aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--AUTHORS34
-rw-r--r--COPYING.FREEFONT690
-rw-r--r--COPYRIGHT3
-rw-r--r--Makefile.common10
-rw-r--r--NEWS77
-rw-r--r--README107
-rw-r--r--audio/audiostream.h4
-rw-r--r--audio/decoders/aac.h6
-rw-r--r--audio/decoders/adpcm.h4
-rw-r--r--audio/decoders/adpcm_intern.h10
-rw-r--r--audio/decoders/aiff.h4
-rw-r--r--audio/decoders/flac.cpp4
-rw-r--r--audio/decoders/flac.h7
-rw-r--r--audio/decoders/iff_sound.cpp2
-rw-r--r--audio/decoders/iff_sound.h4
-rw-r--r--audio/decoders/mac_snd.h5
-rw-r--r--audio/decoders/mp3.h7
-rw-r--r--audio/decoders/qdm2.cpp8
-rw-r--r--audio/decoders/quicktime.cpp32
-rw-r--r--audio/decoders/raw.cpp174
-rw-r--r--audio/decoders/raw.h60
-rw-r--r--audio/decoders/voc.cpp677
-rw-r--r--audio/decoders/voc.h12
-rw-r--r--audio/decoders/vorbis.h7
-rw-r--r--audio/decoders/wave.cpp7
-rw-r--r--audio/decoders/wave.h4
-rw-r--r--audio/fmopl.h4
-rw-r--r--audio/mididrv.cpp25
-rw-r--r--audio/mididrv.h4
-rw-r--r--audio/midiparser.h4
-rw-r--r--audio/midiplayer.h4
-rw-r--r--audio/mixer.h4
-rw-r--r--audio/mixer_intern.h4
-rw-r--r--audio/mods/infogrames.h4
-rw-r--r--audio/mods/maxtrax.cpp4
-rw-r--r--audio/mods/maxtrax.h6
-rw-r--r--audio/mods/module.h4
-rw-r--r--audio/mods/paula.h4
-rw-r--r--audio/mods/protracker.h4
-rw-r--r--audio/mods/rjp1.h4
-rw-r--r--audio/mods/soundfx.h4
-rw-r--r--audio/mods/tfmx.cpp6
-rw-r--r--audio/mods/tfmx.h6
-rw-r--r--audio/mpu401.h4
-rw-r--r--audio/musicplugin.h4
-rw-r--r--audio/null.h4
-rw-r--r--audio/rate.h4
-rw-r--r--audio/rate_arm_asm.s87
-rw-r--r--audio/softsynth/adlib.cpp3
-rw-r--r--audio/softsynth/cms.cpp2
-rw-r--r--audio/softsynth/cms.h4
-rw-r--r--audio/softsynth/emumidi.h4
-rw-r--r--audio/softsynth/fmtowns_pc98/towns_audio.cpp3
-rw-r--r--audio/softsynth/fmtowns_pc98/towns_pc98_driver.cpp2
-rw-r--r--audio/softsynth/mt32.cpp47
-rw-r--r--audio/softsynth/mt32/AReverbModel.cpp237
-rw-r--r--audio/softsynth/mt32/AReverbModel.h86
-rw-r--r--audio/softsynth/mt32/DelayReverb.cpp150
-rw-r--r--audio/softsynth/mt32/DelayReverb.h53
-rw-r--r--audio/softsynth/mt32/FreeverbModel.cpp78
-rw-r--r--audio/softsynth/mt32/FreeverbModel.h44
-rw-r--r--audio/softsynth/mt32/LA32Ramp.cpp150
-rw-r--r--audio/softsynth/mt32/LA32Ramp.h43
-rw-r--r--audio/softsynth/mt32/Part.cpp622
-rw-r--r--audio/softsynth/mt32/Part.h133
-rw-r--r--audio/softsynth/mt32/Partial.cpp557
-rw-r--r--audio/softsynth/mt32/Partial.h119
-rw-r--r--audio/softsynth/mt32/PartialManager.cpp250
-rw-r--r--audio/softsynth/mt32/PartialManager.h54
-rw-r--r--audio/softsynth/mt32/Poly.cpp174
-rw-r--r--audio/softsynth/mt32/Poly.h67
-rw-r--r--audio/softsynth/mt32/Structures.h217
-rw-r--r--audio/softsynth/mt32/Synth.cpp1620
-rw-r--r--audio/softsynth/mt32/Synth.h471
-rw-r--r--audio/softsynth/mt32/TVA.cpp365
-rw-r--r--audio/softsynth/mt32/TVA.h94
-rw-r--r--audio/softsynth/mt32/TVF.cpp230
-rw-r--r--audio/softsynth/mt32/TVF.h54
-rw-r--r--audio/softsynth/mt32/TVP.cpp321
-rw-r--r--audio/softsynth/mt32/TVP.h67
-rw-r--r--audio/softsynth/mt32/Tables.cpp119
-rw-r--r--audio/softsynth/mt32/Tables.h64
-rw-r--r--audio/softsynth/mt32/freeverb.cpp357
-rw-r--r--audio/softsynth/mt32/freeverb.h322
-rw-r--r--audio/softsynth/mt32/i386.cpp849
-rw-r--r--audio/softsynth/mt32/i386.h49
-rw-r--r--audio/softsynth/mt32/mmath.h73
-rw-r--r--audio/softsynth/mt32/module.mk20
-rw-r--r--audio/softsynth/mt32/mt32_file.cpp69
-rw-r--r--audio/softsynth/mt32/mt32_file.h52
-rw-r--r--audio/softsynth/mt32/mt32emu.h140
-rw-r--r--audio/softsynth/mt32/part.cpp633
-rw-r--r--audio/softsynth/mt32/part.h112
-rw-r--r--audio/softsynth/mt32/partial.cpp968
-rw-r--r--audio/softsynth/mt32/partial.h148
-rw-r--r--audio/softsynth/mt32/partialManager.cpp272
-rw-r--r--audio/softsynth/mt32/structures.h284
-rw-r--r--audio/softsynth/mt32/synth.cpp1202
-rw-r--r--audio/softsynth/mt32/synth.h299
-rw-r--r--audio/softsynth/mt32/tables.cpp761
-rw-r--r--audio/softsynth/mt32/tables.h116
-rw-r--r--audio/softsynth/opl/dbopl.cpp4
-rw-r--r--audio/softsynth/opl/dbopl.h4
-rw-r--r--audio/softsynth/opl/dosbox.h4
-rw-r--r--audio/softsynth/opl/mame.h4
-rw-r--r--audio/softsynth/pcspk.h6
-rw-r--r--audio/softsynth/sid.cpp2
-rw-r--r--audio/softsynth/sid.h10
-rw-r--r--audio/softsynth/wave6581.cpp2
-rw-r--r--audio/timestamp.h4
-rw-r--r--backends/events/default/default-events.cpp93
-rw-r--r--backends/events/default/default-events.h2
-rw-r--r--backends/events/maemosdl/maemosdl-events.cpp78
-rw-r--r--backends/events/maemosdl/maemosdl-events.h11
-rw-r--r--backends/events/webossdl/webossdl-events.cpp28
-rw-r--r--backends/events/webossdl/webossdl-events.h6
-rw-r--r--backends/fs/amigaos4/amigaos4-fs.h8
-rw-r--r--backends/fs/ps2/ps2-fs.h2
-rw-r--r--backends/fs/psp/psp-fs-factory.h2
-rw-r--r--backends/fs/symbian/symbian-fs.cpp10
-rw-r--r--backends/fs/symbian/symbianstream.cpp38
-rw-r--r--backends/fs/windows/windows-fs.cpp2
-rw-r--r--backends/graphics/maemosdl/maemosdl-graphics.cpp60
-rw-r--r--backends/graphics/maemosdl/maemosdl-graphics.h40
-rw-r--r--backends/graphics/null/null-graphics.h3
-rw-r--r--backends/graphics/opengl/glerrorcheck.cpp10
-rw-r--r--backends/graphics/opengl/gltexture.cpp15
-rw-r--r--backends/graphics/opengl/gltexture.h17
-rw-r--r--backends/graphics/opengl/opengl-graphics.cpp180
-rw-r--r--backends/graphics/opengl/opengl-graphics.h23
-rw-r--r--backends/graphics/openglsdl/openglsdl-graphics.cpp23
-rw-r--r--backends/keymapper/action.cpp20
-rw-r--r--backends/keymapper/action.h58
-rw-r--r--backends/keymapper/hardware-input.cpp273
-rw-r--r--backends/keymapper/hardware-input.h131
-rw-r--r--backends/keymapper/hardware-key.h136
-rw-r--r--backends/keymapper/keymap.cpp253
-rw-r--r--backends/keymapper/keymap.h37
-rw-r--r--backends/keymapper/keymapper-defaults.h56
-rw-r--r--backends/keymapper/keymapper.cpp114
-rw-r--r--backends/keymapper/keymapper.h65
-rw-r--r--backends/keymapper/remap-dialog.cpp170
-rw-r--r--backends/keymapper/remap-dialog.h6
-rw-r--r--backends/keymapper/types.h74
-rw-r--r--backends/midi/coreaudio.cpp56
-rw-r--r--backends/midi/timidity.cpp2
-rw-r--r--backends/midi/windows.cpp40
-rw-r--r--backends/modular-backend.h7
-rw-r--r--backends/module.mk5
-rw-r--r--backends/mutex/null/null-mutex.h2
-rw-r--r--backends/platform/android/android.cpp1
-rw-r--r--backends/platform/android/android.h2
-rw-r--r--backends/platform/android/android.mk6
-rw-r--r--backends/platform/android/asset-archive.cpp8
-rw-r--r--backends/platform/android/asset-archive.h6
-rw-r--r--backends/platform/android/events.cpp42
-rw-r--r--backends/platform/android/jni.cpp2
-rw-r--r--backends/platform/android/org/scummvm/scummvm/EditableSurfaceView.java (renamed from backends/platform/android/org/inodes/gus/scummvm/EditableSurfaceView.java)2
-rw-r--r--backends/platform/android/org/scummvm/scummvm/PluginProvider.java (renamed from backends/platform/android/org/inodes/gus/scummvm/PluginProvider.java)14
-rw-r--r--backends/platform/android/org/scummvm/scummvm/ScummVM.java (renamed from backends/platform/android/org/inodes/gus/scummvm/ScummVM.java)2
-rw-r--r--backends/platform/android/org/scummvm/scummvm/ScummVMActivity.java (renamed from backends/platform/android/org/inodes/gus/scummvm/ScummVMActivity.java)16
-rw-r--r--backends/platform/android/org/scummvm/scummvm/ScummVMApplication.java (renamed from backends/platform/android/org/inodes/gus/scummvm/ScummVMApplication.java)7
-rw-r--r--backends/platform/android/org/scummvm/scummvm/ScummVMEvents.java (renamed from backends/platform/android/org/inodes/gus/scummvm/ScummVMEvents.java)2
-rw-r--r--backends/platform/android/org/scummvm/scummvm/Unpacker.java (renamed from backends/platform/android/org/inodes/gus/scummvm/Unpacker.java)14
-rw-r--r--backends/platform/android/texture.cpp4
-rw-r--r--backends/platform/bada/application.cpp2
-rw-r--r--backends/platform/bada/audio.cpp2
-rw-r--r--backends/platform/bada/fs.cpp10
-rw-r--r--backends/platform/bada/missing.cpp2
-rw-r--r--backends/platform/bada/portdefs.h7
-rw-r--r--backends/platform/dc/audio.cpp2
-rw-r--r--backends/platform/dc/dc-fs.cpp6
-rw-r--r--backends/platform/dc/dc.h2
-rw-r--r--backends/platform/dc/dcloader.cpp4
-rw-r--r--backends/platform/dc/display.cpp14
-rw-r--r--backends/platform/dc/portdefs.h1
-rw-r--r--backends/platform/ds/arm7/source/main.cpp18
-rw-r--r--backends/platform/ds/arm9/source/blitters.cpp10
-rw-r--r--backends/platform/ds/arm9/source/dsmain.cpp6
-rw-r--r--backends/platform/ds/arm9/source/osystem_ds.cpp17
-rw-r--r--backends/platform/ds/arm9/source/osystem_ds.h2
-rw-r--r--backends/platform/ds/arm9/source/portdefs.h1
-rw-r--r--backends/platform/ds/arm9/source/scummhelp.h2
-rwxr-xr-xbackends/platform/gph/caanoo-bundle.mk20
-rw-r--r--backends/platform/gph/gp2x-bundle.mk29
-rwxr-xr-xbackends/platform/gph/gp2xwiz-bundle.mk20
-rw-r--r--backends/platform/iphone/blit_arm.h35
-rw-r--r--backends/platform/iphone/blit_arm.s137
-rw-r--r--backends/platform/iphone/iphone_common.h66
-rw-r--r--backends/platform/iphone/iphone_keyboard.h13
-rw-r--r--backends/platform/iphone/iphone_keyboard.mm (renamed from backends/platform/iphone/iphone_keyboard.m)10
-rw-r--r--backends/platform/iphone/iphone_main.mm (renamed from backends/platform/iphone/iphone_main.m)77
-rw-r--r--backends/platform/iphone/iphone_video.h79
-rw-r--r--backends/platform/iphone/iphone_video.m756
-rw-r--r--backends/platform/iphone/iphone_video.mm851
-rw-r--r--backends/platform/iphone/module.mk3
-rw-r--r--backends/platform/iphone/osys_events.cpp401
-rw-r--r--backends/platform/iphone/osys_main.cpp66
-rw-r--r--backends/platform/iphone/osys_main.h71
-rw-r--r--backends/platform/iphone/osys_video.cpp503
-rw-r--r--backends/platform/iphone/osys_video.mm491
-rw-r--r--backends/platform/linuxmoto/hardwarekeys.cpp82
-rw-r--r--backends/platform/linuxmoto/linuxmoto-sdl.h4
-rw-r--r--backends/platform/maemo/debian/changelog12
-rw-r--r--backends/platform/maemo/debian/control4
-rwxr-xr-xbackends/platform/maemo/debian/rules2
-rw-r--r--backends/platform/maemo/maemo-common.h19
-rw-r--r--backends/platform/maemo/maemo.cpp122
-rw-r--r--backends/platform/maemo/maemo.h14
-rw-r--r--backends/platform/n64/osys_n64_utilities.cpp4
-rw-r--r--backends/platform/n64/portdefs.h1
-rwxr-xr-xbackends/platform/openpandora/op-bundle.mk29
-rw-r--r--backends/platform/ps2/DmaPipe.cpp6
-rw-r--r--backends/platform/ps2/Gs2dScreen.cpp26
-rw-r--r--backends/platform/ps2/Gs2dScreen.h5
-rw-r--r--backends/platform/ps2/fileio.cpp12
-rw-r--r--backends/platform/ps2/icon.cpp8
-rw-r--r--backends/platform/ps2/ps2mutex.cpp6
-rw-r--r--backends/platform/ps2/ps2pad.cpp2
-rw-r--r--backends/platform/ps2/systemps2.cpp23
-rw-r--r--backends/platform/ps2/systemps2.h1
-rw-r--r--backends/platform/psp/display_manager.cpp8
-rw-r--r--backends/platform/psp/portdefs.h1
-rw-r--r--backends/platform/sdl/hardwarekeys.cpp230
-rwxr-xr-xbackends/platform/sdl/macosx/appmenu_osx.mm44
-rw-r--r--backends/platform/sdl/module.mk1
-rw-r--r--backends/platform/sdl/posix/posix.cpp4
-rw-r--r--backends/platform/sdl/sdl.h1
-rw-r--r--backends/platform/sdl/win32/win32.cpp17
-rw-r--r--backends/platform/symbian/README2
-rw-r--r--backends/platform/symbian/S60/ScummVM_S60.mmp.in2
-rw-r--r--backends/platform/symbian/S60/ScummVM_S60_App.mmp2
-rw-r--r--backends/platform/symbian/S60v3/ScummVM_A0000658_S60v3.mmp.in2
-rw-r--r--backends/platform/symbian/S60v3/ScummVM_S60v3.mmp.in2
-rw-r--r--backends/platform/symbian/S80/ScummVM_S80.mmp.in2
-rw-r--r--backends/platform/symbian/S80/ScummVM_S80_App.mmp2
-rw-r--r--backends/platform/symbian/S90/Scummvm_S90.mmp.in2
-rw-r--r--backends/platform/symbian/S90/Scummvm_S90_App.mmp2
-rw-r--r--backends/platform/symbian/UIQ2/ScummVM.rss2
-rw-r--r--backends/platform/symbian/UIQ3/ScummVM.rss2
-rw-r--r--backends/platform/symbian/UIQ3/ScummVM_A0000658.rss2
-rw-r--r--backends/platform/symbian/UIQ3/ScummVM_A0000658_UIQ3.mmp.in2
-rw-r--r--backends/platform/symbian/UIQ3/ScummVM_UIQ3.mmp.in2
-rw-r--r--backends/platform/symbian/UIQ3/scummvm_A0000658_loc.rss2
-rw-r--r--backends/platform/symbian/mmp/scummvm_agi.mmp.in2
-rw-r--r--backends/platform/symbian/mmp/scummvm_agos.mmp.in2
-rw-r--r--backends/platform/symbian/mmp/scummvm_base.mmp.in2
-rw-r--r--backends/platform/symbian/mmp/scummvm_cine.mmp.in2
-rw-r--r--backends/platform/symbian/mmp/scummvm_cruise.mmp.in2
-rw-r--r--backends/platform/symbian/mmp/scummvm_draci.mmp.in2
-rw-r--r--backends/platform/symbian/mmp/scummvm_drascula.mmp.in2
-rw-r--r--backends/platform/symbian/mmp/scummvm_gob.mmp.in2
-rw-r--r--backends/platform/symbian/mmp/scummvm_groovie.mmp.in2
-rw-r--r--backends/platform/symbian/mmp/scummvm_hugo.mmp.in2
-rw-r--r--backends/platform/symbian/mmp/scummvm_kyra.mmp.in2
-rw-r--r--backends/platform/symbian/mmp/scummvm_lastexpress.mmp.in2
-rw-r--r--backends/platform/symbian/mmp/scummvm_lure.mmp.in2
-rw-r--r--backends/platform/symbian/mmp/scummvm_m4.mmp.in2
-rw-r--r--backends/platform/symbian/mmp/scummvm_made.mmp.in2
-rw-r--r--backends/platform/symbian/mmp/scummvm_mohawk.mmp.in2
-rw-r--r--backends/platform/symbian/mmp/scummvm_parallaction.mmp.in2
-rw-r--r--backends/platform/symbian/mmp/scummvm_queen.mmp.in2
-rw-r--r--backends/platform/symbian/mmp/scummvm_saga.mmp.in2
-rw-r--r--backends/platform/symbian/mmp/scummvm_sci.mmp.in2
-rw-r--r--backends/platform/symbian/mmp/scummvm_scumm.mmp.in2
-rw-r--r--backends/platform/symbian/mmp/scummvm_sky.mmp.in2
-rw-r--r--backends/platform/symbian/mmp/scummvm_sword1.mmp.in2
-rw-r--r--backends/platform/symbian/mmp/scummvm_sword2.mmp.in2
-rw-r--r--backends/platform/symbian/mmp/scummvm_teenagent.mmp.in2
-rw-r--r--backends/platform/symbian/mmp/scummvm_tinsel.mmp.in2
-rw-r--r--backends/platform/symbian/mmp/scummvm_toon.mmp.in2
-rw-r--r--backends/platform/symbian/mmp/scummvm_touche.mmp.in2
-rw-r--r--backends/platform/symbian/mmp/scummvm_tsage.mmp.in2
-rw-r--r--backends/platform/symbian/mmp/scummvm_tucker.mmp.in2
-rw-r--r--backends/platform/symbian/res/ScummVmAif.rss2
-rw-r--r--backends/platform/symbian/res/scummvm.rss2
-rw-r--r--backends/platform/symbian/res/scummvm_A0000658.rss2
-rw-r--r--backends/platform/symbian/src/ScummVm.hrh2
-rw-r--r--backends/platform/webos/webos.cpp14
-rw-r--r--backends/platform/webos/webos.h4
-rw-r--r--backends/platform/wince/README-WinCE.txt17
-rw-r--r--backends/platform/wince/portdefs.h1
-rw-r--r--backends/platform/wince/wince-sdl.cpp12
-rw-r--r--backends/plugins/elf/elf-loader.cpp2
-rw-r--r--backends/saves/windows/windows-saves.cpp78
-rw-r--r--backends/saves/windows/windows-saves.h36
-rw-r--r--backends/taskbar/win32/win32-taskbar.cpp19
-rwxr-xr-xbackends/timer/bada/timer.cpp2
-rw-r--r--backends/timer/default/default-timer.cpp8
-rw-r--r--backends/vkeybd/image-map.cpp11
-rw-r--r--backends/vkeybd/image-map.h9
-rw-r--r--backends/vkeybd/polygon.cpp2
-rw-r--r--backends/vkeybd/polygon.h4
-rw-r--r--backends/vkeybd/virtual-keyboard-gui.cpp47
-rw-r--r--backends/vkeybd/virtual-keyboard-gui.h8
-rw-r--r--backends/vkeybd/virtual-keyboard-parser.cpp34
-rw-r--r--backends/vkeybd/virtual-keyboard-parser.h27
-rw-r--r--backends/vkeybd/virtual-keyboard.cpp16
-rw-r--r--backends/vkeybd/virtual-keyboard.h36
-rw-r--r--base/commandLine.cpp29
-rw-r--r--base/main.cpp50
-rw-r--r--base/plugins.cpp8
-rw-r--r--base/version.cpp4
-rw-r--r--common/EventDispatcher.cpp20
-rw-r--r--common/EventMapper.cpp (renamed from backends/platform/iphone/blit.cpp)50
-rw-r--r--common/algorithm.h12
-rw-r--r--common/archive.cpp22
-rw-r--r--common/archive.h22
-rw-r--r--common/array.h179
-rw-r--r--common/config-file.cpp6
-rw-r--r--common/config-manager.cpp6
-rw-r--r--common/events.h43
-rw-r--r--common/fft.cpp2
-rw-r--r--common/forbidden.h47
-rw-r--r--common/fs.cpp16
-rw-r--r--common/fs.h8
-rw-r--r--common/gui_options.cpp132
-rw-r--r--common/gui_options.h88
-rw-r--r--common/hash-str.h4
-rw-r--r--common/hashmap.h91
-rw-r--r--common/huffman.h2
-rw-r--r--common/keyboard.h20
-rw-r--r--common/language.cpp107
-rw-r--r--common/language.h80
-rw-r--r--common/list.h7
-rw-r--r--common/list_intern.h2
-rw-r--r--common/localization.h2
-rw-r--r--common/macresman.cpp25
-rw-r--r--common/macresman.h7
-rw-r--r--common/memory.h65
-rw-r--r--common/memorypool.cpp2
-rw-r--r--common/memorypool.h2
-rw-r--r--common/module.mk5
-rw-r--r--common/platform.cpp107
-rw-r--r--common/platform.h80
-rw-r--r--common/quicktime.cpp29
-rw-r--r--common/quicktime.h6
-rw-r--r--common/rendermode.cpp81
-rw-r--r--common/rendermode.h67
-rw-r--r--common/scummsys.h9
-rw-r--r--common/serializer.h2
-rw-r--r--common/singleton.h2
-rw-r--r--common/stack.h47
-rw-r--r--common/str.cpp12
-rw-r--r--common/stream.cpp2
-rw-r--r--common/substream.h17
-rw-r--r--common/system.h39
-rw-r--r--common/translation.cpp70
-rw-r--r--common/translation.h23
-rw-r--r--common/unarj.cpp14
-rw-r--r--common/unzip.cpp20
-rw-r--r--common/util.cpp318
-rw-r--r--common/util.h196
-rw-r--r--common/xmlparser.cpp12
-rw-r--r--common/xmlparser.h10
-rw-r--r--common/zlib.cpp9
-rw-r--r--common/zlib.h33
-rwxr-xr-xconfig.guess232
-rwxr-xr-xconfig.sub174
-rwxr-xr-xconfigure267
-rw-r--r--devtools/convbdf.c928
-rw-r--r--devtools/convbdf.cpp510
-rw-r--r--devtools/create_hugo/enums.h2
-rw-r--r--devtools/create_hugo/staticdata.h36
-rw-r--r--devtools/create_kyradat/create_kyradat.cpp1567
-rw-r--r--devtools/create_kyradat/create_kyradat.h569
-rw-r--r--devtools/create_kyradat/extract.cpp180
-rw-r--r--devtools/create_kyradat/extract.h18
-rw-r--r--devtools/create_kyradat/games.cpp1129
-rw-r--r--devtools/create_kyradat/module.mk3
-rw-r--r--devtools/create_kyradat/tables.cpp2748
-rw-r--r--devtools/create_kyradat/util.cpp13
-rw-r--r--devtools/create_kyradat/util.h1
-rw-r--r--devtools/create_lure/process_actions.cpp2
-rw-r--r--devtools/create_mads/main.cpp127
-rw-r--r--devtools/create_mads/module.mk12
-rw-r--r--devtools/create_mads/parser.cpp937
-rw-r--r--devtools/create_mads/scripts/rex_nebular.txt2241
-rw-r--r--devtools/create_project/create_project.cpp165
-rw-r--r--devtools/create_project/create_project.h2
-rwxr-xr-xdevtools/create_project/xcode.cpp2
-rw-r--r--devtools/create_translations/cp_parser.cpp104
-rw-r--r--devtools/create_translations/cp_parser.h54
-rw-r--r--devtools/create_translations/create_translations.cpp105
-rw-r--r--devtools/create_translations/create_translations.h1
-rw-r--r--devtools/create_translations/module.mk1
-rwxr-xr-xdevtools/credits.pl34
-rw-r--r--devtools/md5table.c1
-rw-r--r--devtools/module.mk4
-rw-r--r--devtools/sci/musicplayer.cpp2
-rw-r--r--devtools/scumm-md5.txt27
-rw-r--r--devtools/skycpt/AsciiCptCompile.cpp2
-rw-r--r--devtools/skycpt/TextFile.cpp4
-rw-r--r--devtools/skycpt/cptcompiler.cpp34
-rw-r--r--devtools/tasmrecover/dreamweb/backdrop.asm2
-rw-r--r--devtools/tasmrecover/dreamweb/debug.asm2
-rw-r--r--devtools/tasmrecover/dreamweb/dreamweb.asm6
-rw-r--r--devtools/tasmrecover/dreamweb/keypad.asm2
-rw-r--r--devtools/tasmrecover/dreamweb/look.asm2
-rw-r--r--devtools/tasmrecover/dreamweb/monitor.asm2
-rw-r--r--devtools/tasmrecover/dreamweb/newplace.asm2
-rw-r--r--devtools/tasmrecover/dreamweb/object.asm4
-rw-r--r--devtools/tasmrecover/dreamweb/print.asm2
-rw-r--r--devtools/tasmrecover/dreamweb/saveload.asm3
-rw-r--r--devtools/tasmrecover/dreamweb/sblaster.asm2
-rw-r--r--devtools/tasmrecover/dreamweb/sprite.asm4
-rw-r--r--devtools/tasmrecover/dreamweb/talk.asm2
-rw-r--r--devtools/tasmrecover/dreamweb/titles.asm2
-rw-r--r--devtools/tasmrecover/dreamweb/use.asm2
-rw-r--r--devtools/tasmrecover/dreamweb/vars.asm2
-rw-r--r--devtools/tasmrecover/dreamweb/vgafades.asm2
-rw-r--r--devtools/tasmrecover/dreamweb/vgagrafx.asm2
-rwxr-xr-xdevtools/tasmrecover/tasm-recover2237
-rw-r--r--devtools/tasmrecover/tasm/cpp.py103
-rw-r--r--devtools/tasmrecover/tasm/parser.py51
-rwxr-xr-xdevtools/update-version.pl6
-rw-r--r--dists/android/AndroidManifest.xml10
-rw-r--r--dists/android/AndroidManifest.xml.in10
-rwxr-xr-xdists/android/mkplugin.sh2
-rw-r--r--dists/android/plugin-manifest.xml14
-rw-r--r--dists/android/plugin-manifest.xml.in14
-rw-r--r--dists/android/res/layout/main.xml2
-rw-r--r--dists/debian/changelog544
-rw-r--r--dists/debian/compat1
-rw-r--r--dists/debian/control59
-rw-r--r--dists/debian/copyright (renamed from audio/softsynth/mt32/partialManager.h)63
-rwxr-xr-xdists/debian/rules14
-rw-r--r--dists/debian/scummvm-data.install5
-rw-r--r--dists/debian/scummvm.dirs5
-rw-r--r--dists/debian/scummvm.docs5
-rw-r--r--dists/debian/scummvm.install2
-rw-r--r--dists/debian/scummvm.manpages1
-rw-r--r--dists/debian/scummvm.menu3
-rw-r--r--dists/engine-data/kyra.datbin385091 -> 469735 bytes
-rw-r--r--dists/engine-data/m4.datbin137897 -> 0 bytes
-rw-r--r--dists/engine-data/mads.datbin12126 -> 0 bytes
-rw-r--r--dists/gph/README-GPH (renamed from backends/platform/gph/devices/common/README-GPH)3
-rw-r--r--dists/gph/README-GPH.in61
-rw-r--r--dists/gph/caanoo/scummvm-gdb.gpe (renamed from backends/platform/gph/devices/caanoo/scummvm-gdb.gpe)0
-rw-r--r--dists/gph/caanoo/scummvm.gpe (renamed from backends/platform/gph/devices/caanoo/scummvm.gpe)0
-rw-r--r--dists/gph/gp2x/mmuhack/Makefile (renamed from backends/platform/gph/devices/gp2x/mmuhack/Makefile)0
-rw-r--r--dists/gph/gp2x/mmuhack/README (renamed from backends/platform/gph/devices/gp2x/mmuhack/README)0
-rw-r--r--dists/gph/gp2x/mmuhack/flush_uppermem_cache.h (renamed from backends/platform/gph/devices/gp2x/mmuhack/flush_uppermem_cache.h)0
-rw-r--r--dists/gph/gp2x/mmuhack/flush_uppermem_cache.s (renamed from backends/platform/gph/devices/gp2x/mmuhack/flush_uppermem_cache.s)0
-rw-r--r--dists/gph/gp2x/mmuhack/mmuhack.c (renamed from backends/platform/gph/devices/gp2x/mmuhack/mmuhack.c)0
-rw-r--r--dists/gph/gp2x/mmuhack/mmuhack.o (renamed from backends/platform/gph/devices/gp2x/mmuhack/mmuhack.o)bin1720 -> 1720 bytes
-rw-r--r--dists/gph/gp2x/scummvm.gpe (renamed from backends/platform/gph/devices/gp2x/scummvm.gpe)0
-rw-r--r--dists/gph/gp2xwiz/scummvm-gdb.gpe (renamed from backends/platform/gph/devices/gp2xwiz/scummvm-gdb.gpe)0
-rw-r--r--dists/gph/gp2xwiz/scummvm.gpe (renamed from backends/platform/gph/devices/gp2xwiz/scummvm.gpe)0
-rw-r--r--dists/gph/scummvm.ini (renamed from backends/platform/gph/devices/common/scummvm.ini)2
-rw-r--r--dists/gph/scummvm.ini.in5
-rw-r--r--dists/gph/scummvm.png (renamed from backends/platform/gph/devices/common/scummvm.png)bin2656 -> 2656 bytes
-rw-r--r--dists/gph/scummvmb.png (renamed from backends/platform/gph/devices/common/scummvmb.png)bin34274 -> 34274 bytes
-rw-r--r--dists/irix/scummvm.idb1
-rw-r--r--dists/macosx/DS_Storebin12292 -> 12292 bytes
-rw-r--r--dists/macosx/Info.plist4
-rw-r--r--dists/macosx/Info.plist.in4
-rw-r--r--[-rwxr-xr-x]dists/openpandora/PXML.xml (renamed from backends/platform/openpandora/build/PXML.xml)8
-rw-r--r--dists/openpandora/PXML.xml.in55
-rw-r--r--dists/openpandora/PXML_schema.xsd (renamed from backends/platform/openpandora/build/PXML_schema.xsd)0
-rw-r--r--[-rwxr-xr-x]dists/openpandora/README-OPENPANDORA (renamed from backends/platform/openpandora/build/README-OPENPANDORA)2
-rw-r--r--dists/openpandora/README-OPENPANDORA.in19
-rw-r--r--[-rwxr-xr-x]dists/openpandora/README-PND.txt (renamed from backends/platform/openpandora/build/README-PND.txt)2
-rw-r--r--dists/openpandora/README-PND.txt.in38
-rw-r--r--[-rwxr-xr-x]dists/openpandora/icon/preview-pic.png (renamed from backends/platform/openpandora/build/icon/preview-pic.png)bin72496 -> 72496 bytes
-rw-r--r--[-rwxr-xr-x]dists/openpandora/icon/scummvm.png (renamed from backends/platform/openpandora/build/icon/scummvm.png)bin2656 -> 2656 bytes
-rw-r--r--[-rwxr-xr-x]dists/openpandora/index.html (renamed from backends/platform/openpandora/build/index.html)4
-rw-r--r--dists/openpandora/index.html.in26
-rwxr-xr-xdists/openpandora/pnd_make.sh (renamed from backends/platform/openpandora/build/pnd_make.sh)0
-rwxr-xr-xdists/openpandora/runscummvm.sh (renamed from backends/platform/openpandora/build/runscummvm.sh)0
-rw-r--r--dists/redhat/scummvm.spec8
-rw-r--r--dists/redhat/scummvm.spec.in8
-rw-r--r--dists/scummvm.rc5
-rw-r--r--dists/scummvm.rc.in5
-rw-r--r--dists/win32/ScummVM.iss37
-rw-r--r--dists/win32/migration.bat51
-rw-r--r--dists/win32/migration.txt27
-rw-r--r--dists/win32/scummvm.nsi4
-rw-r--r--dists/win32/scummvm.nsi.in4
-rw-r--r--doc/cz/PrectiMe98
-rw-r--r--doc/de/Liesmich86
-rw-r--r--doc/de/Neues75
-rw-r--r--doc/es/InicioRapido (renamed from doc/es/Inicio rápido)0
-rw-r--r--doc/se/LasMig1652
-rw-r--r--doc/se/Snabbstart79
-rw-r--r--engines/advancedDetector.h12
-rw-r--r--engines/agi/agi.cpp14
-rw-r--r--engines/agi/agi.h5
-rw-r--r--engines/agi/checks.cpp16
-rw-r--r--engines/agi/cycle.cpp82
-rw-r--r--engines/agi/detection_tables.h18
-rw-r--r--engines/agi/graphics.cpp4
-rw-r--r--engines/agi/menu.cpp129
-rw-r--r--engines/agi/menu.h4
-rw-r--r--engines/agi/objects.cpp2
-rw-r--r--engines/agi/op_cmd.cpp9
-rw-r--r--engines/agi/opcodes.cpp4
-rw-r--r--engines/agi/picture.h2
-rw-r--r--engines/agi/preagi_mickey.h2
-rw-r--r--engines/agi/preagi_troll.cpp4
-rw-r--r--engines/agi/preagi_winnie.cpp61
-rw-r--r--engines/agi/predictive.cpp66
-rw-r--r--engines/agi/saveload.cpp197
-rw-r--r--engines/agi/sound_2gs.cpp16
-rw-r--r--engines/agi/sound_2gs.h2
-rw-r--r--engines/agi/sound_sarien.cpp4
-rw-r--r--engines/agi/sprite.cpp2
-rw-r--r--engines/agi/sprite.h2
-rw-r--r--engines/agi/text.cpp23
-rw-r--r--engines/agi/wagparser.cpp4
-rw-r--r--engines/agi/words.cpp2
-rw-r--r--engines/agos/agos.h7
-rw-r--r--engines/agos/animation.cpp14
-rw-r--r--engines/agos/charset-fontdata.cpp573
-rw-r--r--engines/agos/charset.cpp275
-rw-r--r--engines/agos/detection_tables.h102
-rw-r--r--engines/agos/draw.cpp2
-rw-r--r--engines/agos/installshield_cab.cpp13
-rw-r--r--engines/agos/midi.cpp6
-rw-r--r--engines/agos/res.cpp49
-rw-r--r--engines/agos/res_snd.cpp8
-rw-r--r--engines/agos/saveload.cpp13
-rw-r--r--engines/agos/script_pn.cpp8
-rw-r--r--engines/agos/sound.cpp328
-rw-r--r--engines/agos/sound.h2
-rw-r--r--engines/agos/string.cpp2
-rw-r--r--engines/agos/string_pn.cpp2
-rw-r--r--engines/agos/subroutine.cpp5
-rw-r--r--engines/cge/bitmap.cpp24
-rw-r--r--engines/cge/bitmap.h3
-rw-r--r--engines/cge/cge.cpp15
-rw-r--r--engines/cge/cge.h12
-rw-r--r--engines/cge/cge_main.cpp67
-rw-r--r--engines/cge/cge_main.h5
-rw-r--r--engines/cge/console.cpp14
-rw-r--r--engines/cge/console.h1
-rw-r--r--engines/cge/detection.cpp38
-rw-r--r--engines/cge/events.cpp159
-rw-r--r--engines/cge/events.h43
-rw-r--r--engines/cge/fileio.cpp1
-rw-r--r--engines/cge/snail.cpp12
-rw-r--r--engines/cge/snail.h3
-rw-r--r--engines/cge/talk.cpp75
-rw-r--r--engines/cge/talk.h4
-rw-r--r--engines/cge/text.cpp20
-rw-r--r--engines/cge/vga13h.cpp24
-rw-r--r--engines/cge/vga13h.h6
-rw-r--r--engines/cge/walk.h1
-rw-r--r--engines/cine/cine.cpp4
-rw-r--r--engines/cine/detection.cpp4
-rw-r--r--engines/cine/detection_tables.h66
-rw-r--r--engines/cine/gfx.cpp2
-rw-r--r--engines/cine/main_loop.cpp2
-rw-r--r--engines/cine/saveload.cpp2
-rw-r--r--engines/cine/sound.cpp285
-rw-r--r--engines/composer/composer.cpp169
-rw-r--r--engines/composer/composer.h39
-rw-r--r--engines/composer/detection.cpp164
-rw-r--r--engines/composer/graphics.cpp73
-rw-r--r--engines/composer/resource.cpp68
-rw-r--r--engines/composer/resource.h22
-rw-r--r--engines/composer/scripting.cpp260
-rw-r--r--engines/cruise/background.cpp2
-rw-r--r--engines/cruise/backgroundIncrust.cpp6
-rw-r--r--engines/cruise/cruise.h2
-rw-r--r--engines/cruise/cruise_main.cpp12
-rw-r--r--engines/cruise/dataLoader.cpp10
-rw-r--r--engines/cruise/detection.cpp22
-rw-r--r--engines/cruise/font.cpp2
-rw-r--r--engines/cruise/function.cpp10
-rw-r--r--engines/cruise/gfxModule.cpp2
-rw-r--r--engines/cruise/mainDraw.cpp12
-rw-r--r--engines/cruise/overlay.cpp6
-rw-r--r--engines/cruise/saveload.cpp5
-rw-r--r--engines/cruise/script.cpp4
-rw-r--r--engines/cruise/volume.cpp4
-rw-r--r--engines/dialogs.cpp19
-rw-r--r--engines/draci/barchive.cpp6
-rw-r--r--engines/draci/detection.cpp8
-rw-r--r--engines/draci/draci.cpp3
-rw-r--r--engines/draci/saveload.cpp2
-rw-r--r--engines/draci/sprite.cpp2
-rw-r--r--engines/draci/walking.cpp12
-rw-r--r--engines/drascula/animation.cpp49
-rw-r--r--engines/drascula/converse.cpp2
-rw-r--r--engines/drascula/detection.cpp26
-rw-r--r--engines/drascula/drascula.cpp4
-rw-r--r--engines/drascula/drascula.h1
-rw-r--r--engines/drascula/graphics.cpp5
-rw-r--r--engines/drascula/interface.cpp13
-rw-r--r--engines/drascula/saveload.cpp2
-rw-r--r--engines/drascula/sound.cpp32
-rw-r--r--engines/drascula/talk.cpp30
-rw-r--r--engines/dreamweb/README12
-rw-r--r--engines/dreamweb/backdrop.cpp300
-rw-r--r--engines/dreamweb/detection.cpp85
-rw-r--r--engines/dreamweb/detection_tables.h22
-rw-r--r--engines/dreamweb/dreamgen.cpp17268
-rw-r--r--engines/dreamweb/dreamgen.h2000
-rw-r--r--engines/dreamweb/dreamweb.cpp517
-rw-r--r--engines/dreamweb/dreamweb.h1045
-rw-r--r--engines/dreamweb/keypad.cpp866
-rw-r--r--engines/dreamweb/module.mk10
-rw-r--r--engines/dreamweb/monitor.cpp705
-rw-r--r--engines/dreamweb/newplace.cpp271
-rw-r--r--engines/dreamweb/object.cpp1107
-rw-r--r--engines/dreamweb/pathfind.cpp332
-rw-r--r--engines/dreamweb/people.cpp1121
-rw-r--r--engines/dreamweb/print.cpp296
-rw-r--r--engines/dreamweb/rain.cpp194
-rw-r--r--engines/dreamweb/runtime.h588
-rw-r--r--engines/dreamweb/saveload.cpp998
-rw-r--r--engines/dreamweb/sound.cpp274
-rw-r--r--engines/dreamweb/sprite.cpp1476
-rw-r--r--engines/dreamweb/structs.h345
-rw-r--r--engines/dreamweb/stubs.cpp4171
-rw-r--r--engines/dreamweb/stubs.h249
-rw-r--r--engines/dreamweb/talk.cpp263
-rw-r--r--engines/dreamweb/titles.cpp444
-rw-r--r--engines/dreamweb/use.cpp1659
-rw-r--r--engines/dreamweb/vgafades.cpp284
-rw-r--r--engines/dreamweb/vgagrafx.cpp373
-rw-r--r--engines/engine.cpp36
-rw-r--r--engines/engine.h12
-rw-r--r--engines/engines.mk14
-rw-r--r--engines/game.cpp1
-rw-r--r--engines/game.h7
-rw-r--r--engines/gob/aniobject.cpp30
-rw-r--r--engines/gob/aniobject.h5
-rw-r--r--engines/gob/cheater.cpp (renamed from devtools/create_mads/parser.h)14
-rw-r--r--engines/gob/cheater.h62
-rw-r--r--engines/gob/cheater_geisha.cpp66
-rw-r--r--engines/gob/console.cpp19
-rw-r--r--engines/gob/console.h8
-rw-r--r--engines/gob/databases.h2
-rw-r--r--engines/gob/dataio.cpp2
-rw-r--r--engines/gob/detection_tables.h250
-rw-r--r--engines/gob/draw_v1.cpp4
-rw-r--r--engines/gob/draw_v2.cpp4
-rw-r--r--engines/gob/gob.cpp4
-rw-r--r--engines/gob/gob.h3
-rw-r--r--engines/gob/hotspots.cpp2
-rw-r--r--engines/gob/iniconfig.cpp2
-rw-r--r--engines/gob/inter.h4
-rw-r--r--engines/gob/inter_geisha.cpp11
-rw-r--r--engines/gob/inter_playtoons.cpp2
-rw-r--r--engines/gob/inter_v1.cpp16
-rw-r--r--engines/gob/inter_v2.cpp2
-rw-r--r--engines/gob/inter_v7.cpp2
-rw-r--r--engines/gob/map.cpp2
-rw-r--r--engines/gob/minigames/geisha/diving.cpp440
-rw-r--r--engines/gob/minigames/geisha/diving.h68
-rw-r--r--engines/gob/minigames/geisha/evilfish.cpp17
-rw-r--r--engines/gob/minigames/geisha/evilfish.h6
-rw-r--r--engines/gob/minigames/geisha/meter.cpp116
-rw-r--r--engines/gob/minigames/geisha/meter.h89
-rw-r--r--engines/gob/minigames/geisha/oko.cpp170
-rw-r--r--engines/gob/minigames/geisha/oko.h84
-rw-r--r--engines/gob/module.mk4
-rw-r--r--engines/gob/sound/bgatmosphere.h1
-rw-r--r--engines/groovie/detection.cpp33
-rw-r--r--engines/groovie/roq.cpp4
-rw-r--r--engines/groovie/script.cpp8
-rw-r--r--engines/hugo/detection.cpp12
-rw-r--r--engines/hugo/game.h2
-rw-r--r--engines/hugo/object.h2
-rw-r--r--engines/hugo/object_v1d.cpp16
-rw-r--r--engines/hugo/object_v1w.cpp20
-rw-r--r--engines/hugo/object_v2d.cpp20
-rw-r--r--engines/hugo/object_v3d.cpp20
-rw-r--r--engines/hugo/parser.cpp4
-rw-r--r--engines/hugo/route.cpp32
-rw-r--r--engines/hugo/schedule.cpp9
-rw-r--r--engines/hugo/sound.cpp2
-rw-r--r--engines/hugo/sound.h6
-rw-r--r--engines/hugo/util.cpp2
-rw-r--r--engines/kyra/animator_hof.cpp11
-rw-r--r--engines/kyra/animator_lok.cpp22
-rw-r--r--engines/kyra/animator_mr.cpp9
-rw-r--r--engines/kyra/animator_v2.cpp4
-rw-r--r--engines/kyra/chargen.cpp1951
-rw-r--r--engines/kyra/darkmoon.cpp471
-rw-r--r--engines/kyra/darkmoon.h147
-rw-r--r--engines/kyra/debugger.cpp105
-rw-r--r--engines/kyra/debugger.h20
-rw-r--r--engines/kyra/detection.cpp60
-rw-r--r--engines/kyra/detection_tables.h268
-rw-r--r--engines/kyra/eob.cpp562
-rw-r--r--engines/kyra/eob.h121
-rw-r--r--engines/kyra/eobcommon.cpp2420
-rw-r--r--engines/kyra/eobcommon.h1164
-rw-r--r--engines/kyra/gui.cpp646
-rw-r--r--engines/kyra/gui.h174
-rw-r--r--engines/kyra/gui_eob.cpp4093
-rw-r--r--engines/kyra/gui_eob.h165
-rw-r--r--engines/kyra/gui_hof.cpp2
-rw-r--r--engines/kyra/gui_lok.cpp48
-rw-r--r--engines/kyra/gui_lok.h4
-rw-r--r--engines/kyra/gui_lol.cpp185
-rw-r--r--engines/kyra/gui_lol.h11
-rw-r--r--engines/kyra/gui_mr.cpp2
-rw-r--r--engines/kyra/gui_rpg.cpp134
-rw-r--r--engines/kyra/gui_v1.cpp629
-rw-r--r--engines/kyra/gui_v1.h197
-rw-r--r--engines/kyra/gui_v2.cpp18
-rw-r--r--engines/kyra/gui_v2.h4
-rw-r--r--engines/kyra/items_eob.cpp731
-rw-r--r--engines/kyra/items_lok.cpp48
-rw-r--r--engines/kyra/items_lol.cpp129
-rw-r--r--engines/kyra/kyra_hof.cpp22
-rw-r--r--engines/kyra/kyra_hof.h28
-rw-r--r--engines/kyra/kyra_lok.cpp70
-rw-r--r--engines/kyra/kyra_lok.h6
-rw-r--r--engines/kyra/kyra_mr.cpp9
-rw-r--r--engines/kyra/kyra_mr.h2
-rw-r--r--engines/kyra/kyra_rpg.cpp367
-rw-r--r--engines/kyra/kyra_rpg.h392
-rw-r--r--engines/kyra/kyra_v1.cpp99
-rw-r--r--engines/kyra/kyra_v1.h68
-rw-r--r--engines/kyra/kyra_v2.cpp6
-rw-r--r--engines/kyra/kyra_v2.h8
-rw-r--r--engines/kyra/lol.cpp482
-rw-r--r--engines/kyra/lol.h366
-rw-r--r--engines/kyra/magic_eob.cpp1382
-rw-r--r--engines/kyra/module.mk36
-rw-r--r--engines/kyra/resource.cpp22
-rw-r--r--engines/kyra/resource.h635
-rw-r--r--engines/kyra/resource_intern.cpp39
-rw-r--r--engines/kyra/resource_intern.h18
-rw-r--r--engines/kyra/saveload.cpp37
-rw-r--r--engines/kyra/saveload_eob.cpp909
-rw-r--r--engines/kyra/saveload_lok.cpp2
-rw-r--r--engines/kyra/saveload_lol.cpp289
-rw-r--r--engines/kyra/saveload_rpg.cpp127
-rw-r--r--engines/kyra/scene_eob.cpp890
-rw-r--r--engines/kyra/scene_lok.cpp44
-rw-r--r--engines/kyra/scene_lol.cpp750
-rw-r--r--engines/kyra/scene_mr.cpp4
-rw-r--r--engines/kyra/scene_rpg.cpp637
-rw-r--r--engines/kyra/scene_v1.cpp67
-rw-r--r--engines/kyra/scene_v2.cpp40
-rw-r--r--engines/kyra/screen.cpp446
-rw-r--r--engines/kyra/screen.h108
-rw-r--r--engines/kyra/screen_eob.cpp1781
-rw-r--r--engines/kyra/screen_eob.h129
-rw-r--r--engines/kyra/screen_hof.cpp12
-rw-r--r--engines/kyra/screen_hof.h4
-rw-r--r--engines/kyra/screen_lok.cpp74
-rw-r--r--engines/kyra/screen_lok.h4
-rw-r--r--engines/kyra/screen_lol.cpp44
-rw-r--r--engines/kyra/screen_lol.h15
-rw-r--r--engines/kyra/screen_mr.cpp13
-rw-r--r--engines/kyra/screen_mr.h4
-rw-r--r--engines/kyra/screen_v2.cpp15
-rw-r--r--engines/kyra/screen_v2.h2
-rw-r--r--engines/kyra/script.h17
-rw-r--r--engines/kyra/script_eob.cpp1611
-rw-r--r--engines/kyra/script_eob.h132
-rw-r--r--engines/kyra/script_hof.cpp3
-rw-r--r--engines/kyra/script_lok.cpp47
-rw-r--r--engines/kyra/script_lol.cpp183
-rw-r--r--engines/kyra/script_mr.cpp2
-rw-r--r--engines/kyra/script_tim.cpp179
-rw-r--r--engines/kyra/script_tim.h15
-rw-r--r--engines/kyra/script_v1.cpp4
-rw-r--r--engines/kyra/script_v2.cpp22
-rw-r--r--engines/kyra/seqplayer.cpp19
-rw-r--r--engines/kyra/sequences_darkmoon.cpp1436
-rw-r--r--engines/kyra/sequences_eob.cpp1152
-rw-r--r--engines/kyra/sequences_hof.cpp14
-rw-r--r--engines/kyra/sequences_lok.cpp12
-rw-r--r--engines/kyra/sequences_lol.cpp74
-rw-r--r--engines/kyra/sound.cpp139
-rw-r--r--engines/kyra/sound.h70
-rw-r--r--engines/kyra/sound_adlib.cpp700
-rw-r--r--engines/kyra/sound_adlib.h33
-rw-r--r--engines/kyra/sound_amiga.cpp2
-rw-r--r--engines/kyra/sound_intern.h10
-rw-r--r--engines/kyra/sound_lol.cpp35
-rw-r--r--engines/kyra/sound_midi.cpp2
-rw-r--r--engines/kyra/sound_towns.cpp34
-rw-r--r--engines/kyra/sprites_eob.cpp1259
-rw-r--r--engines/kyra/sprites_lol.cpp168
-rw-r--r--engines/kyra/sprites_rpg.cpp46
-rw-r--r--engines/kyra/staticres.cpp207
-rw-r--r--engines/kyra/staticres_eob.cpp1356
-rw-r--r--engines/kyra/staticres_lol.cpp235
-rw-r--r--engines/kyra/staticres_rpg.cpp100
-rw-r--r--engines/kyra/text_lok.cpp21
-rw-r--r--engines/kyra/text_lol.cpp505
-rw-r--r--engines/kyra/text_lol.h53
-rw-r--r--engines/kyra/text_rpg.cpp671
-rw-r--r--engines/kyra/text_rpg.h115
-rw-r--r--engines/kyra/timer.cpp6
-rw-r--r--engines/kyra/timer_eob.cpp360
-rw-r--r--engines/kyra/timer_lok.cpp2
-rw-r--r--engines/kyra/timer_lol.cpp55
-rw-r--r--engines/kyra/timer_rpg.cpp90
-rw-r--r--engines/kyra/wsamovie.cpp12
-rw-r--r--engines/lastexpress/data/archive.cpp6
-rw-r--r--engines/lastexpress/data/archive.h6
-rw-r--r--engines/lastexpress/data/scene.h4
-rw-r--r--engines/lastexpress/detection.cpp18
-rw-r--r--engines/lastexpress/entities/abbot.cpp2
-rw-r--r--engines/lastexpress/entities/alexei.cpp2
-rw-r--r--engines/lastexpress/entities/august.cpp2
-rw-r--r--engines/lastexpress/entities/entity_intern.h4
-rw-r--r--engines/lastexpress/entities/francois.cpp2
-rw-r--r--engines/lastexpress/entities/mertens.cpp2
-rw-r--r--engines/lastexpress/game/action.cpp2
-rw-r--r--engines/lastexpress/game/entities.cpp27
-rw-r--r--engines/lastexpress/game/savegame.cpp4
-rw-r--r--engines/lastexpress/resource.cpp10
-rw-r--r--engines/lastexpress/resource.h6
-rw-r--r--engines/lure/decode.cpp323
-rw-r--r--engines/lure/detection.cpp16
-rw-r--r--engines/lure/hotspots.cpp302
-rw-r--r--engines/lure/menu.cpp63
-rw-r--r--engines/lure/res.cpp2
-rw-r--r--engines/lure/room.cpp2
-rw-r--r--engines/lure/scripts.cpp2
-rw-r--r--engines/lure/sound.cpp12
-rw-r--r--engines/m4/actor.cpp199
-rw-r--r--engines/m4/actor.h114
-rw-r--r--engines/m4/animation.cpp535
-rw-r--r--engines/m4/animation.h127
-rw-r--r--engines/m4/assets.cpp650
-rw-r--r--engines/m4/assets.h212
-rw-r--r--engines/m4/burger_data.h82
-rw-r--r--engines/m4/compression.cpp190
-rw-r--r--engines/m4/compression.h77
-rw-r--r--engines/m4/console.cpp428
-rw-r--r--engines/m4/console.h83
-rw-r--r--engines/m4/converse.cpp1239
-rw-r--r--engines/m4/converse.h214
-rw-r--r--engines/m4/detection.cpp419
-rw-r--r--engines/m4/dialogs.cpp560
-rw-r--r--engines/m4/dialogs.h80
-rw-r--r--engines/m4/events.cpp365
-rw-r--r--engines/m4/events.h132
-rw-r--r--engines/m4/font.cpp291
-rw-r--r--engines/m4/font.h119
-rw-r--r--engines/m4/globals.cpp554
-rw-r--r--engines/m4/globals.h346
-rw-r--r--engines/m4/graphics.cpp1361
-rw-r--r--engines/m4/graphics.h270
-rw-r--r--engines/m4/gui.cpp1215
-rw-r--r--engines/m4/gui.h453
-rw-r--r--engines/m4/hotspot.cpp283
-rw-r--r--engines/m4/hotspot.h126
-rw-r--r--engines/m4/m4.cpp606
-rw-r--r--engines/m4/m4.h252
-rw-r--r--engines/m4/m4_menus.cpp724
-rw-r--r--engines/m4/m4_menus.h103
-rw-r--r--engines/m4/m4_scene.cpp326
-rw-r--r--engines/m4/m4_scene.h84
-rw-r--r--engines/m4/m4_views.cpp342
-rw-r--r--engines/m4/m4_views.h115
-rw-r--r--engines/m4/mads_anim.cpp745
-rw-r--r--engines/m4/mads_anim.h110
-rw-r--r--engines/m4/mads_logic.cpp1038
-rw-r--r--engines/m4/mads_logic.h117
-rw-r--r--engines/m4/mads_menus.cpp1173
-rw-r--r--engines/m4/mads_menus.h179
-rw-r--r--engines/m4/mads_player.cpp789
-rw-r--r--engines/m4/mads_player.h113
-rw-r--r--engines/m4/mads_scene.cpp1272
-rw-r--r--engines/m4/mads_scene.h195
-rw-r--r--engines/m4/mads_views.cpp1632
-rw-r--r--engines/m4/mads_views.h494
-rw-r--r--engines/m4/midi.cpp256
-rw-r--r--engines/m4/module.mk49
-rw-r--r--engines/m4/rails.cpp358
-rw-r--r--engines/m4/rails.h97
-rw-r--r--engines/m4/resource.cpp530
-rw-r--r--engines/m4/resource.h147
-rw-r--r--engines/m4/saveload.cpp166
-rw-r--r--engines/m4/scene.cpp208
-rw-r--r--engines/m4/scene.h120
-rw-r--r--engines/m4/script.cpp1389
-rw-r--r--engines/m4/script.h463
-rw-r--r--engines/m4/scripttab.h135
-rw-r--r--engines/m4/sound.cpp276
-rw-r--r--engines/m4/sound.h110
-rw-r--r--engines/m4/sprite.cpp207
-rw-r--r--engines/m4/sprite.h121
-rw-r--r--engines/m4/viewmgr.cpp444
-rw-r--r--engines/m4/viewmgr.h204
-rw-r--r--engines/m4/woodscript.cpp398
-rw-r--r--engines/m4/woodscript.h348
-rw-r--r--engines/m4/ws_machine.cpp423
-rw-r--r--engines/m4/ws_sequence.cpp768
-rw-r--r--engines/made/database.cpp24
-rw-r--r--engines/made/database.h4
-rw-r--r--engines/made/detection.cpp34
-rw-r--r--engines/made/graphics.cpp4
-rw-r--r--engines/made/resource.h8
-rw-r--r--engines/made/screen.cpp24
-rw-r--r--engines/made/screenfx.cpp4
-rw-r--r--engines/made/scriptfuncs.h2
-rw-r--r--engines/metaengine.h3
-rw-r--r--engines/mohawk/bitmap.cpp2
-rw-r--r--engines/mohawk/console.cpp2
-rw-r--r--engines/mohawk/cstime.h2
-rw-r--r--engines/mohawk/cstime_graphics.cpp64
-rw-r--r--engines/mohawk/cstime_graphics.h51
-rw-r--r--engines/mohawk/detection_tables.h394
-rw-r--r--engines/mohawk/graphics.cpp1002
-rw-r--r--engines/mohawk/graphics.h199
-rw-r--r--engines/mohawk/installer_archive.cpp6
-rw-r--r--engines/mohawk/installer_archive.h6
-rw-r--r--engines/mohawk/livingbooks.cpp306
-rw-r--r--engines/mohawk/livingbooks.h67
-rw-r--r--engines/mohawk/livingbooks_code.cpp483
-rw-r--r--engines/mohawk/livingbooks_code.h49
-rw-r--r--engines/mohawk/livingbooks_graphics.cpp102
-rw-r--r--engines/mohawk/livingbooks_graphics.h52
-rw-r--r--engines/mohawk/livingbooks_lbx.cpp141
-rw-r--r--engines/mohawk/livingbooks_lbx.h (renamed from engines/m4/saveload.h)37
-rw-r--r--engines/mohawk/module.mk5
-rw-r--r--engines/mohawk/myst.cpp2
-rw-r--r--engines/mohawk/myst.h2
-rw-r--r--engines/mohawk/myst_areas.cpp2
-rw-r--r--engines/mohawk/myst_areas.h8
-rw-r--r--engines/mohawk/myst_graphics.cpp493
-rw-r--r--engines/mohawk/myst_graphics.h102
-rw-r--r--engines/mohawk/myst_scripts.cpp2
-rw-r--r--engines/mohawk/myst_scripts.h2
-rw-r--r--engines/mohawk/myst_stacks/channelwood.cpp2
-rw-r--r--engines/mohawk/myst_stacks/credits.cpp2
-rw-r--r--engines/mohawk/myst_stacks/demo.cpp2
-rw-r--r--engines/mohawk/myst_stacks/intro.cpp2
-rw-r--r--engines/mohawk/myst_stacks/mechanical.cpp2
-rw-r--r--engines/mohawk/myst_stacks/myst.cpp12
-rw-r--r--engines/mohawk/myst_stacks/preview.cpp2
-rw-r--r--engines/mohawk/myst_stacks/slides.cpp2
-rw-r--r--engines/mohawk/myst_stacks/stoneship.cpp8
-rw-r--r--engines/mohawk/riven.cpp2
-rw-r--r--engines/mohawk/riven_external.cpp2
-rw-r--r--engines/mohawk/riven_external.h2
-rw-r--r--engines/mohawk/riven_graphics.cpp445
-rw-r--r--engines/mohawk/riven_graphics.h110
-rw-r--r--engines/mohawk/riven_scripts.cpp2
-rw-r--r--engines/mohawk/riven_scripts.h5
-rw-r--r--engines/mohawk/video.cpp11
-rw-r--r--engines/mohawk/video.h1
-rw-r--r--engines/neverhood/blbarchive.cpp2
-rw-r--r--engines/parallaction/balloons.cpp4
-rw-r--r--engines/parallaction/callables_br.cpp14
-rw-r--r--engines/parallaction/callables_ns.cpp16
-rw-r--r--engines/parallaction/debug.cpp6
-rw-r--r--engines/parallaction/dialogue.cpp2
-rw-r--r--engines/parallaction/disk.cpp4
-rw-r--r--engines/parallaction/disk_br.cpp10
-rw-r--r--engines/parallaction/disk_ns.cpp30
-rw-r--r--engines/parallaction/exec.h6
-rw-r--r--engines/parallaction/font.cpp16
-rw-r--r--engines/parallaction/gfxbase.cpp8
-rw-r--r--engines/parallaction/graphics.cpp56
-rw-r--r--engines/parallaction/graphics.h8
-rw-r--r--engines/parallaction/gui.h2
-rw-r--r--engines/parallaction/gui_br.cpp4
-rw-r--r--engines/parallaction/inventory.cpp4
-rw-r--r--engines/parallaction/inventory.h2
-rw-r--r--engines/parallaction/objects.cpp4
-rw-r--r--engines/parallaction/parallaction.cpp2
-rw-r--r--engines/parallaction/parallaction.h74
-rw-r--r--engines/parallaction/parallaction_br.cpp2
-rw-r--r--engines/parallaction/parser.h10
-rw-r--r--engines/parallaction/parser_br.cpp16
-rw-r--r--engines/parallaction/parser_ns.cpp6
-rw-r--r--engines/parallaction/saveload.cpp2
-rw-r--r--engines/parallaction/sound_br.cpp2
-rw-r--r--engines/parallaction/sound_ns.cpp2
-rw-r--r--engines/queen/input.h2
-rw-r--r--engines/queen/logic.cpp8
-rw-r--r--engines/queen/music.cpp2
-rw-r--r--engines/queen/queen.cpp1
-rw-r--r--engines/queen/resource.h3
-rw-r--r--engines/queen/talk.cpp9
-rw-r--r--engines/saga/animation.cpp2
-rw-r--r--engines/saga/detection.cpp2
-rw-r--r--engines/saga/detection_tables.h38
-rw-r--r--engines/saga/gfx.cpp4
-rw-r--r--engines/saga/interface.cpp4
-rw-r--r--engines/saga/isomap.cpp4
-rw-r--r--engines/saga/resource.h2
-rw-r--r--engines/saga/saga.h12
-rw-r--r--engines/saga/saveload.cpp2
-rw-r--r--engines/saga/scene.cpp2
-rw-r--r--engines/saga/script.h4
-rw-r--r--engines/saga/sndres.cpp225
-rw-r--r--engines/saga/sndres.h2
-rw-r--r--engines/saga/sound.cpp35
-rw-r--r--engines/saga/sound.h19
-rw-r--r--engines/sci/console.cpp92
-rw-r--r--engines/sci/detection.cpp22
-rw-r--r--engines/sci/detection_tables.h384
-rw-r--r--engines/sci/engine/features.cpp9
-rw-r--r--engines/sci/engine/kernel.cpp26
-rw-r--r--engines/sci/engine/kernel.h1
-rw-r--r--engines/sci/engine/kernel_tables.h20
-rw-r--r--engines/sci/engine/kfile.cpp45
-rw-r--r--engines/sci/engine/kgraphics.cpp160
-rw-r--r--engines/sci/engine/klists.cpp20
-rw-r--r--engines/sci/engine/kpathing.cpp1
-rw-r--r--engines/sci/engine/kscripts.cpp10
-rw-r--r--engines/sci/engine/ksound.cpp7
-rw-r--r--engines/sci/engine/kstring.cpp34
-rw-r--r--engines/sci/engine/message.cpp2
-rw-r--r--engines/sci/engine/savegame.cpp32
-rw-r--r--engines/sci/engine/script.cpp27
-rw-r--r--engines/sci/engine/script.h18
-rw-r--r--engines/sci/engine/script_patches.cpp62
-rw-r--r--engines/sci/engine/scriptdebug.cpp16
-rw-r--r--engines/sci/engine/seg_manager.cpp34
-rw-r--r--engines/sci/engine/seg_manager.h7
-rw-r--r--engines/sci/engine/segment.cpp13
-rw-r--r--engines/sci/engine/segment.h2
-rw-r--r--engines/sci/engine/selector.cpp1
-rw-r--r--engines/sci/engine/selector.h1
-rw-r--r--engines/sci/engine/state.cpp8
-rw-r--r--engines/sci/engine/vm.cpp31
-rw-r--r--engines/sci/engine/vm.h22
-rw-r--r--engines/sci/engine/vm_types.h20
-rw-r--r--engines/sci/engine/workarounds.cpp2
-rw-r--r--engines/sci/event.cpp13
-rw-r--r--engines/sci/graphics/controls16.cpp (renamed from engines/sci/graphics/controls.cpp)30
-rw-r--r--engines/sci/graphics/controls16.h (renamed from engines/sci/graphics/controls.h)10
-rw-r--r--engines/sci/graphics/controls32.cpp204
-rw-r--r--engines/sci/graphics/controls32.h51
-rw-r--r--engines/sci/graphics/coordadjuster.cpp16
-rw-r--r--engines/sci/graphics/coordadjuster.h4
-rw-r--r--engines/sci/graphics/cursor.cpp53
-rw-r--r--engines/sci/graphics/cursor.h15
-rw-r--r--engines/sci/graphics/frameout.cpp401
-rw-r--r--engines/sci/graphics/frameout.h13
-rw-r--r--engines/sci/graphics/palette.cpp9
-rw-r--r--engines/sci/graphics/screen.cpp8
-rw-r--r--engines/sci/graphics/text16.cpp2
-rw-r--r--engines/sci/graphics/text32.cpp130
-rw-r--r--engines/sci/graphics/text32.h8
-rw-r--r--engines/sci/graphics/transitions.cpp14
-rw-r--r--engines/sci/graphics/view.cpp5
-rw-r--r--engines/sci/module.mk4
-rw-r--r--engines/sci/parser/said.cpp2
-rw-r--r--engines/sci/parser/vocabulary.cpp2
-rw-r--r--engines/sci/resource.cpp31
-rw-r--r--engines/sci/resource.h2
-rw-r--r--engines/sci/resource_audio.cpp36
-rw-r--r--engines/sci/sci.cpp18
-rw-r--r--engines/sci/sci.h11
-rw-r--r--engines/sci/sound/drivers/adlib.cpp2
-rw-r--r--engines/sci/sound/drivers/amigamac.cpp61
-rw-r--r--engines/sci/sound/drivers/fmtowns.cpp652
-rw-r--r--engines/sci/sound/drivers/mididriver.h1
-rw-r--r--engines/sci/sound/midiparser_sci.cpp15
-rw-r--r--engines/sci/sound/music.cpp48
-rw-r--r--engines/sci/sound/music.h8
-rw-r--r--engines/sci/sound/soundcmd.cpp30
-rw-r--r--engines/sci/sound/soundcmd.h4
-rw-r--r--engines/scumm/actor.cpp431
-rw-r--r--engines/scumm/actor.h60
-rw-r--r--engines/scumm/boxes.cpp26
-rw-r--r--engines/scumm/boxes.h2
-rw-r--r--engines/scumm/charset-fontdata.cpp2
-rw-r--r--engines/scumm/costume.cpp243
-rw-r--r--engines/scumm/costume.h18
-rw-r--r--engines/scumm/cursor.cpp2
-rw-r--r--engines/scumm/debugger.cpp10
-rw-r--r--engines/scumm/detection.cpp37
-rw-r--r--engines/scumm/detection.h3
-rw-r--r--engines/scumm/detection_tables.h214
-rw-r--r--engines/scumm/dialogs.cpp34
-rw-r--r--engines/scumm/dialogs.h21
-rw-r--r--engines/scumm/gfx.cpp106
-rw-r--r--engines/scumm/gfx.h12
-rw-r--r--engines/scumm/gfxARM.s4
-rw-r--r--engines/scumm/gfx_towns.cpp12
-rw-r--r--engines/scumm/he/script_v80he.cpp39
-rw-r--r--engines/scumm/he/script_v90he.cpp3
-rw-r--r--engines/scumm/he/sound_he.cpp22
-rw-r--r--engines/scumm/he/sprite_he.cpp7
-rw-r--r--engines/scumm/he/wiz_he.cpp10
-rw-r--r--engines/scumm/help.h1
-rw-r--r--engines/scumm/imuse/imuse_player.cpp1
-rw-r--r--engines/scumm/input.cpp17
-rw-r--r--engines/scumm/module.mk1
-rw-r--r--engines/scumm/object.cpp179
-rw-r--r--engines/scumm/object.h20
-rw-r--r--engines/scumm/palette.cpp2
-rw-r--r--engines/scumm/player_apple2.cpp500
-rw-r--r--engines/scumm/player_apple2.h297
-rw-r--r--engines/scumm/player_nes.cpp2
-rw-r--r--engines/scumm/player_pce.cpp22
-rw-r--r--engines/scumm/player_pce.h1
-rw-r--r--engines/scumm/player_sid.cpp6
-rw-r--r--engines/scumm/player_sid.h3
-rw-r--r--engines/scumm/player_towns.cpp9
-rw-r--r--engines/scumm/player_v1.cpp4
-rw-r--r--engines/scumm/player_v2a.cpp244
-rw-r--r--engines/scumm/player_v2a.h2
-rw-r--r--engines/scumm/resource.cpp4
-rw-r--r--engines/scumm/room.cpp2
-rw-r--r--engines/scumm/saveload.cpp68
-rw-r--r--engines/scumm/saveload.h6
-rw-r--r--engines/scumm/script.cpp197
-rw-r--r--engines/scumm/script_v0.cpp540
-rw-r--r--engines/scumm/script_v2.cpp167
-rw-r--r--engines/scumm/script_v4.cpp4
-rw-r--r--engines/scumm/script_v5.cpp70
-rw-r--r--engines/scumm/script_v8.cpp2
-rw-r--r--engines/scumm/scumm-md5.h27
-rw-r--r--engines/scumm/scumm.cpp63
-rw-r--r--engines/scumm/scumm.h30
-rw-r--r--engines/scumm/scumm_v0.h93
-rw-r--r--engines/scumm/scumm_v2.h13
-rw-r--r--engines/scumm/scumm_v5.h2
-rw-r--r--engines/scumm/smush/smush_player.cpp4
-rw-r--r--engines/scumm/sound.cpp117
-rw-r--r--engines/scumm/sound.h5
-rw-r--r--engines/scumm/string.cpp10
-rw-r--r--engines/scumm/vars.cpp4
-rw-r--r--engines/scumm/verbs.cpp806
-rw-r--r--engines/scumm/verbs.h28
-rw-r--r--engines/sky/autoroute.cpp2
-rw-r--r--engines/sky/compact.cpp34
-rw-r--r--engines/sky/control.cpp60
-rw-r--r--engines/sky/control.h4
-rw-r--r--engines/sky/detection.cpp10
-rw-r--r--engines/sky/disk.cpp4
-rw-r--r--engines/sky/intro.cpp26
-rw-r--r--engines/sky/logic.cpp362
-rw-r--r--engines/sky/mouse.cpp2
-rw-r--r--engines/sky/music/adlibchannel.cpp10
-rw-r--r--engines/sky/music/adlibmusic.cpp3
-rw-r--r--engines/sky/music/adlibmusic.h2
-rw-r--r--engines/sky/music/gmmusic.cpp4
-rw-r--r--engines/sky/music/gmmusic.h2
-rw-r--r--engines/sky/music/mt32music.cpp4
-rw-r--r--engines/sky/music/mt32music.h2
-rw-r--r--engines/sky/music/musicbase.cpp60
-rw-r--r--engines/sky/music/musicbase.h6
-rw-r--r--engines/sky/sky.cpp8
-rw-r--r--engines/sky/text.cpp4
-rw-r--r--engines/sword1/animation.cpp318
-rw-r--r--engines/sword1/animation.h23
-rw-r--r--engines/sword1/detection.cpp13
-rw-r--r--engines/sword1/logic.cpp6
-rw-r--r--engines/sword1/sound.cpp39
-rw-r--r--engines/sword1/sound.h10
-rw-r--r--engines/sword1/staticres.cpp2
-rw-r--r--engines/sword1/sword1.cpp5
-rw-r--r--engines/sword1/sword1.h2
-rw-r--r--engines/sword1/swordres.h592
-rw-r--r--engines/sword2/animation.cpp140
-rw-r--r--engines/sword2/animation.h17
-rw-r--r--engines/sword2/console.cpp2
-rw-r--r--engines/sword2/function.cpp4
-rw-r--r--engines/sword2/music.cpp8
-rw-r--r--engines/sword2/sprite.cpp18
-rw-r--r--engines/sword2/sword2.cpp6
-rw-r--r--engines/sword25/detection_tables.h33
-rw-r--r--engines/sword25/gfx/image/art.cpp136
-rw-r--r--engines/sword25/gfx/image/renderedimage.cpp4
-rw-r--r--engines/sword25/gfx/renderobject.h2
-rw-r--r--engines/sword25/gfx/screenshot.cpp2
-rw-r--r--engines/sword25/util/lua/lbaselib.cpp7
-rw-r--r--engines/sword25/util/lua/llex.cpp26
-rw-r--r--engines/sword25/util/lua/lobject.cpp8
-rw-r--r--engines/sword25/util/lua/lstrlib.cpp2
-rw-r--r--engines/sword25/util/lua/luaconf.h2
-rw-r--r--engines/sword25/util/lua/scummvm_file.cpp2
-rw-r--r--engines/sword25/util/pluto/pluto.cpp26
-rw-r--r--engines/teenagent/callbacks.cpp24
-rw-r--r--engines/teenagent/console.cpp64
-rw-r--r--engines/teenagent/console.h3
-rw-r--r--engines/teenagent/detection.cpp2
-rw-r--r--engines/teenagent/music.cpp1
-rw-r--r--engines/teenagent/music.h2
-rw-r--r--engines/teenagent/surface.h1
-rw-r--r--engines/testbed/detection.cpp2
-rw-r--r--engines/tinsel/background.cpp38
-rw-r--r--engines/tinsel/bg.cpp98
-rw-r--r--engines/tinsel/cursor.cpp298
-rw-r--r--engines/tinsel/detection.cpp2
-rw-r--r--engines/tinsel/detection_tables.h48
-rw-r--r--engines/tinsel/dialogs.cpp2249
-rw-r--r--engines/tinsel/drives.cpp38
-rw-r--r--engines/tinsel/events.cpp86
-rw-r--r--engines/tinsel/font.cpp32
-rw-r--r--engines/tinsel/graphics.cpp12
-rw-r--r--engines/tinsel/handle.cpp108
-rw-r--r--engines/tinsel/heapmem.cpp74
-rw-r--r--engines/tinsel/mareels.cpp34
-rw-r--r--engines/tinsel/move.cpp40
-rw-r--r--engines/tinsel/music.cpp73
-rw-r--r--engines/tinsel/palette.cpp132
-rw-r--r--engines/tinsel/pcode.cpp98
-rw-r--r--engines/tinsel/pdisplay.cpp54
-rw-r--r--engines/tinsel/play.cpp50
-rw-r--r--engines/tinsel/rince.cpp92
-rw-r--r--engines/tinsel/saveload.cpp209
-rw-r--r--engines/tinsel/savescn.cpp140
-rw-r--r--engines/tinsel/scene.cpp60
-rw-r--r--engines/tinsel/sched.cpp64
-rw-r--r--engines/tinsel/scroll.cpp292
-rw-r--r--engines/tinsel/scroll.h6
-rw-r--r--engines/tinsel/sound.cpp34
-rw-r--r--engines/tinsel/strres.cpp56
-rw-r--r--engines/tinsel/strres.h2
-rw-r--r--engines/tinsel/sysvar.cpp20
-rw-r--r--engines/tinsel/text.cpp8
-rw-r--r--engines/tinsel/timers.cpp50
-rw-r--r--engines/tinsel/tinlib.cpp108
-rw-r--r--engines/tinsel/tinsel.cpp174
-rw-r--r--engines/tinsel/token.cpp28
-rw-r--r--engines/toltecs/animation.cpp164
-rw-r--r--engines/toltecs/animation.h (renamed from engines/m4/staticres.cpp)74
-rw-r--r--engines/toltecs/detection.cpp306
-rw-r--r--engines/toltecs/menu.cpp613
-rw-r--r--engines/toltecs/menu.h167
-rw-r--r--engines/toltecs/microtiles.cpp215
-rw-r--r--engines/toltecs/microtiles.h61
-rw-r--r--engines/toltecs/module.mk28
-rw-r--r--engines/toltecs/movie.cpp289
-rw-r--r--engines/toltecs/movie.h59
-rw-r--r--engines/toltecs/music.cpp145
-rw-r--r--engines/toltecs/music.h (renamed from engines/m4/midi.h)46
-rw-r--r--engines/toltecs/palette.cpp231
-rw-r--r--engines/toltecs/palette.h85
-rw-r--r--engines/toltecs/render.cpp311
-rw-r--r--engines/toltecs/render.h99
-rw-r--r--engines/toltecs/resource.cpp128
-rw-r--r--engines/toltecs/resource.h85
-rw-r--r--engines/toltecs/saveload.cpp233
-rw-r--r--engines/toltecs/screen.cpp808
-rw-r--r--engines/toltecs/screen.h251
-rw-r--r--engines/toltecs/script.cpp1108
-rw-r--r--engines/toltecs/script.h184
-rw-r--r--engines/toltecs/segmap.cpp408
-rw-r--r--engines/toltecs/segmap.h116
-rw-r--r--engines/toltecs/sound.cpp224
-rw-r--r--engines/toltecs/sound.h77
-rw-r--r--engines/toltecs/sprite.cpp509
-rw-r--r--engines/toltecs/toltecs.cpp641
-rw-r--r--engines/toltecs/toltecs.h215
-rw-r--r--engines/toon/anim.cpp2
-rw-r--r--engines/toon/anim.h2
-rw-r--r--engines/toon/audio.cpp8
-rw-r--r--engines/toon/audio.h6
-rw-r--r--engines/toon/character.cpp10
-rw-r--r--engines/toon/character.h10
-rw-r--r--engines/toon/detection.cpp21
-rw-r--r--engines/toon/font.cpp6
-rw-r--r--engines/toon/font.h6
-rw-r--r--engines/toon/hotspot.cpp2
-rw-r--r--engines/toon/hotspot.h2
-rw-r--r--engines/toon/movie.cpp2
-rw-r--r--engines/toon/movie.h2
-rw-r--r--engines/toon/path.cpp9
-rw-r--r--engines/toon/picture.cpp2
-rw-r--r--engines/toon/picture.h2
-rw-r--r--engines/toon/resource.cpp20
-rw-r--r--engines/toon/resource.h20
-rw-r--r--engines/toon/script_func.h2
-rw-r--r--engines/toon/text.cpp2
-rw-r--r--engines/toon/text.h2
-rw-r--r--engines/toon/toon.cpp110
-rw-r--r--engines/toon/toon.h10
-rw-r--r--engines/touche/detection.cpp16
-rw-r--r--engines/touche/graphics.h2
-rw-r--r--engines/touche/resource.cpp10
-rw-r--r--engines/touche/saveload.cpp26
-rw-r--r--engines/touche/staticres.cpp7
-rw-r--r--engines/touche/touche.cpp8
-rw-r--r--engines/touche/touche.h3
-rw-r--r--engines/tsage/blue_force/blueforce_dialogs.cpp96
-rw-r--r--engines/tsage/blue_force/blueforce_dialogs.h14
-rw-r--r--engines/tsage/blue_force/blueforce_logic.cpp142
-rw-r--r--engines/tsage/blue_force/blueforce_logic.h15
-rw-r--r--engines/tsage/blue_force/blueforce_scenes0.cpp274
-rw-r--r--engines/tsage/blue_force/blueforce_scenes0.h11
-rw-r--r--engines/tsage/blue_force/blueforce_scenes1.cpp403
-rw-r--r--engines/tsage/blue_force/blueforce_scenes1.h50
-rw-r--r--engines/tsage/blue_force/blueforce_scenes2.cpp114
-rw-r--r--engines/tsage/blue_force/blueforce_scenes3.cpp404
-rw-r--r--engines/tsage/blue_force/blueforce_scenes3.h23
-rw-r--r--engines/tsage/blue_force/blueforce_scenes4.cpp216
-rw-r--r--engines/tsage/blue_force/blueforce_scenes4.h6
-rw-r--r--engines/tsage/blue_force/blueforce_scenes5.cpp151
-rw-r--r--engines/tsage/blue_force/blueforce_scenes5.h3
-rw-r--r--engines/tsage/blue_force/blueforce_scenes6.cpp62
-rw-r--r--engines/tsage/blue_force/blueforce_scenes6.h2
-rw-r--r--engines/tsage/blue_force/blueforce_scenes7.cpp54
-rw-r--r--engines/tsage/blue_force/blueforce_scenes7.h5
-rw-r--r--engines/tsage/blue_force/blueforce_scenes8.cpp140
-rw-r--r--engines/tsage/blue_force/blueforce_scenes9.cpp667
-rw-r--r--engines/tsage/blue_force/blueforce_scenes9.h40
-rw-r--r--engines/tsage/converse.cpp136
-rw-r--r--engines/tsage/converse.h14
-rw-r--r--engines/tsage/core.cpp550
-rw-r--r--engines/tsage/core.h55
-rw-r--r--engines/tsage/debugger.cpp307
-rw-r--r--engines/tsage/debugger.h28
-rw-r--r--engines/tsage/detection.cpp1
-rw-r--r--engines/tsage/detection_tables.h26
-rw-r--r--engines/tsage/dialogs.cpp236
-rw-r--r--engines/tsage/dialogs.h41
-rw-r--r--engines/tsage/events.cpp48
-rw-r--r--engines/tsage/events.h41
-rw-r--r--engines/tsage/globals.cpp276
-rw-r--r--engines/tsage/globals.h84
-rw-r--r--engines/tsage/graphics.cpp201
-rw-r--r--engines/tsage/graphics.h25
-rw-r--r--engines/tsage/module.mk4
-rw-r--r--engines/tsage/resources.cpp143
-rw-r--r--engines/tsage/resources.h9
-rw-r--r--engines/tsage/ringworld/ringworld_dialogs.cpp240
-rw-r--r--engines/tsage/ringworld/ringworld_dialogs.h39
-rw-r--r--engines/tsage/ringworld/ringworld_logic.cpp61
-rw-r--r--engines/tsage/ringworld/ringworld_logic.h4
-rw-r--r--engines/tsage/ringworld/ringworld_scenes10.cpp11
-rw-r--r--engines/tsage/ringworld/ringworld_scenes10.h2
-rw-r--r--engines/tsage/ringworld/ringworld_scenes3.cpp6
-rw-r--r--engines/tsage/ringworld/ringworld_scenes5.cpp26
-rw-r--r--engines/tsage/ringworld/ringworld_scenes5.h8
-rw-r--r--engines/tsage/ringworld/ringworld_scenes6.cpp2
-rw-r--r--engines/tsage/ringworld/ringworld_scenes8.cpp46
-rw-r--r--engines/tsage/ringworld/ringworld_scenes8.h2
-rw-r--r--engines/tsage/ringworld2/ringworld2_dialogs.cpp262
-rw-r--r--engines/tsage/ringworld2/ringworld2_dialogs.h25
-rw-r--r--engines/tsage/ringworld2/ringworld2_logic.cpp1583
-rw-r--r--engines/tsage/ringworld2/ringworld2_logic.h219
-rw-r--r--engines/tsage/ringworld2/ringworld2_scenes0.cpp7311
-rw-r--r--engines/tsage/ringworld2/ringworld2_scenes0.h843
-rw-r--r--engines/tsage/ringworld2/ringworld2_scenes1.cpp14622
-rw-r--r--engines/tsage/ringworld2/ringworld2_scenes1.h1242
-rw-r--r--engines/tsage/ringworld2/ringworld2_scenes2.cpp4527
-rw-r--r--engines/tsage/ringworld2/ringworld2_scenes2.h672
-rw-r--r--engines/tsage/ringworld2/ringworld2_scenes3.cpp5603
-rw-r--r--engines/tsage/ringworld2/ringworld2_scenes3.h868
-rw-r--r--engines/tsage/ringworld2/ringworld2_speakers.cpp2968
-rw-r--r--engines/tsage/ringworld2/ringworld2_speakers.h637
-rw-r--r--engines/tsage/saveload.cpp3
-rw-r--r--engines/tsage/saveload.h2
-rw-r--r--engines/tsage/scenes.cpp17
-rw-r--r--engines/tsage/sound.cpp22
-rw-r--r--engines/tsage/sound.h14
-rw-r--r--engines/tsage/staticres.cpp436
-rw-r--r--engines/tsage/staticres.h238
-rw-r--r--engines/tsage/tsage.cpp14
-rw-r--r--engines/tsage/tsage.h3
-rw-r--r--engines/tsage/user_interface.cpp95
-rw-r--r--engines/tsage/user_interface.h1
-rw-r--r--engines/tucker/detection.cpp16
-rw-r--r--engines/tucker/locations.cpp11
-rw-r--r--engines/tucker/saveload.cpp2
-rw-r--r--engines/tucker/tucker.h2
-rw-r--r--graphics/VectorRenderer.cpp28
-rw-r--r--graphics/VectorRenderer.h3
-rw-r--r--graphics/VectorRendererSpec.cpp1194
-rw-r--r--graphics/VectorRendererSpec.h35
-rw-r--r--graphics/cursorman.cpp4
-rw-r--r--graphics/font.cpp44
-rw-r--r--graphics/font.h9
-rw-r--r--graphics/fontman.cpp72
-rw-r--r--graphics/fontman.h22
-rw-r--r--graphics/fonts/bdf.cpp1056
-rw-r--r--graphics/fonts/bdf.h55
-rw-r--r--graphics/fonts/consolefont.cpp11501
-rw-r--r--graphics/fonts/newfont.cpp15069
-rw-r--r--graphics/fonts/newfont_big.cpp11368
-rw-r--r--graphics/fonts/ttf.cpp483
-rw-r--r--graphics/fonts/ttf.h (renamed from engines/m4/staticres.h)38
-rw-r--r--graphics/iff.cpp4
-rw-r--r--graphics/imagedec.cpp2
-rw-r--r--graphics/jpeg.cpp183
-rw-r--r--graphics/jpeg.h5
-rw-r--r--graphics/module.mk1
-rw-r--r--graphics/pict.cpp11
-rw-r--r--graphics/png.cpp4
-rw-r--r--graphics/png.h12
-rw-r--r--graphics/scaler/scale2x.h4
-rw-r--r--graphics/scaler/scale3x.h4
-rw-r--r--graphics/scaler/scalebit.h4
-rw-r--r--graphics/scaler/thumbnail_intern.cpp10
-rw-r--r--graphics/sjis.h2
-rw-r--r--graphics/surface.cpp8
-rw-r--r--graphics/yuv_to_rgb.h2
-rw-r--r--gui/ThemeEngine.cpp187
-rw-r--r--gui/ThemeEngine.h20
-rw-r--r--gui/ThemeParser.cpp47
-rw-r--r--gui/ThemeParser.h3
-rw-r--r--gui/about.cpp2
-rw-r--r--gui/browser_osx.mm6
-rw-r--r--gui/console.cpp2
-rw-r--r--gui/credits.h27
-rw-r--r--gui/debugger.cpp9
-rw-r--r--gui/dialog.cpp21
-rw-r--r--gui/gui-manager.cpp69
-rw-r--r--gui/gui-manager.h3
-rw-r--r--gui/launcher.cpp89
-rw-r--r--gui/launcher.h1
-rw-r--r--gui/object.cpp20
-rw-r--r--gui/object.h2
-rw-r--r--gui/options.cpp165
-rw-r--r--gui/options.h9
-rw-r--r--gui/saveload.cpp2
-rw-r--r--gui/themes/default.inc1794
-rw-r--r--gui/themes/fonts/FreeMonoBold.ttfbin0 -> 173608 bytes
-rw-r--r--gui/themes/fonts/FreeSans.ttfbin0 -> 714456 bytes
-rw-r--r--gui/themes/fonts/FreeSansBold.ttfbin0 -> 359272 bytes
-rw-r--r--gui/themes/fonts/README2
-rw-r--r--gui/themes/scummclassic.zipbin91156 -> 86033 bytes
-rw-r--r--gui/themes/scummclassic/THEMERC2
-rw-r--r--gui/themes/scummclassic/clR6x12-iso-8859-2.fccbin6403 -> 3724 bytes
-rw-r--r--gui/themes/scummclassic/clR6x12-iso-8859-5.fccbin6403 -> 3724 bytes
-rw-r--r--gui/themes/scummclassic/classic_gfx.stx226
-rw-r--r--gui/themes/scummclassic/classic_layout.stx41
-rw-r--r--gui/themes/scummclassic/classic_layout_lowres.stx41
-rw-r--r--gui/themes/scummclassic/fixed5x8-iso-8859-2.fccbin4619 -> 2832 bytes
-rw-r--r--gui/themes/scummclassic/fixed5x8-iso-8859-5.fccbin3985 -> 3011 bytes
-rw-r--r--gui/themes/scummclassic/helvb12-iso-8859-2.fccbin5727 -> 4104 bytes
-rw-r--r--gui/themes/scummclassic/helvb12-iso-8859-5.fccbin5234 -> 3968 bytes
-rw-r--r--gui/themes/scummmodern.zipbin198479 -> 1441312 bytes
-rw-r--r--gui/themes/scummmodern/FreeMonoBold.ttfbin0 -> 173608 bytes
-rw-r--r--gui/themes/scummmodern/FreeSans.ttfbin0 -> 714456 bytes
-rw-r--r--gui/themes/scummmodern/FreeSansBold.ttfbin0 -> 359272 bytes
-rw-r--r--gui/themes/scummmodern/THEMERC2
-rw-r--r--gui/themes/scummmodern/clR6x12-iso-8859-2.fccbin6403 -> 3724 bytes
-rw-r--r--gui/themes/scummmodern/clR6x12-iso-8859-5.fccbin6403 -> 3724 bytes
-rw-r--r--gui/themes/scummmodern/eraser.bmpbin0 -> 824 bytes
-rw-r--r--gui/themes/scummmodern/fixed5x8-iso-8859-2.fccbin4619 -> 2832 bytes
-rw-r--r--gui/themes/scummmodern/fixed5x8-iso-8859-5.fccbin3985 -> 3011 bytes
-rw-r--r--gui/themes/scummmodern/helvb12-iso-8859-1.fccbin5615 -> 4102 bytes
-rw-r--r--gui/themes/scummmodern/helvb12-iso-8859-2.fccbin5727 -> 4104 bytes
-rw-r--r--gui/themes/scummmodern/helvb12-iso-8859-5.fccbin5234 -> 3968 bytes
-rw-r--r--gui/themes/scummmodern/scummmodern_gfx.stx269
-rw-r--r--gui/themes/scummmodern/scummmodern_layout.stx41
-rw-r--r--gui/themes/scummmodern/scummmodern_layout_lowres.stx41
-rw-r--r--gui/themes/scummmodern/search.bmpbin872 -> 822 bytes
-rwxr-xr-xgui/themes/scummtheme.py2
-rw-r--r--gui/themes/translations.datbin273189 -> 289269 bytes
-rw-r--r--gui/widget.cpp53
-rw-r--r--gui/widget.h15
-rw-r--r--gui/widgets/editable.cpp11
-rw-r--r--gui/widgets/edittext.cpp9
-rw-r--r--gui/widgets/list.cpp1
-rw-r--r--gui/widgets/scrollbar.cpp58
-rw-r--r--gui/widgets/scrollbar.h6
-rw-r--r--po/POTFILES4
-rw-r--r--po/ca_ES.po748
-rw-r--r--po/cs_CZ.po740
-rw-r--r--po/da_DA.po762
-rw-r--r--po/de_DE.po763
-rw-r--r--po/es_ES.po767
-rw-r--r--po/fr_FR.po747
-rw-r--r--po/hu_HU.po736
-rw-r--r--po/iso-8859-2.cp320
-rw-r--r--po/iso-8859-5.cp320
-rw-r--r--po/it_IT.po758
-rw-r--r--po/module.mk7
-rw-r--r--po/nb_NO.po762
-rw-r--r--po/nn_NO.po754
-rw-r--r--po/pl_PL.po1059
-rw-r--r--po/pt_BR.po750
-rw-r--r--po/ru_RU.po763
-rw-r--r--po/scummvm.pot713
-rw-r--r--po/se_SE.po1045
-rw-r--r--po/uk_UA.po752
-rw-r--r--ports.mk52
-rw-r--r--test/audio/helper.h57
-rw-r--r--test/audio/raw.h120
-rw-r--r--test/common/fixedstack.h14
-rw-r--r--test/common/memoryreadstream.h16
-rw-r--r--test/common/pack.h2
-rw-r--r--test/common/stack.h12
-rw-r--r--test/common/subreadstream.h18
-rw-r--r--test/cxxtest/cxxtest/ValueTraits.h4
-rw-r--r--video/avi_decoder.h4
-rw-r--r--video/bink_decoder.cpp64
-rw-r--r--video/bink_decoder.h15
-rw-r--r--video/codecs/cinepak.h4
-rw-r--r--video/codecs/mjpeg.h1
-rw-r--r--video/coktel_decoder.cpp287
-rw-r--r--video/coktel_decoder.h16
-rw-r--r--video/dxa_decoder.cpp12
-rw-r--r--video/dxa_decoder.h4
-rw-r--r--video/module.mk1
-rw-r--r--video/psx_decoder.cpp697
-rw-r--r--video/psx_decoder.h128
-rw-r--r--video/qt_decoder.cpp806
-rw-r--r--video/qt_decoder.h114
1494 files changed, 174058 insertions, 113608 deletions
diff --git a/AUTHORS b/AUTHORS
index ae6b4fc76d..86f5c3e023 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -32,7 +32,7 @@ ScummVM Team
Max Horn - (retired)
Travis Howell
Pawel Kolodziejski - Codecs, iMUSE, Smush, etc.
- Gregory Montoir
+ Gregory Montoir - (retired)
Eugene Sandulenko - FT INSANE, MM NES, MM C64, game detection,
Herc/CGA
Ludvig Strigeus - (retired)
@@ -40,7 +40,7 @@ ScummVM Team
HE:
Jonathan Gray - (retired)
Travis Howell
- Gregory Montoir
+ Gregory Montoir - (retired)
Eugene Sandulenko
AGI:
@@ -67,10 +67,13 @@ ScummVM Team
Cine:
Vincent Hamm - (retired)
Pawel Kolodziejski
- Gregory Montoir
+ Gregory Montoir - (retired)
Kari Salminen
Eugene Sandulenko
+ Composer:
+ Alyssa Milburn
+
CruisE:
Paul Gilbert
Vincent Hamm - (retired)
@@ -86,7 +89,7 @@ ScummVM Team
DreamWeb:
Torbjorn Andersson
Bertrand Augereau
- Vladimir Menshakov
+ Vladimir Menshakov - (retired)
Gob:
Torbjorn Andersson
@@ -108,7 +111,7 @@ ScummVM Team
Torbjorn Andersson - VQA Player
Oystein Eftevaag
Florian Kagerer
- Gregory Montoir
+ Gregory Montoir - (retired)
Johannes Schickel
Lastexpress:
@@ -119,12 +122,6 @@ ScummVM Team
Lure:
Paul Gilbert
- M4:
- Torbjorn Andersson
- Paul Gilbert
- Benjamin Haisch
- Filippos Karapetis
-
MADE:
Benjamin Haisch
Filippos Karapetis
@@ -142,11 +139,13 @@ ScummVM Team
Queen:
David Eriksson - (retired)
- Gregory Montoir
+ Gregory Montoir - (retired)
Joost Peters
SAGA:
Torbjorn Andersson
+ Daniel Balsom - Original engine reimplementation author
+ (retired)
Filippos Karapetis
Andrew Kurushin
Eugene Sandulenko
@@ -186,7 +185,7 @@ ScummVM Team
TeenAgent:
Robert Megone - Help with callback rewriting
- Vladimir Menshakov
+ Vladimir Menshakov - (retired)
Tinsel:
Torbjorn Andersson
@@ -201,14 +200,14 @@ ScummVM Team
Sylvain Dupont
Touche:
- Gregory Montoir
+ Gregory Montoir - (retired)
TsAGE:
Arnaud Boutonne
Paul Gilbert
Tucker:
- Gregory Montoir
+ Gregory Montoir - (retired)
Backend Teams
-------------
@@ -432,6 +431,7 @@ Other contributions
Spanish:
Tomas Maidagan
+ Jordi Vilalta Prat
Swedish:
Hampus Flink
@@ -479,6 +479,7 @@ Other contributions
Daniel Schepler - Final MI1 CD music support, initial Ogg Vorbis
support
Andre Souza - SDL-based OpenGL renderer
+ Tom Frost - WebOS port contributions
FreeSCI Contributors
--------------------
@@ -537,6 +538,7 @@ Other contributions
Special thanks to
*****************
+ Daniel Balsom - For the original Reinherit (SAGA) code
Sander Buskens - For his work on the initial reversing of Monkey2
Canadacow - For the original MT-32 emulator
Kevin Carnes - For Scumm16, the basis of ScummVM's older gfx codecs
@@ -557,6 +559,8 @@ Special thanks to
Tristan - For additional work on the original MT-32 emulator
James Woodcock - Soundtrack enhancements
+ Some icons by Yusuke Kamiyamane
+
Tony Warriner and everyone at Revolution Software Ltd. for sharing with us
the source of some of their brilliant games, allowing us to release
Beneath a Steel Sky as freeware... and generally being supportive above
diff --git a/COPYING.FREEFONT b/COPYING.FREEFONT
new file mode 100644
index 0000000000..df44319b71
--- /dev/null
+++ b/COPYING.FREEFONT
@@ -0,0 +1,690 @@
+NOTE: This license file only applies to the GNU FreeFont files:
+"FreeSansBold.ttf", "FreeSans.ttf" and "FreeMonoBold.ttf" distributed along
+with our theme files.
+
+The following license applies with this exception:
+As a special exception, if you create a document which uses this font, and
+embed this font or unaltered portions of this font into the document, this
+font does not by itself cause the resulting document to be covered by the
+GNU General Public License. This exception does not however invalidate any
+other reasons why the document might be covered by the GNU General Public
+License. If you modify this font, you may extend this exception to your
+version of the font, but you are not obligated to do so. If you do not
+wish to do so, delete this exception statement from your version.
+
+
+
+ GNU GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+ The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works. By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users. We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors. You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+ To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights. Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received. You must make sure that they, too, receive
+or can get the source code. And you must show them these terms so they
+know their rights.
+
+ Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+ For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software. For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+ Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so. This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software. The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable. Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products. If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+ Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary. To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ TERMS AND CONDITIONS
+
+ 0. Definitions.
+
+ "This License" refers to version 3 of the GNU General Public License.
+
+ "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+ "The Program" refers to any copyrightable work licensed under this
+License. Each licensee is addressed as "you". "Licensees" and
+"recipients" may be individuals or organizations.
+
+ To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy. The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+ A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+ To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy. Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+ To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies. Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+ An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License. If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+ 1. Source Code.
+
+ The "source code" for a work means the preferred form of the work
+for making modifications to it. "Object code" means any non-source
+form of a work.
+
+ A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+ The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form. A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+ The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities. However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work. For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+ The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+ The Corresponding Source for a work in source code form is that
+same work.
+
+ 2. Basic Permissions.
+
+ All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met. This License explicitly affirms your unlimited
+permission to run the unmodified Program. The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work. This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+ You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force. You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright. Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+ Conveying under any other circumstances is permitted solely under
+the conditions stated below. Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+ 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+ No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+ When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+ 4. Conveying Verbatim Copies.
+
+ You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+ You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+ 5. Conveying Modified Source Versions.
+
+ You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+ a) The work must carry prominent notices stating that you modified
+ it, and giving a relevant date.
+
+ b) The work must carry prominent notices stating that it is
+ released under this License and any conditions added under section
+ 7. This requirement modifies the requirement in section 4 to
+ "keep intact all notices".
+
+ c) You must license the entire work, as a whole, under this
+ License to anyone who comes into possession of a copy. This
+ License will therefore apply, along with any applicable section 7
+ additional terms, to the whole of the work, and all its parts,
+ regardless of how they are packaged. This License gives no
+ permission to license the work in any other way, but it does not
+ invalidate such permission if you have separately received it.
+
+ d) If the work has interactive user interfaces, each must display
+ Appropriate Legal Notices; however, if the Program has interactive
+ interfaces that do not display Appropriate Legal Notices, your
+ work need not make them do so.
+
+ A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit. Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+ 6. Conveying Non-Source Forms.
+
+ You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+ a) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by the
+ Corresponding Source fixed on a durable physical medium
+ customarily used for software interchange.
+
+ b) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by a
+ written offer, valid for at least three years and valid for as
+ long as you offer spare parts or customer support for that product
+ model, to give anyone who possesses the object code either (1) a
+ copy of the Corresponding Source for all the software in the
+ product that is covered by this License, on a durable physical
+ medium customarily used for software interchange, for a price no
+ more than your reasonable cost of physically performing this
+ conveying of source, or (2) access to copy the
+ Corresponding Source from a network server at no charge.
+
+ c) Convey individual copies of the object code with a copy of the
+ written offer to provide the Corresponding Source. This
+ alternative is allowed only occasionally and noncommercially, and
+ only if you received the object code with such an offer, in accord
+ with subsection 6b.
+
+ d) Convey the object code by offering access from a designated
+ place (gratis or for a charge), and offer equivalent access to the
+ Corresponding Source in the same way through the same place at no
+ further charge. You need not require recipients to copy the
+ Corresponding Source along with the object code. If the place to
+ copy the object code is a network server, the Corresponding Source
+ may be on a different server (operated by you or a third party)
+ that supports equivalent copying facilities, provided you maintain
+ clear directions next to the object code saying where to find the
+ Corresponding Source. Regardless of what server hosts the
+ Corresponding Source, you remain obligated to ensure that it is
+ available for as long as needed to satisfy these requirements.
+
+ e) Convey the object code using peer-to-peer transmission, provided
+ you inform other peers where the object code and Corresponding
+ Source of the work are being offered to the general public at no
+ charge under subsection 6d.
+
+ A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+ A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling. In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage. For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product. A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+ "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source. The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+ If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information. But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+ The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed. Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+ Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+ 7. Additional Terms.
+
+ "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law. If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+ When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it. (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.) You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+ Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+ a) Disclaiming warranty or limiting liability differently from the
+ terms of sections 15 and 16 of this License; or
+
+ b) Requiring preservation of specified reasonable legal notices or
+ author attributions in that material or in the Appropriate Legal
+ Notices displayed by works containing it; or
+
+ c) Prohibiting misrepresentation of the origin of that material, or
+ requiring that modified versions of such material be marked in
+ reasonable ways as different from the original version; or
+
+ d) Limiting the use for publicity purposes of names of licensors or
+ authors of the material; or
+
+ e) Declining to grant rights under trademark law for use of some
+ trade names, trademarks, or service marks; or
+
+ f) Requiring indemnification of licensors and authors of that
+ material by anyone who conveys the material (or modified versions of
+ it) with contractual assumptions of liability to the recipient, for
+ any liability that these contractual assumptions directly impose on
+ those licensors and authors.
+
+ All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10. If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term. If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+ If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+ Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+ 8. Termination.
+
+ You may not propagate or modify a covered work except as expressly
+provided under this License. Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+ However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+ Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+ Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License. If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+ 9. Acceptance Not Required for Having Copies.
+
+ You are not required to accept this License in order to receive or
+run a copy of the Program. Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance. However,
+nothing other than this License grants you permission to propagate or
+modify any covered work. These actions infringe copyright if you do
+not accept this License. Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+ 10. Automatic Licensing of Downstream Recipients.
+
+ Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License. You are not responsible
+for enforcing compliance by third parties with this License.
+
+ An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations. If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+ You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License. For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+ 11. Patents.
+
+ A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based. The
+work thus licensed is called the contributor's "contributor version".
+
+ A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version. For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+ Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+ In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement). To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+ If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients. "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+ If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+ A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License. You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+ Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+ 12. No Surrender of Others' Freedom.
+
+ If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all. For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+ 13. Use with the GNU Affero General Public License.
+
+ Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work. The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+ 14. Revised Versions of this License.
+
+ The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation. If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+ If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+ Later license versions may give you additional or different
+permissions. However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+ 15. Disclaimer of Warranty.
+
+ THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. Limitation of Liability.
+
+ IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+ 17. Interpretation of Sections 15 and 16.
+
+ If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+Also add information on how to contact you by electronic and paper mail.
+
+ If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+ <program> Copyright (C) <year> <name of author>
+ This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+ You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+<http://www.gnu.org/licenses/>.
+
+ The GNU General Public License does not permit incorporating your program
+into proprietary programs. If your program is a subroutine library, you
+may consider it more useful to permit linking proprietary applications with
+the library. If this is what you want to do, use the GNU Lesser General
+Public License instead of this License. But first, please read
+<http://www.gnu.org/philosophy/why-not-lgpl.html>.
diff --git a/COPYRIGHT b/COPYRIGHT
index f240725e1c..9de8ac6492 100644
--- a/COPYRIGHT
+++ b/COPYRIGHT
@@ -1,5 +1,5 @@
ScummVM
-Copyright (C) 2001-2011 by the following:
+Copyright (C) 2001-2012 by the following:
If you have contributed to this project then you deserve to be on this
list. Contact us (see: AUTHORS) and we'll add you.
@@ -213,3 +213,4 @@ Xanathar "xanathar"
Grant Yeager "glo_kidd"
Benjamin W. Zale "junior_aepi"
Yotam Barnoy "bluddy"
+Tom Frost "TomFrost"
diff --git a/Makefile.common b/Makefile.common
index 7c81a0d80c..2a92ba441c 100644
--- a/Makefile.common
+++ b/Makefile.common
@@ -106,7 +106,7 @@ ifdef CXX_UPDATE_DEP_FLAG
%.o: %.m
$(QUIET)$(MKDIR) $(*D)/$(DEPDIR)
- $(QUIET_CXX)$(CXX) $(CXX_UPDATE_DEP_FLAG) $(OBJCFLAGS) -c $(<) -o $*.o
+ $(QUIET_CXX)$(CXX) $(CXX_UPDATE_DEP_FLAG) $(CPPFLAGS) $(OBJCFLAGS) -c $(<) -o $*.o
# Build rule for assembler files with preprocessing
%.o: %.S
@@ -153,7 +153,8 @@ endif
# Get the current version information
######################################################################
-VERSION = $(shell grep SCUMMVM_VERSION "${srcdir}/base/internal_version.h" | cut -d\" -f2)
+# AmigaOS4's grep has a problem with "./" in pathnames, so use cat piped into grep.
+VERSION = $(shell cat "${srcdir}/base/internal_version.h" | grep SCUMMVM_VERSION | cut -d\" -f2)
VER_MAJOR = $(shell echo $(VERSION) | cut -d. -f 1)
VER_MINOR = $(shell echo $(VERSION) | cut -d. -f 2)
VER_PATCH = $(shell echo $(VERSION) | cut -d. -f 3 | cut -c1)
@@ -229,7 +230,7 @@ dist-src: \
@#DEB-src?
# Common files
-DIST_FILES_DOCS:=$(addprefix $(srcdir)/,AUTHORS COPYING COPYING.BSD COPYING.LGPL COPYRIGHT NEWS README)
+DIST_FILES_DOCS:=$(addprefix $(srcdir)/,AUTHORS COPYING COPYING.BSD COPYING.LGPL COPYING.FREEFONT COPYRIGHT NEWS README)
# Themes files
DIST_FILES_THEMES=scummmodern.zip scummclassic.zip
@@ -252,9 +253,6 @@ endif
ifdef ENABLE_LURE
DIST_FILES_ENGINEDATA+=lure.dat
endif
-ifdef ENABLE_M4
-DIST_FILES_ENGINEDATA+=m4.dat
-endif
ifdef ENABLE_QUEEN
DIST_FILES_ENGINEDATA+=queen.tbl
endif
diff --git a/NEWS b/NEWS
index 77fc9a106d..9eab69b715 100644
--- a/NEWS
+++ b/NEWS
@@ -2,9 +2,72 @@ For a more comprehensive changelog of the latest experimental code, see:
https://github.com/scummvm/scummvm/commits/
1.5.0 (????-??-??)
+ New Games:
+ - Added support for Soltys.
+
+ General:
+ - Updated MT-32 emulation code to latest munt project snapshot. The emulation
+ improved dramatically.
+ - Implemented support for TrueType fonts via FreeType2 in our GUI. Along
+ with it GNU FreeFont was also added to our modern theme. Note that not all
+ ports take advantage of this.
+
SDL ports:
- Added support for OpenGL (GSoC Task).
+ Broken Sword 1:
+ - Fixed incorrect sound effects in the DOS/Windows demo.
+ - Added support for PlayStation videos.
+
+ Broken Sword 2:
+ - Added support for PlayStation videos.
+
+ Cine:
+ - Implemented Roland MT-32 output driver.
+
+ SCUMM:
+ - Added support for the Macintosh version of SPY Fox in Hold the Mustard.
+ - Added a difficulty selection dialog for Loom FM-TOWNS.
+
+ iPhone port:
+ - Changed "F5 (menu)" gesture to open up the global main menu instead.
+ - Added support for custom cursor palettes, this makes the moderm theme use
+ the red pointer cursor for example.
+ - Added aspect ratio correction feature.
+ - Implemented 16 bits per pixel support for games.
+
+ Windows port:
+ - Changed default savegames location for Windows NT4/2000/XP/Vista/7.
+ (The migration batch file can be used to copy savegames from the old
+ default location, to the new default location).
+
+1.4.1 (2012-01-27)
+ AGOS:
+ - Fixed loading videos directly from InstallShield cabinets in the Windows
+ version of the The Feeble Files.
+
+ BASS:
+ - Added support for Enhanced Music by James Woodcock
+ (http://www.jameswoodcock.co.uk/?p=7695).
+
+ Broken Sword 2:
+ - Slight graphics improvement for PSX version.
+
+ KYRA:
+ - Fixed bug in the original Lands of Lore GUI which made ScummVM error out
+ in the case the user did not have a contiguous save slot usage.
+ - Add support for original DOS Lands of Lore save files (also applies to save
+ files made with the GOG release).
+
+ SCI:
+ - Fixed race condition in SCI1.1 palette changes. This fixes an error in
+ QFG1VGA, when sleeping at Erana's place.
+ - The option to toggle sound effect types between digitized and synthesized
+ has been disabled until a more user-friendly GUI option is possible.
+ Digital sound effects are always preferred for now.
+ - Fixed a case where starting a new song didn't fully reset its channels,
+ thus some notes sounded wrong.
+
1.4.0 (2011-11-11)
New Games:
- Added support for Lands of Lore: The Throne of Chaos.
@@ -15,6 +78,10 @@ For a more comprehensive changelog of the latest experimental code, see:
New Ports:
- Added PlayStation 3 port.
+ General:
+ - Fixed the ARM assembly routine for reverse stereo audio.
+ - Added support for building with MacPorts out of the box.
+
AGI:
- Implemented sound support for the DOS version of Winnie the Pooh in the
Hundred Acre Wood.
@@ -46,12 +113,20 @@ For a more comprehensive changelog of the latest experimental code, see:
- Improved palette handling for the Amiga version of Indiana Jones and the
Fate of Atlantis.
+ Broken Sword 1:
+ - Fix freeze in Windows demo.
+ - Fix crash when using cutscene subtitles pack with the Macintosh version.
+
Tinsel:
- Fixed deleting saved games from the list of saved games (from the launcher
and the in-game ScummVM menu).
- The US version of Discworld II now shows the correct title screen and
language flag.
+ Android port:
+ - Fixed plugins on Android 3.x.
+ - Moved the default saved game location to the SD card.
+
1.3.1 (2011-07-12)
General:
- Improved audio device detection and fallback.
@@ -95,7 +170,7 @@ For a more comprehensive changelog of the latest experimental code, see:
New Ports:
- Added WebOS port.
- General
+ General:
- Added support for loadable modules on platforms without a dynamic
loader (GSoC Task).
- Added Danish translation.
diff --git a/README b/README
index 4e306d35c8..82d5df3df6 100644
--- a/README
+++ b/README
@@ -1,5 +1,4 @@
ScummVM README
-Last updated: $Date$
------------------------------------------------------------------------
For more information, compatibility lists, details on donating, the latest
@@ -512,6 +511,15 @@ Sword has a "SMACKSLO" directory with the same cutscenes, but these are
of lower quality.) You can put them in a subdirectory called "video" if
you find that neater.
+For the PlayStation versions, you can dump the original videos off the
+disc. For each of the files ending in an "STR" extension, you should
+dump them as *raw* sectors off the disc (all 2352 bytes per sector). You
+may also use the re-encoded cutscenes mentioned below instead, but this
+will not work for all videos in Broken Sword II. For more information,
+see:
+
+ http://wiki.scummvm.org/index.php/HOWTO-PlayStation_Videos
+
Some re-releases of the games, as well as the PlayStation version, do
not have Smacker videos. Revolution Software has kindly allowed us to
provide re-encoded cutscenes for download on our website:
@@ -529,8 +537,9 @@ audio. Viewing these cutscenes with OGG Vorbis audio requires a version
of ScummVM compiled with both libVorbis and zlib support.
For Broken Sword, we also provide a subtitles add-on. Simply unpack it
-and follow the instructions in its readme.txt file. (Broken Sword II
-already has subtitles; no extra work is needed for them.)
+and follow the instructions in its readme.txt file. The subtitle pack
+currently does not work when running PlayStation videos. (Broken Sword
+II already has subtitles; no extra work is needed for them.)
3.7.2) Broken Sword games cutscenes, in retrospect:
@@ -674,7 +683,12 @@ Rename voices.wav on CD4 to voices4.wav
3.14) The Legend of Kyrandia notes:
----- -----------------------------
To run The Legend of Kyrandia under ScummVM you need the 'kyra.dat'
-file, which can be found on the 'Downloads' page of the ScummVM website.
+file. The file should always be included in official ScummVM packages.
+In case ScummVM complains that the file is missing you can find it on the
+'Downloads' page of the ScummVM website. Note that the current Windows
+release of ScummVM should contain the file embedded into the executable,
+thus you only need to grab it in case ScummVM complains about the file
+being missing.
3.15) Sierra AGI games Predictive Input Dialog notes:
@@ -802,10 +816,6 @@ site, please see the section on reporting bugs.
FM-TOWNS versions:
- The Kanji versions require the FM-TOWNS Font ROM
- - ScummVM will crash randomly when using the FM-TOWNS Font ROM for
- the Kanji versions of the following games:
- The Secret of Monkey Island, Monkey Island 2: LeChuck's Revenge
- and Indiana Jones and the Fate of Atlantis
Loom:
- Turning off the subtitles via the config file does not work reliably
@@ -857,7 +867,6 @@ site, please see the section on reporting bugs.
The Legend of Kyrandia:
- No music or sound effects in the Macintosh floppy versions.
- Macintosh CD is using included DOS music and sound effects.
- - PC-9821 version lacks support for sound effects.
Humongous Entertainment games:
- Only the original load and save interface can be used.
@@ -956,6 +965,7 @@ arguments -- see the next section.
--themepath=PATH Path to where GUI themes are stored
--list-themes Display list of all usable GUI themes
-e, --music-driver=MODE Select music driver (see also section 7.0)
+ --list-audio-devices List all available audio devices
-q, --language=LANG Select game's language (see also section 5.2)
-m, --music-volume=NUM Set the music volume, 0-255 (default: 192)
-s, --sfx-volume=NUM Set the sfx volume, 0-255 (default: 192)
@@ -1147,19 +1157,28 @@ Engines which currently support returning to the Launcher are:
AGI
AGOS
CINE
+ COMPOSER
+ CRUISE
DRACI
+ DRASCULA
GOB
GROOVIE
+ HUGO
KYRA
LURE
+ MADE
+ MOHAWK
PARALLACTION
QUEEN
SAGA
+ SCI
SCUMM
SKY
SWORD1
SWORD2
+ TEENAGENT
TOUCHE
+ TSAGE
TUCKER
@@ -1339,13 +1358,32 @@ config file by setting the savepath parameter. See the example config
file later in this README.
The platforms that currently have a different default directory are:
- Mac OS X: $HOME/Documents/ScummVM Savegames/
- Other unices: $HOME/.scummvm/
+ Mac OS X:
+ $HOME/Documents/ScummVM Savegames/
+
+ Other unices:
+ $HOME/.scummvm/
+
+ Windows Vista/7:
+ \Users\username\AppData\Roaming\ScummVM\Saved games\
+
+ Windows 2000/XP:
+ \Documents and Settings\username\Application Data\ScummVM\Saved games\
+
+ Windows NT4:
+ <windir>\Profiles\username\Application Data\ScummVM\Saved games\
+Savegames are stored under a hidden area in Windows NT4/2000/XP/Vista/7,
+which can be accessed by running "%APPDATA%\ScummVM\Saved Games\" or by
+enabling hidden files in Windows Explorer.
+
+Note for Windows NT4/2000/XP/Vista/7 users: The default savegames location
+changed in ScummVM 1.5.0. The migration batch file can be used to copy
+savegames from the old default location, to the new default location.
6.1) Autosaves:
---- ----------
-For some games, (namely "Beneath a Steel Sky", "Flight of the Amazon
+For some games (namely "Beneath a Steel Sky", "Flight of the Amazon
Queen", all AGI games, and all SCUMM games), ScummVM will by default
automatically save the current state every five minutes (adjustable via
the "autosave_period" config setting). For the AGI and SCUMM engines, it
@@ -1355,8 +1393,8 @@ loaded again via Ctrl-0, or the F5 menu.
6.2) Converting Savegames:
---- ---------------------
-Using savegames from original versions, isn't supported by all game
-engines. Only the following games, can use savegames from their original
+Using savegames from original versions isn't supported by all game
+engines. Only the following games can use savegames from their original
versions.
Elvira 1
@@ -1399,20 +1437,28 @@ Where 'xxx' is exact the saved game slot (ie 001) under ScummVM
AGI
AGOS
+ CGE
CINE
+ CRUISE
DRACI
GROOVIE
+ HUGO
KYRA
LURE
+ MOHAWK
PARALLACTION
QUEEN
SAGA
+ SCI
SCUMM
SKY
SWORD1
SWORD2
+ TEENAGENT
TINSEL
+ TOON
TOUCHE
+ TSAGE
TUCKER
--save-slot/-x:
@@ -1424,20 +1470,28 @@ Where 'xxx' is exact the saved game slot (ie 001) under ScummVM
Engines which currently support --save-slot/-x are:
AGI
+ CGE
CINE
+ CRUISE
DRACI
GROOVIE
+ HUGO
KYRA
LURE
- PARALLACTION
+ MOHAWK
QUEEN
SAGA
+ SCI
SCUMM
SKY
SWORD1
SWORD2
+ TEENAGENT
TINSEL
+ TOON
TOUCHE
+ TSAGE
+ TUCKER
7.0) Music and Sound:
@@ -1878,7 +1932,7 @@ the original frequency.
---- -------------------
By default, the configuration file is saved in, and loaded from:
- Windows Vista:
+ Windows Vista/7:
\Users\username\AppData\Roaming\ScummVM\scummvm.ini,
Windows 2000/XP:
@@ -2028,7 +2082,12 @@ King's Quest VI Windows adds the following non-standard keyword:
ones. If false, the DOS cursors are used in the
Windows version, upscaled to match the rest of
the upscaled graphics
-
+
+Space Quest IV CD adds the following non-standard keyword:
+
+ silver_cursors bool If true, an alternate set of silver mouse cursors
+ is used instead of the original golden ones
+
Simon the Sorcerer 1 and 2 add the following non-standard keywords:
music_mute bool If true, music is muted
@@ -2038,6 +2097,10 @@ The Legend of Kyrandia adds the following non-standard keyword:
walkspeed int The walk speed (0-4)
+The 7th Guest adds the following non-standard keyword:
+
+ t7g_speed string Video playback speed (normal, tweaked, im_an_ios)
+
9.0) Compiling:
---- ----------
@@ -2086,16 +2149,6 @@ debug messages (see http://www.sysinternals.com/ntw2k/freeware/debugview.shtml).
* Please refer to:
http://wiki.scummvm.org/index.php/Compiling_ScummVM/Windows_CE
- Debian GNU/Linux:
- * Install the packages 'build-essential', 'fakeroot', 'debhelper',
- and 'libsdl1.2-dev' on your system.
- * Install any of these packages (optional): 'libvorbis-dev' (for Ogg
- Vorbis support), 'libasound2-dev' (for ALSA sequencer support),
- 'libmad0-dev' (for MAD MP3 support), 'zlib1g-dev' (for compressed
- saves support).
- * Run 'make deb'.
- * Finally run 'dpkg -i ../scummvm-cvs*deb', and you're done.
-
Mac OS X:
* Make sure you have the developer tools installed.
* The SDL developer package for OS X available on the SDL web site is
diff --git a/audio/audiostream.h b/audio/audiostream.h
index 9c28e4d67f..801f13d9d9 100644
--- a/audio/audiostream.h
+++ b/audio/audiostream.h
@@ -20,8 +20,8 @@
*
*/
-#ifndef SOUND_AUDIOSTREAM_H
-#define SOUND_AUDIOSTREAM_H
+#ifndef AUDIO_AUDIOSTREAM_H
+#define AUDIO_AUDIOSTREAM_H
#include "common/ptr.h"
#include "common/scummsys.h"
diff --git a/audio/decoders/aac.h b/audio/decoders/aac.h
index 68e322c844..9ad78b28a4 100644
--- a/audio/decoders/aac.h
+++ b/audio/decoders/aac.h
@@ -26,8 +26,8 @@
* - groovie
*/
-#ifndef SOUND_AAC_H
-#define SOUND_AAC_H
+#ifndef AUDIO_AAC_H
+#define AUDIO_AAC_H
#include "common/scummsys.h"
#include "common/types.h"
@@ -59,4 +59,4 @@ Codec *makeAACDecoder(
} // End of namespace Audio
#endif // #ifdef USE_FAAD
-#endif // #ifndef SOUND_AAC_H
+#endif // #ifndef AUDIO_AAC_H
diff --git a/audio/decoders/adpcm.h b/audio/decoders/adpcm.h
index 1dd4d510df..ac8d529917 100644
--- a/audio/decoders/adpcm.h
+++ b/audio/decoders/adpcm.h
@@ -31,8 +31,8 @@
* - tinsel
*/
-#ifndef SOUND_ADPCM_H
-#define SOUND_ADPCM_H
+#ifndef AUDIO_ADPCM_H
+#define AUDIO_ADPCM_H
#include "common/scummsys.h"
#include "common/types.h"
diff --git a/audio/decoders/adpcm_intern.h b/audio/decoders/adpcm_intern.h
index 38514d7fca..31747aabaf 100644
--- a/audio/decoders/adpcm_intern.h
+++ b/audio/decoders/adpcm_intern.h
@@ -28,8 +28,8 @@
* ADPCM decoder implementations.
*/
-#ifndef SOUND_ADPCM_INTERN_H
-#define SOUND_ADPCM_INTERN_H
+#ifndef AUDIO_ADPCM_INTERN_H
+#define AUDIO_ADPCM_INTERN_H
#include "audio/audiostream.h"
#include "common/endian.h"
@@ -43,7 +43,7 @@ namespace Audio {
class ADPCMStream : public RewindableAudioStream {
protected:
Common::DisposablePtr<Common::SeekableReadStream> _stream;
- const int32 _startpos;
+ int32 _startpos;
const int32 _endpos;
const int _channels;
const uint32 _blockAlign;
@@ -97,9 +97,7 @@ protected:
public:
Ima_ADPCMStream(Common::SeekableReadStream *stream, DisposeAfterUse::Flag disposeAfterUse, uint32 size, int rate, int channels, uint32 blockAlign)
- : ADPCMStream(stream, disposeAfterUse, size, rate, channels, blockAlign) {
- memset(&_status, 0, sizeof(_status));
- }
+ : ADPCMStream(stream, disposeAfterUse, size, rate, channels, blockAlign) {}
/**
* This table is used by decodeIMA.
diff --git a/audio/decoders/aiff.h b/audio/decoders/aiff.h
index 558a018f57..59664bb85a 100644
--- a/audio/decoders/aiff.h
+++ b/audio/decoders/aiff.h
@@ -28,8 +28,8 @@
* - sword1
*/
-#ifndef SOUND_AIFF_H
-#define SOUND_AIFF_H
+#ifndef AUDIO_AIFF_H
+#define AUDIO_AIFF_H
#include "common/scummsys.h"
#include "common/types.h"
diff --git a/audio/decoders/flac.cpp b/audio/decoders/flac.cpp
index d06a7b9c0e..bbaf5fd5ae 100644
--- a/audio/decoders/flac.cpp
+++ b/audio/decoders/flac.cpp
@@ -209,7 +209,7 @@ FLACStream::FLACStream(Common::SeekableReadStream *inStream, bool dispose)
::FLAC__seekable_stream_decoder_set_write_callback(_decoder, &FLACStream::callWrapWrite);
::FLAC__seekable_stream_decoder_set_metadata_callback(_decoder, &FLACStream::callWrapMetadata);
::FLAC__seekable_stream_decoder_set_error_callback(_decoder, &FLACStream::callWrapError);
- ::FLAC__seekable_stream_decoder_set_client_data(_decoder, (void*)this);
+ ::FLAC__seekable_stream_decoder_set_client_data(_decoder, (void *)this);
success = (::FLAC__seekable_stream_decoder_init(_decoder) == FLAC__SEEKABLE_STREAM_DECODER_OK);
#else
@@ -223,7 +223,7 @@ FLACStream::FLACStream(Common::SeekableReadStream *inStream, bool dispose)
&FLACStream::callWrapWrite,
&FLACStream::callWrapMetadata,
&FLACStream::callWrapError,
- (void*)this
+ (void *)this
) == FLAC__STREAM_DECODER_INIT_STATUS_OK);
#endif
if (success) {
diff --git a/audio/decoders/flac.h b/audio/decoders/flac.h
index 3182b26425..f5e31684fe 100644
--- a/audio/decoders/flac.h
+++ b/audio/decoders/flac.h
@@ -26,7 +26,6 @@
* - agos
* - draci
* - kyra
- * - m4
* - queen
* - saga
* - sci
@@ -37,8 +36,8 @@
* - tucker
*/
-#ifndef SOUND_FLAC_H
-#define SOUND_FLAC_H
+#ifndef AUDIO_FLAC_H
+#define AUDIO_FLAC_H
#include "common/scummsys.h"
#include "common/types.h"
@@ -68,4 +67,4 @@ SeekableAudioStream *makeFLACStream(
} // End of namespace Audio
#endif // #ifdef USE_FLAC
-#endif // #ifndef SOUND_FLAC_H
+#endif // #ifndef AUDIO_FLAC_H
diff --git a/audio/decoders/iff_sound.cpp b/audio/decoders/iff_sound.cpp
index 4efdce0338..b0c41f0180 100644
--- a/audio/decoders/iff_sound.cpp
+++ b/audio/decoders/iff_sound.cpp
@@ -75,7 +75,7 @@ struct A8SVXLoader {
case ID_BODY:
_dataSize = chunk._size;
- _data = (int8*)malloc(_dataSize);
+ _data = (int8 *)malloc(_dataSize);
assert(_data);
loadData(chunk._stream);
return true;
diff --git a/audio/decoders/iff_sound.h b/audio/decoders/iff_sound.h
index b266e629a1..28b2c67227 100644
--- a/audio/decoders/iff_sound.h
+++ b/audio/decoders/iff_sound.h
@@ -26,8 +26,8 @@
* - parallaction
*/
-#ifndef SOUND_IFF_H
-#define SOUND_IFF_H
+#ifndef AUDIO_IFF_H
+#define AUDIO_IFF_H
namespace Common {
class ReadStream;
diff --git a/audio/decoders/mac_snd.h b/audio/decoders/mac_snd.h
index cbbd82bbe0..4380808eae 100644
--- a/audio/decoders/mac_snd.h
+++ b/audio/decoders/mac_snd.h
@@ -23,11 +23,12 @@
/**
* @file
* Sound decoder used in engines:
+ * - saga
* - sci
*/
-#ifndef SOUND_MAC_SND_H
-#define SOUND_MAC_SND_H
+#ifndef AUDIO_MAC_SND_H
+#define AUDIO_MAC_SND_H
#include "common/scummsys.h"
#include "common/types.h"
diff --git a/audio/decoders/mp3.h b/audio/decoders/mp3.h
index 86ddc599ea..df2ee44805 100644
--- a/audio/decoders/mp3.h
+++ b/audio/decoders/mp3.h
@@ -26,7 +26,6 @@
* - agos
* - draci
* - kyra
- * - m4
* - mohawk
* - queen
* - saga
@@ -38,8 +37,8 @@
* - tucker
*/
-#ifndef SOUND_MP3_H
-#define SOUND_MP3_H
+#ifndef AUDIO_MP3_H
+#define AUDIO_MP3_H
#include "common/scummsys.h"
#include "common/types.h"
@@ -69,4 +68,4 @@ SeekableAudioStream *makeMP3Stream(
} // End of namespace Audio
#endif // #ifdef USE_MAD
-#endif // #ifndef SOUND_MP3_H
+#endif // #ifndef AUDIO_MP3_H
diff --git a/audio/decoders/qdm2.cpp b/audio/decoders/qdm2.cpp
index 19b30217e9..735fb2b6a0 100644
--- a/audio/decoders/qdm2.cpp
+++ b/audio/decoders/qdm2.cpp
@@ -589,7 +589,7 @@ DECL_FFT(32768,16384,8192)
DECL_FFT(65536,32768,16384)
void fftCalc(FFTContext *s, FFTComplex *z) {
- static void (* const fftDispatch[])(FFTComplex*) = {
+ static void (* const fftDispatch[])(FFTComplex *) = {
fft4, fft8, fft16, fft32, fft64, fft128, fft256, fft512, fft1024,
fft2048, fft4096, fft8192, fft16384, fft32768, fft65536,
};
@@ -857,8 +857,8 @@ void rdftCalc(RDFTContext *s, float *data) {
if (s->inverse) {
data[0] *= k1;
data[1] *= k1;
- fftPermute(&s->fft, (FFTComplex*)data);
- fftCalc(&s->fft, (FFTComplex*)data);
+ fftPermute(&s->fft, (FFTComplex *)data);
+ fftCalc(&s->fft, (FFTComplex *)data);
}
}
@@ -1832,7 +1832,7 @@ QDM2Stream::QDM2Stream(Common::SeekableReadStream *extraData, DisposeAfterUse::F
_subSampling = _fftOrder - 7;
_frequencyRange = 255 / (1 << (2 - _subSampling));
- switch ((_subSampling * 2 + _channels - 1)) {
+ switch (_subSampling * 2 + _channels - 1) {
case 0:
tmp = 40;
break;
diff --git a/audio/decoders/quicktime.cpp b/audio/decoders/quicktime.cpp
index 8cf0305e88..dcf80ea1c6 100644
--- a/audio/decoders/quicktime.cpp
+++ b/audio/decoders/quicktime.cpp
@@ -87,6 +87,9 @@ void QuickTimeAudioDecoder::init() {
// Initialize the codec (if necessary)
entry->initCodec();
+
+ if (_tracks[_audioTrackIndex]->editCount > 1)
+ warning("Multiple edit list entries in an audio track. Things may go awry");
}
}
}
@@ -227,16 +230,23 @@ void QuickTimeAudioDecoder::setAudioStreamPos(const Timestamp &where) {
uint32 seekSample = sample;
if (!isOldDemuxing()) {
- // We shouldn't have audio samples that are a different duration
- // That would be quite bad!
- if (_tracks[_audioTrackIndex]->timeToSampleCount != 1) {
- warning("Failed seeking");
- return;
- }
+ // For MPEG-4 style demuxing, we need to track down the sample based on the time
+ // The old style demuxing doesn't require this because each "sample"'s duration
+ // is just 1
+ uint32 curSample = 0;
+ seekSample = 0;
+
+ for (int32 i = 0; i < _tracks[_audioTrackIndex]->timeToSampleCount; i++) {
+ uint32 sampleCount = _tracks[_audioTrackIndex]->timeToSample[i].count * _tracks[_audioTrackIndex]->timeToSample[i].duration;
+
+ if (sample < curSample + sampleCount) {
+ seekSample += (sample - curSample) / _tracks[_audioTrackIndex]->timeToSample[i].duration;
+ break;
+ }
- // Note that duration is in terms of *one* channel
- // This eases calculation a bit
- seekSample /= _tracks[_audioTrackIndex]->timeToSample[0].duration;
+ seekSample += _tracks[_audioTrackIndex]->timeToSample[i].count;
+ curSample += sampleCount;
+ }
}
// Now to track down what chunk it's in
@@ -414,7 +424,9 @@ public:
}
Timestamp getLength() const {
- return Timestamp(0, _tracks[_audioTrackIndex]->duration, _tracks[_audioTrackIndex]->timeScale);
+ // TODO: Switch to the other one when audio edits are supported
+ //return Timestamp(0, _tracks[_audioTrackIndex]->duration, _timeScale);
+ return Timestamp(0, _tracks[_audioTrackIndex]->mediaDuration, _tracks[_audioTrackIndex]->timeScale);
}
};
diff --git a/audio/decoders/raw.cpp b/audio/decoders/raw.cpp
index 881b8c1d6a..d24e07926e 100644
--- a/audio/decoders/raw.cpp
+++ b/audio/decoders/raw.cpp
@@ -45,40 +45,18 @@ namespace Audio {
/**
* This is a stream, which allows for playing raw PCM data from a stream.
- * It also features playback of multiple blocks from a given stream.
*/
template<bool is16Bit, bool isUnsigned, bool isLE>
class RawStream : public SeekableAudioStream {
public:
- RawStream(int rate, bool stereo, DisposeAfterUse::Flag disposeStream, Common::SeekableReadStream *stream, const RawStreamBlockList &blocks)
- : _rate(rate), _isStereo(stereo), _playtime(0, rate), _stream(stream, disposeStream), _blocks(blocks), _curBlock(_blocks.begin()), _blockLeft(0), _buffer(0) {
-
- assert(_blocks.size() > 0);
-
+ RawStream(int rate, bool stereo, DisposeAfterUse::Flag disposeStream, Common::SeekableReadStream *stream)
+ : _rate(rate), _isStereo(stereo), _playtime(0, rate), _stream(stream, disposeStream), _endOfData(false), _buffer(0) {
// Setup our buffer for readBuffer
_buffer = new byte[kSampleBufferLength * (is16Bit ? 2 : 1)];
assert(_buffer);
- // Set current buffer state, playing first block
- _stream->seek(_curBlock->pos, SEEK_SET);
-
- // In case of an error we will stop (or rather
- // not start) stream playback.
- if (_stream->err()) {
- _blockLeft = 0;
- _curBlock = _blocks.end();
- } else {
- _blockLeft = _curBlock->len;
- }
-
- // Add up length of all blocks in order to caluclate total play time
- int32 len = 0;
- for (RawStreamBlockList::const_iterator i = _blocks.begin(); i != _blocks.end(); ++i) {
- assert(i->len % (_isStereo ? 2 : 1) == 0);
- len += i->len;
- }
-
- _playtime = Timestamp(0, len / (_isStereo ? 2 : 1), rate);
+ // Calculate the total playtime of the stream
+ _playtime = Timestamp(0, _stream->size() / (_isStereo ? 2 : 1) / (is16Bit ? 2 : 1), rate);
}
~RawStream() {
@@ -87,8 +65,8 @@ public:
int readBuffer(int16 *buffer, const int numSamples);
- bool isStereo() const { return _isStereo; }
- bool endOfData() const { return (_curBlock == _blocks.end()) && (_blockLeft == 0); }
+ bool isStereo() const { return _isStereo; }
+ bool endOfData() const { return _endOfData; }
int getRate() const { return _rate; }
Timestamp getLength() const { return _playtime; }
@@ -99,18 +77,9 @@ private:
const bool _isStereo; ///< Whether this is an stereo stream
Timestamp _playtime; ///< Calculated total play time
Common::DisposablePtr<Common::SeekableReadStream> _stream; ///< Stream to read data from
- const RawStreamBlockList _blocks; ///< Audio block list
-
- RawStreamBlockList::const_iterator _curBlock; ///< Current audio block number
- int32 _blockLeft; ///< How many bytes are still left in the current block
-
- /**
- * Advance one block in the stream in case
- * the current one is empty.
- */
- void updateBlockIfNeeded();
+ bool _endOfData; ///< Whether the stream end has been reached
- byte *_buffer; ///< Buffer used in readBuffer
+ byte *_buffer; ///< Buffer used in readBuffer
enum {
/**
* How many samples we can buffer at once.
@@ -169,13 +138,9 @@ int RawStream<is16Bit, isUnsigned, isLE>::fillBuffer(int maxSamples) {
// We will only read up to maxSamples
while (maxSamples > 0 && !endOfData()) {
- // Calculate how many samples we can safely read
- // from the current block.
- const int len = MIN<int>(maxSamples, _blockLeft);
-
// Try to read all the sample data and update the
// destination pointer.
- const int bytesRead = _stream->read(dst, len * (is16Bit ? 2 : 1));
+ const int bytesRead = _stream->read(dst, maxSamples * (is16Bit ? 2 : 1));
dst += bytesRead;
// Calculate how many samples we actually read.
@@ -184,87 +149,31 @@ int RawStream<is16Bit, isUnsigned, isLE>::fillBuffer(int maxSamples) {
// Update all status variables
bufferedSamples += samplesRead;
maxSamples -= samplesRead;
- _blockLeft -= samplesRead;
- // In case of an error we will stop
- // stream playback.
- if (_stream->err()) {
- _blockLeft = 0;
- _curBlock = _blocks.end();
- }
-
- // Advance to the next block in case the current
- // one is already finished.
- updateBlockIfNeeded();
+ // We stop stream playback, when we reached the end of the data stream.
+ // We also stop playback when an error occures.
+ if (_stream->pos() == _stream->size() || _stream->err() || _stream->eos())
+ _endOfData = true;
}
return bufferedSamples;
}
template<bool is16Bit, bool isUnsigned, bool isLE>
-void RawStream<is16Bit, isUnsigned, isLE>::updateBlockIfNeeded() {
- // Have we now finished this block? If so, read the next block
- if (_blockLeft == 0 && _curBlock != _blocks.end()) {
- // Next block
- ++_curBlock;
-
- // Check whether we reached the end of the stream
- // yet. In case we did not do this, we will just
- // setup the next block as new block.
- if (_curBlock != _blocks.end()) {
- _stream->seek(_curBlock->pos, SEEK_SET);
-
- // In case of an error we will stop
- // stream playback.
- if (_stream->err()) {
- _blockLeft = 0;
- _curBlock = _blocks.end();
- } else {
- _blockLeft = _curBlock->len;
- }
- }
- }
-}
-
-template<bool is16Bit, bool isUnsigned, bool isLE>
bool RawStream<is16Bit, isUnsigned, isLE>::seek(const Timestamp &where) {
- _blockLeft = 0;
- _curBlock = _blocks.end();
+ _endOfData = true;
if (where > _playtime)
return false;
const uint32 seekSample = convertTimeToStreamPos(where, getRate(), isStereo()).totalNumberOfFrames();
- uint32 curSample = 0;
-
- // Search for the disk block in which the specific sample is placed
- for (_curBlock = _blocks.begin(); _curBlock != _blocks.end(); ++_curBlock) {
- uint32 nextBlockSample = curSample + _curBlock->len;
-
- if (nextBlockSample > seekSample)
- break;
+ _stream->seek(seekSample * (is16Bit ? 2 : 1), SEEK_SET);
- curSample = nextBlockSample;
- }
+ // In case of an error we will not continue stream playback.
+ if (!_stream->err() && !_stream->eos() && _stream->pos() != _stream->size())
+ _endOfData = false;
- if (_curBlock == _blocks.end()) {
- return ((seekSample - curSample) == 0);
- } else {
- const uint32 offset = seekSample - curSample;
-
- _stream->seek(_curBlock->pos + offset * (is16Bit ? 2 : 1), SEEK_SET);
-
- // In case of an error we will stop
- // stream playback.
- if (_stream->err()) {
- _blockLeft = 0;
- _curBlock = _blocks.end();
- } else {
- _blockLeft = _curBlock->len - offset;
- }
-
- return true;
- }
+ return true;
}
#pragma mark -
@@ -283,28 +192,21 @@ bool RawStream<is16Bit, isUnsigned, isLE>::seek(const Timestamp &where) {
#define MAKE_RAW_STREAM(UNSIGNED) \
if (is16Bit) { \
if (isLE) \
- return new RawStream<true, UNSIGNED, true>(rate, isStereo, disposeAfterUse, stream, blockList); \
+ return new RawStream<true, UNSIGNED, true>(rate, isStereo, disposeAfterUse, stream); \
else \
- return new RawStream<true, UNSIGNED, false>(rate, isStereo, disposeAfterUse, stream, blockList); \
+ return new RawStream<true, UNSIGNED, false>(rate, isStereo, disposeAfterUse, stream); \
} else \
- return new RawStream<false, UNSIGNED, false>(rate, isStereo, disposeAfterUse, stream, blockList)
+ return new RawStream<false, UNSIGNED, false>(rate, isStereo, disposeAfterUse, stream)
SeekableAudioStream *makeRawStream(Common::SeekableReadStream *stream,
- const RawStreamBlockList &blockList,
- int rate,
- byte flags,
+ int rate, byte flags,
DisposeAfterUse::Flag disposeAfterUse) {
const bool isStereo = (flags & Audio::FLAG_STEREO) != 0;
const bool is16Bit = (flags & Audio::FLAG_16BITS) != 0;
const bool isUnsigned = (flags & Audio::FLAG_UNSIGNED) != 0;
const bool isLE = (flags & Audio::FLAG_LITTLE_ENDIAN) != 0;
- if (blockList.empty()) {
- warning("Empty block list passed to makeRawStream");
- if (disposeAfterUse == DisposeAfterUse::YES)
- delete stream;
- return 0;
- }
+ assert(stream->size() % ((is16Bit ? 2 : 1) * (isStereo ? 2 : 1)) == 0);
if (isUnsigned) {
MAKE_RAW_STREAM(true);
@@ -313,38 +215,10 @@ SeekableAudioStream *makeRawStream(Common::SeekableReadStream *stream,
}
}
-SeekableAudioStream *makeRawStream(Common::SeekableReadStream *stream,
- int rate, byte flags,
- DisposeAfterUse::Flag disposeAfterUse) {
- RawStreamBlockList blocks;
- RawStreamBlock block;
- block.pos = 0;
-
- const bool isStereo = (flags & Audio::FLAG_STEREO) != 0;
- const bool is16Bit = (flags & Audio::FLAG_16BITS) != 0;
-
- assert(stream->size() % ((is16Bit ? 2 : 1) * (isStereo ? 2 : 1)) == 0);
-
- block.len = stream->size() / (is16Bit ? 2 : 1);
- blocks.push_back(block);
-
- return makeRawStream(stream, blocks, rate, flags, disposeAfterUse);
-}
-
SeekableAudioStream *makeRawStream(const byte *buffer, uint32 size,
int rate, byte flags,
DisposeAfterUse::Flag disposeAfterUse) {
return makeRawStream(new Common::MemoryReadStream(buffer, size, disposeAfterUse), rate, flags, DisposeAfterUse::YES);
}
-SeekableAudioStream *makeRawDiskStream_OLD(Common::SeekableReadStream *stream, RawStreamBlock *block, int numBlocks,
- int rate, byte flags, DisposeAfterUse::Flag disposeStream) {
- assert(numBlocks > 0);
- RawStreamBlockList blocks;
- for (int i = 0; i < numBlocks; ++i)
- blocks.push_back(block[i]);
-
- return makeRawStream(stream, blocks, rate, flags, disposeStream);
-}
-
} // End of namespace Audio
diff --git a/audio/decoders/raw.h b/audio/decoders/raw.h
index 5a7897b688..a06bebee10 100644
--- a/audio/decoders/raw.h
+++ b/audio/decoders/raw.h
@@ -20,8 +20,8 @@
*
*/
-#ifndef SOUND_RAW_H
-#define SOUND_RAW_H
+#ifndef AUDIO_RAW_H
+#define AUDIO_RAW_H
#include "common/scummsys.h"
#include "common/types.h"
@@ -60,21 +60,6 @@ enum RawFlags {
FLAG_STEREO = 1 << 3
};
-
-/**
- * Struct used to define the audio data to be played by a RawStream.
- */
-struct RawStreamBlock {
- int32 pos; ///< Position in stream of the block (in bytes of course!)
- int32 len; ///< Length of the block (in raw samples, not sample pairs!)
-};
-
-/**
- * List containing all blocks of a raw stream.
- * @see RawStreamBlock
- */
-typedef Common::List<RawStreamBlock> RawStreamBlockList;
-
/**
* Creates an audio stream, which plays from the given buffer.
*
@@ -104,47 +89,6 @@ SeekableAudioStream *makeRawStream(Common::SeekableReadStream *stream,
int rate, byte flags,
DisposeAfterUse::Flag disposeAfterUse = DisposeAfterUse::YES);
-/**
- * Creates an audio stream, which plays from the given stream.
- *
- * @param stream Stream object to play from.
- * @param blockList List of blocks to play.
- * @see RawDiskStreamAudioBlock
- * @see RawStreamBlockList
- * @param rate Rate of the sound data.
- * @param flags Audio flags combination.
- * @see RawFlags
- * @param disposeAfterUse Whether to delete the stream after use.
- * @return The new SeekableAudioStream (or 0 on failure).
- */
-SeekableAudioStream *makeRawStream(Common::SeekableReadStream *stream,
- const RawStreamBlockList &blockList,
- int rate,
- byte flags,
- DisposeAfterUse::Flag disposeAfterUse = DisposeAfterUse::YES);
-
-/**
- * NOTE:
- * This API is considered deprecated.
- *
- * Creates a audio stream, which plays from given stream.
- *
- * @param stream Stream to play from
- * @param block Pointer to an RawStreamBlock array
- * @see RawStreamBlock
- * @param numBlocks Number of blocks.
- * @param rate The rate
- * @param flags Flags combination.
- * @see RawFlags
- * @param disposeStream Whether the "stream" object should be destroyed after playback.
- * @return The new SeekableAudioStream (or 0 on failure).
- */
-SeekableAudioStream *makeRawDiskStream_OLD(Common::SeekableReadStream *stream,
- RawStreamBlock *block, int numBlocks,
- int rate, byte flags,
- DisposeAfterUse::Flag disposeStream);
-
-
} // End of namespace Audio
#endif
diff --git a/audio/decoders/voc.cpp b/audio/decoders/voc.cpp
index f06e7f95f2..f0b5b2777d 100644
--- a/audio/decoders/voc.cpp
+++ b/audio/decoders/voc.cpp
@@ -25,305 +25,540 @@
#include "common/util.h"
#include "common/stream.h"
#include "common/textconsole.h"
+#include "common/list.h"
#include "audio/audiostream.h"
#include "audio/decoders/raw.h"
#include "audio/decoders/voc.h"
-
namespace Audio {
-int getSampleRateFromVOCRate(int vocSR) {
- if (vocSR == 0xa5 || vocSR == 0xa6) {
- return 11025;
- } else if (vocSR == 0xd2 || vocSR == 0xd3) {
- return 22050;
- } else {
- int sr = 1000000L / (256L - vocSR);
- // inexact sampling rates occur e.g. in the kitchen in Monkey Island,
- // very easy to reach right from the start of the game.
- //warning("inexact sample rate used: %i (0x%x)", sr, vocSR);
- return sr;
- }
-}
+namespace {
-byte *loadVOCFromStream(Common::ReadStream &stream, int &size, int &rate) {
+bool checkVOCHeader(Common::ReadStream &stream) {
VocFileHeader fileHeader;
- debug(2, "loadVOCFromStream");
-
if (stream.read(&fileHeader, 8) != 8)
- goto invalid;
+ return false;
if (!memcmp(&fileHeader, "VTLK", 4)) {
if (stream.read(&fileHeader, sizeof(VocFileHeader)) != sizeof(VocFileHeader))
- goto invalid;
+ return false;
} else if (!memcmp(&fileHeader, "Creative", 8)) {
if (stream.read(((byte *)&fileHeader) + 8, sizeof(VocFileHeader) - 8) != sizeof(VocFileHeader) - 8)
- goto invalid;
+ return false;
} else {
- invalid:;
- warning("loadVOCFromStream: Invalid header");
- return NULL;
+ return false;
}
if (memcmp(fileHeader.desc, "Creative Voice File", 19) != 0)
- error("loadVOCFromStream: Invalid header");
- if (fileHeader.desc[19] != 0x1A)
- debug(3, "loadVOCFromStream: Partially invalid header");
+ return false;
+ //if (fileHeader.desc[19] != 0x1A)
+ // debug(3, "checkVOCHeader: Partially invalid header");
int32 offset = FROM_LE_16(fileHeader.datablock_offset);
int16 version = FROM_LE_16(fileHeader.version);
int16 code = FROM_LE_16(fileHeader.id);
- assert(offset == sizeof(VocFileHeader));
+
+ if (offset != sizeof(VocFileHeader))
+ return false;
+
// 0x100 is an invalid VOC version used by German version of DOTT (Disk) and
// French version of Simon the Sorcerer 2 (CD)
- assert(version == 0x010A || version == 0x0114 || version == 0x0100);
- assert(code == ~version + 0x1234);
+ if (version != 0x010A && version != 0x0114 && version != 0x0100)
+ return false;
- int len;
- byte *ret_sound = 0;
- size = 0;
+ if (code != ~version + 0x1234)
+ return false;
- while ((code = stream.readByte())) {
- len = stream.readByte();
- len |= stream.readByte() << 8;
- len |= stream.readByte() << 16;
+ return true;
+}
- debug(2, "Block code %d, len %d", code, len);
+class VocStream : public SeekableAudioStream {
+public:
+ VocStream(Common::SeekableReadStream *stream, bool isUnsigned, DisposeAfterUse::Flag disposeAfterUse);
+ ~VocStream();
+
+ virtual int readBuffer(int16 *buffer, const int numSamples);
+
+ virtual bool isStereo() const { return false; }
+
+ virtual int getRate() const { return _rate; }
+
+ virtual bool endOfData() const { return (_curBlock == _blocks.end()) && (_blockLeft == 0); }
+
+ virtual bool seek(const Timestamp &where);
+
+ virtual Timestamp getLength() const { return _length; }
+private:
+ void preProcess();
+
+ Common::SeekableReadStream *const _stream;
+ const DisposeAfterUse::Flag _disposeAfterUse;
+
+ const bool _isUnsigned;
+
+ int _rate;
+ Timestamp _length;
+
+ struct Block {
+ uint8 code;
+ uint32 length;
+
+ union {
+ struct {
+ uint32 offset;
+ int rate;
+ int samples;
+ } sampleBlock;
+
+ struct {
+ int count;
+ } loopBlock;
+ };
+ };
+
+ typedef Common::List<Block> BlockList;
+ BlockList _blocks;
+
+ BlockList::const_iterator _curBlock;
+ uint32 _blockLeft;
+
+ /**
+ * Advance one block in the stream in case
+ * the current one is empty.
+ */
+ void updateBlockIfNeeded();
+
+ // Do some internal buffering for systems with really slow slow disk i/o
+ enum {
+ /**
+ * How many samples we can buffer at once.
+ *
+ * TODO: Check whether this size suffices
+ * for systems with slow disk I/O.
+ */
+ kSampleBufferLength = 2048
+ };
+ byte _buffer[kSampleBufferLength];
+
+ /**
+ * Fill the temporary sample buffer used in readBuffer.
+ *
+ * @param maxSamples Maximum samples to read.
+ * @return actual count of samples read.
+ */
+ int fillBuffer(int maxSamples);
+};
+
+VocStream::VocStream(Common::SeekableReadStream *stream, bool isUnsigned, DisposeAfterUse::Flag disposeAfterUse)
+ : _stream(stream), _disposeAfterUse(disposeAfterUse), _isUnsigned(isUnsigned), _rate(0),
+ _length(), _blocks(), _curBlock(_blocks.end()), _blockLeft(0), _buffer() {
+ preProcess();
+}
- switch (code) {
- case 1:
- case 9: {
- int packing;
- if (code == 1) {
- int time_constant = stream.readByte();
- packing = stream.readByte();
- len -= 2;
- rate = getSampleRateFromVOCRate(time_constant);
- } else {
- rate = stream.readUint32LE();
- int bits = stream.readByte();
- int channels = stream.readByte();
- if (bits != 8 || channels != 1) {
- warning("Unsupported VOC file format (%d bits per sample, %d channels)", bits, channels);
- break;
- }
- packing = stream.readUint16LE();
- stream.readUint32LE();
- len -= 12;
- }
- debug(9, "VOC Data Block: %d, %d, %d", rate, packing, len);
- if (packing == 0) {
- if (size) {
- byte *tmp = (byte *)realloc(ret_sound, size + len);
- if (!tmp)
- error("Cannot reallocate memory for VOC Data Block");
-
- ret_sound = tmp;
- } else {
- ret_sound = (byte *)malloc(len);
- }
- stream.read(ret_sound + size, len);
- size += len;
+VocStream::~VocStream() {
+ if (_disposeAfterUse == DisposeAfterUse::YES)
+ delete _stream;
+}
+
+int VocStream::readBuffer(int16 *buffer, const int numSamples) {
+ int samplesLeft = numSamples;
+ while (samplesLeft > 0) {
+ // Try to read up to "samplesLeft" samples.
+ int len = fillBuffer(samplesLeft);
+
+ // In case we were not able to read any samples
+ // we will stop reading here.
+ if (!len)
+ break;
+
+ // Adjust the samples left to read.
+ samplesLeft -= len;
+
+ // Copy the data to the caller's buffer.
+ const byte *src = _buffer;
+ while (len-- > 0)
+ *buffer++ = (*src++ << 8) ^ (_isUnsigned ? 0x8000 : 0);
+ }
+
+ return numSamples - samplesLeft;
+}
+
+void VocStream::updateBlockIfNeeded() {
+ // Have we now finished this block? If so, read the next block
+ if (_blockLeft == 0 && _curBlock != _blocks.end()) {
+ // Find the next sample block
+ while (true) {
+ // Next block
+ ++_curBlock;
+
+ // Check whether we reached the end of the stream
+ // yet.
+ if (_curBlock == _blocks.end())
+ return;
+
+ // Skip all none sample blocks for now
+ if (_curBlock->code != 1 && _curBlock->code != 9)
+ continue;
+
+ _stream->seek(_curBlock->sampleBlock.offset, SEEK_SET);
+
+ // In case of an error we will stop
+ // stream playback.
+ if (_stream->err()) {
+ _blockLeft = 0;
+ _curBlock = _blocks.end();
} else {
- warning("VOC file packing %d unsupported", packing);
+ _blockLeft = _curBlock->sampleBlock.samples;
}
- } break;
- case 3: // silence
- // occur with a few Igor sounds, voc file starts with a silence block with a
- // frequency different from the data block. Just ignore fow now (implementing
- // it wouldn't make a big difference anyway...)
- assert(len == 3);
- stream.readUint16LE();
- stream.readByte();
- break;
- case 6: // begin of loop
- assert(len == 2);
- stream.readUint16LE();
- break;
- case 7: // end of loop
- assert(len == 0);
+
+ return;
+ }
+ }
+}
+
+int VocStream::fillBuffer(int maxSamples) {
+ int bufferedSamples = 0;
+ byte *dst = _buffer;
+
+ // We can only read up to "kSampleBufferLength" samples
+ // so we take this into consideration, when trying to
+ // read up to maxSamples.
+ maxSamples = MIN<int>(kSampleBufferLength, maxSamples);
+
+ // We will only read up to maxSamples
+ while (maxSamples > 0 && !endOfData()) {
+ // Calculate how many samples we can safely read
+ // from the current block.
+ const int len = MIN<int>(maxSamples, _blockLeft);
+
+ // Try to read all the sample data and update the
+ // destination pointer.
+ const int bytesRead = _stream->read(dst, len);
+ dst += bytesRead;
+
+ // Calculate how many samples we actually read.
+ const int samplesRead = bytesRead;
+
+ // Update all status variables
+ bufferedSamples += samplesRead;
+ maxSamples -= samplesRead;
+ _blockLeft -= samplesRead;
+
+ // In case of an error we will stop
+ // stream playback.
+ if (_stream->err()) {
+ _blockLeft = 0;
+ _curBlock = _blocks.end();
break;
- case 8: { // "Extended"
- // This occures in the LoL Intro demo.
- // This block overwrites the next parameters of a block 1 "Sound data".
- // To assure we never get any bad data here, we will assert in case
- // this tries to define a stereo sound block or tries to use something
- // different than 8bit unsigned sound data.
- // TODO: Actually we would need to check the frequency divisor (the
- // first word) here too. It is used in the following equation:
- // sampleRate = 256000000/(channels * (65536 - frequencyDivisor))
- assert(len == 4);
- stream.readUint16LE();
- uint8 codec = stream.readByte();
- uint8 channels = stream.readByte() + 1;
- assert(codec == 0 && channels == 1);
- } break;
- default:
- warning("Unhandled code %d in VOC file (len %d)", code, len);
- return ret_sound;
}
+
+ // Advance to the next block in case the current
+ // one is already finished.
+ updateBlockIfNeeded();
}
- debug(4, "VOC Data Size : %d", size);
- return ret_sound;
+
+ return bufferedSamples;
}
-#ifdef STREAM_AUDIO_FROM_DISK
+bool VocStream::seek(const Timestamp &where) {
+ // Invalidate stream
+ _blockLeft = 0;
+ _curBlock = _blocks.end();
-int parseVOCFormat(Common::SeekableReadStream& stream, RawStreamBlock* block, int &rate) {
- VocFileHeader fileHeader;
- int currentBlock = 0;
- int size = 0;
+ if (where > _length)
+ return false;
- debug(2, "parseVOCFormat");
+ // Search for the block containing the requested sample
+ const uint32 seekSample = convertTimeToStreamPos(where, getRate(), isStereo()).totalNumberOfFrames();
+ uint32 curSample = 0;
- if (stream.read(&fileHeader, 8) != 8)
- goto invalid;
+ for (_curBlock = _blocks.begin(); _curBlock != _blocks.end(); ++_curBlock) {
+ // Skip all none sample blocks for now
+ if (_curBlock->code != 1 && _curBlock->code != 9)
+ continue;
- if (!memcmp(&fileHeader, "VTLK", 4)) {
- if (stream.read(&fileHeader, sizeof(VocFileHeader)) != sizeof(VocFileHeader))
- goto invalid;
- } else if (!memcmp(&fileHeader, "Creative", 8)) {
- if (stream.read(((byte *)&fileHeader) + 8, sizeof(VocFileHeader) - 8) != sizeof(VocFileHeader) - 8)
- goto invalid;
+ uint32 nextBlockSample = curSample + _curBlock->sampleBlock.samples;
+
+ if (nextBlockSample > seekSample)
+ break;
+
+ curSample = nextBlockSample;
+ }
+
+ if (_curBlock == _blocks.end()) {
+ return ((seekSample - curSample) == 0);
} else {
- invalid:;
- warning("loadVOCFromStream: Invalid header");
- return 0;
+ const uint32 offset = seekSample - curSample;
+
+ _stream->seek(_curBlock->sampleBlock.offset + offset, SEEK_SET);
+
+ // In case of an error we will stop
+ // stream playback.
+ if (_stream->err()) {
+ _blockLeft = 0;
+ _curBlock = _blocks.end();
+ } else {
+ _blockLeft = _curBlock->sampleBlock.samples - offset;
+ }
+
+ return true;
}
+}
- if (memcmp(fileHeader.desc, "Creative Voice File", 19) != 0)
- error("loadVOCFromStream: Invalid header");
- if (fileHeader.desc[19] != 0x1A)
- debug(3, "loadVOCFromStream: Partially invalid header");
+void VocStream::preProcess() {
+ Block block;
- int32 offset = FROM_LE_16(fileHeader.datablock_offset);
- int16 version = FROM_LE_16(fileHeader.version);
- int16 code = FROM_LE_16(fileHeader.id);
- assert(offset == sizeof(VocFileHeader));
- // 0x100 is an invalid VOC version used by German version of DOTT (Disk) and
- // French version of Simon the Sorcerer 2 (CD)
- assert(version == 0x010A || version == 0x0114 || version == 0x0100);
- assert(code == ~version + 0x1234);
+ // Scan through the file and collect all blocks
+ while (true) {
+ block.code = _stream->readByte();
+ block.length = 0;
- int len;
- size = 0;
+ // If we hit EOS here we found the end of the VOC file.
+ // According to http://wiki.multimedia.cx/index.php?title=Creative_Voice
+ // there is no need for an "Terminator" block to be present.
+ // In case we hit a "Terminator" block we also break here.
+ if (_stream->eos() || block.code == 0)
+ break;
+ // We also allow 128 as terminator, since Simon 1 Amiga CD32 uses it.
+ if (block.code == 128) {
+ debug(3, "VocStream::preProcess: Caught 128 as terminator");
+ break;
+ }
- while ((code = stream.readByte())) {
- len = stream.readByte();
- len |= stream.readByte() << 8;
- len |= stream.readByte() << 16;
+ block.length = _stream->readByte();
+ block.length |= _stream->readByte() << 8;
+ block.length |= _stream->readByte() << 16;
- debug(2, "Block code %d, len %d", code, len);
+ // Premature end of stream => error!
+ if (_stream->eos() || _stream->err()) {
+ warning("VocStream::preProcess: Reading failed");
+ return;
+ }
+
+ uint32 skip = 0;
- switch (code) {
+ switch (block.code) {
+ // Sound data
case 1:
- case 9: {
- int packing;
- if (code == 1) {
- int time_constant = stream.readByte();
- packing = stream.readByte();
- len -= 2;
- rate = getSampleRateFromVOCRate(time_constant);
+ // Sound data (New format)
+ case 9:
+ if (block.code == 1) {
+ if (block.length < 2) {
+ warning("Invalid sound data block length %d in VOC file", block.length);
+ return;
+ }
+
+ // Read header data
+ int freqDiv = _stream->readByte();
+ // Prevent division through 0
+ if (freqDiv == 256) {
+ warning("Invalid frequency divisor 256 in VOC file");
+ return;
+ }
+ block.sampleBlock.rate = getSampleRateFromVOCRate(freqDiv);
+
+ int codec = _stream->readByte();
+ // We only support 8bit PCM
+ if (codec != 0) {
+ warning("Unhandled codec %d in VOC file", codec);
+ return;
+ }
+
+ block.sampleBlock.samples = skip = block.length - 2;
+ block.sampleBlock.offset = _stream->pos();
+
+ // Check the last block if there is any
+ if (_blocks.size() > 0) {
+ BlockList::iterator lastBlock = _blocks.end();
+ --lastBlock;
+ // When we have found a block 8 as predecessor
+ // we need to use its settings
+ if (lastBlock->code == 8) {
+ block.sampleBlock.rate = lastBlock->sampleBlock.rate;
+ // Remove the block since we don't need it anymore
+ _blocks.erase(lastBlock);
+ }
+ }
} else {
- rate = stream.readUint32LE();
- int bits = stream.readByte();
- int channels = stream.readByte();
- if (bits != 8 || channels != 1) {
- warning("Unsupported VOC file format (%d bits per sample, %d channels)", bits, channels);
- break;
+ if (block.length < 12) {
+ warning("Invalid sound data (wew format) block length %d in VOC file", block.length);
+ return;
+ }
+
+ block.sampleBlock.rate = _stream->readUint32LE();
+ int bitsPerSample = _stream->readByte();
+ // We only support 8bit PCM
+ if (bitsPerSample != 8) {
+ warning("Unhandled bits per sample %d in VOC file", bitsPerSample);
+ return;
+ }
+ int channels = _stream->readByte();
+ // We only support mono
+ if (channels != 1) {
+ warning("Unhandled channel count %d in VOC file", channels);
+ return;
}
- packing = stream.readUint16LE();
- stream.readUint32LE();
- len -= 12;
+ int codec = _stream->readUint16LE();
+ // We only support 8bit PCM
+ if (codec != 0) {
+ warning("Unhandled codec %d in VOC file", codec);
+ return;
+ }
+ /*uint32 reserved = */_stream->readUint32LE();
+ block.sampleBlock.offset = _stream->pos();
+ block.sampleBlock.samples = skip = block.length - 12;
}
- debug(9, "VOC Data Block: %d, %d, %d", rate, packing, len);
- if (packing == 0) {
- // Found a data block - so add it to the block list
- block[currentBlock].pos = stream.pos();
- block[currentBlock].len = len;
- currentBlock++;
+ // Check whether we found a new highest rate
+ if (_rate < block.sampleBlock.rate)
+ _rate = block.sampleBlock.rate;
+ break;
- stream.seek(len, SEEK_CUR);
+ // Silence
+ case 3: {
+ if (block.length != 3) {
+ warning("Invalid silence block length %d in VOC file", block.length);
+ return;
+ }
- size += len;
- } else {
- warning("VOC file packing %d unsupported", packing);
+ block.sampleBlock.offset = 0;
+
+ block.sampleBlock.samples = _stream->readUint16LE() + 1;
+ int freqDiv = _stream->readByte();
+ // Prevent division through 0
+ if (freqDiv == 256) {
+ warning("Invalid frequency divisor 256 in VOC file");
+ return;
}
+ block.sampleBlock.rate = getSampleRateFromVOCRate(freqDiv);
} break;
- case 3: // silence
- // occur with a few Igor sounds, voc file starts with a silence block with a
- // frequency different from the data block. Just ignore fow now (implementing
- // it wouldn't make a big difference anyway...)
- assert(len == 3);
- stream.readUint16LE();
- stream.readByte();
- break;
- case 6: // begin of loop
- assert(len == 2);
- stream.readUint16LE();
- break;
- case 7: // end of loop
- assert(len == 0);
+
+ // Repeat start
+ case 6:
+ if (block.length != 2) {
+ warning("Invalid repeat start block length %d in VOC file", block.length);
+ return;
+ }
+
+ block.loopBlock.count = _stream->readUint16LE() + 1;
break;
- case 8: // "Extended"
- // This occures in the LoL Intro demo. This block can usually be used to create stereo
- // sound, but the LoL intro has only an empty block, thus this dummy implementation will
- // work.
- assert(len == 4);
- stream.readUint16LE();
- stream.readByte();
- stream.readByte();
+
+ // Repeat end
+ case 7:
break;
+
+ // Extra info
+ case 8: {
+ if (block.length != 4)
+ return;
+
+ int freqDiv = _stream->readUint16LE();
+ // Prevent division through 0
+ if (freqDiv == 65536) {
+ warning("Invalid frequency divisor 65536 in VOC file");
+ return;
+ }
+
+ int codec = _stream->readByte();
+ // We only support RAW 8bit PCM.
+ if (codec != 0) {
+ warning("Unhandled codec %d in VOC file", codec);
+ return;
+ }
+
+ int channels = _stream->readByte() + 1;
+ // We only support mono sound right now
+ if (channels != 1) {
+ warning("Unhandled channel count %d in VOC file", channels);
+ return;
+ }
+
+ block.sampleBlock.offset = 0;
+ block.sampleBlock.samples = 0;
+ block.sampleBlock.rate = 256000000L / (65536L - freqDiv);
+ } break;
+
default:
- warning("Unhandled code %d in VOC file (len %d)", code, len);
- return 0;
+ warning("Unhandled code %d in VOC file (len %d)", block.code, block.length);
+ return;
}
- }
- debug(4, "VOC Data Size : %d", size);
- return currentBlock;
-}
-SeekableAudioStream *makeVOCDiskStreamNoLoop(Common::SeekableReadStream *stream, byte flags, DisposeAfterUse::Flag disposeAfterUse) {
- const int MAX_AUDIO_BLOCKS = 256;
+ // Premature end of stream => error!
+ if (_stream->eos() || _stream->err()) {
+ warning("VocStream::preProcess: Reading failed");
+ return;
+ }
- RawStreamBlock *block = new RawStreamBlock[MAX_AUDIO_BLOCKS];
- int rate;
+ // Skip the rest of the block
+ if (skip)
+ _stream->skip(skip);
- int numBlocks = parseVOCFormat(*stream, block, rate);
+ _blocks.push_back(block);
+ }
- SeekableAudioStream *audioStream = 0;
+ // Since we determined the sample rate we need for playback now, we will
+ // initialize the play length.
+ _length = Timestamp(0, _rate);
+
+ // Calculate the total play time and do some more sanity checks
+ for (BlockList::const_iterator i = _blocks.begin(), end = _blocks.end(); i != end; ++i) {
+ // Check whether we found a block 8 which survived, this is not
+ // allowed to happen!
+ if (i->code == 8) {
+ warning("VOC file contains unused block 8");
+ return;
+ }
- // Create an audiostream from the data. Note the numBlocks may be 0,
- // e.g. when invalid data is encountered. See bug #2890038.
- if (numBlocks)
- audioStream = makeRawDiskStream_OLD(stream, block, numBlocks, rate, flags, disposeAfterUse);
+ // For now only use blocks with actual samples
+ if (i->code != 1 && i->code != 9)
+ continue;
- delete[] block;
+ // Check the sample rate
+ if (i->sampleBlock.rate != _rate) {
+ warning("VOC file contains chunks with different sample rates (%d != %d)", _rate, i->sampleBlock.rate);
+ return;
+ }
- return audioStream;
-}
+ _length = _length.addFrames(i->sampleBlock.samples);
+ }
-#endif
+ // Set the current block to the first block in the stream
+ rewind();
+}
-SeekableAudioStream *makeVOCStream(Common::SeekableReadStream *stream, byte flags, DisposeAfterUse::Flag disposeAfterUse) {
-#ifdef STREAM_AUDIO_FROM_DISK
- return makeVOCDiskStreamNoLoop(stream, flags, disposeAfterUse);
-#else
- int size, rate;
+} // End of anonymous namespace
- byte *data = loadVOCFromStream(*stream, size, rate);
+int getSampleRateFromVOCRate(int vocSR) {
+ if (vocSR == 0xa5 || vocSR == 0xa6) {
+ return 11025;
+ } else if (vocSR == 0xd2 || vocSR == 0xd3) {
+ return 22050;
+ } else {
+ int sr = 1000000L / (256L - vocSR);
+ // inexact sampling rates occur e.g. in the kitchen in Monkey Island,
+ // very easy to reach right from the start of the game.
+ //warning("inexact sample rate used: %i (0x%x)", sr, vocSR);
+ return sr;
+ }
+}
- if (!data) {
+SeekableAudioStream *makeVOCStream(Common::SeekableReadStream *stream, byte flags, DisposeAfterUse::Flag disposeAfterUse) {
+ if (!checkVOCHeader(*stream)) {
if (disposeAfterUse == DisposeAfterUse::YES)
delete stream;
return 0;
}
- return makeRawStream(data, size, rate, flags);
-#endif
+ SeekableAudioStream *audioStream = new VocStream(stream, (flags & Audio::FLAG_UNSIGNED) != 0, disposeAfterUse);
+
+ if (audioStream && audioStream->endOfData()) {
+ delete audioStream;
+ return 0;
+ } else {
+ return audioStream;
+ }
}
} // End of namespace Audio
diff --git a/audio/decoders/voc.h b/audio/decoders/voc.h
index a920eac933..e16ffce42f 100644
--- a/audio/decoders/voc.h
+++ b/audio/decoders/voc.h
@@ -30,8 +30,8 @@
* - touche
*/
-#ifndef SOUND_VOC_H
-#define SOUND_VOC_H
+#ifndef AUDIO_VOC_H
+#define AUDIO_VOC_H
#include "common/scummsys.h"
#include "common/types.h"
@@ -78,14 +78,6 @@ struct VocBlockHeader {
extern int getSampleRateFromVOCRate(int vocSR);
/**
- * Try to load a VOC from the given stream. Returns a pointer to memory
- * containing the PCM sample data (allocated with malloc). It is the callers
- * responsibility to dellocate that data again later on! Currently this
- * function only supports uncompressed raw PCM data.
- */
-extern byte *loadVOCFromStream(Common::ReadStream &stream, int &size, int &rate);
-
-/**
* Try to load a VOC from the given seekable stream and create an AudioStream
* from that data. Currently this function only supports uncompressed raw PCM
* data.
diff --git a/audio/decoders/vorbis.h b/audio/decoders/vorbis.h
index e3d989e9b8..3a3052ed7c 100644
--- a/audio/decoders/vorbis.h
+++ b/audio/decoders/vorbis.h
@@ -26,7 +26,6 @@
* - agos
* - draci
* - kyra
- * - m4
* - queen
* - saga
* - sci
@@ -38,8 +37,8 @@
* - tucker
*/
-#ifndef SOUND_VORBIS_H
-#define SOUND_VORBIS_H
+#ifndef AUDIO_VORBIS_H
+#define AUDIO_VORBIS_H
#include "common/scummsys.h"
#include "common/types.h"
@@ -69,4 +68,4 @@ SeekableAudioStream *makeVorbisStream(
} // End of namespace Audio
#endif // #ifdef USE_VORBIS
-#endif // #ifndef SOUND_VORBIS_H
+#endif // #ifndef AUDIO_VORBIS_H
diff --git a/audio/decoders/wave.cpp b/audio/decoders/wave.cpp
index 3cf4566d0c..44188f84ca 100644
--- a/audio/decoders/wave.cpp
+++ b/audio/decoders/wave.cpp
@@ -175,6 +175,13 @@ RewindableAudioStream *makeWAVStream(Common::SeekableReadStream *stream, Dispose
else if (type == 2) // MS ADPCM
return makeADPCMStream(stream, disposeAfterUse, size, Audio::kADPCMMS, rate, (flags & Audio::FLAG_STEREO) ? 2 : 1, blockAlign);
+ // Raw PCM, make sure the last packet is complete
+ uint sampleSize = (flags & Audio::FLAG_16BITS ? 2 : 1) * (flags & Audio::FLAG_STEREO ? 2 : 1);
+ if (size % sampleSize != 0) {
+ warning("makeWAVStream: Trying to play a WAVE file with an incomplete PCM packet");
+ size &= ~(sampleSize - 1);
+ }
+
// Raw PCM. Just read everything at once.
// TODO: More elegant would be to wrap the stream.
byte *data = (byte *)malloc(size);
diff --git a/audio/decoders/wave.h b/audio/decoders/wave.h
index 6a34bc175a..c8ac7fe318 100644
--- a/audio/decoders/wave.h
+++ b/audio/decoders/wave.h
@@ -34,8 +34,8 @@
* - tucker
*/
-#ifndef SOUND_WAVE_H
-#define SOUND_WAVE_H
+#ifndef AUDIO_WAVE_H
+#define AUDIO_WAVE_H
#include "common/scummsys.h"
#include "common/types.h"
diff --git a/audio/fmopl.h b/audio/fmopl.h
index f62587f557..323cc3d028 100644
--- a/audio/fmopl.h
+++ b/audio/fmopl.h
@@ -19,8 +19,8 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef SOUND_FMOPL_H
-#define SOUND_FMOPL_H
+#ifndef AUDIO_FMOPL_H
+#define AUDIO_FMOPL_H
#include "common/scummsys.h"
diff --git a/audio/mididrv.cpp b/audio/mididrv.cpp
index f638250dcd..0518915e81 100644
--- a/audio/mididrv.cpp
+++ b/audio/mididrv.cpp
@@ -22,6 +22,7 @@
#include "common/config-manager.h"
#include "common/error.h"
+#include "common/gui_options.h"
#include "common/str.h"
#include "common/system.h"
#include "common/textconsole.h"
@@ -59,22 +60,22 @@ static const struct {
uint32 type;
const char *guio;
} GUIOMapping[] = {
- { MT_PCSPK, GUIO_MIDIPCSPK, },
- { MT_CMS, GUIO_MIDICMS, },
- { MT_PCJR, GUIO_MIDIPCJR, },
- { MT_ADLIB, GUIO_MIDIADLIB, },
- { MT_C64, GUIO_MIDIC64, },
- { MT_AMIGA, GUIO_MIDIAMIGA, },
- { MT_APPLEIIGS, GUIO_MIDIAPPLEIIGS, },
- { MT_TOWNS, GUIO_MIDITOWNS, },
- { MT_PC98, GUIO_MIDIPC98, },
- { MT_GM, GUIO_MIDIGM, },
- { MT_MT32, GUIO_MIDIMT32, },
+ { MT_PCSPK, GUIO_MIDIPCSPK },
+ { MT_CMS, GUIO_MIDICMS },
+ { MT_PCJR, GUIO_MIDIPCJR },
+ { MT_ADLIB, GUIO_MIDIADLIB },
+ { MT_C64, GUIO_MIDIC64 },
+ { MT_AMIGA, GUIO_MIDIAMIGA },
+ { MT_APPLEIIGS, GUIO_MIDIAPPLEIIGS },
+ { MT_TOWNS, GUIO_MIDITOWNS },
+ { MT_PC98, GUIO_MIDIPC98 },
+ { MT_GM, GUIO_MIDIGM },
+ { MT_MT32, GUIO_MIDIMT32 },
{ 0, 0 },
};
Common::String MidiDriver::musicType2GUIO(uint32 musicType) {
- Common::String res = "";
+ Common::String res;
for (int i = 0; GUIOMapping[i].guio; i++) {
if (musicType == GUIOMapping[i].type || musicType == (uint32)-1)
diff --git a/audio/mididrv.h b/audio/mididrv.h
index cdf2943f2a..fb3e29bd60 100644
--- a/audio/mididrv.h
+++ b/audio/mididrv.h
@@ -20,8 +20,8 @@
*
*/
-#ifndef SOUND_MIDIDRV_H
-#define SOUND_MIDIDRV_H
+#ifndef AUDIO_MIDIDRV_H
+#define AUDIO_MIDIDRV_H
#include "common/scummsys.h"
#include "common/str.h"
diff --git a/audio/midiparser.h b/audio/midiparser.h
index 9dff4b54ba..c935969e72 100644
--- a/audio/midiparser.h
+++ b/audio/midiparser.h
@@ -22,8 +22,8 @@
/// \brief Declarations related to the MidiParser class
-#ifndef SOUND_MIDIPARSER_H
-#define SOUND_MIDIPARSER_H
+#ifndef AUDIO_MIDIPARSER_H
+#define AUDIO_MIDIPARSER_H
#include "common/scummsys.h"
#include "common/endian.h"
diff --git a/audio/midiplayer.h b/audio/midiplayer.h
index e1da0bfb79..e58c78cafd 100644
--- a/audio/midiplayer.h
+++ b/audio/midiplayer.h
@@ -20,8 +20,8 @@
*
*/
-#ifndef SOUND_MIDIPLAYER_H
-#define SOUND_MIDIPLAYER_H
+#ifndef AUDIO_MIDIPLAYER_H
+#define AUDIO_MIDIPLAYER_H
#include "common/scummsys.h"
#include "common/mutex.h"
diff --git a/audio/mixer.h b/audio/mixer.h
index de709e13fe..e38e052bef 100644
--- a/audio/mixer.h
+++ b/audio/mixer.h
@@ -20,8 +20,8 @@
*
*/
-#ifndef SOUND_MIXER_H
-#define SOUND_MIXER_H
+#ifndef AUDIO_MIXER_H
+#define AUDIO_MIXER_H
#include "common/types.h"
#include "common/noncopyable.h"
diff --git a/audio/mixer_intern.h b/audio/mixer_intern.h
index dc361ce560..c6dfa55ada 100644
--- a/audio/mixer_intern.h
+++ b/audio/mixer_intern.h
@@ -20,8 +20,8 @@
*
*/
-#ifndef SOUND_MIXER_INTERN_H
-#define SOUND_MIXER_INTERN_H
+#ifndef AUDIO_MIXER_INTERN_H
+#define AUDIO_MIXER_INTERN_H
#include "common/scummsys.h"
#include "common/mutex.h"
diff --git a/audio/mods/infogrames.h b/audio/mods/infogrames.h
index 307a26d4e1..8b246eebe7 100644
--- a/audio/mods/infogrames.h
+++ b/audio/mods/infogrames.h
@@ -26,8 +26,8 @@
* - gob
*/
-#ifndef SOUND_MODS_INFOGRAMES_H
-#define SOUND_MODS_INFOGRAMES_H
+#ifndef AUDIO_MODS_INFOGRAMES_H
+#define AUDIO_MODS_INFOGRAMES_H
#include "audio/mods/paula.h"
diff --git a/audio/mods/maxtrax.cpp b/audio/mods/maxtrax.cpp
index 344d678b76..8ed51ae5c3 100644
--- a/audio/mods/maxtrax.cpp
+++ b/audio/mods/maxtrax.cpp
@@ -29,7 +29,7 @@
#include "audio/mods/maxtrax.h"
// test for engines using this class.
-#if defined(SOUND_MODS_MAXTRAX_H)
+#if defined(AUDIO_MODS_MAXTRAX_H)
namespace {
@@ -1034,4 +1034,4 @@ void MaxTrax::outPutScore(const Score &sc, int num) {}
} // End of namespace Audio
-#endif // #if defined(SOUND_MODS_MAXTRAX_H)
+#endif // #if defined(AUDIO_MODS_MAXTRAX_H)
diff --git a/audio/mods/maxtrax.h b/audio/mods/maxtrax.h
index bef6669d2a..c61f4e1b50 100644
--- a/audio/mods/maxtrax.h
+++ b/audio/mods/maxtrax.h
@@ -24,8 +24,8 @@
#if !defined(ENABLE_KYRA)
// normal Header Guard
-#elif !defined SOUND_MODS_MAXTRAX_H
-#define SOUND_MODS_MAXTRAX_H
+#elif !defined AUDIO_MODS_MAXTRAX_H
+#define AUDIO_MODS_MAXTRAX_H
// #define MAXTRAX_HAS_MODULATION
// #define MAXTRAX_HAS_MICROTONAL
@@ -219,4 +219,4 @@ private:
};
} // End of namespace Audio
-#endif // !defined SOUND_MODS_MAXTRAX_H
+#endif // !defined AUDIO_MODS_MAXTRAX_H
diff --git a/audio/mods/module.h b/audio/mods/module.h
index a57a89225e..eb7cbf260e 100644
--- a/audio/mods/module.h
+++ b/audio/mods/module.h
@@ -20,8 +20,8 @@
*
*/
-#ifndef SOUND_MODS_MODULE_H
-#define SOUND_MODS_MODULE_H
+#ifndef AUDIO_MODS_MODULE_H
+#define AUDIO_MODS_MODULE_H
#include "common/scummsys.h"
diff --git a/audio/mods/paula.h b/audio/mods/paula.h
index cd797f51cb..5d11cc7bb6 100644
--- a/audio/mods/paula.h
+++ b/audio/mods/paula.h
@@ -20,8 +20,8 @@
*
*/
-#ifndef SOUND_MODS_PAULA_H
-#define SOUND_MODS_PAULA_H
+#ifndef AUDIO_MODS_PAULA_H
+#define AUDIO_MODS_PAULA_H
#include "audio/audiostream.h"
#include "common/frac.h"
diff --git a/audio/mods/protracker.h b/audio/mods/protracker.h
index 15f708d801..d52322f07e 100644
--- a/audio/mods/protracker.h
+++ b/audio/mods/protracker.h
@@ -27,8 +27,8 @@
* - parallaction
*/
-#ifndef SOUND_MODS_PROTRACKER_H
-#define SOUND_MODS_PROTRACKER_H
+#ifndef AUDIO_MODS_PROTRACKER_H
+#define AUDIO_MODS_PROTRACKER_H
namespace Common {
class SeekableReadStream;
diff --git a/audio/mods/rjp1.h b/audio/mods/rjp1.h
index 232b1926e9..e7e54dafb3 100644
--- a/audio/mods/rjp1.h
+++ b/audio/mods/rjp1.h
@@ -26,8 +26,8 @@
* - queen
*/
-#ifndef SOUND_MODS_RJP1_H
-#define SOUND_MODS_RJP1_H
+#ifndef AUDIO_MODS_RJP1_H
+#define AUDIO_MODS_RJP1_H
namespace Common {
class SeekableReadStream;
diff --git a/audio/mods/soundfx.h b/audio/mods/soundfx.h
index 48ccff2da6..d517c6c78f 100644
--- a/audio/mods/soundfx.h
+++ b/audio/mods/soundfx.h
@@ -26,8 +26,8 @@
* - cine
*/
-#ifndef SOUND_MODS_SOUNDFX_H
-#define SOUND_MODS_SOUNDFX_H
+#ifndef AUDIO_MODS_SOUNDFX_H
+#define AUDIO_MODS_SOUNDFX_H
namespace Common {
class SeekableReadStream;
diff --git a/audio/mods/tfmx.cpp b/audio/mods/tfmx.cpp
index a89da78af1..2957529afc 100644
--- a/audio/mods/tfmx.cpp
+++ b/audio/mods/tfmx.cpp
@@ -29,7 +29,7 @@
#include "audio/mods/tfmx.h"
// test for engines using this class.
-#if defined(SOUND_MODS_TFMX_H)
+#if defined(AUDIO_MODS_TFMX_H)
// couple debug-functions
namespace {
@@ -876,7 +876,7 @@ const int8 *Tfmx::loadSampleFile(uint32 &sampleLen, Common::SeekableReadStream &
const int32 sampleSize = sampleStream.size();
if (sampleSize < 4) {
warning("Tfmx: Cant load Samplefile");
- return false;
+ return 0;
}
int8 *sampleAlloc = new int8[sampleSize];
@@ -1187,4 +1187,4 @@ void displayPatternstep(const void * const vptr) {
} // End of anonymous namespace
#endif
-#endif // #if defined(SOUND_MODS_TFMX_H)
+#endif // #if defined(AUDIO_MODS_TFMX_H)
diff --git a/audio/mods/tfmx.h b/audio/mods/tfmx.h
index 2b07e2e660..4174fbfb27 100644
--- a/audio/mods/tfmx.h
+++ b/audio/mods/tfmx.h
@@ -24,8 +24,8 @@
#if !defined(ENABLE_SCUMM)
// normal Header Guard
-#elif !defined(SOUND_MODS_TFMX_H)
-#define SOUND_MODS_TFMX_H
+#elif !defined(AUDIO_MODS_TFMX_H)
+#define AUDIO_MODS_TFMX_H
#include "audio/mods/paula.h"
@@ -278,4 +278,4 @@ private:
} // End of namespace Audio
-#endif // !defined(SOUND_MODS_TFMX_H)
+#endif // !defined(AUDIO_MODS_TFMX_H)
diff --git a/audio/mpu401.h b/audio/mpu401.h
index 15728a6d97..d4580b6e79 100644
--- a/audio/mpu401.h
+++ b/audio/mpu401.h
@@ -20,8 +20,8 @@
*
*/
-#ifndef SOUND_MPU401_H
-#define SOUND_MPU401_H
+#ifndef AUDIO_MPU401_H
+#define AUDIO_MPU401_H
#include "audio/mididrv.h"
diff --git a/audio/musicplugin.h b/audio/musicplugin.h
index 307293a7c9..2a0f2f0a99 100644
--- a/audio/musicplugin.h
+++ b/audio/musicplugin.h
@@ -19,8 +19,8 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef SOUND_MUSICPLUGIN_H
-#define SOUND_MUSICPLUGIN_H
+#ifndef AUDIO_MUSICPLUGIN_H
+#define AUDIO_MUSICPLUGIN_H
#include "base/plugins.h"
#include "audio/mididrv.h"
diff --git a/audio/null.h b/audio/null.h
index 97c7c8cc93..90897be6af 100644
--- a/audio/null.h
+++ b/audio/null.h
@@ -19,8 +19,8 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef SOUND_NULL_H
-#define SOUND_NULL_H
+#ifndef AUDIO_NULL_H
+#define AUDIO_NULL_H
#include "audio/musicplugin.h"
#include "audio/mpu401.h"
diff --git a/audio/rate.h b/audio/rate.h
index 72bcbf48c5..9813b75b08 100644
--- a/audio/rate.h
+++ b/audio/rate.h
@@ -20,8 +20,8 @@
*
*/
-#ifndef SOUND_RATE_H
-#define SOUND_RATE_H
+#ifndef AUDIO_RATE_H
+#define AUDIO_RATE_H
#include "common/scummsys.h"
diff --git a/audio/rate_arm_asm.s b/audio/rate_arm_asm.s
index d86d96267e..ac999f66e4 100644
--- a/audio/rate_arm_asm.s
+++ b/audio/rate_arm_asm.s
@@ -69,7 +69,7 @@ CopyRate_M_loop:
SUBS r0,r0,#1 @ len--
BGT CopyRate_M_loop @ and loop
- MOV r0, r1 @ return obuf
+ MOV r0, r1 @ return obuf
LDMFD r13!,{r4-r7,PC}
@@ -90,8 +90,8 @@ CopyRate_S_loop:
LDRSH r5, [r12],#2 @ r5 = tmp1 = *ptr++
LDRSH r6, [r1] @ r6 = obuf[0]
LDRSH r7, [r1,#2] @ r7 = obuf[1]
- MUL r4, r2, r4 @ r5 = tmp0*vol_l
- MUL r5, r3, r5 @ r6 = tmp1*vol_r
+ MUL r4, r2, r4 @ r4 = tmp0*vol_l
+ MUL r5, r3, r5 @ r5 = tmp1*vol_r
ADDS r6, r4, r6, LSL #16 @ r6 = obuf[0]<<16 + tmp0*vol_l
RSCVS r6, r14,#0x80000000 @ Clamp r6
@@ -107,7 +107,7 @@ CopyRate_S_loop:
SUBS r0,r0,#2 @ len -= 2
BGT CopyRate_S_loop @ and loop
- MOV r0, r1 @ return obuf
+ MOV r0, r1 @ return obuf
LDMFD r13!,{r4-r7,PC}
@@ -124,16 +124,16 @@ _ARM_CopyRate_R:
ORR r2, r2, r2, LSL #8 @ r2 = vol_l as 16 bits
ORR r3, r3, r3, LSL #8 @ r3 = vol_r as 16 bits
CopyRate_R_loop:
- LDRSH r5, [r12],#2 @ r5 = tmp1 = *ptr++
LDRSH r4, [r12],#2 @ r4 = tmp0 = *ptr++
+ LDRSH r5, [r12],#2 @ r5 = tmp1 = *ptr++
LDRSH r6, [r1] @ r6 = obuf[0]
LDRSH r7, [r1,#2] @ r7 = obuf[1]
MUL r4, r2, r4 @ r4 = tmp0*vol_l
MUL r5, r3, r5 @ r5 = tmp1*vol_r
- ADDS r6, r4, r6, LSL #16 @ r6 = obuf[0]<<16 + tmp0*vol_l
+ ADDS r6, r5, r6, LSL #16 @ r6 = obuf[0]<<16 + tmp1*vol_r
RSCVS r6, r14,#0x80000000 @ Clamp r6
- ADDS r7, r5, r7, LSL #16 @ r7 = obuf[1]<<16 + tmp1*vol_r
+ ADDS r7, r4, r7, LSL #16 @ r7 = obuf[1]<<16 + tmp0*vol_l
RSCVS r7, r14,#0x80000000 @ Clamp r7
MOV r6, r6, LSR #16 @ Shift back to halfword
@@ -145,7 +145,7 @@ CopyRate_R_loop:
SUBS r0,r0,#2 @ len -= 2
BGT CopyRate_R_loop @ and loop
- MOV r0, r1 @ return obuf
+ MOV r0, r1 @ return obuf
LDMFD r13!,{r4-r7,PC}
@@ -203,7 +203,7 @@ SimpleRate_M_end:
ADD r13,r13,#12 @ Skip over r0-r2 on stack
STMIA r14,{r0,r1,r2} @ Store back updated values
- MOV r0, r3 @ return obuf
+ MOV r0, r3 @ return obuf
LDMFD r13!,{r4-r8,r10-r11,PC}
SimpleRate_M_read:
@@ -212,14 +212,14 @@ SimpleRate_M_read:
STMFD r13!,{r0,r2-r3,r12,r14}
MOV r1, r0 @ r1 = inBuf
- LDR r0, [r13,#20] @ r0 = AudioStream & input (20 = 4*5)
+ LDR r0, [r13,#20] @ r0 = AudioStream & input (20 = 4*5)
MOV r2, #512 @ r2 = ARRAYSIZE(inBuf)
@ Calling back into C++ here. WinCE is fairly easy about such things
@ but other OS are more awkward. r9 is preserved for Symbian, and
@ we have 3+8+5 = 16 things on the stack (an even number).
MOV r14,PC
- LDR PC,[r13,#24] @ inLen = input.readBuffer(inBuf,512) (24 = 4*6)
+ LDR PC,[r13,#24] @ inLen = input.readBuffer(inBuf,512) (24 = 4*6)
SUBS r1, r0, #1 @ r1 = inLen-1
LDMFD r13!,{r0,r2-r3,r12,r14}
BLT SimpleRate_M_end
@@ -263,8 +263,8 @@ SimpleRate_S_read_return:
LDRSH r6, [r3] @ r6 = obuf[0]
LDRSH r7, [r3,#2] @ r7 = obuf[1]
ADD r2, r2, r8 @ r2 = opos += opos_inc
- MUL r4, r12,r4 @ r5 = tmp0*vol_l
- MUL r5, r14,r5 @ r6 = tmp1*vol_r
+ MUL r4, r12,r4 @ r4 = tmp0*vol_l
+ MUL r5, r14,r5 @ r5 = tmp1*vol_r
ADDS r6, r4, r6, LSL #16 @ r6 = obuf[0]<<16 + tmp0*vol_l
RSCVS r6, r10,#0x80000000 @ Clamp r6
@@ -283,7 +283,7 @@ SimpleRate_S_end:
LDR r14,[r13,#8] @ r14 = sr
ADD r13,r13,#12 @ skip over r0-r2 on stack
STMIA r14,{r0,r1,r2} @ store back updated values
- MOV r0, r3 @ return obuf
+ MOV r0, r3 @ return obuf
LDMFD r13!,{r4-r8,r10-r11,PC}
SimpleRate_S_read:
LDR r0, [r13,#8] @ r0 = sr (8 = 4*2)
@@ -337,17 +337,17 @@ SimpleRate_R_loop:
ADDGE r0, r0, #4 @ if (r2 >= 0) { sr.inPtr += 2
BGE SimpleRate_R_loop @ and loop }
SimpleRate_R_read_return:
- LDRSH r5, [r0],#2 @ r5 = tmp0 = *inPtr++
- LDRSH r4, [r0],#2 @ r4 = tmp1 = *inPtr++
+ LDRSH r4, [r0],#2 @ r4 = tmp0 = *inPtr++
+ LDRSH r5, [r0],#2 @ r5 = tmp1 = *inPtr++
LDRSH r6, [r3] @ r6 = obuf[0]
LDRSH r7, [r3,#2] @ r7 = obuf[1]
ADD r2, r2, r8 @ r2 = opos += opos_inc
- MUL r4, r12,r4 @ r5 = tmp0*vol_l
- MUL r5, r14,r5 @ r6 = tmp1*vol_r
+ MUL r4, r12,r4 @ r4 = tmp0*vol_l
+ MUL r5, r14,r5 @ r5 = tmp1*vol_r
- ADDS r6, r4, r6, LSL #16 @ r6 = obuf[0]<<16 + tmp0*vol_l
+ ADDS r6, r5, r6, LSL #16 @ r6 = obuf[0]<<16 + tmp1*vol_r
RSCVS r6, r10,#0x80000000 @ Clamp r6
- ADDS r7, r5, r7, LSL #16 @ r7 = obuf[1]<<16 + tmp1*vol_r
+ ADDS r7, r4, r7, LSL #16 @ r7 = obuf[1]<<16 + tmp0*vol_l
RSCVS r7, r10,#0x80000000 @ Clamp r7
MOV r6, r6, LSR #16 @ Shift back to halfword
@@ -360,15 +360,14 @@ SimpleRate_R_read_return:
BGT SimpleRate_R_loop @ and loop
SimpleRate_R_end:
LDR r14,[r13,#8] @ r14 = sr
- ADD r13,r13,#12 @ Skip over r0-r2 on stack
- STMIA r14,{r0,r1,r2} @ Store back updated values
- MOV r0, r3 @ return obuf
+ ADD r13,r13,#12 @ skip over r0-r2 on stack
+ STMIA r14,{r0,r1,r2} @ store back updated values
+ MOV r0, r3 @ return obuf
LDMFD r13!,{r4-r8,r10-r11,PC}
SimpleRate_R_read:
LDR r0, [r13,#8] @ r0 = sr (8 = 4*2)
ADD r0, r0, #16 @ r0 = inPtr = inBuf
STMFD r13!,{r0,r2-r3,r12,r14}
-
MOV r1, r0 @ r1 = inBuf
LDR r0, [r13,#20] @ r0 = AudioStream & input (20 = 4*5)
MOV r2, #512 @ r2 = ARRAYSIZE(inBuf)
@@ -459,7 +458,7 @@ LinearRate_M_part2:
LinearRate_M_end:
ADD r13,r13,#8
STMIA r2,{r0,r1,r8}
- MOV r0, r3 @ return obuf
+ MOV r0, r3 @ return obuf
LDMFD r13!,{r4-r11,PC}
LinearRate_M_read:
ADD r0, r2, #28 @ r0 = inPtr = inBuf
@@ -473,7 +472,7 @@ LinearRate_M_read:
@ but other OS are more awkward. r9 is preserved for Symbian, and
@ we have 2+9+5 = 16 things on the stack (an even number).
MOV r14,PC
- LDR PC,[r13,#24] @ inLen = input.readBuffer(inBuf,512) (24 = 4*6)
+ LDR PC,[r13,#24] @ inLen = input.readBuffer(inBuf,512) (24 = 4*6)
SUBS r1, r0, #1 @ r1 = inLen-1
LDMFD r13!,{r0,r2-r3,r12,r14}
BLT LinearRate_M_end
@@ -509,7 +508,7 @@ LinearRate_S_loop:
LinearRate_S_read_return:
LDR r10,[r2, #16] @ r10= icur[0,1]
LDRSH r5, [r0],#2 @ r5 = tmp0 = *inPtr++
- LDRSH r6, [r0],#2 @ r5 = tmp1 = *inPtr++
+ LDRSH r6, [r0],#2 @ r6 = tmp1 = *inPtr++
SUBS r8, r8, #65536 @ r8 = opos--
STRH r10,[r2,#22] @ ilast[0] = icur[0]
MOV r10,r10,LSR #16
@@ -561,21 +560,21 @@ LinearRate_S_part2:
LinearRate_S_end:
ADD r13,r13,#8
STMIA r2,{r0,r1,r8}
- MOV r0, r3 @ return obuf
+ MOV r0, r3 @ return obuf
LDMFD r13!,{r4-r11,PC}
LinearRate_S_read:
ADD r0, r2, #28 @ r0 = inPtr = inBuf
STMFD r13!,{r0,r2-r3,r12,r14}
MOV r1, r0 @ r1 = inBuf
- LDR r0, [r13,#20] @ r0 = AudioStream & input (20 = 4*5)
+ LDR r0, [r13,#20] @ r0 = AudioStream & input (20 = 4*5)
MOV r2, #512 @ r2 = ARRAYSIZE(inBuf)
@ Calling back into C++ here. WinCE is fairly easy about such things
@ but other OS are more awkward. r9 is preserved for Symbian, and
@ we have 2+9+5 = 16 things on the stack (an even number).
MOV r14,PC
- LDR PC,[r13,#24] @ inLen = input.readBuffer(inBuf,512) (24 = 4*6)
+ LDR PC,[r13,#24] @ inLen = input.readBuffer(inBuf,512) (24 = 4*6)
SUBS r1, r0, #2 @ r1 = inLen-2
LDMFD r13!,{r0,r2-r3,r12,r14}
BLT LinearRate_S_end
@@ -611,41 +610,41 @@ LinearRate_R_loop:
LinearRate_R_read_return:
LDR r10,[r2, #16] @ r10= icur[0,1]
LDRSH r5, [r0],#2 @ r5 = tmp0 = *inPtr++
- LDRSH r6, [r0],#2 @ r5 = tmp1 = *inPtr++
+ LDRSH r6, [r0],#2 @ r6 = tmp1 = *inPtr++
SUBS r8, r8, #65536 @ r8 = opos--
- STRH r10,[r2,#22] @ ilast[0] = icur[0]
+ STRH r10,[r2,#22] @ ilast[0] = icur[0]
MOV r10,r10,LSR #16
- STRH r10,[r2,#22] @ ilast[1] = icur[1]
- STRH r5, [r2,#16] @ icur[0] = tmp0
- STRH r6, [r2,#18] @ icur[1] = tmp1
+ STRH r10,[r2,#26] @ ilast[1] = icur[1]
+ STRH r5, [r2,#16] @ icur[0] = tmp0
+ STRH r6, [r2,#18] @ icur[1] = tmp1
BGE LinearRate_R_loop
@ part2 - form output samples
LinearRate_R_part2:
@ We are guaranteed that opos < 0 here
- LDR r6, [r2,#20] @ r6 = ilast[0]
+ LDR r6, [r2,#20] @ r6 = ilast[0]<<16 + 32768
LDRSH r5, [r2,#16] @ r5 = icur[0]
MOV r4, r8, LSL #16
MOV r4, r4, LSR #16
SUB r5, r5, r6, ASR #16 @ r5 = icur[0] - ilast[0]
MLA r6, r4, r5, r6 @ r6 = (icur[0]-ilast[0])*opos_frac+ilast[0]
- LDR r7, [r2,#24] @ r7 = ilast[1]
+ LDR r7, [r2,#24] @ r7 = ilast[1]<<16 + 32768
LDRSH r5, [r2,#18] @ r5 = icur[1]
- LDR r10,[r3] @ r10= obuf[0]
+ LDRSH r10,[r3,#2] @ r10= obuf[1]
MOV r6, r6, ASR #16 @ r6 = tmp1 >>= 16
SUB r5, r5, r7, ASR #16 @ r5 = icur[1] - ilast[1]
MLA r7, r4, r5, r7 @ r7 = (icur[1]-ilast[1])*opos_frac+ilast[1]
- LDRSH r5, [r3,#2] @ r5 = obuf[1]
+ LDRSH r5, [r3] @ r5 = obuf[0]
MOV r7, r7, ASR #16 @ r7 = tmp0 >>= 16
MUL r7, r12,r7 @ r7 = tmp0*vol_l
MUL r6, r14,r6 @ r6 = tmp1*vol_r
- ADDS r7, r7, r10, LSL #16 @ r7 = obuf[0]<<16 + tmp0*vol_l
+ ADDS r7, r7, r10, LSL #16 @ r7 = obuf[1]<<16 + tmp0*vol_l
MOV r4, #0
RSCVS r7, r4, #0x80000000 @ Clamp r7
- ADDS r6, r6, r5, LSL #16 @ r6 = obuf[1]<<16 + tmp1*vol_r
+ ADDS r6, r6, r5, LSL #16 @ r6 = obuf[0]<<16 + tmp1*vol_r
RSCVS r6, r4, #0x80000000 @ Clamp r6
MOV r7, r7, LSR #16 @ Shift back to halfword
@@ -663,21 +662,21 @@ LinearRate_R_part2:
LinearRate_R_end:
ADD r13,r13,#8
STMIA r2,{r0,r1,r8}
- MOV r0, r3 @ return obuf
+ MOV r0, r3 @ return obuf
LDMFD r13!,{r4-r11,PC}
LinearRate_R_read:
ADD r0, r2, #28 @ r0 = inPtr = inBuf
STMFD r13!,{r0,r2-r3,r12,r14}
MOV r1, r0 @ r1 = inBuf
- LDR r0, [r13,#20] @ r0 = AudioStream & input (20 = 4*5)
+ LDR r0, [r13,#20] @ r0 = AudioStream & input (20 = 4*5)
MOV r2, #512 @ r2 = ARRAYSIZE(inBuf)
@ Calling back into C++ here. WinCE is fairly easy about such things
@ but other OS are more awkward. r9 is preserved for Symbian, and
@ we have 2+9+5 = 16 things on the stack (an even number).
MOV r14,PC
- LDR PC,[r13,#24] @ inLen = input.readBuffer(inBuf,512) (24 = 4*6)
+ LDR PC,[r13,#24] @ inLen = input.readBuffer(inBuf,512) (24 = 4*6)
SUBS r1, r0, #2 @ r1 = inLen-2
LDMFD r13!,{r0,r2-r3,r12,r14}
BLT LinearRate_R_end
diff --git a/audio/softsynth/adlib.cpp b/audio/softsynth/adlib.cpp
index 4025a667ac..32a5f4a910 100644
--- a/audio/softsynth/adlib.cpp
+++ b/audio/softsynth/adlib.cpp
@@ -1471,8 +1471,7 @@ void MidiDriver_ADLIB::adlib_setup_channel(int chan, AdLibInstrument *instr, byt
adlib_write((byte)chan + 0xC0, instr->feedback);
}
-void MidiDriver_ADLIB::adlib_note_on_ex(int chan, byte note, int mod)
-{
+void MidiDriver_ADLIB::adlib_note_on_ex(int chan, byte note, int mod) {
int code;
assert(chan >= 0 && chan < 9);
code = (note << 7) + mod;
diff --git a/audio/softsynth/cms.cpp b/audio/softsynth/cms.cpp
index a675da3f03..681f08dfa3 100644
--- a/audio/softsynth/cms.cpp
+++ b/audio/softsynth/cms.cpp
@@ -41,7 +41,7 @@ static const byte envelope[8][64] = {
{15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
- 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15, },
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15 },
/* single decay */
{15,14,13,12,11,10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
diff --git a/audio/softsynth/cms.h b/audio/softsynth/cms.h
index 48064746a8..0aad856a9d 100644
--- a/audio/softsynth/cms.h
+++ b/audio/softsynth/cms.h
@@ -19,8 +19,8 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef SOUND_SOFTSYNTH_CMS_H
-#define SOUND_SOFTSYNTH_CMS_H
+#ifndef AUDIO_SOFTSYNTH_CMS_H
+#define AUDIO_SOFTSYNTH_CMS_H
#include "common/scummsys.h"
diff --git a/audio/softsynth/emumidi.h b/audio/softsynth/emumidi.h
index f72dad7eaf..3e9d669933 100644
--- a/audio/softsynth/emumidi.h
+++ b/audio/softsynth/emumidi.h
@@ -19,8 +19,8 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef SOUND_SOFTSYNTH_EMUMIDI_H
-#define SOUND_SOFTSYNTH_EMUMIDI_H
+#ifndef AUDIO_SOFTSYNTH_EMUMIDI_H
+#define AUDIO_SOFTSYNTH_EMUMIDI_H
#include "audio/audiostream.h"
#include "audio/mididrv.h"
diff --git a/audio/softsynth/fmtowns_pc98/towns_audio.cpp b/audio/softsynth/fmtowns_pc98/towns_audio.cpp
index 28591117f0..d8300112bf 100644
--- a/audio/softsynth/fmtowns_pc98/towns_audio.cpp
+++ b/audio/softsynth/fmtowns_pc98/towns_audio.cpp
@@ -133,8 +133,9 @@ private:
};
class TownsAudioInterfaceInternal : public TownsPC98_FmSynth {
-public:
+private:
TownsAudioInterfaceInternal(Audio::Mixer *mixer, TownsAudioInterface *owner, TownsAudioInterfacePluginDriver *driver, bool externalMutexHandling = false);
+public:
~TownsAudioInterfaceInternal();
static TownsAudioInterfaceInternal *addNewRef(Audio::Mixer *mixer, TownsAudioInterface *owner, TownsAudioInterfacePluginDriver *driver, bool externalMutexHandling = false);
diff --git a/audio/softsynth/fmtowns_pc98/towns_pc98_driver.cpp b/audio/softsynth/fmtowns_pc98/towns_pc98_driver.cpp
index 05a4079442..f3835c4524 100644
--- a/audio/softsynth/fmtowns_pc98/towns_pc98_driver.cpp
+++ b/audio/softsynth/fmtowns_pc98/towns_pc98_driver.cpp
@@ -387,8 +387,6 @@ void TownsPC98_MusicChannel::reset() {
_totalLevel = 0;
_algorithm = 0;
- _flags = CHS_EOT;
- _algorithm = 0;
_block = 0;
_frequency = 0;
diff --git a/audio/softsynth/mt32.cpp b/audio/softsynth/mt32.cpp
index eabde21296..186118262f 100644
--- a/audio/softsynth/mt32.cpp
+++ b/audio/softsynth/mt32.cpp
@@ -84,42 +84,6 @@ public:
int getRate() const { return _outputRate; }
};
-class MT32File : public MT32Emu::File {
- Common::File _in;
- Common::DumpFile _out;
-public:
- bool open(const char *filename, OpenMode mode) {
- if (mode == OpenMode_read)
- return _in.open(filename);
- else
- return _out.open(filename);
- }
- void close() {
- _in.close();
- _out.close();
- }
- size_t read(void *in, size_t size) {
- return _in.read(in, size);
- }
- bool readBit8u(MT32Emu::Bit8u *in) {
- byte b = _in.readByte();
- if (_in.eos())
- return false;
- *in = b;
- return true;
- }
- size_t write(const void *in, size_t size) {
- return _out.write(in, size);
- }
- bool writeBit8u(MT32Emu::Bit8u out) {
- _out.writeByte(out);
- return !_out.err();
- }
- bool isEOF() {
- return _in.isOpen() && _in.eos();
- }
-};
-
static int eatSystemEvents() {
Common::Event event;
Common::EventManager *eventMan = g_system->getEventManager();
@@ -206,9 +170,9 @@ static void drawMessage(int offset, const Common::String &text) {
g_system->updateScreen();
}
-static MT32Emu::File *MT32_OpenFile(void *userData, const char *filename, MT32Emu::File::OpenMode mode) {
- MT32File *file = new MT32File();
- if (!file->open(filename, mode)) {
+static Common::File *MT32_OpenFile(void *userData, const char *filename) {
+ Common::File *file = new Common::File();
+ if (!file->open(filename)) {
delete file;
return NULL;
}
@@ -329,6 +293,11 @@ int MidiDriver_MT32::open() {
drawMessage(-1, _s("Initializing MT-32 Emulator"));
if (!_synth->open(prop))
return MERR_DEVICE_NOT_AVAILABLE;
+
+ double gain = (double)ConfMan.getInt("midi_gain") / 100.0;
+ _synth->setOutputGain(1.0f * gain);
+ _synth->setReverbOutputGain(0.68f * gain);
+
_initializing = false;
if (screenFormat.bytesPerPixel > 1)
diff --git a/audio/softsynth/mt32/AReverbModel.cpp b/audio/softsynth/mt32/AReverbModel.cpp
new file mode 100644
index 0000000000..4ee6c87943
--- /dev/null
+++ b/audio/softsynth/mt32/AReverbModel.cpp
@@ -0,0 +1,237 @@
+/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher
+ * Copyright (C) 2011 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "mt32emu.h"
+#include "AReverbModel.h"
+
+using namespace MT32Emu;
+
+// Default reverb settings for modes 0-2
+
+static const unsigned int NUM_ALLPASSES = 6;
+static const unsigned int NUM_DELAYS = 5;
+
+static const Bit32u MODE_0_ALLPASSES[] = {729, 78, 394, 994, 1250, 1889};
+static const Bit32u MODE_0_DELAYS[] = {846, 4, 1819, 778, 346};
+static const float MODE_0_TIMES[] = {0.0f, 0.1f, 0.2f, 0.3f, 0.4f, 0.5f, 0.6f, 0.9f};
+static const float MODE_0_LEVELS[] = {0.0f, 0.1f, 0.2f, 0.3f, 0.4f, 0.5f, 0.6f, 1.01575f};
+
+static const Bit32u MODE_1_ALLPASSES[] = {176, 809, 1324, 1258};
+static const Bit32u MODE_1_DELAYS[] = {2262, 124, 974, 2516, 356};
+static const float MODE_1_TIMES[] = {0.0f, 0.1f, 0.2f, 0.3f, 0.4f, 0.5f, 0.6f, 0.95f};
+static const float MODE_1_LEVELS[] = {0.0f, 0.1f, 0.2f, 0.3f, 0.4f, 0.5f, 0.6f, 1.01575f};
+
+static const Bit32u MODE_2_ALLPASSES[] = {78, 729, 994, 389};
+static const Bit32u MODE_2_DELAYS[] = {846, 4, 1819, 778, 346};
+static const float MODE_2_TIMES[] = {0.0f, 0.1f, 0.2f, 0.3f, 0.4f, 0.5f, 0.6f, 0.7f};
+static const float MODE_2_LEVELS[] = {0.0f, 0.1f, 0.2f, 0.3f, 0.4f, 0.5f, 0.6f, 0.7f};
+
+const AReverbSettings AReverbModel::REVERB_MODE_0_SETTINGS = {MODE_0_ALLPASSES, MODE_0_DELAYS, MODE_0_TIMES, MODE_0_LEVELS, 0.687770909f, 0.5f, 0.5f};
+const AReverbSettings AReverbModel::REVERB_MODE_1_SETTINGS = {MODE_1_ALLPASSES, MODE_1_DELAYS, MODE_1_TIMES, MODE_1_LEVELS, 0.712025098f, 0.375f, 0.625f};
+const AReverbSettings AReverbModel::REVERB_MODE_2_SETTINGS = {MODE_2_ALLPASSES, MODE_2_DELAYS, MODE_2_TIMES, MODE_2_LEVELS, 0.939522749f, 0.0f, 0.0f};
+
+RingBuffer::RingBuffer(Bit32u newsize) {
+ index = 0;
+ size = newsize;
+ buffer = new float[size];
+}
+
+RingBuffer::~RingBuffer() {
+ delete[] buffer;
+ buffer = NULL;
+ size = 0;
+}
+
+float RingBuffer::next() {
+ index++;
+ if (index >= size) {
+ index = 0;
+ }
+ return buffer[index];
+}
+
+bool RingBuffer::isEmpty() {
+ if (buffer == NULL) return true;
+
+ float *buf = buffer;
+ float total = 0;
+ for (Bit32u i = 0; i < size; i++) {
+ total += (*buf < 0 ? -*buf : *buf);
+ buf++;
+ }
+ return ((total / size) < .0002 ? true : false);
+}
+
+void RingBuffer::mute() {
+ float *buf = buffer;
+ for (Bit32u i = 0; i < size; i++) {
+ *buf++ = 0;
+ }
+}
+
+AllpassFilter::AllpassFilter(Bit32u useSize) : RingBuffer(useSize) {
+}
+
+Delay::Delay(Bit32u useSize) : RingBuffer(useSize) {
+}
+
+float AllpassFilter::process(float in) {
+ // This model corresponds to the allpass filter implementation in the real CM-32L device
+ // found from sample analysis
+
+ float out;
+
+ out = next();
+
+ // store input - feedback / 2
+ buffer[index] = in - 0.5f * out;
+
+ // return buffer output + feedforward / 2
+ return out + 0.5f * buffer[index];
+}
+
+float Delay::process(float in) {
+ // Implements a very simple delay
+
+ float out;
+
+ out = next();
+
+ // store input
+ buffer[index] = in;
+
+ // return buffer output
+ return out;
+}
+
+AReverbModel::AReverbModel(const AReverbSettings *useSettings) : allpasses(NULL), delays(NULL), currentSettings(useSettings) {
+}
+
+AReverbModel::~AReverbModel() {
+ close();
+}
+
+void AReverbModel::open(unsigned int /*sampleRate*/) {
+ // FIXME: filter sizes must be multiplied by sample rate to 32000Hz ratio
+ // IIR filter values depend on sample rate as well
+ allpasses = new AllpassFilter*[NUM_ALLPASSES];
+ for (Bit32u i = 0; i < NUM_ALLPASSES; i++) {
+ allpasses[i] = new AllpassFilter(currentSettings->allpassSizes[i]);
+ }
+ delays = new Delay*[NUM_DELAYS];
+ for (Bit32u i = 0; i < NUM_DELAYS; i++) {
+ delays[i] = new Delay(currentSettings->delaySizes[i]);
+ }
+ mute();
+}
+
+void AReverbModel::close() {
+ if (allpasses != NULL) {
+ for (Bit32u i = 0; i < NUM_ALLPASSES; i++) {
+ if (allpasses[i] != NULL) {
+ delete allpasses[i];
+ allpasses[i] = NULL;
+ }
+ }
+ delete[] allpasses;
+ allpasses = NULL;
+ }
+ if (delays != NULL) {
+ for (Bit32u i = 0; i < NUM_DELAYS; i++) {
+ if (delays[i] != NULL) {
+ delete delays[i];
+ delays[i] = NULL;
+ }
+ }
+ delete[] delays;
+ delays = NULL;
+ }
+}
+
+void AReverbModel::mute() {
+ for (Bit32u i = 0; i < NUM_ALLPASSES; i++) {
+ allpasses[i]->mute();
+ }
+ for (Bit32u i = 0; i < NUM_DELAYS; i++) {
+ delays[i]->mute();
+ }
+ filterhist1 = 0;
+ filterhist2 = 0;
+ combhist = 0;
+}
+
+void AReverbModel::setParameters(Bit8u time, Bit8u level) {
+// FIXME: wetLevel definitely needs ramping when changed
+// Although, most games don't set reverb level during MIDI playback
+ decayTime = currentSettings->decayTimes[time];
+ wetLevel = currentSettings->wetLevels[level];
+}
+
+bool AReverbModel::isActive() const {
+ bool bActive = false;
+ for (Bit32u i = 0; i < NUM_ALLPASSES; i++) {
+ bActive |= !allpasses[i]->isEmpty();
+ }
+ for (Bit32u i = 0; i < NUM_DELAYS; i++) {
+ bActive |= !delays[i]->isEmpty();
+ }
+ return bActive;
+}
+
+void AReverbModel::process(const float *inLeft, const float *inRight, float *outLeft, float *outRight, unsigned long numSamples) {
+// Three series allpass filters followed by a delay, fourth allpass filter and another delay
+ float dry, link, outL1, outL2, outR1, outR2;
+
+ for (unsigned long i = 0; i < numSamples; i++) {
+ dry = *inLeft + *inRight;
+
+ // Implementation of 2-stage IIR single-pole low-pass filter
+ // found at the entrance of reverb processing on real devices
+ filterhist1 += (dry - filterhist1) * currentSettings->filtVal;
+ filterhist2 += (filterhist1 - filterhist2) * currentSettings->filtVal;
+
+ link = allpasses[0]->process(-filterhist2);
+ link = allpasses[1]->process(link);
+
+ // this implements a comb filter cross-linked with the fourth allpass filter
+ link += combhist * decayTime;
+ link = allpasses[2]->process(link);
+ link = delays[0]->process(link);
+ outL1 = link;
+ link = allpasses[3]->process(link);
+ link = delays[1]->process(link);
+ outR1 = link;
+ link = allpasses[4]->process(link);
+ link = delays[2]->process(link);
+ outL2 = link;
+ link = allpasses[5]->process(link);
+ link = delays[3]->process(link);
+ outR2 = link;
+ link = delays[4]->process(link);
+
+ // comb filter end point
+ combhist = combhist * currentSettings->damp1 + link * currentSettings->damp2;
+
+ *outLeft = (outL1 + outL2) * wetLevel;
+ *outRight = (outR1 + outR2) * wetLevel;
+
+ inLeft++;
+ inRight++;
+ outLeft++;
+ outRight++;
+ }
+}
diff --git a/audio/softsynth/mt32/AReverbModel.h b/audio/softsynth/mt32/AReverbModel.h
new file mode 100644
index 0000000000..3fae08c34c
--- /dev/null
+++ b/audio/softsynth/mt32/AReverbModel.h
@@ -0,0 +1,86 @@
+/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher
+ * Copyright (C) 2011 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef MT32EMU_A_REVERB_MODEL_H
+#define MT32EMU_A_REVERB_MODEL_H
+
+namespace MT32Emu {
+
+struct AReverbSettings {
+ const Bit32u *allpassSizes;
+ const Bit32u *delaySizes;
+ const float *decayTimes;
+ const float *wetLevels;
+ float filtVal;
+ float damp1;
+ float damp2;
+};
+
+class RingBuffer {
+protected:
+ float *buffer;
+ Bit32u size;
+ Bit32u index;
+public:
+ RingBuffer(Bit32u size);
+ virtual ~RingBuffer();
+ float next();
+ bool isEmpty();
+ void mute();
+};
+
+class AllpassFilter : public RingBuffer {
+public:
+ AllpassFilter(Bit32u size);
+ float process(float in);
+};
+
+class Delay : public RingBuffer {
+public:
+ Delay(Bit32u size);
+ float process(float in);
+};
+
+class AReverbModel : public ReverbModel {
+ AllpassFilter **allpasses;
+ Delay **delays;
+
+ const AReverbSettings *currentSettings;
+ float decayTime;
+ float wetLevel;
+ float filterhist1, filterhist2;
+ float combhist;
+ void mute();
+public:
+ AReverbModel(const AReverbSettings *newSettings);
+ ~AReverbModel();
+ void open(unsigned int sampleRate);
+ void close();
+ void setParameters(Bit8u time, Bit8u level);
+ void process(const float *inLeft, const float *inRight, float *outLeft, float *outRight, unsigned long numSamples);
+ bool isActive() const;
+
+ static const AReverbSettings REVERB_MODE_0_SETTINGS;
+ static const AReverbSettings REVERB_MODE_1_SETTINGS;
+ static const AReverbSettings REVERB_MODE_2_SETTINGS;
+};
+
+// Default reverb settings for modes 0-2
+
+}
+
+#endif
diff --git a/audio/softsynth/mt32/DelayReverb.cpp b/audio/softsynth/mt32/DelayReverb.cpp
new file mode 100644
index 0000000000..89eebf0d79
--- /dev/null
+++ b/audio/softsynth/mt32/DelayReverb.cpp
@@ -0,0 +1,150 @@
+/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher
+ * Copyright (C) 2011 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+//#include <cmath>
+//#include <cstring>
+#include "mt32emu.h"
+#include "DelayReverb.h"
+
+using namespace MT32Emu;
+
+
+// CONFIRMED: The values below are found via analysis of digital samples. Checked with all time and level combinations.
+// Obviously:
+// rightDelay = (leftDelay - 2) * 2 + 2
+// echoDelay = rightDelay - 1
+// Leaving these separate in case it's useful for work on other reverb modes...
+const Bit32u REVERB_TIMINGS[8][3]= {
+ // {leftDelay, rightDelay, feedbackDelay}
+ {402, 802, 801},
+ {626, 1250, 1249},
+ {962, 1922, 1921},
+ {1490, 2978, 2977},
+ {2258, 4514, 4513},
+ {3474, 6946, 6945},
+ {5282, 10562, 10561},
+ {8002, 16002, 16001}
+};
+
+const float REVERB_FADE[8] = {0.0f, -0.049400051f, -0.08220577f, -0.131861118f, -0.197344907f, -0.262956344f, -0.345162114f, -0.509508615f};
+const float REVERB_FEEDBACK67 = -0.629960524947437f; // = -EXP2F(-2 / 3)
+const float REVERB_FEEDBACK = -0.682034520443118f; // = -EXP2F(-53 / 96)
+const float LPF_VALUE = 0.594603558f; // = EXP2F(-0.75f)
+
+DelayReverb::DelayReverb() {
+ buf = NULL;
+ sampleRate = 0;
+ setParameters(0, 0);
+}
+
+DelayReverb::~DelayReverb() {
+ delete[] buf;
+}
+
+void DelayReverb::open(unsigned int newSampleRate) {
+ if (newSampleRate != sampleRate || buf == NULL) {
+ sampleRate = newSampleRate;
+
+ delete[] buf;
+
+ // If we ever need a speedup, set bufSize to EXP2F(ceil(log2(bufSize))) and use & instead of % to find buf indexes
+ bufSize = 16384 * sampleRate / 32000;
+ buf = new float[bufSize];
+
+ recalcParameters();
+
+ // mute buffer
+ bufIx = 0;
+ if (buf != NULL) {
+ for (unsigned int i = 0; i < bufSize; i++) {
+ buf[i] = 0.0f;
+ }
+ }
+ }
+ // FIXME: IIR filter value depends on sample rate as well
+}
+
+void DelayReverb::close() {
+ delete[] buf;
+ buf = NULL;
+}
+
+// This method will always trigger a flush of the buffer
+void DelayReverb::setParameters(Bit8u newTime, Bit8u newLevel) {
+ time = newTime;
+ level = newLevel;
+ recalcParameters();
+}
+
+void DelayReverb::recalcParameters() {
+ // Number of samples between impulse and eventual appearance on the left channel
+ delayLeft = REVERB_TIMINGS[time][0] * sampleRate / 32000;
+ // Number of samples between impulse and eventual appearance on the right channel
+ delayRight = REVERB_TIMINGS[time][1] * sampleRate / 32000;
+ // Number of samples between a response and that response feeding back/echoing
+ delayFeedback = REVERB_TIMINGS[time][2] * sampleRate / 32000;
+
+ if (time < 6) {
+ feedback = REVERB_FEEDBACK;
+ } else {
+ feedback = REVERB_FEEDBACK67;
+ }
+
+ // Fading speed, i.e. amplitude ratio of neighbor responses
+ fade = REVERB_FADE[level];
+}
+
+void DelayReverb::process(const float *inLeft, const float *inRight, float *outLeft, float *outRight, unsigned long numSamples) {
+ if (buf == NULL) {
+ return;
+ }
+
+ for (unsigned int sampleIx = 0; sampleIx < numSamples; sampleIx++) {
+ // The ring buffer write index moves backwards; reads are all done with positive offsets.
+ Bit32u bufIxPrev = (bufIx + 1) % bufSize;
+ Bit32u bufIxLeft = (bufIx + delayLeft) % bufSize;
+ Bit32u bufIxRight = (bufIx + delayRight) % bufSize;
+ Bit32u bufIxFeedback = (bufIx + delayFeedback) % bufSize;
+
+ // Attenuated input samples and feedback response are directly added to the current ring buffer location
+ float sample = fade * (inLeft[sampleIx] + inRight[sampleIx]) + feedback * buf[bufIxFeedback];
+
+ // Single-pole IIR filter found on real devices
+ buf[bufIx] = buf[bufIxPrev] + (sample - buf[bufIxPrev]) * LPF_VALUE;
+
+ outLeft[sampleIx] = buf[bufIxLeft];
+ outRight[sampleIx] = buf[bufIxRight];
+
+ bufIx = (bufSize + bufIx - 1) % bufSize;
+ }
+}
+
+bool DelayReverb::isActive() const {
+ // Quick hack: Return true iff all samples in the left buffer are the same and
+ // all samples in the right buffers are the same (within the sample output threshold).
+ if (buf == NULL) {
+ return false;
+ }
+ float last = buf[0] * 8192.0f;
+ for (unsigned int i = 1; i < bufSize; i++) {
+ float s = (buf[i] * 8192.0f);
+ if (fabs(s - last) > 1.0f) {
+ return true;
+ }
+ }
+ return false;
+}
diff --git a/audio/softsynth/mt32/DelayReverb.h b/audio/softsynth/mt32/DelayReverb.h
new file mode 100644
index 0000000000..7c030fb839
--- /dev/null
+++ b/audio/softsynth/mt32/DelayReverb.h
@@ -0,0 +1,53 @@
+/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher
+ * Copyright (C) 2011 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef MT32EMU_DELAYREVERB_H
+#define MT32EMU_DELAYREVERB_H
+
+namespace MT32Emu {
+
+class DelayReverb : public ReverbModel {
+private:
+ Bit8u time;
+ Bit8u level;
+
+ unsigned int sampleRate;
+ Bit32u bufSize;
+ Bit32u bufIx;
+
+ float *buf;
+
+ Bit32u delayLeft;
+ Bit32u delayRight;
+ Bit32u delayFeedback;
+
+ float fade;
+ float feedback;
+
+ void recalcParameters();
+
+public:
+ DelayReverb();
+ ~DelayReverb();
+ void open(unsigned int sampleRate);
+ void close();
+ void setParameters(Bit8u time, Bit8u level);
+ void process(const float *inLeft, const float *inRight, float *outLeft, float *outRight, unsigned long numSamples);
+ bool isActive() const;
+};
+}
+#endif
diff --git a/audio/softsynth/mt32/FreeverbModel.cpp b/audio/softsynth/mt32/FreeverbModel.cpp
new file mode 100644
index 0000000000..c11fa859d8
--- /dev/null
+++ b/audio/softsynth/mt32/FreeverbModel.cpp
@@ -0,0 +1,78 @@
+/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher
+ * Copyright (C) 2011 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "mt32emu.h"
+#include "FreeverbModel.h"
+
+#include "freeverb.h"
+
+using namespace MT32Emu;
+
+FreeverbModel::FreeverbModel(float useScaleTuning, float useFiltVal, float useWet, Bit8u useRoom, float useDamp) {
+ freeverb = NULL;
+ scaleTuning = useScaleTuning;
+ filtVal = useFiltVal;
+ wet = useWet;
+ room = useRoom;
+ damp = useDamp;
+}
+
+FreeverbModel::~FreeverbModel() {
+ delete freeverb;
+}
+
+void FreeverbModel::open(unsigned int /*sampleRate*/) {
+ // FIXME: scaleTuning must be multiplied by sample rate to 32000Hz ratio
+ // IIR filter values depend on sample rate as well
+ if (freeverb == NULL) {
+ freeverb = new revmodel(scaleTuning);
+ }
+ freeverb->mute();
+
+ // entrance Lowpass filter factor
+ freeverb->setfiltval(filtVal);
+
+ // decay speed of high frequencies in the wet signal
+ freeverb->setdamp(damp);
+}
+
+void FreeverbModel::close() {
+ delete freeverb;
+ freeverb = NULL;
+}
+
+void FreeverbModel::process(const float *inLeft, const float *inRight, float *outLeft, float *outRight, unsigned long numSamples) {
+ freeverb->process(inLeft, inRight, outLeft, outRight, numSamples);
+}
+
+void FreeverbModel::setParameters(Bit8u time, Bit8u level) {
+ // wet signal level
+ // FIXME: need to implement some sort of reverb level ramping
+ freeverb->setwet((float)level / 7.0f * wet);
+
+ // wet signal decay speed
+ static float roomTable[] = {
+ 0.25f, 0.37f, 0.54f, 0.71f, 0.78f, 0.86f, 0.93f, 1.00f,
+ -1.00f, -0.50f, 0.00f, 0.30f, 0.51f, 0.64f, 0.77f, 0.90f,
+ 0.50f, 0.57f, 0.70f, 0.77f, 0.85f, 0.93f, 0.96f, 1.01f};
+ freeverb->setroomsize(roomTable[8 * room + time]);
+}
+
+bool FreeverbModel::isActive() const {
+ // FIXME: Not bothering to do this properly since we'll be replacing Freeverb soon...
+ return false;
+}
diff --git a/audio/softsynth/mt32/FreeverbModel.h b/audio/softsynth/mt32/FreeverbModel.h
new file mode 100644
index 0000000000..925b2dbf96
--- /dev/null
+++ b/audio/softsynth/mt32/FreeverbModel.h
@@ -0,0 +1,44 @@
+/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher
+ * Copyright (C) 2011 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef MT32EMU_FREEVERB_MODEL_H
+#define MT32EMU_FREEVERB_MODEL_H
+
+class revmodel;
+
+namespace MT32Emu {
+
+class FreeverbModel : public ReverbModel {
+ revmodel *freeverb;
+ float scaleTuning;
+ float filtVal;
+ float wet;
+ Bit8u room;
+ float damp;
+public:
+ FreeverbModel(float useScaleTuning, float useFiltVal, float useWet, Bit8u useRoom, float useDamp);
+ ~FreeverbModel();
+ void open(unsigned int sampleRate);
+ void close();
+ void setParameters(Bit8u time, Bit8u level);
+ void process(const float *inLeft, const float *inRight, float *outLeft, float *outRight, unsigned long numSamples);
+ bool isActive() const;
+};
+
+}
+
+#endif
diff --git a/audio/softsynth/mt32/LA32Ramp.cpp b/audio/softsynth/mt32/LA32Ramp.cpp
new file mode 100644
index 0000000000..9f1f01c3c2
--- /dev/null
+++ b/audio/softsynth/mt32/LA32Ramp.cpp
@@ -0,0 +1,150 @@
+/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher
+ * Copyright (C) 2011 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+Some notes on this class:
+
+This emulates the LA-32's implementation of "ramps". A ramp in this context is a smooth transition from one value to another, handled entirely within the LA-32.
+The LA-32 provides this feature for amplitude and filter cutoff values.
+
+The 8095 starts ramps on the LA-32 by setting two values in memory-mapped registers:
+
+(1) The target value (between 0 and 255) for the ramp to end on. This is represented by the "target" argument to startRamp().
+(2) The speed at which that value should be approached. This is represented by the "increment" argument to startRamp().
+
+Once the ramp target value has been hit, the LA-32 raises an interrupt.
+
+Note that the starting point of the ramp is whatever internal value the LA-32 had when the registers were set. This is usually the end point of a previously completed ramp.
+
+Our handling of the "target" and "increment" values is based on sample analysis and a little guesswork.
+Here's what we're pretty confident about:
+ - The most significant bit of "increment" indicates the direction that the LA32's current internal value ("current" in our emulation) should change in.
+ Set means downward, clear means upward.
+ - The lower 7 bits of "increment" indicate how quickly "current" should be changed.
+ - If "increment" is 0, no change to "current" is made and no interrupt is raised. [SEMI-CONFIRMED by sample analysis]
+ - Otherwise, if the MSb is set:
+ - If "current" already corresponds to a value <= "target", "current" is set immediately to the equivalent of "target" and an interrupt is raised.
+ - Otherwise, "current" is gradually reduced (at a rate determined by the lower 7 bits of "increment"), and once it reaches the equivalent of "target" an interrupt is raised.
+ - Otherwise (the MSb is unset):
+ - If "current" already corresponds to a value >= "target", "current" is set immediately to the equivalent of "target" and an interrupt is raised.
+ - Otherwise, "current" is gradually increased (at a rate determined by the lower 7 bits of "increment"), and once it reaches the equivalent of "target" an interrupt is raised.
+
+We haven't fully explored:
+ - Values when ramping between levels (though this is probably correct).
+ - Transition timing (may not be 100% accurate, especially for very fast ramps).
+*/
+//#include <cmath>
+
+#include "mt32emu.h"
+#include "LA32Ramp.h"
+#include "mmath.h"
+
+namespace MT32Emu {
+
+// SEMI-CONFIRMED from sample analysis.
+const int TARGET_MULT = 0x40000;
+const unsigned int MAX_CURRENT = 0xFF * TARGET_MULT;
+
+// We simulate the delay in handling "target was reached" interrupts by waiting
+// this many samples before setting interruptRaised.
+// FIXME: This should vary with the sample rate, but doesn't.
+// SEMI-CONFIRMED: Since this involves asynchronous activity between the LA32
+// and the 8095, a good value is hard to pin down.
+// This one matches observed behaviour on a few digital captures I had handy,
+// and should be double-checked. We may also need a more sophisticated delay
+// scheme eventually.
+const int INTERRUPT_TIME = 7;
+
+LA32Ramp::LA32Ramp() :
+ current(0),
+ largeTarget(0),
+ largeIncrement(0),
+ interruptCountdown(0),
+ interruptRaised(false) {
+}
+
+void LA32Ramp::startRamp(Bit8u target, Bit8u increment) {
+ // CONFIRMED: From sample analysis, this appears to be very accurate.
+ // FIXME: We could use a table for this in future
+ if (increment == 0) {
+ largeIncrement = 0;
+ } else {
+ largeIncrement = (unsigned int)(EXP2F(((increment & 0x7F) + 24) / 8.0f) + 0.125f);
+ }
+ descending = (increment & 0x80) != 0;
+ if (descending) {
+ // CONFIRMED: From sample analysis, descending increments are slightly faster
+ largeIncrement++;
+ }
+
+ largeTarget = target * TARGET_MULT;
+ interruptCountdown = 0;
+ interruptRaised = false;
+}
+
+Bit32u LA32Ramp::nextValue() {
+ if (interruptCountdown > 0) {
+ if (--interruptCountdown == 0) {
+ interruptRaised = true;
+ }
+ } else if (largeIncrement != 0) {
+ // CONFIRMED from sample analysis: When increment is 0, the LA32 does *not* change the current value at all (and of course doesn't fire an interrupt).
+ if (descending) {
+ // Lowering current value
+ if (largeIncrement > current) {
+ current = largeTarget;
+ interruptCountdown = INTERRUPT_TIME;
+ } else {
+ current -= largeIncrement;
+ if (current <= largeTarget) {
+ current = largeTarget;
+ interruptCountdown = INTERRUPT_TIME;
+ }
+ }
+ } else {
+ // Raising current value
+ if (MAX_CURRENT - current < largeIncrement) {
+ current = largeTarget;
+ interruptCountdown = INTERRUPT_TIME;
+ } else {
+ current += largeIncrement;
+ if (current >= largeTarget) {
+ current = largeTarget;
+ interruptCountdown = INTERRUPT_TIME;
+ }
+ }
+ }
+ }
+ return current;
+}
+
+bool LA32Ramp::checkInterrupt() {
+ bool wasRaised = interruptRaised;
+ interruptRaised = false;
+ return wasRaised;
+}
+
+void LA32Ramp::reset() {
+ current = 0;
+ largeTarget = 0;
+ largeIncrement = 0;
+ descending = false;
+ interruptCountdown = 0;
+ interruptRaised = false;
+}
+
+}
diff --git a/audio/softsynth/mt32/LA32Ramp.h b/audio/softsynth/mt32/LA32Ramp.h
new file mode 100644
index 0000000000..ae937eb7e1
--- /dev/null
+++ b/audio/softsynth/mt32/LA32Ramp.h
@@ -0,0 +1,43 @@
+/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher
+ * Copyright (C) 2011 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef MT32EMU_LA32RAMP_H
+#define MT32EMU_LA32RAMP_H
+
+namespace MT32Emu {
+
+class LA32Ramp {
+private:
+ Bit32u current;
+ unsigned int largeTarget;
+ unsigned int largeIncrement;
+ bool descending;
+
+ int interruptCountdown;
+ bool interruptRaised;
+
+public:
+ LA32Ramp();
+ void startRamp(Bit8u target, Bit8u increment);
+ Bit32u nextValue();
+ bool checkInterrupt();
+ void reset();
+};
+
+}
+
+#endif /* TVA_H_ */
diff --git a/audio/softsynth/mt32/Part.cpp b/audio/softsynth/mt32/Part.cpp
new file mode 100644
index 0000000000..c9bd86b54a
--- /dev/null
+++ b/audio/softsynth/mt32/Part.cpp
@@ -0,0 +1,622 @@
+/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher
+ * Copyright (C) 2011 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+//#include <cstdio>
+//#include <cstring>
+
+#include "mt32emu.h"
+#include "PartialManager.h"
+
+namespace MT32Emu {
+
+static const Bit8u PartialStruct[13] = {
+ 0, 0, 2, 2, 1, 3,
+ 3, 0, 3, 0, 2, 1, 3
+};
+
+static const Bit8u PartialMixStruct[13] = {
+ 0, 1, 0, 1, 1, 0,
+ 1, 3, 3, 2, 2, 2, 2
+};
+
+static const float floatKeyfollow[17] = {
+ -1.0f, -1.0f / 2.0f, -1.0f / 4.0f, 0.0f,
+ 1.0f / 8.0f, 1.0f / 4.0f, 3.0f / 8.0f, 1.0f / 2.0f, 5.0f / 8.0f, 3.0f / 4.0f, 7.0f / 8.0f, 1.0f,
+ 5.0f / 4.0f, 3.0f / 2.0f, 2.0f,
+ 1.0009765625f, 1.0048828125f
+};
+
+
+RhythmPart::RhythmPart(Synth *useSynth, unsigned int usePartNum): Part(useSynth, usePartNum) {
+ strcpy(name, "Rhythm");
+ rhythmTemp = &synth->mt32ram.rhythmTemp[0];
+ refresh();
+}
+
+Part::Part(Synth *useSynth, unsigned int usePartNum) {
+ synth = useSynth;
+ partNum = usePartNum;
+ patchCache[0].dirty = true;
+ holdpedal = false;
+ patchTemp = &synth->mt32ram.patchTemp[partNum];
+ if (usePartNum == 8) {
+ // Nasty hack for rhythm
+ timbreTemp = NULL;
+ } else {
+ sprintf(name, "Part %d", partNum + 1);
+ timbreTemp = &synth->mt32ram.timbreTemp[partNum];
+ }
+ currentInstr[0] = 0;
+ currentInstr[10] = 0;
+ modulation = 0;
+ expression = 100;
+ pitchBend = 0;
+ activePartialCount = 0;
+ memset(patchCache, 0, sizeof(patchCache));
+ for (int i = 0; i < MT32EMU_MAX_POLY; i++) {
+ freePolys.push_front(new Poly(this));
+ }
+}
+
+Part::~Part() {
+ while (!activePolys.empty()) {
+ delete activePolys.front();
+ activePolys.pop_front();
+ }
+ while (!freePolys.empty()) {
+ delete freePolys.front();
+ freePolys.pop_front();
+ }
+}
+
+void Part::setDataEntryMSB(unsigned char midiDataEntryMSB) {
+ if (nrpn) {
+ // The last RPN-related control change was for an NRPN,
+ // which the real synths don't support.
+ return;
+ }
+ if (rpn != 0) {
+ // The RPN has been set to something other than 0,
+ // which is the only RPN that these synths support
+ return;
+ }
+ patchTemp->patch.benderRange = midiDataEntryMSB > 24 ? 24 : midiDataEntryMSB;
+ updatePitchBenderRange();
+}
+
+void Part::setNRPN() {
+ nrpn = true;
+}
+
+void Part::setRPNLSB(unsigned char midiRPNLSB) {
+ nrpn = false;
+ rpn = (rpn & 0xFF00) | midiRPNLSB;
+}
+
+void Part::setRPNMSB(unsigned char midiRPNMSB) {
+ nrpn = false;
+ rpn = (rpn & 0x00FF) | (midiRPNMSB << 8);
+}
+
+void Part::setHoldPedal(bool pressed) {
+ if (holdpedal && !pressed) {
+ holdpedal = false;
+ stopPedalHold();
+ } else {
+ holdpedal = pressed;
+ }
+}
+
+Bit32s Part::getPitchBend() const {
+ return pitchBend;
+}
+
+void Part::setBend(unsigned int midiBend) {
+ // CONFIRMED:
+ pitchBend = (((signed)midiBend - 8192) * pitchBenderRange) >> 14; // PORTABILITY NOTE: Assumes arithmetic shift
+}
+
+Bit8u Part::getModulation() const {
+ return modulation;
+}
+
+void Part::setModulation(unsigned int midiModulation) {
+ modulation = (Bit8u)midiModulation;
+}
+
+void Part::resetAllControllers() {
+ modulation = 0;
+ expression = 100;
+ pitchBend = 0;
+ setHoldPedal(false);
+}
+
+void Part::reset() {
+ resetAllControllers();
+ allSoundOff();
+ rpn = 0xFFFF;
+}
+
+void RhythmPart::refresh() {
+ // (Re-)cache all the mapped timbres ahead of time
+ for (unsigned int drumNum = 0; drumNum < synth->controlROMMap->rhythmSettingsCount; drumNum++) {
+ int drumTimbreNum = rhythmTemp[drumNum].timbre;
+ if (drumTimbreNum >= 127) { // 94 on MT-32
+ continue;
+ }
+ PatchCache *cache = drumCache[drumNum];
+ backupCacheToPartials(cache);
+ for (int t = 0; t < 4; t++) {
+ // Common parameters, stored redundantly
+ cache[t].dirty = true;
+ cache[t].reverb = rhythmTemp[drumNum].reverbSwitch > 0;
+ }
+ }
+ updatePitchBenderRange();
+}
+
+void Part::refresh() {
+ backupCacheToPartials(patchCache);
+ for (int t = 0; t < 4; t++) {
+ // Common parameters, stored redundantly
+ patchCache[t].dirty = true;
+ patchCache[t].reverb = patchTemp->patch.reverbSwitch > 0;
+ }
+ memcpy(currentInstr, timbreTemp->common.name, 10);
+ updatePitchBenderRange();
+}
+
+const char *Part::getCurrentInstr() const {
+ return &currentInstr[0];
+}
+
+void RhythmPart::refreshTimbre(unsigned int absTimbreNum) {
+ for (int m = 0; m < 85; m++) {
+ if (rhythmTemp[m].timbre == absTimbreNum - 128) {
+ drumCache[m][0].dirty = true;
+ }
+ }
+}
+
+void Part::refreshTimbre(unsigned int absTimbreNum) {
+ if (getAbsTimbreNum() == absTimbreNum) {
+ memcpy(currentInstr, timbreTemp->common.name, 10);
+ patchCache[0].dirty = true;
+ }
+}
+
+void Part::setPatch(const PatchParam *patch) {
+ patchTemp->patch = *patch;
+}
+
+void RhythmPart::setTimbre(TimbreParam * /*timbre*/) {
+ synth->printDebug("%s: Attempted to call setTimbre() - doesn't make sense for rhythm", name);
+}
+
+void Part::setTimbre(TimbreParam *timbre) {
+ *timbreTemp = *timbre;
+}
+
+unsigned int RhythmPart::getAbsTimbreNum() const {
+ synth->printDebug("%s: Attempted to call getAbsTimbreNum() - doesn't make sense for rhythm", name);
+ return 0;
+}
+
+unsigned int Part::getAbsTimbreNum() const {
+ return (patchTemp->patch.timbreGroup * 64) + patchTemp->patch.timbreNum;
+}
+
+#if MT32EMU_MONITOR_MIDI > 0
+void RhythmPart::setProgram(unsigned int patchNum) {
+ synth->printDebug("%s: Attempt to set program (%d) on rhythm is invalid", name, patchNum);
+}
+#else
+void RhythmPart::setProgram(unsigned int) { }
+#endif
+
+void Part::setProgram(unsigned int patchNum) {
+ setPatch(&synth->mt32ram.patches[patchNum]);
+ holdpedal = false;
+ allSoundOff();
+ setTimbre(&synth->mt32ram.timbres[getAbsTimbreNum()].timbre);
+ refresh();
+}
+
+void Part::updatePitchBenderRange() {
+ pitchBenderRange = patchTemp->patch.benderRange * 683;
+}
+
+void Part::backupCacheToPartials(PatchCache cache[4]) {
+ // check if any partials are still playing with the old patch cache
+ // if so then duplicate the cached data from the part to the partial so that
+ // we can change the part's cache without affecting the partial.
+ // We delay this until now to avoid a copy operation with every note played
+ for (Common::List<Poly *>::iterator polyIt = activePolys.begin(); polyIt != activePolys.end(); polyIt++) {
+ (*polyIt)->backupCacheToPartials(cache);
+ }
+}
+
+void Part::cacheTimbre(PatchCache cache[4], const TimbreParam *timbre) {
+ backupCacheToPartials(cache);
+ int partialCount = 0;
+ for (int t = 0; t < 4; t++) {
+ if (((timbre->common.partialMute >> t) & 0x1) == 1) {
+ cache[t].playPartial = true;
+ partialCount++;
+ } else {
+ cache[t].playPartial = false;
+ continue;
+ }
+
+ // Calculate and cache common parameters
+ cache[t].srcPartial = timbre->partial[t];
+
+ cache[t].pcm = timbre->partial[t].wg.pcmWave;
+
+ switch (t) {
+ case 0:
+ cache[t].PCMPartial = (PartialStruct[(int)timbre->common.partialStructure12] & 0x2) ? true : false;
+ cache[t].structureMix = PartialMixStruct[(int)timbre->common.partialStructure12];
+ cache[t].structurePosition = 0;
+ cache[t].structurePair = 1;
+ break;
+ case 1:
+ cache[t].PCMPartial = (PartialStruct[(int)timbre->common.partialStructure12] & 0x1) ? true : false;
+ cache[t].structureMix = PartialMixStruct[(int)timbre->common.partialStructure12];
+ cache[t].structurePosition = 1;
+ cache[t].structurePair = 0;
+ break;
+ case 2:
+ cache[t].PCMPartial = (PartialStruct[(int)timbre->common.partialStructure34] & 0x2) ? true : false;
+ cache[t].structureMix = PartialMixStruct[(int)timbre->common.partialStructure34];
+ cache[t].structurePosition = 0;
+ cache[t].structurePair = 3;
+ break;
+ case 3:
+ cache[t].PCMPartial = (PartialStruct[(int)timbre->common.partialStructure34] & 0x1) ? true : false;
+ cache[t].structureMix = PartialMixStruct[(int)timbre->common.partialStructure34];
+ cache[t].structurePosition = 1;
+ cache[t].structurePair = 2;
+ break;
+ default:
+ break;
+ }
+
+ cache[t].partialParam = &timbre->partial[t];
+
+ cache[t].waveform = timbre->partial[t].wg.waveform;
+ }
+ for (int t = 0; t < 4; t++) {
+ // Common parameters, stored redundantly
+ cache[t].dirty = false;
+ cache[t].partialCount = partialCount;
+ cache[t].sustain = (timbre->common.noSustain == 0);
+ }
+ //synth->printDebug("Res 1: %d 2: %d 3: %d 4: %d", cache[0].waveform, cache[1].waveform, cache[2].waveform, cache[3].waveform);
+
+#if MT32EMU_MONITOR_INSTRUMENTS > 0
+ synth->printDebug("%s (%s): Recached timbre", name, currentInstr);
+ for (int i = 0; i < 4; i++) {
+ synth->printDebug(" %d: play=%s, pcm=%s (%d), wave=%d", i, cache[i].playPartial ? "YES" : "NO", cache[i].PCMPartial ? "YES" : "NO", timbre->partial[i].wg.pcmWave, timbre->partial[i].wg.waveform);
+ }
+#endif
+}
+
+const char *Part::getName() const {
+ return name;
+}
+
+void Part::setVolume(unsigned int midiVolume) {
+ // CONFIRMED: This calculation matches the table used in the control ROM
+ patchTemp->outputLevel = (Bit8u)(midiVolume * 100 / 127);
+ //synth->printDebug("%s (%s): Set volume to %d", name, currentInstr, midiVolume);
+}
+
+Bit8u Part::getVolume() const {
+ return patchTemp->outputLevel;
+}
+
+Bit8u Part::getExpression() const {
+ return expression;
+}
+
+void Part::setExpression(unsigned int midiExpression) {
+ // CONFIRMED: This calculation matches the table used in the control ROM
+ expression = (Bit8u)(midiExpression * 100 / 127);
+}
+
+void RhythmPart::setPan(unsigned int midiPan) {
+ // CONFIRMED: This does change patchTemp, but has no actual effect on playback.
+#if MT32EMU_MONITOR_MIDI > 0
+ synth->printDebug("%s: Pointlessly setting pan (%d) on rhythm part", name, midiPan);
+#endif
+ Part::setPan(midiPan);
+}
+
+void Part::setPan(unsigned int midiPan) {
+ // NOTE: Panning is inverted compared to GM.
+
+ // CM-32L: Divide by 8.5
+ patchTemp->panpot = (Bit8u)((midiPan << 3) / 68);
+ // FIXME: MT-32: Divide by 9
+ //patchTemp->panpot = (Bit8u)(midiPan / 9);
+
+ //synth->printDebug("%s (%s): Set pan to %d", name, currentInstr, panpot);
+}
+
+/**
+ * Applies key shift to a MIDI key and converts it into an internal key value in the range 12-108.
+ */
+unsigned int Part::midiKeyToKey(unsigned int midiKey) {
+ int key = midiKey + patchTemp->patch.keyShift;
+ if (key < 36) {
+ // After keyShift is applied, key < 36, so move up by octaves
+ while (key < 36) {
+ key += 12;
+ }
+ } else if (key > 132) {
+ // After keyShift is applied, key > 132, so move down by octaves
+ while (key > 132) {
+ key -= 12;
+ }
+ }
+ key -= 24;
+ return key;
+}
+
+void RhythmPart::noteOn(unsigned int midiKey, unsigned int velocity) {
+ if (midiKey < 24 || midiKey > 108) { /*> 87 on MT-32)*/
+ synth->printDebug("%s: Attempted to play invalid key %d (velocity %d)", name, midiKey, velocity);
+ return;
+ }
+ unsigned int key = midiKey;
+ unsigned int drumNum = key - 24;
+ int drumTimbreNum = rhythmTemp[drumNum].timbre;
+ if (drumTimbreNum >= 127) { // 94 on MT-32
+ synth->printDebug("%s: Attempted to play unmapped key %d (velocity %d)", name, midiKey, velocity);
+ return;
+ }
+ // CONFIRMED: Two special cases described by Mok
+ if (drumTimbreNum == 64 + 6) {
+ noteOff(0);
+ key = 1;
+ } else if (drumTimbreNum == 64 + 7) {
+ // This noteOff(0) is not performed on MT-32, only LAPC-I
+ noteOff(0);
+ key = 0;
+ }
+ int absTimbreNum = drumTimbreNum + 128;
+ TimbreParam *timbre = &synth->mt32ram.timbres[absTimbreNum].timbre;
+ memcpy(currentInstr, timbre->common.name, 10);
+ if (drumCache[drumNum][0].dirty) {
+ cacheTimbre(drumCache[drumNum], timbre);
+ }
+#if MT32EMU_MONITOR_INSTRUMENTS > 0
+ synth->printDebug("%s (%s): Start poly (drum %d, timbre %d): midiKey %u, key %u, velo %u, mod %u, exp %u, bend %u", name, currentInstr, drumNum, absTimbreNum, midiKey, key, velocity, modulation, expression, pitchBend);
+#if MT32EMU_MONITOR_INSTRUMENTS > 1
+ // According to info from Mok, keyShift does not appear to affect anything on rhythm part on LAPC-I, but may do on MT-32 - needs investigation
+ synth->printDebug(" Patch: (timbreGroup %u), (timbreNum %u), (keyShift %u), fineTune %u, benderRange %u, assignMode %u, (reverbSwitch %u)", patchTemp->patch.timbreGroup, patchTemp->patch.timbreNum, patchTemp->patch.keyShift, patchTemp->patch.fineTune, patchTemp->patch.benderRange, patchTemp->patch.assignMode, patchTemp->patch.reverbSwitch);
+ synth->printDebug(" PatchTemp: outputLevel %u, (panpot %u)", patchTemp->outputLevel, patchTemp->panpot);
+ synth->printDebug(" RhythmTemp: timbre %u, outputLevel %u, panpot %u, reverbSwitch %u", rhythmTemp[drumNum].timbre, rhythmTemp[drumNum].outputLevel, rhythmTemp[drumNum].panpot, rhythmTemp[drumNum].reverbSwitch);
+#endif
+#endif
+ playPoly(drumCache[drumNum], &rhythmTemp[drumNum], midiKey, key, velocity);
+}
+
+void Part::noteOn(unsigned int midiKey, unsigned int velocity) {
+ unsigned int key = midiKeyToKey(midiKey);
+ if (patchCache[0].dirty) {
+ cacheTimbre(patchCache, timbreTemp);
+ }
+#if MT32EMU_MONITOR_INSTRUMENTS > 0
+ synth->printDebug("%s (%s): Start poly: midiKey %u, key %u, velo %u, mod %u, exp %u, bend %u", name, currentInstr, midiKey, key, velocity, modulation, expression, pitchBend);
+#if MT32EMU_MONITOR_INSTRUMENTS > 1
+ synth->printDebug(" Patch: timbreGroup %u, timbreNum %u, keyShift %u, fineTune %u, benderRange %u, assignMode %u, reverbSwitch %u", patchTemp->patch.timbreGroup, patchTemp->patch.timbreNum, patchTemp->patch.keyShift, patchTemp->patch.fineTune, patchTemp->patch.benderRange, patchTemp->patch.assignMode, patchTemp->patch.reverbSwitch);
+ synth->printDebug(" PatchTemp: outputLevel %u, panpot %u", patchTemp->outputLevel, patchTemp->panpot);
+#endif
+#endif
+ playPoly(patchCache, NULL, midiKey, key, velocity);
+}
+
+void Part::abortPoly(Poly *poly) {
+ if (poly->startAbort()) {
+ while (poly->isActive()) {
+ if (!synth->prerender()) {
+ synth->printDebug("%s (%s): Ran out of prerender space to abort poly gracefully", name, currentInstr);
+ poly->terminate();
+ break;
+ }
+ }
+ }
+}
+
+bool Part::abortFirstPoly(unsigned int key) {
+ for (Common::List<Poly *>::iterator polyIt = activePolys.begin(); polyIt != activePolys.end(); polyIt++) {
+ Poly *poly = *polyIt;
+ if (poly->getKey() == key) {
+ abortPoly(poly);
+ return true;
+ }
+ }
+ return false;
+}
+
+bool Part::abortFirstPoly(PolyState polyState) {
+ for (Common::List<Poly *>::iterator polyIt = activePolys.begin(); polyIt != activePolys.end(); polyIt++) {
+ Poly *poly = *polyIt;
+ if (poly->getState() == polyState) {
+ abortPoly(poly);
+ return true;
+ }
+ }
+ return false;
+}
+
+bool Part::abortFirstPolyPreferHeld() {
+ if (abortFirstPoly(POLY_Held)) {
+ return true;
+ }
+ return abortFirstPoly();
+}
+
+bool Part::abortFirstPoly() {
+ if (activePolys.empty()) {
+ return false;
+ }
+ abortPoly(activePolys.front());
+ return true;
+}
+
+void Part::playPoly(const PatchCache cache[4], const MemParams::RhythmTemp *rhythmTemp, unsigned int midiKey, unsigned int key, unsigned int velocity) {
+ // CONFIRMED: Even in single-assign mode, we don't abort playing polys if the timbre to play is completely muted.
+ unsigned int needPartials = cache[0].partialCount;
+ if (needPartials == 0) {
+ synth->printDebug("%s (%s): Completely muted instrument", name, currentInstr);
+ return;
+ }
+
+ if ((patchTemp->patch.assignMode & 2) == 0) {
+ // Single-assign mode
+ abortFirstPoly(key);
+ }
+
+ if (!synth->partialManager->freePartials(needPartials, partNum)) {
+#if MT32EMU_MONITOR_PARTIALS > 0
+ synth->printDebug("%s (%s): Insufficient free partials to play key %d (velocity %d); needed=%d, free=%d, assignMode=%d", name, currentInstr, midiKey, velocity, needPartials, synth->partialManager->getFreePartialCount(), patchTemp->patch.assignMode);
+ synth->printPartialUsage();
+#endif
+ return;
+ }
+
+ if (freePolys.empty()) {
+ synth->printDebug("%s (%s): No free poly to play key %d (velocity %d)", name, currentInstr, midiKey, velocity);
+ return;
+ }
+ Poly *poly = freePolys.front();
+ freePolys.pop_front();
+ if (patchTemp->patch.assignMode & 1) {
+ // Priority to data first received
+ activePolys.push_front(poly);
+ } else {
+ activePolys.push_back(poly);
+ }
+
+ Partial *partials[4];
+ for (int x = 0; x < 4; x++) {
+ if (cache[x].playPartial) {
+ partials[x] = synth->partialManager->allocPartial(partNum);
+ activePartialCount++;
+ } else {
+ partials[x] = NULL;
+ }
+ }
+ poly->reset(key, velocity, cache[0].sustain, partials);
+
+ for (int x = 0; x < 4; x++) {
+ if (partials[x] != NULL) {
+#if MT32EMU_MONITOR_PARTIALS > 2
+ synth->printDebug("%s (%s): Allocated partial %d", name, currentInstr, partials[x]->debugGetPartialNum());
+#endif
+ partials[x]->startPartial(this, poly, &cache[x], rhythmTemp, partials[cache[x].structurePair]);
+ }
+ }
+#if MT32EMU_MONITOR_PARTIALS > 1
+ synth->printPartialUsage();
+#endif
+}
+
+void Part::allNotesOff() {
+ // The MIDI specification states - and Mok confirms - that all notes off (0x7B)
+ // should treat the hold pedal as usual.
+ for (Common::List<Poly *>::iterator polyIt = activePolys.begin(); polyIt != activePolys.end(); polyIt++) {
+ Poly *poly = *polyIt;
+ // FIXME: This has special handling of key 0 in NoteOff that Mok has not yet confirmed
+ // applies to AllNotesOff.
+ poly->noteOff(holdpedal);
+ }
+}
+
+void Part::allSoundOff() {
+ // MIDI "All sound off" (0x78) should release notes immediately regardless of the hold pedal.
+ // This controller is not actually implemented by the synths, though (according to the docs and Mok) -
+ // we're only using this method internally.
+ for (Common::List<Poly *>::iterator polyIt = activePolys.begin(); polyIt != activePolys.end(); polyIt++) {
+ Poly *poly = *polyIt;
+ poly->startDecay();
+ }
+}
+
+void Part::stopPedalHold() {
+ for (Common::List<Poly *>::iterator polyIt = activePolys.begin(); polyIt != activePolys.end(); polyIt++) {
+ Poly *poly = *polyIt;
+ poly->stopPedalHold();
+ }
+}
+
+void RhythmPart::noteOff(unsigned int midiKey) {
+ stopNote(midiKey);
+}
+
+void Part::noteOff(unsigned int midiKey) {
+ stopNote(midiKeyToKey(midiKey));
+}
+
+void Part::stopNote(unsigned int key) {
+#if MT32EMU_MONITOR_INSTRUMENTS > 0
+ synth->printDebug("%s (%s): stopping key %d", name, currentInstr, key);
+#endif
+
+ for (Common::List<Poly *>::iterator polyIt = activePolys.begin(); polyIt != activePolys.end(); polyIt++) {
+ Poly *poly = *polyIt;
+ // Generally, non-sustaining instruments ignore note off. They die away eventually anyway.
+ // Key 0 (only used by special cases on rhythm part) reacts to note off even if non-sustaining or pedal held.
+ if (poly->getKey() == key && (poly->canSustain() || key == 0)) {
+ if (poly->noteOff(holdpedal && key != 0)) {
+ break;
+ }
+ }
+ }
+}
+
+const MemParams::PatchTemp *Part::getPatchTemp() const {
+ return patchTemp;
+}
+
+unsigned int Part::getActivePartialCount() const {
+ return activePartialCount;
+}
+
+unsigned int Part::getActiveNonReleasingPartialCount() const {
+ unsigned int activeNonReleasingPartialCount = 0;
+ for (Common::List<Poly *>::const_iterator polyIt = activePolys.begin(); polyIt != activePolys.end(); polyIt++) {
+ Poly *poly = *polyIt;
+ if (poly->getState() != POLY_Releasing) {
+ activeNonReleasingPartialCount += poly->getActivePartialCount();
+ }
+ }
+ return activeNonReleasingPartialCount;
+}
+
+void Part::partialDeactivated(Poly *poly) {
+ activePartialCount--;
+ if (!poly->isActive()) {
+ activePolys.remove(poly);
+ freePolys.push_front(poly);
+ }
+}
+
+}
diff --git a/audio/softsynth/mt32/Part.h b/audio/softsynth/mt32/Part.h
new file mode 100644
index 0000000000..5c59c6d61f
--- /dev/null
+++ b/audio/softsynth/mt32/Part.h
@@ -0,0 +1,133 @@
+/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher
+ * Copyright (C) 2011 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef MT32EMU_PART_H
+#define MT32EMU_PART_H
+
+#include <common/list.h>
+
+namespace MT32Emu {
+
+class PartialManager;
+class Synth;
+
+class Part {
+private:
+ // Direct pointer to sysex-addressable memory dedicated to this part (valid for parts 1-8, NULL for rhythm)
+ TimbreParam *timbreTemp;
+
+ // 0=Part 1, .. 7=Part 8, 8=Rhythm
+ unsigned int partNum;
+
+ bool holdpedal;
+
+ unsigned int activePartialCount;
+ PatchCache patchCache[4];
+ Common::List<Poly *> freePolys;
+ Common::List<Poly *> activePolys;
+
+ void setPatch(const PatchParam *patch);
+ unsigned int midiKeyToKey(unsigned int midiKey);
+
+ void abortPoly(Poly *poly);
+ bool abortFirstPoly(unsigned int key);
+
+protected:
+ Synth *synth;
+ // Direct pointer into sysex-addressable memory
+ MemParams::PatchTemp *patchTemp;
+ char name[8]; // "Part 1".."Part 8", "Rhythm"
+ char currentInstr[11];
+ Bit8u modulation;
+ Bit8u expression;
+ Bit32s pitchBend;
+ bool nrpn;
+ Bit16u rpn;
+ Bit16u pitchBenderRange; // (patchTemp->patch.benderRange * 683) at the time of the last MIDI program change or MIDI data entry.
+
+ void backupCacheToPartials(PatchCache cache[4]);
+ void cacheTimbre(PatchCache cache[4], const TimbreParam *timbre);
+ void playPoly(const PatchCache cache[4], const MemParams::RhythmTemp *rhythmTemp, unsigned int midiKey, unsigned int key, unsigned int velocity);
+ void stopNote(unsigned int key);
+ const char *getName() const;
+
+public:
+ Part(Synth *synth, unsigned int usePartNum);
+ virtual ~Part();
+ void reset();
+ void setDataEntryMSB(unsigned char midiDataEntryMSB);
+ void setNRPN();
+ void setRPNLSB(unsigned char midiRPNLSB);
+ void setRPNMSB(unsigned char midiRPNMSB);
+ void resetAllControllers();
+ virtual void noteOn(unsigned int midiKey, unsigned int velocity);
+ virtual void noteOff(unsigned int midiKey);
+ void allNotesOff();
+ void allSoundOff();
+ Bit8u getVolume() const; // Internal volume, 0-100, exposed for use by ExternalInterface
+ void setVolume(unsigned int midiVolume);
+ Bit8u getModulation() const;
+ void setModulation(unsigned int midiModulation);
+ Bit8u getExpression() const;
+ void setExpression(unsigned int midiExpression);
+ virtual void setPan(unsigned int midiPan);
+ Bit32s getPitchBend() const;
+ void setBend(unsigned int midiBend);
+ virtual void setProgram(unsigned int midiProgram);
+ void setHoldPedal(bool pedalval);
+ void stopPedalHold();
+ void updatePitchBenderRange();
+ virtual void refresh();
+ virtual void refreshTimbre(unsigned int absTimbreNum);
+ virtual void setTimbre(TimbreParam *timbre);
+ virtual unsigned int getAbsTimbreNum() const;
+ const char *getCurrentInstr() const;
+ unsigned int getActivePartialCount() const;
+ unsigned int getActiveNonReleasingPartialCount() const;
+
+ const MemParams::PatchTemp *getPatchTemp() const;
+
+ // This should only be called by Poly
+ void partialDeactivated(Poly *poly);
+
+ // These are rather specialised, and should probably only be used by PartialManager
+ bool abortFirstPoly(PolyState polyState);
+ // Abort the first poly in PolyState_HELD, or if none exists, the first active poly in any state.
+ bool abortFirstPolyPreferHeld();
+ bool abortFirstPoly();
+};
+
+class RhythmPart: public Part {
+ // Pointer to the area of the MT-32's memory dedicated to rhythm
+ const MemParams::RhythmTemp *rhythmTemp;
+
+ // This caches the timbres/settings in use by the rhythm part
+ PatchCache drumCache[85][4];
+public:
+ RhythmPart(Synth *synth, unsigned int usePartNum);
+ void refresh();
+ void refreshTimbre(unsigned int timbreNum);
+ void setTimbre(TimbreParam *timbre);
+ void noteOn(unsigned int key, unsigned int velocity);
+ void noteOff(unsigned int midiKey);
+ unsigned int getAbsTimbreNum() const;
+ void setPan(unsigned int midiPan);
+ void setProgram(unsigned int patchNum);
+};
+
+}
+#endif
diff --git a/audio/softsynth/mt32/Partial.cpp b/audio/softsynth/mt32/Partial.cpp
new file mode 100644
index 0000000000..03bec560b8
--- /dev/null
+++ b/audio/softsynth/mt32/Partial.cpp
@@ -0,0 +1,557 @@
+/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher
+ * Copyright (C) 2011 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+//#include <cmath>
+//#include <cstdlib>
+//#include <cstring>
+
+#include "mt32emu.h"
+#include "mmath.h"
+
+using namespace MT32Emu;
+
+#ifdef INACCURATE_SMOOTH_PAN
+// Mok wanted an option for smoother panning, and we love Mok.
+static const float PAN_NUMERATOR_NORMAL[] = {0.0f, 0.5f, 1.0f, 1.5f, 2.0f, 2.5f, 3.0f, 3.5f, 4.0f, 4.5f, 5.0f, 5.5f, 6.0f, 6.5f, 7.0f};
+#else
+// CONFIRMED by Mok: These NUMERATOR values (as bytes, not floats, obviously) are sent exactly like this to the LA32.
+static const float PAN_NUMERATOR_NORMAL[] = {0.0f, 0.0f, 1.0f, 1.0f, 2.0f, 2.0f, 3.0f, 3.0f, 4.0f, 4.0f, 5.0f, 5.0f, 6.0f, 6.0f, 7.0f};
+#endif
+static const float PAN_NUMERATOR_MASTER[] = {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f};
+static const float PAN_NUMERATOR_SLAVE[] = {0.0f, 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 7.0f, 7.0f, 7.0f, 7.0f, 7.0f, 7.0f, 7.0f};
+
+Partial::Partial(Synth *useSynth, int useDebugPartialNum) :
+ synth(useSynth), debugPartialNum(useDebugPartialNum), sampleNum(0), tva(new TVA(this, &ampRamp)), tvp(new TVP(this)), tvf(new TVF(this, &cutoffModifierRamp)) {
+ ownerPart = -1;
+ poly = NULL;
+ pair = NULL;
+}
+
+Partial::~Partial() {
+ delete tva;
+ delete tvp;
+ delete tvf;
+}
+
+// Only used for debugging purposes
+int Partial::debugGetPartialNum() const {
+ return debugPartialNum;
+}
+
+// Only used for debugging purposes
+unsigned long Partial::debugGetSampleNum() const {
+ return sampleNum;
+}
+
+int Partial::getOwnerPart() const {
+ return ownerPart;
+}
+
+bool Partial::isActive() const {
+ return ownerPart > -1;
+}
+
+const Poly *Partial::getPoly() const {
+ return poly;
+}
+
+void Partial::activate(int part) {
+ // This just marks the partial as being assigned to a part
+ ownerPart = part;
+}
+
+void Partial::deactivate() {
+ if (!isActive()) {
+ return;
+ }
+ ownerPart = -1;
+ if (poly != NULL) {
+ poly->partialDeactivated(this);
+ if (pair != NULL) {
+ pair->pair = NULL;
+ }
+ }
+#if MT32EMU_MONITOR_PARTIALS > 2
+ synth->printDebug("[+%lu] [Partial %d] Deactivated", sampleNum, debugPartialNum);
+ synth->printPartialUsage(sampleNum);
+#endif
+}
+
+// DEPRECATED: This should probably go away eventually, it's currently only used as a kludge to protect our old assumptions that
+// rhythm part notes were always played as key MIDDLEC.
+int Partial::getKey() const {
+ if (poly == NULL) {
+ return -1;
+ } else if (ownerPart == 8) {
+ // FIXME: Hack, should go away after new pitch stuff is committed (and possibly some TVF changes)
+ return MIDDLEC;
+ } else {
+ return poly->getKey();
+ }
+}
+
+void Partial::startPartial(const Part *part, Poly *usePoly, const PatchCache *usePatchCache, const MemParams::RhythmTemp *rhythmTemp, Partial *pairPartial) {
+ if (usePoly == NULL || usePatchCache == NULL) {
+ synth->printDebug("[Partial %d] *** Error: Starting partial for owner %d, usePoly=%s, usePatchCache=%s", debugPartialNum, ownerPart, usePoly == NULL ? "*** NULL ***" : "OK", usePatchCache == NULL ? "*** NULL ***" : "OK");
+ return;
+ }
+ patchCache = usePatchCache;
+ poly = usePoly;
+ mixType = patchCache->structureMix;
+ structurePosition = patchCache->structurePosition;
+
+ Bit8u panSetting = rhythmTemp != NULL ? rhythmTemp->panpot : part->getPatchTemp()->panpot;
+ float panVal;
+ if (mixType == 3) {
+ if (structurePosition == 0) {
+ panVal = PAN_NUMERATOR_MASTER[panSetting];
+ } else {
+ panVal = PAN_NUMERATOR_SLAVE[panSetting];
+ }
+ // Do a normal mix independent of any pair partial.
+ mixType = 0;
+ pairPartial = NULL;
+ } else {
+ panVal = PAN_NUMERATOR_NORMAL[panSetting];
+ }
+
+ // FIXME: Sample analysis suggests that the use of panVal is linear, but there are some some quirks that still need to be resolved.
+ stereoVolume.leftVol = panVal / 7.0f;
+ stereoVolume.rightVol = 1.0f - stereoVolume.leftVol;
+
+ if (patchCache->PCMPartial) {
+ pcmNum = patchCache->pcm;
+ if (synth->controlROMMap->pcmCount > 128) {
+ // CM-32L, etc. support two "banks" of PCMs, selectable by waveform type parameter.
+ if (patchCache->waveform > 1) {
+ pcmNum += 128;
+ }
+ }
+ pcmWave = &synth->pcmWaves[pcmNum];
+ } else {
+ pcmWave = NULL;
+ wavePos = 0.0f;
+ lastFreq = 0.0;
+ }
+
+ // CONFIRMED: pulseWidthVal calculation is based on information from Mok
+ pulseWidthVal = (poly->getVelocity() - 64) * (patchCache->srcPartial.wg.pulseWidthVeloSensitivity - 7) + synth->tables.pulseWidth100To255[patchCache->srcPartial.wg.pulseWidth];
+ if (pulseWidthVal < 0) {
+ pulseWidthVal = 0;
+ } else if (pulseWidthVal > 255) {
+ pulseWidthVal = 255;
+ }
+
+ pcmPosition = 0.0f;
+ pair = pairPartial;
+ alreadyOutputed = false;
+ tva->reset(part, patchCache->partialParam, rhythmTemp);
+ tvp->reset(part, patchCache->partialParam);
+ tvf->reset(patchCache->partialParam, tvp->getBasePitch());
+}
+
+float Partial::getPCMSample(unsigned int position) {
+ if (position >= pcmWave->len) {
+ if (!pcmWave->loop) {
+ return 0;
+ }
+ position = position % pcmWave->len;
+ }
+ return synth->pcmROMData[pcmWave->addr + position];
+}
+
+unsigned long Partial::generateSamples(float *partialBuf, unsigned long length) {
+ if (!isActive() || alreadyOutputed) {
+ return 0;
+ }
+ if (poly == NULL) {
+ synth->printDebug("[Partial %d] *** ERROR: poly is NULL at Partial::generateSamples()!", debugPartialNum);
+ return 0;
+ }
+
+ alreadyOutputed = true;
+
+ // Generate samples
+
+ for (sampleNum = 0; sampleNum < length; sampleNum++) {
+ float sample = 0;
+ Bit32u ampRampVal = ampRamp.nextValue();
+ if (ampRamp.checkInterrupt()) {
+ tva->handleInterrupt();
+ }
+ if (!tva->isPlaying()) {
+ deactivate();
+ break;
+ }
+ // SEMI-CONFIRMED: From sample analysis:
+ // (1) Tested with a single partial playing PCM wave 77 with pitchCoarse 36 and no keyfollow, velocity follow, etc.
+ // This gives results within +/- 2 at the output (before any DAC bitshifting)
+ // when sustaining at levels 156 - 255 with no modifiers.
+ // (2) Tested with a special square wave partial (internal capture ID tva5) at TVA envelope levels 155-255.
+ // This gives deltas between -1 and 0 compared to the real output. Note that this special partial only produces
+ // positive amps, so negative still needs to be explored, as well as lower levels.
+ //
+ // Also still partially unconfirmed is the behaviour when ramping between levels, as well as the timing.
+ float amp = EXP2F((32772 - ampRampVal / 2048) / -2048.0f);
+
+ Bit16u pitch = tvp->nextPitch();
+ float freq = synth->tables.pitchToFreq[pitch];
+
+ if (patchCache->PCMPartial) {
+ // Render PCM waveform
+ int len = pcmWave->len;
+ int intPCMPosition = (int)pcmPosition;
+ if (intPCMPosition >= len && !pcmWave->loop) {
+ // We're now past the end of a non-looping PCM waveform so it's time to die.
+ deactivate();
+ break;
+ }
+ Bit32u pcmAddr = pcmWave->addr;
+ float positionDelta = freq * 2048.0f / synth->myProp.sampleRate;
+
+ // Linear interpolation
+ float firstSample = synth->pcmROMData[pcmAddr + intPCMPosition];
+ float nextSample = getPCMSample(intPCMPosition + 1);
+ sample = firstSample + (nextSample - firstSample) * (pcmPosition - intPCMPosition);
+
+ float newPCMPosition = pcmPosition + positionDelta;
+ if (pcmWave->loop) {
+ newPCMPosition = fmod(newPCMPosition, (float)pcmWave->len);
+ }
+ pcmPosition = newPCMPosition;
+ } else {
+ // Render synthesised waveform
+ wavePos *= lastFreq / freq;
+ lastFreq = freq;
+
+ Bit32u cutoffModifierRampVal = cutoffModifierRamp.nextValue();
+ if (cutoffModifierRamp.checkInterrupt()) {
+ tvf->handleInterrupt();
+ }
+ float cutoffModifier = cutoffModifierRampVal / 262144.0f;
+
+ // res corresponds to a value set in an LA32 register
+ Bit8u res = patchCache->srcPartial.tvf.resonance + 1;
+
+ // EXP2F(1.0f - (32 - res) / 4.0f);
+ float resAmp = synth->tables.resAmpMax[res];
+
+ // The cutoffModifier may not be supposed to be directly added to the cutoff -
+ // it may for example need to be multiplied in some way.
+ // The 240 cutoffVal limit was determined via sample analysis (internal Munt capture IDs: glop3, glop4).
+ // More research is needed to be sure that this is correct, however.
+ float cutoffVal = tvf->getBaseCutoff() + cutoffModifier;
+ if (cutoffVal > 240.0f) {
+ cutoffVal = 240.0f;
+ }
+
+ // Wave length in samples
+ float waveLen = synth->myProp.sampleRate / freq;
+
+ // Init cosineLen
+ float cosineLen = 0.5f * waveLen;
+ if (cutoffVal > 128.0f) {
+#if MT32EMU_ACCURATE_WG == 1
+ cosineLen *= EXP2F((cutoffVal - 128.0f) / -16.0f); // found from sample analysis
+#else
+ cosineLen *= synth->tables.cutoffToCosineLen[Bit32u((cutoffVal - 128.0f) * 8.0f)];
+#endif
+ }
+
+ // Start playing in center of first cosine segment
+ // relWavePos is shifted by a half of cosineLen
+ float relWavePos = wavePos + 0.5f * cosineLen;
+ if (relWavePos > waveLen) {
+ relWavePos -= waveLen;
+ }
+
+ float pulseLen = 0.5f;
+ if (pulseWidthVal > 128) {
+ pulseLen += synth->tables.pulseLenFactor[pulseWidthVal - 128];
+ }
+ pulseLen *= waveLen;
+
+ float lLen = pulseLen - cosineLen;
+
+ // Ignore pulsewidths too high for given freq
+ if (lLen < 0.0f) {
+ lLen = 0.0f;
+ }
+
+ // Ignore pulsewidths too high for given freq and cutoff
+ float hLen = waveLen - lLen - 2 * cosineLen;
+ if (hLen < 0.0f) {
+ hLen = 0.0f;
+ }
+
+ // Correct resAmp for cutoff in range 50..66
+ if ((cutoffVal >= 128.0f) && (cutoffVal < 144.0f)) {
+#if MT32EMU_ACCURATE_WG == 1
+ resAmp *= sinf(FLOAT_PI * (cutoffVal - 128.0f) / 32.0f);
+#else
+ resAmp *= synth->tables.sinf10[Bit32u(64 * (cutoffVal - 128.0f))];
+#endif
+ }
+
+ // Produce filtered square wave with 2 cosine waves on slopes
+
+ // 1st cosine segment
+ if (relWavePos < cosineLen) {
+#if MT32EMU_ACCURATE_WG == 1
+ sample = -cosf(FLOAT_PI * relWavePos / cosineLen);
+#else
+ sample = -synth->tables.sinf10[Bit32u(2048.0f * relWavePos / cosineLen) + 1024];
+#endif
+ } else
+
+ // high linear segment
+ if (relWavePos < (cosineLen + hLen)) {
+ sample = 1.f;
+ } else
+
+ // 2nd cosine segment
+ if (relWavePos < (2 * cosineLen + hLen)) {
+#if MT32EMU_ACCURATE_WG == 1
+ sample = cosf(FLOAT_PI * (relWavePos - (cosineLen + hLen)) / cosineLen);
+#else
+ sample = synth->tables.sinf10[Bit32u(2048.0f * (relWavePos - (cosineLen + hLen)) / cosineLen) + 1024];
+#endif
+ } else {
+
+ // low linear segment
+ sample = -1.f;
+ }
+
+ if (cutoffVal < 128.0f) {
+
+ // Attenuate samples below cutoff 50
+ // Found by sample analysis
+#if MT32EMU_ACCURATE_WG == 1
+ sample *= EXP2F(-0.125f * (128.0f - cutoffVal));
+#else
+ sample *= synth->tables.cutoffToFilterAmp[Bit32u(cutoffVal * 8.0f)];
+#endif
+ } else {
+
+ // Add resonance sine. Effective for cutoff > 50 only
+ float resSample = 1.0f;
+
+ // Now relWavePos counts from the middle of first cosine
+ relWavePos = wavePos;
+
+ // negative segments
+ if (!(relWavePos < (cosineLen + hLen))) {
+ resSample = -resSample;
+ relWavePos -= cosineLen + hLen;
+ }
+
+ // Resonance sine WG
+#if MT32EMU_ACCURATE_WG == 1
+ resSample *= sinf(FLOAT_PI * relWavePos / cosineLen);
+#else
+ resSample *= synth->tables.sinf10[Bit32u(2048.0f * relWavePos / cosineLen) & 4095];
+#endif
+
+ // Resonance sine amp
+ float resAmpFade = EXP2F(-synth->tables.resAmpFadeFactor[res >> 2] * (relWavePos / cosineLen)); // seems to be exact
+
+ // Now relWavePos set negative to the left from center of any cosine
+ relWavePos = wavePos;
+
+ // negative segment
+ if (!(wavePos < (waveLen - 0.5f * cosineLen))) {
+ relWavePos -= waveLen;
+ } else
+
+ // positive segment
+ if (!(wavePos < (hLen + 0.5f * cosineLen))) {
+ relWavePos -= cosineLen + hLen;
+ }
+
+ // Fading to zero while within cosine segments to avoid jumps in the wave
+ // Sample analysis suggests that this window is very close to cosine
+ if (relWavePos < 0.5f * cosineLen) {
+#if MT32EMU_ACCURATE_WG == 1
+ resAmpFade *= 0.5f * (1.0f - cosf(FLOAT_PI * relWavePos / (0.5f * cosineLen)));
+#else
+ resAmpFade *= 0.5f * (1.0f + synth->tables.sinf10[Bit32s(2048.0f * relWavePos / (0.5f * cosineLen)) + 3072]);
+#endif
+ }
+
+ sample += resSample * resAmp * resAmpFade;
+ }
+
+ // sawtooth waves
+ if ((patchCache->waveform & 1) != 0) {
+#if MT32EMU_ACCURATE_WG == 1
+ sample *= cosf(FLOAT_2PI * wavePos / waveLen);
+#else
+ sample *= synth->tables.sinf10[(Bit32u(4096.0f * wavePos / waveLen) & 4095) + 1024];
+#endif
+ }
+
+ wavePos++;
+
+ // wavePos isn't supposed to be > waveLen
+ if (wavePos > waveLen) {
+ wavePos -= waveLen;
+ }
+ }
+
+ // Multiply sample with current TVA value
+ sample *= amp;
+ *partialBuf++ = sample;
+ }
+ unsigned long renderedSamples = sampleNum;
+ sampleNum = 0;
+ return renderedSamples;
+}
+
+float *Partial::mixBuffersRingMix(float *buf1, float *buf2, unsigned long len) {
+ if (buf1 == NULL) {
+ return NULL;
+ }
+ if (buf2 == NULL) {
+ return buf1;
+ }
+
+ while (len--) {
+ // FIXME: At this point we have no idea whether this is remotely correct...
+ *buf1 = *buf1 * *buf2 + *buf1;
+ buf1++;
+ buf2++;
+ }
+ return buf1;
+}
+
+float *Partial::mixBuffersRing(float *buf1, float *buf2, unsigned long len) {
+ if (buf1 == NULL) {
+ return NULL;
+ }
+ if (buf2 == NULL) {
+ return NULL;
+ }
+
+ while (len--) {
+ // FIXME: At this point we have no idea whether this is remotely correct...
+ *buf1 = *buf1 * *buf2;
+ buf1++;
+ buf2++;
+ }
+ return buf1;
+}
+
+bool Partial::hasRingModulatingSlave() const {
+ return pair != NULL && structurePosition == 0 && (mixType == 1 || mixType == 2);
+}
+
+bool Partial::isRingModulatingSlave() const {
+ return pair != NULL && structurePosition == 1 && (mixType == 1 || mixType == 2);
+}
+
+bool Partial::isPCM() const {
+ return pcmWave != NULL;
+}
+
+const ControlROMPCMStruct *Partial::getControlROMPCMStruct() const {
+ if (pcmWave != NULL) {
+ return pcmWave->controlROMPCMStruct;
+ }
+ return NULL;
+}
+
+Synth *Partial::getSynth() const {
+ return synth;
+}
+
+bool Partial::produceOutput(float *leftBuf, float *rightBuf, unsigned long length) {
+ if (!isActive() || alreadyOutputed || isRingModulatingSlave()) {
+ return false;
+ }
+ if (poly == NULL) {
+ synth->printDebug("[Partial %d] *** ERROR: poly is NULL at Partial::produceOutput()!", debugPartialNum);
+ return false;
+ }
+
+ float *partialBuf = &myBuffer[0];
+ unsigned long numGenerated = generateSamples(partialBuf, length);
+ if (mixType == 1 || mixType == 2) {
+ float *pairBuf;
+ unsigned long pairNumGenerated;
+ if (pair == NULL) {
+ pairBuf = NULL;
+ pairNumGenerated = 0;
+ } else {
+ pairBuf = &pair->myBuffer[0];
+ pairNumGenerated = pair->generateSamples(pairBuf, numGenerated);
+ // pair will have been set to NULL if it deactivated within generateSamples()
+ if (pair != NULL) {
+ if (!isActive()) {
+ pair->deactivate();
+ pair = NULL;
+ } else if (!pair->isActive()) {
+ pair = NULL;
+ }
+ }
+ }
+ if (pairNumGenerated > 0) {
+ if (mixType == 1) {
+ mixBuffersRingMix(partialBuf, pairBuf, pairNumGenerated);
+ } else {
+ mixBuffersRing(partialBuf, pairBuf, pairNumGenerated);
+ }
+ }
+ if (numGenerated > pairNumGenerated) {
+ if (mixType == 1) {
+ mixBuffersRingMix(partialBuf + pairNumGenerated, NULL, numGenerated - pairNumGenerated);
+ } else {
+ mixBuffersRing(partialBuf + pairNumGenerated, NULL, numGenerated - pairNumGenerated);
+ }
+ }
+ }
+
+ for (unsigned int i = 0; i < numGenerated; i++) {
+ *leftBuf++ = partialBuf[i] * stereoVolume.leftVol;
+ }
+ for (unsigned int i = 0; i < numGenerated; i++) {
+ *rightBuf++ = partialBuf[i] * stereoVolume.rightVol;
+ }
+ while (numGenerated < length) {
+ *leftBuf++ = 0.0f;
+ *rightBuf++ = 0.0f;
+ numGenerated++;
+ }
+ return true;
+}
+
+bool Partial::shouldReverb() {
+ if (!isActive()) {
+ return false;
+ }
+ return patchCache->reverb;
+}
+
+void Partial::startAbort() {
+ // This is called when the partial manager needs to terminate partials for re-use by a new Poly.
+ tva->startAbort();
+}
+
+void Partial::startDecayAll() {
+ tva->startDecay();
+ tvp->startDecay();
+ tvf->startDecay();
+}
diff --git a/audio/softsynth/mt32/Partial.h b/audio/softsynth/mt32/Partial.h
new file mode 100644
index 0000000000..95218c858c
--- /dev/null
+++ b/audio/softsynth/mt32/Partial.h
@@ -0,0 +1,119 @@
+/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher
+ * Copyright (C) 2011 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef MT32EMU_PARTIAL_H
+#define MT32EMU_PARTIAL_H
+
+namespace MT32Emu {
+
+class Synth;
+class Part;
+class TVA;
+struct ControlROMPCMStruct;
+
+struct StereoVolume {
+ float leftVol;
+ float rightVol;
+};
+
+// A partial represents one of up to four waveform generators currently playing within a poly.
+class Partial {
+private:
+ Synth *synth;
+ const int debugPartialNum; // Only used for debugging
+ // Number of the sample currently being rendered by generateSamples(), or 0 if no run is in progress
+ // This is only kept available for debugging purposes.
+ unsigned long sampleNum;
+
+ int ownerPart; // -1 if unassigned
+ int mixType;
+ int structurePosition; // 0 or 1 of a structure pair
+ StereoVolume stereoVolume;
+
+ // Distance in (possibly fractional) samples from the start of the current pulse
+ float wavePos;
+
+ float lastFreq;
+
+ float myBuffer[MAX_SAMPLES_PER_RUN];
+
+ // Only used for PCM partials
+ int pcmNum;
+ // FIXME: Give this a better name (e.g. pcmWaveInfo)
+ PCMWaveEntry *pcmWave;
+
+ // Final pulse width value, with velfollow applied, matching what is sent to the LA32.
+ // Range: 0-255
+ int pulseWidthVal;
+
+ float pcmPosition;
+
+ Poly *poly;
+
+ LA32Ramp ampRamp;
+ LA32Ramp cutoffModifierRamp;
+
+ float *mixBuffersRingMix(float *buf1, float *buf2, unsigned long len);
+ float *mixBuffersRing(float *buf1, float *buf2, unsigned long len);
+
+ float getPCMSample(unsigned int position);
+
+public:
+ const PatchCache *patchCache;
+ TVA *tva;
+ TVP *tvp;
+ TVF *tvf;
+
+ PatchCache cachebackup;
+
+ Partial *pair;
+ bool alreadyOutputed;
+
+ Partial(Synth *synth, int debugPartialNum);
+ ~Partial();
+
+ int debugGetPartialNum() const;
+ unsigned long debugGetSampleNum() const;
+
+ int getOwnerPart() const;
+ int getKey() const;
+ const Poly *getPoly() const;
+ bool isActive() const;
+ void activate(int part);
+ void deactivate(void);
+ void startPartial(const Part *part, Poly *usePoly, const PatchCache *useCache, const MemParams::RhythmTemp *rhythmTemp, Partial *pairPartial);
+ void startAbort();
+ void startDecayAll();
+ bool shouldReverb();
+ bool hasRingModulatingSlave() const;
+ bool isRingModulatingSlave() const;
+ bool isPCM() const;
+ const ControlROMPCMStruct *getControlROMPCMStruct() const;
+ Synth *getSynth() const;
+
+ // Returns true only if data written to buffer
+ // This function (unlike the one below it) returns processed stereo samples
+ // made from combining this single partial with its pair, if it has one.
+ bool produceOutput(float *leftBuf, float *rightBuf, unsigned long length);
+
+ // This function writes mono sample output to the provided buffer, and returns the number of samples written
+ unsigned long generateSamples(float *partialBuf, unsigned long length);
+};
+
+}
+
+#endif
diff --git a/audio/softsynth/mt32/PartialManager.cpp b/audio/softsynth/mt32/PartialManager.cpp
new file mode 100644
index 0000000000..42a3eaa179
--- /dev/null
+++ b/audio/softsynth/mt32/PartialManager.cpp
@@ -0,0 +1,250 @@
+/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher
+ * Copyright (C) 2011 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+//#include <cstring>
+
+#include "mt32emu.h"
+#include "PartialManager.h"
+
+using namespace MT32Emu;
+
+PartialManager::PartialManager(Synth *useSynth, Part **useParts) {
+ synth = useSynth;
+ parts = useParts;
+ for (int i = 0; i < MT32EMU_MAX_PARTIALS; i++) {
+ partialTable[i] = new Partial(synth, i);
+ }
+}
+
+PartialManager::~PartialManager(void) {
+ for (int i = 0; i < MT32EMU_MAX_PARTIALS; i++) {
+ delete partialTable[i];
+ }
+}
+
+void PartialManager::clearAlreadyOutputed() {
+ for (int i = 0; i < MT32EMU_MAX_PARTIALS; i++) {
+ partialTable[i]->alreadyOutputed = false;
+ }
+}
+
+bool PartialManager::shouldReverb(int i) {
+ return partialTable[i]->shouldReverb();
+}
+
+bool PartialManager::produceOutput(int i, float *leftBuf, float *rightBuf, Bit32u bufferLength) {
+ return partialTable[i]->produceOutput(leftBuf, rightBuf, bufferLength);
+}
+
+void PartialManager::deactivateAll() {
+ for (int i = 0; i < MT32EMU_MAX_PARTIALS; i++) {
+ partialTable[i]->deactivate();
+ }
+}
+
+unsigned int PartialManager::setReserve(Bit8u *rset) {
+ unsigned int pr = 0;
+ for (int x = 0; x <= 8; x++) {
+ numReservedPartialsForPart[x] = rset[x];
+ pr += rset[x];
+ }
+ return pr;
+}
+
+Partial *PartialManager::allocPartial(int partNum) {
+ Partial *outPartial = NULL;
+
+ // Get the first inactive partial
+ for (int partialNum = 0; partialNum < MT32EMU_MAX_PARTIALS; partialNum++) {
+ if (!partialTable[partialNum]->isActive()) {
+ outPartial = partialTable[partialNum];
+ break;
+ }
+ }
+ if (outPartial != NULL) {
+ outPartial->activate(partNum);
+ }
+ return outPartial;
+}
+
+unsigned int PartialManager::getFreePartialCount(void) {
+ int count = 0;
+ for (int i = 0; i < MT32EMU_MAX_PARTIALS; i++) {
+ if (!partialTable[i]->isActive()) {
+ count++;
+ }
+ }
+ return count;
+}
+
+// This function is solely used to gather data for debug output at the moment.
+void PartialManager::getPerPartPartialUsage(unsigned int perPartPartialUsage[9]) {
+ memset(perPartPartialUsage, 0, 9 * sizeof(unsigned int));
+ for (unsigned int i = 0; i < MT32EMU_MAX_PARTIALS; i++) {
+ if (partialTable[i]->isActive()) {
+ perPartPartialUsage[partialTable[i]->getOwnerPart()]++;
+ }
+ }
+}
+
+// Finds the lowest-priority part that is exceeding its reserved partial allocation and has a poly
+// in POLY_Releasing, then kills its first releasing poly.
+// Parts with higher priority than minPart are not checked.
+// Assumes that getFreePartials() has been called to make numReservedPartialsForPart up-to-date.
+bool PartialManager::abortFirstReleasingPolyWhereReserveExceeded(int minPart) {
+ if (minPart == 8) {
+ // Rhythm is highest priority
+ minPart = -1;
+ }
+ for (int partNum = 7; partNum >= minPart; partNum--) {
+ int usePartNum = partNum == -1 ? 8 : partNum;
+ if (parts[usePartNum]->getActivePartialCount() > numReservedPartialsForPart[usePartNum]) {
+ // This part has exceeded its reserved partial count.
+ // If it has any releasing polys, kill its first one and we're done.
+ if (parts[usePartNum]->abortFirstPoly(POLY_Releasing)) {
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+// Finds the lowest-priority part that is exceeding its reserved partial allocation and has a poly, then kills
+// its first poly in POLY_Held - or failing that, its first poly in any state.
+// Parts with higher priority than minPart are not checked.
+// Assumes that getFreePartials() has been called to make numReservedPartialsForPart up-to-date.
+bool PartialManager::abortFirstPolyPreferHeldWhereReserveExceeded(int minPart) {
+ if (minPart == 8) {
+ // Rhythm is highest priority
+ minPart = -1;
+ }
+ for (int partNum = 7; partNum >= minPart; partNum--) {
+ int usePartNum = partNum == -1 ? 8 : partNum;
+ if (parts[usePartNum]->getActivePartialCount() > numReservedPartialsForPart[usePartNum]) {
+ // This part has exceeded its reserved partial count.
+ // If it has any polys, kill its first (preferably held) one and we're done.
+ if (parts[usePartNum]->abortFirstPolyPreferHeld()) {
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+bool PartialManager::freePartials(unsigned int needed, int partNum) {
+ // CONFIRMED: Barring bugs, this matches the real LAPC-I according to information from Mok.
+
+ // BUG: There's a bug in the LAPC-I implementation:
+ // When allocating for rhythm part, or when allocating for a part that is using fewer partials than it has reserved,
+ // held and playing polys on the rhythm part can potentially be aborted before releasing polys on the rhythm part.
+ // This bug isn't present on MT-32.
+ // I consider this to be a bug because I think that playing polys should always have priority over held polys,
+ // and held polys should always have priority over releasing polys.
+
+ // NOTE: This code generally aborts polys in parts (according to certain conditions) in the following order:
+ // 7, 6, 5, 4, 3, 2, 1, 0, 8 (rhythm)
+ // (from lowest priority, meaning most likely to have polys aborted, to highest priority, meaning least likely)
+
+ if (needed == 0) {
+ return true;
+ }
+
+ // Note that calling getFreePartialCount() also ensures that numReservedPartialsPerPart is up-to-date
+ if (getFreePartialCount() >= needed) {
+ return true;
+ }
+
+ // Note: These #ifdefs are temporary until we have proper "quirk" configuration.
+ // Also, the MT-32 version isn't properly confirmed yet.
+#ifdef MT32EMU_QUIRK_FREE_PARTIALS_MT32
+ // On MT-32, we bail out before even killing releasing partials if the allocating part has exceeded its reserve and is configured for priority-to-earlier-polys.
+ if (parts[partNum]->getActiveNonReleasingPartialCount() + needed > numReservedPartialsForPart[partNum] && (synth->getPart(partNum)->getPatchTemp()->patch.assignMode & 1)) {
+ return false;
+ }
+#endif
+
+ for (;;) {
+#ifdef MT32EMU_QUIRK_FREE_PARTIALS_MT32
+ // Abort releasing polys in parts that have exceeded their partial reservation (working backwards from part 7, with rhythm last)
+ if (!abortFirstReleasingPolyWhereReserveExceeded(-1)) {
+ break;
+ }
+#else
+ // Abort releasing polys in non-rhythm parts that have exceeded their partial reservation (working backwards from part 7)
+ if (!abortFirstReleasingPolyWhereReserveExceeded(0)) {
+ break;
+ }
+#endif
+ if (getFreePartialCount() >= needed) {
+ return true;
+ }
+ }
+
+ if (parts[partNum]->getActiveNonReleasingPartialCount() + needed > numReservedPartialsForPart[partNum]) {
+ // With the new partials we're freeing for, we would end up using more partials than we have reserved.
+ if (synth->getPart(partNum)->getPatchTemp()->patch.assignMode & 1) {
+ // Priority is given to earlier polys, so just give up
+ return false;
+ }
+ // Only abort held polys in the target part and parts that have a lower priority
+ // (higher part number = lower priority, except for rhythm, which has the highest priority).
+ for (;;) {
+ if (!abortFirstPolyPreferHeldWhereReserveExceeded(partNum)) {
+ break;
+ }
+ if (getFreePartialCount() >= needed) {
+ return true;
+ }
+ }
+ if (needed > numReservedPartialsForPart[partNum]) {
+ return false;
+ }
+ } else {
+ // At this point, we're certain that we've reserved enough partials to play our poly.
+ // Check all parts from lowest to highest priority to see whether they've exceeded their
+ // reserve, and abort their polys until until we have enough free partials or they're within
+ // their reserve allocation.
+ for (;;) {
+ if (!abortFirstPolyPreferHeldWhereReserveExceeded(-1)) {
+ break;
+ }
+ if (getFreePartialCount() >= needed) {
+ return true;
+ }
+ }
+ }
+
+ // Abort polys in the target part until there are enough free partials for the new one
+ for (;;) {
+ if (!parts[partNum]->abortFirstPolyPreferHeld()) {
+ break;
+ }
+ if (getFreePartialCount() >= needed) {
+ return true;
+ }
+ }
+
+ // Aww, not enough partials for you.
+ return false;
+}
+
+const Partial *PartialManager::getPartial(unsigned int partialNum) const {
+ if (partialNum > MT32EMU_MAX_PARTIALS - 1) {
+ return NULL;
+ }
+ return partialTable[partialNum];
+}
diff --git a/audio/softsynth/mt32/PartialManager.h b/audio/softsynth/mt32/PartialManager.h
new file mode 100644
index 0000000000..bb78672457
--- /dev/null
+++ b/audio/softsynth/mt32/PartialManager.h
@@ -0,0 +1,54 @@
+/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher
+ * Copyright (C) 2011 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef MT32EMU_PARTIALMANAGER_H
+#define MT32EMU_PARTIALMANAGER_H
+
+namespace MT32Emu {
+
+class Synth;
+
+class PartialManager {
+private:
+ Synth *synth; // Only used for sending debug output
+ Part **parts;
+
+ Partial *partialTable[MT32EMU_MAX_PARTIALS];
+ Bit8u numReservedPartialsForPart[9];
+
+ bool abortFirstReleasingPolyWhereReserveExceeded(int minPart);
+ bool abortFirstPolyPreferHeldWhereReserveExceeded(int minPart);
+
+public:
+
+ PartialManager(Synth *synth, Part **parts);
+ ~PartialManager();
+ Partial *allocPartial(int partNum);
+ unsigned int getFreePartialCount(void);
+ void getPerPartPartialUsage(unsigned int perPartPartialUsage[9]);
+ bool freePartials(unsigned int needed, int partNum);
+ unsigned int setReserve(Bit8u *rset);
+ void deactivateAll();
+ bool produceOutput(int i, float *leftBuf, float *rightBuf, Bit32u bufferLength);
+ bool shouldReverb(int i);
+ void clearAlreadyOutputed();
+ const Partial *getPartial(unsigned int partialNum) const;
+};
+
+}
+
+#endif
diff --git a/audio/softsynth/mt32/Poly.cpp b/audio/softsynth/mt32/Poly.cpp
new file mode 100644
index 0000000000..a2f00db73c
--- /dev/null
+++ b/audio/softsynth/mt32/Poly.cpp
@@ -0,0 +1,174 @@
+/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher
+ * Copyright (C) 2011 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "mt32emu.h"
+
+namespace MT32Emu {
+
+Poly::Poly(Part *usePart) {
+ part = usePart;
+ key = 255;
+ velocity = 255;
+ sustain = false;
+ activePartialCount = 0;
+ for (int i = 0; i < 4; i++) {
+ partials[i] = NULL;
+ }
+ state = POLY_Inactive;
+}
+
+void Poly::reset(unsigned int newKey, unsigned int newVelocity, bool newSustain, Partial **newPartials) {
+ if (isActive()) {
+ // FIXME: Throw out some big ugly debug output with a lot of exclamation marks - we should never get here
+ terminate();
+ }
+
+ key = newKey;
+ velocity = newVelocity;
+ sustain = newSustain;
+
+ activePartialCount = 0;
+ for (int i = 0; i < 4; i++) {
+ partials[i] = newPartials[i];
+ if (newPartials[i] != NULL) {
+ activePartialCount++;
+ state = POLY_Playing;
+ }
+ }
+}
+
+bool Poly::noteOff(bool pedalHeld) {
+ // Generally, non-sustaining instruments ignore note off. They die away eventually anyway.
+ // Key 0 (only used by special cases on rhythm part) reacts to note off even if non-sustaining or pedal held.
+ if (state == POLY_Inactive || state == POLY_Releasing) {
+ return false;
+ }
+ if (pedalHeld) {
+ state = POLY_Held;
+ } else {
+ startDecay();
+ }
+ return true;
+}
+
+bool Poly::stopPedalHold() {
+ if (state != POLY_Held) {
+ return false;
+ }
+ return startDecay();
+}
+
+bool Poly::startDecay() {
+ if (state == POLY_Inactive || state == POLY_Releasing) {
+ return false;
+ }
+ state = POLY_Releasing;
+
+ for (int t = 0; t < 4; t++) {
+ Partial *partial = partials[t];
+ if (partial != NULL) {
+ partial->startDecayAll();
+ }
+ }
+ return true;
+}
+
+bool Poly::startAbort() {
+ if (state == POLY_Inactive) {
+ return false;
+ }
+ for (int t = 0; t < 4; t++) {
+ Partial *partial = partials[t];
+ if (partial != NULL) {
+ partial->startAbort();
+ }
+ }
+ return true;
+}
+
+void Poly::terminate() {
+ if (state == POLY_Inactive) {
+ return;
+ }
+ for (int t = 0; t < 4; t++) {
+ Partial *partial = partials[t];
+ if (partial != NULL) {
+ partial->deactivate();
+ }
+ }
+ if (state != POLY_Inactive) {
+ // FIXME: Throw out lots of debug output - this should never happen
+ // (Deactivating the partials above should've made them each call partialDeactivated(), ultimately changing the state to POLY_Inactive)
+ state = POLY_Inactive;
+ }
+}
+
+void Poly::backupCacheToPartials(PatchCache cache[4]) {
+ for (int partialNum = 0; partialNum < 4; partialNum++) {
+ Partial *partial = partials[partialNum];
+ if (partial != NULL && partial->patchCache == &cache[partialNum]) {
+ partial->cachebackup = cache[partialNum];
+ partial->patchCache = &partial->cachebackup;
+ }
+ }
+}
+
+/**
+ * Returns the internal key identifier.
+ * For non-rhythm, this is within the range 12 to 108.
+ * For rhythm on MT-32, this is 0 or 1 (special cases) or within the range 24 to 87.
+ * For rhythm on devices with extended PCM sounds (e.g. CM-32L), this is 0, 1 or 24 to 108
+ */
+unsigned int Poly::getKey() const {
+ return key;
+}
+
+unsigned int Poly::getVelocity() const {
+ return velocity;
+}
+
+bool Poly::canSustain() const {
+ return sustain;
+}
+
+PolyState Poly::getState() const {
+ return state;
+}
+
+unsigned int Poly::getActivePartialCount() const {
+ return activePartialCount;
+}
+
+bool Poly::isActive() const {
+ return state != POLY_Inactive;
+}
+
+// This is called by Partial to inform the poly that the Partial has deactivated
+void Poly::partialDeactivated(Partial *partial) {
+ for (int i = 0; i < 4; i++) {
+ if (partials[i] == partial) {
+ partials[i] = NULL;
+ activePartialCount--;
+ }
+ }
+ if (activePartialCount == 0) {
+ state = POLY_Inactive;
+ }
+ part->partialDeactivated(this);
+}
+
+}
diff --git a/audio/softsynth/mt32/Poly.h b/audio/softsynth/mt32/Poly.h
new file mode 100644
index 0000000000..cd15a776f5
--- /dev/null
+++ b/audio/softsynth/mt32/Poly.h
@@ -0,0 +1,67 @@
+/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher
+ * Copyright (C) 2011 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef MT32EMU_POLY_H
+#define MT32EMU_POLY_H
+
+namespace MT32Emu {
+
+class Part;
+
+enum PolyState {
+ POLY_Playing,
+ POLY_Held, // This marks keys that have been released on the keyboard, but are being held by the pedal
+ POLY_Releasing,
+ POLY_Inactive
+};
+
+class Poly {
+private:
+ Part *part;
+ unsigned int key;
+ unsigned int velocity;
+ unsigned int activePartialCount;
+ bool sustain;
+
+ PolyState state;
+
+ Partial *partials[4];
+
+public:
+ Poly(Part *part);
+ void reset(unsigned int key, unsigned int velocity, bool sustain, Partial **partials);
+ bool noteOff(bool pedalHeld);
+ bool stopPedalHold();
+ bool startDecay();
+ bool startAbort();
+ void terminate();
+
+ void backupCacheToPartials(PatchCache cache[4]);
+
+ unsigned int getKey() const;
+ unsigned int getVelocity() const;
+ bool canSustain() const;
+ PolyState getState() const;
+ unsigned int getActivePartialCount() const;
+ bool isActive() const;
+
+ void partialDeactivated(Partial *partial);
+};
+
+}
+
+#endif /* POLY_H_ */
diff --git a/audio/softsynth/mt32/Structures.h b/audio/softsynth/mt32/Structures.h
new file mode 100644
index 0000000000..e4d98ad1fc
--- /dev/null
+++ b/audio/softsynth/mt32/Structures.h
@@ -0,0 +1,217 @@
+/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher
+ * Copyright (C) 2011 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef MT32EMU_STRUCTURES_H
+#define MT32EMU_STRUCTURES_H
+
+namespace MT32Emu {
+
+// MT32EMU_MEMADDR() converts from sysex-padded, MT32EMU_SYSEXMEMADDR converts to it
+// Roland provides documentation using the sysex-padded addresses, so we tend to use that in code and output
+#define MT32EMU_MEMADDR(x) ((((x) & 0x7f0000) >> 2) | (((x) & 0x7f00) >> 1) | ((x) & 0x7f))
+#define MT32EMU_SYSEXMEMADDR(x) ((((x) & 0x1FC000) << 2) | (((x) & 0x3F80) << 1) | ((x) & 0x7f))
+
+#ifdef _MSC_VER
+#define MT32EMU_ALIGN_PACKED __declspec(align(1))
+#else
+#define MT32EMU_ALIGN_PACKED __attribute__((packed))
+#endif
+
+typedef unsigned int Bit32u;
+typedef signed int Bit32s;
+typedef unsigned short int Bit16u;
+typedef signed short int Bit16s;
+typedef unsigned char Bit8u;
+typedef signed char Bit8s;
+
+// The following structures represent the MT-32's memory
+// Since sysex allows this memory to be written to in blocks of bytes,
+// we keep this packed so that we can copy data into the various
+// banks directly
+#if defined(_MSC_VER) || defined (__MINGW32__)
+#pragma pack(push, 1)
+#else
+#pragma pack(1)
+#endif
+
+struct TimbreParam {
+ struct CommonParam {
+ char name[10];
+ Bit8u partialStructure12; // 1 & 2 0-12 (1-13)
+ Bit8u partialStructure34; // 3 & 4 0-12 (1-13)
+ Bit8u partialMute; // 0-15 (0000-1111)
+ Bit8u noSustain; // ENV MODE 0-1 (Normal, No sustain)
+ } MT32EMU_ALIGN_PACKED common;
+
+ struct PartialParam {
+ struct WGParam {
+ Bit8u pitchCoarse; // 0-96 (C1,C#1-C9)
+ Bit8u pitchFine; // 0-100 (-50 to +50 (cents - confirmed by Mok))
+ Bit8u pitchKeyfollow; // 0-16 (-1, -1/2, -1/4, 0, 1/8, 1/4, 3/8, 1/2, 5/8, 3/4, 7/8, 1, 5/4, 3/2, 2, s1, s2)
+ Bit8u pitchBenderEnabled; // 0-1 (OFF, ON)
+ Bit8u waveform; // MT-32: 0-1 (SQU/SAW); LAPC-I: WG WAVEFORM/PCM BANK 0 - 3 (SQU/1, SAW/1, SQU/2, SAW/2)
+ Bit8u pcmWave; // 0-127 (1-128)
+ Bit8u pulseWidth; // 0-100
+ Bit8u pulseWidthVeloSensitivity; // 0-14 (-7 - +7)
+ } MT32EMU_ALIGN_PACKED wg;
+
+ struct PitchEnvParam {
+ Bit8u depth; // 0-10
+ Bit8u veloSensitivity; // 0-100
+ Bit8u timeKeyfollow; // 0-4
+ Bit8u time[4]; // 0-100
+ Bit8u level[5]; // 0-100 (-50 - +50) // [3]: SUSTAIN LEVEL, [4]: END LEVEL
+ } MT32EMU_ALIGN_PACKED pitchEnv;
+
+ struct PitchLFOParam {
+ Bit8u rate; // 0-100
+ Bit8u depth; // 0-100
+ Bit8u modSensitivity; // 0-100
+ } MT32EMU_ALIGN_PACKED pitchLFO;
+
+ struct TVFParam {
+ Bit8u cutoff; // 0-100
+ Bit8u resonance; // 0-30
+ Bit8u keyfollow; // -1, -1/2, -1/4, 0, 1/8, 1/4, 3/8, 1/2, 5/8, 3/4, 7/8, 1, 5/4, 3/2, 2
+ Bit8u biasPoint; // 0-127 (<1A-<7C >1A-7C)
+ Bit8u biasLevel; // 0-14 (-7 - +7)
+ Bit8u envDepth; // 0-100
+ Bit8u envVeloSensitivity; // 0-100
+ Bit8u envDepthKeyfollow; // DEPTH KEY FOLL0W 0-4
+ Bit8u envTimeKeyfollow; // TIME KEY FOLLOW 0-4
+ Bit8u envTime[5]; // 0-100
+ Bit8u envLevel[4]; // 0-100 // [3]: SUSTAIN LEVEL
+ } MT32EMU_ALIGN_PACKED tvf;
+
+ struct TVAParam {
+ Bit8u level; // 0-100
+ Bit8u veloSensitivity; // 0-100
+ Bit8u biasPoint1; // 0-127 (<1A-<7C >1A-7C)
+ Bit8u biasLevel1; // 0-12 (-12 - 0)
+ Bit8u biasPoint2; // 0-127 (<1A-<7C >1A-7C)
+ Bit8u biasLevel2; // 0-12 (-12 - 0)
+ Bit8u envTimeKeyfollow; // TIME KEY FOLLOW 0-4
+ Bit8u envTimeVeloSensitivity; // VELOS KEY FOLL0W 0-4
+ Bit8u envTime[5]; // 0-100
+ Bit8u envLevel[4]; // 0-100 // [3]: SUSTAIN LEVEL
+ } MT32EMU_ALIGN_PACKED tva;
+ } MT32EMU_ALIGN_PACKED partial[4];
+} MT32EMU_ALIGN_PACKED;
+
+struct PatchParam {
+ Bit8u timbreGroup; // TIMBRE GROUP 0-3 (group A, group B, Memory, Rhythm)
+ Bit8u timbreNum; // TIMBRE NUMBER 0-63
+ Bit8u keyShift; // KEY SHIFT 0-48 (-24 - +24 semitones)
+ Bit8u fineTune; // FINE TUNE 0-100 (-50 - +50 cents)
+ Bit8u benderRange; // BENDER RANGE 0-24
+ Bit8u assignMode; // ASSIGN MODE 0-3 (POLY1, POLY2, POLY3, POLY4)
+ Bit8u reverbSwitch; // REVERB SWITCH 0-1 (OFF,ON)
+ Bit8u dummy; // (DUMMY)
+} MT32EMU_ALIGN_PACKED;
+
+const unsigned int SYSTEM_MASTER_TUNE_OFF = 0;
+const unsigned int SYSTEM_REVERB_MODE_OFF = 1;
+const unsigned int SYSTEM_REVERB_TIME_OFF = 2;
+const unsigned int SYSTEM_REVERB_LEVEL_OFF = 3;
+const unsigned int SYSTEM_RESERVE_SETTINGS_START_OFF = 4;
+const unsigned int SYSTEM_RESERVE_SETTINGS_END_OFF = 12;
+const unsigned int SYSTEM_CHAN_ASSIGN_START_OFF = 13;
+const unsigned int SYSTEM_CHAN_ASSIGN_END_OFF = 21;
+const unsigned int SYSTEM_MASTER_VOL_OFF = 22;
+
+struct MemParams {
+ // NOTE: The MT-32 documentation only specifies PatchTemp areas for parts 1-8.
+ // The LAPC-I documentation specified an additional area for rhythm at the end,
+ // where all parameters but fine tune, assign mode and output level are ignored
+ struct PatchTemp {
+ PatchParam patch;
+ Bit8u outputLevel; // OUTPUT LEVEL 0-100
+ Bit8u panpot; // PANPOT 0-14 (R-L)
+ Bit8u dummyv[6];
+ } MT32EMU_ALIGN_PACKED patchTemp[9];
+
+ struct RhythmTemp {
+ Bit8u timbre; // TIMBRE 0-94 (M1-M64,R1-30,OFF); LAPC-I: 0-127 (M01-M64,R01-R63)
+ Bit8u outputLevel; // OUTPUT LEVEL 0-100
+ Bit8u panpot; // PANPOT 0-14 (R-L)
+ Bit8u reverbSwitch; // REVERB SWITCH 0-1 (OFF,ON)
+ } MT32EMU_ALIGN_PACKED rhythmTemp[85];
+
+ TimbreParam timbreTemp[8];
+
+ PatchParam patches[128];
+
+ // NOTE: There are only 30 timbres in the "rhythm" bank for MT-32; the additional 34 are for LAPC-I and above
+ struct PaddedTimbre {
+ TimbreParam timbre;
+ Bit8u padding[10];
+ } MT32EMU_ALIGN_PACKED timbres[64 + 64 + 64 + 64]; // Group A, Group B, Memory, Rhythm
+
+ struct System {
+ Bit8u masterTune; // MASTER TUNE 0-127 432.1-457.6Hz
+ Bit8u reverbMode; // REVERB MODE 0-3 (room, hall, plate, tap delay)
+ Bit8u reverbTime; // REVERB TIME 0-7 (1-8)
+ Bit8u reverbLevel; // REVERB LEVEL 0-7 (1-8)
+ Bit8u reserveSettings[9]; // PARTIAL RESERVE (PART 1) 0-32
+ Bit8u chanAssign[9]; // MIDI CHANNEL (PART1) 0-16 (1-16,OFF)
+ Bit8u masterVol; // MASTER VOLUME 0-100
+ } MT32EMU_ALIGN_PACKED system;
+};
+
+#if defined(_MSC_VER) || defined (__MINGW32__)
+#pragma pack(pop)
+#else
+#pragma pack()
+#endif
+
+struct ControlROMPCMStruct;
+
+struct PCMWaveEntry {
+ Bit32u addr;
+ Bit32u len;
+ bool loop;
+ ControlROMPCMStruct *controlROMPCMStruct;
+};
+
+// This is basically a per-partial, pre-processed combination of timbre and patch/rhythm settings
+struct PatchCache {
+ bool playPartial;
+ bool PCMPartial;
+ int pcm;
+ char waveform;
+
+ Bit32u structureMix;
+ int structurePosition;
+ int structurePair;
+
+ // The following fields are actually common to all partials in the timbre
+ bool dirty;
+ Bit32u partialCount;
+ bool sustain;
+ bool reverb;
+
+ TimbreParam::PartialParam srcPartial;
+
+ // The following directly points into live sysex-addressable memory
+ const TimbreParam::PartialParam *partialParam;
+};
+
+class Partial; // Forward reference for class defined in partial.h
+
+}
+
+#endif
diff --git a/audio/softsynth/mt32/Synth.cpp b/audio/softsynth/mt32/Synth.cpp
new file mode 100644
index 0000000000..0861053b5c
--- /dev/null
+++ b/audio/softsynth/mt32/Synth.cpp
@@ -0,0 +1,1620 @@
+/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher
+ * Copyright (C) 2011 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+//#include <cerrno>
+//#include <cmath>
+//#include <cstdlib>
+//#include <cstring>
+
+#define FORBIDDEN_SYMBOL_EXCEPTION_printf
+#define FORBIDDEN_SYMBOL_EXCEPTION_vprintf
+
+#include "mt32emu.h"
+#include "mmath.h"
+#include "PartialManager.h"
+
+#if MT32EMU_USE_AREVERBMODEL == 1
+#include "AReverbModel.h"
+#else
+#include "FreeverbModel.h"
+#endif
+#include "DelayReverb.h"
+
+namespace MT32Emu {
+
+const ControlROMMap ControlROMMaps[7] = {
+ // ID IDc IDbytes PCMmap PCMc tmbrA tmbrAO, tmbrAC tmbrB tmbrBO, tmbrBC tmbrR trC rhythm rhyC rsrv panpot prog rhyMax patMax sysMax timMax
+ {0x4014, 22, "\000 ver1.04 14 July 87 ", 0x3000, 128, 0x8000, 0x0000, false, 0xC000, 0x4000, false, 0x3200, 30, 0x73A6, 85, 0x57C7, 0x57E2, 0x57D0, 0x5252, 0x525E, 0x526E, 0x520A},
+ {0x4014, 22, "\000 ver1.05 06 Aug, 87 ", 0x3000, 128, 0x8000, 0x0000, false, 0xC000, 0x4000, false, 0x3200, 30, 0x7414, 85, 0x57C7, 0x57E2, 0x57D0, 0x5252, 0x525E, 0x526E, 0x520A},
+ {0x4014, 22, "\000 ver1.06 31 Aug, 87 ", 0x3000, 128, 0x8000, 0x0000, false, 0xC000, 0x4000, false, 0x3200, 30, 0x7414, 85, 0x57D9, 0x57F4, 0x57E2, 0x5264, 0x5270, 0x5280, 0x521C},
+ {0x4010, 22, "\000 ver1.07 10 Oct, 87 ", 0x3000, 128, 0x8000, 0x0000, false, 0xC000, 0x4000, false, 0x3200, 30, 0x73fe, 85, 0x57B1, 0x57CC, 0x57BA, 0x523C, 0x5248, 0x5258, 0x51F4}, // MT-32 revision 1
+ {0x4010, 22, "\000verX.XX 30 Sep, 88 ", 0x3000, 128, 0x8000, 0x0000, false, 0xC000, 0x4000, false, 0x3200, 30, 0x741C, 85, 0x57E5, 0x5800, 0x57EE, 0x5270, 0x527C, 0x528C, 0x5228}, // MT-32 Blue Ridge mod
+ {0x2205, 22, "\000CM32/LAPC1.00 890404", 0x8100, 256, 0x8000, 0x8000, false, 0x8080, 0x8000, false, 0x8500, 64, 0x8580, 85, 0x4F65, 0x4F80, 0x4F6E, 0x48A1, 0x48A5, 0x48BE, 0x48D5},
+ {0x2205, 22, "\000CM32/LAPC1.02 891205", 0x8100, 256, 0x8000, 0x8000, true, 0x8080, 0x8000, true, 0x8500, 64, 0x8580, 85, 0x4F93, 0x4FAE, 0x4F9C, 0x48CB, 0x48CF, 0x48E8, 0x48FF} // CM-32L
+ // (Note that all but CM-32L ROM actually have 86 entries for rhythmTemp)
+};
+
+static inline Bit16s *streamOffset(Bit16s *stream, Bit32u pos) {
+ return stream == NULL ? NULL : stream + pos;
+}
+
+static inline void clearIfNonNull(Bit16s *stream, Bit32u len) {
+ if (stream != NULL) {
+ memset(stream, 0, len * sizeof(Bit16s));
+ }
+}
+
+static inline void mix(float *target, const float *stream, Bit32u len) {
+ while (len--) {
+ *target += *stream;
+ stream++;
+ target++;
+ }
+}
+
+static inline void clearFloats(float *leftBuf, float *rightBuf, Bit32u len) {
+ // FIXME: Use memset() where compatibility is guaranteed (if this turns out to be a win)
+ while (len--) {
+ *leftBuf++ = 0.0f;
+ *rightBuf++ = 0.0f;
+ }
+}
+
+static inline Bit16s clipBit16s(Bit32s a) {
+ // Clamp values above 32767 to 32767, and values below -32768 to -32768
+ if ((a + 32768) & ~65535) {
+ return (a >> 31) ^ 32767;
+ }
+ return a;
+}
+
+static void floatToBit16s_nice(Bit16s *target, const float *source, Bit32u len, float outputGain) {
+ float gain = outputGain * 16384.0f;
+ while (len--) {
+ // Since we're not shooting for accuracy here, don't worry about the rounding mode.
+ *target = clipBit16s((Bit32s)(*source * gain));
+ source++;
+ target++;
+ }
+}
+
+static void floatToBit16s_pure(Bit16s *target, const float *source, Bit32u len, float /*outputGain*/) {
+ while (len--) {
+ *target = clipBit16s((Bit32s)floor(*source * 8192.0f));
+ source++;
+ target++;
+ }
+}
+
+static void floatToBit16s_reverb(Bit16s *target, const float *source, Bit32u len, float outputGain) {
+ float gain = outputGain * 8192.0f;
+ while (len--) {
+ *target = clipBit16s((Bit32s)floor(*source * gain));
+ source++;
+ target++;
+ }
+}
+
+static void floatToBit16s_generation1(Bit16s *target, const float *source, Bit32u len, float outputGain) {
+ float gain = outputGain * 8192.0f;
+ while (len--) {
+ *target = clipBit16s((Bit32s)floor(*source * gain));
+ *target = (*target & 0x8000) | ((*target << 1) & 0x7FFE);
+ source++;
+ target++;
+ }
+}
+
+static void floatToBit16s_generation2(Bit16s *target, const float *source, Bit32u len, float outputGain) {
+ float gain = outputGain * 8192.0f;
+ while (len--) {
+ *target = clipBit16s((Bit32s)floor(*source * gain));
+ *target = (*target & 0x8000) | ((*target << 1) & 0x7FFE) | ((*target >> 14) & 0x0001);
+ source++;
+ target++;
+ }
+}
+
+Bit8u Synth::calcSysexChecksum(const Bit8u *data, Bit32u len, Bit8u checksum) {
+ for (unsigned int i = 0; i < len; i++) {
+ checksum = checksum + data[i];
+ }
+ checksum = checksum & 0x7f;
+ if (checksum) {
+ checksum = 0x80 - checksum;
+ }
+ return checksum;
+}
+
+Synth::Synth() {
+ isOpen = false;
+ reverbEnabled = true;
+ reverbOverridden = false;
+
+#if MT32EMU_USE_AREVERBMODEL == 1
+ reverbModels[0] = new AReverbModel(&AReverbModel::REVERB_MODE_0_SETTINGS);
+ reverbModels[1] = new AReverbModel(&AReverbModel::REVERB_MODE_1_SETTINGS);
+ reverbModels[2] = new AReverbModel(&AReverbModel::REVERB_MODE_2_SETTINGS);
+#else
+ reverbModels[0] = new FreeverbModel(0.76f, 0.687770909f, 0.63f, 0, 0.5f);
+ reverbModels[1] = new FreeverbModel(2.0f, 0.712025098f, 0.86f, 1, 0.5f);
+ reverbModels[2] = new FreeverbModel(0.4f, 0.939522749f, 0.38f, 2, 0.05f);
+#endif
+
+ reverbModels[3] = new DelayReverb();
+ reverbModel = NULL;
+ setDACInputMode(DACInputMode_NICE);
+ setOutputGain(1.0f);
+ setReverbOutputGain(0.68f);
+ partialManager = NULL;
+ memset(parts, 0, sizeof(parts));
+ renderedSampleCount = 0;
+}
+
+Synth::~Synth() {
+ close(); // Make sure we're closed and everything is freed
+ for (int i = 0; i < 4; i++) {
+ delete reverbModels[i];
+ }
+}
+
+int Synth::report(ReportType type, const void *data) {
+ if (myProp.report != NULL) {
+ return myProp.report(myProp.userData, type, data);
+ }
+ return 0;
+}
+
+unsigned int Synth::getSampleRate() const {
+ return myProp.sampleRate;
+}
+
+void Synth::printDebug(const char *fmt, ...) {
+ va_list ap;
+ va_start(ap, fmt);
+ if (myProp.printDebug != NULL) {
+ myProp.printDebug(myProp.userData, fmt, ap);
+ } else {
+#if MT32EMU_DEBUG_SAMPLESTAMPS > 0
+ printf("[%u] ", renderedSampleCount);
+#endif
+ vprintf(fmt, ap);
+ printf("\n");
+ }
+ va_end(ap);
+}
+
+void Synth::setReverbEnabled(bool newReverbEnabled) {
+ reverbEnabled = newReverbEnabled;
+}
+
+bool Synth::isReverbEnabled() const {
+ return reverbEnabled;
+}
+
+void Synth::setReverbOverridden(bool newReverbOverridden) {
+ reverbOverridden = newReverbOverridden;
+}
+
+bool Synth::isReverbOverridden() const {
+ return reverbOverridden;
+}
+
+void Synth::setDACInputMode(DACInputMode mode) {
+ switch(mode) {
+ case DACInputMode_GENERATION1:
+ la32FloatToBit16sFunc = floatToBit16s_generation1;
+ reverbFloatToBit16sFunc = floatToBit16s_reverb;
+ break;
+ case DACInputMode_GENERATION2:
+ la32FloatToBit16sFunc = floatToBit16s_generation2;
+ reverbFloatToBit16sFunc = floatToBit16s_reverb;
+ break;
+ case DACInputMode_PURE:
+ la32FloatToBit16sFunc = floatToBit16s_pure;
+ reverbFloatToBit16sFunc = floatToBit16s_pure;
+ break;
+ case DACInputMode_NICE:
+ default:
+ la32FloatToBit16sFunc = floatToBit16s_nice;
+ reverbFloatToBit16sFunc = floatToBit16s_reverb;
+ break;
+ }
+}
+
+void Synth::setOutputGain(float newOutputGain) {
+ outputGain = newOutputGain;
+}
+
+void Synth::setReverbOutputGain(float newReverbOutputGain) {
+ reverbOutputGain = newReverbOutputGain;
+}
+
+Common::File *Synth::openFile(const char *filename) {
+ if (myProp.openFile != NULL) {
+ return myProp.openFile(myProp.userData, filename);
+ }
+ char pathBuf[2048];
+ if (myProp.baseDir != NULL) {
+ strcpy(&pathBuf[0], myProp.baseDir);
+ strcat(&pathBuf[0], filename);
+ filename = pathBuf;
+ }
+ Common::File *file = new Common::File();
+ if (!file->open(filename)) {
+ delete file;
+ return NULL;
+ }
+ return file;
+}
+
+void Synth::closeFile(Common::File *file) {
+ if (myProp.closeFile != NULL) {
+ myProp.closeFile(myProp.userData, file);
+ } else {
+ file->close();
+ delete file;
+ }
+}
+
+LoadResult Synth::loadControlROM(const char *filename) {
+ Common::File *file = openFile(filename); // ROM File
+ if (file == NULL) {
+ return LoadResult_NotFound;
+ }
+ size_t fileSize = file->size();
+ if (fileSize != CONTROL_ROM_SIZE) {
+ printDebug("Control ROM file %s size mismatch: %i", filename, fileSize);
+ }
+ file->read(controlROMData, CONTROL_ROM_SIZE);
+ if (file->err()) {
+ closeFile(file);
+ return LoadResult_Unreadable;
+ }
+ closeFile(file);
+
+ // Control ROM successfully loaded, now check whether it's a known type
+ controlROMMap = NULL;
+ for (unsigned int i = 0; i < sizeof(ControlROMMaps) / sizeof(ControlROMMaps[0]); i++) {
+ if (memcmp(&controlROMData[ControlROMMaps[i].idPos], ControlROMMaps[i].idBytes, ControlROMMaps[i].idLen) == 0) {
+ controlROMMap = &ControlROMMaps[i];
+ return LoadResult_OK;
+ }
+ }
+ printDebug("%s does not match a known control ROM type", filename);
+ return LoadResult_Invalid;
+}
+
+LoadResult Synth::loadPCMROM(const char *filename) {
+ Common::File *file = openFile(filename); // ROM File
+ if (file == NULL) {
+ return LoadResult_NotFound;
+ }
+ size_t fileSize = file->size();
+ if (fileSize < (size_t)(2 * pcmROMSize)) {
+ printDebug("PCM ROM file is too short (expected %d, got %d)", 2 * pcmROMSize, fileSize);
+ closeFile(file);
+ return LoadResult_Invalid;
+ }
+ if (file->err()) {
+ closeFile(file);
+ return LoadResult_Unreadable;
+ }
+ LoadResult rc = LoadResult_OK;
+ for (int i = 0; i < pcmROMSize; i++) {
+ Bit8u s = file->readByte();
+ Bit8u c = file->readByte();
+
+ int order[16] = {0, 9, 1, 2, 3, 4, 5, 6, 7, 10, 11, 12, 13, 14, 15, 8};
+
+ signed short log = 0;
+ for (int u = 0; u < 15; u++) {
+ int bit;
+ if (order[u] < 8) {
+ bit = (s >> (7 - order[u])) & 0x1;
+ } else {
+ bit = (c >> (7 - (order[u] - 8))) & 0x1;
+ }
+ log = log | (short)(bit << (15 - u));
+ }
+ bool negative = log < 0;
+ log &= 0x7FFF;
+
+ // CONFIRMED from sample analysis to be 99.99%+ accurate with current TVA multiplier
+ float lin = EXP2F((32787 - log) / -2048.0f);
+
+ if (negative) {
+ lin = -lin;
+ }
+
+ pcmROMData[i] = lin;
+ }
+ closeFile(file);
+ return rc;
+}
+
+bool Synth::initPCMList(Bit16u mapAddress, Bit16u count) {
+ ControlROMPCMStruct *tps = (ControlROMPCMStruct *)&controlROMData[mapAddress];
+ for (int i = 0; i < count; i++) {
+ int rAddr = tps[i].pos * 0x800;
+ int rLenExp = (tps[i].len & 0x70) >> 4;
+ int rLen = 0x800 << rLenExp;
+ if (rAddr + rLen > pcmROMSize) {
+ printDebug("Control ROM error: Wave map entry %d points to invalid PCM address 0x%04X, length 0x%04X", i, rAddr, rLen);
+ return false;
+ }
+ pcmWaves[i].addr = rAddr;
+ pcmWaves[i].len = rLen;
+ pcmWaves[i].loop = (tps[i].len & 0x80) != 0;
+ pcmWaves[i].controlROMPCMStruct = &tps[i];
+ //int pitch = (tps[i].pitchMSB << 8) | tps[i].pitchLSB;
+ //bool unaffectedByMasterTune = (tps[i].len & 0x01) == 0;
+ //printDebug("PCM %d: pos=%d, len=%d, pitch=%d, loop=%s, unaffectedByMasterTune=%s", i, rAddr, rLen, pitch, pcmWaves[i].loop ? "YES" : "NO", unaffectedByMasterTune ? "YES" : "NO");
+ }
+ return false;
+}
+
+bool Synth::initCompressedTimbre(int timbreNum, const Bit8u *src, unsigned int srcLen) {
+ // "Compressed" here means that muted partials aren't present in ROM (except in the case of partial 0 being muted).
+ // Instead the data from the previous unmuted partial is used.
+ if (srcLen < sizeof(TimbreParam::CommonParam)) {
+ return false;
+ }
+ TimbreParam *timbre = &mt32ram.timbres[timbreNum].timbre;
+ timbresMemoryRegion->write(timbreNum, 0, src, sizeof(TimbreParam::CommonParam), true);
+ unsigned int srcPos = sizeof(TimbreParam::CommonParam);
+ unsigned int memPos = sizeof(TimbreParam::CommonParam);
+ for (int t = 0; t < 4; t++) {
+ if (t != 0 && ((timbre->common.partialMute >> t) & 0x1) == 0x00) {
+ // This partial is muted - we'll copy the previously copied partial, then
+ srcPos -= sizeof(TimbreParam::PartialParam);
+ } else if (srcPos + sizeof(TimbreParam::PartialParam) >= srcLen) {
+ return false;
+ }
+ timbresMemoryRegion->write(timbreNum, memPos, src + srcPos, sizeof(TimbreParam::PartialParam));
+ srcPos += sizeof(TimbreParam::PartialParam);
+ memPos += sizeof(TimbreParam::PartialParam);
+ }
+ return true;
+}
+
+bool Synth::initTimbres(Bit16u mapAddress, Bit16u offset, int count, int startTimbre, bool compressed) {
+ const Bit8u *timbreMap = &controlROMData[mapAddress];
+ for (Bit16u i = 0; i < count * 2; i += 2) {
+ Bit16u address = (timbreMap[i + 1] << 8) | timbreMap[i];
+ if (!compressed && (address + offset + sizeof(TimbreParam) > CONTROL_ROM_SIZE)) {
+ printDebug("Control ROM error: Timbre map entry 0x%04x for timbre %d points to invalid timbre address 0x%04x", i, startTimbre, address);
+ return false;
+ }
+ address += offset;
+ if (compressed) {
+ if (!initCompressedTimbre(startTimbre, &controlROMData[address], CONTROL_ROM_SIZE - address)) {
+ printDebug("Control ROM error: Timbre map entry 0x%04x for timbre %d points to invalid timbre at 0x%04x", i, startTimbre, address);
+ return false;
+ }
+ } else {
+ timbresMemoryRegion->write(startTimbre, 0, &controlROMData[address], sizeof(TimbreParam), true);
+ }
+ startTimbre++;
+ }
+ return true;
+}
+
+bool Synth::open(SynthProperties &useProp) {
+ if (isOpen) {
+ return false;
+ }
+ prerenderReadIx = prerenderWriteIx = 0;
+ myProp = useProp;
+#if MT32EMU_MONITOR_INIT
+ printDebug("Initialising Constant Tables");
+#endif
+ tables.init();
+#if !MT32EMU_REDUCE_REVERB_MEMORY
+ for (int i = 0; i < 4; i++) {
+ reverbModels[i]->open(useProp.sampleRate);
+ }
+#endif
+ if (useProp.baseDir != NULL) {
+ char *baseDirCopy = new char[strlen(useProp.baseDir) + 1];
+ strcpy(baseDirCopy, useProp.baseDir);
+ myProp.baseDir = baseDirCopy;
+ }
+
+ // This is to help detect bugs
+ memset(&mt32ram, '?', sizeof(mt32ram));
+
+#if MT32EMU_MONITOR_INIT
+ printDebug("Loading Control ROM");
+#endif
+ if (loadControlROM("CM32L_CONTROL.ROM") != LoadResult_OK) {
+ if (loadControlROM("MT32_CONTROL.ROM") != LoadResult_OK) {
+ printDebug("Init Error - Missing or invalid MT32_CONTROL.ROM");
+ //report(ReportType_errorControlROM, &errno);
+ return false;
+ }
+ }
+
+ initMemoryRegions();
+
+ // 512KB PCM ROM for MT-32, etc.
+ // 1MB PCM ROM for CM-32L, LAPC-I, CM-64, CM-500
+ // Note that the size below is given in samples (16-bit), not bytes
+ pcmROMSize = controlROMMap->pcmCount == 256 ? 512 * 1024 : 256 * 1024;
+ pcmROMData = new float[pcmROMSize];
+
+#if MT32EMU_MONITOR_INIT
+ printDebug("Loading PCM ROM");
+#endif
+ if (loadPCMROM("CM32L_PCM.ROM") != LoadResult_OK) {
+ if (loadPCMROM("MT32_PCM.ROM") != LoadResult_OK) {
+ printDebug("Init Error - Missing MT32_PCM.ROM");
+ //report(ReportType_errorPCMROM, &errno);
+ return false;
+ }
+ }
+
+#if MT32EMU_MONITOR_INIT
+ printDebug("Initialising Timbre Bank A");
+#endif
+ if (!initTimbres(controlROMMap->timbreAMap, controlROMMap->timbreAOffset, 0x40, 0, controlROMMap->timbreACompressed)) {
+ return false;
+ }
+
+#if MT32EMU_MONITOR_INIT
+ printDebug("Initialising Timbre Bank B");
+#endif
+ if (!initTimbres(controlROMMap->timbreBMap, controlROMMap->timbreBOffset, 0x40, 64, controlROMMap->timbreBCompressed)) {
+ return false;
+ }
+
+#if MT32EMU_MONITOR_INIT
+ printDebug("Initialising Timbre Bank R");
+#endif
+ if (!initTimbres(controlROMMap->timbreRMap, 0, controlROMMap->timbreRCount, 192, true)) {
+ return false;
+ }
+
+#if MT32EMU_MONITOR_INIT
+ printDebug("Initialising Timbre Bank M");
+#endif
+ // CM-64 seems to initialise all bytes in this bank to 0.
+ memset(&mt32ram.timbres[128], 0, sizeof(mt32ram.timbres[128]) * 64);
+
+ partialManager = new PartialManager(this, parts);
+
+ pcmWaves = new PCMWaveEntry[controlROMMap->pcmCount];
+
+#if MT32EMU_MONITOR_INIT
+ printDebug("Initialising PCM List");
+#endif
+ initPCMList(controlROMMap->pcmTable, controlROMMap->pcmCount);
+
+#if MT32EMU_MONITOR_INIT
+ printDebug("Initialising Rhythm Temp");
+#endif
+ memcpy(mt32ram.rhythmTemp, &controlROMData[controlROMMap->rhythmSettings], controlROMMap->rhythmSettingsCount * 4);
+
+#if MT32EMU_MONITOR_INIT
+ printDebug("Initialising Patches");
+#endif
+ for (Bit8u i = 0; i < 128; i++) {
+ PatchParam *patch = &mt32ram.patches[i];
+ patch->timbreGroup = i / 64;
+ patch->timbreNum = i % 64;
+ patch->keyShift = 24;
+ patch->fineTune = 50;
+ patch->benderRange = 12;
+ patch->assignMode = 0;
+ patch->reverbSwitch = 1;
+ patch->dummy = 0;
+ }
+
+#if MT32EMU_MONITOR_INIT
+ printDebug("Initialising System");
+#endif
+ // The MT-32 manual claims that "Standard pitch" is 442Hz.
+ mt32ram.system.masterTune = 0x4A; // Confirmed on CM-64
+ mt32ram.system.reverbMode = 0; // Confirmed
+ mt32ram.system.reverbTime = 5; // Confirmed
+ mt32ram.system.reverbLevel = 3; // Confirmed
+ memcpy(mt32ram.system.reserveSettings, &controlROMData[controlROMMap->reserveSettings], 9); // Confirmed
+ for (Bit8u i = 0; i < 9; i++) {
+ // This is the default: {1, 2, 3, 4, 5, 6, 7, 8, 9}
+ // An alternative configuration can be selected by holding "Master Volume"
+ // and pressing "PART button 1" on the real MT-32's frontpanel.
+ // The channel assignment is then {0, 1, 2, 3, 4, 5, 6, 7, 9}
+ mt32ram.system.chanAssign[i] = i + 1;
+ }
+ mt32ram.system.masterVol = 100; // Confirmed
+ refreshSystem();
+
+ for (int i = 0; i < 9; i++) {
+ MemParams::PatchTemp *patchTemp = &mt32ram.patchTemp[i];
+
+ // Note that except for the rhythm part, these patch fields will be set in setProgram() below anyway.
+ patchTemp->patch.timbreGroup = 0;
+ patchTemp->patch.timbreNum = 0;
+ patchTemp->patch.keyShift = 24;
+ patchTemp->patch.fineTune = 50;
+ patchTemp->patch.benderRange = 12;
+ patchTemp->patch.assignMode = 0;
+ patchTemp->patch.reverbSwitch = 1;
+ patchTemp->patch.dummy = 0;
+
+ patchTemp->outputLevel = 80;
+ patchTemp->panpot = controlROMData[controlROMMap->panSettings + i];
+ memset(patchTemp->dummyv, 0, sizeof(patchTemp->dummyv));
+ patchTemp->dummyv[1] = 127;
+
+ if (i < 8) {
+ parts[i] = new Part(this, i);
+ parts[i]->setProgram(controlROMData[controlROMMap->programSettings + i]);
+ } else {
+ parts[i] = new RhythmPart(this, i);
+ }
+ }
+
+ // For resetting mt32 mid-execution
+ mt32default = mt32ram;
+
+ isOpen = true;
+ isEnabled = false;
+
+#if MT32EMU_MONITOR_INIT
+ printDebug("*** Initialisation complete ***");
+#endif
+ return true;
+}
+
+void Synth::close() {
+ if (!isOpen) {
+ return;
+ }
+
+ delete partialManager;
+ partialManager = NULL;
+
+ for (int i = 0; i < 9; i++) {
+ delete parts[i];
+ parts[i] = NULL;
+ }
+
+ delete[] myProp.baseDir;
+ myProp.baseDir = NULL;
+
+ delete[] pcmWaves;
+ delete[] pcmROMData;
+
+ deleteMemoryRegions();
+
+ for (int i = 0; i < 4; i++) {
+ reverbModels[i]->close();
+ }
+ reverbModel = NULL;
+ isOpen = false;
+}
+
+void Synth::playMsg(Bit32u msg) {
+ // FIXME: Implement active sensing
+ unsigned char code = (unsigned char)((msg & 0x0000F0) >> 4);
+ unsigned char chan = (unsigned char)(msg & 0x00000F);
+ unsigned char note = (unsigned char)((msg & 0x00FF00) >> 8);
+ unsigned char velocity = (unsigned char)((msg & 0xFF0000) >> 16);
+ isEnabled = true;
+
+ //printDebug("Playing chan %d, code 0x%01x note: 0x%02x", chan, code, note);
+
+ char part = chantable[chan];
+ if (part < 0 || part > 8) {
+#if MT32EMU_MONITOR_MIDI > 0
+ printDebug("Play msg on unreg chan %d (%d): code=0x%01x, vel=%d", chan, part, code, velocity);
+#endif
+ return;
+ }
+ playMsgOnPart(part, code, note, velocity);
+}
+
+void Synth::playMsgOnPart(unsigned char part, unsigned char code, unsigned char note, unsigned char velocity) {
+ Bit32u bend;
+
+ //printDebug("Synth::playMsgOnPart(%02x, %02x, %02x, %02x)", part, code, note, velocity);
+ switch (code) {
+ case 0x8:
+ //printDebug("Note OFF - Part %d", part);
+ // The MT-32 ignores velocity for note off
+ parts[part]->noteOff(note);
+ break;
+ case 0x9:
+ //printDebug("Note ON - Part %d, Note %d Vel %d", part, note, velocity);
+ if (velocity == 0) {
+ // MIDI defines note-on with velocity 0 as being the same as note-off with velocity 40
+ parts[part]->noteOff(note);
+ } else {
+ parts[part]->noteOn(note, velocity);
+ }
+ break;
+ case 0xB: // Control change
+ switch (note) {
+ case 0x01: // Modulation
+ //printDebug("Modulation: %d", velocity);
+ parts[part]->setModulation(velocity);
+ break;
+ case 0x06:
+ parts[part]->setDataEntryMSB(velocity);
+ break;
+ case 0x07: // Set volume
+ //printDebug("Volume set: %d", velocity);
+ parts[part]->setVolume(velocity);
+ break;
+ case 0x0A: // Pan
+ //printDebug("Pan set: %d", velocity);
+ parts[part]->setPan(velocity);
+ break;
+ case 0x0B:
+ //printDebug("Expression set: %d", velocity);
+ parts[part]->setExpression(velocity);
+ break;
+ case 0x40: // Hold (sustain) pedal
+ //printDebug("Hold pedal set: %d", velocity);
+ parts[part]->setHoldPedal(velocity >= 64);
+ break;
+
+ case 0x62:
+ case 0x63:
+ parts[part]->setNRPN();
+ break;
+ case 0x64:
+ parts[part]->setRPNLSB(velocity);
+ break;
+ case 0x65:
+ parts[part]->setRPNMSB(velocity);
+ break;
+
+ case 0x79: // Reset all controllers
+ //printDebug("Reset all controllers");
+ parts[part]->resetAllControllers();
+ break;
+
+ case 0x7B: // All notes off
+ //printDebug("All notes off");
+ parts[part]->allNotesOff();
+ break;
+
+ case 0x7C:
+ case 0x7D:
+ case 0x7E:
+ case 0x7F:
+ // CONFIRMED:Mok: A real LAPC-I responds to these controllers as follows:
+ parts[part]->setHoldPedal(false);
+ parts[part]->allNotesOff();
+ break;
+
+ default:
+#if MT32EMU_MONITOR_MIDI > 0
+ printDebug("Unknown MIDI Control code: 0x%02x - vel 0x%02x", note, velocity);
+#endif
+ break;
+ }
+
+ break;
+ case 0xC: // Program change
+ //printDebug("Program change %01x", note);
+ parts[part]->setProgram(note);
+ break;
+ case 0xE: // Pitch bender
+ bend = (velocity << 7) | (note);
+ //printDebug("Pitch bender %02x", bend);
+ parts[part]->setBend(bend);
+ break;
+ default:
+#if MT32EMU_MONITOR_MIDI > 0
+ printDebug("Unknown Midi code: 0x%01x - %02x - %02x", code, note, velocity);
+#endif
+ break;
+ }
+
+ //midiOutShortMsg(m_out, msg);
+}
+
+void Synth::playSysex(const Bit8u *sysex, Bit32u len) {
+ if (len < 2) {
+ printDebug("playSysex: Message is too short for sysex (%d bytes)", len);
+ }
+ if (sysex[0] != 0xF0) {
+ printDebug("playSysex: Message lacks start-of-sysex (0xF0)");
+ return;
+ }
+ // Due to some programs (e.g. Java) sending buffers with junk at the end, we have to go through and find the end marker rather than relying on len.
+ Bit32u endPos;
+ for (endPos = 1; endPos < len; endPos++) {
+ if (sysex[endPos] == 0xF7) {
+ break;
+ }
+ }
+ if (endPos == len) {
+ printDebug("playSysex: Message lacks end-of-sysex (0xf7)");
+ return;
+ }
+ playSysexWithoutFraming(sysex + 1, endPos - 1);
+}
+
+void Synth::playSysexWithoutFraming(const Bit8u *sysex, Bit32u len) {
+ if (len < 4) {
+ printDebug("playSysexWithoutFraming: Message is too short (%d bytes)!", len);
+ return;
+ }
+ if (sysex[0] != SYSEX_MANUFACTURER_ROLAND) {
+ printDebug("playSysexWithoutFraming: Header not intended for this device manufacturer: %02x %02x %02x %02x", (int)sysex[0], (int)sysex[1], (int)sysex[2], (int)sysex[3]);
+ return;
+ }
+ if (sysex[2] == SYSEX_MDL_D50) {
+ printDebug("playSysexWithoutFraming: Header is intended for model D-50 (not yet supported): %02x %02x %02x %02x", (int)sysex[0], (int)sysex[1], (int)sysex[2], (int)sysex[3]);
+ return;
+ } else if (sysex[2] != SYSEX_MDL_MT32) {
+ printDebug("playSysexWithoutFraming: Header not intended for model MT-32: %02x %02x %02x %02x", (int)sysex[0], (int)sysex[1], (int)sysex[2], (int)sysex[3]);
+ return;
+ }
+ playSysexWithoutHeader(sysex[1], sysex[3], sysex + 4, len - 4);
+}
+
+void Synth::playSysexWithoutHeader(unsigned char device, unsigned char command, const Bit8u *sysex, Bit32u len) {
+ if (device > 0x10) {
+ // We have device ID 0x10 (default, but changeable, on real MT-32), < 0x10 is for channels
+ printDebug("playSysexWithoutHeader: Message is not intended for this device ID (provided: %02x, expected: 0x10 or channel)", (int)device);
+ return;
+ }
+ // This is checked early in the real devices (before any sysex length checks or further processing)
+ // FIXME: Response to SYSEX_CMD_DAT reset with partials active (and in general) is untested.
+ if ((command == SYSEX_CMD_DT1 || command == SYSEX_CMD_DAT) && sysex[0] == 0x7F) {
+ reset();
+ return;
+ }
+ if (len < 4) {
+ printDebug("playSysexWithoutHeader: Message is too short (%d bytes)!", len);
+ return;
+ }
+ unsigned char checksum = calcSysexChecksum(sysex, len - 1, 0);
+ if (checksum != sysex[len - 1]) {
+ printDebug("playSysexWithoutHeader: Message checksum is incorrect (provided: %02x, expected: %02x)!", sysex[len - 1], checksum);
+ return;
+ }
+ len -= 1; // Exclude checksum
+ switch (command) {
+ case SYSEX_CMD_DAT:
+ if (hasActivePartials()) {
+ printDebug("playSysexWithoutHeader: Got SYSEX_CMD_DAT but partials are active - ignoring");
+ // FIXME: We should send SYSEX_CMD_RJC in this case
+ break;
+ }
+ // Deliberate fall-through
+ case SYSEX_CMD_DT1:
+ writeSysex(device, sysex, len);
+ break;
+ case SYSEX_CMD_RQD:
+ if (hasActivePartials()) {
+ printDebug("playSysexWithoutHeader: Got SYSEX_CMD_RQD but partials are active - ignoring");
+ // FIXME: We should send SYSEX_CMD_RJC in this case
+ break;
+ }
+ // Deliberate fall-through
+ case SYSEX_CMD_RQ1:
+ readSysex(device, sysex, len);
+ break;
+ default:
+ printDebug("playSysexWithoutHeader: Unsupported command %02x", command);
+ return;
+ }
+}
+
+void Synth::readSysex(unsigned char /*device*/, const Bit8u * /*sysex*/, Bit32u /*len*/) const {
+ // NYI
+}
+
+void Synth::writeSysex(unsigned char device, const Bit8u *sysex, Bit32u len) {
+ Bit32u addr = (sysex[0] << 16) | (sysex[1] << 8) | (sysex[2]);
+ addr = MT32EMU_MEMADDR(addr);
+ sysex += 3;
+ len -= 3;
+ //printDebug("Sysex addr: 0x%06x", MT32EMU_SYSEXMEMADDR(addr));
+ // NOTE: Please keep both lower and upper bounds in each check, for ease of reading
+
+ // Process channel-specific sysex by converting it to device-global
+ if (device < 0x10) {
+#if MT32EMU_MONITOR_SYSEX > 0
+ printDebug("WRITE-CHANNEL: Channel %d temp area 0x%06x", device, MT32EMU_SYSEXMEMADDR(addr));
+#endif
+ if (/*addr >= MT32EMU_MEMADDR(0x000000) && */addr < MT32EMU_MEMADDR(0x010000)) {
+ int offset;
+ if (chantable[device] == -1) {
+#if MT32EMU_MONITOR_SYSEX > 0
+ printDebug(" (Channel not mapped to a part... 0 offset)");
+#endif
+ offset = 0;
+ } else if (chantable[device] == 8) {
+#if MT32EMU_MONITOR_SYSEX > 0
+ printDebug(" (Channel mapped to rhythm... 0 offset)");
+#endif
+ offset = 0;
+ } else {
+ offset = chantable[device] * sizeof(MemParams::PatchTemp);
+#if MT32EMU_MONITOR_SYSEX > 0
+ printDebug(" (Setting extra offset to %d)", offset);
+#endif
+ }
+ addr += MT32EMU_MEMADDR(0x030000) + offset;
+ } else if (/*addr >= MT32EMU_MEMADDR(0x010000) && */ addr < MT32EMU_MEMADDR(0x020000)) {
+ addr += MT32EMU_MEMADDR(0x030110) - MT32EMU_MEMADDR(0x010000);
+ } else if (/*addr >= MT32EMU_MEMADDR(0x020000) && */ addr < MT32EMU_MEMADDR(0x030000)) {
+ int offset;
+ if (chantable[device] == -1) {
+#if MT32EMU_MONITOR_SYSEX > 0
+ printDebug(" (Channel not mapped to a part... 0 offset)");
+#endif
+ offset = 0;
+ } else if (chantable[device] == 8) {
+#if MT32EMU_MONITOR_SYSEX > 0
+ printDebug(" (Channel mapped to rhythm... 0 offset)");
+#endif
+ offset = 0;
+ } else {
+ offset = chantable[device] * sizeof(TimbreParam);
+#if MT32EMU_MONITOR_SYSEX > 0
+ printDebug(" (Setting extra offset to %d)", offset);
+#endif
+ }
+ addr += MT32EMU_MEMADDR(0x040000) - MT32EMU_MEMADDR(0x020000) + offset;
+ } else {
+#if MT32EMU_MONITOR_SYSEX > 0
+ printDebug(" Invalid channel");
+#endif
+ return;
+ }
+ }
+
+ // Process device-global sysex (possibly converted from channel-specific sysex above)
+ for (;;) {
+ // Find the appropriate memory region
+ const MemoryRegion *region = findMemoryRegion(addr);
+
+ if (region == NULL) {
+ printDebug("Sysex write to unrecognised address %06x, len %d", MT32EMU_SYSEXMEMADDR(addr), len);
+ break;
+ }
+ writeMemoryRegion(region, addr, region->getClampedLen(addr, len), sysex);
+
+ Bit32u next = region->next(addr, len);
+ if (next == 0) {
+ break;
+ }
+ addr += next;
+ sysex += next;
+ len -= next;
+ }
+}
+
+void Synth::readMemory(Bit32u addr, Bit32u len, Bit8u *data) {
+ const MemoryRegion *region = findMemoryRegion(addr);
+ if (region != NULL) {
+ readMemoryRegion(region, addr, len, data);
+ }
+}
+
+void Synth::initMemoryRegions() {
+ // Timbre max tables are slightly more complicated than the others, which are used directly from the ROM.
+ // The ROM (sensibly) just has maximums for TimbreParam.commonParam followed by just one TimbreParam.partialParam,
+ // so we produce a table with all partialParams filled out, as well as padding for PaddedTimbre, for quick lookup.
+ paddedTimbreMaxTable = new Bit8u[sizeof(MemParams::PaddedTimbre)];
+ memcpy(&paddedTimbreMaxTable[0], &controlROMData[controlROMMap->timbreMaxTable], sizeof(TimbreParam::CommonParam) + sizeof(TimbreParam::PartialParam)); // commonParam and one partialParam
+ int pos = sizeof(TimbreParam::CommonParam) + sizeof(TimbreParam::PartialParam);
+ for (int i = 0; i < 3; i++) {
+ memcpy(&paddedTimbreMaxTable[pos], &controlROMData[controlROMMap->timbreMaxTable + sizeof(TimbreParam::CommonParam)], sizeof(TimbreParam::PartialParam));
+ pos += sizeof(TimbreParam::PartialParam);
+ }
+ memset(&paddedTimbreMaxTable[pos], 0, 10); // Padding
+ patchTempMemoryRegion = new PatchTempMemoryRegion(this, (Bit8u *)&mt32ram.patchTemp[0], &controlROMData[controlROMMap->patchMaxTable]);
+ rhythmTempMemoryRegion = new RhythmTempMemoryRegion(this, (Bit8u *)&mt32ram.rhythmTemp[0], &controlROMData[controlROMMap->rhythmMaxTable]);
+ timbreTempMemoryRegion = new TimbreTempMemoryRegion(this, (Bit8u *)&mt32ram.timbreTemp[0], paddedTimbreMaxTable);
+ patchesMemoryRegion = new PatchesMemoryRegion(this, (Bit8u *)&mt32ram.patches[0], &controlROMData[controlROMMap->patchMaxTable]);
+ timbresMemoryRegion = new TimbresMemoryRegion(this, (Bit8u *)&mt32ram.timbres[0], paddedTimbreMaxTable);
+ systemMemoryRegion = new SystemMemoryRegion(this, (Bit8u *)&mt32ram.system, &controlROMData[controlROMMap->systemMaxTable]);
+ displayMemoryRegion = new DisplayMemoryRegion(this);
+ resetMemoryRegion = new ResetMemoryRegion(this);
+}
+
+void Synth::deleteMemoryRegions() {
+ delete patchTempMemoryRegion;
+ patchTempMemoryRegion = NULL;
+ delete rhythmTempMemoryRegion;
+ rhythmTempMemoryRegion = NULL;
+ delete timbreTempMemoryRegion;
+ timbreTempMemoryRegion = NULL;
+ delete patchesMemoryRegion;
+ patchesMemoryRegion = NULL;
+ delete timbresMemoryRegion;
+ timbresMemoryRegion = NULL;
+ delete systemMemoryRegion;
+ systemMemoryRegion = NULL;
+ delete displayMemoryRegion;
+ displayMemoryRegion = NULL;
+ delete resetMemoryRegion;
+ resetMemoryRegion = NULL;
+
+ delete[] paddedTimbreMaxTable;
+ paddedTimbreMaxTable = NULL;
+}
+
+MemoryRegion *Synth::findMemoryRegion(Bit32u addr) {
+ MemoryRegion *regions[] = {
+ patchTempMemoryRegion,
+ rhythmTempMemoryRegion,
+ timbreTempMemoryRegion,
+ patchesMemoryRegion,
+ timbresMemoryRegion,
+ systemMemoryRegion,
+ displayMemoryRegion,
+ resetMemoryRegion,
+ NULL
+ };
+ for (int pos = 0; regions[pos] != NULL; pos++) {
+ if (regions[pos]->contains(addr)) {
+ return regions[pos];
+ }
+ }
+ return NULL;
+}
+
+void Synth::readMemoryRegion(const MemoryRegion *region, Bit32u addr, Bit32u len, Bit8u *data) {
+ unsigned int first = region->firstTouched(addr);
+ //unsigned int last = region->lastTouched(addr, len);
+ unsigned int off = region->firstTouchedOffset(addr);
+ len = region->getClampedLen(addr, len);
+
+ unsigned int m;
+
+ if (region->isReadable()) {
+ region->read(first, off, data, len);
+ } else {
+ // FIXME: We might want to do these properly in future
+ for (m = 0; m < len; m += 2) {
+ data[m] = 0xff;
+ if (m + 1 < len) {
+ data[m+1] = (Bit8u)region->type;
+ }
+ }
+ }
+}
+
+void Synth::writeMemoryRegion(const MemoryRegion *region, Bit32u addr, Bit32u len, const Bit8u *data) {
+ unsigned int first = region->firstTouched(addr);
+ unsigned int last = region->lastTouched(addr, len);
+ unsigned int off = region->firstTouchedOffset(addr);
+ switch (region->type) {
+ case MR_PatchTemp:
+ region->write(first, off, data, len);
+ //printDebug("Patch temp: Patch %d, offset %x, len %d", off/16, off % 16, len);
+
+ for (unsigned int i = first; i <= last; i++) {
+ int absTimbreNum = mt32ram.patchTemp[i].patch.timbreGroup * 64 + mt32ram.patchTemp[i].patch.timbreNum;
+ char timbreName[11];
+ memcpy(timbreName, mt32ram.timbres[absTimbreNum].timbre.common.name, 10);
+ timbreName[10] = 0;
+#if MT32EMU_MONITOR_SYSEX > 0
+ printDebug("WRITE-PARTPATCH (%d-%d@%d..%d): %d; timbre=%d (%s), outlevel=%d", first, last, off, off + len, i, absTimbreNum, timbreName, mt32ram.patchTemp[i].outputLevel);
+#endif
+ if (parts[i] != NULL) {
+ if (i != 8) {
+ // Note: Confirmed on CM-64 that we definitely *should* update the timbre here,
+ // but only in the case that the sysex actually writes to those values
+ if (i == first && off > 2) {
+#if MT32EMU_MONITOR_SYSEX > 0
+ printDebug(" (Not updating timbre, since those values weren't touched)");
+#endif
+ } else {
+ parts[i]->setTimbre(&mt32ram.timbres[parts[i]->getAbsTimbreNum()].timbre);
+ }
+ }
+ parts[i]->refresh();
+ }
+ }
+ break;
+ case MR_RhythmTemp:
+ region->write(first, off, data, len);
+ for (unsigned int i = first; i <= last; i++) {
+ int timbreNum = mt32ram.rhythmTemp[i].timbre;
+ char timbreName[11];
+ if (timbreNum < 94) {
+ memcpy(timbreName, mt32ram.timbres[128 + timbreNum].timbre.common.name, 10);
+ timbreName[10] = 0;
+ } else {
+ strcpy(timbreName, "[None]");
+ }
+#if MT32EMU_MONITOR_SYSEX > 0
+ printDebug("WRITE-RHYTHM (%d-%d@%d..%d): %d; level=%02x, panpot=%02x, reverb=%02x, timbre=%d (%s)", first, last, off, off + len, i, mt32ram.rhythmTemp[i].outputLevel, mt32ram.rhythmTemp[i].panpot, mt32ram.rhythmTemp[i].reverbSwitch, mt32ram.rhythmTemp[i].timbre, timbreName);
+#endif
+ }
+ if (parts[8] != NULL) {
+ parts[8]->refresh();
+ }
+ break;
+ case MR_TimbreTemp:
+ region->write(first, off, data, len);
+ for (unsigned int i = first; i <= last; i++) {
+ char instrumentName[11];
+ memcpy(instrumentName, mt32ram.timbreTemp[i].common.name, 10);
+ instrumentName[10] = 0;
+#if MT32EMU_MONITOR_SYSEX > 0
+ printDebug("WRITE-PARTTIMBRE (%d-%d@%d..%d): timbre=%d (%s)", first, last, off, off + len, i, instrumentName);
+#endif
+ if (parts[i] != NULL) {
+ parts[i]->refresh();
+ }
+ }
+ break;
+ case MR_Patches:
+ region->write(first, off, data, len);
+#if MT32EMU_MONITOR_SYSEX > 0
+ for (unsigned int i = first; i <= last; i++) {
+ PatchParam *patch = &mt32ram.patches[i];
+ int patchAbsTimbreNum = patch->timbreGroup * 64 + patch->timbreNum;
+ char instrumentName[11];
+ memcpy(instrumentName, mt32ram.timbres[patchAbsTimbreNum].timbre.common.name, 10);
+ instrumentName[10] = 0;
+ Bit8u *n = (Bit8u *)patch;
+ printDebug("WRITE-PATCH (%d-%d@%d..%d): %d; timbre=%d (%s) %02X%02X%02X%02X%02X%02X%02X%02X", first, last, off, off + len, i, patchAbsTimbreNum, instrumentName, n[0], n[1], n[2], n[3], n[4], n[5], n[6], n[7]);
+ }
+#endif
+ break;
+ case MR_Timbres:
+ // Timbres
+ first += 128;
+ last += 128;
+ region->write(first, off, data, len);
+ for (unsigned int i = first; i <= last; i++) {
+#if MT32EMU_MONITOR_TIMBRES >= 1
+ TimbreParam *timbre = &mt32ram.timbres[i].timbre;
+ char instrumentName[11];
+ memcpy(instrumentName, timbre->common.name, 10);
+ instrumentName[10] = 0;
+ printDebug("WRITE-TIMBRE (%d-%d@%d..%d): %d; name=\"%s\"", first, last, off, off + len, i, instrumentName);
+#if MT32EMU_MONITOR_TIMBRES >= 2
+#define DT(x) printDebug(" " #x ": %d", timbre->x)
+ DT(common.partialStructure12);
+ DT(common.partialStructure34);
+ DT(common.partialMute);
+ DT(common.noSustain);
+
+#define DTP(x) \
+ DT(partial[x].wg.pitchCoarse); \
+ DT(partial[x].wg.pitchFine); \
+ DT(partial[x].wg.pitchKeyfollow); \
+ DT(partial[x].wg.pitchBenderEnabled); \
+ DT(partial[x].wg.waveform); \
+ DT(partial[x].wg.pcmWave); \
+ DT(partial[x].wg.pulseWidth); \
+ DT(partial[x].wg.pulseWidthVeloSensitivity); \
+ DT(partial[x].pitchEnv.depth); \
+ DT(partial[x].pitchEnv.veloSensitivity); \
+ DT(partial[x].pitchEnv.timeKeyfollow); \
+ DT(partial[x].pitchEnv.time[0]); \
+ DT(partial[x].pitchEnv.time[1]); \
+ DT(partial[x].pitchEnv.time[2]); \
+ DT(partial[x].pitchEnv.time[3]); \
+ DT(partial[x].pitchEnv.level[0]); \
+ DT(partial[x].pitchEnv.level[1]); \
+ DT(partial[x].pitchEnv.level[2]); \
+ DT(partial[x].pitchEnv.level[3]); \
+ DT(partial[x].pitchEnv.level[4]); \
+ DT(partial[x].pitchLFO.rate); \
+ DT(partial[x].pitchLFO.depth); \
+ DT(partial[x].pitchLFO.modSensitivity); \
+ DT(partial[x].tvf.cutoff); \
+ DT(partial[x].tvf.resonance); \
+ DT(partial[x].tvf.keyfollow); \
+ DT(partial[x].tvf.biasPoint); \
+ DT(partial[x].tvf.biasLevel); \
+ DT(partial[x].tvf.envDepth); \
+ DT(partial[x].tvf.envVeloSensitivity); \
+ DT(partial[x].tvf.envDepthKeyfollow); \
+ DT(partial[x].tvf.envTimeKeyfollow); \
+ DT(partial[x].tvf.envTime[0]); \
+ DT(partial[x].tvf.envTime[1]); \
+ DT(partial[x].tvf.envTime[2]); \
+ DT(partial[x].tvf.envTime[3]); \
+ DT(partial[x].tvf.envTime[4]); \
+ DT(partial[x].tvf.envLevel[0]); \
+ DT(partial[x].tvf.envLevel[1]); \
+ DT(partial[x].tvf.envLevel[2]); \
+ DT(partial[x].tvf.envLevel[3]); \
+ DT(partial[x].tva.level); \
+ DT(partial[x].tva.veloSensitivity); \
+ DT(partial[x].tva.biasPoint1); \
+ DT(partial[x].tva.biasLevel1); \
+ DT(partial[x].tva.biasPoint2); \
+ DT(partial[x].tva.biasLevel2); \
+ DT(partial[x].tva.envTimeKeyfollow); \
+ DT(partial[x].tva.envTimeVeloSensitivity); \
+ DT(partial[x].tva.envTime[0]); \
+ DT(partial[x].tva.envTime[1]); \
+ DT(partial[x].tva.envTime[2]); \
+ DT(partial[x].tva.envTime[3]); \
+ DT(partial[x].tva.envTime[4]); \
+ DT(partial[x].tva.envLevel[0]); \
+ DT(partial[x].tva.envLevel[1]); \
+ DT(partial[x].tva.envLevel[2]); \
+ DT(partial[x].tva.envLevel[3]);
+
+ DTP(0);
+ DTP(1);
+ DTP(2);
+ DTP(3);
+#undef DTP
+#undef DT
+#endif
+#endif
+ // FIXME:KG: Not sure if the stuff below should be done (for rhythm and/or parts)...
+ // Does the real MT-32 automatically do this?
+ for (unsigned int part = 0; part < 9; part++) {
+ if (parts[part] != NULL) {
+ parts[part]->refreshTimbre(i);
+ }
+ }
+ }
+ break;
+ case MR_System:
+ region->write(0, off, data, len);
+
+ report(ReportType_devReconfig, NULL);
+ // FIXME: We haven't properly confirmed any of this behaviour
+ // In particular, we tend to reset things such as reverb even if the write contained
+ // the same parameters as were already set, which may be wrong.
+ // On the other hand, the real thing could be resetting things even when they aren't touched
+ // by the write at all.
+#if MT32EMU_MONITOR_SYSEX > 0
+ printDebug("WRITE-SYSTEM:");
+#endif
+ if (off <= SYSTEM_MASTER_TUNE_OFF && off + len > SYSTEM_MASTER_TUNE_OFF) {
+ refreshSystemMasterTune();
+ }
+ if (off <= SYSTEM_REVERB_LEVEL_OFF && off + len > SYSTEM_REVERB_MODE_OFF) {
+ refreshSystemReverbParameters();
+ }
+ if (off <= SYSTEM_RESERVE_SETTINGS_END_OFF && off + len > SYSTEM_RESERVE_SETTINGS_START_OFF) {
+ refreshSystemReserveSettings();
+ }
+ if (off <= SYSTEM_CHAN_ASSIGN_END_OFF && off + len > SYSTEM_CHAN_ASSIGN_START_OFF) {
+ int firstPart = off - SYSTEM_CHAN_ASSIGN_START_OFF;
+ if(firstPart < 0)
+ firstPart = 0;
+ int lastPart = off + len - SYSTEM_CHAN_ASSIGN_START_OFF;
+ if(lastPart > 9)
+ lastPart = 9;
+ refreshSystemChanAssign(firstPart, lastPart);
+ }
+ if (off <= SYSTEM_MASTER_VOL_OFF && off + len > SYSTEM_MASTER_VOL_OFF) {
+ refreshSystemMasterVol();
+ }
+ break;
+ case MR_Display:
+ char buf[MAX_SYSEX_SIZE];
+ memcpy(&buf, &data[0], len);
+ buf[len] = 0;
+#if MT32EMU_MONITOR_SYSEX > 0
+ printDebug("WRITE-LCD: %s", buf);
+#endif
+ report(ReportType_lcdMessage, buf);
+ break;
+ case MR_Reset:
+ reset();
+ break;
+ }
+}
+
+void Synth::refreshSystemMasterTune() {
+#if MT32EMU_MONITOR_SYSEX > 0
+ //FIXME:KG: This is just an educated guess.
+ // The LAPC-I documentation claims a range of 427.5Hz-452.6Hz (similar to what we have here)
+ // The MT-32 documentation claims a range of 432.1Hz-457.6Hz
+ float masterTune = 440.0f * EXP2F((mt32ram.system.masterTune - 64.0f) / (128.0f * 12.0f));
+ printDebug(" Master Tune: %f", masterTune);
+#endif
+}
+
+void Synth::refreshSystemReverbParameters() {
+#if MT32EMU_MONITOR_SYSEX > 0
+ printDebug(" Reverb: mode=%d, time=%d, level=%d", mt32ram.system.reverbMode, mt32ram.system.reverbTime, mt32ram.system.reverbLevel);
+#endif
+ if (reverbOverridden && reverbModel != NULL) {
+#if MT32EMU_MONITOR_SYSEX > 0
+ printDebug(" (Reverb overridden - ignoring)");
+#endif
+ return;
+ }
+ report(ReportType_newReverbMode, &mt32ram.system.reverbMode);
+ report(ReportType_newReverbTime, &mt32ram.system.reverbTime);
+ report(ReportType_newReverbLevel, &mt32ram.system.reverbLevel);
+
+ ReverbModel *newReverbModel = reverbModels[mt32ram.system.reverbMode];
+#if MT32EMU_REDUCE_REVERB_MEMORY
+ if (reverbModel != newReverbModel) {
+ if (reverbModel != NULL) {
+ reverbModel->close();
+ }
+ newReverbModel->open(myProp.sampleRate);
+ }
+#endif
+ reverbModel = newReverbModel;
+ reverbModel->setParameters(mt32ram.system.reverbTime, mt32ram.system.reverbLevel);
+}
+
+void Synth::refreshSystemReserveSettings() {
+ Bit8u *rset = mt32ram.system.reserveSettings;
+#if MT32EMU_MONITOR_SYSEX > 0
+ printDebug(" Partial reserve: 1=%02d 2=%02d 3=%02d 4=%02d 5=%02d 6=%02d 7=%02d 8=%02d Rhythm=%02d", rset[0], rset[1], rset[2], rset[3], rset[4], rset[5], rset[6], rset[7], rset[8]);
+#endif
+ partialManager->setReserve(rset);
+}
+
+void Synth::refreshSystemChanAssign(unsigned int firstPart, unsigned int lastPart) {
+ memset(chantable, -1, sizeof(chantable));
+
+ // CONFIRMED: In the case of assigning a channel to multiple parts, the lower part wins.
+ for (unsigned int i = 0; i <= 8; i++) {
+ if (parts[i] != NULL && i >= firstPart && i <= lastPart) {
+ // CONFIRMED: Decay is started for all polys, and all controllers are reset, for every part whose assignment was touched by the sysex write.
+ parts[i]->allSoundOff();
+ parts[i]->resetAllControllers();
+ }
+ int chan = mt32ram.system.chanAssign[i];
+ if (chan != 16 && chantable[chan] == -1) {
+ chantable[chan] = i;
+ }
+ }
+
+#if MT32EMU_MONITOR_SYSEX > 0
+ Bit8u *rset = mt32ram.system.chanAssign;
+ printDebug(" Part assign: 1=%02d 2=%02d 3=%02d 4=%02d 5=%02d 6=%02d 7=%02d 8=%02d Rhythm=%02d", rset[0], rset[1], rset[2], rset[3], rset[4], rset[5], rset[6], rset[7], rset[8]);
+#endif
+}
+
+void Synth::refreshSystemMasterVol() {
+#if MT32EMU_MONITOR_SYSEX > 0
+ printDebug(" Master volume: %d", mt32ram.system.masterVol);
+#endif
+}
+
+void Synth::refreshSystem() {
+ refreshSystemMasterTune();
+ refreshSystemReverbParameters();
+ refreshSystemReserveSettings();
+ refreshSystemChanAssign(0, 8);
+ refreshSystemMasterVol();
+}
+
+void Synth::reset() {
+#if MT32EMU_MONITOR_SYSEX > 0
+ printDebug("RESET");
+#endif
+ report(ReportType_devReset, NULL);
+ partialManager->deactivateAll();
+ mt32ram = mt32default;
+ for (int i = 0; i < 9; i++) {
+ parts[i]->reset();
+ if (i != 8) {
+ parts[i]->setProgram(controlROMData[controlROMMap->programSettings + i]);
+ } else {
+ parts[8]->refresh();
+ }
+ }
+ refreshSystem();
+ isEnabled = false;
+}
+
+void Synth::render(Bit16s *stream, Bit32u len) {
+ if (!isEnabled) {
+ memset(stream, 0, len * sizeof(Bit16s) * 2);
+ return;
+ }
+ while (len > 0) {
+ Bit32u thisLen = len > MAX_SAMPLES_PER_RUN ? MAX_SAMPLES_PER_RUN : len;
+ renderStreams(tmpNonReverbLeft, tmpNonReverbRight, tmpReverbDryLeft, tmpReverbDryRight, tmpReverbWetLeft, tmpReverbWetRight, thisLen);
+ for (Bit32u i = 0; i < thisLen; i++) {
+ stream[0] = clipBit16s((Bit32s)tmpNonReverbLeft[i] + (Bit32s)tmpReverbDryLeft[i] + (Bit32s)tmpReverbWetLeft[i]);
+ stream[1] = clipBit16s((Bit32s)tmpNonReverbRight[i] + (Bit32s)tmpReverbDryRight[i] + (Bit32s)tmpReverbWetRight[i]);
+ stream += 2;
+ }
+ len -= thisLen;
+ }
+}
+
+bool Synth::prerender() {
+ int newPrerenderWriteIx = (prerenderWriteIx + 1) % MAX_PRERENDER_SAMPLES;
+ if (newPrerenderWriteIx == prerenderReadIx) {
+ // The prerender buffer is full
+ return false;
+ }
+ doRenderStreams(
+ prerenderNonReverbLeft + prerenderWriteIx,
+ prerenderNonReverbRight + prerenderWriteIx,
+ prerenderReverbDryLeft + prerenderWriteIx,
+ prerenderReverbDryRight + prerenderWriteIx,
+ prerenderReverbWetLeft + prerenderWriteIx,
+ prerenderReverbWetRight + prerenderWriteIx,
+ 1);
+ prerenderWriteIx = newPrerenderWriteIx;
+ return true;
+}
+
+static inline void maybeCopy(Bit16s *out, Bit32u outPos, Bit16s *in, Bit32u inPos, Bit32u len) {
+ if (out == NULL) {
+ return;
+ }
+ memcpy(out + outPos, in + inPos, len * sizeof(Bit16s));
+}
+
+void Synth::copyPrerender(Bit16s *nonReverbLeft, Bit16s *nonReverbRight, Bit16s *reverbDryLeft, Bit16s *reverbDryRight, Bit16s *reverbWetLeft, Bit16s *reverbWetRight, Bit32u pos, Bit32u len) {
+ maybeCopy(nonReverbLeft, pos, prerenderNonReverbLeft, prerenderReadIx, len);
+ maybeCopy(nonReverbRight, pos, prerenderNonReverbRight, prerenderReadIx, len);
+ maybeCopy(reverbDryLeft, pos, prerenderReverbDryLeft, prerenderReadIx, len);
+ maybeCopy(reverbDryRight, pos, prerenderReverbDryRight, prerenderReadIx, len);
+ maybeCopy(reverbWetLeft, pos, prerenderReverbWetLeft, prerenderReadIx, len);
+ maybeCopy(reverbWetRight, pos, prerenderReverbWetRight, prerenderReadIx, len);
+}
+
+void Synth::checkPrerender(Bit16s *nonReverbLeft, Bit16s *nonReverbRight, Bit16s *reverbDryLeft, Bit16s *reverbDryRight, Bit16s *reverbWetLeft, Bit16s *reverbWetRight, Bit32u &pos, Bit32u &len) {
+ if (prerenderReadIx > prerenderWriteIx) {
+ // There's data in the prerender buffer, and the write index has wrapped.
+ Bit32u prerenderCopyLen = MAX_PRERENDER_SAMPLES - prerenderReadIx;
+ if (prerenderCopyLen > len) {
+ prerenderCopyLen = len;
+ }
+ copyPrerender(nonReverbLeft, nonReverbRight, reverbDryLeft, reverbDryRight, reverbWetLeft, reverbWetRight, pos, prerenderCopyLen);
+ len -= prerenderCopyLen;
+ pos += prerenderCopyLen;
+ prerenderReadIx = (prerenderReadIx + prerenderCopyLen) % MAX_PRERENDER_SAMPLES;
+ }
+ if (prerenderReadIx < prerenderWriteIx) {
+ // There's data in the prerender buffer, and the write index is ahead of the read index.
+ Bit32u prerenderCopyLen = prerenderWriteIx - prerenderReadIx;
+ if (prerenderCopyLen > len) {
+ prerenderCopyLen = len;
+ }
+ copyPrerender(nonReverbLeft, nonReverbRight, reverbDryLeft, reverbDryRight, reverbWetLeft, reverbWetRight, pos, prerenderCopyLen);
+ len -= prerenderCopyLen;
+ pos += prerenderCopyLen;
+ prerenderReadIx += prerenderCopyLen;
+ }
+ if (prerenderReadIx == prerenderWriteIx) {
+ // If the ring buffer's empty, reset it to start at 0 to minimise wrapping,
+ // which requires two writes instead of one.
+ prerenderReadIx = prerenderWriteIx = 0;
+ }
+}
+
+void Synth::renderStreams(Bit16s *nonReverbLeft, Bit16s *nonReverbRight, Bit16s *reverbDryLeft, Bit16s *reverbDryRight, Bit16s *reverbWetLeft, Bit16s *reverbWetRight, Bit32u len) {
+ if (!isEnabled) {
+ clearIfNonNull(nonReverbLeft, len);
+ clearIfNonNull(nonReverbRight, len);
+ clearIfNonNull(reverbDryLeft, len);
+ clearIfNonNull(reverbDryRight, len);
+ clearIfNonNull(reverbWetLeft, len);
+ clearIfNonNull(reverbWetRight, len);
+ return;
+ }
+ Bit32u pos = 0;
+
+ // First, check for data in the prerender buffer and spit that out before generating anything new.
+ // Note that the prerender buffer is rarely used - see comments elsewhere for details.
+ checkPrerender(nonReverbLeft, nonReverbRight, reverbDryLeft, reverbDryRight, reverbWetLeft, reverbWetRight, pos, len);
+
+ while (len > 0) {
+ Bit32u thisLen = len > MAX_SAMPLES_PER_RUN ? MAX_SAMPLES_PER_RUN : len;
+ doRenderStreams(
+ streamOffset(nonReverbLeft, pos),
+ streamOffset(nonReverbRight, pos),
+ streamOffset(reverbDryLeft, pos),
+ streamOffset(reverbDryRight, pos),
+ streamOffset(reverbWetLeft, pos),
+ streamOffset(reverbWetRight, pos),
+ thisLen);
+ len -= thisLen;
+ pos += thisLen;
+ }
+}
+
+// FIXME: Using more temporary buffers than we need to
+void Synth::doRenderStreams(Bit16s *nonReverbLeft, Bit16s *nonReverbRight, Bit16s *reverbDryLeft, Bit16s *reverbDryRight, Bit16s *reverbWetLeft, Bit16s *reverbWetRight, Bit32u len) {
+ clearFloats(&tmpBufMixLeft[0], &tmpBufMixRight[0], len);
+ if (!reverbEnabled) {
+ for (unsigned int i = 0; i < MT32EMU_MAX_PARTIALS; i++) {
+ if (partialManager->produceOutput(i, &tmpBufPartialLeft[0], &tmpBufPartialRight[0], len)) {
+ mix(&tmpBufMixLeft[0], &tmpBufPartialLeft[0], len);
+ mix(&tmpBufMixRight[0], &tmpBufPartialRight[0], len);
+ }
+ }
+ if (nonReverbLeft != NULL) {
+ la32FloatToBit16sFunc(nonReverbLeft, &tmpBufMixLeft[0], len, outputGain);
+ }
+ if (nonReverbRight != NULL) {
+ la32FloatToBit16sFunc(nonReverbRight, &tmpBufMixRight[0], len, outputGain);
+ }
+ clearIfNonNull(reverbDryLeft, len);
+ clearIfNonNull(reverbDryRight, len);
+ clearIfNonNull(reverbWetLeft, len);
+ clearIfNonNull(reverbWetRight, len);
+ } else {
+ for (unsigned int i = 0; i < MT32EMU_MAX_PARTIALS; i++) {
+ if (!partialManager->shouldReverb(i)) {
+ if (partialManager->produceOutput(i, &tmpBufPartialLeft[0], &tmpBufPartialRight[0], len)) {
+ mix(&tmpBufMixLeft[0], &tmpBufPartialLeft[0], len);
+ mix(&tmpBufMixRight[0], &tmpBufPartialRight[0], len);
+ }
+ }
+ }
+ if (nonReverbLeft != NULL) {
+ la32FloatToBit16sFunc(nonReverbLeft, &tmpBufMixLeft[0], len, outputGain);
+ }
+ if (nonReverbRight != NULL) {
+ la32FloatToBit16sFunc(nonReverbRight, &tmpBufMixRight[0], len, outputGain);
+ }
+
+ clearFloats(&tmpBufMixLeft[0], &tmpBufMixRight[0], len);
+ for (unsigned int i = 0; i < MT32EMU_MAX_PARTIALS; i++) {
+ if (partialManager->shouldReverb(i)) {
+ if (partialManager->produceOutput(i, &tmpBufPartialLeft[0], &tmpBufPartialRight[0], len)) {
+ mix(&tmpBufMixLeft[0], &tmpBufPartialLeft[0], len);
+ mix(&tmpBufMixRight[0], &tmpBufPartialRight[0], len);
+ }
+ }
+ }
+ if (reverbDryLeft != NULL) {
+ la32FloatToBit16sFunc(reverbDryLeft, &tmpBufMixLeft[0], len, outputGain);
+ }
+ if (reverbDryRight != NULL) {
+ la32FloatToBit16sFunc(reverbDryRight, &tmpBufMixRight[0], len, outputGain);
+ }
+
+ // FIXME: Note that on the real devices, reverb input and output are signed linear 16-bit (well, kinda, there's some fudging) PCM, not float.
+ reverbModel->process(&tmpBufMixLeft[0], &tmpBufMixRight[0], &tmpBufReverbOutLeft[0], &tmpBufReverbOutRight[0], len);
+ if (reverbWetLeft != NULL) {
+ reverbFloatToBit16sFunc(reverbWetLeft, &tmpBufReverbOutLeft[0], len, reverbOutputGain);
+ }
+ if (reverbWetRight != NULL) {
+ reverbFloatToBit16sFunc(reverbWetRight, &tmpBufReverbOutRight[0], len, reverbOutputGain);
+ }
+ }
+ partialManager->clearAlreadyOutputed();
+ renderedSampleCount += len;
+}
+
+void Synth::printPartialUsage(unsigned long sampleOffset) {
+ unsigned int partialUsage[9];
+ partialManager->getPerPartPartialUsage(partialUsage);
+ if (sampleOffset > 0) {
+ printDebug("[+%lu] Partial Usage: 1:%02d 2:%02d 3:%02d 4:%02d 5:%02d 6:%02d 7:%02d 8:%02d R: %02d TOTAL: %02d", sampleOffset, partialUsage[0], partialUsage[1], partialUsage[2], partialUsage[3], partialUsage[4], partialUsage[5], partialUsage[6], partialUsage[7], partialUsage[8], MT32EMU_MAX_PARTIALS - partialManager->getFreePartialCount());
+ } else {
+ printDebug("Partial Usage: 1:%02d 2:%02d 3:%02d 4:%02d 5:%02d 6:%02d 7:%02d 8:%02d R: %02d TOTAL: %02d", partialUsage[0], partialUsage[1], partialUsage[2], partialUsage[3], partialUsage[4], partialUsage[5], partialUsage[6], partialUsage[7], partialUsage[8], MT32EMU_MAX_PARTIALS - partialManager->getFreePartialCount());
+ }
+}
+
+bool Synth::hasActivePartials() const {
+ if (prerenderReadIx != prerenderWriteIx) {
+ // Data in the prerender buffer means that the current isActive() states are "in the future".
+ // It also means that partials are definitely active at this render point.
+ return true;
+ }
+ for (int partialNum = 0; partialNum < MT32EMU_MAX_PARTIALS; partialNum++) {
+ if (partialManager->getPartial(partialNum)->isActive()) {
+ return true;
+ }
+ }
+ return false;
+}
+
+bool Synth::isActive() const {
+ if (hasActivePartials()) {
+ return true;
+ }
+ if (reverbEnabled) {
+ return reverbModel->isActive();
+ }
+ return false;
+}
+
+const Partial *Synth::getPartial(unsigned int partialNum) const {
+ return partialManager->getPartial(partialNum);
+}
+
+const Part *Synth::getPart(unsigned int partNum) const {
+ if (partNum > 8) {
+ return NULL;
+ }
+ return parts[partNum];
+}
+
+void MemoryRegion::read(unsigned int entry, unsigned int off, Bit8u *dst, unsigned int len) const {
+ off += entry * entrySize;
+ // This method should never be called with out-of-bounds parameters,
+ // or on an unsupported region - seeing any of this debug output indicates a bug in the emulator
+ if (off > entrySize * entries - 1) {
+#if MT32EMU_MONITOR_SYSEX > 0
+ synth->printDebug("read[%d]: parameters start out of bounds: entry=%d, off=%d, len=%d", type, entry, off, len);
+#endif
+ return;
+ }
+ if (off + len > entrySize * entries) {
+#if MT32EMU_MONITOR_SYSEX > 0
+ synth->printDebug("read[%d]: parameters end out of bounds: entry=%d, off=%d, len=%d", type, entry, off, len);
+#endif
+ len = entrySize * entries - off;
+ }
+ Bit8u *src = getRealMemory();
+ if (src == NULL) {
+#if MT32EMU_MONITOR_SYSEX > 0
+ synth->printDebug("read[%d]: unreadable region: entry=%d, off=%d, len=%d", type, entry, off, len);
+#endif
+ return;
+ }
+ memcpy(dst, src + off, len);
+}
+
+void MemoryRegion::write(unsigned int entry, unsigned int off, const Bit8u *src, unsigned int len, bool init) const {
+ unsigned int memOff = entry * entrySize + off;
+ // This method should never be called with out-of-bounds parameters,
+ // or on an unsupported region - seeing any of this debug output indicates a bug in the emulator
+ if (off > entrySize * entries - 1) {
+#if MT32EMU_MONITOR_SYSEX > 0
+ synth->printDebug("write[%d]: parameters start out of bounds: entry=%d, off=%d, len=%d", type, entry, off, len);
+#endif
+ return;
+ }
+ if (off + len > entrySize * entries) {
+#if MT32EMU_MONITOR_SYSEX > 0
+ synth->printDebug("write[%d]: parameters end out of bounds: entry=%d, off=%d, len=%d", type, entry, off, len);
+#endif
+ len = entrySize * entries - off;
+ }
+ Bit8u *dest = getRealMemory();
+ if (dest == NULL) {
+#if MT32EMU_MONITOR_SYSEX > 0
+ synth->printDebug("write[%d]: unwritable region: entry=%d, off=%d, len=%d", type, entry, off, len);
+#endif
+ }
+
+ for (unsigned int i = 0; i < len; i++) {
+ Bit8u desiredValue = src[i];
+ Bit8u maxValue = getMaxValue(memOff);
+ // maxValue == 0 means write-protected unless called from initialisation code, in which case it really means the maximum value is 0.
+ if (maxValue != 0 || init) {
+ if (desiredValue > maxValue) {
+#if MT32EMU_MONITOR_SYSEX > 0
+ synth->printDebug("write[%d]: Wanted 0x%02x at %d, but max 0x%02x", type, desiredValue, memOff, maxValue);
+#endif
+ desiredValue = maxValue;
+ }
+ dest[memOff] = desiredValue;
+ } else if (desiredValue != 0) {
+#if MT32EMU_MONITOR_SYSEX > 0
+ // Only output debug info if they wanted to write non-zero, since a lot of things cause this to spit out a lot of debug info otherwise.
+ synth->printDebug("write[%d]: Wanted 0x%02x at %d, but write-protected", type, desiredValue, memOff);
+#endif
+ }
+ memOff++;
+ }
+}
+
+}
diff --git a/audio/softsynth/mt32/Synth.h b/audio/softsynth/mt32/Synth.h
new file mode 100644
index 0000000000..ccabce7282
--- /dev/null
+++ b/audio/softsynth/mt32/Synth.h
@@ -0,0 +1,471 @@
+/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher
+ * Copyright (C) 2011 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef MT32EMU_SYNTH_H
+#define MT32EMU_SYNTH_H
+
+//#include <cstdarg>
+
+namespace MT32Emu {
+
+class TableInitialiser;
+class Partial;
+class PartialManager;
+class Part;
+
+/**
+ * Methods for emulating the connection between the LA32 and the DAC, which involves
+ * some hacks in the real devices for doubling the volume.
+ * See also http://en.wikipedia.org/wiki/Roland_MT-32#Digital_overflow
+ */
+enum DACInputMode {
+ // Produces samples at double the volume, without tricks.
+ // * Nicer overdrive characteristics than the DAC hacks (it simply clips samples within range)
+ // * Higher quality than the real devices
+ DACInputMode_NICE,
+
+ // Produces samples that exactly match the bits output from the emulated LA32.
+ // * Nicer overdrive characteristics than the DAC hacks (it simply clips samples within range)
+ // * Much less likely to overdrive than any other mode.
+ // * Half the volume of any of the other modes, meaning its volume relative to the reverb
+ // output when mixed together directly will sound wrong.
+ // * Perfect for developers while debugging :)
+ DACInputMode_PURE,
+
+ // Re-orders the LA32 output bits as in early generation MT-32s (according to Wikipedia).
+ // Bit order at DAC (where each number represents the original LA32 output bit number, and XX means the bit is always low):
+ // 15 13 12 11 10 09 08 07 06 05 04 03 02 01 00 XX
+ DACInputMode_GENERATION1,
+
+ // Re-orders the LA32 output bits as in later generations (personally confirmed on my CM-32L - KG).
+ // Bit order at DAC (where each number represents the original LA32 output bit number):
+ // 15 13 12 11 10 09 08 07 06 05 04 03 02 01 00 14
+ DACInputMode_GENERATION2
+};
+
+enum ReportType {
+ // Errors
+ ReportType_errorControlROM = 1,
+ ReportType_errorPCMROM,
+ ReportType_errorSampleRate,
+
+ // Progress
+ ReportType_progressInit,
+
+ // HW spec
+ ReportType_availableSSE,
+ ReportType_available3DNow,
+ ReportType_usingSSE,
+ ReportType_using3DNow,
+
+ // General info
+ ReportType_lcdMessage,
+ ReportType_devReset,
+ ReportType_devReconfig,
+ ReportType_newReverbMode,
+ ReportType_newReverbTime,
+ ReportType_newReverbLevel
+};
+
+enum LoadResult {
+ LoadResult_OK,
+ LoadResult_NotFound,
+ LoadResult_Unreadable,
+ LoadResult_Invalid
+};
+
+struct SynthProperties {
+ // Sample rate to use in mixing
+ unsigned int sampleRate;
+
+ // Deprecated - ignored. Use Synth::setReverbEnabled() instead.
+ bool useReverb;
+ // Deprecated - ignored. Use Synth::setReverbOverridden() instead.
+ bool useDefaultReverb;
+ // Deprecated - ignored. Use Synth::playSysex*() to configure reverb instead.
+ unsigned char reverbType;
+ // Deprecated - ignored. Use Synth::playSysex*() to configure reverb instead.
+ unsigned char reverbTime;
+ // Deprecated - ignored. Use Synth::playSysex*() to configure reverb instead.
+ unsigned char reverbLevel;
+ // The name of the directory in which the ROM and data files are stored (with trailing slash/backslash)
+ // Not used if "openFile" is set. May be NULL in any case.
+ const char *baseDir;
+ // This is used as the first argument to all callbacks
+ void *userData;
+ // Callback for reporting various errors and information. May be NULL
+ int (*report)(void *userData, ReportType type, const void *reportData);
+ // Callback for debug messages, in vprintf() format
+ void (*printDebug)(void *userData, const char *fmt, va_list list);
+ // Callback for providing an implementation of File, opened and ready for use
+ // May be NULL, in which case a default implementation will be used.
+ Common::File *(*openFile)(void *userData, const char *filename);
+ // Callback for closing a File. May be NULL, in which case the File will automatically be close()d/deleted.
+ void (*closeFile)(void *userData, Common::File *file);
+};
+
+// This is the specification of the Callback routine used when calling the RecalcWaveforms
+// function
+typedef void (*recalcStatusCallback)(int percDone);
+
+typedef void (*FloatToBit16sFunc)(Bit16s *target, const float *source, Bit32u len, float outputGain);
+
+const Bit8u SYSEX_MANUFACTURER_ROLAND = 0x41;
+
+const Bit8u SYSEX_MDL_MT32 = 0x16;
+const Bit8u SYSEX_MDL_D50 = 0x14;
+
+const Bit8u SYSEX_CMD_RQ1 = 0x11; // Request data #1
+const Bit8u SYSEX_CMD_DT1 = 0x12; // Data set 1
+const Bit8u SYSEX_CMD_WSD = 0x40; // Want to send data
+const Bit8u SYSEX_CMD_RQD = 0x41; // Request data
+const Bit8u SYSEX_CMD_DAT = 0x42; // Data set
+const Bit8u SYSEX_CMD_ACK = 0x43; // Acknowledge
+const Bit8u SYSEX_CMD_EOD = 0x45; // End of data
+const Bit8u SYSEX_CMD_ERR = 0x4E; // Communications error
+const Bit8u SYSEX_CMD_RJC = 0x4F; // Rejection
+
+const int MAX_SYSEX_SIZE = 512;
+
+const unsigned int CONTROL_ROM_SIZE = 64 * 1024;
+
+struct ControlROMPCMStruct {
+ Bit8u pos;
+ Bit8u len;
+ Bit8u pitchLSB;
+ Bit8u pitchMSB;
+};
+
+struct ControlROMMap {
+ Bit16u idPos;
+ Bit16u idLen;
+ const char *idBytes;
+ Bit16u pcmTable; // 4 * pcmCount bytes
+ Bit16u pcmCount;
+ Bit16u timbreAMap; // 128 bytes
+ Bit16u timbreAOffset;
+ bool timbreACompressed;
+ Bit16u timbreBMap; // 128 bytes
+ Bit16u timbreBOffset;
+ bool timbreBCompressed;
+ Bit16u timbreRMap; // 2 * timbreRCount bytes
+ Bit16u timbreRCount;
+ Bit16u rhythmSettings; // 4 * rhythmSettingsCount bytes
+ Bit16u rhythmSettingsCount;
+ Bit16u reserveSettings; // 9 bytes
+ Bit16u panSettings; // 8 bytes
+ Bit16u programSettings; // 8 bytes
+ Bit16u rhythmMaxTable; // 4 bytes
+ Bit16u patchMaxTable; // 16 bytes
+ Bit16u systemMaxTable; // 23 bytes
+ Bit16u timbreMaxTable; // 72 bytes
+};
+
+enum MemoryRegionType {
+ MR_PatchTemp, MR_RhythmTemp, MR_TimbreTemp, MR_Patches, MR_Timbres, MR_System, MR_Display, MR_Reset
+};
+
+class MemoryRegion {
+private:
+ Synth *synth;
+ Bit8u *realMemory;
+ Bit8u *maxTable;
+public:
+ MemoryRegionType type;
+ Bit32u startAddr, entrySize, entries;
+
+ MemoryRegion(Synth *useSynth, Bit8u *useRealMemory, Bit8u *useMaxTable, MemoryRegionType useType, Bit32u useStartAddr, Bit32u useEntrySize, Bit32u useEntries) {
+ synth = useSynth;
+ realMemory = useRealMemory;
+ maxTable = useMaxTable;
+ type = useType;
+ startAddr = useStartAddr;
+ entrySize = useEntrySize;
+ entries = useEntries;
+ }
+ int lastTouched(Bit32u addr, Bit32u len) const {
+ return (offset(addr) + len - 1) / entrySize;
+ }
+ int firstTouchedOffset(Bit32u addr) const {
+ return offset(addr) % entrySize;
+ }
+ int firstTouched(Bit32u addr) const {
+ return offset(addr) / entrySize;
+ }
+ Bit32u regionEnd() const {
+ return startAddr + entrySize * entries;
+ }
+ bool contains(Bit32u addr) const {
+ return addr >= startAddr && addr < regionEnd();
+ }
+ int offset(Bit32u addr) const {
+ return addr - startAddr;
+ }
+ Bit32u getClampedLen(Bit32u addr, Bit32u len) const {
+ if (addr + len > regionEnd())
+ return regionEnd() - addr;
+ return len;
+ }
+ Bit32u next(Bit32u addr, Bit32u len) const {
+ if (addr + len > regionEnd()) {
+ return regionEnd() - addr;
+ }
+ return 0;
+ }
+ Bit8u getMaxValue(int off) const {
+ if (maxTable == NULL)
+ return 0xFF;
+ return maxTable[off % entrySize];
+ }
+ Bit8u *getRealMemory() const {
+ return realMemory;
+ }
+ bool isReadable() const {
+ return getRealMemory() != NULL;
+ }
+ void read(unsigned int entry, unsigned int off, Bit8u *dst, unsigned int len) const;
+ void write(unsigned int entry, unsigned int off, const Bit8u *src, unsigned int len, bool init = false) const;
+};
+
+class PatchTempMemoryRegion : public MemoryRegion {
+public:
+ PatchTempMemoryRegion(Synth *useSynth, Bit8u *useRealMemory, Bit8u *useMaxTable) : MemoryRegion(useSynth, useRealMemory, useMaxTable, MR_PatchTemp, MT32EMU_MEMADDR(0x030000), sizeof(MemParams::PatchTemp), 9) {}
+};
+class RhythmTempMemoryRegion : public MemoryRegion {
+public:
+ RhythmTempMemoryRegion(Synth *useSynth, Bit8u *useRealMemory, Bit8u *useMaxTable) : MemoryRegion(useSynth, useRealMemory, useMaxTable, MR_RhythmTemp, MT32EMU_MEMADDR(0x030110), sizeof(MemParams::RhythmTemp), 85) {}
+};
+class TimbreTempMemoryRegion : public MemoryRegion {
+public:
+ TimbreTempMemoryRegion(Synth *useSynth, Bit8u *useRealMemory, Bit8u *useMaxTable) : MemoryRegion(useSynth, useRealMemory, useMaxTable, MR_TimbreTemp, MT32EMU_MEMADDR(0x040000), sizeof(TimbreParam), 8) {}
+};
+class PatchesMemoryRegion : public MemoryRegion {
+public:
+ PatchesMemoryRegion(Synth *useSynth, Bit8u *useRealMemory, Bit8u *useMaxTable) : MemoryRegion(useSynth, useRealMemory, useMaxTable, MR_Patches, MT32EMU_MEMADDR(0x050000), sizeof(PatchParam), 128) {}
+};
+class TimbresMemoryRegion : public MemoryRegion {
+public:
+ TimbresMemoryRegion(Synth *useSynth, Bit8u *useRealMemory, Bit8u *useMaxTable) : MemoryRegion(useSynth, useRealMemory, useMaxTable, MR_Timbres, MT32EMU_MEMADDR(0x080000), sizeof(MemParams::PaddedTimbre), 64 + 64 + 64 + 64) {}
+};
+class SystemMemoryRegion : public MemoryRegion {
+public:
+ SystemMemoryRegion(Synth *useSynth, Bit8u *useRealMemory, Bit8u *useMaxTable) : MemoryRegion(useSynth, useRealMemory, useMaxTable, MR_System, MT32EMU_MEMADDR(0x100000), sizeof(MemParams::System), 1) {}
+};
+class DisplayMemoryRegion : public MemoryRegion {
+public:
+ DisplayMemoryRegion(Synth *useSynth) : MemoryRegion(useSynth, NULL, NULL, MR_Display, MT32EMU_MEMADDR(0x200000), MAX_SYSEX_SIZE - 1, 1) {}
+};
+class ResetMemoryRegion : public MemoryRegion {
+public:
+ ResetMemoryRegion(Synth *useSynth) : MemoryRegion(useSynth, NULL, NULL, MR_Reset, MT32EMU_MEMADDR(0x7F0000), 0x3FFF, 1) {}
+};
+
+class ReverbModel {
+public:
+ virtual ~ReverbModel() {}
+ // After construction or a close(), open() will be called at least once before any other call (with the exception of close()).
+ virtual void open(unsigned int sampleRate) = 0;
+ // May be called multiple times without an open() in between.
+ virtual void close() = 0;
+ virtual void setParameters(Bit8u time, Bit8u level) = 0;
+ virtual void process(const float *inLeft, const float *inRight, float *outLeft, float *outRight, unsigned long numSamples) = 0;
+ virtual bool isActive() const = 0;
+};
+
+class Synth {
+friend class Part;
+friend class RhythmPart;
+friend class Poly;
+friend class Partial;
+friend class Tables;
+friend class MemoryRegion;
+friend class TVA;
+friend class TVF;
+friend class TVP;
+private:
+ PatchTempMemoryRegion *patchTempMemoryRegion;
+ RhythmTempMemoryRegion *rhythmTempMemoryRegion;
+ TimbreTempMemoryRegion *timbreTempMemoryRegion;
+ PatchesMemoryRegion *patchesMemoryRegion;
+ TimbresMemoryRegion *timbresMemoryRegion;
+ SystemMemoryRegion *systemMemoryRegion;
+ DisplayMemoryRegion *displayMemoryRegion;
+ ResetMemoryRegion *resetMemoryRegion;
+
+ Bit8u *paddedTimbreMaxTable;
+
+ bool isEnabled;
+
+ PCMWaveEntry *pcmWaves; // Array
+
+ const ControlROMMap *controlROMMap;
+ Bit8u controlROMData[CONTROL_ROM_SIZE];
+ float *pcmROMData;
+ int pcmROMSize; // This is in 16-bit samples, therefore half the number of bytes in the ROM
+
+ Bit8s chantable[32];
+
+ Bit32u renderedSampleCount;
+
+ Tables tables;
+
+ MemParams mt32ram, mt32default;
+
+ ReverbModel *reverbModels[4];
+ ReverbModel *reverbModel;
+ bool reverbEnabled;
+ bool reverbOverridden;
+
+ FloatToBit16sFunc la32FloatToBit16sFunc;
+ FloatToBit16sFunc reverbFloatToBit16sFunc;
+ float outputGain;
+ float reverbOutputGain;
+
+ bool isOpen;
+
+ PartialManager *partialManager;
+ Part *parts[9];
+
+ // FIXME: We can reorganise things so that we don't need all these separate tmpBuf, tmp and prerender buffers.
+ // This should be rationalised when things have stabilised a bit (if prerender buffers don't die in the mean time).
+
+ float tmpBufPartialLeft[MAX_SAMPLES_PER_RUN];
+ float tmpBufPartialRight[MAX_SAMPLES_PER_RUN];
+ float tmpBufMixLeft[MAX_SAMPLES_PER_RUN];
+ float tmpBufMixRight[MAX_SAMPLES_PER_RUN];
+ float tmpBufReverbOutLeft[MAX_SAMPLES_PER_RUN];
+ float tmpBufReverbOutRight[MAX_SAMPLES_PER_RUN];
+
+ Bit16s tmpNonReverbLeft[MAX_SAMPLES_PER_RUN];
+ Bit16s tmpNonReverbRight[MAX_SAMPLES_PER_RUN];
+ Bit16s tmpReverbDryLeft[MAX_SAMPLES_PER_RUN];
+ Bit16s tmpReverbDryRight[MAX_SAMPLES_PER_RUN];
+ Bit16s tmpReverbWetLeft[MAX_SAMPLES_PER_RUN];
+ Bit16s tmpReverbWetRight[MAX_SAMPLES_PER_RUN];
+
+ // These ring buffers are only used to simulate delays present on the real device.
+ // In particular, when a partial needs to be aborted to free it up for use by a new Poly,
+ // the controller will busy-loop waiting for the sound to finish.
+ Bit16s prerenderNonReverbLeft[MAX_PRERENDER_SAMPLES];
+ Bit16s prerenderNonReverbRight[MAX_PRERENDER_SAMPLES];
+ Bit16s prerenderReverbDryLeft[MAX_PRERENDER_SAMPLES];
+ Bit16s prerenderReverbDryRight[MAX_PRERENDER_SAMPLES];
+ Bit16s prerenderReverbWetLeft[MAX_PRERENDER_SAMPLES];
+ Bit16s prerenderReverbWetRight[MAX_PRERENDER_SAMPLES];
+ int prerenderReadIx;
+ int prerenderWriteIx;
+
+ SynthProperties myProp;
+
+ bool prerender();
+ void copyPrerender(Bit16s *nonReverbLeft, Bit16s *nonReverbRight, Bit16s *reverbDryLeft, Bit16s *reverbDryRight, Bit16s *reverbWetLeft, Bit16s *reverbWetRight, Bit32u pos, Bit32u len);
+ void checkPrerender(Bit16s *nonReverbLeft, Bit16s *nonReverbRight, Bit16s *reverbDryLeft, Bit16s *reverbDryRight, Bit16s *reverbWetLeft, Bit16s *reverbWetRight, Bit32u &pos, Bit32u &len);
+ void doRenderStreams(Bit16s *nonReverbLeft, Bit16s *nonReverbRight, Bit16s *reverbDryLeft, Bit16s *reverbDryRight, Bit16s *reverbWetLeft, Bit16s *reverbWetRight, Bit32u len);
+
+ void playAddressedSysex(unsigned char channel, const Bit8u *sysex, Bit32u len);
+ void readSysex(unsigned char channel, const Bit8u *sysex, Bit32u len) const;
+ void initMemoryRegions();
+ void deleteMemoryRegions();
+ MemoryRegion *findMemoryRegion(Bit32u addr);
+ void writeMemoryRegion(const MemoryRegion *region, Bit32u addr, Bit32u len, const Bit8u *data);
+ void readMemoryRegion(const MemoryRegion *region, Bit32u addr, Bit32u len, Bit8u *data);
+
+ LoadResult loadControlROM(const char *filename);
+ LoadResult loadPCMROM(const char *filename);
+
+ bool initPCMList(Bit16u mapAddress, Bit16u count);
+ bool initTimbres(Bit16u mapAddress, Bit16u offset, int timbreCount, int startTimbre, bool compressed);
+ bool initCompressedTimbre(int drumNum, const Bit8u *mem, unsigned int memLen);
+
+ void refreshSystemMasterTune();
+ void refreshSystemReverbParameters();
+ void refreshSystemReserveSettings();
+ void refreshSystemChanAssign(unsigned int firstPart, unsigned int lastPart);
+ void refreshSystemMasterVol();
+ void refreshSystem();
+ void reset();
+
+ unsigned int getSampleRate() const;
+
+ void printPartialUsage(unsigned long sampleOffset = 0);
+protected:
+ int report(ReportType type, const void *reportData);
+ Common::File *openFile(const char *filename);
+ void closeFile(Common::File *file);
+ void printDebug(const char *fmt, ...);
+
+public:
+ static Bit8u calcSysexChecksum(const Bit8u *data, Bit32u len, Bit8u checksum);
+
+ Synth();
+ ~Synth();
+
+ // Used to initialise the MT-32. Must be called before any other function.
+ // Returns true if initialization was sucessful, otherwise returns false.
+ bool open(SynthProperties &useProp);
+
+ // Closes the MT-32 and deallocates any memory used by the synthesizer
+ void close(void);
+
+ // Sends a 4-byte MIDI message to the MT-32 for immediate playback
+ void playMsg(Bit32u msg);
+ void playMsgOnPart(unsigned char part, unsigned char code, unsigned char note, unsigned char velocity);
+
+ // Sends a string of Sysex commands to the MT-32 for immediate interpretation
+ // The length is in bytes
+ void playSysex(const Bit8u *sysex, Bit32u len);
+ void playSysexWithoutFraming(const Bit8u *sysex, Bit32u len);
+ void playSysexWithoutHeader(unsigned char device, unsigned char command, const Bit8u *sysex, Bit32u len);
+ void writeSysex(unsigned char channel, const Bit8u *sysex, Bit32u len);
+
+ void setReverbEnabled(bool reverbEnabled);
+ bool isReverbEnabled() const;
+ void setReverbOverridden(bool reverbOverridden);
+ bool isReverbOverridden() const;
+ void setDACInputMode(DACInputMode mode);
+
+ // Sets output gain factor. Applied to all output samples and unrelated with the synth's Master volume.
+ void setOutputGain(float);
+
+ // Sets output gain factor for the reverb wet output. setOutputGain() doesn't change reverb output gain.
+ void setReverbOutputGain(float);
+
+ // Renders samples to the specified output stream.
+ // The length is in frames, not bytes (in 16-bit stereo,
+ // one frame is 4 bytes).
+ void render(Bit16s *stream, Bit32u len);
+
+ // Renders samples to the specified output streams (any or all of which may be NULL).
+ void renderStreams(Bit16s *nonReverbLeft, Bit16s *nonReverbRight, Bit16s *reverbDryLeft, Bit16s *reverbDryRight, Bit16s *reverbWetLeft, Bit16s *reverbWetRight, Bit32u len);
+
+ // Returns true when there is at least one active partial, otherwise false.
+ bool hasActivePartials() const;
+
+ // Returns true if hasActivePartials() returns true, or reverb is (somewhat unreliably) detected as being active.
+ bool isActive() const;
+
+ const Partial *getPartial(unsigned int partialNum) const;
+
+ void readMemory(Bit32u addr, Bit32u len, Bit8u *data);
+
+ // partNum should be 0..7 for Part 1..8, or 8 for Rhythm
+ const Part *getPart(unsigned int partNum) const;
+};
+
+}
+
+#endif
diff --git a/audio/softsynth/mt32/TVA.cpp b/audio/softsynth/mt32/TVA.cpp
new file mode 100644
index 0000000000..c3be6db591
--- /dev/null
+++ b/audio/softsynth/mt32/TVA.cpp
@@ -0,0 +1,365 @@
+/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher
+ * Copyright (C) 2011 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * This class emulates the calculations performed by the 8095 microcontroller in order to configure the LA-32's amplitude ramp for a single partial at each stage of its TVA envelope.
+ * Unless we introduced bugs, it should be pretty much 100% accurate according to Mok's specifications.
+*/
+//#include <cmath>
+
+#include "mt32emu.h"
+#include "mmath.h"
+
+namespace MT32Emu {
+
+// CONFIRMED: Matches a table in ROM - haven't got around to coming up with a formula for it yet.
+static Bit8u biasLevelToAmpSubtractionCoeff[13] = {255, 187, 137, 100, 74, 54, 40, 29, 21, 15, 10, 5, 0};
+
+TVA::TVA(const Partial *usePartial, LA32Ramp *useAmpRamp) :
+ partial(usePartial), ampRamp(useAmpRamp), system_(&usePartial->getSynth()->mt32ram.system) {
+}
+
+void TVA::startRamp(Bit8u newTarget, Bit8u newIncrement, int newPhase) {
+ target = newTarget;
+ phase = newPhase;
+ ampRamp->startRamp(newTarget, newIncrement);
+#if MT32EMU_MONITOR_TVA >= 1
+ partial->getSynth()->printDebug("[+%lu] [Partial %d] TVA,ramp,%d,%d,%d,%d", partial->debugGetSampleNum(), partial->debugGetPartialNum(), (newIncrement & 0x80) ? -1 : 1, (newIncrement & 0x7F), newPhase);
+#endif
+}
+
+void TVA::end(int newPhase) {
+ phase = newPhase;
+ playing = false;
+#if MT32EMU_MONITOR_TVA >= 1
+ partial->getSynth()->printDebug("[+%lu] [Partial %d] TVA,end,%d", partial->debugGetSampleNum(), partial->debugGetPartialNum(), newPhase);
+#endif
+}
+
+static int multBias(Bit8u biasLevel, int bias) {
+ return (bias * biasLevelToAmpSubtractionCoeff[biasLevel]) >> 5;
+}
+
+static int calcBiasAmpSubtraction(Bit8u biasPoint, Bit8u biasLevel, int key) {
+ if ((biasPoint & 0x40) == 0) {
+ int bias = biasPoint + 33 - key;
+ if (bias > 0) {
+ return multBias(biasLevel, bias);
+ }
+ } else {
+ int bias = biasPoint - 31 - key;
+ if (bias < 0) {
+ bias = -bias;
+ return multBias(biasLevel, bias);
+ }
+ }
+ return 0;
+}
+
+static int calcBiasAmpSubtractions(const TimbreParam::PartialParam *partialParam, int key) {
+ int biasAmpSubtraction1 = calcBiasAmpSubtraction(partialParam->tva.biasPoint1, partialParam->tva.biasLevel1, key);
+ if (biasAmpSubtraction1 > 255) {
+ return 255;
+ }
+ int biasAmpSubtraction2 = calcBiasAmpSubtraction(partialParam->tva.biasPoint2, partialParam->tva.biasLevel2, key);
+ if (biasAmpSubtraction2 > 255) {
+ return 255;
+ }
+ int biasAmpSubtraction = biasAmpSubtraction1 + biasAmpSubtraction2;
+ if (biasAmpSubtraction > 255) {
+ return 255;
+ }
+ return biasAmpSubtraction;
+}
+
+static int calcVeloAmpSubtraction(Bit8u veloSensitivity, unsigned int velocity) {
+ // FIXME:KG: Better variable names
+ int velocityMult = veloSensitivity - 50;
+ int absVelocityMult = velocityMult < 0 ? -velocityMult : velocityMult;
+ velocityMult = (signed)((unsigned)(velocityMult * ((signed)velocity - 64)) << 2);
+ return absVelocityMult - (velocityMult >> 8); // PORTABILITY NOTE: Assumes arithmetic shift
+}
+
+static int calcBasicAmp(const Tables *tables, const Partial *partial, const MemParams::System *system_, const TimbreParam::PartialParam *partialParam, const MemParams::PatchTemp *patchTemp, const MemParams::RhythmTemp *rhythmTemp, int biasAmpSubtraction, int veloAmpSubtraction, Bit8u expression) {
+ int amp = 155;
+
+ if (!partial->isRingModulatingSlave()) {
+ amp -= tables->masterVolToAmpSubtraction[system_->masterVol];
+ if (amp < 0) {
+ return 0;
+ }
+ amp -= tables->levelToAmpSubtraction[patchTemp->outputLevel];
+ if (amp < 0) {
+ return 0;
+ }
+ amp -= tables->levelToAmpSubtraction[expression];
+ if (amp < 0) {
+ return 0;
+ }
+ if (rhythmTemp != NULL) {
+ amp -= tables->levelToAmpSubtraction[rhythmTemp->outputLevel];
+ if (amp < 0) {
+ return 0;
+ }
+ }
+ }
+ amp -= biasAmpSubtraction;
+ if (amp < 0) {
+ return 0;
+ }
+ amp -= tables->levelToAmpSubtraction[partialParam->tva.level];
+ if (amp < 0) {
+ return 0;
+ }
+ amp -= veloAmpSubtraction;
+ if (amp < 0) {
+ return 0;
+ }
+ if (amp > 155) {
+ amp = 155;
+ }
+ amp -= partialParam->tvf.resonance >> 1;
+ if (amp < 0) {
+ return 0;
+ }
+ return amp;
+}
+
+int calcKeyTimeSubtraction(Bit8u envTimeKeyfollow, int key) {
+ if (envTimeKeyfollow == 0) {
+ return 0;
+ }
+ return (key - 60) >> (5 - envTimeKeyfollow); // PORTABILITY NOTE: Assumes arithmetic shift
+}
+
+void TVA::reset(const Part *newPart, const TimbreParam::PartialParam *newPartialParam, const MemParams::RhythmTemp *newRhythmTemp) {
+ part = newPart;
+ partialParam = newPartialParam;
+ patchTemp = newPart->getPatchTemp();
+ rhythmTemp = newRhythmTemp;
+
+ playing = true;
+
+ Tables *tables = &partial->getSynth()->tables;
+
+ int key = partial->getPoly()->getKey();
+ int velocity = partial->getPoly()->getVelocity();
+
+ keyTimeSubtraction = calcKeyTimeSubtraction(partialParam->tva.envTimeKeyfollow, key);
+
+ biasAmpSubtraction = calcBiasAmpSubtractions(partialParam, key);
+ veloAmpSubtraction = calcVeloAmpSubtraction(partialParam->tva.veloSensitivity, velocity);
+
+ int newTarget = calcBasicAmp(tables, partial, system_, partialParam, patchTemp, newRhythmTemp, biasAmpSubtraction, veloAmpSubtraction, part->getExpression());
+ int newPhase;
+ if (partialParam->tva.envTime[0] == 0) {
+ // Initially go to the TVA_PHASE_ATTACK target amp, and spend the next phase going from there to the TVA_PHASE_2 target amp
+ // Note that this means that velocity never affects time for this partial.
+ newTarget += partialParam->tva.envLevel[0];
+ newPhase = TVA_PHASE_ATTACK; // The first target used in nextPhase() will be TVA_PHASE_2
+ } else {
+ // Initially go to the base amp determined by TVA level, part volume, etc., and spend the next phase going from there to the full TVA_PHASE_ATTACK target amp.
+ newPhase = TVA_PHASE_BASIC; // The first target used in nextPhase() will be TVA_PHASE_ATTACK
+ }
+
+ ampRamp->reset();//currentAmp = 0;
+
+ // "Go downward as quickly as possible".
+ // Since the current value is 0, the LA32Ramp will notice that we're already at or below the target and trying to go downward,
+ // and therefore jump to the target immediately and raise an interrupt.
+ startRamp((Bit8u)newTarget, 0x80 | 127, newPhase);
+}
+
+void TVA::startAbort() {
+ startRamp(64, 0x80 | 127, TVA_PHASE_RELEASE);
+}
+
+void TVA::startDecay() {
+ if (phase >= TVA_PHASE_RELEASE) {
+ return;
+ }
+ Bit8u newIncrement;
+ if (partialParam->tva.envTime[4] == 0) {
+ newIncrement = 1;
+ } else {
+ newIncrement = -partialParam->tva.envTime[4];
+ }
+ // The next time nextPhase() is called, it will think TVA_PHASE_RELEASE has finished and the partial will be aborted
+ startRamp(0, newIncrement, TVA_PHASE_RELEASE);
+}
+
+void TVA::handleInterrupt() {
+ nextPhase();
+}
+
+void TVA::recalcSustain() {
+ // We get pinged periodically by the pitch code to recalculate our values when in sustain.
+ // This is done so that the TVA will respond to things like MIDI expression and volume changes while it's sustaining, which it otherwise wouldn't do.
+
+ // The check for envLevel[3] == 0 strikes me as slightly dumb. FIXME: Explain why
+ if (phase != TVA_PHASE_SUSTAIN || partialParam->tva.envLevel[3] == 0) {
+ return;
+ }
+ // We're sustaining. Recalculate all the values
+ Tables *tables = &partial->getSynth()->tables;
+ int newTarget = calcBasicAmp(tables, partial, system_, partialParam, patchTemp, rhythmTemp, biasAmpSubtraction, veloAmpSubtraction, part->getExpression());
+ newTarget += partialParam->tva.envLevel[3];
+ // Since we're in TVA_PHASE_SUSTAIN at this point, we know that target has been reached and an interrupt fired, so we can rely on it being the current amp.
+ int targetDelta = newTarget - target;
+
+ // Calculate an increment to get to the new amp value in a short, more or less consistent amount of time
+ Bit8u newIncrement;
+ if (targetDelta >= 0) {
+ newIncrement = tables->envLogarithmicTime[(Bit8u)targetDelta] - 2;
+ } else {
+ newIncrement = (tables->envLogarithmicTime[(Bit8u)-targetDelta] - 2) | 0x80;
+ }
+ // Configure so that once the transition's complete and nextPhase() is called, we'll just re-enter sustain phase (or decay phase, depending on parameters at the time).
+ startRamp(newTarget, newIncrement, TVA_PHASE_SUSTAIN - 1);
+}
+
+bool TVA::isPlaying() const {
+ return playing;
+}
+
+int TVA::getPhase() const {
+ return phase;
+}
+
+void TVA::nextPhase() {
+ Tables *tables = &partial->getSynth()->tables;
+
+ if (phase >= TVA_PHASE_DEAD || !playing) {
+ partial->getSynth()->printDebug("TVA::nextPhase(): Shouldn't have got here with phase %d, playing=%s", phase, playing ? "true" : "false");
+ return;
+ }
+ int newPhase = phase + 1;
+
+ if (newPhase == TVA_PHASE_DEAD) {
+ end(newPhase);
+ return;
+ }
+
+ bool allLevelsZeroFromNowOn = false;
+ if (partialParam->tva.envLevel[3] == 0) {
+ if (newPhase == TVA_PHASE_4) {
+ allLevelsZeroFromNowOn = true;
+ } else if (partialParam->tva.envLevel[2] == 0) {
+ if (newPhase == TVA_PHASE_3) {
+ allLevelsZeroFromNowOn = true;
+ } else if (partialParam->tva.envLevel[1] == 0) {
+ if (newPhase == TVA_PHASE_2) {
+ allLevelsZeroFromNowOn = true;
+ } else if (partialParam->tva.envLevel[0] == 0) {
+ if (newPhase == TVA_PHASE_ATTACK) { // this line added, missing in ROM - FIXME: Add description of repercussions
+ allLevelsZeroFromNowOn = true;
+ }
+ }
+ }
+ }
+ }
+
+ int newTarget;
+ int newIncrement;
+ int envPointIndex = phase;
+
+ if (!allLevelsZeroFromNowOn) {
+ newTarget = calcBasicAmp(tables, partial, system_, partialParam, patchTemp, rhythmTemp, biasAmpSubtraction, veloAmpSubtraction, part->getExpression());
+
+ if (newPhase == TVA_PHASE_SUSTAIN || newPhase == TVA_PHASE_RELEASE) {
+ if (partialParam->tva.envLevel[3] == 0) {
+ end(newPhase);
+ return;
+ }
+ if (!partial->getPoly()->canSustain()) {
+ newPhase = TVA_PHASE_RELEASE;
+ newTarget = 0;
+ newIncrement = -partialParam->tva.envTime[4];
+ if (newIncrement == 0) {
+ // We can't let the increment be 0, or there would be no emulated interrupt.
+ // So we do an "upward" increment, which should set the amp to 0 extremely quickly
+ // and cause an "interrupt" to bring us back to nextPhase().
+ newIncrement = 1;
+ }
+ } else {
+ newTarget += partialParam->tva.envLevel[3];
+ newIncrement = 0;
+ }
+ } else {
+ newTarget += partialParam->tva.envLevel[envPointIndex];
+ }
+ } else {
+ newTarget = 0;
+ }
+
+ if ((newPhase != TVA_PHASE_SUSTAIN && newPhase != TVA_PHASE_RELEASE) || allLevelsZeroFromNowOn) {
+ int envTimeSetting = partialParam->tva.envTime[envPointIndex];
+
+ if (newPhase == TVA_PHASE_ATTACK) {
+ envTimeSetting -= ((signed)partial->getPoly()->getVelocity() - 64) >> (6 - partialParam->tva.envTimeVeloSensitivity); // PORTABILITY NOTE: Assumes arithmetic shift
+
+ if (envTimeSetting <= 0 && partialParam->tva.envTime[envPointIndex] != 0) {
+ envTimeSetting = 1;
+ }
+ } else {
+ envTimeSetting -= keyTimeSubtraction;
+ }
+ if (envTimeSetting > 0) {
+ int targetDelta = newTarget - target;
+ if (targetDelta <= 0) {
+ if (targetDelta == 0) {
+ // target and newTarget are the same.
+ // We can't have an increment of 0 or we wouldn't get an emulated interrupt.
+ // So instead make the target one less than it really should be and set targetDelta accordingly.
+ targetDelta = -1;
+ newTarget--;
+ if (newTarget < 0) {
+ // Oops, newTarget is less than zero now, so let's do it the other way:
+ // Make newTarget one more than it really should've been and set targetDelta accordingly.
+ // FIXME (apparent bug in real firmware):
+ // This means targetDelta will be positive just below here where it's inverted, and we'll end up using envLogarithmicTime[-1], and we'll be setting newIncrement to be descending later on, etc..
+ targetDelta = 1;
+ newTarget = -newTarget;
+ }
+ }
+ targetDelta = -targetDelta;
+ newIncrement = tables->envLogarithmicTime[(Bit8u)targetDelta] - envTimeSetting;
+ if (newIncrement <= 0) {
+ newIncrement = 1;
+ }
+ newIncrement = newIncrement | 0x80;
+ } else {
+ // FIXME: The last 22 or so entries in this table are 128 - surely that fucks things up, since that ends up being -128 signed?
+ newIncrement = tables->envLogarithmicTime[(Bit8u)targetDelta] - envTimeSetting;
+ if (newIncrement <= 0) {
+ newIncrement = 1;
+ }
+ }
+ } else {
+ newIncrement = newTarget >= target ? (0x80 | 127) : 127;
+ }
+
+ // FIXME: What's the point of this? It's checked or set to non-zero everywhere above
+ if (newIncrement == 0) {
+ newIncrement = 1;
+ }
+ }
+
+ startRamp((Bit8u)newTarget, (Bit8u)newIncrement, newPhase);
+}
+
+}
diff --git a/audio/softsynth/mt32/TVA.h b/audio/softsynth/mt32/TVA.h
new file mode 100644
index 0000000000..a104fe4c1f
--- /dev/null
+++ b/audio/softsynth/mt32/TVA.h
@@ -0,0 +1,94 @@
+/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher
+ * Copyright (C) 2011 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef MT32EMU_TVA_H
+#define MT32EMU_TVA_H
+
+namespace MT32Emu {
+
+class Part;
+
+// Note that when entering nextPhase(), newPhase is set to phase + 1, and the descriptions/names below refer to
+// newPhase's value.
+enum {
+ // In this phase, the base amp (as calculated in calcBasicAmp()) is targeted with an instant time.
+ // This phase is entered by reset() only if time[0] != 0.
+ TVA_PHASE_BASIC = 0,
+
+ // In this phase, level[0] is targeted within time[0], and velocity potentially affects time
+ TVA_PHASE_ATTACK = 1,
+
+ // In this phase, level[1] is targeted within time[1]
+ TVA_PHASE_2 = 2,
+
+ // In this phase, level[2] is targeted within time[2]
+ TVA_PHASE_3 = 3,
+
+ // In this phase, level[3] is targeted within time[3]
+ TVA_PHASE_4 = 4,
+
+ // In this phase, immediately goes to PHASE_RELEASE unless the poly is set to sustain.
+ // Aborts the partial if level[3] is 0.
+ // Otherwise level[3] is continued, no phase change will occur until some external influence (like pedal release)
+ TVA_PHASE_SUSTAIN = 5,
+
+ // In this phase, 0 is targeted within time[4] (the time calculation is quite different from the other phases)
+ TVA_PHASE_RELEASE = 6,
+
+ // It's PHASE_DEAD, Jim.
+ TVA_PHASE_DEAD = 7
+};
+
+class TVA {
+private:
+ const Partial * const partial;
+ LA32Ramp *ampRamp;
+ const MemParams::System * const system_;
+
+ const Part *part;
+ const TimbreParam::PartialParam *partialParam;
+ const MemParams::PatchTemp *patchTemp;
+ const MemParams::RhythmTemp *rhythmTemp;
+
+ bool playing;
+
+ int biasAmpSubtraction;
+ int veloAmpSubtraction;
+ int keyTimeSubtraction;
+
+ Bit8u target;
+ int phase;
+
+ void startRamp(Bit8u newTarget, Bit8u newIncrement, int newPhase);
+ void end(int newPhase);
+ void nextPhase();
+
+public:
+ TVA(const Partial *partial, LA32Ramp *ampRamp);
+ void reset(const Part *part, const TimbreParam::PartialParam *partialParam, const MemParams::RhythmTemp *rhythmTemp);
+ void handleInterrupt();
+ void recalcSustain();
+ void startDecay();
+ void startAbort();
+
+ bool isPlaying() const;
+ int getPhase() const;
+};
+
+}
+
+#endif /* TVA_H_ */
diff --git a/audio/softsynth/mt32/TVF.cpp b/audio/softsynth/mt32/TVF.cpp
new file mode 100644
index 0000000000..58f72e5a9b
--- /dev/null
+++ b/audio/softsynth/mt32/TVF.cpp
@@ -0,0 +1,230 @@
+/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher
+ * Copyright (C) 2011 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+//#include <cmath>
+
+#include "mt32emu.h"
+#include "mmath.h"
+
+namespace MT32Emu {
+
+// Note that when entering nextPhase(), newPhase is set to phase + 1, and the descriptions/names below refer to
+// newPhase's value.
+enum {
+ // When this is the target phase, level[0] is targeted within time[0]
+ // Note that this phase is always set up in reset(), not nextPhase()
+ PHASE_ATTACK = 1,
+
+ // When this is the target phase, level[1] is targeted within time[1]
+ PHASE_2 = 2,
+
+ // When this is the target phase, level[2] is targeted within time[2]
+ PHASE_3 = 3,
+
+ // When this is the target phase, level[3] is targeted within time[3]
+ PHASE_4 = 4,
+
+ // When this is the target phase, immediately goes to PHASE_RELEASE unless the poly is set to sustain.
+ // Otherwise level[3] is continued with increment 0 - no phase change will occur until some external influence (like pedal release)
+ PHASE_SUSTAIN = 5,
+
+ // 0 is targeted within time[4] (the time calculation is quite different from the other phases)
+ PHASE_RELEASE = 6,
+
+ // 0 is targeted with increment 0 (thus theoretically staying that way forever)
+ PHASE_DONE = 7
+};
+
+static int calcBaseCutoff(const TimbreParam::PartialParam *partialParam, Bit32u basePitch, unsigned int key) {
+ // This table matches the values used by a real LAPC-I.
+ static const Bit8s biasLevelToBiasMult[] = {85, 42, 21, 16, 10, 5, 2, 0, -2, -5, -10, -16, -21, -74, -85};
+ // These values represent unique options with no consistent pattern, so we have to use something like a table in any case.
+ // The table entries, when divided by 21, match approximately what the manual claims:
+ // -1, -1/2, -1/4, 0, 1/8, 1/4, 3/8, 1/2, 5/8, 3/4, 7/8, 1, 5/4, 3/2, 2, s1, s2
+ // Note that the entry for 1/8 is rounded to 2 (from 1/8 * 21 = 2.625), which seems strangely inaccurate compared to the others.
+ static const Bit8s keyfollowMult21[] = {-21, -10, -5, 0, 2, 5, 8, 10, 13, 16, 18, 21, 26, 32, 42, 21, 21};
+ int baseCutoff = keyfollowMult21[partialParam->tvf.keyfollow] - keyfollowMult21[partialParam->wg.pitchKeyfollow];
+ // baseCutoff range now: -63 to 63
+ baseCutoff *= (int)key - 60;
+ // baseCutoff range now: -3024 to 3024
+ int biasPoint = partialParam->tvf.biasPoint;
+ if ((biasPoint & 0x40) == 0) {
+ // biasPoint range here: 0 to 63
+ int bias = biasPoint + 33 - key; // bias range here: -75 to 84
+ if (bias > 0) {
+ bias = -bias; // bias range here: -1 to -84
+ baseCutoff += bias * biasLevelToBiasMult[partialParam->tvf.biasLevel]; // Calculation range: -7140 to 7140
+ // baseCutoff range now: -10164 to 10164
+ }
+ } else {
+ // biasPoint range here: 64 to 127
+ int bias = biasPoint - 31 - key; // bias range here: -75 to 84
+ if (bias < 0) {
+ baseCutoff += bias * biasLevelToBiasMult[partialParam->tvf.biasLevel]; // Calculation range: −6375 to 6375
+ // baseCutoff range now: -9399 to 9399
+ }
+ }
+ // baseCutoff range now: -10164 to 10164
+ baseCutoff += ((partialParam->tvf.cutoff << 4) - 800);
+ // baseCutoff range now: -10964 to 10964
+ if (baseCutoff >= 0) {
+ // FIXME: Potentially bad if baseCutoff ends up below -2056?
+ int pitchDeltaThing = (basePitch >> 4) + baseCutoff - 3584;
+ if (pitchDeltaThing > 0) {
+ baseCutoff -= pitchDeltaThing;
+ }
+ } else if (baseCutoff < -2048) {
+ baseCutoff = -2048;
+ }
+ baseCutoff += 2056;
+ baseCutoff >>= 4; // PORTABILITY NOTE: Hmm... Depends whether it could've been below -2056, but maybe arithmetic shift assumed?
+ if (baseCutoff > 255) {
+ baseCutoff = 255;
+ }
+ return (Bit8u)baseCutoff;
+}
+
+TVF::TVF(const Partial *usePartial, LA32Ramp *useCutoffModifierRamp) :
+ partial(usePartial), cutoffModifierRamp(useCutoffModifierRamp) {
+}
+
+void TVF::startRamp(Bit8u newTarget, Bit8u newIncrement, int newPhase) {
+ target = newTarget;
+ phase = newPhase;
+ cutoffModifierRamp->startRamp(newTarget, newIncrement);
+#if MT32EMU_MONITOR_TVF >= 1
+ partial->getSynth()->printDebug("[+%lu] [Partial %d] TVF,ramp,%d,%d,%d,%d", partial->debugGetSampleNum(), partial->debugGetPartialNum(), newTarget, (newIncrement & 0x80) ? -1 : 1, (newIncrement & 0x7F), newPhase);
+#endif
+}
+
+void TVF::reset(const TimbreParam::PartialParam *newPartialParam, unsigned int basePitch) {
+ partialParam = newPartialParam;
+
+ unsigned int key = partial->getPoly()->getKey();
+ unsigned int velocity = partial->getPoly()->getVelocity();
+
+ Tables *tables = &partial->getSynth()->tables;
+
+ baseCutoff = calcBaseCutoff(newPartialParam, basePitch, key);
+#if MT32EMU_MONITOR_TVF >= 1
+ partial->getSynth()->printDebug("[+%lu] [Partial %d] TVF,base,%d", partial->debugGetSampleNum(), partial->debugGetPartialNum(), baseCutoff);
+#endif
+
+ int newLevelMult = velocity * newPartialParam->tvf.envVeloSensitivity;
+ newLevelMult >>= 6;
+ newLevelMult += 109 - newPartialParam->tvf.envVeloSensitivity;
+ newLevelMult += ((signed)key - 60) >> (4 - newPartialParam->tvf.envDepthKeyfollow);
+ if (newLevelMult < 0) {
+ newLevelMult = 0;
+ }
+ newLevelMult *= newPartialParam->tvf.envDepth;
+ newLevelMult >>= 6;
+ if (newLevelMult > 255) {
+ newLevelMult = 255;
+ }
+ levelMult = newLevelMult;
+
+ if (newPartialParam->tvf.envTimeKeyfollow != 0) {
+ keyTimeSubtraction = ((signed)key - 60) >> (5 - newPartialParam->tvf.envTimeKeyfollow);
+ } else {
+ keyTimeSubtraction = 0;
+ }
+
+ int newTarget = (newLevelMult * newPartialParam->tvf.envLevel[0]) >> 8;
+ int envTimeSetting = newPartialParam->tvf.envTime[0] - keyTimeSubtraction;
+ int newIncrement;
+ if (envTimeSetting <= 0) {
+ newIncrement = (0x80 | 127);
+ } else {
+ newIncrement = tables->envLogarithmicTime[newTarget] - envTimeSetting;
+ if (newIncrement <= 0) {
+ newIncrement = 1;
+ }
+ }
+ cutoffModifierRamp->reset();
+ startRamp(newTarget, newIncrement, PHASE_2 - 1);
+}
+
+Bit8u TVF::getBaseCutoff() const {
+ return baseCutoff;
+}
+
+void TVF::handleInterrupt() {
+ nextPhase();
+}
+
+void TVF::startDecay() {
+ if (phase >= PHASE_RELEASE) {
+ return;
+ }
+ if (partialParam->tvf.envTime[4] == 0) {
+ startRamp(0, 1, PHASE_DONE - 1);
+ } else {
+ startRamp(0, -partialParam->tvf.envTime[4], PHASE_DONE - 1);
+ }
+}
+
+void TVF::nextPhase() {
+ Tables *tables = &partial->getSynth()->tables;
+ int newPhase = phase + 1;
+
+ switch (newPhase) {
+ case PHASE_DONE:
+ startRamp(0, 0, newPhase);
+ return;
+ case PHASE_SUSTAIN:
+ case PHASE_RELEASE:
+ // FIXME: Afaict newPhase should never be PHASE_RELEASE here. And if it were, this is an odd way to handle it.
+ if (!partial->getPoly()->canSustain()) {
+ phase = newPhase; // FIXME: Correct?
+ startDecay(); // FIXME: This should actually start decay even if phase is already 6. Does that matter?
+ return;
+ }
+ startRamp((levelMult * partialParam->tvf.envLevel[3]) >> 8, 0, newPhase);
+ return;
+ }
+
+ int envPointIndex = phase;
+ int envTimeSetting = partialParam->tvf.envTime[envPointIndex] - keyTimeSubtraction;
+
+ int newTarget = (levelMult * partialParam->tvf.envLevel[envPointIndex]) >> 8;
+ int newIncrement;
+ if (envTimeSetting > 0) {
+ int targetDelta = newTarget - target;
+ if (targetDelta == 0) {
+ if (newTarget == 0) {
+ targetDelta = 1;
+ newTarget = 1;
+ } else {
+ targetDelta = -1;
+ newTarget--;
+ }
+ }
+ newIncrement = tables->envLogarithmicTime[targetDelta < 0 ? -targetDelta : targetDelta] - envTimeSetting;
+ if (newIncrement <= 0) {
+ newIncrement = 1;
+ }
+ if (targetDelta < 0) {
+ newIncrement |= 0x80;
+ }
+ } else {
+ newIncrement = newTarget >= target ? (0x80 | 127) : 127;
+ }
+ startRamp(newTarget, newIncrement, newPhase);
+}
+
+}
diff --git a/audio/softsynth/mt32/TVF.h b/audio/softsynth/mt32/TVF.h
new file mode 100644
index 0000000000..490d8de504
--- /dev/null
+++ b/audio/softsynth/mt32/TVF.h
@@ -0,0 +1,54 @@
+/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher
+ * Copyright (C) 2011 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef MT32EMU_TVF_H
+#define MT32EMU_TVF_H
+
+namespace MT32Emu {
+
+class TVF {
+private:
+ const Partial * const partial;
+ LA32Ramp *cutoffModifierRamp;
+ const TimbreParam::PartialParam *partialParam;
+
+ Bit8u baseCutoff;
+ int keyTimeSubtraction;
+ unsigned int levelMult;
+
+ Bit8u target;
+ unsigned int phase;
+
+ void startRamp(Bit8u newTarget, Bit8u newIncrement, int newPhase);
+ void nextPhase();
+
+public:
+ TVF(const Partial *partial, LA32Ramp *cutoffModifierRamp);
+ void reset(const TimbreParam::PartialParam *partialParam, Bit32u basePitch);
+ // Returns the base cutoff (without envelope modification).
+ // The base cutoff is calculated when reset() is called and remains static
+ // for the lifetime of the partial.
+ // Barring bugs, the number returned is confirmed accurate
+ // (based on specs from Mok).
+ Bit8u getBaseCutoff() const;
+ void handleInterrupt();
+ void startDecay();
+};
+
+}
+
+#endif
diff --git a/audio/softsynth/mt32/TVP.cpp b/audio/softsynth/mt32/TVP.cpp
new file mode 100644
index 0000000000..0b339e8d71
--- /dev/null
+++ b/audio/softsynth/mt32/TVP.cpp
@@ -0,0 +1,321 @@
+/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher
+ * Copyright (C) 2011 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+//#include <cmath>
+//#include <cstdlib>
+
+#include "mt32emu.h"
+
+namespace MT32Emu {
+
+// FIXME: Add Explanation
+static Bit16u lowerDurationToDivisor[] = {34078, 37162, 40526, 44194, 48194, 52556, 57312, 62499};
+
+// These values represent unique options with no consistent pattern, so we have to use something like a table in any case.
+// The table matches exactly what the manual claims (when divided by 8192):
+// -1, -1/2, -1/4, 0, 1/8, 1/4, 3/8, 1/2, 5/8, 3/4, 7/8, 1, 5/4, 3/2, 2, s1, s2
+// ...except for the last two entries, which are supposed to be "1 cent above 1" and "2 cents above 1", respectively. They can only be roughly approximated with this integer math.
+static Bit16s pitchKeyfollowMult[] = {-8192, -4096, -2048, 0, 1024, 2048, 3072, 4096, 5120, 6144, 7168, 8192, 10240, 12288, 16384, 8198, 8226};
+
+// Note: Keys < 60 use keyToPitchTable[60 - key], keys >= 60 use keyToPitchTable[key - 60].
+// FIXME: This table could really be shorter, since we never use e.g. key 127.
+static Bit16u keyToPitchTable[] = {
+ 0, 341, 683, 1024, 1365, 1707, 2048, 2389,
+ 2731, 3072, 3413, 3755, 4096, 4437, 4779, 5120,
+ 5461, 5803, 6144, 6485, 6827, 7168, 7509, 7851,
+ 8192, 8533, 8875, 9216, 9557, 9899, 10240, 10581,
+ 10923, 11264, 11605, 11947, 12288, 12629, 12971, 13312,
+ 13653, 13995, 14336, 14677, 15019, 15360, 15701, 16043,
+ 16384, 16725, 17067, 17408, 17749, 18091, 18432, 18773,
+ 19115, 19456, 19797, 20139, 20480, 20821, 21163, 21504,
+ 21845, 22187, 22528, 22869
+};
+
+TVP::TVP(const Partial *usePartial) :
+ partial(usePartial), system_(&usePartial->getSynth()->mt32ram.system) {
+ unsigned int sampleRate = usePartial->getSynth()->myProp.sampleRate;
+ // We want to do processing 4000 times per second. FIXME: This is pretty arbitrary.
+ maxCounter = sampleRate / 4000;
+ // The timer runs at 500kHz. We only need to bother updating it every maxCounter samples, before we do processing.
+ // This is how much to increment it by every maxCounter samples.
+ processTimerIncrement = 500000 * maxCounter / sampleRate;
+}
+
+static Bit16s keyToPitch(unsigned int key) {
+ // We're using a table to do: return round_to_nearest_or_even((key - 60) * (4096.0 / 12.0))
+ // Banker's rounding is just slightly annoying to do in C++
+ int k = (int)key;
+ Bit16s pitch = keyToPitchTable[abs(k - 60)];
+ return key < 60 ? -pitch : pitch;
+}
+
+static inline Bit32s coarseToPitch(Bit8u coarse) {
+ return (coarse - 36) * 4096 / 12; // One semitone per coarse offset
+}
+
+static inline Bit32s fineToPitch(Bit8u fine) {
+ return (fine - 50) * 4096 / 1200; // One cent per fine offset
+}
+
+static Bit32u calcBasePitch(const Partial *partial, const TimbreParam::PartialParam *partialParam, const MemParams::PatchTemp *patchTemp, unsigned int key) {
+ Bit32s basePitch = keyToPitch(key);
+ basePitch = (basePitch * pitchKeyfollowMult[partialParam->wg.pitchKeyfollow]) >> 13; // PORTABILITY NOTE: Assumes arithmetic shift
+ basePitch += coarseToPitch(partialParam->wg.pitchCoarse);
+ basePitch += fineToPitch(partialParam->wg.pitchFine);
+ // NOTE:Mok: This is done on MT-32, but not LAPC-I:
+ //pitch += coarseToPitch(patchTemp->patch.keyShift + 12);
+ basePitch += fineToPitch(patchTemp->patch.fineTune);
+
+ const ControlROMPCMStruct *controlROMPCMStruct = partial->getControlROMPCMStruct();
+ if (controlROMPCMStruct != NULL) {
+ basePitch += (Bit32s)((((Bit32s)controlROMPCMStruct->pitchMSB) << 8) | (Bit32s)controlROMPCMStruct->pitchLSB);
+ } else {
+ if ((partialParam->wg.waveform & 1) == 0) {
+ basePitch += 37133; // This puts Middle C at around 261.64Hz (assuming no other modifications, masterTune of 64, etc.)
+ } else {
+ // Sawtooth waves are effectively double the frequency of square waves.
+ // Thus we add 4096 less than for square waves here, which results in halving the frequency.
+ basePitch += 33037;
+ }
+ }
+ if (basePitch < 0) {
+ basePitch = 0;
+ }
+ if (basePitch > 59392) {
+ basePitch = 59392;
+ }
+ return (Bit32u)basePitch;
+}
+
+static Bit32u calcVeloMult(Bit8u veloSensitivity, unsigned int velocity) {
+ if (veloSensitivity == 0 || veloSensitivity > 3) {
+ // Note that on CM-32L/LAPC-I veloSensitivity is never > 3, since it's clipped to 3 by the max tables.
+ return 21845; // aka floor(4096 / 12 * 64), aka ~64 semitones
+ }
+ // When velocity is 127, the multiplier is 21845, aka ~64 semitones (regardless of veloSensitivity).
+ // The lower the velocity, the lower the multiplier. The veloSensitivity determines the amount decreased per velocity value.
+ // The minimum multiplier (with velocity 0, veloSensitivity 3) is 170 (~half a semitone).
+ Bit32u veloMult = 32768;
+ veloMult -= (127 - velocity) << (5 + veloSensitivity);
+ veloMult *= 21845;
+ veloMult >>= 15;
+ return veloMult;
+}
+
+static Bit32s calcTargetPitchOffsetWithoutLFO(const TimbreParam::PartialParam *partialParam, int levelIndex, unsigned int velocity) {
+ int veloMult = calcVeloMult(partialParam->pitchEnv.veloSensitivity, velocity);
+ int targetPitchOffsetWithoutLFO = partialParam->pitchEnv.level[levelIndex] - 50;
+ targetPitchOffsetWithoutLFO = (Bit32s)(targetPitchOffsetWithoutLFO * veloMult) >> (16 - partialParam->pitchEnv.depth); // PORTABILITY NOTE: Assumes arithmetic shift
+ return targetPitchOffsetWithoutLFO;
+}
+
+void TVP::reset(const Part *usePart, const TimbreParam::PartialParam *usePartialParam) {
+ part = usePart;
+ partialParam = usePartialParam;
+ patchTemp = part->getPatchTemp();
+
+ unsigned int key = partial->getPoly()->getKey();
+ unsigned int velocity = partial->getPoly()->getVelocity();
+
+ // FIXME: We're using a per-TVP timer instead of a system-wide one for convenience.
+ timeElapsed = 0;
+
+ basePitch = calcBasePitch(partial, partialParam, patchTemp, key);
+ currentPitchOffset = calcTargetPitchOffsetWithoutLFO(partialParam, 0, velocity);
+ targetPitchOffsetWithoutLFO = currentPitchOffset;
+ phase = 0;
+
+ if (partialParam->pitchEnv.timeKeyfollow) {
+ timeKeyfollowSubtraction = (key - 60) >> (5 - partialParam->pitchEnv.timeKeyfollow); // PORTABILITY NOTE: Assumes arithmetic shift
+ } else {
+ timeKeyfollowSubtraction = 0;
+ }
+ lfoPitchOffset = 0;
+ counter = 0;
+ pitch = basePitch;
+
+ // These don't really need to be initialised, but it aids debugging.
+ pitchOffsetChangePerBigTick = 0;
+ targetPitchOffsetReachedBigTick = 0;
+ shifts = 0;
+}
+
+Bit32u TVP::getBasePitch() const {
+ return basePitch;
+}
+
+void TVP::updatePitch() {
+ Bit32s newPitch = basePitch + currentPitchOffset;
+ if (!partial->isPCM() || (partial->getControlROMPCMStruct()->len & 0x01) == 0) { // FIXME: Use !partial->pcmWaveEntry->unaffectedByMasterTune instead
+ // FIXME: masterTune recalculation doesn't really happen here, and there are various bugs not yet emulated
+ // 171 is ~half a semitone.
+ newPitch += ((system_->masterTune - 64) * 171) >> 6; // PORTABILITY NOTE: Assumes arithmetic shift.
+ }
+ if ((partialParam->wg.pitchBenderEnabled & 1) != 0) {
+ newPitch += part->getPitchBend();
+ }
+ if (newPitch < 0) {
+ newPitch = 0;
+ }
+ if (newPitch > 59392) {
+ newPitch = 59392;
+ }
+ pitch = (Bit16u)newPitch;
+
+ // FIXME: We're doing this here because that's what the CM-32L does - we should probably move this somewhere more appropriate in future.
+ partial->tva->recalcSustain();
+}
+
+void TVP::targetPitchOffsetReached() {
+ currentPitchOffset = targetPitchOffsetWithoutLFO + lfoPitchOffset;
+
+ switch (phase) {
+ case 3:
+ case 4:
+ {
+ int newLFOPitchOffset = (part->getModulation() * partialParam->pitchLFO.modSensitivity) >> 7;
+ newLFOPitchOffset = (newLFOPitchOffset + partialParam->pitchLFO.depth) << 1;
+ if (pitchOffsetChangePerBigTick > 0) {
+ // Go in the opposite direction to last time
+ newLFOPitchOffset = -newLFOPitchOffset;
+ }
+ lfoPitchOffset = newLFOPitchOffset;
+ int targetPitchOffset = targetPitchOffsetWithoutLFO + lfoPitchOffset;
+ setupPitchChange(targetPitchOffset, 101 - partialParam->pitchLFO.rate);
+ updatePitch();
+ break;
+ }
+ case 6:
+ updatePitch();
+ break;
+ default:
+ nextPhase();
+ }
+}
+
+void TVP::nextPhase() {
+ phase++;
+ int envIndex = phase == 6 ? 4 : phase;
+
+ targetPitchOffsetWithoutLFO = calcTargetPitchOffsetWithoutLFO(partialParam, envIndex, partial->getPoly()->getVelocity()); // pitch we'll reach at the end
+
+ int changeDuration = partialParam->pitchEnv.time[envIndex - 1];
+ changeDuration -= timeKeyfollowSubtraction;
+ if (changeDuration > 0) {
+ setupPitchChange(targetPitchOffsetWithoutLFO, changeDuration); // changeDuration between 0 and 112 now
+ updatePitch();
+ } else {
+ targetPitchOffsetReached();
+ }
+}
+
+// Shifts val to the left until bit 31 is 1 and returns the number of shifts
+static Bit8u normalise(Bit32u &val) {
+ Bit8u leftShifts;
+ for (leftShifts = 0; leftShifts < 31; leftShifts++) {
+ if ((val & 0x80000000) != 0) {
+ break;
+ }
+ val = val << 1;
+ }
+ return leftShifts;
+}
+
+void TVP::setupPitchChange(int targetPitchOffset, Bit8u changeDuration) {
+ bool negativeDelta = targetPitchOffset < currentPitchOffset;
+ Bit32s pitchOffsetDelta = targetPitchOffset - currentPitchOffset;
+ if (pitchOffsetDelta > 32767 || pitchOffsetDelta < -32768) {
+ pitchOffsetDelta = 32767;
+ }
+ if (negativeDelta) {
+ pitchOffsetDelta = -pitchOffsetDelta;
+ }
+ // We want to maximise the number of bits of the Bit16s "pitchOffsetChangePerBigTick" we use in order to get the best possible precision later
+ Bit32u absPitchOffsetDelta = pitchOffsetDelta << 16;
+ Bit8u normalisationShifts = normalise(absPitchOffsetDelta); // FIXME: Double-check: normalisationShifts is usually between 0 and 15 here, unless the delta is 0, in which case it's 31
+ absPitchOffsetDelta = absPitchOffsetDelta >> 1; // Make room for the sign bit
+
+ changeDuration--; // changeDuration's now between 0 and 111
+ unsigned int upperDuration = changeDuration >> 3; // upperDuration's now between 0 and 13
+ shifts = normalisationShifts + upperDuration + 2;
+ Bit16u divisor = lowerDurationToDivisor[changeDuration & 7];
+ Bit16s newPitchOffsetChangePerBigTick = ((absPitchOffsetDelta & 0xFFFF0000) / divisor) >> 1; // Result now fits within 15 bits. FIXME: Check nothing's getting sign-extended incorrectly
+ if (negativeDelta) {
+ newPitchOffsetChangePerBigTick = -newPitchOffsetChangePerBigTick;
+ }
+ pitchOffsetChangePerBigTick = newPitchOffsetChangePerBigTick;
+
+ int currentBigTick = timeElapsed >> 8;
+ int durationInBigTicks = divisor >> (12 - upperDuration);
+ if (durationInBigTicks > 32767) {
+ durationInBigTicks = 32767;
+ }
+ // The result of the addition may exceed 16 bits, but wrapping is fine and intended here.
+ targetPitchOffsetReachedBigTick = currentBigTick + durationInBigTicks;
+}
+
+void TVP::startDecay() {
+ phase = 5;
+ lfoPitchOffset = 0;
+ targetPitchOffsetReachedBigTick = timeElapsed >> 8; // FIXME: Afaict there's no good reason for this - check
+}
+
+Bit16u TVP::nextPitch() {
+ // FIXME: Write explanation of counter and time increment
+ if (counter == 0) {
+ timeElapsed += processTimerIncrement;
+ timeElapsed = timeElapsed & 0x00FFFFFF;
+ process();
+ }
+ counter = (counter + 1) % maxCounter;
+ return pitch;
+}
+
+void TVP::process() {
+ if (phase == 0) {
+ targetPitchOffsetReached();
+ return;
+ }
+ if (phase == 5) {
+ nextPhase();
+ return;
+ }
+ if (phase > 7) {
+ updatePitch();
+ return;
+ }
+
+ Bit16s negativeBigTicksRemaining = (timeElapsed >> 8) - targetPitchOffsetReachedBigTick;
+ if (negativeBigTicksRemaining >= 0) {
+ // We've reached the time for a phase change
+ targetPitchOffsetReached();
+ return;
+ }
+ // FIXME: Write explanation for this stuff
+ int rightShifts = shifts;
+ if (rightShifts > 13) {
+ rightShifts -= 13;
+ negativeBigTicksRemaining = negativeBigTicksRemaining >> rightShifts; // PORTABILITY NOTE: Assumes arithmetic shift
+ rightShifts = 13;
+ }
+ int newResult = ((Bit32s)(negativeBigTicksRemaining * pitchOffsetChangePerBigTick)) >> rightShifts; // PORTABILITY NOTE: Assumes arithmetic shift
+ newResult += targetPitchOffsetWithoutLFO + lfoPitchOffset;
+ currentPitchOffset = newResult;
+ updatePitch();
+}
+
+}
diff --git a/audio/softsynth/mt32/TVP.h b/audio/softsynth/mt32/TVP.h
new file mode 100644
index 0000000000..f6f62f8d39
--- /dev/null
+++ b/audio/softsynth/mt32/TVP.h
@@ -0,0 +1,67 @@
+/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher
+ * Copyright (C) 2011 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef MT32EMU_TVP_H
+#define MT32EMU_TVP_H
+
+namespace MT32Emu {
+
+class TVP {
+private:
+ const Partial * const partial;
+ const MemParams::System * const system_; // FIXME: Only necessary because masterTune calculation is done in the wrong place atm.
+
+ const Part *part;
+ const TimbreParam::PartialParam *partialParam;
+ const MemParams::PatchTemp *patchTemp;
+
+ int maxCounter;
+ int processTimerIncrement;
+ int counter;
+ Bit32u timeElapsed;
+
+ int phase;
+ Bit32u basePitch;
+ Bit32s targetPitchOffsetWithoutLFO;
+ Bit32s currentPitchOffset;
+
+ Bit16s lfoPitchOffset;
+ // In range -12 - 36
+ Bit8s timeKeyfollowSubtraction;
+
+ Bit16s pitchOffsetChangePerBigTick;
+ Bit16u targetPitchOffsetReachedBigTick;
+ unsigned int shifts;
+
+ Bit16u pitch;
+
+ void updatePitch();
+ void setupPitchChange(int targetPitchOffset, Bit8u changeDuration);
+ void targetPitchOffsetReached();
+ void nextPhase();
+ void process();
+public:
+ TVP(const Partial *partial);
+ void reset(const Part *part, const TimbreParam::PartialParam *partialParam);
+ Bit32u getBasePitch() const;
+ Bit16u nextPitch();
+ void startDecay();
+};
+
+}
+
+#endif
diff --git a/audio/softsynth/mt32/Tables.cpp b/audio/softsynth/mt32/Tables.cpp
new file mode 100644
index 0000000000..c9bd40b7a4
--- /dev/null
+++ b/audio/softsynth/mt32/Tables.cpp
@@ -0,0 +1,119 @@
+/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher
+ * Copyright (C) 2011 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+//#include <cmath>
+//#include <cstdlib>
+//#include <cstring>
+
+#include "mt32emu.h"
+#include "mmath.h"
+
+using namespace MT32Emu;
+
+Tables::Tables() {
+ initialised = false;
+}
+
+void Tables::init() {
+ if (initialised) {
+ return;
+ }
+ initialised = true;
+
+ int lf;
+ for (lf = 0; lf <= 100; lf++) {
+ // CONFIRMED:KG: This matches a ROM table found by Mok
+ float fVal = (2.0f - LOG10F((float)lf + 1.0f)) * 128.0f;
+ int val = (int)(fVal + 1.0);
+ if (val > 255) {
+ val = 255;
+ }
+ levelToAmpSubtraction[lf] = (Bit8u)val;
+ }
+
+ envLogarithmicTime[0] = 64;
+ for (lf = 1; lf <= 255; lf++) {
+ // CONFIRMED:KG: This matches a ROM table found by Mok
+ envLogarithmicTime[lf] = (Bit8u)ceil(64.0f + LOG2F((float)lf) * 8.0f);
+ }
+
+#ifdef EMULATE_LAPC_I // Dummy #ifdef - we'll have runtime emulation mode selection in future.
+ // CONFIRMED: Based on a table found by Mok in the LAPC-I control ROM
+ // Note that this matches the MT-32 table, but with the values clamped to a maximum of 8.
+ memset(masterVolToAmpSubtraction, 8, 71);
+ memset(masterVolToAmpSubtraction + 71, 7, 3);
+ memset(masterVolToAmpSubtraction + 74, 6, 4);
+ memset(masterVolToAmpSubtraction + 78, 5, 3);
+ memset(masterVolToAmpSubtraction + 81, 4, 4);
+ memset(masterVolToAmpSubtraction + 85, 3, 3);
+ memset(masterVolToAmpSubtraction + 88, 2, 4);
+ memset(masterVolToAmpSubtraction + 92, 1, 4);
+ memset(masterVolToAmpSubtraction + 96, 0, 5);
+#else
+ // CONFIRMED: Based on a table found by Mok in the MT-32 control ROM
+ masterVolToAmpSubtraction[0] = 255;
+ for (int masterVol = 1; masterVol <= 100; masterVol++) {
+ masterVolToAmpSubtraction[masterVol] = (int)(106.31 - 16.0f * LOG2F((float)masterVol));
+ }
+#endif
+
+ for (int i = 0; i <= 100; i++) {
+ pulseWidth100To255[i] = (int)(i * 255 / 100.0f + 0.5f);
+ //synth->printDebug("%d: %d", i, pulseWidth100To255[i]);
+ }
+
+ // Ratio of negative segment to wave length
+ for (int i = 0; i < 128; i++) {
+ // Formula determined from sample analysis.
+ float pt = 0.5f / 127.0f * i;
+ pulseLenFactor[i] = (1.241857812f - pt) * pt; // seems to be 2 ^ (5 / 16) = 1.241857812f
+ }
+
+ for (int i = 0; i < 65536; i++) {
+ // Aka (slightly slower): EXP2F(pitchVal / 4096.0f - 16.0f) * 32000.0f
+ pitchToFreq[i] = EXP2F(i / 4096.0f - 1.034215715f);
+ }
+
+ // found from sample analysis
+ for (int i = 0; i < 1024; i++) {
+ cutoffToCosineLen[i] = EXP2F(i / -128.0f);
+ }
+
+ // found from sample analysis
+ for (int i = 0; i < 1024; i++) {
+ cutoffToFilterAmp[i] = EXP2F(-0.125f * (128.0f - i / 8.0f));
+ }
+
+ // found from sample analysis
+ for (int i = 0; i < 32; i++) {
+ resAmpMax[i] = EXP2F(1.0f - (32 - i) / 4.0f);
+ }
+
+ // found from sample analysis
+ resAmpFadeFactor[7] = 1.0f / 8.0f;
+ resAmpFadeFactor[6] = 2.0f / 8.0f;
+ resAmpFadeFactor[5] = 3.0f / 8.0f;
+ resAmpFadeFactor[4] = 5.0f / 8.0f;
+ resAmpFadeFactor[3] = 8.0f / 8.0f;
+ resAmpFadeFactor[2] = 12.0f / 8.0f;
+ resAmpFadeFactor[1] = 16.0f / 8.0f;
+ resAmpFadeFactor[0] = 31.0f / 8.0f;
+
+ for (int i = 0; i < 5120; i++) {
+ sinf10[i] = sin(FLOAT_PI * i / 2048.0f);
+ }
+}
diff --git a/audio/softsynth/mt32/Tables.h b/audio/softsynth/mt32/Tables.h
new file mode 100644
index 0000000000..a2b5ff5d56
--- /dev/null
+++ b/audio/softsynth/mt32/Tables.h
@@ -0,0 +1,64 @@
+/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher
+ * Copyright (C) 2011 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef MT32EMU_TABLES_H
+#define MT32EMU_TABLES_H
+
+namespace MT32Emu {
+
+const int MIDDLEC = 60;
+
+class Synth;
+
+class Tables {
+ bool initialised;
+
+public:
+ // Constant LUTs
+
+ // CONFIRMED: This is used to convert several parameters to amp-modifying values in the TVA envelope:
+ // - PatchTemp.outputLevel
+ // - RhythmTemp.outlevel
+ // - PartialParam.tva.level
+ // - expression
+ // It's used to determine how much to subtract from the amp envelope's target value
+ Bit8u levelToAmpSubtraction[101];
+
+ // CONFIRMED: ...
+ Bit8u envLogarithmicTime[256];
+
+ // CONFIRMED: ...
+ Bit8u masterVolToAmpSubtraction[101];
+
+ // CONFIRMED:
+ Bit8u pulseWidth100To255[101];
+
+ float pulseLenFactor[128];
+ float pitchToFreq[65536];
+ float cutoffToCosineLen[1024];
+ float cutoffToFilterAmp[1024];
+ float resAmpMax[32];
+ float resAmpFadeFactor[8];
+ float sinf10[5120];
+
+ Tables();
+ void init();
+};
+
+}
+
+#endif
diff --git a/audio/softsynth/mt32/freeverb.cpp b/audio/softsynth/mt32/freeverb.cpp
index 67f065c20e..de8f2632cb 100644
--- a/audio/softsynth/mt32/freeverb.cpp
+++ b/audio/softsynth/mt32/freeverb.cpp
@@ -1,245 +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.
- *
- */
-
-// Comb filter implementation
+// Allpass filter implementation
//
-// Written by
+// Written by Jezar at Dreampoint, June 2000
// http://www.dreampoint.co.uk
// This code is public domain
-#include "audio/softsynth/mt32/freeverb.h"
+#include "freeverb.h"
-comb::comb() {
- filterstore = 0;
+allpass::allpass()
+{
bufidx = 0;
}
-void comb::setbuffer(float *buf, int size) {
+void allpass::setbuffer(float *buf, int size)
+{
buffer = buf;
bufsize = size;
}
-void comb::mute() {
- for (int i = 0; i < bufsize; i++)
- buffer[i] = 0;
-}
-
-void comb::setdamp(float val) {
- damp1 = val;
- damp2 = 1 - val;
-}
-
-float comb::getdamp() {
- return damp1;
+void allpass::mute()
+{
+ for (int i=0; i<bufsize; i++)
+ buffer[i]=0;
}
-void comb::setfeedback(float val) {
+void allpass::setfeedback(float val)
+{
feedback = val;
}
-float comb::getfeedback() {
+float allpass::getfeedback()
+{
return feedback;
}
-// Allpass filter implementation
+void allpass::deletebuffer()
+{
+ delete[] buffer;
+ buffer = 0;
+}
+// Comb filter implementation
+//
+// Written by Jezar at Dreampoint, June 2000
+// http://www.dreampoint.co.uk
+// This code is public domain
-allpass::allpass() {
+comb::comb()
+{
+ filterstore = 0;
bufidx = 0;
}
-void allpass::setbuffer(float *buf, int size) {
+void comb::setbuffer(float *buf, int size)
+{
buffer = buf;
bufsize = size;
}
-void allpass::mute() {
- for (int i = 0; i < bufsize; i++)
- buffer[i] = 0;
+void comb::mute()
+{
+ for (int i=0; i<bufsize; i++)
+ buffer[i]=0;
+}
+
+void comb::setdamp(float val)
+{
+ damp1 = val;
+ damp2 = 1-val;
+}
+
+float comb::getdamp()
+{
+ return damp1;
}
-void allpass::setfeedback(float val) {
+void comb::setfeedback(float val)
+{
feedback = val;
}
-float allpass::getfeedback() {
+float comb::getfeedback()
+{
return feedback;
}
+void comb::deletebuffer()
+{
+ delete[] buffer;
+ buffer = 0;
+}
// Reverb model implementation
+//
+// Written by Jezar at Dreampoint, June 2000
+// Modifications by Jerome Fisher, 2009, 2011
+// http://www.dreampoint.co.uk
+// This code is public domain
-revmodel::revmodel() {
- // Tie the components to their buffers
- combL[0].setbuffer(bufcombL1,combtuningL1);
- combR[0].setbuffer(bufcombR1,combtuningR1);
- combL[1].setbuffer(bufcombL2,combtuningL2);
- combR[1].setbuffer(bufcombR2,combtuningR2);
- combL[2].setbuffer(bufcombL3,combtuningL3);
- combR[2].setbuffer(bufcombR3,combtuningR3);
- combL[3].setbuffer(bufcombL4,combtuningL4);
- combR[3].setbuffer(bufcombR4,combtuningR4);
- combL[4].setbuffer(bufcombL5,combtuningL5);
- combR[4].setbuffer(bufcombR5,combtuningR5);
- combL[5].setbuffer(bufcombL6,combtuningL6);
- combR[5].setbuffer(bufcombR6,combtuningR6);
- combL[6].setbuffer(bufcombL7,combtuningL7);
- combR[6].setbuffer(bufcombR7,combtuningR7);
- combL[7].setbuffer(bufcombL8,combtuningL8);
- combR[7].setbuffer(bufcombR8,combtuningR8);
- allpassL[0].setbuffer(bufallpassL1,allpasstuningL1);
- allpassR[0].setbuffer(bufallpassR1,allpasstuningR1);
- allpassL[1].setbuffer(bufallpassL2,allpasstuningL2);
- allpassR[1].setbuffer(bufallpassR2,allpasstuningR2);
- allpassL[2].setbuffer(bufallpassL3,allpasstuningL3);
- allpassR[2].setbuffer(bufallpassR3,allpasstuningR3);
- allpassL[3].setbuffer(bufallpassL4,allpasstuningL4);
- allpassR[3].setbuffer(bufallpassR4,allpasstuningR4);
+revmodel::revmodel(float scaletuning)
+{
+ int i;
+ int bufsize;
+
+ // Allocate buffers for the components
+ for (i = 0; i < numcombs; i++) {
+ bufsize = int(scaletuning * combtuning[i]);
+ combL[i].setbuffer(new float[bufsize], bufsize);
+ bufsize += int(scaletuning * stereospread);
+ combR[i].setbuffer(new float[bufsize], bufsize);
+ }
+ for (i = 0; i < numallpasses; i++) {
+ bufsize = int(scaletuning * allpasstuning[i]);
+ allpassL[i].setbuffer(new float[bufsize], bufsize);
+ allpassL[i].setfeedback(0.5f);
+ bufsize += int(scaletuning * stereospread);
+ allpassR[i].setbuffer(new float[bufsize], bufsize);
+ allpassR[i].setfeedback(0.5f);
+ }
// Set default values
- allpassL[0].setfeedback(0.5f);
- allpassR[0].setfeedback(0.5f);
- allpassL[1].setfeedback(0.5f);
- allpassR[1].setfeedback(0.5f);
- allpassL[2].setfeedback(0.5f);
- allpassR[2].setfeedback(0.5f);
- allpassL[3].setfeedback(0.5f);
- allpassR[3].setfeedback(0.5f);
- setmode(initialmode);
- setwet(initialwet);
- setroomsize(initialroom);
- setdry(initialdry);
- setdamp(initialdamp);
- setwidth(initialwidth);
+ dry = initialdry;
+ wet = initialwet*scalewet;
+ damp = initialdamp*scaledamp;
+ roomsize = (initialroom*scaleroom) + offsetroom;
+ width = initialwidth;
+ mode = initialmode;
+ update();
// Buffer will be full of rubbish - so we MUST mute them
mute();
}
-void revmodel::mute() {
+revmodel::~revmodel()
+{
+ int i;
+
+ for (i = 0; i < numcombs; i++) {
+ combL[i].deletebuffer();
+ combR[i].deletebuffer();
+ }
+ for (i = 0; i < numallpasses; i++) {
+ allpassL[i].deletebuffer();
+ allpassR[i].deletebuffer();
+ }
+}
+
+void revmodel::mute()
+{
int i;
if (getmode() >= freezemode)
return;
- for (i = 0; i < numcombs; i++) {
+ for (i=0;i<numcombs;i++)
+ {
combL[i].mute();
combR[i].mute();
}
-
- for (i = 0; i < numallpasses; i++) {
+ for (i=0;i<numallpasses;i++)
+ {
allpassL[i].mute();
allpassR[i].mute();
}
-}
-
-void revmodel::processreplace(float *inputL, float *inputR, float *outputL, float *outputR, long numsamples, int skip) {
- float outL, outR, input;
-
- while (numsamples-- > 0) {
- int i;
-
- outL = outR = 0;
- input = (*inputL + *inputR) * gain;
-
- // Accumulate comb filters in parallel
- for (i = 0; i < numcombs; i++) {
- outL += combL[i].process(input);
- outR += combR[i].process(input);
- }
- // Feed through allpasses in series
- for (i = 0; i < numallpasses; i++) {
- outL = allpassL[i].process(outL);
- outR = allpassR[i].process(outR);
- }
-
- // Calculate output REPLACING anything already there
- *outputL = outL * wet1 + outR * wet2 + *inputL * dry;
- *outputR = outR * wet1 + outL * wet2 + *inputR * dry;
-
- // Increment sample pointers, allowing for interleave (if any)
- inputL += skip;
- inputR += skip;
- outputL += skip;
- outputR += skip;
- }
+ // Init LPF history
+ filtprev1 = 0;
+ filtprev2 = 0;
}
-void revmodel::processmix(float *inputL, float *inputR, float *outputL, float *outputR, long numsamples, int skip) {
- float outL, outR, input;
+void revmodel::process(const float *inputL, const float *inputR, float *outputL, float *outputR, long numsamples)
+{
+ float outL,outR,input;
- while (numsamples-- > 0) {
+ while (numsamples-- > 0)
+ {
int i;
outL = outR = 0;
input = (*inputL + *inputR) * gain;
+ // Implementation of 2-stage IIR single-pole low-pass filter
+ // found at the entrance of reverb processing on real devices
+ filtprev1 += (input - filtprev1) * filtval;
+ filtprev2 += (filtprev1 - filtprev2) * filtval;
+ input = filtprev2;
+
+ int s = -1;
// Accumulate comb filters in parallel
- for (i = 0; i < numcombs; i++) {
- outL += combL[i].process(input);
- outR += combR[i].process(input);
+ for (i=0; i<numcombs; i++)
+ {
+ outL += s * combL[i].process(input);
+ outR += s * combR[i].process(input);
+ s = -s;
}
// Feed through allpasses in series
- for (i = 0; i < numallpasses; i++) {
+ for (i=0; i<numallpasses; i++)
+ {
outL = allpassL[i].process(outL);
outR = allpassR[i].process(outR);
}
- // Calculate output MIXING with anything already there
- *outputL += outL * wet1 + outR * wet2 + *inputL * dry;
- *outputR += outR * wet1 + outL * wet2 + *inputR * dry;
-
- // Increment sample pointers, allowing for interleave (if any)
- inputL += skip;
- inputR += skip;
- outputL += skip;
- outputR += skip;
+ // Calculate output REPLACING anything already there
+ *outputL = outL*wet1 + outR*wet2;
+ *outputR = outR*wet1 + outL*wet2;
+
+ inputL++;
+ inputR++;
+ outputL++;
+ outputR++;
}
}
-void revmodel::update() {
- // Recalculate internal values after parameter change
+void revmodel::update()
+{
+// Recalculate internal values after parameter change
int i;
- wet1 = wet * (width / 2 + 0.5f);
- wet2 = wet * ((1 - width) / 2);
+ wet1 = wet*(width/2 + 0.5f);
+ wet2 = wet*((1-width)/2);
- if (mode >= freezemode) {
+ if (mode >= freezemode)
+ {
roomsize1 = 1;
damp1 = 0;
gain = muted;
- } else {
+ }
+ else
+ {
roomsize1 = roomsize;
damp1 = damp;
gain = fixedgain;
}
- for (i = 0; i < numcombs; i++) {
+ for (i=0; i<numcombs; i++)
+ {
combL[i].setfeedback(roomsize1);
combR[i].setfeedback(roomsize1);
}
- for (i = 0; i < numcombs; i++) {
+ for (i=0; i<numcombs; i++)
+ {
combL[i].setdamp(damp1);
combR[i].setdamp(damp1);
}
@@ -250,58 +250,75 @@ void revmodel::update() {
// because as you develop the reverb model, you may
// wish to take dynamic action when they are called.
-void revmodel::setroomsize(float value) {
- roomsize = (value * scaleroom) + offsetroom;
+void revmodel::setroomsize(float value)
+{
+ roomsize = (value*scaleroom) + offsetroom;
update();
}
-float revmodel::getroomsize() {
- return (roomsize - offsetroom) / scaleroom;
+float revmodel::getroomsize()
+{
+ return (roomsize-offsetroom)/scaleroom;
}
-void revmodel::setdamp(float value) {
- damp = value * scaledamp;
+void revmodel::setdamp(float value)
+{
+ damp = value*scaledamp;
update();
}
-float revmodel::getdamp() {
- return damp / scaledamp;
+float revmodel::getdamp()
+{
+ return damp/scaledamp;
}
-void revmodel::setwet(float value) {
- wet = value * scalewet;
+void revmodel::setwet(float value)
+{
+ wet = value*scalewet;
update();
}
-float revmodel::getwet() {
- return wet / scalewet;
+float revmodel::getwet()
+{
+ return wet/scalewet;
}
-void revmodel::setdry(float value) {
- dry = value * scaledry;
+void revmodel::setdry(float value)
+{
+ dry = value*scaledry;
}
-float revmodel::getdry() {
- return dry / scaledry;
+float revmodel::getdry()
+{
+ return dry/scaledry;
}
-void revmodel::setwidth(float value) {
+void revmodel::setwidth(float value)
+{
width = value;
update();
}
-float revmodel::getwidth() {
+float revmodel::getwidth()
+{
return width;
}
-void revmodel::setmode(float value) {
+void revmodel::setmode(float value)
+{
mode = value;
update();
}
-float revmodel::getmode() {
+float revmodel::getmode()
+{
if (mode >= freezemode)
return 1;
else
return 0;
}
+
+void revmodel::setfiltval(float value)
+{
+ filtval = value;
+}
diff --git a/audio/softsynth/mt32/freeverb.h b/audio/softsynth/mt32/freeverb.h
index 39ae463970..ae4d48169e 100644
--- a/audio/softsynth/mt32/freeverb.h
+++ b/audio/softsynth/mt32/freeverb.h
@@ -1,24 +1,32 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public 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 _freeverb_
+#define _freeverb_
+
+// Reverb model tuning values
+//
+// Written by Jezar at Dreampoint, June 2000
+// http://www.dreampoint.co.uk
+// This code is public domain
+
+const int numcombs = 8;
+const int numallpasses = 4;
+const float muted = 0;
+const float fixedgain = 0.015f;
+const float scalewet = 3;
+const float scaledry = 2;
+const float scaledamp = 0.4f;
+const float scaleroom = 0.28f;
+const float offsetroom = 0.7f;
+const float initialroom = 0.5f;
+const float initialdamp = 0.5f;
+const float initialwet = 1/scalewet;
+const float initialdry = 0;
+const float initialwidth = 1;
+const float initialmode = 0;
+const float freezemode = 0.5f;
+const int stereospread = 23;
+
+const int combtuning[] = {1116, 1188, 1277, 1356, 1422, 1491, 1557, 1617};
+const int allpasstuning[] = {556, 441, 341, 225};
// Macro for killing denormalled numbers
//
@@ -27,215 +35,155 @@
// Based on IS_DENORMAL macro by Jon Watte
// This code is public domain
-#ifndef FREEVERB_H
-#define FREEVERB_H
-
-// FIXME: Fix this really ugly hack
-inline float undenormalise(void *sample) {
- if (((*(unsigned int*)sample) & 0x7f800000) == 0)
+static inline float undenormalise(float x) {
+ union {
+ float f;
+ unsigned int i;
+ } u;
+ u.f = x;
+ if ((u.i & 0x7f800000) == 0) {
return 0.0f;
- return *(float*)sample;
+ }
+ return x;
}
-// Comb filter class declaration
+// Allpass filter declaration
+//
+// Written by Jezar at Dreampoint, June 2000
+// http://www.dreampoint.co.uk
+// This code is public domain
-class comb {
+class allpass
+{
public:
- comb();
- void setbuffer(float *buf, int size);
- inline float process(float inp);
- void mute();
- void setdamp(float val);
- float getdamp();
- void setfeedback(float val);
- float getfeedback();
-private:
- float feedback;
- float filterstore;
- float damp1;
- float damp2;
- float *buffer;
- int bufsize;
- int bufidx;
+ allpass();
+ void setbuffer(float *buf, int size);
+ void deletebuffer();
+ inline float process(float inp);
+ void mute();
+ void setfeedback(float val);
+ float getfeedback();
+// private:
+ float feedback;
+ float *buffer;
+ int bufsize;
+ int bufidx;
};
// Big to inline - but crucial for speed
-inline float comb::process(float input) {
+inline float allpass::process(float input)
+{
float output;
+ float bufout;
- output = buffer[bufidx];
- undenormalise(&output);
-
- filterstore = (output * damp2) + (filterstore * damp1);
- undenormalise(&filterstore);
+ bufout = undenormalise(buffer[bufidx]);
- buffer[bufidx] = input + (filterstore * feedback);
+ output = -input + bufout;
+ buffer[bufidx] = input + (bufout*feedback);
- if (++bufidx >= bufsize)
- bufidx = 0;
+ if (++bufidx>=bufsize) bufidx = 0;
return output;
}
-// Allpass filter declaration
+// Comb filter class declaration
+//
+// Written by Jezar at Dreampoint, June 2000
+// http://www.dreampoint.co.uk
+// This code is public domain
-class allpass {
+class comb
+{
public:
- allpass();
- void setbuffer(float *buf, int size);
- inline float process(float inp);
- void mute();
- void setfeedback(float val);
- float getfeedback();
+ comb();
+ void setbuffer(float *buf, int size);
+ void deletebuffer();
+ inline float process(float inp);
+ void mute();
+ void setdamp(float val);
+ float getdamp();
+ void setfeedback(float val);
+ float getfeedback();
private:
- float feedback;
- float *buffer;
- int bufsize;
- int bufidx;
+ float feedback;
+ float filterstore;
+ float damp1;
+ float damp2;
+ float *buffer;
+ int bufsize;
+ int bufidx;
};
// Big to inline - but crucial for speed
-inline float allpass::process(float input) {
+inline float comb::process(float input)
+{
float output;
- float bufout;
- bufout = buffer[bufidx];
- undenormalise(&bufout);
+ output = undenormalise(buffer[bufidx]);
- output = -input + bufout;
- buffer[bufidx] = input + (bufout * feedback);
+ filterstore = undenormalise((output*damp2) + (filterstore*damp1));
+
+ buffer[bufidx] = input + (filterstore*feedback);
- if (++bufidx >= bufsize)
- bufidx = 0;
+ if (++bufidx>=bufsize) bufidx = 0;
return output;
}
-
-// Reverb model tuning values
-
-const int numcombs = 8;
-const int numallpasses = 4;
-const float muted = 0;
-const float fixedgain = 0.015f;
-const float scalewet = 3;
-const float scaledry = 2;
-const float scaledamp = 0.4f;
-const float scaleroom = 0.28f;
-const float offsetroom = 0.7f;
-const float initialroom = 0.5f;
-const float initialdamp = 0.5f;
-const float initialwet = 1 / scalewet;
-const float initialdry = 0;
-const float initialwidth = 1;
-const float initialmode = 0;
-const float freezemode = 0.5f;
-const int stereospread = 23;
-
-// These values assume 44.1KHz sample rate
-// they will probably be OK for 48KHz sample rate
-// but would need scaling for 96KHz (or other) sample rates.
-// The values were obtained by listening tests.
-const int combtuningL1 = 1116;
-const int combtuningR1 = 1116 + stereospread;
-const int combtuningL2 = 1188;
-const int combtuningR2 = 1188 + stereospread;
-const int combtuningL3 = 1277;
-const int combtuningR3 = 1277 + stereospread;
-const int combtuningL4 = 1356;
-const int combtuningR4 = 1356 + stereospread;
-const int combtuningL5 = 1422;
-const int combtuningR5 = 1422 + stereospread;
-const int combtuningL6 = 1491;
-const int combtuningR6 = 1491 + stereospread;
-const int combtuningL7 = 1557;
-const int combtuningR7 = 1557 + stereospread;
-const int combtuningL8 = 1617;
-const int combtuningR8 = 1617 + stereospread;
-const int allpasstuningL1 = 556;
-const int allpasstuningR1 = 556 + stereospread;
-const int allpasstuningL2 = 441;
-const int allpasstuningR2 = 441 + stereospread;
-const int allpasstuningL3 = 341;
-const int allpasstuningR3 = 341 + stereospread;
-const int allpasstuningL4 = 225;
-const int allpasstuningR4 = 225 + stereospread;
-
-
// Reverb model declaration
+//
+// Written by Jezar at Dreampoint, June 2000
+// Modifications by Jerome Fisher, 2009
+// http://www.dreampoint.co.uk
+// This code is public domain
-class revmodel {
+class revmodel
+{
public:
- revmodel();
- void mute();
- void processmix(float *inputL, float *inputR, float *outputL, float *outputR, long numsamples, int skip);
- void processreplace(float *inputL, float *inputR, float *outputL, float *outputR, long numsamples, int skip);
- void setroomsize(float value);
- float getroomsize();
- void setdamp(float value);
- float getdamp();
- void setwet(float value);
- float getwet();
- void setdry(float value);
- float getdry();
- void setwidth(float value);
- float getwidth();
- void setmode(float value);
- float getmode();
+ revmodel(float scaletuning);
+ ~revmodel();
+ void mute();
+ void process(const float *inputL, const float *inputR, float *outputL, float *outputR, long numsamples);
+ void setroomsize(float value);
+ float getroomsize();
+ void setdamp(float value);
+ float getdamp();
+ void setwet(float value);
+ float getwet();
+ void setdry(float value);
+ float getdry();
+ void setwidth(float value);
+ float getwidth();
+ void setmode(float value);
+ float getmode();
+ void setfiltval(float value);
private:
- void update();
-
- float gain;
- float roomsize, roomsize1;
- float damp, damp1;
- float wet, wet1, wet2;
- float dry;
- float width;
- float mode;
-
- // The following are all declared inline
- // to remove the need for dynamic allocation
- // with its subsequent error-checking messiness
+ void update();
+private:
+ float gain;
+ float roomsize,roomsize1;
+ float damp,damp1;
+ float wet,wet1,wet2;
+ float dry;
+ float width;
+ float mode;
+
+ // LPF stuff
+ float filtval;
+ float filtprev1;
+ float filtprev2;
// Comb filters
- comb combL[numcombs];
- comb combR[numcombs];
+ comb combL[numcombs];
+ comb combR[numcombs];
// Allpass filters
allpass allpassL[numallpasses];
allpass allpassR[numallpasses];
-
- // Buffers for the combs
- float bufcombL1[combtuningL1];
- float bufcombR1[combtuningR1];
- float bufcombL2[combtuningL2];
- float bufcombR2[combtuningR2];
- float bufcombL3[combtuningL3];
- float bufcombR3[combtuningR3];
- float bufcombL4[combtuningL4];
- float bufcombR4[combtuningR4];
- float bufcombL5[combtuningL5];
- float bufcombR5[combtuningR5];
- float bufcombL6[combtuningL6];
- float bufcombR6[combtuningR6];
- float bufcombL7[combtuningL7];
- float bufcombR7[combtuningR7];
- float bufcombL8[combtuningL8];
- float bufcombR8[combtuningR8];
-
- // Buffers for the allpasses
- float bufallpassL1[allpasstuningL1];
- float bufallpassR1[allpasstuningR1];
- float bufallpassL2[allpasstuningL2];
- float bufallpassR2[allpasstuningR2];
- float bufallpassL3[allpasstuningL3];
- float bufallpassR3[allpasstuningR3];
- float bufallpassL4[allpasstuningL4];
- float bufallpassR4[allpasstuningR4];
};
-#endif
+#endif//_freeverb_
diff --git a/audio/softsynth/mt32/i386.cpp b/audio/softsynth/mt32/i386.cpp
deleted file mode 100644
index f092189d76..0000000000
--- a/audio/softsynth/mt32/i386.cpp
+++ /dev/null
@@ -1,849 +0,0 @@
-/* Copyright (c) 2003-2005 Various contributors
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- */
-
-#include "mt32emu.h"
-
-#ifdef MT32EMU_HAVE_X86
-
-namespace MT32Emu {
-
-#ifndef _MSC_VER
-
-#define eflag(value) __asm__ __volatile__("pushfl \n popfl \n" : : "a"(value))
-#define cpuid_flag (1 << 21)
-
-static inline bool atti386_DetectCPUID() {
- unsigned int result;
-
- // Is there a cpuid?
- result = cpuid_flag; // set test
- eflag(result);
- if (!(result & cpuid_flag))
- return false;
-
- result = 0; // clear test
- eflag(result);
- if (result & cpuid_flag)
- return false;
-
- return true;
-}
-
-static inline bool atti386_DetectSIMD() {
- unsigned int result;
-
- if (atti386_DetectCPUID() == false)
- return false;
-
- /* check cpuid */
- __asm__ __volatile__(
- "pushl %%ebx \n" \
- "movl $1, %%eax \n" \
- "cpuid \n" \
- "movl %%edx, %0 \n" \
- "popl %%ebx \n" \
- : "=r"(result) : : "eax", "ecx", "edx");
-
- if (result & (1 << 25))
- return true;
-
- return false;
-}
-
-static inline bool atti386_Detect3DNow() {
- unsigned int result;
-
- if (atti386_DetectCPUID() == false)
- return false;
-
- // get cpuid
- __asm__ __volatile__(
- "pushl %%ebx \n" \
- "movl $0x80000001, %%eax \n" \
- "cpuid \n" \
- "movl %%edx, %0 \n" \
- "popl %%ebx \n" \
- : "=r"(result) : : "eax", "ecx", "edx");
-
- if (result & 0x80000000)
- return true;
-
- return false;
-}
-
-
-static inline float atti386_iir_filter_sse(float *output, float *hist1_ptr, float *coef_ptr) {
- __asm__ __volatile__ (
- "pushl %1 \n" \
- "pushl %2 \n" \
- "movss 0(%0), %%xmm1 \n" \
- "movups 0(%1), %%xmm2 \n" \
- "movlps 0(%2), %%xmm3 \n" \
- " \n" \
- "shufps $0x44, %%xmm3, %%xmm3 \n" \
- " \n" \
- "mulps %%xmm3, %%xmm2 \n" \
- " \n" \
- "subss %%xmm2, %%xmm1 \n" \
- "shufps $0x39, %%xmm2, %%xmm2 \n" \
- "subss %%xmm2, %%xmm1 \n" \
- " \n" \
- "movss %%xmm1, 0(%2) \n" \
- " \n" \
- "shufps $0x39, %%xmm2, %%xmm2 \n" \
- "addss %%xmm2, %%xmm1 \n" \
- " \n" \
- "shufps $0x39, %%xmm2, %%xmm2 \n" \
- "addss %%xmm2, %%xmm1 \n" \
- " \n" \
- "movss %%xmm3, 4(%2) \n" \
- " \n" \
- "addl $16, %1 \n" \
- "addl $8, %2 \n" \
- " \n" \
- "movups 0(%1), %%xmm2 \n" \
- " \n" \
- "movlps 0(%2), %%xmm3 \n" \
- "shufps $0x44, %%xmm3, %%xmm3 \n" \
- " \n" \
- "mulps %%xmm3, %%xmm2 \n" \
- " \n" \
- "subss %%xmm2, %%xmm1 \n" \
- "shufps $0x39, %%xmm2, %%xmm2 \n" \
- "subss %%xmm2, %%xmm1 \n" \
- " \n" \
- "movss %%xmm1, 0(%2) \n" \
- " \n" \
- "shufps $0x39, %%xmm2, %%xmm2 \n" \
- "addss %%xmm2, %%xmm1 \n" \
- " \n" \
- "shufps $0x39, %%xmm2, %%xmm2 \n" \
- "addss %%xmm2, %%xmm1 \n" \
- " \n" \
- "movss %%xmm3, 4(%2) \n" \
- "movss %%xmm1, 0(%0) \n" \
- "popl %2 \n" \
- "popl %1 \n" \
- : : "r"(output), "r"(coef_ptr), "r"(hist1_ptr)
- : "memory"
-#ifdef __SSE__
- , "xmm1", "xmm2", "xmm3"
-#endif
- );
-
- return *output;
-}
-
-static inline float atti386_iir_filter_3DNow(float output, float *hist1_ptr, float *coef_ptr) {
- float tmp;
-
- __asm__ __volatile__ (
- "movq %0, %%mm1 \n" \
- " \n" \
- "movl %1, %%edi \n" \
- "movq 0(%%edi), %%mm2 \n" \
- " \n" \
- "movl %2, %%eax; \n" \
- "movq 0(%%eax), %%mm3 \n" \
- " \n" \
- "pfmul %%mm3, %%mm2 \n" \
- "pfsub %%mm2, %%mm1 \n" \
- " \n" \
- "psrlq $32, %%mm2 \n" \
- "pfsub %%mm2, %%mm1 \n" \
- " \n" \
- "movd %%mm1, %3 \n" \
- " \n" \
- "addl $8, %%edi \n" \
- "movq 0(%%edi), %%mm2 \n" \
- "movq 0(%%eax), %%mm3 \n" \
- " \n" \
- "pfmul %%mm3, %%mm2 \n" \
- "pfadd %%mm2, %%mm1 \n" \
- " \n" \
- "psrlq $32, %%mm2 \n" \
- "pfadd %%mm2, %%mm1 \n" \
- " \n" \
- "pushl %3 \n" \
- "popl 0(%%eax) \n" \
- " \n" \
- "movd %%mm3, 4(%%eax) \n" \
- " \n" \
- "addl $8, %%edi \n" \
- "addl $8, %%eax \n" \
- " \n" \
- "movq 0(%%edi), %%mm2 \n" \
- "movq 0(%%eax), %%mm3 \n" \
- " \n" \
- "pfmul %%mm3, %%mm2 \n" \
- "pfsub %%mm2, %%mm1 \n" \
- " \n" \
- "psrlq $32, %%mm2 \n" \
- "pfsub %%mm2, %%mm1 \n" \
- " \n" \
- "movd %%mm1, %3 \n" \
- " \n" \
- "addl $8, %%edi \n" \
- "movq 0(%%edi), %%mm2 \n" \
- "movq 0(%%eax), %%mm3 \n" \
- " \n" \
- "pfmul %%mm3, %%mm2 \n" \
- "pfadd %%mm2, %%mm1 \n" \
- " \n" \
- "psrlq $32, %%mm2 \n" \
- "pfadd %%mm2, %%mm1 \n" \
- " \n" \
- "pushl %3 \n" \
- "popl 0(%%eax) \n" \
- "movd %%mm3, 4(%%eax) \n" \
- " \n" \
- "movd %%mm1, %0 \n" \
- "femms \n" \
- : "=m"(output) : "g"(coef_ptr), "g"(hist1_ptr), "m"(tmp)
- : "eax", "edi", "memory"
-#ifdef __MMX__
- , "mm1", "mm2", "mm3"
-#endif
- );
-
- return output;
-}
-
-static inline void atti386_produceOutput1(int tmplen, Bit16s myvolume, Bit16s *useBuf, Bit16s *snd) {
- __asm__ __volatile__(
- "movl %0, %%ecx \n" \
- "movw %1, %%ax \n" \
- "shll $16, %%eax \n" \
- "movw %1, %%ax \n" \
- "movd %%eax, %%mm3 \n" \
- "movd %%eax, %%mm2 \n" \
- "psllq $32, %%mm3 \n" \
- "por %%mm2, %%mm3 \n" \
- "movl %2, %%esi \n" \
- "movl %3, %%edi \n" \
- "1: \n" \
- "movq 0(%%esi), %%mm1 \n" \
- "movq 0(%%edi), %%mm2 \n" \
- "pmulhw %%mm3, %%mm1 \n" \
- "paddw %%mm2, %%mm1 \n" \
- "movq %%mm1, 0(%%edi) \n" \
- " \n" \
- "addl $8, %%esi \n" \
- "addl $8, %%edi \n" \
- " \n" \
- "decl %%ecx \n" \
- "cmpl $0, %%ecx \n" \
- "jg 1b \n" \
- "emms \n" \
- : : "g"(tmplen), "g"(myvolume), "g"(useBuf), "g"(snd)
- : "eax", "ecx", "edi", "esi", "memory"
-#ifdef __MMX__
- , "mm1", "mm2", "mm3"
-#endif
- );
-}
-
-static inline void atti386_produceOutput2(Bit32u len, Bit16s *snd, float *sndbufl, float *sndbufr, float *multFactor) {
- __asm__ __volatile__(
- "movl %4, %%ecx \n" \
- "shrl $1, %%ecx \n" \
- "addl $4, %%ecx \n" \
- "pushl %%ecx \n" \
- " \n" \
- "movl %0, %%esi \n" \
- "movups 0(%%esi), %%xmm1 \n" \
- " \n" \
- "movl %1, %%esi \n" \
- "movl %2, %%edi \n" \
- "1: \n" \
- "xorl %%eax, %%eax \n" \
- "movw 0(%1), %%ax \n" \
- "cwde \n" \
- "incl %1 \n" \
- "incl %1 \n" \
- "movd %%eax, %%mm1 \n" \
- "psrlq $32, %%mm1 \n" \
- "movw 0(%1), %%ax \n" \
- "incl %1 \n" \
- "incl %1 \n" \
- "movd %%eax, %%mm2 \n" \
- "por %%mm2, %%mm1 \n" \
- " \n" \
- "decl %%ecx \n" \
- "jnz 1b \n" \
- " \n" \
- "popl %%ecx \n" \
- "movl %1, %%esi \n" \
- "movl %3, %%edi \n" \
- "incl %%esi \n" \
- "2: \n" \
- "decl %%ecx \n" \
- "jnz 2b \n" \
- : : "g"(multFactor), "r"(snd), "g"(sndbufl), "g"(sndbufr), "g"(len)
- : "eax", "ecx", "edi", "esi", "mm1", "mm2", "xmm1", "memory");
-}
-
-static inline void atti386_mixBuffers(Bit16s * buf1, Bit16s *buf2, int len) {
- __asm__ __volatile__(
- "movl %0, %%ecx \n" \
- "movl %1, %%esi \n" \
- "movl %2, %%edi \n" \
- "1: \n" \
- "movq 0(%%edi), %%mm1 \n" \
- "movq 0(%%esi), %%mm2 \n" \
- "paddw %%mm2, %%mm1 \n" \
- "movq %%mm1, 0(%%esi) \n" \
- "addl $8, %%edi \n" \
- "addl $8, %%esi \n" \
- "decl %%ecx \n" \
- "cmpl $0, %%ecx \n" \
- "jg 1b \n" \
- "emms \n" \
- : : "g"(len), "g"(buf1), "g"(buf2)
- : "ecx", "edi", "esi", "memory"
-#ifdef __MMX__
- , "mm1", "mm2"
-#endif
- );
-}
-
-static inline void atti386_mixBuffersRingMix(Bit16s * buf1, Bit16s *buf2, int len) {
- __asm__ __volatile__(
- "movl %0, %%ecx \n" \
- "movl %1, %%esi \n" \
- "movl %2, %%edi \n" \
- "1: \n" \
- "movq 0(%%esi), %%mm1 \n" \
- "movq 0(%%edi), %%mm2 \n" \
- "movq %%mm1, %%mm3 \n" \
- "pmulhw %%mm2, %%mm1 \n" \
- "paddw %%mm3, %%mm1 \n" \
- "movq %%mm1, 0(%%esi) \n" \
- "addl $8, %%edi \n" \
- "addl $8, %%esi \n" \
- "decl %%ecx \n" \
- "cmpl $0, %%ecx \n" \
- "jg 1b \n" \
- "emms \n" \
- : : "g"(len), "g"(buf1), "g"(buf2)
- : "ecx", "edi", "esi", "memory"
-#ifdef __MMX__
- , "mm1", "mm2", "mm3"
-#endif
- );
-}
-
-static inline void atti386_mixBuffersRing(Bit16s * buf1, Bit16s *buf2, int len) {
- __asm__ __volatile__(
- "movl %0, %%ecx \n" \
- "movl %1, %%esi \n" \
- "movl %2, %%edi \n" \
- "1: \n" \
- "movq 0(%%esi), %%mm1 \n" \
- "movq 0(%%edi), %%mm2 \n" \
- "pmulhw %%mm2, %%mm1 \n" \
- "movq %%mm1, 0(%%esi) \n" \
- "addl $8, %%edi \n" \
- "addl $8, %%esi \n" \
- "decl %%ecx \n" \
- "cmpl $0, %%ecx \n" \
- "jg 1b \n" \
- "emms \n" \
- : : "g"(len), "g"(buf1), "g"(buf2)
- : "ecx", "edi", "esi", "memory"
-#ifdef __MMX__
- , "mm1", "mm2"
-#endif
- );
-}
-
-static inline void atti386_partialProductOutput(int quadlen, Bit16s leftvol, Bit16s rightvol, Bit16s *partialBuf, Bit16s *p1buf) {
- __asm__ __volatile__(
- "movl %0, %%ecx \n" \
- "movw %1, %%ax \n" \
- "shll $16, %%eax \n" \
- "movw %2, %%ax \n" \
- "movd %%eax, %%mm1 \n" \
- "movd %%eax, %%mm2 \n" \
- "psllq $32, %%mm1 \n" \
- "por %%mm2, %%mm1 \n" \
- "movl %3, %%edi \n" \
- "movl %4, %%esi \n" \
- "pushl %%ebx \n" \
- "1: \n" \
- "movw 0(%%esi), %%bx \n" \
- "addl $2, %%esi \n" \
- "movw 0(%%esi), %%dx \n" \
- "addl $2, %%esi \n" \
- "" \
- "movw %%dx, %%ax \n" \
- "shll $16, %%eax \n" \
- "movw %%dx, %%ax \n" \
- "movd %%eax, %%mm2 \n" \
- "psllq $32, %%mm2 \n" \
- "movw %%bx, %%ax \n" \
- "shll $16, %%eax \n" \
- "movw %%bx, %%ax \n" \
- "movd %%eax, %%mm3 \n" \
- "por %%mm3, %%mm2 \n" \
- "" \
- "pmulhw %%mm1, %%mm2 \n" \
- "movq %%mm2, 0(%%edi) \n" \
- "addl $8, %%edi \n" \
- "" \
- "decl %%ecx \n" \
- "cmpl $0, %%ecx \n" \
- "jg 1b \n" \
- "emms \n" \
- "popl %%ebx \n" \
- : : "g"(quadlen), "g"(leftvol), "g"(rightvol), "g"(partialBuf), "g"(p1buf)
- : "eax", "ecx", "edx", "edi", "esi", "memory"
-#ifdef __MMX__
- , "mm1", "mm2", "mm3"
-#endif
- );
-}
-
-#endif
-
-bool DetectSIMD() {
-#ifdef _MSC_VER
- bool found_simd;
- __asm {
- pushfd
- pop eax // get EFLAGS into eax
- mov ebx,eax // keep a copy
- xor eax,0x200000
- // toggle CPUID bit
-
- push eax
- popfd // set new EFLAGS
- pushfd
- pop eax // EFLAGS back into eax
-
- xor eax,ebx
- // have we changed the ID bit?
-
- je NO_SIMD
- // No, no CPUID instruction
-
- // we could toggle the
- // ID bit so CPUID is present
- mov eax,1
-
- cpuid // get processor features
- test edx,1<<25 // check the SIMD bit
- jz NO_SIMD
- mov found_simd,1
- jmp DONE
- NO_SIMD:
- mov found_simd,0
- DONE:
- }
- return found_simd;
-#else
- return atti386_DetectSIMD();
-#endif
-}
-
-bool Detect3DNow() {
-#ifdef _MSC_VER
- bool found3D = false;
- __asm {
- pushfd
- pop eax
- mov edx, eax
- xor eax, 00200000h
- push eax
- popfd
- pushfd
- pop eax
- xor eax, edx
- jz NO_3DNOW
-
- mov eax, 80000000h
- cpuid
-
- cmp eax, 80000000h
- jbe NO_3DNOW
-
- mov eax, 80000001h
- cpuid
- test edx, 80000000h
- jz NO_3DNOW
- mov found3D, 1
-NO_3DNOW:
-
- }
- return found3D;
-#else
- return atti386_Detect3DNow();
-#endif
-}
-
-float iir_filter_sse(float input,float *hist1_ptr, float *coef_ptr) {
- float output;
-
- // 1st number of coefficients array is overall input scale factor, or filter gain
- output = input * (*coef_ptr++);
-
-#ifdef _MSC_VER
- __asm {
-
- movss xmm1, output
-
- mov eax, coef_ptr
- movups xmm2, [eax]
-
- mov eax, hist1_ptr
- movlps xmm3, [eax]
- shufps xmm3, xmm3, 44h
- // hist1_ptr+1, hist1_ptr, hist1_ptr+1, hist1_ptr
-
- mulps xmm2, xmm3
-
- subss xmm1, xmm2
- // Rotate elements right
- shufps xmm2, xmm2, 39h
- subss xmm1, xmm2
-
- // Store new_hist
- movss DWORD PTR [eax], xmm1
-
- // Rotate elements right
- shufps xmm2, xmm2, 39h
- addss xmm1, xmm2
-
- // Rotate elements right
- shufps xmm2, xmm2, 39h
- addss xmm1, xmm2
-
- // Store previous hist
- movss DWORD PTR [eax+4], xmm3
-
- add coef_ptr, 16
- add hist1_ptr, 8
-
- mov eax, coef_ptr
- movups xmm2, [eax]
-
- mov eax, hist1_ptr
- movlps xmm3, [eax]
- shufps xmm3, xmm3, 44h
- // hist1_ptr+1, hist1_ptr, hist1_ptr+1, hist1_ptr
-
- mulps xmm2, xmm3
-
- subss xmm1, xmm2
- // Rotate elements right
- shufps xmm2, xmm2, 39h
- subss xmm1, xmm2
-
- // Store new_hist
- movss DWORD PTR [eax], xmm1
-
- // Rotate elements right
- shufps xmm2, xmm2, 39h
- addss xmm1, xmm2
-
- // Rotate elements right
- shufps xmm2, xmm2, 39h
- addss xmm1, xmm2
-
- // Store previous hist
- movss DWORD PTR [eax+4], xmm3
-
- movss output, xmm1
- }
-#else
- output = atti386_iir_filter_sse(&output, hist1_ptr, coef_ptr);
-#endif
- return output;
-}
-
-float iir_filter_3dnow(float input,float *hist1_ptr, float *coef_ptr) {
- float output;
-
- // 1st number of coefficients array is overall input scale factor, or filter gain
- output = input * (*coef_ptr++);
-
- // I find it very sad that 3DNow requires twice as many instructions as Intel's SSE
- // Intel does have the upper hand here.
-#ifdef _MSC_VER
- float tmp;
- __asm {
- movq mm1, output
- mov ebx, coef_ptr
- movq mm2, [ebx]
-
- mov eax, hist1_ptr;
- movq mm3, [eax]
-
- pfmul mm2, mm3
- pfsub mm1, mm2
-
- psrlq mm2, 32
- pfsub mm1, mm2
-
- // Store new hist
- movd tmp, mm1
-
- add ebx, 8
- movq mm2, [ebx]
- movq mm3, [eax]
-
- pfmul mm2, mm3
- pfadd mm1, mm2
-
- psrlq mm2, 32
- pfadd mm1, mm2
-
- push tmp
- pop DWORD PTR [eax]
-
- movd DWORD PTR [eax+4], mm3
-
- add ebx, 8
- add eax, 8
-
- movq mm2, [ebx]
- movq mm3, [eax]
-
- pfmul mm2, mm3
- pfsub mm1, mm2
-
- psrlq mm2, 32
- pfsub mm1, mm2
-
- // Store new hist
- movd tmp, mm1
-
- add ebx, 8
- movq mm2, [ebx]
- movq mm3, [eax]
-
- pfmul mm2, mm3
- pfadd mm1, mm2
-
- psrlq mm2, 32
- pfadd mm1, mm2
-
- push tmp
- pop DWORD PTR [eax]
- movd DWORD PTR [eax+4], mm3
-
- movd output, mm1
-
- femms
- }
-#else
- output = atti386_iir_filter_3DNow(output, hist1_ptr, coef_ptr);
-#endif
- return output;
-}
-
-#if MT32EMU_USE_MMX > 0
-
-int i386_partialProductOutput(int len, Bit16s leftvol, Bit16s rightvol, Bit16s *partialBuf, Bit16s *mixedBuf) {
- int tmplen = len >> 1;
- if (tmplen == 0) {
- return 0;
- }
-#ifdef _MSC_VER
- __asm {
- mov ecx,tmplen
- mov ax, leftvol
- shl eax,16
- mov ax, rightvol
- movd mm1, eax
- movd mm2, eax
- psllq mm1, 32
- por mm1, mm2
- mov edi, partialBuf
- mov esi, mixedBuf
-mmxloop1:
- mov bx, [esi]
- add esi,2
- mov dx, [esi]
- add esi,2
-
- mov ax, dx
- shl eax, 16
- mov ax, dx
- movd mm2,eax
- psllq mm2, 32
- mov ax, bx
- shl eax, 16
- mov ax, bx
- movd mm3,eax
- por mm2,mm3
-
- pmulhw mm2, mm1
- movq [edi], mm2
- add edi, 8
-
- dec ecx
- cmp ecx,0
- jg mmxloop1
- emms
- }
-#else
- atti386_partialProductOutput(tmplen, leftvol, rightvol, partialBuf, mixedBuf);
-#endif
- return tmplen << 1;
-}
-
-int i386_mixBuffers(Bit16s * buf1, Bit16s *buf2, int len) {
- int tmplen = len >> 2;
- if (tmplen == 0) {
- return 0;
- }
-#ifdef _MSC_VER
- __asm {
- mov ecx, tmplen
- mov esi, buf1
- mov edi, buf2
-
-mixloop1:
- movq mm1, [edi]
- movq mm2, [esi]
- paddw mm1,mm2
- movq [esi],mm1
- add edi,8
- add esi,8
-
- dec ecx
- cmp ecx,0
- jg mixloop1
- emms
- }
-#else
- atti386_mixBuffers(buf1, buf2, tmplen);
-#endif
- return tmplen << 2;
-}
-
-
-int i386_mixBuffersRingMix(Bit16s * buf1, Bit16s *buf2, int len) {
- int tmplen = len >> 2;
- if (tmplen == 0) {
- return 0;
- }
-#ifdef _MSC_VER
- __asm {
- mov ecx, tmplen
- mov esi, buf1
- mov edi, buf2
-
-mixloop2:
- movq mm1, [esi]
- movq mm2, [edi]
- movq mm3, mm1
- pmulhw mm1, mm2
- paddw mm1,mm3
- movq [esi],mm1
- add edi,8
- add esi,8
-
- dec ecx
- cmp ecx,0
- jg mixloop2
- emms
- }
-#else
- atti386_mixBuffersRingMix(buf1, buf2, tmplen);
-#endif
- return tmplen << 2;
-}
-
-int i386_mixBuffersRing(Bit16s * buf1, Bit16s *buf2, int len) {
- int tmplen = len >> 2;
- if (tmplen == 0) {
- return 0;
- }
-#ifdef _MSC_VER
- __asm {
- mov ecx, tmplen
- mov esi, buf1
- mov edi, buf2
-
-mixloop3:
- movq mm1, [esi]
- movq mm2, [edi]
- pmulhw mm1, mm2
- movq [esi],mm1
- add edi,8
- add esi,8
-
- dec ecx
- cmp ecx,0
- jg mixloop3
- emms
- }
-#else
- atti386_mixBuffersRing(buf1, buf2, tmplen);
-#endif
- return tmplen << 2;
-}
-
-int i386_produceOutput1(Bit16s *useBuf, Bit16s *stream, Bit32u len, Bit16s volume) {
- int tmplen = (len >> 1);
- if (tmplen == 0) {
- return 0;
- }
-#ifdef _MSC_VER
- __asm {
- mov ecx, tmplen
- mov ax,volume
- shl eax,16
- mov ax,volume
- movd mm3,eax
- movd mm2,eax
- psllq mm3, 32
- por mm3,mm2
- mov esi, useBuf
- mov edi, stream
-mixloop4:
- movq mm1, [esi]
- movq mm2, [edi]
- pmulhw mm1, mm3
- paddw mm1,mm2
- movq [edi], mm1
-
- add esi,8
- add edi,8
-
- dec ecx
- cmp ecx,0
- jg mixloop4
- emms
- }
-#else
- atti386_produceOutput1(tmplen, volume, useBuf, stream);
-#endif
- return tmplen << 1;
-}
-
-#endif
-
-}
-
-#endif
diff --git a/audio/softsynth/mt32/i386.h b/audio/softsynth/mt32/i386.h
deleted file mode 100644
index e8644411cd..0000000000
--- a/audio/softsynth/mt32/i386.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/* Copyright (c) 2003-2005 Various contributors
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- */
-
-#ifndef MT32EMU_I386_H
-#define MT32EMU_I386_H
-
-namespace MT32Emu {
-#ifdef MT32EMU_HAVE_X86
-
-// Function that detects the availablity of SSE SIMD instructions
-bool DetectSIMD();
-// Function that detects the availablity of 3DNow instructions
-bool Detect3DNow();
-
-float iir_filter_sse(float input,float *hist1_ptr, float *coef_ptr);
-float iir_filter_3dnow(float input,float *hist1_ptr, float *coef_ptr);
-float iir_filter_normal(float input,float *hist1_ptr, float *coef_ptr);
-
-#if MT32EMU_USE_MMX > 0
-int i386_partialProductOutput(int len, Bit16s leftvol, Bit16s rightvol, Bit16s *partialBuf, Bit16s *mixedBuf);
-int i386_mixBuffers(Bit16s * buf1, Bit16s *buf2, int len);
-int i386_mixBuffersRingMix(Bit16s * buf1, Bit16s *buf2, int len);
-int i386_mixBuffersRing(Bit16s * buf1, Bit16s *buf2, int len);
-int i386_produceOutput1(Bit16s *useBuf, Bit16s *stream, Bit32u len, Bit16s volume);
-#endif
-
-#endif
-
-}
-
-#endif
diff --git a/audio/softsynth/mt32/mmath.h b/audio/softsynth/mt32/mmath.h
new file mode 100644
index 0000000000..226d73e27e
--- /dev/null
+++ b/audio/softsynth/mt32/mmath.h
@@ -0,0 +1,73 @@
+/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher
+ * Copyright (C) 2011 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef MT32EMU_MMATH_H
+#define MT32EMU_MMATH_H
+
+#define FIXEDPOINT_UDIV(x, y, point) (((x) << (point)) / ((y)))
+#define FIXEDPOINT_SDIV(x, y, point) (((x) * (1 << point)) / ((y)))
+#define FIXEDPOINT_UMULT(x, y, point) (((x) * (y)) >> point)
+#define FIXEDPOINT_SMULT(x, y, point) (((x) * (y)) / (1 << point))
+
+#define FIXEDPOINT_MAKE(x, point) ((Bit32u)((1 << point) * x))
+
+namespace MT32Emu {
+
+// Mathematical constants
+const double DOUBLE_PI = 3.141592653589793;
+const double DOUBLE_LN_10 = 2.302585092994046;
+const float FLOAT_PI = 3.1415927f;
+const float FLOAT_2PI = 6.2831853f;
+const float FLOAT_LN_2 = 0.6931472f;
+const float FLOAT_LN_10 = 2.3025851f;
+
+static inline float POWF(float x, float y) {
+ return pow(x, y);
+}
+
+static inline float EXPF(float x) {
+ return exp(x);
+}
+
+static inline float EXP2F(float x) {
+#ifdef __APPLE__
+ // on OSX exp2f() is 1.59 times faster than "exp() and the multiplication with FLOAT_LN_2"
+ return exp2(x);
+#else
+ return exp(FLOAT_LN_2 * x);
+#endif
+}
+
+static inline float EXP10F(float x) {
+ return exp(FLOAT_LN_10 * x);
+}
+
+static inline float LOGF(float x) {
+ return log(x);
+}
+
+static inline float LOG2F(float x) {
+ return log(x) / FLOAT_LN_2;
+}
+
+static inline float LOG10F(float x) {
+ return log10(x);
+}
+
+}
+
+#endif
diff --git a/audio/softsynth/mt32/module.mk b/audio/softsynth/mt32/module.mk
index a8329bc98c..995e450076 100644
--- a/audio/softsynth/mt32/module.mk
+++ b/audio/softsynth/mt32/module.mk
@@ -1,13 +1,19 @@
MODULE := audio/softsynth/mt32
MODULE_OBJS := \
- mt32_file.o \
- i386.o \
- part.o \
- partial.o \
- partialManager.o \
- synth.o \
- tables.o \
+ AReverbModel.o \
+ DelayReverb.o \
+ FreeverbModel.o \
+ LA32Ramp.o \
+ Part.o \
+ Partial.o \
+ PartialManager.o \
+ Poly.o \
+ Synth.o \
+ TVA.o \
+ TVF.o \
+ TVP.o \
+ Tables.o \
freeverb.o
# Include common rules
diff --git a/audio/softsynth/mt32/mt32_file.cpp b/audio/softsynth/mt32/mt32_file.cpp
deleted file mode 100644
index 643082b086..0000000000
--- a/audio/softsynth/mt32/mt32_file.cpp
+++ /dev/null
@@ -1,69 +0,0 @@
-/* Copyright (c) 2003-2005 Various contributors
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- */
-
-
-#include "mt32emu.h"
-
-namespace MT32Emu {
-
-bool File::readBit16u(Bit16u *in) {
- Bit8u b[2];
- if (read(&b[0], 2) != 2)
- return false;
- *in = ((b[0] << 8) | b[1]);
- return true;
-}
-
-bool File::readBit32u(Bit32u *in) {
- Bit8u b[4];
- if (read(&b[0], 4) != 4)
- return false;
- *in = ((b[0] << 24) | (b[1] << 16) | (b[2] << 8) | b[3]);
- return true;
-}
-
-bool File::writeBit16u(Bit16u out) {
- if (!writeBit8u((Bit8u)((out & 0xFF00) >> 8))) {
- return false;
- }
- if (!writeBit8u((Bit8u)(out & 0x00FF))) {
- return false;
- }
- return true;
-}
-
-bool File::writeBit32u(Bit32u out) {
- if (!writeBit8u((Bit8u)((out & 0xFF000000) >> 24))) {
- return false;
- }
- if (!writeBit8u((Bit8u)((out & 0x00FF0000) >> 16))) {
- return false;
- }
- if (!writeBit8u((Bit8u)((out & 0x0000FF00) >> 8))) {
- return false;
- }
- if (!writeBit8u((Bit8u)(out & 0x000000FF))) {
- return false;
- }
- return true;
-}
-
-} // End of namespace MT32Emu
diff --git a/audio/softsynth/mt32/mt32_file.h b/audio/softsynth/mt32/mt32_file.h
deleted file mode 100644
index e6641660ee..0000000000
--- a/audio/softsynth/mt32/mt32_file.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/* Copyright (c) 2003-2005 Various contributors
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- */
-
-#ifndef MT32EMU_FILE_H
-#define MT32EMU_FILE_H
-
-#include "common/scummsys.h"
-
-namespace MT32Emu {
-
-class File {
-public:
- enum OpenMode {
- OpenMode_read = 0,
- OpenMode_write = 1
- };
- virtual ~File() {}
- virtual void close() = 0;
- virtual size_t read(void *in, size_t size) = 0;
- virtual bool readBit8u(Bit8u *in) = 0;
- virtual bool readBit16u(Bit16u *in);
- virtual bool readBit32u(Bit32u *in);
- virtual size_t write(const void *out, size_t size) = 0;
- virtual bool writeBit8u(Bit8u out) = 0;
- // Note: May write a single byte to the file before failing
- virtual bool writeBit16u(Bit16u out);
- // Note: May write some (<4) bytes to the file before failing
- virtual bool writeBit32u(Bit32u out);
- virtual bool isEOF() = 0;
-};
-
-} // End of namespace MT32Emu
-
-#endif
diff --git a/audio/softsynth/mt32/mt32emu.h b/audio/softsynth/mt32/mt32emu.h
index 6eedf04bc0..091819b95c 100644
--- a/audio/softsynth/mt32/mt32emu.h
+++ b/audio/softsynth/mt32/mt32emu.h
@@ -1,37 +1,70 @@
-/* Copyright (c) 2003-2005 Various contributors
+/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher
+ * Copyright (C) 2011 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
*
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 2.1 of the License, or
+ * (at your option) any later version.
*
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
*
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef MT32EMU_MT32EMU_H
#define MT32EMU_MT32EMU_H
// Debugging
-// Show the instruments played
-#define MT32EMU_MONITOR_INSTRUMENTS 1
-// Shows number of partials MT-32 is playing, and on which parts
+
+// 0: Standard debug output is not stamped with the rendered sample count
+// 1: Standard debug output is stamped with the rendered sample count
+// NOTE: The "samplestamp" corresponds to the end of the last completed rendering run.
+// This is important to bear in mind for debug output that occurs during a run.
+#define MT32EMU_DEBUG_SAMPLESTAMPS 0
+
+// 0: No debug output for initialisation progress
+// 1: Debug output for initialisation progress
+#define MT32EMU_MONITOR_INIT 0
+
+// 0: No debug output for MIDI events
+// 1: Debug output for weird MIDI events
+#define MT32EMU_MONITOR_MIDI 0
+
+// 0: No debug output for note on/off
+// 1: Basic debug output for note on/off
+// 2: Comprehensive debug output for note on/off
+#define MT32EMU_MONITOR_INSTRUMENTS 0
+
+// 0: No debug output for partial allocations
+// 1: Show partial stats when an allocation fails
+// 2: Show partial stats with every new poly
+// 3: Show individual partial allocations/deactivations
#define MT32EMU_MONITOR_PARTIALS 0
-// Determines how the waveform cache file is handled (must be regenerated after sampling rate change)
-#define MT32EMU_WAVECACHEMODE 0 // Load existing cache if possible, otherwise generate and save cache
-//#define MT32EMU_WAVECACHEMODE 1 // Load existing cache if possible, otherwise generate but don't save cache
-//#define MT32EMU_WAVECACHEMODE 2 // Ignore existing cache, generate and save cache
-//#define MT32EMU_WAVECACHEMODE 3 // Ignore existing cache, generate but don't save cache
+
+// 0: No debug output for sysex
+// 1: Basic debug output for sysex
+#define MT32EMU_MONITOR_SYSEX 0
+
+// 0: No debug output for sysex writes to the timbre areas
+// 1: Debug output with the name and location of newly-written timbres
+// 2: Complete dump of timbre parameters for newly-written timbres
+#define MT32EMU_MONITOR_TIMBRES 0
+
+// 0: No TVA/TVF-related debug output.
+// 1: Shows changes to TVA/TVF target, increment and phase.
+#define MT32EMU_MONITOR_TVA 0
+#define MT32EMU_MONITOR_TVF 0
+
+
+// 0: Use LUTs to speedup WG
+// 1: Use precise float math
+#define MT32EMU_ACCURATE_WG 0
+
+#define MT32EMU_USE_EXTINT 0
// Configuration
// The maximum number of partials playing simultaneously
@@ -39,32 +72,43 @@
// The maximum number of notes playing simultaneously per part.
// No point making it more than MT32EMU_MAX_PARTIALS, since each note needs at least one partial.
#define MT32EMU_MAX_POLY 32
-// This calculates the exact frequencies of notes as they are played, instead of offsetting from pre-cached semitones. Potentially very slow.
-#define MT32EMU_ACCURATENOTES 0
-
-#if (defined (_MSC_VER) && defined(_M_IX86))
-#define MT32EMU_HAVE_X86
-#elif defined(__GNUC__)
-#if __GNUC__ >= 3 && defined(__i386__)
-#define MT32EMU_HAVE_X86
-#endif
-#endif
-#ifdef MT32EMU_HAVE_X86
-#define MT32EMU_USE_MMX 1
-#else
-#define MT32EMU_USE_MMX 0
-#endif
+// If non-zero, deletes reverb buffers that are not in use to save memory.
+// If zero, keeps reverb buffers for all modes around all the time to avoid allocating/freeing in the critical path.
+#define MT32EMU_REDUCE_REVERB_MEMORY 1
+
+// 0: Use standard Freeverb
+// 1: Use AReverb (currently not properly tuned)
+#define MT32EMU_USE_AREVERBMODEL 0
+
+namespace MT32Emu
+{
+// The higher this number, the more memory will be used, but the more samples can be processed in one run -
+// various parts of sample generation can be processed more efficiently in a single run.
+// A run's maximum length is that given to Synth::render(), so giving a value here higher than render() is ever
+// called with will give no gain (but simply waste the memory).
+// Note that this value does *not* in any way impose limitations on the length given to render(), and has no effect
+// on the generated audio.
+// This value must be >= 1.
+const unsigned int MAX_SAMPLES_PER_RUN = 4096;
-#include "freeverb.h"
+// This determines the amount of memory available for simulating delays.
+// If set too low, partials aborted to allow other partials to play will not end gracefully, but will terminate
+// abruptly and potentially cause a pop/crackle in the audio output.
+// This value must be >= 1.
+const unsigned int MAX_PRERENDER_SAMPLES = 1024;
+}
-#include "structures.h"
-#include "i386.h"
-#include "mt32_file.h"
-#include "tables.h"
-#include "partial.h"
-#include "partialManager.h"
-#include "part.h"
-#include "synth.h"
+#include "Structures.h"
+#include "common/file.h"
+#include "Tables.h"
+#include "Poly.h"
+#include "LA32Ramp.h"
+#include "TVA.h"
+#include "TVP.h"
+#include "TVF.h"
+#include "Partial.h"
+#include "Part.h"
+#include "Synth.h"
#endif
diff --git a/audio/softsynth/mt32/part.cpp b/audio/softsynth/mt32/part.cpp
deleted file mode 100644
index 9f9269cba5..0000000000
--- a/audio/softsynth/mt32/part.cpp
+++ /dev/null
@@ -1,633 +0,0 @@
-/* Copyright (c) 2003-2005 Various contributors
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- */
-
-#include <string.h>
-#include <math.h>
-
-#include "mt32emu.h"
-
-namespace MT32Emu {
-
-static const Bit8u PartialStruct[13] = {
- 0, 0, 2, 2, 1, 3,
- 3, 0, 3, 0, 2, 1, 3 };
-
-static const Bit8u PartialMixStruct[13] = {
- 0, 1, 0, 1, 1, 0,
- 1, 3, 3, 2, 2, 2, 2 };
-
-static const float floatKeyfollow[17] = {
- -1.0f, -1.0f/2.0f, -1.0f/4.0f, 0.0f,
- 1.0f/8.0f, 1.0f/4.0f, 3.0f/8.0f, 1.0f/2.0f, 5.0f/8.0f, 3.0f/4.0f, 7.0f/8.0f, 1.0f,
- 5.0f/4.0f, 3.0f/2.0f, 2.0f,
- 1.0009765625f, 1.0048828125f
-};
-
-//FIXME:KG: Put this dpoly stuff somewhere better
-bool dpoly::isActive() const {
- return partials[0] != NULL || partials[1] != NULL || partials[2] != NULL || partials[3] != NULL;
-}
-
-Bit32u dpoly::getAge() const {
- for (int i = 0; i < 4; i++) {
- if (partials[i] != NULL) {
- return partials[i]->age;
- }
- }
- return 0;
-}
-
-RhythmPart::RhythmPart(Synth *useSynth, unsigned int usePartNum): Part(useSynth, usePartNum) {
- strcpy(name, "Rhythm");
- rhythmTemp = &synth->mt32ram.rhythmSettings[0];
- refresh();
-}
-
-Part::Part(Synth *useSynth, unsigned int usePartNum) {
- this->synth = useSynth;
- this->partNum = usePartNum;
- patchCache[0].dirty = true;
- holdpedal = false;
- patchTemp = &synth->mt32ram.patchSettings[partNum];
- if (usePartNum == 8) {
- // Nasty hack for rhythm
- timbreTemp = NULL;
- } else {
- sprintf(name, "Part %d", partNum + 1);
- timbreTemp = &synth->mt32ram.timbreSettings[partNum];
- }
- currentInstr[0] = 0;
- currentInstr[10] = 0;
- expression = 127;
- volumeMult = 0;
- volumesetting.leftvol = 32767;
- volumesetting.rightvol = 32767;
- bend = 0.0f;
- memset(polyTable,0,sizeof(polyTable));
- memset(patchCache, 0, sizeof(patchCache));
-}
-
-void Part::setHoldPedal(bool pedalval) {
- if (holdpedal && !pedalval) {
- holdpedal = false;
- stopPedalHold();
- } else {
- holdpedal = pedalval;
- }
-}
-
-void RhythmPart::setBend(unsigned int midiBend) {
- synth->printDebug("%s: Setting bend (%d) not supported on rhythm", name, midiBend);
- return;
-}
-
-void Part::setBend(unsigned int midiBend) {
- // FIXME:KG: Slightly unbalanced increments, but I wanted min -1.0, center 0.0 and max 1.0
- if (midiBend <= 0x2000) {
- bend = ((signed int)midiBend - 0x2000) / (float)0x2000;
- } else {
- bend = ((signed int)midiBend - 0x2000) / (float)0x1FFF;
- }
- // Loop through all partials to update their bend
- for (int i = 0; i < MT32EMU_MAX_POLY; i++) {
- for (int j = 0; j < 4; j++) {
- if (polyTable[i].partials[j] != NULL) {
- polyTable[i].partials[j]->setBend(bend);
- }
- }
- }
-}
-
-void RhythmPart::setModulation(unsigned int midiModulation) {
- synth->printDebug("%s: Setting modulation (%d) not supported on rhythm", name, midiModulation);
-}
-
-void Part::setModulation(unsigned int midiModulation) {
- // Just a bloody guess, as always, before I get things figured out
- for (int t = 0; t < 4; t++) {
- if (patchCache[t].playPartial) {
- int newrate = (patchCache[t].modsense * midiModulation) >> 7;
- //patchCache[t].lfoperiod = lfotable[newrate];
- patchCache[t].lfodepth = newrate;
- //FIXME:KG: timbreTemp->partial[t].lfo.depth =
- }
- }
-}
-
-void RhythmPart::refresh() {
- updateVolume();
- // (Re-)cache all the mapped timbres ahead of time
- for (unsigned int drumNum = 0; drumNum < synth->controlROMMap->rhythmSettingsCount; drumNum++) {
- int drumTimbreNum = rhythmTemp[drumNum].timbre;
- if (drumTimbreNum >= 127) // 94 on MT-32
- continue;
- Bit16s pan = rhythmTemp[drumNum].panpot; // They use R-L 0-14...
- // FIXME:KG: Panning cache should be backed up to partials using it, too
- if (pan < 7) {
- drumPan[drumNum].leftvol = pan * 4681;
- drumPan[drumNum].rightvol = 32767;
- } else {
- drumPan[drumNum].rightvol = (14 - pan) * 4681;
- drumPan[drumNum].leftvol = 32767;
- }
- PatchCache *cache = drumCache[drumNum];
- backupCacheToPartials(cache);
- for (int t = 0; t < 4; t++) {
- // Common parameters, stored redundantly
- cache[t].dirty = true;
- cache[t].pitchShift = 0.0f;
- cache[t].benderRange = 0.0f;
- cache[t].pansetptr = &drumPan[drumNum];
- cache[t].reverb = rhythmTemp[drumNum].reverbSwitch > 0;
- }
- }
-}
-
-void Part::refresh() {
- updateVolume();
- backupCacheToPartials(patchCache);
- for (int t = 0; t < 4; t++) {
- // Common parameters, stored redundantly
- patchCache[t].dirty = true;
- patchCache[t].pitchShift = (patchTemp->patch.keyShift - 24) + (patchTemp->patch.fineTune - 50) / 100.0f;
- patchCache[t].benderRange = patchTemp->patch.benderRange;
- patchCache[t].pansetptr = &volumesetting;
- patchCache[t].reverb = patchTemp->patch.reverbSwitch > 0;
- }
- memcpy(currentInstr, timbreTemp->common.name, 10);
-}
-
-const char *Part::getCurrentInstr() const {
- return &currentInstr[0];
-}
-
-void RhythmPart::refreshTimbre(unsigned int absTimbreNum) {
- for (int m = 0; m < 85; m++) {
- if (rhythmTemp[m].timbre == absTimbreNum - 128)
- drumCache[m][0].dirty = true;
- }
-}
-
-void Part::refreshTimbre(unsigned int absTimbreNum) {
- if (getAbsTimbreNum() == absTimbreNum) {
- memcpy(currentInstr, timbreTemp->common.name, 10);
- patchCache[0].dirty = true;
- }
-}
-
-int Part::fixBiaslevel(int srcpnt, int *dir) {
- int noteat = srcpnt & 0x3F;
- int outnote;
- if (srcpnt < 64)
- *dir = 0;
- else
- *dir = 1;
- outnote = 33 + noteat;
- //synth->printDebug("Bias note %d, dir %d", outnote, *dir);
-
- return outnote;
-}
-
-int Part::fixKeyfollow(int srckey) {
- if (srckey>=0 && srckey<=16) {
- int keyfix[17] = { -256*16, -128*16, -64*16, 0, 32*16, 64*16, 96*16, 128*16, (128+32)*16, 192*16, (192+32)*16, 256*16, (256+64)*16, (256+128)*16, (512)*16, 4100, 4116};
- return keyfix[srckey];
- } else {
- //LOG(LOG_ERROR|LOG_MISC,"Missed key: %d", srckey);
- return 256;
- }
-}
-
-void Part::abortPoly(dpoly *poly) {
- if (!poly->isPlaying) {
- return;
- }
- for (int i = 0; i < 4; i++) {
- Partial *partial = poly->partials[i];
- if (partial != NULL) {
- partial->deactivate();
- }
- }
- poly->isPlaying = false;
-}
-
-void Part::setPatch(const PatchParam *patch) {
- patchTemp->patch = *patch;
-}
-
-void RhythmPart::setTimbre(TimbreParam * /*timbre*/) {
- synth->printDebug("%s: Attempted to call setTimbre() - doesn't make sense for rhythm", name);
-}
-
-void Part::setTimbre(TimbreParam *timbre) {
- *timbreTemp = *timbre;
-}
-
-unsigned int RhythmPart::getAbsTimbreNum() const {
- synth->printDebug("%s: Attempted to call getAbsTimbreNum() - doesn't make sense for rhythm", name);
- return 0;
-}
-
-unsigned int Part::getAbsTimbreNum() const {
- return (patchTemp->patch.timbreGroup * 64) + patchTemp->patch.timbreNum;
-}
-
-void RhythmPart::setProgram(unsigned int patchNum) {
- synth->printDebug("%s: Attempt to set program (%d) on rhythm is invalid", name, patchNum);
-}
-
-void Part::setProgram(unsigned int patchNum) {
- setPatch(&synth->mt32ram.patches[patchNum]);
- setTimbre(&synth->mt32ram.timbres[getAbsTimbreNum()].timbre);
-
- refresh();
-
- allSoundOff(); //FIXME:KG: Is this correct?
-}
-
-void Part::backupCacheToPartials(PatchCache cache[4]) {
- // check if any partials are still playing with the old patch cache
- // if so then duplicate the cached data from the part to the partial so that
- // we can change the part's cache without affecting the partial.
- // We delay this until now to avoid a copy operation with every note played
- for (int m = 0; m < MT32EMU_MAX_POLY; m++) {
- for (int i = 0; i < 4; i++) {
- Partial *partial = polyTable[m].partials[i];
- if (partial != NULL && partial->patchCache == &cache[i]) {
- partial->cachebackup = cache[i];
- partial->patchCache = &partial->cachebackup;
- }
- }
- }
-}
-
-void Part::cacheTimbre(PatchCache cache[4], const TimbreParam *timbre) {
- backupCacheToPartials(cache);
- int partialCount = 0;
- for (int t = 0; t < 4; t++) {
- cache[t].PCMPartial = false;
- if (((timbre->common.pmute >> t) & 0x1) == 1) {
- cache[t].playPartial = true;
- partialCount++;
- } else {
- cache[t].playPartial = false;
- continue;
- }
-
- // Calculate and cache common parameters
-
- cache[t].pcm = timbre->partial[t].wg.pcmwave;
- cache[t].useBender = (timbre->partial[t].wg.bender == 1);
-
- switch (t) {
- case 0:
- cache[t].PCMPartial = (PartialStruct[(int)timbre->common.pstruct12] & 0x2) ? true : false;
- cache[t].structureMix = PartialMixStruct[(int)timbre->common.pstruct12];
- cache[t].structurePosition = 0;
- cache[t].structurePair = 1;
- break;
- case 1:
- cache[t].PCMPartial = (PartialStruct[(int)timbre->common.pstruct12] & 0x1) ? true : false;
- cache[t].structureMix = PartialMixStruct[(int)timbre->common.pstruct12];
- cache[t].structurePosition = 1;
- cache[t].structurePair = 0;
- break;
- case 2:
- cache[t].PCMPartial = (PartialStruct[(int)timbre->common.pstruct34] & 0x2) ? true : false;
- cache[t].structureMix = PartialMixStruct[(int)timbre->common.pstruct34];
- cache[t].structurePosition = 0;
- cache[t].structurePair = 3;
- break;
- case 3:
- cache[t].PCMPartial = (PartialStruct[(int)timbre->common.pstruct34] & 0x1) ? true : false;
- cache[t].structureMix = PartialMixStruct[(int)timbre->common.pstruct34];
- cache[t].structurePosition = 1;
- cache[t].structurePair = 2;
- break;
- default:
- break;
- }
-
- cache[t].waveform = timbre->partial[t].wg.waveform;
- cache[t].pulsewidth = timbre->partial[t].wg.pulsewid;
- cache[t].pwsens = timbre->partial[t].wg.pwvelo;
- if (timbre->partial[t].wg.keyfollow > 16) {
- synth->printDebug("Bad keyfollow value in timbre!");
- cache[t].pitchKeyfollow = 1.0f;
- } else {
- cache[t].pitchKeyfollow = floatKeyfollow[timbre->partial[t].wg.keyfollow];
- }
-
- cache[t].pitch = timbre->partial[t].wg.coarse + (timbre->partial[t].wg.fine - 50) / 100.0f + 24.0f;
- cache[t].pitchEnv = timbre->partial[t].env;
- cache[t].pitchEnv.sensitivity = (char)((float)cache[t].pitchEnv.sensitivity * 1.27f);
- cache[t].pitchsustain = cache[t].pitchEnv.level[3];
-
- // Calculate and cache TVA envelope stuff
- cache[t].ampEnv = timbre->partial[t].tva;
- cache[t].ampEnv.level = (char)((float)cache[t].ampEnv.level * 1.27f);
-
- cache[t].ampbias[0] = fixBiaslevel(cache[t].ampEnv.biaspoint1, &cache[t].ampdir[0]);
- cache[t].ampblevel[0] = 12 - cache[t].ampEnv.biaslevel1;
- cache[t].ampbias[1] = fixBiaslevel(cache[t].ampEnv.biaspoint2, &cache[t].ampdir[1]);
- cache[t].ampblevel[1] = 12 - cache[t].ampEnv.biaslevel2;
- cache[t].ampdepth = cache[t].ampEnv.envvkf * cache[t].ampEnv.envvkf;
-
- // Calculate and cache filter stuff
- cache[t].filtEnv = timbre->partial[t].tvf;
- cache[t].filtkeyfollow = fixKeyfollow(cache[t].filtEnv.keyfollow);
- cache[t].filtEnv.envdepth = (char)((float)cache[t].filtEnv.envdepth * 1.27);
- cache[t].tvfbias = fixBiaslevel(cache[t].filtEnv.biaspoint, &cache[t].tvfdir);
- cache[t].tvfblevel = cache[t].filtEnv.biaslevel;
- cache[t].filtsustain = cache[t].filtEnv.envlevel[3];
-
- // Calculate and cache LFO stuff
- cache[t].lfodepth = timbre->partial[t].lfo.depth;
- cache[t].lfoperiod = synth->tables.lfoPeriod[(int)timbre->partial[t].lfo.rate];
- cache[t].lforate = timbre->partial[t].lfo.rate;
- cache[t].modsense = timbre->partial[t].lfo.modsense;
- }
- for (int t = 0; t < 4; t++) {
- // Common parameters, stored redundantly
- cache[t].dirty = false;
- cache[t].partialCount = partialCount;
- cache[t].sustain = (timbre->common.nosustain == 0);
- }
- //synth->printDebug("Res 1: %d 2: %d 3: %d 4: %d", cache[0].waveform, cache[1].waveform, cache[2].waveform, cache[3].waveform);
-
-#if MT32EMU_MONITOR_INSTRUMENTS == 1
- synth->printDebug("%s (%s): Recached timbre", name, currentInstr);
- for (int i = 0; i < 4; i++) {
- synth->printDebug(" %d: play=%s, pcm=%s (%d), wave=%d", i, cache[i].playPartial ? "YES" : "NO", cache[i].PCMPartial ? "YES" : "NO", timbre->partial[i].wg.pcmwave, timbre->partial[i].wg.waveform);
- }
-#endif
-}
-
-const char *Part::getName() const {
- return name;
-}
-
-void Part::updateVolume() {
- volumeMult = synth->tables.volumeMult[patchTemp->outlevel * expression / 127];
-}
-
-int Part::getVolume() const {
- // FIXME: Use the mappings for this in the control ROM
- return patchTemp->outlevel * 127 / 100;
-}
-
-void Part::setVolume(int midiVolume) {
- // FIXME: Use the mappings for this in the control ROM
- patchTemp->outlevel = (Bit8u)(midiVolume * 100 / 127);
- updateVolume();
- synth->printDebug("%s (%s): Set volume to %d", name, currentInstr, midiVolume);
-}
-
-void Part::setExpression(int midiExpression) {
- expression = midiExpression;
- updateVolume();
-}
-
-void RhythmPart::setPan(unsigned int midiPan)
-{
- // FIXME:KG: This is unchangeable for drums (they always use drumPan), is that correct?
- synth->printDebug("%s: Setting pan (%d) not supported on rhythm", name, midiPan);
-}
-
-void Part::setPan(unsigned int midiPan) {
- // FIXME:KG: Tweaked this a bit so that we have a left 100%, center and right 100%
- // (But this makes the range somewhat skewed)
- // Check against the real thing
- // NOTE: Panning is inverted compared to GM.
- if (midiPan < 64) {
- volumesetting.leftvol = (Bit16s)(midiPan * 512);
- volumesetting.rightvol = 32767;
- } else if (midiPan == 64) {
- volumesetting.leftvol = 32767;
- volumesetting.rightvol = 32767;
- } else {
- volumesetting.rightvol = (Bit16s)((127 - midiPan) * 520);
- volumesetting.leftvol = 32767;
- }
- patchTemp->panpot = (Bit8u)(midiPan * 14 / 127);
- //synth->printDebug("%s (%s): Set pan to %d", name, currentInstr, panpot);
-}
-
-void RhythmPart::playNote(unsigned int key, int vel) {
- if (key < 24 || key > 108)/*> 87 on MT-32)*/ {
- synth->printDebug("%s: Attempted to play invalid key %d", name, key);
- return;
- }
- int drumNum = key - 24;
- int drumTimbreNum = rhythmTemp[drumNum].timbre;
- if (drumTimbreNum >= 127) { // 94 on MT-32
- synth->printDebug("%s: Attempted to play unmapped key %d", name, key);
- return;
- }
- int absTimbreNum = drumTimbreNum + 128;
- TimbreParam *timbre = &synth->mt32ram.timbres[absTimbreNum].timbre;
- memcpy(currentInstr, timbre->common.name, 10);
-#if MT32EMU_MONITOR_INSTRUMENTS == 1
- synth->printDebug("%s (%s): starting poly (drum %d, timbre %d) - Vel %d Key %d", name, currentInstr, drumNum, absTimbreNum, vel, key);
-#endif
- if (drumCache[drumNum][0].dirty) {
- cacheTimbre(drumCache[drumNum], timbre);
- }
- playPoly(drumCache[drumNum], key, MIDDLEC, vel);
-}
-
-void Part::playNote(unsigned int key, int vel) {
- int freqNum = key;
- if (freqNum < 12) {
- synth->printDebug("%s (%s): Attempted to play invalid key %d < 12; moving up by octave", name, currentInstr, key);
- freqNum += 12;
- } else if (freqNum > 108) {
- synth->printDebug("%s (%s): Attempted to play invalid key %d > 108; moving down by octave", name, currentInstr, key);
- while (freqNum > 108) {
- freqNum -= 12;
- }
- }
- // POLY1 mode, Single Assign
- // Haven't found any software that uses any of the other poly modes
- // FIXME:KG: Should this also apply to rhythm?
- for (unsigned int i = 0; i < MT32EMU_MAX_POLY; i++) {
- if (polyTable[i].isActive() && (polyTable[i].key == key)) {
- //AbortPoly(&polyTable[i]);
- stopNote(key);
- break;
- }
- }
-#if MT32EMU_MONITOR_INSTRUMENTS == 1
- synth->printDebug("%s (%s): starting poly - Vel %d Key %d", name, currentInstr, vel, key);
-#endif
- if (patchCache[0].dirty) {
- cacheTimbre(patchCache, timbreTemp);
- }
- playPoly(patchCache, key, freqNum, vel);
-}
-
-void Part::playPoly(const PatchCache cache[4], unsigned int key, int freqNum, int vel) {
- unsigned int needPartials = cache[0].partialCount;
- unsigned int freePartials = synth->partialManager->getFreePartialCount();
-
- if (freePartials < needPartials) {
- if (!synth->partialManager->freePartials(needPartials - freePartials, partNum)) {
- synth->printDebug("%s (%s): Insufficient free partials to play key %d (vel=%d); needed=%d, free=%d", name, currentInstr, key, vel, needPartials, synth->partialManager->getFreePartialCount());
- return;
- }
- }
- // Find free poly
- int m;
- for (m = 0; m < MT32EMU_MAX_POLY; m++) {
- if (!polyTable[m].isActive()) {
- break;
- }
- }
- if (m == MT32EMU_MAX_POLY) {
- synth->printDebug("%s (%s): No free poly to play key %d (vel %d)", name, currentInstr, key, vel);
- return;
- }
-
- dpoly *tpoly = &polyTable[m];
-
- tpoly->isPlaying = true;
- tpoly->key = key;
- tpoly->isDecay = false;
- tpoly->freqnum = freqNum;
- tpoly->vel = vel;
- tpoly->pedalhold = false;
-
- bool allnull = true;
- for (int x = 0; x < 4; x++) {
- if (cache[x].playPartial) {
- tpoly->partials[x] = synth->partialManager->allocPartial(partNum);
- allnull = false;
- } else {
- tpoly->partials[x] = NULL;
- }
- }
-
- if (allnull)
- synth->printDebug("%s (%s): No partials to play for this instrument", name, this->currentInstr);
-
- tpoly->sustain = cache[0].sustain;
- tpoly->volumeptr = &volumeMult;
-
- for (int x = 0; x < 4; x++) {
- if (tpoly->partials[x] != NULL) {
- tpoly->partials[x]->startPartial(tpoly, &cache[x], tpoly->partials[cache[x].structurePair]);
- tpoly->partials[x]->setBend(bend);
- }
- }
-}
-
-static void startDecayPoly(dpoly *tpoly) {
- if (tpoly->isDecay) {
- return;
- }
- tpoly->isDecay = true;
-
- for (int t = 0; t < 4; t++) {
- Partial *partial = tpoly->partials[t];
- if (partial == NULL)
- continue;
- partial->startDecayAll();
- }
- tpoly->isPlaying = false;
-}
-
-void Part::allNotesOff() {
- // Note: Unchecked on real MT-32, but the MIDI specification states that all notes off (0x7B)
- // should treat the hold pedal as usual.
- // All *sound* off (0x78) should stop notes immediately regardless of the hold pedal.
- // The latter controller is not implemented on the MT-32 (according to the docs).
- for (int q = 0; q < MT32EMU_MAX_POLY; q++) {
- dpoly *tpoly = &polyTable[q];
- if (tpoly->isPlaying) {
- if (holdpedal)
- tpoly->pedalhold = true;
- else if (tpoly->sustain)
- startDecayPoly(tpoly);
- }
- }
-}
-
-void Part::allSoundOff() {
- for (int q = 0; q < MT32EMU_MAX_POLY; q++) {
- dpoly *tpoly = &polyTable[q];
- if (tpoly->isPlaying) {
- startDecayPoly(tpoly);
- }
- }
-}
-
-void Part::stopPedalHold() {
- for (int q = 0; q < MT32EMU_MAX_POLY; q++) {
- dpoly *tpoly;
- tpoly = &polyTable[q];
- if (tpoly->isActive() && tpoly->pedalhold)
- stopNote(tpoly->key);
- }
-}
-
-void Part::stopNote(unsigned int key) {
- // Non-sustaining instruments ignore stop commands.
- // They die away eventually anyway
-
-#if MT32EMU_MONITOR_INSTRUMENTS == 1
- synth->printDebug("%s (%s): stopping key %d", name, currentInstr, key);
-#endif
-
- if (key != 255) {
- for (int q = 0; q < MT32EMU_MAX_POLY; q++) {
- dpoly *tpoly = &polyTable[q];
- if (tpoly->isPlaying && tpoly->key == key) {
- if (holdpedal)
- tpoly->pedalhold = true;
- else if (tpoly->sustain)
- startDecayPoly(tpoly);
- }
- }
- return;
- }
-
- // Find oldest poly... yes, the MT-32 can be reconfigured to kill different poly first
- // This is simplest
- int oldest = -1;
- Bit32u oldage = 0;
-
- for (int q = 0; q < MT32EMU_MAX_POLY; q++) {
- dpoly *tpoly = &polyTable[q];
-
- if (tpoly->isPlaying && !tpoly->isDecay) {
- if (tpoly->getAge() >= oldage) {
- oldage = tpoly->getAge();
- oldest = q;
- }
- }
- }
-
- if (oldest != -1) {
- startDecayPoly(&polyTable[oldest]);
- }
-}
-
-}
diff --git a/audio/softsynth/mt32/part.h b/audio/softsynth/mt32/part.h
deleted file mode 100644
index 967298258c..0000000000
--- a/audio/softsynth/mt32/part.h
+++ /dev/null
@@ -1,112 +0,0 @@
-/* Copyright (c) 2003-2005 Various contributors
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- */
-
-#ifndef MT32EMU_PART_H
-#define MT32EMU_PART_H
-
-namespace MT32Emu {
-
-class Synth;
-
-class Part {
-private:
- // Pointers to the areas of the MT-32's memory dedicated to this part (for parts 1-8)
- MemParams::PatchTemp *patchTemp;
- TimbreParam *timbreTemp;
-
- // 0=Part 1, .. 7=Part 8, 8=Rhythm
- unsigned int partNum;
-
- bool holdpedal;
-
- StereoVolume volumesetting;
-
- PatchCache patchCache[4];
-
- float bend; // -1.0 .. +1.0
-
- dpoly polyTable[MT32EMU_MAX_POLY];
-
- void abortPoly(dpoly *poly);
-
- static int fixKeyfollow(int srckey);
- static int fixBiaslevel(int srcpnt, int *dir);
-
- void setPatch(const PatchParam *patch);
-
-protected:
- Synth *synth;
- char name[8]; // "Part 1".."Part 8", "Rhythm"
- char currentInstr[11];
- int expression;
- Bit32u volumeMult;
-
- void updateVolume();
- void backupCacheToPartials(PatchCache cache[4]);
- void cacheTimbre(PatchCache cache[4], const TimbreParam *timbre);
- void playPoly(const PatchCache cache[4], unsigned int key, int freqNum, int vel);
- const char *getName() const;
-
-public:
- Part(Synth *synth, unsigned int usePartNum);
- virtual ~Part() {}
- virtual void playNote(unsigned int key, int vel);
- void stopNote(unsigned int key);
- void allNotesOff();
- void allSoundOff();
- int getVolume() const;
- void setVolume(int midiVolume);
- void setExpression(int midiExpression);
- virtual void setPan(unsigned int midiPan);
- virtual void setBend(unsigned int midiBend);
- virtual void setModulation(unsigned int midiModulation);
- virtual void setProgram(unsigned int midiProgram);
- void setHoldPedal(bool pedalval);
- void stopPedalHold();
- virtual void refresh();
- virtual void refreshTimbre(unsigned int absTimbreNum);
- virtual void setTimbre(TimbreParam *timbre);
- virtual unsigned int getAbsTimbreNum() const;
- const char *getCurrentInstr() const;
-};
-
-class RhythmPart: public Part {
- // Pointer to the area of the MT-32's memory dedicated to rhythm
- const MemParams::RhythmTemp *rhythmTemp;
-
- // This caches the timbres/settings in use by the rhythm part
- PatchCache drumCache[85][4];
- StereoVolume drumPan[85];
-public:
- RhythmPart(Synth *synth, unsigned int usePartNum);
- void refresh();
- void refreshTimbre(unsigned int timbreNum);
- void setTimbre(TimbreParam *timbre);
- void playNote(unsigned int key, int vel);
- unsigned int getAbsTimbreNum() const;
- void setPan(unsigned int midiPan);
- void setBend(unsigned int midiBend);
- void setModulation(unsigned int midiModulation);
- void setProgram(unsigned int patchNum);
-};
-
-}
-#endif
diff --git a/audio/softsynth/mt32/partial.cpp b/audio/softsynth/mt32/partial.cpp
deleted file mode 100644
index c4f2e94ebe..0000000000
--- a/audio/softsynth/mt32/partial.cpp
+++ /dev/null
@@ -1,968 +0,0 @@
-/* Copyright (c) 2003-2005 Various contributors
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- */
-
-#include <stdlib.h>
-#include <math.h>
-#include <string.h>
-
-#include "mt32emu.h"
-
-#if defined(MACOSX) || defined(SOLARIS) || defined(__MINGW32__)
-// Older versions of Mac OS X didn't supply a powf function, so using it
-// will cause a binary incompatibility when trying to run a binary built
-// on a newer OS X release on an older one. And Solaris 8 doesn't provide
-// powf, floorf, fabsf etc. at all.
-// Cross-compiled MinGW32 toolchains suffer from a cross-compile bug in
-// libstdc++. math/stubs.o should be empty, but it comes with a symbol for
-// powf, resulting in a linker error because of multiple definitions.
-// Hence we re-define them here. The only potential drawback is that it
-// might be a little bit slower this way.
-#define powf(x,y) ((float)pow(x,y))
-#define floorf(x) ((float)floor(x))
-#define fabsf(x) ((float)fabs(x))
-#endif
-
-#define FIXEDPOINT_UDIV(x, y, point) (((x) << (point)) / ((y)))
-#define FIXEDPOINT_SDIV(x, y, point) (((x) * (1 << point)) / ((y)))
-#define FIXEDPOINT_UMULT(x, y, point) (((x) * (y)) >> point)
-#define FIXEDPOINT_SMULT(x, y, point) (((x) * (y)) / (1 << point))
-
-using namespace MT32Emu;
-
-Partial::Partial(Synth *useSynth) {
- this->synth = useSynth;
- ownerPart = -1;
- poly = NULL;
- pair = NULL;
-#if MT32EMU_ACCURATENOTES == 1
- for (int i = 0; i < 3; i++) {
- noteLookupStorage.waveforms[i] = new Bit16s[65536];
- }
- noteLookup = &noteLookupStorage;
-#endif
-}
-
-Partial::~Partial() {
-#if MT32EMU_ACCURATENOTES == 1
- for (int i = 0; i < 3; i++) {
- delete[] noteLookupStorage.waveforms[i];
- }
- delete[] noteLookupStorage.wavTable;
-#endif
-}
-
-int Partial::getOwnerPart() const {
- return ownerPart;
-}
-
-bool Partial::isActive() {
- return ownerPart > -1;
-}
-
-const dpoly *Partial::getDpoly() const {
- return this->poly;
-}
-
-void Partial::activate(int part) {
- // This just marks the partial as being assigned to a part
- ownerPart = part;
-}
-
-void Partial::deactivate() {
- ownerPart = -1;
- if (poly != NULL) {
- for (int i = 0; i < 4; i++) {
- if (poly->partials[i] == this) {
- poly->partials[i] = NULL;
- break;
- }
- }
- if (pair != NULL) {
- pair->pair = NULL;
- }
- }
-}
-
-void Partial::initKeyFollow(int key) {
- // Setup partial keyfollow
- // Note follow relative to middle C
-
- // Calculate keyfollow for pitch
-#if 1
- float rel = key == -1 ? 0.0f : (key - MIDDLEC);
- float newPitch = rel * patchCache->pitchKeyfollow + patchCache->pitch + patchCache->pitchShift;
- //FIXME:KG: Does it truncate the keyfollowed pitch to a semitone (towards MIDDLEC)?
- //int newKey = (int)(rel * patchCache->pitchKeyfollow);
- //float newPitch = newKey + patchCache->pitch + patchCache->pitchShift;
-#else
- float rel = key == -1 ? 0.0f : (key + patchCache->pitchShift - MIDDLEC);
- float newPitch = rel * patchCache->pitchKeyfollow + patchCache->pitch;
-#endif
-#if MT32EMU_ACCURATENOTES == 1
- noteVal = newPitch;
- synth->printDebug("key=%d, pitch=%f, pitchKeyfollow=%f, pitchShift=%f, newPitch=%f", key, (double)patchCache->pitch, (double)patchCache->pitchKeyfollow, (double)patchCache->pitchShift, (double)newPitch);
-#else
- float newPitchInt;
- float newPitchFract = modff(newPitch, &newPitchInt);
- if (newPitchFract > 0.5f) {
- newPitchInt += 1.0f;
- newPitchFract -= 1.0f;
- }
- noteVal = (int)newPitchInt;
- fineShift = (int)(powf(2.0f, newPitchFract / 12.0f) * 4096.0f);
- synth->printDebug("key=%d, pitch=%f, pitchKeyfollow=%f, pitchShift=%f, newPitch=%f, noteVal=%d, fineShift=%d", key, (double)patchCache->pitch, (double)patchCache->pitchKeyfollow, (double)patchCache->pitchShift, (double)newPitch, noteVal, fineShift);
-#endif
- // FIXME:KG: Raise/lower by octaves until in the supported range.
- while (noteVal > HIGHEST_NOTE) // FIXME:KG: see tables.cpp: >108?
- noteVal -= 12;
- while (noteVal < LOWEST_NOTE) // FIXME:KG: see tables.cpp: <12?
- noteVal += 12;
- // Calculate keyfollow for filter
- int keyfollow = ((key - MIDDLEC) * patchCache->filtkeyfollow) / 4096;
- if (keyfollow > 108)
- keyfollow = 108;
- else if (keyfollow < -108)
- keyfollow = -108;
- filtVal = synth->tables.tvfKeyfollowMult[keyfollow + 108];
- realVal = synth->tables.tvfKeyfollowMult[(noteVal - MIDDLEC) + 108];
-}
-
-int Partial::getKey() const {
- if (poly == NULL) {
- return -1;
- } else {
- return poly->key;
- }
-}
-
-void Partial::startPartial(dpoly *usePoly, const PatchCache *useCache, Partial *pairPartial) {
- if (usePoly == NULL || useCache == NULL) {
- synth->printDebug("*** Error: Starting partial for owner %d, usePoly=%s, useCache=%s", ownerPart, usePoly == NULL ? "*** NULL ***" : "OK", useCache == NULL ? "*** NULL ***" : "OK");
- return;
- }
- patchCache = useCache;
- poly = usePoly;
- mixType = patchCache->structureMix;
- structurePosition = patchCache->structurePosition;
-
- play = true;
- initKeyFollow(poly->freqnum); // Initializes noteVal, filtVal and realVal
-#if MT32EMU_ACCURATENOTES == 0
- noteLookup = &synth->tables.noteLookups[noteVal - LOWEST_NOTE];
-#else
- Tables::initNote(synth, &noteLookupStorage, noteVal, (float)synth->myProp.sampleRate, synth->masterTune, synth->pcmWaves, NULL);
-#endif
- keyLookup = &synth->tables.keyLookups[poly->freqnum - 12];
-
- if (patchCache->PCMPartial) {
- pcmNum = patchCache->pcm;
- if (synth->controlROMMap->pcmCount > 128) {
- // CM-32L, etc. support two "banks" of PCMs, selectable by waveform type parameter.
- if (patchCache->waveform > 1) {
- pcmNum += 128;
- }
- }
- pcmWave = &synth->pcmWaves[pcmNum];
- } else {
- pcmWave = NULL;
- }
-
- lfoPos = 0;
- pulsewidth = patchCache->pulsewidth + synth->tables.pwVelfollowAdd[patchCache->pwsens][poly->vel];
- if (pulsewidth > 100) {
- pulsewidth = 100;
- } else if (pulsewidth < 0) {
- pulsewidth = 0;
- }
-
- for (int e = 0; e < 3; e++) {
- envs[e].envpos = 0;
- envs[e].envstat = -1;
- envs[e].envbase = 0;
- envs[e].envdist = 0;
- envs[e].envsize = 0;
- envs[e].sustaining = false;
- envs[e].decaying = false;
- envs[e].prevlevel = 0;
- envs[e].counter = 0;
- envs[e].count = 0;
- }
- ampEnvVal = 0;
- pitchEnvVal = 0;
- pitchSustain = false;
- loopPos = 0;
- partialOff.pcmoffset = partialOff.pcmplace = 0;
- pair = pairPartial;
- useNoisePair = pairPartial == NULL && (mixType == 1 || mixType == 2);
- age = 0;
- alreadyOutputed = false;
- memset(history,0,sizeof(history));
-}
-
-Bit16s *Partial::generateSamples(long length) {
- if (!isActive() || alreadyOutputed) {
- return NULL;
- }
- if (poly == NULL) {
- synth->printDebug("*** ERROR: poly is NULL at Partial::generateSamples()!");
- return NULL;
- }
-
- alreadyOutputed = true;
-
- // Generate samples
-
- Bit16s *partialBuf = &myBuffer[0];
- Bit32u volume = *poly->volumeptr;
- while (length--) {
- Bit32s envval;
- Bit32s sample = 0;
- if (!envs[EnvelopeType_amp].sustaining) {
- if (envs[EnvelopeType_amp].count <= 0) {
- Bit32u ampval = getAmpEnvelope();
- if (!play) {
- deactivate();
- break;
- }
- if (ampval > 100) {
- ampval = 100;
- }
-
- ampval = synth->tables.volumeMult[ampval];
- ampval = FIXEDPOINT_UMULT(ampval, synth->tables.tvaVelfollowMult[poly->vel][(int)patchCache->ampEnv.velosens], 8);
- //if (envs[EnvelopeType_amp].sustaining)
- ampEnvVal = ampval;
- }
- --envs[EnvelopeType_amp].count;
- }
-
- unsigned int lfoShift = 0x1000;
- if (pitchSustain) {
- // Calculate LFO position
- // LFO does not kick in completely until pitch envelope sustains
- if (patchCache->lfodepth > 0) {
- lfoPos++;
- if (lfoPos >= patchCache->lfoperiod)
- lfoPos = 0;
- int lfoatm = FIXEDPOINT_UDIV(lfoPos, patchCache->lfoperiod, 16);
- int lfoatr = synth->tables.sintable[lfoatm];
- lfoShift = synth->tables.lfoShift[patchCache->lfodepth][lfoatr];
- }
- } else {
- // Calculate Pitch envelope
- envval = getPitchEnvelope();
- int pd = patchCache->pitchEnv.depth;
- pitchEnvVal = synth->tables.pitchEnvVal[pd][envval];
- }
-
- int delta;
-
- // Wrap positions or end if necessary
- if (patchCache->PCMPartial) {
- // PCM partial
-
- delta = noteLookup->wavTable[pcmNum];
- int len = pcmWave->len;
- if (partialOff.pcmplace >= len) {
- if (pcmWave->loop) {
- //partialOff.pcmplace = partialOff.pcmoffset = 0;
- partialOff.pcmplace %= len;
- } else {
- play = false;
- deactivate();
- break;
- }
- }
- } else {
- // Synthesis partial
- delta = 0x10000;
- partialOff.pcmplace %= (Bit16u)noteLookup->div2;
- }
-
- // Build delta for position of next sample
- // Fix delta code
- Bit32u tdelta = delta;
-#if MT32EMU_ACCURATENOTES == 0
- tdelta = FIXEDPOINT_UMULT(tdelta, fineShift, 12);
-#endif
- tdelta = FIXEDPOINT_UMULT(tdelta, pitchEnvVal, 12);
- tdelta = FIXEDPOINT_UMULT(tdelta, lfoShift, 12);
- tdelta = FIXEDPOINT_UMULT(tdelta, bendShift, 12);
- delta = (int)tdelta;
-
- // Get waveform - either PCM or synthesized sawtooth or square
- if (ampEnvVal > 0) {
- if (patchCache->PCMPartial) {
- // Render PCM sample
- int ra, rb, dist;
- Bit32u taddr;
- Bit32u pcmAddr = pcmWave->addr;
- if (delta < 0x10000) {
- // Linear sound interpolation
- taddr = pcmAddr + partialOff.pcmplace;
- ra = synth->pcmROMData[taddr];
- taddr++;
- if (taddr == pcmAddr + pcmWave->len) {
- // Past end of PCM
- if (pcmWave->loop) {
- rb = synth->pcmROMData[pcmAddr];
- } else {
- rb = 0;
- }
- } else {
- rb = synth->pcmROMData[taddr];
- }
- dist = rb - ra;
- sample = (ra + ((dist * (Bit32s)(partialOff.pcmoffset >> 8)) >> 8));
- } else {
- // Sound decimation
- // The right way to do it is to use a lowpass filter on the waveform before selecting
- // a point. This is too slow. The following approximates this as fast as possible
- int idelta = delta >> 16;
- taddr = pcmAddr + partialOff.pcmplace;
- ra = synth->pcmROMData[taddr++];
- for (int ix = 0; ix < idelta - 1; ix++) {
- if (taddr == pcmAddr + pcmWave->len) {
- // Past end of PCM
- if (pcmWave->loop) {
- taddr = pcmAddr;
- } else {
- // Behave as if all subsequent samples were 0
- break;
- }
- }
- ra += synth->pcmROMData[taddr++];
- }
- sample = ra / idelta;
- }
- } else {
- // Render synthesised sample
- int toff = partialOff.pcmplace;
- int minorplace = partialOff.pcmoffset >> 14;
- Bit32s filterInput;
- Bit32s filtval = getFiltEnvelope();
-
- //synth->printDebug("Filtval: %d", filtval);
-
- if ((patchCache->waveform & 1) == 0) {
- // Square waveform. Made by combining two pregenerated bandlimited
- // sawtooth waveforms
- Bit32u ofsA = ((toff << 2) + minorplace) % noteLookup->waveformSize[0];
- int width = FIXEDPOINT_UMULT(noteLookup->div2, synth->tables.pwFactor[pulsewidth], 7);
- Bit32u ofsB = (ofsA + width) % noteLookup->waveformSize[0];
- Bit16s pa = noteLookup->waveforms[0][ofsA];
- Bit16s pb = noteLookup->waveforms[0][ofsB];
- filterInput = pa - pb;
- // Non-bandlimited squarewave
- /*
- ofs = FIXEDPOINT_UMULT(noteLookup->div2, synth->tables.pwFactor[patchCache->pulsewidth], 8);
- if (toff < ofs)
- sample = 1 * WGAMP;
- else
- sample = -1 * WGAMP;
- */
- } else {
- // Sawtooth. Made by combining the full cosine and half cosine according
- // to how it looks on the MT-32. What it really does it takes the
- // square wave and multiplies it by a full cosine
- int waveoff = (toff << 2) + minorplace;
- if (toff < noteLookup->sawTable[pulsewidth])
- filterInput = noteLookup->waveforms[1][waveoff % noteLookup->waveformSize[1]];
- else
- filterInput = noteLookup->waveforms[2][waveoff % noteLookup->waveformSize[2]];
- // This is the correct way
- // Seems slow to me (though bandlimited) -- doesn't seem to
- // sound any better though
- /*
- //int pw = (patchCache->pulsewidth * pulsemod[filtval]) >> 8;
-
- Bit32u ofs = toff % (noteLookup->div2 >> 1);
-
- Bit32u ofs3 = toff + FIXEDPOINT_UMULT(noteLookup->div2, synth->tables.pwFactor[patchCache->pulsewidth], 9);
- ofs3 = ofs3 % (noteLookup->div2 >> 1);
-
- pa = noteLookup->waveforms[0][ofs];
- pb = noteLookup->waveforms[0][ofs3];
- sample = ((pa - pb) * noteLookup->waveforms[2][toff]) / 2;
- */
- }
-
- //Very exact filter
- if (filtval > ((FILTERGRAN * 15) / 16))
- filtval = ((FILTERGRAN * 15) / 16);
- sample = (Bit32s)(floorf((synth->iirFilter)((float)filterInput, &history[0], synth->tables.filtCoeff[filtval][(int)patchCache->filtEnv.resonance])) / synth->tables.resonanceFactor[patchCache->filtEnv.resonance]);
- if (sample < -32768) {
- synth->printDebug("Overdriven amplitude for %d: %d:=%d < -32768", patchCache->waveform, filterInput, sample);
- sample = -32768;
- }
- else if (sample > 32767) {
- synth->printDebug("Overdriven amplitude for %d: %d:=%d > 32767", patchCache->waveform, filterInput, sample);
- sample = 32767;
- }
- }
- }
-
- // Add calculated delta to our waveform offset
- Bit32u absOff = ((partialOff.pcmplace << 16) | partialOff.pcmoffset);
- absOff += delta;
- partialOff.pcmplace = (Bit16u)((absOff & 0xFFFF0000) >> 16);
- partialOff.pcmoffset = (Bit16u)(absOff & 0xFFFF);
-
- // Put volume envelope over generated sample
- sample = FIXEDPOINT_SMULT(sample, ampEnvVal, 9);
- sample = FIXEDPOINT_SMULT(sample, volume, 7);
- envs[EnvelopeType_amp].envpos++;
- envs[EnvelopeType_pitch].envpos++;
- envs[EnvelopeType_filt].envpos++;
-
- *partialBuf++ = (Bit16s)sample;
- }
- // We may have deactivated and broken out of the loop before the end of the buffer,
- // if so then fill the remainder with 0s.
- if (++length > 0)
- memset(partialBuf, 0, length * 2);
- return &myBuffer[0];
-}
-
-void Partial::setBend(float factor) {
- if (!patchCache->useBender || factor == 0.0f) {
- bendShift = 4096;
- return;
- }
- // NOTE:KG: We can't do this smoothly with lookup tables, unless we use several MB.
- // FIXME:KG: Bend should be influenced by pitch key-follow too, according to docs.
- float bendSemitones = factor * patchCache->benderRange; // -24 .. 24
- float mult = powf(2.0f, bendSemitones / 12.0f);
- synth->printDebug("setBend(): factor=%f, benderRange=%f, semitones=%f, mult=%f\n", (double)factor, (double)patchCache->benderRange, (double)bendSemitones, (double)mult);
- bendShift = (int)(mult * 4096.0f);
-}
-
-Bit16s *Partial::mixBuffers(Bit16s * buf1, Bit16s *buf2, int len) {
- if (buf1 == NULL)
- return buf2;
- if (buf2 == NULL)
- return buf1;
-
- Bit16s *outBuf = buf1;
-#if MT32EMU_USE_MMX >= 1
- // KG: This seems to be fine
- int donelen = i386_mixBuffers(buf1, buf2, len);
- len -= donelen;
- buf1 += donelen;
- buf2 += donelen;
-#endif
- while (len--) {
- *buf1 = *buf1 + *buf2;
- buf1++, buf2++;
- }
- return outBuf;
-}
-
-Bit16s *Partial::mixBuffersRingMix(Bit16s * buf1, Bit16s *buf2, int len) {
- if (buf1 == NULL)
- return NULL;
- if (buf2 == NULL) {
- Bit16s *outBuf = buf1;
- while (len--) {
- if (*buf1 < -8192)
- *buf1 = -8192;
- else if (*buf1 > 8192)
- *buf1 = 8192;
- buf1++;
- }
- return outBuf;
- }
-
- Bit16s *outBuf = buf1;
-#if MT32EMU_USE_MMX >= 1
- // KG: This seems to be fine
- int donelen = i386_mixBuffersRingMix(buf1, buf2, len);
- len -= donelen;
- buf1 += donelen;
- buf2 += donelen;
-#endif
- while (len--) {
- float a, b;
- a = ((float)*buf1) / 8192.0f;
- b = ((float)*buf2) / 8192.0f;
- a = (a * b) + a;
- if (a > 1.0f)
- a = 1.0f;
- if (a < -1.0f)
- a = -1.0f;
- *buf1 = (Bit16s)(a * 8192.0f);
- buf1++;
- buf2++;
- //buf1[i] = (Bit16s)(((Bit32s)buf1[i] * (Bit32s)buf2[i]) >> 10) + buf1[i];
- }
- return outBuf;
-}
-
-Bit16s *Partial::mixBuffersRing(Bit16s * buf1, Bit16s *buf2, int len) {
- if (buf1 == NULL) {
- return NULL;
- }
- if (buf2 == NULL) {
- return NULL;
- }
-
- Bit16s *outBuf = buf1;
-#if MT32EMU_USE_MMX >= 1
- // FIXME:KG: Not really checked as working
- int donelen = i386_mixBuffersRing(buf1, buf2, len);
- len -= donelen;
- buf1 += donelen;
- buf2 += donelen;
-#endif
- while (len--) {
- float a, b;
- a = ((float)*buf1) / 8192.0f;
- b = ((float)*buf2) / 8192.0f;
- a *= b;
- if (a > 1.0f)
- a = 1.0f;
- if (a < -1.0f)
- a = -1.0f;
- *buf1 = (Bit16s)(a * 8192.0f);
- buf1++;
- buf2++;
- }
- return outBuf;
-}
-
-void Partial::mixBuffersStereo(Bit16s *buf1, Bit16s *buf2, Bit16s *outBuf, int len) {
- if (buf2 == NULL) {
- while (len--) {
- *outBuf++ = *buf1++;
- *outBuf++ = 0;
- }
- } else if (buf1 == NULL) {
- while (len--) {
- *outBuf++ = 0;
- *outBuf++ = *buf2++;
- }
- } else {
- while (len--) {
- *outBuf++ = *buf1++;
- *outBuf++ = *buf2++;
- }
- }
-}
-
-bool Partial::produceOutput(Bit16s *partialBuf, long length) {
- if (!isActive() || alreadyOutputed)
- return false;
- if (poly == NULL) {
- synth->printDebug("*** ERROR: poly is NULL at Partial::produceOutput()!");
- return false;
- }
-
- Bit16s *pairBuf = NULL;
- // Check for dependant partial
- if (pair != NULL) {
- if (!pair->alreadyOutputed) {
- // Note: pair may have become NULL after this
- pairBuf = pair->generateSamples(length);
- }
- } else if (useNoisePair) {
- // Generate noise for pairless ring mix
- pairBuf = synth->tables.noiseBuf;
- }
-
- Bit16s *myBuf = generateSamples(length);
-
- if (myBuf == NULL && pairBuf == NULL)
- return false;
-
- Bit16s *p1buf, *p2buf;
-
- if (structurePosition == 0 || pairBuf == NULL) {
- p1buf = myBuf;
- p2buf = pairBuf;
- } else {
- p2buf = myBuf;
- p1buf = pairBuf;
- }
-
- //synth->printDebug("mixType: %d", mixType);
-
- Bit16s *mixedBuf;
- switch (mixType) {
- case 0:
- // Standard sound mix
- mixedBuf = mixBuffers(p1buf, p2buf, length);
- break;
-
- case 1:
- // Ring modulation with sound mix
- mixedBuf = mixBuffersRingMix(p1buf, p2buf, length);
- break;
-
- case 2:
- // Ring modulation alone
- mixedBuf = mixBuffersRing(p1buf, p2buf, length);
- break;
-
- case 3:
- // Stereo mixing. One partial to one speaker channel, one to another.
- // FIXME:KG: Surely we should be multiplying by the left/right volumes here?
- mixBuffersStereo(p1buf, p2buf, partialBuf, length);
- return true;
-
- default:
- mixedBuf = mixBuffers(p1buf, p2buf, length);
- break;
- }
-
- if (mixedBuf == NULL)
- return false;
-
- Bit16s leftvol, rightvol;
- leftvol = patchCache->pansetptr->leftvol;
- rightvol = patchCache->pansetptr->rightvol;
-
-#if MT32EMU_USE_MMX >= 2
- // FIXME:KG: This appears to introduce crackle
- int donelen = i386_partialProductOutput(length, leftvol, rightvol, partialBuf, mixedBuf);
- length -= donelen;
- mixedBuf += donelen;
- partialBuf += donelen * 2;
-#endif
- while (length--) {
- *partialBuf++ = (Bit16s)(((Bit32s)*mixedBuf * (Bit32s)leftvol) >> 15);
- *partialBuf++ = (Bit16s)(((Bit32s)*mixedBuf * (Bit32s)rightvol) >> 15);
- mixedBuf++;
- }
- return true;
-}
-
-Bit32s Partial::getFiltEnvelope() {
- int reshigh;
-
- int cutoff, depth;
-
- EnvelopeStatus *tStat = &envs[EnvelopeType_filt];
-
- if (tStat->decaying) {
- reshigh = tStat->envbase;
- reshigh = (reshigh + ((tStat->envdist * tStat->envpos) / tStat->envsize));
- if (tStat->envpos >= tStat->envsize)
- reshigh = 0;
- } else {
- if (tStat->envstat==4) {
- reshigh = patchCache->filtsustain;
- if (!poly->sustain) {
- startDecay(EnvelopeType_filt, reshigh);
- }
- } else {
- if ((tStat->envstat==-1) || (tStat->envpos >= tStat->envsize)) {
- if (tStat->envstat==-1)
- tStat->envbase = 0;
- else
- tStat->envbase = patchCache->filtEnv.envlevel[tStat->envstat];
- tStat->envstat++;
- tStat->envpos = 0;
- if (tStat->envstat == 3) {
- tStat->envsize = synth->tables.envTime[(int)patchCache->filtEnv.envtime[tStat->envstat]];
- } else {
- Bit32u envTime = (int)patchCache->filtEnv.envtime[tStat->envstat];
- if (tStat->envstat > 1) {
- int envDiff = abs(patchCache->filtEnv.envlevel[tStat->envstat] - patchCache->filtEnv.envlevel[tStat->envstat - 1]);
- if (envTime > synth->tables.envDeltaMaxTime[envDiff]) {
- envTime = synth->tables.envDeltaMaxTime[envDiff];
- }
- }
-
- tStat->envsize = (synth->tables.envTime[envTime] * keyLookup->envTimeMult[(int)patchCache->filtEnv.envtkf]) >> 8;
- }
-
- tStat->envsize++;
- tStat->envdist = patchCache->filtEnv.envlevel[tStat->envstat] - tStat->envbase;
- }
-
- reshigh = tStat->envbase;
- reshigh = (reshigh + ((tStat->envdist * tStat->envpos) / tStat->envsize));
-
- }
- tStat->prevlevel = reshigh;
- }
-
- cutoff = patchCache->filtEnv.cutoff;
-
- //if (patchCache->waveform==1) reshigh = (reshigh * 3) >> 2;
-
- depth = patchCache->filtEnv.envdepth;
-
- //int sensedep = (depth * 127-patchCache->filtEnv.envsense) >> 7;
- depth = FIXEDPOINT_UMULT(depth, synth->tables.tvfVelfollowMult[poly->vel][(int)patchCache->filtEnv.envsense], 8);
-
- int bias = patchCache->tvfbias;
- int dist;
-
- if (bias != 0) {
- //FIXME:KG: Is this really based on pitch (as now), or key pressed?
- //synth->printDebug("Cutoff before %d", cutoff);
- if (patchCache->tvfdir == 0) {
- if (noteVal < bias) {
- dist = bias - noteVal;
- cutoff = FIXEDPOINT_UMULT(cutoff, synth->tables.tvfBiasMult[patchCache->tvfblevel][dist], 8);
- }
- } else {
- // > Bias
- if (noteVal > bias) {
- dist = noteVal - bias;
- cutoff = FIXEDPOINT_UMULT(cutoff, synth->tables.tvfBiasMult[patchCache->tvfblevel][dist], 8);
- }
-
- }
- //synth->printDebug("Cutoff after %d", cutoff);
- }
-
- depth = (depth * keyLookup->envDepthMult[patchCache->filtEnv.envdkf]) >> 8;
- reshigh = (reshigh * depth) >> 7;
-
- Bit32s tmp;
-
- cutoff *= filtVal;
- cutoff /= realVal; //FIXME:KG: With filter keyfollow 0, this makes no sense. What's correct?
-
- reshigh *= filtVal;
- reshigh /= realVal; //FIXME:KG: As above for cutoff
-
- if (patchCache->waveform == 1) {
- reshigh = (reshigh * 65) / 100;
- }
-
- if (cutoff > 100)
- cutoff = 100;
- else if (cutoff < 0)
- cutoff = 0;
- if (reshigh > 100)
- reshigh = 100;
- else if (reshigh < 0)
- reshigh = 0;
- tmp = noteLookup->nfiltTable[cutoff][reshigh];
- //tmp *= keyfollow;
- //tmp /= realfollow;
-
- //synth->printDebug("Cutoff %d, tmp %d, freq %d", cutoff, tmp, tmp * 256);
- return tmp;
-}
-
-bool Partial::shouldReverb() {
- if (!isActive())
- return false;
- return patchCache->reverb;
-}
-
-Bit32u Partial::getAmpEnvelope() {
- Bit32s tc;
-
- EnvelopeStatus *tStat = &envs[EnvelopeType_amp];
-
- if (!play)
- return 0;
-
- if (tStat->decaying) {
- tc = tStat->envbase;
- tc += (tStat->envdist * tStat->envpos) / tStat->envsize;
- if (tc < 0)
- tc = 0;
- if ((tStat->envpos >= tStat->envsize) || (tc == 0)) {
- play = false;
- // Don't have to worry about prevlevel storage or anything, this partial's about to die
- return 0;
- }
- } else {
- if ((tStat->envstat == -1) || (tStat->envpos >= tStat->envsize)) {
- if (tStat->envstat == -1)
- tStat->envbase = 0;
- else
- tStat->envbase = patchCache->ampEnv.envlevel[tStat->envstat];
- tStat->envstat++;
- tStat->envpos = 0;
- if (tStat->envstat == 4) {
- //synth->printDebug("Envstat %d, size %d", tStat->envstat, tStat->envsize);
- tc = patchCache->ampEnv.envlevel[3];
- if (!poly->sustain)
- startDecay(EnvelopeType_amp, tc);
- else
- tStat->sustaining = true;
- goto PastCalc;
- }
- Bit8u targetLevel = patchCache->ampEnv.envlevel[tStat->envstat];
- tStat->envdist = targetLevel - tStat->envbase;
- Bit32u envTime = patchCache->ampEnv.envtime[tStat->envstat];
- if (targetLevel == 0) {
- tStat->envsize = synth->tables.envDecayTime[envTime];
- } else {
- int envLevelDelta = abs(tStat->envdist);
- if (envTime > synth->tables.envDeltaMaxTime[envLevelDelta]) {
- envTime = synth->tables.envDeltaMaxTime[envLevelDelta];
- }
- tStat->envsize = synth->tables.envTime[envTime];
- }
-
- // Time keyfollow is used by all sections of the envelope (confirmed on CM-32L)
- tStat->envsize = FIXEDPOINT_UMULT(tStat->envsize, keyLookup->envTimeMult[(int)patchCache->ampEnv.envtkf], 8);
-
- switch (tStat->envstat) {
- case 0:
- //Spot for velocity time follow
- //Only used for first attack
- tStat->envsize = FIXEDPOINT_UMULT(tStat->envsize, synth->tables.envTimeVelfollowMult[(int)patchCache->ampEnv.envvkf][poly->vel], 8);
- //synth->printDebug("Envstat %d, size %d", tStat->envstat, tStat->envsize);
- break;
- case 1:
- case 2:
- case 3:
- //synth->printDebug("Envstat %d, size %d", tStat->envstat, tStat->envsize);
- break;
- default:
- synth->printDebug("Invalid TVA envelope number %d hit!", tStat->envstat);
- break;
- }
-
- tStat->envsize++;
-
- if (tStat->envdist != 0) {
- tStat->counter = abs(tStat->envsize / tStat->envdist);
- //synth->printDebug("Pos %d, envsize %d envdist %d", tStat->envstat, tStat->envsize, tStat->envdist);
- } else {
- tStat->counter = 0;
- //synth->printDebug("Pos %d, envsize %d envdist %d", tStat->envstat, tStat->envsize, tStat->envdist);
- }
- }
- tc = tStat->envbase;
- tc = (tc + ((tStat->envdist * tStat->envpos) / tStat->envsize));
- tStat->count = tStat->counter;
-PastCalc:
- tc = (tc * (Bit32s)patchCache->ampEnv.level) / 100;
- }
-
- // Prevlevel storage is bottle neck
- tStat->prevlevel = tc;
-
- //Bias level crap stuff now
-
- for (int i = 0; i < 2; i++) {
- if (patchCache->ampblevel[i]!=0) {
- int bias = patchCache->ampbias[i];
- if (patchCache->ampdir[i]==0) {
- // < Bias
- if (noteVal < bias) {
- int dist = bias - noteVal;
- tc = FIXEDPOINT_UMULT(tc, synth->tables.tvaBiasMult[patchCache->ampblevel[i]][dist], 8);
- }
- } else {
- // > Bias
- if (noteVal > bias) {
- int dist = noteVal - bias;
- tc = FIXEDPOINT_UMULT(tc, synth->tables.tvaBiasMult[patchCache->ampblevel[i]][dist], 8);
- }
- }
- }
- }
- if (tc < 0) {
- synth->printDebug("*** ERROR: tc < 0 (%d) at getAmpEnvelope()", tc);
- tc = 0;
- }
- return (Bit32u)tc;
-}
-
-Bit32s Partial::getPitchEnvelope() {
- EnvelopeStatus *tStat = &envs[EnvelopeType_pitch];
-
- Bit32s tc;
- pitchSustain = false;
- if (tStat->decaying) {
- if (tStat->envpos >= tStat->envsize)
- tc = patchCache->pitchEnv.level[4];
- else {
- tc = tStat->envbase;
- tc = (tc + ((tStat->envdist * tStat->envpos) / tStat->envsize));
- }
- } else {
- if (tStat->envstat==3) {
- tc = patchCache->pitchsustain;
- if (poly->sustain)
- pitchSustain = true;
- else
- startDecay(EnvelopeType_pitch, tc);
- } else {
- if ((tStat->envstat==-1) || (tStat->envpos >= tStat->envsize)) {
- tStat->envstat++;
-
- tStat->envbase = patchCache->pitchEnv.level[tStat->envstat];
-
- Bit32u envTime = patchCache->pitchEnv.time[tStat->envstat];
- int envDiff = abs(patchCache->pitchEnv.level[tStat->envstat] - patchCache->pitchEnv.level[tStat->envstat + 1]);
- if (envTime > synth->tables.envDeltaMaxTime[envDiff]) {
- envTime = synth->tables.envDeltaMaxTime[envDiff];
- }
-
- tStat->envsize = (synth->tables.envTime[envTime] * keyLookup->envTimeMult[(int)patchCache->pitchEnv.timekeyfollow]) >> 8;
-
- tStat->envpos = 0;
- tStat->envsize++;
- tStat->envdist = patchCache->pitchEnv.level[tStat->envstat + 1] - tStat->envbase;
- }
- tc = tStat->envbase;
- tc = (tc + ((tStat->envdist * tStat->envpos) / tStat->envsize));
- }
- tStat->prevlevel = tc;
- }
- return tc;
-}
-
-void Partial::startDecayAll() {
- startDecay(EnvelopeType_amp, envs[EnvelopeType_amp].prevlevel);
- startDecay(EnvelopeType_filt, envs[EnvelopeType_filt].prevlevel);
- startDecay(EnvelopeType_pitch, envs[EnvelopeType_pitch].prevlevel);
- pitchSustain = false;
-}
-
-void Partial::startDecay(EnvelopeType envnum, Bit32s startval) {
- EnvelopeStatus *tStat = &envs[envnum];
-
- tStat->sustaining = false;
- tStat->decaying = true;
- tStat->envpos = 0;
- tStat->envbase = startval;
-
- switch (envnum) {
- case EnvelopeType_amp:
- tStat->envsize = FIXEDPOINT_UMULT(synth->tables.envDecayTime[(int)patchCache->ampEnv.envtime[4]], keyLookup->envTimeMult[(int)patchCache->ampEnv.envtkf], 8);
- tStat->envdist = -startval;
- break;
- case EnvelopeType_filt:
- tStat->envsize = FIXEDPOINT_UMULT(synth->tables.envDecayTime[(int)patchCache->filtEnv.envtime[4]], keyLookup->envTimeMult[(int)patchCache->filtEnv.envtkf], 8);
- tStat->envdist = -startval;
- break;
- case EnvelopeType_pitch:
- tStat->envsize = FIXEDPOINT_UMULT(synth->tables.envDecayTime[(int)patchCache->pitchEnv.time[3]], keyLookup->envTimeMult[(int)patchCache->pitchEnv.timekeyfollow], 8);
- tStat->envdist = patchCache->pitchEnv.level[4] - startval;
- break;
- default:
- break;
- }
- tStat->envsize++;
-}
diff --git a/audio/softsynth/mt32/partial.h b/audio/softsynth/mt32/partial.h
deleted file mode 100644
index 93d8bcd985..0000000000
--- a/audio/softsynth/mt32/partial.h
+++ /dev/null
@@ -1,148 +0,0 @@
-/* Copyright (c) 2003-2005 Various contributors
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- */
-
-#ifndef MT32EMU_PARTIAL_H
-#define MT32EMU_PARTIAL_H
-
-namespace MT32Emu {
-
-class Synth;
-struct NoteLookup;
-
-enum EnvelopeType {
- EnvelopeType_amp = 0,
- EnvelopeType_filt = 1,
- EnvelopeType_pitch = 2
-};
-
-struct EnvelopeStatus {
- Bit32s envpos;
- Bit32s envstat;
- Bit32s envbase;
- Bit32s envdist;
- Bit32s envsize;
-
- bool sustaining;
- bool decaying;
- Bit32s prevlevel;
-
- Bit32s counter;
- Bit32s count;
-};
-
-// Class definition of MT-32 partials. 32 in all.
-class Partial {
-private:
- Synth *synth;
-
- int ownerPart; // -1 if unassigned
- int mixType;
- int structurePosition; // 0 or 1 of a structure pair
- bool useNoisePair;
-
- Bit16s myBuffer[MAX_SAMPLE_OUTPUT];
-
- // Keyfollowed note value
-#if MT32EMU_ACCURATENOTES == 1
- NoteLookup noteLookupStorage;
- float noteVal;
-#else
- int noteVal;
- int fineShift;
-#endif
- const NoteLookup *noteLookup; // LUTs for this noteVal
- const KeyLookup *keyLookup; // LUTs for the clamped (12..108) key
-
- // Keyfollowed filter values
- int realVal;
- int filtVal;
-
- // Only used for PCM partials
- int pcmNum;
- PCMWaveEntry *pcmWave;
-
- int pulsewidth;
-
- Bit32u lfoPos;
- soundaddr partialOff;
-
- Bit32u ampEnvVal;
- Bit32u pitchEnvVal;
-
- float history[32];
-
- bool pitchSustain;
-
- int loopPos;
-
- dpoly *poly;
-
- int bendShift;
-
- Bit16s *mixBuffers(Bit16s *buf1, Bit16s *buf2, int len);
- Bit16s *mixBuffersRingMix(Bit16s *buf1, Bit16s *buf2, int len);
- Bit16s *mixBuffersRing(Bit16s *buf1, Bit16s *buf2, int len);
- void mixBuffersStereo(Bit16s *buf1, Bit16s *buf2, Bit16s *outBuf, int len);
-
- Bit32s getFiltEnvelope();
- Bit32u getAmpEnvelope();
- Bit32s getPitchEnvelope();
-
- void initKeyFollow(int freqNum);
-
-public:
- const PatchCache *patchCache;
- EnvelopeStatus envs[3];
- bool play;
-
- PatchCache cachebackup;
-
- Partial *pair;
- bool alreadyOutputed;
- Bit32u age;
-
- Partial(Synth *synth);
- ~Partial();
-
- int getOwnerPart() const;
- int getKey() const;
- const dpoly *getDpoly() const;
- bool isActive();
- void activate(int part);
- void deactivate(void);
- void startPartial(dpoly *usePoly, const PatchCache *useCache, Partial *pairPartial);
- void startDecay(EnvelopeType envnum, Bit32s startval);
- void startDecayAll();
- void setBend(float factor);
- bool shouldReverb();
-
- // Returns true only if data written to buffer
- // This function (unlike the one below it) returns processed stereo samples
- // made from combining this single partial with its pair, if it has one.
- bool produceOutput(Bit16s * partialBuf, long length);
-
- // This function produces mono sample output using the partial's private internal buffer
- Bit16s *generateSamples(long length);
-};
-
-}
-
-#endif
diff --git a/audio/softsynth/mt32/partialManager.cpp b/audio/softsynth/mt32/partialManager.cpp
deleted file mode 100644
index 3d3b6302db..0000000000
--- a/audio/softsynth/mt32/partialManager.cpp
+++ /dev/null
@@ -1,272 +0,0 @@
-/* Copyright (c) 2003-2005 Various contributors
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- */
-
-#include <string.h>
-
-#include "mt32emu.h"
-
-using namespace MT32Emu;
-
-PartialManager::PartialManager(Synth *useSynth) {
- this->synth = useSynth;
- for (int i = 0; i < MT32EMU_MAX_PARTIALS; i++)
- partialTable[i] = new Partial(synth);
-}
-
-PartialManager::~PartialManager(void) {
- for (int i = 0; i < MT32EMU_MAX_PARTIALS; i++)
- delete partialTable[i];
-}
-
-void PartialManager::getPerPartPartialUsage(int usage[9]) {
- memset(usage, 0, 9 * sizeof (int));
- for (int i = 0; i < MT32EMU_MAX_PARTIALS; i++) {
- if (partialTable[i]->isActive())
- usage[partialTable[i]->getOwnerPart()]++;
- }
-}
-
-void PartialManager::clearAlreadyOutputed() {
- for (int i = 0; i < MT32EMU_MAX_PARTIALS; i++)
- partialTable[i]->alreadyOutputed = false;
-}
-
-void PartialManager::ageAll() {
- for (int i = 0; i < MT32EMU_MAX_PARTIALS; i++)
- partialTable[i]->age++;
-}
-
-bool PartialManager::shouldReverb(int i) {
- return partialTable[i]->shouldReverb();
-}
-
-bool PartialManager::produceOutput(int i, Bit16s *buffer, Bit32u bufferLength) {
- return partialTable[i]->produceOutput(buffer, bufferLength);
-}
-
-void PartialManager::deactivateAll() {
- for (int i = 0; i < MT32EMU_MAX_PARTIALS; i++) {
- partialTable[i]->deactivate();
- }
-}
-
-unsigned int PartialManager::setReserve(Bit8u *rset) {
- unsigned int pr = 0;
- for (int x = 0; x < 9; x++) {
- for (int y = 0; y < rset[x]; y++) {
- partialReserveTable[pr] = x;
- pr++;
- }
- }
- return pr;
-}
-
-Partial *PartialManager::allocPartial(int partNum) {
- Partial *outPartial = NULL;
-
- // Use the first inactive partial reserved for the specified part (if there are any)
- // Otherwise, use the last inactive partial, if any
- for (int i = 0; i < MT32EMU_MAX_PARTIALS; i++) {
- if (!partialTable[i]->isActive()) {
- outPartial = partialTable[i];
- if (partialReserveTable[i] == partNum)
- break;
- }
- }
- if (outPartial != NULL) {
- outPartial->activate(partNum);
- outPartial->age = 0;
- }
- return outPartial;
-}
-
-unsigned int PartialManager::getFreePartialCount(void) {
- int count = 0;
- memset(partialPart, 0, sizeof(partialPart));
- for (int i = 0; i < MT32EMU_MAX_PARTIALS; i++) {
- if (!partialTable[i]->isActive())
- count++;
- else
- partialPart[partialTable[i]->getOwnerPart()]++;
- }
- return count;
-}
-
-/*
-bool PartialManager::freePartials(unsigned int needed, int partNum) {
- int i;
- int myPartPrior = (int)mt32ram.system.reserveSettings[partNum];
- if (myPartPrior<partialPart[partNum]) {
- //This can have more parts, must kill off those with less priority
- int most, mostPart;
- while (needed > 0) {
- int selectPart = -1;
- //Find the worst offender with more partials than allocated and kill them
- most = -1;
- mostPart = -1;
- int diff;
-
- for (i=0;i<9;i++) {
- diff = partialPart[i] - (int)mt32ram.system.reserveSettings[i];
-
- if (diff>0) {
- if (diff>most) {
- most = diff;
- mostPart = i;
- }
- }
- }
- selectPart = mostPart;
- if (selectPart == -1) {
- // All parts are within the allocated limits, you suck
- // Look for first partial not of this part that's decaying perhaps?
- return false;
- }
- bool found;
- int oldest;
- int oldnum;
- while (partialPart[selectPart] > (int)mt32ram.system.reserveSettings[selectPart]) {
- oldest = -1;
- oldnum = -1;
- found = false;
- for (i = 0; i < MT32EMU_MAX_PARTIALS; i++) {
- if (partialTable[i]->isActive) {
- if (partialTable[i]->ownerPart == selectPart) {
- found = true;
- if (partialTable[i]->age > oldest) {
- oldest = partialTable[i]->age;
- oldnum = i;
- }
- }
- }
- }
- if (!found) break;
- partialTable[oldnum]->deactivate();
- --partialPart[selectPart];
- --needed;
- }
-
- }
- return true;
-
- } else {
- //This part has reached its max, must kill off its own
- bool found;
- int oldest;
- int oldnum;
- while (needed > 0) {
- oldest = -1;
- oldnum = -1;
- found = false;
- for (i = 0; i < MT32EMU_MAX_PARTIALS; i++) {
- if (partialTable[i]->isActive) {
- if (partialTable[i]->ownerPart == partNum) {
- found = true;
- if (partialTable[i]->age > oldest) {
- oldest = partialTable[i]->age;
- oldnum = i;
- }
- }
- }
- }
- if (!found) break;
- partialTable[oldnum]->deactivate();
- --needed;
- }
- // Couldn't free enough partials, sorry
- if (needed>0) return false;
- return true;
- }
-
-}
-*/
-bool PartialManager::freePartials(unsigned int needed, int partNum) {
- if (needed == 0) {
- return true;
- }
- // Reclaim partials reserved for this part
- // Kill those that are already decaying first
- /*
- for (int i = 0; i < MT32EMU_MAX_PARTIALS; i++) {
- if (partialReserveTable[i] == partNum) {
- if (partialTable[i]->ownerPart != partNum) {
- if (partialTable[i]->partCache->envs[AMPENV].decaying) {
- partialTable[i]->isActive = false;
- --needed;
- if (needed == 0)
- return true;
- }
- }
- }
- }*/
- // Then kill those with the lowest part priority -- oldest at the moment
- while (needed > 0) {
- Bit32u prior = 0;
- int priornum = -1;
-
- for (int i = 0; i < MT32EMU_MAX_PARTIALS; i++) {
- if (partialReserveTable[i] == partNum && partialTable[i]->isActive() && partialTable[i]->getOwnerPart() != partNum) {
- /*
- if (mt32ram.system.reserveSettings[partialTable[i]->ownerPart] < prior) {
- prior = mt32ram.system.reserveSettings[partialTable[i]->ownerPart];
- priornum = i;
- }*/
- if (partialTable[i]->age >= prior) {
- prior = partialTable[i]->age;
- priornum = i;
- }
- }
- }
- if (priornum != -1) {
- partialTable[priornum]->deactivate();
- --needed;
- } else {
- break;
- }
- }
-
- // Kill off the oldest partials within this part
- while (needed > 0) {
- Bit32u oldest = 0;
- int oldlist = -1;
- for (int i = 0; i < MT32EMU_MAX_PARTIALS; i++) {
- if (partialTable[i]->getOwnerPart() == partNum && partialTable[i]->isActive()) {
- if (partialTable[i]->age >= oldest) {
- oldest = partialTable[i]->age;
- oldlist = i;
- }
- }
- }
- if (oldlist != -1) {
- partialTable[oldlist]->deactivate();
- --needed;
- } else {
- break;
- }
- }
- return needed == 0;
-}
-
-const Partial *PartialManager::getPartial(unsigned int partialNum) const {
- if (partialNum > MT32EMU_MAX_PARTIALS - 1)
- return NULL;
- return partialTable[partialNum];
-}
diff --git a/audio/softsynth/mt32/structures.h b/audio/softsynth/mt32/structures.h
deleted file mode 100644
index ef58c1d20f..0000000000
--- a/audio/softsynth/mt32/structures.h
+++ /dev/null
@@ -1,284 +0,0 @@
-/* Copyright (c) 2003-2005 Various contributors
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- */
-
-#ifndef MT32EMU_STRUCTURES_H
-#define MT32EMU_STRUCTURES_H
-
-namespace MT32Emu {
-
-const unsigned int MAX_SAMPLE_OUTPUT = 4096;
-
-// MT32EMU_MEMADDR() converts from sysex-padded, MT32EMU_SYSEXMEMADDR converts to it
-// Roland provides documentation using the sysex-padded addresses, so we tend to use that in code and output
-#define MT32EMU_MEMADDR(x) ((((x) & 0x7f0000) >> 2) | (((x) & 0x7f00) >> 1) | ((x) & 0x7f))
-#define MT32EMU_SYSEXMEMADDR(x) ((((x) & 0x1FC000) << 2) | (((x) & 0x3F80) << 1) | ((x) & 0x7f))
-
-#ifdef _MSC_VER
-#define MT32EMU_ALIGN_PACKED __declspec(align(1))
-typedef unsigned __int64 Bit64u;
-typedef signed __int64 Bit64s;
-#else
-#define MT32EMU_ALIGN_PACKED __attribute__((packed))
-typedef unsigned long long Bit64u;
-typedef signed long long Bit64s;
-#endif
-
-typedef unsigned int Bit32u;
-typedef signed int Bit32s;
-typedef unsigned short int Bit16u;
-typedef signed short int Bit16s;
-typedef unsigned char Bit8u;
-typedef signed char Bit8s;
-
-// The following structures represent the MT-32's memory
-// Since sysex allows this memory to be written to in blocks of bytes,
-// we keep this packed so that we can copy data into the various
-// banks directly
-#if defined(_MSC_VER) || defined (__MINGW32__)
-#pragma pack(push, 1)
-#else
-#pragma pack(1)
-#endif
-
-struct TimbreParam {
- struct commonParam {
- char name[10];
- Bit8u pstruct12; // 1&2 0-12 (1-13)
- Bit8u pstruct34; // #3&4 0-12 (1-13)
- Bit8u pmute; // 0-15 (0000-1111)
- Bit8u nosustain; // 0-1(Normal, No sustain)
- } MT32EMU_ALIGN_PACKED common;
-
- struct partialParam {
- struct wgParam {
- Bit8u coarse; // 0-96 (C1,C#1-C9)
- Bit8u fine; // 0-100 (-50 to +50 (cents?))
- Bit8u keyfollow; // 0-16 (-1,-1/2,0,1,1/8,1/4,3/8,1/2,5/8,3/4,7/8,1,5/4,3/2,2.s1,s2)
- Bit8u bender; // 0,1 (ON/OFF)
- Bit8u waveform; // MT-32: 0-1 (SQU/SAW); LAPC-I: WG WAVEFORM/PCM BANK 0 - 3 (SQU/1, SAW/1, SQU/2, SAW/2)
- Bit8u pcmwave; // 0-127 (1-128)
- Bit8u pulsewid; // 0-100
- Bit8u pwvelo; // 0-14 (-7 - +7)
- } MT32EMU_ALIGN_PACKED wg;
-
- struct envParam {
- Bit8u depth; // 0-10
- Bit8u sensitivity; // 1-100
- Bit8u timekeyfollow; // 0-4
- Bit8u time[4]; // 1-100
- Bit8u level[5]; // 1-100 (-50 - +50)
- } MT32EMU_ALIGN_PACKED env;
-
- struct lfoParam {
- Bit8u rate; // 0-100
- Bit8u depth; // 0-100
- Bit8u modsense; // 0-100
- } MT32EMU_ALIGN_PACKED lfo;
-
- struct tvfParam {
- Bit8u cutoff; // 0-100
- Bit8u resonance; // 0-30
- Bit8u keyfollow; // 0-16 (-1,-1/2,1/4,0,1,1/8,1/4,3/8,1/2,5/8,3/2,7/8,1,5/4,3/2,2,s1,s2)
- Bit8u biaspoint; // 0-127 (<1A-<7C >1A-7C)
- Bit8u biaslevel; // 0-14 (-7 - +7)
- Bit8u envdepth; // 0-100
- Bit8u envsense; // 0-100
- Bit8u envdkf; // DEPTH KEY FOLL0W 0-4
- Bit8u envtkf; // TIME KEY FOLLOW 0-4
- Bit8u envtime[5]; // 1-100
- Bit8u envlevel[4]; // 1-100
- } MT32EMU_ALIGN_PACKED tvf;
-
- struct tvaParam {
- Bit8u level; // 0-100
- Bit8u velosens; // 0-100
- Bit8u biaspoint1; // 0-127 (<1A-<7C >1A-7C)
- Bit8u biaslevel1; // 0-12 (-12 - 0)
- Bit8u biaspoint2; // 0-127 (<1A-<7C >1A-7C)
- Bit8u biaslevel2; // 0-12 (-12 - 0)
- Bit8u envtkf; // TIME KEY FOLLOW 0-4
- Bit8u envvkf; // VELOS KEY FOLL0W 0-4
- Bit8u envtime[5]; // 1-100
- Bit8u envlevel[4]; // 1-100
- } MT32EMU_ALIGN_PACKED tva;
- } MT32EMU_ALIGN_PACKED partial[4];
-} MT32EMU_ALIGN_PACKED;
-
-struct PatchParam {
- Bit8u timbreGroup; // TIMBRE GROUP 0-3 (group A, group B, Memory, Rhythm)
- Bit8u timbreNum; // TIMBRE NUMBER 0-63
- Bit8u keyShift; // KEY SHIFT 0-48 (-24 - +24 semitones)
- Bit8u fineTune; // FINE TUNE 0-100 (-50 - +50 cents)
- Bit8u benderRange; // BENDER RANGE 0-24
- Bit8u assignMode; // ASSIGN MODE 0-3 (POLY1, POLY2, POLY3, POLY4)
- Bit8u reverbSwitch; // REVERB SWITCH 0-1 (OFF,ON)
- Bit8u dummy; // (DUMMY)
-} MT32EMU_ALIGN_PACKED;
-
-struct MemParams {
- // NOTE: The MT-32 documentation only specifies PatchTemp areas for parts 1-8.
- // The LAPC-I documentation specified an additional area for rhythm at the end,
- // where all parameters but fine tune, assign mode and output level are ignored
- struct PatchTemp {
- PatchParam patch;
- Bit8u outlevel; // OUTPUT LEVEL 0-100
- Bit8u panpot; // PANPOT 0-14 (R-L)
- Bit8u dummyv[6];
- } MT32EMU_ALIGN_PACKED;
-
- PatchTemp patchSettings[9];
-
- struct RhythmTemp {
- Bit8u timbre; // TIMBRE 0-94 (M1-M64,R1-30,OFF)
- Bit8u outlevel; // OUTPUT LEVEL 0-100
- Bit8u panpot; // PANPOT 0-14 (R-L)
- Bit8u reverbSwitch; // REVERB SWITCH 0-1 (OFF,ON)
- } MT32EMU_ALIGN_PACKED;
-
- RhythmTemp rhythmSettings[85];
-
- TimbreParam timbreSettings[8];
-
- PatchParam patches[128];
-
- // NOTE: There are only 30 timbres in the "rhythm" bank for MT-32; the additional 34 are for LAPC-I and above
- struct PaddedTimbre {
- TimbreParam timbre;
- Bit8u padding[10];
- } MT32EMU_ALIGN_PACKED;
-
- PaddedTimbre timbres[64 + 64 + 64 + 64]; // Group A, Group B, Memory, Rhythm
-
- struct SystemArea {
- Bit8u masterTune; // MASTER TUNE 0-127 432.1-457.6Hz
- Bit8u reverbMode; // REVERB MODE 0-3 (room, hall, plate, tap delay)
- Bit8u reverbTime; // REVERB TIME 0-7 (1-8)
- Bit8u reverbLevel; // REVERB LEVEL 0-7 (1-8)
- Bit8u reserveSettings[9]; // PARTIAL RESERVE (PART 1) 0-32
- Bit8u chanAssign[9]; // MIDI CHANNEL (PART1) 0-16 (1-16,OFF)
- Bit8u masterVol; // MASTER VOLUME 0-100
- } MT32EMU_ALIGN_PACKED;
-
- SystemArea system;
-};
-
-#if defined(_MSC_VER) || defined (__MINGW32__)
-#pragma pack(pop)
-#else
-#pragma pack()
-#endif
-
-struct PCMWaveEntry {
- Bit32u addr;
- Bit32u len;
- double tune;
- bool loop;
-};
-
-struct soundaddr {
- Bit16u pcmplace;
- Bit16u pcmoffset;
-};
-
-struct StereoVolume {
- Bit16s leftvol;
- Bit16s rightvol;
-};
-
-// This is basically a per-partial, pre-processed combination of timbre and patch/rhythm settings
-struct PatchCache {
- bool playPartial;
- bool PCMPartial;
- int pcm;
- char waveform;
- int pulsewidth;
- int pwsens;
-
- float pitch;
-
- int lfodepth;
- int lforate;
- Bit32u lfoperiod;
- int modsense;
-
- float pitchKeyfollow;
-
- int filtkeyfollow;
-
- int tvfbias;
- int tvfblevel;
- int tvfdir;
-
- int ampbias[2];
- int ampblevel[2];
- int ampdir[2];
-
- int ampdepth;
- int amplevel;
-
- bool useBender;
- float benderRange; // 0.0, 1.0, .., 24.0 (semitones)
-
- TimbreParam::partialParam::envParam pitchEnv;
- TimbreParam::partialParam::tvaParam ampEnv;
- TimbreParam::partialParam::tvfParam filtEnv;
-
- Bit32s pitchsustain;
- Bit32s filtsustain;
-
- Bit32u structureMix;
- int structurePosition;
- int structurePair;
-
- // The following fields are actually common to all partials in the timbre
- bool dirty;
- Bit32u partialCount;
- bool sustain;
- float pitchShift;
- bool reverb;
- const StereoVolume *pansetptr;
-};
-
-class Partial; // Forward reference for class defined in partial.h
-
-struct dpoly {
- bool isPlaying;
-
- unsigned int key;
- int freqnum;
- int vel;
-
- bool isDecay;
-
- const Bit32u *volumeptr;
-
- Partial *partials[4];
-
- bool pedalhold; // This marks keys that have been released on the keyboard, but are being held by the pedal
- bool sustain;
-
- bool isActive() const;
- Bit32u getAge() const;
-};
-
-}
-
-#endif
diff --git a/audio/softsynth/mt32/synth.cpp b/audio/softsynth/mt32/synth.cpp
deleted file mode 100644
index 322b864b6e..0000000000
--- a/audio/softsynth/mt32/synth.cpp
+++ /dev/null
@@ -1,1202 +0,0 @@
-/* Copyright (c) 2003-2005 Various contributors
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- */
-
-// FIXME: Avoid using printf
-#define FORBIDDEN_SYMBOL_EXCEPTION_printf
-
-// FIXME: Avoid using vprintf
-#define FORBIDDEN_SYMBOL_EXCEPTION_vprintf
-
-#include <math.h>
-#include <string.h>
-#include <stdlib.h>
-
-#include "mt32emu.h"
-
-#if defined(MACOSX) || defined(SOLARIS) || defined(__MINGW32__)
-// Older versions of Mac OS X didn't supply a powf function, so using it
-// will cause a binary incompatibility when trying to run a binary built
-// on a newer OS X release on an older one. And Solaris 8 doesn't provide
-// powf, floorf, fabsf etc. at all.
-// Cross-compiled MinGW32 toolchains suffer from a cross-compile bug in
-// libstdc++. math/stubs.o should be empty, but it comes with a symbol for
-// powf, resulting in a linker error because of multiple definitions.
-// Hence we re-define them here. The only potential drawback is that it
-// might be a little bit slower this way.
-#define powf(x,y) ((float)pow(x,y))
-#define floorf(x) ((float)floor(x))
-#define fabsf(x) ((float)fabs(x))
-#endif
-
-namespace MT32Emu {
-
-const int MAX_SYSEX_SIZE = 512;
-
-const ControlROMMap ControlROMMaps[5] = {
- // ID IDc IDbytes PCMmap PCMc tmbrA tmbrAO, tmbrB tmbrBO, tmbrR trC rhythm rhyC rsrv panpot prog
- {0x4014, 22, "\000 ver1.04 14 July 87 ", 0x3000, 128, 0x8000, 0x0000, 0xC000, 0x4000, 0x3200, 30, 0x73A6, 85, 0x57C7, 0x57D0, 0x57E2}, // MT-32 revision 0
- {0x4014, 22, "\000 ver1.06 31 Aug, 87 ", 0x3000, 128, 0x8000, 0x0000, 0xC000, 0x4000, 0x3200, 30, 0x7414, 85, 0x57D9, 0x57E2, 0x57F4}, // MT-32 revision 0
- {0x4010, 22, "\000 ver1.07 10 Oct, 87 ", 0x3000, 128, 0x8000, 0x0000, 0xC000, 0x4000, 0x3200, 30, 0x73fe, 85, 0x57B1, 0x57BA, 0x57CC}, // MT-32 revision 1
- {0x4010, 22, "\000verX.XX 30 Sep, 88 ", 0x3000, 128, 0x8000, 0x0000, 0xC000, 0x4000, 0x3200, 30, 0x741C, 85, 0x57E5, 0x57EE, 0x5800}, // MT-32 Blue Ridge mod
- {0x2205, 22, "\000CM32/LAPC1.02 891205", 0x8100, 256, 0x8000, 0x8000, 0x8080, 0x8000, 0x8500, 64, 0x8580, 85, 0x4F93, 0x4F9C, 0x4FAE} // CM-32L
- // (Note that all but CM-32L ROM actually have 86 entries for rhythmTemp)
-};
-
-float iir_filter_normal(float input, float *hist1_ptr, float *coef_ptr) {
- float *hist2_ptr;
- float output,new_hist;
-
- hist2_ptr = hist1_ptr + 1; // next history
-
- // 1st number of coefficients array is overall input scale factor, or filter gain
- output = input * (*coef_ptr++);
-
- output = output - *hist1_ptr * (*coef_ptr++);
- new_hist = output - *hist2_ptr * (*coef_ptr++); // poles
-
- output = new_hist + *hist1_ptr * (*coef_ptr++);
- output = output + *hist2_ptr * (*coef_ptr++); // zeros
-
- *hist2_ptr++ = *hist1_ptr;
- *hist1_ptr++ = new_hist;
- hist1_ptr++;
- hist2_ptr++;
-
- // i = 1
- output = output - *hist1_ptr * (*coef_ptr++);
- new_hist = output - *hist2_ptr * (*coef_ptr++); // poles
-
- output = new_hist + *hist1_ptr * (*coef_ptr++);
- output = output + *hist2_ptr * (*coef_ptr++); // zeros
-
- *hist2_ptr++ = *hist1_ptr;
- *hist1_ptr++ = new_hist;
-
- return(output);
-}
-
-Bit8u Synth::calcSysexChecksum(const Bit8u *data, Bit32u len, Bit8u checksum) {
- for (unsigned int i = 0; i < len; i++) {
- checksum = checksum + data[i];
- }
- checksum = checksum & 0x7f;
- if (checksum)
- checksum = 0x80 - checksum;
- return checksum;
-}
-
-Synth::Synth() {
- isOpen = false;
- reverbModel = NULL;
- partialManager = NULL;
- memset(parts, 0, sizeof(parts));
-}
-
-Synth::~Synth() {
- close(); // Make sure we're closed and everything is freed
-}
-
-int Synth::report(ReportType type, const void *data) {
- if (myProp.report != NULL) {
- return myProp.report(myProp.userData, type, data);
- }
- return 0;
-}
-
-void Synth::printDebug(const char *fmt, ...) {
- va_list ap;
- va_start(ap, fmt);
- if (myProp.printDebug != NULL) {
- myProp.printDebug(myProp.userData, fmt, ap);
- } else {
- vprintf(fmt, ap);
- printf("\n");
- }
- va_end(ap);
-}
-
-void Synth::initReverb(Bit8u newRevMode, Bit8u newRevTime, Bit8u newRevLevel) {
- // FIXME:KG: I don't think it's necessary to recreate the reverbModel... Just set the parameters
- delete reverbModel;
- reverbModel = new revmodel();
-
- switch (newRevMode) {
- case 0:
- reverbModel->setroomsize(.1f);
- reverbModel->setdamp(.75f);
- break;
- case 1:
- reverbModel->setroomsize(.5f);
- reverbModel->setdamp(.5f);
- break;
- case 2:
- reverbModel->setroomsize(.5f);
- reverbModel->setdamp(.1f);
- break;
- case 3:
- reverbModel->setroomsize(1.0f);
- reverbModel->setdamp(.75f);
- break;
- default:
- reverbModel->setroomsize(.1f);
- reverbModel->setdamp(.5f);
- break;
- }
- reverbModel->setdry(1);
- reverbModel->setwet((float)newRevLevel / 8.0f);
- reverbModel->setwidth((float)newRevTime / 8.0f);
-}
-
-File *Synth::openFile(const char *filename, File::OpenMode mode) {
- // It should never happen that openFile is NULL in our use case.
- // Just to cover the case where something is horrible wrong we
- // use an assert here.
- assert(myProp.openFile != NULL);
- return myProp.openFile(myProp.userData, filename, mode);
-}
-
-void Synth::closeFile(File *file) {
- if (myProp.closeFile != NULL) {
- myProp.closeFile(myProp.userData, file);
- } else {
- file->close();
- delete file;
- }
-}
-
-bool Synth::loadPreset(File *file) {
- bool inSys = false;
- Bit8u sysexBuf[MAX_SYSEX_SIZE];
- Bit16u syslen = 0;
- bool rc = true;
- for (;;) {
- Bit8u c;
- if (!file->readBit8u(&c)) {
- if (!file->isEOF()) {
- rc = false;
- }
- break;
- }
- sysexBuf[syslen] = c;
- if (inSys) {
- syslen++;
- if (c == 0xF7) {
- playSysex(&sysexBuf[0], syslen);
- inSys = false;
- syslen = 0;
- } else if (syslen == MAX_SYSEX_SIZE) {
- printDebug("MAX_SYSEX_SIZE (%d) exceeded while processing preset, ignoring message", MAX_SYSEX_SIZE);
- inSys = false;
- syslen = 0;
- }
- } else if (c == 0xF0) {
- syslen++;
- inSys = true;
- }
- }
- return rc;
-}
-
-bool Synth::loadControlROM(const char *filename) {
- File *file = openFile(filename, File::OpenMode_read); // ROM File
- if (file == NULL) {
- return false;
- }
- bool rc = (file->read(controlROMData, CONTROL_ROM_SIZE) == CONTROL_ROM_SIZE);
-
- closeFile(file);
- if (!rc)
- return rc;
-
- // Control ROM successfully loaded, now check whether it's a known type
- controlROMMap = NULL;
- for (unsigned int i = 0; i < sizeof (ControlROMMaps) / sizeof (ControlROMMaps[0]); i++) {
- if (memcmp(&controlROMData[ControlROMMaps[i].idPos], ControlROMMaps[i].idBytes, ControlROMMaps[i].idLen) == 0) {
- controlROMMap = &ControlROMMaps[i];
- return true;
- }
- }
- return false;
-}
-
-bool Synth::loadPCMROM(const char *filename) {
- File *file = openFile(filename, File::OpenMode_read); // ROM File
- if (file == NULL) {
- return false;
- }
- bool rc = true;
- int i;
- for (i = 0; i < pcmROMSize; i++) {
- Bit8u s;
- if (!file->readBit8u(&s)) {
- if (!file->isEOF()) {
- rc = false;
- }
- break;
- }
- Bit8u c;
- if (!file->readBit8u(&c)) {
- if (!file->isEOF()) {
- rc = false;
- } else {
- printDebug("PCM ROM file has an odd number of bytes! Ignoring last");
- }
- break;
- }
-
- short e;
- int bit;
- int u;
- int order[16] = {0, 9, 1 ,2, 3, 4, 5, 6, 7, 10, 11, 12, 13, 14, 15, 8};
-
- e = 0;
- for (u = 0; u < 15; u++) {
- if (order[u] < 8)
- bit = (s >> (7 - order[u])) & 0x1;
- else
- bit = (c >> (7 - (order[u] - 8))) & 0x1;
- e = e | (short)(bit << (15 - u));
- }
-
- /*
- //Bit16s e = ( ((s & 0x7f) << 4) | ((c & 0x40) << 6) | ((s & 0x80) << 6) | ((c & 0x3f))) << 2;
- if (e<0)
- e = -32767 - e;
- int ut = abs(e);
- int dif = 0x7fff - ut;
- x = exp(((float)((float)0x8000-(float)dif) / (float)0x1000));
- e = (int)((float)e * (x/3200));
- */
-
- // File is companded (dB?), convert to linear PCM
- // MINDB = -96
- // MAXDB = -15
- float testval;
- testval = (float)((~e) & 0x7fff);
- testval = -(testval / 400.00f);
- //testval = -(testval / 341.32291666666666666666666666667);
- float vol = powf(8, testval / 20) * 32767.0f;
-
- if (e > 0)
- vol = -vol;
-
- pcmROMData[i] = (Bit16s)vol;
- }
- if (i != pcmROMSize) {
- printDebug("PCM ROM file is too short (expected %d, got %d)", pcmROMSize, i);
- rc = false;
- }
- closeFile(file);
- return rc;
-}
-
-bool Synth::initPCMList(Bit16u mapAddress, Bit16u count) {
- ControlROMPCMStruct *tps = (ControlROMPCMStruct *)&controlROMData[mapAddress];
- for (int i = 0; i < count; i++) {
- int rAddr = tps[i].pos * 0x800;
- int rLenExp = (tps[i].len & 0x70) >> 4;
- int rLen = 0x800 << rLenExp;
- bool rLoop = (tps[i].len & 0x80) != 0;
- //Bit8u rFlag = tps[i].len & 0x0F;
- Bit16u rTuneOffset = (tps[i].pitchMSB << 8) | tps[i].pitchLSB;
- // The number below is confirmed to a reasonable degree of accuracy on CM-32L
- double STANDARDFREQ = 442.0;
- float rTune = (float)(STANDARDFREQ * pow(2.0, (0x5000 - rTuneOffset) / 4056.0 - 9.0 / 12.0));
- //printDebug("%f,%d,%d", (double)pTune, tps[i].pitchCoarse, tps[i].pitchFine);
- if (rAddr + rLen > pcmROMSize) {
- printDebug("Control ROM error: Wave map entry %d points to invalid PCM address 0x%04X, length 0x%04X", i, rAddr, rLen);
- return false;
- }
- pcmWaves[i].addr = rAddr;
- pcmWaves[i].len = rLen;
- pcmWaves[i].loop = rLoop;
- pcmWaves[i].tune = rTune;
- }
- return false;
-}
-
-bool Synth::initRhythmTimbre(int timbreNum, const Bit8u *mem, unsigned int memLen) {
- if (memLen < sizeof(TimbreParam::commonParam)) {
- return false;
- }
- TimbreParam *timbre = &mt32ram.timbres[timbreNum].timbre;
- memcpy(&timbre->common, mem, 14);
- unsigned int memPos = 14;
- char drumname[11];
- memset(drumname, 0, 11);
- memcpy(drumname, timbre->common.name, 10);
- for (int t = 0; t < 4; t++) {
- if (((timbre->common.pmute >> t) & 0x1) == 0x1) {
- if (memPos + 58 >= memLen) {
- return false;
- }
- memcpy(&timbre->partial[t], mem + memPos, 58);
- memPos += 58;
- }
- }
- return true;
-}
-
-bool Synth::initRhythmTimbres(Bit16u mapAddress, Bit16u count) {
- const Bit8u *drumMap = &controlROMData[mapAddress];
- int timbreNum = 192;
- for (Bit16u i = 0; i < count * 2; i += 2) {
- Bit16u address = (drumMap[i + 1] << 8) | drumMap[i];
- /*
- // This check is nonsensical when the control ROM is the full 64KB addressable by 16-bit absolute pointers (which it is)
- if (address >= CONTROL_ROM_SIZE) {
- printDebug("Control ROM error: Timbre map entry 0x%04x points to invalid timbre address 0x%04x", i, address);
- return false;
- }
- */
- if (!initRhythmTimbre(timbreNum++, &controlROMData[address], CONTROL_ROM_SIZE - address)) {
- printDebug("Control ROM error: Timbre map entry 0x%04x points to invalid timbre 0x%04x", i, address);
- return false;
- }
- }
- return true;
-}
-
-bool Synth::initTimbres(Bit16u mapAddress, Bit16u offset, int startTimbre) {
- for (Bit16u i = mapAddress; i < mapAddress + 0x80; i += 2) {
- Bit16u address = (controlROMData[i + 1] << 8) | controlROMData[i];
- if (address + sizeof(TimbreParam) > CONTROL_ROM_SIZE) {
- printDebug("Control ROM error: Timbre map entry 0x%04x points to invalid timbre address 0x%04x", i, address);
- return false;
- }
- address = address + offset;
- TimbreParam *timbre = &mt32ram.timbres[startTimbre++].timbre;
- memcpy(timbre, &controlROMData[address], sizeof(TimbreParam));
- }
- return true;
-}
-
-bool Synth::open(SynthProperties &useProp) {
- if (isOpen)
- return false;
-
- myProp = useProp;
- if (useProp.baseDir != NULL) {
- myProp.baseDir = new char[strlen(useProp.baseDir) + 1];
- strcpy(myProp.baseDir, useProp.baseDir);
- }
-
- // This is to help detect bugs
- memset(&mt32ram, '?', sizeof(mt32ram));
-
- printDebug("Loading Control ROM");
- if (!loadControlROM("CM32L_CONTROL.ROM")) {
- if (!loadControlROM("MT32_CONTROL.ROM")) {
- printDebug("Init Error - Missing or invalid MT32_CONTROL.ROM");
- report(ReportType_errorControlROM, NULL);
- return false;
- }
- }
-
- // 512KB PCM ROM for MT-32, etc.
- // 1MB PCM ROM for CM-32L, LAPC-I, CM-64, CM-500
- // Note that the size below is given in samples (16-bit), not bytes
- pcmROMSize = controlROMMap->pcmCount == 256 ? 512 * 1024 : 256 * 1024;
- pcmROMData = new Bit16s[pcmROMSize];
-
- printDebug("Loading PCM ROM");
- if (!loadPCMROM("CM32L_PCM.ROM")) {
- if (!loadPCMROM("MT32_PCM.ROM")) {
- printDebug("Init Error - Missing MT32_PCM.ROM");
- report(ReportType_errorPCMROM, NULL);
- return false;
- }
- }
-
- printDebug("Initializing Timbre Bank A");
- if (!initTimbres(controlROMMap->timbreAMap, controlROMMap->timbreAOffset, 0)) {
- return false;
- }
-
- printDebug("Initializing Timbre Bank B");
- if (!initTimbres(controlROMMap->timbreBMap, controlROMMap->timbreBOffset, 64)) {
- return false;
- }
-
- printDebug("Initializing Timbre Bank R");
- if (!initRhythmTimbres(controlROMMap->timbreRMap, controlROMMap->timbreRCount)) {
- return false;
- }
-
- printDebug("Initializing Timbre Bank M");
- // CM-64 seems to initialize all bytes in this bank to 0.
- memset(&mt32ram.timbres[128], 0, sizeof (mt32ram.timbres[128]) * 64);
-
- partialManager = new PartialManager(this);
-
- pcmWaves = new PCMWaveEntry[controlROMMap->pcmCount];
-
- printDebug("Initializing PCM List");
- initPCMList(controlROMMap->pcmTable, controlROMMap->pcmCount);
-
- printDebug("Initializing Rhythm Temp");
- memcpy(mt32ram.rhythmSettings, &controlROMData[controlROMMap->rhythmSettings], controlROMMap->rhythmSettingsCount * 4);
-
- printDebug("Initializing Patches");
- for (Bit8u i = 0; i < 128; i++) {
- PatchParam *patch = &mt32ram.patches[i];
- patch->timbreGroup = i / 64;
- patch->timbreNum = i % 64;
- patch->keyShift = 24;
- patch->fineTune = 50;
- patch->benderRange = 12;
- patch->assignMode = 0;
- patch->reverbSwitch = 1;
- patch->dummy = 0;
- }
-
- printDebug("Initializing System");
- // The MT-32 manual claims that "Standard pitch" is 442Hz.
- mt32ram.system.masterTune = 0x40; // Confirmed on CM-64 as 0x4A, but SCUMM games use 0x40 and we don't want to initialize twice
- mt32ram.system.reverbMode = 0; // Confirmed
- mt32ram.system.reverbTime = 5; // Confirmed
- mt32ram.system.reverbLevel = 3; // Confirmed
- memcpy(mt32ram.system.reserveSettings, &controlROMData[controlROMMap->reserveSettings], 9); // Confirmed
- for (Bit8u i = 0; i < 9; i++) {
- // This is the default: {1, 2, 3, 4, 5, 6, 7, 8, 9}
- // An alternative configuration can be selected by holding "Master Volume"
- // and pressing "PART button 1" on the real MT-32's frontpanel.
- // The channel assignment is then {0, 1, 2, 3, 4, 5, 6, 7, 9}
- mt32ram.system.chanAssign[i] = i + 1;
- }
- mt32ram.system.masterVol = 100; // Confirmed
- if (!refreshSystem())
- return false;
-
- for (int i = 0; i < 8; i++) {
- mt32ram.patchSettings[i].outlevel = 80;
- mt32ram.patchSettings[i].panpot = controlROMData[controlROMMap->panSettings + i];
- memset(mt32ram.patchSettings[i].dummyv, 0, sizeof(mt32ram.patchSettings[i].dummyv));
- parts[i] = new Part(this, i);
- parts[i]->setProgram(controlROMData[controlROMMap->programSettings + i]);
- }
- parts[8] = new RhythmPart(this, 8);
-
- // For resetting mt32 mid-execution
- mt32default = mt32ram;
-
- iirFilter = &iir_filter_normal;
-
-#ifdef MT32EMU_HAVE_X86
- bool availableSSE = DetectSIMD();
- bool available3DNow = Detect3DNow();
-
- if (availableSSE)
- report(ReportType_availableSSE, NULL);
- if (available3DNow)
- report(ReportType_available3DNow, NULL);
-
- if (available3DNow) {
- printDebug("Detected and using SIMD (AMD 3DNow) extensions");
- iirFilter = &iir_filter_3dnow;
- report(ReportType_using3DNow, NULL);
- } else if (availableSSE) {
- printDebug("Detected and using SIMD (Intel SSE) extensions");
- iirFilter = &iir_filter_sse;
- report(ReportType_usingSSE, NULL);
- }
-#endif
-
- isOpen = true;
- isEnabled = false;
-
- printDebug("*** Initialisation complete ***");
- return true;
-}
-
-void Synth::close(void) {
- if (!isOpen)
- return;
-
- tables.freeNotes();
- if (partialManager != NULL) {
- delete partialManager;
- partialManager = NULL;
- }
-
- if (reverbModel != NULL) {
- delete reverbModel;
- reverbModel = NULL;
- }
-
- for (int i = 0; i < 9; i++) {
- if (parts[i] != NULL) {
- delete parts[i];
- parts[i] = NULL;
- }
- }
- if (myProp.baseDir != NULL) {
- delete myProp.baseDir;
- myProp.baseDir = NULL;
- }
-
- delete[] pcmWaves;
- delete[] pcmROMData;
- isOpen = false;
-}
-
-void Synth::playMsg(Bit32u msg) {
- // FIXME: Implement active sensing
- unsigned char code = (unsigned char)((msg & 0x0000F0) >> 4);
- unsigned char chan = (unsigned char) (msg & 0x00000F);
- unsigned char note = (unsigned char)((msg & 0x00FF00) >> 8);
- unsigned char velocity = (unsigned char)((msg & 0xFF0000) >> 16);
- isEnabled = true;
-
- //printDebug("Playing chan %d, code 0x%01x note: 0x%02x", chan, code, note);
-
- signed char part = chantable[chan];
- if (part < 0 || part > 8) {
- printDebug("Play msg on unreg chan %d (%d): code=0x%01x, vel=%d", chan, part, code, velocity);
- return;
- }
- playMsgOnPart(part, code, note, velocity);
-}
-
-void Synth::playMsgOnPart(unsigned char part, unsigned char code, unsigned char note, unsigned char velocity) {
- Bit32u bend;
-
- //printDebug("Synth::playMsg(0x%02x)",msg);
- switch (code) {
- case 0x8:
- //printDebug("Note OFF - Part %d", part);
- // The MT-32 ignores velocity for note off
- parts[part]->stopNote(note);
- break;
- case 0x9:
- //printDebug("Note ON - Part %d, Note %d Vel %d", part, note, velocity);
- if (velocity == 0) {
- // MIDI defines note-on with velocity 0 as being the same as note-off with velocity 40
- parts[part]->stopNote(note);
- } else {
- parts[part]->playNote(note, velocity);
- }
- break;
- case 0xB: // Control change
- switch (note) {
- case 0x01: // Modulation
- //printDebug("Modulation: %d", velocity);
- parts[part]->setModulation(velocity);
- break;
- case 0x07: // Set volume
- //printDebug("Volume set: %d", velocity);
- parts[part]->setVolume(velocity);
- break;
- case 0x0A: // Pan
- //printDebug("Pan set: %d", velocity);
- parts[part]->setPan(velocity);
- break;
- case 0x0B:
- //printDebug("Expression set: %d", velocity);
- parts[part]->setExpression(velocity);
- break;
- case 0x40: // Hold (sustain) pedal
- //printDebug("Hold pedal set: %d", velocity);
- parts[part]->setHoldPedal(velocity>=64);
- break;
-
- case 0x79: // Reset all controllers
- //printDebug("Reset all controllers");
- //FIXME: Check for accuracy against real thing
- parts[part]->setVolume(100);
- parts[part]->setExpression(127);
- parts[part]->setPan(64);
- parts[part]->setBend(0x2000);
- parts[part]->setHoldPedal(false);
- break;
-
- case 0x7B: // All notes off
- //printDebug("All notes off");
- parts[part]->allNotesOff();
- break;
-
- default:
- printDebug("Unknown MIDI Control code: 0x%02x - vel 0x%02x", note, velocity);
- break;
- }
-
- break;
- case 0xC: // Program change
- //printDebug("Program change %01x", note);
- parts[part]->setProgram(note);
- break;
- case 0xE: // Pitch bender
- bend = (velocity << 7) | (note);
- //printDebug("Pitch bender %02x", bend);
- parts[part]->setBend(bend);
- break;
- default:
- printDebug("Unknown Midi code: 0x%01x - %02x - %02x", code, note, velocity);
- break;
- }
-
- //midiOutShortMsg(m_out, msg);
-}
-
-void Synth::playSysex(const Bit8u *sysex, Bit32u len) {
- if (len < 2) {
- printDebug("playSysex: Message is too short for sysex (%d bytes)", len);
- }
- if (sysex[0] != 0xF0) {
- printDebug("playSysex: Message lacks start-of-sysex (0xF0)");
- return;
- }
- // Due to some programs (e.g. Java) sending buffers with junk at the end, we have to go through and find the end marker rather than relying on len.
- Bit32u endPos;
- for (endPos = 1; endPos < len; endPos++)
- {
- if (sysex[endPos] == 0xF7)
- break;
- }
- if (endPos == len) {
- printDebug("playSysex: Message lacks end-of-sysex (0xf7)");
- return;
- }
- playSysexWithoutFraming(sysex + 1, endPos - 1);
-}
-
-void Synth::playSysexWithoutFraming(const Bit8u *sysex, Bit32u len) {
- if (len < 4) {
- printDebug("playSysexWithoutFraming: Message is too short (%d bytes)!", len);
- return;
- }
- if (sysex[0] != SYSEX_MANUFACTURER_ROLAND) {
- printDebug("playSysexWithoutFraming: Header not intended for this device manufacturer: %02x %02x %02x %02x", (int)sysex[0], (int)sysex[1], (int)sysex[2], (int)sysex[3]);
- return;
- }
- if (sysex[2] == SYSEX_MDL_D50) {
- printDebug("playSysexWithoutFraming: Header is intended for model D-50 (not yet supported): %02x %02x %02x %02x", (int)sysex[0], (int)sysex[1], (int)sysex[2], (int)sysex[3]);
- return;
- }
- else if (sysex[2] != SYSEX_MDL_MT32) {
- printDebug("playSysexWithoutFraming: Header not intended for model MT-32: %02x %02x %02x %02x", (int)sysex[0], (int)sysex[1], (int)sysex[2], (int)sysex[3]);
- return;
- }
- playSysexWithoutHeader(sysex[1], sysex[3], sysex + 4, len - 4);
-}
-
-void Synth::playSysexWithoutHeader(unsigned char device, unsigned char command, const Bit8u *sysex, Bit32u len) {
- if (device > 0x10) {
- // We have device ID 0x10 (default, but changeable, on real MT-32), < 0x10 is for channels
- printDebug("playSysexWithoutHeader: Message is not intended for this device ID (provided: %02x, expected: 0x10 or channel)", (int)device);
- return;
- }
- if (len < 4) {
- printDebug("playSysexWithoutHeader: Message is too short (%d bytes)!", len);
- return;
- }
- unsigned char checksum = calcSysexChecksum(sysex, len - 1, 0);
- if (checksum != sysex[len - 1]) {
- printDebug("playSysexWithoutHeader: Message checksum is incorrect (provided: %02x, expected: %02x)!", sysex[len - 1], checksum);
- return;
- }
- len -= 1; // Exclude checksum
- switch (command) {
- case SYSEX_CMD_DT1:
- writeSysex(device, sysex, len);
- break;
- case SYSEX_CMD_RQ1:
- readSysex(device, sysex, len);
- break;
- default:
- printDebug("playSysexWithoutFraming: Unsupported command %02x", command);
- return;
- }
-}
-
-void Synth::readSysex(unsigned char /*device*/, const Bit8u * /*sysex*/, Bit32u /*len*/) {
-}
-
-const MemoryRegion memoryRegions[8] = {
- {MR_PatchTemp, MT32EMU_MEMADDR(0x030000), sizeof(MemParams::PatchTemp), 9},
- {MR_RhythmTemp, MT32EMU_MEMADDR(0x030110), sizeof(MemParams::RhythmTemp), 85},
- {MR_TimbreTemp, MT32EMU_MEMADDR(0x040000), sizeof(TimbreParam), 8},
- {MR_Patches, MT32EMU_MEMADDR(0x050000), sizeof(PatchParam), 128},
- {MR_Timbres, MT32EMU_MEMADDR(0x080000), sizeof(MemParams::PaddedTimbre), 64 + 64 + 64 + 64},
- {MR_System, MT32EMU_MEMADDR(0x100000), sizeof(MemParams::SystemArea), 1},
- {MR_Display, MT32EMU_MEMADDR(0x200000), MAX_SYSEX_SIZE - 1, 1},
- {MR_Reset, MT32EMU_MEMADDR(0x7F0000), 0x3FFF, 1}
-};
-
-const int NUM_REGIONS = sizeof(memoryRegions) / sizeof(MemoryRegion);
-
-void Synth::writeSysex(unsigned char device, const Bit8u *sysex, Bit32u len) {
- Bit32u addr = (sysex[0] << 16) | (sysex[1] << 8) | (sysex[2]);
- addr = MT32EMU_MEMADDR(addr);
- sysex += 3;
- len -= 3;
- //printDebug("Sysex addr: 0x%06x", MT32EMU_SYSEXMEMADDR(addr));
- // NOTE: Please keep both lower and upper bounds in each check, for ease of reading
-
- // Process channel-specific sysex by converting it to device-global
- if (device < 0x10) {
- printDebug("WRITE-CHANNEL: Channel %d temp area 0x%06x", device, MT32EMU_SYSEXMEMADDR(addr));
- if (/*addr >= MT32EMU_MEMADDR(0x000000) && */addr < MT32EMU_MEMADDR(0x010000)) {
- int offset;
- if (chantable[device] == -1) {
- printDebug(" (Channel not mapped to a partial... 0 offset)");
- offset = 0;
- } else if (chantable[device] == 8) {
- printDebug(" (Channel mapped to rhythm... 0 offset)");
- offset = 0;
- } else {
- offset = chantable[device] * sizeof(MemParams::PatchTemp);
- printDebug(" (Setting extra offset to %d)", offset);
- }
- addr += MT32EMU_MEMADDR(0x030000) + offset;
- } else if (/*addr >= 0x010000 && */ addr < MT32EMU_MEMADDR(0x020000)) {
- addr += MT32EMU_MEMADDR(0x030110) - MT32EMU_MEMADDR(0x010000);
- } else if (/*addr >= 0x020000 && */ addr < MT32EMU_MEMADDR(0x030000)) {
- int offset;
- if (chantable[device] == -1) {
- printDebug(" (Channel not mapped to a partial... 0 offset)");
- offset = 0;
- } else if (chantable[device] == 8) {
- printDebug(" (Channel mapped to rhythm... 0 offset)");
- offset = 0;
- } else {
- offset = chantable[device] * sizeof(TimbreParam);
- printDebug(" (Setting extra offset to %d)", offset);
- }
- addr += MT32EMU_MEMADDR(0x040000) - MT32EMU_MEMADDR(0x020000) + offset;
- } else {
- printDebug("PlaySysexWithoutHeader: Invalid channel %d address 0x%06x", device, MT32EMU_SYSEXMEMADDR(addr));
- return;
- }
- }
-
- // Process device-global sysex (possibly converted from channel-specific sysex above)
- for (;;) {
- // Find the appropriate memory region
- int regionNum;
- const MemoryRegion *region = NULL; // Initialized to please compiler
- for (regionNum = 0; regionNum < NUM_REGIONS; regionNum++) {
- region = &memoryRegions[regionNum];
- if (region->contains(addr)) {
- writeMemoryRegion(region, addr, region->getClampedLen(addr, len), sysex);
- break;
- }
- }
- if (regionNum == NUM_REGIONS) {
- printDebug("Sysex write to unrecognised address %06x, len %d", MT32EMU_SYSEXMEMADDR(addr), len);
- break;
- }
- Bit32u next = region->next(addr, len);
- if (next == 0) {
- break;
- }
- addr += next;
- sysex += next;
- len -= next;
- }
-}
-
-void Synth::readMemory(Bit32u addr, Bit32u len, Bit8u *data) {
- int regionNum;
- const MemoryRegion *region = NULL;
- for (regionNum = 0; regionNum < NUM_REGIONS; regionNum++) {
- region = &memoryRegions[regionNum];
- if (region->contains(addr)) {
- readMemoryRegion(region, addr, len, data);
- break;
- }
- }
-}
-
-void Synth::readMemoryRegion(const MemoryRegion *region, Bit32u addr, Bit32u len, Bit8u *data) {
- unsigned int first = region->firstTouched(addr);
- //unsigned int last = region->lastTouched(addr, len);
- unsigned int off = region->firstTouchedOffset(addr);
- len = region->getClampedLen(addr, len);
-
- unsigned int m;
-
- switch (region->type) {
- case MR_PatchTemp:
- for (m = 0; m < len; m++)
- data[m] = ((Bit8u *)&mt32ram.patchSettings[first])[off + m];
- break;
- case MR_RhythmTemp:
- for (m = 0; m < len; m++)
- data[m] = ((Bit8u *)&mt32ram.rhythmSettings[first])[off + m];
- break;
- case MR_TimbreTemp:
- for (m = 0; m < len; m++)
- data[m] = ((Bit8u *)&mt32ram.timbreSettings[first])[off + m];
- break;
- case MR_Patches:
- for (m = 0; m < len; m++)
- data[m] = ((Bit8u *)&mt32ram.patches[first])[off + m];
- break;
- case MR_Timbres:
- for (m = 0; m < len; m++)
- data[m] = ((Bit8u *)&mt32ram.timbres[first])[off + m];
- break;
- case MR_System:
- for (m = 0; m < len; m++)
- data[m] = ((Bit8u *)&mt32ram.system)[m + off];
- break;
- default:
- for (m = 0; m < len; m += 2) {
- data[m] = 0xff;
- if (m + 1 < len) {
- data[m+1] = (Bit8u)region->type;
- }
- }
- // TODO: Don't care about the others ATM
- break;
- }
-
-}
-
-void Synth::writeMemoryRegion(const MemoryRegion *region, Bit32u addr, Bit32u len, const Bit8u *data) {
- unsigned int first = region->firstTouched(addr);
- unsigned int last = region->lastTouched(addr, len);
- unsigned int off = region->firstTouchedOffset(addr);
- switch (region->type) {
- case MR_PatchTemp:
- for (unsigned int m = 0; m < len; m++) {
- ((Bit8u *)&mt32ram.patchSettings[first])[off + m] = data[m];
- }
- //printDebug("Patch temp: Patch %d, offset %x, len %d", off/16, off % 16, len);
-
- for (unsigned int i = first; i <= last; i++) {
- int absTimbreNum = mt32ram.patchSettings[i].patch.timbreGroup * 64 + mt32ram.patchSettings[i].patch.timbreNum;
- char timbreName[11];
- memcpy(timbreName, mt32ram.timbres[absTimbreNum].timbre.common.name, 10);
- timbreName[10] = 0;
- printDebug("WRITE-PARTPATCH (%d-%d@%d..%d): %d; timbre=%d (%s), outlevel=%d", first, last, off, off + len, i, absTimbreNum, timbreName, mt32ram.patchSettings[i].outlevel);
- if (parts[i] != NULL) {
- if (i != 8) {
- // Note: Confirmed on CM-64 that we definitely *should* update the timbre here,
- // but only in the case that the sysex actually writes to those values
- if (i == first && off > 2) {
- printDebug(" (Not updating timbre, since those values weren't touched)");
- } else {
- parts[i]->setTimbre(&mt32ram.timbres[parts[i]->getAbsTimbreNum()].timbre);
- }
- }
- parts[i]->refresh();
- }
- }
- break;
- case MR_RhythmTemp:
- for (unsigned int m = 0; m < len; m++)
- ((Bit8u *)&mt32ram.rhythmSettings[first])[off + m] = data[m];
- for (unsigned int i = first; i <= last; i++) {
- int timbreNum = mt32ram.rhythmSettings[i].timbre;
- char timbreName[11];
- if (timbreNum < 94) {
- memcpy(timbreName, mt32ram.timbres[128 + timbreNum].timbre.common.name, 10);
- timbreName[10] = 0;
- } else {
- strcpy(timbreName, "[None]");
- }
- printDebug("WRITE-RHYTHM (%d-%d@%d..%d): %d; level=%02x, panpot=%02x, reverb=%02x, timbre=%d (%s)", first, last, off, off + len, i, mt32ram.rhythmSettings[i].outlevel, mt32ram.rhythmSettings[i].panpot, mt32ram.rhythmSettings[i].reverbSwitch, mt32ram.rhythmSettings[i].timbre, timbreName);
- }
- if (parts[8] != NULL) {
- parts[8]->refresh();
- }
- break;
- case MR_TimbreTemp:
- for (unsigned int m = 0; m < len; m++)
- ((Bit8u *)&mt32ram.timbreSettings[first])[off + m] = data[m];
- for (unsigned int i = first; i <= last; i++) {
- char instrumentName[11];
- memcpy(instrumentName, mt32ram.timbreSettings[i].common.name, 10);
- instrumentName[10] = 0;
- printDebug("WRITE-PARTTIMBRE (%d-%d@%d..%d): timbre=%d (%s)", first, last, off, off + len, i, instrumentName);
- if (parts[i] != NULL) {
- parts[i]->refresh();
- }
- }
- break;
- case MR_Patches:
- for (unsigned int m = 0; m < len; m++)
- ((Bit8u *)&mt32ram.patches[first])[off + m] = data[m];
- for (unsigned int i = first; i <= last; i++) {
- PatchParam *patch = &mt32ram.patches[i];
- int patchAbsTimbreNum = patch->timbreGroup * 64 + patch->timbreNum;
- char instrumentName[11];
- memcpy(instrumentName, mt32ram.timbres[patchAbsTimbreNum].timbre.common.name, 10);
- instrumentName[10] = 0;
- Bit8u *n = (Bit8u *)patch;
- printDebug("WRITE-PATCH (%d-%d@%d..%d): %d; timbre=%d (%s) %02X%02X%02X%02X%02X%02X%02X%02X", first, last, off, off + len, i, patchAbsTimbreNum, instrumentName, n[0], n[1], n[2], n[3], n[4], n[5], n[6], n[7]);
- // FIXME:KG: The below is definitely dodgy. We just guess that this is the patch that the part was using
- // based on a timbre match (but many patches could have the same timbre!)
- // If this refresh is really correct, we should store the patch number in use by each part.
- /*
- for (int part = 0; part < 8; part++) {
- if (parts[part] != NULL) {
- int partPatchAbsTimbreNum = mt32ram.patchSettings[part].patch.timbreGroup * 64 + mt32ram.patchSettings[part].patch.timbreNum;
- if (parts[part]->getAbsTimbreNum() == patchAbsTimbreNum) {
- parts[part]->setPatch(patch);
- parts[part]->RefreshPatch();
- }
- }
- }
- */
- }
- break;
- case MR_Timbres:
- // Timbres
- first += 128;
- last += 128;
- for (unsigned int m = 0; m < len; m++)
- ((Bit8u *)&mt32ram.timbres[first])[off + m] = data[m];
- for (unsigned int i = first; i <= last; i++) {
- char instrumentName[11];
- memcpy(instrumentName, mt32ram.timbres[i].timbre.common.name, 10);
- instrumentName[10] = 0;
- printDebug("WRITE-TIMBRE (%d-%d@%d..%d): %d; name=\"%s\"", first, last, off, off + len, i, instrumentName);
- // FIXME:KG: Not sure if the stuff below should be done (for rhythm and/or parts)...
- // Does the real MT-32 automatically do this?
- for (unsigned int part = 0; part < 9; part++) {
- if (parts[part] != NULL) {
- parts[part]->refreshTimbre(i);
- }
- }
- }
- break;
- case MR_System:
- for (unsigned int m = 0; m < len; m++)
- ((Bit8u *)&mt32ram.system)[m + off] = data[m];
-
- report(ReportType_devReconfig, NULL);
-
- printDebug("WRITE-SYSTEM:");
- refreshSystem();
- break;
- case MR_Display:
- char buf[MAX_SYSEX_SIZE];
- memcpy(&buf, &data[0], len);
- buf[len] = 0;
- printDebug("WRITE-LCD: %s", buf);
- report(ReportType_lcdMessage, buf);
- break;
- case MR_Reset:
- printDebug("RESET");
- report(ReportType_devReset, NULL);
- partialManager->deactivateAll();
- mt32ram = mt32default;
- for (int i = 0; i < 9; i++) {
- parts[i]->refresh();
- }
- isEnabled = false;
- break;
- }
-}
-
-bool Synth::refreshSystem() {
- memset(chantable, -1, sizeof(chantable));
-
- for (unsigned int i = 0; i < 9; i++) {
- //LOG(LOG_MISC|LOG_ERROR,"Part %d set to MIDI channel %d",i,mt32ram.system.chanAssign[i]);
- if (mt32ram.system.chanAssign[i] == 16 && parts[i] != NULL) {
- parts[i]->allSoundOff();
- } else {
- chantable[(int)mt32ram.system.chanAssign[i]] = (char)i;
- }
- }
- //FIXME:KG: This is just an educated guess.
- // The LAPC-I documentation claims a range of 427.5Hz-452.6Hz (similar to what we have here)
- // The MT-32 documentation claims a range of 432.1Hz-457.6Hz
- masterTune = 440.0f * powf(2.0f, (mt32ram.system.masterTune - 64.0f) / (128.0f * 12.0f));
- printDebug(" Master Tune: %f", (double)masterTune);
- printDebug(" Reverb: mode=%d, time=%d, level=%d", mt32ram.system.reverbMode, mt32ram.system.reverbTime, mt32ram.system.reverbLevel);
- report(ReportType_newReverbMode, &mt32ram.system.reverbMode);
- report(ReportType_newReverbTime, &mt32ram.system.reverbTime);
- report(ReportType_newReverbLevel, &mt32ram.system.reverbLevel);
-
- if (myProp.useDefaultReverb) {
- initReverb(mt32ram.system.reverbMode, mt32ram.system.reverbTime, mt32ram.system.reverbLevel);
- } else {
- initReverb(myProp.reverbType, myProp.reverbTime, mt32ram.system.reverbLevel);
- }
-
- Bit8u *rset = mt32ram.system.reserveSettings;
- printDebug(" Partial reserve: 1=%02d 2=%02d 3=%02d 4=%02d 5=%02d 6=%02d 7=%02d 8=%02d Rhythm=%02d", rset[0], rset[1], rset[2], rset[3], rset[4], rset[5], rset[6], rset[7], rset[8]);
- int pr = partialManager->setReserve(rset);
- if (pr != 32)
- printDebug(" (Partial Reserve Table with less than 32 partials reserved!)");
- rset = mt32ram.system.chanAssign;
- printDebug(" Part assign: 1=%02d 2=%02d 3=%02d 4=%02d 5=%02d 6=%02d 7=%02d 8=%02d Rhythm=%02d", rset[0], rset[1], rset[2], rset[3], rset[4], rset[5], rset[6], rset[7], rset[8]);
- printDebug(" Master volume: %d", mt32ram.system.masterVol);
- masterVolume = (Bit16u)(mt32ram.system.masterVol * 32767 / 100);
- if (!tables.init(this, pcmWaves, (float)myProp.sampleRate, masterTune)) {
- report(ReportType_errorSampleRate, NULL);
- return false;
- }
- return true;
-}
-
-bool Synth::dumpTimbre(File *file, const TimbreParam *timbre, Bit32u address) {
- // Sysex header
- if (!file->writeBit8u(0xF0))
- return false;
- if (!file->writeBit8u(0x41))
- return false;
- if (!file->writeBit8u(0x10))
- return false;
- if (!file->writeBit8u(0x16))
- return false;
- if (!file->writeBit8u(0x12))
- return false;
-
- char lsb = (char)(address & 0x7f);
- char isb = (char)((address >> 7) & 0x7f);
- char msb = (char)(((address >> 14) & 0x7f) | 0x08);
-
- //Address
- if (!file->writeBit8u(msb))
- return false;
- if (!file->writeBit8u(isb))
- return false;
- if (!file->writeBit8u(lsb))
- return false;
-
- //Data
- if (file->write(timbre, 246) != 246)
- return false;
-
- //Checksum
- unsigned char checksum = calcSysexChecksum((const Bit8u *)timbre, 246, msb + isb + lsb);
- if (!file->writeBit8u(checksum))
- return false;
-
- //End of sysex
- if (!file->writeBit8u(0xF7))
- return false;
- return true;
-}
-
-int Synth::dumpTimbres(const char *filename, int start, int len) {
- File *file = openFile(filename, File::OpenMode_write);
- if (file == NULL)
- return -1;
-
- for (int timbreNum = start; timbreNum < start + len; timbreNum++) {
- int useaddr = (timbreNum - start) * 256;
- TimbreParam *timbre = &mt32ram.timbres[timbreNum].timbre;
- if (!dumpTimbre(file, timbre, useaddr))
- break;
- }
- closeFile(file);
- return 0;
-}
-
-void ProduceOutput1(Bit16s *useBuf, Bit16s *stream, Bit32u len, Bit16s volume) {
-#if MT32EMU_USE_MMX > 2
- //FIXME:KG: This appears to introduce crackle
- int donelen = i386_produceOutput1(useBuf, stream, len, volume);
- len -= donelen;
- stream += donelen * 2;
- useBuf += donelen * 2;
-#endif
- int end = len * 2;
- while (end--) {
- *stream = *stream + (Bit16s)(((Bit32s)*useBuf++ * (Bit32s)volume)>>15);
- stream++;
- }
-}
-
-void Synth::render(Bit16s *stream, Bit32u len) {
- memset(stream, 0, len * sizeof (Bit16s) * 2);
- if (!isEnabled)
- return;
- while (len > 0) {
- Bit32u thisLen = len > MAX_SAMPLE_OUTPUT ? MAX_SAMPLE_OUTPUT : len;
- doRender(stream, thisLen);
- len -= thisLen;
- stream += 2 * thisLen;
- }
-}
-
-void Synth::doRender(Bit16s *stream, Bit32u len) {
- partialManager->ageAll();
-
- if (myProp.useReverb) {
- for (unsigned int i = 0; i < MT32EMU_MAX_PARTIALS; i++) {
- if (partialManager->shouldReverb(i)) {
- if (partialManager->produceOutput(i, &tmpBuffer[0], len)) {
- ProduceOutput1(&tmpBuffer[0], stream, len, masterVolume);
- }
- }
- }
- Bit32u m = 0;
- for (unsigned int i = 0; i < len; i++) {
- sndbufl[i] = (float)stream[m] / 32767.0f;
- m++;
- sndbufr[i] = (float)stream[m] / 32767.0f;
- m++;
- }
- reverbModel->processreplace(sndbufl, sndbufr, outbufl, outbufr, len, 1);
- m=0;
- for (unsigned int i = 0; i < len; i++) {
- stream[m] = (Bit16s)(outbufl[i] * 32767.0f);
- m++;
- stream[m] = (Bit16s)(outbufr[i] * 32767.0f);
- m++;
- }
- for (unsigned int i = 0; i < MT32EMU_MAX_PARTIALS; i++) {
- if (!partialManager->shouldReverb(i)) {
- if (partialManager->produceOutput(i, &tmpBuffer[0], len)) {
- ProduceOutput1(&tmpBuffer[0], stream, len, masterVolume);
- }
- }
- }
- } else {
- for (unsigned int i = 0; i < MT32EMU_MAX_PARTIALS; i++) {
- if (partialManager->produceOutput(i, &tmpBuffer[0], len))
- ProduceOutput1(&tmpBuffer[0], stream, len, masterVolume);
- }
- }
-
- partialManager->clearAlreadyOutputed();
-
-#if MT32EMU_MONITOR_PARTIALS == 1
- samplepos += len;
- if (samplepos > myProp.SampleRate * 5) {
- samplepos = 0;
- int partialUsage[9];
- partialManager->GetPerPartPartialUsage(partialUsage);
- printDebug("1:%02d 2:%02d 3:%02d 4:%02d 5:%02d 6:%02d 7:%02d 8:%02d", partialUsage[0], partialUsage[1], partialUsage[2], partialUsage[3], partialUsage[4], partialUsage[5], partialUsage[6], partialUsage[7]);
- printDebug("Rhythm: %02d TOTAL: %02d", partialUsage[8], MT32EMU_MAX_PARTIALS - partialManager->GetFreePartialCount());
- }
-#endif
-}
-
-const Partial *Synth::getPartial(unsigned int partialNum) const {
- return partialManager->getPartial(partialNum);
-}
-
-const Part *Synth::getPart(unsigned int partNum) const {
- if (partNum > 8)
- return NULL;
- return parts[partNum];
-}
-
-}
diff --git a/audio/softsynth/mt32/synth.h b/audio/softsynth/mt32/synth.h
deleted file mode 100644
index 0ef2c9d135..0000000000
--- a/audio/softsynth/mt32/synth.h
+++ /dev/null
@@ -1,299 +0,0 @@
-/* Copyright (c) 2003-2005 Various contributors
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- */
-
-#ifndef MT32EMU_SYNTH_H
-#define MT32EMU_SYNTH_H
-
-#include "common/scummsys.h"
-
-class revmodel;
-
-namespace MT32Emu {
-
-class File;
-class Partial;
-class PartialManager;
-class Part;
-
-enum ReportType {
- // Errors
- ReportType_errorControlROM = 1,
- ReportType_errorPCMROM,
- ReportType_errorSampleRate,
-
- // Progress
- ReportType_progressInit,
-
- // HW spec
- ReportType_availableSSE,
- ReportType_available3DNow,
- ReportType_usingSSE,
- ReportType_using3DNow,
-
- // General info
- ReportType_lcdMessage,
- ReportType_devReset,
- ReportType_devReconfig,
- ReportType_newReverbMode,
- ReportType_newReverbTime,
- ReportType_newReverbLevel
-};
-
-struct SynthProperties {
- // Sample rate to use in mixing
- int sampleRate;
-
- // Flag to activate reverb. True = use reverb, False = no reverb
- bool useReverb;
- // True to use software set reverb settings, False to set reverb settings in
- // following parameters
- bool useDefaultReverb;
- // When not using the default settings, this specifies one of the 4 reverb types
- // 1 = Room 2 = Hall 3 = Plate 4 = Tap
- unsigned char reverbType;
- // This specifies the delay time, from 0-7 (not sure of the actual MT-32's measurement)
- unsigned char reverbTime;
- // This specifies the reverb level, from 0-7 (not sure of the actual MT-32's measurement)
- unsigned char reverbLevel;
- // The name of the directory in which the ROM and data files are stored (with trailing slash/backslash)
- // Not used if "openFile" is set. May be NULL in any case.
- char *baseDir;
- // This is used as the first argument to all callbacks
- void *userData;
- // Callback for reporting various errors and information. May be NULL
- int (*report)(void *userData, ReportType type, const void *reportData);
- // Callback for debug messages, in vprintf() format
- void (*printDebug)(void *userData, const char *fmt, va_list list);
- // Callback for providing an implementation of File, opened and ready for use
- // May be NULL, in which case a default implementation will be used.
- File *(*openFile)(void *userData, const char *filename, File::OpenMode mode);
- // Callback for closing a File. May be NULL, in which case the File will automatically be close()d/deleted.
- void (*closeFile)(void *userData, File *file);
-};
-
-// This is the specification of the Callback routine used when calling the RecalcWaveforms
-// function
-typedef void (*recalcStatusCallback)(int percDone);
-
-// This external function recreates the base waveform file (waveforms.raw) using a specifed
-// sampling rate. The callback routine provides interactivity to let the user know what
-// percentage is complete in regenerating the waveforms. When a NULL pointer is used as the
-// callback routine, no status is reported.
-bool RecalcWaveforms(char * baseDir, int sampRate, recalcStatusCallback callBack);
-
-typedef float (*iir_filter_type)(float input,float *hist1_ptr, float *coef_ptr);
-
-const Bit8u SYSEX_MANUFACTURER_ROLAND = 0x41;
-
-const Bit8u SYSEX_MDL_MT32 = 0x16;
-const Bit8u SYSEX_MDL_D50 = 0x14;
-
-const Bit8u SYSEX_CMD_RQ1 = 0x11; // Request data #1
-const Bit8u SYSEX_CMD_DT1 = 0x12; // Data set 1
-const Bit8u SYSEX_CMD_WSD = 0x40; // Want to send data
-const Bit8u SYSEX_CMD_RQD = 0x41; // Request data
-const Bit8u SYSEX_CMD_DAT = 0x42; // Data set
-const Bit8u SYSEX_CMD_ACK = 0x43; // Acknowledge
-const Bit8u SYSEX_CMD_EOD = 0x45; // End of data
-const Bit8u SYSEX_CMD_ERR = 0x4E; // Communications error
-const Bit8u SYSEX_CMD_RJC = 0x4F; // Rejection
-
-const unsigned int CONTROL_ROM_SIZE = 64 * 1024;
-
-struct ControlROMPCMStruct
-{
- Bit8u pos;
- Bit8u len;
- Bit8u pitchLSB;
- Bit8u pitchMSB;
-};
-
-struct ControlROMMap {
- Bit16u idPos;
- Bit16u idLen;
- const char *idBytes;
- Bit16u pcmTable;
- Bit16u pcmCount;
- Bit16u timbreAMap;
- Bit16u timbreAOffset;
- Bit16u timbreBMap;
- Bit16u timbreBOffset;
- Bit16u timbreRMap;
- Bit16u timbreRCount;
- Bit16u rhythmSettings;
- Bit16u rhythmSettingsCount;
- Bit16u reserveSettings;
- Bit16u panSettings;
- Bit16u programSettings;
-};
-
-enum MemoryRegionType {
- MR_PatchTemp, MR_RhythmTemp, MR_TimbreTemp, MR_Patches, MR_Timbres, MR_System, MR_Display, MR_Reset
-};
-
-class MemoryRegion {
-public:
- MemoryRegionType type;
- Bit32u startAddr, entrySize, entries;
-
- int lastTouched(Bit32u addr, Bit32u len) const {
- return (offset(addr) + len - 1) / entrySize;
- }
- int firstTouchedOffset(Bit32u addr) const {
- return offset(addr) % entrySize;
- }
- int firstTouched(Bit32u addr) const {
- return offset(addr) / entrySize;
- }
- Bit32u regionEnd() const {
- return startAddr + entrySize * entries;
- }
- bool contains(Bit32u addr) const {
- return addr >= startAddr && addr < regionEnd();
- }
- int offset(Bit32u addr) const {
- return addr - startAddr;
- }
- Bit32u getClampedLen(Bit32u addr, Bit32u len) const {
- if (addr + len > regionEnd())
- return regionEnd() - addr;
- return len;
- }
- Bit32u next(Bit32u addr, Bit32u len) const {
- if (addr + len > regionEnd()) {
- return regionEnd() - addr;
- }
- return 0;
- }
-};
-
-
-class Synth {
-friend class Part;
-friend class RhythmPart;
-friend class Partial;
-friend class Tables;
-private:
- bool isEnabled;
-
- iir_filter_type iirFilter;
-
- PCMWaveEntry *pcmWaves; // Array
-
- const ControlROMMap *controlROMMap;
- Bit8u controlROMData[CONTROL_ROM_SIZE];
- Bit16s *pcmROMData;
- int pcmROMSize; // This is in 16-bit samples, therefore half the number of bytes in the ROM
-
- Bit8s chantable[32];
-
- #if MT32EMU_MONITOR_PARTIALS == 1
- static Bit32s samplepos = 0;
- #endif
-
- Tables tables;
-
- MemParams mt32ram, mt32default;
-
- revmodel *reverbModel;
-
- float masterTune;
- Bit16u masterVolume;
-
- bool isOpen;
-
- PartialManager *partialManager;
- Part *parts[9];
-
- Bit16s tmpBuffer[MAX_SAMPLE_OUTPUT * 2];
- float sndbufl[MAX_SAMPLE_OUTPUT];
- float sndbufr[MAX_SAMPLE_OUTPUT];
- float outbufl[MAX_SAMPLE_OUTPUT];
- float outbufr[MAX_SAMPLE_OUTPUT];
-
- SynthProperties myProp;
-
- bool loadPreset(File *file);
- void initReverb(Bit8u newRevMode, Bit8u newRevTime, Bit8u newRevLevel);
- void doRender(Bit16s * stream, Bit32u len);
-
- void playAddressedSysex(unsigned char channel, const Bit8u *sysex, Bit32u len);
- void readSysex(unsigned char channel, const Bit8u *sysex, Bit32u len);
- void writeMemoryRegion(const MemoryRegion *region, Bit32u addr, Bit32u len, const Bit8u *data);
- void readMemoryRegion(const MemoryRegion *region, Bit32u addr, Bit32u len, Bit8u *data);
-
- bool loadControlROM(const char *filename);
- bool loadPCMROM(const char *filename);
- bool dumpTimbre(File *file, const TimbreParam *timbre, Bit32u addr);
- int dumpTimbres(const char *filename, int start, int len);
-
- bool initPCMList(Bit16u mapAddress, Bit16u count);
- bool initRhythmTimbres(Bit16u mapAddress, Bit16u count);
- bool initTimbres(Bit16u mapAddress, Bit16u offset, int startTimbre);
- bool initRhythmTimbre(int drumNum, const Bit8u *mem, unsigned int memLen);
- bool refreshSystem();
-
-protected:
- int report(ReportType type, const void *reportData);
- File *openFile(const char *filename, File::OpenMode mode);
- void closeFile(File *file);
- void printDebug(const char *fmt, ...) GCC_PRINTF(2, 3);
-
-public:
- static Bit8u calcSysexChecksum(const Bit8u *data, Bit32u len, Bit8u checksum);
-
- Synth();
- ~Synth();
-
- // Used to initialize the MT-32. Must be called before any other function.
- // Returns true if initialization was sucessful, otherwise returns false.
- bool open(SynthProperties &useProp);
-
- // Closes the MT-32 and deallocates any memory used by the synthesizer
- void close(void);
-
- // Sends a 4-byte MIDI message to the MT-32 for immediate playback
- void playMsg(Bit32u msg);
- void playMsgOnPart(unsigned char part, unsigned char code, unsigned char note, unsigned char velocity);
-
- // Sends a string of Sysex commands to the MT-32 for immediate interpretation
- // The length is in bytes
- void playSysex(const Bit8u *sysex, Bit32u len);
- void playSysexWithoutFraming(const Bit8u *sysex, Bit32u len);
- void playSysexWithoutHeader(unsigned char device, unsigned char command, const Bit8u *sysex, Bit32u len);
- void writeSysex(unsigned char channel, const Bit8u *sysex, Bit32u len);
-
- // This callback routine is used to have the MT-32 generate samples to the specified
- // output stream. The length is in whole samples, not bytes. (I.E. in 16-bit stereo,
- // one sample is 4 bytes)
- void render(Bit16s * stream, Bit32u len);
-
- const Partial *getPartial(unsigned int partialNum) const;
-
- void readMemory(Bit32u addr, Bit32u len, Bit8u *data);
-
- // partNum should be 0..7 for Part 1..8, or 8 for Rhythm
- const Part *getPart(unsigned int partNum) const;
-};
-
-}
-
-#endif
diff --git a/audio/softsynth/mt32/tables.cpp b/audio/softsynth/mt32/tables.cpp
deleted file mode 100644
index 9fdb595467..0000000000
--- a/audio/softsynth/mt32/tables.cpp
+++ /dev/null
@@ -1,761 +0,0 @@
-/* Copyright (c) 2003-2005 Various contributors
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- */
-
-
-// FIXME: Avoid using rand
-#define FORBIDDEN_SYMBOL_EXCEPTION_rand
-
-#include <stdlib.h>
-#include <string.h>
-#include <math.h>
-
-#include "mt32emu.h"
-
-#if defined(MACOSX) || defined(SOLARIS) || defined(__MINGW32__)
-// Older versions of Mac OS X didn't supply a powf function, so using it
-// will cause a binary incompatibility when trying to run a binary built
-// on a newer OS X release on an older one. And Solaris 8 doesn't provide
-// powf, floorf, fabsf etc. at all.
-// Cross-compiled MinGW32 toolchains suffer from a cross-compile bug in
-// libstdc++. math/stubs.o should be empty, but it comes with a symbol for
-// powf, resulting in a linker error because of multiple definitions.
-// Hence we re-define them here. The only potential drawback is that it
-// might be a little bit slower this way.
-#define powf(x,y) ((float)pow(x,y))
-#define floorf(x) ((float)floor(x))
-#define fabsf(x) ((float)fabs(x))
-#endif
-
-#define FIXEDPOINT_MAKE(x, point) ((Bit32u)((1 << point) * x))
-
-namespace MT32Emu {
-
-//Amplitude time velocity follow exponential coefficients
-static const double tvcatconst[5] = {0.0, 0.002791309, 0.005942882, 0.012652792, 0.026938637};
-static const double tvcatmult[5] = {1.0, 1.072662811, 1.169129367, 1.288579123, 1.229630539};
-
-// These are division constants for the TVF depth key follow
-static const Bit32u depexp[5] = {3000, 950, 485, 255, 138};
-
-//Envelope time keyfollow exponential coefficients
-static const double tkcatconst[5] = {0.0, 0.005853144, 0.011148054, 0.019086143, 0.043333215};
-static const double tkcatmult[5] = {1.0, 1.058245688, 1.048488989, 1.016049301, 1.097538067};
-
-// Begin filter stuff
-
-// Pre-warp the coefficients of a numerator or denominator.
-// Note that a0 is assumed to be 1, so there is no wrapping
-// of it.
-static void prewarp(double *a1, double *a2, double fc, double fs) {
- double wp;
-
- wp = 2.0 * fs * tan(DOUBLE_PI * fc / fs);
-
- *a2 = *a2 / (wp * wp);
- *a1 = *a1 / wp;
-}
-
-// Transform the numerator and denominator coefficients
-// of s-domain biquad section into corresponding
-// z-domain coefficients.
-//
-// Store the 4 IIR coefficients in array pointed by coef
-// in following order:
-// beta1, beta2 (denominator)
-// alpha1, alpha2 (numerator)
-//
-// Arguments:
-// a0-a2 - s-domain numerator coefficients
-// b0-b2 - s-domain denominator coefficients
-// k - filter gain factor. initially set to 1
-// and modified by each biquad section in such
-// a way, as to make it the coefficient by
-// which to multiply the overall filter gain
-// in order to achieve a desired overall filter gain,
-// specified in initial value of k.
-// fs - sampling rate (Hz)
-// coef - array of z-domain coefficients to be filled in.
-//
-// Return:
-// On return, set coef z-domain coefficients
-static void bilinear(double a0, double a1, double a2, double b0, double b1, double b2, double *k, double fs, float *coef) {
- double ad, bd;
-
- // alpha (Numerator in s-domain)
- ad = 4. * a2 * fs * fs + 2. * a1 * fs + a0;
- // beta (Denominator in s-domain)
- bd = 4. * b2 * fs * fs + 2. * b1* fs + b0;
-
- // update gain constant for this section
- *k *= ad/bd;
-
- // Denominator
- *coef++ = (float)((2. * b0 - 8. * b2 * fs * fs) / bd); // beta1
- *coef++ = (float)((4. * b2 * fs * fs - 2. * b1 * fs + b0) / bd); // beta2
-
- // Nominator
- *coef++ = (float)((2. * a0 - 8. * a2 * fs * fs) / ad); // alpha1
- *coef = (float)((4. * a2 * fs * fs - 2. * a1 * fs + a0) / ad); // alpha2
-}
-
-// a0-a2: numerator coefficients
-// b0-b2: denominator coefficients
-// fc: Filter cutoff frequency
-// fs: sampling rate
-// k: overall gain factor
-// coef: pointer to 4 iir coefficients
-static void szxform(double *a0, double *a1, double *a2, double *b0, double *b1, double *b2, double fc, double fs, double *k, float *coef) {
- // Calculate a1 and a2 and overwrite the original values
- prewarp(a1, a2, fc, fs);
- prewarp(b1, b2, fc, fs);
- bilinear(*a0, *a1, *a2, *b0, *b1, *b2, k, fs, coef);
-}
-
-static void initFilter(float fs, float fc, float *icoeff, float Q) {
- float *coef;
- double a0, a1, a2, b0, b1, b2;
-
- double k = 1.5; // Set overall filter gain factor
- coef = icoeff + 1; // Skip k, or gain
-
- // Section 1
- a0 = 1.0;
- a1 = 0;
- a2 = 0;
- b0 = 1.0;
- b1 = 0.765367 / Q; // Divide by resonance or Q
- b2 = 1.0;
- szxform(&a0, &a1, &a2, &b0, &b1, &b2, fc, fs, &k, coef);
- coef += 4; // Point to next filter section
-
- // Section 2
- a0 = 1.0;
- a1 = 0;
- a2 = 0;
- b0 = 1.0;
- b1 = 1.847759 / Q;
- b2 = 1.0;
- szxform(&a0, &a1, &a2, &b0, &b1, &b2, fc, fs, &k, coef);
-
- icoeff[0] = (float)k;
-}
-
-void Tables::initFiltCoeff(float samplerate) {
- for (int j = 0; j < FILTERGRAN; j++) {
- for (int res = 0; res < 31; res++) {
- float tres = resonanceFactor[res];
- initFilter((float)samplerate, (((float)(j+1.0)/FILTERGRAN)) * ((float)samplerate/2), filtCoeff[j][res], tres);
- }
- }
-}
-
-void Tables::initEnvelopes(float samplerate) {
- for (int lf = 0; lf <= 100; lf++) {
- float elf = (float)lf;
-
- // General envelope
- // This formula fits observation of the CM-32L by +/- 0.03s or so for the second time value in the filter,
- // when all other times were 0 and all levels were 100. Note that variations occur depending on the level
- // delta of the section, which we're not fully emulating.
- float seconds = powf(2.0f, (elf / 8.0f) + 7.0f) / 32768.0f;
- int samples = (int)(seconds * samplerate);
- envTime[lf] = samples;
-
- // Cap on envelope times depending on the level delta
- if (elf == 0) {
- envDeltaMaxTime[lf] = 63;
- } else {
- float cap = 11.0f * (float)log(elf) + 64;
- if (cap > 100.0f) {
- cap = 100.0f;
- }
- envDeltaMaxTime[lf] = (int)cap;
- }
-
-
- // This (approximately) represents the time durations when the target level is 0.
- // Not sure why this is a special case, but it's seen to be from the real thing.
- seconds = powf(2, (elf / 8.0f) + 6) / 32768.0f;
- envDecayTime[lf] = (int)(seconds * samplerate);
-
- // I am certain of this: Verified by hand LFO log
- lfoPeriod[lf] = (Bit32u)(((float)samplerate) / (powf(1.088883372f, (float)lf) * 0.021236044f));
- }
-}
-
-void Tables::initMT32ConstantTables(Synth *synth) {
- int lf;
- synth->printDebug("Initializing Pitch Tables");
- for (lf = -108; lf <= 108; lf++) {
- tvfKeyfollowMult[lf + 108] = (int)(256 * powf(2.0f, (float)(lf / 24.0f)));
- //synth->printDebug("KT %d = %d", f, keytable[f+108]);
- }
-
- for (int res = 0; res < 31; res++) {
- resonanceFactor[res] = powf((float)res / 30.0f, 5.0f) + 1.0f;
- }
-
- int period = 65536;
-
- for (int ang = 0; ang < period; ang++) {
- int halfang = (period / 2);
- int angval = ang % halfang;
- float tval = (((float)angval / (float)halfang) - 0.5f) * 2;
- if (ang >= halfang)
- tval = -tval;
- sintable[ang] = (Bit16s)(tval * 50.0f) + 50;
- }
-
- int velt, dep;
- float tempdep;
- for (velt = 0; velt < 128; velt++) {
- for (dep = 0; dep < 5; dep++) {
- if (dep > 0) {
- float ff = (float)(exp(3.5f * tvcatconst[dep] * (59.0f - (float)velt)) * tvcatmult[dep]);
- tempdep = 256.0f * ff;
- envTimeVelfollowMult[dep][velt] = (int)tempdep;
- //if ((velt % 16) == 0) {
- // synth->printDebug("Key %d, depth %d, factor %d", velt, dep, (int)tempdep);
- //}
- } else
- envTimeVelfollowMult[dep][velt] = 256;
- }
-
- for (dep = -7; dep < 8; dep++) {
- float fldep = (float)abs(dep) / 7.0f;
- fldep = powf(fldep,2.5f);
- if (dep < 0)
- fldep = fldep * -1.0f;
- pwVelfollowAdd[dep+7][velt] = Bit32s((fldep * (float)velt * 100) / 128.0);
- }
- }
-
- for (dep = 0; dep <= 100; dep++) {
- for (velt = 0; velt < 128; velt++) {
- float fdep = (float)dep * 0.000347013f; // Another MT-32 constant
- float fv = ((float)velt - 64.0f)/7.26f;
- float flogdep = powf(10, fdep * fv);
- float fbase;
-
- if (velt > 64)
- synth->tables.tvfVelfollowMult[velt][dep] = (int)(flogdep * 256.0);
- else {
- //lff = 1 - (pow(((128.0 - (float)lf) / 64.0),.25) * ((float)velt / 96));
- fbase = 1 - (powf(((float)dep / 100.0f),.25f) * ((float)(64-velt) / 96.0f));
- synth->tables.tvfVelfollowMult[velt][dep] = (int)(fbase * 256.0);
- }
- //synth->printDebug("Filvel dep %d velt %d = %x", dep, velt, filveltable[velt][dep]);
- }
- }
-
- for (lf = 0; lf < 128; lf++) {
- float veloFract = lf / 127.0f;
- for (int velsens = 0; velsens <= 100; velsens++) {
- float sensFract = (velsens - 50) / 50.0f;
- if (velsens < 50) {
- tvaVelfollowMult[lf][velsens] = FIXEDPOINT_MAKE(1.0f / powf(2.0f, veloFract * -sensFract * 127.0f / 20.0f), 8);
- } else {
- tvaVelfollowMult[lf][velsens] = FIXEDPOINT_MAKE(1.0f / powf(2.0f, (1.0f - veloFract) * sensFract * 127.0f / 20.0f), 8);
- }
- }
- }
-
- for (lf = 0; lf <= 100; lf++) {
- // Converts the 0-100 range used by the MT-32 to volume multiplier
- volumeMult[lf] = FIXEDPOINT_MAKE(powf((float)lf / 100.0f, FLOAT_LN), 7);
- }
-
- for (lf = 0; lf <= 100; lf++) {
- float mv = lf / 100.0f;
- float pt = mv - 0.5f;
- if (pt < 0)
- pt = 0;
-
- // Original (CC version)
- //pwFactor[lf] = (int)(pt * 210.04f) + 128;
-
- // Approximation from sample comparison
- pwFactor[lf] = (int)(pt * 179.0f) + 128;
- }
-
- for (unsigned int i = 0; i < MAX_SAMPLE_OUTPUT; i++) {
- int myRand;
- myRand = rand();
- //myRand = ((myRand - 16383) * 7168) >> 16;
- // This one is slower but works with all values of RAND_MAX
- myRand = (int)((myRand - RAND_MAX / 2) / (float)RAND_MAX * (7168 / 2));
- //FIXME:KG: Original ultimately set the lowest two bits to 0, for no obvious reason
- noiseBuf[i] = (Bit16s)myRand;
- }
-
- float tdist;
- float padjtable[51];
- for (lf = 0; lf <= 50; lf++) {
- if (lf == 0)
- padjtable[lf] = 7;
- else if (lf == 1)
- padjtable[lf] = 6;
- else if (lf == 2)
- padjtable[lf] = 5;
- else if (lf == 3)
- padjtable[lf] = 4;
- else if (lf == 4)
- padjtable[lf] = 4 - (0.333333f);
- else if (lf == 5)
- padjtable[lf] = 4 - (0.333333f * 2);
- else if (lf == 6)
- padjtable[lf] = 3;
- else if ((lf > 6) && (lf <= 12)) {
- tdist = (lf-6.0f) / 6.0f;
- padjtable[lf] = 3.0f - tdist;
- } else if ((lf > 12) && (lf <= 25)) {
- tdist = (lf - 12.0f) / 13.0f;
- padjtable[lf] = 2.0f - tdist;
- } else {
- tdist = (lf - 25.0f) / 25.0f;
- padjtable[lf] = 1.0f - tdist;
- }
- //synth->printDebug("lf %d = padj %f", lf, (double)padjtable[lf]);
- }
-
- float lfp, depf, finalval, tlf;
- int depat, pval, depti;
- for (lf = 0; lf <= 10; lf++) {
- // I believe the depth is cubed or something
-
- for (depat = 0; depat <= 100; depat++) {
- if (lf > 0) {
- depti = abs(depat - 50);
- tlf = (float)lf - padjtable[depti];
- if (tlf < 0)
- tlf = 0;
- lfp = (float)exp(0.713619942f * tlf) / 407.4945111f;
-
- if (depat < 50)
- finalval = 4096.0f * powf(2, -lfp);
- else
- finalval = 4096.0f * powf(2, lfp);
- pval = (int)finalval;
-
- pitchEnvVal[lf][depat] = pval;
- //synth->printDebug("lf %d depat %d pval %d tlf %f lfp %f", lf,depat,pval, (double)tlf, (double)lfp);
- } else {
- pitchEnvVal[lf][depat] = 4096;
- //synth->printDebug("lf %d depat %d pval 4096", lf, depat);
- }
- }
- }
- for (lf = 0; lf <= 100; lf++) {
- // It's linear - verified on MT-32 - one of the few things linear
- lfp = ((float)lf * 0.1904f) / 310.55f;
-
- for (depat = 0; depat <= 100; depat++) {
- depf = ((float)depat - 50.0f) / 50.0f;
- //finalval = pow(2, lfp * depf * .5);
- finalval = 4096.0f + (4096.0f * lfp * depf);
-
- pval = (int)finalval;
-
- lfoShift[lf][depat] = pval;
-
- //synth->printDebug("lf %d depat %d pval %x", lf,depat,pval);
- }
- }
-
- for (lf = 0; lf <= 12; lf++) {
- for (int distval = 0; distval < 128; distval++) {
- float amplog, dval;
- if (lf == 0) {
- amplog = 0;
- dval = 1;
- tvaBiasMult[lf][distval] = 256;
- } else {
- /*
- amplog = powf(1.431817011f, (float)lf) / FLOAT_PI;
- dval = ((128.0f - (float)distval) / 128.0f);
- amplog = exp(amplog);
- dval = powf(amplog, dval) / amplog;
- tvaBiasMult[lf][distval] = (int)(dval * 256.0);
- */
- // Lets assume for a second it's linear
-
- // Distance of full volume reduction
- amplog = (float)(12.0f / (float)lf) * 24.0f;
- if (distval > amplog) {
- tvaBiasMult[lf][distval] = 0;
- } else {
- dval = (amplog - (float)distval) / amplog;
- tvaBiasMult[lf][distval] = (int)(dval * 256.0f);
- }
- }
- //synth->printDebug("Ampbias lf %d distval %d = %f (%x) %f", lf, distval, (double)dval, tvaBiasMult[lf][distval],(double)amplog);
- }
- }
-
- for (lf = 0; lf <= 14; lf++) {
- for (int distval = 0; distval < 128; distval++) {
- float filval = fabsf((float)((lf - 7) * 12) / 7.0f);
- float amplog, dval;
- if (lf == 7) {
- amplog = 0;
- dval = 1;
- tvfBiasMult[lf][distval] = 256;
- } else {
- //amplog = pow(1.431817011, filval) / FLOAT_PI;
- amplog = powf(1.531817011f, filval) / FLOAT_PI;
- dval = (128.0f - (float)distval) / 128.0f;
- amplog = (float)exp(amplog);
- dval = powf(amplog,dval)/amplog;
- if (lf < 8) {
- tvfBiasMult[lf][distval] = (int)(dval * 256.0f);
- } else {
- dval = powf(dval, 0.3333333f);
- if (dval < 0.01f)
- dval = 0.01f;
- dval = 1 / dval;
- tvfBiasMult[lf][distval] = (int)(dval * 256.0f);
- }
- }
- //synth->printDebug("Fbias lf %d distval %d = %f (%x) %f", lf, distval, (double)dval, tvfBiasMult[lf][distval],(double)amplog);
- }
- }
-}
-
-// Per-note table initialisation follows
-
-static void initSaw(NoteLookup *noteLookup, Bit32s div2) {
- int tmpdiv = div2 << 16;
- for (int rsaw = 0; rsaw <= 100; rsaw++) {
- float fsaw;
- if (rsaw < 50)
- fsaw = 50.0f;
- else
- fsaw = (float)rsaw;
-
- //(66 - (((A8 - 50) / 50) ^ 0.63) * 50) / 132
- float sawfact = (66.0f - (powf((fsaw - 50.0f) / 50.0f, 0.63f) * 50.0f)) / 132.0f;
- noteLookup->sawTable[rsaw] = (int)(sawfact * (float)tmpdiv) >> 16;
- //synth->printDebug("F %d divtable %d saw %d sawtable %d", f, div, rsaw, sawtable[f][rsaw]);
- }
-}
-
-static void initDep(KeyLookup *keyLookup, float f) {
- for (int dep = 0; dep < 5; dep++) {
- if (dep == 0) {
- keyLookup->envDepthMult[dep] = 256;
- keyLookup->envTimeMult[dep] = 256;
- } else {
- float depfac = 3000.0f;
- float ff, tempdep;
- depfac = (float)depexp[dep];
-
- ff = (f - (float)MIDDLEC) / depfac;
- tempdep = powf(2, ff) * 256.0f;
- keyLookup->envDepthMult[dep] = (int)tempdep;
-
- ff = (float)(exp(tkcatconst[dep] * ((float)MIDDLEC - f)) * tkcatmult[dep]);
- keyLookup->envTimeMult[dep] = (int)(ff * 256.0f);
- }
- }
- //synth->printDebug("F %f d1 %x d2 %x d3 %x d4 %x d5 %x", (double)f, noteLookup->fildepTable[0], noteLookup->fildepTable[1], noteLookup->fildepTable[2], noteLookup->fildepTable[3], noteLookup->fildepTable[4]);
-}
-
-Bit16s Tables::clampWF(Synth *synth, const char *n, float ampVal, double input) {
- Bit32s x = (Bit32s)(input * ampVal);
- if (x < -ampVal - 1) {
- synth->printDebug("%s==%d<-WGAMP-1!", n, x);
- x = (Bit32s)(-ampVal - 1);
- } else if (x > ampVal) {
- synth->printDebug("%s==%d>WGAMP!", n, x);
- x = (Bit32s)ampVal;
- }
- return (Bit16s)x;
-}
-
-File *Tables::initWave(Synth *synth, NoteLookup *noteLookup, float ampVal, float div2, File *file) {
- int iDiv2 = (int)div2;
- noteLookup->waveformSize[0] = iDiv2 << 1;
- noteLookup->waveformSize[1] = iDiv2 << 1;
- noteLookup->waveformSize[2] = iDiv2 << 2;
- for (int i = 0; i < 3; i++) {
- if (noteLookup->waveforms[i] == NULL) {
- noteLookup->waveforms[i] = new Bit16s[noteLookup->waveformSize[i]];
- }
- }
- if (file != NULL) {
- for (int i = 0; i < 3 && file != NULL; i++) {
- size_t len = noteLookup->waveformSize[i];
- for (unsigned int j = 0; j < len; j++) {
- if (!file->readBit16u((Bit16u *)&noteLookup->waveforms[i][j])) {
- synth->printDebug("Error reading wave file cache!");
- file->close();
- file = NULL;
- break;
- }
- }
- }
- }
- if (file == NULL) {
- double sd = DOUBLE_PI / div2;
-
- for (int fa = 0; fa < (iDiv2 << 1); fa++) {
- // sa ranges from 0 to 2PI
- double sa = fa * sd;
-
- // Calculate a sample for the bandlimited sawtooth wave
- double saw = 0.0;
- int sincs = iDiv2 >> 1;
- double sinus = 1.0;
- for (int sincNum = 1; sincNum <= sincs; sincNum++) {
- saw += sin(sinus * sa) / sinus;
- sinus++;
- }
-
- // This works pretty well
- // Multiplied by 0.84 so that the spikes caused by bandlimiting don't overdrive the amplitude
- noteLookup->waveforms[0][fa] = clampWF(synth, "saw", ampVal, -saw / (0.5 * DOUBLE_PI) * 0.84);
- noteLookup->waveforms[1][fa] = clampWF(synth, "cos", ampVal, -cos(sa / 2.0));
- noteLookup->waveforms[2][fa * 2] = clampWF(synth, "cosoff_0", ampVal, -cos(sa - DOUBLE_PI));
- noteLookup->waveforms[2][fa * 2 + 1] = clampWF(synth, "cosoff_1", ampVal, -cos((sa + (sd / 2)) - DOUBLE_PI));
- }
- }
- return file;
-}
-
-static void initFiltTable(NoteLookup *noteLookup, float freq, float rate) {
- for (int tr = 0; tr <= 200; tr++) {
- float ftr = (float)tr;
-
- // Verified exact on MT-32
- if (tr > 100)
- ftr = 100.0f + (powf((ftr - 100.0f) / 100.0f, 3.0f) * 100.0f);
-
- // I think this is the one
- float brsq = powf(10.0f, (tr / 50.0f) - 1.0f);
- noteLookup->filtTable[0][tr] = (int)((freq * brsq) / (rate / 2) * FILTERGRAN);
- if (noteLookup->filtTable[0][tr]>=((FILTERGRAN*15)/16))
- noteLookup->filtTable[0][tr] = ((FILTERGRAN*15)/16);
-
- float brsa = powf(10.0f, ((tr / 55.0f) - 1.0f)) / 2.0f;
- noteLookup->filtTable[1][tr] = (int)((freq * brsa) / (rate / 2) * FILTERGRAN);
- if (noteLookup->filtTable[1][tr]>=((FILTERGRAN*15)/16))
- noteLookup->filtTable[1][tr] = ((FILTERGRAN*15)/16);
- }
-}
-
-static void initNFiltTable(NoteLookup *noteLookup, float freq, float rate) {
- for (int cf = 0; cf <= 100; cf++) {
- float cfmult = (float)cf;
-
- for (int tf = 0;tf <= 100; tf++) {
- float tfadd = (float)tf;
-
- //float freqsum = exp((cfmult + tfadd) / 30.0f) / 4.0f;
- //float freqsum = 0.15f * exp(0.45f * ((cfmult + tfadd) / 10.0f));
-
- float freqsum = powf(2.0f, ((cfmult + tfadd) - 40.0f) / 16.0f);
-
- noteLookup->nfiltTable[cf][tf] = (int)((freq * freqsum) / (rate / 2) * FILTERGRAN);
- if (noteLookup->nfiltTable[cf][tf] >= ((FILTERGRAN * 15) / 16))
- noteLookup->nfiltTable[cf][tf] = ((FILTERGRAN * 15) / 16);
- }
- }
-}
-
-File *Tables::initNote(Synth *synth, NoteLookup *noteLookup, float note, float rate, float masterTune, PCMWaveEntry *pcmWaves, File *file) {
- float freq = (float)(masterTune * pow(2.0, ((double)note - MIDDLEA) / 12.0));
- float div2 = rate * 2.0f / freq;
- noteLookup->div2 = (int)div2;
-
- if (noteLookup->div2 == 0)
- noteLookup->div2 = 1;
-
- initSaw(noteLookup, noteLookup->div2);
-
- //synth->printDebug("Note %f; freq=%f, div=%f", (double)note, (double)freq, (double) rate / freq);
- file = initWave(synth, noteLookup, WGAMP, div2, file);
-
- // Create the pitch tables
- if (noteLookup->wavTable == NULL)
- noteLookup->wavTable = new Bit32u[synth->controlROMMap->pcmCount];
- double rateMult = 32000.0 / rate;
- double tuner = freq * 65536.0f;
- for (int pc = 0; pc < synth->controlROMMap->pcmCount; pc++) {
- noteLookup->wavTable[pc] = (int)(tuner / pcmWaves[pc].tune * rateMult);
- }
-
- initFiltTable(noteLookup, freq, rate);
- initNFiltTable(noteLookup, freq, rate);
- return file;
-}
-
-bool Tables::initNotes(Synth *synth, PCMWaveEntry *pcmWaves, float rate, float masterTune) {
- const char *NoteNames[12] = {
- "C ", "C#", "D ", "D#", "E ", "F ", "F#", "G ", "G#", "A ", "A#", "B "
- };
- char filename[64];
- int intRate = (int)rate;
- char version[4] = {0, 0, 0, 5};
- sprintf(filename, "waveformcache-%d-%.2f.raw", intRate, (double)masterTune);
-
- File *file = NULL;
- char header[20];
- memcpy(header, "MT32WAVE", 8);
- int pos = 8;
- // Version...
- for (int i = 0; i < 4; i++)
- header[pos++] = version[i];
- header[pos++] = (char)((intRate >> 24) & 0xFF);
- header[pos++] = (char)((intRate >> 16) & 0xFF);
- header[pos++] = (char)((intRate >> 8) & 0xFF);
- header[pos++] = (char)(intRate & 0xFF);
- int intTuning = (int)masterTune;
- header[pos++] = (char)((intTuning >> 8) & 0xFF);
- header[pos++] = (char)(intTuning & 0xFF);
- header[pos++] = 0;
- header[pos] = (char)((masterTune - intTuning) * 10);
-#if MT32EMU_WAVECACHEMODE < 2
- bool reading = false;
- file = synth->openFile(filename, File::OpenMode_read);
- if (file != NULL) {
- char fileHeader[20];
- if (file->read(fileHeader, 20) == 20) {
- if (memcmp(fileHeader, header, 20) == 0) {
- Bit16u endianCheck;
- if (file->readBit16u(&endianCheck)) {
- if (endianCheck == 1) {
- reading = true;
- } else {
- synth->printDebug("Endian check in %s does not match expected", filename);
- }
- } else {
- synth->printDebug("Unable to read endian check in %s", filename);
- }
- } else {
- synth->printDebug("Header of %s does not match expected", filename);
- }
- } else {
- synth->printDebug("Error reading 16 bytes of %s", filename);
- }
- if (!reading) {
- file->close();
- file = NULL;
- }
- } else {
- synth->printDebug("Unable to open %s for reading", filename);
- }
-#endif
-
- float progress = 0.0f;
- bool abort = false;
- synth->report(ReportType_progressInit, &progress);
- for (int f = LOWEST_NOTE; f <= HIGHEST_NOTE; f++) {
- synth->printDebug("Initializing note %s%d", NoteNames[f % 12], (f / 12) - 2);
- NoteLookup *noteLookup = &noteLookups[f - LOWEST_NOTE];
- file = initNote(synth, noteLookup, (float)f, rate, masterTune, pcmWaves, file);
- progress = (f - LOWEST_NOTE + 1) / (float)NUM_NOTES;
- abort = synth->report(ReportType_progressInit, &progress) != 0;
- if (abort)
- break;
- }
-
-#if MT32EMU_WAVECACHEMODE == 0 || MT32EMU_WAVECACHEMODE == 2
- if (file == NULL) {
- file = synth->openFile(filename, File::OpenMode_write);
- if (file != NULL) {
- if (file->write(header, 20) == 20 && file->writeBit16u(1)) {
- for (int f = 0; f < NUM_NOTES; f++) {
- for (int i = 0; i < 3 && file != NULL; i++) {
- int len = noteLookups[f].waveformSize[i];
- for (int j = 0; j < len; j++) {
- if (!file->writeBit16u(noteLookups[f].waveforms[i][j])) {
- synth->printDebug("Error writing waveform cache file");
- file->close();
- file = NULL;
- break;
- }
- }
- }
- }
- } else {
- synth->printDebug("Error writing 16-byte header to %s - won't continue saving", filename);
- }
- } else {
- synth->printDebug("Unable to open %s for writing - won't be created", filename);
- }
- }
-#endif
-
- if (file != NULL)
- synth->closeFile(file);
- return !abort;
-}
-
-void Tables::freeNotes() {
- for (int t = 0; t < 3; t++) {
- for (int m = 0; m < NUM_NOTES; m++) {
- if (noteLookups[m].waveforms[t] != NULL) {
- delete[] noteLookups[m].waveforms[t];
- noteLookups[m].waveforms[t] = NULL;
- noteLookups[m].waveformSize[t] = 0;
- }
- if (noteLookups[m].wavTable != NULL) {
- delete[] noteLookups[m].wavTable;
- noteLookups[m].wavTable = NULL;
- }
- }
- }
- initializedMasterTune = 0.0f;
-}
-
-Tables::Tables() {
- initializedSampleRate = 0.0f;
- initializedMasterTune = 0.0f;
- memset(&noteLookups, 0, sizeof(noteLookups));
-}
-
-bool Tables::init(Synth *synth, PCMWaveEntry *pcmWaves, float sampleRate, float masterTune) {
- if (sampleRate <= 0.0f) {
- synth->printDebug("Bad sampleRate (%f <= 0.0f)", (double)sampleRate);
- return false;
- }
- if (initializedSampleRate == 0.0f) {
- initMT32ConstantTables(synth);
- }
- if (initializedSampleRate != sampleRate) {
- initFiltCoeff(sampleRate);
- initEnvelopes(sampleRate);
- for (int key = 12; key <= 108; key++) {
- initDep(&keyLookups[key - 12], (float)key);
- }
- }
- if (initializedSampleRate != sampleRate || initializedMasterTune != masterTune) {
- freeNotes();
- if (!initNotes(synth, pcmWaves, sampleRate, masterTune)) {
- return false;
- }
- initializedSampleRate = sampleRate;
- initializedMasterTune = masterTune;
- }
- return true;
-}
-
-}
diff --git a/audio/softsynth/mt32/tables.h b/audio/softsynth/mt32/tables.h
deleted file mode 100644
index 9950323e7b..0000000000
--- a/audio/softsynth/mt32/tables.h
+++ /dev/null
@@ -1,116 +0,0 @@
-/* Copyright (c) 2003-2005 Various contributors
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- */
-
-#ifndef MT32EMU_TABLES_H
-#define MT32EMU_TABLES_H
-
-namespace MT32Emu {
-
-// Mathematical constants
-const double DOUBLE_PI = 3.1415926535897932384626433832795;
-const double DOUBLE_LN = 2.3025850929940456840179914546844;
-const float FLOAT_PI = 3.1415926535897932384626433832795f;
-const float FLOAT_LN = 2.3025850929940456840179914546844f;
-
-// Filter settings
-const int FILTERGRAN = 512;
-
-// Amplitude of waveform generator
-// FIXME: This value is the amplitude possible whilst avoiding
-// overdriven values immediately after filtering when playing
-// back SQ3MT.MID. Needs to be checked.
-const int WGAMP = 12382;
-
-const int MIDDLEC = 60;
-const int MIDDLEA = 69; // By this I mean "A above middle C"
-
-// FIXME:KG: may only need to do 12 to 108
-// 12..108 is the range allowed by note on commands, but the key can be modified by pitch keyfollow
-// and adjustment for timbre pitch, so the results can be outside that range.
-// Should we move it (by octave) into the 12..108 range, or keep it in 0..127 range,
-// or something else altogether?
-const int LOWEST_NOTE = 12;
-const int HIGHEST_NOTE = 127;
-const int NUM_NOTES = HIGHEST_NOTE - LOWEST_NOTE + 1; // Number of slots for note LUT
-
-class Synth;
-
-struct NoteLookup {
- Bit32u div2;
- Bit32u *wavTable;
- Bit32s sawTable[101];
- int filtTable[2][201];
- int nfiltTable[101][101];
- Bit16s *waveforms[3];
- Bit32u waveformSize[3];
-};
-
-struct KeyLookup {
- Bit32s envTimeMult[5]; // For envelope time adjustment for key pressed
- Bit32s envDepthMult[5];
-};
-
-class Tables {
- float initializedSampleRate;
- float initializedMasterTune;
- void initMT32ConstantTables(Synth *synth);
- static Bit16s clampWF(Synth *synth, const char *n, float ampVal, double input);
- static File *initWave(Synth *synth, NoteLookup *noteLookup, float ampsize, float div2, File *file);
- bool initNotes(Synth *synth, PCMWaveEntry *pcmWaves, float rate, float tuning);
- void initEnvelopes(float sampleRate);
- void initFiltCoeff(float samplerate);
-public:
- // Constant LUTs
- Bit32s tvfKeyfollowMult[217];
- Bit32s tvfVelfollowMult[128][101];
- Bit32s tvfBiasMult[15][128];
- Bit32u tvaVelfollowMult[128][101];
- Bit32s tvaBiasMult[13][128];
- Bit16s noiseBuf[MAX_SAMPLE_OUTPUT];
- Bit16s sintable[65536];
- Bit32s pitchEnvVal[16][101];
- Bit32s envTimeVelfollowMult[5][128];
- Bit32s pwVelfollowAdd[15][128];
- float resonanceFactor[31];
- Bit32u lfoShift[101][101];
- Bit32s pwFactor[101];
- Bit32s volumeMult[101];
-
- // LUTs varying with sample rate
- Bit32u envTime[101];
- Bit32u envDeltaMaxTime[101];
- Bit32u envDecayTime[101];
- Bit32u lfoPeriod[101];
- float filtCoeff[FILTERGRAN][31][8];
-
- // Various LUTs for each note and key
- NoteLookup noteLookups[NUM_NOTES];
- KeyLookup keyLookups[97];
-
- Tables();
- bool init(Synth *synth, PCMWaveEntry *pcmWaves, float sampleRate, float masterTune);
- File *initNote(Synth *synth, NoteLookup *noteLookup, float note, float rate, float tuning, PCMWaveEntry *pcmWaves, File *file);
- void freeNotes();
-};
-
-}
-
-#endif
diff --git a/audio/softsynth/opl/dbopl.cpp b/audio/softsynth/opl/dbopl.cpp
index 02c2317b25..43eb40e7ba 100644
--- a/audio/softsynth/opl/dbopl.cpp
+++ b/audio/softsynth/opl/dbopl.cpp
@@ -1131,14 +1131,14 @@ void Chip::WriteBD( Bit8u val ) {
#define REGOP( _FUNC_ ) \
index = ( ( reg >> 3) & 0x20 ) | ( reg & 0x1f ); \
if ( OpOffsetTable[ index ] ) { \
- Operator* regOp = (Operator*)( ((char *)this ) + OpOffsetTable[ index ] ); \
+ Operator* regOp = (Operator *)( ((char *)this ) + OpOffsetTable[ index ] ); \
regOp->_FUNC_( this, val ); \
}
#define REGCHAN( _FUNC_ ) \
index = ( ( reg >> 4) & 0x10 ) | ( reg & 0xf ); \
if ( ChanOffsetTable[ index ] ) { \
- Channel* regChan = (Channel*)( ((char *)this ) + ChanOffsetTable[ index ] ); \
+ Channel* regChan = (Channel *)( ((char *)this ) + ChanOffsetTable[ index ] ); \
regChan->_FUNC_( this, val ); \
}
diff --git a/audio/softsynth/opl/dbopl.h b/audio/softsynth/opl/dbopl.h
index 3dbd98986d..99234ebf88 100644
--- a/audio/softsynth/opl/dbopl.h
+++ b/audio/softsynth/opl/dbopl.h
@@ -18,8 +18,8 @@
// Last synch with DOSBox SVN trunk r3752
-#ifndef SOUND_SOFTSYNTH_OPL_DBOPL_H
-#define SOUND_SOFTSYNTH_OPL_DBOPL_H
+#ifndef AUDIO_SOFTSYNTH_OPL_DBOPL_H
+#define AUDIO_SOFTSYNTH_OPL_DBOPL_H
#include "common/scummsys.h"
diff --git a/audio/softsynth/opl/dosbox.h b/audio/softsynth/opl/dosbox.h
index cdf86df114..3adfe98852 100644
--- a/audio/softsynth/opl/dosbox.h
+++ b/audio/softsynth/opl/dosbox.h
@@ -26,8 +26,8 @@
* http://www.dosbox.com
*/
-#ifndef SOUND_SOFTSYNTH_OPL_DOSBOX_H
-#define SOUND_SOFTSYNTH_OPL_DOSBOX_H
+#ifndef AUDIO_SOFTSYNTH_OPL_DOSBOX_H
+#define AUDIO_SOFTSYNTH_OPL_DOSBOX_H
#ifndef DISABLE_DOSBOX_OPL
diff --git a/audio/softsynth/opl/mame.h b/audio/softsynth/opl/mame.h
index 803ca897e7..3714fa4e0a 100644
--- a/audio/softsynth/opl/mame.h
+++ b/audio/softsynth/opl/mame.h
@@ -23,8 +23,8 @@
*/
-#ifndef SOUND_SOFTSYNTH_OPL_MAME_H
-#define SOUND_SOFTSYNTH_OPL_MAME_H
+#ifndef AUDIO_SOFTSYNTH_OPL_MAME_H
+#define AUDIO_SOFTSYNTH_OPL_MAME_H
#include "common/scummsys.h"
#include "common/random.h"
diff --git a/audio/softsynth/pcspk.h b/audio/softsynth/pcspk.h
index 3641400b1f..f27eb94904 100644
--- a/audio/softsynth/pcspk.h
+++ b/audio/softsynth/pcspk.h
@@ -19,8 +19,8 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef SOUND_SOFTSYNTH_PCSPK_H
-#define SOUND_SOFTSYNTH_PCSPK_H
+#ifndef AUDIO_SOFTSYNTH_PCSPK_H
+#define AUDIO_SOFTSYNTH_PCSPK_H
#include "audio/audiostream.h"
#include "common/mutex.h"
@@ -81,4 +81,4 @@ protected:
} // End of namespace Audio
-#endif // SOUND_SOFTSYNTH_PCSPEAKER_H
+#endif // AUDIO_SOFTSYNTH_PCSPEAKER_H
diff --git a/audio/softsynth/sid.cpp b/audio/softsynth/sid.cpp
index 4b8f783ef4..1ad822b86a 100644
--- a/audio/softsynth/sid.cpp
+++ b/audio/softsynth/sid.cpp
@@ -27,7 +27,7 @@
#ifndef DISABLE_SID
-#include "sid.h"
+#include "audio/softsynth/sid.h"
#include "audio/null.h"
namespace Resid {
diff --git a/audio/softsynth/sid.h b/audio/softsynth/sid.h
index a015242844..88da0eb326 100644
--- a/audio/softsynth/sid.h
+++ b/audio/softsynth/sid.h
@@ -25,8 +25,8 @@
* Copyright (C) 2004 Dag Lem <resid@nimrod.no>
*/
-#ifndef __SID_H__
-#define __SID_H__
+#ifndef AUDIO_SOFTSYNTH_SID_H
+#define AUDIO_SOFTSYNTH_SID_H
// Inlining on/off.
#define RESID_INLINE inline
@@ -55,7 +55,7 @@ class WaveformGenerator {
public:
WaveformGenerator();
- void set_sync_source(WaveformGenerator*);
+ void set_sync_source(WaveformGenerator *);
void updateClock(cycle_count delta_t);
void synchronize();
@@ -272,7 +272,7 @@ class Voice {
public:
Voice();
- void set_sync_source(Voice*);
+ void set_sync_source(Voice *);
void reset();
void writeCONTROL_REG(reg8);
@@ -342,4 +342,4 @@ protected:
}
-#endif // not __SID_H__
+#endif // not AUDIO_SOFTSYNTH_SID_H
diff --git a/audio/softsynth/wave6581.cpp b/audio/softsynth/wave6581.cpp
index 63e08fb113..832a7272ff 100644
--- a/audio/softsynth/wave6581.cpp
+++ b/audio/softsynth/wave6581.cpp
@@ -27,7 +27,7 @@
#ifndef DISABLE_SID
-#include "sid.h"
+#include "audio/softsynth/sid.h"
namespace Resid {
diff --git a/audio/timestamp.h b/audio/timestamp.h
index ef095a2106..1683b554cb 100644
--- a/audio/timestamp.h
+++ b/audio/timestamp.h
@@ -20,8 +20,8 @@
*
*/
-#ifndef SOUND_TIMESTAMP_H
-#define SOUND_TIMESTAMP_H
+#ifndef AUDIO_TIMESTAMP_H
+#define AUDIO_TIMESTAMP_H
#include "common/scummsys.h"
diff --git a/backends/events/default/default-events.cpp b/backends/events/default/default-events.cpp
index 78072b0021..99d12c73dc 100644
--- a/backends/events/default/default-events.cpp
+++ b/backends/events/default/default-events.cpp
@@ -60,6 +60,8 @@ DefaultEventManager::DefaultEventManager(Common::EventSource *boss) :
// EventDispatcher will automatically free the keymapper
_dispatcher.registerMapper(_keymapper);
_remap = false;
+#else
+ _dispatcher.registerMapper(new Common::DefaultEventMapper());
#endif
}
@@ -100,67 +102,7 @@ bool DefaultEventManager::pollEvent(Common::Event &event) {
_currentKeyDown.flags = event.kbd.flags;
_keyRepeatTime = time + kKeyRepeatInitialDelay;
- // Global Main Menu
- if (event.kbd.hasFlags(Common::KBD_CTRL) && event.kbd.keycode == Common::KEYCODE_F5) {
- if (g_engine && !g_engine->isPaused()) {
- Common::Event menuEvent;
- menuEvent.type = Common::EVENT_MAINMENU;
-
- // FIXME: GSoC RTL branch passes the F6 key event to the
- // engine, and also enqueues a EVENT_MAINMENU. For now,
- // we just drop the key event and return an EVENT_MAINMENU
- // instead. This way, we don't have to add special cases
- // to engines (like it was the case for LURE in the RTL branch).
- //
- // However, this has other consequences, possibly negative ones.
- // Like, what happens with key repeat for the trigger key?
-
- //pushEvent(menuEvent);
- event = menuEvent;
-
- // FIXME: Since now we do not push another MAINMENU event onto
- // our event stack, the GMM would never open, so we have to do
- // that here. Of course when the engine would handle MAINMENU
- // as an event now and open up the GMM itself it would open the
- // menu twice.
- if (g_engine && !g_engine->isPaused())
- g_engine->openMainMenuDialog();
-
- if (_shouldQuit)
- event.type = Common::EVENT_QUIT;
- else if (_shouldRTL)
- event.type = Common::EVENT_RTL;
- }
- }
-#ifdef ENABLE_VKEYBD
- else if (event.kbd.keycode == Common::KEYCODE_F7 && event.kbd.hasFlags(0)) {
- if (_vk->isDisplaying()) {
- _vk->close(true);
- } else {
- if (g_engine)
- g_engine->pauseEngine(true);
- _vk->show();
- if (g_engine)
- g_engine->pauseEngine(false);
- result = false;
- }
- }
-#endif
-#ifdef ENABLE_KEYMAPPER
- else if (event.kbd.keycode == Common::KEYCODE_F8 && event.kbd.hasFlags(0)) {
- if (!_remap) {
- _remap = true;
- Common::RemapDialog _remapDialog;
- if (g_engine)
- g_engine->pauseEngine(true);
- _remapDialog.runModal();
- if (g_engine)
- g_engine->pauseEngine(false);
- _remap = false;
- }
- }
-#endif
- else if (event.kbd.keycode == Common::KEYCODE_BACKSPACE) {
+ if (event.kbd.keycode == Common::KEYCODE_BACKSPACE) {
// WORKAROUND: Some engines incorrectly attempt to use the
// ascii value instead of the keycode to detect the backspace
// key (a non-portable behavior). This fails at least on
@@ -214,7 +156,34 @@ bool DefaultEventManager::pollEvent(Common::Event &event) {
else if (_shouldRTL)
event.type = Common::EVENT_RTL;
break;
-
+#ifdef ENABLE_VKEYBD
+ case Common::EVENT_VIRTUAL_KEYBOARD:
+ if (_vk->isDisplaying()) {
+ _vk->close(true);
+ } else {
+ if (g_engine)
+ g_engine->pauseEngine(true);
+ _vk->show();
+ if (g_engine)
+ g_engine->pauseEngine(false);
+ result = false;
+ }
+ break;
+#endif
+#ifdef ENABLE_KEYMAPPER
+ case Common::EVENT_KEYMAPPER_REMAP:
+ if (!_remap) {
+ _remap = true;
+ Common::RemapDialog _remapDialog;
+ if (g_engine)
+ g_engine->pauseEngine(true);
+ _remapDialog.runModal();
+ if (g_engine)
+ g_engine->pauseEngine(false);
+ _remap = false;
+ }
+ break;
+#endif
case Common::EVENT_RTL:
if (ConfMan.getBool("confirm_exit")) {
if (g_engine)
diff --git a/backends/events/default/default-events.h b/backends/events/default/default-events.h
index 3a8025f5e8..4d89b78861 100644
--- a/backends/events/default/default-events.h
+++ b/backends/events/default/default-events.h
@@ -92,6 +92,8 @@ public:
#endif
#ifdef ENABLE_KEYMAPPER
+ // IMPORTANT NOTE: This is part of the WIP Keymapper. If you plan to use
+ // this, please talk to tsoliman and/or LordHoto.
virtual Common::Keymapper *getKeymapper() { return _keymapper; }
#endif
};
diff --git a/backends/events/maemosdl/maemosdl-events.cpp b/backends/events/maemosdl/maemosdl-events.cpp
index 32d5cfb5ac..dcdf0384e3 100644
--- a/backends/events/maemosdl/maemosdl-events.cpp
+++ b/backends/events/maemosdl/maemosdl-events.cpp
@@ -33,10 +33,25 @@ MaemoSdlEventSource::MaemoSdlEventSource() : SdlEventSource(), _clickEnabled(tru
}
+struct KeymapEntry {
+ SDLKey sym;
+ Common::KeyCode keycode;
+ uint16 ascii;
+};
+
+static const KeymapEntry keymapEntries[] = {
+ {SDLK_F4, Common::KEYCODE_F11, 0},
+ {SDLK_F5, Common::KEYCODE_F12, 0},
+ {SDLK_F6, Common::KEYCODE_F13, 0},
+ {SDLK_F7, Common::KEYCODE_F14, 0},
+ {SDLK_F8, Common::KEYCODE_F15, 0},
+ {SDLK_LAST, Common::KEYCODE_INVALID, 0}
+};
+
bool MaemoSdlEventSource::remapKey(SDL_Event &ev, Common::Event &event) {
Model model = Model(((OSystem_SDL_Maemo *)g_system)->getModel());
- debug(10, "Model: %s %u %s %s", model.hwId, model.modelType, model.hwAlias, model.hwKeyboard ? "true" : "false");
+ debug(10, "Model: %s %u %s %s", model.hwId, model.modelType, model.hwAlias, model.hasHwKeyboard ? "true" : "false");
// List of special N810 keys:
// SDLK_F4 -> menu
@@ -45,14 +60,32 @@ bool MaemoSdlEventSource::remapKey(SDL_Event &ev, Common::Event &event) {
// SDLK_F7 -> zoom +
// SDLK_F8 -> zoom -
+#ifdef ENABLE_KEYMAPPER
+ if (ev.type == SDL_KEYDOWN || ev.type == SDL_KEYUP) {
+ const KeymapEntry *entry;
+ for (entry = keymapEntries; entry->sym != SDLK_LAST; ++entry) {
+ if (ev.key.keysym.sym == entry->sym) {
+ SDLModToOSystemKeyFlags(SDL_GetModState(), event);
+ event.type = ev.type == SDL_KEYDOWN ? Common::EVENT_KEYDOWN : Common::EVENT_KEYUP;
+ event.kbd.keycode = entry->keycode;
+ event.kbd.ascii = entry->ascii;
+ return true;
+ }
+ }
+ }
+#else
switch (ev.type) {
case SDL_KEYDOWN:{
- if (ev.key.keysym.sym == SDLK_F4) {
+ if (ev.key.keysym.sym == SDLK_F4
+ || (model.modelType == kModelTypeN900
+ && ev.key.keysym.sym == SDLK_m
+ && (ev.key.keysym.mod & KMOD_CTRL)
+ && (ev.key.keysym.mod & KMOD_SHIFT))) {
event.type = Common::EVENT_MAINMENU;
debug(9, "remapping to main menu");
return true;
} else if (ev.key.keysym.sym == SDLK_F6) {
- if (!model.hwKeyboard) {
+ if (!model.hasHwKeyboard) {
event.type = Common::EVENT_KEYDOWN;
event.kbd.keycode = Common::KEYCODE_F7;
event.kbd.ascii = Common::ASCII_F7;
@@ -83,11 +116,15 @@ bool MaemoSdlEventSource::remapKey(SDL_Event &ev, Common::Event &event) {
break;
}
case SDL_KEYUP: {
- if (ev.key.keysym.sym == SDLK_F4) {
+ if (ev.key.keysym.sym == SDLK_F4
+ || (model.modelType == kModelTypeN900
+ && ev.key.keysym.sym == SDLK_m
+ && (ev.key.keysym.mod & KMOD_CTRL)
+ && (ev.key.keysym.mod & KMOD_SHIFT))) {
event.type = Common::EVENT_MAINMENU;
return true;
} else if (ev.key.keysym.sym == SDLK_F6) {
- if (!model.hwKeyboard) {
+ if (!model.hasHwKeyboard) {
event.type = Common::EVENT_KEYUP;
event.kbd.keycode = Common::KEYCODE_F7;
event.kbd.ascii = Common::ASCII_F7;
@@ -116,9 +153,7 @@ bool MaemoSdlEventSource::remapKey(SDL_Event &ev, Common::Event &event) {
debug(9, "remapping to F7 up (virtual keyboard)");
return true;
} else {
- _clickEnabled = !_clickEnabled;
- ((SurfaceSdlGraphicsManager*) _graphicsManager)->displayMessageOnOSD(
- _clickEnabled ? _("Clicking Enabled") : _("Clicking Disabled"));
+ toggleClickMode();
debug(9, "remapping to click toggle");
return true;
}
@@ -126,6 +161,7 @@ bool MaemoSdlEventSource::remapKey(SDL_Event &ev, Common::Event &event) {
break;
}
}
+#endif
// Invoke parent implementation of this method
return SdlEventSource::remapKey(ev, event);
}
@@ -150,6 +186,32 @@ bool MaemoSdlEventSource::handleMouseButtonUp(SDL_Event &ev, Common::Event &even
return SdlEventSource::handleMouseButtonUp(ev, event);
}
+bool MaemoSdlEventSource::toggleClickMode() {
+ _clickEnabled = !_clickEnabled;
+ ((SurfaceSdlGraphicsManager *) _graphicsManager)->displayMessageOnOSD(
+ _clickEnabled ? _("Clicking Enabled") : _("Clicking Disabled"));
+
+ return _clickEnabled;
+}
+
+MaemoSdlEventObserver::MaemoSdlEventObserver(MaemoSdlEventSource *eventSource) {
+ assert(eventSource);
+ _eventSource = eventSource;
+}
+
+bool MaemoSdlEventObserver::notifyEvent(const Common::Event &event) {
+#ifdef ENABLE_KEYMAPPER
+ if (event.type != Common::EVENT_CUSTOM_BACKEND_ACTION)
+ return false;
+ if (event.customType == kEventClickMode) {
+ assert(_eventSource);
+ _eventSource->toggleClickMode();
+ return true;
+ }
+#endif
+ return false;
+}
+
} // namespace Maemo
#endif // if defined(MAEMO)
diff --git a/backends/events/maemosdl/maemosdl-events.h b/backends/events/maemosdl/maemosdl-events.h
index 5c06c4bc22..f3f05feeca 100644
--- a/backends/events/maemosdl/maemosdl-events.h
+++ b/backends/events/maemosdl/maemosdl-events.h
@@ -37,6 +37,8 @@ namespace Maemo {
class MaemoSdlEventSource : public SdlEventSource {
public:
MaemoSdlEventSource();
+
+ bool toggleClickMode();
protected:
virtual bool remapKey(SDL_Event &ev, Common::Event &event);
virtual bool handleMouseButtonDown(SDL_Event &ev, Common::Event &event);
@@ -45,6 +47,15 @@ protected:
bool _clickEnabled;
};
+class MaemoSdlEventObserver : public Common::EventObserver {
+public:
+ MaemoSdlEventObserver(MaemoSdlEventSource *eventSource);
+
+ virtual bool notifyEvent(const Common::Event &event);
+private:
+ MaemoSdlEventSource *_eventSource;
+};
+
} // namespace Maemo
#endif // include guard
diff --git a/backends/events/webossdl/webossdl-events.cpp b/backends/events/webossdl/webossdl-events.cpp
index d01e51fafe..286289f7a6 100644
--- a/backends/events/webossdl/webossdl-events.cpp
+++ b/backends/events/webossdl/webossdl-events.cpp
@@ -151,8 +151,8 @@ bool WebOSSdlEventSource::handleMouseButtonDown(SDL_Event &ev,
event.type = Common::EVENT_LBUTTONDOWN;
processMouseEvent(event, _curX, _curY);
}
- // If we're not in touchpad mode, move the cursor to the tap
- if (!_touchpadMode) {
+ // If we're not in trackpad mode, move the cursor to the tap
+ if (!_trackpadMode) {
_curX = MIN(_screenX, MAX(0, 0 + ev.motion.x));
_curY = MIN(_screenY, MAX(0, 0 + ev.motion.y));
// If we're already clicking, hold it until after the move.
@@ -254,7 +254,7 @@ bool WebOSSdlEventSource::handleMouseMotion(SDL_Event &ev,
// If only one finger is on the screen and moving, that's
// the mouse pointer.
if (!_fingerDown[1] && !_fingerDown[2]) {
- if (_touchpadMode) {
+ if (_trackpadMode) {
_curX = MIN(_screenX, MAX(0, _curX + ev.motion.xrel));
_curY = MIN(_screenY, MAX(0, _curY + ev.motion.yrel));
} else {
@@ -301,16 +301,16 @@ bool WebOSSdlEventSource::handleMouseMotion(SDL_Event &ev,
_queuedEscapeUpTime = g_system->getMillis() +
QUEUED_KEY_DELAY;
} else if (_dragDiffX[0] > 0 && _dragDiffX[1] > 0) {
- // A swipe right toggles touchpad mode
- _touchpadMode = !_touchpadMode;
- g_system->showMouse(_touchpadMode);
- // I18N: Touchpad mode toggle status.
- Common::String dialogMsg(_("Touchpad mode is now"));
+ // A swipe right toggles trackpad mode
+ _trackpadMode = !_trackpadMode;
+ g_system->showMouse(_trackpadMode);
+ // I18N: Trackpad mode toggle status.
+ Common::String dialogMsg(_("Trackpad mode is now"));
dialogMsg += " ";
- // I18N: Touchpad mode on or off.
- dialogMsg += (_touchpadMode ? _("ON") : _("OFF"));
+ // I18N: Trackpad mode on or off.
+ dialogMsg += (_trackpadMode ? _("ON") : _("OFF"));
dialogMsg += ".\n";
- // I18N: Instructions to toggle Touchpad mode.
+ // I18N: Instructions to toggle Trackpad mode.
dialogMsg +=
_("Swipe two fingers to the right to toggle.");
GUI::TimedMessageDialog dialog(dialogMsg, 1500);
@@ -376,12 +376,12 @@ bool WebOSSdlEventSource::pollEvent(Common::Event &event) {
if (_firstPoll) {
// Set the initial dimensions
calculateDimensions();
-
- // Having a mouse pointer on screen when not in Touchpad mode is poor
+
+ // Having a mouse pointer on screen when not in Trackpad mode is poor
// interface design, because the user won't know whether to tap buttons
// or drag the pointer to them. On the first poll, set the appropriate
// pointer visibility.
- g_system->showMouse(_touchpadMode);
+ g_system->showMouse(_trackpadMode);
_firstPoll = false;
}
diff --git a/backends/events/webossdl/webossdl-events.h b/backends/events/webossdl/webossdl-events.h
index a36ee535a3..99ed3105f8 100644
--- a/backends/events/webossdl/webossdl-events.h
+++ b/backends/events/webossdl/webossdl-events.h
@@ -45,7 +45,7 @@ public:
_dragStartTime(0), _dragging(false),
_curX(0), _curY(0),
_screenX(0), _screenY(0),
- _touchpadMode(false), _autoDragMode(true),
+ _trackpadMode(false), _autoDragMode(true),
_doClick(true),
_queuedDragTime(0), _queuedEscapeUpTime(0), _queuedSpaceUpTime(0),
_queuedRUpTime(0),
@@ -80,8 +80,8 @@ protected:
// The drag distance for linear gestures
int _swipeDistX, _swipeDistY;
- // Indicates if we're in touchpad mode or tap-to-move mode.
- bool _touchpadMode;
+ // Indicates if we're in trackpad mode or tap-to-move mode.
+ bool _trackpadMode;
// Indicates if we're in automatic drag mode.
bool _autoDragMode;
diff --git a/backends/fs/amigaos4/amigaos4-fs.h b/backends/fs/amigaos4/amigaos4-fs.h
index 4e231330f0..c5ca61476f 100644
--- a/backends/fs/amigaos4/amigaos4-fs.h
+++ b/backends/fs/amigaos4/amigaos4-fs.h
@@ -91,10 +91,10 @@ public:
virtual ~AmigaOSFilesystemNode();
virtual bool exists() const;
- virtual Common::String getDisplayName() const { return _sDisplayName; };
- virtual Common::String getName() const { return _sDisplayName; };
- virtual Common::String getPath() const { return _sPath; };
- virtual bool isDirectory() const { return _bIsDirectory; };
+ virtual Common::String getDisplayName() const { return _sDisplayName; }
+ virtual Common::String getName() const { return _sDisplayName; }
+ virtual Common::String getPath() const { return _sPath; }
+ virtual bool isDirectory() const { return _bIsDirectory; }
virtual bool isReadable() const;
virtual bool isWritable() const;
diff --git a/backends/fs/ps2/ps2-fs.h b/backends/fs/ps2/ps2-fs.h
index 9323715c7f..df78f9f68a 100644
--- a/backends/fs/ps2/ps2-fs.h
+++ b/backends/fs/ps2/ps2-fs.h
@@ -96,7 +96,7 @@ public:
virtual Common::SeekableReadStream *createReadStream();
virtual Common::WriteStream *createWriteStream();
- int getDev() { return 0; };
+ int getDev() { return 0; }
};
#endif
diff --git a/backends/fs/psp/psp-fs-factory.h b/backends/fs/psp/psp-fs-factory.h
index aeaa9d6a87..d57c8fb655 100644
--- a/backends/fs/psp/psp-fs-factory.h
+++ b/backends/fs/psp/psp-fs-factory.h
@@ -37,7 +37,7 @@ public:
virtual AbstractFSNode *makeFileNodePath(const Common::String &path) const;
protected:
- PSPFilesystemFactory() {};
+ PSPFilesystemFactory() {}
private:
friend class Common::Singleton<SingletonBaseType>;
diff --git a/backends/fs/symbian/symbian-fs.cpp b/backends/fs/symbian/symbian-fs.cpp
index 9f70e7a7c9..fc78f7580b 100644
--- a/backends/fs/symbian/symbian-fs.cpp
+++ b/backends/fs/symbian/symbian-fs.cpp
@@ -70,7 +70,7 @@ SymbianFilesystemNode::SymbianFilesystemNode(const Common::String &path) {
TPtrC8 ptr((const unsigned char*)_path.c_str(),_path.size());
fname.Copy(ptr);
- if (static_cast<OSystem_SDL_Symbian*>(g_system)->FsSession().Entry(fname, fileAttribs) == KErrNone) {
+ if (static_cast<OSystem_SDL_Symbian *>(g_system)->FsSession().Entry(fname, fileAttribs) == KErrNone) {
_isValid = true;
_isDirectory = fileAttribs.IsDir();
} else {
@@ -87,7 +87,7 @@ bool SymbianFilesystemNode::exists() const {
TFileName fname;
TPtrC8 ptr((const unsigned char*) _path.c_str(), _path.size());
fname.Copy(ptr);
- bool fileExists = BaflUtils::FileExists(static_cast<OSystem_SDL_Symbian*> (g_system)->FsSession(), fname);
+ bool fileExists = BaflUtils::FileExists(static_cast<OSystem_SDL_Symbian *> (g_system)->FsSession(), fname);
if (!fileExists) {
TParsePtrC parser(fname);
if (parser.PathPresent() && parser.Path().Compare(_L("\\")) == KErrNone && !parser.NameOrExtPresent()) {
@@ -125,7 +125,7 @@ bool SymbianFilesystemNode::getChildren(AbstractFSList &myList, ListMode mode, b
if (_isPseudoRoot) {
// Drives enumeration
- RFs& fs = static_cast<OSystem_SDL_Symbian*>(g_system)->FsSession();
+ RFs& fs = static_cast<OSystem_SDL_Symbian *>(g_system)->FsSession();
TInt driveNumber;
TChar driveLetter;
TUint driveLetterValue;
@@ -153,7 +153,7 @@ bool SymbianFilesystemNode::getChildren(AbstractFSList &myList, ListMode mode, b
sprintf(path,"%c:\\", driveNumber+'A');
SymbianFilesystemNode entry(false);
- entry._displayName = (char*) driveString8.PtrZ(); // drive_name
+ entry._displayName = (char *) driveString8.PtrZ(); // drive_name
entry._isDirectory = true;
entry._isValid = true;
entry._isPseudoRoot = false;
@@ -170,7 +170,7 @@ bool SymbianFilesystemNode::getChildren(AbstractFSList &myList, ListMode mode, b
if (_path.lastChar() != '\\')
fname.Append('\\');
- if (static_cast<OSystem_SDL_Symbian*>(g_system)->FsSession().GetDir(fname, KEntryAttNormal|KEntryAttDir, 0, dirPtr) == KErrNone) {
+ if (static_cast<OSystem_SDL_Symbian *>(g_system)->FsSession().GetDir(fname, KEntryAttNormal|KEntryAttDir, 0, dirPtr) == KErrNone) {
CleanupStack::PushL(dirPtr);
TInt cnt = dirPtr->Count();
for (TInt loop = 0; loop < cnt; loop++) {
diff --git a/backends/fs/symbian/symbianstream.cpp b/backends/fs/symbian/symbianstream.cpp
index 39249578f7..fa7842d3b1 100644
--- a/backends/fs/symbian/symbianstream.cpp
+++ b/backends/fs/symbian/symbianstream.cpp
@@ -70,22 +70,22 @@ TSymbianFileEntry* CreateSymbianFileEntry(const char* name, const char* mode) {
switch (mode[0]) {
case 'a':
- if (fileEntry->_fileHandle.Open(static_cast<OSystem_SDL_Symbian*>(g_system)->FsSession(), tempFileName, fileMode) != KErrNone) {
- if (fileEntry->_fileHandle.Create(static_cast<OSystem_SDL_Symbian*>(g_system)->FsSession(), tempFileName, fileMode) != KErrNone) {
+ if (fileEntry->_fileHandle.Open(static_cast<OSystem_SDL_Symbian *>(g_system)->FsSession(), tempFileName, fileMode) != KErrNone) {
+ if (fileEntry->_fileHandle.Create(static_cast<OSystem_SDL_Symbian *>(g_system)->FsSession(), tempFileName, fileMode) != KErrNone) {
delete fileEntry;
fileEntry = NULL;
}
}
break;
case 'r':
- if (fileEntry->_fileHandle.Open(static_cast<OSystem_SDL_Symbian*>(g_system)->FsSession(), tempFileName, fileMode) != KErrNone) {
+ if (fileEntry->_fileHandle.Open(static_cast<OSystem_SDL_Symbian *>(g_system)->FsSession(), tempFileName, fileMode) != KErrNone) {
delete fileEntry;
fileEntry = NULL;
}
break;
case 'w':
- if (fileEntry->_fileHandle.Replace(static_cast<OSystem_SDL_Symbian*>(g_system)->FsSession(), tempFileName, fileMode) != KErrNone) {
+ if (fileEntry->_fileHandle.Replace(static_cast<OSystem_SDL_Symbian *>(g_system)->FsSession(), tempFileName, fileMode) != KErrNone) {
delete fileEntry;
fileEntry = NULL;
}
@@ -96,7 +96,7 @@ TSymbianFileEntry* CreateSymbianFileEntry(const char* name, const char* mode) {
}
size_t ReadData(const void* ptr, size_t size, size_t numItems, TSymbianFileEntry* handle) {
- TSymbianFileEntry* entry = ((TSymbianFileEntry*)(handle));
+ TSymbianFileEntry* entry = ((TSymbianFileEntry *)(handle));
TUint32 totsize = size*numItems;
TPtr8 pointer ( (unsigned char*) ptr, totsize);
@@ -169,29 +169,29 @@ SymbianStdioStream::SymbianStdioStream(void *handle) : _handle(handle) {
}
SymbianStdioStream::~SymbianStdioStream() {
- ((TSymbianFileEntry*)(_handle))->_fileHandle.Close();
+ ((TSymbianFileEntry *)(_handle))->_fileHandle.Close();
- delete (TSymbianFileEntry*)(_handle);
+ delete (TSymbianFileEntry *)(_handle);
}
bool SymbianStdioStream::err() const {
- return ((TSymbianFileEntry*)(_handle))->_lastError != 0;
+ return ((TSymbianFileEntry *)(_handle))->_lastError != 0;
}
void SymbianStdioStream::clearErr() {
- ((TSymbianFileEntry*)(_handle))->_lastError = 0;
- ((TSymbianFileEntry*)(_handle))->_eofReached = 0;
+ ((TSymbianFileEntry *)(_handle))->_lastError = 0;
+ ((TSymbianFileEntry *)(_handle))->_eofReached = 0;
}
bool SymbianStdioStream::eos() const {
- TSymbianFileEntry* entry = ((TSymbianFileEntry*)(_handle));
+ TSymbianFileEntry* entry = ((TSymbianFileEntry *)(_handle));
return entry->_eofReached != 0;
}
int32 SymbianStdioStream::pos() const {
TInt pos = 0;
- TSymbianFileEntry* entry = ((TSymbianFileEntry*)(_handle));
+ TSymbianFileEntry* entry = ((TSymbianFileEntry *)(_handle));
entry->_lastError = entry->_fileHandle.Seek(ESeekCurrent, pos);
if (entry->_lastError == KErrNone && entry->_inputPos != KErrNotFound) {
@@ -204,7 +204,7 @@ int32 SymbianStdioStream::pos() const {
int32 SymbianStdioStream::size() const {
TInt length = 0;
- ((TSymbianFileEntry*)(_handle))->_fileHandle.Size(length);
+ ((TSymbianFileEntry *)(_handle))->_fileHandle.Size(length);
return length;
}
@@ -214,7 +214,7 @@ bool SymbianStdioStream::seek(int32 offs, int whence) {
TSeek seekMode = ESeekStart;
TInt pos = offs;
- TSymbianFileEntry* entry = ((TSymbianFileEntry*)(_handle));
+ TSymbianFileEntry* entry = ((TSymbianFileEntry *)(_handle));
switch (whence) {
case SEEK_SET:
@@ -246,11 +246,11 @@ uint32 SymbianStdioStream::read(void *ptr, uint32 len) {
uint32 SymbianStdioStream::write(const void *ptr, uint32 len) {
TPtrC8 pointer( (unsigned char*) ptr, len);
- ((TSymbianFileEntry*)(_handle))->_inputPos = KErrNotFound;
- ((TSymbianFileEntry*)(_handle))->_lastError = ((TSymbianFileEntry*)(_handle))->_fileHandle.Write(pointer);
- ((TSymbianFileEntry*)(_handle))->_eofReached = EFalse;
+ ((TSymbianFileEntry *)(_handle))->_inputPos = KErrNotFound;
+ ((TSymbianFileEntry *)(_handle))->_lastError = ((TSymbianFileEntry *)(_handle))->_fileHandle.Write(pointer);
+ ((TSymbianFileEntry *)(_handle))->_eofReached = EFalse;
- if (((TSymbianFileEntry*)(_handle))->_lastError == KErrNone) {
+ if (((TSymbianFileEntry *)(_handle))->_lastError == KErrNone) {
return len;
}
@@ -258,7 +258,7 @@ uint32 SymbianStdioStream::write(const void *ptr, uint32 len) {
}
bool SymbianStdioStream::flush() {
- ((TSymbianFileEntry*)(_handle))->_fileHandle.Flush();
+ ((TSymbianFileEntry *)(_handle))->_fileHandle.Flush();
return true;
}
diff --git a/backends/fs/windows/windows-fs.cpp b/backends/fs/windows/windows-fs.cpp
index c32ad2da94..030f394f81 100644
--- a/backends/fs/windows/windows-fs.cpp
+++ b/backends/fs/windows/windows-fs.cpp
@@ -87,7 +87,7 @@ void WindowsFilesystemNode::addFile(AbstractFSList &list, ListMode mode, const c
char* WindowsFilesystemNode::toAscii(TCHAR *str) {
#ifndef UNICODE
- return (char*)str;
+ return (char *)str;
#else
static char asciiString[MAX_PATH];
WideCharToMultiByte(CP_ACP, 0, str, _tcslen(str) + 1, asciiString, sizeof(asciiString), NULL, NULL);
diff --git a/backends/graphics/maemosdl/maemosdl-graphics.cpp b/backends/graphics/maemosdl/maemosdl-graphics.cpp
new file mode 100644
index 0000000000..527ef82b9d
--- /dev/null
+++ b/backends/graphics/maemosdl/maemosdl-graphics.cpp
@@ -0,0 +1,60 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+#if defined(MAEMO)
+
+#include "SDL_syswm.h"
+
+#include "common/scummsys.h"
+
+#include "backends/platform/maemo/maemo.h"
+#include "backends/events/maemosdl/maemosdl-events.h"
+#include "backends/graphics/maemosdl/maemosdl-graphics.h"
+
+MaemoSdlGraphicsManager::MaemoSdlGraphicsManager(SdlEventSource *sdlEventSource)
+ : SurfaceSdlGraphicsManager(sdlEventSource) {
+}
+
+bool MaemoSdlGraphicsManager::loadGFXMode() {
+ bool success = SurfaceSdlGraphicsManager::loadGFXMode();
+
+ // fix the problematic zoom key capture in Maemo5/N900
+ SDL_SysWMinfo info;
+ SDL_VERSION(&info.version);
+ if (SDL_GetWMInfo(&info)) {
+ Display *dpy = info.info.x11.display;
+ Window win;
+ unsigned long val = 1;
+ Atom atom_zoom = XInternAtom(dpy, "_HILDON_ZOOM_KEY_ATOM", 0);
+ info.info.x11.lock_func();
+ win = info.info.x11.fswindow;
+ if (win)
+ XChangeProperty(dpy, win, atom_zoom, XA_INTEGER, 32, PropModeReplace, (unsigned char *) &val, 1); // grab zoom keys
+ win = info.info.x11.wmwindow;
+ if (win)
+ XChangeProperty(dpy, win, atom_zoom, XA_INTEGER, 32, PropModeReplace, (unsigned char *) &val, 1); // grab zoom keys
+ info.info.x11.unlock_func();
+ }
+
+ return success;
+}
+
+#endif
diff --git a/backends/graphics/maemosdl/maemosdl-graphics.h b/backends/graphics/maemosdl/maemosdl-graphics.h
new file mode 100644
index 0000000000..81064d2d5f
--- /dev/null
+++ b/backends/graphics/maemosdl/maemosdl-graphics.h
@@ -0,0 +1,40 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#if defined(MAEMO)
+
+#ifndef BACKENDS_GRAPHICS_MAEMOSDL_GRAPHICS_H
+#define BACKENDS_GRAPHICS_MAEMOSDL_GRAPHICS_H
+
+#include "backends/graphics/surfacesdl/surfacesdl-graphics.h"
+
+class MaemoSdlGraphicsManager : public SurfaceSdlGraphicsManager {
+public:
+ MaemoSdlGraphicsManager(SdlEventSource *sdlEventSource);
+
+protected:
+ virtual bool loadGFXMode();
+};
+
+#endif
+
+#endif
diff --git a/backends/graphics/null/null-graphics.h b/backends/graphics/null/null-graphics.h
index 28b24f6aca..2e6b24d147 100644
--- a/backends/graphics/null/null-graphics.h
+++ b/backends/graphics/null/null-graphics.h
@@ -27,7 +27,7 @@
static const OSystem::GraphicsMode s_noGraphicsModes[] = { {0, 0, 0} };
-class NullGraphicsManager : GraphicsManager {
+class NullGraphicsManager : public GraphicsManager {
public:
virtual ~NullGraphicsManager() {}
@@ -38,6 +38,7 @@ public:
const OSystem::GraphicsMode *getSupportedGraphicsModes() const { return s_noGraphicsModes; }
int getDefaultGraphicsMode() const { return 0; }
bool setGraphicsMode(int mode) { return true; }
+ void resetGraphicsScale(){}
int getGraphicsMode() const { return 0; }
inline Graphics::PixelFormat getScreenFormat() const {
return Graphics::PixelFormat::createFormatCLUT8();
diff --git a/backends/graphics/opengl/glerrorcheck.cpp b/backends/graphics/opengl/glerrorcheck.cpp
index 682207c7ef..439593577d 100644
--- a/backends/graphics/opengl/glerrorcheck.cpp
+++ b/backends/graphics/opengl/glerrorcheck.cpp
@@ -26,6 +26,7 @@
#include "backends/graphics/opengl/glerrorcheck.h"
#include "common/textconsole.h"
+#include "common/str.h"
#ifdef WIN32
#if defined(ARRAYSIZE) && !defined(_WINDOWS_)
@@ -44,7 +45,7 @@
#include <GL/gl.h>
#endif
-static const char *getGlErrStr(GLenum error) {
+static Common::String getGlErrStr(GLenum error) {
switch (error) {
case GL_NO_ERROR: return "GL_NO_ERROR";
case GL_INVALID_ENUM: return "GL_INVALID_ENUM";
@@ -54,16 +55,13 @@ static const char *getGlErrStr(GLenum error) {
case GL_OUT_OF_MEMORY: return "GL_OUT_OF_MEMORY";
}
- // FIXME: Convert to use Common::String::format()
- static char buf[40];
- snprintf(buf, sizeof(buf), "(Unknown GL error code 0x%x)", error);
- return buf;
+ return Common::String::format("(Unknown GL error code 0x%x)", error);
}
void checkGlError(const char *file, int line) {
GLenum error = glGetError();
if (error != GL_NO_ERROR)
- warning("%s:%d: GL error: %s", file, line, getGlErrStr(error));
+ warning("%s:%d: GL error: %s", file, line, getGlErrStr(error).c_str());
}
#endif
diff --git a/backends/graphics/opengl/gltexture.cpp b/backends/graphics/opengl/gltexture.cpp
index b7f5c90105..ce69dc4aab 100644
--- a/backends/graphics/opengl/gltexture.cpp
+++ b/backends/graphics/opengl/gltexture.cpp
@@ -11,7 +11,7 @@
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
@@ -60,8 +60,7 @@ void GLTexture::initGLExtensions() {
return;
// Get a string with all extensions
- const char* ext_string =
- reinterpret_cast<const char*>(glGetString(GL_EXTENSIONS));
+ const char *ext_string = (const char *)glGetString(GL_EXTENSIONS);
CHECK_GL_ERROR();
Common::StringTokenizer tokenizer(ext_string, " ");
// Iterate all string tokens
@@ -132,7 +131,7 @@ void GLTexture::allocBuffer(GLuint w, GLuint h) {
// Allocate room for the texture
glTexImage2D(GL_TEXTURE_2D, 0, _internalFormat,
- _textureWidth, _textureHeight, 0, _glFormat, _glType, NULL); CHECK_GL_ERROR();
+ _textureWidth, _textureHeight, 0, _glFormat, _glType, NULL); CHECK_GL_ERROR();
_refresh = false;
}
@@ -146,15 +145,15 @@ void GLTexture::updateBuffer(const void *buf, int pitch, GLuint x, GLuint y, GLu
glBindTexture(GL_TEXTURE_2D, _textureName); CHECK_GL_ERROR();
// Check if the buffer has its data contiguously
- if (static_cast<int>(w) * _bytesPerPixel == pitch) {
+ if ((int)w * _bytesPerPixel == pitch) {
glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, w, h,
- _glFormat, _glType, buf); CHECK_GL_ERROR();
+ _glFormat, _glType, buf); CHECK_GL_ERROR();
} else {
// Update the texture row by row
- const byte *src = static_cast<const byte *>(buf);
+ const byte *src = (const byte *)buf;
do {
glTexSubImage2D(GL_TEXTURE_2D, 0, x, y,
- w, 1, _glFormat, _glType, src); CHECK_GL_ERROR();
+ w, 1, _glFormat, _glType, src); CHECK_GL_ERROR();
++y;
src += pitch;
} while (--h);
diff --git a/backends/graphics/opengl/gltexture.h b/backends/graphics/opengl/gltexture.h
index 71f1eeb78f..8ff9838ff7 100644
--- a/backends/graphics/opengl/gltexture.h
+++ b/backends/graphics/opengl/gltexture.h
@@ -68,29 +68,29 @@ public:
static void initGLExtensions();
GLTexture(byte bpp, GLenum internalFormat, GLenum format, GLenum type);
- virtual ~GLTexture();
+ ~GLTexture();
/**
* Refresh the texture after a context change. The
* process will be completed on next allocBuffer call.
*/
- virtual void refresh();
+ void refresh();
/**
* Allocates memory needed for the given size.
*/
- virtual void allocBuffer(GLuint width, GLuint height);
+ void allocBuffer(GLuint width, GLuint height);
/**
* Updates the texture pixels.
*/
- virtual void updateBuffer(const void *buf, int pitch, GLuint x, GLuint y,
+ void updateBuffer(const void *buf, int pitch, GLuint x, GLuint y,
GLuint w, GLuint h);
/**
* Draws the texture to the screen buffer.
*/
- virtual void drawTexture(GLshort x, GLshort y, GLshort w, GLshort h);
+ void drawTexture(GLshort x, GLshort y, GLshort w, GLshort h);
/**
* Get the texture width.
@@ -103,12 +103,17 @@ public:
GLuint getHeight() const { return _realHeight; }
/**
+ * Get the bytes per pixel.
+ */
+ uint getBytesPerPixel() const { return _bytesPerPixel; }
+
+ /**
* Set the texture filter.
* @filter the filter type, GL_NEAREST or GL_LINEAR
*/
void setFilter(GLint filter) { _filter = filter; }
-protected:
+private:
const byte _bytesPerPixel;
const GLenum _internalFormat;
const GLenum _glFormat;
diff --git a/backends/graphics/opengl/opengl-graphics.cpp b/backends/graphics/opengl/opengl-graphics.cpp
index 8e01e76f16..45804b5d6e 100644
--- a/backends/graphics/opengl/opengl-graphics.cpp
+++ b/backends/graphics/opengl/opengl-graphics.cpp
@@ -81,8 +81,8 @@ OpenGLGraphicsManager::~OpenGLGraphicsManager() {
bool OpenGLGraphicsManager::hasFeature(OSystem::Feature f) {
return
- (f == OSystem::kFeatureAspectRatioCorrection) ||
- (f == OSystem::kFeatureCursorPalette);
+ (f == OSystem::kFeatureAspectRatioCorrection) ||
+ (f == OSystem::kFeatureCursorPalette);
}
void OpenGLGraphicsManager::setFeatureState(OSystem::Feature f, bool enable) {
@@ -269,9 +269,9 @@ OSystem::TransactionError OpenGLGraphicsManager::endGFXTransaction() {
}
if (_videoMode.fullscreen == _oldVideoMode.fullscreen &&
- _videoMode.mode == _oldVideoMode.mode &&
- _videoMode.screenWidth == _oldVideoMode.screenWidth &&
- _videoMode.screenHeight == _oldVideoMode.screenHeight) {
+ _videoMode.mode == _oldVideoMode.mode &&
+ _videoMode.screenWidth == _oldVideoMode.screenWidth &&
+ _videoMode.screenHeight == _oldVideoMode.screenHeight) {
_oldVideoMode.setup = false;
}
@@ -420,7 +420,7 @@ void OpenGLGraphicsManager::setShakePos(int shakeOffset) {
_shakePos = shakeOffset;
}
-void OpenGLGraphicsManager::setFocusRectangle(const Common::Rect& rect) {
+void OpenGLGraphicsManager::setFocusRectangle(const Common::Rect &rect) {
}
void OpenGLGraphicsManager::clearFocusRectangle() {
@@ -487,7 +487,8 @@ void OpenGLGraphicsManager::copyRectToOverlay(const OverlayColor *buf, int pitch
}
if (y < 0) {
- h += y; buf -= y * pitch;
+ h += y;
+ buf -= y * pitch;
y = 0;
}
@@ -500,26 +501,13 @@ void OpenGLGraphicsManager::copyRectToOverlay(const OverlayColor *buf, int pitch
if (w <= 0 || h <= 0)
return;
- if (_overlayFormat.aBits() == 1) {
- // Copy buffer with the alpha bit on for all pixels for correct
- // overlay drawing.
- const uint16 *src = (const uint16 *)buf;
- uint16 *dst = (uint16 *)_overlayData.pixels + y * _overlayData.w + x;
- for (int i = 0; i < h; i++) {
- for (int e = 0; e < w; e++)
- dst[e] = src[e] | 0x1;
- src += pitch;
- dst += _overlayData.w;
- }
- } else {
- // Copy buffer data to internal overlay surface
- const byte *src = (const byte *)buf;
- byte *dst = (byte *)_overlayData.pixels + y * _overlayData.pitch;
- for (int i = 0; i < h; i++) {
- memcpy(dst + x * _overlayData.format.bytesPerPixel, src, w * _overlayData.format.bytesPerPixel);
- src += pitch * sizeof(buf[0]);
- dst += _overlayData.pitch;
- }
+ // Copy buffer data to internal overlay surface
+ const byte *src = (const byte *)buf;
+ byte *dst = (byte *)_overlayData.pixels + y * _overlayData.pitch;
+ for (int i = 0; i < h; i++) {
+ memcpy(dst + x * _overlayData.format.bytesPerPixel, src, w * _overlayData.format.bytesPerPixel);
+ src += pitch * sizeof(buf[0]);
+ dst += _overlayData.pitch;
}
// Extend dirty area if not full screen redraw is flagged
@@ -594,10 +582,8 @@ void OpenGLGraphicsManager::warpMouse(int x, int y) {
scaledY += _displayY;
}
+ setMousePosition(scaledX, scaledY);
setInternalMousePosition(scaledX, scaledY);
-
- _cursorState.x = scaledX;
- _cursorState.y = scaledY;
}
void OpenGLGraphicsManager::setMouseCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, int cursorTargetScale, const Graphics::PixelFormat *format) {
@@ -613,7 +599,7 @@ void OpenGLGraphicsManager::setMouseCursor(const byte *buf, uint w, uint h, int
// Allocate space for cursor data
if (_cursorData.w != w || _cursorData.h != h ||
- _cursorData.format.bytesPerPixel != _cursorFormat.bytesPerPixel)
+ _cursorData.format.bytesPerPixel != _cursorFormat.bytesPerPixel)
_cursorData.create(w, h, _cursorFormat);
// Save cursor data
@@ -717,7 +703,7 @@ void OpenGLGraphicsManager::refreshGameScreen() {
} else {
// Update the texture
_gameTexture->updateBuffer((byte *)_screenData.pixels + y * _screenData.pitch +
- x * _screenData.format.bytesPerPixel, _screenData.pitch, x, y, w, h);
+ x * _screenData.format.bytesPerPixel, _screenData.pitch, x, y, w, h);
}
_screenNeedsRedraw = false;
@@ -759,7 +745,7 @@ void OpenGLGraphicsManager::refreshOverlay() {
} else {
// Update the texture
_overlayTexture->updateBuffer((byte *)_overlayData.pixels + y * _overlayData.pitch +
- x * _overlayData.format.bytesPerPixel, _overlayData.pitch, x, y, w, h);
+ x * _overlayData.format.bytesPerPixel, _overlayData.pitch, x, y, w, h);
}
_overlayNeedsRedraw = false;
@@ -838,38 +824,50 @@ void OpenGLGraphicsManager::refreshCursor() {
}
void OpenGLGraphicsManager::refreshCursorScale() {
- // Get the window minimum scale factor. The cursor will mantain its original aspect
- // ratio, and we do not want it to get too big if only one dimension is resized
- uint screenScaleFactor = MIN(_videoMode.hardwareWidth * 10000 / _videoMode.screenWidth,
- _videoMode.hardwareHeight * 10000 / _videoMode.screenHeight);
-
- // Do not scale cursor if original size is used
- if (_videoMode.mode == OpenGL::GFX_ORIGINAL)
- screenScaleFactor = _videoMode.scaleFactor * 10000;
-
- if ((uint)_cursorTargetScale * 10000 >= screenScaleFactor && (uint)_videoMode.scaleFactor * 10000 >= screenScaleFactor) {
- // If the cursor target scale and the video mode scale factor are bigger than
- // the current window scale, do not scale the cursor for the overlay
- _cursorState.rW = _cursorState.w;
- _cursorState.rH = _cursorState.h;
- _cursorState.rHotX = _cursorState.hotX;
- _cursorState.rHotY = _cursorState.hotY;
- } else {
- // Otherwise, scale the cursor for the overlay
- int targetScaleFactor = MIN(_cursorTargetScale, _videoMode.scaleFactor);
- // We limit the maximum scale to 3 here to avoid too big cursors, for large overlay resolutions
- int actualFactor = MIN<uint>(3, screenScaleFactor - (targetScaleFactor - 1)) * 10000;
- _cursorState.rW = (int16)(_cursorState.w * actualFactor / 10000);
- _cursorState.rH = (int16)(_cursorState.h * actualFactor / 10000);
- _cursorState.rHotX = (int16)(_cursorState.hotX * actualFactor / 10000);
- _cursorState.rHotY = (int16)(_cursorState.hotY * actualFactor / 10000);
- }
-
- // Always scale the cursor for the game
- _cursorState.vW = (int16)(_cursorState.w * screenScaleFactor / 10000);
- _cursorState.vH = (int16)(_cursorState.h * screenScaleFactor / 10000);
- _cursorState.vHotX = (int16)(_cursorState.hotX * screenScaleFactor / 10000);
- _cursorState.vHotY = (int16)(_cursorState.hotY * screenScaleFactor / 10000);
+ // Calculate the scale factors of the screen. We limit ourselves to 3 at
+ // most here to avoid really big (and ugly) cursors for big resolutions.
+ // It might be noteworthy that 3 is the (current) target scale for the
+ // modern theme and thus assures the cursor is *never* scaled.
+ // We also totally ignore the aspect of the overlay cursor, since aspect
+ // ratio correction only applies to the game screen.
+ uint screenScaleFactorX = MIN(30000, _videoMode.hardwareWidth * 10000 / _videoMode.screenWidth);
+ uint screenScaleFactorY = MIN(30000, _videoMode.hardwareHeight * 10000 / _videoMode.screenHeight);
+
+ // Apply the target scale factor to the cursor.
+ // It might be noteworthy we only apply any scaling to the cursor in case
+ // the current scale factor is bigger than the target scale to match
+ // SurfaceSdlGraphicsManager's behavior. Otherwise we would downscale the
+ // GUI cursor of the modern theme for example.
+ if (screenScaleFactorX > uint(_cursorTargetScale * 10000))
+ screenScaleFactorX /= _cursorTargetScale;
+ else
+ screenScaleFactorX = 10000;
+ if (screenScaleFactorY > uint(_cursorTargetScale * 10000))
+ screenScaleFactorY /= _cursorTargetScale;
+ else
+ screenScaleFactorY = 10000;
+
+ // Apply them (without any possible) aspect ratio correction to the
+ // overlay.
+ _cursorState.rW = (int16)(_cursorState.w * screenScaleFactorX / 10000);
+ _cursorState.rH = (int16)(_cursorState.h * screenScaleFactorY / 10000);
+ _cursorState.rHotX = (int16)(_cursorState.hotX * screenScaleFactorX / 10000);
+ _cursorState.rHotY = (int16)(_cursorState.hotY * screenScaleFactorY / 10000);
+
+ // Make sure we properly scale the cursor according to the desired aspect.
+ // It might be noteworthy that, unlike with the overlay, we do not limit
+ // the scale factor here to avoid odd looks if the game uses items as
+ // mouse cursor, which would otherwise suddenly be smaller.
+ int width, height;
+ calculateDisplaySize(width, height);
+ screenScaleFactorX = (width * 10000 / _videoMode.screenWidth) / _cursorTargetScale;
+ screenScaleFactorY = (height * 10000 / _videoMode.screenHeight) / _cursorTargetScale;
+
+ // Always scale the cursor for the game.
+ _cursorState.vW = (int16)(_cursorState.w * screenScaleFactorX / 10000);
+ _cursorState.vH = (int16)(_cursorState.h * screenScaleFactorY / 10000);
+ _cursorState.vHotX = (int16)(_cursorState.hotX * screenScaleFactorX / 10000);
+ _cursorState.vHotY = (int16)(_cursorState.hotY * screenScaleFactorY / 10000);
}
void OpenGLGraphicsManager::calculateDisplaySize(int &width, int &height) {
@@ -1031,10 +1029,10 @@ void OpenGLGraphicsManager::internUpdateScreen() {
// Draw the cursor
if (_overlayVisible)
_cursorTexture->drawTexture(_cursorState.x - _cursorState.rHotX,
- _cursorState.y - _cursorState.rHotY, _cursorState.rW, _cursorState.rH);
+ _cursorState.y - _cursorState.rHotY, _cursorState.rW, _cursorState.rH);
else
_cursorTexture->drawTexture(_cursorState.x - _cursorState.vHotX,
- _cursorState.y - _cursorState.vHotY, _cursorState.vW, _cursorState.vH);
+ _cursorState.y - _cursorState.vHotY, _cursorState.vW, _cursorState.vH);
glPopMatrix();
}
@@ -1115,8 +1113,6 @@ void OpenGLGraphicsManager::loadTextures() {
}
#endif
- uint gameScreenBPP = 0;
-
if (!_gameTexture) {
byte bpp;
GLenum intformat;
@@ -1127,7 +1123,6 @@ void OpenGLGraphicsManager::loadTextures() {
#else
getGLPixelFormat(Graphics::PixelFormat::createFormatCLUT8(), bpp, intformat, format, type);
#endif
- gameScreenBPP = bpp;
_gameTexture = new GLTexture(bpp, intformat, format, type);
} else
_gameTexture->refresh();
@@ -1161,23 +1156,23 @@ void OpenGLGraphicsManager::loadTextures() {
if (
#ifdef USE_RGB_COLOR
- _transactionDetails.formatChanged ||
+ _transactionDetails.formatChanged ||
#endif
- _oldVideoMode.screenWidth != _videoMode.screenWidth ||
- _oldVideoMode.screenHeight != _videoMode.screenHeight)
+ _oldVideoMode.screenWidth != _videoMode.screenWidth ||
+ _oldVideoMode.screenHeight != _videoMode.screenHeight)
_screenData.create(_videoMode.screenWidth, _videoMode.screenHeight,
#ifdef USE_RGB_COLOR
- _screenFormat
+ _screenFormat
#else
- Graphics::PixelFormat::createFormatCLUT8()
+ Graphics::PixelFormat::createFormatCLUT8()
#endif
- );
+ );
if (_oldVideoMode.overlayWidth != _videoMode.overlayWidth ||
- _oldVideoMode.overlayHeight != _videoMode.overlayHeight)
+ _oldVideoMode.overlayHeight != _videoMode.overlayHeight)
_overlayData.create(_videoMode.overlayWidth, _videoMode.overlayHeight,
- _overlayFormat);
+ _overlayFormat);
_screenNeedsRedraw = true;
_overlayNeedsRedraw = true;
@@ -1186,10 +1181,11 @@ void OpenGLGraphicsManager::loadTextures() {
// We need to setup a proper unpack alignment value here, else we will
// get problems with the texture updates, in case the surface data is
// not properly aligned.
- // For now we use the gcd of the game screen format and 2, since 2 is
- // the BPP value for the overlay and the OSD.
- if (gameScreenBPP)
- glPixelStorei(GL_UNPACK_ALIGNMENT, Common::gcd<uint>(gameScreenBPP, 2));
+ // It is noteworthy this assumes the OSD uses the same BPP as the overlay
+ // and that the cursor works with any alignment setting.
+ int newAlignment = Common::gcd(_gameTexture->getBytesPerPixel(), _overlayTexture->getBytesPerPixel());
+ assert(newAlignment == 1 || newAlignment == 2 || newAlignment == 4);
+ glPixelStorei(GL_UNPACK_ALIGNMENT, newAlignment);
// We use a "pack" alignment (when reading from textures) to 4 here,
// since the only place where we really use it is the BMP screenshot
@@ -1253,8 +1249,8 @@ uint OpenGLGraphicsManager::getAspectRatio() const {
// ratio correction is enabled, but it's better than the previous 4/3 mode
// mess at least...
if (_videoMode.aspectRatioCorrection
- && ((_videoMode.screenWidth == 320 && _videoMode.screenHeight == 200)
- || (_videoMode.screenWidth == 640 && _videoMode.screenHeight == 400)))
+ && ((_videoMode.screenWidth == 320 && _videoMode.screenHeight == 200)
+ || (_videoMode.screenWidth == 640 && _videoMode.screenHeight == 400)))
return 13333;
else if (_videoMode.mode == OpenGL::GFX_NORMAL)
return _videoMode.hardwareWidth * 10000 / _videoMode.hardwareHeight;
@@ -1266,15 +1262,13 @@ void OpenGLGraphicsManager::adjustMousePosition(int16 &x, int16 &y) {
if (_overlayVisible)
return;
- if (!_overlayVisible) {
- x -= _displayX;
- y -= _displayY;
+ x -= _displayX;
+ y -= _displayY;
- if (_displayWidth != _videoMode.screenWidth)
- x = x * _videoMode.screenWidth / _displayWidth;
- if (_displayHeight != _videoMode.screenHeight)
- y = y * _videoMode.screenHeight / _displayHeight;
- }
+ if (_displayWidth != _videoMode.screenWidth)
+ x = x * _videoMode.screenWidth / _displayWidth;
+ if (_displayHeight != _videoMode.screenHeight)
+ y = y * _videoMode.screenHeight / _displayHeight;
}
bool OpenGLGraphicsManager::saveScreenshot(const char *filename) {
@@ -1349,7 +1343,7 @@ const char *OpenGLGraphicsManager::getCurrentModeName() {
#ifdef USE_OSD
const Graphics::Font *OpenGLGraphicsManager::getFontOSD() {
- return FontMan.getFontByUsage(Graphics::FontManager::kLocalizedFont);
+ return FontMan.getFontByUsage(Graphics::FontManager::kLocalizedFont);
}
void OpenGLGraphicsManager::updateOSD() {
diff --git a/backends/graphics/opengl/opengl-graphics.h b/backends/graphics/opengl/opengl-graphics.h
index 6ded680eae..ad8765bab1 100644
--- a/backends/graphics/opengl/opengl-graphics.h
+++ b/backends/graphics/opengl/opengl-graphics.h
@@ -217,6 +217,7 @@ protected:
uint getAspectRatio() const;
+ void setFormatIsBGR(bool isBGR) { _formatBGR = isBGR; }
bool _formatBGR;
//
@@ -285,6 +286,14 @@ protected:
int _cursorTargetScale;
bool _cursorNeedsRedraw;
+ /**
+ * Set up the mouse position for graphics output.
+ *
+ * @param x X coordinate in native coordinates.
+ * @param y Y coordinate in native coordinates.
+ */
+ void setMousePosition(int x, int y) { _cursorState.x = x; _cursorState.y = y; }
+
virtual void refreshCursor();
virtual void refreshCursorScale();
@@ -312,20 +321,20 @@ protected:
#ifdef USE_OSD
/**
- * The OSD contents.
+ * Returns the font used for on screen display
*/
- Common::Array<Common::String> _osdLines;
-
- /**
- * Returns the font used for on screen display
- */
- virtual const Graphics::Font *getFontOSD();
+ virtual const Graphics::Font *getFontOSD();
/**
* Update the OSD texture / surface.
*/
void updateOSD();
+ /**
+ * The OSD contents.
+ */
+ Common::Array<Common::String> _osdLines;
+
GLTexture *_osdTexture;
Graphics::Surface _osdSurface;
uint8 _osdAlpha;
diff --git a/backends/graphics/openglsdl/openglsdl-graphics.cpp b/backends/graphics/openglsdl/openglsdl-graphics.cpp
index cfc78cfcac..b37d631c6d 100644
--- a/backends/graphics/openglsdl/openglsdl-graphics.cpp
+++ b/backends/graphics/openglsdl/openglsdl-graphics.cpp
@@ -318,12 +318,12 @@ bool OpenGLSdlGraphicsManager::loadGFXMode() {
// only used to ensure that the original pixel size aspect for these
// modes is used.
// (Non-square pixels on old monitors vs square pixel on new ones).
- if (_videoMode.aspectRatioCorrection
- && ((_videoMode.screenWidth == 320 && _videoMode.screenHeight == 200)
- || (_videoMode.screenWidth == 640 && _videoMode.screenHeight == 400)))
- _videoMode.overlayHeight = _videoMode.hardwareHeight = 240 * scaleFactor;
- else
- _videoMode.overlayHeight = _videoMode.hardwareHeight = _videoMode.screenHeight * scaleFactor;
+ if (_videoMode.aspectRatioCorrection) {
+ if (_videoMode.screenWidth == 320 && _videoMode.screenHeight == 200)
+ _videoMode.overlayHeight = _videoMode.hardwareHeight = 240 * scaleFactor;
+ else if (_videoMode.screenWidth == 640 && _videoMode.screenHeight == 400)
+ _videoMode.overlayHeight = _videoMode.hardwareHeight = 480 * scaleFactor;
+ }
}
_screenResized = false;
@@ -376,7 +376,7 @@ bool OpenGLSdlGraphicsManager::loadGFXMode() {
}
// Check if the screen is BGR format
- _formatBGR = _hwscreen->format->Rshift != 0;
+ setFormatIsBGR(_hwscreen->format->Rshift != 0);
if (isFullscreen) {
_lastFullscreenModeWidth = _videoMode.hardwareWidth;
@@ -460,10 +460,6 @@ void OpenGLSdlGraphicsManager::toggleFullScreen(int loop) {
_activeFullscreenMode = -2;
setFullscreenMode(!isFullscreen);
}
-
- // HACK: We need to force a refresh here, since we change the
- // fullscreen mode.
- _transactionDetails.needRefresh = true;
endGFXTransaction();
// Ignore resize events for the next 10 frames
@@ -486,7 +482,7 @@ void OpenGLSdlGraphicsManager::toggleFullScreen(int loop) {
}
bool OpenGLSdlGraphicsManager::notifyEvent(const Common::Event &event) {
- switch ((int)event.type) {
+ switch (event.type) {
case Common::EVENT_KEYDOWN:
if (event.kbd.hasFlags(Common::KBD_ALT)) {
// Alt-Return and Alt-Enter toggle full screen mode
@@ -671,8 +667,7 @@ void OpenGLSdlGraphicsManager::transformMouseCoordinates(Common::Point &point) {
}
void OpenGLSdlGraphicsManager::notifyMousePos(Common::Point mouse) {
- _cursorState.x = mouse.x;
- _cursorState.y = mouse.y;
+ setMousePosition(mouse.x, mouse.y);
}
#endif
diff --git a/backends/keymapper/action.cpp b/backends/keymapper/action.cpp
index 6ee506e7c3..33f5c423b0 100644
--- a/backends/keymapper/action.cpp
+++ b/backends/keymapper/action.cpp
@@ -28,10 +28,8 @@
namespace Common {
-Action::Action(Keymap *boss, const char *i, String des, ActionType typ,
- KeyType prefKey, int pri, int flg)
- : _boss(boss), description(des), type(typ), preferredKey(prefKey),
- priority(pri), flags(flg), _hwKey(0) {
+Action::Action(Keymap *boss, const char *i, String des)
+ : _boss(boss), description(des), _hwInput(0) {
assert(i);
assert(_boss);
@@ -40,18 +38,18 @@ Action::Action(Keymap *boss, const char *i, String des, ActionType typ,
_boss->addAction(this);
}
-void Action::mapKey(const HardwareKey *key) {
- if (_hwKey)
+void Action::mapInput(const HardwareInput *input) {
+ if (_hwInput)
_boss->unregisterMapping(this);
- _hwKey = key;
+ _hwInput = input;
- if (_hwKey)
- _boss->registerMapping(this, _hwKey);
+ if (_hwInput)
+ _boss->registerMapping(this, _hwInput);
}
-const HardwareKey *Action::getMappedKey() const {
- return _hwKey;
+const HardwareInput *Action::getMappedInput() const {
+ return _hwInput;
}
} // End of namespace Common
diff --git a/backends/keymapper/action.h b/backends/keymapper/action.h
index b15b3aaaad..5e69ed3918 100644
--- a/backends/keymapper/action.h
+++ b/backends/keymapper/action.h
@@ -27,7 +27,6 @@
#ifdef ENABLE_KEYMAPPER
-#include "backends/keymapper/types.h"
#include "common/events.h"
#include "common/func.h"
#include "common/list.h"
@@ -35,11 +34,17 @@
namespace Common {
-struct HardwareKey;
+struct HardwareInput;
class Keymap;
#define ACTION_ID_SIZE (4)
+struct KeyActionEntry {
+ const KeyState ks;
+ const char *id;
+ const char *description;
+};
+
struct Action {
/** unique id used for saving/loading to config */
char id[ACTION_ID_SIZE];
@@ -48,27 +53,26 @@ struct Action {
/** Events to be sent when mapped key is pressed */
List<Event> events;
- ActionType type;
- KeyType preferredKey;
- int priority;
- int group;
- int flags;
private:
- /** Hardware key that is mapped to this Action */
- const HardwareKey *_hwKey;
+ /** Hardware input that is mapped to this Action */
+ const HardwareInput *_hwInput;
Keymap *_boss;
public:
- Action(Keymap *boss, const char *id, String des = "",
- ActionType typ = kGenericActionType,
- KeyType prefKey = kGenericKeyType,
- int pri = 0, int flg = 0 );
+ Action(Keymap *boss, const char *id, String des = "");
void addEvent(const Event &evt) {
events.push_back(evt);
}
+ void addEvent(const EventType evtType) {
+ Event evt;
+
+ evt.type = evtType;
+ events.push_back(evt);
+ }
+
void addKeyEvent(const KeyState &ks) {
Event evt;
@@ -78,42 +82,24 @@ public:
}
void addLeftClickEvent() {
- Event evt;
-
- evt.type = EVENT_LBUTTONDOWN;
- addEvent(evt);
+ addEvent(EVENT_LBUTTONDOWN);
}
void addMiddleClickEvent() {
- Event evt;
-
- evt.type = EVENT_MBUTTONDOWN;
- addEvent(evt);
+ addEvent(EVENT_MBUTTONDOWN);
}
void addRightClickEvent() {
- Event evt;
-
- evt.type = EVENT_RBUTTONDOWN;
- addEvent(evt);
+ addEvent(EVENT_RBUTTONDOWN);
}
Keymap *getParent() {
return _boss;
}
- void mapKey(const HardwareKey *key);
- const HardwareKey *getMappedKey() const;
-
-};
+ void mapInput(const HardwareInput *input);
+ const HardwareInput *getMappedInput() const;
-struct ActionPriorityComp : public BinaryFunction<Action, Action, bool> {
- bool operator()(const Action *x, const Action *y) const {
- return x->priority > y->priority;
- }
- bool operator()(const Action &x, const Action &y) const {
- return x.priority > y.priority;
- }
};
} // End of namespace Common
diff --git a/backends/keymapper/hardware-input.cpp b/backends/keymapper/hardware-input.cpp
new file mode 100644
index 0000000000..a09f0b54fc
--- /dev/null
+++ b/backends/keymapper/hardware-input.cpp
@@ -0,0 +1,273 @@
+/* ScummVM - Graphic Adventure Engine
+*
+* ScummVM is the legal property of its developers, whose names
+* are too numerous to list here. Please refer to the COPYRIGHT
+* file distributed with this source distribution.
+*
+* This program is free software; you can redistribute it and/or
+* modify it under the terms of the GNU General Public License
+* as published by the Free Software Foundation; either version 2
+* of the License, or (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+*/
+
+#include "backends/keymapper/hardware-input.h"
+
+#ifdef ENABLE_KEYMAPPER
+
+#include "backends/keymapper/keymapper.h"
+
+namespace Common {
+
+static const KeyTableEntry defaultKeys[] = {
+ {"BACKSPACE", KEYCODE_BACKSPACE, ASCII_BACKSPACE, "Backspace", false},
+ {"TAB", KEYCODE_TAB, ASCII_TAB, "Tab", false},
+ {"CLEAR", KEYCODE_CLEAR, 0, "Clear", false},
+ {"RETURN", KEYCODE_RETURN, ASCII_RETURN, "Return", false},
+ {"PAUSE", KEYCODE_PAUSE, 0, "Pause", false},
+ {"ESCAPE", KEYCODE_ESCAPE, ASCII_ESCAPE, "Esc", false},
+ {"SPACE", KEYCODE_SPACE, ASCII_SPACE, "Space", false},
+ {"EXCLAIM", KEYCODE_EXCLAIM, '!', "!", false},
+ {"QUOTEDBL", KEYCODE_QUOTEDBL, '"', "\"", false},
+ {"HASH", KEYCODE_HASH, '#', "#", false},
+ {"DOLLAR", KEYCODE_DOLLAR, '$', "$", false},
+ {"AMPERSAND", KEYCODE_AMPERSAND, '&', "&", false},
+ {"QUOTE", KEYCODE_QUOTE, '\'', "'", false},
+ {"LEFTPAREN", KEYCODE_LEFTPAREN, '(', "(", false},
+ {"RIGHTPAREN", KEYCODE_RIGHTPAREN, ')', ")", false},
+ {"ASTERISK", KEYCODE_ASTERISK, '*', "*", false},
+ {"PLUS", KEYCODE_PLUS, '+', "+", false},
+ {"COMMA", KEYCODE_COMMA, ',', ",", false},
+ {"MINUS", KEYCODE_MINUS, '-', "-", false},
+ {"PERIOD", KEYCODE_PERIOD, '.', ".", false},
+ {"SLASH", KEYCODE_SLASH, '/', "/", false},
+ {"0", KEYCODE_0, '0', "0", false},
+ {"1", KEYCODE_1, '1', "1", false},
+ {"2", KEYCODE_2, '2', "2", false},
+ {"3", KEYCODE_3, '3', "3", false},
+ {"4", KEYCODE_4, '4', "4", false},
+ {"5", KEYCODE_5, '5', "5", false},
+ {"6", KEYCODE_6, '6', "6", false},
+ {"7", KEYCODE_7, '7', "7", false},
+ {"8", KEYCODE_8, '8', "8", false},
+ {"9", KEYCODE_9, '9', "9", false},
+ {"COLON", KEYCODE_COLON, ':', ":", false},
+ {"SEMICOLON", KEYCODE_SEMICOLON, ';', ";", false},
+ {"LESS", KEYCODE_LESS, '<', "<", false},
+ {"EQUALS", KEYCODE_EQUALS, '=', "=", false},
+ {"GREATER", KEYCODE_GREATER, '>', ">", false},
+ {"QUESTION", KEYCODE_QUESTION, '?', "?", false},
+ {"AT", KEYCODE_AT, '@', "@", false},
+
+ {"LEFTBRACKET", KEYCODE_LEFTBRACKET, '[', "[", false},
+ {"BACKSLASH", KEYCODE_BACKSLASH, '\\', "\\", false},
+ {"RIGHTBRACKET", KEYCODE_RIGHTBRACKET, ']', "]", false},
+ {"CARET", KEYCODE_CARET, '^', "^", false},
+ {"UNDERSCORE", KEYCODE_UNDERSCORE, '_', "_", false},
+ {"BACKQUOTE", KEYCODE_BACKQUOTE, '`', "`", false},
+ {"a", KEYCODE_a, 'a', "a", true},
+ {"b", KEYCODE_b, 'b', "b", true},
+ {"c", KEYCODE_c, 'c', "c", true},
+ {"d", KEYCODE_d, 'd', "d", true},
+ {"e", KEYCODE_e, 'e', "e", true},
+ {"f", KEYCODE_f, 'f', "f", true},
+ {"g", KEYCODE_g, 'g', "g", true},
+ {"h", KEYCODE_h, 'h', "h", true},
+ {"i", KEYCODE_i, 'i', "i", true},
+ {"j", KEYCODE_j, 'j', "j", true},
+ {"k", KEYCODE_k, 'k', "k", true},
+ {"l", KEYCODE_l, 'l', "l", true},
+ {"m", KEYCODE_m, 'm', "m", true},
+ {"n", KEYCODE_n, 'n', "n", true},
+ {"o", KEYCODE_o, 'o', "o", true},
+ {"p", KEYCODE_p, 'p', "p", true},
+ {"q", KEYCODE_q, 'q', "q", true},
+ {"r", KEYCODE_r, 'r', "r", true},
+ {"s", KEYCODE_s, 's', "s", true},
+ {"t", KEYCODE_t, 't', "t", true},
+ {"u", KEYCODE_u, 'u', "u", true},
+ {"v", KEYCODE_v, 'v', "v", true},
+ {"w", KEYCODE_w, 'w', "w", true},
+ {"x", KEYCODE_x, 'x', "x", true},
+ {"y", KEYCODE_y, 'y', "y", true},
+ {"z", KEYCODE_z, 'z', "z", true},
+ {"DELETE", KEYCODE_DELETE, 0, "Del", false},
+
+ // Numeric keypad
+ {"KP0", KEYCODE_KP0, 0, "KP0", false},
+ {"KP1", KEYCODE_KP1, 0, "KP1", false},
+ {"KP2", KEYCODE_KP2, 0, "KP2", false},
+ {"KP3", KEYCODE_KP3, 0, "KP3", false},
+ {"KP4", KEYCODE_KP4, 0, "KP4", false},
+ {"KP5", KEYCODE_KP5, 0, "KP5", false},
+ {"KP6", KEYCODE_KP6, 0, "KP6", false},
+ {"KP7", KEYCODE_KP7, 0, "KP7", false},
+ {"KP8", KEYCODE_KP8, 0, "KP8", false},
+ {"KP9", KEYCODE_KP9, 0, "KP9", false},
+ {"KP_PERIOD", KEYCODE_KP_PERIOD, 0, "KP.", false},
+ {"KP_DIVIDE", KEYCODE_KP_DIVIDE, 0, "KP/", false},
+ {"KP_MULTIPLY", KEYCODE_KP_MULTIPLY, 0, "KP*", false},
+ {"KP_MINUS", KEYCODE_KP_MINUS, 0, "KP-", false},
+ {"KP_PLUS", KEYCODE_KP_PLUS, 0, "KP+", false},
+ {"KP_ENTER", KEYCODE_KP_ENTER, 0, "KP Enter", false},
+ {"KP_EQUALS", KEYCODE_KP_EQUALS, 0, "KP=", false},
+
+ // Arrows + Home/End pad
+ {"UP", KEYCODE_UP, 0, "Up", false},
+ {"DOWN", KEYCODE_DOWN, 0, "Down", false},
+ {"RIGHT", KEYCODE_RIGHT, 0, "Right", false},
+ {"LEFT", KEYCODE_LEFT, 0, "Left", false},
+ {"INSERT", KEYCODE_INSERT, 0, "Insert", false},
+ {"HOME", KEYCODE_HOME, 0, "Home", false},
+ {"END", KEYCODE_END, 0, "End", false},
+ {"PAGEUP", KEYCODE_PAGEUP, 0, "PgUp", false},
+ {"PAGEDOWN", KEYCODE_PAGEDOWN, 0, "PgDn", false},
+
+ // Function keys
+ {"F1", KEYCODE_F1, ASCII_F1, "F1", false},
+ {"F2", KEYCODE_F2, ASCII_F2, "F2", false},
+ {"F3", KEYCODE_F3, ASCII_F3, "F3", false},
+ {"F4", KEYCODE_F4, ASCII_F4, "F4", false},
+ {"F5", KEYCODE_F5, ASCII_F5, "F5", false},
+ {"F6", KEYCODE_F6, ASCII_F6, "F6", false},
+ {"F7", KEYCODE_F7, ASCII_F7, "F7", false},
+ {"F8", KEYCODE_F8, ASCII_F8, "F8", false},
+ {"F9", KEYCODE_F9, ASCII_F9, "F9", false},
+ {"F10", KEYCODE_F10, ASCII_F10, "F10", false},
+ {"F11", KEYCODE_F11, ASCII_F11, "F11", false},
+ {"F12", KEYCODE_F12, ASCII_F12, "F12", false},
+ {"F13", KEYCODE_F13, 0, "F13", false},
+ {"F14", KEYCODE_F14, 0, "F14", false},
+ {"F15", KEYCODE_F15, 0, "F15", false},
+
+ // Miscellaneous function keys
+ {"HELP", KEYCODE_HELP, 0, "Help", false},
+ {"PRINT", KEYCODE_PRINT, 0, "Print", false},
+ {"SYSREQ", KEYCODE_SYSREQ, 0, "SysRq", false},
+ {"BREAK", KEYCODE_BREAK, 0, "Break", false},
+ {"MENU", KEYCODE_MENU, 0, "Menu", false},
+ // Power Macintosh power key
+ {"POWER", KEYCODE_POWER, 0, "Power", false},
+ // Some european keyboards
+ {"EURO", KEYCODE_EURO, 0, "Euro", false},
+ // Atari keyboard has Undo
+ {"UNDO", KEYCODE_UNDO, 0, "Undo", false},
+ {0, KEYCODE_INVALID, 0, 0, false}
+};
+
+static const ModifierTableEntry defaultModifiers[] = {
+ { 0, "", "", false },
+ { KBD_CTRL, "C+", "Ctrl+", false },
+ { KBD_ALT, "A+", "Alt+", false },
+ { KBD_SHIFT, "", "", true },
+ { KBD_CTRL | KBD_ALT, "C+A+", "Ctrl+Alt+", false },
+ { KBD_SHIFT | KBD_CTRL, "S+C+", "Shift+Ctrl+", true },
+ { KBD_SHIFT | KBD_CTRL | KBD_ALT, "C+A+", "Ctrl+Alt+", true },
+ { 0, 0, 0, false }
+};
+
+HardwareInputSet::HardwareInputSet(bool useDefault, const KeyTableEntry *keys, const ModifierTableEntry *modifiers) {
+ if (useDefault)
+ addHardwareInputs(defaultKeys, defaultModifiers);
+ if (keys)
+ addHardwareInputs(keys, modifiers ? modifiers : defaultModifiers);
+}
+
+HardwareInputSet::~HardwareInputSet() {
+ List<const HardwareInput *>::const_iterator it;
+
+ for (it = _inputs.begin(); it != _inputs.end(); ++it)
+ delete *it;
+}
+
+void HardwareInputSet::addHardwareInput(const HardwareInput *input) {
+ assert(input);
+
+ debug(8, "Adding hardware input [%s][%s]", input->id.c_str(), input->description.c_str());
+
+ removeHardwareInput(input);
+
+ _inputs.push_back(input);
+}
+
+const HardwareInput *HardwareInputSet::findHardwareInput(String id) const {
+ List<const HardwareInput *>::const_iterator it;
+
+ for (it = _inputs.begin(); it != _inputs.end(); ++it) {
+ if ((*it)->id == id)
+ return (*it);
+ }
+ return 0;
+}
+
+const HardwareInput *HardwareInputSet::findHardwareInput(const KeyState& keystate) const {
+ List<const HardwareInput *>::const_iterator it;
+
+ for (it = _inputs.begin(); it != _inputs.end(); ++it) {
+ if ((*it)->key == keystate)
+ return (*it);
+ }
+ return 0;
+}
+
+void HardwareInputSet::addHardwareInputs(const KeyTableEntry keys[], const ModifierTableEntry modifiers[]) {
+ const KeyTableEntry *key;
+ const ModifierTableEntry *mod;
+ char fullKeyId[50];
+ char fullKeyDesc[100];
+ uint16 ascii;
+
+ for (mod = modifiers; mod->id; mod++) {
+ for (key = keys; key->hwId; key++) {
+ ascii = key->ascii;
+
+ if (mod->shiftable && key->shiftable) {
+ snprintf(fullKeyId, 50, "%s%c", mod->id, toupper(key->hwId[0]));
+ snprintf(fullKeyDesc, 100, "%s%c", mod->desc, toupper(key->desc[0]));
+ ascii = toupper(key->ascii);
+ } else if (mod->shiftable) {
+ snprintf(fullKeyId, 50, "S+%s%s", mod->id, key->hwId);
+ snprintf(fullKeyDesc, 100, "Shift+%s%s", mod->desc, key->desc);
+ } else {
+ snprintf(fullKeyId, 50, "%s%s", mod->id, key->hwId);
+ snprintf(fullKeyDesc, 100, "%s%s", mod->desc, key->desc);
+ }
+
+ addHardwareInput(new HardwareInput(fullKeyId, KeyState(key->keycode, ascii, mod->flag), fullKeyDesc));
+ }
+ }
+}
+
+void HardwareInputSet::addHardwareInputs(const KeyTableEntry keys[]) {
+ addHardwareInputs(keys, defaultModifiers);
+}
+
+void HardwareInputSet::removeHardwareInput(const HardwareInput *input) {
+ if (!input)
+ return;
+
+ List<const HardwareInput *>::iterator it;
+
+ for (it = _inputs.begin(); it != _inputs.end(); ++it) {
+ const HardwareInput *entry = (*it);
+ if (entry->id == input->id || entry->key == input->key) {
+ debug(7, "Removing hardware input [%s] (%s) because it matches [%s] (%s)", entry->id.c_str(), entry->description.c_str(), input->id.c_str(), input->description.c_str());
+ delete entry;
+ _inputs.erase(it);
+ }
+ }
+}
+
+} //namespace Common
+
+#endif // #ifdef ENABLE_KEYMAPPER
+
diff --git a/backends/keymapper/hardware-input.h b/backends/keymapper/hardware-input.h
new file mode 100644
index 0000000000..9396765bbe
--- /dev/null
+++ b/backends/keymapper/hardware-input.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 COMMON_HARDWARE_KEY_H
+#define COMMON_HARDWARE_KEY_H
+
+#include "common/scummsys.h"
+
+#ifdef ENABLE_KEYMAPPER
+
+#include "common/keyboard.h"
+#include "common/list.h"
+#include "common/str.h"
+#include "common/textconsole.h"
+
+namespace Common {
+
+/**
+* Describes an available hardware input
+*/
+struct HardwareInput {
+ /** unique id used for saving/loading to config */
+ String id;
+
+ /** Human readable description */
+ String description;
+
+ /**
+ * The KeyState that is generated by the back-end
+ * when this hardware key is pressed.
+ */
+ KeyState key;
+
+ HardwareInput(String i, KeyState ky = KeyState(), String desc = "")
+ : id(i), key(ky), description(desc) { }
+};
+
+/**
+ * Entry in a static table of available non-modifier keys
+ */
+struct KeyTableEntry {
+ const char *hwId;
+ KeyCode keycode;
+ uint16 ascii;
+ const char *desc;
+ bool shiftable;
+};
+
+/**
+ * Entry in a static table of available key modifiers
+ */
+struct ModifierTableEntry {
+ byte flag;
+ const char *id;
+ const char *desc;
+ bool shiftable;
+};
+
+/**
+ * Simple class to encapsulate a device's set of HardwareInputs.
+ * Each device should instantiate this and call addHardwareInput a number of times
+ * in its constructor to define the device's available keys.
+ */
+class HardwareInputSet {
+public:
+
+ /**
+ * Add hardware input keys to the set out of key and modifier tables.
+ * @param useDefault auto-add the built-in default inputs
+ * @param keys table of available keys
+ * @param modifiers table of available modifiers
+ */
+ HardwareInputSet(bool useDefault = false, const KeyTableEntry keys[] = 0, const ModifierTableEntry modifiers[] = 0);
+
+ virtual ~HardwareInputSet();
+
+ void addHardwareInput(const HardwareInput *input);
+
+ const HardwareInput *findHardwareInput(String id) const;
+
+ const HardwareInput *findHardwareInput(const KeyState& keystate) const;
+
+ const List<const HardwareInput *> &getHardwareInputs() const { return _inputs; }
+
+ uint size() const { return _inputs.size(); }
+
+ /**
+ * Add hardware inputs to the set out of key and modifier tables.
+ * @param keys table of available keys
+ * @param modifiers table of available modifiers
+ */
+ void addHardwareInputs(const KeyTableEntry keys[], const ModifierTableEntry modifiers[]);
+
+ /**
+ * Add hardware inputs to the set out of a key table.
+ * The default modifiers are applied to the key entries
+ * @param keys table of available keys
+ */
+ void addHardwareInputs(const KeyTableEntry keys[]);
+
+ void removeHardwareInput(const HardwareInput *input);
+
+private:
+
+ List<const HardwareInput *> _inputs;
+};
+
+} // End of namespace Common
+
+#endif // #ifdef ENABLE_KEYMAPPER
+
+#endif // #ifndef COMMON_HARDWARE_KEY_H
diff --git a/backends/keymapper/hardware-key.h b/backends/keymapper/hardware-key.h
deleted file mode 100644
index 32df042525..0000000000
--- a/backends/keymapper/hardware-key.h
+++ /dev/null
@@ -1,136 +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 COMMON_HARDWARE_KEY_H
-#define COMMON_HARDWARE_KEY_H
-
-#include "common/scummsys.h"
-
-#ifdef ENABLE_KEYMAPPER
-
-#include "backends/keymapper/types.h"
-#include "common/textconsole.h"
-
-namespace Common {
-
-
-#define HWKEY_ID_SIZE (30)
-
-/**
-* Describes an available hardware key
-*/
-struct HardwareKey {
- /** unique id used for saving/loading to config */
- char hwKeyId[HWKEY_ID_SIZE];
-
- /** Human readable description */
- String description;
-
- /**
- * The KeyState that is generated by the back-end
- * when this hardware key is pressed.
- */
- KeyState key;
-
- KeyType type;
- ActionType preferredAction;
-
- HardwareKey(const char *i, KeyState ky = KeyState(), String desc = "",
- KeyType typ = kGenericKeyType, ActionType prefAct = kGenericActionType)
- : key(ky), description(desc), type(typ), preferredAction(prefAct) {
- assert(i);
- Common::strlcpy(hwKeyId, i, HWKEY_ID_SIZE);
- }
-};
-
-
-/**
- * Simple class to encapsulate a device's set of HardwareKeys.
- * Each device should instantiate this and call addHardwareKey a number of times
- * in its constructor to define the device's available keys.
- */
-class HardwareKeySet {
-public:
-
- virtual ~HardwareKeySet() {
- List<const HardwareKey*>::const_iterator it;
-
- for (it = _keys.begin(); it != _keys.end(); it++)
- delete *it;
- }
-
- void addHardwareKey(HardwareKey *key) {
- checkForKey(key);
- _keys.push_back(key);
- }
-
- const HardwareKey *findHardwareKey(const char *id) const {
- List<const HardwareKey*>::const_iterator it;
-
- for (it = _keys.begin(); it != _keys.end(); it++) {
- if (strncmp((*it)->hwKeyId, id, HWKEY_ID_SIZE) == 0)
- return (*it);
- }
- return 0;
- }
-
- const HardwareKey *findHardwareKey(const KeyState& keystate) const {
- List<const HardwareKey*>::const_iterator it;
-
- for (it = _keys.begin(); it != _keys.end(); it++) {
- if ((*it)->key == keystate)
- return (*it);
- }
- return 0;
- }
-
- const List<const HardwareKey*> &getHardwareKeys() const {
- return _keys;
- }
-
- uint size() const {
- return _keys.size();
- }
-
-
-private:
-
- void checkForKey(HardwareKey *key) {
- List<const HardwareKey*>::iterator it;
-
- for (it = _keys.begin(); it != _keys.end(); it++) {
- if (strncmp((*it)->hwKeyId, key->hwKeyId, HWKEY_ID_SIZE) == 0)
- error("Error adding HardwareKey '%s' - id of %s already in use!", key->description.c_str(), key->hwKeyId);
- else if ((*it)->key == key->key)
- error("Error adding HardwareKey '%s' - key already in use!", key->description.c_str());
- }
- }
-
- List<const HardwareKey*> _keys;
-};
-
-
-} // End of namespace Common
-
-#endif // #ifdef ENABLE_KEYMAPPER
-
-#endif // #ifndef COMMON_HARDWARE_KEY_H
diff --git a/backends/keymapper/keymap.cpp b/backends/keymapper/keymap.cpp
index 1518cba693..8ea975c927 100644
--- a/backends/keymapper/keymap.cpp
+++ b/backends/keymapper/keymap.cpp
@@ -24,26 +24,29 @@
#ifdef ENABLE_KEYMAPPER
-#include "backends/keymapper/hardware-key.h"
+#include "common/system.h"
+
+#include "backends/keymapper/hardware-input.h"
+#include "backends/keymapper/keymapper-defaults.h"
#define KEYMAP_KEY_PREFIX "keymap_"
namespace Common {
Keymap::Keymap(const Keymap& km) : _actions(km._actions), _keymap(), _configDomain(0) {
- List<Action*>::iterator it;
+ List<Action *>::iterator it;
for (it = _actions.begin(); it != _actions.end(); ++it) {
- const HardwareKey *hwKey = (*it)->getMappedKey();
+ const HardwareInput *hwInput = (*it)->getMappedInput();
- if (hwKey) {
- _keymap[hwKey->key] = *it;
+ if (hwInput) {
+ _keymap[hwInput->key] = *it;
}
}
}
Keymap::~Keymap() {
- List<Action*>::iterator it;
+ List<Action *>::iterator it;
for (it = _actions.begin(); it != _actions.end(); ++it)
delete *it;
@@ -56,24 +59,24 @@ void Keymap::addAction(Action *action) {
_actions.push_back(action);
}
-void Keymap::registerMapping(Action *action, const HardwareKey *hwKey) {
- HashMap<KeyState, Action*>::iterator it;
+void Keymap::registerMapping(Action *action, const HardwareInput *hwInput) {
+ HashMap<KeyState, Action *>::iterator it;
- it = _keymap.find(hwKey->key);
+ it = _keymap.find(hwInput->key);
// if key is already mapped to a different action then un-map it
if (it != _keymap.end() && action != it->_value) {
- it->_value->mapKey(0);
+ it->_value->mapInput(0);
}
- _keymap[hwKey->key] = action;
+ _keymap[hwInput->key] = action;
}
void Keymap::unregisterMapping(Action *action) {
- const HardwareKey *hwKey = action->getMappedKey();
+ const HardwareInput *hwInput = action->getMappedInput();
- if (hwKey) {
- _keymap.erase(hwKey->key);
+ if (hwInput) {
+ _keymap.erase(hwInput->key);
}
}
@@ -82,7 +85,7 @@ Action *Keymap::getAction(const char *id) {
}
Action *Keymap::findAction(const char *id) {
- List<Action*>::iterator it;
+ List<Action *>::iterator it;
for (it = _actions.begin(); it != _actions.end(); ++it) {
if (strncmp((*it)->id, id, ACTION_ID_SIZE) == 0)
@@ -92,7 +95,7 @@ Action *Keymap::findAction(const char *id) {
}
const Action *Keymap::findAction(const char *id) const {
- List<Action*>::const_iterator it;
+ List<Action *>::const_iterator it;
for (it = _actions.begin(); it != _actions.end(); ++it) {
if (strncmp((*it)->id, id, ACTION_ID_SIZE) == 0)
@@ -103,7 +106,7 @@ const Action *Keymap::findAction(const char *id) const {
}
Action *Keymap::getMappedAction(const KeyState& ks) const {
- HashMap<KeyState, Action*>::iterator it;
+ HashMap<KeyState, Action *>::iterator it;
it = _keymap.find(ks);
@@ -117,40 +120,55 @@ void Keymap::setConfigDomain(ConfigManager::Domain *dom) {
_configDomain = dom;
}
-void Keymap::loadMappings(const HardwareKeySet *hwKeys) {
+void Keymap::loadMappings(const HardwareInputSet *hwKeys) {
if (!_configDomain)
return;
- ConfigManager::Domain::iterator it;
- String prefix = KEYMAP_KEY_PREFIX + _name + "_";
+ if (_actions.empty())
+ return;
- for (it = _configDomain->begin(); it != _configDomain->end(); ++it) {
- const String& key = it->_key;
+ Common::KeymapperDefaultBindings *defaults = g_system->getKeymapperDefaultBindings();
- if (!key.hasPrefix(prefix.c_str()))
- continue;
+ HashMap<String, const HardwareInput *> mappedInputs;
+ List<Action*>::iterator it;
+ String prefix = KEYMAP_KEY_PREFIX + _name + "_";
- // parse Action ID
- const char *actionId = key.c_str() + prefix.size();
- Action *ua = getAction(actionId);
+ for (it = _actions.begin(); it != _actions.end(); ++it) {
+ Action* ua = *it;
+ String actionId(ua->id);
+ String confKey = prefix + actionId;
+
+ String hwInputId = _configDomain->getVal(confKey);
+
+ bool defaulted = false;
+ // fall back to the platform-specific defaults
+ if (hwInputId.empty() && defaults) {
+ hwInputId = defaults->getDefaultBinding(_name, actionId);
+ if (!hwInputId.empty())
+ defaulted = true;
+ }
+ // there's no mapping
+ if (hwInputId.empty())
+ continue;
- if (!ua) {
- warning("'%s' keymap does not contain Action with ID %s",
- _name.c_str(), actionId);
- _configDomain->erase(key);
+ const HardwareInput *hwInput = hwKeys->findHardwareInput(hwInputId.c_str());
+ if (!hwInput) {
+ warning("HardwareInput with ID '%s' not known", hwInputId.c_str());
continue;
}
- const HardwareKey *hwKey = hwKeys->findHardwareKey(it->_value.c_str());
-
- if (!hwKey) {
- warning("HardwareKey with ID %s not known", it->_value.c_str());
- _configDomain->erase(key);
- continue;
+ if (defaulted) {
+ if (mappedInputs.contains(hwInputId)) {
+ debug(1, "Action [%s] not falling back to hardcoded default value [%s] because the hardware input is in use", confKey.c_str(), hwInputId.c_str());
+ continue;
+ }
+ warning("Action [%s] fell back to hardcoded default value [%s]", confKey.c_str(), hwInputId.c_str());
}
- ua->mapKey(hwKey);
+ mappedInputs.setVal(hwInputId, hwInput);
+ // map the key
+ ua->mapInput(hwInput);
}
}
@@ -158,7 +176,7 @@ void Keymap::saveMappings() {
if (!_configDomain)
return;
- List<Action*>::const_iterator it;
+ List<Action *>::const_iterator it;
String prefix = KEYMAP_KEY_PREFIX + _name + "_";
for (it = _actions.begin(); it != _actions.end(); ++it) {
@@ -167,170 +185,29 @@ void Keymap::saveMappings() {
actIdLen = (actIdLen > ACTION_ID_SIZE) ? ACTION_ID_SIZE : actIdLen;
String actId((*it)->id, (*it)->id + actIdLen);
- char hwId[HWKEY_ID_SIZE+1];
-
- memset(hwId, 0, HWKEY_ID_SIZE+1);
+ String hwId = "";
- if ((*it)->getMappedKey()) {
- memcpy(hwId, (*it)->getMappedKey()->hwKeyId, HWKEY_ID_SIZE);
+ if ((*it)->getMappedInput()) {
+ hwId = (*it)->getMappedInput()->id;
}
_configDomain->setVal(prefix + actId, hwId);
}
}
-bool Keymap::isComplete(const HardwareKeySet *hwKeys) {
- List<Action*>::iterator it;
+bool Keymap::isComplete(const HardwareInputSet *hwInputs) {
+ List<Action *>::iterator it;
bool allMapped = true;
uint numberMapped = 0;
for (it = _actions.begin(); it != _actions.end(); ++it) {
- if ((*it)->getMappedKey()) {
- numberMapped++;
+ if ((*it)->getMappedInput()) {
+ ++numberMapped;
} else {
allMapped = false;
}
}
- return allMapped || (numberMapped == hwKeys->size());
-}
-
-// TODO:
-// - current weakness:
-// - if an action finds a key with required type but a parent action with
-// higher priority is using it, that key is never used
-void Keymap::automaticMapping(HardwareKeySet *hwKeys) {
- // Create copies of action and key lists.
- List<Action*> actions(_actions);
- List<const HardwareKey*> keys(hwKeys->getHardwareKeys());
-
- List<Action*>::iterator actIt;
- List<const HardwareKey*>::iterator keyIt, selectedKey;
-
- // Remove actions and keys from local lists that have already been mapped.
- actIt = actions.begin();
-
- while (actIt != actions.end()) {
- Action *act = *actIt;
- const HardwareKey *key = act->getMappedKey();
-
- if (key) {
- keys.remove(key);
- actIt = actions.erase(actIt);
- } else {
- ++actIt;
- }
- }
-
- // Sort remaining actions by priority.
- ActionPriorityComp priorityComp;
- sort(actions.begin(), actions.end(), priorityComp);
-
- // First mapping pass:
- // - Match if a key's preferred action type is the same as the action's
- // type, or vice versa.
- // - Priority is given to:
- // - keys that match action types over key types.
- // - keys that have not been used by parent maps.
- // - If a key has been used by a parent map the new action must have a
- // higher priority than the parent action.
- // - As soon as the number of skipped actions equals the number of keys
- // remaining we stop matching. This means that the second pass will assign keys
- // to these higher priority skipped actions.
- uint skipped = 0;
- actIt = actions.begin();
-
- while (actIt != actions.end() && skipped < keys.size()) {
- selectedKey = keys.end();
- int matchRank = 0;
- Action *act = *actIt;
-
- for (keyIt = keys.begin(); keyIt != keys.end(); ++keyIt) {
- if ((*keyIt)->preferredAction == act->type && act->type != kGenericActionType) {
- Action *parentAct = getParentMappedAction((*keyIt)->key);
-
- if (!parentAct) {
- selectedKey = keyIt;
- break;
- } else if (parentAct->priority <= act->priority && matchRank < 3) {
- selectedKey = keyIt;
- matchRank = 3;
- }
- } else if ((*keyIt)->type == act->preferredKey && act->preferredKey != kGenericKeyType && matchRank < 2) {
- Action *parentAct = getParentMappedAction((*keyIt)->key);
-
- if (!parentAct) {
- selectedKey = keyIt;
- matchRank = 2;
- } else if (parentAct->priority <= act->priority && matchRank < 1) {
- selectedKey = keyIt;
- matchRank = 1;
- }
- }
- }
- if (selectedKey != keys.end()) {
- // Map action and delete action & key from local lists.
- act->mapKey(*selectedKey);
- keys.erase(selectedKey);
- actIt = actions.erase(actIt);
- } else {
- // Skip action (will be mapped in next pass).
- ++actIt;
- ++skipped;
- }
- }
-
- // Second mapping pass:
- // - Maps any remaining actions to keys
- // - priority given to:
- // - keys that have no parent action
- // - keys whose parent action has lower priority than the new action
- // - keys whose parent action has the lowest priority
- // - is guaranteed to match a key if they are not all used up
- for (actIt = actions.begin(); actIt != actions.end(); ++actIt) {
- selectedKey = keys.end();
-
- int matchRank = 0;
- int lowestPriority = 0;
- Action *act = *actIt;
-
- for (keyIt = keys.begin(); keyIt != keys.end(); ++keyIt) {
- Action *parentAct = getParentMappedAction((*keyIt)->key);
-
- if (!parentAct) {
- selectedKey = keyIt;
- break;
- } else if (matchRank < 2) {
- if (parentAct->priority <= act->priority) {
- matchRank = 2;
- selectedKey = keyIt;
- } else if (parentAct->priority < lowestPriority || matchRank == 0) {
- matchRank = 1;
- lowestPriority = parentAct->priority;
- selectedKey = keyIt;
- }
- }
- }
-
- if (selectedKey != keys.end()) {
- act->mapKey(*selectedKey);
- keys.erase(selectedKey);
- } else {// no match = no keys left
- break;
- }
- }
-}
-
-Action *Keymap::getParentMappedAction(KeyState key) {
- if (_parent) {
- Action *act = _parent->getMappedAction(key);
-
- if (act)
- return act;
- else
- return _parent->getParentMappedAction(key);
- } else {
- return 0;
- }
+ return allMapped || (numberMapped == hwInputs->size());
}
} // End of namespace Common
diff --git a/backends/keymapper/keymap.h b/backends/keymapper/keymap.h
index 73f2293653..4c3e89700f 100644
--- a/backends/keymapper/keymap.h
+++ b/backends/keymapper/keymap.h
@@ -36,8 +36,8 @@
namespace Common {
-struct HardwareKey;
-class HardwareKeySet;
+struct HardwareInput;
+class HardwareInputSet;
/**
* Hash function for KeyState
@@ -52,7 +52,7 @@ template<> struct Hash<KeyState>
class Keymap {
public:
- Keymap(const String& name, Keymap *parent = 0) : _name(name), _parent(parent) {}
+ Keymap(const String& name) : _name(name) {}
Keymap(const Keymap& km);
~Keymap();
@@ -67,7 +67,7 @@ public:
/**
* Get the list of all the Actions contained in this Keymap
*/
- List<Action*>& getActions() { return _actions; }
+ List<Action *>& getActions() { return _actions; }
/**
* Find the Action that a key is mapped to
@@ -80,9 +80,9 @@ public:
/**
* Load this keymap's mappings from the config manager.
- * @param hwKeys the set to retrieve hardware key pointers from
+ * @param hwInputs the set to retrieve hardware input pointers from
*/
- void loadMappings(const HardwareKeySet *hwKeys);
+ void loadMappings(const HardwareInputSet *hwInputs);
/**
* Save this keymap's mappings to the config manager
@@ -91,17 +91,13 @@ public:
*/
void saveMappings();
-
- void automaticMapping(HardwareKeySet *hwKeys);
-
/**
* Returns true if all UserAction's in Keymap are mapped, or,
- * all HardwareKey's from the given set have been used up.
+ * all HardwareInputs from the given set have been used up.
*/
- bool isComplete(const HardwareKeySet *hwKeys);
+ bool isComplete(const HardwareInputSet *hwInputs);
const String& getName() { return _name; }
- Keymap *getParent() { return _parent; }
private:
friend struct Action;
@@ -114,15 +110,15 @@ private:
void addAction(Action *action);
/**
- * Registers a HardwareKey to the given Action
+ * Registers a HardwareInput to the given Action
* @param action Action in this Keymap
- * @param key pointer to HardwareKey to map
+ * @param key pointer to HardwareInput to map
* @see Action::mapKey
*/
- void registerMapping(Action *action, const HardwareKey *key);
+ void registerMapping(Action *action, const HardwareInput *input);
/**
- * Unregisters a HardwareKey from the given Action (if one is mapped)
+ * Unregisters a HardwareInput from the given Action (if one is mapped)
* @param action Action in this Keymap
* @see Action::mapKey
*/
@@ -131,14 +127,9 @@ private:
Action *findAction(const char *id);
const Action *findAction(const char *id) const;
- void internalMapKey(Action *action, HardwareKey *hwKey);
-
- Action *getParentMappedAction(KeyState key);
-
String _name;
- Keymap *_parent;
- List<Action*> _actions;
- HashMap<KeyState, Action*> _keymap;
+ List<Action *> _actions;
+ HashMap<KeyState, Action *> _keymap;
ConfigManager::Domain *_configDomain;
};
diff --git a/backends/keymapper/keymapper-defaults.h b/backends/keymapper/keymapper-defaults.h
new file mode 100644
index 0000000000..bd4afd4e3a
--- /dev/null
+++ b/backends/keymapper/keymapper-defaults.h
@@ -0,0 +1,56 @@
+/* ScummVM - Graphic Adventure Engine
+*
+* ScummVM is the legal property of its developers, whose names
+* are too numerous to list here. Please refer to the COPYRIGHT
+* file distributed with this source distribution.
+*
+* This program is free software; you can redistribute it and/or
+* modify it under the terms of the GNU General Public License
+* as published by the Free Software Foundation; either version 2
+* of the License, or (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+*/
+
+#ifdef ENABLE_KEYMAPPER
+
+#ifndef KEYMAPPER_DEFAULTS_H
+#define KEYMAPPER_DEFAULTS_H
+
+#include "common/scummsys.h"
+#include "common/hashmap.h"
+#include "common/str.h"
+#include "common/hash-str.h"
+
+namespace Common {
+
+class KeymapperDefaultBindings : HashMap<String, String> {
+public:
+ /**
+ * This sets a default hwInput for a given Keymap Action
+ * @param keymapId String representing Keymap id (Keymap.name)
+ * @param actionId String representing Action id (Action.id)
+ * @param hwInputId String representing the HardwareInput id (HardwareInput.id)
+ */
+ void setDefaultBinding(String keymapId, String actionId, String hwInputId) { setVal(keymapId + "_" + actionId, hwInputId); }
+ /**
+ * This retrieves the assigned default hwKey for a given Keymap Action
+ * @param keymapId String representing Keymap id (Keymap.name)
+ * @param actionId String representing Action id (Action.id)
+ * @return String representing the HardwareInput id (HardwareInput.id)
+ */
+ String getDefaultBinding(String keymapId, String actionId) { return getVal(keymapId + "_" + actionId); }
+};
+
+} //namespace Common
+
+#endif // #ifndef KEYMAPPER_DEFAULTS_H
+#endif // #ifdef ENABLE_KEYMAPPER
diff --git a/backends/keymapper/keymapper.cpp b/backends/keymapper/keymapper.cpp
index f5f29a2940..bda4cd47da 100644
--- a/backends/keymapper/keymapper.cpp
+++ b/backends/keymapper/keymapper.cpp
@@ -54,26 +54,26 @@ Keymap *Keymapper::Domain::getKeymap(const String& name) {
}
Keymapper::Keymapper(EventManager *evtMgr)
- : _eventMan(evtMgr), _enabled(true), _hardwareKeys(0) {
+ : _eventMan(evtMgr), _enabled(true), _hardwareInputs(0) {
ConfigManager::Domain *confDom = ConfMan.getDomain(ConfigManager::kKeymapperDomain);
_globalDomain.setConfigDomain(confDom);
}
Keymapper::~Keymapper() {
- delete _hardwareKeys;
+ delete _hardwareInputs;
}
-void Keymapper::registerHardwareKeySet(HardwareKeySet *keys) {
- if (_hardwareKeys)
- error("Hardware key set already registered");
+void Keymapper::registerHardwareInputSet(HardwareInputSet *inputs) {
+ if (_hardwareInputs)
+ error("Hardware input set already registered");
- if (!keys) {
- warning("No hardware keys are supplied");
- return;
+ if (!inputs) {
+ warning("No hardware input were defined, using defaults");
+ inputs = new HardwareInputSet(true);
}
- _hardwareKeys = keys;
+ _hardwareInputs = inputs;
}
void Keymapper::addGlobalKeymap(Keymap *keymap) {
@@ -95,16 +95,15 @@ void Keymapper::addGameKeymap(Keymap *keymap) {
}
void Keymapper::initKeymap(Domain &domain, Keymap *map) {
- if (!_hardwareKeys) {
- warning("No hardware keys were registered yet (%s)", map->getName().c_str());
+ if (!_hardwareInputs) {
+ warning("No hardware inputs were registered yet (%s)", map->getName().c_str());
return;
}
map->setConfigDomain(domain.getConfigDomain());
- map->loadMappings(_hardwareKeys);
+ map->loadMappings(_hardwareInputs);
- if (map->isComplete(_hardwareKeys) == false) {
- map->automaticMapping(_hardwareKeys);
+ if (map->isComplete(_hardwareInputs) == false) {
map->saveMappings();
ConfMan.flushToDisk();
}
@@ -120,7 +119,7 @@ void Keymapper::cleanupGameKeymaps() {
// the game specific (=deleted) ones.
Stack<MapRecord> newStack;
- for (int i = 0; i < _activeMaps.size(); i++) {
+ for (Stack<MapRecord>::size_type i = 0; i < _activeMaps.size(); i++) {
if (_activeMaps[i].global)
newStack.push(_activeMaps[i]);
}
@@ -128,63 +127,87 @@ void Keymapper::cleanupGameKeymaps() {
_activeMaps = newStack;
}
-Keymap *Keymapper::getKeymap(const String& name, bool &global) {
+Keymap *Keymapper::getKeymap(const String& name, bool *globalReturn) {
Keymap *keymap = _gameDomain.getKeymap(name);
- global = false;
+ bool global = false;
if (!keymap) {
keymap = _globalDomain.getKeymap(name);
global = true;
}
+ if (globalReturn)
+ *globalReturn = global;
+
return keymap;
}
-bool Keymapper::pushKeymap(const String& name, bool inherit) {
+bool Keymapper::pushKeymap(const String& name, bool transparent) {
bool global;
- Keymap *newMap = getKeymap(name, global);
+
+ assert(!name.empty());
+ Keymap *newMap = getKeymap(name, &global);
if (!newMap) {
warning("Keymap '%s' not registered", name.c_str());
return false;
}
- pushKeymap(newMap, inherit, global);
+ pushKeymap(newMap, transparent, global);
return true;
}
-void Keymapper::pushKeymap(Keymap *newMap, bool inherit, bool global) {
- MapRecord mr = {newMap, inherit, global};
+void Keymapper::pushKeymap(Keymap *newMap, bool transparent, bool global) {
+ MapRecord mr = {newMap, transparent, global};
_activeMaps.push(mr);
}
-void Keymapper::popKeymap() {
- if (!_activeMaps.empty())
- _activeMaps.pop();
+void Keymapper::popKeymap(const char *name) {
+ if (!_activeMaps.empty()) {
+ if (name) {
+ String topKeymapName = _activeMaps.top().keymap->getName();
+ if (topKeymapName.equals(name))
+ _activeMaps.pop();
+ else
+ warning("An attempt to pop wrong keymap was blocked (expected %s but was %s)", name, topKeymapName.c_str());
+ } else {
+ _activeMaps.pop();
+ }
+ }
+
}
-bool Keymapper::notifyEvent(const Common::Event &ev) {
+List<Event> Keymapper::mapEvent(const Event &ev, EventSource *source) {
+ if (source && !source->allowMapping()) {
+ return DefaultEventMapper::mapEvent(ev, source);
+ }
+
+ List<Event> mappedEvents;
+
if (ev.type == Common::EVENT_KEYDOWN)
- return mapKeyDown(ev.kbd);
+ mappedEvents = mapKeyDown(ev.kbd);
else if (ev.type == Common::EVENT_KEYUP)
- return mapKeyUp(ev.kbd);
+ mappedEvents = mapKeyUp(ev.kbd);
+
+ if (!mappedEvents.empty())
+ return mappedEvents;
else
- return false;
+ return DefaultEventMapper::mapEvent(ev, source);
}
-bool Keymapper::mapKeyDown(const KeyState& key) {
+List<Event> Keymapper::mapKeyDown(const KeyState& key) {
return mapKey(key, true);
}
-bool Keymapper::mapKeyUp(const KeyState& key) {
+List<Event> Keymapper::mapKeyUp(const KeyState& key) {
return mapKey(key, false);
}
-bool Keymapper::mapKey(const KeyState& key, bool keyDown) {
+List<Event> Keymapper::mapKey(const KeyState& key, bool keyDown) {
if (!_enabled || _activeMaps.empty())
- return false;
+ return List<Event>();
Action *action = 0;
@@ -192,17 +215,17 @@ bool Keymapper::mapKey(const KeyState& key, bool keyDown) {
// Search for key in active keymap stack
for (int i = _activeMaps.size() - 1; i >= 0; --i) {
MapRecord mr = _activeMaps[i];
-
+ debug(5, "Keymapper::mapKey keymap: %s", mr.keymap->getName().c_str());
action = mr.keymap->getMappedAction(key);
- if (action || mr.inherit == false)
+ if (action || !mr.transparent)
break;
}
if (action)
_keysDown[key] = action;
} else {
- HashMap<KeyState, Action*>::iterator it = _keysDown.find(key);
+ HashMap<KeyState, Action *>::iterator it = _keysDown.find(key);
if (it != _keysDown.end()) {
action = it->_value;
@@ -211,11 +234,9 @@ bool Keymapper::mapKey(const KeyState& key, bool keyDown) {
}
if (!action)
- return false;
-
- executeAction(action, keyDown);
+ return List<Event>();
- return true;
+ return executeAction(action, keyDown);
}
Action *Keymapper::getAction(const KeyState& key) {
@@ -224,7 +245,8 @@ Action *Keymapper::getAction(const KeyState& key) {
return action;
}
-void Keymapper::executeAction(const Action *action, bool keyDown) {
+List<Event> Keymapper::executeAction(const Action *action, bool keyDown) {
+ List<Event> mappedEvents;
List<Event>::const_iterator it;
for (it = action->events.begin(); it != action->events.end(); ++it) {
@@ -255,18 +277,22 @@ void Keymapper::executeAction(const Action *action, bool keyDown) {
case EVENT_MBUTTONUP:
if (keyDown) evt.type = EVENT_MBUTTONDOWN;
break;
+ case EVENT_MAINMENU:
+ if (!keyDown) evt.type = EVENT_MAINMENU;
+ break;
default:
// don't deliver other events on key up
if (!keyDown) continue;
}
evt.mouse = _eventMan->getMousePos();
- addEvent(evt);
+ mappedEvents.push_back(evt);
}
+ return mappedEvents;
}
-const HardwareKey *Keymapper::findHardwareKey(const KeyState& key) {
- return (_hardwareKeys) ? _hardwareKeys->findHardwareKey(key) : 0;
+const HardwareInput *Keymapper::findHardwareInput(const KeyState& key) {
+ return (_hardwareInputs) ? _hardwareInputs->findHardwareInput(key) : 0;
}
} // End of namespace Common
diff --git a/backends/keymapper/keymapper.h b/backends/keymapper/keymapper.h
index fcb444aa64..daa746f379 100644
--- a/backends/keymapper/keymapper.h
+++ b/backends/keymapper/keymapper.h
@@ -31,17 +31,20 @@
#include "common/list.h"
#include "common/hashmap.h"
#include "common/stack.h"
-#include "backends/keymapper/hardware-key.h"
+#include "backends/keymapper/hardware-input.h"
#include "backends/keymapper/keymap.h"
namespace Common {
-class Keymapper : public Common::EventMapper, private Common::ArtificialEventSource {
+const char *const kGuiKeymapName = "gui";
+const char *const kGlobalKeymapName = "global";
+
+class Keymapper : public Common::DefaultEventMapper {
public:
struct MapRecord {
Keymap* keymap;
- bool inherit;
+ bool transparent;
bool global;
};
@@ -74,18 +77,21 @@ public:
Keymapper(EventManager *eventMan);
~Keymapper();
+ // EventMapper interface
+ virtual List<Event> mapEvent(const Event &ev, EventSource *source);
+
/**
- * Registers a HardwareKeySet with the Keymapper
+ * Registers a HardwareInputSet with the Keymapper
* @note should only be called once (during backend initialisation)
*/
- void registerHardwareKeySet(HardwareKeySet *keys);
+ void registerHardwareInputSet(HardwareInputSet *inputs);
/**
- * Get a list of all registered HardwareKeys
+ * Get a list of all registered HardwareInputs
*/
- const List<const HardwareKey*> &getHardwareKeys() const {
- assert(_hardwareKeys);
- return _hardwareKeys->getHardwareKeys();
+ const List<const HardwareInput *> &getHardwareInputs() const {
+ assert(_hardwareInputs);
+ return _hardwareInputs->getHardwareInputs();
}
/**
@@ -114,26 +120,25 @@ public:
* @param name name of the keymap to return
* @param global set to true if returned keymap is global, false if game
*/
- Keymap *getKeymap(const String& name, bool &global);
+ Keymap *getKeymap(const String& name, bool *global = 0);
/**
* Push a new keymap to the top of the active stack, activating
* it for use.
- * @param name name of the keymap to push
- * @param inherit if true keymapper will iterate down the
- * stack if it cannot find a key in the new map
- * @return true if succesful
+ * @param name name of the keymap to push
+ * @param transparent if true keymapper will iterate down the
+ * stack if it cannot find a key in the new map
+ * @return true if succesful
*/
- bool pushKeymap(const String& name, bool inherit = false);
+ bool pushKeymap(const String& name, bool transparent = false);
/**
* Pop the top keymap off the active stack.
+ * @param name (optional) name of keymap expected to be popped
+ * if provided, will not pop unless name is the same
+ * as the top keymap
*/
- void popKeymap();
-
- // Implementation of the EventMapper interface
- bool notifyEvent(const Common::Event &ev);
- bool pollEvent(Common::Event &ev) { return Common::ArtificialEventSource::pollEvent(ev); }
+ void popKeymap(const char *name = 0);
/**
* @brief Map a key press event.
@@ -141,21 +146,21 @@ public:
* the Action's events are pushed into the EventManager's event queue.
* @param key key that was pressed
* @param keyDown true for key down, false for key up
- * @return true if key was mapped
+ * @return mapped events
*/
- bool mapKey(const KeyState& key, bool keyDown);
+ List<Event> mapKey(const KeyState& key, bool keyDown);
/**
* @brief Map a key down event.
* @see mapKey
*/
- bool mapKeyDown(const KeyState& key);
+ List<Event> mapKeyDown(const KeyState& key);
/**
* @brief Map a key up event.
* @see mapKey
*/
- bool mapKeyUp(const KeyState& key);
+ List<Event> mapKeyUp(const KeyState& key);
/**
* Enable/disable the keymapper
@@ -163,9 +168,9 @@ public:
void setEnabled(bool enabled) { _enabled = enabled; }
/**
- * Return a HardwareKey pointer for the given key state
+ * Return a HardwareInput pointer for the given key state
*/
- const HardwareKey *findHardwareKey(const KeyState& key);
+ const HardwareInput *findHardwareInput(const KeyState& key);
Domain& getGlobalDomain() { return _globalDomain; }
Domain& getGameDomain() { return _gameDomain; }
@@ -178,19 +183,19 @@ private:
Domain _globalDomain;
Domain _gameDomain;
- HardwareKeySet *_hardwareKeys;
+ HardwareInputSet *_hardwareInputs;
- void pushKeymap(Keymap *newMap, bool inherit, bool global);
+ void pushKeymap(Keymap *newMap, bool transparent, bool global);
Action *getAction(const KeyState& key);
- void executeAction(const Action *act, bool keyDown);
+ List<Event> executeAction(const Action *act, bool keyDown);
EventManager *_eventMan;
bool _enabled;
Stack<MapRecord> _activeMaps;
- HashMap<KeyState, Action*> _keysDown;
+ HashMap<KeyState, Action *> _keysDown;
};
diff --git a/backends/keymapper/remap-dialog.cpp b/backends/keymapper/remap-dialog.cpp
index 7f2df2f0fe..dab295219a 100644
--- a/backends/keymapper/remap-dialog.cpp
+++ b/backends/keymapper/remap-dialog.cpp
@@ -28,18 +28,18 @@
#include "gui/widgets/popup.h"
#include "gui/widgets/scrollbar.h"
#include "gui/ThemeEval.h"
-
#include "common/translation.h"
namespace Common {
enum {
kRemapCmd = 'REMP',
+ kClearCmd = 'CLER',
kCloseCmd = 'CLOS'
};
RemapDialog::RemapDialog()
- : Dialog("KeyMapper"), _keymapTable(0), _activeRemapAction(0), _topAction(0), _remapTimeout(0) {
+ : Dialog("KeyMapper"), _keymapTable(0), _activeRemapAction(0), _topAction(0), _remapTimeout(0), _topKeymapIsGui(false) {
_keymapper = g_system->getEventManager()->getKeymapper();
assert(_keymapper);
@@ -57,12 +57,13 @@ RemapDialog::~RemapDialog() {
}
void RemapDialog::open() {
- bool divider = false;
const Stack<Keymapper::MapRecord> &activeKeymaps = _keymapper->getActiveStack();
- if (!(activeKeymaps.size() > 0)) {
- _kmPopUp->appendEntry(activeKeymaps.top().keymap->getName() + _(" (Active)"));
- divider = true;
+ if (activeKeymaps.size() > 0) {
+ if (activeKeymaps.top().keymap->getName() == Common::kGuiKeymapName)
+ _topKeymapIsGui = true;
+ // Add the entry for the "effective" special view. See RemapDialog::loadKeymap()
+ _kmPopUp->appendEntry(activeKeymaps.top().keymap->getName() + _(" (Effective)"));
}
Keymapper::Domain *_globalKeymaps = &_keymapper->getGlobalDomain();
@@ -84,27 +85,45 @@ void RemapDialog::open() {
keymapCount += _gameKeymaps->size();
}
- debug(3, "keymaps: %d", keymapCount);
+ if (activeKeymaps.size() > 1) {
+ keymapCount += activeKeymaps.size() - 1;
+ }
+
+ debug(3, "RemapDialog::open keymaps: %d", keymapCount);
- _keymapTable = (Keymap **)malloc(sizeof(Keymap*) * keymapCount);
+ _keymapTable = (Keymap **)malloc(sizeof(Keymap *) * keymapCount);
Keymapper::Domain::iterator it;
uint32 idx = 0;
+ if (activeKeymaps.size() > 1) {
+ int topIndex = activeKeymaps.size() - 1;
+ bool active = activeKeymaps[topIndex].transparent;
+ for (int i = topIndex - 1; i >= 0; --i) {
+ Keymapper::MapRecord mr = activeKeymaps[i];
+ // Add an entry for each keymap in the stack after the top keymap. Mark it Active if it is
+ // reachable or Blocked if an opaque keymap is on top of it thus blocking access to it.
+ _kmPopUp->appendEntry(mr.keymap->getName() + (active ? _(" (Active)") : _(" (Blocked)")), idx);
+ _keymapTable[idx++] = mr.keymap;
+ active &= mr.transparent;
+ }
+ }
+
+ _kmPopUp->appendEntry("");
+
+ // Now add entries for all known keymaps. Note that there will be duplicates with the stack entries.
+
if (_globalKeymaps) {
- if (divider)
- _kmPopUp->appendEntry("");
for (it = _globalKeymaps->begin(); it != _globalKeymaps->end(); ++it) {
+ // "global" means its keybindings apply to all games; saved in a global conf domain
_kmPopUp->appendEntry(it->_value->getName() + _(" (Global)"), idx);
_keymapTable[idx++] = it->_value;
}
- divider = true;
}
if (_gameKeymaps) {
- if (divider)
- _kmPopUp->appendEntry("");
for (it = _gameKeymaps->begin(); it != _gameKeymaps->end(); ++it) {
+ // "game" means its keybindings are saved per-target
_kmPopUp->appendEntry(it->_value->getName() + _(" (Game)"), idx);
_keymapTable[idx++] = it->_value;
}
@@ -138,16 +157,19 @@ void RemapDialog::reflowLayout() {
int16 areaX, areaY;
uint16 areaW, areaH;
+ g_gui.xmlEval()->getWidgetData((const String&)String("KeyMapper.KeymapArea"), areaX, areaY, areaW, areaH);
+
int spacing = g_gui.xmlEval()->getVar("Globals.KeyMapper.Spacing");
- int labelWidth = g_gui.xmlEval()->getVar("Globals.KeyMapper.LabelWidth");
- int buttonWidth = g_gui.xmlEval()->getVar("Globals.KeyMapper.ButtonWidth");
- int colWidth = labelWidth + buttonWidth + spacing;
+ int keyButtonWidth = g_gui.xmlEval()->getVar("Globals.KeyMapper.ButtonWidth");
+ int clearButtonWidth = g_gui.xmlEval()->getVar("Globals.Line.Height");
+ int clearButtonHeight = g_gui.xmlEval()->getVar("Globals.Line.Height");
- g_gui.xmlEval()->getWidgetData((const String&)String("KeyMapper.KeymapArea"), areaX, areaY, areaW, areaH);
+ int colWidth = areaW - scrollbarWidth;
+ int labelWidth = colWidth - (keyButtonWidth + spacing + clearButtonWidth + spacing);
- _colCount = (areaW - scrollbarWidth) / colWidth;
_rowCount = (areaH + spacing) / (buttonHeight + spacing);
- if (_colCount <= 0 || _rowCount <= 0)
+ debug(7, "rowCount = %d" , _rowCount);
+ if (colWidth <= 0 || _rowCount <= 0)
error("Remap dialog too small to display any keymaps");
_scrollBar->resize(areaX + areaW - scrollbarWidth, areaY, scrollbarWidth, areaH);
@@ -156,8 +178,9 @@ void RemapDialog::reflowLayout() {
_scrollBar->recalc();
uint textYOff = (buttonHeight - kLineHeight) / 2;
+ uint clearButtonYOff = (buttonHeight - clearButtonHeight) / 2;
uint oldSize = _keymapWidgets.size();
- uint newSize = _rowCount * _colCount;
+ uint newSize = _rowCount;
_keymapWidgets.reserve(newSize);
@@ -166,19 +189,22 @@ void RemapDialog::reflowLayout() {
if (i >= _keymapWidgets.size()) {
widg.actionText =
- new GUI::StaticTextWidget(this, 0, 0, 0, 0, "", Graphics::kTextAlignRight);
+ new GUI::StaticTextWidget(this, 0, 0, 0, 0, "", Graphics::kTextAlignLeft);
widg.keyButton =
new GUI::ButtonWidget(this, 0, 0, 0, 0, "", 0, kRemapCmd + i);
+ widg.clearButton = addClearButton(this, "", kClearCmd + i, 0, 0, clearButtonWidth, clearButtonHeight);
_keymapWidgets.push_back(widg);
} else {
widg = _keymapWidgets[i];
}
- uint x = areaX + (i % _colCount) * colWidth;
- uint y = areaY + (i / _colCount) * (buttonHeight + spacing);
+ uint x = areaX;
+ uint y = areaY + (i) * (buttonHeight + spacing);
+
+ widg.keyButton->resize(x, y, keyButtonWidth, buttonHeight);
+ widg.clearButton->resize(x + keyButtonWidth + spacing, y + clearButtonYOff, clearButtonWidth, clearButtonHeight);
+ widg.actionText->resize(x + keyButtonWidth + spacing + clearButtonWidth + spacing, y + textYOff, labelWidth, kLineHeight);
- widg.actionText->resize(x, y + textYOff, labelWidth, kLineHeight);
- widg.keyButton->resize(x + labelWidth, y, buttonWidth, buttonHeight);
}
while (oldSize > newSize) {
ActionWidgets widg = _keymapWidgets.remove_at(--oldSize);
@@ -188,14 +214,19 @@ void RemapDialog::reflowLayout() {
removeWidget(widg.keyButton);
delete widg.keyButton;
+
+ removeWidget(widg.clearButton);
+ delete widg.clearButton;
}
}
void RemapDialog::handleCommand(GUI::CommandSender *sender, uint32 cmd, uint32 data) {
- debug(0, "Command!");
+ debug(3, "RemapDialog::handleCommand %u %u", cmd, data);
if (cmd >= kRemapCmd && cmd < kRemapCmd + _keymapWidgets.size()) {
startRemapping(cmd - kRemapCmd);
+ } else if (cmd >= kClearCmd && cmd < kClearCmd + _keymapWidgets.size()) {
+ clearMapping(cmd - kClearCmd);
} else if (cmd == GUI::kPopUpItemSelectedCmd) {
loadKeymap();
} else if (cmd == GUI::kSetPositionCmd) {
@@ -207,6 +238,23 @@ void RemapDialog::handleCommand(GUI::CommandSender *sender, uint32 cmd, uint32 d
}
}
+void RemapDialog::clearMapping(uint i) {
+ if (_topAction + i >= _currentActions.size())
+ return;
+
+ debug(3, "clear the mapping %u", i);
+ _activeRemapAction = _currentActions[_topAction + i].action;
+ _activeRemapAction->mapInput(0);
+ _activeRemapAction->getParent()->saveMappings();
+ _changes = true;
+
+ // force refresh
+ _topAction = -1;
+ refreshKeymap();
+
+ _activeRemapAction = 0;
+}
+
void RemapDialog::startRemapping(uint i) {
if (_topAction + i >= _currentActions.size())
return;
@@ -238,12 +286,12 @@ void RemapDialog::handleKeyDown(Common::KeyState state) {
void RemapDialog::handleKeyUp(Common::KeyState state) {
if (_activeRemapAction) {
- const HardwareKey *hwkey = _keymapper->findHardwareKey(state);
+ const HardwareInput *hwInput = _keymapper->findHardwareInput(state);
- debug(0, "Key: %d, %d (%c), %x", state.keycode, state.ascii, (state.ascii ? state.ascii : ' '), state.flags);
+ debug(4, "RemapDialog::handleKeyUp Key: %d, %d (%c), %x", state.keycode, state.ascii, (state.ascii ? state.ascii : ' '), state.flags);
- if (hwkey) {
- _activeRemapAction->mapKey(hwkey);
+ if (hwInput) {
+ _activeRemapAction->mapInput(hwInput);
_activeRemapAction->getParent()->saveMappings();
_changes = true;
stopRemapping();
@@ -270,52 +318,67 @@ void RemapDialog::loadKeymap() {
_currentActions.clear();
const Stack<Keymapper::MapRecord> &activeKeymaps = _keymapper->getActiveStack();
+ debug(3, "RemapDialog::loadKeymap active keymaps: %u", activeKeymaps.size());
+
if (!activeKeymaps.empty() && _kmPopUp->getSelected() == 0) {
- // load active keymaps
+ // This is the "effective" view which shows all effective actions:
+ // - all of the topmost keymap action
+ // - all mapped actions that are reachable
- List<const HardwareKey*> freeKeys(_keymapper->getHardwareKeys());
+ List<const HardwareInput *> freeInputs(_keymapper->getHardwareInputs());
- // add most active keymap's keys
- Keymapper::MapRecord top = activeKeymaps.top();
- List<Action*>::iterator actIt;
+ int topIndex = activeKeymaps.size() - 1;
+ // This is a WORKAROUND for changing the popup list selected item and changing it back
+ // to the top entry. Upon changing it back, the top keymap is always "gui".
+ if (!_topKeymapIsGui && activeKeymaps[topIndex].keymap->getName() == kGuiKeymapName)
+ --topIndex;
+
+ // add most active keymap's keys
+ Keymapper::MapRecord top = activeKeymaps[topIndex];
+ List<Action *>::iterator actIt;
+ debug(3, "RemapDialog::loadKeymap top keymap: %s", top.keymap->getName().c_str());
for (actIt = top.keymap->getActions().begin(); actIt != top.keymap->getActions().end(); ++actIt) {
Action *act = *actIt;
ActionInfo info = {act, false, act->description};
_currentActions.push_back(info);
- if (act->getMappedKey())
- freeKeys.remove(act->getMappedKey());
+ if (act->getMappedInput())
+ freeInputs.remove(act->getMappedInput());
}
// loop through remaining finding mappings for unmapped keys
- if (top.inherit) {
- for (int i = activeKeymaps.size() - 2; i >= 0; --i) {
+ if (top.transparent && topIndex >= 0) {
+ for (int i = topIndex - 1; i >= 0; --i) {
Keymapper::MapRecord mr = activeKeymaps[i];
- List<const HardwareKey*>::iterator keyIt = freeKeys.begin();
+ debug(3, "RemapDialog::loadKeymap keymap: %s", mr.keymap->getName().c_str());
+ List<const HardwareInput *>::iterator inputIt = freeInputs.begin();
+ while (inputIt != freeInputs.end()) {
- while (keyIt != freeKeys.end()) {
- Action *act = mr.keymap->getMappedAction((*keyIt)->key);
+ Action *act = mr.keymap->getMappedAction((*inputIt)->key);
if (act) {
ActionInfo info = {act, true, act->description + " (" + mr.keymap->getName() + ")"};
_currentActions.push_back(info);
- freeKeys.erase(keyIt++);
+ freeInputs.erase(inputIt);
} else {
- ++keyIt;
+ ++inputIt;
}
}
- if (mr.inherit == false || freeKeys.empty())
+ if (mr.transparent == false || freeInputs.empty())
break;
}
}
} else if (_kmPopUp->getSelected() != -1) {
+ // This is the regular view of a keymap that isn't the topmost one.
+ // It shows all of that keymap's actions
+
Keymap *km = _keymapTable[_kmPopUp->getSelectedTag()];
- List<Action*>::iterator it;
+ List<Action *>::iterator it;
for (it = km->getActions().begin(); it != km->getActions().end(); ++it) {
ActionInfo info = {*it, false, (*it)->description};
@@ -326,7 +389,7 @@ void RemapDialog::loadKeymap() {
// refresh scroll bar
_scrollBar->_currentPos = 0;
- _scrollBar->_numEntries = (_currentActions.size() + _colCount - 1) / _colCount;
+ _scrollBar->_numEntries = _currentActions.size();
_scrollBar->recalc();
// force refresh
@@ -335,7 +398,7 @@ void RemapDialog::loadKeymap() {
}
void RemapDialog::refreshKeymap() {
- int newTopAction = _scrollBar->_currentPos * _colCount;
+ int newTopAction = _scrollBar->_currentPos;
if (newTopAction == _topAction)
return;
@@ -351,25 +414,28 @@ void RemapDialog::refreshKeymap() {
ActionWidgets& widg = _keymapWidgets[widgetI];
if (actionI < _currentActions.size()) {
+ debug(8, "RemapDialog::refreshKeymap actionI=%u", actionI);
ActionInfo& info = _currentActions[actionI];
- widg.actionText->setLabel(info.description + ": ");
+ widg.actionText->setLabel(info.description);
widg.actionText->setEnabled(!info.inherited);
- const HardwareKey *mappedKey = info.action->getMappedKey();
+ const HardwareInput *mappedInput = info.action->getMappedInput();
- if (mappedKey)
- widg.keyButton->setLabel(mappedKey->description);
+ if (mappedInput)
+ widg.keyButton->setLabel(mappedInput->description);
else
widg.keyButton->setLabel("-");
widg.actionText->setVisible(true);
widg.keyButton->setVisible(true);
+ widg.clearButton->setVisible(true);
actionI++;
} else {
widg.actionText->setVisible(false);
widg.keyButton->setVisible(false);
+ widg.clearButton->setVisible(false);
}
//widg.actionText->draw();
//widg.keyButton->draw();
diff --git a/backends/keymapper/remap-dialog.h b/backends/keymapper/remap-dialog.h
index f587ae515d..143deca4cf 100644
--- a/backends/keymapper/remap-dialog.h
+++ b/backends/keymapper/remap-dialog.h
@@ -55,6 +55,7 @@ protected:
struct ActionWidgets {
GUI::StaticTextWidget *actionText;
GUI::ButtonWidget *keyButton;
+ GUI::ButtonWidget *clearButton;
};
struct ActionInfo {
Action *action;
@@ -64,6 +65,7 @@ protected:
void loadKeymap();
void refreshKeymap();
+ void clearMapping(uint i);
void startRemapping(uint i);
void stopRemapping();
@@ -80,7 +82,7 @@ protected:
//GUI::ContainerWidget *_container;
GUI::ScrollBarWidget *_scrollBar;
- uint _colCount, _rowCount;
+ uint _rowCount;
Array<ActionWidgets> _keymapWidgets;
Action *_activeRemapAction;
@@ -89,6 +91,8 @@ protected:
bool _changes;
+ bool _topKeymapIsGui;
+
};
} // End of namespace Common
diff --git a/backends/keymapper/types.h b/backends/keymapper/types.h
deleted file mode 100644
index ed2e498bd0..0000000000
--- a/backends/keymapper/types.h
+++ /dev/null
@@ -1,74 +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 KEYMAPPER_TYPES_H
-#define KEYMAPPER_TYPES_H
-
-#include "common/scummsys.h"
-
-#ifdef ENABLE_KEYMAPPER
-
-namespace Common {
-
-enum KeyType {
- kGenericKeyType,
- kDirUpKeyType,
- kDirDownKeyType,
- kDirLeftKeyType,
- kDirRightKeyType,
- kActionKeyType,
- kTriggerLeftKeyType,
- kTriggerRightKeyType,
- kStartKeyType,
- kSelectKeyType,
- /* ... */
-
- kKeyTypeMax
-};
-
-enum ActionType {
- kGenericActionType,
-
- // common actions
- kDirUpActionType,
- kDirDownActionType,
- kDirLeftActionType,
- kDirRightActionType,
- kLeftClickActionType,
- kRightClickActionType,
- kSaveActionType,
- kMenuActionType,
- kQuitActionType,
- kVirtualKeyboardActionType,
- kKeyRemapActionType,
- kVolumeUpActionType,
- kVolumeDownActionType,
-
-
- kActionTypeMax
-};
-
-} // End of namespace Common
-
-#endif // #ifdef ENABLE_KEYMAPPER
-
-#endif // #ifndef KEYMAPPER_TYPES_H
diff --git a/backends/midi/coreaudio.cpp b/backends/midi/coreaudio.cpp
index 305b462836..43c801287d 100644
--- a/backends/midi/coreaudio.cpp
+++ b/backends/midi/coreaudio.cpp
@@ -26,15 +26,38 @@
#ifdef MACOSX
-// HACK to disable deprecated warnings under Mac OS X 10.5.
-// Apple depracted the AUGraphNewNode & AUGraphGetNodeInfo APIs
-// in favor of the new AUGraphAddNode & AUGraphNodeInfo APIs.
-// While it would be trivial to switch to those, this would break
-// binary compatibility with all pre-10.5 systems, so we don't want
-// to do that just now. Maybe when 10.6 comes... :)
#include <AvailabilityMacros.h>
-#undef DEPRECATED_ATTRIBUTE
-#define DEPRECATED_ATTRIBUTE
+
+// With the release of Mac OS X 10.5 in October 2007, Apple deprecated the
+// AUGraphNewNode & AUGraphGetNodeInfo APIs in favor of the new AUGraphAddNode &
+// AUGraphNodeInfo APIs. While it is easy to switch to those, it breaks
+// compatibility with all pre-10.5 systems.
+//
+// Since 10.5 was the last system to support PowerPC, we use the old, deprecated
+// APIs on PowerPC based systems by default. On all other systems (such as Mac
+// OS X running on Intel hardware, or iOS running on ARM), we use the new API by
+// default.
+//
+// This leaves Mac OS X 10.4 running on x86 processors as the only system
+// combination that this code will not support by default. It seems quite
+// reasonable to assume that anybody with an Intel system has since then moved
+// on to a newer Mac OS X release. But if for some reason you absolutely need to
+// build an x86 version of this code using the old, deprecated API, you can
+// simply do so by manually enable the USE_DEPRECATED_COREAUDIO_API switch (e.g.
+// by adding setting it suitably in CPPFLAGS).
+#if !defined(USE_DEPRECATED_COREAUDIO_API)
+ #if TARGET_CPU_PPC || TARGET_CPU_PPC64 || !defined(MAC_OS_X_VERSION_10_6)
+ #define USE_DEPRECATED_COREAUDIO_API 1
+ #else
+ #define USE_DEPRECATED_COREAUDIO_API 0
+ #endif
+#endif
+
+#if USE_DEPRECATED_COREAUDIO_API
+ // Try to silence warnings about use of deprecated APIs
+ #undef DEPRECATED_ATTRIBUTE
+ #define DEPRECATED_ATTRIBUTE
+#endif
#include "common/config-manager.h"
@@ -105,7 +128,11 @@ int MidiDriver_CORE::open() {
RequireNoErr(NewAUGraph(&_auGraph));
AUNode outputNode, synthNode;
+#if USE_DEPRECATED_COREAUDIO_API
ComponentDescription desc;
+#else
+ AudioComponentDescription desc;
+#endif
// The default output device
desc.componentType = kAudioUnitType_Output;
@@ -113,13 +140,21 @@ int MidiDriver_CORE::open() {
desc.componentManufacturer = kAudioUnitManufacturer_Apple;
desc.componentFlags = 0;
desc.componentFlagsMask = 0;
+#if USE_DEPRECATED_COREAUDIO_API
RequireNoErr(AUGraphNewNode(_auGraph, &desc, 0, NULL, &outputNode));
+#else
+ RequireNoErr(AUGraphAddNode(_auGraph, &desc, &outputNode));
+#endif
// The built-in default (softsynth) music device
desc.componentType = kAudioUnitType_MusicDevice;
desc.componentSubType = kAudioUnitSubType_DLSSynth;
desc.componentManufacturer = kAudioUnitManufacturer_Apple;
+#if USE_DEPRECATED_COREAUDIO_API
RequireNoErr(AUGraphNewNode(_auGraph, &desc, 0, NULL, &synthNode));
+#else
+ RequireNoErr(AUGraphAddNode(_auGraph, &desc, &synthNode));
+#endif
// Connect the softsynth to the default output
RequireNoErr(AUGraphConnectNodeInput(_auGraph, synthNode, 0, outputNode, 0));
@@ -129,8 +164,11 @@ int MidiDriver_CORE::open() {
RequireNoErr(AUGraphInitialize(_auGraph));
// Get the music device from the graph.
+#if USE_DEPRECATED_COREAUDIO_API
RequireNoErr(AUGraphGetNodeInfo(_auGraph, synthNode, NULL, NULL, NULL, &_synth));
-
+#else
+ RequireNoErr(AUGraphNodeInfo(_auGraph, synthNode, NULL, &_synth));
+#endif
// Load custom soundfont, if specified
if (ConfMan.hasKey("soundfont")) {
diff --git a/backends/midi/timidity.cpp b/backends/midi/timidity.cpp
index 87cd08659c..172d31e799 100644
--- a/backends/midi/timidity.cpp
+++ b/backends/midi/timidity.cpp
@@ -197,6 +197,8 @@ int MidiDriver_TIMIDITY::open() {
/* should read something like "200 63017 is ready acceptable",
* where 63017 is port for data connection */
+ // FIXME: The following looks like a cheap endian test. If this is true, then
+ // it should be replaced by suitable #ifdef SCUMM_LITTLE_ENDIAN.
i = 1;
if (*(char *)&i == 1)
res = timidity_ctl_command("OPEN lsb");
diff --git a/backends/midi/windows.cpp b/backends/midi/windows.cpp
index 828411cd22..f4c5431d6e 100644
--- a/backends/midi/windows.cpp
+++ b/backends/midi/windows.cpp
@@ -177,13 +177,49 @@ MusicDevices WindowsMusicPlugin::getDevices() const {
int numDevs = midiOutGetNumDevs();
MIDIOUTCAPS tmp;
+ Common::StringArray deviceNames;
for (int i = 0; i < numDevs; i++) {
if (midiOutGetDevCaps(i, &tmp, sizeof(MIDIOUTCAPS)) != MMSYSERR_NOERROR)
break;
+ deviceNames.push_back(tmp.szPname);
+ }
+
+ // Check for non-unique device names. This may happen if someone has devices with identical
+ // names (e. g. more than one USB device of the exact same hardware type). It seems that this
+ // does happen in reality sometimes. We generate index numbers for these devices.
+ // This is not an ideal solution, since this index could change whenever another USB
+ // device gets plugged in or removed, switched off or just plugged into a different port.
+ // Unfortunately midiOutGetDevCaps() does not generate any other unique information
+ // that could be used. Our index numbers which match the device order should at least be
+ // a little more stable than just using the midiOutGetDevCaps() device ID, since a missing
+ // device (e.g. switched off) should actually not be harmful to our indices (as it would be
+ // when using the device IDs). The cases where users have devices with identical names should
+ // be rare enough anyway.
+ Common::Array<int> nonUniqueIndex;
+ for (int i = 0; i < numDevs; i++) {
+ int match = -1;
+ for (int ii = 0; ii < i; ii++) {
+ if (deviceNames[i] == deviceNames[ii]) {
+ if (nonUniqueIndex[ii] == -1)
+ nonUniqueIndex[ii] = 0;
+ if (++match == 0)
+ ++match;
+ }
+ }
+ nonUniqueIndex.push_back(match);
+ }
+
+ // We now add the index number to the non-unique device names to make them unique.
+ for (int i = 0; i < numDevs; i++) {
+ if (nonUniqueIndex[i] != -1)
+ deviceNames[i] = Common::String::format("%s - #%.02d", deviceNames[i].c_str(), nonUniqueIndex[i]);
+ }
+
+ for (Common::StringArray::iterator i = deviceNames.begin(); i != deviceNames.end(); ++i)
// There is no way to detect the "MusicType" so I just set it to MT_GM
// The user will have to manually select his MT32 type device and his GM type device.
- devices.push_back(MusicDevice(this, tmp.szPname, MT_GM));
- }
+ devices.push_back(MusicDevice(this, *i, MT_GM));
+
return devices;
}
diff --git a/backends/modular-backend.h b/backends/modular-backend.h
index b864da0df5..072ee805b6 100644
--- a/backends/modular-backend.h
+++ b/backends/modular-backend.h
@@ -105,13 +105,6 @@ public:
//@}
- /** @name Events and Time */
- //@{
-
- virtual Common::HardwareKeySet *getHardwareKeySet() { return 0; }
-
- //@}
-
/** @name Mutex handling */
//@{
diff --git a/backends/module.mk b/backends/module.mk
index 89cde44536..95725d9d87 100644
--- a/backends/module.mk
+++ b/backends/module.mk
@@ -33,6 +33,7 @@ endif
ifdef ENABLE_KEYMAPPER
MODULE_OBJS += \
keymapper/action.o \
+ keymapper/hardware-input.o \
keymapper/keymap.o \
keymapper/keymapper.o \
keymapper/remap-dialog.o
@@ -98,6 +99,7 @@ MODULE_OBJS += \
fs/windows/windows-fs-factory.o \
midi/windows.o \
plugins/win32/win32-provider.o \
+ saves/windows/windows-saves.o \
taskbar/win32/win32-taskbar.o
endif
@@ -149,7 +151,8 @@ endif
ifeq ($(BACKEND),maemo)
MODULE_OBJS += \
- events/maemosdl/maemosdl-events.o
+ events/maemosdl/maemosdl-events.o \
+ graphics/maemosdl/maemosdl-graphics.o
endif
ifeq ($(BACKEND),n64)
diff --git a/backends/mutex/null/null-mutex.h b/backends/mutex/null/null-mutex.h
index fdb32b241c..7ae10cedb8 100644
--- a/backends/mutex/null/null-mutex.h
+++ b/backends/mutex/null/null-mutex.h
@@ -28,7 +28,7 @@
/**
* Null mutex manager
*/
-class NullMutexManager : MutexManager {
+class NullMutexManager : public MutexManager {
public:
virtual OSystem::MutexRef createMutex() { return OSystem::MutexRef(); }
virtual void lockMutex(OSystem::MutexRef mutex) {}
diff --git a/backends/platform/android/android.cpp b/backends/platform/android/android.cpp
index aba31320ea..902599d50f 100644
--- a/backends/platform/android/android.cpp
+++ b/backends/platform/android/android.cpp
@@ -134,6 +134,7 @@ OSystem_Android::OSystem_Android(int audio_sample_rate, int audio_buffer_size) :
_enable_zoning(false),
_mixer(0),
_shake_offset(0),
+ _queuedEventTime(0),
_event_queue_lock(createMutex()),
_touch_pt_down(),
_touch_pt_scroll(),
diff --git a/backends/platform/android/android.h b/backends/platform/android/android.h
index f39a8f1144..47a6515a2a 100644
--- a/backends/platform/android/android.h
+++ b/backends/platform/android/android.h
@@ -220,6 +220,8 @@ public:
private:
Common::Queue<Common::Event> _event_queue;
+ Common::Event _queuedEvent;
+ uint32 _queuedEventTime;
MutexRef _event_queue_lock;
Common::Point _touch_pt_down, _touch_pt_scroll, _touch_pt_dt;
diff --git a/backends/platform/android/android.mk b/backends/platform/android/android.mk
index 63d194fdc1..2e8fd62152 100644
--- a/backends/platform/android/android.mk
+++ b/backends/platform/android/android.mk
@@ -63,7 +63,7 @@ PATH_BUILD_CLASSES_PLUGIN_TOP = $(PATH_BUILD)/classes.plugin
PATH_STAGE_PREFIX = build.stage
PATH_STAGE_MAIN = $(PATH_STAGE_PREFIX).main
-PATH_REL = org/inodes/gus/scummvm
+PATH_REL = org/scummvm/scummvm
PATH_SRC_TOP = $(srcdir)/backends/platform/android
PATH_SRC = $(PATH_SRC_TOP)/$(PATH_REL)
@@ -172,13 +172,13 @@ androidrelease: $(addprefix release/, $(APK_MAIN) $(APK_PLUGINS))
androidtestmain: $(APK_MAIN)
$(ADB) install -r $(APK_MAIN)
- $(ADB) shell am start -a android.intent.action.MAIN -c android.intent.category.LAUNCHER -n org.inodes.gus.scummvm/.Unpacker
+ $(ADB) shell am start -a android.intent.action.MAIN -c android.intent.category.LAUNCHER -n org.scummvm.scummvm/.Unpacker
androidtest: $(APK_MAIN) $(APK_PLUGINS)
@set -e; for apk in $^; do \
$(ADB) install -r $$apk; \
done
- $(ADB) shell am start -a android.intent.action.MAIN -c android.intent.category.LAUNCHER -n org.inodes.gus.scummvm/.Unpacker
+ $(ADB) shell am start -a android.intent.action.MAIN -c android.intent.category.LAUNCHER -n org.scummvm.scummvm/.Unpacker
# used by buildbot!
androiddistdebug: all
diff --git a/backends/platform/android/asset-archive.cpp b/backends/platform/android/asset-archive.cpp
index fe52a3d8d4..14840de996 100644
--- a/backends/platform/android/asset-archive.cpp
+++ b/backends/platform/android/asset-archive.cpp
@@ -103,7 +103,7 @@ JavaInputStream::JavaInputStream(JNIEnv *env, jobject is) :
MID_mark = env->GetMethodID(cls, "mark", "(I)V");
assert(MID_mark);
MID_available = env->GetMethodID(cls, "available", "()I");
- assert(MID_mark);
+ assert(MID_available);
MID_close = env->GetMethodID(cls, "close", "()V");
assert(MID_close);
MID_read = env->GetMethodID(cls, "read", "([BII)I");
@@ -389,7 +389,7 @@ AndroidAssetArchive::~AndroidAssetArchive() {
env->DeleteGlobalRef(_am);
}
-bool AndroidAssetArchive::hasFile(const Common::String &name) {
+bool AndroidAssetArchive::hasFile(const Common::String &name) const {
JNIEnv *env = JNI::getEnv();
jstring path = env->NewStringUTF(name.c_str());
jobject result = env->CallObjectMethod(_am, MID_open, path, ACCESS_UNKNOWN);
@@ -409,7 +409,7 @@ bool AndroidAssetArchive::hasFile(const Common::String &name) {
return true;
}
-int AndroidAssetArchive::listMembers(Common::ArchiveMemberList &member_list) {
+int AndroidAssetArchive::listMembers(Common::ArchiveMemberList &member_list) const {
JNIEnv *env = JNI::getEnv();
Common::List<Common::String> dirlist;
dirlist.push_back("");
@@ -466,7 +466,7 @@ int AndroidAssetArchive::listMembers(Common::ArchiveMemberList &member_list) {
return count;
}
-Common::ArchiveMemberPtr AndroidAssetArchive::getMember(const Common::String &name) {
+const Common::ArchiveMemberPtr AndroidAssetArchive::getMember(const Common::String &name) const {
return Common::ArchiveMemberPtr(new Common::GenericArchiveMember(name, this));
}
diff --git a/backends/platform/android/asset-archive.h b/backends/platform/android/asset-archive.h
index 9216412e0a..c5e43555e0 100644
--- a/backends/platform/android/asset-archive.h
+++ b/backends/platform/android/asset-archive.h
@@ -37,9 +37,9 @@ public:
AndroidAssetArchive(jobject am);
virtual ~AndroidAssetArchive();
- virtual bool hasFile(const Common::String &name);
- virtual int listMembers(Common::ArchiveMemberList &list);
- virtual Common::ArchiveMemberPtr getMember(const Common::String &name);
+ virtual bool hasFile(const Common::String &name) const;
+ virtual int listMembers(Common::ArchiveMemberList &list) const;
+ virtual const Common::ArchiveMemberPtr getMember(const Common::String &name) const;
virtual Common::SeekableReadStream *createReadStreamForMember(const Common::String &name) const;
private:
diff --git a/backends/platform/android/events.cpp b/backends/platform/android/events.cpp
index 2a16e69411..21d2344fa7 100644
--- a/backends/platform/android/events.cpp
+++ b/backends/platform/android/events.cpp
@@ -211,36 +211,35 @@ static const Common::KeyCode jkeymap[] = {
};
// floating point. use sparingly
-template <class T>
+template<class T>
static inline T scalef(T in, float numerator, float denominator) {
return static_cast<float>(in) * numerator / denominator;
}
+static const int kQueuedInputEventDelay = 50;
+
void OSystem_Android::setupKeymapper() {
#ifdef ENABLE_KEYMAPPER
using namespace Common;
Keymapper *mapper = getEventManager()->getKeymapper();
- HardwareKeySet *keySet = new HardwareKeySet();
+ HardwareInputSet *inputSet = new HardwareInputSet();
- keySet->addHardwareKey(
- new HardwareKey("n", KeyState(KEYCODE_n), "n (vk)",
- kTriggerLeftKeyType,
- kVirtualKeyboardActionType));
+ keySet->addHardwareInput(
+ new HardwareInput("n", KeyState(KEYCODE_n), "n (vk)"));
- mapper->registerHardwareKeySet(keySet);
+ mapper->registerHardwareInputSet(inputSet);
- Keymap *globalMap = new Keymap("global");
+ Keymap *globalMap = new Keymap(kGlobalKeymapName);
Action *act;
- act = new Action(globalMap, "VIRT", "Display keyboard",
- kVirtualKeyboardActionType);
+ act = new Action(globalMap, "VIRT", "Display keyboard");
act->addKeyEvent(KeyState(KEYCODE_F7, ASCII_F7, 0));
mapper->addGlobalKeymap(globalMap);
- mapper->pushKeymap("global");
+ mapper->pushKeymap(kGlobalKeymapName);
#endif
}
@@ -601,13 +600,18 @@ void OSystem_Android::pushEvent(int type, int arg1, int arg2, int arg3,
lockMutex(_event_queue_lock);
+ if (_queuedEventTime)
+ _event_queue.push(_queuedEvent);
+
if (!_touchpad_mode)
_event_queue.push(e);
e.type = down;
_event_queue.push(e);
+
e.type = up;
- _event_queue.push(e);
+ _queuedEvent = e;
+ _queuedEventTime = getMillis() + kQueuedInputEventDelay;
unlockMutex(_event_queue_lock);
}
@@ -702,9 +706,14 @@ void OSystem_Android::pushEvent(int type, int arg1, int arg2, int arg3,
lockMutex(_event_queue_lock);
+ if (_queuedEventTime)
+ _event_queue.push(_queuedEvent);
+
_event_queue.push(e);
+
e.type = up;
- _event_queue.push(e);
+ _queuedEvent = e;
+ _queuedEventTime = getMillis() + kQueuedInputEventDelay;
unlockMutex(_event_queue_lock);
return;
@@ -800,6 +809,13 @@ bool OSystem_Android::pollEvent(Common::Event &event) {
lockMutex(_event_queue_lock);
+ if (_queuedEventTime && (getMillis() > _queuedEventTime)) {
+ event = _queuedEvent;
+ _queuedEventTime = 0;
+ unlockMutex(_event_queue_lock);
+ return true;
+ }
+
if (_event_queue.empty()) {
unlockMutex(_event_queue_lock);
return false;
diff --git a/backends/platform/android/jni.cpp b/backends/platform/android/jni.cpp
index b44a585528..a7ebb87651 100644
--- a/backends/platform/android/jni.cpp
+++ b/backends/platform/android/jni.cpp
@@ -125,7 +125,7 @@ jint JNI::onLoad(JavaVM *vm) {
if (_vm->GetEnv((void **)&env, JNI_VERSION_1_2))
return JNI_ERR;
- jclass cls = env->FindClass("org/inodes/gus/scummvm/ScummVM");
+ jclass cls = env->FindClass("org/scummvm/scummvm/ScummVM");
if (cls == 0)
return JNI_ERR;
diff --git a/backends/platform/android/org/inodes/gus/scummvm/EditableSurfaceView.java b/backends/platform/android/org/scummvm/scummvm/EditableSurfaceView.java
index 3aef14b851..b593fc6abf 100644
--- a/backends/platform/android/org/inodes/gus/scummvm/EditableSurfaceView.java
+++ b/backends/platform/android/org/scummvm/scummvm/EditableSurfaceView.java
@@ -1,4 +1,4 @@
-package org.inodes.gus.scummvm;
+package org.scummvm.scummvm;
import android.content.Context;
import android.text.InputType;
diff --git a/backends/platform/android/org/inodes/gus/scummvm/PluginProvider.java b/backends/platform/android/org/scummvm/scummvm/PluginProvider.java
index d90b7b2c68..e27e8d41a8 100644
--- a/backends/platform/android/org/inodes/gus/scummvm/PluginProvider.java
+++ b/backends/platform/android/org/scummvm/scummvm/PluginProvider.java
@@ -1,10 +1,11 @@
-package org.inodes.gus.scummvm;
+package org.scummvm.scummvm;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ActivityInfo;
+import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Bundle;
@@ -16,7 +17,7 @@ public class PluginProvider extends BroadcastReceiver {
private final static String LOG_TAG = "ScummVM";
public final static String META_UNPACK_LIB =
- "org.inodes.gus.scummvm.meta.UNPACK_LIB";
+ "org.scummvm.scummvm.meta.UNPACK_LIB";
public void onReceive(Context context, Intent intent) {
if (!intent.getAction().equals(ScummVMApplication.ACTION_PLUGIN_QUERY))
@@ -25,15 +26,24 @@ public class PluginProvider extends BroadcastReceiver {
Bundle extras = getResultExtras(true);
final ActivityInfo info;
+ final PackageInfo pinfo;
try {
info = context.getPackageManager()
.getReceiverInfo(new ComponentName(context, this.getClass()),
PackageManager.GET_META_DATA);
+ pinfo = context.getPackageManager()
+ .getPackageInfo(context.getPackageName(), 0);
} catch (PackageManager.NameNotFoundException e) {
Log.e(LOG_TAG, "Error finding my own info?", e);
return;
}
+ String host_version = extras.getString(ScummVMApplication.EXTRA_VERSION);
+ if (!pinfo.versionName.equals(host_version)) {
+ Log.e(LOG_TAG, "Plugin version " + pinfo.versionName + " is not equal to ScummVM version " + host_version);
+ return;
+ }
+
String mylib = info.metaData.getString(META_UNPACK_LIB);
if (mylib != null) {
ArrayList<String> all_libs =
diff --git a/backends/platform/android/org/inodes/gus/scummvm/ScummVM.java b/backends/platform/android/org/scummvm/scummvm/ScummVM.java
index 246a02c9be..3a25b54eeb 100644
--- a/backends/platform/android/org/inodes/gus/scummvm/ScummVM.java
+++ b/backends/platform/android/org/scummvm/scummvm/ScummVM.java
@@ -1,4 +1,4 @@
-package org.inodes.gus.scummvm;
+package org.scummvm.scummvm;
import android.util.Log;
import android.content.res.AssetManager;
diff --git a/backends/platform/android/org/inodes/gus/scummvm/ScummVMActivity.java b/backends/platform/android/org/scummvm/scummvm/ScummVMActivity.java
index ce4e016322..fbd6513761 100644
--- a/backends/platform/android/org/inodes/gus/scummvm/ScummVMActivity.java
+++ b/backends/platform/android/org/scummvm/scummvm/ScummVMActivity.java
@@ -1,4 +1,4 @@
-package org.inodes.gus.scummvm;
+package org.scummvm.scummvm;
import android.app.Activity;
import android.app.AlertDialog;
@@ -14,6 +14,8 @@ import android.view.MotionEvent;
import android.view.inputmethod.InputMethodManager;
import android.widget.Toast;
+import java.io.File;
+
public class ScummVMActivity extends Activity {
private class MyScummVM extends ScummVM {
@@ -128,6 +130,16 @@ public class ScummVMActivity extends Activity {
getFilesDir().mkdirs();
+ // Store savegames on external storage if we can, which means they're
+ // world-readable and don't get deleted on uninstall.
+ String savePath = Environment.getExternalStorageDirectory() + "/ScummVM/Saves/";
+ File saveDir = new File(savePath);
+ saveDir.mkdirs();
+ if (!saveDir.isDirectory()) {
+ // If it doesn't work, resort to the internal app path.
+ savePath = getDir("saves", MODE_WORLD_READABLE).getPath();
+ }
+
// Start ScummVM
_scummvm = new MyScummVM(main_surface.getHolder());
@@ -136,7 +148,7 @@ public class ScummVMActivity extends Activity {
"--config=" + getFileStreamPath("scummvmrc").getPath(),
"--path=" + Environment.getExternalStorageDirectory().getPath(),
"--gui-theme=scummmodern",
- "--savepath=" + getDir("saves", 0).getPath()
+ "--savepath=" + savePath
});
_events = new ScummVMEvents(this, _scummvm);
diff --git a/backends/platform/android/org/inodes/gus/scummvm/ScummVMApplication.java b/backends/platform/android/org/scummvm/scummvm/ScummVMApplication.java
index 8ab7d1a084..0adc166222 100644
--- a/backends/platform/android/org/inodes/gus/scummvm/ScummVMApplication.java
+++ b/backends/platform/android/org/scummvm/scummvm/ScummVMApplication.java
@@ -1,12 +1,13 @@
-package org.inodes.gus.scummvm;
+package org.scummvm.scummvm;
import android.app.Application;
import java.io.File;
public class ScummVMApplication extends Application {
- public final static String ACTION_PLUGIN_QUERY = "org.inodes.gus.scummvm.action.PLUGIN_QUERY";
- public final static String EXTRA_UNPACK_LIBS = "org.inodes.gus.scummvm.extra.UNPACK_LIBS";
+ public final static String ACTION_PLUGIN_QUERY = "org.scummvm.scummvm.action.PLUGIN_QUERY";
+ public final static String EXTRA_UNPACK_LIBS = "org.scummvm.scummvm.extra.UNPACK_LIBS";
+ public final static String EXTRA_VERSION = "org.scummvm.scummvm.extra.VERSION";
private static File _cache_dir;
diff --git a/backends/platform/android/org/inodes/gus/scummvm/ScummVMEvents.java b/backends/platform/android/org/scummvm/scummvm/ScummVMEvents.java
index 175ff0b677..86227b9352 100644
--- a/backends/platform/android/org/inodes/gus/scummvm/ScummVMEvents.java
+++ b/backends/platform/android/org/scummvm/scummvm/ScummVMEvents.java
@@ -1,4 +1,4 @@
-package org.inodes.gus.scummvm;
+package org.scummvm.scummvm;
import android.os.Handler;
import android.os.Message;
diff --git a/backends/platform/android/org/inodes/gus/scummvm/Unpacker.java b/backends/platform/android/org/scummvm/scummvm/Unpacker.java
index 6cc7f8eadb..da76ceb5e5 100644
--- a/backends/platform/android/org/inodes/gus/scummvm/Unpacker.java
+++ b/backends/platform/android/org/scummvm/scummvm/Unpacker.java
@@ -1,4 +1,4 @@
-package org.inodes.gus.scummvm;
+package org.scummvm.scummvm;
import android.app.Activity;
import android.app.AlertDialog;
@@ -10,6 +10,7 @@ import android.content.ContextWrapper;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.ActivityInfo;
+import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.net.Uri;
@@ -38,7 +39,7 @@ public class Unpacker extends Activity {
// TODO don't hardcode this
private final static boolean PLUGINS_ENABLED = false;
private final static String META_NEXT_ACTIVITY =
- "org.inodes.gus.unpacker.nextActivity";
+ "org.scummvm.unpacker.nextActivity";
private ProgressBar mProgress;
private File mUnpackDest; // location to unpack into
private AsyncTask<String, Integer, Void> mUnpacker;
@@ -275,6 +276,15 @@ public class Unpacker extends Activity {
extras.putStringArrayList(ScummVMApplication.EXTRA_UNPACK_LIBS,
unpack_libs);
+ final PackageInfo info;
+ try {
+ info = getPackageManager().getPackageInfo(getPackageName(), 0);
+ } catch (PackageManager.NameNotFoundException e) {
+ Log.e(LOG_TAG, "Error finding my own info?", e);
+ return;
+ }
+ extras.putString(ScummVMApplication.EXTRA_VERSION, info.versionName);
+
Intent intent = new Intent(ScummVMApplication.ACTION_PLUGIN_QUERY);
// Android 3.1 defaults to FLAG_EXCLUDE_STOPPED_PACKAGES, and since
// none of our plugins will ever be running, that is not helpful
diff --git a/backends/platform/android/texture.cpp b/backends/platform/android/texture.cpp
index 53b4d1cc59..95c96e0d25 100644
--- a/backends/platform/android/texture.cpp
+++ b/backends/platform/android/texture.cpp
@@ -61,7 +61,7 @@ static inline GLfixed xdiv(int numerator, int denominator) {
return (numerator << 16) / denominator;
}
-template <class T>
+template<class T>
static T nextHigher2(T k) {
if (k == 0)
return 1;
@@ -287,7 +287,7 @@ void GLESTexture::fillBuffer(uint32 color) {
((color & 0xff) == ((color >> 8) & 0xff)))
memset(_pixels, color & 0xff, _surface.pitch * _surface.h);
else
- Common::set_to(_pixels, _pixels + _surface.pitch * _surface.h,
+ Common::fill(_pixels, _pixels + _surface.pitch * _surface.h,
(uint16)color);
setDirty();
diff --git a/backends/platform/bada/application.cpp b/backends/platform/bada/application.cpp
index bf585d2782..ba8e544983 100644
--- a/backends/platform/bada/application.cpp
+++ b/backends/platform/bada/application.cpp
@@ -68,7 +68,7 @@ void BadaScummVM::OnUserEventReceivedN(RequestId requestId,
// assertion failure termination
String *message = NULL;
if (args) {
- message = (String*)args->GetAt(0);
+ message = (String *)args->GetAt(0);
}
if (!message) {
message = new String("Unknown error");
diff --git a/backends/platform/bada/audio.cpp b/backends/platform/bada/audio.cpp
index b868e91357..65a5a80fa5 100644
--- a/backends/platform/bada/audio.cpp
+++ b/backends/platform/bada/audio.cpp
@@ -238,7 +238,7 @@ void AudioThread::OnAudioOutBufferEndReached(Osp::Media::AudioOut &src) {
void AudioThread::OnTimerExpired(Timer &timer) {
if (_ready < NUM_AUDIO_BUFFERS) {
uint len = _audioBuffer[_head].GetCapacity();
- int samples = _mixer->mixCallback((byte*)_audioBuffer[_head].GetPointer(), len);
+ int samples = _mixer->mixCallback((byte *)_audioBuffer[_head].GetPointer(), len);
if (samples) {
_head = (_head + 1) % NUM_AUDIO_BUFFERS;
_ready++;
diff --git a/backends/platform/bada/fs.cpp b/backends/platform/bada/fs.cpp
index 0ae0cde43d..37ca496d18 100644
--- a/backends/platform/bada/fs.cpp
+++ b/backends/platform/bada/fs.cpp
@@ -170,17 +170,17 @@ uint32 BadaFileStream::read(void *ptr, uint32 len) {
uint32 available = bufferLength - bufferIndex;
if (len <= available) {
// use allocation
- memcpy((byte*)ptr, &buffer[bufferIndex], len);
+ memcpy((byte *)ptr, &buffer[bufferIndex], len);
bufferIndex += len;
result = len;
} else {
// use remaining allocation
- memcpy((byte*)ptr, &buffer[bufferIndex], available);
+ memcpy((byte *)ptr, &buffer[bufferIndex], available);
uint32 remaining = len - available;
result = available;
if (remaining) {
- result += file->Read(((byte*)ptr) + available, remaining);
+ result += file->Read(((byte *)ptr) + available, remaining);
}
bufferIndex = bufferLength = 0;
}
@@ -192,11 +192,11 @@ uint32 BadaFileStream::read(void *ptr, uint32 len) {
if (bufferLength < len) {
len = bufferLength;
}
- memcpy((byte*)ptr, buffer, len);
+ memcpy((byte *)ptr, buffer, len);
result = bufferIndex = len;
}
} else {
- result = file->Read((byte*)ptr, len);
+ result = file->Read((byte *)ptr, len);
bufferIndex = bufferLength = 0;
}
} else {
diff --git a/backends/platform/bada/missing.cpp b/backends/platform/bada/missing.cpp
index a5433ec61a..10d45ca4b5 100644
--- a/backends/platform/bada/missing.cpp
+++ b/backends/platform/bada/missing.cpp
@@ -96,7 +96,7 @@ int sprintf(char *str, const char *format, ...) {
char *strdup(const char *strSource) {
char *buffer;
int len = strlen(strSource) + 1;
- buffer = (char*)malloc(len);
+ buffer = (char *)malloc(len);
if (buffer) {
memcpy(buffer, strSource, len);
}
diff --git a/backends/platform/bada/portdefs.h b/backends/platform/bada/portdefs.h
index e85d578678..813c5acde3 100644
--- a/backends/platform/bada/portdefs.h
+++ b/backends/platform/bada/portdefs.h
@@ -30,6 +30,7 @@
#include <stdio.h>
#include <unistd.h>
#include <math.h>
+#include <new>
#define M_PI 3.14159265358979323846
@@ -64,9 +65,9 @@ void stderr_vfprintf(void*, const char *format, va_list ap);
#undef fputs
#undef fflush
-#define stderr (void*)0
-#define stdout (void*)1
-#define stdin (void*)2
+#define stderr (void *)0
+#define stdout (void *)1
+#define stdin (void *)2
#define fputs(str, file)
#define fflush(file)
#define sscanf simple_sscanf
diff --git a/backends/platform/dc/audio.cpp b/backends/platform/dc/audio.cpp
index 35cb51f349..4f01531486 100644
--- a/backends/platform/dc/audio.cpp
+++ b/backends/platform/dc/audio.cpp
@@ -59,7 +59,7 @@ void OSystem_Dreamcast::checkSound()
if (n<100)
return;
- _mixer->mixCallback((byte*)temp_sound_buffer,
+ _mixer->mixCallback((byte *)temp_sound_buffer,
2*SAMPLES_TO_BYTES(n));
if (fillpos+n > curr_ring_buffer_samples) {
diff --git a/backends/platform/dc/dc-fs.cpp b/backends/platform/dc/dc-fs.cpp
index f30c9c56d1..36f5a1465c 100644
--- a/backends/platform/dc/dc-fs.cpp
+++ b/backends/platform/dc/dc-fs.cpp
@@ -39,7 +39,7 @@ protected:
Common::String _path;
public:
- RoninCDFileNode(const Common::String &path) : _path(path) {};
+ RoninCDFileNode(const Common::String &path) : _path(path) {}
virtual bool exists() const { return true; }
virtual Common::String getName() const { return lastPathComponent(_path, '/'); }
@@ -61,7 +61,7 @@ public:
/* A directory */
class RoninCDDirectoryNode : public RoninCDFileNode {
public:
- RoninCDDirectoryNode(const Common::String &path) : RoninCDFileNode(path) {};
+ RoninCDDirectoryNode(const Common::String &path) : RoninCDFileNode(path) {}
virtual bool isDirectory() const { return true; }
virtual AbstractFSNode *getChild(const Common::String &n) const;
@@ -72,7 +72,7 @@ public:
/* A file/directory which does not exist */
class RoninCDNonexistingNode : public RoninCDFileNode {
public:
- RoninCDNonexistingNode(const Common::String &path) : RoninCDFileNode(path) {};
+ RoninCDNonexistingNode(const Common::String &path) : RoninCDFileNode(path) {}
virtual bool exists() const { return false; }
virtual bool isReadable() const { return false; }
diff --git a/backends/platform/dc/dc.h b/backends/platform/dc/dc.h
index 2e32ff3eb4..8ca48bf19e 100644
--- a/backends/platform/dc/dc.h
+++ b/backends/platform/dc/dc.h
@@ -29,6 +29,8 @@
#include "backends/audiocd/default/default-audiocd.h"
#include "backends/fs/fs-factory.h"
#include "audio/mixer_intern.h"
+#include "common/language.h"
+#include "common/platform.h"
#ifdef DYNAMIC_MODULES
#include "backends/plugins/dynamic-plugin.h"
#endif
diff --git a/backends/platform/dc/dcloader.cpp b/backends/platform/dc/dcloader.cpp
index 675f7ad8c7..56193c282a 100644
--- a/backends/platform/dc/dcloader.cpp
+++ b/backends/platform/dc/dcloader.cpp
@@ -385,8 +385,8 @@ void *DLObject::symbol(const char *name)
for (int c = symbol_cnt; c--; s++)
if ((s->st_info>>4 == 1 || s->st_info>>4 == 2) &&
strtab[s->st_name] == '_' && !strcmp(name, strtab+s->st_name+1)) {
- DBG(("=> %p\n", (void*)s->st_value));
- return (void*)s->st_value;
+ DBG(("=> %p\n", (void *)s->st_value));
+ return (void *)s->st_value;
}
seterror("Symbol \"%s\" not found.", name);
diff --git a/backends/platform/dc/display.cpp b/backends/platform/dc/display.cpp
index 76658c6590..e886b55869 100644
--- a/backends/platform/dc/display.cpp
+++ b/backends/platform/dc/display.cpp
@@ -334,8 +334,8 @@ void OSystem_Dreamcast::updateScreenTextures(void)
unsigned short *dst = (unsigned short *)screen_tx[_screen_buffer];
unsigned char *src = screen;
- // while ((*((volatile unsigned int *)(void*)0xa05f810c) & 0x3ff) != 200);
- // *((volatile unsigned int *)(void*)0xa05f8040) = 0xff0000;
+ // while ((*((volatile unsigned int *)(void *)0xa05f810c) & 0x3ff) != 200);
+ // *((volatile unsigned int *)(void *)0xa05f8040) = 0xff0000;
if (_screenFormat == 0)
for ( int y = 0; y<_screen_h; y++ )
@@ -379,7 +379,7 @@ void OSystem_Dreamcast::updateScreenPolygons(void)
struct polygon_list mypoly;
struct packed_colour_vertex_list myvertex;
- // *((volatile unsigned int *)(void*)0xa05f8040) = 0x00ff00;
+ // *((volatile unsigned int *)(void *)0xa05f8040) = 0x00ff00;
mypoly.cmd =
TA_CMD_POLYGON|TA_CMD_POLYGON_TYPE_OPAQUE|TA_CMD_POLYGON_SUBLIST|
@@ -395,7 +395,7 @@ void OSystem_Dreamcast::updateScreenPolygons(void)
mypoly.red = mypoly.green = mypoly.blue = mypoly.alpha = 0;
ta_begin_frame();
- // *((volatile unsigned int *)(void*)0xa05f8040) = 0x0000ff;
+ // *((volatile unsigned int *)(void *)0xa05f8040) = 0x0000ff;
ta_commit_list(&mypoly);
myvertex.cmd = TA_CMD_VERTEX;
@@ -493,12 +493,12 @@ void OSystem_Dreamcast::updateScreenPolygons(void)
_softkbd.draw(330.0*sin(0.013*_softkbd_motion) - 320.0, 200.0,
120-_softkbd_motion);
- // *((volatile unsigned int *)(void*)0xa05f8040) = 0xffff00;
+ // *((volatile unsigned int *)(void *)0xa05f8040) = 0xffff00;
drawMouse(_ms_cur_x, _ms_cur_y, _ms_cur_w, _ms_cur_h, _ms_buf, _ms_visible);
- // *((volatile unsigned int *)(void*)0xa05f8040) = 0xff00ff;
+ // *((volatile unsigned int *)(void *)0xa05f8040) = 0xff00ff;
ta_commit_frame();
- // *((volatile unsigned int *)(void*)0xa05f8040) = 0x0;
+ // *((volatile unsigned int *)(void *)0xa05f8040) = 0x0;
_last_screen_refresh = Timer();
}
diff --git a/backends/platform/dc/portdefs.h b/backends/platform/dc/portdefs.h
index ca2b5208a3..1f5c8f566a 100644
--- a/backends/platform/dc/portdefs.h
+++ b/backends/platform/dc/portdefs.h
@@ -29,6 +29,7 @@
#include <assert.h>
#include <ctype.h>
#include <math.h>
+#include <new>
#ifndef RONIN_TIMER_ACCESS
#define Timer ronin_Timer
#endif
diff --git a/backends/platform/ds/arm7/source/main.cpp b/backends/platform/ds/arm7/source/main.cpp
index 2e9cacc669..6e714b22fa 100644
--- a/backends/platform/ds/arm7/source/main.cpp
+++ b/backends/platform/ds/arm7/source/main.cpp
@@ -46,10 +46,10 @@
#include "cartreset_nolibfat.h"
-#define TOUCH_CAL_X1 (*(vs16*)0x027FFCD8)
-#define TOUCH_CAL_Y1 (*(vs16*)0x027FFCDA)
-#define TOUCH_CAL_X2 (*(vs16*)0x027FFCDE)
-#define TOUCH_CAL_Y2 (*(vs16*)0x027FFCE0)
+#define TOUCH_CAL_X1 (*(vs16 *)0x027FFCD8)
+#define TOUCH_CAL_Y1 (*(vs16 *)0x027FFCDA)
+#define TOUCH_CAL_X2 (*(vs16 *)0x027FFCDE)
+#define TOUCH_CAL_Y2 (*(vs16 *)0x027FFCE0)
#define SCREEN_WIDTH 256
#define SCREEN_HEIGHT 192
s32 TOUCH_WIDTH = TOUCH_CAL_X2 - TOUCH_CAL_X1;
@@ -71,10 +71,10 @@ int temp;
int adpcmBufferNum = 0;
// those are pixel positions of the two points you click when calibrating
-#define TOUCH_CNTRL_X1 (*(vu8*)0x027FFCDC)
-#define TOUCH_CNTRL_Y1 (*(vu8*)0x027FFCDD)
-#define TOUCH_CNTRL_X2 (*(vu8*)0x027FFCE2)
-#define TOUCH_CNTRL_Y2 (*(vu8*)0x027FFCE3)
+#define TOUCH_CNTRL_X1 (*(vu8 *)0x027FFCDC)
+#define TOUCH_CNTRL_Y1 (*(vu8 *)0x027FFCDD)
+#define TOUCH_CNTRL_X2 (*(vu8 *)0x027FFCE2)
+#define TOUCH_CNTRL_Y2 (*(vu8 *)0x027FFCE3)
//////////////////////////////////////////////////////////////////////
@@ -330,7 +330,7 @@ void performSleep() {
// int saveInts = REG_IE;
// REG_IE = (1 << 22) | IRQ_VBLANK; // Lid open
-// *((u32*) (0x0380FFF8)) = *((u32*) (0x0380FFF8)) | (REG_IE & REG_IF);
+// *((u32 *) (0x0380FFF8)) = *((u32 *) (0x0380FFF8)) | (REG_IE & REG_IF);
// VBLANK_INTR_WAIT_FLAGS = IRQ_VBLANK;
diff --git a/backends/platform/ds/arm9/source/blitters.cpp b/backends/platform/ds/arm9/source/blitters.cpp
index 0076b302fd..1e8d56615d 100644
--- a/backends/platform/ds/arm9/source/blitters.cpp
+++ b/backends/platform/ds/arm9/source/blitters.cpp
@@ -222,8 +222,8 @@ static inline void RescaleBlock_5x1555_To_4x1555( u16 s0, u16 s1, u16 s2, u16 s3
u32 d10 = 0x80008000 | (rd1 << 26) | (gd1 << 21) | (bd1 << 16) | (rd0 << 10) | (gd0 << 5) | bd0;
u32 d32 = 0x80008000 | (rd3 << 26) | (gd3 << 21) | (bd3 << 16) | (rd2 << 10) | (gd2 << 5) | bd2;
- ((u32*)dest)[0] = d10;
- ((u32*)dest)[1] = d32;
+ ((u32 *)dest)[0] = d10;
+ ((u32 *)dest)[1] = d32;
}
#else
static inline void RescaleBlock_5x1555_To_4x1555( u16 s0, u16 s1, u16 s2, u16 s3, u16 s4,
@@ -290,7 +290,7 @@ static inline void RescaleBlock_5x8888_To_4x1555( u32 s0, u32 s1, u32 s2, u32 s3
gd0 = DIV_BY_5[gd0]; gd1 = DIV_BY_5[gd1];
bd0 = DIV_BY_5[bd0]; bd1 = DIV_BY_5[bd1];
u32 d10 = 0x80008000 | (rd1 << 26) | (gd1 << 21) | (bd1 << 16) | (rd0 << 10) | (gd0 << 5) | bd0;
- ((u32*)dest)[0] = d10;
+ ((u32 *)dest)[0] = d10;
u32 d2 = 2*s2 + 2*s3 + s3;
u32 d3 = s3 + 4*s4;
@@ -307,7 +307,7 @@ static inline void RescaleBlock_5x8888_To_4x1555( u32 s0, u32 s1, u32 s2, u32 s3
bd2 = DIV_BY_5[bd2]; bd3 = DIV_BY_5[bd3];
u32 d32 = 0x80008000 | (rd3 << 26) | (gd3 << 21) | (bd3 << 16) | (rd2 << 10) | (gd2 << 5) | bd2;
- ((u32*)dest)[1] = d32;
+ ((u32 *)dest)[1] = d32;
}
// Can't work in place
@@ -377,7 +377,7 @@ void Rescale_320x256xPAL8_To_256x256x1555(u16 *dest, const u8 *src, int destStri
void Rescale_320x256xPAL8_To_256x256x1555(u16 *dest, const u8 *src, int destStride, int srcStride, const u16 *palette) {
u16 fastRam[256];
for (size_t i = 0; i < 128; ++i)
- ((u32*)fastRam)[i] = ((const u32*)palette)[i];
+ ((u32 *)fastRam)[i] = ((const u32*)palette)[i];
for (size_t i = 0; i < 200; ++i) {
Rescale_320xPAL8Scanline_To_256x1555Scanline(dest + i*destStride, src + i *srcStride, fastRam);
diff --git a/backends/platform/ds/arm9/source/dsmain.cpp b/backends/platform/ds/arm9/source/dsmain.cpp
index dfd906d816..cedbdcb167 100644
--- a/backends/platform/ds/arm9/source/dsmain.cpp
+++ b/backends/platform/ds/arm9/source/dsmain.cpp
@@ -926,7 +926,7 @@ void displayMode16Bit() {
SUB_BG0_Y0 = 0;
consoleInit(NULL, 0, BgType_Text4bpp, BgSize_T_256x256, 4, 0, false, true);
-// consoleInitDefault((u16*)SCREEN_BASE_BLOCK_SUB(4), (u16*)CHAR_BASE_BLOCK_SUB(0), 16);
+// consoleInitDefault((u16 *)SCREEN_BASE_BLOCK_SUB(4), (u16 *)CHAR_BASE_BLOCK_SUB(0), 16);
for (int r = 0; r < 32 * 32; r++) {
((u16 *) SCREEN_BASE_BLOCK_SUB(4))[r] = buffer[r];
@@ -2414,7 +2414,7 @@ void initHardware() {
BG_PALETTE[255] = RGB15(31,31,31);//by default font will be rendered with color 255
//consoleInit() is a lot more flexible but this gets you up and running quick
-// consoleInitDefault((u16*)SCREEN_BASE_BLOCK(0), (u16*)CHAR_BASE_BLOCK(1), 16);
+// consoleInitDefault((u16 *)SCREEN_BASE_BLOCK(0), (u16 *)CHAR_BASE_BLOCK(1), 16);
//consolePrintSet(0, 6);
//irqs are nice
@@ -2886,7 +2886,7 @@ void dsExceptionHandler() {
setExceptionHandler(NULL);
u32 currentMode = getCPSR() & 0x1f;
- u32 thumbState = ((*(u32*)0x027FFD90) & 0x20);
+ u32 thumbState = ((*(u32 *)0x027FFD90) & 0x20);
u32 codeAddress, exceptionAddress = 0;
diff --git a/backends/platform/ds/arm9/source/osystem_ds.cpp b/backends/platform/ds/arm9/source/osystem_ds.cpp
index fdd310ec17..73340ed18a 100644
--- a/backends/platform/ds/arm9/source/osystem_ds.cpp
+++ b/backends/platform/ds/arm9/source/osystem_ds.cpp
@@ -267,23 +267,6 @@ void OSystem_DS::setCursorPalette(const byte *colors, uint start, uint num) {
refreshCursor();
}
-bool OSystem_DS::grabRawScreen(Graphics::Surface *surf) {
- surf->create(DS::getGameWidth(), DS::getGameHeight(), Graphics::PixelFormat::createFormatCLUT8());
-
- // Ensure we copy using 16 bit quantities due to limitation of VRAM addressing
-
-
- const u16 *image = (const u16 *) DS::get8BitBackBuffer();
- for (int y = 0; y < DS::getGameHeight(); y++) {
- DC_FlushRange(image + (y << 8), DS::getGameWidth());
- for (int x = 0; x < DS::getGameWidth() >> 1; x++) {
- *(((u16 *) (surf->pixels)) + y * (DS::getGameWidth() >> 1) + x) = image[(y << 8) + x];
- }
- }
-
- return true;
-}
-
void OSystem_DS::grabPalette(unsigned char *colors, uint start, uint num) {
// consolePrintf("Grabpalette");
diff --git a/backends/platform/ds/arm9/source/osystem_ds.h b/backends/platform/ds/arm9/source/osystem_ds.h
index b1222a152d..6aa3731916 100644
--- a/backends/platform/ds/arm9/source/osystem_ds.h
+++ b/backends/platform/ds/arm9/source/osystem_ds.h
@@ -141,8 +141,6 @@ public:
void addEvent(const Common::Event& e);
bool isEventQueueEmpty() const { return queuePos == 0; }
- virtual bool grabRawScreen(Graphics::Surface *surf);
-
virtual void setFocusRectangle(const Common::Rect& rect);
virtual void clearFocusRectangle();
diff --git a/backends/platform/ds/arm9/source/portdefs.h b/backends/platform/ds/arm9/source/portdefs.h
index f512ce3ea2..e40849a513 100644
--- a/backends/platform/ds/arm9/source/portdefs.h
+++ b/backends/platform/ds/arm9/source/portdefs.h
@@ -37,6 +37,7 @@
#include <stdarg.h>
#include <ctype.h>
#include <math.h>
+#include <new>
#define double float
diff --git a/backends/platform/ds/arm9/source/scummhelp.h b/backends/platform/ds/arm9/source/scummhelp.h
index 79103b35ed..2735727560 100644
--- a/backends/platform/ds/arm9/source/scummhelp.h
+++ b/backends/platform/ds/arm9/source/scummhelp.h
@@ -24,7 +24,7 @@
#define _SCUMMHELP_H_
#include "common/str.h"
-#include "common/util.h"
+#include "common/platform.h"
namespace DS {
diff --git a/backends/platform/gph/caanoo-bundle.mk b/backends/platform/gph/caanoo-bundle.mk
index 8aabca9028..2cf8e62b37 100755
--- a/backends/platform/gph/caanoo-bundle.mk
+++ b/backends/platform/gph/caanoo-bundle.mk
@@ -14,11 +14,11 @@ caanoo-bundle: $(EXECUTABLE)
echo "Please put your save games in this dir" >> "$(bundle_name)/scummvm/saves/PUT_SAVES_IN_THIS_DIR"
- $(CP) $(srcdir)/backends/platform/gph/devices/caanoo/scummvm.gpe $(bundle_name)/scummvm/
- $(CP) $(srcdir)/backends/platform/gph/devices/common/scummvm.png $(bundle_name)/scummvm/
- $(CP) $(srcdir)/backends/platform/gph/devices/common/scummvmb.png $(bundle_name)/scummvm/
- $(CP) $(srcdir)/backends/platform/gph/devices/common/README-GPH $(bundle_name)/scummvm/
- $(CP) $(srcdir)/backends/platform/gph/devices/common/scummvm.ini $(bundle_name)/
+ $(CP) $(srcdir)/dists/gph/caanoo/scummvm.gpe $(bundle_name)/scummvm/
+ $(CP) $(srcdir)/dists/gph/scummvm.png $(bundle_name)/scummvm/
+ $(CP) $(srcdir)/dists/gph/scummvmb.png $(bundle_name)/scummvm/
+ $(CP) $(srcdir)/dists/gph/README-GPH $(bundle_name)/scummvm/
+ $(CP) $(srcdir)/dists/gph/scummvm.ini $(bundle_name)/
$(INSTALL) -c -m 644 $(DIST_FILES_DOCS) $(bundle_name)/scummvm/
$(INSTALL) -c -m 644 $(DIST_FILES_THEMES) $(bundle_name)/scummvm/
@@ -45,11 +45,11 @@ caanoo-bundle-debug: $(EXECUTABLE)
echo "Please put your save games in this dir" >> "$(bundle_name)/scummvm/saves/PUT_SAVES_IN_THIS_DIR"
- $(CP) $(srcdir)/backends/platform/gph/devices/caanoo/scummvm-gdb.gpe $(bundle_name)/scummvm/scummvm.gpe
- $(CP) $(srcdir)/backends/platform/gph/devices/common/scummvm.png $(bundle_name)/scummvm/
- $(CP) $(srcdir)/backends/platform/gph/devices/common/scummvmb.png $(bundle_name)/scummvm/
- $(CP) $(srcdir)/backends/platform/gph/devices/common/README-GPH $(bundle_name)/scummvm/
- $(CP) $(srcdir)/backends/platform/gph/devices/common/scummvm.ini $(bundle_name)/
+ $(CP) $(srcdir)/dists/gph/caanoo/scummvm-gdb.gpe $(bundle_name)/scummvm/scummvm.gpe
+ $(CP) $(srcdir)/dists/gph/scummvm.png $(bundle_name)/scummvm/
+ $(CP) $(srcdir)/dists/gph/scummvmb.png $(bundle_name)/scummvm/
+ $(CP) $(srcdir)/dists/gph/README-GPH $(bundle_name)/scummvm/
+ $(CP) $(srcdir)/dists/gph/scummvm.ini $(bundle_name)/
$(INSTALL) -c -m 644 $(DIST_FILES_DOCS) $(bundle_name)/scummvm/
$(INSTALL) -c -m 644 $(DIST_FILES_THEMES) $(bundle_name)/scummvm/
diff --git a/backends/platform/gph/gp2x-bundle.mk b/backends/platform/gph/gp2x-bundle.mk
index 810ff8b8f0..9fcb379e04 100644
--- a/backends/platform/gph/gp2x-bundle.mk
+++ b/backends/platform/gph/gp2x-bundle.mk
@@ -12,15 +12,15 @@ gp2x-bundle: $(EXECUTABLE)
echo "Please put your save games in this dir" >> "$(bundle_name)/saves/PUT_SAVES_IN_THIS_DIR"
- $(CP) $(srcdir)/backends/platform/gph/devices/gp2x/scummvm.gpe $(bundle_name)/
- $(CP) $(srcdir)/backends/platform/gph/devices/common/scummvm.png $(bundle_name)/
- $(CP) $(srcdir)/backends/platform/gph/devices/common/README-GPH $(bundle_name)/
- $(CP) $(srcdir)/backends/platform/gph/devices/gp2x/mmuhack/mmuhack.o $(bundle_name)/
+ $(CP) $(srcdir)/dists/gph/gp2x/scummvm.gpe $(bundle_name)
+ $(CP) $(srcdir)/dists/gph/scummvm.png $(bundle_name)
+ $(CP) $(srcdir)/dists/gph/README-GPH $(bundle_name)
+ $(CP) $(srcdir)/dists/gph/gp2x/mmuhack/mmuhack.o $(bundle_name)
- $(INSTALL) -c -m 644 $(DIST_FILES_DOCS) $(bundle_name)/
- $(INSTALL) -c -m 644 $(DIST_FILES_THEMES) $(bundle_name)/
+ $(INSTALL) -c -m 644 $(DIST_FILES_DOCS) $(bundle_name)
+ $(INSTALL) -c -m 644 $(DIST_FILES_THEMES) $(bundle_name)
$(INSTALL) -c -m 644 $(DIST_FILES_ENGINEDATA) $(bundle_name)/engine-data
- $(CP) $(srcdir)/backends/vkeybd/packs/vkeybd_default.zip $(bundle_name)/
+ $(CP) $(srcdir)/backends/vkeybd/packs/vkeybd_default.zip $(bundle_name)
$(STRIP) $(EXECUTABLE) -o $(bundle_name)/$(EXECUTABLE)
@@ -39,18 +39,19 @@ gp2x-bundle-debug: $(EXECUTABLE)
$(MKDIR) "$(bundle_name)"
$(MKDIR) "$(bundle_name)/saves"
$(MKDIR) "$(bundle_name)/engine-data"
+ $(MKDIR) "$(bundle_name)/lib"
echo "Please put your save games in this dir" >> "$(bundle_name)/saves/PUT_SAVES_IN_THIS_DIR"
- $(CP) $(srcdir)/backends/platform/gph/devices/gp2x/scummvm.gpe $(bundle_name)/
- $(CP) $(srcdir)/backends/platform/gph/devices/common/scummvm.png $(bundle_name)/
- $(CP) $(srcdir)/backends/platform/gph/devices/common/README-GPH $(bundle_name)/
- $(CP) $(srcdir)/backends/platform/gph/devices/gp2x/mmuhack/mmuhack.o $(bundle_name)/
+ $(CP) $(srcdir)/dists/gph/gp2x/scummvm.gpe $(bundle_name)
+ $(CP) $(srcdir)/dists/gph/scummvm.png $(bundle_name)
+ $(CP) $(srcdir)/dists/gph/README-GPH $(bundle_name)
+ $(CP) $(srcdir)/dists/gph/gp2x/mmuhack/mmuhack.o $(bundle_name)
- $(INSTALL) -c -m 644 $(DIST_FILES_DOCS) $(bundle_name)/
- $(INSTALL) -c -m 644 $(DIST_FILES_THEMES) $(bundle_name)/
+ $(INSTALL) -c -m 644 $(DIST_FILES_DOCS) $(bundle_name)
+ $(INSTALL) -c -m 644 $(DIST_FILES_THEMES) $(bundle_name)
$(INSTALL) -c -m 644 $(DIST_FILES_ENGINEDATA) $(bundle_name)/engine-data
- $(CP) $(srcdir)/backends/vkeybd/packs/vkeybd_default.zip $(bundle_name)/
+ $(CP) $(srcdir)/backends/vkeybd/packs/vkeybd_default.zip $(bundle_name)
$(INSTALL) -c -m 777 $(srcdir)/$(EXECUTABLE) $(bundle_name)/$(EXECUTABLE)
diff --git a/backends/platform/gph/gp2xwiz-bundle.mk b/backends/platform/gph/gp2xwiz-bundle.mk
index 65e2952fde..4f49850813 100755
--- a/backends/platform/gph/gp2xwiz-bundle.mk
+++ b/backends/platform/gph/gp2xwiz-bundle.mk
@@ -13,11 +13,11 @@ gp2xwiz-bundle: $(EXECUTABLE)
echo "Please put your save games in this dir" >> "$(bundle_name)/scummvm/saves/PUT_SAVES_IN_THIS_DIR"
- $(CP) $(srcdir)/backends/platform/gph/devices/gp2xwiz/scummvm.gpe $(bundle_name)/scummvm/
- $(CP) $(srcdir)/backends/platform/gph/devices/common/scummvm.png $(bundle_name)/scummvm/
- $(CP) $(srcdir)/backends/platform/gph/devices/common/scummvmb.png $(bundle_name)/scummvm/
- $(CP) $(srcdir)/backends/platform/gph/devices/common/README-GPH $(bundle_name)/scummvm/
- $(CP) $(srcdir)/backends/platform/gph/devices/common/scummvm.ini $(bundle_name)/
+ $(CP) $(srcdir)/dists/gph/gp2xwiz/scummvm.gpe $(bundle_name)/scummvm/
+ $(CP) $(srcdir)/dists/gph/scummvm.png $(bundle_name)/scummvm/
+ $(CP) $(srcdir)/dists/gph/scummvmb.png $(bundle_name)/scummvm/
+ $(CP) $(srcdir)/dists/gph/README-GPH $(bundle_name)/scummvm/
+ $(CP) $(srcdir)/dists/gph/scummvm.ini $(bundle_name)/
$(INSTALL) -c -m 644 $(DIST_FILES_DOCS) $(bundle_name)/scummvm/
$(INSTALL) -c -m 644 $(DIST_FILES_THEMES) $(bundle_name)/scummvm/
@@ -47,11 +47,11 @@ gp2xwiz-bundle-debug: $(EXECUTABLE)
echo "Please put your save games in this dir" >> "$(bundle_name)/scummvm/saves/PUT_SAVES_IN_THIS_DIR"
- $(CP) $(srcdir)/backends/platform/gph/devices/gp2xwiz/scummvm-gdb.gpe $(bundle_name)/scummvm/scummvm.gpe
- $(CP) $(srcdir)/backends/platform/gph/devices/common/scummvm.png $(bundle_name)/scummvm/
- $(CP) $(srcdir)/backends/platform/gph/devices/common/scummvmb.png $(bundle_name)/scummvm/
- $(CP) $(srcdir)/backends/platform/gph/devices/common/README-GPH $(bundle_name)/scummvm/
- $(CP) $(srcdir)/backends/platform/gph/devices/common/scummvm.ini $(bundle_name)/
+ $(CP) $(srcdir)/dists/gph/gp2xwiz/scummvm-gdb.gpe $(bundle_name)/scummvm/scummvm.gpe
+ $(CP) $(srcdir)/dists/gph/scummvm.png $(bundle_name)/scummvm/
+ $(CP) $(srcdir)/dists/gph/scummvmb.png $(bundle_name)/scummvm/
+ $(CP) $(srcdir)/dists/gph/README-GPH $(bundle_name)/scummvm/
+ $(CP) $(srcdir)/dists/gph/scummvm.ini $(bundle_name)/
$(INSTALL) -c -m 644 $(DIST_FILES_DOCS) $(bundle_name)/scummvm/
$(INSTALL) -c -m 644 $(DIST_FILES_THEMES) $(bundle_name)/scummvm/
diff --git a/backends/platform/iphone/blit_arm.h b/backends/platform/iphone/blit_arm.h
deleted file mode 100644
index 77bb3578ab..0000000000
--- a/backends/platform/iphone/blit_arm.h
+++ /dev/null
@@ -1,35 +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.
- *
- */
-
-extern "C" void blitLandscapeScreenRect16bpp(uint16 *dst, uint16 *src,
- int width,
- int height,
- int screenWidth,
- int screenHeight);
-
-extern "C" void blitLandscapeScreenRect8bpp(uint16 *dst,
- byte *src,
- int width,
- int height,
- uint16 *palette,
- int screenWidth,
- int screenHeight);
diff --git a/backends/platform/iphone/blit_arm.s b/backends/platform/iphone/blit_arm.s
deleted file mode 100644
index 04f9a87614..0000000000
--- a/backends/platform/iphone/blit_arm.s
+++ /dev/null
@@ -1,137 +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.
-@
-@ @author Robin Watts (robin@wss.co.uk)
-
- .text
-
- .global _blitLandscapeScreenRect16bpp
- .global _blitLandscapeScreenRect8bpp
-
-
-_blitLandscapeScreenRect16bpp:
- @ r0 = dst
- @ r1 = src
- @ r2 = w
- @ r3 = h
- @ <> = _screenWidth
- @ <> = _screenHeight
- mov r12,r13
- stmfd r13!,{r4-r11,r14}
- ldmfd r12,{r12,r14} @ r12 = _screenWidth
- @ r14 = _screenHeight
- add r14,r14,r3 @ r14 = _screenHeight + h
- mvn r11,#0
- mla r11,r3,r12,r11 @ r11= _screenWidth*h-1
- add r12,r12,r12
-xloop:
- subs r4,r3,#5 @ r4 = y = h
- ble thin
-yloop:
- ldrh r5, [r1],r12 @ r5 = *src src += _screenWidth
- ldrh r6, [r1],r12 @ r6 = *src src += _screenWidth
- ldrh r7, [r1],r12 @ r7 = *src src += _screenWidth
- ldrh r8, [r1],r12 @ r8 = *src src += _screenWidth
- ldrh r9, [r1],r12 @ r9 = *src src += _screenWidth
- ldrh r10,[r1],r12 @ r10= *src src += _screenWidth
- subs r4,r4,#6
- strh r5, [r0],#2 @ *dst++ = r5
- strh r6, [r0],#2 @ *dst++ = r6
- strh r7, [r0],#2 @ *dst++ = r7
- strh r8, [r0],#2 @ *dst++ = r8
- strh r9, [r0],#2 @ *dst++ = r9
- strh r10,[r0],#2 @ *dst++ = r10
- bgt yloop
-thin:
- adds r4,r4,#5
- beq lineend
-thin_loop:
- ldrh r5,[r1],r12 @ r5 = *src src += _screenWidth
- subs r4,r4,#1
- strh r5,[r0],#2 @ *dst++ = r5
- bgt thin_loop
-lineend:
- sub r0,r0,r14,LSL #1 @ dst -= _screenHeight + h
- sub r1,r1,r11,LSL #1 @ src += 1-_screenWidth*h
- subs r2,r2,#1
- bgt xloop
-
- ldmfd r13!,{r4-r11,PC}
-
-_blitLandscapeScreenRect8bpp:
- @ r0 = dst
- @ r1 = src
- @ r2 = w
- @ r3 = h
- @ <> = _palette
- @ <> = _screenWidth
- @ <> = _screenHeight
- mov r12,r13
- stmfd r13!,{r4-r11,r14}
- ldmfd r12,{r11,r12,r14} @ r11 = _palette
- @ r12 = _screenWidth
- @ r14 = _screenHeight
- add r14,r14,r3 @ r14 = _screenHeight + h
- mvn r6,#0
- mla r6,r3,r12,r6 @ r6 = _screenWidth*h-1
-xloop8:
- mov r4,r3 @ r4 = y = h
- subs r4,r3,#4 @ r4 = y = h
- ble thin8
-yloop8:
- ldrb r5, [r1],r12 @ r5 = *src src += _screenWidth
- ldrb r7, [r1],r12 @ r7 = *src src += _screenWidth
- ldrb r8, [r1],r12 @ r8 = *src src += _screenWidth
- ldrb r9, [r1],r12 @ r9 = *src src += _screenWidth
- ldrb r10,[r1],r12 @ r10= *src src += _screenWidth
- add r5, r5, r5
- add r7, r7, r7
- add r8, r8, r8
- add r9, r9, r9
- add r10,r10,r10
- ldrh r5, [r11,r5]
- ldrh r7, [r11,r7]
- ldrh r8, [r11,r8]
- ldrh r9, [r11,r9]
- ldrh r10,[r11,r10]
- subs r4,r4,#5
- strh r5, [r0],#2 @ *dst++ = r5
- strh r7, [r0],#2 @ *dst++ = r7
- strh r8, [r0],#2 @ *dst++ = r8
- strh r9, [r0],#2 @ *dst++ = r9
- strh r10,[r0],#2 @ *dst++ = r10
- bgt yloop8
-thin8:
- adds r4,r4,#4
- beq lineend8
-thin_loop8:
- ldrb r5,[r1],r12 @ r5 = *src src += _screenWidth
- add r5,r5,r5
- ldrh r5,[r11,r5]
- subs r4,r4,#1
- strh r5,[r0],#2 @ *dst++ = r5
- bgt thin_loop8
-lineend8:
- sub r0,r0,r14,LSL #1 @ dst -= _screenHeight + h
- sub r1,r1,r6 @ src += 1-_screenWidth*h
- subs r2,r2,#1
- bgt xloop8
-
- ldmfd r13!,{r4-r11,PC}
diff --git a/backends/platform/iphone/iphone_common.h b/backends/platform/iphone/iphone_common.h
index 0cbcb77bcb..19e4f2ce9b 100644
--- a/backends/platform/iphone/iphone_common.h
+++ b/backends/platform/iphone/iphone_common.h
@@ -20,6 +20,10 @@
*
*/
+#ifndef BACKENDS_PLATFORM_IPHONE_IPHONE_COMMON_H
+#define BACKENDS_PLATFORM_IPHONE_IPHONE_COMMON_H
+
+#include "graphics/surface.h"
enum InputEvent {
kInputMouseDown,
@@ -41,43 +45,53 @@ enum ScreenOrientation {
kScreenOrientationFlippedLandscape
};
-typedef enum
-{
+enum UIViewSwipeDirection {
kUIViewSwipeUp = 1,
kUIViewSwipeDown = 2,
kUIViewSwipeLeft = 4,
kUIViewSwipeRight = 8
-} UIViewSwipeDirection;
+};
-#ifdef IPHONE_OFFICIAL
-void iphone_main(int argc, char **argv);
-#endif
+enum GraphicsModes {
+ kGraphicsModeLinear = 0,
+ kGraphicsModeNone = 1
+};
-// We need this to be able to call functions from/in Objective-C.
-#ifdef __cplusplus
-extern "C" {
-#endif
+struct VideoContext {
+ VideoContext() : asprectRatioCorrection(), screenWidth(), screenHeight(), overlayVisible(false),
+ overlayWidth(), overlayHeight(), mouseX(), mouseY(),
+ mouseHotspotX(), mouseHotspotY(), mouseWidth(), mouseHeight(),
+ mouseIsVisible(), graphicsMode(kGraphicsModeLinear), shakeOffsetY() {
+ }
-// On the C++ side
-#ifndef IPHONE_OFFICIAL
-void iphone_main(int argc, char *argv[]);
-#endif
+ // Game screen state
+ bool asprectRatioCorrection;
+ uint screenWidth, screenHeight;
+ Graphics::Surface screenTexture;
+
+ // Overlay state
+ bool overlayVisible;
+ uint overlayWidth, overlayHeight;
+ Graphics::Surface overlayTexture;
+
+ // Mouse cursor state
+ uint mouseX, mouseY;
+ int mouseHotspotX, mouseHotspotY;
+ uint mouseWidth, mouseHeight;
+ bool mouseIsVisible;
+ Graphics::Surface mouseTexture;
+
+ // Misc state
+ GraphicsModes graphicsMode;
+ int shakeOffsetY;
+};
// On the ObjC side
-void iPhone_updateScreen(int mouseX, int mouseY);
-void iPhone_updateScreenRect(unsigned short* screen, int x1, int y1, int x2, int y2);
-void iPhone_updateOverlayRect(unsigned short* screen, int x1, int y1, int x2, int y2);
-void iPhone_initSurface(int width, int height);
-bool iPhone_fetchEvent(int *outEvent, float *outX, float *outY);
-const char* iPhone_getDocumentsDir();
+void iPhone_updateScreen();
+bool iPhone_fetchEvent(int *outEvent, int *outX, int *outY);
+const char *iPhone_getDocumentsDir();
bool iPhone_isHighResDevice();
-int iPhone_getScreenHeight();
-int iPhone_getScreenWidth();
-void iPhone_enableOverlay(int state);
-void iPhone_setMouseCursor(short* buffer, int width, int height);
uint getSizeNextPOT(uint size);
-#ifdef __cplusplus
-}
#endif
diff --git a/backends/platform/iphone/iphone_keyboard.h b/backends/platform/iphone/iphone_keyboard.h
index eecad09398..2d1238c92f 100644
--- a/backends/platform/iphone/iphone_keyboard.h
+++ b/backends/platform/iphone/iphone_keyboard.h
@@ -20,17 +20,22 @@
*
*/
-#import <UIKit/UIKit.h>
-#import <UIKit/UITextView.h>
+#ifndef BACKENDS_PLATFORM_IPHONE_IPHONE_KEYBOARD_H
+#define BACKENDS_PLATFORM_IPHONE_IPHONE_KEYBOARD_H
+
+#include <UIKit/UIKit.h>
+#include <UIKit/UITextView.h>
@interface SoftKeyboard : UIView {
id inputDelegate;
- UITextView* inputView;
+ UITextView *inputView;
}
- (id)initWithFrame:(CGRect)frame;
-- (UITextView*)inputView;
+- (UITextView *)inputView;
- (void)setInputDelegate:(id)delegate;
- (void)handleKeyPress:(unichar)c;
@end
+
+#endif
diff --git a/backends/platform/iphone/iphone_keyboard.m b/backends/platform/iphone/iphone_keyboard.mm
index 1624d02977..b00930ab31 100644
--- a/backends/platform/iphone/iphone_keyboard.m
+++ b/backends/platform/iphone/iphone_keyboard.mm
@@ -20,7 +20,7 @@
*
*/
-#import "iphone_keyboard.h"
+#include "iphone_keyboard.h"
@interface UITextInputTraits
- (void)setAutocorrectionType:(int)type;
@@ -29,17 +29,17 @@
@end
@interface TextInputHandler : UITextView {
- SoftKeyboard* softKeyboard;
+ SoftKeyboard *softKeyboard;
}
-- (id)initWithKeyboard:(SoftKeyboard*)keyboard;
+- (id)initWithKeyboard:(SoftKeyboard *)keyboard;
@end
@implementation TextInputHandler
-- (id)initWithKeyboard:(SoftKeyboard*)keyboard; {
+- (id)initWithKeyboard:(SoftKeyboard *)keyboard; {
self = [super initWithFrame:CGRectMake(0.0f, 0.0f, 0.0f, 0.0f)];
softKeyboard = keyboard;
@@ -80,7 +80,7 @@
return self;
}
-- (UITextView*)inputView {
+- (UITextView *)inputView {
return inputView;
}
diff --git a/backends/platform/iphone/iphone_main.m b/backends/platform/iphone/iphone_main.mm
index c2ec328bf5..e76ffe866e 100644
--- a/backends/platform/iphone/iphone_main.m
+++ b/backends/platform/iphone/iphone_main.mm
@@ -20,38 +20,41 @@
*
*/
-#import <UIKit/UIKit.h>
-#import <Foundation/NSThread.h>
+// Disable symbol overrides so that we can use system headers.
+#define FORBIDDEN_SYMBOL_ALLOW_ALL
+
+#include <UIKit/UIKit.h>
+#include <Foundation/NSThread.h>
#include "iphone_video.h"
void iphone_main(int argc, char *argv[]);
@interface iPhoneMain : UIApplication {
- UIWindow* _window;
- iPhoneView* _view;
+ UIWindow *_window;
+ iPhoneView *_view;
}
-- (void) mainLoop: (id)param;
-- (iPhoneView*) getView;
-- (UIWindow*) getWindow;
+- (void)mainLoop:(id)param;
+- (iPhoneView *)getView;
+- (UIWindow *)getWindow;
- (void)didRotate:(NSNotification *)notification;
@end
-static int gArgc;
-static char** gArgv;
+static int g_argc;
+static char **g_argv;
-int main(int argc, char** argv) {
- gArgc = argc;
- gArgv = argv;
+int main(int argc, char **argv) {
+ g_argc = argc;
+ g_argv = argv;
- NSAutoreleasePool *autoreleasePool = [
- [ NSAutoreleasePool alloc ] init
- ];
+ NSAutoreleasePool *autoreleasePool = [
+ [NSAutoreleasePool alloc] init
+ ];
- int returnCode = UIApplicationMain(argc, argv, @"iPhoneMain", @"iPhoneMain");
- [ autoreleasePool release ];
- return returnCode;
+ int returnCode = UIApplicationMain(argc, argv, @"iPhoneMain", @"iPhoneMain");
+ [autoreleasePool release];
+ return returnCode;
}
@implementation iPhoneMain
@@ -63,14 +66,14 @@ int main(int argc, char** argv) {
return self;
}
-- (void) mainLoop: (id)param {
+- (void)mainLoop:(id)param {
[[NSAutoreleasePool alloc] init];
- iphone_main(gArgc, gArgv);
+ iphone_main(g_argc, g_argv);
exit(0);
}
-- (iPhoneView*) getView {
+- (iPhoneView *)getView {
return _view;
}
@@ -78,38 +81,36 @@ int main(int argc, char** argv) {
CGRect rect = [[UIScreen mainScreen] bounds];
// hide the status bar
- [application setStatusBarStyle:UIStatusBarStyleBlackTranslucent animated:NO];
- [application setStatusBarHidden:YES animated:YES];
+ [application setStatusBarStyle:UIStatusBarStyleBlackTranslucent animated:NO];
+ [application setStatusBarHidden:YES animated:YES];
_window = [[UIWindow alloc] initWithFrame:rect];
[_window retain];
- _view = [[iPhoneView alloc] initWithFrame: rect];
+ _view = [[iPhoneView alloc] initWithFrame:rect];
_view.multipleTouchEnabled = YES;
- [_window setContentView: _view];
+ [_window setContentView:_view];
[_window addSubview:_view];
[_window makeKeyAndVisible];
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
[[NSNotificationCenter defaultCenter] addObserver:self
- selector:@selector(didRotate:)
- name:@"UIDeviceOrientationDidChangeNotification" object:nil];
+ selector:@selector(didRotate:)
+ name:@"UIDeviceOrientationDidChangeNotification"
+ object:nil];
[NSThread detachNewThreadSelector:@selector(mainLoop:) toTarget:self withObject:nil];
}
-- (void)applicationDidResume
-{
+- (void)applicationDidResume {
}
-- (void)applicationWillSuspend
-{
+- (void)applicationWillSuspend {
}
-- (void)applicationWillTerminate
-{
+- (void)applicationWillTerminate {
}
- (void)applicationSuspend:(struct __GSEvent *)event {
@@ -122,14 +123,14 @@ int main(int argc, char** argv) {
// Workaround, need to "hide" and unhide the statusbar to properly remove it,
// since the Springboard has put it back without apparently flagging our application.
- [self setStatusBarHidden:YES animated:YES];
- [self setStatusBarStyle:UIStatusBarStyleBlackTranslucent animated:NO];
- [self setStatusBarHidden:YES animated:YES];
+ [self setStatusBarHidden:YES animated:YES];
+ [self setStatusBarStyle:UIStatusBarStyleBlackTranslucent animated:NO];
+ [self setStatusBarHidden:YES animated:YES];
}
- (void)didRotate:(NSNotification *)notification {
- int screenOrientation = [[UIDevice currentDevice] orientation];
- [_view deviceOrientationChanged: screenOrientation];
+ UIDeviceOrientation screenOrientation = [[UIDevice currentDevice] orientation];
+ [_view deviceOrientationChanged:screenOrientation];
}
- (UIWindow*) getWindow {
diff --git a/backends/platform/iphone/iphone_video.h b/backends/platform/iphone/iphone_video.h
index 223f025978..1405fe35f1 100644
--- a/backends/platform/iphone/iphone_video.h
+++ b/backends/platform/iphone/iphone_video.h
@@ -20,48 +20,69 @@
*
*/
-#ifndef _IPHONE_VIDEO__H
-#define _IPHONE_VIDEO__H
+#ifndef BACKENDS_PLATFORM_IPHONE_IPHONE_VIDEO_H
+#define BACKENDS_PLATFORM_IPHONE_IPHONE_VIDEO_H
-#import <UIKit/UIKit.h>
-#import <Foundation/Foundation.h>
-#import <QuartzCore/QuartzCore.h>
+#include <UIKit/UIKit.h>
+#include <Foundation/Foundation.h>
+#include <QuartzCore/QuartzCore.h>
-#import <OpenGLES/EAGL.h>
-#import <OpenGLES/ES1/gl.h>
-#import <OpenGLES/ES1/glext.h>
+#include <OpenGLES/EAGL.h>
+#include <OpenGLES/ES1/gl.h>
+#include <OpenGLES/ES1/glext.h>
-#import "iphone_keyboard.h"
+#include "iphone_keyboard.h"
+#include "iphone_common.h"
-@interface iPhoneView : UIView
-{
- void* _screenSurface;
- NSMutableArray* _events;
- SoftKeyboard* _keyboardView;
- CALayer* _screenLayer;
+@interface iPhoneView : UIView {
+ VideoContext _videoContext;
- int _widthOffset;
- int _heightOffset;
+ NSMutableArray *_events;
+ SoftKeyboard *_keyboardView;
- EAGLContext* _context;
+ EAGLContext *_context;
GLuint _viewRenderbuffer;
GLuint _viewFramebuffer;
- GLint _backingWidth;
- GLint _backingHeight;
- GLint _visibleWidth;
- GLint _visibleHeight;
GLuint _screenTexture;
GLuint _overlayTexture;
GLuint _mouseCursorTexture;
+
+ UIDeviceOrientation _orientation;
+
+ GLint _renderBufferWidth;
+ GLint _renderBufferHeight;
+
+ GLfloat _gameScreenVertCoords[4 * 2];
+ GLfloat _gameScreenTexCoords[4 * 2];
+ CGRect _gameScreenRect;
+
+ GLfloat _overlayVertCoords[4 * 2];
+ GLfloat _overlayTexCoords[4 * 2];
+ CGRect _overlayRect;
+
+ GLfloat _mouseVertCoords[4 * 2];
+ GLfloat _mouseTexCoords[4 * 2];
+ GLint _mouseHotspotX, _mouseHotspotY;
+ GLint _mouseWidth, _mouseHeight;
+ GLfloat _mouseScaleX, _mouseScaleY;
+
+ int _scaledShakeOffsetY;
+
+ UITouch *_firstTouch;
+ UITouch *_secondTouch;
}
- (id)initWithFrame:(struct CGRect)frame;
-- (void)drawRect:(CGRect)frame;
+- (VideoContext *)getVideoContext;
-- (void *)getSurface;
+- (void)drawRect:(CGRect)frame;
+- (void)createScreenTexture;
- (void)initSurface;
+- (void)setViewTransformation;
+
+- (void)setGraphicsMode;
- (void)updateSurface;
- (void)updateMainSurface;
@@ -69,11 +90,13 @@
- (void)updateMouseSurface;
- (void)clearColorBuffer;
--(void)updateMouseCursor;
+- (void)notifyMouseMove;
+- (void)updateMouseCursorScaling;
+- (void)updateMouseCursor;
- (id)getEvent;
-- (void)deviceOrientationChanged:(int)orientation;
+- (void)deviceOrientationChanged:(UIDeviceOrientation)orientation;
- (void)applicationSuspend;
@@ -81,6 +104,6 @@
@end
+extern iPhoneView *g_iPhoneViewInstance;
-
-#endif /* _IPHONE_VIDEO__H */
+#endif
diff --git a/backends/platform/iphone/iphone_video.m b/backends/platform/iphone/iphone_video.m
deleted file mode 100644
index eb16676428..0000000000
--- a/backends/platform/iphone/iphone_video.m
+++ /dev/null
@@ -1,756 +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 "iphone_video.h"
-#include "iphone_common.h"
-
-static iPhoneView *sharedInstance = nil;
-static int _width = 0;
-static int _height = 0;
-static int _fullWidth;
-static int _fullHeight;
-static CGRect _screenRect;
-
-static char* _textureBuffer = 0;
-static int _textureWidth = 0;
-static int _textureHeight = 0;
-
-static char* _overlayTexBuffer = 0;
-static int _overlayTexWidth = 0;
-static int _overlayTexHeight = 0;
-static int _overlayWidth = 0;
-static int _overlayHeight = 0;
-static float _overlayPortraitRatio = 1.0f;
-
-NSLock* _lock = nil;
-static int _needsScreenUpdate = 0;
-static int _overlayIsEnabled = 0;
-
-static UITouch* _firstTouch = NULL;
-static UITouch* _secondTouch = NULL;
-
-static short* _mouseCursor = NULL;
-static int _mouseCursorHeight = 0;
-static int _mouseCursorWidth = 0;
-static int _mouseX = 0;
-static int _mouseY = 0;
-
-// static long lastTick = 0;
-// static int frames = 0;
-
-#define printOpenGLError() printOglError(__FILE__, __LINE__)
-
-int printOglError(const char *file, int line)
-{
- int retCode = 0;
-
- // returns 1 if an OpenGL error occurred, 0 otherwise.
- GLenum glErr = glGetError();
- while( glErr != GL_NO_ERROR)
- {
- fprintf(stderr, "glError: %u (%s: %d)\n", glErr, file, line );
- retCode = 1;
- glErr = glGetError();
- }
- return retCode;
-}
-
-void iPhone_setMouseCursor(short* buffer, int width, int height) {
- _mouseCursor = buffer;
-
- _mouseCursorWidth = width;
- _mouseCursorHeight = height;
-
- [sharedInstance performSelectorOnMainThread:@selector(updateMouseCursor) withObject:nil waitUntilDone: YES];
-}
-
-void iPhone_enableOverlay(int state) {
- _overlayIsEnabled = state;
-
- [sharedInstance performSelectorOnMainThread:@selector(clearColorBuffer) withObject:nil waitUntilDone: YES];
-}
-
-int iPhone_getScreenHeight() {
- return _overlayHeight;
-}
-
-int iPhone_getScreenWidth() {
- return _overlayWidth;
-}
-
-bool iPhone_isHighResDevice() {
- return _fullHeight > 480;
-}
-
-void iPhone_updateScreen(int mouseX, int mouseY) {
- //printf("Mouse: (%i, %i)\n", mouseX, mouseY);
-
- //_mouseX = _overlayHeight - (float)mouseX / _width * _overlayHeight;
- //_mouseY = (float)mouseY / _height * _overlayWidth;
-
- //_mouseX = _overlayHeight - mouseX;
- //_mouseY = mouseY;
-
- _mouseX = (_overlayWidth - mouseX) / (float)_overlayWidth * _overlayHeight;
- _mouseY = mouseY / (float)_overlayHeight * _overlayWidth;
-
- if (!_needsScreenUpdate) {
- _needsScreenUpdate = 1;
- [sharedInstance performSelectorOnMainThread:@selector(updateSurface) withObject:nil waitUntilDone: NO];
- }
-}
-
-void iPhone_updateScreenRect(unsigned short* screen, int x1, int y1, int x2, int y2) {
- int y;
- for (y = y1; y < y2; ++y)
- memcpy(&_textureBuffer[(y * _textureWidth + x1 )* 2], &screen[y * _width + x1], (x2 - x1) * 2);
-}
-
-void iPhone_updateOverlayRect(unsigned short* screen, int x1, int y1, int x2, int y2) {
- int y;
- //printf("Overlaywidth: %u, fullwidth %u\n", _overlayWidth, _fullWidth);
- for (y = y1; y < y2; ++y)
- memcpy(&_overlayTexBuffer[(y * _overlayTexWidth + x1 )* 2], &screen[y * _overlayWidth + x1], (x2 - x1) * 2);
-}
-
-void iPhone_initSurface(int width, int height) {
- _width = width;
- _height = height;
- [sharedInstance performSelectorOnMainThread:@selector(initSurface) withObject:nil waitUntilDone: YES];
-}
-
-bool iPhone_fetchEvent(int *outEvent, float *outX, float *outY) {
- id event = [sharedInstance getEvent];
- if (event == nil) {
- return false;
- }
-
- id type = [event objectForKey:@"type"];
-
- if (type == nil) {
- printf("fetchEvent says: No type!\n");
- return false;
- }
-
- *outEvent = [type intValue];
- *outX = [[event objectForKey:@"x"] floatValue];
- *outY = [[event objectForKey:@"y"] floatValue];
- return true;
-}
-
-uint getSizeNextPOT(uint size) {
- if ((size & (size - 1)) || !size) {
- int log = 0;
-
- while (size >>= 1)
- ++log;
-
- size = (2 << log);
- }
-
- return size;
-}
-
-const char* iPhone_getDocumentsDir() {
- NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
- NSString *documentsDirectory = [paths objectAtIndex:0];
- return [documentsDirectory UTF8String];
-}
-
-bool getLocalMouseCoords(CGPoint *point) {
- if (_overlayIsEnabled) {
- point->x = point->x / _overlayHeight;
- point->y = point->y / _overlayWidth;
- } else {
- if (point->x < _screenRect.origin.x || point->x >= _screenRect.origin.x + _screenRect.size.width ||
- point->y < _screenRect.origin.y || point->y >= _screenRect.origin.y + _screenRect.size.height) {
- return false;
- }
-
- point->x = (point->x - _screenRect.origin.x) / _screenRect.size.width;
- point->y = (point->y - _screenRect.origin.y) / _screenRect.size.height;
- }
-
- return true;
-}
-
-
-@implementation iPhoneView
-
-+ (Class) layerClass
-{
- return [CAEAGLLayer class];
-}
-
-- (id)initWithFrame:(struct CGRect)frame {
- self = [super initWithFrame: frame];
-
- if([[UIScreen mainScreen] respondsToSelector: NSSelectorFromString(@"scale")])
- {
- if([self respondsToSelector: NSSelectorFromString(@"contentScaleFactor")])
- {
- //self.contentScaleFactor = [[UIScreen mainScreen] scale];
- }
- }
-
- _fullWidth = frame.size.width;
- _fullHeight = frame.size.height;
- _screenLayer = nil;
-
- sharedInstance = self;
-
- _lock = [NSLock new];
- _keyboardView = nil;
- _context = nil;
- _screenTexture = 0;
- _overlayTexture = 0;
- _mouseCursorTexture = 0;
-
- return self;
-}
-
--(void) dealloc {
- [super dealloc];
-
- if (_keyboardView != nil) {
- [_keyboardView dealloc];
- }
-
- if (_screenTexture)
- free(_textureBuffer);
-
- free(_overlayTexBuffer);
-}
-
-- (void *)getSurface {
- return _screenSurface;
-}
-
-- (void)drawRect:(CGRect)frame {
- // if (lastTick == 0) {
- // lastTick = time(0);
- // }
- //
- // frames++;
- // if (time(0) > lastTick) {
- // lastTick = time(0);
- // printf("FPS: %i\n", frames);
- // frames = 0;
- // }
-}
-
-- (void)updateSurface {
- if (!_needsScreenUpdate) {
- return;
- }
- _needsScreenUpdate = 0;
-
- if (_overlayIsEnabled) {
- glClear(GL_COLOR_BUFFER_BIT); printOpenGLError();
- }
-
- [self updateMainSurface];
-
- if (_overlayIsEnabled) {
- [self updateOverlaySurface];
- [self updateMouseSurface];
- }
-
- glBindRenderbufferOES(GL_RENDERBUFFER_OES, _viewRenderbuffer); printOpenGLError();
- [_context presentRenderbuffer:GL_RENDERBUFFER_OES];
-
-}
-
--(void)updateMouseCursor {
- if (_mouseCursorTexture == 0) {
- glGenTextures(1, &_mouseCursorTexture); printOpenGLError();
- glBindTexture(GL_TEXTURE_2D, _mouseCursorTexture); printOpenGLError();
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); printOpenGLError();
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); printOpenGLError();
- }
-
- glBindTexture(GL_TEXTURE_2D, _mouseCursorTexture); printOpenGLError();
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, getSizeNextPOT(_mouseCursorWidth), getSizeNextPOT(_mouseCursorHeight), 0, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, _mouseCursor); printOpenGLError();
-
- free(_mouseCursor);
- _mouseCursor = NULL;
-}
-
-- (void)updateMainSurface {
- GLfloat vertices[] = {
- 0.0f + _heightOffset, 0.0f + _widthOffset,
- _visibleWidth - _heightOffset, 0.0f + _widthOffset,
- 0.0f + _heightOffset, _visibleHeight - _widthOffset,
- _visibleWidth - _heightOffset, _visibleHeight - _widthOffset
- };
-
- float texWidth = _width / (float)_textureWidth;
- float texHeight = _height / (float)_textureHeight;
-
- const GLfloat texCoords[] = {
- texWidth, 0.0f,
- 0.0f, 0.0f,
- texWidth, texHeight,
- 0.0f, texHeight
- };
-
- glVertexPointer(2, GL_FLOAT, 0, vertices); printOpenGLError();
- glTexCoordPointer(2, GL_FLOAT, 0, texCoords); printOpenGLError();
-
- glBindTexture(GL_TEXTURE_2D, _screenTexture); printOpenGLError();
-
- // Unfortunately we have to update the whole texture every frame, since glTexSubImage2D is actually slower in all cases
- // due to the iPhone internals having to convert the whole texture back from its internal format when used.
- // In the future we could use several tiled textures instead.
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, _textureWidth, _textureHeight, 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, _textureBuffer); printOpenGLError();
- glDisable(GL_BLEND);
- glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); printOpenGLError();
-}
-
-- (void)updateOverlaySurface {
- GLfloat vertices[] = {
- 0.0f, 0.0f,
- _overlayHeight, 0.0f,
- 0.0f, _overlayWidth * _overlayPortraitRatio,
- _overlayHeight, _overlayWidth * _overlayPortraitRatio
- };
-
- float texWidth = _overlayWidth / (float)_overlayTexWidth;
- float texHeight = _overlayHeight / (float)_overlayTexHeight;
-
- const GLfloat texCoords[] = {
- texWidth, 0.0f,
- 0.0f, 0.0f,
- texWidth, texHeight,
- 0.0f, texHeight
- };
-
- glVertexPointer(2, GL_FLOAT, 0, vertices); printOpenGLError();
- glTexCoordPointer(2, GL_FLOAT, 0, texCoords); printOpenGLError();
-
- glBindTexture(GL_TEXTURE_2D, _overlayTexture); printOpenGLError();
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, _overlayTexWidth, _overlayTexHeight, 0, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, _overlayTexBuffer); printOpenGLError();
- glEnable(GL_BLEND);
- glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); printOpenGLError();
-}
-
-- (void)updateMouseSurface {
-
- int width = _mouseCursorWidth / (float)_backingWidth * _backingHeight;
- int height = _mouseCursorHeight / (float)_backingHeight * _backingWidth;
-
- GLfloat vertices[] = {
- _mouseX, _mouseY,
- _mouseX + height, _mouseY,
- _mouseX, _mouseY + width,
- _mouseX + height, _mouseY + width
- };
-
- //printf("Cursor: width %u height %u\n", _mouseCursorWidth, _mouseCursorHeight);
-
- float texWidth = _mouseCursorWidth / (float)getSizeNextPOT(_mouseCursorWidth);
- float texHeight = _mouseCursorHeight / (float)getSizeNextPOT(_mouseCursorHeight);
-
- const GLfloat texCoords[] = {
- texWidth, 0.0f,
- 0.0f, 0.0f,
- texWidth, texHeight,
- 0.0f, texHeight
- };
-
- glVertexPointer(2, GL_FLOAT, 0, vertices); printOpenGLError();
- glTexCoordPointer(2, GL_FLOAT, 0, texCoords); printOpenGLError();
-
- glBindTexture(GL_TEXTURE_2D, _mouseCursorTexture); printOpenGLError();
- glEnable(GL_BLEND);
- glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); printOpenGLError();
-}
-
-- (void)initSurface {
- _textureWidth = getSizeNextPOT(_width);
- _textureHeight = getSizeNextPOT(_height);
-
- UIDeviceOrientation orientation = [[UIDevice currentDevice] orientation];
-
- //printf("Window: (%d, %d), Surface: (%d, %d), Texture(%d, %d)\n", _fullWidth, _fullHeight, _width, _height, _textureWidth, _textureHeight);
-
- if (_context == nil) {
- orientation = UIDeviceOrientationLandscapeRight;
- CAEAGLLayer *eaglLayer = (CAEAGLLayer*) self.layer;
-
- eaglLayer.opaque = YES;
- eaglLayer.drawableProperties = [NSDictionary dictionaryWithObjectsAndKeys:
- [NSNumber numberWithBool:FALSE], kEAGLDrawablePropertyRetainedBacking, kEAGLColorFormatRGB565, kEAGLDrawablePropertyColorFormat, nil];
-
- _context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES1];
- if (!_context || [EAGLContext setCurrentContext:_context]) {
- glGenFramebuffersOES(1, &_viewFramebuffer); printOpenGLError();
- glGenRenderbuffersOES(1, &_viewRenderbuffer); printOpenGLError();
-
- glBindFramebufferOES(GL_FRAMEBUFFER_OES, _viewFramebuffer); printOpenGLError();
- glBindRenderbufferOES(GL_RENDERBUFFER_OES, _viewRenderbuffer); printOpenGLError();
- [_context renderbufferStorage:GL_RENDERBUFFER_OES fromDrawable:(id<EAGLDrawable>)self.layer];
- glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, _viewRenderbuffer); printOpenGLError();
-
- glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_WIDTH_OES, &_backingWidth); printOpenGLError();
- glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_HEIGHT_OES, &_backingHeight); printOpenGLError();
-
- if (glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES) != GL_FRAMEBUFFER_COMPLETE_OES) {
- NSLog(@"Failed to make complete framebuffer object %x.", glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES));
- return;
- }
-
- _overlayHeight = _backingWidth;
- _overlayWidth = _backingHeight;
- _overlayTexWidth = getSizeNextPOT(_overlayHeight);
- _overlayTexHeight = getSizeNextPOT(_overlayWidth);
-
- int textureSize = _overlayTexWidth * _overlayTexHeight * 2;
- _overlayTexBuffer = (char *)malloc(textureSize);
- memset(_overlayTexBuffer, 0, textureSize);
-
- glViewport(0, 0, _backingWidth, _backingHeight); printOpenGLError();
- glClearColor(0.0f, 0.0f, 0.0f, 1.0f); printOpenGLError();
-
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
-
- glEnable(GL_TEXTURE_2D); printOpenGLError();
- glEnableClientState(GL_TEXTURE_COORD_ARRAY); printOpenGLError();
- glEnableClientState(GL_VERTEX_ARRAY); printOpenGLError();
- }
- }
-
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
-
- if (orientation == UIDeviceOrientationLandscapeRight) {
- glRotatef(-90, 0, 0, 1); printOpenGLError();
- } else if (orientation == UIDeviceOrientationLandscapeLeft) {
- glRotatef(90, 0, 0, 1); printOpenGLError();
- } else {
- glRotatef(180, 0, 0, 1); printOpenGLError();
- }
-
- glOrthof(0, _backingWidth, 0, _backingHeight, 0, 1); printOpenGLError();
-
- if (_screenTexture > 0) {
- glDeleteTextures(1, &_screenTexture); printOpenGLError();
- }
-
- glGenTextures(1, &_screenTexture); printOpenGLError();
- glBindTexture(GL_TEXTURE_2D, _screenTexture); printOpenGLError();
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); printOpenGLError();
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); printOpenGLError();
-
- if (_overlayTexture > 0) {
- glDeleteTextures(1, &_overlayTexture); printOpenGLError();
- }
-
- glGenTextures(1, &_overlayTexture); printOpenGLError();
- glBindTexture(GL_TEXTURE_2D, _overlayTexture); printOpenGLError();
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); printOpenGLError();
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); printOpenGLError();
-
- if (_textureBuffer) {
- free(_textureBuffer);
- }
-
- int textureSize = _textureWidth * _textureHeight * 2;
- _textureBuffer = (char*)malloc(textureSize);
- memset(_textureBuffer, 0, textureSize);
-
- glBindRenderbufferOES(GL_RENDERBUFFER_OES, _viewRenderbuffer); printOpenGLError();
-
- [self clearColorBuffer];
-
- if (_keyboardView != nil) {
- [_keyboardView removeFromSuperview];
- [[_keyboardView inputView] removeFromSuperview];
- }
-
- if (orientation == UIDeviceOrientationLandscapeLeft || orientation == UIDeviceOrientationLandscapeRight) {
- _visibleHeight = _backingHeight;
- _visibleWidth = _backingWidth;
-
- float ratioDifference = ((float)_height / (float)_width) / ((float)_fullWidth / (float)_fullHeight);
- int rectWidth, rectHeight;
- if (ratioDifference < 1.0f) {
- rectWidth = _fullWidth * ratioDifference;
- rectHeight = _fullHeight;
- _widthOffset = (_fullWidth - rectWidth) / 2;
- _heightOffset = 0;
- } else {
- rectWidth = _fullWidth;
- rectHeight = _fullHeight / ratioDifference;
- _heightOffset = (_fullHeight - rectHeight) / 2;
- _widthOffset = 0;
- }
-
- //printf("Rect: %i, %i, %i, %i\n", _widthOffset, _heightOffset, rectWidth, rectHeight);
- _screenRect = CGRectMake(_widthOffset, _heightOffset, rectWidth, rectHeight);
- _overlayPortraitRatio = 1.0f;
- } else {
- float ratio = (float)_height / (float)_width;
- int height = _fullWidth * ratio;
- //printf("Making rect (%u, %u)\n", _fullWidth, height);
- _screenRect = CGRectMake(0, 0, _fullWidth - 1, height - 1);
-
- _visibleHeight = height;
- _visibleWidth = _backingWidth;
- _heightOffset = 0.0f;
- _widthOffset = 0.0f;
-
- CGRect keyFrame = CGRectMake(0.0f, 0.0f, 0.0f, 0.0f);
- if (_keyboardView == nil) {
- _keyboardView = [[SoftKeyboard alloc] initWithFrame:keyFrame];
- [_keyboardView setInputDelegate:self];
- }
-
- [self addSubview:[_keyboardView inputView]];
- [self addSubview: _keyboardView];
- [[_keyboardView inputView] becomeFirstResponder];
- _overlayPortraitRatio = (_overlayHeight * ratio) / _overlayWidth;
- }
-}
-
-- (void)clearColorBuffer {
- // The color buffer is triple-buffered, so we clear it multiple times right away to avid doing any glClears later.
- int clearCount = 5;
- while (clearCount-- > 0) {
- glClear(GL_COLOR_BUFFER_BIT); printOpenGLError();
- [_context presentRenderbuffer:GL_RENDERBUFFER_OES];
- }
-}
-
-- (id)getEvent {
- if (_events == nil || [_events count] == 0) {
- return nil;
- }
-
-
- id event = [_events objectAtIndex: 0];
-
- [_events removeObjectAtIndex: 0];
-
- return event;
-}
-
-- (void)addEvent:(NSDictionary*)event {
-
- if (_events == nil)
- _events = [[NSMutableArray alloc] init];
-
- [_events addObject: event];
-}
-
-- (void)deviceOrientationChanged:(int)orientation {
- [self addEvent:
- [[NSDictionary alloc] initWithObjectsAndKeys:
- [NSNumber numberWithInt:kInputOrientationChanged], @"type",
- [NSNumber numberWithFloat:(float)orientation], @"x",
- [NSNumber numberWithFloat:0], @"y",
- nil
- ]
- ];
-}
-
-- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
-{
- NSSet *allTouches = [event allTouches];
-
- switch ([allTouches count]) {
- case 1:
- {
- UITouch *touch = [touches anyObject];
- CGPoint point = [touch locationInView:self];
- if (!getLocalMouseCoords(&point))
- return;
-
- _firstTouch = touch;
- [self addEvent:
- [[NSDictionary alloc] initWithObjectsAndKeys:
- [NSNumber numberWithInt:kInputMouseDown], @"type",
- [NSNumber numberWithFloat:point.x], @"x",
- [NSNumber numberWithFloat:point.y], @"y",
- nil
- ]
- ];
- break;
- }
- case 2:
- {
- UITouch *touch = [touches anyObject];
- CGPoint point = [touch locationInView:self];
- if (!getLocalMouseCoords(&point))
- return;
-
- _secondTouch = touch;
- [self addEvent:
- [[NSDictionary alloc] initWithObjectsAndKeys:
- [NSNumber numberWithInt:kInputMouseSecondDown], @"type",
- [NSNumber numberWithFloat:point.x], @"x",
- [NSNumber numberWithFloat:point.y], @"y",
- nil
- ]
- ];
- break;
- }
- }
-}
-
-- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
-{
- //NSSet *allTouches = [event allTouches];
-
- for (UITouch* touch in touches) {
- if (touch == _firstTouch) {
-
- CGPoint point = [touch locationInView:self];
- if (!getLocalMouseCoords(&point))
- return;
-
- [self addEvent:
- [[NSDictionary alloc] initWithObjectsAndKeys:
- [NSNumber numberWithInt:kInputMouseDragged], @"type",
- [NSNumber numberWithFloat:point.x], @"x",
- [NSNumber numberWithFloat:point.y], @"y",
- nil
- ]
- ];
-
- } else if (touch == _secondTouch) {
-
- CGPoint point = [touch locationInView:self];
- if (!getLocalMouseCoords(&point))
- return;
-
- [self addEvent:
- [[NSDictionary alloc] initWithObjectsAndKeys:
- [NSNumber numberWithInt:kInputMouseSecondDragged], @"type",
- [NSNumber numberWithFloat:point.x], @"x",
- [NSNumber numberWithFloat:point.y], @"y",
- nil
- ]
- ];
-
- }
- }
-}
-
-- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
-{
- NSSet *allTouches = [event allTouches];
-
- switch ([allTouches count]) {
- case 1:
- {
- UITouch *touch = [[allTouches allObjects] objectAtIndex:0];
- CGPoint point = [touch locationInView:self];
- if (!getLocalMouseCoords(&point))
- return;
-
- [self addEvent:
- [[NSDictionary alloc] initWithObjectsAndKeys:
- [NSNumber numberWithInt:kInputMouseUp], @"type",
- [NSNumber numberWithFloat:point.x], @"x",
- [NSNumber numberWithFloat:point.y], @"y",
- nil
- ]
- ];
- break;
- }
- case 2:
- {
- UITouch *touch = [[allTouches allObjects] objectAtIndex:1];
- CGPoint point = [touch locationInView:self];
- if (!getLocalMouseCoords(&point))
- return;
-
- [self addEvent:
- [[NSDictionary alloc] initWithObjectsAndKeys:
- [NSNumber numberWithInt:kInputMouseSecondUp], @"type",
- [NSNumber numberWithFloat:point.x], @"x",
- [NSNumber numberWithFloat:point.y], @"y",
- nil
- ]
- ];
- break;
- }
- }
-}
-
-- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
-{
-
-}
-
-- (void)handleKeyPress:(unichar)c {
- [self addEvent:
- [[NSDictionary alloc] initWithObjectsAndKeys:
- [NSNumber numberWithInt:kInputKeyPressed], @"type",
- [NSNumber numberWithFloat:(float)c], @"x",
- [NSNumber numberWithFloat:0], @"y",
- nil
- ]
- ];
-}
-
-- (BOOL)canHandleSwipes {
- return TRUE;
-}
-
-- (int)swipe:(int)num withEvent:(struct __GSEvent *)event {
- //printf("swipe: %i\n", num);
-
- [self addEvent:
- [[NSDictionary alloc] initWithObjectsAndKeys:
- [NSNumber numberWithInt:kInputSwipe], @"type",
- [NSNumber numberWithFloat:(float)num], @"x",
- [NSNumber numberWithFloat:0], @"y",
- nil
- ]
- ];
-}
-
-- (void)applicationSuspend {
- [self addEvent:
- [[NSDictionary alloc] initWithObjectsAndKeys:
- [NSNumber numberWithInt:kInputApplicationSuspended], @"type",
- [NSNumber numberWithFloat:0], @"x",
- [NSNumber numberWithFloat:0], @"y",
- nil
- ]
- ];
-}
-
-- (void)applicationResume {
- [self addEvent:
- [[NSDictionary alloc] initWithObjectsAndKeys:
- [NSNumber numberWithInt:kInputApplicationResumed], @"type",
- [NSNumber numberWithFloat:0], @"x",
- [NSNumber numberWithFloat:0], @"y",
- nil
- ]
- ];
-}
-
-@end
diff --git a/backends/platform/iphone/iphone_video.mm b/backends/platform/iphone/iphone_video.mm
new file mode 100644
index 0000000000..5b78237ff7
--- /dev/null
+++ b/backends/platform/iphone/iphone_video.mm
@@ -0,0 +1,851 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+// Disable symbol overrides so that we can use system headers.
+#define FORBIDDEN_SYMBOL_ALLOW_ALL
+
+#include "iphone_video.h"
+
+#include "graphics/colormasks.h"
+
+iPhoneView *g_iPhoneViewInstance = nil;
+static int g_fullWidth;
+static int g_fullHeight;
+
+static int g_needsScreenUpdate = 0;
+
+#if 0
+static long g_lastTick = 0;
+static int g_frames = 0;
+#endif
+
+#define printOpenGLError() printOglError(__FILE__, __LINE__)
+
+int printOglError(const char *file, int line) {
+ int retCode = 0;
+
+ // returns 1 if an OpenGL error occurred, 0 otherwise.
+ GLenum glErr = glGetError();
+ while (glErr != GL_NO_ERROR) {
+ fprintf(stderr, "glError: %u (%s: %d)\n", glErr, file, line);
+ retCode = 1;
+ glErr = glGetError();
+ }
+ return retCode;
+}
+
+bool iPhone_isHighResDevice() {
+ return g_fullHeight > 480;
+}
+
+void iPhone_updateScreen() {
+ //printf("Mouse: (%i, %i)\n", mouseX, mouseY);
+ if (!g_needsScreenUpdate) {
+ g_needsScreenUpdate = 1;
+ [g_iPhoneViewInstance performSelectorOnMainThread:@selector(updateSurface) withObject:nil waitUntilDone: NO];
+ }
+}
+
+bool iPhone_fetchEvent(int *outEvent, int *outX, int *outY) {
+ id event = [g_iPhoneViewInstance getEvent];
+ if (event == nil) {
+ return false;
+ }
+
+ id type = [event objectForKey:@"type"];
+
+ if (type == nil) {
+ printf("fetchEvent says: No type!\n");
+ return false;
+ }
+
+ *outEvent = [type intValue];
+ *outX = [[event objectForKey:@"x"] intValue];
+ *outY = [[event objectForKey:@"y"] intValue];
+ return true;
+}
+
+uint getSizeNextPOT(uint size) {
+ if ((size & (size - 1)) || !size) {
+ int log = 0;
+
+ while (size >>= 1)
+ ++log;
+
+ size = (2 << log);
+ }
+
+ return size;
+}
+
+const char *iPhone_getDocumentsDir() {
+ NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
+ NSString *documentsDirectory = [paths objectAtIndex:0];
+ return [documentsDirectory UTF8String];
+}
+
+@implementation iPhoneView
+
++ (Class)layerClass {
+ return [CAEAGLLayer class];
+}
+
+- (VideoContext *)getVideoContext {
+ return &_videoContext;
+}
+
+- (void)createContext {
+ CAEAGLLayer *eaglLayer = (CAEAGLLayer *)self.layer;
+
+ eaglLayer.opaque = YES;
+ eaglLayer.drawableProperties = [NSDictionary dictionaryWithObjectsAndKeys:
+ [NSNumber numberWithBool:FALSE], kEAGLDrawablePropertyRetainedBacking, kEAGLColorFormatRGB565, kEAGLDrawablePropertyColorFormat, nil];
+
+ _context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES1];
+
+ // In case creating the OpenGL ES context failed, we will error out here.
+ if (_context == nil) {
+ fprintf(stderr, "Could not create OpenGL ES context\n");
+ exit(-1);
+ }
+
+ if ([EAGLContext setCurrentContext:_context]) {
+ glGenFramebuffersOES(1, &_viewFramebuffer); printOpenGLError();
+ glGenRenderbuffersOES(1, &_viewRenderbuffer); printOpenGLError();
+
+ glBindFramebufferOES(GL_FRAMEBUFFER_OES, _viewFramebuffer); printOpenGLError();
+ glBindRenderbufferOES(GL_RENDERBUFFER_OES, _viewRenderbuffer); printOpenGLError();
+ [_context renderbufferStorage:GL_RENDERBUFFER_OES fromDrawable:(id<EAGLDrawable>)self.layer];
+
+ glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, _viewRenderbuffer); printOpenGLError();
+
+ // Retrieve the render buffer size. This *should* match the frame size,
+ // i.e. g_fullWidth and g_fullHeight.
+ glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_WIDTH_OES, &_renderBufferWidth); printOpenGLError();
+ glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_HEIGHT_OES, &_renderBufferHeight); printOpenGLError();
+
+ if (glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES) != GL_FRAMEBUFFER_COMPLETE_OES) {
+ NSLog(@"Failed to make complete framebuffer object %x.", glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES));
+ return;
+ }
+
+ _videoContext.overlayHeight = _renderBufferWidth;
+ _videoContext.overlayWidth = _renderBufferHeight;
+ uint overlayTextureWidth = getSizeNextPOT(_videoContext.overlayHeight);
+ uint overlayTextureHeight = getSizeNextPOT(_videoContext.overlayWidth);
+
+ // Since the overlay size won't change the whole run, we can
+ // precalculate the texture coordinates for the overlay texture here
+ // and just use it later on.
+ _overlayTexCoords[2] = _overlayTexCoords[6] = _videoContext.overlayWidth / (GLfloat)overlayTextureWidth;
+ _overlayTexCoords[5] = _overlayTexCoords[7] = _videoContext.overlayHeight / (GLfloat)overlayTextureHeight;
+
+ _videoContext.overlayTexture.create(overlayTextureWidth, overlayTextureHeight, Graphics::createPixelFormat<5551>());
+
+ glViewport(0, 0, _renderBufferWidth, _renderBufferHeight); printOpenGLError();
+ glClearColor(0.0f, 0.0f, 0.0f, 1.0f); printOpenGLError();
+
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+
+ glEnable(GL_TEXTURE_2D); printOpenGLError();
+ glEnableClientState(GL_TEXTURE_COORD_ARRAY); printOpenGLError();
+ glEnableClientState(GL_VERTEX_ARRAY); printOpenGLError();
+ }
+}
+
+- (id)initWithFrame:(struct CGRect)frame {
+ self = [super initWithFrame: frame];
+
+ if ([[UIScreen mainScreen] respondsToSelector: NSSelectorFromString(@"scale")]) {
+ if ([self respondsToSelector: NSSelectorFromString(@"contentScaleFactor")]) {
+ //self.contentScaleFactor = [[UIScreen mainScreen] scale];
+ }
+ }
+
+ g_fullWidth = (int)frame.size.width;
+ g_fullHeight = (int)frame.size.height;
+
+ g_iPhoneViewInstance = self;
+
+ _keyboardView = nil;
+ _screenTexture = 0;
+ _overlayTexture = 0;
+ _mouseCursorTexture = 0;
+
+ _scaledShakeOffsetY = 0;
+
+ _firstTouch = NULL;
+ _secondTouch = NULL;
+
+ _gameScreenVertCoords[0] = _gameScreenVertCoords[1] =
+ _gameScreenVertCoords[2] = _gameScreenVertCoords[3] =
+ _gameScreenVertCoords[4] = _gameScreenVertCoords[5] =
+ _gameScreenVertCoords[6] = _gameScreenVertCoords[7] = 0;
+
+ _gameScreenTexCoords[0] = _gameScreenTexCoords[1] =
+ _gameScreenTexCoords[2] = _gameScreenTexCoords[3] =
+ _gameScreenTexCoords[4] = _gameScreenTexCoords[5] =
+ _gameScreenTexCoords[6] = _gameScreenTexCoords[7] = 0;
+
+ _overlayVertCoords[0] = _overlayVertCoords[1] =
+ _overlayVertCoords[2] = _overlayVertCoords[3] =
+ _overlayVertCoords[4] = _overlayVertCoords[5] =
+ _overlayVertCoords[6] = _overlayVertCoords[7] = 0;
+
+ _overlayTexCoords[0] = _overlayTexCoords[1] =
+ _overlayTexCoords[2] = _overlayTexCoords[3] =
+ _overlayTexCoords[4] = _overlayTexCoords[5] =
+ _overlayTexCoords[6] = _overlayTexCoords[7] = 0;
+
+ _mouseVertCoords[0] = _mouseVertCoords[1] =
+ _mouseVertCoords[2] = _mouseVertCoords[3] =
+ _mouseVertCoords[4] = _mouseVertCoords[5] =
+ _mouseVertCoords[6] = _mouseVertCoords[7] = 0;
+
+ _mouseTexCoords[0] = _mouseTexCoords[1] =
+ _mouseTexCoords[2] = _mouseTexCoords[3] =
+ _mouseTexCoords[4] = _mouseTexCoords[5] =
+ _mouseTexCoords[6] = _mouseTexCoords[7] = 0;
+
+ // Initialize the OpenGL ES context
+ [self createContext];
+
+ return self;
+}
+
+- (void)dealloc {
+ if (_keyboardView != nil) {
+ [_keyboardView dealloc];
+ }
+
+ _videoContext.screenTexture.free();
+ _videoContext.overlayTexture.free();
+ _videoContext.mouseTexture.free();
+
+ [super dealloc];
+}
+
+- (void)drawRect:(CGRect)frame {
+#if 0
+ if (g_lastTick == 0) {
+ g_lastTick = time(0);
+ }
+
+ g_frames++;
+ if (time(0) > g_lastTick) {
+ g_lastTick = time(0);
+ printf("FPS: %i\n", g_frames);
+ g_frames = 0;
+ }
+#endif
+}
+
+- (void)setFilterModeForTexture:(GLuint)tex {
+ if (!tex)
+ return;
+
+ glBindTexture(GL_TEXTURE_2D, tex); printOpenGLError();
+
+ GLint filter = GL_LINEAR;
+
+ switch (_videoContext.graphicsMode) {
+ case kGraphicsModeLinear:
+ filter = GL_LINEAR;
+ break;
+
+ case kGraphicsModeNone:
+ filter = GL_NEAREST;
+ break;
+ }
+
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter); printOpenGLError();
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter); printOpenGLError();
+}
+
+- (void)setGraphicsMode {
+ [self setFilterModeForTexture:_screenTexture];
+ [self setFilterModeForTexture:_overlayTexture];
+ [self setFilterModeForTexture:_mouseCursorTexture];
+}
+
+- (void)updateSurface {
+ if (!g_needsScreenUpdate) {
+ return;
+ }
+ g_needsScreenUpdate = 0;
+
+ glClear(GL_COLOR_BUFFER_BIT); printOpenGLError();
+
+ [self updateMainSurface];
+
+ if (_videoContext.overlayVisible)
+ [self updateOverlaySurface];
+
+ if (_videoContext.mouseIsVisible)
+ [self updateMouseSurface];
+
+ glBindRenderbufferOES(GL_RENDERBUFFER_OES, _viewRenderbuffer); printOpenGLError();
+ [_context presentRenderbuffer:GL_RENDERBUFFER_OES];
+
+}
+
+- (void)notifyMouseMove {
+ const GLint mouseX = (GLint)(_videoContext.mouseX * _mouseScaleX) - _mouseHotspotX;
+ const GLint mouseY = (GLint)(_videoContext.mouseY * _mouseScaleY) - _mouseHotspotY;
+
+ _mouseVertCoords[0] = _mouseVertCoords[4] = mouseX;
+ _mouseVertCoords[1] = _mouseVertCoords[3] = mouseY;
+ _mouseVertCoords[2] = _mouseVertCoords[6] = mouseX + _mouseWidth;
+ _mouseVertCoords[5] = _mouseVertCoords[7] = mouseY + _mouseHeight;
+}
+
+- (void)updateMouseCursorScaling {
+ CGRect *rect;
+ int maxWidth, maxHeight;
+
+ if (!_videoContext.overlayVisible) {
+ rect = &_gameScreenRect;
+ maxWidth = _videoContext.screenWidth;
+ maxHeight = _videoContext.screenHeight;
+ } else {
+ rect = &_overlayRect;
+ maxWidth = _videoContext.overlayWidth;
+ maxHeight = _videoContext.overlayHeight;
+ }
+
+ if (!maxWidth || !maxHeight) {
+ printf("WARNING: updateMouseCursorScaling called when screen was not ready (%d)!\n", _videoContext.overlayVisible);
+ return;
+ }
+
+ _mouseScaleX = CGRectGetWidth(*rect) / (GLfloat)maxWidth;
+ _mouseScaleY = CGRectGetHeight(*rect) / (GLfloat)maxHeight;
+
+ _mouseWidth = (GLint)(_videoContext.mouseWidth * _mouseScaleX);
+ _mouseHeight = (GLint)(_videoContext.mouseHeight * _mouseScaleY);
+
+ _mouseHotspotX = (GLint)(_videoContext.mouseHotspotX * _mouseScaleX);
+ _mouseHotspotY = (GLint)(_videoContext.mouseHotspotY * _mouseScaleY);
+
+ // We subtract the screen offset to the hotspot here to simplify the
+ // screen offset handling in the mouse code. Note the subtraction here
+ // makes sure that the offset actually gets added to the mouse position,
+ // since the hotspot offset is substracted from the position.
+ _mouseHotspotX -= (GLint)CGRectGetMinX(*rect);
+ _mouseHotspotY -= (GLint)CGRectGetMinY(*rect);
+
+ // FIXME: For now we also adapt the mouse position here. In reality we
+ // would be better off to also adjust the event position when switching
+ // from overlay to game screen or vica versa.
+ [self notifyMouseMove];
+}
+
+- (void)updateMouseCursor {
+ if (_mouseCursorTexture == 0) {
+ glGenTextures(1, &_mouseCursorTexture); printOpenGLError();
+ [self setFilterModeForTexture:_mouseCursorTexture];
+ }
+
+ [self updateMouseCursorScaling];
+
+ _mouseTexCoords[2] = _mouseTexCoords[6] = _videoContext.mouseWidth / (GLfloat)_videoContext.mouseTexture.w;
+ _mouseTexCoords[5] = _mouseTexCoords[7] = _videoContext.mouseHeight / (GLfloat)_videoContext.mouseTexture.h;
+
+ glBindTexture(GL_TEXTURE_2D, _mouseCursorTexture); printOpenGLError();
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, _videoContext.mouseTexture.w, _videoContext.mouseTexture.h, 0, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, _videoContext.mouseTexture.pixels); printOpenGLError();
+}
+
+- (void)updateMainSurface {
+ glVertexPointer(2, GL_FLOAT, 0, _gameScreenVertCoords); printOpenGLError();
+ glTexCoordPointer(2, GL_FLOAT, 0, _gameScreenTexCoords); printOpenGLError();
+
+ glBindTexture(GL_TEXTURE_2D, _screenTexture); printOpenGLError();
+
+ // Unfortunately we have to update the whole texture every frame, since glTexSubImage2D is actually slower in all cases
+ // due to the iPhone internals having to convert the whole texture back from its internal format when used.
+ // In the future we could use several tiled textures instead.
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, _videoContext.screenTexture.w, _videoContext.screenTexture.h, 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, _videoContext.screenTexture.pixels); printOpenGLError();
+ glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); printOpenGLError();
+}
+
+- (void)updateOverlaySurface {
+ glVertexPointer(2, GL_FLOAT, 0, _overlayVertCoords); printOpenGLError();
+ glTexCoordPointer(2, GL_FLOAT, 0, _overlayTexCoords); printOpenGLError();
+
+ glBindTexture(GL_TEXTURE_2D, _overlayTexture); printOpenGLError();
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, _videoContext.overlayTexture.w, _videoContext.overlayTexture.h, 0, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, _videoContext.overlayTexture.pixels); printOpenGLError();
+ glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); printOpenGLError();
+}
+
+- (void)updateMouseSurface {
+ glVertexPointer(2, GL_FLOAT, 0, _mouseVertCoords); printOpenGLError();
+ glTexCoordPointer(2, GL_FLOAT, 0, _mouseTexCoords); printOpenGLError();
+
+ glBindTexture(GL_TEXTURE_2D, _mouseCursorTexture); printOpenGLError();
+ glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); printOpenGLError();
+}
+
+- (void)setUpOrientation:(UIDeviceOrientation)orientation width:(int *)width height:(int *)height {
+ _orientation = orientation;
+
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+
+ // We always force the origin (0,0) to be in the upper left corner.
+ switch (_orientation) {
+ case UIDeviceOrientationLandscapeRight:
+ glRotatef( 90, 0, 0, 1); printOpenGLError();
+ glOrthof(0, _renderBufferHeight, _renderBufferWidth, 0, 0, 1); printOpenGLError();
+
+ *width = _renderBufferHeight;
+ *height = _renderBufferWidth;
+ break;
+
+ case UIDeviceOrientationLandscapeLeft:
+ glRotatef(-90, 0, 0, 1); printOpenGLError();
+ glOrthof(0, _renderBufferHeight, _renderBufferWidth, 0, 0, 1); printOpenGLError();
+
+ *width = _renderBufferHeight;
+ *height = _renderBufferWidth;
+ break;
+
+ case UIDeviceOrientationPortrait:
+ default:
+ // We must force the portrait orientation here, since we might not know
+ // the real orientation.
+ _orientation = UIDeviceOrientationPortrait;
+
+ glOrthof(0, _renderBufferWidth, _renderBufferHeight, 0, 0, 1); printOpenGLError();
+
+ *width = _renderBufferWidth;
+ *height = _renderBufferHeight;
+ break;
+ }
+}
+
+- (void)createScreenTexture {
+ const uint screenTexWidth = getSizeNextPOT(_videoContext.screenWidth);
+ const uint screenTexHeight = getSizeNextPOT(_videoContext.screenHeight);
+
+ _gameScreenTexCoords[2] = _gameScreenTexCoords[6] = _videoContext.screenWidth / (GLfloat)screenTexWidth;
+ _gameScreenTexCoords[5] = _gameScreenTexCoords[7] = _videoContext.screenHeight / (GLfloat)screenTexHeight;
+
+ _videoContext.screenTexture.create(screenTexWidth, screenTexHeight, Graphics::createPixelFormat<565>());
+}
+
+- (void)initSurface {
+ int screenWidth, screenHeight;
+ [self setUpOrientation:[[UIDevice currentDevice] orientation] width:&screenWidth height:&screenHeight];
+
+ if (_screenTexture > 0) {
+ glDeleteTextures(1, &_screenTexture); printOpenGLError();
+ }
+
+ glGenTextures(1, &_screenTexture); printOpenGLError();
+ [self setFilterModeForTexture:_screenTexture];
+
+ if (_overlayTexture > 0) {
+ glDeleteTextures(1, &_overlayTexture); printOpenGLError();
+ }
+
+ glGenTextures(1, &_overlayTexture); printOpenGLError();
+ [self setFilterModeForTexture:_overlayTexture];
+
+ glBindRenderbufferOES(GL_RENDERBUFFER_OES, _viewRenderbuffer); printOpenGLError();
+
+ [self clearColorBuffer];
+
+ if (_keyboardView != nil) {
+ [_keyboardView removeFromSuperview];
+ [[_keyboardView inputView] removeFromSuperview];
+ }
+
+ GLfloat adjustedWidth = _videoContext.screenWidth;
+ GLfloat adjustedHeight = _videoContext.screenHeight;
+ if (_videoContext.asprectRatioCorrection) {
+ if (_videoContext.screenWidth == 320 && _videoContext.screenHeight == 200)
+ adjustedHeight = 240;
+ else if (_videoContext.screenWidth == 640 && _videoContext.screenHeight == 400)
+ adjustedHeight = 480;
+ }
+
+ float overlayPortraitRatio;
+
+ if (_orientation == UIDeviceOrientationLandscapeLeft || _orientation == UIDeviceOrientationLandscapeRight) {
+ GLfloat gameScreenRatio = adjustedWidth / adjustedHeight;
+ GLfloat screenRatio = (GLfloat)screenWidth / (GLfloat)screenHeight;
+
+ // These are the width/height according to the portrait layout!
+ int rectWidth, rectHeight;
+ int xOffset, yOffset;
+
+ if (gameScreenRatio < screenRatio) {
+ // When the game screen ratio is less than the screen ratio
+ // we need to scale the width, since the game screen was higher
+ // compared to the width than our output screen is.
+ rectWidth = (int)(screenHeight * gameScreenRatio);
+ rectHeight = screenHeight;
+ xOffset = (screenWidth - rectWidth) / 2;
+ yOffset = 0;
+ } else {
+ // When the game screen ratio is bigger than the screen ratio
+ // we need to scale the height, since the game screen was wider
+ // compared to the height than our output screen is.
+ rectWidth = screenWidth;
+ rectHeight = (int)(screenWidth / gameScreenRatio);
+ xOffset = 0;
+ yOffset = (screenHeight - rectHeight) / 2;
+ }
+
+ //printf("Rect: %i, %i, %i, %i\n", xOffset, yOffset, rectWidth, rectHeight);
+ _gameScreenRect = CGRectMake(xOffset, yOffset, rectWidth, rectHeight);
+ overlayPortraitRatio = 1.0f;
+ } else {
+ GLfloat ratio = adjustedHeight / adjustedWidth;
+ int height = (int)(screenWidth * ratio);
+ //printf("Making rect (%u, %u)\n", screenWidth, height);
+ _gameScreenRect = CGRectMake(0, 0, screenWidth, height);
+
+ CGRect keyFrame = CGRectMake(0.0f, 0.0f, 0.0f, 0.0f);
+ if (_keyboardView == nil) {
+ _keyboardView = [[SoftKeyboard alloc] initWithFrame:keyFrame];
+ [_keyboardView setInputDelegate:self];
+ }
+
+ [self addSubview:[_keyboardView inputView]];
+ [self addSubview: _keyboardView];
+ [[_keyboardView inputView] becomeFirstResponder];
+ overlayPortraitRatio = (_videoContext.overlayHeight * ratio) / _videoContext.overlayWidth;
+ }
+
+ _overlayRect = CGRectMake(0, 0, screenWidth, screenHeight * overlayPortraitRatio);
+
+ _gameScreenVertCoords[0] = _gameScreenVertCoords[4] = CGRectGetMinX(_gameScreenRect);
+ _gameScreenVertCoords[1] = _gameScreenVertCoords[3] = CGRectGetMinY(_gameScreenRect);
+ _gameScreenVertCoords[2] = _gameScreenVertCoords[6] = CGRectGetMaxX(_gameScreenRect);
+ _gameScreenVertCoords[5] = _gameScreenVertCoords[7] = CGRectGetMaxY(_gameScreenRect);
+
+ _overlayVertCoords[2] = _overlayVertCoords[6] = CGRectGetMaxX(_overlayRect);
+ _overlayVertCoords[5] = _overlayVertCoords[7] = CGRectGetMaxY(_overlayRect);
+
+ [self setViewTransformation];
+ [self updateMouseCursorScaling];
+}
+
+- (void)setViewTransformation {
+ // Set the modelview matrix. This matrix will be used for the shake offset
+ // support.
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+
+ // Scale the shake offset according to the overlay size. We need this to
+ // adjust the overlay mouse click coordinates when an offset is set.
+ _scaledShakeOffsetY = (int)(_videoContext.shakeOffsetY / (GLfloat)_videoContext.screenHeight * CGRectGetHeight(_overlayRect));
+
+ // Apply the shakeing to the output screen.
+ glTranslatef(0, -_scaledShakeOffsetY, 0);
+}
+
+- (void)clearColorBuffer {
+ // The color buffer is triple-buffered, so we clear it multiple times right away to avid doing any glClears later.
+ int clearCount = 5;
+ while (clearCount-- > 0) {
+ glClear(GL_COLOR_BUFFER_BIT); printOpenGLError();
+ [_context presentRenderbuffer:GL_RENDERBUFFER_OES];
+ }
+}
+
+- (id)getEvent {
+ if (_events == nil || [_events count] == 0) {
+ return nil;
+ }
+
+ id event = [_events objectAtIndex: 0];
+
+ [_events removeObjectAtIndex: 0];
+
+ return event;
+}
+
+- (void)addEvent:(NSDictionary *)event {
+ if (_events == nil)
+ _events = [[NSMutableArray alloc] init];
+
+ [_events addObject: event];
+}
+
+/**
+ * Converts portrait mode coordinates into rotated mode coordinates.
+ */
+- (bool)convertToRotatedCoords:(CGPoint)point result:(CGPoint *)result {
+ switch (_orientation) {
+ case UIDeviceOrientationLandscapeLeft:
+ result->x = point.y;
+ result->y = _renderBufferWidth - point.x;
+ return true;
+
+ case UIDeviceOrientationLandscapeRight:
+ result->x = _renderBufferHeight - point.y;
+ result->y = point.x;
+ return true;
+
+ case UIDeviceOrientationPortrait:
+ result->x = point.x;
+ result->y = point.y;
+ return true;
+
+ default:
+ return false;
+ }
+}
+
+- (bool)getMouseCoords:(CGPoint)point eventX:(int *)x eventY:(int *)y {
+ if (![self convertToRotatedCoords:point result:&point])
+ return false;
+
+ CGRect *area;
+ int width, height, offsetY;
+ if (_videoContext.overlayVisible) {
+ area = &_overlayRect;
+ width = _videoContext.overlayWidth;
+ height = _videoContext.overlayHeight;
+ offsetY = _scaledShakeOffsetY;
+ } else {
+ area = &_gameScreenRect;
+ width = _videoContext.screenWidth;
+ height = _videoContext.screenHeight;
+ offsetY = _videoContext.shakeOffsetY;
+ }
+
+ point.x = (point.x - CGRectGetMinX(*area)) / CGRectGetWidth(*area);
+ point.y = (point.y - CGRectGetMinY(*area)) / CGRectGetHeight(*area);
+
+ *x = (int)(point.x * width);
+ // offsetY describes the translation of the screen in the upward direction,
+ // thus we need to add it here.
+ *y = (int)(point.y * height + offsetY);
+
+ // Clip coordinates
+ if (*x < 0 || *x > width || *y < 0 || *y > height)
+ return false;
+
+ return true;
+}
+
+- (void)deviceOrientationChanged:(UIDeviceOrientation)orientation {
+ switch (orientation) {
+ case UIDeviceOrientationLandscapeLeft:
+ case UIDeviceOrientationLandscapeRight:
+ case UIDeviceOrientationPortrait:
+ _orientation = orientation;
+ break;
+
+ default:
+ return;
+ }
+
+ [self addEvent:
+ [[NSDictionary alloc] initWithObjectsAndKeys:
+ [NSNumber numberWithInt:kInputOrientationChanged], @"type",
+ [NSNumber numberWithInt:orientation], @"x",
+ [NSNumber numberWithInt:0], @"y",
+ nil
+ ]
+ ];
+}
+
+- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
+ NSSet *allTouches = [event allTouches];
+ int x, y;
+
+ switch ([allTouches count]) {
+ case 1: {
+ UITouch *touch = [touches anyObject];
+ CGPoint point = [touch locationInView:self];
+ if (![self getMouseCoords:point eventX:&x eventY:&y])
+ return;
+
+ _firstTouch = touch;
+ [self addEvent:
+ [[NSDictionary alloc] initWithObjectsAndKeys:
+ [NSNumber numberWithInt:kInputMouseDown], @"type",
+ [NSNumber numberWithInt:x], @"x",
+ [NSNumber numberWithInt:y], @"y",
+ nil
+ ]
+ ];
+ break;
+ }
+
+ case 2: {
+ UITouch *touch = [touches anyObject];
+ CGPoint point = [touch locationInView:self];
+ if (![self getMouseCoords:point eventX:&x eventY:&y])
+ return;
+
+ _secondTouch = touch;
+ [self addEvent:
+ [[NSDictionary alloc] initWithObjectsAndKeys:
+ [NSNumber numberWithInt:kInputMouseSecondDown], @"type",
+ [NSNumber numberWithInt:x], @"x",
+ [NSNumber numberWithInt:y], @"y",
+ nil
+ ]
+ ];
+ break;
+ }
+ }
+}
+
+- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
+ //NSSet *allTouches = [event allTouches];
+ int x, y;
+
+ for (UITouch *touch in touches) {
+ if (touch == _firstTouch) {
+ CGPoint point = [touch locationInView:self];
+ if (![self getMouseCoords:point eventX:&x eventY:&y])
+ return;
+
+ [self addEvent:
+ [[NSDictionary alloc] initWithObjectsAndKeys:
+ [NSNumber numberWithInt:kInputMouseDragged], @"type",
+ [NSNumber numberWithInt:x], @"x",
+ [NSNumber numberWithInt:y], @"y",
+ nil
+ ]
+ ];
+ } else if (touch == _secondTouch) {
+ CGPoint point = [touch locationInView:self];
+ if (![self getMouseCoords:point eventX:&x eventY:&y])
+ return;
+
+ [self addEvent:
+ [[NSDictionary alloc] initWithObjectsAndKeys:
+ [NSNumber numberWithInt:kInputMouseSecondDragged], @"type",
+ [NSNumber numberWithInt:x], @"x",
+ [NSNumber numberWithInt:y], @"y",
+ nil
+ ]
+ ];
+ }
+ }
+}
+
+- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
+ NSSet *allTouches = [event allTouches];
+ int x, y;
+
+ switch ([allTouches count]) {
+ case 1: {
+ UITouch *touch = [[allTouches allObjects] objectAtIndex:0];
+ CGPoint point = [touch locationInView:self];
+ if (![self getMouseCoords:point eventX:&x eventY:&y])
+ return;
+
+ [self addEvent:
+ [[NSDictionary alloc] initWithObjectsAndKeys:
+ [NSNumber numberWithInt:kInputMouseUp], @"type",
+ [NSNumber numberWithInt:x], @"x",
+ [NSNumber numberWithInt:y], @"y",
+ nil
+ ]
+ ];
+ break;
+ }
+
+ case 2: {
+ UITouch *touch = [[allTouches allObjects] objectAtIndex:1];
+ CGPoint point = [touch locationInView:self];
+ if (![self getMouseCoords:point eventX:&x eventY:&y])
+ return;
+
+ [self addEvent:
+ [[NSDictionary alloc] initWithObjectsAndKeys:
+ [NSNumber numberWithInt:kInputMouseSecondUp], @"type",
+ [NSNumber numberWithInt:x], @"x",
+ [NSNumber numberWithInt:y], @"y",
+ nil
+ ]
+ ];
+ break;
+ }
+ }
+}
+
+- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event {
+}
+
+- (void)handleKeyPress:(unichar)c {
+ [self addEvent:
+ [[NSDictionary alloc] initWithObjectsAndKeys:
+ [NSNumber numberWithInt:kInputKeyPressed], @"type",
+ [NSNumber numberWithInt:c], @"x",
+ [NSNumber numberWithInt:0], @"y",
+ nil
+ ]
+ ];
+}
+
+- (BOOL)canHandleSwipes {
+ return TRUE;
+}
+
+- (int)swipe:(int)num withEvent:(struct __GSEvent *)event {
+ //printf("swipe: %i\n", num);
+
+ [self addEvent:
+ [[NSDictionary alloc] initWithObjectsAndKeys:
+ [NSNumber numberWithInt:kInputSwipe], @"type",
+ [NSNumber numberWithInt:num], @"x",
+ [NSNumber numberWithInt:0], @"y",
+ nil
+ ]
+ ];
+
+ return 0;
+}
+
+- (void)applicationSuspend {
+ [self addEvent:
+ [[NSDictionary alloc] initWithObjectsAndKeys:
+ [NSNumber numberWithInt:kInputApplicationSuspended], @"type",
+ [NSNumber numberWithInt:0], @"x",
+ [NSNumber numberWithInt:0], @"y",
+ nil
+ ]
+ ];
+}
+
+- (void)applicationResume {
+ [self addEvent:
+ [[NSDictionary alloc] initWithObjectsAndKeys:
+ [NSNumber numberWithInt:kInputApplicationResumed], @"type",
+ [NSNumber numberWithInt:0], @"x",
+ [NSNumber numberWithInt:0], @"y",
+ nil
+ ]
+ ];
+}
+
+@end
diff --git a/backends/platform/iphone/module.mk b/backends/platform/iphone/module.mk
index 9768e6ded4..ea5115782f 100644
--- a/backends/platform/iphone/module.mk
+++ b/backends/platform/iphone/module.mk
@@ -7,8 +7,7 @@ MODULE_OBJS := \
osys_video.o \
iphone_main.o \
iphone_video.o \
- iphone_keyboard.o \
- blit_arm.o
+ iphone_keyboard.o
# We don't use rules.mk but rather manually update OBJS and MODULE_DIRS.
MODULE_OBJS := $(addprefix $(MODULE)/, $(MODULE_OBJS))
diff --git a/backends/platform/iphone/osys_events.cpp b/backends/platform/iphone/osys_events.cpp
index 1ab1db0f27..85efbda208 100644
--- a/backends/platform/iphone/osys_events.cpp
+++ b/backends/platform/iphone/osys_events.cpp
@@ -40,98 +40,66 @@ bool OSystem_IPHONE::pollEvent(Common::Event &event) {
_timerCallbackNext = curTime + _timerCallbackTimer;
}
- if (_queuedInputEvent.type != (Common::EventType)0 && curTime >= _queuedEventTime) {
+ if (_queuedInputEvent.type != Common::EVENT_INVALID && curTime >= _queuedEventTime) {
event = _queuedInputEvent;
- _queuedInputEvent.type = (Common::EventType)0;
+ _queuedInputEvent.type = Common::EVENT_INVALID;
return true;
}
int eventType;
- float xUnit, yUnit;
-
- if (iPhone_fetchEvent(&eventType, &xUnit, &yUnit)) {
- int x = 0;
- int y = 0;
- switch (_screenOrientation) {
- case kScreenOrientationPortrait:
- if (_overlayVisible) {
- x = (int)(xUnit * _overlayWidth);
- y = (int)(yUnit * _overlayHeight);
- } else {
- x = (int)(xUnit * _screenWidth);
- y = (int)(yUnit * _screenHeight);
- }
- break;
- case kScreenOrientationLandscape:
- if (_overlayVisible) {
- x = (int)(yUnit * _overlayWidth);
- y = (int)((1.0 - xUnit) * _overlayHeight);
- } else {
- x = (int)(yUnit * _screenWidth);
- y = (int)((1.0 - xUnit) * _screenHeight);
- }
- break;
- case kScreenOrientationFlippedLandscape:
- if (_overlayVisible) {
- x = (int)((1.0 - yUnit) * _overlayWidth);
- y = (int)(xUnit * _overlayHeight);
- } else {
- x = (int)((1.0 - yUnit) * _screenWidth);
- y = (int)(xUnit * _screenHeight);
- }
- break;
- }
+ int x, y;
+ if (iPhone_fetchEvent(&eventType, &x, &y)) {
switch ((InputEvent)eventType) {
- case kInputMouseDown:
- if (!handleEvent_mouseDown(event, x, y))
- return false;
- break;
+ case kInputMouseDown:
+ if (!handleEvent_mouseDown(event, x, y))
+ return false;
+ break;
- case kInputMouseUp:
+ case kInputMouseUp:
if (!handleEvent_mouseUp(event, x, y))
return false;
- break;
-
- case kInputMouseDragged:
- if (!handleEvent_mouseDragged(event, x, y))
- return false;
- break;
- case kInputMouseSecondDragged:
- if (!handleEvent_mouseSecondDragged(event, x, y))
- return false;
- break;
- case kInputMouseSecondDown:
- _secondaryTapped = true;
- if (!handleEvent_secondMouseDown(event, x, y))
- return false;
- break;
- case kInputMouseSecondUp:
- _secondaryTapped = false;
- if (!handleEvent_secondMouseUp(event, x, y))
- return false;
- break;
- case kInputOrientationChanged:
- handleEvent_orientationChanged((int)xUnit);
- return false;
- break;
+ break;
- case kInputApplicationSuspended:
- suspendLoop();
+ case kInputMouseDragged:
+ if (!handleEvent_mouseDragged(event, x, y))
+ return false;
+ break;
+ case kInputMouseSecondDragged:
+ if (!handleEvent_mouseSecondDragged(event, x, y))
+ return false;
+ break;
+ case kInputMouseSecondDown:
+ _secondaryTapped = true;
+ if (!handleEvent_secondMouseDown(event, x, y))
+ return false;
+ break;
+ case kInputMouseSecondUp:
+ _secondaryTapped = false;
+ if (!handleEvent_secondMouseUp(event, x, y))
return false;
- break;
+ break;
+ case kInputOrientationChanged:
+ handleEvent_orientationChanged(x);
+ return false;
+ break;
- case kInputKeyPressed:
- handleEvent_keyPressed(event, (int)xUnit);
- break;
+ case kInputApplicationSuspended:
+ suspendLoop();
+ return false;
+ break;
- case kInputSwipe:
- if (!handleEvent_swipe(event, (int)xUnit))
- return false;
- break;
+ case kInputKeyPressed:
+ handleEvent_keyPressed(event, x);
+ break;
+
+ case kInputSwipe:
+ if (!handleEvent_swipe(event, x))
+ return false;
+ break;
- default:
- break;
+ default:
+ break;
}
return true;
@@ -154,8 +122,8 @@ bool OSystem_IPHONE::handleEvent_mouseDown(Common::Event &event, int x, int y) {
if (_mouseClickAndDragEnabled) {
event.type = Common::EVENT_LBUTTONDOWN;
- event.mouse.x = _mouseX;
- event.mouse.y = _mouseY;
+ event.mouse.x = _videoContext->mouseX;
+ event.mouse.y = _videoContext->mouseY;
return true;
} else {
_lastMouseDown = getMillis();
@@ -170,20 +138,19 @@ bool OSystem_IPHONE::handleEvent_mouseUp(Common::Event &event, int x, int y) {
_secondaryTapped = false;
if (!handleEvent_secondMouseUp(event, x, y))
return false;
- }
- else if (_mouseClickAndDragEnabled) {
+ } else if (_mouseClickAndDragEnabled) {
event.type = Common::EVENT_LBUTTONUP;
- event.mouse.x = _mouseX;
- event.mouse.y = _mouseY;
+ event.mouse.x = _videoContext->mouseX;
+ event.mouse.y = _videoContext->mouseY;
} else {
if (getMillis() - _lastMouseDown < 250) {
event.type = Common::EVENT_LBUTTONDOWN;
- event.mouse.x = _mouseX;
- event.mouse.y = _mouseY;
+ event.mouse.x = _videoContext->mouseX;
+ event.mouse.y = _videoContext->mouseY;
_queuedInputEvent.type = Common::EVENT_LBUTTONUP;
- _queuedInputEvent.mouse.x = _mouseX;
- _queuedInputEvent.mouse.y = _mouseY;
+ _queuedInputEvent.mouse.x = _videoContext->mouseX;
+ _queuedInputEvent.mouse.y = _videoContext->mouseY;
_lastMouseTap = getMillis();
_queuedEventTime = _lastMouseTap + kQueuedInputEventDelay;
} else
@@ -200,14 +167,13 @@ bool OSystem_IPHONE::handleEvent_secondMouseDown(Common::Event &event, int x, in
if (_mouseClickAndDragEnabled) {
event.type = Common::EVENT_LBUTTONUP;
- event.mouse.x = _mouseX;
- event.mouse.y = _mouseY;
+ event.mouse.x = _videoContext->mouseX;
+ event.mouse.y = _videoContext->mouseY;
_queuedInputEvent.type = Common::EVENT_RBUTTONDOWN;
- _queuedInputEvent.mouse.x = _mouseX;
- _queuedInputEvent.mouse.y = _mouseY;
- }
- else
+ _queuedInputEvent.mouse.x = _videoContext->mouseX;
+ _queuedInputEvent.mouse.y = _videoContext->mouseY;
+ } else
return false;
return true;
@@ -216,9 +182,9 @@ bool OSystem_IPHONE::handleEvent_secondMouseDown(Common::Event &event, int x, in
bool OSystem_IPHONE::handleEvent_secondMouseUp(Common::Event &event, int x, int y) {
int curTime = getMillis();
- if (curTime - _lastSecondaryDown < 400 ) {
+ if (curTime - _lastSecondaryDown < 400) {
//printf("Right tap!\n");
- if (curTime - _lastSecondaryTap < 400 && !_overlayVisible) {
+ if (curTime - _lastSecondaryTap < 400 && !_videoContext->overlayVisible) {
//printf("Right escape!\n");
event.type = Common::EVENT_KEYDOWN;
_queuedInputEvent.type = Common::EVENT_KEYUP;
@@ -231,11 +197,11 @@ bool OSystem_IPHONE::handleEvent_secondMouseUp(Common::Event &event, int x, int
} else if (!_mouseClickAndDragEnabled) {
//printf("Rightclick!\n");
event.type = Common::EVENT_RBUTTONDOWN;
- event.mouse.x = _mouseX;
- event.mouse.y = _mouseY;
+ event.mouse.x = _videoContext->mouseX;
+ event.mouse.y = _videoContext->mouseY;
_queuedInputEvent.type = Common::EVENT_RBUTTONUP;
- _queuedInputEvent.mouse.x = _mouseX;
- _queuedInputEvent.mouse.y = _mouseY;
+ _queuedInputEvent.mouse.x = _videoContext->mouseX;
+ _queuedInputEvent.mouse.y = _videoContext->mouseY;
_lastSecondaryTap = curTime;
_queuedEventTime = curTime + kQueuedInputEventDelay;
} else {
@@ -245,8 +211,8 @@ bool OSystem_IPHONE::handleEvent_secondMouseUp(Common::Event &event, int x, int
}
if (_mouseClickAndDragEnabled) {
event.type = Common::EVENT_RBUTTONUP;
- event.mouse.x = _mouseX;
- event.mouse.y = _mouseY;
+ event.mouse.x = _videoContext->mouseX;
+ event.mouse.y = _videoContext->mouseY;
}
return true;
@@ -262,17 +228,17 @@ bool OSystem_IPHONE::handleEvent_mouseDragged(Common::Event &event, int x, int y
//printf("Mouse dragged at (%u, %u)\n", x, y);
int mouseNewPosX;
int mouseNewPosY;
- if (_touchpadModeEnabled ) {
+ if (_touchpadModeEnabled) {
int deltaX = _lastPadX - x;
int deltaY = _lastPadY - y;
_lastPadX = x;
_lastPadY = y;
- mouseNewPosX = (int)(_mouseX - deltaX / 0.5f);
- mouseNewPosY = (int)(_mouseY - deltaY / 0.5f);
+ mouseNewPosX = (int)(_videoContext->mouseX - deltaX / 0.5f);
+ mouseNewPosY = (int)(_videoContext->mouseY - deltaY / 0.5f);
- int widthCap = _overlayVisible ? _overlayWidth : _screenWidth;
- int heightCap = _overlayVisible ? _overlayHeight : _screenHeight;
+ int widthCap = _videoContext->overlayVisible ? _videoContext->overlayWidth : _videoContext->screenWidth;
+ int heightCap = _videoContext->overlayVisible ? _videoContext->overlayHeight : _videoContext->screenHeight;
if (mouseNewPosX < 0)
mouseNewPosX = 0;
@@ -319,12 +285,9 @@ bool OSystem_IPHONE::handleEvent_mouseSecondDragged(Common::Event &event, int x,
if (absX < kMaxDeviation && vecY >= kNeededLength) {
// Swipe down
- event.type = Common::EVENT_KEYDOWN;
- _queuedInputEvent.type = Common::EVENT_KEYUP;
+ event.type = Common::EVENT_MAINMENU;
+ _queuedInputEvent.type = Common::EVENT_INVALID;
- event.kbd.flags = _queuedInputEvent.kbd.flags = 0;
- event.kbd.keycode = _queuedInputEvent.kbd.keycode = Common::KEYCODE_F5;
- event.kbd.ascii = _queuedInputEvent.kbd.ascii = Common::ASCII_F5;
_queuedEventTime = getMillis() + kQueuedInputEventDelay;
return true;
}
@@ -371,26 +334,26 @@ void OSystem_IPHONE::handleEvent_orientationChanged(int orientation) {
ScreenOrientation newOrientation;
switch (orientation) {
- case 1:
- newOrientation = kScreenOrientationPortrait;
- break;
- case 3:
- newOrientation = kScreenOrientationLandscape;
- break;
- case 4:
- newOrientation = kScreenOrientationFlippedLandscape;
- break;
- default:
- return;
+ case 1:
+ newOrientation = kScreenOrientationPortrait;
+ break;
+ case 3:
+ newOrientation = kScreenOrientationLandscape;
+ break;
+ case 4:
+ newOrientation = kScreenOrientationFlippedLandscape;
+ break;
+ default:
+ return;
}
if (_screenOrientation != newOrientation) {
_screenOrientation = newOrientation;
- iPhone_initSurface(_screenWidth, _screenHeight);
+ updateOutputSurface();
dirtyFullScreen();
- if (_overlayVisible)
+ if (_videoContext->overlayVisible)
dirtyFullOverlayScreen();
updateScreen();
}
@@ -403,50 +366,50 @@ void OSystem_IPHONE::handleEvent_keyPressed(Common::Event &event, int keyPresse
// We remap some of the iPhone keyboard keys.
// The first ten here are the row of symbols below the numeric keys.
switch (keyPressed) {
- case 45:
- keyPressed = Common::KEYCODE_F1;
- ascii = Common::ASCII_F1;
- break;
- case 47:
- keyPressed = Common::KEYCODE_F2;
- ascii = Common::ASCII_F2;
- break;
- case 58:
- keyPressed = Common::KEYCODE_F3;
- ascii = Common::ASCII_F3;
- break;
- case 59:
- keyPressed = Common::KEYCODE_F4;
- ascii = Common::ASCII_F4;
- break;
- case 40:
- keyPressed = Common::KEYCODE_F5;
- ascii = Common::ASCII_F5;
- break;
- case 41:
- keyPressed = Common::KEYCODE_F6;
- ascii = Common::ASCII_F6;
- break;
- case 36:
- keyPressed = Common::KEYCODE_F7;
- ascii = Common::ASCII_F7;
- break;
- case 38:
- keyPressed = Common::KEYCODE_F8;
- ascii = Common::ASCII_F8;
- break;
- case 64:
- keyPressed = Common::KEYCODE_F9;
- ascii = Common::ASCII_F9;
- break;
- case 34:
- keyPressed = Common::KEYCODE_F10;
- ascii = Common::ASCII_F10;
- break;
- case 10:
- keyPressed = Common::KEYCODE_RETURN;
- ascii = Common::ASCII_RETURN;
- break;
+ case 45:
+ keyPressed = Common::KEYCODE_F1;
+ ascii = Common::ASCII_F1;
+ break;
+ case 47:
+ keyPressed = Common::KEYCODE_F2;
+ ascii = Common::ASCII_F2;
+ break;
+ case 58:
+ keyPressed = Common::KEYCODE_F3;
+ ascii = Common::ASCII_F3;
+ break;
+ case 59:
+ keyPressed = Common::KEYCODE_F4;
+ ascii = Common::ASCII_F4;
+ break;
+ case 40:
+ keyPressed = Common::KEYCODE_F5;
+ ascii = Common::ASCII_F5;
+ break;
+ case 41:
+ keyPressed = Common::KEYCODE_F6;
+ ascii = Common::ASCII_F6;
+ break;
+ case 36:
+ keyPressed = Common::KEYCODE_F7;
+ ascii = Common::ASCII_F7;
+ break;
+ case 38:
+ keyPressed = Common::KEYCODE_F8;
+ ascii = Common::ASCII_F8;
+ break;
+ case 64:
+ keyPressed = Common::KEYCODE_F9;
+ ascii = Common::ASCII_F9;
+ break;
+ case 34:
+ keyPressed = Common::KEYCODE_F10;
+ ascii = Common::ASCII_F10;
+ break;
+ case 10:
+ keyPressed = Common::KEYCODE_RETURN;
+ ascii = Common::ASCII_RETURN;
+ break;
}
event.type = Common::EVENT_KEYDOWN;
_queuedInputEvent.type = Common::EVENT_KEYUP;
@@ -460,60 +423,60 @@ void OSystem_IPHONE::handleEvent_keyPressed(Common::Event &event, int keyPresse
bool OSystem_IPHONE::handleEvent_swipe(Common::Event &event, int direction) {
Common::KeyCode keycode = Common::KEYCODE_INVALID;
switch (_screenOrientation) {
- case kScreenOrientationPortrait:
- switch ((UIViewSwipeDirection)direction) {
- case kUIViewSwipeUp:
- keycode = Common::KEYCODE_UP;
- break;
- case kUIViewSwipeDown:
- keycode = Common::KEYCODE_DOWN;
- break;
- case kUIViewSwipeLeft:
- keycode = Common::KEYCODE_LEFT;
- break;
- case kUIViewSwipeRight:
- keycode = Common::KEYCODE_RIGHT;
- break;
- default:
- return false;
- }
+ case kScreenOrientationPortrait:
+ switch ((UIViewSwipeDirection)direction) {
+ case kUIViewSwipeUp:
+ keycode = Common::KEYCODE_UP;
+ break;
+ case kUIViewSwipeDown:
+ keycode = Common::KEYCODE_DOWN;
break;
- case kScreenOrientationLandscape:
- switch ((UIViewSwipeDirection)direction) {
- case kUIViewSwipeUp:
- keycode = Common::KEYCODE_LEFT;
- break;
- case kUIViewSwipeDown:
- keycode = Common::KEYCODE_RIGHT;
- break;
- case kUIViewSwipeLeft:
- keycode = Common::KEYCODE_DOWN;
- break;
- case kUIViewSwipeRight:
- keycode = Common::KEYCODE_UP;
- break;
- default:
- return false;
- }
+ case kUIViewSwipeLeft:
+ keycode = Common::KEYCODE_LEFT;
break;
- case kScreenOrientationFlippedLandscape:
- switch ((UIViewSwipeDirection)direction) {
- case kUIViewSwipeUp:
- keycode = Common::KEYCODE_RIGHT;
- break;
- case kUIViewSwipeDown:
- keycode = Common::KEYCODE_LEFT;
- break;
- case kUIViewSwipeLeft:
- keycode = Common::KEYCODE_UP;
- break;
- case kUIViewSwipeRight:
- keycode = Common::KEYCODE_DOWN;
- break;
- default:
- return false;
- }
+ case kUIViewSwipeRight:
+ keycode = Common::KEYCODE_RIGHT;
break;
+ default:
+ return false;
+ }
+ break;
+ case kScreenOrientationLandscape:
+ switch ((UIViewSwipeDirection)direction) {
+ case kUIViewSwipeUp:
+ keycode = Common::KEYCODE_LEFT;
+ break;
+ case kUIViewSwipeDown:
+ keycode = Common::KEYCODE_RIGHT;
+ break;
+ case kUIViewSwipeLeft:
+ keycode = Common::KEYCODE_DOWN;
+ break;
+ case kUIViewSwipeRight:
+ keycode = Common::KEYCODE_UP;
+ break;
+ default:
+ return false;
+ }
+ break;
+ case kScreenOrientationFlippedLandscape:
+ switch ((UIViewSwipeDirection)direction) {
+ case kUIViewSwipeUp:
+ keycode = Common::KEYCODE_RIGHT;
+ break;
+ case kUIViewSwipeDown:
+ keycode = Common::KEYCODE_LEFT;
+ break;
+ case kUIViewSwipeLeft:
+ keycode = Common::KEYCODE_UP;
+ break;
+ case kUIViewSwipeRight:
+ keycode = Common::KEYCODE_DOWN;
+ break;
+ default:
+ return false;
+ }
+ break;
}
event.kbd.keycode = _queuedInputEvent.kbd.keycode = keycode;
diff --git a/backends/platform/iphone/osys_main.cpp b/backends/platform/iphone/osys_main.cpp
index 4bc567c39d..9a33cd8968 100644
--- a/backends/platform/iphone/osys_main.cpp
+++ b/backends/platform/iphone/osys_main.cpp
@@ -45,7 +45,9 @@
const OSystem::GraphicsMode OSystem_IPHONE::s_supportedGraphicsModes[] = {
- {0, 0, 0}
+ { "linear", "Linear filtering", kGraphicsModeLinear },
+ { "none", "No filtering", kGraphicsModeNone },
+ { 0, 0, 0 }
};
AQCallbackStruct OSystem_IPHONE::s_AudioQueue;
@@ -53,28 +55,28 @@ SoundProc OSystem_IPHONE::s_soundCallback = NULL;
void *OSystem_IPHONE::s_soundParam = NULL;
OSystem_IPHONE::OSystem_IPHONE() :
- _mixer(NULL), _offscreen(NULL),
- _overlayVisible(false), _fullscreen(NULL),
- _mouseHeight(0), _mouseWidth(0), _mouseBuf(NULL), _lastMouseTap(0), _queuedEventTime(0),
- _secondaryTapped(false), _lastSecondaryTap(0),
+ _mixer(NULL), _lastMouseTap(0), _queuedEventTime(0),
+ _mouseNeedTextureUpdate(false), _secondaryTapped(false), _lastSecondaryTap(0),
_screenOrientation(kScreenOrientationFlippedLandscape), _mouseClickAndDragEnabled(false),
_gestureStartX(-1), _gestureStartY(-1), _fullScreenIsDirty(false), _fullScreenOverlayIsDirty(false),
_mouseDirty(false), _timeSuspended(0), _lastDragPosX(-1), _lastDragPosY(-1), _screenChangeCount(0),
- _overlayHeight(0), _overlayWidth(0), _overlayBuffer(0)
-{
- _queuedInputEvent.type = (Common::EventType)0;
- _lastDrawnMouseRect = Common::Rect(0, 0, 0, 0);
-
+ _mouseCursorPaletteEnabled(false), _gfxTransactionError(kTransactionSuccess) {
+ _queuedInputEvent.type = Common::EVENT_INVALID;
_touchpadModeEnabled = !iPhone_isHighResDevice();
_fsFactory = new POSIXFilesystemFactory();
+ initVideoContext();
}
OSystem_IPHONE::~OSystem_IPHONE() {
AudioQueueDispose(s_AudioQueue.queue, true);
delete _mixer;
- delete _offscreen;
- delete _fullscreen;
+ // Prevent accidental freeing of the screen texture here. This needs to be
+ // checked since we might use the screen texture as framebuffer in the case
+ // of hi-color games for example.
+ if (_framebuffer.pixels == _videoContext->screenTexture.pixels)
+ _framebuffer.free();
+ _mouseBuffer.free();
}
int OSystem_IPHONE::timerHandler(int t) {
@@ -102,26 +104,55 @@ void OSystem_IPHONE::initBackend() {
}
bool OSystem_IPHONE::hasFeature(Feature f) {
- return false;
+ switch (f) {
+ case kFeatureCursorPalette:
+ return true;
+
+ default:
+ return false;
+ }
}
void OSystem_IPHONE::setFeatureState(Feature f, bool enable) {
+ switch (f) {
+ case kFeatureCursorPalette:
+ if (_mouseCursorPaletteEnabled != enable) {
+ _mouseNeedTextureUpdate = true;
+ _mouseDirty = true;
+ _mouseCursorPaletteEnabled = enable;
+ }
+ break;
+ case kFeatureAspectRatioCorrection:
+ _videoContext->asprectRatioCorrection = enable;
+ break;
+
+ default:
+ break;
+ }
}
bool OSystem_IPHONE::getFeatureState(Feature f) {
- return false;
+ switch (f) {
+ case kFeatureCursorPalette:
+ return _mouseCursorPaletteEnabled;
+ case kFeatureAspectRatioCorrection:
+ return _videoContext->asprectRatioCorrection;
+
+ default:
+ return false;
+ }
}
void OSystem_IPHONE::suspendLoop() {
bool done = false;
int eventType;
- float xUnit, yUnit;
+ int x, y;
uint32 startTime = getMillis();
stopSoundsystem();
while (!done) {
- if (iPhone_fetchEvent(&eventType, &xUnit, &yUnit))
+ if (iPhone_fetchEvent(&eventType, &x, &y))
if ((InputEvent)eventType == kInputApplicationResumed)
done = true;
usleep(100000);
@@ -226,7 +257,6 @@ Common::String OSystem_IPHONE::getDefaultConfigFileName() {
#endif
}
-
void OSystem_IPHONE::addSysArchivesToSearchSet(Common::SearchSet &s, int priority) {
// Get URL of the Resource directory of the .app bundle
CFURLRef fileUrl = CFBundleCopyResourcesDirectoryURL(CFBundleGetMainBundle());
@@ -272,7 +302,7 @@ void iphone_main(int argc, char *argv[]) {
}
#ifdef IPHONE_OFFICIAL
- chdir( iPhone_getDocumentsDir() );
+ chdir(iPhone_getDocumentsDir());
#else
system("mkdir " SCUMMVM_ROOT_PATH);
system("mkdir " SCUMMVM_SAVE_PATH);
diff --git a/backends/platform/iphone/osys_main.h b/backends/platform/iphone/osys_main.h
index 37896cceeb..b443e22f56 100644
--- a/backends/platform/iphone/osys_main.h
+++ b/backends/platform/iphone/osys_main.h
@@ -20,6 +20,9 @@
*
*/
+#ifndef BACKENDS_PLATFORM_IPHONE_OSYS_MAIN_H
+#define BACKENDS_PLATFORM_IPHONE_OSYS_MAIN_H
+
#include "graphics/surface.h"
#include "iphone_common.h"
#include "backends/base-backend.h"
@@ -42,16 +45,15 @@
typedef void (*SoundProc)(void *param, byte *buf, int len);
typedef int (*TimerProc)(int interval);
-typedef struct AQCallbackStruct {
- AudioQueueRef queue;
- uint32 frameCount;
- AudioQueueBufferRef buffers[AUDIO_BUFFERS];
- AudioStreamBasicDescription dataFormat;
-} AQCallbackStruct;
+struct AQCallbackStruct {
+ AudioQueueRef queue;
+ uint32 frameCount;
+ AudioQueueBufferRef buffers[AUDIO_BUFFERS];
+ AudioStreamBasicDescription dataFormat;
+};
class OSystem_IPHONE : public EventsBaseBackend, public PaletteManager {
protected:
-
static const OSystem::GraphicsMode s_supportedGraphicsModes[];
static AQCallbackStruct s_AudioQueue;
static SoundProc s_soundCallback;
@@ -59,33 +61,31 @@ protected:
Audio::MixerImpl *_mixer;
+ VideoContext *_videoContext;
+
Graphics::Surface _framebuffer;
- byte *_offscreen;
- OverlayColor *_overlayBuffer;
- uint16 _overlayHeight;
- uint16 _overlayWidth;
- uint16 *_fullscreen;
+ // For signaling that screen format set up might have failed.
+ TransactionError _gfxTransactionError;
- uint16 _palette[256];
- bool _overlayVisible;
- uint16 _screenWidth;
- uint16 _screenHeight;
+ // For use with the game texture
+ uint16 _gamePalette[256];
+ // For use with the mouse texture
+ uint16 _gamePaletteRGBA5551[256];
struct timeval _startTime;
uint32 _timeSuspended;
- bool _mouseVisible;
- byte *_mouseBuf;
- byte _mouseKeyColor;
- uint _mouseWidth, _mouseHeight;
- uint _mouseX, _mouseY;
- int _mouseHotspotX, _mouseHotspotY;
+ bool _mouseCursorPaletteEnabled;
+ uint16 _mouseCursorPalette[256];
+ Graphics::Surface _mouseBuffer;
+ uint16 _mouseKeyColor;
bool _mouseDirty;
+ bool _mouseNeedTextureUpdate;
+
long _lastMouseDown;
long _lastMouseTap;
long _queuedEventTime;
- Common::Rect _lastDrawnMouseRect;
Common::Event _queuedInputEvent;
bool _secondaryTapped;
long _lastSecondaryDown;
@@ -121,13 +121,21 @@ public:
virtual bool getFeatureState(Feature f);
virtual const GraphicsMode *getSupportedGraphicsModes() const;
virtual int getDefaultGraphicsMode() const;
- bool setGraphicsMode(const char *name);
virtual bool setGraphicsMode(int mode);
virtual int getGraphicsMode() const;
virtual void initSize(uint width, uint height, const Graphics::PixelFormat *format);
+
+ virtual void beginGFXTransaction();
+ virtual TransactionError endGFXTransaction();
+
virtual int16 getHeight();
virtual int16 getWidth();
+#ifdef USE_RGB_COLOR
+ virtual Graphics::PixelFormat getScreenFormat() const { return _framebuffer.format; }
+ virtual Common::List<Graphics::PixelFormat> getSupportedFormats() const;
+#endif
+
virtual PaletteManager *getPaletteManager() { return this; }
protected:
// PaletteManager API
@@ -154,6 +162,7 @@ public:
virtual void warpMouse(int x, int y);
virtual void setMouseCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor = 255, int cursorTargetScale = 1, const Graphics::PixelFormat *format = NULL);
+ virtual void setCursorPalette(const byte *colors, uint start, uint num);
virtual bool pollEvent(Common::Event &event);
virtual uint32 getMillis();
@@ -167,7 +176,7 @@ public:
static void mixCallback(void *sys, byte *samples, int len);
virtual void setupMixer(void);
virtual void setTimerCallback(TimerProc callback, int interval);
- virtual int getScreenChangeID() const { return _screenChangeCount; }
+ virtual int getScreenChangeID() const { return _screenChangeCount; }
virtual void quit();
virtual void addSysArchivesToSearchSet(Common::SearchSet &s, int priority = 0);
@@ -183,15 +192,15 @@ public:
virtual void logMessage(LogMessageType::Type type, const char *message);
protected:
+ void initVideoContext();
+ void updateOutputSurface();
+
void internUpdateScreen();
void dirtyFullScreen();
void dirtyFullOverlayScreen();
- void clipRectToScreen(int16 &x, int16 &y, int16 &w, int16 &h);
void suspendLoop();
- void drawDirtyRect(const Common::Rect& dirtyRect);
- void drawDirtyOverlayRect(const Common::Rect& dirtyRect);
- void drawMouseCursorOnRectUpdate(const Common::Rect& updatedRect, const Common::Rect& mouseRect);
- void updateHardwareSurfaceForRect(const Common::Rect& updatedRect);
+ void drawDirtyRect(const Common::Rect &dirtyRect);
+ void updateMouseTexture();
static void AQBufferCallback(void *in, AudioQueueRef inQ, AudioQueueBufferRef outQB);
static int timerHandler(int t);
@@ -208,3 +217,5 @@ protected:
bool handleEvent_mouseDragged(Common::Event &event, int x, int y);
bool handleEvent_mouseSecondDragged(Common::Event &event, int x, int y);
};
+
+#endif
diff --git a/backends/platform/iphone/osys_video.cpp b/backends/platform/iphone/osys_video.cpp
deleted file mode 100644
index fa425b108a..0000000000
--- a/backends/platform/iphone/osys_video.cpp
+++ /dev/null
@@ -1,503 +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.
- *
- */
-
-// Disable symbol overrides so that we can use system headers.
-#define FORBIDDEN_SYMBOL_ALLOW_ALL
-
-#include "osys_main.h"
-
-const OSystem::GraphicsMode* OSystem_IPHONE::getSupportedGraphicsModes() const {
- return s_supportedGraphicsModes;
-}
-
-
-int OSystem_IPHONE::getDefaultGraphicsMode() const {
- return -1;
-}
-
-bool OSystem_IPHONE::setGraphicsMode(const char *mode) {
- return true;
-}
-
-bool OSystem_IPHONE::setGraphicsMode(int mode) {
- return true;
-}
-
-int OSystem_IPHONE::getGraphicsMode() const {
- return -1;
-}
-
-void OSystem_IPHONE::initSize(uint width, uint height, const Graphics::PixelFormat *format) {
- //printf("initSize(%i, %i)\n", width, height);
-
- _screenWidth = width;
- _screenHeight = height;
-
- free(_offscreen);
-
- _offscreen = (byte *)malloc(width * height);
- bzero(_offscreen, width * height);
-
- //free(_overlayBuffer);
-
- int fullSize = _screenWidth * _screenHeight * sizeof(OverlayColor);
- //_overlayBuffer = (OverlayColor *)malloc(fullSize);
- clearOverlay();
-
- free(_fullscreen);
-
- _fullscreen = (uint16 *)malloc(fullSize);
- bzero(_fullscreen, fullSize);
-
- iPhone_initSurface(width, height);
-
- if (_overlayBuffer == NULL) {
- _overlayHeight = iPhone_getScreenHeight();
- _overlayWidth = iPhone_getScreenWidth();
-
- printf("Overlay: (%u x %u)\n", _overlayWidth, _overlayHeight);
- _overlayBuffer = new OverlayColor[_overlayHeight * _overlayWidth];
- }
-
- _fullScreenIsDirty = false;
- dirtyFullScreen();
- _mouseVisible = false;
- _screenChangeCount++;
- updateScreen();
-}
-
-int16 OSystem_IPHONE::getHeight() {
- return _screenHeight;
-}
-
-int16 OSystem_IPHONE::getWidth() {
- return _screenWidth;
-}
-
-void OSystem_IPHONE::setPalette(const byte *colors, uint start, uint num) {
- assert(start + num <= 256);
- const byte *b = colors;
-
- for (uint i = start; i < start + num; ++i) {
- _palette[i] = Graphics::RGBToColor<Graphics::ColorMasks<565> >(b[0], b[1], b[2]);
- b += 3;
- }
-
- dirtyFullScreen();
-}
-
-void OSystem_IPHONE::grabPalette(byte *colors, uint start, uint num) {
- assert(start + num <= 256);
- byte *b = colors;
-
- for (uint i = start; i < start + num; ++i) {
- Graphics::colorToRGB<Graphics::ColorMasks<565> >(_palette[i], b[0], b[1], b[2]);
- b += 3;
- }
-}
-
-void OSystem_IPHONE::copyRectToScreen(const byte *buf, int pitch, int x, int y, int w, int h) {
- //printf("copyRectToScreen(%i, %i, %i, %i)\n", x, y, w, h);
- //Clip the coordinates
- if (x < 0) {
- w += x;
- buf -= x;
- x = 0;
- }
-
- if (y < 0) {
- h += y;
- buf -= y * pitch;
- y = 0;
- }
-
- if (w > _screenWidth - x) {
- w = _screenWidth - x;
- }
-
- if (h > _screenHeight - y) {
- h = _screenHeight - y;
- }
-
- if (w <= 0 || h <= 0)
- return;
-
- if (!_fullScreenIsDirty) {
- _dirtyRects.push_back(Common::Rect(x, y, x + w, y + h));
- }
-
-
- byte *dst = _offscreen + y * _screenWidth + x;
- if (_screenWidth == pitch && pitch == w)
- memcpy(dst, buf, h * w);
- else {
- do {
- memcpy(dst, buf, w);
- buf += pitch;
- dst += _screenWidth;
- } while (--h);
- }
-}
-
-void OSystem_IPHONE::clipRectToScreen(int16 &x, int16 &y, int16 &w, int16 &h) {
- if (x < 0) {
- w += x;
- x = 0;
- }
-
- if (y < 0) {
- h += y;
- y = 0;
- }
-
- if (w > _screenWidth - x)
- w = _screenWidth - x;
-
- if (h > _screenHeight - y)
- h = _screenHeight - y;
-
- if (w < 0) {
- w = 0;
- }
-
- if (h < 0) {
- h = 0;
- }
-}
-
-void OSystem_IPHONE::updateScreen() {
- //printf("updateScreen(): %i dirty rects.\n", _dirtyRects.size());
-
- if (_dirtyRects.size() == 0 && _dirtyOverlayRects.size() == 0 && !_mouseDirty)
- return;
-
- internUpdateScreen();
- _fullScreenIsDirty = false;
- _fullScreenOverlayIsDirty = false;
-
- iPhone_updateScreen(_mouseX - _mouseHotspotX, _mouseY - _mouseHotspotY);
-}
-
-void OSystem_IPHONE::internUpdateScreen() {
- int16 mouseX = _mouseX - _mouseHotspotX;
- int16 mouseY = _mouseY - _mouseHotspotY;
- int16 mouseWidth = _mouseWidth;
- int16 mouseHeight = _mouseHeight;
-
- clipRectToScreen(mouseX, mouseY, mouseWidth, mouseHeight);
-
- Common::Rect mouseRect(mouseX, mouseY, mouseX + mouseWidth, mouseY + mouseHeight);
-
- if (_mouseDirty) {
- if (!_fullScreenIsDirty) {
- _dirtyRects.push_back(_lastDrawnMouseRect);
- _dirtyRects.push_back(mouseRect);
- }
- if (!_fullScreenOverlayIsDirty && _overlayVisible) {
- _dirtyOverlayRects.push_back(_lastDrawnMouseRect);
- _dirtyOverlayRects.push_back(mouseRect);
- }
- _mouseDirty = false;
- _lastDrawnMouseRect = mouseRect;
- }
-
- while (_dirtyRects.size()) {
- Common::Rect dirtyRect = _dirtyRects.remove_at(_dirtyRects.size() - 1);
-
- //printf("Drawing: (%i, %i) -> (%i, %i)\n", dirtyRect.left, dirtyRect.top, dirtyRect.right, dirtyRect.bottom);
-
- drawDirtyRect(dirtyRect);
-
- if (_overlayVisible)
- drawDirtyOverlayRect(dirtyRect);
- else
- drawMouseCursorOnRectUpdate(dirtyRect, mouseRect);
-
- updateHardwareSurfaceForRect(dirtyRect);
- }
-
- if (_overlayVisible) {
- while (_dirtyOverlayRects.size()) {
- Common::Rect dirtyRect = _dirtyOverlayRects.remove_at(_dirtyOverlayRects.size() - 1);
-
- //printf("Drawing: (%i, %i) -> (%i, %i)\n", dirtyRect.left, dirtyRect.top, dirtyRect.right, dirtyRect.bottom);
-
- drawDirtyOverlayRect(dirtyRect);
- //drawMouseCursorOnRectUpdate(dirtyRect, mouseRect);
- //updateHardwareSurfaceForRect(dirtyRect);
- }
- }
-}
-
-void OSystem_IPHONE::drawDirtyRect(const Common::Rect& dirtyRect) {
- int h = dirtyRect.bottom - dirtyRect.top;
- int w = dirtyRect.right - dirtyRect.left;
-
- byte *src = &_offscreen[dirtyRect.top * _screenWidth + dirtyRect.left];
- uint16 *dst = &_fullscreen[dirtyRect.top * _screenWidth + dirtyRect.left];
- for (int y = h; y > 0; y--) {
- for (int x = w; x > 0; x--)
- *dst++ = _palette[*src++];
-
- dst += _screenWidth - w;
- src += _screenWidth - w;
- }
-}
-
-void OSystem_IPHONE::drawDirtyOverlayRect(const Common::Rect& dirtyRect) {
- // int h = dirtyRect.bottom - dirtyRect.top;
- //
- // uint16 *src = (uint16 *)&_overlayBuffer[dirtyRect.top * _screenWidth + dirtyRect.left];
- // uint16 *dst = &_fullscreen[dirtyRect.top * _screenWidth + dirtyRect.left];
- // int x = (dirtyRect.right - dirtyRect.left) * 2;
- // for (int y = h; y > 0; y--) {
- // memcpy(dst, src, x);
- // src += _screenWidth;
- // dst += _screenWidth;
- // }
- iPhone_updateOverlayRect(_overlayBuffer, dirtyRect.left, dirtyRect.top, dirtyRect.right, dirtyRect.bottom);
-}
-
-void OSystem_IPHONE::drawMouseCursorOnRectUpdate(const Common::Rect& updatedRect, const Common::Rect& mouseRect) {
- //draw mouse on top
- if (_mouseVisible && (updatedRect.intersects(mouseRect))) {
- int srcX = 0;
- int srcY = 0;
- int left = _mouseX - _mouseHotspotX;
- if (left < 0) {
- srcX -= left;
- left = 0;
- }
- int top = _mouseY - _mouseHotspotY;
- if (top < 0) {
- srcY -= top;
- top = 0;
- }
-
- int bottom = top + _mouseHeight;
- if (bottom > _screenWidth)
- bottom = _screenWidth;
-
- int displayWidth = _mouseWidth;
- if (_mouseWidth + left > _screenWidth)
- displayWidth = _screenWidth - left;
-
- int displayHeight = _mouseHeight;
- if (_mouseHeight + top > _screenHeight)
- displayHeight = _screenHeight - top;
-
- byte *src = &_mouseBuf[srcY * _mouseWidth + srcX];
- uint16 *dst = &_fullscreen[top * _screenWidth + left];
- for (int y = displayHeight; y > srcY; y--) {
- for (int x = displayWidth; x > srcX; x--) {
- if (*src != _mouseKeyColor)
- *dst = _palette[*src];
- dst++;
- src++;
- }
- dst += _screenWidth - displayWidth + srcX;
- src += _mouseWidth - displayWidth + srcX;
- }
- }
-}
-
-void OSystem_IPHONE::updateHardwareSurfaceForRect(const Common::Rect& updatedRect) {
- iPhone_updateScreenRect(_fullscreen, updatedRect.left, updatedRect.top, updatedRect.right, updatedRect.bottom );
-}
-
-Graphics::Surface *OSystem_IPHONE::lockScreen() {
- //printf("lockScreen()\n");
-
- _framebuffer.pixels = _offscreen;
- _framebuffer.w = _screenWidth;
- _framebuffer.h = _screenHeight;
- _framebuffer.pitch = _screenWidth;
- _framebuffer.format = Graphics::PixelFormat::createFormatCLUT8();
-
- return &_framebuffer;
-}
-
-void OSystem_IPHONE::unlockScreen() {
- //printf("unlockScreen()\n");
- dirtyFullScreen();
-}
-
-void OSystem_IPHONE::setShakePos(int shakeOffset) {
- //printf("setShakePos(%i)\n", shakeOffset);
-}
-
-void OSystem_IPHONE::showOverlay() {
- //printf("showOverlay()\n");
- _overlayVisible = true;
- dirtyFullOverlayScreen();
- updateScreen();
- iPhone_enableOverlay(true);
-}
-
-void OSystem_IPHONE::hideOverlay() {
- //printf("hideOverlay()\n");
- _overlayVisible = false;
- _dirtyOverlayRects.clear();
- dirtyFullScreen();
- iPhone_enableOverlay(false);
-}
-
-void OSystem_IPHONE::clearOverlay() {
- //printf("clearOverlay()\n");
- bzero(_overlayBuffer, _overlayWidth * _overlayHeight * sizeof(OverlayColor));
- dirtyFullOverlayScreen();
-}
-
-void OSystem_IPHONE::grabOverlay(OverlayColor *buf, int pitch) {
- //printf("grabOverlay()\n");
- int h = _overlayHeight;
- OverlayColor *src = _overlayBuffer;
-
- do {
- memcpy(buf, src, _overlayWidth * sizeof(OverlayColor));
- src += _overlayWidth;
- buf += pitch;
- } while (--h);
-}
-
-void OSystem_IPHONE::copyRectToOverlay(const OverlayColor *buf, int pitch, int x, int y, int w, int h) {
- //printf("copyRectToOverlay(buf, pitch=%i, x=%i, y=%i, w=%i, h=%i)\n", pitch, x, y, w, h);
-
- //Clip the coordinates
- if (x < 0) {
- w += x;
- buf -= x;
- x = 0;
- }
-
- if (y < 0) {
- h += y;
- buf -= y * pitch;
- y = 0;
- }
-
- if (w > _overlayWidth - x)
- w = _overlayWidth - x;
-
- if (h > _overlayHeight - y)
- h = _overlayHeight - y;
-
- if (w <= 0 || h <= 0)
- return;
-
- if (!_fullScreenOverlayIsDirty) {
- _dirtyOverlayRects.push_back(Common::Rect(x, y, x + w, y + h));
- }
-
- OverlayColor *dst = _overlayBuffer + (y * _overlayWidth + x);
- if (_overlayWidth == pitch && pitch == w)
- memcpy(dst, buf, h * w * sizeof(OverlayColor));
- else {
- do {
- memcpy(dst, buf, w * sizeof(OverlayColor));
- buf += pitch;
- dst += _overlayWidth;
- } while (--h);
- }
-}
-
-int16 OSystem_IPHONE::getOverlayHeight() {
- return _overlayHeight;
-}
-
-int16 OSystem_IPHONE::getOverlayWidth() {
- return _overlayWidth;
-}
-
-bool OSystem_IPHONE::showMouse(bool visible) {
- bool last = _mouseVisible;
- _mouseVisible = visible;
- _mouseDirty = true;
-
- return last;
-}
-
-void OSystem_IPHONE::warpMouse(int x, int y) {
- //printf("warpMouse()\n");
-
- _mouseX = x;
- _mouseY = y;
- _mouseDirty = true;
-}
-
-void OSystem_IPHONE::dirtyFullScreen() {
- if (!_fullScreenIsDirty) {
- _dirtyRects.clear();
- _dirtyRects.push_back(Common::Rect(0, 0, _screenWidth, _screenHeight));
- _fullScreenIsDirty = true;
- }
-}
-
-void OSystem_IPHONE::dirtyFullOverlayScreen() {
- if (!_fullScreenOverlayIsDirty) {
- _dirtyOverlayRects.clear();
- _dirtyOverlayRects.push_back(Common::Rect(0, 0, _overlayWidth, _overlayHeight));
- _fullScreenOverlayIsDirty = true;
- }
-}
-
-void OSystem_IPHONE::setMouseCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, int cursorTargetScale, const Graphics::PixelFormat *format) {
- //printf("setMouseCursor(%i, %i, scale %u)\n", hotspotX, hotspotY, cursorTargetScale);
-
- int texWidth = getSizeNextPOT(w);
- int texHeight = getSizeNextPOT(h);
- int bufferSize = texWidth * texHeight * sizeof(int16);
- int16* mouseBuf = (int16*)malloc(bufferSize);
- memset(mouseBuf, 0, bufferSize);
-
- for (uint x = 0; x < w; ++x) {
- for (uint y = 0; y < h; ++y) {
- byte color = buf[y * w + x];
- if (color != keycolor)
- mouseBuf[y * texWidth + x] = _palette[color] | 0x1;
- else
- mouseBuf[y * texWidth + x] = 0x0;
- }
- }
-
- iPhone_setMouseCursor(mouseBuf, w, h);
-
- if (_mouseBuf != NULL && (_mouseWidth != w || _mouseHeight != h)) {
- free(_mouseBuf);
- _mouseBuf = NULL;
- }
-
- if (_mouseBuf == NULL)
- _mouseBuf = (byte *)malloc(w * h);
-
- _mouseWidth = w;
- _mouseHeight = h;
-
- _mouseHotspotX = hotspotX;
- _mouseHotspotY = hotspotY;
-
- _mouseKeyColor = (byte)keycolor;
-
- memcpy(_mouseBuf, buf, w * h);
-
- _mouseDirty = true;
-}
diff --git a/backends/platform/iphone/osys_video.mm b/backends/platform/iphone/osys_video.mm
new file mode 100644
index 0000000000..6f80a6cba3
--- /dev/null
+++ b/backends/platform/iphone/osys_video.mm
@@ -0,0 +1,491 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+// Disable symbol overrides so that we can use system headers.
+#define FORBIDDEN_SYMBOL_ALLOW_ALL
+
+#include "osys_main.h"
+#include "iphone_video.h"
+
+#include "graphics/conversion.h"
+
+void OSystem_IPHONE::initVideoContext() {
+ _videoContext = [g_iPhoneViewInstance getVideoContext];
+}
+
+const OSystem::GraphicsMode *OSystem_IPHONE::getSupportedGraphicsModes() const {
+ return s_supportedGraphicsModes;
+}
+
+int OSystem_IPHONE::getDefaultGraphicsMode() const {
+ return kGraphicsModeLinear;
+}
+
+bool OSystem_IPHONE::setGraphicsMode(int mode) {
+ switch (mode) {
+ case kGraphicsModeNone:
+ case kGraphicsModeLinear:
+ _videoContext->graphicsMode = (GraphicsModes)mode;
+ return true;
+
+ default:
+ return false;
+ }
+}
+
+int OSystem_IPHONE::getGraphicsMode() const {
+ return _videoContext->graphicsMode;
+}
+
+#ifdef USE_RGB_COLOR
+Common::List<Graphics::PixelFormat> OSystem_IPHONE::getSupportedFormats() const {
+ Common::List<Graphics::PixelFormat> list;
+ // RGB565
+ list.push_back(Graphics::createPixelFormat<565>());
+ // CLUT8
+ list.push_back(Graphics::PixelFormat::createFormatCLUT8());
+ return list;
+}
+#endif
+
+void OSystem_IPHONE::initSize(uint width, uint height, const Graphics::PixelFormat *format) {
+ //printf("initSize(%u, %u, %p)\n", width, height, (const void *)format);
+
+ _videoContext->screenWidth = width;
+ _videoContext->screenHeight = height;
+ _videoContext->shakeOffsetY = 0;
+
+ // In case we use the screen texture as frame buffer we reset the pixels
+ // pointer here to avoid freeing the screen texture.
+ if (_framebuffer.pixels == _videoContext->screenTexture.pixels)
+ _framebuffer.pixels = 0;
+
+ // Create the screen texture right here. We need to do this here, since
+ // when a game requests hi-color mode, we actually set the framebuffer
+ // to the texture buffer to avoid an additional copy step.
+ [g_iPhoneViewInstance performSelectorOnMainThread:@selector(createScreenTexture) withObject:nil waitUntilDone: YES];
+
+ // In case the client code tries to set up a non supported mode, we will
+ // fall back to CLUT8 and set the transaction error accordingly.
+ if (format && format->bytesPerPixel != 1 && *format != _videoContext->screenTexture.format) {
+ format = 0;
+ _gfxTransactionError = kTransactionFormatNotSupported;
+ }
+
+ if (!format || format->bytesPerPixel == 1) {
+ _framebuffer.create(width, height, Graphics::PixelFormat::createFormatCLUT8());
+ } else {
+#if 0
+ printf("bytesPerPixel: %u RGBAlosses: %u,%u,%u,%u RGBAshifts: %u,%u,%u,%u\n", format->bytesPerPixel,
+ format->rLoss, format->gLoss, format->bLoss, format->aLoss,
+ format->rShift, format->gShift, format->bShift, format->aShift);
+#endif
+ // We directly draw on the screen texture in hi-color mode. Thus
+ // we copy over its settings here and just replace the width and
+ // height to avoid any problems.
+ _framebuffer = _videoContext->screenTexture;
+ _framebuffer.w = width;
+ _framebuffer.h = height;
+ }
+
+ _fullScreenIsDirty = false;
+ dirtyFullScreen();
+ _mouseCursorPaletteEnabled = false;
+}
+
+void OSystem_IPHONE::beginGFXTransaction() {
+ _gfxTransactionError = kTransactionSuccess;
+}
+
+OSystem::TransactionError OSystem_IPHONE::endGFXTransaction() {
+ _screenChangeCount++;
+ updateOutputSurface();
+ [g_iPhoneViewInstance performSelectorOnMainThread:@selector(setGraphicsMode) withObject:nil waitUntilDone: YES];
+
+ return _gfxTransactionError;
+}
+
+void OSystem_IPHONE::updateOutputSurface() {
+ [g_iPhoneViewInstance performSelectorOnMainThread:@selector(initSurface) withObject:nil waitUntilDone: YES];
+}
+
+int16 OSystem_IPHONE::getHeight() {
+ return _videoContext->screenHeight;
+}
+
+int16 OSystem_IPHONE::getWidth() {
+ return _videoContext->screenWidth;
+}
+
+void OSystem_IPHONE::setPalette(const byte *colors, uint start, uint num) {
+ assert(start + num <= 256);
+ const byte *b = colors;
+
+ for (uint i = start; i < start + num; ++i) {
+ _gamePalette[i] = Graphics::RGBToColor<Graphics::ColorMasks<565> >(b[0], b[1], b[2]);
+ _gamePaletteRGBA5551[i] = Graphics::RGBToColor<Graphics::ColorMasks<5551> >(b[0], b[1], b[2]);
+ b += 3;
+ }
+
+ dirtyFullScreen();
+}
+
+void OSystem_IPHONE::grabPalette(byte *colors, uint start, uint num) {
+ assert(start + num <= 256);
+ byte *b = colors;
+
+ for (uint i = start; i < start + num; ++i) {
+ Graphics::colorToRGB<Graphics::ColorMasks<565> >(_gamePalette[i], b[0], b[1], b[2]);
+ b += 3;
+ }
+}
+
+void OSystem_IPHONE::copyRectToScreen(const byte *buf, int pitch, int x, int y, int w, int h) {
+ //printf("copyRectToScreen(%i, %i, %i, %i)\n", x, y, w, h);
+ //Clip the coordinates
+ if (x < 0) {
+ w += x;
+ buf -= x;
+ x = 0;
+ }
+
+ if (y < 0) {
+ h += y;
+ buf -= y * pitch;
+ y = 0;
+ }
+
+ if (w > (int)_framebuffer.w - x) {
+ w = _framebuffer.w - x;
+ }
+
+ if (h > (int)_framebuffer.h - y) {
+ h = _framebuffer.h - y;
+ }
+
+ if (w <= 0 || h <= 0)
+ return;
+
+ if (!_fullScreenIsDirty) {
+ _dirtyRects.push_back(Common::Rect(x, y, x + w, y + h));
+ }
+
+ byte *dst = (byte *)_framebuffer.getBasePtr(x, y);
+ if (_framebuffer.pitch == pitch && _framebuffer.w == w) {
+ memcpy(dst, buf, h * pitch);
+ } else {
+ do {
+ memcpy(dst, buf, w * _framebuffer.format.bytesPerPixel);
+ buf += pitch;
+ dst += _framebuffer.pitch;
+ } while (--h);
+ }
+}
+
+void OSystem_IPHONE::updateScreen() {
+ //printf("updateScreen(): %i dirty rects.\n", _dirtyRects.size());
+
+ if (_dirtyRects.size() == 0 && _dirtyOverlayRects.size() == 0 && !_mouseDirty)
+ return;
+
+ internUpdateScreen();
+ _mouseDirty = false;
+ _fullScreenIsDirty = false;
+ _fullScreenOverlayIsDirty = false;
+
+ iPhone_updateScreen();
+}
+
+void OSystem_IPHONE::internUpdateScreen() {
+ if (_mouseNeedTextureUpdate) {
+ updateMouseTexture();
+ _mouseNeedTextureUpdate = false;
+ }
+
+ while (_dirtyRects.size()) {
+ Common::Rect dirtyRect = _dirtyRects.remove_at(_dirtyRects.size() - 1);
+
+ //printf("Drawing: (%i, %i) -> (%i, %i)\n", dirtyRect.left, dirtyRect.top, dirtyRect.right, dirtyRect.bottom);
+ drawDirtyRect(dirtyRect);
+ // TODO: Implement dirty rect code
+ //updateHardwareSurfaceForRect(dirtyRect);
+ }
+
+ if (_videoContext->overlayVisible) {
+ // TODO: Implement dirty rect code
+ _dirtyOverlayRects.clear();
+ /*while (_dirtyOverlayRects.size()) {
+ Common::Rect dirtyRect = _dirtyOverlayRects.remove_at(_dirtyOverlayRects.size() - 1);
+
+ //printf("Drawing: (%i, %i) -> (%i, %i)\n", dirtyRect.left, dirtyRect.top, dirtyRect.right, dirtyRect.bottom);
+ drawDirtyOverlayRect(dirtyRect);
+ }*/
+ }
+}
+
+void OSystem_IPHONE::drawDirtyRect(const Common::Rect &dirtyRect) {
+ // We only need to do a color look up for CLUT8
+ if (_framebuffer.format.bytesPerPixel != 1)
+ return;
+
+ int h = dirtyRect.bottom - dirtyRect.top;
+ int w = dirtyRect.right - dirtyRect.left;
+
+ const byte *src = (const byte *)_framebuffer.getBasePtr(dirtyRect.left, dirtyRect.top);
+ byte *dstRaw = (byte *)_videoContext->screenTexture.getBasePtr(dirtyRect.left, dirtyRect.top);
+
+ // When we use CLUT8 do a color look up
+ for (int y = h; y > 0; y--) {
+ uint16 *dst = (uint16 *)dstRaw;
+ for (int x = w; x > 0; x--)
+ *dst++ = _gamePalette[*src++];
+
+ dstRaw += _videoContext->screenTexture.pitch;
+ src += _framebuffer.pitch - w;
+ }
+}
+
+Graphics::Surface *OSystem_IPHONE::lockScreen() {
+ //printf("lockScreen()\n");
+ return &_framebuffer;
+}
+
+void OSystem_IPHONE::unlockScreen() {
+ //printf("unlockScreen()\n");
+ dirtyFullScreen();
+}
+
+void OSystem_IPHONE::setShakePos(int shakeOffset) {
+ //printf("setShakePos(%i)\n", shakeOffset);
+ _videoContext->shakeOffsetY = shakeOffset;
+ [g_iPhoneViewInstance performSelectorOnMainThread:@selector(setViewTransformation) withObject:nil waitUntilDone: YES];
+ // HACK: We use this to force a redraw.
+ _mouseDirty = true;
+}
+
+void OSystem_IPHONE::showOverlay() {
+ //printf("showOverlay()\n");
+ _videoContext->overlayVisible = true;
+ dirtyFullOverlayScreen();
+ updateScreen();
+ [g_iPhoneViewInstance performSelectorOnMainThread:@selector(updateMouseCursorScaling) withObject:nil waitUntilDone: YES];
+ [g_iPhoneViewInstance performSelectorOnMainThread:@selector(clearColorBuffer) withObject:nil waitUntilDone: YES];
+}
+
+void OSystem_IPHONE::hideOverlay() {
+ //printf("hideOverlay()\n");
+ _videoContext->overlayVisible = false;
+ _dirtyOverlayRects.clear();
+ dirtyFullScreen();
+ [g_iPhoneViewInstance performSelectorOnMainThread:@selector(updateMouseCursorScaling) withObject:nil waitUntilDone: YES];
+ [g_iPhoneViewInstance performSelectorOnMainThread:@selector(clearColorBuffer) withObject:nil waitUntilDone: YES];
+}
+
+void OSystem_IPHONE::clearOverlay() {
+ //printf("clearOverlay()\n");
+ bzero(_videoContext->overlayTexture.getBasePtr(0, 0), _videoContext->overlayTexture.h * _videoContext->overlayTexture.pitch);
+ dirtyFullOverlayScreen();
+}
+
+void OSystem_IPHONE::grabOverlay(OverlayColor *buf, int pitch) {
+ //printf("grabOverlay()\n");
+ int h = _videoContext->overlayHeight;
+
+ const byte *src = (const byte *)_videoContext->overlayTexture.getBasePtr(0, 0);
+ do {
+ memcpy(buf, src, _videoContext->overlayWidth * sizeof(OverlayColor));
+ src += _videoContext->overlayTexture.pitch;
+ buf += pitch;
+ } while (--h);
+}
+
+void OSystem_IPHONE::copyRectToOverlay(const OverlayColor *buf, int pitch, int x, int y, int w, int h) {
+ //printf("copyRectToOverlay(buf, pitch=%i, x=%i, y=%i, w=%i, h=%i)\n", pitch, x, y, w, h);
+
+ //Clip the coordinates
+ if (x < 0) {
+ w += x;
+ buf -= x;
+ x = 0;
+ }
+
+ if (y < 0) {
+ h += y;
+ buf -= y * pitch;
+ y = 0;
+ }
+
+ if (w > (int)_videoContext->overlayWidth - x)
+ w = _videoContext->overlayWidth - x;
+
+ if (h > (int)_videoContext->overlayHeight - y)
+ h = _videoContext->overlayHeight - y;
+
+ if (w <= 0 || h <= 0)
+ return;
+
+ if (!_fullScreenOverlayIsDirty) {
+ _dirtyOverlayRects.push_back(Common::Rect(x, y, x + w, y + h));
+ }
+
+ byte *dst = (byte *)_videoContext->overlayTexture.getBasePtr(x, y);
+ do {
+ memcpy(dst, buf, w * sizeof(OverlayColor));
+ buf += pitch;
+ dst += _videoContext->overlayTexture.pitch;
+ } while (--h);
+}
+
+int16 OSystem_IPHONE::getOverlayHeight() {
+ return _videoContext->overlayHeight;
+}
+
+int16 OSystem_IPHONE::getOverlayWidth() {
+ return _videoContext->overlayWidth;
+}
+
+bool OSystem_IPHONE::showMouse(bool visible) {
+ bool last = _videoContext->mouseIsVisible;
+ _videoContext->mouseIsVisible = visible;
+ _mouseDirty = true;
+
+ return last;
+}
+
+void OSystem_IPHONE::warpMouse(int x, int y) {
+ //printf("warpMouse()\n");
+ _videoContext->mouseX = x;
+ _videoContext->mouseY = y;
+ [g_iPhoneViewInstance performSelectorOnMainThread:@selector(notifyMouseMove) withObject:nil waitUntilDone: YES];
+ _mouseDirty = true;
+}
+
+void OSystem_IPHONE::dirtyFullScreen() {
+ if (!_fullScreenIsDirty) {
+ _dirtyRects.clear();
+ _dirtyRects.push_back(Common::Rect(0, 0, _videoContext->screenWidth, _videoContext->screenHeight));
+ _fullScreenIsDirty = true;
+ }
+}
+
+void OSystem_IPHONE::dirtyFullOverlayScreen() {
+ if (!_fullScreenOverlayIsDirty) {
+ _dirtyOverlayRects.clear();
+ _dirtyOverlayRects.push_back(Common::Rect(0, 0, _videoContext->overlayWidth, _videoContext->overlayHeight));
+ _fullScreenOverlayIsDirty = true;
+ }
+}
+
+void OSystem_IPHONE::setMouseCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, int cursorTargetScale, const Graphics::PixelFormat *format) {
+ //printf("setMouseCursor(%i, %i, scale %u)\n", hotspotX, hotspotY, cursorTargetScale);
+
+ const Graphics::PixelFormat pixelFormat = format ? *format : Graphics::PixelFormat::createFormatCLUT8();
+#if 0
+ printf("bytesPerPixel: %u RGBAlosses: %u,%u,%u,%u RGBAshifts: %u,%u,%u,%u\n", pixelFormat.bytesPerPixel,
+ pixelFormat.rLoss, pixelFormat.gLoss, pixelFormat.bLoss, pixelFormat.aLoss,
+ pixelFormat.rShift, pixelFormat.gShift, pixelFormat.bShift, pixelFormat.aShift);
+#endif
+ assert(pixelFormat.bytesPerPixel == 1 || pixelFormat.bytesPerPixel == 2);
+
+ if (_mouseBuffer.w != w || _mouseBuffer.h != h || _mouseBuffer.format != pixelFormat || !_mouseBuffer.pixels)
+ _mouseBuffer.create(w, h, pixelFormat);
+
+ _videoContext->mouseWidth = w;
+ _videoContext->mouseHeight = h;
+
+ _videoContext->mouseHotspotX = hotspotX;
+ _videoContext->mouseHotspotY = hotspotY;
+
+ _mouseKeyColor = keycolor;
+
+ memcpy(_mouseBuffer.getBasePtr(0, 0), buf, h * _mouseBuffer.pitch);
+
+ _mouseDirty = true;
+ _mouseNeedTextureUpdate = true;
+}
+
+void OSystem_IPHONE::setCursorPalette(const byte *colors, uint start, uint num) {
+ assert(start + num <= 256);
+
+ for (uint i = start; i < start + num; ++i, colors += 3)
+ _mouseCursorPalette[i] = Graphics::RGBToColor<Graphics::ColorMasks<5551> >(colors[0], colors[1], colors[2]);
+
+ // FIXME: This is just stupid, our client code seems to assume that this
+ // automatically enables the cursor palette.
+ _mouseCursorPaletteEnabled = true;
+
+ if (_mouseCursorPaletteEnabled)
+ _mouseDirty = _mouseNeedTextureUpdate = true;
+}
+
+void OSystem_IPHONE::updateMouseTexture() {
+ uint texWidth = getSizeNextPOT(_videoContext->mouseWidth);
+ uint texHeight = getSizeNextPOT(_videoContext->mouseHeight);
+
+ Graphics::Surface &mouseTexture = _videoContext->mouseTexture;
+ if (mouseTexture.w != texWidth || mouseTexture.h != texHeight)
+ mouseTexture.create(texWidth, texHeight, Graphics::createPixelFormat<5551>());
+
+ if (_mouseBuffer.format.bytesPerPixel == 1) {
+ const uint16 *palette;
+ if (_mouseCursorPaletteEnabled)
+ palette = _mouseCursorPalette;
+ else
+ palette = _gamePaletteRGBA5551;
+
+ uint16 *mouseBuf = (uint16 *)mouseTexture.getBasePtr(0, 0);
+ for (uint x = 0; x < _videoContext->mouseWidth; ++x) {
+ for (uint y = 0; y < _videoContext->mouseHeight; ++y) {
+ const byte color = *(const byte *)_mouseBuffer.getBasePtr(x, y);
+ if (color != _mouseKeyColor)
+ mouseBuf[y * texWidth + x] = palette[color] | 0x1;
+ else
+ mouseBuf[y * texWidth + x] = 0x0;
+ }
+ }
+ } else {
+ if (crossBlit((byte *)mouseTexture.getBasePtr(0, 0), (const byte *)_mouseBuffer.getBasePtr(0, 0), mouseTexture.pitch,
+ _mouseBuffer.pitch, _mouseBuffer.w, _mouseBuffer.h, mouseTexture.format, _mouseBuffer.format)) {
+ if (!_mouseBuffer.format.aBits()) {
+ // Apply color keying since the original cursor had no alpha channel.
+ const uint16 *src = (const uint16 *)_mouseBuffer.getBasePtr(0, 0);
+ uint8 *dstRaw = (uint8 *)mouseTexture.getBasePtr(0, 0);
+
+ for (uint y = 0; y < _mouseBuffer.h; ++y, dstRaw += mouseTexture.pitch) {
+ uint16 *dst = (uint16 *)dstRaw;
+ for (uint x = 0; x < _mouseBuffer.w; ++x, ++dst) {
+ if (*src++ == _mouseKeyColor)
+ *dst &= ~1;
+ else
+ *dst |= 1;
+ }
+ }
+ }
+ } else {
+ // TODO: Log this!
+ // Make the cursor all transparent... we really need a better fallback ;-).
+ memset(mouseTexture.getBasePtr(0, 0), 0, mouseTexture.h * mouseTexture.pitch);
+ }
+ }
+
+ [g_iPhoneViewInstance performSelectorOnMainThread:@selector(updateMouseCursor) withObject:nil waitUntilDone: YES];
+}
diff --git a/backends/platform/linuxmoto/hardwarekeys.cpp b/backends/platform/linuxmoto/hardwarekeys.cpp
index e10e39a23d..e1a5757430 100644
--- a/backends/platform/linuxmoto/hardwarekeys.cpp
+++ b/backends/platform/linuxmoto/hardwarekeys.cpp
@@ -33,60 +33,59 @@ struct Key {
KeyCode keycode;
uint16 ascii;
const char *desc;
- KeyType preferredAction;
bool shiftable;
};
static const Key keys[] = {
- { "FIRE", KEYCODE_RETURN, ASCII_RETURN, "Fire", kActionKeyType, false },
- { "CAMERA", KEYCODE_PAUSE, 0, "Camera", kActionKeyType, false },
- { "HANGUP", KEYCODE_ESCAPE, ASCII_ESCAPE, "Hangup", kStartKeyType, false },
- { "CALL", KEYCODE_SPACE, ASCII_SPACE, "Call", kActionKeyType, false },
- { "PLUS", KEYCODE_PLUS, '+', "+", kActionKeyType, false },
- { "MINUS", KEYCODE_MINUS, '-', "-", kActionKeyType, false },
+ { "FIRE", KEYCODE_RETURN, ASCII_RETURN, "Fire", false },
+ { "CAMERA", KEYCODE_PAUSE, 0, "Camera", false },
+ { "HANGUP", KEYCODE_ESCAPE, ASCII_ESCAPE, "Hangup", false },
+ { "CALL", KEYCODE_SPACE, ASCII_SPACE, "Call", false },
+ { "PLUS", KEYCODE_PLUS, '+', "+", false },
+ { "MINUS", KEYCODE_MINUS, '-', "-", false },
#ifdef MOTOMAGX
- {"BACKSPACE", KEYCODE_BACKSPACE, ASCII_BACKSPACE, "Backspace", kActionKeyType, false},
- {"TAB", KEYCODE_TAB, ASCII_TAB, "Tab", kActionKeyType, false},
- {"HASH", KEYCODE_HASH, '#', "#", kActionKeyType, false},
- {"ASTERISK", KEYCODE_ASTERISK, '*', "*", kActionKeyType, false},
- {"LEFTSOFT", KEYCODE_F9, ASCII_F9, "LeftSoft", kActionKeyType, false},
- {"RIGHTSOFT", KEYCODE_F11, ASCII_F11, "RightSoft", kActionKeyType, false},
- {"0", KEYCODE_0, '0', "0", kActionKeyType, false},
- {"1", KEYCODE_1, '1', "1", kActionKeyType, false},
- {"2", KEYCODE_2, '2', "2", kActionKeyType, false},
- {"3", KEYCODE_3, '3', "3", kActionKeyType, false},
- {"4", KEYCODE_4, '4', "4", kActionKeyType, false},
- {"5", KEYCODE_5, '5', "5", kActionKeyType, false},
- {"6", KEYCODE_6, '6', "6", kActionKeyType, false},
- {"7", KEYCODE_7, '7', "7", kActionKeyType, false},
- {"8", KEYCODE_8, '8', "8", kActionKeyType, false},
- {"9", KEYCODE_9, '9', "9", kActionKeyType, false},
+ {"BACKSPACE", KEYCODE_BACKSPACE, ASCII_BACKSPACE, "Backspace", false},
+ {"TAB", KEYCODE_TAB, ASCII_TAB, "Tab", false},
+ {"HASH", KEYCODE_HASH, '#', "#", false},
+ {"ASTERISK", KEYCODE_ASTERISK, '*', "*", false},
+ {"LEFTSOFT", KEYCODE_F9, ASCII_F9, "LeftSoft", false},
+ {"RIGHTSOFT", KEYCODE_F11, ASCII_F11, "RightSoft", false},
+ {"0", KEYCODE_0, '0', "0", false},
+ {"1", KEYCODE_1, '1', "1", false},
+ {"2", KEYCODE_2, '2', "2", false},
+ {"3", KEYCODE_3, '3', "3", false},
+ {"4", KEYCODE_4, '4', "4", false},
+ {"5", KEYCODE_5, '5', "5", false},
+ {"6", KEYCODE_6, '6', "6", false},
+ {"7", KEYCODE_7, '7', "7", false},
+ {"8", KEYCODE_8, '8', "8", false},
+ {"9", KEYCODE_9, '9', "9", false},
#endif
#ifdef MOTOEZX
- { "a", KEYCODE_a, 'a', "a", kActionKeyType, true },
- { "b", KEYCODE_b, 'b', "b", kActionKeyType, true },
- { "c", KEYCODE_c, 'c', "c", kActionKeyType, true },
- { "d", KEYCODE_d, 'd', "d", kActionKeyType, true },
- { "e", KEYCODE_e, 'e', "e", kActionKeyType, true },
- { "f", KEYCODE_f, 'f', "f", kActionKeyType, true },
- { "g", KEYCODE_g, 'g', "g", kActionKeyType, true },
- { "h", KEYCODE_h, 'h', "h", kActionKeyType, true },
- { "i", KEYCODE_i, 'i', "i", kActionKeyType, true },
- { "j", KEYCODE_j, 'j', "j", kActionKeyType, true },
+ { "a", KEYCODE_a, 'a', "a", true },
+ { "b", KEYCODE_b, 'b', "b", true },
+ { "c", KEYCODE_c, 'c', "c", true },
+ { "d", KEYCODE_d, 'd', "d", true },
+ { "e", KEYCODE_e, 'e', "e", true },
+ { "f", KEYCODE_f, 'f', "f", true },
+ { "g", KEYCODE_g, 'g', "g", true },
+ { "h", KEYCODE_h, 'h', "h", true },
+ { "i", KEYCODE_i, 'i', "i", true },
+ { "j", KEYCODE_j, 'j', "j", true },
#endif
// Numeric keypad
// Arrows + Home/End pad
- {"UP", KEYCODE_UP, 0, "Up", kDirUpKeyType, false},
- {"DOWN", KEYCODE_DOWN, 0, "Down", kDirDownKeyType, false},
- {"RIGHT", KEYCODE_RIGHT, 0, "Right", kDirRightKeyType, false},
- {"LEFT", KEYCODE_LEFT, 0, "Left", kDirLeftKeyType, false},
+ {"UP", KEYCODE_UP, 0, "Up", false},
+ {"DOWN", KEYCODE_DOWN, 0, "Down", false},
+ {"RIGHT", KEYCODE_RIGHT, 0, "Right", false},
+ {"LEFT", KEYCODE_LEFT, 0, "Left", false},
// Function keys
// Miscellaneous function keys
- {0, KEYCODE_INVALID, 0, 0, kGenericKeyType, false}
+ {0, KEYCODE_INVALID, 0, 0, false}
};
struct Mod {
@@ -106,9 +105,8 @@ static const Mod modifiers[] = {
{ KBD_SHIFT | KBD_CTRL | KBD_ALT, "C+A+", "Ctrl+Alt+", true },
{ 0, 0, 0, false }
};
-#endif
-
-Common::HardwareKeySet *OSystem_LINUXMOTO::getHardwareKeySet() {
- return OSystem_SDL::getHardwareKeySet();
+Common::HardwareInputSet *OSystem_LINUXMOTO::getHardwareInputSet() {
+ return OSystem_SDL::getHardwareInputSet();
}
+#endif
diff --git a/backends/platform/linuxmoto/linuxmoto-sdl.h b/backends/platform/linuxmoto/linuxmoto-sdl.h
index 97262ccbca..27f4e744bc 100644
--- a/backends/platform/linuxmoto/linuxmoto-sdl.h
+++ b/backends/platform/linuxmoto/linuxmoto-sdl.h
@@ -29,8 +29,10 @@ class OSystem_LINUXMOTO : public OSystem_POSIX {
public:
virtual void initBackend();
+#ifdef ENABLE_KEYMAPPER
// FIXME: This just calls parent methods, is it needed?
- virtual Common::HardwareKeySet *getHardwareKeySet();
+ virtual Common::HardwareInputSet *getHardwareInputSet();
+#endif
};
#endif
diff --git a/backends/platform/maemo/debian/changelog b/backends/platform/maemo/debian/changelog
index d3e0287186..8a9d8ee3c3 100644
--- a/backends/platform/maemo/debian/changelog
+++ b/backends/platform/maemo/debian/changelog
@@ -1,8 +1,14 @@
-scummvm (1.4.0~git) unstable; urgency=low
+scummvm (1.5.0~git) unstable; urgency=low
- * development snapshot
+ * Development snapshot
- -- Tarek Soliman <tsoliman@scummvm.org> Wed, 05 Oct 2011 19:01:25 -0500
+ -- Tarek Soliman <tsoliman@scummvm.org> Tue, 15 Nov 2011 14:56:57 -0600
+
+scummvm (1.4.0) unstable; urgency=low
+
+ * 1.4.0 release
+
+ -- Tarek Soliman <tsoliman@scummvm.org> Thu, 03 Nov 2011 13:54:04 -0500
scummvm (1.2.1~pre) unstable; urgency=low
diff --git a/backends/platform/maemo/debian/control b/backends/platform/maemo/debian/control
index a1f0d95002..6e1dfe2fd4 100644
--- a/backends/platform/maemo/debian/control
+++ b/backends/platform/maemo/debian/control
@@ -7,7 +7,7 @@ Build-Depends: debhelper (>> 4.0.0), libsdl1.2-dev, libmad0-dev, libasound2-dev,
Standards-Version: 3.6.1.1
Package: scummvm
Depends: ${shlibs:Depends}
-Architecture: i386 armel
+Architecture: armel
Section: user/games
Description: interpreter that will play graphic adventure games
written for LucasArts' SCUMM virtual machine, Sierra's AGI adventures,
@@ -17,6 +17,8 @@ Description: interpreter that will play graphic adventure games
Coktel Vision's Gobliiins, Wyrmkeep's Inherit the Earth,
Westwood's Legend of Kyrandia, and various others.
This package does not contain any actual games.
+XSBC-Bugtracker: https://sourceforge.net/tracker/?atid=418820&group_id=37116&func=browse
+XB-Maemo-Display-Name: ScummVM
XBS-Maemo-Icon-26:
iVBORw0KGgoAAAANSUhEUgAAABoAAAAaCAMAAACelLz8AAAC/VBMVEUICwcH
CQUKDAgLDQoMDwsOEAwREAUPEQ0QEg8PFQoRExAUEwoVFAwPGAcTFBIRFg0W
diff --git a/backends/platform/maemo/debian/rules b/backends/platform/maemo/debian/rules
index 7613df25b4..64add08de8 100755
--- a/backends/platform/maemo/debian/rules
+++ b/backends/platform/maemo/debian/rules
@@ -47,7 +47,7 @@ install: build
install -m0644 gui/themes/scummclassic.zip gui/themes/scummmodern.zip debian/scummvm/opt/scummvm/share
install -m0644 backends/vkeybd/packs/vkeybd_default.zip debian/scummvm/opt/scummvm/share
# for optified version we can also add engine datafiles
- install -m0644 dists/engine-data/drascula.dat dists/engine-data/hugo.dat dists/engine-data/kyra.dat dists/engine-data/lure.dat dists/engine-data/m4.dat dists/engine-data/mads.dat dists/engine-data/queen.tbl dists/engine-data/sky.cpt dists/engine-data/teenagent.dat dists/engine-data/toon.dat debian/scummvm/opt/scummvm/share
+ install -m0644 dists/engine-data/drascula.dat dists/engine-data/hugo.dat dists/engine-data/kyra.dat dists/engine-data/lure.dat dists/engine-data/queen.tbl dists/engine-data/sky.cpt dists/engine-data/teenagent.dat dists/engine-data/toon.dat debian/scummvm/opt/scummvm/share
install -m0644 -d debian/scummvm/usr/share/doc/scummvm
install -m0644 NEWS README COPYRIGHT debian/scummvm/usr/share/doc/scummvm
diff --git a/backends/platform/maemo/maemo-common.h b/backends/platform/maemo/maemo-common.h
index f33aa24278..0442b9c0ae 100644
--- a/backends/platform/maemo/maemo-common.h
+++ b/backends/platform/maemo/maemo-common.h
@@ -28,9 +28,10 @@
namespace Maemo {
enum ModelType {
- kModelTypeN800 = 1,
- kModelTypeN810 = 2,
- kModelTypeN900 = 4,
+ kModelType770 = 1 << 0,
+ kModelTypeN800 = 1 << 1,
+ kModelTypeN810 = 1 << 2,
+ kModelTypeN900 = 1 << 3,
kModelTypeInvalid = 0
};
@@ -38,15 +39,13 @@ struct Model {
const char *hwId;
ModelType modelType;
const char *hwAlias;
- bool hwKeyboard;
+ bool hasHwKeyboard;
+ bool hasMenuKey;
};
-static const Model models[] = {
- {"RX-34", kModelTypeN800, "N800", false},
- {"RX-44", kModelTypeN810, "N810", true},
- {"RX-48", kModelTypeN810, "N810W", true},
- {"RX-51", kModelTypeN900, "N900", true},
- {0, kModelTypeInvalid, 0, true}
+enum CustomEventType {
+ kEventClickMode = 1,
+ kEventInvalid = 0
};
} // namespace Maemo
diff --git a/backends/platform/maemo/maemo.cpp b/backends/platform/maemo/maemo.cpp
index 3571039e62..e296d4787c 100644
--- a/backends/platform/maemo/maemo.cpp
+++ b/backends/platform/maemo/maemo.cpp
@@ -29,7 +29,11 @@
#include "backends/platform/maemo/maemo.h"
#include "backends/events/maemosdl/maemosdl-events.h"
+#include "backends/graphics/maemosdl/maemosdl-graphics.h"
+#include "backends/keymapper/keymapper.h"
+#include "backends/keymapper/keymapper-defaults.h"
#include "common/textconsole.h"
+#include "common/translation.h"
#include <SDL/SDL_syswm.h>
@@ -42,17 +46,70 @@ OSystem_SDL_Maemo::OSystem_SDL_Maemo()
OSystem_POSIX() {
}
+OSystem_SDL_Maemo::~OSystem_SDL_Maemo() {
+ delete _eventObserver;
+#ifdef ENABLE_KEYMAPPER
+ delete _keymapperDefaultBindings;
+#endif
+}
+
+#ifdef ENABLE_KEYMAPPER
+static void registerDefaultKeyBindings(Common::KeymapperDefaultBindings *_keymapperDefaultBindings, Model _model) {
+ _keymapperDefaultBindings->setDefaultBinding("gui", "REM", "HOME");
+ _keymapperDefaultBindings->setDefaultBinding("global", "REM", "HOME");
+
+ if (_model.hasMenuKey && _model.hasHwKeyboard) {
+ _keymapperDefaultBindings->setDefaultBinding("gui", "FUL", "FULLSCREEN");
+ _keymapperDefaultBindings->setDefaultBinding("global", "FUL", "FULLSCREEN");
+ }
+
+ if (_model.hasHwKeyboard) {
+ _keymapperDefaultBindings->setDefaultBinding("gui", "VIR", "C+ZOOMMINUS");
+ _keymapperDefaultBindings->setDefaultBinding("global", "VIR", "C+ZOOMMINUS");
+ } else {
+ _keymapperDefaultBindings->setDefaultBinding("gui", "VIR", "FULLSCREEN");
+ _keymapperDefaultBindings->setDefaultBinding("global", "VIR", "FULLSCREEN");
+ }
+
+ if (_model.hasMenuKey )
+ _keymapperDefaultBindings->setDefaultBinding("global", "MEN", "MENU");
+ else
+ _keymapperDefaultBindings->setDefaultBinding("global", "MEN", "S+C+M");
+
+ _keymapperDefaultBindings->setDefaultBinding("gui", "CLO", "ESCAPE");
+
+ _keymapperDefaultBindings->setDefaultBinding("maemo", "RCL", "ZOOMPLUS");
+ _keymapperDefaultBindings->setDefaultBinding("maemo", "CLK", "ZOOMMINUS");
+}
+#endif
+
void OSystem_SDL_Maemo::initBackend() {
// Create the events manager
if (_eventSource == 0)
_eventSource = new MaemoSdlEventSource();
+ if (_graphicsManager == 0)
+ _graphicsManager = new MaemoSdlGraphicsManager(_eventSource);
+
+ if (_eventObserver == 0)
+ _eventObserver = new MaemoSdlEventObserver((MaemoSdlEventSource *)_eventSource);
+
+#ifdef ENABLE_KEYMAPPER
+ if (_keymapperDefaultBindings == 0)
+ _keymapperDefaultBindings = new Common::KeymapperDefaultBindings();
+#endif
+
ConfMan.set("vkeybdpath", DATA_PATH);
- _model = Model(detectModel());
+ _model = detectModel();
+
+#ifdef ENABLE_KEYMAPPER
+ registerDefaultKeyBindings(_keymapperDefaultBindings, _model);
+#endif
// Call parent implementation of this method
OSystem_POSIX::initBackend();
+ initObserver();
}
void OSystem_SDL_Maemo::quit() {
@@ -98,16 +155,77 @@ void OSystem_SDL_Maemo::setWindowCaption(const char *caption) {
setXWindowName(cap.c_str());
}
+static const Model models[] = {
+ {"SU-18", kModelType770, "770", false, true},
+ {"RX-34", kModelTypeN800, "N800", false, true},
+ {"RX-44", kModelTypeN810, "N810", true, true},
+ {"RX-48", kModelTypeN810, "N810W", true, true},
+ {"RX-51", kModelTypeN900, "N900", true, false},
+ {0, kModelTypeInvalid, 0, true, true}
+};
+
const Maemo::Model OSystem_SDL_Maemo::detectModel() {
Common::String deviceHwId = Common::String(getenv("SCUMMVM_MAEMO_DEVICE"));
const Model *model;
- for (model = models; model->hwId; model++) {
+ for (model = models; model->hwId; ++model) {
if (deviceHwId.equals(model->hwId))
return *model;
}
return *model;
}
+void OSystem_SDL_Maemo::setupIcon() {
+ // no Maemo version needs setupIcon
+ // also N900 is hit by SDL_WM_SetIcon bug (window cannot receive input)
+ // http://bugzilla.libsdl.org/show_bug.cgi?id=586
+}
+
+static const Common::KeyTableEntry maemoKeys[] = {
+ // Function keys
+ {"MENU", Common::KEYCODE_F11, 0, "Menu", false},
+ {"HOME", Common::KEYCODE_F12, 0, "Home", false},
+ {"FULLSCREEN", Common::KEYCODE_F13, 0, "FullScreen", false},
+ {"ZOOMPLUS", Common::KEYCODE_F14, 0, "Zoom+", false},
+ {"ZOOMMINUS", Common::KEYCODE_F15, 0, "Zoom-", false},
+
+ {0, Common::KEYCODE_INVALID, 0, 0, false}
+};
+
+#ifdef ENABLE_KEYMAPPER
+Common::HardwareInputSet *OSystem_SDL_Maemo::getHardwareInputSet() {
+ return new Common::HardwareInputSet(true, maemoKeys);
+}
+
+Common::Keymap *OSystem_SDL_Maemo::getGlobalKeymap() {
+ using namespace Common;
+ Keymap *globalMap = new Keymap("maemo");
+
+ Action *act;
+
+ act = new Action(globalMap, "CLKM", _("Click Mode"));
+ Event evt = Event();
+ evt.type = EVENT_CUSTOM_BACKEND_ACTION;
+ evt.customType = Maemo::kEventClickMode;
+ act->addEvent(evt);
+
+ act = new Action(globalMap, "LCLK", _("Left Click"));
+ act->addLeftClickEvent();
+
+ act = new Action(globalMap, "MCLK", _("Middle Click"));
+ act->addMiddleClickEvent();
+
+ act = new Action(globalMap, "RCLK", _("Right Click"));
+ act->addRightClickEvent();
+
+ return globalMap;
+}
+#endif
+
+void OSystem_SDL_Maemo::initObserver() {
+ assert(_eventManager);
+ _eventManager->getEventDispatcher()->registerObserver(_eventObserver, 10, false);
+}
+
} //namespace Maemo
#endif
diff --git a/backends/platform/maemo/maemo.h b/backends/platform/maemo/maemo.h
index e42936ddf0..43bc262ade 100644
--- a/backends/platform/maemo/maemo.h
+++ b/backends/platform/maemo/maemo.h
@@ -29,24 +29,36 @@
#include "backends/platform/maemo/maemo-common.h"
namespace Maemo {
+class MaemoSdlEventObserver;
class OSystem_SDL_Maemo : public OSystem_POSIX {
public:
OSystem_SDL_Maemo();
+ ~OSystem_SDL_Maemo();
virtual void initBackend();
virtual void quit();
virtual void fatalError();
virtual void setWindowCaption(const char *caption);
+ virtual void setupIcon();
+#ifdef ENABLE_KEYMAPPER
+ virtual Common::HardwareInputSet *getHardwareInputSet();
+ virtual Common::Keymap *getGlobalKeymap();
+ virtual Common::KeymapperDefaultBindings *getKeymapperDefaultBindings() { return _keymapperDefaultBindings; }
+#endif
Model getModel() { return _model; }
private:
virtual void setXWindowName(const char *caption);
+ void initObserver();
const Model detectModel();
Model _model;
-
+ MaemoSdlEventObserver *_eventObserver;
+#ifdef ENABLE_KEYMAPPER
+ Common::KeymapperDefaultBindings *_keymapperDefaultBindings;
+#endif
};
} // namespace Maemo
diff --git a/backends/platform/n64/osys_n64_utilities.cpp b/backends/platform/n64/osys_n64_utilities.cpp
index 94d727e421..f007a1bd25 100644
--- a/backends/platform/n64/osys_n64_utilities.cpp
+++ b/backends/platform/n64/osys_n64_utilities.cpp
@@ -100,9 +100,9 @@ void refillAudioBuffers(void) {
Audio::MixerImpl *localmixer = (Audio::MixerImpl *)osys->getMixer();
while (_requiredSoundSlots) {
- sndBuf = (byte*)getAIBuffer();
+ sndBuf = (byte *)getAIBuffer();
- localmixer->mixCallback((byte*)sndBuf, osys->_audioBufferSize);
+ localmixer->mixCallback((byte *)sndBuf, osys->_audioBufferSize);
putAIBuffer();
diff --git a/backends/platform/n64/portdefs.h b/backends/platform/n64/portdefs.h
index 677ad48477..10f5ed6488 100644
--- a/backends/platform/n64/portdefs.h
+++ b/backends/platform/n64/portdefs.h
@@ -31,6 +31,7 @@
#include <stdio.h>
#include <ctype.h>
#include <math.h>
+#include <new>
#undef assert
#define assert(x) ((x) ? 0 : (print_error("ASSERT TRIGGERED:\n\n("#x")\n%s\nline: %d", __FILE__, __LINE__)))
diff --git a/backends/platform/openpandora/op-bundle.mk b/backends/platform/openpandora/op-bundle.mk
index 089430f43c..284a0497a8 100755
--- a/backends/platform/openpandora/op-bundle.mk
+++ b/backends/platform/openpandora/op-bundle.mk
@@ -14,15 +14,15 @@ op-bundle: $(EXECUTABLE)
$(MKDIR) "$(bundle_name)/scummvm/icon"
$(MKDIR) "$(bundle_name)/scummvm/lib"
- $(CP) $(srcdir)/backends/platform/openpandora/build/runscummvm.sh $(bundle_name)/scummvm/
- $(CP) $(srcdir)/backends/platform/openpandora/build/PXML.xml $(bundle_name)/scummvm/data/
+ $(CP) $(srcdir)/dists/openpandora/runscummvm.sh $(bundle_name)/scummvm/
+ $(CP) $(srcdir)/dists/openpandora/PXML.xml $(bundle_name)/scummvm/data/
- $(CP) $(srcdir)/backends/platform/openpandora/build/icon/scummvm.png $(bundle_name)/scummvm/icon/
- $(CP) $(srcdir)/backends/platform/openpandora/build/icon/preview-pic.png $(bundle_name)/scummvm/icon/
+ $(CP) $(srcdir)/dists/openpandora/icon/scummvm.png $(bundle_name)/scummvm/icon/
+ $(CP) $(srcdir)/dists/openpandora/icon/preview-pic.png $(bundle_name)/scummvm/icon/
- $(CP) $(srcdir)/backends/platform/openpandora/build/README-OPENPANDORA $(bundle_name)/scummvm/docs/
- $(CP) $(srcdir)/backends/platform/openpandora/build/index.html $(bundle_name)/scummvm/docs/
+ $(CP) $(srcdir)/dists/openpandora/README-OPENPANDORA $(bundle_name)/scummvm/docs/
+ $(CP) $(srcdir)/dists/openpandora/index.html $(bundle_name)/scummvm/docs/
$(INSTALL) -c -m 644 $(DIST_FILES_DOCS) $(bundle_name)/scummvm/docs/
@@ -50,15 +50,15 @@ op-pnd: $(EXECUTABLE)
$(MKDIR) "$(bundle_name)/scummvm/icon"
$(MKDIR) "$(bundle_name)/scummvm/lib"
- $(CP) $(srcdir)/backends/platform/openpandora/build/runscummvm.sh $(bundle_name)/scummvm/
- $(CP) $(srcdir)/backends/platform/openpandora/build/PXML.xml $(bundle_name)/scummvm/data/
+ $(CP) $(srcdir)/dists/openpandora/runscummvm.sh $(bundle_name)/scummvm/
+ $(CP) $(srcdir)/dists/openpandora/PXML.xml $(bundle_name)/scummvm/data/
- $(CP) $(srcdir)/backends/platform/openpandora/build/icon/scummvm.png $(bundle_name)/scummvm/icon/
- $(CP) $(srcdir)/backends/platform/openpandora/build/icon/preview-pic.png $(bundle_name)/scummvm/icon/
+ $(CP) $(srcdir)/dists/openpandora/icon/scummvm.png $(bundle_name)/scummvm/icon/
+ $(CP) $(srcdir)/dists/openpandora/icon/preview-pic.png $(bundle_name)/scummvm/icon/
- $(CP) $(srcdir)/backends/platform/openpandora/build/README-OPENPANDORA $(bundle_name)/scummvm/docs/
- $(CP) $(srcdir)/backends/platform/openpandora/build/index.html $(bundle_name)/scummvm/docs/
+ $(CP) $(srcdir)/dists/openpandora/README-OPENPANDORA $(bundle_name)/scummvm/docs/
+ $(CP) $(srcdir)/dists/openpandora/index.html $(bundle_name)/scummvm/docs/
$(INSTALL) -c -m 644 $(DIST_FILES_DOCS) $(bundle_name)/scummvm/docs/
@@ -75,9 +75,10 @@ endif
$(CP) $(libloc)/../arm-angstrom-linux-gnueabi/usr/lib/libFLAC.so.8.2.0 $(bundle_name)/scummvm/lib/libFLAC.so.8
- $(srcdir)/backends/platform/openpandora/build/pnd_make.sh -p $(bundle_name).pnd -c -d $(bundle_name)/scummvm -x $(bundle_name)/scummvm/data/PXML.xml -i $(bundle_name)/scummvm/icon/scummvm.png
+ $(srcdir)/dists/openpandora/pnd_make.sh -p $(bundle_name).pnd -c -d $(bundle_name)/scummvm -x $(bundle_name)/scummvm/data/PXML.xml -i $(bundle_name)/scummvm/icon/scummvm.png
+
+ $(CP) $(srcdir)/dists/openpandora/README-PND.txt $(bundle_name)
- $(CP) $(srcdir)/backends/platform/openpandora/build/README-PND.txt $(bundle_name)
tar -cvjf $(bundle_name)-pnd.tar.bz2 $(bundle_name).pnd $(bundle_name)/README-PND.txt
rm -R ./$(bundle_name)
diff --git a/backends/platform/ps2/DmaPipe.cpp b/backends/platform/ps2/DmaPipe.cpp
index c6f6ab72ac..a346a67566 100644
--- a/backends/platform/ps2/DmaPipe.cpp
+++ b/backends/platform/ps2/DmaPipe.cpp
@@ -48,7 +48,7 @@ private:
DmaPipe::DmaPipe(uint32 size) {
size &= ~0x1F;
- _buf = (uint64*)memalign(64, size);
+ _buf = (uint64 *)memalign(64, size);
_curPipe = 0;
_pipes[0] = new SinglePipe(_buf, size >> 4);
_pipes[1] = new SinglePipe(_buf + (size >> 4), size >> 4);
@@ -260,7 +260,7 @@ void SinglePipe::init(void) {
_buf[0] = 0x0000000070000000;
_buf[1] = 0;
_chainHead = _buf;
- _chainSize = (uint16*)_chainHead;
+ _chainSize = (uint16 *)_chainHead;
_bufPos = _buf + 2;
}
@@ -272,7 +272,7 @@ void SinglePipe::appendChain(uint64 dmaTag) {
_chainHead = _bufPos;
_chainHead[0] = dmaTag;
_chainHead[1] = 0;
- _chainSize = (uint16*)_chainHead;
+ _chainSize = (uint16 *)_chainHead;
_bufPos += 2;
}
diff --git a/backends/platform/ps2/Gs2dScreen.cpp b/backends/platform/ps2/Gs2dScreen.cpp
index ddc1bdf668..8df6198c38 100644
--- a/backends/platform/ps2/Gs2dScreen.cpp
+++ b/backends/platform/ps2/Gs2dScreen.cpp
@@ -130,9 +130,9 @@ Gs2dScreen::Gs2dScreen(uint16 width, uint16 height, TVMode tvMode) {
_height = height;
_pitch = (width + 127) & ~127;
- _screenBuf = (uint8*)memalign(64, _width * _height);
- _overlayBuf = (uint16*)memalign(64, _width * _height * 2);
- _clut = (uint32*)memalign(64, 256 * 4);
+ _screenBuf = (uint8 *)memalign(64, _width * _height);
+ _overlayBuf = (uint16 *)memalign(64, _width * _height * 2);
+ _clut = (uint32 *)memalign(64, 256 * 4);
memset(_screenBuf, 0, _width * _height);
memset(_clut, 0, 256 * sizeof(uint32));
@@ -291,11 +291,11 @@ void Gs2dScreen::quit(void) {
}
void Gs2dScreen::createAnimTextures(void) {
- uint8 *buf = (uint8*)memalign(64, 16 * 64);
+ uint8 *buf = (uint8 *)memalign(64, 16 * 64);
memset(buf, 0, 16 * 64);
uint32 vramDest = _texPtrs[TEXT];
for (int i = 0; i < 16; i++) {
- uint32 *destPos = (uint32*)buf;
+ uint32 *destPos = (uint32 *)buf;
for (int ch = 15; ch >= 0; ch--) {
const uint32 *src = (const uint32*)(_binaryData + ((_binaryPattern[i] >> ch) & 1) * 4 * 14);
for (int line = 0; line < 14; line++)
@@ -331,8 +331,8 @@ void Gs2dScreen::newScreenSize(uint16 width, uint16 height) {
// malloc new buffers
free(_screenBuf);
free(_overlayBuf);
- _screenBuf = (uint8*)memalign(64, _width * _height);
- _overlayBuf = (uint16*)memalign(64, _width * _height * 2);
+ _screenBuf = (uint8 *)memalign(64, _width * _height);
+ _overlayBuf = (uint16 *)memalign(64, _width * _height * 2);
memset(_screenBuf, 0, _width * height);
memset(_overlayBuf, 0, _width * height * 2);
memset(_clut, 0, 256 * sizeof(uint32));
@@ -437,14 +437,6 @@ void Gs2dScreen::grabPalette(uint8 *pal, uint8 start, uint16 num) {
}
}
-void Gs2dScreen::grabScreen(Graphics::Surface *surf) {
- assert(surf);
- WaitSema(g_DmacSema);
- surf->create(_width, _height, Graphics::PixelFormat::createFormatCLUT8());
- memcpy(surf->pixels, _screenBuf, _width * _height);
- SignalSema(g_DmacSema);
-}
-
void Gs2dScreen::uploadToVram(void) {
if (_clutChanged) {
_clutChanged = false;
@@ -564,7 +556,7 @@ void Gs2dScreen::copyPrintfOverlay(const uint8 *buf) {
}
void Gs2dScreen::clearPrintfOverlay(void) {
- uint8 *tmpBuf = (uint8*)memalign(64, 320 * 200);
+ uint8 *tmpBuf = (uint8 *)memalign(64, 320 * 200);
memset(tmpBuf, 4, 320 * 200);
_dmaPipe->uploadTex(_texPtrs[PRINTF], 3 * 128, 0, 0, GS_PSMT8H, tmpBuf, 320, 200);
_dmaPipe->flush();
@@ -627,7 +619,7 @@ void Gs2dScreen::setMouseOverlay(const uint8 *buf, uint16 width, uint16 height,
_mTraCol = transpCol;
_clutChanged = true;
}
- uint8 *bufCopy = (uint8*)memalign(64, M_SIZE * M_SIZE); // make a copy to align to 64 bytes
+ uint8 *bufCopy = (uint8 *)memalign(64, M_SIZE * M_SIZE); // make a copy to align to 64 bytes
memset(bufCopy, _mTraCol, M_SIZE * M_SIZE);
for (int cnt = 0; cnt < height; cnt++)
memcpy(bufCopy + cnt * M_SIZE, buf + cnt * width, width);
diff --git a/backends/platform/ps2/Gs2dScreen.h b/backends/platform/ps2/Gs2dScreen.h
index dffdce5b36..4fbb3fdef8 100644
--- a/backends/platform/ps2/Gs2dScreen.h
+++ b/backends/platform/ps2/Gs2dScreen.h
@@ -42,10 +42,6 @@ enum GsInterlace {
};
-namespace Graphics {
-struct Surface;
-}
-
class Gs2dScreen {
public:
Gs2dScreen(uint16 width, uint16 height, TVMode tvMode);
@@ -65,7 +61,6 @@ public:
void setPalette(const uint8 *pal, uint8 start, uint16 num);
void updateScreen(void);
void grabPalette(uint8 *pal, uint8 start, uint16 num);
- void grabScreen(Graphics::Surface *surf);
//- overlay routines
void copyOverlayRect(const uint16 *buf, uint16 pitch, uint16 x, uint16 y, uint16 w, uint16 h);
void grabOverlay(uint16 *buf, uint16 pitch);
diff --git a/backends/platform/ps2/fileio.cpp b/backends/platform/ps2/fileio.cpp
index ef01f3a693..1ec16a3817 100644
--- a/backends/platform/ps2/fileio.cpp
+++ b/backends/platform/ps2/fileio.cpp
@@ -52,7 +52,7 @@ Ps2File::Ps2File() {
_eof = false;
_err = false;
- _cacheBuf = (uint8*)memalign(64, CACHE_SIZE * 2);
+ _cacheBuf = (uint8 *)memalign(64, CACHE_SIZE * 2);
_cacheOpRunning = 0;
_filePos = _physFilePos = _cachePos = 0;
@@ -362,7 +362,7 @@ uint32 Ps2File::read(void *dest, uint32 len) {
_eof = true;
}
- uint8 *destBuf = (uint8*)dest;
+ uint8 *destBuf = (uint8 *)dest;
if ((_filePos < _cachePos) || (_filePos + len > _cachePos + _bytesInCache))
cacheReadSync(); // we have to read from CD, sync cache.
@@ -413,7 +413,7 @@ uint32 Ps2File::read(void *dest, uint32 len) {
#ifdef __PS2_FILE_SEMA__
SignalSema(_sema);
#endif
- return destBuf - (uint8*)dest;
+ return destBuf - (uint8 *)dest;
}
uint32 Ps2File::write(const void *src, uint32 len) {
@@ -518,7 +518,7 @@ FILE *ps2_fopen(const char *fname, const char *mode) {
}
int ps2_fclose(FILE *stream) {
- Ps2File *file = (Ps2File*)stream;
+ Ps2File *file = (Ps2File *)stream;
delete file;
@@ -528,10 +528,10 @@ int ps2_fclose(FILE *stream) {
size_t ps2_fread(void *buf, size_t r, size_t n, FILE *stream) {
assert(r != 0);
- return ((Ps2File*)stream)->read(buf, r * n) / r;
+ return ((Ps2File *)stream)->read(buf, r * n) / r;
}
size_t ps2_fwrite(const void *buf, size_t r, size_t n, FILE *stream) {
assert(r != 0);
- return ((Ps2File*)stream)->write(buf, r * n) / r;
+ return ((Ps2File *)stream)->write(buf, r * n) / r;
}
diff --git a/backends/platform/ps2/icon.cpp b/backends/platform/ps2/icon.cpp
index 9852e6d40b..bda4843647 100644
--- a/backends/platform/ps2/icon.cpp
+++ b/backends/platform/ps2/icon.cpp
@@ -960,13 +960,13 @@ void PS2Icon::setup(mcIcon *icon) {
memcpy(icon->head, "PS2D", 4);
icon->nlOffset = strlen(_info) + 1;
strcpy(title, _info);
- strcpy_sjis((short*)&(icon->title), title);
+ strcpy_sjis((short *)&(icon->title), title);
icon->trans = 0x10;
memcpy(icon->bgCol, _bgcolor, sizeof(_bgcolor));
memcpy(icon->lightDir, _lightdir, sizeof(_lightdir));
memcpy(icon->lightCol, _lightcol, sizeof(_lightcol));
memcpy(icon->lightAmbient, _ambient, sizeof(_ambient));
- strcpy((char*)icon->view, "scummvm.icn");
- strcpy((char*)icon->copy, "scummvm.icn");
- strcpy((char*)icon->del, "scummvm.icn");
+ strcpy((char *)icon->view, "scummvm.icn");
+ strcpy((char *)icon->copy, "scummvm.icn");
+ strcpy((char *)icon->del, "scummvm.icn");
}
diff --git a/backends/platform/ps2/ps2mutex.cpp b/backends/platform/ps2/ps2mutex.cpp
index 5b30fa7862..ae63fe5724 100644
--- a/backends/platform/ps2/ps2mutex.cpp
+++ b/backends/platform/ps2/ps2mutex.cpp
@@ -57,7 +57,7 @@ OSystem::MutexRef OSystem_PS2::createMutex(void) {
void OSystem_PS2::lockMutex(MutexRef mutex) {
WaitSema(_mutexSema);
- Ps2Mutex *sysMutex = (Ps2Mutex*)mutex;
+ Ps2Mutex *sysMutex = (Ps2Mutex *)mutex;
int tid = GetThreadId();
assert(tid != 0);
@@ -75,7 +75,7 @@ void OSystem_PS2::lockMutex(MutexRef mutex) {
void OSystem_PS2::unlockMutex(MutexRef mutex) {
WaitSema(_mutexSema);
- Ps2Mutex *sysMutex = (Ps2Mutex*)mutex;
+ Ps2Mutex *sysMutex = (Ps2Mutex *)mutex;
int tid = GetThreadId();
if (sysMutex->owner && sysMutex->count && (sysMutex->owner == tid))
@@ -90,7 +90,7 @@ void OSystem_PS2::unlockMutex(MutexRef mutex) {
void OSystem_PS2::deleteMutex(MutexRef mutex) {
WaitSema(_mutexSema);
- Ps2Mutex *sysMutex = (Ps2Mutex*)mutex;
+ Ps2Mutex *sysMutex = (Ps2Mutex *)mutex;
if (sysMutex->owner || sysMutex->count)
printf("WARNING: Deleting LOCKED mutex!\n");
DeleteSema(sysMutex->sema);
diff --git a/backends/platform/ps2/ps2pad.cpp b/backends/platform/ps2/ps2pad.cpp
index eeb9dfbd93..b6afc217e6 100644
--- a/backends/platform/ps2/ps2pad.cpp
+++ b/backends/platform/ps2/ps2pad.cpp
@@ -30,7 +30,7 @@
Ps2Pad::Ps2Pad(OSystem_PS2 *system) {
_system = system;
- _padBuf = (uint8*)memalign(64, 256);
+ _padBuf = (uint8 *)memalign(64, 256);
_padStatus = STAT_NONE;
padInit(0); // initialize library
diff --git a/backends/platform/ps2/systemps2.cpp b/backends/platform/ps2/systemps2.cpp
index c75d7493a2..d4e993da63 100644
--- a/backends/platform/ps2/systemps2.cpp
+++ b/backends/platform/ps2/systemps2.cpp
@@ -384,8 +384,8 @@ void OSystem_PS2::initTimer(void) {
ee_thread_t timerThread, soundThread, thisThread;
ReferThreadStatus(GetThreadId(), &thisThread);
- _timerStack = (uint8*)malloc(TIMER_STACK_SIZE);
- _soundStack = (uint8*)malloc(SOUND_STACK_SIZE);
+ _timerStack = (uint8 *)malloc(TIMER_STACK_SIZE);
+ _soundStack = (uint8 *)malloc(SOUND_STACK_SIZE);
// give timer thread a higher priority than main thread
timerThread.initial_priority = thisThread.current_priority - 1;
@@ -435,7 +435,7 @@ void OSystem_PS2::timerThreadCallback(void) {
}
void OSystem_PS2::soundThreadCallback(void) {
- int16 *soundBufL = (int16*)memalign(64, SMP_PER_BLOCK * sizeof(int16) * 2);
+ int16 *soundBufL = (int16 *)memalign(64, SMP_PER_BLOCK * sizeof(int16) * 2);
int16 *soundBufR = soundBufL + SMP_PER_BLOCK;
int bufferedSamples = 0;
@@ -453,9 +453,9 @@ void OSystem_PS2::soundThreadCallback(void) {
if (bufferedSamples <= 8 * SMP_PER_BLOCK) {
// we have to produce more samples, call sound mixer
// the scratchpad at 0x70000000 is used as temporary soundbuffer
- //_scummSoundProc(_scummSoundParam, (uint8*)0x70000000, SMP_PER_BLOCK * 2 * sizeof(int16));
- // Audio::Mixer::mixCallback(_scummMixer, (byte*)0x70000000, SMP_PER_BLOCK * 2 * sizeof(int16));
- _scummMixer->mixCallback((byte*)0x70000000, SMP_PER_BLOCK * 2 * sizeof(int16));
+ //_scummSoundProc(_scummSoundParam, (uint8 *)0x70000000, SMP_PER_BLOCK * 2 * sizeof(int16));
+ // Audio::Mixer::mixCallback(_scummMixer, (byte *)0x70000000, SMP_PER_BLOCK * 2 * sizeof(int16));
+ _scummMixer->mixCallback((byte *)0x70000000, SMP_PER_BLOCK * 2 * sizeof(int16));
// demux data into 2 buffers, L and R
__asm__ (
@@ -558,11 +558,6 @@ void OSystem_PS2::copyRectToScreen(const byte *buf, int pitch, int x, int y, int
_screen->copyScreenRect((const uint8*)buf, pitch, x, y, w, h);
}
-bool OSystem_PS2::grabRawScreen(Graphics::Surface *surf) {
- _screen->grabScreen(surf);
- return true;
-}
-
void OSystem_PS2::updateScreen(void) {
if (_msgClearTime && (_msgClearTime < getMillis())) {
_screen->clearPrintfOverlay();
@@ -640,7 +635,7 @@ void OSystem_PS2::clearOverlay(void) {
}
void OSystem_PS2::grabOverlay(OverlayColor *buf, int pitch) {
- _screen->grabOverlay((uint16*)buf, (uint16)pitch);
+ _screen->grabOverlay((uint16 *)buf, (uint16)pitch);
}
void OSystem_PS2::copyRectToOverlay(const OverlayColor *buf, int pitch, int x, int y, int w, int h) {
@@ -743,12 +738,12 @@ void OSystem_PS2::msgPrintf(int millis, const char *format, ...) {
lnSta = lnEnd + 1;
}
- uint8 *scrBuf = (uint8*)memalign(64, 320 * 200);
+ uint8 *scrBuf = (uint8 *)memalign(64, 320 * 200);
memset(scrBuf, 4, 320 * 200);
uint8 *dstPos = scrBuf + ((200 - posY) >> 1) * 320 + (320 - maxWidth) / 2;
for (int y = 0; y < posY; y++) {
- uint8 *srcPos = (uint8*)surf.getBasePtr((300 - maxWidth) / 2, y);
+ uint8 *srcPos = (uint8 *)surf.getBasePtr((300 - maxWidth) / 2, y);
for (int x = 0; x < maxWidth; x++)
dstPos[x] = srcPos[x] + 5;
dstPos += 320;
diff --git a/backends/platform/ps2/systemps2.h b/backends/platform/ps2/systemps2.h
index 35ceaf829e..3a0e247737 100644
--- a/backends/platform/ps2/systemps2.h
+++ b/backends/platform/ps2/systemps2.h
@@ -64,7 +64,6 @@ public:
virtual void copyRectToScreen(const byte *buf, int pitch, int x, int y, int w, int h);
virtual void setShakePos(int shakeOffset);
- virtual bool grabRawScreen(Graphics::Surface *surf);
virtual Graphics::Surface *lockScreen();
virtual void unlockScreen();
virtual void updateScreen();
diff --git a/backends/platform/psp/display_manager.cpp b/backends/platform/psp/display_manager.cpp
index cdb130e2a0..10a732b1e3 100644
--- a/backends/platform/psp/display_manager.cpp
+++ b/backends/platform/psp/display_manager.cpp
@@ -210,14 +210,14 @@ void MasterGuRenderer::guProgramDisplayBufferSizes() {
switch (GuRenderer::_displayManager->getOutputBitsPerPixel()) {
case 16:
sceGuDrawBuffer(GU_PSM_4444, (void *)0, PSP_BUFFER_WIDTH);
- sceGuDispBuffer(PSP_SCREEN_WIDTH, PSP_SCREEN_HEIGHT, (void*)(PSP_FRAME_SIZE * sizeof(uint16)), PSP_BUFFER_WIDTH);
- sceGuDepthBuffer((void*)(PSP_FRAME_SIZE * sizeof(uint16) * 2), PSP_BUFFER_WIDTH);
+ sceGuDispBuffer(PSP_SCREEN_WIDTH, PSP_SCREEN_HEIGHT, (void *)(PSP_FRAME_SIZE * sizeof(uint16)), PSP_BUFFER_WIDTH);
+ sceGuDepthBuffer((void *)(PSP_FRAME_SIZE * sizeof(uint16) * 2), PSP_BUFFER_WIDTH);
VramAllocator::instance().allocate(PSP_FRAME_SIZE * sizeof(uint16) * 2);
break;
case 32:
sceGuDrawBuffer(GU_PSM_8888, (void *)0, PSP_BUFFER_WIDTH);
- sceGuDispBuffer(PSP_SCREEN_WIDTH, PSP_SCREEN_HEIGHT, (void*)(PSP_FRAME_SIZE * sizeof(uint32)), PSP_BUFFER_WIDTH);
- sceGuDepthBuffer((void*)(PSP_FRAME_SIZE * sizeof(uint32) * 2), PSP_BUFFER_WIDTH);
+ sceGuDispBuffer(PSP_SCREEN_WIDTH, PSP_SCREEN_HEIGHT, (void *)(PSP_FRAME_SIZE * sizeof(uint32)), PSP_BUFFER_WIDTH);
+ sceGuDepthBuffer((void *)(PSP_FRAME_SIZE * sizeof(uint32) * 2), PSP_BUFFER_WIDTH);
VramAllocator::instance().allocate(PSP_FRAME_SIZE * sizeof(uint32) * 2);
break;
}
diff --git a/backends/platform/psp/portdefs.h b/backends/platform/psp/portdefs.h
index e8a28b31e2..620a27a601 100644
--- a/backends/platform/psp/portdefs.h
+++ b/backends/platform/psp/portdefs.h
@@ -38,6 +38,7 @@
#include <time.h>
#include <ctype.h>
#include <assert.h>
+#include <new>
#include <pspkernel.h>
#include <pspdebug.h>
diff --git a/backends/platform/sdl/hardwarekeys.cpp b/backends/platform/sdl/hardwarekeys.cpp
deleted file mode 100644
index 9a33e357da..0000000000
--- a/backends/platform/sdl/hardwarekeys.cpp
+++ /dev/null
@@ -1,230 +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 "backends/platform/sdl/sdl.h"
-#include "backends/keymapper/keymapper.h"
-#include "common/keyboard.h"
-
-#ifdef ENABLE_KEYMAPPER
-
-using namespace Common;
-
-struct Key {
- const char *hwId;
- KeyCode keycode;
- uint16 ascii;
- const char *desc;
- KeyType preferredAction;
- bool shiftable;
-};
-
-static const Key keys[] = {
- {"BACKSPACE", KEYCODE_BACKSPACE, ASCII_BACKSPACE, "Backspace", kActionKeyType, false},
- {"TAB", KEYCODE_TAB, ASCII_TAB, "Tab", kActionKeyType, false},
- {"CLEAR", KEYCODE_CLEAR, 0, "Clear", kActionKeyType, false},
- {"RETURN", KEYCODE_RETURN, ASCII_RETURN, "Return", kActionKeyType, false},
- {"PAUSE", KEYCODE_PAUSE, 0, "Pause", kActionKeyType, false},
- {"ESCAPE", KEYCODE_ESCAPE, ASCII_ESCAPE, "Esc", kStartKeyType, false},
- {"SPACE", KEYCODE_SPACE, ASCII_SPACE, "Space", kActionKeyType, false},
- {"EXCLAIM", KEYCODE_EXCLAIM, '!', "!", kActionKeyType, false},
- {"QUOTEDBL", KEYCODE_QUOTEDBL, '"', "\"", kActionKeyType, false},
- {"HASH", KEYCODE_HASH, '#', "#", kActionKeyType, false},
- {"DOLLAR", KEYCODE_DOLLAR, '$', "$", kActionKeyType, false},
- {"AMPERSAND", KEYCODE_AMPERSAND, '&', "&", kActionKeyType, false},
- {"QUOTE", KEYCODE_QUOTE, '\'', "'", kActionKeyType, false},
- {"LEFTPAREN", KEYCODE_LEFTPAREN, '(', "(", kActionKeyType, false},
- {"RIGHTPAREN", KEYCODE_RIGHTPAREN, ')', ")", kActionKeyType, false},
- {"ASTERISK", KEYCODE_ASTERISK, '*', "*", kActionKeyType, false},
- {"PLUS", KEYCODE_PLUS, '+', "+", kActionKeyType, false},
- {"COMMA", KEYCODE_COMMA, ',', ",", kActionKeyType, false},
- {"MINUS", KEYCODE_MINUS, '-', "-", kActionKeyType, false},
- {"PERIOD", KEYCODE_PERIOD, '.', ".", kActionKeyType, false},
- {"SLASH", KEYCODE_SLASH, '/', "/", kActionKeyType, false},
- {"0", KEYCODE_0, '0', "0", kActionKeyType, false},
- {"1", KEYCODE_1, '1', "1", kActionKeyType, false},
- {"2", KEYCODE_2, '2', "2", kActionKeyType, false},
- {"3", KEYCODE_3, '3', "3", kActionKeyType, false},
- {"4", KEYCODE_4, '4', "4", kActionKeyType, false},
- {"5", KEYCODE_5, '5', "5", kActionKeyType, false},
- {"6", KEYCODE_6, '6', "6", kActionKeyType, false},
- {"7", KEYCODE_7, '7', "7", kActionKeyType, false},
- {"8", KEYCODE_8, '8', "8", kActionKeyType, false},
- {"9", KEYCODE_9, '9', "9", kActionKeyType, false},
- {"COLON", KEYCODE_COLON, ':', ":", kActionKeyType, false},
- {"SEMICOLON", KEYCODE_SEMICOLON, ';', ";", kActionKeyType, false},
- {"LESS", KEYCODE_LESS, '<', "<", kActionKeyType, false},
- {"EQUALS", KEYCODE_EQUALS, '=', "=", kActionKeyType, false},
- {"GREATER", KEYCODE_GREATER, '>', ">", kActionKeyType, false},
- {"QUESTION", KEYCODE_QUESTION, '?', "?", kActionKeyType, false},
- {"AT", KEYCODE_AT, '@', "@", kActionKeyType, false},
-
- {"LEFTBRACKET", KEYCODE_LEFTBRACKET, '[', "[", kActionKeyType, false},
- {"BACKSLASH", KEYCODE_BACKSLASH, '\\', "\\", kActionKeyType, false},
- {"RIGHTBRACKET", KEYCODE_RIGHTBRACKET, ']', "]", kActionKeyType, false},
- {"CARET", KEYCODE_CARET, '^', "^", kActionKeyType, false},
- {"UNDERSCORE", KEYCODE_UNDERSCORE, '_', "_", kActionKeyType, false},
- {"BACKQUOTE", KEYCODE_BACKQUOTE, '`', "`", kActionKeyType, false},
- {"a", KEYCODE_a, 'a', "a", kActionKeyType, true},
- {"b", KEYCODE_b, 'b', "b", kActionKeyType, true},
- {"c", KEYCODE_c, 'c', "c", kActionKeyType, true},
- {"d", KEYCODE_d, 'd', "d", kActionKeyType, true},
- {"e", KEYCODE_e, 'e', "e", kActionKeyType, true},
- {"f", KEYCODE_f, 'f', "f", kActionKeyType, true},
- {"g", KEYCODE_g, 'g', "g", kActionKeyType, true},
- {"h", KEYCODE_h, 'h', "h", kActionKeyType, true},
- {"i", KEYCODE_i, 'i', "i", kActionKeyType, true},
- {"j", KEYCODE_j, 'j', "j", kActionKeyType, true},
- {"k", KEYCODE_k, 'k', "k", kActionKeyType, true},
- {"l", KEYCODE_l, 'l', "l", kActionKeyType, true},
- {"m", KEYCODE_m, 'm', "m", kActionKeyType, true},
- {"n", KEYCODE_n, 'n', "n", kActionKeyType, true},
- {"o", KEYCODE_o, 'o', "o", kActionKeyType, true},
- {"p", KEYCODE_p, 'p', "p", kActionKeyType, true},
- {"q", KEYCODE_q, 'q', "q", kActionKeyType, true},
- {"r", KEYCODE_r, 'r', "r", kActionKeyType, true},
- {"s", KEYCODE_s, 's', "s", kActionKeyType, true},
- {"t", KEYCODE_t, 't', "t", kActionKeyType, true},
- {"u", KEYCODE_u, 'u', "u", kActionKeyType, true},
- {"v", KEYCODE_v, 'v', "v", kActionKeyType, true},
- {"w", KEYCODE_w, 'w', "w", kActionKeyType, true},
- {"x", KEYCODE_x, 'x', "x", kActionKeyType, true},
- {"y", KEYCODE_y, 'y', "y", kActionKeyType, true},
- {"z", KEYCODE_z, 'z', "z", kActionKeyType, true},
- {"DELETE", KEYCODE_DELETE, 0, "Del", kActionKeyType, false},
-
- // Numeric keypad
- {"KP0", KEYCODE_KP0, 0, "KP0", kActionKeyType, false},
- {"KP1", KEYCODE_KP1, 0, "KP1", kActionKeyType, false},
- {"KP2", KEYCODE_KP2, 0, "KP2", kActionKeyType, false},
- {"KP3", KEYCODE_KP3, 0, "KP3", kActionKeyType, false},
- {"KP4", KEYCODE_KP4, 0, "KP4", kActionKeyType, false},
- {"KP5", KEYCODE_KP5, 0, "KP5", kActionKeyType, false},
- {"KP6", KEYCODE_KP6, 0, "KP6", kActionKeyType, false},
- {"KP7", KEYCODE_KP7, 0, "KP7", kActionKeyType, false},
- {"KP8", KEYCODE_KP8, 0, "KP8", kActionKeyType, false},
- {"KP9", KEYCODE_KP9, 0, "KP9", kActionKeyType, false},
- {"KP_PERIOD", KEYCODE_KP_PERIOD, 0, "KP.", kActionKeyType, false},
- {"KP_DIVIDE", KEYCODE_KP_DIVIDE, 0, "KP/", kActionKeyType, false},
- {"KP_MULTIPLY", KEYCODE_KP_MULTIPLY, 0, "KP*", kActionKeyType, false},
- {"KP_MINUS", KEYCODE_KP_MINUS, 0, "KP-", kActionKeyType, false},
- {"KP_PLUS", KEYCODE_KP_PLUS, 0, "KP+", kActionKeyType, false},
- {"KP_ENTER", KEYCODE_KP_ENTER, 0, "KP Enter", kActionKeyType, false},
- {"KP_EQUALS", KEYCODE_KP_EQUALS, 0, "KP=", kActionKeyType, false},
-
- // Arrows + Home/End pad
- {"UP", KEYCODE_UP, 0, "Up", kDirUpKeyType, false},
- {"DOWN", KEYCODE_DOWN, 0, "Down", kDirDownKeyType, false},
- {"RIGHT", KEYCODE_RIGHT, 0, "Right", kDirRightKeyType, false},
- {"LEFT", KEYCODE_LEFT, 0, "Left", kDirLeftKeyType, false},
- {"INSERT", KEYCODE_INSERT, 0, "Insert", kActionKeyType, false},
- {"HOME", KEYCODE_HOME, 0, "Home", kActionKeyType, false},
- {"END", KEYCODE_END, 0, "End", kActionKeyType, false},
- {"PAGEUP", KEYCODE_PAGEUP, 0, "PgUp", kActionKeyType, false},
- {"PAGEDOWN", KEYCODE_PAGEDOWN, 0, "PgDn", kActionKeyType, false},
-
- // Function keys
- {"F1", KEYCODE_F1, ASCII_F1, "F1", kActionKeyType, false},
- {"F2", KEYCODE_F2, ASCII_F2, "F2", kActionKeyType, false},
- {"F3", KEYCODE_F3, ASCII_F3, "F3", kActionKeyType, false},
- {"F4", KEYCODE_F4, ASCII_F4, "F4", kActionKeyType, false},
- {"F5", KEYCODE_F5, ASCII_F5, "F5", kActionKeyType, false},
- {"F6", KEYCODE_F6, ASCII_F6, "F6", kActionKeyType, false},
- {"F7", KEYCODE_F7, ASCII_F7, "F7", kActionKeyType, false},
- {"F8", KEYCODE_F8, ASCII_F8, "F8", kActionKeyType, false},
- {"F9", KEYCODE_F9, ASCII_F9, "F9", kActionKeyType, false},
- {"F10", KEYCODE_F10, ASCII_F10, "F10", kActionKeyType, false},
- {"F11", KEYCODE_F11, ASCII_F11, "F11", kActionKeyType, false},
- {"F12", KEYCODE_F12, ASCII_F12, "F12", kActionKeyType, false},
- {"F13", KEYCODE_F13, 0, "F13", kActionKeyType, false},
- {"F14", KEYCODE_F14, 0, "F14", kActionKeyType, false},
- {"F15", KEYCODE_F15, 0, "F15", kActionKeyType, false},
-
- // Miscellaneous function keys
- {"HELP", KEYCODE_HELP, 0, "Help", kActionKeyType, false},
- {"PRINT", KEYCODE_PRINT, 0, "Print", kActionKeyType, false},
- {"SYSREQ", KEYCODE_SYSREQ, 0, "SysRq", kActionKeyType, false},
- {"BREAK", KEYCODE_BREAK, 0, "Break", kActionKeyType, false},
- {"MENU", KEYCODE_MENU, 0, "Menu", kActionKeyType, false},
- // Power Macintosh power key
- {"POWER", KEYCODE_POWER, 0, "Power", kActionKeyType, false},
- // Some european keyboards
- {"EURO", KEYCODE_EURO, 0, "Euro", kActionKeyType, false},
- // Atari keyboard has Undo
- {"UNDO", KEYCODE_UNDO, 0, "Undo", kActionKeyType, false},
- {0, KEYCODE_INVALID, 0, 0, kGenericKeyType, false}
-};
-
-struct Mod {
- byte flag;
- const char *id;
- const char *desc;
- bool shiftable;
-};
-
-static const Mod modifiers[] = {
- { 0, "", "", false },
- { KBD_CTRL, "C+", "Ctrl+", false },
- { KBD_ALT, "A+", "Alt+", false },
- { KBD_SHIFT, "", "", true },
- { KBD_CTRL | KBD_ALT, "C+A+", "Ctrl+Alt+", false },
- { KBD_SHIFT | KBD_CTRL, "S+C+", "Shift+Ctrl+", true },
- { KBD_SHIFT | KBD_CTRL | KBD_ALT, "C+A+", "Ctrl+Alt+", true },
- { 0, 0, 0, false }
-};
-#endif
-
-
-Common::HardwareKeySet *OSystem_SDL::getHardwareKeySet() {
-#ifdef ENABLE_KEYMAPPER
- HardwareKeySet *keySet = new HardwareKeySet();
- const Key *key;
- const Mod *mod;
- char fullKeyId[50];
- char fullKeyDesc[100];
- uint16 ascii;
-
- for (mod = modifiers; mod->id; mod++) {
- for (key = keys; key->hwId; key++) {
- ascii = key->ascii;
-
- if (mod->shiftable && key->shiftable) {
- snprintf(fullKeyId, 50, "%s%c", mod->id, toupper(key->hwId[0]));
- snprintf(fullKeyDesc, 100, "%s%c", mod->desc, toupper(key->desc[0]));
- ascii = toupper(key->ascii);
- } else if (mod->shiftable) {
- snprintf(fullKeyId, 50, "S+%s%s", mod->id, key->hwId);
- snprintf(fullKeyDesc, 100, "Shift+%s%s", mod->desc, key->desc);
- } else {
- snprintf(fullKeyId, 50, "%s%s", mod->id, key->hwId);
- snprintf(fullKeyDesc, 100, "%s%s", mod->desc, key->desc);
- }
-
- keySet->addHardwareKey(new HardwareKey(fullKeyId, KeyState(key->keycode, ascii, mod->flag), fullKeyDesc, key->preferredAction ));
- }
- }
-
- return keySet;
-
-#else
- return 0;
-#endif
-}
diff --git a/backends/platform/sdl/macosx/appmenu_osx.mm b/backends/platform/sdl/macosx/appmenu_osx.mm
index bb089a6b61..97c7edba3e 100755
--- a/backends/platform/sdl/macosx/appmenu_osx.mm
+++ b/backends/platform/sdl/macosx/appmenu_osx.mm
@@ -35,6 +35,11 @@
- (void)setAppleMenu:(NSMenu *)menu;
@end
+NSString *constructNSStringFromCString(const char* rawCString, NSStringEncoding stringEncoding) {
+ NSData *nsData = [NSData dataWithBytes:rawCString length:strlen(rawCString)];
+ return [[NSString alloc] initWithData:nsData encoding:stringEncoding];
+}
+
void replaceApplicationMenuItems() {
// Code mainly copied and adapted from SDLmain.m
@@ -50,34 +55,47 @@ void replaceApplicationMenuItems() {
// Create new application menu
appleMenu = [[NSMenu alloc] initWithTitle:@""];
+ NSString *nsString = NULL;
+
// Get current encoding
#ifdef USE_TRANSLATION
- NSStringEncoding stringEncoding = CFStringConvertEncodingToNSStringEncoding(CFStringConvertIANACharSetNameToEncoding((CFStringRef)[NSString stringWithCString:(TransMan.getCurrentCharset()).c_str() encoding:NSASCIIStringEncoding]));
+ nsString = constructNSStringFromCString((TransMan.getCurrentCharset()).c_str(), NSASCIIStringEncoding);
+ NSStringEncoding stringEncoding = CFStringConvertEncodingToNSStringEncoding(CFStringConvertIANACharSetNameToEncoding((CFStringRef)nsString));
+ [nsString release];
#else
NSStringEncoding stringEncoding = NSASCIIStringEncoding;
#endif
-
+
// Add "About ScummVM" menu item
- [appleMenu addItemWithTitle:[NSString stringWithCString:_("About ScummVM") encoding:stringEncoding] action:@selector(orderFrontStandardAboutPanel:) keyEquivalent:@""];
+ nsString = constructNSStringFromCString(_("About ScummVM"), stringEncoding);
+ [appleMenu addItemWithTitle:nsString action:@selector(orderFrontStandardAboutPanel:) keyEquivalent:@""];
+ [nsString release];
// Add separator
[appleMenu addItem:[NSMenuItem separatorItem]];
// Add "Hide ScummVM" menu item
- [appleMenu addItemWithTitle:[NSString stringWithCString:_("Hide ScummVM") encoding:stringEncoding] action:@selector(hide:) keyEquivalent:@"h"];
+ nsString = constructNSStringFromCString(_("Hide ScummVM"), stringEncoding);
+ [appleMenu addItemWithTitle:nsString action:@selector(hide:) keyEquivalent:@"h"];
+ [nsString release];
// Add "Hide Others" menu item
- menuItem = (NSMenuItem *)[appleMenu addItemWithTitle:[NSString stringWithCString:_("Hide Others") encoding:stringEncoding] action:@selector(hideOtherApplications:) keyEquivalent:@"h"];
+ nsString = constructNSStringFromCString(_("Hide Others"), stringEncoding);
+ menuItem = (NSMenuItem *)[appleMenu addItemWithTitle:nsString action:@selector(hideOtherApplications:) keyEquivalent:@"h"];
[menuItem setKeyEquivalentModifierMask:(NSAlternateKeyMask|NSCommandKeyMask)];
// Add "Show All" menu item
- [appleMenu addItemWithTitle:[NSString stringWithCString:_("Show All") encoding:stringEncoding] action:@selector(unhideAllApplications:) keyEquivalent:@""];
+ nsString = constructNSStringFromCString(_("Show All"), stringEncoding);
+ [appleMenu addItemWithTitle:nsString action:@selector(unhideAllApplications:) keyEquivalent:@""];
+ [nsString release];
// Add separator
[appleMenu addItem:[NSMenuItem separatorItem]];
// Add "Quit ScummVM" menu item
- [appleMenu addItemWithTitle:[NSString stringWithCString:_("Quit ScummVM") encoding:stringEncoding] action:@selector(terminate:) keyEquivalent:@"q"];
+ nsString = constructNSStringFromCString(_("Quit ScummVM"), stringEncoding);
+ [appleMenu addItemWithTitle:nsString action:@selector(terminate:) keyEquivalent:@"q"];
+ [nsString release];
// Put application menu into the menubar
menuItem = [[NSMenuItem alloc] initWithTitle:@"" action:nil keyEquivalent:@""];
@@ -89,16 +107,22 @@ void replaceApplicationMenuItems() {
// Create new "Window" menu
- windowMenu = [[NSMenu alloc] initWithTitle:[NSString stringWithCString:_("Window") encoding:stringEncoding]];
+ nsString = constructNSStringFromCString(_("Window"), stringEncoding);
+ windowMenu = [[NSMenu alloc] initWithTitle:nsString];
+ [nsString release];
// Add "Minimize" menu item
- menuItem = [[NSMenuItem alloc] initWithTitle:[NSString stringWithCString:_("Minimize") encoding:stringEncoding] action:@selector(performMiniaturize:) keyEquivalent:@"m"];
+ nsString = constructNSStringFromCString(_("Minimize"), stringEncoding);
+ menuItem = [[NSMenuItem alloc] initWithTitle:nsString action:@selector(performMiniaturize:) keyEquivalent:@"m"];
[windowMenu addItem:menuItem];
+ [nsString release];
// Put menu into the menubar
- menuItem = [[NSMenuItem alloc] initWithTitle:[NSString stringWithCString:_("Window") encoding:stringEncoding] action:nil keyEquivalent:@""];
+ nsString = constructNSStringFromCString(_("Window"), stringEncoding);
+ menuItem = [[NSMenuItem alloc] initWithTitle:nsString action:nil keyEquivalent:@""];
[menuItem setSubmenu:windowMenu];
[[NSApp mainMenu] addItem:menuItem];
+ [nsString release];
// Tell the application object that this is now the window menu.
[NSApp setWindowsMenu:windowMenu];
diff --git a/backends/platform/sdl/module.mk b/backends/platform/sdl/module.mk
index f1afe37349..98a8265301 100644
--- a/backends/platform/sdl/module.mk
+++ b/backends/platform/sdl/module.mk
@@ -1,7 +1,6 @@
MODULE := backends/platform/sdl
MODULE_OBJS := \
- hardwarekeys.o \
main.o \
sdl.o
diff --git a/backends/platform/sdl/posix/posix.cpp b/backends/platform/sdl/posix/posix.cpp
index 05c779a4e0..7a8b1e7b70 100644
--- a/backends/platform/sdl/posix/posix.cpp
+++ b/backends/platform/sdl/posix/posix.cpp
@@ -175,7 +175,7 @@ bool OSystem_POSIX::displayLogFile() {
} else if (pid == 0) {
// Try xdg-open first
- execlp("xdg-open", "xdg-open", _logFilePath.c_str(), (char*)0);
+ execlp("xdg-open", "xdg-open", _logFilePath.c_str(), (char *)0);
// If we're here, that clearly failed.
@@ -184,7 +184,7 @@ bool OSystem_POSIX::displayLogFile() {
// Try xterm+less next
- execlp("xterm", "xterm", "-e", "less", _logFilePath.c_str(), (char*)0);
+ execlp("xterm", "xterm", "-e", "less", _logFilePath.c_str(), (char *)0);
// TODO: If less does not exist we could fall back to 'more'.
// However, we'll have to use 'xterm -hold' for that to prevent the
diff --git a/backends/platform/sdl/sdl.h b/backends/platform/sdl/sdl.h
index 22d79dbfe7..f05207b482 100644
--- a/backends/platform/sdl/sdl.h
+++ b/backends/platform/sdl/sdl.h
@@ -58,7 +58,6 @@ public:
virtual void engineInit();
virtual void engineDone();
#endif
- virtual Common::HardwareKeySet *getHardwareKeySet();
virtual void quit();
virtual void fatalError();
diff --git a/backends/platform/sdl/win32/win32.cpp b/backends/platform/sdl/win32/win32.cpp
index a2c8e43424..453d566c7b 100644
--- a/backends/platform/sdl/win32/win32.cpp
+++ b/backends/platform/sdl/win32/win32.cpp
@@ -38,6 +38,7 @@
#include <SDL_syswm.h> // For setting the icon
#include "backends/platform/sdl/win32/win32.h"
+#include "backends/saves/windows/windows-saves.h"
#include "backends/fs/windows/windows-fs-factory.h"
#include "backends/taskbar/win32/win32-taskbar.h"
@@ -74,6 +75,10 @@ void OSystem_Win32::initBackend() {
FreeConsole();
}
+ // Create the savefile manager
+ if (_savefileManager == 0)
+ _savefileManager = new WindowsSaveFileManager();
+
// Invoke parent implementation of this method
OSystem_SDL::initBackend();
}
@@ -256,9 +261,9 @@ class Win32ResourceArchive : public Common::Archive {
public:
Win32ResourceArchive();
- virtual bool hasFile(const Common::String &name);
- virtual int listMembers(Common::ArchiveMemberList &list);
- virtual Common::ArchiveMemberPtr getMember(const Common::String &name);
+ virtual bool hasFile(const Common::String &name) const;
+ virtual int listMembers(Common::ArchiveMemberList &list) const;
+ virtual const Common::ArchiveMemberPtr getMember(const Common::String &name) const;
virtual Common::SeekableReadStream *createReadStreamForMember(const Common::String &name) const;
private:
typedef Common::List<Common::String> FilenameList;
@@ -279,7 +284,7 @@ Win32ResourceArchive::Win32ResourceArchive() {
EnumResourceNames(NULL, MAKEINTRESOURCE(256), &EnumResNameProc, (LONG_PTR)this);
}
-bool Win32ResourceArchive::hasFile(const Common::String &name) {
+bool Win32ResourceArchive::hasFile(const Common::String &name) const {
for (FilenameList::const_iterator i = _files.begin(); i != _files.end(); ++i) {
if (i->equalsIgnoreCase(name))
return true;
@@ -288,7 +293,7 @@ bool Win32ResourceArchive::hasFile(const Common::String &name) {
return false;
}
-int Win32ResourceArchive::listMembers(Common::ArchiveMemberList &list) {
+int Win32ResourceArchive::listMembers(Common::ArchiveMemberList &list) const {
int count = 0;
for (FilenameList::const_iterator i = _files.begin(); i != _files.end(); ++i, ++count)
@@ -297,7 +302,7 @@ int Win32ResourceArchive::listMembers(Common::ArchiveMemberList &list) {
return count;
}
-Common::ArchiveMemberPtr Win32ResourceArchive::getMember(const Common::String &name) {
+const Common::ArchiveMemberPtr Win32ResourceArchive::getMember(const Common::String &name) const {
return Common::ArchiveMemberPtr(new Common::GenericArchiveMember(name, this));
}
diff --git a/backends/platform/symbian/README b/backends/platform/symbian/README
index 83e98a534a..31bc3d8fce 100644
--- a/backends/platform/symbian/README
+++ b/backends/platform/symbian/README
@@ -1,7 +1,7 @@
ScummVM - ScummVM ported to EPOC/SymbianOS
- Copyright (C) 2008-2011 ScummVM Team
+ Copyright (C) 2008-2012 ScummVM Team
Copyright (C) 2003-2008 Lars 'AnotherGuest' Persson
Copyright (C) 2002-2008 Jurgen 'SumthinWicked' Braam
diff --git a/backends/platform/symbian/S60/ScummVM_S60.mmp.in b/backends/platform/symbian/S60/ScummVM_S60.mmp.in
index 7b401fd310..81068ba073 100644
--- a/backends/platform/symbian/S60/ScummVM_S60.mmp.in
+++ b/backends/platform/symbian/S60/ScummVM_S60.mmp.in
@@ -2,7 +2,7 @@
* Copyright (C) 2003-2005 Andreas 'Sprawl' Karlsson - Original EPOC port, ESDL
* Copyright (C) 2003-2005 Lars 'AnotherGuest' Persson - Original EPOC port, Audio System
* Copyright (C) 2005 Jurgen 'SumthinWicked' Braam - EPOC/CVS maintainer
- * Copyright (C) 2005-2011 The ScummVM project
+ * Copyright (C) 2005-2012 The ScummVM project
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
diff --git a/backends/platform/symbian/S60/ScummVM_S60_App.mmp b/backends/platform/symbian/S60/ScummVM_S60_App.mmp
index 940997cc73..e00987e2ad 100644
--- a/backends/platform/symbian/S60/ScummVM_S60_App.mmp
+++ b/backends/platform/symbian/S60/ScummVM_S60_App.mmp
@@ -2,7 +2,7 @@
* Copyright (C) 2003-2005 Andreas 'Sprawl' Karlsson - Original EPOC port, ESDL
* Copyright (C) 2003-2005 Lars 'AnotherGuest' Persson - Original EPOC port, Audio System
* Copyright (C) 2005 Jurgen 'SumthinWicked' Braam - EPOC/CVS maintainer
- * Copyright (C) 2005-2011 The ScummVM project
+ * Copyright (C) 2005-2012 The ScummVM project
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
diff --git a/backends/platform/symbian/S60v3/ScummVM_A0000658_S60v3.mmp.in b/backends/platform/symbian/S60v3/ScummVM_A0000658_S60v3.mmp.in
index 583d1a35e7..ccf38818dc 100644
--- a/backends/platform/symbian/S60v3/ScummVM_A0000658_S60v3.mmp.in
+++ b/backends/platform/symbian/S60v3/ScummVM_A0000658_S60v3.mmp.in
@@ -2,7 +2,7 @@
* Copyright (C) 2003-2005 Andreas 'Sprawl' Karlsson - Original EPOC port, ESDL
* Copyright (C) 2003-2005 Lars 'AnotherGuest' Persson - Original EPOC port, Audio System
* Copyright (C) 2005 Jurgen 'SumthinWicked' Braam - EPOC/CVS maintainer
- * Copyright (C) 2005-2011 The ScummVM project
+ * Copyright (C) 2005-2012 The ScummVM project
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
diff --git a/backends/platform/symbian/S60v3/ScummVM_S60v3.mmp.in b/backends/platform/symbian/S60v3/ScummVM_S60v3.mmp.in
index 5367bf0d1f..0162061284 100644
--- a/backends/platform/symbian/S60v3/ScummVM_S60v3.mmp.in
+++ b/backends/platform/symbian/S60v3/ScummVM_S60v3.mmp.in
@@ -2,7 +2,7 @@
* Copyright (C) 2003-2005 Andreas 'Sprawl' Karlsson - Original EPOC port, ESDL
* Copyright (C) 2003-2005 Lars 'AnotherGuest' Persson - Original EPOC port, Audio System
* Copyright (C) 2005 Jurgen 'SumthinWicked' Braam - EPOC/CVS maintainer
- * Copyright (C) 2005-2011 The ScummVM project
+ * Copyright (C) 2005-2012 The ScummVM project
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
diff --git a/backends/platform/symbian/S80/ScummVM_S80.mmp.in b/backends/platform/symbian/S80/ScummVM_S80.mmp.in
index 5e4b6d447e..7987ccd639 100644
--- a/backends/platform/symbian/S80/ScummVM_S80.mmp.in
+++ b/backends/platform/symbian/S80/ScummVM_S80.mmp.in
@@ -2,7 +2,7 @@
* Copyright (C) 2003-2005 Andreas 'Sprawl' Karlsson - Original EPOC port, ESDL
* Copyright (C) 2003-2005 Lars 'AnotherGuest' Persson - Original EPOC port, Audio System
* Copyright (C) 2005 Jurgen 'SumthinWicked' Braam - EPOC/CVS maintainer
- * Copyright (C) 2005-2011 The ScummVM project
+ * Copyright (C) 2005-2012 The ScummVM project
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
diff --git a/backends/platform/symbian/S80/ScummVM_S80_App.mmp b/backends/platform/symbian/S80/ScummVM_S80_App.mmp
index e91b504087..b66bef7518 100644
--- a/backends/platform/symbian/S80/ScummVM_S80_App.mmp
+++ b/backends/platform/symbian/S80/ScummVM_S80_App.mmp
@@ -2,7 +2,7 @@
* Copyright (C) 2003-2005 Andreas 'Sprawl' Karlsson - Original EPOC port, ESDL
* Copyright (C) 2003-2005 Lars 'AnotherGuest' Persson - Original EPOC port, Audio System
* Copyright (C) 2005 Jurgen 'SumthinWicked' Braam - EPOC/CVS maintainer
- * Copyright (C) 2005-2011 The ScummVM project
+ * Copyright (C) 2005-2012 The ScummVM project
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
diff --git a/backends/platform/symbian/S90/Scummvm_S90.mmp.in b/backends/platform/symbian/S90/Scummvm_S90.mmp.in
index 06d65f1641..d803ce5647 100644
--- a/backends/platform/symbian/S90/Scummvm_S90.mmp.in
+++ b/backends/platform/symbian/S90/Scummvm_S90.mmp.in
@@ -2,7 +2,7 @@
* Copyright (C) 2003-2005 Andreas 'Sprawl' Karlsson - Original EPOC port, ESDL
* Copyright (C) 2003-2005 Lars 'AnotherGuest' Persson - Original EPOC port, Audio System
* Copyright (C) 2005 Jurgen 'SumthinWicked' Braam - EPOC/CVS maintainer
- * Copyright (C) 2005-2011 The ScummVM project
+ * Copyright (C) 2005-2012 The ScummVM project
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
diff --git a/backends/platform/symbian/S90/Scummvm_S90_App.mmp b/backends/platform/symbian/S90/Scummvm_S90_App.mmp
index 3aa2cc2a65..0d8d2b8710 100644
--- a/backends/platform/symbian/S90/Scummvm_S90_App.mmp
+++ b/backends/platform/symbian/S90/Scummvm_S90_App.mmp
@@ -2,7 +2,7 @@
* Copyright (C) 2003-2005 Andreas 'Sprawl' Karlsson - Original EPOC port, ESDL
* Copyright (C) 2003-2005 Lars 'AnotherGuest' Persson - Original EPOC port, Audio System
* Copyright (C) 2005 Jurgen 'SumthinWicked' Braam - EPOC/CVS maintainer
- * Copyright (C) 2005-2011 The ScummVM project
+ * Copyright (C) 2005-2012 The ScummVM project
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
diff --git a/backends/platform/symbian/UIQ2/ScummVM.rss b/backends/platform/symbian/UIQ2/ScummVM.rss
index 374bd50680..a6ba4021e4 100644
--- a/backends/platform/symbian/UIQ2/ScummVM.rss
+++ b/backends/platform/symbian/UIQ2/ScummVM.rss
@@ -2,7 +2,7 @@
* Copyright (C) 2003-2005 Andreas 'Sprawl' Karlsson - Original EPOC port, ESDL
* Copyright (C) 2003-2005 Lars 'AnotherGuest' Persson - Original EPOC port, Audio System
* Copyright (C) 2005 Jurgen 'SumthinWicked' Braam - EPOC/CVS maintainer
- * Copyright (C) 2005-2011 The ScummVM project
+ * Copyright (C) 2005-2012 The ScummVM project
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
diff --git a/backends/platform/symbian/UIQ3/ScummVM.rss b/backends/platform/symbian/UIQ3/ScummVM.rss
index 2021b0506e..00ed4e3b5c 100644
--- a/backends/platform/symbian/UIQ3/ScummVM.rss
+++ b/backends/platform/symbian/UIQ3/ScummVM.rss
@@ -2,7 +2,7 @@
* Copyright (C) 2003-2005 Andreas 'Sprawl' Karlsson - Original EPOC port, ESDL
* Copyright (C) 2003-2005 Lars 'AnotherGuest' Persson - Original EPOC port, Audio System
* Copyright (C) 2005 Jurgen 'SumthinWicked' Braam - EPOC/CVS maintainer
- * Copyright (C) 2005-2011 The ScummVM project
+ * Copyright (C) 2005-2012 The ScummVM project
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
diff --git a/backends/platform/symbian/UIQ3/ScummVM_A0000658.rss b/backends/platform/symbian/UIQ3/ScummVM_A0000658.rss
index 2021b0506e..00ed4e3b5c 100644
--- a/backends/platform/symbian/UIQ3/ScummVM_A0000658.rss
+++ b/backends/platform/symbian/UIQ3/ScummVM_A0000658.rss
@@ -2,7 +2,7 @@
* Copyright (C) 2003-2005 Andreas 'Sprawl' Karlsson - Original EPOC port, ESDL
* Copyright (C) 2003-2005 Lars 'AnotherGuest' Persson - Original EPOC port, Audio System
* Copyright (C) 2005 Jurgen 'SumthinWicked' Braam - EPOC/CVS maintainer
- * Copyright (C) 2005-2011 The ScummVM project
+ * Copyright (C) 2005-2012 The ScummVM project
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
diff --git a/backends/platform/symbian/UIQ3/ScummVM_A0000658_UIQ3.mmp.in b/backends/platform/symbian/UIQ3/ScummVM_A0000658_UIQ3.mmp.in
index 3bc93d8ce3..9e419ad6d9 100644
--- a/backends/platform/symbian/UIQ3/ScummVM_A0000658_UIQ3.mmp.in
+++ b/backends/platform/symbian/UIQ3/ScummVM_A0000658_UIQ3.mmp.in
@@ -2,7 +2,7 @@
* Copyright (C) 2003-2005 Andreas 'Sprawl' Karlsson - Original EPOC port, ESDL
* Copyright (C) 2003-2009 Lars 'AnotherGuest' Persson - Original EPOC port, Audio System
* Copyright (C) 2009 Jurgen 'SumthinWicked' Braam - EPOC/CVS maintainer
- * Copyright (C) 2005-2011 The ScummVM project
+ * Copyright (C) 2005-2012 The ScummVM project
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
diff --git a/backends/platform/symbian/UIQ3/ScummVM_UIQ3.mmp.in b/backends/platform/symbian/UIQ3/ScummVM_UIQ3.mmp.in
index bd5016f8d1..41452127ca 100644
--- a/backends/platform/symbian/UIQ3/ScummVM_UIQ3.mmp.in
+++ b/backends/platform/symbian/UIQ3/ScummVM_UIQ3.mmp.in
@@ -2,7 +2,7 @@
* Copyright (C) 2003-2005 Andreas 'Sprawl' Karlsson - Original EPOC port, ESDL
* Copyright (C) 2003-2005 Lars 'AnotherGuest' Persson - Original EPOC port, Audio System
* Copyright (C) 2005 Jurgen 'SumthinWicked' Braam - EPOC/CVS maintainer
- * Copyright (C) 2005-2011 The ScummVM project
+ * Copyright (C) 2005-2012 The ScummVM project
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
diff --git a/backends/platform/symbian/UIQ3/scummvm_A0000658_loc.rss b/backends/platform/symbian/UIQ3/scummvm_A0000658_loc.rss
index 7f3b71ef84..9af9a33a75 100644
--- a/backends/platform/symbian/UIQ3/scummvm_A0000658_loc.rss
+++ b/backends/platform/symbian/UIQ3/scummvm_A0000658_loc.rss
@@ -2,7 +2,7 @@
* Copyright (C) 2003-2005 Andreas 'Sprawl' Karlsson - Original EPOC port, ESDL
* Copyright (C) 2003-2005 Lars 'AnotherGuest' Persson - Original EPOC port, Audio System
* Copyright (C) 2005 Jurgen 'SumthinWicked' Braam - EPOC/CVS maintainer
- * Copyright (C) 2005-2011 The ScummVM project
+ * Copyright (C) 2005-2012 The ScummVM project
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
diff --git a/backends/platform/symbian/mmp/scummvm_agi.mmp.in b/backends/platform/symbian/mmp/scummvm_agi.mmp.in
index 5805d36133..7d197f786f 100644
--- a/backends/platform/symbian/mmp/scummvm_agi.mmp.in
+++ b/backends/platform/symbian/mmp/scummvm_agi.mmp.in
@@ -2,7 +2,7 @@
* Copyright (C) 2003-2005 Andreas 'Sprawl' Karlsson - Original EPOC port, ESDL
* Copyright (C) 2003-2005 Lars 'AnotherGuest' Persson - Original EPOC port, Audio System
* Copyright (C) 2005 Jurgen 'SumthinWicked' Braam - EPOC/CVS maintainer
- * Copyright (C) 2005-2011 The ScummVM project
+ * Copyright (C) 2005-2012 The ScummVM project
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
diff --git a/backends/platform/symbian/mmp/scummvm_agos.mmp.in b/backends/platform/symbian/mmp/scummvm_agos.mmp.in
index 236a62f1b8..587d1f0b69 100644
--- a/backends/platform/symbian/mmp/scummvm_agos.mmp.in
+++ b/backends/platform/symbian/mmp/scummvm_agos.mmp.in
@@ -2,7 +2,7 @@
* Copyright (C) 2003-2005 Andreas 'Sprawl' Karlsson - Original EPOC port, ESDL
* Copyright (C) 2003-2005 Lars 'AnotherGuest' Persson - Original EPOC port, Audio System
* Copyright (C) 2005 Jurgen 'SumthinWicked' Braam - EPOC/CVS maintainer
- * Copyright (C) 2005-2011 The ScummVM project
+ * Copyright (C) 2005-2012 The ScummVM project
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
diff --git a/backends/platform/symbian/mmp/scummvm_base.mmp.in b/backends/platform/symbian/mmp/scummvm_base.mmp.in
index 0387bfaf26..05cf526233 100644
--- a/backends/platform/symbian/mmp/scummvm_base.mmp.in
+++ b/backends/platform/symbian/mmp/scummvm_base.mmp.in
@@ -2,7 +2,7 @@
* Copyright (C) 2003-2005 Andreas 'Sprawl' Karlsson - Original EPOC port, ESDL
* Copyright (C) 2003-2005 Lars 'AnotherGuest' Persson - Original EPOC port, Audio System
* Copyright (C) 2005 Jurgen 'SumthinWicked' Braam - EPOC/CVS maintainer
- * Copyright (C) 2005-2011 The ScummVM project
+ * Copyright (C) 2005-2012 The ScummVM project
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
diff --git a/backends/platform/symbian/mmp/scummvm_cine.mmp.in b/backends/platform/symbian/mmp/scummvm_cine.mmp.in
index e75ece95f1..79806eb8c2 100644
--- a/backends/platform/symbian/mmp/scummvm_cine.mmp.in
+++ b/backends/platform/symbian/mmp/scummvm_cine.mmp.in
@@ -2,7 +2,7 @@
* Copyright (C) 2003-2005 Andreas 'Sprawl' Karlsson - Original EPOC port, ESDL
* Copyright (C) 2003-2005 Lars 'AnotherGuest' Persson - Original EPOC port, Audio System
* Copyright (C) 2005 Jurgen 'SumthinWicked' Braam - EPOC/CVS maintainer
- * Copyright (C) 2005-2011 The ScummVM project
+ * Copyright (C) 2005-2012 The ScummVM project
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
diff --git a/backends/platform/symbian/mmp/scummvm_cruise.mmp.in b/backends/platform/symbian/mmp/scummvm_cruise.mmp.in
index a91d33b5f5..53d52c80e7 100644
--- a/backends/platform/symbian/mmp/scummvm_cruise.mmp.in
+++ b/backends/platform/symbian/mmp/scummvm_cruise.mmp.in
@@ -2,7 +2,7 @@
* Copyright (C) 2003-2005 Andreas 'Sprawl' Karlsson - Original EPOC port, ESDL
* Copyright (C) 2003-2005 Lars 'AnotherGuest' Persson - Original EPOC port, Audio System
* Copyright (C) 2005 Jurgen 'SumthinWicked' Braam - EPOC/CVS maintainer
- * Copyright (C) 2005-2011 The ScummVM project
+ * Copyright (C) 2005-2012 The ScummVM project
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
diff --git a/backends/platform/symbian/mmp/scummvm_draci.mmp.in b/backends/platform/symbian/mmp/scummvm_draci.mmp.in
index 044247fac7..9a7c87c963 100644
--- a/backends/platform/symbian/mmp/scummvm_draci.mmp.in
+++ b/backends/platform/symbian/mmp/scummvm_draci.mmp.in
@@ -2,7 +2,7 @@
* Copyright (C) 2003-2005 Andreas 'Sprawl' Karlsson - Original EPOC port, ESDL
* Copyright (C) 2003-2005 Lars 'AnotherGuest' Persson - Original EPOC port, Audio System
* Copyright (C) 2005 Jurgen 'SumthinWicked' Braam - EPOC/CVS maintainer
- * Copyright (C) 2005-2011 The ScummVM project
+ * Copyright (C) 2005-2012 The ScummVM project
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
diff --git a/backends/platform/symbian/mmp/scummvm_drascula.mmp.in b/backends/platform/symbian/mmp/scummvm_drascula.mmp.in
index 0561e494c1..fcd7ce7585 100644
--- a/backends/platform/symbian/mmp/scummvm_drascula.mmp.in
+++ b/backends/platform/symbian/mmp/scummvm_drascula.mmp.in
@@ -2,7 +2,7 @@
* Copyright (C) 2003-2005 Andreas 'Sprawl' Karlsson - Original EPOC port, ESDL
* Copyright (C) 2003-2005 Lars 'AnotherGuest' Persson - Original EPOC port, Audio System
* Copyright (C) 2005 Jurgen 'SumthinWicked' Braam - EPOC/CVS maintainer
- * Copyright (C) 2005-2011 The ScummVM project
+ * Copyright (C) 2005-2012 The ScummVM project
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
diff --git a/backends/platform/symbian/mmp/scummvm_gob.mmp.in b/backends/platform/symbian/mmp/scummvm_gob.mmp.in
index 7c92611fd2..23f110bc7d 100644
--- a/backends/platform/symbian/mmp/scummvm_gob.mmp.in
+++ b/backends/platform/symbian/mmp/scummvm_gob.mmp.in
@@ -2,7 +2,7 @@
* Copyright (C) 2003-2005 Andreas 'Sprawl' Karlsson - Original EPOC port, ESDL
* Copyright (C) 2003-2005 Lars 'AnotherGuest' Persson - Original EPOC port, Audio System
* Copyright (C) 2005 Jurgen 'SumthinWicked' Braam - EPOC/CVS maintainer
- * Copyright (C) 2005-2011 The ScummVM project
+ * Copyright (C) 2005-2012 The ScummVM project
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
diff --git a/backends/platform/symbian/mmp/scummvm_groovie.mmp.in b/backends/platform/symbian/mmp/scummvm_groovie.mmp.in
index c0294b3b0d..6bdeb06b10 100644
--- a/backends/platform/symbian/mmp/scummvm_groovie.mmp.in
+++ b/backends/platform/symbian/mmp/scummvm_groovie.mmp.in
@@ -2,7 +2,7 @@
* Copyright (C) 2003-2005 Andreas 'Sprawl' Karlsson - Original EPOC port, ESDL
* Copyright (C) 2003-2005 Lars 'AnotherGuest' Persson - Original EPOC port, Audio System
* Copyright (C) 2005 Jurgen 'SumthinWicked' Braam - EPOC/CVS maintainer
- * Copyright (C) 2005-2011 The ScummVM project
+ * Copyright (C) 2005-2012 The ScummVM project
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
diff --git a/backends/platform/symbian/mmp/scummvm_hugo.mmp.in b/backends/platform/symbian/mmp/scummvm_hugo.mmp.in
index 66e22fc34b..69888bb0ee 100644
--- a/backends/platform/symbian/mmp/scummvm_hugo.mmp.in
+++ b/backends/platform/symbian/mmp/scummvm_hugo.mmp.in
@@ -2,7 +2,7 @@
* Copyright (C) 2003-2005 Andreas 'Sprawl' Karlsson - Original EPOC port, ESDL
* Copyright (C) 2003-2005 Lars 'AnotherGuest' Persson - Original EPOC port, Audio System
* Copyright (C) 2005 Jurgen 'SumthinWicked' Braam - EPOC/CVS maintainer
- * Copyright (C) 2005-2011 The ScummVM project
+ * Copyright (C) 2005-2012 The ScummVM project
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
diff --git a/backends/platform/symbian/mmp/scummvm_kyra.mmp.in b/backends/platform/symbian/mmp/scummvm_kyra.mmp.in
index d5f2ec951c..4a2a87216e 100644
--- a/backends/platform/symbian/mmp/scummvm_kyra.mmp.in
+++ b/backends/platform/symbian/mmp/scummvm_kyra.mmp.in
@@ -2,7 +2,7 @@
* Copyright (C) 2003-2005 Andreas 'Sprawl' Karlsson - Original EPOC port, ESDL
* Copyright (C) 2003-2005 Lars 'AnotherGuest' Persson - Original EPOC port, Audio System
* Copyright (C) 2005 Jurgen 'SumthinWicked' Braam - EPOC/CVS maintainer
- * Copyright (C) 2005-2011 The ScummVM project
+ * Copyright (C) 2005-2012 The ScummVM project
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
diff --git a/backends/platform/symbian/mmp/scummvm_lastexpress.mmp.in b/backends/platform/symbian/mmp/scummvm_lastexpress.mmp.in
index 57efa31a85..27ec0b2148 100644
--- a/backends/platform/symbian/mmp/scummvm_lastexpress.mmp.in
+++ b/backends/platform/symbian/mmp/scummvm_lastexpress.mmp.in
@@ -2,7 +2,7 @@
* Copyright (C) 2003-2005 Andreas 'Sprawl' Karlsson - Original EPOC port, ESDL
* Copyright (C) 2003-2005 Lars 'AnotherGuest' Persson - Original EPOC port, Audio System
* Copyright (C) 2005 Jurgen 'SumthinWicked' Braam - EPOC/CVS maintainer
- * Copyright (C) 2005-2011 The ScummVM project
+ * Copyright (C) 2005-2012 The ScummVM project
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
diff --git a/backends/platform/symbian/mmp/scummvm_lure.mmp.in b/backends/platform/symbian/mmp/scummvm_lure.mmp.in
index 2ac1f8f8ff..20b938a83f 100644
--- a/backends/platform/symbian/mmp/scummvm_lure.mmp.in
+++ b/backends/platform/symbian/mmp/scummvm_lure.mmp.in
@@ -2,7 +2,7 @@
* Copyright (C) 2003-2005 Andreas 'Sprawl' Karlsson - Original EPOC port, ESDL
* Copyright (C) 2003-2005 Lars 'AnotherGuest' Persson - Original EPOC port, Audio System
* Copyright (C) 2005 Jurgen 'SumthinWicked' Braam - EPOC/CVS maintainer
- * Copyright (C) 2005-2011 The ScummVM project
+ * Copyright (C) 2005-2012 The ScummVM project
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
diff --git a/backends/platform/symbian/mmp/scummvm_m4.mmp.in b/backends/platform/symbian/mmp/scummvm_m4.mmp.in
index 81ec94dbd4..fafd5e1e5f 100644
--- a/backends/platform/symbian/mmp/scummvm_m4.mmp.in
+++ b/backends/platform/symbian/mmp/scummvm_m4.mmp.in
@@ -2,7 +2,7 @@
* Copyright (C) 2003-2005 Andreas 'Sprawl' Karlsson - Original EPOC port, ESDL
* Copyright (C) 2003-2005 Lars 'AnotherGuest' Persson - Original EPOC port, Audio System
* Copyright (C) 2005 Jurgen 'SumthinWicked' Braam - EPOC/CVS maintainer
- * Copyright (C) 2005-2011 The ScummVM project
+ * Copyright (C) 2005-2012 The ScummVM project
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
diff --git a/backends/platform/symbian/mmp/scummvm_made.mmp.in b/backends/platform/symbian/mmp/scummvm_made.mmp.in
index dc24aee279..4d5ab6cc33 100644
--- a/backends/platform/symbian/mmp/scummvm_made.mmp.in
+++ b/backends/platform/symbian/mmp/scummvm_made.mmp.in
@@ -2,7 +2,7 @@
* Copyright (C) 2003-2005 Andreas 'Sprawl' Karlsson - Original EPOC port, ESDL
* Copyright (C) 2003-2005 Lars 'AnotherGuest' Persson - Original EPOC port, Audio System
* Copyright (C) 2005 Jurgen 'SumthinWicked' Braam - EPOC/CVS maintainer
- * Copyright (C) 2005-2011 The ScummVM project
+ * Copyright (C) 2005-2012 The ScummVM project
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
diff --git a/backends/platform/symbian/mmp/scummvm_mohawk.mmp.in b/backends/platform/symbian/mmp/scummvm_mohawk.mmp.in
index cb5b18ba18..3fc7c4ca5b 100644
--- a/backends/platform/symbian/mmp/scummvm_mohawk.mmp.in
+++ b/backends/platform/symbian/mmp/scummvm_mohawk.mmp.in
@@ -2,7 +2,7 @@
* Copyright (C) 2003-2005 Andreas 'Sprawl' Karlsson - Original EPOC port, ESDL
* Copyright (C) 2003-2005 Lars 'AnotherGuest' Persson - Original EPOC port, Audio System
* Copyright (C) 2005 Jurgen 'SumthinWicked' Braam - EPOC/CVS maintainer
- * Copyright (C) 2005-2011 The ScummVM project
+ * Copyright (C) 2005-2012 The ScummVM project
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
diff --git a/backends/platform/symbian/mmp/scummvm_parallaction.mmp.in b/backends/platform/symbian/mmp/scummvm_parallaction.mmp.in
index e86473e47a..05578b5994 100644
--- a/backends/platform/symbian/mmp/scummvm_parallaction.mmp.in
+++ b/backends/platform/symbian/mmp/scummvm_parallaction.mmp.in
@@ -2,7 +2,7 @@
* Copyright (C) 2003-2005 Andreas 'Sprawl' Karlsson - Original EPOC port, ESDL
* Copyright (C) 2003-2005 Lars 'AnotherGuest' Persson - Original EPOC port, Audio System
* Copyright (C) 2005 Jurgen 'SumthinWicked' Braam - EPOC/CVS maintainer
- * Copyright (C) 2005-2011 The ScummVM project
+ * Copyright (C) 2005-2012 The ScummVM project
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
diff --git a/backends/platform/symbian/mmp/scummvm_queen.mmp.in b/backends/platform/symbian/mmp/scummvm_queen.mmp.in
index b5326abe74..bfc0a2f760 100644
--- a/backends/platform/symbian/mmp/scummvm_queen.mmp.in
+++ b/backends/platform/symbian/mmp/scummvm_queen.mmp.in
@@ -2,7 +2,7 @@
* Copyright (C) 2003-2005 Andreas 'Sprawl' Karlsson - Original EPOC port, ESDL
* Copyright (C) 2003-2005 Lars 'AnotherGuest' Persson - Original EPOC port, Audio System
* Copyright (C) 2005 Jurgen 'SumthinWicked' Braam - EPOC/CVS maintainer
- * Copyright (C) 2005-2011 The ScummVM project
+ * Copyright (C) 2005-2012 The ScummVM project
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
diff --git a/backends/platform/symbian/mmp/scummvm_saga.mmp.in b/backends/platform/symbian/mmp/scummvm_saga.mmp.in
index 55d89f7868..831f02bdb6 100644
--- a/backends/platform/symbian/mmp/scummvm_saga.mmp.in
+++ b/backends/platform/symbian/mmp/scummvm_saga.mmp.in
@@ -2,7 +2,7 @@
* Copyright (C) 2003-2005 Andreas 'Sprawl' Karlsson - Original EPOC port, ESDL
* Copyright (C) 2003-2005 Lars 'AnotherGuest' Persson - Original EPOC port, Audio System
* Copyright (C) 2005 Jurgen 'SumthinWicked' Braam - EPOC/CVS maintainer
- * Copyright (C) 2005-2011 The ScummVM project
+ * Copyright (C) 2005-2012 The ScummVM project
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
diff --git a/backends/platform/symbian/mmp/scummvm_sci.mmp.in b/backends/platform/symbian/mmp/scummvm_sci.mmp.in
index dc06f44a5d..705f8d0c43 100644
--- a/backends/platform/symbian/mmp/scummvm_sci.mmp.in
+++ b/backends/platform/symbian/mmp/scummvm_sci.mmp.in
@@ -2,7 +2,7 @@
* Copyright (C) 2003-2005 Andreas 'Sprawl' Karlsson - Original EPOC port, ESDL
* Copyright (C) 2003-2005 Lars 'AnotherGuest' Persson - Original EPOC port, Audio System
* Copyright (C) 2005 Jurgen 'SumthinWicked' Braam - EPOC/CVS maintainer
- * Copyright (C) 2005-2011 The ScummVM project
+ * Copyright (C) 2005-2012 The ScummVM project
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
diff --git a/backends/platform/symbian/mmp/scummvm_scumm.mmp.in b/backends/platform/symbian/mmp/scummvm_scumm.mmp.in
index 527ce75181..6b2ad35594 100644
--- a/backends/platform/symbian/mmp/scummvm_scumm.mmp.in
+++ b/backends/platform/symbian/mmp/scummvm_scumm.mmp.in
@@ -2,7 +2,7 @@
* Copyright (C) 2003-2005 Andreas 'Sprawl' Karlsson - Original EPOC port, ESDL
* Copyright (C) 2003-2005 Lars 'AnotherGuest' Persson - Original EPOC port, Audio System
* Copyright (C) 2005 Jurgen 'SumthinWicked' Braam - EPOC/CVS maintainer
- * Copyright (C) 2005-2011 The ScummVM project
+ * Copyright (C) 2005-2012 The ScummVM project
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
diff --git a/backends/platform/symbian/mmp/scummvm_sky.mmp.in b/backends/platform/symbian/mmp/scummvm_sky.mmp.in
index eeb517ffcc..5fdfb56320 100644
--- a/backends/platform/symbian/mmp/scummvm_sky.mmp.in
+++ b/backends/platform/symbian/mmp/scummvm_sky.mmp.in
@@ -2,7 +2,7 @@
* Copyright (C) 2003-2005 Andreas 'Sprawl' Karlsson - Original EPOC port, ESDL
* Copyright (C) 2003-2005 Lars 'AnotherGuest' Persson - Original EPOC port, Audio System
* Copyright (C) 2005 Jurgen 'SumthinWicked' Braam - EPOC/CVS maintainer
- * Copyright (C) 2005-2011 The ScummVM project
+ * Copyright (C) 2005-2012 The ScummVM project
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
diff --git a/backends/platform/symbian/mmp/scummvm_sword1.mmp.in b/backends/platform/symbian/mmp/scummvm_sword1.mmp.in
index 0adc156719..075968cf98 100644
--- a/backends/platform/symbian/mmp/scummvm_sword1.mmp.in
+++ b/backends/platform/symbian/mmp/scummvm_sword1.mmp.in
@@ -2,7 +2,7 @@
* Copyright (C) 2003-2005 Andreas 'Sprawl' Karlsson - Original EPOC port, ESDL
* Copyright (C) 2003-2005 Lars 'AnotherGuest' Persson - Original EPOC port, Audio System
* Copyright (C) 2005 Jurgen 'SumthinWicked' Braam - EPOC/CVS maintainer
- * Copyright (C) 2005-2011 The ScummVM project
+ * Copyright (C) 2005-2012 The ScummVM project
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
diff --git a/backends/platform/symbian/mmp/scummvm_sword2.mmp.in b/backends/platform/symbian/mmp/scummvm_sword2.mmp.in
index c8034c3015..32ab259ee4 100644
--- a/backends/platform/symbian/mmp/scummvm_sword2.mmp.in
+++ b/backends/platform/symbian/mmp/scummvm_sword2.mmp.in
@@ -2,7 +2,7 @@
* Copyright (C) 2003-2005 Andreas 'Sprawl' Karlsson - Original EPOC port, ESDL
* Copyright (C) 2003-2005 Lars 'AnotherGuest' Persson - Original EPOC port, Audio System
* Copyright (C) 2005 Jurgen 'SumthinWicked' Braam - EPOC/CVS maintainer
- * Copyright (C) 2005-2011 The ScummVM project
+ * Copyright (C) 2005-2012 The ScummVM project
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
diff --git a/backends/platform/symbian/mmp/scummvm_teenagent.mmp.in b/backends/platform/symbian/mmp/scummvm_teenagent.mmp.in
index f065bf4376..61c50bd307 100644
--- a/backends/platform/symbian/mmp/scummvm_teenagent.mmp.in
+++ b/backends/platform/symbian/mmp/scummvm_teenagent.mmp.in
@@ -2,7 +2,7 @@
* Copyright (C) 2003-2005 Andreas 'Sprawl' Karlsson - Original EPOC port, ESDL
* Copyright (C) 2003-2005 Lars 'AnotherGuest' Persson - Original EPOC port, Audio System
* Copyright (C) 2005 Jurgen 'SumthinWicked' Braam - EPOC/CVS maintainer
- * Copyright (C) 2005-2011 The ScummVM project
+ * Copyright (C) 2005-2012 The ScummVM project
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
diff --git a/backends/platform/symbian/mmp/scummvm_tinsel.mmp.in b/backends/platform/symbian/mmp/scummvm_tinsel.mmp.in
index d61492de6b..375d948190 100644
--- a/backends/platform/symbian/mmp/scummvm_tinsel.mmp.in
+++ b/backends/platform/symbian/mmp/scummvm_tinsel.mmp.in
@@ -2,7 +2,7 @@
* Copyright (C) 2003-2005 Andreas 'Sprawl' Karlsson - Original EPOC port, ESDL
* Copyright (C) 2003-2005 Lars 'AnotherGuest' Persson - Original EPOC port, Audio System
* Copyright (C) 2005 Jurgen 'SumthinWicked' Braam - EPOC/CVS maintainer
- * Copyright (C) 2005-2011 The ScummVM project
+ * Copyright (C) 2005-2012 The ScummVM project
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
diff --git a/backends/platform/symbian/mmp/scummvm_toon.mmp.in b/backends/platform/symbian/mmp/scummvm_toon.mmp.in
index 01924614b4..d105156107 100644
--- a/backends/platform/symbian/mmp/scummvm_toon.mmp.in
+++ b/backends/platform/symbian/mmp/scummvm_toon.mmp.in
@@ -2,7 +2,7 @@
* Copyright (C) 2003-2005 Andreas 'Sprawl' Karlsson - Original EPOC port, ESDL
* Copyright (C) 2003-2005 Lars 'AnotherGuest' Persson - Original EPOC port, Audio System
* Copyright (C) 2005 Jurgen 'SumthinWicked' Braam - EPOC/CVS maintainer
- * Copyright (C) 2005-2011 The ScummVM project
+ * Copyright (C) 2005-2012 The ScummVM project
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
diff --git a/backends/platform/symbian/mmp/scummvm_touche.mmp.in b/backends/platform/symbian/mmp/scummvm_touche.mmp.in
index b9cb53b4bf..36588e051f 100644
--- a/backends/platform/symbian/mmp/scummvm_touche.mmp.in
+++ b/backends/platform/symbian/mmp/scummvm_touche.mmp.in
@@ -2,7 +2,7 @@
* Copyright (C) 2003-2005 Andreas 'Sprawl' Karlsson - Original EPOC port, ESDL
* Copyright (C) 2003-2005 Lars 'AnotherGuest' Persson - Original EPOC port, Audio System
* Copyright (C) 2005 Jurgen 'SumthinWicked' Braam - EPOC/CVS maintainer
- * Copyright (C) 2005-2011 The ScummVM project
+ * Copyright (C) 2005-2012 The ScummVM project
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
diff --git a/backends/platform/symbian/mmp/scummvm_tsage.mmp.in b/backends/platform/symbian/mmp/scummvm_tsage.mmp.in
index fa4968f704..fb9b075435 100644
--- a/backends/platform/symbian/mmp/scummvm_tsage.mmp.in
+++ b/backends/platform/symbian/mmp/scummvm_tsage.mmp.in
@@ -2,7 +2,7 @@
* Copyright (C) 2003-2005 Andreas 'Sprawl' Karlsson - Original EPOC port, ESDL
* Copyright (C) 2003-2005 Lars 'AnotherGuest' Persson - Original EPOC port, Audio System
* Copyright (C) 2005 Jurgen 'SumthinWicked' Braam - EPOC/CVS maintainer
- * Copyright (C) 2005-2011 The ScummVM project
+ * Copyright (C) 2005-2012 The ScummVM project
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
diff --git a/backends/platform/symbian/mmp/scummvm_tucker.mmp.in b/backends/platform/symbian/mmp/scummvm_tucker.mmp.in
index 1ea564c0c0..f8954e6d21 100644
--- a/backends/platform/symbian/mmp/scummvm_tucker.mmp.in
+++ b/backends/platform/symbian/mmp/scummvm_tucker.mmp.in
@@ -2,7 +2,7 @@
* Copyright (C) 2003-2005 Andreas 'Sprawl' Karlsson - Original EPOC port, ESDL
* Copyright (C) 2003-2005 Lars 'AnotherGuest' Persson - Original EPOC port, Audio System
* Copyright (C) 2005 Jurgen 'SumthinWicked' Braam - EPOC/CVS maintainer
- * Copyright (C) 2005-2011 The ScummVM project
+ * Copyright (C) 2005-2012 The ScummVM project
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
diff --git a/backends/platform/symbian/res/ScummVmAif.rss b/backends/platform/symbian/res/ScummVmAif.rss
index b2addc3f21..3e7a86a3bc 100644
--- a/backends/platform/symbian/res/ScummVmAif.rss
+++ b/backends/platform/symbian/res/ScummVmAif.rss
@@ -2,7 +2,7 @@
* Copyright (C) 2003-2005 Andreas 'Sprawl' Karlsson - Original EPOC port, ESDL
* Copyright (C) 2003-2005 Lars 'AnotherGuest' Persson - Original EPOC port, Audio System
* Copyright (C) 2005 Jurgen 'SumthinWicked' Braam - EPOC/CVS maintainer
- * Copyright (C) 2005-2011 The ScummVM project
+ * Copyright (C) 2005-2012 The ScummVM project
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
diff --git a/backends/platform/symbian/res/scummvm.rss b/backends/platform/symbian/res/scummvm.rss
index 62da39e6a8..361f831e3c 100644
--- a/backends/platform/symbian/res/scummvm.rss
+++ b/backends/platform/symbian/res/scummvm.rss
@@ -2,7 +2,7 @@
* Copyright (C) 2003-2005 Andreas 'Sprawl' Karlsson - Original EPOC port, ESDL
* Copyright (C) 2003-2005 Lars 'AnotherGuest' Persson - Original EPOC port, Audio System
* Copyright (C) 2005 Jurgen 'SumthinWicked' Braam - EPOC/CVS maintainer
- * Copyright (C) 2005-2011 The ScummVM project
+ * Copyright (C) 2005-2012 The ScummVM project
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
diff --git a/backends/platform/symbian/res/scummvm_A0000658.rss b/backends/platform/symbian/res/scummvm_A0000658.rss
index 5615bbda9f..14d591c990 100644
--- a/backends/platform/symbian/res/scummvm_A0000658.rss
+++ b/backends/platform/symbian/res/scummvm_A0000658.rss
@@ -2,7 +2,7 @@
* Copyright (C) 2003-2005 Andreas 'Sprawl' Karlsson - Original EPOC port, ESDL
* Copyright (C) 2003-2005 Lars 'AnotherGuest' Persson - Original EPOC port, Audio System
* Copyright (C) 2005 Jurgen 'SumthinWicked' Braam - EPOC/CVS maintainer
- * Copyright (C) 2005-2011 The ScummVM project
+ * Copyright (C) 2005-2012 The ScummVM project
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
diff --git a/backends/platform/symbian/src/ScummVm.hrh b/backends/platform/symbian/src/ScummVm.hrh
index c18048c922..a84664f995 100644
--- a/backends/platform/symbian/src/ScummVm.hrh
+++ b/backends/platform/symbian/src/ScummVm.hrh
@@ -2,7 +2,7 @@
* Copyright (C) 2003-2005 Andreas 'Sprawl' Karlsson - Original EPOC port, ESDL
* Copyright (C) 2003-2005 Lars 'AnotherGuest' Persson - Original EPOC port, Audio System
* Copyright (C) 2005 Jurgen 'SumthinWicked' Braam - EPOC/CVS maintainer
- * Copyright (C) 2005-2011 The ScummVM project
+ * Copyright (C) 2005-2012 The ScummVM project
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
diff --git a/backends/platform/webos/webos.cpp b/backends/platform/webos/webos.cpp
index bfb19ed3bc..4ec153a7e9 100644
--- a/backends/platform/webos/webos.cpp
+++ b/backends/platform/webos/webos.cpp
@@ -51,20 +51,18 @@ void OSystem_SDL_WebOS::initBackend() {
*
* @return The hardware key set with added webOS specific keys.
*/
-HardwareKeySet *OSystem_SDL_WebOS::getHardwareKeySet() {
#ifdef ENABLE_KEYMAPPER
+HardwareInputSet *OSystem_SDL_WebOS::getHardwareInputSet() {
// Get the original SDL hardware key set
- HardwareKeySet *keySet = OSystem_SDL::getHardwareKeySet();
+ HardwareInputSet *inputSet = OSystem_SDL::getHardwareInputSet();
// Add WebOS specific keys
- keySet->addHardwareKey(new HardwareKey("FORWARD",
- KeyState((KeyCode) 229, 229, 0), "Forward", kActionKeyType));
+ inputSet->addHardwareInput(new HardwareInput("FORWARD",
+ KeyState((KeyCode) 229, 229, 0), "Forward"));
// Return the modified hardware key set
- return keySet;
-#else
- return 0;
-#endif
+ return inputSet;
}
+#endif
#endif
diff --git a/backends/platform/webos/webos.h b/backends/platform/webos/webos.h
index 850aaf9ce2..8dfa43239c 100644
--- a/backends/platform/webos/webos.h
+++ b/backends/platform/webos/webos.h
@@ -31,7 +31,9 @@ public:
OSystem_SDL_WebOS();
virtual void initBackend();
- virtual Common::HardwareKeySet *getHardwareKeySet();
+#ifdef ENABLE_KEYMAPPER
+ virtual Common::HardwareInputSet *getHardwareInputSet();
+#endif
};
#endif
diff --git a/backends/platform/wince/README-WinCE.txt b/backends/platform/wince/README-WinCE.txt
index 429168c293..11467fd482 100644
--- a/backends/platform/wince/README-WinCE.txt
+++ b/backends/platform/wince/README-WinCE.txt
@@ -1,10 +1,17 @@
ScummVM Windows CE FAQ
-Last updated: 2011-10-15
-Release version: 1.4.0
+Last updated: 2011-12-05
+Release version: x.x.x
------------------------------------------------------------------------
New in this version
-------------------
+x.x.x:
+- Removed FLAC support for audio datafiles (now for real, this was originally
+ announced for 1.0.0, but the library was still included until now). This is
+ done because of size constrains of the executable and also FLAC on a mobile
+ device isn't really recommended - so please use MP3 or Ogg for your audio
+ datafiles.
+
1.4.0:
- Changed the memory management so that it is finally possible to break the
32MB per process barrier on Windows CE. It should be possible now (finally)
@@ -18,6 +25,8 @@ New in this version
- Discworld 2 is now playable (works now because of the new memory management)
- Replaced the game mass-adding functionality with the functionality used on
all other platforms. It now shows progress while searching for games.
+- Mapped "Skip" button to F10 for AGI games
+- Mapped "Multi Function" to F10 in Simon 1 & 2 (enables hotspot highlighting)
1.3.1:
- Fix for Normal2xAspect scaler which was causing screen update issues in some
@@ -60,7 +69,7 @@ scummvm2.exe:
- agos, cine, drascula, gob, groovie, kyra, made, parallaction, saga,
teenagent, tucker
scummvm3.exe:
- - hugo, mohawk, sci, sword2, toon
+ - hugo, mohawk, sci, sword2, toon, tsage
There are no other port specific changes.
@@ -264,6 +273,7 @@ The following actions are available :
* Quit : quit ScummVM (without saving, be careful when using it)
* Skip : skip a non interactive sequence, the current dialog or
behaves like the ESC key on a regular keyboard
+ All AGI games -> F10 to quit full-screen dialogs
* Hide : hide or display the toolbar
* Keyboard : hide or display the virtual keyboard
* Sound : turns all sound effects and music off and on
@@ -282,6 +292,7 @@ The following actions are available :
Fate of Atlantis -> sucker punch (cheat)
Bargon -> F1 (start the game)
All AGI games -> bring up the predictive input dialog
+ Simon 1 & 2 -> highlight all hotspots in screen
* Bind keys map a key action to a device button
* Up,Down,Left :
Right, : emulate mouse/stylus behavior
diff --git a/backends/platform/wince/portdefs.h b/backends/platform/wince/portdefs.h
index 93df6cd39e..289406c2a4 100644
--- a/backends/platform/wince/portdefs.h
+++ b/backends/platform/wince/portdefs.h
@@ -73,6 +73,7 @@
#include <mmsystem.h>
#include <ctype.h>
//#include <direct.h>
+#include <new>
#ifdef __MINGW32CE__
void *bsearch(const void *, const void *, size_t, size_t, int (*x)(const void *, const void *));
diff --git a/backends/platform/wince/wince-sdl.cpp b/backends/platform/wince/wince-sdl.cpp
index 4e17827e5c..a57fcb9628 100644
--- a/backends/platform/wince/wince-sdl.cpp
+++ b/backends/platform/wince/wince-sdl.cpp
@@ -87,15 +87,15 @@ extern "C" void *__wrap_malloc(size_t size) {
void *ptr = __real_malloc(size+4);
// printf("malloc(%d) = %p\n", size, ptr);
if (ptr != NULL) {
- *((HANDLE*)ptr) = 0;
- return 4+(char*)ptr;
+ *((HANDLE *)ptr) = 0;
+ return 4+(char *)ptr;
}
return NULL;
}
HANDLE H = CreateFileMapping((HANDLE)INVALID_HANDLE_VALUE, 0, PAGE_READWRITE, 0, size+4, 0);
void *ptr = MapViewOfFile(H, FILE_MAP_ALL_ACCESS, 0, 0, 0);
- *((HANDLE*)ptr) = H;
- return 4+(char*)ptr;
+ *((HANDLE *)ptr) = H;
+ return 4+(char *)ptr;
}
extern "C" void __wrap_free(void *ptr) {
@@ -104,9 +104,9 @@ extern "C" void __wrap_free(void *ptr) {
printf("free(%p)\n", ptr);
*/
if (ptr != NULL) {
- HANDLE H = *(HANDLE*)((char *)ptr-4);
+ HANDLE H = *(HANDLE *)((char *)ptr-4);
if (H == 0) {
- __real_free((char*)ptr-4);
+ __real_free((char *)ptr-4);
return;
}
UnmapViewOfFile((char *)ptr-4);
diff --git a/backends/plugins/elf/elf-loader.cpp b/backends/plugins/elf/elf-loader.cpp
index d75010196a..d60ddce57e 100644
--- a/backends/plugins/elf/elf-loader.cpp
+++ b/backends/plugins/elf/elf-loader.cpp
@@ -480,7 +480,7 @@ void *DLObject::symbol(const char *name) {
!strcmp(name, _strtab + s->st_name)) {
// We found the symbol
debug(2, "elfloader: => 0x%08x", s->st_value);
- return (void*)s->st_value;
+ return (void *)s->st_value;
}
// We didn't find the symbol
diff --git a/backends/saves/windows/windows-saves.cpp b/backends/saves/windows/windows-saves.cpp
new file mode 100644
index 0000000000..87348c3416
--- /dev/null
+++ b/backends/saves/windows/windows-saves.cpp
@@ -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.
+ *
+ */
+
+#include "common/scummsys.h"
+
+#include "backends/saves/windows/windows-saves.h"
+
+#if defined(WIN32) && !defined(_WIN32_WCE) && !defined(DISABLE_DEFAULT_SAVEFILEMANAGER)
+
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+
+#include "common/config-manager.h"
+#include "common/savefile.h"
+
+WindowsSaveFileManager::WindowsSaveFileManager() {
+ char defaultSavepath[MAXPATHLEN];
+
+ OSVERSIONINFO win32OsVersion;
+ ZeroMemory(&win32OsVersion, sizeof(OSVERSIONINFO));
+ win32OsVersion.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
+ GetVersionEx(&win32OsVersion);
+ // Check for non-9X version of Windows.
+ if (win32OsVersion.dwPlatformId != VER_PLATFORM_WIN32_WINDOWS) {
+ // Use the Application Data directory of the user profile.
+ if (win32OsVersion.dwMajorVersion >= 5) {
+ if (!GetEnvironmentVariable("APPDATA", defaultSavepath, sizeof(defaultSavepath)))
+ error("Unable to access application data directory");
+ } else {
+ if (!GetEnvironmentVariable("USERPROFILE", defaultSavepath, sizeof(defaultSavepath)))
+ error("Unable to access user profile directory");
+
+ strcat(defaultSavepath, "\\Application Data");
+
+ // If the directory already exists (as it should in most cases),
+ // we don't want to fail, but we need to stop on other errors (such as ERROR_PATH_NOT_FOUND)
+ if (!CreateDirectory(defaultSavepath, NULL)) {
+ if (GetLastError() != ERROR_ALREADY_EXISTS)
+ error("Cannot create Application data folder");
+ }
+ }
+
+ strcat(defaultSavepath, "\\ScummVM");
+ if (!CreateDirectory(defaultSavepath, NULL)) {
+ if (GetLastError() != ERROR_ALREADY_EXISTS)
+ error("Cannot create ScummVM application data folder");
+ }
+
+ strcat(defaultSavepath, "\\Saved games");
+ if (!CreateDirectory(defaultSavepath, NULL)) {
+ if (GetLastError() != ERROR_ALREADY_EXISTS)
+ error("Cannot create ScummVM Saved games folder");
+ }
+
+ ConfMan.registerDefault("savepath", defaultSavepath);
+ }
+}
+
+#endif
diff --git a/backends/saves/windows/windows-saves.h b/backends/saves/windows/windows-saves.h
new file mode 100644
index 0000000000..a705aa2b7f
--- /dev/null
+++ b/backends/saves/windows/windows-saves.h
@@ -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.
+ *
+ */
+
+#ifndef BACKEND_WINDOWS_SAVES_H
+#define BACKEND_WINDOWS_SAVES_H
+
+#include "backends/saves/default/default-saves.h"
+
+/**
+ * Provides a default savefile manager implementation for common platforms.
+ */
+class WindowsSaveFileManager : public DefaultSaveFileManager {
+public:
+ WindowsSaveFileManager();
+};
+
+#endif
diff --git a/backends/taskbar/win32/win32-taskbar.cpp b/backends/taskbar/win32/win32-taskbar.cpp
index 046ddb1cd0..5c9105b0eb 100644
--- a/backends/taskbar/win32/win32-taskbar.cpp
+++ b/backends/taskbar/win32/win32-taskbar.cpp
@@ -29,13 +29,9 @@
#if defined(WIN32) && defined(USE_TASKBAR)
// Needed for taskbar functions
-#if defined(__GNUC__)
-#ifdef __MINGW32__
+#if defined(__GNUC__) && defined(__MINGW32__) && !defined(__MINGW64__)
#include "backends/taskbar/win32/mingw-compat.h"
#else
- #error Only compilation with MingW is supported
-#endif
-#else
// We need certain functions that are excluded by default
#undef NONLS
#undef NOICONS
@@ -44,9 +40,12 @@
#undef ARRAYSIZE
#endif
- // Default MSVC headers for ITaskbarList3 and IShellLink
- #include <SDKDDKVer.h>
+ #if defined(_MSC_VER)
+ // Default MSVC headers for ITaskbarList3 and IShellLink
+ #include <SDKDDKVer.h>
+ #endif
#endif
+
#include <shlobj.h>
// For HWND
@@ -75,7 +74,7 @@ Win32TaskbarManager::Win32TaskbarManager() : _taskbar(NULL), _count(0), _icon(NU
0,
CLSCTX_INPROC_SERVER,
IID_ITaskbarList3,
- reinterpret_cast<void**> (&(_taskbar)));
+ reinterpret_cast<void **> (&(_taskbar)));
if (SUCCEEDED(hr)) {
// Initialize taskbar object
@@ -275,7 +274,7 @@ void Win32TaskbarManager::addRecent(const Common::String &name, const Common::St
GetModuleFileNameW(NULL, path, MAX_PATH);
// Create a shell link.
- if (SUCCEEDED(CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC, IID_IShellLinkW, reinterpret_cast<void**> (&link)))) {
+ if (SUCCEEDED(CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC, IID_IShellLinkW, reinterpret_cast<void **> (&link)))) {
// Convert game name and description to Unicode.
LPWSTR game = ansiToUnicode(name.c_str());
LPWSTR desc = ansiToUnicode(description.c_str());
@@ -297,7 +296,7 @@ void Win32TaskbarManager::addRecent(const Common::String &name, const Common::St
// The link's display name must be set via property store.
IPropertyStore* propStore;
- HRESULT hr = link->QueryInterface(IID_IPropertyStore, reinterpret_cast<void**> (&(propStore)));
+ HRESULT hr = link->QueryInterface(IID_IPropertyStore, reinterpret_cast<void **> (&(propStore)));
if (SUCCEEDED(hr)) {
PROPVARIANT pv;
pv.vt = VT_LPWSTR;
diff --git a/backends/timer/bada/timer.cpp b/backends/timer/bada/timer.cpp
index 8f5620401f..faddacb3c3 100755
--- a/backends/timer/bada/timer.cpp
+++ b/backends/timer/bada/timer.cpp
@@ -76,7 +76,7 @@ BadaTimerManager::BadaTimerManager() {
BadaTimerManager::~BadaTimerManager() {
for (Common::List<TimerSlot>::iterator slot = _timers.begin();
- slot != _timers.end(); ++slot) {
+ slot != _timers.end(); ) {
slot->Stop();
slot = _timers.erase(slot);
}
diff --git a/backends/timer/default/default-timer.cpp b/backends/timer/default/default-timer.cpp
index e1aadb62b8..8681102cd0 100644
--- a/backends/timer/default/default-timer.cpp
+++ b/backends/timer/default/default-timer.cpp
@@ -122,7 +122,7 @@ bool DefaultTimerManager::installTimerProc(TimerProc callback, int32 interval, v
for (i = _callbacks.begin(); i != _callbacks.end(); ++i) {
if (i->_value == callback) {
- error("Same callback is referred by different names (%s vs %s)", i->_key.c_str(), id.c_str());
+ error("Same callback added twice (old name: %s, new name: %s)", i->_key.c_str(), id.c_str());
}
}
_callbacks[id] = callback;
@@ -136,12 +136,6 @@ bool DefaultTimerManager::installTimerProc(TimerProc callback, int32 interval, v
slot->nextFireTimeMicro = interval % 1000;
slot->next = 0;
- // FIXME: It seems we do allow the client to add one callback multiple times over here,
- // but "removeTimerProc" will remove *all* added instances. We should either prevent
- // multiple additions of a timer proc OR we should change removeTimerProc to only remove
- // a specific timer proc entry.
- // Probably we can safely just allow a single addition of a specific function once
- // and just update our Timer documentation accordingly.
insertPrioQueue(_head, slot);
return true;
diff --git a/backends/vkeybd/image-map.cpp b/backends/vkeybd/image-map.cpp
index 275ec865ed..359fc58d20 100644
--- a/backends/vkeybd/image-map.cpp
+++ b/backends/vkeybd/image-map.cpp
@@ -35,7 +35,7 @@ ImageMap::~ImageMap() {
removeAllAreas();
}
-Polygon *ImageMap::createArea(const String& id) {
+Polygon *ImageMap::createArea(const String &id) {
if (_areas.contains(id)) {
warning("Image map already contains an area with target of '%s'", id.c_str());
return 0;
@@ -45,7 +45,7 @@ Polygon *ImageMap::createArea(const String& id) {
return p;
}
-void ImageMap::removeArea(const String& id) {
+void ImageMap::removeArea(const String &id) {
if (!_areas.contains(id))
return;
delete _areas[id];
@@ -53,19 +53,18 @@ void ImageMap::removeArea(const String& id) {
}
void ImageMap::removeAllAreas() {
- HashMap<String, Polygon*>::iterator it;
- for (it = _areas.begin(); it != _areas.end(); ++it) {
+ for (AreaMap::iterator it = _areas.begin(); it != _areas.end(); ++it) {
delete it->_value;
}
_areas.clear();
}
String ImageMap::findMapArea(int16 x, int16 y) {
- HashMap<String, Polygon*>::iterator it;
- for (it = _areas.begin(); it != _areas.end(); ++it) {
+ for (AreaMap::iterator it = _areas.begin(); it != _areas.end(); ++it) {
if (it->_value->contains(x, y))
return it->_key;
}
+
return String();
}
diff --git a/backends/vkeybd/image-map.h b/backends/vkeybd/image-map.h
index 3bd8cfa0db..952ba624b0 100644
--- a/backends/vkeybd/image-map.h
+++ b/backends/vkeybd/image-map.h
@@ -35,18 +35,17 @@ namespace Common {
struct Polygon;
class ImageMap {
-
public:
-
~ImageMap();
- Polygon *createArea(const String& id);
- void removeArea(const String& id);
+ Polygon *createArea(const String &id);
+ void removeArea(const String &id);
void removeAllAreas();
String findMapArea(int16 x, int16 y);
protected:
- HashMap<String, Polygon *> _areas;
+ typedef HashMap<String, Polygon *> AreaMap;
+ AreaMap _areas;
};
diff --git a/backends/vkeybd/polygon.cpp b/backends/vkeybd/polygon.cpp
index ac42cb1d2e..08727a6fe8 100644
--- a/backends/vkeybd/polygon.cpp
+++ b/backends/vkeybd/polygon.cpp
@@ -42,7 +42,7 @@ bool Polygon::contains(int16 x, int16 y) const {
yflag1 = (vtx1->y >= y);
if (yflag0 != yflag1) {
if (((vtx1->y - y) * (vtx0->x - vtx1->x) >=
- (vtx1->x - x) * (vtx0->y - vtx1->y)) == yflag1) {
+ (vtx1->x - x) * (vtx0->y - vtx1->y)) == yflag1) {
inside_flag = !inside_flag;
}
}
diff --git a/backends/vkeybd/polygon.h b/backends/vkeybd/polygon.h
index 19a12a0409..91c8d017b2 100644
--- a/backends/vkeybd/polygon.h
+++ b/backends/vkeybd/polygon.h
@@ -46,13 +46,13 @@ struct Polygon {
}
}
- void addPoint(const Point& p) {
+ void addPoint(const Point &p) {
_points.push_back(p);
_bound.extend(Rect(p.x, p.y, p.x, p.y));
}
void addPoint(int16 x, int16 y) {
- addPoint(Point(x,y));
+ addPoint(Point(x, y));
}
uint getPointCount() {
diff --git a/backends/vkeybd/virtual-keyboard-gui.cpp b/backends/vkeybd/virtual-keyboard-gui.cpp
index 1c05d62316..42f9707ddc 100644
--- a/backends/vkeybd/virtual-keyboard-gui.cpp
+++ b/backends/vkeybd/virtual-keyboard-gui.cpp
@@ -75,8 +75,8 @@ static void blit(Graphics::Surface *surf_dst, Graphics::Surface *surf_src, int16
VirtualKeyboardGUI::VirtualKeyboardGUI(VirtualKeyboard *kbd)
: _kbd(kbd), _displaying(false), _drag(false),
- _drawCaret(false), _displayEnabled(false), _firstRun(true),
- _cursorAnimateTimer(0), _cursorAnimateCounter(0) {
+ _drawCaret(false), _displayEnabled(false), _firstRun(true),
+ _cursorAnimateTimer(0), _cursorAnimateCounter(0) {
assert(_kbd);
assert(g_system);
@@ -111,7 +111,7 @@ void VirtualKeyboardGUI::initMode(VirtualKeyboard::Mode *mode) {
}
}
-void VirtualKeyboardGUI::setupDisplayArea(Rect& r, OverlayColor forecolor) {
+void VirtualKeyboardGUI::setupDisplayArea(Rect &r, OverlayColor forecolor) {
_dispFont = FontMan.getFontByUsage(Graphics::FontManager::kBigGUIFont);
if (!fontIsSuitable(_dispFont, r)) {
@@ -135,9 +135,9 @@ void VirtualKeyboardGUI::setupDisplayArea(Rect& r, OverlayColor forecolor) {
_displayEnabled = true;
}
-bool VirtualKeyboardGUI::fontIsSuitable(const Graphics::Font *font, const Rect& rect) {
+bool VirtualKeyboardGUI::fontIsSuitable(const Graphics::Font *font, const Rect &rect) {
return (font->getMaxCharWidth() < rect.width() &&
- font->getFontHeight() < rect.height());
+ font->getFontHeight() < rect.height());
}
void VirtualKeyboardGUI::checkScreenChanged() {
@@ -161,7 +161,7 @@ void VirtualKeyboardGUI::run() {
_system->clearOverlay();
}
_overlayBackup.create(_screenW, _screenH, _system->getOverlayFormat());
- _system->grabOverlay((OverlayColor*)_overlayBackup.pixels, _overlayBackup.w);
+ _system->grabOverlay((OverlayColor *)_overlayBackup.pixels, _overlayBackup.w);
setupCursor();
@@ -171,7 +171,7 @@ void VirtualKeyboardGUI::run() {
removeCursor();
- _system->copyRectToOverlay((OverlayColor*)_overlayBackup.pixels, _overlayBackup.w, 0, 0, _overlayBackup.w, _overlayBackup.h);
+ _system->copyRectToOverlay((OverlayColor *)_overlayBackup.pixels, _overlayBackup.w, 0, 0, _overlayBackup.w, _overlayBackup.h);
if (!g_gui.isActive()) _system->hideOverlay();
_overlayBackup.free();
@@ -183,16 +183,15 @@ void VirtualKeyboardGUI::close() {
}
void VirtualKeyboardGUI::reset() {
- _kbdBound.left = _kbdBound.top
- = _kbdBound.right = _kbdBound.bottom = 0;
+ _kbdBound.left = _kbdBound.top = 0;
+ _kbdBound.right = _kbdBound.bottom = 0;
_displaying = _drag = false;
_firstRun = true;
_lastScreenChanged = _system->getScreenChangeID();
_kbdSurface = 0;
}
-void VirtualKeyboardGUI::moveToDefaultPosition()
-{
+void VirtualKeyboardGUI::moveToDefaultPosition() {
int16 kbdW = _kbdBound.width(), kbdH = _kbdBound.height();
int16 x = 0, y = 0;
if (_screenW != kbdW) {
@@ -263,7 +262,7 @@ void VirtualKeyboardGUI::screenChanged() {
_screenH = newScreenH;
_overlayBackup.create(_screenW, _screenH, _system->getOverlayFormat());
- _system->grabOverlay((OverlayColor*)_overlayBackup.pixels, _overlayBackup.w);
+ _system->grabOverlay((OverlayColor *)_overlayBackup.pixels, _overlayBackup.w);
if (!_kbd->checkModeResolutions()) {
_displaying = false;
@@ -290,19 +289,19 @@ void VirtualKeyboardGUI::mainLoop() {
case Common::EVENT_LBUTTONDOWN:
if (_kbdBound.contains(event.mouse)) {
_kbd->handleMouseDown(event.mouse.x - _kbdBound.left,
- event.mouse.y - _kbdBound.top);
+ event.mouse.y - _kbdBound.top);
}
break;
case Common::EVENT_LBUTTONUP:
if (_kbdBound.contains(event.mouse)) {
_kbd->handleMouseUp(event.mouse.x - _kbdBound.left,
- event.mouse.y - _kbdBound.top);
+ event.mouse.y - _kbdBound.top);
}
break;
case Common::EVENT_MOUSEMOVE:
if (_drag)
move(event.mouse.x - _dragPoint.x,
- event.mouse.y - _dragPoint.y);
+ event.mouse.y - _dragPoint.y);
break;
case Common::EVENT_SCREEN_CHANGED:
screenChanged();
@@ -367,20 +366,20 @@ void VirtualKeyboardGUI::redraw() {
}
blit(&surf, _kbdSurface, _kbdBound.left - _dirtyRect.left,
- _kbdBound.top - _dirtyRect.top, _kbdTransparentColor);
+ _kbdBound.top - _dirtyRect.top, _kbdTransparentColor);
if (_displayEnabled) {
blit(&surf, &_dispSurface, _dispX - _dirtyRect.left,
- _dispY - _dirtyRect.top, _dispBackColor);
+ _dispY - _dirtyRect.top, _dispBackColor);
}
- _system->copyRectToOverlay((OverlayColor*)surf.pixels, surf.w,
- _dirtyRect.left, _dirtyRect.top, surf.w, surf.h);
+ _system->copyRectToOverlay((OverlayColor *)surf.pixels, surf.w,
+ _dirtyRect.left, _dirtyRect.top, surf.w, surf.h);
surf.free();
resetDirtyRect();
}
-uint VirtualKeyboardGUI::calculateEndIndex(const String& str, uint startIndex) {
+uint VirtualKeyboardGUI::calculateEndIndex(const String &str, uint startIndex) {
int16 w = 0;
while (w <= _dispSurface.w && startIndex < str.size()) {
w += _dispFont->getCharWidth(str[startIndex++]);
@@ -436,10 +435,10 @@ void VirtualKeyboardGUI::updateDisplay() {
void VirtualKeyboardGUI::setupCursor() {
const byte palette[] = {
- 255, 255, 255, 0,
- 255, 255, 255, 0,
- 171, 171, 171, 0,
- 87, 87, 87, 0
+ 255, 255, 255,
+ 255, 255, 255,
+ 171, 171, 171,
+ 87, 87, 87
};
CursorMan.pushCursorPalette(palette, 0, 4);
diff --git a/backends/vkeybd/virtual-keyboard-gui.h b/backends/vkeybd/virtual-keyboard-gui.h
index da80ef2223..d0f9c884ed 100644
--- a/backends/vkeybd/virtual-keyboard-gui.h
+++ b/backends/vkeybd/virtual-keyboard-gui.h
@@ -121,7 +121,7 @@ private:
bool _displaying;
bool _firstRun;
- void setupDisplayArea(Rect& r, OverlayColor forecolor);
+ void setupDisplayArea(Rect &r, OverlayColor forecolor);
void move(int16 x, int16 y);
void moveToDefaultPosition();
void screenChanged();
@@ -131,8 +131,8 @@ private:
void redraw();
void forceRedraw();
void updateDisplay();
- bool fontIsSuitable(const Graphics::Font *font, const Rect& rect);
- uint calculateEndIndex(const String& str, uint startIndex);
+ bool fontIsSuitable(const Graphics::Font *font, const Rect &rect);
+ uint calculateEndIndex(const String &str, uint startIndex);
bool _drawCaret;
int16 _caretX;
@@ -141,7 +141,7 @@ private:
static const int kCursorAnimateDelay = 250;
int _cursorAnimateCounter;
- int _cursorAnimateTimer;
+ int _cursorAnimateTimer;
byte _cursor[2048];
void setupCursor();
void removeCursor();
diff --git a/backends/vkeybd/virtual-keyboard-parser.cpp b/backends/vkeybd/virtual-keyboard-parser.cpp
index 58f0c468f6..1958113578 100644
--- a/backends/vkeybd/virtual-keyboard-parser.cpp
+++ b/backends/vkeybd/virtual-keyboard-parser.cpp
@@ -116,7 +116,7 @@ bool VirtualKeyboardParser::parserCallback_mode(ParserNode *node) {
_keyboard->_initialMode = _mode;
String resolutions = node->values["resolutions"];
- StringTokenizer tok (resolutions, " ,");
+ StringTokenizer tok(resolutions, " ,");
// select best resolution simply by minimising the difference between the
// overlay size and the resolution dimensions.
@@ -189,7 +189,7 @@ bool VirtualKeyboardParser::parserCallback_event(ParserNode *node) {
}
evt->type = VirtualKeyboard::kVKEventKey;
- KeyState *ks = (KeyState*) malloc(sizeof(KeyState));
+ KeyState *ks = (KeyState *)malloc(sizeof(KeyState));
ks->keycode = (KeyCode)atoi(node->values["code"].c_str());
ks->ascii = atoi(node->values["ascii"].c_str());
ks->flags = 0;
@@ -204,7 +204,7 @@ bool VirtualKeyboardParser::parserCallback_event(ParserNode *node) {
}
evt->type = VirtualKeyboard::kVKEventModifier;
- byte *flags = (byte*) malloc(sizeof(byte));
+ byte *flags = (byte *)malloc(sizeof(byte));
if (!flags)
error("[VirtualKeyboardParser::parserCallback_event] Cannot allocate memory");
@@ -218,8 +218,8 @@ bool VirtualKeyboardParser::parserCallback_event(ParserNode *node) {
}
evt->type = VirtualKeyboard::kVKEventSwitchMode;
- String& mode = node->values["mode"];
- char *str = (char*) malloc(sizeof(char) * mode.size() + 1);
+ String &mode = node->values["mode"];
+ char *str = (char *)malloc(sizeof(char) * mode.size() + 1);
if (!str)
error("[VirtualKeyboardParser::parserCallback_event] Cannot allocate memory");
@@ -302,9 +302,9 @@ bool VirtualKeyboardParser::parserCallback_map(ParserNode *node) {
}
bool VirtualKeyboardParser::parserCallback_area(ParserNode *node) {
- String& shape = node->values["shape"];
- String& target = node->values["target"];
- String& coords = node->values["coords"];
+ String &shape = node->values["shape"];
+ String &target = node->values["target"];
+ String &coords = node->values["coords"];
if (target.equalsIgnoreCase("display_area")) {
if (!shape.equalsIgnoreCase("rect"))
@@ -313,15 +313,21 @@ bool VirtualKeyboardParser::parserCallback_area(ParserNode *node) {
return parseRect(_mode->displayArea, coords);
} else if (shape.equalsIgnoreCase("rect")) {
Polygon *poly = _mode->imageMap.createArea(target);
- return parseRectAsPolygon(*poly, coords);
+ if (!poly)
+ return parserError(Common::String::format("Cannot define area '%s' again", target.c_str()));
+ else
+ return parseRectAsPolygon(*poly, coords);
} else if (shape.equalsIgnoreCase("poly")) {
Polygon *poly = _mode->imageMap.createArea(target);
- return parsePolygon(*poly, coords);
+ if (!poly)
+ return parserError(Common::String::format("Cannot define area '%s' again", target.c_str()));
+ else
+ return parsePolygon(*poly, coords);
}
return parserError("Area shape '" + shape + "' not known");
}
-byte VirtualKeyboardParser::parseFlags(const String& flags) {
+byte VirtualKeyboardParser::parseFlags(const String &flags) {
if (flags.empty())
return 0;
@@ -338,7 +344,7 @@ byte VirtualKeyboardParser::parseFlags(const String& flags) {
return val;
}
-bool VirtualKeyboardParser::parseRect(Rect &rect, const String& coords) {
+bool VirtualKeyboardParser::parseRect(Rect &rect, const String &coords) {
int x1, y1, x2, y2;
if (!parseIntegerKey(coords, 4, &x1, &y1, &x2, &y2))
return parserError("Invalid coords for rect area");
@@ -351,7 +357,7 @@ bool VirtualKeyboardParser::parseRect(Rect &rect, const String& coords) {
return true;
}
-bool VirtualKeyboardParser::parsePolygon(Polygon &poly, const String& coords) {
+bool VirtualKeyboardParser::parsePolygon(Polygon &poly, const String &coords) {
StringTokenizer tok(coords, ", ");
for (String st = tok.nextToken(); !st.empty(); st = tok.nextToken()) {
int x, y;
@@ -368,7 +374,7 @@ bool VirtualKeyboardParser::parsePolygon(Polygon &poly, const String& coords) {
return true;
}
-bool VirtualKeyboardParser::parseRectAsPolygon(Polygon &poly, const String& coords) {
+bool VirtualKeyboardParser::parseRectAsPolygon(Polygon &poly, const String &coords) {
Rect rect;
if (!parseRect(rect, coords))
return false;
diff --git a/backends/vkeybd/virtual-keyboard-parser.h b/backends/vkeybd/virtual-keyboard-parser.h
index eb25ebe6fd..c8a2c4158e 100644
--- a/backends/vkeybd/virtual-keyboard-parser.h
+++ b/backends/vkeybd/virtual-keyboard-parser.h
@@ -56,31 +56,31 @@ keyboard layouts for different screen resolutions.
<area shape="poly" coords="65,50,67,48,94,48,96,50,96,77,94,79,67,79,65,77" target="q" />
<area shape="poly" coords="105,50,107,48,134,48,136,50,136,77,134,79,107,79,105,77" target="w" />
<area shape="poly" coords="146,50,148,48,174,48,176,50,176,77,174,79,148,79,146,77" target="e" />
- ...
+ ...
<area shape="poly" coords="11,89,12,88,69,88,70,89,70,116,69,117,12,117,11,116" target="caps" />
</map>
- </layout>
- <layout resolution="320x200" bitmap="normal_320x200.bmp" transparent_color="255,0,255">
- ...
- </layout>
+ </layout>
+ <layout resolution="320x200" bitmap="normal_320x200.bmp" transparent_color="255,0,255">
+ ...
+ </layout>
<event name="a" type="key" code="97" ascii="97" modifiers="" />
<event name="b" type="key" code="98" ascii="98" modifiers="" />
<event name="c" type="key" code="99" ascii="99" modifiers="" />
- ...
- <event name="caps" type="switch_mode" mode="caps" />
+ ...
+ <event name="caps" type="switch_mode" mode="caps" />
</mode>
<mode name="caps" resolutions="640x400">
<layout resolution="640x400" bitmap="caps_640x480.bmp" transparent_color="255,0,255">
<map>
<area shape="poly" coords="65,50,67,48,94,48,96,50,96,77,94,79,67,79,65,77" target="Q" />
- ...
+ ...
</map>
</layout>
<event name="A" type="key" code="97" ascii="65" modifiers="shift" />
<event name="B" type="key" code="98" ascii="66" modifiers="shift" />
<event name="C" type="key" code="99" ascii="67" modifiers="shift" />
- ...
+ ...
</mode>
</keyboard>
@@ -188,6 +188,7 @@ public:
* Full parse - when loading keyboard pack for first time
*/
kParseFull,
+
/**
* Just check resolutions and reload layouts if needed - following a
* change in screen size
@@ -257,10 +258,10 @@ protected:
virtual bool closedKeyCallback(ParserNode *node);
/** Parse helper functions */
- byte parseFlags(const String& flags);
- bool parseRect(Rect &rect, const String& coords);
- bool parsePolygon(Polygon &poly, const String& coords);
- bool parseRectAsPolygon(Polygon &poly, const String& coords);
+ byte parseFlags(const String &flags);
+ bool parseRect(Rect &rect, const String &coords);
+ bool parsePolygon(Polygon &poly, const String &coords);
+ bool parseRectAsPolygon(Polygon &poly, const String &coords);
};
} // End of namespace GUI
diff --git a/backends/vkeybd/virtual-keyboard.cpp b/backends/vkeybd/virtual-keyboard.cpp
index 1dada06951..678c751410 100644
--- a/backends/vkeybd/virtual-keyboard.cpp
+++ b/backends/vkeybd/virtual-keyboard.cpp
@@ -56,11 +56,9 @@ VirtualKeyboard::~VirtualKeyboard() {
}
void VirtualKeyboard::deleteEvents() {
- ModeMap::iterator it_m;
- VKEventMap::iterator it_e;
- for (it_m = _modes.begin(); it_m != _modes.end(); ++it_m) {
- VKEventMap *evt = &(it_m->_value.events);
- for (it_e = evt->begin(); it_e != evt->end(); ++it_e)
+ for (ModeMap::iterator it_m = _modes.begin(); it_m != _modes.end(); ++it_m) {
+ VKEventMap &evt = it_m->_value.events;
+ for (VKEventMap::iterator it_e = evt.begin(); it_e != evt.end(); ++it_e)
delete it_e->_value;
}
}
@@ -160,7 +158,7 @@ String VirtualKeyboard::findArea(int16 x, int16 y) {
return _currentMode->imageMap.findMapArea(x, y);
}
-void VirtualKeyboard::processAreaClick(const String& area) {
+void VirtualKeyboard::processAreaClick(const String &area) {
if (!_currentMode->events.contains(area))
return;
@@ -169,10 +167,10 @@ void VirtualKeyboard::processAreaClick(const String& area) {
switch (evt->type) {
case kVKEventKey:
// add virtual keypress to queue
- _keyQueue.insertKey(*(KeyState*)evt->data);
+ _keyQueue.insertKey(*(KeyState *)evt->data);
break;
case kVKEventModifier:
- _keyQueue.toggleFlags(*(byte*)(evt->data));
+ _keyQueue.toggleFlags(*(byte *)(evt->data));
break;
case kVKEventSwitchMode:
// switch to new mode
@@ -332,7 +330,7 @@ void VirtualKeyboard::KeyPressQueue::insertKey(KeyState key) {
void VirtualKeyboard::KeyPressQueue::deleteKey() {
if (_keyPos == _keys.begin())
return;
- List<VirtualKeyPress>::iterator it = _keyPos;
+ KeyPressList::iterator it = _keyPos;
it--;
_strPos -= it->strLen;
while ((it->strLen)-- > 0)
diff --git a/backends/vkeybd/virtual-keyboard.h b/backends/vkeybd/virtual-keyboard.h
index 21db5a47da..4ab5ad446d 100644
--- a/backends/vkeybd/virtual-keyboard.h
+++ b/backends/vkeybd/virtual-keyboard.h
@@ -102,21 +102,21 @@ protected:
}
};
- typedef HashMap<String, VKEvent*> VKEventMap;
+ typedef HashMap<String, VKEvent *> VKEventMap;
/**
* Mode struct encapsulates all the data for each mode of the keyboard
*/
struct Mode {
- String name;
- String resolution;
- String bitmapName;
- Graphics::Surface *image;
- OverlayColor transparentColor;
- ImageMap imageMap;
- VKEventMap events;
- Rect displayArea;
- OverlayColor displayFontColor;
+ String name;
+ String resolution;
+ String bitmapName;
+ Graphics::Surface *image;
+ OverlayColor transparentColor;
+ ImageMap imageMap;
+ VKEventMap events;
+ Rect displayArea;
+ OverlayColor displayFontColor;
Mode() : image(0) {}
~Mode() {
@@ -172,13 +172,13 @@ protected:
byte _flags;
String _flagsStr;
-
- List<VirtualKeyPress> _keys;
+ typedef List<VirtualKeyPress> KeyPressList;
+ KeyPressList _keys;
String _keysStr;
bool _strChanged;
- List<VirtualKeyPress>::iterator _keyPos;
+ KeyPressList::iterator _keyPos;
uint _strPos;
};
@@ -193,7 +193,7 @@ public:
* The system first looks for an uncompressed keyboard pack by searching
* for packName.xml in the filesystem, if this does not exist then it
* searches for a compressed keyboard pack by looking for packName.zip.
- * @param packName name of the keyboard pack
+ * @param packName name of the keyboard pack
*/
bool loadKeyboardPack(const String &packName);
@@ -206,8 +206,8 @@ public:
/**
* Hides the keyboard, ending the event loop.
- * @param submit if true all accumulated key presses are submitted to
- * the event manager
+ * @param submit if true all accumulated key presses are submitted to
+ * the event manager
*/
void close(bool submit);
@@ -229,7 +229,7 @@ protected:
Archive *_fileArchive;
friend class VirtualKeyboardGUI;
- VirtualKeyboardGUI *_kbdGUI;
+ VirtualKeyboardGUI *_kbdGUI;
KeyPressQueue _keyQueue;
@@ -241,7 +241,7 @@ protected:
void deleteEvents();
bool checkModeResolutions();
void switchMode(Mode *newMode);
- void switchMode(const String& newMode);
+ void switchMode(const String &newMode);
void handleMouseDown(int16 x, int16 y);
void handleMouseUp(int16 x, int16 y);
String findArea(int16 x, int16 y);
diff --git a/base/commandLine.cpp b/base/commandLine.cpp
index 6550f60670..08838167e9 100644
--- a/base/commandLine.cpp
+++ b/base/commandLine.cpp
@@ -33,12 +33,15 @@
#include "base/version.h"
#include "common/config-manager.h"
+#include "common/fs.h"
+#include "common/rendermode.h"
#include "common/system.h"
#include "common/textconsole.h"
-#include "common/fs.h"
#include "gui/ThemeEngine.h"
+#include "audio/musicplugin.h"
+
#define DETECTOR_TESTING_HACK
#define UPGRADE_ALL_TARGETS_HACK
@@ -81,6 +84,7 @@ static const char HELP_STRING[] =
" --themepath=PATH Path to where GUI themes are stored\n"
" --list-themes Display list of all usable GUI themes\n"
" -e, --music-driver=MODE Select music driver (see README for details)\n"
+ " --list-audio-devices List all available audio devices\n"
" -q, --language=LANG Select language (en,de,fr,it,pt,es,jp,zh,kr,se,gb,\n"
" hb,ru,cz)\n"
" -m, --music-volume=NUM Set the music volume, 0-255 (default: 192)\n"
@@ -274,7 +278,7 @@ void registerDefaults() {
// resp. between "--some-option" and "--no-some-option".
#define DO_OPTION_BOOL(shortCmd, longCmd) \
if (isLongCmd ? (!strcmp(s+2, longCmd) || !strcmp(s+2, "no-"longCmd)) : (tolower(s[1]) == shortCmd)) { \
- bool boolValue = (islower(static_cast<unsigned char>(s[1])) != 0); \
+ bool boolValue = (Common::isLower(s[1]) != 0); \
s += 2; \
if (isLongCmd) { \
boolValue = !strcmp(s, longCmd); \
@@ -381,6 +385,9 @@ Common::String parseCommandLine(Common::StringMap &settings, int argc, const cha
DO_OPTION('e', "music-driver")
END_OPTION
+ DO_LONG_COMMAND("list-audio-devices")
+ END_OPTION
+
DO_LONG_OPTION_INT("output-rate")
END_OPTION
@@ -689,6 +696,21 @@ static void listThemes() {
printf("%-14s %s\n", i->id.c_str(), i->name.c_str());
}
+/** Lists all output devices */
+static void listAudioDevices() {
+ MusicPlugin::List pluginList = MusicMan.getPlugins();
+
+ printf("ID Description\n");
+ printf("------------------------------ ------------------------------------------------\n");
+
+ for (MusicPlugin::List::const_iterator i = pluginList.begin(), iend = pluginList.end(); i != iend; ++i) {
+ MusicDevices deviceList = (**i)->getDevices();
+ for (MusicDevices::iterator j = deviceList.begin(), jend = deviceList.end(); j != jend; ++j) {
+ printf("%-30s %s\n", Common::String::format("\"%s\"", j->getCompleteId().c_str()).c_str(), j->getCompleteName().c_str());
+ }
+ }
+}
+
#ifdef DETECTOR_TESTING_HACK
static void runDetectorTest() {
@@ -906,6 +928,9 @@ bool processSettings(Common::String &command, Common::StringMap &settings, Commo
} else if (command == "list-themes") {
listThemes();
return true;
+ } else if (command == "list-audio-devices") {
+ listAudioDevices();
+ return true;
} else if (command == "version") {
printf("%s\n", gScummVMFullVersion);
printf("Features compiled in: %s\n", gScummVMFeatures);
diff --git a/base/main.cpp b/base/main.cpp
index 5d0c0ea09a..391d911ae8 100644
--- a/base/main.cpp
+++ b/base/main.cpp
@@ -203,6 +203,9 @@ static Common::Error runGame(const EnginePlugin *plugin, OSystem &system, const
warning(_("Engine does not support debug level '%s'"), token.c_str());
}
+ // Initialize any game-specific keymaps
+ engine->initKeymap();
+
// Inform backend that the engine is about to be run
system.engineInit();
@@ -212,6 +215,9 @@ static Common::Error runGame(const EnginePlugin *plugin, OSystem &system, const
// Inform backend that the engine finished
system.engineDone();
+ // Clean up any game-specific keymaps
+ engine->deinitKeymap();
+
// Free up memory
delete engine;
@@ -253,42 +259,52 @@ static void setupGraphics(OSystem &system) {
}
static void setupKeymapper(OSystem &system) {
-
#ifdef ENABLE_KEYMAPPER
using namespace Common;
Keymapper *mapper = system.getEventManager()->getKeymapper();
- Keymap *globalMap = new Keymap("global");
- Action *act;
- HardwareKeySet *keySet;
- keySet = system.getHardwareKeySet();
+ HardwareInputSet *inputSet = system.getHardwareInputSet();
// Query backend for hardware keys and register them
- mapper->registerHardwareKeySet(keySet);
+ mapper->registerHardwareInputSet(inputSet);
// Now create the global keymap
- act = new Action(globalMap, "MENU", _("Menu"), kGenericActionType, kSelectKeyType);
- act->addKeyEvent(KeyState(KEYCODE_F5, ASCII_F5, 0));
+ Keymap *primaryGlobalKeymap = new Keymap(kGlobalKeymapName);
+ Action *act;
+ act = new Action(primaryGlobalKeymap, "MENU", _("Menu"));
+ act->addEvent(EVENT_MAINMENU);
- act = new Action(globalMap, "SKCT", _("Skip"), kGenericActionType, kActionKeyType);
+ act = new Action(primaryGlobalKeymap, "SKCT", _("Skip"));
act->addKeyEvent(KeyState(KEYCODE_ESCAPE, ASCII_ESCAPE, 0));
- act = new Action(globalMap, "PAUS", _("Pause"), kGenericActionType, kStartKeyType);
+ act = new Action(primaryGlobalKeymap, "PAUS", _("Pause"));
act->addKeyEvent(KeyState(KEYCODE_SPACE, ' ', 0));
- act = new Action(globalMap, "SKLI", _("Skip line"), kGenericActionType, kActionKeyType);
+ act = new Action(primaryGlobalKeymap, "SKLI", _("Skip line"));
act->addKeyEvent(KeyState(KEYCODE_PERIOD, '.', 0));
- act = new Action(globalMap, "VIRT", _("Display keyboard"), kVirtualKeyboardActionType);
- act->addKeyEvent(KeyState(KEYCODE_F7, ASCII_F7, 0));
+#ifdef ENABLE_VKEYBD
+ act = new Action(primaryGlobalKeymap, "VIRT", _("Display keyboard"));
+ act->addEvent(EVENT_VIRTUAL_KEYBOARD);
+#endif
+
+ act = new Action(primaryGlobalKeymap, "REMP", _("Remap keys"));
+ act->addEvent(EVENT_KEYMAPPER_REMAP);
- act = new Action(globalMap, "REMP", _("Remap keys"), kKeyRemapActionType);
- act->addKeyEvent(KeyState(KEYCODE_F8, ASCII_F8, 0));
+ act = new Action(primaryGlobalKeymap, "FULS", _("Toggle FullScreen"));
+ act->addKeyEvent(KeyState(KEYCODE_RETURN, ASCII_RETURN, KBD_ALT));
- mapper->addGlobalKeymap(globalMap);
+ mapper->addGlobalKeymap(primaryGlobalKeymap);
+ mapper->pushKeymap(kGlobalKeymapName, true);
- mapper->pushKeymap("global");
+ // Get the platform-specific global keymap (if it exists)
+ Keymap *platformGlobalKeymap = system.getGlobalKeymap();
+ if (platformGlobalKeymap) {
+ String platformGlobalKeymapName = platformGlobalKeymap->getName();
+ mapper->addGlobalKeymap(platformGlobalKeymap);
+ mapper->pushKeymap(platformGlobalKeymapName, true);
+ }
#endif
}
diff --git a/base/plugins.cpp b/base/plugins.cpp
index f9ac338d40..f1b08f7893 100644
--- a/base/plugins.cpp
+++ b/base/plugins.cpp
@@ -133,9 +133,6 @@ public:
#if PLUGIN_ENABLED_STATIC(LURE)
LINK_PLUGIN(LURE)
#endif
- #if PLUGIN_ENABLED_STATIC(M4)
- LINK_PLUGIN(M4)
- #endif
#if PLUGIN_ENABLED_STATIC(MADE)
LINK_PLUGIN(MADE)
#endif
@@ -178,6 +175,9 @@ public:
#if PLUGIN_ENABLED_STATIC(TINSEL)
LINK_PLUGIN(TINSEL)
#endif
+ #if PLUGIN_ENABLED_STATIC(TOLTECS)
+ LINK_PLUGIN(TOLTECS)
+ #endif
#if PLUGIN_ENABLED_STATIC(TOON)
LINK_PLUGIN(TOON)
#endif
@@ -358,8 +358,6 @@ void PluginManagerUncached::init() {
unloadAllPlugins();
_allEnginePlugins.clear();
- // Resize our pluginsInMem list to prevent fragmentation
- _pluginsInMem[PLUGIN_TYPE_ENGINE].resize(2);
unloadPluginsExcept(PLUGIN_TYPE_ENGINE, NULL, false); // empty the engine plugins
for (ProviderList::iterator pp = _providers.begin();
diff --git a/base/version.cpp b/base/version.cpp
index a068f2b141..7943552418 100644
--- a/base/version.cpp
+++ b/base/version.cpp
@@ -121,4 +121,8 @@ const char *gScummVMFeatures = ""
#ifdef USE_FAAD
"AAC "
#endif
+
+#ifdef USE_FREETYPE2
+ "FreeType2 "
+#endif
;
diff --git a/common/EventDispatcher.cpp b/common/EventDispatcher.cpp
index 4e3f671cfd..4c7286bbb5 100644
--- a/common/EventDispatcher.cpp
+++ b/common/EventDispatcher.cpp
@@ -48,24 +48,16 @@ void EventDispatcher::dispatch() {
dispatchPoll();
for (List<SourceEntry>::iterator i = _sources.begin(); i != _sources.end(); ++i) {
- const bool allowMapping = i->source->allowMapping();
-
while (i->source->pollEvent(event)) {
// We only try to process the events via the setup event mapper, when
// we have a setup mapper and when the event source allows mapping.
- if (_mapper && allowMapping) {
- if (_mapper->notifyEvent(event)) {
- // We allow the event mapper to create multiple events, when
- // eating an event.
- while (_mapper->pollEvent(event))
- dispatchEvent(event);
-
- // Try getting another event from the current EventSource.
- continue;
- }
- }
+ assert(_mapper);
+ List<Event> mappedEvents = _mapper->mapEvent(event, i->source);
- dispatchEvent(event);
+ for (List<Event>::iterator j = mappedEvents.begin(); j != mappedEvents.end(); ++j) {
+ const Event mappedEvent = *j;
+ dispatchEvent(mappedEvent);
+ }
}
}
}
diff --git a/backends/platform/iphone/blit.cpp b/common/EventMapper.cpp
index 58de22bf75..2808a7b5fd 100644
--- a/backends/platform/iphone/blit.cpp
+++ b/common/EventMapper.cpp
@@ -20,29 +20,35 @@
*
*/
-#include "common/scummsys.h"
-#include "blit_arm.h"
-
-void blitLandscapeScreenRect16bpp(uint16 *dst, uint16 *src, int width, int height, int screenWidth, int screenHeight)
-{
- for (int x = width; x > 0; x--) {
- for (int y = height; y > 0; y--) {
- *(dst++) = *src;
- src += screenWidth;
- }
- dst -= screenHeight + height;
- src += 1 - height * screenWidth;
- }
-}
+#include "common/events.h"
-void blitLandscapeScreenRect8bpp(uint16 *dst, byte *src, int width, int height, uint16 *palette, int screenWidth, int screenHeight)
-{
- for (int x = width; x > 0; x--) {
- for (int y = height; y > 0; y--) {
- *(dst++) = palette[*src];
- src += screenWidth;
+namespace Common {
+
+List<Event> DefaultEventMapper::mapEvent(const Event &ev, EventSource *source) {
+ List<Event> events;
+ Event mappedEvent;
+ if (ev.type == EVENT_KEYDOWN) {
+ if (ev.kbd.hasFlags(KBD_CTRL) && ev.kbd.keycode == KEYCODE_F5) {
+ mappedEvent.type = EVENT_MAINMENU;
+ }
+#ifdef ENABLE_VKEYBD
+ else if (ev.kbd.keycode == KEYCODE_F7 && ev.kbd.hasFlags(0)) {
+ mappedEvent.type = EVENT_VIRTUAL_KEYBOARD;
}
- dst -= screenHeight + height;
- src += 1 - height * screenWidth;
+#endif
+#ifdef ENABLE_KEYMAPPER
+ else if (ev.kbd.keycode == KEYCODE_F8 && ev.kbd.hasFlags(0)) {
+ mappedEvent.type = EVENT_KEYMAPPER_REMAP;
+ }
+#endif
}
+
+ // if it didn't get mapped, just pass it through
+ if (mappedEvent.type == EVENT_INVALID)
+ mappedEvent = ev;
+ events.push_back(mappedEvent);
+ return events;
}
+
+
+} // namespace Common
diff --git a/common/algorithm.h b/common/algorithm.h
index e7ccef4840..7a0eed89ce 100644
--- a/common/algorithm.h
+++ b/common/algorithm.h
@@ -73,25 +73,25 @@ Out copy_if(In first, In last, Out dst, Op op) {
return dst;
}
-// Our 'specialized' 'set_to' template for char, signed char and unsigned char arrays.
+// Our 'specialized' 'fill' template for char, signed char and unsigned char arrays.
// Since C++ doesn't support partial specialized template functions (currently) we
// are going this way...
// With this we assure the usage of memset for those, which should be
-// faster than a simple loop like for the generic 'set_to'.
+// faster than a simple loop like for the generic 'fill'.
template<class Value>
-signed char *set_to(signed char *first, signed char *last, Value val) {
+signed char *fill(signed char *first, signed char *last, Value val) {
memset(first, (val & 0xFF), last - first);
return last;
}
template<class Value>
-unsigned char *set_to(unsigned char *first, unsigned char *last, Value val) {
+unsigned char *fill(unsigned char *first, unsigned char *last, Value val) {
memset(first, (val & 0xFF), last - first);
return last;
}
template<class Value>
-char *set_to(char *first, char *last, Value val) {
+char *fill(char *first, char *last, Value val) {
memset(first, (val & 0xFF), last - first);
return last;
}
@@ -100,7 +100,7 @@ char *set_to(char *first, char *last, Value val) {
* Sets all elements in the range [first, last) to val.
*/
template<class In, class Value>
-In set_to(In first, In last, Value val) {
+In fill(In first, In last, const Value &val) {
while (first != last)
*first++ = val;
return first;
diff --git a/common/archive.cpp b/common/archive.cpp
index 954de8bcaa..1323f14805 100644
--- a/common/archive.cpp
+++ b/common/archive.cpp
@@ -27,7 +27,7 @@
namespace Common {
-GenericArchiveMember::GenericArchiveMember(String name, Archive *parent)
+GenericArchiveMember::GenericArchiveMember(const String &name, const Archive *parent)
: _parent(parent), _name(name) {
}
@@ -40,14 +40,14 @@ SeekableReadStream *GenericArchiveMember::createReadStream() const {
}
-int Archive::listMatchingMembers(ArchiveMemberList &list, const String &pattern) {
+int Archive::listMatchingMembers(ArchiveMemberList &list, const String &pattern) const {
// Get all "names" (TODO: "files" ?)
ArchiveMemberList allNames;
listMembers(allNames);
int matches = 0;
- ArchiveMemberList::iterator it = allNames.begin();
+ ArchiveMemberList::const_iterator it = allNames.begin();
for ( ; it != allNames.end(); ++it) {
// TODO: We match case-insenstivie for now, our API does not define whether that's ok or not though...
// For our use case case-insensitive is probably what we want to have though.
@@ -206,11 +206,11 @@ void SearchSet::setPriority(const String &name, int priority) {
insert(node);
}
-bool SearchSet::hasFile(const String &name) {
+bool SearchSet::hasFile(const String &name) const {
if (name.empty())
return false;
- ArchiveNodeList::iterator it = _list.begin();
+ ArchiveNodeList::const_iterator it = _list.begin();
for ( ; it != _list.end(); ++it) {
if (it->_arc->hasFile(name))
return true;
@@ -219,31 +219,31 @@ bool SearchSet::hasFile(const String &name) {
return false;
}
-int SearchSet::listMatchingMembers(ArchiveMemberList &list, const String &pattern) {
+int SearchSet::listMatchingMembers(ArchiveMemberList &list, const String &pattern) const {
int matches = 0;
- ArchiveNodeList::iterator it = _list.begin();
+ ArchiveNodeList::const_iterator it = _list.begin();
for ( ; it != _list.end(); ++it)
matches += it->_arc->listMatchingMembers(list, pattern);
return matches;
}
-int SearchSet::listMembers(ArchiveMemberList &list) {
+int SearchSet::listMembers(ArchiveMemberList &list) const {
int matches = 0;
- ArchiveNodeList::iterator it = _list.begin();
+ ArchiveNodeList::const_iterator it = _list.begin();
for ( ; it != _list.end(); ++it)
matches += it->_arc->listMembers(list);
return matches;
}
-ArchiveMemberPtr SearchSet::getMember(const String &name) {
+const ArchiveMemberPtr SearchSet::getMember(const String &name) const {
if (name.empty())
return ArchiveMemberPtr();
- ArchiveNodeList::iterator it = _list.begin();
+ ArchiveNodeList::const_iterator it = _list.begin();
for ( ; it != _list.end(); ++it) {
if (it->_arc->hasFile(name))
return it->_arc->getMember(name);
diff --git a/common/archive.h b/common/archive.h
index c8e78f9bc8..ffd86d786d 100644
--- a/common/archive.h
+++ b/common/archive.h
@@ -65,10 +65,10 @@ class Archive;
* is destroyed.
*/
class GenericArchiveMember : public ArchiveMember {
- Archive *_parent;
- String _name;
+ const Archive *_parent;
+ const String _name;
public:
- GenericArchiveMember(String name, Archive *parent);
+ GenericArchiveMember(const String &name, const Archive *parent);
String getName() const;
SeekableReadStream *createReadStream() const;
};
@@ -88,7 +88,7 @@ public:
* Patterns are not allowed, as this is meant to be a quick File::exists()
* replacement.
*/
- virtual bool hasFile(const String &name) = 0;
+ virtual bool hasFile(const String &name) const = 0;
/**
* Add all members of the Archive matching the specified pattern to list.
@@ -96,7 +96,7 @@ public:
*
* @return the number of members added to list
*/
- virtual int listMatchingMembers(ArchiveMemberList &list, const String &pattern);
+ virtual int listMatchingMembers(ArchiveMemberList &list, const String &pattern) const;
/**
* Add all members of the Archive to list.
@@ -104,12 +104,12 @@ public:
*
* @return the number of names added to list
*/
- virtual int listMembers(ArchiveMemberList &list) = 0;
+ virtual int listMembers(ArchiveMemberList &list) const = 0;
/**
* Returns a ArchiveMember representation of the given file.
*/
- virtual ArchiveMemberPtr getMember(const String &name) = 0;
+ virtual const ArchiveMemberPtr getMember(const String &name) const = 0;
/**
* Create a stream bound to a member with the specified name in the
@@ -230,11 +230,11 @@ public:
*/
void setPriority(const String& name, int priority);
- virtual bool hasFile(const String &name);
- virtual int listMatchingMembers(ArchiveMemberList &list, const String &pattern);
- virtual int listMembers(ArchiveMemberList &list);
+ virtual bool hasFile(const String &name) const;
+ virtual int listMatchingMembers(ArchiveMemberList &list, const String &pattern) const;
+ virtual int listMembers(ArchiveMemberList &list) const;
- virtual ArchiveMemberPtr getMember(const String &name);
+ virtual const ArchiveMemberPtr getMember(const String &name) const;
/**
* Implements createReadStreamForMember from Archive base class. The current policy is
diff --git a/common/array.h b/common/array.h
index 18cecfb98f..a2c3023362 100644
--- a/common/array.h
+++ b/common/array.h
@@ -24,7 +24,8 @@
#include "common/scummsys.h"
#include "common/algorithm.h"
-#include "common/textconsole.h" // For error()
+#include "common/textconsole.h" // For error()
+#include "common/memory.h"
namespace Common {
@@ -37,44 +38,30 @@ namespace Common {
* proportional to the number of elements in the array.
*
* The container class closest to this in the C++ standard library is
- * std::vector. However, there are some differences. The most important one is
- * that std::vector has a far more sophisticated (and complicated) memory
- * management scheme. There, only elements that 'live' are actually constructed
- * (i.e., have their constructor called), and objects that are removed are
- * immediately destructed (have their destructor called).
- * With Array, this is not the case; instead, it simply uses new[] and
- * delete[] to allocate whole blocks of objects, possibly more than are
- * currently 'alive'. This simplifies memory management, but may have
- * undesirable side effects when one wants to use an Array of complex
- * data types.
- *
- * @todo Improve the storage management of this class.
- * In particular, don't use new[] and delete[], but rather
- * construct/destruct objects manually. This way, we can
- * ensure that storage which is not currently used does not
- * correspond to a live active object.
- * (This is only of interest for array of non-POD objects).
+ * std::vector. However, there are some differences.
*/
template<class T>
class Array {
-protected:
- uint _capacity;
- uint _size;
- T *_storage;
-
public:
typedef T *iterator;
typedef const T *const_iterator;
typedef T value_type;
+ typedef uint size_type;
+
+protected:
+ size_type _capacity;
+ size_type _size;
+ T *_storage;
+
public:
Array() : _capacity(0), _size(0), _storage(0) {}
Array(const Array<T> &array) : _capacity(array._size), _size(array._size), _storage(0) {
if (array._storage) {
allocCapacity(_size);
- copy(array._storage, array._storage + _size, _storage);
+ uninitialized_copy(array._storage, array._storage + _size, _storage);
}
}
@@ -82,14 +69,14 @@ public:
* Construct an array by copying data from a regular array.
*/
template<class T2>
- Array(const T2 *data, int n) {
+ Array(const T2 *data, size_type n) {
_size = n;
allocCapacity(n);
- copy(data, data + _size, _storage);
+ uninitialized_copy(data, data + _size, _storage);
}
~Array() {
- delete[] _storage;
+ freeStorage(_storage, _size);
_storage = 0;
_capacity = _size = 0;
}
@@ -97,14 +84,14 @@ public:
/** Appends element to the end of the array. */
void push_back(const T &element) {
if (_size + 1 <= _capacity)
- _storage[_size++] = element;
+ new ((void *)&_storage[_size++]) T(element);
else
insert_aux(end(), &element, &element + 1);
}
void push_back(const Array<T> &array) {
if (_size + array.size() <= _capacity) {
- copy(array.begin(), array.end(), end());
+ uninitialized_copy(array.begin(), array.end(), end());
_size += array.size();
} else
insert_aux(end(), array.begin(), array.end());
@@ -114,6 +101,8 @@ public:
void pop_back() {
assert(_size > 0);
_size--;
+ // We also need to destroy the last object properly here.
+ _storage[_size].~T();
}
/** Returns a reference to the first element of the array. */
@@ -141,55 +130,57 @@ public:
}
- void insert_at(int idx, const T &element) {
- assert(idx >= 0 && (uint)idx <= _size);
+ void insert_at(size_type idx, const T &element) {
+ assert(idx <= _size);
insert_aux(_storage + idx, &element, &element + 1);
}
- void insert_at(int idx, const Array<T> &array) {
- assert(idx >= 0 && (uint)idx <= _size);
+ void insert_at(size_type idx, const Array<T> &array) {
+ assert(idx <= _size);
insert_aux(_storage + idx, array.begin(), array.end());
}
- T remove_at(int idx) {
- assert(idx >= 0 && (uint)idx < _size);
+ T remove_at(size_type idx) {
+ assert(idx < _size);
T tmp = _storage[idx];
copy(_storage + idx + 1, _storage + _size, _storage + idx);
_size--;
+ // We also need to destroy the last object properly here.
+ _storage[_size].~T();
return tmp;
}
// TODO: insert, remove, ...
- T& operator[](int idx) {
- assert(idx >= 0 && (uint)idx < _size);
+ T &operator[](size_type idx) {
+ assert(idx < _size);
return _storage[idx];
}
- const T& operator[](int idx) const {
- assert(idx >= 0 && (uint)idx < _size);
+ const T &operator[](size_type idx) const {
+ assert(idx < _size);
return _storage[idx];
}
- Array<T>& operator=(const Array<T> &array) {
+ Array<T> &operator=(const Array<T> &array) {
if (this == &array)
return *this;
- delete[] _storage;
+ freeStorage(_storage, _size);
_size = array._size;
allocCapacity(_size);
- copy(array._storage, array._storage + _size, _storage);
+ uninitialized_copy(array._storage, array._storage + _size, _storage);
return *this;
}
- uint size() const {
+ size_type size() const {
return _size;
}
void clear() {
- delete[] _storage;
+ freeStorage(_storage, _size);
_storage = 0;
_size = 0;
_capacity = 0;
@@ -204,34 +195,34 @@ public:
return true;
if (_size != other._size)
return false;
- for (uint i = 0; i < _size; ++i) {
+ for (size_type i = 0; i < _size; ++i) {
if (_storage[i] != other._storage[i])
return false;
}
return true;
}
+
bool operator!=(const Array<T> &other) const {
return !(*this == other);
}
-
- iterator begin() {
+ iterator begin() {
return _storage;
}
- iterator end() {
+ iterator end() {
return _storage + _size;
}
- const_iterator begin() const {
+ const_iterator begin() const {
return _storage;
}
- const_iterator end() const {
+ const_iterator end() const {
return _storage + _size;
}
- void reserve(uint newCapacity) {
+ void reserve(size_type newCapacity) {
if (newCapacity <= _capacity)
return;
@@ -240,15 +231,15 @@ public:
if (oldStorage) {
// Copy old data
- copy(oldStorage, oldStorage + _size, _storage);
- delete[] oldStorage;
+ uninitialized_copy(oldStorage, oldStorage + _size, _storage);
+ freeStorage(oldStorage, _size);
}
}
- void resize(uint newSize) {
+ void resize(size_type newSize) {
reserve(newSize);
- for (uint i = _size; i < newSize; ++i)
- _storage[i] = T();
+ for (size_type i = _size; i < newSize; ++i)
+ new ((void *)&_storage[i]) T();
_size = newSize;
}
@@ -260,26 +251,32 @@ public:
}
protected:
- static uint roundUpCapacity(uint capacity) {
+ static size_type roundUpCapacity(size_type capacity) {
// Round up capacity to the next power of 2;
// we use a minimal capacity of 8.
- uint capa = 8;
+ size_type capa = 8;
while (capa < capacity)
capa <<= 1;
return capa;
}
- void allocCapacity(uint capacity) {
+ void allocCapacity(size_type capacity) {
_capacity = capacity;
if (capacity) {
- _storage = new T[capacity];
+ _storage = (T *)malloc(sizeof(T) * capacity);
if (!_storage)
- ::error("Common::Array: failure to allocate %u bytes", capacity * (uint)sizeof(T));
+ ::error("Common::Array: failure to allocate %u bytes", capacity * (size_type)sizeof(T));
} else {
_storage = 0;
}
}
+ void freeStorage(T *storage, const size_type elements) {
+ for (size_type i = 0; i < elements; ++i)
+ storage[i].~T();
+ free(storage);
+ }
+
/**
* Insert a range of elements coming from this or another array.
* Unlike std::vector::insert, this method does not accept
@@ -296,32 +293,52 @@ protected:
iterator insert_aux(iterator pos, const_iterator first, const_iterator last) {
assert(_storage <= pos && pos <= _storage + _size);
assert(first <= last);
- const uint n = last - first;
+ const size_type n = last - first;
if (n) {
- const uint idx = pos - _storage;
- T *oldStorage = _storage;
- if (_size + n > _capacity || (_storage <= first && first <= _storage + _size) ) {
- // If there is not enough space, allocate more and
- // copy old elements over.
+ const size_type idx = pos - _storage;
+ if (_size + n > _capacity || (_storage <= first && first <= _storage + _size)) {
+ T *const oldStorage = _storage;
+
+ // If there is not enough space, allocate more.
// Likewise, if this is a self-insert, we allocate new
- // storage to avoid conflicts. This is not the most efficient
- // way to ensure that, but probably the simplest on.
+ // storage to avoid conflicts.
allocCapacity(roundUpCapacity(_size + n));
- copy(oldStorage, oldStorage + idx, _storage);
- pos = _storage + idx;
- }
-
- // Make room for the new elements by shifting back
- // existing ones.
- copy_backward(oldStorage + idx, oldStorage + _size, _storage + _size + n);
- // Insert the new elements.
- copy(first, last, pos);
+ // Copy the data from the old storage till the position where
+ // we insert new data
+ uninitialized_copy(oldStorage, oldStorage + idx, _storage);
+ // Copy the data we insert
+ uninitialized_copy(first, last, _storage + idx);
+ // Afterwards copy the old data from the position where we
+ // insert.
+ uninitialized_copy(oldStorage + idx, oldStorage + _size, _storage + idx + n);
+
+ freeStorage(oldStorage, _size);
+ } else if (idx + n <= _size) {
+ // Make room for the new elements by shifting back
+ // existing ones.
+ // 1. Move a part of the data to the uninitialized area
+ uninitialized_copy(_storage + _size - n, _storage + _size, _storage + _size);
+ // 2. Move a part of the data to the initialized area
+ copy_backward(pos, _storage + _size - n, _storage + _size);
+
+ // Insert the new elements.
+ copy(first, last, pos);
+ } else {
+ // Copy the old data from the position till the end to the new
+ // place.
+ uninitialized_copy(pos, _storage + _size, _storage + idx + n);
+
+ // Copy a part of the new data to the position inside the
+ // initialized space.
+ copy(first, first + (_size - idx), pos);
+
+ // Copy a part of the new data to the position inside the
+ // uninitialized space.
+ uninitialized_copy(first + (_size - idx), last, _storage + _size);
+ }
// Finally, update the internal state
- if (_storage != oldStorage) {
- delete[] oldStorage;
- }
_size += n;
}
return pos;
diff --git a/common/config-file.cpp b/common/config-file.cpp
index 81e0ae6b45..4224d7491d 100644
--- a/common/config-file.cpp
+++ b/common/config-file.cpp
@@ -30,7 +30,7 @@ namespace Common {
bool ConfigFile::isValidName(const String &name) {
const char *p = name.c_str();
- while (*p && (isalnum(static_cast<unsigned char>(*p)) || *p == '-' || *p == '_' || *p == '.'))
+ while (*p && (isAlnum(*p) || *p == '-' || *p == '_' || *p == '.'))
p++;
return *p == 0;
}
@@ -108,7 +108,7 @@ bool ConfigFile::loadFromStream(SeekableReadStream &stream) {
// is, verify that it only consists of alphanumerics,
// periods, dashes and underscores). Mohawk Living Books games
// can have periods in their section names.
- while (*p && (isalnum(static_cast<unsigned char>(*p)) || *p == '-' || *p == '_' || *p == '.'))
+ while (*p && (isAlnum(*p) || *p == '-' || *p == '_' || *p == '.'))
p++;
if (*p == '\0')
@@ -131,7 +131,7 @@ bool ConfigFile::loadFromStream(SeekableReadStream &stream) {
// Skip leading whitespaces
const char *t = line.c_str();
- while (isspace(static_cast<unsigned char>(*t)))
+ while (isSpace(*t))
t++;
// Skip empty lines / lines with only whitespace
diff --git a/common/config-manager.cpp b/common/config-manager.cpp
index c62dee8bea..aaa812bc94 100644
--- a/common/config-manager.cpp
+++ b/common/config-manager.cpp
@@ -29,7 +29,7 @@
static bool isValidDomainName(const Common::String &domName) {
const char *p = domName.c_str();
- while (*p && (isalnum(static_cast<unsigned char>(*p)) || *p == '-' || *p == '_'))
+ while (*p && (Common::isAlnum(*p) || *p == '-' || *p == '_'))
p++;
return *p == 0;
}
@@ -187,7 +187,7 @@ void ConfigManager::loadFromStream(SeekableReadStream &stream) {
// Get the domain name, and check whether it's valid (that
// is, verify that it only consists of alphanumerics,
// dashes and underscores).
- while (*p && (isalnum(static_cast<unsigned char>(*p)) || *p == '-' || *p == '_'))
+ while (*p && (isAlnum(*p) || *p == '-' || *p == '_'))
p++;
if (*p == '\0')
@@ -205,7 +205,7 @@ void ConfigManager::loadFromStream(SeekableReadStream &stream) {
// Skip leading whitespaces
const char *t = line.c_str();
- while (isspace(static_cast<unsigned char>(*t)))
+ while (isSpace(*t))
t++;
// Skip empty lines / lines with only whitespace
diff --git a/common/events.h b/common/events.h
index f5ace7481b..4efdd67b91 100644
--- a/common/events.h
+++ b/common/events.h
@@ -73,8 +73,21 @@ enum EventType {
* An associated enumerated type can accomplish this.
**/
EVENT_PREDICTIVE_DIALOG = 12
+
+#ifdef ENABLE_KEYMAPPER
+ ,
+ // IMPORTANT NOTE: This is part of the WIP Keymapper. If you plan to use
+ // this, please talk to tsoliman and/or LordHoto.
+ EVENT_CUSTOM_BACKEND_ACTION = 18,
+ EVENT_KEYMAPPER_REMAP = 19
+#endif
+#ifdef ENABLE_VKEYBD
+ ,
+ EVENT_VIRTUAL_KEYBOARD = 20
+#endif
};
+typedef uint32 CustomEventType;
/**
* Data structure for an event. A pointer to an instance of Event
* can be passed to pollEvent.
@@ -99,7 +112,17 @@ struct Event {
*/
Point mouse;
- Event() : type(EVENT_INVALID), synthetic(false) {}
+#ifdef ENABLE_KEYMAPPER
+ // IMPORTANT NOTE: This is part of the WIP Keymapper. If you plan to use
+ // this, please talk to tsoliman and/or LordHoto.
+ CustomEventType customType;
+#endif
+
+ Event() : type(EVENT_INVALID), synthetic(false) {
+#ifdef ENABLE_KEYMAPPER
+ customType = 0;
+#endif
+ }
};
/**
@@ -175,7 +198,7 @@ public:
*
* An observer is supposed to eat the event, with returning true, when
* it wants to prevent other observers from receiving the event.
- * An usage example here is the keymapper:
+ * A usage example here is the keymapper:
* If it processes an Event, it should 'eat' it and create a new
* event, which the EventDispatcher will then catch.
*
@@ -199,10 +222,20 @@ public:
*
* An example for this is the Keymapper.
*/
-class EventMapper : public EventSource, public EventObserver {
+class EventMapper {
+public:
+ virtual ~EventMapper() {}
+
+ /**
+ * Map an incoming event to one or more action events
+ */
+ virtual List<Event> mapEvent(const Event &ev, EventSource *source) = 0;
+};
+
+class DefaultEventMapper : public EventMapper {
public:
- /** For event mappers resulting events should never be mapped */
- bool allowMapping() const { return false; }
+ // EventMapper interface
+ virtual List<Event> mapEvent(const Event &ev, EventSource *source);
};
/**
diff --git a/common/fft.cpp b/common/fft.cpp
index 5852698b61..034570964f 100644
--- a/common/fft.cpp
+++ b/common/fft.cpp
@@ -231,7 +231,7 @@ DECL_FFT(14, 16384, 8192, 4096)
DECL_FFT(15, 32768, 16384, 8192)
DECL_FFT(16, 65536, 32768, 16384)
-static void (* const fft_dispatch[])(Complex*) = {
+static void (* const fft_dispatch[])(Complex *) = {
fft4, fft8, fft16, fft32, fft64, fft128, fft256, fft512, fft1024,
fft2048, fft4096, fft8192, fft16384, fft32768, fft65536,
};
diff --git a/common/forbidden.h b/common/forbidden.h
index 95c1a47d65..eec80bba59 100644
--- a/common/forbidden.h
+++ b/common/forbidden.h
@@ -182,7 +182,8 @@
#define putchar(a) FORBIDDEN_SYMBOL_REPLACEMENT
#endif
-
+// mingw-w64 uses [set|long]jmp in system headers
+#ifndef __MINGW64__
#ifndef FORBIDDEN_SYMBOL_EXCEPTION_setjmp
#undef setjmp
#define setjmp(a) FORBIDDEN_SYMBOL_REPLACEMENT
@@ -192,6 +193,7 @@
#undef longjmp
#define longjmp(a,b) FORBIDDEN_SYMBOL_REPLACEMENT
#endif
+#endif // __MINGW64__
#ifndef FORBIDDEN_SYMBOL_EXCEPTION_system
#undef system
@@ -315,6 +317,49 @@
#endif // FORBIDDEN_SYMBOL_EXCEPTION_unistd_h
+
+//
+// Disable various symbols from ctype.h
+//
+#ifndef FORBIDDEN_SYMBOL_EXCEPTION_ctype_h
+
+ #ifndef FORBIDDEN_SYMBOL_EXCEPTION_isalnum
+ #undef isalnum
+ #define isalnum(a) FORBIDDEN_SYMBOL_REPLACEMENT
+ #endif
+
+ #ifndef FORBIDDEN_SYMBOL_EXCEPTION_isalpha
+ #undef isalpha
+ #define isalpha(a) FORBIDDEN_SYMBOL_REPLACEMENT
+ #endif
+
+ #ifndef FORBIDDEN_SYMBOL_EXCEPTION_isdigit
+ #undef isdigit
+ #define isdigit(a) FORBIDDEN_SYMBOL_REPLACEMENT
+ #endif
+
+ #ifndef FORBIDDEN_SYMBOL_EXCEPTION_isnumber
+ #undef isnumber
+ #define isnumber(a) FORBIDDEN_SYMBOL_REPLACEMENT
+ #endif
+
+ #ifndef FORBIDDEN_SYMBOL_EXCEPTION_islower
+ #undef islower
+ #define islower(a) FORBIDDEN_SYMBOL_REPLACEMENT
+ #endif
+
+ #ifndef FORBIDDEN_SYMBOL_EXCEPTION_isspace
+ #undef isspace
+ #define isspace(a) FORBIDDEN_SYMBOL_REPLACEMENT
+ #endif
+
+ #ifndef FORBIDDEN_SYMBOL_EXCEPTION_isupper
+ #undef isupper
+ #define isupper(a) FORBIDDEN_SYMBOL_REPLACEMENT
+ #endif
+
+#endif // FORBIDDEN_SYMBOL_EXCEPTION_ctype_h
+
#ifndef FORBIDDEN_SYMBOL_EXCEPTION_mkdir
#undef mkdir
#define mkdir(a,b) FORBIDDEN_SYMBOL_REPLACEMENT
diff --git a/common/fs.cpp b/common/fs.cpp
index 4b56cc4594..0143c936d4 100644
--- a/common/fs.cpp
+++ b/common/fs.cpp
@@ -130,10 +130,10 @@ SeekableReadStream *FSNode::createReadStream() const {
if (!_realNode->exists()) {
warning("FSNode::createReadStream: '%s' does not exist", getName().c_str());
- return false;
+ return 0;
} else if (_realNode->isDirectory()) {
warning("FSNode::createReadStream: '%s' is a directory", getName().c_str());
- return false;
+ return 0;
}
return _realNode->createReadStream();
@@ -197,7 +197,7 @@ FSNode *FSDirectory::lookupCache(NodeCache &cache, const String &name) const {
return 0;
}
-bool FSDirectory::hasFile(const String &name) {
+bool FSDirectory::hasFile(const String &name) const {
if (name.empty() || !_node.isDirectory())
return false;
@@ -205,7 +205,7 @@ bool FSDirectory::hasFile(const String &name) {
return node && node->exists();
}
-ArchiveMemberPtr FSDirectory::getMember(const String &name) {
+const ArchiveMemberPtr FSDirectory::getMember(const String &name) const {
if (name.empty() || !_node.isDirectory())
return ArchiveMemberPtr();
@@ -295,7 +295,7 @@ void FSDirectory::ensureCached() const {
_cached = true;
}
-int FSDirectory::listMatchingMembers(ArchiveMemberList &list, const String &pattern) {
+int FSDirectory::listMatchingMembers(ArchiveMemberList &list, const String &pattern) const {
if (!_node.isDirectory())
return 0;
@@ -308,7 +308,7 @@ int FSDirectory::listMatchingMembers(ArchiveMemberList &list, const String &patt
lowercasePattern.toLowercase();
int matches = 0;
- NodeCache::iterator it = _fileCache.begin();
+ NodeCache::const_iterator it = _fileCache.begin();
for ( ; it != _fileCache.end(); ++it) {
if (it->_key.matchString(lowercasePattern, false, true)) {
list.push_back(ArchiveMemberPtr(new FSNode(it->_value)));
@@ -318,7 +318,7 @@ int FSDirectory::listMatchingMembers(ArchiveMemberList &list, const String &patt
return matches;
}
-int FSDirectory::listMembers(ArchiveMemberList &list) {
+int FSDirectory::listMembers(ArchiveMemberList &list) const {
if (!_node.isDirectory())
return 0;
@@ -326,7 +326,7 @@ int FSDirectory::listMembers(ArchiveMemberList &list) {
ensureCached();
int files = 0;
- for (NodeCache::iterator it = _fileCache.begin(); it != _fileCache.end(); ++it) {
+ for (NodeCache::const_iterator it = _fileCache.begin(); it != _fileCache.end(); ++it) {
list.push_back(ArchiveMemberPtr(new FSNode(it->_value)));
++files;
}
diff --git a/common/fs.h b/common/fs.h
index aeaa14718e..fadd672bb1 100644
--- a/common/fs.h
+++ b/common/fs.h
@@ -318,23 +318,23 @@ public:
* Checks for existence in the cache. A full match of relative path and filename is needed
* for success.
*/
- virtual bool hasFile(const String &name);
+ virtual bool hasFile(const String &name) const;
/**
* Returns a list of matching file names. Pattern can use GLOB wildcards.
*/
- virtual int listMatchingMembers(ArchiveMemberList &list, const String &pattern);
+ virtual int listMatchingMembers(ArchiveMemberList &list, const String &pattern) const;
/**
* Returns a list of all the files in the cache.
*/
- virtual int listMembers(ArchiveMemberList &list);
+ virtual int listMembers(ArchiveMemberList &list) const;
/**
* Get a ArchiveMember representation of the specified file. A full match of relative
* path and filename is needed for success.
*/
- virtual ArchiveMemberPtr getMember(const String &name);
+ virtual const ArchiveMemberPtr getMember(const String &name) const;
/**
* Open the specified file. A full match of relative path and filename is needed
diff --git a/common/gui_options.cpp b/common/gui_options.cpp
new file mode 100644
index 0000000000..5b7d939dc4
--- /dev/null
+++ b/common/gui_options.cpp
@@ -0,0 +1,132 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "common/gui_options.h"
+
+#include "common/config-manager.h"
+#include "common/str.h"
+
+namespace Common {
+
+const struct GameOpt {
+ const char *option;
+ const char *desc;
+} g_gameOptions[] = {
+ { GUIO_NOSUBTITLES, "sndNoSubs" },
+ { GUIO_NOMUSIC, "sndNoMusic" },
+ { GUIO_NOSPEECH, "sndNoSpeech" },
+ { GUIO_NOSFX, "sndNoSFX" },
+ { GUIO_NOMIDI, "sndNoMIDI" },
+
+ { GUIO_NOLAUNCHLOAD, "launchNoLoad" },
+
+ { GUIO_MIDIPCSPK, "midiPCSpk" },
+ { GUIO_MIDICMS, "midiCMS" },
+ { GUIO_MIDIPCJR, "midiPCJr" },
+ { GUIO_MIDIADLIB, "midiAdLib" },
+ { GUIO_MIDIC64, "midiC64" },
+ { GUIO_MIDIAMIGA, "midiAmiga" },
+ { GUIO_MIDIAPPLEIIGS,"midiAppleIIgs" },
+ { GUIO_MIDITOWNS, "midiTowns" },
+ { GUIO_MIDIPC98, "midiPC98" },
+ { GUIO_MIDIMT32, "midiMt32" },
+ { GUIO_MIDIGM, "midiGM" },
+
+ { GUIO_NOASPECT, "noAspect" },
+ { GUIO_EGAUNDITHER, "egaUndither" },
+
+ { GUIO_RENDERHERCGREEN, "hercGreen" },
+ { GUIO_RENDERHERCAMBER, "hercAmber" },
+ { GUIO_RENDERCGA, "cga" },
+ { GUIO_RENDEREGA, "ega" },
+ { GUIO_RENDERVGA, "vga" },
+ { GUIO_RENDERAMIGA, "amiga" },
+ { GUIO_RENDERFMTOWNS, "fmtowns" },
+ { GUIO_RENDERPC9821, "pc9821" },
+ { GUIO_RENDERPC9801, "pc9801" },
+
+ { GUIO_NONE, 0 }
+};
+
+bool checkGameGUIOption(const String &option, const String &str) {
+ for (int i = 0; g_gameOptions[i].desc; i++) {
+ if (option.contains(g_gameOptions[i].option)) {
+ if (str.contains(g_gameOptions[i].desc))
+ return true;
+ else
+ return false;
+ }
+ }
+ return false;
+}
+
+bool checkGameGUIOptionLanguage(Language lang, const String &str) {
+ if (!str.contains("lang_")) // If no languages are specified
+ return true;
+
+ if (str.contains(getGameGUIOptionsDescriptionLanguage(lang)))
+ return true;
+
+ return false;
+}
+
+const String getGameGUIOptionsDescriptionLanguage(Language lang) {
+ if (lang == UNK_LANG)
+ return "";
+
+ return String("lang_") + getLanguageDescription(lang);
+}
+
+String parseGameGUIOptions(const String &str) {
+ String res;
+
+ for (int i = 0; g_gameOptions[i].desc; i++)
+ if (str.contains(g_gameOptions[i].desc))
+ res += g_gameOptions[i].option;
+
+ return res;
+}
+
+const String getGameGUIOptionsDescription(const String &options) {
+ String res;
+
+ for (int i = 0; g_gameOptions[i].desc; i++)
+ if (options.contains(g_gameOptions[i].option[0]))
+ res += String(g_gameOptions[i].desc) + " ";
+
+ res.trim();
+
+ return res;
+}
+
+void updateGameGUIOptions(const String &options, const String &langOption) {
+ const String newOptionString = getGameGUIOptionsDescription(options) + " " + langOption;
+
+ if ((!options.empty() && !ConfMan.hasKey("guioptions")) ||
+ (ConfMan.hasKey("guioptions") && ConfMan.get("guioptions") != newOptionString)) {
+ ConfMan.set("guioptions", newOptionString);
+ ConfMan.flushToDisk();
+ }
+}
+
+
+} // End of namespace Common
diff --git a/common/gui_options.h b/common/gui_options.h
new file mode 100644
index 0000000000..5649f1103d
--- /dev/null
+++ b/common/gui_options.h
@@ -0,0 +1,88 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef COMMON_GUI_OPTIONS_H
+#define COMMON_GUI_OPTIONS_H
+
+#include "common/language.h"
+
+#define GUIO_NONE "\000"
+#define GUIO_NOSUBTITLES "\001"
+#define GUIO_NOMUSIC "\002"
+#define GUIO_NOSPEECH "\003"
+#define GUIO_NOSFX "\004"
+#define GUIO_NOMIDI "\005"
+#define GUIO_NOLAUNCHLOAD "\006"
+
+#define GUIO_MIDIPCSPK "\007"
+#define GUIO_MIDICMS "\010"
+#define GUIO_MIDIPCJR "\011"
+#define GUIO_MIDIADLIB "\012"
+#define GUIO_MIDIC64 "\013"
+#define GUIO_MIDIAMIGA "\014"
+#define GUIO_MIDIAPPLEIIGS "\015"
+#define GUIO_MIDITOWNS "\016"
+#define GUIO_MIDIPC98 "\017"
+#define GUIO_MIDIMT32 "\020"
+#define GUIO_MIDIGM "\021"
+
+#define GUIO_NOASPECT "\022"
+#define GUIO_EGAUNDITHER "\023"
+
+#define GUIO_RENDERHERCGREEN "\030"
+#define GUIO_RENDERHERCAMBER "\031"
+#define GUIO_RENDERCGA "\032"
+#define GUIO_RENDEREGA "\033"
+#define GUIO_RENDERVGA "\034"
+#define GUIO_RENDERAMIGA "\035"
+#define GUIO_RENDERFMTOWNS "\036"
+#define GUIO_RENDERPC9821 "\037"
+#define GUIO_RENDERPC9801 "\040"
+
+#define GUIO0() (GUIO_NONE)
+#define GUIO1(a) (a)
+#define GUIO2(a,b) (a b)
+#define GUIO3(a,b,c) (a b c)
+#define GUIO4(a,b,c,d) (a b c d)
+#define GUIO5(a,b,c,d,e) (a b c d e)
+#define GUIO6(a,b,c,d,e,f) (a b c d e f)
+
+namespace Common {
+
+
+bool checkGameGUIOption(const String &option, const String &str);
+bool checkGameGUIOptionLanguage(Common::Language lang, const String &str);
+String parseGameGUIOptions(const String &str);
+const String getGameGUIOptionsDescription(const String &options);
+const String getGameGUIOptionsDescriptionLanguage(Common::Language lang);
+
+/**
+ * Updates the GUI options of the current config manager
+ * domain, when they differ to the ones passed as
+ * parameter.
+ */
+void updateGameGUIOptions(const String &options, const String &langOption);
+
+
+} // End of namespace Common
+
+#endif
diff --git a/common/hash-str.h b/common/hash-str.h
index 1b8a57827a..08f0558bfd 100644
--- a/common/hash-str.h
+++ b/common/hash-str.h
@@ -60,14 +60,14 @@ struct IgnoreCase_Hash {
// case insensitve hashing, then only because one wants to use
// IgnoreCase_EqualTo, and then one has to specify a custom
// hash anyway.
-template <>
+template<>
struct Hash<String> {
uint operator()(const String& s) const {
return hashit(s.c_str());
}
};
-template <>
+template<>
struct Hash<const char *> {
uint operator()(const char *s) const {
return hashit(s);
diff --git a/common/hashmap.h b/common/hashmap.h
index 347ac1fd25..7cf54997e8 100644
--- a/common/hashmap.h
+++ b/common/hashmap.h
@@ -67,7 +67,7 @@ template<class T> class IteratorImpl;
/**
* HashMap<Key,Val> maps objects of type Key to objects of type Val.
- * For each used Key type, we need an "uint hashit(Key,uint)" function
+ * For each used Key type, we need an "size_type hashit(Key,size_type)" function
* that computes a hash for the given Key object and returns it as an
* an integer from 0 to hashsize-1, and also an "equality functor".
* that returns true if if its two arguments are to be considered
@@ -80,6 +80,9 @@ template<class T> class IteratorImpl;
*/
template<class Key, class Val, class HashFunc = Hash<Key>, class EqualFunc = EqualTo<Key> >
class HashMap {
+public:
+ typedef uint size_type;
+
private:
typedef HashMap<Key, Val, HashFunc, EqualFunc> HM_t;
@@ -111,9 +114,9 @@ private:
#endif
Node **_storage; ///< hashtable of size arrsize.
- uint _mask; ///< Capacity of the HashMap minus one; must be a power of two of minus one
- uint _size;
- uint _deleted; ///< Number of deleted elements (_dummyNodes)
+ size_type _mask; ///< Capacity of the HashMap minus one; must be a power of two of minus one
+ size_type _size;
+ size_type _deleted; ///< Number of deleted elements (_dummyNodes)
HashFunc _hash;
EqualFunc _equal;
@@ -146,9 +149,9 @@ private:
}
void assign(const HM_t &map);
- uint lookup(const Key &key) const;
- uint lookupAndCreateIfMissing(const Key &key);
- void expandStorage(uint newCapacity);
+ size_type lookup(const Key &key) const;
+ size_type lookupAndCreateIfMissing(const Key &key);
+ void expandStorage(size_type newCapacity);
#if !defined(__sgi) || defined(__GNUC__)
template<class T> friend class IteratorImpl;
@@ -168,11 +171,11 @@ private:
protected:
typedef const HashMap hashmap_t;
- uint _idx;
+ size_type _idx;
hashmap_t *_hashmap;
protected:
- IteratorImpl(uint idx, hashmap_t *hashmap) : _idx(idx), _hashmap(hashmap) {}
+ IteratorImpl(size_type idx, hashmap_t *hashmap) : _idx(idx), _hashmap(hashmap) {}
NodeType *deref() const {
assert(_hashmap != 0);
@@ -200,7 +203,7 @@ private:
_idx++;
} while (_idx <= _hashmap->_mask && (_hashmap->_storage[_idx] == 0 || _hashmap->_storage[_idx] == HASHMAP_DUMMY_NODE));
if (_idx > _hashmap->_mask)
- _idx = (uint)-1;
+ _idx = (size_type)-1;
return *this;
}
@@ -247,41 +250,41 @@ public:
void erase(iterator entry);
void erase(const Key &key);
- uint size() const { return _size; }
+ size_type size() const { return _size; }
iterator begin() {
// Find and return the first non-empty entry
- for (uint ctr = 0; ctr <= _mask; ++ctr) {
+ for (size_type ctr = 0; ctr <= _mask; ++ctr) {
if (_storage[ctr] && _storage[ctr] != HASHMAP_DUMMY_NODE)
return iterator(ctr, this);
}
return end();
}
iterator end() {
- return iterator((uint)-1, this);
+ return iterator((size_type)-1, this);
}
const_iterator begin() const {
// Find and return the first non-empty entry
- for (uint ctr = 0; ctr <= _mask; ++ctr) {
+ for (size_type ctr = 0; ctr <= _mask; ++ctr) {
if (_storage[ctr] && _storage[ctr] != HASHMAP_DUMMY_NODE)
return const_iterator(ctr, this);
}
return end();
}
const_iterator end() const {
- return const_iterator((uint)-1, this);
+ return const_iterator((size_type)-1, this);
}
iterator find(const Key &key) {
- uint ctr = lookup(key);
+ size_type ctr = lookup(key);
if (_storage[ctr])
return iterator(ctr, this);
return end();
}
const_iterator find(const Key &key) const {
- uint ctr = lookup(key);
+ size_type ctr = lookup(key);
if (_storage[ctr])
return const_iterator(ctr, this);
return end();
@@ -346,7 +349,7 @@ HashMap<Key, Val, HashFunc, EqualFunc>::HashMap(const HM_t &map) :
*/
template<class Key, class Val, class HashFunc, class EqualFunc>
HashMap<Key, Val, HashFunc, EqualFunc>::~HashMap() {
- for (uint ctr = 0; ctr <= _mask; ++ctr)
+ for (size_type ctr = 0; ctr <= _mask; ++ctr)
freeNode(_storage[ctr]);
delete[] _storage;
@@ -373,7 +376,7 @@ void HashMap<Key, Val, HashFunc, EqualFunc>::assign(const HM_t &map) {
// Simply clone the map given to us, one by one.
_size = 0;
_deleted = 0;
- for (uint ctr = 0; ctr <= _mask; ++ctr) {
+ for (size_type ctr = 0; ctr <= _mask; ++ctr) {
if (map._storage[ctr] == HASHMAP_DUMMY_NODE) {
_storage[ctr] = HASHMAP_DUMMY_NODE;
_deleted++;
@@ -391,7 +394,7 @@ void HashMap<Key, Val, HashFunc, EqualFunc>::assign(const HM_t &map) {
template<class Key, class Val, class HashFunc, class EqualFunc>
void HashMap<Key, Val, HashFunc, EqualFunc>::clear(bool shrinkArray) {
- for (uint ctr = 0; ctr <= _mask; ++ctr) {
+ for (size_type ctr = 0; ctr <= _mask; ++ctr) {
freeNode(_storage[ctr]);
_storage[ctr] = NULL;
}
@@ -414,13 +417,13 @@ void HashMap<Key, Val, HashFunc, EqualFunc>::clear(bool shrinkArray) {
}
template<class Key, class Val, class HashFunc, class EqualFunc>
-void HashMap<Key, Val, HashFunc, EqualFunc>::expandStorage(uint newCapacity) {
+void HashMap<Key, Val, HashFunc, EqualFunc>::expandStorage(size_type newCapacity) {
assert(newCapacity > _mask+1);
#ifndef NDEBUG
- const uint old_size = _size;
+ const size_type old_size = _size;
#endif
- const uint old_mask = _mask;
+ const size_type old_mask = _mask;
Node **old_storage = _storage;
// allocate a new array
@@ -432,7 +435,7 @@ void HashMap<Key, Val, HashFunc, EqualFunc>::expandStorage(uint newCapacity) {
memset(_storage, 0, newCapacity * sizeof(Node *));
// rehash all the old elements
- for (uint ctr = 0; ctr <= old_mask; ++ctr) {
+ for (size_type ctr = 0; ctr <= old_mask; ++ctr) {
if (old_storage[ctr] == NULL || old_storage[ctr] == HASHMAP_DUMMY_NODE)
continue;
@@ -440,9 +443,9 @@ void HashMap<Key, Val, HashFunc, EqualFunc>::expandStorage(uint newCapacity) {
// Since we know that no key exists twice in the old table, we
// can do this slightly better than by calling lookup, since we
// don't have to call _equal().
- const uint hash = _hash(old_storage[ctr]->_key);
- uint idx = hash & _mask;
- for (uint perturb = hash; _storage[idx] != NULL && _storage[idx] != HASHMAP_DUMMY_NODE; perturb >>= HASHMAP_PERTURB_SHIFT) {
+ const size_type hash = _hash(old_storage[ctr]->_key);
+ size_type idx = hash & _mask;
+ for (size_type perturb = hash; _storage[idx] != NULL && _storage[idx] != HASHMAP_DUMMY_NODE; perturb >>= HASHMAP_PERTURB_SHIFT) {
idx = (5 * idx + perturb + 1) & _mask;
}
@@ -460,10 +463,10 @@ void HashMap<Key, Val, HashFunc, EqualFunc>::expandStorage(uint newCapacity) {
}
template<class Key, class Val, class HashFunc, class EqualFunc>
-uint HashMap<Key, Val, HashFunc, EqualFunc>::lookup(const Key &key) const {
- const uint hash = _hash(key);
- uint ctr = hash & _mask;
- for (uint perturb = hash; ; perturb >>= HASHMAP_PERTURB_SHIFT) {
+typename HashMap<Key, Val, HashFunc, EqualFunc>::size_type HashMap<Key, Val, HashFunc, EqualFunc>::lookup(const Key &key) const {
+ const size_type hash = _hash(key);
+ size_type ctr = hash & _mask;
+ for (size_type perturb = hash; ; perturb >>= HASHMAP_PERTURB_SHIFT) {
if (_storage[ctr] == NULL)
break;
if (_storage[ctr] == HASHMAP_DUMMY_NODE) {
@@ -491,13 +494,13 @@ uint HashMap<Key, Val, HashFunc, EqualFunc>::lookup(const Key &key) const {
}
template<class Key, class Val, class HashFunc, class EqualFunc>
-uint HashMap<Key, Val, HashFunc, EqualFunc>::lookupAndCreateIfMissing(const Key &key) {
- const uint hash = _hash(key);
- uint ctr = hash & _mask;
- const uint NONE_FOUND = _mask + 1;
- uint first_free = NONE_FOUND;
+typename HashMap<Key, Val, HashFunc, EqualFunc>::size_type HashMap<Key, Val, HashFunc, EqualFunc>::lookupAndCreateIfMissing(const Key &key) {
+ const size_type hash = _hash(key);
+ size_type ctr = hash & _mask;
+ const size_type NONE_FOUND = _mask + 1;
+ size_type first_free = NONE_FOUND;
bool found = false;
- for (uint perturb = hash; ; perturb >>= HASHMAP_PERTURB_SHIFT) {
+ for (size_type perturb = hash; ; perturb >>= HASHMAP_PERTURB_SHIFT) {
if (_storage[ctr] == NULL)
break;
if (_storage[ctr] == HASHMAP_DUMMY_NODE) {
@@ -537,7 +540,7 @@ uint HashMap<Key, Val, HashFunc, EqualFunc>::lookupAndCreateIfMissing(const Key
// Keep the load factor below a certain threshold.
// Deleted nodes are also counted
- uint capacity = _mask + 1;
+ size_type capacity = _mask + 1;
if ((_size + _deleted) * HASHMAP_LOADFACTOR_DENOMINATOR >
capacity * HASHMAP_LOADFACTOR_NUMERATOR) {
capacity = capacity < 500 ? (capacity * 4) : (capacity * 2);
@@ -553,7 +556,7 @@ uint HashMap<Key, Val, HashFunc, EqualFunc>::lookupAndCreateIfMissing(const Key
template<class Key, class Val, class HashFunc, class EqualFunc>
bool HashMap<Key, Val, HashFunc, EqualFunc>::contains(const Key &key) const {
- uint ctr = lookup(key);
+ size_type ctr = lookup(key);
return (_storage[ctr] != NULL);
}
@@ -569,7 +572,7 @@ const Val &HashMap<Key, Val, HashFunc, EqualFunc>::operator[](const Key &key) co
template<class Key, class Val, class HashFunc, class EqualFunc>
Val &HashMap<Key, Val, HashFunc, EqualFunc>::getVal(const Key &key) {
- uint ctr = lookupAndCreateIfMissing(key);
+ size_type ctr = lookupAndCreateIfMissing(key);
assert(_storage[ctr] != NULL);
return _storage[ctr]->_value;
}
@@ -581,7 +584,7 @@ const Val &HashMap<Key, Val, HashFunc, EqualFunc>::getVal(const Key &key) const
template<class Key, class Val, class HashFunc, class EqualFunc>
const Val &HashMap<Key, Val, HashFunc, EqualFunc>::getVal(const Key &key, const Val &defaultVal) const {
- uint ctr = lookup(key);
+ size_type ctr = lookup(key);
if (_storage[ctr] != NULL)
return _storage[ctr]->_value;
else
@@ -590,7 +593,7 @@ const Val &HashMap<Key, Val, HashFunc, EqualFunc>::getVal(const Key &key, const
template<class Key, class Val, class HashFunc, class EqualFunc>
void HashMap<Key, Val, HashFunc, EqualFunc>::setVal(const Key &key, const Val &val) {
- uint ctr = lookupAndCreateIfMissing(key);
+ size_type ctr = lookupAndCreateIfMissing(key);
assert(_storage[ctr] != NULL);
_storage[ctr]->_value = val;
}
@@ -599,7 +602,7 @@ template<class Key, class Val, class HashFunc, class EqualFunc>
void HashMap<Key, Val, HashFunc, EqualFunc>::erase(iterator entry) {
// Check whether we have a valid iterator
assert(entry._hashmap == this);
- const uint ctr = entry._idx;
+ const size_type ctr = entry._idx;
assert(ctr <= _mask);
Node * const node = _storage[ctr];
assert(node != NULL);
@@ -615,7 +618,7 @@ void HashMap<Key, Val, HashFunc, EqualFunc>::erase(iterator entry) {
template<class Key, class Val, class HashFunc, class EqualFunc>
void HashMap<Key, Val, HashFunc, EqualFunc>::erase(const Key &key) {
- uint ctr = lookup(key);
+ size_type ctr = lookup(key);
if (_storage[ctr] == NULL)
return;
diff --git a/common/huffman.h b/common/huffman.h
index 4175d0d309..3b23340b2e 100644
--- a/common/huffman.h
+++ b/common/huffman.h
@@ -68,7 +68,7 @@ private:
typedef List<Symbol> CodeList;
typedef Array<CodeList> CodeLists;
- typedef Array<Symbol*> SymbolList;
+ typedef Array<Symbol *> SymbolList;
/** Lists of codes and their symbols, sorted by code length. */
CodeLists _codes;
diff --git a/common/keyboard.h b/common/keyboard.h
index bdd0a2d4af..e6db086598 100644
--- a/common/keyboard.h
+++ b/common/keyboard.h
@@ -224,11 +224,14 @@ enum {
KBD_CTRL = 1 << 0,
KBD_ALT = 1 << 1,
KBD_SHIFT = 1 << 2,
+ KBD_NON_STICKY = (KBD_CTRL|KBD_ALT|KBD_SHIFT),
// Sticky modifier flags
KBD_NUM = 1 << 3,
KBD_CAPS = 1 << 4,
- KBD_SCRL = 1 << 5
+ KBD_SCRL = 1 << 5,
+ KBD_STICKY = (KBD_NUM|KBD_CAPS|KBD_SCRL)
+
};
/**
@@ -281,18 +284,27 @@ struct KeyState {
/**
* Check whether the non-sticky flags are *exactly* as specified by f.
- * This ignors the sticky flags (KBD_NUM, KBD_CAPS, KBD_SCRL).
+ * This ignores the sticky flags (KBD_NUM, KBD_CAPS, KBD_SCRL).
+ * Sticky flags should never be passed to this function.
* If you just want to check whether a modifier flag is set, just bit-and
* the flag. E.g. to check whether the control key modifier is set,
* you can write
* if (keystate.flags & KBD_CTRL) { ... }
*/
bool hasFlags(byte f) const {
- return f == (flags & ~(KBD_NUM|KBD_CAPS|KBD_SCRL));
+ assert(!(f & KBD_STICKY));
+ return f == (flags & ~KBD_STICKY);
}
+ /**
+ * Check if two key states are equal. This implementation ignores the state
+ * of the sticky flags (caps lock, num lock, scroll lock) completely. This
+ * functionality is currently only used by the keymapper.
+ */
bool operator==(const KeyState &x) const {
- return keycode == x.keycode && ascii == x.ascii && flags == x.flags;
+ // Intentionally ignore ASCII, as the keycode and non-sticky flag
+ // combination should suffice.
+ return keycode == x.keycode && hasFlags(x.flags & ~KBD_STICKY);
}
};
diff --git a/common/language.cpp b/common/language.cpp
new file mode 100644
index 0000000000..1de01b0207
--- /dev/null
+++ b/common/language.cpp
@@ -0,0 +1,107 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "common/language.h"
+#include "common/str.h"
+
+namespace Common {
+
+const LanguageDescription g_languages[] = {
+ { "zh-cn", "zh_CN", "Chinese (China)", ZH_CNA },
+ { "zh", "zh_TW", "Chinese (Taiwan)", ZH_TWN },
+ { "cz", "cs_CZ", "Czech", CZ_CZE },
+ { "nl", "nl_NL", "Dutch", NL_NLD },
+ { "en", "en", "English", EN_ANY }, // Generic English (when only one game version exist)
+ { "gb", "en_GB", "English (GB)", EN_GRB },
+ { "us", "en_US", "English (US)", EN_USA },
+ { "fr", "fr_FR", "French", FR_FRA },
+ { "de", "de_DE", "German", DE_DEU },
+ { "gr", "el_GR", "Greek", GR_GRE },
+ { "he", "he_IL", "Hebrew", HE_ISR },
+ { "hb", "he_IL", "Hebrew", HE_ISR }, // Deprecated
+ { "hr", "hr_HR", "Croatian", HR_HRV },
+ { "hu", "hu_HU", "Hungarian", HU_HUN },
+ { "it", "it_IT", "Italian", IT_ITA },
+ { "jp", "ja_JP", "Japanese", JA_JPN },
+ { "kr", "ko_KR", "Korean", KO_KOR },
+ { "nb", "nb_NO", "Norwegian Bokm\xE5l", NB_NOR }, // TODO Someone should verify the unix locale
+ { "pl", "pl_PL", "Polish", PL_POL },
+ { "br", "pt_BR", "Portuguese", PT_BRA },
+ { "ru", "ru_RU", "Russian", RU_RUS },
+ { "es", "es_ES", "Spanish", ES_ESP },
+ { "se", "sv_SE", "Swedish", SE_SWE },
+ { 0, 0, 0, UNK_LANG }
+};
+
+Language parseLanguage(const String &str) {
+ if (str.empty())
+ return UNK_LANG;
+
+ const LanguageDescription *l = g_languages;
+ for (; l->code; ++l) {
+ if (str.equalsIgnoreCase(l->code))
+ return l->id;
+ }
+
+ return UNK_LANG;
+}
+
+Language parseLanguageFromLocale(const char *locale) {
+ if (!locale || !*locale)
+ return UNK_LANG;
+
+ const LanguageDescription *l = g_languages;
+ for (; l->code; ++l) {
+ if (!strcmp(l->unixLocale, locale))
+ return l->id;
+ }
+
+ return UNK_LANG;
+}
+
+const char *getLanguageCode(Language id) {
+ const LanguageDescription *l = g_languages;
+ for (; l->code; ++l) {
+ if (l->id == id)
+ return l->code;
+ }
+ return 0;
+}
+
+const char *getLanguageLocale(Language id) {
+ const LanguageDescription *l = g_languages;
+ for (; l->code; ++l) {
+ if (l->id == id)
+ return l->unixLocale;
+ }
+ return 0;
+}
+
+const char *getLanguageDescription(Language id) {
+ const LanguageDescription *l = g_languages;
+ for (; l->code; ++l) {
+ if (l->id == id)
+ return l->description;
+ }
+ return 0;
+}
+
+} // End of namespace Common
diff --git a/common/language.h b/common/language.h
new file mode 100644
index 0000000000..b83f0d34fd
--- /dev/null
+++ b/common/language.h
@@ -0,0 +1,80 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef COMMON_LANGUAGE_H
+#define COMMON_LANGUAGE_H
+
+#include "common/scummsys.h"
+
+namespace Common {
+
+class String;
+
+/**
+ * List of game language.
+ */
+enum Language {
+ ZH_CNA,
+ ZH_TWN,
+ CZ_CZE,
+ NL_NLD,
+ EN_ANY, // Generic English (when only one game version exist)
+ EN_GRB,
+ EN_USA,
+ FR_FRA,
+ DE_DEU,
+ GR_GRE,
+ HE_ISR,
+ HR_HRV,
+ HU_HUN,
+ IT_ITA,
+ JA_JPN,
+ KO_KOR,
+ NB_NOR,
+ PL_POL,
+ PT_BRA,
+ RU_RUS,
+ ES_ESP,
+ SE_SWE,
+
+ UNK_LANG = -1 // Use default language (i.e. none specified)
+};
+
+struct LanguageDescription {
+ const char *code;
+ const char *unixLocale;
+ const char *description;
+ Language id;
+};
+
+extern const LanguageDescription g_languages[];
+
+
+/** Convert a string containing a language name into a Language enum value. */
+extern Language parseLanguage(const String &str);
+extern Language parseLanguageFromLocale(const char *locale);
+extern const char *getLanguageCode(Language id);
+extern const char *getLanguageLocale(Language id);
+extern const char *getLanguageDescription(Language id);
+
+} // End of namespace Common
+
+#endif
diff --git a/common/list.h b/common/list.h
index a1e761f55d..9792042239 100644
--- a/common/list.h
+++ b/common/list.h
@@ -43,6 +43,7 @@ public:
typedef ListInternal::ConstIterator<t_T> const_iterator;
typedef t_T value_type;
+ typedef uint size_type;
public:
List() {
@@ -181,8 +182,8 @@ public:
return *this;
}
- uint size() const {
- uint n = 0;
+ size_type size() const {
+ size_type n = 0;
for (const NodeBase *cur = _anchor._next; cur != &_anchor; cur = cur->_next)
++n;
return n;
@@ -226,7 +227,7 @@ public:
}
const_iterator end() const {
- return const_iterator(const_cast<NodeBase*>(&_anchor));
+ return const_iterator(const_cast<NodeBase *>(&_anchor));
}
protected:
diff --git a/common/list_intern.h b/common/list_intern.h
index daa7446781..fef32fbe1e 100644
--- a/common/list_intern.h
+++ b/common/list_intern.h
@@ -35,7 +35,7 @@ namespace ListInternal {
NodeBase *_next;
};
- template <typename T>
+ template<typename T>
struct Node : public NodeBase {
T _data;
diff --git a/common/localization.h b/common/localization.h
index 3945cf5fab..e908485b99 100644
--- a/common/localization.h
+++ b/common/localization.h
@@ -22,7 +22,7 @@
#ifndef COMMON_LOCALIZATION_H
#define COMMON_LOCALIZATION_H
-#include "common/util.h"
+#include "common/language.h"
#include "common/keyboard.h"
namespace Common {
diff --git a/common/macresman.cpp b/common/macresman.cpp
index 2b9c68ade9..14bdfa7080 100644
--- a/common/macresman.cpp
+++ b/common/macresman.cpp
@@ -110,7 +110,7 @@ bool MacResManager::open(String filename) {
String fullPath = ConfMan.get("path") + "/" + filename + "/..namedfork/rsrc";
FSNode resFsNode = FSNode(fullPath);
if (resFsNode.exists()) {
- SeekableReadStream *macResForkRawStream = resFsNode.createReadStream();;
+ SeekableReadStream *macResForkRawStream = resFsNode.createReadStream();
if (macResForkRawStream && loadFromRawFork(*macResForkRawStream)) {
_baseFileName = filename;
@@ -173,7 +173,7 @@ bool MacResManager::open(FSNode path, String filename) {
String fullPath = path.getPath() + "/" + filename + "/..namedfork/rsrc";
FSNode resFsNode = FSNode(fullPath);
if (resFsNode.exists()) {
- SeekableReadStream *macResForkRawStream = resFsNode.createReadStream();;
+ SeekableReadStream *macResForkRawStream = resFsNode.createReadStream();
if (macResForkRawStream && loadFromRawFork(*macResForkRawStream)) {
_baseFileName = filename;
@@ -238,6 +238,27 @@ bool MacResManager::open(FSNode path, String filename) {
return false;
}
+bool MacResManager::exists(const String &filename) {
+ // Try the file name by itself
+ if (Common::File::exists(filename))
+ return true;
+
+ // Try the .rsrc extension
+ if (Common::File::exists(filename + ".rsrc"))
+ return true;
+
+ // Check if we have a MacBinary file
+ Common::File tempFile;
+ if (tempFile.open(filename + ".bin") && isMacBinary(tempFile))
+ return true;
+
+ // Check if we have an AppleDouble file
+ if (tempFile.open("._" + filename) && tempFile.readUint32BE() == 0x00051607)
+ return true;
+
+ return false;
+}
+
bool MacResManager::loadFromAppleDouble(SeekableReadStream &stream) {
if (stream.readUint32BE() != 0x00051607) // tag
return false;
diff --git a/common/macresman.h b/common/macresman.h
index 4d86e46d11..6820106925 100644
--- a/common/macresman.h
+++ b/common/macresman.h
@@ -69,6 +69,13 @@ public:
bool open(FSNode path, String filename);
/**
+ * See if a Mac data/resource fork pair exists.
+ * @param filename The base file name of the file
+ * @return True if either a data fork or resource fork with this name exists
+ */
+ static bool exists(const String &filename);
+
+ /**
* Close the Mac data/resource fork pair.
*/
void close();
diff --git a/common/memory.h b/common/memory.h
new file mode 100644
index 0000000000..0e5a97c20b
--- /dev/null
+++ b/common/memory.h
@@ -0,0 +1,65 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef COMMON_MEMORY_H
+#define COMMON_MEMORY_H
+
+#include "common/scummsys.h"
+
+namespace Common {
+
+/**
+ * Copies data from the range [first, last) to [dst, dst + (last - first)).
+ * It requires the range [dst, dst + (last - first)) to be valid and
+ * uninitialized.
+ */
+template<class In, class Type>
+Type *uninitialized_copy(In first, In last, Type *dst) {
+ while (first != last)
+ new ((void *)dst++) Type(*first++);
+ return dst;
+}
+
+/**
+ * Initializes the memory [first, first + (last - first)) with the value x.
+ * It requires the range [first, first + (last - first)) to be valid and
+ * uninitialized.
+ */
+/*template<class Type, class Value>
+void uninitialized_fill(Type *first, Type *last, const Value &x) {
+ while (first != last)
+ new ((void *)first++) Type(x);
+}*/
+
+/**
+ * Initializes the memory [dst, dst + n) with the value x.
+ * It requires the range [dst, dst + n) to be valid and
+ * uninitialized.
+ */
+/*template<class Type, class Value>
+void uninitialized_fill_n(Type *dst, size_t n, const Value &x) {
+ while (n--)
+ new ((void *)dst++) Type(x);
+}*/
+
+} // End of namespace Common
+
+#endif
diff --git a/common/memorypool.cpp b/common/memorypool.cpp
index 19adc54d00..e3742eeae0 100644
--- a/common/memorypool.cpp
+++ b/common/memorypool.cpp
@@ -33,7 +33,7 @@ static size_t adjustChunkSize(size_t chunkSize) {
// You must at least fit the pointer in the node (technically unneeded considering the next rounding statement)
chunkSize = MAX(chunkSize, sizeof(void *));
// There might be an alignment problem on some platforms when trying to load a void* on a non natural boundary
- // so we round to the next sizeof(void*)
+ // so we round to the next sizeof(void *)
chunkSize = (chunkSize + sizeof(void *) - 1) & (~(sizeof(void *) - 1));
return chunkSize;
diff --git a/common/memorypool.h b/common/memorypool.h
index 5ba09cebed..9a4e523d53 100644
--- a/common/memorypool.h
+++ b/common/memorypool.h
@@ -105,7 +105,7 @@ template<size_t CHUNK_SIZE, size_t NUM_INTERNAL_CHUNKS = 32>
class FixedSizeMemoryPool : public MemoryPool {
private:
enum {
- REAL_CHUNK_SIZE = (CHUNK_SIZE + sizeof(void*) - 1) & (~(sizeof(void*) - 1))
+ REAL_CHUNK_SIZE = (CHUNK_SIZE + sizeof(void *) - 1) & (~(sizeof(void *) - 1))
};
byte _storage[NUM_INTERNAL_CHUNKS * REAL_CHUNK_SIZE];
diff --git a/common/module.mk b/common/module.mk
index 7434df7052..b4928fabda 100644
--- a/common/module.mk
+++ b/common/module.mk
@@ -8,19 +8,24 @@ MODULE_OBJS := \
debug.o \
error.o \
EventDispatcher.o \
+ EventMapper.o \
EventRecorder.o \
file.o \
fs.o \
+ gui_options.o \
hashmap.o \
iff_container.o \
+ language.o \
localization.o \
macresman.o \
memorypool.o \
md5.o \
mutex.o \
+ platform.o \
quicktime.o \
random.o \
rational.o \
+ rendermode.o \
str.o \
stream.o \
system.o \
diff --git a/common/platform.cpp b/common/platform.cpp
new file mode 100644
index 0000000000..9986048b48
--- /dev/null
+++ b/common/platform.cpp
@@ -0,0 +1,107 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "common/platform.h"
+#include "common/str.h"
+
+namespace Common {
+
+const PlatformDescription g_platforms[] = {
+ { "2gs", "2gs", "2gs", "Apple IIgs", kPlatformApple2GS },
+ { "3do", "3do", "3do", "3DO", kPlatform3DO },
+ { "acorn", "acorn", "acorn", "Acorn", kPlatformAcorn },
+ { "amiga", "ami", "amiga", "Amiga", kPlatformAmiga },
+ { "atari", "atari-st", "st", "Atari ST", kPlatformAtariST },
+ { "c64", "c64", "c64", "Commodore 64", kPlatformC64 },
+ { "pc", "dos", "ibm", "DOS", kPlatformPC },
+ { "pc98", "pc98", "pc98", "PC-98", kPlatformPC98 },
+ { "wii", "wii", "wii", "Nintendo Wii", kPlatformWii },
+ { "coco3", "coco3", "coco3", "CoCo3", kPlatformCoCo3 },
+
+ // The 'official' spelling seems to be "FM-TOWNS" (e.g. in the Indy4 demo).
+ // However, on the net many variations can be seen, like "FMTOWNS",
+ // "FM TOWNS", "FmTowns", etc.
+ { "fmtowns", "towns", "fm", "FM-TOWNS", kPlatformFMTowns },
+
+ { "linux", "linux", "linux", "Linux", kPlatformLinux },
+ { "macintosh", "mac", "mac", "Macintosh", kPlatformMacintosh },
+ { "pce", "pce", "pce", "PC-Engine", kPlatformPCEngine },
+ { "nes", "nes", "nes", "NES", kPlatformNES },
+ { "segacd", "segacd", "sega", "SegaCD", kPlatformSegaCD },
+ { "windows", "win", "win", "Windows", kPlatformWindows },
+ { "playstation", "psx", "psx", "Sony PlayStation", kPlatformPSX },
+ { "cdi", "cdi", "cdi", "Philips CD-i", kPlatformCDi },
+ { "ios", "ios", "ios", "Apple iOS", kPlatformIOS },
+
+ { 0, 0, 0, "Default", kPlatformUnknown }
+};
+
+Platform parsePlatform(const String &str) {
+ if (str.empty())
+ return kPlatformUnknown;
+
+ // Handle some special case separately, for compatibility with old config
+ // files.
+ if (str == "1")
+ return kPlatformAmiga;
+ else if (str == "2")
+ return kPlatformAtariST;
+ else if (str == "3")
+ return kPlatformMacintosh;
+
+ const PlatformDescription *l = g_platforms;
+ for (; l->code; ++l) {
+ if (str.equalsIgnoreCase(l->code) || str.equalsIgnoreCase(l->code2) || str.equalsIgnoreCase(l->abbrev))
+ return l->id;
+ }
+
+ return kPlatformUnknown;
+}
+
+
+const char *getPlatformCode(Platform id) {
+ const PlatformDescription *l = g_platforms;
+ for (; l->code; ++l) {
+ if (l->id == id)
+ return l->code;
+ }
+ return 0;
+}
+
+const char *getPlatformAbbrev(Platform id) {
+ const PlatformDescription *l = g_platforms;
+ for (; l->code; ++l) {
+ if (l->id == id)
+ return l->abbrev;
+ }
+ return 0;
+}
+
+const char *getPlatformDescription(Platform id) {
+ const PlatformDescription *l = g_platforms;
+ for (; l->code; ++l) {
+ if (l->id == id)
+ return l->description;
+ }
+ return l->description;
+}
+
+} // End of namespace Common
diff --git a/common/platform.h b/common/platform.h
new file mode 100644
index 0000000000..1891c7096d
--- /dev/null
+++ b/common/platform.h
@@ -0,0 +1,80 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef COMMON_PLATFORM_H
+#define COMMON_PLATFORM_H
+
+#include "common/scummsys.h"
+
+namespace Common {
+
+class String;
+
+/**
+ * List of game platforms. Specifying a platform for a target can be used to
+ * give the game engines a hint for which platform the game data file are.
+ * This may be optional or required, depending on the game engine and the
+ * game in question.
+ */
+enum Platform {
+ kPlatformPC,
+ kPlatformAmiga,
+ kPlatformAtariST,
+ kPlatformMacintosh,
+ kPlatformFMTowns,
+ kPlatformWindows,
+ kPlatformNES,
+ kPlatformC64,
+ kPlatformCoCo3,
+ kPlatformLinux,
+ kPlatformAcorn,
+ kPlatformSegaCD,
+ kPlatform3DO,
+ kPlatformPCEngine,
+ kPlatformApple2GS,
+ kPlatformPC98,
+ kPlatformWii,
+ kPlatformPSX,
+ kPlatformCDi,
+ kPlatformIOS,
+
+ kPlatformUnknown = -1
+};
+
+struct PlatformDescription {
+ const char *code;
+ const char *code2;
+ const char *abbrev;
+ const char *description;
+ Platform id;
+};
+
+extern const PlatformDescription g_platforms[];
+
+/** Convert a string containing a platform name into a Platform enum value. */
+extern Platform parsePlatform(const String &str);
+extern const char *getPlatformCode(Platform id);
+extern const char *getPlatformAbbrev(Platform id);
+extern const char *getPlatformDescription(Platform id);
+
+} // End of namespace Common
+
+#endif
diff --git a/common/quicktime.cpp b/common/quicktime.cpp
index 9ea8c229ea..248d8b2b3a 100644
--- a/common/quicktime.cpp
+++ b/common/quicktime.cpp
@@ -66,7 +66,7 @@ bool QuickTimeParser::parseFile(const String &filename) {
_foundMOOV = false;
_disposeFileHandle = DisposeAfterUse::YES;
- Atom atom = { 0, 0, 0xffffffff };
+ Atom atom = { 0, 0, 0 };
if (_resFork->hasResFork()) {
// Search for a 'moov' resource
@@ -80,14 +80,12 @@ bool QuickTimeParser::parseFile(const String &filename) {
if (readDefault(atom) < 0 || !_foundMOOV)
return false;
}
- delete _fd;
- atom.type = 0;
- atom.offset = 0;
- atom.size = 0xffffffff;
+ delete _fd;
}
_fd = _resFork->getDataFork();
+ atom.size = _fd->size();
if (readDefault(atom) < 0 || !_foundMOOV)
return false;
@@ -135,7 +133,7 @@ void QuickTimeParser::initParseTable() {
{ &QuickTimeParser::readDefault, MKTAG('e', 'd', 't', 's') },
{ &QuickTimeParser::readELST, MKTAG('e', 'l', 's', 't') },
{ &QuickTimeParser::readHDLR, MKTAG('h', 'd', 'l', 'r') },
- { &QuickTimeParser::readDefault, MKTAG('m', 'd', 'a', 't') },
+ { &QuickTimeParser::readLeaf, MKTAG('m', 'd', 'a', 't') },
{ &QuickTimeParser::readMDHD, MKTAG('m', 'd', 'h', 'd') },
{ &QuickTimeParser::readDefault, MKTAG('m', 'd', 'i', 'a') },
{ &QuickTimeParser::readDefault, MKTAG('m', 'i', 'n', 'f') },
@@ -386,8 +384,7 @@ int QuickTimeParser::readTKHD(Atom atom) {
/* track->id = */_fd->readUint32BE(); // track id (NOT 0 !)
_fd->readUint32BE(); // reserved
- //track->startTime = 0; // check
- (version == 1) ? (_fd->readUint32BE(), _fd->readUint32BE()) : _fd->readUint32BE(); // highlevel (considering edits) duration in movie timebase
+ track->duration = (version == 1) ? (_fd->readUint32BE(), _fd->readUint32BE()) : _fd->readUint32BE(); // highlevel (considering edits) duration in movie timebase
_fd->readUint32BE(); // reserved
_fd->readUint32BE(); // reserved
@@ -410,8 +407,8 @@ int QuickTimeParser::readTKHD(Atom atom) {
track->scaleFactorY.debugPrint(1, "readTKHD(): scaleFactorY =");
// these are fixed-point, 16:16
- // uint32 tkWidth = _fd->readUint32BE() >> 16; // track width
- // uint32 tkHeight = _fd->readUint32BE() >> 16; // track height
+ //_fd->readUint32BE() >> 16; // track width
+ //_fd->readUint32BE() >> 16; // track height
return 0;
}
@@ -428,17 +425,18 @@ int QuickTimeParser::readELST(Atom atom) {
debug(2, "Track %d edit list count: %d", _tracks.size() - 1, track->editCount);
+ uint32 offset = 0;
+
for (uint32 i = 0; i < track->editCount; i++){
track->editList[i].trackDuration = _fd->readUint32BE();
track->editList[i].mediaTime = _fd->readSint32BE();
track->editList[i].mediaRate = Rational(_fd->readUint32BE(), 0x10000);
- debugN(3, "\tDuration = %d, Media Time = %d, ", track->editList[i].trackDuration, track->editList[i].mediaTime);
+ track->editList[i].timeOffset = offset;
+ debugN(3, "\tDuration = %d (Offset = %d), Media Time = %d, ", track->editList[i].trackDuration, offset, track->editList[i].mediaTime);
track->editList[i].mediaRate.debugPrint(3, "Media Rate =");
+ offset += track->editList[i].trackDuration;
}
- if (track->editCount != 1)
- warning("Multiple edit list entries. Things may go awry");
-
return 0;
}
@@ -500,7 +498,7 @@ int QuickTimeParser::readMDHD(Atom atom) {
}
track->timeScale = _fd->readUint32BE();
- track->duration = (version == 1) ? (_fd->readUint32BE(), _fd->readUint32BE()) : _fd->readUint32BE(); // duration
+ track->mediaDuration = (version == 1) ? (_fd->readUint32BE(), _fd->readUint32BE()) : _fd->readUint32BE(); // duration
_fd->readUint16BE(); // language
_fd->readUint16BE(); // quality
@@ -793,6 +791,7 @@ QuickTimeParser::Track::Track() {
duration = 0;
startTime = 0;
objectTypeMP4 = 0;
+ mediaDuration = 0;
}
QuickTimeParser::Track::~Track() {
diff --git a/common/quicktime.h b/common/quicktime.h
index e4c821e209..efd2adbd21 100644
--- a/common/quicktime.h
+++ b/common/quicktime.h
@@ -109,6 +109,7 @@ protected:
struct EditListEntry {
uint32 trackDuration;
+ uint32 timeOffset;
int32 mediaTime;
Rational mediaRate;
};
@@ -154,7 +155,7 @@ protected:
uint16 height;
CodecType codecType;
- Array<SampleDesc*> sampleDescs;
+ Array<SampleDesc *> sampleDescs;
uint32 editCount;
EditListEntry *editList;
@@ -163,6 +164,7 @@ protected:
uint32 frameCount;
uint32 duration;
+ uint32 mediaDuration;
uint32 startTime;
Rational scaleFactorX;
Rational scaleFactorY;
@@ -178,7 +180,7 @@ protected:
uint32 _duration;
Rational _scaleFactorX;
Rational _scaleFactorY;
- Array<Track*> _tracks;
+ Array<Track *> _tracks;
uint32 _beginOffset;
MacResManager *_resFork;
diff --git a/common/rendermode.cpp b/common/rendermode.cpp
new file mode 100644
index 0000000000..62b67faee5
--- /dev/null
+++ b/common/rendermode.cpp
@@ -0,0 +1,81 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "common/rendermode.h"
+
+#include "common/str.h"
+#include "common/translation.h"
+
+
+namespace Common {
+
+
+const RenderModeDescription g_renderModes[] = {
+ // I18N: Hercules is graphics card name
+ { "hercGreen", _s("Hercules Green"), kRenderHercG },
+ { "hercAmber", _s("Hercules Amber"), kRenderHercA },
+ { "cga", "CGA", kRenderCGA },
+ { "ega", "EGA", kRenderEGA },
+ { "vga", "VGA", kRenderVGA },
+ { "amiga", "Amiga", kRenderAmiga },
+ { "fmtowns", "FM-Towns", kRenderFMTowns },
+ { "pc9821", "PC-9821 (256 Colors)", kRenderPC9821 },
+ { "pc9801", "PC-9801 (16 Colors)", kRenderPC9801 },
+ {0, 0, kRenderDefault}
+};
+
+DECLARE_TRANSLATION_ADDITIONAL_CONTEXT("Hercules Green", "lowres")
+DECLARE_TRANSLATION_ADDITIONAL_CONTEXT("Hercules Amber", "lowres")
+
+RenderMode parseRenderMode(const String &str) {
+ if (str.empty())
+ return kRenderDefault;
+
+ const RenderModeDescription *l = g_renderModes;
+ for (; l->code; ++l) {
+ if (str.equalsIgnoreCase(l->code))
+ return l->id;
+ }
+
+ return kRenderDefault;
+}
+
+const char *getRenderModeCode(RenderMode id) {
+ const RenderModeDescription *l = g_renderModes;
+ for (; l->code; ++l) {
+ if (l->id == id)
+ return l->code;
+ }
+ return 0;
+}
+
+const char *getRenderModeDescription(RenderMode id) {
+ const RenderModeDescription *l = g_renderModes;
+ for (; l->code; ++l) {
+ if (l->id == id)
+ return l->description;
+ }
+ return 0;
+}
+
+
+} // End of namespace Common
diff --git a/common/rendermode.h b/common/rendermode.h
new file mode 100644
index 0000000000..c2fece77ee
--- /dev/null
+++ b/common/rendermode.h
@@ -0,0 +1,67 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef COMMON_RENDERMODE_H
+#define COMMON_RENDERMODE_H
+
+#include "common/scummsys.h"
+
+namespace Common {
+
+class String;
+
+/**
+ * List of render modes. It specifies which original graphics mode
+ * to use. Some targets used postprocessing dithering routines for
+ * reducing color depth of final image which let it to be rendered on
+ * such low-level adapters as CGA or Hercules.
+ */
+enum RenderMode {
+ kRenderDefault = 0,
+ kRenderVGA = 1,
+ kRenderEGA = 2,
+ kRenderCGA = 3,
+ kRenderHercG = 4,
+ kRenderHercA = 5,
+ kRenderAmiga = 6,
+ kRenderFMTowns = 7,
+ kRenderPC9821 = 8,
+ kRenderPC9801 = 9
+};
+
+struct RenderModeDescription {
+ const char *code;
+ const char *description;
+ RenderMode id;
+};
+
+extern const RenderModeDescription g_renderModes[];
+
+/** Convert a string containing a render mode name into a RenderingMode enum value. */
+extern RenderMode parseRenderMode(const String &str);
+extern const char *getRenderModeCode(RenderMode id);
+extern const char *getRenderModeDescription(RenderMode id);
+
+
+} // End of namespace Common
+
+#endif
diff --git a/common/scummsys.h b/common/scummsys.h
index fbd5bb5273..6baab7c16f 100644
--- a/common/scummsys.h
+++ b/common/scummsys.h
@@ -130,6 +130,15 @@
#define _USE_MATH_DEFINES
#include <math.h>
+ // FIXME: We sadly can't assume standard C++ headers to be present on every
+ // system we support, so we should get rid of this. The solution should be to
+ // write a simple placement new on our own. It might be noteworthy we can't
+ // easily do that for systems which do have a <new>, since it might clash with
+ // the default definition otherwise!
+ // Symbian does not have <new> but the new operator
+ #if !defined(__SYMBIAN32__)
+ #include <new>
+ #endif
#endif
diff --git a/common/serializer.h b/common/serializer.h
index 5b08a9a9fa..4d97c9e930 100644
--- a/common/serializer.h
+++ b/common/serializer.h
@@ -30,7 +30,7 @@ namespace Common {
#define SYNC_AS(SUFFIX,TYPE,SIZE) \
- template <typename T> \
+ template<typename T> \
void syncAs ## SUFFIX(T &val, Version minVersion = 0, Version maxVersion = kLastVersion) { \
if (_version < minVersion || _version > maxVersion) \
return; \
diff --git a/common/singleton.h b/common/singleton.h
index 43f1c0c4d0..a4f106c9d3 100644
--- a/common/singleton.h
+++ b/common/singleton.h
@@ -43,7 +43,7 @@ private:
* singleton class might be pure virtual (or "abstract" in Java terminology),
* and you specialise makeInstance to return an instance of a subclass.
*/
- //template <class T>
+ //template<class T>
#if defined (_WIN32_WCE) || defined (_MSC_VER) || defined (__WINS__)
//FIXME evc4 and msvc7 doesn't like it as private member
public:
diff --git a/common/stack.h b/common/stack.h
index 0d13049f2e..bc5de9ac7f 100644
--- a/common/stack.h
+++ b/common/stack.h
@@ -30,48 +30,59 @@ namespace Common {
/**
* Extremly simple fixed size stack class.
*/
-template<class T, int MAX_SIZE = 10>
+template<class T, uint MAX_SIZE = 10>
class FixedStack {
-protected:
- T _stack[MAX_SIZE];
- int _size;
public:
+ typedef uint size_type;
+
FixedStack<T, MAX_SIZE>() : _size(0) {}
bool empty() const {
return _size <= 0;
}
+
void clear() {
_size = 0;
}
+
void push(const T &x) {
assert(_size < MAX_SIZE);
_stack[_size++] = x;
}
+
const T &top() const {
assert(_size > 0);
return _stack[_size - 1];
}
+
T &top() {
assert(_size > 0);
return _stack[_size - 1];
}
+
T pop() {
T tmp = top();
--_size;
return tmp;
}
- int size() const {
+
+ size_type size() const {
return _size;
}
- T &operator[](int i) {
- assert(0 <= i && i < MAX_SIZE);
+
+ T &operator[](size_type i) {
+ assert(i < MAX_SIZE);
return _stack[i];
}
- const T &operator[](int i) const {
- assert(0 <= i && i < MAX_SIZE);
+
+ const T &operator[](size_type i) const {
+ assert(i < MAX_SIZE);
return _stack[i];
}
+
+protected:
+ T _stack[MAX_SIZE];
+ size_type _size;
};
@@ -81,39 +92,49 @@ public:
template<class T>
class Stack {
private:
- Array<T> _stack;
+ Array<T> _stack;
public:
+ typedef typename Array<T>::size_type size_type;
+
Stack<T>() {}
Stack<T>(const Array<T> &stackContent) : _stack(stackContent) {}
bool empty() const {
return _stack.empty();
}
+
void clear() {
_stack.clear();
}
+
void push(const T &x) {
_stack.push_back(x);
}
+
T &top() {
return _stack.back();
}
+
const T &top() const {
return _stack.back();
}
+
T pop() {
T tmp = _stack.back();
_stack.pop_back();
return tmp;
}
- int size() const {
+
+ size_type size() const {
return _stack.size();
}
- T &operator[](int i) {
+
+ T &operator[](size_type i) {
return _stack[i];
}
- const T &operator[](int i) const {
+
+ const T &operator[](size_type i) const {
return _stack[i];
}
};
diff --git a/common/str.cpp b/common/str.cpp
index 32f4b44e79..84805082ac 100644
--- a/common/str.cpp
+++ b/common/str.cpp
@@ -405,13 +405,13 @@ void String::trim() {
makeUnique();
// Trim trailing whitespace
- while (_size >= 1 && isspace(static_cast<unsigned char>(_str[_size - 1])))
+ while (_size >= 1 && isSpace(_str[_size - 1]))
--_size;
_str[_size] = 0;
// Trim leading whitespace
char *t = _str;
- while (isspace((unsigned char)*t))
+ while (isSpace(*t))
t++;
if (t != _str) {
@@ -606,14 +606,14 @@ String operator+(const String &x, char y) {
}
char *ltrim(char *t) {
- while (isspace(static_cast<unsigned char>(*t)))
+ while (isSpace(*t))
t++;
return t;
}
char *rtrim(char *t) {
int l = strlen(t) - 1;
- while (l >= 0 && isspace(static_cast<unsigned char>(t[l])))
+ while (l >= 0 && isSpace(t[l]))
t[l--] = 0;
return t;
}
@@ -793,7 +793,7 @@ size_t strlcpy(char *dst, const char *src, size_t size) {
}
// Move to the terminating zero of the source
- // string, we need this to determin the length
+ // string, we need this to determine the length
// of the source string.
while (*src)
++src;
@@ -841,7 +841,7 @@ size_t strlcat(char *dst, const char *src, size_t size) {
*dst = 0;
// Move to the terminating zero of the source
- // string, we need this to determin the length
+ // string, we need this to determine the length
// of the source string.
while (*src)
++src;
diff --git a/common/stream.cpp b/common/stream.cpp
index 30b3bca497..85647bfe3a 100644
--- a/common/stream.cpp
+++ b/common/stream.cpp
@@ -240,7 +240,7 @@ bool SeekableSubReadStream::seek(int32 offset, int whence) {
return ret;
}
-uint32 SafeSubReadStream::read(void *dataPtr, uint32 dataSize) {
+uint32 SafeSeekableSubReadStream::read(void *dataPtr, uint32 dataSize) {
// Make sure the parent stream is at the right position
seek(0, SEEK_CUR);
diff --git a/common/substream.h b/common/substream.h
index 7e67389da1..01686529aa 100644
--- a/common/substream.h
+++ b/common/substream.h
@@ -99,21 +99,24 @@ public:
* normal SeekableSubReadStream, at the cost of seek()ing the parent stream
* before each read().
*
- * More than one SafeSubReadStream to the same parent stream can be used
+ * More than one SafeSeekableSubReadStream to the same parent stream can be used
* at the same time; they won't mess up each other. They will, however,
* reposition the parent stream, so don't depend on its position to be
- * the same after a read() or seek() on one of its SafeSubReadStream.
+ * the same after a read() or seek() on one of its SafeSeekableSubReadStream.
+ *
+ * Note that this stream is *not* threading safe. Calling read from the audio
+ * thread and from the main thread might mess up the data retrieved.
*/
-class SafeSubReadStream : public SeekableSubReadStream {
+class SafeSeekableSubReadStream : public SeekableSubReadStream {
public:
- SafeSubReadStream(SeekableReadStream *parentStream, uint32 begin, uint32 end, DisposeAfterUse::Flag disposeParentStream = DisposeAfterUse::NO) :
- SeekableSubReadStream(parentStream, begin, end, disposeParentStream) {
+ SafeSeekableSubReadStream(SeekableReadStream *parentStream, uint32 begin, uint32 end, DisposeAfterUse::Flag disposeParentStream = DisposeAfterUse::NO)
+ : SeekableSubReadStream(parentStream, begin, end, disposeParentStream) {
}
- virtual uint32 read(void *dataPtr, uint32 dataSize);
+ virtual uint32 read(void *dataPtr, uint32 dataSize);
};
-} // End of namespace Common
+} // End of namespace Common
#endif
diff --git a/common/system.h b/common/system.h
index 413fe326a7..dc74533861 100644
--- a/common/system.h
+++ b/common/system.h
@@ -51,7 +51,11 @@ class UpdateManager;
class TimerManager;
class SeekableReadStream;
class WriteStream;
-class HardwareKeySet;
+#ifdef ENABLE_KEYMAPPER
+class HardwareInputSet;
+class Keymap;
+class KeymapperDefaultBindings;
+#endif
}
class AudioCDManager;
@@ -932,15 +936,42 @@ public:
return _eventManager;
}
+#ifdef ENABLE_KEYMAPPER
+ /**
+ * Register hardware inputs with keymapper
+ * IMPORTANT NOTE: This is part of the WIP Keymapper. If you plan to use
+ * this, please talk to tsoliman and/or LordHoto.
+ *
+ * @return HardwareInputSet with all keys and recommended mappings
+ *
+ * See keymapper documentation for further reference.
+ */
+ virtual Common::HardwareInputSet *getHardwareInputSet() { return 0; }
+
/**
- * Register hardware keys with keymapper
+ * Return a platform-specific global keymap
+ * IMPORTANT NOTE: This is part of the WIP Keymapper. If you plan to use
+ * this, please talk to tsoliman and/or LordHoto.
*
- * @return HardwareKeySet with all keys and recommended mappings
+ * @return Keymap with actions appropriate for the platform
+ *
+ * The caller will use and delete the return object.
*
* See keymapper documentation for further reference.
*/
- virtual Common::HardwareKeySet *getHardwareKeySet() { return 0; }
+ virtual Common::Keymap *getGlobalKeymap() { return 0; }
+ /**
+ * Return platform-specific default keybindings
+ * IMPORTANT NOTE: This is part of the WIP Keymapper. If you plan to use
+ * this, please talk to tsoliman and/or LordHoto.
+ *
+ * @return KeymapperDefaultBindings populated with keybindings
+ *
+ * See keymapper documentation for further reference.
+ */
+ virtual Common::KeymapperDefaultBindings *getKeymapperDefaultBindings() { return 0; }
+#endif
//@}
diff --git a/common/translation.cpp b/common/translation.cpp
index 3570e8c5ae..219fce8794 100644
--- a/common/translation.cpp
+++ b/common/translation.cpp
@@ -26,7 +26,7 @@
#undef ARRAYSIZE
#endif
-#define TRANSLATIONS_DAT_VER 2
+#define TRANSLATIONS_DAT_VER 3
#include "common/translation.h"
#include "common/config-manager.h"
@@ -45,7 +45,7 @@ bool operator<(const TLanguage &l, const TLanguage &r) {
return strcmp(l.name, r.name) < 0;
}
-TranslationManager::TranslationManager() : _currentLang(-1) {
+TranslationManager::TranslationManager() : _currentLang(-1), _charmap(0) {
loadTranslationsInfoDat();
// Set the default language
@@ -53,6 +53,7 @@ TranslationManager::TranslationManager() : _currentLang(-1) {
}
TranslationManager::~TranslationManager() {
+ delete[] _charmap;
}
int32 TranslationManager::findMatchingLanguage(const String &lang) {
@@ -130,14 +131,14 @@ const char *TranslationManager::getTranslation(const char *message, const char *
// Get the range of messages with the same ID (but different context)
leftIndex = rightIndex = midIndex;
while (
- leftIndex > 0 &&
- _currentTranslationMessages[leftIndex - 1].msgid == m->msgid
+ leftIndex > 0 &&
+ _currentTranslationMessages[leftIndex - 1].msgid == m->msgid
) {
--leftIndex;
}
while (
- rightIndex < (int)_currentTranslationMessages.size() - 1 &&
- _currentTranslationMessages[rightIndex + 1].msgid == m->msgid
+ rightIndex < (int)_currentTranslationMessages.size() - 1 &&
+ _currentTranslationMessages[rightIndex + 1].msgid == m->msgid
) {
++rightIndex;
}
@@ -222,7 +223,7 @@ String TranslationManager::getLangById(int id) const {
return "";
}
-bool TranslationManager::openTranslationsFile(File& inFile) {
+bool TranslationManager::openTranslationsFile(File &inFile) {
// First look in the Themepath if we can find the file.
if (ConfMan.hasKey("themepath") && openTranslationsFile(FSNode(ConfMan.get("themepath")), inFile))
return true;
@@ -242,7 +243,7 @@ bool TranslationManager::openTranslationsFile(File& inFile) {
return false;
}
-bool TranslationManager::openTranslationsFile(const FSNode &node, File& inFile, int depth) {
+bool TranslationManager::openTranslationsFile(const FSNode &node, File &inFile, int depth) {
if (!node.exists() || !node.isReadable() || !node.isDirectory())
return false;
@@ -289,9 +290,14 @@ void TranslationManager::loadTranslationsInfoDat() {
// Get number of translations
int nbTranslations = in.readUint16BE();
- // Skip all the block sizes
- for (int i = 0; i < nbTranslations + 2; ++i)
- in.readUint16BE();
+ // Get number of codepages
+ int nbCodepages = in.readUint16BE();
+
+ // Determine where the codepages start
+ _charmapStart = 0;
+ for (int i = 0; i < nbTranslations + 3; ++i)
+ _charmapStart += in.readUint16BE();
+ _charmapStart += in.pos();
// Read list of languages
_langs.resize(nbTranslations);
@@ -305,6 +311,14 @@ void TranslationManager::loadTranslationsInfoDat() {
_langNames[i] = String(buf, len - 1);
}
+ // Read list of codepages
+ _charmaps.resize(nbCodepages);
+ for (int i = 0; i < nbCodepages; ++i) {
+ len = in.readUint16BE();
+ in.read(buf, len);
+ _charmaps[i] = String(buf, len - 1);
+ }
+
// Read messages
int numMessages = in.readUint16BE();
_messageIds.resize(numMessages);
@@ -344,9 +358,16 @@ void TranslationManager::loadLanguageDat(int index) {
return;
}
+ // Get the number of codepages
+ int nbCodepages = in.readUint16BE();
+ if (nbCodepages != (int)_charmaps.size()) {
+ warning("The 'translations.dat' file has changed since starting ScummVM. GUI translation will not be available");
+ return;
+ }
+
// Get size of blocks to skip.
int skipSize = 0;
- for (int i = 0; i < index + 2; ++i)
+ for (int i = 0; i < index + 3; ++i)
skipSize += in.readUint16BE();
// We also need to skip the remaining block sizes
skipSize += 2 * (nbTranslations - index);
@@ -380,6 +401,29 @@ void TranslationManager::loadLanguageDat(int index) {
_currentTranslationMessages[i].msgctxt = String(buf, len - 1);
}
}
+
+ // Find the charset
+ int charmapNum = -1;
+ for (uint i = 0; i < _charmaps.size(); ++i) {
+ if (_charmaps[i].equalsIgnoreCase(_currentCharset)) {
+ charmapNum = i;
+ break;
+ }
+ }
+
+ // Setup the new charset mapping
+ if (charmapNum == -1) {
+ delete[] _charmap;
+ _charmap = 0;
+ } else {
+ if (!_charmap)
+ _charmap = new uint32[256];
+
+ in.seek(_charmapStart + charmapNum * 256 * 4, SEEK_SET);
+ for (int i = 0; i < 256; ++i)
+ _charmap[i] = in.readUint32BE();
+ }
+
}
bool TranslationManager::checkHeader(File &in) {
@@ -390,7 +434,7 @@ bool TranslationManager::checkHeader(File &in) {
buf[12] = '\0';
// Check header
- if (strcmp(buf, "TRANSLATIONS")) {
+ if (strcmp(buf, "TRANSLATIONS") != 0) {
warning("File '%s' is not a valid translations data file. Skipping this file", in.getName());
return false;
}
diff --git a/common/translation.h b/common/translation.h
index 9e5245702e..77e2fdfc07 100644
--- a/common/translation.h
+++ b/common/translation.h
@@ -154,6 +154,21 @@ public:
String getCurrentCharset() const;
/**
+ * Returns a pointer to the current charset mapping. This mapping is a
+ * codepage encoding -> unicode mapping and always 256 entries long.
+ *
+ * The MSB of the individual mapped (i.e. unicode) character states
+ * whether the character is required for this charset. If it is set, the
+ * character needs to be present in order to have the text displayed.
+ * This is used in the font loading code to detect whether the font is
+ * able of supporting this language.
+ *
+ * The return value might be 0 in case it's a default ASCII/ISO-8859-1
+ * map.
+ */
+ const uint32 *getCharsetMapping() const { return _charmap; }
+
+ /**
* Returns currently selected translation language
*/
String getCurrentLanguage() const;
@@ -173,13 +188,13 @@ private:
* then if needed using the Themepath. If found it opens the given File
* to read the translations.dat file.
*/
- bool openTranslationsFile(File&);
+ bool openTranslationsFile(File &);
/**
* Find the translations.dat file in the given directory node.
* If found it opens the given File to read the translations.dat file.
*/
- bool openTranslationsFile(const FSNode &node, File&, int depth = -1);
+ bool openTranslationsFile(const FSNode &node, File &, int depth = -1);
/**
* Load the list of languages from the translations.dat file
@@ -200,11 +215,15 @@ private:
StringArray _langs;
StringArray _langNames;
+ StringArray _charmaps;
StringArray _messageIds;
Array<PoMessageEntry> _currentTranslationMessages;
String _currentCharset;
int _currentLang;
+
+ uint32 _charmapStart;
+ uint32 *_charmap;
};
} // End of namespace Common
diff --git a/common/unarj.cpp b/common/unarj.cpp
index cccc330bb5..fe3c17a2ac 100644
--- a/common/unarj.cpp
+++ b/common/unarj.cpp
@@ -701,9 +701,9 @@ public:
virtual ~ArjArchive();
// Archive implementation
- virtual bool hasFile(const String &name);
- virtual int listMembers(ArchiveMemberList &list);
- virtual ArchiveMemberPtr getMember(const String &name);
+ virtual bool hasFile(const String &name) const;
+ virtual int listMembers(ArchiveMemberList &list) const;
+ virtual const ArchiveMemberPtr getMember(const String &name) const;
virtual SeekableReadStream *createReadStreamForMember(const String &name) const;
};
@@ -745,14 +745,14 @@ ArjArchive::~ArjArchive() {
}
}
-bool ArjArchive::hasFile(const String &name) {
+bool ArjArchive::hasFile(const String &name) const {
return _headers.contains(name);
}
-int ArjArchive::listMembers(ArchiveMemberList &list) {
+int ArjArchive::listMembers(ArchiveMemberList &list) const {
int matches = 0;
- ArjHeadersMap::iterator it = _headers.begin();
+ ArjHeadersMap::const_iterator it = _headers.begin();
for ( ; it != _headers.end(); ++it) {
list.push_back(ArchiveMemberList::value_type(new GenericArchiveMember(it->_value->filename, this)));
matches++;
@@ -761,7 +761,7 @@ int ArjArchive::listMembers(ArchiveMemberList &list) {
return matches;
}
-ArchiveMemberPtr ArjArchive::getMember(const String &name) {
+const ArchiveMemberPtr ArjArchive::getMember(const String &name) const {
if (!hasFile(name))
return ArchiveMemberPtr();
diff --git a/common/unzip.cpp b/common/unzip.cpp
index 8650c91866..8cfcd605fa 100644
--- a/common/unzip.cpp
+++ b/common/unzip.cpp
@@ -111,7 +111,7 @@ typedef struct {
#if defined(STRICTUNZIP) || defined(STRICTZIPUNZIP)
/* like the STRICT of WIN32, we define a pointer that cannot be converted
- from (void*) without cast */
+ from (void *) without cast */
typedef struct TagunzFile__ { int unused; } unzFile__;
typedef unzFile__ *unzFile;
#else
@@ -1062,7 +1062,7 @@ int unzOpenCurrentFile (unzFile file) {
if (pfile_in_zip_read_info==NULL)
return UNZ_INTERNALERROR;
- pfile_in_zip_read_info->read_buffer=(char*)malloc(UNZ_BUFSIZE);
+ pfile_in_zip_read_info->read_buffer=(char *)malloc(UNZ_BUFSIZE);
pfile_in_zip_read_info->offset_local_extrafield = offset_local_extrafield;
pfile_in_zip_read_info->size_local_extrafield = size_local_extrafield;
pfile_in_zip_read_info->pos_local_extrafield=0;
@@ -1151,7 +1151,7 @@ int unzReadCurrentFile(unzFile file, voidp buf, unsigned len) {
if (len==0)
return 0;
- pfile_in_zip_read_info->stream.next_out = (Bytef*)buf;
+ pfile_in_zip_read_info->stream.next_out = (Bytef *)buf;
pfile_in_zip_read_info->stream.avail_out = (uInt)len;
@@ -1177,7 +1177,7 @@ int unzReadCurrentFile(unzFile file, voidp buf, unsigned len) {
pfile_in_zip_read_info->rest_read_compressed-=uReadThis;
- pfile_in_zip_read_info->stream.next_in = (Bytef*)pfile_in_zip_read_info->read_buffer;
+ pfile_in_zip_read_info->stream.next_in = (Bytef *)pfile_in_zip_read_info->read_buffer;
pfile_in_zip_read_info->stream.avail_in = (uInt)uReadThis;
}
@@ -1426,9 +1426,9 @@ public:
~ZipArchive();
- virtual bool hasFile(const String &name);
- virtual int listMembers(ArchiveMemberList &list);
- virtual ArchiveMemberPtr getMember(const String &name);
+ virtual bool hasFile(const String &name) const;
+ virtual int listMembers(ArchiveMemberList &list) const;
+ virtual const ArchiveMemberPtr getMember(const String &name) const;
virtual SeekableReadStream *createReadStreamForMember(const String &name) const;
};
@@ -1458,11 +1458,11 @@ ZipArchive::~ZipArchive() {
unzClose(_zipFile);
}
-bool ZipArchive::hasFile(const String &name) {
+bool ZipArchive::hasFile(const String &name) const {
return (unzLocateFile(_zipFile, name.c_str(), 2) == UNZ_OK);
}
-int ZipArchive::listMembers(ArchiveMemberList &list) {
+int ZipArchive::listMembers(ArchiveMemberList &list) const {
int matches = 0;
int err = unzGoToFirstFile(_zipFile);
@@ -1481,7 +1481,7 @@ int ZipArchive::listMembers(ArchiveMemberList &list) {
return matches;
}
-ArchiveMemberPtr ZipArchive::getMember(const String &name) {
+const ArchiveMemberPtr ZipArchive::getMember(const String &name) const {
if (!hasFile(name))
return ArchiveMemberPtr();
diff --git a/common/util.cpp b/common/util.cpp
index bd2ebc4937..4d9ff11c5c 100644
--- a/common/util.cpp
+++ b/common/util.cpp
@@ -19,9 +19,16 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
+#define FORBIDDEN_SYMBOL_EXCEPTION_isalnum
+#define FORBIDDEN_SYMBOL_EXCEPTION_isalpha
+#define FORBIDDEN_SYMBOL_EXCEPTION_isdigit
+#define FORBIDDEN_SYMBOL_EXCEPTION_isnumber
+#define FORBIDDEN_SYMBOL_EXCEPTION_islower
+#define FORBIDDEN_SYMBOL_EXCEPTION_isspace
+#define FORBIDDEN_SYMBOL_EXCEPTION_isupper
+
+
#include "common/util.h"
-#include "common/translation.h"
-#include "common/config-manager.h"
#include "common/debug.h"
namespace Common {
@@ -103,303 +110,38 @@ bool parseBool(const String &val, bool &valAsBool) {
#pragma mark -
-const LanguageDescription g_languages[] = {
- { "zh-cn", "zh_CN", "Chinese (China)", ZH_CNA },
- { "zh", "zh_TW", "Chinese (Taiwan)", ZH_TWN },
- { "cz", "cs_CZ", "Czech", CZ_CZE },
- { "nl", "nl_NL", "Dutch", NL_NLD },
- { "en", "en", "English", EN_ANY }, // Generic English (when only one game version exist)
- { "gb", "en_GB", "English (GB)", EN_GRB },
- { "us", "en_US", "English (US)", EN_USA },
- { "fr", "fr_FR", "French", FR_FRA },
- { "de", "de_DE", "German", DE_DEU },
- { "gr", "el_GR", "Greek", GR_GRE },
- { "he", "he_IL", "Hebrew", HE_ISR },
- { "hb", "he_IL", "Hebrew", HE_ISR }, // Deprecated
- { "hu", "hu_HU", "Hungarian", HU_HUN },
- { "it", "it_IT", "Italian", IT_ITA },
- { "jp", "ja_JP", "Japanese", JA_JPN },
- { "kr", "ko_KR", "Korean", KO_KOR },
- { "nb", "nb_NO", "Norwegian Bokm\xE5l", NB_NOR }, // TODO Someone should verify the unix locale
- { "pl", "pl_PL", "Polish", PL_POL },
- { "br", "pt_BR", "Portuguese", PT_BRA },
- { "ru", "ru_RU", "Russian", RU_RUS },
- { "es", "es_ES", "Spanish", ES_ESP },
- { "se", "sv_SE", "Swedish", SE_SWE },
- { 0, 0, 0, UNK_LANG }
-};
-
-Language parseLanguage(const String &str) {
- if (str.empty())
- return UNK_LANG;
-
- const LanguageDescription *l = g_languages;
- for (; l->code; ++l) {
- if (str.equalsIgnoreCase(l->code))
- return l->id;
- }
-
- return UNK_LANG;
-}
-
-Language parseLanguageFromLocale(const char *locale) {
- if (!locale || !*locale)
- return UNK_LANG;
-
- const LanguageDescription *l = g_languages;
- for (; l->code; ++l) {
- if (!strcmp(l->unixLocale, locale))
- return l->id;
- }
-
- return UNK_LANG;
-}
-
-const char *getLanguageCode(Language id) {
- const LanguageDescription *l = g_languages;
- for (; l->code; ++l) {
- if (l->id == id)
- return l->code;
- }
- return 0;
-}
-
-const char *getLanguageLocale(Language id) {
- const LanguageDescription *l = g_languages;
- for (; l->code; ++l) {
- if (l->id == id)
- return l->unixLocale;
- }
- return 0;
-}
-
-const char *getLanguageDescription(Language id) {
- const LanguageDescription *l = g_languages;
- for (; l->code; ++l) {
- if (l->id == id)
- return l->description;
- }
- return 0;
-}
-
-
-#pragma mark -
-
-
-const PlatformDescription g_platforms[] = {
- { "2gs", "2gs", "2gs", "Apple IIgs", kPlatformApple2GS },
- { "3do", "3do", "3do", "3DO", kPlatform3DO },
- { "acorn", "acorn", "acorn", "Acorn", kPlatformAcorn },
- { "amiga", "ami", "amiga", "Amiga", kPlatformAmiga },
- { "atari", "atari-st", "st", "Atari ST", kPlatformAtariST },
- { "c64", "c64", "c64", "Commodore 64", kPlatformC64 },
- { "pc", "dos", "ibm", "DOS", kPlatformPC },
- { "pc98", "pc98", "pc98", "PC-98", kPlatformPC98 },
- { "wii", "wii", "wii", "Nintendo Wii", kPlatformWii },
- { "coco3", "coco3", "coco3", "CoCo3", kPlatformCoCo3 },
-
- // The 'official' spelling seems to be "FM-TOWNS" (e.g. in the Indy4 demo).
- // However, on the net many variations can be seen, like "FMTOWNS",
- // "FM TOWNS", "FmTowns", etc.
- { "fmtowns", "towns", "fm", "FM-TOWNS", kPlatformFMTowns },
-
- { "linux", "linux", "linux", "Linux", kPlatformLinux },
- { "macintosh", "mac", "mac", "Macintosh", kPlatformMacintosh },
- { "pce", "pce", "pce", "PC-Engine", kPlatformPCEngine },
- { "nes", "nes", "nes", "NES", kPlatformNES },
- { "segacd", "segacd", "sega", "SegaCD", kPlatformSegaCD },
- { "windows", "win", "win", "Windows", kPlatformWindows },
- { "playstation", "psx", "psx", "Sony PlayStation", kPlatformPSX },
- { "cdi", "cdi", "cdi", "Philips CD-i", kPlatformCDi },
- { "ios", "ios", "ios", "Apple iOS", kPlatformIOS },
-
- { 0, 0, 0, "Default", kPlatformUnknown }
-};
-
-Platform parsePlatform(const String &str) {
- if (str.empty())
- return kPlatformUnknown;
-
- // Handle some special case separately, for compatibility with old config
- // files.
- if (str == "1")
- return kPlatformAmiga;
- else if (str == "2")
- return kPlatformAtariST;
- else if (str == "3")
- return kPlatformMacintosh;
-
- const PlatformDescription *l = g_platforms;
- for (; l->code; ++l) {
- if (str.equalsIgnoreCase(l->code) || str.equalsIgnoreCase(l->code2) || str.equalsIgnoreCase(l->abbrev))
- return l->id;
- }
-
- return kPlatformUnknown;
-}
-
-
-const char *getPlatformCode(Platform id) {
- const PlatformDescription *l = g_platforms;
- for (; l->code; ++l) {
- if (l->id == id)
- return l->code;
- }
- return 0;
-}
-
-const char *getPlatformAbbrev(Platform id) {
- const PlatformDescription *l = g_platforms;
- for (; l->code; ++l) {
- if (l->id == id)
- return l->abbrev;
- }
- return 0;
-}
-
-const char *getPlatformDescription(Platform id) {
- const PlatformDescription *l = g_platforms;
- for (; l->code; ++l) {
- if (l->id == id)
- return l->description;
- }
- return l->description;
-}
-
-
-#pragma mark -
-
-
-const RenderModeDescription g_renderModes[] = {
- // I18N: Hercules is graphics card name
- { "hercGreen", _s("Hercules Green"), kRenderHercG },
- { "hercAmber", _s("Hercules Amber"), kRenderHercA },
- { "cga", "CGA", kRenderCGA },
- { "ega", "EGA", kRenderEGA },
- { "amiga", "Amiga", kRenderAmiga },
- {0, 0, kRenderDefault}
-};
-
-DECLARE_TRANSLATION_ADDITIONAL_CONTEXT("Hercules Green", "lowres")
-DECLARE_TRANSLATION_ADDITIONAL_CONTEXT("Hercules Amber", "lowres")
-
-RenderMode parseRenderMode(const String &str) {
- if (str.empty())
- return kRenderDefault;
+#define ENSURE_ASCII_CHAR(c) \
+ if (c < 0 || c > 127) \
+ return false
- const RenderModeDescription *l = g_renderModes;
- for (; l->code; ++l) {
- if (str.equalsIgnoreCase(l->code))
- return l->id;
- }
-
- return kRenderDefault;
+bool isAlnum(int c) {
+ ENSURE_ASCII_CHAR(c);
+ return isalnum((byte)c);
}
-const char *getRenderModeCode(RenderMode id) {
- const RenderModeDescription *l = g_renderModes;
- for (; l->code; ++l) {
- if (l->id == id)
- return l->code;
- }
- return 0;
+bool isAlpha(int c) {
+ ENSURE_ASCII_CHAR(c);
+ return isalpha((byte)c);
}
-const char *getRenderModeDescription(RenderMode id) {
- const RenderModeDescription *l = g_renderModes;
- for (; l->code; ++l) {
- if (l->id == id)
- return l->description;
- }
- return 0;
+bool isDigit(int c) {
+ ENSURE_ASCII_CHAR(c);
+ return isdigit((byte)c);
}
-const struct GameOpt {
- const char *option;
- const char *desc;
-} g_gameOptions[] = {
- { GUIO_NOSUBTITLES, "sndNoSubs" },
- { GUIO_NOMUSIC, "sndNoMusic" },
- { GUIO_NOSPEECH, "sndNoSpeech" },
- { GUIO_NOSFX, "sndNoSFX" },
- { GUIO_NOMIDI, "sndNoMIDI" },
-
- { GUIO_NOLAUNCHLOAD, "launchNoLoad" },
-
- { GUIO_MIDIPCSPK, "midiPCSpk" },
- { GUIO_MIDICMS, "midiCMS" },
- { GUIO_MIDIPCJR, "midiPCJr" },
- { GUIO_MIDIADLIB, "midiAdLib" },
- { GUIO_MIDIC64, "midiC64" },
- { GUIO_MIDIAMIGA, "midiAmiga" },
- { GUIO_MIDIAPPLEIIGS,"midiAppleIIgs" },
- { GUIO_MIDITOWNS, "midiTowns" },
- { GUIO_MIDIPC98, "midiPC98" },
- { GUIO_MIDIMT32, "midiMt32" },
- { GUIO_MIDIGM, "midiGM" },
-
- { GUIO_NONE, 0 }
-};
-
-bool checkGameGUIOption(const String &option, const String &str) {
- for (int i = 0; g_gameOptions[i].desc; i++) {
- if (option.contains(g_gameOptions[i].option)) {
- if (str.contains(g_gameOptions[i].desc))
- return true;
- else
- return false;
- }
- }
- return false;
-}
-
-bool checkGameGUIOptionLanguage(Language lang, const String &str) {
- if (!str.contains("lang_")) // If no languages are specified
- return true;
-
- if (str.contains(getGameGUIOptionsDescriptionLanguage(lang)))
- return true;
-
- return false;
-}
-
-const String getGameGUIOptionsDescriptionLanguage(Language lang) {
- if (lang == UNK_LANG)
- return "";
-
- return String(String("lang_") + getLanguageDescription(lang));
-}
-
-String parseGameGUIOptions(const String &str) {
- Common::String res;
-
- for (int i = 0; g_gameOptions[i].desc; i++)
- if (str.contains(g_gameOptions[i].desc))
- res += g_gameOptions[i].option;
-
- return res;
+bool isLower(int c) {
+ ENSURE_ASCII_CHAR(c);
+ return islower((byte)c);
}
-const String getGameGUIOptionsDescription(const String &options) {
- String res = "";
-
- for (int i = 0; g_gameOptions[i].desc; i++)
- if (options.contains(g_gameOptions[i].option[0]))
- res += String(g_gameOptions[i].desc) + " ";
-
- res.trim();
-
- return res;
+bool isSpace(int c) {
+ ENSURE_ASCII_CHAR(c);
+ return isspace((byte)c);
}
-void updateGameGUIOptions(const String &options, const String &langOption) {
- const String newOptionString = getGameGUIOptionsDescription(options) + " " + langOption;
-
- if ((!options.empty() && !ConfMan.hasKey("guioptions")) ||
- (ConfMan.hasKey("guioptions") && ConfMan.get("guioptions") != newOptionString)) {
- ConfMan.set("guioptions", newOptionString);
- ConfMan.flushToDisk();
- }
+bool isUpper(int c) {
+ ENSURE_ASCII_CHAR(c);
+ return isupper((byte)c);
}
} // End of namespace Common
diff --git a/common/util.h b/common/util.h
index bad07d4cb2..b90be0675b 100644
--- a/common/util.h
+++ b/common/util.h
@@ -25,7 +25,6 @@
#include "common/scummsys.h"
#include "common/str.h"
-
/**
* Check whether a given pointer is aligned correctly.
* Note that 'alignment' must be a power of two!
@@ -78,32 +77,6 @@ template<typename T> inline void SWAP(T &a, T &b) { T tmp = a; a = b; b = tmp; }
# define SCUMMVM_CURRENT_FUNCTION "<unknown>"
#endif
-#define GUIO_NONE "\000"
-#define GUIO_NOSUBTITLES "\001"
-#define GUIO_NOMUSIC "\002"
-#define GUIO_NOSPEECH "\003"
-#define GUIO_NOSFX "\003"
-#define GUIO_NOMIDI "\004"
-#define GUIO_NOLAUNCHLOAD "\005"
-
-#define GUIO_MIDIPCSPK "\006"
-#define GUIO_MIDICMS "\007"
-#define GUIO_MIDIPCJR "\010"
-#define GUIO_MIDIADLIB "\011"
-#define GUIO_MIDIC64 "\012"
-#define GUIO_MIDIAMIGA "\013"
-#define GUIO_MIDIAPPLEIIGS "\014"
-#define GUIO_MIDITOWNS "\015"
-#define GUIO_MIDIPC98 "\016"
-#define GUIO_MIDIMT32 "\017"
-#define GUIO_MIDIGM "\020"
-
-#define GUIO1(a) (a)
-#define GUIO2(a,b) (a b)
-#define GUIO3(a,b,c) (a b c)
-#define GUIO4(a,b,c,d) (a b c d)
-#define GUIO5(a,b,c,d,e) (a b c d e)
-
namespace Common {
/**
@@ -129,139 +102,68 @@ extern void hexdump(const byte * data, int len, int bytesPerLine = 16, int start
*/
bool parseBool(const String &val, bool &valAsBool);
+
/**
- * List of game language.
+ * Test whether the given character is alphanumeric (a-z, A-Z, 0-9).
+ * If the parameter is outside the range of a signed or unsigned char, then
+ * false is returned.
+ *
+ * @param c the character to test
+ * @return true if the character is alphanumeric, false otherwise.
*/
-enum Language {
- ZH_CNA,
- ZH_TWN,
- CZ_CZE,
- NL_NLD,
- EN_ANY, // Generic English (when only one game version exist)
- EN_GRB,
- EN_USA,
- FR_FRA,
- DE_DEU,
- GR_GRE,
- HE_ISR,
- HU_HUN,
- IT_ITA,
- JA_JPN,
- KO_KOR,
- NB_NOR,
- PL_POL,
- PT_BRA,
- RU_RUS,
- ES_ESP,
- SE_SWE,
-
- UNK_LANG = -1 // Use default language (i.e. none specified)
-};
-
-struct LanguageDescription {
- const char *code;
- const char *unixLocale;
- const char *description;
- Language id;
-};
-
-extern const LanguageDescription g_languages[];
-
-
-/** Convert a string containing a language name into a Language enum value. */
-extern Language parseLanguage(const String &str);
-extern Language parseLanguageFromLocale(const char *locale);
-extern const char *getLanguageCode(Language id);
-extern const char *getLanguageLocale(Language id);
-extern const char *getLanguageDescription(Language id);
+bool isAlnum(int c);
/**
- * List of game platforms. Specifying a platform for a target can be used to
- * give the game engines a hint for which platform the game data file are.
- * This may be optional or required, depending on the game engine and the
- * game in question.
+ * Test whether the given character is an alphabetic letter (a-z, A-Z).
+ * If the parameter is outside the range of a signed or unsigned char, then
+ * false is returned.
+ *
+ * @param c the character to test
+ * @return true if the character is TODO, false otherwise.
*/
-enum Platform {
- kPlatformPC,
- kPlatformAmiga,
- kPlatformAtariST,
- kPlatformMacintosh,
- kPlatformFMTowns,
- kPlatformWindows,
- kPlatformNES,
- kPlatformC64,
- kPlatformCoCo3,
- kPlatformLinux,
- kPlatformAcorn,
- kPlatformSegaCD,
- kPlatform3DO,
- kPlatformPCEngine,
- kPlatformApple2GS,
- kPlatformPC98,
- kPlatformWii,
- kPlatformPSX,
- kPlatformCDi,
- kPlatformIOS,
-
- kPlatformUnknown = -1
-};
-
-struct PlatformDescription {
- const char *code;
- const char *code2;
- const char *abbrev;
- const char *description;
- Platform id;
-};
-
-extern const PlatformDescription g_platforms[];
-
-/** Convert a string containing a platform name into a Platform enum value. */
-extern Platform parsePlatform(const String &str);
-extern const char *getPlatformCode(Platform id);
-extern const char *getPlatformAbbrev(Platform id);
-extern const char *getPlatformDescription(Platform id);
+bool isAlpha(int c);
/**
- * List of render modes. It specifies which original graphics mode
- * to use. Some targets used postprocessing dithering routines for
- * reducing color depth of final image which let it to be rendered on
- * such low-level adapters as CGA or Hercules.
+ * Test whether the given character is a decimal-digit (0-9).
+ * If the parameter is outside the range of a signed or unsigned char, then
+ * false is returned.
+ *
+ * @param c the character to test
+ * @return true if the character is a decimal-digit, false otherwise.
*/
-enum RenderMode {
- kRenderDefault = 0,
- kRenderEGA = 1,
- kRenderCGA = 2,
- kRenderHercG = 3,
- kRenderHercA = 4,
- kRenderAmiga = 5
-};
-
-struct RenderModeDescription {
- const char *code;
- const char *description;
- RenderMode id;
-};
+bool isDigit(int c);
-extern const RenderModeDescription g_renderModes[];
-
-/** Convert a string containing a render mode name into a RenderingMode enum value. */
-extern RenderMode parseRenderMode(const String &str);
-extern const char *getRenderModeCode(RenderMode id);
-extern const char *getRenderModeDescription(RenderMode id);
+/**
+ * Test whether the given character is a lower-case letter (a-z).
+ * If the parameter is outside the range of a signed or unsigned char, then
+ * false is returned.
+ *
+ * @param c the character to test
+ * @return true if the character is a lower-case letter, false otherwise.
+ */
+bool isLower(int c);
-bool checkGameGUIOption(const String &option, const String &str);
-bool checkGameGUIOptionLanguage(Language lang, const String &str);
-String parseGameGUIOptions(const String &str);
-const String getGameGUIOptionsDescription(const String &options);
-const String getGameGUIOptionsDescriptionLanguage(Language lang);
+/**
+ * Test whether the given character is a white-space.
+ * White-space characters are ' ', '\t', '\r', '\n', '\v', '\f'.
+ *
+ * If the parameter is outside the range of a signed or unsigned char, then
+ * false is returned.
+ *
+ * @param c the character to test
+ * @return true if the character is a white-space, false otherwise.
+ */
+bool isSpace(int c);
/**
- * Updates the GUI options of the current config manager
- * domain, when they differ to the ones passed as
- * parameter.
+ * Test whether the given character is an upper-case letter (A-Z).
+ * If the parameter is outside the range of a signed or unsigned char, then
+ * false is returned.
+ *
+ * @param c the character to test
+ * @return true if the character is an upper-case letter, false otherwise.
*/
-void updateGameGUIOptions(const String &options, const String &langOption);
+bool isUpper(int c);
} // End of namespace Common
diff --git a/common/xmlparser.cpp b/common/xmlparser.cpp
index f768e44382..ea3d44cf87 100644
--- a/common/xmlparser.cpp
+++ b/common/xmlparser.cpp
@@ -39,7 +39,7 @@ XMLParser::~XMLParser() {
delete _XMLkeys;
delete _stream;
- for (List<XMLKeyLayout*>::iterator i = _layoutList.begin();
+ for (List<XMLKeyLayout *>::iterator i = _layoutList.begin();
i != _layoutList.end(); ++i)
delete *i;
@@ -263,7 +263,7 @@ bool XMLParser::vparseIntegerKey(const char *key, int count, va_list args) {
int *num_ptr;
while (count--) {
- while (isspace(static_cast<unsigned char>(*key)))
+ while (isSpace(*key))
key++;
num_ptr = va_arg(args, int*);
@@ -271,7 +271,7 @@ bool XMLParser::vparseIntegerKey(const char *key, int count, va_list args) {
key = parseEnd;
- while (isspace(static_cast<unsigned char>(*key)))
+ while (isSpace(*key))
key++;
if (count && *key++ != ',')
@@ -463,10 +463,10 @@ bool XMLParser::parse() {
}
bool XMLParser::skipSpaces() {
- if (!isspace(static_cast<unsigned char>(_char)))
+ if (!isSpace(_char))
return false;
- while (_char && isspace(static_cast<unsigned char>(_char)))
+ while (_char && isSpace(_char))
_char = _stream->readByte();
return true;
@@ -516,7 +516,7 @@ bool XMLParser::parseToken() {
_char = _stream->readByte();
}
- return isspace(static_cast<unsigned char>(_char)) != 0 || _char == '>' || _char == '=' || _char == '/';
+ return isSpace(_char) != 0 || _char == '>' || _char == '=' || _char == '/';
}
} // End of namespace Common
diff --git a/common/xmlparser.h b/common/xmlparser.h
index 93433b7132..1e474b596c 100644
--- a/common/xmlparser.h
+++ b/common/xmlparser.h
@@ -68,9 +68,9 @@ class SeekableReadStream;
struct CustomXMLKeyLayout : public XMLKeyLayout {\
typedef bool (parserName::*ParserCallback)(ParserNode *node);\
ParserCallback callback;\
- bool doCallback(XMLParser *parent, ParserNode *node) {return ((kLocalParserName*)parent->*callback)(node);} };\
+ bool doCallback(XMLParser *parent, ParserNode *node) {return ((kLocalParserName *)parent->*callback)(node);} };\
virtual void buildLayout() { \
- Common::Stack<XMLKeyLayout*> layout; \
+ Common::Stack<XMLKeyLayout *> layout; \
CustomXMLKeyLayout *lay = 0; \
XMLKeyLayout::XMLKeyProperty prop; \
_XMLkeys = new CustomXMLKeyLayout; \
@@ -295,7 +295,7 @@ protected:
* in their name.
*/
virtual inline bool isValidNameChar(char c) {
- return isalnum(static_cast<unsigned char>(c)) || c == '_';
+ return isAlnum(c) || c == '_';
}
/**
@@ -334,7 +334,7 @@ protected:
*/
virtual void cleanup() {}
- List<XMLKeyLayout*> _layoutList;
+ List<XMLKeyLayout *> _layoutList;
private:
char _char;
@@ -346,7 +346,7 @@ private:
String _error; /** Current error message */
String _token; /** Current text token */
- Stack<ParserNode*> _activeKey; /** Node stack of the parsed keys */
+ Stack<ParserNode *> _activeKey; /** Node stack of the parsed keys */
};
} // End of namespace Common
diff --git a/common/zlib.cpp b/common/zlib.cpp
index 70133fea30..7d765fc539 100644
--- a/common/zlib.cpp
+++ b/common/zlib.cpp
@@ -49,7 +49,7 @@ bool uncompress(byte *dst, unsigned long *dstLen, const byte *src, unsigned long
return Z_OK == ::uncompress(dst, dstLen, src, srcLen);
}
-bool inflateZlibHeaderless(byte *dst, uint dstLen, const byte *src, uint srcLen) {
+bool inflateZlibHeaderless(byte *dst, uint dstLen, const byte *src, uint srcLen, const byte *dict, uint dictLen) {
if (!dst || !dstLen || !src || !srcLen)
return false;
@@ -68,6 +68,13 @@ bool inflateZlibHeaderless(byte *dst, uint dstLen, const byte *src, uint srcLen)
if (err != Z_OK)
return false;
+ // Set the dictionary, if provided
+ if (dict != 0) {
+ err = inflateSetDictionary(&stream, const_cast<byte *>(dict), dictLen);
+ if (err != Z_OK)
+ return false;
+ }
+
err = inflate(&stream, Z_SYNC_FLUSH);
if (err != Z_OK && err != Z_STREAM_END) {
inflateEnd(&stream);
diff --git a/common/zlib.h b/common/zlib.h
index 7af7df0da8..61322c286a 100644
--- a/common/zlib.h
+++ b/common/zlib.h
@@ -37,7 +37,19 @@ class WriteStream;
* it possible to uncompress data in engines without being forced to link
* them against zlib, thus simplifying the build system.
*
- * @return true on success (i.e. Z_OK), false otherwise
+ * Taken from the zlib manual:
+ * Decompresses the src buffer into the dst buffer.
+ * srcLen is the byte length of the source buffer. Upon entry, dstLen is the
+ * total size of the destination buffer, which must be large enough to hold
+ * the entire uncompressed data. Upon exit, dstLen is the actual size of the
+ * compressed buffer.
+ *
+ * @param dst the buffer to store into.
+ * @param dstLen a pointer to the size of the destination buffer.
+ * @param src the data to be decompressed.
+ * @param srcLen the size of the compressed data.
+ *
+ * @return true on success (i.e. Z_OK), false otherwise.
*/
bool uncompress(byte *dst, unsigned long *dstLen, const byte *src, unsigned long srcLen);
@@ -46,9 +58,24 @@ bool uncompress(byte *dst, unsigned long *dstLen, const byte *src, unsigned long
* necessary inflate functions to uncompress data compressed with deflate
* but *not* with the standard zlib header.
*
- * @return true on success (Z_OK or Z_STREAM_END), false otherwise
+ * Decompresses the src buffer into the dst buffer.
+ * srcLen is the byte length of the source buffer, dstLen is the byte
+ * length of the output buffer.
+ * It decompress as much data as possible, up to dstLen bytes.
+ * If a dictionary is provided through the dict buffer, uses it to initializes
+ * the internal decompression dictionary, before the decompression takes place.
+ *
+ * @param dst the buffer to store into.
+ * @param dstLen the size of the destination buffer.
+ * @param src the data to be decompressed.
+ * @param dstLen the size of the compressed data.
+ * @param dict (optional) a decompress dictionary.
+ * @param dictLen (optional) the size of the dictionary.
+ * Mandatory if dict is not 0.
+ *
+ * @return true on success (Z_OK or Z_STREAM_END), false otherwise.
*/
-bool inflateZlibHeaderless(byte *dst, uint dstLen, const byte *src, uint srcLen);
+bool inflateZlibHeaderless(byte *dst, uint dstLen, const byte *src, uint srcLen, const byte *dict = 0, uint dictLen = 0);
#endif
diff --git a/config.guess b/config.guess
index 64cae2741b..43f0cdbcfd 100755
--- a/config.guess
+++ b/config.guess
@@ -1,10 +1,10 @@
#! /bin/sh
# Attempt to guess a canonical system name.
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
-# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
-# Free Software Foundation, Inc.
+# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
+# 2011 Free Software Foundation, Inc.
-timestamp='2009-12-13'
+timestamp='2011-10-01'
# This file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
@@ -56,8 +56,9 @@ version="\
GNU config.guess ($timestamp)
Originally written by Per Bothner.
-Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
-2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
+2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free
+Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
@@ -180,7 +181,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
fi
;;
*)
- os=netbsd
+ os=netbsd
;;
esac
# The OS release
@@ -223,7 +224,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
;;
*5.*)
- UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'`
+ UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'`
;;
esac
# According to Compaq, /usr/sbin/psrinfo has been available on
@@ -269,7 +270,10 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
# A Xn.n version is an unreleased experimental baselevel.
# 1.2 uses "1.2" for uname -r.
echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
- exit ;;
+ # Reset EXIT trap before exiting to avoid spurious non-zero exit code.
+ exitcode=$?
+ trap '' 0
+ exit $exitcode ;;
Alpha\ *:Windows_NT*:*)
# How do we know it's Interix rather than the generic POSIX subsystem?
# Should we change UNAME_MACHINE based on the output of uname instead
@@ -295,7 +299,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
echo s390-ibm-zvmoe
exit ;;
*:OS400:*:*)
- echo powerpc-ibm-os400
+ echo powerpc-ibm-os400
exit ;;
arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
echo arm-acorn-riscix${UNAME_RELEASE}
@@ -394,23 +398,23 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
# MiNT. But MiNT is downward compatible to TOS, so this should
# be no problem.
atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*)
- echo m68k-atari-mint${UNAME_RELEASE}
+ echo m68k-atari-mint${UNAME_RELEASE}
exit ;;
atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)
echo m68k-atari-mint${UNAME_RELEASE}
- exit ;;
+ exit ;;
*falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)
- echo m68k-atari-mint${UNAME_RELEASE}
+ echo m68k-atari-mint${UNAME_RELEASE}
exit ;;
milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)
- echo m68k-milan-mint${UNAME_RELEASE}
- exit ;;
+ echo m68k-milan-mint${UNAME_RELEASE}
+ exit ;;
hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)
- echo m68k-hades-mint${UNAME_RELEASE}
- exit ;;
+ echo m68k-hades-mint${UNAME_RELEASE}
+ exit ;;
*:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
- echo m68k-unknown-mint${UNAME_RELEASE}
- exit ;;
+ echo m68k-unknown-mint${UNAME_RELEASE}
+ exit ;;
m68k:machten:*:*)
echo m68k-apple-machten${UNAME_RELEASE}
exit ;;
@@ -480,8 +484,8 @@ EOF
echo m88k-motorola-sysv3
exit ;;
AViiON:dgux:*:*)
- # DG/UX returns AViiON for all architectures
- UNAME_PROCESSOR=`/usr/bin/uname -p`
+ # DG/UX returns AViiON for all architectures
+ UNAME_PROCESSOR=`/usr/bin/uname -p`
if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ]
then
if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \
@@ -494,7 +498,7 @@ EOF
else
echo i586-dg-dgux${UNAME_RELEASE}
fi
- exit ;;
+ exit ;;
M88*:DolphinOS:*:*) # DolphinOS (SVR3)
echo m88k-dolphin-sysv3
exit ;;
@@ -551,7 +555,7 @@ EOF
echo rs6000-ibm-aix3.2
fi
exit ;;
- *:AIX:*:[456])
+ *:AIX:*:[4567])
IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`
if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then
IBM_ARCH=rs6000
@@ -594,52 +598,52 @@ EOF
9000/[678][0-9][0-9])
if [ -x /usr/bin/getconf ]; then
sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
- sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
- case "${sc_cpu_version}" in
- 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0
- 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1
- 532) # CPU_PA_RISC2_0
- case "${sc_kernel_bits}" in
- 32) HP_ARCH="hppa2.0n" ;;
- 64) HP_ARCH="hppa2.0w" ;;
+ sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
+ case "${sc_cpu_version}" in
+ 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0
+ 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1
+ 532) # CPU_PA_RISC2_0
+ case "${sc_kernel_bits}" in
+ 32) HP_ARCH="hppa2.0n" ;;
+ 64) HP_ARCH="hppa2.0w" ;;
'') HP_ARCH="hppa2.0" ;; # HP-UX 10.20
- esac ;;
- esac
+ esac ;;
+ esac
fi
if [ "${HP_ARCH}" = "" ]; then
eval $set_cc_for_build
- sed 's/^ //' << EOF >$dummy.c
+ sed 's/^ //' << EOF >$dummy.c
- #define _HPUX_SOURCE
- #include <stdlib.h>
- #include <unistd.h>
+ #define _HPUX_SOURCE
+ #include <stdlib.h>
+ #include <unistd.h>
- int main ()
- {
- #if defined(_SC_KERNEL_BITS)
- long bits = sysconf(_SC_KERNEL_BITS);
- #endif
- long cpu = sysconf (_SC_CPU_VERSION);
+ int main ()
+ {
+ #if defined(_SC_KERNEL_BITS)
+ long bits = sysconf(_SC_KERNEL_BITS);
+ #endif
+ long cpu = sysconf (_SC_CPU_VERSION);
- switch (cpu)
- {
- case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
- case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
- case CPU_PA_RISC2_0:
- #if defined(_SC_KERNEL_BITS)
- switch (bits)
- {
- case 64: puts ("hppa2.0w"); break;
- case 32: puts ("hppa2.0n"); break;
- default: puts ("hppa2.0"); break;
- } break;
- #else /* !defined(_SC_KERNEL_BITS) */
- puts ("hppa2.0"); break;
- #endif
- default: puts ("hppa1.0"); break;
- }
- exit (0);
- }
+ switch (cpu)
+ {
+ case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
+ case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
+ case CPU_PA_RISC2_0:
+ #if defined(_SC_KERNEL_BITS)
+ switch (bits)
+ {
+ case 64: puts ("hppa2.0w"); break;
+ case 32: puts ("hppa2.0n"); break;
+ default: puts ("hppa2.0"); break;
+ } break;
+ #else /* !defined(_SC_KERNEL_BITS) */
+ puts ("hppa2.0"); break;
+ #endif
+ default: puts ("hppa1.0"); break;
+ }
+ exit (0);
+ }
EOF
(CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy`
test -z "$HP_ARCH" && HP_ARCH=hppa
@@ -730,22 +734,22 @@ EOF
exit ;;
C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
echo c1-convex-bsd
- exit ;;
+ exit ;;
C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
if getsysinfo -f scalar_acc
then echo c32-convex-bsd
else echo c2-convex-bsd
fi
- exit ;;
+ exit ;;
C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
echo c34-convex-bsd
- exit ;;
+ exit ;;
C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
echo c38-convex-bsd
- exit ;;
+ exit ;;
C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
echo c4-convex-bsd
- exit ;;
+ exit ;;
CRAY*Y-MP:*:*:*)
echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
exit ;;
@@ -769,14 +773,14 @@ EOF
exit ;;
F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
- FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
- FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
- echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
- exit ;;
+ FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+ FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
+ echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+ exit ;;
5000:UNIX_System_V:4.*:*)
- FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
- FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'`
- echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+ FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+ FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'`
+ echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
exit ;;
i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
@@ -788,13 +792,12 @@ EOF
echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
exit ;;
*:FreeBSD:*:*)
- case ${UNAME_MACHINE} in
- pc98)
- echo i386-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
+ UNAME_PROCESSOR=`/usr/bin/uname -p`
+ case ${UNAME_PROCESSOR} in
amd64)
echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
*)
- echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
+ echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
esac
exit ;;
i*:CYGWIN*:*)
@@ -804,14 +807,14 @@ EOF
echo ${UNAME_MACHINE}-pc-mingw32
exit ;;
i*:windows32*:*)
- # uname -m includes "-pc" on this system.
- echo ${UNAME_MACHINE}-mingw32
+ # uname -m includes "-pc" on this system.
+ echo ${UNAME_MACHINE}-mingw32
exit ;;
i*:PW*:*)
echo ${UNAME_MACHINE}-pc-pw32
exit ;;
*:Interix*:*)
- case ${UNAME_MACHINE} in
+ case ${UNAME_MACHINE} in
x86)
echo i586-pc-interix${UNAME_RELEASE}
exit ;;
@@ -866,7 +869,7 @@ EOF
EV6) UNAME_MACHINE=alphaev6 ;;
EV67) UNAME_MACHINE=alphaev67 ;;
EV68*) UNAME_MACHINE=alphaev68 ;;
- esac
+ esac
objdump --private-headers /bin/sh | grep -q ld.so.1
if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi
echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC}
@@ -878,7 +881,13 @@ EOF
then
echo ${UNAME_MACHINE}-unknown-linux-gnu
else
- echo ${UNAME_MACHINE}-unknown-linux-gnueabi
+ if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \
+ | grep -q __ARM_PCS_VFP
+ then
+ echo ${UNAME_MACHINE}-unknown-linux-gnueabi
+ else
+ echo ${UNAME_MACHINE}-unknown-linux-gnueabihf
+ fi
fi
exit ;;
avr32*:Linux:*:*)
@@ -891,7 +900,10 @@ EOF
echo crisv32-axis-linux-gnu
exit ;;
frv:Linux:*:*)
- echo frv-unknown-linux-gnu
+ echo frv-unknown-linux-gnu
+ exit ;;
+ hexagon:Linux:*:*)
+ echo hexagon-unknown-linux-gnu
exit ;;
i*86:Linux:*:*)
LIBC=gnu
@@ -959,7 +971,7 @@ EOF
echo ${UNAME_MACHINE}-ibm-linux
exit ;;
sh64*:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
exit ;;
sh*:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-gnu
@@ -967,6 +979,9 @@ EOF
sparc:Linux:*:* | sparc64:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-gnu
exit ;;
+ tile*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit ;;
vax:Linux:*:*)
echo ${UNAME_MACHINE}-dec-linux-gnu
exit ;;
@@ -974,7 +989,7 @@ EOF
echo x86_64-unknown-linux-gnu
exit ;;
xtensa*:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
exit ;;
i*86:DYNIX/ptx:4*:*)
# ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.
@@ -983,11 +998,11 @@ EOF
echo i386-sequent-sysv4
exit ;;
i*86:UNIX_SV:4.2MP:2.*)
- # Unixware is an offshoot of SVR4, but it has its own version
- # number series starting with 2...
- # I am not positive that other SVR4 systems won't match this,
+ # Unixware is an offshoot of SVR4, but it has its own version
+ # number series starting with 2...
+ # I am not positive that other SVR4 systems won't match this,
# I just have to hope. -- rms.
- # Use sysv4.2uw... so that sysv4* matches it.
+ # Use sysv4.2uw... so that sysv4* matches it.
echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
exit ;;
i*86:OS/2:*:*)
@@ -1019,7 +1034,7 @@ EOF
fi
exit ;;
i*86:*:5:[678]*)
- # UnixWare 7.x, OpenUNIX and OpenServer 6.
+ # UnixWare 7.x, OpenUNIX and OpenServer 6.
case `/bin/uname -X | grep "^Machine"` in
*486*) UNAME_MACHINE=i486 ;;
*Pentium) UNAME_MACHINE=i586 ;;
@@ -1047,13 +1062,13 @@ EOF
exit ;;
pc:*:*:*)
# Left here for compatibility:
- # uname -m prints for DJGPP always 'pc', but it prints nothing about
- # the processor, so we play safe by assuming i586.
+ # uname -m prints for DJGPP always 'pc', but it prints nothing about
+ # the processor, so we play safe by assuming i586.
# Note: whatever this is, it MUST be the same as what config.sub
# prints for the "djgpp" host, or else GDB configury will decide that
# this is a cross-build.
echo i586-pc-msdosdjgpp
- exit ;;
+ exit ;;
Intel:Mach:3*:*)
echo i386-pc-mach3
exit ;;
@@ -1088,8 +1103,8 @@ EOF
/bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
&& { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
- /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
- && { echo i486-ncr-sysv4; exit; } ;;
+ /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+ && { echo i486-ncr-sysv4; exit; } ;;
NCR*:*:4.2:* | MPRAS*:*:4.2:*)
OS_REL='.3'
test -r /etc/.relid \
@@ -1132,10 +1147,10 @@ EOF
echo ns32k-sni-sysv
fi
exit ;;
- PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
- # says <Richard.M.Bartel@ccMail.Census.GOV>
- echo i586-unisys-sysv4
- exit ;;
+ PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
+ # says <Richard.M.Bartel@ccMail.Census.GOV>
+ echo i586-unisys-sysv4
+ exit ;;
*:UNIX_System_V:4*:FTX*)
# From Gerald Hewes <hewes@openmarket.com>.
# How about differentiating between stratus architectures? -djm
@@ -1161,11 +1176,11 @@ EOF
exit ;;
R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)
if [ -d /usr/nec ]; then
- echo mips-nec-sysv${UNAME_RELEASE}
+ echo mips-nec-sysv${UNAME_RELEASE}
else
- echo mips-unknown-sysv${UNAME_RELEASE}
+ echo mips-unknown-sysv${UNAME_RELEASE}
fi
- exit ;;
+ exit ;;
BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only.
echo powerpc-be-beos
exit ;;
@@ -1230,6 +1245,9 @@ EOF
*:QNX:*:4*)
echo i386-pc-qnx
exit ;;
+ NEO-?:NONSTOP_KERNEL:*:*)
+ echo neo-tandem-nsk${UNAME_RELEASE}
+ exit ;;
NSE-?:NONSTOP_KERNEL:*:*)
echo nse-tandem-nsk${UNAME_RELEASE}
exit ;;
@@ -1275,13 +1293,13 @@ EOF
echo pdp10-unknown-its
exit ;;
SEI:*:*:SEIUX)
- echo mips-sei-seiux${UNAME_RELEASE}
+ echo mips-sei-seiux${UNAME_RELEASE}
exit ;;
*:DragonFly:*:*)
echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
exit ;;
*:*VMS:*:*)
- UNAME_MACHINE=`(uname -p) 2>/dev/null`
+ UNAME_MACHINE=`(uname -p) 2>/dev/null`
case "${UNAME_MACHINE}" in
A*) echo alpha-dec-vms ; exit ;;
I*) echo ia64-dec-vms ; exit ;;
@@ -1321,11 +1339,11 @@ main ()
#include <sys/param.h>
printf ("m68k-sony-newsos%s\n",
#ifdef NEWSOS4
- "4"
+ "4"
#else
- ""
+ ""
#endif
- ); exit (0);
+ ); exit (0);
#endif
#endif
diff --git a/config.sub b/config.sub
index 110a68e347..5b8736823d 100755
--- a/config.sub
+++ b/config.sub
@@ -1,10 +1,10 @@
#! /bin/sh
# Configuration validation subroutine script.
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
-# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
-# Free Software Foundation, Inc.
+# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
+# 2011 Free Software Foundation, Inc.
-timestamp='2009-12-13'
+timestamp='2011-10-08'
# This file is (in principle) common to ALL GNU software.
# The presence of a machine in this file suggests that SOME GNU software
@@ -75,8 +75,9 @@ Report bugs and patches to <config-patches@gnu.org>."
version="\
GNU config.sub ($timestamp)
-Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
-2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
+2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free
+Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
@@ -123,8 +124,9 @@ esac
# Here we must recognize all the valid KERNEL-OS combinations.
maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
case $maybe_os in
- nto-qnx* | linux-gnu* | linux-dietlibc | linux-newlib* | linux-uclibc* | \
- uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | \
+ nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \
+ linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \
+ knetbsd*-gnu* | netbsd*-gnu* | \
kopensolaris*-gnu* | \
storm-chaos* | os2-emx* | rtmk-nova*)
os=-$maybe_os
@@ -156,8 +158,8 @@ case $os in
os=
basic_machine=$1
;;
- -bluegene*)
- os=-cnk
+ -bluegene*)
+ os=-cnk
;;
-sim | -cisco | -oki | -wec | -winbond)
os=
@@ -173,10 +175,10 @@ case $os in
os=-chorusos
basic_machine=$1
;;
- -chorusrdb)
- os=-chorusrdb
+ -chorusrdb)
+ os=-chorusrdb
basic_machine=$1
- ;;
+ ;;
-hiux*)
os=-hiuxwe2
;;
@@ -249,13 +251,17 @@ case $basic_machine in
| alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
| am33_2.0 \
| arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \
+ | be32 | be64 \
| bfin \
| c4x | clipper \
| d10v | d30v | dlx | dsp16xx \
+ | epiphany \
| fido | fr30 | frv \
| h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
+ | hexagon \
| i370 | i860 | i960 | ia64 \
| ip2k | iq2000 \
+ | le32 | le64 \
| lm32 \
| m32c | m32r | m32rle | m68000 | m68k | m88k \
| maxq | mb | microblaze | mcore | mep | metag \
@@ -281,11 +287,13 @@ case $basic_machine in
| moxie \
| mt \
| msp430 \
+ | nds32 | nds32le | nds32be \
| nios | nios2 \
| ns16k | ns32k \
+ | open8 \
| or32 \
| pdp10 | pdp11 | pj | pjl \
- | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \
+ | powerpc | powerpc64 | powerpc64le | powerpcle \
| pyramid \
| rx \
| score \
@@ -293,15 +301,24 @@ case $basic_machine in
| sh64 | sh64le \
| sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \
| sparcv8 | sparcv9 | sparcv9b | sparcv9v \
- | spu | strongarm \
- | tahoe | thumb | tic4x | tic80 | tron \
+ | spu \
+ | tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \
| ubicom32 \
- | v850 | v850e \
+ | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \
| we32k \
- | x86 | xc16x | xscale | xscalee[bl] | xstormy16 | xtensa \
+ | x86 | xc16x | xstormy16 | xtensa \
| z8k | z80)
basic_machine=$basic_machine-unknown
;;
+ c54x)
+ basic_machine=tic54x-unknown
+ ;;
+ c55x)
+ basic_machine=tic55x-unknown
+ ;;
+ c6x)
+ basic_machine=tic6x-unknown
+ ;;
m6811 | m68hc11 | m6812 | m68hc12 | picochip)
# Motorola 68HC11/12.
basic_machine=$basic_machine-unknown
@@ -313,6 +330,18 @@ case $basic_machine in
basic_machine=mt-unknown
;;
+ strongarm | thumb | xscale)
+ basic_machine=arm-unknown
+ ;;
+
+ xscaleeb)
+ basic_machine=armeb-unknown
+ ;;
+
+ xscaleel)
+ basic_machine=armel-unknown
+ ;;
+
# We use `pc' rather than `unknown'
# because (1) that's what they normally are, and
# (2) the word "unknown" tends to confuse beginning users.
@@ -332,16 +361,19 @@ case $basic_machine in
| alphapca5[67]-* | alpha64pca5[67]-* | arc-* \
| arm-* | armbe-* | armle-* | armeb-* | armv*-* \
| avr-* | avr32-* \
+ | be32-* | be64-* \
| bfin-* | bs2000-* \
- | c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \
+ | c[123]* | c30-* | [cjt]90-* | c4x-* \
| clipper-* | craynv-* | cydra-* \
| d10v-* | d30v-* | dlx-* \
| elxsi-* \
| f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \
| h8300-* | h8500-* \
| hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
+ | hexagon-* \
| i*86-* | i860-* | i960-* | ia64-* \
| ip2k-* | iq2000-* \
+ | le32-* | le64-* \
| lm32-* \
| m32c-* | m32r-* | m32rle-* \
| m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
@@ -367,25 +399,29 @@ case $basic_machine in
| mmix-* \
| mt-* \
| msp430-* \
+ | nds32-* | nds32le-* | nds32be-* \
| nios-* | nios2-* \
| none-* | np1-* | ns16k-* | ns32k-* \
+ | open8-* \
| orion-* \
| pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
- | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \
+ | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \
| pyramid-* \
| romp-* | rs6000-* | rx-* \
| sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \
| shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
| sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \
| sparclite-* \
- | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | strongarm-* | sv1-* | sx?-* \
- | tahoe-* | thumb-* \
- | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* | tile-* \
+ | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx?-* \
+ | tahoe-* \
+ | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
+ | tile*-* \
| tron-* \
| ubicom32-* \
- | v850-* | v850e-* | vax-* \
+ | v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \
+ | vax-* \
| we32k-* \
- | x86-* | x86_64-* | xc16x-* | xps100-* | xscale-* | xscalee[bl]-* \
+ | x86-* | x86_64-* | xc16x-* | xps100-* \
| xstormy16-* | xtensa*-* \
| ymp-* \
| z8k-* | z80-*)
@@ -410,7 +446,7 @@ case $basic_machine in
basic_machine=a29k-amd
os=-udi
;;
- abacus)
+ abacus)
basic_machine=abacus-unknown
;;
adobe68k)
@@ -480,11 +516,20 @@ case $basic_machine in
basic_machine=powerpc-ibm
os=-cnk
;;
+ c54x-*)
+ basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ c55x-*)
+ basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ c6x-*)
+ basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
c90)
basic_machine=c90-cray
os=-unicos
;;
- cegcc)
+ cegcc)
basic_machine=arm-unknown
os=-cegcc
;;
@@ -516,7 +561,7 @@ case $basic_machine in
basic_machine=craynv-cray
os=-unicosmp
;;
- cr16)
+ cr16 | cr16-*)
basic_machine=cr16-unknown
os=-elf
;;
@@ -732,7 +777,7 @@ case $basic_machine in
basic_machine=ns32k-utek
os=-sysv
;;
- microblaze)
+ microblaze)
basic_machine=microblaze-xilinx
;;
mingw32)
@@ -775,6 +820,10 @@ case $basic_machine in
basic_machine=i370-ibm
os=-mvs
;;
+ nacl)
+ basic_machine=le32-unknown
+ os=-nacl
+ ;;
ncr3000)
basic_machine=i486-ncr
os=-sysv4
@@ -839,6 +888,12 @@ case $basic_machine in
np1)
basic_machine=np1-gould
;;
+ neo-tandem)
+ basic_machine=neo-tandem
+ ;;
+ nse-tandem)
+ basic_machine=nse-tandem
+ ;;
nsr-tandem)
basic_machine=nsr-tandem
;;
@@ -921,9 +976,10 @@ case $basic_machine in
;;
power) basic_machine=power-ibm
;;
- ppc) basic_machine=powerpc-unknown
+ ppc | ppcbe) basic_machine=powerpc-unknown
;;
- ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ppc-* | ppcbe-*)
+ basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
ppcle | powerpclittle | ppc-le | powerpc-little)
basic_machine=powerpcle-unknown
@@ -1017,6 +1073,9 @@ case $basic_machine in
basic_machine=i860-stratus
os=-sysv4
;;
+ strongarm-* | thumb-*)
+ basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
sun2)
basic_machine=m68000-sun
;;
@@ -1073,20 +1132,8 @@ case $basic_machine in
basic_machine=t90-cray
os=-unicos
;;
- tic54x | c54x*)
- basic_machine=tic54x-unknown
- os=-coff
- ;;
- tic55x | c55x*)
- basic_machine=tic55x-unknown
- os=-coff
- ;;
- tic6x | c6x*)
- basic_machine=tic6x-unknown
- os=-coff
- ;;
tile*)
- basic_machine=tile-unknown
+ basic_machine=$basic_machine-unknown
os=-linux-gnu
;;
tx39)
@@ -1156,6 +1203,9 @@ case $basic_machine in
xps | xps100)
basic_machine=xps100-honeywell
;;
+ xscale-* | xscalee[bl]-*)
+ basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'`
+ ;;
ymp)
basic_machine=ymp-cray
os=-unicos
@@ -1253,11 +1303,11 @@ esac
if [ x"$os" != x"" ]
then
case $os in
- # First match some system type aliases
- # that might get confused with valid system types.
+ # First match some system type aliases
+ # that might get confused with valid system types.
# -solaris* is a basic system type, with this one exception.
- -auroraux)
- os=-auroraux
+ -auroraux)
+ os=-auroraux
;;
-solaris1 | -solaris1.*)
os=`echo $os | sed -e 's|solaris1|sunos4|'`
@@ -1294,7 +1344,8 @@ case $os in
| -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
| -chorusos* | -chorusrdb* | -cegcc* \
| -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
- | -mingw32* | -linux-gnu* | -linux-newlib* | -linux-uclibc* \
+ | -mingw32* | -linux-gnu* | -linux-android* \
+ | -linux-newlib* | -linux-uclibc* \
| -uxpv* | -beos* | -mpeix* | -udk* \
| -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
| -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
@@ -1341,7 +1392,7 @@ case $os in
-opened*)
os=-openedition
;;
- -os400*)
+ -os400*)
os=-os400
;;
-wince*)
@@ -1390,7 +1441,7 @@ case $os in
-sinix*)
os=-sysv4
;;
- -tpf*)
+ -tpf*)
os=-tpf
;;
-triton*)
@@ -1435,6 +1486,8 @@ case $os in
-dicos*)
os=-dicos
;;
+ -nacl*)
+ ;;
-none)
;;
*)
@@ -1457,10 +1510,10 @@ else
# system, and we'll never get to this point.
case $basic_machine in
- score-*)
+ score-*)
os=-elf
;;
- spu-*)
+ spu-*)
os=-elf
;;
*-acorn)
@@ -1472,8 +1525,17 @@ case $basic_machine in
arm*-semi)
os=-aout
;;
- c4x-* | tic4x-*)
- os=-coff
+ c4x-* | tic4x-*)
+ os=-coff
+ ;;
+ tic54x-*)
+ os=-coff
+ ;;
+ tic55x-*)
+ os=-coff
+ ;;
+ tic6x-*)
+ os=-coff
;;
# This must come before the *-dec entry.
pdp10-*)
@@ -1500,7 +1562,7 @@ case $basic_machine in
m68*-cisco)
os=-aout
;;
- mep-*)
+ mep-*)
os=-elf
;;
mips*-cisco)
@@ -1527,7 +1589,7 @@ case $basic_machine in
*-ibm)
os=-aix
;;
- *-knuth)
+ *-knuth)
os=-mmixware
;;
*-wec)
diff --git a/configure b/configure
index bacaea1f2f..fcdfedb09a 100755
--- a/configure
+++ b/configure
@@ -83,7 +83,7 @@ add_engine he "HE71+ games" yes
add_engine agi "AGI" yes
add_engine agos "AGOS" yes "agos2"
add_engine agos2 "AGOS 2 games" yes
-add_engine cge "CGE" no
+add_engine cge "CGE" yes
add_engine cine "Cinematique evo 1" yes
add_engine composer "Magic Composer" no
add_engine cruise "Cinematique evo 2" yes
@@ -94,11 +94,11 @@ add_engine gob "Gobli*ns" yes
add_engine groovie "Groovie" yes "groovie2"
add_engine groovie2 "Groovie 2 games" no
add_engine hugo "Hugo Trilogy" yes
-add_engine kyra "Legend of Kyrandia" yes "lol"
+add_engine kyra "Legend of Kyrandia" yes "lol eob"
add_engine lol "Lands of Lore" yes
+add_engine eob "Eye of the Beholder" no
add_engine lastexpress "The Last Express" no
add_engine lure "Lure of the Temptress" yes
-add_engine m4 "M4/MADS" no
add_engine made "MADE" yes
add_engine mohawk "Mohawk" yes "cstime myst riven"
add_engine cstime "Where in Time is Carmen Sandiego?" no
@@ -119,9 +119,10 @@ add_engine sword25 "Broken Sword 2.5" no
add_engine teenagent "Teen Agent" yes
add_engine testbed "TestBed: the Testing framework" no
add_engine tinsel "Tinsel" yes
+add_engine toltecs "3 Skulls of the Toltecs" no
add_engine toon "Toonstruck" yes
add_engine touche "Touche: The Adventures of the Fifth Musketeer" yes
-add_engine tsage "Ringworld: Revenge Of The Patriarch" yes
+add_engine tsage "TsAGE" yes
add_engine tucker "Bud Tucker in Double Trouble" yes
#
@@ -138,13 +139,14 @@ _seq_midi=auto
_timidity=auto
_zlib=auto
_sparkle=auto
-_png=auto
+_png=no
_theoradec=auto
_faad=auto
_fluidsynth=auto
_opengl=auto
_opengles=auto
_readline=auto
+_freetype2=auto
_taskbar=yes
_updates=no
_libunity=auto
@@ -188,7 +190,9 @@ _win32path="c:/scummvm"
_aos4path="Games:ScummVM"
_staticlibpath=/sw
_sdlconfig=sdl-config
+_freetypeconfig=freetype-config
_sdlpath="$PATH"
+_freetypepath="$PATH"
_nasmpath="$PATH"
NASMFLAGS=""
NASM=""
@@ -384,6 +388,40 @@ find_sdlconfig() {
}
#
+# Determine freetype-config
+#
+find_freetypeconfig() {
+ echo_n "Looking for freetype-config... "
+ freetypeconfigs="$_freetypeconfig"
+ _freetypeconfig=
+
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="$SEPARATOR"
+ for path_dir in $_freetypepath; do
+ #reset separator to parse freetypeconfigs
+ IFS=":"
+ for freetypeconfig in $freetypeconfigs; do
+ if test -f "$path_dir/$freetypeconfig" ; then
+ _freetypeconfig="$path_dir/$freetypeconfig"
+ echo $_freetypeconfig
+ # Save the prefix
+ _freetypepath=$path_dir
+ if test `basename $path_dir` = bin ; then
+ _freetypepath=`dirname $path_dir`
+ fi
+ # break at first freetype-config found in path
+ break 2
+ fi
+ done
+ done
+
+ IFS="$ac_save_ifs"
+
+ if test -z "$_freetypeconfig"; then
+ echo "none found!"
+ fi
+}
+
+#
# Determine extension used for executables
#
get_system_exe_extension() {
@@ -412,19 +450,39 @@ get_system_exe_extension() {
# Show the configure help line for an option
option_help() {
+ if test "${3}" != "" ; then
+ tmpopt_prefix="${3}"
+ else
+ tmpopt_prefix="--"
+ fi
tmpopt=`echo $1 | sed 's/_/-/g'`
- option=`echo "--${tmpopt} " | sed "s/\(.\{23\}\).*/\1/"`
+ option=`echo "${tmpopt_prefix}${tmpopt} " | sed "s/\(.\{23\}\).*/\1/"`
echo " ${option} ${2}"
}
# Show an error about an unknown option
option_error() {
- echo "error: unrecognised option: $ac_option
+ echo "error: unrecognized option: $ac_option
+Try \`$0 --help' for more information." >&2
+ exit 1
+}
+
+# Show an error about an unknown engine
+engine_option_error() {
+ echo "error: unrecognized engine: $1
+Try \`$0 --help' for more information." >&2
+ exit 1
+}
+
+# Show an error about an invalid subengine option
+subengine_option_error() {
+ echo "error: this option is invalid for the subengine $1: $ac_option
Try \`$0 --help' for more information." >&2
exit 1
}
+
#
# Engine handling functions
#
@@ -475,9 +533,9 @@ engine_disable_all() {
# Enable the given engine
engine_enable() {
# Get the parameter
- if ( echo $1 | grep '=' ) 2> /dev/null > /dev/null ; then
- eng=`echo $1 | cut -d '=' -f 1`
- opt=`echo $1 | cut -d '=' -f 2`
+ if ( echo $1 | grep ':' ) 2> /dev/null > /dev/null ; then
+ eng=`echo $1 | cut -d ':' -f 1`
+ opt=`echo $1 | cut -d ':' -f 2`
else
eng=$1
opt=yes
@@ -486,7 +544,7 @@ engine_enable() {
# Filter the parameter for the subengines
if test "`get_engine_sub ${engine}`" != "no" -a "$opt" != "yes" ; then
- option_error
+ subengine_option_error ${engine}
return
fi
@@ -494,7 +552,7 @@ engine_enable() {
if test "`get_engine_name ${engine}`" != "" ; then
set_var _engine_${engine}_build "$opt"
else
- option_error
+ engine_option_error ${engine}
fi
else
option_error
@@ -513,21 +571,14 @@ engine_disable() {
if test "`get_engine_name ${engine}`" != "" ; then
set_var _engine_${engine}_build "no"
else
- option_error
+ engine_option_error ${engine}
fi
}
# Show the configure help line for a given engine
show_engine_help() {
- if test `get_engine_build $1` = yes ; then
- option="disable"
- do="don't "
- else
- option="enable"
- do=""
- fi
name=`get_engine_name $1`
- option_help ${option}-${1} "${do}build the ${name} engine"
+ option_help "${1}" "${name} engine" " "
for sub in `get_engine_subengines $1`; do
show_subengine_help $sub $1
done
@@ -535,16 +586,9 @@ show_engine_help() {
# Show the configure help line for a given subengine
show_subengine_help() {
- if test `get_engine_build $1` = yes ; then
- option="disable"
- do="exclude"
- else
- option="enable"
- do="include"
- fi
name=`get_engine_name $1`
parent=`get_engine_name $2`
- option_help ${option}-${1} "${do} the ${name} in ${parent} engine"
+ option_help "${1}" "${name} in ${parent} engine" " "
}
# Prepare the strings about the engines to build
@@ -767,6 +811,13 @@ Game engines:
--enable-all-engines enable all engines, including those which are
broken or unsupported
--disable-all-engines disable all engines
+ --enable-engine=<engine name>[,<engine name>...] enable engine(s) listed
+ --disable-engine=<engine name>[,<engine name>...] disable engine(s) listed
+ --enable-engine-static=<engine name>[,<engine name>...]
+ enable engine(s) listed as static builtin (when plugins are enabled)
+ --enable-engine-dynamic=<engine name>[,<engine name>...]
+ enable engine(s) listed as dynamic plugin (when plugins are enabled)
+ The values of <engine name> for these options are as follows:
$engines_help
Optional Features:
--disable-debug disable building with debugging symbols
@@ -833,6 +884,9 @@ Optional Libraries:
--with-sdl-prefix=DIR Prefix where the sdl-config script is
installed (optional)
+ --with-freetype-prefix=DIR Prefix where the freetype-config script is
+ installed (optional)
+
--with-nasm-prefix=DIR Prefix where nasm executable is installed (optional)
--disable-nasm disable assembly language optimizations [autodetect]
@@ -892,6 +946,8 @@ for ac_option in $@; do
--disable-fluidsynth) _fluidsynth=no ;;
--enable-readline) _readline=yes ;;
--disable-readline) _readline=no ;;
+ --enable-freetype2) _freetype2=yes ;;
+ --disable-freetype2) _freetype2=no ;;
--enable-taskbar) _taskbar=yes ;;
--disable-taskbar) _taskbar=no ;;
--enable-updates) _updates=yes ;;
@@ -1029,6 +1085,10 @@ for ac_option in $@; do
arg=`echo $ac_option | cut -d '=' -f 2`
_sdlpath="$arg:$arg/bin"
;;
+ --with-freetype2-prefix=*)
+ arg=`echo $ac_option | cut -d '=' -f 2`
+ _freetypepath="$arg:$arg/bin"
+ ;;
--with-nasm-prefix=*)
arg=`echo $ac_option | cut -d '=' -f 2`
_nasmpath="$arg:$arg/bin"
@@ -1069,11 +1129,25 @@ for ac_option in $@; do
--disable-all-engines)
engine_disable_all
;;
- --enable-*)
- engine_enable `echo $ac_option | cut -d '-' -f 4-`
+ --enable-engine=* | --enable-engines=*)
+ for engine_name in `echo $ac_option | cut -d '=' -f 2- | tr ',' '\n'`; do
+ engine_enable "${engine_name}"
+ done
+ ;;
+ --enable-engine-static=* | --enable-engines-static=*)
+ for engine_name in `echo $ac_option | cut -d '=' -f 2- | tr ',' '\n'`; do
+ engine_enable "${engine_name}:static"
+ done
+ ;;
+ --enable-engine-dynamic=* | --enable-engines-dynamic=*)
+ for engine_name in `echo $ac_option | cut -d '=' -f 2- | tr ',' '\n'`; do
+ engine_enable "${engine_name}:dynamic"
+ done
;;
- --disable-*)
- engine_disable `echo $ac_option | cut -d '-' -f 4-`
+ --disable-engine=* | --disable-engines=*)
+ for engine_name in `echo $ac_option | cut -d '=' -f 2 | tr ',' '\n'`; do
+ engine_disable ${engine_name}
+ done
;;
*)
option_error
@@ -1253,7 +1327,7 @@ wii)
wince)
_host_os=wince
_host_cpu=arm
- _host_alias=arm-wince-mingw32ce
+ _host_alias=arm-mingw32ce
;;
*)
if test -n "$_host"; then
@@ -1547,7 +1621,7 @@ fi
echo "$cxx_version"
#
-# Bail out now if now useable compiler was found.
+# Bail out now if no useable compiler was found.
#
if test "$cxx_verc_fail" = yes ; then
echo
@@ -1592,7 +1666,7 @@ fi;
# However, some platforms use GNU extensions in system header files, so
# for these we must not use -pedantic.
case $_host_os in
-android | gamecube | psp | wii)
+android | gamecube | psp | wii | webos)
;;
*)
# ICC does not support pedantic, while GCC and clang do.
@@ -1655,7 +1729,7 @@ esac
# Determine a data type with the given length
#
find_type_with_size() {
- for datatype in int short char long unknown; do
+ for datatype in int short char long "long long" unknown; do
cat > tmp_find_type_with_size.cpp << EOF
typedef $datatype ac__type_sizeof_;
int main() {
@@ -1679,6 +1753,35 @@ EOF
}
#
+# Check whether the system is 32-bit
+#
+pointer_is_32bit() {
+ cat > tmp_pointer_is_32bit.cpp << EOF
+int main() {
+ static int test_array[1 - 2 * !(sizeof(void *) == 4)];
+ test_array[0] = 0;
+ return 0;
+}
+EOF
+ $CXX $CXXFLAGS -c -o $TMPO.o tmp_pointer_is_32bit.cpp 2>/dev/null
+ status=$?
+ cc_check_clean tmp_pointer_is_32bit.cpp
+ return $status
+}
+
+echo_n "Checking 64-bitness... "
+pointer_is_32bit
+if test $? -eq 0; then
+ type_ptr=int32
+ echo "no"
+ add_line_to_config_h "/* #define SCUMM_64BITS */"
+else
+ type_ptr=int64
+ echo "yes"
+ add_line_to_config_h "#define SCUMM_64BITS"
+fi
+
+#
# Determine data type sizes
#
echo_n "Type with 1 byte... "
@@ -1699,6 +1802,17 @@ TMPR="$?"
echo "$type_4_byte"
test $TMPR -eq 0 || exit 1 # check exit code of subshell
+echo_n "Type with 8 bytes... "
+type_8_byte=`find_type_with_size 8`
+TMPR="$?"
+echo "$type_8_byte"
+if test $TMPR -eq 0; then
+ _def_64bit_type_signed="typedef signed $type_8_byte int64;"
+ _def_64bit_type_unsigned="typedef unsigned $type_8_byte uint64;"
+fi
+# force cleanup after check for 8 bytes type
+cc_check_clean tmp_find_type_with_size.cpp
+
#
# Check whether memory alignment is required
#
@@ -1865,7 +1979,7 @@ case $_host_os in
# Now we may have MacPorts or Fink installed
# Which put libraries and headers in non-standard places
# Checking them here
-
+
# MacPorts
# There is no way to get the prefix, so implementing a hack here
macport_version=`port version 2>/dev/null`
@@ -2021,6 +2135,7 @@ case $_host_os in
LIBS="$LIBS -lnsl -lsocket"
;;
webos)
+ CXXFLAGS="$CXXFLAGS --sysroot=$WEBOS_PDK/arm-gcc/sysroot"
CXXFLAGS="$CXXFLAGS -I$WEBOS_PDK/include"
CXXFLAGS="$CXXFLAGS -I$WEBOS_PDK/include/SDL"
CXXFLAGS="$CXXFLAGS -I$WEBOS_PDK/device/usr/include"
@@ -2252,8 +2367,10 @@ if test -n "$_host"; then
iphone)
DEFINES="$DEFINES -DIPHONE"
_backend="iphone"
- _build_hq_scalers=no
+ _build_scalers=no
+ _mt32emu=no
_seq_midi=no
+ _timidity=no
;;
m68k-atari-mint)
DEFINES="$DEFINES -DSYSTEM_NOT_SUPPORTING_D_TYPE"
@@ -2266,11 +2383,12 @@ if test -n "$_host"; then
CXXFLAGS="$CXXFLAGS -mcpu=arm926ej-s"
CXXFLAGS="$CXXFLAGS -fomit-frame-pointer"
INCLUDES="$INCLUDES -I/usr/X11R6/include"
- LIBS="$LIBS -lpthread"
+ LIBS="$LIBS -lX11"
LIBS="$LIBS -L/usr/lib"
_backend="maemo"
_vkeybd=yes
+ _keymapper=yes
_build_hq_scalers=no
_mt32emu=no
_alsa=no
@@ -2468,8 +2586,9 @@ case $_backend in
DEFINES="$DEFINES -DREDUCE_MEMORY_USAGE"
CXXFLAGS="$CXXFLAGS -Wa,--noexecstack"
LDFLAGS="$LDFLAGS -Wl,-z,noexecstack"
+ INCLUDES="$INCLUDES -I$ANDROID_NDK/sources/cxx-stl/system/include"
;;
- bada)
+ bada)
# dirent.h not available. NONSTANDARD_PORT==ensure portdefs.h is included
DEFINES="$DEFINES -DBADA -DDISABLE_STDIO_FILESTREAM -DNONSTANDARD_PORT"
DEFINES="$DEFINES -DNO_STDERR_STDOUT"
@@ -2523,7 +2642,6 @@ case $_backend in
gph)
;;
iphone)
- OBJCFLAGS="$OBJCFLAGS --std=c99"
LIBS="$LIBS -lobjc -framework UIKit -framework CoreGraphics -framework OpenGLES"
LIBS="$LIBS -framework QuartzCore -framework GraphicsServices -framework CoreFoundation"
LIBS="$LIBS -framework Foundation -framework AudioToolbox -framework CoreAudio"
@@ -2640,7 +2758,7 @@ esac
# Enable 16bit support only for backends which support it
#
case $_backend in
- android | bada | dingux | dreamcast | gph | maemo | openpandora | psp | samsungtv | sdl | webos | wii)
+ android | bada | dingux | dreamcast | gph | iphone | maemo | openpandora | psp | samsungtv | sdl | webos | wii)
if test "$_16bit" = auto ; then
_16bit=yes
else
@@ -3343,6 +3461,50 @@ fi
echo "$_libunity"
#
+# Check for FreeType2 to be present
+#
+if test "$_freetype2" != "no"; then
+
+ # Look for the freetype-config script
+ find_freetypeconfig
+
+ if test -z "$_freetypeconfig"; then
+ _freetype2=no
+ else
+ FREETYPE2_LIBS=`$_freetypeconfig --prefix="$_freetypepath" --libs`
+ FREETYPE2_CFLAGS=`$_freetypeconfig --prefix="$_freetypepath" --cflags`
+
+ if test "$_freetype2" = "auto"; then
+ _freetype2=no
+
+ cat > $TMPC << EOF
+#include <ft2build.h>
+#include FT_FREETYPE_H
+
+int main(int argc, char *argv[]) {
+ FT_Library library;
+ FT_Error error = FT_Init_FreeType(&library);
+ FT_Done_FreeType(library);
+}
+EOF
+
+ cc_check $FREETYPE2_CFLAGS $FREETYPE2_LIBS && _freetype2=yes
+ fi
+
+ if test "$_freetype2" = "yes"; then
+ LIBS="$LIBS $FREETYPE2_LIBS"
+ INCLUDES="$INCLUDES $FREETYPE2_CFLAGS"
+ fi
+ fi
+
+fi
+
+echocheck "FreeType2"
+echo "$_freetype2"
+
+define_in_config_h_if_yes "$_freetype2" "USE_FREETYPE2"
+
+#
# Check for OpenGL (ES)
#
echocheck "OpenGL"
@@ -3823,6 +3985,25 @@ typedef unsigned $type_4_byte uint32;
typedef signed $type_1_byte int8;
typedef signed $type_2_byte int16;
typedef signed $type_4_byte int32;
+EOF
+
+if test -n "$_def_64bit_type_unsigned" ; then
+cat >> config.h << EOF
+
+/* 64-bit stuff */
+$_def_64bit_type_signed
+#if defined(__APPLE__) && !defined(__ppc__)
+#ifndef _UINT64
+#define _UINT64
+$_def_64bit_type_unsigned
+#endif
+#else
+$_def_64bit_type_unsigned
+#endif
+EOF
+fi
+
+cat >> config.h << EOF
#endif /* CONFIG_H */
EOF
diff --git a/devtools/convbdf.c b/devtools/convbdf.c
deleted file mode 100644
index e465b77a9c..0000000000
--- a/devtools/convbdf.c
+++ /dev/null
@@ -1,928 +0,0 @@
-/*
- * Convert BDF files to C++ source.
- *
- * Copyright (c) 2002 by Greg Haerr <greg@censoft.com>
- *
- * Originally writen for the Microwindows Project <http://microwindows.org>
- *
- * Greg then modified it for Rockbox <http://rockbox.haxx.se/>
- *
- * Max Horn took that version and changed it to work for ScummVM.
- * Changes include: warning fixes, removed .FNT output, output C++ source,
- * tweak code generator so that the generated code fits into ScummVM code base.
- *
- * What fun it is converting font data...
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-#include <stdarg.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
-
-int READ_UINT16(void *addr) {
- unsigned char *buf = (unsigned char *)addr;
- return (buf[0] << 8) | buf[1];
-}
-
-void WRITE_UINT16(void *addr, int value) {
- unsigned char *buf = (unsigned char *)addr;
- buf[0] = (value >> 8) & 0xFF;
- buf[1] = value & 0xFF;
-}
-
-/* BEGIN font.h*/
-/* bitmap_t helper macros*/
-#define BITMAP_WORDS(x) (((x)+15)/16) /* image size in words*/
-#define BITMAP_BYTES(x) (BITMAP_WORDS(x)*sizeof(bitmap_t))
-#define BITMAP_BITSPERIMAGE (sizeof(bitmap_t) * 8)
-#define BITMAP_BITVALUE(n) ((bitmap_t) (((bitmap_t) 1) << (n)))
-#define BITMAP_FIRSTBIT (BITMAP_BITVALUE(BITMAP_BITSPERIMAGE - 1))
-#define BITMAP_TESTBIT(m) ((m) & BITMAP_FIRSTBIT)
-#define BITMAP_SHIFTBIT(m) ((bitmap_t) ((m) << 1))
-
-typedef unsigned short bitmap_t; /* bitmap image unit size*/
-
-typedef struct {
- signed char w;
- signed char h;
- signed char x;
- signed char y;
-} BBX;
-
-/* builtin C-based proportional/fixed font structure */
-/* based on The Microwindows Project http://microwindows.org */
-struct font {
- char * name; /* font name*/
- int maxwidth; /* max width in pixels*/
- int height; /* height in pixels*/
- int fbbw, fbbh, fbbx, fbby; /* max bounding box */
- int ascent; /* ascent (baseline) height*/
- int firstchar; /* first character in bitmap*/
- int size; /* font size in glyphs*/
- bitmap_t* bits; /* 16-bit right-padded bitmap data*/
- unsigned long* offset; /* offsets into bitmap data*/
- unsigned char* width; /* character widths or NULL if fixed*/
- BBX* bbx; /* character bounding box or NULL if fixed*/
- int defaultchar; /* default char (not glyph index)*/
- long bits_size; /* # words of bitmap_t bits*/
-
- /* unused by runtime system, read in by convbdf*/
- char * facename; /* facename of font*/
- char * copyright; /* copyright info for loadable fonts*/
- int pixel_size;
- int descent;
-};
-/* END font.h*/
-
-#define isprefix(buf,str) (!strncmp(buf, str, strlen(str)))
-#define strequal(s1,s2) (!strcmp(s1, s2))
-
-#define EXTRA 300 /* # bytes extra allocation for buggy .bdf files*/
-
-int gen_map = 1;
-int start_char = 0;
-int limit_char = 65535;
-int oflag = 0;
-char outfile[256];
-
-void usage(void);
-void getopts(int *pac, char ***pav);
-int convbdf(char *path);
-
-void free_font(struct font* pf);
-struct font* bdf_read_font(char *path);
-int bdf_read_header(FILE *fp, struct font* pf);
-int bdf_read_bitmaps(FILE *fp, struct font* pf);
-char * bdf_getline(FILE *fp, char *buf, int len);
-bitmap_t bdf_hexval(unsigned char *buf);
-
-int gen_c_source(struct font* pf, char *path);
-
-void error(const char *s, ...) {
- char buf[1024];
- va_list va;
-
- va_start(va, s);
- vsnprintf(buf, 1024, s, va);
- va_end(va);
-
- fprintf(stderr, "ERROR: %s!\n", buf);
-
- exit(1);
-}
-
-void warning(const char *s, ...) {
- char buf[1024];
- va_list va;
-
- va_start(va, s);
- vsnprintf(buf, 1024, s, va);
- va_end(va);
-
- fprintf(stderr, "WARNING: %s!\n", buf);
-}
-
-void
-usage(void) {
- char help[] = {
- "Usage: convbdf [options] [input-files]\n"
- " convbdf [options] [-o output-file] [single-input-file]\n"
- "Options:\n"
- " -s N Start output at character encodings >= N\n"
- " -l N Limit output to character encodings <= N\n"
- " -n Don't generate bitmaps as comments in .c file\n"
- };
-
- fprintf(stderr, "%s", help);
-}
-
-/* parse command line options*/
-void getopts(int *pac, char ***pav) {
- const char *p;
- char **av;
- int ac;
-
- ac = *pac;
- av = *pav;
- while (ac > 0 && av[0][0] == '-') {
- p = &av[0][1];
- while (*p) {
- switch (*p++) {
- case ' ': /* multiple -args on av[]*/
- while (*p && *p == ' ')
- p++;
- if (*p++ != '-') /* next option must have dash*/
- p = "";
- break; /* proceed to next option*/
- case 'n': /* don't gen bitmap comments*/
- gen_map = 0;
- break;
- case 'o': /* set output file*/
- oflag = 1;
- if (*p) {
- strcpy(outfile, p);
- while (*p && *p != ' ')
- p++;
- }
- else {
- av++; ac--;
- if (ac > 0)
- strcpy(outfile, av[0]);
- }
- break;
- case 'l': /* set encoding limit*/
- if (*p) {
- limit_char = atoi(p);
- while (*p && *p != ' ')
- p++;
- }
- else {
- av++; ac--;
- if (ac > 0)
- limit_char = atoi(av[0]);
- }
- break;
- case 's': /* set encoding start*/
- if (*p) {
- start_char = atoi(p);
- while (*p && *p != ' ')
- p++;
- }
- else {
- av++; ac--;
- if (ac > 0)
- start_char = atoi(av[0]);
- }
- break;
- default:
- fprintf(stderr, "Unknown option ignored: %c\r\n", *(p-1));
- }
- }
- ++av; --ac;
- }
- *pac = ac;
- *pav = av;
-}
-
-/* remove directory prefix and file suffix from full path*/
-char *basename(char *path) {
- char *p, *b;
- static char base[256];
-
- /* remove prepended path and extension*/
- b = path;
- for (p = path; *p; ++p) {
- if (*p == '/')
- b = p + 1;
- }
- strcpy(base, b);
- for (p = base; *p; ++p) {
- if (*p == '.') {
- *p = 0;
- break;
- }
- }
- return base;
-}
-
-int convbdf(char *path) {
- struct font* pf;
- int ret = 0;
-
- pf = bdf_read_font(path);
- if (!pf)
- exit(1);
-
- if (!oflag) {
- strcpy(outfile, basename(path));
- strcat(outfile, ".cpp");
- }
- ret |= gen_c_source(pf, outfile);
-
- free_font(pf);
- return ret;
-}
-
-int main(int ac, char *av[]) {
- int ret = 0;
-
- ++av; --ac; /* skip av[0]*/
- getopts(&ac, &av); /* read command line options*/
-
- if (ac < 1) {
- usage();
- exit(1);
- }
- if (oflag && ac > 1) {
- usage();
- exit(1);
- }
-
- while (ac > 0) {
- ret |= convbdf(av[0]);
- ++av; --ac;
- }
-
- exit(ret);
-}
-
-/* free font structure*/
-void free_font(struct font* pf) {
- if (!pf)
- return;
- free(pf->name);
- free(pf->facename);
- free(pf->bits);
- free(pf->offset);
- free(pf->width);
- free(pf);
-}
-
-/* build incore structure from .bdf file*/
-struct font* bdf_read_font(char *path) {
- FILE *fp;
- struct font* pf;
-
- fp = fopen(path, "rb");
- if (!fp) {
- fprintf(stderr, "Error opening file: %s\n", path);
- return NULL;
- }
-
- pf = (struct font*)calloc(1, sizeof(struct font));
- if (!pf)
- goto errout;
-
- pf->name = strdup(basename(path));
-
- if (!bdf_read_header(fp, pf)) {
- fprintf(stderr, "Error reading font header\n");
- goto errout;
- }
-
- if (!bdf_read_bitmaps(fp, pf)) {
- fprintf(stderr, "Error reading font bitmaps\n");
- goto errout;
- }
-
- fclose(fp);
- return pf;
-
- errout:
- fclose(fp);
- free_font(pf);
- return NULL;
-}
-
-/* read bdf font header information, return 0 on error*/
-int bdf_read_header(FILE *fp, struct font* pf) {
- int encoding;
- int nchars, maxwidth;
- int firstchar = 65535;
- int lastchar = -1;
- char buf[256];
- char facename[256];
- char copyright[256];
-
- /* set certain values to errors for later error checking*/
- pf->defaultchar = -1;
- pf->ascent = -1;
- pf->descent = -1;
-
- for (;;) {
- if (!bdf_getline(fp, buf, sizeof(buf))) {
- fprintf(stderr, "Error: EOF on file\n");
- return 0;
- }
- if (isprefix(buf, "FONT ")) { /* not required*/
- if (sscanf(buf, "FONT %[^\n]", facename) != 1) {
- fprintf(stderr, "Error: bad 'FONT'\n");
- return 0;
- }
- pf->facename = strdup(facename);
- continue;
- }
- if (isprefix(buf, "COPYRIGHT ")) { /* not required*/
- if (sscanf(buf, "COPYRIGHT \"%[^\"]", copyright) != 1) {
- fprintf(stderr, "Error: bad 'COPYRIGHT'\n");
- return 0;
- }
- pf->copyright = strdup(copyright);
- continue;
- }
- if (isprefix(buf, "DEFAULT_CHAR ")) { /* not required*/
- if (sscanf(buf, "DEFAULT_CHAR %d", &pf->defaultchar) != 1) {
- fprintf(stderr, "Error: bad 'DEFAULT_CHAR'\n");
- return 0;
- }
- }
- if (isprefix(buf, "FONT_DESCENT ")) {
- if (sscanf(buf, "FONT_DESCENT %d", &pf->descent) != 1) {
- fprintf(stderr, "Error: bad 'FONT_DESCENT'\n");
- return 0;
- }
- continue;
- }
- if (isprefix(buf, "FONT_ASCENT ")) {
- if (sscanf(buf, "FONT_ASCENT %d", &pf->ascent) != 1) {
- fprintf(stderr, "Error: bad 'FONT_ASCENT'\n");
- return 0;
- }
- continue;
- }
- if (isprefix(buf, "FONTBOUNDINGBOX ")) {
- if (sscanf(buf, "FONTBOUNDINGBOX %d %d %d %d",
- &pf->fbbw, &pf->fbbh, &pf->fbbx, &pf->fbby) != 4) {
- fprintf(stderr, "Error: bad 'FONTBOUNDINGBOX'\n");
- return 0;
- }
- continue;
- }
- if (isprefix(buf, "CHARS ")) {
- if (sscanf(buf, "CHARS %d", &nchars) != 1) {
- fprintf(stderr, "Error: bad 'CHARS'\n");
- return 0;
- }
- continue;
- }
-
- /*
- * Reading ENCODING is necessary to get firstchar/lastchar
- * which is needed to pre-calculate our offset and widths
- * array sizes.
- */
- if (isprefix(buf, "ENCODING ")) {
- if (sscanf(buf, "ENCODING %d", &encoding) != 1) {
- fprintf(stderr, "Error: bad 'ENCODING'\n");
- return 0;
- }
- if (encoding >= 0 &&
- encoding <= limit_char &&
- encoding >= start_char) {
-
- if (firstchar > encoding)
- firstchar = encoding;
- if (lastchar < encoding)
- lastchar = encoding;
- }
- continue;
- }
- if (strequal(buf, "ENDFONT"))
- break;
- }
-
- /* calc font height*/
- if (pf->ascent < 0 || pf->descent < 0 || firstchar < 0) {
- fprintf(stderr, "Error: Invalid BDF file, requires FONT_ASCENT/FONT_DESCENT/ENCODING\n");
- return 0;
- }
- pf->height = pf->ascent + pf->descent;
-
- /* calc default char*/
- if (pf->defaultchar < 0 ||
- pf->defaultchar < firstchar ||
- pf->defaultchar > limit_char )
- pf->defaultchar = firstchar;
-
- /* calc font size (offset/width entries)*/
- pf->firstchar = firstchar;
- pf->size = lastchar - firstchar + 1;
-
- /* use the font boundingbox to get initial maxwidth*/
- /*maxwidth = pf->fbbw - pf->fbbx;*/
- maxwidth = pf->fbbw;
-
- /* initially use font maxwidth * height for bits allocation*/
- pf->bits_size = nchars * BITMAP_WORDS(maxwidth) * pf->height;
-
- /* allocate bits, offset, and width arrays*/
- pf->bits = (bitmap_t *)malloc(pf->bits_size * sizeof(bitmap_t) + EXTRA);
- pf->offset = (unsigned long *)malloc(pf->size * sizeof(unsigned long));
- pf->width = (unsigned char *)malloc(pf->size * sizeof(unsigned char));
- pf->bbx = (BBX *)malloc(pf->size * sizeof(BBX));
-
- if (!pf->bits || !pf->offset || !pf->width) {
- fprintf(stderr, "Error: no memory for font load\n");
- return 0;
- }
-
- return 1;
-}
-
-/* read bdf font bitmaps, return 0 on error*/
-int bdf_read_bitmaps(FILE *fp, struct font* pf) {
- long ofs = 0;
- int maxwidth = 0;
- int i, k, encoding, width;
- int bbw, bbh, bbx, bby;
- int proportional = 0;
- int need_bbx = 0;
- int encodetable = 0;
- long l;
- char buf[256];
-
- /* reset file pointer*/
- fseek(fp, 0L, SEEK_SET);
-
- /* initially mark offsets as not used*/
- for (i = 0; i < pf->size; ++i)
- pf->offset[i] = -1;
-
- for (;;) {
- if (!bdf_getline(fp, buf, sizeof(buf))) {
- fprintf(stderr, "Error: EOF on file\n");
- return 0;
- }
- if (isprefix(buf, "STARTCHAR")) {
- encoding = width = bbw = bbh = bbx = bby = -1;
- continue;
- }
- if (isprefix(buf, "ENCODING ")) {
- if (sscanf(buf, "ENCODING %d", &encoding) != 1) {
- fprintf(stderr, "Error: bad 'ENCODING'\n");
- return 0;
- }
- if (encoding < start_char || encoding > limit_char)
- encoding = -1;
- continue;
- }
- if (isprefix(buf, "DWIDTH ")) {
- if (sscanf(buf, "DWIDTH %d", &width) != 1) {
- fprintf(stderr, "Error: bad 'DWIDTH'\n");
- return 0;
- }
- /* use font boundingbox width if DWIDTH <= 0*/
- if (width <= 0)
- width = pf->fbbw - pf->fbbx;
- continue;
- }
- if (isprefix(buf, "BBX ")) {
- if (sscanf(buf, "BBX %d %d %d %d", &bbw, &bbh, &bbx, &bby) != 4) {
- fprintf(stderr, "Error: bad 'BBX'\n");
- return 0;
- }
- continue;
- }
- if (strequal(buf, "BITMAP")) {
- bitmap_t *ch_bitmap = pf->bits + ofs;
- int ch_words;
-
- if (encoding < 0)
- continue;
-
- /* set bits offset in encode map*/
- if (pf->offset[encoding-pf->firstchar] != (unsigned long)-1) {
- fprintf(stderr, "Error: duplicate encoding for character %d (0x%02x), ignoring duplicate\n",
- encoding, encoding);
- continue;
- }
- pf->offset[encoding-pf->firstchar] = ofs;
- pf->width[encoding-pf->firstchar] = width;
-
- pf->bbx[encoding-pf->firstchar].w = bbw;
- pf->bbx[encoding-pf->firstchar].h = bbh;
- pf->bbx[encoding-pf->firstchar].x = bbx;
- pf->bbx[encoding-pf->firstchar].y = bby;
-
- if (width > maxwidth)
- maxwidth = width;
-
- /* clear bitmap*/
- memset(ch_bitmap, 0, BITMAP_BYTES(bbw) * bbh);
-
- ch_words = BITMAP_WORDS(bbw);
-
- /* read bitmaps*/
- for (i = 0; i < bbh; ++i) {
- if (!bdf_getline(fp, buf, sizeof(buf))) {
- fprintf(stderr, "Error: EOF reading BITMAP data\n");
- return 0;
- }
- if (isprefix(buf, "ENDCHAR"))
- break;
-
- for (k = 0; k < ch_words; ++k) {
- bitmap_t value;
-
- value = bdf_hexval((unsigned char *)buf);
-
- if (bbw > 8) {
- WRITE_UINT16(ch_bitmap, value);
- } else {
- WRITE_UINT16(ch_bitmap, value << 8);
- }
- ch_bitmap++;
- }
- }
-
- // If the default glyph is completely empty, the next
- // glyph will not be dumped. Work around this by
- // never generating completely empty glyphs.
-
- if (bbh == 0 && bbw == 0) {
- pf->bbx[encoding-pf->firstchar].w = 1;
- pf->bbx[encoding-pf->firstchar].h = 1;
- *ch_bitmap++ = 0;
- ofs++;
- } else {
- ofs += ch_words * bbh;
- }
- continue;
- }
- if (strequal(buf, "ENDFONT"))
- break;
- }
-
- /* set max width*/
- pf->maxwidth = maxwidth;
-
- /* change unused offset/width values to default char values*/
- for (i = 0; i < pf->size; ++i) {
- int defchar = pf->defaultchar - pf->firstchar;
-
- if (pf->offset[i] == (unsigned long)-1) {
- pf->offset[i] = pf->offset[defchar];
- pf->width[i] = pf->width[defchar];
- pf->bbx[i].w = pf->bbx[defchar].w;
- pf->bbx[i].h = pf->bbx[defchar].h;
- pf->bbx[i].x = pf->bbx[defchar].x;
- pf->bbx[i].y = pf->bbx[defchar].y;
- }
- }
-
- /* determine whether font doesn't require encode table*/
- l = 0;
- for (i = 0; i < pf->size; ++i) {
- if (pf->offset[i] != (unsigned long)l) {
- encodetable = 1;
- break;
- }
- l += BITMAP_WORDS(pf->bbx[i].w) * pf->bbx[i].h;
- }
- if (!encodetable) {
- free(pf->offset);
- pf->offset = NULL;
- }
-
- /* determine whether font is fixed-width*/
- for (i = 0; i < pf->size; ++i) {
- if (pf->width[i] != maxwidth) {
- proportional = 1;
- break;
- }
- }
- if (!proportional) {
- free(pf->width);
- pf->width = NULL;
- }
-
- /* determine if the font needs a bbx table */
- for (i = 0; i < pf->size; ++i) {
- if (pf->bbx[i].w != pf->fbbw || pf->bbx[i].h != pf->fbbh || pf->bbx[i].x != pf->fbbx || pf->bbx[i].y != pf->fbby) {
- need_bbx = 1;
- break;
- }
- }
- if (!need_bbx) {
- free(pf->bbx);
- pf->bbx = NULL;
- }
-
- /* reallocate bits array to actual bits used*/
- if (ofs < pf->bits_size) {
- pf->bits = (bitmap_t *)realloc(pf->bits, ofs * sizeof(bitmap_t));
- pf->bits_size = ofs;
- }
- else {
- if (ofs > pf->bits_size) {
- fprintf(stderr, "Warning: DWIDTH spec > max FONTBOUNDINGBOX\n");
- if (ofs > pf->bits_size+EXTRA) {
- fprintf(stderr, "Error: Not enough bits initially allocated\n");
- return 0;
- }
- pf->bits_size = ofs;
- }
- }
-
- return 1;
-}
-
-/* read the next non-comment line, returns buf or NULL if EOF*/
-char *bdf_getline(FILE *fp, char *buf, int len) {
- int c;
- char *b;
-
- for (;;) {
- b = buf;
- while ((c = getc(fp)) != EOF) {
- if (c == '\r')
- continue;
- if (c == '\n')
- break;
- if (b - buf >= (len - 1))
- break;
- *b++ = c;
- }
- *b = '\0';
- if (c == EOF && b == buf)
- return NULL;
- if (b != buf && !isprefix(buf, "COMMENT"))
- break;
- }
- return buf;
-}
-
-/* return hex value of buffer */
-bitmap_t bdf_hexval(unsigned char *buf) {
- bitmap_t val = 0;
- unsigned char *ptr;
-
- for (ptr = buf; *ptr; ptr++) {
- int c = *ptr;
-
- if (c >= '0' && c <= '9')
- c -= '0';
- else if (c >= 'A' && c <= 'F')
- c = c - 'A' + 10;
- else if (c >= 'a' && c <= 'f')
- c = c - 'a' + 10;
- else
- c = 0;
- val = (val << 4) | c;
- }
- return val;
-}
-
-/* generate C source from in-core font*/
-int gen_c_source(struct font* pf, char *path) {
- FILE *ofp;
- int h, i;
- int did_defaultchar = 0;
- int did_syncmsg = 0;
- time_t t = time(0);
- bitmap_t *ofs = pf->bits;
- char buf[256];
- char obuf[256];
- char bbuf[256];
- char hdr1[] = {
- "/* Generated by convbdf on %s. */\n"
- "#include \"graphics/fonts/bdf.h\"\n"
- "\n"
- "/* Font information:\n"
- " name: %s\n"
- " facename: %s\n"
- " w x h: %dx%d\n"
- " bbx: %d %d %d %d\n"
- " size: %d\n"
- " ascent: %d\n"
- " descent: %d\n"
- " first char: %d (0x%02x)\n"
- " last char: %d (0x%02x)\n"
- " default char: %d (0x%02x)\n"
- " proportional: %s\n"
- " %s\n"
- "*/\n"
- "\n"
- "namespace Graphics {\n"
- "\n"
- "/* Font character bitmap data. */\n"
- "static const bitmap_t _font_bits[] = {\n"
- };
-
- ofp = fopen(path, "w");
- if (!ofp) {
- fprintf(stderr, "Can't create %s\n", path);
- return 1;
- }
-
- strcpy(buf, ctime(&t));
- buf[strlen(buf) - 1] = 0;
-
- fprintf(ofp, hdr1, buf,
- pf->name,
- pf->facename? pf->facename: "",
- pf->maxwidth, pf->height,
- pf->fbbw, pf->fbbh, pf->fbbx, pf->fbby,
- pf->size,
- pf->ascent, pf->descent,
- pf->firstchar, pf->firstchar,
- pf->firstchar+pf->size-1, pf->firstchar+pf->size-1,
- pf->defaultchar, pf->defaultchar,
- pf->width? "yes": "no",
- pf->copyright? pf->copyright: "");
-
- /* generate bitmaps*/
- for (i = 0; i < pf->size; ++i) {
- int x;
- int bitcount = 0;
- int width = pf->bbx ? pf->bbx[i].w : pf->fbbw;
- int height = pf->bbx ? pf->bbx[i].h : pf->fbbh;
- int xoff = pf->bbx ? pf->bbx[i].x : pf->fbbx;
- int yoff = pf->bbx ? pf->bbx[i].y : pf->fbby;
- bitmap_t *bits = pf->bits + (pf->offset? pf->offset[i]: (height * i));
- bitmap_t bitvalue = 0;
-
- /*
- * Generate bitmap bits only if not this index isn't
- * the default character in encode map, or the default
- * character hasn't been generated yet.
- */
- if (pf->offset &&
- (pf->offset[i] == pf->offset[pf->defaultchar-pf->firstchar])) {
- if (did_defaultchar)
- continue;
- did_defaultchar = 1;
- }
-
- fprintf(ofp, "\n/* Character %d (0x%02x):\n width %d\n bbx ( %d, %d, %d, %d )\n",
- i+pf->firstchar, i+pf->firstchar,
- pf->width ? pf->width[i+pf->firstchar] : pf->maxwidth,
- width, height, xoff, yoff);
-
- if (gen_map) {
- fprintf(ofp, "\n +");
- for (x=0; x<width; ++x) fprintf(ofp, "-");
- fprintf(ofp, "+\n");
-
- x = 0;
- h = height;
- while (h > 0) {
- if (x == 0) fprintf(ofp, " |");
-
- if (bitcount <= 0) {
- bitcount = BITMAP_BITSPERIMAGE;
- bitvalue = READ_UINT16(bits);
- bits++;
- }
-
- fprintf(ofp, BITMAP_TESTBIT(bitvalue)? "*": " ");
-
- bitvalue = BITMAP_SHIFTBIT(bitvalue);
- --bitcount;
- if (++x == width) {
- fprintf(ofp, "|\n");
- --h;
- x = 0;
- bitcount = 0;
- }
- }
- fprintf(ofp, " +");
- for (x = 0; x < width; ++x)
- fprintf(ofp, "-");
- fprintf(ofp, "+\n*/\n");
- } else
- fprintf(ofp, "\n*/\n");
-
- bits = pf->bits + (pf->offset? pf->offset[i]: (height * i));
- for (x = BITMAP_WORDS(width) * height; x > 0; --x) {
- fprintf(ofp, "0x%04x,\n", READ_UINT16(bits));
- if (!did_syncmsg && *bits++ != *ofs++) {
- fprintf(stderr, "Warning: found encoding values in non-sorted order (not an error).\n");
- did_syncmsg = 1;
- }
- }
- }
- fprintf(ofp, "};\n\n");
-
- if (pf->offset) {
- /* output offset table*/
- fprintf(ofp, "/* Character->glyph mapping. */\n"
- "static const unsigned long _sysfont_offset[] = {\n");
-
- for (i = 0; i < pf->size; ++i)
- fprintf(ofp, " %ld,\t/* (0x%02x) */\n",
- pf->offset[i], i+pf->firstchar);
- fprintf(ofp, "};\n\n");
- }
-
- /* output width table for proportional fonts*/
- if (pf->width) {
- fprintf(ofp, "/* Character width data. */\n"
- "static const unsigned char _sysfont_width[] = {\n");
-
- for (i = 0; i < pf->size; ++i)
- fprintf(ofp, " %d,\t/* (0x%02x) */\n",
- pf->width[i], i+pf->firstchar);
- fprintf(ofp, "};\n\n");
- }
-
- /* output bbox table */
- if (pf->bbx) {
- fprintf(ofp, "/* Bounding box data. */\n"
- "static const BBX _sysfont_bbx[] = {\n");
-
- for (i = 0; i < pf->size; ++i)
- fprintf(ofp, "\t{ %d, %d, %d, %d },\t/* (0x%02x) */\n",
- pf->bbx[i].w, pf->bbx[i].h, pf->bbx[i].x, pf->bbx[i].y, i+pf->firstchar);
- fprintf(ofp, "};\n\n");
- }
-
- /* output struct font struct*/
- if (pf->offset)
- sprintf(obuf, "_sysfont_offset,");
- else
- sprintf(obuf, "0, /* no encode table*/");
-
- if (pf->width)
- sprintf(buf, "_sysfont_width,");
- else
- sprintf(buf, "0, /* fixed width*/");
-
- if (pf->bbx)
- sprintf(bbuf, "_sysfont_bbx,");
- else
- sprintf(bbuf, "0, /* fixed bbox*/");
-
- fprintf(ofp,
- "/* Exported structure definition. */\n"
- "static const BdfFontDesc desc = {\n"
- "\t" "\"%s\",\n"
- "\t" "%d,\n"
- "\t" "%d,\n"
- "\t" "%d, %d, %d, %d,\n"
- "\t" "%d,\n"
- "\t" "%d,\n"
- "\t" "%d,\n"
- "\t" "_font_bits,\n"
- "\t" "%s\n"
- "\t" "%s\n"
- "\t" "%s\n"
- "\t" "%d,\n"
- "\t" "sizeof(_font_bits)/sizeof(bitmap_t)\n"
- "};\n",
- pf->name,
- pf->maxwidth, pf->height,
- pf->fbbw, pf->fbbh, pf->fbbx, pf->fbby,
- pf->ascent,
- pf->firstchar,
- pf->size,
- obuf,
- buf,
- bbuf,
- pf->defaultchar);
-
- fprintf(ofp, "\n" "#if !(defined(__GP32__))\n");
- fprintf(ofp, "extern const BdfFont g_sysfont(desc);\n");
- fprintf(ofp, "#else\n");
- fprintf(ofp, "DEFINE_FONT(g_sysfont)\n");
- fprintf(ofp, "#endif\n");
- fprintf(ofp, "\n} // End of namespace Graphics\n");
- fclose(ofp);
-
- return 0;
-}
diff --git a/devtools/convbdf.cpp b/devtools/convbdf.cpp
new file mode 100644
index 0000000000..c8b1fb7d6d
--- /dev/null
+++ b/devtools/convbdf.cpp
@@ -0,0 +1,510 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include <fstream>
+#include <string>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <time.h>
+
+struct BdfBoundingBox {
+ int width, height;
+ int xOffset, yOffset;
+};
+
+struct BdfFont {
+ int maxAdvance;
+ int height;
+ BdfBoundingBox defaultBox;
+ int ascent;
+
+ int firstCharacter;
+ int defaultCharacter;
+ int numCharacters;
+
+ unsigned char **bitmaps;
+ unsigned char *advances;
+ BdfBoundingBox *boxes;
+
+ BdfFont() : bitmaps(0), advances(0), boxes(0) {
+ }
+
+ ~BdfFont() {
+ if (bitmaps) {
+ for (int i = 0; i < numCharacters; ++i)
+ delete[] bitmaps[i];
+ }
+ delete[] bitmaps;
+ delete[] advances;
+ delete[] boxes;
+ }
+};
+
+void error(const char *s, ...) {
+ char buf[1024];
+ va_list va;
+
+ va_start(va, s);
+ vsnprintf(buf, 1024, s, va);
+ va_end(va);
+
+ fprintf(stderr, "ERROR: %s!\n", buf);
+ exit(1);
+}
+
+void warning(const char *s, ...) {
+ char buf[1024];
+ va_list va;
+
+ va_start(va, s);
+ vsnprintf(buf, 1024, s, va);
+ va_end(va);
+
+ fprintf(stderr, "WARNING: %s!\n", buf);
+}
+
+bool hasPrefix(const std::string &str, const std::string &prefix) {
+ return str.compare(0, prefix.size(), prefix) == 0;
+}
+
+inline void hexToInt(unsigned char &h) {
+ if (h >= '0' && h <= '9')
+ h -= '0';
+ else if (h >= 'A' && h <= 'F')
+ h -= 'A' - 10;
+ else if (h >= 'a' && h <= 'f')
+ h -= 'a' - 10;
+ else
+ h = 0;
+}
+
+int main(int argc, char *argv[]) {
+ if (argc != 3) {
+ printf("Usage: convbdf [input] [fontname]\n");
+ return 1;
+ }
+
+ std::ifstream in(argv[1]);
+ std::string line;
+
+ std::getline(in, line);
+ if (in.fail() || in.eof())
+ error("Premature end of file");
+
+ int verMajor, verMinor;
+ if (sscanf(line.c_str(), "STARTFONT %d.%d", &verMajor, &verMinor) != 2)
+ error("File '%s' is no BDF file", argv[1]);
+
+ if (verMajor != 2 || (verMinor != 1 && verMinor != 2))
+ error("File '%s' does not use a supported BDF version (%d.%d)", argv[1], verMajor, verMinor);
+
+ std::string fontName;
+ std::string copyright;
+ BdfFont font;
+ memset(&font, 0, sizeof(font));
+ font.ascent = -1;
+ font.defaultCharacter = -1;
+
+ int charsProcessed = 0, charsAvailable = 0, descent = -1;
+
+ while (true) {
+ std::getline(in, line);
+ if (in.fail() || in.eof())
+ error("Premature end of file");
+
+ if (hasPrefix(line, "SIZE ")) {
+ // Ignore
+ } else if (hasPrefix(line, "FONT ")) {
+ fontName = line.substr(5);
+ } else if (hasPrefix(line, "COPYRIGHT ")) {
+ copyright = line.substr(10);
+ } else if (hasPrefix(line, "COMMENT ")) {
+ // Ignore
+ } else if (hasPrefix(line, "FONTBOUNDINGBOX ")) {
+ if (sscanf(line.c_str(), "FONTBOUNDINGBOX %d %d %d %d",
+ &font.defaultBox.width, &font.defaultBox.height,
+ &font.defaultBox.xOffset, &font.defaultBox.yOffset) != 4)
+ error("Invalid FONTBOUNDINGBOX");
+ } else if (hasPrefix(line, "CHARS ")) {
+ if (sscanf(line.c_str(), "CHARS %d", &charsAvailable) != 1)
+ error("Invalid CHARS");
+
+ font.numCharacters = 256;
+ font.bitmaps = new unsigned char *[font.numCharacters];
+ memset(font.bitmaps, 0, sizeof(unsigned char *) * font.numCharacters);
+ font.advances = new unsigned char[font.numCharacters];
+ font.boxes = new BdfBoundingBox[font.numCharacters];
+ } else if (hasPrefix(line, "FONT_ASCENT ")) {
+ if (sscanf(line.c_str(), "FONT_ASCENT %d", &font.ascent) != 1)
+ error("Invalid FONT_ASCENT");
+ } else if (hasPrefix(line, "FONT_DESCENT ")) {
+ if (sscanf(line.c_str(), "FONT_DESCENT %d", &descent) != 1)
+ error("Invalid FONT_ASCENT");
+ } else if (hasPrefix(line, "DEFAULT_CHAR ")) {
+ if (sscanf(line.c_str(), "DEFAULT_CHAR %d", &font.defaultCharacter) != 1)
+ error("Invalid DEFAULT_CHAR");
+ } else if (hasPrefix(line, "STARTCHAR ")) {
+ ++charsProcessed;
+ if (charsProcessed > charsAvailable)
+ error("Too many characters defined (only %d specified, but %d existing already)",
+ charsAvailable, charsProcessed);
+
+ bool hasWidth = false, hasBitmap = false;
+
+ int encoding = -1;
+ int xAdvance;
+ unsigned char *bitmap = 0;
+ BdfBoundingBox bbox = font.defaultBox;
+
+ while (true) {
+ std::getline(in, line);
+ if (in.fail() || in.eof())
+ error("Premature end of file");
+
+ if (hasPrefix(line, "ENCODING ")) {
+ if (sscanf(line.c_str(), "ENCODING %d", &encoding) != 1)
+ error("Invalid ENCODING");
+ } else if (hasPrefix(line, "DWIDTH ")) {
+ int yAdvance;
+ if (sscanf(line.c_str(), "DWIDTH %d %d", &xAdvance, &yAdvance) != 2)
+ error("Invalid DWIDTH");
+ if (yAdvance != 0)
+ error("Character %d uses a DWIDTH y advance of %d", encoding, yAdvance);
+ if (xAdvance < 0)
+ error("Character %d has a negative x advance", encoding);
+
+ if (xAdvance > font.maxAdvance)
+ font.maxAdvance = xAdvance;
+
+ hasWidth = true;
+ } else if (hasPrefix(line, "BBX" )) {
+ if (sscanf(line.c_str(), "BBX %d %d %d %d",
+ &bbox.width, &bbox.height,
+ &bbox.xOffset, &bbox.yOffset) != 4)
+ error("Invalid BBX");
+ } else if (line == "BITMAP") {
+ hasBitmap = true;
+
+ const size_t bytesPerRow = ((bbox.width + 7) / 8);
+
+ // Since we do not load all characters, we only create a
+ // buffer for the ones we actually load.
+ if (encoding < font.numCharacters)
+ bitmap = new unsigned char[bbox.height * bytesPerRow];
+
+ for (int i = 0; i < bbox.height; ++i) {
+ std::getline(in, line);
+ if (in.fail() || in.eof())
+ error("Premature end of file");
+ if (line.size() != bytesPerRow * 2)
+ error("Glyph bitmap line too short");
+
+ if (!bitmap)
+ continue;
+
+ for (size_t j = 0; j < bytesPerRow; ++j) {
+ unsigned char nibble1 = line[j * 2 + 0];
+ hexToInt(nibble1);
+ unsigned char nibble2 = line[j * 2 + 1];
+ hexToInt(nibble2);
+ bitmap[i * bytesPerRow + j] = (nibble1 << 4) | nibble2;
+ }
+ }
+ } else if (line == "ENDCHAR") {
+ if (encoding == -1 || !hasWidth || !hasBitmap)
+ error("Character not completly defined");
+
+ if (encoding < font.numCharacters) {
+ font.advances[encoding] = xAdvance;
+ font.boxes[encoding] = bbox;
+ font.bitmaps[encoding] = bitmap;
+ }
+ break;
+ }
+ }
+ } else if (line == "ENDFONT") {
+ break;
+ } else {
+ // Silently ignore other declarations
+ //warning("Unsupported declaration: \"%s\"", line.c_str());
+ }
+ }
+
+ if (font.ascent < 0)
+ error("No ascent specified");
+ if (descent < 0)
+ error("No descent specified");
+
+ font.height = font.ascent + descent;
+
+ int firstCharacter = font.numCharacters;
+ int lastCharacter = -1;
+ bool hasFixedBBox = true;
+ bool hasFixedAdvance = true;
+
+ for (int i = 0; i < font.numCharacters; ++i) {
+ if (!font.bitmaps[i])
+ continue;
+
+ if (i < firstCharacter)
+ firstCharacter = i;
+
+ if (i > lastCharacter)
+ lastCharacter = i;
+
+ if (font.advances[i] != font.maxAdvance)
+ hasFixedAdvance = false;
+
+ const BdfBoundingBox &bbox = font.boxes[i];
+ if (bbox.width != font.defaultBox.width
+ || bbox.height != font.defaultBox.height
+ || bbox.xOffset != font.defaultBox.xOffset
+ || bbox.yOffset != font.defaultBox.yOffset)
+ hasFixedBBox = false;
+ }
+
+ if (lastCharacter == -1)
+ error("No glyphs found");
+
+ // Free the advance table, in case all glyphs use the same advance
+ if (hasFixedAdvance) {
+ delete[] font.advances;
+ font.advances = 0;
+ }
+
+ // Free the box table, in case all glyphs use the same box
+ if (hasFixedBBox) {
+ delete[] font.boxes;
+ font.boxes = 0;
+ }
+
+ // Adapt for the fact that we never use encoding 0.
+ if (font.defaultCharacter < firstCharacter
+ || font.defaultCharacter > lastCharacter)
+ font.defaultCharacter = -1;
+
+ font.firstCharacter = firstCharacter;
+
+ charsAvailable = lastCharacter - firstCharacter + 1;
+ // Try to compact the tables
+ if (charsAvailable < font.numCharacters) {
+ unsigned char **bitmaps = new unsigned char *[charsAvailable];
+ BdfBoundingBox *boxes = 0;
+ if (!hasFixedBBox)
+ boxes = new BdfBoundingBox[charsAvailable];
+ unsigned char *advances = 0;
+ if (!hasFixedAdvance)
+ advances = new unsigned char[charsAvailable];
+
+ for (int i = 0; i < charsAvailable; ++i) {
+ const int encoding = i + firstCharacter;
+ if (font.bitmaps[encoding]) {
+ bitmaps[i] = font.bitmaps[encoding];
+
+ if (!hasFixedBBox)
+ boxes[i] = font.boxes[encoding];
+ if (!hasFixedAdvance)
+ advances[i] = font.advances[encoding];
+ } else {
+ bitmaps[i] = 0;
+ }
+ }
+
+ delete[] font.bitmaps;
+ font.bitmaps = bitmaps;
+ delete[] font.advances;
+ font.advances = advances;
+ delete[] font.boxes;
+ font.boxes = boxes;
+
+ font.numCharacters = charsAvailable;
+ }
+
+ char dateBuffer[256];
+ time_t curTime = time(0);
+ snprintf(dateBuffer, sizeof(dateBuffer), "%s", ctime(&curTime));
+
+ // Finally output the cpp source file to stdout
+ printf("// Generated by convbdf on %s"
+ "#include \"graphics/fonts/bdf.h\"\n"
+ "\n"
+ "// Font information:\n"
+ "// Name: %s\n"
+ "// Size: %dx%d\n"
+ "// Box: %d %d %d %d\n"
+ "// Ascent: %d\n"
+ "// First character: %d\n"
+ "// Default character: %d\n"
+ "// Characters: %d\n"
+ "// Copyright: %s\n"
+ "\n",
+ dateBuffer, fontName.c_str(), font.maxAdvance, font.height,
+ font.defaultBox.width, font.defaultBox.height, font.defaultBox.xOffset,
+ font.defaultBox.yOffset, font.ascent, font.firstCharacter,
+ font.defaultCharacter, font.numCharacters, copyright.c_str());
+
+ printf("namespace Graphics {\n"
+ "\n");
+
+ for (int i = 0; i < font.numCharacters; ++i) {
+ if (!font.bitmaps[i])
+ continue;
+
+ BdfBoundingBox box = hasFixedBBox ? font.defaultBox : font.boxes[i];
+ printf("// Character %d (0x%02X)\n"
+ "// Box: %d %d %d %d\n"
+ "// Advance: %d\n"
+ "//\n", i + font.firstCharacter, i + font.firstCharacter,
+ box.width, box.height, box.xOffset, box.yOffset,
+ hasFixedAdvance ? font.maxAdvance : font.advances[i]);
+
+ printf("// +");
+ for (int x = 0; x < box.width; ++x)
+ printf("-");
+ printf("+\n");
+
+ const unsigned char *bitmap = font.bitmaps[i];
+
+ for (int y = 0; y < box.height; ++y) {
+ printf("// |");
+ unsigned char data;
+ for (int x = 0; x < box.width; ++x) {
+ if (!(x % 8))
+ data = *bitmap++;
+
+ printf("%c", (data & 0x80) ? '*' : ' ');
+ data <<= 1;
+ }
+ printf("|\n");
+ }
+
+ printf("// +");
+ for (int x = 0; x < box.width; ++x)
+ printf("-");
+ printf("+\n");
+
+ const int bytesPerRow = (box.width + 7) / 8;
+ bitmap = font.bitmaps[i];
+ printf("static const byte glyph%d[] = {\n", i);
+ for (int y = 0; y < box.height; ++y) {
+ printf("\t");
+
+ for (int x = 0; x < bytesPerRow; ++x) {
+ if (x)
+ printf(", ");
+ printf("0x%02X", *bitmap++);
+ }
+
+ if (y != box.height - 1)
+ printf(",");
+ printf("\n");
+ }
+ printf("};\n"
+ "\n");
+ }
+
+ printf("// Bitmap pointer table\n"
+ "const byte *const bitmapTable[] = {\n");
+ for (int i = 0; i < font.numCharacters; ++i) {
+ if (font.bitmaps[i])
+ printf("\tglyph%d", i);
+ else
+ printf("\t0");
+
+ if (i != font.numCharacters - 1)
+ printf(",");
+ printf("\n");
+ }
+ printf("};\n"
+ "\n");
+
+ if (!hasFixedAdvance) {
+ printf("// Advance table\n"
+ "static const byte advances[] = {\n");
+ for (int i = 0; i < font.numCharacters; ++i) {
+ if (font.bitmaps[i])
+ printf("\t%d", font.advances[i]);
+ else
+ printf("\t0");
+
+ if (i != font.numCharacters - 1)
+ printf(",");
+ printf("\n");
+ }
+ printf("};\n"
+ "\n");
+ }
+
+ if (!hasFixedBBox) {
+ printf("// Bounding box table\n"
+ "static const BdfBoundingBox boxes[] = {\n");
+ for (int i = 0; i < font.numCharacters; ++i) {
+ if (font.bitmaps[i]) {
+ const BdfBoundingBox &box = font.boxes[i];
+ printf("\t{ %d, %d, %d, %d }", box.width, box.height, box.xOffset, box.yOffset);
+ } else {
+ printf("\t{ 0, 0, 0, 0 }");
+ }
+
+ if (i != font.numCharacters - 1)
+ printf(",");
+ printf("\n");
+ }
+ printf("};\n"
+ "\n");
+ }
+
+ printf("// Font structure\n"
+ "static const BdfFontData desc = {\n"
+ "\t%d, // Max advance\n"
+ "\t%d, // Height\n"
+ "\t{ %d, %d, %d, %d }, // Bounding box\n"
+ "\t%d, // Ascent\n"
+ "\n"
+ "\t%d, // First character\n"
+ "\t%d, // Default character\n"
+ "\t%d, // Characters\n"
+ "\n"
+ "\tbitmapTable, // Bitmaps\n",
+ font.maxAdvance, font.height, font.defaultBox.width,
+ font.defaultBox.height, font.defaultBox.xOffset, font.defaultBox.yOffset,
+ font.ascent, font.firstCharacter, font.defaultCharacter, font.numCharacters);
+
+ if (hasFixedAdvance)
+ printf("\t0, // Advances\n");
+ else
+ printf("\tadvances, // Advances\n");
+
+ if (hasFixedBBox)
+ printf("\t0 // Boxes\n");
+ else
+ printf("\tboxes // Boxes\n");
+
+ printf("};\n"
+ "\n"
+ "DEFINE_FONT(%s)\n"
+ "\n"
+ "} // End of namespace Graphics\n",
+ argv[2]);
+}
diff --git a/devtools/create_hugo/enums.h b/devtools/create_hugo/enums.h
index f721c3d4f5..667d7ebce1 100644
--- a/devtools/create_hugo/enums.h
+++ b/devtools/create_hugo/enums.h
@@ -1501,7 +1501,7 @@ enum objid_3d {
};
// Enumerate sequence index matching direction of travel
-enum {RIGHT, LEFT, DOWN, _UP};
+enum {RIGHT, LEFT, DOWN, __UP};
enum sound_t_1w {
//Hugo 1 Win
diff --git a/devtools/create_hugo/staticdata.h b/devtools/create_hugo/staticdata.h
index 612e044982..0ead2109d0 100644
--- a/devtools/create_hugo/staticdata.h
+++ b/devtools/create_hugo/staticdata.h
@@ -6171,8 +6171,8 @@ act16 adogseq2_1w = {INIT_OBJ_SEQ, 4 * NORMAL_TPS_v2d, DOG_1w, 2};
act16 adog5_1w = {INIT_OBJ_SEQ, 0, DOG_1w, 0};
act16 at78c_1w = {INIT_OBJ_SEQ, NORMAL_TPS_v2d + 12, TRAP_1w, 0};
act16 arock3_1w = {INIT_OBJ_SEQ, 0, HERO, RIGHT};
-act16 arock5_1w = {INIT_OBJ_SEQ, 11, HERO, _UP};
-act16 arock10_1w = {INIT_OBJ_SEQ, 40, HERO, _UP};
+act16 arock5_1w = {INIT_OBJ_SEQ, 11, HERO, __UP};
+act16 arock10_1w = {INIT_OBJ_SEQ, 40, HERO, __UP};
act16 arock12_1w = {INIT_OBJ_SEQ, 44, HERO, DOWN};
act16 acutrope_1w = {INIT_OBJ_SEQ, 0, ROPE_1w, 1};
act16 abin1_1w = {INIT_OBJ_SEQ, 0, BOAT_1w, 1};
@@ -7192,9 +7192,9 @@ act16 abd11_2w = {INIT_OBJ_SEQ, 0, HERO, DOWN};
act16 abd2_2w = {INIT_OBJ_SEQ, 0, HERO, DOWN};
act16 abd21_2w = {INIT_OBJ_SEQ, 0, HERO, DOWN};
act16 aclosedoor1_2w = {INIT_OBJ_SEQ, DOORDELAY, DOOR1_2w, 0};
-act16 adone10_2w = {INIT_OBJ_SEQ, 10, HERO, _UP};
+act16 adone10_2w = {INIT_OBJ_SEQ, 10, HERO, __UP};
act16 adone6_2w = {INIT_OBJ_SEQ, 0, HORACE_2w, LEFT};
-act16 adone9_2w = {INIT_OBJ_SEQ, 10, HORACE_2w, _UP};
+act16 adone9_2w = {INIT_OBJ_SEQ, 10, HORACE_2w, __UP};
act16 adumb13_2w = {INIT_OBJ_SEQ, 0, HERO, DOWN};
act16 adumb3_2w = {INIT_OBJ_SEQ, 0, HERO, RIGHT};
act16 afuze1_2w = {INIT_OBJ_SEQ, 0, DYNAMITE_2w, 1};
@@ -7202,10 +7202,10 @@ act16 agiveb5_2w = {INIT_OBJ_SEQ, 2, CAT_2w, 1};
act16 ahall1_3_2w = {INIT_OBJ_SEQ, 0, HERO, RIGHT};
act16 ahall2_2a_2w = {INIT_OBJ_SEQ, 0, HERO, LEFT};
act16 ahall3_1a_2w = {INIT_OBJ_SEQ, 0, HERO, DOWN};
-act16 ahdrink4_2w = {INIT_OBJ_SEQ, 3, HESTER_2w, _UP};
+act16 ahdrink4_2w = {INIT_OBJ_SEQ, 3, HESTER_2w, __UP};
act16 ahdrink5_2w = {INIT_OBJ_SEQ, 70, HESTER_2w, DOWN};
act16 ahest3_2w = {INIT_OBJ_SEQ, 0, HESTER_2w, RIGHT};
-act16 ahest5_2w = {INIT_OBJ_SEQ, 22, HESTER_2w, _UP};
+act16 ahest5_2w = {INIT_OBJ_SEQ, 22, HESTER_2w, __UP};
act16 ahest7_2w = {INIT_OBJ_SEQ, 24, HESTER_2w, LEFT};
act16 ahest9_2w = {INIT_OBJ_SEQ, 45, HESTER_2w, DOWN};
act16 ainshed2_2w = {INIT_OBJ_SEQ, 0, HERO, DOWN};
@@ -7236,11 +7236,11 @@ act16 amaidc4_2w = {INIT_OBJ_SEQ, 8, MAID_2w, RIGHT};
act16 amaidc7_2w = {INIT_OBJ_SEQ, 16, MAID_2w, LEFT};
act16 amaidp6_2w = {INIT_OBJ_SEQ, 10, MAID_2w, DOWN};
act16 apenbseq1_2w = {INIT_OBJ_SEQ, 0, PENNY_2w, RIGHT};
-act16 apenbseq2_2w = {INIT_OBJ_SEQ, 25, PENNY_2w, _UP};
+act16 apenbseq2_2w = {INIT_OBJ_SEQ, 25, PENNY_2w, __UP};
act16 apenseq1_2w = {INIT_OBJ_SEQ, 0, PENNY_2w, RIGHT};
act16 apenseq2_2w = {INIT_OBJ_SEQ, PENDELAY + 7, PENNY_2w, DOWN};
act16 apenseq3_2w = {INIT_OBJ_SEQ, PENDELAY + 10, PENNY_2w, LEFT};
-act16 apenseq4_2w = {INIT_OBJ_SEQ, PENDELAY + 17, PENNY_2w, _UP};
+act16 apenseq4_2w = {INIT_OBJ_SEQ, PENDELAY + 17, PENNY_2w, __UP};
act16 apenseq5_2w = {INIT_OBJ_SEQ, PENDELAY + 42, PENNY_2w, RIGHT};
act16 apenseq6_2w = {INIT_OBJ_SEQ, PENDELAY + 74, PENNY_2w, 2};
@@ -8254,12 +8254,12 @@ act16 acamp7b_3w = {INIT_OBJ_SEQ, 40, NATG_3w, 2};
act16 acrash10_3w = {INIT_OBJ_SEQ, 8, HERO, LEFT};
act16 acrash15_3w = {INIT_OBJ_SEQ, 21, PENNY_3w, DOWN};
act16 acrash16_3w = {INIT_OBJ_SEQ, 22, PENNY_3w, LEFT};
-act16 acrash18_3w = {INIT_OBJ_SEQ, 40, HERO, _UP};
+act16 acrash18_3w = {INIT_OBJ_SEQ, 40, HERO, __UP};
act16 acrash2_3w = {INIT_OBJ_SEQ, 1, PENNY_3w, DOWN};
act16 acrash3_3w = {INIT_OBJ_SEQ, 1, HERO, DOWN};
act16 acrash8_3w = {INIT_OBJ_SEQ, 4, PENNY_3w, RIGHT};
act16 adart6_3w = {INIT_OBJ_SEQ, DARTTIME - 1, E_EYES_3w, 1};
-act16 adoc1_3w = {INIT_OBJ_SEQ, 0, HERO, _UP};
+act16 adoc1_3w = {INIT_OBJ_SEQ, 0, HERO, __UP};
act16 aeleblink1_3w = {INIT_OBJ_SEQ, 41, E_EYES_3w, 1};
act16 aeleblink2_3w = {INIT_OBJ_SEQ, 42, E_EYES_3w, 0};
act16 aeleblink3_3w = {INIT_OBJ_SEQ, 43, E_EYES_3w, 1};
@@ -10145,9 +10145,9 @@ act16 abd2_2d = {INIT_OBJ_SEQ, 0, HERO, DOWN};
act16 abd21_2d = {INIT_OBJ_SEQ, 0, HERO, DOWN};
act16 aclosedoor1_2d = {INIT_OBJ_SEQ, DOORDELAY, DOOR1_2d, 0};
act16 adalek2_2d = {INIT_OBJ_SEQ, 0, DALEK_2d, 2};
-act16 adone10_2d = {INIT_OBJ_SEQ, 10, HERO, _UP};
+act16 adone10_2d = {INIT_OBJ_SEQ, 10, HERO, __UP};
act16 adone6_2d = {INIT_OBJ_SEQ, 0, HORACE_2d, LEFT};
-act16 adone9_2d = {INIT_OBJ_SEQ, 10, HORACE_2d, _UP};
+act16 adone9_2d = {INIT_OBJ_SEQ, 10, HORACE_2d, __UP};
act16 adumb13_2d = {INIT_OBJ_SEQ, 0, HERO, DOWN};
act16 adumb3_2d = {INIT_OBJ_SEQ, 0, HERO, RIGHT};
act16 afuze1_2d = {INIT_OBJ_SEQ, 0, DYNAMITE_2d, 1};
@@ -10155,10 +10155,10 @@ act16 agiveb5_2d = {INIT_OBJ_SEQ, 2, CAT_2d, 1};
act16 ahall1_3_2d = {INIT_OBJ_SEQ, 0, HERO, RIGHT};
act16 ahall2_2a_2d = {INIT_OBJ_SEQ, 0, HERO, LEFT};
act16 ahall3_1a_2d = {INIT_OBJ_SEQ, 0, HERO, DOWN};
-act16 ahdrink4_2d = {INIT_OBJ_SEQ, 3, HESTER_2d, _UP};
+act16 ahdrink4_2d = {INIT_OBJ_SEQ, 3, HESTER_2d, __UP};
act16 ahdrink5_2d = {INIT_OBJ_SEQ, 50, HESTER_2d, DOWN};
act16 ahest3_2d = {INIT_OBJ_SEQ, 0, HESTER_2d, RIGHT};
-act16 ahest5_2d = {INIT_OBJ_SEQ, 22, HESTER_2d, _UP};
+act16 ahest5_2d = {INIT_OBJ_SEQ, 22, HESTER_2d, __UP};
act16 ahest7_2d = {INIT_OBJ_SEQ, 24, HESTER_2d, LEFT};
act16 ahest9_2d = {INIT_OBJ_SEQ, 45, HESTER_2d, DOWN};
act16 ainshed2_2d = {INIT_OBJ_SEQ, 0, HERO, DOWN};
@@ -10188,11 +10188,11 @@ act16 amaidc4_2d = {INIT_OBJ_SEQ, 8, MAID_2d, RIGHT};
act16 amaidc7_2d = {INIT_OBJ_SEQ, 16, MAID_2d, LEFT};
act16 amaidp6_2d = {INIT_OBJ_SEQ, 10, MAID_2d, DOWN};
act16 apenbseq1_2d = {INIT_OBJ_SEQ, 0, PENNY_2d, RIGHT};
-act16 apenbseq2_2d = {INIT_OBJ_SEQ, 25, PENNY_2d, _UP};
+act16 apenbseq2_2d = {INIT_OBJ_SEQ, 25, PENNY_2d, __UP};
act16 apenseq1_2d = {INIT_OBJ_SEQ, 0, PENNY_2d, RIGHT};
act16 apenseq2_2d = {INIT_OBJ_SEQ, PENDELAY + 7, PENNY_2d, DOWN};
act16 apenseq3_2d = {INIT_OBJ_SEQ, PENDELAY + 10, PENNY_2d, LEFT};
-act16 apenseq4_2d = {INIT_OBJ_SEQ, PENDELAY + 17, PENNY_2d, _UP};
+act16 apenseq4_2d = {INIT_OBJ_SEQ, PENDELAY + 17, PENNY_2d, __UP};
act16 apenseq5_2d = {INIT_OBJ_SEQ, PENDELAY + 42, PENNY_2d, RIGHT};
act16 apenseq6_2d = {INIT_OBJ_SEQ, PENDELAY + 74, PENNY_2d, 2};
@@ -11155,12 +11155,12 @@ act16 acamp7b_3d = {INIT_OBJ_SEQ, 40, NATG_3d, 2};
act16 acrash10_3d = {INIT_OBJ_SEQ, 8, HERO, LEFT};
act16 acrash15_3d = {INIT_OBJ_SEQ, 21, PENNY_3d, DOWN};
act16 acrash16_3d = {INIT_OBJ_SEQ, 22, PENNY_3d, LEFT};
-act16 acrash18_3d = {INIT_OBJ_SEQ, 40, HERO, _UP};
+act16 acrash18_3d = {INIT_OBJ_SEQ, 40, HERO, __UP};
act16 acrash2_3d = {INIT_OBJ_SEQ, 1, PENNY_3d, DOWN};
act16 acrash3_3d = {INIT_OBJ_SEQ, 1, HERO, DOWN};
act16 acrash8_3d = {INIT_OBJ_SEQ, 4, PENNY_3d, RIGHT};
act16 adart6_3d = {INIT_OBJ_SEQ, DARTTIME - 1, E_EYES_3d, 1};
-act16 adoc1_3d = {INIT_OBJ_SEQ, 0, HERO, _UP};
+act16 adoc1_3d = {INIT_OBJ_SEQ, 0, HERO, __UP};
act16 aeleblink1_3d = {INIT_OBJ_SEQ, 41, E_EYES_3d, 1};
act16 aeleblink2_3d = {INIT_OBJ_SEQ, 42, E_EYES_3d, 0};
act16 aeleblink3_3d = {INIT_OBJ_SEQ, 43, E_EYES_3d, 1};
diff --git a/devtools/create_kyradat/create_kyradat.cpp b/devtools/create_kyradat/create_kyradat.cpp
index 627b517c62..489be3e04d 100644
--- a/devtools/create_kyradat/create_kyradat.cpp
+++ b/devtools/create_kyradat/create_kyradat.cpp
@@ -45,7 +45,7 @@
#include <map>
enum {
- kKyraDatVersion = 78
+ kKyraDatVersion = 82
};
const ExtractFilename extractFilenames[] = {
@@ -215,92 +215,482 @@ const ExtractFilename extractFilenames[] = {
{ k3ItemMagicTable, k3TypeRaw16to8, false },
{ k3ItemStringMap, kTypeRawData, false },
+ // EYE OF THE BEHOLDER COMMON
+ { kEoBBaseChargenStrings1, kTypeStringList, true },
+ { kEoBBaseChargenStrings2, kTypeStringList, true },
+ { kEoBBaseChargenStartLevels, kTypeRawData, false },
+ { kEoBBaseChargenStatStrings, kTypeStringList, true},
+ { kEoBBaseChargenRaceSexStrings, kTypeStringList, true },
+ { kEoBBaseChargenClassStrings, kTypeStringList, true },
+ { kEoBBaseChargenAlignmentStrings, kTypeStringList, true },
+ { kEoBBaseChargenEnterGameStrings, kTypeStringList, true },
+ { kEoBBaseChargenClassMinStats, k3TypeRaw16to8, false },
+ { kEoBBaseChargenRaceMinStats, k3TypeRaw16to8, false },
+ { kEoBBaseChargenRaceMaxStats, kLoLTypeRaw16, false },
+
+ { kEoBBaseSaveThrowTable1, kTypeRawData, false },
+ { kEoBBaseSaveThrowTable2, kTypeRawData, false },
+ { kEoBBaseSaveThrowTable3, kTypeRawData, false },
+ { kEoBBaseSaveThrowTable4, kTypeRawData, false },
+ { kEoBBaseSaveThrwLvlIndex, kTypeRawData, false },
+ { kEoBBaseSaveThrwModDiv, kTypeRawData, false },
+ { kEoBBaseSaveThrwModExt, kTypeRawData, false },
+
+ { kEoBBasePryDoorStrings, kTypeStringList, true },
+ { kEoBBaseWarningStrings, kTypeStringList, true },
+
+ { kEoBBaseItemSuffixStringsRings, kTypeStringList, true },
+ { kEoBBaseItemSuffixStringsPotions, kTypeStringList, true },
+ { kEoBBaseItemSuffixStringsWands, kTypeStringList, true },
+
+ { kEoBBaseRipItemStrings, kTypeStringList, true },
+ { kEoBBaseCursedString, kTypeStringList, true },
+ { kEoBBaseEnchantedString, kTypeStringList, false },
+ { kEoBBaseMagicObjectStrings, kTypeStringList, true },
+ { kEoBBaseMagicObject5String, kTypeStringList, true },
+ { kEoBBasePatternSuffix, kTypeStringList, true },
+ { kEoBBasePatternGrFix1, kTypeStringList, true },
+ { kEoBBasePatternGrFix2, kTypeStringList, true },
+ { kEoBBaseValidateArmorString, kTypeStringList, true },
+ { kEoBBaseValidateCursedString, kTypeStringList, true },
+ { kEoBBaseValidateNoDropString, kTypeStringList, true },
+ { kEoBBasePotionStrings, kTypeStringList, true },
+ { kEoBBaseWandString, kTypeStringList, true },
+ { kEoBBaseItemMisuseStrings, kTypeStringList, true },
+
+ { kEoBBaseTakenStrings, kTypeStringList, true },
+ { kEoBBasePotionEffectStrings, kTypeStringList, true },
+
+ { kEoBBaseYesNoStrings, kTypeStringList, true },
+ { kRpgCommonMoreStrings, kTypeStringList, true },
+ { kEoBBaseNpcMaxStrings, kTypeStringList, true },
+ { kEoBBaseOkStrings, kTypeStringList, true },
+ { kEoBBaseNpcJoinStrings, kTypeStringList, true },
+ { kEoBBaseCancelStrings, kTypeStringList, true },
+ { kEoBBaseAbortStrings, kTypeStringList, true },
+
+ { kEoBBaseMenuStringsMain, kTypeStringList, true },
+ { kEoBBaseMenuStringsSaveLoad, kTypeStringList, true },
+ { kEoBBaseMenuStringsOnOff, kTypeStringList, true },
+ { kEoBBaseMenuStringsSpells, kTypeStringList, true },
+ { kEoBBaseMenuStringsRest, kTypeStringList, true },
+ { kEoBBaseMenuStringsDrop, kTypeStringList, true },
+ { kEoBBaseMenuStringsExit, kTypeStringList, true },
+ { kEoBBaseMenuStringsStarve, kTypeStringList, true },
+ { kEoBBaseMenuStringsScribe, kTypeStringList, true },
+ { kEoBBaseMenuStringsDrop2, kTypeStringList, true },
+ { kEoBBaseMenuStringsHead, kTypeStringList, true },
+ { kEoBBaseMenuStringsPoison, kTypeStringList, true },
+ { kEoBBaseMenuStringsMgc, kTypeStringList, true },
+ { kEoBBaseMenuStringsPrefs, kTypeStringList, true },
+ { kEoBBaseMenuStringsRest2, kTypeStringList, true },
+ { kEoBBaseMenuStringsRest3, kTypeStringList, true },
+ { kEoBBaseMenuStringsRest4, kTypeStringList, true },
+ { kEoBBaseMenuStringsDefeat, kTypeStringList, true },
+ { kEoBBaseMenuStringsTransfer, kTypeStringList, true },
+ { kEoBBaseMenuStringsSpec, kTypeStringList, true },
+ { kEoBBaseMenuStringsSpellNo, kTypeStringList, false },
+ { kEoBBaseMenuYesNoStrings, kTypeStringList, true },
+
+ { kEoBBaseSpellLevelsMage, kTypeRawData, false },
+ { kEoBBaseSpellLevelsCleric, kTypeRawData, false },
+ { kEoBBaseNumSpellsCleric, kTypeRawData, false },
+ { kEoBBaseNumSpellsWisAdj, kTypeRawData, false },
+ { kEoBBaseNumSpellsPal, kTypeRawData, false },
+ { kEoBBaseNumSpellsMage, kTypeRawData, false },
+
+ { kEoBBaseCharGuiStringsHp, kTypeStringList, true },
+ { kEoBBaseCharGuiStringsWp1, kTypeStringList, true },
+ { kEoBBaseCharGuiStringsWp2, kTypeStringList, true },
+ { kEoBBaseCharGuiStringsWr, kTypeStringList, true },
+ { kEoBBaseCharGuiStringsSt1, kTypeStringList, true },
+ { kEoBBaseCharGuiStringsSt2, kTypeStringList, true },
+ { kEoBBaseCharGuiStringsIn, kTypeStringList, true },
+
+ { kEoBBaseCharStatusStrings7, kTypeStringList, true },
+ { kEoBBaseCharStatusStrings81, kTypeStringList, true },
+ { kEoBBaseCharStatusStrings82, kTypeStringList, true },
+ { kEoBBaseCharStatusStrings9, kTypeStringList, true },
+ { kEoBBaseCharStatusStrings12, kTypeStringList, true },
+ { kEoBBaseCharStatusStrings131, kTypeStringList, true },
+ { kEoBBaseCharStatusStrings132, kTypeStringList, true },
+
+ { kEoBBaseLevelGainStrings, kTypeStringList, true },
+ { kEoBBaseExperienceTable0, kLoLTypeRaw32, false },
+ { kEoBBaseExperienceTable1, kLoLTypeRaw32, false },
+ { kEoBBaseExperienceTable2, kLoLTypeRaw32, false },
+ { kEoBBaseExperienceTable3, kLoLTypeRaw32, false },
+ { kEoBBaseExperienceTable4, kLoLTypeRaw32, false },
+
+ { kEoBBaseWllFlagPreset, kTypeRawData, false },
+ { kEoBBaseDscShapeCoords, kLoLTypeRaw16, false },
+ { kEoBBaseDscDoorScaleOffs, kTypeRawData, false },
+ { kEoBBaseDscDoorScaleMult1, kTypeRawData, false },
+ { kEoBBaseDscDoorScaleMult2, kTypeRawData, false },
+ { kEoBBaseDscDoorScaleMult3, kTypeRawData, false },
+ { kEoBBaseDscDoorScaleMult4, kTypeRawData, false },
+ { kEoBBaseDscDoorScaleMult5, kTypeRawData, false },
+ { kEoBBaseDscDoorScaleMult6, kTypeRawData, false },
+ { kEoBBaseDscDoorType5Offs, kTypeRawData, false },
+ { kEoBBaseDscDoorXE, kTypeRawData, false },
+ { kEoBBaseDscDoorY1, kTypeRawData, false },
+ { kEoBBaseDscDoorY3, kTypeRawData, false },
+ { kEoBBaseDscDoorY4, kTypeRawData, false },
+ { kEoBBaseDscDoorY5, kTypeRawData, false },
+ { kEoBBaseDscDoorY6, kTypeRawData, false },
+ { kEoBBaseDscDoorY7, kTypeRawData, false },
+ { kEoBBaseDscDoorCoordsExt, kLoLTypeRaw16, false },
+
+ { kEoBBaseDscItemPosIndex, kTypeRawData, false },
+ { kEoBBaseDscItemShpX, kLoLTypeRaw16, false },
+ { kEoBBaseDscItemPosUnk, kTypeRawData, false },
+ { kEoBBaseDscItemTileIndex, kTypeRawData, false },
+ { kEoBBaseDscItemShapeMap, kTypeRawData, false },
+ { kEoBBaseDscTelptrShpCoords, kTypeRawData, false },
+
+ { kEoBBasePortalSeqData, kTypeRawData, false },
+ { kEoBBaseManDef, kTypeRawData, true },
+ { kEoBBaseManWord, kTypeStringList, true },
+ { kEoBBaseManPrompt, kTypeStringList, true },
+
+ { kEoBBaseDscMonsterFrmOffsTbl1, kTypeRawData, false },
+ { kEoBBaseDscMonsterFrmOffsTbl2, kTypeRawData, false },
+
+ { kEoBBaseInvSlotX, kLoLTypeRaw16, false },
+ { kEoBBaseInvSlotY, kTypeRawData, false },
+ { kEoBBaseSlotValidationFlags, kLoLTypeRaw16, false },
+
+ { kEoBBaseProjectileWeaponTypes, kTypeRawData, false },
+ { kEoBBaseWandTypes, kTypeRawData, false },
+
+ { kEoBBaseDrawObjPosIndex, kTypeRawData, false },
+ { kEoBBaseFlightObjFlipIndex, kTypeRawData, false },
+ { kEoBBaseFlightObjShpMap, kTypeRawData, false },
+ { kEoBBaseFlightObjSclIndex, kTypeRawData, false },
+
+ { kEoBBaseBookNumbers, kTypeStringList, true },
+ { kEoBBaseMageSpellsList, kTypeStringList, true },
+ { kEoBBaseClericSpellsList, kTypeStringList, true },
+ { kEoBBaseSpellNames, kTypeStringList, true },
+
+ { kEoBBaseMagicStrings1, kTypeStringList, true },
+ { kEoBBaseMagicStrings2, kTypeStringList, true },
+ { kEoBBaseMagicStrings3, kTypeStringList, true },
+ { kEoBBaseMagicStrings4, kTypeStringList, true },
+ { kEoBBaseMagicStrings6, kTypeStringList, true },
+ { kEoBBaseMagicStrings7, kTypeStringList, true },
+ { kEoBBaseMagicStrings8, kTypeStringList, true },
+
+ { kEoBBaseExpObjectTlMode, kTypeRawData, false },
+ { kEoBBaseExpObjectTblIndex, kTypeRawData, false },
+ { kEoBBaseExpObjectShpStart, kTypeRawData, false },
+ { kEoBBaseExpObjectTbl1, kTypeRawData, false },
+ { kEoBBaseExpObjectTbl2, kTypeRawData, false },
+ { kEoBBaseExpObjectTbl3, kTypeRawData, false },
+ { kEoBBaseExpObjectY, k3TypeRaw16to8, false },
+
+ { kEoBBaseSparkDefSteps, kTypeRawData, false },
+ { kEoBBaseSparkDefSubSteps, kTypeRawData, false },
+ { kEoBBaseSparkDefShift, kTypeRawData, false },
+ { kEoBBaseSparkDefAdd, kTypeRawData, false },
+ { kEoBBaseSparkDefX, k3TypeRaw16to8, false },
+ { kEoBBaseSparkDefY, kTypeRawData, false },
+ { kEoBBaseSparkOfFlags1, kLoLTypeRaw32, false },
+ { kEoBBaseSparkOfFlags2, kLoLTypeRaw32, false },
+ { kEoBBaseSparkOfShift, kTypeRawData, false },
+ { kEoBBaseSparkOfX, kTypeRawData, false },
+ { kEoBBaseSparkOfY, kTypeRawData, false },
+ { kEoBBaseSpellProperties, kTypeRawData, false },
+ { kEoBBaseMagicFlightProps, kTypeRawData, false },
+ { kEoBBaseTurnUndeadEffect, kTypeRawData, false },
+ { kEoBBaseBurningHandsDest, kTypeRawData, false },
+ { kEoBBaseConeOfColdDest1, kTypeRawData, false },
+ { kEoBBaseConeOfColdDest2, kTypeRawData, false },
+ { kEoBBaseConeOfColdDest3, kTypeRawData, false },
+ { kEoBBaseConeOfColdDest4, kTypeRawData, false },
+ { kEoBBaseConeOfColdGfxTbl, k3TypeRaw16to8, false },
+
+ // EYE OF THE BEHOLDER I
+ { kEoB1MainMenuStrings, kTypeStringList, true },
+ { kEoB1BonusStrings, kTypeStringList, true },
+
+ { kEoB1IntroFilesOpening, kTypeStringList, false },
+ { kEoB1IntroFilesTower, kTypeStringList, false },
+ { kEoB1IntroFilesOrb, kTypeStringList, false },
+ { kEoB1IntroFilesWdEntry, kTypeStringList, false },
+ { kEoB1IntroFilesKing, kTypeStringList, false },
+ { kEoB1IntroFilesHands, kTypeStringList, false },
+ { kEoB1IntroFilesWdExit, kTypeStringList, false },
+ { kEoB1IntroFilesTunnel, kTypeStringList, false },
+ { kEoB1IntroOpeningFrmDelay, k3TypeRaw16to8, false },
+ { kEoB1IntroWdEncodeX, kTypeRawData, false },
+ { kEoB1IntroWdEncodeY, kTypeRawData, false },
+ { kEoB1IntroWdEncodeWH, kTypeRawData, false },
+ { kEoB1IntroWdDsX, kLoLTypeRaw16, false },
+ { kEoB1IntroWdDsY, kTypeRawData, false },
+ { kEoB1IntroTvlX1, kTypeRawData, false },
+ { kEoB1IntroTvlY1, kTypeRawData, false },
+ { kEoB1IntroTvlX2, kTypeRawData, false },
+ { kEoB1IntroTvlY2, kTypeRawData, false },
+ { kEoB1IntroTvlW, kTypeRawData, false },
+ { kEoB1IntroTvlH, kTypeRawData, false },
+
+ { kEoB1DoorShapeDefs, kTypeRawData, false },
+ { kEoB1DoorSwitchShapeDefs, kTypeRawData, false },
+ { kEoB1DoorSwitchCoords, kTypeRawData, false },
+ { kEoB1MonsterProperties, kTypeRawData, false },
+ { kEoB1EnemyMageSpellList, kTypeRawData, false },
+ { kEoB1EnemyMageSfx, kTypeRawData, false },
+ { kEoB1BeholderSpellList, kTypeRawData, false },
+ { kEoB1BeholderSfx, kTypeRawData, false },
+ { kEoB1TurnUndeadString, kTypeStringList, true },
+
+ { kEoB1CgaMappingDefault, kTypeRawData, false },
+ { kEoB1CgaMappingAlt, kTypeRawData, false },
+ { kEoB1CgaMappingInv, kTypeRawData, false },
+ { kEoB1CgaMappingItemsL, kTypeRawData, false },
+ { kEoB1CgaMappingItemsS, kTypeRawData, false },
+ { kEoB1CgaMappingThrown, kTypeRawData, false },
+ { kEoB1CgaMappingIcons, kTypeRawData, false },
+ { kEoB1CgaMappingDeco, kTypeRawData, false },
+ { kEoB1CgaLevelMappingIndex, kTypeRawData, false },
+ { kEoB1CgaMappingLevel0, kTypeRawData, false },
+ { kEoB1CgaMappingLevel1, kTypeRawData, false },
+ { kEoB1CgaMappingLevel2, kTypeRawData, false },
+ { kEoB1CgaMappingLevel3, kTypeRawData, false },
+ { kEoB1CgaMappingLevel4, kTypeRawData, false },
+
+ { kEoB1NpcShpData, kTypeRawData, false },
+ { kEoB1NpcSubShpIndex1, kTypeRawData, false },
+ { kEoB1NpcSubShpIndex2, kTypeRawData, false },
+ { kEoB1NpcSubShpY, kTypeRawData, false },
+ { kEoB1Npc0Strings, kTypeStringList, true },
+ { kEoB1Npc11Strings, kTypeStringList, true },
+ { kEoB1Npc12Strings, kTypeStringList, true },
+ { kEoB1Npc21Strings, kTypeStringList, true },
+ { kEoB1Npc22Strings, kTypeStringList, true },
+ { kEoB1Npc31Strings, kTypeStringList, true },
+ { kEoB1Npc32Strings, kTypeStringList, true },
+ { kEoB1Npc4Strings, kTypeStringList, true },
+ { kEoB1Npc5Strings, kTypeStringList, true },
+ { kEoB1Npc6Strings, kTypeStringList, true },
+ { kEoB1Npc7Strings, kTypeStringList, true },
+
+ // EYE OF THE BEHOLDER II
+ { kEoB2MainMenuStrings, kTypeStringList, true },
+
+ { kEoB2TransferPortraitFrames, kLoLTypeRaw16, false },
+ { kEoB2TransferConvertTable, kTypeRawData, false },
+ { kEoB2TransferItemTable, kTypeRawData, false },
+ { kEoB2TransferExpTable, kLoLTypeRaw32, false },
+ { kEoB2TransferStrings1, kTypeStringList, true },
+ { kEoB2TransferStrings2, kTypeStringList, true },
+ { kEoB2TransferLabels, kTypeStringList, true },
+
+ { kEoB2IntroStrings, k2TypeSfxList, true },
+ { kEoB2IntroCPSFiles, kTypeStringList, true },
+ { kEob2IntroAnimData00, kEoB2TypeSeqData, false },
+ { kEob2IntroAnimData01, kEoB2TypeSeqData, false },
+ { kEob2IntroAnimData02, kEoB2TypeSeqData, false },
+ { kEob2IntroAnimData03, kEoB2TypeSeqData, false },
+ { kEob2IntroAnimData04, kEoB2TypeSeqData, false },
+ { kEob2IntroAnimData05, kEoB2TypeSeqData, false },
+ { kEob2IntroAnimData06, kEoB2TypeSeqData, false },
+ { kEob2IntroAnimData07, kEoB2TypeSeqData, false },
+ { kEob2IntroAnimData08, kEoB2TypeSeqData, false },
+ { kEob2IntroAnimData09, kEoB2TypeSeqData, false },
+ { kEob2IntroAnimData10, kEoB2TypeSeqData, false },
+ { kEob2IntroAnimData11, kEoB2TypeSeqData, false },
+ { kEob2IntroAnimData12, kEoB2TypeSeqData, false },
+ { kEob2IntroAnimData13, kEoB2TypeSeqData, false },
+ { kEob2IntroAnimData14, kEoB2TypeSeqData, false },
+ { kEob2IntroAnimData15, kEoB2TypeSeqData, false },
+ { kEob2IntroAnimData16, kEoB2TypeSeqData, false },
+ { kEob2IntroAnimData17, kEoB2TypeSeqData, false },
+ { kEob2IntroAnimData18, kEoB2TypeSeqData, false },
+ { kEob2IntroAnimData19, kEoB2TypeSeqData, false },
+ { kEob2IntroAnimData20, kEoB2TypeSeqData, false },
+ { kEob2IntroAnimData21, kEoB2TypeSeqData, false },
+ { kEob2IntroAnimData22, kEoB2TypeSeqData, false },
+ { kEob2IntroAnimData23, kEoB2TypeSeqData, false },
+ { kEob2IntroAnimData24, kEoB2TypeSeqData, false },
+ { kEob2IntroAnimData25, kEoB2TypeSeqData, false },
+ { kEob2IntroAnimData26, kEoB2TypeSeqData, false },
+ { kEob2IntroAnimData27, kEoB2TypeSeqData, false },
+ { kEob2IntroAnimData28, kEoB2TypeSeqData, false },
+ { kEob2IntroAnimData29, kEoB2TypeSeqData, false },
+ { kEob2IntroAnimData30, kEoB2TypeSeqData, false },
+ { kEob2IntroAnimData31, kEoB2TypeSeqData, false },
+ { kEob2IntroAnimData32, kEoB2TypeSeqData, false },
+ { kEob2IntroAnimData33, kEoB2TypeSeqData, false },
+ { kEob2IntroAnimData34, kEoB2TypeSeqData, false },
+ { kEob2IntroAnimData35, kEoB2TypeSeqData, false },
+ { kEob2IntroAnimData36, kEoB2TypeSeqData, false },
+ { kEob2IntroAnimData37, kEoB2TypeSeqData, false },
+ { kEob2IntroAnimData38, kEoB2TypeSeqData, false },
+ { kEob2IntroAnimData39, kEoB2TypeSeqData, false },
+ { kEob2IntroAnimData40, kEoB2TypeSeqData, false },
+ { kEob2IntroAnimData41, kEoB2TypeSeqData, false },
+ { kEob2IntroAnimData42, kEoB2TypeSeqData, false },
+ { kEob2IntroAnimData43, kEoB2TypeSeqData, false },
+ { kEoB2IntroShapes00, kEoB2TypeShapeData, false },
+ { kEoB2IntroShapes01, kEoB2TypeShapeData, false },
+ { kEoB2IntroShapes04, kEoB2TypeShapeData, false },
+ { kEoB2IntroShapes07, kEoB2TypeShapeData, false },
+
+ { kEoB2FinaleStrings, k2TypeSfxList, true },
+ { kEoB2CreditsData, kTypeRawData, true },
+ { kEoB2FinaleCPSFiles, kTypeStringList, true },
+ { kEob2FinaleAnimData00, kEoB2TypeSeqData, false },
+ { kEob2FinaleAnimData01, kEoB2TypeSeqData, false },
+ { kEob2FinaleAnimData02, kEoB2TypeSeqData, false },
+ { kEob2FinaleAnimData03, kEoB2TypeSeqData, false },
+ { kEob2FinaleAnimData04, kEoB2TypeSeqData, false },
+ { kEob2FinaleAnimData05, kEoB2TypeSeqData, false },
+ { kEob2FinaleAnimData06, kEoB2TypeSeqData, false },
+ { kEob2FinaleAnimData07, kEoB2TypeSeqData, false },
+ { kEob2FinaleAnimData08, kEoB2TypeSeqData, false },
+ { kEob2FinaleAnimData09, kEoB2TypeSeqData, false },
+ { kEob2FinaleAnimData10, kEoB2TypeSeqData, false },
+ { kEob2FinaleAnimData11, kEoB2TypeSeqData, false },
+ { kEob2FinaleAnimData12, kEoB2TypeSeqData, false },
+ { kEob2FinaleAnimData13, kEoB2TypeSeqData, false },
+ { kEob2FinaleAnimData14, kEoB2TypeSeqData, false },
+ { kEob2FinaleAnimData15, kEoB2TypeSeqData, false },
+ { kEob2FinaleAnimData16, kEoB2TypeSeqData, false },
+ { kEob2FinaleAnimData17, kEoB2TypeSeqData, false },
+ { kEob2FinaleAnimData18, kEoB2TypeSeqData, false },
+ { kEob2FinaleAnimData19, kEoB2TypeSeqData, false },
+ { kEob2FinaleAnimData20, kEoB2TypeSeqData, false },
+ { kEoB2FinaleShapes00, kEoB2TypeShapeData, false },
+ { kEoB2FinaleShapes03, kEoB2TypeShapeData, false },
+ { kEoB2FinaleShapes07, kEoB2TypeShapeData, false },
+ { kEoB2FinaleShapes09, kEoB2TypeShapeData, false },
+ { kEoB2FinaleShapes10, kEoB2TypeShapeData, false },
+ { kEoB2NpcShapeData, kTypeRawData, false },
+ { kEoBBaseClassModifierFlags, kTypeRawData, false },
+ { kEoBBaseMonsterStepTable01, kTypeRawData, false },
+ { kEoBBaseMonsterStepTable02, kTypeRawData, false },
+ { kEoBBaseMonsterStepTable1, kTypeRawData, false },
+ { kEoBBaseMonsterStepTable2, k3TypeRaw16to8, false },
+ { kEoBBaseMonsterStepTable3, k3TypeRaw16to8, false },
+ { kEoBBaseMonsterCloseAttPosTable1, kTypeRawData, false },
+ { kEoBBaseMonsterCloseAttPosTable21, kTypeRawData, false },
+ { kEoBBaseMonsterCloseAttPosTable22, kTypeRawData, false },
+ { kEoBBaseMonsterCloseAttUnkTable, kTypeRawData, false },
+ { kEoBBaseMonsterCloseAttChkTable1, kTypeRawData, false },
+ { kEoBBaseMonsterCloseAttChkTable2, kTypeRawData, false },
+ { kEoBBaseMonsterCloseAttDstTable1, kTypeRawData, false },
+ { kEoBBaseMonsterCloseAttDstTable2, kTypeRawData, false },
+ { kEoBBaseMonsterProximityTable, kTypeRawData, false },
+ { kEoBBaseFindBlockMonstersTable, kTypeRawData, false },
+ { kEoBBaseMonsterDirChangeTable, kTypeRawData, false },
+ { kEoBBaseMonsterDistAttStrings, kTypeStringList, true },
+ { kEoBBaseEncodeMonsterDefs, kLoLTypeRaw16, false },
+ { kEoBBaseNpcPresets, kEoBTypeNpcData, false },
+ { kEoB2Npc1Strings, kTypeStringList, true },
+ { kEoB2Npc2Strings, kTypeStringList, true },
+ { kEoB2MonsterDustStrings, kTypeStringList, true },
+ { kEoB2DreamSteps, kTypeRawData, false },
+ { kEoB2KheldranStrings, kTypeStringList, true },
+ { kEoB2HornStrings, kTypeStringList, true },
+ { kEoB2HornSounds, kTypeRawData, false },
+ { kEoB2WallOfForceDsX, kLoLTypeRaw16, false },
+ { kEoB2WallOfForceDsY, kTypeRawData, false },
+ { kEoB2WallOfForceNumW, kTypeRawData, false },
+ { kEoB2WallOfForceNumH, kTypeRawData, false },
+ { kEoB2WallOfForceShpId, kTypeRawData, false },
+
// LANDS OF LORE
// Ingame
- { kLolIngamePakFiles, kTypeStringList, false },
-
- { kLolCharacterDefs, kLolTypeCharData, true },
- { kLolIngameSfxFiles, k2TypeSfxList, false },
- { kLolIngameSfxIndex, kTypeRawData, false },
- { kLolMusicTrackMap, kTypeRawData, false },
- { kLolIngameGMSfxIndex, kTypeRawData, false },
- { kLolIngameMT32SfxIndex, kTypeRawData, false },
- { kLolIngamePcSpkSfxIndex, kTypeRawData, false },
- { kLolSpellProperties, kLolTypeSpellData, false },
- { kLolGameShapeMap, kTypeRawData, false },
- { kLolSceneItemOffs, kTypeRawData, false },
- { kLolCharInvIndex, k3TypeRaw16to8, false },
- { kLolCharInvDefs, kTypeRawData, false },
- { kLolCharDefsMan, kLolTypeRaw16, false },
- { kLolCharDefsWoman, kLolTypeRaw16, false },
- { kLolCharDefsKieran, kLolTypeRaw16, false },
- { kLolCharDefsAkshel, kLolTypeRaw16, false },
- { kLolExpRequirements, kLolTypeRaw32, false },
- { kLolMonsterModifiers, kLolTypeRaw16, false },
- { kLolMonsterShiftOffsets, kTypeRawData, false },
- { kLolMonsterDirFlags, kTypeRawData, false },
- { kLolMonsterScaleY, kTypeRawData, false },
- { kLolMonsterScaleX, kTypeRawData, false },
- { kLolMonsterScaleWH, kLolTypeRaw16, false },
- { kLolFlyingObjectShp, kLolTypeFlightShpData, false },
- { kLolInventoryDesc, kLolTypeRaw16, false },
- { kLolLevelShpList, kTypeStringList, false },
- { kLolLevelDatList, kTypeStringList, false },
- { kLolCompassDefs, kLolTypeCompassData, false },
- { kLolItemPrices, kLolTypeRaw16, false },
- { kLolStashSetup, kTypeRawData, false },
-
- { kLolDscUnk1, kTypeRawData, false },
- { kLolDscShapeIndex, kTypeRawData, false },
- { kLolDscOvlMap, kTypeRawData, false },
- { kLolDscScaleWidthData, kLolTypeRaw16, false },
- { kLolDscScaleHeightData, kLolTypeRaw16, false },
- { kLolDscX, kLolTypeRaw16, false },
- { kLolDscY, kTypeRawData, false },
- { kLolDscTileIndex, kTypeRawData, false },
- { kLolDscUnk2, kTypeRawData, false },
- { kLolDscDoorShapeIndex, kTypeRawData, false },
- { kLolDscDimData1, kTypeRawData, false },
- { kLolDscDimData2, kTypeRawData, false },
- { kLolDscBlockMap, kTypeRawData, false },
- { kLolDscDimMap, kTypeRawData, false },
- { kLolDscDoorScale, kLolTypeRaw16, false },
- { kLolDscOvlIndex, k3TypeRaw16to8, false },
- { kLolDscBlockIndex, kTypeRawData, false },
- { kLolDscDoor4, kLolTypeRaw16, false },
- { kLolDscDoor1, kTypeRawData, false },
- { kLolDscDoorX, kLolTypeRaw16, false },
- { kLolDscDoorY, kLolTypeRaw16, false },
-
- { kLolScrollXTop, k3TypeRaw16to8, false },
- { kLolScrollYTop, k3TypeRaw16to8, false },
- { kLolScrollXBottom, k3TypeRaw16to8, false },
- { kLolScrollYBottom, k3TypeRaw16to8, false },
-
- { kLolButtonDefs, kLolTypeButtonDef, false },
- { kLolButtonList1, kLolTypeRaw16, false },
- { kLolButtonList2, kLolTypeRaw16, false },
- { kLolButtonList3, kLolTypeRaw16, false },
- { kLolButtonList4, kLolTypeRaw16, false },
- { kLolButtonList5, kLolTypeRaw16, false },
- { kLolButtonList6, kLolTypeRaw16, false },
- { kLolButtonList7, kLolTypeRaw16, false },
- { kLolButtonList8, kLolTypeRaw16, false },
-
- { kLolLegendData, kTypeRawData, false },
- { kLolMapCursorOvl, kTypeRawData, false },
- { kLolMapStringId, kLolTypeRaw16, false },
-
- { kLolSpellbookAnim, k3TypeRaw16to8, false },
- { kLolSpellbookCoords, k3TypeRaw16to8, false },
- { kLolHealShapeFrames, kTypeRawData, false },
- { kLolLightningDefs, kTypeRawData, false },
- { kLolFireballCoords, kLolTypeRaw16, false },
-
- { kLolCredits, kTypeRawData, false },
-
- { kLolHistory, kTypeRawData, false },
+ { kLoLIngamePakFiles, kTypeStringList, false },
+
+ { kLoLCharacterDefs, kLoLTypeCharData, true },
+ { kLoLIngameSfxFiles, k2TypeSfxList, false },
+ { kLoLIngameSfxIndex, kTypeRawData, false },
+ { kLoLMusicTrackMap, kTypeRawData, false },
+ { kLoLIngameGMSfxIndex, kTypeRawData, false },
+ { kLoLIngameMT32SfxIndex, kTypeRawData, false },
+ { kLoLIngamePcSpkSfxIndex, kTypeRawData, false },
+ { kLoLSpellProperties, kLoLTypeSpellData, false },
+ { kLoLGameShapeMap, kTypeRawData, false },
+ { kLoLSceneItemOffs, kTypeRawData, false },
+ { kLoLCharInvIndex, k3TypeRaw16to8, false },
+ { kLoLCharInvDefs, kTypeRawData, false },
+ { kLoLCharDefsMan, kLoLTypeRaw16, false },
+ { kLoLCharDefsWoman, kLoLTypeRaw16, false },
+ { kLoLCharDefsKieran, kLoLTypeRaw16, false },
+ { kLoLCharDefsAkshel, kLoLTypeRaw16, false },
+ { kLoLExpRequirements, kLoLTypeRaw32, false },
+ { kLoLMonsterModifiers, kLoLTypeRaw16, false },
+ { kLoLMonsterShiftOffsets, kTypeRawData, false },
+ { kLoLMonsterDirFlags, kTypeRawData, false },
+ { kLoLMonsterScaleY, kTypeRawData, false },
+ { kLoLMonsterScaleX, kTypeRawData, false },
+ { kLoLMonsterScaleWH, kLoLTypeRaw16, false },
+ { kLoLFlyingObjectShp, kLoLTypeFlightShpData, false },
+ { kLoLInventoryDesc, kLoLTypeRaw16, false },
+ { kLoLLevelShpList, kTypeStringList, false },
+ { kLoLLevelDatList, kTypeStringList, false },
+ { kLoLCompassDefs, kLoLTypeCompassData, false },
+ { kLoLItemPrices, kLoLTypeRaw16, false },
+ { kLoLStashSetup, kTypeRawData, false },
+
+ { kLoLDscWalls, kTypeRawData, false },
+ { kRpgCommonDscShapeIndex, kTypeRawData, false },
+ { kLoLDscOvlMap, kTypeRawData, false },
+ { kLoLDscScaleWidthData, kLoLTypeRaw16, false },
+ { kLoLDscScaleHeightData, kLoLTypeRaw16, false },
+ { kRpgCommonDscX, kLoLTypeRaw16, false },
+ { kLoLDscY, kTypeRawData, false },
+ { kRpgCommonDscTileIndex, kTypeRawData, false },
+ { kRpgCommonDscUnk2, kTypeRawData, false },
+ { kRpgCommonDscDoorShapeIndex, kTypeRawData, false },
+ { kRpgCommonDscDimData1, kTypeRawData, false },
+ { kRpgCommonDscDimData2, kTypeRawData, false },
+ { kRpgCommonDscBlockMap, kTypeRawData, false },
+ { kRpgCommonDscDimMap, kTypeRawData, false },
+ { kLoLDscDoorScale, kLoLTypeRaw16, false },
+ { kLoLDscOvlIndex, k3TypeRaw16to8, false },
+ { kRpgCommonDscBlockIndex, kTypeRawData, false },
+ { kLoLDscDoor4, kLoLTypeRaw16, false },
+ { kRpgCommonDscDoorY2, kTypeRawData, false },
+ { kRpgCommonDscDoorFrameY1, kTypeRawData, false },
+ { kRpgCommonDscDoorFrameY2, kTypeRawData, false },
+ { kRpgCommonDscDoorFrameIndex1, kTypeRawData, false },
+ { kRpgCommonDscDoorFrameIndex2, kTypeRawData, false },
+ { kLoLDscDoorX, kLoLTypeRaw16, false },
+ { kLoLDscDoorY, kLoLTypeRaw16, false },
+
+ { kLoLScrollXTop, k3TypeRaw16to8, false },
+ { kLoLScrollYTop, k3TypeRaw16to8, false },
+ { kLoLScrollXBottom, k3TypeRaw16to8, false },
+ { kLoLScrollYBottom, k3TypeRaw16to8, false },
+
+ { kLoLButtonDefs, kLoLTypeButtonDef, false },
+ { kLoLButtonList1, kLoLTypeRaw16, false },
+ { kLoLButtonList2, kLoLTypeRaw16, false },
+ { kLoLButtonList3, kLoLTypeRaw16, false },
+ { kLoLButtonList4, kLoLTypeRaw16, false },
+ { kLoLButtonList5, kLoLTypeRaw16, false },
+ { kLoLButtonList6, kLoLTypeRaw16, false },
+ { kLoLButtonList7, kLoLTypeRaw16, false },
+ { kLoLButtonList8, kLoLTypeRaw16, false },
+
+ { kLoLLegendData, kTypeRawData, false },
+ { kLoLMapCursorOvl, kTypeRawData, false },
+ { kLoLMapStringId, kLoLTypeRaw16, false },
+
+ { kLoLSpellbookAnim, k3TypeRaw16to8, false },
+ { kLoLSpellbookCoords, k3TypeRaw16to8, false },
+ { kLoLHealShapeFrames, kTypeRawData, false },
+ { kLoLLightningDefs, kTypeRawData, false },
+ { kLoLFireballCoords, kLoLTypeRaw16, false },
+
+ { kLoLCredits, kTypeRawData, false },
+
+ { kLoLHistory, kTypeRawData, false },
{ -1, 0, 0 }
};
@@ -326,7 +716,9 @@ const TypeTable gameTable[] = {
{ kKyra1, 0 },
{ kKyra2, 1 },
{ kKyra3, 2 },
- { kLol, 3 },
+ { kEoB1, 3 },
+ { kEoB2, 4 },
+ { kLoL, 5 },
{ -1, -1 }
};
@@ -980,154 +1372,863 @@ const char *getIdString(const int id) {
return "k3ItemMagicTable";
case k3ItemStringMap:
return "k3ItemStringMap";
- case kLolIngamePakFiles:
- return "kLolIngamePakFiles";
- case kLolCharacterDefs:
- return "kLolCharacterDefs";
- case kLolIngameSfxFiles:
- return "kLolIngameSfxFiles";
- case kLolIngameSfxIndex:
- return "kLolIngameSfxIndex";
- case kLolMusicTrackMap:
- return "kLolMusicTrackMap";
- case kLolIngameGMSfxIndex:
- return "kLolIngameGMSfxIndex";
- case kLolIngameMT32SfxIndex:
- return "kLolIngameMT32SfxIndex";
- case kLolIngamePcSpkSfxIndex:
- return "kLolIngamePcSpkSfxIndex";
- case kLolSpellProperties:
- return "kLolSpellProperties";
- case kLolGameShapeMap:
- return "kLolGameShapeMap";
- case kLolSceneItemOffs:
- return "kLolSceneItemOffs";
- case kLolCharInvIndex:
- return "kLolCharInvIndex";
- case kLolCharInvDefs:
- return "kLolCharInvDefs";
- case kLolCharDefsMan:
- return "kLolCharDefsMan";
- case kLolCharDefsWoman:
- return "kLolCharDefsWoman";
- case kLolCharDefsKieran:
- return "kLolCharDefsKieran";
- case kLolCharDefsAkshel:
- return "kLolCharDefsAkshel";
- case kLolExpRequirements:
- return "kLolExpRequirements";
- case kLolMonsterModifiers:
- return "kLolMonsterModifiers";
- case kLolMonsterShiftOffsets:
- return "kLolMonsterShiftOffsets";
- case kLolMonsterDirFlags:
- return "kLolMonsterDirFlags";
- case kLolMonsterScaleY:
- return "kLolMonsterScaleY";
- case kLolMonsterScaleX:
- return "kLolMonsterScaleX";
- case kLolMonsterScaleWH:
- return "kLolMonsterScaleWH";
- case kLolFlyingObjectShp:
- return "kLolFlyingObjectShp";
- case kLolInventoryDesc:
- return "kLolInventoryDesc";
- case kLolLevelShpList:
- return "kLolLevelShpList";
- case kLolLevelDatList:
- return "kLolLevelDatList";
- case kLolCompassDefs:
- return "kLolCompassDefs";
- case kLolItemPrices:
- return "kLolItemPrices";
- case kLolStashSetup:
- return "kLolStashSetup";
- case kLolDscUnk1:
- return "kLolDscUnk1";
- case kLolDscShapeIndex:
- return "kLolDscShapeIndex";
- case kLolDscOvlMap:
- return "kLolDscOvlMap";
- case kLolDscScaleWidthData:
- return "kLolDscScaleWidthData";
- case kLolDscScaleHeightData:
- return "kLolDscScaleHeightData";
- case kLolDscX:
- return "kLolDscX";
- case kLolDscY:
- return "kLolDscY";
- case kLolDscTileIndex:
- return "kLolDscTileIndex";
- case kLolDscUnk2:
- return "kLolDscUnk2";
- case kLolDscDoorShapeIndex:
- return "kLolDscDoorShapeIndex";
- case kLolDscDimData1:
- return "kLolDscDimData1";
- case kLolDscDimData2:
- return "kLolDscDimData2";
- case kLolDscBlockMap:
- return "kLolDscBlockMap";
- case kLolDscDimMap:
- return "kLolDscDimMap";
- case kLolDscOvlIndex:
- return "kLolDscOvlIndex";
- case kLolDscBlockIndex:
- return "kLolDscBlockIndex";
- case kLolDscDoor1:
- return "kLolDscDoor1";
- case kLolDscDoorScale:
- return "kLolDscDoorScale";
- case kLolDscDoor4:
- return "kLolDscDoor4";
- case kLolDscDoorX:
- return "kLolDscDoorX";
- case kLolDscDoorY:
- return "kLolDscDoorY";
- case kLolScrollXTop:
- return "kLolScrollXTop";
- case kLolScrollYTop:
- return "kLolScrollYTop";
- case kLolScrollXBottom:
- return "kLolScrollXBottom";
- case kLolScrollYBottom:
- return "kLolScrollYBottom";
- case kLolButtonDefs:
- return "kLolButtonDefs";
- case kLolButtonList1:
- return "kLolButtonList1";
- case kLolButtonList2:
- return "kLolButtonList2";
- case kLolButtonList3:
- return "kLolButtonList3";
- case kLolButtonList4:
- return "kLolButtonList4";
- case kLolButtonList5:
- return "kLolButtonList5";
- case kLolButtonList6:
- return "kLolButtonList6";
- case kLolButtonList7:
- return "kLolButtonList7";
- case kLolButtonList8:
- return "kLolButtonList8";
- case kLolLegendData:
- return "kLolLegendData";
- case kLolMapCursorOvl:
- return "kLolMapCursorOvl";
- case kLolMapStringId:
- return "kLolMapStringId";
- case kLolSpellbookAnim:
- return "kLolSpellbookAnim";
- case kLolSpellbookCoords:
- return "kLolSpellbookCoords";
- case kLolHealShapeFrames:
- return "kLolHealShapeFrames";
- case kLolLightningDefs:
- return "kLolLightningDefs";
- case kLolFireballCoords:
- return "kLolFireballCoords";
- case kLolHistory:
- return "kLolHistory";
+ case kEoBBaseChargenStrings1:
+ return "kEoBBaseChargenStrings1";
+ case kEoBBaseChargenStrings2:
+ return "kEoBBaseChargenStrings2";
+ case kEoBBaseChargenStartLevels:
+ return "kEoBBaseChargenStartLevels";
+ case kEoBBaseChargenStatStrings:
+ return "kEoBBaseChargenStatStrings";
+ case kEoBBaseChargenRaceSexStrings:
+ return "kEoBBaseChargenRaceSexStrings";
+ case kEoBBaseChargenClassStrings:
+ return "kEoBBaseChargenClassStrings";
+ case kEoBBaseChargenAlignmentStrings:
+ return "kEoBBaseChargenAlignmentStrings";
+ case kEoBBaseChargenEnterGameStrings:
+ return "kEoBBaseChargenEnterGameStrings";
+ case kEoBBaseChargenClassMinStats:
+ return "kEoBBaseChargenClassMinStats";
+ case kEoBBaseChargenRaceMinStats:
+ return "kEoBBaseChargenRaceMinStats";
+ case kEoBBaseChargenRaceMaxStats:
+ return "kEoBBaseChargenRaceMaxStats";
+ case kEoBBaseSaveThrowTable1:
+ return "kEoBBaseSaveThrowTable1";
+ case kEoBBaseSaveThrowTable2:
+ return "kEoBBaseSaveThrowTable2";
+ case kEoBBaseSaveThrowTable3:
+ return "kEoBBaseSaveThrowTable3";
+ case kEoBBaseSaveThrowTable4:
+ return "kEoBBaseSaveThrowTable4";
+ case kEoBBaseSaveThrwLvlIndex:
+ return "kEoBBaseSaveThrwLvlIndex";
+ case kEoBBaseSaveThrwModDiv:
+ return "kEoBBaseSaveThrwModDiv";
+ case kEoBBaseSaveThrwModExt:
+ return "kEoBBaseSaveThrwModExt";
+ case kEoBBasePryDoorStrings:
+ return "kEoBBasePryDoorStrings";
+ case kEoBBaseWarningStrings:
+ return "kEoBBaseWarningStrings";
+ case kEoBBaseItemSuffixStringsRings:
+ return "kEoBBaseItemSuffixStringsRings";
+ case kEoBBaseItemSuffixStringsPotions:
+ return "kEoBBaseItemSuffixStringsPotions";
+ case kEoBBaseItemSuffixStringsWands:
+ return "kEoBBaseItemSuffixStringsWands";
+ case kEoBBaseRipItemStrings:
+ return "kEoBBaseRipItemStrings";
+ case kEoBBaseCursedString:
+ return "kEoBBaseCursedString";
+ case kEoBBaseEnchantedString:
+ return "kEoBBaseEnchantedString";
+ case kEoBBaseMagicObjectStrings:
+ return "kEoBBaseMagicObjectStrings";
+ case kEoBBaseMagicObject5String:
+ return "kEoBBaseMagicObject5String";
+ case kEoBBasePatternSuffix:
+ return "kEoBBasePatternSuffix";
+ case kEoBBasePatternGrFix1:
+ return "kEoBBasePatternGrFix1";
+ case kEoBBasePatternGrFix2:
+ return "kEoBBasePatternGrFix2";
+ case kEoBBaseValidateArmorString:
+ return "kEoBBaseValidateArmorString";
+ case kEoBBaseValidateCursedString:
+ return "kEoBBaseValidateCursedString";
+ case kEoBBaseValidateNoDropString:
+ return "kEoBBaseValidateNoDropString";
+ case kEoBBasePotionStrings:
+ return "kEoBBasePotionStrings";
+ case kEoBBaseWandString:
+ return "kEoBBaseWandString";
+ case kEoBBaseItemMisuseStrings:
+ return "kEoBBaseItemMisuseStrings";
+ case kEoBBaseTakenStrings:
+ return "kEoBBaseTakenStrings";
+ case kEoBBasePotionEffectStrings:
+ return "kEoBBasePotionEffectStrings";
+ case kEoBBaseYesNoStrings:
+ return "kEoBBaseYesNoStrings";
+ case kRpgCommonMoreStrings:
+ return "kRpgCommonMoreStrings";
+ case kEoBBaseNpcMaxStrings:
+ return "kEoBBaseNpcMaxStrings";
+ case kEoBBaseOkStrings:
+ return "kEoBBaseOkStrings";
+ case kEoBBaseNpcJoinStrings:
+ return "kEoBBaseNpcJoinStrings";
+ case kEoBBaseCancelStrings:
+ return "kEoBBaseCancelStrings";
+ case kEoBBaseAbortStrings:
+ return "kEoBBaseAbortStrings";
+ case kEoBBaseMenuStringsMain:
+ return "kEoBBaseMenuStringsMain";
+ case kEoBBaseMenuStringsSaveLoad:
+ return "kEoBBaseMenuStringsSaveLoad";
+ case kEoBBaseMenuStringsOnOff:
+ return "kEoBBaseMenuStringsOnOff";
+ case kEoBBaseMenuStringsSpells:
+ return "kEoBBaseMenuStringsSpells";
+ case kEoBBaseMenuStringsRest:
+ return "kEoBBaseMenuStringsRest";
+ case kEoBBaseMenuStringsDrop:
+ return "kEoBBaseMenuStringsDrop";
+ case kEoBBaseMenuStringsExit:
+ return "kEoBBaseMenuStringsExit";
+ case kEoBBaseMenuStringsStarve:
+ return "kEoBBaseMenuStringsStarve";
+ case kEoBBaseMenuStringsScribe:
+ return "kEoBBaseMenuStringsScribe";
+ case kEoBBaseMenuStringsDrop2:
+ return "kEoBBaseMenuStringsDrop2";
+ case kEoBBaseMenuStringsHead:
+ return "kEoBBaseMenuStringsHead";
+ case kEoBBaseMenuStringsPoison:
+ return "kEoBBaseMenuStringsPoison";
+ case kEoBBaseMenuStringsMgc:
+ return "kEoBBaseMenuStringsMgc";
+ case kEoBBaseMenuStringsPrefs:
+ return "kEoBBaseMenuStringsPrefs";
+ case kEoBBaseMenuStringsRest2:
+ return "kEoBBaseMenuStringsRest2";
+ case kEoBBaseMenuStringsRest3:
+ return "kEoBBaseMenuStringsRest3";
+ case kEoBBaseMenuStringsRest4:
+ return "kEoBBaseMenuStringsRest4";
+ case kEoBBaseMenuStringsDefeat:
+ return "kEoBBaseMenuStringsDefeat";
+ case kEoBBaseMenuStringsTransfer:
+ return "kEoBBaseMenuStringsTransfer";
+ case kEoBBaseMenuStringsSpec:
+ return "kEoBBaseMenuStringsSpec";
+ case kEoBBaseMenuStringsSpellNo:
+ return "kEoBBaseMenuStringsSpellNo";
+ case kEoBBaseMenuYesNoStrings:
+ return "kEoBBaseMenuYesNoStrings";
+ case kEoBBaseSpellLevelsMage:
+ return "kEoBBaseSpellLevelsMage";
+ case kEoBBaseSpellLevelsCleric:
+ return "kEoBBaseSpellLevelsCleric";
+ case kEoBBaseNumSpellsCleric:
+ return "kEoBBaseNumSpellsCleric";
+ case kEoBBaseNumSpellsWisAdj:
+ return "kEoBBaseNumSpellsWisAdj";
+ case kEoBBaseNumSpellsPal:
+ return "kEoBBaseNumSpellsPal";
+ case kEoBBaseNumSpellsMage:
+ return "kEoBBaseNumSpellsMage";
+ case kEoBBaseCharGuiStringsHp:
+ return "kEoBBaseCharGuiStringsHp";
+ case kEoBBaseCharGuiStringsWp1:
+ return "kEoBBaseCharGuiStringsWp1";
+ case kEoBBaseCharGuiStringsWp2:
+ return "kEoBBaseCharGuiStringsWp2";
+ case kEoBBaseCharGuiStringsWr:
+ return "kEoBBaseCharGuiStringsWr";
+ case kEoBBaseCharGuiStringsSt1:
+ return "kEoBBaseCharGuiStringsSt1";
+ case kEoBBaseCharGuiStringsSt2:
+ return "kEoBBaseCharGuiStringsSt2";
+ case kEoBBaseCharGuiStringsIn:
+ return "kEoBBaseCharGuiStringsIn";
+ case kEoBBaseCharStatusStrings7:
+ return "kEoBBaseCharStatusStrings7";
+ case kEoBBaseCharStatusStrings81:
+ return "kEoBBaseCharStatusStrings81";
+ case kEoBBaseCharStatusStrings82:
+ return "kEoBBaseCharStatusStrings82";
+ case kEoBBaseCharStatusStrings9:
+ return "kEoBBaseCharStatusStrings9";
+ case kEoBBaseCharStatusStrings12:
+ return "kEoBBaseCharStatusStrings12";
+ case kEoBBaseCharStatusStrings131:
+ return "kEoBBaseCharStatusStrings131";
+ case kEoBBaseCharStatusStrings132:
+ return "kEoBBaseCharStatusStrings132";
+ case kEoBBaseLevelGainStrings:
+ return "kEoBBaseLevelGainStrings";
+ case kEoBBaseExperienceTable0:
+ return "kEoBBaseExperienceTable0";
+ case kEoBBaseExperienceTable1:
+ return "kEoBBaseExperienceTable1";
+ case kEoBBaseExperienceTable2:
+ return "kEoBBaseExperienceTable2";
+ case kEoBBaseExperienceTable3:
+ return "kEoBBaseExperienceTable3";
+ case kEoBBaseExperienceTable4:
+ return "kEoBBaseExperienceTable4";
+ case kEoBBaseWllFlagPreset:
+ return "kEoBBaseWllFlagPreset";
+ case kEoBBaseDscShapeCoords:
+ return "kEoBBaseDscShapeCoords";
+ case kEoBBaseDscDoorScaleOffs:
+ return "kEoBBaseDscDoorScaleOffs";
+ case kEoBBaseDscDoorScaleMult1:
+ return "kEoBBaseDscDoorScaleMult1";
+ case kEoBBaseDscDoorScaleMult2:
+ return "kEoBBaseDscDoorScaleMult2";
+ case kEoBBaseDscDoorScaleMult3:
+ return "kEoBBaseDscDoorScaleMult3";
+ case kEoBBaseDscDoorScaleMult4:
+ return "kEoBBaseDscDoorScaleMult4";
+ case kEoBBaseDscDoorScaleMult5:
+ return "kEoBBaseDscDoorScaleMult5";
+ case kEoBBaseDscDoorScaleMult6:
+ return "kEoBBaseDscDoorScaleMult6";
+ case kEoBBaseDscDoorType5Offs:
+ return "kEoBBaseDscDoorType5Offs";
+ case kEoBBaseDscDoorXE:
+ return "kEoBBaseDscDoorXE";
+ case kEoBBaseDscDoorY1:
+ return "kEoBBaseDscDoorY1";
+ case kEoBBaseDscDoorY3:
+ return "kEoBBaseDscDoorY3";
+ case kEoBBaseDscDoorY4:
+ return "kEoBBaseDscDoorY4";
+ case kEoBBaseDscDoorY5:
+ return "kEoBBaseDscDoorY5";
+ case kEoBBaseDscDoorY6:
+ return "kEoBBaseDscDoorY6";
+ case kEoBBaseDscDoorY7:
+ return "kEoBBaseDscDoorY7";
+ case kEoBBaseDscDoorCoordsExt:
+ return "kEoBBaseDscDoorCoordsExt";
+ case kEoBBaseDscItemPosIndex:
+ return "kEoBBaseDscItemPosIndex";
+ case kEoBBaseDscItemShpX:
+ return "kEoBBaseDscItemShpX";
+ case kEoBBaseDscItemPosUnk:
+ return "kEoBBaseDscItemPosUnk";
+ case kEoBBaseDscItemTileIndex:
+ return "kEoBBaseDscItemTileIndex";
+ case kEoBBaseDscItemShapeMap:
+ return "kEoBBaseDscItemShapeMap";
+ case kEoBBaseDscMonsterFrmOffsTbl1:
+ return "kEoBBaseDscMonsterFrmOffsTbl1";
+ case kEoBBaseDscMonsterFrmOffsTbl2:
+ return "kEoBBaseDscMonsterFrmOffsTbl2";
+ case kEoBBaseInvSlotX:
+ return "kEoBBaseInvSlotX";
+ case kEoBBaseInvSlotY:
+ return "kEoBBaseInvSlotY";
+ case kEoBBaseSlotValidationFlags:
+ return "kEoBBaseSlotValidationFlags";
+ case kEoBBaseProjectileWeaponTypes:
+ return "kEoBBaseProjectileWeaponTypes";
+ case kEoBBaseWandTypes:
+ return "kEoBBaseWandTypes";
+ case kEoBBaseDrawObjPosIndex:
+ return "kEoBBaseDrawObjPosIndex";
+ case kEoBBaseFlightObjFlipIndex:
+ return "kEoBBaseFlightObjFlipIndex";
+ case kEoBBaseFlightObjShpMap:
+ return "kEoBBaseFlightObjShpMap";
+ case kEoBBaseFlightObjSclIndex:
+ return "kEoBBaseFlightObjSclIndex";
+ case kEoBBaseDscTelptrShpCoords:
+ return "kEoBBaseDscTelptrShpCoords";
+ case kEoBBasePortalSeqData:
+ return "kEoBBasePortalSeqData";
+ case kEoBBaseManDef:
+ return "kEoBBaseManDef";
+ case kEoBBaseManWord:
+ return "kEoBBaseManWord";
+ case kEoBBaseManPrompt:
+ return "kEoBBaseManPrompt";
+ case kEoBBaseBookNumbers:
+ return "kEoBBaseBookNumbers";
+ case kEoBBaseMageSpellsList:
+ return "kEoBBaseMageSpellsList";
+ case kEoBBaseClericSpellsList:
+ return "kEoBBaseClericSpellsList";
+ case kEoBBaseSpellNames:
+ return "kEoBBaseSpellNames";
+
+ case kEoBBaseMagicStrings1:
+ return "kEoBBaseMagicStrings1";
+ case kEoBBaseMagicStrings2:
+ return "kEoBBaseMagicStrings2";
+ case kEoBBaseMagicStrings3:
+ return "kEoBBaseMagicStrings3";
+ case kEoBBaseMagicStrings4:
+ return "kEoBBaseMagicStrings4";
+ case kEoBBaseMagicStrings6:
+ return "kEoBBaseMagicStrings6";
+ case kEoBBaseMagicStrings7:
+ return "kEoBBaseMagicStrings7";
+ case kEoBBaseMagicStrings8:
+ return "kEoBBaseMagicStrings8";
+ case kEoBBaseExpObjectTlMode:
+ return "kEoBBaseExpObjectTlMode";
+ case kEoBBaseExpObjectTblIndex:
+ return "kEoBBaseExpObjectTblIndex";
+ case kEoBBaseExpObjectShpStart:
+ return "kEoBBaseExpObjectShpStart";
+ case kEoBBaseExpObjectTbl1:
+ return "kEoBBaseExpObjectTbl1";
+ case kEoBBaseExpObjectTbl2:
+ return "kEoBBaseExpObjectTbl2";
+ case kEoBBaseExpObjectTbl3:
+ return "kEoBBaseExpObjectTbl3";
+ case kEoBBaseExpObjectY:
+ return "kEoBBaseExpObjectY";
+ case kEoBBaseSparkDefSteps:
+ return "kEoBBaseSparkDefSteps";
+ case kEoBBaseSparkDefSubSteps:
+ return "kEoBBaseSparkDefSubSteps";
+ case kEoBBaseSparkDefShift:
+ return "kEoBBaseSparkDefShift";
+ case kEoBBaseSparkDefAdd:
+ return "kEoBBaseSparkDefAdd";
+ case kEoBBaseSparkDefX:
+ return "kEoBBaseSparkDefX";
+ case kEoBBaseSparkDefY:
+ return "kEoBBaseSparkDefY";
+ case kEoBBaseSparkOfFlags1:
+ return "kEoBBaseSparkOfFlags1";
+ case kEoBBaseSparkOfFlags2:
+ return "kEoBBaseSparkOfFlags2";
+ case kEoBBaseSparkOfShift:
+ return "kEoBBaseSparkOfShift";
+ case kEoBBaseSparkOfX:
+ return "kEoBBaseSparkOfX";
+ case kEoBBaseSparkOfY:
+ return "kEoBBaseSparkOfY";
+ case kEoBBaseSpellProperties:
+ return "kEoBBaseSpellProperties";
+ case kEoBBaseMagicFlightProps:
+ return "kEoBBaseMagicFlightProps";
+ case kEoBBaseTurnUndeadEffect:
+ return "kEoBBaseTurnUndeadEffect";
+ case kEoBBaseBurningHandsDest:
+ return "kEoBBaseBurningHandsDest";
+ case kEoBBaseConeOfColdDest1:
+ return "kEoBBaseConeOfColdDest1";
+ case kEoBBaseConeOfColdDest2:
+ return "kEoBBaseConeOfColdDest2";
+ case kEoBBaseConeOfColdDest3:
+ return "kEoBBaseConeOfColdDest3";
+ case kEoBBaseConeOfColdDest4:
+ return "kEoBBaseConeOfColdDest4";
+ case kEoBBaseConeOfColdGfxTbl:
+ return "kEoBBaseConeOfColdGfxTbl";
+ case kEoB1MainMenuStrings:
+ return "kEoB1MainMenuStrings";
+ case kEoB1BonusStrings:
+ return "kEoB1BonusStrings";
+ case kEoB1IntroFilesOpening:
+ return "kEoB1IntroFilesOpening";
+ case kEoB1IntroFilesTower:
+ return "kEoB1IntroFilesTower";
+ case kEoB1IntroFilesOrb:
+ return "kEoB1IntroFilesOrb";
+ case kEoB1IntroFilesWdEntry:
+ return "kEoB1IntroFilesWdEntry";
+ case kEoB1IntroFilesKing:
+ return "kEoB1IntroFilesKing";
+ case kEoB1IntroFilesHands:
+ return "kEoB1IntroFilesHands";
+ case kEoB1IntroFilesWdExit:
+ return "kEoB1IntroFilesWdExit";
+ case kEoB1IntroFilesTunnel:
+ return "kEoB1IntroFilesTunnel";
+ case kEoB1IntroOpeningFrmDelay:
+ return "kEoB1IntroOpeningFrmDelay";
+ case kEoB1IntroWdEncodeX:
+ return "kEoB1IntroWdEncodeX";
+ case kEoB1IntroWdEncodeY:
+ return "kEoB1IntroWdEncodeY";
+ case kEoB1IntroWdEncodeWH:
+ return "kEoB1IntroWdEncodeWH";
+ case kEoB1IntroWdDsX:
+ return "kEoB1IntroWdDsX";
+ case kEoB1IntroWdDsY:
+ return "kEoB1IntroWdDsY";
+ case kEoB1IntroTvlX1:
+ return "kEoB1IntroTvlX1";
+ case kEoB1IntroTvlY1:
+ return "kEoB1IntroTvlY1";
+ case kEoB1IntroTvlX2:
+ return "kEoB1IntroTvlX2";
+ case kEoB1IntroTvlY2:
+ return "kEoB1IntroTvlY2";
+ case kEoB1IntroTvlW:
+ return "kEoB1IntroTvlW";
+ case kEoB1IntroTvlH:
+ return "kEoB1IntroTvlH";
+ case kEoB1DoorShapeDefs:
+ return "kEoB1DoorShapeDefs";
+ case kEoB1DoorSwitchCoords:
+ return "kEoB1DoorSwitchCoords";
+ case kEoB1MonsterProperties:
+ return "kEoB1MonsterProperties";
+ case kEoB1EnemyMageSpellList:
+ return "kEoB1EnemyMageSpellList";
+ case kEoB1EnemyMageSfx:
+ return "kEoB1EnemyMageSfx";
+ case kEoB1BeholderSpellList:
+ return "kEoB1BeholderSpellList";
+ case kEoB1BeholderSfx:
+ return "kEoB1BeholderSfx";
+ case kEoB1TurnUndeadString:
+ return "kEoB1TurnUndeadString";
+ case kEoB1CgaMappingDefault:
+ return "kEoB1CgaMappingDefault";
+ case kEoB1CgaMappingAlt:
+ return "kEoB1CgaMappingAlt";
+ case kEoB1CgaMappingInv:
+ return "kEoB1CgaMappingInv";
+ case kEoB1CgaMappingItemsL:
+ return "kEoB1CgaMappingItemsL";
+ case kEoB1CgaMappingItemsS:
+ return "kEoB1CgaMappingItemsS";
+ case kEoB1CgaMappingThrown:
+ return "kEoB1CgaMappingThrown";
+ case kEoB1CgaMappingIcons:
+ return "kEoB1CgaMappingIcons";
+ case kEoB1CgaMappingDeco:
+ return "kEoB1CgaMappingDeco";
+ case kEoB1CgaLevelMappingIndex:
+ return "kEoB1CgaLevelMappingIndex";
+ case kEoB1CgaMappingLevel0:
+ return "kEoB1CgaMappingLevel0";
+ case kEoB1CgaMappingLevel1:
+ return "kEoB1CgaMappingLevel1";
+ case kEoB1CgaMappingLevel2:
+ return "kEoB1CgaMappingLevel2";
+ case kEoB1CgaMappingLevel3:
+ return "kEoB1CgaMappingLevel3";
+ case kEoB1CgaMappingLevel4:
+ return "kEoB1CgaMappingLevel4";
+ case kEoB1NpcShpData:
+ return "kEoB1NpcShpData";
+ case kEoB1NpcSubShpIndex1:
+ return "kEoB1NpcSubShpIndex1";
+ case kEoB1NpcSubShpIndex2:
+ return "kEoB1NpcSubShpIndex2";
+ case kEoB1NpcSubShpY:
+ return "kEoB1NpcSubShpY";
+ case kEoB1Npc0Strings:
+ return "kEoB1Npc0Strings";
+ case kEoB1Npc11Strings:
+ return "kEoB1Npc11Strings";
+ case kEoB1Npc12Strings:
+ return "kEoB1Npc12Strings";
+ case kEoB1Npc21Strings:
+ return "kEoB1Npc21Strings";
+ case kEoB1Npc22Strings:
+ return "kEoB1Npc22Strings";
+ case kEoB1Npc31Strings:
+ return "kEoB1Npc31Strings";
+ case kEoB1Npc32Strings:
+ return "kEoB1Npc32Strings";
+ case kEoB1Npc4Strings:
+ return "kEoB1Npc4Strings";
+ case kEoB1Npc5Strings:
+ return "kEoB1Npc5Strings";
+ case kEoB1Npc6Strings:
+ return "kEoB1Npc6Strings";
+ case kEoB1Npc7Strings:
+ return "kEoB1Npc7Strings";
+ case kEoB2MainMenuStrings:
+ return "kEoB2MainMenuStrings";
+ case kEoB2TransferPortraitFrames:
+ return "kEoB2TransferPortraitFrames";
+ case kEoB2TransferConvertTable:
+ return "kEoB2TransferConvertTable";
+ case kEoB2TransferItemTable:
+ return "kEoB2TransferItemTable";
+ case kEoB2TransferExpTable:
+ return "kEoB2TransferExpTable";
+ case kEoB2TransferStrings1:
+ return "kEoB2TransferStrings1";
+ case kEoB2TransferStrings2:
+ return "kEoB2TransferStrings2";
+ case kEoB2TransferLabels:
+ return "kEoB2TransferLabels";
+ case kEoB2IntroStrings:
+ return "kEoB2IntroStrings";
+ case kEoB2IntroCPSFiles:
+ return "kEoB2IntroCPSFiles";
+ case kEob2IntroAnimData00:
+ return "kEob2IntroAnimData00";
+ case kEob2IntroAnimData01:
+ return "kEob2IntroAnimData01";
+ case kEob2IntroAnimData02:
+ return "kEob2IntroAnimData02";
+ case kEob2IntroAnimData03:
+ return "kEob2IntroAnimData03";
+ case kEob2IntroAnimData04:
+ return "kEob2IntroAnimData04";
+ case kEob2IntroAnimData05:
+ return "kEob2IntroAnimData05";
+ case kEob2IntroAnimData06:
+ return "kEob2IntroAnimData06";
+ case kEob2IntroAnimData07:
+ return "kEob2IntroAnimData07";
+ case kEob2IntroAnimData08:
+ return "kEob2IntroAnimData08";
+ case kEob2IntroAnimData09:
+ return "kEob2IntroAnimData09";
+ case kEob2IntroAnimData10:
+ return "kEob2IntroAnimData10";
+ case kEob2IntroAnimData11:
+ return "kEob2IntroAnimData11";
+ case kEob2IntroAnimData12:
+ return "kEob2IntroAnimData12";
+ case kEob2IntroAnimData13:
+ return "kEob2IntroAnimData13";
+ case kEob2IntroAnimData14:
+ return "kEob2IntroAnimData14";
+ case kEob2IntroAnimData15:
+ return "kEob2IntroAnimData15";
+ case kEob2IntroAnimData16:
+ return "kEob2IntroAnimData16";
+ case kEob2IntroAnimData17:
+ return "kEob2IntroAnimData17";
+ case kEob2IntroAnimData18:
+ return "kEob2IntroAnimData18";
+ case kEob2IntroAnimData19:
+ return "kEob2IntroAnimData19";
+ case kEob2IntroAnimData20:
+ return "kEob2IntroAnimData20";
+ case kEob2IntroAnimData21:
+ return "kEob2IntroAnimData21";
+ case kEob2IntroAnimData22:
+ return "kEob2IntroAnimData22";
+ case kEob2IntroAnimData23:
+ return "kEob2IntroAnimData23";
+ case kEob2IntroAnimData24:
+ return "kEob2IntroAnimData24";
+ case kEob2IntroAnimData25:
+ return "kEob2IntroAnimData25";
+ case kEob2IntroAnimData26:
+ return "kEob2IntroAnimData26";
+ case kEob2IntroAnimData27:
+ return "kEob2IntroAnimData27";
+ case kEob2IntroAnimData28:
+ return "kEob2IntroAnimData28";
+ case kEob2IntroAnimData29:
+ return "kEob2IntroAnimData29";
+ case kEob2IntroAnimData30:
+ return "kEob2IntroAnimData30";
+ case kEob2IntroAnimData31:
+ return "kEob2IntroAnimData31";
+ case kEob2IntroAnimData32:
+ return "kEob2IntroAnimData32";
+ case kEob2IntroAnimData33:
+ return "kEob2IntroAnimData33";
+ case kEob2IntroAnimData34:
+ return "kEob2IntroAnimData34";
+ case kEob2IntroAnimData35:
+ return "kEob2IntroAnimData35";
+ case kEob2IntroAnimData36:
+ return "kEob2IntroAnimData36";
+ case kEob2IntroAnimData37:
+ return "kEob2IntroAnimData37";
+ case kEob2IntroAnimData38:
+ return "kEob2IntroAnimData38";
+ case kEob2IntroAnimData39:
+ return "kEob2IntroAnimData39";
+ case kEob2IntroAnimData40:
+ return "kEob2IntroAnimData40";
+ case kEob2IntroAnimData41:
+ return "kEob2IntroAnimData41";
+ case kEob2IntroAnimData42:
+ return "kEob2IntroAnimData42";
+ case kEob2IntroAnimData43:
+ return "kEob2IntroAnimData43";
+ case kEoB2IntroShapes00:
+ return "kEoB2IntroShapes00";
+ case kEoB2IntroShapes01:
+ return "kEoB2IntroShapes01";
+ case kEoB2IntroShapes04:
+ return "kEoB2IntroShapes04";
+ case kEoB2IntroShapes07:
+ return "kEoB2IntroShapes07";
+ case kEoB2FinaleStrings:
+ return "kEoB2FinaleStrings";
+ case kEoB2CreditsData:
+ return "kEoB2CreditsData";
+ case kEoB2FinaleCPSFiles:
+ return "kEoB2FinaleCPSFiles";
+ case kEob2FinaleAnimData00:
+ return "kEob2FinaleAnimData00";
+ case kEob2FinaleAnimData01:
+ return "kEob2FinaleAnimData01";
+ case kEob2FinaleAnimData02:
+ return "kEob2FinaleAnimData02";
+ case kEob2FinaleAnimData03:
+ return "kEob2FinaleAnimData03";
+ case kEob2FinaleAnimData04:
+ return "kEob2FinaleAnimData04";
+ case kEob2FinaleAnimData05:
+ return "kEob2FinaleAnimData05";
+ case kEob2FinaleAnimData06:
+ return "kEob2FinaleAnimData06";
+ case kEob2FinaleAnimData07:
+ return "kEob2FinaleAnimData07";
+ case kEob2FinaleAnimData08:
+ return "kEob2FinaleAnimData08";
+ case kEob2FinaleAnimData09:
+ return "kEob2FinaleAnimData09";
+ case kEob2FinaleAnimData10:
+ return "kEob2FinaleAnimData10";
+ case kEob2FinaleAnimData11:
+ return "kEob2FinaleAnimData11";
+ case kEob2FinaleAnimData12:
+ return "kEob2FinaleAnimData12";
+ case kEob2FinaleAnimData13:
+ return "kEob2FinaleAnimData13";
+ case kEob2FinaleAnimData14:
+ return "kEob2FinaleAnimData14";
+ case kEob2FinaleAnimData15:
+ return "kEob2FinaleAnimData15";
+ case kEob2FinaleAnimData16:
+ return "kEob2FinaleAnimData16";
+ case kEob2FinaleAnimData17:
+ return "kEob2FinaleAnimData17";
+ case kEob2FinaleAnimData18:
+ return "kEob2FinaleAnimData18";
+ case kEob2FinaleAnimData19:
+ return "kEob2FinaleAnimData19";
+ case kEob2FinaleAnimData20:
+ return "kEob2FinaleAnimData20";
+ case kEoB2FinaleShapes00:
+ return "kEoB2FinaleShapes00";
+ case kEoB2FinaleShapes03:
+ return "kEoB2FinaleShapes03";
+ case kEoB2FinaleShapes07:
+ return "kEoB2FinaleShapes07";
+ case kEoB2FinaleShapes09:
+ return "kEoB2FinaleShapes09";
+ case kEoB2FinaleShapes10:
+ return "kEoB2FinaleShapes10";
+ case kEoB2NpcShapeData:
+ return "kEoB2NpcShapeData";
+ case kEoBBaseClassModifierFlags:
+ return "kEoBBaseClassModifierFlags";
+ case kEoBBaseMonsterStepTable01:
+ return "kEoBBaseMonsterStepTable01";
+ case kEoBBaseMonsterStepTable02:
+ return "kEoBBaseMonsterStepTable02";
+ case kEoBBaseMonsterStepTable1:
+ return "kEoBBaseMonsterStepTable1";
+ case kEoBBaseMonsterStepTable2:
+ return "kEoBBaseMonsterStepTable2";
+ case kEoBBaseMonsterStepTable3:
+ return "kEoBBaseMonsterStepTable3";
+ case kEoBBaseMonsterCloseAttPosTable1:
+ return "kEoBBaseMonsterCloseAttPosTable1";
+ case kEoBBaseMonsterCloseAttPosTable21:
+ return "kEoBBaseMonsterCloseAttPosTable21";
+ case kEoBBaseMonsterCloseAttPosTable22:
+ return "kEoBBaseMonsterCloseAttPosTable22";
+ case kEoBBaseMonsterCloseAttUnkTable:
+ return "kEoBBaseMonsterCloseAttUnkTable";
+ case kEoBBaseMonsterCloseAttChkTable1:
+ return "kEoBBaseMonsterCloseAttChkTable1";
+ case kEoBBaseMonsterCloseAttChkTable2:
+ return "kEoBBaseMonsterCloseAttChkTable2";
+ case kEoBBaseMonsterCloseAttDstTable1:
+ return "kEoBBaseMonsterCloseAttDstTable1";
+ case kEoBBaseMonsterCloseAttDstTable2:
+ return "kEoBBaseMonsterCloseAttDstTable2";
+ case kEoBBaseMonsterProximityTable:
+ return "kEoBBaseMonsterProximityTable";
+ case kEoBBaseFindBlockMonstersTable:
+ return "kEoBBaseFindBlockMonstersTable";
+ case kEoBBaseMonsterDirChangeTable:
+ return "kEoBBaseMonsterDirChangeTable";
+ case kEoBBaseMonsterDistAttStrings:
+ return "kEoBBaseMonsterDistAttStrings";
+ case kEoBBaseEncodeMonsterDefs:
+ return "kEoBBaseEncodeMonsterDefs";
+ case kEoBBaseNpcPresets:
+ return "kEoBBaseNpcPresets";
+ case kEoB2Npc1Strings:
+ return "kEoB2Npc1Strings";
+ case kEoB2Npc2Strings:
+ return "kEoB2Npc2Strings";
+ case kEoB2MonsterDustStrings:
+ return "kEoB2MonsterDustStrings";
+ case kEoB2DreamSteps:
+ return "kEoB2DreamSteps";
+ case kEoB2KheldranStrings:
+ return "kEoB2KheldranStrings";
+ case kEoB2HornStrings:
+ return "kEoB2HornStrings";
+ case kEoB2HornSounds:
+ return "kEoB2HornSounds";
+ case kEoB2WallOfForceDsX:
+ return "kEoB2WallOfForceDsX";
+ case kEoB2WallOfForceDsY:
+ return "kEoB2WallOfForceDsY";
+ case kEoB2WallOfForceNumW:
+ return "kEoB2WallOfForceNumW";
+ case kEoB2WallOfForceNumH:
+ return "kEoB2WallOfForceNumH";
+ case kEoB2WallOfForceShpId:
+ return "kEoB2WallOfForceShpId";
+ case kLoLIngamePakFiles:
+ return "kLoLIngamePakFiles";
+ case kLoLCharacterDefs:
+ return "kLoLCharacterDefs";
+ case kLoLIngameSfxFiles:
+ return "kLoLIngameSfxFiles";
+ case kLoLIngameSfxIndex:
+ return "kLoLIngameSfxIndex";
+ case kLoLMusicTrackMap:
+ return "kLoLMusicTrackMap";
+ case kLoLIngameGMSfxIndex:
+ return "kLoLIngameGMSfxIndex";
+ case kLoLIngameMT32SfxIndex:
+ return "kLoLIngameMT32SfxIndex";
+ case kLoLIngamePcSpkSfxIndex:
+ return "kLoLIngamePcSpkSfxIndex";
+ case kLoLSpellProperties:
+ return "kLoLSpellProperties";
+ case kLoLGameShapeMap:
+ return "kLoLGameShapeMap";
+ case kLoLSceneItemOffs:
+ return "kLoLSceneItemOffs";
+ case kLoLCharInvIndex:
+ return "kLoLCharInvIndex";
+ case kLoLCharInvDefs:
+ return "kLoLCharInvDefs";
+ case kLoLCharDefsMan:
+ return "kLoLCharDefsMan";
+ case kLoLCharDefsWoman:
+ return "kLoLCharDefsWoman";
+ case kLoLCharDefsKieran:
+ return "kLoLCharDefsKieran";
+ case kLoLCharDefsAkshel:
+ return "kLoLCharDefsAkshel";
+ case kLoLExpRequirements:
+ return "kLoLExpRequirements";
+ case kLoLMonsterModifiers:
+ return "kLoLMonsterModifiers";
+ case kLoLMonsterShiftOffsets:
+ return "kLoLMonsterShiftOffsets";
+ case kLoLMonsterDirFlags:
+ return "kLoLMonsterDirFlags";
+ case kLoLMonsterScaleY:
+ return "kLoLMonsterScaleY";
+ case kLoLMonsterScaleX:
+ return "kLoLMonsterScaleX";
+ case kLoLMonsterScaleWH:
+ return "kLoLMonsterScaleWH";
+ case kLoLFlyingObjectShp:
+ return "kLoLFlyingObjectShp";
+ case kLoLInventoryDesc:
+ return "kLoLInventoryDesc";
+ case kLoLLevelShpList:
+ return "kLoLLevelShpList";
+ case kLoLLevelDatList:
+ return "kLoLLevelDatList";
+ case kLoLCompassDefs:
+ return "kLoLCompassDefs";
+ case kLoLItemPrices:
+ return "kLoLItemPrices";
+ case kLoLStashSetup:
+ return "kLoLStashSetup";
+ case kLoLDscWalls:
+ return "kLoLDscWalls";
+ case kRpgCommonDscShapeIndex:
+ return "kRpgCommonDscShapeIndex";
+ case kLoLDscOvlMap:
+ return "kLoLDscOvlMap";
+ case kLoLDscScaleWidthData:
+ return "kLoLDscScaleWidthData";
+ case kLoLDscScaleHeightData:
+ return "kLoLDscScaleHeightData";
+ case kRpgCommonDscX:
+ return "kRpgCommonDscX";
+ case kLoLDscY:
+ return "kLoLDscY";
+ case kRpgCommonDscTileIndex:
+ return "kRpgCommonDscTileIndex";
+ case kRpgCommonDscUnk2:
+ return "kRpgCommonDscUnk2";
+ case kRpgCommonDscDoorShapeIndex:
+ return "kRpgCommonDscDoorShapeIndex";
+ case kRpgCommonDscDimData1:
+ return "kRpgCommonDscDimData1";
+ case kRpgCommonDscDimData2:
+ return "kRpgCommonDscDimData2";
+ case kRpgCommonDscBlockMap:
+ return "kRpgCommonDscBlockMap";
+ case kRpgCommonDscDimMap:
+ return "kRpgCommonDscDimMap";
+ case kLoLDscOvlIndex:
+ return "kLoLDscOvlIndex";
+ case kRpgCommonDscBlockIndex:
+ return "kRpgCommonDscBlockIndex";
+ case kRpgCommonDscDoorY2:
+ return "kRpgCommonDscDoorY2";
+ case kRpgCommonDscDoorFrameY1:
+ return "kRpgCommonDscDoorFrameY1";
+ case kRpgCommonDscDoorFrameY2:
+ return "kRpgCommonDscDoorFrameY2";
+ case kRpgCommonDscDoorFrameIndex1:
+ return "kRpgCommonDscDoorFrameIndex1";
+ case kRpgCommonDscDoorFrameIndex2:
+ return "kRpgCommonDscDoorFrameIndex2";
+ case kLoLDscDoorScale:
+ return "kLoLDscDoorScale";
+ case kLoLDscDoor4:
+ return "kLoLDscDoor4";
+ case kLoLDscDoorX:
+ return "kLoLDscDoorX";
+ case kLoLDscDoorY:
+ return "kLoLDscDoorY";
+ case kLoLScrollXTop:
+ return "kLoLScrollXTop";
+ case kLoLScrollYTop:
+ return "kLoLScrollYTop";
+ case kLoLScrollXBottom:
+ return "kLoLScrollXBottom";
+ case kLoLScrollYBottom:
+ return "kLoLScrollYBottom";
+ case kLoLButtonDefs:
+ return "kLoLButtonDefs";
+ case kLoLButtonList1:
+ return "kLoLButtonList1";
+ case kLoLButtonList2:
+ return "kLoLButtonList2";
+ case kLoLButtonList3:
+ return "kLoLButtonList3";
+ case kLoLButtonList4:
+ return "kLoLButtonList4";
+ case kLoLButtonList5:
+ return "kLoLButtonList5";
+ case kLoLButtonList6:
+ return "kLoLButtonList6";
+ case kLoLButtonList7:
+ return "kLoLButtonList7";
+ case kLoLButtonList8:
+ return "kLoLButtonList8";
+ case kLoLLegendData:
+ return "kLoLLegendData";
+ case kLoLMapCursorOvl:
+ return "kLoLMapCursorOvl";
+ case kLoLMapStringId:
+ return "kLoLMapStringId";
+ case kLoLSpellbookAnim:
+ return "kLoLSpellbookAnim";
+ case kLoLSpellbookCoords:
+ return "kLoLSpellbookCoords";
+ case kLoLHealShapeFrames:
+ return "kLoLHealShapeFrames";
+ case kLoLLightningDefs:
+ return "kLoLLightningDefs";
+ case kLoLFireballCoords:
+ return "kLoLFireballCoords";
+ case kLoLHistory:
+ return "kLoLHistory";
default:
return "Unknown";
}
diff --git a/devtools/create_kyradat/create_kyradat.h b/devtools/create_kyradat/create_kyradat.h
index cabf65706f..c2a69cfd79 100644
--- a/devtools/create_kyradat/create_kyradat.h
+++ b/devtools/create_kyradat/create_kyradat.h
@@ -179,89 +179,488 @@ enum kExtractID {
k3ItemMagicTable,
k3ItemStringMap,
- kLolIngamePakFiles,
- kLolCharacterDefs,
- kLolIngameSfxFiles,
- kLolIngameSfxIndex,
- kLolMusicTrackMap,
- kLolIngameGMSfxIndex,
- kLolIngameMT32SfxIndex,
- kLolIngamePcSpkSfxIndex,
- kLolSpellProperties,
- kLolGameShapeMap,
- kLolSceneItemOffs,
- kLolCharInvIndex,
- kLolCharInvDefs,
- kLolCharDefsMan,
- kLolCharDefsWoman,
- kLolCharDefsKieran,
- kLolCharDefsAkshel,
- kLolExpRequirements,
- kLolMonsterModifiers,
- kLolMonsterShiftOffsets,
- kLolMonsterDirFlags,
- kLolMonsterScaleY,
- kLolMonsterScaleX,
- kLolMonsterScaleWH,
- kLolFlyingObjectShp,
- kLolInventoryDesc,
-
- kLolLevelShpList,
- kLolLevelDatList,
- kLolCompassDefs,
- kLolItemPrices,
- kLolStashSetup,
-
- kLolDscUnk1,
- kLolDscShapeIndex,
- kLolDscOvlMap,
- kLolDscScaleWidthData,
- kLolDscScaleHeightData,
- kLolDscX,
- kLolDscY,
- kLolDscTileIndex,
- kLolDscUnk2,
- kLolDscDoorShapeIndex,
- kLolDscDimData1,
- kLolDscDimData2,
- kLolDscBlockMap,
- kLolDscDimMap,
- kLolDscDoor1,
- kLolDscDoorScale,
- kLolDscDoor4,
- kLolDscDoorX,
- kLolDscDoorY,
- kLolDscOvlIndex,
- kLolDscBlockIndex,
-
- kLolScrollXTop,
- kLolScrollYTop,
- kLolScrollXBottom,
- kLolScrollYBottom,
-
- kLolButtonDefs,
- kLolButtonList1,
- kLolButtonList2,
- kLolButtonList3,
- kLolButtonList4,
- kLolButtonList5,
- kLolButtonList6,
- kLolButtonList7,
- kLolButtonList8,
-
- kLolLegendData,
- kLolMapCursorOvl,
- kLolMapStringId,
-
- kLolSpellbookAnim,
- kLolSpellbookCoords,
- kLolHealShapeFrames,
- kLolLightningDefs,
- kLolFireballCoords,
-
- kLolCredits,
-
- kLolHistory,
+ kRpgCommonMoreStrings,
+ kRpgCommonDscShapeIndex,
+ kRpgCommonDscX,
+ kRpgCommonDscTileIndex,
+ kRpgCommonDscUnk2,
+ kRpgCommonDscDoorShapeIndex,
+ kRpgCommonDscDimData1,
+ kRpgCommonDscDimData2,
+ kRpgCommonDscBlockMap,
+ kRpgCommonDscDimMap,
+ kRpgCommonDscDoorY2,
+ kRpgCommonDscDoorFrameY1,
+ kRpgCommonDscDoorFrameY2,
+ kRpgCommonDscDoorFrameIndex1,
+ kRpgCommonDscDoorFrameIndex2,
+ kRpgCommonDscBlockIndex,
+
+ kEoBBaseChargenStrings1,
+ kEoBBaseChargenStrings2,
+ kEoBBaseChargenStartLevels,
+ kEoBBaseChargenStatStrings,
+ kEoBBaseChargenRaceSexStrings,
+ kEoBBaseChargenClassStrings,
+ kEoBBaseChargenAlignmentStrings,
+ kEoBBaseChargenEnterGameStrings,
+ kEoBBaseChargenClassMinStats,
+ kEoBBaseChargenRaceMinStats,
+ kEoBBaseChargenRaceMaxStats,
+
+ kEoBBaseSaveThrowTable1,
+ kEoBBaseSaveThrowTable2,
+ kEoBBaseSaveThrowTable3,
+ kEoBBaseSaveThrowTable4,
+ kEoBBaseSaveThrwLvlIndex,
+ kEoBBaseSaveThrwModDiv,
+ kEoBBaseSaveThrwModExt,
+
+ kEoBBasePryDoorStrings,
+ kEoBBaseWarningStrings,
+
+ kEoBBaseItemSuffixStringsRings,
+ kEoBBaseItemSuffixStringsPotions,
+ kEoBBaseItemSuffixStringsWands,
+
+ kEoBBaseRipItemStrings,
+ kEoBBaseCursedString,
+ kEoBBaseEnchantedString,
+ kEoBBaseMagicObjectStrings,
+ kEoBBaseMagicObject5String,
+ kEoBBasePatternSuffix,
+ kEoBBasePatternGrFix1,
+ kEoBBasePatternGrFix2,
+ kEoBBaseValidateArmorString,
+ kEoBBaseValidateCursedString,
+ kEoBBaseValidateNoDropString,
+ kEoBBasePotionStrings,
+ kEoBBaseWandString,
+ kEoBBaseItemMisuseStrings,
+
+ kEoBBaseTakenStrings,
+ kEoBBasePotionEffectStrings,
+
+ kEoBBaseYesNoStrings,
+ kEoBBaseNpcMaxStrings,
+ kEoBBaseOkStrings,
+ kEoBBaseNpcJoinStrings,
+ kEoBBaseCancelStrings,
+ kEoBBaseAbortStrings,
+
+ kEoBBaseMenuStringsMain,
+ kEoBBaseMenuStringsSaveLoad,
+ kEoBBaseMenuStringsOnOff,
+ kEoBBaseMenuStringsSpells,
+ kEoBBaseMenuStringsRest,
+ kEoBBaseMenuStringsDrop,
+ kEoBBaseMenuStringsExit,
+ kEoBBaseMenuStringsStarve,
+ kEoBBaseMenuStringsScribe,
+ kEoBBaseMenuStringsDrop2,
+ kEoBBaseMenuStringsHead,
+ kEoBBaseMenuStringsPoison,
+ kEoBBaseMenuStringsMgc,
+ kEoBBaseMenuStringsPrefs,
+ kEoBBaseMenuStringsRest2,
+ kEoBBaseMenuStringsRest3,
+ kEoBBaseMenuStringsRest4,
+ kEoBBaseMenuStringsDefeat,
+ kEoBBaseMenuStringsTransfer,
+ kEoBBaseMenuStringsSpec,
+ kEoBBaseMenuStringsSpellNo,
+ kEoBBaseMenuYesNoStrings,
+
+ kEoBBaseSpellLevelsMage,
+ kEoBBaseSpellLevelsCleric,
+ kEoBBaseNumSpellsCleric,
+ kEoBBaseNumSpellsWisAdj,
+ kEoBBaseNumSpellsPal,
+ kEoBBaseNumSpellsMage,
+
+ kEoBBaseCharGuiStringsHp,
+ kEoBBaseCharGuiStringsWp1,
+ kEoBBaseCharGuiStringsWp2,
+ kEoBBaseCharGuiStringsWr,
+ kEoBBaseCharGuiStringsSt1,
+ kEoBBaseCharGuiStringsSt2,
+ kEoBBaseCharGuiStringsIn,
+
+ kEoBBaseCharStatusStrings7,
+ kEoBBaseCharStatusStrings81,
+ kEoBBaseCharStatusStrings82,
+ kEoBBaseCharStatusStrings9,
+ kEoBBaseCharStatusStrings12,
+ kEoBBaseCharStatusStrings131,
+ kEoBBaseCharStatusStrings132,
+
+ kEoBBaseLevelGainStrings,
+ kEoBBaseExperienceTable0,
+ kEoBBaseExperienceTable1,
+ kEoBBaseExperienceTable2,
+ kEoBBaseExperienceTable3,
+ kEoBBaseExperienceTable4,
+
+ kEoBBaseClassModifierFlags,
+
+ kEoBBaseMonsterStepTable01,
+ kEoBBaseMonsterStepTable02,
+ kEoBBaseMonsterStepTable1,
+ kEoBBaseMonsterStepTable2,
+ kEoBBaseMonsterStepTable3,
+ kEoBBaseMonsterCloseAttPosTable1,
+ kEoBBaseMonsterCloseAttPosTable21,
+ kEoBBaseMonsterCloseAttPosTable22,
+ kEoBBaseMonsterCloseAttUnkTable,
+ kEoBBaseMonsterCloseAttChkTable1,
+ kEoBBaseMonsterCloseAttChkTable2,
+ kEoBBaseMonsterCloseAttDstTable1,
+ kEoBBaseMonsterCloseAttDstTable2,
+
+ kEoBBaseMonsterProximityTable,
+ kEoBBaseFindBlockMonstersTable,
+ kEoBBaseMonsterDirChangeTable,
+ kEoBBaseMonsterDistAttStrings,
+
+ kEoBBaseEncodeMonsterDefs,
+ kEoBBaseNpcPresets,
+
+ kEoBBaseWllFlagPreset,
+ kEoBBaseDscShapeCoords,
+
+ kEoBBaseDscDoorScaleOffs,
+ kEoBBaseDscDoorScaleMult1,
+ kEoBBaseDscDoorScaleMult2,
+ kEoBBaseDscDoorScaleMult3,
+ kEoBBaseDscDoorScaleMult4,
+ kEoBBaseDscDoorScaleMult5,
+ kEoBBaseDscDoorScaleMult6,
+ kEoBBaseDscDoorType5Offs,
+ kEoBBaseDscDoorXE,
+ kEoBBaseDscDoorY1,
+ kEoBBaseDscDoorY3,
+ kEoBBaseDscDoorY4,
+ kEoBBaseDscDoorY5,
+ kEoBBaseDscDoorY6,
+ kEoBBaseDscDoorY7,
+ kEoBBaseDscDoorCoordsExt,
+
+ kEoBBaseDscItemPosIndex,
+ kEoBBaseDscItemShpX,
+ kEoBBaseDscItemPosUnk,
+ kEoBBaseDscItemTileIndex,
+ kEoBBaseDscItemShapeMap,
+
+ kEoBBaseDscMonsterFrmOffsTbl1,
+ kEoBBaseDscMonsterFrmOffsTbl2,
+
+ kEoBBaseInvSlotX,
+ kEoBBaseInvSlotY,
+ kEoBBaseSlotValidationFlags,
+
+ kEoBBaseProjectileWeaponTypes,
+ kEoBBaseWandTypes,
+
+ kEoBBaseDrawObjPosIndex,
+ kEoBBaseFlightObjFlipIndex,
+ kEoBBaseFlightObjShpMap,
+ kEoBBaseFlightObjSclIndex,
+
+ kEoBBaseDscTelptrShpCoords,
+
+ kEoBBasePortalSeqData,
+ kEoBBaseManDef,
+ kEoBBaseManWord,
+ kEoBBaseManPrompt,
+
+ kEoBBaseBookNumbers,
+ kEoBBaseMageSpellsList,
+ kEoBBaseClericSpellsList,
+ kEoBBaseSpellNames,
+ kEoBBaseMagicStrings1,
+ kEoBBaseMagicStrings2,
+ kEoBBaseMagicStrings3,
+ kEoBBaseMagicStrings4,
+ kEoBBaseMagicStrings6,
+ kEoBBaseMagicStrings7,
+ kEoBBaseMagicStrings8,
+
+ kEoBBaseExpObjectTlMode,
+ kEoBBaseExpObjectTblIndex,
+ kEoBBaseExpObjectShpStart,
+ kEoBBaseExpObjectTbl1,
+ kEoBBaseExpObjectTbl2,
+ kEoBBaseExpObjectTbl3,
+ kEoBBaseExpObjectY,
+
+ kEoBBaseSparkDefSteps,
+ kEoBBaseSparkDefSubSteps,
+ kEoBBaseSparkDefShift,
+ kEoBBaseSparkDefAdd,
+ kEoBBaseSparkDefX,
+ kEoBBaseSparkDefY,
+ kEoBBaseSparkOfFlags1,
+ kEoBBaseSparkOfFlags2,
+ kEoBBaseSparkOfShift,
+ kEoBBaseSparkOfX,
+ kEoBBaseSparkOfY,
+
+ kEoBBaseSpellProperties,
+ kEoBBaseMagicFlightProps,
+ kEoBBaseTurnUndeadEffect,
+ kEoBBaseBurningHandsDest,
+ kEoBBaseConeOfColdDest1,
+ kEoBBaseConeOfColdDest2,
+ kEoBBaseConeOfColdDest3,
+ kEoBBaseConeOfColdDest4,
+ kEoBBaseConeOfColdGfxTbl,
+
+ kEoB1MainMenuStrings,
+ kEoB1BonusStrings,
+
+ kEoB1IntroFilesOpening,
+ kEoB1IntroFilesTower,
+ kEoB1IntroFilesOrb,
+ kEoB1IntroFilesWdEntry,
+ kEoB1IntroFilesKing,
+ kEoB1IntroFilesHands,
+ kEoB1IntroFilesWdExit,
+ kEoB1IntroFilesTunnel,
+ kEoB1IntroOpeningFrmDelay,
+ kEoB1IntroWdEncodeX,
+ kEoB1IntroWdEncodeY,
+ kEoB1IntroWdEncodeWH,
+ kEoB1IntroWdDsX,
+ kEoB1IntroWdDsY,
+ kEoB1IntroTvlX1,
+ kEoB1IntroTvlY1,
+ kEoB1IntroTvlX2,
+ kEoB1IntroTvlY2,
+ kEoB1IntroTvlW,
+ kEoB1IntroTvlH,
+
+ kEoB1DoorShapeDefs,
+ kEoB1DoorSwitchShapeDefs,
+ kEoB1DoorSwitchCoords,
+ kEoB1MonsterProperties,
+
+ kEoB1EnemyMageSpellList,
+ kEoB1EnemyMageSfx,
+ kEoB1BeholderSpellList,
+ kEoB1BeholderSfx,
+ kEoB1TurnUndeadString,
+
+ kEoB1CgaMappingDefault,
+ kEoB1CgaMappingAlt,
+ kEoB1CgaMappingInv,
+ kEoB1CgaMappingItemsL,
+ kEoB1CgaMappingItemsS,
+ kEoB1CgaMappingThrown,
+ kEoB1CgaMappingIcons,
+ kEoB1CgaMappingDeco,
+ kEoB1CgaLevelMappingIndex,
+ kEoB1CgaMappingLevel0,
+ kEoB1CgaMappingLevel1,
+ kEoB1CgaMappingLevel2,
+ kEoB1CgaMappingLevel3,
+ kEoB1CgaMappingLevel4,
+
+ kEoB1NpcShpData,
+ kEoB1NpcSubShpIndex1,
+ kEoB1NpcSubShpIndex2,
+ kEoB1NpcSubShpY,
+ kEoB1Npc0Strings,
+ kEoB1Npc11Strings,
+ kEoB1Npc12Strings,
+ kEoB1Npc21Strings,
+ kEoB1Npc22Strings,
+ kEoB1Npc31Strings,
+ kEoB1Npc32Strings,
+ kEoB1Npc4Strings,
+ kEoB1Npc5Strings,
+ kEoB1Npc6Strings,
+ kEoB1Npc7Strings,
+
+ kEoB2MainMenuStrings,
+
+ kEoB2TransferPortraitFrames,
+ kEoB2TransferConvertTable,
+ kEoB2TransferItemTable,
+ kEoB2TransferExpTable,
+ kEoB2TransferStrings1,
+ kEoB2TransferStrings2,
+ kEoB2TransferLabels,
+
+ kEoB2IntroStrings,
+ kEoB2IntroCPSFiles,
+ kEob2IntroAnimData00,
+ kEob2IntroAnimData01,
+ kEob2IntroAnimData02,
+ kEob2IntroAnimData03,
+ kEob2IntroAnimData04,
+ kEob2IntroAnimData05,
+ kEob2IntroAnimData06,
+ kEob2IntroAnimData07,
+ kEob2IntroAnimData08,
+ kEob2IntroAnimData09,
+ kEob2IntroAnimData10,
+ kEob2IntroAnimData11,
+ kEob2IntroAnimData12,
+ kEob2IntroAnimData13,
+ kEob2IntroAnimData14,
+ kEob2IntroAnimData15,
+ kEob2IntroAnimData16,
+ kEob2IntroAnimData17,
+ kEob2IntroAnimData18,
+ kEob2IntroAnimData19,
+ kEob2IntroAnimData20,
+ kEob2IntroAnimData21,
+ kEob2IntroAnimData22,
+ kEob2IntroAnimData23,
+ kEob2IntroAnimData24,
+ kEob2IntroAnimData25,
+ kEob2IntroAnimData26,
+ kEob2IntroAnimData27,
+ kEob2IntroAnimData28,
+ kEob2IntroAnimData29,
+ kEob2IntroAnimData30,
+ kEob2IntroAnimData31,
+ kEob2IntroAnimData32,
+ kEob2IntroAnimData33,
+ kEob2IntroAnimData34,
+ kEob2IntroAnimData35,
+ kEob2IntroAnimData36,
+ kEob2IntroAnimData37,
+ kEob2IntroAnimData38,
+ kEob2IntroAnimData39,
+ kEob2IntroAnimData40,
+ kEob2IntroAnimData41,
+ kEob2IntroAnimData42,
+ kEob2IntroAnimData43,
+ kEoB2IntroShapes00,
+ kEoB2IntroShapes01,
+ kEoB2IntroShapes04,
+ kEoB2IntroShapes07,
+
+ kEoB2FinaleStrings,
+ kEoB2CreditsData,
+ kEoB2FinaleCPSFiles,
+ kEob2FinaleAnimData00,
+ kEob2FinaleAnimData01,
+ kEob2FinaleAnimData02,
+ kEob2FinaleAnimData03,
+ kEob2FinaleAnimData04,
+ kEob2FinaleAnimData05,
+ kEob2FinaleAnimData06,
+ kEob2FinaleAnimData07,
+ kEob2FinaleAnimData08,
+ kEob2FinaleAnimData09,
+ kEob2FinaleAnimData10,
+ kEob2FinaleAnimData11,
+ kEob2FinaleAnimData12,
+ kEob2FinaleAnimData13,
+ kEob2FinaleAnimData14,
+ kEob2FinaleAnimData15,
+ kEob2FinaleAnimData16,
+ kEob2FinaleAnimData17,
+ kEob2FinaleAnimData18,
+ kEob2FinaleAnimData19,
+ kEob2FinaleAnimData20,
+ kEoB2FinaleShapes00,
+ kEoB2FinaleShapes03,
+ kEoB2FinaleShapes07,
+ kEoB2FinaleShapes09,
+ kEoB2FinaleShapes10,
+
+ kEoB2NpcShapeData,
+ kEoB2Npc1Strings,
+ kEoB2Npc2Strings,
+ kEoB2MonsterDustStrings,
+
+ kEoB2DreamSteps,
+ kEoB2KheldranStrings,
+ kEoB2HornStrings,
+ kEoB2HornSounds,
+
+ kEoB2WallOfForceDsX,
+ kEoB2WallOfForceDsY,
+ kEoB2WallOfForceNumW,
+ kEoB2WallOfForceNumH,
+ kEoB2WallOfForceShpId,
+
+ kLoLIngamePakFiles,
+ kLoLCharacterDefs,
+ kLoLIngameSfxFiles,
+ kLoLIngameSfxIndex,
+ kLoLMusicTrackMap,
+ kLoLIngameGMSfxIndex,
+ kLoLIngameMT32SfxIndex,
+ kLoLIngamePcSpkSfxIndex,
+ kLoLSpellProperties,
+ kLoLGameShapeMap,
+ kLoLSceneItemOffs,
+ kLoLCharInvIndex,
+ kLoLCharInvDefs,
+ kLoLCharDefsMan,
+ kLoLCharDefsWoman,
+ kLoLCharDefsKieran,
+ kLoLCharDefsAkshel,
+ kLoLExpRequirements,
+ kLoLMonsterModifiers,
+ kLoLMonsterShiftOffsets,
+ kLoLMonsterDirFlags,
+ kLoLMonsterScaleY,
+ kLoLMonsterScaleX,
+ kLoLMonsterScaleWH,
+ kLoLFlyingObjectShp,
+ kLoLInventoryDesc,
+
+ kLoLLevelShpList,
+ kLoLLevelDatList,
+ kLoLCompassDefs,
+ kLoLItemPrices,
+ kLoLStashSetup,
+
+ kLoLDscWalls,
+ kLoLDscOvlMap,
+ kLoLDscScaleWidthData,
+ kLoLDscScaleHeightData,
+ kLoLDscY,
+
+ kLoLDscDoorScale,
+ kLoLDscDoor4,
+ kLoLDscDoorX,
+ kLoLDscDoorY,
+ kLoLDscOvlIndex,
+
+ kLoLScrollXTop,
+ kLoLScrollYTop,
+ kLoLScrollXBottom,
+ kLoLScrollYBottom,
+
+ kLoLButtonDefs,
+ kLoLButtonList1,
+ kLoLButtonList2,
+ kLoLButtonList3,
+ kLoLButtonList4,
+ kLoLButtonList5,
+ kLoLButtonList6,
+ kLoLButtonList7,
+ kLoLButtonList8,
+
+ kLoLLegendData,
+ kLoLMapCursorOvl,
+ kLoLMapStringId,
+
+ kLoLSpellbookAnim,
+ kLoLSpellbookCoords,
+ kLoLHealShapeFrames,
+ kLoLLightningDefs,
+ kLoLFireballCoords,
+
+ kLoLCredits,
+
+ kLoLHistory,
kMaxResIDs
};
@@ -284,7 +683,9 @@ enum kGame {
kKyra1 = 0,
kKyra2,
kKyra3,
- kLol
+ kLoL,
+ kEoB1,
+ kEoB2
};
struct Game {
diff --git a/devtools/create_kyradat/extract.cpp b/devtools/create_kyradat/extract.cpp
index 371f2f4e2b..34308f1b5b 100644
--- a/devtools/create_kyradat/extract.cpp
+++ b/devtools/create_kyradat/extract.cpp
@@ -50,8 +50,11 @@ bool extractRaw16to8(PAKFile &out, const ExtractInformation *info, const byte *d
bool extractMrShapeAnimData(PAKFile &out, const ExtractInformation *info, const byte *data, const uint32 size, const char *filename, int id);
bool extractRaw16(PAKFile &out, const ExtractInformation *info, const byte *data, const uint32 size, const char *filename, int id);
bool extractRaw32(PAKFile &out, const ExtractInformation *info, const byte *data, const uint32 size, const char *filename, int id);
-bool extractLolButtonDefs(PAKFile &out, const ExtractInformation *info, const byte *data, const uint32 size, const char *filename, int id);
+bool extractLoLButtonDefs(PAKFile &out, const ExtractInformation *info, const byte *data, const uint32 size, const char *filename, int id);
+bool extractEoB2SeqData(PAKFile &out, const ExtractInformation *info, const byte *data, const uint32 size, const char *filename, int id);
+bool extractEoB2ShapeData(PAKFile &out, const ExtractInformation *info, const byte *data, const uint32 size, const char *filename, int id);
+bool extractEoBNpcData(PAKFile &out, const ExtractInformation *info, const byte *data, const uint32 size, const char *filename, int id);
// Extraction type table
const ExtractType extractTypeTable[] = {
@@ -73,13 +76,17 @@ const ExtractType extractTypeTable[] = {
{ k3TypeRaw16to8, extractRaw16to8 },
{ k3TypeShpData, extractMrShapeAnimData },
- { kLolTypeCharData, extractRaw },
- { kLolTypeSpellData, extractRaw },
- { kLolTypeCompassData, extractRaw16to8 },
- { kLolTypeFlightShpData, extractRaw16to8 },
- { kLolTypeRaw16, extractRaw16 },
- { kLolTypeRaw32, extractRaw32 },
- { kLolTypeButtonDef, extractLolButtonDefs },
+ { kLoLTypeCharData, extractRaw },
+ { kLoLTypeSpellData, extractRaw },
+ { kLoLTypeCompassData, extractRaw16to8 },
+ { kLoLTypeFlightShpData, extractRaw16to8 },
+ { kLoLTypeRaw16, extractRaw16 },
+ { kLoLTypeRaw32, extractRaw32 },
+ { kLoLTypeButtonDef, extractLoLButtonDefs },
+
+ { kEoB2TypeSeqData, extractEoB2SeqData },
+ { kEoB2TypeShapeData, extractEoB2ShapeData },
+ { kEoBTypeNpcData, extractEoBNpcData },
{ -1, 0 }
};
@@ -104,13 +111,16 @@ const TypeTable typeTable[] = {
{ k2TypeSfxList, 0 },
{ k3TypeRaw16to8, 1 },
{ k3TypeShpData, 7 },
- { kLolTypeRaw16, 13 },
- { kLolTypeRaw32, 14 },
- { kLolTypeButtonDef, 12 },
- { kLolTypeCharData, 8 },
- { kLolTypeSpellData, 9 },
- { kLolTypeCompassData, 10 },
- { kLolTypeFlightShpData, 11 },
+ { kLoLTypeRaw16, 13 },
+ { kLoLTypeRaw32, 14 },
+ { kLoLTypeButtonDef, 12 },
+ { kLoLTypeCharData, 8 },
+ { kLoLTypeSpellData, 9 },
+ { kLoLTypeCompassData, 10 },
+ { kLoLTypeFlightShpData, 11 },
+ { kEoB2TypeSeqData, 15 },
+ { kEoB2TypeShapeData, 16 },
+ { kEoBTypeNpcData, 17},
{ -1, 1 }
};
@@ -151,7 +161,7 @@ bool extractStrings(PAKFile &out, const ExtractInformation *info, const byte *da
static const uint8 rusFanSkip_k1GUIStrings[] = { 1, 3, 6, 8, 11, 13, 18 };
uint32 rusFanSkipIdLen = 0;
const uint8 *rusFanSkipId = 0;
- int rusFanEmptyId = 10000;
+ uint rusFanEmptyId = 10000;
uint32 skipCount = 0;
int patch = 0;
@@ -168,7 +178,7 @@ bool extractStrings(PAKFile &out, const ExtractInformation *info, const byte *da
if (id == k2IngamePakFiles)
patch = 4;
- if (info->lang == Common::RU_RUS) {
+ if (info->lang == Common::RU_RUS && info->special == kNoSpecial) {
patch = 5;
if (id == k2SeqplayStrings) {
rusFanSkipId = rusFanSkip_k2SeqplayStrings;
@@ -194,7 +204,7 @@ bool extractStrings(PAKFile &out, const ExtractInformation *info, const byte *da
}
// HACK
- if (id == k2SeqplayIntroTracks && info->game == kLol)
+ if (id == k2SeqplayIntroTracks && info->game == kLoL)
return extractStringsWoSuffix(out, info, data, size, filename, id);
}
@@ -304,7 +314,7 @@ bool extractStrings(PAKFile &out, const ExtractInformation *info, const byte *da
input += 0x11; output += 0x0F;
}
- strcpy((char*) output, (const char*) input);
+ strcpy((char *) output, (const char*) input);
uint32 stringsize = strlen((const char*)output) + 1;
input += stringsize; output += stringsize;
// skip empty entries
@@ -360,7 +370,7 @@ bool extractStrings(PAKFile &out, const ExtractInformation *info, const byte *da
} else if (patch == 5) {
const byte *c = data + size;
do {
- strcpy((char*) output, (const char*) input);
+ strcpy((char *) output, (const char*) input);
uint32 stringsize = strlen((const char*)output) + 1;
input += stringsize; output += stringsize;
@@ -384,7 +394,7 @@ bool extractStrings(PAKFile &out, const ExtractInformation *info, const byte *da
}
}
}
-
+
} while (input < c);
} else {
uint32 copySize = size;
@@ -393,7 +403,7 @@ bool extractStrings(PAKFile &out, const ExtractInformation *info, const byte *da
output += 44;
data += 44;
for (int t = 1; t != 10; t++) {
- sprintf((char*) output, "COST%d_SH.PAK", t);
+ sprintf((char *) output, "COST%d_SH.PAK", t);
output += 13;
}
data += 126;
@@ -566,7 +576,7 @@ bool extractHofSeqData(PAKFile &out, const ExtractInformation *info, const byte
byte *buffer = new byte[bufferSize];
assert(buffer);
memset(buffer, 0, bufferSize );
- uint16 *header = (uint16*) buffer;
+ uint16 *header = (uint16 *) buffer;
byte *output = buffer + headerSize;
uint16 *hdout = header;
@@ -741,7 +751,7 @@ bool extractHofSeqData(PAKFile &out, const ExtractInformation *info, const byte
byte *finBuffer = new byte[finBufferSize];
assert(finBuffer);
uint16 diff = headerSize - finHeaderSize;
- uint16 *finHeader = (uint16*) finBuffer;
+ uint16 *finHeader = (uint16 *) finBuffer;
for (int i = 1; i < finHeaderSize; i++)
WRITE_BE_UINT16(&finHeader[i], (READ_BE_UINT16(&header[i]) - diff));
@@ -750,7 +760,7 @@ bool extractHofSeqData(PAKFile &out, const ExtractInformation *info, const byte
memcpy (finBuffer + finHeaderSize, buffer + headerSize, finBufferSize - finHeaderSize);
delete[] buffer;
- finHeader = (uint16*) (finBuffer + ((numSequences + 2) * sizeof(uint16)));
+ finHeader = (uint16 *) (finBuffer + ((numSequences + 2) * sizeof(uint16)));
for (int i = 0; i < numNestedSequences; i++) {
uint8 * offs = finBuffer + READ_BE_UINT16(finHeader++) + 26;
uint16 ctrl = READ_BE_UINT16(offs);
@@ -1006,7 +1016,7 @@ bool extractRaw32(PAKFile &out, const ExtractInformation *info, const byte *data
return out.addFile(filename, buffer, size);
}
-bool extractLolButtonDefs(PAKFile &out, const ExtractInformation *info, const byte *data, const uint32 size, const char *filename, int id) {
+bool extractLoLButtonDefs(PAKFile &out, const ExtractInformation *info, const byte *data, const uint32 size, const char *filename, int id) {
int num = size / 22;
uint8 *buffer = new uint8[size];
uint32 outsize = num * 18;
@@ -1037,6 +1047,124 @@ bool extractLolButtonDefs(PAKFile &out, const ExtractInformation *info, const by
return out.addFile(filename, buffer, outsize);
}
+bool extractEoB2SeqData(PAKFile &out, const ExtractInformation *info, const byte *data, const uint32 size, const char *filename, int id) {
+ int num = size / 11;
+ uint8 *buffer = new uint8[size];
+ const uint8 *src = data;
+ uint8 *dst = buffer;
+
+ for (int i = 0; i < num; i++) {
+ memcpy(dst, src, 2);
+ src += 2; dst += 2;
+ WRITE_BE_UINT16(dst, READ_LE_UINT16(src));
+ src += 2; dst += 2;
+ memcpy(dst, src, 7);
+ src += 7; dst += 7;
+ }
+
+ return out.addFile(filename, buffer, size);
+}
+
+bool extractEoB2ShapeData(PAKFile &out, const ExtractInformation *info, const byte *data, const uint32 size, const char *filename, int id) {
+ int num = size / 6;
+ uint8 *buffer = new uint8[size];
+ const uint8 *src = data;
+ uint8 *dst = buffer;
+
+ for (int i = 0; i < num; i++) {
+ WRITE_BE_UINT16(dst, READ_LE_UINT16(src));
+ src += 2; dst += 2;
+ memcpy(dst, src, 4);
+ src += 4; dst += 4;
+ }
+
+ return out.addFile(filename, buffer, size);
+}
+
+bool extractEoBNpcData(PAKFile &out, const ExtractInformation *info, const byte *data, const uint32 size, const char *filename, int id) {
+ // We use one extraction routine for both EOB 1 and EOB 2 (in spite of the data format differences)
+ // since it is easy enough to generate a common output usable by both engines
+
+ uint8 *buffer = 0;
+ uint32 outsize = 0;
+
+ if (info->game == kEoB1) {
+ uint16 num = size / 243;
+ outsize = num * 111 + 2;
+ buffer = new uint8[outsize];
+ const uint8 *src = data;
+ uint8 *dst = buffer;
+
+ WRITE_BE_UINT16(dst, num);
+ dst += 2;
+
+ for (int i = 0; i < num; i++) {
+ memcpy(dst, src, 27);
+ src += 27; dst += 27;
+ WRITE_BE_UINT16(dst, *src++);
+ dst += 2;
+ WRITE_BE_UINT16(dst, *src++);
+ dst += 2;
+ memcpy(dst, src, 10);
+ src += 10; dst += 10;
+ WRITE_BE_UINT32(dst, READ_LE_UINT32(src));
+ src += 4; dst += 4;
+ WRITE_BE_UINT32(dst, READ_LE_UINT32(src));
+ src += 4; dst += 4;
+ WRITE_BE_UINT32(dst, READ_LE_UINT32(src));
+ src += 4; dst += 4;
+ // skipping lots of zero space
+ src += 64;
+ WRITE_BE_UINT32(dst, READ_LE_UINT32(src));
+ src += 4; dst += 4;
+ for (int ii = 0; ii < 27; ii++) {
+ WRITE_BE_UINT16(dst, READ_LE_UINT16(src));
+ src += 2; dst += 2;
+ }
+ // skipping more zero space
+ src += 70;
+ }
+ } else {
+ uint16 num = size / 345;
+ outsize = num * 111 + 2;
+ buffer = new uint8[outsize];
+ const uint8 *src = data;
+ uint8 *dst = buffer;
+
+ WRITE_BE_UINT16(dst, num);
+ dst += 2;
+
+ for (int i = 0; i < num; i++) {
+ memcpy(dst, src, 27);
+ src += 27; dst += 27;
+ WRITE_BE_UINT16(dst, READ_LE_UINT16(src));
+ src += 2; dst += 2;
+ WRITE_BE_UINT16(dst, READ_LE_UINT16(src));
+ src += 2; dst += 2;
+ memcpy(dst, src, 10);
+ src += 10; dst += 10;
+ WRITE_BE_UINT32(dst, READ_LE_UINT32(src));
+ src += 4; dst += 4;
+ WRITE_BE_UINT32(dst, READ_LE_UINT32(src));
+ src += 4; dst += 4;
+ WRITE_BE_UINT32(dst, READ_LE_UINT32(src));
+ src += 4; dst += 4;
+ // skipping lots of zero space
+ src += 164;
+ WRITE_BE_UINT32(dst, READ_LE_UINT32(src));
+ src += 4; dst += 4;
+ for (int ii = 0; ii < 27; ii++) {
+ WRITE_BE_UINT16(dst, READ_LE_UINT16(src));
+ src += 2; dst += 2;
+ }
+ // skipping more zero space
+ src += 70;
+ }
+ }
+
+ return out.addFile(filename, buffer, outsize);
+}
+
bool extractMrShapeAnimData(PAKFile &out, const ExtractInformation *info, const byte *data, const uint32 size, const char *filename, int id) {
int outsize = 1;
uint8 *buffer = new uint8[size + 1];
diff --git a/devtools/create_kyradat/extract.h b/devtools/create_kyradat/extract.h
index a44927427f..4af9a146f4 100644
--- a/devtools/create_kyradat/extract.h
+++ b/devtools/create_kyradat/extract.h
@@ -47,13 +47,17 @@ enum kExtractType {
k3TypeRaw16to8,
k3TypeShpData,
- kLolTypeRaw16,
- kLolTypeRaw32,
- kLolTypeButtonDef,
- kLolTypeCharData,
- kLolTypeSpellData,
- kLolTypeCompassData,
- kLolTypeFlightShpData
+ kLoLTypeRaw16,
+ kLoLTypeRaw32,
+ kLoLTypeButtonDef,
+ kLoLTypeCharData,
+ kLoLTypeSpellData,
+ kLoLTypeCompassData,
+ kLoLTypeFlightShpData,
+
+ kEoB2TypeSeqData,
+ kEoB2TypeShapeData,
+ kEoBTypeNpcData
};
struct ExtractInformation {
diff --git a/devtools/create_kyradat/games.cpp b/devtools/create_kyradat/games.cpp
index 86f3535f10..258d2dd50d 100644
--- a/devtools/create_kyradat/games.cpp
+++ b/devtools/create_kyradat/games.cpp
@@ -77,6 +77,7 @@ const Game kyra2Games[] = {
// talkie games
{ kKyra2, { EN_ANY, FR_FRA, DE_DEU }, kPlatformPC, kTalkieVersion, { "85bbc1cc6c4cef6ad31fc6ee79518efb", "e20d0d2e500f01e399ec588247a7e213" } },
{ kKyra2, { IT_ITA, FR_FRA, DE_DEU }, kPlatformPC, kTalkieVersion, { "130795aa8f2333250c895dae9028b9bb", "e20d0d2e500f01e399ec588247a7e213" } }, // Italian Fan Translation
+ { kKyra2, { RU_RUS, FR_FRA, DE_DEU }, kPlatformPC, kTalkieVersion, { "c3afd22959f515355b2a33cde950f418", "e20d0d2e500f01e399ec588247a7e213" } }, // Russian Fan Translation
// FM-TOWNS games
{ kKyra2, { EN_ANY, JA_JPN, -1 }, kPlatformFMTowns, kNoSpecial, { "74f50d79c919cc8e7196c24942ce43d7", "a9a7fd4f05d00090e9e8bda073e6d431" } },
@@ -96,22 +97,34 @@ const Game kyra3Games[] = {
GAME_DUMMY_ENTRY
};
+const Game eob1Games[] = {
+ { kEoB1, { EN_ANY, -1, -1 }, kPlatformPC, kNoSpecial, { "1bde1dd37b40ab6de8ad11be33a44c5a", "d760a605d1a1302d06975a1f209fdd72" } },
+ { kEoB1, { DE_DEU, -1, -1 }, kPlatformPC, kNoSpecial, { "0fa3c6e00a81171b9f2adb3fdeb8eea3", "756f300c62aabf1dbd3c26b3b04f8c00" } },
+ GAME_DUMMY_ENTRY
+};
+
+const Game eob2Games[] = {
+ { kEoB2, { EN_ANY, -1, -1 }, kPlatformPC, kNoSpecial, { "e006d031c2d854f748947f777e0c59b0", 0 } },
+ { kEoB2, { DE_DEU, -1, -1 }, kPlatformPC, kNoSpecial, { "6c6c4168deb2a4cb3dee3f1be2d39746", 0 } },
+ GAME_DUMMY_ENTRY
+};
+
const Game lolGames[] = {
// DOS demo
- { kLol, { EN_ANY, -1, -1 }, kPlatformPC, kDemoVersion, { "30bb5af87d38adb47d3e6ce06b1cb042", 0 } },
+ { kLoL, { EN_ANY, -1, -1 }, kPlatformPC, kDemoVersion, { "30bb5af87d38adb47d3e6ce06b1cb042", 0 } },
// DOS floppy (no language specifc strings except character presets)
- { kLol, { EN_ANY, -1, -1 }, kPlatformPC, kNoSpecial, { "0cc764a204f7ba8cefe1a5f14c479619", 0 } },
- { kLol, { RU_RUS, -1, -1 }, kPlatformPC, kNoSpecial, { "80a9f9bf243bc6ed36d98584fc6988c4", 0 } },
- { kLol, { DE_DEU, -1, -1 }, kPlatformPC, kNoSpecial, { "6b843869772c1b779e1386be868c15dd", 0 } },
+ { kLoL, { EN_ANY, -1, -1 }, kPlatformPC, kNoSpecial, { "0cc764a204f7ba8cefe1a5f14c479619", 0 } },
+ { kLoL, { RU_RUS, -1, -1 }, kPlatformPC, kNoSpecial, { "80a9f9bf243bc6ed36d98584fc6988c4", 0 } },
+ { kLoL, { DE_DEU, -1, -1 }, kPlatformPC, kNoSpecial, { "6b843869772c1b779e1386be868c15dd", 0 } },
// PC98 (no language specifc strings)
- { kLol, { JA_JPN, -1, -1 }, kPlatformPC98, kNoSpecial, { "6d5bd4a2f5ce433365734ca6b7a8d984", "1b0a457c48ae6908da301b656fe0aab4" } },
+ { kLoL, { JA_JPN, -1, -1 }, kPlatformPC98, kNoSpecial, { "6d5bd4a2f5ce433365734ca6b7a8d984", "1b0a457c48ae6908da301b656fe0aab4" } },
// DOS CD (multi language version, with no language specific strings)
- { kLol, { EN_ANY, FR_FRA, DE_DEU }, kPlatformPC, kTalkieVersion, { "9d1778314de80598c0b0d032e2a1a1cf", "263998ec600afca1cc7b935c473df670" } },
- { kLol, { IT_ITA, FR_FRA, DE_DEU }, kPlatformPC, kTalkieVersion, { "9d1778314de80598c0b0d032e2a1a1cf", "f2af366e00f79dbf832fa19701d71ed9" } }, // Italian fan translation
- { kLol, { EN_ANY, FR_FRA, RU_RUS }, kPlatformPC, kTalkieVersion, { "9d1778314de80598c0b0d032e2a1a1cf", "5b33478718968676343803911dd5e3e4" } }, // Russian fan translation
+ { kLoL, { EN_ANY, FR_FRA, DE_DEU }, kPlatformPC, kTalkieVersion, { "9d1778314de80598c0b0d032e2a1a1cf", "263998ec600afca1cc7b935c473df670" } },
+ { kLoL, { IT_ITA, FR_FRA, DE_DEU }, kPlatformPC, kTalkieVersion, { "9d1778314de80598c0b0d032e2a1a1cf", "f2af366e00f79dbf832fa19701d71ed9" } }, // Italian fan translation
+ { kLoL, { EN_ANY, FR_FRA, RU_RUS }, kPlatformPC, kTalkieVersion, { "9d1778314de80598c0b0d032e2a1a1cf", "5b33478718968676343803911dd5e3e4" } }, // Russian fan translation
GAME_DUMMY_ENTRY
};
@@ -122,6 +135,8 @@ const Game * const gameDescs[] = {
kyra2Games,
kyra3Games,
lolGames,
+ eob1Games,
+ eob2Games,
0
};
@@ -505,7 +520,6 @@ const int kyra1TownsNeed[] = {
k1ConfigStrings,
k1TownsMusicFadeTable,
- k1TownsMusicFadeTable,
k1TownsSFXwdTable,
k1TownsSFXbtTable,
k1TownsCDATable,
@@ -764,250 +778,256 @@ const int kyra3Need[] = {
};
const int lolFloppyNeed[] = {
- kLolIngamePakFiles,
-
- kLolCharacterDefs,
- kLolIngameSfxFiles,
- kLolIngameSfxIndex,
- kLolMusicTrackMap,
- kLolIngameGMSfxIndex,
- kLolIngameMT32SfxIndex,
- kLolIngamePcSpkSfxIndex,
- kLolSpellProperties,
- kLolGameShapeMap,
- kLolSceneItemOffs,
- kLolCharInvIndex,
- kLolCharInvDefs,
- kLolCharDefsMan,
- kLolCharDefsWoman,
- kLolCharDefsKieran,
- kLolCharDefsAkshel,
- kLolExpRequirements,
- kLolMonsterModifiers,
- kLolMonsterShiftOffsets,
- kLolMonsterDirFlags,
- kLolMonsterScaleY,
- kLolMonsterScaleX,
- kLolMonsterScaleWH,
- kLolFlyingObjectShp,
- kLolInventoryDesc,
-
- kLolLevelShpList,
- kLolLevelDatList,
- kLolCompassDefs,
- kLolStashSetup,
- kLolDscUnk1,
- kLolDscShapeIndex,
- kLolDscOvlMap,
- kLolDscScaleWidthData,
- kLolDscScaleHeightData,
- kLolDscX,
- kLolDscY,
- kLolDscTileIndex,
- kLolDscUnk2,
- kLolDscDoorShapeIndex,
- kLolDscDimData1,
- kLolDscDimData2,
- kLolDscBlockMap,
- kLolDscDimMap,
- kLolDscOvlIndex,
- kLolDscBlockIndex,
- kLolDscDoor1,
- kLolDscDoorScale,
- kLolDscDoor4,
- kLolDscDoorX,
- kLolDscDoorY,
-
- kLolScrollXTop,
- kLolScrollYTop,
- kLolScrollXBottom,
- kLolScrollYBottom,
-
- kLolButtonDefs,
- kLolButtonList1,
- kLolButtonList1,
- kLolButtonList2,
- kLolButtonList3,
- kLolButtonList4,
- kLolButtonList5,
- kLolButtonList6,
- kLolButtonList7,
- kLolButtonList8,
-
- kLolLegendData,
- kLolMapCursorOvl,
- kLolMapStringId,
-
- kLolSpellbookAnim,
- kLolSpellbookCoords,
- kLolHealShapeFrames,
- kLolLightningDefs,
- kLolFireballCoords,
+ kLoLIngamePakFiles,
+
+ kLoLCharacterDefs,
+ kLoLIngameSfxFiles,
+ kLoLIngameSfxIndex,
+ kLoLMusicTrackMap,
+ kLoLIngameGMSfxIndex,
+ kLoLIngameMT32SfxIndex,
+ kLoLIngamePcSpkSfxIndex,
+ kLoLSpellProperties,
+ kLoLGameShapeMap,
+ kLoLSceneItemOffs,
+ kLoLCharInvIndex,
+ kLoLCharInvDefs,
+ kLoLCharDefsMan,
+ kLoLCharDefsWoman,
+ kLoLCharDefsKieran,
+ kLoLCharDefsAkshel,
+ kLoLExpRequirements,
+ kLoLMonsterModifiers,
+ kLoLMonsterShiftOffsets,
+ kLoLMonsterDirFlags,
+ kLoLMonsterScaleY,
+ kLoLMonsterScaleX,
+ kLoLMonsterScaleWH,
+ kLoLFlyingObjectShp,
+ kLoLInventoryDesc,
+
+ kLoLLevelShpList,
+ kLoLLevelDatList,
+ kLoLCompassDefs,
+ kLoLStashSetup,
+ kLoLDscWalls,
+ kRpgCommonDscShapeIndex,
+ kLoLDscOvlMap,
+ kLoLDscScaleWidthData,
+ kLoLDscScaleHeightData,
+ kRpgCommonDscX,
+ kLoLDscY,
+ kRpgCommonDscTileIndex,
+ kRpgCommonDscUnk2,
+ kRpgCommonDscDoorShapeIndex,
+ kRpgCommonDscDimData1,
+ kRpgCommonDscDimData2,
+ kRpgCommonDscBlockMap,
+ kRpgCommonDscDimMap,
+ kLoLDscOvlIndex,
+ kRpgCommonDscBlockIndex,
+ kRpgCommonDscDoorY2,
+ kRpgCommonDscDoorFrameY1,
+ kRpgCommonDscDoorFrameY2,
+ kLoLDscDoorScale,
+ kLoLDscDoor4,
+ kLoLDscDoorX,
+ kLoLDscDoorY,
+
+ kLoLScrollXTop,
+ kLoLScrollYTop,
+ kLoLScrollXBottom,
+ kLoLScrollYBottom,
+
+ kLoLButtonDefs,
+ kLoLButtonList1,
+ kLoLButtonList1,
+ kLoLButtonList2,
+ kLoLButtonList3,
+ kLoLButtonList4,
+ kLoLButtonList5,
+ kLoLButtonList6,
+ kLoLButtonList7,
+ kLoLButtonList8,
+
+ kLoLLegendData,
+ kLoLMapCursorOvl,
+ kLoLMapStringId,
+
+ kLoLSpellbookAnim,
+ kLoLSpellbookCoords,
+ kLoLHealShapeFrames,
+ kLoLLightningDefs,
+ kLoLFireballCoords,
-1
};
const int lolPC98Need[] = {
- kLolIngamePakFiles,
-
- kLolCharacterDefs,
- kLolIngameSfxFiles,
- kLolIngameSfxIndex,
- kLolSpellProperties,
- kLolGameShapeMap,
- kLolSceneItemOffs,
- kLolCharInvIndex,
- kLolCharInvDefs,
- kLolCharDefsMan,
- kLolCharDefsWoman,
- kLolCharDefsKieran,
- kLolCharDefsAkshel,
- kLolExpRequirements,
- kLolMonsterModifiers,
- kLolMonsterShiftOffsets,
- kLolMonsterDirFlags,
- kLolMonsterScaleY,
- kLolMonsterScaleX,
- kLolMonsterScaleWH,
- kLolFlyingObjectShp,
- kLolInventoryDesc,
-
- kLolLevelShpList,
- kLolLevelDatList,
- kLolCompassDefs,
- kLolStashSetup,
- kLolDscUnk1,
- kLolDscShapeIndex,
- kLolDscOvlMap,
- kLolDscScaleWidthData,
- kLolDscScaleHeightData,
- kLolDscX,
- kLolDscY,
- kLolDscTileIndex,
- kLolDscUnk2,
- kLolDscDoorShapeIndex,
- kLolDscDimData1,
- kLolDscDimData2,
- kLolDscBlockMap,
- kLolDscDimMap,
- kLolDscOvlIndex,
- kLolDscBlockIndex,
- kLolDscDoor1,
- kLolDscDoorScale,
- kLolDscDoor4,
- kLolDscDoorX,
- kLolDscDoorY,
-
- kLolScrollXTop,
- kLolScrollYTop,
- kLolScrollXBottom,
- kLolScrollYBottom,
-
- kLolButtonDefs,
- kLolButtonList1,
- kLolButtonList1,
- kLolButtonList2,
- kLolButtonList3,
- kLolButtonList4,
- kLolButtonList5,
- kLolButtonList6,
- kLolButtonList7,
- kLolButtonList8,
-
- kLolLegendData,
- kLolMapStringId,
-
- kLolSpellbookAnim,
- kLolSpellbookCoords,
- kLolHealShapeFrames,
- kLolLightningDefs,
- kLolFireballCoords,
-
- kLolCredits,
+ kLoLIngamePakFiles,
+
+ kLoLCharacterDefs,
+ kLoLIngameSfxFiles,
+ kLoLIngameSfxIndex,
+ kLoLSpellProperties,
+ kLoLGameShapeMap,
+ kLoLSceneItemOffs,
+ kLoLCharInvIndex,
+ kLoLCharInvDefs,
+ kLoLCharDefsMan,
+ kLoLCharDefsWoman,
+ kLoLCharDefsKieran,
+ kLoLCharDefsAkshel,
+ kLoLExpRequirements,
+ kLoLMonsterModifiers,
+ kLoLMonsterShiftOffsets,
+ kLoLMonsterDirFlags,
+ kLoLMonsterScaleY,
+ kLoLMonsterScaleX,
+ kLoLMonsterScaleWH,
+ kLoLFlyingObjectShp,
+ kLoLInventoryDesc,
+
+ kLoLLevelShpList,
+ kLoLLevelDatList,
+ kLoLCompassDefs,
+ kLoLStashSetup,
+ kLoLDscWalls,
+ kRpgCommonDscShapeIndex,
+ kLoLDscOvlMap,
+ kLoLDscScaleWidthData,
+ kLoLDscScaleHeightData,
+ kRpgCommonDscX,
+ kLoLDscY,
+ kRpgCommonDscTileIndex,
+ kRpgCommonDscUnk2,
+ kRpgCommonDscDoorShapeIndex,
+ kRpgCommonDscDimData1,
+ kRpgCommonDscDimData2,
+ kRpgCommonDscBlockMap,
+ kRpgCommonDscDimMap,
+ kLoLDscOvlIndex,
+ kRpgCommonDscBlockIndex,
+ kRpgCommonDscDoorY2,
+ kRpgCommonDscDoorFrameY1,
+ kRpgCommonDscDoorFrameY2,
+ kLoLDscDoorScale,
+ kLoLDscDoor4,
+ kLoLDscDoorX,
+ kLoLDscDoorY,
+
+ kLoLScrollXTop,
+ kLoLScrollYTop,
+ kLoLScrollXBottom,
+ kLoLScrollYBottom,
+
+ kLoLButtonDefs,
+ kLoLButtonList1,
+ kLoLButtonList1,
+ kLoLButtonList2,
+ kLoLButtonList3,
+ kLoLButtonList4,
+ kLoLButtonList5,
+ kLoLButtonList6,
+ kLoLButtonList7,
+ kLoLButtonList8,
+
+ kLoLLegendData,
+ kLoLMapStringId,
+
+ kLoLSpellbookAnim,
+ kLoLSpellbookCoords,
+ kLoLHealShapeFrames,
+ kLoLLightningDefs,
+ kLoLFireballCoords,
+
+ kLoLCredits,
-1
};
const int lolCDNeed[] = {
- kLolHistory,
- kLolCharacterDefs,
- kLolIngameSfxFiles,
- kLolIngameSfxIndex,
- kLolMusicTrackMap,
- kLolIngameGMSfxIndex,
- kLolIngameMT32SfxIndex,
- kLolIngamePcSpkSfxIndex,
- kLolSpellProperties,
- kLolGameShapeMap,
- kLolSceneItemOffs,
- kLolCharInvIndex,
- kLolCharInvDefs,
- kLolCharDefsMan,
- kLolCharDefsWoman,
- kLolCharDefsKieran,
- kLolCharDefsAkshel,
- kLolExpRequirements,
- kLolMonsterModifiers,
- kLolMonsterShiftOffsets,
- kLolMonsterDirFlags,
- kLolMonsterScaleY,
- kLolMonsterScaleX,
- kLolMonsterScaleWH,
- kLolFlyingObjectShp,
- kLolInventoryDesc,
-
- kLolLevelShpList,
- kLolLevelDatList,
- kLolCompassDefs,
- kLolItemPrices,
- kLolStashSetup,
- kLolDscUnk1,
- kLolDscShapeIndex,
- kLolDscOvlMap,
- kLolDscScaleWidthData,
- kLolDscScaleHeightData,
- kLolDscX,
- kLolDscY,
- kLolDscTileIndex,
- kLolDscUnk2,
- kLolDscDoorShapeIndex,
- kLolDscDimData1,
- kLolDscDimData2,
- kLolDscBlockMap,
- kLolDscDimMap,
- kLolDscOvlIndex,
- kLolDscBlockIndex,
- kLolDscDoor1,
- kLolDscDoorScale,
- kLolDscDoor4,
- kLolDscDoorX,
- kLolDscDoorY,
-
- kLolScrollXTop,
- kLolScrollYTop,
- kLolScrollXBottom,
- kLolScrollYBottom,
-
- kLolButtonDefs,
- kLolButtonList1,
- kLolButtonList1,
- kLolButtonList2,
- kLolButtonList3,
- kLolButtonList4,
- kLolButtonList5,
- kLolButtonList6,
- kLolButtonList7,
- kLolButtonList8,
-
- kLolLegendData,
- kLolMapCursorOvl,
- kLolMapStringId,
-
- kLolSpellbookAnim,
- kLolSpellbookCoords,
- kLolHealShapeFrames,
- kLolLightningDefs,
- kLolFireballCoords,
+ kLoLHistory,
+ kLoLCharacterDefs,
+ kLoLIngameSfxFiles,
+ kLoLIngameSfxIndex,
+ kLoLMusicTrackMap,
+ kLoLIngameGMSfxIndex,
+ kLoLIngameMT32SfxIndex,
+ kLoLIngamePcSpkSfxIndex,
+ kLoLSpellProperties,
+ kLoLGameShapeMap,
+ kLoLSceneItemOffs,
+ kLoLCharInvIndex,
+ kLoLCharInvDefs,
+ kLoLCharDefsMan,
+ kLoLCharDefsWoman,
+ kLoLCharDefsKieran,
+ kLoLCharDefsAkshel,
+ kLoLExpRequirements,
+ kLoLMonsterModifiers,
+ kLoLMonsterShiftOffsets,
+ kLoLMonsterDirFlags,
+ kLoLMonsterScaleY,
+ kLoLMonsterScaleX,
+ kLoLMonsterScaleWH,
+ kLoLFlyingObjectShp,
+ kLoLInventoryDesc,
+
+ kLoLLevelShpList,
+ kLoLLevelDatList,
+ kLoLCompassDefs,
+ kLoLItemPrices,
+ kLoLStashSetup,
+ kLoLDscWalls,
+ kRpgCommonDscShapeIndex,
+ kLoLDscOvlMap,
+ kLoLDscScaleWidthData,
+ kLoLDscScaleHeightData,
+ kRpgCommonDscX,
+ kLoLDscY,
+ kRpgCommonDscTileIndex,
+ kRpgCommonDscUnk2,
+ kRpgCommonDscDoorShapeIndex,
+ kRpgCommonDscDimData1,
+ kRpgCommonDscDimData2,
+ kRpgCommonDscBlockMap,
+ kRpgCommonDscDimMap,
+ kLoLDscOvlIndex,
+ kRpgCommonDscBlockIndex,
+ kRpgCommonDscDoorY2,
+ kRpgCommonDscDoorFrameY1,
+ kRpgCommonDscDoorFrameY2,
+ kLoLDscDoorScale,
+ kLoLDscDoor4,
+ kLoLDscDoorX,
+ kLoLDscDoorY,
+
+ kLoLScrollXTop,
+ kLoLScrollYTop,
+ kLoLScrollXBottom,
+ kLoLScrollYBottom,
+
+ kLoLButtonDefs,
+ kLoLButtonList1,
+ kLoLButtonList1,
+ kLoLButtonList2,
+ kLoLButtonList3,
+ kLoLButtonList4,
+ kLoLButtonList5,
+ kLoLButtonList6,
+ kLoLButtonList7,
+ kLoLButtonList8,
+
+ kLoLLegendData,
+ kLoLMapCursorOvl,
+ kLoLMapStringId,
+
+ kLoLSpellbookAnim,
+ kLoLSpellbookCoords,
+ kLoLHealShapeFrames,
+ kLoLLightningDefs,
+ kLoLFireballCoords,
-1
};
@@ -1020,6 +1040,617 @@ const int lolDemoNeed[] = {
-1
};
+const int eob1FloppyNeed[] = {
+ kEoBBaseChargenStrings1,
+ kEoBBaseChargenStrings2,
+ kEoBBaseChargenStartLevels,
+ kEoBBaseChargenStatStrings,
+ kEoBBaseChargenRaceSexStrings,
+ kEoBBaseChargenClassStrings,
+ kEoBBaseChargenAlignmentStrings,
+ kEoBBaseChargenEnterGameStrings,
+ kEoBBaseChargenClassMinStats,
+ kEoBBaseChargenRaceMinStats,
+ kEoBBaseChargenRaceMaxStats,
+
+ kEoBBaseSaveThrowTable1,
+ kEoBBaseSaveThrowTable2,
+ kEoBBaseSaveThrowTable3,
+ kEoBBaseSaveThrowTable4,
+ kEoBBaseSaveThrwLvlIndex,
+ kEoBBaseSaveThrwModDiv,
+ kEoBBaseSaveThrwModExt,
+
+ kEoB1MainMenuStrings,
+ kEoB1BonusStrings,
+
+ kEoB1IntroFilesOpening,
+ kEoB1IntroFilesTower,
+ kEoB1IntroFilesOrb,
+ kEoB1IntroFilesWdEntry,
+ kEoB1IntroFilesKing,
+ kEoB1IntroFilesHands,
+ kEoB1IntroFilesWdExit,
+ kEoB1IntroFilesTunnel,
+ kEoB1IntroOpeningFrmDelay,
+ kEoB1IntroWdEncodeX,
+ kEoB1IntroWdEncodeY,
+ kEoB1IntroWdEncodeWH,
+ kEoB1IntroWdDsX,
+ kEoB1IntroWdDsY,
+ kEoB1IntroTvlX1,
+ kEoB1IntroTvlY1,
+ kEoB1IntroTvlX2,
+ kEoB1IntroTvlY2,
+ kEoB1IntroTvlW,
+ kEoB1IntroTvlH,
+
+ kEoB1DoorShapeDefs,
+ kEoB1DoorSwitchShapeDefs,
+ kEoB1DoorSwitchCoords,
+ kEoB1MonsterProperties,
+ kEoB1EnemyMageSpellList,
+ kEoB1EnemyMageSfx,
+ kEoB1BeholderSpellList,
+ kEoB1BeholderSfx,
+ kEoB1TurnUndeadString,
+
+ kEoB1CgaMappingDefault,
+ kEoB1CgaMappingAlt,
+ kEoB1CgaMappingInv,
+ kEoB1CgaMappingItemsL,
+ kEoB1CgaMappingItemsS,
+ kEoB1CgaMappingThrown,
+ kEoB1CgaMappingIcons,
+ kEoB1CgaMappingDeco,
+ kEoB1CgaLevelMappingIndex,
+ kEoB1CgaMappingLevel0,
+ kEoB1CgaMappingLevel1,
+ kEoB1CgaMappingLevel2,
+ kEoB1CgaMappingLevel3,
+ kEoB1CgaMappingLevel4,
+
+ kEoB1NpcShpData,
+ kEoB1NpcSubShpIndex1,
+ kEoB1NpcSubShpIndex2,
+ kEoB1NpcSubShpY,
+ kEoB1Npc0Strings,
+ kEoB1Npc11Strings,
+ kEoB1Npc12Strings,
+ kEoB1Npc21Strings,
+ kEoB1Npc22Strings,
+ kEoB1Npc31Strings,
+ kEoB1Npc32Strings,
+ kEoB1Npc4Strings,
+ kEoB1Npc5Strings,
+ kEoB1Npc6Strings,
+ kEoB1Npc7Strings,
+
+ kEoBBasePryDoorStrings,
+ kEoBBaseWarningStrings,
+
+ kEoBBaseItemSuffixStringsRings,
+ kEoBBaseItemSuffixStringsPotions,
+ kEoBBaseItemSuffixStringsWands,
+
+ kEoBBaseRipItemStrings,
+ kEoBBaseCursedString,
+ kEoBBaseEnchantedString,
+ kEoBBaseMagicObjectStrings,
+ kEoBBaseMagicObject5String,
+ kEoBBasePatternSuffix,
+ kEoBBasePatternGrFix1,
+ kEoBBasePatternGrFix2,
+ kEoBBaseValidateArmorString,
+ kEoBBaseValidateNoDropString,
+ kEoBBasePotionStrings,
+ kEoBBaseWandString,
+ kEoBBaseItemMisuseStrings,
+
+ kEoBBaseTakenStrings,
+ kEoBBasePotionEffectStrings,
+
+ kEoBBaseYesNoStrings,
+ kRpgCommonMoreStrings,
+ kEoBBaseNpcMaxStrings,
+ kEoBBaseNpcJoinStrings,
+ kEoBBaseCancelStrings,
+
+ kEoBBaseMenuStringsMain,
+ kEoBBaseMenuStringsSaveLoad,
+ kEoBBaseMenuStringsOnOff,
+ kEoBBaseMenuStringsSpells,
+ kEoBBaseMenuStringsRest,
+ kEoBBaseMenuStringsDrop,
+ kEoBBaseMenuStringsExit,
+ kEoBBaseMenuStringsStarve,
+ kEoBBaseMenuStringsScribe,
+ kEoBBaseMenuStringsDrop2,
+ kEoBBaseMenuStringsHead,
+ kEoBBaseMenuStringsPoison,
+ kEoBBaseMenuStringsMgc,
+ kEoBBaseMenuStringsPrefs,
+ kEoBBaseMenuStringsRest2,
+ kEoBBaseMenuStringsRest4,
+ kEoBBaseMenuStringsDefeat,
+ kEoBBaseMenuYesNoStrings,
+
+ kEoBBaseSpellLevelsMage,
+ kEoBBaseSpellLevelsCleric,
+ kEoBBaseNumSpellsCleric,
+ kEoBBaseNumSpellsWisAdj,
+ kEoBBaseNumSpellsPal,
+ kEoBBaseNumSpellsMage,
+
+ kEoBBaseCharGuiStringsHp,
+ kEoBBaseCharGuiStringsWp1,
+ kEoBBaseCharGuiStringsWr,
+ kEoBBaseCharGuiStringsSt1,
+ kEoBBaseCharGuiStringsIn,
+
+ kEoBBaseCharStatusStrings7,
+ kEoBBaseCharStatusStrings81,
+ kEoBBaseCharStatusStrings9,
+ kEoBBaseCharStatusStrings131,
+
+ kEoBBaseLevelGainStrings,
+ kEoBBaseExperienceTable0,
+ kEoBBaseExperienceTable1,
+ kEoBBaseExperienceTable2,
+ kEoBBaseExperienceTable3,
+ kEoBBaseExperienceTable4,
+
+ kEoBBaseBookNumbers,
+ kEoBBaseMageSpellsList,
+ kEoBBaseClericSpellsList,
+ kEoBBaseSpellNames,
+ kEoBBaseMagicStrings1,
+ kEoBBaseMagicStrings2,
+ kEoBBaseMagicStrings3,
+ kEoBBaseMagicStrings4,
+ kEoBBaseMagicStrings6,
+ kEoBBaseMagicStrings7,
+ kEoBBaseMagicStrings8,
+
+ kEoBBaseExpObjectTblIndex,
+ kEoBBaseExpObjectShpStart,
+ kEoBBaseExpObjectTbl1,
+ kEoBBaseExpObjectTbl2,
+ kEoBBaseExpObjectTbl3,
+ kEoBBaseExpObjectY,
+
+ kEoBBaseSparkDefSteps,
+ kEoBBaseSparkDefSubSteps,
+ kEoBBaseSparkDefShift,
+ kEoBBaseSparkDefAdd,
+ kEoBBaseSparkDefX,
+ kEoBBaseSparkDefY,
+ kEoBBaseSparkOfFlags1,
+ kEoBBaseSparkOfFlags2,
+ kEoBBaseSparkOfShift,
+ kEoBBaseSparkOfX,
+ kEoBBaseSparkOfY,
+
+ kEoBBaseSpellProperties,
+ kEoBBaseMagicFlightProps,
+ kEoBBaseTurnUndeadEffect,
+ kEoBBaseBurningHandsDest,
+ kEoBBaseConeOfColdDest1,
+ kEoBBaseConeOfColdDest2,
+ kEoBBaseConeOfColdDest3,
+ kEoBBaseConeOfColdDest4,
+ kEoBBaseConeOfColdGfxTbl,
+
+ kRpgCommonDscDoorShapeIndex,
+ kEoBBaseWllFlagPreset,
+ kEoBBaseDscShapeCoords,
+ kEoBBaseDscDoorScaleOffs,
+ kEoBBaseDscDoorScaleMult1,
+ kEoBBaseDscDoorScaleMult2,
+ kEoBBaseDscDoorScaleMult3,
+ kEoBBaseDscDoorScaleMult4,
+ kEoBBaseDscDoorScaleMult5,
+ kEoBBaseDscDoorScaleMult6,
+ kEoBBaseDscDoorXE,
+ kEoBBaseDscDoorY1,
+ kEoBBaseDscDoorY3,
+ kEoBBaseDscDoorY4,
+ kEoBBaseDscDoorY5,
+ kEoBBaseDscDoorY6,
+ kEoBBaseDscDoorY7,
+ kEoBBaseDscDoorCoordsExt,
+ kRpgCommonDscDoorFrameY1,
+ kRpgCommonDscDoorFrameY2,
+ kRpgCommonDscDoorFrameIndex1,
+ kRpgCommonDscDoorFrameIndex2,
+
+ kEoBBaseDscItemPosIndex,
+ kEoBBaseDscItemShpX,
+ kEoBBaseDscItemPosUnk,
+ kEoBBaseDscItemTileIndex,
+ kEoBBaseDscItemShapeMap,
+ kEoBBaseDscTelptrShpCoords,
+
+ kEoBBasePortalSeqData,
+ kEoBBaseManDef,
+ kEoBBaseManWord,
+ kEoBBaseManPrompt,
+
+ kEoBBaseDscMonsterFrmOffsTbl1,
+ kEoBBaseDscMonsterFrmOffsTbl2,
+
+ kEoBBaseInvSlotX,
+ kEoBBaseInvSlotY,
+ kEoBBaseSlotValidationFlags,
+
+ kEoBBaseProjectileWeaponTypes,
+ kEoBBaseWandTypes,
+
+ kEoBBaseDrawObjPosIndex,
+ kEoBBaseFlightObjFlipIndex,
+ kEoBBaseFlightObjShpMap,
+ kEoBBaseFlightObjSclIndex,
+
+ kRpgCommonDscShapeIndex,
+ kRpgCommonDscX,
+ kRpgCommonDscTileIndex,
+ kRpgCommonDscUnk2,
+ kRpgCommonDscDimData1,
+ kRpgCommonDscDimData2,
+ kRpgCommonDscBlockMap,
+ kRpgCommonDscDimMap,
+ kRpgCommonDscBlockIndex,
+
+ kEoBBaseClassModifierFlags,
+
+ kEoBBaseMonsterStepTable01,
+ //kEoBBaseMonsterStepTable1,
+ kEoBBaseMonsterStepTable2,
+ kEoBBaseMonsterStepTable3,
+ kEoBBaseMonsterCloseAttPosTable1,
+ kEoBBaseMonsterCloseAttPosTable21,
+ //kEoBBaseMonsterCloseAttUnkTable,
+ kEoBBaseMonsterCloseAttChkTable1,
+ kEoBBaseMonsterCloseAttChkTable2,
+ kEoBBaseMonsterCloseAttDstTable1,
+ kEoBBaseMonsterCloseAttDstTable2,
+
+ kEoBBaseMonsterProximityTable,
+ kEoBBaseFindBlockMonstersTable,
+ kEoBBaseMonsterDirChangeTable,
+ kEoBBaseMonsterDistAttStrings,
+ kEoBBaseEncodeMonsterDefs,
+ kEoBBaseNpcPresets,
+ //kEoB1Npc1Strings,
+ //kEoB1Npc2Strings,
+ -1
+};
+
+const int eob2FloppyNeed[] = {
+ kEoBBaseChargenStrings1,
+ kEoBBaseChargenStrings2,
+ kEoBBaseChargenStartLevels,
+ kEoBBaseChargenStatStrings,
+ kEoBBaseChargenRaceSexStrings,
+ kEoBBaseChargenClassStrings,
+ kEoBBaseChargenAlignmentStrings,
+ kEoBBaseChargenEnterGameStrings,
+ kEoBBaseChargenClassMinStats,
+ kEoBBaseChargenRaceMinStats,
+ kEoBBaseChargenRaceMaxStats,
+
+ kEoBBaseSaveThrowTable1,
+ kEoBBaseSaveThrowTable2,
+ kEoBBaseSaveThrowTable3,
+ kEoBBaseSaveThrowTable4,
+ kEoBBaseSaveThrwLvlIndex,
+ kEoBBaseSaveThrwModDiv,
+ kEoBBaseSaveThrwModExt,
+
+ kEoBBasePryDoorStrings,
+ kEoBBaseWarningStrings,
+
+ kEoBBaseItemSuffixStringsRings,
+ kEoBBaseItemSuffixStringsPotions,
+ kEoBBaseItemSuffixStringsWands,
+
+ kEoBBaseRipItemStrings,
+ kEoBBaseCursedString,
+ kEoBBaseEnchantedString,
+ kEoBBaseMagicObjectStrings,
+ kEoBBaseMagicObject5String,
+ kEoBBasePatternSuffix,
+ kEoBBasePatternGrFix1,
+ kEoBBasePatternGrFix2,
+ kEoBBaseValidateArmorString,
+ kEoBBaseValidateCursedString,
+ kEoBBaseValidateNoDropString,
+ kEoBBasePotionStrings,
+ kEoBBaseWandString,
+ kEoBBaseItemMisuseStrings,
+
+ kEoBBaseTakenStrings,
+ kEoBBasePotionEffectStrings,
+
+ kEoBBaseYesNoStrings,
+ kRpgCommonMoreStrings,
+ kEoBBaseNpcMaxStrings,
+ kEoBBaseOkStrings,
+ kEoBBaseNpcJoinStrings,
+ kEoBBaseCancelStrings,
+ kEoBBaseAbortStrings,
+
+ kEoBBaseMenuStringsMain,
+ kEoBBaseMenuStringsSaveLoad,
+ kEoBBaseMenuStringsOnOff,
+ kEoBBaseMenuStringsSpells,
+ kEoBBaseMenuStringsRest,
+ kEoBBaseMenuStringsDrop,
+ kEoBBaseMenuStringsExit,
+ kEoBBaseMenuStringsStarve,
+ kEoBBaseMenuStringsScribe,
+ kEoBBaseMenuStringsDrop2,
+ kEoBBaseMenuStringsHead,
+ kEoBBaseMenuStringsPoison,
+ kEoBBaseMenuStringsMgc,
+ kEoBBaseMenuStringsPrefs,
+ kEoBBaseMenuStringsRest2,
+ kEoBBaseMenuStringsRest3,
+ kEoBBaseMenuStringsRest4,
+ kEoBBaseMenuStringsDefeat,
+ kEoBBaseMenuStringsTransfer,
+ kEoBBaseMenuStringsSpec,
+ kEoBBaseMenuStringsSpellNo,
+ kEoBBaseMenuYesNoStrings,
+
+ kEoBBaseSpellLevelsMage,
+ kEoBBaseSpellLevelsCleric,
+ kEoBBaseNumSpellsCleric,
+ kEoBBaseNumSpellsWisAdj,
+ kEoBBaseNumSpellsPal,
+ kEoBBaseNumSpellsMage,
+
+ kEoBBaseCharGuiStringsHp,
+ kEoBBaseCharGuiStringsWp2,
+ kEoBBaseCharGuiStringsWr,
+ kEoBBaseCharGuiStringsSt2,
+ kEoBBaseCharGuiStringsIn,
+
+ kEoBBaseCharStatusStrings7,
+ kEoBBaseCharStatusStrings82,
+ kEoBBaseCharStatusStrings9,
+ kEoBBaseCharStatusStrings12,
+ kEoBBaseCharStatusStrings132,
+
+ kEoBBaseLevelGainStrings,
+ kEoBBaseExperienceTable0,
+ kEoBBaseExperienceTable1,
+ kEoBBaseExperienceTable2,
+ kEoBBaseExperienceTable3,
+ kEoBBaseExperienceTable4,
+
+ kEoBBaseBookNumbers,
+ kEoBBaseMageSpellsList,
+ kEoBBaseClericSpellsList,
+ kEoBBaseSpellNames,
+ kEoBBaseMagicStrings1,
+ kEoBBaseMagicStrings2,
+ kEoBBaseMagicStrings3,
+ kEoBBaseMagicStrings4,
+ kEoBBaseMagicStrings6,
+ kEoBBaseMagicStrings7,
+ kEoBBaseMagicStrings8,
+
+ kEoBBaseExpObjectTlMode,
+ kEoBBaseExpObjectTblIndex,
+ kEoBBaseExpObjectShpStart,
+ kEoBBaseExpObjectTbl1,
+ kEoBBaseExpObjectTbl2,
+ kEoBBaseExpObjectTbl3,
+ kEoBBaseExpObjectY,
+
+ kEoBBaseSparkDefSteps,
+ kEoBBaseSparkDefSubSteps,
+ kEoBBaseSparkDefShift,
+ kEoBBaseSparkDefAdd,
+ kEoBBaseSparkDefX,
+ kEoBBaseSparkDefY,
+ kEoBBaseSparkOfFlags1,
+ kEoBBaseSparkOfFlags2,
+ kEoBBaseSparkOfShift,
+ kEoBBaseSparkOfX,
+ kEoBBaseSparkOfY,
+
+ kEoBBaseSpellProperties,
+ kEoBBaseMagicFlightProps,
+ kEoBBaseTurnUndeadEffect,
+ kEoBBaseBurningHandsDest,
+ kEoBBaseConeOfColdDest1,
+ kEoBBaseConeOfColdDest2,
+ kEoBBaseConeOfColdDest3,
+ kEoBBaseConeOfColdDest4,
+ kEoBBaseConeOfColdGfxTbl,
+
+ kRpgCommonDscDoorShapeIndex,
+ kEoBBaseWllFlagPreset,
+ kEoBBaseDscShapeCoords,
+
+ kEoBBaseDscDoorScaleOffs,
+ kEoBBaseDscDoorScaleMult1,
+ kEoBBaseDscDoorScaleMult2,
+ kEoBBaseDscDoorScaleMult3,
+ kEoBBaseDscDoorType5Offs,
+ kEoBBaseDscDoorY1,
+ kRpgCommonDscDoorY2,
+ kRpgCommonDscDoorFrameY1,
+ kRpgCommonDscDoorFrameY2,
+
+ kEoBBaseDscItemPosIndex,
+ kEoBBaseDscItemShpX,
+ kEoBBaseDscItemPosUnk,
+ kEoBBaseDscItemTileIndex,
+ kEoBBaseDscItemShapeMap,
+ kEoBBaseDscTelptrShpCoords,
+
+ kEoBBasePortalSeqData,
+ kEoBBaseManDef,
+ kEoBBaseManWord,
+ kEoBBaseManPrompt,
+
+ kEoBBaseDscMonsterFrmOffsTbl1,
+ kEoBBaseDscMonsterFrmOffsTbl2,
+
+ kEoBBaseInvSlotX,
+ kEoBBaseInvSlotY,
+ kEoBBaseSlotValidationFlags,
+
+ kEoBBaseProjectileWeaponTypes,
+ kEoBBaseWandTypes,
+
+ kEoBBaseDrawObjPosIndex,
+ kEoBBaseFlightObjFlipIndex,
+ kEoBBaseFlightObjShpMap,
+ kEoBBaseFlightObjSclIndex,
+
+ kEoB2MainMenuStrings,
+
+ kEoB2TransferPortraitFrames,
+ kEoB2TransferConvertTable,
+ kEoB2TransferItemTable,
+ kEoB2TransferExpTable,
+ kEoB2TransferStrings1,
+ kEoB2TransferStrings2,
+ kEoB2TransferLabels,
+
+ kEoB2IntroStrings,
+ kEoB2IntroCPSFiles,
+ kEob2IntroAnimData00,
+ kEob2IntroAnimData01,
+ kEob2IntroAnimData02,
+ kEob2IntroAnimData03,
+ kEob2IntroAnimData04,
+ kEob2IntroAnimData05,
+ kEob2IntroAnimData06,
+ kEob2IntroAnimData07,
+ kEob2IntroAnimData08,
+ kEob2IntroAnimData09,
+ kEob2IntroAnimData10,
+ kEob2IntroAnimData11,
+ kEob2IntroAnimData12,
+ kEob2IntroAnimData13,
+ kEob2IntroAnimData14,
+ kEob2IntroAnimData15,
+ kEob2IntroAnimData16,
+ kEob2IntroAnimData17,
+ kEob2IntroAnimData18,
+ kEob2IntroAnimData19,
+ kEob2IntroAnimData20,
+ kEob2IntroAnimData21,
+ kEob2IntroAnimData22,
+ kEob2IntroAnimData23,
+ kEob2IntroAnimData24,
+ kEob2IntroAnimData25,
+ kEob2IntroAnimData26,
+ kEob2IntroAnimData27,
+ kEob2IntroAnimData28,
+ kEob2IntroAnimData29,
+ kEob2IntroAnimData30,
+ kEob2IntroAnimData31,
+ kEob2IntroAnimData32,
+ kEob2IntroAnimData33,
+ kEob2IntroAnimData34,
+ kEob2IntroAnimData35,
+ kEob2IntroAnimData36,
+ kEob2IntroAnimData37,
+ kEob2IntroAnimData38,
+ kEob2IntroAnimData39,
+ kEob2IntroAnimData40,
+ kEob2IntroAnimData41,
+ kEob2IntroAnimData42,
+ kEob2IntroAnimData43,
+
+ kEoB2IntroShapes00,
+ kEoB2IntroShapes01,
+ kEoB2IntroShapes04,
+ kEoB2IntroShapes07,
+
+ kEoB2FinaleStrings,
+ kEoB2CreditsData,
+ kEoB2FinaleCPSFiles,
+ kEob2FinaleAnimData00,
+ kEob2FinaleAnimData01,
+ kEob2FinaleAnimData02,
+ kEob2FinaleAnimData03,
+ kEob2FinaleAnimData04,
+ kEob2FinaleAnimData05,
+ kEob2FinaleAnimData06,
+ kEob2FinaleAnimData07,
+ kEob2FinaleAnimData08,
+ kEob2FinaleAnimData09,
+ kEob2FinaleAnimData10,
+ kEob2FinaleAnimData11,
+ kEob2FinaleAnimData12,
+ kEob2FinaleAnimData13,
+ kEob2FinaleAnimData14,
+ kEob2FinaleAnimData15,
+ kEob2FinaleAnimData16,
+ kEob2FinaleAnimData17,
+ kEob2FinaleAnimData18,
+ kEob2FinaleAnimData19,
+ kEob2FinaleAnimData20,
+ kEoB2FinaleShapes00,
+ kEoB2FinaleShapes03,
+ kEoB2FinaleShapes07,
+ kEoB2FinaleShapes09,
+ kEoB2FinaleShapes10,
+
+ kEoB2NpcShapeData,
+ kEoBBaseClassModifierFlags,
+
+ kEoBBaseMonsterStepTable02,
+ kEoBBaseMonsterStepTable1,
+ kEoBBaseMonsterStepTable2,
+ kEoBBaseMonsterStepTable3,
+ kEoBBaseMonsterCloseAttPosTable1,
+ kEoBBaseMonsterCloseAttPosTable22,
+ kEoBBaseMonsterCloseAttUnkTable,
+ kEoBBaseMonsterCloseAttChkTable1,
+ kEoBBaseMonsterCloseAttChkTable2,
+ kEoBBaseMonsterCloseAttDstTable1,
+ kEoBBaseMonsterCloseAttDstTable2,
+
+ kEoBBaseMonsterProximityTable,
+ kEoBBaseFindBlockMonstersTable,
+ kEoBBaseMonsterDirChangeTable,
+ kEoBBaseMonsterDistAttStrings,
+ kEoBBaseEncodeMonsterDefs,
+ kEoBBaseNpcPresets,
+ kEoB2Npc1Strings,
+ kEoB2Npc2Strings,
+ kEoB2MonsterDustStrings,
+ kEoB2DreamSteps,
+ kEoB2KheldranStrings,
+ kEoB2HornStrings,
+ kEoB2HornSounds,
+ kEoB2WallOfForceDsX,
+ kEoB2WallOfForceDsY,
+ kEoB2WallOfForceNumW,
+ kEoB2WallOfForceNumH,
+ kEoB2WallOfForceShpId,
+
+ kRpgCommonDscShapeIndex,
+ kRpgCommonDscX,
+ kRpgCommonDscTileIndex,
+ kRpgCommonDscUnk2,
+ kRpgCommonDscDimData1,
+ kRpgCommonDscDimData2,
+ kRpgCommonDscBlockMap,
+ kRpgCommonDscDimMap,
+ kRpgCommonDscBlockIndex,
+
+ -1
+};
+
struct GameNeed {
int game;
int platform;
@@ -1055,14 +1686,18 @@ const GameNeed gameNeedTable[] = {
{ kKyra2, kPlatformPC, kDemoVersion, kyra2DemoNeed },
- { kLol, kPlatformPC, kDemoVersion, lolDemoNeed },
+ { kLoL, kPlatformPC, kDemoVersion, lolDemoNeed },
{ kKyra3, kPlatformPC, kTalkieVersion, kyra3Need },
- { kLol, kPlatformPC, kNoSpecial, lolFloppyNeed },
- { kLol, kPlatformPC98, kNoSpecial, lolPC98Need },
+ { kLoL, kPlatformPC, kNoSpecial, lolFloppyNeed },
+ { kLoL, kPlatformPC98, kNoSpecial, lolPC98Need },
+
+ { kLoL, kPlatformPC, kTalkieVersion, lolCDNeed },
+
+ { kEoB1, kPlatformPC, kNoSpecial, eob1FloppyNeed },
- { kLol, kPlatformPC, kTalkieVersion, lolCDNeed },
+ { kEoB2, kPlatformPC, kNoSpecial, eob2FloppyNeed },
{ -1, -1, -1, 0 }
};
diff --git a/devtools/create_kyradat/module.mk b/devtools/create_kyradat/module.mk
index 4241f82e34..fb458b43ff 100644
--- a/devtools/create_kyradat/module.mk
+++ b/devtools/create_kyradat/module.mk
@@ -14,8 +14,5 @@ MODULE_OBJS := \
# Set the name of the executable
TOOL_EXECUTABLE := create_kyradat
-# Link against common code (for scumm_stricmp)
-TOOL_DEPS := common/libcommon.a
-
# Include common rules
include $(srcdir)/rules.mk
diff --git a/devtools/create_kyradat/tables.cpp b/devtools/create_kyradat/tables.cpp
index 8042dcac71..1b9ca45259 100644
--- a/devtools/create_kyradat/tables.cpp
+++ b/devtools/create_kyradat/tables.cpp
@@ -137,7 +137,7 @@ const ExtractEntrySearchData k1OutroReunionSeqProvider[] = {
{ UNK_LANG, kPlatformPC, { 0x00000547, 0x0000781C, { { 0xCF, 0xD6, 0x1D, 0x3D, 0x14, 0x40, 0x88, 0x35, 0x36, 0x4F, 0x0B, 0x1F, 0x9A, 0x1C, 0x3D, 0xAC } } } }, // floppy
{ UNK_LANG, kPlatformPC, { 0x00000547, 0x000077E0, { { 0x80, 0xC4, 0xFC, 0xD5, 0xEB, 0xAA, 0xA5, 0x87, 0x58, 0x5E, 0xAA, 0xE7, 0x01, 0x8F, 0x59, 0x3F } } } }, // floppy
{ UNK_LANG, kPlatformPC, { 0x000005E5, 0x00008918, { { 0x6A, 0x33, 0x8C, 0xB0, 0x16, 0x57, 0x2D, 0xEB, 0xB2, 0xE1, 0x64, 0x80, 0x98, 0x99, 0x98, 0x19 } } } }, // CD
-
+
{ UNK_LANG, kPlatformAmiga, { 0x0000054A, 0x0000785F, { { 0x55, 0xEA, 0xB8, 0x7F, 0x3A, 0x86, 0xCD, 0xA6, 0xBC, 0xA7, 0x9A, 0x39, 0xED, 0xF5, 0x30, 0x0A } } } },
{ UNK_LANG, kPlatformUnknown, { 0x00000547, 0x00007876, { { 0x7A, 0xC7, 0x80, 0x34, 0x7A, 0x1B, 0xAB, 0xF8, 0xA7, 0x2F, 0x63, 0x3C, 0xDA, 0x89, 0x3F, 0x82 } } } }, // some floppy DOS + FM-TOWNS
@@ -342,9 +342,9 @@ const ExtractEntrySearchData k1PlacedStringsProvider[] = {
{ IT_ITA, kPlatformPC, { 0x0000000D, 0x0000040D, { { 0x9C, 0x71, 0x53, 0x35, 0xC3, 0xE8, 0x46, 0xB9, 0xD2, 0xFA, 0x1C, 0x8C, 0xC3, 0xFF, 0xBC, 0x1F } } } }, // floppy
{ IT_ITA, kPlatformPC, { 0x00000011, 0x000003B8, { { 0xC8, 0xA6, 0xE4, 0x8A, 0xF7, 0x4C, 0x3F, 0xA6, 0x24, 0x7F, 0xEF, 0xE4, 0x63, 0x8B, 0x72, 0xF3 } } } }, // (fan) CD
-
+
{ ES_ESP, kPlatformPC, { 0x0000000D, 0x00000439, { { 0x57, 0xAE, 0x1C, 0xC1, 0xF5, 0xE8, 0x5B, 0x9E, 0x90, 0x02, 0xB9, 0x8D, 0x86, 0x38, 0xFB, 0xA8 } } } },
-
+
{ RU_RUS, kPlatformPC, { 0x00000009, 0x00000203, { { 0x7D, 0xAE, 0x67, 0x94, 0x8E, 0x73, 0x35, 0xC1, 0x11, 0xB4, 0x55, 0x6E, 0x92, 0x25, 0x39, 0xE4 } } } },
EXTRACT_END_ENTRY
@@ -563,7 +563,7 @@ const ExtractEntrySearchData k1ThePoisonStringsProvider[] = {
{ ES_ESP, kPlatformPC, { 0x00000059, 0x00001DF7, { { 0x16, 0x7B, 0x5F, 0x91, 0x06, 0x5B, 0xFC, 0x9C, 0x88, 0x61, 0xCC, 0x1B, 0x52, 0x4F, 0x91, 0xC5 } } } },
{ RU_RUS, kPlatformPC, { 0x00000052, 0x0000136F, { { 0xEF, 0xD2, 0xA0, 0x5F, 0xD5, 0xE6, 0x77, 0x96, 0xFA, 0xC5, 0x60, 0x7C, 0xB7, 0xA8, 0x7C, 0x7A } } } },
-
+
{ EN_ANY, kPlatformAmiga, { 0x00000058, 0x00001C24, { { 0xBA, 0x1F, 0xBD, 0x5C, 0x85, 0x3D, 0x3C, 0x92, 0xD1, 0x13, 0xF3, 0x40, 0x2E, 0xBB, 0x1C, 0xE2 } } } },
{ DE_DEU, kPlatformAmiga, { 0x00000073, 0x00002690, { { 0x44, 0xAE, 0xC9, 0xFD, 0x9F, 0x8E, 0x1B, 0xDD, 0x3F, 0xE4, 0x4D, 0x4B, 0x5A, 0x13, 0xE5, 0x99 } } } },
@@ -1113,6 +1113,7 @@ const ExtractEntrySearchData k2SeqplayStringsProvider[] = {
{ IT_ITA, kPlatformPC, { 0x00000916, 0x0003188F, { { 0xDC, 0x46, 0x06, 0xE1, 0xB0, 0x66, 0xBC, 0x18, 0x2E, 0x6E, 0x9E, 0xC9, 0xA4, 0x14, 0x8D, 0x08 } } } }, // floppy
{ IT_ITA, kPlatformPC, { 0x000008C8, 0x00030947, { { 0x7F, 0x75, 0x5F, 0x99, 0x94, 0xFE, 0xA1, 0xE6, 0xEF, 0xB8, 0x93, 0x71, 0x83, 0x1B, 0xAC, 0x4A } } } }, // (fan) CD
+ { RU_RUS, kPlatformPC, { 0x00000916, 0x00032C49, { { 0xEA, 0x5C, 0xE5, 0x06, 0x05, 0x5F, 0x36, 0xE8, 0x31, 0x3E, 0xBF, 0x74, 0x73, 0xFB, 0xAB, 0xFF } } } }, // (fan) CD - intro and outro strings haven't been translated in this fan translation
{ RU_RUS, kPlatformPC, { 0x000008C8, 0x00028639, { { 0xF9, 0x1D, 0x6A, 0x85, 0x23, 0x5E, 0x2A, 0x64, 0xBC, 0x45, 0xB2, 0x48, 0x13, 0x49, 0xD4, 0xF7 } } } }, // (fan) floppy
{ EN_ANY, kPlatformFMTowns, { 0x00000990, 0x00030C61, { { 0x60, 0x51, 0x11, 0x83, 0x3F, 0x06, 0xC3, 0xA3, 0xE0, 0xC0, 0x2F, 0x41, 0x29, 0xDE, 0x65, 0xB1 } } } },
@@ -1142,6 +1143,7 @@ const ExtractEntrySearchData k2SeqplayTlkFilesProvider[] = {
{ FR_FRA, kPlatformPC, { 0x0000009D, 0x00002878, { { 0x28, 0x5D, 0x7F, 0x5B, 0x57, 0xC2, 0xFF, 0x73, 0xC1, 0x8E, 0xD6, 0xE0, 0x4D, 0x03, 0x99, 0x2C } } } },
{ DE_DEU, kPlatformPC, { 0x0000009D, 0x00002885, { { 0x87, 0x24, 0xB6, 0xE9, 0xD6, 0xAA, 0x68, 0x2D, 0x6B, 0x05, 0xDF, 0xE1, 0x2B, 0xA4, 0x79, 0xE5 } } } },
{ IT_ITA, kPlatformPC, { 0x0000009D, 0x0000286B, { { 0x58, 0x30, 0x72, 0x62, 0xC8, 0x77, 0x2A, 0x06, 0xD6, 0x24, 0x1A, 0x7A, 0xAF, 0x79, 0xFF, 0xAE } } } },
+ { RU_RUS, kPlatformPC, { 0x0000009D, 0x0000286B, { { 0x58, 0x30, 0x72, 0x62, 0xC8, 0x77, 0x2A, 0x06, 0xD6, 0x24, 0x1A, 0x7A, 0xAF, 0x79, 0xFF, 0xAE } } } },
EXTRACT_END_ENTRY
};
@@ -1222,7 +1224,7 @@ const ExtractEntrySearchData k2IngamePakFilesProvider[] = {
const ExtractEntrySearchData k2IngameSfxFilesProvider[] = {
{ UNK_LANG, kPlatformPC, { 0x000006F1, 0x0001545E, { { 0xD3, 0x8A, 0xA1, 0xD4, 0x83, 0x77, 0x96, 0x6D, 0x87, 0xB1, 0x71, 0x8F, 0x38, 0x6A, 0x34, 0xDC } } } },
{ UNK_LANG, kPlatformFMTowns, { 0x00000967, 0x0002101A, { { 0x09, 0xC7, 0xB7, 0x2A, 0x76, 0xF1, 0x4B, 0x87, 0xC5, 0x83, 0xFF, 0xF3, 0xDB, 0x3C, 0x66, 0x60 } } } },
- { UNK_LANG, kPlatformPC98, { 0x000006F1, 0x0001545E, { { 0xD3, 0x8A, 0xA1, 0xD4, 0x83, 0x77, 0x96, 0x6D, 0x87, 0xB1, 0x71, 0x8F, 0x38, 0x6A, 0x34, 0xDC } } } },
+ { UNK_LANG, kPlatformPC98, { 0x000006F1, 0x0001545E, { { 0xD3, 0x8A, 0xA1, 0xD4, 0x83, 0x77, 0x96, 0x6D, 0x87, 0xB1, 0x71, 0x8F, 0x38, 0x6A, 0x34, 0xDC } } } },
EXTRACT_END_ENTRY
};
@@ -1331,14 +1333,2017 @@ const ExtractEntrySearchData k3ItemStringMapProvider[] = {
EXTRACT_END_ENTRY
};
-const ExtractEntrySearchData kLolIngamePakFilesProvider[] = {
+const ExtractEntrySearchData kEoBBaseChargenStrings1Provider[] = {
+ { EN_ANY, kPlatformUnknown, { 0x000000CA, 0x00003BC8, { { 0x27, 0xEA, 0xE3, 0x0D, 0x55, 0xB3, 0x69, 0x3E, 0xC2, 0x66, 0x58, 0x64, 0xAA, 0xC2, 0x80, 0x58 } } } },
+ { DE_DEU, kPlatformUnknown, { 0x000000C3, 0x000038F6, { { 0x20, 0x68, 0xAB, 0xD4, 0xBF, 0x49, 0x04, 0xC0, 0x91, 0xB4, 0x71, 0xB0, 0xB6, 0xC9, 0x11, 0xF0 } } } }, // EOB 1
+ { DE_DEU, kPlatformUnknown, { 0x000000C7, 0x00003ADB, { { 0x0D, 0x03, 0x7A, 0xE6, 0x7D, 0x41, 0x89, 0x49, 0x0C, 0xB6, 0xD0, 0x4F, 0xEA, 0x1E, 0x54, 0xFF } } } }, // EOB 2
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBaseChargenStrings2Provider[] = {
+ { EN_ANY, kPlatformUnknown, { 0x0000004B, 0x000011AE, { { 0x28, 0x98, 0x4C, 0xA3, 0x98, 0xB0, 0xA2, 0x17, 0x9C, 0x80, 0x4F, 0x3F, 0x58, 0x3B, 0x2C, 0xFB } } } },
+ { DE_DEU, kPlatformUnknown, { 0x0000004E, 0x0000129D, { { 0xED, 0xF3, 0x36, 0x16, 0xE2, 0x1B, 0x32, 0x95, 0xFE, 0xE8, 0x3E, 0x7D, 0xE6, 0x32, 0x34, 0xD4 } } } }, // EOB 1
+ { DE_DEU, kPlatformUnknown, { 0x0000004A, 0x00001267, { { 0xD6, 0xE2, 0x27, 0x6A, 0x6F, 0x7E, 0xB4, 0xCE, 0xA8, 0xE9, 0x79, 0x31, 0x5C, 0x13, 0xA1, 0x8F } } } }, // EOB 2
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBaseChargenStartLevelsProvider[] = {
+ { UNK_LANG, kPlatformUnknown, { 0x0000003C, 0x00000054, { { 0xAB, 0x68, 0x74, 0x3E, 0x0D, 0x45, 0xA3, 0x50, 0xA7, 0x72, 0x6A, 0xDF, 0x9C, 0x23, 0x98, 0x74 } } } }, // EOB 1
+ { UNK_LANG, kPlatformUnknown, { 0x0000003C, 0x000000B1, { { 0xFD, 0x3F, 0x6B, 0xB5, 0xE4, 0xEE, 0x32, 0x3B, 0xBD, 0x72, 0x37, 0x88, 0x52, 0x84, 0xBD, 0xC6 } } } }, // EOB 2
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBaseChargenStatStringsProvider[] = {
+ { EN_ANY, kPlatformUnknown, { 0x00000055, 0x000015D6, { { 0xB8, 0x29, 0x4B, 0xA4, 0x4F, 0x45, 0x16, 0x1A, 0x07, 0x28, 0x14, 0x86, 0x1B, 0xDF, 0xAC, 0xDF } } } },
+ { DE_DEU, kPlatformUnknown, { 0x00000056, 0x000015F9, { { 0xBB, 0x5A, 0x7D, 0xCF, 0xC3, 0x90, 0x9A, 0xB3, 0x73, 0xB2, 0x4D, 0x46, 0xB8, 0x89, 0x7D, 0xAE } } } }, // EOB 1
+ { DE_DEU, kPlatformUnknown, { 0x00000053, 0x0000159A, { { 0x1D, 0xA6, 0x84, 0xDB, 0xC5, 0x81, 0xC7, 0xF0, 0x1C, 0xA4, 0xE3, 0x10, 0x4F, 0x8A, 0xF3, 0xCE } } } }, // EOB 2
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBaseChargenRaceSexStringsProvider[] = {
+ { EN_ANY, kPlatformUnknown, { 0x00000098, 0x00002572, { { 0x8D, 0xF9, 0xDE, 0x92, 0xFC, 0xA8, 0xFC, 0xE9, 0x0A, 0x98, 0x6D, 0xA4, 0x6F, 0x21, 0xCD, 0xF4 } } } },
+ { DE_DEU, kPlatformUnknown, { 0x000000AA, 0x00002A1E, { { 0x8E, 0xAF, 0x4B, 0x20, 0xEA, 0xFE, 0x71, 0x8E, 0x8B, 0x4B, 0x46, 0x62, 0x91, 0x48, 0x08, 0xAF } } } }, // EOB 1
+ { DE_DEU, kPlatformUnknown, { 0x00000098, 0x00002502, { { 0xA4, 0x8B, 0x20, 0xF5, 0x97, 0xFE, 0x34, 0x6D, 0x9F, 0xF0, 0xA8, 0xE9, 0xE8, 0xFA, 0x23, 0x9B } } } }, // EOB 2
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBaseChargenClassStringsProvider[] = {
+ { EN_ANY, kPlatformUnknown, { 0x000000D5, 0x000035A7, { { 0xAF, 0x89, 0x9A, 0x11, 0x9A, 0x8D, 0x39, 0x6F, 0x26, 0x41, 0x4E, 0x20, 0xAD, 0x91, 0xC5, 0xDA } } } },
+ { DE_DEU, kPlatformUnknown, { 0x000000FA, 0x00003FD8, { { 0xBD, 0x78, 0xF7, 0xEC, 0x9D, 0x9A, 0x3A, 0x22, 0xAB, 0xD9, 0x10, 0xAD, 0x8E, 0x1D, 0x4D, 0xDE } } } }, // EOB 1
+ { DE_DEU, kPlatformUnknown, { 0x000000E4, 0x00003BE5, { { 0xDE, 0x1B, 0x25, 0x4F, 0xE6, 0xD0, 0xB5, 0x95, 0xD0, 0xA6, 0x69, 0xE6, 0x53, 0xB8, 0x20, 0x1E } } } }, // EOB 2
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBaseChargenAlignmentStringsProvider[] = {
+ { EN_ANY, kPlatformUnknown, { 0x00000078, 0x00001F44, { { 0xBB, 0x52, 0x3C, 0xA6, 0x79, 0x87, 0xDC, 0xB8, 0x21, 0x7A, 0xA0, 0x17, 0x45, 0xEA, 0xF2, 0x50 } } } },
+ { DE_DEU, kPlatformUnknown, { 0x0000008A, 0x00002423, { { 0xA3, 0x36, 0x0D, 0x64, 0x33, 0xFD, 0x54, 0xA5, 0xA9, 0xD7, 0xFA, 0x34, 0x39, 0xAD, 0x6A, 0x98 } } } }, // EOB 1
+ { DE_DEU, kPlatformUnknown, { 0x0000007F, 0x000021F8, { { 0xBD, 0xB2, 0x06, 0xF9, 0xC9, 0x36, 0x5D, 0x91, 0x43, 0x08, 0x3A, 0x2C, 0x5F, 0x1C, 0xF3, 0x9C } } } }, // EOB 2
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBaseChargenEnterGameStringsProvider[] = {
+ { EN_ANY, kPlatformUnknown, { 0x00000020, 0x00000A0E, { { 0x98, 0x7F, 0x2C, 0x2E, 0xBB, 0x5E, 0xAA, 0xD0, 0x72, 0xF5, 0xBC, 0x4A, 0x34, 0x5B, 0xB4, 0xF5 } } } },
+ { DE_DEU, kPlatformUnknown, { 0x00000021, 0x00000AB6, { { 0x02, 0x7F, 0x19, 0x5A, 0xA9, 0xB7, 0x8C, 0xE2, 0xF7, 0x35, 0xB0, 0xD8, 0xA8, 0x0C, 0x24, 0x44 } } } }, // EOB 1
+ { DE_DEU, kPlatformUnknown, { 0x0000001E, 0x00000925, { { 0xDA, 0x83, 0x00, 0xD2, 0x94, 0xF0, 0xD8, 0xFC, 0x3D, 0xA8, 0xD2, 0x4E, 0xF2, 0xD7, 0x2B, 0x7E } } } }, // EOB 2
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBaseChargenClassMinStatsProvider[] = {
+ { UNK_LANG, kPlatformUnknown, { 0x000000B4, 0x00000165, { { 0x83, 0x5E, 0x91, 0x10, 0x4D, 0x75, 0x6B, 0xF9, 0x45, 0x1B, 0x65, 0x13, 0x37, 0x3E, 0xC0, 0xAE } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBaseChargenRaceMinStatsProvider[] = {
+ { UNK_LANG, kPlatformUnknown, { 0x00000048, 0x000000B2, { { 0x08, 0xF0, 0x8F, 0x22, 0x9D, 0xD8, 0xBE, 0x52, 0x70, 0x7C, 0xCA, 0x8D, 0xB2, 0xF5, 0xC6, 0xB8 } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBaseChargenRaceMaxStatsProvider[] = {
+ { UNK_LANG, kPlatformUnknown, { 0x00000048, 0x00000479, { { 0xBD, 0xA0, 0x8C, 0xC2, 0x05, 0xCA, 0x0D, 0x4B, 0x82, 0x9B, 0x3D, 0xB5, 0x4B, 0xDB, 0xD2, 0xC1 } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBaseSaveThrowTable1Provider[] = {
+ { UNK_LANG, kPlatformUnknown, { 0x00000032, 0x00000214, { { 0x3D, 0x89, 0x30, 0x0A, 0x5C, 0x4A, 0x0F, 0xC3, 0xC7, 0x6B, 0x72, 0x7C, 0x12, 0x51, 0x8D, 0x8E } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBaseSaveThrowTable2Provider[] = {
+ { UNK_LANG, kPlatformUnknown, { 0x00000019, 0x000000E7, { { 0xF4, 0x0D, 0xDF, 0xA3, 0x23, 0x71, 0x76, 0x2A, 0xC5, 0x6F, 0xF1, 0x59, 0x5F, 0x45, 0x73, 0x05 } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBaseSaveThrowTable3Provider[] = {
+ { UNK_LANG, kPlatformUnknown, { 0x00000023, 0x00000155, { { 0x42, 0x98, 0x84, 0x00, 0x70, 0x8A, 0x7B, 0x26, 0xC0, 0x96, 0xA3, 0x28, 0x41, 0x36, 0x4B, 0x21 } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBaseSaveThrowTable4Provider[] = {
+ { UNK_LANG, kPlatformUnknown, { 0x0000001E, 0x0000013B, { { 0xAB, 0x84, 0x2B, 0x0A, 0xC2, 0x46, 0xFF, 0x83, 0x03, 0xF8, 0x3F, 0x32, 0x53, 0xA2, 0x95, 0x65 } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBaseSaveThrwLvlIndexProvider[] = {
+ { UNK_LANG, kPlatformUnknown, { 0x00000006, 0x00000070, { { 0x57, 0x48, 0x5F, 0x75, 0x79, 0xD4, 0xAA, 0x7D, 0xB7, 0xEB, 0x19, 0x9F, 0xCF, 0x99, 0x29, 0x29 } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBaseSaveThrwModDivProvider[] = {
+ { UNK_LANG, kPlatformUnknown, { 0x00000006, 0x00000012, { { 0x50, 0x29, 0x51, 0x65, 0x0B, 0xF1, 0xCC, 0xDA, 0x2C, 0xA4, 0x7E, 0xEE, 0x20, 0xB0, 0x29, 0xB1 } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBaseSaveThrwModExtProvider[] = {
+ { UNK_LANG, kPlatformUnknown, { 0x00000006, 0x00000030, { { 0x07, 0x7D, 0x61, 0x1C, 0x95, 0xEC, 0x9A, 0xCE, 0xA1, 0x29, 0x83, 0x2F, 0xCA, 0x95, 0x95, 0xF5 } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBasePryDoorStringsProvider[] = {
+ { EN_ANY, kPlatformUnknown, { 0x000000E8, 0x00004D9F, { { 0xDE, 0x01, 0x69, 0x00, 0x0B, 0x32, 0xFA, 0x20, 0xB8, 0x11, 0xD6, 0xD9, 0xE2, 0xEA, 0xF5, 0xE8 } } } }, // EOB 1
+ { EN_ANY, kPlatformUnknown, { 0x000000D2, 0x000043D2, { { 0x82, 0x3C, 0xF4, 0x4A, 0x87, 0x84, 0xFE, 0xF9, 0xBA, 0xC6, 0x67, 0x3A, 0x0D, 0x0F, 0x76, 0x78 } } } }, // EOB 2
+ { DE_DEU, kPlatformUnknown, { 0x00000128, 0x0000657C, { { 0xA3, 0xC8, 0x48, 0xA7, 0x1F, 0x75, 0xDF, 0xB0, 0x37, 0xDA, 0x75, 0x2E, 0x9F, 0x4E, 0x45, 0xB0 } } } }, // EOB 1
+ { DE_DEU, kPlatformUnknown, { 0x000000D9, 0x00004769, { { 0x24, 0x59, 0x00, 0x8F, 0x9A, 0x3E, 0x95, 0xAB, 0x14, 0x9A, 0x3B, 0x19, 0x34, 0xDB, 0x9B, 0x18 } } } }, // EOB 2
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBaseWarningStringsProvider[] = {
+ { EN_ANY, kPlatformUnknown, { 0x00000052, 0x00001A7B, { { 0x81, 0x7A, 0xDF, 0xD2, 0x4F, 0xA7, 0x92, 0xA7, 0x44, 0xE5, 0x22, 0x73, 0xF6, 0xB3, 0x29, 0x5C } } } }, // EOB 1
+ { EN_ANY, kPlatformUnknown, { 0x00000085, 0x00002B5C, { { 0xF1, 0xCE, 0x7C, 0x53, 0xEF, 0x5B, 0x59, 0x71, 0xA9, 0xEB, 0x00, 0xBA, 0xB7, 0x59, 0xC5, 0x2E } } } }, // EOB 2
+ { DE_DEU, kPlatformUnknown, { 0x0000005F, 0x00001FD2, { { 0xBA, 0x85, 0x97, 0x63, 0x84, 0x80, 0x79, 0x44, 0x50, 0x99, 0x1A, 0x01, 0x37, 0x37, 0x0E, 0xD1 } } } }, // EOB 1
+ { DE_DEU, kPlatformUnknown, { 0x00000096, 0x000032BF, { { 0x07, 0x95, 0x91, 0x1A, 0x1B, 0xC8, 0xA3, 0xEE, 0x76, 0x0A, 0x48, 0x11, 0x37, 0x6F, 0xBA, 0x05 } } } }, // EOB 1
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBaseItemSuffixStringsRingsProvider[] = {
+ { EN_ANY, kPlatformUnknown, { 0x0000002B, 0x00000F7B, { { 0x8A, 0x27, 0x87, 0x81, 0x5F, 0x74, 0x27, 0xA9, 0x5E, 0x1B, 0xEE, 0xC0, 0xF7, 0x22, 0x8F, 0x57 } } } },
+ { DE_DEU, kPlatformUnknown, { 0x00000022, 0x00000C02, { { 0x7D, 0x5F, 0x40, 0xEA, 0xAD, 0xDD, 0x1B, 0xA0, 0xA6, 0xE0, 0x57, 0x7D, 0x0D, 0x60, 0xF4, 0x2C } } } }, // EOB 1
+ { DE_DEU, kPlatformUnknown, { 0x0000002E, 0x00000FF2, { { 0xE1, 0x50, 0xB7, 0xE2, 0xEF, 0xAD, 0x5B, 0x6D, 0x27, 0x35, 0x9C, 0xE7, 0x2D, 0xB2, 0x2E, 0xD0 } } } }, // EOB 2
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBaseItemSuffixStringsPotionsProvider[] = {
+ { EN_ANY, kPlatformUnknown, { 0x00000054, 0x00001DDB, { { 0xB6, 0x78, 0xD9, 0x09, 0x1D, 0x09, 0x63, 0xF8, 0x96, 0x74, 0xF0, 0x75, 0x23, 0xF5, 0xD4, 0xC4 } } } },
+ { DE_DEU, kPlatformUnknown, { 0x00000064, 0x000024ED, { { 0x10, 0x5A, 0xB8, 0xCA, 0x0F, 0x0D, 0x44, 0x19, 0x9D, 0x3D, 0x76, 0x54, 0xA1, 0x69, 0x97, 0x8B } } } }, // EOB 1
+ { DE_DEU, kPlatformUnknown, { 0x0000006F, 0x00002792, { { 0x1A, 0x71, 0x2B, 0xCC, 0xCA, 0xDA, 0xF6, 0xED, 0x5E, 0xF0, 0x24, 0x20, 0xD7, 0x2D, 0x18, 0x49 } } } }, // EOB 2
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBaseItemSuffixStringsWandsProvider[] = {
+ { EN_ANY, kPlatformUnknown, { 0x0000003C, 0x000014EB, { { 0xB5, 0x38, 0x35, 0x57, 0xF2, 0xF8, 0x0E, 0xBA, 0x75, 0x03, 0x1C, 0xCD, 0x46, 0x7D, 0x03, 0x83 } } } }, // EOB 1
+ { EN_ANY, kPlatformUnknown, { 0x0000004A, 0x000019B2, { { 0x44, 0x10, 0xE4, 0xAF, 0xAB, 0x19, 0x25, 0x87, 0x2B, 0x15, 0x1C, 0x4C, 0x03, 0x50, 0x41, 0xC4 } } } }, // EOB 2
+ { DE_DEU, kPlatformUnknown, { 0x00000040, 0x000016B5, { { 0xEC, 0xF4, 0x71, 0xC1, 0x69, 0x5C, 0xF9, 0xC1, 0xED, 0xC1, 0xED, 0x0C, 0x25, 0x3E, 0x13, 0xB1 } } } }, // EOB 1
+ { DE_DEU, kPlatformUnknown, { 0x00000069, 0x0000252B, { { 0x12, 0x06, 0xEA, 0x2F, 0xAF, 0x47, 0x55, 0x52, 0xB6, 0xD9, 0x11, 0xA4, 0x4F, 0x30, 0xCE, 0x9D } } } }, // EOB 2
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBaseRipItemStringsProvider[] = {
+ { EN_ANY, kPlatformUnknown, { 0x00000025, 0x00000AEA, { { 0x7A, 0x2D, 0x03, 0xA5, 0x94, 0xD1, 0xA2, 0x2C, 0x41, 0x1F, 0xEB, 0x5C, 0xFB, 0xB2, 0xC6, 0x9E } } } },
+ { DE_DEU, kPlatformUnknown, { 0x00000024, 0x00000B1B, { { 0xD0, 0x26, 0x19, 0x0B, 0xA5, 0x8A, 0x38, 0x73, 0x14, 0x25, 0x40, 0x5D, 0x24, 0xB8, 0x4E, 0xC5 } } } }, // EOB 1
+ { DE_DEU, kPlatformUnknown, { 0x0000002E, 0x00000D38, { { 0xCE, 0xC5, 0x00, 0x63, 0xBB, 0xF0, 0xC4, 0x0D, 0x50, 0x2B, 0x82, 0x1C, 0xC0, 0xCD, 0xF1, 0xAF } } } }, // EOB 2
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBaseCursedStringProvider[] = {
+ { EN_ANY, kPlatformUnknown, { 0x0000000D, 0x000003C7, { { 0x7F, 0x6B, 0x6A, 0xFE, 0x63, 0xF4, 0x17, 0xAF, 0xFD, 0x00, 0x31, 0x4A, 0x20, 0x9E, 0x8C, 0xEB } } } }, // EOB 1
+ { EN_ANY, kPlatformUnknown, { 0x0000000D, 0x000003C7, { { 0x59, 0xD8, 0x84, 0x25, 0xE0, 0x06, 0x51, 0xA4, 0x70, 0xC5, 0x78, 0x22, 0xF0, 0x2D, 0xA0, 0x43 } } } }, // EOB 2
+ { DE_DEU, kPlatformUnknown, { 0x00000010, 0x00000514, { { 0x97, 0x41, 0xA6, 0xAE, 0xF8, 0xA8, 0x3E, 0x85, 0xA8, 0x16, 0x01, 0x15, 0x0E, 0x46, 0x13, 0x45 } } } }, // EOB 1
+ { DE_DEU, kPlatformUnknown, { 0x00000013, 0x000005A5, { { 0xEC, 0xD3, 0xA5, 0xD2, 0xAD, 0x7C, 0x5E, 0x0F, 0x42, 0xBC, 0x6E, 0xDE, 0x7E, 0x36, 0x0B, 0x43 } } } }, // EOB 2
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBaseEnchantedStringProvider[] = {
+ { UNK_LANG, kPlatformUnknown, { 0x00000007, 0x0000016C, { { 0x98, 0x62, 0xD3, 0xA3, 0x11, 0xAE, 0x0A, 0xBA, 0x8F, 0xE8, 0x30, 0x0B, 0xDC, 0x12, 0x90, 0x3B } } } }, // EOB 1
+ { UNK_LANG, kPlatformUnknown, { 0x00000007, 0x0000016C, { { 0x01, 0x91, 0xBD, 0x89, 0xAE, 0x0E, 0x71, 0xEE, 0xBE, 0x31, 0xD9, 0x55, 0x21, 0x61, 0x19, 0xAE } } } }, // EOB 2
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBaseMagicObjectStringsProvider[] = {
+ { EN_ANY, kPlatformUnknown, { 0x0000002B, 0x00000E7D, { { 0x7E, 0x8F, 0x17, 0xEB, 0xE5, 0x5D, 0xEB, 0x9A, 0x84, 0xFF, 0x86, 0x6A, 0x01, 0x3E, 0x04, 0x84 } } } },
+ { DE_DEU, kPlatformUnknown, { 0x0000003A, 0x000014E4, { { 0x3D, 0x34, 0x3C, 0xCA, 0xDC, 0xD1, 0xCF, 0x15, 0x69, 0x57, 0xC3, 0xB1, 0x58, 0xDF, 0xE9, 0x9D } } } }, // EOB 1
+ { DE_DEU, kPlatformUnknown, { 0x0000002A, 0x00000EE4, { { 0x9C, 0x38, 0x4B, 0x9B, 0x67, 0x30, 0x4E, 0x88, 0xA9, 0xA2, 0xF8, 0x78, 0x8E, 0xC7, 0xC3, 0x86 } } } }, // EOB 2
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBaseMagicObject5StringProvider[] = {
+ { EN_ANY, kPlatformUnknown, { 0x00000006, 0x000001FE, { { 0x74, 0x8D, 0xB9, 0x76, 0xD2, 0x2F, 0x60, 0xD2, 0x36, 0x45, 0x98, 0x4C, 0x0A, 0xE5, 0xE5, 0x0D } } } },
+ { DE_DEU, kPlatformUnknown, { 0x00000006, 0x00000204, { { 0xE4, 0xC1, 0xAD, 0x71, 0x87, 0x80, 0x9D, 0x97, 0x91, 0x80, 0x3F, 0x71, 0xD3, 0x62, 0x06, 0xD5 } } } }, // EOB 1
+ { DE_DEU, kPlatformUnknown, { 0x00000007, 0x0000027A, { { 0x44, 0x47, 0x79, 0x46, 0x9B, 0xE5, 0xBD, 0x3C, 0xE8, 0x8D, 0xC6, 0xC5, 0x4E, 0x88, 0x13, 0xC0 } } } }, // EOB 2
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBasePatternSuffixProvider[] = {
+ { EN_ANY, kPlatformUnknown, { 0x00000009, 0x00000245, { { 0x67, 0x3F, 0x33, 0xA5, 0x3B, 0x5D, 0x2C, 0x9E, 0x15, 0x82, 0x04, 0xE2, 0xD7, 0x34, 0x42, 0x24 } } } },
+ { DE_DEU, kPlatformUnknown, { 0x00000006, 0x0000015D, { { 0x33, 0xD6, 0x91, 0x2D, 0xED, 0xE1, 0x43, 0x42, 0x23, 0xB9, 0xE9, 0x3D, 0x48, 0x82, 0x92, 0x1E } } } }, // EOB 1
+ { DE_DEU, kPlatformUnknown, { 0x00000008, 0x00000219, { { 0xCD, 0xDC, 0x7F, 0x8B, 0xBE, 0xD6, 0x05, 0x37, 0xDA, 0xDC, 0x11, 0xC3, 0x1E, 0x7A, 0xE7, 0x13 } } } }, // EOB 2
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBasePatternGrFix1Provider[] = {
+ { EN_ANY, kPlatformUnknown, { 0x00000009, 0x00000245, { { 0x67, 0x3F, 0x33, 0xA5, 0x3B, 0x5D, 0x2C, 0x9E, 0x15, 0x82, 0x04, 0xE2, 0xD7, 0x34, 0x42, 0x24 } } } },
+ { DE_DEU, kPlatformUnknown, { 0x00000006, 0x0000015D, { { 0x33, 0xD6, 0x91, 0x2D, 0xED, 0xE1, 0x43, 0x42, 0x23, 0xB9, 0xE9, 0x3D, 0x48, 0x82, 0x92, 0x1E } } } }, // EOB 1
+ { DE_DEU, kPlatformUnknown, { 0x00000007, 0x0000018A, { { 0x02, 0x5C, 0x86, 0xD9, 0x62, 0x0C, 0x71, 0xB3, 0x77, 0x9C, 0x7B, 0xBC, 0x4D, 0x5B, 0xDB, 0xE7 } } } }, // EOB 2
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBasePatternGrFix2Provider[] = {
+ { EN_ANY, kPlatformUnknown, { 0x00000009, 0x00000245, { { 0x67, 0x3F, 0x33, 0xA5, 0x3B, 0x5D, 0x2C, 0x9E, 0x15, 0x82, 0x04, 0xE2, 0xD7, 0x34, 0x42, 0x24 } } } },
+ { DE_DEU, kPlatformUnknown, { 0x00000006, 0x0000015D, { { 0x33, 0xD6, 0x91, 0x2D, 0xED, 0xE1, 0x43, 0x42, 0x23, 0xB9, 0xE9, 0x3D, 0x48, 0x82, 0x92, 0x1E } } } }, // EOB 1
+ { DE_DEU, kPlatformUnknown, { 0x00000006, 0x00000150, { { 0x48, 0xBE, 0xED, 0xD3, 0xA5, 0x2E, 0xCD, 0xE0, 0x34, 0xBA, 0xA6, 0x8D, 0x7D, 0x00, 0xA2, 0xFF } } } }, // EOB 2
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBaseValidateArmorStringProvider[] = {
+ { EN_ANY, kPlatformUnknown, { 0x00000023, 0x00000B78, { { 0xC2, 0x33, 0x6B, 0xB9, 0xE1, 0x5E, 0x88, 0x5E, 0x22, 0xF2, 0x97, 0x83, 0xF8, 0xC8, 0x8C, 0xAB } } } },
+ { DE_DEU, kPlatformUnknown, { 0x00000026, 0x00000D19, { { 0xAD, 0x19, 0xE2, 0xDE, 0x04, 0xF9, 0x8F, 0x92, 0xAC, 0x1A, 0x05, 0xEA, 0x7B, 0xB5, 0x9F, 0x09 } } } }, // EOB 1
+ { DE_DEU, kPlatformUnknown, { 0x00000029, 0x00000E7A, { { 0xEC, 0xA8, 0x2E, 0x8D, 0xB1, 0xC8, 0x0F, 0xCD, 0x24, 0xBD, 0x4B, 0x39, 0x16, 0xC9, 0x53, 0x08 } } } }, // EOB 2
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBaseValidateCursedStringProvider[] = {
+ { EN_ANY, kPlatformUnknown, { 0x0000002E, 0x00000F35, { { 0xE7, 0x0E, 0xA1, 0xCE, 0xCC, 0x13, 0xBC, 0x4B, 0x2B, 0x19, 0xEB, 0xA4, 0x05, 0xCF, 0xCF, 0x65 } } } },
+ { DE_DEU, kPlatformUnknown, { 0x00000037, 0x000012D8, { { 0x3C, 0x7F, 0x16, 0xCE, 0x40, 0x58, 0xF1, 0x3A, 0xAB, 0x4C, 0x37, 0x82, 0x32, 0x88, 0xA4, 0x2D } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBaseValidateNoDropStringProvider[] = {
+ { EN_ANY, kPlatformUnknown, { 0x0000001F, 0x00000A8F, { { 0x61, 0x99, 0x3E, 0x36, 0x49, 0x19, 0xB4, 0xE4, 0xBC, 0xFA, 0xB5, 0x71, 0x0E, 0xD6, 0x15, 0x3C } } } }, // EOB 1
+ { EN_ANY, kPlatformUnknown, { 0x00000020, 0x00000AB6, { { 0xAA, 0x0E, 0x64, 0xD1, 0xA2, 0xA6, 0x62, 0x76, 0x51, 0xDF, 0x9E, 0x76, 0x85, 0x42, 0xE1, 0x4A } } } }, // EOB 2
+ { DE_DEU, kPlatformUnknown, { 0x00000024, 0x00000C31, { { 0x10, 0xD9, 0x55, 0x69, 0xFE, 0x0A, 0x8C, 0xE5, 0xF7, 0x05, 0x5F, 0x09, 0x3B, 0xC9, 0x93, 0x38 } } } }, // EOB 1
+ { DE_DEU, kPlatformUnknown, { 0x00000027, 0x00000D9F, { { 0xA5, 0xF0, 0x8E, 0x78, 0x0A, 0x37, 0x31, 0xDC, 0xE0, 0xDF, 0xE5, 0xCB, 0x86, 0xDC, 0x21, 0x73 } } } }, // EOB 2
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBasePotionStringsProvider[] = {
+ { EN_ANY, kPlatformUnknown, { 0x00000017, 0x0000070E, { { 0xD9, 0xCB, 0x26, 0xB6, 0x6F, 0x17, 0x12, 0xB7, 0xB0, 0x95, 0x1B, 0x2A, 0xD8, 0x83, 0x0D, 0x2B } } } },
+ { DE_DEU, kPlatformUnknown, { 0x0000001E, 0x000009BD, { { 0xCA, 0xD0, 0x29, 0xB0, 0x7A, 0x2B, 0x0B, 0x69, 0xCA, 0xA4, 0xCA, 0x97, 0xCF, 0x8B, 0x03, 0xAD } } } }, // EOB 1
+ { DE_DEU, kPlatformUnknown, { 0x0000001D, 0x00000964, { { 0x5D, 0xE2, 0xA5, 0x0D, 0x72, 0xE9, 0x8F, 0xC9, 0xFA, 0xF3, 0x41, 0x5A, 0x3F, 0x33, 0xAA, 0x15 } } } }, // EOB 2
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBaseWandStringProvider[] = {
+ { EN_ANY, kPlatformUnknown, { 0x00000035, 0x000011EC, { { 0x7C, 0x3D, 0xF1, 0x28, 0x0C, 0x23, 0xD3, 0x18, 0xEE, 0xAD, 0xA7, 0xF4, 0x58, 0xD7, 0x1C, 0x8E } } } }, // EOB 1
+ { EN_ANY, kPlatformUnknown, { 0x00000029, 0x00000E47, { { 0xED, 0x2E, 0xD4, 0x4D, 0xDB, 0x90, 0x3F, 0xD0, 0xFB, 0x95, 0xB8, 0xF2, 0xCF, 0x06, 0x08, 0xAF } } } }, // EOB 2
+ { DE_DEU, kPlatformUnknown, { 0x00000046, 0x0000186E, { { 0x54, 0x8F, 0x53, 0x34, 0xE8, 0x81, 0x76, 0x71, 0x53, 0x3F, 0x99, 0xE7, 0xCF, 0xB7, 0xC9, 0xD9 } } } }, // EOB 1
+ { DE_DEU, kPlatformUnknown, { 0x0000002F, 0x00001070, { { 0x86, 0x18, 0x00, 0x54, 0x05, 0x3D, 0xC2, 0x26, 0xA7, 0xD9, 0x68, 0xE6, 0xC2, 0x0D, 0x26, 0x99 } } } }, // EOB 2
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBaseItemMisuseStringsProvider[] = {
+ { EN_ANY, kPlatformUnknown, { 0x00000066, 0x000022F6, { { 0xE8, 0xB9, 0x07, 0x61, 0x29, 0x90, 0xB0, 0x22, 0x30, 0xC5, 0x0F, 0xAD, 0xCA, 0x6C, 0x83, 0xC6 } } } },
+ { DE_DEU, kPlatformUnknown, { 0x00000068, 0x00002472, { { 0xCA, 0xD7, 0xFD, 0x5B, 0x65, 0x72, 0xC7, 0x15, 0xB3, 0xFE, 0xFC, 0xEF, 0x53, 0xFB, 0x57, 0x6C } } } }, // EOB 1
+ { DE_DEU, kPlatformUnknown, { 0x0000007E, 0x00002C87, { { 0x5E, 0x11, 0xC9, 0x93, 0xF4, 0xAB, 0x1A, 0x9D, 0xA7, 0x62, 0x71, 0x94, 0x37, 0xCA, 0xE2, 0x25 } } } }, // EOB 2
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBaseTakenStringsProvider[] = {
+ { EN_ANY, kPlatformUnknown, { 0x00000009, 0x0000026E, { { 0x3B, 0x73, 0x70, 0x2E, 0x22, 0x90, 0x0D, 0xC1, 0xDE, 0x32, 0x11, 0xCC, 0x97, 0xBA, 0xA3, 0x58 } } } },
+ { DE_DEU, kPlatformUnknown, { 0x0000000F, 0x000004ED, { { 0x8D, 0x12, 0x1E, 0x91, 0xD3, 0xF4, 0x34, 0x15, 0xC7, 0x4F, 0xE7, 0x23, 0x5B, 0xE8, 0x66, 0xB7 } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBasePotionEffectStringsProvider[] = {
+ { EN_ANY, kPlatformUnknown, { 0x00000065, 0x0000248F, { { 0x4F, 0x60, 0x7F, 0xA7, 0x6F, 0x81, 0xD4, 0xAA, 0x68, 0xD5, 0xAA, 0xBE, 0xBC, 0xD4, 0x92, 0x3A } } } }, // EOB 1
+ { EN_ANY, kPlatformUnknown, { 0x0000005D, 0x0000219D, { { 0x87, 0x60, 0x9F, 0xF3, 0x1B, 0x30, 0x4B, 0x2B, 0xE4, 0x94, 0xEF, 0x22, 0xEA, 0x36, 0xE4, 0x7F } } } }, // EOB 2
+ { DE_DEU, kPlatformUnknown, { 0x0000006E, 0x00002840, { { 0x04, 0xF8, 0x53, 0x38, 0x09, 0xD8, 0x58, 0xFC, 0x5F, 0xE9, 0x69, 0xFB, 0x9C, 0x0D, 0x92, 0x2E } } } }, // EOB 1
+ { DE_DEU, kPlatformUnknown, { 0x00000059, 0x000020D2, { { 0xB6, 0xA1, 0x57, 0xD6, 0x46, 0xE3, 0xCF, 0x04, 0x5A, 0xC8, 0xBB, 0x59, 0x8D, 0xE3, 0x6F, 0xBF } } } }, // EOB 2
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBaseYesNoStringsProvider[] = {
+ { EN_ANY, kPlatformUnknown, { 0x00000007, 0x0000022E, { { 0xF1, 0x30, 0x61, 0xA7, 0x20, 0x71, 0x3B, 0x75, 0xBE, 0xA7, 0xD6, 0x78, 0x34, 0xF7, 0x19, 0x06 } } } },
+ { DE_DEU, kPlatformUnknown, { 0x00000008, 0x00000275, { { 0xAF, 0x3E, 0xC5, 0x5A, 0x60, 0x34, 0x9B, 0x39, 0x37, 0x9E, 0xE2, 0x17, 0x23, 0x8E, 0x23, 0x23 } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kRpgCommonMoreStringsProvider[] = {
+ { EN_ANY, kPlatformUnknown, { 0x00000005, 0x00000133, { { 0xA6, 0x1A, 0x3A, 0xB8, 0xCC, 0x92, 0xB8, 0xBE, 0x28, 0xD6, 0x64, 0x8F, 0x0A, 0x2A, 0x39, 0xCD } } } },
+ { DE_DEU, kPlatformUnknown, { 0x00000005, 0x0000012C, { { 0x82, 0x30, 0x00, 0xD6, 0xFA, 0x53, 0x17, 0x69, 0x64, 0xCA, 0xFE, 0x0F, 0x92, 0xEF, 0x87, 0x7A } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBaseNpcMaxStringsProvider[] = {
+ { EN_ANY, kPlatformUnknown, { 0x00000052, 0x00001D23, { { 0x95, 0xB0, 0xBF, 0xF9, 0xE6, 0x8C, 0xCF, 0x9B, 0x36, 0xE3, 0x81, 0x22, 0x1E, 0x68, 0x9E, 0xBE } } } },
+ { DE_DEU, kPlatformUnknown, { 0x00000064, 0x00002341, { { 0xC0, 0xA6, 0xCD, 0x5E, 0x8E, 0xFA, 0x89, 0xE4, 0x98, 0xE5, 0x3D, 0x13, 0x6B, 0xE7, 0x8F, 0x6E } } } }, // EoB 1
+ { DE_DEU, kPlatformUnknown, { 0x0000003E, 0x00001613, { { 0x4E, 0x31, 0x7F, 0xC4, 0xC7, 0x9C, 0xB5, 0x7D, 0x36, 0x85, 0xD8, 0x81, 0xE2, 0x06, 0xF9, 0xAE } } } }, // EoB 2
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBaseOkStringsProvider[] = {
+ { EN_ANY, kPlatformUnknown, { 0x00000003, 0x0000009A, { { 0x88, 0xD2, 0x76, 0x1C, 0x80, 0x02, 0xC5, 0x5B, 0x35, 0x57, 0x0E, 0xEB, 0xCA, 0xD6, 0xC9, 0x2E } } } },
+ { DE_DEU, kPlatformUnknown, { 0x00000003, 0x0000009A, { { 0x88, 0xD2, 0x76, 0x1C, 0x80, 0x02, 0xC5, 0x5B, 0x35, 0x57, 0x0E, 0xEB, 0xCA, 0xD6, 0xC9, 0x2E } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBaseNpcJoinStringsProvider[] = {
+ { EN_ANY, kPlatformUnknown, { 0x00000015, 0x000006C7, { { 0x5A, 0xBF, 0xA2, 0x3E, 0x36, 0xC4, 0x23, 0xC8, 0xA8, 0x86, 0x06, 0x80, 0xAF, 0xB1, 0xDD, 0xAB } } } },
+ { DE_DEU, kPlatformUnknown, { 0x00000020, 0x00000A93, { { 0x4A, 0xFD, 0x70, 0xB7, 0x7A, 0x0B, 0x7C, 0x32, 0x07, 0x5A, 0x4A, 0xC7, 0x84, 0x9D, 0x2D, 0xF3 } } } }, // EoB 1
+ { DE_DEU, kPlatformUnknown, { 0x00000018, 0x00000848, { { 0xC9, 0xEE, 0x71, 0x04, 0xA2, 0xA5, 0x52, 0x87, 0x7C, 0x6D, 0x3C, 0x15, 0x7D, 0x41, 0xE0, 0xE7 } } } }, // EoB 2
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBaseCancelStringsProvider[] = {
+ { EN_ANY, kPlatformUnknown, { 0x00000007, 0x000001A6, { { 0x21, 0xED, 0xF9, 0x71, 0xEF, 0x74, 0xD7, 0x9E, 0xF3, 0x02, 0xE5, 0x03, 0x06, 0xDE, 0xD5, 0x09 } } } },
+ { DE_DEU, kPlatformUnknown, { 0x0000000A, 0x0000027A, { { 0xBD, 0x88, 0xB2, 0xA0, 0xAF, 0x8D, 0xFE, 0x5B, 0xAC, 0xDF, 0xB5, 0x9F, 0xA0, 0x23, 0x6E, 0xAE } } } }, // EoB 1
+ { DE_DEU, kPlatformUnknown, { 0x00000006, 0x00000145, { { 0x22, 0x45, 0x35, 0xC6, 0x28, 0x00, 0x22, 0xAA, 0xD1, 0x15, 0x48, 0xE6, 0xE5, 0x62, 0x73, 0x37 } } } }, // EoB 2
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBaseAbortStringsProvider[] = {
+ { EN_ANY, kPlatformUnknown, { 0x00000006, 0x00000178, { { 0xDD, 0xEC, 0x68, 0x6D, 0x2E, 0x10, 0x34, 0x94, 0x46, 0x25, 0xF9, 0xAB, 0x29, 0x27, 0x32, 0xA8 } } } },
+ { DE_DEU, kPlatformUnknown, { 0x00000006, 0x00000145, { { 0x22, 0x45, 0x35, 0xC6, 0x28, 0x00, 0x22, 0xAA, 0xD1, 0x15, 0x48, 0xE6, 0xE5, 0x62, 0x73, 0x37 } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBaseMenuStringsMainProvider[] = {
+ { EN_ANY, kPlatformUnknown, { 0x00000067, 0x0000245E, { { 0xD9, 0xE0, 0x74, 0x9D, 0x43, 0x96, 0xDC, 0x3B, 0xDF, 0x90, 0x03, 0xDE, 0x91, 0xE6, 0xA0, 0x1E } } } }, // EOB1
+ { DE_DEU, kPlatformUnknown, { 0x00000068, 0x000025D9, { { 0x17, 0xEB, 0xAB, 0x4F, 0x95, 0xD1, 0x7F, 0xEB, 0xF4, 0x92, 0x42, 0xD1, 0xD2, 0xA8, 0xC4, 0xA8 } } } }, // EOB1
+ { DE_DEU, kPlatformUnknown, { 0x00000069, 0x0000265B, { { 0x4C, 0xA9, 0x38, 0x28, 0xE1, 0xD0, 0xE3, 0x35, 0xBB, 0xDC, 0xFB, 0x6B, 0xAB, 0xB1, 0x62, 0x88 } } } }, // EOB2
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBaseMenuStringsSaveLoadProvider[] = {
+ { EN_ANY, kPlatformUnknown, { 0x00000077, 0x00002513, { { 0x70, 0xD9, 0x48, 0xC2, 0x3A, 0x38, 0x1D, 0xD0, 0x8B, 0x90, 0x08, 0x8D, 0x80, 0xF5, 0x24, 0x59 } } } }, // EOB1
+ { DE_DEU, kPlatformUnknown, { 0x00000086, 0x00002D2F, { { 0x2B, 0x48, 0x5C, 0x78, 0xF9, 0xB9, 0xD6, 0xA8, 0x1D, 0xF4, 0x97, 0xAC, 0xF1, 0x09, 0x26, 0xA7 } } } }, // EOB1
+ { EN_ANY, kPlatformUnknown, { 0x000000A9, 0x00003850, { { 0xC3, 0x09, 0x7B, 0x18, 0xD6, 0x08, 0x0E, 0x2A, 0xB6, 0x66, 0x43, 0x14, 0xD7, 0x59, 0x34, 0xF7 } } } }, // EOB2
+ { DE_DEU, kPlatformUnknown, { 0x000000A2, 0x00003942, { { 0x6E, 0x10, 0x87, 0x4B, 0x80, 0xE8, 0x89, 0xC4, 0x31, 0xDC, 0xAC, 0xA9, 0xA3, 0x8D, 0x79, 0x41 } } } }, // EOB2
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBaseMenuStringsOnOffProvider[] = {
+ { EN_ANY, kPlatformUnknown, { 0x00000007, 0x00000178, { { 0x4D, 0xA7, 0x13, 0x00, 0x05, 0xF2, 0x44, 0xCB, 0xF7, 0x12, 0x72, 0x54, 0xDE, 0x35, 0x04, 0xEC } } } }, // EOB1
+ { DE_DEU, kPlatformUnknown, { 0x00000007, 0x00000178, { { 0xC7, 0x6F, 0x60, 0x72, 0x47, 0x89, 0x47, 0xF0, 0x29, 0x57, 0x45, 0x41, 0xD5, 0x80, 0x40, 0x7B } } } }, // EOB2
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBaseMenuStringsSpellsProvider[] = {
+ { EN_ANY, kPlatformUnknown, { 0x000001EF, 0x0000A0D0, { { 0xBA, 0x80, 0x5C, 0xAB, 0x93, 0x19, 0x53, 0x45, 0x17, 0xBC, 0x86, 0x5B, 0x1B, 0x01, 0x3E, 0x98 } } } }, // EOB1
+ { DE_DEU, kPlatformUnknown, { 0x000001EA, 0x00009DE0, { { 0x00, 0xB0, 0x1F, 0xE7, 0x16, 0x48, 0x51, 0x25, 0xE5, 0xD8, 0xA1, 0x31, 0x13, 0x81, 0x8D, 0xB6 } } } }, // EOB1
+ { EN_ANY, kPlatformUnknown, { 0x000001FB, 0x0000A658, { { 0xAD, 0x6A, 0xFE, 0x13, 0xE5, 0xEA, 0x6A, 0xD1, 0xC9, 0x80, 0x1C, 0xEE, 0xD7, 0x2A, 0xF8, 0xB2 } } } }, // EOB2
+ { DE_DEU, kPlatformUnknown, { 0x00000222, 0x0000B1C9, { { 0x24, 0xC8, 0x9B, 0x51, 0xEE, 0x45, 0x14, 0xFC, 0x1B, 0xE4, 0x37, 0x8B, 0xEC, 0x94, 0xD9, 0x0B } } } }, // EOB2
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBaseMenuStringsRestProvider[] = {
+ { EN_ANY, kPlatformUnknown, { 0x000000B3, 0x00003CED, { { 0x82, 0xF9, 0xA1, 0x74, 0xE6, 0x95, 0xA4, 0xFC, 0xE6, 0x5E, 0xB4, 0x43, 0x7D, 0x10, 0xFD, 0x12 } } } }, // EOB1
+ { DE_DEU, kPlatformUnknown, { 0x000000B3, 0x00003BE4, { { 0x7F, 0xE8, 0xFE, 0xA4, 0xD9, 0x5C, 0x49, 0x66, 0x38, 0x8F, 0x84, 0xB8, 0xF5, 0x03, 0xCD, 0x70 } } } }, // EOB
+ { DE_DEU, kPlatformUnknown, { 0x000000C0, 0x000040A6, { { 0x05, 0x97, 0x45, 0x72, 0xE2, 0x33, 0xBE, 0xDE, 0x56, 0x26, 0x26, 0x15, 0x3A, 0x56, 0x93, 0xFD } } } }, // EOB2
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBaseMenuStringsDropProvider[] = {
+ { EN_ANY, kPlatformUnknown, { 0x0000002E, 0x00000FCA, { { 0x88, 0xCB, 0xD2, 0xB3, 0xDA, 0x36, 0x97, 0x3D, 0xB8, 0x75, 0xFF, 0x36, 0xE1, 0x4E, 0xF4, 0x6D } } } }, // EOB1
+ { DE_DEU, kPlatformUnknown, { 0x00000039, 0x0000131E, { { 0x74, 0x0B, 0xE9, 0x04, 0x76, 0x26, 0xD2, 0xE8, 0x03, 0x48, 0x38, 0x18, 0xAC, 0x19, 0xBD, 0x7E } } } }, // EOB1
+ { DE_DEU, kPlatformUnknown, { 0x00000033, 0x0000119C, { { 0x8F, 0x2B, 0xC3, 0x01, 0xB2, 0xDE, 0x1F, 0xC6, 0x82, 0xC3, 0x58, 0x7C, 0x50, 0x23, 0x37, 0x65 } } } }, // EOB2
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBaseMenuStringsExitProvider[] = {
+ { EN_ANY, kPlatformUnknown, { 0x0000002B, 0x00000E3D, { { 0x1C, 0xD6, 0x39, 0xA9, 0xC7, 0x3D, 0x32, 0x4A, 0xF2, 0xAE, 0xEC, 0x08, 0x6F, 0xC7, 0xA6, 0x7B } } } }, // EOB1
+ { DE_DEU, kPlatformUnknown, { 0x0000002D, 0x00000E68, { { 0x4B, 0x2F, 0x65, 0x39, 0x69, 0xE7, 0x3D, 0x7B, 0x10, 0x15, 0x6F, 0x1F, 0xD8, 0x8E, 0xEA, 0x55 } } } }, // EOB1
+ { DE_DEU, kPlatformUnknown, { 0x00000026, 0x00000CBD, { { 0x0C, 0x5D, 0xE4, 0xD2, 0x6F, 0xA3, 0x91, 0xDA, 0x5F, 0xE2, 0x57, 0x77, 0x74, 0x22, 0xE7, 0x85 } } } }, // EOB2
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBaseMenuStringsStarveProvider[] = {
+ { EN_ANY, kPlatformUnknown, { 0x0000003D, 0x0000150C, { { 0x40, 0xEB, 0x79, 0xC3, 0x99, 0x4C, 0xEA, 0xCD, 0x8A, 0xB4, 0x54, 0xB8, 0xAA, 0xEC, 0xAD, 0x4F } } } }, // EOB1
+ { DE_DEU, kPlatformUnknown, { 0x00000037, 0x00001296, { { 0x51, 0x3C, 0x90, 0x91, 0x4E, 0x1C, 0x73, 0x2F, 0x0C, 0x7A, 0x6D, 0x03, 0x1E, 0x54, 0x65, 0xF1 } } } }, // EOB1
+ { DE_DEU, kPlatformUnknown, { 0x00000030, 0x00001057, { { 0xF3, 0x5E, 0xFC, 0xC3, 0x9D, 0xB5, 0xFE, 0x4E, 0x66, 0x9D, 0x6A, 0xC6, 0x61, 0xC8, 0x0A, 0x17 } } } }, // EOB2
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBaseMenuStringsScribeProvider[] = {
+ { EN_ANY, kPlatformUnknown, { 0x00000103, 0x000055E1, { { 0x1B, 0x56, 0xD2, 0x78, 0x3F, 0x67, 0x7A, 0x5B, 0xB6, 0x2B, 0x70, 0x3D, 0x6A, 0xBB, 0x08, 0x0A } } } }, // EOB1
+ { DE_DEU, kPlatformUnknown, { 0x0000010C, 0x00005B1C, { { 0xD7, 0xBF, 0x37, 0x21, 0xA2, 0x63, 0x8C, 0x6A, 0x02, 0x92, 0x13, 0x32, 0xD6, 0xA6, 0x1C, 0xDC } } } }, // EOB1
+ { DE_DEU, kPlatformUnknown, { 0x00000100, 0x0000560F, { { 0x69, 0x15, 0x2C, 0x2D, 0xE7, 0x40, 0x4A, 0xE0, 0x86, 0x0D, 0xC8, 0x66, 0x87, 0x1C, 0x27, 0x0B } } } }, // EOB2
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBaseMenuStringsDrop2Provider[] = {
+ { EN_ANY, kPlatformUnknown, { 0x00000084, 0x00002ACE, { { 0xAB, 0x78, 0x42, 0x29, 0xFB, 0xC5, 0x34, 0x96, 0x9D, 0x8A, 0x21, 0x46, 0xE7, 0x6B, 0x06, 0xBA } } } }, // EOB1
+ { DE_DEU, kPlatformUnknown, { 0x0000008C, 0x00002D02, { { 0x11, 0x3F, 0x0C, 0xB2, 0xBF, 0xA7, 0x39, 0x23, 0xDC, 0x00, 0xB4, 0xEA, 0x5E, 0xFE, 0x40, 0xB7 } } } }, // EOB1
+ { EN_ANY, kPlatformUnknown, { 0x0000008E, 0x00002FFB, { { 0xCE, 0x7A, 0xCC, 0xA4, 0x02, 0x54, 0x1A, 0x78, 0xF1, 0xFC, 0xE6, 0x6C, 0x76, 0xCD, 0xFD, 0x9E } } } }, // EOB2
+ { DE_DEU, kPlatformUnknown, { 0x00000090, 0x000031CE, { { 0x01, 0x72, 0x59, 0xBE, 0x62, 0x72, 0xD4, 0x99, 0x76, 0xC9, 0x92, 0x0E, 0xE9, 0x1A, 0xCD, 0x65 } } } }, // EOB2
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBaseMenuStringsHeadProvider[] = {
+ { EN_ANY, kPlatformUnknown, { 0x00000021, 0x00000B27, { { 0x04, 0x06, 0x01, 0xF8, 0x50, 0x54, 0x11, 0x61, 0xFF, 0xB4, 0xE1, 0x97, 0xFA, 0x08, 0xAA, 0x1B } } } }, // EOB1
+ { DE_DEU, kPlatformUnknown, { 0x00000024, 0x00000CF5, { { 0x96, 0xD6, 0xB5, 0xB0, 0x2E, 0x71, 0xA4, 0x0A, 0x34, 0x41, 0x94, 0x02, 0x2F, 0xB0, 0x4C, 0x36 } } } }, // EOB1
+ { DE_DEU, kPlatformUnknown, { 0x00000025, 0x00000D92, { { 0xE4, 0x73, 0x2D, 0x29, 0xAD, 0x30, 0xE5, 0x8D, 0xAE, 0xC6, 0xD7, 0xF5, 0x35, 0xD8, 0xA4, 0x98 } } } }, // EOB2
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBaseMenuStringsPoisonProvider[] = {
+ { EN_ANY, kPlatformUnknown, { 0x0000002E, 0x00001077, { { 0x14, 0x7E, 0xFC, 0xE0, 0x88, 0xFE, 0x86, 0xA8, 0x96, 0x94, 0xB1, 0x71, 0x90, 0x47, 0x2D, 0x78 } } } }, // EOB1
+ { DE_DEU, kPlatformUnknown, { 0x00000036, 0x000013A2, { { 0x18, 0xD9, 0x1D, 0xE5, 0x3D, 0xFD, 0x52, 0xB6, 0x18, 0x17, 0x61, 0xE8, 0xA5, 0x32, 0x9F, 0xA8 } } } }, // EOB1
+ { EN_ANY, kPlatformUnknown, { 0x0000002D, 0x00001006, { { 0xD6, 0x0B, 0x11, 0x79, 0xAD, 0x61, 0x5B, 0x3A, 0x72, 0x7D, 0x53, 0x6F, 0xA9, 0x08, 0x73, 0xDC } } } }, // EOB2
+ { DE_DEU, kPlatformUnknown, { 0x00000035, 0x000013BE, { { 0x73, 0x38, 0x76, 0x2C, 0x42, 0x87, 0x43, 0x7E, 0x8E, 0x4C, 0x41, 0x57, 0x3F, 0x04, 0xBA, 0x11 } } } }, // EOB2
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBaseMenuStringsMgcProvider[] = {
+ { EN_ANY, kPlatformUnknown, { 0x00000020, 0x00000857, { { 0xD1, 0x9E, 0xBF, 0xF7, 0xCF, 0xF7, 0xD0, 0x94, 0x14, 0x56, 0xD2, 0x4F, 0x59, 0x91, 0x57, 0x52 } } } }, // EOB1
+ { DE_DEU, kPlatformUnknown, { 0x00000020, 0x0000086C, { { 0x12, 0x36, 0x84, 0x2F, 0x00, 0xAD, 0x12, 0x42, 0x3A, 0xA2, 0xC5, 0xC9, 0x59, 0x90, 0x64, 0x5F } } } }, // EOB1
+ { DE_DEU, kPlatformUnknown, { 0x00000021, 0x0000090B, { { 0x26, 0xA7, 0x58, 0x7C, 0x0C, 0x9E, 0x67, 0xB9, 0x05, 0xE6, 0x91, 0x59, 0xE3, 0xDF, 0x9C, 0x52 } } } }, // EOB2
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBaseMenuStringsPrefsProvider[] = {
+ { EN_ANY, kPlatformUnknown, { 0x00000041, 0x00001392, { { 0xB1, 0x7E, 0xE3, 0x73, 0xB2, 0xA2, 0x63, 0x39, 0x20, 0xE8, 0xF3, 0x38, 0x45, 0xB6, 0xAC, 0xC8 } } } }, // EOB1
+ { DE_DEU, kPlatformUnknown, { 0x00000045, 0x000015F6, { { 0x53, 0xBA, 0x7E, 0x6D, 0x24, 0x88, 0x2C, 0x19, 0x10, 0x71, 0x6F, 0xAB, 0x85, 0x8E, 0x97, 0xF6 } } } }, // EOB1
+ { DE_DEU, kPlatformUnknown, { 0x0000003D, 0x00001246, { { 0x03, 0xFB, 0x7C, 0x80, 0x33, 0x45, 0x6C, 0x27, 0x89, 0x7B, 0x7C, 0xAC, 0x7A, 0xE1, 0xDE, 0x49 } } } }, // EOB2
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBaseMenuStringsRest2Provider[] = {
+ { EN_ANY, kPlatformUnknown, { 0x0000004D, 0x00001744, { { 0x63, 0xA5, 0x6F, 0x09, 0x6F, 0x5E, 0x4B, 0x89, 0xFF, 0x33, 0x63, 0xCB, 0xAA, 0x04, 0x59, 0x63 } } } }, // EOB1
+ { DE_DEU, kPlatformUnknown, { 0x0000004D, 0x00001769, { { 0x2C, 0xA9, 0x7D, 0x4C, 0xC5, 0x13, 0xE2, 0xEB, 0x89, 0x6C, 0xAE, 0x25, 0xC3, 0x3E, 0x56, 0x7E } } } }, // EOB1
+ { EN_ANY, kPlatformUnknown, { 0x00000052, 0x000017F6, { { 0x7C, 0x49, 0xFC, 0x89, 0x90, 0x5D, 0xFF, 0x86, 0x86, 0xE9, 0xB2, 0x29, 0x60, 0xB2, 0x22, 0x7F } } } }, // EOB2
+ { DE_DEU, kPlatformUnknown, { 0x0000004C, 0x000014FF, { { 0x0C, 0x94, 0x6D, 0x5A, 0x42, 0x68, 0xE0, 0xDC, 0xCD, 0xB9, 0x1A, 0x4A, 0xC1, 0xCC, 0xE6, 0x91 } } } }, // EOB2
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBaseMenuStringsRest3Provider[] = {
+ { EN_ANY, kPlatformUnknown, { 0x0000002B, 0x00000DF4, { { 0x42, 0x90, 0x49, 0xA7, 0x2E, 0x61, 0x77, 0x7F, 0x9F, 0x53, 0xAD, 0x3C, 0x87, 0xE2, 0x0E, 0x36 } } } }, // EOB2
+ { DE_DEU, kPlatformUnknown, { 0x00000027, 0x00000D45, { { 0x8D, 0xAB, 0xBF, 0x57, 0xF3, 0x2C, 0x3F, 0x93, 0xBF, 0x33, 0x58, 0x2D, 0x97, 0x78, 0x71, 0x7F } } } }, // EOB2
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBaseMenuStringsRest4Provider[] = {
+ { EN_ANY, kPlatformUnknown, { 0x00000029, 0x00000DEC, { { 0x1C, 0x86, 0x3D, 0x40, 0x2C, 0x5E, 0xCA, 0xA0, 0xA1, 0xB8, 0x23, 0x42, 0x9C, 0x6B, 0xFA, 0xBB } } } }, // EOB1
+ { DE_DEU, kPlatformUnknown, { 0x00000034, 0x00001238, { { 0xE9, 0x95, 0x27, 0x79, 0x1C, 0x0D, 0xF5, 0x94, 0x92, 0xFC, 0xCA, 0x22, 0x17, 0xA8, 0x36, 0x96 } } } }, // EOB1
+ { EN_ANY, kPlatformUnknown, { 0x0000002A, 0x00000DEB, { { 0x0E, 0xD3, 0xC5, 0xA9, 0x8B, 0x06, 0x57, 0xB0, 0x20, 0x1A, 0xEE, 0x42, 0x49, 0x2E, 0xA1, 0x50 } } } }, // EOB2
+ { DE_DEU, kPlatformUnknown, { 0x00000033, 0x00001189, { { 0x56, 0x1B, 0x6B, 0x00, 0x47, 0xFD, 0x56, 0xD3, 0x12, 0x03, 0x79, 0x7D, 0xFF, 0x83, 0xCF, 0xAA } } } }, // EOB2
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBaseMenuStringsDefeatProvider[] = {
+ { EN_ANY, kPlatformUnknown, { 0x0000006D, 0x00002643, { { 0x94, 0xBA, 0xAC, 0xA4, 0x87, 0x6A, 0xEA, 0x7D, 0x98, 0x6E, 0x09, 0x82, 0xE0, 0x16, 0x65, 0x4F } } } }, // EOB1
+ { DE_DEU, kPlatformUnknown, { 0x0000006A, 0x00002456, { { 0xE0, 0x9A, 0x10, 0xE2, 0x73, 0x42, 0xF6, 0x79, 0xCB, 0x65, 0xA2, 0x50, 0xF0, 0x2B, 0xFD, 0x9B } } } }, // EOB1
+ { EN_ANY, kPlatformUnknown, { 0x00000056, 0x00001E4F, { { 0x97, 0x07, 0x5F, 0xA2, 0x0D, 0x58, 0xD2, 0xDF, 0xD6, 0x04, 0xA2, 0x16, 0x0B, 0x1F, 0x7E, 0x23 } } } }, // EOB2
+ { DE_DEU, kPlatformUnknown, { 0x00000042, 0x000016B1, { { 0xCA, 0x57, 0xDC, 0x2B, 0xC6, 0xC7, 0x78, 0x1E, 0x84, 0x0A, 0x10, 0x88, 0xCA, 0xCD, 0xFF, 0x89 } } } }, // EOB2
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBaseMenuStringsTransferProvider[] = {
+ { EN_ANY, kPlatformUnknown, { 0x00000114, 0x00005E09, { { 0xBF, 0xCE, 0x7F, 0xE4, 0x17, 0x15, 0xC6, 0x10, 0xDF, 0x16, 0xF9, 0x3C, 0xDA, 0x29, 0xA0, 0xA6 } } } }, // EOB2
+ { DE_DEU, kPlatformUnknown, { 0x000000D1, 0x00004811, { { 0x2E, 0x00, 0xD1, 0xA6, 0x9F, 0x53, 0xC5, 0x4B, 0x25, 0x4A, 0xAC, 0x9E, 0x11, 0x6C, 0x58, 0x5E } } } }, // EOB2
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBaseMenuStringsSpecProvider[] = {
+ { EN_ANY, kPlatformUnknown, { 0x0000006F, 0x00002785, { { 0xAE, 0xC7, 0x88, 0x89, 0x39, 0xB8, 0xF7, 0xB4, 0xD5, 0x82, 0xBC, 0x46, 0xA1, 0xCB, 0x04, 0x1F } } } }, // EOB2
+ { DE_DEU, kPlatformUnknown, { 0x00000075, 0x00002871, { { 0xB4, 0x38, 0x0F, 0x94, 0x8B, 0xB1, 0x8D, 0xA3, 0xF8, 0xDA, 0x37, 0x75, 0x6F, 0x39, 0x3E, 0xB5 } } } }, // EOB2
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBaseMenuStringsSpellNoProvider[] = {
+ { UNK_LANG, kPlatformUnknown, { 0x00000006, 0x000000A5, { { 0x0D, 0x4A, 0x8B, 0x40, 0x70, 0x79, 0xCD, 0xB3, 0x0F, 0x5A, 0x5A, 0x3F, 0x6E, 0xE8, 0xF9, 0x74 } } } }, // EOB2
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBaseMenuYesNoStringsProvider[] = {
+ { EN_ANY, kPlatformUnknown, { 0x00000007, 0x000001EE, { { 0x8C, 0xF1, 0x35, 0x1F, 0xD6, 0x1F, 0xA4, 0xA1, 0xD6, 0xD6, 0x0A, 0x27, 0xB9, 0xFC, 0x9E, 0x62 } } } },
+ { DE_DEU, kPlatformUnknown, { 0x00000008, 0x00000235, { { 0xC7, 0x06, 0xCF, 0xA8, 0xC0, 0xDE, 0xD4, 0x8C, 0x7F, 0xA2, 0x3A, 0xD3, 0x48, 0x51, 0x36, 0x89 } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBaseSpellLevelsMageProvider[] = {
+ { UNK_LANG, kPlatformUnknown, { 0x0000001A, 0x00000042, { { 0x4F, 0xA3, 0x70, 0x0F, 0x6D, 0xB4, 0xC2, 0xAF, 0x12, 0xB4, 0x2E, 0x26, 0xEF, 0x0B, 0x37, 0x92 } } } }, // EOB1
+ { UNK_LANG, kPlatformUnknown, { 0x00000023, 0x00000074, { { 0xBE, 0x10, 0xFA, 0xD9, 0xB3, 0xB0, 0x4E, 0x73, 0xC9, 0xA1, 0xE2, 0xCE, 0xE8, 0xEC, 0x85, 0x0F } } } }, // EOB2
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBaseSpellLevelsClericProvider[] = {
+ { UNK_LANG, kPlatformUnknown, { 0x00000019, 0x00000045, { { 0x9E, 0xDA, 0xF2, 0x94, 0x3E, 0x0B, 0xA0, 0x23, 0x08, 0x41, 0xD5, 0x3C, 0x61, 0x77, 0xFD, 0x78 } } } }, // EOB1
+ { UNK_LANG, kPlatformUnknown, { 0x0000001D, 0x00000066, { { 0xDB, 0x7F, 0x93, 0xE2, 0x2E, 0xCF, 0x69, 0xCC, 0x2A, 0xEF, 0x7C, 0x1E, 0x92, 0x6B, 0x51, 0x4E } } } }, // EOB2
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBaseNumSpellsClericProvider[] = {
+ { UNK_LANG, kPlatformUnknown, { 0x00000032, 0x0000004C, { { 0x87, 0xDD, 0xD0, 0xF8, 0x52, 0x84, 0x26, 0xC4, 0x9C, 0x5D, 0x0E, 0x46, 0x1A, 0xE8, 0x19, 0xD6 } } } }, // EOB1
+ { UNK_LANG, kPlatformUnknown, { 0x00000088, 0x00000114, { { 0xA0, 0xB7, 0x2F, 0xED, 0x50, 0xE7, 0xC6, 0x11, 0xC9, 0x25, 0xB2, 0xB9, 0x81, 0xFB, 0xD8, 0x59 } } } }, // EOB2
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBaseNumSpellsWisAdjProvider[] = {
+ { UNK_LANG, kPlatformUnknown, { 0x00000028, 0x0000001D, { { 0xA5, 0xCA, 0x1D, 0x96, 0xAE, 0x89, 0xBC, 0x7A, 0x32, 0x50, 0xCE, 0x44, 0x5D, 0x93, 0x25, 0x4B } } } }, // EOB1
+ { UNK_LANG, kPlatformUnknown, { 0x00000040, 0x0000001D, { { 0x07, 0x31, 0x0D, 0x12, 0x55, 0x11, 0x11, 0xB6, 0x68, 0xC7, 0xEE, 0xDE, 0xC6, 0xED, 0x82, 0x5A } } } }, // EOB2
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBaseNumSpellsPalProvider[] = {
+ { UNK_LANG, kPlatformUnknown, { 0x0000003C, 0x00000012, { { 0x96, 0x7E, 0x17, 0x9E, 0xFD, 0x39, 0xC9, 0x3A, 0xB7, 0x3E, 0x8D, 0xA8, 0xED, 0xA3, 0x07, 0xEB } } } }, // EOB1
+ { UNK_LANG, kPlatformUnknown, { 0x00000088, 0x0000002F, { { 0x19, 0x1A, 0x9B, 0x42, 0xA0, 0x67, 0x10, 0x1A, 0xAC, 0x00, 0x0F, 0xF7, 0xBE, 0x04, 0x61, 0x36 } } } }, // EOB2
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBaseNumSpellsMageProvider[] = {
+ { UNK_LANG, kPlatformUnknown, { 0x00000037, 0x0000005E, { { 0x61, 0x30, 0x1A, 0x74, 0x9B, 0x4C, 0x8C, 0x83, 0xD5, 0xE6, 0x39, 0x6E, 0xCA, 0x18, 0x16, 0x63 } } } }, // EOB1
+ { UNK_LANG, kPlatformUnknown, { 0x00000114, 0x00000102, { { 0x33, 0xEE, 0x32, 0x9C, 0xB2, 0xB3, 0x60, 0x66, 0x91, 0xE0, 0x90, 0x0E, 0x8F, 0xE1, 0xA5, 0x4A } } } }, // EOB2
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBaseCharGuiStringsHpProvider[] = {
+ { EN_ANY, kPlatformUnknown, { 0x0000000F, 0x00000352, { { 0x9C, 0x13, 0x3D, 0x2A, 0x68, 0x11, 0x81, 0xA4, 0x77, 0x54, 0x47, 0x43, 0xA1, 0xDA, 0x55, 0x50 } } } },
+ { DE_DEU, kPlatformUnknown, { 0x0000000E, 0x000002AC, { { 0xBB, 0xD5, 0x36, 0xB2, 0x8A, 0x60, 0x78, 0x04, 0x46, 0x2D, 0x35, 0x59, 0x3E, 0x42, 0xB9, 0x83 } } } }, // EoB 1
+ { DE_DEU, kPlatformUnknown, { 0x0000000E, 0x000002B8, { { 0x77, 0x76, 0xA0, 0x38, 0xE9, 0xB6, 0x0C, 0x43, 0xFE, 0x5A, 0x51, 0xC7, 0x1B, 0x59, 0xD3, 0x63 } } } }, // EoB 2
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBaseCharGuiStringsWp1Provider[] = {
+ { EN_ANY, kPlatformUnknown, { 0x0000000A, 0x00000253, { { 0x1D, 0xF4, 0xB9, 0x56, 0xE6, 0x16, 0x7D, 0x08, 0xA4, 0x00, 0x1E, 0x1A, 0x60, 0x49, 0xE9, 0x29 } } } },
+ { DE_DEU, kPlatformUnknown, { 0x0000000A, 0x00000236, { { 0x17, 0xEC, 0x54, 0xA0, 0x43, 0xFB, 0x52, 0x66, 0xC5, 0x44, 0x1B, 0xDF, 0x95, 0x47, 0x62, 0xB3 } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBaseCharGuiStringsWp2Provider[] = {
+ { EN_ANY, kPlatformUnknown, { 0x0000000F, 0x00000371, { { 0x42, 0xF4, 0x52, 0x60, 0x20, 0xFC, 0x34, 0x94, 0x49, 0x1E, 0x67, 0x54, 0xB5, 0x6A, 0x97, 0x2A } } } },
+ { DE_DEU, kPlatformUnknown, { 0x00000010, 0x000003D6, { { 0x10, 0xD1, 0x77, 0x6C, 0xCD, 0x00, 0x94, 0xC7, 0xD0, 0x53, 0x47, 0x9F, 0x70, 0x77, 0x50, 0xD1 } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBaseCharGuiStringsWrProvider[] = {
+ { EN_ANY, kPlatformUnknown, { 0x00000014, 0x00000477, { { 0xAA, 0x26, 0xD5, 0xFD, 0xE6, 0x16, 0x53, 0x19, 0x39, 0x46, 0xEB, 0xCD, 0x88, 0xEC, 0x5E, 0xCB } } } },
+ { DE_DEU, kPlatformUnknown, { 0x00000015, 0x000004A4, { { 0x53, 0x54, 0x37, 0x35, 0x27, 0x1F, 0xB9, 0x09, 0x9C, 0xE9, 0x5E, 0x11, 0xBD, 0x8F, 0x15, 0xAE } } } }, // EoB 1
+ { DE_DEU, kPlatformUnknown, { 0x00000011, 0x00000402, { { 0xE0, 0x92, 0xF4, 0x49, 0xB7, 0x74, 0xBB, 0xEB, 0x90, 0x0D, 0x75, 0x65, 0xBB, 0xF6, 0xB6, 0xE9 } } } }, // EoB 2
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBaseCharGuiStringsSt1Provider[] = {
+ { EN_ANY, kPlatformUnknown, { 0x0000003B, 0x0000104B, { { 0xC0, 0xD9, 0x0F, 0x7B, 0x6D, 0x17, 0x02, 0xBD, 0x7B, 0xB1, 0x76, 0x72, 0xA1, 0xEE, 0x5E, 0xAD } } } },
+ { DE_DEU, kPlatformUnknown, { 0x00000039, 0x00000F69, { { 0x09, 0x42, 0x35, 0x47, 0x48, 0x50, 0x05, 0x09, 0x3B, 0x81, 0x14, 0x01, 0xF9, 0xB5, 0x04, 0xB2 } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBaseCharGuiStringsSt2Provider[] = {
+ { EN_ANY, kPlatformUnknown, { 0x00000045, 0x000012E7, { { 0x49, 0x48, 0x30, 0x73, 0xDA, 0x42, 0xDB, 0xB9, 0xF4, 0x07, 0x00, 0x26, 0x96, 0x1F, 0x02, 0x4E } } } },
+ { DE_DEU, kPlatformUnknown, { 0x00000042, 0x0000114D, { { 0x88, 0x6E, 0x45, 0xF9, 0xAE, 0xEF, 0xE8, 0x54, 0x9C, 0xEF, 0xD2, 0x73, 0x78, 0x41, 0xD9, 0xAF } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBaseCharGuiStringsInProvider[] = {
+ { EN_ANY, kPlatformUnknown, { 0x00000023, 0x000008CB, { { 0xF0, 0xE9, 0xF1, 0x05, 0x47, 0x3A, 0x5D, 0xCA, 0x9F, 0x75, 0x9D, 0x51, 0x9E, 0xEC, 0x9B, 0x67 } } } },
+ { DE_DEU, kPlatformUnknown, { 0x00000020, 0x00000810, { { 0xF5, 0x39, 0x1E, 0x0E, 0x65, 0xEF, 0x09, 0xF2, 0x8D, 0x90, 0xC4, 0xF6, 0x8A, 0xED, 0xAD, 0xDF } } } }, // EoB 1
+ { DE_DEU, kPlatformUnknown, { 0x00000023, 0x00000940, { { 0xAB, 0xF6, 0xE4, 0xD4, 0x07, 0x07, 0xDA, 0x92, 0x71, 0xE2, 0x73, 0x1F, 0x06, 0xE3, 0x12, 0xEB } } } }, // EoB 2
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBaseCharStatusStrings7Provider[] = {
+ { EN_ANY, kPlatformUnknown, { 0x00000022, 0x00000B95, { { 0xCB, 0xB7, 0x16, 0x77, 0x9C, 0xEB, 0x70, 0x83, 0xB2, 0xBE, 0xF7, 0x67, 0xB1, 0xE9, 0xD0, 0x5E } } } }, // EOB 1 + 2
+ { DE_DEU, kPlatformUnknown, { 0x0000002B, 0x00000EE3, { { 0xC8, 0x81, 0x23, 0xC3, 0x03, 0xBD, 0x4C, 0xF5, 0x41, 0x47, 0xFA, 0x32, 0xA0, 0x98, 0x0A, 0x8E } } } }, // EOB 1
+ { DE_DEU, kPlatformUnknown, { 0x00000023, 0x00000C68, { { 0xF5, 0x55, 0x09, 0xD8, 0x73, 0xF8, 0xF0, 0xE3, 0x14, 0xCD, 0x78, 0x84, 0x58, 0xB0, 0x64, 0x5B } } } }, // EOB 2
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBaseCharStatusStrings81Provider[] = {
+ { EN_ANY, kPlatformUnknown, { 0x00000021, 0x00000B03, { { 0x44, 0xFC, 0xC2, 0x23, 0x4B, 0x78, 0xA8, 0xF8, 0xA5, 0x46, 0x5B, 0x89, 0x1F, 0x9D, 0x4E, 0xFA } } } }, // EOB 1
+ { DE_DEU, kPlatformUnknown, { 0x00000020, 0x00000A52, { { 0x81, 0xDA, 0x22, 0x8A, 0xD3, 0x7D, 0xE7, 0xF5, 0x39, 0x6A, 0x62, 0x41, 0xE5, 0x8D, 0x45, 0x20 } } } }, // EOB 1
+};
+
+const ExtractEntrySearchData kEoBBaseCharStatusStrings82Provider[] = {
+ { EN_ANY, kPlatformUnknown, { 0x00000023, 0x00000B0F, { { 0xBD, 0xED, 0xFE, 0xFD, 0x40, 0x95, 0x42, 0x21, 0x1F, 0x55, 0x67, 0x65, 0xA8, 0xC3, 0x99, 0xA1 } } } }, // EOB 2
+ { DE_DEU, kPlatformUnknown, { 0x0000001A, 0x00000789, { { 0x8C, 0xF3, 0xB8, 0x3C, 0x6E, 0x85, 0xED, 0xD6, 0x2B, 0xD7, 0xAE, 0x8A, 0xFC, 0x25, 0x5E, 0x8F } } } }, // EOB 2
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBaseCharStatusStrings9Provider[] = {
+ { EN_ANY, kPlatformUnknown, { 0x0000001C, 0x00000952, { { 0x2F, 0x41, 0x17, 0x95, 0xF8, 0xC8, 0x4E, 0x88, 0xC6, 0x83, 0x38, 0x9B, 0xAB, 0x23, 0x48, 0xB9 } } } }, // EOB 1 + 2
+ { DE_DEU, kPlatformUnknown, { 0x0000001D, 0x0000099F, { { 0x5E, 0xB4, 0xBE, 0xA9, 0x0C, 0xB2, 0xF2, 0x4E, 0x63, 0xF8, 0x7B, 0x98, 0x67, 0x2D, 0xC9, 0xBF } } } }, // EOB 1
+ { DE_DEU, kPlatformUnknown, { 0x0000001E, 0x00000A52, { { 0xD4, 0x65, 0x3F, 0x35, 0xDD, 0x8A, 0x33, 0x44, 0x2F, 0x8C, 0xAC, 0x2F, 0xEC, 0x96, 0x5B, 0x02 } } } }, // EOB 2
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBaseCharStatusStrings12Provider[] = {
+ { EN_ANY, kPlatformUnknown, { 0x00000010, 0x00000503, { { 0x81, 0x22, 0xE9, 0x0F, 0xA5, 0xEA, 0xFE, 0xB5, 0xB6, 0x43, 0x36, 0x22, 0x87, 0x24, 0x2C, 0x40 } } } },
+ { DE_DEU, kPlatformUnknown, { 0x00000014, 0x00000683, { { 0x5A, 0xF8, 0xAA, 0x16, 0x97, 0xBE, 0xD5, 0x22, 0xCE, 0x3F, 0xBC, 0x00, 0x44, 0xC1, 0x27, 0xD3 } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBaseCharStatusStrings131Provider[] = {
+ { EN_ANY, kPlatformUnknown, { 0x0000000B, 0x0000027A, { { 0x70, 0x1A, 0x83, 0x35, 0x0A, 0x51, 0xEA, 0x27, 0x6E, 0xCD, 0xEB, 0xAD, 0x20, 0x74, 0x28, 0x7D } } } },
+ { DE_DEU, kPlatformUnknown, { 0x0000000C, 0x000002EE, { { 0xFE, 0xF9, 0x45, 0xE7, 0x89, 0x7B, 0xA4, 0x82, 0x90, 0x63, 0x91, 0x5B, 0x9E, 0x83, 0x80, 0x10 } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBaseCharStatusStrings132Provider[] = {
+ { EN_ANY, kPlatformUnknown, { 0x0000000D, 0x00000286, { { 0x00, 0x1E, 0x11, 0xCC, 0x57, 0xFA, 0xEF, 0x2A, 0x0A, 0xFF, 0xFF, 0xE9, 0x3E, 0xA3, 0x62, 0x21 } } } },
+ { DE_DEU, kPlatformUnknown, { 0x0000000A, 0x0000018A, { { 0x10, 0x54, 0x6F, 0xC3, 0x08, 0xC4, 0xD2, 0xBB, 0x34, 0x0A, 0x04, 0x65, 0x49, 0xFC, 0x5E, 0x15 } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBaseLevelGainStringsProvider[] = {
+ { EN_ANY, kPlatformUnknown, { 0x0000002A, 0x00000CC9, { { 0xF2, 0x1F, 0xDF, 0xE0, 0xA5, 0x86, 0x46, 0xF4, 0xFC, 0x71, 0xB0, 0x22, 0x32, 0x46, 0x71, 0xB6 } } } }, // EOB 1
+ { DE_DEU, kPlatformUnknown, { 0x00000029, 0x00000D38, { { 0x18, 0xA3, 0xFD, 0xCC, 0xF2, 0x68, 0x18, 0x9E, 0x80, 0x5A, 0xC0, 0x22, 0xFD, 0x15, 0x83, 0x84 } } } }, // EOB 1
+ { EN_ANY, kPlatformUnknown, { 0x0000001C, 0x0000078C, { { 0x15, 0x70, 0x37, 0xE4, 0x0B, 0x50, 0x32, 0xCA, 0xAE, 0xF6, 0x81, 0xD0, 0x98, 0x9B, 0x36, 0x8A } } } }, // EOB 2
+ { DE_DEU, kPlatformUnknown, { 0x0000001F, 0x000008E3, { { 0x07, 0x2C, 0x51, 0x5E, 0x47, 0xAA, 0xCC, 0x27, 0x77, 0xD8, 0x17, 0x59, 0x6B, 0xBE, 0xF5, 0x87 } } } }, // EOB 2
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBaseExperienceTable0Provider[] = {
+ { UNK_LANG, kPlatformUnknown, { 0x00000030, 0x00000C9E, { { 0xDB, 0x47, 0xD9, 0x0D, 0x6E, 0x68, 0x04, 0xE4, 0x17, 0xCB, 0x60, 0x89, 0x35, 0x3E, 0xA9, 0xEE } } } }, // EoB 1
+ { UNK_LANG, kPlatformUnknown, { 0x00000038, 0x00000E24, { { 0xBC, 0xF3, 0x96, 0x8A, 0xD5, 0x0C, 0xAA, 0x94, 0xBB, 0xB5, 0x08, 0x73, 0xF8, 0x5C, 0xF0, 0xA9 } } } }, // EoB 2
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBaseExperienceTable1Provider[] = {
+ { UNK_LANG, kPlatformUnknown, { 0x00000030, 0x00000C80, { { 0x35, 0x45, 0x0D, 0x4F, 0xE0, 0x84, 0xA2, 0x1B, 0xB0, 0x0D, 0x60, 0x4D, 0x1D, 0xD5, 0x6C, 0x72 } } } }, // EoB 1
+ { UNK_LANG, kPlatformUnknown, { 0x00000038, 0x00000E6F, { { 0xBD, 0x3F, 0x42, 0x54, 0x75, 0x41, 0xAA, 0x58, 0x0D, 0xD8, 0xC0, 0x07, 0x63, 0x35, 0x83, 0x6B } } } }, // EoB 2
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBaseExperienceTable2Provider[] = {
+ { UNK_LANG, kPlatformUnknown, { 0x0000002C, 0x00000E10, { { 0xA5, 0x4D, 0xCB, 0xF3, 0x5F, 0x89, 0x71, 0x24, 0x6F, 0x70, 0xCA, 0x51, 0xAA, 0x1C, 0x0A, 0x97 } } } }, // EoB 1
+ { UNK_LANG, kPlatformUnknown, { 0x00000038, 0x00001149, { { 0xF9, 0xF1, 0x7E, 0x6B, 0xB2, 0xFE, 0x04, 0xC4, 0x29, 0x3D, 0xE3, 0x42, 0x5D, 0x92, 0x77, 0x53 } } } }, // EoB 2
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBaseExperienceTable3Provider[] = {
+ { UNK_LANG, kPlatformUnknown, { 0x00000030, 0x00000ADC, { { 0x42, 0x2E, 0x2E, 0xF5, 0xF8, 0x65, 0x69, 0x28, 0x50, 0x67, 0x43, 0xDF, 0x91, 0x67, 0x9B, 0x09 } } } }, // EoB 1
+ { UNK_LANG, kPlatformUnknown, { 0x00000038, 0x00000C94, { { 0x67, 0x09, 0x98, 0x19, 0x1F, 0x6B, 0x4D, 0xEB, 0x1D, 0x4D, 0x55, 0xA8, 0xFF, 0xD1, 0xAB, 0xE1 } } } }, // EoB 2
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBaseExperienceTable4Provider[] = {
+ { UNK_LANG, kPlatformUnknown, { 0x00000030, 0x00000DA7, { { 0x45, 0x58, 0x34, 0xC9, 0x09, 0x61, 0xD7, 0xE1, 0xF8, 0x68, 0x80, 0xBC, 0xEF, 0x7A, 0x24, 0x03 } } } }, // EoB 1
+ { UNK_LANG, kPlatformUnknown, { 0x00000038, 0x00000FE1, { { 0x26, 0x7F, 0x83, 0x53, 0x4A, 0xC6, 0xA2, 0x7B, 0xD2, 0xFB, 0x73, 0xB2, 0x08, 0x0A, 0xF7, 0xFD } } } }, // EoB 2
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBaseWllFlagPresetProvider[] = {
+ { UNK_LANG, kPlatformUnknown, { 0x00000019, 0x00000BD9, { { 0xBE, 0x5A, 0xA6, 0xC8, 0xE4, 0x04, 0x4C, 0x32, 0x35, 0x61, 0x48, 0x73, 0x29, 0xA9, 0x99, 0x54 } } } }, // EoB 1
+ { UNK_LANG, kPlatformUnknown, { 0x00000019, 0x00000BC9, { { 0x56, 0xC0, 0x66, 0x4D, 0xE1, 0x3A, 0x27, 0x89, 0x9D, 0x73, 0x63, 0x93, 0x08, 0x2B, 0x13, 0xBC } } } }, // EoB 2
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBaseDscShapeCoordsProvider[] = {
+ { UNK_LANG, kPlatformUnknown, { 0x00000168, 0x0000F206, { { 0xB8, 0xDF, 0x10, 0xBB, 0x06, 0xA1, 0x46, 0xC6, 0xD2, 0xE3, 0xD7, 0x64, 0x4A, 0xC6, 0x40, 0xC0 } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBaseDscDoorScaleOffsProvider[] = {
+ { UNK_LANG, kPlatformPC, { 0x00000020, 0x0000010F, { { 0x7B, 0x7D, 0x03, 0xDE, 0x33, 0x95, 0xB8, 0xFD, 0xAD, 0x72, 0x44, 0x7D, 0x47, 0xFE, 0x04, 0x3D } } } }, // EoB1
+ { UNK_LANG, kPlatformPC, { 0x00000035, 0x00000139, { { 0x74, 0x63, 0x18, 0xE7, 0xAB, 0xA4, 0x22, 0xCF, 0x32, 0x19, 0x28, 0x9E, 0x7F, 0x97, 0xA7, 0x37 } } } }, // EoB2
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBaseDscDoorScaleMult1Provider[] = {
+ { UNK_LANG, kPlatformPC, { 0x00000004, 0x00000026, { { 0x5D, 0x17, 0xFB, 0x6A, 0x7F, 0x51, 0x55, 0xFB, 0x55, 0xB9, 0x50, 0xB0, 0x7F, 0xE4, 0xDF, 0x67 } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBaseDscDoorScaleMult2Provider[] = {
+ { UNK_LANG, kPlatformPC, { 0x00000004, 0x00000006, { { 0x98, 0xD8, 0xF8, 0x0C, 0x98, 0xC4, 0xF1, 0x87, 0x59, 0x32, 0x78, 0x31, 0xFA, 0x98, 0x8A, 0x43 } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBaseDscDoorScaleMult3Provider[] = {
+ { UNK_LANG, kPlatformPC, { 0x00000004, 0x00000013, { { 0xEE, 0xB6, 0xA5, 0x6E, 0x0C, 0x8E, 0xAB, 0x38, 0xD9, 0x23, 0xC6, 0x21, 0xB3, 0x7E, 0x97, 0x78 } } } }, // EOB 1
+ { UNK_LANG, kPlatformPC, { 0x00000004, 0x00000019, { { 0x86, 0xD8, 0x04, 0xD2, 0x66, 0x6F, 0x43, 0x24, 0x2E, 0x93, 0xB9, 0xAE, 0xEB, 0x44, 0xCA, 0x48 } } } }, // EOB 2
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBaseDscDoorScaleMult4Provider[] = {
+ { UNK_LANG, kPlatformPC, { 0x00000004, 0x00000006, { { 0x98, 0xD8, 0xF8, 0x0C, 0x98, 0xC4, 0xF1, 0x87, 0x59, 0x32, 0x78, 0x31, 0xFA, 0x98, 0x8A, 0x43 } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBaseDscDoorScaleMult5Provider[] = {
+ { UNK_LANG, kPlatformPC, { 0x00000004, 0x00000020, { { 0x37, 0xA1, 0x0D, 0x64, 0xD6, 0x1E, 0xBA, 0xA3, 0xD9, 0x0A, 0x6C, 0xAB, 0x6B, 0xA3, 0x59, 0x24 } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBaseDscDoorScaleMult6Provider[] = {
+ { UNK_LANG, kPlatformPC, { 0x00000004, 0x00000006, { { 0x98, 0xD8, 0xF8, 0x0C, 0x98, 0xC4, 0xF1, 0x87, 0x59, 0x32, 0x78, 0x31, 0xFA, 0x98, 0x8A, 0x43 } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBaseDscDoorType5OffsProvider[] = {
+ { UNK_LANG, kPlatformPC, { 0x00000006, 0x00000012, { { 0x73, 0xBB, 0x61, 0xD6, 0xA7, 0x75, 0xC8, 0x7B, 0xD6, 0xA4, 0x53, 0x1B, 0x54, 0xE9, 0x30, 0x3F } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBaseDscDoorXEProvider[] = {
+ { UNK_LANG, kPlatformPC, { 0x00000020, 0x0000010F, { { 0x7B, 0x7D, 0x03, 0xDE, 0x33, 0x95, 0xB8, 0xFD, 0xAD, 0x72, 0x44, 0x7D, 0x47, 0xFE, 0x04, 0x3D } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBaseDscDoorY1Provider[] = {
+ { UNK_LANG, kPlatformPC, { 0x00000004, 0x000000D7, { { 0x25, 0xAE, 0xF4, 0x99, 0xE8, 0x97, 0x47, 0xAE, 0x75, 0xF3, 0xA9, 0x70, 0x4C, 0x70, 0xF3, 0x11 } } } }, // EOB 1
+ { UNK_LANG, kPlatformPC, { 0x00000004, 0x000000D8, { { 0xB4, 0xAA, 0x0D, 0x91, 0x58, 0x22, 0x16, 0xCF, 0xC5, 0x9D, 0x8D, 0xA1, 0xB4, 0x40, 0x83, 0x0E } } } }, // EOB 2
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBaseDscDoorY3Provider[] = {
+ { UNK_LANG, kPlatformPC, { 0x00000004, 0x00000058, { { 0xF0, 0x3C, 0x3B, 0x97, 0x10, 0x95, 0x89, 0x18, 0x3B, 0xA9, 0xE8, 0x77, 0x9B, 0x10, 0xDC, 0xF1 } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBaseDscDoorY4Provider[] = {
+ { UNK_LANG, kPlatformPC, { 0x00000004, 0x00000076, { { 0x84, 0xB6, 0x8F, 0x7E, 0x9A, 0x17, 0xAC, 0x59, 0xB1, 0x4C, 0xDE, 0x11, 0xA6, 0x95, 0xE3, 0x76 } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBaseDscDoorY5Provider[] = {
+ { UNK_LANG, kPlatformPC, { 0x00000004, 0x000000D9, { { 0x5D, 0x27, 0x1D, 0xD6, 0x5F, 0x98, 0xF9, 0x7D, 0x65, 0x7B, 0xE0, 0x67, 0x34, 0xA0, 0xE8, 0x30 } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBaseDscDoorY6Provider[] = {
+ { UNK_LANG, kPlatformPC, { 0x00000004, 0x000000D9, { { 0x4D, 0x15, 0x4A, 0xF1, 0x17, 0x09, 0xC1, 0xA6, 0x08, 0x4A, 0xCD, 0xB2, 0x68, 0xC2, 0x59, 0x52 } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBaseDscDoorY7Provider[] = {
+ { UNK_LANG, kPlatformPC, { 0x00000004, 0x000000DA, { { 0xA9, 0x24, 0x71, 0x8A, 0x18, 0x24, 0x6D, 0x0A, 0x65, 0x12, 0xBB, 0x1F, 0xE7, 0x95, 0xC5, 0xA4 } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBaseDscDoorCoordsExtProvider[] = {
+ { UNK_LANG, kPlatformPC, { 0x00000048, 0x00000C8E, { { 0x2E, 0x0E, 0xB2, 0xAC, 0xE7, 0x0F, 0xDF, 0x38, 0xDF, 0x92, 0xB7, 0xB5, 0xA2, 0xFD, 0x40, 0x2D } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBaseDscItemPosIndexProvider[] = {
+ { UNK_LANG, kPlatformPC, { 0x00000010, 0x00000018, { { 0x74, 0x90, 0x47, 0xE6, 0xFB, 0xC0, 0x34, 0xDF, 0x92, 0x5B, 0xA1, 0xCB, 0x06, 0x33, 0xCA, 0x6B } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBaseDscItemShpXProvider[] = {
+ { UNK_LANG, kPlatformPC, { 0x00000024, 0x00000F2C, { { 0x9E, 0x22, 0x3F, 0x8F, 0x31, 0x83, 0xF7, 0x7C, 0x59, 0x60, 0x7C, 0x0A, 0xEB, 0xD2, 0x18, 0x85 } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBaseDscItemPosUnkProvider[] = {
+ { UNK_LANG, kPlatformPC, { 0x00000012, 0x00000433, { { 0xA4, 0x7B, 0x08, 0x07, 0x81, 0xEA, 0x4F, 0x99, 0x77, 0x74, 0x93, 0x65, 0xBF, 0x0C, 0x3B, 0x94 } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBaseDscItemTileIndexProvider[] = {
+ { UNK_LANG, kPlatformPC, { 0x00000012, 0x00000D23, { { 0x0E, 0x17, 0xE1, 0x1F, 0x34, 0x7D, 0x30, 0xF6, 0xAE, 0x0B, 0xAC, 0x9D, 0x21, 0xB6, 0x97, 0xCC } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBaseDscItemShapeMapProvider[] = {
+ { UNK_LANG, kPlatformPC, { 0x0000005A, 0x00000B23, { { 0x41, 0x4A, 0x95, 0x7F, 0x82, 0x85, 0x28, 0x55, 0xD4, 0xD5, 0xD6, 0xD8, 0xA9, 0xAE, 0xF4, 0xC0 } } } }, // EoB 1
+ { UNK_LANG, kPlatformPC, { 0x00000071, 0x00000860, { { 0xEA, 0x5D, 0x33, 0xB6, 0x38, 0x30, 0x65, 0x29, 0x7F, 0x08, 0x89, 0x04, 0xC5, 0x97, 0x76, 0xCB } } } }, // EoB 2
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBaseDscTelptrShpCoordsProvider[] = {
+ { UNK_LANG, kPlatformPC, { 0x0000009C, 0x00000EBE, { { 0x2D, 0x1D, 0x74, 0x39, 0x29, 0xC3, 0x6F, 0x53, 0xD9, 0xA5, 0x4B, 0x9F, 0xD6, 0xDD, 0x73, 0xE9 } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBasePortalSeqDataProvider[] = {
+ { UNK_LANG, kPlatformPC, { 0x0000007E, 0x000002D0, { { 0x18, 0x7E, 0x65, 0x17, 0x4C, 0xD2, 0xB5, 0x2E, 0x81, 0xF8, 0x1C, 0xAC, 0x37, 0x21, 0x62, 0x2A } } } },
+
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBaseManDefProvider[] = {
+ { EN_ANY, kPlatformPC, { 0x00000078, 0x000002CD, { { 0x33, 0x9B, 0x0C, 0x6A, 0x2E, 0x4F, 0xE9, 0x02, 0x7B, 0xEE, 0xF1, 0x04, 0xA3, 0xBA, 0xD4, 0xF3 } } } }, // EoB 1
+ { DE_DEU, kPlatformPC, { 0x00000078, 0x000002C4, { { 0x92, 0x20, 0x58, 0x5F, 0x44, 0x09, 0x0B, 0xF0, 0xDA, 0x09, 0xE2, 0x44, 0x0B, 0xB7, 0x95, 0x96 } } } }, // EoB 1
+ { EN_ANY, kPlatformPC, { 0x000000C8, 0x00000834, { { 0x18, 0xEA, 0x33, 0xB7, 0x4B, 0x72, 0x23, 0x8D, 0x0E, 0x9F, 0x4E, 0xF5, 0x09, 0xA3, 0x9C, 0xEA } } } }, // EoB 2
+ { DE_DEU, kPlatformPC, { 0x000000C8, 0x00000622, { { 0xFE, 0x1D, 0x94, 0x3A, 0x0B, 0x17, 0x89, 0xEF, 0x60, 0x18, 0xB2, 0x43, 0x7A, 0x02, 0xDB, 0x61 } } } }, // EoB 2
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBaseManWordProvider[] = {
+ { EN_ANY, kPlatformPC, { 0x000000E0, 0x00005134, { { 0x68, 0x9C, 0x19, 0x2B, 0x5F, 0x38, 0x36, 0x41, 0xA7, 0x7E, 0xB7, 0x51, 0x41, 0x60, 0x1D, 0x67 } } } }, // EoB 1
+ { DE_DEU, kPlatformPC, { 0x000000EA, 0x00005458, { { 0xEC, 0x14, 0x11, 0xE9, 0x19, 0xFD, 0xF8, 0xFC, 0xA8, 0x46, 0x3D, 0xCD, 0x56, 0x08, 0xC3, 0x4A } } } }, // EoB 1
+ { EN_ANY, kPlatformPC, { 0x0000017E, 0x00008B64, { { 0x66, 0x38, 0x09, 0x5B, 0x2E, 0x50, 0x54, 0x43, 0x1C, 0xEC, 0x56, 0x3B, 0x72, 0x39, 0xF9, 0xC3 } } } }, // EoB 2
+ { DE_DEU, kPlatformPC, { 0x0000015B, 0x00007C37, { { 0x44, 0xA3, 0x32, 0x88, 0x9F, 0x63, 0x28, 0xA0, 0xBD, 0x00, 0xF1, 0x08, 0xCA, 0xE5, 0xFE, 0x5F } } } }, // EoB 2
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBaseManPromptProvider[] = {
+ { EN_ANY, kPlatformPC, { 0x00000041, 0x000013AC, { { 0x40, 0x2B, 0xB5, 0x99, 0xEF, 0x8F, 0x3C, 0x9F, 0xB1, 0x5A, 0xBE, 0xE4, 0x80, 0x8E, 0xBB, 0x96 } } } }, // EoB 1
+ { DE_DEU, kPlatformPC, { 0x00000048, 0x000015A5, { { 0x0B, 0xB4, 0x9E, 0xAD, 0xB3, 0x56, 0x75, 0xC1, 0xAE, 0x29, 0xF7, 0xB5, 0x82, 0x14, 0xD1, 0x27 } } } }, // EoB 1
+ { EN_ANY, kPlatformPC, { 0x00000041, 0x000013AC, { { 0x40, 0x2B, 0xB5, 0x99, 0xEF, 0x8F, 0x3C, 0x9F, 0xB1, 0x5A, 0xBE, 0xE4, 0x80, 0x8E, 0xBB, 0x96 } } } }, // EoB 2
+ { DE_DEU, kPlatformPC, { 0x0000005C, 0x00001D08, { { 0x10, 0xCE, 0x2D, 0xED, 0xA9, 0xA0, 0x7C, 0xA1, 0x91, 0x3F, 0xD8, 0x43, 0x03, 0x53, 0x97, 0xCA } } } }, // EoB 2
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBaseDscMonsterFrmOffsTbl1Provider[] = {
+ { UNK_LANG, kPlatformPC, { 0x00000020, 0x00001000, { { 0x98, 0x27, 0x57, 0x25, 0x3B, 0x04, 0x7D, 0x14, 0x3A, 0xD4, 0xA2, 0x5D, 0xBA, 0x04, 0x45, 0xAC } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBaseDscMonsterFrmOffsTbl2Provider[] = {
+ { UNK_LANG, kPlatformPC, { 0x00000020, 0x00000828, { { 0x7E, 0x8A, 0x0C, 0xEB, 0x5C, 0xBC, 0x6C, 0xBD, 0xD2, 0x48, 0x08, 0xCC, 0xF7, 0x7B, 0x81, 0x03 } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBaseInvSlotXProvider[] = {
+ { UNK_LANG, kPlatformPC, { 0x00000036, 0x000010BF, { { 0x50, 0x6E, 0x67, 0x2B, 0x7D, 0x6C, 0xF2, 0x21, 0x73, 0xA2, 0xD5, 0xBB, 0xCE, 0x3B, 0x71, 0xAA } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBaseInvSlotYProvider[] = {
+ { UNK_LANG, kPlatformPC, { 0x0000001B, 0x00000A5B, { { 0x47, 0x55, 0x7D, 0x84, 0x45, 0x91, 0xC4, 0x44, 0x10, 0xD5, 0x39, 0xC4, 0xC8, 0x4F, 0x01, 0xA4 } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBaseSlotValidationFlagsProvider[] = {
+ { UNK_LANG, kPlatformPC, { 0x00000036, 0x00001F6B, { { 0x87, 0x4F, 0x9A, 0x97, 0x20, 0x20, 0xB2, 0xA6, 0xF7, 0xC2, 0x5F, 0xAA, 0x17, 0xEA, 0xB4, 0x50 } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBaseProjectileWeaponTypesProvider[] = {
+ { UNK_LANG, kPlatformPC, { 0x00000008, 0x0000061C, { { 0x05, 0x55, 0xA6, 0xD1, 0x3C, 0x12, 0x84, 0xDA, 0xA9, 0x33, 0xCF, 0x07, 0x05, 0x2A, 0xB2, 0x29 } } } }, // EOB 1
+ { UNK_LANG, kPlatformPC, { 0x0000000F, 0x00000829, { { 0x9F, 0x6A, 0x13, 0x8A, 0xA7, 0x40, 0xE8, 0x40, 0x2E, 0x87, 0x49, 0x6B, 0x67, 0xED, 0xE8, 0xCE } } } }, // EOB 2
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBaseWandTypesProvider[] = {
+ { UNK_LANG, kPlatformPC, { 0x00000007, 0x00000162, { { 0xDB, 0x5D, 0x34, 0x70, 0x41, 0xAB, 0x8F, 0x75, 0xC8, 0x61, 0x8E, 0x44, 0x82, 0xCF, 0x28, 0x03 } } } }, // EOB 1
+ { UNK_LANG, kPlatformPC, { 0x00000008, 0x00000175, { { 0x01, 0xC2, 0xF0, 0xC6, 0x1C, 0xD0, 0x14, 0xD9, 0xB8, 0xF5, 0x9C, 0xFC, 0x22, 0xE4, 0xA0, 0xA7 } } } }, // EOB 2
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBaseDrawObjPosIndexProvider[] = {
+ { UNK_LANG, kPlatformPC, { 0x00000014, 0x00000028, { { 0x44, 0x46, 0x8C, 0x94, 0x76, 0x24, 0x08, 0xC7, 0x1F, 0x1B, 0x10, 0xD7, 0xDF, 0x18, 0x6C, 0x0D } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBaseFlightObjFlipIndexProvider[] = {
+ { UNK_LANG, kPlatformPC, { 0x00000010, 0x00000008, { { 0xEB, 0xF0, 0x27, 0x7E, 0xA8, 0x09, 0x3A, 0x95, 0x3B, 0x71, 0x2A, 0x43, 0x2E, 0xCF, 0x22, 0x0B } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBaseFlightObjShpMapProvider[] = {
+ { UNK_LANG, kPlatformPC, { 0x00000058, 0x000051BD, { { 0xC3, 0xD2, 0xD1, 0xE5, 0x78, 0xEE, 0xA7, 0xAA, 0x71, 0xD1, 0xDD, 0xDF, 0x40, 0xBB, 0xAF, 0x66 } } } }, // EOB 1
+ { UNK_LANG, kPlatformPC, { 0x0000002D, 0x000025E6, { { 0x64, 0x26, 0x3D, 0xDC, 0x6C, 0x1A, 0xFC, 0x36, 0x9E, 0x5A, 0xBF, 0x64, 0xAD, 0xF4, 0xA3, 0x5D } } } }, // EOB 2
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBaseFlightObjSclIndexProvider[] = {
+ { UNK_LANG, kPlatformPC, { 0x00000048, 0x00002A0E, { { 0xAC, 0xBB, 0x7D, 0x73, 0x98, 0xF4, 0x1E, 0x4A, 0x77, 0xF0, 0x98, 0x75, 0x11, 0xBF, 0xF7, 0xD5 } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBaseBookNumbersProvider[] = {
+ { EN_ANY, kPlatformPC, { 0x00000020, 0x00000AC8, { { 0x35, 0x05, 0x37, 0x4C, 0x05, 0x74, 0x04, 0x08, 0xAD, 0xA3, 0x64, 0xBF, 0xC0, 0x67, 0xF2, 0xF7 } } } },
+ { DE_DEU, kPlatformPC, { 0x00000028, 0x00000E5D, { { 0x80, 0x98, 0x05, 0x54, 0x84, 0x90, 0xD3, 0xB3, 0x9B, 0xFB, 0x8F, 0xB9, 0xA0, 0x43, 0xAA, 0xFD } } } },
+ { EN_ANY, kPlatformPC, { 0x00000020, 0x00000AC8, { { 0x35, 0x05, 0x37, 0x4C, 0x05, 0x74, 0x04, 0x08, 0xAD, 0xA3, 0x64, 0xBF, 0xC0, 0x67, 0xF2, 0xF7 } } } },
+ { DE_DEU, kPlatformPC, { 0x00000022, 0x00000BCA, { { 0x93, 0x0E, 0xE0, 0x6D, 0xDD, 0x40, 0xBC, 0x89, 0x67, 0xBD, 0x8A, 0xCB, 0xD2, 0xCF, 0x78, 0x8D } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBaseMageSpellsListProvider[] = {
+ { EN_ANY, kPlatformPC, { 0x00000122, 0x00006304, { { 0xD7, 0x14, 0x28, 0x83, 0x04, 0xC3, 0x42, 0x5A, 0x15, 0x49, 0x91, 0x12, 0x1D, 0x49, 0x17, 0x5B } } } },
+ { DE_DEU, kPlatformPC, { 0x0000013A, 0x00007155, { { 0x94, 0x45, 0xB9, 0x15, 0x57, 0x6E, 0xC6, 0x70, 0x66, 0x5F, 0xA7, 0x90, 0xA0, 0xC7, 0xC9, 0xE9 } } } },
+ { EN_ANY, kPlatformPC, { 0x00000195, 0x00008AC0, { { 0x55, 0xB8, 0x75, 0x35, 0x09, 0x23, 0x83, 0x11, 0x22, 0xF8, 0x23, 0x1E, 0x8F, 0x08, 0x57, 0x66 } } } },
+ { DE_DEU, kPlatformPC, { 0x0000019A, 0x0000929F, { { 0xB3, 0xA0, 0x2D, 0x3B, 0xF3, 0x72, 0x9B, 0x75, 0xA3, 0xC4, 0xD8, 0x72, 0x4B, 0xDE, 0x69, 0x82 } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBaseClericSpellsListProvider[] = {
+ { EN_ANY, kPlatformPC, { 0x0000013B, 0x00006BE6, { { 0x34, 0x63, 0x0B, 0xBA, 0xED, 0xC2, 0x9B, 0x31, 0xC3, 0x65, 0x51, 0xFF, 0xEF, 0xD8, 0x25, 0x92 } } } },
+ { DE_DEU, kPlatformPC, { 0x0000016D, 0x00007E74, { { 0x6E, 0xDE, 0x28, 0xE6, 0x13, 0x3D, 0xA6, 0x42, 0x80, 0xAB, 0xE7, 0xED, 0xAD, 0xC8, 0x62, 0x48 } } } },
+ { EN_ANY, kPlatformPC, { 0x00000164, 0x000079B3, { { 0x93, 0x16, 0x25, 0xFB, 0x76, 0xFF, 0xBC, 0x70, 0x9A, 0xB7, 0x93, 0xFC, 0x2E, 0xC3, 0x61, 0x7F } } } },
+ { DE_DEU, kPlatformPC, { 0x0000018B, 0x00008BB1, { { 0x8C, 0x21, 0xED, 0xE0, 0x1F, 0xF1, 0xDB, 0x72, 0xC4, 0x46, 0x36, 0x50, 0x16, 0xD5, 0xA8, 0x68 } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBaseSpellNamesProvider[] = {
+ { EN_ANY, kPlatformPC, { 0x0000029A, 0x0000F1C8, { { 0xCA, 0xE1, 0x30, 0xDC, 0xAB, 0xD1, 0x87, 0xE8, 0x51, 0xA2, 0xA2, 0x1C, 0x23, 0x4A, 0x34, 0x58 } } } },
+ { DE_DEU, kPlatformPC, { 0x000002D3, 0x0001080D, { { 0x5F, 0xDB, 0x9E, 0x48, 0x30, 0x03, 0xE1, 0x8E, 0xC7, 0xDC, 0x98, 0x10, 0xCE, 0xA1, 0x28, 0x31 } } } },
+ { EN_ANY, kPlatformPC, { 0x00000366, 0x00013B1A, { { 0x15, 0xCB, 0x0E, 0xA9, 0x4E, 0x78, 0x30, 0x99, 0xA1, 0xCF, 0xF7, 0x05, 0xAB, 0x00, 0x66, 0x82 } } } },
+ { DE_DEU, kPlatformPC, { 0x000003BA, 0x0001626B, { { 0x0E, 0x4F, 0xF6, 0xFB, 0x78, 0x5E, 0x03, 0xE7, 0x82, 0xC4, 0xE2, 0x7B, 0xD9, 0xB2, 0xD7, 0xB2 } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBaseMagicStrings1Provider[] = {
+ { EN_ANY, kPlatformPC, { 0x00000084, 0x000029B0, { { 0xC6, 0x90, 0x19, 0x61, 0xA1, 0x66, 0xF6, 0x03, 0x7A, 0x1F, 0x10, 0x00, 0xCA, 0x8F, 0x69, 0x3B } } } },
+ { DE_DEU, kPlatformPC, { 0x0000009D, 0x000033E4, { { 0x4B, 0xCF, 0x40, 0xCE, 0x0F, 0x86, 0x98, 0x36, 0x03, 0x59, 0xFE, 0x32, 0xFA, 0x4C, 0x14, 0x75 } } } },
+ { EN_ANY, kPlatformPC, { 0x00000085, 0x000029BD, { { 0xAB, 0x22, 0x4A, 0x70, 0xBB, 0x29, 0xB8, 0xBD, 0xAF, 0xC5, 0x0D, 0x1F, 0x23, 0x38, 0xBD, 0x06 } } } },
+ { DE_DEU, kPlatformPC, { 0x0000008C, 0x00002D68, { { 0x4B, 0x0A, 0x09, 0x22, 0xF7, 0x77, 0x82, 0x4B, 0xFE, 0x0B, 0xF1, 0x8F, 0x1C, 0xEA, 0x1A, 0x0C } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBaseMagicStrings2Provider[] = {
+ { EN_ANY, kPlatformPC, { 0x00000051, 0x00001AD6, { { 0x28, 0x18, 0x2B, 0xF0, 0x0E, 0xC6, 0xEB, 0x01, 0xB0, 0x9A, 0x0A, 0x65, 0x05, 0xCB, 0x8F, 0x41 } } } },
+ { DE_DEU, kPlatformPC, { 0x0000004F, 0x00001A82, { { 0x77, 0x85, 0x17, 0x25, 0x07, 0x72, 0x4A, 0x7F, 0x4F, 0x39, 0x6C, 0xDD, 0xB6, 0x70, 0x11, 0x02 } } } },
+ { EN_ANY, kPlatformPC, { 0x00000090, 0x00002E35, { { 0x39, 0xD7, 0xA3, 0x21, 0xF0, 0xB7, 0x93, 0x9D, 0xDD, 0xEE, 0x33, 0xC2, 0x05, 0xE6, 0xE3, 0x63 } } } },
+ { DE_DEU, kPlatformPC, { 0x000000A1, 0x0000365C, { { 0x9A, 0x2D, 0xDB, 0x38, 0xB3, 0xF4, 0x0E, 0xF4, 0x36, 0x87, 0x60, 0xAE, 0xF8, 0x7E, 0xCA, 0x8A } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBaseMagicStrings3Provider[] = {
+ { EN_ANY, kPlatformPC, { 0x0000008D, 0x00002DC8, { { 0x35, 0x5E, 0xDD, 0x32, 0x2D, 0x55, 0x1E, 0xBC, 0x93, 0x49, 0x55, 0x48, 0x8F, 0xCD, 0x87, 0xEB } } } },
+ { DE_DEU, kPlatformPC, { 0x000000A8, 0x0000381C, { { 0x12, 0x95, 0x55, 0x57, 0x2B, 0xA0, 0x1A, 0x75, 0xD3, 0x43, 0xFF, 0x3E, 0x00, 0xB6, 0xEC, 0x35 } } } },
+ { EN_ANY, kPlatformPC, { 0x00000088, 0x00002CD4, { { 0xD8, 0xBA, 0x5D, 0x14, 0x92, 0x84, 0x5A, 0x07, 0xC6, 0x76, 0xDF, 0x11, 0x1D, 0x84, 0x7A, 0x98 } } } },
+ { DE_DEU, kPlatformPC, { 0x00000081, 0x00002B14, { { 0xC8, 0xB7, 0x77, 0xBC, 0x3A, 0xB6, 0xDC, 0xB7, 0x00, 0xF3, 0x06, 0xEB, 0x77, 0x10, 0x7C, 0x7E } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBaseMagicStrings4Provider[] = {
+ { EN_ANY, kPlatformPC, { 0x00000017, 0x0000071C, { { 0x96, 0x50, 0xA8, 0x08, 0x1B, 0x2D, 0x0C, 0xF6, 0x90, 0x6A, 0xE7, 0x9F, 0x65, 0xCC, 0x71, 0xA0 } } } },
+ { DE_DEU, kPlatformPC, { 0x0000001B, 0x00000840, { { 0xA2, 0xCF, 0x81, 0x3E, 0x87, 0xA8, 0x10, 0x1B, 0x44, 0x8D, 0x5B, 0x8B, 0xAE, 0x23, 0x30, 0xD3 } } } },
+ { EN_ANY, kPlatformPC, { 0x0000000C, 0x000003A5, { { 0x72, 0x64, 0xBD, 0x1C, 0xED, 0x05, 0x28, 0xFC, 0x94, 0x4B, 0x8F, 0x3C, 0x38, 0x08, 0x77, 0xED } } } },
+ { DE_DEU, kPlatformPC, { 0x00000010, 0x0000054E, { { 0xD9, 0x97, 0xA8, 0x24, 0x27, 0x7B, 0x01, 0x3F, 0x03, 0xBA, 0x2A, 0x43, 0x81, 0x8F, 0x97, 0x03 } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBaseMagicStrings6Provider[] = {
+ { EN_ANY, kPlatformPC, { 0x00000029, 0x00000DA4, { { 0x5C, 0x6F, 0xA1, 0xC2, 0x56, 0xDE, 0xFE, 0xD5, 0x01, 0xFB, 0x65, 0x00, 0x24, 0xD1, 0x49, 0x7B } } } },
+ { DE_DEU, kPlatformPC, { 0x00000032, 0x00001211, { { 0x13, 0xBC, 0xF1, 0x03, 0x49, 0xDB, 0x16, 0xA5, 0xC3, 0x7C, 0xBF, 0x14, 0x8F, 0x40, 0x07, 0x8E } } } },
+ { EN_ANY, kPlatformPC, { 0x00000030, 0x00000FF5, { { 0xE4, 0x2B, 0xB9, 0xF0, 0x26, 0x3D, 0x30, 0xCD, 0xEF, 0xCD, 0xF5, 0xC0, 0x4E, 0xA4, 0xC4, 0x92 } } } },
+ { DE_DEU, kPlatformPC, { 0x00000029, 0x00000E6D, { { 0xE1, 0xBD, 0x4B, 0x42, 0x17, 0xA2, 0xB6, 0x6C, 0xF2, 0x7F, 0xEB, 0x41, 0x2C, 0x82, 0x8C, 0x76 } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBaseMagicStrings7Provider[] = {
+ { EN_ANY, kPlatformPC, { 0x00000014, 0x00000406, { { 0xBD, 0xE1, 0x0A, 0x75, 0xD1, 0x18, 0xF7, 0x08, 0x2D, 0x2B, 0x65, 0x36, 0xA7, 0x59, 0x2E, 0x13 } } } },
+ { DE_DEU, kPlatformPC, { 0x0000000F, 0x000001E5, { { 0x1F, 0xC9, 0x46, 0x8B, 0x41, 0xAD, 0xAD, 0x2B, 0x5A, 0xA9, 0xAB, 0x94, 0x9A, 0x1E, 0x36, 0xAC } } } },
+ { EN_ANY, kPlatformPC, { 0x00000065, 0x000021AF, { { 0x76, 0x35, 0xAE, 0x1D, 0xC2, 0x54, 0x36, 0x11, 0x4D, 0x3E, 0x96, 0x11, 0xB2, 0xDC, 0x15, 0x20 } } } },
+ { DE_DEU, kPlatformPC, { 0x0000006F, 0x000026BA, { { 0xC9, 0x46, 0xD7, 0xF3, 0xF2, 0x5F, 0xF4, 0xB1, 0x22, 0xC8, 0x30, 0x16, 0x8E, 0x75, 0x4D, 0xA8 } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBaseMagicStrings8Provider[] = {
+ { EN_ANY, kPlatformPC, { 0x00000056, 0x00001C95, { { 0x7E, 0x43, 0x73, 0xEC, 0x94, 0x0D, 0xF8, 0x1B, 0xF3, 0x1A, 0x62, 0x19, 0x96, 0x6A, 0x2C, 0xB5 } } } },
+ { DE_DEU, kPlatformPC, { 0x00000061, 0x0000213B, { { 0xE2, 0x3B, 0xA7, 0xB7, 0xE6, 0xA5, 0x0D, 0x0F, 0xE0, 0x94, 0x9B, 0xAE, 0xE1, 0x11, 0x97, 0x93 } } } },
+ { EN_ANY, kPlatformPC, { 0x00000085, 0x00002C0E, { { 0x6A, 0xEC, 0xF2, 0x5F, 0xA6, 0x3F, 0xB1, 0x1A, 0x74, 0x49, 0x5A, 0x47, 0xB0, 0x7A, 0xE6, 0x99 } } } },
+ { DE_DEU, kPlatformPC, { 0x00000096, 0x0000342E, { { 0x83, 0x48, 0x3B, 0xED, 0x73, 0x02, 0x03, 0xCA, 0xA9, 0x4D, 0x40, 0x0F, 0xDE, 0x17, 0x7D, 0x40 } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBaseExpObjectTlModeProvider[] = {
+ { UNK_LANG, kPlatformPC, { 0x00000012, 0x0000000C, { { 0x98, 0x29, 0x54, 0xCD, 0xED, 0xAC, 0x7B, 0x61, 0x8D, 0x4F, 0x19, 0xE8, 0xA6, 0xB1, 0x51, 0x80 } } } },
+ EXTRACT_END_ENTRY
+};
+const ExtractEntrySearchData kEoBBaseExpObjectTblIndexProvider[] = {
+ { UNK_LANG, kPlatformPC, { 0x00000009, 0x00000005, { { 0xFE, 0xEA, 0xC4, 0x54, 0x62, 0x7E, 0x43, 0x6E, 0x89, 0x48, 0x03, 0xE7, 0x47, 0xBF, 0x7D, 0x9D } } } }, // EOB 1
+ { UNK_LANG, kPlatformPC, { 0x0000000E, 0x00000004, { { 0x63, 0x27, 0x19, 0x17, 0xBD, 0xC3, 0x8A, 0xA7, 0x1E, 0xF7, 0xD1, 0x78, 0x39, 0x3B, 0xD4, 0x4F } } } }, // EOB 2
+ EXTRACT_END_ENTRY
+};
+const ExtractEntrySearchData kEoBBaseExpObjectShpStartProvider[] = {
+ { UNK_LANG, kPlatformPC, { 0x00000004, 0x00000034, { { 0x27, 0xC5, 0x09, 0x97, 0x8E, 0xD4, 0xF1, 0x8D, 0x77, 0xEB, 0x1D, 0x34, 0x55, 0xB2, 0x48, 0x38 } } } },
+ EXTRACT_END_ENTRY
+};
+const ExtractEntrySearchData kEoBBaseExpObjectTbl1Provider[] = {
+ { UNK_LANG, kPlatformPC, { 0x0000000D, 0x0000005D, { { 0x49, 0xC4, 0x47, 0x55, 0xDC, 0x25, 0x08, 0x03, 0x3D, 0x23, 0xAD, 0x09, 0x5F, 0x9C, 0x34, 0x06 } } } },
+ EXTRACT_END_ENTRY
+};
+const ExtractEntrySearchData kEoBBaseExpObjectTbl2Provider[] = {
+ { UNK_LANG, kPlatformPC, { 0x0000000A, 0x0000005C, { { 0xAB, 0x6A, 0x97, 0x35, 0xCC, 0x13, 0xC4, 0x17, 0x0B, 0xF2, 0xD3, 0xFD, 0xA2, 0x1C, 0x6C, 0xA8 } } } },
+ EXTRACT_END_ENTRY
+};
+const ExtractEntrySearchData kEoBBaseExpObjectTbl3Provider[] = {
+ { UNK_LANG, kPlatformPC, { 0x0000000B, 0x00000032, { { 0x59, 0x23, 0xB9, 0xBE, 0x0E, 0xFA, 0xEB, 0xDD, 0x82, 0x68, 0x5B, 0xB0, 0xBE, 0x9B, 0x1D, 0x8E } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBaseExpObjectYProvider[] = {
+ { UNK_LANG, kPlatformPC, { 0x00000008, 0x0000016C, { { 0xCF, 0x5B, 0x04, 0xAB, 0x1A, 0xAF, 0xDD, 0x56, 0xAC, 0xF6, 0x23, 0x86, 0x33, 0x06, 0x5A, 0xC6 } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBaseSparkDefStepsProvider[] = {
+ { UNK_LANG, kPlatformPC, { 0x00000008, 0x000002FD, { { 0xB5, 0x6F, 0x31, 0x5F, 0xC6, 0x47, 0xE9, 0x23, 0x0E, 0x73, 0xBF, 0x77, 0xC7, 0xEE, 0xDB, 0x27 } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBaseSparkDefSubStepsProvider[] = {
+ { UNK_LANG, kPlatformPC, { 0x00000004, 0x000000FF, { { 0x18, 0x27, 0x73, 0x45, 0x26, 0x58, 0x81, 0x82, 0x70, 0x86, 0x7A, 0x0D, 0xDE, 0xC1, 0x08, 0x52 } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBaseSparkDefShiftProvider[] = {
+ { UNK_LANG, kPlatformPC, { 0x00000004, 0x0000000C, { { 0xCC, 0xDC, 0x78, 0xF9, 0xFE, 0x88, 0xF3, 0x87, 0xFD, 0x08, 0xE8, 0x8A, 0x38, 0xD5, 0x4C, 0x53 } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBaseSparkDefAddProvider[] = {
+ { UNK_LANG, kPlatformPC, { 0x00000008, 0x0000007F, { { 0x7F, 0x86, 0x2E, 0x14, 0xDB, 0x36, 0xED, 0x99, 0xD9, 0xCE, 0xAF, 0x11, 0xC2, 0x89, 0x21, 0x6B } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBaseSparkDefXProvider[] = {
+ { UNK_LANG, kPlatformPC, { 0x0000000C, 0x000000A5, { { 0x77, 0xD7, 0xE0, 0x2D, 0xD4, 0x25, 0x94, 0x6E, 0x59, 0x3B, 0xAF, 0x9B, 0x16, 0x4F, 0x6D, 0x4C } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBaseSparkDefYProvider[] = {
+ { UNK_LANG, kPlatformPC, { 0x00000006, 0x00000138, { { 0xB9, 0xA2, 0x72, 0x01, 0x2A, 0xD7, 0x61, 0xAB, 0x02, 0x57, 0x87, 0xC8, 0x86, 0x83, 0xDF, 0xB3 } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBaseSparkOfFlags1Provider[] = {
+ { UNK_LANG, kPlatformPC, { 0x0000002C, 0x00000BF4, { { 0x94, 0x8C, 0x1B, 0x77, 0xBF, 0x3A, 0x51, 0x17, 0x89, 0x16, 0xD0, 0x74, 0x95, 0xBD, 0x85, 0x98 } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBaseSparkOfFlags2Provider[] = {
+ { UNK_LANG, kPlatformPC, { 0x00000040, 0x000003FC, { { 0x40, 0x13, 0x5A, 0x9D, 0xBD, 0x29, 0x2E, 0x9C, 0xC1, 0xE7, 0xD4, 0xC9, 0x26, 0xFA, 0xF2, 0x70 } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBaseSparkOfShiftProvider[] = {
+ { UNK_LANG, kPlatformPC, { 0x00000010, 0x000000F0, { { 0xC5, 0xC8, 0x91, 0x7E, 0x78, 0x2F, 0xF1, 0xE5, 0xE0, 0x06, 0xB2, 0x39, 0xDC, 0x0D, 0x7A, 0x5F } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBaseSparkOfXProvider[] = {
+ { UNK_LANG, kPlatformPC, { 0x00000010, 0x00000528, { { 0x58, 0xE6, 0x24, 0x6A, 0xD3, 0xA4, 0xEF, 0x58, 0x4A, 0x9C, 0x32, 0x31, 0x4C, 0x61, 0xBC, 0x1C } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBaseSparkOfYProvider[] = {
+ { UNK_LANG, kPlatformPC, { 0x00000010, 0x000002D4, { { 0x74, 0x31, 0xFE, 0x7C, 0x38, 0x16, 0x0C, 0x05, 0x64, 0xAB, 0x8A, 0x69, 0xEA, 0x66, 0x29, 0x2F } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBaseSpellPropertiesProvider[] = {
+ { UNK_LANG, kPlatformPC, { 0x000003EF, 0x0000BE7A, { { 0x10, 0xEA, 0x14, 0x26, 0xE2, 0xFC, 0xA1, 0xCB, 0xD9, 0x80, 0xFE, 0x9F, 0x69, 0x58, 0x4A, 0xCA } } } },
+ { UNK_LANG, kPlatformPC, { 0x000003EF, 0x00008FCE, { { 0xC9, 0x36, 0xDD, 0x7B, 0x05, 0x6E, 0x92, 0xBA, 0x2B, 0x39, 0x87, 0xA7, 0x3A, 0x7E, 0xB0, 0xAD } } } },
+ { UNK_LANG, kPlatformPC, { 0x000006D6, 0x0000CA78, { { 0xEB, 0x3B, 0x9F, 0xFD, 0x4E, 0x3F, 0x5C, 0xDE, 0xC6, 0xBA, 0xFE, 0x83, 0xB4, 0x10, 0x6D, 0x95 } } } },
+ { UNK_LANG, kPlatformPC, { 0x000006D6, 0x0000EC32, { { 0x52, 0xAE, 0x4D, 0xC2, 0x24, 0xC8, 0xD3, 0xBE, 0x09, 0x45, 0x98, 0x38, 0x17, 0x7D, 0xFF, 0xE4 } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBaseMagicFlightPropsProvider[] = {
+ { UNK_LANG, kPlatformPC, { 0x00000060, 0x0000166F, { { 0x38, 0x30, 0xCA, 0x07, 0x64, 0xBA, 0xC4, 0xA4, 0x4F, 0x75, 0xB4, 0x84, 0x3A, 0x92, 0xFD, 0xE3 } } } },
+ { UNK_LANG, kPlatformPC, { 0x00000038, 0x00000DDC, { { 0x23, 0x32, 0x8D, 0x34, 0x4F, 0x72, 0x37, 0xE1, 0x0C, 0x1B, 0x47, 0x17, 0x5D, 0xDF, 0xDB, 0xF5 } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBaseTurnUndeadEffectProvider[] = {
+ { UNK_LANG, kPlatformPC, { 0x0000008C, 0x00002E8B, { { 0x96, 0x15, 0x61, 0x12, 0x43, 0xCF, 0x3A, 0x84, 0x1A, 0x89, 0xB5, 0x32, 0x0D, 0xB3, 0x20, 0x67 } } } },
+
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBaseBurningHandsDestProvider[] = {
+ { UNK_LANG, kPlatformPC, { 0x00000008, 0x0000000C, { { 0x61, 0xD7, 0xAB, 0xE1, 0x56, 0x54, 0x51, 0x5B, 0xD9, 0x59, 0x2D, 0x3D, 0xAE, 0xA4, 0x49, 0x31 } } } }, // EOB1
+ { UNK_LANG, kPlatformPC, { 0x00000020, 0x0000003E, { { 0xA5, 0x8C, 0xCA, 0x13, 0xED, 0x0F, 0xB7, 0xA2, 0xD7, 0x9C, 0xCD, 0x11, 0x65, 0x11, 0x4B, 0xD8 } } } }, // EOB2
+
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBaseConeOfColdDest1Provider[] = {
+ { UNK_LANG, kPlatformPC, { 0x00000007, 0x00000500, { { 0x48, 0xF1, 0xFE, 0x48, 0xEC, 0x64, 0x17, 0x51, 0x5C, 0x9A, 0x91, 0x35, 0x95, 0xC3, 0x73, 0x8E } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBaseConeOfColdDest2Provider[] = {
+ { UNK_LANG, kPlatformPC, { 0x00000007, 0x00000210, { { 0xBA, 0x62, 0xA0, 0x4F, 0x50, 0x0C, 0x02, 0xC3, 0xAD, 0x7C, 0x39, 0x63, 0x5F, 0x41, 0xB4, 0xFB } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBaseConeOfColdDest3Provider[] = {
+ { UNK_LANG, kPlatformPC, { 0x00000007, 0x00000200, { { 0xA0, 0x1F, 0xAC, 0x3A, 0x2D, 0x25, 0x1F, 0x5C, 0xD2, 0x04, 0xAC, 0xAB, 0x97, 0x8B, 0x61, 0xD7 } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBaseConeOfColdDest4Provider[] = {
+ { UNK_LANG, kPlatformPC, { 0x00000007, 0x000004F0, { { 0xB3, 0x9A, 0x2B, 0x3A, 0x51, 0x24, 0x95, 0xBE, 0xDE, 0x0F, 0xD5, 0xE9, 0xE9, 0x21, 0x96, 0x04 } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBaseConeOfColdGfxTblProvider[] = {
+ { UNK_LANG, kPlatformPC, { 0x00000010, 0x0000003E, { { 0x0A, 0xBA, 0xFD, 0x3F, 0xD8, 0x49, 0x3F, 0xD2, 0x26, 0x1B, 0x19, 0x53, 0x4F, 0x84, 0xB9, 0x4F } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoB1MainMenuStringsProvider[] = {
+ { EN_ANY, kPlatformUnknown, { 0x00000037, 0x00000D79, { { 0x1D, 0x72, 0x7F, 0x8F, 0xEB, 0x4A, 0xBF, 0x82, 0xB7, 0xB5, 0x9D, 0xB0, 0x7B, 0xDA, 0xEC, 0xEE } } } },
+ { DE_DEU, kPlatformUnknown, { 0x00000034, 0x00000C6F, { { 0xF2, 0x5F, 0xBE, 0xFB, 0x27, 0x1C, 0x91, 0x33, 0x25, 0x09, 0xC1, 0xA0, 0x27, 0x89, 0xD7, 0xD5 } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoB1BonusStringsProvider[] = {
+ { EN_ANY, kPlatformUnknown, { 0x00000093, 0x000031B6, { { 0xC1, 0x54, 0x1D, 0x02, 0x4A, 0x35, 0x7F, 0x5D, 0x84, 0x2D, 0x2C, 0x9C, 0x06, 0x97, 0x29, 0x8D } } } },
+ { DE_DEU, kPlatformUnknown, { 0x00000093, 0x000031CD, { { 0x3E, 0x0F, 0x52, 0x02, 0xC7, 0x9E, 0x83, 0xB3, 0xB1, 0xAB, 0x03, 0x3A, 0x18, 0xE2, 0x87, 0x2E } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoB1IntroFilesOpeningProvider[] = {
+ { UNK_LANG, kPlatformPC, { 0x0000003F, 0x00001044, { { 0xF5, 0x8C, 0xC8, 0x39, 0x38, 0xBB, 0x0B, 0xCA, 0x34, 0x38, 0x1D, 0x11, 0x46, 0x91, 0xEF, 0x7E } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoB1IntroFilesTowerProvider[] = {
+ { UNK_LANG, kPlatformPC, { 0x0000001A, 0x000006E6, { { 0xBD, 0x06, 0x3B, 0x7D, 0x24, 0x79, 0xD6, 0xC2, 0xFA, 0xDA, 0x31, 0x15, 0x3E, 0xE2, 0x75, 0xF8 } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoB1IntroFilesOrbProvider[] = {
+ { UNK_LANG, kPlatformPC, { 0x00000015, 0x00000565, { { 0xA7, 0x91, 0x97, 0x5B, 0x29, 0xE8, 0x27, 0x90, 0xB3, 0x8F, 0xD5, 0x13, 0x77, 0x4A, 0x93, 0x37 } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoB1IntroFilesWdEntryProvider[] = {
+ { UNK_LANG, kPlatformPC, { 0x0000002C, 0x00000B42, { { 0x5C, 0xDF, 0xB1, 0x2A, 0x83, 0x03, 0x73, 0x47, 0x1E, 0x29, 0x7C, 0x16, 0x2E, 0x5D, 0x0F, 0xA4 } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoB1IntroFilesKingProvider[] = {
+ { UNK_LANG, kPlatformPC, { 0x00000016, 0x000005AE, { { 0xB5, 0xB5, 0x80, 0xD3, 0xC0, 0xF4, 0x9F, 0xE1, 0x12, 0x3C, 0xCB, 0xD6, 0xF2, 0x7F, 0x15, 0x5B } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoB1IntroFilesHandsProvider[] = {
+ { UNK_LANG, kPlatformPC, { 0x0000000A, 0x0000027C, { { 0x90, 0xC7, 0x36, 0xE6, 0x7D, 0x6D, 0xCB, 0x77, 0xA0, 0x03, 0x45, 0x48, 0x46, 0xF3, 0x80, 0xC8 } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoB1IntroFilesWdExitProvider[] = {
+ { UNK_LANG, kPlatformPC, { 0x00000033, 0x00000D2A, { { 0xA8, 0xF0, 0x36, 0x0E, 0x37, 0xC6, 0xCC, 0xDB, 0x9B, 0xB8, 0x52, 0x64, 0x02, 0x1E, 0x9D, 0x1C } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoB1IntroFilesTunnelProvider[] = {
+ { UNK_LANG, kPlatformPC, { 0x0000001A, 0x000006E2, { { 0xA1, 0xDD, 0x20, 0x50, 0x7A, 0xB6, 0x89, 0x67, 0x13, 0xAA, 0x47, 0x6B, 0xC0, 0xA0, 0x8A, 0xFD } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoB1IntroOpeningFrmDelayProvider[] = {
+ { UNK_LANG, kPlatformPC, { 0x0000000A, 0x000001E0, { { 0xDA, 0xE3, 0x06, 0xA2, 0x41, 0xF6, 0x5A, 0x6A, 0xBD, 0x0B, 0xA6, 0x09, 0x69, 0x03, 0x1D, 0x2C } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoB1IntroWdEncodeXProvider[] = {
+ { UNK_LANG, kPlatformPC, { 0x0000001F, 0x000001BB, { { 0x00, 0x50, 0x8E, 0xF5, 0x51, 0xA6, 0xF5, 0x57, 0x0D, 0x55, 0x6C, 0x14, 0x62, 0xCD, 0xD0, 0x7E } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoB1IntroWdEncodeYProvider[] = {
+ { UNK_LANG, kPlatformPC, { 0x0000001F, 0x0000000B, { { 0x39, 0x38, 0x02, 0xCE, 0x9D, 0x89, 0x1E, 0xBF, 0x32, 0x86, 0xA0, 0x79, 0xA4, 0xBE, 0xC5, 0x81 } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoB1IntroWdEncodeWHProvider[] = {
+ { UNK_LANG, kPlatformPC, { 0x0000001F, 0x00000027, { { 0xA8, 0x6C, 0x13, 0x2B, 0x4C, 0x26, 0x38, 0x3D, 0xDA, 0xC2, 0x90, 0xB3, 0x97, 0xA9, 0x45, 0x84 } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoB1IntroWdDsXProvider[] = {
+ { UNK_LANG, kPlatformPC, { 0x0000003E, 0x0000104A, { { 0xAC, 0x1F, 0xA6, 0x20, 0xD0, 0x02, 0xF0, 0x9D, 0x75, 0x93, 0x6C, 0x12, 0x0A, 0x76, 0x1B, 0x3F } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoB1IntroWdDsYProvider[] = {
+ { UNK_LANG, kPlatformPC, { 0x0000001F, 0x00000655, { { 0xF3, 0xF7, 0x65, 0xEC, 0xEA, 0x5C, 0x08, 0xCF, 0xAD, 0x48, 0x35, 0xA2, 0x5B, 0x82, 0xB0, 0xC5 } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoB1IntroTvlX1Provider[] = {
+ { UNK_LANG, kPlatformPC, { 0x00000006, 0x00000027, { { 0x7F, 0x14, 0x7D, 0x8C, 0x20, 0x49, 0xDB, 0xC3, 0x31, 0x1A, 0xC3, 0x95, 0xA4, 0x8C, 0x96, 0xDC } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoB1IntroTvlY1Provider[] = {
+ { UNK_LANG, kPlatformPC, { 0x00000006, 0x000000EC, { { 0x29, 0xB4, 0x8D, 0xE1, 0xDF, 0x36, 0x39, 0x27, 0xC8, 0xF6, 0x32, 0x1A, 0x3B, 0x74, 0xA1, 0x4F } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoB1IntroTvlX2Provider[] = {
+ { UNK_LANG, kPlatformPC, { 0x00000006, 0x00000051, { { 0x51, 0x33, 0x0A, 0x55, 0x76, 0xA2, 0x91, 0xDA, 0x59, 0xD6, 0x09, 0xD9, 0x3D, 0xD4, 0xB8, 0xFE } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoB1IntroTvlY2Provider[] = {
+ { UNK_LANG, kPlatformPC, { 0x00000006, 0x0000016A, { { 0xD5, 0xA3, 0xF6, 0x12, 0x90, 0x87, 0xF2, 0xC7, 0x6A, 0x22, 0x77, 0xB5, 0x48, 0xB2, 0xCB, 0xCA } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoB1IntroTvlWProvider[] = {
+ { UNK_LANG, kPlatformPC, { 0x00000006, 0x0000004E, { { 0xCF, 0xC7, 0xA8, 0x59, 0x6A, 0x5B, 0x35, 0x7F, 0xC9, 0xEC, 0x59, 0x7E, 0x88, 0x31, 0x32, 0xA6 } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoB1IntroTvlHProvider[] = {
+ { UNK_LANG, kPlatformPC, { 0x00000006, 0x0000013D, { { 0x26, 0x7B, 0x3D, 0x5F, 0x64, 0x97, 0xF9, 0x1B, 0xB6, 0x65, 0x99, 0x95, 0x0A, 0x98, 0x38, 0x92 } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoB1DoorShapeDefsProvider[] = {
+ { UNK_LANG, kPlatformPC, { 0x00000060, 0x00000F8A, { { 0x95, 0x53, 0x1B, 0x07, 0x64, 0x81, 0x0E, 0x04, 0xC0, 0xDA, 0xB5, 0x74, 0x57, 0x04, 0x10, 0xE2 } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoB1DoorSwitchShapeDefsProvider[] = {
+ { UNK_LANG, kPlatformPC, { 0x00000060, 0x0000119E, { { 0xA4, 0xE6, 0x96, 0x36, 0x59, 0x05, 0xB8, 0x57, 0xF4, 0x6D, 0x79, 0x1D, 0x29, 0x52, 0xA0, 0xEE } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoB1DoorSwitchCoordsProvider[] = {
+ { UNK_LANG, kPlatformPC, { 0x00000030, 0x000007F7, { { 0x85, 0x20, 0x98, 0x20, 0xE1, 0xD6, 0xA5, 0xBD, 0x9E, 0x59, 0x63, 0x6A, 0xEF, 0xEF, 0x80, 0x19 } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoB1MonsterPropertiesProvider[] = {
+ { UNK_LANG, kPlatformPC, { 0x00000252, 0x000038E5, { { 0x5E, 0xD7, 0xEF, 0x3B, 0xD5, 0xDA, 0x2A, 0x09, 0x78, 0xF6, 0xD8, 0x57, 0x68, 0xB4, 0x90, 0xCA } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoB1EnemyMageSpellListProvider[] = {
+ { UNK_LANG, kPlatformPC, { 0x0000000A, 0x0000000F, { { 0x01, 0x1B, 0x9C, 0x51, 0xC9, 0xA2, 0x10, 0xBB, 0xA7, 0x82, 0xD4, 0x91, 0x7E, 0x84, 0x54, 0x93 } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoB1EnemyMageSfxProvider[] = {
+ { UNK_LANG, kPlatformPC, { 0x0000000A, 0x0000029B, { { 0xA2, 0x9F, 0x2E, 0xDE, 0x15, 0x23, 0x78, 0xDD, 0x26, 0x98, 0x6E, 0xA3, 0x77, 0xEA, 0xB5, 0x80 } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoB1BeholderSpellListProvider[] = {
+ { UNK_LANG, kPlatformPC, { 0x00000004, 0x00000079, { { 0x8E, 0x13, 0x54, 0x9D, 0x54, 0xF6, 0xC9, 0x6E, 0x10, 0xF1, 0xC0, 0xE9, 0x66, 0xDD, 0x95, 0xED } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoB1BeholderSfxProvider[] = {
+ { UNK_LANG, kPlatformPC, { 0x00000004, 0x000000F5, { { 0xA9, 0x90, 0x41, 0x0D, 0xB5, 0xE0, 0x28, 0xFD, 0x0A, 0xC3, 0xF9, 0xEC, 0xC8, 0x47, 0xC1, 0x57 } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoB1TurnUndeadStringProvider[] = {
+ { EN_ANY, kPlatformUnknown, { 0x00000027, 0x00000BF2, { { 0x43, 0x0A, 0x1E, 0xEE, 0x84, 0xD6, 0xD6, 0x87, 0x20, 0x9F, 0x15, 0x22, 0x9B, 0x65, 0x24, 0xDB } } } },
+ { DE_DEU, kPlatformUnknown, { 0x00000030, 0x00000F48, { { 0xDA, 0x59, 0xEC, 0xC1, 0x9B, 0xCF, 0x90, 0x4A, 0x93, 0x3E, 0xE5, 0x26, 0x20, 0x8B, 0x74, 0x92 } } } },
+
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoB1CgaMappingDefaultProvider[] = {
+ { UNK_LANG, kPlatformPC, { 0x00000020, 0x0000002C, { { 0x7E, 0x1C, 0x75, 0xC3, 0x8E, 0xF7, 0x56, 0x62, 0x9B, 0xB6, 0xF4, 0x3A, 0x21, 0x03, 0xFA, 0xF5 } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoB1CgaMappingAltProvider[] = {
+ { UNK_LANG, kPlatformPC, { 0x00000020, 0x00000030, { { 0x2A, 0x8C, 0xF6, 0xD7, 0x87, 0xFA, 0x7B, 0x22, 0x28, 0x2A, 0x50, 0xE2, 0x26, 0x7B, 0xC7, 0x44 } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoB1CgaMappingInvProvider[] = {
+ { UNK_LANG, kPlatformPC, { 0x00000020, 0x0000002E, { { 0x3A, 0x06, 0xBF, 0x0C, 0xD4, 0xD0, 0x15, 0x1F, 0xB5, 0xC5, 0x49, 0xFD, 0x21, 0xE1, 0xE1, 0x66 } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoB1CgaMappingItemsLProvider[] = {
+ { UNK_LANG, kPlatformPC, { 0x00000020, 0x0000002A, { { 0xE0, 0x85, 0xA1, 0x3A, 0x3D, 0xC9, 0xF8, 0x56, 0x17, 0x0A, 0xD8, 0x44, 0x56, 0xDF, 0x3C, 0x57 } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoB1CgaMappingItemsSProvider[] = {
+ { UNK_LANG, kPlatformPC, { 0x00000020, 0x00000036, { { 0x2E, 0x6F, 0xD4, 0x2E, 0xB2, 0x84, 0xB2, 0xC3, 0x36, 0x88, 0x80, 0xC1, 0x67, 0x5A, 0xEB, 0x60 } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoB1CgaMappingThrownProvider[] = {
+ { UNK_LANG, kPlatformPC, { 0x00000020, 0x00000030, { { 0x0C, 0x3D, 0x1E, 0xAB, 0x0B, 0x25, 0x9F, 0x78, 0xE6, 0xB1, 0x52, 0x79, 0x0F, 0x96, 0x33, 0x97 } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoB1CgaMappingIconsProvider[] = {
+ { UNK_LANG, kPlatformPC, { 0x00000020, 0x00000039, { { 0x99, 0x50, 0x1A, 0xE1, 0xF3, 0x52, 0xC3, 0x5A, 0x4E, 0xBD, 0x03, 0x74, 0x2C, 0x39, 0xCA, 0x71 } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoB1CgaMappingDecoProvider[] = {
+ { UNK_LANG, kPlatformPC, { 0x00000020, 0x00000035, { { 0xA5, 0x17, 0xED, 0xEE, 0x02, 0x87, 0x8C, 0x9D, 0xAC, 0x96, 0xC6, 0x07, 0xB0, 0x8E, 0x5D, 0xE3 } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoB1CgaLevelMappingIndexProvider[] = {
+ { UNK_LANG, kPlatformPC, { 0x0000000C, 0x00000013, { { 0x48, 0x5D, 0xDF, 0x8F, 0xFD, 0x5D, 0xA0, 0xB0, 0x00, 0xD8, 0xB3, 0x09, 0x90, 0x5D, 0x13, 0x3F } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoB1CgaMappingLevel0Provider[] = {
+ { UNK_LANG, kPlatformPC, { 0x00000020, 0x00000035, { { 0xC2, 0x4D, 0x2F, 0x0A, 0xB0, 0x3E, 0x46, 0x80, 0xD1, 0xEE, 0x32, 0x5F, 0xBA, 0x5C, 0xCC, 0x7A } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoB1CgaMappingLevel1Provider[] = {
+ { UNK_LANG, kPlatformPC, { 0x00000020, 0x00000030, { { 0x94, 0x8E, 0xAE, 0x12, 0xB5, 0x68, 0xCD, 0x43, 0x95, 0xD2, 0x01, 0x21, 0x0C, 0xA1, 0x34, 0xF5 } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoB1CgaMappingLevel2Provider[] = {
+ { UNK_LANG, kPlatformPC, { 0x00000020, 0x00000030, { { 0x20, 0x6F, 0x9F, 0x57, 0x0C, 0xFD, 0xDA, 0x5C, 0xA0, 0x1D, 0x28, 0xB4, 0x88, 0x24, 0x68, 0x68 } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoB1CgaMappingLevel3Provider[] = {
+ { UNK_LANG, kPlatformPC, { 0x00000020, 0x00000030, { { 0x44, 0x95, 0x9A, 0x69, 0x70, 0xB2, 0x63, 0xB6, 0xFB, 0xD0, 0xFF, 0xD9, 0xF0, 0xCD, 0xD4, 0x75 } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoB1CgaMappingLevel4Provider[] = {
+ { UNK_LANG, kPlatformPC, { 0x00000020, 0x00000031, { { 0xEA, 0xC4, 0x01, 0xC0, 0x21, 0xFE, 0x66, 0xDD, 0xD4, 0x83, 0xC1, 0x2C, 0x09, 0xD3, 0xD0, 0x97 } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoB1NpcShpDataProvider[] = {
+ { UNK_LANG, kPlatformPC, { 0x0000004C, 0x00000A42, { { 0x70, 0x21, 0x85, 0x8C, 0xD4, 0x04, 0xAA, 0x20, 0x1D, 0x0E, 0x9D, 0xB7, 0x74, 0x58, 0xCC, 0x0C } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoB1NpcSubShpIndex1Provider[] = {
+ { UNK_LANG, kPlatformPC, { 0x00000006, 0x00000035, { { 0x9A, 0x83, 0xF9, 0xA4, 0x27, 0xBA, 0xFC, 0xD2, 0xDE, 0x03, 0x65, 0xF2, 0xFA, 0x37, 0xDA, 0xF1 } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoB1NpcSubShpIndex2Provider[] = {
+ { UNK_LANG, kPlatformPC, { 0x00000006, 0x00000051, { { 0x7E, 0xAC, 0x0E, 0x54, 0x59, 0x5D, 0xF6, 0x53, 0x03, 0x22, 0x1D, 0xC7, 0xFC, 0x16, 0xC8, 0x88 } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoB1NpcSubShpYProvider[] = {
+ { UNK_LANG, kPlatformPC, { 0x00000006, 0x00000143, { { 0xC1, 0xED, 0x93, 0x5E, 0x84, 0xCE, 0x48, 0xCF, 0x4C, 0xF3, 0x9C, 0x93, 0xBF, 0xFE, 0xB8, 0x6F } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoB1Npc0StringsProvider[] = {
+ { EN_ANY, kPlatformUnknown, { 0x00000044, 0x000016E2, { { 0x7C, 0x28, 0x72, 0xC9, 0x57, 0xF5, 0xAB, 0x02, 0xD1, 0x42, 0xE8, 0xA3, 0xF9, 0x33, 0x70, 0xEE } } } },
+ { DE_DEU, kPlatformUnknown, { 0x00000050, 0x00001B13, { { 0x69, 0x05, 0xEB, 0xB6, 0x86, 0x81, 0xAC, 0x09, 0x53, 0x35, 0x4D, 0x55, 0xF3, 0x13, 0x6F, 0xC0 } } } },
+
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoB1Npc11StringsProvider[] = {
+ { EN_ANY, kPlatformUnknown, { 0x0000001B, 0x00000928, { { 0x86, 0x08, 0x95, 0x6B, 0xBF, 0x12, 0x2D, 0xF9, 0x62, 0x25, 0xD9, 0xAE, 0x25, 0x10, 0xDF, 0xDC } } } },
+ { DE_DEU, kPlatformUnknown, { 0x0000001A, 0x000008DB, { { 0xBD, 0xBB, 0x48, 0x8E, 0x04, 0x7D, 0xE4, 0x78, 0xBB, 0x59, 0x6E, 0x86, 0xE1, 0x06, 0x27, 0x50 } } } },
+
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoB1Npc12StringsProvider[] = {
+ { EN_ANY, kPlatformUnknown, { 0x00000016, 0x0000079C, { { 0x22, 0x57, 0x3A, 0x9C, 0x7C, 0xDB, 0x55, 0xD0, 0x9C, 0x84, 0x28, 0xA6, 0x9D, 0x40, 0x38, 0x6E } } } },
+ { DE_DEU, kPlatformUnknown, { 0x00000014, 0x000006ED, { { 0x88, 0x1C, 0x09, 0x61, 0x5D, 0x9D, 0xDE, 0x8A, 0x54, 0x1C, 0x40, 0xCF, 0x28, 0x2B, 0x52, 0x9D } } } },
+
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoB1Npc21StringsProvider[] = {
+ { EN_ANY, kPlatformUnknown, { 0x00000014, 0x000006FD, { { 0x55, 0x77, 0x2F, 0xB0, 0xB3, 0x2D, 0x81, 0x29, 0xDE, 0x71, 0x83, 0x41, 0x06, 0x5B, 0x72, 0x21 } } } },
+ { DE_DEU, kPlatformUnknown, { 0x00000015, 0x00000748, { { 0x3E, 0x15, 0x27, 0xFD, 0x76, 0xFB, 0x14, 0x8C, 0xF6, 0x14, 0x3E, 0x20, 0x0A, 0x04, 0xF5, 0x32 } } } },
+
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoB1Npc22StringsProvider[] = {
+ { EN_ANY, kPlatformUnknown, { 0x0000000F, 0x000004D4, { { 0xE5, 0x97, 0x06, 0x45, 0x6A, 0xAC, 0x96, 0x6D, 0x0A, 0xC9, 0xDF, 0x8F, 0x96, 0x2D, 0x01, 0x5D } } } },
+ { DE_DEU, kPlatformUnknown, { 0x0000000D, 0x00000439, { { 0x87, 0xCB, 0x17, 0xD2, 0xC8, 0x7F, 0x34, 0xDA, 0x82, 0x30, 0xB2, 0x68, 0xB0, 0x10, 0xD9, 0x52 } } } },
+
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoB1Npc31StringsProvider[] = {
+ { EN_ANY, kPlatformUnknown, { 0x00000011, 0x00000597, { { 0x5C, 0xEB, 0x0A, 0xE6, 0xB1, 0x37, 0x0E, 0x8F, 0x14, 0xB4, 0x68, 0x86, 0xE5, 0xD2, 0xDE, 0xC7 } } } },
+ { DE_DEU, kPlatformUnknown, { 0x00000012, 0x00000603, { { 0x8E, 0x68, 0x55, 0xCD, 0x29, 0x1E, 0x3C, 0x06, 0x7B, 0x97, 0xE1, 0x07, 0x49, 0x09, 0xF0, 0x57 } } } },
+
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoB1Npc32StringsProvider[] = {
+ { EN_ANY, kPlatformUnknown, { 0x00000020, 0x00000AE4, { { 0xED, 0x09, 0x04, 0xEC, 0xE3, 0x43, 0xDA, 0xEE, 0x5D, 0x78, 0x32, 0x63, 0x68, 0xFC, 0x4F, 0x9E } } } },
+ { DE_DEU, kPlatformUnknown, { 0x00000020, 0x00000B13, { { 0x87, 0x40, 0x88, 0xA5, 0xE2, 0x6F, 0x83, 0xBC, 0x99, 0x2B, 0xD3, 0xF5, 0x8D, 0x6B, 0x6E, 0x7D } } } },
+
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoB1Npc4StringsProvider[] = {
+ { EN_ANY, kPlatformUnknown, { 0x0000000D, 0x0000043C, { { 0x2C, 0xE7, 0xE5, 0xAA, 0xF3, 0x50, 0xA8, 0x6D, 0xC2, 0xC6, 0x88, 0xFE, 0x12, 0x96, 0xFE, 0x54 } } } },
+ { DE_DEU, kPlatformUnknown, { 0x00000014, 0x00000720, { { 0xF8, 0x58, 0x9A, 0xDB, 0xE5, 0x3F, 0x67, 0x53, 0x1F, 0x27, 0x2E, 0x8D, 0x6E, 0xAD, 0x45, 0xF5 } } } },
+
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoB1Npc5StringsProvider[] = {
+ { EN_ANY, kPlatformUnknown, { 0x00000021, 0x00000ABC, { { 0xF1, 0xB5, 0x9E, 0x51, 0x9E, 0xF8, 0x84, 0x95, 0x55, 0x55, 0xE7, 0xDF, 0x36, 0xE1, 0x78, 0x9A } } } },
+ { DE_DEU, kPlatformUnknown, { 0x0000001D, 0x00000A8C, { { 0x4A, 0xAE, 0x5B, 0x3B, 0xAD, 0x18, 0x91, 0x3F, 0xC9, 0x5A, 0x82, 0x5D, 0xA7, 0x06, 0x1A, 0xAE } } } },
+
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoB1Npc6StringsProvider[] = {
+ { EN_ANY, kPlatformUnknown, { 0x00000011, 0x00000612, { { 0x1B, 0xE2, 0x23, 0xD9, 0x00, 0x5C, 0xB9, 0x54, 0xCE, 0xA7, 0x6A, 0x51, 0xF6, 0xBB, 0x8A, 0xC9 } } } },
+ { DE_DEU, kPlatformUnknown, { 0x00000012, 0x00000647, { { 0x6C, 0x3F, 0xE2, 0xD0, 0xB0, 0x75, 0x2D, 0x73, 0xEE, 0x6F, 0x17, 0x74, 0xAA, 0x7D, 0xA2, 0x21 } } } },
+
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoB1Npc7StringsProvider[] = {
+ { EN_ANY, kPlatformUnknown, { 0x00000018, 0x00000777, { { 0x60, 0xB4, 0x17, 0x72, 0x89, 0x87, 0x47, 0xE3, 0xD9, 0xC3, 0x59, 0x16, 0xFD, 0x03, 0x31, 0xD4 } } } },
+ { DE_DEU, kPlatformUnknown, { 0x00000016, 0x000007B6, { { 0xAE, 0xB6, 0x3C, 0x14, 0x2B, 0x34, 0xB8, 0x7C, 0xCF, 0x87, 0xDA, 0x70, 0xBF, 0x0D, 0xAB, 0xE2 } } } },
+
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoB2MainMenuStringsProvider[] = {
+ { EN_ANY, kPlatformUnknown, { 0x0000005F, 0x000017BE, { { 0x77, 0x8A, 0x50, 0x9F, 0x42, 0xD8, 0x00, 0x05, 0x60, 0x2A, 0x80, 0x25, 0x00, 0xDC, 0x7C, 0x92 } } } },
+ { DE_DEU, kPlatformUnknown, { 0x0000005E, 0x000017F3, { { 0xD0, 0x93, 0x2E, 0x5F, 0x9D, 0xDB, 0xC4, 0xFB, 0x9E, 0x9F, 0x14, 0xD6, 0xB4, 0xBE, 0x3D, 0x0C } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoB2TransferPortraitFramesProvider[] = {
+ { UNK_LANG, kPlatformUnknown, { 0x00000040, 0x00000B25, { { 0x13, 0x25, 0x69, 0xC6, 0xE4, 0x9D, 0x35, 0x11, 0xAB, 0xE2, 0xC1, 0xEF, 0x21, 0x8B, 0xB8, 0x28 } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoB2TransferConvertTableProvider[] = {
+ { UNK_LANG, kPlatformUnknown, { 0x00000031, 0x000004BC, { { 0x96, 0x53, 0xA2, 0xF1, 0x26, 0xFE, 0x1B, 0x5E, 0xDF, 0x62, 0x2C, 0x8C, 0xBD, 0x62, 0x5A, 0xF9 } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoB2TransferItemTableProvider[] = {
+ { UNK_LANG, kPlatformUnknown, { 0x0000003C, 0x00000025, { { 0xD0, 0xA4, 0xB3, 0x7D, 0x74, 0x4D, 0x16, 0x43, 0x56, 0x07, 0x84, 0xAA, 0x96, 0xBD, 0x82, 0x25 } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoB2TransferExpTableProvider[] = {
+ { UNK_LANG, kPlatformUnknown, { 0x00000018, 0x0000076B, { { 0x91, 0x65, 0x5B, 0x8D, 0xE8, 0x5B, 0x28, 0x32, 0x4D, 0x7A, 0x57, 0x8E, 0x18, 0x5B, 0x1A, 0xE9 } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoB2TransferStrings1Provider[] = {
+ { EN_ANY, kPlatformUnknown, { 0x00000010, 0x000003D3, { { 0x31, 0xE4, 0x65, 0x69, 0x0A, 0xA1, 0x1D, 0xD1, 0xFE, 0xF8, 0x5C, 0x29, 0xB1, 0x46, 0xBD, 0xBE } } } },
+ { DE_DEU, kPlatformUnknown, { 0x00000010, 0x000003E2, { { 0xF0, 0x10, 0xF8, 0x9F, 0x05, 0x1E, 0x31, 0x33, 0x4E, 0xC8, 0x49, 0xBC, 0x9E, 0xAD, 0xD4, 0x99 } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoB2TransferStrings2Provider[] = {
+ { EN_ANY, kPlatformUnknown, { 0x0000006A, 0x00002681, { { 0x12, 0x4D, 0x29, 0x9D, 0xD3, 0xFC, 0x39, 0x22, 0x73, 0x1E, 0x5C, 0xAF, 0x1F, 0xD1, 0xAA, 0x87 } } } },
+ { DE_DEU, kPlatformUnknown, { 0x00000057, 0x00001F8E, { { 0x85, 0xD8, 0x39, 0x1E, 0x6D, 0x97, 0xBD, 0x0E, 0xDD, 0xCF, 0x19, 0x47, 0x31, 0xDC, 0x7C, 0x1A } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoB2TransferLabelsProvider[] = {
+ { EN_ANY, kPlatformUnknown, { 0x0000000A, 0x00000240, { { 0x2A, 0x8B, 0x54, 0x99, 0x94, 0x35, 0x2B, 0xAB, 0x7F, 0x7F, 0x98, 0xA3, 0xFD, 0x57, 0x20, 0xDE } } } },
+ { DE_DEU, kPlatformUnknown, { 0x00000009, 0x000001DF, { { 0x47, 0x6B, 0xBA, 0xCD, 0x99, 0x74, 0xCA, 0x3C, 0xAA, 0xC6, 0xB4, 0x50, 0x38, 0x90, 0x25, 0xB8 } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoB2IntroStringsProvider[] = {
+ { EN_ANY, kPlatformUnknown, { 0x00000321, 0x0000DBC3, { { 0x11, 0x9B, 0x54, 0xB3, 0x34, 0xF0, 0xB5, 0xE1, 0xFA, 0x6A, 0x31, 0x02, 0x59, 0x29, 0xCA, 0x94 } } } },
+ { DE_DEU, kPlatformUnknown, { 0x0000038E, 0x0001119C, { { 0x92, 0x63, 0x18, 0xDD, 0x9F, 0x62, 0xF5, 0xBC, 0x3D, 0x93, 0xDC, 0x6E, 0xE5, 0xBE, 0x8C, 0x0B } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoB2IntroCPSFilesProvider[] = {
+ { EN_ANY, kPlatformUnknown, { 0x000000A2, 0x0000296A, { { 0xE9, 0x28, 0x4A, 0x6E, 0xAA, 0x44, 0xF4, 0xD7, 0xD1, 0x29, 0xBF, 0x90, 0x6B, 0x82, 0xD1, 0x77 } } } },
+ { DE_DEU, kPlatformUnknown, { 0x000000A2, 0x0000296B, { { 0x03, 0xA2, 0x0A, 0xAB, 0x76, 0x78, 0x04, 0x88, 0x6A, 0xE0, 0x36, 0x8B, 0x3A, 0x87, 0x44, 0xC8 } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob2IntroAnimData00Provider[] = {
+ { UNK_LANG, kPlatformUnknown, { 0x00000037, 0x000003E1, { { 0x38, 0xC2, 0x0F, 0xE1, 0x43, 0x6A, 0xE8, 0x7C, 0x82, 0x65, 0x9B, 0x4A, 0x9F, 0x83, 0xCD, 0xC8 } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob2IntroAnimData01Provider[] = {
+ { UNK_LANG, kPlatformUnknown, { 0x00000037, 0x000003A3, { { 0x84, 0x44, 0xF4, 0x46, 0x4E, 0x2B, 0xD7, 0xC6, 0xAD, 0x14, 0xF1, 0x9E, 0x8A, 0xBE, 0x7B, 0x42 } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob2IntroAnimData02Provider[] = {
+ { UNK_LANG, kPlatformUnknown, { 0x00000037, 0x00000446, { { 0x0C, 0xCA, 0x41, 0x0C, 0x89, 0x59, 0xD5, 0x28, 0x9A, 0xDC, 0x51, 0x1C, 0x0B, 0x8C, 0xD2, 0xDB } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob2IntroAnimData03Provider[] = {
+ { UNK_LANG, kPlatformUnknown, { 0x0000002C, 0x0000010E, { { 0xAB, 0x48, 0x64, 0x02, 0xB3, 0xF3, 0x6C, 0x82, 0x9D, 0x37, 0x5F, 0x52, 0x0F, 0x5B, 0xDF, 0x96 } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob2IntroAnimData04Provider[] = {
+ { UNK_LANG, kPlatformUnknown, { 0x00000021, 0x00000149, { { 0x3B, 0xAC, 0x14, 0x51, 0xDF, 0x5D, 0x22, 0x15, 0x46, 0x4E, 0xCD, 0xF3, 0xD4, 0x61, 0x29, 0x4A } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob2IntroAnimData05Provider[] = {
+ { UNK_LANG, kPlatformUnknown, { 0x0000002C, 0x0000010E, { { 0x28, 0x29, 0x5F, 0x31, 0x23, 0x53, 0xBA, 0xD7, 0x24, 0xB9, 0x21, 0x70, 0x84, 0x8A, 0x1C, 0x2E } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob2IntroAnimData06Provider[] = {
+ { UNK_LANG, kPlatformUnknown, { 0x000000B0, 0x00001365, { { 0x91, 0x28, 0x2F, 0x10, 0x45, 0x4D, 0xCF, 0x3E, 0x70, 0x1E, 0xD4, 0xBA, 0x0E, 0x70, 0xDE, 0xD0 } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob2IntroAnimData07Provider[] = {
+ { UNK_LANG, kPlatformUnknown, { 0x00000037, 0x000003C4, { { 0x8C, 0x72, 0xDE, 0x4F, 0x92, 0x52, 0x0A, 0xED, 0xF4, 0x79, 0xD6, 0x3D, 0x8F, 0x59, 0x9D, 0x69 } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob2IntroAnimData08Provider[] = {
+ { UNK_LANG, kPlatformUnknown, { 0x00000042, 0x00000442, { { 0xD2, 0x91, 0x51, 0xEB, 0x91, 0x13, 0x43, 0xCE, 0x7E, 0x60, 0xB8, 0xFF, 0xA7, 0xE2, 0x4C, 0x11 } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob2IntroAnimData09Provider[] = {
+ { UNK_LANG, kPlatformUnknown, { 0x0000002C, 0x000004BC, { { 0xD6, 0xC7, 0x44, 0x2E, 0xE7, 0x2A, 0x44, 0x09, 0x39, 0xC3, 0xD3, 0xA8, 0x02, 0xC8, 0xA0, 0x19 } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob2IntroAnimData10Provider[] = {
+ { UNK_LANG, kPlatformUnknown, { 0x0000006E, 0x00000C12, { { 0x91, 0xDB, 0x41, 0x7A, 0x4F, 0x7C, 0x7B, 0x83, 0x32, 0x13, 0x68, 0xF6, 0x58, 0x79, 0xDA, 0x99 } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob2IntroAnimData11Provider[] = {
+ { UNK_LANG, kPlatformUnknown, { 0x000000B0, 0x0000073C, { { 0x17, 0x1F, 0x4D, 0x05, 0x3F, 0x14, 0x2E, 0x77, 0xD3, 0xDB, 0x78, 0x67, 0xBB, 0x18, 0xDC, 0x85 } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob2IntroAnimData12Provider[] = {
+ { UNK_LANG, kPlatformUnknown, { 0x00000021, 0x00000228, { { 0xC9, 0x50, 0x68, 0x51, 0xD0, 0xC1, 0x5D, 0xD4, 0xFF, 0x08, 0x28, 0xDE, 0xC4, 0x41, 0x8C, 0xDB } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob2IntroAnimData13Provider[] = {
+ { UNK_LANG, kPlatformUnknown, { 0x0000002C, 0x00000340, { { 0x03, 0xCA, 0x5D, 0xD1, 0x15, 0xFA, 0x60, 0xD7, 0x70, 0x64, 0x3D, 0x44, 0x08, 0xB8, 0xDB, 0xAD } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob2IntroAnimData14Provider[] = {
+ { UNK_LANG, kPlatformUnknown, { 0x00000042, 0x000007C0, { { 0x82, 0xA9, 0x0B, 0x90, 0x9D, 0x65, 0x1E, 0xC7, 0x03, 0x5E, 0xB7, 0xDF, 0x6E, 0x1F, 0xED, 0xD6 } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob2IntroAnimData15Provider[] = {
+ { UNK_LANG, kPlatformUnknown, { 0x0000002C, 0x00000504, { { 0xA7, 0x91, 0x4F, 0xAD, 0xB1, 0x77, 0x80, 0x3A, 0xC7, 0xDE, 0x35, 0x7A, 0x96, 0x16, 0xD2, 0x13 } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob2IntroAnimData16Provider[] = {
+ { UNK_LANG, kPlatformUnknown, { 0x00000079, 0x00000B3D, { { 0xCC, 0x63, 0x5A, 0x11, 0xEE, 0x8A, 0xAE, 0x3A, 0x14, 0xC3, 0xBC, 0xDA, 0xAF, 0x1D, 0xD4, 0x2C } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob2IntroAnimData17Provider[] = {
+ { UNK_LANG, kPlatformUnknown, { 0x00000084, 0x00000911, { { 0x09, 0x1C, 0x4B, 0xD9, 0x0B, 0x2A, 0xD6, 0xC1, 0xE3, 0x8D, 0xFE, 0x43, 0x8F, 0x2E, 0x21, 0x51 } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob2IntroAnimData18Provider[] = {
+ { UNK_LANG, kPlatformUnknown, { 0x00000058, 0x000008FA, { { 0xFE, 0x58, 0xD9, 0x67, 0x78, 0x97, 0xE2, 0xCD, 0x82, 0xB8, 0xC9, 0xC0, 0x1F, 0xCA, 0x7C, 0xF5 } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob2IntroAnimData19Provider[] = {
+ { UNK_LANG, kPlatformUnknown, { 0x0000009A, 0x00000D6B, { { 0xA1, 0xDD, 0x7B, 0x8B, 0x25, 0xA5, 0x96, 0x5A, 0x33, 0x5E, 0x80, 0x5F, 0xA5, 0xBB, 0xAC, 0x11 } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob2IntroAnimData20Provider[] = {
+ { UNK_LANG, kPlatformUnknown, { 0x0000009A, 0x00000D6C, { { 0x19, 0xF9, 0x93, 0x1D, 0x01, 0xEE, 0x7C, 0x8B, 0x6C, 0x3E, 0x35, 0x2C, 0x5C, 0x88, 0xCD, 0xB6 } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob2IntroAnimData21Provider[] = {
+ { UNK_LANG, kPlatformUnknown, { 0x0000009A, 0x00000D83, { { 0xCB, 0x4F, 0x21, 0x29, 0x63, 0x5B, 0x8C, 0xF2, 0xBA, 0x03, 0x49, 0xD1, 0xAF, 0x22, 0xB0, 0xD5 } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob2IntroAnimData22Provider[] = {
+ { UNK_LANG, kPlatformUnknown, { 0x00000016, 0x00000200, { { 0x66, 0xEE, 0x45, 0xB1, 0x87, 0x66, 0xC4, 0x55, 0xCE, 0x60, 0x0C, 0x5B, 0xBB, 0x3C, 0x7D, 0x33 } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob2IntroAnimData23Provider[] = {
+ { UNK_LANG, kPlatformUnknown, { 0x00000016, 0x0000020D, { { 0xC4, 0x49, 0xE2, 0x5B, 0x2E, 0x17, 0x68, 0xC4, 0xBA, 0x20, 0xEC, 0xB1, 0xEB, 0x1A, 0xFB, 0xE0 } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob2IntroAnimData24Provider[] = {
+ { UNK_LANG, kPlatformUnknown, { 0x00000016, 0x00000214, { { 0xF1, 0x46, 0x82, 0xEF, 0x6D, 0xCA, 0x68, 0xA2, 0xF3, 0x55, 0x63, 0xD2, 0x13, 0x25, 0x19, 0xF7 } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob2IntroAnimData25Provider[] = {
+ { UNK_LANG, kPlatformUnknown, { 0x00000016, 0x00000256, { { 0x8F, 0xB9, 0xCD, 0xB8, 0x58, 0xCB, 0x90, 0x03, 0xFC, 0xB6, 0x95, 0x6F, 0x52, 0xF8, 0x7D, 0x19 } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob2IntroAnimData26Provider[] = {
+ { UNK_LANG, kPlatformUnknown, { 0x00000016, 0x00000263, { { 0x7A, 0x37, 0x07, 0xC4, 0x67, 0x72, 0x1F, 0xCB, 0xAC, 0x98, 0x46, 0x9A, 0xF3, 0x5F, 0xBA, 0x78 } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob2IntroAnimData27Provider[] = {
+ { UNK_LANG, kPlatformUnknown, { 0x00000016, 0x0000026A, { { 0x80, 0x11, 0xEE, 0x44, 0xDA, 0xE1, 0x26, 0x1F, 0x14, 0x7E, 0x93, 0x99, 0x44, 0x44, 0x9F, 0x85 } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob2IntroAnimData28Provider[] = {
+ { UNK_LANG, kPlatformUnknown, { 0x00000016, 0x000001F6, { { 0x45, 0xA1, 0xA5, 0xEC, 0x85, 0x06, 0xE2, 0x91, 0x28, 0xE0, 0xBB, 0x53, 0x74, 0x44, 0xD9, 0xA6 } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob2IntroAnimData29Provider[] = {
+ { UNK_LANG, kPlatformUnknown, { 0x00000016, 0x000001F9, { { 0x3F, 0x03, 0x2F, 0x8B, 0xFB, 0x6A, 0x97, 0x05, 0xED, 0xBB, 0xD6, 0xA0, 0xF5, 0x7A, 0x6D, 0x08 } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob2IntroAnimData30Provider[] = {
+ { UNK_LANG, kPlatformUnknown, { 0x00000016, 0x00000204, { { 0xA1, 0x37, 0x57, 0xC3, 0x72, 0x08, 0x98, 0xA6, 0xF4, 0x5E, 0x58, 0x9E, 0xF3, 0x11, 0x88, 0x1E } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob2IntroAnimData31Provider[] = {
+ { UNK_LANG, kPlatformUnknown, { 0x00000016, 0x00000212, { { 0x19, 0xCC, 0x6F, 0xA8, 0x29, 0xB5, 0x3B, 0x15, 0x2F, 0x2C, 0x43, 0xED, 0x7A, 0xF5, 0xC5, 0x69 } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob2IntroAnimData32Provider[] = {
+ { UNK_LANG, kPlatformUnknown, { 0x00000037, 0x000006C9, { { 0xBF, 0x65, 0xBA, 0x3F, 0x44, 0xEE, 0xB0, 0x5C, 0x8B, 0xBD, 0x15, 0xAB, 0x03, 0xD1, 0x55, 0x21 } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob2IntroAnimData33Provider[] = {
+ { UNK_LANG, kPlatformUnknown, { 0x0000009A, 0x00001585, { { 0xB5, 0x44, 0x06, 0xC9, 0xE8, 0x27, 0x75, 0x6E, 0x63, 0x77, 0xE9, 0xA9, 0x68, 0x73, 0xF5, 0x78 } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob2IntroAnimData34Provider[] = {
+ { UNK_LANG, kPlatformUnknown, { 0x00000058, 0x00000B43, { { 0x52, 0xB4, 0x1E, 0x14, 0x88, 0xBD, 0x8A, 0xD7, 0x38, 0xDF, 0x25, 0xB0, 0xAF, 0xAE, 0x76, 0xE1 } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob2IntroAnimData35Provider[] = {
+ { UNK_LANG, kPlatformUnknown, { 0x00000037, 0x000005A4, { { 0xFB, 0x82, 0xE7, 0xB2, 0x54, 0xDB, 0xB5, 0xE1, 0xCE, 0xFB, 0xD1, 0x23, 0x39, 0x8F, 0xA1, 0x0D } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob2IntroAnimData36Provider[] = {
+ { UNK_LANG, kPlatformUnknown, { 0x00000042, 0x00000572, { { 0x2C, 0x16, 0xD9, 0xBE, 0xDB, 0xBA, 0x04, 0xCA, 0x97, 0xB5, 0x88, 0x43, 0xA8, 0x62, 0xE2, 0x04 } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob2IntroAnimData37Provider[] = {
+ { UNK_LANG, kPlatformUnknown, { 0x00000016, 0x0000024E, { { 0xFF, 0x28, 0xD8, 0x62, 0xC6, 0xAD, 0x48, 0xC7, 0x31, 0x84, 0x6C, 0xBA, 0x9F, 0x4D, 0x15, 0xDA } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob2IntroAnimData38Provider[] = {
+ { UNK_LANG, kPlatformUnknown, { 0x000001D9, 0x00001FB1, { { 0x16, 0xB0, 0xDF, 0x86, 0x8C, 0xB3, 0x52, 0xEF, 0x21, 0x04, 0x22, 0x6D, 0xC0, 0x03, 0xB8, 0xC6 } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob2IntroAnimData39Provider[] = {
+ { UNK_LANG, kPlatformUnknown, { 0x0000004D, 0x00000582, { { 0x11, 0x6C, 0xBB, 0xF6, 0x1B, 0x3C, 0xAE, 0xAA, 0x40, 0x27, 0x3F, 0x86, 0x33, 0x92, 0xCB, 0xA9 } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob2IntroAnimData40Provider[] = {
+ { UNK_LANG, kPlatformUnknown, { 0x00000160, 0x000010A2, { { 0xD9, 0x9D, 0xF1, 0x7D, 0xE1, 0x7C, 0x61, 0xC0, 0xD4, 0xD3, 0x05, 0x0C, 0x79, 0xDD, 0xDB, 0xD1 } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob2IntroAnimData41Provider[] = {
+ { UNK_LANG, kPlatformUnknown, { 0x00000037, 0x00000355, { { 0x92, 0x85, 0xBE, 0x5A, 0x38, 0x08, 0xF3, 0xDF, 0xC6, 0x56, 0x74, 0xC3, 0x0B, 0x3F, 0x72, 0x4D } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob2IntroAnimData42Provider[] = {
+ { UNK_LANG, kPlatformUnknown, { 0x00000021, 0x0000010B, { { 0x68, 0xF8, 0x1D, 0x74, 0x6D, 0x32, 0x1E, 0x3A, 0x1C, 0xD1, 0x1D, 0x4B, 0x89, 0x3D, 0x5F, 0x2B } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob2IntroAnimData43Provider[] = {
+ { UNK_LANG, kPlatformUnknown, { 0x00000037, 0x00000116, { { 0xD5, 0x46, 0xCB, 0x3F, 0x27, 0xBD, 0x2B, 0xD6, 0x35, 0x69, 0x9E, 0x0A, 0x28, 0xDA, 0xC9, 0x84 } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoB2IntroShapes00Provider[] = {
+ { UNK_LANG, kPlatformUnknown, { 0x0000005A, 0x00000A86, { { 0xF9, 0xD5, 0xD2, 0x93, 0xBC, 0xC4, 0x86, 0x3F, 0x83, 0x0D, 0xDB, 0x38, 0x60, 0x6E, 0xA7, 0xDA } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoB2IntroShapes01Provider[] = {
+ { UNK_LANG, kPlatformUnknown, { 0x0000000C, 0x0000009B, { { 0xAA, 0xDD, 0x25, 0x21, 0x57, 0x6A, 0xB7, 0xEB, 0xDA, 0xFD, 0x72, 0x3B, 0xCA, 0x68, 0xDB, 0x34 } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoB2IntroShapes04Provider[] = {
+ { UNK_LANG, kPlatformUnknown, { 0x0000003C, 0x00000417, { { 0x13, 0x95, 0x81, 0x46, 0x84, 0x36, 0xF2, 0xFC, 0xDE, 0x15, 0x85, 0x81, 0xB3, 0x9A, 0x9D, 0x20 } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoB2IntroShapes07Provider[] = {
+ { UNK_LANG, kPlatformUnknown, { 0x0000006C, 0x000021F1, { { 0x6F, 0x7C, 0x28, 0xBB, 0xC3, 0x52, 0xE4, 0x13, 0xB4, 0xE9, 0xA4, 0x47, 0x9A, 0xBE, 0x19, 0xDA } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoB2FinaleStringsProvider[] = {
+ { EN_ANY, kPlatformUnknown, { 0x0000031C, 0x0000E287, { { 0x1E, 0x73, 0x93, 0x79, 0xB7, 0xF8, 0x17, 0xEE, 0xE4, 0xFC, 0xF0, 0x34, 0x9D, 0x06, 0x4F, 0x55 } } } },
+ { DE_DEU, kPlatformUnknown, { 0x0000039F, 0x00011660, { { 0xBC, 0x1D, 0x95, 0x20, 0x32, 0xF5, 0x83, 0xCF, 0xF7, 0x11, 0xE4, 0x1D, 0x89, 0x47, 0xF0, 0x65 } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoB2CreditsDataProvider[] = {
+ { EN_ANY, kPlatformUnknown, { 0x0000090C, 0x00023464, { { 0x55, 0x31, 0x9D, 0x60, 0x2C, 0xA1, 0x0B, 0xF9, 0xED, 0x46, 0xDF, 0x44, 0x1A, 0x9F, 0xB1, 0xB0 } } } },
+ { DE_DEU, kPlatformUnknown, { 0x00000B11, 0x0002BBD7, { { 0x46, 0x24, 0x78, 0xE9, 0xCE, 0x75, 0x45, 0x7B, 0x3B, 0xAA, 0x15, 0xD8, 0x5B, 0xCB, 0x06, 0x3A } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoB2FinaleCPSFilesProvider[] = {
+ { EN_ANY, kPlatformUnknown, { 0x0000009C, 0x00002853, { { 0x1F, 0xB9, 0x3D, 0x48, 0x47, 0x31, 0x0D, 0xA8, 0x92, 0x52, 0xD1, 0x54, 0x48, 0x42, 0x47, 0xBD } } } },
+ { DE_DEU, kPlatformUnknown, { 0x0000009C, 0x00002878, { { 0x48, 0x3B, 0x7A, 0xC2, 0x9C, 0xEC, 0x10, 0x07, 0xD1, 0xB6, 0x9E, 0x89, 0xE9, 0xE1, 0xBF, 0xBF } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob2FinaleAnimData00Provider[] = {
+ { UNK_LANG, kPlatformUnknown, { 0x00000079, 0x00000B66, { { 0x9B, 0x8C, 0x17, 0xFA, 0xD2, 0x4F, 0x4B, 0x0E, 0x3A, 0x43, 0xB1, 0x86, 0x0C, 0xDC, 0x73, 0xAB } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob2FinaleAnimData01Provider[] = {
+ { UNK_LANG, kPlatformUnknown, { 0x00000063, 0x00000A03, { { 0xBB, 0x31, 0xEA, 0x35, 0xFB, 0x99, 0x4C, 0x3E, 0x72, 0xBD, 0x36, 0x6B, 0x5C, 0x03, 0x19, 0x7F } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob2FinaleAnimData02Provider[] = {
+ { UNK_LANG, kPlatformUnknown, { 0x0000002C, 0x000007C2, { { 0xF6, 0x83, 0x37, 0x58, 0x3C, 0x59, 0x84, 0x8F, 0x97, 0x80, 0xE2, 0xD8, 0xFD, 0x77, 0xA9, 0x54 } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob2FinaleAnimData03Provider[] = {
+ { UNK_LANG, kPlatformUnknown, { 0x00000042, 0x0000092B, { { 0x47, 0xE4, 0x34, 0xE8, 0x72, 0xCC, 0xA4, 0x4A, 0xA4, 0x8F, 0xBA, 0xBC, 0x0C, 0x04, 0x18, 0xAF } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob2FinaleAnimData04Provider[] = {
+ { UNK_LANG, kPlatformUnknown, { 0x00000058, 0x0000080B, { { 0x16, 0xDB, 0x77, 0x4C, 0x8E, 0xFD, 0x44, 0xF6, 0x5E, 0x28, 0x0B, 0x74, 0x93, 0x45, 0x8F, 0xD9 } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob2FinaleAnimData05Provider[] = {
+ { UNK_LANG, kPlatformUnknown, { 0x0000004D, 0x00000C72, { { 0x6C, 0x57, 0x56, 0x7E, 0x87, 0x10, 0x9C, 0xE7, 0x69, 0xAC, 0x3B, 0x3F, 0xF6, 0x43, 0x5C, 0xD4 } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob2FinaleAnimData06Provider[] = {
+ { UNK_LANG, kPlatformUnknown, { 0x00000016, 0x00000264, { { 0x48, 0x49, 0x5D, 0x78, 0xE2, 0xF1, 0x0D, 0x87, 0xEE, 0xEE, 0xD1, 0xA1, 0xC6, 0x64, 0xCA, 0x13 } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob2FinaleAnimData07Provider[] = {
+ { UNK_LANG, kPlatformUnknown, { 0x00000042, 0x00000ABE, { { 0xFE, 0xA9, 0x5D, 0x87, 0xAF, 0x55, 0x04, 0x92, 0x41, 0xD3, 0xAD, 0x1D, 0xFF, 0x03, 0x81, 0x3C } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob2FinaleAnimData08Provider[] = {
+ { UNK_LANG, kPlatformUnknown, { 0x00000021, 0x000004D8, { { 0x4E, 0xA7, 0xCC, 0x0B, 0x1B, 0x48, 0x22, 0x09, 0x33, 0xF7, 0x23, 0xF1, 0xF5, 0x9F, 0xA5, 0x7B } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob2FinaleAnimData09Provider[] = {
+ { UNK_LANG, kPlatformUnknown, { 0x00000058, 0x000004BE, { { 0xF6, 0xEA, 0xA0, 0x7F, 0x54, 0x61, 0x79, 0x4C, 0x71, 0xD7, 0x9B, 0xA6, 0xC3, 0x45, 0xEE, 0x3E } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob2FinaleAnimData10Provider[] = {
+ { UNK_LANG, kPlatformUnknown, { 0x0000009A, 0x00000FC4, { { 0xA9, 0xFB, 0x31, 0x55, 0xB8, 0x28, 0x63, 0xC3, 0x4B, 0x9E, 0x7D, 0x41, 0xC7, 0x1F, 0x2F, 0xBD } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob2FinaleAnimData11Provider[] = {
+ { UNK_LANG, kPlatformUnknown, { 0x000000C6, 0x0000166B, { { 0xCC, 0x16, 0x50, 0xFF, 0xFF, 0xD5, 0xAE, 0x03, 0x40, 0xA3, 0x9A, 0x1F, 0xF8, 0x8E, 0x23, 0x7A } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob2FinaleAnimData12Provider[] = {
+ { UNK_LANG, kPlatformUnknown, { 0x000000FD, 0x00001A69, { { 0x6A, 0x80, 0x89, 0x7E, 0xFC, 0xE4, 0x01, 0xF5, 0xA2, 0x11, 0xE7, 0x26, 0x20, 0x96, 0x62, 0x7B } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob2FinaleAnimData13Provider[] = {
+ { UNK_LANG, kPlatformUnknown, { 0x000000FD, 0x00001886, { { 0xF9, 0x5B, 0x62, 0xDD, 0xAB, 0x14, 0x35, 0x77, 0x53, 0x05, 0xDB, 0xC5, 0xFD, 0x4D, 0x4F, 0x12 } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob2FinaleAnimData14Provider[] = {
+ { UNK_LANG, kPlatformUnknown, { 0x00000108, 0x00001895, { { 0x22, 0xA1, 0x88, 0x69, 0xF9, 0x1C, 0xA2, 0x64, 0x44, 0xCD, 0x00, 0xFA, 0xB1, 0x94, 0xEB, 0x3A } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob2FinaleAnimData15Provider[] = {
+ { UNK_LANG, kPlatformUnknown, { 0x000000D1, 0x000016E5, { { 0xD8, 0xE9, 0xA5, 0xEE, 0x54, 0x1B, 0x3E, 0x32, 0xDA, 0x78, 0x90, 0xC2, 0x54, 0xFC, 0xD5, 0x39 } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob2FinaleAnimData16Provider[] = {
+ { UNK_LANG, kPlatformUnknown, { 0x0000008F, 0x00000C69, { { 0xBC, 0x41, 0xE5, 0xAF, 0x89, 0xE2, 0x54, 0x12, 0x9E, 0xB0, 0x5F, 0x28, 0xFF, 0x92, 0x9D, 0x89 } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob2FinaleAnimData17Provider[] = {
+ { UNK_LANG, kPlatformUnknown, { 0x000000DC, 0x0000170D, { { 0x7A, 0x7B, 0x74, 0xCB, 0x68, 0xC2, 0xFF, 0xC7, 0xBE, 0x47, 0xE9, 0x43, 0xF7, 0x15, 0x8D, 0x59 } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob2FinaleAnimData18Provider[] = {
+ { UNK_LANG, kPlatformUnknown, { 0x00000134, 0x00002651, { { 0x71, 0x26, 0x47, 0x0D, 0x7C, 0x96, 0x45, 0x0B, 0x82, 0xD0, 0x37, 0xB9, 0xD4, 0xD0, 0x84, 0xFC } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob2FinaleAnimData19Provider[] = {
+ { UNK_LANG, kPlatformUnknown, { 0x0000004D, 0x000009C3, { { 0xDA, 0x96, 0xDF, 0x16, 0xEB, 0x5D, 0x49, 0xA4, 0x3F, 0xD3, 0x31, 0xBE, 0x49, 0x72, 0xF2, 0x71 } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob2FinaleAnimData20Provider[] = {
+ { UNK_LANG, kPlatformUnknown, { 0x00000021, 0x000003D8, { { 0xD9, 0xC8, 0x58, 0x4B, 0x7D, 0x79, 0x86, 0xCB, 0xEB, 0x77, 0xC2, 0xD4, 0xB7, 0xB4, 0xE9, 0x6A } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoB2FinaleShapes00Provider[] = {
+ { UNK_LANG, kPlatformUnknown, { 0x00000018, 0x0000071C, { { 0xE8, 0x67, 0xCB, 0x76, 0x6D, 0x49, 0xC2, 0x05, 0x0D, 0xAD, 0xB6, 0x83, 0x35, 0xB3, 0xBE, 0xE5 } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoB2FinaleShapes03Provider[] = {
+ { UNK_LANG, kPlatformUnknown, { 0x00000012, 0x00000571, { { 0x91, 0xEC, 0xAC, 0x12, 0x08, 0x33, 0xDA, 0x7C, 0xBD, 0x51, 0x64, 0xE3, 0xAE, 0x43, 0x75, 0x14 } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoB2FinaleShapes07Provider[] = {
+ { UNK_LANG, kPlatformUnknown, { 0x00000018, 0x00000166, { { 0xED, 0x6E, 0x0C, 0x85, 0x13, 0x6F, 0xAC, 0xEB, 0xCA, 0x74, 0x2E, 0x2D, 0x0E, 0xCE, 0x17, 0xD6 } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoB2FinaleShapes09Provider[] = {
+ { UNK_LANG, kPlatformUnknown, { 0x00000036, 0x00000898, { { 0xEB, 0xB0, 0xD9, 0xC4, 0xB6, 0xBC, 0xE3, 0xAF, 0xB2, 0x5D, 0xE3, 0xCE, 0xF7, 0x26, 0x07, 0xE5 } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoB2FinaleShapes10Provider[] = {
+ { UNK_LANG, kPlatformUnknown, { 0x00000018, 0x0000017F, { { 0x0F, 0x37, 0x94, 0xA6, 0xCE, 0x23, 0xE3, 0x2E, 0x5E, 0x2B, 0x78, 0x5B, 0x66, 0xC8, 0xE5, 0x96 } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoB2NpcShapeDataProvider[] = {
+ { UNK_LANG, kPlatformUnknown, { 0x00000018, 0x0000045D, { { 0x69, 0xE0, 0x5E, 0x86, 0xEB, 0x7D, 0x25, 0x95, 0xC2, 0xA0, 0xE9, 0xD5, 0x3A, 0x4A, 0x65, 0xBC } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBaseClassModifierFlagsProvider[] = {
+ { UNK_LANG, kPlatformUnknown, { 0x0000000F, 0x00000059, { { 0x17, 0x2B, 0x23, 0x14, 0x0F, 0x9D, 0x94, 0xD3, 0xBF, 0x94, 0x83, 0x0B, 0x79, 0xDB, 0xC0, 0xA9 } } } }, // EOB 1
+ { UNK_LANG, kPlatformUnknown, { 0x0000000F, 0x00000083, { { 0x54, 0x68, 0xF4, 0x07, 0x3E, 0x2A, 0xD4, 0x06, 0xF3, 0x10, 0x88, 0x6C, 0xE3, 0x34, 0x08, 0x30 } } } }, // EOB 2
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBaseMonsterStepTable01Provider[] = {
+ { UNK_LANG, kPlatformUnknown, { 0x00000004, 0x00000200, { { 0x26, 0x86, 0x10, 0x04, 0xC1, 0x48, 0xDD, 0xC0, 0x9F, 0x92, 0xD6, 0x20, 0x38, 0x36, 0xE2, 0xDD } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBaseMonsterStepTable02Provider[] = {
+ { UNK_LANG, kPlatformUnknown, { 0x00000008, 0x00000400, { { 0x6E, 0x53, 0x3C, 0x7A, 0x11, 0x46, 0x8B, 0xDC, 0x73, 0x24, 0xF8, 0x13, 0xCB, 0x6C, 0x9B, 0xE6 } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBaseMonsterStepTable1Provider[] = {
+ { UNK_LANG, kPlatformUnknown, { 0x00000010, 0x00000400, { { 0x8B, 0x4C, 0x6B, 0x86, 0x93, 0xDA, 0x82, 0x1B, 0x04, 0x23, 0x92, 0x5B, 0x79, 0xB9, 0xFB, 0x06 } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBaseMonsterStepTable2Provider[] = {
+ { UNK_LANG, kPlatformUnknown, { 0x00000010, 0x00000601, { { 0xE4, 0x36, 0x12, 0x93, 0x44, 0xDE, 0x6E, 0xA0, 0x4B, 0x98, 0x4B, 0x47, 0x87, 0xE3, 0x40, 0xD4 } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBaseMonsterStepTable3Provider[] = {
+ { UNK_LANG, kPlatformUnknown, { 0x00000010, 0x000007F8, { { 0x00, 0x0C, 0xB0, 0xDA, 0xE1, 0xC8, 0x45, 0x11, 0x57, 0xE4, 0x72, 0xD2, 0x32, 0xC6, 0x16, 0x2B } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBaseMonsterCloseAttPosTable1Provider[] = {
+ { UNK_LANG, kPlatformUnknown, { 0x00000004, 0x00000006, { { 0x4F, 0x9D, 0x50, 0xDA, 0xA1, 0x75, 0xB0, 0xD5, 0x90, 0xCA, 0xFF, 0x3E, 0xB5, 0xE8, 0x0D, 0xAA } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBaseMonsterCloseAttPosTable21Provider[] = {
+ { UNK_LANG, kPlatformUnknown, { 0x00000008, 0x0000000C, { { 0x6A, 0xED, 0x15, 0xCE, 0x69, 0x54, 0x7D, 0x7B, 0x6D, 0xCE, 0xC7, 0x2A, 0x01, 0xD7, 0xDC, 0xB0 } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBaseMonsterCloseAttPosTable22Provider[] = {
+ { UNK_LANG, kPlatformUnknown, { 0x00000010, 0x00000018, { { 0x6D, 0xB9, 0x69, 0x4A, 0xE3, 0x72, 0x03, 0x5B, 0x5A, 0xBB, 0x15, 0x4A, 0xDA, 0xFB, 0x99, 0x87 } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBaseMonsterCloseAttUnkTableProvider[] = {////
+ { UNK_LANG, kPlatformUnknown, { 0x0000000C, 0x000007FE, { { 0xF0, 0xCB, 0x3A, 0x53, 0xDD, 0x59, 0x04, 0x87, 0x6F, 0x1B, 0x5A, 0x13, 0xBA, 0x78, 0x62, 0xEC } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBaseMonsterCloseAttChkTable1Provider[] = {
+ { UNK_LANG, kPlatformUnknown, { 0x00000010, 0x00000008, { { 0x93, 0x27, 0x19, 0xA7, 0xA7, 0x49, 0x0E, 0xC9, 0xED, 0x5C, 0x8F, 0x9F, 0xC2, 0x34, 0x62, 0x07 } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBaseMonsterCloseAttChkTable2Provider[] = {
+ { UNK_LANG, kPlatformUnknown, { 0x00000010, 0x00000008, { { 0xEB, 0xF0, 0x27, 0x7E, 0xA8, 0x09, 0x3A, 0x95, 0x3B, 0x71, 0x2A, 0x43, 0x2E, 0xCF, 0x22, 0x0B } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBaseMonsterCloseAttDstTable1Provider[] = {
+ { UNK_LANG, kPlatformUnknown, { 0x00000010, 0x00000018, { { 0x1E, 0xC9, 0x6C, 0x5D, 0xDF, 0xD4, 0xC0, 0x87, 0xAD, 0xEE, 0x86, 0x29, 0xD5, 0x3E, 0x8D, 0xB4 } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBaseMonsterCloseAttDstTable2Provider[] = {
+ { UNK_LANG, kPlatformUnknown, { 0x00000030, 0x00000078, { { 0x4C, 0xA8, 0x2A, 0x53, 0xB3, 0xAA, 0x52, 0x96, 0x1D, 0xE8, 0x37, 0xDB, 0x4A, 0x77, 0xD8, 0x5B } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBaseMonsterProximityTableProvider[] = {
+ { UNK_LANG, kPlatformUnknown, { 0x00000020, 0x00000030, { { 0x25, 0xFC, 0xA3, 0xEB, 0x44, 0x93, 0x9B, 0x33, 0xB5, 0x86, 0xC4, 0xCB, 0x17, 0xEF, 0x2D, 0x47 } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBaseFindBlockMonstersTableProvider[] = {
+ { UNK_LANG, kPlatformUnknown, { 0x00000040, 0x00000088, { { 0x6F, 0xEE, 0x8B, 0x4C, 0x21, 0xF0, 0xC6, 0x4F, 0x1D, 0x05, 0x95, 0x41, 0xD7, 0xD6, 0x52, 0x66 } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBaseMonsterDirChangeTableProvider[] = {
+ { UNK_LANG, kPlatformUnknown, { 0x00000030, 0x0000180C, { { 0xCD, 0xBB, 0xFD, 0xAB, 0xFB, 0x1D, 0x5C, 0x0F, 0xA2, 0xAC, 0x32, 0xA9, 0xA1, 0x93, 0x2D, 0x1C } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBaseMonsterDistAttStringsProvider[] = {
+ { EN_ANY, kPlatformUnknown, { 0x00000076, 0x00002965, { { 0x1A, 0x22, 0x50, 0x04, 0x27, 0x05, 0xE9, 0x61, 0xF9, 0x0A, 0xF0, 0x50, 0x01, 0x0E, 0x65, 0xB4 } } } },
+ { DE_DEU, kPlatformUnknown, { 0x0000008C, 0x00003274, { { 0xE7, 0x24, 0x17, 0x13, 0x4F, 0xB3, 0xF9, 0xB7, 0x90, 0xFA, 0x3D, 0xFF, 0xA7, 0xFB, 0x3F, 0x1F } } } },
+ { EN_ANY, kPlatformUnknown, { 0x00000054, 0x00001D03, { { 0xEB, 0x07, 0xD4, 0x22, 0xFD, 0xA0, 0x77, 0x80, 0x22, 0x04, 0x2E, 0x27, 0x7F, 0x64, 0x99, 0x4E } } } },
+ { DE_DEU, kPlatformUnknown, { 0x00000062, 0x000023E0, { { 0xB8, 0x03, 0x5C, 0x31, 0xCC, 0x18, 0xCD, 0x8D, 0x60, 0xD1, 0xFB, 0x5B, 0x66, 0xC2, 0x9A, 0x4C } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBaseEncodeMonsterDefsProvider[] = {
+ { UNK_LANG, kPlatformUnknown, { 0x00000150, 0x00001ACB, { { 0x73, 0x67, 0x5B, 0x64, 0x22, 0xDB, 0x08, 0x3A, 0xCD, 0xEB, 0x30, 0x28, 0xBD, 0xAD, 0xF8, 0x9B } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoBBaseNpcPresetsProvider[] = {
+ { UNK_LANG, kPlatformUnknown, { 0x0000088B, 0x000038D0, { { 0x2E, 0xAE, 0xF0, 0x2A, 0x71, 0x6F, 0x7C, 0x5C, 0xF5, 0xAF, 0xB8, 0xBB, 0x47, 0xE5, 0xB6, 0xC3 } } } }, // EOB 1
+ { UNK_LANG, kPlatformUnknown, { 0x00000816, 0x00002C8E, { { 0xAB, 0xEE, 0x18, 0x0E, 0x59, 0xF6, 0xE0, 0x26, 0x93, 0xAB, 0x3B, 0x23, 0x29, 0x7A, 0x2C, 0x97 } } } }, // EOB 2
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoB2Npc1StringsProvider[] = {
+ { EN_ANY, kPlatformUnknown, { 0x0000000B, 0x000003B9, { { 0xB1, 0x67, 0x80, 0x21, 0x92, 0xDD, 0xFA, 0x4C, 0x4D, 0x64, 0x7C, 0x05, 0x08, 0xDC, 0x55, 0xFD } } } },
+ { DE_DEU, kPlatformUnknown, { 0x0000000D, 0x0000049E, { { 0x2D, 0x78, 0xF6, 0x20, 0x30, 0xEC, 0x62, 0x6E, 0x58, 0xF7, 0xC7, 0x6D, 0xD7, 0xBD, 0x70, 0x76 } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoB2Npc2StringsProvider[] = {
+ { EN_ANY, kPlatformUnknown, { 0x00000012, 0x0000064C, { { 0xB0, 0x66, 0x0D, 0xDE, 0x16, 0xEB, 0x5E, 0x51, 0xAF, 0x4D, 0x19, 0xD1, 0x1E, 0x0B, 0xCB, 0xD6 } } } },
+ { DE_DEU, kPlatformUnknown, { 0x00000018, 0x000008FF, { { 0x59, 0x29, 0x01, 0x6F, 0xF0, 0x49, 0xC8, 0x57, 0x3E, 0x70, 0x01, 0x7E, 0x5E, 0xF2, 0xEB, 0x35 } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoB2MonsterDustStringsProvider[] = {
+ { EN_ANY, kPlatformUnknown, { 0x0000001F, 0x00000AD7, { { 0x2B, 0x66, 0x27, 0xFD, 0xC6, 0x17, 0x0B, 0x6B, 0xFC, 0x7D, 0x7F, 0xD2, 0xC4, 0x12, 0x8F, 0x33 } } } },
+ { DE_DEU, kPlatformUnknown, { 0x0000001F, 0x00000A91, { { 0x1D, 0x7D, 0xEE, 0xB8, 0x9B, 0x37, 0x2E, 0x64, 0x13, 0xB6, 0x39, 0xED, 0x88, 0xB6, 0x8B, 0xD7 } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoB2DreamStepsProvider[] = {
+ { UNK_LANG, kPlatformUnknown, { 0x0000000E, 0x00000114, { { 0x27, 0x32, 0xCB, 0x89, 0x27, 0xC5, 0xDD, 0x91, 0xBE, 0x97, 0x62, 0xF5, 0x76, 0xF7, 0xCD, 0x25 } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoB2KheldranStringsProvider[] = {
+ { EN_ANY, kPlatformUnknown, { 0x0000001A, 0x00000887, { { 0xA6, 0xB4, 0x45, 0x1B, 0x33, 0x54, 0x36, 0xAD, 0x1D, 0xB1, 0xDA, 0xC3, 0x12, 0x85, 0x3C, 0x58 } } } },
+ { DE_DEU, kPlatformUnknown, { 0x00000012, 0x00000511, { { 0xEE, 0x21, 0xA8, 0x6E, 0xF7, 0xEC, 0x9A, 0x8D, 0xBA, 0x8D, 0xE3, 0x4A, 0x17, 0x15, 0xCA, 0x8C } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoB2HornStringsProvider[] = {
+ { EN_ANY, kPlatformUnknown, { 0x0000009A, 0x00003541, { { 0xA5, 0x4D, 0x88, 0xAC, 0x1C, 0xCD, 0x57, 0xD4, 0x1E, 0x9F, 0xAE, 0x13, 0x46, 0xAD, 0xA0, 0x22 } } } },
+ { DE_DEU, kPlatformUnknown, { 0x000000AB, 0x00003B6C, { { 0x36, 0x34, 0xB3, 0xB1, 0x55, 0x66, 0x7A, 0x90, 0x97, 0x01, 0xDC, 0x4A, 0xAF, 0x17, 0x6B, 0x5A } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoB2HornSoundsProvider[] = {
+ { UNK_LANG, kPlatformPC, { 0x00000004, 0x00000106, { { 0x3E, 0x7B, 0x96, 0xFD, 0xCA, 0x4E, 0xA7, 0xA6, 0xB8, 0x82, 0x67, 0xCF, 0x93, 0x86, 0xE4, 0x45 } } } },
+
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoB2WallOfForceDsXProvider[] = {
+ { UNK_LANG, kPlatformPC, { 0x00000024, 0x00000D67, { { 0x51, 0xCF, 0xAB, 0x1E, 0xB4, 0xE0, 0xE3, 0x44, 0x29, 0xD1, 0xDC, 0x82, 0xCD, 0x08, 0x50, 0xF5 } } } },
+
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoB2WallOfForceDsYProvider[] = {
+ { UNK_LANG, kPlatformPC, { 0x00000003, 0x00000048, { { 0x45, 0xFC, 0xEA, 0x8C, 0x34, 0xD7, 0xBE, 0x74, 0x05, 0x03, 0xE6, 0x94, 0x34, 0xB5, 0x45, 0x4D } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoB2WallOfForceNumWProvider[] = {
+ { UNK_LANG, kPlatformPC, { 0x00000003, 0x00000006, { { 0x52, 0x89, 0xDF, 0x73, 0x7D, 0xF5, 0x73, 0x26, 0xFC, 0xDD, 0x22, 0x59, 0x7A, 0xFB, 0x1F, 0xAC } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoB2WallOfForceNumHProvider[] = {
+ { UNK_LANG, kPlatformPC, { 0x00000003, 0x00000011, { { 0x33, 0x86, 0x06, 0xBE, 0x8D, 0xC8, 0x37, 0x2D, 0x0F, 0x61, 0x97, 0xA4, 0x26, 0xA9, 0xBC, 0x60 } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEoB2WallOfForceShpIdProvider[] = {
+ { UNK_LANG, kPlatformPC, { 0x00000003, 0x00000006, { { 0x77, 0xAE, 0x9B, 0x52, 0x9E, 0xF7, 0xEB, 0x48, 0xA8, 0x5E, 0xED, 0xC2, 0x08, 0x53, 0xCE, 0x3C } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kLoLIngamePakFilesProvider[] = {
{ UNK_LANG, kPlatformPC, { 0x00000088, 0x0000224F, { { 0xDA, 0x24, 0x18, 0xA3, 0xEF, 0x16, 0x70, 0x8F, 0xA8, 0xC2, 0x2E, 0xC2, 0xED, 0x39, 0x03, 0xD1 } } } },
{ UNK_LANG, kPlatformPC98, { 0x00000084, 0x00002125, { { 0x7A, 0x89, 0xE2, 0x36, 0xEC, 0x6F, 0x52, 0x2B, 0xEF, 0xBA, 0x3D, 0x28, 0x54, 0xDA, 0xFB, 0x72 } } } },
EXTRACT_END_ENTRY
};
-const ExtractEntrySearchData kLolCharacterDefsProvider[] = {
+const ExtractEntrySearchData kLoLCharacterDefsProvider[] = {
{ RU_RUS, kPlatformPC, { 0x00000492, 0x000052BA, { { 0x52, 0x29, 0x0D, 0x49, 0xFD, 0x17, 0xD7, 0x70, 0x6D, 0xCA, 0xEB, 0xB6, 0x7E, 0xFA, 0xBE, 0x08 } } } }, // floppy
{ EN_ANY, kPlatformPC, { 0x00000492, 0x000046B0, { { 0x7A, 0x94, 0x8B, 0xC6, 0xF7, 0xF1, 0x2F, 0xF3, 0xBC, 0x1B, 0x0B, 0x4E, 0x00, 0xC9, 0x44, 0x58 } } } }, // floppy
{ DE_DEU, kPlatformPC, { 0x00000492, 0x000047FD, { { 0x8C, 0x0B, 0x8B, 0xCE, 0xE0, 0xB0, 0x8F, 0xA9, 0x06, 0xC3, 0x98, 0xE6, 0x2E, 0x09, 0xB6, 0x93 } } } }, // floppy
@@ -1352,7 +3357,7 @@ const ExtractEntrySearchData kLolCharacterDefsProvider[] = {
EXTRACT_END_ENTRY
};
-const ExtractEntrySearchData kLolIngameSfxFilesProvider[] = {
+const ExtractEntrySearchData kLoLIngameSfxFilesProvider[] = {
{ UNK_LANG, kPlatformPC, { 0x000008F2, 0x0001E5B6, { { 0x63, 0x5E, 0x37, 0xAA, 0x27, 0x80, 0x4C, 0x85, 0xB1, 0x9D, 0x7B, 0x1D, 0x64, 0xA3, 0xEB, 0x97 } } } }, // floppy
{ UNK_LANG, kPlatformPC, { 0x000008F2, 0x0001E5B7, { { 0x9E, 0xC8, 0xE8, 0x19, 0x2F, 0x58, 0x0B, 0xC7, 0x2D, 0x41, 0x72, 0xE7, 0xF4, 0x80, 0x03, 0xCB } } } }, // CD
{ UNK_LANG, kPlatformPC98, { 0x000008EF, 0x0001E585, { { 0x85, 0x81, 0x5C, 0xA4, 0x34, 0x44, 0xF4, 0x58, 0xF9, 0x82, 0xEE, 0x0F, 0x6A, 0x0D, 0xA2, 0x7F } } } },
@@ -1360,329 +3365,359 @@ const ExtractEntrySearchData kLolIngameSfxFilesProvider[] = {
EXTRACT_END_ENTRY
};
-const ExtractEntrySearchData kLolIngameSfxIndexProvider[] = {
+const ExtractEntrySearchData kLoLIngameSfxIndexProvider[] = {
{ UNK_LANG, kPlatformUnknown, { 0x000003E8, 0x0000E8D2, { { 0x19, 0x39, 0x17, 0xED, 0xAE, 0xDC, 0x7A, 0xAC, 0x45, 0x5F, 0x2D, 0xCD, 0x65, 0x8D, 0xAD, 0xAE } } } },
EXTRACT_END_ENTRY
};
-const ExtractEntrySearchData kLolMusicTrackMapProvider[] = {
+const ExtractEntrySearchData kLoLMusicTrackMapProvider[] = {
{ UNK_LANG, kPlatformPC, { 0x000000F0, 0x0000210D, { { 0x55, 0x25, 0x3E, 0x35, 0xD2, 0xD8, 0x13, 0xE3, 0x1D, 0xB1, 0xB3, 0x00, 0x2E, 0x17, 0x91, 0x2F } } } },
EXTRACT_END_ENTRY
};
-const ExtractEntrySearchData kLolIngameGMSfxIndexProvider[] = {
+const ExtractEntrySearchData kLoLIngameGMSfxIndexProvider[] = {
{ UNK_LANG, kPlatformPC, { 0x000000FA, 0x00006281, { { 0x25, 0x89, 0xB0, 0x3B, 0x12, 0x09, 0x02, 0xF6, 0xFE, 0x76, 0xD5, 0xC9, 0x5B, 0x88, 0xAC, 0xAA } } } },
EXTRACT_END_ENTRY
};
-const ExtractEntrySearchData kLolIngameMT32SfxIndexProvider[] = {
+const ExtractEntrySearchData kLoLIngameMT32SfxIndexProvider[] = {
{ UNK_LANG, kPlatformPC, { 0x000000FA, 0x00006579, { { 0x16, 0x40, 0x1C, 0x09, 0x69, 0xA9, 0x0D, 0x6D, 0x4B, 0x0C, 0x99, 0xF0, 0x40, 0x5D, 0xBB, 0x6E } } } },
EXTRACT_END_ENTRY
};
-const ExtractEntrySearchData kLolIngamePcSpkSfxIndexProvider[] = {
+const ExtractEntrySearchData kLoLIngamePcSpkSfxIndexProvider[] = {
{ UNK_LANG, kPlatformPC, { 0x000000FA, 0x00005EFC, { { 0xA3, 0x5C, 0x69, 0xED, 0x13, 0xEC, 0x08, 0x0E, 0xFA, 0x72, 0x83, 0x0D, 0xD7, 0x8D, 0x9C, 0x70 } } } },
EXTRACT_END_ENTRY
};
-const ExtractEntrySearchData kLolSpellPropertiesProvider[] = {
+const ExtractEntrySearchData kLoLSpellPropertiesProvider[] = {
{ UNK_LANG, kPlatformUnknown, { 0x00000118, 0x00000B06, { { 0x27, 0x69, 0x53, 0x01, 0xA0, 0xE3, 0x76, 0xAA, 0x33, 0xA4, 0x52, 0x11, 0x52, 0xB1, 0x0E, 0xDA } } } },
EXTRACT_END_ENTRY
};
-const ExtractEntrySearchData kLolGameShapeMapProvider[] = {
+const ExtractEntrySearchData kLoLGameShapeMapProvider[] = {
{ UNK_LANG, kPlatformUnknown, { 0x00000114, 0x000038D3, { { 0xB2, 0x8A, 0x5D, 0x9A, 0x51, 0x63, 0x4D, 0x65, 0xE4, 0xF5, 0xBA, 0x88, 0x70, 0x6C, 0xA6, 0xF8 } } } }, // floppy + PC98
{ UNK_LANG, kPlatformPC, { 0x00000114, 0x00003B97, { { 0x29, 0xE5, 0x0F, 0x51, 0xF0, 0x10, 0x35, 0x3E, 0x70, 0x3A, 0xAA, 0xFE, 0xD7, 0xD5, 0xAA, 0x9F } } } }, // CD
EXTRACT_END_ENTRY
};
-const ExtractEntrySearchData kLolSceneItemOffsProvider[] = {
+const ExtractEntrySearchData kLoLSceneItemOffsProvider[] = {
{ UNK_LANG, kPlatformUnknown, { 0x00000008, 0x00000300, { { 0x69, 0x80, 0x5A, 0x3E, 0x63, 0xC1, 0x04, 0x60, 0x09, 0x2F, 0x49, 0xD7, 0x26, 0x32, 0xAA, 0xE2 } } } },
EXTRACT_END_ENTRY
};
-const ExtractEntrySearchData kLolCharInvIndexProvider[] = {
+const ExtractEntrySearchData kLoLCharInvIndexProvider[] = {
{ UNK_LANG, kPlatformUnknown, { 0x0000000A, 0x00000006, { { 0x19, 0x79, 0x4E, 0xFC, 0x05, 0x14, 0x89, 0x23, 0xEB, 0xCA, 0x94, 0x50, 0xE8, 0xD3, 0x81, 0x24 } } } },
EXTRACT_END_ENTRY
};
-const ExtractEntrySearchData kLolCharInvDefsProvider[] = {
+const ExtractEntrySearchData kLoLCharInvDefsProvider[] = {
{ UNK_LANG, kPlatformUnknown, { 0x00000058, 0x00001D7A, { { 0x25, 0xE4, 0xEB, 0x6D, 0xBE, 0xEA, 0xBD, 0x9A, 0x9F, 0xA5, 0x9E, 0xEB, 0x3D, 0x03, 0x1D, 0x72 } } } },
EXTRACT_END_ENTRY
};
-const ExtractEntrySearchData kLolCharDefsManProvider[] = {
+const ExtractEntrySearchData kLoLCharDefsManProvider[] = {
{ UNK_LANG, kPlatformUnknown, { 0x00000012, 0x0000003D, { { 0xEB, 0x82, 0x32, 0x9D, 0x76, 0xC8, 0x3D, 0x5E, 0x8C, 0x26, 0x53, 0xDF, 0xC1, 0xFD, 0x0F, 0xC5 } } } },
EXTRACT_END_ENTRY
};
-const ExtractEntrySearchData kLolCharDefsWomanProvider[] = {
+const ExtractEntrySearchData kLoLCharDefsWomanProvider[] = {
{ UNK_LANG, kPlatformUnknown, { 0x00000012, 0x0000003D, { { 0xEB, 0x82, 0x32, 0x9D, 0x76, 0xC8, 0x3D, 0x5E, 0x8C, 0x26, 0x53, 0xDF, 0xC1, 0xFD, 0x0F, 0xC5 } } } },
EXTRACT_END_ENTRY
};
-const ExtractEntrySearchData kLolCharDefsKieranProvider[] = {
+const ExtractEntrySearchData kLoLCharDefsKieranProvider[] = {
{ UNK_LANG, kPlatformUnknown, { 0x00000012, 0x000002E3, { { 0xBF, 0xB1, 0x0F, 0x40, 0xBF, 0xA1, 0xD0, 0x2B, 0xC9, 0x80, 0x35, 0x40, 0xA9, 0xA3, 0x01, 0xC8 } } } },
EXTRACT_END_ENTRY
};
-const ExtractEntrySearchData kLolCharDefsAkshelProvider[] = {
+const ExtractEntrySearchData kLoLCharDefsAkshelProvider[] = {
{ UNK_LANG, kPlatformUnknown, { 0x00000012, 0x000002FB, { { 0x47, 0x3C, 0x07, 0x15, 0x20, 0xE6, 0x90, 0x59, 0x55, 0xF2, 0xA7, 0xC3, 0x27, 0x22, 0xAB, 0xDC } } } },
EXTRACT_END_ENTRY
};
-const ExtractEntrySearchData kLolExpRequirementsProvider[] = {
+const ExtractEntrySearchData kLoLExpRequirementsProvider[] = {
{ UNK_LANG, kPlatformUnknown, { 0x0000002C, 0x00000C0A, { { 0x3F, 0x36, 0xFA, 0xE3, 0xB0, 0x76, 0x5E, 0xFF, 0xE9, 0xBA, 0xDF, 0xD0, 0x9D, 0xFF, 0xDD, 0x27 } } } },
EXTRACT_END_ENTRY
};
-const ExtractEntrySearchData kLolMonsterModifiersProvider[] = {
+const ExtractEntrySearchData kLoLMonsterModifiersProvider[] = {
{ UNK_LANG, kPlatformUnknown, { 0x00000018, 0x000002C6, { { 0x38, 0x9A, 0x8B, 0x50, 0xD2, 0x9B, 0x95, 0x38, 0x91, 0x02, 0xA9, 0xBE, 0x78, 0xE5, 0x89, 0x65 } } } }, // floppy + PC98
{ UNK_LANG, kPlatformPC, { 0x00000018, 0x000002EE, { { 0x4E, 0x37, 0x56, 0xE3, 0x42, 0xB3, 0x15, 0x2C, 0x7E, 0x9B, 0x7E, 0x50, 0x32, 0x91, 0x55, 0xBE } } } }, // CD
EXTRACT_END_ENTRY
};
-const ExtractEntrySearchData kLolMonsterShiftOffsetsProvider[] = {
+const ExtractEntrySearchData kLoLMonsterShiftOffsetsProvider[] = {
{ UNK_LANG, kPlatformUnknown, { 0x00000020, 0x00000803, { { 0x30, 0x55, 0x74, 0x0D, 0xC7, 0x3B, 0xD9, 0x5C, 0x26, 0xF0, 0x4E, 0x8F, 0xE4, 0x4D, 0xCB, 0x2A } } } },
EXTRACT_END_ENTRY
};
-const ExtractEntrySearchData kLolMonsterDirFlagsProvider[] = {
+const ExtractEntrySearchData kLoLMonsterDirFlagsProvider[] = {
{ UNK_LANG, kPlatformUnknown, { 0x00000010, 0x00000080, { { 0xE5, 0xA1, 0xE3, 0xCE, 0xA0, 0x5F, 0x15, 0xE9, 0x5B, 0x28, 0x90, 0xC0, 0xDF, 0x21, 0xEC, 0x24 } } } },
EXTRACT_END_ENTRY
};
-const ExtractEntrySearchData kLolMonsterScaleYProvider[] = {
+const ExtractEntrySearchData kLoLMonsterScaleYProvider[] = {
{ UNK_LANG, kPlatformUnknown, { 0x0000001E, 0x00000982, { { 0xE2, 0x71, 0x5F, 0x57, 0x4A, 0x8F, 0x50, 0xDB, 0x3E, 0xDA, 0xAB, 0x10, 0xEB, 0xDB, 0x0D, 0x14 } } } },
EXTRACT_END_ENTRY
};
-const ExtractEntrySearchData kLolMonsterScaleXProvider[] = {
+const ExtractEntrySearchData kLoLMonsterScaleXProvider[] = {
{ UNK_LANG, kPlatformPC, { 0x00000020, 0x00000918, { { 0xF6, 0x14, 0xE6, 0x48, 0x4E, 0x5B, 0x43, 0xCC, 0xCE, 0x4E, 0x98, 0x71, 0x5A, 0xC2, 0x00, 0x1E } } } },
{ UNK_LANG, kPlatformPC98, { 0x0000001D, 0x000008D2, { { 0x1C, 0x25, 0x38, 0xE2, 0xBB, 0xB2, 0xDB, 0x93, 0x1B, 0x25, 0xB6, 0x89, 0xA9, 0x9B, 0x0A, 0xFE } } } },
EXTRACT_END_ENTRY
};
-const ExtractEntrySearchData kLolMonsterScaleWHProvider[] = {
+const ExtractEntrySearchData kLoLMonsterScaleWHProvider[] = {
{ UNK_LANG, kPlatformUnknown, { 0x00000082, 0x00001D2A, { { 0x85, 0x7E, 0x18, 0xDD, 0x74, 0x1C, 0x62, 0x6F, 0xF4, 0xE5, 0xAF, 0x65, 0xEC, 0x6A, 0x90, 0xAD } } } },
EXTRACT_END_ENTRY
};
-const ExtractEntrySearchData kLolFlyingObjectShpProvider[] = {
+const ExtractEntrySearchData kLoLFlyingObjectShpProvider[] = {
{ UNK_LANG, kPlatformUnknown, { 0x00000082, 0x00000252, { { 0xDE, 0x9D, 0x89, 0xAF, 0x0F, 0x50, 0x14, 0x60, 0x68, 0xAF, 0x19, 0xD8, 0x54, 0x8A, 0x36, 0x27 } } } },
EXTRACT_END_ENTRY
};
-const ExtractEntrySearchData kLolInventoryDescProvider[] = {
+const ExtractEntrySearchData kLoLInventoryDescProvider[] = {
{ UNK_LANG, kPlatformUnknown, { 0x00000016, 0x0000082D, { { 0x86, 0xB4, 0xB9, 0x50, 0xB6, 0xDA, 0x29, 0xB2, 0xC0, 0x0D, 0x34, 0x3F, 0x8D, 0x88, 0xAA, 0xE4 } } } },
EXTRACT_END_ENTRY
};
-const ExtractEntrySearchData kLolLevelShpListProvider[] = {
+const ExtractEntrySearchData kLoLLevelShpListProvider[] = {
{ UNK_LANG, kPlatformUnknown, { 0x0000007F, 0x00002090, { { 0x17, 0x31, 0x8A, 0xB5, 0x9B, 0x3A, 0xDA, 0x16, 0x9E, 0xE3, 0xD1, 0x5F, 0xB4, 0x7B, 0xB2, 0x25 } } } },
EXTRACT_END_ENTRY
};
-const ExtractEntrySearchData kLolLevelDatListProvider[] = {
+const ExtractEntrySearchData kLoLLevelDatListProvider[] = {
{ UNK_LANG, kPlatformUnknown, { 0x0000007F, 0x00001FB8, { { 0xF6, 0xE9, 0x98, 0x79, 0x51, 0xCA, 0xA0, 0x35, 0xE4, 0xD0, 0xA1, 0xCD, 0x23, 0x89, 0x7D, 0x11 } } } }, // floppy + PC98
{ UNK_LANG, kPlatformPC, { 0x000000FF, 0x000047EC, { { 0x0D, 0xA5, 0xFD, 0x8A, 0x33, 0xDB, 0x93, 0x43, 0xE2, 0x57, 0x35, 0xEC, 0xA6, 0xCF, 0x7A, 0xA1 } } } }, // CD
EXTRACT_END_ENTRY
};
-const ExtractEntrySearchData kLolCompassDefsProvider[] = {
+const ExtractEntrySearchData kLoLCompassDefsProvider[] = {
{ UNK_LANG, kPlatformUnknown, { 0x00000100, 0x000030EF, { { 0x6F, 0xF0, 0x46, 0x6E, 0xB3, 0x72, 0xCF, 0xC7, 0xE3, 0xAF, 0xBE, 0x63, 0xA1, 0x1C, 0x33, 0x20 } } } },
EXTRACT_END_ENTRY
};
-const ExtractEntrySearchData kLolItemPricesProvider[] = {
+const ExtractEntrySearchData kLoLItemPricesProvider[] = {
{ UNK_LANG, kPlatformPC, { 0x0000005C, 0x00001251, { { 0x18, 0x62, 0x5E, 0xE2, 0xE4, 0x2A, 0xB0, 0xA0, 0x8B, 0x8D, 0x9D, 0x07, 0x5F, 0x83, 0x53, 0xF7 } } } },
EXTRACT_END_ENTRY
};
-const ExtractEntrySearchData kLolStashSetupProvider[] = {
+const ExtractEntrySearchData kLoLStashSetupProvider[] = {
{ UNK_LANG, kPlatformUnknown, { 0x0000000C, 0x0000001E, { { 0x1C, 0x93, 0x66, 0x56, 0xDB, 0xD7, 0xA4, 0xB3, 0xE7, 0x2F, 0xEA, 0x88, 0xE2, 0xC8, 0x79, 0xD0 } } } },
EXTRACT_END_ENTRY
};
-const ExtractEntrySearchData kLolDscUnk1Provider[] = {
+const ExtractEntrySearchData kLoLDscWallsProvider[] = {
{ UNK_LANG, kPlatformUnknown, { 0x00000024, 0x00000A2A, { { 0xAC, 0x4E, 0x73, 0x2C, 0xB0, 0xEE, 0x24, 0x0E, 0x66, 0x8D, 0x48, 0xE5, 0xCA, 0x6B, 0x7F, 0x7F } } } },
EXTRACT_END_ENTRY
};
-const ExtractEntrySearchData kLolDscShapeIndexProvider[] = {
+const ExtractEntrySearchData kRpgCommonDscShapeIndexProvider[] = {
+ // LOL:
{ UNK_LANG, kPlatformUnknown, { 0x00000024, 0x00000728, { { 0x14, 0xBA, 0x6D, 0x5C, 0x7D, 0x20, 0x0D, 0x35, 0xA7, 0xB0, 0x8D, 0x2F, 0x1D, 0x2A, 0x49, 0xA4 } } } },
+ // EOB:
+ { UNK_LANG, kPlatformUnknown, { 0x00000024, 0x00000632, { { 0xBE, 0x3E, 0x84, 0x71, 0x89, 0x04, 0xC9, 0x1D, 0xCF, 0xE4, 0x3B, 0xD8, 0x2A, 0xF4, 0x0F, 0x54 } } } },
EXTRACT_END_ENTRY
};
-const ExtractEntrySearchData kLolDscOvlMapProvider[] = {
+const ExtractEntrySearchData kLoLDscOvlMapProvider[] = {
{ UNK_LANG, kPlatformUnknown, { 0x0000000A, 0x0000001F, { { 0x9C, 0xF2, 0xCC, 0x48, 0x42, 0xC6, 0x76, 0x83, 0xD3, 0x1A, 0x43, 0x42, 0x7F, 0xEF, 0x19, 0x0F } } } },
EXTRACT_END_ENTRY
};
-const ExtractEntrySearchData kLolDscScaleWidthDataProvider[] = {
+const ExtractEntrySearchData kLoLDscScaleWidthDataProvider[] = {
{ UNK_LANG, kPlatformUnknown, { 0x00000048, 0x00000ABE, { { 0x28, 0x9A, 0xAA, 0x16, 0xC4, 0xFD, 0x52, 0xA9, 0x76, 0x98, 0x72, 0x0C, 0x2D, 0xE4, 0xB0, 0x57 } } } },
-
EXTRACT_END_ENTRY
};
-const ExtractEntrySearchData kLolDscScaleHeightDataProvider[] = {
+const ExtractEntrySearchData kLoLDscScaleHeightDataProvider[] = {
{ UNK_LANG, kPlatformUnknown, { 0x00000048, 0x000009E8, { { 0x25, 0x35, 0x07, 0xBC, 0xF9, 0x82, 0x8B, 0x5B, 0x67, 0x7C, 0x38, 0xD1, 0xF8, 0x35, 0x81, 0xC7 } } } },
EXTRACT_END_ENTRY
};
-const ExtractEntrySearchData kLolDscXProvider[] = {
+const ExtractEntrySearchData kRpgCommonDscXProvider[] = {
+ // LOL
{ UNK_LANG, kPlatformUnknown, { 0x00000048, 0x00001468, { { 0x55, 0xC5, 0x30, 0x76, 0x0A, 0xDC, 0xEC, 0xAB, 0x68, 0x9B, 0x61, 0xF0, 0x58, 0x78, 0x56, 0xA6 } } } },
+ // EOB
+ { UNK_LANG, kPlatformUnknown, { 0x00000024, 0x00000BFA, { { 0x5F, 0x86, 0x9B, 0xDA, 0x5D, 0x6E, 0xC0, 0xB9, 0x29, 0x82, 0xA5, 0xD7, 0xC9, 0x34, 0x90, 0x63 } } } },
EXTRACT_END_ENTRY
};
-const ExtractEntrySearchData kLolDscYProvider[] = {
+const ExtractEntrySearchData kLoLDscYProvider[] = {
{ UNK_LANG, kPlatformUnknown, { 0x00000024, 0x00000282, { { 0x09, 0x98, 0x3A, 0x33, 0x15, 0xA1, 0x4A, 0xFF, 0x76, 0x19, 0x2B, 0xB1, 0x74, 0x89, 0xF4, 0x37 } } } },
EXTRACT_END_ENTRY
};
-const ExtractEntrySearchData kLolDscTileIndexProvider[] = {
+const ExtractEntrySearchData kRpgCommonDscTileIndexProvider[] = {
{ UNK_LANG, kPlatformUnknown, { 0x00000012, 0x00000099, { { 0x18, 0xD9, 0x39, 0x27, 0x5B, 0x34, 0xAE, 0x7C, 0xA9, 0xA9, 0xDB, 0x42, 0x49, 0x61, 0x6B, 0x37 } } } },
EXTRACT_END_ENTRY
};
-const ExtractEntrySearchData kLolDscUnk2Provider[] = {
+const ExtractEntrySearchData kRpgCommonDscUnk2Provider[] = {
{ UNK_LANG, kPlatformUnknown, { 0x00000017, 0x000000D2, { { 0xDE, 0xDA, 0x75, 0x15, 0x2B, 0xDC, 0x90, 0x3F, 0xC9, 0x92, 0x04, 0x01, 0x23, 0x7A, 0xDA, 0x2E } } } },
EXTRACT_END_ENTRY
};
-const ExtractEntrySearchData kLolDscDoorShapeIndexProvider[] = {
- { UNK_LANG, kPlatformUnknown, { 0x00000017, 0x0000000A, { { 0x2E, 0xC4, 0xA1, 0x47, 0x7C, 0xAE, 0xAD, 0xD8, 0x8A, 0x72, 0x95, 0x2F, 0x18, 0xC5, 0x08, 0x19 } } } },
-
+const ExtractEntrySearchData kRpgCommonDscDoorShapeIndexProvider[] = {
+ { UNK_LANG, kPlatformUnknown, { 0x00000017, 0x0000000A, { { 0x2E, 0xC4, 0xA1, 0x47, 0x7C, 0xAE, 0xAD, 0xD8, 0x8A, 0x72, 0x95, 0x2F, 0x18, 0xC5, 0x08, 0x19 } } } }, // LOL
+ { UNK_LANG, kPlatformUnknown, { 0x00000020, 0x00000021, { { 0xE3, 0x00, 0x85, 0x1C, 0x13, 0xCE, 0x5D, 0xA7, 0xA2, 0x93, 0x9B, 0x56, 0x1A, 0x0C, 0x43, 0x3E } } } }, // EOB 1
+ { UNK_LANG, kPlatformUnknown, { 0x00000035, 0x0000000B, { { 0xC2, 0xBC, 0xCA, 0x95, 0x69, 0xE8, 0x3F, 0x1F, 0xC2, 0x1C, 0x37, 0x90, 0x63, 0x8F, 0xE6, 0x1D } } } }, // EOB 2
EXTRACT_END_ENTRY
};
-const ExtractEntrySearchData kLolDscDimData1Provider[] = {
+const ExtractEntrySearchData kRpgCommonDscDimData1Provider[] = {
+ // LOL
{ UNK_LANG, kPlatformUnknown, { 0x00000144, 0x0001007D, { { 0x18, 0x3D, 0xA5, 0xF7, 0x1A, 0x5A, 0x90, 0xA7, 0x4E, 0x66, 0x1A, 0x4E, 0x0C, 0x69, 0x58, 0x31 } } } },
-
+ // EOB
+ { UNK_LANG, kPlatformUnknown, { 0x00000144, 0x00010115, { { 0x89, 0x37, 0x1C, 0x85, 0x53, 0xEE, 0xC0, 0xEC, 0x17, 0x26, 0x0B, 0xE5, 0xCC, 0x9C, 0x30, 0x58 } } } },
EXTRACT_END_ENTRY
};
-const ExtractEntrySearchData kLolDscDimData2Provider[] = {
- { UNK_LANG, kPlatformUnknown, { 0x00000289, 0x00001BC2, { { 0x7F, 0x9D, 0xD3, 0x5A, 0x57, 0x73, 0xEA, 0x37, 0x44, 0x5E, 0x1A, 0x88, 0xFB, 0xE8, 0xE8, 0x8F } } } },
+const ExtractEntrySearchData kRpgCommonDscDimData2Provider[] = {
+ { UNK_LANG, kPlatformUnknown, { 0x00000288, 0x00001BC2, { { 0x30, 0xD1, 0xD1, 0x35, 0x74, 0x2C, 0x86, 0x81, 0x23, 0xE2, 0x05, 0xCE, 0x75, 0x60, 0x3C, 0x55 } } } },
EXTRACT_END_ENTRY
};
-const ExtractEntrySearchData kLolDscBlockMapProvider[] = {
+const ExtractEntrySearchData kRpgCommonDscBlockMapProvider[] = {
{ UNK_LANG, kPlatformUnknown, { 0x0000000C, 0x00000012, { { 0x01, 0xEE, 0x32, 0xA6, 0x71, 0x15, 0x8D, 0xFB, 0x33, 0xF2, 0xD6, 0x8A, 0x30, 0x00, 0x10, 0x4B } } } },
EXTRACT_END_ENTRY
};
-const ExtractEntrySearchData kLolDscDimMapProvider[] = {
+const ExtractEntrySearchData kRpgCommonDscDimMapProvider[] = {
{ UNK_LANG, kPlatformUnknown, { 0x00000012, 0x00000014, { { 0x4D, 0x53, 0x2E, 0xF2, 0xA3, 0xF9, 0xE2, 0xEC, 0x44, 0xBE, 0x5F, 0x04, 0x91, 0xF8, 0xE1, 0x04 } } } },
EXTRACT_END_ENTRY
};
-const ExtractEntrySearchData kLolDscOvlIndexProvider[] = {
+const ExtractEntrySearchData kLoLDscOvlIndexProvider[] = {
{ UNK_LANG, kPlatformUnknown, { 0x00000028, 0x00000048, { { 0x3E, 0x8E, 0x62, 0xAF, 0xD1, 0x28, 0x39, 0x73, 0x0D, 0xD8, 0x4A, 0xA7, 0xF4, 0xD7, 0x32, 0x25 } } } },
EXTRACT_END_ENTRY
};
-const ExtractEntrySearchData kLolDscBlockIndexProvider[] = {
+const ExtractEntrySearchData kRpgCommonDscBlockIndexProvider[] = {
{ UNK_LANG, kPlatformUnknown, { 0x00000048, 0x00002200, { { 0xF4, 0x8B, 0x32, 0xC3, 0xD3, 0xFB, 0x46, 0xF2, 0xB8, 0x3A, 0x58, 0x39, 0x94, 0x57, 0x97, 0x4B } } } },
EXTRACT_END_ENTRY
};
-const ExtractEntrySearchData kLolDscDoor1Provider[] = {
- { UNK_LANG, kPlatformUnknown, { 0x00000080, 0x00000348, { { 0xC6, 0x58, 0x8B, 0xFE, 0x18, 0x72, 0x47, 0xF1, 0xB6, 0x3A, 0x0F, 0xFB, 0x3D, 0x99, 0x74, 0xD0 } } } },
+const ExtractEntrySearchData kRpgCommonDscDoorY2Provider[] = {
+ { UNK_LANG, kPlatformUnknown, { 0x00000080, 0x00000348, { { 0xC6, 0x58, 0x8B, 0xFE, 0x18, 0x72, 0x47, 0xF1, 0xB6, 0x3A, 0x0F, 0xFB, 0x3D, 0x99, 0x74, 0xD0 } } } }, // LOL
+ { UNK_LANG, kPlatformUnknown, { 0x00000004, 0x00000046, { { 0x35, 0x36, 0xBC, 0xD8, 0x63, 0x25, 0x31, 0xA9, 0x61, 0x8E, 0xF6, 0x54, 0x4A, 0x79, 0x17, 0xF8 } } } }, // EOB
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kRpgCommonDscDoorFrameY1Provider[] = {
+ { UNK_LANG, kPlatformUnknown, { 0x00000020, 0x0000053B, { { 0xF0, 0x9E, 0xC5, 0xB1, 0xEA, 0x5A, 0x58, 0xBD, 0xAC, 0x7B, 0xB2, 0xD4, 0xFE, 0x3F, 0x4F, 0x51 } } } }, // EOB I
+ { UNK_LANG, kPlatformUnknown, { 0x00000004, 0x00000046, { { 0xD4, 0xA4, 0xEC, 0xA2, 0x99, 0xB6, 0x5E, 0x12, 0x98, 0xFF, 0xF2, 0x55, 0xC8, 0xBD, 0xC5, 0x8F } } } }, // EOB II
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kRpgCommonDscDoorFrameY2Provider[] = {
+ { UNK_LANG, kPlatformUnknown, { 0x00000020, 0x0000053B, { { 0xF0, 0x9E, 0xC5, 0xB1, 0xEA, 0x5A, 0x58, 0xBD, 0xAC, 0x7B, 0xB2, 0xD4, 0xFE, 0x3F, 0x4F, 0x51 } } } }, // EOB I
+ { UNK_LANG, kPlatformUnknown, { 0x00000004, 0x00000150, { { 0x49, 0x7E, 0xF4, 0xDF, 0x8D, 0x04, 0x0A, 0xCE, 0x49, 0xBB, 0xA2, 0x1D, 0x8D, 0xC2, 0x14, 0x9E } } } }, // EOB II
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kRpgCommonDscDoorFrameIndex1Provider[] = {
+ { UNK_LANG, kPlatformUnknown, { 0x0000000C, 0x00000058, { { 0xC9, 0xAF, 0x1F, 0x68, 0xF1, 0xDE, 0x96, 0x9B, 0x3B, 0xCB, 0x56, 0xEC, 0x2E, 0x62, 0x9A, 0x0A } } } },
+ EXTRACT_END_ENTRY
+};
+const ExtractEntrySearchData kRpgCommonDscDoorFrameIndex2Provider[] = {
+ { UNK_LANG, kPlatformUnknown, { 0x0000000C, 0x000000E8, { { 0x8C, 0x10, 0x56, 0xEA, 0x4D, 0x1A, 0x9C, 0xB2, 0x55, 0x54, 0xA5, 0x61, 0x1D, 0x19, 0x4E, 0x50 } } } },
EXTRACT_END_ENTRY
};
-const ExtractEntrySearchData kLolDscDoorScaleProvider[] = {
+const ExtractEntrySearchData kLoLDscDoorScaleProvider[] = {
{ UNK_LANG, kPlatformUnknown, { 0x00000010, 0x0000024C, { { 0x8D, 0x83, 0x26, 0xEE, 0xDC, 0xF7, 0x13, 0xC0, 0xAA, 0x88, 0xC2, 0xAA, 0x66, 0xA7, 0x59, 0x41 } } } },
EXTRACT_END_ENTRY
};
-const ExtractEntrySearchData kLolDscDoor4Provider[] = {
+const ExtractEntrySearchData kLoLDscDoor4Provider[] = {
{ UNK_LANG, kPlatformUnknown, { 0x00000008, 0x00000103, { { 0x29, 0xC0, 0x4B, 0x7F, 0x36, 0x23, 0xBB, 0x38, 0x4C, 0x83, 0xC6, 0x9D, 0xB4, 0x8F, 0x29, 0x2E } } } },
EXTRACT_END_ENTRY
};
-const ExtractEntrySearchData kLolDscDoorXProvider[] = {
+const ExtractEntrySearchData kLoLDscDoorXProvider[] = {
{ UNK_LANG, kPlatformUnknown, { 0x00000480, 0x0001654D, { { 0x2A, 0x1F, 0xBF, 0xE3, 0xC4, 0xEF, 0x7E, 0xD1, 0x61, 0x51, 0xFE, 0x88, 0x8D, 0x1F, 0x59, 0x70 } } } },
EXTRACT_END_ENTRY
};
-const ExtractEntrySearchData kLolDscDoorYProvider[] = {
+const ExtractEntrySearchData kLoLDscDoorYProvider[] = {
{ UNK_LANG, kPlatformUnknown, { 0x00000480, 0x00026666, { { 0x06, 0xBF, 0xA4, 0xD4, 0x6E, 0x29, 0x42, 0xA2, 0xA0, 0x8E, 0x3C, 0x14, 0xF3, 0xD6, 0x3F, 0x87 } } } },
EXTRACT_END_ENTRY
};
-const ExtractEntrySearchData kLolScrollXTopProvider[] = {
+const ExtractEntrySearchData kLoLScrollXTopProvider[] = {
{ UNK_LANG, kPlatformUnknown, { 0x0000000A, 0x0000004B, { { 0x18, 0x1E, 0x6E, 0xE9, 0x34, 0xF0, 0x02, 0xC6, 0x57, 0x34, 0xDF, 0x55, 0xD9, 0x39, 0xE8, 0x98 } } } },
EXTRACT_END_ENTRY
};
-const ExtractEntrySearchData kLolScrollYTopProvider[] = {
+const ExtractEntrySearchData kLoLScrollYTopProvider[] = {
{ UNK_LANG, kPlatformUnknown, { 0x0000000A, 0x00000022, { { 0xF3, 0x20, 0x5A, 0xC1, 0xBB, 0x0C, 0x79, 0x52, 0x23, 0xC1, 0x36, 0x81, 0x70, 0x2F, 0x92, 0xFC } } } },
EXTRACT_END_ENTRY
};
-const ExtractEntrySearchData kLolScrollXBottomProvider[] = {
+const ExtractEntrySearchData kLoLScrollXBottomProvider[] = {
{ UNK_LANG, kPlatformUnknown, { 0x0000000A, 0x0000004B, { { 0x18, 0x1E, 0x6E, 0xE9, 0x34, 0xF0, 0x02, 0xC6, 0x57, 0x34, 0xDF, 0x55, 0xD9, 0x39, 0xE8, 0x98 } } } },
EXTRACT_END_ENTRY
};
-const ExtractEntrySearchData kLolScrollYBottomProvider[] = {
+const ExtractEntrySearchData kLoLScrollYBottomProvider[] = {
{ UNK_LANG, kPlatformUnknown, { 0x0000000A, 0x0000003C, { { 0x5B, 0x4F, 0xB7, 0xB5, 0x55, 0xA2, 0x9A, 0x21, 0xEF, 0xB4, 0x98, 0x47, 0x05, 0x57, 0x49, 0x55 } } } },
EXTRACT_END_ENTRY
};
-const ExtractEntrySearchData kLolButtonDefsProvider[] = {
+const ExtractEntrySearchData kLoLButtonDefsProvider[] = {
{ UNK_LANG, kPlatformPC, { 0x0000082A, 0x0000CAAE, { { 0xC1, 0x83, 0x0D, 0xA0, 0x66, 0x16, 0x3D, 0x31, 0xCE, 0x30, 0x9F, 0x4E, 0x00, 0x65, 0x5A, 0xC8 } } } }, // floppy
{ UNK_LANG, kPlatformPC, { 0x0000082A, 0x0000C34E, { { 0x7F, 0x9A, 0x0F, 0x28, 0x1A, 0x8F, 0x03, 0x46, 0x48, 0xEB, 0xC9, 0xB9, 0x23, 0x29, 0x5E, 0x50 } } } }, // floppy
{ UNK_LANG, kPlatformPC, { 0x0000082A, 0x0000C47B, { { 0xDF, 0x1A, 0x18, 0x1F, 0x58, 0x05, 0x1F, 0x56, 0xD8, 0x6D, 0xBB, 0x93, 0xEC, 0x35, 0x9D, 0xA5 } } } }, // CD
@@ -1691,110 +3726,110 @@ const ExtractEntrySearchData kLolButtonDefsProvider[] = {
EXTRACT_END_ENTRY
};
-const ExtractEntrySearchData kLolButtonList1Provider[] = {
+const ExtractEntrySearchData kLoLButtonList1Provider[] = {
{ UNK_LANG, kPlatformUnknown, { 0x00000050, 0x00000A37, { { 0x0F, 0x73, 0xEC, 0xDD, 0xAB, 0xFF, 0x49, 0x46, 0x5E, 0x8F, 0x0D, 0xC3, 0xE7, 0x1B, 0x89, 0x51 } } } },
EXTRACT_END_ENTRY
};
-const ExtractEntrySearchData kLolButtonList2Provider[] = {
+const ExtractEntrySearchData kLoLButtonList2Provider[] = {
{ UNK_LANG, kPlatformUnknown, { 0x0000001E, 0x00000522, { { 0xEA, 0x41, 0x46, 0xE2, 0xFE, 0xAA, 0x7D, 0x5E, 0x89, 0x7F, 0xBF, 0x9B, 0x30, 0x60, 0x74, 0xF3 } } } },
EXTRACT_END_ENTRY
};
-const ExtractEntrySearchData kLolButtonList3Provider[] = {
+const ExtractEntrySearchData kLoLButtonList3Provider[] = {
{ UNK_LANG, kPlatformUnknown, { 0x00000004, 0x0000023E, { { 0x70, 0xAA, 0xCA, 0xAC, 0x5C, 0x21, 0xCF, 0xA5, 0xBF, 0x7F, 0x5F, 0xBC, 0xF1, 0x24, 0x8A, 0xAF } } } },
EXTRACT_END_ENTRY
};
-const ExtractEntrySearchData kLolButtonList4Provider[] = {
+const ExtractEntrySearchData kLoLButtonList4Provider[] = {
{ UNK_LANG, kPlatformUnknown, { 0x0000001E, 0x0000054D, { { 0x19, 0x2A, 0xBE, 0x7F, 0x94, 0x10, 0xA0, 0x60, 0x2A, 0x33, 0xD6, 0x11, 0x85, 0xF0, 0xA4, 0xA9 } } } },
EXTRACT_END_ENTRY
};
-const ExtractEntrySearchData kLolButtonList5Provider[] = {
+const ExtractEntrySearchData kLoLButtonList5Provider[] = {
{ UNK_LANG, kPlatformUnknown, { 0x00000020, 0x0000045D, { { 0xE3, 0x7C, 0xC2, 0x36, 0x21, 0x46, 0xDB, 0xF3, 0xDD, 0x38, 0x4B, 0x40, 0xE0, 0x35, 0x09, 0xC3 } } } },
EXTRACT_END_ENTRY
};
-const ExtractEntrySearchData kLolButtonList6Provider[] = {
+const ExtractEntrySearchData kLoLButtonList6Provider[] = {
{ UNK_LANG, kPlatformUnknown, { 0x0000001C, 0x000004C4, { { 0x21, 0x7C, 0x29, 0x3F, 0x95, 0x6F, 0x91, 0x8C, 0xB2, 0x30, 0x09, 0xA6, 0x7B, 0x48, 0x44, 0x8F } } } },
EXTRACT_END_ENTRY
};
-const ExtractEntrySearchData kLolButtonList7Provider[] = {
+const ExtractEntrySearchData kLoLButtonList7Provider[] = {
{ UNK_LANG, kPlatformUnknown, { 0x00000006, 0x0000021D, { { 0xDC, 0xCE, 0x1B, 0xEB, 0x11, 0x6D, 0xDE, 0x37, 0x17, 0xC8, 0x06, 0x51, 0xC3, 0x0C, 0xCB, 0xA6 } } } },
EXTRACT_END_ENTRY
};
-const ExtractEntrySearchData kLolButtonList8Provider[] = {
+const ExtractEntrySearchData kLoLButtonList8Provider[] = {
{ UNK_LANG, kPlatformUnknown, { 0x00000004, 0x00000253, { { 0x0C, 0x7B, 0x10, 0x99, 0x93, 0xD0, 0x33, 0xCA, 0xAB, 0x8D, 0x7E, 0x24, 0xE5, 0x7E, 0x6C, 0x91 } } } },
EXTRACT_END_ENTRY
};
-const ExtractEntrySearchData kLolLegendDataProvider[] = {
+const ExtractEntrySearchData kLoLLegendDataProvider[] = {
{ UNK_LANG, kPlatformUnknown, { 0x00000030, 0x00000858, { { 0x63, 0x5E, 0x60, 0xC7, 0x62, 0x2C, 0x5D, 0x8F, 0x74, 0x71, 0x98, 0xB7, 0x09, 0xD2, 0x51, 0xC7 } } } },
{ UNK_LANG, kPlatformUnknown, { 0x0000003C, 0x00000A52, { { 0x81, 0xC5, 0xA4, 0xE7, 0x60, 0xDA, 0xD6, 0x5E, 0x19, 0xAB, 0xF3, 0xC7, 0xDD, 0xDB, 0x92, 0x5E } } } },
EXTRACT_END_ENTRY
};
-const ExtractEntrySearchData kLolMapCursorOvlProvider[] = {
+const ExtractEntrySearchData kLoLMapCursorOvlProvider[] = {
{ UNK_LANG, kPlatformPC, { 0x00000019, 0x000009CD, { { 0xF6, 0xD2, 0xFA, 0x36, 0x62, 0x95, 0x1D, 0x99, 0x7F, 0x11, 0x5F, 0xA8, 0x4D, 0x47, 0x72, 0x40 } } } },
EXTRACT_END_ENTRY
};
-const ExtractEntrySearchData kLolMapStringIdProvider[] = {
+const ExtractEntrySearchData kLoLMapStringIdProvider[] = {
{ UNK_LANG, kPlatformUnknown, { 0x0000003C, 0x00000CFB, { { 0xE3, 0xC3, 0x41, 0x06, 0xD1, 0x71, 0x77, 0x78, 0xAD, 0x39, 0xAE, 0x2C, 0x16, 0x21, 0x45, 0xB7 } } } },
EXTRACT_END_ENTRY
};
-const ExtractEntrySearchData kLolSpellbookAnimProvider[] = {
+const ExtractEntrySearchData kLoLSpellbookAnimProvider[] = {
{ UNK_LANG, kPlatformUnknown, { 0x00000038, 0x000003A1, { { 0x50, 0xA0, 0xF6, 0xA7, 0x53, 0x96, 0x86, 0x49, 0xB0, 0x8D, 0xA8, 0xB2, 0x2D, 0x9A, 0xE2, 0x1F } } } },
EXTRACT_END_ENTRY
};
-const ExtractEntrySearchData kLolSpellbookCoordsProvider[] = {
+const ExtractEntrySearchData kLoLSpellbookCoordsProvider[] = {
{ UNK_LANG, kPlatformUnknown, { 0x00000018, 0x0000018F, { { 0xA5, 0xF6, 0x8A, 0x58, 0x9A, 0xC7, 0x3C, 0x3A, 0xB5, 0x87, 0x89, 0x87, 0x73, 0x51, 0x9B, 0x1B } } } },
EXTRACT_END_ENTRY
};
-const ExtractEntrySearchData kLolHealShapeFramesProvider[] = {
+const ExtractEntrySearchData kLoLHealShapeFramesProvider[] = {
{ UNK_LANG, kPlatformUnknown, { 0x00000050, 0x000000F4, { { 0xC9, 0x6E, 0x39, 0xE1, 0xD7, 0xAD, 0x10, 0x4F, 0xE2, 0xFE, 0xDC, 0xAD, 0x00, 0x9D, 0x41, 0xEF } } } },
EXTRACT_END_ENTRY
};
-const ExtractEntrySearchData kLolLightningDefsProvider[] = {
+const ExtractEntrySearchData kLoLLightningDefsProvider[] = {
{ UNK_LANG, kPlatformUnknown, { 0x00000014, 0x00000385, { { 0x68, 0x39, 0x65, 0xCB, 0xA9, 0x80, 0x90, 0xFB, 0xDD, 0x77, 0x0C, 0x76, 0x5A, 0xB5, 0x05, 0x03 } } } },
EXTRACT_END_ENTRY
};
-const ExtractEntrySearchData kLolFireballCoordsProvider[] = {
+const ExtractEntrySearchData kLoLFireballCoordsProvider[] = {
{ UNK_LANG, kPlatformUnknown, { 0x00000200, 0x0000FD81, { { 0xB3, 0xE0, 0x6F, 0x89, 0xCD, 0xE5, 0xA9, 0x6A, 0x4B, 0x61, 0x7A, 0x3F, 0x47, 0x26, 0x73, 0x58 } } } },
EXTRACT_END_ENTRY
};
-const ExtractEntrySearchData kLolCreditsProvider[] = {
+const ExtractEntrySearchData kLoLCreditsProvider[] = {
{ JA_JPN , kPlatformPC98, { 0x000005E7, 0x0001A1B0, { { 0x2A, 0xD0, 0x38, 0x84, 0x0C, 0x38, 0xCB, 0x52, 0x5D, 0x82, 0xBE, 0x03, 0x76, 0xFA, 0x0A, 0x4A } } } },
EXTRACT_END_ENTRY
};
-const ExtractEntrySearchData kLolHistoryProvider[] = {
+const ExtractEntrySearchData kLoLHistoryProvider[] = {
{ UNK_LANG, kPlatformPC, { 0x000001D1, 0x00007F9B, { { 0x25, 0x10, 0x86, 0x40, 0xAC, 0x53, 0xFE, 0x11, 0x4D, 0xE2, 0xD9, 0x35, 0xD6, 0x89, 0xBB, 0x09 } } } },
EXTRACT_END_ENTRY
@@ -1934,81 +3969,472 @@ const ExtractEntry extractProviders[] = {
{ k3ItemAnimData, k3ItemAnimDataProvider },
{ k3ItemMagicTable, k3ItemMagicTableProvider },
{ k3ItemStringMap, k3ItemStringMapProvider },
- { kLolIngamePakFiles, kLolIngamePakFilesProvider },
- { kLolCharacterDefs, kLolCharacterDefsProvider },
- { kLolIngameSfxFiles, kLolIngameSfxFilesProvider },
- { kLolIngameSfxIndex, kLolIngameSfxIndexProvider },
- { kLolMusicTrackMap, kLolMusicTrackMapProvider },
- { kLolIngameGMSfxIndex, kLolIngameGMSfxIndexProvider },
- { kLolIngameMT32SfxIndex, kLolIngameMT32SfxIndexProvider },
- { kLolIngamePcSpkSfxIndex, kLolIngamePcSpkSfxIndexProvider },
- { kLolSpellProperties, kLolSpellPropertiesProvider },
- { kLolGameShapeMap, kLolGameShapeMapProvider },
- { kLolSceneItemOffs, kLolSceneItemOffsProvider },
- { kLolCharInvIndex, kLolCharInvIndexProvider },
- { kLolCharInvDefs, kLolCharInvDefsProvider },
- { kLolCharDefsMan, kLolCharDefsManProvider },
- { kLolCharDefsWoman, kLolCharDefsWomanProvider },
- { kLolCharDefsKieran, kLolCharDefsKieranProvider },
- { kLolCharDefsAkshel, kLolCharDefsAkshelProvider },
- { kLolExpRequirements, kLolExpRequirementsProvider },
- { kLolMonsterModifiers, kLolMonsterModifiersProvider },
- { kLolMonsterShiftOffsets, kLolMonsterShiftOffsetsProvider },
- { kLolMonsterDirFlags, kLolMonsterDirFlagsProvider },
- { kLolMonsterScaleY, kLolMonsterScaleYProvider },
- { kLolMonsterScaleX, kLolMonsterScaleXProvider },
- { kLolMonsterScaleWH, kLolMonsterScaleWHProvider },
- { kLolFlyingObjectShp, kLolFlyingObjectShpProvider },
- { kLolInventoryDesc, kLolInventoryDescProvider },
- { kLolLevelShpList, kLolLevelShpListProvider },
- { kLolLevelDatList, kLolLevelDatListProvider },
- { kLolCompassDefs, kLolCompassDefsProvider },
- { kLolItemPrices, kLolItemPricesProvider },
- { kLolStashSetup, kLolStashSetupProvider },
- { kLolDscUnk1, kLolDscUnk1Provider },
- { kLolDscShapeIndex, kLolDscShapeIndexProvider },
- { kLolDscOvlMap, kLolDscOvlMapProvider },
- { kLolDscScaleWidthData, kLolDscScaleWidthDataProvider },
- { kLolDscScaleHeightData, kLolDscScaleHeightDataProvider },
- { kLolDscX, kLolDscXProvider },
- { kLolDscY, kLolDscYProvider },
- { kLolDscTileIndex, kLolDscTileIndexProvider },
- { kLolDscUnk2, kLolDscUnk2Provider },
- { kLolDscDoorShapeIndex, kLolDscDoorShapeIndexProvider },
- { kLolDscDimData1, kLolDscDimData1Provider },
- { kLolDscDimData2, kLolDscDimData2Provider },
- { kLolDscBlockMap, kLolDscBlockMapProvider },
- { kLolDscDimMap, kLolDscDimMapProvider },
- { kLolDscOvlIndex, kLolDscOvlIndexProvider },
- { kLolDscBlockIndex, kLolDscBlockIndexProvider },
- { kLolDscDoor1, kLolDscDoor1Provider },
- { kLolDscDoorScale, kLolDscDoorScaleProvider },
- { kLolDscDoor4, kLolDscDoor4Provider },
- { kLolDscDoorX, kLolDscDoorXProvider },
- { kLolDscDoorY, kLolDscDoorYProvider },
- { kLolScrollXTop, kLolScrollXTopProvider },
- { kLolScrollYTop, kLolScrollYTopProvider },
- { kLolScrollXBottom, kLolScrollXBottomProvider },
- { kLolScrollYBottom, kLolScrollYBottomProvider },
- { kLolButtonDefs, kLolButtonDefsProvider },
- { kLolButtonList1, kLolButtonList1Provider },
- { kLolButtonList2, kLolButtonList2Provider },
- { kLolButtonList3, kLolButtonList3Provider },
- { kLolButtonList4, kLolButtonList4Provider },
- { kLolButtonList5, kLolButtonList5Provider },
- { kLolButtonList6, kLolButtonList6Provider },
- { kLolButtonList7, kLolButtonList7Provider },
- { kLolButtonList8, kLolButtonList8Provider },
- { kLolLegendData, kLolLegendDataProvider },
- { kLolMapCursorOvl, kLolMapCursorOvlProvider },
- { kLolMapStringId, kLolMapStringIdProvider },
- { kLolSpellbookAnim, kLolSpellbookAnimProvider },
- { kLolSpellbookCoords, kLolSpellbookCoordsProvider },
- { kLolHealShapeFrames, kLolHealShapeFramesProvider },
- { kLolLightningDefs, kLolLightningDefsProvider },
- { kLolFireballCoords, kLolFireballCoordsProvider },
- { kLolCredits, kLolCreditsProvider },
- { kLolHistory, kLolHistoryProvider },
+
+ { kEoBBaseChargenStrings1, kEoBBaseChargenStrings1Provider },
+ { kEoBBaseChargenStrings2, kEoBBaseChargenStrings2Provider },
+ { kEoBBaseChargenStartLevels, kEoBBaseChargenStartLevelsProvider },
+ { kEoBBaseChargenStatStrings, kEoBBaseChargenStatStringsProvider },
+ { kEoBBaseChargenRaceSexStrings, kEoBBaseChargenRaceSexStringsProvider },
+ { kEoBBaseChargenClassStrings, kEoBBaseChargenClassStringsProvider },
+ { kEoBBaseChargenAlignmentStrings, kEoBBaseChargenAlignmentStringsProvider },
+ { kEoBBaseChargenEnterGameStrings, kEoBBaseChargenEnterGameStringsProvider },
+ { kEoBBaseChargenClassMinStats, kEoBBaseChargenClassMinStatsProvider },
+ { kEoBBaseChargenRaceMinStats, kEoBBaseChargenRaceMinStatsProvider },
+ { kEoBBaseChargenRaceMaxStats, kEoBBaseChargenRaceMaxStatsProvider },
+
+ { kEoBBaseSaveThrowTable1, kEoBBaseSaveThrowTable1Provider },
+ { kEoBBaseSaveThrowTable2, kEoBBaseSaveThrowTable2Provider },
+ { kEoBBaseSaveThrowTable3, kEoBBaseSaveThrowTable3Provider },
+ { kEoBBaseSaveThrowTable4, kEoBBaseSaveThrowTable4Provider },
+ { kEoBBaseSaveThrwLvlIndex, kEoBBaseSaveThrwLvlIndexProvider },
+ { kEoBBaseSaveThrwModDiv, kEoBBaseSaveThrwModDivProvider },
+ { kEoBBaseSaveThrwModExt, kEoBBaseSaveThrwModExtProvider },
+
+ { kEoBBasePryDoorStrings, kEoBBasePryDoorStringsProvider },
+ { kEoBBaseWarningStrings, kEoBBaseWarningStringsProvider },
+
+ { kEoBBaseItemSuffixStringsRings, kEoBBaseItemSuffixStringsRingsProvider },
+ { kEoBBaseItemSuffixStringsPotions, kEoBBaseItemSuffixStringsPotionsProvider },
+ { kEoBBaseItemSuffixStringsWands, kEoBBaseItemSuffixStringsWandsProvider },
+
+ { kEoBBaseRipItemStrings, kEoBBaseRipItemStringsProvider },
+ { kEoBBaseCursedString, kEoBBaseCursedStringProvider },
+ { kEoBBaseEnchantedString, kEoBBaseEnchantedStringProvider },
+ { kEoBBaseMagicObjectStrings, kEoBBaseMagicObjectStringsProvider },
+ { kEoBBaseMagicObject5String, kEoBBaseMagicObject5StringProvider },
+ { kEoBBasePatternSuffix, kEoBBasePatternSuffixProvider },
+ { kEoBBasePatternGrFix1, kEoBBasePatternGrFix1Provider },
+ { kEoBBasePatternGrFix2, kEoBBasePatternGrFix2Provider },
+ { kEoBBaseValidateArmorString, kEoBBaseValidateArmorStringProvider },
+ { kEoBBaseValidateCursedString, kEoBBaseValidateCursedStringProvider },
+ { kEoBBaseValidateNoDropString, kEoBBaseValidateNoDropStringProvider },
+ { kEoBBasePotionStrings, kEoBBasePotionStringsProvider },
+ { kEoBBaseWandString, kEoBBaseWandStringProvider },
+ { kEoBBaseItemMisuseStrings, kEoBBaseItemMisuseStringsProvider },
+
+ { kEoBBaseTakenStrings, kEoBBaseTakenStringsProvider },
+ { kEoBBasePotionEffectStrings, kEoBBasePotionEffectStringsProvider },
+
+ { kEoBBaseYesNoStrings, kEoBBaseYesNoStringsProvider },
+ { kRpgCommonMoreStrings, kRpgCommonMoreStringsProvider },
+ { kEoBBaseNpcMaxStrings, kEoBBaseNpcMaxStringsProvider },
+ { kEoBBaseOkStrings, kEoBBaseOkStringsProvider },
+ { kEoBBaseNpcJoinStrings, kEoBBaseNpcJoinStringsProvider },
+ { kEoBBaseCancelStrings, kEoBBaseCancelStringsProvider },
+ { kEoBBaseAbortStrings, kEoBBaseAbortStringsProvider },
+
+ { kEoBBaseMenuStringsMain, kEoBBaseMenuStringsMainProvider },
+ { kEoBBaseMenuStringsSaveLoad, kEoBBaseMenuStringsSaveLoadProvider },
+ { kEoBBaseMenuStringsOnOff, kEoBBaseMenuStringsOnOffProvider },
+ { kEoBBaseMenuStringsSpells, kEoBBaseMenuStringsSpellsProvider },
+ { kEoBBaseMenuStringsRest, kEoBBaseMenuStringsRestProvider },
+ { kEoBBaseMenuStringsDrop, kEoBBaseMenuStringsDropProvider },
+ { kEoBBaseMenuStringsExit, kEoBBaseMenuStringsExitProvider },
+ { kEoBBaseMenuStringsStarve, kEoBBaseMenuStringsStarveProvider },
+ { kEoBBaseMenuStringsScribe, kEoBBaseMenuStringsScribeProvider },
+ { kEoBBaseMenuStringsDrop2, kEoBBaseMenuStringsDrop2Provider },
+ { kEoBBaseMenuStringsHead, kEoBBaseMenuStringsHeadProvider },
+ { kEoBBaseMenuStringsPoison, kEoBBaseMenuStringsPoisonProvider },
+ { kEoBBaseMenuStringsMgc, kEoBBaseMenuStringsMgcProvider },
+ { kEoBBaseMenuStringsPrefs, kEoBBaseMenuStringsPrefsProvider },
+ { kEoBBaseMenuStringsRest2, kEoBBaseMenuStringsRest2Provider },
+ { kEoBBaseMenuStringsRest3, kEoBBaseMenuStringsRest3Provider },
+ { kEoBBaseMenuStringsRest4, kEoBBaseMenuStringsRest4Provider },
+ { kEoBBaseMenuStringsDefeat, kEoBBaseMenuStringsDefeatProvider },
+ { kEoBBaseMenuStringsTransfer, kEoBBaseMenuStringsTransferProvider },
+ { kEoBBaseMenuStringsSpec, kEoBBaseMenuStringsSpecProvider },
+ { kEoBBaseMenuStringsSpellNo, kEoBBaseMenuStringsSpellNoProvider },
+ { kEoBBaseMenuYesNoStrings, kEoBBaseMenuYesNoStringsProvider },
+
+ { kEoBBaseSpellLevelsMage, kEoBBaseSpellLevelsMageProvider },
+ { kEoBBaseSpellLevelsCleric, kEoBBaseSpellLevelsClericProvider },
+ { kEoBBaseNumSpellsCleric, kEoBBaseNumSpellsClericProvider },
+ { kEoBBaseNumSpellsWisAdj, kEoBBaseNumSpellsWisAdjProvider },
+ { kEoBBaseNumSpellsPal, kEoBBaseNumSpellsPalProvider },
+ { kEoBBaseNumSpellsMage, kEoBBaseNumSpellsMageProvider },
+
+ { kEoBBaseCharGuiStringsHp, kEoBBaseCharGuiStringsHpProvider },
+ { kEoBBaseCharGuiStringsWp1, kEoBBaseCharGuiStringsWp1Provider },
+ { kEoBBaseCharGuiStringsWp2, kEoBBaseCharGuiStringsWp2Provider },
+ { kEoBBaseCharGuiStringsWr, kEoBBaseCharGuiStringsWrProvider },
+ { kEoBBaseCharGuiStringsSt1, kEoBBaseCharGuiStringsSt1Provider },
+ { kEoBBaseCharGuiStringsSt2, kEoBBaseCharGuiStringsSt2Provider },
+ { kEoBBaseCharGuiStringsIn, kEoBBaseCharGuiStringsInProvider },
+
+ { kEoBBaseCharStatusStrings7, kEoBBaseCharStatusStrings7Provider },
+ { kEoBBaseCharStatusStrings81, kEoBBaseCharStatusStrings81Provider },
+ { kEoBBaseCharStatusStrings82, kEoBBaseCharStatusStrings82Provider },
+ { kEoBBaseCharStatusStrings9, kEoBBaseCharStatusStrings9Provider },
+ { kEoBBaseCharStatusStrings12, kEoBBaseCharStatusStrings12Provider },
+ { kEoBBaseCharStatusStrings131, kEoBBaseCharStatusStrings131Provider },
+ { kEoBBaseCharStatusStrings132, kEoBBaseCharStatusStrings132Provider },
+
+ { kEoBBaseLevelGainStrings, kEoBBaseLevelGainStringsProvider },
+ { kEoBBaseExperienceTable0, kEoBBaseExperienceTable0Provider },
+ { kEoBBaseExperienceTable1, kEoBBaseExperienceTable1Provider },
+ { kEoBBaseExperienceTable2, kEoBBaseExperienceTable2Provider },
+ { kEoBBaseExperienceTable3, kEoBBaseExperienceTable3Provider },
+ { kEoBBaseExperienceTable4, kEoBBaseExperienceTable4Provider },
+
+ { kEoBBaseWllFlagPreset, kEoBBaseWllFlagPresetProvider },
+ { kEoBBaseDscShapeCoords, kEoBBaseDscShapeCoordsProvider },
+ { kEoBBaseDscDoorScaleOffs, kEoBBaseDscDoorScaleOffsProvider },
+ { kEoBBaseDscDoorScaleMult1, kEoBBaseDscDoorScaleMult1Provider },
+ { kEoBBaseDscDoorScaleMult2, kEoBBaseDscDoorScaleMult2Provider },
+ { kEoBBaseDscDoorScaleMult3, kEoBBaseDscDoorScaleMult3Provider },
+ { kEoBBaseDscDoorScaleMult4, kEoBBaseDscDoorScaleMult4Provider },
+ { kEoBBaseDscDoorScaleMult5, kEoBBaseDscDoorScaleMult5Provider },
+ { kEoBBaseDscDoorScaleMult6, kEoBBaseDscDoorScaleMult6Provider },
+ { kEoBBaseDscDoorType5Offs, kEoBBaseDscDoorType5OffsProvider },
+ { kEoBBaseDscDoorXE, kEoBBaseDscDoorXEProvider },
+ { kEoBBaseDscDoorY1, kEoBBaseDscDoorY1Provider },
+ { kEoBBaseDscDoorY3, kEoBBaseDscDoorY3Provider },
+ { kEoBBaseDscDoorY4, kEoBBaseDscDoorY4Provider },
+ { kEoBBaseDscDoorY5, kEoBBaseDscDoorY5Provider },
+ { kEoBBaseDscDoorY6, kEoBBaseDscDoorY6Provider },
+ { kEoBBaseDscDoorY7, kEoBBaseDscDoorY7Provider },
+ { kEoBBaseDscDoorCoordsExt, kEoBBaseDscDoorCoordsExtProvider },
+ { kEoBBaseDscItemPosIndex, kEoBBaseDscItemPosIndexProvider },
+ { kEoBBaseDscItemShpX, kEoBBaseDscItemShpXProvider },
+ { kEoBBaseDscItemPosUnk, kEoBBaseDscItemPosUnkProvider },
+ { kEoBBaseDscItemTileIndex, kEoBBaseDscItemTileIndexProvider },
+ { kEoBBaseDscItemShapeMap, kEoBBaseDscItemShapeMapProvider },
+ { kEoBBaseDscTelptrShpCoords, kEoBBaseDscTelptrShpCoordsProvider },
+
+ { kEoBBasePortalSeqData, kEoBBasePortalSeqDataProvider },
+ { kEoBBaseManDef, kEoBBaseManDefProvider },
+ { kEoBBaseManWord, kEoBBaseManWordProvider },
+ { kEoBBaseManPrompt, kEoBBaseManPromptProvider },
+
+ { kEoBBaseDscMonsterFrmOffsTbl1, kEoBBaseDscMonsterFrmOffsTbl1Provider },
+ { kEoBBaseDscMonsterFrmOffsTbl2, kEoBBaseDscMonsterFrmOffsTbl2Provider },
+
+ { kEoBBaseInvSlotX, kEoBBaseInvSlotXProvider },
+ { kEoBBaseInvSlotY, kEoBBaseInvSlotYProvider },
+ { kEoBBaseSlotValidationFlags, kEoBBaseSlotValidationFlagsProvider },
+
+ { kEoBBaseProjectileWeaponTypes, kEoBBaseProjectileWeaponTypesProvider },
+ { kEoBBaseWandTypes, kEoBBaseWandTypesProvider },
+
+ { kEoBBaseDrawObjPosIndex, kEoBBaseDrawObjPosIndexProvider },
+ { kEoBBaseFlightObjFlipIndex, kEoBBaseFlightObjFlipIndexProvider },
+ { kEoBBaseFlightObjShpMap, kEoBBaseFlightObjShpMapProvider },
+ { kEoBBaseFlightObjSclIndex, kEoBBaseFlightObjSclIndexProvider },
+
+ { kEoBBaseBookNumbers, kEoBBaseBookNumbersProvider },
+ { kEoBBaseMageSpellsList, kEoBBaseMageSpellsListProvider },
+ { kEoBBaseClericSpellsList, kEoBBaseClericSpellsListProvider },
+ { kEoBBaseSpellNames, kEoBBaseSpellNamesProvider },
+ { kEoBBaseMagicStrings1, kEoBBaseMagicStrings1Provider },
+ { kEoBBaseMagicStrings2, kEoBBaseMagicStrings2Provider },
+ { kEoBBaseMagicStrings3, kEoBBaseMagicStrings3Provider },
+ { kEoBBaseMagicStrings4, kEoBBaseMagicStrings4Provider },
+ { kEoBBaseMagicStrings6, kEoBBaseMagicStrings6Provider },
+ { kEoBBaseMagicStrings7, kEoBBaseMagicStrings7Provider },
+ { kEoBBaseMagicStrings8, kEoBBaseMagicStrings8Provider },
+
+ { kEoBBaseExpObjectTlMode, kEoBBaseExpObjectTlModeProvider },
+ { kEoBBaseExpObjectTblIndex, kEoBBaseExpObjectTblIndexProvider },
+ { kEoBBaseExpObjectShpStart, kEoBBaseExpObjectShpStartProvider },
+ { kEoBBaseExpObjectTbl1, kEoBBaseExpObjectTbl1Provider },
+ { kEoBBaseExpObjectTbl2, kEoBBaseExpObjectTbl2Provider },
+ { kEoBBaseExpObjectTbl3, kEoBBaseExpObjectTbl3Provider },
+ { kEoBBaseExpObjectY, kEoBBaseExpObjectYProvider },
+
+ { kEoBBaseSparkDefSteps, kEoBBaseSparkDefStepsProvider },
+ { kEoBBaseSparkDefSubSteps, kEoBBaseSparkDefSubStepsProvider },
+ { kEoBBaseSparkDefShift, kEoBBaseSparkDefShiftProvider },
+ { kEoBBaseSparkDefAdd, kEoBBaseSparkDefAddProvider },
+ { kEoBBaseSparkDefX, kEoBBaseSparkDefXProvider },
+ { kEoBBaseSparkDefY, kEoBBaseSparkDefYProvider },
+ { kEoBBaseSparkOfFlags1, kEoBBaseSparkOfFlags1Provider },
+ { kEoBBaseSparkOfFlags2, kEoBBaseSparkOfFlags2Provider },
+ { kEoBBaseSparkOfShift, kEoBBaseSparkOfShiftProvider },
+ { kEoBBaseSparkOfX, kEoBBaseSparkOfXProvider },
+ { kEoBBaseSparkOfY, kEoBBaseSparkOfYProvider },
+
+ { kEoBBaseSpellProperties, kEoBBaseSpellPropertiesProvider },
+ { kEoBBaseMagicFlightProps, kEoBBaseMagicFlightPropsProvider },
+ { kEoBBaseTurnUndeadEffect, kEoBBaseTurnUndeadEffectProvider },
+ { kEoBBaseBurningHandsDest, kEoBBaseBurningHandsDestProvider },
+ { kEoBBaseConeOfColdDest1, kEoBBaseConeOfColdDest1Provider },
+ { kEoBBaseConeOfColdDest2, kEoBBaseConeOfColdDest2Provider },
+ { kEoBBaseConeOfColdDest3, kEoBBaseConeOfColdDest3Provider },
+ { kEoBBaseConeOfColdDest4, kEoBBaseConeOfColdDest4Provider },
+ { kEoBBaseConeOfColdGfxTbl, kEoBBaseConeOfColdGfxTblProvider },
+
+ { kEoB1MainMenuStrings, kEoB1MainMenuStringsProvider },
+ { kEoB1BonusStrings, kEoB1BonusStringsProvider },
+
+ { kEoB1IntroFilesOpening, kEoB1IntroFilesOpeningProvider },
+ { kEoB1IntroFilesTower, kEoB1IntroFilesTowerProvider },
+ { kEoB1IntroFilesOrb, kEoB1IntroFilesOrbProvider },
+ { kEoB1IntroFilesWdEntry, kEoB1IntroFilesWdEntryProvider },
+ { kEoB1IntroFilesKing, kEoB1IntroFilesKingProvider },
+ { kEoB1IntroFilesHands, kEoB1IntroFilesHandsProvider },
+ { kEoB1IntroFilesWdExit, kEoB1IntroFilesWdExitProvider },
+ { kEoB1IntroFilesTunnel, kEoB1IntroFilesTunnelProvider },
+ { kEoB1IntroOpeningFrmDelay, kEoB1IntroOpeningFrmDelayProvider },
+ { kEoB1IntroWdEncodeX, kEoB1IntroWdEncodeXProvider },
+ { kEoB1IntroWdEncodeY, kEoB1IntroWdEncodeYProvider },
+ { kEoB1IntroWdEncodeWH, kEoB1IntroWdEncodeWHProvider },
+ { kEoB1IntroWdDsX, kEoB1IntroWdDsXProvider },
+ { kEoB1IntroWdDsY, kEoB1IntroWdDsYProvider },
+ { kEoB1IntroTvlX1, kEoB1IntroTvlX1Provider },
+ { kEoB1IntroTvlY1, kEoB1IntroTvlY1Provider },
+ { kEoB1IntroTvlX2, kEoB1IntroTvlX2Provider },
+ { kEoB1IntroTvlY2, kEoB1IntroTvlY2Provider },
+ { kEoB1IntroTvlW, kEoB1IntroTvlWProvider },
+ { kEoB1IntroTvlH, kEoB1IntroTvlHProvider },
+
+ { kEoB1DoorShapeDefs, kEoB1DoorShapeDefsProvider },
+ { kEoB1DoorSwitchShapeDefs, kEoB1DoorSwitchShapeDefsProvider },
+ { kEoB1DoorSwitchCoords, kEoB1DoorSwitchCoordsProvider },
+ { kEoB1MonsterProperties, kEoB1MonsterPropertiesProvider },
+
+ { kEoB1EnemyMageSpellList, kEoB1EnemyMageSpellListProvider },
+ { kEoB1EnemyMageSfx, kEoB1EnemyMageSfxProvider },
+ { kEoB1BeholderSpellList, kEoB1BeholderSpellListProvider },
+ { kEoB1BeholderSfx, kEoB1BeholderSfxProvider },
+ { kEoB1TurnUndeadString, kEoB1TurnUndeadStringProvider },
+
+ { kEoB1CgaMappingDefault, kEoB1CgaMappingDefaultProvider },
+ { kEoB1CgaMappingAlt, kEoB1CgaMappingAltProvider },
+ { kEoB1CgaMappingInv, kEoB1CgaMappingInvProvider },
+ { kEoB1CgaMappingItemsL, kEoB1CgaMappingItemsLProvider },
+ { kEoB1CgaMappingItemsS, kEoB1CgaMappingItemsSProvider },
+ { kEoB1CgaMappingThrown, kEoB1CgaMappingThrownProvider },
+ { kEoB1CgaMappingIcons, kEoB1CgaMappingIconsProvider },
+ { kEoB1CgaMappingDeco, kEoB1CgaMappingDecoProvider },
+ { kEoB1CgaLevelMappingIndex, kEoB1CgaLevelMappingIndexProvider },
+ { kEoB1CgaMappingLevel0, kEoB1CgaMappingLevel0Provider },
+ { kEoB1CgaMappingLevel1, kEoB1CgaMappingLevel1Provider },
+ { kEoB1CgaMappingLevel2, kEoB1CgaMappingLevel2Provider },
+ { kEoB1CgaMappingLevel3, kEoB1CgaMappingLevel3Provider },
+ { kEoB1CgaMappingLevel4, kEoB1CgaMappingLevel4Provider },
+
+ { kEoB1NpcShpData, kEoB1NpcShpDataProvider },
+ { kEoB1NpcSubShpIndex1, kEoB1NpcSubShpIndex1Provider },
+ { kEoB1NpcSubShpIndex2, kEoB1NpcSubShpIndex2Provider },
+ { kEoB1NpcSubShpY, kEoB1NpcSubShpYProvider },
+ { kEoB1Npc0Strings, kEoB1Npc0StringsProvider },
+ { kEoB1Npc11Strings, kEoB1Npc11StringsProvider },
+ { kEoB1Npc12Strings, kEoB1Npc12StringsProvider },
+ { kEoB1Npc21Strings, kEoB1Npc21StringsProvider },
+ { kEoB1Npc22Strings, kEoB1Npc22StringsProvider },
+ { kEoB1Npc31Strings, kEoB1Npc31StringsProvider },
+ { kEoB1Npc32Strings, kEoB1Npc32StringsProvider },
+ { kEoB1Npc4Strings, kEoB1Npc4StringsProvider },
+ { kEoB1Npc5Strings, kEoB1Npc5StringsProvider },
+ { kEoB1Npc6Strings, kEoB1Npc6StringsProvider },
+ { kEoB1Npc7Strings, kEoB1Npc7StringsProvider },
+
+ { kEoB2MainMenuStrings, kEoB2MainMenuStringsProvider },
+
+ { kEoB2TransferPortraitFrames, kEoB2TransferPortraitFramesProvider },
+ { kEoB2TransferConvertTable, kEoB2TransferConvertTableProvider },
+ { kEoB2TransferItemTable, kEoB2TransferItemTableProvider },
+ { kEoB2TransferExpTable, kEoB2TransferExpTableProvider },
+ { kEoB2TransferStrings1, kEoB2TransferStrings1Provider },
+ { kEoB2TransferStrings2, kEoB2TransferStrings2Provider },
+ { kEoB2TransferLabels, kEoB2TransferLabelsProvider },
+
+ { kEoB2IntroStrings, kEoB2IntroStringsProvider },
+ { kEoB2IntroCPSFiles, kEoB2IntroCPSFilesProvider },
+ { kEob2IntroAnimData00, kEob2IntroAnimData00Provider },
+ { kEob2IntroAnimData01, kEob2IntroAnimData01Provider },
+ { kEob2IntroAnimData02, kEob2IntroAnimData02Provider },
+ { kEob2IntroAnimData03, kEob2IntroAnimData03Provider },
+ { kEob2IntroAnimData04, kEob2IntroAnimData04Provider },
+ { kEob2IntroAnimData05, kEob2IntroAnimData05Provider },
+ { kEob2IntroAnimData06, kEob2IntroAnimData06Provider },
+ { kEob2IntroAnimData07, kEob2IntroAnimData07Provider },
+ { kEob2IntroAnimData08, kEob2IntroAnimData08Provider },
+ { kEob2IntroAnimData09, kEob2IntroAnimData09Provider },
+ { kEob2IntroAnimData10, kEob2IntroAnimData10Provider },
+ { kEob2IntroAnimData11, kEob2IntroAnimData11Provider },
+ { kEob2IntroAnimData12, kEob2IntroAnimData12Provider },
+ { kEob2IntroAnimData13, kEob2IntroAnimData13Provider },
+ { kEob2IntroAnimData14, kEob2IntroAnimData14Provider },
+ { kEob2IntroAnimData15, kEob2IntroAnimData15Provider },
+ { kEob2IntroAnimData16, kEob2IntroAnimData16Provider },
+ { kEob2IntroAnimData17, kEob2IntroAnimData17Provider },
+ { kEob2IntroAnimData18, kEob2IntroAnimData18Provider },
+ { kEob2IntroAnimData19, kEob2IntroAnimData19Provider },
+ { kEob2IntroAnimData20, kEob2IntroAnimData20Provider },
+ { kEob2IntroAnimData21, kEob2IntroAnimData21Provider },
+ { kEob2IntroAnimData22, kEob2IntroAnimData22Provider },
+ { kEob2IntroAnimData23, kEob2IntroAnimData23Provider },
+ { kEob2IntroAnimData24, kEob2IntroAnimData24Provider },
+ { kEob2IntroAnimData25, kEob2IntroAnimData25Provider },
+ { kEob2IntroAnimData26, kEob2IntroAnimData26Provider },
+ { kEob2IntroAnimData27, kEob2IntroAnimData27Provider },
+ { kEob2IntroAnimData28, kEob2IntroAnimData28Provider },
+ { kEob2IntroAnimData29, kEob2IntroAnimData29Provider },
+ { kEob2IntroAnimData30, kEob2IntroAnimData30Provider },
+ { kEob2IntroAnimData31, kEob2IntroAnimData31Provider },
+ { kEob2IntroAnimData32, kEob2IntroAnimData32Provider },
+ { kEob2IntroAnimData33, kEob2IntroAnimData33Provider },
+ { kEob2IntroAnimData34, kEob2IntroAnimData34Provider },
+ { kEob2IntroAnimData35, kEob2IntroAnimData35Provider },
+ { kEob2IntroAnimData36, kEob2IntroAnimData36Provider },
+ { kEob2IntroAnimData37, kEob2IntroAnimData37Provider },
+ { kEob2IntroAnimData38, kEob2IntroAnimData38Provider },
+ { kEob2IntroAnimData39, kEob2IntroAnimData39Provider },
+ { kEob2IntroAnimData40, kEob2IntroAnimData40Provider },
+ { kEob2IntroAnimData41, kEob2IntroAnimData41Provider },
+ { kEob2IntroAnimData42, kEob2IntroAnimData42Provider },
+ { kEob2IntroAnimData43, kEob2IntroAnimData43Provider },
+ { kEoB2IntroShapes00, kEoB2IntroShapes00Provider },
+ { kEoB2IntroShapes01, kEoB2IntroShapes01Provider },
+ { kEoB2IntroShapes04, kEoB2IntroShapes04Provider },
+ { kEoB2IntroShapes07, kEoB2IntroShapes07Provider },
+
+ { kEoB2FinaleStrings, kEoB2FinaleStringsProvider },
+ { kEoB2CreditsData, kEoB2CreditsDataProvider },
+ { kEoB2FinaleCPSFiles, kEoB2FinaleCPSFilesProvider },
+ { kEob2FinaleAnimData00, kEob2FinaleAnimData00Provider },
+ { kEob2FinaleAnimData01, kEob2FinaleAnimData01Provider },
+ { kEob2FinaleAnimData02, kEob2FinaleAnimData02Provider },
+ { kEob2FinaleAnimData03, kEob2FinaleAnimData03Provider },
+ { kEob2FinaleAnimData04, kEob2FinaleAnimData04Provider },
+ { kEob2FinaleAnimData05, kEob2FinaleAnimData05Provider },
+ { kEob2FinaleAnimData06, kEob2FinaleAnimData06Provider },
+ { kEob2FinaleAnimData07, kEob2FinaleAnimData07Provider },
+ { kEob2FinaleAnimData08, kEob2FinaleAnimData08Provider },
+ { kEob2FinaleAnimData09, kEob2FinaleAnimData09Provider },
+ { kEob2FinaleAnimData10, kEob2FinaleAnimData10Provider },
+ { kEob2FinaleAnimData11, kEob2FinaleAnimData11Provider },
+ { kEob2FinaleAnimData12, kEob2FinaleAnimData12Provider },
+ { kEob2FinaleAnimData13, kEob2FinaleAnimData13Provider },
+ { kEob2FinaleAnimData14, kEob2FinaleAnimData14Provider },
+ { kEob2FinaleAnimData15, kEob2FinaleAnimData15Provider },
+ { kEob2FinaleAnimData16, kEob2FinaleAnimData16Provider },
+ { kEob2FinaleAnimData17, kEob2FinaleAnimData17Provider },
+ { kEob2FinaleAnimData18, kEob2FinaleAnimData18Provider },
+ { kEob2FinaleAnimData19, kEob2FinaleAnimData19Provider },
+ { kEob2FinaleAnimData20, kEob2FinaleAnimData20Provider },
+ { kEoB2FinaleShapes00, kEoB2FinaleShapes00Provider },
+ { kEoB2FinaleShapes03, kEoB2FinaleShapes03Provider },
+ { kEoB2FinaleShapes07, kEoB2FinaleShapes07Provider },
+ { kEoB2FinaleShapes09, kEoB2FinaleShapes09Provider },
+ { kEoB2FinaleShapes10, kEoB2FinaleShapes10Provider },
+
+ { kEoB2NpcShapeData, kEoB2NpcShapeDataProvider },
+ { kEoBBaseClassModifierFlags, kEoBBaseClassModifierFlagsProvider },
+
+ { kEoBBaseMonsterStepTable01, kEoBBaseMonsterStepTable01Provider },
+ { kEoBBaseMonsterStepTable02, kEoBBaseMonsterStepTable02Provider },
+ { kEoBBaseMonsterStepTable1, kEoBBaseMonsterStepTable1Provider },
+ { kEoBBaseMonsterStepTable2, kEoBBaseMonsterStepTable2Provider },
+ { kEoBBaseMonsterStepTable3, kEoBBaseMonsterStepTable3Provider },
+ { kEoBBaseMonsterCloseAttPosTable1, kEoBBaseMonsterCloseAttPosTable1Provider },
+ { kEoBBaseMonsterCloseAttPosTable21, kEoBBaseMonsterCloseAttPosTable21Provider },
+ { kEoBBaseMonsterCloseAttPosTable22, kEoBBaseMonsterCloseAttPosTable22Provider },
+ { kEoBBaseMonsterCloseAttUnkTable, kEoBBaseMonsterCloseAttUnkTableProvider },
+ { kEoBBaseMonsterCloseAttChkTable1, kEoBBaseMonsterCloseAttChkTable1Provider },
+ { kEoBBaseMonsterCloseAttChkTable2, kEoBBaseMonsterCloseAttChkTable2Provider },
+ { kEoBBaseMonsterCloseAttDstTable1, kEoBBaseMonsterCloseAttDstTable1Provider },
+ { kEoBBaseMonsterCloseAttDstTable2, kEoBBaseMonsterCloseAttDstTable2Provider },
+
+ { kEoBBaseMonsterProximityTable, kEoBBaseMonsterProximityTableProvider },
+ { kEoBBaseFindBlockMonstersTable, kEoBBaseFindBlockMonstersTableProvider },
+ { kEoBBaseMonsterDirChangeTable, kEoBBaseMonsterDirChangeTableProvider },
+ { kEoBBaseMonsterDistAttStrings, kEoBBaseMonsterDistAttStringsProvider },
+ { kEoBBaseEncodeMonsterDefs, kEoBBaseEncodeMonsterDefsProvider },
+ { kEoBBaseNpcPresets, kEoBBaseNpcPresetsProvider },
+ { kEoB2Npc1Strings, kEoB2Npc1StringsProvider },
+ { kEoB2Npc2Strings, kEoB2Npc2StringsProvider },
+ { kEoB2MonsterDustStrings, kEoB2MonsterDustStringsProvider },
+ { kEoB2DreamSteps, kEoB2DreamStepsProvider },
+ { kEoB2KheldranStrings, kEoB2KheldranStringsProvider },
+ { kEoB2HornStrings, kEoB2HornStringsProvider },
+ { kEoB2HornSounds, kEoB2HornSoundsProvider },
+ { kEoB2WallOfForceDsX, kEoB2WallOfForceDsXProvider },
+ { kEoB2WallOfForceDsY, kEoB2WallOfForceDsYProvider },
+ { kEoB2WallOfForceNumW, kEoB2WallOfForceNumWProvider },
+ { kEoB2WallOfForceNumH, kEoB2WallOfForceNumHProvider },
+ { kEoB2WallOfForceShpId, kEoB2WallOfForceShpIdProvider },
+
+ { kLoLIngamePakFiles, kLoLIngamePakFilesProvider },
+ { kLoLCharacterDefs, kLoLCharacterDefsProvider },
+ { kLoLIngameSfxFiles, kLoLIngameSfxFilesProvider },
+ { kLoLIngameSfxIndex, kLoLIngameSfxIndexProvider },
+ { kLoLMusicTrackMap, kLoLMusicTrackMapProvider },
+ { kLoLIngameGMSfxIndex, kLoLIngameGMSfxIndexProvider },
+ { kLoLIngameMT32SfxIndex, kLoLIngameMT32SfxIndexProvider },
+ { kLoLIngamePcSpkSfxIndex, kLoLIngamePcSpkSfxIndexProvider },
+ { kLoLSpellProperties, kLoLSpellPropertiesProvider },
+ { kLoLGameShapeMap, kLoLGameShapeMapProvider },
+ { kLoLSceneItemOffs, kLoLSceneItemOffsProvider },
+ { kLoLCharInvIndex, kLoLCharInvIndexProvider },
+ { kLoLCharInvDefs, kLoLCharInvDefsProvider },
+ { kLoLCharDefsMan, kLoLCharDefsManProvider },
+ { kLoLCharDefsWoman, kLoLCharDefsWomanProvider },
+ { kLoLCharDefsKieran, kLoLCharDefsKieranProvider },
+ { kLoLCharDefsAkshel, kLoLCharDefsAkshelProvider },
+ { kLoLExpRequirements, kLoLExpRequirementsProvider },
+ { kLoLMonsterModifiers, kLoLMonsterModifiersProvider },
+ { kLoLMonsterShiftOffsets, kLoLMonsterShiftOffsetsProvider },
+ { kLoLMonsterDirFlags, kLoLMonsterDirFlagsProvider },
+ { kLoLMonsterScaleY, kLoLMonsterScaleYProvider },
+ { kLoLMonsterScaleX, kLoLMonsterScaleXProvider },
+ { kLoLMonsterScaleWH, kLoLMonsterScaleWHProvider },
+ { kLoLFlyingObjectShp, kLoLFlyingObjectShpProvider },
+ { kLoLInventoryDesc, kLoLInventoryDescProvider },
+ { kLoLLevelShpList, kLoLLevelShpListProvider },
+ { kLoLLevelDatList, kLoLLevelDatListProvider },
+ { kLoLCompassDefs, kLoLCompassDefsProvider },
+ { kLoLItemPrices, kLoLItemPricesProvider },
+ { kLoLStashSetup, kLoLStashSetupProvider },
+ { kLoLDscWalls, kLoLDscWallsProvider },
+ { kRpgCommonDscShapeIndex, kRpgCommonDscShapeIndexProvider },
+ { kLoLDscOvlMap, kLoLDscOvlMapProvider },
+ { kLoLDscScaleWidthData, kLoLDscScaleWidthDataProvider },
+ { kLoLDscScaleHeightData, kLoLDscScaleHeightDataProvider },
+ { kRpgCommonDscX, kRpgCommonDscXProvider },
+ { kLoLDscY, kLoLDscYProvider },
+ { kRpgCommonDscTileIndex, kRpgCommonDscTileIndexProvider },
+ { kRpgCommonDscUnk2, kRpgCommonDscUnk2Provider },
+ { kRpgCommonDscDoorShapeIndex, kRpgCommonDscDoorShapeIndexProvider },
+ { kRpgCommonDscDimData1, kRpgCommonDscDimData1Provider },
+ { kRpgCommonDscDimData2, kRpgCommonDscDimData2Provider },
+ { kRpgCommonDscBlockMap, kRpgCommonDscBlockMapProvider },
+ { kRpgCommonDscDimMap, kRpgCommonDscDimMapProvider },
+ { kLoLDscOvlIndex, kLoLDscOvlIndexProvider },
+ { kRpgCommonDscBlockIndex, kRpgCommonDscBlockIndexProvider },
+ { kRpgCommonDscDoorY2, kRpgCommonDscDoorY2Provider },
+ { kRpgCommonDscDoorFrameY1, kRpgCommonDscDoorFrameY1Provider },
+ { kRpgCommonDscDoorFrameY2, kRpgCommonDscDoorFrameY2Provider },
+ { kRpgCommonDscDoorFrameIndex1, kRpgCommonDscDoorFrameIndex1Provider },
+ { kRpgCommonDscDoorFrameIndex2, kRpgCommonDscDoorFrameIndex2Provider },
+ { kLoLDscDoorScale, kLoLDscDoorScaleProvider },
+ { kLoLDscDoor4, kLoLDscDoor4Provider },
+ { kLoLDscDoorX, kLoLDscDoorXProvider },
+ { kLoLDscDoorY, kLoLDscDoorYProvider },
+ { kLoLScrollXTop, kLoLScrollXTopProvider },
+ { kLoLScrollYTop, kLoLScrollYTopProvider },
+ { kLoLScrollXBottom, kLoLScrollXBottomProvider },
+ { kLoLScrollYBottom, kLoLScrollYBottomProvider },
+ { kLoLButtonDefs, kLoLButtonDefsProvider },
+ { kLoLButtonList1, kLoLButtonList1Provider },
+ { kLoLButtonList2, kLoLButtonList2Provider },
+ { kLoLButtonList3, kLoLButtonList3Provider },
+ { kLoLButtonList4, kLoLButtonList4Provider },
+ { kLoLButtonList5, kLoLButtonList5Provider },
+ { kLoLButtonList6, kLoLButtonList6Provider },
+ { kLoLButtonList7, kLoLButtonList7Provider },
+ { kLoLButtonList8, kLoLButtonList8Provider },
+ { kLoLLegendData, kLoLLegendDataProvider },
+ { kLoLMapCursorOvl, kLoLMapCursorOvlProvider },
+ { kLoLMapStringId, kLoLMapStringIdProvider },
+ { kLoLSpellbookAnim, kLoLSpellbookAnimProvider },
+ { kLoLSpellbookCoords, kLoLSpellbookCoordsProvider },
+ { kLoLHealShapeFrames, kLoLHealShapeFramesProvider },
+ { kLoLLightningDefs, kLoLLightningDefsProvider },
+ { kLoLFireballCoords, kLoLFireballCoordsProvider },
+ { kLoLCredits, kLoLCreditsProvider },
+ { kLoLHistory, kLoLHistoryProvider },
{ -1, NULL }
};
diff --git a/devtools/create_kyradat/util.cpp b/devtools/create_kyradat/util.cpp
index 2420f44168..5ce8237b85 100644
--- a/devtools/create_kyradat/util.cpp
+++ b/devtools/create_kyradat/util.cpp
@@ -54,6 +54,19 @@ void warning(const char *s, ...) {
fprintf(stderr, "WARNING: %s!\n", buf);
}
+int scumm_stricmp(const char *s1, const char *s2) {
+ byte l1, l2;
+ do {
+ // Don't use ++ inside tolower, in case the macro uses its
+ // arguments more than once.
+ l1 = (byte)*s1++;
+ l1 = tolower(l1);
+ l2 = (byte)*s2++;
+ l2 = tolower(l2);
+ } while (l1 == l2 && l1 != 0);
+ return l1 - l2;
+}
+
void debug(int level, const char *s, ...) {
char buf[1024];
va_list va;
diff --git a/devtools/create_kyradat/util.h b/devtools/create_kyradat/util.h
index 0d8e15cc37..a2783cca71 100644
--- a/devtools/create_kyradat/util.h
+++ b/devtools/create_kyradat/util.h
@@ -50,6 +50,7 @@ uint32 fileSize(FILE *fp);
void NORETURN_PRE error(const char *s, ...) NORETURN_POST;
void warning(const char *s, ...);
void debug(int level, const char *s, ...);
+int scumm_stricmp(const char *s1, const char *s2);
using namespace Common;
diff --git a/devtools/create_lure/process_actions.cpp b/devtools/create_lure/process_actions.cpp
index 8539391d57..db965730cb 100644
--- a/devtools/create_lure/process_actions.cpp
+++ b/devtools/create_lure/process_actions.cpp
@@ -255,7 +255,7 @@ uint16 process_action_sequence_entry(int supportIndex, byte *data, uint16 remain
// Replace code offset with an index
params[0] = index;
else {
- printf("\nEncountered unrecognised NPC code jump point: %xh\n", params[0]);
+ printf("\nEncountered unrecognized NPC code jump point: %xh\n", params[0]);
exit(1);
}
break;
diff --git a/devtools/create_mads/main.cpp b/devtools/create_mads/main.cpp
deleted file mode 100644
index b4de34d832..0000000000
--- a/devtools/create_mads/main.cpp
+++ /dev/null
@@ -1,127 +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.
- *
- */
-
-// HACK to allow building with the SDL backend on MinGW
-// see bug #1800764 "TOOLS: MinGW tools building broken"
-#ifdef main
-#undef main
-#endif // main
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include "parser.h"
-
-#define BUFFER_SIZE 8192
-
-void link(const char *destFilename, char **srcFilenames, int srcCount) {
- if (srcCount <= 0)
- return;
-
- FILE *destFile = fopen(destFilename, "wb");
- if (!destFile)
- return;
- unsigned int v = 0;
- const char *headerStr = "MADS";
- int fileOffset = 4 * (srcCount + 2);
-
- // Write header bit
- fwrite(headerStr, 1, 4, destFile);
- for (int i = 0; i <= srcCount; ++i)
- fwrite(&v, 1, 4, destFile);
-
- // Set up buffer for copying
- void *tempBuffer = malloc(BUFFER_SIZE);
-
- // Loop through copying each source file and setting it's file offset in the header
- for (int i = 0; i < srcCount; ++i) {
- // Add any extra padding to ensure that each file starts on a paragraph boundary
- if ((fileOffset % 16) != 0) {
- v = 0;
- while ((fileOffset % 16) != 0) {
- fwrite(&v, 1, 1, destFile);
- ++fileOffset;
- }
- }
-
- FILE *srcFile = fopen(srcFilenames[i], "rb");
- if (!srcFile) {
- printf("Could not locate file '%s'\n", srcFilenames[i]);
- break;
- }
-
- // Set the starting position of the file
- fseek(destFile, 4 + (i * 4), SEEK_SET);
- fwrite(&fileOffset, 1, 4, destFile);
-
- // Move back to the end of the destination and copy the source file contents over
- fseek(destFile, 0, SEEK_END);
- while (!feof(srcFile)) {
- int bytesRead = fread(tempBuffer, 1, BUFFER_SIZE, srcFile);
- fwrite(tempBuffer, 1, bytesRead, destFile);
- fileOffset += bytesRead;
- }
-
- fclose(srcFile);
- }
-
- fclose(destFile);
- free(tempBuffer);
- printf("Done.\n");
-}
-
-int main(int argc, char *argv[]) {
- if (argc == 1) {
- printf("%s - ScummVM MADS Game script compiler v 1.0\n\n", argv[0]);
- printf("Parameters: %s src_filename.txt [dest_filename.bin] - Compiles a script text file to an output binary\t", argv[0]);
- printf("\t%s /link mads.dat filename1.bin [filename2.bin ..] - Joins one or more compiled Bin files to make\n", argv[0]);
- printf("an output suitable for running in ScummVM.\n\n");
- } else if (!strcmp(argv[1], "/link")) {
- // Link intermediate files into a final mads.dat file
- if (argc < 4)
- printf("Insufficient parameters\n");
- else
- link(argv[2], &argv[3], argc - 3);
-
- } else {
- // Compile a file
- char buffer[256];
- const char *destFilename = buffer;
- if (argc >= 3)
- destFilename = argv[2];
- else {
- // Use the source filename, but change the extension to '.bin'
- strcpy(buffer, argv[1]);
- char *p = buffer + strlen(buffer) - 1;
- while ((p >= buffer) && (*p != '.')) --p;
- if (p > buffer)
- // Change the extension
- strcpy(p, ".bin");
- }
-
- // Compile the specified source file
- bool result = Compile(argv[1], destFilename);
- return result ? 0 : 1;
- }
-
- return 0;
-}
diff --git a/devtools/create_mads/module.mk b/devtools/create_mads/module.mk
deleted file mode 100644
index 20d8deb8af..0000000000
--- a/devtools/create_mads/module.mk
+++ /dev/null
@@ -1,12 +0,0 @@
-
-MODULE := devtools/create_mads
-
-MODULE_OBJS := \
- main.o \
- parser.o
-
-# Set the name of the executable
-TOOL_EXECUTABLE := create_mads
-
-# Include common rules
-include $(srcdir)/rules.mk
diff --git a/devtools/create_mads/parser.cpp b/devtools/create_mads/parser.cpp
deleted file mode 100644
index 5df505e0df..0000000000
--- a/devtools/create_mads/parser.cpp
+++ /dev/null
@@ -1,937 +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 <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-
-#define MAX_SOURCE_LINE_LENGTH 256
-#define MAX_TOKEN_STRING_LENGTH MAX_SOURCE_LINE_LENGTH
-#define MAX_DIGIT_COUNT 20
-#define MAX_SYMBOLS 1024
-#define MAX_SUBROUTINES 1024
-#define MAX_SUBROUTINE_SIZE 4096
-#define MAX_SUBROUTINE_JUMPS 256
-
-#define OPSIZE8 0x40 ///< when this bit is set - the operand size is 8 bits
-#define OPSIZE16 0x80 ///< when this bit is set - the operand size is 16 bits
-#define OPSIZE32 0x00 ///< when no bits are set - the operand size is 32 bits
-
-#define VERSION 1
-
-enum CharCode {
- LETTER, DIGIT, SPECIAL, EOF_CODE, EOL_CODE
-};
-
-enum TokenCode {
- NO_TOKEN, WORD, NUMBER, IDENTIFIER, END_OF_FILE, END_OF_LINE,
- RW_DEFINE, RW_COLON, RW_SUB, RW_END, RW_OPCODE,
- ERROR
-};
-
-enum LiteralType {
- INTEGER_LIT
-};
-
-struct Literal {
- LiteralType type;
- union {
- int integer;
- } value;
-};
-
-struct SymbolEntry {
- char symbol[MAX_TOKEN_STRING_LENGTH];
- char value[MAX_TOKEN_STRING_LENGTH];
-};
-
-struct SubEntry {
- char name[MAX_TOKEN_STRING_LENGTH];
- int fileOffset;
-};
-
-struct JumpSource {
- char name[MAX_TOKEN_STRING_LENGTH];
- int line_number;
- int offset;
-};
-
-struct JumpDest {
- char name[MAX_TOKEN_STRING_LENGTH];
- int offset;
-};
-
-enum Opcodes {
- OP_HALT = 0, OP_IMM = 1, OP_ZERO = 2, OP_ONE = 3, OP_MINUSONE = 4, OP_STR = 5, OP_DLOAD = 6,
- OP_DSTORE = 7, OP_PAL = 8, OP_LOAD = 9, OP_GLOAD = 10, OP_STORE = 11, OP_GSTORE = 12,
- OP_CALL = 13, OP_LIBCALL = 14, OP_RET = 15, OP_ALLOC = 16, OP_JUMP = 17, OP_JMPFALSE = 18,
- OP_JMPTRUE = 19, OP_EQUAL = 20, OP_LESS = 21, OP_LEQUAL = 22, OP_NEQUAL = 23, OP_GEQUAL = 24,
- OP_GREAT = 25, OP_PLUS = 26, OP_MINUS = 27, OP_LOR = 28, OP_MULT = 29, OP_DIV = 30,
- OP_MOD = 31, OP_AND = 32, OP_OR = 33, OP_EOR = 34, OP_LAND = 35, OP_NOT = 36, OP_COMP = 37,
- OP_NEG = 38, OP_DUP = 39,
- TOTAL_OPCODES = 40
-};
-
-typedef unsigned char byte;
-
-const unsigned char EOF_CHAR = (unsigned char)255;
-const unsigned char EOL_CHAR = (unsigned char)254;
-
-/*----------------------------------------------------------------------*/
-/* Reserved words tables */
-/*----------------------------------------------------------------------*/
-
-enum OpcodeParamType {OP_NO_PARAM, OP_IMM_PARAM, OP_TRANSFER_PARAM};
-
-struct OpcodeEntry {
- const char *str;
- OpcodeParamType paramType;
-};
-
-OpcodeEntry OpcodeList[OP_DUP + 1] = {
- {"HALT", OP_NO_PARAM}, {"IMM", OP_IMM_PARAM}, {"ZERO", OP_NO_PARAM}, {"ONE", OP_NO_PARAM},
- {"MINUSONE", OP_NO_PARAM}, {"STR", OP_IMM_PARAM}, {"DLOAD", OP_IMM_PARAM}, {"DSTORE", OP_IMM_PARAM},
- {"PAL", OP_IMM_PARAM}, {"LOAD", OP_IMM_PARAM}, {"GLOAD", OP_IMM_PARAM}, {"STORE", OP_IMM_PARAM},
- {"GSTORE", OP_IMM_PARAM}, {"CALL", OP_IMM_PARAM}, {"LIBCALL", OP_IMM_PARAM}, {"RET", OP_NO_PARAM},
- {"ALLOC", OP_IMM_PARAM}, {"JUMP", OP_TRANSFER_PARAM}, {"JMPFALSE", OP_TRANSFER_PARAM},
- {"JMPTRUE", OP_TRANSFER_PARAM}, {"EQUAL", OP_NO_PARAM}, {"LESS", OP_NO_PARAM},
- {"LEQUAL", OP_NO_PARAM}, {"NEQUAL", OP_NO_PARAM}, {"GEQUAL", OP_NO_PARAM},
- {"GREAT", OP_NO_PARAM}, {"PLUS", OP_NO_PARAM}, {"MINUS", OP_NO_PARAM},
- {"LOR", OP_NO_PARAM}, {"MULT", OP_NO_PARAM}, {"DIV", OP_IMM_PARAM}, {"MOD", OP_NO_PARAM},
- {"AND", OP_NO_PARAM}, {"OR", OP_NO_PARAM}, {"EOR", OP_NO_PARAM}, {"LAND", OP_NO_PARAM},
- {"NOT", OP_NO_PARAM}, {"COMP", OP_NO_PARAM}, {"NEG", OP_NO_PARAM}, {"DUP", OP_NO_PARAM}
-};
-
-
-const char *symbol_strings[] = {"#DEFINE", ":", "SUB", "END"};
-
-/*----------------------------------------------------------------------*/
-/* Globals */
-/*----------------------------------------------------------------------*/
-
-unsigned char ch; // Current input character
-TokenCode token; // code of current token
-Opcodes opcode; // Current instruction opcode
-OpcodeParamType paramType; // Parameter type opcode expects
-Literal literal; // Value of literal
-int buffer_offset; // Char offset into source buffer
-int level = 0; // current nesting level
-int line_number = 0; // current line number
-
-char source_buffer[MAX_SOURCE_LINE_LENGTH]; // Source file buffer
-char token_string[MAX_TOKEN_STRING_LENGTH]; // Token string
-const char *bufferp = source_buffer; // Source buffer ptr
-char *tokenp = token_string; // Token string ptr
-
-int digit_count; // Total no. of digits in number
-bool count_error; // Too many digits in number?
-
-FILE *source_file;
-FILE *dest_file;
-CharCode char_table[256];
-
-SymbolEntry symbolTable[MAX_SYMBOLS];
-int symbolCount = 0;
-
-int game_number = 0;
-int language = 0;
-
-int indexSize = 0;
-int fileOffset = 0;
-SubEntry subroutinesTable[MAX_SUBROUTINES];
-int subroutinesCount = 0;
-
-byte subroutineData[MAX_SUBROUTINE_SIZE];
-int subroutineSize = 0;
-
-JumpSource jumpSources[MAX_SUBROUTINE_JUMPS];
-int jumpSourceCount = 0;
-JumpDest jumpDests[MAX_SUBROUTINE_JUMPS];
-int jumpDestCount = 0;
-
-#define char_code(ch) char_table[ch]
-
-void get_char();
-void get_token();
-
-/*----------------------------------------------------------------------*/
-/* Miscellaneous support functions */
-/*----------------------------------------------------------------------*/
-
-void strToUpper(char *string) {
- while (*string) {
- *string = toupper(*string);
- ++string;
- }
-}
-
-void strToLower(char *string) {
- while (*string) {
- *string = tolower(*string);
- ++string;
- }
-}
-
-int strToInt(const char *s) {
- unsigned int tmp;
-
- if (!*s)
- // No string at all
- return 0;
- else if (toupper(s[strlen(s) - 1]) == 'H')
- // Hexadecimal string with trailing 'h'
- sscanf(s, "%xh", &tmp);
- else if (*s == '$')
- // Hexadecimal string starting with '$'
- sscanf(s + 1, "%x", &tmp);
- else
- // Standard decimal string
- return atoi(s);
-
- return (int)tmp;
-}
-
-/*----------------------------------------------------------------------*/
-/* Initialisation / De-initialisation code */
-/*----------------------------------------------------------------------*/
-
-/**
- * Open the input file for parsing
- */
-void open_source_file(const char *name) {
- if ((source_file = fopen(name, "r")) == NULL) {
- printf("*** Error: Failed to open source file.\n");
- exit(0);
- }
-
- // Fetch the first character
- bufferp = "";
- get_char();
-}
-
-/**
- * Close the source file
- */
-void close_source_file() {
- fclose(source_file);
-}
-
-/**
- * Initializes the scanner
- */
-void init_scanner(const char *name) {
- // Initialize character table
- for (int i = 0; i < 256; ++i) char_table[i] = SPECIAL;
- for (int i = '0'; i <= '9'; ++i) char_table[i] = DIGIT;
- for (int i = 'A'; i <= 'Z'; ++i) char_table[i] = LETTER;
- for (int i = 'a'; i <= 'z'; ++i) char_table[i] = LETTER;
- char_table[EOF_CHAR] = EOF_CODE;
- char_table[EOL_CHAR] = EOL_CODE;
- char_table[(int)'$'] = DIGIT; // Needed for hexadecimal number handling
-
- open_source_file(name);
-}
-
-/**
- * Shuts down the scanner
- */
-void quit_scanner() {
- close_source_file();
-}
-
-/*----------------------------------------------------------------------*/
-/* Output routines */
-/*----------------------------------------------------------------------*/
-
-
-/**
- * Initializes the output
- */
-void init_output(const char *destFilename) {
- dest_file = fopen(destFilename, "wb");
- if (dest_file == NULL) {
- printf("Could not open file for writing\n");
- exit(0);
- }
-}
-
-/**
- * Closes the output file
- */
-void close_output() {
- fclose(dest_file);
-}
-
-/**
- * Writes a single byte to the output
- */
-void write_byte(byte v) {
- fwrite(&v, 1, 1, dest_file);
- ++fileOffset;
-}
-
-/**
- * Writes a word to the output
- */
-void write_word(int v) {
- write_byte(v & 0xff);
- write_byte((v >> 8) & 0xff);
-}
-
-/**
- * Writes a 32-bit value to the output
- */
-void write_long(int v) {
- write_byte(v & 0xff);
- write_byte((v >> 8) & 0xff);
- write_byte((v >> 16) & 0xff);
- write_byte((v >> 24) & 0xff);
-}
-
-/**
- * Writes a sequence of bytes to the output
- */
-void write_bytes(byte *v, int len) {
- fwrite(v, 1, len, dest_file);
- fileOffset += len;
-}
-
-/**
- * Writes a repeat sequence of a value to the output
- */
-void write_byte_seq(byte v, int len) {
- byte *tempData = (byte *)malloc(len);
- memset(tempData, v, len);
- write_bytes(tempData, len);
- free(tempData);
-}
-
-/**
- * Writes out the header and allocates space for the symbol table
- */
-void write_header() {
- // Write out three bytes - game Id, language Id, and version number
- if (game_number == 0) {
- game_number = 1;
- printf("No game specified, defaulting to Rex Nebular\n");
- }
- write_byte(game_number);
-
- if (language == 0) {
- language = 1;
- printf("No language specified, defaulting to English\n");
- }
- write_byte(language);
-
- write_byte(VERSION);
-
- // Write out space to later come back and store the list of subroutine names and offsets
- if (indexSize == 0) {
- indexSize = 4096;
- printf("No index size specified, defaulting to %d bytes\n", indexSize);
- }
- write_byte_seq(0, indexSize - 3);
-
- fileOffset = indexSize;
-}
-
-/**
- * Goes back and writes out the subroutine list
- */
-void write_index() {
- fseek(dest_file, 3, SEEK_SET);
-
- int bytesRemaining = indexSize - 3;
- for (int i = 0; i < subroutinesCount; ++i) {
- int entrySize = strlen(subroutinesTable[i].name) + 5;
-
- // Ensure there is enough remaining space
- if ((bytesRemaining - entrySize) < 0) {
- printf("Index has exceeded allowable size.\n");
- token = ERROR;
- }
-
- // Write out the name and the file offset
- write_bytes((byte *)&subroutinesTable[i].name, strlen(subroutinesTable[i].name) + 1);
- write_long(subroutinesTable[i].fileOffset);
- }
-}
-
-/*----------------------------------------------------------------------*/
-/* Processing routines */
-/*----------------------------------------------------------------------*/
-
-int symbolFind() {
- for (int i = 0; i < symbolCount; ++i) {
- if (!strcmp(symbolTable[i].symbol, token_string))
- return i;
- }
- return -1;
-}
-
-int subIndexOf() {
- for (int i = 0; i < subroutinesCount; ++i) {
- if (!strcmp(subroutinesTable[i].name, token_string))
- return i;
- }
- return -1;
-}
-
-int jumpIndexOf(const char *name) {
- for (int i = 0; i < jumpDestCount; ++i) {
- if (!strcmp(jumpDests[i].name, name))
- return i;
- }
- return -1;
-}
-
-void handle_define() {
- // Read the variable name
- get_token();
- if (token != IDENTIFIER) {
- token = ERROR;
- return;
- }
-
- // Make sure it doesn't already exist
- if (symbolFind() != -1) {
- printf("Duplicate symbol encountered.\n");
- token = ERROR;
- return;
- }
-
- // Store the new symbol name
- strcpy(symbolTable[symbolCount].symbol, token_string);
-
- // Get the value
- get_token();
- if (token == END_OF_LINE) {
- printf("Unexpected end of line.\n");
- token = ERROR;
- }
- if ((token != NUMBER) && (token != IDENTIFIER)) {
- printf("Invalid define value.\n");
- token = ERROR;
- }
- if (token == ERROR)
- return;
-
- // Handle special symbols
- if (!strcmp(symbolTable[symbolCount].symbol, "GAME_ID")) {
- // Specify game number
- if (!strcmp(token_string, "REX"))
- game_number = 1;
- else
- token = ERROR;
- } else if (!strcmp(symbolTable[symbolCount].symbol, "LANGUAGE")) {
- // Specify the language
- if (!strcmp(token_string, "ENGLISH"))
- language = 1;
- else
- token = ERROR;
- } else if (!strcmp(symbolTable[symbolCount].symbol, "INDEX_BLOCK_SIZE")) {
- // Specifying the size of the index
- indexSize = strToInt(token_string);
- } else {
- // Standard symbol - save it's value
- strcpy(symbolTable[symbolCount].value, token_string);
- ++symbolCount;
- }
-
- if (token == ERROR)
- return;
-
- // Ensure the next symbol is the end of line
- get_token();
- if (token != END_OF_LINE) {
- printf("Extraneous information on line.\n");
- token = ERROR;
- }
-}
-
-/**
- * Handles getting a parameter for an opcode
- */
-void get_parameter() {
- int nvalue;
-
- if (token == NUMBER) {
- literal.value.integer = strToInt(token_string);
- return;
- }
-
- if (token != IDENTIFIER)
- return;
-
- nvalue = symbolFind();
- if (nvalue != -1) {
- // Found symbol, so get it's numeric value and return
- token = NUMBER;
- literal.value.integer = strToInt(symbolTable[nvalue].value);
- return;
- }
-
- // Check if the parameter is the name of an already processed subroutine
- strToLower(token_string);
- nvalue = subIndexOf();
- if (nvalue == -1) {
- token = ERROR;
- return;
- }
-
- // Store the index (not the offset) of the subroutine to call
- token = NUMBER;
- literal.value.integer = nvalue;
-}
-
-#define INC_SUB_PTR if (++subroutineSize == MAX_SUBROUTINE_SIZE) { \
- printf("Maximum allowable subroutine size exceeded\n"); \
- token = ERROR; \
- return; \
- }
-
-#define WRITE_SUB_BYTE(v) subroutineData[subroutineSize] = (byte)(v)
-
-/**
- * Handles a single instruction within the sub-routine
- */
-void handle_instruction() {
- // Write out the opcode
- WRITE_SUB_BYTE(opcode);
- INC_SUB_PTR;
-
- get_token();
-
- if (OpcodeList[opcode].paramType == OP_IMM_PARAM) {
- get_parameter();
-
- if (token != NUMBER) {
- printf("Incorrect opcode parameter encountered\n");
- token = ERROR;
- return;
- }
-
- // Apply the correct opcode size to the previously stored opcode and save the byte(s)
- if (literal.value.integer <= 0xff) {
- subroutineData[subroutineSize - 1] |= OPSIZE8;
- WRITE_SUB_BYTE(literal.value.integer);
- INC_SUB_PTR;
- } else if (literal.value.integer <= 0xffff) {
- subroutineData[subroutineSize - 1] |= OPSIZE16;
- WRITE_SUB_BYTE(literal.value.integer);
- INC_SUB_PTR;
- WRITE_SUB_BYTE(literal.value.integer >> 8);
- INC_SUB_PTR;
-
- } else {
- subroutineData[subroutineSize - 1] |= OPSIZE32;
- int v = literal.value.integer;
- for (int i = 0; i < 4; ++i, v >>= 8) {
- WRITE_SUB_BYTE(v);
- INC_SUB_PTR;
- }
- }
-
- get_token();
- } else if (OpcodeList[opcode].paramType == OP_TRANSFER_PARAM) {
-
- if (token != IDENTIFIER) {
- printf("Incorrect opcode parameter encountered\n");
- token = ERROR;
- return;
- }
-
- // Check to see if it's a backward jump to an existing label
- int idx = jumpIndexOf(token_string);
- if (idx != -1) {
- // It's a backwards jump whose destination is already known
- if (jumpDests[idx].offset < 256) {
- // 8-bit destination
- subroutineData[subroutineSize - 1] |= OPSIZE8;
- subroutineData[subroutineSize] = jumpDests[idx].offset;
- INC_SUB_PTR;
- } else {
- // 16-bit destination
- subroutineData[subroutineSize - 1] |= OPSIZE16;
- INC_SUB_PTR;
- subroutineData[subroutineSize] = jumpDests[idx].offset & 0xff;
- INC_SUB_PTR;
- subroutineData[subroutineSize] = (jumpDests[idx].offset >> 8) & 0xff;
- }
- } else {
- // Unknown destination, so save it for later resolving
- strcpy(jumpSources[jumpSourceCount].name, token_string);
- jumpSources[jumpSourceCount].line_number = line_number;
- jumpSources[jumpSourceCount].offset = subroutineSize;
- if (++jumpSourceCount == MAX_SUBROUTINE_JUMPS) {
- printf("Maximum allowable jumps size exceeded\n");
- token = ERROR;
- return;
- }
-
- // Store a 16-bit placeholder
- subroutineData[subroutineSize - 1] |= OPSIZE16;
- WRITE_SUB_BYTE(0);
- INC_SUB_PTR;
- WRITE_SUB_BYTE(0);
- INC_SUB_PTR;
- }
-
- get_token();
- }
-
- if (token != END_OF_LINE)
- token = ERROR;
-}
-
-/**
- * Called at the end of the sub-routine, fixes the destination of any forward jump references
- */
-void fix_subroutine_jumps() {
- for (int i = 0; i < jumpSourceCount; ++i) {
- // Scan through the list of transfer destinations within the script
- int idx = jumpIndexOf(jumpSources[i].name);
- if (idx == -1) {
- token = ERROR;
- line_number = jumpSources[i].line_number;
- return;
- }
-
- // Replace the placeholder bytes with the new destination
- subroutineData[jumpSources[i].offset] = jumpDests[idx].offset & 0xff;
- subroutineData[jumpSources[i].offset + 1] = (jumpDests[idx].offset >> 8) & 0xff;
- }
-}
-
-/**
- * Handles parsing a sub-routine
- */
-void handle_sub() {
- // Get the subroutine name
- get_token();
- if (token != IDENTIFIER) {
- printf("Missing subroutine name.\n");
- token = ERROR;
- return;
- }
-
- strToLower(token_string);
- if (subIndexOf() != -1) {
- printf("Duplicate sub-routine encountered\n");
- token = ERROR;
- return;
- }
-
- // If this is the first subroutine, start writing out the data
- if (subroutinesCount == 0)
- write_header();
-
- // Save the sub-routine details
- strcpy(subroutinesTable[subroutinesCount].name, token_string);
- subroutinesTable[subroutinesCount].fileOffset = fileOffset;
- if (++subroutinesCount == MAX_SUBROUTINES) {
- printf("Exceeded maximum allowed subroutine count\n");
- token = ERROR;
- return;
- }
-
- // Ensure the line end
- get_token();
- if (token != END_OF_LINE) {
- token = ERROR;
- return;
- }
-
- // Initial processing arrays
- memset(subroutineData, 0, MAX_SUBROUTINE_SIZE);
- subroutineSize = 0;
- jumpSourceCount = 0;
- jumpDestCount = 0;
-
- // Loop through the lines of the sub-routine
- while (token != ERROR) {
- get_token();
-
- if (token == END_OF_LINE) continue;
- if (token == RW_OPCODE) {
- // Handle instructions
- handle_instruction();
-
- } else if (token == IDENTIFIER) {
- // Save identifier, it's hopefully a jump symbol
- strcpy(jumpDests[jumpDestCount].name, token_string);
- get_token();
- if (token != RW_COLON)
- token = ERROR;
- else {
- // Save the jump point
- jumpDests[jumpDestCount].offset = subroutineSize;
-
- if (++jumpDestCount == MAX_SUBROUTINE_JUMPS) {
- printf("Subroutine exceeded maximum allowable jump points\n");
- token = ERROR;
- return;
- }
-
- // Ensure it's the last value on the line
- get_token();
- if (token != END_OF_LINE)
- token = ERROR;
- }
- } else if (token == RW_END) {
- // End of subroutine reached
- get_token();
- if (token != ERROR)
- fix_subroutine_jumps();
- write_bytes(&subroutineData[0], subroutineSize);
- break;
-
- } else {
- token = ERROR;
- printf("Unexpected error\n");
- }
- }
-}
-
-/*----------------------------------------------------------------------*/
-/* Character routines */
-/*----------------------------------------------------------------------*/
-
-/**
- * Read the next line from the source file.
- */
-bool get_source_line() {
- if ((fgets(source_buffer, MAX_SOURCE_LINE_LENGTH, source_file)) != NULL) {
- return true;
- }
-
- return false;
-}
-
-/**
- * Set ch to the next character from the source buffer
- */
-void get_char() {
- // If at the end of current source line, read another line.
- // If at end of file, set ch to the EOF character and return
- if (*bufferp == '\0') {
- if (!get_source_line()) {
- ch = EOF_CHAR;
- return;
- }
- bufferp = source_buffer;
- buffer_offset = 0;
- ++line_number;
- ch = EOL_CHAR;
- return;
- }
-
- ch = *bufferp++; // Next character in the buffer
-
- if ((ch == '\n') || (ch == '\t')) ch = ' ';
-}
-
-/**
- * Skip past any blanks in the current location in the source buffer.
- * Set ch to the next nonblank character
- */
-void skip_blanks() {
- while (ch == ' ') get_char();
-}
-
-/*----------------------------------------------------------------------*/
-/* Token routines */
-/*----------------------------------------------------------------------*/
-
-bool is_reserved_word() {
- for (int i = 0; i < 4; ++i) {
- if (!strcmp(symbol_strings[i], token_string)) {
- token = (TokenCode)(RW_DEFINE + i);
- return true;
- }
- }
- return false;
-}
-
-bool is_opcode() {
- for (int i = 0; i < TOTAL_OPCODES; ++i) {
- if (!strcmp(OpcodeList[i].str, token_string)) {
- token = RW_OPCODE;
- opcode = (Opcodes)i;
- paramType = OpcodeList[i].paramType;
- return true;
- }
- }
- return false;
-}
-
-/**
- * Extract a word token and set token to IDENTIFIER
- */
-void get_word() {
- // Extract the word
- while ((char_code(ch) == LETTER) || (char_code(ch) == DIGIT) || (ch == '_')) {
- *tokenp++ = ch;
- get_char();
- }
-
- *tokenp = '\0';
-
- strToUpper(token_string);
- token = WORD;
- if (!is_reserved_word() && !is_opcode()) token = IDENTIFIER;
-}
-
-/**
- * Extract a number token and set literal to it's value. Set token to NUMBER
- */
-void get_number() {
- digit_count = 0; // Total no. of digits in number */
- count_error = false; // Too many digits in number?
-
- do {
- *tokenp++ = ch;
-
- if (++digit_count > MAX_DIGIT_COUNT) {
- count_error = true;
- break;
- }
-
- get_char();
- } while ((char_code(ch) == DIGIT) || (toupper(ch) == 'X') || ((toupper(ch) >= 'A') && (toupper(ch) <= 'F')));
-
- if (count_error) {
- token = ERROR;
- return;
- }
-
- literal.type = INTEGER_LIT;
- literal.value.integer = strToInt(token_string);
- *tokenp = '\0';
- token = NUMBER;
-}
-
-/**
- * Extract a special token
- */
-void get_special() {
- *tokenp++ = ch;
- if (ch == ':') {
- token = RW_COLON;
- get_char();
- return;
- } else if (ch == '/') {
- *tokenp++ = ch;
- get_char();
- if (ch == '/') {
- // Comment, so read until end of line
- while ((ch != EOL_CHAR) && (ch != EOF_CHAR))
- get_char();
- token = END_OF_LINE;
- return;
- }
- }
-
- // Extract the rest of the word
- get_char();
- while ((char_code(ch) == LETTER) || (char_code(ch) == DIGIT)) {
- *tokenp++ = ch;
- get_char();
- }
- *tokenp = '\0';
-
- strToUpper(token_string);
- if (token_string[0] == '@')
- token = IDENTIFIER;
- else if (!is_reserved_word())
- token = ERROR;
-}
-
-/**
- * Extract the next token from the source buffer
- */
-void get_token() {
- skip_blanks();
- tokenp = token_string;
-
- switch (char_code(ch)) {
- case LETTER: get_word(); break;
- case DIGIT: get_number(); break;
- case EOL_CODE: { token = END_OF_LINE; get_char(); break; }
- case EOF_CODE: token = END_OF_FILE; break;
- default: get_special(); break;
- }
-}
-
-/**
- * Handles processing a line outside of subroutines
- */
-void process_line() {
- if ((token == ERROR) || (token == END_OF_FILE)) return;
-
- switch (token) {
- case RW_DEFINE:
- handle_define();
- break;
- case RW_SUB:
- handle_sub();
- break;
- case END_OF_LINE:
- break;
- default:
- token = ERROR;
- break;
- }
-
- if (token == END_OF_LINE) {
- get_token();
- }
-}
-
-/*----------------------------------------------------------------------*/
-/* Interface methods */
-/*----------------------------------------------------------------------*/
-
-/**
- * Main compiler method
- */
-bool Compile(const char *srcFilename, const char *destFilename) {
- init_scanner(srcFilename);
- init_output(destFilename);
-
- get_token();
- while ((token != END_OF_FILE) && (token != ERROR))
- process_line();
-
- if (token != ERROR) {
- write_index();
- }
-
- quit_scanner();
-
- if (token == ERROR)
- printf("Error encountered on line %d\n", line_number);
- else
- printf("Compilation complete\n");
- return token != ERROR;
-}
diff --git a/devtools/create_mads/scripts/rex_nebular.txt b/devtools/create_mads/scripts/rex_nebular.txt
deleted file mode 100644
index f33a574813..0000000000
--- a/devtools/create_mads/scripts/rex_nebular.txt
+++ /dev/null
@@ -1,2241 +0,0 @@
-// MADS Script Engine auto-generated script file
-
-// Special #defines
-#define INDEX_BLOCK_SIZE 8192
-#define GAME_ID REX
-#define LANGUAGE ENGLISH
-
-// List of data variables
-#define Scene_abortTimersMode2 1
-#define Scene_abortTimers 2
-#define Player_stepEnabled 3
-#define Scene_nextScene 4
-#define Scene_priorSceneId 5
-#define Player_playerPos_x 6
-#define Player_playerPos_y 7
-#define Player_direction 8
-#define Player_visible 9
-#define Scene_activeAnimation 10
-#define Animation_currentFrame 11
-
-// Library function list
-#define dialog_show 1
-#define SequenceList_remove 2
-#define start_reversible_sprite_sequence 3
-#define SequenceList_setAnimRange 4
-#define SequenceList_addSubEntry 5
-#define start_cycled_sprite_sequence 6
-#define quotes_get_pointer 7
-#define KernelMessageList_add 8
-#define SequenceList_unk3 9
-#define start_sound 10
-#define SceneLogic_formAnimName 11
-#define SpriteList_addSprites 12
-#define hotspot_activate 13
-#define DynamicHotspots_add 14
-#define SequenceList_setDepth 15
-#define quotes_load 16
-#define form_resource_name 17
-#define MadsScene_loadAnimation 18
-#define Action_isAction 19
-#define start_sprite_sequence3 20
-#define DynamicHotspots_remove 21
-#define object_is_present 22
-#define inventory_add 23
-#define dialog_picture_show 24
-#define object_is_in_inventory 25
-
-// Script functions start here
-
-sub scene101_sub1
- ONE
- DSTORE Scene_abortTimersMode2 // 2ecf2h
- ZERO
- DSTORE Player_stepEnabled // 2ecf8h
- DLOAD Scene_abortTimers // 2ecfeh
- STORE 0
- JUMP @2edc0 // 2ed01h
-@2ed04:
- DLOAD $546E // 2ed04h
- STORE 0
- LOAD 0
- LIBCALL SequenceList_remove
- ZERO
- ZERO
- IMM 6 // 2ed10h
- DLOAD $5450 // 2ed12h
- STORE 0
- IMM 3
- ZERO
- LOAD 0
- LIBCALL start_reversible_sprite_sequence
- STORE 0 // 2ed1ah
- LOAD 0 // 2ed1fh
- DSTORE $546E
- IMM 21
- IMM 17
- LOAD 0
- LIBCALL SequenceList_setAnimRange
- IMM 72 // 2ed2dh
- DLOAD $546E // 2ed2fh
- STORE 0
- ZERO
- ZERO
- LOAD 0
- LIBCALL SequenceList_addSubEntry
- STORE 0 // 2ed36h
- IMM 17 // 2ed3bh
- LIBCALL start_sound
- ZERO
- ZERO
- IMM 2 // 2ed49h
- DLOAD $544A // 2ed4bh
- STORE 0
- IMM 3
- ZERO
- LOAD 0
- LIBCALL start_cycled_sprite_sequence
- STORE 0 // 2ed53h
- LOAD 0 // 2ed58h
- DSTORE $5468
- RET
-@2ed5c:
- ZERO
- ZERO
- ZERO
- DLOAD $5450 // 2ed62h
- STORE 0
- IMM 6
- ZERO
- LOAD 0
- LIBCALL start_cycled_sprite_sequence
- STORE 0 // 2ed6ah
- LOAD 0 // 2ed6fh
- DSTORE $546E
- IMM 17 // 2ed75h
- IMM 17
- IMM 17
- LOAD 0
- LIBCALL SequenceList_setAnimRange
- IMM 57
- LIBCALL quotes_get_pointer
- ZERO
- IMM 60 // 2ed90h
- ZERO
- ZERO
- IMM $1110
- IMM 61
- IMM 143
- LIBCALL KernelMessageList_add
- STORE 0 // 2ed9fh
- IMM 120
- LIBCALL SequenceList_unk3
- STORE 0 // 2edaah
- RET
-@2edb0:
- IMM $2785
- ZERO
- LIBCALL dialog_show
- MINUSONE
- DSTORE Player_stepEnabled // 2edb9h
- RET
-@2edc0:
- LOAD 0 // 2edc0h
- DUP
- STORE 4
- IMM 73
- DUP
- STORE 5
- EQUAL
- JMPTRUE @2edb0 // 2edc3h
- LOAD 4 // 2edc5h
- LOAD 5
- GREAT
- JMPTRUE @2edd2
- LOAD 0 // 2edc7h
- ZERO
- NEQUAL
- JMPTRUE @2edce // 2edc9h
- JUMP @2ed04 // 2edcbh
-@2edce:
- LOAD 0 // 2edceh
- IMM 72
- MINUS
- STORE 0
- LOAD 0 // 2edd0h
- STORE 4
- LOAD 4
- ZERO
- EQUAL
- JMPTRUE @2ed5c
-@2edd2:
- RET
-end
-
-
-sub low_rooms_entry_sound
- DLOAD $5A00 // 2b48ch
- ZERO
- NEQUAL
- JMPTRUE @2b49e // 2b491h
- IMM 2 // 2b493h
-@2b495:
- LIBCALL start_sound
- RET
-@2b49e:
- DLOAD Scene_nextScene // 2b49eh
- STORE 0
- JUMP @2b4d8 // 2b4a1h
-@2b4a4:
- IMM 11 // 2b4a4h
- JUMP @2b495 // 2b4a6h
-@2b4a8:
- IMM 12 // 2b4a8h
- JUMP @2b495 // 2b4aah
-@2b4ac:
- IMM 3 // 2b4ach
- LIBCALL start_sound
- IMM 25 // 2b4b6h
- JUMP @2b495 // 2b4b8h
-@2b4ba:
- DLOAD Scene_priorSceneId // 2b4bah
- IMM 104
- LESS
- JMPTRUE @2b4c8 // 2b4bfh
- DLOAD Scene_priorSceneId // 2b4c1h
- IMM 108
- LEQUAL
- JMPTRUE @2b500 // 2b4c6h
-@2b4c8:
- IMM 10 // 2b4c8h
- JUMP @2b495 // 2b4cah
-@2b4cc:
- IMM 13 // 2b4cch
- JUMP @2b495 // 2b4ceh
-@2b4d0:
- IMM 3 // 2b4d0h
- JUMP @2b495 // 2b4d2h
-@2b4d4:
- IMM 15 // 2b4d4h
- JUMP @2b495 // 2b4d6h
-@2b4d8:
- LOAD 0 // 2b4d8h
- IMM 101
- MINUS
- STORE 0
- LOAD 0 // 2b4dbh
- IMM 11
- GREAT
- JMPTRUE @2b500 // 2b4deh
- LOAD 0 // 2b4e0h
- IMM 2
- MULT
- LOAD 0 // 2b4e2h
- LOAD 1
- STORE 0
-//--- Begin Jump Table ---
- LOAD 1
- ZERO
- EQUAL
- JMPTRUE @2b4a4
- LOAD 1
- ONE
- EQUAL
- JMPTRUE @2b4a8
- LOAD 1
- IMM 2
- EQUAL
- JMPTRUE @2b4ac
- LOAD 1
- IMM 3
- EQUAL
- JMPTRUE @2b4ba
- LOAD 1
- IMM 4
- EQUAL
- JMPTRUE @2b4ba
- LOAD 1
- IMM 5
- EQUAL
- JMPTRUE @2b4ba
- LOAD 1
- IMM 6
- EQUAL
- JMPTRUE @2b4ba
- LOAD 1
- IMM 7
- EQUAL
- JMPTRUE @2b4ba
- LOAD 1
- IMM 8
- EQUAL
- JMPTRUE @2b4cc
- LOAD 1
- IMM 9
- EQUAL
- JMPTRUE @2b4c8
- LOAD 1
- IMM 10
- EQUAL
- JMPTRUE @2b4d0
- LOAD 1
- IMM 11
- EQUAL
- JMPTRUE @2b4d4
-//--- End Jump Table ---
-@2b500:
- RET
-end
-
-
-sub scene101_enter
- ONE
- IMM 120
- LIBCALL SceneLogic_formAnimName
- STORE 0 // 2c985h
- LOAD 0 // 2c98ah
- STORE 1
- ZERO
- LOAD 1
- LIBCALL SpriteList_addSprites
- STORE 0 // 2c98eh
- LOAD 0 // 2c993h
- DSTORE $543C
- IMM 2
- IMM 120
- LIBCALL SceneLogic_formAnimName
- STORE 0 // 2c99bh
- LOAD 0 // 2c9a0h
- STORE 1
- ZERO
- LOAD 1
- LIBCALL SpriteList_addSprites
- STORE 0 // 2c9a4h
- LOAD 0 // 2c9a9h
- DSTORE $543E
- IMM 3
- IMM 120
- LIBCALL SceneLogic_formAnimName
- STORE 0 // 2c9b1h
- LOAD 0 // 2c9b6h
- STORE 1
- ZERO
- LOAD 1
- LIBCALL SpriteList_addSprites
- STORE 0 // 2c9bah
- LOAD 0 // 2c9bfh
- DSTORE $5440
- IMM 4
- IMM 120
- LIBCALL SceneLogic_formAnimName
- STORE 0 // 2c9c7h
- LOAD 0 // 2c9cch
- STORE 1
- ZERO
- LOAD 1
- LIBCALL SpriteList_addSprites
- STORE 0 // 2c9d0h
- LOAD 0 // 2c9d5h
- DSTORE $5442
- IMM 5
- IMM 120
- LIBCALL SceneLogic_formAnimName
- STORE 0 // 2c9ddh
- LOAD 0 // 2c9e2h
- STORE 1
- ZERO
- LOAD 1
- LIBCALL SpriteList_addSprites
- STORE 0 // 2c9e6h
- LOAD 0 // 2c9ebh
- DSTORE $5444
- IMM 6
- IMM 120
- LIBCALL SceneLogic_formAnimName
- STORE 0 // 2c9f3h
- LOAD 0 // 2c9f8h
- STORE 1
- ZERO
- LOAD 1
- LIBCALL SpriteList_addSprites
- STORE 0 // 2c9fch
- LOAD 0 // 2ca01h
- DSTORE $5446
- IMM 7
- IMM 120
- LIBCALL SceneLogic_formAnimName
- STORE 0 // 2ca09h
- LOAD 0 // 2ca0eh
- STORE 1
- ZERO
- LOAD 1
- LIBCALL SpriteList_addSprites
- STORE 0 // 2ca12h
- LOAD 0 // 2ca17h
- DSTORE $5448
- MINUSONE
- IMM 109
- LIBCALL SceneLogic_formAnimName
- STORE 0 // 2ca1fh
- LOAD 0 // 2ca24h
- STORE 1
- ZERO
- LOAD 1
- LIBCALL SpriteList_addSprites
- STORE 0 // 2ca28h
- LOAD 0 // 2ca2dh
- DSTORE $544A
- ONE
- IMM 98
- LIBCALL SceneLogic_formAnimName
- STORE 0 // 2ca35h
- LOAD 0 // 2ca3ah
- STORE 1
- ZERO
- LOAD 1
- LIBCALL SpriteList_addSprites
- STORE 0 // 2ca3eh
- LOAD 0 // 2ca43h
- DSTORE $544C
- IMM 2
- IMM 98
- LIBCALL SceneLogic_formAnimName
- STORE 0 // 2ca4bh
- LOAD 0 // 2ca50h
- STORE 1
- ZERO
- LOAD 1
- LIBCALL SpriteList_addSprites
- STORE 0 // 2ca54h
- LOAD 0 // 2ca59h
- DSTORE $544E
- ZERO
- IMM 97
- LIBCALL SceneLogic_formAnimName
- STORE 0 // 2ca60h
- LOAD 0 // 2ca65h
- STORE 1
- ZERO
- LOAD 1
- LIBCALL SpriteList_addSprites
- STORE 0 // 2ca69h
- LOAD 0 // 2ca6eh
- DSTORE $5450
- ONE
- IMM 97
- LIBCALL SceneLogic_formAnimName
- STORE 0 // 2ca76h
- LOAD 0 // 2ca7bh
- STORE 1
- ZERO
- LOAD 1
- LIBCALL SpriteList_addSprites
- STORE 0 // 2ca7fh
- LOAD 0 // 2ca84h
- DSTORE $5452
- IMM 8
- IMM 120
- LIBCALL SceneLogic_formAnimName
- STORE 0 // 2ca8ch
- LOAD 0 // 2ca91h
- STORE 1
- ZERO
- LOAD 1
- LIBCALL SpriteList_addSprites
- STORE 0 // 2ca95h
- LOAD 0 // 2ca9ah
- DSTORE $5454
- ZERO
- IMM 120
- LIBCALL SceneLogic_formAnimName
- STORE 0 // 2caa1h
- LOAD 0 // 2caa6h
- STORE 1
- ZERO
- LOAD 1
- LIBCALL SpriteList_addSprites
- STORE 0 // 2caaah
- LOAD 0 // 2caafh
- DSTORE $5456
- IMM 25 // 2cab2h
- ZERO
- ZERO
- DLOAD $543C // 2cab8h
- STORE 0
- IMM 5
- ZERO
- LOAD 0
- LIBCALL start_cycled_sprite_sequence
- STORE 0 // 2cac0h
- LOAD 0 // 2cac5h
- DSTORE $545A
- ZERO
- ONE
- ZERO
- DLOAD $543E // 2caceh
- STORE 0
- IMM 4
- ZERO
- LOAD 0
- LIBCALL start_cycled_sprite_sequence
- STORE 0 // 2cad6h
- LOAD 0 // 2cadbh
- DSTORE $545C
- ZERO
- IMM 2 // 2cae0h
- ZERO
- DLOAD $5440 // 2cae4h
- STORE 0
- IMM 6
- ZERO
- LOAD 0
- LIBCALL start_cycled_sprite_sequence
- STORE 0 // 2caech
- LOAD 0 // 2caf1h
- DSTORE $545E
- IMM 70 // 2caf4h
- IMM 7
- IMM 2
- LOAD 0
- LIBCALL SequenceList_addSubEntry
- STORE 0 // 2cafch
- IMM 60 // 2cb01h
- ZERO
- ZERO
- DLOAD $5442 // 2cb07h
- STORE 0
- IMM 10
- ZERO
- LOAD 0
- LIBCALL start_reversible_sprite_sequence
- STORE 0 // 2cb0fh
- LOAD 0 // 2cb14h
- DSTORE $5460
- ZERO
- ONE
- ZERO
- DLOAD $5444 // 2cb1dh
- STORE 0
- IMM 5
- ZERO
- LOAD 0
- LIBCALL start_cycled_sprite_sequence
- STORE 0 // 2cb25h
- LOAD 0 // 2cb2ah
- DSTORE $5462
- ZERO
- IMM 2 // 2cb2fh
- ZERO
- DLOAD $5446 // 2cb33h
- STORE 0
- IMM 10
- ZERO
- LOAD 0
- LIBCALL start_cycled_sprite_sequence
- STORE 0 // 2cb3bh
- LOAD 0 // 2cb40h
- DSTORE $5464
- ZERO
- ZERO
- ZERO
- DLOAD $5448 // 2cb49h
- STORE 0
- IMM 6
- ZERO
- LOAD 0
- LIBCALL start_cycled_sprite_sequence
- STORE 0 // 2cb51h
- LOAD 0 // 2cb56h
- DSTORE $5466
- IMM 4 // 2cb59h
- IMM 10 // 2cb5bh
- ZERO
- DLOAD $544C // 2cb5fh
- STORE 0
- IMM 6
- ZERO
- LOAD 0
- LIBCALL start_cycled_sprite_sequence
- STORE 0 // 2cb67h
- LOAD 0 // 2cb6ch
- DSTORE $546A
- IMM 47 // 2cb6fh
- IMM 32 // 2cb71h
- ZERO
- DLOAD $544E // 2cb75h
- STORE 0
- IMM 6
- ZERO
- LOAD 0
- LIBCALL start_cycled_sprite_sequence
- STORE 0 // 2cb7dh
- LOAD 0 // 2cb82h
- DSTORE $546C
- ZERO
- IMM 311
- LIBCALL hotspot_activate
- ZERO
- DSTORE $547E // 2cb8eh
- DLOAD Scene_priorSceneId // 2cb94h
- MINUSONE
- EQUAL
- JMPTRUE @2cba1 // 2cb99h
- ZERO
- GSTORE 10 // 2cb9bh
-@2cba1:
- DLOAD Scene_priorSceneId // 2cba1h
- IMM $FFFE
- EQUAL
- JMPTRUE @2cbb4 // 2cba6h
- IMM 100 // 2cba8h
- DSTORE Player_playerPos_x
- IMM 152 // 2cbaeh
- DSTORE Player_playerPos_y
-@2cbb4:
- DLOAD Scene_priorSceneId // 2cbb4h
- IMM 112
- EQUAL
- JMPTRUE @2cbc9 // 2cbb9h
- DLOAD Scene_priorSceneId // 2cbbbh
- IMM $FFFE
- NEQUAL
- JMPTRUE @2cc36 // 2cbc0h
- DLOAD $5476 // 2cbc2h
- ZERO
- EQUAL
- JMPTRUE @2cc36 // 2cbc7h
-@2cbc9:
- IMM 161 // 2cbcfh
- DSTORE Player_playerPos_x
- IMM 123 // 2cbd5h
- DSTORE Player_playerPos_y
- IMM 9 // 2cbdbh
- DSTORE Player_direction
- ZERO
- ZERO
- ZERO
- DLOAD $5450 // 2cbe7h
- STORE 0
- ZERO
- DSTORE Player_visible // 2cbech
- IMM 3
- ZERO
- LOAD 0
- LIBCALL start_cycled_sprite_sequence
- STORE 0 // 2cbf3h
- LOAD 0 // 2cbf8h
- DSTORE $546E
- IMM 17 // 2cbfeh
- IMM 17
- IMM 17
- LOAD 0
- LIBCALL SequenceList_setAnimRange
- ZERO
- IMM 71
- LIBCALL hotspot_activate
- IMM 159 // 2cc0eh
- IMM 84 // 2cc11h
- IMM 33 // 2cc13h
- IMM 36 // 2cc15h
- MINUSONE
- IMM 319
- IMM 71
- LIBCALL DynamicHotspots_add
- STORE 0 // 2cc20h
- LOAD 0 // 2cc25h
- DSTORE $5478
- DLOAD Scene_priorSceneId // 2cc28h
- IMM 112
- NEQUAL
- JMPTRUE @2cc54 // 2cc2dh
- CALL scene101_sub1
- JUMP @2cc54 // 2cc34h
-@2cc36:
- ZERO
- ZERO
- ZERO
- DLOAD $5452 // 2cc3ch
- STORE 0
- IMM 6
- ZERO
- LOAD 0
- LIBCALL start_cycled_sprite_sequence
- STORE 0 // 2cc44h
- LOAD 0 // 2cc49h
- DSTORE $5470
- IMM 4
- LOAD 0
- LIBCALL SequenceList_setDepth
-@2cc54:
- ZERO
- IMM 56 // 2cc56h
- IMM 55 // 2cc58h
- IMM 54 // 2cc5ah
- IMM 57 // 2cc5ch
- IMM 50 // 2cc5eh
- IMM 49 // 2cc60h
- LIBCALL quotes_load
- STORE 0 // 2cc62h
- LOAD 0 // 2cc6ah
- DSTORE $5674
- GLOAD 10 // 2cc71h
- ZERO
- EQUAL
- JMPTRUE @2ccb8 // 2cc76h
- ZERO
- ZERO
- IMM 2 // 2cc7ch
- MINUSONE
- IMM 83
- IMM 101
- LIBCALL form_resource_name
- STORE 0 // 2cc86h
- LOAD 0 // 2cc8bh
- STORE 1
- LOAD 1
- IMM 71
- LIBCALL MadsScene_loadAnimation
- IMM 68 // 2cc95h
- DSTORE Player_playerPos_x
- IMM 140 // 2cc9bh
- DSTORE Player_playerPos_y
- IMM 4 // 2cca1h
- DSTORE Player_direction
- ZERO
- DSTORE Player_visible // 2cca9h
- ZERO
- DSTORE Player_stepEnabled // 2ccach
- ZERO
- DSTORE $5482 // 2ccafh
- IMM 30 // 2ccb2h
- DSTORE $5484
-@2ccb8:
- ZERO
- DSTORE $5486 // 2ccb8h
- CALL low_rooms_entry_sound
- RET
-end
-
-
-sub scene101_step
- DLOAD $56E4 // 2eb30h
- STORE 0
- DLOAD $5486 // 2eb33h
- LOAD 0
- EQUAL
- JMPTRUE @2eb4e // 2eb37h
- LOAD 0 // 2eb39h
- DSTORE $5486
- LOAD 0 // 2eb3ch
- ZERO
- EQUAL
- JMPTRUE @2eb44 // 2eb3eh
- IMM 39 // 2eb40h
- JUMP @2eb46 // 2eb42h
-@2eb44:
- IMM 11 // 2eb44h
-@2eb46:
- LIBCALL start_sound
-@2eb4e:
- DLOAD Scene_abortTimers // 2eb4eh
- STORE 0
- JUMP @2eb92 // 2eb51h
-@2eb54:
- IMM 9 // 2eb54h
- LIBCALL start_sound
- JUMP @2eba0 // 2eb5eh
-@2eb60:
- ZERO
- GSTORE 10 // 2eb60h
- MINUSONE
- DSTORE Player_visible // 2eb69h
- MINUSONE
- DSTORE Player_stepEnabled // 2eb6ch
- DLOAD $56E8 // 2eb6fh
- STORE 0
- DLOAD $542A // 2eb73h
- STORE 2
- ZERO
- STORE 1 // 2eb77h
- LOAD 2 // 2eb7bh
- LOAD 0
- MINUS
- STORE 2
- LOAD 2 // 2eb7fh
- DSTORE $57D0
- JUMP @2eba0 // 2eb87h
-@2eb8a:
- CALL scene101_sub1
- JUMP @2eba0 // 2eb8fh
-@2eb92:
- LOAD 0 // 2eb92h
- IMM 70
- MINUS
- STORE 0
- LOAD 0 // 2eb95h
- STORE 4
- LOAD 4
- ZERO
- EQUAL
- JMPTRUE @2eb54
- LOAD 0 // 2eb97h
- ONE
- MINUS
- STORE 0
- LOAD 0 // 2eb98h
- STORE 4
- LOAD 4
- ZERO
- EQUAL
- JMPTRUE @2eb60
- LOAD 0 // 2eb9ah
- ONE
- MINUS
- STORE 0
- LOAD 0 // 2eb9bh
- STORE 4
- LOAD 4
- ZERO
- EQUAL
- JMPTRUE @2eb8a
- LOAD 0 // 2eb9dh
- ONE
- MINUS
- STORE 0
- LOAD 0 // 2eb9eh
- STORE 4
- LOAD 4
- ZERO
- EQUAL
- JMPTRUE @2eb8a
-@2eba0:
- ZERO
- STORE 0 // 2eba0h
- LOAD 0 // 2eba3h
- DLOAD Scene_activeAnimation
- OR
- ZERO
- NEQUAL
- JMPTRUE @2ebac // 2eba7h
- JUMP @2ecf1 // 2eba9h
-@2ebac:
- DLOAD Animation_currentFrame // 2ebach
- IMM 6
- LESS
- JMPTRUE @2ebed // 2ebb1h
- DLOAD $5482 // 2ebb3h
- ZERO
- NEQUAL
- JMPTRUE @2ebed // 2ebb8h
- DLOAD $5482 // 2ebbah
- ONE
- PLUS
- DSTORE $5482
- IMM 49
- LIBCALL quotes_get_pointer
- ZERO
- IMM 240 // 2ebd2h
- ZERO
- ZERO
- DLOAD $5484 // 2ebd9h
- STORE 3
- IMM $1110
- LOAD 3
- IMM 63
- LIBCALL KernelMessageList_add
- STORE 0 // 2ebe3h
- DLOAD $5484 // 2ebe8h
- IMM 14
- PLUS
- DSTORE $5484
-@2ebed:
- DLOAD Animation_currentFrame // 2ebedh
- IMM 7
- LESS
- JMPTRUE @2ec2e // 2ebf2h
- DLOAD $5482 // 2ebf4h
- ONE
- NEQUAL
- JMPTRUE @2ec2e // 2ebf9h
- DLOAD $5482 // 2ebfbh
- ONE
- PLUS
- DSTORE $5482
- IMM 54
- LIBCALL quotes_get_pointer
- ZERO
- IMM 240 // 2ec13h
- ZERO
- ZERO
- DLOAD $5484 // 2ec1ah
- STORE 3
- IMM $1110
- LOAD 3
- IMM 63
- LIBCALL KernelMessageList_add
- STORE 0 // 2ec24h
- DLOAD $5484 // 2ec29h
- IMM 14
- PLUS
- DSTORE $5484
-@2ec2e:
- DLOAD Animation_currentFrame // 2ec2eh
- IMM 10
- LESS
- JMPTRUE @2ec6f // 2ec33h
- DLOAD $5482 // 2ec35h
- IMM 2
- NEQUAL
- JMPTRUE @2ec6f // 2ec3ah
- DLOAD $5482 // 2ec3ch
- ONE
- PLUS
- DSTORE $5482
- IMM 55
- LIBCALL quotes_get_pointer
- ZERO
- IMM 240 // 2ec54h
- ZERO
- ZERO
- DLOAD $5484 // 2ec5bh
- STORE 3
- IMM $1110
- LOAD 3
- IMM 63
- LIBCALL KernelMessageList_add
- STORE 0 // 2ec65h
- DLOAD $5484 // 2ec6ah
- IMM 14
- PLUS
- DSTORE $5484
-@2ec6f:
- DLOAD Animation_currentFrame // 2ec6fh
- IMM 17
- LESS
- JMPTRUE @2ecb0 // 2ec74h
- DLOAD $5482 // 2ec76h
- IMM 3
- NEQUAL
- JMPTRUE @2ecb0 // 2ec7bh
- DLOAD $5482 // 2ec7dh
- ONE
- PLUS
- DSTORE $5482
- IMM 56
- LIBCALL quotes_get_pointer
- ZERO
- IMM 240 // 2ec95h
- ZERO
- ZERO
- DLOAD $5484 // 2ec9ch
- STORE 3
- IMM $1110
- LOAD 3
- IMM 63
- LIBCALL KernelMessageList_add
- STORE 0 // 2eca6h
- DLOAD $5484 // 2ecabh
- IMM 14
- PLUS
- DSTORE $5484
-@2ecb0:
- DLOAD Animation_currentFrame // 2ecb0h
- IMM 20
- LESS
- JMPTRUE @2ecf1 // 2ecb5h
- DLOAD $5482 // 2ecb7h
- IMM 4
- NEQUAL
- JMPTRUE @2ecf1 // 2ecbch
- DLOAD $5482 // 2ecbeh
- ONE
- PLUS
- DSTORE $5482
- IMM 50
- LIBCALL quotes_get_pointer
- ZERO
- IMM 240 // 2ecd6h
- ZERO
- ZERO
- DLOAD $5484 // 2ecddh
- STORE 3
- IMM $1110
- LOAD 3
- IMM 63
- LIBCALL KernelMessageList_add
- STORE 0 // 2ece7h
- DLOAD $5484 // 2ecech
- IMM 14
- PLUS
- DSTORE $5484
-@2ecf1:
- RET
-end
-
-
-sub scene101_preaction
- ZERO
- IMM 384 // 2edd6h
- IMM 3 // 2edd9h
- LIBCALL Action_isAction
- STORE 0 // 2eddbh
- LOAD 0 // 2ede3h
- ZERO
- EQUAL
- JMPTRUE @2eded // 2ede5h
- MINUSONE
- DSTORE $56F2 // 2ede7h
-@2eded:
- DLOAD $5476 // 2ededh
- ZERO
- NEQUAL
- JMPTRUE @2edf7 // 2edf2h
- JUMP @2eea9 // 2edf4h
-@2edf7:
- ZERO
- IMM 3 // 2edf9h
- LIBCALL Action_isAction
- STORE 0 // 2edfbh
- LOAD 0 // 2ee03h
- ZERO
- NEQUAL
- JMPTRUE @2ee44 // 2ee05h
- LOAD 0 // 2ee07h
- IMM 71 // 2ee08h
- LIBCALL Action_isAction
- STORE 0 // 2ee0ah
- LOAD 0 // 2ee12h
- ZERO
- NEQUAL
- JMPTRUE @2ee44 // 2ee14h
- LOAD 0 // 2ee16h
- IMM 8 // 2ee17h
- LIBCALL Action_isAction
- STORE 0 // 2ee19h
- LOAD 0 // 2ee21h
- ZERO
- NEQUAL
- JMPTRUE @2ee44 // 2ee23h
- LOAD 0 // 2ee25h
- IMM 259 // 2ee26h
- LIBCALL Action_isAction
- STORE 0 // 2ee29h
- LOAD 0 // 2ee31h
- ZERO
- NEQUAL
- JMPTRUE @2ee44 // 2ee33h
- LOAD 0 // 2ee35h
- IMM 125 // 2ee36h
- LIBCALL Action_isAction
- STORE 0 // 2ee38h
- LOAD 0 // 2ee40h
- ZERO
- EQUAL
- JMPTRUE @2ee4a // 2ee42h
-@2ee44:
- ZERO
- DSTORE $56F2 // 2ee44h
-@2ee4a:
- DLOAD $56F2 // 2ee4ah
- ZERO
- EQUAL
- JMPTRUE @2eea9 // 2ee4fh
- DLOAD Scene_abortTimers // 2ee51h
- STORE 0
- LOAD 0 // 2ee54h
- ZERO
- EQUAL
- JMPTRUE @2ee60 // 2ee56h
- LOAD 0 // 2ee58h
- ONE
- MINUS
- STORE 0
- LOAD 0 // 2ee59h
- STORE 4
- LOAD 4
- ZERO
- NEQUAL
- JMPTRUE @2ee5e
- JUMP @2eee0 // 2ee5bh
-@2ee5e:
- JUMP @2eea9 // 2ee5eh
-@2ee60:
- ZERO
- DSTORE $56F4 // 2ee62h
- ZERO
- DSTORE Player_stepEnabled // 2ee65h
- DLOAD $546E // 2ee68h
- STORE 0
- LOAD 0
- LIBCALL SequenceList_remove
- ZERO
- ZERO
- ONE
- DLOAD $5450 // 2ee76h
- STORE 0
- IMM 3
- ZERO
- LOAD 0
- LIBCALL start_sprite_sequence3
- STORE 0 // 2ee7eh
- LOAD 0 // 2ee83h
- DSTORE $546E
- ONE
- ZERO
- ZERO
- LOAD 0
- LIBCALL SequenceList_addSubEntry
- STORE 0 // 2ee8ch
- DLOAD $546E // 2ee91h
- STORE 0
- IMM 17
- ONE
- LOAD 0
- LIBCALL SequenceList_setAnimRange
- IMM 16 // 2ee9fh
- LIBCALL start_sound
-@2eea9:
- DLOAD $547E // 2eea9h
- ZERO
- NEQUAL
- JMPTRUE @2eeb3 // 2eeaeh
- JUMP @2ef9f // 2eeb0h
-@2eeb3:
- ZERO
- IMM 309 // 2eeb5h
- LIBCALL Action_isAction
- STORE 0 // 2eeb8h
- LOAD 0 // 2eec0h
- ZERO
- EQUAL
- JMPTRUE @2eec7 // 2eec2h
- JUMP @2ef9f // 2eec4h
-@2eec7:
- LOAD 0 // 2eec7h
- IMM 311 // 2eec8h
- LIBCALL Action_isAction
- STORE 0 // 2eecbh
- LOAD 0 // 2eed3h
- ZERO
- EQUAL
- JMPTRUE @2eeda // 2eed5h
- JUMP @2ef9f // 2eed7h
-@2eeda:
- DLOAD Scene_abortTimers // 2eedah
- STORE 0
- JUMP @2ef98 // 2eeddh
-@2eee0:
- MINUSONE
- DSTORE Player_visible // 2eee9h
- MINUSONE
- DSTORE Player_stepEnabled // 2eeedh
- MINUSONE
- DSTORE $56F4 // 2eef1h
- MINUSONE
- IMM 71
- LIBCALL hotspot_activate
- DLOAD $5478 // 2eefdh
- STORE 0
- LOAD 0
- LIBCALL DynamicHotspots_remove
- ZERO
- ZERO
- ZERO
- DLOAD $5452 // 2ef0bh
- STORE 0
- IMM 6
- ZERO
- LOAD 0
- LIBCALL start_cycled_sprite_sequence
- STORE 0 // 2ef13h
- LOAD 0 // 2ef18h
- DSTORE $5470
- IMM 4
- LOAD 0
- LIBCALL SequenceList_setDepth
- JUMP @2eea9 // 2ef23h
-@2ef26:
- DLOAD $56F2 // 2ef26h
- ZERO
- EQUAL
- JMPTRUE @2ef9f // 2ef2bh
- DLOAD $5472 // 2ef2dh
- STORE 0
- LOAD 0
- LIBCALL SequenceList_remove
- IMM 24
- LIBCALL object_is_present
- STORE 0 // 2ef38h
- ONE
- STORE 4 // 2ef3dh
- LOAD 0
- ONE
- EQUAL
- JMPFALSE @2ef42
- ZERO
- STORE 4
-@2ef42:
- LOAD 4
- STORE 0
- LOAD 0 // 2ef45h
- IMM 13
- PLUS
- STORE 0
- LOAD 0 // 2ef48h
- DSTORE $5480
- ZERO
- ZERO
- ONE
- LOAD 0 // 2ef51h
- STORE 1
- LOAD 1 // 2ef53h
- IMM 2
- MULT
- IMM 6
- ZERO
- ONE
- LIBCALL start_sprite_sequence3
- STORE 0 // 2ef5eh
- LOAD 0 // 2ef63h
- DSTORE $5472
- ONE
- ZERO
- ZERO
- LOAD 0
- LIBCALL SequenceList_addSubEntry
- STORE 0 // 2ef6ch
- ZERO
- DSTORE Player_stepEnabled // 2ef71h
- IMM 20 // 2ef77h
- LIBCALL start_sound
- RET
-@2ef82:
- MINUSONE
- DSTORE Player_stepEnabled // 2ef82h
- ZERO
- DSTORE $547E // 2ef8ah
- ZERO
- IMM 311
- LIBCALL hotspot_activate
- RET
-@2ef98:
- LOAD 0 // 2ef98h
- ZERO
- EQUAL
- JMPTRUE @2ef26 // 2ef9ah
- LOAD 0 // 2ef9ch
- ONE
- MINUS
- STORE 0
- LOAD 0 // 2ef9dh
- STORE 4
- LOAD 4
- ZERO
- EQUAL
- JMPTRUE @2ef82
-@2ef9f:
- RET
-end
-
-
-sub scene101_actions
- DLOAD $577A // 2efa0h
- ZERO
- EQUAL
- JMPTRUE @2efae // 2efa5h
- DLOAD 0 // 2efaah
- STORE 0
- JUMP @2f28f
-@2efae:
- ZERO
- IMM 204 // 2efb0h
- IMM 13 // 2efb3h
- LIBCALL Action_isAction
- STORE 0 // 2efb5h
- LOAD 0 // 2efbdh
- ZERO
- EQUAL
- JMPTRUE @2efca // 2efbfh
- IMM 102 // 2efc1h
- DSTORE Scene_nextScene
- JUMP @2f6b4 // 2efc7h
-@2efca:
- ZERO
- IMM 71 // 2efcch
- IMM 319 // 2efceh
- LIBCALL Action_isAction
- STORE 0 // 2efd1h
- LOAD 0 // 2efd9h
- ZERO
- NEQUAL
- JMPTRUE @2eff9 // 2efdbh
- LOAD 0 // 2efddh
- IMM 384 // 2efdeh
- IMM 3 // 2efe1h
- LIBCALL Action_isAction
- STORE 0 // 2efe3h
- LOAD 0 // 2efebh
- ZERO
- NEQUAL
- JMPTRUE @2eff2 // 2efedh
- JUMP @2f072 // 2efefh
-@2eff2:
- DLOAD $5476 // 2eff2h
- ZERO
- NEQUAL
- JMPTRUE @2f072 // 2eff7h
-@2eff9:
- DLOAD $5476 // 2eff9h
- ZERO
- EQUAL
- JMPTRUE @2f003 // 2effeh
- JUMP @2f120 // 2f000h
-@2f003:
- DLOAD Scene_abortTimers // 2f003h
- STORE 0
- LOAD 0 // 2f006h
- ZERO
- EQUAL
- JMPTRUE @2f016 // 2f008h
- LOAD 0 // 2f00ah
- ONE
- MINUS
- STORE 0
- LOAD 0 // 2f00bh
- STORE 4
- LOAD 4
- ZERO
- EQUAL
- JMPTRUE @2f068
- LOAD 0 // 2f00dh
- ONE
- MINUS
- STORE 0
- LOAD 0 // 2f00eh
- STORE 4
- LOAD 4
- ZERO
- NEQUAL
- JMPTRUE @2f013
- JUMP @2f0b4 // 2f010h
-@2f013:
- JUMP @2f072 // 2f013h
-@2f016:
- DLOAD $5470 // 2f016h
- STORE 0
- LOAD 0
- LIBCALL SequenceList_remove
- ZERO
- ZERO
- ONE
- DLOAD $5450 // 2f024h
- STORE 0
- IMM 3
- ZERO
- LOAD 0
- LIBCALL start_cycled_sprite_sequence
- STORE 0 // 2f02ch
- LOAD 0 // 2f031h
- DSTORE $546E
- IMM 17
- ONE
- LOAD 0
- LIBCALL SequenceList_setAnimRange
- ONE
- DLOAD $546E // 2f041h
- STORE 0
- IMM 10
- IMM 2
- LOAD 0
- LIBCALL SequenceList_addSubEntry
- STORE 0 // 2f04ah
- IMM 2 // 2f04fh
- DLOAD $546E // 2f051h
- STORE 0
- ZERO
- ZERO
- LOAD 0
- LIBCALL SequenceList_addSubEntry
- STORE 0 // 2f058h
- ZERO
- DSTORE Player_stepEnabled // 2f05fh
- ZERO
- DSTORE Player_visible // 2f062h
- DLOAD 0 // 2f065h
- STORE 0
- JUMP @2f6b4
-@2f068:
- IMM 16 // 2f068h
- LIBCALL start_sound
-@2f072:
- ZERO
- IMM 309 // 2f074h
- IMM 13 // 2f077h
- LIBCALL Action_isAction
- STORE 0 // 2f079h
- LOAD 0 // 2f081h
- ZERO
- NEQUAL
- JMPTRUE @2f09a // 2f083h
- LOAD 0 // 2f085h
- IMM 309 // 2f086h
- IMM 6 // 2f089h
- LIBCALL Action_isAction
- STORE 0 // 2f08bh
- LOAD 0 // 2f093h
- ZERO
- NEQUAL
- JMPTRUE @2f09a // 2f095h
- JUMP @2f1cc // 2f097h
-@2f09a:
- DLOAD $547E // 2f09ah
- ZERO
- EQUAL
- JMPTRUE @2f0a4 // 2f09fh
- JUMP @2f1cc // 2f0a1h
-@2f0a4:
- DLOAD Scene_abortTimers // 2f0a4h
- STORE 0
- LOAD 0 // 2f0a7h
- ZERO
- EQUAL
- JMPTRUE @2f126 // 2f0a9h
- LOAD 0 // 2f0abh
- ONE
- MINUS
- STORE 0
- LOAD 0 // 2f0ach
- STORE 4
- LOAD 4
- ZERO
- NEQUAL
- JMPTRUE @2f0b1
- JUMP @2f176 // 2f0aeh
-@2f0b1:
- JUMP @2f6b4 // 2f0b1h
-@2f0b4:
- ZERO
- ZERO
- ZERO
- DLOAD $5450 // 2f0bah
- STORE 0
- IMM 3
- ZERO
- LOAD 0
- LIBCALL start_cycled_sprite_sequence
- STORE 0 // 2f0c2h
- LOAD 0 // 2f0c7h
- DSTORE $546E
- IMM 17 // 2f0cdh
- IMM 17
- IMM 17
- LOAD 0
- LIBCALL SequenceList_setAnimRange
- MINUSONE
- DSTORE Player_stepEnabled // 2f0d7h
- ZERO
- IMM 71
- LIBCALL hotspot_activate
- IMM 159 // 2f0e6h
- IMM 84 // 2f0e9h
- IMM 33 // 2f0ebh
- IMM 36 // 2f0edh
- MINUSONE
- IMM 319
- IMM 71
- LIBCALL DynamicHotspots_add
- STORE 0 // 2f0f8h
- LOAD 0 // 2f0fdh
- DSTORE $5478
- ZERO
- IMM 384 // 2f102h
- IMM 3 // 2f105h
- LIBCALL Action_isAction
- STORE 0 // 2f107h
- LOAD 0 // 2f10fh
- ZERO
- NEQUAL
- JMPTRUE @2f116 // 2f111h
- JUMP @2f6b4 // 2f113h
-@2f116:
- ZERO
- DSTORE Scene_abortTimers // 2f116h
- JUMP @2f072 // 2f11ch
-@2f120:
- DLOAD 0 // 2f123h
- STORE 0
- JUMP @2f28f
-@2f126:
- IMM 24
- LIBCALL object_is_present
- STORE 0 // 2f129h
- ONE
- STORE 4 // 2f12eh
- LOAD 0
- ONE
- EQUAL
- JMPFALSE @2f133
- ZERO
- STORE 4
-@2f133:
- LOAD 4
- STORE 0
- LOAD 0 // 2f136h
- IMM 13
- PLUS
- STORE 0
- LOAD 0 // 2f139h
- DSTORE $5480
- ZERO
- ZERO
- ONE
- LOAD 0 // 2f142h
- STORE 1
- LOAD 1 // 2f144h
- IMM 2
- MULT
- IMM 6
- ZERO
- ONE
- LIBCALL start_cycled_sprite_sequence
- STORE 0 // 2f14fh
- LOAD 0 // 2f154h
- DSTORE $5472
- ONE
- ZERO
- ZERO
- LOAD 0
- LIBCALL SequenceList_addSubEntry
- STORE 0 // 2f15dh
- ZERO
- DSTORE Player_stepEnabled // 2f162h
- IMM 20 // 2f168h
-@2f16a:
- LIBCALL start_sound
- JUMP @2f6b4 // 2f172h
-@2f176:
- DLOAD $5472 // 2f176h
- STORE 0
- LOAD 0
- LIBCALL SequenceList_remove
- ZERO
- ZERO
- ZERO
- DLOAD $5480 // 2f184h
- STORE 1
- LOAD 1 // 2f188h
- IMM 2
- MULT
- IMM 6
- ZERO
- ONE
- LIBCALL start_cycled_sprite_sequence
- STORE 0 // 2f193h
- LOAD 0 // 2f198h
- DSTORE $5472
- IMM $FFFE // 2f19eh
- IMM $FFFE
- IMM $FFFE
- LOAD 0
- LIBCALL SequenceList_setAnimRange
- MINUSONE
- DSTORE Player_stepEnabled // 2f1a8h
- MINUSONE
- DSTORE $547E // 2f1abh
- IMM 24
- LIBCALL object_is_present
- STORE 0 // 2f1b1h
- LOAD 0 // 2f1b6h
- ZERO
- NEQUAL
- JMPTRUE @2f1bd // 2f1b8h
- JUMP @2f6b4 // 2f1bah
-@2f1bd:
- MINUSONE
- IMM 311
- LIBCALL hotspot_activate
- JUMP @2f6b4 // 2f1c8h
-@2f1cc:
- ZERO
- IMM 311 // 2f1ceh
- IMM 4 // 2f1d1h
- LIBCALL Action_isAction
- STORE 0 // 2f1d3h
- LOAD 0 // 2f1dbh
- ZERO
- NEQUAL
- JMPTRUE @2f1f1 // 2f1ddh
- LOAD 0 // 2f1dfh
- IMM 311 // 2f1e0h
- IMM 10 // 2f1e3h
- LIBCALL Action_isAction
- STORE 0 // 2f1e5h
- LOAD 0 // 2f1edh
- ZERO
- EQUAL
- JMPTRUE @2f248 // 2f1efh
-@2f1f1:
- IMM 24
- LIBCALL object_is_present
- STORE 0 // 2f1f4h
- LOAD 0 // 2f1f9h
- ZERO
- EQUAL
- JMPTRUE @2f248 // 2f1fbh
- IMM 24
- LIBCALL inventory_add
- DLOAD $5472 // 2f205h
- STORE 0
- LOAD 0
- LIBCALL SequenceList_remove
- ZERO
- ZERO
- ZERO
- DLOAD $5456 // 2f213h
- STORE 0
- IMM 6
- ZERO
- LOAD 0
- LIBCALL start_cycled_sprite_sequence
- STORE 0 // 2f21bh
- LOAD 0 // 2f220h
- DSTORE $5472
- IMM $FFFE // 2f226h
- IMM $FFFE
- IMM $FFFE
- LOAD 0
- LIBCALL SequenceList_setAnimRange
- ZERO
- IMM 311
- LIBCALL hotspot_activate
- ZERO
- IMM $2788 // 2f238h
- LIBCALL dialog_picture_show
- IMM 22 // 2f243h
- JUMP @2f16a // 2f245h
-@2f248:
- ZERO
- IMM 309 // 2f24ah
- IMM 3 // 2f24dh
- LIBCALL Action_isAction
- STORE 0 // 2f24fh
- LOAD 0 // 2f257h
- ZERO
- NEQUAL
- JMPTRUE @2f279 // 2f259h
- LOAD 0 // 2f25bh
- IMM 311 // 2f25ch
- IMM 3 // 2f25fh
- LIBCALL Action_isAction
- STORE 0 // 2f261h
- LOAD 0 // 2f269h
- ZERO
- EQUAL
- JMPTRUE @2f2a6 // 2f26bh
- LIBCALL object_is_in_inventory
- STORE 0 // 2f270h
- LOAD 0 // 2f275h
- ZERO
- NEQUAL
- JMPTRUE @2f2a6 // 2f277h
-@2f279:
- DLOAD $547E // 2f279h
- ZERO
- EQUAL
- JMPTRUE @2f2a0 // 2f27eh
- IMM 24
- LIBCALL object_is_present
- STORE 0 // 2f283h
- LOAD 0 // 2f288h
- ZERO
- EQUAL
- JMPTRUE @2f29a // 2f28ah
-@2f28f:
-@2f291:
- IMM $2790
- ZERO
- LIBCALL dialog_show
- JUMP @2f6b4 // 2f296h
-@2f29a:
-@2f29d:
- DLOAD 0 // 2f29eh
- STORE 0
- JUMP @2f291
-@2f2a0:
- DLOAD 0 // 2f2a3h
- STORE 0
- JUMP @2f29d
-@2f2a6:
- ZERO
- IMM 309 // 2f2a8h
- IMM 6 // 2f2abh
- LIBCALL Action_isAction
- STORE 0 // 2f2adh
- LOAD 0 // 2f2b5h
- ZERO
- EQUAL
- JMPTRUE @2f2c6 // 2f2b7h
- DLOAD $547E // 2f2b9h
- ZERO
- EQUAL
- JMPTRUE @2f2c6 // 2f2beh
- DLOAD 0 // 2f2c3h
- STORE 0
- JUMP @2f28f
-@2f2c6:
- ZERO
- IMM 384 // 2f2c8h
- IMM 3 // 2f2cbh
- LIBCALL Action_isAction
- STORE 0 // 2f2cdh
- LOAD 0 // 2f2d5h
- ZERO
- NEQUAL
- JMPTRUE @2f2dc // 2f2d7h
- JUMP @2f3d8 // 2f2d9h
-@2f2dc:
- DLOAD $5476 // 2f2dch
- ZERO
- NEQUAL
- JMPTRUE @2f2e6 // 2f2e1h
- JUMP @2f3d8 // 2f2e3h
-@2f2e6:
- GLOAD 14 // 2f2e6h
- ZERO
- EQUAL
- JMPTRUE @2f2f4 // 2f2ebh
- CALL scene101_sub1
- JUMP @2f6b4 // 2f2f1h
-@2f2f4:
- DLOAD Scene_abortTimers // 2f2f4h
- STORE 0
- LOAD 0 // 2f2f7h
- ZERO
- EQUAL
- JMPTRUE @2f30a // 2f2f9h
- LOAD 0 // 2f2fbh
- ONE
- MINUS
- STORE 0
- LOAD 0 // 2f2fch
- STORE 4
- LOAD 4
- ZERO
- EQUAL
- JMPTRUE @2f34c
- LOAD 0 // 2f2feh
- ONE
- MINUS
- STORE 0
- LOAD 0 // 2f2ffh
- STORE 4
- LOAD 4
- ZERO
- EQUAL
- JMPTRUE @2f37e
- LOAD 0 // 2f301h
- ONE
- MINUS
- STORE 0
- LOAD 0 // 2f302h
- STORE 4
- LOAD 4
- ZERO
- NEQUAL
- JMPTRUE @2f307
- JUMP @2f3c2 // 2f304h
-@2f307:
- JUMP @2f6b4 // 2f307h
-@2f30a:
- ZERO
- DSTORE Player_stepEnabled // 2f30ah
- DLOAD $546E // 2f310h
- STORE 0
- LOAD 0
- LIBCALL SequenceList_remove
- ZERO
- ZERO
- ONE
- DLOAD $5450 // 2f31eh
- STORE 0
- IMM 3
- ZERO
- LOAD 0
- LIBCALL start_cycled_sprite_sequence
- STORE 0 // 2f326h
- LOAD 0 // 2f32bh
- DSTORE $546E
- IMM 21
- IMM 17
- LOAD 0
- LIBCALL SequenceList_setAnimRange
- ONE
- DLOAD $546E // 2f33bh
- STORE 0
- ZERO
- ZERO
- LOAD 0
- LIBCALL SequenceList_addSubEntry
- STORE 0 // 2f342h
- IMM 17 // 2f347h
- JUMP @2f16a // 2f349h
-@2f34c:
- ZERO
- ZERO
- ONE
- DLOAD $5450 // 2f352h
- STORE 0
- IMM 3
- ZERO
- LOAD 0
- LIBCALL start_sprite_sequence3
- STORE 0 // 2f35ah
- LOAD 0 // 2f35fh
- DSTORE $546E
- IMM 2 // 2f362h
- ZERO
- ZERO
- LOAD 0
- LIBCALL SequenceList_addSubEntry
- STORE 0 // 2f368h
- DLOAD $546E // 2f36dh
- STORE 0
- IMM 21
- IMM 17
- LOAD 0
- LIBCALL SequenceList_setAnimRange
- JUMP @2f6b4 // 2f37bh
-@2f37e:
- ZERO
- ZERO
- ZERO
- DLOAD $5450 // 2f384h
- STORE 0
- IMM 3
- ZERO
- LOAD 0
- LIBCALL start_cycled_sprite_sequence
- STORE 0 // 2f38ch
- LOAD 0 // 2f391h
- DSTORE $546E
- IMM 17 // 2f397h
- IMM 17
- IMM 17
- LOAD 0
- LIBCALL SequenceList_setAnimRange
- ZERO
- ZERO
- ONE
- DLOAD $544A // 2f3a4h
- STORE 0
- IMM 3
- ZERO
- LOAD 0
- LIBCALL start_cycled_sprite_sequence
- STORE 0 // 2f3ach
- LOAD 0 // 2f3b1h
- DSTORE $5468
- IMM 3 // 2f3b4h
- ZERO
- ZERO
- LOAD 0
- LIBCALL SequenceList_addSubEntry
- STORE 0 // 2f3bah
- JUMP @2f6b4 // 2f3bfh
-@2f3c2:
- MINUSONE
- DSTORE Player_stepEnabled // 2f3c5h
- MINUSONE
- GSTORE 14 // 2f3c8h
- IMM 112 // 2f3ceh
- DSTORE Scene_nextScene
- DLOAD 0 // 2f3d4h
- STORE 0
- JUMP @2f6b4
-@2f3d8:
- ZERO
- IMM 71 // 2f3dah
- IMM 3 // 2f3dch
- LIBCALL Action_isAction
- STORE 0 // 2f3deh
- LOAD 0 // 2f3e6h
- ZERO
- EQUAL
- JMPTRUE @2f3f0 // 2f3e8h
- DLOAD 0 // 2f3edh
- STORE 0
- JUMP @2f28f
-@2f3f0:
- ZERO
- IMM 3 // 2f3f2h
- LIBCALL Action_isAction
- STORE 0 // 2f3f4h
- LOAD 0 // 2f3fch
- ZERO
- NEQUAL
- JMPTRUE @2f410 // 2f3feh
- LOAD 0 // 2f400h
- IMM 259 // 2f401h
- LIBCALL Action_isAction
- STORE 0 // 2f404h
- LOAD 0 // 2f40ch
- ZERO
- EQUAL
- JMPTRUE @2f438 // 2f40eh
-@2f410:
- ZERO
- IMM 142 // 2f412h
- LIBCALL Action_isAction
- STORE 0 // 2f415h
- LOAD 0 // 2f41dh
- ZERO
- NEQUAL
- JMPTRUE @2f431 // 2f41fh
- LOAD 0 // 2f421h
- IMM 249 // 2f422h
- LIBCALL Action_isAction
- STORE 0 // 2f425h
- LOAD 0 // 2f42dh
- ZERO
- EQUAL
- JMPTRUE @2f438 // 2f42fh
-@2f431:
- DLOAD 0 // 2f434h
- STORE 0
- JUMP @2f28f
-@2f438:
- ZERO
- IMM 168 // 2f43ah
- IMM 3 // 2f43dh
- LIBCALL Action_isAction
- STORE 0 // 2f43fh
- LOAD 0 // 2f447h
- ZERO
- NEQUAL
- JMPTRUE @2f481 // 2f449h
- LOAD 0 // 2f44bh
- IMM 248 // 2f44ch
- IMM 3 // 2f44fh
- LIBCALL Action_isAction
- STORE 0 // 2f451h
- LOAD 0 // 2f459h
- ZERO
- NEQUAL
- JMPTRUE @2f481 // 2f45bh
- LOAD 0 // 2f45dh
- IMM 168 // 2f45eh
- IMM 125 // 2f461h
- LIBCALL Action_isAction
- STORE 0 // 2f463h
- LOAD 0 // 2f46bh
- ZERO
- NEQUAL
- JMPTRUE @2f481 // 2f46dh
- LOAD 0 // 2f46fh
- IMM 248 // 2f470h
- IMM 125 // 2f473h
- LIBCALL Action_isAction
- STORE 0 // 2f475h
- LOAD 0 // 2f47dh
- ZERO
- EQUAL
- JMPTRUE @2f488 // 2f47fh
-@2f481:
- DLOAD 0 // 2f484h
- STORE 0
- JUMP @2f28f
-@2f488:
- ZERO
- IMM 145 // 2f48ah
- IMM 3 // 2f48dh
- LIBCALL Action_isAction
- STORE 0 // 2f48fh
- LOAD 0 // 2f497h
- ZERO
- EQUAL
- JMPTRUE @2f4a2 // 2f499h
- DLOAD 0 // 2f49eh
- STORE 0
- JUMP @2f28f
-@2f4a2:
- ZERO
- IMM 225 // 2f4a4h
- IMM 3 // 2f4a7h
- LIBCALL Action_isAction
- STORE 0 // 2f4a9h
- LOAD 0 // 2f4b1h
- ZERO
- NEQUAL
- JMPTRUE @2f4c8 // 2f4b3h
- LOAD 0 // 2f4b5h
- IMM 225 // 2f4b6h
- IMM 210 // 2f4b9h
- LIBCALL Action_isAction
- STORE 0 // 2f4bch
- LOAD 0 // 2f4c4h
- ZERO
- EQUAL
- JMPTRUE @2f4ce // 2f4c6h
-@2f4c8:
- DLOAD 0 // 2f4cbh
- STORE 0
- JUMP @2f28f
-@2f4ce:
- ZERO
- IMM 96 // 2f4d0h
- IMM 3 // 2f4d2h
- LIBCALL Action_isAction
- STORE 0 // 2f4d4h
- LOAD 0 // 2f4dch
- ZERO
- EQUAL
- JMPTRUE @2f4e6 // 2f4deh
- DLOAD 0 // 2f4e3h
- STORE 0
- JUMP @2f28f
-@2f4e6:
- ZERO
- IMM 273 // 2f4e8h
- IMM 3 // 2f4ebh
- LIBCALL Action_isAction
- STORE 0 // 2f4edh
- LOAD 0 // 2f4f5h
- ZERO
- EQUAL
- JMPTRUE @2f500 // 2f4f7h
- DLOAD 0 // 2f4fch
- STORE 0
- JUMP @2f28f
-@2f500:
- ZERO
- IMM 123 // 2f502h
- IMM 3 // 2f504h
- LIBCALL Action_isAction
- STORE 0 // 2f506h
- LOAD 0 // 2f50eh
- ZERO
- NEQUAL
- JMPTRUE @2f52f // 2f510h
- LOAD 0 // 2f512h
- IMM 123 // 2f513h
- IMM 6 // 2f515h
- LIBCALL Action_isAction
- STORE 0 // 2f517h
- LOAD 0 // 2f51fh
- ZERO
- EQUAL
- JMPTRUE @2f536 // 2f521h
- LIBCALL object_is_in_inventory
- STORE 0 // 2f526h
- LOAD 0 // 2f52bh
- ZERO
- NEQUAL
- JMPTRUE @2f536 // 2f52dh
-@2f52f:
- DLOAD 0 // 2f532h
- STORE 0
- JUMP @2f28f
-@2f536:
- ZERO
- IMM 123 // 2f538h
- IMM 6 // 2f53ah
- LIBCALL Action_isAction
- STORE 0 // 2f53ch
- LOAD 0 // 2f544h
- ZERO
- EQUAL
- JMPTRUE @2f54e // 2f546h
- DLOAD 0 // 2f54bh
- STORE 0
- JUMP @2f28f
-@2f54e:
- ZERO
- IMM 358 // 2f550h
- IMM 3 // 2f553h
- LIBCALL Action_isAction
- STORE 0 // 2f555h
- LOAD 0 // 2f55dh
- ZERO
- EQUAL
- JMPTRUE @2f568 // 2f55fh
- DLOAD 0 // 2f564h
- STORE 0
- JUMP @2f28f
-@2f568:
- ZERO
- IMM 202 // 2f56ah
- IMM 3 // 2f56dh
- LIBCALL Action_isAction
- STORE 0 // 2f56fh
- LOAD 0 // 2f577h
- ZERO
- EQUAL
- JMPTRUE @2f582 // 2f579h
- DLOAD 0 // 2f57eh
- STORE 0
- JUMP @2f28f
-@2f582:
- ZERO
- IMM 99 // 2f584h
- IMM 3 // 2f586h
- LIBCALL Action_isAction
- STORE 0 // 2f588h
- LOAD 0 // 2f590h
- ZERO
- EQUAL
- JMPTRUE @2f59a // 2f592h
- DLOAD 0 // 2f597h
- STORE 0
- JUMP @2f28f
-@2f59a:
- ZERO
- IMM 235 // 2f59ch
- IMM 3 // 2f59fh
- LIBCALL Action_isAction
- STORE 0 // 2f5a1h
- LOAD 0 // 2f5a9h
- ZERO
- EQUAL
- JMPTRUE @2f5b4 // 2f5abh
- DLOAD 0 // 2f5b0h
- STORE 0
- JUMP @2f28f
-@2f5b4:
- ZERO
- IMM 120 // 2f5b6h
- IMM 3 // 2f5b8h
- LIBCALL Action_isAction
- STORE 0 // 2f5bah
- LOAD 0 // 2f5c2h
- ZERO
- EQUAL
- JMPTRUE @2f5cc // 2f5c4h
- DLOAD 0 // 2f5c9h
- STORE 0
- JUMP @2f28f
-@2f5cc:
- ZERO
- IMM 400 // 2f5ceh
- IMM 3 // 2f5d1h
- LIBCALL Action_isAction
- STORE 0 // 2f5d3h
- LOAD 0 // 2f5dbh
- ZERO
- EQUAL
- JMPTRUE @2f5e6 // 2f5ddh
- DLOAD 0 // 2f5e2h
- STORE 0
- JUMP @2f28f
-@2f5e6:
- ZERO
- IMM 312 // 2f5e8h
- IMM 3 // 2f5ebh
- LIBCALL Action_isAction
- STORE 0 // 2f5edh
- LOAD 0 // 2f5f5h
- ZERO
- EQUAL
- JMPTRUE @2f600 // 2f5f7h
- DLOAD 0 // 2f5fch
- STORE 0
- JUMP @2f28f
-@2f600:
- ZERO
- IMM 273 // 2f602h
- IMM 4 // 2f605h
- LIBCALL Action_isAction
- STORE 0 // 2f607h
- LOAD 0 // 2f60fh
- ZERO
- EQUAL
- JMPTRUE @2f61a // 2f611h
- DLOAD 0 // 2f616h
- STORE 0
- JUMP @2f28f
-@2f61a:
- ZERO
- IMM 145 // 2f61ch
- IMM 4 // 2f61fh
- LIBCALL Action_isAction
- STORE 0 // 2f621h
- LOAD 0 // 2f629h
- ZERO
- EQUAL
- JMPTRUE @2f634 // 2f62bh
- DLOAD 0 // 2f630h
- STORE 0
- JUMP @2f28f
-@2f634:
- ZERO
- IMM 99 // 2f636h
- IMM 6 // 2f638h
- LIBCALL Action_isAction
- STORE 0 // 2f63ah
- LOAD 0 // 2f642h
- ZERO
- EQUAL
- JMPTRUE @2f64c // 2f644h
- DLOAD 0 // 2f649h
- STORE 0
- JUMP @2f28f
-@2f64c:
- ZERO
- IMM 96 // 2f64eh
- IMM 6 // 2f650h
- LIBCALL Action_isAction
- STORE 0 // 2f652h
- LOAD 0 // 2f65ah
- ZERO
- EQUAL
- JMPTRUE @2f664 // 2f65ch
- DLOAD 0 // 2f661h
- STORE 0
- JUMP @2f28f
-@2f664:
- ZERO
- IMM 96 // 2f666h
- IMM 11 // 2f668h
- LIBCALL Action_isAction
- STORE 0 // 2f66ah
- LOAD 0 // 2f672h
- ZERO
- EQUAL
- JMPTRUE @2f67c // 2f674h
- DLOAD 0 // 2f679h
- STORE 0
- JUMP @2f28f
-@2f67c:
- ZERO
- IMM 3 // 2f67eh
- LIBCALL Action_isAction
- STORE 0 // 2f680h
- LOAD 0 // 2f688h
- ZERO
- NEQUAL
- JMPTRUE @2f69c // 2f68ah
- LOAD 0 // 2f68ch
- IMM 274 // 2f68dh
- LIBCALL Action_isAction
- STORE 0 // 2f690h
- LOAD 0 // 2f698h
- ZERO
- EQUAL
- JMPTRUE @2f6ba // 2f69ah
-@2f69c:
- ZERO
- IMM 382 // 2f69eh
- LIBCALL Action_isAction
- STORE 0 // 2f6a1h
- LOAD 0 // 2f6a9h
- ZERO
- EQUAL
- JMPTRUE @2f6ba // 2f6abh
- DLOAD 0 // 2f6b0h
- STORE 0
- JUMP @2f28f
-@2f6b4:
- ZERO
- DSTORE $5768 // 2f6b4h
-@2f6ba:
- RET
-end
diff --git a/devtools/create_project/create_project.cpp b/devtools/create_project/create_project.cpp
index 084641608a..15830bd467 100644
--- a/devtools/create_project/create_project.cpp
+++ b/devtools/create_project/create_project.cpp
@@ -105,6 +105,30 @@ struct FSNode {
};
typedef std::list<FSNode> FileList;
+
+typedef StringList TokenList;
+
+/**
+ * Takes a given input line and creates a list of tokens out of it.
+ *
+ * A token in this context is separated by whitespaces. A special case
+ * are quotation marks though. A string inside quotation marks is treated
+ * as single token, even when it contains whitespaces.
+ *
+ * Thus for example the input:
+ * foo bar "1 2 3 4" ScummVM
+ * will create a list with the following entries:
+ * "foo", "bar", "1 2 3 4", "ScummVM"
+ * As you can see the quotation marks will get *removed* too.
+ *
+ * You can also use this with non-whitespace by passing another separator
+ * character (e.g. ',').
+ *
+ * @param input The text to be tokenized.
+ * @param separator The token separator.
+ * @return A list of tokens.
+ */
+TokenList tokenize(const std::string &input, char separator = ' ');
} // End of anonymous namespace
enum ProjectType {
@@ -201,6 +225,38 @@ int main(int argc, char *argv[]) {
std::cerr << "ERROR: Unsupported version: \"" << msvcVersion << "\" passed to \"--msvc-version\"!\n";
return -1;
}
+ } else if (!strncmp(argv[i], "--enable-engine=", 16)) {
+ const char *names = &argv[i][16];
+ if (!*names) {
+ std::cerr << "ERROR: Invalid command \"" << argv[i] << "\"\n";
+ return -1;
+ }
+
+ TokenList tokens = tokenize(names, ',');
+ TokenList::const_iterator token = tokens.begin();
+ while (token != tokens.end()) {
+ std::string name = *token++;
+ if (!setEngineBuildState(name, setup.engines, true)) {
+ std::cerr << "ERROR: \"" << name << "\" is not a known engine!\n";
+ return -1;
+ }
+ }
+ } else if (!strncmp(argv[i], "--disable-engine=", 17)) {
+ const char *names = &argv[i][17];
+ if (!*names) {
+ std::cerr << "ERROR: Invalid command \"" << argv[i] << "\"\n";
+ return -1;
+ }
+
+ TokenList tokens = tokenize(names, ',');
+ TokenList::const_iterator token = tokens.begin();
+ while (token != tokens.end()) {
+ std::string name = *token++;
+ if (!setEngineBuildState(name, setup.engines, false)) {
+ std::cerr << "ERROR: \"" << name << "\" is not a known engine!\n";
+ return -1;
+ }
+ }
} else if (!strncmp(argv[i], "--enable-", 9)) {
const char *name = &argv[i][9];
if (!*name) {
@@ -211,12 +267,9 @@ int main(int argc, char *argv[]) {
if (!std::strcmp(name, "all-engines")) {
for (EngineDescList::iterator j = setup.engines.begin(); j != setup.engines.end(); ++j)
j->enable = true;
- } else if (!setEngineBuildState(name, setup.engines, true)) {
- // If none found, we'll try the features list
- if (!setFeatureBuildState(name, setup.features, true)) {
- std::cerr << "ERROR: \"" << name << "\" is neither an engine nor a feature!\n";
- return -1;
- }
+ } else if (!setFeatureBuildState(name, setup.features, true)) {
+ std::cerr << "ERROR: \"" << name << "\" is not a feature!\n";
+ return -1;
}
} else if (!strncmp(argv[i], "--disable-", 10)) {
const char *name = &argv[i][10];
@@ -228,12 +281,9 @@ int main(int argc, char *argv[]) {
if (!std::strcmp(name, "all-engines")) {
for (EngineDescList::iterator j = setup.engines.begin(); j != setup.engines.end(); ++j)
j->enable = false;
- } else if (!setEngineBuildState(name, setup.engines, false)) {
- // If none found, we'll try the features list
- if (!setFeatureBuildState(name, setup.features, false)) {
- std::cerr << "ERROR: \"" << name << "\" is neither an engine nor a feature!\n";
- return -1;
- }
+ } else if (!setFeatureBuildState(name, setup.features, false)) {
+ std::cerr << "ERROR: \"" << name << "\" is not a feature!\n";
+ return -1;
}
} else if (!std::strcmp(argv[i], "--file-prefix")) {
if (i + 1 >= argc) {
@@ -411,6 +461,12 @@ int main(int argc, char *argv[]) {
// 4310 (cast truncates constant value)
// used in some engines
//
+ // 4345 (behavior change: an object of POD type constructed with an
+ // initializer of the form () will be default-initialized)
+ // used in Common::Array(), and it basically means that newer VS
+ // versions adhere to the standard in this case. Can be safely
+ // disabled.
+ //
// 4351 (new behavior: elements of array 'array' will be default initialized)
// a change in behavior in Visual Studio 2005. We want the new behavior, so it can be disabled
//
@@ -460,6 +516,7 @@ int main(int argc, char *argv[]) {
globalWarnings.push_back("4244");
globalWarnings.push_back("4250");
globalWarnings.push_back("4310");
+ globalWarnings.push_back("4345");
globalWarnings.push_back("4351");
globalWarnings.push_back("4512");
globalWarnings.push_back("4702");
@@ -476,10 +533,14 @@ int main(int argc, char *argv[]) {
projectWarnings["agos"].push_back("4511");
+ projectWarnings["dreamweb"].push_back("4355");
+
projectWarnings["lure"].push_back("4189");
projectWarnings["lure"].push_back("4355");
projectWarnings["kyra"].push_back("4355");
+ projectWarnings["kyra"].push_back("4510");
+ projectWarnings["kyra"].push_back("4610");
projectWarnings["m4"].push_back("4355");
@@ -611,26 +672,6 @@ void displayHelp(const char *exe) {
cout.setf(std::ios_base::right, std::ios_base::adjustfield);
}
-typedef StringList TokenList;
-
-/**
- * Takes a given input line and creates a list of tokens out of it.
- *
- * A token in this context is separated by whitespaces. A special case
- * are quotation marks though. A string inside quotation marks is treated
- * as single token, even when it contains whitespaces.
- *
- * Thus for example the input:
- * foo bar "1 2 3 4" ScummVM
- * will create a list with the following entries:
- * "foo", "bar", "1 2 3 4", "ScummVM"
- * As you can see the quotation marks will get *removed* too.
- *
- * @param input The text to be tokenized.
- * @return A list of tokens.
- */
-TokenList tokenize(const std::string &input);
-
/**
* Try to parse a given line and create an engine definition
* out of the result.
@@ -760,7 +801,7 @@ bool parseEngine(const std::string &line, EngineDesc &engine) {
return true;
}
-TokenList tokenize(const std::string &input) {
+TokenList tokenize(const std::string &input, char separator) {
TokenList result;
std::string::size_type sIdx = input.find_first_not_of(" \t");
@@ -774,12 +815,15 @@ TokenList tokenize(const std::string &input) {
++sIdx;
nIdx = input.find_first_of('\"', sIdx);
} else {
- nIdx = input.find_first_of(' ', sIdx);
+ nIdx = input.find_first_of(separator, sIdx);
}
if (nIdx != std::string::npos) {
result.push_back(input.substr(sIdx, nIdx - sIdx));
- sIdx = input.find_first_not_of(" \t", nIdx + 1);
+ if (separator == ' ')
+ sIdx = input.find_first_not_of(" \t", nIdx + 1);
+ else
+ sIdx = input.find_first_not_of(separator, nIdx + 1);
} else {
result.push_back(input.substr(sIdx));
break;
@@ -811,6 +855,7 @@ const Feature s_features[] = {
{ "taskbar", "USE_TASKBAR", "", true, "Taskbar integration support" },
{ "translation", "USE_TRANSLATION", "", true, "Translation support" },
{ "vkeybd", "ENABLE_VKEYBD", "", false, "Virtual keyboard support"},
+ { "keymapper","ENABLE_KEYMAPPER", "", false, "Keymapper support"},
{ "langdetect", "USE_DETECTLANG", "", true, "System language detection support" } // This feature actually depends on "translation", there
// is just no current way of properly detecting this...
};
@@ -820,7 +865,6 @@ const Tool s_tools[] = {
{ "create_hugo", true},
{ "create_kyradat", true},
{ "create_lure", true},
- { "create_mads", true},
{ "create_teenagent", true},
{ "create_toon", true},
{ "create_translations", true},
@@ -1301,6 +1345,8 @@ void ProjectProvider::createModuleList(const std::string &moduleDir, const Strin
std::stack<bool> shouldInclude;
shouldInclude.push(true);
+ StringList filesInVariableList;
+
bool hadModule = false;
std::string line;
for (;;) {
@@ -1354,6 +1400,30 @@ void ProjectProvider::createModuleList(const std::string &moduleDir, const Strin
std::getline(moduleMk, line);
tokens = tokenize(line);
i = tokens.begin();
+ } else if (*i == "$(KYRARPG_COMMON_OBJ)") {
+ // HACK to fix EOB/LOL compilation in the kyra engine:
+ // replace the variable name with the stored files.
+ // This assumes that the file list has already been defined.
+ if (filesInVariableList.size() == 0)
+ error("$(KYRARPG_COMMON_OBJ) found, but the variable hasn't been set before it");
+ // Construct file list and replace the variable
+ for (StringList::iterator j = filesInVariableList.begin(); j != filesInVariableList.end(); ++j) {
+ const std::string filename = *j;
+
+ if (shouldInclude.top()) {
+ // In case we should include a file, we need to make
+ // sure it is not in the exclude list already. If it
+ // is we just drop it from the exclude list.
+ excludeList.remove(filename);
+
+ includeList.push_back(filename);
+ } else if (std::find(includeList.begin(), includeList.end(), filename) == includeList.end()) {
+ // We only add the file to the exclude list in case it
+ // has not yet been added to the include list.
+ excludeList.push_back(filename);
+ }
+ }
+ ++i;
} else {
const std::string filename = moduleDir + "/" + unifyPath(*i);
@@ -1372,6 +1442,29 @@ void ProjectProvider::createModuleList(const std::string &moduleDir, const Strin
++i;
}
}
+ } else if (*i == "KYRARPG_COMMON_OBJ") {
+ // HACK to fix EOB/LOL compilation in the kyra engine: add the
+ // files defined in the KYRARPG_COMMON_OBJ variable in a list
+ if (tokens.size() < 3)
+ error("Malformed KYRARPG_COMMON_OBJ definition in " + moduleMkFile);
+ ++i;
+
+ if (*i != ":=" && *i != "+=" && *i != "=")
+ error("Malformed KYRARPG_COMMON_OBJ definition in " + moduleMkFile);
+
+ ++i;
+
+ while (i != tokens.end()) {
+ if (*i == "\\") {
+ std::getline(moduleMk, line);
+ tokens = tokenize(line);
+ i = tokens.begin();
+ } else {
+ const std::string filename = moduleDir + "/" + unifyPath(*i);
+ filesInVariableList.push_back(filename);
+ ++i;
+ }
+ }
} else if (*i == "ifdef") {
if (tokens.size() < 2)
error("Malformed ifdef in " + moduleMkFile);
diff --git a/devtools/create_project/create_project.h b/devtools/create_project/create_project.h
index 55e04be4ec..8719143f4a 100644
--- a/devtools/create_project/create_project.h
+++ b/devtools/create_project/create_project.h
@@ -371,7 +371,7 @@ protected:
*
* @param output File stream to write to.
*/
- virtual void writeReferences(const BuildSetup &, std::ofstream &) {};
+ virtual void writeReferences(const BuildSetup &, std::ofstream &) {}
/**
* Get the file extension for project files
diff --git a/devtools/create_project/xcode.cpp b/devtools/create_project/xcode.cpp
index 77ac88f85d..eb51ab3da1 100755
--- a/devtools/create_project/xcode.cpp
+++ b/devtools/create_project/xcode.cpp
@@ -448,7 +448,6 @@ void XCodeProvider::setupResourcesBuildPhase() {
properties["sky.cpt"] = FileProperty("file", "", "sky.cpt", "\"<group>\"");
properties["drascula.dat"] = FileProperty("file", "", "drascula.dat", "\"<group>\"");
properties["hugo.dat"] = FileProperty("file", "", "hugo.dat", "\"<group>\"");
- properties["m4.dat"] = FileProperty("file", "", "m4.dat", "\"<group>\"");
properties["teenagent.dat"] = FileProperty("file", "", "teenagent.dat", "\"<group>\"");
properties["toon.dat"] = FileProperty("file", "", "toon.dat", "\"<group>\"");
@@ -481,7 +480,6 @@ void XCodeProvider::setupResourcesBuildPhase() {
files_list.push_back("icon4.png");
files_list.push_back("drascula.dat");
files_list.push_back("hugo.dat");
- files_list.push_back("m4.dat");
files_list.push_back("teenagent.dat");
files_list.push_back("toon.dat");
diff --git a/devtools/create_translations/cp_parser.cpp b/devtools/create_translations/cp_parser.cpp
new file mode 100644
index 0000000000..a4202bf153
--- /dev/null
+++ b/devtools/create_translations/cp_parser.cpp
@@ -0,0 +1,104 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * This is a utility for create the translations.dat file from all the po files.
+ * The generated files is used by ScummVM to propose translation of its GUI.
+ */
+
+#include "cp_parser.h"
+
+#include <fstream>
+#include <stdio.h>
+
+Codepage::Codepage(const std::string &name, const uint32 *mapping) : _name(name) {
+ if (!mapping) {
+ // Default to a ISO-8859-1 mapping
+ for (unsigned int i = 0; i < 256; ++i)
+ _mapping[i] = i;
+ } else {
+ for (unsigned int i = 0; i < 256; ++i)
+ _mapping[i] = *mapping++;
+ }
+}
+
+Codepage *parseCodepageMapping(const std::string &filename) {
+ size_t start = filename.find_last_of("/\\");
+ if (start == std::string::npos)
+ start = 0;
+ // Strip off the filename extension
+ const size_t pos = filename.find_last_of('.');
+ const std::string charset(filename.substr(start + 1, pos != std::string::npos ? (pos - start - 1) : std::string::npos));
+
+ std::ifstream in(filename.c_str());
+ if (!in) {
+ fprintf(stderr, "ERROR: Could not open file \"%s\"!", filename.c_str());
+ return 0;
+ }
+
+ uint32 mapping[256];
+
+ int processedMappings = 0;
+ std::string line;
+ while (processedMappings < 256) {
+ std::getline(in, line);
+ if (in.eof())
+ break;
+ if (in.fail()) {
+ fprintf(stderr, "ERROR: Reading from file \"%s\" failed!", filename.c_str());
+ return 0;
+ }
+
+ // In case the line starts with a "#" it is a comment. We also ignore
+ // empty lines.
+ if (line.empty() || line[0] == '#')
+ continue;
+
+ // Read the unicode number, we thereby ignore everything else on the line
+ int unicode, required;
+ const int parsed = sscanf(line.c_str(), "%d %d", &unicode, &required);
+ if (parsed < 1 || parsed > 2) {
+ fprintf(stderr, "ERROR: Line \"%s\" is malformed!", filename.c_str());
+ return 0;
+ }
+ // In case no required integer was given, we assume the character is
+ // required
+ if (parsed == 1)
+ required = 1;
+
+ // -1 means default mapping
+ if (unicode == -1)
+ unicode = processedMappings;
+
+ uint32 unicodeValue = unicode;
+ if (required)
+ unicodeValue |= 0x80000000;
+
+ mapping[processedMappings++] = (uint32)unicodeValue;
+ }
+
+ // Check whether all character encodings are mapped, if not error out
+ if (processedMappings != 256) {
+ fprintf(stderr, "ERROR: File \"%s\" does not contain mappings for exactly 256 characters!", filename.c_str());
+ return 0;
+ }
+
+ // Return the codepage
+ return new Codepage(charset, mapping);
+}
diff --git a/devtools/create_translations/cp_parser.h b/devtools/create_translations/cp_parser.h
new file mode 100644
index 0000000000..b748430ca0
--- /dev/null
+++ b/devtools/create_translations/cp_parser.h
@@ -0,0 +1,54 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * This is a utility for create the translations.dat file from all the po files.
+ * The generated files is used by ScummVM to propose translation of its GUI.
+ */
+
+#ifndef CP_PARSER_H
+#define CP_PARSER_H
+
+#include "create_translations.h"
+
+#include <string>
+
+/**
+ * Codepage description.
+ *
+ * This includes a name, and the codepage -> unicode mapping.
+ */
+class Codepage {
+public:
+ Codepage(const std::string &name, const uint32 *mapping);
+
+ const std::string &getName() const { return _name; }
+
+ uint32 getMapping(unsigned char src) const { return _mapping[src]; }
+private:
+ std::string _name;
+ uint32 _mapping[256];
+};
+
+/**
+ * Parse the codepage file and create a codepage.
+ */
+Codepage *parseCodepageMapping(const std::string &filename);
+
+#endif
diff --git a/devtools/create_translations/create_translations.cpp b/devtools/create_translations/create_translations.cpp
index 9fcf3b4a31..a153632c47 100644
--- a/devtools/create_translations/create_translations.cpp
+++ b/devtools/create_translations/create_translations.cpp
@@ -25,6 +25,8 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <ctype.h>
+#include <vector>
// HACK to allow building with the SDL backend on MinGW
// see bug #1800764 "TOOLS: MinGW tools building broken"
@@ -34,8 +36,23 @@
#include "create_translations.h"
#include "po_parser.h"
+#include "cp_parser.h"
-#define TRANSLATIONS_DAT_VER 2 // 1 byte
+#define TRANSLATIONS_DAT_VER 3 // 1 byte
+
+// Portable implementation of stricmp / strcasecmp / strcmpi.
+int scumm_stricmp(const char *s1, const char *s2) {
+ uint8 l1, l2;
+ do {
+ // Don't use ++ inside tolower, in case the macro uses its
+ // arguments more than once.
+ l1 = (uint8)*s1++;
+ l1 = tolower(l1);
+ l2 = (uint8)*s2++;
+ l2 = tolower(l2);
+ } while (l1 == l2 && l1 != 0);
+ return l1 - l2;
+}
// Padding buffer (filled with 0) used if we want to aligned writes
// static uint8 padBuf[DATAALIGNMENT];
@@ -52,6 +69,13 @@ void writeUint16BE(FILE *fp, uint16 value) {
writeByte(fp, (uint8)(value & 0xFF));
}
+void writeUint32BE(FILE *fp, uint32 value) {
+ writeByte(fp, (uint8)(value >> 24));
+ writeByte(fp, (uint8)(value >> 16));
+ writeByte(fp, (uint8)(value >> 8));
+ writeByte(fp, (uint8)(value & 0xFF));
+}
+
int stringSize(const char *string) {
// Each string is preceded by its size coded on 2 bytes
if (string == NULL)
@@ -82,14 +106,51 @@ void writeString(FILE *fp, const char *string) {
// Main
int main(int argc, char *argv[]) {
- // Build the translation list
+ std::vector<Codepage *> codepages;
+ // Add default codepages, we won't store them in the output later on
+ codepages.push_back(new Codepage("ascii", 0));
+ codepages.push_back(new Codepage("iso-8859-1", 0));
+
+ // Build the translation and codepage list
PoMessageList messageIds;
- PoMessageEntryList **translations = new PoMessageEntryList*[argc - 1];
+ std::vector<PoMessageEntryList *> translations;
int numLangs = 0;
for (int i = 1; i < argc; ++i) {
- translations[numLangs] = parsePoFile(argv[i], messageIds);
- if (translations[numLangs] != NULL)
- ++numLangs;
+ // Check file extension
+ int len = strlen(argv[i]);
+ if (scumm_stricmp(argv[i] + len - 2, "po") == 0) {
+ PoMessageEntryList *po = parsePoFile(argv[i], messageIds);
+ if (po != NULL) {
+ translations.push_back(po);
+ ++numLangs;
+ }
+ } else if (scumm_stricmp(argv[i] + len - 2, "cp") == 0) {
+ // Else try to parse an codepage
+ Codepage *co = parseCodepageMapping(argv[i]);
+ if (co)
+ codepages.push_back(co);
+ }
+ }
+
+ // Parse all charset mappings
+ for (int i = 0; i < numLangs; ++i) {
+ bool found = false;
+ for (size_t j = 0; j < codepages.size(); ++j) {
+ if (scumm_stricmp(codepages[j]->getName().c_str(), translations[i]->charset()) == 0) {
+ found = true;
+ break;
+ }
+ }
+
+ // In case the codepage was not found error out
+ if (!found) {
+ fprintf(stderr, "ERROR: No codepage mapping for codepage \"%s\" present!\n", translations[i]->charset());
+ for (size_t j = 0; j < translations.size(); ++j)
+ delete translations[j];
+ for (size_t j = 0; j < codepages.size(); ++j)
+ delete codepages[j];
+ return -1;
+ }
}
FILE *outFile;
@@ -110,6 +171,8 @@ int main(int argc, char *argv[]) {
// Write number of translations
writeUint16BE(outFile, numLangs);
+ // Write number of codepages, we don't save ascii and iso-8859-1
+ writeUint16BE(outFile, codepages.size() - 2);
// Write the length of each data block here.
// We could write it at the start of each block but that would mean that
@@ -119,9 +182,14 @@ int main(int argc, char *argv[]) {
// file and can then skip to the block we want.
// Blocks are:
// 1. List of languages with the language name
- // 2. Original messages (i.e. english)
- // 3. First translation
- // 4. Second translation
+ // 2. List of codepages
+ // 3. Original messages (i.e. english)
+ // 4. First translation
+ // 5. Second translation
+ // ...
+ // n. First codepage (These don't have any data size, since they are all
+ // 256 * 4 bytes long)
+ // n+1. Second codepage
// ...
// Write length for translation description
@@ -132,6 +200,12 @@ int main(int argc, char *argv[]) {
}
writeUint16BE(outFile, len);
+ // Write length for the codepage names
+ len = 0;
+ for (size_t j = 2; j < codepages.size(); ++j)
+ len += stringSize(codepages[j]->getName().c_str());
+ writeUint16BE(outFile, len);
+
// Write size for the original language (english) block
// It starts with the number of strings coded on 2 bytes followed by each
// string (two bytes for the number of chars and the string itself).
@@ -159,6 +233,11 @@ int main(int argc, char *argv[]) {
writeString(outFile, translations[lang]->languageName());
}
+ // Write list of codepages
+ for (size_t j = 2; j < codepages.size(); ++j) {
+ writeString(outFile, codepages[j]->getName().c_str());
+ }
+
// Write original messages
writeUint16BE(outFile, messageIds.size());
for (i = 0; i < messageIds.size(); ++i) {
@@ -176,12 +255,18 @@ int main(int argc, char *argv[]) {
}
}
+ // Write codepages
+ for (size_t j = 2; j < codepages.size(); ++j) {
+ const Codepage *cp = codepages[j];
+ for (i = 0; i < 256; ++i)
+ writeUint32BE(outFile, cp->getMapping(i));
+ }
+
fclose(outFile);
// Clean the memory
for (i = 0; i < numLangs; ++i)
delete translations[i];
- delete[] translations;
return 0;
}
diff --git a/devtools/create_translations/create_translations.h b/devtools/create_translations/create_translations.h
index 0ece8102f0..9ccbd39b2b 100644
--- a/devtools/create_translations/create_translations.h
+++ b/devtools/create_translations/create_translations.h
@@ -25,6 +25,7 @@
typedef unsigned char uint8;
typedef unsigned short uint16;
+typedef unsigned int uint32;
typedef signed short int16;
#endif /* CREATE_TRANSLATIONS_H */
diff --git a/devtools/create_translations/module.mk b/devtools/create_translations/module.mk
index 430cf91976..9a2b302aef 100644
--- a/devtools/create_translations/module.mk
+++ b/devtools/create_translations/module.mk
@@ -1,6 +1,7 @@
MODULE := devtools/create_translations
MODULE_OBJS := \
+ cp_parser.o \
po_parser.o \
create_translations.o
diff --git a/devtools/credits.pl b/devtools/credits.pl
index 5daf232b2b..8330450984 100755
--- a/devtools/credits.pl
+++ b/devtools/credits.pl
@@ -484,7 +484,7 @@ begin_credits("Credits");
add_person("Max Horn", "Fingolfin", "(retired)");
add_person("Travis Howell", "Kirben", "");
add_person("Pawe&#322; Ko&#322;odziejski", "aquadran", "Codecs, iMUSE, Smush, etc.");
- add_person("Gregory Montoir", "cyx", "");
+ add_person("Gregory Montoir", "cyx", "(retired)");
add_person("Eugene Sandulenko", "sev", "FT INSANE, MM NES, MM C64, game detection, Herc/CGA");
add_person("Ludvig Strigeus", "ludde", "(retired)");
end_section();
@@ -492,7 +492,7 @@ begin_credits("Credits");
begin_section("HE");
add_person("Jonathan Gray", "khalek", "(retired)");
add_person("Travis Howell", "Kirben", "");
- add_person("Gregory Montoir", "cyx", "");
+ add_person("Gregory Montoir", "cyx", "(retired)");
add_person("Eugene Sandulenko", "sev", "");
end_section();
@@ -523,11 +523,15 @@ begin_credits("Credits");
begin_section("Cine");
add_person("Vincent Hamm", "yaz0r", "(retired)");
add_person("Pawe&#322; Ko&#322;odziejski", "aquadran", "");
- add_person("Gregory Montoir", "cyx", "");
+ add_person("Gregory Montoir", "cyx", "(retired)");
add_person("Kari Salminen", "Buddha^", "");
add_person("Eugene Sandulenko", "sev", "");
end_section();
+ begin_section("Composer");
+ add_person("Alyssa Milburn", "fuzzie", "");
+ end_section();
+
begin_section("CruisE");
add_person("Paul Gilbert", "dreammaster", "");
add_person("Vincent Hamm", "yaz0r", "(retired)");
@@ -546,7 +550,7 @@ begin_credits("Credits");
begin_section("DreamWeb");
add_person("Torbj&ouml;rn Andersson", "eriktorbjorn", "");
add_person("Bertrand Augereau", "Tramb", "");
- add_person("Vladimir Menshakov", "whoozle", "");
+ add_person("Vladimir Menshakov", "whoozle", "(retired)");
end_section();
begin_section("Gob");
@@ -572,7 +576,7 @@ begin_credits("Credits");
add_person("Torbj&ouml;rn Andersson", "eriktorbjorn", "VQA Player");
add_person("Oystein Eftevaag", "vinterstum", "");
add_person("Florian Kagerer", "athrxx", "");
- add_person("Gregory Montoir", "cyx", "");
+ add_person("Gregory Montoir", "cyx", "(retired)");
add_person("Johannes Schickel", "LordHoto", "");
end_section();
@@ -586,13 +590,6 @@ begin_credits("Credits");
add_person("Paul Gilbert", "dreammaster", "");
end_section();
- begin_section("M4");
- add_person("Torbj&ouml;rn Andersson", "eriktorbjorn", "");
- add_person("Paul Gilbert", "dreammaster", "");
- add_person("Benjamin Haisch", "john_doe", "");
- add_person("Filippos Karapetis", "[md5]", "");
- end_section();
-
begin_section("MADE");
add_person("Benjamin Haisch", "john_doe", "");
add_person("Filippos Karapetis", "[md5]", "");
@@ -613,12 +610,13 @@ begin_credits("Credits");
begin_section("Queen");
add_person("David Eriksson", "twogood", "(retired)");
- add_person("Gregory Montoir", "cyx", "");
+ add_person("Gregory Montoir", "cyx", "(retired)");
add_person("Joost Peters", "joostp", "");
end_section();
begin_section("SAGA");
add_person("Torbj&ouml;rn Andersson", "eriktorbjorn", "");
+ add_person("Daniel Balsom", "DanielFox", "Original engine reimplementation author (retired)");
add_person("Filippos Karapetis", "[md5]", "");
add_person("Andrew Kurushin", "ajax16384", "");
add_person("Eugene Sandulenko", "sev", "");
@@ -664,7 +662,7 @@ begin_credits("Credits");
begin_section("TeenAgent");
add_person("Robert Megone", "sanguine", "Help with callback rewriting");
- add_person("Vladimir Menshakov", "whoozle", "");
+ add_person("Vladimir Menshakov", "whoozle", "(retired)");
end_section();
begin_section("Tinsel");
@@ -682,7 +680,7 @@ begin_credits("Credits");
end_section();
begin_section("Touch&eacute;");
- add_person("Gregory Montoir", "cyx", "");
+ add_person("Gregory Montoir", "cyx", "(retired)");
end_section();
begin_section("TsAGE");
@@ -691,7 +689,7 @@ begin_credits("Credits");
end_section();
begin_section("Tucker");
- add_person("Gregory Montoir", "cyx", "");
+ add_person("Gregory Montoir", "cyx", "(retired)");
end_section();
end_section();
@@ -1003,6 +1001,7 @@ begin_credits("Credits");
add_person("Edward Rudd", "urkle", "Fixes for playing MP3 versions of MI1/Loom audio");
add_person("Daniel Schepler", "dschepler", "Final MI1 CD music support, initial Ogg Vorbis support");
add_person("Andr&eacute; Souza", "luke_br", "SDL-based OpenGL renderer");
+ add_person("Tom Frost", "TomFrost", "WebOS port contributions");
end_persons();
end_section();
@@ -1061,6 +1060,7 @@ begin_credits("Credits");
begin_section("Special thanks to");
begin_persons();
+ add_person("Daniel Balsom", "DanielFox", "For the original Reinherit (SAGA) code");
add_person("Sander Buskens", "", "For his work on the initial reversing of Monkey2");
add_person("", "Canadacow", "For the original MT-32 emulator");
add_person("Kevin Carnes", "", "For Scumm16, the basis of ScummVM's older gfx codecs");
@@ -1079,6 +1079,8 @@ begin_credits("Credits");
add_person("James Woodcock", "", "Soundtrack enhancements");
end_persons();
+ add_paragraph("Some icons by Yusuke Kamiyamane");
+
add_paragraph(
"Tony Warriner and everyone at Revolution Software Ltd. for sharing ".
"with us the source of some of their brilliant games, allowing us to ".
diff --git a/devtools/md5table.c b/devtools/md5table.c
index 9e57edbc35..cb1434c90b 100644
--- a/devtools/md5table.c
+++ b/devtools/md5table.c
@@ -81,6 +81,7 @@ static const StringMap platformMap[] = {
{ "C64", "kPlatformC64" },
{ "DOS", "kPlatformPC" },
{ "FM-TOWNS", "kPlatformFMTowns" },
+ { "iOS", "kPlatformIOS" },
{ "Mac", "kPlatformMacintosh" },
{ "NES", "kPlatformNES" },
{ "PC-Engine", "kPlatformPCEngine" },
diff --git a/devtools/module.mk b/devtools/module.mk
index 1ff5ba6da9..95eca50d18 100644
--- a/devtools/module.mk
+++ b/devtools/module.mk
@@ -32,9 +32,9 @@ clean-devtools:
# Build rules for the devtools
#
-devtools/convbdf$(EXEEXT): $(srcdir)/devtools/convbdf.c
+devtools/convbdf$(EXEEXT): $(srcdir)/devtools/convbdf.cpp
$(QUIET)$(MKDIR) devtools/$(DEPDIR)
- $(QUIET_LINK)$(LD) $(CFLAGS) -Wall -o $@ $<
+ $(QUIET_LINK)$(LD) $(CXXFLAGS) -Wall -o $@ $<
devtools/md5table$(EXEEXT): $(srcdir)/devtools/md5table.c
$(QUIET)$(MKDIR) devtools/$(DEPDIR)
diff --git a/devtools/sci/musicplayer.cpp b/devtools/sci/musicplayer.cpp
index d225195f71..25f2d684a8 100644
--- a/devtools/sci/musicplayer.cpp
+++ b/devtools/sci/musicplayer.cpp
@@ -90,7 +90,7 @@ int main(int argc, char** argv) {
return 2;
}
sfx_song_set_status(&sound, DUMMY_SOUND_HANDLE, SOUND_STATUS_PLAYING);
- while (sfx_poll(&sound, &dummy1, &dummy2) != SI_FINISHED) {};
+ while (sfx_poll(&sound, &dummy1, &dummy2) != SI_FINISHED) {}
}
sfx_exit(&sound);
scir_free_resource_manager(resmgr);
diff --git a/devtools/scumm-md5.txt b/devtools/scumm-md5.txt
index 53e3f38a2c..e48e99a698 100644
--- a/devtools/scumm-md5.txt
+++ b/devtools/scumm-md5.txt
@@ -235,11 +235,15 @@ monkey The Secret of Monkey Island
pass Passport to Adventure
e6cd81b25ab1453a8a6d3482118c391e 7857 en DOS - - v1.0 9/14/90 Fingolfin
-zak Misc FM-TOWNS demos
+indyloom Indiana Jones and the Last Crusade & Loom non-interactive demo
2d388339d6050d8ccaa757b64633954e 7520 en FM-TOWNS FM-TOWNS Demo indy/loom (non-interactive) khalek
- 77f5c9cc0986eb729c1a6b4c8823bbae 7520 en FM-TOWNS FM-TOWNS Demo zak/loom (non-interactive) khalek, Fingolfin
+
+indyzak Indiana Jones and the Last Crusade & Zak McKracken non-interactive demo
3938ee1aa4433fca9d9308c9891172b1 7520 en FM-TOWNS FM-TOWNS Demo indy/zak (non-interactive) khalek
+zakloom Zak McKracken & Loom non-interactive demo
+ 77f5c9cc0986eb729c1a6b4c8823bbae 7520 en FM-TOWNS FM-TOWNS Demo zak/loom (non-interactive) khalek, Fingolfin
+
monkey2 Monkey Island 2: LeChuck's Revenge
132bff65e6367c09cc69318ce1b59333 11155 en Amiga - - v1.0 4/8/92 Fingolfin
c30ef068add4277104243c31ce46c12b -1 fr Amiga - - - Andreas Bylund
@@ -513,7 +517,7 @@ freddi2 Freddi Fish 2: The Case of the Haunted Schoolhouse
8ee63cafb1fe9d62aa0d5a23117e70e7 -1 us All HE 100 Updated - Kirben
e41de1c2a15abbcdbf9977e2d7e8a340 -1 ru Windows HE 100 Updated - sev
- c20848f53c2d48bfacdc840993843765 -1 nl Windows HE 80 Demo - DarthBo
+ c20848f53c2d48bfacdc840993843765 -1 nl All HE 80 Demo - DarthBo
fc8d197a22146e74766e9cb0cfcaf1da 27298 en All HE 80 Demo - khalek, sev
d37c55388294b66e53e7ced3af88fa68 -1 en All HE 100 Updated Demo - khalek
@@ -526,10 +530,11 @@ freddi3 Freddi Fish 3: The Case of the Stolen Conch Shell
78c07ca088526d8d4446a4c2cb501203 -1 fr All HE 99 - - alamaz, gist974
83cedbe26aa8b58988e984e3d34cac8e -1 de All HE 99 - - Joachim Eberhard
75bff95816b84672b877d22a911ab811 -1 ru Windows HE 99 Updated - sev
+ 0ddf1174d0d097956ba10dd452ea65e6 -1 he Windows HE 99 - - Matan Bareket
cb1559e8405d17a5a278a6b5ad9338d1 22718 en All - Demo - khalek, sev
bbadf7309c4a2c2763e4bbba3c3be634 -1 fr All - Demo - Kirben
- 754feb59d3bf86b8a00840df74fd7b26 -1 nl Windows - Demo - adutchguy
+ 754feb59d3bf86b8a00840df74fd7b26 -1 nl All - Demo - adutchguy
ed2b074bc3166087a747acb2a3c6abb0 -1 de All HE 98.5 Demo - Joachim Eberhard
d73c851b942af44deb9b6d5f416a0972 -1 he Windows HE 99 Demo - Ori Avtalion
@@ -550,7 +555,7 @@ freddi4 Freddi Fish 4: The Case of the Hogfish Rustlers of Briny Gulch
ebd324dcf06a4c49e1ba5c231eee1060 -1 us All HE 99 Demo - sev
688328c5bdc4c8ec4145688dfa077bf2 -1 de All HE 99 Demo - Joachim Eberhard
03d3b18ee3fd68114e2a687c871e38d5 -1 us Windows HE 99 Mini Game - eriktorbjorn
- 16effd200aa6b8abe9c569c3e578814d -1 nl Windows HE 99 Demo - joostp
+ 16effd200aa6b8abe9c569c3e578814d -1 nl All HE 99 Demo - joostp
499c958affc394f2a3868f1eb568c3ee -1 nl Windows HE 99 Demo - adutchguy
5fdb2ac2483908b065c6e77988338a54 -1 nl Windows HE 99 Demo - Ben
e03ed1474ec14de78359970e0457a820 -1 gb Windows HE 99 Demo - eriktorbjorn
@@ -581,6 +586,7 @@ water Freddi Fish and Luther's Water Worries
FreddisFunShop Freddi Fish's One-Stop Fun Shop
16542a7342a918bfe4ba512007d36c47 -1 us All HE 99L - - Kirben
+ 4d3fbc888de4e6565013f61dc83da6b6 36245 nl All HE 99 - - Ben Castricum
catalog Humongous Interactive Catalog
11e6e244078ff09b0f3832e35420e0a7 -1 en Windows - Demo - khalek, sev
@@ -632,7 +638,7 @@ pajama Pajama Sam 1: No Need to Hide When It's Dark Outside
f237bf8a5ef9af78b2a6a4f3901da341 18354 en All - Demo - khalek, sev
7f945525abcd48015adf1632637a44a1 -1 fr All - Demo - Kirben
- 0305e850382b812fec6e5998ef88a966 -1 nl Windows - Demo - adutchguy
+ 0305e850382b812fec6e5998ef88a966 -1 nl All - Demo - adutchguy
87df3e0074624040407764b7c5e710b9 18354 nl Windows - Demo - George Kormendi
d7ab7cd6105546016e6a0d46fb36b964 -1 en All HE 100 Demo - khalek
@@ -645,6 +651,7 @@ pajama2 Pajama Sam 2: Thunder and Lightning Aren't so Frightening
c6907d44f1166941d982864cd42cdc89 -1 de All HE 99 - - nachbarnebenan
f8be685007a8b425ba2a455da732f59f -1 fr Mac HE 99 - - alamaz
32709cbeeb3044b34129950860a83f14 -1 ru Windows HE 99 - - sev
+ 1af4eb581a33d808707d66d50e084dca -1 he Windows HE 99 - - Matan Bareket
36a6750e03fb505fc19fc2bf3e4dbe91 58749 en All - Demo - sev
30ba1e825d4ad2b448143ae8df18482a -1 nl All HE 98.5 Demo - Kirben
@@ -729,6 +736,7 @@ puttcircus Putt-Putt Joins the Circus
db74136c20557eca6ed3411bff39f7a1 -1 gb Windows - - - Reckless
d0ad929def3e9cfe39dea55bd12098d4 -1 fr Windows - - - gist974
febf4a983ea5faea1c9dd6c710ebb09c -1 de Windows - - - andy482
+ c8253da0f4626d2236b5291b99e33408 -1 he Windows HE 99 - - Matan Bareket
a7cacad9c40c4dc9e1812abf6c8af9d5 -1 en All - Demo - Kirben, sev
1387d16aa620dc1c2d1fd87f8a9e7a09 -1 fr Windows - Demo - Mevi
@@ -759,6 +767,7 @@ puttzoo Putt-Putt Saves the Zoo
92e7727e67f5cd979d8a1070e4eb8cb3 -1 en All HE 98.5 Updated - cyx
3a3e592b074f595489f7f11e150c398d -1 us Windows HE 99 Updated - Adrian
c5cc7cba02a2fbd539c4439e775b0536 43470 de Windows HE 99 Updated - Lightkey
+ 5c9cecbd2952ccec14c9ecebf5822a34 -1 en iOS HE 100 - - clone2727
3486ede0f904789267d4bcc5537a46d4 14337 en Mac - Demo - khalek
d220d154aafbfa12bd6f3ab1b2dae420 -1 de Mac - Demo - Joachim Eberhard
@@ -783,7 +792,7 @@ PuttTime Putt-Putt Travels Through Time
4e5867848ee61bc30d157e2c94eee9b4 18394 us All HE 90 Demo - khalek, sev
59d5cfcc5e672a6e07baae01328b918b -1 fr All HE 90 Demo - Kirben
fbb697d89d2beca87360a145f467bdae -1 de All HE 90 Demo - Joachim Eberhard
- 6b19d0e25cbf720d05822379b8b90ed9 -1 nl Windows HE 90 Demo - adutchguy
+ 6b19d0e25cbf720d05822379b8b90ed9 -1 nl All HE 90 Demo - adutchguy
0a6d7b81b850ed4a77811c60c9b5c555 -1 us Windows HE 99 Mini Game - eriktorbjorn
0ab19be9e2a3f6938226638b2a3744fe -1 us All HE 100 Demo - khalek
@@ -798,6 +807,7 @@ balloon Putt-Putt and Pep's Balloon-O-Rama
dog Putt-Putt and Pep's Dog on a Stick
bd5fd7835335dfce03064d5f77b7f0ae 19681 nl Windows - - - George Kormendi
+ 1b720def35ecfa07032ddf1efb34c368 19681 nl All - - - Ben Castricum
eae95b2b3546d8ba86ae1d397c383253 -1 en All - - - Kirben
839a658f7d22de00787ebc945348cdb6 19681 de Windows - - - George Kormendi
d4b8ee426b1afd3e53bc0cf020418cf6 -1 en Windows HE 99 - - sev
@@ -834,7 +844,8 @@ spyfox SPY Fox 1: Dry Cereal
fbdd947d21e8f5bac6d6f7a316af1c5a 15693 en All - Demo - sev
ba888e6831517597859e91aa173f945c -1 fr All - Demo - Kirben
73b8197e236da4bf49adc99fe8f5fa1b -1 de All - Demo - Joachim Eberhard
- 4edbf9d03550f7ba01e7f34d69b678dd -1 nl Windows HE 98.5 Demo - Kirben
+ 4edbf9d03550f7ba01e7f34d69b678dd -1 nl All HE 98.5 Demo - Kirben
+ f2ec78e50bdc63b70044e9758be10914 -1 nl Mac HE 98.5 Demo - Ben Castricum
9d4ab3e0e1d1ebc6ba8a6a4c470ed184 -1 en All HE 100 Demo - khalek
spyfox2 SPY Fox 2: Some Assembly Required
diff --git a/devtools/skycpt/AsciiCptCompile.cpp b/devtools/skycpt/AsciiCptCompile.cpp
index 154c13b8cd..f339f6816c 100644
--- a/devtools/skycpt/AsciiCptCompile.cpp
+++ b/devtools/skycpt/AsciiCptCompile.cpp
@@ -49,7 +49,7 @@ void doCompile(FILE *inf, FILE *debOutf, FILE *resOutf, TextFile *cptDef, FILE *
int main(int argc, char* argv[])
{
uint8 testBuf[4] = { 0x11, 0x22, 0x33, 0x44 };
- if (*(uint32*)testBuf != 0x44332211) {
+ if (*(uint32 *)testBuf != 0x44332211) {
printf("Sorry, this program only works on little endian systems.\nGoodbye.\n");
return 0;
}
diff --git a/devtools/skycpt/TextFile.cpp b/devtools/skycpt/TextFile.cpp
index e9887dc87b..038b1b9329 100644
--- a/devtools/skycpt/TextFile.cpp
+++ b/devtools/skycpt/TextFile.cpp
@@ -60,7 +60,7 @@ char *TextFile::giveLine(uint32 num) {
}
void TextFile::read(FILE *inf) {
- char *line = (char*)malloc(4096);
+ char *line = (char *)malloc(4096);
_lines = (char**)malloc(4096 * sizeof(char *));
_numLines = 0;
uint32 linesMax = 4096;
@@ -78,7 +78,7 @@ void TextFile::read(FILE *inf) {
start++;
}
uint32 length = crop(start);
- _lines[_numLines] = (char*)malloc(length + 1);
+ _lines[_numLines] = (char *)malloc(length + 1);
memcpy(_lines[_numLines], start, length + 1);
_numLines++;
}
diff --git a/devtools/skycpt/cptcompiler.cpp b/devtools/skycpt/cptcompiler.cpp
index f6ee926075..2c7d33c73b 100644
--- a/devtools/skycpt/cptcompiler.cpp
+++ b/devtools/skycpt/cptcompiler.cpp
@@ -50,7 +50,7 @@ void processMainLists(FILE *inf, CptObj *destArr, uint16 *idList) {
char line[1024];
dofgets(line, 1024, inf);
assert(lineMatchSection(line, "MAINLISTS"));
- uint16 *resBuf = (uint16*)malloc(MAX_OBJ_SIZE);
+ uint16 *resBuf = (uint16 *)malloc(MAX_OBJ_SIZE);
uint32 idNum = 0;
do {
dofgets(line, 1024, inf);
@@ -60,7 +60,7 @@ void processMainLists(FILE *inf, CptObj *destArr, uint16 *idList) {
CptObj *dest = destArr + id;
assertEmpty(dest);
dest->type = MAINLIST;
- dest->dbgName = (char*)malloc(strlen(cptName) + 1);
+ dest->dbgName = (char *)malloc(strlen(cptName) + 1);
strcpy(dest->dbgName, cptName);
memset(resBuf, 0, MAX_OBJ_SIZE);
uint32 resPos = 0;
@@ -82,7 +82,7 @@ void processMainLists(FILE *inf, CptObj *destArr, uint16 *idList) {
} while (1);
assert(resPos < (MAX_OBJ_SIZE / 2));
dest->len = resPos;
- dest->data = (uint16*)malloc(resPos * 2);
+ dest->data = (uint16 *)malloc(resPos * 2);
memcpy(dest->data, resBuf, resPos * 2);
} else
break;
@@ -95,7 +95,7 @@ void processCpts(FILE *inf, CptObj *destArr) {
char line[1024];
dofgets(line, 1024, inf);
assert(lineMatchSection(line, "COMPACTS"));
- uint16 *resBuf = (uint16*)malloc(MAX_OBJ_SIZE);
+ uint16 *resBuf = (uint16 *)malloc(MAX_OBJ_SIZE);
do {
dofgets(line, 1024, inf);
if (!isEndOfSection(line)) {
@@ -103,7 +103,7 @@ void processCpts(FILE *inf, CptObj *destArr) {
uint16 id = getInfo(line, "COMPACT", cptName);
CptObj *dest = destArr + id;
assertEmpty(dest);
- dest->dbgName = (char*)malloc(strlen(cptName) + 1);
+ dest->dbgName = (char *)malloc(strlen(cptName) + 1);
dest->type = COMPACT;
strcpy(dest->dbgName, cptName);
memset(resBuf, 0, MAX_OBJ_SIZE);
@@ -134,7 +134,7 @@ void processCpts(FILE *inf, CptObj *destArr) {
} while (1);
assert(resPos < (MAX_OBJ_SIZE / 2));
dest->len = resPos;
- dest->data = (uint16*)malloc(resPos * 2);
+ dest->data = (uint16 *)malloc(resPos * 2);
memcpy(dest->data, resBuf, resPos * 2);
} else
break;
@@ -147,7 +147,7 @@ void processTurntabs(FILE *inf, CptObj *destArr) {
char line[1024];
dofgets(line, 1024, inf);
assert(lineMatchSection(line, "TURNTABS"));
- uint16 *resBuf = (uint16*)malloc(MAX_OBJ_SIZE);
+ uint16 *resBuf = (uint16 *)malloc(MAX_OBJ_SIZE);
do {
dofgets(line, 1024, inf);
if (!isEndOfSection(line)) {
@@ -155,7 +155,7 @@ void processTurntabs(FILE *inf, CptObj *destArr) {
uint16 id = getInfo(line, "TURNTAB", cptName);
CptObj *dest = destArr + id;
assertEmpty(dest);
- dest->dbgName = (char*)malloc(strlen(cptName) + 1);
+ dest->dbgName = (char *)malloc(strlen(cptName) + 1);
dest->type = TURNTAB;
strcpy(dest->dbgName, cptName);
memset(resBuf, 0, MAX_OBJ_SIZE);
@@ -176,7 +176,7 @@ void processTurntabs(FILE *inf, CptObj *destArr) {
} while (1);
assert(resPos < (MAX_OBJ_SIZE / 2));
dest->len = resPos;
- dest->data = (uint16*)malloc(resPos * 2);
+ dest->data = (uint16 *)malloc(resPos * 2);
memcpy(dest->data, resBuf, resPos * 2);
} else
break;
@@ -189,7 +189,7 @@ void processBins(FILE *inf, CptObj *destArr, const char *typeName, const char *o
char line[1024];
dofgets(line, 1024, inf);
assert(lineMatchSection(line, typeName));
- uint16 *resBuf = (uint16*)malloc(MAX_OBJ_SIZE);
+ uint16 *resBuf = (uint16 *)malloc(MAX_OBJ_SIZE);
do {
dofgets(line, 1024, inf);
if (!isEndOfSection(line)) {
@@ -197,7 +197,7 @@ void processBins(FILE *inf, CptObj *destArr, const char *typeName, const char *o
uint16 id = getInfo(line, objName, cptName);
CptObj *dest = destArr + id;
assertEmpty(dest);
- dest->dbgName = (char*)malloc(strlen(cptName) + 1);
+ dest->dbgName = (char *)malloc(strlen(cptName) + 1);
dest->type = cTypeId;
strcpy(dest->dbgName, cptName);
memset(resBuf, 0, MAX_OBJ_SIZE);
@@ -218,7 +218,7 @@ void processBins(FILE *inf, CptObj *destArr, const char *typeName, const char *o
} while (1);
assert(resPos < (MAX_OBJ_SIZE / 2));
dest->len = resPos;
- dest->data = (uint16*)malloc(resPos * 2);
+ dest->data = (uint16 *)malloc(resPos * 2);
memcpy(dest->data, resBuf, resPos * 2);
} else
break;
@@ -242,7 +242,7 @@ void processSymlinks(FILE *inf, CptObj *destArr, uint16 *baseLists) {
uint16 fromId = getInfo(line, "SYMLINK", cptName);
CptObj *from = destArr + fromId;
assertEmpty(from);
- dlinkNames[dlinkCount] = (char*)malloc(strlen(cptName) + 1);
+ dlinkNames[dlinkCount] = (char *)malloc(strlen(cptName) + 1);
strcpy(dlinkNames[dlinkCount], cptName);
dofgets(line, 1024, inf);
@@ -272,7 +272,7 @@ void doCompile(FILE *inf, FILE *debOutf, FILE *resOutf, TextFile *cptDef, FILE *
CptObj *resCpts;
uint16 baseLists[NUM_DATA_LISTS];
memset(baseLists, 0, NUM_DATA_LISTS * 2);
- resCpts = (CptObj*)malloc(MAX_CPTS * sizeof(CptObj));
+ resCpts = (CptObj *)malloc(MAX_CPTS * sizeof(CptObj));
memset(resCpts, 0, MAX_CPTS * sizeof(CptObj));
printf(" MainLists...\n");
processMainLists(inf, resCpts, baseLists);
@@ -323,7 +323,7 @@ void doCompile(FILE *inf, FILE *debOutf, FILE *resOutf, TextFile *cptDef, FILE *
fwrite(&binSize, 1, 4, debOutf);
fwrite(&binSize, 1, 4, resOutf);
- char *asciiBuf = (char*)malloc(ASCII_SIZE);
+ char *asciiBuf = (char *)malloc(ASCII_SIZE);
char *asciiPos = asciiBuf;
// now process all the compacts
@@ -491,7 +491,7 @@ void doCompile(FILE *inf, FILE *debOutf, FILE *resOutf, TextFile *cptDef, FILE *
assert((ftell(res288) / 2) < 65536);
uint16 resSize = (uint16)(ftell(res288) / 2);
fseek(res288, 0, SEEK_SET);
- uint16 *buf288 = (uint16*)malloc(resSize * 2);
+ uint16 *buf288 = (uint16 *)malloc(resSize * 2);
fread(buf288, 2, resSize, res288);
fclose(res288);
fwrite(&resSize, 1, 2, debOutf);
@@ -514,7 +514,7 @@ void doCompile(FILE *inf, FILE *debOutf, FILE *resOutf, TextFile *cptDef, FILE *
fseek(resDiff, 0, SEEK_END);
assert(ftell(resDiff) == (resSize * 2));
fseek(resDiff, 0, SEEK_SET);
- uint16 *bufDif = (uint16*)malloc(resSize *2);
+ uint16 *bufDif = (uint16 *)malloc(resSize *2);
fread(bufDif, 2, resSize, resDiff);
fclose(resDiff);
for (uint16 eCnt = 0; eCnt < resSize; eCnt++)
diff --git a/devtools/tasmrecover/dreamweb/backdrop.asm b/devtools/tasmrecover/dreamweb/backdrop.asm
index ec0e4959b3..f588e7d02b 100644
--- a/devtools/tasmrecover/dreamweb/backdrop.asm
+++ b/devtools/tasmrecover/dreamweb/backdrop.asm
@@ -1,4 +1,4 @@
-;Copyright (c) 1990-2011 by Neil Dodwell
+;Copyright (c) 1990-2012 by Neil Dodwell
;Released with permission from Neil Dodwell under GPLv2
;See LICENSE file for full license text
;----------------------------------------------Code to draw floor and panel----
diff --git a/devtools/tasmrecover/dreamweb/debug.asm b/devtools/tasmrecover/dreamweb/debug.asm
index 951da4fa3f..f4321de7bf 100644
--- a/devtools/tasmrecover/dreamweb/debug.asm
+++ b/devtools/tasmrecover/dreamweb/debug.asm
@@ -1,4 +1,4 @@
-;Copyright (c) 1990-2011 by Neil Dodwell
+;Copyright (c) 1990-2012 by Neil Dodwell
;Released with permission from Neil Dodwell under GPLv2
;See LICENSE file for full license text
diff --git a/devtools/tasmrecover/dreamweb/dreamweb.asm b/devtools/tasmrecover/dreamweb/dreamweb.asm
index 8a52435b0c..28165a51ab 100644
--- a/devtools/tasmrecover/dreamweb/dreamweb.asm
+++ b/devtools/tasmrecover/dreamweb/dreamweb.asm
@@ -1,4 +1,4 @@
-;Copyright (c) 1990-2011 by Neil Dodwell
+;Copyright (c) 1990-2012 by Neil Dodwell
;Released with permission from Neil Dodwell under GPLv2
;See LICENSE file for full license text
@@ -1129,6 +1129,8 @@ Screenupdate proc near
call newplace
call mainscreen
+ cmp quitrequested, 0
+ jnz finishearly
call animpointer
call showpointer
cmp watchingtime,0
@@ -5914,7 +5916,7 @@ Fileheader db "DREAMWEB DATA FILE "
db "CREATIVE REALITY"
Filedata dw 20 dup (0)
Extradata db 6 dup (0)
-Headerlen equ $-Fileheader
+Headerlen equ 96 ; $-Fileheader
Roomdata db "DREAMWEB.R00",0 ;Ryan's apartment
diff --git a/devtools/tasmrecover/dreamweb/keypad.asm b/devtools/tasmrecover/dreamweb/keypad.asm
index 6eee2fa11c..29542937c1 100644
--- a/devtools/tasmrecover/dreamweb/keypad.asm
+++ b/devtools/tasmrecover/dreamweb/keypad.asm
@@ -1,4 +1,4 @@
-;Copyright (c) 1990-2011 by Neil Dodwell
+;Copyright (c) 1990-2012 by Neil Dodwell
;Released with permission from Neil Dodwell under GPLv2
;See LICENSE file for full license text
Entercode proc near
diff --git a/devtools/tasmrecover/dreamweb/look.asm b/devtools/tasmrecover/dreamweb/look.asm
index a5a8b8055e..81fa663e19 100644
--- a/devtools/tasmrecover/dreamweb/look.asm
+++ b/devtools/tasmrecover/dreamweb/look.asm
@@ -1,4 +1,4 @@
-;Copyright (c) 1990-2011 by Neil Dodwell
+;Copyright (c) 1990-2012 by Neil Dodwell
;Released with permission from Neil Dodwell under GPLv2
;See LICENSE file for full license text
;---------------------------------------------------------------Look-routine----
diff --git a/devtools/tasmrecover/dreamweb/monitor.asm b/devtools/tasmrecover/dreamweb/monitor.asm
index 5354e9f7d5..25075e7eb7 100644
--- a/devtools/tasmrecover/dreamweb/monitor.asm
+++ b/devtools/tasmrecover/dreamweb/monitor.asm
@@ -1,4 +1,4 @@
-;Copyright (c) 1990-2011 by Neil Dodwell
+;Copyright (c) 1990-2012 by Neil Dodwell
;Released with permission from Neil Dodwell under GPLv2
;See LICENSE file for full license text
Usemon proc near
diff --git a/devtools/tasmrecover/dreamweb/newplace.asm b/devtools/tasmrecover/dreamweb/newplace.asm
index b06a351f5f..d2f54509dd 100644
--- a/devtools/tasmrecover/dreamweb/newplace.asm
+++ b/devtools/tasmrecover/dreamweb/newplace.asm
@@ -1,4 +1,4 @@
-;Copyright (c) 1990-2011 by Neil Dodwell
+;Copyright (c) 1990-2012 by Neil Dodwell
;Released with permission from Neil Dodwell under GPLv2
;See LICENSE file for full license text
;----------------------------------------------------Choosing a new location----
diff --git a/devtools/tasmrecover/dreamweb/object.asm b/devtools/tasmrecover/dreamweb/object.asm
index 807a100052..f7068d2cb0 100644
--- a/devtools/tasmrecover/dreamweb/object.asm
+++ b/devtools/tasmrecover/dreamweb/object.asm
@@ -1,4 +1,4 @@
-;Copyright (c) 1990-2011 by Neil Dodwell
+;Copyright (c) 1990-2012 by Neil Dodwell
;Released with permission from Neil Dodwell under GPLv2
;See LICENSE file for full license text
;---------------------------------------------------------Inventory printer----
@@ -375,7 +375,7 @@ invlist1: dw 273,320,157,198,getbackfromob
dw inventx+167,inventx+167+(18*3),inventy-18,inventy-2,incryanpage
dw inventx
openchangesize: dw inventx+(4*itempicsize)
- dw inventy+100,inventy+100+itempicsize,useopened
+invlist1continued: dw inventy+100,inventy+100+itempicsize,useopened
dw inventx,inventx+(5*itempicsize)
dw inventy,inventy+(2*itempicsize),intoinv
dw 0,320,0,200,blank
diff --git a/devtools/tasmrecover/dreamweb/print.asm b/devtools/tasmrecover/dreamweb/print.asm
index 7cbb45c08b..22ca61b8b1 100644
--- a/devtools/tasmrecover/dreamweb/print.asm
+++ b/devtools/tasmrecover/dreamweb/print.asm
@@ -1,4 +1,4 @@
-;Copyright (c) 1990-2011 by Neil Dodwell
+;Copyright (c) 1990-2012 by Neil Dodwell
;Released with permission from Neil Dodwell under GPLv2
;See LICENSE file for full license text
Printchar proc near
diff --git a/devtools/tasmrecover/dreamweb/saveload.asm b/devtools/tasmrecover/dreamweb/saveload.asm
index 6c98774a0f..a49b527d01 100644
--- a/devtools/tasmrecover/dreamweb/saveload.asm
+++ b/devtools/tasmrecover/dreamweb/saveload.asm
@@ -1,4 +1,4 @@
-;Copyright (c) 1990-2011 by Neil Dodwell
+;Copyright (c) 1990-2012 by Neil Dodwell
;Released with permission from Neil Dodwell under GPLv2
;See LICENSE file for full license text
@@ -1502,7 +1502,6 @@ Loadold proc near
alreadyloadold: mov ax,mousebutton
and ax,1
jz noloadold
- mov ax,0ffffh
call doload
cmp getback,4
jz noloadold
diff --git a/devtools/tasmrecover/dreamweb/sblaster.asm b/devtools/tasmrecover/dreamweb/sblaster.asm
index 7a271e9c90..5eef2dbfd8 100644
--- a/devtools/tasmrecover/dreamweb/sblaster.asm
+++ b/devtools/tasmrecover/dreamweb/sblaster.asm
@@ -1,4 +1,4 @@
-;Copyright (c) 1990-2011 by Neil Dodwell
+;Copyright (c) 1990-2012 by Neil Dodwell
;Released with permission from Neil Dodwell under GPLv2
;See LICENSE file for full license text
; Creative Reality Sound Blaster Drivers . (C) 1994 Creative Reality
diff --git a/devtools/tasmrecover/dreamweb/sprite.asm b/devtools/tasmrecover/dreamweb/sprite.asm
index 06b06c76e3..c6a75063a0 100644
--- a/devtools/tasmrecover/dreamweb/sprite.asm
+++ b/devtools/tasmrecover/dreamweb/sprite.asm
@@ -1,4 +1,4 @@
-;Copyright (c) 1990-2011 by Neil Dodwell
+;Copyright (c) 1990-2012 by Neil Dodwell
;Released with permission from Neil Dodwell under GPLv2
;See LICENSE file for full license text
;------------------------------------------------------------People Routines----
@@ -244,7 +244,7 @@ Reelroutines db 1,44,0 ;Room number and x,y
db 255
-Lenofreelrouts equ $-reelroutines
+Lenofreelrouts equ 457 ; $-reelroutines
Reelcalls dw gamer,sparkydrip,eden,edeninbath,sparky,smokebloke
diff --git a/devtools/tasmrecover/dreamweb/talk.asm b/devtools/tasmrecover/dreamweb/talk.asm
index 4d6b381881..91cbb96c6e 100644
--- a/devtools/tasmrecover/dreamweb/talk.asm
+++ b/devtools/tasmrecover/dreamweb/talk.asm
@@ -1,4 +1,4 @@
-;Copyright (c) 1990-2011 by Neil Dodwell
+;Copyright (c) 1990-2012 by Neil Dodwell
;Released with permission from Neil Dodwell under GPLv2
;See LICENSE file for full license text
Talk proc near
diff --git a/devtools/tasmrecover/dreamweb/titles.asm b/devtools/tasmrecover/dreamweb/titles.asm
index 52f58867ed..f2e96f9c78 100644
--- a/devtools/tasmrecover/dreamweb/titles.asm
+++ b/devtools/tasmrecover/dreamweb/titles.asm
@@ -1,4 +1,4 @@
-;Copyright (c) 1990-2011 by Neil Dodwell
+;Copyright (c) 1990-2012 by Neil Dodwell
;Released with permission from Neil Dodwell under GPLv2
;See LICENSE file for full license text
diff --git a/devtools/tasmrecover/dreamweb/use.asm b/devtools/tasmrecover/dreamweb/use.asm
index 78917d50f4..f8c64f6f45 100644
--- a/devtools/tasmrecover/dreamweb/use.asm
+++ b/devtools/tasmrecover/dreamweb/use.asm
@@ -1,4 +1,4 @@
-;Copyright (c) 1990-2011 by Neil Dodwell
+;Copyright (c) 1990-2012 by Neil Dodwell
;Released with permission from Neil Dodwell under GPLv2
;See LICENSE file for full license text
diff --git a/devtools/tasmrecover/dreamweb/vars.asm b/devtools/tasmrecover/dreamweb/vars.asm
index 6d34074528..99592233d3 100644
--- a/devtools/tasmrecover/dreamweb/vars.asm
+++ b/devtools/tasmrecover/dreamweb/vars.asm
@@ -1,4 +1,4 @@
-;Copyright (c) 1990-2011 by Neil Dodwell
+;Copyright (c) 1990-2012 by Neil Dodwell
;Released with permission from Neil Dodwell under GPLv2
;See LICENSE file for full license text
;---------------------------------------------------Equates and definitions----
diff --git a/devtools/tasmrecover/dreamweb/vgafades.asm b/devtools/tasmrecover/dreamweb/vgafades.asm
index a1043d9cf5..a39ae5d297 100644
--- a/devtools/tasmrecover/dreamweb/vgafades.asm
+++ b/devtools/tasmrecover/dreamweb/vgafades.asm
@@ -1,4 +1,4 @@
-;Copyright (c) 1990-2011 by Neil Dodwell
+;Copyright (c) 1990-2012 by Neil Dodwell
;Released with permission from Neil Dodwell under GPLv2
;See LICENSE file for full license text
Fadedos proc near
diff --git a/devtools/tasmrecover/dreamweb/vgagrafx.asm b/devtools/tasmrecover/dreamweb/vgagrafx.asm
index 4ba1b16ba1..368ad3c501 100644
--- a/devtools/tasmrecover/dreamweb/vgagrafx.asm
+++ b/devtools/tasmrecover/dreamweb/vgagrafx.asm
@@ -1,4 +1,4 @@
-;Copyright (c) 1990-2011 by Neil Dodwell
+;Copyright (c) 1990-2012 by Neil Dodwell
;Released with permission from Neil Dodwell under GPLv2
;See LICENSE file for full license text
Screenwidth equ 320 ;physical width of screen
diff --git a/devtools/tasmrecover/tasm-recover b/devtools/tasmrecover/tasm-recover
index 2066ae9b3d..e46b2efaa8 100755
--- a/devtools/tasmrecover/tasm-recover
+++ b/devtools/tasmrecover/tasm-recover
@@ -24,191 +24,2118 @@
from tasm.parser import parser
from tasm.cpp import cpp
-p = parser()
+p = parser(skip_binary_data = [
+ # These data blobs are not output
+ # dreamweb.asm
+ 'characterset1',
+ 'roomdata',
+ 'mainlist',
+ 'mainlist2',
+ 'menulist',
+ 'folderlist',
+ 'stak',
+ 'keyconverttab',
+ 'atmospherelist',
+ 'linedata',
+ 'madeuproomdat',
+ 'recname',
+ 'fileheader',
+ 'filedata',
+ 'foreignrelease',
+ 'extradata',
+ 'keybuffer',
+ 'spritename1',
+ 'subtitles',
+ 'icongraphics0',
+ 'icongraphics1',
+ 'savenames',
+ 'volumetabname',
+ 'commandline',
+ 'openchangesize',
+ 'roompics',
+ 'roomscango',
+ 'oplist',
+ 'presslist',
+ 'inputline',
+ 'flashmousetab',
+ 'id',
+ 'place',
+ 'blinktab',
+ 'quitrequested',
+ # keypad.asm
+ 'keypadlist',
+ 'symbollist',
+ 'diarylist',
+ # monitor.asm
+ 'comlist',
+ 'keys',
+ 'rootdir',
+ 'operand1',
+ 'currentfile',
+ # newplace.asm
+ 'destlist',
+ # object.asm
+ 'invlist1',
+ 'invlist1continued',
+ 'examlist',
+ 'withlist1',
+ # saveload.asm
+ 'loadlist',
+ 'savelist',
+ 'gameerror1',
+ 'gameerror2',
+ 'gameerror3',
+ 'gameerror4',
+ 'gameerror5',
+ 'gameerror6',
+ 'gameerror7',
+ 'gameerror8',
+ 'error2patch',
+ 'error6patch',
+ 'error8patch',
+ 'gameinfo',
+ 'endgametext1',
+ 'savefiles',
+ 'decidelist',
+ 'discopslist',
+ 'opslist',
+ # sblaster.asm
+ 'dmaaddresses',
+ 'speechfilename',
+ 'speechfile',
+ 'speechlength',
+ 'soundbufferwrite',
+ # sprite.asm
+ 'reelroutines',
+ 'reelcalls',
+ 'facelist',
+ 'rainlocations',
+ 'roombyroom',
+ 'r0','r1','r2','r6','r8','r9','r10','r11','r12','r13','r14',
+ 'r20','r22','r23','r25','r26','r27','r28','r29',
+ 'r45','r46','r47','r52','r53','r55',
+ #talk.asm
+ 'talklist',
+ 'quitlist',
+ # titles.asm
+ 'introtextname',
+ 'title0graphics',
+ 'title1graphics',
+ 'title2graphics',
+ 'title3graphics',
+ 'title4graphics',
+ 'title5graphics',
+ 'title6graphics',
+ # use.asm
+ 'uselist',
+ 'money1poke',
+ 'money2poke',
+ # vars.asm
+ 'currentset',
+ 'currentsample',
+ 'ch0playing',
+ 'ch0repeat',
+ 'ch1playing',
+ 'icons1',
+ 'icons2',
+ 'tempcharset',
+ 'currentframe',
+ 'takeoff',
+ 'reelpointer',
+ 'roomssample',
+ 'needsoundbuff',
+ 'oldint8seg',
+ 'oldint8add',
+ 'oldint9seg',
+ 'oldint9add',
+ 'soundbuffer',
+ 'soundbufferad',
+ 'soundbufferpage',
+ 'soundtimes',
+ 'oldsoundintseg',
+ 'oldsoundintadd',
+ 'soundbaseadd',
+ 'dsp_status',
+ 'dsp_write',
+ 'dmaaddress',
+ 'soundint',
+ 'sounddmachannel',
+ 'sampleplaying',
+ 'testresult',
+ 'currentirq',
+ 'gameerror',
+ 'howmuchalloc',
+ 'inputport',
+ 'emmhandle',
+ 'emmpageframe',
+ 'emmhardwarepage',
+ 'ch0emmpage',
+ 'ch0offset',
+ 'ch0oldemmpage',
+ 'ch0oldoffset',
+ 'ch0oldblockstocopy',
+ 'ch1emmpage',
+ 'ch1offset',
+ 'ch1blocksplayed',
+ 'soundemmpage',
+ 'speechemmpage',
+ 'speechloaded',
+ 'lineroutine',
+ 'increment1',
+ 'increment2',
+ 'keypadax',
+ 'keypadcx',
+ 'soundbuffer',
+ 'cursloc',
+ 'liftsoundcount',
+ 'playblock',
+ 'gotfrom',
+ 'flagx',
+ 'flagy',
+ 'lastflagex',
+ 'keynum',
+ 'newlogonum',
+ 'currentex',
+ 'currentfree',
+ 'frsegment',
+ 'dataad',
+ 'framesad',
+ 'objectx',
+ 'objecty',
+ 'savesize',
+ 'savesource',
+ 'savex',
+ 'savey',
+ 'persondata',
+ 'talknum',
+ 'saidno',
+ 'prioritydep',
+ 'currentkey2',
+ 'mustload',
+ 'answered',
+ 'slotdata',
+ 'thisslot',
+ 'slotflags',
+ 'numberinroom',
+ 'currentcel',
+ 'oldselection',
+ 'stopwalking',
+ 'mouseon',
+ 'played',
+ 'timer1',
+ 'timer2',
+ 'timer3',
+ 'volume',
+ 'volumeto',
+ 'volumedirection',
+ 'volumecount',
+ 'wholetimer',
+ 'wongame',
+ 'timer1to',
+ 'timer2to',
+ 'timer3to',
+ 'oldsubject',
+ 'buffers',
+ 'itemtotran',
+ 'symboltolight',
+ 'symbol1',
+ 'symbol2',
+ 'symbol3',
+ 'symbolnum',
+ 'monsource',
+ 'netseg',
+ 'netpoint',
+ 'cursorstate',
+ 'ch0blockstocopy',
+ 'ch1blockstocopy',
+ 'sounddata',
+ 'sounddata2',
+ 'mapstore',
+ 'mapdata',
+ 'backdrops',
+ 'textfile1',
+ 'textfile2',
+ 'textfile3',
+ 'puzzletext',
+ 'commandtext',
+ 'traveltext',
+ 'tempgraphics',
+ 'tempgraphics2',
+ 'tempgraphics3',
+ 'tempsprites',
+ 'charset1',
+ 'extras',
+ 'freeframes',
+ 'setframes',
+ 'reel1',
+ 'reel2',
+ 'reel3',
+ 'setdesc',
+ 'blockdesc',
+ 'roomdesc',
+ 'freedesc',
+ 'people',
+ 'reels',
+ 'setdat',
+ 'freedat',
+ 'speechcount',
+ 'charshift',
+ 'kerning',
+ 'brightness',
+ 'roomloaded',
+ 'didzoom',
+ 'linespacing',
+ 'textaddressx',
+ 'textaddressy',
+ 'textlen',
+ 'lastxpos',
+ 'icontop',
+ 'iconleft',
+ 'itemframe',
+ 'roomad',
+ 'withobject',
+ 'withtype',
+ 'lookcounter',
+ 'command',
+ 'commandtype',
+ 'oldcommandtype',
+ 'objecttype',
+ 'getback',
+ 'invopen',
+ 'mainmode',
+ 'pickup',
+ 'lastinvpos',
+ 'examagain',
+ 'newtextline',
+ 'openedob',
+ 'openedtype',
+ 'oldmapadx',
+ 'oldmapady',
+ 'mapadx',
+ 'mapady',
+ 'mapoffsetx',
+ 'mapoffsety',
+ 'mapxstart',
+ 'mapystart',
+ 'mapxsize',
+ 'mapysize',
+ 'havedoneobs',
+ 'manisoffscreen',
+ 'rainspace',
+ 'facing',
+ 'leavedirection',
+ 'turntoface',
+ 'turndirection',
+ 'maintimer',
+ 'introcount',
+ 'arrowad',
+ 'currentkey',
+ 'oldkey',
+ 'useddirection',
+ 'timercount',
+ 'oldtimercount',
+ 'mapx',
+ 'mapy',
+ 'newscreen',
+ 'ryanx',
+ 'ryany',
+ 'lastflag',
+ 'offsetx',
+ 'offsety',
+ 'currentob',
+ 'destpos',
+ 'reallocation',
+ 'roomnum',
+ 'nowinnewroom',
+ 'resetmanxy',
+ 'newlocation',
+ 'autolocation',
+ 'doorcheck1',
+ 'doorcheck2',
+ 'doorcheck3',
+ 'doorcheck4',
+ 'mousex',
+ 'mousey',
+ 'mousebutton',
+ 'mousebutton1',
+ 'mousebutton2',
+ 'mousebutton3',
+ 'mousebutton4',
+ 'oldbutton',
+ 'oldx',
+ 'oldy',
+ 'lastbutton',
+ 'oldpointerx',
+ 'oldpointery',
+ 'delherex',
+ 'delherey',
+ 'pointerxs',
+ 'pointerys',
+ 'delxs',
+ 'delys',
+ 'pointerframe',
+ 'pointerpower',
+ 'auxpointerframe',
+ 'pointermode',
+ 'pointerspeed',
+ 'pointercount',
+ 'inmaparea',
+ 'talkmode',
+ 'talkpos',
+ 'character',
+ 'watchdump',
+ 'logonum',
+ 'oldlogonum',
+ 'pressed',
+ 'presspointer',
+ 'graphicpress',
+ 'presscount',
+ 'lightcount',
+ 'folderpage',
+ 'diarypage',
+ 'menucount',
+ 'symboltopx',
+ 'symboltopnum',
+ 'symboltopdir',
+ 'symbolbotx',
+ 'symbolbotnum',
+ 'symbolbotdir',
+ 'dumpx',
+ 'dumpy',
+ 'walkandexam',
+ 'walkexamtype',
+ 'walkexamnum',
+ 'curslocx',
+ 'curslocy',
+ 'curpos',
+ 'monadx',
+ 'monady',
+ 'numtodo',
+ 'timecount',
+ 'counttotimed',
+ 'timedseg',
+ 'timedoffset',
+ 'timedy',
+ 'timedx',
+ 'needtodumptimed',
+ 'loadingorsave',
+ 'currentslot',
+ 'cursorpos',
+ 'colourpos',
+ 'fadedirection',
+ 'numtofade',
+ 'fadecount',
+ 'addtogreen',
+ 'addtored',
+ 'addtoblue',
+ 'lastsoundreel',
+ 'volume',
+ 'volumeto',
+ 'volumedirection',
+ 'volumecount',
+ 'lasthardkey',
+ 'bufferin',
+ 'bufferout',
+ 'workspace',
+ 'mainsprites',
+ 'backdrop',
+ 'recordspace',
+ 'blinkframe',
+ 'blinkcount',
+ 'reasseschanges',
+ 'pointerspath',
+ 'manspath',
+ 'pointerfirstpath',
+ 'finaldest',
+ 'destination',
+ 'linestartx',
+ 'linestarty',
+ 'lineendx',
+ 'lineendy',
+ 'linepointer',
+ 'linedirection',
+ 'linelength',
+ # vars.asm - saved vars
+ 'startvars',
+ 'progresspoints',
+ 'watchon',
+ 'shadeson',
+ 'secondcount',
+ 'minutecount',
+ 'hourcount',
+ 'zoomon',
+ 'location',
+ 'expos',
+ 'exframepos',
+ 'extextpos',
+ 'card1money',
+ 'listpos',
+ 'ryanpage',
+ 'watchingtime',
+ 'reeltowatch',
+ 'endwatchreel',
+ 'speedcount',
+ 'watchspeed',
+ 'reeltohold',
+ 'endofholdreel',
+ 'watchmode',
+ 'destafterhold',
+ 'newsitem',
+ 'liftflag',
+ 'liftpath',
+ 'lockstatus',
+ 'doorpath',
+ 'counttoopen',
+ 'counttoclose',
+ 'rockstardead',
+ 'generaldead',
+ 'sartaindead',
+ 'aidedead',
+ 'beenmugged',
+ 'gunpassflag',
+ 'canmovealtar',
+ 'talkedtoattendant',
+ 'talkedtosparky',
+ 'talkedtoboss',
+ 'talkedtorecep',
+ 'cardpassflag',
+ 'madmanflag',
+ 'keeperflag',
+ 'lasttrigger',
+ 'mandead',
+ 'seed',
+ 'seed',
+ 'seed',
+ 'needtotravel',
+ 'throughdoor',
+ 'newobs',
+ 'ryanon',
+ 'combatcount',
+ 'lastweapon',
+ 'dreamnumber',
+ 'roomafterdream',
+ 'shakecounter',
+ # vars.asm - constants
+ 'openinvlist',
+ 'ryaninvlist',
+ 'pointerback',
+ 'mapflags',
+ 'startpal',
+ 'endpal',
+ 'maingamepal',
+ 'spritetable',
+ 'setlist',
+ 'freelist',
+ 'exlist',
+ 'peoplelist',
+ 'zoomspace',
+ 'printedlist',
+ 'listofchanges',
+ 'undertimedtext',
+ 'rainlist',
+ 'initialreelrouts',
+ 'initialvars',
+ 'lengthofbuffer',
+ 'lenofreelrouts',
+ 'reellist',
+ 'intext',
+ 'lengthofmap',
+ 'blocktext',
+ 'blocks',
+ 'frframes',
+ 'frames',
+ 'persontxtdat',
+ 'persontext',
+ 'tablesize',
+ 'undertextsizex', # defined in dreambase.h
+ 'undertextsizey', # defined in dreambase.h
+ 'lengthofvars', # defined in dreambase.h
+ 'lenofmapstore', # defined in dreambase.h
+ 'keypadx',
+ 'keypady',
+ 'settext',
+ 'freetext',
+ 'setdatlen',
+ 'textstart',
+ 'maplen',
+ 'maplength',
+ 'undertimedysize',
+ 'blocktextdat',
+ 'personframes',
+ 'map',
+ 'settextdat',
+ 'textunder',
+ 'pathdata',
+ 'framedata',
+ 'flags',
+ 'intextdat',
+ 'freetextdat',
+ 'frframedata',
+ 'zoomx',
+ 'zoomy',
+ 'menux',
+ 'menuy',
+ 'headerlen',
+ 'freedatlen',
+ 'diaryx',
+ 'diaryy',
+ 'inventx',
+ 'inventy',
+ 'screenwidth',
+ 'mapwidth',
+ 'opsx',
+ 'opsy',
+ 'symbolx',
+ 'symboly',
+ 'numchanges',
+ # vgagrafx.asm
+ 'cityname',
+ 'extragraphics1',
+ 'icongraphics8',
+ 'shaketable',
+ 'symbolgraphic',
+ 'travelgraphic1',
+ 'travelgraphic2',
+ 'foldergraphic1',
+ 'foldergraphic2',
+ 'foldergraphic3',
+ 'foldertext',
+ 'traveltextname',
+ 'mongraphics2',
+ 'spritename3',
+ 'mongraphicname',
+ 'puzzletextname',
+ 'commandtextname',
+ 'characterset2',
+ 'characterset3',
+ 'monitorfile1',
+ 'monitorfile2',
+ 'monitorfile10',
+ 'monitorfile11',
+ 'monitorfile12',
+ 'monitorfile13',
+ 'monitorfile20',
+ 'monitorfile21',
+ 'monitorfile22',
+ 'monitorfile23',
+ 'monitorfile24',
+ 'introtextfile',
+ 'palettescreen',
+ 'idname',
+ 'samplename',
+ 'diarygraphic',
+ 'diarytext',
+ 'title7graphics',
+ 'handle',
+ 'basicsample',
+ 'endtextname',
+ 'gungraphic',
+ 'monkface',
+ ])
p.strip_path = 3
context = p.parse('dreamweb/dreamweb.asm')
p.link()
generator = cpp(context, "DreamGen", blacklist = [
# These functions are not processed
- 'randomnumber',
- 'quickquit',
- 'quickquit2',
- 'seecommandtail',
- 'multiget',
- 'multiput',
- 'multidump',
- 'frameoutnm',
- 'frameoutbh',
- 'frameoutfx',
- 'cls',
- 'clearwork',
- 'printundermon',
- 'kernchars',
- 'getnextword',
- 'getnumber',
- 'dumptextline',
- 'printboth',
- 'printchar',
- 'printdirect',
- 'printslow',
- 'printmessage',
- 'usetimedtext',
- 'dumptimedtext',
- 'setuptimedtemp',
- 'putundertimed',
- 'getundertimed',
- 'worktoscreen',
- 'width160',
- 'convertkey',
- 'readabyte',
- 'readoneblock',
- 'printsprites',
- 'printasprite',
- 'eraseoldobs',
- 'clearsprites',
- 'makesprite',
- 'showframe',
- 'initman',
+
'aboutturn',
- 'readheader',
- 'fillspace',
- 'getroomdata',
- 'startloading',
- 'showreelframe',
- 'showgamereel',
- 'getreelframeax',
- 'findsource',
- 'walking',
- 'autosetwalk',
- 'checkdest',
- 'spriteupdate',
- 'dodoor',
- 'lockeddoorway',
- 'liftsprite',
- 'frameoutv',
- 'modifychar',
+ 'accesslightoff',
+ 'accesslighton',
+ 'actualload',
+ 'actualsave',
+ 'addalong',
+ 'additionaltext',
+ 'addlength',
+ 'addtopeoplelist',
+ 'addtopresslist',
+ 'adjustdown',
+ 'adjustleft',
+ 'adjustlen',
+ 'adjustright',
+ 'adjustup',
+ 'advisor',
+ 'afterintroroom',
+ 'afternewroom',
+ 'aide',
+ 'alleybarksound',
+ 'allocatebuffers',
+ 'allocateload',
+ 'allocatemem',
'allocatework',
- 'lockmon',
+ 'allpalette',
+ 'allpointer',
+ 'animpointer',
+ 'atmospheres',
+ 'attendant',
+ 'autoappear',
+ 'autolook',
+ 'autosetwalk',
+ 'backobject',
+ 'bartender',
+ 'barwoman',
+ 'biblequote',
+ 'blank',
+ 'blockget',
+ 'blocknametext',
+ 'bossman',
+ 'bothchannels',
+ 'bresenhams',
+ 'businessman',
+ 'buttoneight',
+ 'buttonenter',
+ 'buttonfive',
+ 'buttonfour',
+ 'buttonnine',
+ 'buttonnought',
+ 'buttonone',
+ 'buttonpress',
+ 'buttonseven',
+ 'buttonsix',
+ 'buttonthree',
+ 'buttontwo',
+ 'calcfrframe',
+ 'calcmapad',
+ 'calledensdlift',
+ 'calledenslift',
+ 'callhotellift',
'cancelch0',
'cancelch1',
- 'getroomspaths',
- 'makebackob',
- 'dealwithspecial',
- 'plotreel',
- 'facerightway',
- 'zoom',
- 'crosshair',
- 'showrain',
- 'domix',
+ 'candles',
+ 'candles1',
+ 'candles2',
+ 'cantdrop',
+ 'carparkdrip',
+ 'channel0only',
'channel0tran',
- 'makenextblock',
- 'loopchannel0',
- 'parseblaster',
- 'deltextline',
- 'doblocks',
- 'checkifperson',
- 'checkiffree',
+ 'channel1only',
+ 'checkbasemem',
+ 'checkcoords',
+ 'checkdest',
+ 'checkforemm',
+ 'checkforexit',
+ 'checkforshake',
'checkifex',
- 'getreelstart',
- 'findobname',
- 'copyname',
+ 'checkiffree',
+ 'checkifpathison',
+ 'checkifperson',
+ 'checkifset',
+ 'checkinput',
+ 'checkinside',
+ 'checkobjectsize',
+ 'checkone',
+ 'checksoundint',
+ 'checkspeed',
+ 'chewy',
+ 'clearbeforeload',
+ 'clearbuffers',
+ 'clearchanges',
+ 'clearendpal',
+ 'clearpalette',
+ 'clearreels',
+ 'clearrest',
+ 'clearsprites',
+ 'clearstartpal',
+ 'clearwork',
+ 'closefile',
+ 'cls',
+ 'commandonly',
'commandwithob',
- 'showpanel',
- 'updatepeople',
- 'madmantext',
- 'madmode',
- 'movemap',
+ 'compare',
+ 'constant',
+ 'convertkey',
+ 'convicons',
+ 'convnum',
+ 'copper',
+ 'copyname',
+ 'createfile',
+ 'createname',
+ 'createpanel',
+ 'createpanel2',
+ 'credits',
+ 'crosshair',
+ 'dealwithspecial',
+ 'deallocatemem',
+ 'decide',
+ 'delchar',
+ 'delcurs',
+ 'deleteexframe',
+ 'deleteextext',
+ 'deleteexobject',
+ 'deletetaken',
+ 'deleverything',
+ 'delpointer',
+ 'delsprite',
+ 'deltextline',
+ 'delthisone',
+ 'describeob',
+ 'destselect',
+ 'diarykeyp',
+ 'diarykeyn',
+ 'dircom',
+ 'dirfile',
+ 'disablepath',
+ 'disablesoundint',
+ 'discops',
+ 'dmaend',
+ 'doblocks',
+ 'dochange',
+ 'dodoor',
+ 'dofade',
+ 'doload',
+ 'dolook',
+ 'domix',
+ 'dontloadseg',
'doorway',
- 'widedoor',
- 'showallobs',
- 'addalong',
- 'addlength',
- 'getdimension',
- 'getxad',
- 'getyad',
- 'getmapad',
- 'calcmapad',
- 'calcfrframe',
+ 'dosaveload',
+ 'dosometalk',
+ 'dosreturn',
+ 'doshake',
+ 'drawflags',
+ 'drawfloor',
+ 'drawitall',
+ 'dreamweb',
+ 'drinker',
+ 'droperror',
+ 'dropobject',
+ 'drunk',
+ 'dumpblink',
+ 'dumpcurrent',
+ 'dumpdiarykeys',
+ 'dumpeverything',
+ 'dumpkeypad',
+ 'dumpmap',
+ 'dumpmenu',
+ 'dumppointer',
+ 'dumpsymbol',
+ 'dumpsymbox',
+ 'dumptextline',
+ 'dumptimedtext',
+ 'dumpwatch',
+ 'dumpzoom',
+ 'eden',
+ 'edeninbath',
+ 'edenscdplayer',
+ 'emergencypurge',
+ 'enablesoundint',
+ 'endgame',
+ 'endgameseq',
+ 'endpaltostart',
+ 'entercode',
+ 'entersymbol',
+ 'entryanims',
+ 'entrytexts',
+ 'eraseoldobs',
+ 'error',
+ 'errormessage1',
+ 'errormessage2',
+ 'errormessage3',
+ 'examicon',
+ 'examinventory',
+ 'examineob',
+ 'examineobtext',
+ 'execcommand',
+ 'facerightway',
+ 'fadecalculation',
+ 'fadedos',
+ 'fadedownmon',
+ 'fadefromwhite',
+ 'fadescreenup',
+ 'fadescreenups',
+ 'fadescreenuphalf',
+ 'fadescreendown',
+ 'fadescreendowns',
+ 'fadescreendownhalf',
+ 'fadetowhite',
+ 'fadeupmon',
+ 'fadeupmonfirst',
+ 'fadeupyellows',
+ 'femalefan',
+ 'fillopen',
+ 'fillryan',
+ 'fillspace',
'finalframe',
- 'commandonly',
- 'makename',
+ 'findallopen',
+ 'findallryan',
+ 'findexobject',
+ 'findfirstpath',
+ 'findinvpos',
'findlen',
- 'blocknametext',
- 'walktotext',
- 'personnametext',
- 'findxyfrompath',
+ 'findnextcolon',
+ 'findobname',
+ 'findopenpos',
'findormake',
- 'setallchanges',
- 'dochange',
- 'deletetaken',
- 'placesetobject',
- 'removesetobject',
- 'showallfree',
- 'showallex',
- 'adjustlen',
+ 'findpathofpoint',
+ 'findpuztext',
+ 'findroominloc',
+ 'findsetobject',
+ 'findsource',
+ 'findtext1',
+ 'findxyfrompath',
'finishedwalking',
- 'checkone',
+ 'folderexit',
+ 'folderhints',
+ 'foghornsound',
+ 'frameoutbh',
+ 'frameoutfx',
+ 'frameoutnm',
+ 'frameoutv',
+ 'gamer',
+ 'gates',
+ 'generalerror',
+ 'getanyad',
+ 'getanyaddir',
+ 'getback1',
+ 'getbackfromob',
+ 'getbackfromops',
+ 'getbacktoops',
'getblockofpixel',
+ 'getdestinfo',
+ 'getdimension',
+ 'geteitherad',
+ 'getexad',
+ 'getexpos',
'getflagunderp',
- 'walkandexamine',
+ 'getfreead',
+ 'getkeyandlogo',
+ 'getlocation',
+ 'getmapad',
+ 'getnamepos',
+ 'getnextword',
+ 'getnumber',
+ 'getobtextstart',
+ 'getopenedsize',
+ 'getpersframe',
+ 'getpersontext',
+ 'getreelframeax',
+ 'getreelstart',
+ 'getridofall',
+ 'getridofpit',
+ 'getridofreels',
+ 'getridoftemp',
+ 'getridoftemp2',
+ 'getridoftemp3',
+ 'getridoftempcharset',
+ 'getridoftempsp',
+ 'getridoftemptext',
+ 'getroomdata',
+ 'getroomspaths',
+ 'getsetad',
+ 'gettime',
+ 'gettingshot',
+ 'getundercentre',
+ 'getundermenu',
+ 'getundertimed',
+ 'getunderzoom',
+ 'getxad',
+ 'getyad',
+ 'grafittidoor',
+ 'greyscalesum',
+ 'handclap',
+ 'hangon',
+ 'hangoncurs',
+ 'hangone',
+ 'hangonp',
+ 'hangonpq',
+ 'hangonw',
+ 'heavy',
+ 'helicopter',
+ 'hotelbell',
+ 'hotelcontrol',
+ 'identifyob',
+ 'incryanpage',
+ 'initialinv',
+ 'initialmoncols',
+ 'initman',
+ 'initrain',
+ 'input',
+ 'interupttest',
+ 'interviewer',
+ 'intoinv',
+ 'intro',
+ 'intro1text',
+ 'intro2text',
+ 'intro3text',
+ 'intromagic1',
+ 'intromagic2',
+ 'intromagic3',
+ 'intromonks1',
+ 'intromonks2',
+ 'intromusic',
+ 'inventory',
+ 'isitdescribed',
+ 'isitright',
+ 'isitworn',
+ 'isryanholding',
+ 'issetobonmap',
+ 'keeper',
+ 'kernchars',
+ 'keyboardread',
+ 'lastdest',
+ 'lastfolder',
+ 'liftnoise',
+ 'liftsprite',
+ 'loadcart',
+ 'loadfolder',
+ 'loadgame',
+ 'loadintroroom',
+ 'loadintotemp',
+ 'loadintotemp2',
+ 'loadintotemp3',
+ 'loadkeypad',
+ 'loadmenu',
+ 'loadnews',
+ 'loadold',
+ 'loadpalfromiff',
+ 'loadpersonal',
+ 'loadposition',
+ 'loadseg',
+ 'loadspeech',
+ 'loadroom',
+ 'loadroomssample',
+ 'loadsample',
+ 'loadsavebox',
+ 'loadsecondsample',
+ 'loadtempcharset',
+ 'loadtemptext',
+ 'loadtraveltext',
+ 'locationpic',
+ 'lockeddoorway',
+ 'locklightoff',
+ 'locklighton',
+ 'lockmon',
+ 'look',
+ 'lookatcard',
+ 'lookatplace',
+ 'lookininterface',
+ 'loopchannel0',
+ 'louis',
+ 'louischair',
+ 'madman',
+ 'madmanrun',
+ 'madmanstelly',
+ 'madmantext',
+ 'madmode',
+ 'mainman',
+ 'mainscreen',
+ 'makebackob',
+ 'makecaps',
+ 'makeheader',
+ 'makemainscreen',
+ 'makename',
+ 'makenextblock',
+ 'makesprite',
+ 'makeworn',
+ 'malefan',
+ 'manasleep',
+ 'manasleep2',
+ 'mansatstill',
+ 'maptopanel',
+ 'middlepanel',
+ 'mode640x480',
+ 'modifychar',
+ 'moneypoke',
+ 'monitorlogo',
+ 'monkandryan',
+ 'monks2text',
+ 'monkspeaking',
+ 'monmessage',
+ 'monprint',
+ 'moretalk',
+ 'mousecall',
+ 'movemap',
+ 'mugger',
+ 'multidump',
+ 'multiget',
+ 'multiput',
+ 'namestoold',
+ 'neterror',
+ 'newgame',
+ 'newplace',
+ 'nextcolon',
+ 'nextdest',
+ 'nextfolder',
+ 'nextsymbol',
+ 'nothelderror',
+ 'obicons',
'obname',
- 'delpointer',
- 'showblink',
- 'dumpblink',
- 'dumppointer',
- 'showpointer',
- 'animpointer',
- 'checkcoords',
+ 'obpicture',
+ 'obsthatdothings',
+ 'obtoinv',
+ 'oldtonames',
+ 'onedigit',
+ 'openeden',
+ 'openfile',
+ 'openfilefromc',
+ 'openfilenocheck',
+ 'openforsave',
+ 'openhoteldoor',
+ 'openhoteldoor2',
+ 'openinv',
+ 'openlouis',
+ 'openob',
+ 'openpoolboss',
+ 'openryan',
+ 'opensarters',
+ 'opentomb',
+ 'opentvdoor',
+ 'openyourneighbour',
+ 'othersmoker',
+ 'out22c',
+ 'outofinv',
+ 'outofopen',
+ 'paltoendpal',
+ 'paltostartpal',
+ 'panelicons1',
+ 'paneltomap',
+ 'parseblaster',
+ 'parser',
+ 'personnametext',
+ 'pickupconts',
+ 'pickupob',
+ 'pitinterupt',
+ 'pixelcheckset',
+ 'placefreeobject',
+ 'placesetobject',
+ 'playchannel0',
+ 'playchannel1',
+ 'playguitar',
+ 'plotreel',
+ 'poolguard',
+ 'powerlightoff',
+ 'powerlighton',
+ 'priest',
+ 'priesttext',
+ 'printasprite',
+ 'printboth',
+ 'printchar',
+ 'printcurs',
+ 'printdirect',
+ 'printlogo',
+ 'printmessage',
+ 'printmessage2',
+ 'printoutermon',
+ 'printslow',
+ 'printsprites',
+ 'printundermon',
+ 'processtrigger',
+ 'purgealocation',
+ 'purgeanitem',
+ 'putbackobstuff',
+ 'putundercentre',
+ 'putundermenu',
+ 'putundertimed',
+ 'putunderzoom',
+ 'quickquit',
+ 'quickquit2',
+ 'quitkey',
+ 'quitsymbol',
+ 'random',
+ 'randomaccess',
+ 'randomnum1',
+ 'randomnum2',
+ 'randomnumber',
+ 'read',
+ 'readabyte',
+ 'readcitypic',
+ 'readdesticon',
+ 'readfromfile',
+ 'readheader',
+ 'readkey',
'readmouse',
'readmouse1',
'readmouse2',
'readmouse3',
'readmouse4',
- 'waitframes',
- 'drawflags',
- 'addtopeoplelist',
- 'getexpos',
- 'paneltomap',
- 'maptopanel',
- 'dumpmap',
- 'obpicture',
- 'delthisone',
+ 'readoneblock',
+ 'readsetdata',
+ 'realcredits',
+ 'receptionist',
+ 'reconstruct',
+ 'redes',
+ 'redrawmainscrn',
+ 'reelsonscreen',
+ 'reexfrominv',
+ 'reexfromopen',
+ 'reminders',
+ 'removeemm',
+ 'removefreeobject',
+ 'removesetobject',
+ 'removeobfrominv',
+ 'resetkeyboard',
+ 'resetlocation',
+ 'restoreall',
+ 'restoreems',
+ 'restorereels',
+ 'rockstar',
+ 'rollem',
+ 'rollendcredits',
+ 'rollendcredits2',
+ 'roomname',
+ 'runendseq',
+ 'runtap',
+ 'runintroseq',
+ 'saveems',
+ 'savefileread',
+ 'savefilewrite',
+ 'savegame',
+ 'saveload',
+ 'saveposition',
+ 'saveseg',
+ 'scanfornames',
+ 'screenupdate',
+ 'scrollmonitor',
+ 'searchforfiles',
+ 'searchforsame',
+ 'searchforstring',
+ 'security',
+ 'seecommandtail',
+ 'selectlocation',
+ 'selectob',
+ 'selectopenob',
+ 'selectslot',
+ 'selectslot2',
+ 'set16colpalette',
+ 'setallchanges',
+ 'setbotleft',
+ 'setbotright',
+ 'setkeyboardint',
+ 'setlocation',
+ 'setmode',
+ 'setmouse',
+ 'setpickup',
+ 'setsoundoff',
+ 'settopleft',
+ 'settopright',
+ 'setupemm',
+ 'setuppit',
+ 'setuptimedtemp',
+ 'setuptimeduse',
+ 'setwalk',
+ 'showallex',
+ 'showallfree',
+ 'showallobs',
+ 'showarrows',
+ 'showblink',
+ 'showbyte',
+ 'showcity',
+ 'showcurrentfile',
+ 'showdecisions',
+ 'showdiary',
+ 'showdiarykeys',
+ 'showdiarypage',
+ 'showdiscops',
+ 'showexit',
+ 'showfirstuse',
+ 'showfolder',
+ 'showframe',
+ 'showgamereel',
+ 'showgroup',
+ 'showgun',
+ 'showicon',
+ 'showkeypad',
+ 'showkeys',
+ 'showleftpage',
+ 'showloadops',
+ 'showmainops',
+ 'showman',
+ 'showmenu',
+ 'showmonk',
+ 'shownames',
+ 'showopbox',
+ 'showoutermenu',
+ 'showouterpad',
+ 'showpanel',
+ 'showpcx',
+ 'showpointer',
+ 'showpuztext',
+ 'showrain',
+ 'showreelframe',
+ 'showrightpage',
+ 'showryanpage',
+ 'showsaveops',
+ 'showseconduse',
+ 'showslots',
+ 'showsymbol',
+ 'showtime',
+ 'showwatch',
+ 'showword',
+ 'signon',
+ 'singlekey',
+ 'sitdowninbar',
+ 'slabdoora',
+ 'slabdoorb',
+ 'slabdoorc',
+ 'slabdoord',
+ 'slabdoore',
+ 'slabdoorf',
+ 'smallcandle',
+ 'smokebloke',
+ 'soldier1',
+ 'sortoutmap',
+ 'soundend',
+ 'soundonreels',
+ 'soundstartup',
+ 'sparky',
+ 'sparkydrip',
+ 'splitintolines',
+ 'spriteupdate',
+ 'standardload',
+ 'startdmablock',
+ 'startloading',
+ 'startpaltoend',
+ 'starttalk',
+ 'startup',
+ 'startup1',
+ 'steady',
+ 'storeit',
+ 'swapwithinv',
+ 'swapwithopen',
+ 'switchryanoff',
+ 'switchryanon',
+ 'talk',
+ 'tattooman',
+ 'textforend',
+ 'textformonk',
+ 'titles',
+ 'train',
+ 'transfercontoex',
'transferinv',
- 'obicons',
- 'compare',
- 'pixelcheckset',
- 'turnpathon',
- 'turnpathoff',
- 'turnanypathon',
+ 'transfermap',
+ 'transfertext',
+ 'transfertoex',
+ 'trapdoor',
+ 'triggermessage',
+ 'trysoundalloc',
'turnanypathoff',
- 'isitdescribed',
- 'checkifset',
- 'checkifpathison',
- 'delsprite',
- 'dumpeverything',
- 'isitworn',
- 'makeworn',
- 'obtoinv',
- 'showryanpage',
- 'findallryan',
- 'fillryan',
+ 'turnanypathon',
+ 'turnonpower',
+ 'turnpathoff',
+ 'turnpathon',
+ 'twodigitnum',
+ 'undertextline',
+ 'updatepeople',
+ 'updatesymboltop',
+ 'updatesymbolbot',
+ 'usealtar',
+ 'useaxe',
+ 'usebalcony',
+ 'usebuttona',
+ 'usecardreader1',
+ 'usecardreader2',
+ 'usecardreader3',
+ 'usecart',
+ 'usecashcard',
+ 'usecharset1',
+ 'usechurchgate',
+ 'usechurchhole',
+ 'useclearbox',
+ 'usecontrol',
+ 'usecooker',
+ 'usecoveredbox',
+ 'usediary',
+ 'usedryer',
+ 'useelevator1',
+ 'useelevator2',
+ 'useelevator3',
+ 'useelevator4',
+ 'useelevator5',
+ 'useelvdoor',
+ 'usefullcart',
+ 'usegun',
+ 'usehandle',
+ 'usehole',
+ 'usekey',
+ 'useladder',
+ 'useladderb',
+ 'uselighter',
+ 'usehatch',
+ 'usemenu',
+ 'usemon',
+ 'useobject',
+ 'useopenbox',
+ 'useopened',
+ 'usepipe',
+ 'useplate',
+ 'useplinth',
+ 'usepoolreader',
+ 'userailing',
'useroutine',
- 'hangon',
- 'hangonp',
- 'findnextcolon',
+ 'useshield',
+ 'useslab',
+ 'usestereo',
+ 'usetempcharset',
'usetext',
- 'bresenhams',
- 'examineobtext',
+ 'usetimedtext',
+ 'usetrainer',
+ 'usewall',
+ 'usewinch',
+ 'usewindow',
+ 'usewire',
+ 'viewfolder',
+ 'vsync',
+ 'volumeadjust',
+ 'waitframes',
+ 'walkandexamine',
+ 'walking',
+ 'walkintoroom',
+ 'walktotext',
+ 'watchcount',
+ 'watchreel',
+ 'wearwatch',
+ 'wearshades',
+ 'wheelsound',
+ 'widedoor',
+ 'width160',
+ 'withwhat',
+ 'workoutframes',
+ 'worktoscreen',
+ 'worktoscreenm',
'wornerror',
+ 'zoom',
+ 'zoomicon',
+ 'zoomonoff',
], skip_output = [
# These functions are processed but not output
- 'dreamweb',
- 'backobject',
- 'mainman',
- 'madman',
- 'loadgame',
- 'savegame',
- 'zoomonoff',
- 'doload'
- ])
+ ], skip_dispatch_call = True, skip_addr_constants = True,
+ header_omit_blacklisted = True,
+ function_name_remapping = {
+ # This remaps the function naming at output for readability
+ 'aboutturn' : 'aboutTurn',
+ 'accesslightoff' : 'accessLightOff',
+ 'accesslighton' : 'accessLightOn',
+ 'actualload' : 'actualLoad',
+ 'actualsave' : 'actualSave',
+ 'addalong' : 'addAlong',
+ 'additionaltext' : 'additionalText',
+ 'addlength' : 'addLength',
+ 'addtopeoplelist' : 'addToPeopleList',
+ 'addtopresslist' : 'addToPressList',
+ 'adjustdown' : 'adjustDown',
+ 'adjustleft' : 'adjustLeft',
+ 'adjustlen' : 'adjustLen',
+ 'adjustright' : 'adjustRight',
+ 'adjustup' : 'adjustUp',
+ 'advisor' : 'advisor',
+ 'afterintroroom' : 'afterIntroRoom',
+ 'afternewroom' : 'afterNewRoom',
+ 'aide' : 'aide',
+ 'alleybarksound' : 'alleyBarkSound',
+ 'allocatebuffers' : 'allocateBuffers',
+ 'allocateload' : 'allocateLoad',
+ 'allocatemem' : 'allocateMem',
+ 'allocatework' : 'allocateWork',
+ 'allpointer' : 'allPointer',
+ 'animpointer' : 'animPointer',
+ 'atmospheres' : 'atmospheres',
+ 'attendant' : 'attendant',
+ 'autoappear' : 'autoAppear',
+ 'autolook' : 'autoLook',
+ 'autosetwalk' : 'autoSetWalk',
+ 'backobject' : 'backObject',
+ 'bartender' : 'bartender',
+ 'barwoman' : 'barWoman',
+ 'biblequote' : 'bibleQuote',
+ 'blank' : 'blank',
+ 'blockget' : 'blockGet',
+ 'blocknametext' : 'blockNameText',
+ 'bossman' : 'bossMan',
+ 'bothchannels' : 'bothChannels',
+ 'businessman' : 'businessMan',
+ 'buttoneight' : 'buttonEight',
+ 'buttonenter' : 'buttonEnter',
+ 'buttonfive' : 'buttonFive',
+ 'buttonfour' : 'buttonFour',
+ 'buttonnine' : 'buttonNine',
+ 'buttonnought' : 'buttonNought',
+ 'buttonone' : 'buttonOne',
+ 'buttonpress' : 'buttonPress',
+ 'buttonseven' : 'buttonSeven',
+ 'buttonsix' : 'buttonSix',
+ 'buttonthree' : 'buttonThree',
+ 'buttontwo' : 'buttonTwo',
+ 'calcfrframe' : 'calcFrFrame',
+ 'calcmapad' : 'calcMapAd',
+ 'calledensdlift' : 'callEdensDLift',
+ 'calledenslift' : 'callEdensLift',
+ 'callhotellift' : 'callHotelLift',
+ 'cancelch0' : 'cancelCh0',
+ 'cancelch1' : 'cancelCh1',
+ 'candles' : 'candles',
+ 'candles1' : 'candles1',
+ 'candles2' : 'candles2',
+ 'cantdrop' : 'cantDrop',
+ 'carparkdrip' : 'carParkDrip',
+ 'channel0only' : 'channel0only',
+ 'channel0tran' : 'channel0Tran',
+ 'channel1only' : 'channel1only',
+ 'checkbasemem' : 'checkBaseMem',
+ 'checkcoords' : 'checkCoords',
+ 'checkdest' : 'checkDest',
+ 'checkforemm' : 'checkForEMM',
+ 'checkforexit' : 'checkForExit',
+ 'checkforshake' : 'checkForShake',
+ 'checkifex' : 'checkIfEx',
+ 'checkiffree' : 'checkIfFree',
+ 'checkifpathison' : 'checkIfPathIsOn',
+ 'checkifperson' : 'checkIfPerson',
+ 'checkifset' : 'checkIfSet',
+ 'checkinput' : 'checkInput',
+ 'checkinside' : 'checkInside',
+ 'checkobjectsize' : 'checkObjectSize',
+ 'checkone' : 'checkOne',
+ 'checksoundint' : 'checkSoundInt',
+ 'checkspeed' : 'checkSpeed',
+ 'chewy' : 'chewy',
+ 'clearbeforeload' : 'clearBeforeLoad',
+ 'clearbuffers' : 'clearBuffers',
+ 'clearchanges' : 'clearChanges',
+ 'clearendpal' : 'clearEndPal',
+ 'clearpalette' : 'clearPalette',
+ 'clearreels' : 'clearReels',
+ 'clearrest' : 'clearRest',
+ 'clearsprites' : 'clearSprites',
+ 'clearstartpal' : 'clearStartPal',
+ 'clearwork' : 'clearWork',
+ 'closefile' : 'closeFile',
+ 'commandonly' : 'commandOnly',
+ 'commandwithob' : 'commandWithOb',
+ 'constant' : 'constant',
+ 'convertkey' : 'convertKey',
+ 'convicons' : 'convIcons',
+ 'convnum' : 'convNum',
+ 'copper' : 'copper',
+ 'copyname' : 'copyName',
+ 'createfile' : 'createFile',
+ 'createname' : 'createName',
+ 'createpanel' : 'createPanel',
+ 'createpanel2' : 'createPanel2',
+ 'credits' : 'credits',
+ 'crosshair' : 'crossHair',
+ 'deallocatemem' : 'deallocateMem',
+ 'dealwithspecial' : 'dealWithSpecial',
+ 'decide' : 'decide',
+ 'delchar' : 'delChar',
+ 'delcurs' : 'delCurs',
+ 'deleteexframe' : 'deleteExFrame',
+ 'deleteexobject' : 'deleteExObject',
+ 'deleteextext' : 'deleteExText',
+ 'deletetaken' : 'deleteTaken',
+ 'deleverything' : 'delEverything',
+ 'delpointer' : 'delPointer',
+ 'delsprite' : 'delSprite',
+ 'deltextline' : 'delTextLine',
+ 'delthisone' : 'delThisOne',
+ 'describeob' : 'describeOb',
+ 'destselect' : 'destSelect',
+ 'diarykeyn' : 'diaryKeyN',
+ 'diarykeyp' : 'diaryKeyP',
+ 'dircom' : 'dirCom',
+ 'dirfile' : 'dirFile',
+ 'disablepath' : 'disablePath',
+ 'disablesoundint' : 'disableSoundInt',
+ 'discops' : 'discOps',
+ 'dmaend' : 'DMAEnd',
+ 'doblocks' : 'doBlocks',
+ 'dochange' : 'doChange',
+ 'dodoor' : 'doDoor',
+ 'doload' : 'doLoad',
+ 'dolook' : 'doLook',
+ 'domix' : 'doMix',
+ 'dontloadseg' : 'dontLoadSeg',
+ 'dosaveload' : 'doSaveLoad',
+ 'doshake' : 'doShake',
+ 'dosometalk' : 'doSomeTalk',
+ 'dosreturn' : 'DOSReturn',
+ 'drawflags' : 'drawFlags',
+ 'drawfloor' : 'drawFloor',
+ 'drawitall' : 'drawItAll',
+ 'dreamweb' : 'dreamweb',
+ 'drinker' : 'drinker',
+ 'droperror' : 'dropError',
+ 'dropobject' : 'dropObject',
+ 'drunk' : 'drunk',
+ 'dumpblink' : 'dumpBlink',
+ 'dumpdiarykeys' : 'dumpDiaryKeys',
+ 'dumpeverything' : 'dumpEverything',
+ 'dumpkeypad' : 'dumpKeypad',
+ 'dumpmap' : 'dumpMap',
+ 'dumpmenu' : 'dumpMenu',
+ 'dumppointer' : 'dumpPointer',
+ 'dumpsymbol' : 'dumpSymbol',
+ 'dumpsymbox' : 'dumpSymBox',
+ 'dumptextline' : 'dumpTextLine',
+ 'dumptimedtext' : 'dumpTimedText',
+ 'dumpwatch' : 'dumpWatch',
+ 'dumpzoom' : 'dumpZoom',
+ 'eden' : 'eden',
+ 'edeninbath' : 'edenInBath',
+ 'edenscdplayer' : 'edensCDPlayer',
+ 'emergencypurge' : 'emergencyPurge',
+ 'enablesoundint' : 'enableSoundInt',
+ 'endgame' : 'endGame',
+ 'endgameseq' : 'endGameSeq',
+ 'endpaltostart' : 'endPalToStart',
+ 'entercode' : 'enterCode',
+ 'entersymbol' : 'enterSymbol',
+ 'entryanims' : 'entryAnims',
+ 'entrytexts' : 'entryTexts',
+ 'eraseoldobs' : 'eraseOldObs',
+ 'error' : 'error',
+ 'errormessage1' : 'errorMessage1',
+ 'errormessage2' : 'errorMessage2',
+ 'errormessage3' : 'errorMessage3',
+ 'examicon' : 'examIcon',
+ 'examineob' : 'examineOb',
+ 'examineobtext' : 'examineObText',
+ 'examinventory' : 'examineInventory',
+ 'execcommand' : 'execCommand',
+ 'facerightway' : 'faceRightWay',
+ 'fadecalculation' : 'fadeCalculation',
+ 'fadedownmon' : 'fadeDownMon',
+ 'fadefromwhite' : 'fadeFromWhite',
+ 'fadescreendown' : 'fadeScreenDown',
+ 'fadescreendownhalf' : 'fadeScreenDownHalf',
+ 'fadescreendowns' : 'fadeScreenDowns',
+ 'fadescreenup' : 'fadeScreenUp',
+ 'fadescreenuphalf' : 'fadeScreenUpHalf',
+ 'fadescreenups' : 'fadeScreenUps',
+ 'fadetowhite' : 'fadeToWhite',
+ 'fadeupmon' : 'fadeUpMon',
+ 'fadeupmonfirst' : 'fadeUpMonFirst',
+ 'fadeupyellows' : 'fadeUpYellows',
+ 'femalefan' : 'femaleFan',
+ 'fillopen' : 'fillOpen',
+ 'fillryan' : 'fillRyan',
+ 'fillspace' : 'fillSpace',
+ 'finalframe' : 'finalFrame',
+ 'findallopen' : 'findAllOpen',
+ 'findallryan' : 'findAllRyan',
+ 'findexobject' : 'findExObject',
+ 'findfirstpath' : 'findFirstPath',
+ 'findinvpos' : 'findInvPos',
+ 'findlen' : 'findLen',
+ 'findnextcolon' : 'findNextColon',
+ 'findobname' : 'findObName',
+ 'findopenpos' : 'findOpenPos',
+ 'findormake' : 'findOrMake',
+ 'findpathofpoint' : 'findPathOfPoint',
+ 'findpuztext' : 'findPuzText',
+ 'findroominloc' : 'findRoomInLoc',
+ 'findsetobject' : 'findSetObject',
+ 'findsource' : 'findSource',
+ 'findtext1' : 'findText1',
+ 'findxyfrompath' : 'findXYFromPath',
+ 'finishedwalking' : 'finishedWalking',
+ 'foghornsound' : 'foghornSound',
+ 'folderexit' : 'folderExit',
+ 'folderhints' : 'folderHints',
+ 'frameoutbh' : 'frameOutbh',
+ 'frameoutfx' : 'frameOutfx',
+ 'frameoutnm' : 'frameOutnm',
+ 'frameoutv' : 'frameOutV',
+ 'gamer' : 'gamer',
+ 'gates' : 'gates',
+ 'generalerror' : 'generalError',
+ 'getanyad' : 'getAnyAd',
+ 'getanyaddir' : 'getAnyAdDir',
+ 'getback1' : 'getBack1',
+ 'getbackfromob' : 'getBackFromOb',
+ 'getbackfromops' : 'getBackFromOps',
+ 'getbacktoops' : 'getBackToOps',
+ 'getblockofpixel' : 'getBlockOfPixel',
+ 'getdestinfo' : 'getDestInfo',
+ 'getdimension' : 'getDimension',
+ 'geteitherad' : 'getEitherAd',
+ 'getexad' : 'getExAd',
+ 'getexpos' : 'getExPos',
+ 'getflagunderp' : 'getFlagUnderP',
+ 'getfreead' : 'getFreeAd',
+ 'getkeyandlogo' : 'getKeyAndLogo',
+ 'getlocation' : 'getLocation',
+ 'getmapad' : 'getMapAd',
+ 'getnamepos' : 'getNamePos',
+ 'getnextword' : 'getNextWord',
+ 'getnumber' : 'getNumber',
+ 'getobtextstart' : 'getObTextStart',
+ 'getopenedsize' : 'getOpenedSize',
+ 'getpersframe' : 'getPersFrame',
+ 'getpersontext' : 'getPersonText',
+ 'getreelframeax' : 'getReelFrameAX',
+ 'getreelstart' : 'getReelStart',
+ 'getridofall' : 'getRidOfAll',
+ 'getridofpit' : 'getRidOfPit',
+ 'getridofpitsetuppit' : 'getRidOfPitSetupPit',
+ 'getridofreels' : 'getRidOfReels',
+ 'getridoftemp' : 'getRidOfTemp',
+ 'getridoftemp2' : 'getRidOfTemp2',
+ 'getridoftemp3' : 'getRidOfTemp3',
+ 'getridoftempcharset' : 'getRidOfTempCharset',
+ 'getridoftempsp' : 'getRidOfTempsP',
+ 'getridoftemptext' : 'getRidOfTempText',
+ 'getroomdata' : 'getRoomData',
+ 'getroomspaths' : 'getRoomsPaths',
+ 'getsetad' : 'getSetAd',
+ 'gettime' : 'getTime',
+ 'gettingshot' : 'gettingShot',
+ 'getundercentre' : 'getUnderCentre',
+ 'getundermenu' : 'getUnderMenu',
+ 'getundertimed' : 'getUnderTimed',
+ 'getunderzoom' : 'getUnderZoom',
+ 'getxad' : 'getXAd',
+ 'getyad' : 'getYAd',
+ 'grafittidoor' : 'grafittiDoor',
+ 'handclap' : 'handClap',
+ 'hangon' : 'hangOn',
+ 'hangoncurs' : 'hangOnCurs',
+ 'hangone' : 'hangOne',
+ 'hangonp' : 'hangOnP',
+ 'hangonpq' : 'hangOnPQ',
+ 'hangonw' : 'hangOnW',
+ 'heavy' : 'heavy',
+ 'helicopter' : 'helicopter',
+ 'hotelbell' : 'hotelBell',
+ 'hotelcontrol' : 'hotelControl',
+ 'identifyob' : 'identifyOb',
+ 'incryanpage' : 'incRyanPage',
+ 'initialinv' : 'initialInv',
+ 'initialmoncols' : 'initialMonCols',
+ 'initman' : 'initMan',
+ 'initrain' : 'initRain',
+ 'interupttest' : 'interruptTest',
+ 'interviewer' : 'interviewer',
+ 'intoinv' : 'inToInv',
+ 'intro' : 'intro',
+ 'intro1text' : 'intro1Text',
+ 'intro2text' : 'intro2Text',
+ 'intro3text' : 'intro3Text',
+ 'intromagic1' : 'introMagic1',
+ 'intromagic2' : 'introMagic2',
+ 'intromagic3' : 'introMagic3',
+ 'intromonks1' : 'introMonks1',
+ 'intromonks2' : 'introMonks2',
+ 'intromusic' : 'introMusic',
+ 'inventory' : 'inventory',
+ 'isitdescribed' : 'isItDescribed',
+ 'isitright' : 'isItRight',
+ 'isitworn' : 'isItWorn',
+ 'isryanholding' : 'isRyanHolding',
+ 'issetobonmap' : 'isSetObOnMap',
+ 'keeper' : 'keeper',
+ 'kernchars' : 'kernChars',
+ 'keyboardread' : 'keyboardRead',
+ 'lastdest' : 'lastDest',
+ 'lastfolder' : 'lastFolder',
+ 'liftnoise' : 'liftNoise',
+ 'liftsprite' : 'liftSprite',
+ 'loadcart' : 'loadCart',
+ 'loadfolder' : 'loadFolder',
+ 'loadgame' : 'loadGame',
+ 'loadintotemp' : 'loadIntoTemp',
+ 'loadintotemp2' : 'loadIntoTemp2',
+ 'loadintotemp3' : 'loadIntoTemp3',
+ 'loadintroroom' : 'loadIntroRoom',
+ 'loadkeypad' : 'loadKeypad',
+ 'loadmenu' : 'loadMenu',
+ 'loadnews' : 'loadNews',
+ 'loadold' : 'loadOld',
+ 'loadpalfromiff' : 'loadPalFromIFF',
+ 'loadpersonal' : 'loadPersonal',
+ 'loadposition' : 'loadPosition',
+ 'loadroom' : 'loadRoom',
+ 'loadroomssample' : 'loadRoomsSample',
+ 'loadsample' : 'loadSample',
+ 'loadsavebox' : 'loadSaveBox',
+ 'loadsecondsample' : 'loadSecondSample',
+ 'loadseg' : 'loadSeg',
+ 'loadspeech' : 'loadSpeech',
+ 'loadtempcharset' : 'loadTempCharset',
+ 'loadtemptext' : 'loadTempText',
+ 'loadtraveltext' : 'loadTravelText',
+ 'locationpic' : 'locationPic',
+ 'lockeddoorway' : 'lockedDoorway',
+ 'locklightoff' : 'lockLightOff',
+ 'locklighton' : 'lockLightOn',
+ 'lockmon' : 'lockMon',
+ 'lookatcard' : 'lookAtCard',
+ 'lookatplace' : 'lookAtPlace',
+ 'lookininterface' : 'lookInInterface',
+ 'loopchannel0' : 'loopChannel0',
+ 'louis' : 'louis',
+ 'louischair' : 'louisChair',
+ 'madman' : 'madman',
+ 'madmanrun' : 'madmanRun',
+ 'madmanstelly' : 'madmansTelly',
+ 'madmantext' : 'madmanText',
+ 'madmode' : 'madMode',
+ 'mainman' : 'mainMan',
+ 'mainscreen' : 'mainScreen',
+ 'makebackob' : 'makeBackOb',
+ 'makecaps' : 'makeCaps',
+ 'makeheader' : 'makeHeader',
+ 'makemainscreen' : 'makeMainScreen',
+ 'makename' : 'makeName',
+ 'makenextblock' : 'makeNextBlock',
+ 'makesprite' : 'makeSprite',
+ 'makeworn' : 'makeWorn',
+ 'malefan' : 'maleFan',
+ 'manasleep' : 'manAsleep',
+ 'manasleep2' : 'manAsleep2',
+ 'mansatstill' : 'manSatStill',
+ 'maptopanel' : 'mapToPanel',
+ 'middlepanel' : 'middlePanel',
+ 'mode640x480' : 'mode640x480',
+ 'modifychar' : 'modifyChar',
+ 'moneypoke' : 'moneyPoke',
+ 'monitorlogo' : 'monitorLogo',
+ 'monkandryan' : 'monkAndRyan',
+ 'monks2text' : 'monks2text',
+ 'monkspeaking' : 'monkSpeaking',
+ 'monmessage' : 'monMessage',
+ 'monprint' : 'monPrint',
+ 'moretalk' : 'moreTalk',
+ 'mousecall' : 'mouseCall',
+ 'movemap' : 'moveMap',
+ 'mugger' : 'mugger',
+ 'multidump' : 'multiDump',
+ 'multiget' : 'multiGet',
+ 'multiput' : 'multiPut',
+ 'namestoold' : 'namesToOld',
+ 'neterror' : 'netError',
+ 'newgame' : 'newGame',
+ 'newplace' : 'newPlace',
+ 'nextcolon' : 'nextColon',
+ 'nextdest' : 'nextDest',
+ 'nextfolder' : 'nextFolder',
+ 'nextsymbol' : 'nextSymbol',
+ 'obicons' : 'obIcons',
+ 'obname' : 'obName',
+ 'obpicture' : 'obPicture',
+ 'obsthatdothings' : 'obsThatDoThings',
+ 'obtoinv' : 'obToInv',
+ 'oldtonames' : 'oldToNames',
+ 'onedigit' : 'oneDigit',
+ 'openeden' : 'openEden',
+ 'openfile' : 'openFile',
+ 'openfilefromc' : 'openFileFromC',
+ 'openfilenocheck' : 'openFileNoCheck',
+ 'openforsave' : 'openForSave',
+ 'openhoteldoor' : 'openHotelDoor',
+ 'openhoteldoor2' : 'openHotelDoor2',
+ 'openinv' : 'openInv',
+ 'openlouis' : 'openLouis',
+ 'openob' : 'openOb',
+ 'openpoolboss' : 'openPoolBoss',
+ 'openryan' : 'openRyan',
+ 'opensarters' : 'openSarters',
+ 'opentomb' : 'openTomb',
+ 'opentvdoor' : 'openTVDoor',
+ 'openyourneighbour' : 'openYourNeighbour',
+ 'othersmoker' : 'otherSmoker',
+ 'out22c' : 'out22c',
+ 'outofinv' : 'outOfInv',
+ 'outofopen' : 'outOfOpen',
+ 'paltoendpal' : 'palToEndPal',
+ 'paltostartpal' : 'palToStartPal',
+ 'panelicons1' : 'panelIcons1',
+ 'paneltomap' : 'panelToMap',
+ 'parseblaster' : 'parseBlaster',
+ 'parser' : 'parser',
+ 'personnametext' : 'personNameText',
+ 'pickupconts' : 'pickupConts',
+ 'pickupob' : 'pickupOb',
+ 'pitinterupt' : 'pitInterrupt',
+ 'pixelcheckset' : 'pixelCheckSet',
+ 'placefreeobject' : 'placeFreeObject',
+ 'placesetobject' : 'placeSetObject',
+ 'playchannel0' : 'playChannel0',
+ 'playchannel1' : 'playChannel1',
+ 'playguitar' : 'playGuitar',
+ 'plotreel' : 'plotReel',
+ 'poolguard' : 'poolGuard',
+ 'powerlightoff' : 'powerLightOff',
+ 'powerlighton' : 'powerLightOn',
+ 'priest' : 'priest',
+ 'priesttext' : 'priestText',
+ 'printasprite' : 'printASprite',
+ 'printboth' : 'printBoth',
+ 'printchar' : 'printChar',
+ 'printcurs' : 'printCurs',
+ 'printdirect' : 'printDirect',
+ 'printlogo' : 'printLogo',
+ 'printmessage' : 'printMessage',
+ 'printmessage2' : 'printMessage2',
+ 'printoutermon' : 'printOuterMon',
+ 'printslow' : 'printSlow',
+ 'printsprites' : 'printSprites',
+ 'printundermon' : 'printUnderMon',
+ 'processtrigger' : 'processTrigger',
+ 'purgealocation' : 'purgeALocation',
+ 'purgeanitem' : 'purgeAnItem',
+ 'putbackobstuff' : 'putBackObStuff',
+ 'putundercentre' : 'putUnderCentre',
+ 'putundermenu' : 'putUnderMenu',
+ 'putundertimed' : 'putUnderTimed',
+ 'putunderzoom' : 'putUnderZoom',
+ 'quickquit' : 'quickQuit',
+ 'quickquit2' : 'quickQuit2',
+ 'quitkey' : 'quitKey',
+ 'quitsymbol' : 'quitSymbol',
+ 'random' : 'random',
+ 'randomaccess' : 'randomAccess',
+ 'randomnum1' : 'randomNum1',
+ 'randomnum2' : 'randomNum2',
+ 'randomnumber' : 'randomNumber',
+ 'read' : 'read',
+ 'readabyte' : 'readAByte',
+ 'readcitypic' : 'readCityPic',
+ 'readdesticon' : 'readDestIcon',
+ 'readfromfile' : 'readFromFile',
+ 'readheader' : 'readHeader',
+ 'readkey' : 'readKey',
+ 'readmouse' : 'readMouse',
+ 'readmouse1' : 'readMouse1',
+ 'readmouse2' : 'readMouse2',
+ 'readmouse3' : 'readMouse3',
+ 'readmouse4' : 'readMouse4',
+ 'readoneblock' : 'readOneBlock',
+ 'readsetdata' : 'readSetData',
+ 'realcredits' : 'realCredits',
+ 'receptionist' : 'receptionist',
+ 'redes' : 'redes',
+ 'redrawmainscrn' : 'redrawMainScrn',
+ 'reelsonscreen' : 'reelsOnScreen',
+ 'reexfrominv' : 'reExFromInv',
+ 'reexfromopen' : 'reExFromOpen',
+ 'reminders' : 'reminders',
+ 'removeemm' : 'removeEMM',
+ 'removefreeobject' : 'removeFreeObject',
+ 'removeobfrominv' : 'removeObFromInv',
+ 'removesetobject' : 'removeSetObject',
+ 'resetkeyboard' : 'resetKeyboard',
+ 'resetlocation' : 'resetLocation',
+ 'restoreall' : 'restoreAll',
+ 'restoreems' : 'restoreEMS',
+ 'restorereels' : 'restoreReels',
+ 'rockstar' : 'rockstar',
+ 'rollem' : 'rollEm',
+ 'rollendcredits' : 'rollEndCredits',
+ 'rollendcredits2' : 'rollEndCredits2',
+ 'roomname' : 'roomName',
+ 'runendseq' : 'runEndSeq',
+ 'runintroseq' : 'runIntroSeq',
+ 'runtap' : 'runTap',
+ 'saveems' : 'saveEMS',
+ 'savefileread' : 'saveFileRead',
+ 'savefilewrite' : 'savefileWrite',
+ 'savegame' : 'saveGame',
+ 'saveload' : 'saveLoad',
+ 'saveposition' : 'savePosition',
+ 'saveseg' : 'saveSeg',
+ 'scanfornames' : 'scanForNames',
+ 'screenupdate' : 'screenUpdate',
+ 'scrollmonitor' : 'scrollMonitor',
+ 'searchforfiles' : 'searchForFiles',
+ 'searchforsame' : 'searchForSame',
+ 'searchforstring' : 'searchForString',
+ 'security' : 'security',
+ 'seecommandtail' : 'seeCommandTail',
+ 'selectlocation' : 'selectLocation',
+ 'selectob' : 'selectOb',
+ 'selectopenob' : 'selectOpenOb',
+ 'selectslot' : 'selectSlot',
+ 'selectslot2' : 'selectSlot2',
+ 'set16colpalette' : 'set16ColPalette',
+ 'setallchanges' : 'setAllChanges',
+ 'setbotleft' : 'setBotLeft',
+ 'setbotright' : 'setBotRight',
+ 'setkeyboardint' : 'setKeyboardInt',
+ 'setlocation' : 'setLocation',
+ 'setmode' : 'setMode',
+ 'setmouse' : 'setMouse',
+ 'setpickup' : 'setPickup',
+ 'setsoundoff' : 'setSoundOff',
+ 'settopleft' : 'setTopLeft',
+ 'settopright' : 'setTopRight',
+ 'setupemm' : 'setupEMM',
+ 'setuppit' : 'setupPit',
+ 'setuptimedtemp' : 'setupTimedTemp',
+ 'setuptimeduse' : 'setupTimedUse',
+ 'setwalk' : 'setWalk',
+ 'showallex' : 'showAllEx',
+ 'showallfree' : 'showAllFree',
+ 'showallobs' : 'showAllObs',
+ 'showarrows' : 'showArrows',
+ 'showblink' : 'showBlink',
+ 'showbyte' : 'showByte',
+ 'showcity' : 'showCity',
+ 'showcurrentfile' : 'showCurrentFile',
+ 'showdecisions' : 'showDecisions',
+ 'showdiary' : 'showDiary',
+ 'showdiarykeys' : 'showDiaryKeys',
+ 'showdiarypage' : 'showDiaryPage',
+ 'showdiscops' : 'showDiscOps',
+ 'showexit' : 'showExit',
+ 'showfirstuse' : 'showFirstUse',
+ 'showfolder' : 'showFolder',
+ 'showframe' : 'showFrame',
+ 'showgamereel' : 'showGameReel',
+ 'showgroup' : 'showGroup',
+ 'showgun' : 'showGun',
+ 'showicon' : 'showIcon',
+ 'showkeypad' : 'showKeypad',
+ 'showkeys' : 'showKeys',
+ 'showleftpage' : 'showLeftPage',
+ 'showloadops' : 'showLoadOps',
+ 'showmainops' : 'showMainOps',
+ 'showman' : 'showMan',
+ 'showmenu' : 'showMenu',
+ 'showmonk' : 'showMonk',
+ 'shownames' : 'showNames',
+ 'showopbox' : 'showOpBox',
+ 'showoutermenu' : 'showOuterMenu',
+ 'showouterpad' : 'showOuterPad',
+ 'showpanel' : 'showPanel',
+ 'showpcx' : 'showPCX',
+ 'showpointer' : 'showPointer',
+ 'showpuztext' : 'showPuzText',
+ 'showrain' : 'showRain',
+ 'showreelframe' : 'showReelFrame',
+ 'showrightpage' : 'showRightPage',
+ 'showryanpage' : 'showRyanPage',
+ 'showsaveops' : 'showSaveOps',
+ 'showseconduse' : 'showSecondUse',
+ 'showslots' : 'showSlots',
+ 'showsymbol' : 'showSymbol',
+ 'showtime' : 'showTime',
+ 'showwatch' : 'showWatch',
+ 'showword' : 'showWord',
+ 'signon' : 'signOn',
+ 'singlekey' : 'singleKey',
+ 'sitdowninbar' : 'sitDownInBar',
+ 'slabdoora' : 'slabDoorA',
+ 'slabdoorb' : 'slabDoorB',
+ 'slabdoorc' : 'slabDoorC',
+ 'slabdoord' : 'slabDoorD',
+ 'slabdoore' : 'slabDoorE',
+ 'slabdoorf' : 'slabDoorF',
+ 'smallcandle' : 'smallCandle',
+ 'smokebloke' : 'smokeBloke',
+ 'soldier1' : 'soldier1',
+ 'sortoutmap' : 'sortOutMap',
+ 'soundend' : 'soundEnd',
+ 'soundonreels' : 'soundOnReels',
+ 'soundstartup' : 'soundStartup',
+ 'sparky' : 'sparky',
+ 'sparkydrip' : 'sparkyDrip',
+ 'splitintolines' : 'splitIntoLines',
+ 'spriteupdate' : 'spriteUpdate',
+ 'standardload' : 'standardLoad',
+ 'startdmablock' : 'startDMABlock',
+ 'startloading' : 'startLoading',
+ 'startpaltoend' : 'startPalToEnd',
+ 'starttalk' : 'startTalk',
+ 'steady' : 'steady',
+ 'storeit' : 'storeIt',
+ 'swapwithinv' : 'swapWithInv',
+ 'swapwithopen' : 'swapWithOpen',
+ 'switchryanoff' : 'switchRyanOff',
+ 'switchryanon' : 'switchRyanOn',
+ 'talk' : 'talk',
+ 'tattooman' : 'tattooMan',
+ 'textforend' : 'textForEnd',
+ 'textformonk' : 'textForMonk',
+ 'titles' : 'titles',
+ 'train' : 'train',
+ 'transfercontoex' : 'transferConToEx',
+ 'transferinv' : 'transferInv',
+ 'transfermap' : 'transferMap',
+ 'transfertext' : 'transferText',
+ 'transfertoex' : 'transferToEx',
+ 'trapdoor' : 'trapDoor',
+ 'triggermessage' : 'triggerMessage',
+ 'trysoundalloc' : 'trySoundAlloc',
+ 'turnanypathoff' : 'turnAnyPathOff',
+ 'turnanypathon' : 'turnAnyPathOn',
+ 'turnonpower' : 'turnOnPower',
+ 'turnpathoff' : 'turnPathOff',
+ 'turnpathon' : 'turnPathOn',
+ 'twodigitnum' : 'twoDigitNum',
+ 'undertextline' : 'underTextLine',
+ 'updatepeople' : 'updatePeople',
+ 'updatesymbolbot' : 'updateSymbolBot',
+ 'updatesymboltop' : 'updateSymbolTop',
+ 'usealtar' : 'useAltar',
+ 'useaxe' : 'useAxe',
+ 'usebalcony' : 'useBalcony',
+ 'usebuttona' : 'useButtonA',
+ 'usecardreader1' : 'useCardReader1',
+ 'usecardreader2' : 'useCardReader2',
+ 'usecardreader3' : 'useCardReader3',
+ 'usecart' : 'useCart',
+ 'usecashcard' : 'useCashCard',
+ 'usecharset1' : 'useCharset1',
+ 'usechurchgate' : 'useChurchGate',
+ 'usechurchhole' : 'useChurchHole',
+ 'useclearbox' : 'useClearBox',
+ 'usecontrol' : 'useControl',
+ 'usecooker' : 'useCooker',
+ 'usecoveredbox' : 'useCoveredBox',
+ 'usediary' : 'useDiary',
+ 'usedryer' : 'useDryer',
+ 'useelevator1' : 'useElevator1',
+ 'useelevator2' : 'useElevator2',
+ 'useelevator3' : 'useElevator3',
+ 'useelevator4' : 'useElevator4',
+ 'useelevator5' : 'useElevator5',
+ 'useelvdoor' : 'useElvDoor',
+ 'usefullcart' : 'useFullCart',
+ 'usegun' : 'useGun',
+ 'usehandle' : 'useHandle',
+ 'usehatch' : 'useHatch',
+ 'usehole' : 'useHole',
+ 'usekey' : 'useKey',
+ 'useladder' : 'useLadder',
+ 'useladderb' : 'useLadderB',
+ 'uselighter' : 'useLighter',
+ 'usemenu' : 'useMenu',
+ 'usemon' : 'useMon',
+ 'useobject' : 'useObject',
+ 'useopenbox' : 'useOpenBox',
+ 'useopened' : 'useOpened',
+ 'usepipe' : 'usePipe',
+ 'useplate' : 'usePlate',
+ 'useplinth' : 'usePlinth',
+ 'usepoolreader' : 'usePoolReader',
+ 'userailing' : 'useRailing',
+ 'useroutine' : 'useRoutine',
+ 'useshield' : 'useShield',
+ 'useslab' : 'useSlab',
+ 'usestereo' : 'useStereo',
+ 'usetempcharset' : 'useTempCharset',
+ 'usetext' : 'useText',
+ 'usetimedtext' : 'useTimedText',
+ 'usetrainer' : 'useTrainer',
+ 'usewall' : 'useWall',
+ 'usewinch' : 'useWinch',
+ 'usewindow' : 'useWindow',
+ 'usewire' : 'useWire',
+ 'viewfolder' : 'viewFolder',
+ 'vsync' : 'vSync',
+ 'waitframes' : 'waitFrames',
+ 'walkandexamine' : 'walkAndExamine',
+ 'walkintoroom' : 'walkIntoRoom',
+ 'walktotext' : 'walkToText',
+ 'watchcount' : 'watchCount',
+ 'watchreel' : 'watchReel',
+ 'wearshades' : 'wearShades',
+ 'wearwatch' : 'wearWatch',
+ 'wheelsound' : 'wheelSound',
+ 'widedoor' : 'wideDoor',
+ 'withwhat' : 'withWhat',
+ 'worktoscreen' : 'workToScreen',
+ 'worktoscreenm' : 'workToScreenM',
+ 'wornerror' : 'wornError',
+ 'zoomicon' : 'zoomIcon',
+ 'zoomonoff' : 'zoomOnOff',
+ })
generator.generate('dreamweb') #start routine
diff --git a/devtools/tasmrecover/tasm/cpp.py b/devtools/tasmrecover/tasm/cpp.py
index 61edb41fb2..e1f8228ab7 100644
--- a/devtools/tasmrecover/tasm/cpp.py
+++ b/devtools/tasmrecover/tasm/cpp.py
@@ -33,7 +33,7 @@ def parse_bin(s):
return v
class cpp:
- def __init__(self, context, namespace, skip_first = 0, blacklist = [], skip_output = []):
+ def __init__(self, context, namespace, skip_first = 0, blacklist = [], skip_output = [], skip_dispatch_call = False, skip_addr_constants = False, header_omit_blacklisted = False, function_name_remapping = { }):
self.namespace = namespace
fname = namespace.lower() + ".cpp"
header = namespace.lower() + ".h"
@@ -60,7 +60,6 @@ class cpp:
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/
-
"""
self.fd = open(fname, "wt")
self.hd = open(header, "wt")
@@ -68,9 +67,7 @@ class cpp:
self.hd.write("""#ifndef %s
#define %s
-%s
-
-""" %(hid, hid, banner))
+%s""" %(hid, hid, banner))
self.context = context
self.data_seg = context.binary_data
self.procs = context.proc_list
@@ -80,12 +77,15 @@ class cpp:
self.blacklist = blacklist
self.failed = list(blacklist)
self.skip_output = skip_output
+ self.skip_dispatch_call = skip_dispatch_call
+ self.skip_addr_constants = skip_addr_constants
+ self.header_omit_blacklisted = header_omit_blacklisted
+ self.function_name_remapping = function_name_remapping
self.translated = []
self.proc_addr = []
self.used_data_offsets = set()
self.methods = []
self.fd.write("""%s
-
#include \"%s\"
namespace %s {
@@ -286,7 +286,10 @@ namespace %s {
jump_proc = True
if jump_proc:
- return "{ %s(); return; }" %name
+ if name in self.function_name_remapping:
+ return "{ %s(); return; }" %self.function_name_remapping[name]
+ else:
+ return "{ %s(); return; }" %name
else:
# TODO: name or self.resolve_label(name) or self.mangle_label(name)??
if name in self.proc.retlabels:
@@ -308,7 +311,10 @@ namespace %s {
if name == 'ax':
self.body += "\t__dispatch_call(%s);\n" %self.expand('ax', 2)
return
- self.body += "\t%s();\n" %name
+ if name in self.function_name_remapping:
+ self.body += "\t%s();\n" %self.function_name_remapping[name]
+ else:
+ self.body += "\t%s();\n" %name
self.schedule(name)
def _ret(self):
@@ -499,7 +505,10 @@ namespace %s {
self.proc_addr.append((name, self.proc.offset))
self.body = str()
- self.body += "void %sContext::%s() {\n\tSTACK_CHECK;\n" %(self.namespace, name);
+ if name in self.function_name_remapping:
+ self.body += "void %sContext::%s() {\n\tSTACK_CHECK;\n" %(self.namespace, self.function_name_remapping[name]);
+ else:
+ self.body += "void %sContext::%s() {\n\tSTACK_CHECK;\n" %(self.namespace, name);
self.proc.optimize()
self.unbounded = []
self.proc.visit(self, skip)
@@ -550,8 +559,11 @@ namespace %s {
fd = open(fname, "wt")
fd.write("namespace %s {\n" %self.namespace)
for p in procs:
- fd.write("void %sContext::%s() {\n\t::error(\"%s\");\n}\n\n" %(self.namespace, p, p))
- fd.write("} /*namespace %s */\n" %self.namespace)
+ if p in self.function_name_remapping:
+ fd.write("void %sContext::%s() {\n\t::error(\"%s\");\n}\n\n" %(self.namespace, self.function_name_remapping[p], self.function_name_remapping[p]))
+ else:
+ fd.write("void %sContext::%s() {\n\t::error(\"%s\");\n}\n\n" %(self.namespace, p, p))
+ fd.write("} // End of namespace %s\n" %self.namespace)
fd.close()
@@ -578,7 +590,7 @@ namespace %s {
self.fd.write("\n")
self.fd.write("\n".join(self.translated))
- self.fd.write("\n\n")
+ self.fd.write("\n")
print "%d ok, %d failed of %d, %.02g%% translated" %(done, failed, done + failed, 100.0 * done / (done + failed))
print "\n".join(self.failed)
data_bin = self.data_seg
@@ -596,26 +608,25 @@ namespace %s {
elif (n & 0x3) == 0:
comment += " "
data_impl += "};\n\tds.assign(src, src + sizeof(src));\n"
+
self.hd.write(
"""\n#include "dreamweb/runtime.h"
+#include "dreamweb/structs.h"
+#include "dreamweb/dreambase.h"
+
namespace %s {
-#include "structs.h"
-class %sContext : public Context {
-public:
- void __start();
- void __dispatch_call(uint16 addr);
-#include "stubs.h" // Allow hand-reversed functions to have a signature different than void f()
-"""
-%(self.namespace, self.namespace))
+"""
+%(self.namespace))
- for name,addr in self.proc_addr:
- self.hd.write("\tstatic const uint16 addr_%s = 0x%04x;\n" %(name, addr))
+ if self.skip_addr_constants == False:
+ for name,addr in self.proc_addr:
+ self.hd.write("static const uint16 addr_%s = 0x%04x;\n" %(name, addr))
for name,addr in self.used_data_offsets:
- self.hd.write("\tstatic const uint16 offset_%s = 0x%04x;\n" %(name, addr))
+ self.hd.write("static const uint16 offset_%s = 0x%04x;\n" %(name, addr))
offsets = []
for k, v in self.context.get_globals().items():
@@ -626,24 +637,46 @@ public:
offsets = sorted(offsets, key=lambda t: t[1])
for o in offsets:
- self.hd.write("\tstatic const uint16 k%s = %s;\n" %o)
+ self.hd.write("static const uint16 k%s = %s;\n" %o)
self.hd.write("\n")
+
+ self.hd.write(
+"""
+class %sContext : public DreamBase, public Context {
+public:
+ DreamGenContext(DreamWeb::DreamWebEngine *en) : DreamBase(en), Context(this) {}
+
+ void __start();
+"""
+%(self.namespace))
+ if self.skip_dispatch_call == False:
+ self.hd.write(
+""" void __dispatch_call(uint16 addr);
+""")
+
+
for p in set(self.methods):
if p in self.blacklist:
- self.hd.write("\t//void %s();\n" %p)
+ if self.header_omit_blacklisted == False:
+ self.hd.write("\t//void %s();\n" %p)
else:
- self.hd.write("\tvoid %s();\n" %p)
+ if p in self.function_name_remapping:
+ self.hd.write("\tvoid %s();\n" %self.function_name_remapping[p])
+ else:
+ self.hd.write("\tvoid %s();\n" %p)
- self.hd.write("};\n}\n\n#endif\n")
+ self.hd.write("};\n\n} // End of namespace DreamGen\n\n#endif\n")
self.hd.close()
- self.fd.write("\nvoid %sContext::__start() { %s%s(); \n}\n" %(self.namespace, data_impl, start))
+ self.fd.write("void %sContext::__start() { %s\t%s(); \n}\n" %(self.namespace, data_impl, start))
- self.fd.write("\nvoid %sContext::__dispatch_call(uint16 addr) {\n\tswitch(addr) {\n" %self.namespace)
- self.proc_addr.sort(cmp = lambda x, y: x[1] - y[1])
- for name,addr in self.proc_addr:
- self.fd.write("\t\tcase addr_%s: %s(); break;\n" %(name, name))
- self.fd.write("\t\tdefault: ::error(\"invalid call to %04x dispatched\", (uint16)ax);")
- self.fd.write("\n\t}\n}\n\n} /*namespace*/\n")
-
+ if self.skip_dispatch_call == False:
+ self.fd.write("\nvoid %sContext::__dispatch_call(uint16 addr) {\n\tswitch(addr) {\n" %self.namespace)
+ self.proc_addr.sort(cmp = lambda x, y: x[1] - y[1])
+ for name,addr in self.proc_addr:
+ self.fd.write("\t\tcase addr_%s: %s(); break;\n" %(name, name))
+ self.fd.write("\t\tdefault: ::error(\"invalid call to %04x dispatched\", (uint16)ax);")
+ self.fd.write("\n\t}\n}")
+
+ self.fd.write("\n} // End of namespace DreamGen\n")
self.fd.close()
diff --git a/devtools/tasmrecover/tasm/parser.py b/devtools/tasmrecover/tasm/parser.py
index ebbd714cf4..0782fff22f 100644
--- a/devtools/tasmrecover/tasm/parser.py
+++ b/devtools/tasmrecover/tasm/parser.py
@@ -25,7 +25,8 @@ import lex
import op
class parser:
- def __init__(self):
+ def __init__(self, skip_binary_data = []):
+ self.skip_binary_data = skip_binary_data
self.strip_path = 0
self.__globals = {}
self.__offsets = {}
@@ -186,6 +187,7 @@ class parser:
def parse(self, fname):
# print "opening file %s..." %(fname, basedir)
+ skipping_binary_data = False
fd = open(fname, 'rb')
for line in fd:
line = line.strip()
@@ -198,10 +200,15 @@ class parser:
line = line[len(m.group(0)):].strip()
if self.visible():
name = m.group(1)
- if self.proc is not None:
- self.proc.add_label(name)
- print "offset %s -> %d" %(name, len(self.binary_data))
- self.set_offset(name, (len(self.binary_data), self.proc, len(self.proc.stmts) if self.proc is not None else 0))
+ if not (name.lower() in self.skip_binary_data):
+ if self.proc is not None:
+ self.proc.add_label(name)
+ print "offset %s -> %d" %(name, len(self.binary_data))
+ self.set_offset(name, (len(self.binary_data), self.proc, len(self.proc.stmts) if self.proc is not None else 0))
+ skipping_binary_data = False
+ else:
+ print "skipping binary data for %s" % (name,)
+ skipping_binary_data = True
#print line
cmd = line.split()
@@ -224,9 +231,10 @@ class parser:
if cmd0 == 'db' or cmd0 == 'dw' or cmd0 == 'dd':
arg = line[len(cmd0):].strip()
- print "%d:1: %s" %(len(self.binary_data), arg) #fixme: COPYPASTE
- binary_width = {'b': 1, 'w': 2, 'd': 4}[cmd0[1]]
- self.binary_data += self.compact_data(binary_width, lex.parse_args(arg))
+ if not skipping_binary_data:
+ print "%d:1: %s" %(len(self.binary_data), arg) #fixme: COPYPASTE
+ binary_width = {'b': 1, 'w': 2, 'd': 4}[cmd0[1]]
+ self.binary_data += self.compact_data(binary_width, lex.parse_args(arg))
continue
elif cmd0 == 'include':
self.include(os.path.dirname(fname), cmd[1])
@@ -245,16 +253,25 @@ class parser:
if len(cmd) >= 3:
cmd1 = cmd[1]
if cmd1 == 'equ':
- v = cmd[2]
- self.set_global(cmd0, op.const(self.fix_dollar(v)))
+ if not (cmd0.lower() in self.skip_binary_data):
+ v = cmd[2]
+ self.set_global(cmd0, op.const(self.fix_dollar(v)))
+ else:
+ print "skipping binary data for %s" % (cmd0.lower(),)
+ skipping_binary_data = True
elif cmd1 == 'db' or cmd1 == 'dw' or cmd1 == 'dd':
- binary_width = {'b': 1, 'w': 2, 'd': 4}[cmd1[1]]
- offset = len(self.binary_data)
- arg = line[len(cmd0):].strip()
- arg = arg[len(cmd1):].strip()
- print "%d: %s" %(offset, arg)
- self.binary_data += self.compact_data(binary_width, lex.parse_args(arg))
- self.set_global(cmd0.lower(), op.var(binary_width, offset))
+ if not (cmd0.lower() in self.skip_binary_data):
+ binary_width = {'b': 1, 'w': 2, 'd': 4}[cmd1[1]]
+ offset = len(self.binary_data)
+ arg = line[len(cmd0):].strip()
+ arg = arg[len(cmd1):].strip()
+ print "%d: %s" %(offset, arg)
+ self.binary_data += self.compact_data(binary_width, lex.parse_args(arg))
+ self.set_global(cmd0.lower(), op.var(binary_width, offset))
+ skipping_binary_data = False
+ else:
+ print "skipping binary data for %s" % (cmd0.lower(),)
+ skipping_binary_data = True
continue
elif cmd1 == 'proc':
name = cmd0.lower()
diff --git a/devtools/update-version.pl b/devtools/update-version.pl
index 169fba7788..b313846ab3 100755
--- a/devtools/update-version.pl
+++ b/devtools/update-version.pl
@@ -43,6 +43,12 @@ my @subs_files = qw(
dists/wii/meta.xml
dists/android/AndroidManifest.xml
dists/android/plugin-manifest.xml
+ dists/openpandora/PXML.xml
+ dists/openpandora/README-OPENPANDORA
+ dists/openpandora/README-PND.txt
+ dists/openpandora/index.html
+ dists/gph/README-GPH
+ dists/gph/scummvm.ini
backends/platform/psp/README.PSP
);
diff --git a/dists/android/AndroidManifest.xml b/dists/android/AndroidManifest.xml
index a25048fe28..e7778fdf61 100644
--- a/dists/android/AndroidManifest.xml
+++ b/dists/android/AndroidManifest.xml
@@ -2,11 +2,11 @@
<!-- NB: android:versionCode needs to be bumped for formal releases -->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="org.inodes.gus.scummvm"
+ package="org.scummvm.scummvm"
android:versionCode="@ANDROID_VERSIONCODE@"
android:versionName="1.5.0git"
android:installLocation="preferExternal"
- android:sharedUserId="org.inodes.gus.scummvm">
+ android:sharedUserId="org.scummvm.scummvm">
<!-- This version works on Android 1.5 (SDK 3) and newer, but we
want Android 2.2 (SDK 8) defaults and features. -->
@@ -31,8 +31,8 @@
android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
android:screenOrientation="landscape"
android:configChanges="orientation|keyboardHidden">
- <meta-data android:name="org.inodes.gus.unpacker.nextActivity"
- android:value="org.inodes.gus.scummvm/.ScummVMActivity"/>
+ <meta-data android:name="org.scummvm.unpacker.nextActivity"
+ android:value="org.scummvm.scummvm/.ScummVMActivity"/>
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
@@ -40,7 +40,7 @@
</activity>
</application>
- <permission android:name="org.inodes.gus.scummvm.permission.SCUMMVM_PLUGIN"
+ <permission android:name="org.scummvm.scummvm.permission.SCUMMVM_PLUGIN"
android:label="@string/scummvm_perm_plugin_label"
android:description="@string/scummvm_perm_plugin_desc"
android:protectionLevel="signature"/>
diff --git a/dists/android/AndroidManifest.xml.in b/dists/android/AndroidManifest.xml.in
index 32444a03f0..8f7887eaf5 100644
--- a/dists/android/AndroidManifest.xml.in
+++ b/dists/android/AndroidManifest.xml.in
@@ -2,11 +2,11 @@
<!-- NB: android:versionCode needs to be bumped for formal releases -->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="org.inodes.gus.scummvm"
+ package="org.scummvm.scummvm"
android:versionCode="@ANDROID_VERSIONCODE@"
android:versionName="@VERSION@"
android:installLocation="preferExternal"
- android:sharedUserId="org.inodes.gus.scummvm">
+ android:sharedUserId="org.scummvm.scummvm">
<!-- This version works on Android 1.5 (SDK 3) and newer, but we
want Android 2.2 (SDK 8) defaults and features. -->
@@ -31,8 +31,8 @@
android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
android:screenOrientation="landscape"
android:configChanges="orientation|keyboardHidden">
- <meta-data android:name="org.inodes.gus.unpacker.nextActivity"
- android:value="org.inodes.gus.scummvm/.ScummVMActivity"/>
+ <meta-data android:name="org.scummvm.unpacker.nextActivity"
+ android:value="org.scummvm.scummvm/.ScummVMActivity"/>
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
@@ -40,7 +40,7 @@
</activity>
</application>
- <permission android:name="org.inodes.gus.scummvm.permission.SCUMMVM_PLUGIN"
+ <permission android:name="org.scummvm.scummvm.permission.SCUMMVM_PLUGIN"
android:label="@string/scummvm_perm_plugin_label"
android:description="@string/scummvm_perm_plugin_desc"
android:protectionLevel="signature"/>
diff --git a/dists/android/mkplugin.sh b/dists/android/mkplugin.sh
index 1811fc0475..30a7ef66d6 100755
--- a/dists/android/mkplugin.sh
+++ b/dists/android/mkplugin.sh
@@ -11,6 +11,6 @@ TEMPLATE=$3
PLUGIN_VERSION_CODE=$4
TARGET=$5
-PLUGIN_DESC=`sed -n s/add_engine\s$PLUGIN_NAME\s\"\(.\+\)\"\s.*/\1/p` < $CONFIGURE
+PLUGIN_DESC=`sed -n "s/add_engine\s$PLUGIN_NAME\s\"\(.\+\)\"\s.*/\1/p" < $CONFIGURE`
sed "s|@PLUGIN_NAME@|$PLUGIN_NAME|;s|@PLUGIN_VERSION_CODE@|$PLUGIN_VERSION_CODE|;s|@PLUGIN_DESC@|$PLUGIN_DESC|" < $TEMPLATE > $TARGET
diff --git a/dists/android/plugin-manifest.xml b/dists/android/plugin-manifest.xml
index 728beb1de3..51b39be3b1 100644
--- a/dists/android/plugin-manifest.xml
+++ b/dists/android/plugin-manifest.xml
@@ -1,29 +1,29 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="org.inodes.gus.scummvm.plugin.@PLUGIN_NAME@"
+ package="org.scummvm.scummvm.plugin.@PLUGIN_NAME@"
android:versionCode="@PLUGIN_VERSION_CODE@"
android:versionName="1.5.0git"
android:installLocation="preferExternal"
- android:sharedUserId="org.inodes.gus.scummvm">
+ android:sharedUserId="org.scummvm.scummvm">
<uses-sdk android:minSdkVersion="3" android:targetSdkVersion="8" />
<application android:label="@string/app_name"
android:description="@string/app_desc"
android:icon="@drawable/scummvm">
- <receiver android:name="org.inodes.gus.scummvm.PluginProvider"
- android:process="org.inodes.gus.scummvm">
+ <receiver android:name="org.scummvm.scummvm.PluginProvider"
+ android:process="org.scummvm.scummvm">
<intent-filter>
- <action android:name="org.inodes.gus.scummvm.action.PLUGIN_QUERY"/>
+ <action android:name="org.scummvm.scummvm.action.PLUGIN_QUERY"/>
<category android:name="android.intent.category.INFO"/>
</intent-filter>
- <meta-data android:name="org.inodes.gus.scummvm.meta.UNPACK_LIB"
+ <meta-data android:name="org.scummvm.scummvm.meta.UNPACK_LIB"
android:value="mylib/armeabi/lib@PLUGIN_NAME@.so" />
</receiver>
</application>
- <uses-permission android:name="org.inodes.gus.scummvm.permission.SCUMMVM_PLUGIN"/>
+ <uses-permission android:name="org.scummvm.scummvm.permission.SCUMMVM_PLUGIN"/>
<uses-configuration android:reqFiveWayNav="true"
android:reqKeyboardType="qwerty"/>
diff --git a/dists/android/plugin-manifest.xml.in b/dists/android/plugin-manifest.xml.in
index ab0a63a0cf..4b429097ae 100644
--- a/dists/android/plugin-manifest.xml.in
+++ b/dists/android/plugin-manifest.xml.in
@@ -1,29 +1,29 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="org.inodes.gus.scummvm.plugin.@PLUGIN_NAME@"
+ package="org.scummvm.scummvm.plugin.@PLUGIN_NAME@"
android:versionCode="@PLUGIN_VERSION_CODE@"
android:versionName="@VERSION@"
android:installLocation="preferExternal"
- android:sharedUserId="org.inodes.gus.scummvm">
+ android:sharedUserId="org.scummvm.scummvm">
<uses-sdk android:minSdkVersion="3" android:targetSdkVersion="8" />
<application android:label="@string/app_name"
android:description="@string/app_desc"
android:icon="@drawable/scummvm">
- <receiver android:name="org.inodes.gus.scummvm.PluginProvider"
- android:process="org.inodes.gus.scummvm">
+ <receiver android:name="org.scummvm.scummvm.PluginProvider"
+ android:process="org.scummvm.scummvm">
<intent-filter>
- <action android:name="org.inodes.gus.scummvm.action.PLUGIN_QUERY"/>
+ <action android:name="org.scummvm.scummvm.action.PLUGIN_QUERY"/>
<category android:name="android.intent.category.INFO"/>
</intent-filter>
- <meta-data android:name="org.inodes.gus.scummvm.meta.UNPACK_LIB"
+ <meta-data android:name="org.scummvm.scummvm.meta.UNPACK_LIB"
android:value="mylib/armeabi/lib@PLUGIN_NAME@.so" />
</receiver>
</application>
- <uses-permission android:name="org.inodes.gus.scummvm.permission.SCUMMVM_PLUGIN"/>
+ <uses-permission android:name="org.scummvm.scummvm.permission.SCUMMVM_PLUGIN"/>
<uses-configuration android:reqFiveWayNav="true"
android:reqKeyboardType="qwerty"/>
diff --git a/dists/android/res/layout/main.xml b/dists/android/res/layout/main.xml
index 7b633c416d..8b0d515d62 100644
--- a/dists/android/res/layout/main.xml
+++ b/dists/android/res/layout/main.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
-<org.inodes.gus.scummvm.EditableSurfaceView
+<org.scummvm.scummvm.EditableSurfaceView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/main_surface"
android:layout_width="fill_parent"
diff --git a/dists/debian/changelog b/dists/debian/changelog
new file mode 100644
index 0000000000..902aa89c9a
--- /dev/null
+++ b/dists/debian/changelog
@@ -0,0 +1,544 @@
+scummvm (1.4.0-1) unstable; urgency=low
+
+ * New upstream release
+ - Fixes script bug in "Beneath a Steel Sky" (Closes: #462595)
+ * Remove Build-Conflicts on liboss-salsa-dev and disable ALSA on
+ kfreebsd (Closes: #647124)
+ * Bump debhelper level to 9, which enables default build flags
+ and thus hardened compiler flags
+
+ -- Moritz Muehlenhoff <jmm@debian.org> Sat, 05 Nov 2011 10:29:43 +0100
+
+scummvm (1.3.1-1) unstable; urgency=low
+
+ * New upstream release
+
+ -- Moritz Muehlenhoff <jmm@debian.org> Mon, 04 Jul 2011 19:07:04 +0200
+
+scummvm (1.3.0-1) unstable; urgency=low
+
+ * New upstream release
+ - Fixes FTBFS with ld --as-needed (Closes: #607182)
+ * Version debhelper build dep for debhelper override support
+
+ -- Moritz Muehlenhoff <jmm@debian.org> Wed, 25 May 2011 19:02:23 +0200
+
+scummvm (1.2.1-2) unstable; urgency=low
+
+ * Pass "--enable-release" to the configure script. This prevents
+ the build of a few "work in progress" engines, which upstream
+ doesn't see fit for general use yet.
+ * Add a build conflict on liboss-salsa-dev to prevent the libsalsa
+ emulation library being present in the buildd chroots. ScummVM
+ itself builds fine with OSS support (Closes: #600655)
+
+ -- Moritz Muehlenhoff <jmm@debian.org> Sun, 19 Dec 2010 19:51:42 +0100
+
+scummvm (1.2.1-1) unstable; urgency=low
+
+ * New upstream release
+
+ -- Moritz Muehlenhoff <jmm@debian.org> Sat, 11 Dec 2010 12:17:22 +0100
+
+scummvm (1.2.0-2) unstable; urgency=low
+
+ * Add python to the build dependencies, since it's needed for the
+ test suite (Closes: #600173)
+ * Change data dir to /usr/share/scummvm (Closes: #600157)
+ * 1.2.0 also introduced official support for SCI games (Closes: #576268)
+
+ -- Moritz Muehlenhoff <jmm@debian.org> Sun, 17 Oct 2010 15:58:36 +0200
+
+scummvm (1.2.0-1) unstable; urgency=low
+
+ * New upstream release (Closes: #593945)
+ * Drop obsolete build deps on texlive-base, texlive-extra-utils,
+ ghostscript (Thanks, Max Horn)
+ * Update description to point out that ScummVM supports much
+ more than SCUMM these days (Thanks, Max Horn)
+ * Update to standards version 3.9.1:
+ - Modify asound build dep to linux-any
+ * Unversion several build deps even supported in oldstable
+
+ -- Moritz Muehlenhoff <jmm@debian.org> Tue, 12 Oct 2010 21:49:29 +0200
+
+scummvm (1.1.1-1) unstable; urgency=low
+
+ * New upstream release
+ * Switch to bz2 upstream tarball
+ * Disable SCI engine as requested by upstream, it's not yet ready to
+ replace FreeSCI
+
+ -- Moritz Muehlenhoff <jmm@debian.org> Fri, 07 May 2010 18:57:09 +0200
+
+scummvm (1.1.0-2) unstable; urgency=low
+
+ * Do not build-depend on libasound on KFreeBSD and the Hurd
+
+ -- Moritz Muehlenhoff <jmm@debian.org> Sun, 25 Apr 2010 22:28:48 +0200
+
+scummvm (1.1.0-1) unstable; urgency=low
+
+ * New upstream release
+ - Fixes running ScummVM without a soundcard (Closes: #540166)
+ * Enable SCI engine (Closes: #576268)
+ * Lintian cleanups, bump standards version (no changes necessary)
+
+ -- Moritz Muehlenhoff <jmm@debian.org> Wed, 07 Apr 2010 20:49:10 +0200
+
+scummvm (1.0.0-4) unstable; urgency=high
+
+ * Fix Replaces for scummvm.xpm (Closes: #573372)
+
+ -- Moritz Muehlenhoff <jmm@debian.org> Mon, 22 Mar 2010 18:46:55 +0100
+
+scummvm (1.0.0-3) unstable; urgency=low
+
+ * Install the architecture-independant data files into a separate
+ binary package to save disk space on the mirrors.
+
+ -- Moritz Muehlenhoff <jmm@debian.org> Tue, 26 Jan 2010 21:01:25 +0100
+
+scummvm (1.0.0-2) unstable; urgency=low
+
+ * Switch to a minimal dh Makefile
+
+ -- Moritz Muehlenhoff <jmm@debian.org> Wed, 06 Jan 2010 22:03:22 +0100
+
+scummvm (1.0.0-1) unstable; urgency=low
+
+ * New upstream release
+ * Switch to source format 3 (quilt)
+
+ -- Moritz Muehlenhoff <jmm@debian.org> Mon, 16 Nov 2009 19:48:57 +0100
+
+scummvm (1.0.0~rc1-1-1) unstable; urgency=low
+
+ * New upstream release (Closes: #544570)
+ - Adds support for Discworld (Closes: #513950)
+ * Remove dh_desktop
+ * Version the dependency on debhelper
+ * Bump Standards-Version to 3.8.1, no changes needed
+ * Update copyright file
+
+ -- Moritz Muehlenhoff <jmm@debian.org> Tue, 01 Sep 2009 22:11:17 +0200
+
+scummvm (0.13.1-1) unstable; urgency=low
+
+ * New upstream release (Closes: #530863)
+ * Bump Standards-Version to 3.8.1, add Homepage field
+ * Bump debhelper level to 7
+ * Build-depend on ghostscript instead of gs-gpl
+ * Build-depend on texlive-base instead of tetex-bin
+ * Build-depend on texlive-extra-utils instead of tetex-extra
+
+ -- Moritz Muehlenhoff <jmm@debian.org> Sun, 07 Jun 2009 12:28:30 +0200
+
+scummvm (0.13.0-1) unstable; urgency=low
+
+ * New upstream release (Closes: #499849)
+ * Move maintainer to Debian Games Team, add myself and David as
+ uploaders
+ * Fix link to compability matrix in package description
+ (Closes: #508894)
+
+ -- Moritz Muehlenhoff <jmm@debian.org> Sat, 07 Mar 2009 01:18:12 +0100
+
+scummvm (0.11.1-1) unstable; urgency=low
+
+ * New upstream release
+ * Install upstream NEWS file too
+
+ -- David Weinehall <tao@debian.org> Sat, 01 Mar 2008 10:28:14 +0200
+
+scummvm (0.11.0-1) unstable; urgency=low
+
+ * New upstream release (Closes: #465745)
+ * debian/control:
+ - Build-Depend on libflac (>= 1.1.2), not (>= 1.1.2-1) to simplify
+ things for backports
+ - Standards-Version 3.7.3 - no changes required
+ * debian/copyright:
+ - Fixed to contain better copyright information
+
+ -- David Weinehall <tao@debian.org> Thu, 14 Feb 2008 15:38:44 +0200
+
+scummvm (0.10.0-2) unstable; urgency=low
+
+ * Run configure before clean target (Closes: #445610)
+
+ -- David Weinehall <tao@debian.org> Sun, 07 Oct 2007 15:56:49 +0300
+
+scummvm (0.10.0-1) unstable; urgency=low
+
+ * The ``Too late for words'' release
+ * New upstream release
+
+ -- David Weinehall <tao@debian.org> Thu, 04 Oct 2007 00:54:56 +0300
+
+scummvm (0.9.1-1) unstable; urgency=low
+
+ * New upstream release
+ * debian/prepare: refer to me instead
+ * debian/copyright: add the date I adopted the package
+
+ -- David Weinehall <tao@debian.org> Mon, 30 Oct 2006 16:44:12 +0200
+
+scummvm (0.9.0-1) unstable; urgency=low
+
+ * New upstream release (Closes: #379184)
+ - Buffer overflow fixed (Closes: #292263)
+ * debian/control:
+ - Standards-Version 3.7.2.1 - no changes required
+
+ -- David Weinehall <tao@debian.org> Sat, 23 Sep 2006 16:01:48 +0300
+
+scummvm (0.8.2-2) unstable; urgency=low
+
+ * Install (updated) .desktop-file + SVG-icon (Closes: #361534)
+ | Thanks to Sven Arvidsson
+
+ -- David Weinehall <tao@debian.org> Sun, 9 Apr 2006 01:42:30 +0300
+
+scummvm (0.8.2-1) unstable; urgency=low
+
+ * New upstream release
+
+ -- David Weinehall <tao@debian.org> Sun, 5 Feb 2006 20:48:31 +0200
+
+scummvm (0.8.1-1) unstable; urgency=low
+
+ * New upstream release.
+ * New maintainer.
+
+ -- David Weinehall <tao@debian.org> Mon, 30 Jan 2006 10:29:59 +0200
+
+scummvm (0.8.0-1) unstable; urgency=low
+
+ * New upstream release:
+ - Uses British English as the default subtitle language for Beneath a
+ Steel Sky, closes: #329157.
+
+ * debian/control, debian/rules:
+ - Build using the default GCC, as GCC 4 is now supported.
+
+ * debian/control:
+ - Add a dependency on libfluidsynth-dev, as the new upstream release can
+ make use of the fluidsynth library directly.
+
+ -- Tore Anderson <tore@debian.org> Sat, 29 Oct 2005 21:05:52 +0200
+
+scummvm (0.7.1-3) unstable; urgency=low
+
+ * debian/control:
+ - Narrow build-dependency on libflac-dev to version 1.1.2-1 or above,
+ closes: #325954. Many thanks to Joshua Kwan for notifying me of FLAC's
+ recent SONAME increase, which necessitates this change.
+
+ -- Tore Anderson <tore@debian.org> Fri, 2 Sep 2005 07:20:32 +0200
+
+scummvm (0.7.1-2) unstable; urgency=low
+
+ * debian/control, debian/rules:
+ - Compile the package with GCC 3.4.
+
+ * debian/prepare (new):
+ - Added a script that prepares the debian/ tree for building developement
+ snapshots of ScummVM.
+
+ * debian/control:
+ - Up standards-version to 3.6.2.1, no changes required.
+
+ -- Tore Anderson <tore@debian.org> Sun, 31 Jul 2005 11:38:18 +0200
+
+scummvm (0.7.1-1) unstable; urgency=low
+
+ * New upstream release.
+
+ * debian/control:
+ - Remove the nasm [!i386] build conflict, as the configure script now
+ correctly detects if nasm can be used.
+ - Up standards-version to 3.6.1.1 (no changes required).
+
+ * configure:
+ - Reverted to the upstream version, as the GCC 4.0 patch from 0.7.0-3 is
+ now included there.
+
+ -- Tore Anderson <tore@debian.org> Tue, 29 Mar 2005 21:57:38 +0200
+
+scummvm (0.7.0-3) unstable; urgency=medium
+
+ * debian/control:
+ - Add a version requirement of >= 1.1.1-2 to the libflac-dev build
+ dependency, closes: #289214.
+ - Add fluidsynth as a preferred alternative to the timidity suggestion.
+ - Remove superfluous "the" from the description.
+
+ * configure:
+ - Partly apply patch from Andreas Jochens, closes: #289122. Thanks!
+ Hopefully, this should make it possible to compile ScummVM on AMD64
+ using GCC 4.0. GCC 4.0 is not yet supported from upstream, though.
+
+ -- Tore Anderson <tore@debian.org> Sat, 8 Jan 2005 15:03:34 +0100
+
+scummvm (0.7.0-2) unstable; urgency=low
+
+ * debian/control:
+ - Build-depend on nasm only on i386.
+ - Add a build conflict on nasm for all other archs than i386.
+ - Add an explicit build dependency on libz-dev.
+
+ * debian/copyright:
+ - Change URLs from http://scummvm.sf.net/ to http://www.scummvm.org/.
+
+ -- Tore Anderson <tore@debian.org> Wed, 5 Jan 2005 23:22:08 +0100
+
+scummvm (0.7.0-1) unstable; urgency=low
+
+ * New upstream release.
+ - Fixes scripting bug that in some cases may render the game unwinnable,
+ closes: #209418.
+
+ * debian/control:
+ - Improve description. Closes: #266055. Thanks, Frederic Briere!
+ - Add build dependencies on nasm, tetex-bin, tetex-extra, gs-gpl, and
+ libflac-dev.
+
+ * debian/rules, debian/scummvm.docs, debian/copyright:
+ - Build and include README.pdf (generated from doc/*.tex).
+ - Include AUTHORS, and reference it from debian/copyright instead of
+ maintaining a separate list of authors there.
+
+ * debian/scummvm.dirs, debian/rules, debian/scummvm.sh (removed):
+ - A more sane default save game path has been chosen upstream. Remove
+ the Debian-specific wrapper script workaround introduced in 0.6.0-2
+ accordingly.
+
+ -- Tore Anderson <tore@debian.org> Wed, 5 Jan 2005 14:43:08 +0100
+
+scummvm (0.6.1b-1) unstable; urgency=low
+
+ * New upstream release.
+
+ -- Tore Anderson <tore@debian.org> Fri, 6 Aug 2004 12:45:46 +0200
+
+scummvm (0.6.1-1) unstable; urgency=low
+
+ * New upstream release.
+
+ -- Tore Anderson <tore@debian.org> Mon, 26 Jul 2004 15:11:10 +0200
+
+scummvm (0.6.0-2) unstable; urgency=low
+
+ * debian/scummvm.dirs, debian/rules, debian/scummvm.sh (new):
+ - Make /usr/games/scummvm be a wrapper script which creates the
+ ~/.scummvmrc file if it doesn't already exist, setting the savegame
+ path to ~/.scummvm/. Closes: #216178. This is a workaround, though,
+ I really wish this would be fixed in the upstream sources.
+
+ * debian/control:
+ - Correct the compability chart link in the package description.
+ - Update package description so it is clear that Flight of The Amazon
+ Queen and Beneath a Steel Sky is available in Debian, closes: #245356.
+
+ * debian/README.Debian (removed):
+ - Removed from the package, as it only spoke of the ScummVM tools,
+ which was removed in the 0.6.0-1 upload. Closes: #259259 (sort-of).
+
+ * base/main.cpp, scumm/actor.cpp, scumm/debugger.cpp:
+ - GCC 3.4 fixes from Andreas Jochens. Thanks! Closes: #259835.
+
+ -- Tore Anderson <tore@debian.org> Sun, 18 Jul 2004 12:26:27 +0200
+
+scummvm (0.6.0-1) unstable; urgency=low
+
+ * New upstream release.
+
+ * debian/control:
+ - Build-Depend on libmpeg2-4-dev to support Broken Sword cutscenes.
+
+ * debian/rules:
+ - Start using upstream's new configure script.
+ - Remove unneeded call to dh_link.
+
+ * debian/scummvm.docs:
+ - Add upstream's TODO file.
+
+ * debian/scummvm.menu:
+ - Enclose the "needs" and "section" directives in double quotes.
+
+ * debian/patches/* (removed), debian/control, debian/rules:
+ - Stop using dpatch. All of the previously required patches are now
+ integrated in the upstream sources.
+
+ * debian/tools/* (removed), debian/scummvm.examples, debian/rules:
+ - Remove the various tools as they really don't belong in the ScummVM
+ package.
+
+ -- Tore Anderson <tore@debian.org> Sun, 14 Mar 2004 16:28:54 +0100
+
+scummvm (0.5.1-4) unstable; urgency=low
+
+ * debian/patches/03alsa_api_fix.dpatch (new), debian/patches/00list:
+ - FTBFS fix; improve ALSA version detection macro so it works with
+ version 1.0 and above. Thanks, Jordi Mallach!
+
+ -- Tore Anderson <tore@debian.org> Sun, 1 Feb 2004 01:36:07 +0100
+
+scummvm (0.5.1-3) unstable; urgency=low
+
+ * debian/patches/02bass_soundreload (new):
+ - Forces BASS to reload music and sound even if the intro was
+ viewed in full, closes: #208901.
+ * debian/control:
+ - Change maintainer email address.
+ - Bump Standards-Version to current policy, no changes required.
+
+ -- Tore Anderson <tore@debian.org> Mon, 29 Sep 2003 16:13:43 +0200
+
+scummvm (0.5.1-2) unstable; urgency=low
+
+ * Move to main. (Note to the FTP masters: This is because the
+ one of the supported games, Beneath A Steel Sky, has recently been
+ released as free software. It should appear in NEW shortly, if
+ it's not there already.)
+ * Sponsored by David Weinehall.
+
+ -- David Weinehall <tao@debian.org> Wed, 27 Aug 2003 21:00:42 +0200
+
+scummvm (0.5.1-1) unstable; urgency=low
+
+ * New upstream release.
+ * Sponsored by David Weinehall. (No beer needed...)
+
+ -- Tore Anderson <tore@linpro.no> Sat, 9 Aug 2003 15:18:18 +0200
+
+scummvm (0.5.0-1) unstable; urgency=low
+
+ * New upstream release.
+ * Suggest beneath-a-steel-sky.
+ * Restructure 00buildopts somewhat, to ease future maintenance.
+ * Standards-Version 3.6.0, no changes required.
+ * Revised the description.
+ * Sponsored by Joey Hess. (Tore fed me all the beer I could take ..
+ and then asked me to do this. ;-)
+
+ -- Tore Anderson <tore@linpro.no> Fri, 1 Aug 2003 21:45:06 +0200
+
+scummvm (0.4.1-1) unstable; urgency=low
+
+ * New upstream release.
+ * Standards-Version 3.5.10.
+ - Use upstream's icon in the menu system.
+ * Removed debian/patches/01-enable-alsa-and-vorbis.dpatch, this
+ is now done from debian/rules instead.
+ * Added debian/patches/00buildopts, which makes it possible
+ for environment variables to override the compiler flags.
+ * Better handling of $DEB_BUILD_OPTIONS.
+ * Declare the debhelper compability level in debian/compat instead
+ of debian/rules.
+
+ -- Tore Anderson <tore@linpro.no> Thu, 29 May 2003 15:15:55 +0200
+
+scummvm (0.4.0-1) unstable; urgency=low
+
+ * New upstream release, closes: #193522.
+ - Lots of VM fixes in The DIG, closes: #173550.
+ - Obsoletes debian/patches/02-fix-manpage-savekey.dpatch.
+ - Obsoletes debian/patches/03-fix-talking-to-parrot.dpatch.
+ - Obsoletes debian/patches/04-alsa-seq-tty-output.dpatch.
+ * Add extract.c and simon2mp3.c to the examples directory, closes: #154449.
+
+ -- Tore Anderson <tore@linpro.no> Wed, 14 May 2003 19:04:53 +0200
+
+scummvm (0.3.0b-3) unstable; urgency=low
+
+ * It appears I reinvented the wheel. Start using dpatch instead of
+ my own patchsystem.
+ * Update Standards-Version to match current policy.
+ * Tighten build-dependency on libvorbis-dev, to ensure that the binary
+ will be linked against the new libvorbis0a package. Closes: #185447.
+
+ -- Tore Anderson <tore@linpro.no> Tue, 18 Mar 2003 22:54:32 +0100
+
+scummvm (0.3.0b-2) unstable; urgency=low
+
+ * Re-upload to build the binary with GCC 3.2.
+ * Use a patch system instead of putting all changes in the .diff.gz.
+ * Correct save-game modifier key in the manpage. Closes: #173153.
+ * Two fixes from upstream:
+ - Fix 'talking to parrot' script deadlock in Fate of Atlantis.
+ - Print correct alsa client and port variables to console.
+
+ -- Tore Anderson <tore@linpro.no> Fri, 10 Jan 2003 17:28:36 +0100
+
+scummvm (0.3.0b-1) unstable; urgency=low
+
+ * New upstream release.
+ * Update standards-version again.
+ * Convert icon to use only the colours mandated by the menu package.
+
+ -- Tore Anderson <tore@linpro.no> Sun, 8 Dec 2002 14:56:26 +0100
+
+scummvm (0.2.81cvs20021110-1) unstable; urgency=low
+
+ * New CVS snapshot.
+ * Remove README.Debian - it was incorrect.
+ * Drop build-deps on curses and readline.
+ * Update standards-version to current policy.
+ * Don't install the empty dir /usr/lib/scummvm anymore.
+
+ -- Tore Anderson <tore@linpro.no> Sun, 10 Nov 2002 17:13:36 +0100
+
+scummvm (0.2.0.1cvs20021028-1) unstable; urgency=low
+
+ * New CVS snapshot.
+ * Kill cruft that sneaked into the .diff.gz.
+ * Add menu entry.
+ * Rewrote description and copyright file.
+ * Suggest timidity (can be used with ALSA for gorgeous in-game music).
+ * Support .SOG (Ogg Vorbis-compressed .SOU-files).
+
+ -- Tore Anderson <tore@linpro.no> Mon, 28 Oct 2002 14:30:21 +0100
+
+scummvm (0.2.0.1cvs20021012-1) unstable; urgency=low
+
+ * New upstream rele^WCVS snapshot.
+ * New maintainer. Closes: #163105.
+ * Compliant with Policy 3.5.7.0. Or so I hope.
+ * Support ALSA's sequencer. Closes: #154451.
+
+ -- Tore Anderson <tore@linpro.no> Sat, 12 Oct 2002 15:17:11 +0200
+
+scummvm (0.2.0.1) unstable; urgency=low
+
+ * Fix by James Brown <ender@enderboi.com> for the trailing slash bug
+ (Closes: #150144)
+ * Add libmad-dev to the Buildreqs, compile with compressed audio support
+ (Closes: #150272)
+
+ -- Bastien Nocera <hadess@hadess.net> Tue, 18 Jun 2002 02:35:50 +0100
+
+scummvm (0.2.0) unstable; urgency=low
+
+ * New upstream version (Closes: #143281)
+ * Killed the wrapper script, see upstream changelog
+
+ -- Bastien Nocera <hadess@hadess.net> Wed, 15 May 2002 03:27:11 +0100
+
+scummvm (0.1.0b-2) unstable; urgency=low
+
+ * Moved the scummvm main bin under /usr/lib, the wrapper script under
+ /usr/games
+ * Fixed bug in the script that made it not work if the path was relative
+
+ -- Bastien Nocera <hadess@hadess.net> Wed, 10 Apr 2002 19:27:05 +0100
+
+scummvm (0.1.0b-1) unstable; urgency=low
+
+ * Initial Release.
+ * Packaged made under the influence of beer at GUAD3C in Sevilla ! Arriba !
+ Ole !
+
+ -- Bastien Nocera <hadess@hadess.net> Fri, 5 Apr 2002 16:37:09 +0100
+
diff --git a/dists/debian/compat b/dists/debian/compat
new file mode 100644
index 0000000000..7f8f011eb7
--- /dev/null
+++ b/dists/debian/compat
@@ -0,0 +1 @@
+7
diff --git a/dists/debian/control b/dists/debian/control
new file mode 100644
index 0000000000..40c0e53470
--- /dev/null
+++ b/dists/debian/control
@@ -0,0 +1,59 @@
+Source: scummvm
+Section: games
+Priority: optional
+Maintainer: Debian Games Team <pkg-games-devel@lists.alioth.debian.org>
+Uploaders: David Weinehall <tao@debian.org>, Moritz Muehlenhoff <jmm@debian.org>
+Build-Depends: debhelper (>= 7.0.50~), nasm [i386], libsdl1.2-dev, libmad0-dev, libasound2-dev [linux-any], libvorbis-dev, libmpeg2-4-dev, libflac-dev, libz-dev, libfluidsynth-dev, python
+Standards-Version: 3.9.2
+Homepage: http://www.scummvm.org
+
+Package: scummvm
+Architecture: any
+Depends: ${shlibs:Depends}, scummvm-data, ${misc:Depends}
+Suggests: fluidsynth | timidity, beneath-a-steel-sky, flight-of-the-amazon-queen
+Description: engine for several graphical adventure games
+ ScummVM is a `virtual machine' for several classic graphical
+ point-and-click adventure games. It is designed to run Adventure Soft's
+ Simon the Sorcerer 1 and 2, Revolution's Beneath A Steel Sky, and games
+ based on LucasArts' SCUMM (Script Creation Utility for Maniac Mansion)
+ system. SCUMM is used for many games, including Monkey Island,
+ Day of the Tentacle, Sam and Max and more. See the official compatibility
+ list at <http://www.scummvm.org/compatibility.php> for a full list
+ of supported games.
+ .
+ The game data of two games compatible with ScummVM is included in Debian.
+ These are:
+ .
+ - Beneath a Steel Sky (package name: beneath-a-steel-sky)
+ - Flight of the Amazon Queen (package name: flight-of-the-amazon-queen)
+ .
+ To actually make use of ScummVM, you'll have to install one of these, or
+ obtain the proprietary game data for another supported game from somewhere
+ else.
+
+Package: scummvm-data
+Architecture: all
+Depends: ${shlibs:Depends},${misc:Depends}
+Replaces: scummvm (<< 1.0.0-3)
+Description: engine for several graphical adventure games (data files)
+ ScummVM is a `virtual machine' for several classic graphical
+ point-and-click adventure games. It is designed to run Adventure Soft's
+ Simon the Sorcerer 1 and 2, Revolution's Beneath A Steel Sky, and games
+ based on LucasArts' SCUMM (Script Creation Utility for Maniac Mansion)
+ system. SCUMM is used for many games, including Monkey Island,
+ Day of the Tentacle, Sam and Max and more. See the official compatibility
+ list at <http://www.scummvm.org/compatibility.php> for a full list
+ of supported games.
+ .
+ The game data of two games compatible with ScummVM is included in Debian.
+ These are:
+ .
+ - Beneath a Steel Sky (package name: beneath-a-steel-sky)
+ - Flight of the Amazon Queen (package name: flight-of-the-amazon-queen)
+ .
+ To actually make use of ScummVM, you'll have to install one of these, or
+ obtain the proprietary game data for another supported game from somewhere
+ else.
+ .
+ These packages provides data files needed to run some engines supported by
+ ScummVM.
diff --git a/audio/softsynth/mt32/partialManager.h b/dists/debian/copyright
index b10f93ff02..318c06f62b 100644
--- a/audio/softsynth/mt32/partialManager.h
+++ b/dists/debian/copyright
@@ -1,5 +1,27 @@
-/* Copyright (c) 2003-2005 Various contributors
- *
+ScummVM was debianized by Bastien Nocera <hadess@hadess.net> the 5th Apr 2002.
+It was adopted by Tore Anderson <tore@linpro.no> the 4th Oct 2002,
+then adopted by David Weinehall <tao@debian.org> the 30th Jan 2006,
+then adopted by the Debian Games Team by Moritz Muehlenhoff <jmm@debian.org>
+
+It was downloaded from <http://www.scummvm.org/>.
+
+Upstream Authors: see `/usr/share/doc/scummvm/AUTHORS'.
+
+Scummvm is Copyright © 2002-2012 The ScummVM Project
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by the
+ Free Software Foundation; either version 2, or (at your option) any
+ later version.
+
+ On Debian GNU/Linux systems, the complete text of the GNU General
+ Public License can be found in `/usr/share/common-licenses/GPL'.
+
+This copyright also applies to the Debian-related build scripts.
+
+Some parts of ScummVM (the mt32 softsynth code) is covered by a more
+permissive BSD-style license:
+
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
@@ -17,40 +39,3 @@
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
- */
-
-#ifndef MT32EMU_PARTIALMANAGER_H
-#define MT32EMU_PARTIALMANAGER_H
-
-namespace MT32Emu {
-
-class Synth;
-
-class PartialManager {
-private:
- Synth *synth; // Only used for sending debug output
-
- Partial *partialTable[MT32EMU_MAX_PARTIALS];
- Bit32s partialReserveTable[MT32EMU_MAX_PARTIALS];
- Bit32s partialPart[9]; // The count of partials played per part
-
-public:
-
- PartialManager(Synth *synth);
- ~PartialManager();
- Partial *allocPartial(int partNum);
- unsigned int getFreePartialCount(void);
- bool freePartials(unsigned int needed, int partNum);
- unsigned int setReserve(Bit8u *rset);
- void deactivateAll();
- void ageAll();
- bool produceOutput(int i, Bit16s *buffer, Bit32u bufferLength);
- bool shouldReverb(int i);
- void clearAlreadyOutputed();
- void getPerPartPartialUsage(int usage[9]);
- const Partial *getPartial(unsigned int partialNum) const;
-};
-
-}
-
-#endif
diff --git a/dists/debian/rules b/dists/debian/rules
new file mode 100755
index 0000000000..bf91ca37aa
--- /dev/null
+++ b/dists/debian/rules
@@ -0,0 +1,14 @@
+#!/usr/bin/make -f
+
+%:
+ dh $@
+
+override_dh_auto_configure:
+ifeq ($(DEB_BUILD_ARCH_OS),kfreebsd)
+ ./configure --prefix=/usr --datadir=/usr/share/scummvm --enable-release --disable-alsa
+else
+ ./configure --prefix=/usr --datadir=/usr/share/scummvm --enable-release
+endif
+
+
+
diff --git a/dists/debian/scummvm-data.install b/dists/debian/scummvm-data.install
new file mode 100644
index 0000000000..c77aefbc0a
--- /dev/null
+++ b/dists/debian/scummvm-data.install
@@ -0,0 +1,5 @@
+icons/scummvm.xpm usr/share/icons
+icons/scummvm.svg usr/share/icons
+dists/scummvm.desktop usr/share/applications
+gui/themes/scummmodern.zip usr/share/scummvm
+dists/pred.dic usr/share/scummvm
diff --git a/dists/debian/scummvm.dirs b/dists/debian/scummvm.dirs
new file mode 100644
index 0000000000..6b05c7ace8
--- /dev/null
+++ b/dists/debian/scummvm.dirs
@@ -0,0 +1,5 @@
+usr/games
+usr/share/man/man6
+usr/share/icons
+usr/share/scummvm
+usr/share/applications
diff --git a/dists/debian/scummvm.docs b/dists/debian/scummvm.docs
new file mode 100644
index 0000000000..c73c810363
--- /dev/null
+++ b/dists/debian/scummvm.docs
@@ -0,0 +1,5 @@
+AUTHORS
+COPYRIGHT
+README
+TODO
+NEWS
diff --git a/dists/debian/scummvm.install b/dists/debian/scummvm.install
new file mode 100644
index 0000000000..457a89cfaa
--- /dev/null
+++ b/dists/debian/scummvm.install
@@ -0,0 +1,2 @@
+scummvm usr/games
+
diff --git a/dists/debian/scummvm.manpages b/dists/debian/scummvm.manpages
new file mode 100644
index 0000000000..7b3eb23799
--- /dev/null
+++ b/dists/debian/scummvm.manpages
@@ -0,0 +1 @@
+dists/scummvm.6
diff --git a/dists/debian/scummvm.menu b/dists/debian/scummvm.menu
new file mode 100644
index 0000000000..27d94b0e65
--- /dev/null
+++ b/dists/debian/scummvm.menu
@@ -0,0 +1,3 @@
+?package(scummvm):needs="x11" section="Games/Adventure" \
+ title="ScummVM" command="/usr/games/scummvm" \
+ icon="/usr/share/icons/scummvm.xpm"
diff --git a/dists/engine-data/kyra.dat b/dists/engine-data/kyra.dat
index 902d55c457..c89b21cbca 100644
--- a/dists/engine-data/kyra.dat
+++ b/dists/engine-data/kyra.dat
Binary files differ
diff --git a/dists/engine-data/m4.dat b/dists/engine-data/m4.dat
deleted file mode 100644
index 3181d0182c..0000000000
--- a/dists/engine-data/m4.dat
+++ /dev/null
Binary files differ
diff --git a/dists/engine-data/mads.dat b/dists/engine-data/mads.dat
deleted file mode 100644
index b27f9d4471..0000000000
--- a/dists/engine-data/mads.dat
+++ /dev/null
Binary files differ
diff --git a/backends/platform/gph/devices/common/README-GPH b/dists/gph/README-GPH
index ea196f6649..29f0175306 100644
--- a/backends/platform/gph/devices/common/README-GPH
+++ b/dists/gph/README-GPH
@@ -1,4 +1,5 @@
-ScummVM - GPH DEVICE SPECIFIC README
+ScummVM 1.5.0git - GPH DEVICE SPECIFIC README
+
------------------------------------------------------------------------
Contents:
diff --git a/dists/gph/README-GPH.in b/dists/gph/README-GPH.in
new file mode 100644
index 0000000000..31ec3e4041
--- /dev/null
+++ b/dists/gph/README-GPH.in
@@ -0,0 +1,61 @@
+ScummVM @VERSION@ - GPH DEVICE SPECIFIC README
+
+------------------------------------------------------------------------
+
+Contents:
+
+ * About the backend/port <#About_the_backendport>
+ * Supported audio options <#Supported_audio_options>
+ * Credits <#Credits>
+
+------------------------------------------------------------------------
+
+Please refer to the:
+
+GPH ScummVM Forum: <http://forums.scummvm.org/viewforum.php?f=14>
+
+WiKi: (Select your device)
+
+<http://wiki.scummvm.org/index.php/GP2X>
+<http://wiki.scummvm.org/index.php/GP2XWiz>
+<http://wiki.scummvm.org/index.php/Caanoo>
+
+for the most current information on the port and any updates to this
+documentation.
+
+The wiki includes detailed instructions on how to use the port and
+control information.
+
+------------------------------------------------------------------------
+About the backend/port
+
+This is the readme for the official GPH ScummVM backend (also known as
+the GP2X port/GP2XWiz port or Caanoo port).
+
+This is an SVN test release of ScummVM for GPH devices, it would be
+appreciated if this SVN test distribution was not mirrored and that
+people be directed to http://scummvm.distant-earth.com/ instead for
+updated SVN builds.
+
+Fully supported official releases of the GPH ScummVM backend are made in
+line with main official releases and are avalalble from the ScummVM
+downloads page <http://www.scummvm.org/downloads.php> for the GP2X,
+GP2XWiz and Caanoo.
+
+------------------------------------------------------------------------
+Supported audio options
+
+Raw audio.
+MP3 audio.
+OGG Vorbis audio.
+
+FLAC audio is currently unsupported.
+
+For best results use uncompressed audio in games.
+
+------------------------------------------------------------------------
+Credits
+
+Core ScummVM code (c) The ScummVM Team
+Portions of the GPH backend (c) John Willis
+Detailed (c) information can be found within the source code
diff --git a/backends/platform/gph/devices/caanoo/scummvm-gdb.gpe b/dists/gph/caanoo/scummvm-gdb.gpe
index 63ce193ca8..63ce193ca8 100644
--- a/backends/platform/gph/devices/caanoo/scummvm-gdb.gpe
+++ b/dists/gph/caanoo/scummvm-gdb.gpe
diff --git a/backends/platform/gph/devices/caanoo/scummvm.gpe b/dists/gph/caanoo/scummvm.gpe
index 37d0f65d18..37d0f65d18 100644
--- a/backends/platform/gph/devices/caanoo/scummvm.gpe
+++ b/dists/gph/caanoo/scummvm.gpe
diff --git a/backends/platform/gph/devices/gp2x/mmuhack/Makefile b/dists/gph/gp2x/mmuhack/Makefile
index a35d5c2a98..a35d5c2a98 100644
--- a/backends/platform/gph/devices/gp2x/mmuhack/Makefile
+++ b/dists/gph/gp2x/mmuhack/Makefile
diff --git a/backends/platform/gph/devices/gp2x/mmuhack/README b/dists/gph/gp2x/mmuhack/README
index 6db7d81845..6db7d81845 100644
--- a/backends/platform/gph/devices/gp2x/mmuhack/README
+++ b/dists/gph/gp2x/mmuhack/README
diff --git a/backends/platform/gph/devices/gp2x/mmuhack/flush_uppermem_cache.h b/dists/gph/gp2x/mmuhack/flush_uppermem_cache.h
index d01548e474..d01548e474 100644
--- a/backends/platform/gph/devices/gp2x/mmuhack/flush_uppermem_cache.h
+++ b/dists/gph/gp2x/mmuhack/flush_uppermem_cache.h
diff --git a/backends/platform/gph/devices/gp2x/mmuhack/flush_uppermem_cache.s b/dists/gph/gp2x/mmuhack/flush_uppermem_cache.s
index 265908e1fd..265908e1fd 100644
--- a/backends/platform/gph/devices/gp2x/mmuhack/flush_uppermem_cache.s
+++ b/dists/gph/gp2x/mmuhack/flush_uppermem_cache.s
diff --git a/backends/platform/gph/devices/gp2x/mmuhack/mmuhack.c b/dists/gph/gp2x/mmuhack/mmuhack.c
index 2e38bdb284..2e38bdb284 100644
--- a/backends/platform/gph/devices/gp2x/mmuhack/mmuhack.c
+++ b/dists/gph/gp2x/mmuhack/mmuhack.c
diff --git a/backends/platform/gph/devices/gp2x/mmuhack/mmuhack.o b/dists/gph/gp2x/mmuhack/mmuhack.o
index 475f4a54ae..475f4a54ae 100644
--- a/backends/platform/gph/devices/gp2x/mmuhack/mmuhack.o
+++ b/dists/gph/gp2x/mmuhack/mmuhack.o
Binary files differ
diff --git a/backends/platform/gph/devices/gp2x/scummvm.gpe b/dists/gph/gp2x/scummvm.gpe
index 51a49f7560..51a49f7560 100644
--- a/backends/platform/gph/devices/gp2x/scummvm.gpe
+++ b/dists/gph/gp2x/scummvm.gpe
diff --git a/backends/platform/gph/devices/gp2xwiz/scummvm-gdb.gpe b/dists/gph/gp2xwiz/scummvm-gdb.gpe
index 63ce193ca8..63ce193ca8 100644
--- a/backends/platform/gph/devices/gp2xwiz/scummvm-gdb.gpe
+++ b/dists/gph/gp2xwiz/scummvm-gdb.gpe
diff --git a/backends/platform/gph/devices/gp2xwiz/scummvm.gpe b/dists/gph/gp2xwiz/scummvm.gpe
index 59ff562aeb..59ff562aeb 100644
--- a/backends/platform/gph/devices/gp2xwiz/scummvm.gpe
+++ b/dists/gph/gp2xwiz/scummvm.gpe
diff --git a/backends/platform/gph/devices/common/scummvm.ini b/dists/gph/scummvm.ini
index c9cce92379..952cd0de24 100644
--- a/backends/platform/gph/devices/common/scummvm.ini
+++ b/dists/gph/scummvm.ini
@@ -1,5 +1,5 @@
[info]
-name="ScummVM"
+name="ScummVM 1.5.0git"
path="/scummvm/scummvm.gpe"
icon="/scummvm/scummvm.png"
title="/scummvm/scummvmb.png"
diff --git a/dists/gph/scummvm.ini.in b/dists/gph/scummvm.ini.in
new file mode 100644
index 0000000000..1c80d97d8b
--- /dev/null
+++ b/dists/gph/scummvm.ini.in
@@ -0,0 +1,5 @@
+[info]
+name="ScummVM @VERSION@"
+path="/scummvm/scummvm.gpe"
+icon="/scummvm/scummvm.png"
+title="/scummvm/scummvmb.png"
diff --git a/backends/platform/gph/devices/common/scummvm.png b/dists/gph/scummvm.png
index 128e59efc4..128e59efc4 100644
--- a/backends/platform/gph/devices/common/scummvm.png
+++ b/dists/gph/scummvm.png
Binary files differ
diff --git a/backends/platform/gph/devices/common/scummvmb.png b/dists/gph/scummvmb.png
index 24a27bc0e1..24a27bc0e1 100644
--- a/backends/platform/gph/devices/common/scummvmb.png
+++ b/dists/gph/scummvmb.png
Binary files differ
diff --git a/dists/irix/scummvm.idb b/dists/irix/scummvm.idb
index 73876e6bd1..6a613bbbd5 100644
--- a/dists/irix/scummvm.idb
+++ b/dists/irix/scummvm.idb
@@ -8,7 +8,6 @@ f 0644 root sys usr/ScummVM/share/pixmaps/scummvm.xpm scummvm.xpm scummvm.sw.eoe
f 0644 root sys usr/ScummVM/share/scummvm/drascula.dat drascula.dat scummvm.sw.eoe
f 0644 root sys usr/ScummVM/share/scummvm/kyra.dat kyra.dat scummvm.sw.eoe
f 0644 root sys usr/ScummVM/share/scummvm/lure.dat lure.dat scummvm.sw.eoe
-f 0644 root sys usr/ScummVM/share/scummvm/m4.dat m4.dat scummvm.sw.eoe
f 0644 root sys usr/ScummVM/share/scummvm/pred.dic pred.dic scummvm.sw.eoe
f 0644 root sys usr/ScummVM/share/scummvm/queen.tbl queen.tbl scummvm.sw.eoe
f 0644 root sys usr/ScummVM/share/scummvm/scummmodern.zip scummmodern.zip scummvm.sw.eoe
diff --git a/dists/macosx/DS_Store b/dists/macosx/DS_Store
index 2d4193a6af..7ad5a19d61 100644
--- a/dists/macosx/DS_Store
+++ b/dists/macosx/DS_Store
Binary files differ
diff --git a/dists/macosx/Info.plist b/dists/macosx/Info.plist
index a355ec1e62..94adc00a9b 100644
--- a/dists/macosx/Info.plist
+++ b/dists/macosx/Info.plist
@@ -28,7 +28,7 @@
<key>CFBundleExecutable</key>
<string>scummvm</string>
<key>CFBundleGetInfoString</key>
- <string>1.5.0git, Copyright 2001-2011 The ScummVM team</string>
+ <string>1.5.0git, Copyright 2001-2012 The ScummVM team</string>
<key>CFBundleIconFile</key>
<string>scummvm.icns</string>
<key>CFBundleIdentifier</key>
@@ -46,7 +46,7 @@
<key>NSPrincipalClass</key>
<string>NSApplication</string>
<key>NSHumanReadableCopyright</key>
- <string>Copyright 2001-2011 The ScummVM team</string>
+ <string>Copyright 2001-2012 The ScummVM team</string>
<key>SUFeedURL</key>
<string>http://www.scummvm.org/appcasts/macosx/release.xml</string>
<key>SUPublicDSAKeyFile</key>
diff --git a/dists/macosx/Info.plist.in b/dists/macosx/Info.plist.in
index b251f32509..ff010bee07 100644
--- a/dists/macosx/Info.plist.in
+++ b/dists/macosx/Info.plist.in
@@ -28,7 +28,7 @@
<key>CFBundleExecutable</key>
<string>scummvm</string>
<key>CFBundleGetInfoString</key>
- <string>@VERSION@, Copyright 2001-2011 The ScummVM team</string>
+ <string>@VERSION@, Copyright 2001-2012 The ScummVM team</string>
<key>CFBundleIconFile</key>
<string>scummvm.icns</string>
<key>CFBundleIdentifier</key>
@@ -46,7 +46,7 @@
<key>NSPrincipalClass</key>
<string>NSApplication</string>
<key>NSHumanReadableCopyright</key>
- <string>Copyright 2001-2011 The ScummVM team</string>
+ <string>Copyright 2001-2012 The ScummVM team</string>
<key>SUFeedURL</key>
<string>http://www.scummvm.org/appcasts/macosx/release.xml</string>
<key>SUPublicDSAKeyFile</key>
diff --git a/backends/platform/openpandora/build/PXML.xml b/dists/openpandora/PXML.xml
index a87c49e2b8..896210bf01 100755..100644
--- a/backends/platform/openpandora/build/PXML.xml
+++ b/dists/openpandora/PXML.xml
@@ -4,11 +4,11 @@
<package id="scummvm.djwillis.0001">
<author name="DJWillis" website="http://www.scummvm.org/"/>
<!-- version type can be alpha, beta or release, set to release in branch -->
- <version major="1" minor="4" release="0" build="1" type="alpha"/>
+ <version major="1" minor="5" release="0" build="1" type="release"/>
<!-- Both title and titles are needed -->
- <title lang="en_US">ScummVM</title>
+ <title lang="en_US">ScummVM 1.5.0git</title>
<titles>
- <title lang="en_US">ScummVM</title>
+ <title lang="en_US">ScummVM 1.5.0git</title>
</titles>
<descriptions>
<description lang="en_US">
@@ -25,7 +25,7 @@
<exec command="./runscummvm.sh"/>
<author name="DJWillis" website="http://www.scummvm.org/"/>
<!-- version type can be alpha, beta or release, set to release in branch -->
- <version major="1" minor="4" release="0" build="1" type="alpha"/>
+ <version major="1" minor="5" release="0" build="1" type="release"/>
<!-- Both title and titles are needed -->
<title lang="en_US">ScummVM</title>
<titles>
diff --git a/dists/openpandora/PXML.xml.in b/dists/openpandora/PXML.xml.in
new file mode 100644
index 0000000000..938e9cb24a
--- /dev/null
+++ b/dists/openpandora/PXML.xml.in
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<PXML xmlns="http://openpandora.org/namespaces/PXML" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="PXML_schema.xsd">
+ <!-- This is the package, in our case ScummVM -->
+ <package id="scummvm.djwillis.0001">
+ <author name="DJWillis" website="http://www.scummvm.org/"/>
+ <!-- version type can be alpha, beta or release, set to release in branch -->
+ <version major="@VER_MAJOR@" minor="@VER_MINOR@" release="@VER_PATCH@" build="1" type="release"/>
+ <!-- Both title and titles are needed -->
+ <title lang="en_US">ScummVM @VERSION@</title>
+ <titles>
+ <title lang="en_US">ScummVM @VERSION@</title>
+ </titles>
+ <descriptions>
+ <description lang="en_US">
+ ScummVM is a program which allows you to run certain classic graphical point-and-click adventure games, provided you already have their data files. The clever part about this: ScummVM just replaces the executables shipped with the games, allowing you to play them on systems for which they were never designed!
+
+ ScummVM supports many adventure games, including LucasArts SCUMM games (such as Monkey Island 1-3, Day of the Tentacle, Sam &amp; Max, ...), many of Sierra's AGI and SCI games (such as King's Quest 1-6, Space Quest 1-5, ...), Discworld 1 and 2, Simon the Sorcerer 1 and 2, Beneath A Steel Sky, Lure of the Temptress, Broken Sword 1 and 2, Flight of the Amazon Queen, Gobliiins 1-3, The Legend of Kyrandia 1-3, many of Humongous Entertainment's children's SCUMM games (including Freddi Fish and Putt Putt games) and many more.
+ </description>
+ </descriptions>
+ <icon src="icon/scummvm.png"/>
+ </package>
+
+ <!-- This is the application, the ScummVM binary -->
+ <application id="scummvm.djwillis.0001" appdata="scummvm">
+ <exec command="./runscummvm.sh"/>
+ <author name="DJWillis" website="http://www.scummvm.org/"/>
+ <!-- version type can be alpha, beta or release, set to release in branch -->
+ <version major="@VER_MAJOR@" minor="@VER_MINOR@" release="@VER_PATCH@" build="1" type="release"/>
+ <!-- Both title and titles are needed -->
+ <title lang="en_US">ScummVM</title>
+ <titles>
+ <title lang="en_US">ScummVM</title>
+ </titles>
+ <descriptions>
+ <description lang="en_US">
+ ScummVM is a program which allows you to run certain classic graphical point-and-click adventure games, provided you already have their data files. The clever part about this: ScummVM just replaces the executables shipped with the games, allowing you to play them on systems for which they were never designed!
+
+ ScummVM supports many adventure games, including LucasArts SCUMM games (such as Monkey Island 1-3, Day of the Tentacle, Sam &amp; Max, ...), many of Sierra's AGI and SCI games (such as King's Quest 1-6, Space Quest 1-5, ...), Discworld 1 and 2, Simon the Sorcerer 1 and 2, Beneath A Steel Sky, Lure of the Temptress, Broken Sword 1 and 2, Flight of the Amazon Queen, Gobliiins 1-3, The Legend of Kyrandia 1-3, many of Humongous Entertainment's children's SCUMM games (including Freddi Fish and Putt Putt games) and many more.
+ </description>
+ </descriptions>
+ <licenses>
+ <license name="GPLv2" url="http://www.gnu.org/licenses/gpl-2.0.html" sourcecodeurl="http://www.scummvm.org"/>
+ </licenses>
+ <icon src="icon/scummvm.png"/>
+ <previewpics>
+ <pic src="icon/preview-pic.png"/>
+ </previewpics>
+ <info name="ScummVM Documentation" type="text/html" src="docs/index.html"/>
+ <categories>
+ <category name="Game">
+ <subcategory name="AdventureGame"/>
+ </category>
+ </categories>
+ </application>
+</PXML>
diff --git a/backends/platform/openpandora/build/PXML_schema.xsd b/dists/openpandora/PXML_schema.xsd
index 7c0d635016..7c0d635016 100644
--- a/backends/platform/openpandora/build/PXML_schema.xsd
+++ b/dists/openpandora/PXML_schema.xsd
diff --git a/backends/platform/openpandora/build/README-OPENPANDORA b/dists/openpandora/README-OPENPANDORA
index c8aabcbb7a..b3947975c0 100755..100644
--- a/backends/platform/openpandora/build/README-OPENPANDORA
+++ b/dists/openpandora/README-OPENPANDORA
@@ -1,4 +1,4 @@
-ScummVM - OPENPANDORA SPECIFIC README
+ScummVM 1.5.0git - OPENPANDORA SPECIFIC README
------------------------------------------------------------------------
Please refer to the:
diff --git a/dists/openpandora/README-OPENPANDORA.in b/dists/openpandora/README-OPENPANDORA.in
new file mode 100644
index 0000000000..0a63a5938d
--- /dev/null
+++ b/dists/openpandora/README-OPENPANDORA.in
@@ -0,0 +1,19 @@
+ScummVM @VERSION@ - OPENPANDORA SPECIFIC README
+------------------------------------------------------------------------
+Please refer to the:
+
+ScummVM Forum: <http://forums.scummvm.org/>
+WiKi: <http://wiki.scummvm.org/index.php/OpenPandora>
+
+for the most current information on the port and any updates to this
+documentation.
+
+The wiki includes detailed instructions on how to use the port and
+control information.
+
+------------------------------------------------------------------------
+Credits
+
+Core ScummVM code (c) The ScummVM Team
+OpenPandora backend (c) John Willis
+Detailed (c) information can be found within the source code
diff --git a/backends/platform/openpandora/build/README-PND.txt b/dists/openpandora/README-PND.txt
index 942c3a43e2..240936f755 100755..100644
--- a/backends/platform/openpandora/build/README-PND.txt
+++ b/dists/openpandora/README-PND.txt
@@ -1,4 +1,4 @@
-ScummVM - OPENPANDORA README - HOW TO INSTALL
+ScummVM 1.5.0git - OPENPANDORA README - HOW TO INSTALL
------------------------------------------------------------------------
Please refer to the:
diff --git a/dists/openpandora/README-PND.txt.in b/dists/openpandora/README-PND.txt.in
new file mode 100644
index 0000000000..076c0e0a5c
--- /dev/null
+++ b/dists/openpandora/README-PND.txt.in
@@ -0,0 +1,38 @@
+ScummVM @VERSION@ - OPENPANDORA README - HOW TO INSTALL
+------------------------------------------------------------------------
+
+Please refer to the:
+
+ScummVM Forum: <http://forums.scummvm.org/>
+WiKi: <http://wiki.scummvm.org/index.php/OpenPandora>
+
+for the most current information on the port and any updates to this
+documentation.
+
+------------------------------------------------------------------------
+Installing:
+
+This archive contains ScummVM in a PND format ready to be copied to the
+OpenPandora and used.
+
+To install just copy the .pnd file from this archive to your device.
+
+You will need to place the .pnd file in a suitable location on your SD
+card.
+
+/pandora/desktop <- place here if you wish the icon to show on the
+ desktop. Documentation will show in the menu.
+
+/pandora/menu <- place here if you wish the icon to show on the
+ Xfce menu. Documentation will show in the menu.
+
+/pandora/apps <- place here if you wish the icon to show on the
+ desktop and in the menu. Documentation will show
+ in the menu.
+
+------------------------------------------------------------------------
+Credits
+
+Core ScummVM code (c) The ScummVM Team
+OpenPandora backend (c) John Willis
+Detailed (c) information can be found within the source code
diff --git a/backends/platform/openpandora/build/icon/preview-pic.png b/dists/openpandora/icon/preview-pic.png
index 2f4a536d30..2f4a536d30 100755..100644
--- a/backends/platform/openpandora/build/icon/preview-pic.png
+++ b/dists/openpandora/icon/preview-pic.png
Binary files differ
diff --git a/backends/platform/openpandora/build/icon/scummvm.png b/dists/openpandora/icon/scummvm.png
index 128e59efc4..128e59efc4 100755..100644
--- a/backends/platform/openpandora/build/icon/scummvm.png
+++ b/dists/openpandora/icon/scummvm.png
Binary files differ
diff --git a/backends/platform/openpandora/build/index.html b/dists/openpandora/index.html
index 34d381d0f8..d7238c1889 100755..100644
--- a/backends/platform/openpandora/build/index.html
+++ b/dists/openpandora/index.html
@@ -5,7 +5,7 @@
</h3>
<h4>
- <p>ScummVM: OpenPandora Specific Documentation</p>
+ <p>ScummVM 1.5.0git: OpenPandora Specific Documentation</p>
</h4>
<A href="docs/README-OPENPANDORA">ScummVM OpenPandora README</a><br/>
@@ -13,7 +13,7 @@
<A href="http://wiki.scummvm.org/index.php/OpenPandora">ScummVM OpenPandora WiKi</a><br/>
<h4>
- <p>ScummVM: General Documentation</p>
+ <p>ScummVM 1.5.0git: General Documentation</p>
</h4>
<A href="http://www.scummvm.org/">ScummVM website</a><br/>
diff --git a/dists/openpandora/index.html.in b/dists/openpandora/index.html.in
new file mode 100644
index 0000000000..42c8e8c147
--- /dev/null
+++ b/dists/openpandora/index.html.in
@@ -0,0 +1,26 @@
+<html>
+
+<h3>
+ <p>Welcome to the ScummVM!</p>
+</h3>
+
+<h4>
+ <p>ScummVM @VERSION@: OpenPandora Specific Documentation</p>
+</h4>
+
+<A href="docs/README-OPENPANDORA">ScummVM OpenPandora README</a><br/>
+<A href="http://scummvm.distant-earth.com/">ScummVM OpenPandora Website</a><br/>
+<A href="http://wiki.scummvm.org/index.php/OpenPandora">ScummVM OpenPandora WiKi</a><br/>
+
+<h4>
+ <p>ScummVM @VERSION@: General Documentation</p>
+</h4>
+
+<A href="http://www.scummvm.org/">ScummVM website</a><br/>
+<A href="docs/README">ScummVM README</a><br/>
+<A href="docs/NEWS">ScummVM NEWS</a><br/>
+<A href="docs/AUTHORS">ScummVM Authors</a><br/>
+<A href="docs/COPYRIGHT">ScummVM Copyright</a><br/>
+<A href="docs/COPYING">GPL Licence</a><br/>
+
+</html>
diff --git a/backends/platform/openpandora/build/pnd_make.sh b/dists/openpandora/pnd_make.sh
index 0c03e8154d..0c03e8154d 100755
--- a/backends/platform/openpandora/build/pnd_make.sh
+++ b/dists/openpandora/pnd_make.sh
diff --git a/backends/platform/openpandora/build/runscummvm.sh b/dists/openpandora/runscummvm.sh
index 9c9d8362cb..9c9d8362cb 100755
--- a/backends/platform/openpandora/build/runscummvm.sh
+++ b/dists/openpandora/runscummvm.sh
diff --git a/dists/redhat/scummvm.spec b/dists/redhat/scummvm.spec
index 7457ddd195..2ccccae79d 100644
--- a/dists/redhat/scummvm.spec
+++ b/dists/redhat/scummvm.spec
@@ -17,6 +17,7 @@ Url : http://www.scummvm.org
Source : %{name}-%{version}.tar.bz2
Source1 : libmad-0.15.1b.tar.bz2
+Source2 : faad2-2.7.tar.bz2
BuildRoot : %{_tmppath}/%{name}-%{version}-root
BuildRequires: desktop-file-utils
@@ -44,12 +45,13 @@ games) and many more. See http://www.scummvm.org for a full compatibility list.
# install scripts
#------------------------------------------------------------------------------
%prep
-%setup -q -a 1 -n scummvm-%{version}
+%setup -q -a 1 -a 2 -n scummvm-%{version}
mkdir tmp
%build
(cd libmad-0.15.1b; ./configure --enable-static --disable-shared --prefix=%{_builddir}/scummvm-%{version}/tmp; make; make install)
-./configure --with-mad-prefix=%{_builddir}/scummvm-%{version}/tmp --prefix=%{_prefix} --enable-release
+(cd faad2-2.7; ./configure --enable-static --disable-shared --prefix=%{_builddir}/scummvm-%{version}/tmp; make; make install)
+./configure --with-mad-prefix=%{_builddir}/scummvm-%{version}/tmp --with-faad-prefix=%{_builddir}/scummvm-%{version}/tmp --prefix=%{_prefix} --enable-release
make
%install
@@ -115,6 +117,8 @@ fi
# Change Log
#------------------------------------------------------------------------------
%changelog
+* Thu Dec 29 2011 (1.4.0-2)
+ - include libfaad2
* Fri Sep 17 2010 (1.2.0)
- include png/svg icons
- remove libmpeg2
diff --git a/dists/redhat/scummvm.spec.in b/dists/redhat/scummvm.spec.in
index 56e165c979..3beef2f960 100644
--- a/dists/redhat/scummvm.spec.in
+++ b/dists/redhat/scummvm.spec.in
@@ -17,6 +17,7 @@ Url : http://www.scummvm.org
Source : %{name}-%{version}.tar.bz2
Source1 : libmad-0.15.1b.tar.bz2
+Source2 : faad2-2.7.tar.bz2
BuildRoot : %{_tmppath}/%{name}-%{version}-root
BuildRequires: desktop-file-utils
@@ -44,12 +45,13 @@ games) and many more. See http://www.scummvm.org for a full compatibility list.
# install scripts
#------------------------------------------------------------------------------
%prep
-%setup -q -a 1 -n scummvm-%{version}
+%setup -q -a 1 -a 2 -n scummvm-%{version}
mkdir tmp
%build
(cd libmad-0.15.1b; ./configure --enable-static --disable-shared --prefix=%{_builddir}/scummvm-%{version}/tmp; make; make install)
-./configure --with-mad-prefix=%{_builddir}/scummvm-%{version}/tmp --prefix=%{_prefix} --enable-release
+(cd faad2-2.7; ./configure --enable-static --disable-shared --prefix=%{_builddir}/scummvm-%{version}/tmp; make; make install)
+./configure --with-mad-prefix=%{_builddir}/scummvm-%{version}/tmp --with-faad-prefix=%{_builddir}/scummvm-%{version}/tmp --prefix=%{_prefix} --enable-release
make
%install
@@ -115,6 +117,8 @@ fi
# Change Log
#------------------------------------------------------------------------------
%changelog
+* Thu Dec 29 2011 (1.4.0-2)
+ - include libfaad2
* Fri Sep 17 2010 (1.2.0)
- include png/svg icons
- remove libmpeg2
diff --git a/dists/scummvm.rc b/dists/scummvm.rc
index ce287cdd42..e5d28d089a 100644
--- a/dists/scummvm.rc
+++ b/dists/scummvm.rc
@@ -31,9 +31,6 @@ kyra.dat FILE "dists/engine-data/kyra.dat"
#if ENABLE_LURE == STATIC_PLUGIN
lure.dat FILE "dists/engine-data/lure.dat"
#endif
-#if ENABLE_M4 == STATIC_PLUGIN
-m4.dat FILE "dists/engine-data/m4.dat"
-#endif
#if ENABLE_QUEEN == STATIC_PLUGIN
queen.tbl FILE "dists/engine-data/queen.tbl"
#endif
@@ -71,7 +68,7 @@ BEGIN
VALUE "FileDescription", "http://www.scummvm.org/\0"
VALUE "FileVersion", "1.5.0git\0"
VALUE "InternalName", "scummvm\0"
- VALUE "LegalCopyright", "Copyright © 2001-2011 The ScummVM Team\0"
+ VALUE "LegalCopyright", "Copyright © 2001-2012 The ScummVM Team\0"
VALUE "LegalTrademarks", "'SCUMM', and all SCUMM games are a TM of LucasArts. Simon The Sorcerer is a TM of AdventureSoft. Beneath a Steel Sky and Broken Sword are a TM of Revolution. Flight of the Amazon Queen is a TM of John Passfield and Steve Stamatiadis. \0"
VALUE "OriginalFilename", "scummvm.exe\0"
VALUE "ProductName", "ScummVM\0"
diff --git a/dists/scummvm.rc.in b/dists/scummvm.rc.in
index b91e7ebb0c..6969e0b2a7 100644
--- a/dists/scummvm.rc.in
+++ b/dists/scummvm.rc.in
@@ -31,9 +31,6 @@ kyra.dat FILE "dists/engine-data/kyra.dat"
#if ENABLE_LURE == STATIC_PLUGIN
lure.dat FILE "dists/engine-data/lure.dat"
#endif
-#if ENABLE_M4 == STATIC_PLUGIN
-m4.dat FILE "dists/engine-data/m4.dat"
-#endif
#if ENABLE_QUEEN == STATIC_PLUGIN
queen.tbl FILE "dists/engine-data/queen.tbl"
#endif
@@ -71,7 +68,7 @@ BEGIN
VALUE "FileDescription", "http://www.scummvm.org/\0"
VALUE "FileVersion", "@VERSION@\0"
VALUE "InternalName", "scummvm\0"
- VALUE "LegalCopyright", "Copyright © 2001-2011 The ScummVM Team\0"
+ VALUE "LegalCopyright", "Copyright © 2001-2012 The ScummVM Team\0"
VALUE "LegalTrademarks", "'SCUMM', and all SCUMM games are a TM of LucasArts. Simon The Sorcerer is a TM of AdventureSoft. Beneath a Steel Sky and Broken Sword are a TM of Revolution. Flight of the Amazon Queen is a TM of John Passfield and Steve Stamatiadis. \0"
VALUE "OriginalFilename", "scummvm.exe\0"
VALUE "ProductName", "ScummVM\0"
diff --git a/dists/win32/ScummVM.iss b/dists/win32/ScummVM.iss
index 852597fb69..d0448c5620 100644
--- a/dists/win32/ScummVM.iss
+++ b/dists/win32/ScummVM.iss
@@ -1,5 +1,5 @@
[Setup]
-AppCopyright=2011
+AppCopyright=2012
AppName=ScummVM
AppVerName=ScummVM Git
AppPublisher=The ScummVM Team
@@ -37,6 +37,7 @@ Name: nb; MessagesFile: compiler:Languages\Norwegian.isl
Name: pl; MessagesFile: compiler:Languages\Polish.isl
Name: ru; MessagesFile: compiler:Languages\Russian.isl
Name: es; MessagesFile: compiler:Languages\Spanish.isl
+Name: se; MessagesFile: compiler:Languages\Swedish.isl
[Icons]
Name: {group}\{cm:UninstallProgram, ScummVM}; Filename: {uninstallexe}
@@ -44,48 +45,64 @@ Name: {group}\ScummVM; Filename: {app}\scummvm.exe; WorkingDir: {app}; Comment:
Name: {group}\ScummVM (noconsole); Filename: {app}\scummvm.exe; Parameters: "--no-console"; WorkingDir: {app}; Comment: scummvm; Flags: createonlyiffileexists; IconIndex: 0
Name: {group}\Authors; Filename: {app}\AUTHORS.txt; WorkingDir: {app}; Comment: AUTHORS; Flags: createonlyiffileexists
Name: {group}\Copying; Filename: {app}\COPYING.txt; WorkingDir: {app}; Comment: COPYING; Flags: createonlyiffileexists
+Name: {group}\Copying.FREEFONT; Filename: {app}\COPYING.FREEFONT.txt; WorkingDir: {app}; Comment: COPYING.FREEFONT; Flags: createonlyiffileexists
Name: {group}\Copying.LGPL; Filename: {app}\COPYING.LGPL.txt; WorkingDir: {app}; Comment: COPYING.LGPL; Flags: createonlyiffileexists
Name: {group}\Copyright; Filename: {app}\COPYRIGHT.txt; WorkingDir: {app}; Comment: COPYRIGHT; Flags: createonlyiffileexists
;NEWS
Name: {group}\News; Filename: {app}\NEWS.txt; WorkingDir: {app}; Comment: NEWS; Flags: createonlyiffileexists; Languages: not de
Name: {group}\Neues; Filename: {app}\Neues.txt; WorkingDir: {app}; Comment: Neues; Flags: createonlyiffileexists; Languages: de
;QUICKSTART
-Name: {group}\QuickStart; Filename: {app}\QUICKSTART.txt; WorkingDir: {app}; Comment: QUICKSTART; Flags: createonlyiffileexists; Languages: not (de or es or fr or it or nb)
+Name: {group}\QuickStart; Filename: {app}\QUICKSTART.txt; WorkingDir: {app}; Comment: QUICKSTART; Flags: createonlyiffileexists; Languages: not (de or es or fr or it or nb or se)
Name: {group}\Schnellstart; Filename: {app}\Schnellstart.txt; WorkingDir: {app}; Comment: Schnellstart; Flags: createonlyiffileexists; Languages: de
-Name: {group}\Inicio Rápido; Filename: {app}\Inicio Rápido.txt; WorkingDir: {app}; Comment: Inicio Rápido; Flags: createonlyiffileexists; Languages: es
+Name: {group}\InicioRapido; Filename: {app}\InicioRapido.txt; WorkingDir: {app}; Comment: InicioRapido; Flags: createonlyiffileexists; Languages: es
Name: {group}\DemarrageRapide; Filename: {app}\DemarrageRapide.txt; WorkingDir: {app}; Comment: DemarrageRapide; Flags: createonlyiffileexists; Languages: fr
Name: {group}\GuidaRapida; Filename: {app}\GuidaRapida.txt; WorkingDir: {app}; Comment: GuidaRapida; Flags: createonlyiffileexists; Languages: it
Name: {group}\HurtigStart; Filename: {app}\HurtigStart.txt; WorkingDir: {app}; Comment: HurtigStart; Flags: createonlyiffileexists; Languages: nb
+Name: {group}\Snabbstart; Filename: {app}\Snabbstart.txt; WorkingDir: {app}; Comment: Snabbstart; Flags: createonlyiffileexists; Languages: se
;README
-Name: {group}\Readme; Filename: {app}\README.txt; WorkingDir: {app}; Comment: README; Flags: createonlyiffileexists; Languages: not (cz or de)
+Name: {group}\Readme; Filename: {app}\README.txt; WorkingDir: {app}; Comment: README; Flags: createonlyiffileexists; Languages: not (cz or de or se)
Name: {group}\PrectiMe; Filename: {app}\PrectiMe.txt; WorkingDir: {app}; Comment: PrectiMe; Flags: createonlyiffileexists; Languages: cz
Name: {group}\Liesmich; Filename: {app}\Liesmich.txt; WorkingDir: {app}; Comment: Liesmich; Flags: createonlyiffileexists; Languages: de
+Name: {group}\LasMig; Filename: {app}\LasMig.txt; WorkingDir: {app}; Comment: LasMig; Flags: createonlyiffileexists; Languages: se
+
+Name: {group}\Saved Games\Migrate Saved Games; Filename: {app}\migration.bat; WorkingDir: {app}; Comment: Migrate Saved Games; IconIndex: 0; MinVersion: 0, 1
+Name: {group}\Saved Games\Saved Games (old default); Filename: {app}; WorkingDir: {app}; Comment: Saved Games (old default); IconIndex: 0; MinVersion: 0, 1
+Name: {group}\Saved Games\Saved Games (new default); Filename: {userappdata}\ScummVM\Saved Games; WorkingDir: {userappdata}\ScummVM\Saved Games; Comment: Saved Games (new default); IconIndex: 0; MinVersion: 0, 1
[Run]
Filename: {app}\ScummVM.exe; Flags: nowait skipifdoesntexist postinstall skipifsilent
+;Creates a symbolic link for standard save games area, under Windows Vista/7
+Filename: {cmd}; Parameters: "/c ""mklink /d ""%userprofile%\Saved Games\ScummVM"" ""%appdata%\ScummVM\Saved games"" "" "; MinVersion: 0, 6.1
[UninstallDelete]
Type: files; Name: {app}\ISTool.url
+[Dirs]
+Name: "{userappdata}\ScummVM"; MinVersion: 0, 1
+Name: "{userappdata}\ScummVM\Saved Games"; MinVersion: 0, 1
+
[Files]
Source: AUTHORS.txt; DestDir: {app}; Flags: ignoreversion
Source: COPYING.txt; DestDir: {app}; Flags: ignoreversion
+Source: COPYING.FREEFONT.txt; DestDir: {app}; Flags: ignoreversion
Source: COPYING.LGPL.txt; DestDir: {app}; Flags: ignoreversion
Source: COPYRIGHT.txt; DestDir: {app}; Flags: ignoreversion
;NEWS
Source: NEWS.txt; DestDir: {app}; Flags: ignoreversion; Languages: not de
Source: doc/de/Neues.txt; DestDir: {app}; Flags: ignoreversion; Languages: de
;QUICKSTART
-Source: doc/QUICKSTART.txt; DestDir: {app}; Flags: ignoreversion isreadme; Languages: not (de or es or fr or it or nb)
+Source: doc/QUICKSTART.txt; DestDir: {app}; Flags: ignoreversion isreadme; Languages: not (de or es or fr or it or nb or se)
Source: doc/de/Schnellstart.txt; DestDir: {app}; Flags: ignoreversion isreadme; Languages: de
-Source: doc/es/Inicio Rápido.txt; DestDir: {app}; Flags: ignoreversion isreadme; Languages: es
+Source: doc/es/InicioRapido.txt; DestDir: {app}; Flags: ignoreversion isreadme; Languages: es
Source: doc/fr/DemarrageRapide.txt; DestDir: {app}; Flags: ignoreversion isreadme; Languages: fr
Source: doc/it/GuidaRapida.txt; DestDir: {app}; Flags: ignoreversion isreadme; Languages: it
Source: doc/no-nb/HurtigStart.txt; DestDir: {app}; Flags: ignoreversion isreadme; Languages: nb
+Source: doc/se/Snabbstart.txt; DestDir: {app}; Flags: ignoreversion isreadme; Languages: se
;README
-Source: README.txt; DestDir: {app}; Flags: ignoreversion isreadme; Languages: not (cz or de)
+Source: README.txt; DestDir: {app}; Flags: ignoreversion isreadme; Languages: not (cz or de or se)
Source: doc/cz/PrectiMe.txt; DestDir: {app}; Flags: ignoreversion isreadme; Languages: cz
Source: doc/de/Liesmich.txt; DestDir: {app}; Flags: ignoreversion isreadme; Languages: de
+Source: doc/se/LasMig.txt; DestDir: {app}; Flags: ignoreversion isreadme; Languages: se
Source: README-SDL.txt; DestDir: {app}; Flags: ignoreversion
Source: scummvm.exe; DestDir: {app}; Flags: ignoreversion
Source: SDL.dll; DestDir: {app}
@@ -95,10 +112,14 @@ Source: drascula.dat; DestDir: {app}; Flags: ignoreversion
Source: hugo.dat; DestDir: {app}; Flags: ignoreversion
Source: kyra.dat; DestDir: {app}; Flags: ignoreversion
Source: lure.dat; DestDir: {app}; Flags: ignoreversion
-Source: m4.dat; DestDir: {app}; Flags: ignoreversion
Source: pred.dic; DestDir: {app}; Flags: ignoreversion
Source: queen.tbl; DestDir: {app}; Flags: ignoreversion
Source: sky.cpt; DestDir: {app}; Flags: ignoreversion
Source: teenagent.dat; DestDir: {app}; Flags: ignoreversion
Source: toon.dat; DestDir: {app}; Flags: ignoreversion
Source: translations.dat; DestDir: {app}; Flags: ignoreversion
+;Mirgration script for saved games in Windows NT4 onwards
+Source: migration.bat; DestDir: {app}; Flags: ignoreversion; MinVersion: 0, 1
+Source: migration.txt; DestDir: {app}; Flags: ignoreversion; MinVersion: 0, 1
+
+
diff --git a/dists/win32/migration.bat b/dists/win32/migration.bat
new file mode 100644
index 0000000000..2bba7baef4
--- /dev/null
+++ b/dists/win32/migration.bat
@@ -0,0 +1,51 @@
+:: Script for migrating saved games in Windows 2000/XP/Vista/7
+::
+:: Put this batch file into the ScummVM directory
+:: This script will copy any saved games located in the
+:: old default location, to the new default location.
+::
+:: (c) 2012 ScummVM Team
+::
+
+@echo off
+echo ScummVM Saved Games Migration Script
+echo The default location for saved games changed
+echo in Windows NT4/2000/XP/Vista/7 for ScummVM 1.5.0
+echo This script will copy any saved games stored in
+echo the old default location, to the new default location
+pause
+
+if defined APPDATA goto :test2
+echo.
+echo Unable to access the Application Data variable!
+pause
+goto :eof
+
+:test2
+if exist "%APPDATA%" goto :test3
+echo.
+echo Application Data directory doesn't exist!
+pause
+goto :eof
+
+:test3
+if exist "%APPDATA%\ScummVM\" goto :test4
+echo.
+echo ScummVM Application Data directory doesn't exist!
+pause
+goto :eof
+
+:test4
+if exist "%APPDATA%\ScummVM\Saved Games\" goto :copyfiles
+echo.
+echo ScummVM Saved Games directory doesn't exist!
+pause
+goto :eof
+
+:copyfiles
+echo Copying ScummVM Saved Games...
+xcopy /EXCLUDE:migration.txt /F /-Y * "%APPDATA%\ScummVM\Saved Games"
+
+echo.
+echo All saved games have been copied to the new location of "%APPDATA%\ScummVM\Saved Games"
+pause
diff --git a/dists/win32/migration.txt b/dists/win32/migration.txt
new file mode 100644
index 0000000000..eedd773b32
--- /dev/null
+++ b/dists/win32/migration.txt
@@ -0,0 +1,27 @@
+AUTHORS.txt
+COPYING.LGPL.txt
+COPYING.txt
+COPYRIGHT.txt
+drascula.dat
+hugo.dat
+kyra.dat
+lure.dat
+m4.dat
+NEWS.txt
+pred.dic
+queen.tbl
+QUICKSTART.txt
+README-SDL.txt
+README.txt
+scummclassic.zip
+scummmodern.zip
+scummvm.exe
+SDL.dll
+sky.cpt
+teenagent.dat
+migration.bat
+migration.txt
+toon.dat
+translations.dat
+unins000.dat
+unins000.exe
diff --git a/dists/win32/scummvm.nsi b/dists/win32/scummvm.nsi
index 23a3abcfd4..7ff174befb 100644
--- a/dists/win32/scummvm.nsi
+++ b/dists/win32/scummvm.nsi
@@ -76,7 +76,7 @@ Name ScummVM
!define COMPANY "ScummVM Team"
!define URL "http://scummvm.org/"
!define DESCRIPTION "ScummVM Installer. Look! A three headed monkey (TM)!"
-!define COPYRIGHT "Copyright © 2001-2011 The ScummVM Team"
+!define COPYRIGHT "Copyright © 2001-2012 The ScummVM Team"
#########################################################################################
# Installer configuration
@@ -265,7 +265,6 @@ Section "ScummVM" SecMain
File "${engine_data}\hugo.dat"
File "${engine_data}\kyra.dat"
File "${engine_data}\lure.dat"
- File "${engine_data}\m4.dat"
File "${engine_data}\queen.tbl"
File "${engine_data}\sky.cpt"
File "${engine_data}\teenagent.dat"
@@ -352,7 +351,6 @@ Section -un.Main SecUninstall
Delete /REBOOTOK $INSTDIR\hugo.dat
Delete /REBOOTOK $INSTDIR\kyra.dat
Delete /REBOOTOK $INSTDIR\lure.dat
- Delete /REBOOTOK $INSTDIR\m4.dat
Delete /REBOOTOK $INSTDIR\queen.tbl
Delete /REBOOTOK $INSTDIR\sky.cpt
Delete /REBOOTOK $INSTDIR\teenagent.dat
diff --git a/dists/win32/scummvm.nsi.in b/dists/win32/scummvm.nsi.in
index cba1e81e33..340024e6a1 100644
--- a/dists/win32/scummvm.nsi.in
+++ b/dists/win32/scummvm.nsi.in
@@ -76,7 +76,7 @@ Name ScummVM
!define COMPANY "ScummVM Team"
!define URL "http://scummvm.org/"
!define DESCRIPTION "ScummVM Installer. Look! A three headed monkey (TM)!"
-!define COPYRIGHT "Copyright © 2001-2011 The ScummVM Team"
+!define COPYRIGHT "Copyright © 2001-2012 The ScummVM Team"
#########################################################################################
# Installer configuration
@@ -265,7 +265,6 @@ Section "ScummVM" SecMain
File "${engine_data}\hugo.dat"
File "${engine_data}\kyra.dat"
File "${engine_data}\lure.dat"
- File "${engine_data}\m4.dat"
File "${engine_data}\queen.tbl"
File "${engine_data}\sky.cpt"
File "${engine_data}\teenagent.dat"
@@ -352,7 +351,6 @@ Section -un.Main SecUninstall
Delete /REBOOTOK $INSTDIR\hugo.dat
Delete /REBOOTOK $INSTDIR\kyra.dat
Delete /REBOOTOK $INSTDIR\lure.dat
- Delete /REBOOTOK $INSTDIR\m4.dat
Delete /REBOOTOK $INSTDIR\queen.tbl
Delete /REBOOTOK $INSTDIR\sky.cpt
Delete /REBOOTOK $INSTDIR\teenagent.dat
diff --git a/doc/cz/PrectiMe b/doc/cz/PrectiMe
index cf5cd53986..cb2484299b 100644
--- a/doc/cz/PrectiMe
+++ b/doc/cz/PrectiMe
@@ -1,5 +1,4 @@
PŘEČTIMĚ ScummVM
-Poslední aktualizace: $Date$
------------------------------------------------------------------------
Pro více informací, seznamy kompatibility, podrobnosti o dotacích, nejnovější verze, novinky o vývoji a další, prosím navštivte domovskou stránku ScummVM na: http://www.scummvm.org/
@@ -388,6 +387,10 @@ Pokyny pro hry Broken Sword jsou pro verze od Sold-Out Software, kde každá hra
------ -------------------------
Videa pro hry Broken Sword mají v sobÄ› trochu historie (viz další oddíl, pokud jste zvÄ›daví), ale obecnÄ› jediné, co potÅ™ebujete udÄ›lat, je zkopírovat soubory .SMK ze složek "SMACKS" nebo "SMACKSHI" na CD do stejné složky jako ostatní datové soubory hry. (Broken Sword má také složku "SMACKSLO" se stejnými videi, ale ty jsou nižší kvality.) Můžete je umístit do podsložky s názvem "video", pokud Vám to pÅ™ijde hezÄí.
+Ve verzích pro PlayStation, můžete původní videa vypsat z disku. Každý soubor, který má příponu "STR", byste mÄ›li vypsat jako *Äist* sektory z disku (vÅ¡ech 2352 bajtů na sektor). Můžete také míst toho použít pÅ™eformátovaná videa, která jsou zmínÄ›na níže, ale to nebude fungovat pro vÅ¡echny videa v Broken Sword II. Pro více informací si prohlédnÄ›te:
+
+ http://wiki.scummvm.org/index.php/HOWTO-PlayStation_Videos
+
Některá vydání hry, a také verze pro PlayStation, Smacker videa nemají. Revolution Software nám laskavě dovolilo poskytovat přeformátovaná videa ke stažení na naší stránce:
http://www.scummvm.org/downloads.php
@@ -396,7 +399,7 @@ Tato videa jsou poskytována ve formátu DXA se zvukem ve formátu FLAC. Jejich
Pro systémy, které jsou příliš pomalé, aby zvládli dekódovat formát FLAC byl zvuk videí také poskytnut odděleně ve formátu OGG Vorbis audio. Toto vyžaduje, aby verze ScummVM byla sestavena s podporou libVorbis a zlib.
-Pro Broken Sword také poskytujeme přídavek pro titulky. Jednoduše ho rozbalte a následujte pokyny v souboru readme.txt. (Broken Sword II již titulky má; není třeba další práce pro jejich přidání.)
+Pro Broken Sword také poskytujeme přídavek pro titulky. JednoduÅ¡e ho rozbalte a následujte pokyny v souboru readme.txt. BalíÄek v souÄasnosti nefunguje ve videích na PlayStation. (Broken Sword II již titulky má; není tÅ™eba další práce pro jejich pÅ™idání.)
3.7.2) Videa her Broken Sword ve zpětném pohledu:
@@ -449,8 +452,7 @@ Také můžete použít nástroj 'compress_queen' z balíÄku nástrojů pro 'z
CD verze série Gobliiins obsahuje jednu velkou zvukovou stopu, kterou potÅ™ebujete vyjmout (viz oddíl o použití komprimovaných zvukových souborů) a zkopírovat ji do herní složky, pokud chcete ve hÅ™e hudbu, aniž byste museli CD mít stále v jednotce. V této stopÄ› jsou také Å™eÄ a její hlasitost se tedy také mÄ›ní podle hlasitosti hudby.
-3.11) Poznámky k Inherit the Earth: Quest for the Orb
-:
+3.11) Poznámky k Inherit the Earth: Quest for the Orb:
----- ------------------------------------------------
Abyste mohli spustit verzi pro Mac OS X od Wyrmkeep musíte data zkopírovat z CD na Váš pevný disk. Pokud používáte PC, pak se podívejte na:
@@ -482,8 +484,11 @@ Přejmenovat voices.wav na CD4 na voices4.wav
3.14) Poznámky k The Legend of Kyrandia:
----- ----------------------------------
-Abyste mohli spustit The Legend of Kyrandia ve ScummVM potřebujete soubor 'kyra.dat', který můžete najít na stránce 'Downloads' domovské stránky ScummVM.
-
+Abyste mohli spustit The Legend of Kyrandia ve ScummVM potřebujete soubor 'kyra.dat'.
+Soubor by mÄ›l být vždykcy souÄástí oficiálních balíÄků ScummVM. V případÄ›, že ScummVM
+hlásí, že soubor chybá, můžete ho najít na stránce ScummVM v sekci 'Downloads'.
+Nezapomeňte, že souÄasná verze ScummVM pro Windows by mÄ›la soubor obsahovat ve spouÅ¡tÄ›Äi a tudíž ho
+musíte mít pouze, když ScummVM soubor nemůže nalézt.
3.15) Poznámky k Předvídavému Vstupnímu Dialogu her Sierra AGI:
----- ---------------------------------------------------------
@@ -491,7 +496,7 @@ Předvídavý Vstupní Dialog je pomůcka ScummVM pro spouštění her používa
Abyste zapnuli pÅ™edvídavý vstup v hrách AGI, potÅ™ebujete zkopírovat soubor pred.dic do dodateÄné složky ScummVM nebo do složky hry, kterou chcete hrát. Tento slovník byl vytvoÅ™en analýzou vÅ¡ech známých her AGI a obsahuje maximální sadu běžných slov.
-Pokud je slovník zjiÅ¡tÄ›n je PÅ™edvídavý Vstupní Dialog zobrazen buÄ pÅ™i klinutí na oblast příkazového řádku (kdykoliv je požadován vstup klávesnice, i v rámeÄcích dialogových oken), nebo v nÄ›kterých verzích pro jiné systémy stisknutím urÄené klávesové zkratky.
+Pokud je slovník zjiÅ¡tÄ›n, je PÅ™edvídavý Vstupní Dialog zobrazen buÄ pÅ™i klinutí na oblast příkazového řádku (kdykoliv je požadován vstup klávesnice, i v rámeÄcích dialogových oken), nebo v nÄ›kterých verzích pro jiné systémy stisknutím urÄené klávesové zkratky.
PÅ™edvídavý Vstupní Dialog pracuje ve tÅ™ech režimech, které jsou pÅ™epínány tlaÄítkem (*)Pre/123/Abc. Hlavní vstupní metodou je pÅ™edvídavý režim
(Pre), který připomíná "rychlé zadávání" v mobilních telefonech.
@@ -507,7 +512,7 @@ Dialogové okno je plně použitelné pomocí myši, ale v některých verzích
3.16) Poznámky k Mickey's Space Adventure:
----- ------------------------------------
-Abyste mohli Mickey's Space Adventure hrát ve ScummVM, potÅ™ebujete spolu s datovými soubory hry také původní spouÅ¡tÄ›Ä executable (mickey.exe).
+Abyste mohli Mickey's Space Adventure hrát ve ScummVM, potÅ™ebujete spolu s datovými soubory hry také původní spouÅ¡tÄ›Ä (mickey.exe).
Pro tuto hru ve ScummVM, existuje rozšířená podpora myÅ¡i, i když v původní hÅ™e takováto podpora nebyla. Položky menu mohou být vybrány pomocí myÅ¡i a je také možné se myší pÅ™esunout do jiných míst. Když se kurzor myÅ¡i nachází na okraji obrazovky, zÄervená, pokud je možné jít v tomto smÄ›ru. HrÃ¡Ä pak může jednoduÅ¡e kliknout na okraje herní obrazovky pro zmÄ›nu místa, podobnÄ› jako mnoho adventur, což je jednodušší a přímoÄaÅ™ejší než pohyb pomocí menu.
@@ -543,10 +548,7 @@ Toto vydání má následující známé problémy. Není třeba je ohlašovat,
- PÅ™i hraní her, které používají CD Audio (hry FM-TOWNS, Loom CD, atd) může u uživatelů Microsoft Windows 2000/XP docházet k náhodným pádům. To je díky dlouhotrvající chybÄ› Windows, která má za následek poÅ¡kozené soubory pÅ™i Ätení z CD. Abyste se tomuto vyhnuli, zkopírujte, prosím, soubory na pevný disk
Verze FM-TOWNS:
-- Verze Kandži vyžaduje ROM písma FM-TOWNS Font
-- ScummVM bude náhodně padat v následujících hrách při použití ROM písma FM-TOWNS pro Kandži:
-The Secret of Monkey Island, Monkey Island 2: LeChuck's Revenge
-a Indiana Jones and the Fate of Atlantis
+- Verze Kandži vyžaduje ROM písma FM-TOWNS
Loom:
- Vypnutí titulků pomocí souboru nastavení je nevypne spolehlivě, protože skripty Loom je znovu automaticky zapnou
@@ -590,7 +592,6 @@ a Indiana Jones and the Fate of Atlantis
The Legend of Kyrandia:
- Ve verzích na disketě pro Mac není žádná hudba ani zvukové efekty.
- CD Macintosh používá zahrnutou hudbu a zvukové efekty z DOS.
-- Verze pro PC-9821 nemá podporu zvukových efektů.
Hry Humongous Entertainment:
- Pouze původní rozhraní pro uložení a naÄtení mohou být použity.
@@ -668,6 +669,7 @@ ScummVM může také hru spustit přímo pomocí argumentů příkazové řádky
--themepath=CESTA Cesta kde jsou vzhledy rozhraní uloženy
--list-themes Zobrazí seznam všech použitelných vzhledů
-e, --music-driver=REŽIM Vybere ovladaÄ hudby (viz také Äást 7.0)
+ --list-audio-devices Zobrazí seznam všech dostupných zvukových zařízení
-q, --language=JAZYK Vybere jazyk hry (viz také Äást 5.2)
-m, --music-volume=Č. Nastaví hlasitost hudby, 0-255 (výchozí: 192)
-s, --sfx-volume=Č. Nastaví hlasitost zvuků, 0-255 (výchozí: 192)
@@ -816,19 +818,28 @@ Jádra, která v souÄasnosti podporují návrat do spouÅ¡tÄ›Äe, jsou:
AGI
AGOS
CINE
+ COMPOSER
+ CRUISE
DRACI
+ DRASCULA
GOB
GROOVIE
+ HUGO
KYRA
LURE
+ MADE
+ MOHAWK
PARALLACTION
QUEEN
SAGA
+ SCI
SCUMM
SKY
SWORD1
SWORD2
+ TEENAGENT
TOUCHE
+ TSAGE
TUCKER
@@ -977,16 +988,36 @@ Poznámka pro uživatele WinCE: Kvůli omezenému vstupu z klávesnice ve vÄ›tÅ
6.0) Uložené hry:
---- ------------
-Uložené hry jsou na nÄ›kterých platformách standardnÄ› umístÄ›ny do souÄasné složky a v jiných do pÅ™ednastavené složky. To můžete urÄit v souboru s nastavení nastavením parametru savepath. Podívejte se na vzorový soubor s nastavením dále v tomto souboru.
+Uložené hry jsou na nÄ›kterých platformách standardnÄ› umístÄ›ny do souÄasné složky a v jiných do pÅ™ednastavené složky. To můžete urÄit v souboru s nastavením pomocí parametru savepath. Podívejte se na vzorový soubor s nastavením dále v tomto souboru.
Platformy, které v souÄasnosti mají jiné výchozí složky jsou:
- Mac OS X: $HOME/Documents/ScummVM Savegames/
- Jiné unixy: $HOME/.scummvm/
+ Mac OS X:
+ $HOME/Documents/ScummVM Savegames/
+
+ Jiné unixy:
+ $HOME/.scummvm/
+
+ Windows Vista/7:
+ \Users\užjméno\AppData\Roaming\ScummVM\Saved games\
+
+ Windows 2000/XP:
+ \Documents and Settings\užjméno\Application Data\ScummVM\Saved games\
+
+ Windows NT4:
+ <windir>\Profiles\užjméno\Application Data\ScummVM\Saved games\
+
+Uložené hry jsou ve Windows NT4/2000/XP/Vista/7 ukládány ve skryté složce,
+do které můžete vstoupit spuštěním "%APPDATA%\ScummVM\Saved Games\" nebo
+povolením zobrazení skrytých složek v Průzkumníku Windows.
+
+Poznámka pro uživatele Windows NT4/2000/XP/Vista/7: Výchozí umístění uložených her
+bylo ve ScummVM 1.5.0 změněno. Dávkový soubor přesunu může být použit pro zkopírování
+uložených her ze starého výchozího umístění do nového.
6.1) 6.1 Automatické ukládání:
---- -------------------------
V některých hrách, (a to "Beneath a Steel Sky", "Flight of the Amazon
-Queen", vÅ¡echny hry AGI, and vÅ¡echny hry SCUMM), bude ScummVM standardnÄ› automaticky ukládat souÄasný stav každých pÅ¡t minut (upravitelné pomocí nastavení "autoukládání"). Pro jádra AGI a SCUMM, je bude ukládat do pozice 0. V jádru SCUMM může být tento uložený stav znovu naÄten pomocí Ctrl-0 nebo menu F5.
+Queen", vÅ¡echny hry AGI, a vÅ¡echny hry SCUMM), bude ScummVM standardnÄ› automaticky ukládat souÄasný stav každých pÄ›t minut (upravitelné pomocí nastavení "autoukládání"). Pro jádra AGI a SCUMM, je bude ukládat do pozice 0. V jádru SCUMM může být tento uložený stav znovu naÄten pomocí Ctrl-0 nebo menu F5.
6.2) Převod uložených her:
@@ -1030,20 +1061,28 @@ Kde 'xxx' je Äíslo pozice uložené hry (tj. 001) ve ScummVM
AGI
AGOS
+ CGE
CINE
+ CRUISE
DRACI
GROOVIE
+ HUGO
KYRA
LURE
+ MOHAWK
PARALLACTION
QUEEN
SAGA
+ SCI
SCUMM
SKY
SWORD1
SWORD2
+ TEENAGENT
TINSEL
+ TOON
TOUCHE
+ TSAGE
TUCKER
--save-slot/-x:
@@ -1055,20 +1094,28 @@ Kde 'xxx' je Äíslo pozice uložené hry (tj. 001) ve ScummVM
Jádra, která v souÄasnosti podporují--save-slot/-x jsou:
AGI
+ CGE
CINE
+ CRUISE
DRACI
GROOVIE
+ HUGO
KYRA
LURE
- PARALLACTION
+ MOHAWK
QUEEN
SAGA
+ SCI
SCUMM
SKY
SWORD1
SWORD2
+ TEENAGENT
TINSEL
+ TOON
TOUCHE
+ TSAGE
+ TUCKER
7.0) Hudba a Zvuk:
@@ -1370,7 +1417,7 @@ Použití kmitoÄtů mezi není doporuÄeno. Za prvé VaÅ¡e zvuková karta ho ne
---- --------------------
StandardnÄ› je soubor s nastavením uložen a naÄítán:
- Windows Vista:
+ Windows Vista/7:
\Users\jméno uživatele\AppData\Roaming\ScummVM\scummvm.ini,
Windows 2000/XP:
@@ -1493,10 +1540,13 @@ Simon the Sorcerer 1 a 2 pÅ™idává následující nestandardní klíÄová slov
music_mute boolean Pokud true, hudba je ztlumena
sfx_mute boolean Pokud true, zvukové efekty jsou ztlumeny
-The Legend of Kyrandia pÅ™idává následující nestandardní klíÄová slova:
+The Legend of Kyrandia pÅ™idává následující nestandardní klíÄové slovo:
walkspeed celé Äíslo Rychlost chůze (0-4)
+
+The 7th Guest pÅ™idává následující nestandardní klíÄové slovo:
+ t7g_speed řetězec Rychlost přehrávání videa (normal - normální, tweaked - upravená, im_an_ios - jsem na ios)
9.0) Sestavení:
---- ----------
@@ -1533,12 +1583,6 @@ Na Win9x/NT/XP můžete urÄit USE_WINDBG a pÅ™ipojit WinDbg pro procházení la
* PÅ™eÄtÄ›te si prosím:
http://wiki.scummvm.org/index.php/Compiling_ScummVM/Windows_CE
- Debian GNU/Linux:
- * VeVaÅ¡em systému nainstalujte balíÄky 'build-essential', 'fakeroot', 'debhelper' a 'libsdl1.2-dev'.
- * Instalujte jakýkoli z tÄ›chto balíÄků (nepovinné): 'libvorbis-dev' (pro podporu Ogg Vorbis), 'libasound2-dev' (pro podporu sekvencéru ALSA), 'libmad0-dev' (pro podporu MAD MP3), 'zlib1g-dev' (pro podporu komprimovaných uložených pozic).
- * Spusťte 'make deb'.
- * Nakonec spusťte 'dpkg -i ../scummvm-cvs*deb', a máte hotovo.
-
Mac OS X:
* Ujistěte se, že máte nainstalovány nástroje pro vývojáře.
* BalíÄek SDL pro vývojáře na OS X, který je dostupný na stránce SDL _není_ vhodný. Spíše potÅ™ebujete sestavení v unixovém stylu. Jeden takový způsob, jak ho nainstalovat je pomocí Fink
@@ -1574,3 +1618,5 @@ Hodně Štěstí a Šťastné Adventurování!
Tým ScummVM.
http://www.scummvm.org/
------------------------------------------------------------------------
+
+
diff --git a/doc/de/Liesmich b/doc/de/Liesmich
index b446250189..5d24ec050b 100644
--- a/doc/de/Liesmich
+++ b/doc/de/Liesmich
@@ -726,8 +726,12 @@ voices.wav von CD4 in voices4.wav
3.14) Hinweise zu The Legend of Kyrandia:
----- -----------------------------------
Um The Legend of Kyrandia unter ScummVM laufen zu lassen, benötigen Sie die
-Datei „kyra.dat“, welche auf der Seite „Downloads“ der ScummVM-Website gefunden
-werden kann.
+Datei „kyra.dat“. Die Datei sollte immer in offiziellen ScummVM-Paketen
+enthalten sein. Wenn ScummVM beanstandet, dass die Datei fehlt, können Sie sie
+auf der Seite „Downloads“ der ScummVM-Website finden. Beachten Sie, dass in der
+momentanen Windows-Version von ScummVM diese Datei in der ausführbaren Datei
+eingebettet sein sollte. Also müssen Sie sich nur diese besorgen, wenn sich
+ScummVM darüber beschwert, dass diese Datei fehlt.
3.15) Hinweise zum vorhersagenden Eingabedialog bei Sierras AGI-Spielen:
@@ -862,10 +866,6 @@ Kompatibilitätsseite der Website aufgeführt ist, sehen Sie bitte im Abschnitt
FM-TOWNS-Versionen:
- Die Kanji-Versionen erfordern die Schriftart-ROM-Datei von FM-TOWNS.
- - ScummVM stürzt bei Kanji-Versionen der folgenden Spielen zufällig ab, wenn
- die Schriftart-ROM-Datei von FM-TOWNS verwendet wird:
- The Secret of Monkey Island, Monkey Island 2: LeChuck's Revenge
- und Indiana Jones and the Fate of Atlantis
Loom:
- Das Abschalten der Untertitel über die Spieleinstellungen funktioniert
@@ -920,7 +920,6 @@ Kompatibilitätsseite der Website aufgeführt ist, sehen Sie bitte im Abschnitt
- Keine Musik oder Sound-Effekte in der Macintosh-Diskettenversion
- Die Macintosh-CD-Version verwendet eingebundene DOS-Musik und
DOS-Sound-Effekte.
- - PC-9821-Versionen fehlt Unterstützung für Sound-Effekte.
Spiele von Humongous Entertainment:
- Nur die Originaloberfläche kann zum Laden und Speichern verwendet werden.
@@ -1030,6 +1029,7 @@ gestartet werden -- siehe nächster Abschnitt.
--list-themes Zeigt Liste aller verwendbaren Oberflächenthemen.
-e, --music-driver=MODUS
Wählt Musiktreiber (siehe auch Abschnitt 7.0).
+ --list-audio-devices Listet alle verfügbaren Audiogeräte auf.
-q, --language=SPRACHE Wählt Spielsprache (siehe auch Abschnitt 5.2).
-m, --music-volume=ZAHL Wählt Musiklautstärke, 0-255 (Standard: 192).
-s, --sfx-volume=ZAHL Wählt Effektlautstärke, 0-255 (Standard: 192).
@@ -1233,19 +1233,28 @@ Die Engines, die momentan das Zurückkehren zur Spieleliste unterstützen, sind:
AGI
AGOS
CINE
+ COMPOSER
+ CRUISE
DRACI
+ DRASCULA
GOB
GROOVIE
+ HUGO
KYRA
LURE
+ MADE
+ MOHAWK
PARALLACTION
QUEEN
SAGA
+ SCI
SCUMM
SKY
SWORD1
SWORD2
+ TEENAGENT
TOUCHE
+ TSAGE
TUCKER
@@ -1428,8 +1437,22 @@ Verzeichnis gespeichert und bei anderen in voreingestellten Verzeichnissen.
Sehen Sie sich das Beispiel weiter unten in dieser Liesmich-Datei an.
Die folgenden Plattformen haben ein anderes Standardverzeichnis:
- Mac OS X: $HOME/Documents/ScummVM Savegames/
- Andere UNIX-Systeme: $HOME/.scummvm/
+ Mac OS X:
+ $HOME/Documents/ScummVM Savegames/
+
+ Andere UNIX-Systeme:
+ $HOME/.scummvm/
+
+ Windows Vista/7:
+ \Users\Benutzername\AppData\Roaming\ScummVM\Saved games\
+
+ Windows 2000/XP:
+ \Dokumente und Einstellungen\Benutzername\Anwendungsdaten\
+ ScummVM\Saved games\
+
+ Windows NT4:
+ <Windows-Verzeichnis>\Profiles\Benutzername\
+ Application Data\ScummVM\Saved games\
6.1) Automatische Spielstände:
@@ -1443,6 +1466,11 @@ automatischen Spielstände auf Platz 0 abgelegt. Bei der SCUMM-Engine kann diese
Speicherstand über die Tastenkombination Strg+0 oder über das F5-Menü geladen
werden.
+Spielstände werden unter Windows NT4/2000/XP/Vista/7 in einem versteckten
+Bereich gespeichert, auf den durch Aufruf von „%APPDATA%\ScummVM\Saved Games\“
+zugegriffen werden kann oder indem das Anzeigen versteckter Dateien im Windows
+Explorer aktiviert wird.
+
6.2) Spielstände umwandeln:
---- ----------------------
@@ -1495,20 +1523,28 @@ der Spielstand unter ScummVM befinden soll.
AGI
AGOS
+ CGE
CINE
+ CRUISE
DRACI
GROOVIE
+ HUGO
KYRA
LURE
+ MOHAWK
PARALLACTION
QUEEN
SAGA
+ SCI
SCUMM
SKY
SWORD1
SWORD2
+ TEENAGENT
TINSEL
+ TOON
TOUCHE
+ TSAGE
TUCKER
--save-slot/-x:
@@ -1522,20 +1558,28 @@ der Spielstand unter ScummVM befinden soll.
Die Engines, die momentan --save-slot/-x unterstützen, sind:
AGI
+ CGE
CINE
+ CRUISE
DRACI
GROOVIE
+ HUGO
KYRA
LURE
- PARALLACTION
+ MOHAWK
QUEEN
SAGA
+ SCI
SCUMM
SKY
SWORD1
SWORD2
+ TEENAGENT
TINSEL
+ TOON
TOUCHE
+ TSAGE
+ TUCKER
7.0) Musik und Sound:
@@ -2009,7 +2053,7 @@ Ausgabefrequenz ein Vielfaches der Originalfrequenz ist.
---- --------------------
Standardmäßig wird die Konfigurationsdatei hier gespeichert und geladen:
- Windows Vista:
+ Windows Vista/7:
\Users\Benutzername\AppData\Roaming\ScummVM\scummvm.ini
Windows 2000/XP:
@@ -2190,6 +2234,13 @@ Schlüsselwort:
walkspeed Zahl Bewegungsgeschwindigkeit (0-4)
+The 7th Guest verfügt zusätzlich über folgendes nicht standardmäßiges
+Schlüsselwort:
+
+ t7g_speed Text Videowiedergabe-Geschwindigkeit
+ (normal, tweaked [optimiert],
+ im_an_ios [ich bin ein iOS])
+
9.0) Kompilierung:
---- -------------
@@ -2243,17 +2294,6 @@ Debug-Nachrichten zu durchsuchen
* Bitte lesen Sie:
http://wiki.scummvm.org/index.php/Compiling_ScummVM/Windows_CE
- Debian GNU/Linux:
- * Installieren Sie die Pakete „build-essential“, „fakeroot“, „debhelper“,
- und „libsdl1.2-dev“ auf Ihrem Betriebssystem.
- * Installieren Sie beliebig viele der folgenden Pakete (optional):
- „libvorbis-dev“ (für Ogg-Vorbis-Unterstützung), „libasound2-dev“ (für
- ALSA-Sequenzer-Unterstützung), „libmad0-dev“ (für MAD-MP3-Unterstützung),
- „zlib1g-dev“ (für Unterstützung von komprimierten Spielständen)
- * Rufen Sie „make deb“ auf.
- * Rufen Sie zum Schluss „dpkg -i ../scummvm-cvs*deb“ auf und
- Sie sind fertig.
-
Mac OS X:
* Stellen Sie sicher, dass Sie die „Developer“-Tools installiert haben.
* Das „Developer“-Paket von SDL für OS X, das auf der SDL-Website
@@ -2304,4 +2344,4 @@ http://www.scummvm.org/
(Deutscher Text basiert auf README mit SHA1-ID:
-264240eb5da43b8b1fbe309bbafb00aff7e1b51b)
+d1de75a6ca828ab2fcdbce6352a12337f93fc21c)
diff --git a/doc/de/Neues b/doc/de/Neues
index efd79b87e0..23fe6751c1 100644
--- a/doc/de/Neues
+++ b/doc/de/Neues
@@ -1,8 +1,61 @@
-Umfangreichere Änderungsaufzeichnungen des neusten experimentellen Codes finden
+Umfangreichere Änderungsaufzeichnungen des neusten experimentellen Codes finden
Sie auf Englisch unter:
https://github.com/scummvm/scummvm/commits/
-1.4.0 (??.??.????)
+1.5.0 (??.??.????)
+ Neue Spiele:
+ - Unterstützung für Soltys hinzugefügt.
+
+ SDL-Portierungen:
+ - Unterstützung für OpenGL hinzugefügt. (GSoC-Aufgabe)
+
+ Cine:
+ - Roland-MT-32-Ausgabetreiber integriert.
+
+ SCUMM:
+ - Unterstützung für die Macintosh-Version von SPY Fox in Hold the Mustard
+ hinzugefügt.
+ - Dialog zur Auswahl des Schwierigkeitsgrads für Loom FM-TOWNS hinzugefügt.
+
+ Sword1:
+ - Falsche Soundeffekte in der DOS-/Windows-Demo korrigiert.
+
+ Windows-Portierung:
+ - Standardmäßiger Speicherort für Spielstände bei
+ Windows NT4/2000/XP/Vista/7 geändert.
+
+1.4.1 (27.01.2012)
+ AGOS:
+ - Das Laden von Videos direkt aus InstallShield-Archiven in der
+ Windows-Version von Floyd - Es gibt noch Helden korrigiert.
+
+ BASS:
+ - Unterstützung für verbesserte Musik von James Woodcock hinzugefügt
+ (http://www.jameswoodcock.co.uk/?p=7695).
+
+ KYRA:
+ - Fehler in der originalen Benutzeroberfläche von Lands of Lore beseitigt,
+ der dazu führte, dass ScummVM abstürzte, wenn der Anwender keine
+ durchgehend fortlaufenden Speicherplätze verwendete.
+ - Unterstützung für originale DOS-Speicherstände von Lands of Lore
+ hinzugefügt (trifft auch auf Speicherstände zu, die mit der GOG-Version
+ gemacht wurden).
+
+ SCI:
+ - Abfolgebedingung bei SCI1.1-Palettenänderungen korrigiert. Dies behebt
+ einen Fehler in QFG1VGA, wenn man in Erana's Peace schläft.
+ - Die Option, um zwischen digitalisierten und synthetisierten
+ Soundeffekten auszuwählen, wurde bis auf Weiteres deaktiviert, bis eine
+ anwenderfreundlichere Benutzeroberflächen-Option möglich ist.
+ Digitale Soundeffekte werden vorerst immer bevorzugt.
+ - Fehler in einem Fall beseitigt, bei welchem bei Beginn eines neuen Liedes
+ nicht alle Kanäle zurückgesetzt wurden und somit einige Noten falsch
+ klangen.
+
+ Sword2:
+ - Leichte Grafikverbesserung für PSX-Version.
+
+1.4.0 (11.11.2011)
Neue Spiele:
- Unterstützung für Lands of Lore: The Throne of Chaos hinzugefügt.
- Unterstützung für Blue's Birthday Adventure hinzugefügt.
@@ -13,6 +66,11 @@ Sie auf Englisch unter:
Neue Portierungen:
- Portierung für PlayStation 3 hinzugefügt.
+ Allgemein:
+ - ARM-Assembler-Routinen für Stereo-Umkehr bei Audio repariert.
+ - Unterstützung für unkomplizierte Zusammenstellung mit MacPorts
+ hinzugefügt.
+
AGI:
- Sound-Unterstützung für die DOS-Version von Winnie the Pooh in the
Hundred Acre Wood integriert.
@@ -47,9 +105,10 @@ Sie auf Englisch unter:
- Palettenhandhabung in der Amiga-Version von Indiana Jones and the
Fate of Atlantis verbessert.
-
- SDL-Portierungen:
- - Unterstützung für OpenGL hinzugefügt. (GSoC-Aufgabe)
+ Sword1:
+ - Aufhängen in Windows-Demo beseitigt.
+ - Absturz beseitigt, wenn Untertitelpaket für Zwischensequenzen in
+ Macintosh-Version verwendet wird.
Tinsel:
- Löschen von Spielständen aus der Liste der Speicherstände korrigiert (im
@@ -57,6 +116,10 @@ Sie auf Englisch unter:
- Die US-Version von Discworld II zeigt nun den korrekten Titelbildschirm und
die richtige Sprachenflagge.
+ Android-Portierung:
+ - Plugins bei Android 3.x repariert.
+ - Standardmäßigen Speicherort für Spielstände auf SD-Karte verschoben.
+
1.3.1 (12.07.2011)
Allgemein:
- Audiogeräte-Erkennung und Zurückgreifen auf Alternativen verbessert.
@@ -1607,4 +1670,4 @@ Sie auf Englisch unter:
(Deutscher Text basiert auf NEWS mit SHA1-ID:
-744f8507d714da5710c020bf56aa49dd0662acf6)
+ab2b020ff10b2e5d25cc93757029838c7eac6b41)
diff --git a/doc/es/Inicio rápido b/doc/es/InicioRapido
index 3848b049f1..3848b049f1 100644
--- a/doc/es/Inicio rápido
+++ b/doc/es/InicioRapido
diff --git a/doc/se/LasMig b/doc/se/LasMig
new file mode 100644
index 0000000000..656210883f
--- /dev/null
+++ b/doc/se/LasMig
@@ -0,0 +1,1652 @@
+ScummVM LÄS MIG
+Senast uppdaterad: $Date$
+------------------------------------------------------------------------
+
+För ytterligare information, kompatibilitetslistor, donationsdetaljer, den senaste programversionen, utvecklingsrapporter med mera, var god besök ScummVM:s hemsida på http://www.scummvm.org/
+
+Innehåll:
+---------
+1.0) Introduktion
+ * 1.1 Om ScummVM
+ * 1.2 Snabbstart
+2.0) Kontaktinformation
+ * 2.1 Att rapportera buggar
+ * 2.3 Snabbstart
+3.0) Stödda spel
+ * 3.1 Kopieringsskydd
+ * 3.2 Notiser om Commodore64-spel
+ * 3.3 Notiser om Maniac Mansion för NES
+ * 3.4 Notiser om Macintosh-spel
+ * 3.5 Notiser om spel med flera CD-skivor:
+ * 3.6 Notiser om The Curse of Monkey Island
+ * 3.7 Notiser om Broken Sword-spelen
+ * 3.8 Notiser om Beneath a Steel Sky
+ * 3.9 Notiser om Flight of the Amazon Queen
+ * 3.10 Notiser om Gobliiins
+ * 3.11 Notiser om Inherit the Earth: Quest for the Orb
+ * 3.12 Notiser om Simon the Sorcerer
+ * 3.13 Notiser om The Feeble Files
+ * 3.14 Notiser om The Legend of Kyrandia
+ * 3.15 Sierra AGI games Predictive Input Dialog notes
+ * 3.16 Notiser om Mickey’s Space Adventure
+ * 3.17 Notiser om Winnie the Pooh
+ * 3.18 Notiser om Troll's Tale
+ * 3.19 Notiser om Dragon History
+ * 3.20 Kända problem
+4.0) Stödda plattformar
+5.0) Att köra ScummVM
+ * 5.1 Att använda kommandoraden
+ * 5.2 Språkinställningar
+ * 5.3 Grafikfilter
+ * 5.4 Den globala menyn
+ * 5.5 Kortkommandon
+6.0) Spardata
+ * 6.1 Autosparning
+ * 6.2 Att konvertera speldata
+ * 6.3 Visa/ladda spardata från kommandoraden
+7.0) Musik och ljud
+ * 7.1 AdLib-emulation
+ * 7.2 FluidSynth MIDI-emulation
+ * 7.3 MT-32-emulation
+ * 7.4 MIDI-emulation
+ * 7.5 Native MIDI-stöd
+ * 7.6 Support för UNIX, ALSA och dmedia sequencers
+ * 7.7 Att använda TiMidity++ MIDI-servern
+ * 7.8 Att använda komprimerade ljudfiler (MP3, Ogg Vorbis, Flac)
+ * 7.9 Uppspelningsfrekvens
+8.0) Konfigurationsfilen
+9.0) Kompilering
+
+
+1.0) Introduktion:
+---- -------------
+
+1.1) Om ScummVM:
+---- -----------
+ScummVM är ett program som gör det möjligt att spela vissa klassiska â€peka-och-klickaâ€-äventyrsspel, förutsatt att du redan har de nödvändiga datafilerna. Det finurliga i det hela är att ScummVM ersätter de ursprungliga programfilerna som följde med spelet, vilket lÃ¥ter dig spela dem pÃ¥ operativsystem de aldrig var designade för!
+
+FrÃ¥n början var programmet designat för att köra LucasArts SCUMM-spel, till exempel Maniac Mansion, Monkey Island, Day of the Tentacle och Sam and Max. SCUMM stÃ¥r för â€Script Creation Utility for Maniac Mansionâ€, och just Maniac Mansion var det första spelet där LucasArts använde det här spelsystemet. Mycket senare gav det namn till ScummVM (â€VM†stÃ¥r för â€Virtual Machineâ€).
+
+Med tiden har stöd lagts till för många spel som inte använder SCUMM-systemet och ScummVM stöder nu även många av Sierras AGI- och SCI-spel (till exempel King’s Quest 1-6, Space Quest 1-5, ...), Discworld 1 och 2, Simon the Sorcerer 1 och 2, Beneath A Steel Sky, Lure of the Temptress, Broken Sword I och II, Flight of the Amazon Queen, Gobliiins 1-3, Legend of Kyrandia-serien, många av Humongous Entertainments barnspel (inklusive Freddi Fish och Putt Putt-spelen) med flera. Du kan se en fullständig lista med delaljer om vilka äventyr som stöds och hur väl de fungerar på kompatibilitetssidan. ScummVM förbättras konstant, så håll ett öga på listan.
+
+Bland systemen du kan använda för att spela dessa spel räknas vanliga persondatorer (Windows, Linux, Mac OS X, ...) spelkonsoler (Dreamcast, Nintendo DS & Wii, PS2, PSP, ...), smartphones (Android, iPhone, PocketPC, Symbian ...) med flera.
+
+Just nu är ScummVM fortfarande under utveckling. Var medveten om att trots att vi försöker se till att många spel kan avklaras utan att stöta på allvarliga buggar finns det ändå risk för krasher, och vi erbjuder inga garantier. Dock har många spel varit stödda av programmet väldigt länge och borde fungera utmärkt i vilken som helst av de senaste stabila versionerna. Du kan få en uppfattning om hur väl varje spel fungerar i ScummVM genom att titta på kompatibilitetssidan. Faktum är att ScummVM används kommersiellt för nyutgåvor av vissa spel på moderna plattformar. Alltså är många företag nöjda med mjukvarans kvalitet och hur väl programmet stöder spelen.
+
+Om du gillar ScummVM får du gärna donera till teamet med hjälp av PayPal-knappen på ScummVM:s hemsida. Donationer hjälper oss att köpa nödvändig utrustning för att göra utvecklingen av ScummVM lättare och snabbare. Om du inte kan donera kan du hjälpa till genom att bidra med uppdateringar!
+
+
+1.2) Snabbstart:
+---- -----------
+VIKTIGT: Den här korta guiden förutsätter att du använder ScummVM på svenska. ScummVM använder automatiskt samma språk som ditt operativsystem. Om du föredrar att använda ScummVM på engelska kommer du troligtvis föredra att använda guiden i den engelska README-filen.
+
+För de otåliga följer här instruktioner för att köra igång ScummVM i fem enkla steg.
+
+1. Ladda hem ScummVM från http://www.scummvm.org/downloads.php och installera programmet.
+
+2. Skapa en filkatalog på din hårddisk och kopiera spelets datafiler från dess ursprungliga plats till den nya katalogen. Upprepa det här steget för varje spel du vill spela (det är bättre att använda separata kataloger för vaje spel).
+
+3. Starta ScummVM.
+
+Om programmet nu visas på engelska istället för svenska, gör såhär för att byta språk:
+- Klicka pÃ¥ â€Optionsâ€.
+- Klicka pÃ¥ högerpilen i tab-raden och navigera till “Miscâ€-tabben.
+- Välj “Svenska†i “GUI Languageâ€-menyn och klicka pÃ¥ “OKâ€.
+- Konfirmera meddelandet som visas, klicka på “Quit†för att avsluta ScummVM och starta sedan om programmet.
+
+Klicka pÃ¥ “Lägg till spelâ€, välj katalogen som innehÃ¥ller datafilerna (var noga att välja själva filkatalogen - inte datafilerna inuti filkatalogen!) och klicka pÃ¥ â€Väljâ€.
+
+4. Nu visas en dialogruta där du kan ändra diverse inställningar om du vill (det borde vara nog att lämna inställningarna som de är från början). Konfirmera dialogrutan.
+
+5. Välj spelet du vill spela frÃ¥n listan och klicka pÃ¥ â€Startaâ€.
+
+ScummVM kommer ihåg alla spelen du lägger till, så om du avslutar ScummVM kommer spellistan vid nästa omstart innehålla alla spelen du hittills lagt till. Du kan därför hoppa direkt till steg 5, såtillvida inte du vill läga till fler spel.
+
+Tips: Om du vill lägga till flera spel på en gång, pröva att trycka och hålla ned skift-tangenten när du klickar på “Lägg till spel†– knappens text ändras nu till “Masstillägg†och om du klickar på den kommer du åter igen ombedjas att välja en filkatalog, men den här gången söker ScummVM automatiskt igenom alla underkataloger efter stödda spel.
+
+
+2.0) Kontakt:
+---- --------
+Det enklaste sättet att kontakta ScummVM-teamet är att skicka in bugg-rapporter (se 2.1) eller genom att använda vårt forum på http://forums.scummv.org. Du kan även skriva upp dig för och skicka e-post via vår sändlista (scummvm-devel) eller chatta med oss på IRC (#scummvm på irc.freenode.net) Vi ber dig att inte skicka önskemål på spel som inte stöds av ScummVM – läs avdelningen för vanliga frågor (FAQ) på våran hemsida först. Märk även att det officiella språket för vårt forum, vår sändlista och chatten är engelska och att inga andra språk borde användas där.
+
+
+2.1) Att rapportera buggar:
+---- ----------------------
+För att rapportera en bugg mÃ¥ste du skapa ett konto hos SourceForge och följa “Bug Trackerâ€-länken frÃ¥n vÃ¥ran hemsida. Var god se till att buggen kan reproduceras med säkerhet och att den fortfarande är aktiv i den senaste git/Daily build-versionen. Se även till att kontrollera att felet inte redan rapporterats genom att läsa listan av kända fel för spelet pÃ¥ vÃ¥ran kompatibilitetssida:
+
+ http://www.scummvm.org/compatibility_stable.php
+
+Var god rapportera inte buggar för spel som inte är möjliga att avklara enligt “Supported Gamesâ€-avdelningen, eller i kompatibilitetslistan. Vi vet redan att dessa spel är buggiga.
+
+Se till att bifoga följande information:
+ - ScummVM version (Var god testa med den senaste git/Daily Build-versionen)
+ - Detaljer om buggen, inklusive instruktioner för reproduktion
+ - Spelets språk (engelska, tyska, ...)
+ - Version av spelet (talversionen, diskettversionen, ...)
+ - Plattform och kompilator (Win32, Linux, FreeBSD, ...)
+ - Bifoga spardata om möjligt
+ - Om den här buggen dök upp alldeles nyligen, var god notera den senaste versionen av ScummVM där buggen inte fanns och den första versionen där buggen dök upp. På det här viset kan vi fixa problemet snabbare genom att se vilka förändringar som skedde mellan versionerna.
+
+Slutligen, var god rapportera varje bugg i enskilda rapporter; skicka inte flera buggar i en och samma rapport (annars blir det svårt att hålla reda på varje buggs individuella status).
+
+
+3.0) Stödda spel:
+---- ------------
+För tillfället har de följande spelen anmälts som funktionella, och borde kunna spelas från början till slut:
+
+SCUMM-spel från LucasArts:
+ Maniac Mansion [maniac]
+ Zak McKracken and the Alien Mindbenders [zak]
+ Indiana Jones and the Last Crusade [indy3]
+ Loom [loom]
+ The Secret of Monkey Island [monkey]
+ Monkey Island 2: LeChuck's Revenge [monkey2]
+ Indiana Jones and the Fate of Atlantis [atlantis]
+ Day of the Tentacle [tentacle]
+ Sam & Max Hit the Road [samnmax]
+ Full Throttle [ft]
+ The Dig [dig]
+ The Curse of Monkey Island [comi]
+
+AGI-spel från Sierra:
+ The Black Cauldron [bc]
+ Gold Rush! [goldrush]
+ King's Quest I [kq1]
+ King's Quest II [kq2]
+ King's Quest III [kq3]
+ King's Quest IV [kq4]
+ Leisure Suit Larry in the Land of the
+ Lounge Lizards [lsl1]
+ Mixed-Up Mother Goose [mixedup]
+ Manhunter 1: New York [mh1]
+ Manhunter 2: San Francisco [mh2]
+ Police Quest I: In Pursuit of the Death
+ Angel [pq1]
+ Space Quest I: The Sarien Encounter [sq1]
+ Space Quest II: Vohaul's Revenge [sq2]
+ Fanmade Games [agi-fanmade]
+
+AGOS-spel från Adventuresoft/Horrorsoft:
+ Elvira - Mistress of the Dark [elvira1]
+ Elvira II - The Jaws of Cerberus [elvira2]
+ Personal Nightmare [pn]
+ Waxworks [waxworks]
+ Simon the Sorcerer 1 [simon1]
+ Simon the Sorcerer 2 [simon2]
+ Simon the Sorcerer's Puzzle Pack
+ - Demon In My Pocket [dimp]
+ Simon the Sorcerer's Puzzle Pack
+ - Jumble [jumble]
+ Simon the Sorcerer's Puzzle Pack
+ - NoPatience [puzzle]
+ Simon the Sorcerer's Puzzle Pack
+ - Swampy Adventures [swampy]
+ The Feeble Files [feeble]
+
+GOB-spel från Coktel Vision:
+ Bargon Attack [bargon]
+ Gobliiins [gob1]
+ Gobliins 2 [gob2]
+ Goblins 3 [gob3]
+ Lost in Time [lostintime]
+ The Bizarre Adventures of Woodruff
+ and the Schnibble [woodruff]
+ Ween: The Prophecy [ween]
+
+MADE-spel från Activision:
+ Leather Goddesses of Phobos 2 [lgop2]
+ Return to Zork [rtz]
+ Rodney's Funscreen [rodney]
+ The Manhole [manhole]
+
+Övriga spel:
+ Beneath a Steel Sky [sky]
+ Broken Sword: The Shadow of the Templars [sword1]
+ Broken Sword II: The Smoking Mirror [sword2]
+ Cruise for a Corpse [cruise]
+ Discworld [dw]
+ Discworld 2: Missing Presumed ...!? [dw2]
+ Dragon History [draci]
+ Drascula: The Vampire Strikes Back [drascula]
+ Flight of the Amazon Queen [queen]
+ Future Wars [fw]
+ Inherit the Earth: Quest for the Orb [ite]
+ Nippon Safes Inc. [nippon]
+ The Legend of Kyrandia [kyra1]
+ The Legend of Kyrandia: The Hand of Fate [kyra2]
+ The Legend of Kyrandia: Malcolm's Revenge [kyra3]
+ Touche: The Adventures of the Fifth
+ Musketeer [touche]
+
+SCUMM-spel från Humongous Entertainment:
+ Backyard Baseball [baseball]
+ Backyard Baseball 2001 [baseball2001]
+ Backyard Football [football]
+ Big Thinkers First Grade [thinker1]
+ Big Thinkers Kindergarten [thinkerk]
+ Blue's 123 Time Activities [Blues123Time]
+ Blue's ABC Time Activities [BluesABCTime]
+ Blue's Art Time Activities [arttime]
+ Blue's Birthday Adventure [BluesBirthday]
+ Blue's Reading Time Activities [readtime]
+ Fatty Bear's Birthday Surprise [fbear]
+ Fatty Bear's Fun Pack [fbpack]
+ Freddi Fish 1: The Case of the Missing
+ Kelp Seeds [freddi]
+ Freddi Fish 2: The Case of the Haunted
+ Schoolhouse [freddi2]
+ Freddi Fish 3: The Case of the Stolen
+ Conch Shell [freddi3]
+ Freddi Fish 4: The Case of the Hogfish
+ Rustlers of Briny Gulch [freddi4]
+ Freddi Fish 5: The Case of the Creature
+ of Coral Cove [freddicove]
+ Freddi Fish and Luther's Maze Madness [maze]
+ Freddi Fish and Luther's Water Worries [water]
+ Let's Explore the Airport with Buzzy [airport]
+ Let's Explore the Farm with Buzzy [farm]
+ Let's Explore the Jungle with Buzzy [jungle]
+ Pajama Sam 1: No Need to Hide When It's
+ Dark Outside [pajama]
+ Pajama Sam 2: Thunder and Lightning
+ Aren't so Frightening [pajama2]
+ Pajama Sam 3: You Are What You Eat
+ From Your Head to Your Feet [pajama3]
+ Pajama Sam's Lost & Found [lost]
+ Pajama Sam's Sock Works [socks]
+ Putt-Putt Joins the Parade [puttputt]
+ Putt-Putt Goes to the Moon [puttmoon]
+ Putt-Putt Saves the Zoo [puttzoo]
+ Putt-Putt Travels Through Time [putttime]
+ Putt-Putt Enters the Race [puttrace]
+ Putt-Putt Joins the Circus [puttcircus]
+ Putt-Putt and Pep's Balloon-O-Rama [balloon]
+ Putt-Putt and Pep's Dog on a Stick [dog]
+ Putt-Putt & Fatty Bear's Activity Pack [activity]
+ Putt-Putt's Fun Pack [funpack]
+ SPY Fox 1: Dry Cereal [spyfox]
+ SPY Fox 2: Some Assembly Required [spyfox2]
+ SPY Fox 3: Operation Ozone [spyozon]
+ SPY Fox in Cheese Chase [chase]
+ SPY Fox in Hold the Mustard [mustard]
+
+Living Books-spel:
+ Aesop's Fables: The Tortoise and the Hare [tortoise]
+ Arthur's Birthday [arthurbday]
+ Arthur's Teacher Trouble [arthur]
+ Dr. Seuss's ABC [seussabc]
+ Green Eggs and Ham [greeneggs]
+ Harry and the Haunted House [harryhh]
+ Just Grandma and Me [grandma]
+ Little Monster at School [lilmonster]
+ Ruff's Bone [ruff]
+ Sheila Rae, the Brave [sheila]
+ Stellaluna [stellaluna]
+ The Berenstain Bears Get in a Fight [bearfight]
+ The Berenstain Bears in the Dark [beardark]
+ The New Kid on the Block [newkid]
+
+De följande spelen borde starta, men är ännu ej helt spelbara. Spela dem på egen risk och var god skicka inga buggrapporter angående dem. För senaste nytt angående spelkompatibilitet kan du besöka vår hemsida och läsa kompatibilitetslistan.
+
+ Backyard Baseball 2003 [baseball2003]
+ Backyard Football 2002 [football2002]
+ Backyard Soccer [soccer]
+ Backyard Soccer MLS [soccermls]
+ Backyard Soccer 2004 [soccer2004]
+ Blue's Treasure Hunt [BluesTreasureHunt]
+ Pajama Sam: Games to Play on Any Day [pjgames]
+
+De följande spelen är baserade på SCUMM-motorn men stöds INTE (ännu) av ScummVM:
+
+ Övriga Humongous Entertainment-spel
+
+Tänk pÃ¥ att spelmotorerna kan inehÃ¥lla buggar och funktioner som inte implementerats vilket kan göra det omöjligt att klara spelet. Spara ofta och skicka en buggrapport om du stöter pÃ¥ en sÃ¥dan bugg i ett â€stött†spel (se ovan för instruktioner om hur man skickar buggrapporter).
+
+
+3.1) Kopieringsskydd:
+---- ----------------
+ScummVM-teamet föresprÃ¥kar inte piratkopiering. Dock finns det fall där spelföretag (t.ex. LucasArts) pÃ¥ egen hand har bifogat â€crackade†programfiler med sina spel. I dessa fall inehÃ¥ller datafilerna fortfarande koden för kopieringsskydd, men programfilen överskrider den (pÃ¥ samma sätt som en illegalt â€crackad†version tar sig förbi skyddskoden, med skillnaden att speltillverkarna här själva stod för överskridningen). DÃ¥ vi omöjligen kan se skillnad pÃ¥ legitima och piratkopierade datafiler mÃ¥ste vi lÃ¥ta ScummVM överskrida kopieringsskyddet för alla spel som nÃ¥gon gÃ¥ng sÃ¥lts i original med â€crackade†programfiler.
+
+I vissa fall visar ScummVM fortfarande skärmen för kopieringsskydd. Försök att ge vilket svar som helst. Troligtvis fungerar det.
+
+ScummVM skippar kopieringsskyddet för följande spel:
+
+ * Maniac Mansion
+ * Zak McKracken and the Alien Mindbenders
+ * Loom (EGA)
+ * The Secret of Monkey Island (VGA)
+ * Monkey Island 2: LeChuck's Revenge
+ * Beneath a Steel Sky
+ -- överskridit med tillstånd från Revolution Software.
+ * Inherit the Earth: Quest for the Orb (Diskettversionen)
+ -- överskridit med tillstånd från Wyrmkeep Entertainment,
+ då det överskridits på alla CD-utgåvor av spelet.
+ * Simon the Sorcerer 1 (Diskettversionen)
+ * Simon the Sorcerer 2 (Diskettversionen)
+ -- överskridit med tillstånd från Adventure Soft,
+ då det överskridits på alla CD-utgåvor av spelet.
+ * Waxworks
+
+
+3.2) Notiser om Commodore64-spel:
+---- ----------------------------
+BÃ¥de Maniac Mansion och Zak McKracken startar men Maniac Mansion är ännu inte spelbart. Namnge D64 disketterna â€maniac1.d64†och â€maniac2.d64†(för Maniac Mansion) och â€zak1.d64†och â€zak2.d64†(för Zak McKracken) sÃ¥ kommer ScummVM automatiskt hitta spelen om du hänvisar till rätt katalog.
+
+Annars kan du använda â€extract_mm_c64†frÃ¥n tools-paketet för att extrahera datafilerna. Tyvärr kan inte spelet identifieras korrekt av ScummVM med den här metoden sÃ¥ du mÃ¥ste se till att plattformen ställts in till Commodore64. Vi rekommenderar att använda den lättare metoden frÃ¥n paragrafen ovan.
+
+
+3.3) Notiser om Maniac Mansion för NES:
+---- ----------------------------------
+Versionerna av spelet som stöds av ScummVM är engelska (E), franska (F), tyska (G) italienska (I), svenska (SW) och amerikanska (U). ScummVM kräver endast PRG-delen av ROM-filen för att köra spelet.
+
+För att få igång spelet måste du radera de första 16 byten från ROM-filen du vill använda. Du kan använda vilken hex-redigerare du vill så länge du har möjlighet att kopiera/klistra in. När du öppnat ROM-filen med hex-redigeraren, markera allt från den andra raden (17:e byten) till och med slutet av filen. Kopiera och klistra in i en ny hex-fil. Namnge den nya filen “Maniac Mansion (XX).prg†där XX står för vilken version av spelet du jobbar med (E, F, G, I, SW eller U). Den slutliga filstorleken borde vara exakt 262144 bytes.
+Om du lägger till spelet manuellt, se till att plattformen är inställd för NES.
+
+De vanligaste misstagen som förhindrar att spelet fungerar:
+
+ * DÃ¥lig fil
+ * ROM extraherades med 0.7.0-verktygen
+ * Försökte mata in hela ROM-filen istället för PRG-delen.
+
+Det är även möjligt att extrahera LFL-filerna frÃ¥n PRG-delen. För att göra detta kan du använda verktyget â€extract_mm_nes†frÃ¥n tools-paketet.
+
+
+3.4) Notiser om Macintosh-spel:
+---- --------------------------
+Alla SCUMM-baserade LucasArts spel (utom COMI) finns även i Macintosh-versioner. ScummVM kan använda de flesta (eller alla?) av dem, men i vissa fall krävs det lite extra fiffel. Till att börja med, om du inte använder en Macintosh kan det vara knepigt att använda spelets CD/diskett-data. Anledningen är att mac använder ett speciellt skivformat kallat HFS vilket övriga system i regel inte stöder. Dock finns det gratis verktyg som gör det möjligt att läsa dessa HFS-enheter, t.ex. â€HFVExplorer†för Windows och â€hfutils†för Linux och andra Unix-liknande operativsystem.
+
+De flesta av de nyare spelen för Macintosh gavs ut med endast en datafil (märk att i vissa fall gjordes den här filen osynlig, så det kan krävas speciella verktyg för att kopiera den). ScummVM kan använda sådana datafiler direkt; hänvisa ScummVM till katalogen som innehåller datafilen så borde det fungera (precis som med alla andra stödda spel).
+
+Vi har även ett verktyg som heter â€extract_scumm_mac†i tools-paketet för att extrahera datan frÃ¥n dessa filer, men det är varken nödvändigt eller rekommenderat.
+
+För ytterligare information om hur man kopierar spelfiler för Macintosh till hårddisken, besök:
+
+ http://wiki.scummvm.org/index.php/HOWTO-Mac_Games
+
+
+3.5) Notiser om spel med flera CD-skivor:
+---- ------------------------------------
+I regel hanterar ScummVM inte spel spridda över flera CD-skivor vidare bra. Anledningen är att ScummVM utgår ifrån att spelets fullständiga resurser är samlade i en enda katalog. Även då ScummVM ber användaren byta skiva vid tillfälle kan originalversionen av spelet fungerat genom att installera ett antal filer på hårddisken. Om dessa filer inte kan hittas på samtliga CD-skivor får ScummVM problem.
+
+Som tur är har ScummVM inga problem med att köra spelen helt från hårddisken så länge du skapar en filkatalog som innehåller rätt kombination av filer. När en fil existerar på fler än en CD kan du i regel välja vilken av dem du vill.
+
+
+3.6) Notiser om The Curse of Monkey Island:
+---- --------------------------------------
+För det här spelet behöver du filerna comi.la0, comi.la1 och comi.la2. En fil med namnet Comi.la0 existerar på båda CD-skivorna, men då filerna är identiska spelar det ingen roll vilken av dem du använder.
+
+Du behöver dessutom skapa en â€resource†katalog som innehÃ¥ller alla filer frÃ¥n BÃ…DA â€resourceâ€-katalogera pÃ¥ de tvÃ¥ CD-skivorna. Vissa av filerna existerar pÃ¥ bÃ¥da CD-skivorna, men även dessa är identiska.
+
+
+3.7) Notiser om Broken Sword-spelen:
+---- -------------------------------
+Instruktionerna för Broken Sword-spelen är för Sold-Out Software-versionerna där varje spel kom på två CD-skivor eftersom dessa versioner var mest tillgängliga när ScummVM lade till stöd för dem. Förhoppningsvis fungerar dessa konfigurationer även med andra versioner.
+
+
+3.7.1) Filmscener i Broken Sword-spelen:
+------ ---------------------------------
+Filmscenerna i Broken Sword-spelen har varit med om en hel del (se nästa avdelning om du är intresserad) men i regel behöver du bara kopiera .SMK-filerna frÃ¥n â€SMACKS†eller â€SMACKSHIâ€-katalogerna pÃ¥ CD-skivorna till samma katalog där de andra datafilerna ligger. (Broken Sword har även en â€SMACKSLO†katalog med samma filmscener, men dessa har lägre kvalitet.) Du kan även lägga dem i en underkatalog med namnet â€videoâ€, om du vill.
+
+Vissa nyutgåvor av spelen, tillika PlayStation-versionen, har inga Smacker videos. Revolution Software har varit goda nog att skapa nykodade filmscener som kan laddas hem från våran hemsida:
+
+ http://www.scummvm.org/downloads.php
+
+Dessa filmscener är tillgängliga i DXA-format med FLAC-ljud. Kvaliteten är densamma som i originalversionerna av spelet tack vare ickedestruktiv komprimering. För att se dessa filmscener krävs en version av ScummVM som kompilerats med stöd för både FLAC och zlib.
+
+För de system som är för långsamma för att hantera FLAC-ljud finns ljudet för dessa filmscener att ladda hem separat som OGG Vorbis-ljud. För att se dessa filmscener med OGG Vorbis-ljud krävs en version av ScummVM som kompilerats med stöd för både libVorbis och zlib.
+
+Vi erbjuder även ett tillägg för undertexter i Broken Sword. Packa upp tillägget och följ instruktionerna i readme.txt-filen. (Broken Sword II har redan undertexter; inga modifikationer krävs för dem).
+
+
+3.7.2) Broken Sword-spelens filmscener – en återblick:
+------ -----------------------------------------------
+Originalutgåvorna av Broken Sword-spelen använde sig av RAD Game Tools Smacker(tm)-format. Då RAD inte ville låta oss använda källkoden för deras äldre versioner av det här formatet, och bad oss att inte dekonstruera formatet, var vi tvugna att hitta en alternativ lösning.
+
+I Broken Sword II var det möjligt att spela upp röstspåret utan att spela videospåret. Detta var en nödlösning fram till ScummVM 1.0.0 men var aldrig den enda lösningen för en stabil version.
+
+I ScummVM 0.6.0 använde vi MPEG vilket möjliggjorde en rimlig kompromiss mellan filstorlek och kvalitet. I ScummVM 0.10.0 ersattes formatet av DXA (frÃ¥n början tillagt för AdventureSofts â€The Feeble Filesâ€). Detta gjorde det möjligt att Ã¥terge filmscenerna i exakt samma kvalitet som originalen, med nackdelen att filstorleken var större.
+
+Slutligen i början av 2006 dekonstruerades Smacker-formatet av FFMpeg-teamet. Tack vare deras hårda arbete stöder nu ScummVM från och med version 1.0.0 originalfilmscenerna. Stöd för MPEG har indragits. Från en teknisk synvinkel var detta en god sak då kodning av MPEG-filmer var en komplex process. Dessutom såg de inte lika bra ut som Smacker- och DXA-versionerna.
+
+
+3.7.3) Broken Sword:
+------ -------------
+För det här spelet behöver du alla filer från clusters-katalogerna på båda CD-skivorna. För Windows- och Macintosh-versionerna behöver du även speech.clu filerna från speech-katalogerna, men då de inte är identiska måste du döpa om dem till speec1.clu (för CD 1) och speech2.clu (för CD 2). PlayStation-versionen kräver speech.tab, speech.dat, speech.lis och speech.inf.
+
+Windows- och Macintosh-versionerna kräver även en underkatalog för musik med alla filerna från musik-katalogerna på båda CD-skivorna. Vissa av de här filerna existerar på båda skivorna, men i det här fallet är de antingen identiska eller, i ett fall, identiska till den grad att det inte gör någon skillnad. PlayStation-versionen kräver tunes.dat och tunes.tab.
+
+
+3.7.4) Broken Sword II:
+------ ----------------
+För det här spelet behöver du alla filer från clusters-katalogerna på båda CD-skivorna. (Vissa av dem kanske inte är helt nödvändiga, men de vi är osäkra på är ganska små.) Du måste döpa om speech.clu och music.clu-filerna till speech1.clu, speech2.clu, music1.clu och music2.clu så ScummVM kan se vilka av dem som kommer från CD 1 och vilka som kommer från CD 2. Övriga filer som existerar i båda clusters-katalogerna är identiska. Använd vilka exemplar du vill.
+
+Du behöver även cd.inf och (om du vill) startup.inf filerna från sword2-katalogen på CD 1.
+
+
+3.8) Notiser om Beneath a Steel Sky:
+---- -------------------------------
+FrÃ¥n och med ScummVM 0.8.0 behöver du â€SKY.CPTâ€-filen för att spela Beneath a Steel Sky.
+
+Den här filen är tillgänglig frÃ¥n â€Downloadsâ€-avdelningen pÃ¥ ScummVM:s hemsida. Du kan lägga den antingen i katalogen som innehÃ¥ller de andra datafilerna (SKY.DNR, SKY.DSK), i din â€extraâ€-sökväg, eller i katalogen där programfilen för ScummVM befinner sig.
+
+
+3.9) Notiser om Flight of the Amazon Queen:
+---- --------------------------------------
+För att kunna använda en icke-freeware version av Flight of the Amazon Queen (frÃ¥n original-CD:n) mÃ¥ste du placera “queen.tbl†filen (tillgänglig frÃ¥n “Downloadsâ€-avdelningen pÃ¥ vÃ¥ran hemsida) antingen i katalogen som innehÃ¥ller “queen.1†datafilen, i din “extraâ€-sökväg eller i katalogen där programfilen för ScummVM befinner sig.
+
+Alternativt kan du använda verktyget “compress_queen†frÃ¥n tools-paketet för att “bygga om†din FOTAQ-datafil sÃ¥ den inkluderar tabellen för din version, och pÃ¥ sÃ¥ vis göra programmet oberoende av â€queen.tblâ€-filen. Det här verktyget lÃ¥ter dig även komprimera tal- och ljudeffekterna till MP3, OGG eller FLAC.
+
+
+3.10) Notiser om Gobliiins:
+----- ---------------------
+CD-versionerna av Gobliiins-spelen innehåller ett stort ljudspår som du måste extrahera (se avdelningen för användning av komprimerade ljudfiler; 7.8) och kopiera till spelkatalogen om du vill ha musik när du spelar utan att ha CD:n inmatad. Taleffekterna ligger på samma ljudspår och sålunda ändras även deras volym när du justerar musikvolymen.
+
+
+3.11) Notiser om Inherit the Earth: Quest for the Orb:
+----- ------------------------------------------------
+För att spela nyutgåvan från Wyrmkeep för Mac OS X måste du kopiera datafilerna från CD:n till din hårddisk. Om du är PC-användare, hänvisa sedan till:
+
+ http://wiki.scummvm.org/index.php/HOWTO-Mac_Games
+
+Länken handlar i huvudsak om SCUMM-spel men nämner även verktyget “HFVExplorer†som du behöver för att extrahera filerna. Märk att du mÃ¥ste lägga tal-datafilerna â€Inherit the Earth Voices†i samma katalog som speldatan som förvaras i:
+
+ Inherit the Earth.app/Contents/Resources
+
+För den gamla Mac OS 9-utgÃ¥van behöver du kopiera filerna i MacBinary format dÃ¥ de borde innehÃ¥lla bÃ¥de spelets resource- och data fork. Kopiera alla â€ITE*â€-filer.
+
+
+3.12) Notiser om Simon the Sorcerer 1 och 2:
+----- --------------------------------------
+Om du har dubbel-versionen av Simon the Sorcerer 1 eller 2 på CD kan du finna Windows-versionen i huvudkatalogen på CD:n och DOS-versionen i DOS-katalogen på CD:n.
+
+
+3.13) Notiser om The Feeble Files:
+----- ----------------------------
+Om du har Windows-versionen av The Feeble Files finns det ett flertal saker att tänka på.
+
+Många av de nödvändiga filerna är förvarade i en InstallShield-fil med namnet data1.cab, vilken ScummVM inte kan packa up. Du måste använda originalinstallationsprogrammet eller i5comp för att packa upp innehållet ur den här filen. Extraktionsprogrammet i5comp kan du hitta med en enkel internetsökning.
+
+För att använda talfilerna med ScummVM måste de döpas om enligt följande:
+Döp om voices.wav på CD1 till voices1.wav
+Döp om voices.wav på CD2 till voices2.wav
+Döp om voices.wav på CD3 till voices3.wav
+Döp om voices.wav på CD4 till voices4.wav
+
+
+3.14) Notiser om The Legend of Kyrandia:
+----- ----------------------------------
+För att spela The Legend of Kyrandia i ScummVM behöver du “kyra.datâ€-filen som är tillgänglig frÃ¥n â€Downloadsâ€-avdelningen pÃ¥ ScummVM:s hemsida.
+
+
+3.15) Notiser om Sierra AGI-spel med textinmatningshjälp:
+----- ---------------------------------------------------
+Textinmatningshjälpen är ett hjälpmedel i ScummVM för att spela AGI-spel (som är ökända för kommandoradsinmatning) på enheter med begränsat stöd för tangentbord. I dessa situationer (då det lätt kan bli långtråkigt att skriva med emulerade tangentbord) kan kommandon matas in snabbt och enkelt via textinmatningshjälpen.
+
+För att använda textinmatningshjälp i AGI-spel mÃ¥ste du kopiera pred.dic-filen till â€ScummVM extrasâ€-katalogen eller till katalogen för spelet du vill spela. Den här ordboken har skapats genom att söka igenom alla kända AGI-spel och innehÃ¥ller det maximala antalet vanliga ord.
+
+Om ScummVM känner igen ordboken visas textinmatningshjälpen antingen när du klickar på kommandoraden (när helst tangetbordsinmatning krävs, även i dialogrutor), eller i vissa konversioner genom att trycka på en angiven tangent.
+
+Textinmatningshjälpen fungerar i tre lägen som du kan växla mellan med (*)Pre/123/Abc-knappen. Det första inmatningsläget är förutsägelse-läget, och fungerar pÃ¥ samma sätt som snabbinmatning pÃ¥ telefoner. Alfabetet är indelat i 9 uppsättningar som pÃ¥ uppenbart vis fördelats mellan de nio nummerknapparna (0 är mellanslag). För att skriva ett ord trycker du en gÃ¥ng pÃ¥ numret för uppsättningen som innehÃ¥ller bokstaven för det ord du vill skriva, sedan tar du dig vidare till nästa bokstav. Till exempel: för att skriva ordet â€look†trycker du 5665. Allteftersom du skriver in ordets numeriska kod tillfrÃ¥gas ordboken efter ord som matchar vad du skrivit hittills. Ju fler knappar du trycker desto mer exakt blir det föreslagna ordet. Av den här anledningen kan det skrivna ordet ändras snabbt mellan tangenttryckningar. Dock finns det situationer där fler än ett ord delar samma numeriska representation. Till exempel har order â€quit†och â€suit†samma nummer – 7847. I sÃ¥dana fall lyser (#)nästa-knappen upp. Genom att trycka pÃ¥ den kan du växla mellan orden som delar samma kod och till slut acceptera det korrekta ordet genom att trycka (0)mellanslag eller OK-knappen.
+
+Det andra inmatningsläget (123) är den numeriska inmatningsmetoden: Varje knapp du trycker på matas in som sitt angivna nummer.
+
+Det tredje inmatningsläget (Abc) är Multi-tap Alpha inmatningsläget. Det här läget är menat för inmatning av fri text utan assistans frÃ¥n ordboken eller förutsägelseläget (Pre). Texten matas in en bokstav i taget. För varje bokstav trycker du först pÃ¥ nummerknappen för uppsättningen du vill Ã¥t, sedan använder du (#)nästa-knappen för att växla mellan bokstäverna. Repetera sedan proceduren med nästa bokstav. Till exempel: för att skriva ordet â€look†mÃ¥ste du trycka följande: 5##6##6##5
+
+Dialogrutan kan användas med musen, men visa provisioner i ScummVM-konversioner har gjort det mer bekvämligt genom att kartlägga funktionerna till nummertangenterna. Dialogrutornas knappar kan även navigeras med hjälp av piltangenterna och enter-tangenten.
+
+
+3.16) Notiser om Mickey’s Space Adventure:
+----- ------------------------------------
+För att spela Mickey’s Space Adventure i ScummVM behöver du originalprogramfilen (mickey.exe) tillsammans med spelets datafiler.
+
+Användning av musen stöds för spelet i ScummVM även då det inte fanns stöd för mus i originalspelet. Menyer kan användas med musen och den går även att använda till att förflytta sig i spelet. När muspekaren hålls nära kanten av skärmen färgas den röd om det är möjligt att gå i den riktningen. Spelaren kan sedan klicka på spelets skärmkant för att byta plats på samma sätt som i andra äventyrsspel, vilket är lättare än att byta plats med hjälp av menyn.
+
+
+3.17) Notiser om Winnie the Pooh:
+----- ---------------------------
+Det är möjligt att importera spardata från originalprogrammet i ScummVM.
+
+Användning av musen stöds för spelet i ScummVM även då det inte fanns stöd för mus i originalspelet. Menyer kan användas med musen och den går även att använda till att förflytta sig i spelet. När muspekaren hålls nära kanten av skärmen färgas den röd om det är möjligt att gå i den riktningen. Spelaren kan sedan klicka på spelets skärmkant för att byta plats på samma sätt som i andra äventyrsspel, vilket är lättare än att byta plats med hjälp av menyn.
+
+
+3.18) Notiser om Troll’s Tale:
+----- ------------------------
+Originalspelet gavs ut pÃ¥ en PC booter-diskett. Därför mÃ¥ste du extrahera innehÃ¥llet frÃ¥n disketten till en image-fil och döpa den till â€troll.img†för att kunna spela spelet i ScummVM.
+
+
+3.19) Notiser om Dragon History:
+----- --------------------------
+Det finns fyra olika språkversioner av spelet: tjeckiska, engelska, polska och tyska. Var och en av dem finns utgivna i separata arkiv. Den enda officiella versionen är den tjeckiska – de engelska, polska och tyska konversionerna har alltid varit under utveckling och släpptes aldrig officiellt. Emedan all text är översatt kan man i dessa versioner stöta på en del stavfel.
+
+Det finns en alternativ tjeckisk dubbning av spelet. Av utrymmesskäl kan du ladda hem denna separat och packa upp den till spelkatalogen. Du kan lyssna på den tjeckiska dubbningen med alla språkversioner medan du läser undertexterna.
+
+Alla spelfiler och spelguiden kan laddas hem från
+http://www.ucw.cz/draci-historie/index-en.html
+
+
+3.20) Kända problem:
+----- --------------
+Den här versionen har följande kända problem. Du behöver inte rapportera dem, men om du kan erbjuda uppdateringar för att fixa problemen vore det välkommet. Om du upptäcker en bugg som inte finns i listan nedan eller i kompatibilitetslistan på hemsidan, var god hänvisa till avdelningen för hur man rapporterar buggar; 2.1.
+
+ Spel med CD-ljud:
+ - När du spelar spel som använder CD-ljud (FM-TOWNS-spel, Loom CD, etc.)
+ kan Microsoft Windows 2000/XP-användare stöta på slumpmässiga krasher.
+ Anledningen är en långlivad Windows-bugg som gör att korrupta spelfiler
+ läses in från CD:n. Kopiera speldatan till din hårddisk för att undvika
+ detta.
+
+ FM-TOWNS-versioner av spel:
+ - Kanji-versioner kräver en FM-TOWNS Font ROM
+ - ScummVM krashar slumpmässigt när FM-TOWNS Font Rom används för
+ kanji-versionerna av de följande spelen:
+ The Secret of Monkey Island, Monkey Island 2: LeChuck's Revenge
+ och Indiana Jones and the Fate of Atlantis
+
+ Loom:
+ - Att stänga av undertexterna via konfigurationsfilen är inte pålitligt då
+ Loom-koden automatiskt aktiverar dem igen.
+ - MIDI stöd i EGA-versionen kräver Roland-uppdateringen från LucasArts
+ - PC-Engine kanji-versionen kräver en ROM för systemkortet
+
+ The Secret of Monkey Island:
+ - MIDI stöd i EGA-versionen kräver Roland-uppdateringen från LucasArts
+
+ Beneath a Steel Sky:
+ - Amiga-versionerna stöds ej
+ - Diskett-demon stöds ej
+ - Inte en bugg: CD-versionen saknar tal för viss dialog. Det här är
+ normalt.
+
+ Elvira - Mistress of the Dark
+ - Ingen musik i Atari ST-versionen
+
+ Elvira II - The Jaws of Cerberus
+ - Ingen musik i Atari ST-versionen
+ - Inga ljudeffekter i PC-versionen
+ - Problem med färgpaletten i Atari ST-versionen
+
+ Inherit the Earth: Quest for the Orb
+ - Amigaversionerna stöds ej
+
+ Simon the Sorcerer 1:
+ - Undertexter är inte tillgängliga i de engelska och tyska
+ CD-versionerna eftersom en majoritet av undertexterna fattas.
+
+ Simon the Sorcerer 2:
+ - Kombinerade tal och undertexter kan ofta orsaka att talljudet
+ klipps av för tidigt. Det här är en begränsning från originalspelet.
+ - Endast standardspråket (engelska) för datafilerna stöds i Amiga-
+ och Macintosh-versionerna.
+
+ Simon the Sorcerer's Puzzle Pack:
+ - Inget stöd för att visa, mata in, ladda eller spara topplistor.
+ - Inget stöd för att visa namnen på föremål när man pekar på dem
+ i Swampy Adventures.
+
+ The Feeble Files:
+ - Undertexterna är ofta ofullständiga – de var alltid avstängda
+ i originalspelet.
+
+ The Legend of Kyrandia:
+ - Varken musik eller ljudeffekter i Macintosh diskett-versioner.
+ - Macintosh-CD använder DOS-musik och ljudeffekter.
+ - PC-9821-versionen saknar stöd för ljudeffekter.
+
+ Humongous Entertainment-spel:
+ - Endast originalgränssnittet för att ladda och spara kan användas.
+ - Inget stöd för multiplayer eller utskrift av bilder.
+
+
+4.0) Stödda plattformar:
+---- -------------------
+ScummVM har konverterats för många olika plattformar och operativsystem. Länkar till dessa konversioner kan du hitta antingen på ScummVM:s hemsida eller via en Google-sökning. Tack till våra konversionsprogrammerare för deras arbete. Om du har en konversion av ScummVM och vill lägga till den i vår master git, kontakta oss gärna!
+
+Stödda plattformar inkluderar bl.a. följande:
+
+ UNIX (Linux, Solaris, IRIX, *BSD, ...)
+ Windows
+ Windows CE och Windows Mobile (inklusive Smartphones och PocketPCs)
+ Mac OS X
+ AmigaOS
+ Android
+ BeOS
+ Dreamcast
+ GP2x
+ iPhone (även iPod Touch och iPad)
+ Maemo (Nokia Internet tablet N810)
+ Nintendo 64
+ Nintendo DS
+ Nintendo GameCube
+ Nintendo Wii
+ OS/2
+ PlayStation 2
+ PlayStation Portable
+ Symbian
+ WebOS
+
+Dreamcast-konversionen stöder inte The Curse of Monkey Island eller The Dig. Nintendo DS-konversionen stöder inte Full Throttle, The Dig eller The Curse of Monkey Island.
+För fler plattform-specifika begränsningar, se vår Wiki:
+ http://wiki.scummvm.org/index.php/Platforms
+
+För Macintosh-konversionen emuleras höger musknapp med Cmd-klickning (klicka med vänster musknapp medan du håller ned Command/Apple/Propeller-knappen).
+
+Det finns inofficiella konversioner för ett antal plattformar inklusive PlayStation 3, Xbox och Xbox 360. Märk att dessa inte är skapade av oss, så vi varken förespråkar eller stöder användning av dem. Använd på egen risk!
+
+
+5.0) Att använda ScummVM:
+---- --------------------
+Märk att ScummVM som standard sparar data i samma katalog som programmet används ifrån, så undvik att köra programmet från fler än en katalog. För ytterligare information, inklusive instruktioner för hur du inrättar en egen katalog för spardata för att undvika det här problemet, se avdelning 6.0.
+
+ScummVM kan öppnas direkt genom att öppna programfilen. I sÃ¥dana fall aktiveras den inbyggda launchern. FrÃ¥n launchern kan du lägga till spel (klicka pÃ¥ â€Lägg till spelâ€) eller spela spel som redan konfigurerats. Spel kan även läggas till i större antal. Genom att hÃ¥lla ned skift-tangenten och trycka pÃ¥ â€Lägg till spel†(lägg märke till att knappen byter namn till â€Masstilläggâ€) kan du specificera en katalog att starta i, varvid ScummVM sedan försöker hitta spel i alla underkataloger.
+
+ScummVM kan även öppna spel via kommandoraden – se nästa avdelning.
+
+
+5.1) Att använda kommandoraden:
+---- --------------------------
+
+Ordning: scummvm [INSTÄLLNINGAR]... [SPEL]
+
+ [SPEL] Kortnamnet för spelet du vill ladda, t.ex. 'monkey'
+ för Monkey Island. Det kan vara det inbyggda kortnamnet
+ eller ett kortnamn bestämt av användaren.
+
+ -v, --version Visar information om ScummVM-versionen
+ -h, --help Visar kortfattad hjälptext
+ -z, --list-games Visar lista med stödda spel
+ -t, --list-targets Visar lista med konfigurerade targets
+ --list-saves=TARGET Visar en lista med sparade data för det specificerade
+ spelet (TARGET)
+ --console Öppnar konsolfönstret (standard: på) (endast Windows)
+ -c, --config=CONFIG Använd alternativ konfigurationsfil (CONFIG)
+ -p, --path=PATH Sökväg dit spelet är installerat (PATH)
+ -x, --save-slot[=NUM] Spardata-nummer att ladda (standard: autosparning)
+ -f, --fullscreen Fullskärmsläge
+ -F, --no-fullscreen Fönsterläge
+ -g, --gfx-mode=MODE Välj grafikskalning (se även avdelning 5.3)
+ --gui-theme=THEME Välj GUI-tema (standard, modern, klassisk)
+ --themepath=PATH Sökväg dit GUI-teman lagras
+ --list-themes Visa full lista med alla användbara GUI-teman
+ -e, --music-driver=MODE Välj musik-driver (se även avdelning 7.0)
+ -q, --language=LANG Välj spelets språk (se även avdelning 5.2)
+ -m, --music-volume=NUM Ställ in musikvolym, 0-255 (standard: 192)
+ -s, --sfx-volume=NUM Ställ in ljudeffektsvolym, 0-255 (standard: 192)
+ -r, --speech-volume=NUM Ställ in röstvolym, 0-255 (standard: 192)
+ --midi-gain=NUM Ställ in gain för MIDI-uppspelning,
+ 0-1000 (standard: 100)
+ (stöds endast av vissa MIDI-drivers)
+ -n, --subtitles Aktivera undertexter (för spel med röster)
+ -b, --boot-param=NUM Skicka nummer till boot script (boot param)
+ -d, --debuglevel=NUM Ställ in debug-ordmängd
+ --debugflags=FLAGS Aktivera motorspecifika debugflaggor
+ (separera med kommatecken)
+ -u, --dump-scripts Aktivera kod-dumpning om en katalog med namnet â€dumpsâ€
+ existerar i den aktiva katalogen
+
+ --cdrom=NUM CD-enheten spelar automatiskt CD-ljud från (NUM)
+ (standard: 0 = första enheten)
+ --joystick[=NUM] Aktivera joystick (standard: 0 = första joystick)
+ --platform=WORD Bestäm plattform för spel (tillåtna värden: 2gs, 3do,
+ acorn, amiga, atari, c64, fmtowns, mac, nes, pc,
+ pce, segacd, windows)
+ --savepath=PATH Sökväg dit spardata lagras
+ --extrapath=PATH â€Extraâ€-sökväg för ytterligare speldata
+ --soundfont=FILE Välj SoundFont för MIDI-uppspelning (Stöds endast
+ av vissa MIDI-drivers)
+ --multi-midi Aktivera kombination av AdLib och Native MIDI
+ --native-mt32 True Roland MT-32 (deaktivera GM-emulation)
+ --enable-gs Aktivera Roland GS-läge för MIDI-uppspelning
+ --output-rate=RATE Välj ljudfrekvens i Hz (t.ex. 22050)
+ --opl-driver=DRIVER Välj AdLib (OPL)-emulator (db, mame)
+ --aspect-ratio Aktivera korrektion av bildförhållande
+ --render-mode=MODE Aktivera ytterligare renderingslägen (cga, ega,
+ hercGreen, hercAmber, amiga)
+
+ --alt-intro Använd alternativt intro för CD-versionerna av Beneath a
+ Steel Sky och Flight of the Amazon Queen
+ --copy-protection Aktiverar kopieringsskyddet för vissa spel
+ där ScummVM automatiskt överskrider det.
+ --talkspeed=NUM Ställ in textfördröjning i SCUMM-spel, eller
+ texthastighet i andra spel. (standard: 60)
+ --demo-mode Öppna demon i Maniac Mansion (klassisk version)
+ --tempo=NUM Ställ in musiktempo (i procent, 50-200) för SCUMM games
+ (standard: 100)
+
+
+Betydelsen för de flesta långa funktionerna (det vill säga de funktioner som börjar med dubbla bindestreck) kan inverteras genom att sätta “no-“ framför dem. Till exmpel, --no-aspect-ratio stänger av korrektion av bildförhållande. Detta är användbart om du vill överskrida en inställning i konfigurationsfilen.
+
+Det korta spelnamnet (“game targetâ€) vid slutet av kommandoraden bestämmer vilket spel som startas. Det matchar antingen en användardefinerad target (frÃ¥n konfigurationsfilen) eller ett inbyggd gameid. En kort lista med de senare finns i avdelning 3.0.
+
+Exempel:
+ * Win32:
+ För att spela Monkey Island i fullskärm från hårddisk:
+ C:\Games\LucasArts\scummvm.exe -f -pC:\Games\LucasArts\monkey\ monkey
+ För att spela Full Throttle från CD i fullskärm med undertexter:
+ C:\Games\LucasArts\scummvm.exe -f -n -pD:\resource\ ft
+
+ * Unix:
+ För att spela Monkey Island i fullskärm från hårddisk:
+ /path/to/scummvm -f -p/games/LucasArts/monkey/ monkey
+ För att spela Full Throttle från CD i fullskärm med undertexter:
+ /path/to/scummvm -f -n -p/cdrom/resource/ ft
+
+
+5.2) Språkinställningar:
+------------------------
+ScummVM stöder vissa språkinställningar för Maniac Mansion, Zak McKracken, The Dig, The Curse of Monkey Island, Beneath a Steel Sky och Broken Sword.
+
+Märk att med undantag för Beneath a Steel Sky, Broken Sword, flerspråksversioner av Goblins-spelen och Nippon Safes Inc. byter INTE den här funktionen språk på spelet (vilket ofta är bestämt i källkoden). Inställningarna låter dig endast byta till ett lämligare typsnitt (t.ex. typsnitt med diakritiska tecken för en tysk version av spelet).
+
+Undantagen här är The Dig och The Curse of Monkey Island – icke-engelsksprÃ¥kiga versioner kan ställas in till “engelskaâ€. Detta pÃ¥verkar dock endast undertexterna; spelets röster förblir de samma.
+
+Maniac Mansion och Zak McKracken
+ en - Engelska (standard)
+ de - Tyska
+ fr - Franska
+ it - Italienska
+ es - Spanska
+
+The Dig
+ jp - Japanska
+ zh - Kinesiska
+ kr - Koreanska
+
+The Curse of Monkey Island
+ en - Engelska (standard)
+ de - Tyska
+ fr - Franska
+ it - Italienska
+ pt - Portugisiska
+ es - Spanska
+ jp - Japanska
+ zh - Kinesiska
+ kr - Koreanska
+
+Beneath a Steel Sky
+ gb - Engelska (Storbritannien) (standard)
+ en - Engelska (USA)
+ de - Tyska
+ fr - Franska
+ it - Italienska
+ pt - Portugisiska
+ es - Spanska
+ se - Svenska
+
+Broken Sword
+ en - Engelska (standard)
+ de - Tyska
+ fr - Franska
+ it - Italienska
+ es - Spanska
+ pt - Portugisiska
+ cz - Tjeckiska
+
+
+5.3.) Grafikfilter:
+----- -------------
+ScummVM erbjuder ett antal anti-aliasfilter för att förbättra bildkvaliteten. Dessa filter används i många andra emulatorer, t.ex. MAME. De kan ta ett spels originalgrafik och förstora den enligt förbestämda faktorer (vanligtvis 2x eller 3x). Till exempel: om spelet från början endast kunde spelas i 320x200 upplösning (typiskt för de flesta SCUMM-spelen) ger dig ett filter med skalningsfaktor 2x istället 640x400 upplösning. På samma sett ger dig ett 3x filter 960x600.
+
+Tillgängliga filter:
+ 1x - Inget filter, ingen skalning. Snabbast.
+ 2x - Inget filter, faktor 2x (standard för spel utan 640x480).
+ 3x - Inget filter, faktor 3x.
+ 2xsai - 2xSAI filter, faktor 2x.
+ super2xsai - Förbättrat 2xSAI filter, faktor 2x.
+ supereagle – Mindre suddigt än 2xSAI, men långsammare. Faktor 2x.
+ advmame2x - Använder inte suddighet som 2xSAI, snabbt. Faktor 2x.
+ advmame3x - Använder inte suddighet som 2xSAI, snabbt. Faktor 3x.
+ hq2x - Fint filter av hög kvalitet, men långsamt. Faktor 2x.
+ hq3x - Fint filter av hög kvalitet, men långsamt. Faktor 3x.
+ tv2x - Interlace-filter, försöker emulera TV-skärmen. Faktor 2x.
+ dotmatrix - Dot matrix-effekt. Faktor 2x.
+
+För att använda ett grafiskfilter, välj det i Launchern eller skicka dess namn via “-g†funktionen till scummvm, till exempel:
+
+ scummvm -gadvmame2x monkey2
+
+Notis #1: Vissa back-ends stöder inte alla (eller ens några) av filterna ovan; vissa kan stöda övriga filter. Filterna ovan är de som stöds av standard SDL-back-end.
+
+Notis #2: Filter kan bli väldigt långsamma när ScummVM kompileras i en debug-konfiguration utan optimering och hastigheten påverkas alltid när man använder en form av anti-alias/linjär filtrering.
+
+Notis #3: FM-TOWNS-versionen av Zak McKracken använder en upplösning på 320x240. Konsekvent sker skalning för det här spelet till 640x480 eller 960x720. På samma sätt skalas spel som från början använder 640x480 (t.ex. Curse of Monkey Island eller Broken Sword) upp till 1280x960 och 1920x1440.
+
+
+5.4) Den globala menyn:
+---- ------------------
+Den globala menyn är en generisk meny som kan användas i alla spelmotorer genom att trycka Ctrl-F5. I den här menyn finns följande knappar: Fortsätt, Inställningar, Om, Ã…tervänd till launcher, och Avsluta. Väljer du â€Inställningar†öppnas en dialogruta där grundläggande ljudinställningar, t.ex. volymnivÃ¥n, kan justeras. Väljer du â€Ã…tervänd till launcher†stängs spelfönstret och du skickas tillbaka till ScummVM-launchern där du kan välja andra spel att spela.
+
+Notis: Att återvända till launchern stöds inte av alla spelmotorer och knappen kommer deaktiveras i den globala menyn för spel där funktionen inte stöds.
+
+Motorer som för närvarande stöder återvändo till launchern:
+
+ AGI
+ AGOS
+ CINE
+ DRACI
+ GOB
+ GROOVIE
+ KYRA
+ LURE
+ PARALLACTION
+ QUEEN
+ SAGA
+ SCUMM
+ SKY
+ SWORD1
+ SWORD2
+ TOUCHE
+ TUCKER
+
+
+5.5) Kortkommandon:
+---- --------------
+ScummVM stöder ett antal kortkommandon medan du spelar. De är olika för SCUMM-spel och andra spel.
+
+ Gemensamma:
+ Ctrl-F5 - Öppnar menyn
+ Cmd-q - Avsluta (Mac OS X)
+ Ctrl-q - Avsluta (andra system inklusive Linux)
+ Ctrl-z ELLER Alt-x - Avsluta (andra plattformar)
+ Ctrl-u - Stäng av allt ljud
+ Ctrl-m - Aktivera musrestriktion
+ Ctrl-Alt 1-8 - Växla grafikfilter
+ Ctrl-Alt + och - - Höj/sänk skalningsfaktor
+ Ctrl-Alt a - Aktivera/deaktivera korrigering av bild-
+ förhållanden. De flesta spelen använder en
+ upplösning på 320x200 pixlar, vilket kan
+ se förvrängt ut på moderna skärmar.
+ Korrigering av bildförhållanden sträcker
+ bilden proportionellt till 320x240.
+
+ Alt-Enter - Växlar mellan fullskärm och fönster
+ Alt-s - Skärmdump (endast med SDL-back-end)
+
+ SCUMM:
+ Ctrl 0-9 och Alt 0-9 - Ladda och spara speldata
+ Ctrl-d - Öppnar debug-fönstret
+ Ctrl-f - Aktivera snabbläge
+ Ctrl-g - Aktivera EXTRA snabbt läge
+ Ctrl-t - Växla mellan “Endast talâ€,
+ “Tal och undertexter†och â€Endast undertexterâ€
+ Tilde (~) - Visa/dölj debug-konsolen
+ [ och ] - Musikvolym höj/sänk
+ - och + - Texthastighet långsammare/snabbare
+ F5 - Visar en ladda/spara-ruta
+ Alt-F5 - Visar spelets originalruta för att ladda/spara,
+ förutsatt att det finns en. Du kan ladda och spara
+ på det här viset, men det rekommenderas ej då det
+ kan orsaka krascher.
+ i - Visar IQ-poäng (Indiana Jones and the Last
+ Crusade och Indiana Jones and the Fate of
+ Atlantis)
+ Space - Paus
+ Punkt (.) - Hoppar över en textrad i vissa spel
+ Enter - Simulerar vänster musklick
+ Tab - Simulerar höger musklick
+
+ Beneath a Steel Sky:
+ Ctrl-d - Öppnar debug-fönstret
+ Ctrl-f - Aktivera snabbläge
+ Ctrl-g - Aktivera EXTRA snabbt läge
+ F5 - Visar en ladda/spara-ruta
+ Escape - Hoppar över spelets intro
+ Punkt (.) - Hoppar över en textrad
+
+ Broken Sword:
+ F5 eller Escape - Visar en ladda/spara-ruta
+
+ Broken Sword II:
+ Ctrl-d - Öppnar debug-fönstret
+ Ctrl-f - Aktivera snabbläge
+ p - Paus
+
+ Dragon History:
+ F5 - Visar globala menyn
+ vänsterklick - Gå, utforska
+ högerklick - Use, talk
+ rör mus uppåt, i - Inventarie
+ rör mus nedåt, m - Karta
+ Escape - Hoppa över intro, lämna karta/inventarie
+ musklick - Hoppar över pågående filmscen
+ q - Snabb gång på/av
+
+ Flight of the Amazon Queen:
+ Ctrl-d - Öppnar debug-fönstret
+ Ctrl-f - Aktivera snabbläge
+ F1 - Använd dagbok (spara/ladda)
+ F11 - Snabbspara
+ F12 - Snabbladda
+ Escape - Hoppa över filmscen
+ Mellanslag - Hoppa över textrad
+
+ Future Wars
+ F1 - Undersök
+ F2 - Ta
+ F3 - Inventarie
+ F4 - Använd
+ F5 - Aktivera
+ F6 - Tala
+ F9 - "Aktivera"-meny
+ F10 - "Använd"-meny
+ Escape - Öppna kommandomeny
+
+ Nippon Safes
+ Ctrl-d - Öppnar debug-fönstret
+ l - Ladda data
+ s - Spara data
+
+ Simon the Sorcerer 1 och 2:
+ Ctrl 0-9 och Alt 0-9 - Ladda och spara data
+ Ctrl-d - Öppnar debug-fönstret
+ Ctrl-f - Aktivera snabbläge
+ F1 - F3 - Texthastighet snabbare - långsammare
+ F10 - Visar alla karaktärer och föremål du kan
+ interagera med
+ Escape - Hoppa över filmscen
+ - och + - Musikvolym sänk/höj
+ m - Musik av/på
+ s - Ljudeffekter av/på
+ b - Bakgrundsljud av/på
+ [endast Simon the Sorcerer 2]
+ Pause - Paus
+ t - Växla mellan endast tal och kombinerade
+ tal och undertexter
+ [Simon the Sorcerer 1 CD (förutom
+ engelska och tyska) och Simon the
+ Sorcerer 2 CD (alla språk)]
+ v - Växla mellan endast undertexter och kombinerade
+ tal och undertexter
+ [endast Simon the Sorcerer 2 CD]
+
+ Simon the Sorcerer's Puzzle Pack
+ Ctrl-d - Öppnar debug-fönstret
+ Ctrl-f - Aktivera snabbläge
+ F12 - Snabbläge av/på i Swampy Adventures
+ - och + - Musikvolym sänk/höj
+ m - Musik av/på
+ s - Ljudeffekter av/på
+ Pause - Paus
+
+ The Feeble Files
+ Ctrl-d - Öppnar debug-fönstret
+ Ctrl-f - Aktivera snabbläge
+ F7 - Byt karaktär
+ F9 - Hitbox-namn av/på
+ s - Ljudeffekter av/på
+ Pause - Paus
+ t - Växla mellan endast tal och kombinerade
+ tal och undertexter
+ v - Växla mellan endast undertexter och kombinerade
+ tal och undertexter
+
+ The Legend of Kyrandia:
+ Ctrl 0-9 och Alt 0-9 - Ladda och spara speldata
+ Ctrl-d - Öppnar debug-fönstret
+
+ TeenAgent
+ F5 - Visar den globala menyn
+
+ Touche: The Adventures of the Fifth Musketeer:
+ Ctrl-f - Aktivera snabbläge
+ F5 - Visa inställningar
+ F9 - Snabbt gångläge på
+ F10 - Snabbt gångläge av
+ Escape - Avsluta
+ Space - Hoppa över textrad
+ t - Växla mellan “Endast talâ€,
+ “Tal och undertexter†och â€Endast undertexterâ€
+
+Märk att trycka Ctrl-f och Ctrl-g inte rekommenderas: spel kan krasha när de spelas snabbare än normalt, då koden kan desynkroniseras.
+
+Notis för WinCE-användare: På grund av de begränsade tangentborden på de flesta enheter stöds ett litet antal av de här tangenterna via tangentinställning och/eller kontrollpanelen. Var god se READ-WinCE.txt filen.
+
+
+6.0) Spardata:
+---- ---------
+Spardata lagras som standard i den aktiva katalogen på vissa plattformar och i förbestämda kataloger på andra plattformar. Du kan ställa in katalogen i konfigurationsfilen genom att ändra savepath-parametern. Se exempel för konfigurationsfilen senare i detta dokument.
+
+Plattformar som för närvarande har annorlunda standardkataloger:
+ Mac OS X: $HOME/Documents/ScummVM Savegames/
+ Övriga unix-system: $HOME/.scummvm/
+
+
+6.1) Autosparning:
+---- -------------
+I vissa spel (nämligen “Beneath a Steel Skyâ€, “Flight of the Amazon Queenâ€, alla AGI-spel och alla SCUMM-spel) autosparar som standard ScummVM var femte minut (detta kan justeras via “autosave_period†inställningen i konfigurationsfilen). För AGI- och SCUMM-motorerna sparas data i position 0. För SCUMM-motorn kan den här positionen laddas igen via Ctrl-0 eller F5-menyn.
+
+
+6.2) Att konvertera speldata:
+---- ------------------------
+Att använda spardata från originalversioner av spel stöds inte av alla spelmotorer. Endast följande spel kan använda spardata från sina originalversioner.
+
+ Elvira 1
+ - Lägg till 8 byte (namn för spardata) i början av spardata-filen
+ - Döp om spardatan till â€elvira1.xxxâ€
+
+ Elvira 2
+ - Lägg till 8 byte (namn för spardata) i början av spardata-filen
+ - Döp om spardatan till â€elvira2-pc.xxx†(DOS-versionen) eller
+ â€elvira2.xxx†(övriga versioner)
+
+ Waxworks
+ - Lägg till 8 byte (namn för spardata) i början av spardata-filen
+ - Döp om spardatan till â€waxworks-pc.xxx†(DOS-versionen) eller
+ â€waxworks.xxx†(övriga versioner)
+
+ Simon the Sorcerer 1
+ - Döp om spardatan till â€simon1.xxxâ€
+
+ Simon the Sorcerer 2
+ - Döp om spardatan till â€simon2.xxxâ€
+
+ The Feeble Files
+ - Döp om spardatan till â€feeble.xxxâ€
+
+Där “xxx†står för positionsnumret (t.ex. 001) i ScummVM.
+
+
+6.3) Visa/ladda spardata från kommandoraden:
+---- ---------------------------------------
+
+--list-saves:
+
+ Den här funktionen kan användas för att visa en lista med befintliga speldata
+ från det specificerade spelet och dess respektive spar-positioner.
+
+ Användning: --list-saves=[TARGET], där [TARGET] är spelets kortnamn.
+
+ Motorer som för tillfället stöder --list-saves:
+
+ AGI
+ AGOS
+ CINE
+ DRACI
+ GROOVIE
+ KYRA
+ LURE
+ PARALLACTION
+ QUEEN
+ SAGA
+ SCUMM
+ SKY
+ SWORD1
+ SWORD2
+ TINSEL
+ TOUCHE
+ TUCKER
+
+--save-slot/-x:
+
+ Den här funktionen kan användas för att ladda spardata direkt från
+ kommandoraden.
+
+ Användning: --save-slot[SLOT] eller -x[SLOT], där [SLOT] är spardatans
+ positionsnummer.
+
+ Motorer som för tillfället stöder --save-slot/-x:
+
+ AGI
+ CINE
+ DRACI
+ GROOVIE
+ KYRA
+ LURE
+ PARALLACTION
+ QUEEN
+ SAGA
+ SCUMM
+ SKY
+ SWORD1
+ SWORD2
+ TINSEL
+ TOUCHE
+
+
+7.0) Musik och ljud:
+---- ---------------
+För de flesta operativsystemen och spelen använder ScummVM som standard MT-32 eller AdLib-emulation för musikuppspelning. MIDI kan vara otillgängligt på vissa operativsystem eller i behov av manuell inställning. Om du vill använda MIDI har du flera val för uppspelning beroende på ditt operativsystem och dina inställningar.
+
+ null - Ingen musikuppspelning.
+
+ adlib - Intern AdLib-emulation
+ fluidsynth - FluidSynth MIDI-emulation
+ mt32 - Intern MT-32-emulation
+ pcjr - Intern PCjr-emulation (fungerar endast i SCUMM-spel)
+ pcspk - Intern PC Speaker-emulation
+ towns - Intern FM-TOWNS YM2612 emulation
+ (fungerar endast i SCUMM FM-TOWNS-spel)
+
+ alsa - Uppspelning med ALSA sequencer-enhet. Se nedan.
+ core - CoreAudio ljud, för Mac OS X användare.
+ coremidi - CoreMIDI ljud, för Mac OS X användare. Använd endast om du har
+ en MIDI-synthesizer i hårdvaruform.
+ seq - Använd /dev/sequencer för MIDI, *nix användare. Se nedan.
+ timidity - Anslut till TiMidity++ MIDI-servern. Se nedan.
+ windows - Windows MIDI. Använd inbyggd sequencer, för Windows användare
+
+För att använda en musik-driver, välj den i launchern eller skicka dess namn via â€-e†funktionen till scummvm, till exempel:
+
+ scummvm -eadlib monkey2
+
+
+7.1) Spela ljud med AdLib emulation:
+---- -------------------------------
+Som standard emuleras ett AdLib-kort och ScummVM spelar upp musiken efter samplade ljudvågor. Det här är standardläget för många spel och erbjuder bäst kompatibilitet mellan maskin och spel.
+
+
+7.2) Ljud med FluidSynth MIDI-emulation:
+---- -----------------------------------
+Om ScummVM byggts med stöd för libfluidsynth kommer programmet kunna spela MIDI-musik via FluidSynth-drivern. Dock måste du specificera vilket SoundFont som ska användas.
+
+DÃ¥ standardvolymen frÃ¥n FluidSynth kan vara ganska lÃ¥g ställer ScummVM in gain för att fÃ¥ en bättre signal som standard. Denna kan justeras ytterligare via –midi-gain funktinonen i kommandoraden, eller inställningen â€midi_gain†i konfigurationsfilen.
+
+Du kan justera med ett värde från 0 till 1000, där standardvärdet är 100. (Detta matchar FluidSynths gain-inställningar från 0.0 till 10.0, troligtvis räknade i decibel.)
+
+NOTERA: Processorkraven för FluidSynth kan vara höga – en snabb processor rekommenderas.
+
+
+7.3) Ljud med MT-32-emulation:
+---- -------------------------
+Somliga spel som innehåller MIDI-musikdata har även förbättrade ljudspår designade för MT-32 ljudmodulen. ScummVM kan nu emulera den här enheten, men du måste dock använda MT-32 original-ROM:s för att det ska fungera:
+
+MT32_PCM.ROM - IC21 (512KB)
+MT32_CONTROL.ROM - IC26 (32KB) och IC27 (32KB), sammanflätade byte
+
+Placera dessa ROM-filer i spelkatalogen, i din â€Extraâ€-sökväg, eller i katalogen där ScummVM-programfilen befinner sig.
+
+Du behöver inte specificera –-native-mt32 med den här drivern, då den aktiveras automatiskt.
+
+NOTERA: Processorkraven för emulatorn är mycket höga – en snabb processor rekommenderas.
+
+
+7.4) Ljud med MIDI-emulation:
+---- ------------------------
+Vissa spel (t.ex. Sam & Max) innehåller endast musikdata i MIDI-form. En gång i tiden förhindrade detta musiken från att fungera i dessa spel på plattformar som inte stödde MIDI samt ljudkort som inte hade MIDI-drivers (t.ex. spelar många ljudkort inte MIDI under Linux). ScummVM kan nu emulera MIDI-läget med hjälp av samplade ljudvågor och AdLib, FluidSynth MIDI-emulation eller MT-32-emulation genom att använda –eadlib, -efluidsynth eller –emt32 funktionerna. Om du har möjlighet att använda Native MIDI rekommenderar vi ett av MIDI-lägena för bästa ljudkvalitet.
+
+
+7.5) Ljud med Native MIDI:
+---- ---------------------
+Använd den lämpliga –e<mode> funktionen i kommandoraden från listan ovan för att välja din föredragna MIDI-enhet. Till exempel, om du vill använda Windows MIDI-drivern, använd –ewindows funktionen.
+
+
+7.5.1) MIDI-inställningar för Native MIDI-uppspelning:
+------ -----------------------------------------------
+ScummVM stöder ett antal MIDI-lägen, beroende på din MIDI-enhets egenskaper.
+
+Om –-native-mt32 specificerats kommer ScummVM behandla din enhet som en verklig MT-32. Då instrumentkartan och systemkommandon hos MT-32:an är annorlunda från andra generiska MIDI-enheter borde du endast använda den här funktionen om du verkligen använder en riktig Roland MT-32, LAPC-I, CM-64, CM-32L, CM-500 eller GS-enhet med en MT-32 karta.
+
+Om –-enable-gs specificerats kommer ScummVM ställa in din GS-kompatibla enhet med inställningar som härmar MT-32:ans reverb, (brist på) chorus, pitch bend-känslighet, etc. Om det specificerats tillsammans med –-native-mt32 kommer ScummVM välja den MT-32-kompatibla kartan och trumsetet på din GS-enhet. Den här inställningen fungerar bättre än standard GM- eller GS-emulation i spel som saknar speciella instrumentkartor (Loom och Monkey1). Du borde endast specificera båda funktionerna om du använder en GS-enhet som har en MT-32 karta, till exempel en SC-55, SC-88, SC-88 Pro, SC-8820, SC-8850, etc. Märk att –-enable-gs är automatiskt deaktiverad i både DOTT och Samnmax, då de använder General MIDI.
+
+Om ingendera av de ovanstående inställningarna aktiverats kommer ScummVM ställa in din enhet i General MIDI-läge och använda GM-emulation i spel med MT-32 musik.
+
+Vissa spel innehåller ljudeffekter som är exklusiva för AdLib-musik. För dessa spel kan du specificera --multi-midi för att kombinera MIDI-musik med AdLib-ljudeffekter.
+
+
+7.6) Ljud med Sequencer MIDI: [ENDAST UNIX]
+---- ------------------------
+Om ditt ljudkort stöder en sequencer kan du ställa in environment-variabeln “SCUMMVM_MIDI†till din sequencer-enhet – till exempel till /dev/sequencer.
+
+Om du inte kan höra ljudet med den här konfigurationen kan du behöva ställa in environment-variabeln â€SCUMMVM_MIDIPORT†till 1 eller 2. PÃ¥ det här viset väljer du vilken port som används pÃ¥ den valda sequencern. Starta sedan scummvm med –eseq parametern. Det här borde fungera pÃ¥ flera ljudkort och kan erbjuda bättre prestanda och kvalitet än AdLib-emulation. För de system som inte stöder sequencer MIDI kan du alltid använda AdLib-emulation istället.
+
+
+7.6.1) Ljud med ALSA sequencer: [ENDAST UNIX]
+------ ------------------------
+Om du installerat ALSA-drivern med stöd för sequencer kan du ställa in environment-variabeln “SCUMMVM_PORT†eller konfigurationsfilsvariabeln “also_port†för att specificera sequencer-porten. Om ingendera är inställd är standardprocessen att försöka bÃ¥de â€65:0†och â€17:0â€.
+
+Här är en kort guide för hur du använder ALSA sequencern med ditt ljudkort. För att fÃ¥ en lista pÃ¥ alla sequencer-portar du har, försök kommandot â€aconnect –o -lâ€. Det borde ge dig en output i stil med följande:
+
+client 14: 'Midi Through' [type=kernel]
+ 0 'Midi Through Port-0'
+client 16: 'SBLive! Value [CT4832]' [type=kernel]
+ 0 'EMU10K1 MPU-401 (UART)'
+client 17: 'Emu10k1 WaveTable' [type=kernel]
+ 0 'Emu10k1 Port 0 '
+ 1 'Emu10k1 Port 1 '
+ 2 'Emu10k1 Port 2 '
+ 3 'Emu10k1 Port 3 '
+client 128: 'TiMidity' [type=user]
+ 0 'TiMidity port 0 '
+ 1 'TiMidity port 1 '
+ 2 'TiMidity port 2 '
+ 3 'TiMidity port 3 '
+
+Viktigst här är att det finns fyra WaveTable MIDI-outputs på 17:0, 17:1, 17:2 och 17:3, samt fyra TiMidity-portar på 128:0, 128:1, 128:2 och 128:3.
+
+Om du har ett FM-chip på ditt kort, som på SB16, kan du ladda SoundFonts med hjälp av sbiload-mjukvaran. Exempel:
+
+ sbiload -p 17:0 /etc/std.o3 /etc/drums.o3
+
+Om du har ett WaveTable-kapabelt ljudkort måste du ladda ett sbk- eller sf2-SoundFont med hjälp av sfxload eller asfxload-mjukvaran. Exempel:
+
+ sfxload /path/to/8mbgmsfx.sf2
+
+Om du inte har ett MIDI-kapabelt ljudkort finns det två möjligheter:
+FluidSynth och TiMidity. Vi rekommenderar FluidSynth, då TiMidity kan orsaka musikfördröjning på många system. Detta är väldigt märkbart i iMUSE-spel, vilka använder snabba och dynamiska musikskiften. Att köra TiMidity som root låter det sätta upp aktiv tidsprioritering, vilket kan reducera musikfördröjningen.
+
+För att göra TiMidity till en ALSA sequencer:
+
+ timidity -iAqqq -B2,8 -Os1S -s 44100 &
+
+(Om du får förvrängd uppspelning med den här inställningen försök samma kommando utan –B2,8, eller ändra värdet.)
+
+För att göra FluidSynth till en ALSA sequencer (med SoundFonts):
+
+ fluidsynth -m alsa_seq /path/to/8mbgmsfx.sf2
+
+När antingen TiMidity eller FluidSynth väl är igÃ¥ng kan du använda “aconnect –o –lâ€-kommandot enligt ovan.
+
+
+7.6.2) Ljud med IRIX dmedia sequencer: [ENDAST UNIX]
+---- ---------------------------------
+Om du använder IRIX och dmedia-drivern med sequencer-stöd kan du ställa in environment-variabeln “SCUMMVM_MIDIPORT†eller konfigurationsfilsvariabeln “dmedia_port†för att specificera din sequencer-port. Standardprocessen är att använda den första porten.
+
+För att få en lista med konfigurerade midi-interface på ditt system, kör
+â€startmidi†utan parametrar. Exempel pÃ¥ output:
+
+ 2 konfigurerade MIDI interface:
+ Serial Port 2
+ Software Synth
+
+I exemplet ovan kan du konfigurera ScummVM att använda “Software Synth†istället för den standardförvalda “Serial Port 2†genom att lägga till följande rad
+
+ dmedia_port=Software Synth
+
+i din konfigurationsfil i avdelningen [scummvm] eller ställa in SCUMMVM_PORT=Software Synth i ditt environment.
+
+
+7.7) Att använda TiMidity++ MIDI-servern:
+---- ------------------------------------
+Om ditt system saknar en MIDI-sequencer men du fortfarande vill ha bättre MIDI-kvalitet än standard AdLib-emulation har att erbjuda kan du prova TiMidity++ MIDI-servern. Se http://timidity.sourceforge.net/ för instruktioner för nedladdning och installation.
+
+
+Först måste du starta en daemon:
+
+ timidity -ir 7777
+
+Nu kan du starta ScummVM och prova att välja TiMidity musikuppspelning. Som standard ansluter sig programmet till localhost:7777 men du kan ändra värd/port via â€TIMIDITY_HOST†environment-variabeln. Du kan även specificera ett enhetsnummer (device number) via environment-variabeln i â€SCUMMVM_MIDIPORTâ€.
+
+
+7.8) Att använda komprimerade ljudfiler
+---- ----------------------------------
+
+7.8.0) Att använda MP3 filer som CD-ljud:
+------ ----------------------------------
+Använd LAME eller en annan MP3-kodare för att extrahera ljudspåren från CD som filer. Namnge filerna track1.mp3, track2.mp3, etc. ScummVM måste ha kompilerats med MAD-stöd för att använda den här metoden. Om du behöver extrahera filerna från CD:n som WAV-filer, se till att koda MP3-filerna med konstant bit-ratio. Det kan du göra med följande kommandorad för LAME:
+
+ lame -t -q 0 -b 96 track1.wav track1.mp3
+
+
+7.8.1) Att använda Ogg Vorbis-filer som CD-ljud:
+------ -----------------------------------------
+Använd oggenc eller en annan vorbis-kompressor för att komprimera ljudspåren till filer. Namnge filerna track1.ogg, track2.ogg, etc. ScummVM måste kompileras med vorbis-stöd för att kunna använda den här funktionen. Du måste extrahera filerna från CD:n som WAV-filer, sedan komprimera vorbis-filerna. Detta kan göras via följande oggenc kommandorad. Värdet efter q specificerar önskad kvalitet från 0 till 10:
+
+ oggenc -q 5 track1.wav
+
+
+7.8.2) Att använda Flac-filer som CD-ljud:
+------ -----------------------------------
+Använd flac eller en annan flac-kompressor för att komprimera ljudspåren till filer. Namnge filerna track1.flac, track2.flac, etc. Om ditt filsystem endast tillåter tre bokstäver i filändelser, namnge filerna track1.fla, track2.fla, etc. ScummVM måste kompileras med flac-stöd för att använda den här funktionen. Du måste extrahera filerna från CD:n som WAV-filer, sedan komprimera flac-filerna. Detta kan göras med följande flac kommandorad:
+
+ flac --best track1.wav
+
+Kom ihåg att kvaliteten alltid är densamma; att ändra komprimeringsinställningarna påverkar endast komprimeringstiden och den slutgiltiga filstorleken.
+
+
+7.8.3) Att komprimera MONSTER.SOU med MP3:
+------ -----------------------------------
+Du behöver LAME och â€compress_scumm_souâ€-verktyget frÃ¥n scummvm-tools paketet för att göra det här, och ScummVM mÃ¥ste kompileras med MAD-stöd.
+
+ compress_scumm_sou monster.sou
+
+Till slut kommer du ha en mycket mindre monster.so3-fil. Kopiera den här filen till din spelkatalog. Du kan med säkerhet radera monster.sou-filen.
+
+
+7.8.4) Att komprimera MONSTER.SOU med Ogg Vorbis:
+------ ------------------------------------------
+Som ovan, men ScummVM måste kompileras med OGG-stöd. Kör
+
+ compress_scumm_sou --vorbis monster.sou
+
+Detta borde skapa en mindre monster.sog-fil som du bör kopiera till din spelkatalog. Ogg-kompression kan ta betydligt längre än MP3, så se till att ha en god bok tillhanda.
+
+
+7.8.5) Att komprimera MONSTER.SOU med Flac:
+------ ------------------------------------
+Som ovan, men ScummVM måste kompileras med Flac-stöd. Kör:
+
+ compress_scumm_sou --flac monster.sou
+
+Detta borde skapa en mindre monster.sof-fil som du bör kopiera till din spelkatalog. Kom ihåg att kvaliteten alltid är den samma; att ändra komprimeringsinställningarna påverkar endast komprimeringstiden och den slutgiltiga filstorleken. Att leka med blockstorleken (-b <value>) har störst inverkan på den slutliga filstorleken – 1152 verkar vara ett bra värde för dessa typer av ljudfiler. Se till att läsa instruktionerna för kompressorn innan du använder andra värden.
+
+7.8.6) Att komprimera musik/ljudeffekter/tal i AGOS-spel:
+------ --------------------------------------------------
+Använd “compress_agosâ€-verktyget frÃ¥n scummvm-tools paketet för att göra det här. Du kan välja mellan ett flertal komprimeringsformat, men märk att du endast kan använda dem om ScummVM kompilerats med stöd för respektive dekoder.
+
+ compress_agos effects (För Acorn CD-versionen av Simon 1)
+ compress_agos simon (För Acorn CD-versionen av Simon 1)
+ compress_agos effects.voc (För DOS CD-versionen av Simon 1)
+ compress_agos simon.voc (För DOS CD-versionen av Simon 1)
+ compress_agos simon.wav (För Windows CD-versionen av Simon 1)
+ compress_agos simon2.voc (För DOS CD-versionen av Simon 2)
+ compress_agos simon2.wav (För Windows CD-versionen av Simon 2)
+ compress_agos mac (För Macintosh-versionen av Simon 2)
+
+ compress_agos voices1.wav (För Windows 2CD/4CD-versionen av Feeble)
+ compress_agos voices2.wav (För Windows 2CD/4CD-versionen av Feeble)
+ compress_agos voices3.wav (För Windows 4CD-versionen av Feeble)
+ compress_agos voices4.wav (För Windows 4CD-versionen av Feeble)
+
+ compress_agos Music (För Windows-versionen av Puzzle Pack)
+
+För Ogg Vorbis, lägg till --vorbis till inställningarna, t.ex.
+
+ compress_agos --vorbis
+
+För Flac, lägg till --flac och valfria parametrar, t.ex.
+
+ compress_agos –flac
+
+Till slut kommer du ha en mycket mindre *.mp3, *.ogg eller *.fla-fil. Kopiera den här filen till din spelkatalog. Du kan med säkerhet radera den gamla filen.
+
+
+7.8.7) Att komprimera tal/musik i Broken Sword:
+------ -----------------------------------------
+“Compress_sword1â€-verktyget frÃ¥n scummvm-tools paketet kan komprimera musik och tal till MP3, Ogg Vorbis eller Flac. Det enklaste sättet att komprimera filerna är att kopiera programfilen till din BS1-katalog (tillsammans med lame-kompressorn) och köra den därifrÃ¥n. PÃ¥ det här viset kommer den automatiskt komprimera allting till MP3. EfterÃ¥t kan du för hand radera SPEECH?.CLU-filerna och wave musik-filerna.
+
+Att köra "compress_sword1 --vorbis" komprimerar filerna med Ogg
+Vorbis istället för MP3.
+
+Att köra "compress_sword1 --flac" komprimerar filerna med Flac istället för MP3.
+
+Använd “compress_sword1 –-help†för att få en full lista med inställningar.
+
+
+7.8.8) Att komprimera tal/musik i Broken Sword II:
+------ -------------------------------------------
+Använd “compress_sword2â€-verktyget frÃ¥n scummvm-tools paketet för att göra det här. Du kan välja mellan ett flertal komprimeringsformat, men märk att du endast kan använda dem om ScummVM kompilerats med stöd för respektive dekoder.
+
+ compress_sword2 speech1.clu
+ compress_sword2 music1.clu
+
+För Ogg Vorbis, lägg till --vorbis till inställningarna, t.ex.
+
+ compress_sword2 --vorbis
+
+Till slut kommer du ha en mycket mindre *.cl3 eller *.clg-fil. Kopiera den här filen till din spelkatalog. Du kan med säkerhet radera den gamla filen.
+
+Det är möjligt att använda Flac-komprimering genom att lägga till –-flac inställningen. Den resulterande *.clf-filen blir dock faktiskt större än originalfilen.
+
+Tänk på att compress_sword2 endast fungerar med de fyra tal/musikfilerna i Broken Sword II. Det fungerar inte för de andra *.clu-filerna, och inte heller med talfilerna från Broken Sword.
+
+
+7.9) Uppspelningsfrekvens:
+---- ---------------------
+Uppspelningsfrekvensen bestämmer hur många ljudsamplingar som spelas per kanal per sekund. Det finns mycket att säga om det här ämnet, men det mesta vore irrelevant här. Kortfattat är 22050 Hz gott nog för de flesta spelen, men i vissa fall är 44100 Hz att föredra. På extremt lågpresterande system kanske du vill använda 11025 Hz, men det är inte troligt att du behöver oroa dig för detta.
+
+De flesta ljuden ScummVM måste spela upp samplades med antingen 22050 Hz eller 11025 Hz. En högre uppspelningsfrekvens kommer alltså inte som av trolleri förbättra ljudkvaliten för dessa ljud. Sålunda räcker 22050 Hz gott och väl.
+
+Vissa spel använder CD-ljud. Om du vill använda komprimerade filer för CD-ljudspåren kan du utgå ifrån att de samplades med 44100 Hz, så för dessa spel är detta ett bättre val av uppspelningsfrekvens.
+
+När du använder AdLib, FM Towns, PC Speaker eller IBM PCjr musikdrivers är ScummVM ansvarigt för att generera samplingarna. Vanligtvis är 22050 Hz mer än nog för dessa, men det finns minst ett stycke AdLib musik i Beneath a Steel Sky som låter mycket bättre i 44100 Hz.
+
+Att använda frekvenser mellan de ovansagda rekommenderas ej. Till att börja med finns risken att ditt ljudkort inte stöder dem. I teorin borde ScummVM växla till en mer resonlig frekvens i sådana fall, men räkna inte med det. Vad värre är måste ScummVM återsampla alla ljud till den nya uppspelningsfrekvensen. Detta är mycket lättare att göra ordentligt om ljudfrekvensen är en multipel av originalfrekvensen.
+
+
+8.0) Konfigurationsfilen:
+---- --------------------
+Som standard sparas och laddas konfigrationsfilen i:
+
+ Windows Vista:
+ \Users\username\AppData\Roaming\ScummVM\scummvm.ini,
+
+ Windows 2000/XP:
+ \Documents and Settings\username\Application Data\ScummVM\scummvm.ini,
+
+ Windows NT4:
+ <windir>\Profiles\username\Application Data\ScummVM\scummvm.ini,
+
+ Windows 95/98/ME:
+ <windir>\scummvm.ini,
+
+ Om en tidigare version av ScummVM installerats i Windows behålls
+ den tidigare standardsökvägen â€<windir>\scummvm.iniâ€.
+
+ Unix:
+ ~/.scummvmrc
+
+ Mac OS X:
+ ~/Library/Preferences/ScummVM Preferences
+ (här hänvisar ~ till din hemkatalog)
+
+ Övriga:
+ scummvm.ini i den nuvarande katalogen
+
+Ett exempel på en konfigurationsfil ser ut så här:
+
+ [scummvm]
+ gfx_mode=supereagle
+ fullscreen=true
+ savepath=C:\saves\
+
+ [sky]
+ path=C:\games\SteelSky\
+
+ [germansky]
+ gameid=sky
+ language=de
+ path=C:\games\SteelSky\
+ description=Beneath a Steel Sky w/ German subtitles
+
+ [germandott]
+ gameid=tentacle
+ path=C:\german\tentacle\
+ description=German version of DOTT
+
+ [tentacle]
+ path=C:\tentacle\
+ subtitles=true
+ music_volume=40
+ sfx_volume=255
+
+ [loomcd]
+ cdrom=1
+ path=C:\loom\
+ talkspeed=5
+ savepath=C:\loom\saves\
+
+ [monkey2]
+ path=C:\amiga_mi2\
+ music_driver=windows
+
+Följande nyckelord kan användas:
+
+ path string Sökvägen dit spelets datafiler ligger
+ autosave_period number Antal sekunder mellan autosparningar (standard: 300)
+ save_slot number Positionsnumret för spardata att ladda vid
+ uppstart.
+ savepath string Sökvägen där spelet lagrar sina spardata.
+ versioninfo string Versionen av ScummVM som användes för att
+ skapa konfigurationsfilen.
+
+ gameid string ID:n för ett spel. Användbart om du har
+ flera olika versioner av samma spel och vill
+ ha olika alias för dem. Se exempel.
+
+ description string Beskrivningen av spelet enligt launchern.
+
+ language string Bestäm språk (en, us, de, fr, it, pt, es,
+ jp, zh, kr, se, gb, hb, cz, ru)
+ speech_mute bool Ställ in till “true†för att stänga av röster
+ subtitles bool Ställ in till “true†för att visa undertexter
+ talkspeed number Textfördröjning i SCUMM-spel, eller texthastighet
+ i andra spel.
+
+ fullscreen bool Fullskärmsläge
+ aspect_ratio bool Aktivera korrektion av bildförhållande
+ disable_dithering bool Anti-gitter för EGA-spel
+ gfx_mode string Grafikläge (normalt, 2x, 3x, 2xsai,
+ super2xsai, supereagle, advmame2x, advmame3x,
+ hq2x, hq3x, tv2x, dotmatrix)
+
+ confirm_exit bool Be om bekräftelse från användaren innan avslutnig
+ (endast SDL-back-end).
+ console bool Öppna konsolfönstret (standard: på) (endast Windows)
+ cdrom number Nummer på CD-ROM enhet för använding av ljud.
+ Försök inte använda CD-ROM enheten om detta numret
+ är negativt.
+ joystick_num number Nummer på joystick-enhet att använda för input
+ music_driver string Musikenheten att använda.
+ opl_driver string AdLib (OPL)-emulatorn att använda.
+ output_rate number Uppspelningsvärdet i Hz. Lämpliga värden är
+ 11025, 22050 och 44100.
+ alsa_port string Port att använda för utmatning för ALSA-
+ musikdrivern.
+ music_volume number Musikvolym (0-255)
+ multi_midi bool Ställ in till “true†för att kombinera AdLib
+ och Native MIDI.
+ soundfont string SoundFont att använda för MIDI-uppspelning. (Stöds
+ endast av vissa MIDI-drivers.)
+ native_mt32 bool Ställ in till “true†för att deaktivera GM-
+ emulation och utgå ifrån att en verklig Roland
+ MT-32 finns tillhanda.
+ enable_gs bool Ställ in till “true†för att aktivera Roland GS-
+ specifika funktioner för att förbättra GM-
+ emulation. Om native_mt32 även ställts till â€trueâ€
+ kommer GS-enheten att välja en MT-32 karta för att
+ spela rätt instrument.
+ sfx_volume number Ljudeffektsvolym (0-255)
+ tempo number Musiktempo (50-200) (standard: 100)
+ speech_volume number Röstvolym (0-255)
+ midi_gain number MIDI gain (0-1000) (standard: 100) (Stöds endast
+ av vissa MIDI-drivers.)
+
+ copy_protection bool Aktiverar kopieringsskyddet för vissa spel i fall
+ där ScummVM automatiskt deaktiverar det.
+ demo_mode bool Öppna demon i Maniac Mansion
+ alt_intro bool Använd alternativt intro för CD-versionerna av
+ Beneath a Steel Sky och Flight of the Amazon
+ Queen
+
+ boot_param number Skicka det här numret till boot script
+
+Broken Sword II lägger till följande nyckelord:
+
+ gfx_details number Grafisk detalj (0-3)
+ music_mute bool Ställ in till “true†för att deaktivera musik
+ object_labels bool Ställ in till “true†för att aktivera etiketter för
+ föremål
+ reverse_stereo bool Ställ in till “true†för att ivertera
+ stereokanalerna
+ sfx_mute bool Ställ in till “true†för att deaktivera
+ ljudeffekter
+
+Flight of the Amazon Queen lägger till följande nyckelord:
+
+ music_mute bool Ställ in till “true†för att deaktivera musik
+ sfx_mute bool Ställ in till “true†för att deaktivera
+ ljudeffekter
+
+King's Quest VI Windows lägger till följande nyckelord:
+
+ windows_cursors bool Ställ in till “true†för att använda de svartvita
+ Windows-muspekarna istället för DOS-muspekarna.
+ Ställ in till â€false†för att använda de uppskalade
+ muspekarna som matchar resten av grafiken.
+
+Simon the Sorcerer 1 och 2 lägger till följande nyckelord:
+
+ music_mute bool Ställ in till “true†för att deaktivera musik
+ sfx_mute bool Ställ in till “true†för att deaktivera
+ ljudeffekter
+
+
+The Legend of Kyrandia lägger till följande nyckelord:
+
+ walkspeed int GÃ¥nghastighet (0-4)
+
+
+9.0) Kompilering:
+---- ------------
+För en uppdaterad överblick för hur man kompilerar ScummVM på diverse plattformar var god se vår Wiki, speciellt den här här sidan:
+ http://wiki.scummvm.org/index.php/Compiling_ScummVM
+
+Om du kompilerar för Windows, Linux eller Mac OS X behöver du SDL-1.2.2 eller senare (äldre versioner kan fungera, men stöds inte) och ett stött kompileringsprogram. Flera kompileringsprogram inklusive GCC, mingw och senare versioner av Microsoft Visual C++ stöds. Om du vill använda MP3-komprimerade CD-spår eller .SOU-filer måste du installera MAD-biblioteket; på samma sätt behöver du de nödvändiga biblioteken för Ogg Vorbis och FLAC-komprimerat ljud. För komprimerade spardata krävs zlib.
+
+Vissa delar av ScummVM, speciellt skalningsfilter, har optimerade versioner skrivna i assembler-kod. Om du vill använda dem måste du installera nasm-assemblern (se http://nasm.sf.net). Märk att vi för tillfället endast har optimerade versioner för x86 MMX och att de inte kan kompileras med andra processorer.
+
+På Win9x/NT/XP kan du definiera USE_WINDBG och lägga till WinDbg för att visa debug-meddelanden (se http://www.sysinternals.com/ntw2k/freeware/debugview.shtml).
+
+ GCC och MinGW32:
+ * Skriv "./configure"
+ * Skriv "make" (eller "gmake", eller "gnumake", beroende på vilken GNU
+ används av ditt system) så kompilerar ScummVM förhoppningsvis allt åt dig.
+ * För ytterligare information se:
+ http://wiki.scummvm.org/index.php/Compiling_ScummVM/GCC
+ eller
+ http://wiki.scummvm.org/index.php/Compiling_ScummVM/MinGW
+
+ Microsoft Visual C++ 8/9/10:
+ * Läs på hur man skapar projekt-filerna i "dists\msvc8",
+ "dists\msvc9" eller "dists\msvc10".
+ * Öppna den resulterade lösningsfilen.
+ * Ange sökvägen till de nödvändiga biblioteken och include-resurserna i
+ Tools|Options|Projects and Solutions|VC++ Directories.
+ * Programmet borde nu kompileras utan problem.
+ * För mer information se:
+ http://wiki.scummvm.org/index.php/Compiling_ScummVM/VS2005
+
+ Windows Mobile:
+ * Var god se:
+ http://wiki.scummvm.org/index.php/Compiling_ScummVM/Windows_CE
+
+ Debian GNU/Linux:
+ * Installera paketen 'build-essential', 'fakeroot', 'debhelper',
+ och 'libsdl1.2-dev' på ditt system.
+ * Installera de här paketen (valfria): 'libvorbis-dev' (för Ogg
+ Vorbis stöd), 'libasound2-dev' (för ALSA sequencer stöd),
+ 'libmad0-dev' (för MAD MP3 stöd), 'zlib1g-dev' (för stöd av kompresserad spardata).
+ * Kör 'make deb'.
+ * Kör sedan 'dpkg -i ../scummvm-cvs*deb', så är du klar.
+
+ Mac OS X:
+ * Se till att du har utvecklingsverktygen istallerade.
+ * SDL-utvecklingspaketet för OS X som finns tillgängligt på SLD:s hemsida
+ är INTE lämpligt. Du behöver istället en unix-artad kompilation av SDL.
+ Ett sätt att få tag i en sådan är att installera SDL via Fink
+ (http://fink.sf.net). Annars kan du kompilera SDL manuellt från källkoden
+ med unix build-systemet (configure && make).
+ * Skriv "./configure" i ScummVM-katalogen.
+ * Du kan nu skriva â€make†för att skapa en kommandorad-binary.
+ * För att få en version du kan köra från Finder, skriv “make bundle†vilket
+ skapar ScummVM.app (det här fungerar endast om du installerade SDL i /sw
+ (vilket sker om du använder Fink). Om du installerade SDL på annat vis måste
+ du redigera ports.mk).
+ * För ytterligare information se:
+ http://wiki.scummvm.org/index.php/Compiling_ScummVM/MacOS_X_Crosscompiling
+
+ AmigaOS 4 (Kors-kompilering med Cygwin):
+ * Se till att du har SDL installerad. Du kan även behöva
+ libogg, libvorbis, libvorbisfile, zlib, libmad.
+ * Skriv ./configure --host=ppc-amigaos
+ * Om du får ett felmeddelande om sdl-config, använd --with-sdl-prefix
+ parametern för att ställa in sökvägen.
+ * Kolla â€config.mk†filen och om allt ser ut att vara som det ska:
+ * Kör â€makeâ€.
+ * Att kors-kompilera med Linux kan vara lika enkelt.
+
+ iPhone:
+ * Var god se:
+ http://wiki.scummvm.org/index.php/Compiling_ScummVM/iPhone
+
+ Maemo:
+ * Installera Maemo SDK med 4.1.2 rootstrap
+ * Installera libmad, Tremor, FLAC från källkoden
+ * Kör â€ln -s backends/platform/maemo/debianâ€
+ * Uppdatera debian/changelog
+ * Kör â€sb2 dpkg-buildpackage –bâ€
+
+------------------------------------------------------------------------
+Lycka till och glada äventyr!
+ScummVM-teamet.
+http://www.scummvm.org/
+------------------------------------------------------------------------ \ No newline at end of file
diff --git a/doc/se/Snabbstart b/doc/se/Snabbstart
new file mode 100644
index 0000000000..bf37de5d2f
--- /dev/null
+++ b/doc/se/Snabbstart
@@ -0,0 +1,79 @@
+Det här dokumentet är en ofullständig översättning av den engelska README-filen. Det sistnämnda dokumentet innehåller mer information så om du inte kan hitta vad du behöver här (och pratar lite engelska), ta en titt i den engelska README-filen.
+
+För ytterligare information, kompatibilitetslistor, donationsdetaljer, den senaste programversionen, utvecklingsrapporter med mera, var god besök ScummVM:s hemsida på http://www.scummvm.org/
+
+Innehåll:
+---------
+1.0) Introduktion
+ * 1.1 Om ScummVM
+ * 1.2 Snabbstart
+2.0) Kontaktinformation
+ * 2.1 Att rapportera buggar
+
+1.0) Introduktion:
+---- -------------
+
+1.1) Om ScummVM:
+---- -----------
+ScummVM är ett program som gör det möjligt att spela vissa klassiska ”peka-och-klicka”-äventyrsspel, förutsatt att du redan har de nödvändiga datafilerna. Det finurliga i det hela är att ScummVM ersätter de ursprungliga programfilerna som följde med spelet, vilket låter dig spela dem på operativsystem de aldrig var designade för!
+
+Från början var programmet designat för att köra LucasArts SCUMM-spel, till exempel Maniac Mansion, Monkey Island, Day of the Tentacle och Sam and Max. SCUMM står för ”Script Creation Utility for Maniac Mansion”, och just Maniac Mansion var det första spelet där LucasArts använde det här spelsystemet. Mycket senare gav det namn till ScummVM (”VM” står för ”Virtual Machine”).
+
+Med tiden har stöd lagts till för många spel som inte använder SCUMM-systemet och ScummVM stöder nu även många av Sierras AGI- och SCI-spel (till exempel King’s Quest 1-6, Space Quest 1-5, ...), Discworld 1 och 2, Simon the Sorcerer 1 och 2, Beneath A Steel Sky, Lure of the Temptress, Broken Sword I och II, Flight of the Amazon Queen, Gobliiins 1-3, Legend of Kyrandia-serien, många av Humongous Entertainments barnspel (inklusive Freddi Fish och Putt Putt-spelen) med flera. Du kan se en fullständig lista med delaljer om vilka äventyr som stöds och hur väl de fungerar på kompatibilitetssidan. ScummVM förbättras konstant, så håll ett öga på listan.
+
+Bland systemen du kan använda för att spela dessa spel räknas vanliga persondatorer (Windows, Linux, Mac OS X, ...) spelkonsoler (Dreamcast, Nintendo DS & Wii, PS2, PSP, ...), smartphones (Android, iPhone, PocketPC, Symbian ...) med flera.
+
+Just nu är ScummVM fortfarande under utveckling. Var medveten om att trots att vi försöker se till att många spel kan avklaras utan att stöta på allvarliga buggar finns det ändå risk för krasher, och vi erbjuder inga garantier. Dock har många spel varit stödda av programmet väldigt länge och borde fungera utmärkt i vilken som helst av de senaste stabila versionerna. Du kan få en uppfattning om hur väl varje spel fungerar i ScummVM genom att titta på kompatibilitetssidan. Faktum är att ScummVM används kommersiellt för nyutgåvor av vissa spel på moderna plattformer. Alltså är många företag nöjda med mjukvarans kvalitet och hur väl programmet stöder spelen.
+
+Om du gillar ScummVM får du gärna donera till teamet med hjälp av PayPal-knappen på ScummVM:s hemsida. Donationer hjälper oss att köpa nödvändig utrustning för att göra utvecklingen av ScummVM lättare och snabbare. Om du inte kan donera kan du hjälpa till genom att bidra med uppdateringar!
+
+1.2) Snabbstart:
+---- -----------
+VIKTIGT: Den här korta guiden förutsätter att du använder ScummVM på svenska. ScummVM använder automatiskt samma språk som ditt operativsystem. Om du föredrar att använda ScummVM på engelska kommer du troligtvis föredra att använda guiden i den engelska README-filen.
+
+För de otåliga följer här instruktioner för att köra igång ScummVM i fem enkla steg.
+
+1. Ladda hem ScummVM från http://www.scummvm.org/downloads.php och installera programmet.
+
+2. Skapa en filkatalog på din hårddisk och kopiera spelets datafiler från dess ursprungliga plats till den nya katalogen. Upprepa det här steget för varje spel du vill spela (det är bättre att använda separata kataloger för vaje spel).
+
+3. Starta ScummVM.
+
+Om programmet nu visas på engelska istället för svenska, gör såhär för att byta språk:
+- Klicka på ”Options”.
+- Klicka på högerpilen i tab-raden och navigera till “Misc”-tabben.
+- Välj “Svenska” i “GUI Language”-menyn och klicka på “OK”.
+- Konfirmera meddelandet som visas, klicka på “Quit” för att avsluta ScummVM och starta sedan om programmet.
+
+Klicka på “Lägg till spel”, välj katalogen som innehåller datafilerna (var noga att välja själva filkatalogen - inte datafilerna inuti filkatalogen!) och klicka på ”Välj”.
+
+4. Nu visas en dialogruta där du kan ändra diverse inställningar om du vill (det borde vara nog att lämna inställningarna som de är från början). Konfirmera dialogrutan.
+
+5. Välj spelet du vill spela från listan och klicka på ”Starta”.
+
+ScummVM kommer ihåg alla spelen du lägger till, så om du avslutar ScummVM kommer spellistan vid nästa omstart innehålla alla spelen du hittills lagt till. Du kan därför hoppa direkt till steg 5, såtillvida inte du vill läga till fler spel.
+
+Tips: Om du vill lägga till flera spel på en gång, pröva att trycka och hålla ned skift-tangenten när du klickar på “Lägg till spel” – knappens text ändras nu till “Masstillägg” och om du klickar på den kommer du åter igen ombedjas att välja en filkatalog, men den här gången söker ScummVM automatiskt igenom alla underkataloger efter stödda spel.
+
+2.0) Kontakt:
+---- --------
+Det enklaste sättet att kontakta ScummVM-teamet är att skicka in bugg-rapporter (se 2.1) eller genom att använda vårt forum på http://forums.scummv.org. Du kan även skriva upp dig för och skicka e-post via vår sändlista (scummvm-devel) eller chatta med oss på IRC (#scummvm på irc.freenode.net) Vi ber dig att inte skicka önskemål på spel som inte stöds av ScummVM – läs avdelningen för vanliga frågor (FAQ) på våran hemsida först. Märk även att det officiella språket för vårt forum, vår sändlista och chatten är engelska och att inga andra språk borde användas där.
+
+2.1) Att rapportera buggar:
+---- ----------------------
+För att rapportera en bugg måste du skapa ett konto hos SourceForge och följa “Bug Tracker”-länken från våran hemsida. Var god se till att buggen kan reproduceras med säkerhet och att den fortfarande är aktiv i den senaste git/Daily build-versionen. Se även till att kontrollera att felet inte redan rapporterats genom att läsa listan av kända fel för spelet på våran kompatibilitetssida:
+
+ http://www.scummvm.org/compatibility_stable.php
+
+Var god rapportera inte buggar för spel som inte är möjliga att avklara enligt “Supported Games”-avdelningen, eller i kompatibilitetslistan. Vi vet redan att dessa spel är buggiga.
+
+Se till att bifoga följande information:
+ - ScummVM version (Var god testa med den senaste git/Daily Build-versionen)
+ - Detaljer om buggen, inklusive instruktioner för reproduktion
+ - Spelets språk (engelska, tyska, ...)
+ - Version av spelet (talversionen, diskettversionen, ...)
+ - Plattform och kompilator (Win32, Linux, FreeBSD, ...)
+ - Bifoga spardata om möjligt
+ - Om den här buggen dök upp alldeles nyligen, var god notera den senaste versionen av ScummVM där buggen inte fanns och den första versionen där buggen dök upp. På det här viset kan vi fixa problemet snabbare genom att se vilka förändringar som skedde mellan versionerna.
+
+Slutligen, var god rapportera varje bugg i enskilda rapporter; skicka inte flera buggar i en och samma rapport (annars blir det svårt att hålla reda på varje buggs individuella status). Tänk även på att alla buggrapporter måste vara skrivna på engelska.
diff --git a/engines/advancedDetector.h b/engines/advancedDetector.h
index 9a6b5e4ef7..0cec039b5e 100644
--- a/engines/advancedDetector.h
+++ b/engines/advancedDetector.h
@@ -26,6 +26,8 @@
#include "engines/metaengine.h"
#include "engines/engine.h"
+#include "common/gui_options.h" // FIXME: Temporary hack?
+
namespace Common {
class Error;
class FSList;
@@ -101,7 +103,7 @@ typedef Common::Array<const ADGameDescription *> ADGameDescList;
* 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, GUIO1(GUIO_NONE) }
+ { NULL, NULL, { { NULL, 0, NULL, 0 } }, Common::UNK_LANG, Common::kPlatformUnknown, ADGF_NO_FLAGS, GUIO0() }
struct ADFileBasedFallback {
/**
@@ -169,7 +171,13 @@ protected:
/**
* Name of single gameid (optional).
*
- * @todo Properly explain this -- what does it do?
+ * Used to override gameid.
+ * This is a recommended setting to prevent global gameid pollution.
+ * With this option set, the gameid effectively turns into engineid.
+ *
+ * FIXME: This field actually removes a feature (gameid) in order to
+ * address a more generic problem. We should find a better way to
+ * disambiguate gameids.
*/
const char *_singleid;
diff --git a/engines/agi/agi.cpp b/engines/agi/agi.cpp
index 4ed606c3ba..e9c9645768 100644
--- a/engines/agi/agi.cpp
+++ b/engines/agi/agi.cpp
@@ -250,19 +250,7 @@ void AgiEngine::processEvents() {
// Not a special key, so get the ASCII code for it
key = event.kbd.ascii;
- // Function isalpha is defined in <ctype.h> so the following applies to it:
- //
- // The C Programming Language Standard states:
- // The header <ctype.h> declares several functions useful for classifying
- // and mapping characters. In all cases the argument is an int, the value
- // of which shall be representable as an unsigned char or shall equal the
- // value of the macro EOF. If the argument has any other value, the
- // behavior is undefined.
- //
- // For a concrete example (e.g. in Microsoft Visual Studio 2003):
- // When used with a debug CRT library, isalpha will display a CRT assert
- // if passed a parameter that isn't EOF or in the range of 0 through 0xFF.
- if (key >= 0 && key <= 0xFF && isalpha(key)) {
+ if (Common::isAlpha(key)) {
// Key is A-Z.
// Map Ctrl-A to 1, Ctrl-B to 2, etc.
if (event.kbd.flags & Common::KBD_CTRL) {
diff --git a/engines/agi/agi.h b/engines/agi/agi.h
index 6bb3beec78..55b4805022 100644
--- a/engines/agi/agi.h
+++ b/engines/agi/agi.h
@@ -28,6 +28,7 @@
#include "common/util.h"
#include "common/file.h"
#include "common/rect.h"
+#include "common/rendermode.h"
#include "common/stack.h"
#include "common/system.h"
@@ -631,7 +632,7 @@ struct AgiGame {
AgiLogic *_curLogic;
// words
- Common::Array<AgiWord*> words[26];
+ Common::Array<AgiWord *> words[26];
// view table
VtEntry viewTable[MAX_VIEWTABLE];
@@ -809,8 +810,6 @@ public:
virtual void replayImageStackCall(uint8 type, int16 p1, int16 p2, int16 p3,
int16 p4, int16 p5, int16 p6, int16 p7) = 0;
virtual void releaseImageStack() = 0;
- virtual int saveGame(const Common::String &fileName, const Common::String &saveName) = 0;
- virtual int loadGame(const Common::String &fileName, bool checkId = true) = 0;
int _soundemu;
diff --git a/engines/agi/checks.cpp b/engines/agi/checks.cpp
index c3b31f6ba9..624476509e 100644
--- a/engines/agi/checks.cpp
+++ b/engines/agi/checks.cpp
@@ -113,6 +113,22 @@ int AgiEngine::checkPriority(VtEntry *v) {
water = 1;
+ // Check if any picture is loaded before checking for priority below.
+ // If no picture has been loaded, the priority buffer won't be initialized,
+ // thus the check below will always fail. This case causes an infinite loop
+ // in the fanmade game Nick's Quest (bug #3451122), as the game attempts to
+ // draw a sprite (view 4, floating Nick) before it loads any picture. This
+ // causes the checks below to always fail, and the engine keeps readjusting
+ // the sprite's position in fixPosition() forever, as there is no valid
+ // position to place it (the default visual and priority screen is set to
+ // zero, i.e. unconditional black). To remedy this situation, we always
+ // return true here if no picture has been loaded and no priority screen
+ // has been set up.
+ if (!_game._vm->_picture->isPictureLoaded()) {
+ warning("checkPriority: no picture loaded");
+ return pass;
+ }
+
p0 = &_game.sbuf16c[v->xPos + v->yPos * _WIDTH];
for (i = 0; i < v->xSize; i++, p0++) {
diff --git a/engines/agi/cycle.cpp b/engines/agi/cycle.cpp
index 9cbab1f3c4..5daadbd1df 100644
--- a/engines/agi/cycle.cpp
+++ b/engines/agi/cycle.cpp
@@ -200,10 +200,11 @@ int AgiEngine::mainCycle() {
// vars in every interpreter cycle.
//
// We run AGIMOUSE always as a side effect
- if (getFeatures() & GF_AGIMOUSE || true) {
+ //if (getFeatures() & GF_AGIMOUSE) {
_game.vars[28] = _mouse.x / 2;
_game.vars[29] = _mouse.y;
- }
+ //}
+
if (key == KEY_PRIORITY) {
_sprites->eraseBoth();
_debug.priority = !_debug.priority;
@@ -247,44 +248,47 @@ int AgiEngine::mainCycle() {
if (kascii)
setvar(vKey, kascii);
-process_key:
-
- switch (_game.inputMode) {
- case INPUT_NORMAL:
- if (!handleController(key)) {
- if (key == 0 || !_game.inputEnabled)
- break;
- handleKeys(key);
-
- // if ESC pressed, activate menu before
- // accept.input from the interpreter cycle
- // sets the input mode to normal again
- // (closes: #540856)
- if (key == KEY_ESCAPE) {
- key = 0;
- goto process_key;
+ bool restartProcessKey;
+ do {
+ restartProcessKey = false;
+
+ switch (_game.inputMode) {
+ case INPUT_NORMAL:
+ if (!handleController(key)) {
+ if (key == 0 || !_game.inputEnabled)
+ break;
+ handleKeys(key);
+
+ // if ESC pressed, activate menu before
+ // accept.input from the interpreter cycle
+ // sets the input mode to normal again
+ // (closes: #540856)
+ if (key == KEY_ESCAPE) {
+ key = 0;
+ restartProcessKey = true;
+ }
+
+ // commented out to close Sarien bug #438872
+ //if (key)
+ // _game.keypress = key;
}
-
- // commented out to close Sarien bug #438872
- //if (key)
- // _game.keypress = key;
+ break;
+ case INPUT_GETSTRING:
+ handleController(key);
+ handleGetstring(key);
+ setvar(vKey, 0); // clear ENTER key
+ break;
+ case INPUT_MENU:
+ _menu->keyhandler(key);
+ _gfx->doUpdate();
+ return false;
+ case INPUT_NONE:
+ handleController(key);
+ if (key)
+ _game.keypress = key;
+ break;
}
- break;
- case INPUT_GETSTRING:
- handleController(key);
- handleGetstring(key);
- setvar(vKey, 0); // clear ENTER key
- break;
- case INPUT_MENU:
- _menu->keyhandler(key);
- _gfx->doUpdate();
- return false;
- case INPUT_NONE:
- handleController(key);
- if (key)
- _game.keypress = key;
- break;
- }
+ } while (restartProcessKey);
_gfx->doUpdate();
if (_game.msgBoxTicks > 0)
@@ -315,7 +319,7 @@ int AgiEngine::playGame() {
_game.lineUserInput = 22;
// We run AGIMOUSE always as a side effect
- if (getFeatures() & GF_AGIMOUSE || true)
+ //if (getFeatures() & GF_AGIMOUSE)
debug(1, "Using AGI Mouse 1.0 protocol");
if (getFeatures() & GF_AGIPAL)
diff --git a/engines/agi/detection_tables.h b/engines/agi/detection_tables.h
index 081cb39668..ab0e9a1fe4 100644
--- a/engines/agi/detection_tables.h
+++ b/engines/agi/detection_tables.h
@@ -30,7 +30,7 @@ namespace Agi {
lang, \
platform, \
ADGF_NO_FLAGS, \
- GUIO1(GUIO_NONE) \
+ GUIO0() \
}, \
gid, \
interp, \
@@ -46,7 +46,7 @@ namespace Agi {
lang, \
platform, \
ADGF_USEEXTRAASTITLE, \
- GUIO1(GUIO_NONE) \
+ GUIO0() \
}, \
gid, \
interp, \
@@ -130,7 +130,7 @@ static const AGIGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformPC,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO0()
},
GID_BC,
GType_V1,
@@ -151,7 +151,7 @@ static const AGIGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformPC,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO0()
},
GID_BC,
GType_V1,
@@ -172,7 +172,7 @@ static const AGIGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformPC,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO0()
},
GID_BC,
GType_V1,
@@ -252,7 +252,7 @@ static const AGIGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformMacintosh,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO0()
},
GID_GOLDRUSH,
GType_V3,
@@ -570,7 +570,7 @@ static const AGIGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformAmiga,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO0()
},
GID_SQ2,
GType_V2,
@@ -859,7 +859,7 @@ static const AGIGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformPC,
ADGF_USEEXTRAASTITLE,
- GUIO1(GUIO_NONE)
+ GUIO0()
},
GID_FANMADE,
GType_V3,
@@ -887,7 +887,7 @@ static AGIGameDescription g_fallbackDesc = {
Common::UNK_LANG,
Common::kPlatformPC,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO0()
},
GID_FANMADE,
GType_V2,
diff --git a/engines/agi/graphics.cpp b/engines/agi/graphics.cpp
index 074e5570d5..4bb3877f7d 100644
--- a/engines/agi/graphics.cpp
+++ b/engines/agi/graphics.cpp
@@ -1083,7 +1083,7 @@ void GfxMgr::putPixelsA(int x, int y, int n, uint8 *p) {
// Choose the correct screen to read from. If AGI256 or AGI256-2 is used and we're not trying to show the priority information,
// then choose the 256 color screen, otherwise choose the 16 color screen (Which also has the priority information).
- p += _vm->getFeatures() & (GF_AGI256 | GF_AGI256_2) && !_vm->_debug.priority ? FROM_SBUF16_TO_SBUF256_OFFSET : 0;
+ p += ((_vm->getFeatures() & (GF_AGI256 | GF_AGI256_2)) && !_vm->_debug.priority) ? FROM_SBUF16_TO_SBUF256_OFFSET : 0;
if (_vm->_renderMode == Common::kRenderCGA) {
for (x *= 2; n--; p++, x += 2) {
@@ -1091,7 +1091,7 @@ void GfxMgr::putPixelsA(int x, int y, int n, uint8 *p) {
*(uint16 *)&_agiScreen[x + y * GFX_WIDTH] = (q >> rShift) & 0x0f0f;
}
} else {
- const uint16 mask = _vm->getFeatures() & (GF_AGI256 | GF_AGI256_2) && !_vm->_debug.priority ? 0xffff : 0x0f0f;
+ const uint16 mask = ((_vm->getFeatures() & (GF_AGI256 | GF_AGI256_2)) && !_vm->_debug.priority) ? 0xffff : 0x0f0f;
for (x *= 2; n--; p++, x += 2) {
register uint16 q = ((uint16)*p << 8) | *p;
*(uint16 *)&_agiScreen[x + y * GFX_WIDTH] = (q >> rShift) & mask;
diff --git a/engines/agi/menu.cpp b/engines/agi/menu.cpp
index b504cd3e30..cac1701596 100644
--- a/engines/agi/menu.cpp
+++ b/engines/agi/menu.cpp
@@ -279,6 +279,7 @@ bool Menu::keyhandler(int key) {
static int clockVal;
static int menuActive = false;
static int buttonUsed = 0;
+ bool exitMenu = false;
if (!_vm->getflag(fMenusWork) && !(_vm->getFeatures() & GF_MENUS))
return false;
@@ -288,9 +289,8 @@ bool Menu::keyhandler(int key) {
_vm->_game.clockEnabled = false;
drawMenuBar();
}
- //
+
// Mouse handling
- //
if (_vm->_mouse.button) {
int hmenu, vmenu;
@@ -372,83 +372,84 @@ bool Menu::keyhandler(int key) {
debugC(6, kDebugLevelMenu | kDebugLevelInput, "event %d registered", d->event);
_vm->_game.controllerOccured[d->event] = true;
_vm->_menuSelected = true;
-
- goto exit_menu;
+ break;
}
}
}
- goto exit_menu;
+ exitMenu = true;
}
}
- if (!menuActive) {
- if (_hCurMenu >= 0) {
- drawMenuHilite(_hCurMenu);
- drawMenuOption(_hCurMenu);
- if (!buttonUsed && _vCurMenu >= 0)
- drawMenuOptionHilite(_hCurMenu, _vCurMenu);
+ if (!exitMenu) {
+ if (!menuActive) {
+ if (_hCurMenu >= 0) {
+ drawMenuHilite(_hCurMenu);
+ drawMenuOption(_hCurMenu);
+ if (!buttonUsed && _vCurMenu >= 0)
+ drawMenuOptionHilite(_hCurMenu, _vCurMenu);
+ }
+ menuActive = true;
}
- menuActive = true;
- }
- switch (key) {
- case KEY_ESCAPE:
- debugC(6, kDebugLevelMenu | kDebugLevelInput, "KEY_ESCAPE");
- goto exit_menu;
- case KEY_ENTER:
- {
- debugC(6, kDebugLevelMenu | kDebugLevelInput, "KEY_ENTER");
- AgiMenuOption* d = getMenuOption(_hCurMenu, _vCurMenu);
-
- if (d->enabled) {
- debugC(6, kDebugLevelMenu | kDebugLevelInput, "event %d registered", d->event);
- _vm->_game.controllerOccured[d->event] = true;
- _vm->_menuSelected = true;
- goto exit_menu;
+ switch (key) {
+ case KEY_ESCAPE:
+ debugC(6, kDebugLevelMenu | kDebugLevelInput, "KEY_ESCAPE");
+ exitMenu = true;
+ break;
+ case KEY_ENTER:
+ {
+ debugC(6, kDebugLevelMenu | kDebugLevelInput, "KEY_ENTER");
+ AgiMenuOption* d = getMenuOption(_hCurMenu, _vCurMenu);
+
+ if (d->enabled) {
+ debugC(6, kDebugLevelMenu | kDebugLevelInput, "event %d registered", d->event);
+ _vm->_game.controllerOccured[d->event] = true;
+ _vm->_menuSelected = true;
+ exitMenu = true;
+ }
+ break;
}
- break;
- }
- case KEY_DOWN:
- case KEY_UP:
- _vCurMenu += key == KEY_DOWN ? 1 : -1;
+ case KEY_DOWN:
+ case KEY_UP:
+ _vCurMenu += key == KEY_DOWN ? 1 : -1;
- if (_vCurMenu < 0)
- _vCurMenu = _vMaxMenu[_hCurMenu];
- if (_vCurMenu > _vMaxMenu[_hCurMenu])
- _vCurMenu = 0;
+ if (_vCurMenu < 0)
+ _vCurMenu = _vMaxMenu[_hCurMenu];
+ if (_vCurMenu > _vMaxMenu[_hCurMenu])
+ _vCurMenu = 0;
- drawMenuOption(_hCurMenu);
- drawMenuOptionHilite(_hCurMenu, _vCurMenu);
- break;
- case KEY_RIGHT:
- case KEY_LEFT:
- _hCurMenu += key == KEY_RIGHT ? 1 : -1;
-
- if (_hCurMenu < 0)
- _hCurMenu = _hMaxMenu;
- if (_hCurMenu > _hMaxMenu)
- _hCurMenu = 0;
-
- _vCurMenu = 0;
- newMenuSelected(_hCurMenu);
- drawMenuOptionHilite(_hCurMenu, _vCurMenu);
- break;
- }
+ drawMenuOption(_hCurMenu);
+ drawMenuOptionHilite(_hCurMenu, _vCurMenu);
+ break;
+ case KEY_RIGHT:
+ case KEY_LEFT:
+ _hCurMenu += key == KEY_RIGHT ? 1 : -1;
- return true;
+ if (_hCurMenu < 0)
+ _hCurMenu = _hMaxMenu;
+ if (_hCurMenu > _hMaxMenu)
+ _hCurMenu = 0;
-exit_menu:
- buttonUsed = 0;
- _picture->showPic();
- _vm->writeStatus();
+ _vCurMenu = 0;
+ newMenuSelected(_hCurMenu);
+ drawMenuOptionHilite(_hCurMenu, _vCurMenu);
+ break;
+ }
+ }
- _vm->setvar(vKey, 0);
- _vm->_game.keypress = 0;
- _vm->_game.clockEnabled = clockVal;
- _vm->oldInputMode();
+ if (exitMenu) {
+ buttonUsed = 0;
+ _picture->showPic();
+ _vm->writeStatus();
- debugC(3, kDebugLevelMenu, "exit_menu: input mode reset to %d", _vm->_game.inputMode);
- menuActive = false;
+ _vm->setvar(vKey, 0);
+ _vm->_game.keypress = 0;
+ _vm->_game.clockEnabled = clockVal;
+ _vm->oldInputMode();
+
+ debugC(3, kDebugLevelMenu, "exit_menu: input mode reset to %d", _vm->_game.inputMode);
+ menuActive = false;
+ }
return true;
}
diff --git a/engines/agi/menu.h b/engines/agi/menu.h
index e659c71fab..1d5828d78a 100644
--- a/engines/agi/menu.h
+++ b/engines/agi/menu.h
@@ -33,8 +33,8 @@ namespace Agi {
struct AgiMenu;
struct AgiMenuOption;
-typedef Common::List<AgiMenu*> MenuList;
-typedef Common::List<AgiMenuOption*> MenuOptionList;
+typedef Common::List<AgiMenu *> MenuList;
+typedef Common::List<AgiMenuOption *> MenuOptionList;
class GfxMgr;
class PictureMgr;
diff --git a/engines/agi/objects.cpp b/engines/agi/objects.cpp
index 94eef92579..447cff2a3f 100644
--- a/engines/agi/objects.cpp
+++ b/engines/agi/objects.cpp
@@ -52,7 +52,7 @@ int AgiEngine::decodeObjects(uint8 *mem, uint32 flen) {
// alloc memory for object list
// byte 3 = number of animated objects. this is ignored.. ??
- if (READ_LE_UINT16(mem) / padsize >= 256) {
+ if (READ_LE_UINT16(mem) / padsize > 256) {
// die with no error! AGDS game needs not to die to work!! :(
return errOK;
}
diff --git a/engines/agi/op_cmd.cpp b/engines/agi/op_cmd.cpp
index 72f60e2516..7e04328a67 100644
--- a/engines/agi/op_cmd.cpp
+++ b/engines/agi/op_cmd.cpp
@@ -1622,15 +1622,15 @@ void cmdPrintAtV(AgiGame *state, uint8 *p) {
void cmdPushScript(AgiGame *state, uint8 *p) {
// We run AGIMOUSE always as a side effect
- if (getFeatures() & GF_AGIMOUSE || true) {
+ //if (getFeatures() & GF_AGIMOUSE || true) {
state->vars[27] = state->_vm->_mouse.button;
state->vars[28] = state->_vm->_mouse.x / 2;
state->vars[29] = state->_vm->_mouse.y;
- } else {
+ /*} else {
if (getVersion() >= 0x2915) {
debug(0, "push.script");
}
- }
+ }*/
}
void cmdSetPriBase(AgiGame *state, uint8 *p) {
@@ -1702,6 +1702,9 @@ void cmdSetItemView(AgiGame *state, uint8 *p) {
void cmdCallV1(AgiGame *state, uint8 *p) {
state->_vm->agiLoadResource(rLOGIC, p0);
+ // FIXME: The following instruction looks incomplete.
+ // Maybe something is meant to be assigned to, or read from,
+ // the logic_list entry?
state->logic_list[++state->max_logics];
_v[13] = 1;
}
diff --git a/engines/agi/opcodes.cpp b/engines/agi/opcodes.cpp
index d1baab93e1..29fb860635 100644
--- a/engines/agi/opcodes.cpp
+++ b/engines/agi/opcodes.cpp
@@ -360,7 +360,7 @@ AgiInstruction insV2[] = {
void AgiEngine::setupOpcodes() {
if (getVersion() >= 0x2000) {
- for (int i = 0; i <= ARRAYSIZE(insV2Test); ++i)
+ for (int i = 0; i < ARRAYSIZE(insV2Test); ++i)
_agiCondCommands[i] = insV2Test[i].func;
for (int i = 0; i < ARRAYSIZE(insV2); ++i)
_agiCommands[i] = insV2[i].func;
@@ -368,7 +368,7 @@ void AgiEngine::setupOpcodes() {
logicNamesTest = insV2Test;
logicNamesCmd = insV2;
} else {
- for (int i = 0; i <= ARRAYSIZE(insV1Test); ++i)
+ for (int i = 0; i < ARRAYSIZE(insV1Test); ++i)
_agiCondCommands[i] = insV1Test[i].func;
for (int i = 0; i < ARRAYSIZE(insV1); ++i)
_agiCommands[i] = insV1[i].func;
diff --git a/engines/agi/picture.h b/engines/agi/picture.h
index f2a6586b93..45a95202e5 100644
--- a/engines/agi/picture.h
+++ b/engines/agi/picture.h
@@ -115,6 +115,8 @@ public:
putVirtPixel(x, y);
}
+ bool isPictureLoaded() { return _data != NULL; }
+
private:
uint8 *_data;
uint32 _flen;
diff --git a/engines/agi/preagi_mickey.h b/engines/agi/preagi_mickey.h
index 673839a592..18b0593d78 100644
--- a/engines/agi/preagi_mickey.h
+++ b/engines/agi/preagi_mickey.h
@@ -704,7 +704,7 @@ protected:
void readOfsData(int, int, uint8*, long);
bool chooseY_N(int, bool);
int choose1to9(int);
- void printStr(char*);
+ void printStr(char *);
void printLine(const char*);
void printExeStr(int);
void printExeMsg(int);
diff --git a/engines/agi/preagi_troll.cpp b/engines/agi/preagi_troll.cpp
index 50b2945383..b7d2801076 100644
--- a/engines/agi/preagi_troll.cpp
+++ b/engines/agi/preagi_troll.cpp
@@ -455,7 +455,7 @@ int TrollEngine::drawRoom(char *menu) {
_gfx->doUpdate();
char tmp[10];
- strncat(menu, (char*)_gameData + _locMessagesIdx[_currentRoom], 39);
+ strncat(menu, (char *)_gameData + _locMessagesIdx[_currentRoom], 39);
for (int i = 0; i < 3; i++) {
if (_roomDescs[_roomPicture - 1].options[i]) {
@@ -725,7 +725,7 @@ void TrollEngine::fillOffsets() {
void TrollEngine::init() {
_picture->setPictureVersion(AGIPIC_V15);
- //SetScreenPar(320, 200, (char*)ibm_fontdata);
+ //SetScreenPar(320, 200, (char *)ibm_fontdata);
const int gaps[] = { 0x3A40, 0x4600, 0x4800, 0x5800, 0x5a00, 0x6a00,
0x6c00, 0x7400, 0x7600, 0x7c00, 0x7e00, 0x8e00,
diff --git a/engines/agi/preagi_winnie.cpp b/engines/agi/preagi_winnie.cpp
index cc5c2470ae..53863a8c7e 100644
--- a/engines/agi/preagi_winnie.cpp
+++ b/engines/agi/preagi_winnie.cpp
@@ -1006,36 +1006,47 @@ void WinnieEngine::gameLoop() {
WTP_ROOM_HDR hdr;
uint8 *roomdata = (uint8 *)malloc(4096);
int iBlock;
+ uint8 decodePhase = 0;
-phase0:
- if (!_gameStateWinnie.nObjMiss && (_room == IDI_WTP_ROOM_PICNIC))
- _room = IDI_WTP_ROOM_PARTY;
+ while (!shouldQuit()) {
+ if (decodePhase == 0) {
+ if (!_gameStateWinnie.nObjMiss && (_room == IDI_WTP_ROOM_PICNIC))
+ _room = IDI_WTP_ROOM_PARTY;
- readRoom(_room, roomdata, hdr);
- drawRoomPic();
- _gfx->doUpdate();
+ readRoom(_room, roomdata, hdr);
+ drawRoomPic();
+ _gfx->doUpdate();
+ decodePhase = 1;
+ }
-phase1:
- if (getObjInRoom(_room)) {
- printObjStr(getObjInRoom(_room), IDI_WTP_OBJ_DESC);
- getSelection(kSelAnyKey);
- }
+ if (decodePhase == 1) {
+ if (getObjInRoom(_room)) {
+ printObjStr(getObjInRoom(_room), IDI_WTP_OBJ_DESC);
+ getSelection(kSelAnyKey);
+ }
+ decodePhase = 2;
+ }
-phase2:
- for (iBlock = 0; iBlock < IDI_WTP_MAX_BLOCK; iBlock++) {
- if (parser(hdr.ofsDesc[iBlock] - _roomOffset, iBlock, roomdata) == IDI_WTP_PAR_BACK)
- goto phase1;
- }
+ if (decodePhase == 2) {
+ for (iBlock = 0; iBlock < IDI_WTP_MAX_BLOCK; iBlock++) {
+ if (parser(hdr.ofsDesc[iBlock] - _roomOffset, iBlock, roomdata) == IDI_WTP_PAR_BACK) {
+ decodePhase = 1;
+ break;
+ }
+ }
+ if (decodePhase == 2)
+ decodePhase = 3;
+ }
- while (!shouldQuit()) {
- for (iBlock = 0; iBlock < IDI_WTP_MAX_BLOCK; iBlock++) {
- switch (parser(hdr.ofsBlock[iBlock] - _roomOffset, iBlock, roomdata)) {
- case IDI_WTP_PAR_GOTO:
- goto phase0;
- break;
- case IDI_WTP_PAR_BACK:
- goto phase2;
- break;
+ if (decodePhase == 3) {
+ for (iBlock = 0; iBlock < IDI_WTP_MAX_BLOCK; iBlock++) {
+ if (parser(hdr.ofsBlock[iBlock] - _roomOffset, iBlock, roomdata) == IDI_WTP_PAR_GOTO) {
+ decodePhase = 0;
+ break;
+ } else if (parser(hdr.ofsBlock[iBlock] - _roomOffset, iBlock, roomdata) == IDI_WTP_PAR_BACK) {
+ decodePhase = 2;
+ break;
+ }
}
}
}
diff --git a/engines/agi/predictive.cpp b/engines/agi/predictive.cpp
index edfe83b1cb..4bb378934d 100644
--- a/engines/agi/predictive.cpp
+++ b/engines/agi/predictive.cpp
@@ -96,8 +96,6 @@ void bringWordtoTop(char *str, int wordnum) {
}
bool AgiEngine::predictiveDialog() {
- int key = 0, active = -1, lastactive = 0;
- bool rc = false;
uint8 x;
int y;
int bx[17], by[17];
@@ -105,7 +103,6 @@ bool AgiEngine::predictiveDialog() {
char temp[MAXWORDLEN + 1], repeatcount[MAXWORDLEN];
AgiBlock tmpwindow;
bool navigationwithkeys = false;
- bool processkey;
const char *buttonStr[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9", "0" };
const char *buttons[] = {
@@ -115,7 +112,7 @@ bool AgiEngine::predictiveDialog() {
"(#)next", "add",
"<",
"Cancel", "OK",
- "Pre", "(0) ", NULL
+ "(*)Pre", "(0) ", NULL
};
const int colors[] = {
15, 0, 15, 0, 15, 0,
@@ -189,8 +186,11 @@ bool AgiEngine::predictiveDialog() {
int mode = kModePre;
bool needRefresh = true;
-
- while (!shouldQuit()) {
+ int active = -1, lastactive = 0;
+ bool rc = false;
+ bool closeDialog = false;
+ bool enterPredictiveResult = false;
+ while (!closeDialog && !shouldQuit()) {
if (needRefresh) {
for (int i = 0; buttons[i]; i++) {
int color1 = colors[i * 2];
@@ -234,9 +234,10 @@ bool AgiEngine::predictiveDialog() {
_gfx->doUpdate();
}
+ bool processkey = false;
+
pollTimer();
- key = doPollKeyboard();
- processkey = false;
+ int key = doPollKeyboard();
switch (key) {
case KEY_ENTER:
if (navigationwithkeys) {
@@ -251,7 +252,8 @@ bool AgiEngine::predictiveDialog() {
break;
case KEY_ESCAPE:
rc = false;
- goto getout;
+ closeDialog = true;
+ break;
case BUTTON_LEFT:
navigationwithkeys = false;
for (int i = 0; buttons[i]; i++) {
@@ -361,7 +363,7 @@ bool AgiEngine::predictiveDialog() {
break;
}
- if (processkey) {
+ if (processkey && !closeDialog) {
if (active >= 0) {
needRefresh = true;
lastactive = active;
@@ -442,7 +444,8 @@ bool AgiEngine::predictiveDialog() {
if (mode == kModePre && _predictiveDictActLine && numMatchingWords > 1 && _wordNumber != 0)
bringWordtoTop(_predictiveDictActLine, _wordNumber);
rc = true;
- goto press;
+ enterPredictiveResult = true;
+ closeDialog = true;
} else if (active == 14) { // Mode
mode++;
if (mode > kModeAbc)
@@ -455,18 +458,20 @@ bool AgiEngine::predictiveDialog() {
_currentCode.clear();
_currentWord.clear();
memset(repeatcount, 0, sizeof(repeatcount));
+ _predictiveDictActLine = NULL;
} else {
- goto press;
+ enterPredictiveResult = true;
+ closeDialog = true;
}
}
}
}
- press:
- Common::strlcpy(_predictiveResult, prefix.c_str(), sizeof(_predictiveResult));
- Common::strlcat(_predictiveResult, _currentWord.c_str(), sizeof(_predictiveResult));
+ if (enterPredictiveResult) {
+ Common::strlcpy(_predictiveResult, prefix.c_str(), sizeof(_predictiveResult));
+ Common::strlcat(_predictiveResult, _currentWord.c_str(), sizeof(_predictiveResult));
+ }
- getout:
// if another window was shown, bring it up again
if (!tmpwindow.active)
closeWindow();
@@ -561,37 +566,50 @@ bool AgiEngine::matchWord() {
if (_currentCode.size() > MAXWORDLEN)
return false;
- // Perform a binary search on the dictionary to find the first
- // entry that has _currentCode as a prefix.
+ // The entries in the dictionary consist of a code, a space, and then
+ // a space-separated list of words matching this code.
+ // To exactly match a code, we therefore match the code plus the trailing
+ // space in the dictionary.
+ Common::String code = _currentCode + " ";
+
+ // Perform a binary search on the dictionary.
int hi = _predictiveDictLineCount - 1;
int lo = 0;
int line = 0;
- while (lo < hi) {
+ while (lo <= hi) {
line = (lo + hi) / 2;
- int cmpVal = strncmp(_predictiveDictLine[line], _currentCode.c_str(), _currentCode.size());
+ int cmpVal = strncmp(_predictiveDictLine[line], code.c_str(), code.size());
if (cmpVal > 0)
hi = line - 1;
else if (cmpVal < 0)
lo = line + 1;
else {
- hi = line;
break;
}
}
+ bool partial = hi < lo;
+ if (partial) {
+ // Didn't find an exact match, but 'lo' now points to the first entry
+ // lexicographically greater than the current code, so that will
+ // be the first entry with the current code as a prefix, if it exists.
+ line = lo;
+ _predictiveDictActLine = NULL;
+ } else {
+ _predictiveDictActLine = _predictiveDictLine[line];
+ }
+
_currentWord.clear();
_wordNumber = 0;
if (0 == strncmp(_predictiveDictLine[line], _currentCode.c_str(), _currentCode.size())) {
- _predictiveDictActLine = _predictiveDictLine[line];
char tmp[MAXLINELEN];
- strncpy(tmp, _predictiveDictActLine, MAXLINELEN);
+ strncpy(tmp, _predictiveDictLine[line], MAXLINELEN);
tmp[MAXLINELEN - 1] = 0;
char *tok = strtok(tmp, " ");
tok = strtok(NULL, " ");
_currentWord = Common::String(tok, _currentCode.size());
return true;
} else {
- _predictiveDictActLine = NULL;
return false;
}
}
diff --git a/engines/agi/saveload.cpp b/engines/agi/saveload.cpp
index 3cebbf50c8..0ef6230374 100644
--- a/engines/agi/saveload.cpp
+++ b/engines/agi/saveload.cpp
@@ -221,8 +221,8 @@ int AgiEngine::saveGame(const Common::String &fileName, const Common::String &de
// Save image stack
- for (i = 0; i < _imageStack.size(); i++) {
- ImageStackElement ise = _imageStack[i];
+ for (Common::Stack<ImageStackElement>::size_type j = 0; j < _imageStack.size(); ++j) {
+ const ImageStackElement &ise = _imageStack[j];
out->writeByte(ise.type);
out->writeSint16BE(ise.parm1);
out->writeSint16BE(ise.parm2);
@@ -300,7 +300,7 @@ int AgiEngine::loadGame(const Common::String &fileName, bool checkId) {
_game.state = (State)in->readByte();
in->read(loadId, 8);
- if (strcmp(loadId, _game.id) && checkId) {
+ if (strcmp(loadId, _game.id) != 0 && checkId) {
delete in;
warning("This save seems to be from a different AGI game (save from %s, running %s), not loaded", loadId, _game.id);
return errBadFileOpen;
@@ -331,7 +331,7 @@ int AgiEngine::loadGame(const Common::String &fileName, bool checkId) {
warning("Since your game was only detected via the fallback detector, there is no possibility to assure the save is compatible with your game version");
debug(0, "The game used for saving is \"%s\".", md5);
- } else if (strcmp(md5, getGameMD5())) {
+ } else if (strcmp(md5, getGameMD5()) != 0) {
warning("Game was saved with different gamedata - you may encounter problems");
debug(0, "Your game is \"%s\" and save is \"%s\".", getGameMD5(), md5);
@@ -609,8 +609,8 @@ int AgiEngine::selectSlot() {
AllowSyntheticEvents on(this);
int oldFirstSlot = _firstSlot + 1;
int oldActive = active + 1;
-
- while (!(shouldQuit() || _restartGame)) {
+ bool exitSelectSlot = false;
+ while (!exitSelectSlot && !(shouldQuit() || _restartGame)) {
int sbPos = 0;
// Use the extreme scrollbar positions only if the extreme
@@ -661,119 +661,122 @@ int AgiEngine::selectSlot() {
// out of the dead loop
if (getflag(fRestoreJustRan)) {
rc = -2;
- goto getout;
+ exitSelectSlot = true;
}
- switch (key) {
- case KEY_ENTER:
- rc = active;
- strncpy(_game.strings[MAX_STRINGS], desc[i], MAX_STRINGLEN);
- goto press;
- case KEY_ESCAPE:
- rc = -1;
- goto getout;
- case BUTTON_LEFT:
- if (_gfx->testButton(buttonX[0], buttonY, buttonText[0])) {
+ if (!exitSelectSlot) {
+ switch (key) {
+ case KEY_ENTER:
rc = active;
strncpy(_game.strings[MAX_STRINGS], desc[i], MAX_STRINGLEN);
- goto press;
- }
- if (_gfx->testButton(buttonX[1], buttonY, buttonText[1])) {
+ debugC(8, kDebugLevelMain | kDebugLevelInput, "Button pressed: %d", rc);
+ exitSelectSlot = true;
+ break;
+ case KEY_ESCAPE:
rc = -1;
- goto getout;
- }
- slotClicked = ((int)_mouse.y - 1) / CHAR_COLS - (vm + 4);
- xmin = (hm + 1) * CHAR_COLS;
- xmax = xmin + CHAR_COLS * 34;
- if ((int)_mouse.x >= xmin && (int)_mouse.x <= xmax) {
- if (slotClicked >= 0 && slotClicked < NUM_VISIBLE_SLOTS)
- active = slotClicked;
- }
- xmin = (hm + 36) * CHAR_COLS;
- xmax = xmin + CHAR_COLS;
- if ((int)_mouse.x >= xmin && (int)_mouse.x <= xmax) {
- if (slotClicked >= 0 && slotClicked < NUM_VISIBLE_SLOTS) {
- if (slotClicked == 0)
- keyEnqueue(KEY_UP);
- else if (slotClicked == NUM_VISIBLE_SLOTS - 1)
- keyEnqueue(KEY_DOWN);
- else if (slotClicked < sbPos)
- keyEnqueue(KEY_UP_RIGHT);
- else if (slotClicked > sbPos)
- keyEnqueue(KEY_DOWN_RIGHT);
+ exitSelectSlot = true;
+ break;
+ case BUTTON_LEFT:
+ if (_gfx->testButton(buttonX[0], buttonY, buttonText[0])) {
+ rc = active;
+ strncpy(_game.strings[MAX_STRINGS], desc[i], MAX_STRINGLEN);
+ debugC(8, kDebugLevelMain | kDebugLevelInput, "Button pressed: %d", rc);
+ exitSelectSlot = true;
+ } else if (_gfx->testButton(buttonX[1], buttonY, buttonText[1])) {
+ rc = -1;
+ exitSelectSlot = true;
+ } else {
+ slotClicked = ((int)_mouse.y - 1) / CHAR_COLS - (vm + 4);
+ xmin = (hm + 1) * CHAR_COLS;
+ xmax = xmin + CHAR_COLS * 34;
+ if ((int)_mouse.x >= xmin && (int)_mouse.x <= xmax) {
+ if (slotClicked >= 0 && slotClicked < NUM_VISIBLE_SLOTS)
+ active = slotClicked;
+ }
+ xmin = (hm + 36) * CHAR_COLS;
+ xmax = xmin + CHAR_COLS;
+ if ((int)_mouse.x >= xmin && (int)_mouse.x <= xmax) {
+ if (slotClicked >= 0 && slotClicked < NUM_VISIBLE_SLOTS) {
+ if (slotClicked == 0)
+ keyEnqueue(KEY_UP);
+ else if (slotClicked == NUM_VISIBLE_SLOTS - 1)
+ keyEnqueue(KEY_DOWN);
+ else if (slotClicked < sbPos)
+ keyEnqueue(KEY_UP_RIGHT);
+ else if (slotClicked > sbPos)
+ keyEnqueue(KEY_DOWN_RIGHT);
+ }
+ }
}
- }
- break;
- case KEY_DOWN:
- active++;
- if (active >= NUM_VISIBLE_SLOTS) {
- if (_firstSlot + NUM_VISIBLE_SLOTS < NUM_SLOTS) {
+ break;
+
+ case KEY_DOWN:
+ active++;
+ if (active >= NUM_VISIBLE_SLOTS) {
+ if (_firstSlot + NUM_VISIBLE_SLOTS < NUM_SLOTS) {
+ _firstSlot++;
+ for (i = 1; i < NUM_VISIBLE_SLOTS; i++)
+ memcpy(desc[i - 1], desc[i], sizeof(desc[0]));
+ getSavegameDescription(_firstSlot + NUM_VISIBLE_SLOTS - 1, desc[NUM_VISIBLE_SLOTS - 1]);
+ }
+ active = NUM_VISIBLE_SLOTS - 1;
+ }
+ break;
+ case KEY_UP:
+ active--;
+ if (active < 0) {
+ active = 0;
+ if (_firstSlot > 0) {
+ _firstSlot--;
+ for (i = NUM_VISIBLE_SLOTS - 1; i > 0; i--)
+ memcpy(desc[i], desc[i - 1], sizeof(desc[0]));
+ getSavegameDescription(_firstSlot, desc[0]);
+ }
+ }
+ break;
+
+ // Page Up/Down and mouse wheel scrolling all leave 'active'
+ // unchanged so that a visible slot will remain selected.
+
+ case WHEEL_DOWN:
+ if (_firstSlot < NUM_SLOTS - NUM_VISIBLE_SLOTS) {
_firstSlot++;
for (i = 1; i < NUM_VISIBLE_SLOTS; i++)
memcpy(desc[i - 1], desc[i], sizeof(desc[0]));
getSavegameDescription(_firstSlot + NUM_VISIBLE_SLOTS - 1, desc[NUM_VISIBLE_SLOTS - 1]);
}
- active = NUM_VISIBLE_SLOTS - 1;
- }
- break;
- case KEY_UP:
- active--;
- if (active < 0) {
- active = 0;
+ break;
+ case WHEEL_UP:
if (_firstSlot > 0) {
_firstSlot--;
for (i = NUM_VISIBLE_SLOTS - 1; i > 0; i--)
memcpy(desc[i], desc[i - 1], sizeof(desc[0]));
getSavegameDescription(_firstSlot, desc[0]);
}
+ break;
+ case KEY_DOWN_RIGHT:
+ // This is probably triggered by Page Down.
+ _firstSlot += NUM_VISIBLE_SLOTS;
+ if (_firstSlot > NUM_SLOTS - NUM_VISIBLE_SLOTS) {
+ _firstSlot = NUM_SLOTS - NUM_VISIBLE_SLOTS;
+ }
+ for (i = 0; i < NUM_VISIBLE_SLOTS; i++)
+ getSavegameDescription(_firstSlot + i, desc[i]);
+ break;
+ case KEY_UP_RIGHT:
+ // This is probably triggered by Page Up.
+ _firstSlot -= NUM_VISIBLE_SLOTS;
+ if (_firstSlot < 0) {
+ _firstSlot = 0;
+ }
+ for (i = 0; i < NUM_VISIBLE_SLOTS; i++)
+ getSavegameDescription(_firstSlot + i, desc[i]);
+ break;
}
- break;
-
- // Page Up/Down and mouse wheel scrolling all leave 'active'
- // unchanged so that a visible slot will remain selected.
-
- case WHEEL_DOWN:
- if (_firstSlot < NUM_SLOTS - NUM_VISIBLE_SLOTS) {
- _firstSlot++;
- for (i = 1; i < NUM_VISIBLE_SLOTS; i++)
- memcpy(desc[i - 1], desc[i], sizeof(desc[0]));
- getSavegameDescription(_firstSlot + NUM_VISIBLE_SLOTS - 1, desc[NUM_VISIBLE_SLOTS - 1]);
- }
- break;
- case WHEEL_UP:
- if (_firstSlot > 0) {
- _firstSlot--;
- for (i = NUM_VISIBLE_SLOTS - 1; i > 0; i--)
- memcpy(desc[i], desc[i - 1], sizeof(desc[0]));
- getSavegameDescription(_firstSlot, desc[0]);
- }
- break;
- case KEY_DOWN_RIGHT:
- // This is probably triggered by Page Down.
- _firstSlot += NUM_VISIBLE_SLOTS;
- if (_firstSlot > NUM_SLOTS - NUM_VISIBLE_SLOTS) {
- _firstSlot = NUM_SLOTS - NUM_VISIBLE_SLOTS;
- }
- for (i = 0; i < NUM_VISIBLE_SLOTS; i++)
- getSavegameDescription(_firstSlot + i, desc[i]);
- break;
- case KEY_UP_RIGHT:
- // This is probably triggered by Page Up.
- _firstSlot -= NUM_VISIBLE_SLOTS;
- if (_firstSlot < 0) {
- _firstSlot = 0;
- }
- for (i = 0; i < NUM_VISIBLE_SLOTS; i++)
- getSavegameDescription(_firstSlot + i, desc[i]);
- break;
}
_gfx->doUpdate();
}
-press:
- debugC(8, kDebugLevelMain | kDebugLevelInput, "Button pressed: %d", rc);
-
-getout:
closeWindow();
_noSaveLoadAllowed = false;
diff --git a/engines/agi/sound_2gs.cpp b/engines/agi/sound_2gs.cpp
index c5cfa125d6..bfc8d4d8f3 100644
--- a/engines/agi/sound_2gs.cpp
+++ b/engines/agi/sound_2gs.cpp
@@ -68,10 +68,10 @@ int SoundGen2GS::readBuffer(int16 *buffer, const int numSamples) {
static uint data_available = 0;
static uint data_offset = 0;
uint n = numSamples << 1;
- uint8 *p = (uint8*)buffer;
+ uint8 *p = (uint8 *)buffer;
while (n > data_available) {
- memcpy(p, (uint8*)_out + data_offset, data_available);
+ memcpy(p, (uint8 *)_out + data_offset, data_available);
p += data_available;
n -= data_available;
@@ -81,7 +81,7 @@ int SoundGen2GS::readBuffer(int16 *buffer, const int numSamples) {
data_offset = 0;
}
- memcpy(p, (uint8*)_out + data_offset, n);
+ memcpy(p, (uint8 *)_out + data_offset, n);
data_offset += n;
data_available -= n;
@@ -719,7 +719,10 @@ bool SoundGen2GS::loadInstrumentHeaders(Common::String &exePath, const IIgsExeIn
}
// Read the whole executable file into memory
- Common::SharedPtr<Common::SeekableReadStream> data(file.readStream(file.size()));
+ // CHECKME: Why do we read the file into memory first? It does not seem to be
+ // kept outside of this function. Is the processing of the data too slow
+ // otherwise?
+ Common::ScopedPtr<Common::SeekableReadStream> data(file.readStream(file.size()));
file.close();
// Check that we got enough data to be able to parse the instruments
@@ -769,8 +772,11 @@ bool SoundGen2GS::loadWaveFile(Common::String &wavePath, const IIgsExeInfo &exeI
Common::File file;
// Open the wave file and read it into memory
+ // CHECKME: Why do we read the file into memory first? It does not seem to be
+ // kept outside of this function. Is the processing of the data too slow
+ // otherwise?
file.open(wavePath);
- Common::SharedPtr<Common::SeekableReadStream> uint8Wave(file.readStream(file.size()));
+ Common::ScopedPtr<Common::SeekableReadStream> uint8Wave(file.readStream(file.size()));
file.close();
// Check that we got the whole wave file
diff --git a/engines/agi/sound_2gs.h b/engines/agi/sound_2gs.h
index 89ffc3fe11..404f4a47a1 100644
--- a/engines/agi/sound_2gs.h
+++ b/engines/agi/sound_2gs.h
@@ -247,7 +247,7 @@ private:
void midiNoteOff(int channel, int note, int velocity);
void midiNoteOn(int channel, int note, int velocity);
double midiKeyToFreq(int key, double finetune);
- IIgsInstrumentHeader* getInstrument(uint8 program) { return &_instruments[_progToInst->map(program)]; };
+ IIgsInstrumentHeader* getInstrument(uint8 program) { return &_instruments[_progToInst->map(program)]; }
IIgsGenerator* allocateGenerator() { IIgsGenerator* g = &_generators[_nextGen++]; _nextGen %= 16; return g; }
bool _disableMidi; ///< Disable MIDI if loading instruments fail
diff --git a/engines/agi/sound_sarien.cpp b/engines/agi/sound_sarien.cpp
index a2baf89d12..576801bc56 100644
--- a/engines/agi/sound_sarien.cpp
+++ b/engines/agi/sound_sarien.cpp
@@ -330,7 +330,7 @@ void SoundGenSarien::fillAudio(int16 *stream, uint len) {
debugC(5, kDebugLevelSound, "(%p, %d)", (void *)stream, len);
while (len > data_available) {
- memcpy((uint8 *)stream + p, (uint8*)_sndBuffer + data_offset, data_available);
+ memcpy((uint8 *)stream + p, (uint8 *)_sndBuffer + data_offset, data_available);
p += data_available;
len -= data_available;
@@ -339,7 +339,7 @@ void SoundGenSarien::fillAudio(int16 *stream, uint len) {
data_offset = 0;
}
- memcpy((uint8 *)stream + p, (uint8*)_sndBuffer + data_offset, len);
+ memcpy((uint8 *)stream + p, (uint8 *)_sndBuffer + data_offset, len);
data_offset += len;
data_available -= len;
}
diff --git a/engines/agi/sprite.cpp b/engines/agi/sprite.cpp
index 8d13be3f68..ea2d329fb0 100644
--- a/engines/agi/sprite.cpp
+++ b/engines/agi/sprite.cpp
@@ -55,7 +55,7 @@ void *SpritesMgr::poolAlloc(int size) {
// Adjust size to sizeof(void *) boundary to prevent data misalignment
// errors.
- const int alignPadding = sizeof(void*) - 1;
+ const int alignPadding = sizeof(void *) - 1;
size = (size + alignPadding) & ~alignPadding;
x = _poolTop;
diff --git a/engines/agi/sprite.h b/engines/agi/sprite.h
index 68f0e32b86..851c2438fb 100644
--- a/engines/agi/sprite.h
+++ b/engines/agi/sprite.h
@@ -27,7 +27,7 @@ namespace Agi {
struct Sprite;
-typedef Common::List<Sprite*> SpriteList;
+typedef Common::List<Sprite *> SpriteList;
class AgiEngine;
class GfxMgr;
diff --git a/engines/agi/text.cpp b/engines/agi/text.cpp
index d5027588f9..1886a74ab1 100644
--- a/engines/agi/text.cpp
+++ b/engines/agi/text.cpp
@@ -240,7 +240,6 @@ char *AgiEngine::wordWrapString(const char *s, int *len) {
while (*s) {
pWord = s;
- wLen = 0;
while (*s != '\0' && *s != ' ' && *s != '\n' && *s != '\r')
s++;
@@ -341,8 +340,6 @@ int AgiEngine::messageBox(const char *s) {
int AgiEngine::selectionBox(const char *m, const char **b) {
int numButtons = 0;
int x, y, i, s;
- int key, active = 0;
- int rc = -1;
int bx[5], by[5];
_noSaveLoadAllowed = true;
@@ -381,7 +378,9 @@ int AgiEngine::selectionBox(const char *m, const char **b) {
AllowSyntheticEvents on(this);
debugC(4, kDebugLevelText, "selectionBox(): waiting...");
- while (!(shouldQuit() || _restartGame)) {
+ int key, active = 0;
+ int rc = -1;
+ while (rc == -1 && !(shouldQuit() || _restartGame)) {
for (i = 0; b[i]; i++)
_gfx->drawCurrentStyleButton(bx[i], by[i], b[i], i == active, false, i == 0);
@@ -390,10 +389,8 @@ int AgiEngine::selectionBox(const char *m, const char **b) {
switch (key) {
case KEY_ENTER:
rc = active;
- goto press;
- case KEY_ESCAPE:
- rc = -1;
- goto getout;
+ debugC(4, kDebugLevelText, "selectionBox(): Button pressed: %d", rc);
+ break;
case KEY_RIGHT:
active++;
if (active >= numButtons)
@@ -408,7 +405,8 @@ int AgiEngine::selectionBox(const char *m, const char **b) {
for (i = 0; b[i]; i++) {
if (_gfx->testButton(bx[i], by[i], b[i])) {
rc = active = i;
- goto press;
+ debugC(4, kDebugLevelText, "selectionBox(): Button pressed: %d", rc);
+ break;
}
}
break;
@@ -419,12 +417,11 @@ int AgiEngine::selectionBox(const char *m, const char **b) {
break;
}
_gfx->doUpdate();
- }
-press:
- debugC(4, kDebugLevelText, "selectionBox(): Button pressed: %d", rc);
+ if (key == KEY_ESCAPE)
+ break;
+ }
-getout:
closeWindow();
debugC(2, kDebugLevelText, "selectionBox(): Result = %d", rc);
diff --git a/engines/agi/wagparser.cpp b/engines/agi/wagparser.cpp
index 39f9e0dd92..61feac5d17 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(static_cast<unsigned char>(version.getData()[0])) && // And the first character must be a digit
+ Common::isDigit(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(static_cast<unsigned char>(version.getData()[i])))
+ if (!Common::isDigit(version.getData()[i]))
return false; // Bail out if found a non-digit after the decimal point
return true;
diff --git a/engines/agi/words.cpp b/engines/agi/words.cpp
index 1001c66b20..4400112247 100644
--- a/engines/agi/words.cpp
+++ b/engines/agi/words.cpp
@@ -130,7 +130,7 @@ int AgiEngine::findWord(const char *word, int *flen) {
return -1;
*flen = 0;
- Common::Array<AgiWord*> &a = _game.words[c];
+ Common::Array<AgiWord *> &a = _game.words[c];
for (int i = 0; i < (int)a.size(); i++) {
int wlen = strlen(a[i]->word);
diff --git a/engines/agos/agos.h b/engines/agos/agos.h
index cf75842cdd..d9f982a0fa 100644
--- a/engines/agos/agos.h
+++ b/engines/agos/agos.h
@@ -197,7 +197,12 @@ public:
void registerArchive(const Common::String &filename, int priority);
#endif
- Common::SeekableReadStream *open(const Common::String &filename);
+ virtual bool hasFile(const Common::String &name) const;
+ virtual int listMatchingMembers(Common::ArchiveMemberList &list, const Common::String &pattern) const;
+ virtual int listMembers(Common::ArchiveMemberList &list) const;
+
+ virtual const Common::ArchiveMemberPtr getMember(const Common::String &name) const;
+ virtual Common::SeekableReadStream *createReadStreamForMember(const Common::String &filename) const;
private:
bool _fallBack;
diff --git a/engines/agos/animation.cpp b/engines/agos/animation.cpp
index d9d6b71a2a..29d1b36e19 100644
--- a/engines/agos/animation.cpp
+++ b/engines/agos/animation.cpp
@@ -251,7 +251,7 @@ bool MoviePlayerDXA::load() {
}
Common::String videoName = Common::String::format("%s.dxa", baseName);
- Common::SeekableReadStream *videoStream = _vm->_archives.open(videoName);
+ Common::SeekableReadStream *videoStream = _vm->_archives.createReadStreamForMember(videoName);
if (!videoStream)
error("Failed to load video file %s", videoName.c_str());
if (!loadStream(videoStream))
@@ -312,7 +312,7 @@ void MoviePlayerDXA::startSound() {
_fileStream->seek(size, SEEK_CUR);
- in.open((const char *)"audio.wav");
+ in.open("audio.wav");
if (!in.isOpen()) {
error("Can't read offset file 'audio.wav'");
}
@@ -415,7 +415,7 @@ MoviePlayerSMK::MoviePlayerSMK(AGOSEngine_Feeble *vm, const char *name)
bool MoviePlayerSMK::load() {
Common::String videoName = Common::String::format("%s.smk", baseName);
- Common::SeekableReadStream *videoStream = _vm->_archives.open(videoName);
+ Common::SeekableReadStream *videoStream = _vm->_archives.createReadStreamForMember(videoName);
if (!videoStream)
error("Failed to load video file %s", videoName.c_str());
if (!loadStream(videoStream))
@@ -525,25 +525,25 @@ MoviePlayer *makeMoviePlayer(AGOSEngine_Feeble *vm, const char *name) {
memcpy(shortName, baseName, 6);
sprintf(filename, "%s~1.dxa", shortName);
- if (Common::File::exists(filename)) {
+ if (vm->_archives.hasFile(filename)) {
memset(baseName, 0, sizeof(baseName));
memcpy(baseName, filename, 8);
}
sprintf(filename, "%s~1.smk", shortName);
- if (Common::File::exists(filename)) {
+ if (vm->_archives.hasFile(filename)) {
memset(baseName, 0, sizeof(baseName));
memcpy(baseName, filename, 8);
}
}
sprintf(filename, "%s.dxa", baseName);
- if (Common::File::exists(filename)) {
+ if (vm->_archives.hasFile(filename)) {
return new MoviePlayerDXA(vm, baseName);
}
sprintf(filename, "%s.smk", baseName);
- if (Common::File::exists(filename)) {
+ if (vm->_archives.hasFile(filename)) {
return new MoviePlayerSMK(vm, baseName);
}
diff --git a/engines/agos/charset-fontdata.cpp b/engines/agos/charset-fontdata.cpp
index e6b81f54ee..87f51cfad2 100644
--- a/engines/agos/charset-fontdata.cpp
+++ b/engines/agos/charset-fontdata.cpp
@@ -20,6 +20,7 @@
*
*/
+#include "common/endian.h"
#include "common/system.h"
#include "common/textconsole.h"
@@ -680,6 +681,578 @@ static const byte feeble_windowFont[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
+static const byte english_simon1AGAFontData[] = {
+ 0x00,0x00,0x00,0x20,0x00,0x00,0x20,0x50,0x20,0x10,0x40,0x88,0x30,0x40,0x00,0x88,0x20,0x00,0x00,0x50,0x20,0x00,0x00,0x50,0x00,0x00,0x00,0x20,0x00,0x00,0x20,0x50,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x00,0x05,
+ 0x00,0x00,0x00,0x30,0x00,0x10,0x20,0x48,0x10,0x20,0x00,0x48,0x20,0x40,0x00,0x90,0x00,0x00,0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05,
+ 0x00,0x00,0x00,0x28,0x00,0x00,0x28,0x54,0x00,0x28,0x00,0x54,0x1C,0x20,0x40,0x82,0x28,0x00,0x00,0x54,0x1C,0x20,0x40,0x82,0x28,0x00,0x00,0x54,0x28,0x00,0x00,0x54,0x00,0x00,0x00,0x28,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x10,0x00,0x00,0x10,0x28,0x08,0x10,0x20,0x44,0x00,0x40,0x00,0xB8,0x30,0x00,0x00,0x48,0x08,0x00,0x00,0x74,0x30,0x00,0x40,0x88,0x20,0x00,0x00,0x50,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x00,0x06,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x00,0x00,0x48,0xB4,0x00,0x48,0x00,0xB4,0x10,0x00,0x00,0x68,0x00,0x20,0x00,0x58,0x00,0x08,0x40,0xB4,0x08,0x40,0x00,0xB4,0x00,0x00,0x00,0x48,0x00,0x00,0x00,0x00,0x06,
+ 0x00,0x00,0x00,0x20,0x00,0x00,0x20,0x50,0x10,0x00,0x40,0xA8,0x18,0x20,0x00,0x44,0x10,0x00,0x00,0x28,0x18,0x20,0x00,0x44,0x10,0x00,0x40,0xAC,0x0C,0x20,0x00,0x52,0x00,0x00,0x00,0x2C,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x30,0x00,0x10,0x20,0x48,0x10,0x20,0x00,0x48,0x20,0x40,0x00,0x90,0x00,0x00,0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05,
+ 0x00,0x00,0x00,0x28,0x00,0x00,0x28,0x54,0x00,0x28,0x00,0x54,0x1C,0x20,0x40,0x82,0x28,0x00,0x00,0x54,0x1C,0x20,0x40,0x82,0x28,0x00,0x00,0x54,0x28,0x00,0x00,0x54,0x00,0x00,0x00,0x28,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x28,0x00,0x00,0x28,0x54,0x00,0x28,0x00,0x54,0x1C,0x20,0x40,0x82,0x28,0x00,0x00,0x54,0x1C,0x20,0x40,0x82,0x28,0x00,0x00,0x54,0x28,0x00,0x00,0x54,0x00,0x00,0x00,0x28,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x28,0x00,0x00,0x28,0x54,0x00,0x28,0x00,0x54,0x1C,0x20,0x40,0x82,0x28,0x00,0x00,0x54,0x1C,0x20,0x40,0x82,0x28,0x00,0x00,0x54,0x28,0x00,0x00,0x54,0x00,0x00,0x00,0x28,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x10,0x20,0x48,0x10,0x20,0x00,0x48,0x20,0x40,0x00,0x90,0x00,0x00,0x00,0x60,0x05,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x10,0x20,0x48,0x10,0x20,0x00,0x48,0x20,0x40,0x00,0x90,0x00,0x00,0x00,0x60,0x05,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x78,0x18,0x20,0x40,0x84,0x00,0x00,0x00,0x78,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x00,0x20,0x40,0x90,0x20,0x40,0x00,0x90,0x00,0x00,0x00,0x60,0x00,0x00,0x00,0x00,0x04,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x00,0x20,0x40,0x90,0x20,0x40,0x00,0x90,0x00,0x00,0x00,0x60,0x00,0x00,0x00,0x00,0x04,
+ 0x00,0x00,0x00,0x38,0x00,0x18,0x20,0x44,0x04,0x00,0x40,0xBA,0x0C,0x00,0x40,0xB2,0x04,0x50,0x00,0xAA,0x44,0x20,0x00,0x9A,0x44,0x00,0x00,0xBA,0x38,0x00,0x00,0x44,0x00,0x00,0x00,0x38,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x20,0x00,0x00,0x20,0x50,0x00,0x20,0x40,0x90,0x00,0x20,0x00,0x50,0x20,0x00,0x00,0x50,0x20,0x00,0x00,0x50,0x20,0x00,0x00,0x50,0x10,0x20,0x40,0x88,0x00,0x00,0x00,0x70,0x00,0x00,0x00,0x00,0x05,
+ 0x00,0x00,0x00,0x38,0x00,0x08,0x30,0x44,0x04,0x00,0x40,0xBA,0x04,0x00,0x00,0x5A,0x08,0x10,0x00,0x24,0x00,0x20,0x00,0x5C,0x00,0x04,0x40,0xBA,0x3C,0x40,0x00,0x82,0x00,0x00,0x00,0x7C,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x38,0x08,0x10,0x20,0x44,0x04,0x00,0x40,0xBA,0x04,0x00,0x00,0x5A,0x00,0x08,0x10,0x24,0x04,0x00,0x00,0x5A,0x04,0x00,0x40,0xBA,0x18,0x20,0x00,0x44,0x00,0x00,0x00,0x38,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x08,0x00,0x08,0x00,0x14,0x08,0x00,0x10,0x24,0x08,0x00,0x20,0x54,0x08,0x40,0x00,0xB4,0x3C,0x40,0x00,0x82,0x08,0x00,0x00,0x74,0x04,0x08,0x10,0x22,0x00,0x00,0x00,0x1C,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x7C,0x04,0x18,0x60,0x82,0x00,0x40,0x00,0xBC,0x78,0x00,0x00,0x84,0x04,0x00,0x00,0x7A,0x04,0x00,0x00,0x4A,0x04,0x00,0x40,0xBA,0x18,0x20,0x00,0x44,0x00,0x00,0x00,0x38,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x18,0x08,0x10,0x00,0x24,0x00,0x00,0x20,0x58,0x00,0x40,0x00,0xB8,0x38,0x40,0x00,0x84,0x44,0x00,0x00,0xBA,0x44,0x00,0x00,0xBA,0x38,0x00,0x00,0x44,0x00,0x00,0x00,0x38,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x7C,0x04,0x38,0x40,0x82,0x04,0x40,0x00,0xBA,0x00,0x04,0x00,0x4A,0x00,0x00,0x08,0x14,0x00,0x10,0x00,0x28,0x00,0x10,0x00,0x28,0x10,0x00,0x00,0x28,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x38,0x00,0x18,0x20,0x44,0x04,0x00,0x40,0xBA,0x04,0x40,0x00,0xBA,0x18,0x20,0x00,0x44,0x04,0x00,0x40,0xBA,0x04,0x40,0x00,0xBA,0x38,0x00,0x00,0x44,0x00,0x00,0x00,0x38,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x38,0x00,0x18,0x20,0x44,0x04,0x00,0x40,0xBA,0x04,0x40,0x00,0xBA,0x1C,0x20,0x00,0x42,0x04,0x00,0x00,0x3A,0x00,0x08,0x00,0x34,0x00,0x10,0x20,0x48,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x00,0x20,0x40,0x90,0x20,0x40,0x00,0x90,0x00,0x00,0x00,0x60,0x00,0x00,0x00,0x60,0x00,0x20,0x40,0x90,0x20,0x40,0x00,0x90,0x00,0x00,0x00,0x60,0x00,0x00,0x00,0x00,0x04,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x10,0x20,0x48,0x10,0x20,0x00,0x48,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x30,0x00,0x10,0x20,0x48,0x10,0x20,0x00,0x48,0x20,0x40,0x00,0x90,0x00,0x00,0x00,0x60,0x05,
+ 0x00,0x00,0x00,0x38,0x00,0x08,0x30,0x44,0x04,0x40,0x00,0xBA,0x04,0x00,0x00,0x4A,0x08,0x00,0x00,0x14,0x10,0x00,0x00,0x28,0x00,0x00,0x00,0x10,0x10,0x00,0x00,0x28,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x38,0x00,0x08,0x30,0x44,0x04,0x40,0x00,0xBA,0x04,0x00,0x00,0x4A,0x08,0x00,0x00,0x14,0x10,0x00,0x00,0x28,0x00,0x00,0x00,0x10,0x10,0x00,0x00,0x28,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x38,0x00,0x08,0x30,0x44,0x04,0x40,0x00,0xBA,0x04,0x00,0x00,0x4A,0x08,0x00,0x00,0x14,0x10,0x00,0x00,0x28,0x00,0x00,0x00,0x10,0x10,0x00,0x00,0x28,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x38,0x00,0x08,0x30,0x44,0x04,0x40,0x00,0xBA,0x04,0x00,0x00,0x4A,0x08,0x00,0x00,0x14,0x10,0x00,0x00,0x28,0x00,0x00,0x00,0x10,0x10,0x00,0x00,0x28,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x38,0x00,0x08,0x30,0x44,0x04,0x00,0x40,0xBA,0x04,0x40,0x10,0xAA,0x0C,0x50,0x00,0xA2,0x1C,0x40,0x00,0xA2,0x40,0x00,0x00,0xBC,0x38,0x00,0x00,0x44,0x00,0x00,0x00,0x38,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x38,0x08,0x10,0x20,0x44,0x04,0x00,0x40,0xBA,0x04,0x00,0x40,0xBA,0x0C,0x70,0x00,0x82,0x04,0x40,0x00,0xBA,0x44,0x00,0x00,0xAA,0x44,0x00,0x00,0xAA,0x00,0x00,0x00,0x44,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x78,0x08,0x10,0x60,0x84,0x04,0x00,0x20,0x5A,0x04,0x20,0x00,0x5A,0x28,0x10,0x00,0x44,0x24,0x00,0x00,0x5A,0x24,0x00,0x00,0x5A,0x18,0x20,0x40,0x84,0x00,0x00,0x00,0x78,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x18,0x00,0x18,0x00,0x24,0x04,0x00,0x20,0x5A,0x00,0x00,0x40,0xA4,0x00,0x00,0x40,0xA0,0x00,0x40,0x00,0xA4,0x24,0x00,0x00,0x5A,0x18,0x00,0x00,0x24,0x00,0x00,0x00,0x18,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x70,0x10,0x20,0x40,0x88,0x08,0x20,0x00,0x54,0x04,0x20,0x00,0x5A,0x04,0x20,0x00,0x5A,0x24,0x00,0x00,0x5A,0x28,0x00,0x00,0x54,0x10,0x20,0x40,0x88,0x00,0x00,0x00,0x70,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x7C,0x04,0x18,0x60,0x82,0x04,0x20,0x00,0x5A,0x00,0x20,0x00,0x5C,0x28,0x10,0x00,0x44,0x20,0x00,0x00,0x5C,0x20,0x04,0x00,0x5A,0x0C,0x30,0x40,0x82,0x00,0x00,0x00,0x7C,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x7C,0x04,0x18,0x60,0x82,0x04,0x20,0x00,0x5A,0x00,0x20,0x00,0x5C,0x28,0x10,0x00,0x44,0x20,0x00,0x00,0x58,0x20,0x00,0x00,0x50,0x10,0x20,0x40,0x88,0x00,0x00,0x00,0x70,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x18,0x00,0x18,0x00,0x24,0x04,0x00,0x20,0x5A,0x00,0x40,0x00,0xAC,0x00,0x44,0x08,0xB2,0x44,0x00,0x00,0xAA,0x24,0x00,0x00,0x5A,0x1C,0x00,0x00,0x22,0x00,0x00,0x00,0x1C,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x44,0x00,0x00,0x44,0xAA,0x00,0x44,0x00,0xAA,0x04,0x40,0x00,0xBA,0x4C,0x30,0x00,0x82,0x44,0x00,0x00,0xBA,0x44,0x00,0x00,0xAA,0x44,0x00,0x00,0xAA,0x00,0x00,0x00,0x44,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x7C,0x04,0x38,0x40,0x82,0x00,0x10,0x00,0x6C,0x10,0x00,0x00,0x28,0x10,0x00,0x00,0x28,0x10,0x00,0x00,0x28,0x10,0x00,0x00,0x6C,0x1C,0x20,0x40,0x82,0x00,0x00,0x00,0x7C,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x0C,0x00,0x04,0x08,0x12,0x00,0x04,0x00,0x0A,0x04,0x00,0x00,0x0A,0x04,0x00,0x00,0x4A,0x04,0x00,0x40,0xAA,0x04,0x40,0x00,0xBA,0x18,0x20,0x00,0x44,0x00,0x00,0x00,0x38,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x64,0x00,0x24,0x40,0x9A,0x00,0x24,0x00,0x5A,0x20,0x08,0x00,0x54,0x20,0x10,0x00,0x48,0x28,0x00,0x00,0x54,0x24,0x00,0x00,0x5A,0x04,0x20,0x40,0x9A,0x00,0x00,0x00,0x64,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x70,0x00,0x30,0x40,0x88,0x00,0x20,0x00,0x50,0x00,0x20,0x00,0x50,0x00,0x20,0x00,0x50,0x20,0x00,0x00,0x54,0x24,0x00,0x00,0x5A,0x1C,0x20,0x40,0x82,0x00,0x00,0x00,0x7C,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x44,0x00,0x04,0x40,0xAA,0x24,0x40,0x08,0x92,0x04,0x50,0x00,0xAA,0x14,0x40,0x00,0xAA,0x44,0x00,0x00,0xBA,0x44,0x00,0x00,0xAA,0x44,0x00,0x00,0xAA,0x00,0x00,0x00,0x44,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x44,0x00,0x00,0x44,0xAA,0x20,0x44,0x00,0x9A,0x14,0x40,0x00,0xAA,0x0C,0x40,0x00,0xB2,0x44,0x00,0x00,0xAA,0x44,0x00,0x00,0xAA,0x44,0x00,0x00,0xAA,0x00,0x00,0x00,0x44,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x38,0x00,0x18,0x20,0x44,0x04,0x00,0x40,0xBA,0x04,0x00,0x40,0xAA,0x04,0x40,0x00,0xAA,0x04,0x40,0x00,0xAA,0x04,0x40,0x00,0xBA,0x38,0x00,0x00,0x44,0x00,0x00,0x00,0x38,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x78,0x08,0x30,0x40,0x84,0x04,0x20,0x00,0x5A,0x04,0x20,0x00,0x5A,0x28,0x10,0x00,0x44,0x20,0x00,0x00,0x58,0x20,0x00,0x00,0x50,0x10,0x20,0x40,0x88,0x00,0x00,0x00,0x70,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x38,0x08,0x10,0x20,0x44,0x04,0x00,0x40,0xBA,0x04,0x00,0x40,0xAA,0x04,0x40,0x00,0xAA,0x04,0x40,0x00,0xBA,0x44,0x00,0x10,0xAA,0x30,0x08,0x00,0x44,0x04,0x00,0x00,0x3A,0x00,0x00,0x00,0x04,0x07,
+ 0x00,0x00,0x00,0x78,0x00,0x18,0x60,0x84,0x04,0x20,0x00,0x5A,0x24,0x00,0x00,0x5A,0x28,0x10,0x00,0x44,0x24,0x00,0x00,0x5A,0x24,0x00,0x00,0x5A,0x04,0x20,0x40,0x9A,0x00,0x00,0x00,0x64,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x38,0x00,0x18,0x20,0x44,0x04,0x00,0x40,0xBA,0x00,0x40,0x00,0xBC,0x08,0x30,0x00,0x44,0x04,0x00,0x00,0x7A,0x04,0x00,0x40,0xBA,0x08,0x30,0x00,0x44,0x00,0x00,0x00,0x38,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x7C,0x04,0x18,0x60,0x82,0x14,0x40,0x00,0xAA,0x10,0x00,0x00,0x6C,0x10,0x00,0x00,0x28,0x10,0x00,0x00,0x28,0x10,0x00,0x00,0x28,0x08,0x10,0x20,0x44,0x00,0x00,0x00,0x38,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x44,0x00,0x00,0x44,0xAA,0x00,0x44,0x00,0xAA,0x04,0x40,0x00,0xAA,0x04,0x40,0x00,0xAA,0x44,0x00,0x00,0xAA,0x44,0x00,0x00,0xBA,0x3C,0x00,0x00,0x42,0x00,0x00,0x00,0x3C,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x44,0x00,0x04,0x40,0xAA,0x00,0x44,0x00,0xAA,0x04,0x40,0x00,0xAA,0x28,0x00,0x00,0x54,0x28,0x00,0x00,0x54,0x10,0x00,0x00,0x28,0x10,0x00,0x00,0x28,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x44,0x00,0x00,0x44,0xAA,0x00,0x04,0x40,0xAA,0x04,0x40,0x00,0xAA,0x04,0x40,0x00,0xBA,0x54,0x00,0x00,0xAA,0x6C,0x00,0x00,0x92,0x44,0x00,0x00,0xAA,0x00,0x00,0x00,0x44,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x44,0x00,0x00,0x44,0xAA,0x04,0x40,0x00,0xAA,0x28,0x00,0x00,0x54,0x10,0x00,0x00,0x28,0x08,0x20,0x00,0x54,0x04,0x00,0x40,0xAA,0x04,0x40,0x00,0xAA,0x00,0x00,0x00,0x44,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x44,0x04,0x00,0x40,0xAA,0x04,0x40,0x00,0xAA,0x04,0x40,0x00,0xBA,0x38,0x00,0x00,0x44,0x10,0x00,0x00,0x28,0x10,0x00,0x00,0x28,0x08,0x10,0x20,0x44,0x00,0x00,0x00,0x38,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x7C,0x04,0x38,0x40,0x82,0x04,0x40,0x00,0xBA,0x08,0x00,0x00,0x54,0x10,0x00,0x00,0x28,0x00,0x20,0x00,0x54,0x04,0x00,0x40,0xBA,0x3C,0x40,0x00,0x82,0x00,0x00,0x00,0x7C,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x7C,0x04,0x38,0x40,0x82,0x04,0x40,0x00,0xBA,0x08,0x00,0x00,0x54,0x10,0x00,0x00,0x28,0x00,0x20,0x00,0x54,0x04,0x00,0x40,0xBA,0x3C,0x40,0x00,0x82,0x00,0x00,0x00,0x7C,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x7C,0x04,0x38,0x40,0x82,0x04,0x40,0x00,0xBA,0x08,0x00,0x00,0x54,0x10,0x00,0x00,0x28,0x00,0x20,0x00,0x54,0x04,0x00,0x40,0xBA,0x3C,0x40,0x00,0x82,0x00,0x00,0x00,0x7C,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x7C,0x04,0x38,0x40,0x82,0x04,0x40,0x00,0xBA,0x08,0x00,0x00,0x54,0x10,0x00,0x00,0x28,0x00,0x20,0x00,0x54,0x04,0x00,0x40,0xBA,0x3C,0x40,0x00,0x82,0x00,0x00,0x00,0x7C,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x7C,0x04,0x38,0x40,0x82,0x04,0x40,0x00,0xBA,0x08,0x00,0x00,0x54,0x10,0x00,0x00,0x28,0x00,0x20,0x00,0x54,0x04,0x00,0x40,0xBA,0x3C,0x40,0x00,0x82,0x00,0x00,0x00,0x7C,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x7C,0x04,0x38,0x40,0x82,0x04,0x40,0x00,0xBA,0x08,0x00,0x00,0x54,0x10,0x00,0x00,0x28,0x00,0x20,0x00,0x54,0x04,0x00,0x40,0xBA,0x3C,0x40,0x00,0x82,0x00,0x00,0x00,0x7C,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x7C,0x04,0x38,0x40,0x82,0x04,0x40,0x00,0xBA,0x08,0x00,0x00,0x54,0x10,0x00,0x00,0x28,0x00,0x20,0x00,0x54,0x04,0x00,0x40,0xBA,0x3C,0x40,0x00,0x82,0x00,0x00,0x00,0x7C,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x00,0x28,0x10,0x44,0x04,0x00,0x00,0x3A,0x04,0x08,0x30,0x42,0x04,0x40,0x00,0xBA,0x3C,0x00,0x00,0x42,0x00,0x00,0x00,0x3C,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x60,0x00,0x20,0x40,0x90,0x00,0x20,0x00,0x58,0x00,0x28,0x00,0x54,0x04,0x20,0x10,0x4A,0x04,0x20,0x00,0x5A,0x04,0x20,0x00,0x5A,0x18,0x20,0x00,0x44,0x00,0x00,0x00,0x38,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x00,0x08,0x30,0x44,0x04,0x00,0x40,0xBA,0x00,0x40,0x00,0xA4,0x04,0x40,0x00,0xBA,0x38,0x00,0x00,0x44,0x00,0x00,0x00,0x38,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x0C,0x00,0x04,0x08,0x12,0x08,0x00,0x00,0x34,0x08,0x20,0x00,0x54,0x18,0x40,0x00,0xA4,0x08,0x40,0x00,0xB4,0x08,0x40,0x00,0xB4,0x38,0x00,0x00,0x44,0x00,0x00,0x00,0x38,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x00,0x08,0x30,0x44,0x04,0x00,0x40,0xBA,0x3C,0x40,0x00,0x82,0x00,0x40,0x00,0xBC,0x38,0x00,0x00,0x44,0x00,0x00,0x00,0x38,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x18,0x00,0x08,0x10,0x24,0x04,0x00,0x20,0x5A,0x00,0x20,0x00,0x54,0x10,0x20,0x40,0x88,0x20,0x00,0x00,0x50,0x20,0x00,0x00,0x50,0x30,0x40,0x00,0x88,0x00,0x00,0x00,0x70,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x34,0x04,0x10,0x20,0x4A,0x08,0x00,0x40,0xB4,0x08,0x40,0x00,0xB4,0x38,0x00,0x00,0x44,0x04,0x00,0x40,0xBA,0x18,0x20,0x00,0x44,0x00,0x00,0x00,0x38,0x07,
+ 0x00,0x00,0x00,0x60,0x00,0x20,0x40,0x90,0x00,0x20,0x00,0x58,0x20,0x08,0x00,0x54,0x24,0x00,0x10,0x4A,0x24,0x00,0x00,0x5A,0x24,0x00,0x00,0x5A,0x04,0x20,0x40,0x9A,0x00,0x00,0x00,0x64,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x20,0x00,0x00,0x20,0x50,0x00,0x00,0x00,0x60,0x00,0x40,0x20,0x90,0x00,0x20,0x00,0x50,0x20,0x00,0x00,0x50,0x20,0x00,0x00,0x50,0x10,0x20,0x40,0x88,0x00,0x00,0x00,0x70,0x00,0x00,0x00,0x00,0x05,
+ 0x00,0x00,0x00,0x04,0x00,0x00,0x04,0x0A,0x00,0x00,0x00,0x04,0x00,0x00,0x04,0x0A,0x00,0x04,0x00,0x0A,0x04,0x00,0x00,0x0A,0x04,0x00,0x00,0x4A,0x04,0x00,0x40,0xBA,0x18,0x20,0x00,0x44,0x00,0x00,0x00,0x38,0x07,
+ 0x00,0x00,0x00,0x60,0x00,0x00,0x60,0x90,0x00,0x20,0x00,0x54,0x20,0x04,0x00,0x5A,0x20,0x00,0x08,0x54,0x20,0x10,0x00,0x48,0x28,0x00,0x00,0x54,0x04,0x20,0x40,0x9A,0x00,0x00,0x00,0x64,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x60,0x00,0x20,0x40,0x90,0x00,0x20,0x00,0x50,0x20,0x00,0x00,0x50,0x20,0x00,0x00,0x50,0x20,0x00,0x00,0x50,0x20,0x00,0x00,0x50,0x10,0x20,0x40,0x88,0x00,0x00,0x00,0x70,0x00,0x00,0x00,0x00,0x05,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x00,0x00,0x48,0xB4,0x24,0x48,0x00,0x92,0x44,0x10,0x00,0xAA,0x44,0x00,0x00,0xBA,0x44,0x00,0x00,0xAA,0x00,0x00,0x00,0x44,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x78,0x08,0x10,0x60,0x84,0x04,0x00,0x40,0xBA,0x04,0x40,0x00,0xAA,0x44,0x00,0x00,0xAA,0x44,0x00,0x00,0xAA,0x00,0x00,0x00,0x44,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x08,0x10,0x20,0x44,0x04,0x00,0x40,0xBA,0x04,0x40,0x00,0xAA,0x44,0x00,0x00,0xBA,0x38,0x00,0x00,0x44,0x00,0x00,0x00,0x38,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x58,0x00,0x08,0x50,0xA4,0x04,0x20,0x00,0x5A,0x24,0x00,0x00,0x5A,0x38,0x00,0x00,0x44,0x20,0x00,0x00,0x58,0x10,0x20,0x40,0x88,0x00,0x00,0x00,0x70,0x07,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x34,0x00,0x14,0x20,0x4A,0x08,0x40,0x00,0xB4,0x48,0x00,0x00,0xB4,0x38,0x00,0x00,0x44,0x08,0x00,0x00,0x34,0x04,0x08,0x10,0x22,0x00,0x00,0x00,0x1C,0x07,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x58,0x00,0x08,0x50,0xA4,0x04,0x20,0x00,0x5A,0x24,0x00,0x00,0x5A,0x20,0x00,0x00,0x54,0x10,0x20,0x40,0x88,0x00,0x00,0x00,0x70,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3C,0x04,0x18,0x20,0x42,0x00,0x40,0x00,0xBC,0x38,0x00,0x00,0x44,0x04,0x00,0x00,0x7A,0x38,0x00,0x40,0x84,0x00,0x00,0x00,0x78,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x20,0x00,0x00,0x20,0x50,0x00,0x20,0x00,0x58,0x08,0x30,0x40,0x84,0x20,0x00,0x00,0x58,0x20,0x00,0x00,0x54,0x04,0x20,0x00,0x5A,0x08,0x10,0x00,0x24,0x00,0x00,0x00,0x18,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x00,0x00,0x48,0xB4,0x00,0x48,0x00,0xB4,0x08,0x40,0x00,0xB4,0x48,0x00,0x00,0xB4,0x34,0x00,0x00,0x4A,0x00,0x00,0x00,0x34,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x44,0x00,0x00,0x44,0xAA,0x00,0x44,0x00,0xAA,0x04,0x40,0x00,0xAA,0x28,0x00,0x00,0x54,0x10,0x00,0x00,0x28,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x44,0x00,0x00,0x44,0xAA,0x00,0x44,0x00,0xBA,0x14,0x40,0x00,0xAA,0x2C,0x40,0x00,0x92,0x48,0x00,0x00,0xB4,0x00,0x00,0x00,0x48,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x44,0x00,0x00,0x44,0xAA,0x00,0x28,0x00,0x54,0x10,0x00,0x00,0x28,0x08,0x20,0x00,0x54,0x04,0x40,0x00,0xAA,0x00,0x00,0x00,0x44,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x44,0x00,0x00,0x44,0xAA,0x00,0x44,0x00,0xAA,0x04,0x40,0x00,0xBA,0x38,0x00,0x00,0x44,0x00,0x10,0x00,0x68,0x00,0x20,0x40,0x90,0x00,0x00,0x00,0x60,0x07,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7C,0x04,0x38,0x40,0x82,0x08,0x40,0x00,0xB4,0x00,0x10,0x00,0x6C,0x04,0x20,0x00,0x5A,0x3C,0x00,0x40,0x82,0x00,0x00,0x00,0x7C,0x00,0x00,0x00,0x00,0x07
+};
+
+static const byte german_simon1AGAFontData[] = {
+ 0x00,0x00,0x00,0x20,0x00,0x00,0x20,0x50,0x20,0x10,0x40,0x88,0x30,0x40,0x00,0x88,0x20,0x00,0x00,0x50,0x20,0x00,0x00,0x50,0x00,0x00,0x00,0x20,0x00,0x00,0x20,0x50,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x00,0x05,
+ 0x00,0x00,0x00,0x30,0x00,0x10,0x20,0x48,0x10,0x20,0x00,0x48,0x20,0x40,0x00,0x90,0x00,0x00,0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05,
+ 0x00,0x00,0x00,0x28,0x00,0x00,0x28,0x54,0x00,0x00,0x00,0x38,0x00,0x28,0x10,0x44,0x04,0x00,0x00,0x3a,0x04,0x08,0x30,0x42,0x04,0x40,0x00,0xba,0x3c,0x00,0x00,0x42,0x00,0x00,0x00,0x3c,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x28,0x00,0x00,0x28,0x54,0x00,0x00,0x00,0x38,0x08,0x10,0x20,0x44,0x04,0x00,0x40,0xba,0x04,0x40,0x00,0xaa,0x44,0x00,0x00,0xba,0x38,0x00,0x00,0x44,0x00,0x00,0x00,0x38,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x50,0x00,0x00,0x50,0xa8,0x00,0x00,0x00,0x48,0x00,0x00,0x48,0xb4,0x00,0x48,0x00,0xb4,0x08,0x40,0x00,0xb4,0x48,0x00,0x00,0xb4,0x34,0x00,0x00,0x4a,0x00,0x00,0x00,0x34,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x20,0x00,0x00,0x20,0x50,0x10,0x00,0x40,0xa8,0x18,0x20,0x00,0x44,0x10,0x00,0x00,0x28,0x18,0x20,0x00,0x44,0x10,0x00,0x40,0xac,0x0c,0x20,0x00,0x52,0x00,0x00,0x00,0x2c,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x30,0x00,0x10,0x20,0x48,0x10,0x20,0x00,0x48,0x20,0x40,0x00,0x90,0x00,0x00,0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05,
+ 0x00,0x00,0x00,0x28,0x00,0x00,0x28,0x54,0x00,0x28,0x00,0x54,0x1c,0x20,0x40,0x82,0x28,0x00,0x00,0x54,0x1c,0x20,0x40,0x82,0x28,0x00,0x00,0x54,0x28,0x00,0x00,0x54,0x00,0x00,0x00,0x28,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x28,0x00,0x00,0x28,0x54,0x00,0x28,0x00,0x54,0x1c,0x20,0x40,0x82,0x28,0x00,0x00,0x54,0x1c,0x20,0x40,0x82,0x28,0x00,0x00,0x54,0x28,0x00,0x00,0x54,0x00,0x00,0x00,0x28,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x28,0x00,0x00,0x28,0x54,0x00,0x28,0x00,0x54,0x1c,0x20,0x40,0x82,0x28,0x00,0x00,0x54,0x1c,0x20,0x40,0x82,0x28,0x00,0x00,0x54,0x28,0x00,0x00,0x54,0x00,0x00,0x00,0x28,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x30,0x10,0x20,0x00,0x48,0x08,0x00,0x40,0xb4,0x08,0x40,0x00,0xb4,0x50,0x00,0x00,0xa8,0x48,0x00,0x00,0xb4,0x48,0x00,0x00,0xb4,0x50,0x00,0x00,0xa8,0x40,0x00,0x00,0xa0,0x00,0x00,0x00,0x00,0x06,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x10,0x20,0x48,0x10,0x20,0x00,0x48,0x20,0x40,0x00,0x90,0x00,0x00,0x00,0x60,0x05,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x78,0x18,0x20,0x40,0x84,0x00,0x00,0x00,0x78,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x00,0x20,0x40,0x90,0x20,0x40,0x00,0x90,0x00,0x00,0x00,0x60,0x00,0x00,0x00,0x00,0x04,
+ 0x00,0x00,0x00,0x28,0x00,0x00,0x28,0x54,0x00,0x00,0x00,0x38,0x08,0x10,0x20,0x44,0x04,0x00,0x40,0xba,0x0c,0x70,0x00,0x82,0x04,0x40,0x00,0xba,0x44,0x00,0x00,0xaa,0x00,0x00,0x00,0x44,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x38,0x00,0x18,0x20,0x44,0x04,0x00,0x40,0xba,0x0c,0x00,0x40,0xb2,0x04,0x50,0x00,0xaa,0x44,0x20,0x00,0x9a,0x44,0x00,0x00,0xba,0x38,0x00,0x00,0x44,0x00,0x00,0x00,0x38,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x20,0x00,0x00,0x20,0x50,0x00,0x20,0x40,0x90,0x00,0x20,0x00,0x50,0x20,0x00,0x00,0x50,0x20,0x00,0x00,0x50,0x20,0x00,0x00,0x50,0x10,0x20,0x40,0x88,0x00,0x00,0x00,0x70,0x00,0x00,0x00,0x00,0x05,
+ 0x00,0x00,0x00,0x38,0x00,0x08,0x30,0x44,0x04,0x00,0x40,0xba,0x04,0x00,0x00,0x5a,0x08,0x10,0x00,0x24,0x00,0x20,0x00,0x5c,0x00,0x04,0x40,0xba,0x3c,0x40,0x00,0x82,0x00,0x00,0x00,0x7c,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x38,0x08,0x10,0x20,0x44,0x04,0x00,0x40,0xba,0x04,0x00,0x00,0x5a,0x00,0x08,0x10,0x24,0x04,0x00,0x00,0x5a,0x04,0x00,0x40,0xba,0x18,0x20,0x00,0x44,0x00,0x00,0x00,0x38,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x08,0x00,0x08,0x00,0x14,0x08,0x00,0x10,0x24,0x08,0x00,0x20,0x54,0x08,0x40,0x00,0xb4,0x3c,0x40,0x00,0x82,0x08,0x00,0x00,0x74,0x04,0x08,0x10,0x22,0x00,0x00,0x00,0x1c,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x7c,0x04,0x18,0x60,0x82,0x00,0x40,0x00,0xbc,0x78,0x00,0x00,0x84,0x04,0x00,0x00,0x7a,0x04,0x00,0x00,0x4a,0x04,0x00,0x40,0xba,0x18,0x20,0x00,0x44,0x00,0x00,0x00,0x38,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x18,0x08,0x10,0x00,0x24,0x00,0x00,0x20,0x58,0x00,0x40,0x00,0xb8,0x38,0x40,0x00,0x84,0x44,0x00,0x00,0xba,0x44,0x00,0x00,0xba,0x38,0x00,0x00,0x44,0x00,0x00,0x00,0x38,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x7c,0x04,0x38,0x40,0x82,0x04,0x40,0x00,0xba,0x00,0x04,0x00,0x4a,0x00,0x00,0x08,0x14,0x00,0x10,0x00,0x28,0x00,0x10,0x00,0x28,0x10,0x00,0x00,0x28,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x38,0x00,0x18,0x20,0x44,0x04,0x00,0x40,0xba,0x04,0x40,0x00,0xba,0x18,0x20,0x00,0x44,0x04,0x00,0x40,0xba,0x04,0x40,0x00,0xba,0x38,0x00,0x00,0x44,0x00,0x00,0x00,0x38,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x38,0x00,0x18,0x20,0x44,0x04,0x00,0x40,0xba,0x04,0x40,0x00,0xba,0x1c,0x20,0x00,0x42,0x04,0x00,0x00,0x3a,0x00,0x08,0x00,0x34,0x00,0x10,0x20,0x48,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x00,0x20,0x40,0x90,0x20,0x40,0x00,0x90,0x00,0x00,0x00,0x60,0x00,0x00,0x00,0x60,0x00,0x20,0x40,0x90,0x20,0x40,0x00,0x90,0x00,0x00,0x00,0x60,0x00,0x00,0x00,0x00,0x04,
+ 0x00,0x00,0x00,0x28,0x00,0x00,0x28,0x54,0x00,0x00,0x00,0x38,0x00,0x18,0x20,0x44,0x04,0x00,0x40,0xba,0x04,0x40,0x00,0xaa,0x04,0x40,0x00,0xba,0x38,0x00,0x00,0x44,0x00,0x00,0x00,0x38,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x28,0x00,0x00,0x28,0x54,0x00,0x00,0x00,0x6c,0x00,0x00,0x44,0xaa,0x00,0x44,0x00,0xaa,0x04,0x40,0x00,0xaa,0x44,0x00,0x00,0xaa,0x3c,0x00,0x00,0x42,0x00,0x00,0x00,0x3c,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x50,0x00,0x00,0x50,0xa8,0x00,0x00,0x00,0x48,0x00,0x00,0x48,0xb4,0x00,0x48,0x00,0xb4,0x08,0x40,0x00,0xb4,0x48,0x00,0x00,0xb4,0x34,0x00,0x00,0x4a,0x00,0x00,0x00,0x34,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x10,0x28,0x00,0x08,0x20,0x54,0x00,0x00,0x00,0x38,0x00,0x08,0x30,0x44,0x04,0x00,0x40,0xba,0x3c,0x40,0x00,0x82,0x00,0x40,0x00,0xbc,0x38,0x00,0x00,0x44,0x00,0x00,0x00,0x38,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x38,0x00,0x08,0x30,0x44,0x04,0x40,0x00,0xba,0x04,0x00,0x00,0x4a,0x08,0x00,0x00,0x14,0x10,0x00,0x00,0x28,0x00,0x00,0x00,0x10,0x10,0x00,0x00,0x28,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x20,0x50,0x00,0x10,0x40,0xa8,0x00,0x00,0x00,0x60,0x00,0x40,0x20,0x90,0x00,0x20,0x00,0x50,0x20,0x00,0x00,0x50,0x20,0x00,0x00,0x50,0x10,0x20,0x40,0x88,0x00,0x00,0x00,0x70,0x00,0x00,0x00,0x00,0x05,
+ 0x00,0x00,0x00,0x38,0x08,0x10,0x20,0x44,0x04,0x00,0x40,0xba,0x04,0x00,0x40,0xba,0x0c,0x70,0x00,0x82,0x04,0x40,0x00,0xba,0x44,0x00,0x00,0xaa,0x44,0x00,0x00,0xaa,0x00,0x00,0x00,0x44,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x78,0x08,0x10,0x60,0x84,0x04,0x00,0x20,0x5a,0x04,0x20,0x00,0x5a,0x28,0x10,0x00,0x44,0x24,0x00,0x00,0x5a,0x24,0x00,0x00,0x5a,0x18,0x20,0x40,0x84,0x00,0x00,0x00,0x78,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x18,0x00,0x18,0x00,0x24,0x04,0x00,0x20,0x5a,0x00,0x00,0x40,0xa4,0x00,0x00,0x40,0xa0,0x00,0x40,0x00,0xa4,0x24,0x00,0x00,0x5a,0x18,0x00,0x00,0x24,0x00,0x00,0x00,0x18,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x70,0x10,0x20,0x40,0x88,0x08,0x20,0x00,0x54,0x04,0x20,0x00,0x5a,0x04,0x20,0x00,0x5a,0x24,0x00,0x00,0x5a,0x28,0x00,0x00,0x54,0x10,0x20,0x40,0x88,0x00,0x00,0x00,0x70,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x7c,0x04,0x18,0x60,0x82,0x04,0x20,0x00,0x5a,0x00,0x20,0x00,0x5c,0x28,0x10,0x00,0x44,0x20,0x00,0x00,0x5c,0x20,0x04,0x00,0x5a,0x0c,0x30,0x40,0x82,0x00,0x00,0x00,0x7c,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x7c,0x04,0x18,0x60,0x82,0x04,0x20,0x00,0x5a,0x00,0x20,0x00,0x5c,0x28,0x10,0x00,0x44,0x20,0x00,0x00,0x58,0x20,0x00,0x00,0x50,0x10,0x20,0x40,0x88,0x00,0x00,0x00,0x70,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x18,0x00,0x18,0x00,0x24,0x04,0x00,0x20,0x5a,0x00,0x40,0x00,0xac,0x00,0x44,0x08,0xb2,0x44,0x00,0x00,0xaa,0x24,0x00,0x00,0x5a,0x1c,0x00,0x00,0x22,0x00,0x00,0x00,0x1c,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x44,0x00,0x00,0x44,0xaa,0x00,0x44,0x00,0xaa,0x04,0x40,0x00,0xba,0x4c,0x30,0x00,0x82,0x44,0x00,0x00,0xba,0x44,0x00,0x00,0xaa,0x44,0x00,0x00,0xaa,0x00,0x00,0x00,0x44,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x7c,0x04,0x38,0x40,0x82,0x00,0x10,0x00,0x6c,0x10,0x00,0x00,0x28,0x10,0x00,0x00,0x28,0x10,0x00,0x00,0x28,0x10,0x00,0x00,0x6c,0x1c,0x20,0x40,0x82,0x00,0x00,0x00,0x7c,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x0c,0x00,0x04,0x08,0x12,0x00,0x04,0x00,0x0a,0x04,0x00,0x00,0x0a,0x04,0x00,0x00,0x4a,0x04,0x00,0x40,0xaa,0x04,0x40,0x00,0xba,0x18,0x20,0x00,0x44,0x00,0x00,0x00,0x38,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x64,0x00,0x24,0x40,0x9a,0x00,0x24,0x00,0x5a,0x20,0x08,0x00,0x54,0x20,0x10,0x00,0x48,0x28,0x00,0x00,0x54,0x24,0x00,0x00,0x5a,0x04,0x20,0x40,0x9a,0x00,0x00,0x00,0x64,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x70,0x00,0x30,0x40,0x88,0x00,0x20,0x00,0x50,0x00,0x20,0x00,0x50,0x00,0x20,0x00,0x50,0x20,0x00,0x00,0x54,0x24,0x00,0x00,0x5a,0x1c,0x20,0x40,0x82,0x00,0x00,0x00,0x7c,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x44,0x00,0x04,0x40,0xaa,0x24,0x40,0x08,0x92,0x04,0x50,0x00,0xaa,0x14,0x40,0x00,0xaa,0x44,0x00,0x00,0xba,0x44,0x00,0x00,0xaa,0x44,0x00,0x00,0xaa,0x00,0x00,0x00,0x44,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x44,0x00,0x00,0x44,0xaa,0x20,0x44,0x00,0x9a,0x14,0x40,0x00,0xaa,0x0c,0x40,0x00,0xb2,0x44,0x00,0x00,0xaa,0x44,0x00,0x00,0xaa,0x44,0x00,0x00,0xaa,0x00,0x00,0x00,0x44,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x38,0x00,0x18,0x20,0x44,0x04,0x00,0x40,0xba,0x04,0x00,0x40,0xaa,0x04,0x40,0x00,0xaa,0x04,0x40,0x00,0xaa,0x04,0x40,0x00,0xba,0x38,0x00,0x00,0x44,0x00,0x00,0x00,0x38,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x78,0x08,0x30,0x40,0x84,0x04,0x20,0x00,0x5a,0x04,0x20,0x00,0x5a,0x28,0x10,0x00,0x44,0x20,0x00,0x00,0x58,0x20,0x00,0x00,0x50,0x10,0x20,0x40,0x88,0x00,0x00,0x00,0x70,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x38,0x08,0x10,0x20,0x44,0x04,0x00,0x40,0xba,0x04,0x00,0x40,0xaa,0x04,0x40,0x00,0xaa,0x04,0x40,0x00,0xba,0x44,0x00,0x10,0xaa,0x30,0x08,0x00,0x44,0x04,0x00,0x00,0x3a,0x00,0x00,0x00,0x04,0x07,
+ 0x00,0x00,0x00,0x78,0x00,0x18,0x60,0x84,0x04,0x20,0x00,0x5a,0x24,0x00,0x00,0x5a,0x28,0x10,0x00,0x44,0x24,0x00,0x00,0x5a,0x24,0x00,0x00,0x5a,0x04,0x20,0x40,0x9a,0x00,0x00,0x00,0x64,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x38,0x00,0x18,0x20,0x44,0x04,0x00,0x40,0xba,0x00,0x40,0x00,0xbc,0x08,0x30,0x00,0x44,0x04,0x00,0x00,0x7a,0x04,0x00,0x40,0xba,0x08,0x30,0x00,0x44,0x00,0x00,0x00,0x38,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x7c,0x04,0x18,0x60,0x82,0x14,0x40,0x00,0xaa,0x10,0x00,0x00,0x6c,0x10,0x00,0x00,0x28,0x10,0x00,0x00,0x28,0x10,0x00,0x00,0x28,0x08,0x10,0x20,0x44,0x00,0x00,0x00,0x38,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x44,0x00,0x00,0x44,0xaa,0x00,0x44,0x00,0xaa,0x04,0x40,0x00,0xaa,0x04,0x40,0x00,0xaa,0x44,0x00,0x00,0xaa,0x44,0x00,0x00,0xba,0x3c,0x00,0x00,0x42,0x00,0x00,0x00,0x3c,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x44,0x00,0x04,0x40,0xaa,0x00,0x44,0x00,0xaa,0x04,0x40,0x00,0xaa,0x28,0x00,0x00,0x54,0x28,0x00,0x00,0x54,0x10,0x00,0x00,0x28,0x10,0x00,0x00,0x28,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x44,0x00,0x00,0x44,0xaa,0x00,0x04,0x40,0xaa,0x04,0x40,0x00,0xaa,0x04,0x40,0x00,0xba,0x54,0x00,0x00,0xaa,0x6c,0x00,0x00,0x92,0x44,0x00,0x00,0xaa,0x00,0x00,0x00,0x44,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x44,0x00,0x00,0x44,0xaa,0x04,0x40,0x00,0xaa,0x28,0x00,0x00,0x54,0x10,0x00,0x00,0x28,0x08,0x20,0x00,0x54,0x04,0x00,0x40,0xaa,0x04,0x40,0x00,0xaa,0x00,0x00,0x00,0x44,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x44,0x04,0x00,0x40,0xaa,0x04,0x40,0x00,0xaa,0x04,0x40,0x00,0xba,0x38,0x00,0x00,0x44,0x10,0x00,0x00,0x28,0x10,0x00,0x00,0x28,0x08,0x10,0x20,0x44,0x00,0x00,0x00,0x38,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x7c,0x04,0x38,0x40,0x82,0x04,0x40,0x00,0xba,0x08,0x00,0x00,0x54,0x10,0x00,0x00,0x28,0x00,0x20,0x00,0x54,0x04,0x00,0x40,0xba,0x3c,0x40,0x00,0x82,0x00,0x00,0x00,0x7c,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x7c,0x04,0x38,0x40,0x82,0x04,0x40,0x00,0xba,0x08,0x00,0x00,0x54,0x10,0x00,0x00,0x28,0x00,0x20,0x00,0x54,0x04,0x00,0x40,0xba,0x3c,0x40,0x00,0x82,0x00,0x00,0x00,0x7c,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x7c,0x04,0x38,0x40,0x82,0x04,0x40,0x00,0xba,0x08,0x00,0x00,0x54,0x10,0x00,0x00,0x28,0x00,0x20,0x00,0x54,0x04,0x00,0x40,0xba,0x3c,0x40,0x00,0x82,0x00,0x00,0x00,0x7c,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x00,0x00,0x48,0xb4,0x00,0x48,0x00,0xb4,0x10,0x00,0x00,0x68,0x00,0x20,0x00,0x58,0x00,0x08,0x40,0xb4,0x08,0x40,0x00,0xb4,0x00,0x00,0x00,0x48,0x00,0x00,0x00,0x00,0x06,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x00,0x08,0x30,0x44,0x04,0x00,0x40,0xa0,0x00,0x40,0x00,0xb8,0x38,0x00,0x00,0x44,0x10,0x00,0x00,0x28,0x00,0x10,0x20,0x48,0x00,0x00,0x00,0x30,0x06,
+ 0x00,0x00,0x00,0x50,0x00,0x00,0x50,0xa8,0x00,0x00,0x00,0x50,0x00,0x40,0x20,0x90,0x00,0x20,0x00,0x50,0x20,0x00,0x00,0x50,0x20,0x00,0x00,0x50,0x10,0x20,0x40,0x88,0x00,0x00,0x00,0x70,0x00,0x00,0x00,0x00,0x05,
+ 0x00,0x00,0x20,0x50,0x00,0x10,0x00,0x28,0x00,0x00,0x00,0x48,0x00,0x00,0x48,0xb4,0x00,0x48,0x00,0xb4,0x08,0x40,0x00,0xb4,0x48,0x00,0x00,0xb4,0x34,0x00,0x00,0x4a,0x00,0x00,0x00,0x34,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x00,0x28,0x10,0x44,0x04,0x00,0x00,0x3a,0x04,0x08,0x30,0x42,0x04,0x40,0x00,0xba,0x3c,0x00,0x00,0x42,0x00,0x00,0x00,0x3c,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x60,0x00,0x20,0x40,0x90,0x00,0x20,0x00,0x58,0x00,0x28,0x00,0x54,0x04,0x20,0x10,0x4a,0x04,0x20,0x00,0x5a,0x04,0x20,0x00,0x5a,0x18,0x20,0x00,0x44,0x00,0x00,0x00,0x38,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x00,0x08,0x30,0x44,0x04,0x00,0x40,0xba,0x00,0x40,0x00,0xa4,0x04,0x40,0x00,0xba,0x38,0x00,0x00,0x44,0x00,0x00,0x00,0x38,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x0c,0x00,0x04,0x08,0x12,0x08,0x00,0x00,0x34,0x08,0x20,0x00,0x54,0x18,0x40,0x00,0xa4,0x08,0x40,0x00,0xb4,0x08,0x40,0x00,0xb4,0x38,0x00,0x00,0x44,0x00,0x00,0x00,0x38,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x00,0x08,0x30,0x44,0x04,0x00,0x40,0xba,0x3c,0x40,0x00,0x82,0x00,0x40,0x00,0xbc,0x38,0x00,0x00,0x44,0x00,0x00,0x00,0x38,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x18,0x00,0x08,0x10,0x24,0x04,0x00,0x20,0x5a,0x00,0x20,0x00,0x54,0x10,0x20,0x40,0x88,0x20,0x00,0x00,0x50,0x20,0x00,0x00,0x50,0x30,0x40,0x00,0x88,0x00,0x00,0x00,0x70,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x34,0x04,0x10,0x20,0x4a,0x08,0x00,0x40,0xb4,0x08,0x40,0x00,0xb4,0x38,0x00,0x00,0x44,0x04,0x00,0x40,0xba,0x18,0x20,0x00,0x44,0x00,0x00,0x00,0x38,0x07,
+ 0x00,0x00,0x00,0x60,0x00,0x20,0x40,0x90,0x00,0x20,0x00,0x58,0x20,0x08,0x00,0x54,0x24,0x00,0x10,0x4a,0x24,0x00,0x00,0x5a,0x24,0x00,0x00,0x5a,0x04,0x20,0x40,0x9a,0x00,0x00,0x00,0x64,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x20,0x00,0x00,0x20,0x50,0x00,0x00,0x00,0x60,0x00,0x40,0x20,0x90,0x00,0x20,0x00,0x50,0x20,0x00,0x00,0x50,0x20,0x00,0x00,0x50,0x10,0x20,0x40,0x88,0x00,0x00,0x00,0x70,0x00,0x00,0x00,0x00,0x05,
+ 0x00,0x00,0x00,0x04,0x00,0x00,0x04,0x0a,0x00,0x00,0x00,0x04,0x00,0x00,0x04,0x0a,0x00,0x04,0x00,0x0a,0x04,0x00,0x00,0x0a,0x04,0x00,0x00,0x4a,0x04,0x00,0x40,0xba,0x18,0x20,0x00,0x44,0x00,0x00,0x00,0x38,0x07,
+ 0x00,0x00,0x00,0x60,0x00,0x00,0x60,0x90,0x00,0x20,0x00,0x54,0x20,0x04,0x00,0x5a,0x20,0x00,0x08,0x54,0x20,0x10,0x00,0x48,0x28,0x00,0x00,0x54,0x04,0x20,0x40,0x9a,0x00,0x00,0x00,0x64,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x60,0x00,0x20,0x40,0x90,0x00,0x20,0x00,0x50,0x20,0x00,0x00,0x50,0x20,0x00,0x00,0x50,0x20,0x00,0x00,0x50,0x20,0x00,0x00,0x50,0x10,0x20,0x40,0x88,0x00,0x00,0x00,0x70,0x00,0x00,0x00,0x00,0x05,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x00,0x00,0x48,0xb4,0x24,0x48,0x00,0x92,0x44,0x10,0x00,0xaa,0x44,0x00,0x00,0xba,0x44,0x00,0x00,0xaa,0x00,0x00,0x00,0x44,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x78,0x08,0x10,0x60,0x84,0x04,0x00,0x40,0xba,0x04,0x40,0x00,0xaa,0x44,0x00,0x00,0xaa,0x44,0x00,0x00,0xaa,0x00,0x00,0x00,0x44,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x08,0x10,0x20,0x44,0x04,0x00,0x40,0xba,0x04,0x40,0x00,0xaa,0x44,0x00,0x00,0xba,0x38,0x00,0x00,0x44,0x00,0x00,0x00,0x38,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x58,0x00,0x08,0x50,0xa4,0x04,0x20,0x00,0x5a,0x24,0x00,0x00,0x5a,0x38,0x00,0x00,0x44,0x20,0x00,0x00,0x58,0x10,0x20,0x40,0x88,0x00,0x00,0x00,0x70,0x07,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x34,0x00,0x14,0x20,0x4a,0x08,0x40,0x00,0xb4,0x48,0x00,0x00,0xb4,0x38,0x00,0x00,0x44,0x08,0x00,0x00,0x34,0x04,0x08,0x10,0x22,0x00,0x00,0x00,0x1c,0x07,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x58,0x00,0x08,0x50,0xa4,0x04,0x20,0x00,0x5a,0x24,0x00,0x00,0x5a,0x20,0x00,0x00,0x54,0x10,0x20,0x40,0x88,0x00,0x00,0x00,0x70,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3c,0x04,0x18,0x20,0x42,0x00,0x40,0x00,0xbc,0x38,0x00,0x00,0x44,0x04,0x00,0x00,0x7a,0x38,0x00,0x40,0x84,0x00,0x00,0x00,0x78,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x20,0x00,0x00,0x20,0x50,0x00,0x20,0x00,0x58,0x08,0x30,0x40,0x84,0x20,0x00,0x00,0x58,0x20,0x00,0x00,0x54,0x04,0x20,0x00,0x5a,0x08,0x10,0x00,0x24,0x00,0x00,0x00,0x18,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x00,0x00,0x48,0xb4,0x00,0x48,0x00,0xb4,0x08,0x40,0x00,0xb4,0x48,0x00,0x00,0xb4,0x34,0x00,0x00,0x4a,0x00,0x00,0x00,0x34,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x44,0x00,0x00,0x44,0xaa,0x00,0x44,0x00,0xaa,0x04,0x40,0x00,0xaa,0x28,0x00,0x00,0x54,0x10,0x00,0x00,0x28,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x44,0x00,0x00,0x44,0xaa,0x00,0x44,0x00,0xba,0x14,0x40,0x00,0xaa,0x2c,0x40,0x00,0x92,0x48,0x00,0x00,0xb4,0x00,0x00,0x00,0x48,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x44,0x00,0x00,0x44,0xaa,0x00,0x28,0x00,0x54,0x10,0x00,0x00,0x28,0x08,0x20,0x00,0x54,0x04,0x40,0x00,0xaa,0x00,0x00,0x00,0x44,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x44,0x00,0x00,0x44,0xaa,0x00,0x44,0x00,0xaa,0x04,0x40,0x00,0xba,0x38,0x00,0x00,0x44,0x00,0x10,0x00,0x68,0x00,0x20,0x40,0x90,0x00,0x00,0x00,0x60,0x07,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7c,0x04,0x38,0x40,0x82,0x08,0x40,0x00,0xb4,0x00,0x10,0x00,0x6c,0x04,0x20,0x00,0x5a,0x3c,0x00,0x40,0x82,0x00,0x00,0x00,0x7c,0x00,0x00,0x00,0x00,0x07
+};
+
+static const byte french_simon1AGAFontData[] = {
+ 0x00,0x00,0x00,0x20,0x00,0x00,0x20,0x50,0x20,0x10,0x40,0x88,0x30,0x40,0x00,0x88,0x20,0x00,0x00,0x50,0x20,0x00,0x00,0x50,0x00,0x00,0x00,0x20,0x00,0x00,0x20,0x50,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x00,0x05,
+ 0x00,0x00,0x00,0x30,0x00,0x10,0x20,0x48,0x10,0x20,0x00,0x48,0x20,0x40,0x00,0x90,0x00,0x00,0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05,
+ 0x00,0x00,0x10,0x28,0x00,0x08,0x20,0x54,0x00,0x00,0x00,0x38,0x08,0x10,0x20,0x44,0x04,0x00,0x40,0xba,0x04,0x40,0x00,0xaa,0x44,0x00,0x00,0xba,0x38,0x00,0x00,0x44,0x00,0x00,0x00,0x38,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x10,0x28,0x00,0x08,0x20,0x54,0x00,0x00,0x00,0x38,0x00,0x28,0x10,0x44,0x04,0x00,0x00,0x3a,0x04,0x08,0x30,0x42,0x04,0x40,0x00,0xba,0x3c,0x00,0x00,0x42,0x00,0x00,0x00,0x3c,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x38,0x00,0x08,0x30,0x44,0x04,0x00,0x40,0xba,0x00,0x40,0x00,0xa4,0x00,0x40,0x00,0xa0,0x04,0x40,0x00,0xba,0x38,0x00,0x00,0x44,0x10,0x00,0x00,0x28,0x00,0x10,0x20,0x48,0x00,0x00,0x00,0x30,0x07,
+ 0x00,0x00,0x00,0x20,0x00,0x00,0x20,0x50,0x10,0x00,0x40,0xa8,0x18,0x20,0x00,0x44,0x10,0x00,0x00,0x28,0x18,0x20,0x00,0x44,0x10,0x00,0x40,0xac,0x0c,0x20,0x00,0x52,0x00,0x00,0x00,0x2c,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x30,0x00,0x10,0x20,0x48,0x10,0x20,0x00,0x48,0x20,0x40,0x00,0x90,0x00,0x00,0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05,
+ 0x00,0x00,0x00,0x28,0x00,0x00,0x28,0x54,0x00,0x28,0x00,0x54,0x1c,0x20,0x40,0x82,0x28,0x00,0x00,0x54,0x1c,0x20,0x40,0x82,0x28,0x00,0x00,0x54,0x28,0x00,0x00,0x54,0x00,0x00,0x00,0x28,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x28,0x00,0x00,0x28,0x54,0x00,0x28,0x00,0x54,0x1c,0x20,0x40,0x82,0x28,0x00,0x00,0x54,0x1c,0x20,0x40,0x82,0x28,0x00,0x00,0x54,0x28,0x00,0x00,0x54,0x00,0x00,0x00,0x28,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x28,0x00,0x00,0x28,0x54,0x00,0x28,0x00,0x54,0x1c,0x20,0x40,0x82,0x28,0x00,0x00,0x54,0x1c,0x20,0x40,0x82,0x28,0x00,0x00,0x54,0x28,0x00,0x00,0x54,0x00,0x00,0x00,0x28,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x38,0x00,0x08,0x30,0x44,0x04,0x00,0x40,0xba,0x00,0x40,0x00,0xa4,0x00,0x40,0x00,0xa0,0x04,0x40,0x00,0xba,0x38,0x00,0x00,0x44,0x10,0x00,0x00,0x28,0x00,0x10,0x20,0x48,0x00,0x00,0x00,0x30,0x07,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x10,0x20,0x48,0x10,0x20,0x00,0x48,0x20,0x40,0x00,0x90,0x00,0x00,0x00,0x60,0x05,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x78,0x18,0x20,0x40,0x84,0x00,0x00,0x00,0x78,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x00,0x20,0x40,0x90,0x20,0x40,0x00,0x90,0x00,0x00,0x00,0x60,0x00,0x00,0x00,0x00,0x04,
+ 0x00,0x00,0x10,0x28,0x00,0x00,0x20,0x50,0x00,0x00,0x00,0x38,0x00,0x08,0x30,0x44,0x04,0x00,0x40,0xba,0x3c,0x40,0x00,0x82,0x00,0x40,0x00,0xbc,0x38,0x00,0x00,0x44,0x00,0x00,0x00,0x38,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x38,0x00,0x18,0x20,0x44,0x04,0x00,0x40,0xba,0x0c,0x00,0x40,0xb2,0x04,0x50,0x00,0xaa,0x44,0x20,0x00,0x9a,0x44,0x00,0x00,0xba,0x38,0x00,0x00,0x44,0x00,0x00,0x00,0x38,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x20,0x00,0x00,0x20,0x50,0x00,0x20,0x40,0x90,0x00,0x20,0x00,0x50,0x20,0x00,0x00,0x50,0x20,0x00,0x00,0x50,0x20,0x00,0x00,0x50,0x10,0x20,0x40,0x88,0x00,0x00,0x00,0x70,0x00,0x00,0x00,0x00,0x05,
+ 0x00,0x00,0x00,0x38,0x00,0x08,0x30,0x44,0x04,0x00,0x40,0xba,0x04,0x00,0x00,0x5a,0x08,0x10,0x00,0x24,0x00,0x20,0x00,0x5c,0x00,0x04,0x40,0xba,0x3c,0x40,0x00,0x82,0x00,0x00,0x00,0x7c,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x38,0x08,0x10,0x20,0x44,0x04,0x00,0x40,0xba,0x04,0x00,0x00,0x5a,0x00,0x08,0x10,0x24,0x04,0x00,0x00,0x5a,0x04,0x00,0x40,0xba,0x18,0x20,0x00,0x44,0x00,0x00,0x00,0x38,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x08,0x00,0x08,0x00,0x14,0x08,0x00,0x10,0x24,0x08,0x00,0x20,0x54,0x08,0x40,0x00,0xb4,0x3c,0x40,0x00,0x82,0x08,0x00,0x00,0x74,0x04,0x08,0x10,0x22,0x00,0x00,0x00,0x1c,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x7c,0x04,0x18,0x60,0x82,0x00,0x40,0x00,0xbc,0x78,0x00,0x00,0x84,0x04,0x00,0x00,0x7a,0x04,0x00,0x00,0x4a,0x04,0x00,0x40,0xba,0x18,0x20,0x00,0x44,0x00,0x00,0x00,0x38,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x18,0x08,0x10,0x00,0x24,0x00,0x00,0x20,0x58,0x00,0x40,0x00,0xb8,0x38,0x40,0x00,0x84,0x44,0x00,0x00,0xba,0x44,0x00,0x00,0xba,0x38,0x00,0x00,0x44,0x00,0x00,0x00,0x38,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x7c,0x04,0x38,0x40,0x82,0x04,0x40,0x00,0xba,0x00,0x04,0x00,0x4a,0x00,0x00,0x08,0x14,0x00,0x10,0x00,0x28,0x00,0x10,0x00,0x28,0x10,0x00,0x00,0x28,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x38,0x00,0x18,0x20,0x44,0x04,0x00,0x40,0xba,0x04,0x40,0x00,0xba,0x18,0x20,0x00,0x44,0x04,0x00,0x40,0xba,0x04,0x40,0x00,0xba,0x38,0x00,0x00,0x44,0x00,0x00,0x00,0x38,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x38,0x00,0x18,0x20,0x44,0x04,0x00,0x40,0xba,0x04,0x40,0x00,0xba,0x1c,0x20,0x00,0x42,0x04,0x00,0x00,0x3a,0x00,0x08,0x00,0x34,0x00,0x10,0x20,0x48,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x00,0x20,0x40,0x90,0x20,0x40,0x00,0x90,0x00,0x00,0x00,0x60,0x00,0x00,0x00,0x60,0x00,0x20,0x40,0x90,0x20,0x40,0x00,0x90,0x00,0x00,0x00,0x60,0x00,0x00,0x00,0x00,0x04,
+ 0x00,0x00,0x10,0x28,0x00,0x08,0x00,0x14,0x00,0x00,0x00,0x38,0x00,0x28,0x10,0x44,0x04,0x00,0x00,0x3a,0x04,0x08,0x30,0x42,0x04,0x40,0x00,0xba,0x3c,0x00,0x00,0x42,0x00,0x00,0x00,0x3c,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x20,0x50,0x00,0x10,0x40,0xa8,0x00,0x00,0x00,0x48,0x00,0x00,0x48,0xb4,0x00,0x48,0x00,0xb4,0x08,0x40,0x00,0xb4,0x48,0x00,0x00,0xb4,0x34,0x00,0x00,0x4a,0x00,0x00,0x00,0x34,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x10,0x28,0x00,0x08,0x00,0x14,0x00,0x00,0x00,0x38,0x00,0x08,0x30,0x44,0x04,0x00,0x40,0xba,0x3c,0x40,0x00,0x82,0x00,0x40,0x00,0xbc,0x38,0x00,0x00,0x44,0x00,0x00,0x00,0x38,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x10,0x28,0x00,0x08,0x20,0x54,0x00,0x00,0x00,0x38,0x00,0x08,0x30,0x44,0x04,0x00,0x40,0xba,0x3c,0x40,0x00,0x82,0x00,0x40,0x00,0xbc,0x38,0x00,0x00,0x44,0x00,0x00,0x00,0x38,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x38,0x00,0x08,0x30,0x44,0x04,0x40,0x00,0xba,0x04,0x00,0x00,0x4a,0x08,0x00,0x00,0x14,0x10,0x00,0x00,0x28,0x00,0x00,0x00,0x10,0x10,0x00,0x00,0x28,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x20,0x50,0x00,0x10,0x40,0xa8,0x00,0x00,0x00,0x60,0x00,0x40,0x20,0x90,0x00,0x20,0x00,0x50,0x20,0x00,0x00,0x50,0x20,0x00,0x00,0x50,0x10,0x20,0x40,0x88,0x00,0x00,0x00,0x70,0x00,0x00,0x00,0x00,0x05,
+ 0x00,0x00,0x00,0x38,0x08,0x10,0x20,0x44,0x04,0x00,0x40,0xba,0x04,0x00,0x40,0xba,0x0c,0x70,0x00,0x82,0x04,0x40,0x00,0xba,0x44,0x00,0x00,0xaa,0x44,0x00,0x00,0xaa,0x00,0x00,0x00,0x44,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x78,0x08,0x10,0x60,0x84,0x04,0x00,0x20,0x5a,0x04,0x20,0x00,0x5a,0x28,0x10,0x00,0x44,0x24,0x00,0x00,0x5a,0x24,0x00,0x00,0x5a,0x18,0x20,0x40,0x84,0x00,0x00,0x00,0x78,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x18,0x00,0x18,0x00,0x24,0x04,0x00,0x20,0x5a,0x00,0x00,0x40,0xa4,0x00,0x00,0x40,0xa0,0x00,0x40,0x00,0xa4,0x24,0x00,0x00,0x5a,0x18,0x00,0x00,0x24,0x00,0x00,0x00,0x18,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x70,0x10,0x20,0x40,0x88,0x08,0x20,0x00,0x54,0x04,0x20,0x00,0x5a,0x04,0x20,0x00,0x5a,0x24,0x00,0x00,0x5a,0x28,0x00,0x00,0x54,0x10,0x20,0x40,0x88,0x00,0x00,0x00,0x70,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x7c,0x04,0x18,0x60,0x82,0x04,0x20,0x00,0x5a,0x00,0x20,0x00,0x5c,0x28,0x10,0x00,0x44,0x20,0x00,0x00,0x5c,0x20,0x04,0x00,0x5a,0x0c,0x30,0x40,0x82,0x00,0x00,0x00,0x7c,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x7c,0x04,0x18,0x60,0x82,0x04,0x20,0x00,0x5a,0x00,0x20,0x00,0x5c,0x28,0x10,0x00,0x44,0x20,0x00,0x00,0x58,0x20,0x00,0x00,0x50,0x10,0x20,0x40,0x88,0x00,0x00,0x00,0x70,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x18,0x00,0x18,0x00,0x24,0x04,0x00,0x20,0x5a,0x00,0x40,0x00,0xac,0x00,0x44,0x08,0xb2,0x44,0x00,0x00,0xaa,0x24,0x00,0x00,0x5a,0x1c,0x00,0x00,0x22,0x00,0x00,0x00,0x1c,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x44,0x00,0x00,0x44,0xaa,0x00,0x44,0x00,0xaa,0x04,0x40,0x00,0xba,0x4c,0x30,0x00,0x82,0x44,0x00,0x00,0xba,0x44,0x00,0x00,0xaa,0x44,0x00,0x00,0xaa,0x00,0x00,0x00,0x44,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x7c,0x04,0x38,0x40,0x82,0x00,0x10,0x00,0x6c,0x10,0x00,0x00,0x28,0x10,0x00,0x00,0x28,0x10,0x00,0x00,0x28,0x10,0x00,0x00,0x6c,0x1c,0x20,0x40,0x82,0x00,0x00,0x00,0x7c,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x0c,0x00,0x04,0x08,0x12,0x00,0x04,0x00,0x0a,0x04,0x00,0x00,0x0a,0x04,0x00,0x00,0x4a,0x04,0x00,0x40,0xaa,0x04,0x40,0x00,0xba,0x18,0x20,0x00,0x44,0x00,0x00,0x00,0x38,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x64,0x00,0x24,0x40,0x9a,0x00,0x24,0x00,0x5a,0x20,0x08,0x00,0x54,0x20,0x10,0x00,0x48,0x28,0x00,0x00,0x54,0x24,0x00,0x00,0x5a,0x04,0x20,0x40,0x9a,0x00,0x00,0x00,0x64,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x70,0x00,0x30,0x40,0x88,0x00,0x20,0x00,0x50,0x00,0x20,0x00,0x50,0x00,0x20,0x00,0x50,0x20,0x00,0x00,0x54,0x24,0x00,0x00,0x5a,0x1c,0x20,0x40,0x82,0x00,0x00,0x00,0x7c,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x44,0x00,0x04,0x40,0xaa,0x24,0x40,0x08,0x92,0x04,0x50,0x00,0xaa,0x14,0x40,0x00,0xaa,0x44,0x00,0x00,0xba,0x44,0x00,0x00,0xaa,0x44,0x00,0x00,0xaa,0x00,0x00,0x00,0x44,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x44,0x00,0x00,0x44,0xaa,0x20,0x44,0x00,0x9a,0x14,0x40,0x00,0xaa,0x0c,0x40,0x00,0xb2,0x44,0x00,0x00,0xaa,0x44,0x00,0x00,0xaa,0x44,0x00,0x00,0xaa,0x00,0x00,0x00,0x44,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x38,0x00,0x18,0x20,0x44,0x04,0x00,0x40,0xba,0x04,0x00,0x40,0xaa,0x04,0x40,0x00,0xaa,0x04,0x40,0x00,0xaa,0x04,0x40,0x00,0xba,0x38,0x00,0x00,0x44,0x00,0x00,0x00,0x38,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x78,0x08,0x30,0x40,0x84,0x04,0x20,0x00,0x5a,0x04,0x20,0x00,0x5a,0x28,0x10,0x00,0x44,0x20,0x00,0x00,0x58,0x20,0x00,0x00,0x50,0x10,0x20,0x40,0x88,0x00,0x00,0x00,0x70,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x38,0x08,0x10,0x20,0x44,0x04,0x00,0x40,0xba,0x04,0x00,0x40,0xaa,0x04,0x40,0x00,0xaa,0x04,0x40,0x00,0xba,0x44,0x00,0x10,0xaa,0x30,0x08,0x00,0x44,0x04,0x00,0x00,0x3a,0x00,0x00,0x00,0x04,0x07,
+ 0x00,0x00,0x00,0x78,0x00,0x18,0x60,0x84,0x04,0x20,0x00,0x5a,0x24,0x00,0x00,0x5a,0x28,0x10,0x00,0x44,0x24,0x00,0x00,0x5a,0x24,0x00,0x00,0x5a,0x04,0x20,0x40,0x9a,0x00,0x00,0x00,0x64,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x38,0x00,0x18,0x20,0x44,0x04,0x00,0x40,0xba,0x00,0x40,0x00,0xbc,0x08,0x30,0x00,0x44,0x04,0x00,0x00,0x7a,0x04,0x00,0x40,0xba,0x08,0x30,0x00,0x44,0x00,0x00,0x00,0x38,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x7c,0x04,0x18,0x60,0x82,0x14,0x40,0x00,0xaa,0x10,0x00,0x00,0x6c,0x10,0x00,0x00,0x28,0x10,0x00,0x00,0x28,0x10,0x00,0x00,0x28,0x08,0x10,0x20,0x44,0x00,0x00,0x00,0x38,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x44,0x00,0x00,0x44,0xaa,0x00,0x44,0x00,0xaa,0x04,0x40,0x00,0xaa,0x04,0x40,0x00,0xaa,0x44,0x00,0x00,0xaa,0x44,0x00,0x00,0xba,0x3c,0x00,0x00,0x42,0x00,0x00,0x00,0x3c,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x44,0x00,0x04,0x40,0xaa,0x00,0x44,0x00,0xaa,0x04,0x40,0x00,0xaa,0x28,0x00,0x00,0x54,0x28,0x00,0x00,0x54,0x10,0x00,0x00,0x28,0x10,0x00,0x00,0x28,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x44,0x00,0x00,0x44,0xaa,0x00,0x04,0x40,0xaa,0x04,0x40,0x00,0xaa,0x04,0x40,0x00,0xba,0x54,0x00,0x00,0xaa,0x6c,0x00,0x00,0x92,0x44,0x00,0x00,0xaa,0x00,0x00,0x00,0x44,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x44,0x00,0x00,0x44,0xaa,0x04,0x40,0x00,0xaa,0x28,0x00,0x00,0x54,0x10,0x00,0x00,0x28,0x08,0x20,0x00,0x54,0x04,0x00,0x40,0xaa,0x04,0x40,0x00,0xaa,0x00,0x00,0x00,0x44,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x44,0x04,0x00,0x40,0xaa,0x04,0x40,0x00,0xaa,0x04,0x40,0x00,0xba,0x38,0x00,0x00,0x44,0x10,0x00,0x00,0x28,0x10,0x00,0x00,0x28,0x08,0x10,0x20,0x44,0x00,0x00,0x00,0x38,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x7c,0x04,0x38,0x40,0x82,0x04,0x40,0x00,0xba,0x08,0x00,0x00,0x54,0x10,0x00,0x00,0x28,0x00,0x20,0x00,0x54,0x04,0x00,0x40,0xba,0x3c,0x40,0x00,0x82,0x00,0x00,0x00,0x7c,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x7c,0x04,0x38,0x40,0x82,0x04,0x40,0x00,0xba,0x08,0x00,0x00,0x54,0x10,0x00,0x00,0x28,0x00,0x20,0x00,0x54,0x04,0x00,0x40,0xba,0x3c,0x40,0x00,0x82,0x00,0x00,0x00,0x7c,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x7c,0x04,0x38,0x40,0x82,0x04,0x40,0x00,0xba,0x08,0x00,0x00,0x54,0x10,0x00,0x00,0x28,0x00,0x20,0x00,0x54,0x04,0x00,0x40,0xba,0x3c,0x40,0x00,0x82,0x00,0x00,0x00,0x7c,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x00,0x00,0x48,0xb4,0x00,0x48,0x00,0xb4,0x10,0x00,0x00,0x68,0x00,0x20,0x00,0x58,0x00,0x08,0x40,0xb4,0x08,0x40,0x00,0xb4,0x00,0x00,0x00,0x48,0x00,0x00,0x00,0x00,0x06,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x00,0x08,0x30,0x44,0x04,0x00,0x40,0xa0,0x00,0x40,0x00,0xb8,0x38,0x00,0x00,0x44,0x10,0x00,0x00,0x28,0x00,0x10,0x20,0x48,0x00,0x00,0x00,0x30,0x06,
+ 0x00,0x00,0x00,0x50,0x00,0x00,0x50,0xa8,0x00,0x00,0x00,0x50,0x00,0x40,0x20,0x90,0x00,0x20,0x00,0x50,0x20,0x00,0x00,0x50,0x20,0x00,0x00,0x50,0x10,0x20,0x40,0x88,0x00,0x00,0x00,0x70,0x00,0x00,0x00,0x00,0x05,
+ 0x00,0x00,0x20,0x50,0x00,0x10,0x00,0x28,0x00,0x00,0x00,0x48,0x00,0x00,0x48,0xb4,0x00,0x48,0x00,0xb4,0x08,0x40,0x00,0xb4,0x48,0x00,0x00,0xb4,0x34,0x00,0x00,0x4a,0x00,0x00,0x00,0x34,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x00,0x28,0x10,0x44,0x04,0x00,0x00,0x3a,0x04,0x08,0x30,0x42,0x04,0x40,0x00,0xba,0x3c,0x00,0x00,0x42,0x00,0x00,0x00,0x3c,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x60,0x00,0x20,0x40,0x90,0x00,0x20,0x00,0x58,0x00,0x28,0x00,0x54,0x04,0x20,0x10,0x4a,0x04,0x20,0x00,0x5a,0x04,0x20,0x00,0x5a,0x18,0x20,0x00,0x44,0x00,0x00,0x00,0x38,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x00,0x08,0x30,0x44,0x04,0x00,0x40,0xba,0x00,0x40,0x00,0xa4,0x04,0x40,0x00,0xba,0x38,0x00,0x00,0x44,0x00,0x00,0x00,0x38,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x0c,0x00,0x04,0x08,0x12,0x08,0x00,0x00,0x34,0x08,0x20,0x00,0x54,0x18,0x40,0x00,0xa4,0x08,0x40,0x00,0xb4,0x08,0x40,0x00,0xb4,0x38,0x00,0x00,0x44,0x00,0x00,0x00,0x38,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x00,0x08,0x30,0x44,0x04,0x00,0x40,0xba,0x3c,0x40,0x00,0x82,0x00,0x40,0x00,0xbc,0x38,0x00,0x00,0x44,0x00,0x00,0x00,0x38,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x18,0x00,0x08,0x10,0x24,0x04,0x00,0x20,0x5a,0x00,0x20,0x00,0x54,0x10,0x20,0x40,0x88,0x20,0x00,0x00,0x50,0x20,0x00,0x00,0x50,0x30,0x40,0x00,0x88,0x00,0x00,0x00,0x70,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x34,0x04,0x10,0x20,0x4a,0x08,0x00,0x40,0xb4,0x08,0x40,0x00,0xb4,0x38,0x00,0x00,0x44,0x04,0x00,0x40,0xba,0x18,0x20,0x00,0x44,0x00,0x00,0x00,0x38,0x07,
+ 0x00,0x00,0x00,0x60,0x00,0x20,0x40,0x90,0x00,0x20,0x00,0x58,0x20,0x08,0x00,0x54,0x24,0x00,0x10,0x4a,0x24,0x00,0x00,0x5a,0x24,0x00,0x00,0x5a,0x04,0x20,0x40,0x9a,0x00,0x00,0x00,0x64,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x20,0x00,0x00,0x20,0x50,0x00,0x00,0x00,0x60,0x00,0x40,0x20,0x90,0x00,0x20,0x00,0x50,0x20,0x00,0x00,0x50,0x20,0x00,0x00,0x50,0x10,0x20,0x40,0x88,0x00,0x00,0x00,0x70,0x00,0x00,0x00,0x00,0x05,
+ 0x00,0x00,0x00,0x04,0x00,0x00,0x04,0x0a,0x00,0x00,0x00,0x04,0x00,0x00,0x04,0x0a,0x00,0x04,0x00,0x0a,0x04,0x00,0x00,0x0a,0x04,0x00,0x00,0x4a,0x04,0x00,0x40,0xba,0x18,0x20,0x00,0x44,0x00,0x00,0x00,0x38,0x07,
+ 0x00,0x00,0x00,0x60,0x00,0x00,0x60,0x90,0x00,0x20,0x00,0x54,0x20,0x04,0x00,0x5a,0x20,0x00,0x08,0x54,0x20,0x10,0x00,0x48,0x28,0x00,0x00,0x54,0x04,0x20,0x40,0x9a,0x00,0x00,0x00,0x64,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x60,0x00,0x20,0x40,0x90,0x00,0x20,0x00,0x50,0x20,0x00,0x00,0x50,0x20,0x00,0x00,0x50,0x20,0x00,0x00,0x50,0x20,0x00,0x00,0x50,0x10,0x20,0x40,0x88,0x00,0x00,0x00,0x70,0x00,0x00,0x00,0x00,0x05,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x00,0x00,0x48,0xb4,0x24,0x48,0x00,0x92,0x44,0x10,0x00,0xaa,0x44,0x00,0x00,0xba,0x44,0x00,0x00,0xaa,0x00,0x00,0x00,0x44,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x78,0x08,0x10,0x60,0x84,0x04,0x00,0x40,0xba,0x04,0x40,0x00,0xaa,0x44,0x00,0x00,0xaa,0x44,0x00,0x00,0xaa,0x00,0x00,0x00,0x44,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x08,0x10,0x20,0x44,0x04,0x00,0x40,0xba,0x04,0x40,0x00,0xaa,0x44,0x00,0x00,0xba,0x38,0x00,0x00,0x44,0x00,0x00,0x00,0x38,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x58,0x00,0x08,0x50,0xa4,0x04,0x20,0x00,0x5a,0x24,0x00,0x00,0x5a,0x38,0x00,0x00,0x44,0x20,0x00,0x00,0x58,0x10,0x20,0x40,0x88,0x00,0x00,0x00,0x70,0x07,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x34,0x00,0x14,0x20,0x4a,0x08,0x40,0x00,0xb4,0x48,0x00,0x00,0xb4,0x38,0x00,0x00,0x44,0x08,0x00,0x00,0x34,0x04,0x08,0x10,0x22,0x00,0x00,0x00,0x1c,0x07,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x58,0x00,0x08,0x50,0xa4,0x04,0x20,0x00,0x5a,0x24,0x00,0x00,0x5a,0x20,0x00,0x00,0x54,0x10,0x20,0x40,0x88,0x00,0x00,0x00,0x70,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3c,0x04,0x18,0x20,0x42,0x00,0x40,0x00,0xbc,0x38,0x00,0x00,0x44,0x04,0x00,0x00,0x7a,0x38,0x00,0x40,0x84,0x00,0x00,0x00,0x78,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x20,0x00,0x00,0x20,0x50,0x00,0x20,0x00,0x58,0x08,0x30,0x40,0x84,0x20,0x00,0x00,0x58,0x20,0x00,0x00,0x54,0x04,0x20,0x00,0x5a,0x08,0x10,0x00,0x24,0x00,0x00,0x00,0x18,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x00,0x00,0x48,0xb4,0x00,0x48,0x00,0xb4,0x08,0x40,0x00,0xb4,0x48,0x00,0x00,0xb4,0x34,0x00,0x00,0x4a,0x00,0x00,0x00,0x34,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x44,0x00,0x00,0x44,0xaa,0x00,0x44,0x00,0xaa,0x04,0x40,0x00,0xaa,0x28,0x00,0x00,0x54,0x10,0x00,0x00,0x28,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x44,0x00,0x00,0x44,0xaa,0x00,0x44,0x00,0xba,0x14,0x40,0x00,0xaa,0x2c,0x40,0x00,0x92,0x48,0x00,0x00,0xb4,0x00,0x00,0x00,0x48,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x44,0x00,0x00,0x44,0xaa,0x00,0x28,0x00,0x54,0x10,0x00,0x00,0x28,0x08,0x20,0x00,0x54,0x04,0x40,0x00,0xaa,0x00,0x00,0x00,0x44,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x44,0x00,0x00,0x44,0xaa,0x00,0x44,0x00,0xaa,0x04,0x40,0x00,0xba,0x38,0x00,0x00,0x44,0x00,0x10,0x00,0x68,0x00,0x20,0x40,0x90,0x00,0x00,0x00,0x60,0x07,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7c,0x04,0x38,0x40,0x82,0x08,0x40,0x00,0xb4,0x00,0x10,0x00,0x6c,0x04,0x20,0x00,0x5a,0x3c,0x00,0x40,0x82,0x00,0x00,0x00,0x7c,0x00,0x00,0x00,0x00,0x07
+};
+
+static const byte italian_simon1AGAFontData[] = {
+ 0x00,0x00,0x00,0x20,0x00,0x00,0x20,0x50,0x20,0x10,0x40,0x88,0x30,0x40,0x00,0x88,0x20,0x00,0x00,0x50,0x20,0x00,0x00,0x50,0x00,0x00,0x00,0x20,0x00,0x00,0x20,0x50,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x00,0x05,
+ 0x00,0x00,0x00,0x30,0x00,0x10,0x20,0x48,0x10,0x20,0x00,0x48,0x20,0x40,0x00,0x90,0x00,0x00,0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05,
+ 0x00,0x00,0x00,0x28,0x00,0x00,0x28,0x54,0x00,0x00,0x00,0x38,0x00,0x28,0x10,0x44,0x04,0x00,0x00,0x3a,0x04,0x08,0x30,0x42,0x04,0x40,0x00,0xba,0x3c,0x00,0x00,0x42,0x00,0x00,0x00,0x3c,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x28,0x00,0x00,0x28,0x54,0x00,0x00,0x00,0x38,0x08,0x10,0x20,0x44,0x04,0x00,0x40,0xba,0x04,0x40,0x00,0xaa,0x44,0x00,0x00,0xba,0x38,0x00,0x00,0x44,0x00,0x00,0x00,0x38,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x10,0x28,0x00,0x08,0x00,0x14,0x00,0x00,0x00,0x38,0x08,0x10,0x20,0x44,0x04,0x00,0x40,0xba,0x04,0x40,0x00,0xaa,0x44,0x00,0x00,0xba,0x38,0x00,0x00,0x44,0x00,0x00,0x00,0x38,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x20,0x00,0x00,0x20,0x50,0x10,0x00,0x40,0xa8,0x18,0x20,0x00,0x44,0x10,0x00,0x00,0x28,0x18,0x20,0x00,0x44,0x10,0x00,0x40,0xac,0x0c,0x20,0x00,0x52,0x00,0x00,0x00,0x2c,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x30,0x00,0x10,0x20,0x48,0x10,0x20,0x00,0x48,0x20,0x40,0x00,0x90,0x00,0x00,0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05,
+ 0x00,0x00,0x00,0x28,0x00,0x00,0x28,0x54,0x00,0x28,0x00,0x54,0x1c,0x20,0x40,0x82,0x28,0x00,0x00,0x54,0x1c,0x20,0x40,0x82,0x28,0x00,0x00,0x54,0x28,0x00,0x00,0x54,0x00,0x00,0x00,0x28,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x28,0x00,0x00,0x28,0x54,0x00,0x28,0x00,0x54,0x1c,0x20,0x40,0x82,0x28,0x00,0x00,0x54,0x1c,0x20,0x40,0x82,0x28,0x00,0x00,0x54,0x28,0x00,0x00,0x54,0x00,0x00,0x00,0x28,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x28,0x00,0x00,0x28,0x54,0x00,0x28,0x00,0x54,0x1c,0x20,0x40,0x82,0x28,0x00,0x00,0x54,0x1c,0x20,0x40,0x82,0x28,0x00,0x00,0x54,0x28,0x00,0x00,0x54,0x00,0x00,0x00,0x28,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x20,0x50,0x00,0x10,0x00,0x28,0x00,0x00,0x00,0x60,0x00,0x40,0x20,0x90,0x00,0x20,0x00,0x50,0x20,0x00,0x00,0x50,0x20,0x00,0x00,0x50,0x10,0x20,0x40,0x88,0x00,0x00,0x00,0x70,0x00,0x00,0x00,0x00,0x05,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x10,0x20,0x48,0x10,0x20,0x00,0x48,0x20,0x40,0x00,0x90,0x00,0x00,0x00,0x60,0x05,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x78,0x18,0x20,0x40,0x84,0x00,0x00,0x00,0x78,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x00,0x20,0x40,0x90,0x20,0x40,0x00,0x90,0x00,0x00,0x00,0x60,0x00,0x00,0x00,0x00,0x04,
+ 0x00,0x00,0x10,0x28,0x00,0x00,0x20,0x50,0x00,0x00,0x00,0x38,0x00,0x08,0x30,0x44,0x04,0x00,0x40,0xba,0x3c,0x40,0x00,0x82,0x00,0x40,0x00,0xbc,0x38,0x00,0x00,0x44,0x00,0x00,0x00,0x38,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x38,0x00,0x18,0x20,0x44,0x04,0x00,0x40,0xba,0x0c,0x00,0x40,0xb2,0x04,0x50,0x00,0xaa,0x44,0x20,0x00,0x9a,0x44,0x00,0x00,0xba,0x38,0x00,0x00,0x44,0x00,0x00,0x00,0x38,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x20,0x00,0x00,0x20,0x50,0x00,0x20,0x40,0x90,0x00,0x20,0x00,0x50,0x20,0x00,0x00,0x50,0x20,0x00,0x00,0x50,0x20,0x00,0x00,0x50,0x10,0x20,0x40,0x88,0x00,0x00,0x00,0x70,0x00,0x00,0x00,0x00,0x05,
+ 0x00,0x00,0x00,0x38,0x00,0x08,0x30,0x44,0x04,0x00,0x40,0xba,0x04,0x00,0x00,0x5a,0x08,0x10,0x00,0x24,0x00,0x20,0x00,0x5c,0x00,0x04,0x40,0xba,0x3c,0x40,0x00,0x82,0x00,0x00,0x00,0x7c,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x38,0x08,0x10,0x20,0x44,0x04,0x00,0x40,0xba,0x04,0x00,0x00,0x5a,0x00,0x08,0x10,0x24,0x04,0x00,0x00,0x5a,0x04,0x00,0x40,0xba,0x18,0x20,0x00,0x44,0x00,0x00,0x00,0x38,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x08,0x00,0x08,0x00,0x14,0x08,0x00,0x10,0x24,0x08,0x00,0x20,0x54,0x08,0x40,0x00,0xb4,0x3c,0x40,0x00,0x82,0x08,0x00,0x00,0x74,0x04,0x08,0x10,0x22,0x00,0x00,0x00,0x1c,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x7c,0x04,0x18,0x60,0x82,0x00,0x40,0x00,0xbc,0x78,0x00,0x00,0x84,0x04,0x00,0x00,0x7a,0x04,0x00,0x00,0x4a,0x04,0x00,0x40,0xba,0x18,0x20,0x00,0x44,0x00,0x00,0x00,0x38,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x18,0x08,0x10,0x00,0x24,0x00,0x00,0x20,0x58,0x00,0x40,0x00,0xb8,0x38,0x40,0x00,0x84,0x44,0x00,0x00,0xba,0x44,0x00,0x00,0xba,0x38,0x00,0x00,0x44,0x00,0x00,0x00,0x38,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x7c,0x04,0x38,0x40,0x82,0x04,0x40,0x00,0xba,0x00,0x04,0x00,0x4a,0x00,0x00,0x08,0x14,0x00,0x10,0x00,0x28,0x00,0x10,0x00,0x28,0x10,0x00,0x00,0x28,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x38,0x00,0x18,0x20,0x44,0x04,0x00,0x40,0xba,0x04,0x40,0x00,0xba,0x18,0x20,0x00,0x44,0x04,0x00,0x40,0xba,0x04,0x40,0x00,0xba,0x38,0x00,0x00,0x44,0x00,0x00,0x00,0x38,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x38,0x00,0x18,0x20,0x44,0x04,0x00,0x40,0xba,0x04,0x40,0x00,0xba,0x1c,0x20,0x00,0x42,0x04,0x00,0x00,0x3a,0x00,0x08,0x00,0x34,0x00,0x10,0x20,0x48,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x00,0x20,0x40,0x90,0x20,0x40,0x00,0x90,0x00,0x00,0x00,0x60,0x00,0x00,0x00,0x60,0x00,0x20,0x40,0x90,0x20,0x40,0x00,0x90,0x00,0x00,0x00,0x60,0x00,0x00,0x00,0x00,0x04,
+ 0x00,0x00,0x10,0x28,0x00,0x08,0x00,0x14,0x00,0x00,0x00,0x38,0x00,0x28,0x10,0x44,0x04,0x00,0x00,0x3a,0x04,0x08,0x30,0x42,0x04,0x40,0x00,0xba,0x3c,0x00,0x00,0x42,0x00,0x00,0x00,0x3c,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x10,0x28,0x00,0x08,0x00,0x14,0x00,0x00,0x00,0x38,0x08,0x10,0x20,0x44,0x04,0x00,0x40,0xba,0x04,0x40,0x00,0xaa,0x44,0x00,0x00,0xba,0x38,0x00,0x00,0x44,0x00,0x00,0x00,0x38,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x10,0x28,0x00,0x08,0x00,0x14,0x00,0x00,0x00,0x38,0x00,0x08,0x30,0x44,0x04,0x00,0x40,0xba,0x3c,0x40,0x00,0x82,0x00,0x40,0x00,0xbc,0x38,0x00,0x00,0x44,0x00,0x00,0x00,0x38,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x10,0x28,0x00,0x08,0x20,0x54,0x00,0x00,0x00,0x38,0x00,0x08,0x30,0x44,0x04,0x00,0x40,0xba,0x3c,0x40,0x00,0x82,0x00,0x40,0x00,0xbc,0x38,0x00,0x00,0x44,0x00,0x00,0x00,0x38,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x38,0x00,0x08,0x30,0x44,0x04,0x40,0x00,0xba,0x04,0x00,0x00,0x4a,0x08,0x00,0x00,0x14,0x10,0x00,0x00,0x28,0x00,0x00,0x00,0x10,0x10,0x00,0x00,0x28,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x20,0x50,0x00,0x10,0x40,0xa8,0x00,0x00,0x00,0x60,0x00,0x40,0x20,0x90,0x00,0x20,0x00,0x50,0x20,0x00,0x00,0x50,0x20,0x00,0x00,0x50,0x10,0x20,0x40,0x88,0x00,0x00,0x00,0x70,0x00,0x00,0x00,0x00,0x05,
+ 0x00,0x00,0x00,0x38,0x08,0x10,0x20,0x44,0x04,0x00,0x40,0xba,0x04,0x00,0x40,0xba,0x0c,0x70,0x00,0x82,0x04,0x40,0x00,0xba,0x44,0x00,0x00,0xaa,0x44,0x00,0x00,0xaa,0x00,0x00,0x00,0x44,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x78,0x08,0x10,0x60,0x84,0x04,0x00,0x20,0x5a,0x04,0x20,0x00,0x5a,0x28,0x10,0x00,0x44,0x24,0x00,0x00,0x5a,0x24,0x00,0x00,0x5a,0x18,0x20,0x40,0x84,0x00,0x00,0x00,0x78,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x18,0x00,0x18,0x00,0x24,0x04,0x00,0x20,0x5a,0x00,0x00,0x40,0xa4,0x00,0x00,0x40,0xa0,0x00,0x40,0x00,0xa4,0x24,0x00,0x00,0x5a,0x18,0x00,0x00,0x24,0x00,0x00,0x00,0x18,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x70,0x10,0x20,0x40,0x88,0x08,0x20,0x00,0x54,0x04,0x20,0x00,0x5a,0x04,0x20,0x00,0x5a,0x24,0x00,0x00,0x5a,0x28,0x00,0x00,0x54,0x10,0x20,0x40,0x88,0x00,0x00,0x00,0x70,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x7c,0x04,0x18,0x60,0x82,0x04,0x20,0x00,0x5a,0x00,0x20,0x00,0x5c,0x28,0x10,0x00,0x44,0x20,0x00,0x00,0x5c,0x20,0x04,0x00,0x5a,0x0c,0x30,0x40,0x82,0x00,0x00,0x00,0x7c,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x7c,0x04,0x18,0x60,0x82,0x04,0x20,0x00,0x5a,0x00,0x20,0x00,0x5c,0x28,0x10,0x00,0x44,0x20,0x00,0x00,0x58,0x20,0x00,0x00,0x50,0x10,0x20,0x40,0x88,0x00,0x00,0x00,0x70,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x18,0x00,0x18,0x00,0x24,0x04,0x00,0x20,0x5a,0x00,0x40,0x00,0xac,0x00,0x44,0x08,0xb2,0x44,0x00,0x00,0xaa,0x24,0x00,0x00,0x5a,0x1c,0x00,0x00,0x22,0x00,0x00,0x00,0x1c,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x44,0x00,0x00,0x44,0xaa,0x00,0x44,0x00,0xaa,0x04,0x40,0x00,0xba,0x4c,0x30,0x00,0x82,0x44,0x00,0x00,0xba,0x44,0x00,0x00,0xaa,0x44,0x00,0x00,0xaa,0x00,0x00,0x00,0x44,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x7c,0x04,0x38,0x40,0x82,0x00,0x10,0x00,0x6c,0x10,0x00,0x00,0x28,0x10,0x00,0x00,0x28,0x10,0x00,0x00,0x28,0x10,0x00,0x00,0x6c,0x1c,0x20,0x40,0x82,0x00,0x00,0x00,0x7c,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x0c,0x00,0x04,0x08,0x12,0x00,0x04,0x00,0x0a,0x04,0x00,0x00,0x0a,0x04,0x00,0x00,0x4a,0x04,0x00,0x40,0xaa,0x04,0x40,0x00,0xba,0x18,0x20,0x00,0x44,0x00,0x00,0x00,0x38,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x64,0x00,0x24,0x40,0x9a,0x00,0x24,0x00,0x5a,0x20,0x08,0x00,0x54,0x20,0x10,0x00,0x48,0x28,0x00,0x00,0x54,0x24,0x00,0x00,0x5a,0x04,0x20,0x40,0x9a,0x00,0x00,0x00,0x64,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x70,0x00,0x30,0x40,0x88,0x00,0x20,0x00,0x50,0x00,0x20,0x00,0x50,0x00,0x20,0x00,0x50,0x20,0x00,0x00,0x54,0x24,0x00,0x00,0x5a,0x1c,0x20,0x40,0x82,0x00,0x00,0x00,0x7c,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x44,0x00,0x04,0x40,0xaa,0x24,0x40,0x08,0x92,0x04,0x50,0x00,0xaa,0x14,0x40,0x00,0xaa,0x44,0x00,0x00,0xba,0x44,0x00,0x00,0xaa,0x44,0x00,0x00,0xaa,0x00,0x00,0x00,0x44,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x44,0x00,0x00,0x44,0xaa,0x20,0x44,0x00,0x9a,0x14,0x40,0x00,0xaa,0x0c,0x40,0x00,0xb2,0x44,0x00,0x00,0xaa,0x44,0x00,0x00,0xaa,0x44,0x00,0x00,0xaa,0x00,0x00,0x00,0x44,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x38,0x00,0x18,0x20,0x44,0x04,0x00,0x40,0xba,0x04,0x00,0x40,0xaa,0x04,0x40,0x00,0xaa,0x04,0x40,0x00,0xaa,0x04,0x40,0x00,0xba,0x38,0x00,0x00,0x44,0x00,0x00,0x00,0x38,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x78,0x08,0x30,0x40,0x84,0x04,0x20,0x00,0x5a,0x04,0x20,0x00,0x5a,0x28,0x10,0x00,0x44,0x20,0x00,0x00,0x58,0x20,0x00,0x00,0x50,0x10,0x20,0x40,0x88,0x00,0x00,0x00,0x70,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x38,0x08,0x10,0x20,0x44,0x04,0x00,0x40,0xba,0x04,0x00,0x40,0xaa,0x04,0x40,0x00,0xaa,0x04,0x40,0x00,0xba,0x44,0x00,0x10,0xaa,0x30,0x08,0x00,0x44,0x04,0x00,0x00,0x3a,0x00,0x00,0x00,0x04,0x07,
+ 0x00,0x00,0x00,0x78,0x00,0x18,0x60,0x84,0x04,0x20,0x00,0x5a,0x24,0x00,0x00,0x5a,0x28,0x10,0x00,0x44,0x24,0x00,0x00,0x5a,0x24,0x00,0x00,0x5a,0x04,0x20,0x40,0x9a,0x00,0x00,0x00,0x64,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x38,0x00,0x18,0x20,0x44,0x04,0x00,0x40,0xba,0x00,0x40,0x00,0xbc,0x08,0x30,0x00,0x44,0x04,0x00,0x00,0x7a,0x04,0x00,0x40,0xba,0x08,0x30,0x00,0x44,0x00,0x00,0x00,0x38,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x7c,0x04,0x18,0x60,0x82,0x14,0x40,0x00,0xaa,0x10,0x00,0x00,0x6c,0x10,0x00,0x00,0x28,0x10,0x00,0x00,0x28,0x10,0x00,0x00,0x28,0x08,0x10,0x20,0x44,0x00,0x00,0x00,0x38,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x44,0x00,0x00,0x44,0xaa,0x00,0x44,0x00,0xaa,0x04,0x40,0x00,0xaa,0x04,0x40,0x00,0xaa,0x44,0x00,0x00,0xaa,0x44,0x00,0x00,0xba,0x3c,0x00,0x00,0x42,0x00,0x00,0x00,0x3c,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x44,0x00,0x04,0x40,0xaa,0x00,0x44,0x00,0xaa,0x04,0x40,0x00,0xaa,0x28,0x00,0x00,0x54,0x28,0x00,0x00,0x54,0x10,0x00,0x00,0x28,0x10,0x00,0x00,0x28,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x44,0x00,0x00,0x44,0xaa,0x00,0x04,0x40,0xaa,0x04,0x40,0x00,0xaa,0x04,0x40,0x00,0xba,0x54,0x00,0x00,0xaa,0x6c,0x00,0x00,0x92,0x44,0x00,0x00,0xaa,0x00,0x00,0x00,0x44,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x44,0x00,0x00,0x44,0xaa,0x04,0x40,0x00,0xaa,0x28,0x00,0x00,0x54,0x10,0x00,0x00,0x28,0x08,0x20,0x00,0x54,0x04,0x00,0x40,0xaa,0x04,0x40,0x00,0xaa,0x00,0x00,0x00,0x44,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x44,0x04,0x00,0x40,0xaa,0x04,0x40,0x00,0xaa,0x04,0x40,0x00,0xba,0x38,0x00,0x00,0x44,0x10,0x00,0x00,0x28,0x10,0x00,0x00,0x28,0x08,0x10,0x20,0x44,0x00,0x00,0x00,0x38,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x7c,0x04,0x38,0x40,0x82,0x04,0x40,0x00,0xba,0x08,0x00,0x00,0x54,0x10,0x00,0x00,0x28,0x00,0x20,0x00,0x54,0x04,0x00,0x40,0xba,0x3c,0x40,0x00,0x82,0x00,0x00,0x00,0x7c,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x7c,0x04,0x38,0x40,0x82,0x04,0x40,0x00,0xba,0x08,0x00,0x00,0x54,0x10,0x00,0x00,0x28,0x00,0x20,0x00,0x54,0x04,0x00,0x40,0xba,0x3c,0x40,0x00,0x82,0x00,0x00,0x00,0x7c,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x7c,0x04,0x38,0x40,0x82,0x04,0x40,0x00,0xba,0x08,0x00,0x00,0x54,0x10,0x00,0x00,0x28,0x00,0x20,0x00,0x54,0x04,0x00,0x40,0xba,0x3c,0x40,0x00,0x82,0x00,0x00,0x00,0x7c,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x00,0x00,0x48,0xb4,0x00,0x48,0x00,0xb4,0x10,0x00,0x00,0x68,0x00,0x20,0x00,0x58,0x00,0x08,0x40,0xb4,0x08,0x40,0x00,0xb4,0x00,0x00,0x00,0x48,0x00,0x00,0x00,0x00,0x06,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x00,0x08,0x30,0x44,0x04,0x00,0x40,0xa0,0x00,0x40,0x00,0xb8,0x38,0x00,0x00,0x44,0x10,0x00,0x00,0x28,0x00,0x10,0x20,0x48,0x00,0x00,0x00,0x30,0x06,
+ 0x00,0x00,0x00,0x50,0x00,0x00,0x50,0xa8,0x00,0x00,0x00,0x50,0x00,0x40,0x20,0x90,0x00,0x20,0x00,0x50,0x20,0x00,0x00,0x50,0x20,0x00,0x00,0x50,0x10,0x20,0x40,0x88,0x00,0x00,0x00,0x70,0x00,0x00,0x00,0x00,0x05,
+ 0x00,0x00,0x20,0x50,0x00,0x10,0x00,0x28,0x00,0x00,0x00,0x48,0x00,0x00,0x48,0xb4,0x00,0x48,0x00,0xb4,0x08,0x40,0x00,0xb4,0x48,0x00,0x00,0xb4,0x34,0x00,0x00,0x4a,0x00,0x00,0x00,0x34,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x00,0x28,0x10,0x44,0x04,0x00,0x00,0x3a,0x04,0x08,0x30,0x42,0x04,0x40,0x00,0xba,0x3c,0x00,0x00,0x42,0x00,0x00,0x00,0x3c,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x60,0x00,0x20,0x40,0x90,0x00,0x20,0x00,0x58,0x00,0x28,0x00,0x54,0x04,0x20,0x10,0x4a,0x04,0x20,0x00,0x5a,0x04,0x20,0x00,0x5a,0x18,0x20,0x00,0x44,0x00,0x00,0x00,0x38,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x00,0x08,0x30,0x44,0x04,0x00,0x40,0xba,0x00,0x40,0x00,0xa4,0x04,0x40,0x00,0xba,0x38,0x00,0x00,0x44,0x00,0x00,0x00,0x38,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x0c,0x00,0x04,0x08,0x12,0x08,0x00,0x00,0x34,0x08,0x20,0x00,0x54,0x18,0x40,0x00,0xa4,0x08,0x40,0x00,0xb4,0x08,0x40,0x00,0xb4,0x38,0x00,0x00,0x44,0x00,0x00,0x00,0x38,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x00,0x08,0x30,0x44,0x04,0x00,0x40,0xba,0x3c,0x40,0x00,0x82,0x00,0x40,0x00,0xbc,0x38,0x00,0x00,0x44,0x00,0x00,0x00,0x38,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x18,0x00,0x08,0x10,0x24,0x04,0x00,0x20,0x5a,0x00,0x20,0x00,0x54,0x10,0x20,0x40,0x88,0x20,0x00,0x00,0x50,0x20,0x00,0x00,0x50,0x30,0x40,0x00,0x88,0x00,0x00,0x00,0x70,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x34,0x04,0x10,0x20,0x4a,0x08,0x00,0x40,0xb4,0x08,0x40,0x00,0xb4,0x38,0x00,0x00,0x44,0x04,0x00,0x40,0xba,0x18,0x20,0x00,0x44,0x00,0x00,0x00,0x38,0x07,
+ 0x00,0x00,0x00,0x60,0x00,0x20,0x40,0x90,0x00,0x20,0x00,0x58,0x20,0x08,0x00,0x54,0x24,0x00,0x10,0x4a,0x24,0x00,0x00,0x5a,0x24,0x00,0x00,0x5a,0x04,0x20,0x40,0x9a,0x00,0x00,0x00,0x64,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x20,0x00,0x00,0x20,0x50,0x00,0x00,0x00,0x60,0x00,0x40,0x20,0x90,0x00,0x20,0x00,0x50,0x20,0x00,0x00,0x50,0x20,0x00,0x00,0x50,0x10,0x20,0x40,0x88,0x00,0x00,0x00,0x70,0x00,0x00,0x00,0x00,0x05,
+ 0x00,0x00,0x00,0x04,0x00,0x00,0x04,0x0a,0x00,0x00,0x00,0x04,0x00,0x00,0x04,0x0a,0x00,0x04,0x00,0x0a,0x04,0x00,0x00,0x0a,0x04,0x00,0x00,0x4a,0x04,0x00,0x40,0xba,0x18,0x20,0x00,0x44,0x00,0x00,0x00,0x38,0x07,
+ 0x00,0x00,0x00,0x60,0x00,0x00,0x60,0x90,0x00,0x20,0x00,0x54,0x20,0x04,0x00,0x5a,0x20,0x00,0x08,0x54,0x20,0x10,0x00,0x48,0x28,0x00,0x00,0x54,0x04,0x20,0x40,0x9a,0x00,0x00,0x00,0x64,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x60,0x00,0x20,0x40,0x90,0x00,0x20,0x00,0x50,0x20,0x00,0x00,0x50,0x20,0x00,0x00,0x50,0x20,0x00,0x00,0x50,0x20,0x00,0x00,0x50,0x10,0x20,0x40,0x88,0x00,0x00,0x00,0x70,0x00,0x00,0x00,0x00,0x05,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x00,0x00,0x48,0xb4,0x24,0x48,0x00,0x92,0x44,0x10,0x00,0xaa,0x44,0x00,0x00,0xba,0x44,0x00,0x00,0xaa,0x00,0x00,0x00,0x44,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x78,0x08,0x10,0x60,0x84,0x04,0x00,0x40,0xba,0x04,0x40,0x00,0xaa,0x44,0x00,0x00,0xaa,0x44,0x00,0x00,0xaa,0x00,0x00,0x00,0x44,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x08,0x10,0x20,0x44,0x04,0x00,0x40,0xba,0x04,0x40,0x00,0xaa,0x44,0x00,0x00,0xba,0x38,0x00,0x00,0x44,0x00,0x00,0x00,0x38,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x58,0x00,0x08,0x50,0xa4,0x04,0x20,0x00,0x5a,0x24,0x00,0x00,0x5a,0x38,0x00,0x00,0x44,0x20,0x00,0x00,0x58,0x10,0x20,0x40,0x88,0x00,0x00,0x00,0x70,0x07,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x34,0x00,0x14,0x20,0x4a,0x08,0x40,0x00,0xb4,0x48,0x00,0x00,0xb4,0x38,0x00,0x00,0x44,0x08,0x00,0x00,0x34,0x04,0x08,0x10,0x22,0x00,0x00,0x00,0x1c,0x07,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x58,0x00,0x08,0x50,0xa4,0x04,0x20,0x00,0x5a,0x24,0x00,0x00,0x5a,0x20,0x00,0x00,0x54,0x10,0x20,0x40,0x88,0x00,0x00,0x00,0x70,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3c,0x04,0x18,0x20,0x42,0x00,0x40,0x00,0xbc,0x38,0x00,0x00,0x44,0x04,0x00,0x00,0x7a,0x38,0x00,0x40,0x84,0x00,0x00,0x00,0x78,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x20,0x00,0x00,0x20,0x50,0x00,0x20,0x00,0x58,0x08,0x30,0x40,0x84,0x20,0x00,0x00,0x58,0x20,0x00,0x00,0x54,0x04,0x20,0x00,0x5a,0x08,0x10,0x00,0x24,0x00,0x00,0x00,0x18,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x00,0x00,0x48,0xb4,0x00,0x48,0x00,0xb4,0x08,0x40,0x00,0xb4,0x48,0x00,0x00,0xb4,0x34,0x00,0x00,0x4a,0x00,0x00,0x00,0x34,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x44,0x00,0x00,0x44,0xaa,0x00,0x44,0x00,0xaa,0x04,0x40,0x00,0xaa,0x28,0x00,0x00,0x54,0x10,0x00,0x00,0x28,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x44,0x00,0x00,0x44,0xaa,0x00,0x44,0x00,0xba,0x14,0x40,0x00,0xaa,0x2c,0x40,0x00,0x92,0x48,0x00,0x00,0xb4,0x00,0x00,0x00,0x48,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x44,0x00,0x00,0x44,0xaa,0x00,0x28,0x00,0x54,0x10,0x00,0x00,0x28,0x08,0x20,0x00,0x54,0x04,0x40,0x00,0xaa,0x00,0x00,0x00,0x44,0x00,0x00,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x44,0x00,0x00,0x44,0xaa,0x00,0x44,0x00,0xaa,0x04,0x40,0x00,0xba,0x38,0x00,0x00,0x44,0x00,0x10,0x00,0x68,0x00,0x20,0x40,0x90,0x00,0x00,0x00,0x60,0x07,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7c,0x04,0x38,0x40,0x82,0x08,0x40,0x00,0xb4,0x00,0x10,0x00,0x6c,0x04,0x20,0x00,0x5a,0x3c,0x00,0x40,0x82,0x00,0x00,0x00,0x7c,0x00,0x00,0x00,0x00,0x07
+};
+
+void AGOSEngine::renderStringAmiga(uint vgaSpriteId, uint color, uint width, uint height, const char *txt) {
+ VgaPointersEntry *vpe = &_vgaBufferPointers[2];
+ byte *p, *dst, *dst_org, chr;
+ uint count;
+
+ if (vgaSpriteId >= 100) {
+ vgaSpriteId -= 100;
+ vpe++;
+ }
+
+ dst = vpe->vgaFile2;
+
+ count = 2000;
+ if (vgaSpriteId == 1)
+ count *= 2;
+
+ p = dst + vgaSpriteId * 8;
+ WRITE_BE_UINT16(p + 4, height);
+ WRITE_BE_UINT16(p + 6, width);
+ dst += READ_BE_UINT32(p);
+
+ width /= 8; // convert width from pixels to bytes
+
+ const byte *imgSrc = NULL;
+ switch (_language) {
+ case Common::IT_ITA:
+ imgSrc = italian_simon1AGAFontData;
+ break;
+ case Common::FR_FRA:
+ imgSrc = french_simon1AGAFontData;
+ break;
+ case Common::DE_DEU:
+ imgSrc = german_simon1AGAFontData;
+ break;
+ case Common::EN_ANY:
+ imgSrc = english_simon1AGAFontData;
+ break;
+ default:
+ error("renderStringAmiga: Unknown language %d", _language);
+ }
+
+
+ uint charsize = width * height;
+ memset(dst, 0, count);
+ dst_org = dst;
+ int delta = 0;
+ while ((chr = *txt++) != 0) {
+ int img_width = 1;
+ if (chr == 10) {
+ dst += width * 10;
+ dst_org = dst;
+ delta = 0;
+ } else if ((signed char)(chr -= '!') < 0) {
+ img_width = 7;
+ } else {
+ const byte *img = imgSrc + chr * 41;
+ img_width = img[40];
+ byte *cur_dst = dst_org;
+ for (int row = 0; row < 10; row++) {
+ int col = color;
+ for (int plane = 0; plane < 3; plane++) {
+ chr = img[plane] >> delta;
+ if (chr) {
+ if (col & 1) cur_dst[charsize * 0] |= chr;
+ if (col & 2) cur_dst[charsize * 1] |= chr;
+ if (col & 4) cur_dst[charsize * 2] |= chr;
+ if (col & 8) cur_dst[charsize * 3] |= chr;
+ }
+ chr = img[plane] << (8 - delta);
+ if (((8 - delta) < img_width) && (chr)) {
+ if (col & 1) cur_dst[charsize * 0 + 1] |= chr;
+ if (col & 2) cur_dst[charsize * 1 + 1] |= chr;
+ if (col & 4) cur_dst[charsize * 2 + 1] |= chr;
+ if (col & 8) cur_dst[charsize * 3 + 1] |= chr;
+ }
+ col++;
+ }
+ chr = img[3] >> delta;
+ if (chr) {
+ cur_dst[charsize * 0] |= chr;
+ cur_dst[charsize * 1] |= chr;
+ cur_dst[charsize * 2] |= chr;
+ cur_dst[charsize * 3] |= chr;
+ }
+ chr = img[3] << (8 - delta);
+ if (((8 - delta) < img_width) && (chr)) {
+ cur_dst[charsize * 0 + 1] |= chr;
+ cur_dst[charsize * 1 + 1] |= chr;
+ cur_dst[charsize * 2 + 1] |= chr;
+ cur_dst[charsize * 3 + 1] |= chr;
+ }
+ cur_dst += width;
+ img += 4;
+ }
+ }
+ delta += img_width - 1;
+ if (delta >= 8) {
+ delta -= 8;
+ dst_org++;
+ }
+ }
+}
+
+void AGOSEngine::renderString(uint vgaSpriteId, uint color, uint width, uint height, const char *txt) {
+ VgaPointersEntry *vpe = &_vgaBufferPointers[2];
+ byte *src, *dst, *p, *dst_org, chr;
+ const int textHeight = (getGameType() == GType_FF || getGameType() == GType_PP) ? 15: 10;
+ uint count = 0;
+
+ if (vgaSpriteId >= 100) {
+ vgaSpriteId -= 100;
+ vpe++;
+ }
+
+ src = dst = vpe->vgaFile2;
+
+ if (getGameType() == GType_FF || getGameType() == GType_PP) {
+ if (vgaSpriteId == 1)
+ count = 45000;
+ } else {
+ count = 4000;
+ if (vgaSpriteId == 1)
+ count *= 2;
+ }
+
+ p = dst + vgaSpriteId * 8;
+
+ if (getGameType() == GType_FF || getGameType() == GType_PP) {
+ if (vgaSpriteId != 1)
+ WRITE_LE_UINT32(p, READ_LE_UINT32(p - 8) + READ_LE_UINT16(p - 4) * READ_LE_UINT16(p - 2));
+
+ WRITE_LE_UINT16(p + 4, height);
+ WRITE_LE_UINT16(p + 6, width);
+ } else {
+ WRITE_BE_UINT16(p + 4, height);
+ WRITE_BE_UINT16(p + 6, width);
+ }
+ dst += readUint32Wrapper(p);
+
+ if (count != 0)
+ memset(dst, 0, count);
+
+ if (_language == Common::HE_ISR)
+ dst += width - 1; // For Hebrew, start at the right edge, not the left.
+
+ dst_org = dst;
+ while ((chr = *txt++) != 0) {
+ if (chr == 10) {
+ dst_org += width * textHeight;
+ dst = dst_org;
+ } else if ((chr -= ' ') == 0) {
+ dst += (_language == Common::HE_ISR ? -6 : 6); // Hebrew moves to the left, all others to the right
+ } else {
+ byte *img_hdr, *img;
+ uint i, img_width, img_height;
+
+ if (getGameType() == GType_FF || getGameType() == GType_PP) {
+ img_hdr = src + 96 + chr * 8;
+ img_height = READ_LE_UINT16(img_hdr + 4);
+ img_width = READ_LE_UINT16(img_hdr + 6);
+ img = src + READ_LE_UINT32(img_hdr);
+ } else {
+ img_hdr = src + 48 + chr * 4;
+ img_height = img_hdr[2];
+ img_width = img_hdr[3];
+ img = src + READ_LE_UINT16(img_hdr);
+ }
+
+ if (_language == Common::HE_ISR)
+ dst -= img_width - 1; // For Hebrew, move from right edge to left edge of image.
+ byte *cur_dst = dst;
+
+ // Occurs in Amiga and Macintosh ports of The Feeble Files, when
+ // special characters are used by French/German/Spanish versions.
+ // Due to the English image data, been used by all languages.
+ if (img_width == 0 || img_height == 0)
+ continue;
+
+ assert(img_width < 50 && img_height < 50);
+
+ do {
+ for (i = 0; i != img_width; i++) {
+ chr = *img++;
+ if (chr) {
+ if (chr == 0xF)
+ chr = 207;
+ else
+ chr += color;
+ cur_dst[i] = chr;
+ }
+ }
+ cur_dst += width;
+ } while (--img_height);
+
+ if (_language != Common::HE_ISR) // Hebrew character movement is done higher up
+ dst += img_width - 1;
+ }
+ }
+}
+
void AGOSEngine_Feeble::windowDrawChar(WindowBlock *window, uint x, uint y, byte chr) {
const byte *src;
byte color, *dst;
diff --git a/engines/agos/charset.cpp b/engines/agos/charset.cpp
index 54aef99a47..f58f4397b5 100644
--- a/engines/agos/charset.cpp
+++ b/engines/agos/charset.cpp
@@ -20,7 +20,6 @@
*
*/
-#include "common/endian.h"
#include "common/system.h"
#include "agos/agos.h"
@@ -99,280 +98,6 @@ void AGOSEngine::tidyIconArray(uint i) {
}
}
-static const byte simon_agaFont[] = {
- 0x00,0x00,0x00,0x20,0x00,0x00,0x20,0x50,0x20,0x10,0x40,0x88,0x30,0x40,0x00,0x88,0x20,0x00,0x00,0x50,0x20,0x00,0x00,0x50,0x00,0x00,0x00,0x20,0x00,0x00,0x20,0x50,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x00,0x05,
- 0x00,0x00,0x00,0x30,0x00,0x10,0x20,0x48,0x10,0x20,0x00,0x48,0x20,0x40,0x00,0x90,0x00,0x00,0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05,
- 0x00,0x00,0x00,0x28,0x00,0x00,0x28,0x54,0x00,0x28,0x00,0x54,0x1C,0x20,0x40,0x82,0x28,0x00,0x00,0x54,0x1C,0x20,0x40,0x82,0x28,0x00,0x00,0x54,0x28,0x00,0x00,0x54,0x00,0x00,0x00,0x28,0x00,0x00,0x00,0x00,0x07,
- 0x00,0x00,0x00,0x10,0x00,0x00,0x10,0x28,0x08,0x10,0x20,0x44,0x00,0x40,0x00,0xB8,0x30,0x00,0x00,0x48,0x08,0x00,0x00,0x74,0x30,0x00,0x40,0x88,0x20,0x00,0x00,0x50,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x00,0x06,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x00,0x00,0x48,0xB4,0x00,0x48,0x00,0xB4,0x10,0x00,0x00,0x68,0x00,0x20,0x00,0x58,0x00,0x08,0x40,0xB4,0x08,0x40,0x00,0xB4,0x00,0x00,0x00,0x48,0x00,0x00,0x00,0x00,0x06,
- 0x00,0x00,0x00,0x20,0x00,0x00,0x20,0x50,0x10,0x00,0x40,0xA8,0x18,0x20,0x00,0x44,0x10,0x00,0x00,0x28,0x18,0x20,0x00,0x44,0x10,0x00,0x40,0xAC,0x0C,0x20,0x00,0x52,0x00,0x00,0x00,0x2C,0x00,0x00,0x00,0x00,0x07,
- 0x00,0x00,0x00,0x30,0x00,0x10,0x20,0x48,0x10,0x20,0x00,0x48,0x20,0x40,0x00,0x90,0x00,0x00,0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05,
- 0x00,0x00,0x00,0x28,0x00,0x00,0x28,0x54,0x00,0x28,0x00,0x54,0x1C,0x20,0x40,0x82,0x28,0x00,0x00,0x54,0x1C,0x20,0x40,0x82,0x28,0x00,0x00,0x54,0x28,0x00,0x00,0x54,0x00,0x00,0x00,0x28,0x00,0x00,0x00,0x00,0x07,
- 0x00,0x00,0x00,0x28,0x00,0x00,0x28,0x54,0x00,0x28,0x00,0x54,0x1C,0x20,0x40,0x82,0x28,0x00,0x00,0x54,0x1C,0x20,0x40,0x82,0x28,0x00,0x00,0x54,0x28,0x00,0x00,0x54,0x00,0x00,0x00,0x28,0x00,0x00,0x00,0x00,0x07,
- 0x00,0x00,0x00,0x28,0x00,0x00,0x28,0x54,0x00,0x28,0x00,0x54,0x1C,0x20,0x40,0x82,0x28,0x00,0x00,0x54,0x1C,0x20,0x40,0x82,0x28,0x00,0x00,0x54,0x28,0x00,0x00,0x54,0x00,0x00,0x00,0x28,0x00,0x00,0x00,0x00,0x07,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x10,0x20,0x48,0x10,0x20,0x00,0x48,0x20,0x40,0x00,0x90,0x00,0x00,0x00,0x60,0x05,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x10,0x20,0x48,0x10,0x20,0x00,0x48,0x20,0x40,0x00,0x90,0x00,0x00,0x00,0x60,0x05,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x78,0x18,0x20,0x40,0x84,0x00,0x00,0x00,0x78,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x00,0x20,0x40,0x90,0x20,0x40,0x00,0x90,0x00,0x00,0x00,0x60,0x00,0x00,0x00,0x00,0x04,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x00,0x20,0x40,0x90,0x20,0x40,0x00,0x90,0x00,0x00,0x00,0x60,0x00,0x00,0x00,0x00,0x04,
- 0x00,0x00,0x00,0x38,0x00,0x18,0x20,0x44,0x04,0x00,0x40,0xBA,0x0C,0x00,0x40,0xB2,0x04,0x50,0x00,0xAA,0x44,0x20,0x00,0x9A,0x44,0x00,0x00,0xBA,0x38,0x00,0x00,0x44,0x00,0x00,0x00,0x38,0x00,0x00,0x00,0x00,0x07,
- 0x00,0x00,0x00,0x20,0x00,0x00,0x20,0x50,0x00,0x20,0x40,0x90,0x00,0x20,0x00,0x50,0x20,0x00,0x00,0x50,0x20,0x00,0x00,0x50,0x20,0x00,0x00,0x50,0x10,0x20,0x40,0x88,0x00,0x00,0x00,0x70,0x00,0x00,0x00,0x00,0x05,
- 0x00,0x00,0x00,0x38,0x00,0x08,0x30,0x44,0x04,0x00,0x40,0xBA,0x04,0x00,0x00,0x5A,0x08,0x10,0x00,0x24,0x00,0x20,0x00,0x5C,0x00,0x04,0x40,0xBA,0x3C,0x40,0x00,0x82,0x00,0x00,0x00,0x7C,0x00,0x00,0x00,0x00,0x07,
- 0x00,0x00,0x00,0x38,0x08,0x10,0x20,0x44,0x04,0x00,0x40,0xBA,0x04,0x00,0x00,0x5A,0x00,0x08,0x10,0x24,0x04,0x00,0x00,0x5A,0x04,0x00,0x40,0xBA,0x18,0x20,0x00,0x44,0x00,0x00,0x00,0x38,0x00,0x00,0x00,0x00,0x07,
- 0x00,0x00,0x00,0x08,0x00,0x08,0x00,0x14,0x08,0x00,0x10,0x24,0x08,0x00,0x20,0x54,0x08,0x40,0x00,0xB4,0x3C,0x40,0x00,0x82,0x08,0x00,0x00,0x74,0x04,0x08,0x10,0x22,0x00,0x00,0x00,0x1C,0x00,0x00,0x00,0x00,0x07,
- 0x00,0x00,0x00,0x7C,0x04,0x18,0x60,0x82,0x00,0x40,0x00,0xBC,0x78,0x00,0x00,0x84,0x04,0x00,0x00,0x7A,0x04,0x00,0x00,0x4A,0x04,0x00,0x40,0xBA,0x18,0x20,0x00,0x44,0x00,0x00,0x00,0x38,0x00,0x00,0x00,0x00,0x07,
- 0x00,0x00,0x00,0x18,0x08,0x10,0x00,0x24,0x00,0x00,0x20,0x58,0x00,0x40,0x00,0xB8,0x38,0x40,0x00,0x84,0x44,0x00,0x00,0xBA,0x44,0x00,0x00,0xBA,0x38,0x00,0x00,0x44,0x00,0x00,0x00,0x38,0x00,0x00,0x00,0x00,0x07,
- 0x00,0x00,0x00,0x7C,0x04,0x38,0x40,0x82,0x04,0x40,0x00,0xBA,0x00,0x04,0x00,0x4A,0x00,0x00,0x08,0x14,0x00,0x10,0x00,0x28,0x00,0x10,0x00,0x28,0x10,0x00,0x00,0x28,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x07,
- 0x00,0x00,0x00,0x38,0x00,0x18,0x20,0x44,0x04,0x00,0x40,0xBA,0x04,0x40,0x00,0xBA,0x18,0x20,0x00,0x44,0x04,0x00,0x40,0xBA,0x04,0x40,0x00,0xBA,0x38,0x00,0x00,0x44,0x00,0x00,0x00,0x38,0x00,0x00,0x00,0x00,0x07,
- 0x00,0x00,0x00,0x38,0x00,0x18,0x20,0x44,0x04,0x00,0x40,0xBA,0x04,0x40,0x00,0xBA,0x1C,0x20,0x00,0x42,0x04,0x00,0x00,0x3A,0x00,0x08,0x00,0x34,0x00,0x10,0x20,0x48,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x00,0x07,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x00,0x20,0x40,0x90,0x20,0x40,0x00,0x90,0x00,0x00,0x00,0x60,0x00,0x00,0x00,0x60,0x00,0x20,0x40,0x90,0x20,0x40,0x00,0x90,0x00,0x00,0x00,0x60,0x00,0x00,0x00,0x00,0x04,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x10,0x20,0x48,0x10,0x20,0x00,0x48,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x30,0x00,0x10,0x20,0x48,0x10,0x20,0x00,0x48,0x20,0x40,0x00,0x90,0x00,0x00,0x00,0x60,0x05,
- 0x00,0x00,0x00,0x38,0x00,0x08,0x30,0x44,0x04,0x40,0x00,0xBA,0x04,0x00,0x00,0x4A,0x08,0x00,0x00,0x14,0x10,0x00,0x00,0x28,0x00,0x00,0x00,0x10,0x10,0x00,0x00,0x28,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x07,
- 0x00,0x00,0x00,0x38,0x00,0x08,0x30,0x44,0x04,0x40,0x00,0xBA,0x04,0x00,0x00,0x4A,0x08,0x00,0x00,0x14,0x10,0x00,0x00,0x28,0x00,0x00,0x00,0x10,0x10,0x00,0x00,0x28,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x07,
- 0x00,0x00,0x00,0x38,0x00,0x08,0x30,0x44,0x04,0x40,0x00,0xBA,0x04,0x00,0x00,0x4A,0x08,0x00,0x00,0x14,0x10,0x00,0x00,0x28,0x00,0x00,0x00,0x10,0x10,0x00,0x00,0x28,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x07,
- 0x00,0x00,0x00,0x38,0x00,0x08,0x30,0x44,0x04,0x40,0x00,0xBA,0x04,0x00,0x00,0x4A,0x08,0x00,0x00,0x14,0x10,0x00,0x00,0x28,0x00,0x00,0x00,0x10,0x10,0x00,0x00,0x28,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x07,
- 0x00,0x00,0x00,0x38,0x00,0x08,0x30,0x44,0x04,0x00,0x40,0xBA,0x04,0x40,0x10,0xAA,0x0C,0x50,0x00,0xA2,0x1C,0x40,0x00,0xA2,0x40,0x00,0x00,0xBC,0x38,0x00,0x00,0x44,0x00,0x00,0x00,0x38,0x00,0x00,0x00,0x00,0x07,
- 0x00,0x00,0x00,0x38,0x08,0x10,0x20,0x44,0x04,0x00,0x40,0xBA,0x04,0x00,0x40,0xBA,0x0C,0x70,0x00,0x82,0x04,0x40,0x00,0xBA,0x44,0x00,0x00,0xAA,0x44,0x00,0x00,0xAA,0x00,0x00,0x00,0x44,0x00,0x00,0x00,0x00,0x07,
- 0x00,0x00,0x00,0x78,0x08,0x10,0x60,0x84,0x04,0x00,0x20,0x5A,0x04,0x20,0x00,0x5A,0x28,0x10,0x00,0x44,0x24,0x00,0x00,0x5A,0x24,0x00,0x00,0x5A,0x18,0x20,0x40,0x84,0x00,0x00,0x00,0x78,0x00,0x00,0x00,0x00,0x07,
- 0x00,0x00,0x00,0x18,0x00,0x18,0x00,0x24,0x04,0x00,0x20,0x5A,0x00,0x00,0x40,0xA4,0x00,0x00,0x40,0xA0,0x00,0x40,0x00,0xA4,0x24,0x00,0x00,0x5A,0x18,0x00,0x00,0x24,0x00,0x00,0x00,0x18,0x00,0x00,0x00,0x00,0x07,
- 0x00,0x00,0x00,0x70,0x10,0x20,0x40,0x88,0x08,0x20,0x00,0x54,0x04,0x20,0x00,0x5A,0x04,0x20,0x00,0x5A,0x24,0x00,0x00,0x5A,0x28,0x00,0x00,0x54,0x10,0x20,0x40,0x88,0x00,0x00,0x00,0x70,0x00,0x00,0x00,0x00,0x07,
- 0x00,0x00,0x00,0x7C,0x04,0x18,0x60,0x82,0x04,0x20,0x00,0x5A,0x00,0x20,0x00,0x5C,0x28,0x10,0x00,0x44,0x20,0x00,0x00,0x5C,0x20,0x04,0x00,0x5A,0x0C,0x30,0x40,0x82,0x00,0x00,0x00,0x7C,0x00,0x00,0x00,0x00,0x07,
- 0x00,0x00,0x00,0x7C,0x04,0x18,0x60,0x82,0x04,0x20,0x00,0x5A,0x00,0x20,0x00,0x5C,0x28,0x10,0x00,0x44,0x20,0x00,0x00,0x58,0x20,0x00,0x00,0x50,0x10,0x20,0x40,0x88,0x00,0x00,0x00,0x70,0x00,0x00,0x00,0x00,0x07,
- 0x00,0x00,0x00,0x18,0x00,0x18,0x00,0x24,0x04,0x00,0x20,0x5A,0x00,0x40,0x00,0xAC,0x00,0x44,0x08,0xB2,0x44,0x00,0x00,0xAA,0x24,0x00,0x00,0x5A,0x1C,0x00,0x00,0x22,0x00,0x00,0x00,0x1C,0x00,0x00,0x00,0x00,0x07,
- 0x00,0x00,0x00,0x44,0x00,0x00,0x44,0xAA,0x00,0x44,0x00,0xAA,0x04,0x40,0x00,0xBA,0x4C,0x30,0x00,0x82,0x44,0x00,0x00,0xBA,0x44,0x00,0x00,0xAA,0x44,0x00,0x00,0xAA,0x00,0x00,0x00,0x44,0x00,0x00,0x00,0x00,0x07,
- 0x00,0x00,0x00,0x7C,0x04,0x38,0x40,0x82,0x00,0x10,0x00,0x6C,0x10,0x00,0x00,0x28,0x10,0x00,0x00,0x28,0x10,0x00,0x00,0x28,0x10,0x00,0x00,0x6C,0x1C,0x20,0x40,0x82,0x00,0x00,0x00,0x7C,0x00,0x00,0x00,0x00,0x07,
- 0x00,0x00,0x00,0x0C,0x00,0x04,0x08,0x12,0x00,0x04,0x00,0x0A,0x04,0x00,0x00,0x0A,0x04,0x00,0x00,0x4A,0x04,0x00,0x40,0xAA,0x04,0x40,0x00,0xBA,0x18,0x20,0x00,0x44,0x00,0x00,0x00,0x38,0x00,0x00,0x00,0x00,0x07,
- 0x00,0x00,0x00,0x64,0x00,0x24,0x40,0x9A,0x00,0x24,0x00,0x5A,0x20,0x08,0x00,0x54,0x20,0x10,0x00,0x48,0x28,0x00,0x00,0x54,0x24,0x00,0x00,0x5A,0x04,0x20,0x40,0x9A,0x00,0x00,0x00,0x64,0x00,0x00,0x00,0x00,0x07,
- 0x00,0x00,0x00,0x70,0x00,0x30,0x40,0x88,0x00,0x20,0x00,0x50,0x00,0x20,0x00,0x50,0x00,0x20,0x00,0x50,0x20,0x00,0x00,0x54,0x24,0x00,0x00,0x5A,0x1C,0x20,0x40,0x82,0x00,0x00,0x00,0x7C,0x00,0x00,0x00,0x00,0x07,
- 0x00,0x00,0x00,0x44,0x00,0x04,0x40,0xAA,0x24,0x40,0x08,0x92,0x04,0x50,0x00,0xAA,0x14,0x40,0x00,0xAA,0x44,0x00,0x00,0xBA,0x44,0x00,0x00,0xAA,0x44,0x00,0x00,0xAA,0x00,0x00,0x00,0x44,0x00,0x00,0x00,0x00,0x07,
- 0x00,0x00,0x00,0x44,0x00,0x00,0x44,0xAA,0x20,0x44,0x00,0x9A,0x14,0x40,0x00,0xAA,0x0C,0x40,0x00,0xB2,0x44,0x00,0x00,0xAA,0x44,0x00,0x00,0xAA,0x44,0x00,0x00,0xAA,0x00,0x00,0x00,0x44,0x00,0x00,0x00,0x00,0x07,
- 0x00,0x00,0x00,0x38,0x00,0x18,0x20,0x44,0x04,0x00,0x40,0xBA,0x04,0x00,0x40,0xAA,0x04,0x40,0x00,0xAA,0x04,0x40,0x00,0xAA,0x04,0x40,0x00,0xBA,0x38,0x00,0x00,0x44,0x00,0x00,0x00,0x38,0x00,0x00,0x00,0x00,0x07,
- 0x00,0x00,0x00,0x78,0x08,0x30,0x40,0x84,0x04,0x20,0x00,0x5A,0x04,0x20,0x00,0x5A,0x28,0x10,0x00,0x44,0x20,0x00,0x00,0x58,0x20,0x00,0x00,0x50,0x10,0x20,0x40,0x88,0x00,0x00,0x00,0x70,0x00,0x00,0x00,0x00,0x07,
- 0x00,0x00,0x00,0x38,0x08,0x10,0x20,0x44,0x04,0x00,0x40,0xBA,0x04,0x00,0x40,0xAA,0x04,0x40,0x00,0xAA,0x04,0x40,0x00,0xBA,0x44,0x00,0x10,0xAA,0x30,0x08,0x00,0x44,0x04,0x00,0x00,0x3A,0x00,0x00,0x00,0x04,0x07,
- 0x00,0x00,0x00,0x78,0x00,0x18,0x60,0x84,0x04,0x20,0x00,0x5A,0x24,0x00,0x00,0x5A,0x28,0x10,0x00,0x44,0x24,0x00,0x00,0x5A,0x24,0x00,0x00,0x5A,0x04,0x20,0x40,0x9A,0x00,0x00,0x00,0x64,0x00,0x00,0x00,0x00,0x07,
- 0x00,0x00,0x00,0x38,0x00,0x18,0x20,0x44,0x04,0x00,0x40,0xBA,0x00,0x40,0x00,0xBC,0x08,0x30,0x00,0x44,0x04,0x00,0x00,0x7A,0x04,0x00,0x40,0xBA,0x08,0x30,0x00,0x44,0x00,0x00,0x00,0x38,0x00,0x00,0x00,0x00,0x07,
- 0x00,0x00,0x00,0x7C,0x04,0x18,0x60,0x82,0x14,0x40,0x00,0xAA,0x10,0x00,0x00,0x6C,0x10,0x00,0x00,0x28,0x10,0x00,0x00,0x28,0x10,0x00,0x00,0x28,0x08,0x10,0x20,0x44,0x00,0x00,0x00,0x38,0x00,0x00,0x00,0x00,0x07,
- 0x00,0x00,0x00,0x44,0x00,0x00,0x44,0xAA,0x00,0x44,0x00,0xAA,0x04,0x40,0x00,0xAA,0x04,0x40,0x00,0xAA,0x44,0x00,0x00,0xAA,0x44,0x00,0x00,0xBA,0x3C,0x00,0x00,0x42,0x00,0x00,0x00,0x3C,0x00,0x00,0x00,0x00,0x07,
- 0x00,0x00,0x00,0x44,0x00,0x04,0x40,0xAA,0x00,0x44,0x00,0xAA,0x04,0x40,0x00,0xAA,0x28,0x00,0x00,0x54,0x28,0x00,0x00,0x54,0x10,0x00,0x00,0x28,0x10,0x00,0x00,0x28,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x07,
- 0x00,0x00,0x00,0x44,0x00,0x00,0x44,0xAA,0x00,0x04,0x40,0xAA,0x04,0x40,0x00,0xAA,0x04,0x40,0x00,0xBA,0x54,0x00,0x00,0xAA,0x6C,0x00,0x00,0x92,0x44,0x00,0x00,0xAA,0x00,0x00,0x00,0x44,0x00,0x00,0x00,0x00,0x07,
- 0x00,0x00,0x00,0x44,0x00,0x00,0x44,0xAA,0x04,0x40,0x00,0xAA,0x28,0x00,0x00,0x54,0x10,0x00,0x00,0x28,0x08,0x20,0x00,0x54,0x04,0x00,0x40,0xAA,0x04,0x40,0x00,0xAA,0x00,0x00,0x00,0x44,0x00,0x00,0x00,0x00,0x07,
- 0x00,0x00,0x00,0x44,0x04,0x00,0x40,0xAA,0x04,0x40,0x00,0xAA,0x04,0x40,0x00,0xBA,0x38,0x00,0x00,0x44,0x10,0x00,0x00,0x28,0x10,0x00,0x00,0x28,0x08,0x10,0x20,0x44,0x00,0x00,0x00,0x38,0x00,0x00,0x00,0x00,0x07,
- 0x00,0x00,0x00,0x7C,0x04,0x38,0x40,0x82,0x04,0x40,0x00,0xBA,0x08,0x00,0x00,0x54,0x10,0x00,0x00,0x28,0x00,0x20,0x00,0x54,0x04,0x00,0x40,0xBA,0x3C,0x40,0x00,0x82,0x00,0x00,0x00,0x7C,0x00,0x00,0x00,0x00,0x07,
- 0x00,0x00,0x00,0x7C,0x04,0x38,0x40,0x82,0x04,0x40,0x00,0xBA,0x08,0x00,0x00,0x54,0x10,0x00,0x00,0x28,0x00,0x20,0x00,0x54,0x04,0x00,0x40,0xBA,0x3C,0x40,0x00,0x82,0x00,0x00,0x00,0x7C,0x00,0x00,0x00,0x00,0x07,
- 0x00,0x00,0x00,0x7C,0x04,0x38,0x40,0x82,0x04,0x40,0x00,0xBA,0x08,0x00,0x00,0x54,0x10,0x00,0x00,0x28,0x00,0x20,0x00,0x54,0x04,0x00,0x40,0xBA,0x3C,0x40,0x00,0x82,0x00,0x00,0x00,0x7C,0x00,0x00,0x00,0x00,0x07,
- 0x00,0x00,0x00,0x7C,0x04,0x38,0x40,0x82,0x04,0x40,0x00,0xBA,0x08,0x00,0x00,0x54,0x10,0x00,0x00,0x28,0x00,0x20,0x00,0x54,0x04,0x00,0x40,0xBA,0x3C,0x40,0x00,0x82,0x00,0x00,0x00,0x7C,0x00,0x00,0x00,0x00,0x07,
- 0x00,0x00,0x00,0x7C,0x04,0x38,0x40,0x82,0x04,0x40,0x00,0xBA,0x08,0x00,0x00,0x54,0x10,0x00,0x00,0x28,0x00,0x20,0x00,0x54,0x04,0x00,0x40,0xBA,0x3C,0x40,0x00,0x82,0x00,0x00,0x00,0x7C,0x00,0x00,0x00,0x00,0x07,
- 0x00,0x00,0x00,0x7C,0x04,0x38,0x40,0x82,0x04,0x40,0x00,0xBA,0x08,0x00,0x00,0x54,0x10,0x00,0x00,0x28,0x00,0x20,0x00,0x54,0x04,0x00,0x40,0xBA,0x3C,0x40,0x00,0x82,0x00,0x00,0x00,0x7C,0x00,0x00,0x00,0x00,0x07,
- 0x00,0x00,0x00,0x7C,0x04,0x38,0x40,0x82,0x04,0x40,0x00,0xBA,0x08,0x00,0x00,0x54,0x10,0x00,0x00,0x28,0x00,0x20,0x00,0x54,0x04,0x00,0x40,0xBA,0x3C,0x40,0x00,0x82,0x00,0x00,0x00,0x7C,0x00,0x00,0x00,0x00,0x07,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x00,0x28,0x10,0x44,0x04,0x00,0x00,0x3A,0x04,0x08,0x30,0x42,0x04,0x40,0x00,0xBA,0x3C,0x00,0x00,0x42,0x00,0x00,0x00,0x3C,0x00,0x00,0x00,0x00,0x07,
- 0x00,0x00,0x00,0x60,0x00,0x20,0x40,0x90,0x00,0x20,0x00,0x58,0x00,0x28,0x00,0x54,0x04,0x20,0x10,0x4A,0x04,0x20,0x00,0x5A,0x04,0x20,0x00,0x5A,0x18,0x20,0x00,0x44,0x00,0x00,0x00,0x38,0x00,0x00,0x00,0x00,0x07,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x00,0x08,0x30,0x44,0x04,0x00,0x40,0xBA,0x00,0x40,0x00,0xA4,0x04,0x40,0x00,0xBA,0x38,0x00,0x00,0x44,0x00,0x00,0x00,0x38,0x00,0x00,0x00,0x00,0x07,
- 0x00,0x00,0x00,0x0C,0x00,0x04,0x08,0x12,0x08,0x00,0x00,0x34,0x08,0x20,0x00,0x54,0x18,0x40,0x00,0xA4,0x08,0x40,0x00,0xB4,0x08,0x40,0x00,0xB4,0x38,0x00,0x00,0x44,0x00,0x00,0x00,0x38,0x00,0x00,0x00,0x00,0x07,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x00,0x08,0x30,0x44,0x04,0x00,0x40,0xBA,0x3C,0x40,0x00,0x82,0x00,0x40,0x00,0xBC,0x38,0x00,0x00,0x44,0x00,0x00,0x00,0x38,0x00,0x00,0x00,0x00,0x07,
- 0x00,0x00,0x00,0x18,0x00,0x08,0x10,0x24,0x04,0x00,0x20,0x5A,0x00,0x20,0x00,0x54,0x10,0x20,0x40,0x88,0x20,0x00,0x00,0x50,0x20,0x00,0x00,0x50,0x30,0x40,0x00,0x88,0x00,0x00,0x00,0x70,0x00,0x00,0x00,0x00,0x07,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x34,0x04,0x10,0x20,0x4A,0x08,0x00,0x40,0xB4,0x08,0x40,0x00,0xB4,0x38,0x00,0x00,0x44,0x04,0x00,0x40,0xBA,0x18,0x20,0x00,0x44,0x00,0x00,0x00,0x38,0x07,
- 0x00,0x00,0x00,0x60,0x00,0x20,0x40,0x90,0x00,0x20,0x00,0x58,0x20,0x08,0x00,0x54,0x24,0x00,0x10,0x4A,0x24,0x00,0x00,0x5A,0x24,0x00,0x00,0x5A,0x04,0x20,0x40,0x9A,0x00,0x00,0x00,0x64,0x00,0x00,0x00,0x00,0x07,
- 0x00,0x00,0x00,0x20,0x00,0x00,0x20,0x50,0x00,0x00,0x00,0x60,0x00,0x40,0x20,0x90,0x00,0x20,0x00,0x50,0x20,0x00,0x00,0x50,0x20,0x00,0x00,0x50,0x10,0x20,0x40,0x88,0x00,0x00,0x00,0x70,0x00,0x00,0x00,0x00,0x05,
- 0x00,0x00,0x00,0x04,0x00,0x00,0x04,0x0A,0x00,0x00,0x00,0x04,0x00,0x00,0x04,0x0A,0x00,0x04,0x00,0x0A,0x04,0x00,0x00,0x0A,0x04,0x00,0x00,0x4A,0x04,0x00,0x40,0xBA,0x18,0x20,0x00,0x44,0x00,0x00,0x00,0x38,0x07,
- 0x00,0x00,0x00,0x60,0x00,0x00,0x60,0x90,0x00,0x20,0x00,0x54,0x20,0x04,0x00,0x5A,0x20,0x00,0x08,0x54,0x20,0x10,0x00,0x48,0x28,0x00,0x00,0x54,0x04,0x20,0x40,0x9A,0x00,0x00,0x00,0x64,0x00,0x00,0x00,0x00,0x07,
- 0x00,0x00,0x00,0x60,0x00,0x20,0x40,0x90,0x00,0x20,0x00,0x50,0x20,0x00,0x00,0x50,0x20,0x00,0x00,0x50,0x20,0x00,0x00,0x50,0x20,0x00,0x00,0x50,0x10,0x20,0x40,0x88,0x00,0x00,0x00,0x70,0x00,0x00,0x00,0x00,0x05,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x00,0x00,0x48,0xB4,0x24,0x48,0x00,0x92,0x44,0x10,0x00,0xAA,0x44,0x00,0x00,0xBA,0x44,0x00,0x00,0xAA,0x00,0x00,0x00,0x44,0x00,0x00,0x00,0x00,0x07,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x78,0x08,0x10,0x60,0x84,0x04,0x00,0x40,0xBA,0x04,0x40,0x00,0xAA,0x44,0x00,0x00,0xAA,0x44,0x00,0x00,0xAA,0x00,0x00,0x00,0x44,0x00,0x00,0x00,0x00,0x07,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x08,0x10,0x20,0x44,0x04,0x00,0x40,0xBA,0x04,0x40,0x00,0xAA,0x44,0x00,0x00,0xBA,0x38,0x00,0x00,0x44,0x00,0x00,0x00,0x38,0x00,0x00,0x00,0x00,0x07,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x58,0x00,0x08,0x50,0xA4,0x04,0x20,0x00,0x5A,0x24,0x00,0x00,0x5A,0x38,0x00,0x00,0x44,0x20,0x00,0x00,0x58,0x10,0x20,0x40,0x88,0x00,0x00,0x00,0x70,0x07,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x34,0x00,0x14,0x20,0x4A,0x08,0x40,0x00,0xB4,0x48,0x00,0x00,0xB4,0x38,0x00,0x00,0x44,0x08,0x00,0x00,0x34,0x04,0x08,0x10,0x22,0x00,0x00,0x00,0x1C,0x07,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x58,0x00,0x08,0x50,0xA4,0x04,0x20,0x00,0x5A,0x24,0x00,0x00,0x5A,0x20,0x00,0x00,0x54,0x10,0x20,0x40,0x88,0x00,0x00,0x00,0x70,0x00,0x00,0x00,0x00,0x07,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3C,0x04,0x18,0x20,0x42,0x00,0x40,0x00,0xBC,0x38,0x00,0x00,0x44,0x04,0x00,0x00,0x7A,0x38,0x00,0x40,0x84,0x00,0x00,0x00,0x78,0x00,0x00,0x00,0x00,0x07,
- 0x00,0x00,0x00,0x20,0x00,0x00,0x20,0x50,0x00,0x20,0x00,0x58,0x08,0x30,0x40,0x84,0x20,0x00,0x00,0x58,0x20,0x00,0x00,0x54,0x04,0x20,0x00,0x5A,0x08,0x10,0x00,0x24,0x00,0x00,0x00,0x18,0x00,0x00,0x00,0x00,0x07,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x00,0x00,0x48,0xB4,0x00,0x48,0x00,0xB4,0x08,0x40,0x00,0xB4,0x48,0x00,0x00,0xB4,0x34,0x00,0x00,0x4A,0x00,0x00,0x00,0x34,0x00,0x00,0x00,0x00,0x07,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x44,0x00,0x00,0x44,0xAA,0x00,0x44,0x00,0xAA,0x04,0x40,0x00,0xAA,0x28,0x00,0x00,0x54,0x10,0x00,0x00,0x28,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x07,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x44,0x00,0x00,0x44,0xAA,0x00,0x44,0x00,0xBA,0x14,0x40,0x00,0xAA,0x2C,0x40,0x00,0x92,0x48,0x00,0x00,0xB4,0x00,0x00,0x00,0x48,0x00,0x00,0x00,0x00,0x07,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x44,0x00,0x00,0x44,0xAA,0x00,0x28,0x00,0x54,0x10,0x00,0x00,0x28,0x08,0x20,0x00,0x54,0x04,0x40,0x00,0xAA,0x00,0x00,0x00,0x44,0x00,0x00,0x00,0x00,0x07,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x44,0x00,0x00,0x44,0xAA,0x00,0x44,0x00,0xAA,0x04,0x40,0x00,0xBA,0x38,0x00,0x00,0x44,0x00,0x10,0x00,0x68,0x00,0x20,0x40,0x90,0x00,0x00,0x00,0x60,0x07,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7C,0x04,0x38,0x40,0x82,0x08,0x40,0x00,0xB4,0x00,0x10,0x00,0x6C,0x04,0x20,0x00,0x5A,0x3C,0x00,0x40,0x82,0x00,0x00,0x00,0x7C,0x00,0x00,0x00,0x00,0x07
-};
-
-void AGOSEngine::renderStringAmiga(uint vgaSpriteId, uint color, uint width, uint height, const char *txt) {
- VgaPointersEntry *vpe = &_vgaBufferPointers[2];
- byte *p, *dst, *dst_org, chr;
- uint count;
-
- if (vgaSpriteId >= 100) {
- vgaSpriteId -= 100;
- vpe++;
- }
-
- dst = vpe->vgaFile2;
-
- count = 2000;
- if (vgaSpriteId == 1)
- count *= 2;
-
- p = dst + vgaSpriteId * 8;
- WRITE_BE_UINT16(p + 4, height);
- WRITE_BE_UINT16(p + 6, width);
- dst += READ_BE_UINT32(p);
-
- width /= 8; // convert width from pixels to bytes
-
- uint charsize = width * height;
- memset(dst, 0, count);
- dst_org = dst;
- int delta = 0;
- while ((chr = *txt++) != 0) {
- int img_width = 1;
- if (chr == 10) {
- dst += width * 10;
- dst_org = dst;
- delta = 0;
- } else if ((signed char)(chr -= '!') < 0) {
- img_width = 7;
- } else {
- const byte *img = simon_agaFont + chr * 41;
- img_width = img[40];
- byte *cur_dst = dst_org;
- for (int row = 0; row < 10; row++) {
- int col = color;
- for (int plane = 0; plane < 3; plane++) {
- chr = img[plane] >> delta;
- if (chr) {
- if (col & 1) cur_dst[charsize * 0] |= chr;
- if (col & 2) cur_dst[charsize * 1] |= chr;
- if (col & 4) cur_dst[charsize * 2] |= chr;
- if (col & 8) cur_dst[charsize * 3] |= chr;
- }
- chr = img[plane] << (8 - delta);
- if (((8 - delta) < img_width) && (chr)) {
- if (col & 1) cur_dst[charsize * 0 + 1] |= chr;
- if (col & 2) cur_dst[charsize * 1 + 1] |= chr;
- if (col & 4) cur_dst[charsize * 2 + 1] |= chr;
- if (col & 8) cur_dst[charsize * 3 + 1] |= chr;
- }
- col++;
- }
- chr = img[3] >> delta;
- if (chr) {
- cur_dst[charsize * 0] |= chr;
- cur_dst[charsize * 1] |= chr;
- cur_dst[charsize * 2] |= chr;
- cur_dst[charsize * 3] |= chr;
- }
- chr = img[3] << (8 - delta);
- if (((8 - delta) < img_width) && (chr)) {
- cur_dst[charsize * 0 + 1] |= chr;
- cur_dst[charsize * 1 + 1] |= chr;
- cur_dst[charsize * 2 + 1] |= chr;
- cur_dst[charsize * 3 + 1] |= chr;
- }
- cur_dst += width;
- img += 4;
- }
- }
- delta += img_width - 1;
- if (delta >= 8) {
- delta -= 8;
- dst_org++;
- }
- }
-}
-
-void AGOSEngine::renderString(uint vgaSpriteId, uint color, uint width, uint height, const char *txt) {
- VgaPointersEntry *vpe = &_vgaBufferPointers[2];
- byte *src, *dst, *p, *dst_org, chr;
- const int textHeight = (getGameType() == GType_FF || getGameType() == GType_PP) ? 15: 10;
- uint count = 0;
-
- if (vgaSpriteId >= 100) {
- vgaSpriteId -= 100;
- vpe++;
- }
-
- src = dst = vpe->vgaFile2;
-
- if (getGameType() == GType_FF || getGameType() == GType_PP) {
- if (vgaSpriteId == 1)
- count = 45000;
- } else {
- count = 4000;
- if (vgaSpriteId == 1)
- count *= 2;
- }
-
- p = dst + vgaSpriteId * 8;
-
- if (getGameType() == GType_FF || getGameType() == GType_PP) {
- if (vgaSpriteId != 1)
- WRITE_LE_UINT32(p, READ_LE_UINT32(p - 8) + READ_LE_UINT16(p - 4) * READ_LE_UINT16(p - 2));
-
- WRITE_LE_UINT16(p + 4, height);
- WRITE_LE_UINT16(p + 6, width);
- } else {
- WRITE_BE_UINT16(p + 4, height);
- WRITE_BE_UINT16(p + 6, width);
- }
- dst += readUint32Wrapper(p);
-
- if (count != 0)
- memset(dst, 0, count);
-
- if (_language == Common::HE_ISR)
- dst += width - 1; // For Hebrew, start at the right edge, not the left.
-
- dst_org = dst;
- while ((chr = *txt++) != 0) {
- if (chr == 10) {
- dst_org += width * textHeight;
- dst = dst_org;
- } else if ((chr -= ' ') == 0) {
- dst += (_language == Common::HE_ISR ? -6 : 6); // Hebrew moves to the left, all others to the right
- } else {
- byte *img_hdr, *img;
- uint i, img_width, img_height;
-
- if (getGameType() == GType_FF || getGameType() == GType_PP) {
- img_hdr = src + 96 + chr * 8;
- img_height = READ_LE_UINT16(img_hdr + 4);
- img_width = READ_LE_UINT16(img_hdr + 6);
- img = src + READ_LE_UINT32(img_hdr);
- } else {
- img_hdr = src + 48 + chr * 4;
- img_height = img_hdr[2];
- img_width = img_hdr[3];
- img = src + READ_LE_UINT16(img_hdr);
- }
-
- if (_language == Common::HE_ISR)
- dst -= img_width - 1; // For Hebrew, move from right edge to left edge of image.
- byte *cur_dst = dst;
-
- // Occurs in Amiga and Macintosh ports of The Feeble Files, when
- // special characters are used by French/German/Spanish versions.
- // Due to the English image data, been used by all languages.
- if (img_width == 0 || img_height == 0)
- continue;
-
- assert(img_width < 50 && img_height < 50);
-
- do {
- for (i = 0; i != img_width; i++) {
- chr = *img++;
- if (chr) {
- if (chr == 0xF)
- chr = 207;
- else
- chr += color;
- cur_dst[i] = chr;
- }
- }
- cur_dst += width;
- } while (--img_height);
-
- if (_language != Common::HE_ISR) // Hebrew character movement is done higher up
- dst += img_width - 1;
- }
- }
-}
-
void AGOSEngine::showMessageFormat(const char *s, ...) {
char buf[STRINGBUFLEN];
char *str;
diff --git a/engines/agos/detection_tables.h b/engines/agos/detection_tables.h
index 21b9d24c7c..7fe6df5f17 100644
--- a/engines/agos/detection_tables.h
+++ b/engines/agos/detection_tables.h
@@ -1591,7 +1591,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::RU_RUS,
Common::kPlatformPC,
ADGF_CD,
- GUIO1(GUIO_NONE)
+ GUIO0()
},
GType_SIMON1,
@@ -1616,7 +1616,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::FR_FRA,
Common::kPlatformPC,
ADGF_CD,
- GUIO1(GUIO_NONE)
+ GUIO0()
},
GType_SIMON1,
@@ -1666,7 +1666,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::HE_ISR,
Common::kPlatformPC,
ADGF_CD,
- GUIO1(GUIO_NONE)
+ GUIO0()
},
GType_SIMON1,
@@ -1691,7 +1691,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::IT_ITA,
Common::kPlatformPC,
ADGF_CD,
- GUIO1(GUIO_NONE)
+ GUIO0()
},
GType_SIMON1,
@@ -1717,7 +1717,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::IT_ITA,
Common::kPlatformWindows,
ADGF_CD,
- GUIO1(GUIO_NONE)
+ GUIO0()
},
GType_SIMON1,
@@ -1742,7 +1742,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::ES_ESP,
Common::kPlatformPC,
ADGF_CD,
- GUIO1(GUIO_NONE)
+ GUIO0()
},
GType_SIMON1,
@@ -1942,7 +1942,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformPC,
ADGF_DEMO,
- GUIO1(GUIO_NONE)
+ GUIO0()
},
GType_SIMON2,
@@ -1967,7 +1967,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::DE_DEU,
Common::kPlatformPC,
ADGF_DEMO,
- GUIO1(GUIO_NONE)
+ GUIO0()
},
GType_SIMON2,
@@ -1992,7 +1992,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::DE_DEU,
Common::kPlatformPC,
ADGF_DEMO,
- GUIO1(GUIO_NONE)
+ GUIO0()
},
GType_SIMON2,
@@ -2017,7 +2017,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformPC,
ADGF_CD,
- GUIO1(GUIO_NONE)
+ GUIO0()
},
GType_SIMON2,
@@ -2042,7 +2042,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformPC,
ADGF_CD,
- GUIO1(GUIO_NONE)
+ GUIO0()
},
GType_SIMON2,
@@ -2067,7 +2067,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::FR_FRA,
Common::kPlatformPC,
ADGF_CD,
- GUIO1(GUIO_NONE)
+ GUIO0()
},
GType_SIMON2,
@@ -2092,7 +2092,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::DE_DEU,
Common::kPlatformPC,
ADGF_CD,
- GUIO1(GUIO_NONE)
+ GUIO0()
},
GType_SIMON2,
@@ -2117,7 +2117,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::DE_DEU,
Common::kPlatformPC,
ADGF_CD,
- GUIO1(GUIO_NONE)
+ GUIO0()
},
GType_SIMON2,
@@ -2142,7 +2142,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::HE_ISR,
Common::kPlatformPC,
ADGF_CD,
- GUIO1(GUIO_NONE)
+ GUIO0()
},
GType_SIMON2,
@@ -2168,7 +2168,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::IT_ITA,
Common::kPlatformWindows,
ADGF_CD,
- GUIO1(GUIO_NONE)
+ GUIO0()
},
GType_SIMON2,
@@ -2193,7 +2193,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::ES_ESP,
Common::kPlatformPC,
ADGF_CD,
- GUIO1(GUIO_NONE)
+ GUIO0()
},
GType_SIMON2,
@@ -2218,7 +2218,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::CZ_CZE,
Common::kPlatformWindows,
ADGF_CD,
- GUIO1(GUIO_NONE)
+ GUIO0()
},
GType_SIMON2,
@@ -2243,7 +2243,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_CD,
- GUIO1(GUIO_NONE)
+ GUIO0()
},
GType_SIMON2,
@@ -2268,7 +2268,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::FR_FRA,
Common::kPlatformWindows,
ADGF_CD,
- GUIO1(GUIO_NONE)
+ GUIO0()
},
GType_SIMON2,
@@ -2293,7 +2293,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::DE_DEU,
Common::kPlatformWindows,
ADGF_CD,
- GUIO1(GUIO_NONE)
+ GUIO0()
},
GType_SIMON2,
@@ -2318,7 +2318,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::PL_POL,
Common::kPlatformWindows,
ADGF_CD,
- GUIO1(GUIO_NONE)
+ GUIO0()
},
GType_SIMON2,
@@ -2340,7 +2340,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformPC,
ADGF_DEMO,
- GUIO2(GUIO_NOSUBTITLES, GUIO_NOMUSIC)
+ GUIO3(GUIO_NOSUBTITLES, GUIO_NOMUSIC, GUIO_NOASPECT)
},
GType_FF,
@@ -2361,7 +2361,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::DE_DEU,
Common::kPlatformPC,
ADGF_DEMO,
- GUIO2(GUIO_NOSUBTITLES, GUIO_NOMUSIC)
+ GUIO3(GUIO_NOSUBTITLES, GUIO_NOMUSIC, GUIO_NOASPECT)
},
GType_FF,
@@ -2385,7 +2385,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformAmiga,
ADGF_NO_FLAGS,
- GUIO2(GUIO_NOSUBTITLES, GUIO_NOMUSIC)
+ GUIO3(GUIO_NOSUBTITLES, GUIO_NOMUSIC, GUIO_NOASPECT)
},
GType_FF,
@@ -2409,7 +2409,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::DE_DEU,
Common::kPlatformAmiga,
ADGF_NO_FLAGS,
- GUIO2(GUIO_NOSUBTITLES, GUIO_NOMUSIC)
+ GUIO3(GUIO_NOSUBTITLES, GUIO_NOMUSIC, GUIO_NOASPECT)
},
GType_FF,
@@ -2433,7 +2433,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformMacintosh,
ADGF_NO_FLAGS,
- GUIO2(GUIO_NOSUBTITLES, GUIO_NOMUSIC)
+ GUIO3(GUIO_NOSUBTITLES, GUIO_NOMUSIC, GUIO_NOASPECT)
},
GType_FF,
@@ -2457,7 +2457,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::FR_FRA,
Common::kPlatformMacintosh,
ADGF_NO_FLAGS,
- GUIO2(GUIO_NOSUBTITLES, GUIO_NOMUSIC)
+ GUIO3(GUIO_NOSUBTITLES, GUIO_NOMUSIC, GUIO_NOASPECT)
},
GType_FF,
@@ -2481,7 +2481,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::DE_DEU,
Common::kPlatformMacintosh,
ADGF_NO_FLAGS,
- GUIO2(GUIO_NOSUBTITLES, GUIO_NOMUSIC)
+ GUIO3(GUIO_NOSUBTITLES, GUIO_NOMUSIC, GUIO_NOASPECT)
},
GType_FF,
@@ -2505,7 +2505,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::ES_ESP,
Common::kPlatformMacintosh,
ADGF_NO_FLAGS,
- GUIO2(GUIO_NOSUBTITLES, GUIO_NOMUSIC)
+ GUIO3(GUIO_NOSUBTITLES, GUIO_NOMUSIC, GUIO_NOASPECT)
},
GType_FF,
@@ -2526,7 +2526,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
- GUIO2(GUIO_NOSUBTITLES, GUIO_NOMUSIC)
+ GUIO3(GUIO_NOSUBTITLES, GUIO_NOMUSIC, GUIO_NOASPECT)
},
GType_FF,
@@ -2549,7 +2549,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
- GUIO2(GUIO_NOSUBTITLES, GUIO_NOMUSIC)
+ GUIO3(GUIO_NOSUBTITLES, GUIO_NOMUSIC, GUIO_NOASPECT)
},
GType_FF,
@@ -2572,7 +2572,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::PL_POL,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
- GUIO2(GUIO_NOSUBTITLES, GUIO_NOMUSIC)
+ GUIO3(GUIO_NOSUBTITLES, GUIO_NOMUSIC, GUIO_NOASPECT)
},
GType_FF,
@@ -2593,7 +2593,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
- GUIO2(GUIO_NOSUBTITLES, GUIO_NOMUSIC)
+ GUIO3(GUIO_NOSUBTITLES, GUIO_NOMUSIC, GUIO_NOASPECT)
},
GType_FF,
@@ -2616,7 +2616,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
- GUIO2(GUIO_NOSUBTITLES, GUIO_NOMUSIC)
+ GUIO3(GUIO_NOSUBTITLES, GUIO_NOMUSIC, GUIO_NOASPECT)
},
GType_FF,
@@ -2639,7 +2639,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::FR_FRA,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
- GUIO2(GUIO_NOSUBTITLES, GUIO_NOMUSIC)
+ GUIO3(GUIO_NOSUBTITLES, GUIO_NOMUSIC, GUIO_NOASPECT)
},
GType_FF,
@@ -2662,7 +2662,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::DE_DEU,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
- GUIO2(GUIO_NOSUBTITLES, GUIO_NOMUSIC)
+ GUIO3(GUIO_NOSUBTITLES, GUIO_NOMUSIC, GUIO_NOASPECT)
},
GType_FF,
@@ -2685,7 +2685,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::IT_ITA,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
- GUIO2(GUIO_NOSUBTITLES, GUIO_NOMUSIC)
+ GUIO3(GUIO_NOSUBTITLES, GUIO_NOMUSIC, GUIO_NOASPECT)
},
GType_FF,
@@ -2708,7 +2708,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::PL_POL,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
- GUIO2(GUIO_NOSUBTITLES, GUIO_NOMUSIC)
+ GUIO3(GUIO_NOSUBTITLES, GUIO_NOMUSIC, GUIO_NOASPECT)
},
GType_FF,
@@ -2731,7 +2731,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::ES_ESP,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
- GUIO2(GUIO_NOSUBTITLES, GUIO_NOMUSIC)
+ GUIO3(GUIO_NOSUBTITLES, GUIO_NOMUSIC, GUIO_NOASPECT)
},
GType_FF,
@@ -2752,7 +2752,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
- GUIO2(GUIO_NOSUBTITLES, GUIO_NOMUSIC)
+ GUIO3(GUIO_NOSUBTITLES, GUIO_NOMUSIC, GUIO_NOASPECT)
},
GType_PP,
@@ -2773,7 +2773,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
- GUIO2(GUIO_NOSUBTITLES, GUIO_NOMUSIC)
+ GUIO3(GUIO_NOSUBTITLES, GUIO_NOMUSIC, GUIO_NOASPECT)
},
GType_PP,
@@ -2794,7 +2794,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NOSUBTITLES)
+ GUIO2(GUIO_NOSUBTITLES, GUIO_NOASPECT)
},
GType_PP,
@@ -2815,7 +2815,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NOSUBTITLES)
+ GUIO2(GUIO_NOSUBTITLES, GUIO_NOASPECT)
},
GType_PP,
@@ -2836,7 +2836,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NOSUBTITLES)
+ GUIO2(GUIO_NOSUBTITLES, GUIO_NOASPECT)
},
GType_PP,
@@ -2857,7 +2857,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NOSUBTITLES)
+ GUIO2(GUIO_NOSUBTITLES, GUIO_NOASPECT)
},
GType_PP,
@@ -2878,7 +2878,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NOSUBTITLES)
+ GUIO2(GUIO_NOSUBTITLES, GUIO_NOASPECT)
},
GType_PP,
@@ -2899,7 +2899,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NOSUBTITLES)
+ GUIO2(GUIO_NOSUBTITLES, GUIO_NOASPECT)
},
GType_PP,
@@ -2920,7 +2920,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::DE_DEU,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NOSUBTITLES)
+ GUIO2(GUIO_NOSUBTITLES, GUIO_NOASPECT)
},
GType_PP,
@@ -2941,7 +2941,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::PL_POL,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NOSUBTITLES)
+ GUIO2(GUIO_NOSUBTITLES, GUIO_NOASPECT)
},
GType_PP,
@@ -2962,7 +2962,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::ES_ESP,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NOSUBTITLES)
+ GUIO2(GUIO_NOSUBTITLES, GUIO_NOASPECT)
},
GType_PP,
diff --git a/engines/agos/draw.cpp b/engines/agos/draw.cpp
index 9fc5cedbf9..cf3a12ceb8 100644
--- a/engines/agos/draw.cpp
+++ b/engines/agos/draw.cpp
@@ -776,7 +776,7 @@ void AGOSEngine::setMoveRect(uint16 x, uint16 y, uint16 width, uint16 height) {
void AGOSEngine::displayScreen() {
if (_fastFadeInFlag == 0 && _paletteFlag == 1) {
_paletteFlag = 0;
- if (memcmp(_displayPalette, _currentPalette, sizeof(_currentPalette))) {
+ if (memcmp(_displayPalette, _currentPalette, sizeof(_currentPalette)) != 0) {
memcpy(_currentPalette, _displayPalette, sizeof(_displayPalette));
_system->getPaletteManager()->setPalette(_displayPalette, 0, 256);
}
diff --git a/engines/agos/installshield_cab.cpp b/engines/agos/installshield_cab.cpp
index f7b49a64c5..d4e636f7b3 100644
--- a/engines/agos/installshield_cab.cpp
+++ b/engines/agos/installshield_cab.cpp
@@ -60,9 +60,9 @@ public:
~InstallShieldCabinet();
// Common::Archive API implementation
- bool hasFile(const Common::String &name);
- int listMembers(Common::ArchiveMemberList &list);
- Common::ArchiveMemberPtr getMember(const Common::String &name);
+ bool hasFile(const Common::String &name) const;
+ int listMembers(Common::ArchiveMemberList &list) const;
+ const Common::ArchiveMemberPtr getMember(const Common::String &name) const;
Common::SeekableReadStream *createReadStreamForMember(const Common::String &name) const;
private:
@@ -161,19 +161,18 @@ InstallShieldCabinet::InstallShieldCabinet(const Common::String &filename) : _in
delete[] fileTableOffsets;
}
-bool InstallShieldCabinet::hasFile(const Common::String &name) {
- warning("hasFile: Filename %s", name.c_str());
+bool InstallShieldCabinet::hasFile(const Common::String &name) const {
return _map.contains(name);
}
-int InstallShieldCabinet::listMembers(Common::ArchiveMemberList &list) {
+int InstallShieldCabinet::listMembers(Common::ArchiveMemberList &list) const {
for (FileMap::const_iterator it = _map.begin(); it != _map.end(); it++)
list.push_back(getMember(it->_key));
return _map.size();
}
-Common::ArchiveMemberPtr InstallShieldCabinet::getMember(const Common::String &name) {
+const Common::ArchiveMemberPtr InstallShieldCabinet::getMember(const Common::String &name) const {
return Common::ArchiveMemberPtr(new Common::GenericArchiveMember(name, this));
}
diff --git a/engines/agos/midi.cpp b/engines/agos/midi.cpp
index 431f080bf2..b3ade91107 100644
--- a/engines/agos/midi.cpp
+++ b/engines/agos/midi.cpp
@@ -478,7 +478,7 @@ void MidiPlayer::loadMultipleSMF(Common::File *in, bool sfx) {
// Make sure there's a MThd
in->read(buf, 4);
- if (memcmp(buf, "MThd", 4)) {
+ if (memcmp(buf, "MThd", 4) != 0) {
warning("Expected MThd but found '%c%c%c%c' instead", buf[0], buf[1], buf[2], buf[3]);
return;
}
@@ -487,7 +487,7 @@ void MidiPlayer::loadMultipleSMF(Common::File *in, bool sfx) {
// Now skip all the MTrk blocks
while (true) {
in->read(buf, 4);
- if (memcmp(buf, "MTrk", 4))
+ if (memcmp(buf, "MTrk", 4) != 0)
break;
in->seek(in->readUint32BE(), SEEK_CUR);
}
@@ -524,7 +524,7 @@ void MidiPlayer::loadXMIDI(Common::File *in, bool sfx) {
memcpy(buf, &buf[2], 2);
in->read(&buf[2], 2);
}
- if (memcmp(buf, "CAT ", 4)) {
+ if (memcmp(buf, "CAT ", 4) != 0) {
error("Could not find 'CAT ' tag to determine resource size");
}
size += 4 + in->readUint32BE();
diff --git a/engines/agos/res.cpp b/engines/agos/res.cpp
index 69447f4b83..0305879390 100644
--- a/engines/agos/res.cpp
+++ b/engines/agos/res.cpp
@@ -47,12 +47,37 @@ void ArchiveMan::registerArchive(const Common::String &filename, int priority) {
}
#endif
-Common::SeekableReadStream *ArchiveMan::open(const Common::String &filename) {
+bool ArchiveMan::hasFile(const Common::String &name) const {
+ if (_fallBack && SearchMan.hasFile(name))
+ return true;
+
+ return Common::SearchSet::hasFile(name);
+}
+
+int ArchiveMan::listMatchingMembers(Common::ArchiveMemberList &list, const Common::String &pattern) const {
+ const int matches = _fallBack ? SearchMan.listMatchingMembers(list, pattern) : 0;
+ return matches + Common::SearchSet::listMatchingMembers(list, pattern);
+}
+
+int ArchiveMan::listMembers(Common::ArchiveMemberList &list) const {
+ const int matches = _fallBack ? SearchMan.listMembers(list) : 0;
+ return matches + Common::SearchSet::listMembers(list);
+}
+
+const Common::ArchiveMemberPtr ArchiveMan::getMember(const Common::String &name) const {
+ Common::ArchiveMemberPtr ptr = _fallBack ? SearchMan.getMember(name) : Common::ArchiveMemberPtr();
+ if (ptr)
+ return ptr;
+
+ return Common::SearchSet::getMember(name);
+}
+
+Common::SeekableReadStream *ArchiveMan::createReadStreamForMember(const Common::String &filename) const {
if (_fallBack && SearchMan.hasFile(filename)) {
return SearchMan.createReadStreamForMember(filename);
}
- return createReadStreamForMember(filename);
+ return Common::SearchSet::createReadStreamForMember(filename);
}
#ifdef ENABLE_AGOS2
@@ -173,7 +198,7 @@ void AGOSEngine_PN::loadGamePcFile() {
if (getFileName(GAME_BASEFILE) != NULL) {
// Read dataBase
- in = _archives.open(getFileName(GAME_BASEFILE));
+ in = _archives.createReadStreamForMember(getFileName(GAME_BASEFILE));
if (!in) {
error("loadGamePcFile: Can't load database file '%s'", getFileName(GAME_BASEFILE));
}
@@ -191,7 +216,7 @@ void AGOSEngine_PN::loadGamePcFile() {
if (getFileName(GAME_TEXTFILE) != NULL) {
// Read textBase
- in = _archives.open(getFileName(GAME_TEXTFILE));
+ in = _archives.createReadStreamForMember(getFileName(GAME_TEXTFILE));
if (!in) {
error("loadGamePcFile: Can't load textbase file '%s'", getFileName(GAME_TEXTFILE));
}
@@ -214,7 +239,7 @@ void AGOSEngine::loadGamePcFile() {
if (getFileName(GAME_BASEFILE) != NULL) {
/* Read main gamexx file */
- in = _archives.open(getFileName(GAME_BASEFILE));
+ in = _archives.createReadStreamForMember(getFileName(GAME_BASEFILE));
if (!in) {
error("loadGamePcFile: Can't load gamexx file '%s'", getFileName(GAME_BASEFILE));
}
@@ -240,7 +265,7 @@ void AGOSEngine::loadGamePcFile() {
if (getFileName(GAME_TBLFILE) != NULL) {
/* Read list of TABLE resources */
- in = _archives.open(getFileName(GAME_TBLFILE));
+ in = _archives.createReadStreamForMember(getFileName(GAME_TBLFILE));
if (!in) {
error("loadGamePcFile: Can't load table resources file '%s'", getFileName(GAME_TBLFILE));
}
@@ -261,7 +286,7 @@ void AGOSEngine::loadGamePcFile() {
if (getFileName(GAME_STRFILE) != NULL) {
/* Read list of TEXT resources */
- in = _archives.open(getFileName(GAME_STRFILE));
+ in = _archives.createReadStreamForMember(getFileName(GAME_STRFILE));
if (!in)
error("loadGamePcFile: Can't load text resources file '%s'", getFileName(GAME_STRFILE));
@@ -275,7 +300,7 @@ void AGOSEngine::loadGamePcFile() {
if (getFileName(GAME_STATFILE) != NULL) {
/* Read list of ROOM STATE resources */
- in = _archives.open(getFileName(GAME_STATFILE));
+ in = _archives.createReadStreamForMember(getFileName(GAME_STATFILE));
if (!in) {
error("loadGamePcFile: Can't load state resources file '%s'", getFileName(GAME_STATFILE));
}
@@ -298,7 +323,7 @@ void AGOSEngine::loadGamePcFile() {
if (getFileName(GAME_RMSLFILE) != NULL) {
/* Read list of ROOM ITEMS resources */
- in = _archives.open(getFileName(GAME_RMSLFILE));
+ in = _archives.createReadStreamForMember(getFileName(GAME_RMSLFILE));
if (!in) {
error("loadGamePcFile: Can't load room resources file '%s'", getFileName(GAME_RMSLFILE));
}
@@ -314,7 +339,7 @@ void AGOSEngine::loadGamePcFile() {
if (getFileName(GAME_XTBLFILE) != NULL) {
/* Read list of XTABLE resources */
- in = _archives.open(getFileName(GAME_XTBLFILE));
+ in = _archives.createReadStreamForMember(getFileName(GAME_XTBLFILE));
if (!in) {
error("loadGamePcFile: Can't load xtable resources file '%s'", getFileName(GAME_XTBLFILE));
}
@@ -815,7 +840,7 @@ void AGOSEngine::loadVGABeardFile(uint16 id) {
sprintf(filename, "0%d.VGA", id);
}
- in = _archives.open(filename);
+ in = _archives.createReadStreamForMember(filename);
if (!in)
error("loadSimonVGAFile: Can't load %s", filename);
@@ -893,7 +918,7 @@ void AGOSEngine::loadVGAVideoFile(uint16 id, uint8 type, bool useError) {
}
}
- in = _archives.open(filename);
+ in = _archives.createReadStreamForMember(filename);
if (!in) {
if (useError)
error("loadVGAVideoFile: Can't load %s", filename);
diff --git a/engines/agos/res_snd.cpp b/engines/agos/res_snd.cpp
index b5612d710d..2777d4f269 100644
--- a/engines/agos/res_snd.cpp
+++ b/engines/agos/res_snd.cpp
@@ -452,7 +452,7 @@ static const char *const dimpSoundList[32] = {
void AGOSEngine::loadSoundFile(const char* filename) {
Common::SeekableReadStream *in;
- in = _archives.open(filename);
+ in = _archives.createReadStreamForMember(filename);
if (!in)
error("loadSound: Can't load %s", filename);
@@ -475,7 +475,7 @@ void AGOSEngine::loadSound(uint16 sound, int16 pan, int16 vol, uint16 type) {
assert(sound >= 1 && sound <= 32);
sprintf(filename, "%s.wav", dimpSoundList[sound - 1]);
- in = _archives.open(filename);
+ in = _archives.createReadStreamForMember(filename);
if (!in)
error("loadSound: Can't load %s", filename);
@@ -495,7 +495,7 @@ void AGOSEngine::loadSound(uint16 sound, int16 pan, int16 vol, uint16 type) {
}
if (getPlatform() == Common::kPlatformAmiga)
- sprintf(filename, "sfx%d.wav", file);
+ sprintf(filename, "sfx%u.wav", file);
else
sprintf(filename, "effects.wav");
@@ -606,7 +606,7 @@ void AGOSEngine::loadVoice(uint speechId) {
}
if (getPlatform() == Common::kPlatformAmiga)
- sprintf(filename, "sp%d.wav", file);
+ sprintf(filename, "sp%u.wav", file);
else
sprintf(filename, "speech.wav");
diff --git a/engines/agos/saveload.cpp b/engines/agos/saveload.cpp
index 6779eabdbf..4fbde09ff8 100644
--- a/engines/agos/saveload.cpp
+++ b/engines/agos/saveload.cpp
@@ -1019,7 +1019,7 @@ bool AGOSEngine::loadGame(const char *filename, bool restartMode) {
if (restartMode) {
// Load restart state
- f = _archives.open(filename);
+ f = _archives.createReadStreamForMember(filename);
} else {
f = _saveFileMan->openForLoading(filename);
}
@@ -1193,7 +1193,7 @@ bool AGOSEngine_Elvira2::loadGame(const char *filename, bool restartMode) {
if (restartMode) {
// Load restart state
- f = _archives.open(filename);
+ f = _archives.createReadStreamForMember(filename);
} else {
f = _saveFileMan->openForLoading(filename);
}
@@ -1390,6 +1390,15 @@ bool AGOSEngine_Elvira2::loadGame(const char *filename, bool restartMode) {
_videoLockOut &= ~0x100;
+ // The floppy disk versions of Simon the Sorcerer 2 block changing
+ // to scrolling rooms, if the copy protection fails. But the copy
+ // protection flags are never set in the CD version.
+ // Setting this copy protection flag, allows saved games to be shared
+ // between all versions of Simon the Sorcerer 2.
+ if (getGameType() == GType_SIMON2) {
+ setBitFlag(135, 1);
+ }
+
return true;
}
diff --git a/engines/agos/script_pn.cpp b/engines/agos/script_pn.cpp
index 196350b9bf..60a1376f25 100644
--- a/engines/agos/script_pn.cpp
+++ b/engines/agos/script_pn.cpp
@@ -466,8 +466,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(static_cast<unsigned char>(*_inpp)))
- while ((*_inpp) && (isspace(static_cast<unsigned char>(*_inpp))))
+ if (Common::isSpace(*_inpp))
+ while ((*_inpp) && (Common::isSpace(*_inpp)))
_inpp++;
if (*_inpp == 0) {
setScriptReturn(false);
@@ -481,7 +481,7 @@ void AGOSEngine_PN::opn_opcode36() {
}
int ct = 1;
- while ((*_inpp != '.') && (*_inpp != ',') && (!isspace(static_cast<unsigned char>(*_inpp))) && (*_inpp != '\0') &&
+ while ((*_inpp != '.') && (*_inpp != ',') && (!Common::isSpace(*_inpp)) && (*_inpp != '\0') &&
(*_inpp!='"')) {
if (ct < _dataBase[57])
_wordcp[ct++] = *_inpp;
@@ -581,7 +581,7 @@ void AGOSEngine_PN::opn_opcode46() {
return;
}
x++;
- while ((*x != '.') && (*x != ',') && (*x != '"') && (!isspace(static_cast<unsigned char>(*x))) && (*x != '\0'))
+ while ((*x != '.') && (*x != ',') && (*x != '"') && (!Common::isSpace(*x)) && (*x != '\0'))
pcf(*x++);
setScriptReturn(true);
}
diff --git a/engines/agos/sound.cpp b/engines/agos/sound.cpp
index 11a1cd792e..85c449eafc 100644
--- a/engines/agos/sound.cpp
+++ b/engines/agos/sound.cpp
@@ -22,9 +22,9 @@
#include "common/file.h"
#include "common/memstream.h"
-#include "common/ptr.h"
#include "common/textconsole.h"
#include "common/util.h"
+#include "common/substream.h"
#include "agos/agos.h"
#include "agos/sound.h"
@@ -44,34 +44,39 @@ namespace AGOS {
class BaseSound : Common::NonCopyable {
protected:
- Common::DisposablePtr<Common::File> _file;
+ const Common::String _filename;
uint32 *_offsets;
Audio::Mixer *_mixer;
bool _freeOffsets;
+ Common::SeekableReadStream *getSoundStream(uint sound) const;
public:
- BaseSound(Audio::Mixer *mixer, Common::File *file, uint32 base, bool bigEndian, DisposeAfterUse::Flag disposeFileAfterUse = DisposeAfterUse::YES);
- BaseSound(Audio::Mixer *mixer, Common::File *file, uint32 *offsets, DisposeAfterUse::Flag disposeFileAfterUse = DisposeAfterUse::YES);
+ BaseSound(Audio::Mixer *mixer, const Common::String &filename, uint32 base, bool bigEndian);
+ BaseSound(Audio::Mixer *mixer, const Common::String &filename, uint32 *offsets);
virtual ~BaseSound();
void playSound(uint sound, Audio::Mixer::SoundType type, Audio::SoundHandle *handle, bool loop, int vol = 0) {
playSound(sound, sound, type, handle, loop, vol);
}
- virtual void playSound(uint sound, uint loopSound, Audio::Mixer::SoundType type, Audio::SoundHandle *handle, bool loop, int vol = 0) = 0;
+ virtual void playSound(uint sound, uint loopSound, Audio::Mixer::SoundType type, Audio::SoundHandle *handle, bool loop, int vol = 0);
virtual Audio::AudioStream *makeAudioStream(uint sound) = 0;
};
-BaseSound::BaseSound(Audio::Mixer *mixer, Common::File *file, uint32 base, bool bigEndian, DisposeAfterUse::Flag disposeFileAfterUse)
- : _mixer(mixer), _file(file, disposeFileAfterUse) {
+BaseSound::BaseSound(Audio::Mixer *mixer, const Common::String &filename, uint32 base, bool bigEndian)
+ : _mixer(mixer), _filename(filename), _offsets(NULL) {
uint res = 0;
uint32 size;
- _file->seek(base + sizeof(uint32), SEEK_SET);
+ Common::File file;
+ if (!file.open(_filename))
+ error("BaseSound: Could not open file \"%s\"", filename.c_str());
+
+ file.seek(base + sizeof(uint32), SEEK_SET);
if (bigEndian)
- size = _file->readUint32BE();
+ size = file.readUint32BE();
else
- size = _file->readUint32LE();
+ size = file.readUint32LE();
// The Feeble Files uses set amount of voice offsets
if (size == 0)
@@ -82,24 +87,20 @@ BaseSound::BaseSound(Audio::Mixer *mixer, Common::File *file, uint32 base, bool
_offsets = (uint32 *)malloc(size + sizeof(uint32));
_freeOffsets = true;
- _file->seek(base, SEEK_SET);
+ file.seek(base, SEEK_SET);
for (uint i = 0; i < res; i++) {
if (bigEndian)
- _offsets[i] = base + _file->readUint32BE();
+ _offsets[i] = base + file.readUint32BE();
else
- _offsets[i] = base + _file->readUint32LE();
+ _offsets[i] = base + file.readUint32LE();
}
- // only needed for mp3
- _offsets[res] = _file->size();
+ _offsets[res] = file.size();
}
-BaseSound::BaseSound(Audio::Mixer *mixer, Common::File *file, uint32 *offsets, DisposeAfterUse::Flag disposeFileAfterUse)
- : _mixer(mixer), _file(file, disposeFileAfterUse) {
-
- _offsets = offsets;
- _freeOffsets = false;
+BaseSound::BaseSound(Audio::Mixer *mixer, const Common::String &filename, uint32 *offsets)
+ : _mixer(mixer), _filename(filename), _offsets(offsets), _freeOffsets(false) {
}
BaseSound::~BaseSound() {
@@ -107,6 +108,23 @@ BaseSound::~BaseSound() {
free(_offsets);
}
+Common::SeekableReadStream *BaseSound::getSoundStream(uint sound) const {
+ if (_offsets == NULL)
+ return NULL;
+
+ Common::File *file = new Common::File();
+ if (!file->open(_filename)) {
+ warning("BaseSound::getSoundStream: Could not open file \"%s\"", _filename.c_str());
+ return NULL;
+ }
+
+ int i = 1;
+ while (_offsets[sound + i] == _offsets[sound])
+ i++;
+
+ return new Common::SeekableSubReadStream(file, _offsets[sound], _offsets[sound + i], DisposeAfterUse::YES);
+}
+
///////////////////////////////////////////////////////////////////////////////
#pragma mark -
@@ -218,26 +236,25 @@ static void convertPan(int &pan) {
///////////////////////////////////////////////////////////////////////////////
#pragma mark -
+// TODO: Move to a better place?
+void BaseSound::playSound(uint sound, uint loopSound, Audio::Mixer::SoundType type, Audio::SoundHandle *handle, bool loop, int vol) {
+ convertVolume(vol);
+ _mixer->playStream(type, handle, new LoopingAudioStream(this, sound, loopSound, loop), -1, vol);
+}
+
class WavSound : public BaseSound {
public:
- WavSound(Audio::Mixer *mixer, Common::File *file, uint32 base = 0, DisposeAfterUse::Flag disposeFileAfterUse = DisposeAfterUse::YES)
- : BaseSound(mixer, file, base, false, disposeFileAfterUse) {}
- WavSound(Audio::Mixer *mixer, Common::File *file, uint32 *offsets) : BaseSound(mixer, file, offsets) {}
+ WavSound(Audio::Mixer *mixer, const Common::String &filename, uint32 base = 0)
+ : BaseSound(mixer, filename, base, false) {}
+ WavSound(Audio::Mixer *mixer, const Common::String &filename, uint32 *offsets) : BaseSound(mixer, filename, offsets) {}
Audio::AudioStream *makeAudioStream(uint sound);
- void playSound(uint sound, uint loopSound, Audio::Mixer::SoundType type, Audio::SoundHandle *handle, bool loop, int vol = 0);
};
Audio::AudioStream *WavSound::makeAudioStream(uint sound) {
- if (_offsets == NULL)
+ Common::SeekableReadStream *tmp = getSoundStream(sound);
+ if (!tmp)
return NULL;
-
- _file->seek(_offsets[sound], SEEK_SET);
- return Audio::makeWAVStream(_file.get(), DisposeAfterUse::NO);
-}
-
-void WavSound::playSound(uint sound, uint loopSound, Audio::Mixer::SoundType type, Audio::SoundHandle *handle, bool loop, int vol) {
- convertVolume(vol);
- _mixer->playStream(type, handle, new LoopingAudioStream(this, sound, loopSound, loop), -1, vol);
+ return Audio::makeWAVStream(tmp, DisposeAfterUse::YES);
}
///////////////////////////////////////////////////////////////////////////////
@@ -246,21 +263,16 @@ void WavSound::playSound(uint sound, uint loopSound, Audio::Mixer::SoundType typ
class VocSound : public BaseSound {
const byte _flags;
public:
- VocSound(Audio::Mixer *mixer, Common::File *file, bool isUnsigned, uint32 base = 0, bool bigEndian = false, DisposeAfterUse::Flag disposeFileAfterUse = DisposeAfterUse::YES)
- : BaseSound(mixer, file, base, bigEndian, disposeFileAfterUse), _flags(isUnsigned ? Audio::FLAG_UNSIGNED : 0) {}
+ VocSound(Audio::Mixer *mixer, const Common::String &filename, bool isUnsigned, uint32 base = 0, bool bigEndian = false)
+ : BaseSound(mixer, filename, base, bigEndian), _flags(isUnsigned ? Audio::FLAG_UNSIGNED : 0) {}
Audio::AudioStream *makeAudioStream(uint sound);
- void playSound(uint sound, uint loopSound, Audio::Mixer::SoundType type, Audio::SoundHandle *handle, bool loop, int vol = 0);
};
Audio::AudioStream *VocSound::makeAudioStream(uint sound) {
- assert(_offsets);
- _file->seek(_offsets[sound], SEEK_SET);
- return Audio::makeVOCStream(_file.get(), _flags);
-}
-
-void VocSound::playSound(uint sound, uint loopSound, Audio::Mixer::SoundType type, Audio::SoundHandle *handle, bool loop, int vol) {
- convertVolume(vol);
- _mixer->playStream(type, handle, new LoopingAudioStream(this, sound, loopSound, loop), -1, vol);
+ Common::SeekableReadStream *tmp = getSoundStream(sound);
+ if (!tmp)
+ return NULL;
+ return Audio::makeVOCStream(tmp, _flags, DisposeAfterUse::YES);
}
///////////////////////////////////////////////////////////////////////////////
@@ -270,8 +282,8 @@ void VocSound::playSound(uint sound, uint loopSound, Audio::Mixer::SoundType typ
class RawSound : public BaseSound {
const byte _flags;
public:
- RawSound(Audio::Mixer *mixer, Common::File *file, bool isUnsigned)
- : BaseSound(mixer, file, 0, SOUND_BIG_ENDIAN), _flags(isUnsigned ? Audio::FLAG_UNSIGNED : 0) {}
+ RawSound(Audio::Mixer *mixer, const Common::String &filename, bool isUnsigned)
+ : BaseSound(mixer, filename, 0, SOUND_BIG_ENDIAN), _flags(isUnsigned ? Audio::FLAG_UNSIGNED : 0) {}
Audio::AudioStream *makeAudioStream(uint sound);
void playSound(uint sound, uint loopSound, Audio::Mixer::SoundType type, Audio::SoundHandle *handle, bool loop, int vol = 0);
};
@@ -280,14 +292,15 @@ Audio::AudioStream *RawSound::makeAudioStream(uint sound) {
if (_offsets == NULL)
return NULL;
- _file->seek(_offsets[sound], SEEK_SET);
-
- uint size = _file->readUint32BE();
- byte *buffer = (byte *)malloc(size);
- assert(buffer);
- _file->read(buffer, size);
-
- return Audio::makeRawStream(buffer, size, 22050, _flags);
+ Common::File *file = new Common::File();
+ if (!file->open(_filename)) {
+ warning("RawSound::makeAudioStream: Could not open file \"%s\"", _filename.c_str());
+ return NULL;
+ }
+
+ file->seek(_offsets[sound], SEEK_SET);
+ uint size = file->readUint32BE();
+ return Audio::makeRawStream(new Common::SeekableSubReadStream(file, _offsets[sound] + 4, _offsets[sound] + 4 + size, DisposeAfterUse::YES), 22050, _flags, DisposeAfterUse::YES);
}
void RawSound::playSound(uint sound, uint loopSound, Audio::Mixer::SoundType type, Audio::SoundHandle *handle, bool loop, int vol) {
@@ -298,40 +311,15 @@ void RawSound::playSound(uint sound, uint loopSound, Audio::Mixer::SoundType typ
///////////////////////////////////////////////////////////////////////////////
#pragma mark -
-class CompressedSound : public BaseSound {
-public:
- CompressedSound(Audio::Mixer *mixer, Common::File *file, uint32 base) : BaseSound(mixer, file, base, false) {}
-
- Common::SeekableReadStream *loadStream(uint sound) const {
- if (_offsets == NULL)
- return NULL;
-
- _file->seek(_offsets[sound], SEEK_SET);
-
- int i = 1;
- while (_offsets[sound + i] == _offsets[sound])
- i++;
-
- uint32 size = _offsets[sound + i] - _offsets[sound];
-
- return _file->readStream(size);
- }
-
- void playSound(uint sound, uint loopSound, Audio::Mixer::SoundType type, Audio::SoundHandle *handle, bool loop, int vol = 0) {
- convertVolume(vol);
- _mixer->playStream(type, handle, new LoopingAudioStream(this, sound, loopSound, loop), -1, vol);
- }
-};
-
///////////////////////////////////////////////////////////////////////////////
#pragma mark -
#ifdef USE_MAD
-class MP3Sound : public CompressedSound {
+class MP3Sound : public BaseSound {
public:
- MP3Sound(Audio::Mixer *mixer, Common::File *file, uint32 base = 0) : CompressedSound(mixer, file, base) {}
+ MP3Sound(Audio::Mixer *mixer, const Common::String &filename, uint32 base = 0) : BaseSound(mixer, filename, base, false) {}
Audio::AudioStream *makeAudioStream(uint sound) {
- Common::SeekableReadStream *tmp = loadStream(sound);
+ Common::SeekableReadStream *tmp = getSoundStream(sound);
if (!tmp)
return NULL;
return Audio::makeMP3Stream(tmp, DisposeAfterUse::YES);
@@ -343,11 +331,11 @@ public:
#pragma mark -
#ifdef USE_VORBIS
-class VorbisSound : public CompressedSound {
+class VorbisSound : public BaseSound {
public:
- VorbisSound(Audio::Mixer *mixer, Common::File *file, uint32 base = 0) : CompressedSound(mixer, file, base) {}
+ VorbisSound(Audio::Mixer *mixer, const Common::String &filename, uint32 base = 0) : BaseSound(mixer, filename, base, false) {}
Audio::AudioStream *makeAudioStream(uint sound) {
- Common::SeekableReadStream *tmp = loadStream(sound);
+ Common::SeekableReadStream *tmp = getSoundStream(sound);
if (!tmp)
return NULL;
return Audio::makeVorbisStream(tmp, DisposeAfterUse::YES);
@@ -359,11 +347,11 @@ public:
#pragma mark -
#ifdef USE_FLAC
-class FLACSound : public CompressedSound {
+class FLACSound : public BaseSound {
public:
- FLACSound(Audio::Mixer *mixer, Common::File *file, uint32 base = 0) : CompressedSound(mixer, file, base) {}
+ FLACSound(Audio::Mixer *mixer, const Common::String &filename, uint32 base = 0) : BaseSound(mixer, filename, base, false) {}
Audio::AudioStream *makeAudioStream(uint sound) {
- Common::SeekableReadStream *tmp = loadStream(sound);
+ Common::SeekableReadStream *tmp = getSoundStream(sound);
if (!tmp)
return NULL;
return Audio::makeFLACStream(tmp, DisposeAfterUse::YES);
@@ -374,25 +362,23 @@ public:
///////////////////////////////////////////////////////////////////////////////
#pragma mark -
-static CompressedSound *makeCompressedSound(Audio::Mixer *mixer, Common::File *file, const Common::String &basename) {
+static BaseSound *makeSound(Audio::Mixer *mixer, const Common::String &basename) {
#ifdef USE_FLAC
- file->open(basename + ".fla");
- if (file->isOpen()) {
- return new FLACSound(mixer, file);
- }
+ if (Common::File::exists(basename + ".fla"))
+ return new FLACSound(mixer, basename + ".fla");
#endif
#ifdef USE_VORBIS
- file->open(basename + ".ogg");
- if (file->isOpen()) {
- return new VorbisSound(mixer, file);
- }
+ if (Common::File::exists(basename + ".ogg"))
+ return new VorbisSound(mixer, basename + ".ogg");
#endif
#ifdef USE_MAD
- file->open(basename + ".mp3");
- if (file->isOpen()) {
- return new MP3Sound(mixer, file);
- }
+ if (Common::File::exists(basename + ".mp3"))
+ return new MP3Sound(mixer, basename + ".mp3");
#endif
+ if (Common::File::exists(basename + ".wav"))
+ return new WavSound(mixer, basename + ".wav");
+ if (Common::File::exists(basename + ".voc"))
+ return new VocSound(mixer, basename + ".voc", true);
return 0;
}
@@ -441,90 +427,59 @@ Sound::~Sound() {
void Sound::loadVoiceFile(const GameSpecificSettings *gss) {
// Game versions which use separate voice files
- if (_vm->getGameType() == GType_FF || _vm->getGameId() == GID_SIMON1CD32)
+ if (_hasVoiceFile || _vm->getGameType() == GType_FF || _vm->getGameId() == GID_SIMON1CD32)
return;
+ _voice = makeSound(_mixer, gss->speech_filename);
+ _hasVoiceFile = (_voice != 0);
- char filename[16];
- Common::File *file = new Common::File();
+ if (_hasVoiceFile)
+ return;
- if (!_hasVoiceFile) {
- _voice = makeCompressedSound(_mixer, file, gss->speech_filename);
- _hasVoiceFile = (_voice != 0);
- }
- if (!_hasVoiceFile && _vm->getGameType() == GType_SIMON2) {
+ if (_vm->getGameType() == GType_SIMON2) {
// for simon2 mac/amiga, only read index file
- file->open("voices.idx");
- if (file->isOpen() == true) {
- int end = file->size();
+ Common::File file;
+ if (file.open("voices.idx")) {
+ int end = file.size();
_filenums = (uint16 *)malloc((end / 6 + 1) * 2);
_offsets = (uint32 *)malloc((end / 6 + 1) * 4);
for (int i = 1; i <= end / 6; i++) {
- _filenums[i] = file->readUint16BE();
- _offsets[i] = file->readUint32BE();
+ _filenums[i] = file.readUint16BE();
+ _offsets[i] = file.readUint32BE();
}
+
_hasVoiceFile = true;
- }
- }
- if (!_hasVoiceFile) {
- sprintf(filename, "%s.wav", gss->speech_filename);
- file->open(filename);
- if (file->isOpen()) {
- _hasVoiceFile = true;
- _voice = new WavSound(_mixer, file);
+ return;
}
}
const bool dataIsUnsigned = true;
- if (!_hasVoiceFile) {
- sprintf(filename, "%s.voc", gss->speech_filename);
- file->open(filename);
- if (file->isOpen()) {
- _hasVoiceFile = true;
- _voice = new VocSound(_mixer, file, dataIsUnsigned);
- }
- }
- if (!_hasVoiceFile) {
- sprintf(filename, "%s", gss->speech_filename);
- file->open(filename);
- if (file->isOpen()) {
- _hasVoiceFile = true;
- if (_vm->getGameType() == GType_PP)
- _voice = new WavSound(_mixer, file);
- else
- _voice = new VocSound(_mixer, file, dataIsUnsigned);
- }
+ if (Common::File::exists(gss->speech_filename)) {
+ _hasVoiceFile = true;
+ if (_vm->getGameType() == GType_PP)
+ _voice = new WavSound(_mixer, gss->speech_filename);
+ else
+ _voice = new VocSound(_mixer, gss->speech_filename, dataIsUnsigned);
}
}
void Sound::loadSfxFile(const GameSpecificSettings *gss) {
- char filename[16];
- Common::File *file = new Common::File();
+ if (_hasEffectsFile)
+ return;
- if (!_hasEffectsFile) {
- _effects = makeCompressedSound(_mixer, file, gss->effects_filename);
- _hasEffectsFile = (_effects != 0);
- }
+ _effects = makeSound(_mixer, gss->effects_filename);
+ _hasEffectsFile = (_effects != 0);
+
+ if (_hasEffectsFile)
+ return;
const bool dataIsUnsigned = true;
- if (!_hasEffectsFile) {
- sprintf(filename, "%s.voc", gss->effects_filename);
- file->open(filename);
- if (file->isOpen()) {
- _hasEffectsFile = true;
- _effects = new VocSound(_mixer, file, dataIsUnsigned);
- }
- }
- if (!_hasEffectsFile) {
- sprintf(filename, "%s", gss->effects_filename);
- file->open(filename);
- if (file->isOpen()) {
- _hasEffectsFile = true;
- _effects = new VocSound(_mixer, file, dataIsUnsigned);
- }
+ if (Common::File::exists(gss->effects_filename)) {
+ _hasEffectsFile = true;
+ _effects = new VocSound(_mixer, gss->effects_filename, dataIsUnsigned);
}
}
@@ -535,10 +490,7 @@ void Sound::readSfxFile(const Common::String &filename) {
_mixer->stopHandle(_effectsHandle);
- Common::File *file = new Common::File();
- file->open(filename);
-
- if (file->isOpen() == false) {
+ if (!Common::File::exists(filename)) {
error("readSfxFile: Can't load sfx file %s", filename.c_str());
}
@@ -546,37 +498,34 @@ void Sound::readSfxFile(const Common::String &filename) {
delete _effects;
if (_vm->getGameId() == GID_SIMON1CD32) {
- _effects = new VocSound(_mixer, file, dataIsUnsigned, 0, SOUND_BIG_ENDIAN);
+ _effects = new VocSound(_mixer, filename, dataIsUnsigned, 0, SOUND_BIG_ENDIAN);
} else
- _effects = new WavSound(_mixer, file);
+ _effects = new WavSound(_mixer, filename);
}
// This method is only used by Simon2
-void Sound::loadSfxTable(Common::File *gameFile, uint32 base) {
+void Sound::loadSfxTable(const char *gameFilename, uint32 base) {
stopAll();
delete _effects;
const bool dataIsUnsigned = true;
if (_vm->getPlatform() == Common::kPlatformWindows)
- _effects = new WavSound(_mixer, gameFile, base, DisposeAfterUse::NO);
+ _effects = new WavSound(_mixer, gameFilename, base);
else
- _effects = new VocSound(_mixer, gameFile, dataIsUnsigned, base, false, DisposeAfterUse::NO);
+ _effects = new VocSound(_mixer, gameFilename, dataIsUnsigned, base, false);
}
// This method is only used by Simon1 Amiga CD32
void Sound::readVoiceFile(const Common::String &filename) {
_mixer->stopHandle(_voiceHandle);
- Common::File *file = new Common::File();
- file->open(filename);
-
- if (file->isOpen() == false)
+ if (!Common::File::exists(filename))
error("readVoiceFile: Can't load voice file %s", filename.c_str());
const bool dataIsUnsigned = false;
delete _voice;
- _voice = new RawSound(_mixer, file, dataIsUnsigned);
+ _voice = new RawSound(_mixer, filename, dataIsUnsigned);
}
void Sound::playVoice(uint sound) {
@@ -587,13 +536,11 @@ void Sound::playVoice(uint sound) {
char filename[16];
_lastVoiceFile = _filenums[sound];
sprintf(filename, "voices%d.dat", _filenums[sound]);
- Common::File *file = new Common::File();
- file->open(filename);
- if (file->isOpen() == false)
+ if (!Common::File::exists(filename))
error("playVoice: Can't load voice file %s", filename);
delete _voice;
- _voice = new WavSound(_mixer, file, _offsets);
+ _voice = new WavSound(_mixer, filename, _offsets);
}
}
@@ -606,8 +553,6 @@ void Sound::playVoice(uint sound) {
_voice->playSound(sound, sound + 1, Audio::Mixer::kMusicSoundType, &_voiceHandle, true, -1500);
else
_voice->playSound(sound, sound, Audio::Mixer::kMusicSoundType, &_voiceHandle, true);
- } else if (_vm->getGameType() == GType_FF || _vm->getGameId() == GID_SIMON1CD32) {
- _voice->playSound(sound, Audio::Mixer::kSpeechSoundType, &_voiceHandle, false);
} else {
_voice->playSound(sound, Audio::Mixer::kSpeechSoundType, &_voiceHandle, false);
}
@@ -796,22 +741,13 @@ void Sound::switchVoiceFile(const GameSpecificSettings *gss, uint disc) {
_lastVoiceFile = disc;
char filename[16];
- Common::File *file = new Common::File();
- if (!_hasVoiceFile) {
- sprintf(filename, "%s%d", gss->speech_filename, disc);
- _voice = makeCompressedSound(_mixer, file, filename);
- _hasVoiceFile = (_voice != 0);
- }
- if (!_hasVoiceFile) {
- sprintf(filename, "%s%d.wav", gss->speech_filename, disc);
- file->open(filename);
- if (file->isOpen() == false) {
- error("switchVoiceFile: Can't load voice file %s", filename);
- }
- _hasVoiceFile = true;
- _voice = new WavSound(_mixer, file);
- }
+ sprintf(filename, "%s%u", gss->speech_filename, disc);
+ _voice = makeSound(_mixer, filename);
+ _hasVoiceFile = (_voice != 0);
+
+ if (!_hasVoiceFile)
+ error("switchVoiceFile: Can't load voice file %s", filename);
}
} // End of namespace AGOS
diff --git a/engines/agos/sound.h b/engines/agos/sound.h
index ab4a3a963d..8633fe2f70 100644
--- a/engines/agos/sound.h
+++ b/engines/agos/sound.h
@@ -85,7 +85,7 @@ protected:
public:
void readSfxFile(const Common::String &filename);
- void loadSfxTable(Common::File *gameFile, uint32 base);
+ void loadSfxTable(const char *gameFilename, uint32 base);
void readVoiceFile(const Common::String &filename);
void playVoice(uint sound);
diff --git a/engines/agos/string.cpp b/engines/agos/string.cpp
index 410fd5a1ce..ee1b9df246 100644
--- a/engines/agos/string.cpp
+++ b/engines/agos/string.cpp
@@ -152,7 +152,7 @@ const byte *AGOSEngine::getStringPtrByID(uint16 stringId, bool upperCase) {
}
if (upperCase && *dst) {
- if (islower(*dst))
+ if (Common::isLower(*dst))
*dst = toupper(*dst);
}
diff --git a/engines/agos/string_pn.cpp b/engines/agos/string_pn.cpp
index ac8c263da3..4d4e2be16a 100644
--- a/engines/agos/string_pn.cpp
+++ b/engines/agos/string_pn.cpp
@@ -137,7 +137,7 @@ void AGOSEngine_PN::pcf(uint8 ch) {
if ((ch != 32) || (_bp + _xofs != 50))
_buffer[_bp++] = ch;
}
- if ((ch != 254) && (!isspace(ch)) && (_bp < 60))
+ if ((ch != 254) && (!Common::isSpace(ch)) && (_bp < 60))
return;
/* We know have a case of needing to print the text */
if (_bp + _xofs > 50) {
diff --git a/engines/agos/subroutine.cpp b/engines/agos/subroutine.cpp
index 10c1c1aaf9..f5aad2dcc8 100644
--- a/engines/agos/subroutine.cpp
+++ b/engines/agos/subroutine.cpp
@@ -266,7 +266,7 @@ Common::SeekableReadStream *AGOSEngine::openTablesFile(const char *filename) {
}
Common::SeekableReadStream *AGOSEngine::openTablesFile_simon1(const char *filename) {
- Common::SeekableReadStream *in = _archives.open(filename);
+ Common::SeekableReadStream *in = _archives.createReadStreamForMember(filename);
if (!in)
error("openTablesFile: Can't open '%s'", filename);
return in;
@@ -369,7 +369,7 @@ bool AGOSEngine_Waxworks::loadTablesIntoMem(uint16 subrId) {
readSubroutineBlock(in);
closeTablesFile(in);
if (getGameType() == GType_SIMON2) {
- _sound->loadSfxTable(_gameFile, _gameOffsetsPtr[atoi(filename.c_str() + 6) - 1 + _soundIndexBase]);
+ _sound->loadSfxTable(getFileName(GAME_GMEFILE), _gameOffsetsPtr[atoi(filename.c_str() + 6) - 1 + _soundIndexBase]);
} else if (getGameType() == GType_SIMON1 && getPlatform() == Common::kPlatformWindows) {
filename.setChar('S', 0);
filename.setChar('F', 1);
@@ -558,7 +558,6 @@ restart:
while ((byte *)sl != (byte *)sub) {
_currentLine = sl;
if (checkIfToRunSubroutineLine(sl, sub)) {
- result = 0;
_codePtr = (byte *)sl;
if (sub->id)
_codePtr += 2;
diff --git a/engines/cge/bitmap.cpp b/engines/cge/bitmap.cpp
index 39bafc5e98..37f4eb070e 100644
--- a/engines/cge/bitmap.cpp
+++ b/engines/cge/bitmap.cpp
@@ -136,7 +136,7 @@ Bitmap &Bitmap::operator=(const Bitmap &bmp) {
} else {
uint16 vsiz = (uint8 *)bmp._b - (uint8 *)v0;
uint16 siz = vsiz + _h * sizeof(HideDesc);
- uint8 *v1 = (uint8 *)malloc(sizeof(uint8) * siz);
+ uint8 *v1 = new uint8[siz];
assert(v1 != NULL);
memcpy(v1, v0, siz);
_b = (HideDesc *)((_v = v1) + vsiz);
@@ -154,20 +154,6 @@ char *Bitmap::forceExt(char *buf, const char *name, const char *ext) {
return buf;
}
-uint16 Bitmap::moveVmap(uint8 *buf) {
- debugC(1, kCGEDebugBitmap, "Bitmap::moveVmap(buf)");
-
- if (!_v)
- return 0;
-
- uint16 vsiz = (uint8 *)_b - (uint8 *)_v;
- uint16 siz = vsiz + _h * sizeof(HideDesc);
- memcpy(buf, _v, siz);
- delete[] _v;
- _b = (HideDesc *)((_v = buf) + vsiz);
- return siz;
-}
-
BitmapPtr Bitmap::code() {
debugC(1, kCGEDebugBitmap, "Bitmap::code()");
@@ -212,7 +198,7 @@ BitmapPtr Bitmap::code() {
if ((pix == kPixelTransp) != skip || cnt >= 0x3FF0) { // end of block
cnt |= (skip) ? kBmpSKP : kBmpCPY;
if (_v)
- *cp = TO_LE_16(cnt); // store block description uint16
+ WRITE_LE_UINT16(cp, cnt); // store block description uint16
cp = (uint16 *) im;
im += 2;
@@ -234,7 +220,7 @@ BitmapPtr Bitmap::code() {
} else {
cnt |= kBmpCPY;
if (_v)
- *cp = TO_LE_16(cnt);
+ WRITE_LE_UINT16(cp, cnt);
cp = (uint16 *) im;
im += 2;
@@ -246,13 +232,13 @@ BitmapPtr Bitmap::code() {
if (cnt && ! skip) {
cnt |= kBmpCPY;
if (_v)
- *cp = TO_LE_16(cnt);
+ WRITE_LE_UINT16(cp, cnt);
cp = (uint16 *) im;
im += 2;
}
if (_v)
- *cp = TO_LE_16(kBmpEOI);
+ WRITE_LE_UINT16(cp, kBmpEOI);
cp = (uint16 *) im;
im += 2;
}
diff --git a/engines/cge/bitmap.h b/engines/cge/bitmap.h
index aa6282705c..3de05ac2fd 100644
--- a/engines/cge/bitmap.h
+++ b/engines/cge/bitmap.h
@@ -49,7 +49,7 @@ enum {
struct HideDesc {
uint16 _skip;
uint16 _hide;
-};
+} PACKED_STRUCT;
#include "common/pack-end.h"
@@ -77,7 +77,6 @@ public:
void show(int16 x, int16 y);
void xShow(int16 x, int16 y);
bool solidAt(int16 x, int16 y);
- uint16 moveVmap(uint8 *buf);
};
diff --git a/engines/cge/cge.cpp b/engines/cge/cge.cpp
index 4ed2932cd9..875ac34cd0 100644
--- a/engines/cge/cge.cpp
+++ b/engines/cge/cge.cpp
@@ -28,6 +28,7 @@
#include "common/EventRecorder.h"
#include "common/file.h"
#include "common/fs.h"
+#include "engines/advancedDetector.h"
#include "engines/util.h"
#include "cge/cge.h"
#include "cge/vga13h.h"
@@ -53,9 +54,8 @@ CGEEngine::CGEEngine(OSystem *syst, const ADGameDescription *gameDescription)
_oldLev = 0;
_pocPtr = 0;
_bitmapPalette = NULL;
-
-
-
+ _quitFlag = false;
+ _showBoundariesFl = false;
}
void CGEEngine::initSceneValues() {
@@ -91,7 +91,7 @@ void CGEEngine::init() {
_font = new Font(this, "CGE");
_text = new Text(this, "CGE");
_talk = NULL;
- _vga = new Vga();
+ _vga = new Vga(this);
_sys = new System(this);
_pocLight = new PocLight(this);
for (int i = 0; i < kPocketNX; i++)
@@ -144,7 +144,6 @@ void CGEEngine::deinit() {
DebugMan.clearAllDebugChannels();
delete _console;
- _midiPlayer->killMidi();
// Delete engine objects
delete _vga;
@@ -161,8 +160,9 @@ void CGEEngine::deinit() {
delete _keyboard;
delete _mouse;
delete _eventManager;
- delete _fx;
delete _sound;
+ delete _fx;
+ delete _midiPlayer;
delete _font;
delete _commandHandler;
delete _commandHandlerTurbo;
@@ -214,7 +214,8 @@ bool CGEEngine::canLoadGameStateCurrently() {
}
bool CGEEngine::canSaveGameStateCurrently() {
- return (_startupMode == 0) && _mouse->_active;
+ return (_startupMode == 0) && _mouse->_active &&
+ _commandHandler->idle() && !_hero->_flags._hide;
}
} // End of namespace CGE
diff --git a/engines/cge/cge.h b/engines/cge/cge.h
index 2ce154a4fb..4ebc836ee0 100644
--- a/engines/cge/cge.h
+++ b/engines/cge/cge.h
@@ -31,11 +31,12 @@
#include "engines/engine.h"
#include "gui/debugger.h"
#include "graphics/surface.h"
-#include "engines/advancedDetector.h"
#include "cge/console.h"
#include "cge/bitmap.h"
#include "cge/sound.h"
+struct ADGameDescription;
+
namespace CGE {
class Console;
@@ -73,8 +74,9 @@ class Talk;
#define kPathMax 128
#define kCryptSeed 0xA5
#define kMaxFile 128
-#define kMapXCnt 40
-#define kMapZCnt 20
+#define kMapXCnt 40
+#define kMapZCnt 20
+#define kMapTop 80
// our engine debug channels
enum {
@@ -140,6 +142,8 @@ public:
virtual Common::Error saveGameState(int slot, const Common::String &desc);
static const int _maxSceneArr[5];
+ bool _quitFlag;
+ bool _showBoundariesFl;
const ADGameDescription *_gameDescription;
int _startupMode;
@@ -222,7 +226,7 @@ public:
void runGame();
bool showTitle(const char *name);
void movie(const char *ext);
- void inf(const char *text);
+ void inf(const char *text, bool wideSpace = false);
void selectSound();
void dummy() {}
void NONE();
diff --git a/engines/cge/cge_main.cpp b/engines/cge/cge_main.cpp
index 1c2759bd97..fd7dd85c57 100644
--- a/engines/cge/cge_main.cpp
+++ b/engines/cge/cge_main.cpp
@@ -185,7 +185,7 @@ void CGEEngine::syncHeader(Common::Serializer &s) {
s.syncAsUint16LE(checksum);
} else {
// Read checksum and validate it
- uint16 checksum;
+ uint16 checksum = 0;
s.syncAsUint16LE(checksum);
if (checksum != kSavegameCheckSum)
error("%s", _text->getText(kBadSVG));
@@ -200,7 +200,7 @@ bool CGEEngine::loadGame(int slotNumber, SavegameHeader *header, bool tiny) {
if (slotNumber == -1) {
// Loading the data for the initial game state
- kSavegame0File file = kSavegame0File(this, kSavegame0Name);
+ EncryptedStream file = EncryptedStream(this, kSavegame0Name);
int size = file.size();
byte *dataBuffer = (byte *)malloc(size);
file.read(dataBuffer, size);
@@ -277,7 +277,12 @@ Common::String CGEEngine::generateSaveName(int slot) {
Common::Error CGEEngine::loadGameState(int slot) {
// Clear current game activity
sceneDown();
+ _hero->park();
resetGame();
+
+ // If music is playing, kill it.
+ if (_music)
+ _midiPlayer->killMidi();
// Load the game
loadGame(slot, NULL);
@@ -291,10 +296,12 @@ Common::Error CGEEngine::loadGameState(int slot) {
void CGEEngine::resetGame() {
_vga->_spareQ->clear();
+ _commandHandler->reset();
}
Common::Error CGEEngine::saveGameState(int slot, const Common::String &desc) {
sceneDown();
+ _hero->park();
_oldLev = _lev;
// Write out the user's progress
@@ -685,6 +692,8 @@ void CGEEngine::xScene() {
debugC(6, kCGEDebugEngine, "CGEEngine::xScene()");
sceneDown();
+ if (_lev != -1)
+ _commandHandler->addCommand(kCmdLevel, -1, _lev, &_sceneLight);
sceneUp();
}
@@ -692,6 +701,7 @@ void CGEEngine::qGame() {
debugC(1, kCGEDebugEngine, "CGEEngine::qGame()");
sceneDown();
+ _hero->park();
_oldLev = _lev;
// Write out the user's progress
@@ -716,7 +726,7 @@ void CGEEngine::switchScene(int newScene) {
if (_hero) {
_hero->park();
_hero->step(0);
- _vga->_spareQ->_show = 0;
+ _vga->_spareQ->_show = false;
}
_sceneLight->gotoxy(kSceneX + ((_now - 1) % kSceneNx) * kSceneDx + kSceneSX,
kSceneY + ((_now - 1) / kSceneNx) * kSceneDy + kSceneSY);
@@ -725,6 +735,7 @@ void CGEEngine::switchScene(int newScene) {
keyClick();
_commandHandler->addCommand(kCmdLabel, -1, 0, NULL); // wait for repaint
_commandHandler->addCallback(kCmdExec, 0, 0, kXScene); // switch scene
+
}
}
@@ -753,27 +764,14 @@ void System::touch(uint16 mask, int x, int y) {
funTouch();
if (mask & kEventKeyb) {
- _vm->keyClick();
- _vm->killText();
- if (_vm->_startupMode == 1) {
- _vm->_commandHandler->addCommand(kCmdClear, -1, 0, NULL);
- return;
- }
- switch (x) {
- case 'X':
- if (_vm->_keyboard->_key[kKeyAlt])
- _vm->quit();
- break;
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- if (_vm->_keyboard->_key[kKeyAlt]) {
- _vm->_commandHandler->addCommand(kCmdLevel, -1, x - '0', NULL);
- break;
+ if (x == Common::KEYCODE_ESCAPE) {
+ // The original was calling keyClick()
+ // The sound is uselessly annoying and noisy, so it has been removed
+ _vm->killText();
+ if (_vm->_startupMode == 1) {
+ _vm->_commandHandler->addCommand(kCmdClear, -1, 0, NULL);
+ return;
}
- break;
}
} else {
if (_vm->_startupMode)
@@ -830,7 +828,7 @@ void System::tick() {
if (_vm->_commandHandler->idle()) {
if (_vm->_flag[0]) // Pain flag
_vm->heroCover(9);
- else { // CHECKME: Before, was: if (Startup::_core >= CORE_MID) {
+ else {
int n = _vm->newRandom(100);
if (n > 96)
_vm->heroCover(6 + (_vm->_hero->_x + _vm->_hero->_w / 2 < kScrWidth / 2));
@@ -920,7 +918,7 @@ void CGEEngine::optionTouch(int opt, uint16 mask) {
if (mask & kMouseLeftUp)
switchMusic();
else if (mask & kMouseRightUp)
- warning("TODO: Use ScummVM sound dialog");
+ openMainMenuDialog();
break;
case 3:
if (mask & kMouseLeftUp)
@@ -1252,12 +1250,15 @@ void CGEEngine::mainLoop() {
// Handle any pending events
_eventManager->poll();
+
+ // Check shouldQuit()
+ _quitFlag = shouldQuit();
}
void CGEEngine::handleFrame() {
// Game frame delay
uint32 millis = g_system->getMillis();
- while (!_eventManager->_quitFlag && (millis < (_lastFrame + kGameFrameDelay))) {
+ while (!_quitFlag && (millis < (_lastFrame + kGameFrameDelay))) {
// Handle any pending events
_eventManager->poll();
@@ -1306,7 +1307,7 @@ void CGEEngine::loadUser() {
}
void CGEEngine::runGame() {
- if (_eventManager->_quitFlag)
+ if (_quitFlag)
return;
loadHeroXY();
@@ -1336,9 +1337,7 @@ void CGEEngine::runGame() {
_vga->_showQ->append(_mouse);
-// ___________
loadUser();
-// ~~~~~~~~~~~
if ((_sprite = _vga->_spareQ->locate(121)) != NULL)
_commandHandlerTurbo->addCommand(kCmdSeq, -1, _vga->_mono, _sprite);
@@ -1406,7 +1405,7 @@ void CGEEngine::runGame() {
_keyboard->setClient(_sys);
// main loop
- while (!_finis && !_eventManager->_quitFlag) {
+ while (!_finis && !_quitFlag) {
if (_flag[3])
_commandHandler->addCallback(kCmdExec, -1, 0, kQGame);
mainLoop();
@@ -1429,7 +1428,7 @@ void CGEEngine::runGame() {
void CGEEngine::movie(const char *ext) {
assert(ext);
- if (_eventManager->_quitFlag)
+ if (_quitFlag)
return;
char fn[12];
@@ -1441,7 +1440,7 @@ void CGEEngine::movie(const char *ext) {
feedSnail(_vga->_showQ->locate(999), kTake);
_vga->_showQ->append(_mouse);
_keyboard->setClient(_sys);
- while (!_commandHandler->idle() && !_eventManager->_quitFlag)
+ while (!_commandHandler->idle() && !_quitFlag)
mainLoop();
_keyboard->setClient(NULL);
@@ -1453,7 +1452,7 @@ void CGEEngine::movie(const char *ext) {
}
bool CGEEngine::showTitle(const char *name) {
- if (_eventManager->_quitFlag)
+ if (_quitFlag)
return false;
_bitmapPalette = _vga->_sysPal;
@@ -1486,7 +1485,7 @@ bool CGEEngine::showTitle(const char *name) {
_mouse->on();
for (; !_commandHandler->idle() || Vmenu::_addr;) {
mainLoop();
- if (_eventManager->_quitFlag)
+ if (_quitFlag)
return false;
}
diff --git a/engines/cge/cge_main.h b/engines/cge/cge_main.h
index bdb3121d63..87199ee524 100644
--- a/engines/cge/cge_main.h
+++ b/engines/cge/cge_main.h
@@ -56,10 +56,8 @@ namespace CGE {
#define kSystemRate 6 // 12 Hz
#define kHeroFun0 (40 * 12)
#define kHeroFun1 ( 2 * 12)
-#define kGetNamePrompt 50
-#define kGetNameTitle 51
+#define kShowScummVMVersion 15
#define kTSeq 96
-#define kNoMusic 98
#define kBadSVG 99
#define kSeqHTalk (kTSeq + 4)
#define kSeqTooFar (kTSeq + 5)
@@ -82,7 +80,6 @@ namespace CGE {
#define kStackSize 2048
#define kSavegameCheckSum (1956 + _now + _oldLev + _game + _music + _demoText)
#define kSavegame0Name ("{{INIT}}" kSvgExt)
-#define kSavegame0File EncryptedStream
#define kSavegameStrSize 11
#define kGameFrameDelay (1000 / 50)
#define kGameTickDelay (1000 / 62)
diff --git a/engines/cge/console.cpp b/engines/cge/console.cpp
index 71eedf34ea..105f241944 100644
--- a/engines/cge/console.cpp
+++ b/engines/cge/console.cpp
@@ -26,9 +26,23 @@
namespace CGE {
CGEConsole::CGEConsole(CGEEngine *vm) : GUI::Debugger(), _vm(vm) {
+ DCmd_Register("Boundaries", WRAP_METHOD(CGEConsole, Cmd_boundaries));
}
CGEConsole::~CGEConsole() {
}
+/**
+ * This command shows and hides boundaries
+ */
+bool CGEConsole::Cmd_boundaries(int argc, const char **argv) {
+ if (argc != 1) {
+ DebugPrintf("Usage: %s\n", argv[0]);
+ return true;
+ }
+
+ _vm->_showBoundariesFl = !_vm->_showBoundariesFl;
+ return false;
+}
+
} // End of namespace CGE
diff --git a/engines/cge/console.h b/engines/cge/console.h
index 25a1a4fae3..ea36dfbaae 100644
--- a/engines/cge/console.h
+++ b/engines/cge/console.h
@@ -36,6 +36,7 @@ public:
private:
CGEEngine *_vm;
+ bool Cmd_boundaries(int argc, const char **argv);
};
} // End of namespace CGE
diff --git a/engines/cge/detection.cpp b/engines/cge/detection.cpp
index f2f5764e54..b3ef31f30f 100644
--- a/engines/cge/detection.cpp
+++ b/engines/cge/detection.cpp
@@ -44,7 +44,7 @@ static const ADGameDescription gameDescriptions[] = {
{"vol.dat", 0, "f9ae2e7f8f7cac91378cdafca43faf1e", 8437572},
AD_LISTEND
},
- Common::PL_POL, Common::kPlatformPC, ADGF_NO_FLAGS, GUIO1(GUIO_NONE)
+ Common::PL_POL, Common::kPlatformPC, ADGF_NO_FLAGS, GUIO0()
},
{
"soltys", "Soltys Freeware",
@@ -53,17 +53,7 @@ static const ADGameDescription gameDescriptions[] = {
{"vol.dat", 0, "f9ae2e7f8f7cac91378cdafca43faf1e", 8437676},
AD_LISTEND
},
- Common::PL_POL, Common::kPlatformPC, ADGF_NO_FLAGS, GUIO1(GUIO_NONE)
- },
- // English ScummVM version
- {
- "soltys", "",
- {
- {"vol.cat", 0, "bd08969b5f1acea0f92d195f750c17d5", 50176},
- {"vol.dat", 0, "f9ae2e7f8f7cac91378cdafca43faf1e", 8428832},
- AD_LISTEND
- },
- Common::EN_ANY, Common::kPlatformPC, ADGF_NO_FLAGS, GUIO1(GUIO_NONE)
+ Common::PL_POL, Common::kPlatformPC, ADGF_NO_FLAGS, GUIO0()
},
{
"soltys", "Soltys Demo (not supported)",
@@ -72,7 +62,7 @@ static const ADGameDescription gameDescriptions[] = {
{"vol.dat", 0, "75d385a6074c58b69f7730481f256051", 1796710},
AD_LISTEND
},
- Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO , GUIO1(GUIO_NONE)
+ Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO , GUIO0()
},
{
"soltys", "Soltys Demo (not supported)",
@@ -81,7 +71,25 @@ static const ADGameDescription gameDescriptions[] = {
{"vol.dat", 0, "c5d9b15863cab61dc125551576dece04", 1075272},
AD_LISTEND
},
- Common::PL_POL, Common::kPlatformPC, ADGF_DEMO , GUIO1(GUIO_NONE)
+ Common::PL_POL, Common::kPlatformPC, ADGF_DEMO , GUIO0()
+ },
+ {
+ "soltys", "Soltys Freeware v1.0",
+ {
+ {"vol.cat", 0, "f1675684c68ab90272f5776f8f2c3974", 50176},
+ {"vol.dat", 0, "4ffeff4abc99ac5999b55ccfc56ab1df", 8430868},
+ AD_LISTEND
+ },
+ Common::EN_ANY, Common::kPlatformPC, ADGF_NO_FLAGS , GUIO0()
+ },
+ {
+ "soltys", "Soltys Freeware v1.0",
+ {
+ {"vol.cat", 0, "20fdce799adb618100ef9ee2362be875", 50176},
+ {"vol.dat", 0, "0e43331c846094d77f5dd201827e0a3b", 8439339},
+ AD_LISTEND
+ },
+ Common::PL_POL, Common::kPlatformPC, ADGF_NO_FLAGS, GUIO0()
},
AD_TABLE_END_MARKER
};
@@ -96,7 +104,7 @@ static const ADFileBasedFallback fileBasedFallback[] = {
class CGEMetaEngine : public AdvancedMetaEngine {
public:
CGEMetaEngine() : AdvancedMetaEngine(CGE::gameDescriptions, sizeof(ADGameDescription), CGEGames) {
- _singleid = "Soltys";
+ _singleid = "soltys";
}
virtual const ADGameDescription *fallbackDetect(const FileMap &allFiles, const Common::FSList &fslist) const {
diff --git a/engines/cge/events.cpp b/engines/cge/events.cpp
index cc22d9075a..3c561c5659 100644
--- a/engines/cge/events.cpp
+++ b/engines/cge/events.cpp
@@ -30,6 +30,7 @@
#include "gui/message.h"
#include "common/config-manager.h"
#include "common/events.h"
+#include "engines/advancedDetector.h"
#include "cge/events.h"
#include "cge/events.h"
#include "cge/text.h"
@@ -39,55 +40,8 @@ namespace CGE {
/*----------------- KEYBOARD interface -----------------*/
-const uint16 Keyboard::_code[0x60] = {
- 0, Esc, '1', '2', '3',
- '4', '5', '6', '7', '8',
- '9', '0', '-', '+', BSp,
- Tab, 'Q', 'W', 'E', 'R',
- 'T', 'Y', 'U', 'I', 'O',
- 'P', '[', ']', Enter, 0/*Ctrl*/,
- 'A', 'S', 'D', 'F', 'G',
- 'H', 'J', 'K', 'L', ';',
- '\'', '`', 0/*LShift*/, '\\', 'Z',
- 'X', 'C', 'V', 'B', 'N',
- 'M', ',', '.', '/', 0/*RShift*/,
- '*', 0/*Alt*/, ' ', 0/*Caps*/, F1,
- F2, F3, F4, F5, F6,
- F7, F8, F9, F10, 0/*NumLock*/,
- 0/*ScrollLock*/, Home, Up, PgUp, '-',
- Left, Ctr, Right, '+', End,
- Down, PgDn, Ins, Del, 0 * 0x54,
- 0 * 0x55, 0 * 0x56, F11, F12, 0 * 0x59,
- 0 * 0x5A, 0 * 0x5B, 0 * 0x5C, 0 * 0x5D, 0 * 0x5E,
- 0 * 0x5F
-};
-
-const uint16 Keyboard::_scummVmCodes[0x60] = {
- 0, Common::KEYCODE_ESCAPE, Common::KEYCODE_1, Common::KEYCODE_2, Common::KEYCODE_3,
- Common::KEYCODE_4, Common::KEYCODE_5, Common::KEYCODE_6, Common::KEYCODE_7, Common::KEYCODE_8,
- Common::KEYCODE_9, Common::KEYCODE_0, Common::KEYCODE_MINUS, Common::KEYCODE_PLUS, Common::KEYCODE_BACKSPACE,
- Common::KEYCODE_TAB, Common::KEYCODE_q, Common::KEYCODE_w, Common::KEYCODE_e, Common::KEYCODE_r,
- Common::KEYCODE_t, Common::KEYCODE_y, Common::KEYCODE_u, Common::KEYCODE_i, Common::KEYCODE_o,
- Common::KEYCODE_p, Common::KEYCODE_LEFTBRACKET, Common::KEYCODE_RIGHTBRACKET, Common::KEYCODE_RETURN, 0/*Ctrl*/,
- Common::KEYCODE_a, Common::KEYCODE_s, Common::KEYCODE_d, Common::KEYCODE_f, Common::KEYCODE_g,
- Common::KEYCODE_h, Common::KEYCODE_j, Common::KEYCODE_k, Common::KEYCODE_l, Common::KEYCODE_SEMICOLON,
- Common::KEYCODE_BACKSLASH, Common::KEYCODE_TILDE, Common::KEYCODE_LSHIFT, Common::KEYCODE_BACKSLASH, Common::KEYCODE_z,
- Common::KEYCODE_x, Common::KEYCODE_c, Common::KEYCODE_v, Common::KEYCODE_b, Common::KEYCODE_n,
- Common::KEYCODE_m, Common::KEYCODE_COMMA, Common::KEYCODE_PERIOD, Common::KEYCODE_SLASH, Common::KEYCODE_RSHIFT,
- Common::KEYCODE_KP_MULTIPLY, 0 /*Alt*/, Common::KEYCODE_SPACE, Common::KEYCODE_CAPSLOCK, Common::KEYCODE_F1,
- Common::KEYCODE_F2, Common::KEYCODE_F3, Common::KEYCODE_F4, Common::KEYCODE_F5, Common::KEYCODE_F6,
- Common::KEYCODE_F7, Common::KEYCODE_F8, Common::KEYCODE_F9, Common::KEYCODE_F10, Common::KEYCODE_NUMLOCK,
- Common::KEYCODE_SCROLLOCK, Common::KEYCODE_KP7, Common::KEYCODE_KP8, Common::KEYCODE_KP9, Common::KEYCODE_KP_MINUS,
- Common::KEYCODE_KP4, Common::KEYCODE_KP5, Common::KEYCODE_KP6, Common::KEYCODE_KP_PLUS, Common::KEYCODE_KP1,
- Common::KEYCODE_KP2, Common::KEYCODE_KP3, Common::KEYCODE_KP0, Common::KEYCODE_KP_PERIOD, 0,
- 0, 0, Common::KEYCODE_F11, Common::KEYCODE_F12, 0,
- 0, 0, 0, 0, 0,
- 0
-};
-
Keyboard::Keyboard(CGEEngine *vm) : _client(NULL), _vm(vm) {
- Common::set_to(&_key[0], &_key[0x60], false);
- _current = 0;
+ _keyAlt = false;
}
Keyboard::~Keyboard() {
@@ -98,22 +52,23 @@ Sprite *Keyboard::setClient(Sprite *spr) {
return spr;
}
-bool Keyboard::getKey(Common::Event &event, int &cgeCode) {
+bool Keyboard::getKey(Common::Event &event) {
Common::KeyCode keycode = event.kbd.keycode;
- if ((keycode == Common::KEYCODE_LCTRL) || (keycode == Common::KEYCODE_RCTRL)) {
- cgeCode = kKeyCtrl;
- return true;
- }
- if ((keycode == Common::KEYCODE_LALT) || (keycode == Common::KEYCODE_RALT)) {
- cgeCode = kKeyAlt;
- return true;
- }
- if (keycode == Common::KEYCODE_KP_ENTER) {
- cgeCode = 28;
- return true;
- }
- if (keycode == Common::KEYCODE_F5) {
- warning("keycode %d", event.kbd.ascii);
+
+ if ((keycode == Common::KEYCODE_LALT) || (keycode == Common::KEYCODE_RALT))
+ _keyAlt = true;
+ else
+ _keyAlt = false;
+
+ switch (keycode) {
+ case Common::KEYCODE_F1:
+ if (event.type == Common::EVENT_KEYUP)
+ return false;
+ // Display ScummVM version and translation strings
+ for (int i = 0; i < 5; i++)
+ _vm->_commandHandler->addCommand(kCmdInf, 1, kShowScummVMVersion + i, NULL);
+ return false;
+ case Common::KEYCODE_F5:
if (_vm->canSaveGameStateCurrently()) {
const EnginePlugin *plugin = NULL;
EngineMan.findGame(_vm->_gameDescription->gameid, &plugin);
@@ -123,10 +78,12 @@ bool Keyboard::getKey(Common::Event &event, int &cgeCode) {
int16 savegameId = dialog->runModalWithPluginAndTarget(plugin, ConfMan.getActiveDomainName());
Common::String savegameDescription = dialog->getResultString();
delete dialog;
- _vm->saveGameState(savegameId, savegameDescription);
- }
+
+ if (savegameId != -1)
+ _vm->saveGameState(savegameId, savegameDescription);
+ }
return false;
- } else if (keycode == Common::KEYCODE_F7) {
+ case Common::KEYCODE_F7:
if (_vm->canLoadGameStateCurrently()) {
const EnginePlugin *plugin = NULL;
EngineMan.findGame(_vm->_gameDescription->gameid, &plugin);
@@ -135,50 +92,53 @@ bool Keyboard::getKey(Common::Event &event, int &cgeCode) {
dialog->setSaveMode(false);
int16 savegameId = dialog->runModalWithPluginAndTarget(plugin, ConfMan.getActiveDomainName());
delete dialog;
- _vm->loadGameState(savegameId);
+
+ if (savegameId != -1)
+ _vm->loadGameState(savegameId);
}
return false;
- }
-
- // Scan through the ScummVM mapping list
- for (int idx = 0; idx < 0x60; idx++) {
- if (_scummVmCodes[idx] == event.kbd.ascii) {
- cgeCode = idx;
- return true;
+ case Common::KEYCODE_d:
+ if (event.kbd.flags & Common::KBD_CTRL) {
+ // Start the debugger
+ _vm->getDebugger()->attach();
+ _vm->getDebugger()->onFrame();
+ return false;
+ }
+ break;
+ case Common::KEYCODE_x:
+ if (event.kbd.flags & Common::KBD_ALT) {
+ _vm->quit();
+ return false;
+ }
+ break;
+ case Common::KEYCODE_0:
+ case Common::KEYCODE_1:
+ case Common::KEYCODE_2:
+ case Common::KEYCODE_3:
+ case Common::KEYCODE_4:
+ if (event.kbd.flags & Common::KBD_ALT) {
+ _vm->_commandHandler->addCommand(kCmdLevel, -1, keycode - '0', NULL);
+ return false;
}
+ default:
+ break;
}
- return false;
+ return true;
}
void Keyboard::newKeyboard(Common::Event &event) {
- int keycode;
- if (!getKey(event, keycode))
+ if (!getKey(event))
return;
- if (event.type == Common::EVENT_KEYUP) {
- // Key release
- _key[keycode] = false;
- } else if (event.type == Common::EVENT_KEYDOWN) {
- // Key press
- _key[keycode] = true;
- _current = Keyboard::_code[keycode];
-
- if (_client) {
- CGEEvent &evt = _vm->_eventManager->getNextEvent();
- evt._x = _current; // Keycode
- evt._mask = kEventKeyb; // Event mask
- evt._spritePtr = _client; // Sprite pointer
- }
+ if ((event.type == Common::EVENT_KEYDOWN) && (_client)) {
+ CGEEvent &evt = _vm->_eventManager->getNextEvent();
+ evt._x = event.kbd.keycode; // Keycode
+ evt._mask = kEventKeyb; // Event mask
+ evt._spritePtr = _client; // Sprite pointer
}
}
-uint16 Keyboard::lastKey() {
- uint16 cur = _current;
- _current = 0;
- return cur;
-}
-
/*----------------- MOUSE interface -----------------*/
Mouse::Mouse(CGEEngine *vm) : Sprite(vm, NULL), _busy(NULL), _hold(NULL), _hx(0), _vm(vm) {
@@ -272,7 +232,6 @@ void Mouse::newMouse(Common::Event &event) {
/*----------------- EventManager interface -----------------*/
EventManager::EventManager(CGEEngine *vm) : _vm(vm){
- _quitFlag = false;
_eventQueueHead = 0;
_eventQueueTail = 0;
memset(&_eventQueue, 0, kEventMax * sizeof(CGEEvent));
@@ -282,10 +241,6 @@ EventManager::EventManager(CGEEngine *vm) : _vm(vm){
void EventManager::poll() {
while (g_system->getEventManager()->pollEvent(_event)) {
switch (_event.type) {
- case Common::EVENT_QUIT:
- // Signal to quit
- _quitFlag = true;
- return;
case Common::EVENT_KEYDOWN:
case Common::EVENT_KEYUP:
// Handle keyboard events
diff --git a/engines/cge/events.h b/engines/cge/events.h
index a4cdfed793..6bbd52e4a5 100644
--- a/engines/cge/events.h
+++ b/engines/cge/events.h
@@ -37,8 +37,6 @@ namespace CGE {
/*----------------- KEYBOARD interface -----------------*/
-#define kKeyCtrl 29
-#define kKeyAlt 56
#define kEventMax 256
enum EventMask {
@@ -51,49 +49,15 @@ enum EventMask {
kEventKeyb = 1 << 7
};
-enum Keys {
- NoKey = 0, CtrlA, CtrlB, CtrlC, CtrlD, CtrlE, CtrlF, CtrlG, CtrlH,
- CtrlI, CtrlJ, CtrlK, CtrlL, CtrlM, CtrlN, CtrlO, CtrlP,
- CtrlQ, CtrlR, CtrlS, CtrlT, CtrlU, CtrlV, CtrlW, CtrlX,
- CtrlY, CtrlZ,
- BSp = 8, Tab,
- Enter = 13,
- Eof = 26, Esc,
- AltQ = 256 + 16, AltW, AltE, AltR, AltT, AltY, AltU, AltI, AltO, AltP,
- AltA = 256 + 30, AltS, AltD, AltF, AltG, AltH, AltJ, AltK, AltL,
- AltZ = 256 + 44, AltX, AltC, AltV, AltB, AltN, AltM,
- F11 = 256 + 87, F12,
- F1 = 256 + 59, F2, F3, F4, F5, F6, F7, F8, F9, F10,
- ShiftTab = 256 + 15,
- ShiftF1 = 256 + 84, ShiftF2, ShiftF3, ShiftF4, ShiftF5,
- ShiftF6, ShiftF7, ShiftF8, ShiftF9, ShiftF10,
- CtrlF1 = 256 + 94, CtrlF2, CtrlF3, CtrlF4, CtrlF5,
- CtrlF6, CtrlF7, CtrlF8, CtrlF9, CtrlF10,
- AltF1 = 256 + 104, AltF2, AltF3, AltF4, AltF5,
- AltF6, AltF7, AltF8, AltF9, AltF10,
- Home = 256 + 71, Up, PgUp,
- Left = 256 + 75, Ctr, Right,
- End = 256 + 79, Down, PgDn, Ins, Del,
- CtrlLeft = 256 + 115, CtrlRight, CtrlEnd, CtrlPgDn, CtrlHome,
- CtrlPgUp = 256 + 132,
- MouseLeft = 512 + 1, MouseRight,
- TwiceLeft = 512 + 256 + 1, TwiceRight
-};
-
class Keyboard {
private:
- bool getKey(Common::Event &event, int &cgeCode);
- uint16 _current;
+ bool getKey(Common::Event &event);
CGEEngine *_vm;
public:
- static const uint16 _code[0x60];
- static const uint16 _scummVmCodes[0x60];
-
Sprite *_client;
- bool _key[0x60];
+ bool _keyAlt;
void newKeyboard(Common::Event &event);
- uint16 lastKey();
Sprite *setClient(Sprite *spr);
Keyboard(CGEEngine *vm);
@@ -118,7 +82,6 @@ public:
bool _exist;
int _buttons;
Sprite *_busy;
- //Sprite *Touched;
Mouse(CGEEngine *vm);
~Mouse();
void on();
@@ -140,8 +103,6 @@ private:
void handleEvents();
public:
- bool _quitFlag;
-
EventManager(CGEEngine *vm);
void poll();
void clearEvent(Sprite *spr);
diff --git a/engines/cge/fileio.cpp b/engines/cge/fileio.cpp
index 6db0818287..c50db4e929 100644
--- a/engines/cge/fileio.cpp
+++ b/engines/cge/fileio.cpp
@@ -235,6 +235,7 @@ int32 EncryptedStream::pos() {
}
EncryptedStream::~EncryptedStream() {
+ delete _readStream;
}
} // End of namespace CGE
diff --git a/engines/cge/snail.cpp b/engines/cge/snail.cpp
index cbc463ced2..c26f68fa7b 100644
--- a/engines/cge/snail.cpp
+++ b/engines/cge/snail.cpp
@@ -194,7 +194,7 @@ void CommandHandler::runCommand() {
break;
case kCmdInf:
if (_talkEnable) {
- _vm->inf(_vm->_text->getText(tailCmd->_val));
+ _vm->inf(_vm->_text->getText(tailCmd->_val), true);
_vm->_sys->_funDel = kHeroFun0;
}
break;
@@ -375,6 +375,10 @@ bool CommandHandler::idle() {
return (_head == _tail);
}
+void CommandHandler::reset() {
+ _tail = _head;
+}
+
/**
* Handles mini-Games logic
* @param com Command
@@ -406,7 +410,7 @@ void CGEEngine::snGame(Sprite *spr, int num) {
Stage++;
if (hand && Stage > kDressed)
++hand;
- if (i >= 0 || (dup[i] == spr && newRandom(3) == 0)) {
+ if (i >= 0 && (dup[i] == spr && newRandom(3) == 0)) {
_commandHandler->addCommand(kCmdSeq, -1, 3, dup[0]); // Yes
_commandHandler->addCommand(kCmdSeq, -1, 3, dup[1]); // Yes
_commandHandler->addCommand(kCmdSeq, -1, 3, dup[2]); // Yes
@@ -443,7 +447,7 @@ void CGEEngine::snGame(Sprite *spr, int num) {
_commandHandler->addCommand(kCmdSeq, -1, 0, dup[2]); // Get Away (Her)
_commandHandler->addCommand(kCmdSetXY, -1, 182 + kScrWidth * 62, dup[2]);
_commandHandler->addCommand(kCmdSetZ, -1, 9, dup[2]);
- _game = 0;
+ _game = false;
return;
} else {
_commandHandler->addCommand(kCmdSeq, -1, 2, dup[0]); // reset animation sequence
@@ -489,7 +493,7 @@ void CGEEngine::snGame(Sprite *spr, int num) {
_sprK2->step(newRandom(6));
_sprK3->step(newRandom(6));
- if (spr->_ref == 1 && _keyboard->_key[kKeyAlt]) {
+ if (spr->_ref == 1 && _keyboard->_keyAlt) {
_sprK1->step(5);
_sprK2->step(5);
_sprK3->step(5);
diff --git a/engines/cge/snail.h b/engines/cge/snail.h
index 3acbbd0e5f..6a9e717441 100644
--- a/engines/cge/snail.h
+++ b/engines/cge/snail.h
@@ -45,7 +45,7 @@ enum CommandType {
kCmdSetX, kCmdSetY, kCmdSetZ, kCmdTrans, kCmdPort,
kCmdNext, kCmdNNext, kCmdTNext, kCmdRNNext, kCmdRTNext,
kCmdRMNear, kCmdRmTake, kCmdFlag, kCmdSetRef, kCmdBackPt,
- kCmdFlash, kCmdLight, kCmdSetHBarrier, kCmdSetVBarrier, kCmdWalk,
+ kCmdFlash, kCmdLight, kCmdSetVBarrier, kCmdSetHBarrier, kCmdWalk,
kCmdReach, kCmdCover, kCmdUncover, kCmdClear, kCmdTalk,
kCmdMouse, kCmdSound, kCmdCount, kCmdExec, kCmdStep,
kCmdZTrim, kCmdGhost
@@ -70,6 +70,7 @@ public:
void addCallback(CommandType com, int ref, int val, CallbackType cbType);
void insertCommand(CommandType com, int ref, int val, void *ptr);
bool idle();
+ void reset();
private:
CGEEngine *_vm;
bool _turbo;
diff --git a/engines/cge/talk.cpp b/engines/cge/talk.cpp
index 467b39be40..f5d570b389 100644
--- a/engines/cge/talk.cpp
+++ b/engines/cge/talk.cpp
@@ -73,8 +73,8 @@ uint16 Font::width(const char *text) {
return w;
}
-Talk::Talk(CGEEngine *vm, const char *text, TextBoxStyle mode)
- : Sprite(vm, NULL), _mode(mode), _vm(vm) {
+Talk::Talk(CGEEngine *vm, const char *text, TextBoxStyle mode, bool wideSpace)
+ : Sprite(vm, NULL), _mode(mode), _wideSpace(wideSpace), _vm(vm) {
_ts = NULL;
_flags._syst = true;
update(text);
@@ -85,6 +85,7 @@ Talk::Talk(CGEEngine *vm)
: Sprite(vm, NULL), _mode(kTBPure), _vm(vm) {
_ts = NULL;
_flags._syst = true;
+ _wideSpace = false;
}
void Talk::update(const char *text) {
@@ -103,7 +104,9 @@ void Talk::update(const char *text) {
if (k > mw)
mw = k;
k = 2 * hmarg;
- } else
+ } else if ((*p == 0x20) && (_vm->_font->_widthArr[(unsigned char)*p] > 4) && (!_wideSpace))
+ k += _vm->_font->_widthArr[(unsigned char)*p] - 2;
+ else
k += _vm->_font->_widthArr[(unsigned char)*p];
}
if (k > mw)
@@ -122,7 +125,14 @@ void Talk::update(const char *text) {
} else {
int cw = _vm->_font->_widthArr[(unsigned char)*text];
uint8 *f = _vm->_font->_map + _vm->_font->_pos[(unsigned char)*text];
- for (int i = 0; i < cw; i++) {
+
+ // Handle properly space size, after it was enlarged to display properly
+ // 'F1' text.
+ int8 fontStart = 0;
+ if ((*text == 0x20) && (cw > 4) && (!_wideSpace))
+ fontStart = 2;
+
+ for (int i = fontStart; i < cw; i++) {
uint8 *pp = m;
uint16 n;
uint16 b = *(f++);
@@ -182,55 +192,6 @@ Bitmap *Talk::box(uint16 w, uint16 h) {
return new Bitmap(_vm, w, h, b);
}
-void Talk::putLine(int line, const char *text) {
- // Note: (_ts[0]._w % 4) must be 0
- uint16 w = _ts[0]->_w;
- uint16 h = _ts[0]->_h;
- uint8 *v = _ts[0]->_v;
- uint16 dsiz = w >> 2; // data size (1 plane line size)
- uint16 lsiz = 2 + dsiz + 2; // uint16 for line header, uint16 for gap
- uint16 psiz = h * lsiz; // - last gap, but + plane trailer
- uint16 size = 4 * psiz; // whole map size
- uint16 rsiz = kFontHigh * lsiz; // length of whole text row map
-
- // set desired line pointer
- v += (kTextVMargin + (kFontHigh + kTextLineSpace) * line) * lsiz;
- uint8 *p = v; // assume blanked line above text
-
- // clear whole rectangle
- assert((rsiz % lsiz) == 0);
- for (int planeCtr = 0; planeCtr < 4; planeCtr++, p += psiz) {
- for (byte *pDest = p; pDest < (p + (rsiz - lsiz)); pDest += lsiz)
- Common::copy(p - lsiz, p, pDest);
- }
-
- // paint text line
- if (!text)
- return;
- p = v + 2 + (kTextHMargin / 4) + (kTextHMargin % 4) * psiz;
- uint8 *q = v + size;
-
- while (*text) {
- uint16 cw = _vm->_font->_widthArr[(unsigned char)*text], i;
- uint8 *fp = _vm->_font->_map + _vm->_font->_pos[(unsigned char)*text];
-
- for (i = 0; i < cw; i++) {
- uint16 b = fp[i];
- uint16 n;
- for (n = 0; n < kFontHigh; n++) {
- if (b & 1)
- *p = kTextColFG;
- b >>= 1;
- p += lsiz;
- }
- p = p - rsiz + psiz;
- if (p >= q)
- p = p - size + 1;
- }
- text++;
- }
-}
-
InfoLine::InfoLine(CGEEngine *vm, uint16 w) : Talk(vm), _oldText(NULL), _vm(vm) {
if (!_ts) {
_ts = new BitmapPtr[2];
@@ -271,7 +232,13 @@ void InfoLine::update(const char *text) {
uint16 cw = _vm->_font->_widthArr[(unsigned char)*text];
uint8 *fp = _vm->_font->_map + _vm->_font->_pos[(unsigned char)*text];
- for (uint16 i = 0; i < cw; i++) {
+ // Handle properly space size, after it was enlarged to display properly
+ // 'F1' text.
+ int8 fontStart = 0;
+ if ((*text == 0x20) && (cw > 4) && (!_wideSpace))
+ fontStart = 2;
+
+ for (int i = fontStart; i < cw; i++) {
uint16 b = fp[i];
for (uint16 n = 0; n < kFontHigh; n++) {
if (b & 1)
diff --git a/engines/cge/talk.h b/engines/cge/talk.h
index 55c529b7ea..66e3d85214 100644
--- a/engines/cge/talk.h
+++ b/engines/cge/talk.h
@@ -52,12 +52,12 @@ protected:
TextBoxStyle _mode;
BitmapPtr *_ts;
Bitmap *box(uint16 w, uint16 h);
+ bool _wideSpace;
public:
- Talk(CGEEngine *vm, const char *text, TextBoxStyle mode);
+ Talk(CGEEngine *vm, const char *text, TextBoxStyle mode, bool wideSpace = false);
Talk(CGEEngine *vm);
virtual void update(const char *text);
- void putLine(int line, const char *text);
private:
CGEEngine *_vm;
};
diff --git a/engines/cge/text.cpp b/engines/cge/text.cpp
index 58acb5548c..fd4120d49d 100644
--- a/engines/cge/text.cpp
+++ b/engines/cge/text.cpp
@@ -72,7 +72,7 @@ int16 Text::count() {
strcpy(tmpStr, line.c_str());
if ((s = strtok(tmpStr, " =,;/\t\n")) == NULL)
continue;
- if (!isdigit(*s))
+ if (!Common::isDigit(*s))
continue;
counter++;
@@ -105,7 +105,7 @@ void Text::load() {
strcpy(tmpStr, line.c_str());
if ((s = strtok(tmpStr, " =,;/\t\n")) == NULL)
continue;
- if (!isdigit(*s))
+ if (!Common::isDigit(*s))
continue;
int r = atoi(s);
@@ -135,6 +135,13 @@ char *Text::getText(int ref) {
void Text::say(const char *text, Sprite *spr) {
_vm->killText();
+
+ if (!text)
+ return;
+
+ if (*text == 0)
+ return;
+
_vm->_talk = new Talk(_vm, text, kTBRound);
if (!_vm->_talk)
return;
@@ -175,11 +182,16 @@ void Text::say(const char *text, Sprite *spr) {
_vm->_vga->_showQ->insert(speaker, _vm->_vga->_showQ->last());
}
-void CGEEngine::inf(const char *text) {
+void CGEEngine::inf(const char *text, bool wideSpace) {
debugC(1, kCGEDebugEngine, "CGEEngine::inf(%s)", text);
+ if (!text)
+ return;
+
+ if (*text == 0)
+ return;
killText();
- _talk = new Talk(this, text, kTBRect);
+ _talk = new Talk(this, text, kTBRect, wideSpace);
if (!_talk)
return;
diff --git a/engines/cge/vga13h.cpp b/engines/cge/vga13h.cpp
index 49cfcd3084..186de24036 100644
--- a/engines/cge/vga13h.cpp
+++ b/engines/cge/vga13h.cpp
@@ -115,13 +115,6 @@ BitmapPtr *Sprite::setShapeList(BitmapPtr *shpP) {
return r;
}
-void Sprite::moveShapes(uint8 *buf) {
- BitmapPtr *p;
- for (p = _ext->_shpList; *p; p++) {
- buf += (*p)->moveVmap(buf);
- }
-}
-
bool Sprite::works(Sprite *spr) {
if (!spr || !spr->_ext)
return false;
@@ -492,7 +485,7 @@ void Sprite::sync(Common::Serializer &s) {
_flags._near = flags & 0x0002 ? true : false;
_flags._drag = flags & 0x0004 ? true : false;
_flags._hold = flags & 0x0008 ? true : false;
- _flags._____ = flags & 0x0010 ? true : false;
+ _flags._dummy = flags & 0x0010 ? true : false;
_flags._slav = flags & 0x0020 ? true : false;
_flags._syst = flags & 0x0040 ? true : false;
_flags._kill = flags & 0x0080 ? true : false;
@@ -516,7 +509,7 @@ void Sprite::sync(Common::Serializer &s) {
flags = (flags << 1) | _flags._kill;
flags = (flags << 1) | _flags._syst;
flags = (flags << 1) | _flags._slav;
- flags = (flags << 1) | _flags._____;
+ flags = (flags << 1) | _flags._dummy;
flags = (flags << 1) | _flags._hold;
flags = (flags << 1) | _flags._drag;
flags = (flags << 1) | _flags._near;
@@ -632,7 +625,7 @@ Sprite *Queue::locate(int ref) {
return NULL;
}
-Vga::Vga() : _frmCnt(0), _msg(NULL), _name(NULL), _setPal(false), _mono(0) {
+Vga::Vga(CGEEngine *vm) : _frmCnt(0), _msg(NULL), _name(NULL), _setPal(false), _mono(0), _vm(vm) {
_oldColors = NULL;
_newColors = NULL;
_showQ = new Queue(true);
@@ -829,6 +822,17 @@ void Vga::update() {
updateColors();
_setPal = false;
}
+ if (_vm->_showBoundariesFl) {
+ Vga::_page[0]->hLine(0, 200 - kPanHeight, 320, 0xee);
+ if (_vm->_barriers[_vm->_now]._horz != 255) {
+ for (int i = 0; i < 8; i++)
+ Vga::_page[0]->vLine((_vm->_barriers[_vm->_now]._horz * 8) + i, 0, 200, 0xff);
+ }
+ if (_vm->_barriers[_vm->_now]._vert != 255) {
+ for (int i = 0; i < 4; i++)
+ Vga::_page[0]->hLine(0, 80 + (_vm->_barriers[_vm->_now]._vert * 4) + i, 320, 0xff);
+ }
+ }
g_system->copyRectToScreen((const byte *)Vga::_page[0]->getBasePtr(0, 0), kScrWidth, 0, 0, kScrWidth, kScrHeight);
g_system->updateScreen();
diff --git a/engines/cge/vga13h.h b/engines/cge/vga13h.h
index 0c514c4a66..beca19f667 100644
--- a/engines/cge/vga13h.h
+++ b/engines/cge/vga13h.h
@@ -91,7 +91,7 @@ public:
uint16 _near : 1; // Near action lock
uint16 _drag : 1; // sprite is moveable
uint16 _hold : 1; // sprite is held with mouse
- uint16 _____ : 1; // intrrupt driven animation
+ uint16 _dummy : 1; // intrrupt driven animation
uint16 _slav : 1; // slave object
uint16 _syst : 1; // system object
uint16 _kill : 1; // dispose memory after remove
@@ -128,7 +128,6 @@ public:
virtual ~Sprite();
BitmapPtr shp();
BitmapPtr *setShapeList(BitmapPtr *shp);
- void moveShapes(uint8 *buf);
Sprite *expand();
Sprite *contract();
Sprite *backShow(bool fast = false);
@@ -178,6 +177,7 @@ public:
};
class Vga {
+ CGEEngine *_vm;
bool _setPal;
Dac *_oldColors;
Dac *_newColors;
@@ -197,7 +197,7 @@ public:
Graphics::Surface *_page[4];
Dac *_sysPal;
- Vga();
+ Vga(CGEEngine *vm);
~Vga();
uint8 *glass(Dac *pal, const uint8 colR, const uint8 colG, const uint8 colB);
diff --git a/engines/cge/walk.h b/engines/cge/walk.h
index 99dc362eec..00ec080416 100644
--- a/engines/cge/walk.h
+++ b/engines/cge/walk.h
@@ -35,7 +35,6 @@
namespace CGE {
#define kMapArrSize (kMapZCnt * kMapXCnt)
-#define kMapTop 80
#define kMapHig 80
#define kMapGridX (kScrWidth / kMapXCnt)
#define kMapGridZ (kMapHig / kMapZCnt)
diff --git a/engines/cine/cine.cpp b/engines/cine/cine.cpp
index 6f34b0f860..6b94c33c31 100644
--- a/engines/cine/cine.cpp
+++ b/engines/cine/cine.cpp
@@ -141,11 +141,11 @@ void CineEngine::initialize() {
// Resize zone data table to its correct size and reset all its elements
g_cine->_zoneData.resize(NUM_MAX_ZONE);
- Common::set_to(g_cine->_zoneData.begin(), g_cine->_zoneData.end(), 0);
+ Common::fill(g_cine->_zoneData.begin(), g_cine->_zoneData.end(), 0);
// Resize zone query table to its correct size and reset all its elements
g_cine->_zoneQuery.resize(NUM_MAX_ZONE);
- Common::set_to(g_cine->_zoneQuery.begin(), g_cine->_zoneQuery.end(), 0);
+ Common::fill(g_cine->_zoneQuery.begin(), g_cine->_zoneQuery.end(), 0);
_timerDelayMultiplier = 12; // Set default speed
setupOpcodes();
diff --git a/engines/cine/detection.cpp b/engines/cine/detection.cpp
index a64272d967..823b8e38b5 100644
--- a/engines/cine/detection.cpp
+++ b/engines/cine/detection.cpp
@@ -65,7 +65,7 @@ class CineMetaEngine : public AdvancedMetaEngine {
public:
CineMetaEngine() : AdvancedMetaEngine(Cine::gameDescriptions, sizeof(Cine::CINEGameDescription), cineGames) {
_singleid = "cine";
- _guioptions = GUIO2(GUIO_NOSPEECH, GUIO_NOMIDI);
+ _guioptions = GUIO1(GUIO_NOSPEECH);
}
virtual GameDescriptor findGame(const char *gameid) const {
@@ -141,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(static_cast<unsigned char>(file->lastChar())))
+ if (!Common::isDigit(file->lastChar()))
continue;
// Obtain the last digit of the filename, since they correspond to the save slot
diff --git a/engines/cine/detection_tables.h b/engines/cine/detection_tables.h
index c8ab63edaf..0ec2768bae 100644
--- a/engines/cine/detection_tables.h
+++ b/engines/cine/detection_tables.h
@@ -31,7 +31,7 @@ static const CINEGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformPC,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO0()
},
GType_FW,
0,
@@ -51,7 +51,7 @@ static const CINEGameDescription gameDescriptions[] = {
Common::EN_USA,
Common::kPlatformPC,
ADGF_CD,
- GUIO1(GUIO_NONE)
+ GUIO0()
},
GType_FW,
GF_CD | GF_CRYPTED_BOOT_PRC,
@@ -66,7 +66,7 @@ static const CINEGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformPC,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO0()
},
GType_FW,
0,
@@ -80,7 +80,7 @@ static const CINEGameDescription gameDescriptions[] = {
Common::DE_DEU,
Common::kPlatformPC,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO0()
},
GType_FW,
GF_ALT_FONT,
@@ -94,7 +94,7 @@ static const CINEGameDescription gameDescriptions[] = {
Common::ES_ESP,
Common::kPlatformPC,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO0()
},
GType_FW,
GF_ALT_FONT,
@@ -108,7 +108,7 @@ static const CINEGameDescription gameDescriptions[] = {
Common::FR_FRA,
Common::kPlatformPC,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO0()
},
GType_FW,
0,
@@ -122,7 +122,7 @@ static const CINEGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformAmiga,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOMIDI)
},
GType_FW,
0,
@@ -136,7 +136,7 @@ static const CINEGameDescription gameDescriptions[] = {
Common::EN_USA,
Common::kPlatformAmiga,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOMIDI)
},
GType_FW,
0,
@@ -150,7 +150,7 @@ static const CINEGameDescription gameDescriptions[] = {
Common::DE_DEU,
Common::kPlatformAmiga,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOMIDI)
},
GType_FW,
GF_ALT_FONT,
@@ -164,7 +164,7 @@ static const CINEGameDescription gameDescriptions[] = {
Common::ES_ESP,
Common::kPlatformAmiga,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOMIDI)
},
GType_FW,
0,
@@ -178,7 +178,7 @@ static const CINEGameDescription gameDescriptions[] = {
Common::FR_FRA,
Common::kPlatformAmiga,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOMIDI)
},
GType_FW,
0,
@@ -192,7 +192,7 @@ static const CINEGameDescription gameDescriptions[] = {
Common::IT_ITA,
Common::kPlatformAmiga,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOMIDI)
},
GType_FW,
0,
@@ -210,7 +210,7 @@ static const CINEGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformAmiga,
ADGF_DEMO,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOMIDI)
},
GType_FW,
0,
@@ -224,7 +224,7 @@ static const CINEGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformAtariST,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOMIDI)
},
GType_FW,
0,
@@ -238,7 +238,7 @@ static const CINEGameDescription gameDescriptions[] = {
Common::FR_FRA,
Common::kPlatformAtariST,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOMIDI)
},
GType_FW,
0,
@@ -252,7 +252,7 @@ static const CINEGameDescription gameDescriptions[] = {
Common::EN_GRB,
Common::kPlatformPC,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO0()
},
GType_OS,
0,
@@ -268,7 +268,7 @@ static const CINEGameDescription gameDescriptions[] = {
Common::EN_GRB,
Common::kPlatformPC,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO0()
},
GType_OS,
0,
@@ -282,7 +282,7 @@ static const CINEGameDescription gameDescriptions[] = {
Common::EN_USA,
Common::kPlatformPC,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO0()
},
GType_OS,
0,
@@ -296,7 +296,7 @@ static const CINEGameDescription gameDescriptions[] = {
Common::EN_USA,
Common::kPlatformPC,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO0()
},
GType_OS,
GF_CD,
@@ -310,7 +310,7 @@ static const CINEGameDescription gameDescriptions[] = {
Common::DE_DEU,
Common::kPlatformPC,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO0()
},
GType_OS,
0,
@@ -324,7 +324,7 @@ static const CINEGameDescription gameDescriptions[] = {
Common::ES_ESP,
Common::kPlatformPC,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO0()
},
GType_OS,
0,
@@ -342,7 +342,7 @@ static const CINEGameDescription gameDescriptions[] = {
Common::ES_ESP,
Common::kPlatformPC,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO0()
},
GType_OS,
GF_CD,
@@ -356,7 +356,7 @@ static const CINEGameDescription gameDescriptions[] = {
Common::FR_FRA,
Common::kPlatformPC,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO0()
},
GType_OS,
0,
@@ -370,7 +370,7 @@ static const CINEGameDescription gameDescriptions[] = {
Common::IT_ITA,
Common::kPlatformPC,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO0()
},
GType_OS,
0,
@@ -384,7 +384,7 @@ static const CINEGameDescription gameDescriptions[] = {
Common::EN_GRB,
Common::kPlatformAmiga,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOMIDI)
},
GType_OS,
0,
@@ -398,7 +398,7 @@ static const CINEGameDescription gameDescriptions[] = {
Common::EN_GRB,
Common::kPlatformAmiga,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOMIDI)
},
GType_OS,
0,
@@ -412,7 +412,7 @@ static const CINEGameDescription gameDescriptions[] = {
Common::EN_USA,
Common::kPlatformAmiga,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOMIDI)
},
GType_OS,
0,
@@ -426,7 +426,7 @@ static const CINEGameDescription gameDescriptions[] = {
Common::DE_DEU,
Common::kPlatformAmiga,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOMIDI)
},
GType_OS,
0,
@@ -440,7 +440,7 @@ static const CINEGameDescription gameDescriptions[] = {
Common::ES_ESP,
Common::kPlatformAmiga,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOMIDI)
},
GType_OS,
0,
@@ -454,7 +454,7 @@ static const CINEGameDescription gameDescriptions[] = {
Common::FR_FRA,
Common::kPlatformAmiga,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOMIDI)
},
GType_OS,
0,
@@ -468,7 +468,7 @@ static const CINEGameDescription gameDescriptions[] = {
Common::EN_GRB,
Common::kPlatformAmiga,
ADGF_DEMO,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOMIDI)
},
GType_OS,
GF_DEMO,
@@ -482,7 +482,7 @@ static const CINEGameDescription gameDescriptions[] = {
Common::EN_GRB,
Common::kPlatformAtariST,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOMIDI)
},
GType_OS,
0,
@@ -496,7 +496,7 @@ static const CINEGameDescription gameDescriptions[] = {
Common::FR_FRA,
Common::kPlatformAtariST,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOMIDI)
},
GType_OS,
0,
diff --git a/engines/cine/gfx.cpp b/engines/cine/gfx.cpp
index 01e05bed6d..918d522606 100644
--- a/engines/cine/gfx.cpp
+++ b/engines/cine/gfx.cpp
@@ -1801,7 +1801,7 @@ void maskBgOverlay(const byte *bgPtr, const byte *maskPtr, int16 width, int16 he
for (it = g_cine->_bgIncrustList.begin(); it != g_cine->_bgIncrustList.end(); ++it) {
tmpWidth = g_cine->_animDataTable[it->frame]._realWidth;
tmpHeight = g_cine->_animDataTable[it->frame]._height;
- mask = (byte*)malloc(tmpWidth * tmpHeight);
+ mask = (byte *)malloc(tmpWidth * tmpHeight);
if (it->param == 0) {
generateMask(g_cine->_animDataTable[it->frame].data(), mask, tmpWidth * tmpHeight, it->part);
diff --git a/engines/cine/main_loop.cpp b/engines/cine/main_loop.cpp
index bb0545db72..971830ce8f 100644
--- a/engines/cine/main_loop.cpp
+++ b/engines/cine/main_loop.cpp
@@ -345,7 +345,7 @@ void CineEngine::mainLoop(int bootScriptIdx) {
// Clear the zoneQuery table (Operation Stealth specific)
if (g_cine->getGameType() == Cine::GType_OS) {
- Common::set_to(g_cine->_zoneQuery.begin(), g_cine->_zoneQuery.end(), 0);
+ Common::fill(g_cine->_zoneQuery.begin(), g_cine->_zoneQuery.end(), 0);
}
if (g_cine->getGameType() == Cine::GType_OS) {
diff --git a/engines/cine/saveload.cpp b/engines/cine/saveload.cpp
index 0ea1a23e8f..223099a587 100644
--- a/engines/cine/saveload.cpp
+++ b/engines/cine/saveload.cpp
@@ -1034,7 +1034,7 @@ void loadResourcesFromSave(Common::SeekableReadStream &fHandle, enum CineSaveGam
}
// Alright, the animation entry looks to be valid so let's start handling it...
- if (strcmp(currentPartName, name)) {
+ if (strcmp(currentPartName, name) != 0) {
closePart();
loadPart(name);
}
diff --git a/engines/cine/sound.cpp b/engines/cine/sound.cpp
index 0c3541fae7..b2e992e8f6 100644
--- a/engines/cine/sound.cpp
+++ b/engines/cine/sound.cpp
@@ -25,12 +25,16 @@
#include "common/memstream.h"
#include "common/system.h"
#include "common/textconsole.h"
+#include "common/timer.h"
+#include "common/mutex.h"
+#include "common/config-manager.h"
#include "cine/cine.h"
#include "cine/sound.h"
#include "audio/audiostream.h"
#include "audio/fmopl.h"
+#include "audio/mididrv.h"
#include "audio/decoders/raw.h"
#include "audio/mods/soundfx.h"
@@ -48,14 +52,13 @@ public:
virtual void playSample(const byte *data, int size, int channel, int volume) = 0;
virtual void stopAll() = 0;
virtual const char *getInstrumentExtension() const { return ""; }
+ virtual void notifyInstrumentLoad(const byte *data, int size, int channel) {}
- void setUpdateCallback(UpdateCallback upCb, void *ref);
+ virtual void setUpdateCallback(UpdateCallback upCb, void *ref) = 0;
void resetChannel(int channel);
void findNote(int freq, int *note, int *oct) const;
protected:
- UpdateCallback _upCb;
- void *_upRef;
static const int _noteTable[];
static const int _noteTableCount;
@@ -104,6 +107,7 @@ public:
virtual ~AdLibSoundDriver();
// PCSoundDriver interface
+ virtual void setUpdateCallback(UpdateCallback upCb, void *ref);
virtual void setupChannel(int channel, const byte *data, int instrument, int volume);
virtual void stopChannel(int channel);
virtual void stopAll();
@@ -121,6 +125,9 @@ public:
virtual void loadInstrument(const byte *data, AdLibSoundInstrument *asi) = 0;
protected:
+ UpdateCallback _upCb;
+ void *_upRef;
+
FM_OPL *_opl;
int _sampleRate;
Audio::Mixer *_mixer;
@@ -177,6 +184,30 @@ public:
virtual void playSample(const byte *data, int size, int channel, int volume);
};
+// (Future Wars) MIDI driver
+class MidiSoundDriverH32 : public PCSoundDriver {
+public:
+ MidiSoundDriverH32(MidiDriver *output);
+ ~MidiSoundDriverH32();
+
+ virtual void setUpdateCallback(UpdateCallback upCb, void *ref);
+ virtual void setupChannel(int channel, const byte *data, int instrument, int volume);
+ virtual void setChannelFrequency(int channel, int frequency);
+ virtual void stopChannel(int channel);
+ virtual void playSample(const byte *data, int size, int channel, int volume);
+ virtual void stopAll() {}
+ virtual const char *getInstrumentExtension() const { return ".H32"; }
+ virtual void notifyInstrumentLoad(const byte *data, int size, int channel);
+
+private:
+ MidiDriver *_output;
+ UpdateCallback _callback;
+ Common::Mutex _mutex;
+
+ void writeInstrument(int offset, const byte *data, int size);
+ void selectInstrument(int channel, int timbreGroup, int timbreNumber, int volume);
+};
+
class PCSoundFxPlayer {
public:
@@ -213,23 +244,35 @@ private:
byte *_sfxData;
byte *_instrumentsData[NUM_INSTRUMENTS];
PCSoundDriver *_driver;
+ Common::Mutex _mutex;
};
-void PCSoundDriver::setUpdateCallback(UpdateCallback upCb, void *ref) {
- _upCb = upCb;
- _upRef = ref;
-}
-
void PCSoundDriver::findNote(int freq, int *note, int *oct) const {
- *note = _noteTableCount - 1;
- for (int i = 0; i < _noteTableCount; ++i) {
- if (_noteTable[i] <= freq) {
+ if (freq > 0x777)
+ *oct = 0;
+ else if (freq > 0x3BB)
+ *oct = 1;
+ else if (freq > 0x1DD)
+ *oct = 2;
+ else if (freq > 0x0EE)
+ *oct = 3;
+ else if (freq > 0x077)
+ *oct = 4;
+ else if (freq > 0x03B)
+ *oct = 5;
+ else if (freq > 0x01D)
+ *oct = 6;
+ else
+ *oct = 7;
+
+ *note = 11;
+ for (int i = 0; i < 12; ++i) {
+ if (_noteTable[*oct * 12 + i] <= freq) {
*note = i;
break;
}
}
- *oct = *note / 12;
}
void PCSoundDriver::resetChannel(int channel) {
@@ -252,6 +295,11 @@ AdLibSoundDriver::~AdLibSoundDriver() {
OPLDestroy(_opl);
}
+void AdLibSoundDriver::setUpdateCallback(UpdateCallback upCb, void *ref) {
+ _upCb = upCb;
+ _upRef = ref;
+}
+
void AdLibSoundDriver::setupChannel(int channel, const byte *data, int instrument, int volume) {
assert(channel < 4);
if (data) {
@@ -441,12 +489,11 @@ void AdLibSoundDriverINS::setChannelFrequency(int channel, int frequency) {
if (ins->mode == 0 || ins->channel == 6) {
int freq, note, oct;
findNote(frequency, &note, &oct);
- if (channel == 6) {
- note %= 12;
- }
+ if (channel == 6)
+ oct = 0;
freq = _freqTable[note % 12];
OPLWriteReg(_opl, 0xA0 | channel, freq);
- freq = ((note / 12) << 2) | ((freq & 0x300) >> 8);
+ freq = (oct << 2) | ((freq & 0x300) >> 8);
if (ins->mode == 0) {
freq |= 0x20;
}
@@ -509,14 +556,16 @@ void AdLibSoundDriverADL::setChannelFrequency(int channel, int frequency) {
findNote(frequency, &note, &oct);
if (ins->amDepth) {
note = ins->amDepth;
+ oct = note / 12;
}
if (note < 0) {
note = 0;
+ oct = 0;
}
freq = _freqTable[note % 12];
OPLWriteReg(_opl, 0xA0 | channel, freq);
- freq = ((note / 12) << 2) | ((freq & 0x300) >> 8);
+ freq = (oct << 2) | ((freq & 0x300) >> 8);
if (ins->mode == 0) {
freq |= 0x20;
}
@@ -564,8 +613,163 @@ void AdLibSoundDriverADL::playSample(const byte *data, int size, int channel, in
}
}
+MidiSoundDriverH32::MidiSoundDriverH32(MidiDriver *output)
+ : _output(output), _callback(0), _mutex() {
+}
+
+MidiSoundDriverH32::~MidiSoundDriverH32() {
+ if (_callback)
+ g_system->getTimerManager()->removeTimerProc(_callback);
+
+ _output->close();
+ delete _output;
+}
+
+void MidiSoundDriverH32::setUpdateCallback(UpdateCallback upCb, void *ref) {
+ Common::StackLock lock(_mutex);
+
+ Common::TimerManager *timer = g_system->getTimerManager();
+ assert(timer);
+
+ if (_callback)
+ timer->removeTimerProc(_callback);
+
+ _callback = upCb;
+ if (_callback)
+ timer->installTimerProc(_callback, 1000000 / 50, ref, "MidiSoundDriverH32");
+}
+
+void MidiSoundDriverH32::setupChannel(int channel, const byte *data, int instrument, int volume) {
+ Common::StackLock lock(_mutex);
+
+ if (volume < 0 || volume > 100)
+ volume = 0;
+
+ if (!data)
+ selectInstrument(channel, 0, 0, volume);
+ // In case the instrument is a builtin instrument select it directly.
+ else if (data[0] < 0x80)
+ selectInstrument(channel, data[0] / 0x40, data[0] % 0x40, volume);
+ // In case we use a custom instrument we need to specify the timbre group
+ // 2, which means it's a timbre from the timbre memory area.
+ else
+ selectInstrument(channel, 2, instrument, volume);
+}
+
+void MidiSoundDriverH32::setChannelFrequency(int channel, int frequency) {
+ Common::StackLock lock(_mutex);
+
+ int note, oct;
+ findNote(frequency, &note, &oct);
+ note %= 12;
+ note = oct * 12 + note + 12;
+
+ _output->send(0x91 + channel, note, 0x7F);
+}
+
+void MidiSoundDriverH32::stopChannel(int channel) {
+ Common::StackLock lock(_mutex);
+
+ _output->send(0xB1 + channel, 0x7B, 0x00);
+}
+
+void MidiSoundDriverH32::playSample(const byte *data, int size, int channel, int volume) {
+ Common::StackLock lock(_mutex);
+
+ stopChannel(channel);
+
+ volume = volume * 8 / 5;
+
+ if (data[0] < 0x80) {
+ selectInstrument(channel, data[0] / 0x40, data[0] % 0x40, volume);
+ } else {
+ writeInstrument(channel * 512 + 0x80000, data + 1, 256);
+ selectInstrument(channel, 2, channel, volume);
+ }
+
+ _output->send(0x91 + channel, 12, 0x7F);
+}
+
+void MidiSoundDriverH32::notifyInstrumentLoad(const byte *data, int size, int channel) {
+ Common::StackLock lock(_mutex);
+
+ // In case we specify a standard instrument or standard rhythm instrument
+ // do not do anything here. It might be noteworthy that the instrument
+ // selection client code does not support rhythm instruments!
+ if (data[0] < 0x80 || data[0] > 0xC0)
+ return;
+
+ writeInstrument(channel * 512 + 0x80000, data + 1, size - 1);
+}
+
+void MidiSoundDriverH32::writeInstrument(int offset, const byte *data, int size) {
+ byte sysEx[254];
+
+ sysEx[0] = 0x41;
+ sysEx[1] = 0x10;
+ sysEx[2] = 0x16;
+ sysEx[3] = 0x12;
+ sysEx[4] = (offset >> 16) & 0xFF;
+ sysEx[5] = (offset >> 8) & 0xFF;
+ sysEx[6] = (offset >> 0) & 0xFF;
+ int copySize = MIN(246, size);
+ memcpy(&sysEx[7], data, copySize);
+
+ byte checkSum = 0;
+ for (int i = 0; i < copySize + 3; ++i)
+ checkSum += sysEx[4 + i];
+ sysEx[7 + copySize] = 0x80 - (checkSum & 0x7F);
+
+ _output->sysEx(sysEx, copySize + 8);
+}
+
+void MidiSoundDriverH32::selectInstrument(int channel, int timbreGroup, int timbreNumber, int volume) {
+ const int offset = channel * 16 + 0x30000; // 0x30000 is the start of the patch temp area
+
+ byte sysEx[24] = {
+ 0x41, 0x10, 0x16, 0x12,
+ 0x00, 0x00, 0x00, // offset
+ 0x00, // Timbre group _ timbreGroup * 64 + timbreNumber should be the
+ 0x00, // Timbre number / MT-32 instrument in case timbreGroup is 0 or 1.
+ 0x18, // Key shift (= 0)
+ 0x32, // Fine tune (= 0)
+ 0x0C, // Bender Range
+ 0x03, // Assign Mode
+ 0x01, // Reverb Switch (= enabled)
+ 0x00, // dummy
+ 0x00, // Output level
+ 0x07, // Panpot (= balanced)
+ 0x00, // dummy
+ 0x00, // dummy
+ 0x00, // dummy
+ 0x00, // dummy
+ 0x00, // dummy
+ 0x00, // dummy
+ 0x00 // checksum
+ };
+
+
+ sysEx[4] = (offset >> 16) & 0xFF;
+ sysEx[5] = (offset >> 8) & 0xFF;
+ sysEx[6] = (offset >> 0) & 0xFF;
+
+ sysEx[7] = timbreGroup;
+ sysEx[8] = timbreNumber;
+
+ sysEx[15] = volume;
+
+ byte checkSum = 0;
+
+ for (int i = 4; i < 23; ++i)
+ checkSum += sysEx[i];
+
+ sysEx[23] = 0x80 - (checkSum & 0x7F);
+
+ _output->sysEx(sysEx, 24);
+}
+
PCSoundFxPlayer::PCSoundFxPlayer(PCSoundDriver *driver)
- : _playing(false), _driver(driver) {
+ : _playing(false), _driver(driver), _mutex() {
memset(_instrumentsData, 0, sizeof(_instrumentsData));
_sfxData = NULL;
_fadeOutCounter = 0;
@@ -573,12 +777,15 @@ PCSoundFxPlayer::PCSoundFxPlayer(PCSoundDriver *driver)
}
PCSoundFxPlayer::~PCSoundFxPlayer() {
+ Common::StackLock lock(_mutex);
+
_driver->setUpdateCallback(NULL, NULL);
stop();
}
bool PCSoundFxPlayer::load(const char *song) {
debug(9, "PCSoundFxPlayer::load('%s')", song);
+ Common::StackLock lock(_mutex);
/* stop (w/ fade out) the previous song */
while (_fadeOutCounter != 0 && _fadeOutCounter < 100) {
@@ -602,15 +809,18 @@ bool PCSoundFxPlayer::load(const char *song) {
memcpy(instrument, _sfxData + 20 + i * 30, 12);
instrument[63] = '\0';
- if (strlen(instrument) != 0) {
+ if (instrument[0] != '\0') {
char *dot = strrchr(instrument, '.');
if (dot) {
*dot = '\0';
}
strcat(instrument, _driver->getInstrumentExtension());
- _instrumentsData[i] = readBundleSoundFile(instrument);
+ uint32 instrumentSize;
+ _instrumentsData[i] = readBundleSoundFile(instrument, &instrumentSize);
if (!_instrumentsData[i]) {
warning("Unable to load soundfx instrument '%s'", instrument);
+ } else {
+ _driver->notifyInstrumentLoad(_instrumentsData[i], instrumentSize, i);
}
}
}
@@ -619,6 +829,7 @@ bool PCSoundFxPlayer::load(const char *song) {
void PCSoundFxPlayer::play() {
debug(9, "PCSoundFxPlayer::play()");
+ Common::StackLock lock(_mutex);
if (_sfxData) {
for (int i = 0; i < NUM_CHANNELS; ++i) {
_instrumentsChannelTable[i] = -1;
@@ -633,6 +844,7 @@ void PCSoundFxPlayer::play() {
}
void PCSoundFxPlayer::stop() {
+ Common::StackLock lock(_mutex);
if (_playing || _fadeOutCounter != 0) {
_fadeOutCounter = 0;
_playing = false;
@@ -645,6 +857,7 @@ void PCSoundFxPlayer::stop() {
}
void PCSoundFxPlayer::fadeOut() {
+ Common::StackLock lock(_mutex);
if (_playing) {
_fadeOutCounter = 1;
_playing = false;
@@ -656,6 +869,7 @@ void PCSoundFxPlayer::updateCallback(void *ref) {
}
void PCSoundFxPlayer::update() {
+ Common::StackLock lock(_mutex);
if (_playing || (_fadeOutCounter != 0 && _fadeOutCounter < 100)) {
++_updateTicksCounter;
if (_updateTicksCounter > _eventsDelay) {
@@ -717,12 +931,33 @@ void PCSoundFxPlayer::unload() {
PCSound::PCSound(Audio::Mixer *mixer, CineEngine *vm)
- : Sound(mixer, vm) {
- if (_vm->getGameType() == GType_FW) {
- _soundDriver = new AdLibSoundDriverINS(_mixer);
- } else {
- _soundDriver = new AdLibSoundDriverADL(_mixer);
+ : Sound(mixer, vm), _soundDriver(0) {
+
+ const MidiDriver::DeviceHandle dev = MidiDriver::detectDevice(MDT_MIDI | MDT_ADLIB);
+ const MusicType musicType = MidiDriver::getMusicType(dev);
+ if (musicType == MT_MT32 || musicType == MT_GM) {
+ const bool isMT32 = (musicType == MT_MT32 || ConfMan.getBool("native_mt32"));
+ if (isMT32) {
+ MidiDriver *driver = MidiDriver::createMidi(dev);
+ if (driver && driver->open() == 0) {
+ driver->sendMT32Reset();
+ _soundDriver = new MidiSoundDriverH32(driver);
+ } else {
+ warning("Could not create MIDI output, falling back to AdLib");
+ }
+ } else {
+ warning("General MIDI output devices are not supported, falling back to AdLib");
+ }
}
+
+ if (!_soundDriver) {
+ if (_vm->getGameType() == GType_FW) {
+ _soundDriver = new AdLibSoundDriverINS(_mixer);
+ } else {
+ _soundDriver = new AdLibSoundDriverADL(_mixer);
+ }
+ }
+
_player = new PCSoundFxPlayer(_soundDriver);
}
diff --git a/engines/composer/composer.cpp b/engines/composer/composer.cpp
index 085ce815dd..556dad7e94 100644
--- a/engines/composer/composer.cpp
+++ b/engines/composer/composer.cpp
@@ -32,6 +32,7 @@
#include "graphics/cursorman.h"
#include "graphics/surface.h"
#include "graphics/pixelformat.h"
+#include "graphics/wincursor.h"
#include "engines/util.h"
#include "engines/advancedDetector.h"
@@ -52,6 +53,11 @@ ComposerEngine::ComposerEngine(OSystem *syst, const ComposerGameDescription *gam
ComposerEngine::~ComposerEngine() {
DebugMan.clearAllDebugChannels();
+ stopPipes();
+ for (Common::List<OldScript *>::iterator i = _oldScripts.begin(); i != _oldScripts.end(); i++)
+ delete *i;
+ for (Common::List<Animation *>::iterator i = _anims.begin(); i != _anims.end(); i++)
+ delete *i;
for (Common::List<Library>::iterator i = _libraries.begin(); i != _libraries.end(); i++)
delete i->_archive;
for (Common::List<Sprite>::iterator i = _sprites.begin(); i != _sprites.end(); i++)
@@ -99,6 +105,11 @@ Common::Error ComposerEngine::run() {
_surface.create(width, height, Graphics::PixelFormat::createFormatCLUT8());
_needsUpdate = true;
+ Graphics::Cursor *cursor = Graphics::makeDefaultWinCursor();
+ CursorMan.replaceCursor(cursor->getSurface(), cursor->getWidth(), cursor->getHeight(), cursor->getHotspotX(),
+ cursor->getHotspotY(), cursor->getKeyColor());
+ CursorMan.replaceCursorPalette(cursor->getPalette(), cursor->getPaletteStartIndex(), cursor->getPaletteCount());
+
loadLibrary(0);
_currentTime = 0;
@@ -150,6 +161,7 @@ Common::Error ComposerEngine::run() {
redraw();
+ tickOldScripts();
processAnimFrame();
} else if (_needsUpdate) {
redraw();
@@ -213,11 +225,13 @@ void ComposerEngine::onMouseDown(const Common::Point &pos) {
if (!button)
return;
+ debug(3, "mouseDown on button id %d", button->_id);
+
// TODO: other buttons?
uint16 buttonsDown = 1; // MK_LBUTTON
uint16 spriteId = sprite ? sprite->_id : 0;
- runScript(button->_scriptId, button->_id, buttonsDown, spriteId);
+ runScript(button->_scriptId, (getGameType() == GType_ComposerV1) ? 0 : button->_id, buttonsDown, spriteId);
}
void ComposerEngine::onMouseMove(const Common::Point &pos) {
@@ -233,21 +247,48 @@ void ComposerEngine::onMouseMove(const Common::Point &pos) {
const Button *button = getButtonFor(sprite, pos);
if (_lastButton != button) {
if (_lastButton && _lastButton->_scriptIdRollOff)
- runScript(_lastButton->_scriptIdRollOff, _lastButton->_id, buttonsDown, 0);
+ runScript(_lastButton->_scriptIdRollOff, (getGameType() == GType_ComposerV1) ? 0 : _lastButton->_id, buttonsDown, 0);
_lastButton = button;
if (_lastButton && _lastButton->_scriptIdRollOn)
- runScript(_lastButton->_scriptIdRollOn, _lastButton->_id, buttonsDown, 0);
+ runScript(_lastButton->_scriptIdRollOn, (getGameType() == GType_ComposerV1) ? 0 : _lastButton->_id, buttonsDown, 0);
}
if (_mouseSpriteId) {
addSprite(_mouseSpriteId, 0, 0, _lastMousePos - _mouseOffset);
- _needsUpdate = true;
}
+ _needsUpdate = true;
}
void ComposerEngine::onKeyDown(uint16 keyCode) {
runEvent(kEventKeyDown, keyCode, 0, 0);
runEvent(kEventChar, keyCode, 0, 0);
+
+ for (Common::List<Library>::iterator i = _libraries.begin(); i != _libraries.end(); i++) {
+ for (Common::List<KeyboardHandler>::iterator j = i->_keyboardHandlers.begin(); j != i->_keyboardHandlers.end(); j++) {
+ const KeyboardHandler &handler = *j;
+ if (keyCode != handler.keyId)
+ continue;
+
+ int modifiers = g_system->getEventManager()->getModifierState();
+ switch (handler.modifierId) {
+ case 0x10: // shift
+ if (!(modifiers & Common::KBD_SHIFT))
+ continue;
+ break;
+ case 0x11: // control
+ if (!(modifiers & Common::KBD_CTRL))
+ continue;
+ break;
+ case 0:
+ break;
+ default:
+ warning("unknown keyb modifier %d", handler.modifierId);
+ continue;
+ }
+
+ runScript(handler.scriptId);
+ }
+ }
}
void ComposerEngine::setCursor(uint16 id, const Common::Point &offset) {
@@ -269,11 +310,15 @@ void ComposerEngine::setCursorVisible(bool visible) {
_mouseVisible = true;
if (_mouseSpriteId)
addSprite(_mouseSpriteId, 0, 0, _lastMousePos - _mouseOffset);
+ else
+ CursorMan.showMouse(true);
onMouseMove(_lastMousePos);
} else if (!visible && _mouseVisible) {
_mouseVisible = false;
if (_mouseSpriteId)
removeSprite(_mouseSpriteId, 0);
+ else
+ CursorMan.showMouse(false);
}
}
@@ -316,9 +361,42 @@ Common::String ComposerEngine::mangleFilename(Common::String filename) {
}
void ComposerEngine::loadLibrary(uint id) {
- if (!id)
- id = atoi(getStringFromConfig("Common", "StartUp").c_str());
- Common::String filename = getFilename("Libs", id);
+ if (getGameType() == GType_ComposerV1 && !_libraries.empty()) {
+ // kill the previous page, starting with any scripts running on it
+
+ for (Common::List<OldScript *>::iterator i = _oldScripts.begin(); i != _oldScripts.end(); i++)
+ delete *i;
+ _oldScripts.clear();
+
+ Library *library = &_libraries.front();
+ unloadLibrary(library->_id);
+ }
+
+ Common::String filename;
+
+ if (getGameType() == GType_ComposerV1) {
+ if (!id || _bookGroup.empty())
+ filename = getStringFromConfig("Common", "StartPage");
+ else
+ filename = getStringFromConfig(_bookGroup, Common::String::format("%d", id));
+ filename = mangleFilename(filename);
+
+ _bookGroup.clear();
+ for (uint i = 0; i < filename.size(); i++) {
+ if (filename[i] == '\\' || filename[i] == ':')
+ continue;
+ for (uint j = 0; j < filename.size(); j++) {
+ if (filename[j] == '.')
+ break;
+ _bookGroup += filename[j];
+ }
+ break;
+ }
+ } else {
+ if (!id)
+ id = atoi(getStringFromConfig("Common", "StartUp").c_str());
+ filename = getFilename("Libs", id);
+ }
Library library;
@@ -348,6 +426,37 @@ void ComposerEngine::loadLibrary(uint id) {
newLib._buttons.push_back(button);
}
+ Common::Array<uint16> ambientResources = library._archive->getResourceIDList(ID_AMBI);
+ for (uint i = 0; i < ambientResources.size(); i++) {
+ Common::SeekableReadStream *stream = library._archive->getResource(ID_AMBI, ambientResources[i]);
+ Button button(stream);
+ newLib._buttons.insert(newLib._buttons.begin(), button);
+ }
+
+ Common::Array<uint16> accelResources = library._archive->getResourceIDList(ID_ACEL);
+ for (uint i = 0; i < accelResources.size(); i++) {
+ Common::SeekableReadStream *stream = library._archive->getResource(ID_ACEL, accelResources[i]);
+ KeyboardHandler handler;
+ handler.keyId = stream->readUint16LE();
+ handler.modifierId = stream->readUint16LE();
+ handler.scriptId = stream->readUint16LE();
+ newLib._keyboardHandlers.push_back(handler);
+ }
+
+ Common::Array<uint16> randResources = library._archive->getResourceIDList(ID_RAND);
+ for (uint i = 0; i < randResources.size(); i++) {
+ Common::SeekableReadStream *stream = library._archive->getResource(ID_RAND, randResources[i]);
+ Common::Array<RandomEvent> &events = _randomEvents[randResources[i]];
+ uint16 count = stream->readUint16LE();
+ for (uint j = 0; j < count; j++) {
+ RandomEvent random;
+ random.scriptId = stream->readUint16LE();
+ random.weight = stream->readUint16LE();
+ events.push_back(random);
+ }
+ delete stream;
+ }
+
// add background sprite, if it exists
if (hasResource(ID_BMAP, 1000))
setBackground(1000);
@@ -373,10 +482,9 @@ void ComposerEngine::unloadLibrary(uint id) {
delete *j;
}
_anims.clear();
- for (Common::List<Pipe *>::iterator j = _pipes.begin(); j != _pipes.end(); j++) {
- delete *j;
- }
- _pipes.clear();
+ stopPipes();
+
+ _randomEvents.clear();
for (Common::List<Sprite>::iterator j = _sprites.begin(); j != _sprites.end(); j++) {
j->_surface.free();
@@ -426,13 +534,14 @@ Button::Button(Common::SeekableReadStream *stream, uint16 id, uint gameType) {
_type = stream->readUint16LE();
_active = (_type & 0x8000) ? true : false;
+ bool hasRollover = (gameType == GType_ComposerV1) && (_type & 0x4000);
_type &= 0xfff;
debug(9, "button %d: type %d, active %d", id, _type, _active);
- uint16 flags = 0;
uint16 size = 4;
if (gameType == GType_ComposerV1) {
- flags = stream->readUint16LE();
+ stream->skip(2);
+
_zorder = 0;
_scriptId = stream->readUint16LE();
_scriptIdRollOn = 0;
@@ -469,7 +578,7 @@ Button::Button(Common::SeekableReadStream *stream, uint16 id, uint gameType) {
error("unknown button type %d", _type);
}
- if (flags & 0x40) {
+ if (hasRollover) {
_scriptIdRollOn = stream->readUint16LE();
_scriptIdRollOff = stream->readUint16LE();
}
@@ -477,6 +586,26 @@ Button::Button(Common::SeekableReadStream *stream, uint16 id, uint gameType) {
delete stream;
}
+// AMBI-style button
+Button::Button(Common::SeekableReadStream *stream) {
+ _id = 0;
+ _zorder = 0;
+ _active = true;
+ _type = kButtonSprites;
+ _scriptIdRollOn = 0;
+ _scriptIdRollOff = 0;
+
+ _scriptId = stream->readUint16LE();
+
+ uint16 count = stream->readUint16LE();
+ for (uint j = 0; j < count; j++) {
+ uint16 spriteId = stream->readUint16LE();
+ _spriteIds.push_back(spriteId);
+ }
+
+ delete stream;
+}
+
bool Button::contains(const Common::Point &pos) const {
switch (_type) {
case kButtonRect:
@@ -524,4 +653,16 @@ const Button *ComposerEngine::getButtonFor(const Sprite *sprite, const Common::P
return NULL;
}
+void ComposerEngine::setButtonActive(uint16 id, bool active) {
+ for (Common::List<Library>::iterator l = _libraries.begin(); l != _libraries.end(); l++) {
+ for (Common::List<Button>::iterator i = l->_buttons.begin(); i != l->_buttons.end(); i++) {
+ if (i->_id != id)
+ continue;
+ i->_active = active;
+ }
+ }
+
+ onMouseMove(_lastMousePos);
+}
+
} // End of namespace Composer
diff --git a/engines/composer/composer.h b/engines/composer/composer.h
index 03e895b59e..0f53258289 100644
--- a/engines/composer/composer.h
+++ b/engines/composer/composer.h
@@ -69,6 +69,7 @@ class Button {
public:
Button() { }
Button(Common::SeekableReadStream *stream, uint16 id, uint gameType);
+ Button(Common::SeekableReadStream *stream);
bool contains(const Common::Point &pos) const;
@@ -94,11 +95,23 @@ enum {
kEventKeyUp = 7
};
+struct KeyboardHandler {
+ uint16 keyId;
+ uint16 modifierId;
+ uint16 scriptId;
+};
+
+struct RandomEvent {
+ uint16 weight;
+ uint16 scriptId;
+};
+
struct Library {
uint _id;
Archive *_archive;
Common::List<Button> _buttons;
+ Common::List<KeyboardHandler> _keyboardHandlers;
};
struct QueuedScript {
@@ -116,6 +129,19 @@ struct PendingPageChange {
bool _remove;
};
+struct OldScript {
+ OldScript(uint16 id, Common::SeekableReadStream *stream);
+ ~OldScript();
+
+ uint16 _id;
+
+ uint32 _size;
+ Common::SeekableReadStream *_stream;
+
+ uint16 _zorder;
+ uint32 _currDelay;
+};
+
class ComposerEngine : public Engine {
protected:
Common::Error run();
@@ -149,15 +175,20 @@ private:
uint _directoriesToStrip;
Common::ConfigFile _bookIni;
+ Common::String _bookGroup;
Common::List<Library> _libraries;
Common::Array<PendingPageChange> _pendingPageChanges;
Common::Array<uint16> _stack;
Common::Array<uint16> _vars;
+ Common::List<OldScript *> _oldScripts;
Common::Array<QueuedScript> _queuedScripts;
Common::List<Animation *> _anims;
Common::List<Pipe *> _pipes;
+ Common::Array<Common::SeekableReadStream *> _pipeStreams;
+
+ Common::HashMap<uint16, Common::Array<RandomEvent> > _randomEvents;
void onMouseDown(const Common::Point &pos);
void onMouseMove(const Common::Point &pos);
@@ -188,17 +219,25 @@ private:
void setArg(uint16 arg, uint16 type, uint16 val);
void runScript(uint16 id);
int16 scriptFuncCall(uint16 id, int16 param1, int16 param2, int16 param3);
+ void runOldScript(uint16 id, uint16 wait);
+ void stopOldScript(uint16 id);
+ void tickOldScripts();
+ bool tickOldScript(OldScript *script);
void playAnimation(uint16 animId, int16 param1, int16 param2, int16 param3);
void stopAnimation(Animation *anim, bool localOnly = false, bool pipesOnly = false);
void playWaveForAnim(uint16 id, uint16 priority, bool bufferingOnly);
void processAnimFrame();
+ void playPipe(uint16 id);
+ void stopPipes();
+
bool spriteVisible(uint16 id, uint16 animId);
Sprite *addSprite(uint16 id, uint16 animId, uint16 zorder, const Common::Point &pos);
void removeSprite(uint16 id, uint16 animId);
const Sprite *getSpriteAtPos(const Common::Point &pos);
const Button *getButtonFor(const Sprite *sprite, const Common::Point &pos);
+ void setButtonActive(uint16 id, bool active);
void dirtySprite(const Sprite &sprite);
void redraw();
diff --git a/engines/composer/detection.cpp b/engines/composer/detection.cpp
index eb4e820a13..835f3c5683 100644
--- a/engines/composer/detection.cpp
+++ b/engines/composer/detection.cpp
@@ -53,9 +53,12 @@ Common::Language ComposerEngine::getLanguage() const {
static const PlainGameDescriptor composerGames[] = {
{"composer", "Composer Game"},
+ {"babayaga", "Magic Tales: Baba Yaga and the Magic Geese"},
{"darby", "Darby the Dragon"},
{"gregory", "Gregory and the Hot Air Balloon"},
+ {"imoking", "Magic Tales: Imo and the King"},
{"liam", "Magic Tales: Liam Finds a Story"},
+ {"littlesamurai", "Magic Tales: The Little Samurai"},
{"princess", "The Princess and the Crab"},
{"sleepingcub", "Sleeping Cub's Test of Courage"},
{0, 0}
@@ -64,6 +67,90 @@ static const PlainGameDescriptor composerGames[] = {
namespace Composer {
static const ComposerGameDescription gameDescriptions[] = {
+ // Magic Tales: Baba Yaga and the Magic Geese - from bug #3485018
+ {
+ {
+ "babayaga",
+ "",
+ AD_ENTRY1s("book.ini", "412b7f4b0ef07f442009d28e3a819974", 3852),
+ Common::EN_ANY,
+ Common::kPlatformWindows,
+ ADGF_NO_FLAGS,
+ GUIO1(GUIO_NOASPECT)
+ },
+ GType_ComposerV1
+ },
+
+ // Magic Tales: Baba Yaga and the Magic Geese Mac - from bug #3466402
+ {
+ {
+ "babayaga",
+ "",
+ AD_ENTRY1("Baba Yaga", "ae3a4445f42fe10253da7ee4ea0d37"),
+ Common::EN_ANY,
+ Common::kPlatformMacintosh,
+ ADGF_NO_FLAGS,
+ GUIO1(GUIO_NOASPECT)
+ },
+ GType_ComposerV1
+ },
+
+ // Magic Tales: Imo and the King - from bug #3485018
+ {
+ {
+ "imoking",
+ "",
+ AD_ENTRY1s("book.ini", "62b52a1763cce7d7d6ccde9f9d32fd4b", 3299),
+ Common::EN_ANY,
+ Common::kPlatformWindows,
+ ADGF_NO_FLAGS,
+ GUIO1(GUIO_NOASPECT)
+ },
+ GType_ComposerV1
+ },
+
+ // Magic Tales: Imo and the King Mac - from bug #3466402
+ {
+ {
+ "imoking",
+ "",
+ AD_ENTRY1("imo and the king", "b0277885fec943b5f19409f35b33964c"),
+ Common::EN_ANY,
+ Common::kPlatformMacintosh,
+ ADGF_NO_FLAGS,
+ GUIO1(GUIO_NOASPECT)
+ },
+ GType_ComposerV1
+ },
+
+ // Magic Tales: The Little Samurai - from bug #3485018
+ {
+ {
+ "littlesamurai",
+ "",
+ AD_ENTRY1s("book.ini", "7a851869d022a9041e0dd11e5bace09b", 3747),
+ Common::EN_ANY,
+ Common::kPlatformWindows,
+ ADGF_NO_FLAGS,
+ GUIO1(GUIO_NOASPECT)
+ },
+ GType_ComposerV1
+ },
+
+ // Magic Tales: The Little Samurai Mac - from bug #3466402
+ {
+ {
+ "littlesamurai",
+ "",
+ AD_ENTRY1("The Little Samurai", "38121dd649c24e8676aa108cf35d44b5"),
+ Common::EN_ANY,
+ Common::kPlatformMacintosh,
+ ADGF_NO_FLAGS,
+ GUIO1(GUIO_NOASPECT)
+ },
+ GType_ComposerV1
+ },
+
// from Liam Finds a Story CD
{
{
@@ -73,7 +160,7 @@ static const ComposerGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_USEEXTRAASTITLE | ADGF_DEMO,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_ComposerV1
},
@@ -86,7 +173,25 @@ static const ComposerGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
+ },
+ GType_ComposerV2
+ },
+
+ // Liam Finds a Story Mac - from bug #3463201
+ {
+ {
+ "liam",
+ 0,
+ {
+ {"liam finds a story.ini", 0, "85a1ca6002ded8572920bbdb73d35b0a", -1},
+ {"page99.rsc", 0, "11b0a19c6b6d73c39e2bd289a457c1dc", -1},
+ AD_LISTEND
+ },
+ Common::EN_ANY,
+ Common::kPlatformMacintosh,
+ ADGF_NO_FLAGS,
+ GUIO1(GUIO_NOASPECT)
},
GType_ComposerV2
},
@@ -100,7 +205,7 @@ static const ComposerGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_USEEXTRAASTITLE | ADGF_DEMO,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_ComposerV2
},
@@ -117,7 +222,7 @@ static const ComposerGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_ComposerV2
},
@@ -130,7 +235,7 @@ static const ComposerGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformMacintosh,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_ComposerV2
},
@@ -143,7 +248,7 @@ static const ComposerGameDescription gameDescriptions[] = {
Common::FR_FRA,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_ComposerV2
},
@@ -160,7 +265,7 @@ static const ComposerGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_ComposerV2
},
@@ -173,7 +278,7 @@ static const ComposerGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformMacintosh,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_ComposerV2
},
@@ -186,7 +291,7 @@ static const ComposerGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_ComposerV2
},
@@ -203,7 +308,25 @@ static const ComposerGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
+ },
+ GType_ComposerV2
+ },
+
+ // The Princess and the Crab Mac - From Bug #3461984
+ {
+ {
+ "princess",
+ 0,
+ {
+ {"the princess and the crab.ini", 0, "f6b551a7304643004bd5e4df7ac1e76e", -1},
+ {"page99.rsc", 0, "fd5ebd3b5e36c4651c50241619525355", -1},
+ AD_LISTEND
+ },
+ Common::EN_ANY,
+ Common::kPlatformMacintosh,
+ ADGF_NO_FLAGS,
+ GUIO1(GUIO_NOASPECT)
},
GType_ComposerV2
},
@@ -220,7 +343,25 @@ static const ComposerGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
+ },
+ GType_ComposerV2
+ },
+
+ // Sleeping Cub Mac - From Bug #3461369
+ {
+ {
+ "sleepingcub",
+ 0,
+ {
+ {"sleeping cub.ini", 0, "39642a4036cb51443f5e90052c3ad0b2", -1},
+ {"page99.rsc", 0, "219fbd9bd2ff87c7023814405d753145", -1},
+ AD_LISTEND
+ },
+ Common::EN_ANY,
+ Common::kPlatformMacintosh,
+ ADGF_NO_FLAGS,
+ GUIO1(GUIO_NOASPECT)
},
GType_ComposerV2
},
@@ -235,6 +376,7 @@ using namespace Composer;
// we match from data too, to stop detection from a non-top-level directory
const static char *directoryGlobs[] = {
"data",
+ "liam",
"programs",
"princess",
"sleepcub",
diff --git a/engines/composer/graphics.cpp b/engines/composer/graphics.cpp
index f253d85ad7..1314e903ae 100644
--- a/engines/composer/graphics.cpp
+++ b/engines/composer/graphics.cpp
@@ -123,8 +123,10 @@ void ComposerEngine::playAnimation(uint16 animId, int16 x, int16 y, int16 eventP
// If the resource is a pipe itself, then load the pipe
// and then fish the requested animation out of it.
if (type != 1) {
+ _pipeStreams.push_back(stream);
newPipe = new Pipe(stream);
_pipes.push_front(newPipe);
+ newPipe->nextFrame();
stream = newPipe->getResource(ID_ANIM, animId, false);
}
}
@@ -187,8 +189,10 @@ void ComposerEngine::playWaveForAnim(uint16 id, uint16 priority, bool bufferingO
}
}
Common::SeekableReadStream *stream = NULL;
+ bool fromPipe = true;
if (!bufferingOnly && hasResource(ID_WAVE, id)) {
stream = getResource(ID_WAVE, id);
+ fromPipe = false;
} else {
for (Common::List<Pipe *>::iterator k = _pipes.begin(); k != _pipes.end(); k++) {
Pipe *pipe = *k;
@@ -200,12 +204,18 @@ void ComposerEngine::playWaveForAnim(uint16 id, uint16 priority, bool bufferingO
}
if (!stream)
return;
- // FIXME: non-pipe buffers have fixed wav header (data at +44, size at +40)
- byte *buffer = (byte *)malloc(stream->size());
- stream->read(buffer, stream->size());
+
+ uint32 size = stream->size();
+ if (!fromPipe) {
+ // non-pipe buffers have fixed wav header (data at +44, size at +40)
+ stream->skip(40);
+ size = stream->readUint32LE();
+ }
+ byte *buffer = (byte *)malloc(size);
+ stream->read(buffer, size);
if (!_audioStream)
_audioStream = Audio::makeQueuingAudioStream(22050, false);
- _audioStream->queueBuffer(buffer, stream->size(), DisposeAfterUse::YES, Audio::FLAG_UNSIGNED);
+ _audioStream->queueBuffer(buffer, size, DisposeAfterUse::YES, Audio::FLAG_UNSIGNED);
_currSoundPriority = priority;
delete stream;
if (!_mixer->isSoundHandleActive(_soundHandle))
@@ -351,9 +361,50 @@ void ComposerEngine::processAnimFrame() {
for (Common::List<Pipe *>::iterator j = _pipes.begin(); j != _pipes.end(); j++) {
Pipe *pipe = *j;
pipe->nextFrame();
+
+ // V1 pipe audio; see OldPipe
+ if (pipe->hasResource(ID_WAVE, 0xffff))
+ playWaveForAnim(0xffff, 0, false);
}
}
+void ComposerEngine::playPipe(uint16 id) {
+ stopPipes();
+
+ if (!hasResource(ID_PIPE, id)) {
+ error("couldn't find pipe %d", id);
+ }
+
+ Common::SeekableReadStream *stream = getResource(ID_PIPE, id);
+ OldPipe *pipe = new OldPipe(stream);
+ _pipes.push_front(pipe);
+ //pipe->nextFrame();
+
+ const Common::Array<uint16> *scripts = pipe->getScripts();
+ if (scripts && !scripts->empty())
+ runScript((*scripts)[0], 1, 0, 0);
+}
+
+void ComposerEngine::stopPipes() {
+ for (Common::List<Pipe *>::iterator j = _pipes.begin(); j != _pipes.end(); j++) {
+ const Common::Array<uint16> *scripts = (*j)->getScripts();
+ if (scripts) {
+ for (uint i = 0; i < scripts->size(); i++) {
+ removeSprite((*scripts)[i], 0);
+ stopOldScript((*scripts)[i]);
+ }
+ }
+ delete *j;
+ }
+
+ _pipes.clear();
+
+ // substreams may need to remain valid until the end of a page
+ for (uint i = 0; i < _pipeStreams.size(); i++)
+ delete _pipeStreams[i];
+ _pipeStreams.clear();
+}
+
bool ComposerEngine::spriteVisible(uint16 id, uint16 animId) {
for (Common::List<Sprite>::iterator i = _sprites.begin(); i != _sprites.end(); i++) {
if (i->_id != id)
@@ -375,7 +426,10 @@ Sprite *ComposerEngine::addSprite(uint16 id, uint16 animId, uint16 zorder, const
for (Common::List<Sprite>::iterator i = _sprites.begin(); i != _sprites.end(); i++) {
if (i->_id != id)
continue;
- if (i->_animId && animId && (i->_animId != animId))
+ if (getGameType() == GType_ComposerV1) {
+ if (i->_animId != animId)
+ continue;
+ } else if (i->_animId && animId && (i->_animId != animId))
continue;
dirtySprite(*i);
@@ -425,7 +479,10 @@ void ComposerEngine::removeSprite(uint16 id, uint16 animId) {
for (Common::List<Sprite>::iterator i = _sprites.begin(); i != _sprites.end(); i++) {
if (!i->_id || (id && i->_id != id))
continue;
- if (i->_animId && animId && (i->_animId != animId))
+ if (getGameType() == GType_ComposerV1) {
+ if (i->_animId != animId)
+ continue;
+ } else if (i->_animId && animId && (i->_animId != animId))
continue;
dirtySprite(*i);
i->_surface.free();
@@ -499,8 +556,8 @@ void ComposerEngine::loadCTBL(uint16 id, uint fadePercent) {
uint16 numEntries = stream->readUint16LE();
debug(1, "CTBL: %d entries", numEntries);
- assert(numEntries <= 256);
- assert(stream->size() == 2 + (numEntries * 3));
+ if ((numEntries > 256) || (stream->size() < 2 + (numEntries * 3)))
+ error("CTBL %d was invalid (%d entries, size %d)", id, numEntries, stream->size());
byte buffer[256 * 3];
stream->read(buffer, numEntries * 3);
diff --git a/engines/composer/resource.cpp b/engines/composer/resource.cpp
index b40bdb379b..a4e292747c 100644
--- a/engines/composer/resource.cpp
+++ b/engines/composer/resource.cpp
@@ -252,8 +252,9 @@ Pipe::Pipe(Common::SeekableReadStream *stream) {
_offset = 0;
_stream = stream;
_anim = NULL;
+}
- nextFrame();
+Pipe::~Pipe() {
}
void Pipe::nextFrame() {
@@ -334,4 +335,69 @@ Common::SeekableReadStream *Pipe::getResource(uint32 tag, uint16 id, bool buffer
return new Common::MemoryReadStream(buffer, size, DisposeAfterUse::YES);
}
+OldPipe::OldPipe(Common::SeekableReadStream *stream) : Pipe(stream), _currFrame(0) {
+ uint32 tag = _stream->readUint32BE();
+ if (tag != ID_PIPE)
+ error("invalid tag for pipe (%08x)", tag);
+
+ _numFrames = _stream->readUint32LE();
+ uint16 scriptCount = _stream->readUint16LE();
+ _scripts.reserve(scriptCount);
+ for (uint i = 0; i < scriptCount; i++)
+ _scripts.push_back(_stream->readUint16LE());
+
+ _offset = _stream->pos();
+}
+
+void OldPipe::nextFrame() {
+ if (_currFrame >= _numFrames)
+ return;
+
+ _stream->seek(_offset, SEEK_SET);
+
+ uint32 tag = _stream->readUint32BE();
+ if (tag != ID_FRME)
+ error("invalid tag for pipe (%08x)", tag);
+
+ uint16 spriteCount = _stream->readUint16LE();
+ uint32 spriteSize = _stream->readUint32LE();
+ uint32 audioSize = _stream->readUint32LE();
+
+ Common::Array<uint16> spriteIds;
+ Common::Array<PipeResourceEntry> spriteEntries;
+ for (uint i = 0; i < spriteCount; i++) {
+ spriteIds.push_back(_stream->readUint16LE());
+ PipeResourceEntry entry;
+ entry.size = _stream->readUint32LE();
+ entry.offset = _stream->readUint32LE();
+ spriteEntries.push_back(entry);
+ }
+
+ uint32 spriteDataOffset = _stream->pos();
+ _stream->skip(spriteSize);
+
+ ResourceMap &spriteResMap = _types[ID_BMAP];
+ spriteResMap.clear();
+ for (uint i = 0; i < spriteIds.size(); i++) {
+ PipeResourceEntry &entry = spriteEntries[i];
+ entry.offset += spriteDataOffset;
+ spriteResMap[spriteIds[i]].entries.push_back(entry);
+ }
+
+ ResourceMap &audioResMap = _types[ID_WAVE];
+ audioResMap.clear();
+
+ if (audioSize > 0) {
+ PipeResourceEntry entry;
+ entry.size = audioSize;
+ entry.offset = _stream->pos();
+ // we use 0xffff for per-frame pipe audio
+ audioResMap[0xffff].entries.push_back(entry);
+ _stream->skip(audioSize);
+ }
+
+ _offset = _stream->pos();
+ _currFrame++;
+}
+
} // End of namespace Composer
diff --git a/engines/composer/resource.h b/engines/composer/resource.h
index 9408cdffb8..e0052cd868 100644
--- a/engines/composer/resource.h
+++ b/engines/composer/resource.h
@@ -35,16 +35,21 @@ struct Animation;
#define ID_LBRC MKTAG('L','B','R','C') // Main FourCC
+#define ID_ACEL MKTAG('A','C','E','L') // Keyboard Accelerator (v1)
+#define ID_AMBI MKTAG('A','M','B','I') // Ambient (v1 sprite button)
#define ID_ANIM MKTAG('A','N','I','M') // Animation
#define ID_BMAP MKTAG('B','M','A','P') // Bitmap
#define ID_BUTN MKTAG('B','U','T','N') // Button
#define ID_CTBL MKTAG('C','T','B','L') // Color Table
#define ID_EVNT MKTAG('E','V','N','T') // Event
#define ID_PIPE MKTAG('P','I','P','E') // Pipe
+#define ID_RAND MKTAG('R','A','N','D') // Random Object
#define ID_SCRP MKTAG('S','C','R','P') // Script
#define ID_VARI MKTAG('V','A','R','I') // Variables
#define ID_WAVE MKTAG('W','A','V','E') // Wave
+#define ID_FRME MKTAG('F','R','M','E') // Frame
+
class Archive {
public:
Archive();
@@ -102,13 +107,16 @@ struct PipeResource {
class Pipe {
public:
Pipe(Common::SeekableReadStream *stream);
- void nextFrame();
+ virtual ~Pipe();
+ virtual void nextFrame();
Animation *_anim;
bool hasResource(uint32 tag, uint16 id) const;
Common::SeekableReadStream *getResource(uint32 tag, uint16 id, bool buffering);
+ virtual const Common::Array<uint16> *getScripts() { return NULL; }
+
protected:
Common::SeekableReadStream *_stream;
@@ -119,6 +127,18 @@ protected:
uint32 _offset;
};
+class OldPipe : public Pipe {
+public:
+ OldPipe(Common::SeekableReadStream *stream);
+ void nextFrame();
+
+ const Common::Array<uint16> *getScripts() { return &_scripts; }
+
+protected:
+ uint32 _currFrame, _numFrames;
+ Common::Array<uint16> _scripts;
+};
+
} // End of namespace Composer
#endif
diff --git a/engines/composer/scripting.cpp b/engines/composer/scripting.cpp
index 1989919233..3a201c841a 100644
--- a/engines/composer/scripting.cpp
+++ b/engines/composer/scripting.cpp
@@ -122,6 +122,11 @@ void ComposerEngine::runEvent(uint16 id, int16 param1, int16 param2, int16 param
}
int16 ComposerEngine::runScript(uint16 id, int16 param1, int16 param2, int16 param3) {
+ if (getGameType() == GType_ComposerV1) {
+ runOldScript(id, param1);
+ return 0;
+ }
+
_vars[1] = param1;
_vars[2] = param2;
_vars[3] = param3;
@@ -155,10 +160,14 @@ void ComposerEngine::setArg(uint16 arg, uint16 type, uint16 val) {
default:
error("invalid argument type %d (setting arg %d)", type, arg);
}
-
}
void ComposerEngine::runScript(uint16 id) {
+ if (getGameType() == GType_ComposerV1) {
+ runOldScript(id, 0);
+ return;
+ }
+
if (!hasResource(ID_SCRP, id)) {
debug(1, "ignoring attempt to run script %d, because it doesn't exist", id);
return;
@@ -561,25 +570,11 @@ int16 ComposerEngine::scriptFuncCall(uint16 id, int16 param1, int16 param2, int1
return 0;
case kFuncActivateButton:
debug(3, "kFuncActivateButton(%d)", param1);
- for (Common::List<Library>::iterator l = _libraries.begin(); l != _libraries.end(); l++) {
- for (Common::List<Button>::iterator i = l->_buttons.begin(); i != l->_buttons.end(); i++) {
- if (i->_id != param1)
- continue;
- i->_active = true;
- }
- }
- onMouseMove(_lastMousePos);
+ setButtonActive(param1, true);
return 1;
case kFuncDeactivateButton:
debug(3, "kFuncDeactivateButton(%d)", param1);
- for (Common::List<Library>::iterator l = _libraries.begin(); l != _libraries.end(); l++) {
- for (Common::List<Button>::iterator i = l->_buttons.begin(); i != l->_buttons.end(); i++) {
- if (i->_id != param1)
- continue;
- i->_active = false;
- }
- }
- onMouseMove(_lastMousePos);
+ setButtonActive(param1, false);
return 1;
case kFuncNewPage:
debug(3, "kFuncNewPage(%d, %d)", param1, param2);
@@ -726,4 +721,235 @@ int16 ComposerEngine::scriptFuncCall(uint16 id, int16 param1, int16 param2, int1
}
}
+OldScript::OldScript(uint16 id, Common::SeekableReadStream *stream) : _id(id), _stream(stream) {
+ _size = _stream->readUint32LE();
+ _stream->skip(2);
+ _currDelay = 0;
+ _zorder = 10;
+}
+
+OldScript::~OldScript() {
+ delete _stream;
+}
+
+void ComposerEngine::runOldScript(uint16 id, uint16 wait) {
+ stopOldScript(id);
+
+ Common::SeekableReadStream *stream = getResource(ID_SCRP, id);
+ OldScript *script = new OldScript(id, stream);
+ script->_currDelay = wait;
+ _oldScripts.push_back(script);
+}
+
+void ComposerEngine::stopOldScript(uint16 id) {
+ // FIXME: this could potentially (in the case of buggy script) be called on an in-use script
+
+ for (Common::List<OldScript *>::iterator i = _oldScripts.begin(); i != _oldScripts.end(); i++) {
+ if ((*i)->_id == id) {
+ delete *i;
+ i = _oldScripts.reverse_erase(i);
+ }
+ }
+}
+
+void ComposerEngine::tickOldScripts() {
+ for (Common::List<OldScript *>::iterator i = _oldScripts.begin(); i != _oldScripts.end(); i++) {
+ if (!tickOldScript(*i)) {
+ delete *i;
+ i = _oldScripts.reverse_erase(i);
+ }
+ }
+}
+
+enum {
+ kOldOpNoOp = 0,
+ kOldOpReplaceSprite = 1,
+ kOldOpPlayWav = 2,
+ kOldOpRunScript = 3,
+ kOldOpStopScript = 4,
+ kOldOpActivateButton = 5,
+ kOldOpDeactivateButton = 6,
+ kOldOpDrawSprite = 7,
+ kOldOpRemoveSprite = 8,
+ kOldOpDisableMouseInput = 9,
+ kOldOpEnableMouseInput = 10,
+ kOldOpWait = 11,
+ kOldOpRandWait = 12,
+ kOldOpDrawGlobalSprite = 13,
+ kOldOpRemoveGlobalSprite = 14,
+ kOldOpSetZOrder = 15,
+ kOldOpPlayPipe = 16,
+ kOldOpStopPipe = 17,
+ kOldOpNewScreen = 20,
+ kOldOpRunRandom = 22
+};
+
+bool ComposerEngine::tickOldScript(OldScript *script) {
+ if (script->_currDelay) {
+ script->_currDelay--;
+ return true;
+ }
+
+ bool running = true;
+ bool erasedOldSprite = false;
+ while (running && script->_stream->pos() < (int)script->_size) {
+ uint16 spriteId, scriptId, buttonId, pipeId;
+ Common::Point spritePos;
+
+ script->_stream->skip(0);
+ byte op = script->_stream->readByte();
+ switch (op) {
+ case kOldOpNoOp:
+ debug(3, "kOldOpNoOp()");
+ running = false;
+ break;
+ case kOldOpReplaceSprite:
+ if (!erasedOldSprite) {
+ removeSprite(0, script->_id);
+ erasedOldSprite = true;
+ }
+
+ spriteId = script->_stream->readUint16LE();
+ spritePos.x = script->_stream->readSint16LE();
+ spritePos.y = script->_stream->readSint16LE();
+ debug(3, "kOldOpReplaceSprite(%d, %d, %d)", spriteId, spritePos.x, spritePos.y);
+ addSprite(spriteId, script->_id, script->_zorder, spritePos);
+ break;
+ case kOldOpPlayWav:
+ uint16 wavId, prio;
+ wavId = script->_stream->readUint16LE();
+ prio = script->_stream->readUint16LE();
+ debug(3, "kOldOpPlayWav(%d, %d)", wavId, prio);
+ playWaveForAnim(wavId, prio, false);
+ break;
+ case kOldOpRunScript:
+ scriptId = script->_stream->readUint16LE();
+ debug(3, "kOldOpRunScript(%d)", scriptId);
+ if (scriptId == script->_id) {
+ // reset ourselves
+ removeSprite(0, script->_id);
+ script->_stream->seek(6);
+ } else {
+ runScript(scriptId);
+ }
+ break;
+ case kOldOpStopScript:
+ scriptId = script->_stream->readUint16LE();
+ debug(3, "kOldOpStopScript(%d)", scriptId);
+ removeSprite(0, scriptId);
+ stopOldScript(scriptId);
+ break;
+ case kOldOpActivateButton:
+ buttonId = script->_stream->readUint16LE();
+ debug(3, "kOldOpActivateButton(%d)", buttonId);
+ setButtonActive(buttonId, true);
+ break;
+ case kOldOpDeactivateButton:
+ buttonId = script->_stream->readUint16LE();
+ debug(3, "kOldOpDeactivateButton(%d)", buttonId);
+ setButtonActive(buttonId, false);
+ break;
+ case kOldOpDrawSprite:
+ spriteId = script->_stream->readUint16LE();
+ spritePos.x = script->_stream->readSint16LE();
+ spritePos.y = script->_stream->readSint16LE();
+ debug(3, "kOldOpDrawSprite(%d, %d, %d)", spriteId, spritePos.x, spritePos.y);
+ addSprite(spriteId, script->_id, script->_zorder, spritePos);
+ break;
+ case kOldOpRemoveSprite:
+ spriteId = script->_stream->readUint16LE();
+ debug(3, "kOldOpRemoveSprite(%d)", spriteId);
+ removeSprite(spriteId, script->_id);
+ break;
+ case kOldOpDisableMouseInput:
+ debug(3, "kOldOpDisableMouseInput()");
+ setCursorVisible(false);
+ break;
+ case kOldOpEnableMouseInput:
+ debug(3, "kOldOpEnableMouseInput()");
+ setCursorVisible(true);
+ break;
+ case kOldOpWait:
+ script->_currDelay = script->_stream->readUint16LE();
+ debug(3, "kOldOpWait(%d)", script->_currDelay);
+ break;
+ case kOldOpRandWait:
+ uint16 min, max;
+ min = script->_stream->readUint16LE();
+ max = script->_stream->readUint16LE();
+ debug(3, "kOldOpRandWait(%d, %d)", min, max);
+ script->_currDelay = _rnd->getRandomNumberRng(min, max);
+ break;
+ case kOldOpDrawGlobalSprite:
+ spriteId = script->_stream->readUint16LE();
+ spritePos.x = script->_stream->readSint16LE();
+ spritePos.y = script->_stream->readSint16LE();
+ debug(3, "kOldOpDrawGlobalSprite(%d, %d, %d)", spriteId, spritePos.x, spritePos.y);
+ addSprite(spriteId, 0, script->_zorder, spritePos);
+ break;
+ case kOldOpRemoveGlobalSprite:
+ spriteId = script->_stream->readUint16LE();
+ debug(3, "kOldOpRemoveGlobalSprite(%d)", spriteId);
+ removeSprite(spriteId, 0);
+ break;
+ case kOldOpSetZOrder:
+ script->_zorder = script->_stream->readUint16LE();
+ debug(3, "kOldOpSetZOrder(%d)", script->_zorder);
+ break;
+ case kOldOpPlayPipe:
+ pipeId = script->_stream->readUint16LE();
+ debug(3, "kOldOpPlayPipe(%d)", pipeId);
+ playPipe(pipeId);
+ break;
+ case kOldOpStopPipe:
+ pipeId = script->_stream->readUint16LE();
+ debug(3, "kOldOpStopPipe(%d)", pipeId);
+ // yes, pipeId is ignored here..
+ stopPipes();
+ break;
+ case kOldOpNewScreen:
+ uint16 newScreenId;
+ newScreenId = script->_stream->readUint16LE();
+ debug(3, "kOldOpNewScreen(%d)", newScreenId);
+ if (!newScreenId) {
+ quitGame();
+ } else {
+ _pendingPageChanges.clear();
+ _pendingPageChanges.push_back(PendingPageChange(newScreenId, false));
+ }
+ break;
+ case kOldOpRunRandom:
+ uint16 randomId;
+ randomId = script->_stream->readUint16LE();
+ debug(3, "kOldOpRunRandom(%d)", randomId);
+ if (!_randomEvents.contains(randomId)) {
+ warning("kOldOpRunRandom found no entries for id %d", randomId);
+ } else {
+ uint32 randValue = _rnd->getRandomNumberRng(0, 32767);
+ const Common::Array<RandomEvent> &events = _randomEvents[randomId];
+ uint i = 0;
+ for (i = 0; i < events.size(); i++) {
+ if ((i + 1 == events.size()) || (randValue <= events[i].weight)) {
+ runScript(events[i].scriptId);
+ break;
+ } else {
+ randValue -= events[i].weight;
+ }
+ }
+ }
+ break;
+ default:
+ error("unknown oldScript op %d", op);
+ }
+ }
+
+ if (script->_stream->pos() >= (int)script->_size) {
+ // stop running if we ran out of script
+ removeSprite(0, script->_id);
+ return false;
+ }
+
+ return true;
+}
+
} // End of namespace Composer
diff --git a/engines/cruise/background.cpp b/engines/cruise/background.cpp
index 4d1284a802..9da5413013 100644
--- a/engines/cruise/background.cpp
+++ b/engines/cruise/background.cpp
@@ -129,7 +129,7 @@ int loadBackground(const char *name, int idx) {
flagSpeed = 0;
}
- if (!strcmp((char*)ptr, "PAL")) {
+ if (!strcmp((char *)ptr, "PAL")) {
memcpy(palScreen[idx], ptr + 4, 256*3);
gfxModuleData_setPal256(palScreen[idx]);
} else {
diff --git a/engines/cruise/backgroundIncrust.cpp b/engines/cruise/backgroundIncrust.cpp
index 39286670ed..ddda8dee45 100644
--- a/engines/cruise/backgroundIncrust.cpp
+++ b/engines/cruise/backgroundIncrust.cpp
@@ -46,7 +46,7 @@ void backupBackground(backgroundIncrustStruct *pIncrust, int X, int Y, int width
pIncrust->savedX = X;
pIncrust->savedY = Y;
- pIncrust->ptr = (uint8*)MemAlloc(width * height);
+ pIncrust->ptr = (uint8 *)MemAlloc(width * height);
for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++) {
int xp = j + X;
@@ -169,7 +169,7 @@ backgroundIncrustStruct *addBackgroundIncrust(int16 overlayIdx, int16 objectIdx,
int sizeTable[4]; // 0 = left, 1 = right, 2 = bottom, 3 = top
// this function checks if the dataPtr is not 0, else it retrives the data for X, Y, scale and DataPtr again (OLD: mainDrawSub1Sub1)
- flipPoly(params.fileIdx, (int16*)filesDatabase[params.fileIdx].subData.ptr, params.scale, &newFrame, newElement->X, newElement->Y, &newX, &newY, &newScale);
+ flipPoly(params.fileIdx, (int16 *)filesDatabase[params.fileIdx].subData.ptr, params.scale, &newFrame, newElement->X, newElement->Y, &newX, &newY, &newScale);
// this function fills the sizeTable for the poly (OLD: mainDrawSub1Sub2)
getPolySize(newX, newY, newScale, sizeTable, (unsigned char*)newFrame);
@@ -213,7 +213,7 @@ void regenerateBackgroundIncrust(backgroundIncrustStruct *pHead) {
drawSprite(width, height, NULL, filesDatabase[frame].subData.ptr, pl->Y, pl->X, backgroundScreens[pl->backgroundIdx], filesDatabase[frame].subData.ptrMask);
} else {
// Poly
- addBackgroundIncrustSub1(frame, pl->X, pl->Y, NULL, pl->scale, (char*)backgroundScreens[pl->backgroundIdx], (char *)filesDatabase[frame].subData.ptr);
+ addBackgroundIncrustSub1(frame, pl->X, pl->Y, NULL, pl->scale, (char *)backgroundScreens[pl->backgroundIdx], (char *)filesDatabase[frame].subData.ptr);
}
backgroundChanged[pl->backgroundIdx] = true;
diff --git a/engines/cruise/cruise.h b/engines/cruise/cruise.h
index 94f8759d01..9782df8f09 100644
--- a/engines/cruise/cruise.h
+++ b/engines/cruise/cruise.h
@@ -116,7 +116,7 @@ public:
static uint32 const cookie = 0x41424344;
};
- Common::List<MemInfo*> _memList;
+ Common::List<MemInfo *> _memList;
typedef Common::List<Common::Rect> RectList;
diff --git a/engines/cruise/cruise_main.cpp b/engines/cruise/cruise_main.cpp
index d0340238cd..6e2847d6d7 100644
--- a/engines/cruise/cruise_main.cpp
+++ b/engines/cruise/cruise_main.cpp
@@ -45,7 +45,7 @@ typedef CruiseEngine::MemInfo MemInfo;
void MemoryList() {
if (!_vm->_memList.empty()) {
debug("Current list of un-freed memory blocks:");
- Common::List<MemInfo*>::iterator i;
+ Common::List<MemInfo *>::iterator i;
for (i = _vm->_memList.begin(); i != _vm->_memList.end(); ++i) {
MemInfo const *const v = *i;
debug("%s - %d", v->fname, v->lineNum);
@@ -691,7 +691,7 @@ int findObject(int mouseX, int mouseY, int *outObjOvl, int *outObjIdx) {
if ((filesDatabase[j].subData.resourceType == OBJ_TYPE_POLY) && (filesDatabase[j].subData.ptr)) {
int zoom = params.scale;
- int16* dataPtr = (int16*)filesDatabase[j].subData.ptr;
+ int16* dataPtr = (int16 *)filesDatabase[j].subData.ptr;
if (*dataPtr == 0) {
int16 offset;
@@ -723,7 +723,7 @@ int findObject(int mouseX, int mouseY, int *outObjOvl, int *outObjIdx) {
y -= newY;
}
- if (dataPtr && findPoly((char*)dataPtr, x, y, zoom, mouseX, mouseY)) {
+ if (dataPtr && findPoly((char *)dataPtr, x, y, zoom, mouseX, mouseY)) {
*outObjOvl = linkedObjOvl;
*outObjIdx = linkedObjIdx;
@@ -998,7 +998,7 @@ bool findRelation(int objOvl, int objIdx, int x, int y) {
ovlDataStruct *ovl2 = NULL;
ovlDataStruct *ovl3 = NULL;
- ovlDataStruct *ovl4 = NULL;
+ //ovlDataStruct *ovl4 = NULL;
if (verbeOvl > 0)
ovl2 = overlayTable[verbeOvl].ovlData;
@@ -1006,8 +1006,8 @@ bool findRelation(int objOvl, int objIdx, int x, int y) {
if (obj1Ovl > 0)
ovl3 = overlayTable[obj1Ovl].ovlData;
- if (obj2Ovl > 0)
- ovl4 = overlayTable[obj2Ovl].ovlData;
+ //if (obj2Ovl > 0)
+ // ovl4 = overlayTable[obj2Ovl].ovlData;
if ((ovl3) && (ptrHead->obj1Number >= 0)) {
testState = ptrHead->obj1OldState;
diff --git a/engines/cruise/dataLoader.cpp b/engines/cruise/dataLoader.cpp
index 66bc0fbf46..94d075ecc3 100644
--- a/engines/cruise/dataLoader.cpp
+++ b/engines/cruise/dataLoader.cpp
@@ -369,14 +369,14 @@ int loadFNTSub(uint8 *ptr, int destIdx) {
destPtr = filesDatabase[fileIndex].subData.ptr;
- memcpy(destPtr, ptr2, loadFileVar1);
-
- //fontSize = READ_BE_UINT32(ptr2);
-
if (destPtr != NULL) {
int32 i;
uint8 *currentPtr;
+ memcpy(destPtr, ptr2, loadFileVar1);
+
+ //fontSize = READ_BE_UINT32(ptr2);
+
destPtr = filesDatabase[fileIndex].subData.ptr;
bigEndianLongToNative((int32 *) destPtr);
@@ -420,7 +420,7 @@ int loadSetEntry(const char *name, uint8 *ptr, int currentEntryIdx, int currentD
int sec = 0;
uint16 numIdx;
- if (!strcmp((char*)ptr, "SEC")) {
+ if (!strcmp((char *)ptr, "SEC")) {
sec = 1;
}
diff --git a/engines/cruise/detection.cpp b/engines/cruise/detection.cpp
index a482e263a2..eb7c1c524f 100644
--- a/engines/cruise/detection.cpp
+++ b/engines/cruise/detection.cpp
@@ -75,7 +75,7 @@ static const CRUISEGameDescription gameDescriptions[] = {
Common::EN_GRB,
Common::kPlatformPC,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO0()
},
GType_CRUISE,
0,
@@ -88,7 +88,7 @@ static const CRUISEGameDescription gameDescriptions[] = {
Common::FR_FRA,
Common::kPlatformPC,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO0()
},
GType_CRUISE,
0,
@@ -101,7 +101,7 @@ static const CRUISEGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformPC,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO0()
},
GType_CRUISE,
0,
@@ -114,7 +114,7 @@ static const CRUISEGameDescription gameDescriptions[] = {
Common::FR_FRA,
Common::kPlatformPC,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO0()
},
GType_CRUISE,
0,
@@ -127,7 +127,7 @@ static const CRUISEGameDescription gameDescriptions[] = {
Common::DE_DEU,
Common::kPlatformPC,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO0()
},
GType_CRUISE,
0,
@@ -140,7 +140,7 @@ static const CRUISEGameDescription gameDescriptions[] = {
Common::DE_DEU,
Common::kPlatformPC,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO0()
},
GType_CRUISE,
0,
@@ -153,7 +153,7 @@ static const CRUISEGameDescription gameDescriptions[] = {
Common::DE_DEU,
Common::kPlatformAmiga,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO0()
},
GType_CRUISE,
0,
@@ -166,7 +166,7 @@ static const CRUISEGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformAmiga,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO0()
},
GType_CRUISE,
0,
@@ -179,7 +179,7 @@ static const CRUISEGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformAtariST,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO0()
},
GType_CRUISE,
0,
@@ -192,7 +192,7 @@ static const CRUISEGameDescription gameDescriptions[] = {
Common::IT_ITA,
Common::kPlatformPC,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO0()
},
GType_CRUISE,
0,
@@ -205,7 +205,7 @@ static const CRUISEGameDescription gameDescriptions[] = {
Common::ES_ESP,
Common::kPlatformPC,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO0()
},
GType_CRUISE,
0,
diff --git a/engines/cruise/font.cpp b/engines/cruise/font.cpp
index a6680f7a02..2fd86a11b7 100644
--- a/engines/cruise/font.cpp
+++ b/engines/cruise/font.cpp
@@ -106,7 +106,7 @@ void loadFNT(const char *fileName) {
fontFileHandle.read(header, 4);
- if (strcmp((char*)header, "FNT") == 0) {
+ if (strcmp((char *)header, "FNT") == 0) {
uint32 fontSize = fontFileHandle.readUint32BE();
_systemFNT = (uint8 *)mallocAndZero(fontSize);
diff --git a/engines/cruise/function.cpp b/engines/cruise/function.cpp
index 27b9be7e79..610465e962 100644
--- a/engines/cruise/function.cpp
+++ b/engines/cruise/function.cpp
@@ -142,7 +142,7 @@ int16 Op_AddProc() {
if (procBss) {
for (long int i = 0; i < pop1; i++) {
- int16* ptr = (int16*)(procBss + i * 2);
+ int16* ptr = (int16 *)(procBss + i * 2);
*ptr = param[i];
bigEndianShortToNative(ptr);
}
@@ -1046,7 +1046,7 @@ int16 Op_ComputeLine() {
int y1 = popVar();
int x1 = popVar();
- point* pDest = (point*)popPtr();
+ point* pDest = (point *)popPtr();
int maxValue = cor_droite(x1, y1, x2, y2, pDest);
@@ -1334,7 +1334,7 @@ int16 Op_TrackAnim() { // setup actor position
}
int16 Op_BgName() {
- char* bgName = (char*)popPtr();
+ char* bgName = (char *)popPtr();
int bgIdx = popVar();
if ((bgIdx >= 0) && (bgIdx < NBSCREENS) && bgName) {
@@ -1524,7 +1524,7 @@ int16 Op_Itoa() {
param[i] = popVar();
int val = popVar();
- char* pDest = (char*)popPtr();
+ char* pDest = (char *)popPtr();
if (!nbp)
sprintf(txt, "%d", val);
@@ -1645,7 +1645,7 @@ int16 Op_SetVolume() {
}
int16 Op_SongExist() {
- const char *songName = (char*)popPtr();
+ const char *songName = (char *)popPtr();
if (songName) {
char name[33];
diff --git a/engines/cruise/gfxModule.cpp b/engines/cruise/gfxModule.cpp
index 7bbcae2259..aa2dbc5370 100644
--- a/engines/cruise/gfxModule.cpp
+++ b/engines/cruise/gfxModule.cpp
@@ -326,7 +326,7 @@ void flip() {
void drawSolidBox(int32 x1, int32 y1, int32 x2, int32 y2, uint8 color) {
for (int y = y1; y < y2; ++y) {
byte *p = &gfxModuleData.pPage00[y * 320 + x1];
- Common::set_to(p, p + (x2 - x1), color);
+ Common::fill(p, p + (x2 - x1), color);
}
}
diff --git a/engines/cruise/mainDraw.cpp b/engines/cruise/mainDraw.cpp
index 14b6daf4bb..24f65500db 100644
--- a/engines/cruise/mainDraw.cpp
+++ b/engines/cruise/mainDraw.cpp
@@ -185,7 +185,7 @@ void flipPoly(int fileId, int16 *dataPtr, int scale, char** newFrame, int X, int
Y -= newY;
}
- *newFrame = (char*)dataPtr;
+ *newFrame = (char *)dataPtr;
*outX = X;
*outY = Y;
*outScale = scale;
@@ -621,11 +621,9 @@ void buildSegment() {
unsigned char *drawPolyMode1(unsigned char *dataPointer, int linesToDraw) {
int index;
- int16 *pBufferDest;
+ int16 *pBufferDest = polyBuffer4 + nbseg * 2;
- pBufferDest = polyBuffer4 + nbseg * 2;
nbseg = linesToDraw;
- A2ptr = polyBuffer4;
index = *(dataPointer++);
polyXMin = polyXMax = pBufferDest[-2] = pBufferDest[-2 + linesToDraw * 2] = polyBuffer2[index * 2];
@@ -1079,7 +1077,7 @@ void mainDrawPolygons(int fileIndex, cellStruct *plWork, int X, int scale, int Y
int sizeTable[4]; // 0 = left, 1 = right, 2 = bottom, 3 = top
// this function checks if the dataPtr is not 0, else it retrives the data for X, Y, scale and DataPtr again (OLD: mainDrawSub1Sub1)
- flipPoly(fileIndex, (int16*)dataPtr, scale, &newFrame, X, Y, &newX, &newY, &newScale);
+ flipPoly(fileIndex, (int16 *)dataPtr, scale, &newFrame, X, Y, &newX, &newY, &newScale);
// this function fills the sizeTable for the poly (OLD: mainDrawSub1Sub2)
getPolySize(newX, newY, newScale, sizeTable, (unsigned char*)newFrame);
@@ -1145,7 +1143,7 @@ void mainDrawPolygons(int fileIndex, cellStruct *plWork, int X, int scale, int Y
}
// this function builds the poly model and then calls the draw functions (OLD: mainDrawSub1Sub5)
- buildPolyModel(newX, newY, newScale, (char*)polygonMask, destBuffer, newFrame);
+ buildPolyModel(newX, newY, newScale, (char *)polygonMask, destBuffer, newFrame);
}
void drawMessage(const gfxEntryStruct *pGfxPtr, int globalX, int globalY, int width, int newColor, uint8 *ouputPtr) {
@@ -1421,7 +1419,7 @@ void mainDraw(int16 param) {
currentObjPtr = cellHead.next;
#ifdef _DEBUG
- /* polyOutputBuffer = (char*)bgPtr;
+ /* polyOutputBuffer = (char *)bgPtr;
drawCtp(); */
#endif
diff --git a/engines/cruise/overlay.cpp b/engines/cruise/overlay.cpp
index 2f4b375865..d618ab5599 100644
--- a/engines/cruise/overlay.cpp
+++ b/engines/cruise/overlay.cpp
@@ -185,11 +185,10 @@ int loadOverlay(const char *scriptName) {
// This memory block will be later passed to a MemoryReadStream, which will dispose of it
unpackedBuffer = (byte *)malloc(unpackedSize);
- memset(unpackedBuffer, 0, unpackedSize);
-
if (!unpackedBuffer) {
return (-2);
}
+ memset(unpackedBuffer, 0, unpackedSize);
if (volumePtrToFileDescriptor[fileIdx].size + 2 != unpackedSize) {
char *pakedBuffer =
@@ -566,11 +565,10 @@ int loadOverlay(const char *scriptName) {
// This memory block will be later passed to a MemoryReadStream, which will dispose of it
unpackedBuffer = (byte *)malloc(unpackedSize);
- memset(unpackedBuffer, 0, unpackedSize);
-
if (!unpackedBuffer) {
return (-2);
}
+ memset(unpackedBuffer, 0, unpackedSize);
if (volumePtrToFileDescriptor[fileIdx].size + 2 !=
unpackedSize) {
diff --git a/engines/cruise/saveload.cpp b/engines/cruise/saveload.cpp
index c3d1ea6643..26bea0441c 100644
--- a/engines/cruise/saveload.cpp
+++ b/engines/cruise/saveload.cpp
@@ -84,6 +84,7 @@ void writeSavegameHeader(Common::OutSaveFile *out, CruiseSavegameHeader &header)
Graphics::Surface *thumb = new Graphics::Surface();
::createThumbnail(thumb, globalScreen, 320, 200, workpal);
Graphics::saveThumbnail(*out, *thumb);
+ thumb->free();
delete thumb;
}
@@ -923,10 +924,10 @@ Common::Error loadSavegameData(int saveGameIdx) {
if (ptr) {
ASSERT(0);
- //*(int16*)(currentcellHead->datas+0x2E) = getSprite(ptr,*(int16*)(currentcellHead->datas+0xE));
+ //*(int16 *)(currentcellHead->datas+0x2E) = getSprite(ptr,*(int16 *)(currentcellHead->datas+0xE));
} else {
ASSERT(0);
- //*(int16*)(currentcellHead->datas+0x2E) = 0;
+ //*(int16 *)(currentcellHead->datas+0x2E) = 0;
}
}
diff --git a/engines/cruise/script.cpp b/engines/cruise/script.cpp
index cf28548e7d..d753d938bd 100644
--- a/engines/cruise/script.cpp
+++ b/engines/cruise/script.cpp
@@ -33,7 +33,7 @@ scriptInstanceStruct procHead;
scriptInstanceStruct *currentScriptPtr;
int8 getByteFromScript() {
- int8 var = *(int8*)(currentData3DataPtr + currentScriptPtr->scriptOffset);
+ int8 var = *(int8 *)(currentData3DataPtr + currentScriptPtr->scriptOffset);
++currentScriptPtr->scriptOffset;
return (var);
@@ -202,7 +202,7 @@ int32 opcodeType1() {
di = currentScriptPtr->overlayNumber;
}
- if ((var == 0x85) && !strcmp((char*)currentCtpName, "S26.CTP") && !di && mode == 1) { // patch in bar
+ if ((var == 0x85) && !strcmp((char *)currentCtpName, "S26.CTP") && !di && mode == 1) { // patch in bar
var = 0x87;
}
diff --git a/engines/cruise/volume.cpp b/engines/cruise/volume.cpp
index 773a146b9a..4b64d4ff77 100644
--- a/engines/cruise/volume.cpp
+++ b/engines/cruise/volume.cpp
@@ -326,7 +326,7 @@ int closeCnf() {
int16 readVolCnf() {
int i;
Common::File fileHandle;
- short int sizeHEntry;
+ //short int sizeHEntry;
volumeDataLoaded = 0;
@@ -344,7 +344,7 @@ int16 readVolCnf() {
}
numOfDisks = fileHandle.readSint16BE();
- sizeHEntry = fileHandle.readSint16BE(); // size of one header entry - 20 bytes
+ /*sizeHEntry =*/ fileHandle.readSint16BE(); // size of one header entry - 20 bytes
for (i = 0; i < numOfDisks; i++) {
// fread(&volumeData[i],20,1,fileHandle);
diff --git a/engines/dialogs.cpp b/engines/dialogs.cpp
index 435576e9e4..1b54c7e26a 100644
--- a/engines/dialogs.cpp
+++ b/engines/dialogs.cpp
@@ -227,19 +227,24 @@ void MainMenuDialog::save() {
Common::String result(_saveDialog->getResultString());
if (result.empty()) {
// If the user was lazy and entered no save name, come up with a default name.
- Common::String buf;
#if defined(USE_SAVEGAME_TIMESTAMP)
TimeDate curTime;
g_system->getTimeAndDate(curTime);
curTime.tm_year += 1900; // fixup year
curTime.tm_mon++; // fixup month
- buf = Common::String::format("%04d.%02d.%02d / %02d:%02d:%02d", curTime.tm_year, curTime.tm_mon, curTime.tm_mday, curTime.tm_hour, curTime.tm_min, curTime.tm_sec);
+ result = Common::String::format("%04d.%02d.%02d / %02d:%02d:%02d", curTime.tm_year, curTime.tm_mon, curTime.tm_mday, curTime.tm_hour, curTime.tm_min, curTime.tm_sec);
#else
- buf = Common::String::format("Save %d", slot + 1);
+ result = Common::String::format("Save %d", slot + 1);
#endif
- _engine->saveGameState(slot, buf);
- } else {
- _engine->saveGameState(slot, result);
+ }
+
+ Common::Error status = _engine->saveGameState(slot, result);
+ if (status.getCode() != Common::kNoError) {
+ Common::String failMessage = Common::String::format(_("Gamestate save failed (%s)! "
+ "Please consult the README for basic information, and for "
+ "instructions on how to obtain further assistance."), status.getDesc().c_str());
+ GUI::MessageDialog dialog(failMessage);
+ dialog.runModal();
}
close();
@@ -256,7 +261,7 @@ void MainMenuDialog::load() {
_engine->setGameToLoadSlot(slot);
- if (slot >= 0)
+ if (slot >= 0)
close();
}
diff --git a/engines/draci/barchive.cpp b/engines/draci/barchive.cpp
index 154073250c..31dfe62dee 100644
--- a/engines/draci/barchive.cpp
+++ b/engines/draci/barchive.cpp
@@ -212,7 +212,8 @@ void BArchive::openArchive(const Common::String &path) {
_files[i]._offset = fileOffset; // Offset of file from start
- assert(_f.readByte() == 0 &&
+ byte compressionType = _f.readByte();
+ assert(compressionType == 0 &&
"Compression type flag is non-zero (file is compressed)");
_files[i]._crc = _f.readByte(); // CRC checksum of the file
@@ -221,7 +222,8 @@ void BArchive::openArchive(const Common::String &path) {
}
// Last footer item should be equal to footerOffset
- assert(reader.readUint32LE() == footerOffset && "Footer offset mismatch");
+ uint32 footerOffset2 = reader.readUint32LE();
+ assert(footerOffset2 == footerOffset && "Footer offset mismatch");
// Indicate that the archive has been successfully opened
_opened = true;
diff --git a/engines/draci/detection.cpp b/engines/draci/detection.cpp
index e483e8ca9f..de76eb83e0 100644
--- a/engines/draci/detection.cpp
+++ b/engines/draci/detection.cpp
@@ -43,7 +43,7 @@ const ADGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformPC,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO0()
},
{
@@ -53,7 +53,7 @@ const ADGameDescription gameDescriptions[] = {
Common::CZ_CZE,
Common::kPlatformPC,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO0()
},
{
@@ -63,7 +63,7 @@ const ADGameDescription gameDescriptions[] = {
Common::PL_POL,
Common::kPlatformPC,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO0()
},
{
@@ -73,7 +73,7 @@ const ADGameDescription gameDescriptions[] = {
Common::DE_DEU,
Common::kPlatformPC,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO0()
},
AD_TABLE_END_MARKER
diff --git a/engines/draci/draci.cpp b/engines/draci/draci.cpp
index 67e043632e..6aa8477887 100644
--- a/engines/draci/draci.cpp
+++ b/engines/draci/draci.cpp
@@ -359,10 +359,11 @@ void DraciEngine::handleEvents() {
DraciEngine::~DraciEngine() {
// Dispose your resources here
- // If the common library supported STL's scoped_ptr<>, then wrapping
+ // If the common library supported Boost's scoped_ptr<>, then wrapping
// all the following pointers and many more would be appropriate. So
// far, there is only SharedPtr, which I feel being an overkill for
// easy deallocation.
+ // TODO: We have ScopedPtr nowadays. Maybe should adapt this code then?
delete _smallFont;
delete _bigFont;
diff --git a/engines/draci/saveload.cpp b/engines/draci/saveload.cpp
index b3bf0cbcd8..e3551c78b3 100644
--- a/engines/draci/saveload.cpp
+++ b/engines/draci/saveload.cpp
@@ -41,7 +41,7 @@ bool readSavegameHeader(Common::InSaveFile *in, DraciSavegameHeader &header) {
// Validate the header Id
in->read(saveIdentBuffer, 6);
- if (strcmp(saveIdentBuffer, draciIdentString))
+ if (strcmp(saveIdentBuffer, draciIdentString) != 0)
return false;
header.version = in->readByte();
diff --git a/engines/draci/sprite.cpp b/engines/draci/sprite.cpp
index 92ce7d31d9..965cdabf3e 100644
--- a/engines/draci/sprite.cpp
+++ b/engines/draci/sprite.cpp
@@ -318,7 +318,7 @@ void Text::repeatedlySplitLongLines(uint maxWidth) {
}
void Text::splitLinesLongerThan(uint maxWidth) {
- char *start = const_cast<char*> (_text.c_str()); // hacky
+ char *start = const_cast<char *> (_text.c_str()); // hacky
while (1) {
char *end = strchr(start, '|');
if (end) {
diff --git a/engines/draci/walking.cpp b/engines/draci/walking.cpp
index 9a66c6163a..f1ae769d80 100644
--- a/engines/draci/walking.cpp
+++ b/engines/draci/walking.cpp
@@ -729,20 +729,18 @@ Movement WalkingState::transitionBetweenAnimations(Movement previous, Movement n
Movement WalkingState::animationForSightDirection(SightDirection dir, const Common::Point &hero, const Common::Point &mouse, const WalkingPath &path, Movement startingDirection) {
switch (dir) {
+ case kDirectionLeft:
+ return kStopLeft;
+ case kDirectionRight:
+ return kStopRight;
case kDirectionMouse:
if (mouse.x < hero.x) {
return kStopLeft;
} else if (mouse.x > hero.x) {
return kStopRight;
- } else {
- goto defaultCase;
}
- case kDirectionLeft:
- return kStopLeft;
- case kDirectionRight:
- return kStopRight;
+ // fall-through here intentional
default: {
-defaultCase:
// Find the last horizontal direction on the path.
int i = path.size() - 1;
while (i >= 0 && path[i].x == hero.x) {
diff --git a/engines/drascula/animation.cpp b/engines/drascula/animation.cpp
index c4a8d3eb01..43799f7944 100644
--- a/engines/drascula/animation.cpp
+++ b/engines/drascula/animation.cpp
@@ -748,6 +748,19 @@ void DrasculaEngine::animation_14_2() {
loadPic(99, backSurface);
}
+void DrasculaEngine::asco() {
+ loadPic(roomDisk, drawSurface3);
+ loadPic(roomNumber, bgSurface, HALF_PAL);
+ black();
+ updateRoom();
+ updateScreen();
+ fadeFromBlack(0);
+ if (roomMusic != 0)
+ playMusic(roomMusic);
+ else
+ stopMusic();
+}
+
// The drunk tells us about Von Braun
void DrasculaEngine::animation_16_2() {
debug(4, "animation_16_2()");
@@ -763,8 +776,10 @@ void DrasculaEngine::animation_16_2() {
else
playMusic(32);
- if (getScan() != 0)
- goto asco;
+ if (getScan() != 0) {
+ asco();
+ return;
+ }
color_abc(kColorDarkGreen);
@@ -778,16 +793,20 @@ void DrasculaEngine::animation_16_2() {
centerText(_texthis[i], 180, 180);
updateScreen();
- if (getScan() != 0)
- goto asco;
+ if (getScan() != 0) {
+ asco();
+ return;
+ }
delay(3000);
if (i < 4) {
fadeToBlack(1);
- if (getScan() != 0)
- goto asco;
+ if (getScan() != 0) {
+ asco();
+ return;
+ }
clearRoom();
}
@@ -800,25 +819,17 @@ void DrasculaEngine::animation_16_2() {
copyBackground(0, 0, 0, l, 320, 200 - l, drawSurface3, screenSurface);
copyBackground(0, 200 - l, 0, 0, 320, l, bgSurface, screenSurface);
updateScreen();
- if (getScan() != 0)
- goto asco;
+ if (getScan() != 0) {
+ asco();
+ return;
+ }
}
pause(5);
fadeToBlack(2);
clearRoom();
-asco:
- loadPic(roomDisk, drawSurface3);
- loadPic(roomNumber, bgSurface, HALF_PAL);
- black();
- updateRoom();
- updateScreen();
- fadeFromBlack(0);
- if (roomMusic != 0)
- playMusic(roomMusic);
- else
- stopMusic();
+ asco();
}
void DrasculaEngine::animation_20_2() {
diff --git a/engines/drascula/converse.cpp b/engines/drascula/converse.cpp
index 6f028e6e12..7abbb3214b 100644
--- a/engines/drascula/converse.cpp
+++ b/engines/drascula/converse.cpp
@@ -197,7 +197,7 @@ void DrasculaEngine::converse(int index) {
// from 1(top) to 31
color_abc(kColorLightGreen);
- while (breakOut == 0) {
+ while (breakOut == 0 && !shouldQuit()) {
updateRoom();
if (musicStatus() == 0 && roomMusic != 0) {
diff --git a/engines/drascula/detection.cpp b/engines/drascula/detection.cpp
index 0969ad4131..3310ac0598 100644
--- a/engines/drascula/detection.cpp
+++ b/engines/drascula/detection.cpp
@@ -73,7 +73,7 @@ static const DrasculaGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformPC,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO0()
},
},
@@ -93,7 +93,7 @@ static const DrasculaGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformPC,
GF_PACKED,
- GUIO1(GUIO_NONE)
+ GUIO0()
},
},
@@ -110,7 +110,7 @@ static const DrasculaGameDescription gameDescriptions[] = {
Common::DE_DEU,
Common::kPlatformPC,
GF_PACKED,
- GUIO1(GUIO_NONE)
+ GUIO0()
},
},
@@ -127,7 +127,7 @@ static const DrasculaGameDescription gameDescriptions[] = {
Common::FR_FRA,
Common::kPlatformPC,
GF_PACKED,
- GUIO1(GUIO_NONE)
+ GUIO0()
},
},
@@ -140,7 +140,7 @@ static const DrasculaGameDescription gameDescriptions[] = {
Common::ES_ESP,
Common::kPlatformPC,
GF_PACKED,
- GUIO1(GUIO_NONE)
+ GUIO0()
},
},
@@ -153,7 +153,7 @@ static const DrasculaGameDescription gameDescriptions[] = {
Common::ES_ESP,
Common::kPlatformPC,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO0()
},
},
@@ -166,7 +166,7 @@ static const DrasculaGameDescription gameDescriptions[] = {
Common::DE_DEU,
Common::kPlatformPC,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO0()
},
},
@@ -179,7 +179,7 @@ static const DrasculaGameDescription gameDescriptions[] = {
Common::FR_FRA,
Common::kPlatformPC,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO0()
},
},
@@ -192,7 +192,7 @@ static const DrasculaGameDescription gameDescriptions[] = {
Common::IT_ITA,
Common::kPlatformPC,
GF_PACKED,
- GUIO1(GUIO_NONE)
+ GUIO0()
},
},
{
@@ -204,7 +204,7 @@ static const DrasculaGameDescription gameDescriptions[] = {
Common::IT_ITA,
Common::kPlatformPC,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO0()
},
},
@@ -221,7 +221,7 @@ static const DrasculaGameDescription gameDescriptions[] = {
Common::ES_ESP,
Common::kPlatformPC,
GF_PACKED,
- GUIO1(GUIO_NONE)
+ GUIO0()
},
},
@@ -238,7 +238,7 @@ static const DrasculaGameDescription gameDescriptions[] = {
Common::IT_ITA,
Common::kPlatformPC,
GF_PACKED,
- GUIO1(GUIO_NONE)
+ GUIO0()
},
},
@@ -255,7 +255,7 @@ static const DrasculaGameDescription gameDescriptions[] = {
Common::FR_FRA,
Common::kPlatformPC,
GF_PACKED,
- GUIO1(GUIO_NONE)
+ GUIO0()
},
},
diff --git a/engines/drascula/drascula.cpp b/engines/drascula/drascula.cpp
index b4f009eb44..1b3c4038f0 100644
--- a/engines/drascula/drascula.cpp
+++ b/engines/drascula/drascula.cpp
@@ -789,7 +789,7 @@ void DrasculaEngine::delay(int ms) {
_system->delayMillis(10);
updateEvents();
_system->updateScreen();
- } while (_system->getMillis() < end);
+ } while (_system->getMillis() < end && !shouldQuit());
}
void DrasculaEngine::pause(int duration) {
@@ -882,7 +882,7 @@ bool DrasculaEngine::loadDrasculaDat() {
in.read(buf, 8);
buf[8] = '\0';
- if (strcmp(buf, "DRASCULA")) {
+ if (strcmp(buf, "DRASCULA") != 0) {
Common::String errorMessage = "File 'drascula.dat' is corrupt. Get it from the ScummVM website";
GUIErrorMessage(errorMessage);
warning("%s", errorMessage.c_str());
diff --git a/engines/drascula/drascula.h b/engines/drascula/drascula.h
index 6f98c50fdc..2d1954e3ca 100644
--- a/engines/drascula/drascula.h
+++ b/engines/drascula/drascula.h
@@ -664,6 +664,7 @@ public:
void animation_12_2();
void animation_13_2();
void animation_14_2();
+ void asco();
void animation_16_2();
void animation_20_2();
void animation_23_2();
diff --git a/engines/drascula/graphics.cpp b/engines/drascula/graphics.cpp
index 9ea20e3e12..590561f0bd 100644
--- a/engines/drascula/graphics.cpp
+++ b/engines/drascula/graphics.cpp
@@ -154,6 +154,7 @@ void DrasculaEngine::showFrame(Common::SeekableReadStream *stream, bool firstFra
}
void DrasculaEngine::copyBackground(int xorg, int yorg, int xdes, int ydes, int width, int height, byte *src, byte *dest) {
+ debug(1, "DrasculaEngine::copyBackground(xorg:%d, yorg:%d, xdes:%d, ydes:%d width:%d height:%d, src, dest)", xorg, yorg, xdes, ydes, width,height);
dest += xdes + ydes * 320;
src += xorg + yorg * 320;
/* Unoptimized code
@@ -361,7 +362,7 @@ void DrasculaEngine::centerText(const char *message, int textX, int textY) {
curWord = strtok(msg, " ");
while (curWord != NULL) {
// Check if the word and the current line fit on screen
- if (strlen(tmpMessageLine) > 0)
+ if (tmpMessageLine[0] != '\0')
strcat(tmpMessageLine, " ");
strcat(tmpMessageLine, curWord);
if (textFitsCentered(tmpMessageLine, textX)) {
@@ -643,7 +644,7 @@ void DrasculaEngine::waitFrameSSN() {
}
bool DrasculaEngine::animate(const char *animationFile, int FPS) {
- int NFrames = 1;
+ int NFrames;
int cnt = 2;
Common::SeekableReadStream *stream = _archives.open(animationFile);
diff --git a/engines/drascula/interface.cpp b/engines/drascula/interface.cpp
index e3a97087c0..c08bcea01f 100644
--- a/engines/drascula/interface.cpp
+++ b/engines/drascula/interface.cpp
@@ -100,9 +100,18 @@ bool DrasculaEngine::confirmExit() {
key = getScan();
if (key != 0)
break;
+
+ // This gives a better feedback to the user when he is asked to
+ // confirm whether he wants to quit. It now still updates the room and
+ // shows mouse cursor movement. Hopefully it will work in all
+ // locations of the game.
+ updateRoom();
+ color_abc(kColorRed);
+ centerText(_textsys[1], 160, 87);
+ updateScreen();
}
- if (key == Common::KEYCODE_ESCAPE) {
+ if (key == Common::KEYCODE_ESCAPE || shouldQuit()) {
stopMusic();
return false;
}
@@ -159,7 +168,7 @@ void DrasculaEngine::enterName() {
key = getScan();
if (key != 0) {
- if (key >= 0 && key <= 0xFF && isalpha(static_cast<unsigned char>(key)))
+ if (key >= 0 && key <= 0xFF && isAlpha(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/saveload.cpp b/engines/drascula/saveload.cpp
index c8622f3c92..35e3821dc4 100644
--- a/engines/drascula/saveload.cpp
+++ b/engines/drascula/saveload.cpp
@@ -123,7 +123,7 @@ bool DrasculaEngine::saveLoadScreen() {
if (mouseX > 115 && mouseY > y + (9 * n) && mouseX < 115 + 175 && mouseY < y + 10 + (9 * n)) {
strcpy(select, _saveNames[n]);
- if (strcmp(select, "*"))
+ if (strcmp(select, "*") != 0)
selectionMade = 1;
else {
enterName();
diff --git a/engines/drascula/sound.cpp b/engines/drascula/sound.cpp
index 413a631118..112f6fd06c 100644
--- a/engines/drascula/sound.cpp
+++ b/engines/drascula/sound.cpp
@@ -26,6 +26,7 @@
#include "common/config-manager.h"
#include "common/textconsole.h"
+#include "common/substream.h"
#include "backends/audiocd/audiocd.h"
@@ -78,6 +79,8 @@ void DrasculaEngine::volumeControls() {
;
if (rightMouseButton == 1) {
+ // Clear this to avoid going straight to the inventory
+ rightMouseButton = 0;
delay(100);
break;
}
@@ -163,29 +166,28 @@ void DrasculaEngine::MusicFadeout() {
void DrasculaEngine::playFile(const char *fname) {
Common::SeekableReadStream *stream = _archives.open(fname);
if (stream) {
- int soundSize = stream->size();
- byte *soundData = (byte *)malloc(soundSize);
+ int startOffset = 0;
+ int soundSize = stream->size() - startOffset;
- if (!(!strcmp(fname, "3.als") && soundSize == 145166 && _lang != kSpanish)) {
- stream->seek(32);
- } else {
+ if (!strcmp(fname, "3.als") && soundSize == 145166 && _lang != kSpanish) {
// WORKAROUND: File 3.als with English speech files has a big silence at
// its beginning and end. We seek past the silence at the beginning,
// and ignore the silence at the end
// Fixes bug #2111815 - "DRASCULA: Voice delayed"
- stream->seek(73959, SEEK_SET);
- soundSize = 117158 - 73959;
+ startOffset = 73959;
+ soundSize = soundSize - startOffset - 26306;
}
- stream->read(soundData, soundSize);
- delete stream;
-
- _subtitlesDisabled = !ConfMan.getBool("subtitles");
- if (ConfMan.getBool("speech_mute"))
- memset(soundData, 0x80, soundSize); // Mute speech but keep the pause
+ Common::SeekableReadStream *subStream = new Common::SeekableSubReadStream(
+ stream, startOffset, startOffset + soundSize, DisposeAfterUse::YES);
+ if (!subStream) {
+ warning("playFile: Out of memory");
+ delete stream;
+ return;
+ }
- Audio::AudioStream *sound = Audio::makeRawStream(soundData, soundSize - 64,
- 11025, Audio::FLAG_UNSIGNED);
+ Audio::AudioStream *sound = Audio::makeRawStream(subStream, 11025,
+ Audio::FLAG_UNSIGNED);
_mixer->playStream(Audio::Mixer::kSpeechSoundType, &_soundHandle, sound);
} else
warning("playFile: Could not open %s", fname);
diff --git a/engines/drascula/talk.cpp b/engines/drascula/talk.cpp
index 6d1509fe3c..a326852e96 100644
--- a/engines/drascula/talk.cpp
+++ b/engines/drascula/talk.cpp
@@ -34,6 +34,11 @@ void DrasculaEngine::talkInit(const char *filename) {
}
bool DrasculaEngine::isTalkFinished() {
+ if (shouldQuit()) {
+ stopSound();
+ return true;
+ }
+
if (getScan() != 0)
stopSound();
if (soundIsActive())
@@ -367,6 +372,7 @@ void DrasculaEngine::talk(int index) {
}
void DrasculaEngine::talk(const char *said, const char *filename) {
+ debug(1, "DrasculaEngine::talk(said:\"%s\", filename:\"%s\")", said, filename);
int talkOffset = 0;
if (currentChapter != 2)
talkOffset = 1;
@@ -409,8 +415,8 @@ void DrasculaEngine::talk(const char *said, const char *filename) {
if (currentChapter == 2)
copyBackground(curX, curY, OBJWIDTH + 1, 0, curWidth, talkHeight - 1, screenSurface, drawSurface3);
else
- copyBackground(curX, curY, OBJWIDTH + 1, 0, (int)(((float)curWidth / 100) * factor_red[curY + curHeight]),
- (int)(((float)(talkHeight - 1) / 100) * factor_red[curY + curHeight]),
+ copyBackground(curX, curY, OBJWIDTH + 1, 0, (int)(((float)curWidth / 100) * factor_red[MIN(201, curY + curHeight)]),
+ (int)(((float)(talkHeight - 1) / 100) * factor_red[MIN(201, curY + curHeight)]),
screenSurface, drawSurface3);
moveCharacters();
@@ -419,8 +425,8 @@ void DrasculaEngine::talk(const char *said, const char *filename) {
if (!strcmp(menuBackground, "99.alg") || !strcmp(menuBackground, "994.alg"))
copyBackground(OBJWIDTH + 1, 0, curX, curY, curWidth, talkHeight - 1, drawSurface3, screenSurface);
} else {
- copyBackground(OBJWIDTH + 1, 0, curX, curY, (int)(((float)curWidth / 100) * factor_red[curY + curHeight]),
- (int)(((float)(talkHeight - 1) / 100) * factor_red[curY + curHeight]),
+ copyBackground(OBJWIDTH + 1, 0, curX, curY, (int)(((float)curWidth / 100) * factor_red[MIN(201, curY + curHeight)]),
+ (int)(((float)(talkHeight - 1) / 100) * factor_red[MIN(201, curY + curHeight)]),
drawSurface3, screenSurface);
}
@@ -429,8 +435,8 @@ void DrasculaEngine::talk(const char *said, const char *filename) {
copyRect(x_talk_izq[face], y_mask_talk, curX + 8, curY - 1, talkWidth, talkHeight,
extraSurface, screenSurface);
else
- reduce_hare_chico(x_talk_izq[face], y_mask_talk, curX + (int)((8.0f / 100) * factor_red[curY + curHeight]),
- curY, talkWidth, talkHeight, factor_red[curY + curHeight],
+ reduce_hare_chico(x_talk_izq[face], y_mask_talk, curX + (int)((8.0f / 100) * factor_red[MIN(201, curY + curHeight)]),
+ curY, talkWidth, talkHeight, factor_red[MIN(201, curY + curHeight)],
extraSurface, screenSurface);
updateRefresh();
@@ -439,8 +445,8 @@ void DrasculaEngine::talk(const char *said, const char *filename) {
copyRect(x_talk_dch[face], y_mask_talk, curX + 12, curY, talkWidth, talkHeight,
extraSurface, screenSurface);
else
- reduce_hare_chico(x_talk_dch[face], y_mask_talk, curX + (int)((12.0f / 100) * factor_red[curY + curHeight]),
- curY, talkWidth, talkHeight, factor_red[curY + curHeight], extraSurface, screenSurface);
+ reduce_hare_chico(x_talk_dch[face], y_mask_talk, curX + (int)((12.0f / 100) * factor_red[MIN(201, curY + curHeight)]),
+ curY, talkWidth, talkHeight, factor_red[MIN(201, curY + curHeight)], extraSurface, screenSurface);
updateRefresh();
} else if (trackProtagonist == 2) {
if (currentChapter == 2)
@@ -448,8 +454,8 @@ void DrasculaEngine::talk(const char *said, const char *filename) {
frontSurface, screenSurface);
else
reduce_hare_chico(x_talk_izq[face], y_mask_talk,
- talkOffset + curX + (int)((12.0f / 100) * factor_red[curY + curHeight]),
- curY, talkWidth, talkHeight, factor_red[curY + curHeight],
+ talkOffset + curX + (int)((12.0f / 100) * factor_red[MIN(201, curY + curHeight)]),
+ curY, talkWidth, talkHeight, factor_red[MIN(201, curY + curHeight)],
frontSurface, screenSurface);
updateRefresh();
} else if (trackProtagonist == 3) {
@@ -458,8 +464,8 @@ void DrasculaEngine::talk(const char *said, const char *filename) {
frontSurface, screenSurface);
else
reduce_hare_chico(x_talk_dch[face], y_mask_talk,
- talkOffset + curX + (int)((8.0f / 100) * factor_red[curY + curHeight]),
- curY, talkWidth,talkHeight, factor_red[curY + curHeight],
+ talkOffset + curX + (int)((8.0f / 100) * factor_red[MIN(201, curY + curHeight)]),
+ curY, talkWidth,talkHeight, factor_red[MIN(201, curY + curHeight)],
frontSurface, screenSurface);
updateRefresh();
}
diff --git a/engines/dreamweb/README b/engines/dreamweb/README
deleted file mode 100644
index d184613249..0000000000
--- a/engines/dreamweb/README
+++ /dev/null
@@ -1,12 +0,0 @@
-
-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/backdrop.cpp b/engines/dreamweb/backdrop.cpp
index ffcad5b6bf..1db2663624 100644
--- a/engines/dreamweb/backdrop.cpp
+++ b/engines/dreamweb/backdrop.cpp
@@ -22,24 +22,20 @@
#include "dreamweb/dreamweb.h"
-namespace DreamGen {
-
-void DreamGenContext::doblocks() {
- uint16 dstOffset = data.word(kMapady) * 320 + data.word(kMapadx);
- uint16 mapOffset = kMap + data.byte(kMapy) * kMapwidth + data.byte(kMapx);
- ds = data.word(kMapdata);
- const uint8 *mapData = ds.ptr(mapOffset, 0);
- ds = data.word(kBackdrop);
- const uint8 *blocks = ds.ptr(kBlocks, 0);
- es = data.word(kWorkspace);
- uint8 *dstBuffer = es.ptr(dstOffset, 0);
+namespace DreamWeb {
+
+void DreamWebEngine::doBlocks() {
+ uint16 dstOffset = _mapAdY * 320 + _mapAdX;
+ uint16 mapOffset = _mapY * kMapWidth + _mapX;
+ const uint8 *mapData = _mapData + mapOffset;
+ uint8 *dstBuffer = workspace() + dstOffset;
for (size_t i = 0; i < 10; ++i) {
for (size_t j = 0; j < 11; ++j) {
uint16 blockType = mapData[j];
if (blockType != 0) {
uint8 *dst = dstBuffer + i * 320 * 16 + j * 16;
- const uint8 *block = blocks + blockType * 256;
+ const uint8 *block = _backdropBlocks + blockType * 256;
for (size_t k = 0; k < 4; ++k) {
memcpy(dst, block, 16);
block += 16;
@@ -52,7 +48,6 @@ void DreamGenContext::doblocks() {
dst += 320;
}
dst += 4;
- ax = 0x0dfdf;
memset(dst, 0xdf, 16);
dst += 320;
memset(dst, 0xdf, 16);
@@ -62,272 +57,223 @@ void DreamGenContext::doblocks() {
memset(dst, 0xdf, 16);
}
}
- mapData += kMapwidth;
+ mapData += kMapWidth;
}
}
-uint8 DreamGenContext::getxad(const uint8 *setData, uint8 *result) {
+uint8 DreamWebEngine::getXAd(const uint8 *setData, uint8 *result) {
uint8 v0 = setData[0];
uint8 v1 = setData[1];
uint8 v2 = setData[2];
if (v0 != 0)
return 0;
- if (v1 < data.byte(kMapx))
+ if (v1 < _mapX)
return 0;
- v1 -= data.byte(kMapx);
+ v1 -= _mapX;
if (v1 >= 11)
return 0;
*result = (v1 << 4) | v2;
return 1;
}
-uint8 DreamGenContext::getyad(const uint8 *setData, uint8 *result) {
+uint8 DreamWebEngine::getYAd(const uint8 *setData, uint8 *result) {
uint8 v0 = setData[3];
uint8 v1 = setData[4];
- if (v0 < data.byte(kMapy))
+ if (v0 < _mapY)
return 0;
- v0 -= data.byte(kMapy);
+ v0 -= _mapY;
if (v0 >= 10)
return 0;
*result = (v0 << 4) | v1;
return 1;
}
-void DreamGenContext::getmapad() {
- ch = getmapad((const uint8 *)es.ptr(si, 5));
-}
-
-uint8 DreamGenContext::getmapad(const uint8 *setData) {
+uint8 DreamWebEngine::getMapAd(const uint8 *setData, uint16 *x, uint16 *y) {
uint8 xad, yad;
- if (getxad(setData, &xad) == 0)
+ if (getXAd(setData, &xad) == 0)
return 0;
- data.word(kObjectx) = xad;
- if (getyad(setData, &yad) == 0)
+ *x = xad;
+ if (getYAd(setData, &yad) == 0)
return 0;
- data.word(kObjecty) = yad;
+ *y = yad;
return 1;
}
-void DreamGenContext::calcfrframe() {
- uint8 width, height;
- calcfrframe(&width, &height);
- cl = width;
- ch = height;
-}
-
-void DreamGenContext::calcfrframe(uint8* width, uint8* height) {
- const Frame *frame = (const Frame *)segRef(data.word(kFrsegment)).ptr(data.word(kCurrentframe) * sizeof(Frame), sizeof(Frame));
- data.word(kSavesource) = data.word(kFramesad) + frame->ptr();
- data.byte(kSavesize+0) = frame->width;
- data.byte(kSavesize+1) = frame->height;
- data.word(kOffsetx) = frame->x;
- data.word(kOffsety) = frame->y;
- *width = frame->width;
- *height = frame->height;
-}
+void DreamWebEngine::calcFrFrame(const Frame &frame, uint8 *width, uint8 *height, uint16 x, uint16 y, ObjPos *objPos) {
+ *width = frame.width;
+ *height = frame.height;
-void DreamGenContext::finalframe() {
- uint16 x, y;
- finalframe(&x, &y);
- di = x;
- bx = y;
+ objPos->xMin = (x + frame.x) & 0xff;
+ objPos->yMin = (y + frame.y) & 0xff;
+ objPos->xMax = objPos->xMin + frame.width;
+ objPos->yMax = objPos->yMin + frame.height;
}
-void DreamGenContext::finalframe(uint16 *x, uint16 *y) {
- data.byte(kSavex) = (data.word(kObjectx) + data.word(kOffsetx)) & 0xff;
- data.byte(kSavey) = (data.word(kObjecty) + data.word(kOffsety)) & 0xff;
- *x = data.word(kObjectx);
- *y = data.word(kObjecty);
+void DreamWebEngine::makeBackOb(SetObject *objData, uint16 x, uint16 y) {
+ if (_vars._newObs == 0)
+ return;
+ uint8 priority = objData->priority;
+ uint8 type = objData->type;
+ Sprite *sprite = makeSprite(x, y, false, &_setFrames);
+
+ sprite->_objData = objData;
+ if (priority == 255)
+ priority = 0;
+ sprite->priority = priority;
+ sprite->type = type;
+ sprite->delay = 0;
+ sprite->animFrame = 0;
}
-void DreamGenContext::showallobs() {
- data.word(kListpos) = kSetlist;
- memset(segRef(data.word(kBuffers)).ptr(kSetlist, 0), 0xff, 128 * 5);
- data.word(kFrsegment) = data.word(kSetframes);
- data.word(kDataad) = kFramedata;
- data.word(kFramesad) = kFrames;
+void DreamWebEngine::showAllObs() {
+ _setList.clear();
- const Frame *frames = (const Frame *)segRef(data.word(kFrsegment)).ptr(0, 0);
- SetObject *setEntries = (SetObject *)segRef(data.word(kSetdat)).ptr(0, 128 * sizeof(SetObject));
+ const GraphicsFile &frameBase = _setFrames;
for (size_t i = 0; i < 128; ++i) {
- SetObject *setEntry = setEntries + i;
- if (getmapad(setEntry->mapad) == 0)
+ SetObject *setEntry = &_setDat[i];
+ uint16 x, y;
+ if (getMapAd(setEntry->mapad, &x, &y) == 0)
continue;
- uint8 currentFrame = setEntry->b18[0];
- data.word(kCurrentframe) = currentFrame;
+ uint8 currentFrame = setEntry->frames[0];
if (currentFrame == 0xff)
continue;
- calcfrframe();
- uint16 x, y;
- finalframe(&x, &y);
- setEntry->index = setEntry->b18[0];
+ uint8 width, height;
+ ObjPos objPos;
+ calcFrFrame(frameBase._frames[currentFrame], &width, &height, x, y, &objPos);
+ setEntry->index = setEntry->frames[0];
if ((setEntry->type == 0) && (setEntry->priority != 5) && (setEntry->priority != 6)) {
- x += data.word(kMapadx);
- y += data.word(kMapady);
- showframe(frames, x, y, data.word(kCurrentframe), 0);
+ x += _mapAdX;
+ y += _mapAdY;
+ showFrame(frameBase, x, y, currentFrame, 0);
} else
- makebackob(setEntry);
-
- ObjPos *objPos = (ObjPos *)segRef(data.word(kBuffers)).ptr(data.word(kListpos), sizeof(ObjPos));
- objPos->xMin = data.byte(kSavex);
- objPos->yMin = data.byte(kSavey);
- objPos->xMax = data.byte(kSavex) + data.byte(kSavesize+0);
- objPos->yMax = data.byte(kSavey) + data.byte(kSavesize+1);
- objPos->index = i;
- data.word(kListpos) += sizeof(ObjPos);
- }
-}
+ makeBackOb(setEntry, x, y);
-void DreamGenContext::getdimension()
-{
- uint8 mapXstart, mapYstart;
- uint8 mapXsize, mapYsize;
- getdimension(&mapXstart, &mapYstart, &mapXsize, &mapYsize);
- cl = mapXstart;
- ch = mapYstart;
- dl = mapXsize;
- dh = mapYsize;
+ objPos.index = i;
+ _setList.push_back(objPos);
+ }
}
-bool DreamGenContext::addalong(const uint8 *mapFlags) {
+static bool addAlong(const MapFlag *mapFlags) {
for (size_t i = 0; i < 11; ++i) {
- if (mapFlags[3 * i] != 0)
+ if (mapFlags[i]._flag != 0)
return true;
}
return false;
}
-bool DreamGenContext::addlength(const uint8 *mapFlags) {
+static bool addLength(const MapFlag *mapFlags) {
for (size_t i = 0; i < 10; ++i) {
- if (mapFlags[3 * 11 * i] != 0)
+ if (mapFlags[11 * i]._flag != 0)
return true;
}
return false;
}
-void DreamGenContext::getdimension(uint8 *mapXstart, uint8 *mapYstart, uint8 *mapXsize, uint8 *mapYsize) {
- const uint8 *mapFlags = segRef(data.word(kBuffers)).ptr(kMapflags, 0);
-
+void DreamWebEngine::getDimension(uint8 *mapXstart, uint8 *mapYstart, uint8 *mapXsize, uint8 *mapYsize) {
uint8 yStart = 0;
- while (! addalong(mapFlags + 3 * 11 * yStart))
+ while (! addAlong(_mapFlags + 11 * yStart))
++yStart;
uint8 xStart = 0;
- while (! addlength(mapFlags + 3 * xStart))
+ while (! addLength(_mapFlags + xStart))
++xStart;
uint8 yEnd = 10;
- while (! addalong(mapFlags + 3 * 11 * (yEnd - 1)))
+ while (! addAlong(_mapFlags + 11 * (yEnd - 1)))
--yEnd;
uint8 xEnd = 11;
- while (! addlength(mapFlags + 3 * (xEnd - 1)))
+ while (! addLength(_mapFlags + (xEnd - 1)))
--xEnd;
*mapXstart = xStart;
*mapYstart = yStart;
*mapXsize = xEnd - xStart;
*mapYsize = yEnd - yStart;
- data.word(kMapxstart) = xStart << 4;
- data.word(kMapystart) = yStart << 4;
- data.byte(kMapxsize) = *mapXsize << 4;
- data.byte(kMapysize) = *mapYsize << 4;
+ _mapXStart = xStart << 4;
+ _mapYStart = yStart << 4;
+ _mapXSize = *mapXsize << 4;
+ _mapYSize = *mapYsize << 4;
}
-void DreamGenContext::calcmapad() {
+void DreamWebEngine::calcMapAd() {
uint8 mapXstart, mapYstart;
uint8 mapXsize, mapYsize;
- getdimension(&mapXstart, &mapYstart, &mapXsize, &mapYsize);
- data.word(kMapadx) = data.word(kMapoffsetx) - 8 * (mapXsize + 2 * mapXstart - 11);
- data.word(kMapady) = data.word(kMapoffsety) - 8 * (mapYsize + 2 * mapYstart - 10);
+ getDimension(&mapXstart, &mapYstart, &mapXsize, &mapYsize);
+ _mapAdX = _mapOffsetX - 8 * (mapXsize + 2 * mapXstart - 11);
+ _mapAdY = _mapOffsetY - 8 * (mapYsize + 2 * mapYstart - 10);
}
-void DreamGenContext::showallfree() {
- data.word(kListpos) = kFreelist;
- ObjPos *listPos = (ObjPos *)segRef(data.word(kBuffers)).ptr(kFreelist, 80 * sizeof(ObjPos));
- memset(listPos, 0xff, 80 * sizeof(ObjPos));
-
- data.word(kFrsegment) = data.word(kFreeframes);
- data.word(kDataad) = kFrframedata;
- data.word(kFramesad) = kFrframes;
- data.byte(kCurrentfree) = 0;
- const DynObject *freeObjects = (const DynObject *)segRef(data.word(kFreedat)).ptr(0, 0);
- for(size_t i = 0; i < 80; ++i) {
- uint8 mapad = getmapad(freeObjects[i].mapad);
- if (mapad != 0) {
- data.word(kCurrentframe) = 3 * data.byte(kCurrentfree);
+void DreamWebEngine::showAllFree() {
+ const unsigned int count = 80;
+
+ _freeList.clear();
+
+ const DynObject *freeObjects = _freeDat;
+ const GraphicsFile &frameBase = _freeFrames;
+ for (size_t i = 0; i < count; ++i) {
+ uint16 x, y;
+ uint8 mapAd = getMapAd(freeObjects[i].mapad, &x, &y);
+ if (mapAd != 0) {
uint8 width, height;
- calcfrframe(&width, &height);
- uint16 x, y;
- finalframe(&x, &y);
+ ObjPos objPos;
+ uint16 currentFrame = 3 * i;
+ calcFrFrame(frameBase._frames[currentFrame], &width, &height, x, y, &objPos);
if ((width != 0) || (height != 0)) {
- x += data.word(kMapadx);
- y += data.word(kMapady);
- showframe((Frame *)segRef(data.word(kFrsegment)).ptr(0, 0), x, y, data.word(kCurrentframe) & 0xff, 0);
- ObjPos *objPos = (ObjPos *)segRef(data.word(kBuffers)).ptr(data.word(kListpos), sizeof(ObjPos));
- objPos->xMin = data.byte(kSavex);
- objPos->yMin = data.byte(kSavey);
- objPos->xMax = data.byte(kSavex) + data.byte(kSavesize+0);
- objPos->yMax = data.byte(kSavey) + data.byte(kSavesize+1);
- objPos->index = i;
- data.word(kListpos) += sizeof(ObjPos);
+ x += _mapAdX;
+ y += _mapAdY;
+ assert(currentFrame < 256);
+ showFrame(frameBase, x, y, currentFrame, 0);
+ objPos.index = i;
+ _freeList.push_back(objPos);
}
}
-
- ++data.byte(kCurrentfree);
}
}
-void DreamGenContext::drawflags() {
- uint8 *mapFlags = segRef(data.word(kBuffers)).ptr(kMapflags, 0);
- const uint8 *mapData = segRef(data.word(kMapdata)).ptr(kMap + data.byte(kMapy) * kMapwidth + data.byte(kMapx), 0);
- const uint8 *backdropFlags = segRef(data.word(kBackdrop)).ptr(kFlags, 0);
+void DreamWebEngine::drawFlags() {
+ MapFlag *mapFlag = _mapFlags;
+ uint16 mapOffset = _mapY * kMapWidth + _mapX;
+ const uint8 *mapData = _mapData + mapOffset;
for (size_t i = 0; i < 10; ++i) {
for (size_t j = 0; j < 11; ++j) {
- uint8 tile = mapData[i * kMapwidth + j];
- mapFlags[0] = backdropFlags[2 * tile + 0];
- mapFlags[1] = backdropFlags[2 * tile + 1];
- mapFlags[2] = tile;
- mapFlags += 3;
+ uint8 tile = mapData[i * kMapWidth + j];
+ mapFlag->_flag = _backdropFlags[tile]._flag;
+ mapFlag->_flagEx = _backdropFlags[tile]._flagEx;
+ mapFlag->_type = tile;
+ mapFlag++;
}
}
}
-void DreamGenContext::showallex() {
- data.word(kListpos) = kExlist;
- memset(segRef(data.word(kBuffers)).ptr(kExlist, 100 * 5), 0xff, 100 * 5);
+void DreamWebEngine::showAllEx() {
+ const unsigned int count = 100;
+
+ _exList.clear();
- data.word(kFrsegment) = data.word(kExtras);
- data.word(kDataad) = kExframedata;
- data.word(kFramesad) = kExframes;
- data.byte(kCurrentex) = 0;
- DynObject *objects = (DynObject *)segRef(data.word(kExtras)).ptr(kExdata, sizeof(DynObject));
- for (size_t i = 0; i < 100; ++i, ++data.byte(kCurrentex)) {
+ DynObject *objects = _exData;
+ const GraphicsFile &frameBase = _exFrames;
+ for (size_t i = 0; i < count; ++i) {
DynObject *object = objects + i;
if (object->mapad[0] == 0xff)
continue;
- if (object->currentLocation != data.byte(kReallocation))
+ if (object->currentLocation != _realLocation)
continue;
- if (getmapad(object->mapad) == 0)
+ uint16 x, y;
+ if (getMapAd(object->mapad, &x, &y) == 0)
continue;
- data.word(kCurrentframe) = 3 * data.byte(kCurrentex);
uint8 width, height;
- calcfrframe(&width, &height);
- uint16 x, y;
- finalframe(&x, &y);
+ ObjPos objPos;
+ uint16 currentFrame = 3 * i;
+ calcFrFrame(frameBase._frames[currentFrame], &width, &height, x, y, &objPos);
if ((width != 0) || (height != 0)) {
- showframe((Frame *)segRef(data.word(kFrsegment)).ptr(0, 0), x + data.word(kMapadx), y + data.word(kMapady), data.word(kCurrentframe) & 0xff, 0);
- ObjPos *objPos = (ObjPos *)segRef(data.word(kBuffers)).ptr(data.word(kListpos), sizeof(ObjPos));
- objPos->xMin = data.byte(kSavex);
- objPos->yMin = data.byte(kSavey);
- objPos->xMax = data.byte(kSavesize + 0) + data.byte(kSavex);
- objPos->yMax = data.byte(kSavesize + 1) + data.byte(kSavey);
- objPos->index = i;
- data.word(kListpos) += sizeof(ObjPos);
+ assert(currentFrame < 256);
+ showFrame(frameBase, x + _mapAdX, y + _mapAdY, currentFrame, 0);
+ objPos.index = i;
+ _exList.push_back(objPos);
}
}
}
-} /*namespace dreamgen */
-
+} // End of namespace DreamWeb
diff --git a/engines/dreamweb/detection.cpp b/engines/dreamweb/detection.cpp
index a3f311c304..9d3797db03 100644
--- a/engines/dreamweb/detection.cpp
+++ b/engines/dreamweb/detection.cpp
@@ -25,7 +25,12 @@
#include "common/algorithm.h"
#include "common/system.h"
+#include "engines/advancedDetector.h"
+
+#include "graphics/thumbnail.h"
+
#include "dreamweb/dreamweb.h"
+#include "dreamweb/structs.h"
static const PlainGameDescriptor dreamWebGames[] = {
{ "dreamweb", "DreamWeb" },
@@ -56,6 +61,7 @@ public:
virtual SaveStateList listSaves(const char *target) const;
virtual int getMaximumSaveSlot() const;
virtual void removeSaveState(const char *target, int slot) const;
+ SaveStateDescriptor querySaveMetaInfos(const char *target, int slot) const;
};
bool DreamWebMetaEngine::hasFeature(MetaEngineFeature f) const {
@@ -63,6 +69,10 @@ bool DreamWebMetaEngine::hasFeature(MetaEngineFeature f) const {
case kSupportsListSaves:
case kSupportsLoadingDuringStartup:
case kSupportsDeleteSave:
+ case kSavesSupportMetaInfo:
+ case kSavesSupportThumbnail:
+ case kSavesSupportCreationDate:
+ case kSavesSupportPlayTime:
return true;
default:
return false;
@@ -95,7 +105,7 @@ SaveStateList DreamWebMetaEngine::listSaves(const char *target) const {
Common::sort(files.begin(), files.end());
SaveStateList saveList;
- for(uint i = 0; i < files.size(); ++i) {
+ for (uint i = 0; i < files.size(); ++i) {
const Common::String &file = files[i];
Common::InSaveFile *stream = saveFileMan->openForLoading(file);
if (!stream)
@@ -116,6 +126,71 @@ SaveStateList DreamWebMetaEngine::listSaves(const char *target) const {
int DreamWebMetaEngine::getMaximumSaveSlot() const { return 99; }
void DreamWebMetaEngine::removeSaveState(const char *target, int slot) const {
+ Common::String fileName = Common::String::format("DREAMWEB.D%02d", slot);
+ g_system->getSavefileManager()->removeSavefile(fileName);
+}
+
+SaveStateDescriptor DreamWebMetaEngine::querySaveMetaInfos(const char *target, int slot) const {
+ Common::String filename = Common::String::format("DREAMWEB.D%02d", slot);
+ Common::InSaveFile *in = g_system->getSavefileManager()->openForLoading(filename.c_str());
+
+ if (in) {
+ DreamWeb::FileHeader header;
+ in->read((uint8 *)&header, sizeof(DreamWeb::FileHeader));
+
+ Common::String saveName;
+ byte descSize = header.len(0);
+ byte i;
+
+ for (i = 0; i < descSize; i++)
+ saveName += (char)in->readByte();
+
+ SaveStateDescriptor desc(slot, saveName);
+ desc.setDeletableFlag(true);
+ desc.setWriteProtectedFlag(false);
+
+ // Check if there is a ScummVM data block
+ if (header.len(6) == SCUMMVM_BLOCK_MAGIC_SIZE) {
+ // Skip the game data
+ for (i = 1; i <= 5; i++)
+ in->skip(header.len(i));
+
+ uint32 tag = in->readUint32BE();
+ if (tag != SCUMMVM_HEADER) {
+ warning("ScummVM data block found, but the block header is incorrect - skipping");
+ delete in;
+ return desc;
+ }
+
+ byte version = in->readByte();
+ if (version > SAVEGAME_VERSION) {
+ warning("ScummVM data block found, but it has been saved with a newer version of ScummVM - skipping");
+ delete in;
+ return desc;
+ }
+
+ uint32 saveDate = in->readUint32LE();
+ uint32 saveTime = in->readUint32LE();
+ uint32 playTime = in->readUint32LE();
+ Graphics::Surface *thumbnail = Graphics::loadThumbnail(*in);
+
+ int day = (saveDate >> 24) & 0xFF;
+ int month = (saveDate >> 16) & 0xFF;
+ int year = saveDate & 0xFFFF;
+ int hour = (saveTime >> 16) & 0xFF;
+ int minutes = (saveTime >> 8) & 0xFF;
+
+ desc.setSaveDate(year, month, day);
+ desc.setSaveTime(hour, minutes);
+ desc.setPlayTime(playTime * 1000);
+ desc.setThumbnail(thumbnail);
+ }
+
+ delete in;
+ return desc;
+ }
+
+ return SaveStateDescriptor();
}
#if PLUGIN_ENABLED_DYNAMIC(DREAMWEB)
@@ -142,4 +217,12 @@ bool DreamWebEngine::canSaveGameStateCurrently() {
return false;
}
+Common::Language DreamWebEngine::getLanguage() const {
+ return _gameDescription->desc.language;
+}
+
+bool DreamWebEngine::isCD() {
+ return _gameDescription->desc.flags & ADGF_CD;
+}
+
} // End of namespace DreamWeb
diff --git a/engines/dreamweb/detection_tables.h b/engines/dreamweb/detection_tables.h
index 0902236916..216e6715dc 100644
--- a/engines/dreamweb/detection_tables.h
+++ b/engines/dreamweb/detection_tables.h
@@ -25,6 +25,10 @@
namespace DreamWeb {
+struct DreamWebGameDescription {
+ ADGameDescription desc;
+};
+
static const DreamWebGameDescription gameDescriptions[] = {
// International floppy release
{
@@ -39,7 +43,7 @@ static const DreamWebGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformPC,
ADGF_UNSTABLE,
- GUIO1(GUIO_NONE)
+ GUIO0()
},
},
@@ -56,7 +60,7 @@ static const DreamWebGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformPC,
ADGF_CD | ADGF_UNSTABLE,
- GUIO1(GUIO_NONE)
+ GUIO0()
},
},
@@ -73,7 +77,7 @@ static const DreamWebGameDescription gameDescriptions[] = {
Common::EN_USA,
Common::kPlatformPC,
ADGF_CD,
- GUIO1(GUIO_NONE)
+ GUIO0()
},
},
@@ -90,7 +94,7 @@ static const DreamWebGameDescription gameDescriptions[] = {
Common::FR_FRA,
Common::kPlatformPC,
ADGF_CD | ADGF_UNSTABLE,
- GUIO1(GUIO_NONE)
+ GUIO0()
},
},
@@ -107,7 +111,7 @@ static const DreamWebGameDescription gameDescriptions[] = {
Common::DE_DEU,
Common::kPlatformPC,
ADGF_UNSTABLE,
- GUIO1(GUIO_NONE)
+ GUIO0()
},
},
@@ -124,7 +128,7 @@ static const DreamWebGameDescription gameDescriptions[] = {
Common::DE_DEU,
Common::kPlatformPC,
ADGF_CD | ADGF_UNSTABLE,
- GUIO1(GUIO_NONE)
+ GUIO0()
},
},
@@ -141,7 +145,7 @@ static const DreamWebGameDescription gameDescriptions[] = {
Common::ES_ESP,
Common::kPlatformPC,
ADGF_UNSTABLE,
- GUIO1(GUIO_NONE)
+ GUIO0()
},
},
@@ -158,7 +162,7 @@ static const DreamWebGameDescription gameDescriptions[] = {
Common::ES_ESP,
Common::kPlatformPC,
ADGF_CD | ADGF_UNSTABLE,
- GUIO1(GUIO_NONE)
+ GUIO0()
},
},
@@ -175,7 +179,7 @@ static const DreamWebGameDescription gameDescriptions[] = {
Common::IT_ITA,
Common::kPlatformPC,
ADGF_UNSTABLE,
- GUIO1(GUIO_NONE)
+ GUIO0()
},
},
diff --git a/engines/dreamweb/dreamgen.cpp b/engines/dreamweb/dreamgen.cpp
deleted file mode 100644
index 8f4b4cea21..0000000000
--- a/engines/dreamweb/dreamgen.cpp
+++ /dev/null
@@ -1,17268 +0,0 @@
-/* PLEASE DO NOT MODIFY THIS FILE. ALL CHANGES WILL BE LOST! LOOK FOR README FOR DETAILS */
-
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-
-
-#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::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::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::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 = offset_rainlocations;
-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::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::reelsonscreen() {
- STACK_CHECK;
- reconstruct();
- updatepeople();
- watchreel();
- showrain();
- usetimedtext();
-}
-
-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::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::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::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::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::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::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::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::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 = offset_examlist;
- _cmp(data.byte(kInvopen), 0);
- if (flags.z())
- goto notuseinv;
- bx = offset_invlist1;
- _cmp(data.byte(kInvopen), 1);
- if (flags.z())
- goto notuseinv;
- bx = offset_withlist1;
-notuseinv:
- checkcoords();
- _cmp(data.byte(kQuitrequested), 0);
- if (!flags.z())
- goto stopwaiting;
- _cmp(data.byte(kExamagain), 0);
- if (flags.z())
- goto norex;
- goto examineagain;
-norex:
- _cmp(data.byte(kGetback), 0);
- if (flags.z())
- goto waitexam;
-stopwaiting:
- 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::openob() {
- STACK_CHECK;
- al = data.byte(kOpenedob);
- ah = data.byte(kOpenedtype);
- di = offset_commandline;
- copyname();
- di = (80);
- bx = (58)+86;
- al = 62;
- dl = 240;
- printmessage();
- di = data.word(kLastxpos);
- _add(di, 5);
- bx = (58)+86;
- es = cs;
- si = offset_commandline;
- dl = 220;
- al = 0;
- ah = 0;
- printdirect();
- fillopen();
- getopenedsize();
- al = ah;
- ah = 0;
- cx = (44);
- _mul(cx);
- _add(ax, (80));
- bx = offset_openchangesize;
- cs.word(bx) = ax;
-}
-
-void DreamGenContext::examicon() {
- STACK_CHECK;
- ds = data.word(kIcons2);
- di = 254;
- bx = 5;
- al = 3;
- ah = 0;
- 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::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-69*/
-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 = offset_examlist;
- _cmp(data.byte(kInvopen), 0);
- if (flags.z())
- goto notuseinv;
- bx = offset_invlist1;
- _cmp(data.byte(kInvopen), 1);
- if (flags.z())
- goto notuseinv;
- bx = offset_withlist1;
-notuseinv:
- checkcoords();
- _cmp(data.byte(kQuitrequested), 0);
- if (!flags.z())
- goto stopwaiting;
- _cmp(data.byte(kExamagain), 0);
- if (flags.z())
- goto norex;
- goto examineagain;
-norex:
- _cmp(data.byte(kGetback), 0);
- if (flags.z())
- goto waitexam;
-stopwaiting:
- 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::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::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::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::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 = offset_talklist;
- 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 = offset_quitlist;
- 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 = offset_destlist;
- 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 = offset_operand1+1;
- cx = 12;
- al = 32;
- _stosb(cx, true);
- es = cs;
- di = offset_keys;
- 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 = offset_comlist;
- 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 = offset_rootdir;
- _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 = offset_keys;
- 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 = offset_keys;
- 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 = offset_operand1;
- 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 = offset_operand1+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 = offset_keys;
- _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 = offset_operand1;
- cx = 13;
- al = 0;
- _stosb(cx, true);
- di = offset_operand1;
- 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 = offset_operand1;
-}
-
-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::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::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 = offset_money1poke;
- data.word(kCharshift) = 91*2+75;
- al = 0;
- ah = 0;
- dl = 240;
- printdirect();
- di = 187;
- bx = 155;
- es = cs;
- si = offset_money2poke;
- 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 = offset_money1poke;
- 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 = offset_money2poke;
- _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 = offset_commandline;
- copyname();
- di = 100;
- bx = 21;
- dl = 200;
- al = 63;
- ah = 2;
- printmessage2();
- di = data.word(kLastxpos);
- _add(di, 5);
- bx = 21;
- es = cs;
- si = offset_commandline;
- 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::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::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::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::switchryanon() {
- STACK_CHECK;
- data.byte(kRyanon) = 255;
-}
-
-void DreamGenContext::switchryanoff() {
- STACK_CHECK;
- data.byte(kRyanon) = 1;
-}
-
-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::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::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 = offset_keypadlist;
- 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 = offset_menulist;
- 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 = offset_folderlist;
- 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 = offset_folderlist;
- 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 = offset_folderlist;
- 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 = offset_symbollist;
- 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 = offset_diarylist;
- 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::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 = offset_opslist;
- 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::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 = offset_discopslist;
- checkcoords();
- _cmp(data.byte(kGetback), 0);
- if (flags.z())
- goto discopsloop;
-}
-
-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::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 = offset_decidelist;
- 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::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) */;
- ax = 0x0ffff;
- 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 = offset_speechfile;
- 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::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::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::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::mainscreen() {
- STACK_CHECK;
- data.byte(kInmaparea) = 0;
- bx = offset_mainlist;
- _cmp(data.byte(kWatchon), 1);
- if (flags.z())
- goto checkmain;
- bx = offset_mainlist2;
-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::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::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::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 = offset_atmospherelist;
-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::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::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::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::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::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::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::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::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::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 = offset_keybuffer;
- _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::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::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::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::allocateload() {
- STACK_CHECK;
- push(es);
- push(di);
- bx = es.word(di);
- cl = 4;
- _shr(bx, cl);
- allocatemem();
- di = 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::__start() {
- static const uint8 src[] = {
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x13, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- //0x0000: .... .... .... ....
- 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff,
- //0x0010: .... .... .... ....
- 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- //0x0020: .... .... .... ....
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x00, 0x00, 0x00, 0xff, 0x00,
- //0x0030: .... .... .... ....
- 0xff, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x0d, 0x00, 0xb6,
- //0x0040: ...0 .... .... ....
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- //0x0050: .... .... .... ....
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- //0x0060: .... .... .... ....
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x68, 0x00, 0x26, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- //0x0070: .... ...h .&.. ....
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- //0x0080: .... .... .... ....
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- //0x0090: .... .... .... ....
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- //0x00a0: .... .... .... ....
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00,
- //0x00b0: .... .... .... ....
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- //0x00c0: .... .... .... ....
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- //0x00d0: .... .... .... ....
- 0x00, 0x00, 0x20, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- //0x00e0: .. .... .... ....
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- //0x00f0: .... .... .... ....
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- //0x0100: .... .... .... ....
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- //0x0110: .... .... .... ....
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- //0x0120: .... .... .... ....
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- //0x0130: .... .... .... ....
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- //0x0140: .... .... .... ....
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- //0x0150: .... .... .... ....
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
- //0x0160: .... .... .... ....
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x01, 0xff, 0x00, 0x00, 0x00, 0x00,
- //0x0170: .... .... .... ....
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- //0x0180: .... .... .... ....
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- //0x0190: .... .... .... ....
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
- //0x01a0: .... .... .... ....
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- //0x01b0: .... .... .... ....
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- //0x01c0: .... .... .... ....
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- //0x01d0: .... .... .... ....
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- //0x01e0: .... .... .... ....
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- //0x01f0: .... .... .... ....
- 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- //0x0200: .... .... .... ....
- 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x01, 0x2c, 0x00, 0x14, 0x00, 0x02, 0x00, 0x01, 0x01, 0x37,
- //0x0210: .... ..., .... ...7
- 0x00, 0x00, 0x00, 0x32, 0x14, 0x00, 0x18, 0x16, 0x00, 0x4a, 0x00, 0x01, 0x00, 0x00, 0x18, 0x21,
- //0x0220: ...2 .... .J.. ...!
- 0x0a, 0x4b, 0x00, 0x01, 0x00, 0x01, 0x01, 0x2c, 0x00, 0x1b, 0x00, 0x02, 0x00, 0x02, 0x01, 0x2c,
- //0x0230: .K.. ..., .... ...,
- 0x00, 0x60, 0x00, 0x03, 0x00, 0x04, 0x01, 0x2c, 0x00, 0x76, 0x00, 0x02, 0x00, 0x05, 0x01, 0x2c,
- //0x0240: .`.. ..., .v.. ...,
- 0x0a, 0x00, 0x00, 0x02, 0x00, 0x00, 0x05, 0x16, 0x14, 0x35, 0x00, 0x03, 0x00, 0x00, 0x05, 0x16,
- //0x0250: .... .... .5.. ....
- 0x14, 0x28, 0x00, 0x01, 0x00, 0x02, 0x05, 0x16, 0x14, 0x32, 0x00, 0x01, 0x00, 0x03, 0x02, 0x0b,
- //0x0260: .(.. .... .2.. ....
- 0x0a, 0xc0, 0x00, 0x01, 0x00, 0x00, 0x02, 0x0b, 0x0a, 0xb6, 0x00, 0x02, 0x00, 0x01, 0x08, 0x0b,
- //0x0270: .... .... .... ....
- 0x0a, 0x00, 0x00, 0x02, 0x00, 0x01, 0x17, 0x00, 0x32, 0x00, 0x00, 0x03, 0x00, 0x00, 0x1c, 0x0b,
- //0x0280: .... .... 2... ....
- 0x14, 0xfa, 0x00, 0x04, 0x00, 0x00, 0x17, 0x00, 0x32, 0x2b, 0x00, 0x02, 0x00, 0x08, 0x17, 0x0b,
- //0x0290: .... .... 2+.. ....
- 0x28, 0x82, 0x00, 0x02, 0x00, 0x01, 0x17, 0x16, 0x28, 0x7a, 0x00, 0x02, 0x00, 0x02, 0x17, 0x16,
- //0x02a0: (... .... (z.. ....
- 0x28, 0x69, 0x00, 0x02, 0x00, 0x03, 0x17, 0x16, 0x28, 0x51, 0x00, 0x02, 0x00, 0x04, 0x17, 0x0b,
- //0x02b0: (i.. .... (Q.. ....
- 0x28, 0x87, 0x00, 0x02, 0x00, 0x05, 0x17, 0x16, 0x28, 0x91, 0x00, 0x02, 0x00, 0x06, 0x04, 0x16,
- //0x02c0: (... .... (... ....
- 0x1e, 0x00, 0x00, 0x02, 0x00, 0x00, 0x2d, 0x16, 0x1e, 0xc8, 0x00, 0x00, 0x00, 0x14, 0x2d, 0x16,
- //0x02d0: .... ..-. .... ..-.
- 0x1e, 0x27, 0x00, 0x02, 0x00, 0x00, 0x2d, 0x16, 0x1e, 0x19, 0x00, 0x02, 0x00, 0x00, 0x08, 0x16,
- //0x02e0: .'.. ..-. .... ....
- 0x28, 0x20, 0x00, 0x02, 0x00, 0x00, 0x07, 0x0b, 0x14, 0x40, 0x00, 0x02, 0x00, 0x00, 0x16, 0x16,
- //0x02f0: ( .. .... .@.. ....
- 0x14, 0x52, 0x00, 0x02, 0x00, 0x00, 0x1b, 0x0b, 0x1e, 0x00, 0x00, 0x02, 0x00, 0x00, 0x14, 0x00,
- //0x0300: .R.. .... .... ....
- 0x1e, 0x00, 0x00, 0x02, 0x00, 0x00, 0x0e, 0x21, 0x28, 0x15, 0x00, 0x01, 0x00, 0x00, 0x1d, 0x0b,
- //0x0310: .... ...! (... ....
- 0x0a, 0x00, 0x00, 0x01, 0x00, 0x00, 0x02, 0x16, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x19, 0x00,
- //0x0320: .... .... .... ....
- 0x32, 0x04, 0x00, 0x02, 0x00, 0x00, 0x32, 0x16, 0x1e, 0x79, 0x00, 0x02, 0x00, 0x00, 0x32, 0x16,
- //0x0330: 2... ..2. .y.. ..2.
- 0x1e, 0x00, 0x00, 0x14, 0x00, 0x00, 0x34, 0x16, 0x1e, 0xc0, 0x00, 0x02, 0x00, 0x00, 0x34, 0x16,
- //0x0340: .... ..4. .... ..4.
- 0x1e, 0xe9, 0x00, 0x02, 0x00, 0x00, 0x32, 0x16, 0x28, 0x68, 0x00, 0x37, 0x00, 0x00, 0x35, 0x21,
- //0x0350: .... ..2. (h.7 ..5!
- 0x00, 0x63, 0x00, 0x02, 0x00, 0x00, 0x32, 0x16, 0x28, 0x00, 0x00, 0x03, 0x00, 0x00, 0x32, 0x16,
- //0x0360: .c.. ..2. (... ..2.
- 0x1e, 0xa2, 0x00, 0x02, 0x00, 0x00, 0x34, 0x16, 0x1e, 0x39, 0x00, 0x02, 0x00, 0x00, 0x34, 0x16,
- //0x0370: .... ..4. .9.. ..4.
- 0x1e, 0x00, 0x00, 0x02, 0x00, 0x00, 0x36, 0x00, 0x00, 0x48, 0x00, 0x03, 0x00, 0x00, 0x37, 0x2c,
- //0x0380: .... ..6. .H.. ..7,
- 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x0e, 0x16,
- //0x0390: .... .... .... ....
- 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x0e, 0x16, 0x00, 0x2c, 0x01, 0x01, 0x00, 0x00, 0x0a, 0x16,
- //0x03a0: .... .... .,.. ....
- 0x1e, 0xae, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x16, 0x14, 0x00, 0x00, 0x01, 0x00, 0x00, 0x0b, 0x0b,
- //0x03b0: .... .... .... ....
- 0x14, 0x00, 0x00, 0x32, 0x14, 0x00, 0x0b, 0x0b, 0x1e, 0x00, 0x00, 0x32, 0x14, 0x00, 0x0b, 0x16,
- //0x03c0: ...2 .... ...2 ....
- 0x14, 0x00, 0x00, 0x32, 0x14, 0x00, 0x0e, 0x21, 0x28, 0x00, 0x00, 0x32, 0x14, 0x00, 0xff, 0x7c,
- //0x03d0: ...2 ...! (..2 ...|
- 0xc0, 0x80, 0xc0, 0x1c, 0xc0, 0x20, 0xc0, 0x00, 0xc1, 0x10, 0xc0, 0x18, 0xc0, 0xf4, 0xc0, 0x0c,
- //0x03e0: .... . .. .... ....
- 0xc0, 0x24, 0xc0, 0x28, 0xc0, 0x2c, 0xc0, 0x30, 0xc0, 0x54, 0xc0, 0x78, 0xc0, 0x50, 0xc0, 0x74,
- //0x03f0: .$.( .,.0 .T.x .P.t
- 0xc0, 0x34, 0xc0, 0x38, 0xc0, 0x40, 0xc0, 0x44, 0xc0, 0x48, 0xc0, 0x3c, 0xc0, 0x14, 0xc0, 0x88,
- //0x0400: .4.8 .@.D .H.< ....
- 0xc0, 0x8c, 0xc0, 0x90, 0xc0, 0x70, 0xc0, 0xfc, 0xc0, 0x6c, 0xc0, 0x58, 0xc0, 0x68, 0xc0, 0x04,
- //0x0410: .... .p.. .l.X .h..
- 0xc1, 0x64, 0xc0, 0x60, 0xc0, 0x5c, 0xc0, 0x94, 0xc0, 0x04, 0xc0, 0xa4, 0xc0, 0x9c, 0xc0, 0xa0,
- //0x0420: .d.` .... .... ....
- 0xc0, 0xa8, 0xc0, 0xac, 0xc0, 0x98, 0xc0, 0xb0, 0xc0, 0xb4, 0xc0, 0xc8, 0xc0, 0xcc, 0xc0, 0xd4,
- //0x0430: .... .... .... ....
- 0xc0, 0xdc, 0xc0, 0xd8, 0xc0, 0x00, 0xc0, 0x08, 0xc0, 0x84, 0xc0, 0x84, 0xc0, 0x84, 0xc0, 0x84,
- //0x0440: .... .... .... ....
- 0xc0, 0x00, 0x3c, 0x21, 0x47, 0x0b, 0x52, 0x16, 0x5d, 0x01, 0x2c, 0x0a, 0x10, 0x04, 0x0b, 0x1e,
- //0x0450: ..<! G.R. ].,. ....
- 0x0e, 0x04, 0x16, 0x1e, 0x0e, 0x03, 0x21, 0x0a, 0x0e, 0x0a, 0x21, 0x1e, 0x0e, 0x0a, 0x16, 0x1e,
- //0x0460: .... ..!. ..!. ....
- 0x18, 0x09, 0x16, 0x0a, 0x0e, 0x02, 0x21, 0x00, 0x0e, 0x02, 0x16, 0x00, 0x0e, 0x06, 0x0b, 0x1e,
- //0x0470: .... ..!. .... ....
- 0x0e, 0x07, 0x0b, 0x14, 0x12, 0x07, 0x00, 0x14, 0x12, 0x07, 0x00, 0x1e, 0x12, 0x37, 0x2c, 0x00,
- //0x0480: .... .... .... .7,.
- 0x0e, 0x05, 0x16, 0x1e, 0x0e, 0x08, 0x00, 0x0a, 0x12, 0x08, 0x0b, 0x0a, 0x12, 0x08, 0x16, 0x0a,
- //0x0490: .... .... .... ....
- 0x12, 0x08, 0x21, 0x0a, 0x12, 0x08, 0x21, 0x14, 0x12, 0x08, 0x21, 0x1e, 0x12, 0x08, 0x21, 0x28,
- //0x04a0: ..!. ..!. ..!. ..!(
- 0x12, 0x08, 0x16, 0x28, 0x12, 0x08, 0x0b, 0x28, 0x12, 0x15, 0x2c, 0x14, 0x12, 0xff, 0x2e, 0x05,
- //0x04b0: ...( ...( ..,. ....
- 0x2f, 0x05, 0x33, 0x05, 0x2e, 0x05, 0x2e, 0x05, 0x2e, 0x05, 0x46, 0x05, 0x2e, 0x05, 0x4d, 0x05,
- //0x04c0: /.3. .... ..F. ..M.
- 0x5d, 0x05, 0x64, 0x05, 0x68, 0x05, 0x6c, 0x05, 0x70, 0x05, 0x7d, 0x05, 0x2e, 0x05, 0x2e, 0x05,
- //0x04d0: ].d. h.l. p.}. ....
- 0x2e, 0x05, 0x2e, 0x05, 0x2e, 0x05, 0x9f, 0x05, 0x2e, 0x05, 0xb5, 0x05, 0xd4, 0x05, 0x2e, 0x05,
- //0x04e0: .... .... .... ....
- 0xe1, 0x05, 0xf7, 0x05, 0x0d, 0x06, 0x26, 0x06, 0x39, 0x06, 0x2e, 0x05, 0x2e, 0x05, 0x2e, 0x05,
- //0x04f0: .... ..&. 9... ....
- 0x2e, 0x05, 0x2e, 0x05, 0x2e, 0x05, 0x2e, 0x05, 0x2e, 0x05, 0x2e, 0x05, 0x2e, 0x05, 0x2e, 0x05,
- //0x0500: .... .... .... ....
- 0x2e, 0x05, 0x2e, 0x05, 0x2e, 0x05, 0x2e, 0x05, 0x49, 0x06, 0x50, 0x06, 0x75, 0x06, 0x2e, 0x05,
- //0x0510: .... .... I.P. u...
- 0x2e, 0x05, 0x2e, 0x05, 0x2e, 0x05, 0x82, 0x06, 0x86, 0x06, 0x2e, 0x05, 0x8d, 0x06, 0xff, 0x0f,
- //0x0520: .... .... .... ....
- 0x01, 0x01, 0xff, 0x0c, 0x05, 0x00, 0x0d, 0x15, 0x00, 0x0f, 0x23, 0x00, 0x11, 0x32, 0x00, 0x12,
- //0x0530: .... .... ..#. .2..
- 0x67, 0x00, 0x13, 0x6c, 0x00, 0xff, 0x12, 0x13, 0x00, 0x13, 0x17, 0x00, 0xff, 0x0c, 0x33, 0x00,
- //0x0540: g..l .... .... ..3.
- 0x0d, 0x35, 0x00, 0x0e, 0x0e, 0x00, 0x0f, 0x14, 0x00, 0x00, 0x4e, 0x00, 0xff, 0x0c, 0x77, 0x00,
- //0x0550: .5.. .... ..N. ..w.
- 0x0c, 0x91, 0x00, 0xff, 0x0d, 0x10, 0x00, 0xff, 0x0d, 0x14, 0x00, 0xff, 0x0e, 0x10, 0x00, 0xff,
- //0x0560: .... .... .... ....
- 0x0f, 0x04, 0x00, 0x10, 0x08, 0x00, 0x11, 0x86, 0x00, 0x12, 0x99, 0x00, 0xff, 0x0d, 0x6c, 0x00,
- //0x0570: .... .... .... ..l.
- 0x0f, 0x46, 0x01, 0x0f, 0x4b, 0x01, 0x0f, 0x50, 0x01, 0x0f, 0x56, 0x01, 0x0f, 0x5c, 0x01, 0x0f,
- //0x0580: .F.. K..P ..V. ....
- 0x62, 0x01, 0x12, 0x9f, 0x00, 0x12, 0xb2, 0x00, 0x93, 0xd9, 0x00, 0x54, 0xe4, 0x00, 0xff, 0x0d,
- //0x0590: b... .... ...T ....
- 0x14, 0x00, 0x0d, 0x15, 0x00, 0x0f, 0x22, 0x00, 0x0d, 0x34, 0x00, 0x0d, 0x37, 0x00, 0x19, 0x39,
- //0x05a0: .... ..". .4.. 7..9
- 0x00, 0x15, 0x49, 0x00, 0xff, 0x0d, 0xc4, 0x00, 0x0d, 0xea, 0x00, 0x0d, 0x9c, 0x00, 0x0e, 0x81,
- //0x05b0: ..I. .... .... ....
- 0x00, 0x0d, 0x7c, 0x00, 0x0f, 0xa2, 0x00, 0x0f, 0xc8, 0x00, 0x0f, 0xef, 0x00, 0x11, 0x63, 0x00,
- //0x05c0: ..|. .... .... ..c.
- 0x0c, 0x34, 0x00, 0xff, 0x0f, 0x38, 0x00, 0x10, 0x40, 0x00, 0x13, 0x16, 0x00, 0x14, 0x21, 0x00,
- //0x05d0: .4.. .8.. @... ..!.
- 0xff, 0x14, 0x0b, 0x00, 0x14, 0x0f, 0x00, 0x0f, 0x1c, 0x00, 0x0d, 0x50, 0x00, 0x15, 0x52, 0x00,
- //0x05e0: .... .... ...P ..R.
- 0x93, 0x57, 0x00, 0x57, 0x80, 0x00, 0xff, 0x0c, 0x0d, 0x00, 0x0e, 0x27, 0x00, 0x0c, 0x43, 0x00,
- //0x05f0: .W.W .... ...' ..C.
- 0x0c, 0x4b, 0x00, 0x0c, 0x53, 0x00, 0x0c, 0x5b, 0x00, 0x0f, 0x66, 0x00, 0xff, 0x16, 0x24, 0x00,
- //0x0600: .K.. S..[ ..f. ..$.
- 0x0d, 0x7d, 0x00, 0x12, 0x58, 0x00, 0x0f, 0x6b, 0x00, 0x0e, 0x7f, 0x00, 0x0e, 0x9a, 0x00, 0x93,
- //0x0610: .}.. X..k .... ....
- 0xaa, 0x00, 0x57, 0xe8, 0x00, 0xff, 0x15, 0x10, 0x00, 0x15, 0x48, 0x00, 0x15, 0xcd, 0x00, 0x16,
- //0x0620: ..W. .... ..H. ....
- 0x3f, 0x00, 0x97, 0x63, 0x00, 0x58, 0x9e, 0x00, 0xff, 0x0d, 0x15, 0x00, 0x0e, 0x18, 0x00, 0x93,
- //0x0630: ?..c .X.. .... ....
- 0x32, 0x00, 0x57, 0x4b, 0x00, 0x18, 0x80, 0x00, 0xff, 0x53, 0x2e, 0x00, 0x10, 0xa7, 0x00, 0xff,
- //0x0640: 2.WK .... .S.. ....
- 0x10, 0x13, 0x00, 0x0e, 0x24, 0x00, 0x10, 0x32, 0x00, 0x0e, 0x41, 0x00, 0x10, 0x51, 0x00, 0x0e,
- //0x0650: .... $..2 ..A. .Q..
- 0x60, 0x00, 0x10, 0x72, 0x00, 0x0e, 0x81, 0x00, 0x10, 0x93, 0x00, 0x0e, 0xa2, 0x00, 0x10, 0xb1,
- //0x0660: `..r .... .... ....
- 0x00, 0x0e, 0xbf, 0x00, 0xff, 0x0d, 0x30, 0x00, 0x0e, 0x29, 0x00, 0x0f, 0x4e, 0x00, 0x10, 0x5c,
- //0x0670: .... ..0. .).. N...
- 0x00, 0xff, 0x10, 0x73, 0x00, 0xff, 0x15, 0x67, 0x00, 0x14, 0xc7, 0x00, 0xff, 0x11, 0x35, 0x00,
- //0x0680: ...s ...g .... ..5.
- 0x11, 0x36, 0x00, 0x11, 0x37, 0x00, 0x11, 0x38, 0x00, 0x11, 0x39, 0x00, 0x11, 0x3a, 0x00, 0x11,
- //0x0690: .6.. 7..8 ..9. .:..
- 0x3b, 0x00, 0x11, 0x3d, 0x00, 0x11, 0x3f, 0x00, 0x11, 0x40, 0x00, 0x11, 0x41, 0x00, 0xff, 0x9c,
- //0x06a0: ;..= ..?. .@.. A...
- 0x9a, 0x9f, 0x9a, 0x9c, 0x9e, 0xa0, 0x9b, 0x9d, 0x99, 0x9f, 0x9e, 0x9c, 0x9a, 0x9f, 0x9a, 0x9c,
- //0x06b0: .... .... .... ....
- 0x9e, 0xa0, 0x9b, 0x9d, 0x99, 0x9f, 0x9e, 0x9c, 0x9a, 0x9f, 0x9a, 0x9c, 0x9e, 0xa0, 0x9b, 0x9d,
- //0x06c0: .... .... .... ....
- 0x99, 0x9f, 0x9e, 0x9c, 0x9a, 0x9f, 0x9a, 0x9c, 0x9e, 0xa0, 0x9b, 0x9d, 0x99, 0x9f, 0x9e, 0x9c,
- //0x06d0: .... .... .... ....
- 0x9a, 0x9f, 0x9a, 0x9c, 0x9e, 0xa0, 0x9b, 0x9d, 0x99, 0x9f, 0x9e, 0x9c, 0x9a, 0x9f, 0x9a, 0x9c,
- //0x06e0: .... .... .... ....
- 0x9e, 0xa0, 0x9b, 0x9d, 0x99, 0x9f, 0x9e, 0x9c, 0x9a, 0x9f, 0x9a, 0x9c, 0x9e, 0xa0, 0x9b, 0x9d,
- //0x06f0: .... .... .... ....
- 0x99, 0x9f, 0x9e, 0x9c, 0x9a, 0x9f, 0x9a, 0x9c, 0x9e, 0xa0, 0x9b, 0x9d, 0x99, 0x9f, 0x9e, 0x9c,
- //0x0700: .... .... .... ....
- 0x9a, 0x9f, 0x9a, 0x9c, 0x9e, 0xa0, 0x9b, 0x9d, 0x99, 0x9f, 0x9c, 0x44, 0x52, 0x45, 0x41, 0x4d,
- //0x0710: .... .... ...D REAM
- 0x57, 0x45, 0x42, 0x2e, 0x53, 0x30, 0x30, 0x00, 0x44, 0x52, 0x45, 0x41, 0x4d, 0x57, 0x45, 0x42,
- //0x0720: WEB. S00. DREA MWEB
- 0x2e, 0x53, 0x30, 0x32, 0x00, 0x49, 0x4e, 0x53, 0x54, 0x41, 0x4c, 0x4c, 0x2e, 0x44, 0x41, 0x54,
- //0x0730: .S02 .INS TALL .DAT
- 0x00, 0x44, 0x52, 0x45, 0x41, 0x4d, 0x57, 0x45, 0x42, 0x2e, 0x43, 0x30, 0x30, 0x00, 0x44, 0x52,
- //0x0740: .DRE AMWE B.C0 0.DR
- 0x45, 0x41, 0x4d, 0x57, 0x45, 0x42, 0x2e, 0x43, 0x30, 0x31, 0x00, 0x44, 0x52, 0x45, 0x41, 0x4d,
- //0x0750: EAMW EB.C 01.D REAM
- 0x57, 0x45, 0x42, 0x2e, 0x43, 0x30, 0x32, 0x00, 0x44, 0x52, 0x45, 0x41, 0x4d, 0x57, 0x45, 0x42,
- //0x0760: WEB. C02. DREA MWEB
- 0x2e, 0x56, 0x30, 0x30, 0x00, 0x44, 0x52, 0x45, 0x41, 0x4d, 0x57, 0x45, 0x42, 0x2e, 0x56, 0x39,
- //0x0770: .V00 .DRE AMWE B.V9
- 0x39, 0x00, 0x44, 0x52, 0x45, 0x41, 0x4d, 0x57, 0x45, 0x42, 0x2e, 0x47, 0x30, 0x30, 0x00, 0x44,
- //0x0780: 9.DR EAMW EB.G 00.D
- 0x52, 0x45, 0x41, 0x4d, 0x57, 0x45, 0x42, 0x2e, 0x47, 0x30, 0x31, 0x00, 0x44, 0x52, 0x45, 0x41,
- //0x0790: REAM WEB. G01. DREA
- 0x4d, 0x57, 0x45, 0x42, 0x2e, 0x47, 0x30, 0x32, 0x00, 0x44, 0x52, 0x45, 0x41, 0x4d, 0x57, 0x45,
- //0x07a0: MWEB .G02 .DRE AMWE
- 0x42, 0x2e, 0x47, 0x30, 0x38, 0x00, 0x44, 0x52, 0x45, 0x41, 0x4d, 0x57, 0x45, 0x42, 0x2e, 0x47,
- //0x07b0: B.G0 8.DR EAMW EB.G
- 0x30, 0x33, 0x00, 0x44, 0x52, 0x45, 0x41, 0x4d, 0x57, 0x45, 0x42, 0x2e, 0x47, 0x30, 0x37, 0x00,
- //0x07c0: 03.D REAM WEB. G07.
- 0x44, 0x52, 0x45, 0x41, 0x4d, 0x57, 0x45, 0x42, 0x2e, 0x47, 0x30, 0x34, 0x00, 0x44, 0x52, 0x45,
- //0x07d0: DREA MWEB .G04 .DRE
- 0x41, 0x4d, 0x57, 0x45, 0x42, 0x2e, 0x47, 0x30, 0x35, 0x00, 0x44, 0x52, 0x45, 0x41, 0x4d, 0x57,
- //0x07e0: AMWE B.G0 5.DR EAMW
- 0x45, 0x42, 0x2e, 0x47, 0x30, 0x36, 0x00, 0x44, 0x52, 0x45, 0x41, 0x4d, 0x57, 0x45, 0x42, 0x2e,
- //0x07f0: EB.G 06.D REAM WEB.
- 0x47, 0x31, 0x34, 0x00, 0x44, 0x52, 0x45, 0x41, 0x4d, 0x57, 0x45, 0x42, 0x2e, 0x54, 0x30, 0x31,
- //0x0800: G14. DREA MWEB .T01
- 0x00, 0x44, 0x52, 0x45, 0x41, 0x4d, 0x57, 0x45, 0x42, 0x2e, 0x54, 0x30, 0x32, 0x00, 0x44, 0x52,
- //0x0810: .DRE AMWE B.T0 2.DR
- 0x45, 0x41, 0x4d, 0x57, 0x45, 0x42, 0x2e, 0x54, 0x31, 0x30, 0x00, 0x44, 0x52, 0x45, 0x41, 0x4d,
- //0x0820: EAMW EB.T 10.D REAM
- 0x57, 0x45, 0x42, 0x2e, 0x54, 0x31, 0x31, 0x00, 0x44, 0x52, 0x45, 0x41, 0x4d, 0x57, 0x45, 0x42,
- //0x0830: WEB. T11. DREA MWEB
- 0x2e, 0x54, 0x31, 0x32, 0x00, 0x44, 0x52, 0x45, 0x41, 0x4d, 0x57, 0x45, 0x42, 0x2e, 0x54, 0x31,
- //0x0840: .T12 .DRE AMWE B.T1
- 0x33, 0x00, 0x44, 0x52, 0x45, 0x41, 0x4d, 0x57, 0x45, 0x42, 0x2e, 0x54, 0x32, 0x30, 0x00, 0x44,
- //0x0850: 3.DR EAMW EB.T 20.D
- 0x52, 0x45, 0x41, 0x4d, 0x57, 0x45, 0x42, 0x2e, 0x54, 0x32, 0x31, 0x00, 0x44, 0x52, 0x45, 0x41,
- //0x0860: REAM WEB. T21. DREA
- 0x4d, 0x57, 0x45, 0x42, 0x2e, 0x54, 0x32, 0x32, 0x00, 0x44, 0x52, 0x45, 0x41, 0x4d, 0x57, 0x45,
- //0x0870: MWEB .T22 .DRE AMWE
- 0x42, 0x2e, 0x54, 0x32, 0x33, 0x00, 0x44, 0x52, 0x45, 0x41, 0x4d, 0x57, 0x45, 0x42, 0x2e, 0x54,
- //0x0880: B.T2 3.DR EAMW EB.T
- 0x32, 0x34, 0x00, 0x44, 0x52, 0x45, 0x41, 0x4d, 0x57, 0x45, 0x42, 0x2e, 0x54, 0x35, 0x30, 0x00,
- //0x0890: 24.D REAM WEB. T50.
- 0x44, 0x52, 0x45, 0x41, 0x4d, 0x57, 0x45, 0x42, 0x2e, 0x54, 0x35, 0x31, 0x00, 0x44, 0x52, 0x45,
- //0x08a0: DREA MWEB .T51 .DRE
- 0x41, 0x4d, 0x57, 0x45, 0x42, 0x2e, 0x54, 0x38, 0x30, 0x00, 0x44, 0x52, 0x45, 0x41, 0x4d, 0x57,
- //0x08b0: AMWE B.T8 0.DR EAMW
- 0x45, 0x42, 0x2e, 0x54, 0x38, 0x31, 0x00, 0x44, 0x52, 0x45, 0x41, 0x4d, 0x57, 0x45, 0x42, 0x2e,
- //0x08c0: EB.T 81.D REAM WEB.
- 0x54, 0x38, 0x32, 0x00, 0x44, 0x52, 0x45, 0x41, 0x4d, 0x57, 0x45, 0x42, 0x2e, 0x54, 0x38, 0x33,
- //0x08d0: T82. DREA MWEB .T83
- 0x00, 0x44, 0x52, 0x45, 0x41, 0x4d, 0x57, 0x45, 0x42, 0x2e, 0x54, 0x38, 0x34, 0x00, 0x44, 0x52,
- //0x08e0: .DRE AMWE B.T8 4.DR
- 0x45, 0x41, 0x4d, 0x57, 0x45, 0x42, 0x2e, 0x56, 0x4f, 0x4c, 0x00, 0x44, 0x52, 0x45, 0x41, 0x4d,
- //0x08f0: EAMW EB.V OL.D REAM
- 0x57, 0x45, 0x42, 0x2e, 0x47, 0x30, 0x39, 0x00, 0x44, 0x52, 0x45, 0x41, 0x4d, 0x57, 0x45, 0x42,
- //0x0900: WEB. G09. DREA MWEB
- 0x2e, 0x47, 0x31, 0x30, 0x00, 0x44, 0x52, 0x45, 0x41, 0x4d, 0x57, 0x45, 0x42, 0x2e, 0x47, 0x31,
- //0x0910: .G10 .DRE AMWE B.G1
- 0x31, 0x00, 0x44, 0x52, 0x45, 0x41, 0x4d, 0x57, 0x45, 0x42, 0x2e, 0x47, 0x31, 0x32, 0x00, 0x44,
- //0x0920: 1.DR EAMW EB.G 12.D
- 0x52, 0x45, 0x41, 0x4d, 0x57, 0x45, 0x42, 0x2e, 0x47, 0x31, 0x33, 0x00, 0x44, 0x52, 0x45, 0x41,
- //0x0930: REAM WEB. G13. DREA
- 0x4d, 0x57, 0x45, 0x42, 0x2e, 0x47, 0x31, 0x35, 0x00, 0x44, 0x52, 0x45, 0x41, 0x4d, 0x57, 0x45,
- //0x0940: MWEB .G15 .DRE AMWE
- 0x42, 0x2e, 0x49, 0x30, 0x30, 0x00, 0x44, 0x52, 0x45, 0x41, 0x4d, 0x57, 0x45, 0x42, 0x2e, 0x49,
- //0x0950: B.I0 0.DR EAMW EB.I
- 0x30, 0x31, 0x00, 0x44, 0x52, 0x45, 0x41, 0x4d, 0x57, 0x45, 0x42, 0x2e, 0x49, 0x30, 0x32, 0x00,
- //0x0960: 01.D REAM WEB. I02.
- 0x44, 0x52, 0x45, 0x41, 0x4d, 0x57, 0x45, 0x42, 0x2e, 0x49, 0x30, 0x33, 0x00, 0x44, 0x52, 0x45,
- //0x0970: DREA MWEB .I03 .DRE
- 0x41, 0x4d, 0x57, 0x45, 0x42, 0x2e, 0x49, 0x30, 0x34, 0x00, 0x44, 0x52, 0x45, 0x41, 0x4d, 0x57,
- //0x0980: AMWE B.I0 4.DR EAMW
- 0x45, 0x42, 0x2e, 0x49, 0x30, 0x35, 0x00, 0x44, 0x52, 0x45, 0x41, 0x4d, 0x57, 0x45, 0x42, 0x2e,
- //0x0990: EB.I 05.D REAM WEB.
- 0x49, 0x30, 0x36, 0x00, 0x44, 0x52, 0x45, 0x41, 0x4d, 0x57, 0x45, 0x42, 0x2e, 0x49, 0x30, 0x37,
- //0x09a0: I06. DREA MWEB .I07
- 0x00, 0x44, 0x52, 0x45, 0x41, 0x4d, 0x57, 0x45, 0x42, 0x2e, 0x50, 0x41, 0x4c, 0x00, 0x11, 0x01,
- //0x09b0: .DRE AMWE B.PA L...
- 0x40, 0x01, 0x9d, 0x00, 0xc6, 0x00, 0x44, 0xc3, 0x04, 0x01, 0x2c, 0x01, 0x00, 0x00, 0x2c, 0x00,
- //0x09c0: @... ..D. ..,. ..,.
- 0x80, 0xc5, 0xd2, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x2c, 0x00, 0xdc, 0xc3, 0x90, 0x00, 0xb0, 0x00,
- //0x09d0: .... .... ,... ....
- 0x40, 0x00, 0x60, 0x00, 0x80, 0xc3, 0x00, 0x00, 0x32, 0x00, 0x32, 0x00, 0xc8, 0x00, 0x84, 0xc3,
- //0x09e0: @.`. .... 2.2. ....
- 0x00, 0x00, 0x40, 0x01, 0x00, 0x00, 0xc8, 0x00, 0xa0, 0xca, 0xff, 0xff, 0x11, 0x01, 0x40, 0x01,
- //0x09f0: ..@. .... .... ..@.
- 0x9d, 0x00, 0xc6, 0x00, 0x44, 0xc3, 0xff, 0x00, 0x26, 0x01, 0x00, 0x00, 0x18, 0x00, 0xc8, 0xc3,
- //0x0a00: .... D... &... ....
- 0xf7, 0x00, 0x2d, 0x01, 0x28, 0x00, 0x38, 0x00, 0x48, 0xc3, 0x50, 0x00, 0x00, 0x01, 0x9e, 0x00,
- //0x0a10: ..-. (.8. H.P. ....
- 0xca, 0x00, 0xe0, 0xc3, 0x50, 0x00, 0x2c, 0x01, 0x3a, 0x00, 0x92, 0x00, 0x98, 0xc3, 0x00, 0x00,
- //0x0a20: .... P.,. :... ....
- 0x40, 0x01, 0x00, 0x00, 0xc8, 0x00, 0xa0, 0xca, 0xff, 0xff, 0x11, 0x01, 0x40, 0x01, 0x9d, 0x00,
- //0x0a30: @... .... .... @...
- 0xc6, 0x00, 0x44, 0xc3, 0xf7, 0x00, 0x2d, 0x01, 0x28, 0x00, 0x38, 0x00, 0x48, 0xc3, 0x50, 0x00,
- //0x0a40: ..D. ..-. (.8. H.P.
- 0x2c, 0x01, 0x3a, 0x00, 0x92, 0x00, 0xbc, 0xc6, 0x00, 0x00, 0x40, 0x01, 0x00, 0x00, 0xc8, 0x00,
- //0x0a50: ,.:. .... ..@. ....
- 0xa0, 0xca, 0xff, 0xff, 0x11, 0x01, 0x40, 0x01, 0x9d, 0x00, 0xc6, 0x00, 0x7c, 0xc4, 0xf0, 0x00,
- //0x0a60: .... ..@. .... |...
- 0x22, 0x01, 0x02, 0x00, 0x2c, 0x00, 0x94, 0xc4, 0x00, 0x00, 0x40, 0x01, 0x00, 0x00, 0xc8, 0x00,
- //0x0a70: "... ,... ..@. ....
- 0xa0, 0xca, 0xff, 0xff, 0x11, 0x01, 0x40, 0x01, 0x9d, 0x00, 0xc6, 0x00, 0x7c, 0xc4, 0x00, 0x00,
- //0x0a80: .... ..@. .... |...
- 0x40, 0x01, 0x00, 0x00, 0xc8, 0x00, 0xa0, 0xca, 0xff, 0xff, 0xee, 0x00, 0x02, 0x01, 0x04, 0x00,
- //0x0a90: @... .... .... ....
- 0x2c, 0x00, 0xc8, 0xc4, 0x68, 0x00, 0x7c, 0x00, 0x04, 0x00, 0x2c, 0x00, 0xcc, 0xc4, 0x18, 0x01,
- //0x0aa0: ,... h.|. ..,. ....
- 0x34, 0x01, 0x04, 0x00, 0x2c, 0x00, 0xb0, 0xc4, 0x68, 0x00, 0xd8, 0x00, 0x8a, 0x00, 0xc0, 0x00,
- //0x0ab0: 4... ,... h... ....
- 0xd0, 0xc4, 0x11, 0x01, 0x40, 0x01, 0x9d, 0x00, 0xc6, 0x00, 0x7c, 0xc4, 0x00, 0x00, 0x40, 0x01,
- //0x0ac0: .... @... ..|. ..@.
- 0x00, 0x00, 0xc8, 0x00, 0xa0, 0xca, 0xff, 0xff, 0x45, 0x58, 0x49, 0x54, 0x20, 0x20, 0x20, 0x20,
- //0x0ad0: .... .... EXIT
- 0x20, 0x20, 0x48, 0x45, 0x4c, 0x50, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x4c, 0x49, 0x53, 0x54,
- //0x0ae0: HE LP LIST
- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x52, 0x45, 0x41, 0x44, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
- //0x0af0: RE AD
- 0x4c, 0x4f, 0x47, 0x4f, 0x4e, 0x20, 0x20, 0x20, 0x20, 0x20, 0x4b, 0x45, 0x59, 0x53, 0x20, 0x20,
- //0x0b00: LOGO N KE YS
- 0x20, 0x20, 0x20, 0x20, 0x01, 0x00, 0x50, 0x55, 0x42, 0x4c, 0x49, 0x43, 0x20, 0x20, 0x20, 0x20,
- //0x0b10: ..PU BLIC
- 0x20, 0x20, 0x50, 0x55, 0x42, 0x4c, 0x49, 0x43, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x00, 0x00,
- //0x0b20: PU BLIC ...
- 0x42, 0x4c, 0x41, 0x43, 0x4b, 0x44, 0x52, 0x41, 0x47, 0x4f, 0x4e, 0x20, 0x52, 0x59, 0x41, 0x4e,
- //0x0b30: BLAC KDRA GON RYAN
- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x00, 0x00, 0x48, 0x45, 0x4e, 0x44, 0x52, 0x49,
- //0x0b40: . ..HE NDRI
- 0x58, 0x20, 0x20, 0x20, 0x20, 0x20, 0x4c, 0x4f, 0x55, 0x49, 0x53, 0x20, 0x20, 0x20, 0x20, 0x20,
- //0x0b50: X LO UIS
- 0x20, 0x00, 0x00, 0x00, 0x53, 0x45, 0x50, 0x54, 0x49, 0x4d, 0x55, 0x53, 0x20, 0x20, 0x20, 0x20,
- //0x0b60: ... SEPT IMUS
- 0x42, 0x45, 0x43, 0x4b, 0x45, 0x54, 0x54, 0x20, 0x20, 0x20, 0x20, 0x00, 0xff, 0xff, 0x20, 0x20,
- //0x0b70: BECK ETT . ..
- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x22, 0x52, 0x4f, 0x4f,
- //0x0b80: . "ROO
- 0x54, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x22, 0x20, 0x20, 0x20, 0x20, 0x20,
- //0x0b90: T ."
- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x4e, 0x45, 0x54, 0x57, 0xe8, 0xc4, 0x45, 0x4c,
- //0x0ba0: . NETW ..EL
- 0x56, 0x41, 0x8c, 0xc6, 0x45, 0x4c, 0x56, 0x42, 0x9c, 0xc6, 0x45, 0x4c, 0x56, 0x43, 0x94, 0xc6,
- //0x0bb0: VA.. ELVB ..EL VC..
- 0x45, 0x4c, 0x56, 0x45, 0x98, 0xc6, 0x45, 0x4c, 0x56, 0x46, 0xa0, 0xc6, 0x43, 0x47, 0x41, 0x54,
- //0x0bc0: ELVE ..EL VF.. CGAT
- 0x30, 0xc7, 0x52, 0x45, 0x4d, 0x4f, 0xa8, 0xc6, 0x42, 0x55, 0x54, 0x41, 0x3c, 0xc7, 0x43, 0x42,
- //0x0bd0: 0.RE MO.. BUTA <.CB
- 0x4f, 0x58, 0x44, 0xc7, 0x4c, 0x49, 0x54, 0x45, 0x5c, 0xc6, 0x50, 0x4c, 0x41, 0x54, 0x40, 0xc7,
- //0x0be0: OXD. LITE ..PL AT@.
- 0x4c, 0x49, 0x46, 0x54, 0x7c, 0xc6, 0x57, 0x49, 0x52, 0x45, 0x84, 0xc6, 0x48, 0x4e, 0x44, 0x4c,
- //0x0bf0: LIFT |.WI RE.. HNDL
- 0x88, 0xc6, 0x48, 0x41, 0x43, 0x48, 0x80, 0xc6, 0x44, 0x4f, 0x4f, 0x52, 0xb4, 0xc6, 0x43, 0x53,
- //0x0c00: ..HA CH.. DOOR ..CS
- 0x48, 0x52, 0x70, 0xc6, 0x47, 0x55, 0x4e, 0x41, 0x34, 0xc7, 0x43, 0x52, 0x41, 0x41, 0x64, 0xc6,
- //0x0c10: HRp. GUNA 4.CR AAd.
- 0x43, 0x52, 0x42, 0x42, 0x68, 0xc6, 0x43, 0x52, 0x43, 0x43, 0x6c, 0xc6, 0x53, 0x45, 0x41, 0x54,
- //0x0c20: CRBB h.CR CCl. SEAT
- 0xf8, 0xc5, 0x4d, 0x45, 0x4e, 0x55, 0x98, 0xc7, 0x43, 0x4f, 0x4f, 0x4b, 0xac, 0xc6, 0x45, 0x4c,
- //0x0c30: ..ME NU.. COOK ..EL
- 0x43, 0x41, 0x4c, 0xc6, 0x45, 0x44, 0x43, 0x41, 0x50, 0xc6, 0x44, 0x44, 0x43, 0x41, 0x54, 0xc6,
- //0x0c40: CAL. EDCA P.DD CAT.
- 0x41, 0x4c, 0x54, 0x52, 0x04, 0xc6, 0x4c, 0x4f, 0x4b, 0x41, 0x3c, 0xc6, 0x4c, 0x4f, 0x4b, 0x42,
- //0x0c50: ALTR ..LO KA<. LOKB
- 0x40, 0xc6, 0x45, 0x4e, 0x54, 0x41, 0x10, 0xc6, 0x45, 0x4e, 0x54, 0x42, 0x24, 0xc6, 0x45, 0x4e,
- //0x0c60: @.EN TA.. ENTB $.EN
- 0x54, 0x45, 0x28, 0xc6, 0x45, 0x4e, 0x54, 0x43, 0x18, 0xc6, 0x45, 0x4e, 0x54, 0x44, 0x2c, 0xc6,
- //0x0c70: TE(. ENTC ..EN TD,.
- 0x45, 0x4e, 0x54, 0x48, 0x30, 0xc6, 0x57, 0x57, 0x41, 0x54, 0xf0, 0xc5, 0x50, 0x4f, 0x4f, 0x4c,
- //0x0c80: ENTH 0.WW AT.. POOL
- 0x58, 0xc6, 0x57, 0x53, 0x48, 0x44, 0xf4, 0xc5, 0x47, 0x52, 0x41, 0x46, 0x44, 0xc6, 0x54, 0x52,
- //0x0c90: X.WS HD.. GRAF D.TR
- 0x41, 0x50, 0x48, 0xc6, 0x43, 0x44, 0x50, 0x45, 0x28, 0xc7, 0x44, 0x4c, 0x4f, 0x4b, 0x08, 0xc6,
- //0x0ca0: APH. CDPE (.DL OK..
- 0x48, 0x4f, 0x4c, 0x45, 0x00, 0xc6, 0x44, 0x52, 0x59, 0x52, 0x0c, 0xc6, 0x48, 0x4f, 0x4c, 0x59,
- //0x0cb0: HOLE ..DR YR.. HOLY
- 0xfc, 0xc5, 0x57, 0x41, 0x4c, 0x4c, 0x2c, 0xc7, 0x42, 0x4f, 0x4f, 0x4b, 0x08, 0xc8, 0x41, 0x58,
- //0x0cc0: ..WA LL,. BOOK ..AX
- 0x45, 0x44, 0xb0, 0xc6, 0x53, 0x48, 0x4c, 0x44, 0x38, 0xc7, 0x42, 0x43, 0x4e, 0x59, 0xe8, 0xc5,
- //0x0cd0: ED.. SHLD 8.BC NY..
- 0x4c, 0x49, 0x44, 0x43, 0xe4, 0xc5, 0x4c, 0x49, 0x44, 0x55, 0xe0, 0xc5, 0x4c, 0x49, 0x44, 0x4f,
- //0x0ce0: LIDC ..LI DU.. LIDO
- 0xec, 0xc5, 0x50, 0x49, 0x50, 0x45, 0xa8, 0xc5, 0x42, 0x41, 0x4c, 0x43, 0x20, 0xc6, 0x57, 0x49,
- //0x0cf0: ..PI PE.. BALC .WI
- 0x4e, 0x44, 0x1c, 0xc6, 0x50, 0x41, 0x50, 0x52, 0xb4, 0xc7, 0x55, 0x57, 0x54, 0x41, 0xa0, 0xc5,
- //0x0d00: ND.. PAPR ..UW TA..
- 0x55, 0x57, 0x54, 0x42, 0xa0, 0xc5, 0x53, 0x54, 0x41, 0x54, 0xd8, 0xc7, 0x54, 0x4c, 0x49, 0x44,
- //0x0d10: UWTB ..ST AT.. TLID
- 0x9c, 0xc5, 0x53, 0x4c, 0x41, 0x42, 0xd8, 0xc5, 0x43, 0x41, 0x52, 0x54, 0xdc, 0xc5, 0x46, 0x43,
- //0x0d20: ..SL AB.. CART ..FC
- 0x41, 0x52, 0xac, 0xc5, 0x53, 0x4c, 0x42, 0x41, 0xc0, 0xc5, 0x53, 0x4c, 0x42, 0x42, 0xc4, 0xc5,
- //0x0d30: AR.. SLBA ..SL BB..
- 0x53, 0x4c, 0x42, 0x43, 0xcc, 0xc5, 0x53, 0x4c, 0x42, 0x44, 0xc8, 0xc5, 0x53, 0x4c, 0x42, 0x45,
- //0x0d40: SLBC ..SL BD.. SLBE
- 0xd0, 0xc5, 0x53, 0x4c, 0x42, 0x46, 0xd4, 0xc5, 0x50, 0x4c, 0x49, 0x4e, 0xb0, 0xc5, 0x4c, 0x41,
- //0x0d50: ..SL BF.. PLIN ..LA
- 0x44, 0x44, 0xb8, 0xc5, 0x4c, 0x41, 0x44, 0x42, 0xbc, 0xc5, 0x47, 0x55, 0x4d, 0x41, 0xb4, 0xc5,
- //0x0d60: DD.. LADB ..GU MA..
- 0x53, 0x51, 0x45, 0x45, 0x88, 0xc5, 0x54, 0x41, 0x50, 0x50, 0x8c, 0xc5, 0x47, 0x55, 0x49, 0x54,
- //0x0d70: SQEE ..TA PP.. GUIT
- 0x90, 0xc5, 0x43, 0x4f, 0x4e, 0x54, 0x94, 0xc5, 0x42, 0x45, 0x4c, 0x4c, 0x98, 0xc5, 0x8c, 0x8c,
- //0x0d80: ..CO NT.. BELL ....
- 0x8c, 0x8c, 0x30, 0x30, 0x30, 0x30, 0x00, 0x30, 0x30, 0x00, 0x9d, 0x00, 0xb2, 0x00, 0x51, 0x00,
- //0x0d90: ..00 00.0 0... ..Q.
- 0x5e, 0x00, 0x58, 0xc7, 0xb3, 0x00, 0xc8, 0x00, 0x51, 0x00, 0x5e, 0x00, 0x5c, 0xc7, 0xc9, 0x00,
- //0x0da0: ^.X. .... Q.^. ....
- 0xde, 0x00, 0x51, 0x00, 0x5e, 0x00, 0x60, 0xc7, 0x9d, 0x00, 0xb2, 0x00, 0x5f, 0x00, 0x70, 0x00,
- //0x0db0: ..Q. ^.`. .... _.p.
- 0x64, 0xc7, 0xb3, 0x00, 0xc8, 0x00, 0x5f, 0x00, 0x70, 0x00, 0x68, 0xc7, 0xc9, 0x00, 0xde, 0x00,
- //0x0dc0: d... .._. p.h. ....
- 0x5f, 0x00, 0x70, 0x00, 0x6c, 0xc7, 0x9d, 0x00, 0xb2, 0x00, 0x71, 0x00, 0x82, 0x00, 0x70, 0xc7,
- //0x0dd0: _.p. l... ..q. ..p.
- 0xb3, 0x00, 0xc8, 0x00, 0x71, 0x00, 0x82, 0x00, 0x74, 0xc7, 0xc9, 0x00, 0xde, 0x00, 0x71, 0x00,
- //0x0de0: .... q... t... ..q.
- 0x82, 0x00, 0x78, 0xc7, 0x9d, 0x00, 0xb2, 0x00, 0x83, 0x00, 0x91, 0x00, 0x7c, 0xc7, 0xb3, 0x00,
- //0x0df0: ..x. .... .... |...
- 0xde, 0x00, 0x83, 0x00, 0x91, 0x00, 0x80, 0xc7, 0xdc, 0x00, 0xea, 0x00, 0x98, 0x00, 0xa6, 0x00,
- //0x0e00: .... .... .... ....
- 0x50, 0xc7, 0x00, 0x00, 0x40, 0x01, 0x00, 0x00, 0xc8, 0x00, 0xa0, 0xca, 0xff, 0xff, 0xae, 0x00,
- //0x0e10: P... @... .... ....
- 0xbc, 0x00, 0x84, 0x00, 0x94, 0x00, 0x50, 0xc7, 0x00, 0x00, 0x40, 0x01, 0x00, 0x00, 0xc8, 0x00,
- //0x0e20: .... ..P. ..@. ....
- 0xa0, 0xca, 0xff, 0xff, 0x18, 0x01, 0x40, 0x01, 0xa0, 0x00, 0xc8, 0x00, 0x50, 0xc7, 0x8f, 0x00,
- //0x0e30: .... ..@. .... P...
- 0x2c, 0x01, 0x06, 0x00, 0xc2, 0x00, 0xb8, 0xc7, 0x00, 0x00, 0x8f, 0x00, 0x06, 0x00, 0xc2, 0x00,
- //0x0e40: ,... .... .... ....
- 0xc0, 0xc7, 0x00, 0x00, 0x40, 0x01, 0x00, 0x00, 0xc8, 0x00, 0xa0, 0xca, 0xff, 0xff, 0x68, 0x00,
- //0x0e50: .... @... .... ..h.
- 0x80, 0x00, 0x3a, 0x00, 0x48, 0x00, 0xdc, 0xc7, 0x40, 0x00, 0x74, 0x00, 0x4c, 0x00, 0x6a, 0x00,
- //0x0e60: ..:. H... @.t. L.j.
- 0xe0, 0xc7, 0x74, 0x00, 0xa8, 0x00, 0x4c, 0x00, 0x6a, 0x00, 0xe4, 0xc7, 0x40, 0x00, 0x74, 0x00,
- //0x0e70: ..t. ..L. j... @.t.
- 0x6a, 0x00, 0x88, 0x00, 0xe8, 0xc7, 0x74, 0x00, 0xa8, 0x00, 0x6a, 0x00, 0x88, 0x00, 0xec, 0xc7,
- //0x0e80: j... ..t. ..j. ....
- 0x00, 0x00, 0x40, 0x01, 0x00, 0x00, 0xc8, 0x00, 0xa0, 0xca, 0xff, 0xff, 0xba, 0x00, 0xca, 0x00,
- //0x0e90: ..@. .... .... ....
- 0x9d, 0x00, 0xad, 0x00, 0x1c, 0xc8, 0xf3, 0x00, 0x03, 0x01, 0x83, 0x00, 0x93, 0x00, 0x18, 0xc8,
- //0x0ea0: .... .... .... ....
- 0x0c, 0x01, 0x1c, 0x01, 0xa8, 0x00, 0xb8, 0x00, 0x50, 0xc7, 0x00, 0x00, 0x40, 0x01, 0x00, 0x00,
- //0x0eb0: .... .... P... @...
- 0xc8, 0x00, 0xa0, 0xca, 0xff, 0xff, 0x77, 0x00, 0xae, 0x00, 0x52, 0x00, 0x80, 0x00, 0x34, 0xc8,
- //0x0ec0: .... ..w. ..R. ..4.
- 0x46, 0x00, 0x89, 0x00, 0x3e, 0x00, 0x6f, 0x00, 0x80, 0xc8, 0xbc, 0x00, 0xfa, 0x00, 0x44, 0x00,
- //0x0ed0: F... >.o. .... ..D.
- 0x98, 0x00, 0x4c, 0xc8, 0x00, 0x00, 0x40, 0x01, 0x00, 0x00, 0xc8, 0x00, 0xa0, 0xca, 0xff, 0xff,
- //0x0ee0: ..L. ..@. .... ....
- 0xec, 0x00, 0xfc, 0x00, 0x70, 0x00, 0x80, 0x00, 0x48, 0xc8, 0xbc, 0x00, 0xfa, 0x00, 0x40, 0x00,
- //0x0ef0: .... p... H... ..@.
- 0x98, 0x00, 0x58, 0xc8, 0x3e, 0x00, 0x98, 0x00, 0x38, 0x00, 0x85, 0x00, 0x74, 0xc8, 0x00, 0x00,
- //0x0f00: ..X. >... 8... t...
- 0x40, 0x01, 0x00, 0x00, 0xc8, 0x00, 0xa0, 0xca, 0xff, 0xff, 0x77, 0x00, 0xae, 0x00, 0x52, 0x00,
- //0x0f10: @... .... ..w. ..R.
- 0x80, 0x00, 0x44, 0xc8, 0x46, 0x00, 0x8b, 0x00, 0x3e, 0x00, 0x6f, 0x00, 0x50, 0xc8, 0xec, 0x00,
- //0x0f20: ..D. F... >.o. P...
- 0xfc, 0x00, 0x70, 0x00, 0x80, 0x00, 0x48, 0xc8, 0x00, 0x00, 0x40, 0x01, 0x00, 0x00, 0xc8, 0x00,
- //0x0f30: ..p. ..H. ..@. ....
- 0xa0, 0xca, 0xff, 0xff, 0xec, 0x00, 0xfc, 0x00, 0x70, 0x00, 0x80, 0x00, 0x48, 0xc8, 0xbc, 0x00,
- //0x0f40: .... .... p... H...
- 0xfa, 0x00, 0x40, 0x00, 0x98, 0x00, 0x54, 0xc8, 0x3e, 0x00, 0x98, 0x00, 0x38, 0x00, 0x85, 0x00,
- //0x0f50: ..@. ..T. >... 8...
- 0x74, 0xc8, 0x00, 0x00, 0x40, 0x01, 0x00, 0x00, 0xc8, 0x00, 0xa0, 0xca, 0xff, 0xff, 0x0d, 0x0a,
- //0x0f60: t... @... .... ....
- 0x0d, 0x0a, 0x44, 0x72, 0x65, 0x61, 0x6d, 0x77, 0x65, 0x62, 0x20, 0x68, 0x61, 0x73, 0x20, 0x61,
- //0x0f70: ..Dr eamw eb h as a
- 0x6e, 0x20, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x3a, 0x0d, 0x0a, 0x55, 0x6e, 0x61, 0x62, 0x6c, 0x65,
- //0x0f80: n Er ror: ..Un able
- 0x20, 0x74, 0x6f, 0x20, 0x61, 0x6c, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x65, 0x20, 0x45, 0x78, 0x70,
- //0x0f90: to allo cate Exp
- 0x61, 0x6e, 0x64, 0x65, 0x64, 0x20, 0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x2e, 0x0d, 0x0a, 0x0d,
- //0x0fa0: ande d Me mory ....
- 0x0a, 0x24, 0x0d, 0x0a, 0x0d, 0x0a, 0x44, 0x72, 0x65, 0x61, 0x6d, 0x77, 0x65, 0x62, 0x20, 0x68,
- //0x0fb0: .$.. ..Dr eamw eb h
- 0x61, 0x73, 0x20, 0x61, 0x6e, 0x20, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x3a, 0x0d, 0x0a, 0x53, 0x6f,
- //0x0fc0: as a n Er ror: ..So
- 0x75, 0x6e, 0x64, 0x20, 0x42, 0x6c, 0x61, 0x73, 0x74, 0x65, 0x72, 0x20, 0x63, 0x61, 0x72, 0x64,
- //0x0fd0: und Blas ter card
- 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x66, 0x6f, 0x75, 0x6e, 0x64, 0x20, 0x61, 0x74, 0x20, 0x61, 0x64,
- //0x0fe0: not fou nd a t ad
- 0x64, 0x72, 0x65, 0x73, 0x73, 0x20, 0x32, 0x32, 0x30, 0x20, 0x48, 0x65, 0x78, 0x2e, 0x0d, 0x0a,
- //0x0ff0: dres s 22 0 He x...
- 0x0d, 0x0a, 0x24, 0x0d, 0x0a, 0x0d, 0x0a, 0x44, 0x72, 0x65, 0x61, 0x6d, 0x77, 0x65, 0x62, 0x20,
- //0x1000: ..$. ...D ream web
- 0x68, 0x61, 0x73, 0x20, 0x61, 0x6e, 0x20, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x3a, 0x0d, 0x0a, 0x4f,
- //0x1010: has an E rror :..O
- 0x75, 0x74, 0x20, 0x6f, 0x66, 0x20, 0x42, 0x61, 0x73, 0x65, 0x20, 0x4d, 0x65, 0x6d, 0x6f, 0x72,
- //0x1020: ut o f Ba se M emor
- 0x79, 0x2e, 0x0d, 0x0a, 0x0d, 0x0a, 0x24, 0x0d, 0x0a, 0x0d, 0x0a, 0x44, 0x72, 0x65, 0x61, 0x6d,
- //0x1030: y... ..$. ...D ream
- 0x77, 0x65, 0x62, 0x20, 0x68, 0x61, 0x73, 0x20, 0x61, 0x6e, 0x20, 0x45, 0x72, 0x72, 0x6f, 0x72,
- //0x1040: web has an E rror
- 0x3a, 0x0d, 0x0a, 0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x20, 0x44, 0x65, 0x61, 0x6c, 0x6c, 0x6f,
- //0x1050: :..M emor y De allo
- 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x70, 0x72, 0x6f, 0x62, 0x6c, 0x65, 0x6d, 0x2e, 0x0d,
- //0x1060: cati on p robl em..
- 0x0a, 0x0d, 0x0a, 0x24, 0x0d, 0x0a, 0x0d, 0x0a, 0x44, 0x72, 0x65, 0x61, 0x6d, 0x77, 0x65, 0x62,
- //0x1070: ...$ .... Drea mweb
- 0x20, 0x68, 0x61, 0x73, 0x20, 0x61, 0x6e, 0x20, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x3a, 0x0d, 0x0a,
- //0x1080: has an Erro r:..
- 0x41, 0x74, 0x20, 0x6c, 0x65, 0x61, 0x73, 0x74, 0x20, 0x35, 0x39, 0x30, 0x4b, 0x20, 0x6f, 0x66,
- //0x1090: At l east 590 K of
- 0x20, 0x62, 0x61, 0x73, 0x65, 0x20, 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x20, 0x69, 0x73, 0x20,
- //0x10a0: bas e me mory is
- 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x2e, 0x0d, 0x0a, 0x0d, 0x0a, 0x24, 0x0d, 0x0a,
- //0x10b0: requ ired .... .$..
- 0x0d, 0x0a, 0x44, 0x72, 0x65, 0x61, 0x6d, 0x77, 0x65, 0x62, 0x20, 0x68, 0x61, 0x73, 0x20, 0x61,
- //0x10c0: ..Dr eamw eb h as a
- 0x6e, 0x20, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x3a, 0x0d, 0x0a, 0x53, 0x6f, 0x75, 0x6e, 0x64, 0x20,
- //0x10d0: n Er ror: ..So und
- 0x42, 0x6c, 0x61, 0x73, 0x74, 0x65, 0x72, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x66, 0x6f, 0x75, 0x6e,
- //0x10e0: Blas ter not foun
- 0x64, 0x20, 0x6f, 0x6e, 0x20, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x75, 0x70, 0x74, 0x20, 0x30, 0x0d,
- //0x10f0: d on int erup t 0.
- 0x0a, 0x0d, 0x0a, 0x24, 0x0d, 0x0a, 0x0d, 0x0a, 0x44, 0x72, 0x65, 0x61, 0x6d, 0x77, 0x65, 0x62,
- //0x1100: ...$ .... Drea mweb
- 0x20, 0x68, 0x61, 0x73, 0x20, 0x61, 0x6e, 0x20, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x3a, 0x0d, 0x0a,
- //0x1110: has an Erro r:..
- 0x55, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x74, 0x6f, 0x20, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74,
- //0x1120: Unab le t o se lect
- 0x20, 0x45, 0x4d, 0x4d, 0x20, 0x70, 0x61, 0x67, 0x65, 0x2e, 0x0d, 0x0a, 0x0d, 0x0a, 0x24, 0x0d,
- //0x1130: EMM pag e... ..$.
- 0x0a, 0x0d, 0x0a, 0x44, 0x72, 0x65, 0x61, 0x6d, 0x77, 0x65, 0x62, 0x20, 0x68, 0x61, 0x73, 0x20,
- //0x1140: ...D ream web has
- 0x61, 0x6e, 0x20, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x3a, 0x0d, 0x0a, 0x46, 0x69, 0x6c, 0x65, 0x20,
- //0x1150: an E rror :..F ile
- 0x6e, 0x6f, 0x74, 0x20, 0x66, 0x6f, 0x75, 0x6e, 0x64, 0x2e, 0x63, 0x0d, 0x0a, 0x0d, 0x0a, 0x24,
- //0x1160: not foun d.c. ...$
- 0x44, 0x72, 0x65, 0x61, 0x6d, 0x77, 0x65, 0x62, 0x20, 0x6c, 0x6f, 0x6f, 0x6b, 0x73, 0x20, 0x66,
- //0x1170: Drea mweb loo ks f
- 0x6f, 0x72, 0x20, 0x53, 0x6f, 0x75, 0x6e, 0x64, 0x20, 0x42, 0x6c, 0x61, 0x73, 0x74, 0x65, 0x72,
- //0x1180: or S ound Bla ster
- 0x20, 0x69, 0x6e, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x69, 0x6e, 0x0d,
- //0x1190: inf orma tion in.
- 0x0a, 0x74, 0x68, 0x65, 0x20, 0x42, 0x4c, 0x41, 0x53, 0x54, 0x45, 0x52, 0x20, 0x65, 0x6e, 0x76,
- //0x11a0: .the BLA STER env
- 0x69, 0x72, 0x6f, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x20, 0x76, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c,
- //0x11b0: iron ment var iabl
- 0x65, 0x20, 0x28, 0x69, 0x6e, 0x20, 0x79, 0x6f, 0x75, 0x72, 0x20, 0x41, 0x55, 0x54, 0x4f, 0x45,
- //0x11c0: e (i n yo ur A UTOE
- 0x58, 0x45, 0x43, 0x2e, 0x42, 0x41, 0x54, 0x29, 0x0d, 0x0a, 0x0d, 0x0a, 0x49, 0x66, 0x20, 0x74,
- //0x11d0: XEC. BAT) .... If t
- 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x66, 0x6f, 0x75, 0x6e, 0x64,
- //0x11e0: his is n ot f ound
- 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x49, 0x52, 0x51, 0x20, 0x37, 0x2c, 0x20, 0x44, 0x4d, 0x41,
- //0x11f0: the n IR Q 7, DMA
- 0x20, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x20, 0x31, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x62,
- //0x1200: cha nnel 1 a nd b
- 0x61, 0x73, 0x65, 0x0d, 0x0a, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x20, 0x32, 0x32, 0x30,
- //0x1210: ase. .add ress 220
- 0x68, 0x20, 0x61, 0x72, 0x65, 0x20, 0x61, 0x73, 0x73, 0x75, 0x6d, 0x65, 0x64, 0x2e, 0x0d, 0x0a,
- //0x1220: h ar e as sume d...
- 0x0d, 0x0a, 0x54, 0x6f, 0x20, 0x61, 0x6c, 0x74, 0x65, 0x72, 0x20, 0x61, 0x6e, 0x79, 0x20, 0x6f,
- //0x1230: ..To alt er a ny o
- 0x72, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x73, 0x65, 0x20, 0x73,
- //0x1240: r al l of the se s
- 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x20, 0x79, 0x6f, 0x75, 0x20, 0x63, 0x61, 0x6e, 0x20,
- //0x1250: etti ngs you can
- 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x79, 0x20, 0x74, 0x68, 0x65, 0x6d, 0x0d, 0x0a, 0x6f, 0x6e,
- //0x1260: spec ify them ..on
- 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x20, 0x6c, 0x69, 0x6e,
- //0x1270: the com mand lin
- 0x65, 0x2e, 0x20, 0x46, 0x6f, 0x72, 0x20, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x3a, 0x0d,
- //0x1280: e. F or e xamp le:.
- 0x0a, 0x0d, 0x0a, 0x54, 0x79, 0x70, 0x65, 0x20, 0x20, 0x20, 0x20, 0x44, 0x52, 0x45, 0x41, 0x4d,
- //0x1290: ...T ype D REAM
- 0x57, 0x45, 0x42, 0x20, 0x49, 0x37, 0x20, 0x41, 0x32, 0x32, 0x30, 0x20, 0x44, 0x31, 0x20, 0x20,
- //0x12a0: WEB I7 A 220 D1
- 0x20, 0x20, 0x74, 0x6f, 0x20, 0x72, 0x75, 0x6e, 0x20, 0x44, 0x72, 0x65, 0x61, 0x6d, 0x77, 0x65,
- //0x12b0: to run Dre amwe
- 0x62, 0x20, 0x6f, 0x6e, 0x20, 0x49, 0x52, 0x51, 0x20, 0x37, 0x2c, 0x20, 0x44, 0x4d, 0x41, 0x0d,
- //0x12c0: b on IRQ 7, DMA.
- 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
- //0x12d0: .
- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
- //0x12e0:
- 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x20, 0x31, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x62, 0x61,
- //0x12f0: chan nel 1 an d ba
- 0x73, 0x65, 0x20, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x20, 0x32, 0x32, 0x30, 0x68, 0x0d,
- //0x1300: se a ddre ss 2 20h.
- 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x44, 0x52, 0x45, 0x41, 0x4d, 0x57, 0x45,
- //0x1310: . DRE AMWE
- 0x42, 0x20, 0x49, 0x35, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
- //0x1320: B I5
- 0x74, 0x6f, 0x20, 0x72, 0x75, 0x6e, 0x20, 0x44, 0x72, 0x65, 0x61, 0x6d, 0x77, 0x65, 0x62, 0x20,
- //0x1330: to r un D ream web
- 0x6f, 0x6e, 0x20, 0x49, 0x52, 0x51, 0x20, 0x35, 0x20, 0x61, 0x6e, 0x64, 0x0d, 0x0a, 0x20, 0x20,
- //0x1340: on I RQ 5 and ..
- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
- //0x1350:
- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x64, 0x65, 0x66,
- //0x1360: def
- 0x61, 0x75, 0x6c, 0x74, 0x20, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x20, 0x6f, 0x66, 0x20,
- //0x1370: ault add ress of
- 0x32, 0x32, 0x30, 0x68, 0x2c, 0x20, 0x44, 0x4d, 0x41, 0x20, 0x31, 0x0d, 0x0a, 0x0d, 0x0a, 0x24,
- //0x1380: 220h , DM A 1. ...$
- 0x0d, 0x0a, 0x0d, 0x0a, 0x54, 0x72, 0x79, 0x20, 0x74, 0x68, 0x65, 0x20, 0x44, 0x72, 0x65, 0x61,
- //0x1390: .... Try the Drea
- 0x6d, 0x77, 0x65, 0x62, 0x20, 0x43, 0x44, 0x20, 0x69, 0x6e, 0x20, 0x79, 0x6f, 0x75, 0x72, 0x20,
- //0x13a0: mweb CD in y our
- 0x73, 0x74, 0x65, 0x72, 0x65, 0x6f, 0x2e, 0x2e, 0x2e, 0x2e, 0x0d, 0x0a, 0x0d, 0x0a, 0x0d, 0x0a,
- //0x13b0: ster eo.. .... ....
- 0x24, 0x81, 0x00, 0xb8, 0x00, 0x52, 0x00, 0x80, 0x00, 0xc0, 0xc8, 0x50, 0x00, 0x93, 0x00, 0x3e,
- //0x13c0: $... .R.. ...P ...>
- 0x00, 0x6f, 0x00, 0x80, 0xc8, 0xb7, 0x00, 0xfa, 0x00, 0x3e, 0x00, 0x6f, 0x00, 0xc4, 0xc8, 0x00,
- //0x13d0: .o.. .... .>.o ....
- 0x00, 0x40, 0x01, 0x00, 0x00, 0xc8, 0x00, 0xa0, 0xca, 0xff, 0xff, 0x53, 0x50, 0x45, 0x45, 0x43,
- //0x13e0: .@.. .... ...S PEEC
- 0x48, 0x52, 0x32, 0x34, 0x43, 0x30, 0x30, 0x30, 0x35, 0x2e, 0x52, 0x41, 0x57, 0x00, 0x87, 0x83,
- //0x13f0: HR24 C000 5.RA W...
- 0x81, 0x82, 0x2c, 0x00, 0x46, 0x00, 0x20, 0x00, 0x2e, 0x00, 0x70, 0xc4, 0x00, 0x00, 0x32, 0x00,
- //0x1400: ..,. F. . ..p. ..2.
- 0x00, 0x00, 0xb4, 0x00, 0x7c, 0xc3, 0xe2, 0x00, 0xf4, 0x00, 0x0a, 0x00, 0x1a, 0x00, 0x28, 0xc8,
- //0x1410: .... |... .... ..(.
- 0xe2, 0x00, 0xf4, 0x00, 0x1a, 0x00, 0x28, 0x00, 0x2c, 0xc8, 0xf0, 0x00, 0x04, 0x01, 0x64, 0x00,
- //0x1420: .... ..(. ,... ..d.
- 0x7c, 0x00, 0xcc, 0xc9, 0x00, 0x00, 0x40, 0x01, 0x00, 0x00, 0xc8, 0x00, 0xd4, 0xc9, 0xff, 0xff,
- //0x1430: |... ..@. .... ....
- 0x2c, 0x00, 0x46, 0x00, 0x20, 0x00, 0x2e, 0x00, 0x70, 0xc4, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00,
- //0x1440: ,.F. ... p... 2...
- 0xb4, 0x00, 0x7c, 0xc3, 0x12, 0x01, 0x24, 0x01, 0x0a, 0x00, 0x1a, 0x00, 0x28, 0xc8, 0x12, 0x01,
- //0x1450: ..|. ..$. .... (...
- 0x24, 0x01, 0x1a, 0x00, 0x28, 0x00, 0x2c, 0xc8, 0xf0, 0x00, 0x04, 0x01, 0x64, 0x00, 0x7c, 0x00,
- //0x1460: $... (.,. .... d.|.
- 0xcc, 0xc9, 0x00, 0x00, 0x40, 0x01, 0x00, 0x00, 0xc8, 0x00, 0xd4, 0xc9, 0xff, 0xff, 0x00, 0x21,
- //0x1470: .... @... .... ...!
- 0x0a, 0x0f, 0xff, 0x00, 0x16, 0x0a, 0x0f, 0xff, 0x00, 0x16, 0x00, 0x0f, 0xff, 0x00, 0x0b, 0x00,
- //0x1480: .... .... .... ....
- 0x0f, 0xff, 0x00, 0x0b, 0x0a, 0x0f, 0xff, 0x00, 0x00, 0x0a, 0x0f, 0xff, 0x01, 0x2c, 0x0a, 0x06,
- //0x1490: .... .... .... .,..
- 0xff, 0x01, 0x2c, 0x00, 0x0d, 0xff, 0x02, 0x21, 0x00, 0x06, 0xff, 0x02, 0x16, 0x00, 0x05, 0xff,
- //0x14a0: ..,. ...! .... ....
- 0x02, 0x16, 0x0a, 0x10, 0xff, 0x02, 0x0b, 0x0a, 0x10, 0xff, 0x03, 0x2c, 0x00, 0x0f, 0xff, 0x03,
- //0x14b0: .... .... ..., ....
- 0x21, 0x0a, 0x06, 0xff, 0x03, 0x21, 0x00, 0x05, 0xff, 0x04, 0x0b, 0x1e, 0x06, 0xff, 0x04, 0x16,
- //0x14c0: !... .!.. .... ....
- 0x1e, 0x05, 0xff, 0x04, 0x16, 0x14, 0x0d, 0xff, 0x0a, 0x21, 0x1e, 0x06, 0xff, 0x0a, 0x16, 0x1e,
- //0x14d0: .... .... .!.. ....
- 0x06, 0xff, 0x09, 0x16, 0x0a, 0x06, 0xff, 0x09, 0x16, 0x14, 0x10, 0xff, 0x09, 0x16, 0x1e, 0x10,
- //0x14e0: .... .... .... ....
- 0xff, 0x09, 0x16, 0x28, 0x10, 0xff, 0x09, 0x16, 0x32, 0x10, 0xff, 0x06, 0x0b, 0x1e, 0x06, 0xff,
- //0x14f0: ...( .... 2... ....
- 0x06, 0x00, 0x0a, 0x0f, 0xff, 0x06, 0x00, 0x14, 0x0f, 0xff, 0x06, 0x0b, 0x14, 0x0f, 0xff, 0x06,
- //0x1500: .... .... .... ....
- 0x16, 0x14, 0x0f, 0xff, 0x07, 0x0b, 0x14, 0x06, 0xff, 0x07, 0x00, 0x14, 0x06, 0xff, 0x07, 0x00,
- //0x1510: .... .... .... ....
- 0x1e, 0x06, 0xff, 0x37, 0x2c, 0x00, 0x05, 0xff, 0x37, 0x2c, 0x0a, 0x05, 0xff, 0x05, 0x16, 0x1e,
- //0x1520: ...7 ,... 7,.. ....
- 0x06, 0xff, 0x05, 0x16, 0x14, 0x0f, 0xff, 0x05, 0x16, 0x0a, 0x0f, 0xff, 0x18, 0x16, 0x00, 0x0f,
- //0x1530: .... .... .... ....
- 0xff, 0x18, 0x21, 0x00, 0x0f, 0xff, 0x18, 0x2c, 0x00, 0x0f, 0xff, 0x18, 0x21, 0x0a, 0x0f, 0xff,
- //0x1540: ..!. ..., .... !...
- 0x08, 0x00, 0x0a, 0x06, 0xff, 0x08, 0x0b, 0x0a, 0x06, 0xff, 0x08, 0x16, 0x0a, 0x06, 0xff, 0x08,
- //0x1550: .... .... .... ....
- 0x21, 0x0a, 0x06, 0xff, 0x08, 0x21, 0x14, 0x06, 0xff, 0x08, 0x21, 0x1e, 0x06, 0xff, 0x08, 0x21,
- //0x1560: !... .!.. ..!. ...!
- 0x28, 0x06, 0xff, 0x08, 0x16, 0x28, 0x06, 0xff, 0x08, 0x0b, 0x28, 0x06, 0xff, 0x0b, 0x0b, 0x14,
- //0x1570: (... .(.. ..(. ....
- 0x0c, 0xff, 0x0b, 0x0b, 0x1e, 0x0c, 0xff, 0x0b, 0x16, 0x14, 0x0c, 0xff, 0x0b, 0x16, 0x1e, 0x0c,
- //0x1580: .... .... .... ....
- 0xff, 0x0c, 0x16, 0x14, 0x0c, 0xff, 0x0d, 0x16, 0x14, 0x0c, 0xff, 0x0d, 0x21, 0x14, 0x0c, 0xff,
- //0x1590: .... .... .... !...
- 0x0e, 0x2c, 0x14, 0x0c, 0xff, 0x0e, 0x21, 0x00, 0x0c, 0xff, 0x0e, 0x21, 0x0a, 0x0c, 0xff, 0x0e,
- //0x15a0: .,.. ..!. ...! ....
- 0x21, 0x14, 0x0c, 0xff, 0x0e, 0x21, 0x1e, 0x0c, 0xff, 0x0e, 0x21, 0x28, 0x0c, 0xff, 0x0e, 0x16,
- //0x15b0: !... .!.. ..!( ....
- 0x00, 0x10, 0xff, 0x13, 0x00, 0x00, 0x0c, 0xff, 0x14, 0x00, 0x14, 0x10, 0xff, 0x14, 0x00, 0x1e,
- //0x15c0: .... .... .... ....
- 0x10, 0xff, 0x14, 0x0b, 0x1e, 0x10, 0xff, 0x14, 0x00, 0x28, 0x10, 0xff, 0x14, 0x0b, 0x28, 0x10,
- //0x15d0: .... .... .(.. ..(.
- 0xff, 0x15, 0x0b, 0x0a, 0x0f, 0xff, 0x15, 0x0b, 0x14, 0x0f, 0xff, 0x15, 0x00, 0x14, 0x0f, 0xff,
- //0x15e0: .... .... .... ....
- 0x15, 0x16, 0x14, 0x0f, 0xff, 0x15, 0x21, 0x14, 0x0f, 0xff, 0x15, 0x2c, 0x14, 0x0f, 0xff, 0x15,
- //0x15f0: .... ..!. ..., ....
- 0x2c, 0x0a, 0x0f, 0xff, 0x16, 0x16, 0x0a, 0x10, 0xff, 0x16, 0x16, 0x14, 0x10, 0xff, 0x17, 0x16,
- //0x1600: ,... .... .... ....
- 0x1e, 0x0d, 0xff, 0x17, 0x16, 0x28, 0x0d, 0xff, 0x17, 0x21, 0x28, 0x0d, 0xff, 0x17, 0x0b, 0x28,
- //0x1610: .... .(.. .!(. ...(
- 0x0d, 0xff, 0x17, 0x00, 0x28, 0x0d, 0xff, 0x17, 0x00, 0x32, 0x0d, 0xff, 0x19, 0x0b, 0x28, 0x10,
- //0x1620: .... (... .2.. ..(.
- 0xff, 0x19, 0x0b, 0x32, 0x10, 0xff, 0x19, 0x00, 0x32, 0x10, 0xff, 0x1b, 0x0b, 0x14, 0x10, 0xff,
- //0x1630: ...2 .... 2... ....
- 0x1b, 0x0b, 0x1e, 0x10, 0xff, 0x1d, 0x0b, 0x0a, 0x10, 0xff, 0x2d, 0x16, 0x1e, 0x0c, 0xff, 0x2d,
- //0x1640: .... .... ..-. ...-
- 0x16, 0x28, 0x0c, 0xff, 0x2d, 0x16, 0x32, 0x0c, 0xff, 0x2e, 0x16, 0x28, 0x0c, 0xff, 0x2e, 0x0b,
- //0x1650: .(.. -.2. ...( ....
- 0x32, 0x0c, 0xff, 0x2e, 0x16, 0x32, 0x0c, 0xff, 0x2e, 0x21, 0x32, 0x0c, 0xff, 0x2f, 0x00, 0x00,
- //0x1660: 2... .2.. .!2. ./..
- 0x0c, 0xff, 0x1a, 0x16, 0x14, 0x10, 0xff, 0x1a, 0x21, 0x0a, 0x10, 0xff, 0x1a, 0x21, 0x14, 0x10,
- //0x1670: .... .... !... .!..
- 0xff, 0x1a, 0x21, 0x1e, 0x10, 0xff, 0x1a, 0x2c, 0x1e, 0x10, 0xff, 0x1a, 0x16, 0x1e, 0x10, 0xff,
- //0x1680: ..!. ..., .... ....
- 0x1a, 0x0b, 0x1e, 0x10, 0xff, 0x1a, 0x0b, 0x14, 0x10, 0xff, 0x1a, 0x00, 0x14, 0x10, 0xff, 0x1a,
- //0x1690: .... .... .... ....
- 0x0b, 0x28, 0x10, 0xff, 0x1a, 0x00, 0x28, 0x10, 0xff, 0x1a, 0x16, 0x28, 0x10, 0xff, 0x1a, 0x0b,
- //0x16a0: .(.. ..(. ...( ....
- 0x32, 0x10, 0xff, 0x1c, 0x00, 0x1e, 0x0f, 0xff, 0x1c, 0x00, 0x14, 0x0f, 0xff, 0x1c, 0x00, 0x28,
- //0x16b0: 2... .... .... ...(
- 0x0f, 0xff, 0x1c, 0x0b, 0x1e, 0x0f, 0xff, 0x1c, 0x0b, 0x14, 0x0f, 0xff, 0x1c, 0x16, 0x1e, 0x0f,
- //0x16c0: .... .... .... ....
- 0xff, 0x1c, 0x16, 0x14, 0x0f, 0xff, 0xff, 0x4f, 0x42, 0x4a, 0x45, 0x43, 0x54, 0x20, 0x4e, 0x41,
- //0x16d0: .... ...O BJEC T NA
- 0x4d, 0x45, 0x20, 0x4f, 0x4e, 0x45, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
- //0x16e0: ME O NE
- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00,
- //0x16f0: .
- 0x10, 0x12, 0x12, 0x11, 0x10, 0x10, 0x10, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
- //0x1700: .... .... .... ....
- 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- //0x1710: .... .... .... ....
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36,
- //0x1720: .... .... ..12 3456
- 0x37, 0x38, 0x39, 0x30, 0x2d, 0x00, 0x08, 0x00, 0x51, 0x57, 0x45, 0x52, 0x54, 0x59, 0x55, 0x49,
- //0x1730: 7890 -... QWER TYUI
- 0x4f, 0x50, 0x00, 0x00, 0x0d, 0x00, 0x41, 0x53, 0x44, 0x46, 0x47, 0x48, 0x4a, 0x4b, 0x4c, 0x00,
- //0x1740: OP.. ..AS DFGH JKL.
- 0x00, 0x00, 0x00, 0x00, 0x5a, 0x58, 0x43, 0x56, 0x42, 0x4e, 0x4d, 0x00, 0x00, 0x00, 0x00, 0x00,
- //0x1750: .... ZXCV BNM. ....
- 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- //0x1760: . .. .... .... ....
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- //0x1770: .... .... .... ....
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- //0x1780: .... .... .... ....
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- //0x1790: .... .... .... ....
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x3a, 0x00, 0x00, 0x00,
- //0x17a0: .... .... ...D :...
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- //0x17b0: .... .... .... ....
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x52, 0x45, 0x41, 0x4d,
- //0x17c0: .... .... ...D REAM
- 0x57, 0x45, 0x42, 0x20, 0x44, 0x41, 0x54, 0x41, 0x20, 0x46, 0x49, 0x4c, 0x45, 0x20, 0x43, 0x4f,
- //0x17d0: WEB DATA FIL E CO
- 0x50, 0x59, 0x52, 0x49, 0x47, 0x48, 0x54, 0x20, 0x31, 0x39, 0x39, 0x32, 0x20, 0x43, 0x52, 0x45,
- //0x17e0: PYRI GHT 1992 CRE
- 0x41, 0x54, 0x49, 0x56, 0x45, 0x20, 0x52, 0x45, 0x41, 0x4c, 0x49, 0x54, 0x59, 0x00, 0x00, 0x00,
- //0x17f0: ATIV E RE ALIT Y...
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- //0x1800: .... .... .... ....
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- //0x1810: .... .... .... ....
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x52, 0x45, 0x41, 0x4d,
- //0x1820: .... .... ...D REAM
- 0x57, 0x45, 0x42, 0x2e, 0x52, 0x30, 0x30, 0x00, 0x05, 0xff, 0x21, 0x0a, 0xff, 0xff, 0xff, 0x00,
- //0x1830: WEB. R00. ..!. ....
- 0x01, 0x06, 0x02, 0xff, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x44, 0x52, 0x45, 0x41, 0x4d,
- //0x1840: .... .... ...D REAM
- 0x57, 0x45, 0x42, 0x2e, 0x52, 0x30, 0x31, 0x00, 0x01, 0xff, 0x2c, 0x0a, 0xff, 0xff, 0xff, 0x00,
- //0x1850: WEB. R01. ..,. ....
- 0x07, 0x02, 0xff, 0xff, 0xff, 0xff, 0x06, 0xff, 0xff, 0xff, 0x01, 0x44, 0x52, 0x45, 0x41, 0x4d,
- //0x1860: .... .... ...D REAM
- 0x57, 0x45, 0x42, 0x2e, 0x52, 0x30, 0x32, 0x00, 0x02, 0xff, 0x21, 0x00, 0xff, 0xff, 0xff, 0x00,
- //0x1870: WEB. R02. ..!. ....
- 0x01, 0x00, 0xff, 0xff, 0x01, 0xff, 0x03, 0xff, 0xff, 0xff, 0x02, 0x44, 0x52, 0x45, 0x41, 0x4d,
- //0x1880: .... .... ...D REAM
- 0x57, 0x45, 0x42, 0x2e, 0x52, 0x30, 0x33, 0x00, 0x05, 0xff, 0x21, 0x0a, 0xff, 0xff, 0xff, 0x00,
- //0x1890: WEB. R03. ..!. ....
- 0x02, 0x02, 0x00, 0x02, 0x04, 0xff, 0x00, 0xff, 0xff, 0xff, 0x03, 0x44, 0x52, 0x45, 0x41, 0x4d,
- //0x18a0: .... .... ...D REAM
- 0x57, 0x45, 0x42, 0x2e, 0x52, 0x30, 0x34, 0x00, 0x17, 0xff, 0x0b, 0x1e, 0xff, 0xff, 0xff, 0x00,
- //0x18b0: WEB. R04. .... ....
- 0x01, 0x04, 0x00, 0x05, 0xff, 0xff, 0x03, 0xff, 0xff, 0xff, 0x04, 0x44, 0x52, 0x45, 0x41, 0x4d,
- //0x18c0: .... .... ...D REAM
- 0x57, 0x45, 0x42, 0x2e, 0x52, 0x30, 0x35, 0x00, 0x05, 0xff, 0x16, 0x1e, 0xff, 0xff, 0xff, 0x00,
- //0x18d0: WEB. R05. .... ....
- 0x01, 0x02, 0x00, 0x04, 0xff, 0xff, 0x03, 0xff, 0xff, 0xff, 0x05, 0x44, 0x52, 0x45, 0x41, 0x4d,
- //0x18e0: .... .... ...D REAM
- 0x57, 0x45, 0x42, 0x2e, 0x52, 0x30, 0x36, 0x00, 0x05, 0xff, 0x0b, 0x1e, 0xff, 0xff, 0xff, 0x00,
- //0x18f0: WEB. R06. .... ....
- 0x01, 0x00, 0x00, 0x01, 0x02, 0xff, 0x00, 0xff, 0xff, 0xff, 0x06, 0x44, 0x52, 0x45, 0x41, 0x4d,
- //0x1900: .... .... ...D REAM
- 0x57, 0x45, 0x42, 0x2e, 0x52, 0x30, 0x37, 0x00, 0xff, 0xff, 0x00, 0x14, 0xff, 0xff, 0xff, 0x00,
- //0x1910: WEB. R07. .... ....
- 0x02, 0x02, 0xff, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x07, 0x44, 0x52, 0x45, 0x41, 0x4d,
- //0x1920: .... .... ...D REAM
- 0x57, 0x45, 0x42, 0x2e, 0x52, 0x30, 0x38, 0x00, 0x08, 0xff, 0x00, 0x0a, 0xff, 0xff, 0xff, 0x00,
- //0x1930: WEB. R08. .... ....
- 0x01, 0x02, 0xff, 0xff, 0xff, 0xff, 0x00, 0x0b, 0x28, 0x00, 0x08, 0x44, 0x52, 0x45, 0x41, 0x4d,
- //0x1940: .... .... (..D REAM
- 0x57, 0x45, 0x42, 0x2e, 0x52, 0x30, 0x39, 0x00, 0x09, 0xff, 0x16, 0x0a, 0xff, 0xff, 0xff, 0x00,
- //0x1950: WEB. R09. .... ....
- 0x04, 0x06, 0xff, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x09, 0x44, 0x52, 0x45, 0x41, 0x4d,
- //0x1960: .... .... ...D REAM
- 0x57, 0x45, 0x42, 0x2e, 0x52, 0x31, 0x30, 0x00, 0x0a, 0xff, 0x21, 0x1e, 0xff, 0xff, 0xff, 0x00,
- //0x1970: WEB. R10. ..!. ....
- 0x02, 0x00, 0xff, 0xff, 0x02, 0x02, 0x04, 0x16, 0x1e, 0xff, 0x0a, 0x44, 0x52, 0x45, 0x41, 0x4d,
- //0x1980: .... .... ...D REAM
- 0x57, 0x45, 0x42, 0x2e, 0x52, 0x31, 0x31, 0x00, 0x0b, 0xff, 0x0b, 0x14, 0xff, 0xff, 0xff, 0x00,
- //0x1990: WEB. R11. .... ....
- 0x00, 0x04, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0b, 0x44, 0x52, 0x45, 0x41, 0x4d,
- //0x19a0: .... .... ...D REAM
- 0x57, 0x45, 0x42, 0x2e, 0x52, 0x31, 0x32, 0x00, 0x0c, 0xff, 0x16, 0x14, 0xff, 0xff, 0xff, 0x00,
- //0x19b0: WEB. R12. .... ....
- 0x01, 0x04, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0c, 0x44, 0x52, 0x45, 0x41, 0x4d,
- //0x19c0: .... .... ...D REAM
- 0x57, 0x45, 0x42, 0x2e, 0x52, 0x31, 0x33, 0x00, 0x0c, 0xff, 0x16, 0x14, 0xff, 0xff, 0xff, 0x00,
- //0x19d0: WEB. R13. .... ....
- 0x01, 0x04, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0d, 0x44, 0x52, 0x45, 0x41, 0x4d,
- //0x19e0: .... .... ...D REAM
- 0x57, 0x45, 0x42, 0x2e, 0x52, 0x31, 0x34, 0x00, 0x0e, 0xff, 0x2c, 0x14, 0xff, 0xff, 0xff, 0x00,
- //0x19f0: WEB. R14. ..,. ....
- 0x00, 0x06, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00,
- //0x1a00: .... .... .... ....
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- //0x1a10: .... .... .... ....
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- //0x1a20: .... .... .... ....
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- //0x1a30: .... .... .... ....
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- //0x1a40: .... .... .... ....
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- //0x1a50: .... .... .... ....
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- //0x1a60: .... .... .... ....
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- //0x1a70: .... .... .... ....
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x52, 0x45, 0x41, 0x4d,
- //0x1a80: .... .... ...D REAM
- 0x57, 0x45, 0x42, 0x2e, 0x52, 0x31, 0x39, 0x00, 0x13, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00,
- //0x1a90: WEB. R19. .... ....
- 0x00, 0x04, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x13, 0x44, 0x52, 0x45, 0x41, 0x4d,
- //0x1aa0: .... .... ...D REAM
- 0x57, 0x45, 0x42, 0x2e, 0x52, 0x32, 0x30, 0x00, 0x16, 0xff, 0x00, 0x14, 0xff, 0xff, 0xff, 0x00,
- //0x1ab0: WEB. R20. .... ....
- 0x01, 0x04, 0x02, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x14, 0x44, 0x52, 0x45, 0x41, 0x4d,
- //0x1ac0: .... .... ...D REAM
- 0x57, 0x45, 0x42, 0x2e, 0x52, 0x32, 0x31, 0x00, 0x05, 0xff, 0x0b, 0x0a, 0xff, 0xff, 0xff, 0x00,
- //0x1ad0: WEB. R21. .... ....
- 0x01, 0x04, 0x02, 0x0f, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0x15, 0x44, 0x52, 0x45, 0x41, 0x4d,
- //0x1ae0: .... .... ...D REAM
- 0x57, 0x45, 0x42, 0x2e, 0x52, 0x32, 0x32, 0x00, 0x16, 0xff, 0x16, 0x0a, 0xff, 0xff, 0xff, 0x00,
- //0x1af0: WEB. R22. .... ....
- 0x00, 0x04, 0xff, 0xff, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0x16, 0x44, 0x52, 0x45, 0x41, 0x4d,
- //0x1b00: .... .... ...D REAM
- 0x57, 0x45, 0x42, 0x2e, 0x52, 0x32, 0x33, 0x00, 0x17, 0xff, 0x16, 0x1e, 0xff, 0xff, 0xff, 0x00,
- //0x1b10: WEB. R23. .... ....
- 0x01, 0x04, 0x02, 0x0f, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0x17, 0x44, 0x52, 0x45, 0x41, 0x4d,
- //0x1b20: .... .... ...D REAM
- 0x57, 0x45, 0x42, 0x2e, 0x52, 0x32, 0x34, 0x00, 0x05, 0xff, 0x2c, 0x00, 0xff, 0xff, 0xff, 0x00,
- //0x1b30: WEB. R24. ..,. ....
- 0x01, 0x06, 0x02, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x18, 0x44, 0x52, 0x45, 0x41, 0x4d,
- //0x1b40: .... .... ...D REAM
- 0x57, 0x45, 0x42, 0x2e, 0x52, 0x32, 0x35, 0x00, 0x16, 0xff, 0x0b, 0x28, 0xff, 0xff, 0xff, 0x00,
- //0x1b50: WEB. R25. ...( ....
- 0x01, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x19, 0x44, 0x52, 0x45, 0x41, 0x4d,
- //0x1b60: .... .... ...D REAM
- 0x57, 0x45, 0x42, 0x2e, 0x52, 0x32, 0x36, 0x00, 0x09, 0xff, 0x16, 0x14, 0xff, 0xff, 0xff, 0x00,
- //0x1b70: WEB. R26. .... ....
- 0x04, 0x02, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1a, 0x44, 0x52, 0x45, 0x41, 0x4d,
- //0x1b80: .... .... ...D REAM
- 0x57, 0x45, 0x42, 0x2e, 0x52, 0x32, 0x37, 0x00, 0x16, 0xff, 0x0b, 0x14, 0xff, 0xff, 0xff, 0x00,
- //0x1b90: WEB. R27. .... ....
- 0x00, 0x06, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1b, 0x44, 0x52, 0x45, 0x41, 0x4d,
- //0x1ba0: .... .... ...D REAM
- 0x57, 0x45, 0x42, 0x2e, 0x52, 0x32, 0x38, 0x00, 0x05, 0xff, 0x0b, 0x1e, 0xff, 0xff, 0xff, 0x00,
- //0x1bb0: WEB. R28. .... ....
- 0x00, 0x00, 0xff, 0xff, 0x02, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1c, 0x44, 0x52, 0x45, 0x41, 0x4d,
- //0x1bc0: .... .... ...D REAM
- 0x57, 0x45, 0x42, 0x2e, 0x52, 0x32, 0x39, 0x00, 0x16, 0xff, 0x0b, 0x0a, 0xff, 0xff, 0xff, 0x00,
- //0x1bd0: WEB. R29. .... ....
- 0x00, 0x02, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1d, 0x44, 0x52, 0x45, 0x41, 0x4d,
- //0x1be0: .... .... ...D REAM
- 0x57, 0x45, 0x42, 0x2e, 0x52, 0x30, 0x35, 0x00, 0x05, 0xff, 0x16, 0x0a, 0xff, 0xff, 0xff, 0x00,
- //0x1bf0: WEB. R05. .... ....
- 0x01, 0x04, 0x01, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x05, 0x44, 0x52, 0x45, 0x41, 0x4d,
- //0x1c00: .... .... ...D REAM
- 0x57, 0x45, 0x42, 0x2e, 0x52, 0x30, 0x34, 0x00, 0x17, 0xff, 0x16, 0x14, 0xff, 0xff, 0xff, 0x00,
- //0x1c10: WEB. R04. .... ....
- 0x01, 0x04, 0x02, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x04, 0x44, 0x52, 0x45, 0x41, 0x4d,
- //0x1c20: .... .... ...D REAM
- 0x57, 0x45, 0x42, 0x2e, 0x52, 0x31, 0x30, 0x00, 0x0a, 0xff, 0x16, 0x1e, 0xff, 0xff, 0xff, 0x00,
- //0x1c30: WEB. R10. .... ....
- 0x03, 0x06, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0a, 0x44, 0x52, 0x45, 0x41, 0x4d,
- //0x1c40: .... .... ...D REAM
- 0x57, 0x45, 0x42, 0x2e, 0x52, 0x31, 0x32, 0x00, 0x0c, 0xff, 0x16, 0x14, 0xff, 0xff, 0xff, 0x00,
- //0x1c50: WEB. R12. .... ....
- 0x00, 0x02, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0c, 0x44, 0x52, 0x45, 0x41, 0x4d,
- //0x1c60: .... .... ...D REAM
- 0x57, 0x45, 0x42, 0x2e, 0x52, 0x30, 0x33, 0x00, 0x05, 0xff, 0x2c, 0x00, 0xff, 0xff, 0xff, 0x00,
- //0x1c70: WEB. R03. ..,. ....
- 0x01, 0x06, 0x02, 0xff, 0x04, 0xff, 0xff, 0xff, 0xff, 0xff, 0x03, 0x44, 0x52, 0x45, 0x41, 0x4d,
- //0x1c80: .... .... ...D REAM
- 0x57, 0x45, 0x42, 0x2e, 0x52, 0x32, 0x34, 0x00, 0x05, 0xff, 0x16, 0x00, 0xff, 0xff, 0xff, 0x00,
- //0x1c90: WEB. R24. .... ....
- 0x03, 0x06, 0x00, 0xff, 0xff, 0xff, 0xff, 0x21, 0x00, 0x03, 0x18, 0x44, 0x52, 0x45, 0x41, 0x4d,
- //0x1ca0: .... ...! ...D REAM
- 0x57, 0x45, 0x42, 0x2e, 0x52, 0x32, 0x32, 0x00, 0x16, 0xff, 0x16, 0x14, 0xff, 0xff, 0xff, 0x00,
- //0x1cb0: WEB. R22. .... ....
- 0x01, 0x04, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x16, 0x44, 0x52, 0x45, 0x41, 0x4d,
- //0x1cc0: .... .... ...D REAM
- 0x57, 0x45, 0x42, 0x2e, 0x52, 0x32, 0x32, 0x00, 0x16, 0xff, 0x16, 0x14, 0xff, 0xff, 0xff, 0x00,
- //0x1cd0: WEB. R22. .... ....
- 0x00, 0x02, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x16, 0x44, 0x52, 0x45, 0x41, 0x4d,
- //0x1ce0: .... .... ...D REAM
- 0x57, 0x45, 0x42, 0x2e, 0x52, 0x31, 0x31, 0x00, 0x0b, 0xff, 0x16, 0x1e, 0xff, 0xff, 0xff, 0x00,
- //0x1cf0: WEB. R11. .... ....
- 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0b, 0x44, 0x52, 0x45, 0x41, 0x4d,
- //0x1d00: .... .... ...D REAM
- 0x57, 0x45, 0x42, 0x2e, 0x52, 0x32, 0x38, 0x00, 0x05, 0xff, 0x0b, 0x14, 0xff, 0xff, 0xff, 0x00,
- //0x1d10: WEB. R28. .... ....
- 0x00, 0x06, 0xff, 0xff, 0x02, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1c, 0x44, 0x52, 0x45, 0x41, 0x4d,
- //0x1d20: .... .... ...D REAM
- 0x57, 0x45, 0x42, 0x2e, 0x52, 0x32, 0x31, 0x00, 0x05, 0xff, 0x0b, 0x0a, 0xff, 0xff, 0xff, 0x00,
- //0x1d30: WEB. R21. .... ....
- 0x01, 0x04, 0x02, 0x0f, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0x15, 0x44, 0x52, 0x45, 0x41, 0x4d,
- //0x1d40: .... .... ...D REAM
- 0x57, 0x45, 0x42, 0x2e, 0x52, 0x32, 0x36, 0x00, 0x09, 0xff, 0x00, 0x28, 0xff, 0xff, 0xff, 0x00,
- //0x1d50: WEB. R26. ...( ....
- 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1a, 0x44, 0x52, 0x45, 0x41, 0x4d,
- //0x1d60: .... .... ...D REAM
- 0x57, 0x45, 0x42, 0x2e, 0x52, 0x31, 0x39, 0x00, 0x13, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00,
- //0x1d70: WEB. R19. .... ....
- 0x02, 0x02, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x13, 0x44, 0x52, 0x45, 0x41, 0x4d,
- //0x1d80: .... .... ...D REAM
- 0x57, 0x45, 0x42, 0x2e, 0x52, 0x30, 0x38, 0x00, 0x08, 0xff, 0x0b, 0x28, 0xff, 0xff, 0xff, 0x00,
- //0x1d90: WEB. R08. ...( ....
- 0x00, 0x04, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x08, 0x44, 0x52, 0x45, 0x41, 0x4d,
- //0x1da0: .... .... ...D REAM
- 0x57, 0x45, 0x42, 0x2e, 0x52, 0x30, 0x31, 0x00, 0x01, 0xff, 0x2c, 0x0a, 0xff, 0xff, 0xff, 0x00,
- //0x1db0: WEB. R01. ..,. ....
- 0x03, 0x06, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0x44, 0x52, 0x45, 0x41, 0x4d,
- //0x1dc0: .... .... ...D REAM
- 0x57, 0x45, 0x42, 0x2e, 0x52, 0x34, 0x35, 0x00, 0x23, 0xff, 0x16, 0x1e, 0xff, 0xff, 0xff, 0x00,
- //0x1dd0: WEB. R45. #... ....
- 0x00, 0x06, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x2d, 0x44, 0x52, 0x45, 0x41, 0x4d,
- //0x1de0: .... .... ..-D REAM
- 0x57, 0x45, 0x42, 0x2e, 0x52, 0x34, 0x36, 0x00, 0x23, 0xff, 0x16, 0x28, 0xff, 0xff, 0xff, 0x00,
- //0x1df0: WEB. R46. #..( ....
- 0x00, 0x04, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x2e, 0x44, 0x52, 0x45, 0x41, 0x4d,
- //0x1e00: .... .... ...D REAM
- 0x57, 0x45, 0x42, 0x2e, 0x52, 0x34, 0x37, 0x00, 0x23, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00,
- //0x1e10: WEB. R47. #... ....
- 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x2f, 0x44, 0x52, 0x45, 0x41, 0x4d,
- //0x1e20: .... .... ../D REAM
- 0x57, 0x45, 0x42, 0x2e, 0x52, 0x34, 0x35, 0x00, 0x23, 0xff, 0x16, 0x1e, 0xff, 0xff, 0xff, 0x00,
- //0x1e30: WEB. R45. #... ....
- 0x04, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x2d, 0x44, 0x52, 0x45, 0x41, 0x4d,
- //0x1e40: .... .... ..-D REAM
- 0x57, 0x45, 0x42, 0x2e, 0x52, 0x34, 0x36, 0x00, 0x23, 0xff, 0x16, 0x32, 0xff, 0xff, 0xff, 0x00,
- //0x1e50: WEB. R46. #..2 ....
- 0x00, 0x04, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x2e, 0x44, 0x52, 0x45, 0x41, 0x4d,
- //0x1e60: .... .... ...D REAM
- 0x57, 0x45, 0x42, 0x2e, 0x52, 0x35, 0x30, 0x00, 0x23, 0xff, 0x16, 0x1e, 0xff, 0xff, 0xff, 0x00,
- //0x1e70: WEB. R50. #... ....
- 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x32, 0x44, 0x52, 0x45, 0x41, 0x4d,
- //0x1e80: .... .... ..2D REAM
- 0x57, 0x45, 0x42, 0x2e, 0x52, 0x35, 0x31, 0x00, 0x23, 0xff, 0x0b, 0x1e, 0xff, 0xff, 0xff, 0x00,
- //0x1e90: WEB. R51. #... ....
- 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x33, 0x44, 0x52, 0x45, 0x41, 0x4d,
- //0x1ea0: .... .... ..3D REAM
- 0x57, 0x45, 0x42, 0x2e, 0x52, 0x35, 0x32, 0x00, 0x23, 0xff, 0x16, 0x1e, 0xff, 0xff, 0xff, 0x00,
- //0x1eb0: WEB. R52. #... ....
- 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x34, 0x44, 0x52, 0x45, 0x41, 0x4d,
- //0x1ec0: .... .... ..4D REAM
- 0x57, 0x45, 0x42, 0x2e, 0x52, 0x35, 0x33, 0x00, 0x23, 0xff, 0x21, 0x00, 0xff, 0xff, 0xff, 0x00,
- //0x1ed0: WEB. R53. #.!. ....
- 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x35, 0x44, 0x52, 0x45, 0x41, 0x4d,
- //0x1ee0: .... .... ..5D REAM
- 0x57, 0x45, 0x42, 0x2e, 0x52, 0x35, 0x34, 0x00, 0x23, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00,
- //0x1ef0: WEB. R54. #... ....
- 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x36, 0x44, 0x52, 0x45, 0x41, 0x4d,
- //0x1f00: .... .... ..6D REAM
- 0x57, 0x45, 0x42, 0x2e, 0x52, 0x35, 0x35, 0x00, 0x0e, 0xff, 0x2c, 0x00, 0xff, 0xff, 0xff, 0x00,
- //0x1f10: WEB. R55. ..,. ....
- 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x37, 0x00, 0x00, 0x00, 0x00, 0x00,
- //0x1f20: .... .... ..7. ....
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- //0x1f30: .... .... .... ....
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x01, 0x00,
- //0x1f40: .... .... .... ....
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x03, 0x02, 0x04,
- //0x1f50: .... .... .... ....
- 0x01, 0x0a, 0x09, 0x08, 0x06, 0x0b, 0x04, 0x07, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- //0x1f60: .... .... .... ....
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- //0x1f70: .... .... .... ....
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- //0x1f80: .... .... .... ....
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- //0x1f90: .... .... .... ....
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- //0x1fa0: .... .... .... ....
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- //0x1fb0: .... .... .... ....
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- //0x1fc0: .... .... .... ....
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- //0x1fd0: .... .... .... ....
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff,
- //0x1fe0: .... .... .... ....
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- //0x1ff0: .... .... .... ....
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- //0x2000: .... .... .... ....
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- //0x2010: .... .... .... ....
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- //0x2020: .... .... .... ....
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- //0x2030: .... .... .... ....
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- //0x2040: .... .... .... ....
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- //0x2050: .... .... .... ....
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- //0x2060: .... .... .... ....
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- //0x2070: .... .... .... ....
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- //0x2080: .... .... .... ....
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- //0x2090: .... .... .... ....
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- //0x20a0: .... .... .... ....
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- //0x20b0: .... .... .... ....
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- //0x20c0: .... .... .... ....
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- //0x20d0: .... .... .... ....
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- //0x20e0: .... .... .... ....
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- //0x20f0: .... .... .... ....
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- //0x2100: .... .... .... ....
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- //0x2110: .... .... .... ....
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- //0x2120: .... .... .... ....
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- //0x2130: .... .... .... ....
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- //0x2140: .... .... .... ....
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- //0x2150: .... .... .... ....
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- //0x2160: .... .... .... ....
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- //0x2170: .... .... .... ....
- 0xff, 0xff, 0xff, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
- //0x2180: .... .... .... ....
- 0x01, 0x01, 0x01, 0x01, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
- //0x2190: .... .... .... ....
- 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
- //0x21a0: .... .... .... ....
- 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
- //0x21b0: .... .... .... ....
- 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
- //0x21c0: .... .... .... ....
- 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
- //0x21d0: .... .... .... ....
- 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01,
- //0x21e0: .... .... .... ....
- 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x44, 0x52, 0x45, 0x41, 0x4d, 0x57,
- //0x21f0: .... .... ..DR EAMW
- 0x45, 0x42, 0x2e, 0x44, 0x30, 0x30, 0x00, 0x44, 0x52, 0x45, 0x41, 0x4d, 0x57, 0x45, 0x42, 0x2e,
- //0x2200: EB.D 00.D REAM WEB.
- 0x44, 0x30, 0x31, 0x00, 0x44, 0x52, 0x45, 0x41, 0x4d, 0x57, 0x45, 0x42, 0x2e, 0x44, 0x30, 0x32,
- //0x2210: D01. DREA MWEB .D02
- 0x00, 0x44, 0x52, 0x45, 0x41, 0x4d, 0x57, 0x45, 0x42, 0x2e, 0x44, 0x30, 0x33, 0x00, 0x44, 0x52,
- //0x2220: .DRE AMWE B.D0 3.DR
- 0x45, 0x41, 0x4d, 0x57, 0x45, 0x42, 0x2e, 0x44, 0x30, 0x34, 0x00, 0x44, 0x52, 0x45, 0x41, 0x4d,
- //0x2230: EAMW EB.D 04.D REAM
- 0x57, 0x45, 0x42, 0x2e, 0x44, 0x30, 0x35, 0x00, 0x44, 0x52, 0x45, 0x41, 0x4d, 0x57, 0x45, 0x42,
- //0x2240: WEB. D05. DREA MWEB
- 0x2e, 0x44, 0x30, 0x36, 0x00, 0x44, 0x52, 0x45, 0x41, 0x4d, 0x57, 0x45, 0x42, 0x2e, 0x44, 0x45,
- //0x2250: .D06 .DRE AMWE B.DE
- 0x4d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- //0x2260: M... .... .... ....
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- //0x2270: .... .... .... ....
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- //0x2280: .... .... .... ....
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- //0x2290: .... .... .... ....
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- //0x22a0: .... .... .... ....
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- //0x22b0: .... .... .... ....
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- //0x22c0: .... .... .... ....
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- //0x22d0: .... .... .... ....
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- //0x22e0: .... .... .... ....
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- //0x22f0: .... .... .... ....
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- //0x2300: .... .... .... ....
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- //0x2310: .... .... .... ....
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- //0x2320: .... .... .... ....
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- //0x2330: .... .... .... ....
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- //0x2340: .... .... .... ....
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- //0x2350: .... .... .... ....
- 0x00, 0x00, 0x00, 0x00, 0x00, };
- ds.assign(src, src + sizeof(src));
-dreamweb();
-}
-
-void DreamGenContext::__dispatch_call(uint16 addr) {
- switch(addr) {
- case addr_alleybarksound: alleybarksound(); break;
- case addr_intromusic: intromusic(); break;
- case addr_foghornsound: foghornsound(); break;
- case addr_receptionist: receptionist(); break;
- case addr_smokebloke: smokebloke(); break;
- case addr_attendant: attendant(); break;
- case addr_manasleep: manasleep(); break;
- case addr_eden: eden(); break;
- case addr_edeninbath: edeninbath(); break;
- case addr_malefan: malefan(); break;
- case addr_femalefan: femalefan(); break;
- case addr_louis: louis(); break;
- case addr_louischair: louischair(); break;
- case addr_manasleep2: manasleep2(); break;
- case addr_mansatstill: mansatstill(); break;
- case addr_tattooman: tattooman(); break;
- case addr_drinker: drinker(); break;
- case addr_bartender: bartender(); break;
- case addr_othersmoker: othersmoker(); break;
- case addr_barwoman: barwoman(); break;
- case addr_interviewer: interviewer(); break;
- case addr_soldier1: soldier1(); break;
- case addr_rockstar: rockstar(); break;
- case addr_helicopter: helicopter(); break;
- case addr_mugger: mugger(); break;
- case addr_aide: aide(); break;
- case addr_businessman: businessman(); break;
- case addr_poolguard: poolguard(); break;
- case addr_security: security(); break;
- case addr_heavy: heavy(); break;
- case addr_bossman: bossman(); break;
- case addr_gamer: gamer(); break;
- case addr_sparkydrip: sparkydrip(); break;
- case addr_carparkdrip: carparkdrip(); break;
- case addr_keeper: keeper(); break;
- case addr_candles1: candles1(); break;
- case addr_smallcandle: smallcandle(); break;
- case addr_intromagic1: intromagic1(); break;
- case addr_candles: candles(); break;
- case addr_candles2: candles2(); break;
- case addr_gates: gates(); break;
- case addr_intromagic2: intromagic2(); break;
- case addr_intromagic3: intromagic3(); break;
- case addr_intromonks1: intromonks1(); break;
- case addr_intromonks2: intromonks2(); break;
- case addr_handclap: handclap(); break;
- case addr_monks2text: monks2text(); break;
- case addr_intro1text: intro1text(); break;
- case addr_intro2text: intro2text(); break;
- case addr_intro3text: intro3text(); break;
- case addr_monkandryan: monkandryan(); break;
- case addr_endgameseq: endgameseq(); break;
- case addr_rollendcredits: rollendcredits(); break;
- case addr_priest: priest(); break;
- case addr_madmanstelly: madmanstelly(); break;
- case addr_madman: madman(); break;
- case addr_priesttext: priesttext(); break;
- case addr_textforend: textforend(); break;
- case addr_textformonk: textformonk(); break;
- case addr_drunk: drunk(); break;
- case addr_advisor: advisor(); break;
- case addr_copper: copper(); break;
- case addr_sparky: sparky(); break;
- case addr_train: train(); break;
- case addr_checkspeed: checkspeed(); break;
- case addr_mainman: mainman(); break;
- case addr_checkforexit: checkforexit(); break;
- case addr_adjustdown: adjustdown(); break;
- case addr_adjustup: adjustup(); break;
- case addr_adjustleft: adjustleft(); break;
- case addr_adjustright: adjustright(); break;
- case addr_reminders: reminders(); break;
- case addr_initrain: initrain(); break;
- case addr_splitintolines: splitintolines(); break;
- case addr_backobject: backobject(); break;
- case addr_liftnoise: liftnoise(); break;
- case addr_random: random(); break;
- case addr_steady: steady(); break;
- case addr_constant: constant(); break;
- case addr_reelsonscreen: reelsonscreen(); break;
- case addr_soundonreels: soundonreels(); break;
- case addr_reconstruct: reconstruct(); break;
- case addr_deleverything: deleverything(); break;
- case addr_showpcx: showpcx(); break;
- case addr_loadpalfromiff: loadpalfromiff(); break;
- case addr_setmode: setmode(); break;
- case addr_createpanel: createpanel(); break;
- case addr_createpanel2: createpanel2(); break;
- case addr_vsync: vsync(); break;
- case addr_doshake: doshake(); break;
- case addr_transfermap: transfermap(); break;
- case addr_fadedos: fadedos(); break;
- case addr_dofade: dofade(); break;
- case addr_clearendpal: clearendpal(); break;
- case addr_clearpalette: clearpalette(); break;
- case addr_fadescreenup: fadescreenup(); break;
- case addr_fadetowhite: fadetowhite(); break;
- case addr_fadefromwhite: fadefromwhite(); break;
- case addr_fadescreenups: fadescreenups(); break;
- case addr_fadescreendownhalf: fadescreendownhalf(); break;
- case addr_fadescreenuphalf: fadescreenuphalf(); break;
- case addr_fadescreendown: fadescreendown(); break;
- case addr_fadescreendowns: fadescreendowns(); break;
- case addr_clearstartpal: clearstartpal(); break;
- case addr_showgun: showgun(); break;
- case addr_rollendcredits2: rollendcredits2(); break;
- case addr_rollem: rollem(); break;
- case addr_fadecalculation: fadecalculation(); break;
- case addr_greyscalesum: greyscalesum(); break;
- case addr_showgroup: showgroup(); break;
- case addr_paltostartpal: paltostartpal(); break;
- case addr_endpaltostart: endpaltostart(); break;
- case addr_startpaltoend: startpaltoend(); break;
- case addr_paltoendpal: paltoendpal(); break;
- case addr_allpalette: allpalette(); break;
- case addr_dumpcurrent: dumpcurrent(); break;
- case addr_fadedownmon: fadedownmon(); break;
- case addr_fadeupmon: fadeupmon(); break;
- case addr_fadeupmonfirst: fadeupmonfirst(); break;
- case addr_fadeupyellows: fadeupyellows(); break;
- case addr_initialmoncols: initialmoncols(); break;
- case addr_titles: titles(); break;
- case addr_endgame: endgame(); break;
- case addr_monkspeaking: monkspeaking(); break;
- case addr_showmonk: showmonk(); break;
- case addr_gettingshot: gettingshot(); break;
- case addr_credits: credits(); break;
- case addr_biblequote: biblequote(); break;
- case addr_hangone: hangone(); break;
- case addr_intro: intro(); break;
- case addr_runintroseq: runintroseq(); break;
- case addr_runendseq: runendseq(); break;
- case addr_loadintroroom: loadintroroom(); break;
- case addr_mode640x480: mode640x480(); break;
- case addr_set16colpalette: set16colpalette(); break;
- case addr_realcredits: realcredits(); break;
- case addr_monprint: monprint(); break;
- case addr_fillopen: fillopen(); break;
- case addr_findallopen: findallopen(); break;
- case addr_examineob: examineob(); break;
- case addr_makemainscreen: makemainscreen(); break;
- case addr_getbackfromob: getbackfromob(); break;
- case addr_incryanpage: incryanpage(); break;
- case addr_openinv: openinv(); break;
- case addr_openob: openob(); break;
- case addr_examicon: examicon(); break;
- case addr_describeob: describeob(); break;
- case addr_additionaltext: additionaltext(); break;
- case addr_obsthatdothings: obsthatdothings(); break;
- case addr_getobtextstart: getobtextstart(); break;
- case addr_searchforsame: searchforsame(); break;
- case addr_inventory: inventory(); break;
- case addr_setpickup: setpickup(); break;
- case addr_examinventory: examinventory(); break;
- case addr_reexfrominv: reexfrominv(); break;
- case addr_reexfromopen: reexfromopen(); break;
- case addr_swapwithinv: swapwithinv(); break;
- case addr_swapwithopen: swapwithopen(); break;
- case addr_intoinv: intoinv(); break;
- case addr_outofinv: outofinv(); break;
- case addr_getfreead: getfreead(); break;
- case addr_getexad: getexad(); break;
- case addr_geteitherad: geteitherad(); break;
- case addr_getanyad: getanyad(); break;
- case addr_getanyaddir: getanyaddir(); break;
- case addr_getopenedsize: getopenedsize(); break;
- case addr_getsetad: getsetad(); break;
- case addr_findinvpos: findinvpos(); break;
- case addr_findopenpos: findopenpos(); break;
- case addr_dropobject: dropobject(); break;
- case addr_droperror: droperror(); break;
- case addr_cantdrop: cantdrop(); break;
- case addr_removeobfrominv: removeobfrominv(); break;
- case addr_selectopenob: selectopenob(); break;
- case addr_useopened: useopened(); break;
- case addr_errormessage1: errormessage1(); break;
- case addr_errormessage2: errormessage2(); break;
- case addr_errormessage3: errormessage3(); break;
- case addr_checkobjectsize: checkobjectsize(); break;
- case addr_outofopen: outofopen(); break;
- case addr_transfertoex: transfertoex(); break;
- case addr_pickupconts: pickupconts(); break;
- case addr_transfercontoex: transfercontoex(); break;
- case addr_transfertext: transfertext(); break;
- case addr_purgealocation: purgealocation(); break;
- case addr_emergencypurge: emergencypurge(); break;
- case addr_purgeanitem: purgeanitem(); break;
- case addr_deleteexobject: deleteexobject(); break;
- case addr_deleteexframe: deleteexframe(); break;
- case addr_deleteextext: deleteextext(); break;
- case addr_blockget: blockget(); break;
- case addr_drawfloor: drawfloor(); break;
- case addr_autolook: autolook(); break;
- case addr_look: look(); break;
- case addr_dolook: dolook(); break;
- case addr_redrawmainscrn: redrawmainscrn(); break;
- case addr_getback1: getback1(); break;
- case addr_talk: talk(); break;
- case addr_convicons: convicons(); break;
- case addr_getpersframe: getpersframe(); break;
- case addr_starttalk: starttalk(); break;
- case addr_getpersontext: getpersontext(); break;
- case addr_moretalk: moretalk(); break;
- case addr_dosometalk: dosometalk(); break;
- case addr_hangonpq: hangonpq(); break;
- case addr_redes: redes(); break;
- case addr_newplace: newplace(); break;
- case addr_selectlocation: selectlocation(); break;
- case addr_showcity: showcity(); break;
- case addr_lookatplace: lookatplace(); break;
- case addr_getundercentre: getundercentre(); break;
- case addr_putundercentre: putundercentre(); break;
- case addr_locationpic: locationpic(); break;
- case addr_getdestinfo: getdestinfo(); break;
- case addr_showarrows: showarrows(); break;
- case addr_nextdest: nextdest(); break;
- case addr_lastdest: lastdest(); break;
- case addr_destselect: destselect(); break;
- case addr_getlocation: getlocation(); break;
- case addr_setlocation: setlocation(); break;
- case addr_resetlocation: resetlocation(); break;
- case addr_readdesticon: readdesticon(); break;
- case addr_readcitypic: readcitypic(); break;
- case addr_usemon: usemon(); break;
- case addr_printoutermon: printoutermon(); break;
- case addr_loadpersonal: loadpersonal(); break;
- case addr_loadnews: loadnews(); break;
- case addr_loadcart: loadcart(); break;
- case addr_lookininterface: lookininterface(); break;
- case addr_turnonpower: turnonpower(); break;
- case addr_randomaccess: randomaccess(); break;
- case addr_powerlighton: powerlighton(); break;
- case addr_powerlightoff: powerlightoff(); break;
- case addr_accesslighton: accesslighton(); break;
- case addr_accesslightoff: accesslightoff(); break;
- case addr_locklighton: locklighton(); break;
- case addr_locklightoff: locklightoff(); break;
- case addr_input: input(); break;
- case addr_makecaps: makecaps(); break;
- case addr_delchar: delchar(); break;
- case addr_execcommand: execcommand(); break;
- case addr_neterror: neterror(); break;
- case addr_dircom: dircom(); break;
- case addr_searchforfiles: searchforfiles(); break;
- case addr_signon: signon(); break;
- case addr_showkeys: showkeys(); break;
- case addr_read: read(); break;
- case addr_dirfile: dirfile(); break;
- case addr_getkeyandlogo: getkeyandlogo(); break;
- case addr_searchforstring: searchforstring(); break;
- case addr_parser: parser(); break;
- case addr_scrollmonitor: scrollmonitor(); break;
- case addr_monitorlogo: monitorlogo(); break;
- case addr_printlogo: printlogo(); break;
- case addr_showcurrentfile: showcurrentfile(); break;
- case addr_monmessage: monmessage(); break;
- case addr_processtrigger: processtrigger(); break;
- case addr_triggermessage: triggermessage(); break;
- case addr_printcurs: printcurs(); break;
- case addr_delcurs: delcurs(); break;
- case addr_useobject: useobject(); break;
- case addr_wheelsound: wheelsound(); break;
- case addr_runtap: runtap(); break;
- case addr_playguitar: playguitar(); break;
- case addr_hotelcontrol: hotelcontrol(); break;
- case addr_hotelbell: hotelbell(); break;
- case addr_opentomb: opentomb(); break;
- case addr_usetrainer: usetrainer(); break;
- case addr_nothelderror: nothelderror(); break;
- case addr_usepipe: usepipe(); break;
- case addr_usefullcart: usefullcart(); break;
- case addr_useplinth: useplinth(); break;
- case addr_chewy: chewy(); break;
- case addr_useladder: useladder(); break;
- case addr_useladderb: useladderb(); break;
- case addr_slabdoora: slabdoora(); break;
- case addr_slabdoorb: slabdoorb(); break;
- case addr_slabdoord: slabdoord(); break;
- case addr_slabdoorc: slabdoorc(); break;
- case addr_slabdoore: slabdoore(); break;
- case addr_slabdoorf: slabdoorf(); break;
- case addr_useslab: useslab(); break;
- case addr_usecart: usecart(); break;
- case addr_useclearbox: useclearbox(); break;
- case addr_usecoveredbox: usecoveredbox(); break;
- case addr_userailing: userailing(); break;
- case addr_useopenbox: useopenbox(); break;
- case addr_wearwatch: wearwatch(); break;
- case addr_wearshades: wearshades(); break;
- case addr_sitdowninbar: sitdowninbar(); break;
- case addr_usechurchhole: usechurchhole(); break;
- case addr_usehole: usehole(); break;
- case addr_usealtar: usealtar(); break;
- case addr_opentvdoor: opentvdoor(); break;
- case addr_usedryer: usedryer(); break;
- case addr_openlouis: openlouis(); break;
- case addr_nextcolon: nextcolon(); break;
- case addr_openyourneighbour: openyourneighbour(); break;
- case addr_usewindow: usewindow(); break;
- case addr_usebalcony: usebalcony(); break;
- case addr_openryan: openryan(); break;
- case addr_openpoolboss: openpoolboss(); break;
- case addr_openeden: openeden(); break;
- case addr_opensarters: opensarters(); break;
- case addr_isitright: isitright(); break;
- case addr_drawitall: drawitall(); break;
- case addr_openhoteldoor: openhoteldoor(); break;
- case addr_openhoteldoor2: openhoteldoor2(); break;
- case addr_grafittidoor: grafittidoor(); break;
- case addr_trapdoor: trapdoor(); break;
- case addr_callhotellift: callhotellift(); break;
- case addr_calledenslift: calledenslift(); break;
- case addr_calledensdlift: calledensdlift(); break;
- case addr_usepoolreader: usepoolreader(); break;
- case addr_uselighter: uselighter(); break;
- case addr_showseconduse: showseconduse(); break;
- case addr_usecardreader1: usecardreader1(); break;
- case addr_usecardreader2: usecardreader2(); break;
- case addr_usecardreader3: usecardreader3(); break;
- case addr_usecashcard: usecashcard(); break;
- case addr_lookatcard: lookatcard(); break;
- case addr_moneypoke: moneypoke(); break;
- case addr_usecontrol: usecontrol(); break;
- case addr_usehatch: usehatch(); break;
- case addr_usewire: usewire(); break;
- case addr_usehandle: usehandle(); break;
- case addr_useelevator1: useelevator1(); break;
- case addr_showfirstuse: showfirstuse(); break;
- case addr_useelevator3: useelevator3(); break;
- case addr_useelevator4: useelevator4(); break;
- case addr_useelevator2: useelevator2(); break;
- case addr_useelevator5: useelevator5(); break;
- case addr_usekey: usekey(); break;
- case addr_usestereo: usestereo(); break;
- case addr_usecooker: usecooker(); break;
- case addr_useaxe: useaxe(); break;
- case addr_useelvdoor: useelvdoor(); break;
- case addr_withwhat: withwhat(); break;
- case addr_selectob: selectob(); break;
- case addr_findsetobject: findsetobject(); break;
- case addr_findexobject: findexobject(); break;
- case addr_isryanholding: isryanholding(); break;
- case addr_checkinside: checkinside(); break;
- case addr_putbackobstuff: putbackobstuff(); break;
- case addr_showpuztext: showpuztext(); break;
- case addr_findpuztext: findpuztext(); break;
- case addr_issetobonmap: issetobonmap(); break;
- case addr_placefreeobject: placefreeobject(); break;
- case addr_removefreeobject: removefreeobject(); break;
- case addr_switchryanon: switchryanon(); break;
- case addr_switchryanoff: switchryanoff(); break;
- case addr_autoappear: autoappear(); break;
- case addr_setuptimeduse: setuptimeduse(); break;
- case addr_edenscdplayer: edenscdplayer(); break;
- case addr_usewall: usewall(); break;
- case addr_usechurchgate: usechurchgate(); break;
- case addr_usegun: usegun(); break;
- case addr_useshield: useshield(); break;
- case addr_usebuttona: usebuttona(); break;
- case addr_useplate: useplate(); break;
- case addr_usewinch: usewinch(); break;
- case addr_entercode: entercode(); break;
- case addr_loadkeypad: loadkeypad(); break;
- case addr_quitkey: quitkey(); break;
- case addr_addtopresslist: addtopresslist(); break;
- case addr_buttonone: buttonone(); break;
- case addr_buttontwo: buttontwo(); break;
- case addr_buttonthree: buttonthree(); break;
- case addr_buttonfour: buttonfour(); break;
- case addr_buttonfive: buttonfive(); break;
- case addr_buttonsix: buttonsix(); break;
- case addr_buttonseven: buttonseven(); break;
- case addr_buttoneight: buttoneight(); break;
- case addr_buttonnine: buttonnine(); break;
- case addr_buttonnought: buttonnought(); break;
- case addr_buttonenter: buttonenter(); break;
- case addr_buttonpress: buttonpress(); break;
- case addr_showouterpad: showouterpad(); break;
- case addr_showkeypad: showkeypad(); break;
- case addr_singlekey: singlekey(); break;
- case addr_dumpkeypad: dumpkeypad(); break;
- case addr_usemenu: usemenu(); break;
- case addr_dumpmenu: dumpmenu(); break;
- case addr_getundermenu: getundermenu(); break;
- case addr_putundermenu: putundermenu(); break;
- case addr_showoutermenu: showoutermenu(); break;
- case addr_showmenu: showmenu(); break;
- case addr_loadmenu: loadmenu(); break;
- case addr_viewfolder: viewfolder(); break;
- case addr_nextfolder: nextfolder(); break;
- case addr_folderhints: folderhints(); break;
- case addr_lastfolder: lastfolder(); break;
- case addr_loadfolder: loadfolder(); break;
- case addr_showfolder: showfolder(); break;
- case addr_folderexit: folderexit(); break;
- case addr_showleftpage: showleftpage(); break;
- case addr_showrightpage: showrightpage(); break;
- case addr_entersymbol: entersymbol(); break;
- case addr_quitsymbol: quitsymbol(); break;
- case addr_settopleft: settopleft(); break;
- case addr_settopright: settopright(); break;
- case addr_setbotleft: setbotleft(); break;
- case addr_setbotright: setbotright(); break;
- case addr_dumpsymbol: dumpsymbol(); break;
- case addr_showsymbol: showsymbol(); break;
- case addr_nextsymbol: nextsymbol(); break;
- case addr_updatesymboltop: updatesymboltop(); break;
- case addr_updatesymbolbot: updatesymbolbot(); break;
- case addr_dumpsymbox: dumpsymbox(); break;
- case addr_usediary: usediary(); break;
- case addr_showdiary: showdiary(); break;
- case addr_showdiarykeys: showdiarykeys(); break;
- case addr_dumpdiarykeys: dumpdiarykeys(); break;
- case addr_diarykeyp: diarykeyp(); break;
- case addr_diarykeyn: diarykeyn(); break;
- case addr_showdiarypage: showdiarypage(); break;
- case addr_findtext1: findtext1(); break;
- case addr_zoomonoff: zoomonoff(); break;
- case addr_saveload: saveload(); break;
- case addr_dosaveload: dosaveload(); break;
- case addr_getbackfromops: getbackfromops(); break;
- case addr_showmainops: showmainops(); break;
- case addr_showdiscops: showdiscops(); break;
- case addr_loadsavebox: loadsavebox(); break;
- case addr_loadgame: loadgame(); break;
- case addr_getbacktoops: getbacktoops(); break;
- case addr_discops: discops(); break;
- case addr_savegame: savegame(); break;
- case addr_actualsave: actualsave(); break;
- case addr_actualload: actualload(); break;
- case addr_selectslot2: selectslot2(); break;
- case addr_checkinput: checkinput(); break;
- case addr_getnamepos: getnamepos(); break;
- case addr_showopbox: showopbox(); break;
- case addr_showloadops: showloadops(); break;
- case addr_showsaveops: showsaveops(); break;
- case addr_selectslot: selectslot(); break;
- case addr_showslots: showslots(); break;
- case addr_shownames: shownames(); break;
- case addr_dosreturn: dosreturn(); break;
- case addr_error: error(); break;
- case addr_namestoold: namestoold(); break;
- case addr_oldtonames: oldtonames(); break;
- case addr_savefilewrite: savefilewrite(); break;
- case addr_savefileread: savefileread(); break;
- case addr_saveposition: saveposition(); break;
- case addr_loadposition: loadposition(); break;
- case addr_loadseg: loadseg(); break;
- case addr_makeheader: makeheader(); break;
- case addr_storeit: storeit(); break;
- case addr_saveseg: saveseg(); break;
- case addr_scanfornames: scanfornames(); break;
- case addr_decide: decide(); break;
- case addr_showdecisions: showdecisions(); break;
- case addr_newgame: newgame(); break;
- case addr_loadold: loadold(); break;
- case addr_loadspeech: loadspeech(); break;
- case addr_createname: createname(); break;
- case addr_loadsample: loadsample(); break;
- case addr_loadsecondsample: loadsecondsample(); break;
- case addr_soundstartup: soundstartup(); break;
- case addr_trysoundalloc: trysoundalloc(); break;
- case addr_setsoundoff: setsoundoff(); break;
- case addr_checksoundint: checksoundint(); break;
- case addr_enablesoundint: enablesoundint(); break;
- case addr_disablesoundint: disablesoundint(); break;
- case addr_interupttest: interupttest(); break;
- case addr_soundend: soundend(); break;
- case addr_out22c: out22c(); break;
- case addr_playchannel0: playchannel0(); break;
- case addr_playchannel1: playchannel1(); break;
- case addr_volumeadjust: volumeadjust(); break;
- case addr_channel0only: channel0only(); break;
- case addr_channel1only: channel1only(); break;
- case addr_bothchannels: bothchannels(); break;
- case addr_saveems: saveems(); break;
- case addr_restoreems: restoreems(); break;
- case addr_dmaend: dmaend(); break;
- case addr_startdmablock: startdmablock(); break;
- case addr_setuppit: setuppit(); break;
- case addr_getridofpit: getridofpit(); break;
- case addr_pitinterupt: pitinterupt(); break;
- case addr_dreamweb: dreamweb(); break;
- case addr_entrytexts: entrytexts(); break;
- case addr_entryanims: entryanims(); break;
- case addr_initialinv: initialinv(); break;
- case addr_pickupob: pickupob(); break;
- case addr_setupemm: setupemm(); break;
- case addr_removeemm: removeemm(); break;
- case addr_checkforemm: checkforemm(); break;
- case addr_checkbasemem: checkbasemem(); break;
- case addr_allocatebuffers: allocatebuffers(); break;
- case addr_clearbuffers: clearbuffers(); break;
- case addr_clearchanges: clearchanges(); break;
- case addr_clearbeforeload: clearbeforeload(); break;
- case addr_clearreels: clearreels(); break;
- case addr_clearrest: clearrest(); break;
- case addr_deallocatemem: deallocatemem(); break;
- case addr_allocatemem: allocatemem(); break;
- case addr_startup: startup(); break;
- case addr_startup1: startup1(); break;
- case addr_screenupdate: screenupdate(); break;
- case addr_watchreel: watchreel(); break;
- case addr_checkforshake: checkforshake(); break;
- case addr_watchcount: watchcount(); break;
- case addr_showtime: showtime(); break;
- case addr_dumpwatch: dumpwatch(); break;
- case addr_showbyte: showbyte(); break;
- case addr_onedigit: onedigit(); break;
- case addr_twodigitnum: twodigitnum(); break;
- case addr_showword: showword(); break;
- case addr_convnum: convnum(); break;
- case addr_mainscreen: mainscreen(); break;
- case addr_madmanrun: madmanrun(); break;
- case addr_identifyob: identifyob(); break;
- case addr_findpathofpoint: findpathofpoint(); break;
- case addr_findfirstpath: findfirstpath(); break;
- case addr_afternewroom: afternewroom(); break;
- case addr_atmospheres: atmospheres(); break;
- case addr_walkintoroom: walkintoroom(); break;
- case addr_afterintroroom: afterintroroom(); break;
- case addr_printmessage2: printmessage2(); break;
- case addr_setwalk: setwalk(); break;
- case addr_workoutframes: workoutframes(); break;
- case addr_showicon: showicon(); break;
- case addr_middlepanel: middlepanel(); break;
- case addr_showman: showman(); break;
- case addr_roomname: roomname(); break;
- case addr_usecharset1: usecharset1(); break;
- case addr_usetempcharset: usetempcharset(); break;
- case addr_showexit: showexit(); break;
- case addr_panelicons1: panelicons1(); break;
- case addr_showwatch: showwatch(); break;
- case addr_gettime: gettime(); break;
- case addr_zoomicon: zoomicon(); break;
- case addr_worktoscreenm: worktoscreenm(); break;
- case addr_blank: blank(); break;
- case addr_allpointer: allpointer(); break;
- case addr_hangonw: hangonw(); break;
- case addr_hangoncurs: hangoncurs(); break;
- case addr_getunderzoom: getunderzoom(); break;
- case addr_dumpzoom: dumpzoom(); break;
- case addr_putunderzoom: putunderzoom(); break;
- case addr_undertextline: undertextline(); break;
- case addr_setmouse: setmouse(); break;
- case addr_mousecall: mousecall(); break;
- case addr_readkey: readkey(); break;
- case addr_randomnum1: randomnum1(); break;
- case addr_randomnum2: randomnum2(); break;
- case addr_loadtraveltext: loadtraveltext(); break;
- case addr_loadintotemp: loadintotemp(); break;
- case addr_loadintotemp2: loadintotemp2(); break;
- case addr_loadintotemp3: loadintotemp3(); break;
- case addr_loadtempcharset: loadtempcharset(); break;
- case addr_standardload: standardload(); break;
- case addr_loadtemptext: loadtemptext(); break;
- case addr_loadroom: loadroom(); break;
- case addr_loadroomssample: loadroomssample(); break;
- case addr_getridofreels: getridofreels(); break;
- case addr_getridofall: getridofall(); break;
- case addr_restorereels: restorereels(); break;
- case addr_restoreall: restoreall(); break;
- case addr_sortoutmap: sortoutmap(); break;
- case addr_disablepath: disablepath(); break;
- case addr_findroominloc: findroominloc(); break;
- case addr_dontloadseg: dontloadseg(); break;
- case addr_allocateload: allocateload(); break;
- case addr_getridoftemp: getridoftemp(); break;
- case addr_getridoftemptext: getridoftemptext(); break;
- case addr_getridoftemp2: getridoftemp2(); break;
- case addr_getridoftemp3: getridoftemp3(); break;
- case addr_getridoftempcharset: getridoftempcharset(); break;
- case addr_getridoftempsp: getridoftempsp(); break;
- case addr_readsetdata: readsetdata(); break;
- case addr_createfile: createfile(); break;
- case addr_openfile: openfile(); break;
- case addr_openfilefromc: openfilefromc(); break;
- case addr_openfilenocheck: openfilenocheck(); break;
- case addr_openforsave: openforsave(); break;
- case addr_closefile: closefile(); break;
- case addr_readfromfile: readfromfile(); break;
- case addr_setkeyboardint: setkeyboardint(); break;
- case addr_resetkeyboard: resetkeyboard(); break;
- case addr_keyboardread: keyboardread(); break;
- case addr_doload: doload(); break;
- case addr_generalerror: generalerror(); break;
- default: ::error("invalid call to %04x dispatched", (uint16)ax);
- }
-}
-
-} /*namespace*/
diff --git a/engines/dreamweb/dreamgen.h b/engines/dreamweb/dreamgen.h
deleted file mode 100644
index f3a763fbd8..0000000000
--- a/engines/dreamweb/dreamgen.h
+++ /dev/null
@@ -1,2000 +0,0 @@
-#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 */
-
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-
-
-
-#include "dreamweb/runtime.h"
-
-namespace DreamGen {
-#include "structs.h"
-class DreamGenContext : public Context {
-public:
- void __start();
- void __dispatch_call(uint16 addr);
-#include "stubs.h" // Allow hand-reversed functions to have a signature different than void f()
-
- static const uint16 addr_dreamweb = 0xc948;
- static const uint16 addr_keyboardread = 0xcbb4;
- static const uint16 addr_resetkeyboard = 0xcbb0;
- static const uint16 addr_setkeyboardint = 0xcbac;
- static const uint16 addr_readfromfile = 0xcba8;
- static const uint16 addr_closefile = 0xcba4;
- static const uint16 addr_openforsave = 0xcba0;
- static const uint16 addr_openfilenocheck = 0xcb9c;
- static const uint16 addr_openfilefromc = 0xcb94;
- static const uint16 addr_openfile = 0xcb90;
- static const uint16 addr_createfile = 0xcb8c;
- static const uint16 addr_readsetdata = 0xcb88;
- static const uint16 addr_getridoftempsp = 0xcb84;
- static const uint16 addr_getridoftempcharset = 0xcb80;
- static const uint16 addr_getridoftemp3 = 0xcb7c;
- static const uint16 addr_getridoftemp2 = 0xcb78;
- static const uint16 addr_getridoftemptext = 0xcb74;
- static const uint16 addr_getridoftemp = 0xcb70;
- static const uint16 addr_allocateload = 0xcb68;
- static const uint16 addr_dontloadseg = 0xcb64;
- static const uint16 addr_findroominloc = 0xcb58;
- static const uint16 addr_disablepath = 0xcb50;
- static const uint16 addr_sortoutmap = 0xcb48;
- static const uint16 addr_restoreall = 0xcb44;
- static const uint16 addr_restorereels = 0xcb40;
- static const uint16 addr_getridofall = 0xcb3c;
- static const uint16 addr_getridofreels = 0xcb38;
- static const uint16 addr_loadroomssample = 0xcb34;
- static const uint16 addr_loadroom = 0xcb30;
- static const uint16 addr_loadtemptext = 0xcb2c;
- static const uint16 addr_standardload = 0xcb28;
- static const uint16 addr_loadtempcharset = 0xcb24;
- static const uint16 addr_loadintotemp3 = 0xcb20;
- static const uint16 addr_loadintotemp2 = 0xcb1c;
- static const uint16 addr_loadintotemp = 0xcb18;
- static const uint16 addr_loadtraveltext = 0xcb14;
- static const uint16 addr_randomnum2 = 0xcb08;
- static const uint16 addr_randomnum1 = 0xcb04;
- static const uint16 addr_readkey = 0xcafc;
- static const uint16 addr_mousecall = 0xcae8;
- static const uint16 addr_setmouse = 0xcae0;
- static const uint16 addr_undertextline = 0xcad0;
- static const uint16 addr_putunderzoom = 0xcabc;
- static const uint16 addr_dumpzoom = 0xcab8;
- static const uint16 addr_getunderzoom = 0xcab4;
- static const uint16 addr_hangoncurs = 0xcab0;
- static const uint16 addr_hangonw = 0xcaac;
- static const uint16 addr_allpointer = 0xcaa4;
- static const uint16 addr_blank = 0xcaa0;
- static const uint16 addr_worktoscreenm = 0xca9c;
- static const uint16 addr_zoomicon = 0xca90;
- static const uint16 addr_gettime = 0xca8c;
- static const uint16 addr_showwatch = 0xca88;
- static const uint16 addr_panelicons1 = 0xca84;
- static const uint16 addr_showexit = 0xca80;
- static const uint16 addr_usetempcharset = 0xca7c;
- static const uint16 addr_usecharset1 = 0xca78;
- static const uint16 addr_roomname = 0xca74;
- static const uint16 addr_showman = 0xca6c;
- static const uint16 addr_middlepanel = 0xca68;
- static const uint16 addr_showicon = 0xca64;
- static const uint16 addr_workoutframes = 0xca54;
- static const uint16 addr_setwalk = 0xca44;
- static const uint16 addr_printmessage2 = 0xca30;
- static const uint16 addr_afterintroroom = 0xca14;
- static const uint16 addr_walkintoroom = 0xca10;
- static const uint16 addr_atmospheres = 0xca0c;
- static const uint16 addr_afternewroom = 0xca08;
- static const uint16 addr_findfirstpath = 0xc9f0;
- static const uint16 addr_findpathofpoint = 0xc9ec;
- static const uint16 addr_identifyob = 0xc9d4;
- static const uint16 addr_madmanrun = 0xc9cc;
- static const uint16 addr_mainscreen = 0xc9c8;
- static const uint16 addr_convnum = 0xc9c4;
- static const uint16 addr_showword = 0xc9c0;
- static const uint16 addr_twodigitnum = 0xc9bc;
- static const uint16 addr_onedigit = 0xc9b8;
- static const uint16 addr_showbyte = 0xc9b4;
- static const uint16 addr_dumpwatch = 0xc9b0;
- static const uint16 addr_showtime = 0xc9ac;
- static const uint16 addr_watchcount = 0xc9a8;
- static const uint16 addr_checkforshake = 0xc9a4;
- static const uint16 addr_watchreel = 0xc9a0;
- static const uint16 addr_screenupdate = 0xc99c;
- static const uint16 addr_startup1 = 0xc998;
- static const uint16 addr_startup = 0xc994;
- static const uint16 addr_allocatemem = 0xc988;
- static const uint16 addr_deallocatemem = 0xc984;
- static const uint16 addr_clearrest = 0xc980;
- static const uint16 addr_clearreels = 0xc97c;
- static const uint16 addr_clearbeforeload = 0xc978;
- static const uint16 addr_clearchanges = 0xc974;
- static const uint16 addr_clearbuffers = 0xc970;
- static const uint16 addr_allocatebuffers = 0xc96c;
- static const uint16 addr_checkbasemem = 0xc968;
- static const uint16 addr_checkforemm = 0xc964;
- static const uint16 addr_removeemm = 0xc960;
- static const uint16 addr_setupemm = 0xc95c;
- static const uint16 addr_pickupob = 0xc958;
- static const uint16 addr_initialinv = 0xc954;
- static const uint16 addr_entryanims = 0xc950;
- static const uint16 addr_entrytexts = 0xc94c;
- static const uint16 addr_pitinterupt = 0xc944;
- static const uint16 addr_getridofpit = 0xc940;
- static const uint16 addr_setuppit = 0xc93c;
- static const uint16 addr_startdmablock = 0xc938;
- static const uint16 addr_dmaend = 0xc934;
- static const uint16 addr_restoreems = 0xc92c;
- static const uint16 addr_saveems = 0xc928;
- static const uint16 addr_bothchannels = 0xc924;
- static const uint16 addr_channel1only = 0xc91c;
- static const uint16 addr_channel0only = 0xc918;
- static const uint16 addr_volumeadjust = 0xc908;
- static const uint16 addr_playchannel1 = 0xc900;
- static const uint16 addr_playchannel0 = 0xc8fc;
- static const uint16 addr_out22c = 0xc8f8;
- static const uint16 addr_soundend = 0xc8f4;
- static const uint16 addr_interupttest = 0xc8f0;
- static const uint16 addr_disablesoundint = 0xc8ec;
- static const uint16 addr_enablesoundint = 0xc8e8;
- static const uint16 addr_checksoundint = 0xc8e4;
- static const uint16 addr_setsoundoff = 0xc8e0;
- static const uint16 addr_trysoundalloc = 0xc8dc;
- static const uint16 addr_soundstartup = 0xc8d8;
- static const uint16 addr_loadsecondsample = 0xc8d4;
- static const uint16 addr_loadsample = 0xc8d0;
- static const uint16 addr_createname = 0xc8cc;
- static const uint16 addr_loadspeech = 0xc8c8;
- static const uint16 addr_loadold = 0xc8c4;
- static const uint16 addr_doload = 0xcbb8;
- static const uint16 addr_newgame = 0xc8c0;
- static const uint16 addr_showdecisions = 0xc8bc;
- static const uint16 addr_decide = 0xc8b8;
- static const uint16 addr_scanfornames = 0xc8b4;
- static const uint16 addr_saveseg = 0xc8ac;
- static const uint16 addr_storeit = 0xc8a8;
- static const uint16 addr_makeheader = 0xc8a4;
- static const uint16 addr_loadseg = 0xc8a0;
- static const uint16 addr_loadposition = 0xc89c;
- static const uint16 addr_saveposition = 0xc898;
- static const uint16 addr_savefileread = 0xc894;
- static const uint16 addr_savefilewrite = 0xc890;
- static const uint16 addr_oldtonames = 0xc88c;
- static const uint16 addr_namestoold = 0xc888;
- static const uint16 addr_error = 0xc884;
- static const uint16 addr_generalerror = 0xcbbc;
- static const uint16 addr_dosreturn = 0xc880;
- static const uint16 addr_shownames = 0xc87c;
- static const uint16 addr_showslots = 0xc878;
- static const uint16 addr_selectslot = 0xc874;
- static const uint16 addr_showsaveops = 0xc870;
- static const uint16 addr_showloadops = 0xc86c;
- static const uint16 addr_showopbox = 0xc868;
- static const uint16 addr_getnamepos = 0xc864;
- static const uint16 addr_checkinput = 0xc860;
- static const uint16 addr_selectslot2 = 0xc85c;
- static const uint16 addr_actualload = 0xc858;
- static const uint16 addr_actualsave = 0xc854;
- static const uint16 addr_savegame = 0xc850;
- static const uint16 addr_discops = 0xc84c;
- static const uint16 addr_getbacktoops = 0xc848;
- static const uint16 addr_loadgame = 0xc844;
- static const uint16 addr_loadsavebox = 0xc840;
- static const uint16 addr_showdiscops = 0xc83c;
- static const uint16 addr_showmainops = 0xc838;
- static const uint16 addr_getbackfromops = 0xc834;
- static const uint16 addr_dosaveload = 0xc830;
- static const uint16 addr_saveload = 0xc82c;
- static const uint16 addr_zoomonoff = 0xc828;
- static const uint16 addr_findtext1 = 0xc824;
- static const uint16 addr_showdiarypage = 0xc820;
- static const uint16 addr_diarykeyn = 0xc81c;
- static const uint16 addr_diarykeyp = 0xc818;
- static const uint16 addr_dumpdiarykeys = 0xc814;
- static const uint16 addr_showdiarykeys = 0xc810;
- static const uint16 addr_showdiary = 0xc80c;
- static const uint16 addr_usediary = 0xc808;
- static const uint16 addr_dumpsymbox = 0xc804;
- static const uint16 addr_updatesymbolbot = 0xc800;
- static const uint16 addr_updatesymboltop = 0xc7fc;
- static const uint16 addr_nextsymbol = 0xc7f8;
- static const uint16 addr_showsymbol = 0xc7f4;
- static const uint16 addr_dumpsymbol = 0xc7f0;
- static const uint16 addr_setbotright = 0xc7ec;
- static const uint16 addr_setbotleft = 0xc7e8;
- static const uint16 addr_settopright = 0xc7e4;
- static const uint16 addr_settopleft = 0xc7e0;
- static const uint16 addr_quitsymbol = 0xc7dc;
- static const uint16 addr_entersymbol = 0xc7d8;
- static const uint16 addr_showrightpage = 0xc7d4;
- static const uint16 addr_showleftpage = 0xc7d0;
- static const uint16 addr_folderexit = 0xc7cc;
- static const uint16 addr_showfolder = 0xc7c8;
- static const uint16 addr_loadfolder = 0xc7c4;
- static const uint16 addr_lastfolder = 0xc7c0;
- static const uint16 addr_folderhints = 0xc7bc;
- static const uint16 addr_nextfolder = 0xc7b8;
- static const uint16 addr_viewfolder = 0xc7b4;
- static const uint16 addr_loadmenu = 0xc7b0;
- static const uint16 addr_showmenu = 0xc7ac;
- static const uint16 addr_showoutermenu = 0xc7a8;
- static const uint16 addr_putundermenu = 0xc7a4;
- static const uint16 addr_getundermenu = 0xc7a0;
- static const uint16 addr_dumpmenu = 0xc79c;
- static const uint16 addr_usemenu = 0xc798;
- static const uint16 addr_dumpkeypad = 0xc794;
- static const uint16 addr_singlekey = 0xc790;
- static const uint16 addr_showkeypad = 0xc78c;
- static const uint16 addr_showouterpad = 0xc788;
- static const uint16 addr_buttonpress = 0xc784;
- static const uint16 addr_buttonenter = 0xc780;
- static const uint16 addr_buttonnought = 0xc77c;
- static const uint16 addr_buttonnine = 0xc778;
- static const uint16 addr_buttoneight = 0xc774;
- static const uint16 addr_buttonseven = 0xc770;
- static const uint16 addr_buttonsix = 0xc76c;
- static const uint16 addr_buttonfive = 0xc768;
- static const uint16 addr_buttonfour = 0xc764;
- static const uint16 addr_buttonthree = 0xc760;
- static const uint16 addr_buttontwo = 0xc75c;
- static const uint16 addr_buttonone = 0xc758;
- static const uint16 addr_addtopresslist = 0xc754;
- static const uint16 addr_quitkey = 0xc750;
- static const uint16 addr_loadkeypad = 0xc74c;
- static const uint16 addr_entercode = 0xc748;
- static const uint16 addr_usewinch = 0xc744;
- static const uint16 addr_useplate = 0xc740;
- static const uint16 addr_usebuttona = 0xc73c;
- static const uint16 addr_useshield = 0xc738;
- static const uint16 addr_usegun = 0xc734;
- static const uint16 addr_usechurchgate = 0xc730;
- static const uint16 addr_usewall = 0xc72c;
- static const uint16 addr_edenscdplayer = 0xc728;
- static const uint16 addr_setuptimeduse = 0xc71c;
- static const uint16 addr_autoappear = 0xc70c;
- static const uint16 addr_switchryanoff = 0xc700;
- static const uint16 addr_switchryanon = 0xc6fc;
- static const uint16 addr_removefreeobject = 0xc6f4;
- static const uint16 addr_placefreeobject = 0xc6f0;
- static const uint16 addr_issetobonmap = 0xc6ec;
- static const uint16 addr_findpuztext = 0xc6e0;
- static const uint16 addr_showpuztext = 0xc6dc;
- static const uint16 addr_putbackobstuff = 0xc6d8;
- static const uint16 addr_checkinside = 0xc6d0;
- static const uint16 addr_isryanholding = 0xc6cc;
- static const uint16 addr_findexobject = 0xc6c8;
- static const uint16 addr_findsetobject = 0xc6c4;
- static const uint16 addr_selectob = 0xc6bc;
- static const uint16 addr_withwhat = 0xc6b8;
- static const uint16 addr_useelvdoor = 0xc6b4;
- static const uint16 addr_useaxe = 0xc6b0;
- static const uint16 addr_usecooker = 0xc6ac;
- static const uint16 addr_usestereo = 0xc6a8;
- static const uint16 addr_usekey = 0xc6a4;
- static const uint16 addr_useelevator5 = 0xc6a0;
- static const uint16 addr_useelevator2 = 0xc69c;
- static const uint16 addr_useelevator4 = 0xc698;
- static const uint16 addr_useelevator3 = 0xc694;
- static const uint16 addr_showfirstuse = 0xc690;
- static const uint16 addr_useelevator1 = 0xc68c;
- static const uint16 addr_usehandle = 0xc688;
- static const uint16 addr_usewire = 0xc684;
- static const uint16 addr_usehatch = 0xc680;
- static const uint16 addr_usecontrol = 0xc67c;
- static const uint16 addr_moneypoke = 0xc678;
- static const uint16 addr_lookatcard = 0xc674;
- static const uint16 addr_usecashcard = 0xc670;
- static const uint16 addr_usecardreader3 = 0xc66c;
- static const uint16 addr_usecardreader2 = 0xc668;
- static const uint16 addr_usecardreader1 = 0xc664;
- static const uint16 addr_showseconduse = 0xc660;
- static const uint16 addr_uselighter = 0xc65c;
- static const uint16 addr_usepoolreader = 0xc658;
- static const uint16 addr_calledensdlift = 0xc654;
- static const uint16 addr_calledenslift = 0xc650;
- static const uint16 addr_callhotellift = 0xc64c;
- static const uint16 addr_trapdoor = 0xc648;
- static const uint16 addr_grafittidoor = 0xc644;
- static const uint16 addr_openhoteldoor2 = 0xc640;
- static const uint16 addr_openhoteldoor = 0xc63c;
- static const uint16 addr_drawitall = 0xc638;
- static const uint16 addr_isitright = 0xc634;
- static const uint16 addr_opensarters = 0xc630;
- static const uint16 addr_openeden = 0xc62c;
- static const uint16 addr_openpoolboss = 0xc628;
- static const uint16 addr_openryan = 0xc624;
- static const uint16 addr_usebalcony = 0xc620;
- static const uint16 addr_usewindow = 0xc61c;
- static const uint16 addr_openyourneighbour = 0xc618;
- static const uint16 addr_nextcolon = 0xc614;
- static const uint16 addr_openlouis = 0xc610;
- static const uint16 addr_usedryer = 0xc60c;
- static const uint16 addr_opentvdoor = 0xc608;
- static const uint16 addr_usealtar = 0xc604;
- static const uint16 addr_usehole = 0xc600;
- static const uint16 addr_usechurchhole = 0xc5fc;
- static const uint16 addr_sitdowninbar = 0xc5f8;
- static const uint16 addr_wearshades = 0xc5f4;
- static const uint16 addr_wearwatch = 0xc5f0;
- static const uint16 addr_useopenbox = 0xc5ec;
- static const uint16 addr_userailing = 0xc5e8;
- static const uint16 addr_usecoveredbox = 0xc5e4;
- static const uint16 addr_useclearbox = 0xc5e0;
- static const uint16 addr_usecart = 0xc5dc;
- static const uint16 addr_useslab = 0xc5d8;
- static const uint16 addr_slabdoorf = 0xc5d4;
- static const uint16 addr_slabdoore = 0xc5d0;
- static const uint16 addr_slabdoorc = 0xc5cc;
- static const uint16 addr_slabdoord = 0xc5c8;
- static const uint16 addr_slabdoorb = 0xc5c4;
- static const uint16 addr_slabdoora = 0xc5c0;
- static const uint16 addr_useladderb = 0xc5bc;
- static const uint16 addr_useladder = 0xc5b8;
- static const uint16 addr_chewy = 0xc5b4;
- static const uint16 addr_useplinth = 0xc5b0;
- static const uint16 addr_usefullcart = 0xc5ac;
- static const uint16 addr_usepipe = 0xc5a8;
- static const uint16 addr_nothelderror = 0xc5a4;
- static const uint16 addr_usetrainer = 0xc5a0;
- static const uint16 addr_opentomb = 0xc59c;
- static const uint16 addr_hotelbell = 0xc598;
- static const uint16 addr_hotelcontrol = 0xc594;
- static const uint16 addr_playguitar = 0xc590;
- static const uint16 addr_runtap = 0xc58c;
- static const uint16 addr_wheelsound = 0xc588;
- static const uint16 addr_useobject = 0xc580;
- static const uint16 addr_delcurs = 0xc57c;
- static const uint16 addr_printcurs = 0xc578;
- static const uint16 addr_triggermessage = 0xc574;
- static const uint16 addr_processtrigger = 0xc570;
- static const uint16 addr_monmessage = 0xc56c;
- static const uint16 addr_showcurrentfile = 0xc568;
- static const uint16 addr_printlogo = 0xc564;
- static const uint16 addr_monitorlogo = 0xc560;
- static const uint16 addr_scrollmonitor = 0xc558;
- static const uint16 addr_parser = 0xc554;
- static const uint16 addr_searchforstring = 0xc550;
- static const uint16 addr_getkeyandlogo = 0xc54c;
- static const uint16 addr_dirfile = 0xc548;
- static const uint16 addr_read = 0xc544;
- static const uint16 addr_showkeys = 0xc540;
- static const uint16 addr_signon = 0xc53c;
- static const uint16 addr_searchforfiles = 0xc538;
- static const uint16 addr_dircom = 0xc534;
- static const uint16 addr_neterror = 0xc530;
- static const uint16 addr_execcommand = 0xc52c;
- static const uint16 addr_delchar = 0xc528;
- static const uint16 addr_makecaps = 0xc524;
- static const uint16 addr_input = 0xc520;
- static const uint16 addr_locklightoff = 0xc51c;
- static const uint16 addr_locklighton = 0xc518;
- static const uint16 addr_accesslightoff = 0xc514;
- static const uint16 addr_accesslighton = 0xc510;
- static const uint16 addr_powerlightoff = 0xc50c;
- static const uint16 addr_powerlighton = 0xc508;
- static const uint16 addr_randomaccess = 0xc504;
- static const uint16 addr_turnonpower = 0xc500;
- static const uint16 addr_lookininterface = 0xc4fc;
- static const uint16 addr_loadcart = 0xc4f8;
- static const uint16 addr_loadnews = 0xc4f4;
- static const uint16 addr_loadpersonal = 0xc4f0;
- static const uint16 addr_printoutermon = 0xc4ec;
- static const uint16 addr_usemon = 0xc4e8;
- static const uint16 addr_readcitypic = 0xc4e4;
- static const uint16 addr_readdesticon = 0xc4e0;
- static const uint16 addr_resetlocation = 0xc4dc;
- static const uint16 addr_setlocation = 0xc4d8;
- static const uint16 addr_getlocation = 0xc4d4;
- static const uint16 addr_destselect = 0xc4d0;
- static const uint16 addr_lastdest = 0xc4cc;
- static const uint16 addr_nextdest = 0xc4c8;
- static const uint16 addr_showarrows = 0xc4c4;
- static const uint16 addr_getdestinfo = 0xc4c0;
- static const uint16 addr_locationpic = 0xc4bc;
- static const uint16 addr_putundercentre = 0xc4b8;
- static const uint16 addr_getundercentre = 0xc4b4;
- static const uint16 addr_lookatplace = 0xc4b0;
- static const uint16 addr_showcity = 0xc4ac;
- static const uint16 addr_selectlocation = 0xc4a8;
- static const uint16 addr_newplace = 0xc4a4;
- static const uint16 addr_redes = 0xc4a0;
- static const uint16 addr_hangonpq = 0xc49c;
- static const uint16 addr_dosometalk = 0xc498;
- static const uint16 addr_moretalk = 0xc494;
- static const uint16 addr_getpersontext = 0xc490;
- static const uint16 addr_starttalk = 0xc48c;
- static const uint16 addr_getpersframe = 0xc488;
- static const uint16 addr_convicons = 0xc484;
- static const uint16 addr_talk = 0xc480;
- static const uint16 addr_getback1 = 0xc47c;
- static const uint16 addr_redrawmainscrn = 0xc478;
- static const uint16 addr_dolook = 0xc474;
- static const uint16 addr_look = 0xc470;
- static const uint16 addr_autolook = 0xc46c;
- static const uint16 addr_drawfloor = 0xc428;
- static const uint16 addr_blockget = 0xc424;
- static const uint16 addr_deleteextext = 0xc420;
- static const uint16 addr_deleteexframe = 0xc41c;
- static const uint16 addr_deleteexobject = 0xc418;
- static const uint16 addr_purgeanitem = 0xc414;
- static const uint16 addr_emergencypurge = 0xc410;
- static const uint16 addr_purgealocation = 0xc40c;
- static const uint16 addr_transfertext = 0xc404;
- static const uint16 addr_transfercontoex = 0xc400;
- static const uint16 addr_pickupconts = 0xc3fc;
- static const uint16 addr_transfertoex = 0xc3f8;
- static const uint16 addr_outofopen = 0xc3f4;
- static const uint16 addr_checkobjectsize = 0xc3f0;
- static const uint16 addr_errormessage3 = 0xc3ec;
- static const uint16 addr_errormessage2 = 0xc3e8;
- static const uint16 addr_errormessage1 = 0xc3e4;
- static const uint16 addr_useopened = 0xc3e0;
- static const uint16 addr_selectopenob = 0xc3dc;
- static const uint16 addr_removeobfrominv = 0xc3d8;
- static const uint16 addr_cantdrop = 0xc3d0;
- static const uint16 addr_droperror = 0xc3cc;
- static const uint16 addr_dropobject = 0xc3c8;
- static const uint16 addr_findopenpos = 0xc3c4;
- static const uint16 addr_findinvpos = 0xc3c0;
- static const uint16 addr_getsetad = 0xc3bc;
- static const uint16 addr_getopenedsize = 0xc3b8;
- static const uint16 addr_getanyaddir = 0xc3b4;
- static const uint16 addr_getanyad = 0xc3b0;
- static const uint16 addr_geteitherad = 0xc3ac;
- static const uint16 addr_getexad = 0xc3a8;
- static const uint16 addr_getfreead = 0xc3a4;
- static const uint16 addr_outofinv = 0xc3a0;
- static const uint16 addr_intoinv = 0xc398;
- static const uint16 addr_swapwithopen = 0xc394;
- static const uint16 addr_swapwithinv = 0xc390;
- static const uint16 addr_reexfromopen = 0xc38c;
- static const uint16 addr_reexfrominv = 0xc388;
- static const uint16 addr_examinventory = 0xc384;
- static const uint16 addr_setpickup = 0xc380;
- static const uint16 addr_inventory = 0xc37c;
- static const uint16 addr_searchforsame = 0xc374;
- static const uint16 addr_getobtextstart = 0xc370;
- static const uint16 addr_obsthatdothings = 0xc36c;
- static const uint16 addr_additionaltext = 0xc368;
- static const uint16 addr_describeob = 0xc364;
- static const uint16 addr_examicon = 0xc35c;
- static const uint16 addr_openob = 0xc354;
- static const uint16 addr_openinv = 0xc34c;
- static const uint16 addr_incryanpage = 0xc348;
- static const uint16 addr_getbackfromob = 0xc344;
- static const uint16 addr_makemainscreen = 0xc340;
- static const uint16 addr_examineob = 0xc33c;
- static const uint16 addr_findallopen = 0xc32c;
- static const uint16 addr_fillopen = 0xc324;
- static const uint16 addr_monprint = 0xc314;
- static const uint16 addr_realcredits = 0xc2f8;
- static const uint16 addr_set16colpalette = 0xc2f4;
- static const uint16 addr_mode640x480 = 0xc2f0;
- static const uint16 addr_loadintroroom = 0xc2ec;
- static const uint16 addr_runendseq = 0xc2e8;
- static const uint16 addr_runintroseq = 0xc2e4;
- static const uint16 addr_intro = 0xc2e0;
- static const uint16 addr_hangone = 0xc2dc;
- static const uint16 addr_biblequote = 0xc2d8;
- static const uint16 addr_credits = 0xc2d4;
- static const uint16 addr_gettingshot = 0xc2d0;
- static const uint16 addr_showmonk = 0xc2cc;
- static const uint16 addr_monkspeaking = 0xc2c8;
- static const uint16 addr_endgame = 0xc2c4;
- static const uint16 addr_titles = 0xc2c0;
- static const uint16 addr_initialmoncols = 0xc2bc;
- static const uint16 addr_fadeupyellows = 0xc2b8;
- static const uint16 addr_fadeupmonfirst = 0xc2b4;
- static const uint16 addr_fadeupmon = 0xc2b0;
- static const uint16 addr_fadedownmon = 0xc2ac;
- static const uint16 addr_dumpcurrent = 0xc2a8;
- static const uint16 addr_allpalette = 0xc2a4;
- static const uint16 addr_paltoendpal = 0xc2a0;
- static const uint16 addr_startpaltoend = 0xc29c;
- static const uint16 addr_endpaltostart = 0xc298;
- static const uint16 addr_paltostartpal = 0xc294;
- static const uint16 addr_showgroup = 0xc290;
- static const uint16 addr_greyscalesum = 0xc28c;
- static const uint16 addr_fadecalculation = 0xc288;
- static const uint16 addr_rollem = 0xc284;
- static const uint16 addr_rollendcredits2 = 0xc280;
- static const uint16 addr_showgun = 0xc27c;
- static const uint16 addr_clearstartpal = 0xc278;
- static const uint16 addr_fadescreendowns = 0xc274;
- static const uint16 addr_fadescreendown = 0xc270;
- static const uint16 addr_fadescreenuphalf = 0xc26c;
- static const uint16 addr_fadescreendownhalf = 0xc268;
- static const uint16 addr_fadescreenups = 0xc264;
- static const uint16 addr_fadefromwhite = 0xc260;
- static const uint16 addr_fadetowhite = 0xc25c;
- static const uint16 addr_fadescreenup = 0xc258;
- static const uint16 addr_clearpalette = 0xc254;
- static const uint16 addr_clearendpal = 0xc250;
- static const uint16 addr_dofade = 0xc24c;
- static const uint16 addr_fadedos = 0xc248;
- static const uint16 addr_transfermap = 0xc244;
- static const uint16 addr_doshake = 0xc20c;
- static const uint16 addr_vsync = 0xc208;
- static const uint16 addr_createpanel2 = 0xc200;
- static const uint16 addr_createpanel = 0xc1fc;
- static const uint16 addr_setmode = 0xc1dc;
- static const uint16 addr_loadpalfromiff = 0xc1d8;
- static const uint16 addr_showpcx = 0xc1cc;
- static const uint16 addr_deleverything = 0xc1c0;
- static const uint16 addr_reconstruct = 0xc1ac;
- static const uint16 addr_soundonreels = 0xc1a8;
- static const uint16 addr_reelsonscreen = 0xc1a0;
- static const uint16 addr_constant = 0xc184;
- static const uint16 addr_steady = 0xc180;
- static const uint16 addr_random = 0xc17c;
- static const uint16 addr_liftnoise = 0xc178;
- static const uint16 addr_backobject = 0xc170;
- static const uint16 addr_splitintolines = 0xc164;
- static const uint16 addr_initrain = 0xc160;
- static const uint16 addr_reminders = 0xc15c;
- static const uint16 addr_adjustright = 0xc158;
- static const uint16 addr_adjustleft = 0xc154;
- static const uint16 addr_adjustup = 0xc150;
- static const uint16 addr_adjustdown = 0xc14c;
- static const uint16 addr_checkforexit = 0xc148;
- static const uint16 addr_mainman = 0xc138;
- static const uint16 addr_checkspeed = 0xc110;
- static const uint16 addr_train = 0xc104;
- static const uint16 addr_sparky = 0xc100;
- static const uint16 addr_copper = 0xc0fc;
- static const uint16 addr_advisor = 0xc0f8;
- static const uint16 addr_drunk = 0xc0f4;
- static const uint16 addr_textformonk = 0xc0f0;
- static const uint16 addr_textforend = 0xc0ec;
- static const uint16 addr_priesttext = 0xc0e8;
- static const uint16 addr_madman = 0xc0dc;
- static const uint16 addr_madmanstelly = 0xc0d8;
- static const uint16 addr_priest = 0xc0d4;
- static const uint16 addr_rollendcredits = 0xc0d0;
- static const uint16 addr_endgameseq = 0xc0cc;
- static const uint16 addr_monkandryan = 0xc0c8;
- static const uint16 addr_intro3text = 0xc0c4;
- static const uint16 addr_intro2text = 0xc0c0;
- static const uint16 addr_intro1text = 0xc0bc;
- static const uint16 addr_monks2text = 0xc0b8;
- static const uint16 addr_handclap = 0xc0b4;
- static const uint16 addr_intromonks2 = 0xc0b0;
- static const uint16 addr_intromonks1 = 0xc0ac;
- static const uint16 addr_intromagic3 = 0xc0a8;
- static const uint16 addr_intromagic2 = 0xc0a4;
- static const uint16 addr_gates = 0xc0a0;
- static const uint16 addr_candles2 = 0xc09c;
- static const uint16 addr_candles = 0xc098;
- static const uint16 addr_intromagic1 = 0xc094;
- static const uint16 addr_smallcandle = 0xc090;
- static const uint16 addr_candles1 = 0xc08c;
- static const uint16 addr_keeper = 0xc088;
- static const uint16 addr_carparkdrip = 0xc084;
- static const uint16 addr_sparkydrip = 0xc080;
- static const uint16 addr_gamer = 0xc07c;
- static const uint16 addr_bossman = 0xc078;
- static const uint16 addr_heavy = 0xc074;
- static const uint16 addr_security = 0xc070;
- static const uint16 addr_poolguard = 0xc06c;
- static const uint16 addr_businessman = 0xc068;
- static const uint16 addr_aide = 0xc064;
- static const uint16 addr_mugger = 0xc060;
- static const uint16 addr_helicopter = 0xc05c;
- static const uint16 addr_rockstar = 0xc058;
- static const uint16 addr_soldier1 = 0xc054;
- static const uint16 addr_interviewer = 0xc050;
- static const uint16 addr_barwoman = 0xc04c;
- static const uint16 addr_othersmoker = 0xc048;
- static const uint16 addr_bartender = 0xc044;
- static const uint16 addr_drinker = 0xc040;
- static const uint16 addr_tattooman = 0xc03c;
- static const uint16 addr_mansatstill = 0xc038;
- static const uint16 addr_manasleep2 = 0xc034;
- static const uint16 addr_louischair = 0xc030;
- static const uint16 addr_louis = 0xc02c;
- static const uint16 addr_femalefan = 0xc028;
- static const uint16 addr_malefan = 0xc024;
- static const uint16 addr_edeninbath = 0xc020;
- static const uint16 addr_eden = 0xc01c;
- static const uint16 addr_manasleep = 0xc018;
- static const uint16 addr_attendant = 0xc014;
- static const uint16 addr_smokebloke = 0xc010;
- static const uint16 addr_receptionist = 0xc00c;
- static const uint16 addr_foghornsound = 0xc008;
- static const uint16 addr_intromusic = 0xc004;
- static const uint16 addr_alleybarksound = 0xc000;
- static const uint16 offset_quitlist = 0x0a84;
- static const uint16 offset_savelist = 0x0f44;
- static const uint16 offset_mainlist = 0x1402;
- static const uint16 offset_gameerror8 = 0x113f;
- static const uint16 offset_gameerror5 = 0x1074;
- static const uint16 offset_error2patch = 0x0ff6;
- static const uint16 offset_openchangesize = 0x0a1c;
- static const uint16 offset_keys = 0x0b14;
- static const uint16 offset_mainlist2 = 0x1440;
- static const uint16 offset_gameerror2 = 0x0fb2;
- static const uint16 offset_loadlist = 0x0ef0;
- static const uint16 offset_gameerror6 = 0x10be;
- static const uint16 offset_speechfile = 0x13f1;
- static const uint16 offset_atmospherelist = 0x147e;
- static const uint16 offset_gameerror4 = 0x1037;
- static const uint16 offset_gameerror1 = 0x0f6e;
- static const uint16 offset_examlist = 0x09be;
- static const uint16 offset_gameinfo = 0x1170;
- static const uint16 offset_opslist = 0x0ec6;
- static const uint16 offset_invlist1 = 0x09fc;
- static const uint16 offset_money2poke = 0x0d97;
- static const uint16 offset_talklist = 0x0a64;
- static const uint16 offset_menulist = 0x0e1e;
- static const uint16 offset_comlist = 0x0ad8;
- static const uint16 offset_withlist1 = 0x0a3a;
- static const uint16 offset_money1poke = 0x0d92;
- static const uint16 offset_gameerror7 = 0x1104;
- static const uint16 offset_discopslist = 0x0f1a;
- static const uint16 offset_commandline = 0x16d7;
- static const uint16 offset_destlist = 0x0a9a;
- static const uint16 offset_shaketable = 0x06af;
- static const uint16 offset_error6patch = 0x10fe;
- static const uint16 offset_keybuffer = 0x1718;
- static const uint16 offset_speechfilename = 0x13eb;
- static const uint16 offset_rootdir = 0x0b8c;
- static const uint16 offset_gameerror3 = 0x1003;
- static const uint16 offset_rainlocations = 0x0459;
- static const uint16 offset_diarylist = 0x0e9c;
- static const uint16 offset_decidelist = 0x13c1;
- static const uint16 offset_symbollist = 0x0e5e;
- static const uint16 offset_folderlist = 0x0e34;
- static const uint16 offset_facelist = 0x0451;
- static const uint16 offset_operand1 = 0x0b7e;
- static const uint16 offset_keypadlist = 0x0d9a;
- static const uint16 kStartvars = 0;
- static const uint16 kProgresspoints = 1;
- static const uint16 kWatchon = 2;
- static const uint16 kShadeson = 3;
- static const uint16 kSecondcount = 4;
- static const uint16 kMinutecount = 5;
- static const uint16 kHourcount = 6;
- static const uint16 kZoomon = 7;
- static const uint16 kLocation = 8;
- static const uint16 kExpos = 9;
- static const uint16 kExframepos = 10;
- static const uint16 kExtextpos = 12;
- static const uint16 kCard1money = 14;
- static const uint16 kListpos = 16;
- static const uint16 kRyanpage = 18;
- static const uint16 kWatchingtime = 19;
- static const uint16 kReeltowatch = 21;
- static const uint16 kEndwatchreel = 23;
- static const uint16 kSpeedcount = 25;
- static const uint16 kWatchspeed = 26;
- static const uint16 kReeltohold = 27;
- static const uint16 kEndofholdreel = 29;
- static const uint16 kWatchmode = 31;
- static const uint16 kDestafterhold = 32;
- static const uint16 kNewsitem = 33;
- static const uint16 kLiftflag = 34;
- static const uint16 kLiftpath = 35;
- static const uint16 kLockstatus = 36;
- static const uint16 kDoorpath = 37;
- static const uint16 kCounttoopen = 38;
- static const uint16 kCounttoclose = 39;
- static const uint16 kRockstardead = 40;
- static const uint16 kGeneraldead = 41;
- static const uint16 kSartaindead = 42;
- static const uint16 kAidedead = 43;
- static const uint16 kBeenmugged = 44;
- static const uint16 kGunpassflag = 45;
- static const uint16 kCanmovealtar = 46;
- static const uint16 kTalkedtoattendant = 47;
- static const uint16 kTalkedtosparky = 48;
- static const uint16 kTalkedtoboss = 49;
- static const uint16 kTalkedtorecep = 50;
- static const uint16 kCardpassflag = 51;
- static const uint16 kMadmanflag = 52;
- static const uint16 kKeeperflag = 53;
- static const uint16 kLasttrigger = 54;
- static const uint16 kMandead = 55;
- static const uint16 kSeed = 56;
- static const uint16 kNeedtotravel = 59;
- static const uint16 kThroughdoor = 60;
- static const uint16 kNewobs = 61;
- static const uint16 kRyanon = 62;
- static const uint16 kCombatcount = 63;
- static const uint16 kLastweapon = 64;
- static const uint16 kDreamnumber = 65;
- static const uint16 kRoomafterdream = 66;
- static const uint16 kShakecounter = 67;
- static const uint16 kSpeechcount = 68;
- static const uint16 kCharshift = 69;
- static const uint16 kKerning = 71;
- static const uint16 kBrightness = 72;
- static const uint16 kRoomloaded = 73;
- static const uint16 kDidzoom = 74;
- static const uint16 kLinespacing = 75;
- static const uint16 kTextaddressx = 77;
- static const uint16 kTextaddressy = 79;
- static const uint16 kTextlen = 81;
- static const uint16 kLastxpos = 82;
- static const uint16 kIcontop = 84;
- static const uint16 kIconleft = 86;
- static const uint16 kItemframe = 88;
- static const uint16 kItemtotran = 89;
- static const uint16 kRoomad = 90;
- static const uint16 kOldsubject = 92;
- static const uint16 kWithobject = 94;
- static const uint16 kWithtype = 95;
- static const uint16 kLookcounter = 96;
- static const uint16 kCommand = 98;
- static const uint16 kCommandtype = 99;
- static const uint16 kOldcommandtype = 100;
- static const uint16 kObjecttype = 101;
- static const uint16 kGetback = 102;
- static const uint16 kInvopen = 103;
- static const uint16 kMainmode = 104;
- static const uint16 kPickup = 105;
- static const uint16 kLastinvpos = 106;
- static const uint16 kExamagain = 107;
- static const uint16 kNewtextline = 108;
- static const uint16 kOpenedob = 109;
- static const uint16 kOpenedtype = 110;
- static const uint16 kOldmapadx = 111;
- static const uint16 kOldmapady = 113;
- static const uint16 kMapadx = 115;
- static const uint16 kMapady = 117;
- static const uint16 kMapoffsetx = 119;
- static const uint16 kMapoffsety = 121;
- static const uint16 kMapxstart = 123;
- static const uint16 kMapystart = 125;
- static const uint16 kMapxsize = 127;
- static const uint16 kMapysize = 128;
- static const uint16 kHavedoneobs = 129;
- static const uint16 kManisoffscreen = 130;
- static const uint16 kRainspace = 131;
- static const uint16 kFacing = 132;
- static const uint16 kLeavedirection = 133;
- static const uint16 kTurntoface = 134;
- static const uint16 kTurndirection = 135;
- static const uint16 kMaintimer = 136;
- static const uint16 kIntrocount = 138;
- static const uint16 kArrowad = 139;
- static const uint16 kCurrentkey = 141;
- static const uint16 kOldkey = 142;
- static const uint16 kUseddirection = 143;
- static const uint16 kCurrentkey2 = 144;
- static const uint16 kTimercount = 145;
- static const uint16 kOldtimercount = 146;
- static const uint16 kMapx = 147;
- static const uint16 kMapy = 148;
- static const uint16 kNewscreen = 149;
- static const uint16 kRyanx = 150;
- static const uint16 kRyany = 151;
- static const uint16 kLastflag = 152;
- static const uint16 kLastflagex = 153;
- static const uint16 kFlagx = 154;
- static const uint16 kFlagy = 155;
- static const uint16 kCurrentex = 156;
- static const uint16 kCurrentfree = 157;
- static const uint16 kCurrentframe = 158;
- static const uint16 kFramesad = 160;
- static const uint16 kDataad = 162;
- static const uint16 kFrsegment = 164;
- static const uint16 kObjectx = 166;
- static const uint16 kObjecty = 168;
- static const uint16 kOffsetx = 170;
- static const uint16 kOffsety = 172;
- static const uint16 kSavesize = 174;
- static const uint16 kSavesource = 176;
- static const uint16 kSavex = 178;
- static const uint16 kSavey = 179;
- static const uint16 kCurrentob = 180;
- static const uint16 kPrioritydep = 181;
- static const uint16 kDestpos = 182;
- static const uint16 kReallocation = 183;
- static const uint16 kRoomnum = 184;
- static const uint16 kNowinnewroom = 185;
- static const uint16 kResetmanxy = 186;
- static const uint16 kNewlocation = 187;
- static const uint16 kAutolocation = 188;
- static const uint16 kMustload = 189;
- static const uint16 kAnswered = 190;
- static const uint16 kSaidno = 191;
- static const uint16 kDoorcheck1 = 192;
- static const uint16 kDoorcheck2 = 193;
- static const uint16 kDoorcheck3 = 194;
- static const uint16 kDoorcheck4 = 195;
- static const uint16 kMousex = 196;
- static const uint16 kMousey = 198;
- static const uint16 kMousebutton = 200;
- static const uint16 kMousebutton1 = 202;
- static const uint16 kMousebutton2 = 204;
- static const uint16 kMousebutton3 = 206;
- static const uint16 kMousebutton4 = 208;
- static const uint16 kOldbutton = 210;
- static const uint16 kOldx = 212;
- static const uint16 kOldy = 214;
- static const uint16 kLastbutton = 216;
- static const uint16 kOldpointerx = 218;
- static const uint16 kOldpointery = 220;
- static const uint16 kDelherex = 222;
- static const uint16 kDelherey = 224;
- static const uint16 kPointerxs = 226;
- static const uint16 kPointerys = 227;
- static const uint16 kDelxs = 228;
- static const uint16 kDelys = 229;
- static const uint16 kPointerframe = 230;
- static const uint16 kPointerpower = 231;
- static const uint16 kAuxpointerframe = 232;
- static const uint16 kPointermode = 233;
- static const uint16 kPointerspeed = 234;
- static const uint16 kPointercount = 235;
- static const uint16 kInmaparea = 236;
- static const uint16 kReelpointer = 237;
- static const uint16 kSlotdata = 239;
- static const uint16 kThisslot = 240;
- static const uint16 kSlotflags = 241;
- static const uint16 kTakeoff = 242;
- static const uint16 kTalkmode = 244;
- static const uint16 kTalkpos = 245;
- static const uint16 kCharacter = 246;
- static const uint16 kPersondata = 247;
- static const uint16 kTalknum = 249;
- static const uint16 kNumberinroom = 250;
- static const uint16 kCurrentcel = 251;
- static const uint16 kOldselection = 252;
- static const uint16 kStopwalking = 253;
- static const uint16 kMouseon = 254;
- static const uint16 kPlayed = 255;
- static const uint16 kTimer1 = 257;
- static const uint16 kTimer2 = 258;
- static const uint16 kTimer3 = 259;
- static const uint16 kWholetimer = 260;
- static const uint16 kTimer1to = 262;
- static const uint16 kTimer2to = 263;
- static const uint16 kTimer3to = 264;
- static const uint16 kWatchdump = 265;
- static const uint16 kCurrentset = 266;
- static const uint16 kLogonum = 268;
- static const uint16 kOldlogonum = 269;
- static const uint16 kNewlogonum = 270;
- static const uint16 kNetseg = 271;
- static const uint16 kNetpoint = 273;
- static const uint16 kKeynum = 275;
- static const uint16 kCursorstate = 276;
- static const uint16 kPressed = 277;
- static const uint16 kPresspointer = 278;
- static const uint16 kGraphicpress = 280;
- static const uint16 kPresscount = 281;
- static const uint16 kKeypadax = 282;
- static const uint16 kKeypadcx = 284;
- static const uint16 kLightcount = 286;
- static const uint16 kFolderpage = 287;
- static const uint16 kDiarypage = 288;
- static const uint16 kMenucount = 289;
- static const uint16 kSymboltopx = 290;
- static const uint16 kSymboltopnum = 291;
- static const uint16 kSymboltopdir = 292;
- static const uint16 kSymbolbotx = 293;
- static const uint16 kSymbolbotnum = 294;
- static const uint16 kSymbolbotdir = 295;
- static const uint16 kSymboltolight = 296;
- static const uint16 kSymbol1 = 297;
- static const uint16 kSymbol2 = 298;
- static const uint16 kSymbol3 = 299;
- static const uint16 kSymbolnum = 300;
- static const uint16 kDumpx = 301;
- static const uint16 kDumpy = 303;
- static const uint16 kWalkandexam = 305;
- static const uint16 kWalkexamtype = 306;
- static const uint16 kWalkexamnum = 307;
- static const uint16 kCursloc = 308;
- static const uint16 kCurslocx = 310;
- static const uint16 kCurslocy = 312;
- static const uint16 kCurpos = 314;
- static const uint16 kMonadx = 316;
- static const uint16 kMonady = 318;
- static const uint16 kGotfrom = 320;
- static const uint16 kMonsource = 322;
- static const uint16 kNumtodo = 324;
- static const uint16 kTimecount = 326;
- static const uint16 kCounttotimed = 328;
- static const uint16 kTimedseg = 330;
- static const uint16 kTimedoffset = 332;
- static const uint16 kTimedy = 334;
- static const uint16 kTimedx = 335;
- static const uint16 kNeedtodumptimed = 336;
- static const uint16 kHandle = 337;
- static const uint16 kLoadingorsave = 339;
- static const uint16 kCurrentslot = 340;
- static const uint16 kCursorpos = 341;
- static const uint16 kColourpos = 342;
- static const uint16 kFadedirection = 343;
- static const uint16 kNumtofade = 344;
- static const uint16 kFadecount = 345;
- static const uint16 kAddtogreen = 346;
- static const uint16 kAddtored = 347;
- static const uint16 kAddtoblue = 348;
- static const uint16 kLastsoundreel = 349;
- static const uint16 kSoundbuffer = 351;
- static const uint16 kSoundbufferad = 353;
- static const uint16 kSoundbufferpage = 355;
- static const uint16 kSoundtimes = 356;
- static const uint16 kNeedsoundbuff = 357;
- static const uint16 kOldint9seg = 358;
- static const uint16 kOldint9add = 360;
- static const uint16 kOldint8seg = 362;
- static const uint16 kOldint8add = 364;
- static const uint16 kOldsoundintseg = 366;
- static const uint16 kOldsoundintadd = 368;
- static const uint16 kSoundbaseadd = 370;
- static const uint16 kDsp_status = 372;
- static const uint16 kDsp_write = 374;
- static const uint16 kDmaaddress = 376;
- static const uint16 kSoundint = 377;
- static const uint16 kSounddmachannel = 378;
- static const uint16 kSampleplaying = 379;
- static const uint16 kTestresult = 380;
- static const uint16 kCurrentirq = 381;
- static const uint16 kSpeechloaded = 382;
- static const uint16 kSpeechlength = 383;
- static const uint16 kVolume = 385;
- static const uint16 kVolumeto = 386;
- static const uint16 kVolumedirection = 387;
- static const uint16 kVolumecount = 388;
- static const uint16 kPlayblock = 389;
- static const uint16 kWongame = 390;
- static const uint16 kLasthardkey = 391;
- static const uint16 kBufferin = 392;
- static const uint16 kBufferout = 394;
- static const uint16 kExtras = 396;
- static const uint16 kWorkspace = 398;
- static const uint16 kMapstore = 400;
- static const uint16 kCharset1 = 402;
- static const uint16 kTempcharset = 404;
- static const uint16 kIcons1 = 406;
- static const uint16 kIcons2 = 408;
- static const uint16 kBuffers = 410;
- static const uint16 kMainsprites = 412;
- static const uint16 kBackdrop = 414;
- static const uint16 kMapdata = 416;
- static const uint16 kSounddata = 418;
- static const uint16 kSounddata2 = 420;
- static const uint16 kRecordspace = 422;
- static const uint16 kFreedat = 424;
- static const uint16 kSetdat = 426;
- static const uint16 kReel1 = 428;
- static const uint16 kReel2 = 430;
- static const uint16 kReel3 = 432;
- static const uint16 kRoomdesc = 434;
- static const uint16 kFreedesc = 436;
- static const uint16 kSetdesc = 438;
- static const uint16 kBlockdesc = 440;
- static const uint16 kSetframes = 442;
- static const uint16 kFreeframes = 444;
- static const uint16 kPeople = 446;
- static const uint16 kReels = 448;
- static const uint16 kCommandtext = 450;
- static const uint16 kPuzzletext = 452;
- static const uint16 kTraveltext = 454;
- static const uint16 kTempgraphics = 456;
- static const uint16 kTempgraphics2 = 458;
- static const uint16 kTempgraphics3 = 460;
- static const uint16 kTempsprites = 462;
- static const uint16 kTextfile1 = 464;
- static const uint16 kTextfile2 = 466;
- static const uint16 kTextfile3 = 468;
- static const uint16 kBlinkframe = 470;
- static const uint16 kBlinkcount = 471;
- static const uint16 kReasseschanges = 472;
- static const uint16 kPointerspath = 473;
- static const uint16 kManspath = 474;
- static const uint16 kPointerfirstpath = 475;
- static const uint16 kFinaldest = 476;
- static const uint16 kDestination = 477;
- static const uint16 kLinestartx = 478;
- static const uint16 kLinestarty = 480;
- static const uint16 kLineendx = 482;
- static const uint16 kLineendy = 484;
- static const uint16 kIncrement1 = 486;
- static const uint16 kIncrement2 = 488;
- static const uint16 kLineroutine = 490;
- static const uint16 kLinepointer = 491;
- static const uint16 kLinedirection = 492;
- static const uint16 kLinelength = 493;
- static const uint16 kLiftsoundcount = 494;
- static const uint16 kEmmhandle = 495;
- static const uint16 kEmmpageframe = 497;
- static const uint16 kEmmhardwarepage = 499;
- static const uint16 kCh0emmpage = 500;
- static const uint16 kCh0offset = 502;
- static const uint16 kCh0blockstocopy = 504;
- static const uint16 kCh0playing = 506;
- static const uint16 kCh0repeat = 507;
- static const uint16 kCh0oldemmpage = 508;
- static const uint16 kCh0oldoffset = 510;
- static const uint16 kCh0oldblockstocopy = 512;
- static const uint16 kCh1playing = 514;
- static const uint16 kCh1emmpage = 515;
- static const uint16 kCh1offset = 517;
- static const uint16 kCh1blockstocopy = 519;
- static const uint16 kCh1blocksplayed = 521;
- static const uint16 kSoundbufferwrite = 523;
- static const uint16 kSoundemmpage = 525;
- static const uint16 kSpeechemmpage = 527;
- static const uint16 kCurrentsample = 529;
- static const uint16 kRoomssample = 530;
- static const uint16 kGameerror = 531;
- static const uint16 kHowmuchalloc = 532;
- static const uint16 kReelroutines = 534;
- static const uint16 kReelcalls = 991;
- static const uint16 kRoombyroom = 1214;
- static const uint16 kR0 = 1326;
- static const uint16 kR1 = 1327;
- static const uint16 kR2 = 1331;
- static const uint16 kR6 = 1350;
- static const uint16 kR8 = 1357;
- static const uint16 kR9 = 1373;
- static const uint16 kR10 = 1380;
- static const uint16 kR11 = 1384;
- static const uint16 kR12 = 1388;
- static const uint16 kR13 = 1392;
- static const uint16 kR14 = 1405;
- static const uint16 kR20 = 1439;
- static const uint16 kR22 = 1461;
- static const uint16 kR23 = 1492;
- static const uint16 kR25 = 1505;
- static const uint16 kR26 = 1527;
- static const uint16 kR27 = 1549;
- static const uint16 kR28 = 1574;
- static const uint16 kR29 = 1593;
- static const uint16 kR45 = 1609;
- static const uint16 kR46 = 1616;
- static const uint16 kR47 = 1653;
- static const uint16 kR52 = 1666;
- static const uint16 kR53 = 1670;
- static const uint16 kR55 = 1677;
- static const uint16 kSpritename1 = 1819;
- static const uint16 kSpritename3 = 1832;
- static const uint16 kIdname = 1845;
- static const uint16 kCharacterset1 = 1857;
- static const uint16 kCharacterset2 = 1870;
- static const uint16 kCharacterset3 = 1883;
- static const uint16 kSamplename = 1896;
- static const uint16 kBasicsample = 1909;
- static const uint16 kIcongraphics0 = 1922;
- static const uint16 kIcongraphics1 = 1935;
- static const uint16 kExtragraphics1 = 1948;
- static const uint16 kIcongraphics8 = 1961;
- static const uint16 kMongraphicname = 1974;
- static const uint16 kMongraphics2 = 1987;
- static const uint16 kCityname = 2000;
- static const uint16 kTravelgraphic1 = 2013;
- static const uint16 kTravelgraphic2 = 2026;
- static const uint16 kDiarygraphic = 2039;
- static const uint16 kMonitorfile1 = 2052;
- static const uint16 kMonitorfile2 = 2065;
- static const uint16 kMonitorfile10 = 2078;
- static const uint16 kMonitorfile11 = 2091;
- static const uint16 kMonitorfile12 = 2104;
- static const uint16 kMonitorfile13 = 2117;
- static const uint16 kMonitorfile20 = 2130;
- static const uint16 kMonitorfile21 = 2143;
- static const uint16 kMonitorfile22 = 2156;
- static const uint16 kMonitorfile23 = 2169;
- static const uint16 kMonitorfile24 = 2182;
- static const uint16 kFoldertext = 2195;
- static const uint16 kDiarytext = 2208;
- static const uint16 kPuzzletextname = 2221;
- static const uint16 kTraveltextname = 2234;
- static const uint16 kIntrotextname = 2247;
- static const uint16 kEndtextname = 2260;
- static const uint16 kCommandtextname = 2273;
- static const uint16 kVolumetabname = 2286;
- static const uint16 kFoldergraphic1 = 2299;
- static const uint16 kFoldergraphic2 = 2312;
- static const uint16 kFoldergraphic3 = 2325;
- static const uint16 kSymbolgraphic = 2338;
- static const uint16 kGungraphic = 2351;
- static const uint16 kMonkface = 2364;
- static const uint16 kTitle0graphics = 2377;
- static const uint16 kTitle1graphics = 2390;
- static const uint16 kTitle2graphics = 2403;
- static const uint16 kTitle3graphics = 2416;
- static const uint16 kTitle4graphics = 2429;
- static const uint16 kTitle5graphics = 2442;
- static const uint16 kTitle6graphics = 2455;
- static const uint16 kTitle7graphics = 2468;
- static const uint16 kPalettescreen = 2481;
- static const uint16 kCurrentfile = 2970;
- static const uint16 kDmaaddresses = 5118;
- static const uint16 kFileheader = 6091;
- static const uint16 kFiledata = 6141;
- static const uint16 kExtradata = 6181;
- static const uint16 kRoomdata = 6187;
- static const uint16 kMadeuproomdat = 7979;
- static const uint16 kRoomscango = 8011;
- static const uint16 kRoompics = 8027;
- static const uint16 kOplist = 8042;
- static const uint16 kInputline = 8045;
- static const uint16 kLinedata = 8173;
- static const uint16 kPresslist = 8573;
- static const uint16 kSavenames = 8579;
- static const uint16 kSavefiles = 8698;
- static const uint16 kRecname = 8789;
- static const uint16 kQuitrequested = 8802;
- static const uint16 kSubtitles = 8803;
- static const uint16 kForeignrelease = 8804;
- static const uint16 kStak = 8805;
- static const uint16 kBlocktextdat = (0);
- static const uint16 kPersonframes = (0);
- static const uint16 kDebuglevel1 = (0);
- static const uint16 kDebuglevel2 = (0);
- static const uint16 kPlayback = (0);
- static const uint16 kMap = (0);
- static const uint16 kSettextdat = (0);
- static const uint16 kSpanish = (0);
- static const uint16 kFramedata = (0);
- static const uint16 kRecording = (0);
- static const uint16 kFlags = (0);
- static const uint16 kGerman = (0);
- static const uint16 kTextunder = (0);
- static const uint16 kPathdata = (0);
- static const uint16 kDemo = (0);
- static const uint16 kExframedata = (0);
- static const uint16 kIntextdat = (0);
- static const uint16 kFreetextdat = (0);
- static const uint16 kFrframedata = (0);
- static const uint16 kSettext = (0+(130*2));
- static const uint16 kOpeninvlist = (0+(228*13));
- static const uint16 kRyaninvlist = (0+(228*13)+32);
- static const uint16 kPointerback = (0+(228*13)+32+60);
- static const uint16 kMapflags = (0+(228*13)+32+60+(32*32));
- static const uint16 kStartpal = (0+(228*13)+32+60+(32*32)+(11*10*3));
- static const uint16 kEndpal = (0+(228*13)+32+60+(32*32)+(11*10*3)+768);
- static const uint16 kMaingamepal = (0+(228*13)+32+60+(32*32)+(11*10*3)+768+768);
- static const uint16 kSpritetable = (0+(228*13)+32+60+(32*32)+(11*10*3)+768+768+768);
- static const uint16 kSetlist = (0+(228*13)+32+60+(32*32)+(11*10*3)+768+768+768+(32*32));
- static const uint16 kFreelist = (0+(228*13)+32+60+(32*32)+(11*10*3)+768+768+768+(32*32)+(128*5));
- static const uint16 kExlist = (0+(228*13)+32+60+(32*32)+(11*10*3)+768+768+768+(32*32)+(128*5)+(80*5));
- static const uint16 kPeoplelist = (0+(228*13)+32+60+(32*32)+(11*10*3)+768+768+768+(32*32)+(128*5)+(80*5)+(100*5));
- static const 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));
- static const 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));
- static const 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));
- static const 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));
- static const 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));
- static const 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));
- static const 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);
- static const 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);
- static const uint16 kReellist = (0+(36*144));
- static const uint16 kIntext = (0+(38*2));
- static const uint16 kLengthofmap = (0+(66*60));
- static const uint16 kFreetext = (0+(82*2));
- static const uint16 kBlocktext = (0+(98*2));
- static const uint16 kBlocks = (0+192);
- static const uint16 kFrframes = (0+2080);
- static const uint16 kExframes = (0+2080);
- static const uint16 kFrames = (0+2080);
- static const uint16 kExdata = (0+2080+30000);
- static const uint16 kExtextdat = (0+2080+30000+(16*114));
- static const uint16 kExtext = (0+2080+30000+(16*114)+((114+2)*2));
- static const uint16 kLengthofextra = (0+2080+30000+(16*114)+((114+2)*2)+18000);
- static const uint16 kPersontxtdat = (0+24);
- static const uint16 kPersontext = (0+24+(1026*2));
- static const uint16 kInputport = (0x63);
- static const uint16 kForeign = (1);
- static const uint16 kCd = (1);
- static const uint16 kNumexobjects = (114);
- static const uint16 kUndertextsizey = (13);
- static const uint16 kZoomy = (132);
- static const uint16 kFreedatlen = (16*80);
- static const uint16 kExtextlen = (18000);
- static const uint16 kLenofmapstore = (22*8*20*8);
- static const uint16 kUndertextsizex = (228);
- static const uint16 kNumchanges = (250);
- static const uint16 kUndertimedysize = (30);
- static const uint16 kExframeslen = (30000);
- static const uint16 kTablesize = (32);
- static const uint16 kScreenwidth = (320);
- static const uint16 kKeypadx = (36+112);
- static const uint16 kItempicsize = (44);
- static const uint16 kDiaryy = (48+12);
- static const uint16 kOpsy = (52);
- static const uint16 kSymboly = (56);
- static const uint16 kInventy = (58);
- static const uint16 kMenuy = (60);
- static const uint16 kOpsx = (60);
- static const uint16 kMaplength = (60);
- static const uint16 kHeaderlen = (6187-6091);
- static const uint16 kSymbolx = (64);
- static const uint16 kSetdatlen = (64*128);
- static const uint16 kMapwidth = (66);
- static const uint16 kTextstart = (66*2);
- static const uint16 kMaplen = (66*60);
- static const uint16 kDiaryx = (68+24);
- static const uint16 kLengthofvars = (68-0);
- static const uint16 kKeypady = (72);
- static const uint16 kZoomx = (8);
- static const uint16 kInventx = (80);
- static const uint16 kMenux = (80+40);
- static const uint16 kLenofreelrouts = (991-534);
-
- void bothchannels();
- void usewire();
- void getnamepos();
- void loadtemptext();
- void clearstartpal();
- void femalefan();
- //void showgamereel();
- void identifyob();
- void trysoundalloc();
- void uselighter();
- void showmenu();
- void usepoolreader();
- void startdmablock();
- void useopenbox();
- void clearbuffers();
- //void getyad();
- void neterror();
- void storeit();
- //void lockeddoorway();
- //void isitworn();
- //void putundertimed();
- //void dumpmap();
- //void multidump();
- void channel0only();
- void worktoscreenm();
- //void obicons();
- void removeemm();
- //void frameoutbh();
- 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 setmode();
- void getbackfromops();
- //void frameoutv();
- void showbyte();
- void screenupdate();
- //void addlength();
- //void usetimedtext();
- void putundercentre();
- void checkobjectsize();
- //void commandonly();
- void titles();
- 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 fillspace();
- void selectlocation();
- //void multiget();
- //void autosetwalk();
- void fadeupmonfirst();
- void drawfloor();
- void loadkeypad();
- //void findsource();
- void clearendpal();
- void findtext1();
- void isryanholding();
- void showslots();
- void usecashcard();
- void usewall();
- void opentomb();
- //void makename();
- void buttonfour();
- void restoreall();
- //void lockmon();
- //void dochange();
- void getanyaddir();
- //void dumpblink();
- void showsaveops();
- void intromonks1();
- void resetlocation();
- void oldtonames();
- void showdiscops();
- void advisor();
- void additionaltext();
- //void compare();
- void othersmoker();
- void dofade();
- //void setuptimedtemp();
- //void blocknametext();
- void useelevator5();
- void useelevator4();
- void useelevator1();
- //void findormake();
- 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 slabdoorf();
- void loadintotemp();
- void loadintroroom();
- void saveseg();
- //void showblink();
- void mousecall();
- void train();
- void watchcount();
- void fadedownmon();
- void loadcart();
- //void calcfrframe();
- void bartender();
- void eden();
- void showdiary();
- void purgealocation();
- //void updatepeople();
- //void addtopeoplelist();
- void hangoncurs();
- //void getblockofpixel();
- //void kernchars();
- void printcurs();
- //void convertkey();
- void outofopen();
- //void dealwithspecial();
- //void eraseoldobs();
- void dircom();
- //void liftsprite();
- void dumpkeypad();
- void showsymbol();
- void endgameseq();
- //void cancelch0();
- void setbotleft();
- void findfirstpath();
- //void cancelch1();
- void loadold();
- void loadtempcharset();
- void useslab();
- void dumpzoom();
- //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 paneltomap();
- //void obname();
- void getridoftemp3();
- void getridoftemp2();
- void usebalcony();
- void runendseq();
- void dumpdiarykeys();
- void disablesoundint();
- void priesttext();
- //void showallex();
- void openpoolboss();
- void buttontwo();
- //void delsprite();
- //void getroomspaths();
- //void dumptextline();
- void fadescreendownhalf();
- void useplate();
- void candles1();
- void lookininterface();
- void manasleep();
- //void isitdescribed();
- void hotelbell();
- void loadspeech();
- void interupttest();
- //void cls();
- //void printsprites();
- //void checkifperson();
- //void showallobs();
- //void getnumber();
- void adjustleft();
- void calledenslift();
- void useclearbox();
- void entryanims();
- void nextfolder();
- void getfreead();
- void showarrows();
- void walkintoroom();
- void usehatch();
- void printoutermon();
- void setuppit();
- void showpcx();
- void showdecisions();
- void checkspeed();
- //void printchar();
- void showkeypad();
- //void obtoinv();
- //void getroomdata();
- 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 bresenhams();
- //void walktotext();
- void pickupconts();
- void locklightoff();
- void wearwatch();
- void runintroseq();
- //void doblocks();
- void opensarters();
- //void delpointer();
- void attendant();
- void nextsymbol();
- void monks2text();
- void clearpalette();
- void cantdrop();
- //void maptopanel();
- //void calcmapad();
- void getridofall();
- void copper();
- void folderhints();
- void openhoteldoor();
- //void removesetobject();
- //void dumptimedtext();
- //void frameoutfx();
- void blank();
- void drinker();
- void nextcolon();
- void placefreeobject();
- void allpalette();
- //void loopchannel0();
- void initrain();
- void showleftpage();
- void rockstar();
- void adjustright();
- void putunderzoom();
- void vsync();
- //void finishedwalking();
- void findinvpos();
- void dumpmenu();
- //void examineobtext();
- 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 usetext();
- void chewy();
- void accesslighton();
- void useplinth();
- //void adjustlen();
- //void quickquit();
- //void showpointer();
- void usecooker();
- void loadmenu();
- void checkforemm();
- //void checkifpathison();
- //void finalframe();
- void receptionist();
- void selectslot();
- void openfilenocheck();
- //void readoneblock();
- void fadeupmon();
- void paltoendpal();
- void fadetowhite();
- void loadsavebox();
- void soundend();
- void redes();
- void errormessage1();
- void clearchanges();
- void errormessage3();
- //void deletetaken();
- void putundermenu();
- void intromonks2();
- void intromagic2();
- void intromagic3();
- void edeninbath();
- void intromagic1();
- void showdiarypage();
- void useshield();
- void getbacktoops();
- void rollendcredits();
- void intro1text();
- void transfertoex();
- void playchannel1();
- void playchannel0();
- void usemon();
- void steady();
- //void pixelcheckset();
- void reexfrominv();
- void examinventory();
- void talk();
- void usedryer();
- //void dumpeverything();
- //void readmouse2();
- //void zoom();
- void outofinv();
- void viewfolder();
- //void walking();
- void diarykeyp();
- //void readabyte();
- //void showframe();
- void random();
- void mainman();
- void mansatstill();
- void channel1only();
- void checkbasemem();
- 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 enablesoundint();
- void madmanstelly();
- void constant();
- void loadroomssample();
- void sparkydrip();
- void paltostartpal();
- void bossman();
- void getridofpit();
- void convnum();
- //void checkifset();
- void nothelderror();
- //void readheader();
- void getsetad();
- void textformonk();
- void reconstruct();
- void soldier1();
- //void animpointer();
- void getundercentre();
- void checkforexit();
- void loadseg();
- void makeheader();
- void setkeyboardint();
- void priest();
- //void readmouse();
- void powerlighton();
- void savefilewrite();
- void printmessage2();
- //void showallfree();
- void loadnews();
- void rollem();
- //void makeworn();
- void hangonpq();
- void startup();
- void savegame();
- void startpaltoend();
- void showicon();
- void findopenpos();
- void describeob();
- void deleteexframe();
- void folderexit();
- void dosreturn();
- void wheelsound();
- void actualsave();
- void autolook();
- void playguitar();
- void transfertext();
- void searchforsame();
- void showmainops();
- 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 afterintroroom();
- //void printundermon();
- void buttonnine();
- void findallopen();
- void loadintotemp3();
- void loadintotemp2();
- void gamer();
- void poolguard();
- void readfromfile();
- void initialinv();
- void quitsymbol();
- //void modifychar();
- //void initman();
- 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 doorway();
- void dropobject();
- void isitright();
- void reexfromopen();
- //void fillryan();
- void drawitall();
- void usestereo();
- void showcurrentfile();
- //void turnpathoff();
- //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 showexit();
- 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 showrain();
- void useopened();
- void inventory();
- void powerlightoff();
- void fillopen();
- void showoutermenu();
- void signon();
- void deleteextext();
- void foghornsound();
- void showrightpage();
- void showloadops();
- void examicon();
- void showgun();
- void switchryanon();
- //void personnametext();
- void louischair();
- void saveems();
- void locationpic();
- //void getflagunderp();
- void dolook();
- void opentvdoor();
- void triggermessage();
- void smallcandle();
- //void plotreel();
- void swapwithopen();
- //void makesprite();
- void dreamweb();
- void droperror();
- void edenscdplayer();
- void calledensdlift();
- void checkinside();
- void gates();
- void newgame();
- void showwatch();
- //void turnanypathon();
- void restorereels();
- void setwalk();
- //void useroutine();
- void zoomicon();
- //void findlen();
- void findpathofpoint();
- void issetobonmap();
- void getdestinfo();
- void drunk();
- void getridoftemptext();
- void setuptimeduse();
- void grafittidoor();
- void input();
- void nextdest();
- //void getdimension();
- void makecaps();
- void read();
- void fadescreenups();
- //void checkdest();
- //void hangon();
- void loadpalfromiff();
- //void facerightway();
- void startup1();
- void hotelcontrol();
- 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 callhotellift();
- void showman();
- void usefullcart();
- void newplace();
- //void movemap();
- void loadsample();
- void usecardreader1();
- void usecardreader2();
- void usecardreader3();
- void tattooman();
- void usehandle();
- void openfile();
- void usecharset1();
- //void makenextblock();
- void showpuztext();
- //void addalong();
- //void width160();
- void incryanpage();
- //void dodoor();
- void greyscalesum();
- void buttoneight();
- 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 openforsave();
- void closefile();
- void delcurs();
- void randomaccess();
- void splitintolines();
- //void checkifex();
- //void findobname();
- void initialmoncols();
- void checkforshake();
- void usebuttona();
- void fadescreenup();
- //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 showgroup();
- //void findallryan();
- //void channel0tran();
- void buttonpress();
- //void parseblaster();
- //void readmouse1();
- void makemainscreen();
- void usewinch();
- void setbotright();
- //void readmouse3();
- void showfirstuse();
- void setupemm();
- void aide();
- //void getmapad();
- 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 openhoteldoor2();
- void getridoftempsp();
- void scanfornames();
- //void setallchanges();
- void readsetdata();
- //void printboth();
- 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 quitkey();
- void processtrigger();
- void monmessage();
- void readdesticon();
- void randomnum2();
- void loadsecondsample();
- void transfercontoex();
- //void multiput();
- //void printmessage();
- 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 volumeadjust();
- //void checkiffree();
-};
-}
-
-#endif
diff --git a/engines/dreamweb/dreamweb.cpp b/engines/dreamweb/dreamweb.cpp
index 0e43f18db6..af55d0c72c 100644
--- a/engines/dreamweb/dreamweb.cpp
+++ b/engines/dreamweb/dreamweb.cpp
@@ -30,21 +30,22 @@
#include "common/timer.h"
#include "common/util.h"
-#include "audio/mixer.h"
-#include "audio/decoders/raw.h"
+#include "engines/advancedDetector.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") {
+ Engine(syst), _gameDescription(gameDesc), _rnd("dreamweb"),
+ _exText(kNumExTexts),
+ _setDesc(kNumSetTexts), _blockDesc(kNumBlockTexts),
+ _roomDesc(kNumRoomTexts), _freeDesc(kNumFreeTexts),
+ _personText(kNumPersonTexts) {
- _context.engine = this;
// Setup mixer
_mixer->setVolumeForSoundType(Audio::Mixer::kSFXSoundType, ConfMan.getInt("sfx_volume"));
_mixer->setVolumeForSoundType(Audio::Mixer::kMusicSoundType, ConfMan.getInt("music_volume"));
@@ -55,15 +56,173 @@ DreamWebEngine::DreamWebEngine(OSystem *syst, const DreamWebGameDescription *gam
_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;
+ _datafilePrefix = "DREAMWEB.";
+
+ _openChangeSize = kInventx+(4*kItempicsize);
+ _quitRequested = false;
+
+ _currentSample = 0xff;
+ _channel0Playing = 0;
+ _channel0Repeat = 0;
+ _channel1Playing = 0xff;
+
+ _volume = 0;
+ _volumeTo = 0;
+ _volumeDirection = 0;
+ _volumeCount = 0;
+
+ _speechLoaded = false;
+
+ _backdropBlocks = 0;
+ _reelList = 0;
+
+ _oldSubject._type = 0;
+ _oldSubject._index = 0;
+
+ // misc variables
+ _speechCount = 0;
+ _charShift = 0;
+ _kerning = 0;
+ _brightPalette = false;
+ _roomLoaded = 0;
+ _didZoom = 0;
+ _lineSpacing = 10;
+ _textAddressX = 13;
+ _textAddressY = 182;
+ _textLen = 0;
+ _lastXPos = 0;
+ _itemFrame = 0;
+ _withObject = 0;
+ _withType = 0;
+ _lookCounter = 0;
+ _command = 0;
+ _commandType = 0;
+ _objectType = 0;
+ _getBack = 0;
+ _invOpen = 0;
+ _mainMode = 0;
+ _pickUp = 0;
+ _lastInvPos = 0;
+ _examAgain = 0;
+ _newTextLine = 0;
+ _openedOb = 0;
+ _openedType = 0;
+ _mapAdX = 0;
+ _mapAdY = 0;
+ _mapOffsetX = 104;
+ _mapOffsetY = 38;
+ _mapXStart = 0;
+ _mapYStart = 0;
+ _mapXSize = 0;
+ _mapYSize = 0;
+ _haveDoneObs = 0;
+ _manIsOffScreen = 0;
+ _facing = 0;
+ _leaveDirection = 0;
+ _turnToFace = 0;
+ _turnDirection = 0;
+ _mainTimer = 0;
+ _introCount = 0;
+ _currentKey = 0;
+ _timerCount = 0;
+ _mapX = 0;
+ _mapY = 0;
+ _ryanX = 0;
+ _ryanY = 0;
+ _lastFlag = 0;
+ _destPos = 0;
+ _realLocation = 0;
+ _roomNum = 0;
+ _nowInNewRoom = 0;
+ _resetManXY = 0;
+ _newLocation = 0xFF;
+ _autoLocation = 0xFF;
+ _mouseX = 0;
+ _mouseY = 0;
+ _mouseButton = 0;
+ _oldButton = 0;
+ _oldX = 0;
+ _oldY = 0;
+ _oldPointerX = 0;
+ _oldPointerY = 0;
+ _delHereX = 0;
+ _delHereY = 0;
+ _pointerXS = 32;
+ _pointerYS = 32;
+ _delXS = 0;
+ _delYS = 0;
+ _pointerFrame = 0;
+ _pointerPower = 0;
+ _pointerMode = 0;
+ _pointerSpeed = 0;
+ _pointerCount = 0;
+ _inMapArea = 0;
+ _talkMode = 0;
+ _talkPos = 0;
+ _character = 0;
+ _watchDump = 0;
+ _logoNum = 0;
+ _oldLogoNum = 0;
+ _pressed = 0;
+ _pressPointer = 0;
+ _graphicPress = 0;
+ _pressCount = 0;
+ _lightCount = 0;
+ _folderPage = 0;
+ _diaryPage = 0;
+ _menuCount = 0;
+ _symbolTopX = 0;
+ _symbolTopNum = 0;
+ _symbolTopDir = 0;
+ _symbolBotX = 0;
+ _symbolBotNum = 0;
+ _symbolBotDir = 0;
+ _walkAndExam = 0;
+ _walkExamType = 0;
+ _walkExamNum = 0;
+ _cursLocX = 0;
+ _cursLocY = 0;
+ _curPos = 0;
+ _monAdX = 0;
+ _monAdY = 0;
+ _timeCount = 0;
+ _needToDumpTimed = 0;
+ _loadingOrSave = 0;
+ _saveLoadPage = 0;
+ _currentSlot = 0;
+ _cursorPos = 0;
+ _colourPos = 0;
+ _fadeDirection = 0;
+ _numToFade = 0;
+ _fadeCount = 0;
+ _addToGreen = 0;
+ _addToRed = 0;
+ _addToBlue = 0;
+ _lastSoundReel = 0;
+ _lastHardKey = 0;
+ _bufferIn = 0;
+ _bufferOut = 0;
+ _blinkFrame = 23;
+ _blinkCount = 0;
+ _reAssesChanges = 0;
+ _pointersPath = 0;
+ _mansPath = 0;
+ _pointerFirstPath = 0;
+ _finalDest = 0;
+ _destination = 0;
+ _lineStartX = 0;
+ _lineStartY = 0;
+ _lineEndX = 0;
+ _lineEndY = 0;
+ _linePointer = 0;
+ _lineDirection = 0;
+ _lineLength = 0;
}
DreamWebEngine::~DreamWebEngine() {
@@ -93,19 +252,18 @@ void DreamWebEngine::waitForVSync() {
setVSyncInterrupt(false);
}
- _context.doshake();
- _context.dofade();
+ doShake();
+ doFade();
_system->updateScreen();
}
void DreamWebEngine::quit() {
- _context.data.byte(DreamGen::DreamGenContext::kQuitrequested) = 1;
- _context.data.byte(DreamGen::DreamGenContext::kLasthardkey) = 1;
+ _quitRequested = true;
+ _lastHardKey = 1;
}
void DreamWebEngine::processEvents() {
- Common::EventManager *event_manager = _system->getEventManager();
- if (event_manager->shouldQuit()) {
+ if (_eventMan->shouldQuit()) {
quit();
return;
}
@@ -113,7 +271,7 @@ void DreamWebEngine::processEvents() {
soundHandler();
Common::Event event;
int softKey, hardKey;
- while (event_manager->pollEvent(event)) {
+ while (_eventMan->pollEvent(event)) {
switch(event.type) {
case Common::EVENT_RTL:
quit();
@@ -136,8 +294,8 @@ void DreamWebEngine::processEvents() {
break;
case Common::KEYCODE_c: //skip statue puzzle
- _context.data.byte(DreamGen::DreamGenContext::kSymbolbotnum) = 3;
- _context.data.byte(DreamGen::DreamGenContext::kSymboltopnum) = 5;
+ _symbolBotNum = 3;
+ _symbolTopNum = 5;
break;
default:
@@ -167,7 +325,7 @@ void DreamWebEngine::processEvents() {
break;
}
- _context.data.byte(DreamGen::DreamGenContext::kLasthardkey) = hardKey;
+ _lastHardKey = hardKey;
// The rest of the keys are converted to ASCII. This
// is fairly restrictive, and eventually we may want
@@ -203,18 +361,21 @@ void DreamWebEngine::processEvents() {
}
}
-
Common::Error DreamWebEngine::run() {
syncSoundSettings();
_console = new DreamWebConsole(this);
- ConfMan.registerDefault("dreamweb_originalsaveload", "true");
+ ConfMan.registerDefault("dreamweb_originalsaveload", "false");
+ ConfMan.registerDefault("bright_palette", true);
+ _hasSpeech = Common::File::exists("speech/r01c0000.raw") && !ConfMan.getBool("speech_mute");
+ _brightPalette = ConfMan.getBool("bright_palette");
- getTimerManager()->installTimerProc(vSyncInterrupt, 1000000 / 70, this, "dreamwebVSync");
- _context.__start();
- _context.data.byte(DreamGen::DreamGenContext::kQuitrequested) = 0;
+ _timer->installTimerProc(vSyncInterrupt, 1000000 / 70, this, "dreamwebVSync");
+ dreamweb();
+ dreamwebFinalize();
+ _quitRequested = false;
- getTimerManager()->removeTimerProc(vSyncInterrupt);
+ _timer->removeTimerProc(vSyncInterrupt);
return Common::kNoError;
}
@@ -222,91 +383,34 @@ Common::Error DreamWebEngine::run() {
void DreamWebEngine::setSpeed(uint speed) {
debug(0, "setting speed %u", speed);
_speed = speed;
- getTimerManager()->removeTimerProc(vSyncInterrupt);
- getTimerManager()->installTimerProc(vSyncInterrupt, 1000000 / 70 / speed, this, "dreamwebVSync");
-}
-
-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());
+ _timer->removeTimerProc(vSyncInterrupt);
+ _timer->installTimerProc(vSyncInterrupt, 1000000 / 70 / speed, this, "dreamwebVSync");
}
-uint32 DreamWebEngine::skipBytes(uint32 bytes) {
- if (!_file.seek(bytes, SEEK_CUR))
- error("seek failed");
- return _file.pos();
+Common::String DreamWebEngine::getSavegameFilename(int slot) const {
+ // TODO: Are saves from all versions of Dreamweb compatible with each other?
+ // Then we can can consider keeping the filenames as DREAMWEB.Dnn.
+ // Otherwise, this must be changed to be target dependent.
+ //Common::String filename = _targetName + Common::String::format(".d%02d", savegameId);
+ Common::String filename = Common::String::format("DREAMWEB.D%02d", slot);
+ return filename;
}
-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);
+ uint16 in = (_bufferIn + 1) & 0x0f;
+ uint16 out = _bufferOut;
if (in == out) {
warning("keyboard buffer is full");
return;
}
- _context.data.word(DreamGen::DreamGenContext::kBufferin) = in;
- keybuf[in] = ascii;
+ _bufferIn = in;
+ DreamWeb::g_keyBuffer[in] = ascii;
}
void DreamWebEngine::mouseCall(uint16 *x, uint16 *y, uint16 *state) {
processEvents();
- Common::EventManager *eventMan = _system->getEventManager();
- Common::Point pos = eventMan->getMousePos();
+ Common::Point pos = _eventMan->getMousePos();
if (pos.x > 298)
pos.x = 298;
if (pos.x < 15)
@@ -318,54 +422,26 @@ void DreamWebEngine::mouseCall(uint16 *x, uint16 *y, uint16 *state) {
*x = pos.x;
*y = pos.y;
- unsigned newState = eventMan->getButtonState();
+ unsigned newState = _eventMan->getButtonState();
*state = (newState == _oldMouseState? 0 : newState);
_oldMouseState = newState;
}
-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--)
+ 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) {
+ 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;
@@ -377,28 +453,23 @@ void DreamWebEngine::blit(const uint8 *src, int pitch, int x, int y, int w, int
}
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;
+ uint8 *dst = workspace() + kScreenwidth * 43 + 76;
Graphics::Surface *s = _system->lockScreen();
if (!s)
error("lockScreen failed");
- for(uint y = 0; y < 104; ++y) {
+ 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) {
+ 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);
+ dst += kScreenwidth - 170;
}
- _context.cx = 0;
_system->unlockScreen();
}
@@ -406,181 +477,13 @@ 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);
-}
-
-void DreamWebEngine::stopSound(uint8 channel) {
- debug(1, "stopSound(%u)", channel);
- assert(channel == 0 || channel == 1);
- _mixer->stopHandle(_channelHandle[channel]);
- if (channel == 0)
- _channel0 = 0;
- else
- _channel1 = 0;
-}
-
-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) {
+ switch(getLanguage()) {
case Common::DE_DEU:
- switch(c)
- {
+ switch(c) {
case 129:
return 'Z' + 3;
case 132:
@@ -628,4 +531,8 @@ uint8 DreamWebEngine::modifyChar(uint8 c) const {
}
}
+bool DreamWebEngine::hasSpeech() {
+ return isCD() && _hasSpeech;
+}
+
} // End of namespace DreamWeb
diff --git a/engines/dreamweb/dreamweb.h b/engines/dreamweb/dreamweb.h
index 97f6007f9d..13a27449dc 100644
--- a/engines/dreamweb/dreamweb.h
+++ b/engines/dreamweb/dreamweb.h
@@ -34,23 +34,71 @@
#include "audio/audiostream.h"
#include "audio/mixer.h"
-#include "engines/advancedDetector.h"
#include "engines/engine.h"
-#include "dreamweb/dreamgen.h"
#include "dreamweb/console.h"
+#include "dreamweb/structs.h"
+
+#define SCUMMVM_HEADER MKTAG('S', 'C', 'V', 'M')
+#define SCUMMVM_BLOCK_MAGIC_SIZE 0x1234
+#define SAVEGAME_VERSION 1
+
namespace DreamWeb {
+const unsigned int kNumReelRoutines = 57;
+const unsigned int kUnderTextSizeX = 180;
+const unsigned int kUnderTextSizeY = 10;
+const unsigned int kUnderTimedTextSizeY = 24;
+const unsigned int kUnderTextSizeX_f = 228; // foreign version
+const unsigned int kUnderTextSizeY_f = 13; // foreign version
+const unsigned int kUnderTimedTextSizeY_f = 30;
+const unsigned int kUnderTextBufSize = kUnderTextSizeX_f * kUnderTextSizeY_f;
+const unsigned int kUnderTimedTextBufSize = 256 * kUnderTimedTextSizeY_f;
+const unsigned int kLengthOfVars = 68;
+const unsigned int kNumChanges = 250;
+const unsigned int kLenOfMapStore = 22*8*20*8;
+const unsigned int kMapWidth = 66;
+const unsigned int kMapHeight = 60;
+const unsigned int kLengthOfMap = kMapWidth * kMapHeight;
+const unsigned int kNumExObjects = 114;
+const unsigned int kScreenwidth = 320;
+const unsigned int kDiaryx = (68+24);
+const unsigned int kDiaryy = (48+12);
+const unsigned int kInventx = 80;
+const unsigned int kInventy = 58;
+const unsigned int kMenux = (80+40);
+const unsigned int kMenuy = 60;
+const unsigned int kOpsx = 60;
+const unsigned int kOpsy = 52;
+const unsigned int kSymbolx = 64;
+const unsigned int kSymboly = 56;
+const unsigned int kLengthofvars = 68;
+const unsigned int kFrameBlocksize = 2080;
+const unsigned int kGraphicsFileFrameSize = 347; // ceil(2080 / sizeof(Frame))
+const unsigned int kNumexobjects = 114;
+const unsigned int kNumExTexts = kNumexobjects + 2;
+const uint16 kExtextlen = 18000;
+const uint16 kExframeslen = 30000;
+const unsigned int kLengthofextra = kFrameBlocksize + kExframeslen + sizeof(DynObject)*kNumexobjects + sizeof(uint16)*kNumExTexts + kExtextlen;
+const unsigned int kItempicsize = 44;
+const unsigned int kNumSetTexts = 130;
+const unsigned int kNumBlockTexts = 98;
+const unsigned int kNumRoomTexts = 38;
+const unsigned int kNumFreeTexts = 82;
+const unsigned int kNumPersonTexts = 1026;
+
+// Keyboard buffer. data.word(kBufferin) and data.word(kBufferout) are indexes
+// into this, making it a ring buffer
+extern uint8 g_keyBuffer[16];
+
// Engine Debug Flags
enum {
kDebugAnimation = (1 << 0),
kDebugSaveLoad = (1 << 1)
};
-struct DreamWebGameDescription {
- ADGameDescription desc;
-};
+struct DreamWebGameDescription;
class DreamWebEngine : public Engine {
private:
@@ -77,42 +125,35 @@ public:
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(uint16 *x, uint16 *y, uint16 *state); //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();
+ bool isCD();
+ bool hasSpeech();
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);
+ Common::String getSavegameFilename(int slot) const;
void setShakePos(int pos) { _system->setShakePos(pos); }
void printUnderMonitor();
void quit();
- void loadSounds(uint bank, const Common::String &file);
+ void loadSounds(uint bank, const Common::String &suffix);
bool loadSpeech(const Common::String &filename);
void enableSavingOrLoading(bool enable = true) { _enableSavingOrLoading = enable; }
- Common::Language getLanguage() const { return _language; }
+ Common::Language getLanguage() const;
uint8 modifyChar(uint8 c) const;
void stopSound(uint8 channel);
+ const Common::String& getDatafilePrefix() { return _datafilePrefix; };
+
private:
void keyPressed(uint16 ascii);
void setSpeed(uint speed);
@@ -121,16 +162,12 @@ private:
const DreamWebGameDescription *_gameDescription;
Common::RandomSource _rnd;
-
- Common::File _file;
- Common::OutSaveFile *_outSaveFile;
- Common::InSaveFile *_inSaveFile;
+ Common::String _datafilePrefix;
uint _speed;
bool _turbo;
uint _oldMouseState;
bool _enableSavingOrLoading;
- Common::Language _language;
struct Sample {
uint offset;
@@ -148,7 +185,965 @@ private:
Audio::SoundHandle _channelHandle[2];
uint8 _channel0, _channel1;
- DreamGen::DreamGenContext _context;
+protected:
+ GameVars _vars; // saved variables
+
+ // from backdrop.cpp
+ uint8 *_backdropBlocks;
+ BackdropMapFlag _backdropFlags[96];
+ uint8 _mapData[kLengthOfMap + 32];
+
+ // from keypad.cpp
+ uint8 _pressList[6];
+ uint8 _pressed;
+ uint16 _pressPointer;
+ uint8 _graphicPress;
+ uint8 _pressCount;
+ uint8 _lightCount;
+ uint8 _folderPage;
+ uint8 _diaryPage;
+ uint8 _menuCount;
+ uint8 _symbolTopX;
+ uint8 _symbolTopNum;
+ int8 _symbolTopDir;
+ uint8 _symbolBotX;
+ uint8 _symbolBotNum;
+ int8 _symbolBotDir;
+
+ // from monitor.cpp
+ char _inputLine[64];
+ char _operand1[14];
+ char _currentFile[14];
+
+ // from newplace.cpp
+ uint8 _roomsCanGo[16];
+
+ // from object.cpp
+ uint16 _openChangeSize;
+ ObjectRef _oldSubject;
+
+ // from pathfind.cpp
+ Common::Point _lineData[200]; // Output of Bresenham
+
+ // from saveload.cpp
+ char _saveNames[17*21];
+ char _saveNamesOld[17*21];
+
+ // from vgagrafx.cpp
+ uint8 _workspace[(0x1000 + 2) * 16];
+ uint8 _mapStore[kLenOfMapStore + 32];
+
+ // from people.cpp
+ ReelRoutine _reelRoutines[kNumReelRoutines+1];
+ ReelRoutine *_personData;
+
+ // from Buffers
+ uint8 _textUnder[kUnderTextBufSize];
+ ObjectRef _openInvList[16];
+ ObjectRef _ryanInvList[30];
+ uint8 _pointerBack[32*32];
+ MapFlag _mapFlags[11*10];
+ uint8 _startPal[3*256];
+ uint8 _endPal[3*256];
+ uint8 _mainPal[3*256];
+ Common::List<Sprite> _spriteTable;
+ Common::List<ObjPos> _setList;
+ Common::List<ObjPos> _freeList;
+ Common::List<ObjPos> _exList;
+ Common::List<People> _peopleList;
+ uint8 _zoomSpace[46*40];
+ // _printedList (unused?)
+ Change _listOfChanges[kNumChanges]; // Note: this array is saved
+ uint8 _underTimedText[kUnderTimedTextBufSize];
+ Common::List<Rain> _rainList;
+
+ // textfiles
+ TextFile _textFile1;
+ TextFile _textFile2;
+ TextFile _textFile3;
+ TextFile _travelText;
+ TextFile _puzzleText;
+ TextFile _commandText;
+
+ // local graphics files
+ GraphicsFile _keypadGraphics;
+ GraphicsFile _menuGraphics;
+ GraphicsFile _menuGraphics2;
+ GraphicsFile _folderGraphics;
+ GraphicsFile _folderGraphics2;
+ GraphicsFile _folderGraphics3;
+ GraphicsFile _folderCharset;
+ GraphicsFile _symbolGraphics;
+ GraphicsFile _diaryGraphics;
+ GraphicsFile _diaryCharset;
+ GraphicsFile _monitorGraphics;
+ GraphicsFile _monitorCharset;
+ GraphicsFile _newplaceGraphics;
+ GraphicsFile _newplaceGraphics2;
+ GraphicsFile _newplaceGraphics3;
+ GraphicsFile _cityGraphics;
+ GraphicsFile _saveGraphics;
+
+ // global graphics files
+ GraphicsFile _icons1;
+ GraphicsFile _icons2;
+ GraphicsFile _charset1;
+ GraphicsFile _mainSprites;
+ const GraphicsFile *_currentCharset;
+
+ // room files
+ GraphicsFile _setFrames;
+ GraphicsFile _freeFrames;
+ GraphicsFile _reel1;
+ GraphicsFile _reel2;
+ GraphicsFile _reel3;
+ TextFile _setDesc;
+ TextFile _blockDesc;
+ TextFile _roomDesc;
+ TextFile _freeDesc;
+ TextFile _personText;
+ uint16 _personFramesLE[12];
+ RoomPaths _pathData[36];
+ Reel *_reelList;
+ SetObject _setDat[128];
+ DynObject _freeDat[80];
+
+ // Extras segment (NB: this is saved)
+ GraphicsFile _exFrames;
+ DynObject _exData[kNumExObjects];
+ TextFile _exText;
+
+public:
+ DreamWebEngine(/*DreamWeb::DreamWebEngine *en*/);
+
+ bool _quitRequested;
+ bool _subtitles;
+ bool _foreignRelease;
+
+ bool _wonGame;
+ bool _hasSpeech;
+
+ // sound related
+ uint8 _roomsSample;
+ uint8 _currentSample;
+ uint8 _channel0Playing;
+ uint8 _channel0Repeat;
+ uint8 _channel1Playing;
+
+ uint8 _volume;
+ uint8 _volumeTo;
+ int8 _volumeDirection;
+ uint8 _volumeCount;
+
+ bool _speechLoaded;
+
+ // misc variables
+ uint8 _speechCount;
+ uint16 _charShift;
+ uint8 _kerning;
+ bool _brightPalette;
+ uint8 _roomLoaded;
+ uint8 _didZoom;
+ uint16 _lineSpacing;
+ uint16 _textAddressX;
+ uint16 _textAddressY;
+ uint8 _textLen;
+ uint16 _lastXPos;
+ uint8 _itemFrame;
+ uint8 _withObject;
+ uint8 _withType;
+ uint16 _lookCounter;
+ uint8 _command;
+ uint8 _commandType;
+ uint8 _objectType;
+ uint8 _getBack;
+ uint8 _invOpen;
+ uint8 _mainMode;
+ uint8 _pickUp;
+ uint8 _lastInvPos;
+ uint8 _examAgain;
+ uint8 _newTextLine;
+ uint8 _openedOb;
+ uint8 _openedType;
+ uint16 _mapAdX;
+ uint16 _mapAdY;
+ uint16 _mapOffsetX;
+ uint16 _mapOffsetY;
+ uint16 _mapXStart;
+ uint16 _mapYStart;
+ uint8 _mapXSize;
+ uint8 _mapYSize;
+ uint8 _haveDoneObs;
+ uint8 _manIsOffScreen;
+ uint8 _facing;
+ uint8 _leaveDirection;
+ uint8 _turnToFace;
+ uint8 _turnDirection;
+ uint16 _mainTimer;
+ uint8 _introCount;
+ uint8 _currentKey;
+ uint8 _timerCount;
+ uint8 _mapX;
+ uint8 _mapY;
+ uint8 _ryanX;
+ uint8 _ryanY;
+ uint8 _lastFlag;
+ uint8 _destPos;
+ uint8 _realLocation;
+ uint8 _roomNum;
+ uint8 _nowInNewRoom;
+ uint8 _resetManXY;
+ uint8 _newLocation;
+ uint8 _autoLocation;
+ uint16 _mouseX;
+ uint16 _mouseY;
+ uint16 _mouseButton;
+ uint16 _oldButton;
+ uint16 _oldX;
+ uint16 _oldY;
+ uint16 _oldPointerX;
+ uint16 _oldPointerY;
+ uint16 _delHereX;
+ uint16 _delHereY;
+ uint8 _pointerXS;
+ uint8 _pointerYS;
+ uint8 _delXS;
+ uint8 _delYS;
+ uint8 _pointerFrame;
+ uint8 _pointerPower;
+ uint8 _pointerMode;
+ uint8 _pointerSpeed;
+ uint8 _pointerCount;
+ uint8 _inMapArea;
+ uint8 _talkMode;
+ uint8 _talkPos;
+ uint8 _character;
+ uint8 _watchDump;
+ uint8 _logoNum;
+ uint8 _oldLogoNum;
+ uint8 _walkAndExam;
+ uint8 _walkExamType;
+ uint8 _walkExamNum;
+ uint16 _cursLocX;
+ uint16 _cursLocY;
+ uint16 _curPos;
+ uint16 _monAdX;
+ uint16 _monAdY;
+ uint16 _timeCount;
+ uint8 _needToDumpTimed;
+ TimedTemp _previousTimedTemp;
+ TimedTemp _timedTemp;
+ uint8 _loadingOrSave;
+ uint8 _saveLoadPage;
+ uint8 _currentSlot;
+ uint8 _cursorPos;
+ uint8 _colourPos;
+ uint8 _fadeDirection;
+ uint8 _numToFade;
+ uint8 _fadeCount;
+ uint8 _addToGreen;
+ uint8 _addToRed;
+ uint8 _addToBlue;
+ uint16 _lastSoundReel;
+ uint8 _lastHardKey;
+ uint16 _bufferIn;
+ uint16 _bufferOut;
+ uint8 _blinkFrame;
+ uint8 _blinkCount;
+ uint8 _reAssesChanges;
+ uint8 _pointersPath;
+ uint8 _mansPath;
+ uint8 _pointerFirstPath;
+ uint8 _finalDest;
+ uint8 _destination;
+ uint16 _lineStartX;
+ uint16 _lineStartY;
+ uint16 _lineEndX;
+ uint16 _lineEndY;
+ uint8 _linePointer;
+ uint8 _lineDirection;
+ uint8 _lineLength;
+
+ // from backdrop.cpp
+ void doBlocks();
+ uint8 getXAd(const uint8 *setData, uint8 *result);
+ uint8 getYAd(const uint8 *setData, uint8 *result);
+ uint8 getMapAd(const uint8 *setData, uint16 *x, uint16 *y);
+ void calcFrFrame(const Frame &frame, uint8* width, uint8* height, uint16 x, uint16 y, ObjPos *objPos);
+ void makeBackOb(SetObject *objData, uint16 x, uint16 y);
+ void showAllObs();
+ void getDimension(uint8 *mapXstart, uint8 *mapYstart, uint8 *mapXsize, uint8 *mapYsize);
+ void calcMapAd();
+ void showAllFree();
+ void drawFlags();
+ void showAllEx();
+
+ // from keypad.cpp
+ void getUnderMenu();
+ void putUnderMenu();
+ void singleKey(uint8 key, uint16 x, uint16 y);
+ void loadKeypad();
+ void showKeypad();
+ bool isItRight(uint8 digit0, uint8 digit1, uint8 digit2, uint8 digit3);
+ void addToPressList();
+ void buttonOne();
+ void buttonTwo();
+ void buttonThree();
+ void buttonFour();
+ void buttonFive();
+ void buttonSix();
+ void buttonSeven();
+ void buttonEight();
+ void buttonNine();
+ void buttonNought();
+ void buttonEnter();
+ void buttonPress(uint8 buttonId);
+ void showOuterPad();
+ void dumpKeypad();
+ void dumpSymbol();
+ void quitSymbol();
+ void enterCode(uint8 digit0, uint8 digit1, uint8 digit2, uint8 digit3);
+
+ // from monitor.cpp
+ void input();
+ byte makeCaps(byte c);
+ void delChar();
+ void monMessage(uint8 index);
+ void netError();
+ void monitorLogo();
+ void randomAccess(uint16 count);
+ void printOuterMon();
+ void showCurrentFile();
+ void accessLightOn();
+ void accessLightOff();
+ void turnOnPower();
+ void powerLightOn();
+ void powerLightOff();
+ void printLogo();
+ void scrollMonitor();
+ const char *monPrint(const char *string);
+ void lockLightOn();
+ void lockLightOff();
+ void loadPersonal();
+ void loadNews();
+ void loadCart();
+ void showKeys();
+ const char *parser();
+ const char *searchForString(const char *topic, const char *text);
+ const char *getKeyAndLogo(const char *foundString);
+ void read();
+ void dirFile(const char *dirName);
+ void dirCom();
+ void useMon();
+ bool execCommand();
+
+ // from newplace.cpp
+ void getUnderCentre();
+ void putUnderCentre();
+ void showArrows();
+ uint8 getLocation(uint8 index);
+ void setLocation(uint8 index);
+ void clearLocation(uint8 index);
+ void resetLocation(uint8 index);
+ void readCityPic();
+ void readDestIcon();
+ void showCity();
+ void locationPic();
+ void selectLocation();
+ void newPlace();
+ void nextDest();
+ void lastDest();
+ void destSelect();
+ void lookAtPlace();
+
+ // from object.cpp
+ void obIcons();
+ void fillRyan();
+ void findAllRyan();
+ void obToInv(uint8 index, uint8 flag, uint16 x, uint16 y);
+ void obPicture();
+ void removeObFromInv();
+ void deleteExObject(uint8 index);
+ void deleteExFrame(uint8 frameNum);
+ void deleteExText(uint8 textNum);
+ void purgeALocation(uint8 index);
+ const uint8 *getObTextStart();
+ void wornError();
+ void makeWorn(DynObject *object);
+ void dropObject();
+ ObjectRef findOpenPos();
+ byte getOpenedSlotSize();
+ byte getOpenedSlotCount();
+ void openOb();
+ void findAllOpen();
+ void fillOpen();
+ ObjectRef findInvPos();
+ void reExFromInv();
+ void swapWithInv();
+ void transferText(uint8 from, uint8 to);
+ void pickupConts(uint8 from, uint8 containerEx);
+ byte transferToEx(uint8 from);
+ void swapWithOpen();
+ void outOfOpen();
+ void inToInv();
+ void outOfInv();
+ bool checkObjectSize();
+ void useOpened();
+ void setPickup();
+ void selectOpenOb();
+ void examineOb(bool examineAgain = true);
+ void selectOb();
+ void inventory();
+ void identifyOb();
+
+ // from pathfind.cpp
+ void turnPathOn(uint8 param);
+ void turnPathOff(uint8 param);
+ void turnAnyPathOn(uint8 param, uint8 room);
+ void turnAnyPathOff(uint8 param, uint8 room);
+ RoomPaths *getRoomsPaths();
+ void faceRightWay();
+ void setWalk();
+ void autoSetWalk();
+ void checkDest(const RoomPaths *roomsPaths);
+ void findXYFromPath();
+ bool checkIfPathIsOn(uint8 index);
+ void bresenhams();
+ void workoutFrames();
+ byte findFirstPath(byte x, byte y);
+ byte findPathOfPoint(byte x, byte y);
+
+ // from people.cpp
+ void setupInitialReelRoutines();
+ void updatePeople();
+ void madmanText();
+ void madman(ReelRoutine &routine);
+ void madMode();
+ void addToPeopleList(ReelRoutine *routine);
+ bool checkSpeed(ReelRoutine &routine);
+ void sparkyDrip(ReelRoutine &routine);
+ void genericPerson(ReelRoutine &routine);
+ void gamer(ReelRoutine &routine);
+ void eden(ReelRoutine &routine);
+ void sparky(ReelRoutine &routine);
+ void rockstar(ReelRoutine &routine);
+ void madmansTelly(ReelRoutine &routine);
+ void smokeBloke(ReelRoutine &routine);
+ void manAsleep(ReelRoutine &routine);
+ void drunk(ReelRoutine &routine);
+ void introMagic1(ReelRoutine &routine);
+ void introMagic2(ReelRoutine &routine);
+ void introMagic3(ReelRoutine &routine);
+ void introMusic(ReelRoutine &routine);
+ void candles(ReelRoutine &routine);
+ void candles1(ReelRoutine &routine);
+ void candles2(ReelRoutine &routine);
+ void smallCandle(ReelRoutine &routine);
+ void gates(ReelRoutine &routine);
+ void security(ReelRoutine &routine);
+ void edenInBath(ReelRoutine &routine);
+ void louis(ReelRoutine &routine);
+ void handClap(ReelRoutine &routine);
+ void carParkDrip(ReelRoutine &routine);
+ void foghornSound(ReelRoutine &routine);
+ void train(ReelRoutine &routine);
+ void attendant(ReelRoutine &routine);
+ void keeper(ReelRoutine &routine);
+ void interviewer(ReelRoutine &routine);
+ void drinker(ReelRoutine &routine);
+ void alleyBarkSound(ReelRoutine &routine);
+ void louisChair(ReelRoutine &routine);
+ void bossMan(ReelRoutine &routine);
+ void priest(ReelRoutine &routine);
+ void monkAndRyan(ReelRoutine &routine);
+ void copper(ReelRoutine &routine);
+ void introMonks1(ReelRoutine &routine);
+ void introMonks2(ReelRoutine &routine);
+ void soldier1(ReelRoutine &routine);
+ void receptionist(ReelRoutine &routine);
+ void bartender(ReelRoutine &routine);
+ void heavy(ReelRoutine &routine);
+ void helicopter(ReelRoutine &routine);
+ void mugger(ReelRoutine &routine);
+ void businessMan(ReelRoutine &routine);
+ void endGameSeq(ReelRoutine &routine);
+ void poolGuard(ReelRoutine &routine);
+
+ // from print.cpp
+ uint8 getNextWord(const GraphicsFile &charSet, const uint8 *string, uint8 *totalWidth, uint8 *charCount);
+ void printChar(const GraphicsFile &charSet, uint16 *x, uint16 y, uint8 c, uint8 nextChar, uint8 *width, uint8 *height);
+ void printChar(const GraphicsFile &charSet, uint16 x, uint16 y, uint8 c, uint8 nextChar, uint8 *width, uint8 *height);
+ void printBoth(const GraphicsFile &charSet, uint16 *x, uint16 y, uint8 c, uint8 nextChar);
+ uint8 printDirect(const uint8** string, uint16 x, uint16 *y, uint8 maxWidth, bool centered);
+ uint8 printDirect(const uint8* string, uint16 x, uint16 y, uint8 maxWidth, bool centered);
+ uint8 getNumber(const GraphicsFile &charSet, const uint8 *string, uint16 maxWidth, bool centered, uint16 *offset);
+ uint8 kernChars(uint8 firstChar, uint8 secondChar, uint8 width);
+ uint8 printSlow(const uint8 *string, uint16 x, uint16 y, uint8 maxWidth, bool centered);
+ uint16 waitFrames();
+ void printCurs();
+ void delCurs();
+ void rollEndCreditsGameWon();
+ void rollEndCreditsGameLost();
+
+ // from saveload.cpp
+ void loadGame();
+ void doLoad(int slot);
+ void saveGame();
+ void namesToOld();
+ void oldToNames();
+ void saveLoad();
+ void doSaveLoad();
+ void showMainOps();
+ void showDiscOps();
+ void discOps();
+ void actualSave();
+ void actualLoad();
+ void loadPosition(unsigned int slot);
+ void savePosition(unsigned int slot, const char *descbuf);
+ uint scanForNames();
+ void loadOld();
+ void showDecisions();
+ void loadSaveBox();
+ void showNames();
+ void checkInput();
+ void selectSaveLoadPage();
+ void selectSlot();
+ void showSlots();
+ void showOpBox();
+ void showSaveOps();
+ void showLoadOps();
+
+ // from sound.cpp
+ bool loadSpeech(byte type1, int idx1, byte type2, int idx2);
+ void volumeAdjust();
+ void cancelCh0();
+ void cancelCh1();
+ void loadRoomsSample();
+ void playChannel0(uint8 index, uint8 repeat);
+ void playChannel1(uint8 index);
+
+ // from sprite.cpp
+ void printSprites();
+ void printASprite(const Sprite *sprite);
+ void clearSprites();
+ Sprite *makeSprite(uint8 x, uint8 y, bool _mainManCallback, const GraphicsFile *frameData);
+ void initMan();
+ void walking(Sprite *sprite);
+ void aboutTurn(Sprite *sprite);
+ void backObject(Sprite *sprite);
+ void constant(Sprite *sprite, SetObject *objData);
+ void randomSprite(Sprite *sprite, SetObject *objData);
+ void doorway(Sprite *sprite, SetObject *objData);
+ void wideDoor(Sprite *sprite, SetObject *objData);
+ void doDoor(Sprite *sprite, SetObject *objData, Common::Rect check);
+ void steady(Sprite *sprite, SetObject *objData);
+ void lockedDoorway(Sprite *sprite, SetObject *objData);
+ void liftSprite(Sprite *sprite, SetObject *objData);
+
+ Reel *getReelStart(uint16 reelPointer);
+ const GraphicsFile *findSource(uint16 &frame);
+ void showReelFrame(Reel *reel);
+ void showGameReel(ReelRoutine *routine);
+ const Frame *getReelFrameAX(uint16 frame);
+ void moveMap(uint8 param);
+ void checkOne(uint8 x, uint8 y, uint8 *flag, uint8 *flagEx, uint8 *type, uint8 *flagX, uint8 *flagY);
+
+ uint8 getBlockOfPixel(uint8 x, uint8 y);
+ void splitIntoLines(uint8 x, uint8 y);
+ void initRain();
+
+ void intro1Text();
+ void intro2Text(uint16 nextReelPointer);
+ void intro3Text(uint16 nextReelPointer);
+
+ void monks2text();
+ void textForEnd();
+ void textForMonkHelper(uint8 textIndex, uint8 voiceIndex, uint8 x, uint8 y, uint16 countToTimed, uint16 timeCount);
+ void textForMonk();
+ void priestText(ReelRoutine &routine);
+ void soundOnReels(uint16 reelPointer);
+ void clearBeforeLoad();
+ void clearReels();
+ void getRidOfReels();
+ void liftNoise(uint8 index);
+ void checkForExit(Sprite *sprite);
+ void mainMan(Sprite *sprite);
+ void spriteUpdate();
+ void showRain();
+ void reconstruct();
+ void reelsOnScreen();
+
+ // from stubs.cpp
+ void setupInitialVars();
+ void crosshair();
+ void delTextLine();
+ void showBlink();
+ void dumpBlink();
+ void dumpPointer();
+ void showPointer();
+ void delPointer();
+ void showRyanPage();
+ void switchRyanOn();
+ void switchRyanOff();
+ void middlePanel();
+ void showDiary();
+ void readMouse();
+ uint16 readMouseState();
+ void hangOn(uint16 frameCount);
+ void lockMon();
+ uint8 *textUnder();
+ void readKey();
+ void findOrMake(uint8 index, uint8 value, uint8 type);
+ DynObject *getFreeAd(uint8 index);
+ DynObject *getExAd(uint8 index);
+ DynObject *getEitherAd();
+ void *getAnyAdDir(uint8 index, uint8 flag);
+ void showWatch();
+ void showTime();
+ void showExit();
+ void showMan();
+ void panelIcons1();
+ SetObject *getSetAd(uint8 index);
+ void *getAnyAd(uint8 *slotSize, uint8 *slotCount);
+ const uint8 *getTextInFile1(uint16 index);
+ uint8 findNextColon(const uint8 **string);
+ void allocateBuffers();
+ void loadTextFile(TextFile &file, const char *suffix);
+ void loadGraphicsFile(GraphicsFile &file, const char *suffix);
+ void loadGraphicsSegment(GraphicsFile &file, Common::File &inFile, unsigned int len);
+ void loadTextSegment(TextFile &file, Common::File &inFile, unsigned int len);
+ void loadTravelText();
+ void loadTempText(const char *suffix);
+ void sortOutMap();
+ void loadRoomData(const Room &room, bool skipDat);
+ void useTempCharset(GraphicsFile *charset);
+ void useCharset1();
+ void printMessage(uint16 x, uint16 y, uint8 index, uint8 maxWidth, bool centered);
+ void printMessage2(uint16 x, uint16 y, uint8 index, uint8 maxWidth, bool centered, uint8 count);
+ bool isItDescribed(const ObjPos *objPos);
+ void zoomIcon();
+ void roomName();
+ void showIcon();
+ void eraseOldObs();
+ void commandOnlyCond(uint8 command, uint8 commandType);
+ void commandOnly(uint8 command);
+ void commandWithOb(uint8 command, uint8 type, uint8 index);
+ void blank();
+ void setTopLeft();
+ void setTopRight();
+ void setBotLeft();
+ void setBotRight();
+ void examIcon();
+ void animPointer();
+ void getFlagUnderP(uint8 *flag, uint8 *flagEx);
+ void workToScreenM();
+ void quitKey();
+ void restoreReels();
+ void loadFolder();
+ void folderHints();
+ void folderExit();
+ void showFolder();
+ void showLeftPage();
+ void showRightPage();
+ void underTextLine();
+ void hangOnP(uint16 count);
+ void getUnderZoom();
+ void putUnderZoom();
+ void examineInventory();
+ void openInv();
+ void getBack1();
+ void getBackFromOb();
+ void getBackFromOps();
+ void getBackToOps();
+ void DOSReturn();
+ bool isItWorn(const DynObject *object);
+ bool compare(uint8 index, uint8 flag, const char id[4]);
+ void hangOnW(uint16 frameCount);
+ void getRidOfTempText();
+ void getRidOfAll();
+ void placeSetObject(uint8 index);
+ void removeSetObject(uint8 index);
+ bool isSetObOnMap(uint8 index);
+ void dumpZoom();
+ void diaryKeyP();
+ void diaryKeyN();
+ void findRoomInLoc();
+ void loadMenu();
+ void showMenu();
+ void dumpMenu();
+ void dealWithSpecial(uint8 firstParam, uint8 secondParam);
+ void plotReel(uint16 &reelPointer);
+ void setupTimedTemp(uint8 textIndex, uint8 voiceIndex, uint8 x, uint8 y, uint16 countToTimed, uint16 timeCount);
+ void getUnderTimed();
+ void putUnderTimed();
+ void dumpTextLine();
+ void useTimedText();
+ void dumpTimedText();
+ void getTime();
+ void doChange(uint8 index, uint8 value, uint8 type);
+ bool isRyanHolding(const char *id);
+ void clearBuffers();
+ void clearChanges();
+ void drawFloor();
+ uint16 findSetObject(const char *id);
+ void hangOnCurs(uint16 frameCount);
+ const uint8 *findObName(uint8 type, uint8 index);
+ void copyName(uint8 type, uint8 index, uint8 *dst);
+ uint16 findExObject(const char *id);
+ void makeMainScreen();
+ void showWatchReel();
+ void watchReel();
+ void examineObText();
+ void blockNameText();
+ void personNameText();
+ void walkToText();
+ void entryTexts();
+ void setAllChanges();
+ void restoreAll();
+ void redrawMainScrn();
+ void checkCoords(const RectWithCallback *rectWithCallbacks);
+ void newGame();
+ void deleteTaken();
+ void autoAppear();
+ void loadRoom();
+ void startLoading(const Room &room);
+ void startup();
+ void atmospheres();
+ bool objectMatches(void *object, const char *id);
+ void checkFolderCoords();
+ void nextFolder();
+ void lastFolder();
+ void lookAtCard();
+ void obsThatDoThings();
+ void describeOb();
+ void putBackObStuff();
+ void reExFromOpen();
+ void showDiaryPage();
+ void showDiaryKeys();
+ void dumpDiaryKeys();
+ void useMenu();
+ void incRyanPage();
+ void edensFlatReminders();
+ void dropError();
+ void cantDrop();
+ void entryAnims();
+ bool finishedWalking();
+ void emergencyPurge();
+ void purgeAnItem();
+ uint8 nextSymbol(uint8 symbol);
+ void enterSymbol();
+ void showSymbol();
+ void updateSymbolTop();
+ void updateSymbolBot();
+ void pickupOb(uint8 command, uint8 pos);
+ void errorMessage1();
+ void errorMessage2();
+ void errorMessage3();
+ void decide();
+ void allPointer();
+ void dumpWatch();
+ void watchCount();
+ void signOn();
+ void searchForFiles(const char *filesString);
+ void triggerMessage(uint16 index);
+ void processTrigger();
+ void dreamwebFinalize();
+ void dreamweb();
+ void screenUpdate();
+ void startup1();
+ void readOneBlock();
+ bool checkIfPerson(uint8 x, uint8 y);
+ bool checkIfFree(uint8 x, uint8 y);
+ bool checkIfEx(uint8 x, uint8 y);
+ void walkAndExamine();
+ void obName(uint8 command, uint8 commandType);
+ bool checkIfSet(uint8 x, uint8 y);
+ void readSetData();
+ void look();
+ void autoLook();
+ void doLook();
+ void mainScreen();
+ void zoomOnOff();
+ void initialInv();
+ void walkIntoRoom();
+ void afterNewRoom();
+ void madmanRun();
+ void showGun();
+
+ // from talk.cpp
+ void talk();
+ void convIcons();
+ uint16 getPersFrame(uint8 index);
+ const uint8 *getPersonText(uint8 index, uint8 talkPos);
+ void startTalk();
+ void moreTalk();
+ void doSomeTalk();
+ bool hangOnPQ();
+ void redes();
+
+ // from titles.cpp
+ void endGame();
+ void monkSpeaking();
+ void gettingShot();
+ void bibleQuote();
+ void hangOne(uint16 delay);
+ void intro();
+ void runIntroSeq();
+ void runEndSeq();
+ void loadIntroRoom();
+ void set16ColPalette();
+ void realCredits();
+ uint8 getExPos();
+
+ // from use.cpp
+ void useRoutine();
+ void useObject();
+ void placeFreeObject(uint8 index);
+ void removeFreeObject(uint8 index);
+ void setupTimedUse(uint16 offset, uint16 countToTimed, uint16 timeCount, byte x, byte y);
+ void withWhat();
+ uint16 checkInside(uint16 command, uint16 type);
+ void showPuzText(uint16 command, uint16 count);
+ void useText(const uint8 *string);
+ void showFirstUse();
+ void showSecondUse();
+ void viewFolder();
+ void edensCDPlayer();
+ void hotelBell();
+ void playGuitar();
+ void useElevator1();
+ void useElevator2();
+ void useElevator3();
+ void useElevator4();
+ void useElevator5();
+ void useHatch();
+ void wheelSound();
+ void callHotelLift();
+ void useShield();
+ void useCoveredBox();
+ void useRailing();
+ void useChurchHole();
+ void sitDownInBar();
+ void useBalcony();
+ void useWindow();
+ void trapDoor();
+ void useDryer();
+ void callEdensDLift();
+ void callEdensLift();
+ void openYourNeighbour();
+ void openRyan();
+ void openPoolBoss();
+ void openEden();
+ void openSarters();
+ void openLouis();
+ void useWall();
+ void useChurchGate();
+ void useLadder();
+ void useLadderB();
+ bool defaultUseHandler(const char *id);
+ void slabDoorA();
+ void slabDoorB();
+ void slabDoorC();
+ void slabDoorE();
+ void slabDoorD();
+ void slabDoorF();
+ void useGun();
+ void useFullCart();
+ void useClearBox();
+ void openTVDoor();
+ void usePlate();
+ void usePlinth();
+ void useElvDoor();
+ void useWinch();
+ void useCart();
+ void useHole();
+ void openHotelDoor();
+ void openHotelDoor2();
+ void grafittiDoor();
+ void useCardReader1();
+ void useCardReader2();
+ void useCardReader3();
+ void usePoolReader();
+ void useLighter();
+ void useWire();
+ void openTomb();
+ void hotelControl();
+ void useCooker();
+ void useDiary();
+ void useControl();
+ void useSlab();
+ void usePipe();
+ void useOpenBox();
+ void runTap();
+ void useAxe();
+ void useHandle();
+ void useAltar();
+ void notHeldError();
+ void useCashCard();
+ void useButtonA();
+ void wearWatch();
+ void wearShades();
+ void useTrainer();
+ void useStereo();
+ void chewy();
+ void delEverything();
+ void afterIntroRoom();
+
+ // from vgafades.cpp
+ void clearStartPal();
+ void clearEndPal();
+ void palToStartPal();
+ void endPalToStart();
+ void startPalToEnd();
+ void palToEndPal();
+ void fadeDOS();
+ void doFade();
+ void fadeCalculation();
+ void fadeUpYellows();
+ void fadeUpMonFirst();
+ void fadeUpMon();
+ void fadeDownMon();
+ void initialMonCols();
+ void fadeScreenUp();
+ void fadeScreenUps();
+ void fadeScreenUpHalf();
+ void fadeScreenDown();
+ void fadeScreenDowns();
+ void fadeScreenDownHalf();
+ void clearPalette();
+ void greyscaleSum();
+ void allPalette();
+ void dumpCurrent();
+
+ // from vgagrafx.cpp
+ inline uint8 *workspace() { return _workspace; }
+ void clearWork();
+
+ void panelToMap();
+ void mapToPanel();
+ void dumpMap();
+ void transferFrame(uint8 from, uint8 to, uint8 offset);
+ void zoom();
+ void multiGet(uint8 *dst, uint16 x, uint16 y, uint8 width, uint8 height);
+ void multiPut(const uint8 *src, uint16 x, uint16 y, uint8 width, uint8 height);
+ void multiDump(uint16 x, uint16 y, uint8 width, uint8 height);
+ void workToScreen();
+ void frameOutV(uint8 *dst, const uint8 *src, uint16 pitch, uint16 width, uint16 height, int16 x, int16 y);
+ void frameOutNm(uint8 *dst, const uint8 *src, uint16 pitch, uint16 width, uint16 height, uint16 x, uint16 y);
+ void frameOutBh(uint8 *dst, const uint8 *src, uint16 pitch, uint16 width, uint16 height, uint16 x, uint16 y);
+ void frameOutFx(uint8 *dst, const uint8 *src, uint16 pitch, uint16 width, uint16 height, uint16 x, uint16 y);
+ void doShake();
+ void vSync();
+ void setMode();
+ void showPCX(const Common::String &suffix);
+ void showFrameInternal(const uint8 *pSrc, uint16 x, uint16 y, uint8 effectsFlag, uint8 width, uint8 height);
+ void showFrame(const GraphicsFile &frameData, uint16 x, uint16 y, uint16 frameNumber, uint8 effectsFlag, uint8 *width, uint8 *height);
+ void showFrame(const GraphicsFile &frameData, uint16 x, uint16 y, uint16 frameNumber, uint8 effectsFlag);
+ bool pixelCheckSet(const ObjPos *pos, uint8 x, uint8 y);
+ void loadPalFromIFF();
+ void createPanel();
+ void createPanel2();
+ void showPanel();
};
} // End of namespace DreamWeb
diff --git a/engines/dreamweb/keypad.cpp b/engines/dreamweb/keypad.cpp
new file mode 100644
index 0000000000..2ab5835997
--- /dev/null
+++ b/engines/dreamweb/keypad.cpp
@@ -0,0 +1,866 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "dreamweb/dreamweb.h"
+
+namespace DreamWeb {
+
+const uint16 kKeypadx = 36+112;
+const uint16 kKeypady = 72;
+
+void DreamWebEngine::enterCode(uint8 digit0, uint8 digit1, uint8 digit2, uint8 digit3) {
+ RectWithCallback keypadList[] = {
+ { kKeypadx+9,kKeypadx+30,kKeypady+9,kKeypady+22,&DreamWebEngine::buttonOne },
+ { kKeypadx+31,kKeypadx+52,kKeypady+9,kKeypady+22,&DreamWebEngine::buttonTwo },
+ { kKeypadx+53,kKeypadx+74,kKeypady+9,kKeypady+22,&DreamWebEngine::buttonThree },
+ { kKeypadx+9,kKeypadx+30,kKeypady+23,kKeypady+40,&DreamWebEngine::buttonFour },
+ { kKeypadx+31,kKeypadx+52,kKeypady+23,kKeypady+40,&DreamWebEngine::buttonFive },
+ { kKeypadx+53,kKeypadx+74,kKeypady+23,kKeypady+40,&DreamWebEngine::buttonSix },
+ { kKeypadx+9,kKeypadx+30,kKeypady+41,kKeypady+58,&DreamWebEngine::buttonSeven },
+ { kKeypadx+31,kKeypadx+52,kKeypady+41,kKeypady+58,&DreamWebEngine::buttonEight },
+ { kKeypadx+53,kKeypadx+74,kKeypady+41,kKeypady+58,&DreamWebEngine::buttonNine },
+ { kKeypadx+9,kKeypadx+30,kKeypady+59,kKeypady+73,&DreamWebEngine::buttonNought },
+ { kKeypadx+31,kKeypadx+74,kKeypady+59,kKeypady+73,&DreamWebEngine::buttonEnter },
+ { kKeypadx+72,kKeypadx+86,kKeypady+80,kKeypady+94,&DreamWebEngine::quitKey },
+ { 0,320,0,200,&DreamWebEngine::blank },
+ { 0xFFFF,0,0,0,0 }
+ };
+
+ getRidOfReels();
+ loadKeypad();
+ createPanel();
+ showIcon();
+ showOuterPad();
+ showKeypad();
+ readMouse();
+ showPointer();
+ workToScreen();
+ delPointer();
+ _pressPointer = 0;
+ _getBack = 0;
+ while (true) {
+ delPointer();
+ readMouse();
+ showKeypad();
+ showPointer();
+ vSync();
+ if (_pressCount == 0) {
+ _pressed = 255;
+ _graphicPress = 255;
+ vSync();
+ } else
+ --_pressCount;
+
+ dumpPointer();
+ dumpKeypad();
+ dumpTextLine();
+ checkCoords(keypadList);
+ if (_quitRequested || (_getBack == 1))
+ break;
+ if (_lightCount == 1) {
+ if (_vars._lockStatus == 0)
+ break;
+ } else {
+ if (_pressCount == 40) {
+ addToPressList();
+ if (_pressed == 11) {
+ if (isItRight(digit0, digit1, digit2, digit3))
+ _vars._lockStatus = 0;
+ playChannel1(11);
+ _lightCount = 120;
+ _pressPointer = 0;
+ }
+ }
+ }
+ }
+ _manIsOffScreen = 0;
+ _keypadGraphics.clear();
+ restoreReels();
+ redrawMainScrn();
+ workToScreenM();
+}
+
+// Note: isItRight comes from use.asm, but is only used by enterCode(),
+// so we place it here.
+bool DreamWebEngine::isItRight(uint8 digit0, uint8 digit1, uint8 digit2, uint8 digit3) {
+
+ return digit0 == _pressList[0] && digit1 == _pressList[1]
+ && digit2 == _pressList[2] && digit3 == _pressList[3];
+}
+
+void DreamWebEngine::loadKeypad() {
+ loadGraphicsFile(_keypadGraphics, "G02");
+}
+
+void DreamWebEngine::quitKey() {
+ commandOnlyCond(4, 222);
+
+ if (_mouseButton != _oldButton && (_mouseButton & 1))
+ _getBack = 1;
+}
+
+void DreamWebEngine::addToPressList() {
+ if (_pressPointer == 5)
+ return;
+ uint8 pressed = _pressed;
+ if (pressed == 10)
+ pressed = 0;
+
+ _pressList[_pressPointer] = pressed;
+ ++_pressPointer;
+}
+
+void DreamWebEngine::buttonOne() {
+ buttonPress(1);
+}
+
+void DreamWebEngine::buttonTwo() {
+ buttonPress(2);
+}
+
+void DreamWebEngine::buttonThree() {
+ buttonPress(3);
+}
+
+void DreamWebEngine::buttonFour() {
+ buttonPress(4);
+}
+
+void DreamWebEngine::buttonFive() {
+ buttonPress(5);
+}
+
+void DreamWebEngine::buttonSix() {
+ buttonPress(6);
+}
+
+void DreamWebEngine::buttonSeven() {
+ buttonPress(7);
+}
+
+void DreamWebEngine::buttonEight() {
+ buttonPress(8);
+}
+
+void DreamWebEngine::buttonNine() {
+ buttonPress(9);
+}
+
+void DreamWebEngine::buttonNought() {
+ buttonPress(10);
+}
+
+void DreamWebEngine::buttonEnter() {
+ buttonPress(11);
+}
+
+void DreamWebEngine::buttonPress(uint8 buttonId) {
+ commandOnlyCond(buttonId + 4, buttonId + 100);
+ if ((_mouseButton & 1) && (_mouseButton != _oldButton)) {
+ _pressed = buttonId;
+ _graphicPress = buttonId + 21;
+ _pressCount = 40;
+ if (buttonId != 11)
+ playChannel1(10);
+ }
+}
+
+void DreamWebEngine::showOuterPad() {
+ showFrame(_keypadGraphics, kKeypadx-3, kKeypady-4, 1, 0);
+ showFrame(_keypadGraphics, kKeypadx+74, kKeypady+76, 37, 0);
+}
+
+void DreamWebEngine::showKeypad() {
+ singleKey(22, kKeypadx+9, kKeypady+5);
+ singleKey(23, kKeypadx+31, kKeypady+5);
+ singleKey(24, kKeypadx+53, kKeypady+5);
+ singleKey(25, kKeypadx+9, kKeypady+23);
+ singleKey(26, kKeypadx+31, kKeypady+23);
+ singleKey(27, kKeypadx+53, kKeypady+23);
+ singleKey(28, kKeypadx+9, kKeypady+41);
+ singleKey(29, kKeypadx+31, kKeypady+41);
+ singleKey(30, kKeypadx+53, kKeypady+41);
+ singleKey(31, kKeypadx+9, kKeypady+59);
+ singleKey(32, kKeypadx+31, kKeypady+59);
+ if (_lightCount) {
+ --_lightCount;
+ uint8 frameIndex;
+ uint16 y;
+ if (_vars._lockStatus) {
+ frameIndex = 36;
+ y = kKeypady-1+63;
+ } else {
+ frameIndex = 41;
+ y = kKeypady+4+63;
+ }
+ if ((_lightCount >= 60) && (_lightCount < 100))
+ --frameIndex;
+ showFrame(_keypadGraphics, kKeypadx+60, y, frameIndex, 0);
+ }
+}
+
+void DreamWebEngine::singleKey(uint8 key, uint16 x, uint16 y) {
+ if (key == _graphicPress) {
+ key += 11;
+ if (_pressCount < 8)
+ key -= 11;
+ }
+ key -= 20;
+ showFrame(_keypadGraphics, x, y, key, 0);
+}
+
+void DreamWebEngine::dumpKeypad() {
+ multiDump(kKeypadx - 3, kKeypady - 4, 120, 90);
+}
+
+void DreamWebEngine::useMenu() {
+ getRidOfReels();
+ loadMenu();
+ createPanel();
+ showPanel();
+ showIcon();
+ _vars._newObs = 0;
+ drawFloor();
+ printSprites();
+ showFrame(_menuGraphics2, kMenux-48, kMenuy-4, 4, 0);
+ getUnderMenu();
+ showFrame(_menuGraphics2, kMenux+54, kMenuy+72, 5, 0);
+ workToScreenM();
+ _getBack = 0;
+ do {
+ delPointer();
+ putUnderMenu();
+ showMenu();
+ readMouse();
+ showPointer();
+ vSync();
+ dumpPointer();
+ dumpMenu();
+ dumpTextLine();
+ RectWithCallback menuList[] = {
+ { kMenux+54,kMenux+68,kMenuy+72,kMenuy+88,&DreamWebEngine::quitKey },
+ { 0,320,0,200,&DreamWebEngine::blank },
+ { 0xFFFF,0,0,0,0 }
+ };
+ checkCoords(menuList);
+ } while ((_getBack != 1) && !_quitRequested);
+ _manIsOffScreen = 0;
+ redrawMainScrn();
+ _menuGraphics.clear();
+ _menuGraphics2.clear();
+ restoreReels();
+ workToScreenM();
+}
+
+void DreamWebEngine::dumpMenu() {
+ multiDump(kMenux, kMenuy, 48, 48);
+}
+
+void DreamWebEngine::getUnderMenu() {
+ multiGet(_underTimedText, kMenux, kMenuy, 48, 48);
+}
+
+void DreamWebEngine::putUnderMenu() {
+ multiPut(_underTimedText, kMenux, kMenuy, 48, 48);
+}
+
+// Note: showoutermenu from the asm version was unused and thus not placed here
+
+void DreamWebEngine::showMenu() {
+ ++_menuCount;
+ if (_menuCount == 37*2)
+ _menuCount = 0;
+ showFrame(_menuGraphics, kMenux, kMenuy, _menuCount / 2, 0);
+}
+
+void DreamWebEngine::loadMenu() {
+ loadGraphicsFile(_menuGraphics, "S02"); // sprite name 3
+ loadGraphicsFile(_menuGraphics2, "G07"); // mon. graphics 2
+}
+
+void DreamWebEngine::viewFolder() {
+ _manIsOffScreen = 1;
+ getRidOfAll();
+ loadFolder();
+ _folderPage = 0;
+ showFolder();
+ workToScreenM();
+ _getBack = 0;
+ do {
+ if (_quitRequested)
+ break;
+ delPointer();
+ readMouse();
+ showPointer();
+ vSync();
+ dumpPointer();
+ dumpTextLine();
+ checkFolderCoords();
+ } while (_getBack == 0);
+ _manIsOffScreen = 0;
+ _folderGraphics.clear();
+ _folderGraphics2.clear();
+ _folderGraphics3.clear();
+ _folderCharset.clear();
+ restoreAll();
+ redrawMainScrn();
+ workToScreenM();
+}
+
+void DreamWebEngine::nextFolder() {
+ if (_folderPage == 12) {
+ blank();
+ return;
+ }
+ commandOnlyCond(16, 201);
+ if ((_mouseButton == 1) && (_mouseButton != _oldButton)) {
+ ++_folderPage;
+ folderHints();
+ delPointer();
+ showFolder();
+ _mouseButton = 0;
+ checkFolderCoords();
+ workToScreenM();
+ }
+}
+
+void DreamWebEngine::folderHints() {
+ if (_folderPage == 5) {
+ if ((_vars._aideDead != 1) && (getLocation(13) != 1)) {
+ setLocation(13);
+ showFolder();
+ const uint8 *string = getTextInFile1(30);
+ printDirect(string, 0, 86, 141, true);
+ workToScreenM();
+ hangOnP(200);
+ }
+ } else if (_folderPage == 9) {
+ if (getLocation(7) != 1) {
+ setLocation(7);
+ showFolder();
+ const uint8 *string = getTextInFile1(31);
+ printDirect(string, 0, 86, 141, true);
+ workToScreenM();
+ hangOnP(200);
+ }
+ }
+}
+
+void DreamWebEngine::lastFolder() {
+ if (_folderPage == 0) {
+ blank();
+ return;
+ }
+ commandOnlyCond(17, 202);
+
+ if ((_mouseButton == 1) && (_mouseButton != _oldButton)) {
+ --_folderPage;
+ delPointer();
+ showFolder();
+ _mouseButton = 0;
+ checkFolderCoords();
+ workToScreenM();
+ }
+}
+
+void DreamWebEngine::checkFolderCoords() {
+ RectWithCallback folderList[] = {
+ { 280,320,160,200, &DreamWebEngine::quitKey },
+ { 143,300,6,194, &DreamWebEngine::nextFolder },
+ { 0,143,6,194, &DreamWebEngine::lastFolder },
+ { 0,320,0,200, &DreamWebEngine::blank },
+ { 0xFFFF,0,0,0, 0 }
+ };
+ checkCoords(folderList);
+}
+
+void DreamWebEngine::loadFolder() {
+ loadGraphicsFile(_folderGraphics, "G09"); // folder graphics 1
+ loadGraphicsFile(_folderGraphics2, "G10"); // folder graphics 2
+ loadGraphicsFile(_folderGraphics3, "G11"); // folder graphics 3
+ loadGraphicsFile(_folderCharset, "C02"); // character set 3
+ loadTempText("T50"); // folder text
+}
+
+void DreamWebEngine::showFolder() {
+ _commandType = 255;
+ if (_folderPage) {
+ useTempCharset(&_folderCharset);
+ createPanel2();
+ showFrame(_folderGraphics, 0, 0, 0, 0);
+ showFrame(_folderGraphics, 143, 0, 1, 0);
+ showFrame(_folderGraphics, 0, 92, 2, 0);
+ showFrame(_folderGraphics, 143, 92, 3, 0);
+ folderExit();
+ if (_folderPage != 1)
+ showLeftPage();
+ if (_folderPage != 12)
+ showRightPage();
+ useCharset1();
+ underTextLine();
+ } else {
+ createPanel2();
+ showFrame(_folderGraphics3, 143-28, 0, 0, 0);
+ showFrame(_folderGraphics3, 143-28, 92, 1, 0);
+ folderExit();
+ underTextLine();
+ }
+}
+
+void DreamWebEngine::folderExit() {
+ showFrame(_folderGraphics2, 296, 178, 6, 0);
+}
+
+void DreamWebEngine::showLeftPage() {
+ showFrame(_folderGraphics2, 0, 12, 3, 0);
+ uint16 y = 12+5;
+ for (size_t i = 0; i < 9; ++i) {
+ showFrame(_folderGraphics2, 0, y, 4, 0);
+ y += 16;
+ }
+ showFrame(_folderGraphics2, 0, y, 5, 0);
+ _lineSpacing = 8;
+ _charShift = 91;
+ _kerning = 1;
+ uint8 pageIndex = _folderPage - 2;
+ const uint8 *string = getTextInFile1(pageIndex * 2);
+ y = 48;
+ for (size_t i = 0; i < 2; ++i) {
+ uint8 lastChar;
+ do {
+ lastChar = printDirect(&string, 2, &y, 140, false);
+ y += _lineSpacing;
+ } while (lastChar != '\0');
+ }
+ _kerning = 0;
+ _charShift = 0;
+ _lineSpacing = 10;
+ uint8 *bufferToSwap = workspace() + (48*320)+2;
+ for (size_t i = 0; i < 120; ++i) {
+ for (size_t j = 0; j < 65; ++j) {
+ SWAP(bufferToSwap[j], bufferToSwap[130 - j]);
+ }
+ bufferToSwap += 320;
+ }
+}
+
+void DreamWebEngine::showRightPage() {
+ showFrame(_folderGraphics2, 143, 12, 0, 0);
+ uint16 y = 12+37;
+ for (size_t i = 0; i < 7; ++i) {
+ showFrame(_folderGraphics2, 143, y, 1, 0);
+ y += 16;
+ }
+
+ showFrame(_folderGraphics2, 143, y, 2, 0);
+ _lineSpacing = 8;
+ _kerning = 1;
+ uint8 pageIndex = _folderPage - 1;
+ const uint8 *string = getTextInFile1(pageIndex * 2);
+ y = 48;
+ for (size_t i = 0; i < 2; ++i) {
+ uint8 lastChar;
+ do {
+ lastChar = printDirect(&string, 152, &y, 140, false);
+ y += _lineSpacing;
+ } while (lastChar != '\0');
+ }
+ _kerning = 0;
+ _lineSpacing = 10;
+}
+
+void DreamWebEngine::enterSymbol() {
+ _manIsOffScreen = 1;
+ getRidOfReels();
+ loadGraphicsFile(_symbolGraphics, "G12"); // symbol graphics
+ _symbolTopX = 24;
+ _symbolTopDir = 0;
+ _symbolBotX = 24;
+ _symbolBotDir = 0;
+ redrawMainScrn();
+ showSymbol();
+ underTextLine();
+ workToScreenM();
+ _getBack = 0;
+ do {
+ delPointer();
+ updateSymbolTop();
+ updateSymbolBot();
+ showSymbol();
+ readMouse();
+ showPointer();
+ vSync();
+ dumpPointer();
+ dumpTextLine();
+ dumpSymbol();
+ RectWithCallback symbolList[] = {
+ { kSymbolx+40,kSymbolx+64,kSymboly+2,kSymboly+16,&DreamWebEngine::quitSymbol },
+ { kSymbolx,kSymbolx+52,kSymboly+20,kSymboly+50,&DreamWebEngine::setTopLeft },
+ { kSymbolx+52,kSymbolx+104,kSymboly+20,kSymboly+50,&DreamWebEngine::setTopRight },
+ { kSymbolx,kSymbolx+52,kSymboly+50,kSymboly+80,&DreamWebEngine::setBotLeft },
+ { kSymbolx+52,kSymbolx+104,kSymboly+50,kSymboly+80,&DreamWebEngine::setBotRight },
+ { 0,320,0,200,&DreamWebEngine::blank },
+ { 0xFFFF,0,0,0,0 }
+ };
+ checkCoords(symbolList);
+ } while ((_getBack == 0) && !_quitRequested);
+ if ((_symbolBotNum == 3) && (_symbolTopNum == 5)) {
+ removeSetObject(43);
+ placeSetObject(46);
+ turnAnyPathOn(0, _roomNum + 12);
+ _manIsOffScreen = 0;
+ redrawMainScrn();
+ _symbolGraphics.clear();
+ restoreReels();
+ workToScreenM();
+ playChannel1(13);
+ } else {
+ removeSetObject(46);
+ placeSetObject(43);
+ turnAnyPathOff(0, _roomNum + 12);
+ _manIsOffScreen = 0;
+ redrawMainScrn();
+ _symbolGraphics.clear();
+ restoreReels();
+ workToScreenM();
+ }
+}
+
+void DreamWebEngine::quitSymbol() {
+ if (_symbolTopX != 24 || _symbolBotX != 24) {
+ blank();
+ return;
+ };
+
+ commandOnlyCond(18, 222);
+
+ if (_mouseButton == _oldButton)
+ return; // notqs
+
+ if (!(_mouseButton & 1))
+ return;
+
+ _getBack = 1;
+}
+
+void DreamWebEngine::setTopLeft() {
+ if (_symbolTopDir != 0) {
+ blank();
+ return;
+ }
+
+ commandOnlyCond(19, 210);
+
+ if (_mouseButton != 0)
+ _symbolTopDir = -1;
+}
+
+void DreamWebEngine::setTopRight() {
+ if (_symbolTopDir != 0) {
+ blank();
+ return;
+ }
+
+ commandOnlyCond(20, 211);
+
+ if (_mouseButton != 0)
+ _symbolTopDir = +1;
+}
+
+void DreamWebEngine::setBotLeft() {
+ if (_symbolBotDir != 0) {
+ blank();
+ return;
+ }
+
+ commandOnlyCond(21, 212);
+
+ if (_mouseButton != 0)
+ _symbolBotDir = -1;
+}
+
+void DreamWebEngine::setBotRight() {
+ if (_symbolBotDir != 0) {
+ blank();
+ return;
+ }
+
+ commandOnlyCond(22, 213);
+
+ if (_mouseButton != 0)
+ _symbolBotDir = +1;
+}
+
+void DreamWebEngine::dumpSymbol() {
+ _newTextLine = 0;
+ multiDump(kSymbolx, kSymboly + 20, 104, 60);
+}
+
+void DreamWebEngine::showSymbol() {
+ showFrame(_symbolGraphics, kSymbolx, kSymboly, 12, 0);
+
+ showFrame(_symbolGraphics, _symbolTopX + kSymbolx-44, kSymboly+20, _symbolTopNum, 32);
+ uint8 nextTopSymbol = nextSymbol(_symbolTopNum);
+ showFrame(_symbolGraphics, _symbolTopX + kSymbolx+5, kSymboly+20, nextTopSymbol, 32);
+ uint8 nextNextTopSymbol = nextSymbol(nextTopSymbol);
+ showFrame(_symbolGraphics, _symbolTopX + kSymbolx+54, kSymboly+20, nextNextTopSymbol, 32);
+
+ showFrame(_symbolGraphics, _symbolBotX + kSymbolx-44, kSymboly+49, 6 + _symbolBotNum, 32);
+ uint8 nextBotSymbol = nextSymbol(_symbolBotNum);
+ showFrame(_symbolGraphics, _symbolBotX + kSymbolx+5, kSymboly+49, 6 + nextBotSymbol, 32);
+ uint8 nextNextBotSymbol = nextSymbol(nextBotSymbol);
+ showFrame(_symbolGraphics, _symbolBotX + kSymbolx+54, kSymboly+49, 6 + nextNextBotSymbol, 32);
+}
+
+uint8 DreamWebEngine::nextSymbol(uint8 symbol) {
+ uint8 result = symbol + 1;
+ if (result == 6)
+ return 0;
+ if (result == 12)
+ return 6;
+ return result;
+}
+
+void DreamWebEngine::updateSymbolTop() {
+ if (!_symbolTopDir)
+ return; // topfinished
+
+ if (_symbolTopDir == -1) {
+ // Backward
+ _symbolTopX--;
+ if (_symbolTopX != (byte)-1) {
+ // Not wrapping
+ if (_symbolTopX != 24)
+ return; // topfinished
+ _symbolTopDir = 0;
+ } else {
+ _symbolTopX = 48;
+ _symbolTopNum++;
+ if (_symbolTopNum != 6)
+ return; // topfinished
+ _symbolTopNum = 0;
+ }
+ } else {
+ // Forward
+ _symbolTopX++;
+ if (_symbolTopX != 49) {
+ // Not wrapping
+ if (_symbolTopX != 24)
+ return; // topfinished
+ _symbolTopDir = 0;
+ } else {
+ _symbolTopX = 0;
+ _symbolTopNum--;
+ if (_symbolTopNum != (byte)-1)
+ return; // topfinished
+ _symbolTopNum = 5;
+ }
+ }
+}
+
+void DreamWebEngine::updateSymbolBot() {
+ if (!_symbolBotDir)
+ return; // botfinished
+
+ if (_symbolBotDir == -1) {
+ // Backward
+ _symbolBotX--;
+ if (_symbolBotX != (byte)-1) {
+ // Not wrapping
+ if (_symbolBotX != 24)
+ return; // botfinished
+ _symbolBotDir = 0;
+ } else {
+ _symbolBotX = 48;
+ _symbolBotNum++;
+ if (_symbolBotNum != 6)
+ return; // botfinished
+ _symbolBotNum = 0;
+ }
+ } else {
+ // Forward
+ _symbolBotX++;
+ if (_symbolBotX != 49) {
+ // Not wrapping
+ if (_symbolBotX != 24)
+ return; // botfinished
+ _symbolBotDir = 0;
+ } else {
+ _symbolBotX = 0;
+ _symbolBotNum--;
+ if (_symbolBotNum != (byte)-1)
+ return; // botfinished
+ _symbolBotNum = 5;
+ }
+ }
+}
+
+void DreamWebEngine::useDiary() {
+ getRidOfReels();
+ loadGraphicsFile(_diaryGraphics, "G14");
+ loadTempText("T51");
+ loadGraphicsFile(_diaryCharset, "C02");
+ createPanel();
+ showIcon();
+ showDiary();
+ underTextLine();
+ showDiaryPage();
+ readMouse();
+ showPointer();
+ workToScreen();
+ delPointer();
+ _getBack = 0;
+
+ RectWithCallback diaryList[] = {
+ { kDiaryx+94,kDiaryx+110,kDiaryy+97,kDiaryy+113,&DreamWebEngine::diaryKeyN },
+ { kDiaryx+151,kDiaryx+167,kDiaryy+71,kDiaryy+87,&DreamWebEngine::diaryKeyP },
+ { kDiaryx+176,kDiaryx+192,kDiaryy+108,kDiaryy+124,&DreamWebEngine::quitKey },
+ { 0,320,0,200,&DreamWebEngine::blank },
+ { 0xFFFF,0,0,0,0 }
+ };
+
+ do {
+ delPointer();
+ readMouse();
+ showDiaryKeys();
+ showPointer();
+ vSync();
+ dumpPointer();
+ dumpDiaryKeys();
+ dumpTextLine();
+ checkCoords(diaryList);
+ } while (!_getBack && !_quitRequested);
+
+
+ _diaryGraphics.clear();
+ getRidOfTempText();
+ _diaryCharset.clear();
+ restoreReels();
+ _manIsOffScreen = 0;
+ redrawMainScrn();
+ workToScreenM();
+}
+
+void DreamWebEngine::showDiary() {
+ showFrame(_diaryGraphics, kDiaryx, kDiaryy + 37, 1, 0);
+ showFrame(_diaryGraphics, kDiaryx + 176, kDiaryy + 108, 2, 0);
+}
+
+void DreamWebEngine::showDiaryKeys() {
+ if (!_pressCount)
+ return; // nokeyatall
+
+ _pressCount--;
+
+ if (!_pressCount)
+ return; // nokeyatall
+
+ if (_pressed == 'N') {
+ byte frame = (_pressCount == 1) ? 3 : 4;
+ showFrame(_diaryGraphics, kDiaryx + 94, kDiaryy + 97, frame, 0);
+ } else {
+ byte frame = (_pressCount == 1) ? 5 : 6;
+ showFrame(_diaryGraphics, kDiaryx + 151, kDiaryy + 71, frame, 0);
+ }
+
+ if (_pressCount == 1)
+ showDiaryPage();
+}
+
+void DreamWebEngine::dumpDiaryKeys() {
+ if (_pressCount == 1) {
+ if (_vars._sartainDead != 1 && _diaryPage == 5 && getLocation(6) != 1) {
+ // Add Sartain Industries note
+ setLocation(6);
+ delPointer();
+ const uint8 *string = getTextInFile1(12);
+ printDirect(string, 70, 106, 241, 241 & 1);
+ workToScreenM();
+ hangOnP(200);
+ createPanel();
+ showIcon();
+ showDiary();
+ showDiaryPage();
+ workToScreenM();
+ showPointer();
+ return;
+ } else {
+ multiDump(kDiaryx + 48, kDiaryy + 15, 200, 16);
+ }
+ }
+
+ multiDump(kDiaryx + 94, kDiaryy + 97, 16, 16);
+ multiDump(kDiaryx + 151, kDiaryy + 71, 16, 16);
+}
+
+void DreamWebEngine::diaryKeyP() {
+ commandOnlyCond(23, 214);
+
+ if (!_mouseButton ||
+ _oldButton == _mouseButton ||
+ _pressCount)
+ return; // notkeyp
+
+ playChannel1(16);
+ _pressCount = 12;
+ _pressed = 'P';
+ _diaryPage--;
+
+ if (_diaryPage == 0xFF)
+ _diaryPage = 11;
+}
+
+void DreamWebEngine::diaryKeyN() {
+ commandOnlyCond(23, 213);
+
+ if (!_mouseButton ||
+ _oldButton == _mouseButton ||
+ _pressCount)
+ return; // notkeyn
+
+ playChannel1(16);
+ _pressCount = 12;
+ _pressed = 'N';
+ _diaryPage++;
+
+ if (_diaryPage == 12)
+ _diaryPage = 0;
+}
+
+void DreamWebEngine::showDiaryPage() {
+ showFrame(_diaryGraphics, kDiaryx, kDiaryy, 0, 0);
+ _kerning = 1;
+ useTempCharset(&_diaryCharset);
+ _charShift = 91+91;
+ const uint8 *string = getTextInFile1(_diaryPage);
+ uint16 y = kDiaryy + 16;
+ printDirect(&string, kDiaryx + 48, &y, 240, 240 & 1);
+ y = kDiaryy + 16;
+ printDirect(&string, kDiaryx + 129, &y, 240, 240 & 1);
+ y = kDiaryy + 23;
+ printDirect(&string, kDiaryx + 48, &y, 240, 240 & 1);
+ _kerning = 0;
+ _charShift = 0;
+ useCharset1();
+}
+
+} // End of namespace DreamWeb
diff --git a/engines/dreamweb/module.mk b/engines/dreamweb/module.mk
index 21429dc960..6bc4f8728e 100644
--- a/engines/dreamweb/module.mk
+++ b/engines/dreamweb/module.mk
@@ -5,14 +5,22 @@ MODULE_OBJS := \
console.o \
detection.o \
dreamweb.o \
- dreamgen.o \
+ keypad.o \
+ monitor.o \
+ newplace.o \
object.o \
pathfind.o \
+ people.o \
print.o \
+ rain.o \
saveload.o \
+ sound.o \
sprite.o \
stubs.o \
+ talk.o \
+ titles.o \
use.o \
+ vgafades.o \
vgagrafx.o
# This module can be built as a plugin
diff --git a/engines/dreamweb/monitor.cpp b/engines/dreamweb/monitor.cpp
new file mode 100644
index 0000000000..95aa400c3a
--- /dev/null
+++ b/engines/dreamweb/monitor.cpp
@@ -0,0 +1,705 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "dreamweb/dreamweb.h"
+
+namespace DreamWeb {
+
+struct MonitorKeyEntry {
+ uint8 keyAssigned;
+ char username[12];
+ char password[12];
+};
+
+// New monitor key list
+static MonitorKeyEntry monitorKeyEntries[4] = {
+ { 1, "PUBLIC", "PUBLIC" },
+ { 0, "RYAN", "BLACKDRAGON" },
+ { 0, "LOUIS", "HENDRIX" },
+ { 0, "BECKETT", "SEPTIMUS" }
+};
+
+void DreamWebEngine::useMon() {
+ _vars._lastTrigger = 0;
+ _currentFile[0] = 34;
+ memset(_currentFile+1, ' ', 12);
+ _currentFile[13] = 0;
+
+ monitorKeyEntries[0].keyAssigned = 1;
+ monitorKeyEntries[1].keyAssigned = 0;
+ monitorKeyEntries[2].keyAssigned = 0;
+ monitorKeyEntries[3].keyAssigned = 0;
+
+ createPanel();
+ showPanel();
+ showIcon();
+ drawFloor();
+ getRidOfAll();
+ loadGraphicsFile(_monitorGraphics, "G03"); // mon. graphic name
+ loadPersonal();
+ loadNews();
+ loadCart();
+ loadGraphicsFile(_monitorCharset, "C01"); // character set 2
+ printOuterMon();
+ initialMonCols();
+ printLogo();
+ workToScreen();
+ turnOnPower();
+ fadeUpYellows();
+ fadeUpMonFirst();
+ _monAdX = 76;
+ _monAdY = 141;
+ monMessage(1);
+ hangOnCurs(120);
+ monMessage(2);
+ randomAccess(60);
+ monMessage(3);
+ hangOnCurs(100);
+ printLogo();
+ scrollMonitor();
+ _bufferIn = 0;
+ _bufferOut = 0;
+ bool stop = false;
+ do {
+ uint16 oldMonadx = _monAdX;
+ uint16 oldMonady = _monAdY;
+ input();
+ _monAdX = oldMonadx;
+ _monAdY = oldMonady;
+ stop = execCommand();
+ if (_quitRequested) //TODO : Check why it crashes when put before the execcommand
+ break;
+ } while (!stop);
+ _monitorGraphics.clear();
+ _monitorCharset.clear();
+
+ _textFile1.clear();
+ _textFile2.clear();
+ _textFile3.clear();
+
+ _getBack = 1;
+ playChannel1(26);
+ _manIsOffScreen = 0;
+ restoreAll();
+ redrawMainScrn();
+ workToScreenM();
+}
+
+bool DreamWebEngine::execCommand() {
+ static const char *comlist[] = {
+ "EXIT",
+ "HELP",
+ "LIST",
+ "READ",
+ "LOGON",
+ "KEYS"
+ };
+
+ if (_inputLine[0] == 0) {
+ // No input
+ scrollMonitor();
+ return false;
+ }
+
+ int cmd;
+ bool done = false;
+ // Loop over all commands in the list and see if we get a match
+ for (cmd = 0; cmd < ARRAYSIZE(comlist); ++cmd) {
+ const char *cmdStr = comlist[cmd];
+ const char *inputStr = _inputLine;
+ // Compare the command, char by char, to see if we get a match.
+ // We only care about the prefix matching, though.
+ char inputChar, cmdChar;
+ do {
+ inputChar = *inputStr; inputStr += 2;
+ cmdChar = *cmdStr++;
+ if (cmdChar == 0) {
+ done = true;
+ break;
+ }
+ } while (inputChar == cmdChar);
+
+ if (done)
+ break;
+ }
+
+ // Execute the selected command
+ switch (cmd) {
+ case 0:
+ return true;
+ case 1:
+ monMessage(6);
+ break;
+ case 2:
+ dirCom();
+ break;
+ case 3:
+ read();
+ break;
+ case 4:
+ signOn();
+ break;
+ case 5:
+ showKeys();
+ break;
+ default:
+ netError();
+ break;
+ }
+ return false;
+}
+
+
+
+void DreamWebEngine::monitorLogo() {
+ if (_logoNum != _oldLogoNum) {
+ _oldLogoNum = _logoNum;
+ //fadeDownMon(); // FIXME: Commented out in ASM
+ printLogo();
+ printUnderMonitor();
+ workToScreen();
+ printLogo();
+ //fadeUpMon(); // FIXME: Commented out in ASM
+ printLogo();
+ playChannel1(26);
+ randomAccess(20);
+ } else {
+ printLogo();
+ }
+}
+
+void DreamWebEngine::printLogo() {
+ showFrame(_monitorGraphics, 56, 32, 0, 0);
+ showCurrentFile();
+}
+
+void DreamWebEngine::input() {
+ memset(_inputLine, 0, 64);
+ _curPos = 0;
+ printChar(_monitorCharset, _monAdX, _monAdY, '>', 0, NULL, NULL);
+ multiDump(_monAdX, _monAdY, 6, 8);
+ _monAdX += 6;
+ _cursLocX = _monAdX;
+ _cursLocY = _monAdY;
+ while (true) {
+ printCurs();
+ vSync();
+ delCurs();
+ readKey();
+ if (_quitRequested)
+ return;
+ uint8 currentKey = _currentKey;
+ if (currentKey == 0)
+ continue;
+ if (currentKey == 13)
+ return;
+ if (currentKey == 8) {
+ if (_curPos > 0)
+ delChar();
+ continue;
+ }
+ if (_curPos == 28)
+ continue;
+ if ((currentKey == 32) && (_curPos == 0))
+ continue;
+ currentKey = makeCaps(currentKey);
+ _inputLine[_curPos * 2 + 0] = currentKey;
+ if (currentKey > 'Z')
+ continue;
+ multiGet(_mapStore + _curPos * 256, _monAdX, _monAdY, 8, 8);
+ uint8 charWidth;
+ printChar(_monitorCharset, _monAdX, _monAdY, currentKey, 0, &charWidth, NULL);
+ _inputLine[_curPos * 2 + 1] = charWidth;
+ _monAdX += charWidth;
+ ++_curPos;
+ _cursLocX += charWidth;
+ }
+}
+
+byte DreamWebEngine::makeCaps(byte c) {
+ // TODO: Replace calls to this by toupper() ?
+ if (c >= 'a')
+ c -= 'a' - 'A'; // = 32
+ return c;
+}
+
+void DreamWebEngine::delChar() {
+ --_curPos;
+ _inputLine[_curPos * 2] = 0;
+ uint8 width = _inputLine[_curPos * 2 + 1];
+ _monAdX -= width;
+ _cursLocX -= width;
+ uint16 offset = _curPos;
+ offset = ((offset & 0x00ff) << 8) | ((offset & 0xff00) >> 8);
+ multiPut(_mapStore + offset, _monAdX, _monAdY, 8, 8);
+ multiDump(_monAdX, _monAdY, 8, 8);
+}
+
+void DreamWebEngine::printCurs() {
+ uint16 x = _cursLocX;
+ uint16 y = _cursLocY;
+ uint16 height;
+ if (_foreignRelease) {
+ y -= 3;
+ height = 11;
+ } else
+ height = 8;
+ multiGet(_textUnder, x, y, 6, height);
+ ++_mainTimer;
+ if ((_mainTimer & 16) == 0)
+ showFrame(_monitorCharset, x, y, '/' - 32, 0);
+ multiDump(x - 6, y, 12, height);
+}
+
+void DreamWebEngine::delCurs() {
+ uint16 x = _cursLocX;
+ uint16 y = _cursLocY;
+ uint16 width = 6;
+ uint16 height;
+ if (_foreignRelease) {
+ y -= 3;
+ height = 11;
+ } else
+ height = 8;
+ multiPut(_textUnder, x, y, width, height);
+ multiDump(x, y, width, height);
+}
+
+void DreamWebEngine::scrollMonitor() {
+ printLogo();
+ printUnderMonitor();
+ workToScreen();
+ playChannel1(25);
+}
+
+void DreamWebEngine::showCurrentFile() {
+ uint16 x;
+ // Monitor Frame position differs between Floppy and CD version
+ if (isCD())
+ x = 178;
+ else
+ x = 199;
+ const char *currentFile = _currentFile + 1;
+ while (*currentFile) {
+ char c = *currentFile++;
+ c = modifyChar(c);
+ printChar(_monitorCharset, &x, 37, c, 0, NULL, NULL);
+ }
+}
+
+void DreamWebEngine::accessLightOn() {
+ showFrame(_monitorGraphics, 74, 182, 8, 0);
+ multiDump(74, 182, 12, 8);
+}
+
+void DreamWebEngine::accessLightOff() {
+ showFrame(_monitorGraphics, 74, 182, 7, 0);
+ multiDump(74, 182, 12, 8);
+}
+
+void DreamWebEngine::randomAccess(uint16 count) {
+ for (uint16 i = 0; i < count; ++i) {
+ vSync();
+ vSync();
+ uint16 v = _rnd.getRandomNumber(15);
+ if (v < 10)
+ accessLightOff();
+ else
+ accessLightOn();
+ }
+ accessLightOff();
+}
+
+void DreamWebEngine::monMessage(uint8 index) {
+ assert(index > 0);
+ const char *string = _textFile1._text;
+ for (uint8 i = 0; i < index; ++i) {
+ while (*string++ != '+') {
+ }
+ }
+ monPrint(string);
+}
+
+void DreamWebEngine::netError() {
+ monMessage(5);
+ scrollMonitor();
+}
+
+void DreamWebEngine::powerLightOn() {
+ showFrame(_monitorGraphics, 257+4, 182, 6, 0);
+ multiDump(257+4, 182, 12, 8);
+}
+
+void DreamWebEngine::powerLightOff() {
+ showFrame(_monitorGraphics, 257+4, 182, 5, 0);
+ multiDump(257+4, 182, 12, 8);
+}
+
+void DreamWebEngine::lockLightOn() {
+ showFrame(_monitorGraphics, 56, 182, 10, 0);
+ multiDump(58, 182, 12, 8);
+}
+
+void DreamWebEngine::lockLightOff() {
+ showFrame(_monitorGraphics, 56, 182, 9, 0);
+ multiDump(58, 182, 12, 8);
+}
+
+void DreamWebEngine::turnOnPower() {
+ for (size_t i = 0; i < 3; ++i) {
+ powerLightOn();
+ hangOn(30);
+ powerLightOff();
+ hangOn(30);
+ }
+ powerLightOn();
+}
+
+void DreamWebEngine::printOuterMon() {
+ showFrame(_monitorGraphics, 40, 32, 1, 0);
+ showFrame(_monitorGraphics, 264, 32, 2, 0);
+ showFrame(_monitorGraphics, 40, 12, 3, 0);
+ showFrame(_monitorGraphics, 40, 164, 4, 0);
+}
+
+void DreamWebEngine::loadPersonal() {
+ if (_vars._location == 0 || _vars._location == 42)
+ loadTextFile(_textFile1, "T01"); // monitor file 1
+ else
+ loadTextFile(_textFile1, "T02"); // monitor file 2
+}
+
+void DreamWebEngine::loadNews() {
+ // textfile2 holds information accessible by anyone
+ if (_vars._newsItem == 0)
+ loadTextFile(_textFile2, "T10"); // monitor file 10
+ else if (_vars._newsItem == 1)
+ loadTextFile(_textFile2, "T11"); // monitor file 11
+ else if (_vars._newsItem == 2)
+ loadTextFile(_textFile2, "T12"); // monitor file 12
+ else
+ loadTextFile(_textFile2, "T13"); // monitor file 13
+}
+
+void DreamWebEngine::loadCart() {
+ byte cartridgeId = 0;
+ uint16 objectIndex = findSetObject("INTF");
+ uint16 cartridgeIndex = checkInside(objectIndex, 1);
+ if (cartridgeIndex != kNumexobjects)
+ cartridgeId = getExAd(cartridgeIndex)->objId[3] + 1;
+
+ if (cartridgeId == 0)
+ loadTextFile(_textFile3, "T20"); // monitor file 20
+ else if (cartridgeId == 1)
+ loadTextFile(_textFile3, "T21"); // monitor file 21
+ else if (cartridgeId == 2)
+ loadTextFile(_textFile3, "T22"); // monitor file 22
+ else if (cartridgeId == 3)
+ loadTextFile(_textFile3, "T23"); // monitor file 23
+ else
+ loadTextFile(_textFile3, "T24"); // monitor file 24
+}
+
+void DreamWebEngine::showKeys() {
+ randomAccess(10);
+ scrollMonitor();
+ monMessage(18);
+
+ for (int i = 0; i < 4; i++) {
+ if (monitorKeyEntries[i].keyAssigned)
+ monPrint(monitorKeyEntries[i].username);
+ }
+
+ scrollMonitor();
+}
+
+const char *DreamWebEngine::getKeyAndLogo(const char *foundString) {
+ byte newLogo = foundString[1] - 48;
+ byte keyNum = foundString[3] - 48;
+
+ if (monitorKeyEntries[keyNum].keyAssigned == 1) {
+ // Key OK
+ _logoNum = newLogo;
+ return foundString + 4;
+ } else {
+ monMessage(12); // "Access denied, key required -"
+ monPrint(monitorKeyEntries[keyNum].username);
+ scrollMonitor();
+ return 0;
+ }
+}
+
+const char *DreamWebEngine::searchForString(const char *topic, const char *text) {
+ char delim = *topic;
+
+ while (true) {
+ const char *s = topic;
+ int delimCount = 0;
+
+ char c;
+ do {
+ c = makeCaps(*text++);
+
+ if (c == '*' || (delim == '=' && c == 34))
+ return 0;
+
+ if (c == delim) {
+ delimCount++;
+ if (delimCount == 2)
+ return text;
+ }
+
+ } while (c == *s++);
+ }
+}
+
+void DreamWebEngine::dirCom() {
+ randomAccess(30);
+
+ const char *dirname = parser();
+ if (dirname[1]) {
+ dirFile(dirname);
+ return;
+ }
+
+ _logoNum = 0;
+ memcpy(_currentFile+1, "ROOT ", 12);
+ monitorLogo();
+ scrollMonitor();
+ monMessage(9);
+ searchForFiles(_textFile1._text);
+ searchForFiles(_textFile2._text);
+ searchForFiles(_textFile3._text);
+ scrollMonitor();
+}
+
+void DreamWebEngine::dirFile(const char *dirName) {
+ char topic[14];
+
+ memcpy(topic, dirName, 14);
+ topic[0] = 34;
+
+ const char *text = _textFile1._text;
+ const char *found = searchForString(topic, text);
+ if (!found) {
+ text = _textFile2._text;
+ found = searchForString(topic, text);
+ if (!found) {
+ text = _textFile3._text;
+ found = searchForString(topic, text);
+ }
+ }
+
+ if (found) {
+ found = getKeyAndLogo(found);
+ if (!found)
+ return; // not logged in
+ } else {
+ monMessage(7);
+ return;
+ }
+
+ // "keyok2"
+ memcpy(_currentFile+1, dirName+1, 12);
+ monitorLogo();
+ scrollMonitor();
+ monMessage(10);
+
+ while (true) {
+ byte curChar = *found++;
+ if (curChar == 34 || curChar == '*') {
+ // "endofdir2"
+ scrollMonitor();
+ return;
+ }
+
+ if (curChar == '=')
+ found = monPrint(found);
+ }
+}
+
+void DreamWebEngine::read() {
+ randomAccess(40);
+ const char *name = parser();
+ if (name[1] == 0) {
+ netError();
+ return;
+ }
+
+ const char *topic = _currentFile;
+
+ const char *text = _textFile1._text;
+ const char *found = searchForString(topic, text);
+ if (!found) {
+ text = _textFile2._text;
+ found = searchForString(topic, text);
+ if (!found) {
+ text = _textFile3._text;
+ found = searchForString(topic, text);
+ }
+ }
+
+ if (found) {
+ if (!getKeyAndLogo(found))
+ return;
+ } else {
+ monMessage(7);
+ return;
+ }
+
+ // "keyok1"
+ found = searchForString(name, found);
+ if (!found) {
+ _logoNum = _oldLogoNum;
+ monMessage(11);
+ return;
+ }
+
+ // "findtopictext"
+ monitorLogo();
+ scrollMonitor();
+
+ found++;
+
+ while (true) {
+ found = monPrint(found);
+ if (found[0] == 34 || found[0] == '=' || found[0] == '*') {
+ // "endoftopic"
+ scrollMonitor();
+ return;
+ }
+
+ processTrigger();
+ randomAccess(24);
+ }
+}
+
+void DreamWebEngine::signOn() {
+ const char *name = parser();
+
+ int8 foundIndex = -1;
+ Common::String inputLine = name + 1;
+ inputLine.trim();
+
+ for (byte i = 0; i < 4; i++) {
+ if (inputLine.equalsIgnoreCase(monitorKeyEntries[i].username)) {
+ // Check if the key has already been assigned
+ if (monitorKeyEntries[i].keyAssigned) {
+ monMessage(17);
+ return;
+ } else {
+ foundIndex = i;
+ break;
+ }
+ }
+ }
+
+ if (foundIndex == -1) {
+ monMessage(13);
+ return;
+ }
+
+ monMessage(15);
+
+ uint16 prevX = _monAdX;
+ uint16 prevY = _monAdY;
+ input(); // password input
+ _monAdX = prevX;
+ _monAdY = prevY;
+
+ inputLine = (const char *)_inputLine;
+ inputLine.toUppercase();
+
+ // The entered line has zeroes in-between each character
+ uint32 len = strlen(monitorKeyEntries[foundIndex].password);
+ bool found = true;
+
+ for (uint32 i = 0; i < len; i++) {
+ if (monitorKeyEntries[foundIndex].password[i] != inputLine[i * 2]) {
+ found = false;
+ break;
+ }
+ }
+
+ if (!found) {
+ scrollMonitor();
+ monMessage(16);
+ } else {
+ monMessage(14);
+ monPrint(monitorKeyEntries[foundIndex].username);
+ scrollMonitor();
+ monitorKeyEntries[foundIndex].keyAssigned = 1;
+ }
+}
+
+void DreamWebEngine::searchForFiles(const char *filesString) {
+ byte curChar;
+
+ while (true) {
+ curChar = filesString[0];
+ filesString++;
+ if (curChar == '*')
+ return; // "endofdir"
+ if (curChar == 34)
+ filesString = monPrint(filesString);
+ }
+}
+
+const char *DreamWebEngine::parser() {
+ char *output = _operand1;
+
+ memset(output, 0, 14);
+
+ *output++ = '=';
+
+ const char *in = _inputLine;
+
+ uint8 c;
+
+ // skip command
+ do {
+ c = *in++;
+ in++;
+
+ if (!c)
+ return output;
+ } while (c != 32);
+
+ // skip spaces between command and operand
+ do {
+ c = *in++;
+ in++;
+ } while (c == 32);
+
+ // copy first operand
+ do {
+ *output++ = c;
+ c = *in++;
+ in++;
+ if (!c)
+ return _operand1;
+ } while (c != 32);
+
+ return _operand1;
+}
+
+} // End of namespace DreamWeb
diff --git a/engines/dreamweb/newplace.cpp b/engines/dreamweb/newplace.cpp
new file mode 100644
index 0000000000..529c45bd4a
--- /dev/null
+++ b/engines/dreamweb/newplace.cpp
@@ -0,0 +1,271 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "dreamweb/dreamweb.h"
+
+namespace DreamWeb {
+
+void DreamWebEngine::newPlace() {
+ if (_vars._needToTravel == 1) {
+ _vars._needToTravel = 0;
+ selectLocation();
+ } else if (_autoLocation != 0xFF) {
+ _newLocation = _autoLocation;
+ _autoLocation = 0xFF;
+ }
+}
+
+void DreamWebEngine::selectLocation() {
+ _inMapArea = 0;
+ clearBeforeLoad();
+ _getBack = 0;
+ _pointerFrame = 22;
+ readCityPic();
+ showCity();
+ _cityGraphics.clear();
+ readDestIcon();
+ loadTravelText();
+ showPanel();
+ showMan();
+ showArrows();
+ showExit();
+ locationPic();
+ underTextLine();
+ _commandType = 255;
+ readMouse();
+ _pointerFrame = 0;
+ showPointer();
+ workToScreen();
+ playChannel0(9, 255);
+ _newLocation = 255;
+
+ while (_newLocation == 255) {
+ if (_quitRequested)
+ break;
+
+ delPointer();
+ readMouse();
+ showPointer();
+ vSync();
+ dumpPointer();
+ dumpTextLine();
+
+ if (_getBack == 1)
+ break;
+
+ RectWithCallback destList[] = {
+ { 238,258,4,44,&DreamWebEngine::nextDest },
+ { 104,124,4,44,&DreamWebEngine::lastDest },
+ { 280,308,4,44,&DreamWebEngine::lookAtPlace },
+ { 104,216,138,192,&DreamWebEngine::destSelect },
+ { 273,320,157,198,&DreamWebEngine::getBack1 },
+ { 0,320,0,200,&DreamWebEngine::blank },
+ { 0xFFFF,0,0,0,0 }
+ };
+ checkCoords(destList);
+ }
+
+ if (_quitRequested || _getBack == 1 || _newLocation == _vars._location) {
+ _newLocation = _realLocation;
+ _getBack = 0;
+ }
+
+ _newplaceGraphics.clear();
+ _newplaceGraphics2.clear();
+ _newplaceGraphics3.clear();
+
+ _travelText.clear();
+}
+
+void DreamWebEngine::showCity() {
+ clearWork();
+ showFrame(_cityGraphics, 57, 32, 0, 0);
+ showFrame(_cityGraphics, 120+57, 32, 1, 0);
+}
+
+void DreamWebEngine::lookAtPlace() {
+ commandOnlyCond(27, 224);
+
+ if (!(_mouseButton & 1) ||
+ _mouseButton == _oldButton ||
+ _destPos >= 15)
+ return; // noinfo
+
+ delPointer();
+ delTextLine();
+ getUnderCentre();
+ showFrame(_newplaceGraphics3, 60, 72, 0, 0);
+ showFrame(_newplaceGraphics3, 60, 72 + 55, 4, 0);
+ if (_foreignRelease)
+ showFrame(_newplaceGraphics3, 60, 72+55+21, 4, 0);
+
+ const uint8 *string = (const uint8 *)_travelText.getString(_destPos);
+ findNextColon(&string);
+ uint16 y = (_foreignRelease) ? 84 + 4 : 84;
+ printDirect(&string, 63, &y, 191, 191 & 1);
+ workToScreenM();
+ hangOnP(500);
+ _pointerMode = 0;
+ _pointerFrame = 0;
+ putUnderCentre();
+ workToScreenM();
+}
+
+void DreamWebEngine::getUnderCentre() {
+ multiGet(_mapStore, 58, 72, 254, 110);
+}
+
+void DreamWebEngine::putUnderCentre() {
+ multiPut(_mapStore, 58, 72, 254, 110);
+}
+
+void DreamWebEngine::locationPic() {
+ const int roomPics[] = { 5, 0, 3, 2, 4, 1, 10, 9, 8, 6, 11, 4, 7, 7, 0 };
+ byte picture = roomPics[_destPos];
+
+ if (picture >= 6)
+ showFrame(_newplaceGraphics2, 104, 138 + 14, picture - 6, 0); // Second slot
+ else
+ showFrame(_newplaceGraphics, 104, 138 + 14, picture + 4, 0);
+
+ if (_destPos == _realLocation)
+ showFrame(_newplaceGraphics, 104, 140 + 14, 3, 0); // Currently in this location
+
+ const uint8 *string = (const uint8 *)_travelText.getString(_destPos);
+ printDirect(string, 50, 20, 241, 241 & 1);
+}
+
+void DreamWebEngine::showArrows() {
+ showFrame(_newplaceGraphics, 116 - 12, 16, 0, 0);
+ showFrame(_newplaceGraphics, 226 + 12, 16, 1, 0);
+ showFrame(_newplaceGraphics, 280, 14, 2, 0);
+}
+
+void DreamWebEngine::nextDest() {
+ commandOnlyCond(28, 218);
+
+ if (!(_mouseButton & 1) || _oldButton == 1)
+ return; // nodu
+
+ do {
+ _destPos++;
+ if (_destPos == 15)
+ _destPos = 0; // last destination
+ } while (!getLocation(_destPos));
+
+ _newTextLine = 1;
+ delTextLine();
+ delPointer();
+ showPanel();
+ showMan();
+ showArrows();
+ locationPic();
+ underTextLine();
+ readMouse();
+ showPointer();
+ workToScreen();
+ delPointer();
+}
+
+void DreamWebEngine::lastDest() {
+ commandOnlyCond(29, 219);
+
+ if (!(_mouseButton & 1) || _oldButton == 1)
+ return; // nodd
+
+ do {
+ _destPos--;
+ if (_destPos == 0xFF)
+ _destPos = 15; // first destination
+ } while (!getLocation(_destPos));
+
+ _newTextLine = 1;
+ delTextLine();
+ delPointer();
+ showPanel();
+ showMan();
+ showArrows();
+ locationPic();
+ underTextLine();
+ readMouse();
+ showPointer();
+ workToScreen();
+ delPointer();
+}
+
+void DreamWebEngine::destSelect() {
+ commandOnlyCond(30, 222);
+
+ if (!(_mouseButton & 1) || _oldButton == 1)
+ return; // notrav
+
+ _newLocation = _destPos;
+}
+
+uint8 DreamWebEngine::getLocation(uint8 index) {
+ return _roomsCanGo[index];
+}
+
+void DreamWebEngine::setLocation(uint8 index) {
+ _roomsCanGo[index] = 1;
+}
+
+void DreamWebEngine::clearLocation(uint8 index) {
+ _roomsCanGo[index] = 0;
+}
+
+void DreamWebEngine::resetLocation(uint8 index) {
+ if (index == 5) {
+ // delete hotel
+ purgeALocation(5);
+ purgeALocation(21);
+ purgeALocation(22);
+ purgeALocation(27);
+ } else if (index == 8) {
+ // delete TV studio
+ purgeALocation(8);
+ purgeALocation(28);
+ } else if (index == 6) {
+ // delete sarters
+ purgeALocation(6);
+ purgeALocation(20);
+ purgeALocation(25);
+ } else if (index == 13) {
+ // delete boathouse
+ purgeALocation(13);
+ purgeALocation(29);
+ }
+
+ clearLocation(index);
+}
+
+void DreamWebEngine::readDestIcon() {
+ loadGraphicsFile(_newplaceGraphics, "G05");
+ loadGraphicsFile(_newplaceGraphics2, "G06");
+ loadGraphicsFile(_newplaceGraphics3, "G08");
+}
+
+void DreamWebEngine::readCityPic() {
+ loadGraphicsFile(_cityGraphics, "G04");
+}
+
+} // End of namespace DreamWeb
diff --git a/engines/dreamweb/object.cpp b/engines/dreamweb/object.cpp
index e2da902465..443366561a 100644
--- a/engines/dreamweb/object.cpp
+++ b/engines/dreamweb/object.cpp
@@ -22,93 +22,1084 @@
#include "dreamweb/dreamweb.h"
-namespace DreamGen {
+namespace DreamWeb {
-void DreamGenContext::fillryan() {
- uint8 *inv = segRef(data.word(kBuffers)).ptr(kRyaninvlist, 60);
- findallryan(inv);
- inv += data.byte(kRyanpage) * 2 * 10;
+void DreamWebEngine::showRyanPage() {
+ showFrame(_icons1, kInventx + 167, kInventy - 12, 12, 0);
+ showFrame(_icons1, kInventx + 167 + 18 * _vars._ryanPage, kInventy - 12, 13 + _vars._ryanPage, 0);
+}
+
+void DreamWebEngine::findAllRyan() {
+ memset(_ryanInvList, 0xff, sizeof(_ryanInvList));
+ for (size_t i = 0; i < kNumexobjects; ++i) {
+ const DynObject *extra = getExAd(i);
+ if (extra->mapad[0] != kExObjectType)
+ continue;
+ if (extra->mapad[1] != 0xff)
+ continue;
+ uint8 slot = extra->mapad[2];
+ assert(slot < 30);
+ _ryanInvList[slot]._index = i;
+ _ryanInvList[slot]._type = kExObjectType;
+ }
+}
+
+void DreamWebEngine::fillRyan() {
+ ObjectRef *inv = &_ryanInvList[_vars._ryanPage * 10];
+ findAllRyan();
for (size_t i = 0; i < 2; ++i) {
for (size_t j = 0; j < 5; ++j) {
- uint8 objIndex = *inv++;
- uint8 objType = *inv++;
- obtoinv(objIndex, objType, kInventx + j * kItempicsize, kInventy + i * kItempicsize);
+ obToInv(inv->_index, inv->_type, kInventx + j * kItempicsize, kInventy + i * kItempicsize);
+ ++inv;
}
}
- showryanpage();
+ showRyanPage();
}
-void DreamGenContext::isitworn() {
- flags._z = isitworn((const DynObject *)es.ptr(bx, sizeof(DynObject)));
+bool DreamWebEngine::isItWorn(const DynObject *object) {
+ return (object->objId[0] == 'W'-'A') && (object->objId[1] == 'E'-'A');
}
-bool DreamGenContext::isitworn(const DynObject *object) {
- return (object->id[0] == 'W'-'A') && (object->id[1] == 'E'-'A');
+void DreamWebEngine::wornError() {
+ _commandType = 255;
+ delPointer();
+ printMessage(76, 21, 57, 240, false);
+ workToScreenM();
+ hangOnP(50);
+ showPanel();
+ showMan();
+ examIcon();
+ _commandType = 255;
+ workToScreenM();
}
-void DreamGenContext::wornerror() {
- data.byte(kCommandtype) = 255;
- delpointer();
- printmessage(76, 21, 57, 240, false);
- worktoscreenm();
- hangonp(50);
- showpanel();
- showman();
- examicon();
- data.byte(kCommandtype) = 255;
- worktoscreenm();
+void DreamWebEngine::makeWorn(DynObject *object) {
+ object->objId[0] = 'W'-'A';
+ object->objId[1] = 'E'-'A';
}
-void DreamGenContext::makeworn() {
- makeworn((DynObject *)es.ptr(bx, sizeof(DynObject)));
+void DreamWebEngine::obToInv(uint8 index, uint8 flag, uint16 x, uint16 y) {
+ showFrame(_icons1, x - 2, y - 1, 10, 0);
+ if (index == 0xff)
+ return;
+
+ if (flag == kExObjectType)
+ showFrame(_exFrames, x + 18, y + 19, 3 * index + 1, 128);
+ else
+ showFrame(_freeFrames, x + 18, y + 19, 3 * index + 1, 128);
+
+ const DynObject *object = (const DynObject *)getAnyAdDir(index, flag);
+ bool worn = isItWorn(object);
+ if (worn)
+ showFrame(_icons1, x - 3, y - 2, 7, 0);
}
-void DreamGenContext::makeworn(DynObject *object) {
- object->id[0] = 'W'-'A';
- object->id[1] = 'E'-'A';
+void DreamWebEngine::obPicture() {
+ if (_objectType == kSetObjectType1)
+ return;
+ uint8 frame = 3 * _command + 1;
+ if (_objectType == kExObjectType)
+ showFrame(_exFrames, 160, 68, frame, 0x80);
+ else
+ showFrame(_freeFrames, 160, 68, frame, 0x80);
}
-void DreamGenContext::obtoinv() {
- obtoinv(al, ah, di, bx);
+void DreamWebEngine::obIcons() {
+ uint8 slotSize, slotCount;
+ getAnyAd(&slotSize, &slotCount);
+ if (slotSize != 0xff) {
+ // can open it
+ showFrame(_icons2, 210, 1, 4, 0);
+ }
+
+ showFrame(_icons2, 260, 1, 1, 0);
}
-void DreamGenContext::obtoinv(uint8 index, uint8 flag, uint16 x, uint16 y) {
- Frame *icons1 = (Frame *)segRef(data.word(kIcons1)).ptr(0, 0);
- showframe(icons1, x - 2, y - 1, 10, 0);
- if (index == 0xff)
+void DreamWebEngine::examineOb(bool examineAgain) {
+ _pointerMode = 0;
+ _timeCount = 0;
+
+ while (true) {
+ if (examineAgain) {
+ _inMapArea = 0;
+ _examAgain = 0;
+ _openedOb = 255;
+ _openedType = 255;
+ _invOpen = 0;
+ _objectType = _commandType;
+ _itemFrame = 0;
+ _pointerFrame = 0;
+ createPanel();
+ showPanel();
+ showMan();
+ showExit();
+ obIcons();
+ obPicture();
+ describeOb();
+ underTextLine();
+ _commandType = 255;
+ readMouse();
+ showPointer();
+ workToScreen();
+ delPointer();
+ examineAgain = false;
+ }
+
+ readMouse();
+ showPointer();
+ vSync();
+ dumpPointer();
+ dumpTextLine();
+ delPointer();
+ _getBack = 0;
+
+ switch (_invOpen) {
+ case 0: {
+ RectWithCallback examList[] = {
+ { 273,320,157,198,&DreamWebEngine::getBackFromOb },
+ { 260,300,0,44,&DreamWebEngine::useObject },
+ { 210,254,0,44,&DreamWebEngine::selectOpenOb },
+ { 144,176,64,96,&DreamWebEngine::setPickup },
+ { 0,50,50,200,&DreamWebEngine::examineInventory },
+ { 0,320,0,200,&DreamWebEngine::blank },
+ { 0xFFFF,0,0,0,0 }
+ };
+ checkCoords(examList);
+ break;
+ }
+ case 1: {
+ // Note: This table contains the non-constant _openChangeSize!
+ RectWithCallback invList1[] = {
+ { 273,320,157,198,&DreamWebEngine::getBackFromOb },
+ { 255,294,0,24,&DreamWebEngine::dropObject },
+ { kInventx+167,kInventx+167+(18*3),kInventy-18,kInventy-2,&DreamWebEngine::incRyanPage },
+ { kInventx,_openChangeSize,kInventy+100,kInventy+100+kItempicsize,&DreamWebEngine::useOpened },
+ { kInventx,kInventx+(5*kItempicsize),kInventy,kInventy+(2*kItempicsize),&DreamWebEngine::inToInv },
+ { 0,320,0,200,&DreamWebEngine::blank },
+ { 0xFFFF,0,0,0,0 }
+ };
+ checkCoords(invList1);
+ break;
+ }
+ default: {
+ RectWithCallback withList1[] = {
+ { 273,320,157,198,&DreamWebEngine::getBackFromOb },
+ { kInventx+167,kInventx+167+(18*3),kInventy-18,kInventy-2,&DreamWebEngine::incRyanPage },
+ { kInventx,kInventx+(5*kItempicsize), kInventy,kInventy+(2*kItempicsize),&DreamWebEngine::selectOb },
+ { 0,320,0,200,&DreamWebEngine::blank },
+ { 0xFFFF,0,0,0,0 }
+ };
+ checkCoords(withList1);
+ break;
+ }
+ }
+
+ if (_quitRequested)
+ break;
+ if (_examAgain != 0)
+ examineAgain = true;
+ else if (_getBack != 0)
+ break;
+ }
+
+ _pickUp = 0;
+ if (_vars._watchingTime != 0 || _newLocation == 255) {
+ // isWatching
+ makeMainScreen();
+ }
+
+ _invOpen = 0;
+ _openedOb = 255;
+}
+
+void DreamWebEngine::inventory() {
+ if (_vars._manDead == 1 || _vars._watchingTime != 0) {
+ blank();
return;
+ }
- Frame *extras = (Frame *)segRef(data.word(kExtras)).ptr(0, 0);
- Frame *frees = (Frame *)segRef(data.word(kFreeframes)).ptr(0, 0);
- Frame *frames = (flag == 4) ? extras : frees;
- showframe(frames, x + 18, y + 19, 3 * index + 1, 128);
- const DynObject *object = (const DynObject *)getanyaddir(index, flag);
- bool worn = isitworn(object);
- if (worn)
- showframe(icons1, x - 3, y - 2, 7, 0);
+ commandOnlyCond(32, 239);
+
+ if (_mouseButton == _oldButton)
+ return;
+ if (!(_mouseButton & 1)) // only on left mouse button
+ return;
+
+
+ _timeCount = 0;
+ _pointerMode = 0;
+ _inMapArea = 0;
+ animPointer();
+ createPanel();
+ showPanel();
+ examIcon();
+ showMan();
+ showExit();
+ underTextLine();
+ _pickUp = 0;
+ _invOpen = 2;
+ openInv();
+ readMouse();
+ showPointer();
+ workToScreen();
+ delPointer();
+ _openedOb = 255;
+ examineOb(false);
}
-void DreamGenContext::obpicture() {
- if (data.byte(kObjecttype) == 1)
+void DreamWebEngine::transferText(uint8 from, uint8 to) {
+ _exText.setOffset(to, _vars._exTextPos);
+ const char *src = _freeDesc.getString(from);
+ char *dst = _exText._text + _vars._exTextPos;
+
+ size_t len = strlen(src);
+ memcpy(dst, src, len + 1);
+ _vars._exTextPos += len + 1;
+}
+
+void DreamWebEngine::getBackFromOb() {
+ if (_pickUp != 1)
+ getBack1();
+ else
+ blank();
+}
+
+byte DreamWebEngine::getOpenedSlotCount() {
+ byte obj = _openedOb;
+ switch (_openedType) {
+ case kExObjectType:
+ return getExAd(obj)->slotCount;
+ case kFreeObjectType:
+ return getFreeAd(obj)->slotCount;
+ default:
+ return getSetAd(obj)->slotCount;
+ }
+}
+
+byte DreamWebEngine::getOpenedSlotSize() {
+ byte obj = _openedOb;
+ switch (_openedType) {
+ case kExObjectType:
+ return getExAd(obj)->slotSize;
+ case kFreeObjectType:
+ return getFreeAd(obj)->slotSize;
+ default:
+ return getSetAd(obj)->slotSize;
+ }
+}
+
+void DreamWebEngine::openOb() {
+ uint8 commandLine[64] = "OBJECT NAME ONE ";
+
+ copyName(_openedType, _openedOb, commandLine);
+
+ printMessage(kInventx, kInventy+86, 62, 240, false);
+
+ printDirect(commandLine, _lastXPos + 5, kInventy+86, 220, false);
+
+ fillOpen();
+ _openChangeSize = getOpenedSlotCount() * kItempicsize + kInventx;
+}
+
+void DreamWebEngine::identifyOb() {
+ if (_vars._watchingTime != 0) {
+ blank();
return;
- Frame *frames;
- if (data.byte(kObjecttype) == 4)
- frames = (Frame *)segRef(data.word(kExtras)).ptr(0, 0);
+ }
+
+ uint16 initialX = _mouseX - _mapAdX;
+ uint16 initialY = _mouseY - _mapAdY;
+
+ if (initialX >= 22 * 8 || initialY >= 20 * 8) {
+ blank();
+ return;
+ }
+
+ byte x = initialX & 0xFF;
+ byte y = initialY & 0xFF;
+
+ _inMapArea = 1;
+ _pointersPath = findPathOfPoint(x, y);
+ _pointerFirstPath = findFirstPath(x, y);
+
+ if (checkIfEx(x, y) || checkIfFree(x, y) ||
+ checkIfPerson(x, y) || checkIfSet(x, y))
+ return; // finishidentify
+
+ x = (_mouseX - _mapAdX) & 0xFF;
+ y = (_mouseY - _mapAdY) & 0xFF;
+ byte flag, flagEx, type, flagX, flagY;
+
+ checkOne(x, y, &flag, &flagEx, &type, &flagX, &flagY);
+
+ if (type != 0 && _vars._manDead != 1)
+ obName(type, 3);
else
- frames = (Frame *)segRef(data.word(kFreeframes)).ptr(0, 0);
- uint8 frame = 3 * data.byte(kCommand) + 1;
- showframe(frames, 160, 68, frame, 0x80);
+ blank();
+}
+
+ObjectRef DreamWebEngine::findInvPos() {
+ uint16 x = _mouseX - kInventx;
+ uint16 y = _mouseY - kInventy;
+ uint8 pos = (x / kItempicsize) + (y / kItempicsize) * 5;
+ uint8 invPos = _vars._ryanPage * 10 + pos;
+ _lastInvPos = invPos;
+ return _ryanInvList[invPos];
+}
+
+void DreamWebEngine::selectOb() {
+ ObjectRef objectId = findInvPos();
+ if (objectId._index == 255) {
+ blank();
+ return;
+ }
+
+ _withObject = objectId._index;
+ _withType = objectId._type;
+
+ if (objectId != _oldSubject || _commandType != 221) {
+ if (objectId == _oldSubject)
+ _commandType = 221;
+ _oldSubject = objectId;
+ commandWithOb(0, objectId._type, objectId._index);
+ }
+
+ if (_mouseButton == _oldButton || !(_mouseButton & 1))
+ return;
+
+ delPointer();
+ _invOpen = 0;
+ useRoutine();
+}
+
+void DreamWebEngine::setPickup() {
+ if (_objectType != kSetObjectType1 && _objectType != kSetObjectType3) {
+ // Object types 1 and 3 are excluded, so the resulting object is a DynObject
+ uint8 dummy;
+ DynObject *object = (DynObject *)getAnyAd(&dummy, &dummy);
+ if (object->mapad[0] == 4) {
+ blank();
+ return;
+ }
+ } else {
+ blank();
+ return;
+ }
+
+ if (_commandType != 209) {
+ _commandType = 209;
+ commandWithOb(33, _objectType, _command);
+ }
+
+ if (_mouseButton != 1 || _mouseButton == _oldButton)
+ return;
+
+ createPanel();
+ showPanel();
+ showMan();
+ showExit();
+ examIcon();
+ _pickUp = 1;
+ _invOpen = 2;
+
+ if (_objectType != kExObjectType) {
+ assert(_objectType == kFreeObjectType);
+ _openedOb = 255;
+ _itemFrame = transferToEx(_command);
+ _objectType = kExObjectType;
+ DynObject *object = getExAd(_itemFrame);
+ object->mapad[0] = 20;
+ object->mapad[1] = 255;
+ } else {
+ _itemFrame = _command;
+ _openedOb = 255;
+ }
+
+ openInv();
+ workToScreenM();
+}
+
+void DreamWebEngine::deleteExFrame(uint8 frameNum) {
+ Frame *frame = &_exFrames._frames[frameNum];
+
+ uint16 frameSize = frame->width * frame->height;
+ // Note: the original asm didn't subtract frameSize from remainder
+ uint16 remainder = kExframeslen - frame->ptr() - frameSize;
+ uint16 startOff = frame->ptr();
+ uint16 endOff = startOff + frameSize;
+
+ // Shift frame data after this one down
+ memmove(&_exFrames._data[startOff], &_exFrames._data[endOff], remainder);
+
+ // Combined frame data is now frameSize smaller
+ _vars._exFramePos -= frameSize;
+
+ // Adjust all frame pointers pointing into the shifted data
+ for (unsigned int i = 0; i < 3*kNumexobjects; ++i) {
+ frame = &_exFrames._frames[i];
+ if (frame->ptr() >= startOff)
+ frame->setPtr(frame->ptr() - frameSize);
+ }
+}
+
+void DreamWebEngine::deleteExText(uint8 textNum) {
+ uint16 offset = _exText.getOffset(textNum);
+
+ uint16 startOff = offset;
+ uint16 textSize = strlen(_exText.getString(textNum)) + 1;
+ uint16 endOff = startOff + textSize;
+ uint16 remainder = kExtextlen - offset - textSize;
+
+ // Shift text data after this one down
+ memmove(&_exText._text[startOff], &_exText._text[endOff], remainder);
+
+ // Combined text data is now frameSize smaller
+ _vars._exTextPos -= textSize;
+
+ // Adjust all text pointers pointing into the shifted data
+ for (unsigned int i = 0; i < kNumexobjects; ++i) {
+ uint16 t = _exText.getOffset(i);
+ if (t >= offset + textSize)
+ _exText.setOffset(i, t - textSize);
+ }
+}
+
+void DreamWebEngine::deleteExObject(uint8 index) {
+ DynObject *obj = getExAd(index);
+
+ memset(obj, 0xFF, sizeof(DynObject));
+
+ deleteExFrame(3*index);
+ deleteExFrame(3*index + 1);
+
+ deleteExText(index);
+
+ for (uint8 i = 0; i < kNumexobjects; ++i) {
+ DynObject *t = getExAd(i);
+ // Is this object contained in the one we've just deleted?
+ if (t->mapad[0] == 4 && t->mapad[1] == index)
+ deleteExObject(i);
+ }
+}
+
+void DreamWebEngine::removeObFromInv() {
+ if (_command == 100)
+ return; // object doesn't exist
+
+ assert(_objectType == kExObjectType);
+
+ deleteExObject(_command);
+}
+
+void DreamWebEngine::inToInv() {
+ if (!_pickUp) {
+ outOfInv();
+ return;
+ }
+
+ ObjectRef subject = findInvPos();
+
+ if (subject._index != 255) {
+ swapWithInv();
+ return;
+ }
+
+ subject._type = _objectType;
+ subject._index = _itemFrame;
+
+ if (subject != _oldSubject || _commandType != 220) {
+ if (subject == _oldSubject)
+ _commandType = 220;
+ _oldSubject = subject;
+ commandWithOb(35, subject._type, subject._index);
+ }
+
+ if (_mouseButton == _oldButton || !(_mouseButton & 1))
+ return; // notletgo2
+
+ delPointer();
+ DynObject *object = getExAd(_itemFrame);
+ object->mapad[0] = 4;
+ object->mapad[1] = 255;
+ object->mapad[2] = _lastInvPos;
+ _pickUp = 0;
+ fillRyan();
+ readMouse();
+ showPointer();
+ outOfInv();
+ workToScreen();
+ delPointer();
+}
+
+void DreamWebEngine::outOfInv() {
+ ObjectRef subject = findInvPos();
+
+ if (subject._index == 255) {
+ blank();
+ return;
+ }
+
+ if (_mouseButton == 2) {
+ reExFromInv();
+ return;
+ }
+
+ if (subject != _oldSubject || _commandType != 221) {
+ if (subject == _oldSubject)
+ _commandType = 221;
+ _oldSubject = subject;
+ commandWithOb(36, subject._type, subject._index);
+ }
+
+ if (_mouseButton == _oldButton || !(_mouseButton & 1))
+ return;
+
+ delPointer();
+ _pickUp = 1;
+ subject = findInvPos();
+ _objectType = subject._type;
+ _itemFrame = subject._index;
+ assert(subject._type == kExObjectType);
+ DynObject *object = getExAd(subject._index);
+ object->mapad[0] = 20;
+ object->mapad[1] = 255;
+ fillRyan();
+ readMouse();
+ showPointer();
+ inToInv();
+ workToScreen();
+ delPointer();
+}
+
+void DreamWebEngine::purgeALocation(uint8 index) {
+ // index == al
+ for (uint8 i = 0; i < kNumexobjects; ++i) {
+ DynObject *t = getExAd(i);
+ if (t->currentLocation == index && t->mapad[0] == 0) {
+ deleteExObject(i);
+ }
+ }
+}
+
+const uint8 *DreamWebEngine::getObTextStart() {
+ const uint8 *textBase = 0;
+ const uint8 *text;
+ uint16 textOff = 0;
+ if (_objectType == kFreeObjectType) {
+ text = (const uint8 *)_freeDesc.getString(_command);
+ } else if (_objectType == kSetObjectType1) {
+ textBase = (const uint8 *)_setDesc._text;
+ textOff = kNumSetTexts * 2;
+ text = (const uint8 *)_setDesc.getString(_command);
+ } else {
+ text = (const uint8 *)_exText.getString(_command);
+ }
+
+ if (_objectType != kSetObjectType1)
+ return text;
+
+ const uint8 *obname = text;
+ while (true) {
+ const uint8 *start = text;
+ findNextColon(&text);
+
+ // Not an empty description string?
+ if (*text != 0 && *text != ':')
+ return start;
+
+ // If the description string (of a SetObjectType1 object) is empty,
+ // look for an object with the same name.
+ // Example: Eden's garage door outside has two parts. The right part
+ // has no description of its own but uses that of the left part.
+
+ bool found = false;
+ do {
+ text++;
+ uint8 c = *obname;
+
+ // scan for matching first character
+ while (*text != c) {
+ text++;
+
+ // arbitrary give-up counter
+ // FIXME: Make this more precise to avoid reading out of bounds
+ if (text - (textBase - textOff) >= 8000) {
+ warning("Object description for %d/%d not found", _objectType, _command);
+ return obname;
+ }
+ }
+
+ // found matching first character, so match the rest
+ const uint8 *s1 = obname;
+ const uint8 *s2 = text;
+ do {
+ s1++;
+ s2++;
+ } while (*s1 != ':' && *s1 != 0 && *s1 == *s2);
+
+ if (*s1 == ':' || *s1 == 0)
+ found = true; // (prefix) matched the entire object name
+ } while (!found);
+
+ // We found an object with the same name. The next loop iteration
+ // will check if this one again has an empty description.
+ }
}
-void DreamGenContext::obicons() {
- uint8 value1, value2;
- getanyad(&value1, &value2);
- if (value1 == 0xff) {
- showframe((Frame *)segRef(data.word(kIcons2)).ptr(0, 0), 260, 1, 1, 0);
+void DreamWebEngine::dropObject() {
+ if (_commandType != 223) {
+ _commandType = 223;
+ if (!_pickUp) {
+ blank();
+ return;
+ }
+ commandWithOb(37, _objectType, _itemFrame);
+ }
+
+ if (_mouseButton == _oldButton || !(_mouseButton & 1))
+ return;
+
+ if (isItWorn(getEitherAd())) {
+ wornError();
+ return;
+ }
+
+ if (_realLocation != 47) {
+ byte flag, flagEx, type, flagX, flagY;
+ checkOne(_ryanX + 12, _ryanY + 12, &flag, &flagEx, &type, &flagX, &flagY);
+
+ if (flag >= 2) {
+ dropError();
+ return;
+ }
} else {
- showframe((Frame *)segRef(data.word(kIcons2)).ptr(0, 0), 210, 1, 4, 0);
+ dropError();
+ return;
+ }
+
+ if (_mapXSize == 64 && _mapYSize == 64) {
+ // Inside lift
+ dropError();
+ return;
+ }
+
+ if (compare(_itemFrame, kExObjectType, "GUNA") || compare(_itemFrame, kExObjectType, "SHLD")) {
+ cantDrop();
+ return;
+ }
+
+ _objectType = kExObjectType;
+ DynObject *object = getExAd(_itemFrame);
+ object->mapad[0] = 0;
+ object->mapad[1] = ((_ryanX + 4) >> 4) + _mapX;
+ object->mapad[2] = (_ryanX + 4) & 0xF;
+ object->mapad[3] = ((_ryanY + 8) >> 4) + _mapY;
+ object->mapad[4] = (_ryanY + 8) & 0xF;
+ _pickUp = 0;
+ object->currentLocation = _realLocation;
+}
+
+bool DreamWebEngine::checkObjectSize() {
+ byte containerSize = getOpenedSlotSize();
+ DynObject *object = getEitherAd();
+ // If there is no size defined for the object in the editor, set its size
+ // to 6. This could be a bad idea, according to the original source.
+ byte objectSize = (object->objectSize != 255) ? object->objectSize : 6;
+
+ if (containerSize >= 100) {
+ // Special type of container: only objects of the same special type fit.
+ if (containerSize == objectSize)
+ return true;
+
+ errorMessage3();
+ return false;
+ }
+
+ if (objectSize >= 100) {
+ // Special type of object, but a regular container.
+ // Subtract 100 from the size to get its regular size.
+ objectSize -= 100;
+ }
+
+ if (containerSize >= objectSize)
+ return true;
+
+ errorMessage2();
+ return false;
+}
+
+void DreamWebEngine::selectOpenOb() {
+ uint8 slotSize, slotCount;
+ getAnyAd(&slotSize, &slotCount);
+ if (slotCount == 255) {
+ // Can't open the object
+ blank();
+ return;
+ }
+
+ if (_commandType != 224) {
+ _commandType = 224;
+ commandWithOb(38, _objectType, _command);
+ }
+
+ if (_mouseButton == _oldButton || !(_mouseButton & 1))
+ return;
+
+ _openedOb = _command;
+ _openedType = _objectType;
+ createPanel();
+ showPanel();
+ showMan();
+ examIcon();
+ showExit();
+ openInv();
+ openOb();
+ underTextLine();
+ readMouse();
+ showPointer();
+ workToScreen();
+ delPointer();
+}
+
+void DreamWebEngine::reExFromInv() {
+ ObjectRef objectId = findInvPos();
+ _commandType = objectId._type;
+ _command = objectId._index;
+ _examAgain = 1;
+ _pointerMode = 0;
+}
+
+void DreamWebEngine::swapWithInv() {
+ ObjectRef subject;
+ subject._type = _objectType;
+ subject._index = _itemFrame;
+ if (subject != _oldSubject || _commandType != 243) {
+ if (subject == _oldSubject)
+ _commandType = 243;
+ _oldSubject = subject;
+ commandWithOb(34, subject._type, subject._index);
+ }
+
+ if (_mouseButton == _oldButton || !(_mouseButton & 1))
+ return;
+
+ byte prevType = _objectType;
+ byte prevFrame = _itemFrame;
+ ObjectRef objectId = findInvPos();
+ _itemFrame = objectId._index;
+ _objectType = objectId._type;
+ DynObject *object = getEitherAd();
+ object->mapad[0] = 20;
+ object->mapad[1] = 255;
+ byte prevType2 = _objectType;
+ byte prevFrame2 = _itemFrame;
+ _objectType = prevType;
+ _itemFrame = prevFrame;
+ delPointer();
+ object = getEitherAd();
+ object->mapad[0] = 4;
+ object->mapad[1] = 255;
+ object->mapad[2] = _lastInvPos;
+ _objectType = prevType2;
+ _itemFrame = prevFrame2;
+ fillRyan();
+ readMouse();
+ showPointer();
+ workToScreen();
+ delPointer();
+}
+
+void DreamWebEngine::useOpened() {
+ if (_openedOb == 255)
+ return; // cannot use opened object
+
+ if (!_pickUp) {
+ outOfOpen();
+ return;
+ }
+
+ ObjectRef objectId = findOpenPos();
+
+ if (objectId._index != 255) {
+ swapWithOpen();
+ return;
+ }
+
+ if (_pickUp != 1) {
+ blank();
+ return;
+ }
+
+ objectId._type = _objectType;
+ objectId._index = _itemFrame;
+ if (objectId != _oldSubject || _commandType != 227) {
+ if (objectId == _oldSubject)
+ _commandType = 227;
+ _oldSubject = objectId;
+ commandWithOb(35, objectId._type, objectId._index);
+ }
+
+ if (_mouseButton == _oldButton || !(_mouseButton & 1))
+ return;
+
+ if (isItWorn(getEitherAd())) {
+ wornError();
+ return;
+ }
+
+ delPointer();
+
+ if (_itemFrame == _openedOb &&
+ _objectType == _openedType) {
+ errorMessage1();
+ return;
+ }
+
+ if (!checkObjectSize())
+ return;
+
+ _pickUp = 0;
+ DynObject *object = getEitherAd();
+ object->mapad[0] = _openedType;
+ object->mapad[1] = _openedOb;
+ object->mapad[2] = _lastInvPos;
+ object->mapad[3] = _realLocation;
+ fillOpen();
+ underTextLine();
+ readMouse();
+ useOpened();
+ showPointer();
+ workToScreen();
+ delPointer();
+}
+
+void DreamWebEngine::outOfOpen() {
+ if (_openedOb == 255)
+ return; // cannot use opened object
+
+ ObjectRef objectId = findOpenPos();
+
+ if (objectId._index == 255) {
+ blank();
+ return;
+ }
+
+ if (objectId != _oldSubject || _commandType != 228) {
+ if (objectId == _oldSubject)
+ _commandType = 228;
+ _oldSubject = objectId;
+ commandWithOb(36, objectId._type, objectId._index);
+ }
+
+ if (_mouseButton == _oldButton)
+ return; // notletgo4
+
+ if (_mouseButton != 1) {
+ if (_mouseButton == 2)
+ reExFromOpen();
+ return;
}
+
+ delPointer();
+ _pickUp = 1;
+ objectId = findOpenPos();
+ _objectType = objectId._type;
+ _itemFrame = objectId._index;
+
+ if (_objectType != kExObjectType) {
+ assert(objectId._type == kFreeObjectType);
+ _itemFrame = transferToEx(objectId._index);
+ _objectType = kExObjectType;
+ }
+
+ DynObject *object = getEitherAd();
+ object->mapad[0] = 20;
+ object->mapad[1] = 255;
+
+ fillOpen();
+ underTextLine();
+ readMouse();
+ useOpened();
+ showPointer();
+ workToScreen();
+ delPointer();
}
-} /*namespace dreamgen */
+void DreamWebEngine::swapWithOpen() {
+ ObjectRef subject;
+ subject._type = _objectType;
+ subject._index = _itemFrame;
+ if (subject != _oldSubject || _commandType != 242) {
+ if (subject == _oldSubject)
+ _commandType = 242;
+ _oldSubject = subject;
+ commandWithOb(34, subject._type, subject._index);
+ }
+
+ if (_mouseButton == _oldButton || !(_mouseButton & 1))
+ return;
+
+ if (isItWorn(getEitherAd())) {
+ wornError();
+ return;
+ }
+
+ delPointer();
+
+ if (_itemFrame == _openedOb &&
+ _objectType == _openedType) {
+ errorMessage1();
+ return;
+ }
+
+ if (!checkObjectSize())
+ return;
+
+ byte prevType = _objectType;
+ byte prevFrame = _itemFrame;
+ ObjectRef objectId = findOpenPos();
+ _objectType = objectId._type;
+ _itemFrame = objectId._index;
+
+ if (_objectType != kExObjectType) {
+ assert(objectId._type == kFreeObjectType);
+ _itemFrame = transferToEx(objectId._index);
+ _objectType = kExObjectType;
+ }
+
+ DynObject *object = getEitherAd();
+ object->mapad[0] = 20;
+ object->mapad[1] = 255;
+
+ byte prevType2 = _objectType;
+ byte prevFrame2 = _itemFrame;
+ _objectType = prevType;
+ _itemFrame = prevFrame;
+ object = getEitherAd();
+ object->mapad[0] = _openedType;
+ object->mapad[1] = _openedOb;
+ object->mapad[2] = _lastInvPos;
+ object->mapad[3] = _realLocation;
+ _objectType = prevType2;
+ _itemFrame = prevFrame2;
+ fillOpen();
+ fillRyan();
+ underTextLine();
+ readMouse();
+ useOpened();
+ showPointer();
+ workToScreen();
+ delPointer();
+}
+
+ObjectRef DreamWebEngine::findOpenPos() {
+ uint8 pos = (_mouseX - kInventx) / kItempicsize;
+ _lastInvPos = pos;
+
+ return _openInvList[pos];
+}
+
+byte DreamWebEngine::transferToEx(uint8 from) {
+ emergencyPurge();
+
+ byte pos = getExPos();
+ DynObject *exObject = getExAd(pos);
+
+ DynObject *freeObject = getFreeAd(from);
+
+ memcpy(exObject, freeObject, sizeof(DynObject));
+
+ exObject->currentLocation = _realLocation;
+ exObject->initialLocation = _realLocation;
+ exObject->index = from;
+ exObject->mapad[0] = 4;
+ exObject->mapad[1] = 255;
+ exObject->mapad[2] = _lastInvPos;
+
+ transferFrame(from, pos, 0);
+ transferFrame(from, pos, 1);
+ transferText(from, pos);
+
+ freeObject->mapad[0] = 254;
+
+ pickupConts(from, pos);
+
+ return pos;
+}
+
+void DreamWebEngine::fillOpen() {
+ delTextLine();
+ uint8 size = getOpenedSlotCount();
+ if (size > 4)
+ size = 4;
+ findAllOpen();
+ for (uint8 i = 0; i < size; ++i) {
+ uint8 index = _openInvList[i]._index;
+ uint8 type = _openInvList[i]._type;
+ obToInv(index, type, kInventx + i * kItempicsize, kInventy + 96);
+ }
+ underTextLine();
+}
+
+void DreamWebEngine::findAllOpen() {
+ memset(_openInvList, 0xFF, 32);
+
+ for (uint8 i = 0; i < kNumexobjects; ++i) {
+ const DynObject *obj = getExAd(i);
+ if (obj->mapad[1] != _openedOb)
+ continue;
+ if (obj->mapad[0] != _openedType)
+ continue;
+ if (_openedType != kExObjectType && obj->mapad[3] != _realLocation)
+ continue;
+ uint8 slot = obj->mapad[2];
+ assert(slot < 16);
+ _openInvList[slot]._index = i;
+ _openInvList[slot]._type = kExObjectType;
+ }
+
+ for (uint8 i = 0; i < 80; ++i) {
+ const DynObject *obj = getFreeAd(i);
+ if (obj->mapad[1] != _openedOb)
+ continue;
+ if (obj->mapad[0] != _openedType)
+ continue;
+ uint8 slot = obj->mapad[2];
+ _openInvList[slot]._index = i;
+ _openInvList[slot]._type = kFreeObjectType;
+ }
+}
+
+void DreamWebEngine::pickupConts(uint8 from, uint8 containerEx) {
+ const DynObject *obj = getFreeAd(from);
+
+ if (obj->slotCount == 255)
+ return; // not openable
+
+ for (uint8 index = 0; index < 80; ++index) {
+ DynObject *freeObj = getFreeAd(index);
+
+ if (freeObj->mapad[0] != kFreeObjectType)
+ continue;
+ if (freeObj->mapad[1] != from)
+ continue;
+
+ uint8 pos = getExPos();
+ DynObject *exObj = getExAd(pos);
+
+ memcpy(exObj, freeObj, sizeof(DynObject));
+ exObj->currentLocation = _realLocation;
+ exObj->initialLocation = _realLocation;
+ exObj->index = index;
+ exObj->mapad[0] = 4; // kExObjectType?
+ exObj->mapad[1] = containerEx;
+
+ transferFrame(index, pos, 0);
+ transferFrame(index, pos, 1);
+ transferText(index, pos);
+
+ freeObj->mapad[0] = 0xFF;
+ }
+}
+} // End of namespace DreamWeb
diff --git a/engines/dreamweb/pathfind.cpp b/engines/dreamweb/pathfind.cpp
index d367f02d15..c39070532c 100644
--- a/engines/dreamweb/pathfind.cpp
+++ b/engines/dreamweb/pathfind.cpp
@@ -22,121 +22,128 @@
#include "dreamweb/dreamweb.h"
-namespace DreamGen {
+namespace DreamWeb {
-void DreamGenContext::turnpathon() {
- turnpathon(al);
-}
-
-void DreamGenContext::turnpathon(uint8 param) {
- findormake(param, 0xff, data.byte(kRoomnum) + 100);
- PathNode *roomsPaths = getroomspaths()->nodes;
+void DreamWebEngine::turnPathOn(uint8 param) {
+ findOrMake(param, 0xff, _roomNum + 100);
+ PathNode *roomsPaths = getRoomsPaths()->nodes;
if (param == 0xff)
return;
roomsPaths[param].on = 0xff;
}
-void DreamGenContext::turnpathoff() {
- turnpathoff(al);
-}
-
-void DreamGenContext::turnpathoff(uint8 param) {
- findormake(param, 0x00, data.byte(kRoomnum) + 100);
- PathNode *roomsPaths = getroomspaths()->nodes;
+void DreamWebEngine::turnPathOff(uint8 param) {
+ findOrMake(param, 0x00, _roomNum + 100);
+ PathNode *roomsPaths = getRoomsPaths()->nodes;
if (param == 0xff)
return;
roomsPaths[param].on = 0x00;
}
-void DreamGenContext::turnanypathon(uint8 param, uint8 room) {
- findormake(param, 0xff, room + 100);
- PathNode *paths = (PathNode *)segRef(data.word(kReels)).ptr(kPathdata + 144 * room, 0);
- paths[param].on = 0xff;
+void DreamWebEngine::turnAnyPathOn(uint8 param, uint8 room) {
+ findOrMake(param, 0xff, room + 100);
+ _pathData[room].nodes[param].on = 0xff;
}
-
-void DreamGenContext::turnanypathon() {
- turnanypathon(al, ah);
+void DreamWebEngine::turnAnyPathOff(uint8 param, uint8 room) {
+ findOrMake(param, 0x00, room + 100);
+ _pathData[room].nodes[param].on = 0x00;
}
-void DreamGenContext::turnanypathoff(uint8 param, uint8 room) {
- findormake(param, 0x00, room + 100);
- PathNode *paths = (PathNode *)segRef(data.word(kReels)).ptr(kPathdata + 144 * room, 0);
- paths[param].on = 0x00;
+RoomPaths *DreamWebEngine::getRoomsPaths() {
+ return &_pathData[_roomNum];
}
-void DreamGenContext::turnanypathoff() {
- turnanypathoff(al, ah);
+void DreamWebEngine::faceRightWay() {
+ PathNode *paths = getRoomsPaths()->nodes;
+ uint8 dir = paths[_mansPath].dir;
+ _turnToFace = dir;
+ _leaveDirection = dir;
}
-RoomPaths *DreamGenContext::getroomspaths() {
- void *result = segRef(data.word(kReels)).ptr(data.byte(kRoomnum) * 144, 144);
- return (RoomPaths *)result;
+void DreamWebEngine::setWalk() {
+ if (_linePointer != 254) {
+ // Already walking
+ _finalDest = _pointersPath;
+ } else if (_pointersPath == _mansPath) {
+ // Can't walk
+ faceRightWay();
+ } else if (_vars._watchMode == 1) {
+ // Holding reel
+ _vars._destAfterHold = _pointersPath;
+ _vars._watchMode = 2;
+ } else if (_vars._watchMode == 2) {
+ // Can't walk
+ } else {
+ _destination = _pointersPath;
+ _finalDest = _pointersPath;
+ if (_mouseButton != 2 || _commandType == 3) {
+ autoSetWalk();
+ } else {
+ _walkAndExam = 1;
+ _walkExamType = _commandType;
+ _walkExamNum = _command;
+ autoSetWalk();
+ }
+ }
}
-void DreamGenContext::autosetwalk() {
- al = data.byte(kManspath);
- if (data.byte(kFinaldest) == al)
+void DreamWebEngine::autoSetWalk() {
+ if (_finalDest == _mansPath)
return;
- const RoomPaths *roomsPaths = getroomspaths();
- checkdest(roomsPaths);
- data.word(kLinestartx) = roomsPaths->nodes[data.byte(kManspath)].x - 12;
- data.word(kLinestarty) = roomsPaths->nodes[data.byte(kManspath)].y - 12;
- data.word(kLineendx) = roomsPaths->nodes[data.byte(kDestination)].x - 12;
- data.word(kLineendy) = roomsPaths->nodes[data.byte(kDestination)].y - 12;
+ const RoomPaths *roomsPaths = getRoomsPaths();
+ checkDest(roomsPaths);
+ _lineStartX = roomsPaths->nodes[_mansPath].x - 12;
+ _lineStartY = roomsPaths->nodes[_mansPath].y - 12;
+ _lineEndX = roomsPaths->nodes[_destination].x - 12;
+ _lineEndY = roomsPaths->nodes[_destination].y - 12;
bresenhams();
- if (data.byte(kLinedirection) != 0) {
- data.byte(kLinepointer) = data.byte(kLinelength) - 1;
- data.byte(kLinedirection) = 1;
+ if (_lineDirection != 0) {
+ _linePointer = _lineLength - 1;
+ _lineDirection = 1;
return;
}
- data.byte(kLinepointer) = 0;
+ _linePointer = 0;
}
-void DreamGenContext::checkdest(const RoomPaths *roomsPaths) {
+void DreamWebEngine::checkDest(const RoomPaths *roomsPaths) {
const PathSegment *segments = roomsPaths->segments;
- ah = data.byte(kManspath) << 4;
- al = data.byte(kDestination);
- uint8 destination = data.byte(kDestination);
+ const uint8 tmp = _mansPath << 4;
+ uint8 destination = _destination;
for (size_t i = 0; i < 24; ++i) {
- dh = segments[i].b0 & 0xf0;
- dl = segments[i].b0 & 0x0f;
- if (ax == dx) {
- data.byte(kDestination) = segments[i].b1 & 0x0f;
+ if ((segments[i].b0 & 0xf0) == tmp &&
+ (segments[i].b0 & 0x0f) == _destination) {
+ _destination = segments[i].b1 & 0x0f;
return;
}
- dl = (segments[i].b0 & 0xf0) >> 4;
- dh = (segments[i].b0 & 0x0f) << 4;
- if (ax == dx) {
+
+ if (((segments[i].b0 & 0x0f) << 4) == tmp &&
+ ((segments[i].b0 & 0xf0) >> 4) == _destination) {
destination = segments[i].b1 & 0x0f;
}
}
- data.byte(kDestination) = destination;
+ _destination = destination;
}
-void DreamGenContext::findxyfrompath() {
- const PathNode *roomsPaths = getroomspaths()->nodes;
- data.byte(kRyanx) = roomsPaths[data.byte(kManspath)].x - 12;
- data.byte(kRyany) = roomsPaths[data.byte(kManspath)].y - 12;
+void DreamWebEngine::findXYFromPath() {
+ const PathNode *roomsPaths = getRoomsPaths()->nodes;
+ _ryanX = roomsPaths[_mansPath].x - 12;
+ _ryanY = roomsPaths[_mansPath].y - 12;
}
-void DreamGenContext::checkifpathison() {
- flags._z = checkifpathison(al);
-}
-
-bool DreamGenContext::checkifpathison(uint8 index) {
- RoomPaths *roomsPaths = getroomspaths();
+bool DreamWebEngine::checkIfPathIsOn(uint8 index) {
+ RoomPaths *roomsPaths = getRoomsPaths();
uint8 pathOn = roomsPaths->nodes[index].on;
return pathOn == 0xff;
}
-void DreamGenContext::bresenhams() {
- workoutframes();
- int8 *lineData = (int8 *)data.ptr(kLinedata, 0);
- int16 startX = (int16)data.word(kLinestartx);
- int16 startY = (int16)data.word(kLinestarty);
- int16 endX = (int16)data.word(kLineendx);
- int16 endY = (int16)data.word(kLineendy);
+void DreamWebEngine::bresenhams() {
+ workoutFrames();
+ Common::Point *lineData = &_lineData[0];
+ int16 startX = (int16)_lineStartX;
+ int16 startY = (int16)_lineStartY;
+ int16 endX = (int16)_lineEndX;
+ int16 endY = (int16)_lineEndY;
if (endX == startX) {
uint16 deltaY;
@@ -144,22 +151,21 @@ void DreamGenContext::bresenhams() {
if (endY < startY) {
deltaY = startY - endY;
y = (int8)endY;
- data.byte(kLinedirection) = 1;
+ _lineDirection = 1;
} else {
deltaY = endY - startY;
y = (int8)startY;
- data.byte(kLinedirection) = 0;
+ _lineDirection = 0;
}
++deltaY;
int8 x = (int8)startX;
- data.byte(kLinelength) = deltaY;
- do {
- lineData[0] = x;
- lineData[1] = y;
- lineData += 2;
+ _lineLength = deltaY;
+ for (; deltaY; --deltaY) {
+ lineData->x = x;
+ lineData->y = y;
+ ++lineData;
++y;
- --deltaY;
- } while (deltaY);
+ }
return;
}
uint16 deltaX;
@@ -167,14 +173,14 @@ void DreamGenContext::bresenhams() {
deltaX = startX - endX;
SWAP(startX, endX);
SWAP(startY, endY);
- data.word(kLinestartx) = (uint16)startX;
- data.word(kLinestarty) = (uint16)startY;
- data.word(kLineendx) = (uint16)endX;
- data.word(kLineendy) = (uint16)endY;
- data.byte(kLinedirection) = 1;
+ _lineStartX = (uint16)startX;
+ _lineStartY = (uint16)startY;
+ _lineEndX = (uint16)endX;
+ _lineEndY = (uint16)endY;
+ _lineDirection = 1;
} else {
deltaX = endX - startX;
- data.byte(kLinedirection) = 0;
+ _lineDirection = 0;
}
int16 increment;
@@ -182,14 +188,13 @@ void DreamGenContext::bresenhams() {
int8 x = (int8)startX;
int8 y = (int8)startY;
++deltaX;
- data.byte(kLinelength) = deltaX;
- do {
- lineData[0] = x;
- lineData[1] = y;
- lineData += 2;
+ _lineLength = deltaX;
+ for (; deltaX; --deltaX) {
+ lineData->x = x;
+ lineData->y = y;
+ ++lineData;
++x;
- --deltaX;
- } while (deltaX);
+ }
return;
}
uint16 deltaY;
@@ -202,53 +207,144 @@ void DreamGenContext::bresenhams() {
}
uint16 delta1, delta2;
+ byte lineRoutine;
+
if (deltaY > deltaX) {
- data.byte(kLineroutine) = 1;
+ lineRoutine = 1;
delta1 = deltaY;
delta2 = deltaX;
} else {
- data.byte(kLineroutine) = 0;
+ lineRoutine = 0;
delta1 = deltaX;
delta2 = deltaY;
}
- data.word(kIncrement1) = delta2 * 2;
+ uint16 increment1 = delta2 * 2;
+ uint16 increment2 = delta2 * 2 - delta1 * 2;
int16 remainder = delta2 * 2 - delta1;
- data.word(kIncrement2) = delta2 * 2 - delta1 * 2;
++delta1;
int8 x = (int8)startX;
int8 y = (int8)startY;
- data.byte(kLinelength) = delta1;
- if (data.byte(kLineroutine) != 1) {
- do {
- lineData[0] = x;
- lineData[1] = y;
- lineData += 2;
+ _lineLength = delta1;
+ if (lineRoutine != 1) {
+ for (; delta1; --delta1) {
+ lineData->x = x;
+ lineData->y = y;
+ ++lineData;
++x;
if (remainder < 0) {
- remainder += data.word(kIncrement1);
+ remainder += increment1;
} else {
- remainder += data.word(kIncrement2);
+ remainder += increment2;
y += increment;
}
- --delta1;
- } while (delta1);
+ }
} else {
- do {
- lineData[0] = x;
- lineData[1] = y;
- lineData += 2;
+ for (; delta1; --delta1) {
+ lineData->x = x;
+ lineData->y = y;
+ ++lineData;
y += increment;
if (remainder < 0) {
- remainder += data.word(kIncrement1);
+ remainder += increment1;
} else {
- remainder += data.word(kIncrement2);
+ remainder += increment2;
++x;
}
- --delta1;
- } while (delta1);
+ }
}
}
-} /*namespace dreamgen */
+void DreamWebEngine::workoutFrames() {
+ byte tmp;
+ int diffx, diffy;
+
+ // We have to use signed arithmetic here because these values can
+ // be slightly negative when walking off-screen
+ int lineStartX = (int16)_lineStartX;
+ int lineStartY = (int16)_lineStartY;
+ int lineEndX = (int16)_lineEndX;
+ int lineEndY = (int16)_lineEndY;
+
+
+ diffx = ABS(lineStartX - lineEndX);
+ diffy = ABS(lineStartY - lineEndY);
+
+ if (diffx < diffy) {
+ tmp = 2;
+ if (diffx >= (diffy >> 1))
+ tmp = 1;
+ } else {
+ // tendstohoriz
+ tmp = 0;
+ if (diffy >= (diffx >> 1))
+ tmp = 1;
+ }
+
+ if (lineStartX >= lineEndX) {
+ // isinleft
+ if (lineStartY < lineEndY) {
+ if (tmp != 1)
+ tmp ^= 2;
+ tmp += 4;
+ } else {
+ // topleft
+ tmp += 6;
+ }
+ } else {
+ // isinright
+ if (lineStartY < lineEndY) {
+ tmp += 2;
+ } else {
+ // botright
+ if (tmp != 1)
+ tmp ^= 2;
+ }
+ }
+
+ _turnToFace = tmp & 7;
+ _turnDirection = 0;
+}
+
+byte DreamWebEngine::findFirstPath(byte x, byte y) {
+ PathNode *paths = _pathData[_roomNum].nodes;
+
+ for (uint8 index = 0; index < 12; index++) {
+ if (paths[index].x1 == 0xff && paths[index].y1 == 0xff)
+ continue; // "nofirst"
+
+ if (x < paths[index].x1 || y < paths[index].y1)
+ continue; // "nofirst"
+
+ if (x >= paths[index].x2 || y >= paths[index].y2)
+ continue; // "nofirst"
+
+ return paths[index].on; // "gotfirst"
+ }
+
+ return 0;
+}
+
+byte DreamWebEngine::findPathOfPoint(byte x, byte y) {
+ PathNode *paths = _pathData[_roomNum].nodes;
+
+ for (uint8 index = 0; index < 12; index++) {
+ if (paths[index].on != 0xff)
+ continue; // "flunkedit"
+
+ if (paths[index].x1 == 0xff && paths[index].y1 == 0xff)
+ continue; // "flunkedit"
+
+ if (x < paths[index].x1 || y < paths[index].y1)
+ continue; // "flunkedit"
+
+ if (x >= paths[index].x2 || y >= paths[index].y2)
+ continue; // "flunkedit"
+
+ return index; // "gotvalidpath"
+ }
+
+ return 0xff;
+}
+} // End of namespace DreamWeb
diff --git a/engines/dreamweb/people.cpp b/engines/dreamweb/people.cpp
new file mode 100644
index 0000000000..dfb5c62618
--- /dev/null
+++ b/engines/dreamweb/people.cpp
@@ -0,0 +1,1121 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "dreamweb/dreamweb.h"
+
+namespace DreamWeb {
+
+static void (DreamWebEngine::*reelCallbacks[57])(ReelRoutine &) = {
+ &DreamWebEngine::gamer, &DreamWebEngine::sparkyDrip,
+ &DreamWebEngine::eden, &DreamWebEngine::edenInBath,
+ &DreamWebEngine::sparky, &DreamWebEngine::smokeBloke,
+ &DreamWebEngine::manAsleep, &DreamWebEngine::drunk,
+ &DreamWebEngine::receptionist, &DreamWebEngine::genericPerson /*maleFan*/,
+ &DreamWebEngine::genericPerson /*femaleFan*/, &DreamWebEngine::louis,
+ &DreamWebEngine::louisChair, &DreamWebEngine::soldier1,
+ &DreamWebEngine::bossMan, &DreamWebEngine::interviewer,
+ &DreamWebEngine::heavy, &DreamWebEngine::manAsleep /*manAsleep2*/,
+ &DreamWebEngine::genericPerson /*manSatStill*/, &DreamWebEngine::drinker,
+ &DreamWebEngine::bartender, &DreamWebEngine::genericPerson /*otherSmoker*/,
+ &DreamWebEngine::genericPerson /*tattooMan*/, &DreamWebEngine::attendant,
+ &DreamWebEngine::keeper, &DreamWebEngine::candles1,
+ &DreamWebEngine::smallCandle, &DreamWebEngine::security,
+ &DreamWebEngine::copper, &DreamWebEngine::poolGuard,
+ &DreamWebEngine::rockstar, &DreamWebEngine::businessMan,
+ &DreamWebEngine::train, &DreamWebEngine::genericPerson /*aide*/,
+ &DreamWebEngine::mugger, &DreamWebEngine::helicopter,
+ &DreamWebEngine::introMagic1, &DreamWebEngine::introMusic,
+ &DreamWebEngine::introMagic2, &DreamWebEngine::candles2,
+ &DreamWebEngine::gates, &DreamWebEngine::introMagic3,
+ &DreamWebEngine::introMonks1, &DreamWebEngine::candles,
+ &DreamWebEngine::introMonks2, &DreamWebEngine::handClap,
+ &DreamWebEngine::monkAndRyan, &DreamWebEngine::endGameSeq,
+ &DreamWebEngine::priest, &DreamWebEngine::madman,
+ &DreamWebEngine::madmansTelly, &DreamWebEngine::alleyBarkSound,
+ &DreamWebEngine::foghornSound, &DreamWebEngine::carParkDrip,
+ &DreamWebEngine::carParkDrip, &DreamWebEngine::carParkDrip,
+ &DreamWebEngine::carParkDrip
+};
+
+static const ReelRoutine g_initialReelRoutines[] = {
+// Room number and x,y
+// reel pointer
+// speed,speed count,convers. no.
+ { 1,44,0, 20, 2,0,1 },
+ { 1,55,0, 0, 50,20,0 },
+ { 24,22,0, 74, 1,0,0 },
+ { 24,33,10, 75, 1,0,1 },
+ { 1,44,0, 27, 2,0,2 },
+ { 1,44,0, 96, 3,0,4 },
+ { 1,44,0, 118, 2,0,5 },
+ { 1,44,10, 0, 2,0,0 },
+ { 5,22,20, 53, 3,0,0 },
+ { 5,22,20, 40, 1,0,2 },
+ { 5,22,20, 50, 1,0,3 },
+ { 2,11,10, 192, 1,0,0 },
+ { 2,11,10, 182, 2,0,1 },
+ { 8,11,10, 0, 2,0,1 },
+ { 23,0,50, 0, 3,0,0 },
+ { 28,11,20, 250, 4,0,0 },
+ { 23,0,50, 43, 2,0,8 },
+ { 23,11,40, 130, 2,0,1 },
+ { 23,22,40, 122, 2,0,2 },
+ { 23,22,40, 105, 2,0,3 },
+ { 23,22,40, 81, 2,0,4 },
+ { 23,11,40, 135, 2,0,5 },
+ { 23,22,40, 145, 2,0,6 },
+ { 4,22,30, 0, 2,0,0 },
+ { 45,22,30, 200, 0,0,20 },
+ { 45,22,30, 39, 2,0,0 },
+ { 45,22,30, 25, 2,0,0 },
+ { 8,22,40, 32, 2,0,0 },
+ { 7,11,20, 64, 2,0,0 },
+ { 22,22,20, 82, 2,0,0 },
+ { 27,11,30, 0, 2,0,0 },
+ { 20,0,30, 0, 2,0,0 },
+ { 14,33,40, 21, 1,0,0 },
+ { 29,11,10, 0, 1,0,0 },
+ { 2,22,0, 2, 2,0,0 },
+ { 25,0,50, 4, 2,0,0 },
+ { 50,22,30, 121, 2,0,0 },
+ { 50,22,30, 0, 20,0,0 },
+ { 52,22,30, 192, 2,0,0 },
+ { 52,22,30, 233, 2,0,0 },
+ { 50,22,40, 104, 55,0,0 }, // ...., 65,0,0 for German CD
+ { 53,33,0, 99, 2,0,0 },
+ { 50,22,40, 0, 3,0,0 },
+ { 50,22,30, 162, 2,0,0 },
+ { 52,22,30, 57, 2,0,0 },
+ { 52,22,30, 0, 2,0,0 },
+ { 54,0,0, 72, 3,0,0 },
+ { 55,44,0, 0, 2,0,0 },
+ { 19,0,0, 0, 28,0,0 },
+ { 14,22,0, 2, 2,0,0 },
+ { 14,22,0, 300, 1,0,0 },
+ { 10,22,30, 174, 0,0,0 },
+ { 12,22,20, 0, 1,0,0 },
+ { 11,11,20, 0, 50,20,0 },
+ { 11,11,30, 0, 50,20,0 },
+ { 11,22,20, 0, 50,20,0 },
+ { 14,33,40, 0, 50,20,0 },
+ { 255,0,0, 0, 0,0,0 }
+};
+
+void DreamWebEngine::setupInitialReelRoutines() {
+ for (unsigned int i = 0; i < kNumReelRoutines + 1; ++i) {
+ _reelRoutines[i] = g_initialReelRoutines[i];
+ if (_reelRoutines[i].period == 55 && hasSpeech() && getLanguage() == Common::DE_DEU)
+ _reelRoutines[i].period = 65;
+ }
+}
+
+void DreamWebEngine::updatePeople() {
+ _peopleList.clear();
+ ++_mainTimer;
+
+ for (int i = 0; _reelRoutines[i].reallocation != 255; ++i) {
+ if (_reelRoutines[i].reallocation == _realLocation &&
+ _reelRoutines[i].mapX == _mapX &&
+ _reelRoutines[i].mapY == _mapY) {
+ assert(reelCallbacks[i]);
+ (this->*(reelCallbacks[i]))(_reelRoutines[i]);
+ }
+ }
+}
+
+void DreamWebEngine::madmanText() {
+ byte origCount;
+
+ uint16 length = 90;
+ if (hasSpeech()) {
+ if (_speechCount > 15)
+ return;
+ if (_channel1Playing != 255)
+ return;
+ origCount = _speechCount;
+ ++_speechCount;
+
+ if (origCount != 15)
+ length = 32000; // Set subtitle time very high to make it
+ // always wait for the next line, except for the
+ // last one, when there is no next line.
+ } else {
+ if (_vars._combatCount >= 61)
+ return;
+ if (_vars._combatCount & 3)
+ return;
+ origCount = _vars._combatCount / 4;
+ }
+ setupTimedTemp(47 + origCount, 82, 72, 80, length, 1);
+}
+
+void DreamWebEngine::madman(ReelRoutine &routine) {
+ _vars._watchingTime = 2;
+ if (checkSpeed(routine)) {
+ uint16 newReelPointer = routine.reelPointer();
+ if (newReelPointer >= 364) {
+ _vars._manDead = 2;
+ showGameReel(&routine);
+ return;
+ }
+ if (newReelPointer == 10) {
+ loadTempText("T82");
+ _vars._combatCount = (uint8)-1;
+ _speechCount = 0;
+ }
+ ++newReelPointer;
+ if (newReelPointer == 294) {
+ if (!_wonGame) {
+ _wonGame = true;
+ getRidOfTempText();
+ }
+ return;
+ }
+ if (newReelPointer == 66) {
+ ++_vars._combatCount;
+
+ if (_lastHardKey == 1) // ESC pressed, skip the mad man's speech
+ _vars._combatCount = _speechCount = (hasSpeech() ? 65 : 63);
+
+ madmanText();
+ newReelPointer = 53;
+
+ if (_vars._combatCount >= (hasSpeech() ? 64 : 62)) {
+ if (_vars._combatCount == (hasSpeech() ? 70 : 68))
+ newReelPointer = 310;
+ else {
+ if (_vars._lastWeapon == 8) {
+ _vars._combatCount = hasSpeech() ? 72 : 70;
+ _vars._lastWeapon = (uint8)-1;
+ _vars._madmanFlag = 1;
+ newReelPointer = 67;
+ }
+ }
+ }
+ }
+ routine.setReelPointer(newReelPointer);
+ }
+ showGameReel(&routine);
+ routine.mapX = _mapX;
+ madMode();
+}
+
+void DreamWebEngine::madMode() {
+ _vars._watchingTime = 2;
+ _pointerMode = 0;
+ if (_vars._combatCount < (hasSpeech() ? 65 : 63))
+ return;
+ if (_vars._combatCount >= (hasSpeech() ? 70 : 68))
+ return;
+ _pointerMode = 2;
+}
+
+void DreamWebEngine::addToPeopleList(ReelRoutine *routine) {
+ People people;
+ people._reelPointer = routine->reelPointer();
+ people._routinePointer = routine;
+ people.b4 = routine->b7;
+
+ _peopleList.push_back(people);
+}
+
+bool DreamWebEngine::checkSpeed(ReelRoutine &routine) {
+ if (_vars._lastWeapon != (uint8)-1)
+ return true;
+ ++routine.counter;
+ if (routine.counter != routine.period)
+ return false;
+ routine.counter = 0;
+ return true;
+}
+
+void DreamWebEngine::sparkyDrip(ReelRoutine &routine) {
+ if (checkSpeed(routine))
+ playChannel0(14, 0);
+}
+
+void DreamWebEngine::genericPerson(ReelRoutine &routine) {
+ showGameReel(&routine);
+ addToPeopleList(&routine);
+}
+
+void DreamWebEngine::gamer(ReelRoutine &routine) {
+ if (checkSpeed(routine)) {
+ uint8 v;
+ do {
+ v = _rnd.getRandomNumberRng(20, 24);
+ } while (v == routine.reelPointer());
+ routine.setReelPointer(v);
+ }
+
+ showGameReel(&routine);
+ addToPeopleList(&routine);
+}
+
+void DreamWebEngine::eden(ReelRoutine &routine) {
+ if (_vars._generalDead)
+ return;
+ showGameReel(&routine);
+ addToPeopleList(&routine);
+}
+
+void DreamWebEngine::sparky(ReelRoutine &routine) {
+ if (_vars._card1Money)
+ routine.b7 = 3;
+ if (checkSpeed(routine)) {
+ if (routine.reelPointer() == 34) {
+ if (randomNumber() < 30)
+ routine.incReelPointer();
+ else
+ routine.setReelPointer(27);
+ } else {
+ if (routine.reelPointer() != 48)
+ routine.incReelPointer();
+ else
+ routine.setReelPointer(27);
+ }
+ }
+ showGameReel(&routine);
+ addToPeopleList(&routine);
+ if (routine.b7 & 128)
+ _vars._talkedToSparky = 1;
+}
+
+void DreamWebEngine::rockstar(ReelRoutine &routine) {
+ if ((routine.reelPointer() == 303) || (routine.reelPointer() == 118)) {
+ _newLocation = 45;
+ showGameReel(&routine);
+ return;
+ }
+ if (checkSpeed(routine)) {
+ uint16 nextReelPointer = routine.reelPointer() + 1;
+ if (nextReelPointer == 118) {
+ _vars._manDead = 2;
+ } else if (nextReelPointer == 79) {
+ --nextReelPointer;
+ if (_vars._lastWeapon != 1) {
+ ++_vars._combatCount;
+ if (_vars._combatCount == 40) {
+ _vars._combatCount = 0;
+ nextReelPointer = 79;
+ }
+ } else {
+ _vars._lastWeapon = (uint8)-1;
+ nextReelPointer = 123;
+ }
+ }
+ routine.setReelPointer(nextReelPointer);
+ }
+ showGameReel(&routine);
+ if (routine.reelPointer() == 78) {
+ addToPeopleList(&routine);
+ _pointerMode = 2;
+ _vars._watchingTime = 0;
+ } else {
+ _vars._watchingTime = 2;
+ _pointerMode = 0;
+ routine.mapY = _mapY;
+ }
+}
+
+void DreamWebEngine::madmansTelly(ReelRoutine &routine) {
+ uint16 nextReelPointer = routine.reelPointer() + 1;
+ if (nextReelPointer == 307)
+ nextReelPointer = 300;
+ routine.setReelPointer(nextReelPointer);
+ showGameReel(&routine);
+}
+
+
+void DreamWebEngine::smokeBloke(ReelRoutine &routine) {
+ if (_vars._rockstarDead == 0) {
+ if (routine.b7 & 128)
+ setLocation(5);
+ }
+ if (checkSpeed(routine)) {
+ if (routine.reelPointer() == 100) {
+ if (randomNumber() < 30)
+ routine.incReelPointer();
+ else
+ routine.setReelPointer(96);
+ } else if (routine.reelPointer() == 117)
+ routine.setReelPointer(96);
+ else
+ routine.incReelPointer();
+ }
+ showGameReel(&routine);
+ addToPeopleList(&routine);
+}
+
+void DreamWebEngine::manAsleep(ReelRoutine &routine) {
+ routine.b7 &= 127;
+ showGameReel(&routine);
+ addToPeopleList(&routine);
+}
+
+void DreamWebEngine::attendant(ReelRoutine &routine) {
+ showGameReel(&routine);
+ addToPeopleList(&routine);
+ if (routine.b7 & 128)
+ _vars._talkedToAttendant = 1;
+}
+
+void DreamWebEngine::keeper(ReelRoutine &routine) {
+ if (_vars._keeperFlag != 0) {
+ // Not waiting
+ addToPeopleList(&routine);
+ showGameReel(&routine);
+ return;
+ }
+
+ if (_vars._reelToWatch < 190)
+ return; // waiting
+
+ _vars._keeperFlag++;
+
+ if ((routine.b7 & 127) != _vars._dreamNumber)
+ routine.b7 = _vars._dreamNumber;
+}
+
+void DreamWebEngine::drunk(ReelRoutine &routine) {
+ if (_vars._generalDead)
+ return;
+ routine.b7 &= 127;
+ showGameReel(&routine);
+ addToPeopleList(&routine);
+}
+
+void DreamWebEngine::interviewer(ReelRoutine &routine) {
+ if (_vars._reelToWatch == 68)
+ routine.incReelPointer();
+
+ if (routine.reelPointer() != 250 && routine.reelPointer() != 259 && checkSpeed(routine))
+ routine.incReelPointer();
+
+ showGameReel(&routine);
+}
+
+void DreamWebEngine::drinker(ReelRoutine &routine) {
+ if (checkSpeed(routine)) {
+ routine.incReelPointer();
+
+ if ( routine.reelPointer() == 115 ||
+ (routine.reelPointer() == 106 && randomNumber() >= 3))
+ routine.setReelPointer(105);
+ }
+
+ showGameReel(&routine);
+ addToPeopleList(&routine);
+}
+
+void DreamWebEngine::alleyBarkSound(ReelRoutine &routine) {
+ uint16 prevReelPointer = routine.reelPointer() - 1;
+ if (prevReelPointer == 0) {
+ playChannel1(14);
+ routine.setReelPointer(1000);
+ } else {
+ routine.setReelPointer(prevReelPointer);
+ }
+}
+
+void DreamWebEngine::introMagic1(ReelRoutine &routine) {
+ if (checkSpeed(routine)) {
+ uint16 nextReelPointer = routine.reelPointer() + 1;
+ if (nextReelPointer == 145)
+ nextReelPointer = 121;
+ routine.setReelPointer(nextReelPointer);
+ if (nextReelPointer == 121) {
+ ++_introCount;
+ intro1Text();
+ if (_introCount == 8) {
+ _mapY += 10;
+ _nowInNewRoom = 1;
+ }
+ }
+ }
+ showGameReel(&routine);
+}
+
+void DreamWebEngine::introMagic2(ReelRoutine &routine) {
+ if (checkSpeed(routine)) {
+ uint16 nextReelPointer = routine.reelPointer() + 1;
+ if (nextReelPointer == 216)
+ nextReelPointer = 192;
+ routine.setReelPointer(nextReelPointer);
+ }
+ showGameReel(&routine);
+}
+
+void DreamWebEngine::introMagic3(ReelRoutine &routine) {
+ if (checkSpeed(routine)) {
+ uint16 nextReelPointer = routine.reelPointer() + 1;
+ if (nextReelPointer == 218)
+ _getBack = 1;
+ routine.setReelPointer(nextReelPointer);
+ }
+ showGameReel(&routine);
+ routine.mapX = _mapX;
+}
+
+void DreamWebEngine::candles1(ReelRoutine &routine) {
+ if (checkSpeed(routine)) {
+ uint16 nextReelPointer = routine.reelPointer() + 1;
+ if (nextReelPointer == 44)
+ nextReelPointer = 39;
+ routine.setReelPointer(nextReelPointer);
+ }
+ showGameReel(&routine);
+}
+
+void DreamWebEngine::candles2(ReelRoutine &routine) {
+ if (checkSpeed(routine)) {
+ uint16 nextReelPointer = routine.reelPointer() + 1;
+ if (nextReelPointer == 238)
+ nextReelPointer = 233;
+ routine.setReelPointer(nextReelPointer);
+ }
+ showGameReel(&routine);
+}
+
+void DreamWebEngine::smallCandle(ReelRoutine &routine) {
+ if (checkSpeed(routine)) {
+ uint16 nextReelPointer = routine.reelPointer() + 1;
+ if (nextReelPointer == 37)
+ nextReelPointer = 25;
+ routine.setReelPointer(nextReelPointer);
+ }
+ showGameReel(&routine);
+}
+
+void DreamWebEngine::introMusic(ReelRoutine &routine) {
+}
+
+void DreamWebEngine::candles(ReelRoutine &routine) {
+ if (checkSpeed(routine)) {
+ uint16 nextReelPointer = routine.reelPointer() + 1;
+ if (nextReelPointer == 167)
+ nextReelPointer = 162;
+ routine.setReelPointer(nextReelPointer);
+ }
+ showGameReel(&routine);
+}
+
+void DreamWebEngine::gates(ReelRoutine &routine) {
+ if (checkSpeed(routine)) {
+ uint16 nextReelPointer = routine.reelPointer() + 1;
+ if (nextReelPointer == 116)
+ playChannel1(17);
+ if (nextReelPointer >= 110)
+ routine.period = 2;
+ if (nextReelPointer == 120) {
+ _getBack = 1;
+ nextReelPointer = 119;
+ }
+ routine.setReelPointer(nextReelPointer);
+ intro3Text(nextReelPointer);
+ }
+ showGameReel(&routine);
+}
+
+void DreamWebEngine::security(ReelRoutine &routine) {
+ if (routine.reelPointer() == 32) {
+ if (_vars._lastWeapon == 1) {
+ _vars._watchingTime = 10;
+ if ((_mansPath == 9) && (_facing == 0)) {
+ _vars._lastWeapon = (uint8)-1;
+ routine.incReelPointer();
+ }
+ }
+ } else if (routine.reelPointer() == 69)
+ return;
+ else {
+ _vars._watchingTime = 10;
+ if (checkSpeed(routine))
+ routine.incReelPointer();
+ }
+ showGameReel(&routine);
+ addToPeopleList(&routine);
+}
+
+void DreamWebEngine::edenInBath(ReelRoutine &routine) {
+ if (_vars._generalDead == 0 || _vars._sartainDead != 0)
+ return;
+
+ showGameReel(&routine);
+ addToPeopleList(&routine);
+}
+
+void DreamWebEngine::louis(ReelRoutine &routine) {
+ if (_vars._rockstarDead != 0)
+ return;
+
+ showGameReel(&routine);
+ addToPeopleList(&routine);
+}
+
+void DreamWebEngine::handClap(ReelRoutine &routine) {
+}
+
+void DreamWebEngine::carParkDrip(ReelRoutine &routine) {
+ if (!checkSpeed(routine))
+ return; // cantdrip2
+
+ playChannel1(14);
+}
+
+void DreamWebEngine::foghornSound(ReelRoutine &routine) {
+ if (randomNumber() == 198)
+ playChannel1(13);
+}
+
+void DreamWebEngine::train(ReelRoutine &routine) {
+ // The original code has logic for this, but it is disabled
+}
+
+void DreamWebEngine::louisChair(ReelRoutine &routine) {
+ if (_vars._rockstarDead == 0)
+ return; // notlouis2
+
+ if (checkSpeed(routine)) {
+ uint16 nextReelPointer = routine.reelPointer() + 1;
+ if (nextReelPointer == 191) {
+ routine.setReelPointer(182); // Restart Louis
+ } else if (nextReelPointer != 185) {
+ routine.setReelPointer(nextReelPointer);
+ } else {
+ if (randomNumber() < 245)
+ routine.setReelPointer(182); // Restart Louis
+ else
+ routine.setReelPointer(nextReelPointer);
+ }
+ }
+
+ showGameReel(&routine);
+ addToPeopleList(&routine);
+}
+
+void DreamWebEngine::bossMan(ReelRoutine &routine) {
+ if (checkSpeed(routine)) {
+ uint16 nextReelPointer = routine.reelPointer() + 1;
+
+ if (nextReelPointer == 4) {
+ if (_vars._gunPassFlag != 1 && randomNumber() >= 10)
+ nextReelPointer = 0;
+ } else if (nextReelPointer == 20) {
+ if (_vars._gunPassFlag != 1)
+ nextReelPointer = 0;
+ } else if (nextReelPointer == 41) {
+ nextReelPointer = 0;
+ _vars._gunPassFlag++;
+ routine.b7 = 10;
+ }
+
+ routine.setReelPointer(nextReelPointer);
+ }
+
+ showGameReel(&routine);
+ addToPeopleList(&routine);
+
+ if (routine.b7 & 128)
+ _vars._talkedToBoss = 1;
+}
+
+void DreamWebEngine::priest(ReelRoutine &routine) {
+ if (routine.reelPointer() == 8)
+ return; // priestspoken
+
+ _pointerMode = 0;
+ _vars._watchingTime = 2;
+
+ if (checkSpeed(routine)) {
+ routine.incReelPointer();
+ priestText(routine);
+ }
+}
+
+void DreamWebEngine::priestText(ReelRoutine &routine) {
+ uint16 reel = routine.reelPointer();
+ if (reel < 2 || reel >= 7 || (reel & 1))
+ return; // nopriesttext
+
+ setupTimedUse((reel >> 1) + 50, 54, 1, 72, 80);
+}
+
+void DreamWebEngine::monkAndRyan(ReelRoutine &routine) {
+ if (checkSpeed(routine)) {
+ uint16 nextReelPointer = routine.reelPointer() + 1;
+ if (nextReelPointer == 83) {
+ _introCount++;
+ textForMonk();
+ nextReelPointer = 77;
+
+ if (_introCount == 57) {
+ _getBack = 1;
+ return;
+ }
+ }
+
+ routine.setReelPointer(nextReelPointer);
+ }
+
+ showGameReel(&routine);
+}
+
+void DreamWebEngine::copper(ReelRoutine &routine) {
+ if (checkSpeed(routine)) {
+ uint16 nextReelPointer = routine.reelPointer() + 1;
+ if (nextReelPointer == 94) {
+ nextReelPointer = 64;
+ } else if (nextReelPointer == 81 || nextReelPointer == 66) {
+ // Might wait
+ if (randomNumber() >= 7)
+ nextReelPointer--;
+ }
+
+ routine.setReelPointer(nextReelPointer);
+ }
+
+ showGameReel(&routine);
+ addToPeopleList(&routine);
+}
+
+void DreamWebEngine::introMonks1(ReelRoutine &routine) {
+ if (checkSpeed(routine)) {
+ uint16 nextReelPointer = routine.reelPointer() + 1;
+
+ if (nextReelPointer == 80) {
+ _mapY += 10;
+ _nowInNewRoom = 1;
+ showGameReel(&routine);
+ return;
+ } else if (nextReelPointer == 30) {
+ _mapY -= 10;
+ _nowInNewRoom = 1;
+ nextReelPointer = 51;
+ }
+
+ routine.setReelPointer(nextReelPointer);
+
+ if (nextReelPointer == 5 || nextReelPointer == 15 ||
+ nextReelPointer == 25 || nextReelPointer == 61 ||
+ nextReelPointer == 71) {
+ // Wait step
+ intro2Text(nextReelPointer);
+ routine.counter = (uint8)-20;
+ }
+ }
+
+ showGameReel(&routine);
+ routine.mapY = _mapY;
+}
+
+void DreamWebEngine::introMonks2(ReelRoutine &routine) {
+ if (checkSpeed(routine)) {
+ uint16 nextReelPointer = routine.reelPointer() + 1;
+ if (nextReelPointer == 87) {
+ _introCount++;
+ monks2text();
+
+ if (_introCount == 19)
+ nextReelPointer = 87;
+ else
+ nextReelPointer = 74;
+ }
+
+ if (nextReelPointer == 110) {
+ _introCount++;
+ monks2text();
+
+ if (_introCount == 35)
+ nextReelPointer = 111;
+ else
+ nextReelPointer = 98;
+ } else if (nextReelPointer == 176) {
+ _getBack = 1;
+ } else if (nextReelPointer == 125) {
+ nextReelPointer = 140;
+ }
+
+ routine.setReelPointer(nextReelPointer);
+ }
+
+ showGameReel(&routine);
+}
+
+void DreamWebEngine::soldier1(ReelRoutine &routine) {
+ if (routine.reelPointer() != 0) {
+ _vars._watchingTime = 10;
+ if (routine.reelPointer() == 30) {
+ _vars._combatCount++;
+ if (_vars._combatCount == 40)
+ _vars._manDead = 2;
+ } else if (checkSpeed(routine)) {
+ // Not after shot
+ routine.incReelPointer();
+ }
+ } else if (_vars._lastWeapon == 1) {
+ _vars._watchingTime = 10;
+ if (_mansPath == 2 && _facing == 4)
+ routine.incReelPointer();
+ _vars._lastWeapon = 0xFF;
+ _vars._combatCount = 0;
+ }
+
+ showGameReel(&routine);
+ addToPeopleList(&routine);
+}
+
+void DreamWebEngine::receptionist(ReelRoutine &routine) {
+ if (checkSpeed(routine)) {
+ if (_vars._cardPassFlag == 1) {
+ // Set card
+ _vars._cardPassFlag++;
+ routine.b7 = 1;
+ routine.setReelPointer(64);
+ }
+
+ if (routine.reelPointer() != 58) {
+ // notdes1
+ if (routine.reelPointer() != 60) {
+ // notdes2
+ if (routine.reelPointer() != 88)
+ routine.incReelPointer(); // not end card
+ else
+ routine.setReelPointer(53);
+ } else if (randomNumber() >= 240) {
+ routine.setReelPointer(53);
+ }
+ } else if (randomNumber() >= 30) {
+ routine.setReelPointer(55);
+ } else {
+ // notdes2
+ if (routine.reelPointer() != 88)
+ routine.incReelPointer(); // not end card
+ else
+ routine.setReelPointer(53);
+ }
+ }
+
+ showGameReel(&routine);
+ addToPeopleList(&routine);
+ if (routine.b7 & 128)
+ _vars._talkedToRecep = 1;
+}
+
+void DreamWebEngine::bartender(ReelRoutine &routine) {
+ if (checkSpeed(routine)) {
+ if (routine.reelPointer() == 86) {
+ if (randomNumber() >= 18)
+ routine.setReelPointer(81);
+ else
+ routine.incReelPointer(); // notsmoket2
+ } else if (routine.reelPointer() == 103) {
+ routine.setReelPointer(81); // notsmoket1
+ } else {
+ routine.incReelPointer(); // notsmoket2
+ }
+ }
+
+ showGameReel(&routine);
+ if (_vars._gunPassFlag == 1)
+ routine.b7 = 9; // got gun
+
+ addToPeopleList(&routine);
+}
+
+void DreamWebEngine::heavy(ReelRoutine &routine) {
+ routine.b7 &= 127;
+ if (routine.reelPointer() != 43) {
+ _vars._watchingTime = 10;
+ if (routine.reelPointer() == 70) {
+ // After shot
+ _vars._combatCount++;
+ if (_vars._combatCount == 80)
+ _vars._manDead = 2;
+ } else {
+ if (checkSpeed(routine))
+ routine.incReelPointer();
+ }
+ } else if (_vars._lastWeapon == 1 && _mansPath == 5 && _facing == 4) {
+ // Heavy wait
+ _vars._lastWeapon = (byte)-1;
+ routine.incReelPointer();
+ _vars._combatCount = 0;
+ }
+
+ showGameReel(&routine);
+ addToPeopleList(&routine);
+}
+
+void DreamWebEngine::helicopter(ReelRoutine &routine) {
+ if (routine.reelPointer() == 203) {
+ // Won helicopter
+ _pointerMode = 0;
+ return;
+ }
+
+ if (checkSpeed(routine)) {
+ uint16 nextReelPointer = routine.reelPointer() + 1;
+ if (nextReelPointer == 53) {
+ // Before killing helicopter
+ _vars._combatCount++;
+ if (_vars._combatCount >= 8)
+ _vars._manDead = 2;
+ nextReelPointer = 49;
+ } else if (nextReelPointer == 9) {
+ nextReelPointer--;
+ if (_vars._lastWeapon == 1) {
+ _vars._lastWeapon = (byte)-1;
+ nextReelPointer = 55;
+ } else {
+ nextReelPointer = 5;
+ _vars._combatCount++;
+ if (_vars._combatCount == 20) {
+ _vars._combatCount = 0;
+ nextReelPointer = 9;
+ }
+ }
+ }
+
+ routine.setReelPointer(nextReelPointer);
+ }
+
+ showGameReel(&routine);
+ routine.mapX = _mapX;
+ if (routine.reelPointer() < 9 && _vars._combatCount >= 7) {
+ _pointerMode = 2;
+ _vars._watchingTime = 0;
+ } else {
+ // Not waiting helicopter
+ _pointerMode = 0;
+ _vars._watchingTime = 2;
+ }
+}
+
+void DreamWebEngine::mugger(ReelRoutine &routine) {
+ if (routine.reelPointer() != 138) {
+ if (routine.reelPointer() == 176)
+ return; // endmugger2
+
+ if (routine.reelPointer() == 2)
+ _vars._watchingTime = 175 * 2; // set watch
+
+ if (checkSpeed(routine))
+ routine.incReelPointer();
+
+ showGameReel(&routine);
+ routine.mapX = _mapX;
+ } else {
+ createPanel2();
+ showIcon();
+
+ const uint8 *string = (const uint8 *)_puzzleText.getString(41);
+ uint16 y = 104;
+ printDirect(&string, 33 + 20, &y, 241, 241 & 1);
+ workToScreen();
+ hangOn(300);
+ routine.setReelPointer(140);
+ _mansPath = 2;
+ _finalDest = 2;
+ findXYFromPath();
+ _resetManXY = 1;
+ _command = findExObject("WETA");
+ _objectType = kExObjectType;
+ removeObFromInv();
+ _command = findExObject("WETB");
+ _objectType = kExObjectType;
+ removeObFromInv();
+ makeMainScreen();
+ setupTimedUse(48, 70, 10, 68 - 32, 54 + 64);
+ _vars._beenMugged = 1;
+ }
+}
+
+// Exiting the elevator of Sartain's industries, Sartain (the businessman) and
+// two bodyguards are expecting Ryan.
+void DreamWebEngine::businessMan(ReelRoutine &routine) {
+ _pointerMode = 0;
+ _vars._watchingTime = 2;
+ if (routine.reelPointer() == 2)
+ setupTimedUse(49, 30, 1, 68, 174); // First
+
+ if (routine.reelPointer() == 95) {
+ // Businessman combat won - end
+ _pointerMode = 0;
+ _vars._watchingTime = 0;
+ return;
+ }
+
+ if (routine.reelPointer() == 49)
+ return; // Businessman combat end
+
+ if (checkSpeed(routine)) {
+ uint16 nextReelPointer = routine.reelPointer() + 1;
+ if (nextReelPointer == 48) {
+ _vars._manDead = 2; // before dead body
+ } else if (nextReelPointer == 15) {
+ nextReelPointer--;
+ if (_vars._lastWeapon == 3) {
+ // Shield on bus
+ _vars._lastWeapon = (byte)-1;
+ _vars._combatCount = 0;
+ nextReelPointer = 51;
+ } else {
+ // No shield on businessman
+ _vars._combatCount++;
+ if (_vars._combatCount == 20) {
+ _vars._combatCount = 0;
+ nextReelPointer = 15;
+ }
+ }
+ } else {
+ // Businessman combat won
+ if (nextReelPointer == 91) {
+ turnPathOn(0);
+ turnPathOn(1);
+ turnPathOn(2);
+ turnPathOff(3);
+ _mansPath = 5;
+ _finalDest = 5;
+ findXYFromPath();
+ _resetManXY = 1;
+ nextReelPointer = 92;
+ }
+ }
+
+ routine.setReelPointer(nextReelPointer);
+ }
+
+ showGameReel(&routine);
+ routine.mapY = _mapY;
+ if (routine.reelPointer() == 14) {
+ _vars._watchingTime = 0;
+ _pointerMode = 2;
+ }
+}
+
+void DreamWebEngine::endGameSeq(ReelRoutine &routine) {
+ if (checkSpeed(routine)) {
+ uint16 nextReelPointer = routine.reelPointer() + 1;
+ if (nextReelPointer == 51 && _introCount != 140) {
+ _introCount++;
+ textForEnd();
+ nextReelPointer = 50;
+ }
+
+ routine.setReelPointer(nextReelPointer);
+ if (nextReelPointer == 134) {
+ fadeScreenDownHalf();
+ } else if (nextReelPointer == 324) {
+ fadeScreenDowns();
+ _volumeTo = 7;
+ _volumeDirection = 1;
+ }
+
+ if (nextReelPointer == 340)
+ _getBack = 1;
+ }
+
+ showGameReel(&routine);
+ routine.mapY = _mapY;
+
+ if (routine.reelPointer() == 145) {
+ routine.setReelPointer(146);
+ rollEndCreditsGameWon();
+ }
+}
+
+void DreamWebEngine::poolGuard(ReelRoutine &routine) {
+ if (routine.reelPointer() == 214 || routine.reelPointer() == 258) {
+ // Combat over 2
+ showGameReel(&routine);
+ _vars._watchingTime = 2;
+ _pointerMode = 0;
+ _vars._combatCount++;
+ if (_vars._combatCount < 100)
+ return; // doneover2
+ _vars._watchingTime = 0;
+ _vars._manDead = 2;
+ return;
+ } else if (routine.reelPointer() == 185) {
+ // Combat over 1
+ _vars._watchingTime = 0;
+ _pointerMode = 0;
+ turnPathOn(0);
+ turnPathOff(1);
+ return;
+ }
+
+ if (routine.reelPointer() == 0)
+ turnPathOn(0); // first pool
+
+ if (checkSpeed(routine)) {
+ uint16 nextReelPointer = routine.reelPointer() + 1;
+
+ if (nextReelPointer != 122) {
+ // Not end guard 1
+ if (nextReelPointer == 147) {
+ nextReelPointer--;
+ if (_vars._lastWeapon == 1) {
+ // Gun on pool
+ _vars._lastWeapon = (byte)-1;
+ nextReelPointer = 147;
+ } else {
+ // Gun not on pool
+ _vars._combatCount++;
+ if (_vars._combatCount == 40) {
+ _vars._combatCount = 0;
+ nextReelPointer = 220;
+ }
+ }
+ }
+ } else {
+ nextReelPointer--;
+
+ if (_vars._lastWeapon == 2) {
+ // Axe on pool
+ _vars._lastWeapon = (byte)-1;
+ nextReelPointer = 122;
+ } else {
+ _vars._combatCount++;
+ if (_vars._combatCount == 40) {
+ _vars._combatCount = 0;
+ nextReelPointer = 195;
+ }
+ }
+ }
+
+ routine.setReelPointer(nextReelPointer);
+ }
+
+ showGameReel(&routine);
+
+ if (routine.reelPointer() != 121 && routine.reelPointer() != 146) {
+ _pointerMode = 0;
+ _vars._watchingTime = 2;
+ } else {
+ _pointerMode = 2;
+ _vars._watchingTime = 0;
+ }
+}
+
+} // End of namespace DreamWeb
diff --git a/engines/dreamweb/print.cpp b/engines/dreamweb/print.cpp
index edaf8ee1eb..a6b93a5590 100644
--- a/engines/dreamweb/print.cpp
+++ b/engines/dreamweb/print.cpp
@@ -22,20 +22,20 @@
#include "dreamweb/dreamweb.h"
-namespace DreamGen {
+namespace DreamWeb {
-void DreamGenContext::printboth(const Frame *charSet, uint16 *x, uint16 y, uint8 c, uint8 nextChar) {
+void DreamWebEngine::printBoth(const GraphicsFile &charSet, uint16 *x, uint16 y, uint8 c, uint8 nextChar) {
uint16 newX = *x;
uint8 width, height;
- printchar(charSet, &newX, y, c, nextChar, &width, &height);
- multidump(*x, y, width, height);
+ printChar(charSet, &newX, y, c, nextChar, &width, &height);
+ multiDump(*x, y, width, height);
*x = newX;
}
-uint8 DreamGenContext::getnextword(const Frame *charSet, const uint8 *string, uint8 *totalWidth, uint8 *charCount) {
+uint8 DreamWebEngine::getNextWord(const GraphicsFile &charSet, const uint8 *string, uint8 *totalWidth, uint8 *charCount) {
*totalWidth = 0;
*charCount = 0;
- while(true) {
+ while (true) {
uint8 firstChar = *string;
++string;
++*charCount;
@@ -47,75 +47,66 @@ uint8 DreamGenContext::getnextword(const Frame *charSet, const uint8 *string, ui
*totalWidth += 6;
return 0;
}
- firstChar = engine->modifyChar(firstChar);
+ firstChar = modifyChar(firstChar);
if (firstChar != 255) {
uint8 secondChar = *string;
- uint8 width = charSet[firstChar - 32 + data.word(kCharshift)].width;
- width = kernchars(firstChar, secondChar, width);
+ uint8 width = charSet._frames[firstChar - 32 + _charShift].width;
+ width = kernChars(firstChar, secondChar, width);
*totalWidth += width;
}
}
}
-void DreamGenContext::printchar() {
- uint16 x = di;
- uint8 width, height;
- printchar((const Frame *)ds.ptr(0, 0), &x, bx, al, ah, &width, &height);
- di = x;
- cl = width;
- ch = height;
-}
-
-void DreamGenContext::printchar(const Frame *charSet, uint16* x, uint16 y, uint8 c, uint8 nextChar, uint8 *width, uint8 *height) {
+void DreamWebEngine::printChar(const GraphicsFile &charSet, uint16* x, uint16 y, uint8 c, uint8 nextChar, uint8 *width, uint8 *height) {
if (c == 255)
return;
- push(si);
- push(di);
- if (data.byte(kForeignrelease) != 0)
+
+ uint8 dummyWidth, dummyHeight;
+ if (width == NULL)
+ width = &dummyWidth;
+ if (height == NULL)
+ height = &dummyHeight;
+ if (_foreignRelease)
y -= 3;
- uint16 tmp = c - 32 + data.word(kCharshift);
- showframe(charSet, *x, y, tmp & 0x1ff, (tmp >> 8) & 0xfe, width, height);
- di = pop();
- si = pop();
- _cmp(data.byte(kKerning), 0);
- if (flags.z())
- *width = kernchars(c, nextChar, *width);
+ uint16 tmp = c - 32 + _charShift;
+ showFrame(charSet, *x, y, tmp & 0x1ff, (tmp >> 8) & 0xfe, width, height);
+ if (_kerning == 0)
+ *width = kernChars(c, nextChar, *width);
(*x) += *width;
}
-void DreamGenContext::printslow() {
- al = printslow(es.ptr(si, 0), di, bx, dl, (bool)(dl & 1));
+void DreamWebEngine::printChar(const GraphicsFile &charSet, uint16 x, uint16 y, uint8 c, uint8 nextChar, uint8 *width, uint8 *height) {
+ printChar(charSet, &x, y, c, nextChar, width, height);
}
-uint8 DreamGenContext::printslow(const uint8 *string, uint16 x, uint16 y, uint8 maxWidth, bool centered) {
- data.byte(kPointerframe) = 1;
- data.byte(kPointermode) = 3;
- const Frame* charSet = (const Frame *)segRef(data.word(kCharset1)).ptr(0, 0);
+uint8 DreamWebEngine::printSlow(const uint8 *string, uint16 x, uint16 y, uint8 maxWidth, bool centered) {
+ _pointerFrame = 1;
+ _pointerMode = 3;
do {
uint16 offset = x;
- uint16 charCount = getnumber(charSet, string, maxWidth, centered, &offset);
+ uint16 charCount = getNumber(_charset1, string, maxWidth, centered, &offset);
do {
uint8 c0 = string[0];
uint8 c1 = string[1];
uint8 c2 = string[2];
- c0 = engine->modifyChar(c0);
- printboth(charSet, &offset, y, c0, c1);
+ c0 = modifyChar(c0);
+ printBoth(_charset1, &offset, y, c0, c1);
if ((c1 == 0) || (c1 == ':')) {
return 0;
}
if (charCount != 1) {
- c1 = engine->modifyChar(c1);
- data.word(kCharshift) = 91;
+ c1 = modifyChar(c1);
+ _charShift = 91;
uint16 offset2 = offset;
- printboth(charSet, &offset2, y, c1, c2);
- data.word(kCharshift) = 0;
+ printBoth(_charset1, &offset2, y, c1, c2);
+ _charShift = 0;
for (int i=0; i<2; ++i) {
- uint16 mouseState = waitframes();
- if (data.byte(kQuitrequested))
+ uint16 mouseState = waitFrames();
+ if (_quitRequested)
return 0;
if (mouseState == 0)
continue;
- if (mouseState != data.word(kOldbutton)) {
+ if (mouseState != _oldButton) {
return 1;
}
}
@@ -128,83 +119,66 @@ uint8 DreamGenContext::printslow(const uint8 *string, uint16 x, uint16 y, uint8
} while (true);
}
-void DreamGenContext::printdirect() {
- uint16 y = bx;
- uint16 initialSi = si;
- const uint8 *initialString = es.ptr(si, 0);
- const uint8 *string = initialString;
- printdirect(&string, di, &y, dl, (bool)(dl & 1));
- si = initialSi + (string - initialString);
- bx = y;
-}
-
-void DreamGenContext::printdirect(const uint8* string, uint16 x, uint16 y, uint8 maxWidth, bool centered) {
- printdirect(&string, x, &y, maxWidth, centered);
+uint8 DreamWebEngine::printDirect(const uint8* string, uint16 x, uint16 y, uint8 maxWidth, bool centered) {
+ return printDirect(&string, x, &y, maxWidth, centered);
}
-void DreamGenContext::printdirect(const uint8** string, uint16 x, uint16 *y, uint8 maxWidth, bool centered) {
- data.word(kLastxpos) = x;
- const Frame *charSet = (const Frame *)segRef(data.word(kCurrentset)).ptr(0, 0);
+uint8 DreamWebEngine::printDirect(const uint8** string, uint16 x, uint16 *y, uint8 maxWidth, bool centered) {
+ _lastXPos = x;
+ const GraphicsFile &charSet = *_currentCharset;
while (true) {
uint16 offset = x;
- uint8 charCount = getnumber(charSet, *string, maxWidth, centered, &offset);
+ uint8 charCount = getNumber(charSet, *string, maxWidth, centered, &offset);
uint16 i = offset;
do {
uint8 c = (*string)[0];
uint8 nextChar = (*string)[1];
++(*string);
if ((c == 0) || (c == ':')) {
- return;
+ return c;
}
- c = engine->modifyChar(c);
+ c = modifyChar(c);
uint8 width, height;
- printchar(charSet, &i, *y, c, nextChar, &width, &height);
- data.word(kLastxpos) = i;
+ printChar(charSet, &i, *y, c, nextChar, &width, &height);
+ _lastXPos = i;
--charCount;
- } while(charCount);
- *y += data.word(kLinespacing);
+ } while (charCount);
+ *y += _lineSpacing;
}
}
-void DreamGenContext::getnumber() {
- uint16 offset = di;
- cl = getnumber((Frame *)ds.ptr(0, 0), es.ptr(si, 0), dl, (bool)(dl & 1), &offset);
- di = offset;
-}
-
-uint8 DreamGenContext::getnumber(const Frame *charSet, const uint8 *string, uint16 maxWidth, bool centered, uint16* offset) {
+uint8 DreamWebEngine::getNumber(const GraphicsFile &charSet, const uint8 *string, uint16 maxWidth, bool centered, uint16* offset) {
uint8 totalWidth = 0;
uint8 charCount = 0;
while (true) {
uint8 wordTotalWidth, wordCharCount;
- uint8 done = getnextword(charSet, string, &wordTotalWidth, &wordCharCount);
+ uint8 done = getNextWord(charSet, string, &wordTotalWidth, &wordCharCount);
string += wordCharCount;
+ uint16 tmp = totalWidth + wordTotalWidth - 10;
if (done == 1) { //endoftext
- ax = totalWidth + wordTotalWidth - 10;
- if (ax < maxWidth) {
+ if (tmp < maxWidth) {
totalWidth += wordTotalWidth;
charCount += wordCharCount;
}
if (centered) {
- ax = (maxWidth & 0xfe) + 2 + 20 - totalWidth;
- ax /= 2;
+ tmp = (maxWidth & 0xfe) + 2 + 20 - totalWidth;
+ tmp /= 2;
} else {
- ax = 0;
+ tmp = 0;
}
- *offset += ax;
+ *offset += tmp;
return charCount;
}
- ax = totalWidth + wordTotalWidth - 10;
- if (ax >= maxWidth) { //gotoverend
+ if (tmp >= maxWidth) { //gotoverend
if (centered) {
- ax = (maxWidth & 0xfe) - totalWidth + 20;
- ax /= 2;
+ tmp = (maxWidth & 0xfe) - totalWidth + 20;
+ tmp /= 2;
} else {
- ax = 0;
+ tmp = 0;
}
- *offset += ax;
+ *offset += tmp;
return charCount;
}
totalWidth += wordTotalWidth;
@@ -212,22 +186,150 @@ uint8 DreamGenContext::getnumber(const Frame *charSet, const uint8 *string, uint
}
}
-uint8 DreamGenContext::kernchars(uint8 firstChar, uint8 secondChar, uint8 width) {
- if ((firstChar == 'a') || (al == 'u')) {
+uint8 DreamWebEngine::kernChars(uint8 firstChar, uint8 secondChar, uint8 width) {
+ if ((firstChar == 'a') || (firstChar == 'u')) {
if ((secondChar == 'n') || (secondChar == 't') || (secondChar == 'r') || (secondChar == 'i') || (secondChar == 'l'))
return width-1;
}
return width;
}
-uint16 DreamGenContext::waitframes() {
- readmouse();
- showpointer();
- vsync();
- dumppointer();
- delpointer();
- return data.word(kMousebutton);
+uint16 DreamWebEngine::waitFrames() {
+ readMouse();
+ showPointer();
+ vSync();
+ dumpPointer();
+ delPointer();
+ return _mouseButton;
+}
+
+const char *DreamWebEngine::monPrint(const char *string) {
+ _kerning = 1;
+ uint16 x = _monAdX;
+ const char *iterator = string;
+ bool done = false;
+ while (!done) {
+
+ uint16 count = getNumber(_monitorCharset, (const uint8 *)iterator, 166, false, &x);
+ do {
+ char c = *iterator++;
+ if (c == ':')
+ break;
+ if ((c == 0) || (c == '"') || (c == '=')) {
+ done = true;
+ break;
+ }
+ if (c == '%') {
+ _vars._lastTrigger = *iterator;
+ iterator += 2;
+ done = true;
+ break;
+ }
+ c = modifyChar(c);
+ printChar(_monitorCharset, &x, _monAdY, c, 0, NULL, NULL);
+ _cursLocX = x;
+ _cursLocY = _monAdY;
+ _mainTimer = 1;
+ printCurs();
+ vSync();
+ lockMon();
+ delCurs();
+ } while (--count);
+
+ x = _monAdX;
+ scrollMonitor();
+ _cursLocX = _monAdX;
+ }
+
+ _kerning = 0;
+ return iterator;
+}
+
+void DreamWebEngine::rollEndCreditsGameWon() {
+ playChannel0(16, 255);
+ _volume = 7;
+ _volumeTo = 0;
+ _volumeDirection = -1;
+
+ multiGet(_mapStore, 75, 20, 160, 160);
+
+ const uint8 *string = getTextInFile1(3);
+ const int linespacing = _lineSpacing;
+
+ for (int i = 0; i < 254; ++i) {
+ // Output the text, initially with an offset of 10 pixels,
+ // then move it up one pixel until we shifted it by a complete
+ // line of text.
+ for (int j = 0; j < linespacing; ++j) {
+ vSync();
+ multiPut(_mapStore, 75, 20, 160, 160);
+ vSync();
+
+ // Output up to 18 lines of text
+ uint16 y = 10 - j;
+ const uint8 *tmp_str = string;
+ for (int k = 0; k < 18; ++k) {
+ printDirect(&tmp_str, 75, &y, 160 + 1, true);
+ y += linespacing;
+ }
+
+ vSync();
+ multiDump(75, 20, 160, 160);
+ }
+
+ // Skip to the next text line
+ byte c;
+ do {
+ c = *string++;
+ } while (c != ':' && c != 0);
+ }
+
+ hangOn(100);
+ panelToMap();
+ fadeScreenUpHalf();
}
-} /*namespace dreamgen */
+void DreamWebEngine::rollEndCreditsGameLost() {
+ multiGet(_mapStore, 25, 20, 160, 160);
+
+ const uint8 *string = getTextInFile1(49);
+ const int linespacing = _lineSpacing;
+
+ for (int i = 0; i < 80; ++i) {
+ // Output the text, initially with an offset of 10 pixels,
+ // then move it up one pixel until we shifted it by a complete
+ // line of text.
+ for (int j = 0; j < linespacing; ++j) {
+ vSync();
+ multiPut(_mapStore, 25, 20, 160, 160);
+ vSync();
+
+ // Output up to 18 lines of text
+ uint16 y = 10 - j;
+ const uint8 *tmp_str = string;
+ for (int k = 0; k < 18; ++k) {
+ printDirect(&tmp_str, 25, &y, 160 + 1, true);
+ y += linespacing;
+ }
+
+ vSync();
+ multiDump(25, 20, 160, 160);
+
+ if (_lastHardKey == 1)
+ return;
+ }
+
+ // Skip to the next text line
+ byte c;
+ do {
+ c = *string++;
+ } while (c != ':' && c != 0);
+
+ if (_lastHardKey == 1)
+ return;
+ }
+
+ hangOne(120);
+}
+} // End of namespace DreamWeb
diff --git a/engines/dreamweb/rain.cpp b/engines/dreamweb/rain.cpp
new file mode 100644
index 0000000000..7db4744cbf
--- /dev/null
+++ b/engines/dreamweb/rain.cpp
@@ -0,0 +1,194 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "dreamweb/dreamweb.h"
+
+namespace DreamWeb {
+
+void DreamWebEngine::showRain() {
+ Common::List<Rain>::iterator i;
+
+ // Do nothing if there's no rain at all
+ if (_rainList.empty())
+ return;
+
+ const uint8 *frameData = _mainSprites.getFrameData(58);
+
+ for (i = _rainList.begin(); i != _rainList.end(); ++i) {
+ Rain &rain = *i;
+ uint16 y = rain.y + _mapAdY + _mapYStart;
+ uint16 x = rain.x + _mapAdX + _mapXStart;
+ uint16 size = rain.size;
+ uint16 offset = (rain.w3 - rain.b5) & 511;
+ rain.w3 = offset;
+ const uint8 *src = frameData + offset;
+ uint8 *dst = workspace() + y * 320 + x;
+ for (uint16 j = 0; j < size; ++j) {
+ uint8 v = src[j];
+ if (v != 0)
+ *dst = v;
+ dst += 320-1; // advance diagonally
+ }
+ }
+
+ if (_channel1Playing != 255)
+ return;
+ if (_realLocation == 2 && _vars._beenMugged != 1)
+ return;
+ if (_realLocation == 55)
+ return;
+
+ if (randomNumber() >= 1) // play thunder with 1 in 256 chance
+ return;
+
+ uint8 soundIndex;
+ if (_channel0Playing != 6)
+ soundIndex = 4;
+ else
+ soundIndex = 7;
+ playChannel1(soundIndex);
+}
+
+uint8 DreamWebEngine::getBlockOfPixel(uint8 x, uint8 y) {
+ uint8 flag, flagEx, type, flagX, flagY;
+ checkOne(x + _mapXStart, y + _mapYStart, &flag, &flagEx, &type, &flagX, &flagY);
+ if (flag & 1)
+ return 0;
+ else
+ return type;
+}
+
+void DreamWebEngine::splitIntoLines(uint8 x, uint8 y) {
+ do {
+ Rain rain;
+
+ // Look for line start
+ while (!getBlockOfPixel(x, y)) {
+ --x;
+ ++y;
+ if (x == 0 || y >= _mapYSize)
+ return;
+ }
+
+ rain.x = x;
+ rain.y = y;
+
+ uint8 length = 1;
+
+ // Look for line end
+ while (getBlockOfPixel(x, y)) {
+ --x;
+ ++y;
+ if (x == 0 || y >= _mapYSize)
+ break;
+ ++length;
+ }
+
+ rain.size = length;
+ rain.w3 = _rnd.getRandomNumber(65535);
+ rain.b5 = _rnd.getRandomNumberRng(4, 7);
+ _rainList.push_back(rain);
+ } while (x > 0 && y < _mapYSize);
+}
+
+struct RainLocation {
+ uint8 location;
+ uint8 x, y;
+ uint8 rainSpacing;
+};
+
+static const RainLocation rainLocationList[] = {
+ { 1,44,10,16 },
+ { 4,11,30,14 },
+ { 4,22,30,14 },
+ { 3,33,10,14 },
+ { 10,33,30,14 },
+ { 10,22,30,24 },
+ { 9,22,10,14 },
+ { 2,33,0,14 },
+ { 2,22,0,14 },
+ { 6,11,30,14 },
+ { 7,11,20,18 },
+ { 7,0,20,18 },
+ { 7,0,30,18 },
+ { 55,44,0,14 },
+ { 5,22,30,14 },
+
+ { 8,0,10,18 },
+ { 8,11,10,18 },
+ { 8,22,10,18 },
+ { 8,33,10,18 },
+ { 8,33,20,18 },
+ { 8,33,30,18 },
+ { 8,33,40,18 },
+ { 8,22,40,18 },
+ { 8,11,40,18 },
+
+ { 21,44,20,18 },
+ { 255,0,0,0 }
+};
+
+void DreamWebEngine::initRain() {
+ const RainLocation *r = rainLocationList;
+ _rainList.clear();
+
+ uint8 rainSpacing = 0;
+
+ // look up location in rainLocationList to determine rainSpacing
+ for (r = rainLocationList; r->location != 0xff; ++r) {
+ if (r->location == _realLocation &&
+ r->x == _mapX && r->y == _mapY) {
+ rainSpacing = r->rainSpacing;
+ break;
+ }
+ }
+
+ if (rainSpacing == 0) {
+ // location not found in rainLocationList: no rain
+ return;
+ }
+
+ // start lines of rain from top of screen
+ uint8 x = 4;
+ do {
+ uint8 delta = _rnd.getRandomNumberRng(3, rainSpacing - 1);
+ x += delta;
+ if (x >= _mapXSize)
+ break;
+
+ splitIntoLines(x, 0);
+ } while (true);
+
+ // start lines of rain from side of screen
+ uint8 y = 0;
+ do {
+ uint8 delta = _rnd.getRandomNumberRng(3, rainSpacing - 1);
+ y += delta;
+ if (y >= _mapYSize)
+ break;
+
+ splitIntoLines(_mapXSize - 1, y);
+ } while (true);
+}
+
+} // End of namespace DreamWeb
+
diff --git a/engines/dreamweb/runtime.h b/engines/dreamweb/runtime.h
deleted file mode 100644
index 8aa71b285c..0000000000
--- a/engines/dreamweb/runtime.h
+++ /dev/null
@@ -1,588 +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 DREAMGEN_RUNTIME_H__
-#define 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);
- }
-
- SegmentRef segRef(uint16 seg) {
- SegmentRef result(this);
- result = seg;
- return result;
- }
-
- 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/saveload.cpp b/engines/dreamweb/saveload.cpp
index 636182dc83..a526c8a3bc 100644
--- a/engines/dreamweb/saveload.cpp
+++ b/engines/dreamweb/saveload.cpp
@@ -22,61 +22,133 @@
#include "dreamweb/dreamweb.h"
#include "engines/metaengine.h"
+#include "graphics/thumbnail.h"
#include "gui/saveload.h"
#include "common/config-manager.h"
#include "common/translation.h"
+#include "common/serializer.h"
-namespace DreamGen {
+namespace DreamWeb {
-void DreamGenContext::loadgame() {
- STACK_CHECK;
- if (data.byte(kCommandtype) != 246) {
- data.byte(kCommandtype) = 246;
- al = 41;
- commandonly();
- }
- if (data.word(kMousebutton) == data.word(kOldbutton))
+// Temporary storage for loading the room from a savegame
+Room g_madeUpRoomDat;
+
+
+void syncReelRoutine(Common::Serializer &s, ReelRoutine *reel) {
+ s.syncAsByte(reel->reallocation);
+ s.syncAsByte(reel->mapX);
+ s.syncAsByte(reel->mapY);
+ s.syncAsUint16LE(reel->_reelPointer);
+ s.syncAsByte(reel->period);
+ s.syncAsByte(reel->counter);
+ s.syncAsByte(reel->b7);
+}
+
+void syncGameVars(Common::Serializer &s, GameVars &vars) {
+ s.syncAsByte(vars._startVars);
+ s.syncAsByte(vars._progressPoints);
+ s.syncAsByte(vars._watchOn);
+ s.syncAsByte(vars._shadesOn);
+ s.syncAsByte(vars._secondCount);
+ s.syncAsByte(vars._minuteCount);
+ s.syncAsByte(vars._hourCount);
+ s.syncAsByte(vars._zoomOn);
+ s.syncAsByte(vars._location);
+ s.syncAsByte(vars._exPos);
+ s.syncAsUint16LE(vars._exFramePos);
+ s.syncAsUint16LE(vars._exTextPos);
+ s.syncAsUint16LE(vars._card1Money);
+ s.syncAsUint16LE(vars._listPos);
+ s.syncAsByte(vars._ryanPage);
+ s.syncAsUint16LE(vars._watchingTime);
+ s.syncAsUint16LE(vars._reelToWatch);
+ s.syncAsUint16LE(vars._endWatchReel);
+ s.syncAsByte(vars._speedCount);
+ s.syncAsByte(vars._watchSpeed);
+ s.syncAsUint16LE(vars._reelToHold);
+ s.syncAsUint16LE(vars._endOfHoldReel);
+ s.syncAsByte(vars._watchMode);
+ s.syncAsByte(vars._destAfterHold);
+ s.syncAsByte(vars._newsItem);
+ s.syncAsByte(vars._liftFlag);
+ s.syncAsByte(vars._liftPath);
+ s.syncAsByte(vars._lockStatus);
+ s.syncAsByte(vars._doorPath);
+ s.syncAsByte(vars._countToOpen);
+ s.syncAsByte(vars._countToClose);
+ s.syncAsByte(vars._rockstarDead);
+ s.syncAsByte(vars._generalDead);
+ s.syncAsByte(vars._sartainDead);
+ s.syncAsByte(vars._aideDead);
+ s.syncAsByte(vars._beenMugged);
+ s.syncAsByte(vars._gunPassFlag);
+ s.syncAsByte(vars._canMoveAltar);
+ s.syncAsByte(vars._talkedToAttendant);
+ s.syncAsByte(vars._talkedToSparky);
+ s.syncAsByte(vars._talkedToBoss);
+ s.syncAsByte(vars._talkedToRecep);
+ s.syncAsByte(vars._cardPassFlag);
+ s.syncAsByte(vars._madmanFlag);
+ s.syncAsByte(vars._keeperFlag);
+ s.syncAsByte(vars._lastTrigger);
+ s.syncAsByte(vars._manDead);
+ s.syncAsByte(vars._seed1);
+ s.syncAsByte(vars._seed2);
+ s.syncAsByte(vars._seed3);
+ s.syncAsByte(vars._needToTravel);
+ s.syncAsByte(vars._throughDoor);
+ s.syncAsByte(vars._newObs);
+ s.syncAsByte(vars._ryanOn);
+ s.syncAsByte(vars._combatCount);
+ s.syncAsByte(vars._lastWeapon);
+ s.syncAsByte(vars._dreamNumber);
+ s.syncAsByte(vars._roomAfterDream);
+ s.syncAsByte(vars._shakeCounter);
+}
+
+void DreamWebEngine::loadGame() {
+ commandOnlyCond(41, 246);
+ if (_mouseButton == _oldButton)
return; // "noload"
- if (data.word(kMousebutton) == 1) {
- ax = 0xFFFF;
- doload();
- }
+ if (_mouseButton == 1)
+ doLoad(-1);
}
-// input: ax = savegameId
// if -1, open menu to ask for slot to load
// if >= 0, directly load from that slot
-void DreamGenContext::doload() {
- STACK_CHECK;
- int savegameId = (int16)ax;
-
- data.byte(kLoadingorsave) = 1;
+void DreamWebEngine::doLoad(int savegameId) {
+ _loadingOrSave = 1;
if (ConfMan.getBool("dreamweb_originalsaveload") && savegameId == -1) {
- showopbox();
- showloadops();
- data.byte(kCurrentslot) = 0;
- showslots();
- shownames();
- data.byte(kPointerframe) = 0;
- worktoscreenm();
- namestoold();
- data.byte(kGetback) = 0;
-
- while (true) {
- if (data.byte(kQuitrequested))
- return; // "quitloaded"
- delpointer();
- readmouse();
- showpointer();
- vsync();
- dumppointer();
- dumptextline();
- bx = offset_loadlist;
- checkcoords();
- if (data.byte(kGetback) == 1)
- break;
- if (data.byte(kGetback) == 2)
+ showOpBox();
+ showLoadOps();
+ _currentSlot = 0;
+ showSlots();
+ showNames();
+ _pointerFrame = 0;
+ workToScreenM();
+ namesToOld();
+ _getBack = 0;
+
+ while (_getBack == 0) {
+ if (_quitRequested)
+ return;
+ delPointer();
+ readMouse();
+ showPointer();
+ vSync();
+ dumpPointer();
+ dumpTextLine();
+ RectWithCallback loadlist[] = {
+ { kOpsx+176,kOpsx+192,kOpsy+60,kOpsy+76,&DreamWebEngine::getBackToOps },
+ { kOpsx+128,kOpsx+190,kOpsy+12,kOpsy+100,&DreamWebEngine::actualLoad },
+ { kOpsx+2,kOpsx+92,kOpsy+4,kOpsy+81,&DreamWebEngine::selectSlot },
+ { kOpsx+158,kOpsx+158+(18*3),kOpsy-17,kOpsy-1,&DreamWebEngine::selectSaveLoadPage },
+ { 0,320,0,200,&DreamWebEngine::blank },
+ { 0xFFFF,0,0,0,0 }
+ };
+ checkCoords(loadlist);
+ if (_getBack == 2)
return; // "quitloaded"
}
} else {
@@ -94,131 +166,80 @@ void DreamGenContext::doload() {
}
if (savegameId < 0) {
- data.byte(kGetback) = 0;
+ _getBack = 0;
return;
}
+ loadPosition(savegameId);
- // TODO: proper scheme for filename, in a separate function
- //Common::String filename = ConfMan.getActiveDomainName() + Common::String::format(".d%02d", savegameId);
- Common::String filename = Common::String::format("DREAMWEB.D%02d", savegameId);
- debug(1, "Loading from filename: %s", filename.c_str());
- engine->openSaveFileForReading(filename);
-
- // TODO: The below is duplicated from Loadposition
- data.word(kTimecount) = 0;
- clearchanges();
-
- ds = cs;
- dx = kFileheader;
- cx = kHeaderlen;
- savefileread();
- es = cs;
- di = kFiledata;
- ax = savegameId;
- if (savegameId < 7) {
- cx = 17;
- _mul(cx);
- ds = data;
- dx = kSavenames;
- _add(dx, ax);
- loadseg();
- } else {
- // For potential support of more than 7 savegame slots,
- // loading into the savenames buffer isn't always possible
- // Emulate a loadseg call:
- uint8 namebuf[17];
- engine->readFromFile(namebuf, 17);
- _add(di, 2);
- }
- ds = data;
- dx = kStartvars;
- loadseg();
- ds = data.word(kExtras);
- dx = kExframedata;
- loadseg();
- ds = data.word(kBuffers);
- dx = kListofchanges;
- loadseg();
- ds = data;
- dx = kMadeuproomdat;
- loadseg();
- ds = cs;
- dx = kReelroutines;
- loadseg();
- closefile();
- data.byte(kGetback) = 1;
+ _getBack = 1;
}
- // kTempgraphics might not have been allocated if we bypassed all menus
- if (data.word(kTempgraphics) != 0xFFFF)
- getridoftemp();
-
- dx = data;
- es = dx;
- bx = kMadeuproomdat;
- 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;
+ // If we reach this point, loadPosition() has just been called.
+ // Among other things, it will have filled g_MadeUpRoomDat.
+
+ _saveGraphics.clear();
+
+ startLoading(g_madeUpRoomDat);
+ loadRoomsSample();
+ _roomLoaded = 1;
+ _newLocation = 255;
+ clearSprites();
+ initMan();
+ initRain();
+ _textAddressX = 13;
+ _textAddressY = 182;
+ _textLen = 240;
startup();
- worktoscreen();
- data.byte(kGetback) = 4;
+ workToScreen();
+ _getBack = 4;
}
-void DreamGenContext::savegame() {
- STACK_CHECK;
- if (data.byte(kMandead) == 2) {
+void DreamWebEngine::saveGame() {
+ if (_vars._manDead == 2) {
blank();
return;
}
- if (data.byte(kCommandtype) != 247) {
- data.byte(kCommandtype) = 247;
- al = 44;
- commandonly();
- }
- if (data.word(kMousebutton) != 1)
+ commandOnlyCond(44, 247);
+ if (_mouseButton != 1)
return;
- data.byte(kLoadingorsave) = 2;
+ _loadingOrSave = 2;
if (ConfMan.getBool("dreamweb_originalsaveload")) {
- showopbox();
- showsaveops();
- data.byte(kCurrentslot) = 0;
- showslots();
- shownames();
- worktoscreenm();
- namestoold();
- data.word(kBufferin) = 0;
- data.word(kBufferout) = 0;
- data.byte(kGetback) = 0;
-
- while (true) {
- _cmp(data.byte(kQuitrequested), 0);
- if (!flags.z())
- return /* (quitsavegame) */;
- delpointer();
- checkinput();
- readmouse();
- showpointer();
- vsync();
- dumppointer();
- dumptextline();
- bx = offset_savelist;
- checkcoords();
- _cmp(data.byte(kGetback), 0);
- if (flags.z())
- continue;
- break;
+ showOpBox();
+ showSaveOps();
+ _currentSlot = 0;
+ showSlots();
+ showNames();
+ workToScreenM();
+ namesToOld();
+ _bufferIn = 0;
+ _bufferOut = 0;
+ _getBack = 0;
+
+ while (_getBack == 0) {
+ if (_quitRequested)
+ return;
+ delPointer();
+ checkInput();
+ readMouse();
+ showPointer();
+ vSync();
+ dumpPointer();
+ dumpTextLine();
+
+ RectWithCallback savelist[] = {
+ { kOpsx+176,kOpsx+192,kOpsy+60,kOpsy+76,&DreamWebEngine::getBackToOps },
+ { kOpsx+128,kOpsx+190,kOpsy+12,kOpsy+100,&DreamWebEngine::actualSave },
+ { kOpsx+2,kOpsx+92,kOpsy+4,kOpsy+81,&DreamWebEngine::selectSlot },
+ { kOpsx+158,kOpsx+158+(18*3),kOpsy-17,kOpsy-1,&DreamWebEngine::selectSaveLoadPage },
+ { 0,320,0,200,&DreamWebEngine::blank },
+ { 0xFFFF,0,0,0,0 }
+ };
+ checkCoords(savelist);
}
return;
} else {
@@ -234,110 +255,605 @@ void DreamGenContext::savegame() {
delete dialog;
if (savegameId < 0) {
- data.byte(kGetback) = 0;
+ _getBack = 0;
return;
}
- // TODO: The below is copied from actualsave
- al = data.byte(kLocation);
- ah = 0;
- cx = 32;
- _mul(cx);
- ds = cs;
- si = kRoomdata;
- _add(si, ax);
- di = kMadeuproomdat;
- 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;
-
- // TODO: The below is copied from saveposition
- makeheader();
-
- //Common::String filename = ConfMan.getActiveDomainName() + Common::String::format(".d%02d", savegameId);
- Common::String filename = Common::String::format("DREAMWEB.D%02d", savegameId);
- debug(1, "Saving to filename: %s (%s)", filename.c_str(), game_description.c_str());
-
- engine->openSaveFileForWriting(filename.c_str());
-
- dx = data;
- ds = dx;
- dx = kFileheader;
- cx = kHeaderlen;
- savefilewrite();
- dx = data;
- es = dx;
- di = kFiledata;
-
- // TODO: Check if this 2 is a constant
- uint8 descbuf[17] = { 2, 0 };
- strncpy((char*)descbuf+1, game_description.c_str(), 16);
+ char descbuf[17] = { 2, 0 };
+ Common::strlcpy((char *)descbuf + 1, game_description.c_str(), 16);
unsigned int desclen = game_description.size();
if (desclen > 15)
desclen = 15;
// zero terminate, and pad with ones
descbuf[++desclen] = 0;
- while (desclen < 17)
+ while (desclen < 16)
descbuf[++desclen] = 1;
- if (savegameId < 7) {
- ax = savegameId;
- cx = 17;
- _mul(cx);
- ds = data;
- dx = kSavenames;
- _add(dx, ax);
- memcpy(data.ptr(dx,17), descbuf, 17);
- saveseg();
+
+ // TODO: The below is copied from actualsave
+ _saveGraphics.clear();
+ restoreAll(); // reels
+ _textAddressX = 13;
+ _textAddressY = 182;
+ _textLen = 240;
+ redrawMainScrn();
+ workToScreen(); // show the main screen without the mouse pointer
+
+ // We need to save after the scene has been redrawn, to capture the
+ // correct screen thumbnail
+ savePosition(savegameId, descbuf);
+
+ workToScreenM();
+ _getBack = 4;
+ }
+}
+
+void DreamWebEngine::namesToOld() {
+ memcpy(_saveNamesOld, _saveNames, 17*21);
+}
+
+void DreamWebEngine::oldToNames() {
+ memcpy(_saveNames, _saveNamesOld, 17*21);
+}
+
+void DreamWebEngine::saveLoad() {
+ if (_vars._watchingTime || (_pointerMode == 2)) {
+ blank();
+ return;
+ }
+ commandOnlyCond(43, 253);
+ if ((_mouseButton != _oldButton) && (_mouseButton & 1))
+ doSaveLoad();
+}
+
+void DreamWebEngine::doSaveLoad() {
+ _pointerFrame = 0;
+ _textAddressX = 70;
+ _textAddressY = 182-8;
+ _textLen = 181;
+ _manIsOffScreen = 1;
+ clearWork();
+ createPanel2();
+ underTextLine();
+ getRidOfAll();
+ loadSaveBox();
+ showOpBox();
+ showMainOps();
+ workToScreen();
+
+ RectWithCallback opsList[] = {
+ { kOpsx+59,kOpsx+114,kOpsy+30,kOpsy+76,&DreamWebEngine::getBackFromOps },
+ { kOpsx+10,kOpsx+77,kOpsy+10,kOpsy+59,&DreamWebEngine::DOSReturn },
+ { kOpsx+128,kOpsx+190,kOpsy+16,kOpsy+100,&DreamWebEngine::discOps },
+ { 0,320,0,200,&DreamWebEngine::blank },
+ { 0xFFFF,0,0,0,0 }
+ };
+
+ bool firstOps = true;
+
+ do { // restart ops
+ if (firstOps) {
+ firstOps = false;
} else {
- // savenames only has room for descriptions for 7 slots
- uint16 len = es.word(di);
- _add(di, 2);
- assert(len == 17);
- engine->writeToSaveFile(descbuf, len);
+ showOpBox();
+ showMainOps();
+ workToScreenM();
+ }
+ _getBack = 0;
+
+ do { // wait ops
+ if (_quitRequested) {
+ _manIsOffScreen = 0;
+ return;
+ }
+
+ readMouse();
+ showPointer();
+ vSync();
+ dumpPointer();
+ dumpTextLine();
+ delPointer();
+ checkCoords(opsList);
+ } while (!_getBack);
+ } while (_getBack == 2);
+
+ _textAddressX = 13;
+ _textAddressY = 182;
+ _textLen = 240;
+ if (_getBack != 4) {
+ _saveGraphics.clear();
+ restoreAll();
+ redrawMainScrn();
+ workToScreenM();
+ _commandType = 200;
+ }
+ _manIsOffScreen = 0;
+}
+
+void DreamWebEngine::getBackFromOps() {
+ if (_vars._manDead == 2)
+ blank();
+ else
+ getBack1();
+}
+
+void DreamWebEngine::getBackToOps() {
+ commandOnlyCond(42, 201);
+
+ if (_mouseButton != _oldButton) {
+ if (_mouseButton & 1) {
+ oldToNames();
+ _getBack = 2;
+ }
+ }
+}
+
+void DreamWebEngine::showMainOps() {
+ showFrame(_saveGraphics, kOpsx+10, kOpsy+10, 8, 0);
+ showFrame(_saveGraphics, kOpsx+59, kOpsy+30, 7, 0);
+ showFrame(_saveGraphics, kOpsx+128+4, kOpsy+12, 1, 0);
+}
+
+void DreamWebEngine::showDiscOps() {
+ showFrame(_saveGraphics, kOpsx+128+4, kOpsy+12, 1, 0);
+ showFrame(_saveGraphics, kOpsx+10, kOpsy+10, 9, 0);
+ showFrame(_saveGraphics, kOpsx+59, kOpsy+30, 10, 0);
+ showFrame(_saveGraphics, kOpsx+176+2, kOpsy+60-4, 5, 0);
+}
+
+void DreamWebEngine::discOps() {
+ commandOnlyCond(43, 249);
+
+ if (_mouseButton == _oldButton || !(_mouseButton & 1))
+ return;
+
+ scanForNames();
+ _loadingOrSave = 2;
+ showOpBox();
+ showDiscOps();
+ _currentSlot = 0;
+ workToScreenM();
+ _getBack = 0;
+
+ RectWithCallback discOpsList[] = {
+ { kOpsx+59,kOpsx+114,kOpsy+30,kOpsy+76,&DreamWebEngine::loadGame },
+ { kOpsx+10,kOpsx+79,kOpsy+10,kOpsy+59,&DreamWebEngine::saveGame },
+ { kOpsx+176,kOpsx+192,kOpsy+60,kOpsy+76,&DreamWebEngine::getBackToOps },
+ { 0,320,0,200,&DreamWebEngine::blank },
+ { 0xFFFF,0,0,0,0 }
+ };
+
+ do {
+ if (_quitRequested)
+ return; // quitdiscops
+
+ delPointer();
+ readMouse();
+ showPointer();
+ vSync();
+ dumpPointer();
+ dumpTextLine();
+ checkCoords(discOpsList);
+ } while (!_getBack);
+}
+
+void DreamWebEngine::actualSave() {
+ commandOnlyCond(44, 222);
+
+ if (!(_mouseButton & 1))
+ return;
+
+ unsigned int slot = _currentSlot + 7 * _saveLoadPage;
+
+ const char *desc = &_saveNames[17*slot];
+ if (desc[1] == 0) // The actual description string starts at desc[1]
+ return;
+
+ savePosition(slot, desc);
+
+ _saveGraphics.clear();
+ restoreAll(); // reels
+ _textAddressX = 13;
+ _textAddressY = 182;
+ _textLen = 240;
+ redrawMainScrn();
+ workToScreenM();
+ _getBack = 4;
+}
+
+void DreamWebEngine::actualLoad() {
+ commandOnlyCond(41, 221);
+
+ if (_mouseButton == _oldButton || _mouseButton != 1)
+ return;
+
+ unsigned int slot = _currentSlot + 7 * _saveLoadPage;
+
+ const char *desc = &_saveNames[17*slot];
+ if (desc[1] == 0) // The actual description string starts at desc[1]
+ return;
+
+ loadPosition(slot);
+ _getBack = 1;
+}
+
+void DreamWebEngine::savePosition(unsigned int slot, const char *descbuf) {
+
+ const Room &currentRoom = g_roomData[_vars._location];
+
+ Room madeUpRoom = currentRoom;
+ madeUpRoom.roomsSample = _roomsSample;
+ madeUpRoom.mapX = _mapX;
+ madeUpRoom.mapY = _mapY;
+ madeUpRoom.liftFlag = _vars._liftFlag;
+ madeUpRoom.b21 = _mansPath;
+ madeUpRoom.facing = _facing;
+ madeUpRoom.b27 = 255;
+
+ Common::String filename = getSavegameFilename(slot);
+ debug(1, "savePosition: slot %d filename %s", slot, filename.c_str());
+ Common::OutSaveFile *outSaveFile = getSaveFileManager()->openForSaving(filename);
+ if (!outSaveFile) // TODO: Do proper error handling!
+ error("save could not be opened for writing");
+
+ // Initialize new header
+ FileHeader header;
+
+ // Note: _desc is not zero-terminated
+ const char *desc = "DREAMWEB DATA FILE COPYRIGHT 1992 CREATIVE REALITY";
+ assert(strlen(desc) == sizeof(header._desc));
+ memcpy(header._desc, desc, sizeof(header._desc));
+ memset(&header._len[0], 0, sizeof(header._len));
+ memset(&header._padding[0], 0, sizeof(header._padding));
+
+ // fill length fields in savegame file header
+ uint16 len[6] = { 17, kLengthofvars, kLengthofextra,
+ 4*kNumChanges, 48, kNumReelRoutines*8+1 };
+ for (int i = 0; i < 6; ++i)
+ header.setLen(i, len[i]);
+
+ // Write a new section with data that we need for ScummVM (version,
+ // thumbnail, played time etc). We don't really care for its size,
+ // so we just set it to a magic number.
+ header.setLen(6, SCUMMVM_BLOCK_MAGIC_SIZE);
+
+ outSaveFile->write((const uint8 *)&header, sizeof(FileHeader));
+ outSaveFile->write(descbuf, len[0]);
+ // TODO: Convert more to serializer?
+ Common::Serializer s(0, outSaveFile);
+ syncGameVars(s, _vars);
+
+ // the Extras segment:
+ outSaveFile->write((const uint8 *)_exFrames._frames, kFrameBlocksize);
+ outSaveFile->write((const uint8 *)_exFrames._data, kExframeslen);
+ outSaveFile->write((const uint8 *)_exData, sizeof(DynObject)*kNumexobjects);
+ outSaveFile->write((const uint8 *)_exText._offsetsLE, 2*(kNumExObjects+2));
+ outSaveFile->write((const uint8 *)_exText._text, kExtextlen);
+
+ outSaveFile->write(_listOfChanges, len[3]);
+
+ // len[4] == 48, which is sizeof(Room) plus 16 for 'Roomscango'
+ outSaveFile->write((const uint8 *)&madeUpRoom, sizeof(Room));
+ outSaveFile->write(_roomsCanGo, 16);
+
+ for (unsigned int i = 0; i < kNumReelRoutines; ++i) {
+ syncReelRoutine(s, &_reelRoutines[i]);
+ }
+ // Terminator
+ s.syncAsByte(_reelRoutines[kNumReelRoutines].reallocation);
+
+ // ScummVM data block
+ outSaveFile->writeUint32BE(SCUMMVM_HEADER);
+ outSaveFile->writeByte(SAVEGAME_VERSION);
+ TimeDate curTime;
+ g_system->getTimeAndDate(curTime);
+ uint32 saveDate = ((curTime.tm_mday & 0xFF) << 24) | (((curTime.tm_mon + 1) & 0xFF) << 16) | ((curTime.tm_year + 1900) & 0xFFFF);
+ uint32 saveTime = ((curTime.tm_hour & 0xFF) << 16) | (((curTime.tm_min) & 0xFF) << 8) | ((curTime.tm_sec) & 0xFF);
+ uint32 playTime = g_engine->getTotalPlayTime() / 1000;
+ outSaveFile->writeUint32LE(saveDate);
+ outSaveFile->writeUint32LE(saveTime);
+ outSaveFile->writeUint32LE(playTime);
+ Graphics::saveThumbnail(*outSaveFile);
+
+ outSaveFile->finalize();
+ if (outSaveFile->err()) {
+ // TODO: Do proper error handling
+ warning("an error occurred while writing the savegame");
+ }
+
+ delete outSaveFile;
+}
+
+void DreamWebEngine::loadPosition(unsigned int slot) {
+ _timeCount = 0;
+ clearChanges();
+
+ Common::String filename = getSavegameFilename(slot);
+ debug(1, "loadPosition: slot %d filename %s", slot, filename.c_str());
+ Common::InSaveFile *inSaveFile = getSaveFileManager()->openForLoading(filename);
+ if (!inSaveFile) // TODO: Do proper error handling!
+ error("save could not be opened for reading");
+
+ FileHeader header;
+
+ inSaveFile->read((uint8 *)&header, sizeof(FileHeader));
+
+ // read segment lengths from savegame file header
+ int len[6];
+ for (int i = 0; i < 6; ++i)
+ len[i] = header.len(i);
+ if (len[0] != 17)
+ ::error("Error loading save: description buffer isn't 17 bytes");
+
+ if (slot < 21) {
+ inSaveFile->read(&_saveNames[17*slot], len[0]);
+ } else {
+ // The savenames buffer only has room for 21 descriptions
+ uint8 namebuf[17];
+ inSaveFile->read(namebuf, 17);
+ }
+
+ // TODO: Use serializer for more?
+ Common::Serializer s(inSaveFile, 0);
+ syncGameVars(s, _vars);
+
+ // the Extras segment:
+ inSaveFile->read((uint8 *)_exFrames._frames, kFrameBlocksize);
+ inSaveFile->read((uint8 *)_exFrames._data, kExframeslen);
+ inSaveFile->read((uint8 *)_exData, sizeof(DynObject)*kNumexobjects);
+ inSaveFile->read((uint8 *)_exText._offsetsLE, 2*(kNumExObjects+2));
+ inSaveFile->read((uint8 *)_exText._text, kExtextlen);
+
+ inSaveFile->read(_listOfChanges, len[3]);
+
+ // len[4] == 48, which is sizeof(Room) plus 16 for 'Roomscango'
+ // Note: the values read into g_madeUpRoomDat are only used in actualLoad,
+ // which is (almost) immediately called after this function
+ inSaveFile->read((uint8 *)&g_madeUpRoomDat, sizeof(Room));
+ inSaveFile->read(_roomsCanGo, 16);
+
+ for (unsigned int i = 0; i < kNumReelRoutines; ++i) {
+ syncReelRoutine(s, &_reelRoutines[i]);
+ }
+ // Terminator
+ s.syncAsByte(_reelRoutines[kNumReelRoutines].reallocation);
+
+ // Check if there's a ScummVM data block
+ if (header.len(6) == SCUMMVM_BLOCK_MAGIC_SIZE) {
+ uint32 tag = inSaveFile->readUint32BE();
+ if (tag != SCUMMVM_HEADER) {
+ warning("ScummVM data block found, but the block header is incorrect - skipping");
+ delete inSaveFile;
+ return;
}
- ds = data;
- dx = kStartvars;
- saveseg();
- ds = data.word(kExtras);
- dx = kExframedata;
- saveseg();
- ds = data.word(kBuffers);
- dx = kListofchanges;
- saveseg();
- ds = data;
- dx = kMadeuproomdat;
- saveseg();
- ds = data;
- dx = kReelroutines;
- saveseg();
- closefile();
-
- getridoftemp();
- restoreall();
- data.word(kTextaddressx) = 13;
- data.word(kTextaddressy) = 182;
- data.byte(kTextlen) = 240;
- redrawmainscrn();
- worktoscreenm();
- data.byte(kGetback) = 4;
+ byte version = inSaveFile->readByte();
+ if (version > SAVEGAME_VERSION) {
+ warning("ScummVM data block found, but it has been saved with a newer version of ScummVM - skipping");
+ delete inSaveFile;
+ return;
+ }
+
+ inSaveFile->skip(4); // saveDate
+ inSaveFile->skip(4); // saveTime
+ uint32 playTime = inSaveFile->readUint32LE();
+ g_engine->setTotalPlayTime(playTime * 1000);
+
+ // The thumbnail data follows, but we don't need it here
+ }
+
+ delete inSaveFile;
+}
+
+// Count number of save files, and load their descriptions into _saveNames
+uint DreamWebEngine::scanForNames() {
+ // There are 21 save slots, each of which are 17 bytes. The first byte
+ // doesn't seem to be used. The name starts at the second byte. All the
+ // slots are initialized to be empty.
+ for (unsigned int slot = 0; slot < 21; ++slot) {
+ _saveNames[17 * slot + 0] = 2;
+ _saveNames[17 * slot + 1] = 0;
+ for (int i = 2; i < 17; ++i)
+ _saveNames[17 * slot + i] = 1; // initialize with 1'sdrea
+ }
+
+ 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;
+
+ int slotNum = atoi(file.c_str() + file.size() - 2);
+ SaveStateDescriptor sd(slotNum, name);
+ saveList.push_back(sd);
+ if (slotNum < 21)
+ Common::strlcpy(&_saveNames[17 * slotNum + 1], name, 16); // the first character is unused
}
+
+ // FIXME: Can the following be safely removed?
+// al = saveList.size() <= 7 ? (uint8)saveList.size() : 7;
+
+ return saveList.size();
}
+void DreamWebEngine::loadOld() {
+ commandOnlyCond(48, 252);
+
+ if (!(_mouseButton & 1))
+ return;
+
+ doLoad(-1);
+
+ if (_getBack == 4 || _quitRequested)
+ return;
+
+ showDecisions();
+ workToScreenM();
+ _getBack = 0;
+}
+
+void DreamWebEngine::showDecisions() {
+ createPanel2();
+ showOpBox();
+ showFrame(_saveGraphics, kOpsx + 17, kOpsy + 13, 6, 0);
+ underTextLine();
+}
+
+void DreamWebEngine::loadSaveBox() {
+ loadGraphicsFile(_saveGraphics, "G08");
+}
+
+// show savegame names (original interface), and set kCursorpos
+void DreamWebEngine::showNames() {
+ unsigned int offset = 7 * _saveLoadPage;
+ for (int slot = 0; slot < 7; ++slot) {
+ // The first character of the savegame name is unused
+ Common::String name(&_saveNames[17 * (slot + offset) + 1]);
+
+ if (slot != _currentSlot) {
+ printDirect((const uint8 *)name.c_str(), kOpsx + 21, kOpsy + 10*slot + 10, 200, false);
+ continue;
+ }
+ if (_loadingOrSave != 2) {
+ _charShift = 91;
+ printDirect((const uint8 *)name.c_str(), kOpsx + 21, kOpsy + 10*slot + 10, 200, false);
+ _charShift = 0;
+ continue;
+ }
+
+ int pos = name.size();
+ _cursorPos = pos;
+ name += '/'; // cursor character
+ printDirect((const uint8 *)name.c_str(), kOpsx + 21, kOpsy + 10*slot + 10, 200, false);
+ }
+}
+
+void DreamWebEngine::checkInput() {
+ if (_loadingOrSave == 3)
+ return;
+
+ readKey();
+
+ unsigned int slot = _currentSlot + 7 * _saveLoadPage;
+
+ // The first character of the savegame name is unused
+ char *name = &_saveNames[17*slot + 1];
+
+ if (_currentKey == 0) {
+ return;
+ } else if (_currentKey == 13) {
+ _loadingOrSave = 3;
+ } else if (_currentKey == 8) {
+ if (_cursorPos == 0)
+ return;
+
+ --_cursorPos;
+ name[_cursorPos] = 0;
+ name[_cursorPos+1] = 1;
+ } else {
+ if (_cursorPos == 14)
+ return;
+
+ name[_cursorPos] = _currentKey;
+ name[_cursorPos+1] = 0;
+ name[_cursorPos+2] = 1;
+ ++_cursorPos;
+ }
+
+ showOpBox();
+ showNames();
+ showSlots();
+ showSaveOps();
+ workToScreenM();
+}
+
+void DreamWebEngine::selectSaveLoadPage() {
+ commandOnlyCond(31, 254);
+
+ if (_mouseButton != 1 || _mouseButton == _oldButton)
+ return;
+ uint saveLoadPage = (_mouseX - (kOpsx + 158)) / 18;
+ if (saveLoadPage != _saveLoadPage) {
+ _saveLoadPage = saveLoadPage;
+ // This will also make the first slot the selected one, based
+ // on the mouse Y position. I can't decide if this is a feature
+ // or not.
+ selectSlot();
+ }
+}
+
+void DreamWebEngine::selectSlot() {
+ commandOnlyCond(45, 244);
+
+ if (_mouseButton != 1 || _mouseButton == _oldButton)
+ return; // noselslot
+ if (_loadingOrSave == 3)
+ _loadingOrSave--;
+
+ oldToNames();
+ int y = _mouseY - (kOpsy + 4);
+ if (y < 11)
+ _currentSlot = 0;
+ else
+ _currentSlot = y / 11;
+
+ delPointer();
+ showOpBox();
+ showSlots();
+ showNames();
+ if (_loadingOrSave == 1)
+ showLoadOps();
+ else
+ showSaveOps();
+ readMouse();
+ showPointer();
+ workToScreen();
+ delPointer();
+}
+
+void DreamWebEngine::showSlots() {
+ showFrame(_icons1, kOpsx + 158, kOpsy - 11, 12, 0);
+ showFrame(_icons1, kOpsx + 158 + 18 * _saveLoadPage, kOpsy - 11, 13 + _saveLoadPage, 0);
+ showFrame(_saveGraphics, kOpsx + 7, kOpsy + 8, 2, 0);
+
+ uint16 y = kOpsy + 11;
+
+ for (int slot = 0; slot < 7; slot++) {
+ if (slot == _currentSlot)
+ showFrame(_saveGraphics, kOpsx + 10, y, 3, 0);
+
+ y += 10;
+ }
+}
+
+void DreamWebEngine::showOpBox() {
+ showFrame(_saveGraphics, kOpsx, kOpsy, 0, 0);
+
+ // This call displays half of the ops dialog in the CD version. It's not
+ // in the floppy version, and if it's called, a stray red dot is shown in
+ // the game dialogs.
+ if (isCD())
+ showFrame(_saveGraphics, kOpsx, kOpsy + 55, 4, 0);
+}
+
+void DreamWebEngine::showLoadOps() {
+ showFrame(_saveGraphics, kOpsx + 128 + 4, kOpsy + 12, 1, 0);
+ showFrame(_saveGraphics, kOpsx + 176 + 2, kOpsy + 60 - 4, 5, 0);
+ printMessage(kOpsx + 104, kOpsy + 14, 55, 101, (101 & 1));
+}
+
+void DreamWebEngine::showSaveOps() {
+ showFrame(_saveGraphics, kOpsx + 128 + 4, kOpsy + 12, 1, 0);
+ showFrame(_saveGraphics, kOpsx + 176 + 2, kOpsy + 60 - 4, 5, 0);
+ printMessage(kOpsx + 104, kOpsy + 14, 54, 101, (101 & 1));
+}
-} /*namespace dreamgen */
+} // End of namespace DreamWeb
diff --git a/engines/dreamweb/sound.cpp b/engines/dreamweb/sound.cpp
new file mode 100644
index 0000000000..b51527a8cd
--- /dev/null
+++ b/engines/dreamweb/sound.cpp
@@ -0,0 +1,274 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "dreamweb/dreamweb.h"
+
+#include "audio/mixer.h"
+#include "audio/decoders/raw.h"
+
+#include "common/config-manager.h"
+
+namespace DreamWeb {
+
+bool DreamWebEngine::loadSpeech(byte type1, int idx1, byte type2, int idx2) {
+ cancelCh1();
+
+ Common::String name = Common::String::format("%c%02d%c%04d.RAW", type1, idx1, type2, idx2);
+ //debug("name = %s", name.c_str());
+ bool result = loadSpeech(name);
+
+ _speechLoaded = result;
+ return result;
+}
+
+
+void DreamWebEngine::volumeAdjust() {
+ if (_volumeDirection == 0)
+ return;
+ if (_volume != _volumeTo) {
+ _volumeCount += 64;
+ // Only modify the volume every 256/64 = 4th time around
+ if (_volumeCount == 0)
+ _volume += _volumeDirection;
+ } else {
+ _volumeDirection = 0;
+ }
+}
+
+void DreamWebEngine::playChannel0(uint8 index, uint8 repeat) {
+ _channel0Playing = index;
+ if (index >= 12)
+ index -= 12;
+
+ _channel0Repeat = repeat;
+}
+
+void DreamWebEngine::playChannel1(uint8 index) {
+ if (_channel1Playing == 7)
+ return;
+
+ _channel1Playing = index;
+ if (index >= 12)
+ index -= 12;
+}
+
+void DreamWebEngine::cancelCh0() {
+ _channel0Repeat = 0;
+ _channel0Playing = 255;
+ stopSound(0);
+}
+
+void DreamWebEngine::cancelCh1() {
+ _channel1Playing = 255;
+ stopSound(1);
+}
+
+void DreamWebEngine::loadRoomsSample() {
+ uint8 sample = _roomsSample;
+
+ if (sample == 255 || _currentSample == sample)
+ return; // loaded already
+
+ assert(sample < 100);
+ Common::String sampleSuffix = Common::String::format("V%02d", sample);
+ _currentSample = sample;
+
+ uint8 ch0 = _channel0Playing;
+ if (ch0 >= 12 && ch0 != 255)
+ cancelCh0();
+ uint8 ch1 = _channel1Playing;
+ if (ch1 >= 12)
+ cancelCh1();
+ loadSounds(1, sampleSuffix.c_str());
+}
+
+} // End of namespace DreamWeb
+
+
+namespace DreamWeb {
+
+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());
+ if (!buffer)
+ error("out of memory: cannot allocate memory for sound(%u bytes)", _speechData.size());
+ memcpy(buffer, _speechData.begin(), _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);
+}
+
+void DreamWebEngine::stopSound(uint8 channel) {
+ debug(1, "stopSound(%u)", channel);
+ assert(channel == 0 || channel == 1);
+ _mixer->stopHandle(_channelHandle[channel]);
+ if (channel == 0)
+ _channel0 = 0;
+ else
+ _channel1 = 0;
+}
+
+bool DreamWebEngine::loadSpeech(const Common::String &filename) {
+ if (!hasSpeech())
+ 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() {
+ _subtitles = ConfMan.getBool("subtitles");
+ volumeAdjust();
+
+ uint volume = _volume;
+ //.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 = _channel0Playing;
+ if (ch0 == 255)
+ ch0 = 0;
+ uint8 ch1 = _channel1Playing;
+ if (ch1 == 255)
+ ch1 = 0;
+ uint8 ch0loop = _channel0Repeat;
+
+ 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])) {
+ _channel0Playing = 255;
+ _channel0 = 0;
+ }
+ if (!_mixer->isSoundHandleActive(_channelHandle[1])) {
+ _channel1Playing = 255;
+ _channel1 = 0;
+ }
+
+}
+
+void DreamWebEngine::loadSounds(uint bank, const Common::String &suffix) {
+ Common::String filename = getDatafilePrefix() + suffix;
+ 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();
+}
+
+} // End of namespace DreamWeb
diff --git a/engines/dreamweb/sprite.cpp b/engines/dreamweb/sprite.cpp
index 3b67bfbd72..3df324abe1 100644
--- a/engines/dreamweb/sprite.cpp
+++ b/engines/dreamweb/sprite.cpp
@@ -22,215 +22,184 @@
#include "dreamweb/dreamweb.h"
-namespace DreamGen {
+namespace DreamWeb {
-Sprite *DreamGenContext::spritetable() {
- Sprite *sprite = (Sprite *)segRef(data.word(kBuffers)).ptr(kSpritetable, 16 * sizeof(Sprite));
- return sprite;
-}
-
-void DreamGenContext::printsprites() {
+void DreamWebEngine::printSprites() {
for (size_t priority = 0; priority < 7; ++priority) {
- Sprite *sprites = spritetable();
- for (size_t j = 0; j < 16; ++j) {
- const Sprite &sprite = sprites[j];
- if (sprite.updateCallback() == 0x0ffff)
- continue;
+ Common::List<Sprite>::const_iterator i;
+ for (i = _spriteTable.begin(); i != _spriteTable.end(); ++i) {
+ const Sprite &sprite = *i;
if (priority != sprite.priority)
continue;
if (sprite.hidden == 1)
continue;
- printasprite(&sprite);
+ printASprite(&sprite);
}
}
}
-void DreamGenContext::printasprite(const Sprite *sprite) {
+void DreamWebEngine::printASprite(const Sprite *sprite) {
uint16 x, y;
if (sprite->y >= 220) {
- y = data.word(kMapady) - (256 - sprite->y);
+ y = _mapAdY - (256 - sprite->y);
} else {
- y = sprite->y + data.word(kMapady);
+ y = sprite->y + _mapAdY;
}
if (sprite->x >= 220) {
- x = data.word(kMapadx) - (256 - sprite->x);
+ x = _mapAdX - (256 - sprite->x);
} else {
- x = sprite->x + data.word(kMapadx);
+ x = sprite->x + _mapAdX;
}
uint8 c;
- if (sprite->b29 != 0)
+ if (sprite->walkFrame != 0)
c = 8;
else
c = 0;
- showframe((const Frame *)segRef(sprite->frameData()).ptr(0, 0), x, y, sprite->b15, c);
+ showFrame(*sprite->_frameData, x, y, sprite->frameNumber, c);
}
-void DreamGenContext::clearsprites() {
- memset(spritetable(), 0xff, sizeof(Sprite) * 16);
+void DreamWebEngine::clearSprites() {
+ _spriteTable.clear();
}
-Sprite *DreamGenContext::makesprite(uint8 x, uint8 y, uint16 updateCallback, uint16 frameData, uint16 somethingInDi) {
- Sprite *sprite = spritetable();
- while (sprite->b15 != 0xff) { // NB: No boundchecking in the original code either
- ++sprite;
- }
+Sprite *DreamWebEngine::makeSprite(uint8 x, uint8 y, bool mainManCallback, const GraphicsFile *frameData) {
+ // Note: the original didn't append sprites here, but filled up the
+ // first unused entry. This can change the order of entries, but since they
+ // are drawn based on the priority field, this shouldn't matter.
+ _spriteTable.push_back(Sprite());
+ Sprite *sprite = &_spriteTable.back();
- sprite->setUpdateCallback(updateCallback);
+ memset(sprite, 0xff, sizeof(Sprite));
+
+ sprite->_mainManCallback = mainManCallback;
sprite->x = x;
sprite->y = y;
- sprite->setFrameData(frameData);
- WRITE_LE_UINT16(&sprite->w8, somethingInDi);
- sprite->w2 = 0xffff;
- sprite->b15 = 0;
+ sprite->_frameData = frameData;
+ sprite->frameNumber = 0;
sprite->delay = 0;
+ sprite->_objData = 0;
return sprite;
}
-void DreamGenContext::spriteupdate() {
- Sprite *sprites = spritetable();
- sprites[0].hidden = data.byte(kRyanon);
-
- Sprite *sprite = sprites;
- for (size_t i=0; i < 16; ++i) {
- uint16 updateCallback = sprite->updateCallback();
- if (updateCallback != 0xffff) {
- sprite->w24 = sprite->w2;
- if (updateCallback == addr_mainman) // NB : Let's consider the callback as an enum while more code is not ported to C++
- mainman(sprite);
- else {
- assert(updateCallback == addr_backobject);
- backobject(sprite);
- }
+void DreamWebEngine::spriteUpdate() {
+ // During the intro the sprite table can be empty
+ if (!_spriteTable.empty())
+ _spriteTable.front().hidden = _vars._ryanOn;
+
+ Common::List<Sprite>::iterator i;
+ for (i = _spriteTable.begin(); i != _spriteTable.end(); ++i) {
+ Sprite &sprite = *i;
+ if (sprite._mainManCallback)
+ mainMan(&sprite);
+ else {
+ backObject(&sprite);
}
- if (data.byte(kNowinnewroom) == 1)
+ if (_nowInNewRoom == 1)
break;
- ++sprite;
}
}
-void DreamGenContext::initman() {
- Sprite *sprite = makesprite(data.byte(kRyanx), data.byte(kRyany), addr_mainman, data.word(kMainsprites), 0);
+void DreamWebEngine::initMan() {
+ Sprite *sprite = makeSprite(_ryanX, _ryanY, true, &_mainSprites);
sprite->priority = 4;
- sprite->b22 = 0;
- sprite->b29 = 0;
-}
-
-void DreamGenContext::mainman() {
- assert(false);
+ sprite->speed = 0;
+ sprite->walkFrame = 0;
}
-void DreamGenContext::mainman(Sprite *sprite) {
- push(es);
- push(ds);
-
- // Recover es:bx from sprite
- es = data.word(kBuffers);
- bx = kSpritetable;
- Sprite *sprites = (Sprite *)es.ptr(bx, sizeof(Sprite) * 16);
- bx += 32 * (sprite - sprites);
- //
-
- if (data.byte(kResetmanxy) == 1) {
- data.byte(kResetmanxy) = 0;
- sprite->x = data.byte(kRyanx);
- sprite->y = data.byte(kRyany);
- sprite->b29 = 0;
+void DreamWebEngine::mainMan(Sprite *sprite) {
+ if (_resetManXY == 1) {
+ _resetManXY = 0;
+ sprite->x = _ryanX;
+ sprite->y = _ryanY;
+ sprite->walkFrame = 0;
}
- --sprite->b22;
- if (sprite->b22 != 0xff) {
- ds = pop();
- es = pop();
+
+ --sprite->speed;
+ if (sprite->speed != 0xff)
return;
- }
- sprite->b22 = 0;
- if (data.byte(kTurntoface) != data.byte(kFacing)) {
- aboutturn(sprite);
+ sprite->speed = 0;
+
+ if (_turnToFace != _facing) {
+ aboutTurn(sprite);
} else {
- if ((data.byte(kTurndirection) != 0) && (data.byte(kLinepointer) == 254)) {
- data.byte(kReasseschanges) = 1;
- if (data.byte(kFacing) == data.byte(kLeavedirection))
- checkforexit();
+ if ((_turnDirection != 0) && (_linePointer == 254)) {
+ _reAssesChanges = 1;
+ if (_facing == _leaveDirection)
+ checkForExit(sprite);
}
- data.byte(kTurndirection) = 0;
- if (data.byte(kLinepointer) == 254) {
- sprite->b29 = 0;
+ _turnDirection = 0;
+ if (_linePointer == 254) {
+ sprite->walkFrame = 0;
} else {
- ++sprite->b29;
- if (sprite->b29 == 11)
- sprite->b29 = 1;
+ ++sprite->walkFrame;
+ if (sprite->walkFrame == 11)
+ sprite->walkFrame = 1;
walking(sprite);
- if (data.byte(kLinepointer) != 254) {
- if ((data.byte(kFacing) & 1) == 0)
+ if (_linePointer != 254) {
+ if ((_facing & 1) == 0)
walking(sprite);
- else if ((sprite->b29 != 2) && (sprite->b29 != 7))
+ else if ((sprite->walkFrame != 2) && (sprite->walkFrame != 7))
walking(sprite);
}
- if (data.byte(kLinepointer) == 254) {
- if (data.byte(kTurntoface) == data.byte(kFacing)) {
- data.byte(kReasseschanges) = 1;
- if (data.byte(kFacing) == data.byte(kLeavedirection))
- checkforexit();
+ if (_linePointer == 254) {
+ if (_turnToFace == _facing) {
+ _reAssesChanges = 1;
+ if (_facing == _leaveDirection)
+ checkForExit(sprite);
}
}
}
}
static const uint8 facelist[] = { 0,60,33,71,11,82,22,93 };
- sprite->b15 = sprite->b29 + facelist[data.byte(kFacing)];
- data.byte(kRyanx) = sprite->x;
- data.byte(kRyany) = sprite->y;
-
- ds = pop();
- es = pop();
+ sprite->frameNumber = sprite->walkFrame + facelist[_facing];
+ _ryanX = sprite->x;
+ _ryanY = sprite->y;
}
-void DreamGenContext::walking(Sprite *sprite) {
+void DreamWebEngine::walking(Sprite *sprite) {
uint8 comp;
- if (data.byte(kLinedirection) != 0) {
- --data.byte(kLinepointer);
+ if (_lineDirection != 0) {
+ --_linePointer;
comp = 200;
} else {
- ++data.byte(kLinepointer);
- comp = data.byte(kLinelength);
+ ++_linePointer;
+ comp = _lineLength;
}
- if (data.byte(kLinepointer) < comp) {
- sprite->x = data.byte(kLinedata + data.byte(kLinepointer) * 2 + 0);
- sprite->y = data.byte(kLinedata + data.byte(kLinepointer) * 2 + 1);
+ if (_linePointer < comp) {
+ sprite->x = (uint8)_lineData[_linePointer].x;
+ sprite->y = (uint8)_lineData[_linePointer].y;
return;
}
- data.byte(kLinepointer) = 254;
- data.byte(kManspath) = data.byte(kDestination);
- if (data.byte(kDestination) == data.byte(kFinaldest)) {
- facerightway();
+ _linePointer = 254;
+ _mansPath = _destination;
+ if (_destination == _finalDest) {
+ faceRightWay();
return;
}
- data.byte(kDestination) = data.byte(kFinaldest);
- push(es);
- push(bx);
- autosetwalk();
- bx = pop();
- es = pop();
+ _destination = _finalDest;
+ autoSetWalk();
}
-void DreamGenContext::aboutturn(Sprite *sprite) {
+void DreamWebEngine::aboutTurn(Sprite *sprite) {
bool incdir = true;
- if (data.byte(kTurndirection) == 1)
+ if (_turnDirection == 1)
incdir = true;
- else if ((int8)data.byte(kTurndirection) == -1)
+ else if ((int8)_turnDirection == -1)
incdir = false;
else {
- if (data.byte(kFacing) < data.byte(kTurntoface)) {
- uint8 delta = data.byte(kTurntoface) - data.byte(kFacing);
+ if (_facing < _turnToFace) {
+ uint8 delta = _turnToFace - _facing;
if (delta >= 4)
incdir = false;
else
incdir = true;
} else {
- uint8 delta = data.byte(kFacing) - data.byte(kTurntoface);
+ uint8 delta = _facing - _turnToFace;
if (delta >= 4)
incdir = true;
else
@@ -239,22 +208,18 @@ void DreamGenContext::aboutturn(Sprite *sprite) {
}
if (incdir) {
- data.byte(kTurndirection) = 1;
- data.byte(kFacing) = (data.byte(kFacing) + 1) & 7;
- sprite->b29 = 0;
+ _turnDirection = 1;
+ _facing = (_facing + 1) & 7;
+ sprite->walkFrame = 0;
} else {
- data.byte(kTurndirection) = (uint8)-1;
- data.byte(kFacing) = (data.byte(kFacing) - 1) & 7;
- sprite->b29 = 0;
+ _turnDirection = (uint8)-1;
+ _facing = (_facing - 1) & 7;
+ sprite->walkFrame = 0;
}
}
-void DreamGenContext::backobject() {
- assert(false);
-}
-
-void DreamGenContext::backobject(Sprite *sprite) {
- SetObject *objData = (SetObject *)segRef(data.word(kSetdat)).ptr(sprite->objData(), 0);
+void DreamWebEngine::backObject(Sprite *sprite) {
+ SetObject *objData = sprite->_objData;
if (sprite->delay != 0) {
--sprite->delay;
@@ -262,646 +227,795 @@ void DreamGenContext::backobject(Sprite *sprite) {
}
sprite->delay = objData->delay;
- if (objData->type == 6)
- widedoor(sprite, objData);
- else if (objData->type == 5)
- random(sprite, objData);
- else if (objData->type == 4)
- lockeddoorway(sprite, objData);
- else if (objData->type == 3)
- liftsprite(sprite, objData);
- else if (objData->type == 2)
+ switch (objData->type) {
+ case 6:
+ wideDoor(sprite, objData);
+ break;
+ case 5:
+ randomSprite(sprite, objData);
+ break;
+ case 4:
+ lockedDoorway(sprite, objData);
+ break;
+ case 3:
+ liftSprite(sprite, objData);
+ break;
+ case 2:
doorway(sprite, objData);
- else if (objData->type == 1)
+ break;
+ case 1:
constant(sprite, objData);
- else
+ break;
+ default:
steady(sprite, objData);
+ break;
+ }
}
-void DreamGenContext::constant(Sprite *sprite, SetObject *objData) {
- ++sprite->frame;
- if (objData->b18[sprite->frame] == 255) {
- sprite->frame = 0;
+void DreamWebEngine::constant(Sprite *sprite, SetObject *objData) {
+ ++sprite->animFrame;
+ if (objData->frames[sprite->animFrame] == 255) {
+ sprite->animFrame = 0;
}
- uint8 b18 = objData->b18[sprite->frame];
- objData->index = b18;
- sprite->b15 = b18;
+ uint8 frame = objData->frames[sprite->animFrame];
+ objData->index = frame;
+ sprite->frameNumber = frame;
}
-void DreamGenContext::random(Sprite *sprite, SetObject *objData) {
- randomnum1();
- uint16 r = ax;
- sprite->b15 = objData->b18[r&7];
+void DreamWebEngine::randomSprite(Sprite *sprite, SetObject *objData) {
+ uint8 r = _rnd.getRandomNumber(7);
+ sprite->frameNumber = objData->frames[r];
}
-void DreamGenContext::doorway(Sprite *sprite, SetObject *objData) {
- data.byte(kDoorcheck1) = (uint8)-24;
- data.byte(kDoorcheck2) = 10;
- data.byte(kDoorcheck3) = (uint8)-30;
- data.byte(kDoorcheck4) = 10;
- dodoor(sprite, objData);
+void DreamWebEngine::doorway(Sprite *sprite, SetObject *objData) {
+ Common::Rect check(-24, -30, 10, 10);
+ doDoor(sprite, objData, check);
}
-void DreamGenContext::widedoor(Sprite *sprite, SetObject *objData) {
- data.byte(kDoorcheck1) = (uint8)-24;
- data.byte(kDoorcheck2) = 24;
- data.byte(kDoorcheck3) = (uint8)-30;
- data.byte(kDoorcheck4) = 24;
- dodoor(sprite, objData);
+void DreamWebEngine::wideDoor(Sprite *sprite, SetObject *objData) {
+ Common::Rect check(-24, -30, 24, 24);
+ doDoor(sprite, objData, check);
}
-void DreamGenContext::dodoor() {
- Sprite *sprite = (Sprite *)es.ptr(bx, sizeof(Sprite));
- SetObject *objData = (SetObject *)ds.ptr(di, 0);
- dodoor(sprite, objData);
-}
+void DreamWebEngine::doDoor(Sprite *sprite, SetObject *objData, Common::Rect check) {
+ int ryanx = _ryanX;
+ int ryany = _ryanY;
+
+ // Automatically opening doors: check if Ryan is in range
+
+ check.translate(sprite->x, sprite->y);
+ bool openDoor = check.contains(ryanx, ryany);
+
+ if (openDoor) {
+
+ if ((_vars._throughDoor == 1) && (sprite->animFrame == 0))
+ sprite->animFrame = 6;
+
+ ++sprite->animFrame;
+ if (sprite->animFrame == 1) { // doorsound2
+ uint8 soundIndex;
+ if (_realLocation == 5) // hoteldoor2
+ soundIndex = 13;
+ else
+ soundIndex = 0;
+ playChannel1(soundIndex);
+ }
+ if (objData->frames[sprite->animFrame] == 255)
+ --sprite->animFrame;
+
+ sprite->frameNumber = objData->index = objData->frames[sprite->animFrame];
+ _vars._throughDoor = 1;
-void DreamGenContext::dodoor(Sprite *sprite, SetObject *objData) {
- uint8 ryanx = data.byte(kRyanx);
- uint8 ryany = data.byte(kRyany);
- if (ryanx < sprite->x) {
- if (ryanx < sprite->x + (int8)data.byte(kDoorcheck1))
- goto shutdoor;
- } else {
- if (ryanx >= sprite->x + data.byte(kDoorcheck2))
- goto shutdoor;
- }
- if (ryany < sprite->y) {
- if (ryany < sprite->y + (int8)data.byte(kDoorcheck3))
- goto shutdoor;
} else {
- if (ryany >= sprite->y + data.byte(kDoorcheck4))
- goto shutdoor;
- }
-//opendoor:
- if ((data.byte(kThroughdoor) == 1) && (sprite->frame == 0))
- sprite->frame = 6;
-
- ++sprite->frame;
- if (sprite->frame == 1) { //doorsound2
- if (data.byte(kReallocation) == 5) //hoteldoor2
- al = 13;
- else
- al = 0;
- playchannel1();
- }
- if (objData->b18[sprite->frame] == 255) {
- --sprite->frame;
- }
- sprite->b15 = objData->index = objData->b18[sprite->frame];
- data.byte(kThroughdoor) = 1;
- return;
-shutdoor:
- if (sprite->frame == 5) { //doorsound1;
- if (data.byte(kReallocation) == 5) //hoteldoor1
- al = 13;
- else
- al = 1;
- playchannel1();
- }
- if (sprite->frame != 0) {
- --sprite->frame;
+ // shut door
+
+ if (sprite->animFrame == 5) { // doorsound1;
+ uint8 soundIndex;
+ if (_realLocation == 5) // hoteldoor1
+ soundIndex = 13;
+ else
+ soundIndex = 1;
+ playChannel1(soundIndex);
+ }
+ if (sprite->animFrame != 0)
+ --sprite->animFrame;
+
+ sprite->frameNumber = objData->index = objData->frames[sprite->animFrame];
+ if (sprite->animFrame == 5) // nearly
+ _vars._throughDoor = 0;
}
- sprite->b15 = objData->index = objData->b18[sprite->frame];
- if (sprite->frame == 5) //nearly
- data.byte(kThroughdoor) = 0;
}
-void DreamGenContext::steady(Sprite *sprite, SetObject *objData) {
- uint8 b18 = objData->b18[0];
- objData->index = b18;
- sprite->b15 = b18;
+void DreamWebEngine::steady(Sprite *sprite, SetObject *objData) {
+ uint8 frame = objData->frames[0];
+ objData->index = frame;
+ sprite->frameNumber = frame;
}
-void DreamGenContext::lockeddoorway(Sprite *sprite, SetObject *objData) {
- if (data.byte(kRyanx) < sprite->x) {
- if (sprite->x - data.byte(kRyanx) > 24)
- goto shutdoor2;
- } else {
- if (data.byte(kRyanx) - sprite->x >= 10)
- goto shutdoor2;
- }
+void DreamWebEngine::lockedDoorway(Sprite *sprite, SetObject *objData) {
+ int ryanx = _ryanX;
+ int ryany = _ryanY;
- if (data.byte(kRyany) < sprite->y) {
- if (sprite->y - data.byte(kRyany) > 30)
- goto shutdoor2;
- } else {
- if (data.byte(kRyany) - sprite->y >= 12)
- goto shutdoor2;
- }
+ Common::Rect check(-24, -30, 10, 12);
+ check.translate(sprite->x, sprite->y);
+ bool openDoor = check.contains(ryanx, ryany);
- if (data.byte(kThroughdoor) != 1) {
- if (data.byte(kLockstatus) == 1)
- goto shutdoor2;
- }
+ if (_vars._throughDoor != 1 && _vars._lockStatus == 1)
+ openDoor = false;
- if (sprite->frame == 1) {
- al = 0;
- playchannel1();
- }
+ if (openDoor) {
- if (sprite->frame == 6) {
- turnpathon(data.byte(kDoorpath));
- }
+ if (sprite->animFrame == 1) {
+ playChannel1(0);
+ }
- if ((data.byte(kThroughdoor) == 1) && (sprite->frame == 0)) {
- sprite->frame = 6;
- }
+ if (sprite->animFrame == 6)
+ turnPathOn(_vars._doorPath);
- ++sprite->frame;
- if (objData->b18[sprite->frame] == 255) {
- --sprite->frame;
- }
+ if (_vars._throughDoor == 1 && sprite->animFrame == 0)
+ sprite->animFrame = 6;
- sprite->b15 = objData->index = objData->b18[sprite->frame];
- if (sprite->frame == 5)
- data.byte(kThroughdoor) = 1;
- return;
+ ++sprite->animFrame;
+ if (objData->frames[sprite->animFrame] == 255)
+ --sprite->animFrame;
-shutdoor2:
- if (sprite->frame == 5) {
- al = 1;
- playchannel1();
- }
+ sprite->frameNumber = objData->index = objData->frames[sprite->animFrame];
+ if (sprite->animFrame == 5)
+ _vars._throughDoor = 1;
- if (sprite->frame != 0) {
- --sprite->frame;
- }
+ } else {
+ // shut door
- data.byte(kThroughdoor) = 0;
- sprite->b15 = objData->index = objData->b18[sprite->frame];
+ if (sprite->animFrame == 5) {
+ playChannel1(1);
+ }
- if (sprite->frame == 0) {
- turnpathoff(data.byte(kDoorpath));
- data.byte(kLockstatus) = 1;
+ if (sprite->animFrame != 0)
+ --sprite->animFrame;
+
+ _vars._throughDoor = 0;
+ sprite->frameNumber = objData->index = objData->frames[sprite->animFrame];
+
+ if (sprite->animFrame == 0) {
+ turnPathOff(_vars._doorPath);
+ _vars._lockStatus = 1;
+ }
}
}
-void DreamGenContext::liftsprite(Sprite *sprite, SetObject *objData) {
- uint8 liftFlag = data.byte(kLiftflag);
+void DreamWebEngine::liftSprite(Sprite *sprite, SetObject *objData) {
+ uint8 liftFlag = _vars._liftFlag;
if (liftFlag == 0) { //liftclosed
- turnpathoff(data.byte(kLiftpath));
+ turnPathOff(_vars._liftPath);
- if (data.byte(kCounttoopen) != 0) {
- _dec(data.byte(kCounttoopen));
- if (data.byte(kCounttoopen) == 0)
- data.byte(kLiftflag) = 3;
+ if (_vars._countToOpen != 0) {
+ _vars._countToOpen--;
+ if (_vars._countToOpen == 0)
+ _vars._liftFlag = 3;
}
- sprite->frame = 0;
- sprite->b15 = objData->index = objData->b18[sprite->frame];
+ sprite->animFrame = 0;
+ sprite->frameNumber = objData->index = objData->frames[sprite->animFrame];
}
else if (liftFlag == 1) { //liftopen
- turnpathon(data.byte(kLiftpath));
+ turnPathOn(_vars._liftPath);
- if (data.byte(kCounttoclose) != 0) {
- _dec(data.byte(kCounttoclose));
- if (data.byte(kCounttoclose) == 0)
- data.byte(kLiftflag) = 2;
+ if (_vars._countToClose != 0) {
+ _vars._countToClose--;
+ if (_vars._countToClose == 0)
+ _vars._liftFlag = 2;
}
- sprite->frame = 12;
- sprite->b15 = objData->index = objData->b18[sprite->frame];
+ sprite->animFrame = 12;
+ sprite->frameNumber = objData->index = objData->frames[sprite->animFrame];
}
else if (liftFlag == 3) { //openlift
- if (sprite->frame == 12) {
- data.byte(kLiftflag) = 1;
+ if (sprite->animFrame == 12) {
+ _vars._liftFlag = 1;
return;
}
- ++sprite->frame;
- if (sprite->frame == 1) {
- al = 2;
- liftnoise();
+ ++sprite->animFrame;
+ if (sprite->animFrame == 1) {
+ liftNoise(2);
}
- sprite->b15 = objData->index = objData->b18[sprite->frame];
+ sprite->frameNumber = objData->index = objData->frames[sprite->animFrame];
} else { //closeLift
assert(liftFlag == 2);
- if (sprite->frame == 0) {
- data.byte(kLiftflag) = 0;
+ if (sprite->animFrame == 0) {
+ _vars._liftFlag = 0;
return;
}
- --sprite->frame;
- if (sprite->frame == 11) {
- al = 3;
- liftnoise();
+ --sprite->animFrame;
+ if (sprite->animFrame == 11) {
+ liftNoise(3);
}
- sprite->b15 = objData->index = objData->b18[sprite->frame];
+ sprite->frameNumber = objData->index = objData->frames[sprite->animFrame];
}
}
-void DreamGenContext::facerightway() {
- PathNode *paths = getroomspaths()->nodes;
- uint8 dir = paths[data.byte(kManspath)].dir;
- data.byte(kTurntoface) = dir;
- data.byte(kLeavedirection) = dir;
+Reel *DreamWebEngine::getReelStart(uint16 reelPointer) {
+ Reel *reel = &_reelList[reelPointer * 8];
+ return reel;
}
-void DreamGenContext::findsource() {
- uint16 currentFrame = data.word(kCurrentframe);
- if (currentFrame < 160) {
- ds = data.word(kReel1);
- data.word(kTakeoff) = 0;
- } else if (currentFrame < 320) {
- ds = data.word(kReel2);
- data.word(kTakeoff) = 160;
+// Locate the reel segment (reel1, reel2, reel3) this frame is stored in,
+// and adjust the frame number relative to this segment.
+const GraphicsFile *DreamWebEngine::findSource(uint16 &frame) {
+ if (frame < 160) {
+ return &_reel1;
+ } else if (frame < 320) {
+ frame -= 160;
+ return &_reel2;
} else {
- ds = data.word(kReel3);
- data.word(kTakeoff) = 320;
+ frame -= 320;
+ return &_reel3;
}
}
-Frame *DreamGenContext::findsourceCPP() {
- push(ds);
- findsource();
- Frame *result = (Frame *)ds.ptr(0, 0);
- ds = pop();
- return result;
+void DreamWebEngine::showReelFrame(Reel *reel) {
+ uint16 x = reel->x + _mapAdX;
+ uint16 y = reel->y + _mapAdY;
+ uint16 frame = reel->frame();
+ const GraphicsFile *base = findSource(frame);
+ showFrame(*base, x, y, frame, 8);
}
-Reel *DreamGenContext::getreelstart() {
- Reel *reel = (Reel *)segRef(data.word(kReels)).ptr(kReellist + data.word(kReelpointer) * sizeof(Reel) * 8, sizeof(Reel));
- return reel;
-}
-
-void DreamGenContext::showreelframe() {
- Reel *reel = (Reel *)es.ptr(si, sizeof(Reel));
- showreelframe(reel);
-}
-
-void DreamGenContext::showreelframe(Reel *reel) {
- uint16 x = reel->x + data.word(kMapadx);
- uint16 y = reel->y + data.word(kMapady);
- data.word(kCurrentframe) = reel->frame();
- Frame *source = findsourceCPP();
- uint16 frame = data.word(kCurrentframe) - data.word(kTakeoff);
- showframe(source, x, y, frame, 8);
+void DreamWebEngine::showGameReel(ReelRoutine *routine) {
+ uint16 reelPointer = routine->reelPointer();
+ if (reelPointer >= 512)
+ return;
+ plotReel(reelPointer);
+ routine->setReelPointer(reelPointer);
}
-void DreamGenContext::showgamereel() {
- showgamereel((ReelRoutine *)es.ptr(bx, sizeof(ReelRoutine)));
+const Frame *DreamWebEngine::getReelFrameAX(uint16 frame) {
+ const GraphicsFile *base = findSource(frame);
+ return &base->_frames[frame];
}
-void DreamGenContext::showgamereel(ReelRoutine *routine) {
- uint16 reelpointer = routine->reelPointer();
- if (reelpointer >= 512)
- return;
- data.word(kReelpointer) = reelpointer;
- plotreel();
- routine->setReelPointer(data.word(kReelpointer));
+void DreamWebEngine::moveMap(uint8 param) {
+ switch (param) {
+ case 32:
+ _mapY -= 20;
+ break;
+ case 16:
+ _mapY -= 10;
+ break;
+ case 8:
+ _mapY += 10;
+ break;
+ case 2:
+ _mapX += 11;
+ break;
+ default:
+ _mapX -= 11;
+ break;
+ }
+ _nowInNewRoom = 1;
}
-const Frame *DreamGenContext::getreelframeax(uint16 frame) {
- data.word(kCurrentframe) = frame;
- Frame *source = findsourceCPP();
- uint16 offset = data.word(kCurrentframe) - data.word(kTakeoff);
- return source + offset;
+void DreamWebEngine::checkOne(uint8 x, uint8 y, uint8 *flag, uint8 *flagEx, uint8 *type, uint8 *flagX, uint8 *flagY) {
+ *flagX = x / 16;
+ *flagY = y / 16;
+ const MapFlag &tileData = _mapFlags[*flagY * 11 + *flagX];
+ *flag = tileData._flag;
+ *flagEx = tileData._flagEx;
+ *type = tileData._type;
}
-void DreamGenContext::showrain() {
- ds = data.word(kMainsprites);
- si = 6*58;
- ax = ds.word(si+2);
- si = ax + 2080;
- Rain *rain = (Rain *)segRef(data.word(kBuffers)).ptr(kRainlist, 0);
- if (rain->x == 255)
+void DreamWebEngine::intro1Text() {
+ if (_introCount != 2 && _introCount != 4 && _introCount != 6)
return;
- while (true) {
- if (rain->x == 255) {
- if (data.word(kCh1blockstocopy) != 0)
- return;
- if ((data.byte(kReallocation) == 2) && (data.byte(kBeenmugged) != 1))
- return;
- if (data.byte(kReallocation) == 55)
- return;
- randomnum1();
- if (al >= 1)
- return;
- if (data.byte(kCh0playing) != 6)
- al = 4;
- else
- al = 7;
- playchannel1();
- return;
- }
- uint16 y = rain->y + data.word(kMapady) + data.word(kMapystart);
- uint16 x = rain->x + data.word(kMapadx) + data.word(kMapxstart);
- uint16 size = rain->size;
- ax = ((uint16)(rain->w3() - rain->b5)) & 511;
- rain->setW3(ax);
- ++rain;
- const uint8 *src = ds.ptr(si, 0) + ax;
- uint8 *dst = workspace() + y * 320 + x;
- for(uint16 i = 0; i < size; ++i) {
- uint8 v = src[i];
- if (v != 0)
- *dst = v;
- dst += 320-1;
- }
- }
-}
-void DreamGenContext::updatepeople() {
- data.word(kListpos) = kPeoplelist;
- memset(segRef(data.word(kBuffers)).ptr(kPeoplelist, 12 * sizeof(People)), 0xff, 12 * sizeof(People));
- ++data.word(kMaintimer);
- es = cs;
- bx = kReelroutines;
- const ReelRoutine *reelRoutine = (const ReelRoutine *)cs.ptr(bx, 0);
- const uint16 *callbacks = (const uint16 *)cs.ptr(kReelcalls, 0);
- while (true) {
- uint8 realLocation = reelRoutine->reallocation;
- if (realLocation == 255)
- return;
- if ((realLocation == data.byte(kReallocation)) &&
- (reelRoutine->mapX == data.byte(kMapx)) &&
- (reelRoutine->mapY == data.byte(kMapy))) {
- uint16 callback = READ_LE_UINT16(callbacks);
- //dw gamer,sparkydrip,eden,edeninbath,sparky,smokebloke
- if (callback == addr_gamer)
- gamer();
- else if (callback == addr_sparkydrip)
- sparkydrip();
- else if (callback == addr_eden)
- eden();
- else if (callback == addr_edeninbath)
- edeninbath();
- else if (callback == addr_sparky)
- sparky();
- else if (callback == addr_smokebloke)
- smokebloke();
- //dw manasleep,drunk,receptionist,malefan,femalefan
- else if (callback == addr_manasleep)
- manasleep();
- else if (callback == addr_drunk)
- drunk();
- else if (callback == addr_receptionist)
- receptionist();
- else if (callback == addr_malefan)
- malefan();
- else if (callback == addr_femalefan)
- femalefan();
- //dw louis,louischair,soldier1,bossman,interviewer
- else if (callback == addr_louis)
- louis();
- else if (callback == addr_louischair)
- louischair();
- else if (callback == addr_soldier1)
- soldier1();
- else if (callback == addr_bossman)
- bossman();
- else if (callback == addr_interviewer)
- interviewer();
- //dw heavy,manasleep2,mansatstill,drinker,bartender
- else if (callback == addr_heavy)
- heavy();
- else if (callback == addr_manasleep2)
- manasleep2();
- else if (callback == addr_mansatstill)
- mansatstill();
- else if (callback == addr_drinker)
- drinker();
- else if (callback == addr_bartender)
- bartender();
- //dw othersmoker,tattooman,attendant,keeper,candles1
- else if (callback == addr_othersmoker)
- othersmoker();
- else if (callback == addr_tattooman)
- tattooman();
- else if (callback == addr_attendant)
- attendant();
- else if (callback == addr_keeper)
- keeper();
- else if (callback == addr_candles1)
- candles1();
- //dw smallcandle,security,copper,poolguard,rockstar
- else if (callback == addr_smallcandle)
- smallcandle();
- else if (callback == addr_security)
- security();
- else if (callback == addr_copper)
- copper();
- else if (callback == addr_poolguard)
- poolguard();
- else if (callback == addr_rockstar)
- rockstar();
- //dw businessman,train,aide,mugger,helicopter
- else if (callback == addr_businessman)
- businessman();
- else if (callback == addr_train)
- train();
- else if (callback == addr_aide)
- aide();
- else if (callback == addr_mugger)
- mugger();
- else if (callback == addr_helicopter)
- helicopter();
- //dw intromagic1,intromusic,intromagic2,candles2,gates
- else if (callback == addr_intromagic1)
- intromagic1();
- else if (callback == addr_intromusic)
- intromusic();
- else if (callback == addr_intromagic2)
- intromagic2();
- else if (callback == addr_candles2)
- candles2();
- else if (callback == addr_gates)
- gates();
- //dw intromagic3,intromonks1,candles,intromonks2
- else if (callback == addr_intromagic3)
- intromagic3();
- else if (callback == addr_intromonks1)
- intromonks1();
- else if (callback == addr_candles)
- candles();
- else if (callback == addr_intromonks2)
- intromonks2();
- //dw handclap,monkandryan,endgameseq,priest,madman
- else if (callback == addr_handclap)
- handclap();
- else if (callback == addr_monkandryan)
- monkandryan();
- else if (callback == addr_endgameseq)
- endgameseq();
- else if (callback == addr_priest)
- priest();
- else if (callback == addr_madman)
- madman();
- //dw madmanstelly,alleybarksound,foghornsound
- else if (callback == addr_madmanstelly)
- madmanstelly();
- else if (callback == addr_alleybarksound)
- alleybarksound();
- else if (callback == addr_foghornsound)
- foghornsound();
- //dw carparkdrip,carparkdrip,carparkdrip,carparkdrip
- else if (callback == addr_carparkdrip)
- carparkdrip();
- else
- assert(false); // Oops I forgot something in the dispatch table
+ if (hasSpeech() && _channel1Playing != 255) {
+ _introCount--;
+ } else {
+ if (_introCount == 2)
+ setupTimedTemp(40, 82, 34, 130, 90, 1);
+ else if (_introCount == 4)
+ setupTimedTemp(41, 82, 34, 130, 90, 1);
+ else if (_introCount == 6)
+ setupTimedTemp(42, 82, 34, 130, 90, 1);
+ }
+}
+
+void DreamWebEngine::intro2Text(uint16 nextReelPointer) {
+ if (nextReelPointer == 5)
+ setupTimedTemp(43, 82, 34, 40, 90, 1);
+ else if (nextReelPointer == 15)
+ setupTimedTemp(44, 82, 34, 40, 90, 1);
+}
+
+void DreamWebEngine::intro3Text(uint16 nextReelPointer) {
+ if (nextReelPointer == 107)
+ setupTimedTemp(45, 82, 36, 56, 100, 1);
+ else if (nextReelPointer == (hasSpeech() ? 108 : 109))
+ setupTimedTemp(46, 82, 36, 56, 100, 1);
+}
+
+void DreamWebEngine::monks2text() {
+ bool isGermanCD = hasSpeech() && getLanguage() == Common::DE_DEU;
+
+ if (_introCount == 1)
+ setupTimedTemp(8, 82, 36, 160, 120, 1);
+ else if (_introCount == (isGermanCD ? 5 : 4))
+ setupTimedTemp(9, 82, 36, 160, 120, 1);
+ else if (_introCount == (isGermanCD ? 9 : 7))
+ setupTimedTemp(10, 82, 36, 160, 120, 1);
+ else if (_introCount == 10 && !isGermanCD) {
+ if (hasSpeech())
+ _introCount = 12;
+ setupTimedTemp(11, 82, 0, 105, 120, 1);
+ } else if (_introCount == 13 && isGermanCD) {
+ _introCount = 14;
+ setupTimedTemp(11, 82, 0, 105, 120, 1);
+ } else if (_introCount == 13 && !isGermanCD) {
+ if (hasSpeech())
+ _introCount = 17;
+ else
+ setupTimedTemp(12, 82, 0, 120, 120, 1);
+ } else if (_introCount == 16 && !isGermanCD)
+ setupTimedTemp(13, 82, 0, 135, 120, 1);
+ else if (_introCount == 19)
+ setupTimedTemp(14, 82, 36, 160, 100, 1);
+ else if (_introCount == (isGermanCD ? 23 : 22))
+ setupTimedTemp(15, 82, 36, 160, 120, 1);
+ else if (_introCount == (isGermanCD ? 27 : 25))
+ setupTimedTemp(16, 82, 36, 160, 120, 1);
+ else if (_introCount == (hasSpeech() ? 27 : 28) && !isGermanCD)
+ setupTimedTemp(17, 82, 36, 160, 120, 1);
+ else if (_introCount == 30 && isGermanCD)
+ setupTimedTemp(17, 82, 36, 160, 120, 1);
+ else if (_introCount == (isGermanCD ? 35 : 31))
+ setupTimedTemp(18, 82, 36, 160, 120, 1);
+}
+
+void DreamWebEngine::textForEnd() {
+ if (_introCount == 20)
+ setupTimedTemp(0, 83, 34, 20, 60, 1);
+ else if (_introCount == (hasSpeech() ? 50 : 65))
+ setupTimedTemp(1, 83, 34, 20, 60, 1);
+ else if (_introCount == (hasSpeech() ? 85 : 110))
+ setupTimedTemp(2, 83, 34, 20, 60, 1);
+}
+
+void DreamWebEngine::textForMonkHelper(uint8 textIndex, uint8 voiceIndex, uint8 x, uint8 y, uint16 countToTimed, uint16 timeCount) {
+ if (hasSpeech() && _channel1Playing != 255)
+ _introCount--;
+ else
+ setupTimedTemp(textIndex, voiceIndex, x, y, countToTimed, timeCount);
+}
+
+void DreamWebEngine::textForMonk() {
+ if (_introCount == 1)
+ textForMonkHelper(19, 82, 68, 154, 120, 1);
+ else if (_introCount == 5)
+ textForMonkHelper(20, 82, 68, 38, 120, 1);
+ else if (_introCount == 9)
+ textForMonkHelper(21, 82, 48, 154, 120, 1);
+ else if (_introCount == 13)
+ textForMonkHelper(22, 82, 68, 38, 120, 1);
+ else if (_introCount == (hasSpeech() ? 15 : 17))
+ textForMonkHelper(23, 82, 68, 154, 120, 1);
+ else if (_introCount == 21)
+ textForMonkHelper(24, 82, 68, 38, 120, 1);
+ else if (_introCount == 25)
+ textForMonkHelper(25, 82, 68, 154, 120, 1);
+ else if (_introCount == 29)
+ textForMonkHelper(26, 82, 68, 38, 120, 1);
+ else if (_introCount == 33)
+ textForMonkHelper(27, 82, 68, 154, 120, 1);
+ else if (_introCount == 37)
+ textForMonkHelper(28, 82, 68, 154, 120, 1);
+ else if (_introCount == 41)
+ textForMonkHelper(29, 82, 68, 38, 120, 1);
+ else if (_introCount == 45)
+ textForMonkHelper(30, 82, 68, 154, 120, 1);
+ else if (_introCount == (hasSpeech() ? 52 : 49))
+ textForMonkHelper(31, 82, 68, 154, 220, 1);
+ else if (_introCount == 53) {
+ fadeScreenDowns();
+ if (hasSpeech()) {
+ _volumeTo = 7;
+ _volumeDirection = 1;
}
- bx += 8;
- ++reelRoutine;
- ++callbacks;
}
}
-void DreamGenContext::madmantext() {
- if (isCD()) {
- if (data.byte(kSpeechcount) >= 63)
- return;
- if (data.byte(kCh1playing) != 255)
- return;
- al = data.byte(kSpeechcount);
- ++data.byte(kSpeechcount);
- } else {
- if (data.byte(kCombatcount) >= 61)
- return;
- al = data.byte(kCombatcount);
- _and(al, 3);
- if (!flags.z())
- return;
- al = data.byte(kCombatcount) / 4;
- }
- setuptimedtemp(47 + al, 82, 72, 80, 90, 1);
+void DreamWebEngine::reelsOnScreen() {
+ reconstruct();
+ updatePeople();
+ watchReel();
+ showRain();
+ useTimedText();
}
-void DreamGenContext::madman() {
- data.word(kWatchingtime) = 2;
- checkspeed();
- if (flags.z()) {
- ax = es.word(bx+3);
- if (ax >= 364) {
- data.byte(kMandead) = 2;
- showgamereel();
+void DreamWebEngine::reconstruct() {
+ if (_haveDoneObs == 0)
+ return;
+ _vars._newObs = 1;
+ drawFloor();
+ spriteUpdate();
+ printSprites();
+ if (_foreignRelease && (_realLocation == 20))
+ underTextLine();
+ _haveDoneObs = 0;
+}
+
+
+
+struct ReelSound {
+ uint8 _sample;
+ uint16 _reelPointer;
+};
+
+static const ReelSound g_roomSound0[] = {
+ { 255,0 }
+};
+
+static const ReelSound g_roomSound1[] = {
+ { 15, 257 },
+ { 255,0 }
+};
+
+static const ReelSound g_roomSound2[] = {
+ { 12, 5 },
+ { 13, 21 },
+ { 15, 35 }, // hitting floor?
+ { 17, 50 },
+ { 18, 103 },
+ { 19, 108 },
+ { 255,0 }
+};
+
+static const ReelSound g_roomSound6[] = {
+ { 18, 19 },
+ { 19, 23 },
+ { 255,0 }
+};
+static const ReelSound g_roomSound8[] = {
+
+ { 12, 51 },
+ { 13, 53 },
+ { 14, 14 },
+ { 15, 20 },
+ { 0, 78 },
+ { 255,0 }
+};
+static const ReelSound g_roomSound9[] = {
+
+ { 12, 119 },
+ { 12, 145 },
+ { 255,0 }
+};
+
+static const ReelSound g_roomSound10[] = {
+ { 13, 16 },
+ { 255,0 }
+};
+
+static const ReelSound g_roomSound11[] = {
+ { 13, 20 },
+ { 255,0 }
+};
+
+static const ReelSound g_roomSound12[] = {
+ { 14, 16 },
+ { 255,0 }
+};
+
+static const ReelSound g_roomSound13[] = {
+ { 15, 4 },
+ { 16, 8 },
+ { 17, 134 },
+ { 18, 153 },
+ { 255,0 }
+};
+
+static const ReelSound g_roomSound14[] = {
+ { 13, 108 },
+ { 15, 326 },
+ { 15, 331 },
+ { 15, 336 },
+ { 15, 342 },
+ { 15, 348 },
+ { 15, 354 },
+ { 18, 159 },
+ { 18, 178 },
+ { 19+128, 217 },
+ { 20+64, 228 },
+ { 255,0 }
+};
+
+static const ReelSound g_roomSound20[] = {
+ { 13, 20 },
+ { 13, 21 },
+ { 15, 34 },
+ { 13, 52 },
+ { 13, 55 },
+ { 25, 57 },
+ { 21, 73 },
+ { 255,0 }
+};
+
+static const ReelSound g_roomSound22[] = {
+ { 13, 196 },
+ { 13, 234 },
+ { 13, 156 },
+ { 14, 129 },
+ { 13, 124 },
+ { 15, 162 },
+ { 15, 200 },
+ { 15, 239 },
+ { 17, 99 },
+ { 12, 52 },
+ { 255,0 }
+};
+
+static const ReelSound g_roomSound23[] = {
+ { 15, 56 },
+ { 16, 64 },
+ { 19, 22 },
+ { 20, 33 },
+ { 255,0 }
+};
+
+static const ReelSound g_roomSound25[] = {
+ { 20, 11 },
+ { 20, 15 },
+ { 15, 28 },
+ { 13, 80 },
+ { 21, 82 },
+ { 19+128, 87 },
+ { 23+64, 128 },
+ { 255,0 }
+};
+
+static const ReelSound g_roomSound26[] = {
+ { 12, 13 },
+ { 14, 39 },
+ { 12, 67 },
+ { 12, 75 },
+ { 12, 83 },
+ { 12, 91 },
+ { 15, 102 }, // was 90, should be mine cart
+ { 255,0 }
+};
+
+static const ReelSound g_roomSound27[] = {
+ { 22, 36 },
+ { 13, 125 },
+ { 18, 88 },
+ { 15, 107 },
+ { 14, 127 },
+ { 14, 154 },
+ { 19+128, 170 },
+ { 23+64, 232 },
+ { 255,0 }
+};
+
+static const ReelSound g_roomSound28[] = {
+ { 21, 16 },
+ { 21, 72 },
+ { 21, 205 },
+ { 22, 63 }, // 65
+ { 23+128, 99 },
+ { 24+64, 158 },
+ { 255,0 }
+};
+
+static const ReelSound g_roomSound29[] = {
+ { 13, 21 },
+ { 14, 24 },
+ { 19+128, 50 },
+ { 23+64, 75 },
+ { 24, 128 },
+ { 255,0 }
+};
+
+static const ReelSound g_roomSound29_German[] = {
+ { 13, 21 },
+ { 14, 24 },
+ { 19+128, 50 },
+ { 23+64, 75 },
+ { 255,0 }
+};
+
+
+static const ReelSound g_roomSound45[] = {
+ { 19+64, 46 },
+ { 16, 167 },
+ { 255,0 }
+};
+
+static const ReelSound g_roomSound46[] = {
+ { 16, 19 },
+ { 14, 36 },
+ { 16, 50 },
+ { 14, 65 },
+ { 16, 81 },
+ { 14, 96 },
+ { 16, 114 },
+ { 14, 129 },
+ { 16, 147 },
+ { 14, 162 },
+ { 16, 177 },
+ { 14, 191 },
+ { 255,0 }
+};
+
+static const ReelSound g_roomSound47[] = {
+ { 13, 48 },
+ { 14, 41 },
+ { 15, 78 },
+ { 16, 92 },
+ { 255,0 }
+};
+
+static const ReelSound g_roomSound52[] = {
+ { 16, 115 },
+ { 255,0 }
+};
+
+static const ReelSound g_roomSound53[] = {
+ { 21, 103 },
+ { 20, 199 },
+ { 255,0 }
+};
+
+static const ReelSound g_roomSound55[] = {
+ { 17, 53 },
+ { 17, 54 },
+ { 17, 55 },
+ { 17, 56 },
+ { 17, 57 },
+ { 17, 58 },
+ { 17, 59 },
+ { 17, 61 },
+ { 17, 63 },
+ { 17, 64 },
+ { 17, 65 },
+ { 255,0 }
+};
+
+static const ReelSound *g_roomByRoom[] = {
+ g_roomSound0,g_roomSound1,g_roomSound2,g_roomSound0,g_roomSound0,
+ g_roomSound0,g_roomSound6,g_roomSound0,g_roomSound8,g_roomSound9,
+ g_roomSound10,g_roomSound11,g_roomSound12,g_roomSound13,g_roomSound14,
+ g_roomSound0,g_roomSound0,g_roomSound0,g_roomSound0,g_roomSound0,
+ g_roomSound20,g_roomSound0,g_roomSound22,g_roomSound23,g_roomSound0,
+ g_roomSound25,g_roomSound26,g_roomSound27,g_roomSound28,g_roomSound29,
+ g_roomSound0,g_roomSound0,g_roomSound0,g_roomSound0,g_roomSound0,
+ g_roomSound0,g_roomSound0,g_roomSound0,g_roomSound0,g_roomSound0,
+ g_roomSound0,g_roomSound0,g_roomSound0,g_roomSound0,g_roomSound0,
+ g_roomSound45,g_roomSound46,g_roomSound47,g_roomSound0,g_roomSound0,
+ g_roomSound0,g_roomSound0,g_roomSound52,g_roomSound53,g_roomSound0,
+ g_roomSound55
+};
+
+
+void DreamWebEngine::soundOnReels(uint16 reelPointer) {
+ const ReelSound *r = g_roomByRoom[_realLocation];
+
+ if (getLanguage() == Common::DE_DEU && r == g_roomSound29)
+ r = g_roomSound29_German;
+
+ for (; r->_sample != 255; ++r) {
+ if (r->_reelPointer != reelPointer)
+ continue;
+ if (r->_reelPointer == _lastSoundReel)
+ continue;
+ _lastSoundReel = r->_reelPointer;
+ if (r->_sample < 64) {
+ playChannel1(r->_sample);
return;
}
- if (ax == 10) {
- push(es);
- push(bx);
- push(ax);
- dx = kIntrotextname;
- loadtemptext();
- ax = pop();
- bx = pop();
- es = pop();
- data.byte(kCombatcount) = (uint8)-1;
- data.byte(kSpeechcount) = 0;
- }
- ++ax;
- if (ax == 294) {
- if (data.byte(kWongame) == 1)
- return;
- data.byte(kWongame) = 1;
- push(es);
- push(bx);
- getridoftemptext();
- bx = pop();
- es = pop();
+ if (r->_sample < 128) {
+ playChannel0(r->_sample & 63, 0);
return;
}
- if (ax == 66) {
- ++data.byte(kCombatcount);
- push(es);
- push(bx);
- madmantext();
- bx = pop();
- es = pop();
- ax = 53;
- if (data.byte(kCombatcount) >= (isCD() ? 64 : 62)) {
- if (data.byte(kCombatcount) == (isCD() ? 70 : 68))
- ax = 310;
- else {
- if (data.byte(kLastweapon) == 8) {
- data.byte(kCombatcount) = isCD() ? 72 : 70;
- data.byte(kLastweapon) = (uint8)-1;
- data.byte(kMadmanflag) = 1;
- ax = 67;
- }
- }
- }
- }
- es.word(bx+3) = ax;
+ playChannel0(r->_sample & 63, 255);
}
- showgamereel();
- es.byte(bx+1) = data.byte(kMapx);
- madmode();
-}
-void DreamGenContext::madmode() {
- data.word(kWatchingtime) = 2;
- data.byte(kPointermode) = 0;
- if (data.byte(kCombatcount) < (isCD() ? 65 : 63))
- return;
- if (data.byte(kCombatcount) >= (isCD() ? 70 : 68))
- return;
- data.byte(kPointermode) = 2;
+ if (_lastSoundReel != reelPointer)
+ _lastSoundReel = (uint16)-1;
}
-void DreamGenContext::movemap(uint8 param) {
- switch (param) {
- case 32:
- data.byte(kMapy) -= 20;
- break;
- case 16:
- data.byte(kMapy) -= 10;
- break;
- case 8:
- data.byte(kMapy) += 10;
- break;
- case 2:
- data.byte(kMapx) += 11;
- break;
- default:
- data.byte(kMapx) -= 11;
- break;
- }
- data.byte(kNowinnewroom) = 1;
-}
+void DreamWebEngine::clearBeforeLoad() {
+ if (_roomLoaded != 1)
+ return; // noclear
-void DreamGenContext::checkone() {
- uint8 flag, flagEx, type, flagX, flagY;
- checkone(cl, ch, &flag, &flagEx, &type, &flagX, &flagY);
+ clearReels();
- cl = flag;
- ch = flagEx;
- dl = flagX;
- dh = flagY;
- al = type;
+ //clearRest
+ memset(_mapData, 0, kLengthOfMap);
+ delete[] _backdropBlocks;
+ _backdropBlocks = 0;
+ _setFrames.clear();
+ delete[] _reelList;
+ _reelList = 0;
+ _personText.clear();
+ _setDesc.clear();
+ _blockDesc.clear();
+ _roomDesc.clear();
+ _freeFrames.clear();
+ _freeDesc.clear();
+
+ _roomLoaded = 0;
}
-void DreamGenContext::checkone(uint8 x, uint8 y, uint8 *flag, uint8 *flagEx, uint8 *type, uint8 *flagX, uint8 *flagY) {
- *flagX = x / 16;
- *flagY = y / 16;
- const uint8 *tileData = segRef(data.word(kBuffers)).ptr(kMapflags + (*flagY * 11 + *flagX) * 3, 3);
- *flag = tileData[0];
- *flagEx = tileData[1];
- *type = tileData[2];
+void DreamWebEngine::clearReels() {
+ _reel1.clear();
+ _reel2.clear();
+ _reel3.clear();
}
-void DreamGenContext::getblockofpixel() {
- al = getblockofpixel(cl, ch);
+void DreamWebEngine::getRidOfReels() {
+ if (_roomLoaded)
+ clearReels();
}
-uint8 DreamGenContext::getblockofpixel(uint8 x, uint8 y) {
- uint8 flag, flagEx, type, flagX, flagY;
- checkone(x + data.word(kMapxstart), y + data.word(kMapystart), &flag, &flagEx, &type, &flagX, &flagY);
- if (flag & 1)
- return 0;
+void DreamWebEngine::liftNoise(uint8 index) {
+ if (_realLocation == 5 || _realLocation == 21)
+ playChannel1(13); // hiss noise
else
- return type;
+ playChannel1(index);
}
-void DreamGenContext::addtopeoplelist() {
- addtopeoplelist((ReelRoutine *)es.ptr(bx, sizeof(ReelRoutine)));
-}
+void DreamWebEngine::checkForExit(Sprite *sprite) {
+ uint8 flag, flagEx, type, flagX, flagY;
+ checkOne(_ryanX + 12, _ryanY + 12, &flag, &flagEx, &type, &flagX, &flagY);
+ _lastFlag = flag;
+
+ if (flag & 64) {
+ _autoLocation = flagEx;
+ return;
+ }
-void DreamGenContext::addtopeoplelist(ReelRoutine *routine) {
- uint16 routinePointer = (const uint8 *)routine - cs.ptr(0, 0);
+ if (!(flag & 32)) {
+ if (flag & 4) {
+ // adjust left
+ _lastFlag = 0;
+ _mapX -= 11;
+ sprite->x = 16 * flagEx;
+ _nowInNewRoom = 1;
+ } else if (flag & 2) {
+ // adjust right
+ _mapX += 11;
+ sprite->x = 16 * flagEx - 2;
+ _nowInNewRoom = 1;
+ } else if (flag & 8) {
+ // adjust down
+ _mapY += 10;
+ sprite->y = 16 * flagEx;
+ _nowInNewRoom = 1;
+ } else if (flag & 16) {
+ // adjust up
+ _mapY -= 10;
+ sprite->y = 16 * flagEx;
+ _nowInNewRoom = 1;
+ }
+
+ return;
+ }
+
+ if (_realLocation == 2) {
+ // Can't leave Louis' until you found shoes
+
+ int shoeCount = 0;
+ if (isRyanHolding("WETA")) shoeCount++;
+ if (isRyanHolding("WETB")) shoeCount++;
+
+ if (shoeCount < 2) {
+ uint8 text = shoeCount ? 43 : 42;
+ setupTimedUse(text, 80, 10, 68, 64);
+
+ _turnToFace = (_facing + 4) & 7;
+ return;
+ }
+
+ }
- People *people = (People *)segRef(data.word(kBuffers)).ptr(data.word(kListpos), sizeof(People));
- people->setReelPointer(routine->reelPointer());
- people->setRoutinePointer(routinePointer);
- people->b4 = routine->b7;
- data.word(kListpos) += sizeof(People);
+ _vars._needToTravel = 1;
}
-} /*namespace dreamgen */
+} // End of namespace DreamWeb
diff --git a/engines/dreamweb/structs.h b/engines/dreamweb/structs.h
index 0d7bbb6cbf..24b67e317a 100644
--- a/engines/dreamweb/structs.h
+++ b/engines/dreamweb/structs.h
@@ -20,36 +20,29 @@
*
*/
+#ifndef DREAMWEB_STRUCTS_H
+#define DREAMWEB_STRUCTS_H
+
#include "common/endian.h"
+#include "common/rect.h"
+
+namespace DreamWeb {
+
+struct GraphicsFile;
+struct SetObject;
struct Sprite {
- uint16 _updateCallback;
- uint16 updateCallback() const { return READ_LE_UINT16(&_updateCallback); }
- void setUpdateCallback(uint16 v) { WRITE_LE_UINT16(&_updateCallback, v); }
- uint16 w2;
- uint16 w4;
- uint16 _frameData;
- uint16 frameData() const { return READ_LE_UINT16(&_frameData); }
- void setFrameData(uint16 v) { WRITE_LE_UINT16(&_frameData, v); }
- uint16 w8;
+ bool _mainManCallback;
+ const GraphicsFile *_frameData;
uint8 x;
uint8 y;
- uint16 w12;
- uint8 b14;
- uint8 b15;
- uint8 b16;
- uint8 b17;
+ uint8 frameNumber;
uint8 delay;
- uint8 frame;
- uint16 _objData;
- uint16 objData() const { return READ_LE_UINT16(&_objData); }
- void setObjData(uint16 v) { WRITE_LE_UINT16(&_objData, v); }
- uint8 b22;
+ uint8 animFrame; // index into SetObject::frames
+ SetObject *_objData;
+ uint8 speed;
uint8 priority;
- uint16 w24;
- uint16 w26;
- uint8 b28;
- uint8 b29;
+ uint8 walkFrame;
uint8 type;
uint8 hidden;
};
@@ -57,25 +50,23 @@ struct Sprite {
struct RectWithCallback {
uint16 _xMin, _xMax;
uint16 _yMin, _yMax;
- uint16 _callback;
-
- uint16 xMin() const { return READ_LE_UINT16(&_xMin); }
- uint16 xMax() const { return READ_LE_UINT16(&_xMax); }
- uint16 yMin() const { return READ_LE_UINT16(&_yMin); }
- uint16 yMax() const { return READ_LE_UINT16(&_yMax); }
- uint16 callback() const { return READ_LE_UINT16(&_callback); }
+ void (DreamWebEngine::*_callback)();
bool contains(uint16 x, uint16 y) const {
- return (x >= xMin()) && (x < xMax()) && (y >= yMin()) && (y < yMax());
+ return (x >= _xMin) && (x < _xMax) && (y >= _yMin) && (y < _yMax);
}
};
+
+
+#include "common/pack-start.h" // START STRUCT PACKING
+
struct SetObject {
uint8 b0;
uint8 b1;
uint8 b2;
- uint8 b3;
- uint8 b4;
+ uint8 slotSize;
+ uint8 slotCount;
uint8 priority;
uint8 b6;
uint8 delay;
@@ -83,10 +74,11 @@ struct SetObject {
uint8 b9;
uint8 b10;
uint8 b11;
- uint8 name[4];
+ uint8 objId[4];
uint8 b16;
uint8 index;
- uint8 b18[13]; // NB: Don't know the size yet
+ uint8 frames[13]; // Table mapping animFrame to sprite frame number
+ // NB: Don't know the size yet
uint8 b31;
uint8 b32;
uint8 b33;
@@ -116,19 +108,19 @@ struct SetObject {
uint8 b57;
uint8 mapad[5];
uint8 b63;
-};
+} PACKED_STRUCT;
struct DynObject {
uint8 currentLocation;
uint8 index;
uint8 mapad[5];
- uint8 b7;
- uint8 b8;
- uint8 b9;
- uint8 b10;
+ uint8 slotSize; // the size of an object's slots
+ uint8 slotCount; // the number of slots of an object
+ uint8 objectSize; // the size of an object
+ uint8 turnedOn;
uint8 initialLocation;
- uint8 id[4];
-};
+ uint8 objId[4];
+} PACKED_STRUCT;
struct ObjPos {
uint8 xMin;
@@ -136,7 +128,10 @@ struct ObjPos {
uint8 xMax;
uint8 yMax;
uint8 index;
-};
+ bool contains(uint8 x, uint8 y) const {
+ return (x >= xMin) && (x < xMax) && (y >= yMin) && (y < yMax);
+ }
+} PACKED_STRUCT;
struct Frame {
uint8 width;
@@ -146,7 +141,7 @@ struct Frame {
void setPtr(uint16 v) { WRITE_LE_UINT16(&_ptr, v); }
uint8 x;
uint8 y;
-};
+} PACKED_STRUCT;
struct Reel {
uint8 frame_lo;
@@ -156,39 +151,37 @@ struct Reel {
uint8 x;
uint8 y;
uint8 b4;
-};
+} PACKED_STRUCT;
+
+#include "common/pack-end.h" // END STRUCT PACKING
+
+
struct ReelRoutine {
uint8 reallocation;
uint8 mapX;
uint8 mapY;
- uint8 b3;
- uint8 b4;
- uint16 reelPointer() const { return READ_LE_UINT16(&b3); }
- void setReelPointer(uint16 v) { WRITE_LE_UINT16(&b3, v); }
- uint8 b5;
- uint8 b6;
+ uint16 _reelPointer;
+ uint16 reelPointer() const { return _reelPointer; }
+ void setReelPointer(uint16 v) { _reelPointer = v; }
+ void incReelPointer() { _reelPointer++; }
+ uint8 period;
+ uint8 counter;
uint8 b7;
};
struct People {
- uint8 b0;
- uint8 b1;
- uint16 reelPointer() const { return READ_LE_UINT16(&b0); }
- void setReelPointer(uint16 v) { WRITE_LE_UINT16(&b0, v); }
- uint8 b2;
- uint8 b3;
- uint16 routinePointer() const { return READ_LE_UINT16(&b2); }
- void setRoutinePointer(uint16 v) { WRITE_LE_UINT16(&b2, v); }
+ uint16 _reelPointer;
+ ReelRoutine *_routinePointer;
uint8 b4;
-
};
+
+
+#include "common/pack-start.h" // START STRUCT PACKING
+
struct Room {
- uint8 name[10];
- uint8 b10;
- uint8 b11;
- uint8 b12;
+ char name[13];
uint8 roomsSample;
uint8 b14;
uint8 mapX;
@@ -198,7 +191,7 @@ struct Room {
uint8 b19;
uint8 liftFlag;
uint8 b21;
- uint8 b22;
+ uint8 facing;
uint8 countToOpen;
uint8 liftPath;
uint8 doorPath;
@@ -207,45 +200,239 @@ struct Room {
uint8 b28;
uint8 b29;
uint8 b30;
- uint8 b31;
-};
+ uint8 realLocation;
+} PACKED_STRUCT;
+
+extern const Room g_roomData[];
struct Rain {
uint8 x;
uint8 y;
uint8 size;
- uint8 w3_lo;
- uint8 w3_hi;
- uint16 w3() const { return READ_LE_UINT16(&w3_lo); }
- void setW3(uint16 v) { WRITE_LE_UINT16(&w3_lo, v); }
+ uint16 w3;
uint8 b5;
-};
+} PACKED_STRUCT;
struct Change {
uint8 index;
uint8 location;
uint8 value;
uint8 type;
-};
+} PACKED_STRUCT;
struct PathNode {
uint8 x;
uint8 y;
- uint8 b2;
- uint8 b3;
- uint8 b4;
- uint8 b5;
+ uint8 x1;
+ uint8 y1;
+ uint8 x2;
+ uint8 y2;
uint8 on;
uint8 dir;
-};
+} PACKED_STRUCT;
struct PathSegment {
uint8 b0;
uint8 b1;
-};
+} PACKED_STRUCT;
struct RoomPaths {
PathNode nodes[12];
PathSegment segments[24];
+} PACKED_STRUCT;
+
+struct FileHeader {
+ char _desc[50];
+ uint16 _len[20];
+ uint8 _padding[6];
+
+ uint16 len(unsigned int i) const {
+ assert(i < 20);
+ return READ_LE_UINT16(&_len[i]);
+ }
+ void setLen(unsigned int i, uint16 length) {
+ assert(i < 20);
+ WRITE_LE_UINT16(&_len[i], length);
+ }
+} PACKED_STRUCT;
+
+struct Atmosphere {
+ uint8 _location;
+ uint8 _mapX;
+ uint8 _mapY;
+ uint8 _sound;
+ uint8 _repeat;
+} PACKED_STRUCT;
+
+#include "common/pack-end.h" // END STRUCT PACKING
+
+
+
+enum ObjectTypes {
+ kSetObjectType1 = 1,
+ kFreeObjectType = 2,
+ kSetObjectType3 = 3,
+ kExObjectType = 4
+};
+
+struct ObjectRef {
+ uint8 _index;
+ uint8 _type; // enum ObjectTypes
+
+ bool operator==(const ObjectRef &r) const {
+ return _index == r._index && _type == r._type;
+ }
+ bool operator!=(const ObjectRef &r) const {
+ return _index != r._index || _type != r._type;
+ }
};
+
+
+#include "common/pack-start.h" // START STRUCT PACKING
+
+struct BackdropMapFlag {
+ uint8 _flag;
+ uint8 _flagEx;
+} PACKED_STRUCT;
+
+struct MapFlag {
+ uint8 _flag;
+ uint8 _flagEx;
+ uint8 _type;
+} PACKED_STRUCT;
+
+#include "common/pack-end.h" // END STRUCT PACKING
+
+
+
+
+
+struct TextFile {
+ TextFile(unsigned int size = 66) : _size(size), _text(0) { _offsetsLE = new uint16[_size]; }
+
+ ~TextFile() {
+ delete[] _offsetsLE;
+ _offsetsLE = 0;
+ _size = 0;
+ clear();
+ }
+
+ uint16 *_offsetsLE;
+ unsigned int _size;
+ char *_text;
+
+ const char *getString(unsigned int i) const {
+ assert(i < _size);
+ return _text + getOffset(i);
+ }
+ void setOffset(unsigned int i, uint16 offset) {
+ WRITE_LE_UINT16(&_offsetsLE[i], offset);
+ }
+ uint16 getOffset(unsigned int i) const {
+ return READ_LE_UINT16(&_offsetsLE[i]);
+ }
+ void clear() {
+ delete[] _text;
+ _text = 0;
+ }
+};
+
+struct GraphicsFile {
+ GraphicsFile() : _data(0), _frames(0) { }
+
+ Frame *_frames;
+ uint8 *_data;
+
+ const uint8 *getFrameData(unsigned int i) const {
+ // There is 2080 bytes of Frame data, but that is between 346 and 347
+ // frames
+ assert(i < 346);
+ return _data + _frames[i].ptr();
+ }
+ void clear() {
+ delete[] _frames;
+ _frames = 0;
+ delete[] _data;
+ _data = 0;
+ }
+};
+
+struct GameVars {
+ uint8 _startVars;
+ uint8 _progressPoints;
+ uint8 _watchOn;
+ uint8 _shadesOn;
+ uint8 _secondCount;
+ uint8 _minuteCount;
+ uint8 _hourCount;
+ uint8 _zoomOn;
+ uint8 _location;
+ uint8 _exPos;
+ uint16 _exFramePos;
+ uint16 _exTextPos;
+ uint16 _card1Money;
+ uint16 _listPos;
+ uint8 _ryanPage;
+ uint16 _watchingTime;
+ uint16 _reelToWatch; // reel plays from here in mode 0
+ uint16 _endWatchReel; // and stops here. Mode set to 1
+ uint8 _speedCount;
+ uint8 _watchSpeed;
+ uint16 _reelToHold; // if mode is 1 hold on this reel
+ uint16 _endOfHoldReel; // if mode is 2 then play to endOfHoldReel and reset mode to -1
+ uint8 _watchMode;
+ uint8 _destAfterHold; // set walking destination
+ uint8 _newsItem;
+ uint8 _liftFlag;
+ uint8 _liftPath;
+ uint8 _lockStatus;
+ uint8 _doorPath;
+ uint8 _countToOpen;
+ uint8 _countToClose;
+ uint8 _rockstarDead;
+ uint8 _generalDead;
+ uint8 _sartainDead;
+ uint8 _aideDead;
+ uint8 _beenMugged;
+ uint8 _gunPassFlag;
+ uint8 _canMoveAltar;
+ uint8 _talkedToAttendant;
+ uint8 _talkedToSparky;
+ uint8 _talkedToBoss;
+ uint8 _talkedToRecep;
+ uint8 _cardPassFlag;
+ uint8 _madmanFlag;
+ uint8 _keeperFlag;
+ uint8 _lastTrigger;
+ uint8 _manDead;
+ uint8 _seed1;
+ uint8 _seed2;
+ uint8 _seed3;
+ uint8 _needToTravel;
+ uint8 _throughDoor;
+ uint8 _newObs;
+ uint8 _ryanOn;
+ uint8 _combatCount;
+ uint8 _lastWeapon;
+ uint8 _dreamNumber;
+ uint8 _roomAfterDream;
+ uint8 _shakeCounter;
+};
+
+struct TimedTemp {
+ TimedTemp() : _timeCount(0), _string(0) { }
+
+ uint8 _x;
+ uint8 _y;
+
+ uint16 _timeCount;
+ uint16 _countToTimed;
+
+ const char *_string;
+};
+
+} // End of namespace DreamWeb
+
+#endif
+
diff --git a/engines/dreamweb/stubs.cpp b/engines/dreamweb/stubs.cpp
index bfa22f431c..9789e20210 100644
--- a/engines/dreamweb/stubs.cpp
+++ b/engines/dreamweb/stubs.cpp
@@ -21,972 +21,1186 @@
*/
#include "dreamweb/dreamweb.h"
-#include "engines/util.h"
#include "common/config-manager.h"
-namespace DreamGen {
-
-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();
+namespace DreamWeb {
+
+// Keyboard buffer. _bufferIn and _bufferOut are indexes
+// into this, making it a ring buffer
+uint8 g_keyBuffer[16];
+
+const Room g_roomData[] = {
+ // location 0
+ { "DREAMWEB.R00", // Ryan's apartment
+ 5,255,33,10,
+ 255,255,255,0,
+ 1,6,2,255,3,255,255,255,255,255,0 },
+
+ // location 1
+ { "DREAMWEB.R01",
+ 1,255,44,10,
+ 255,255,255,0,
+ 7,2,255,255,255,255,6,255,255,255,1 },
+
+ // location 2: Louis' (?)
+ { "DREAMWEB.R02",
+ 2,255,33,0,
+ 255,255,255,0,
+ 1,0,255,255,1,255,3,255,255,255,2 },
+
+ // location 3
+ { "DREAMWEB.R03",
+ 5,255,33,10,
+ 255,255,255,0,
+ 2,2,0,2,4,255,0,255,255,255,3 },
+
+ // location 4
+ { "DREAMWEB.R04",
+ 23,255,11,30,
+ 255,255,255,0,
+ 1,4,0,5,255,255,3,255,255,255,4 },
+
+ // location 5: In hotel, lift noise audible (?)
+ { "DREAMWEB.R05",
+ 5,255,22,30, // if demo: 22,255,22,30,
+ 255,255,255,0,
+ 1,2,0,4,255,255,3,255,255,255,5 },
+
+ // location 6: sarters (?)
+ { "DREAMWEB.R06",
+ 5,255,11,30,
+ 255,255,255,0,
+ 1,0,0,1,2,255,0,255,255,255,6 },
+
+ // location 7
+ { "DREAMWEB.R07",
+ 255,255,0,20,
+ 255,255,255,0,
+ 2,2,255,255,255,255,0,255,255,255,7 },
+
+ // location 8: TV studio (?)
+ { "DREAMWEB.R08",
+ 8,255,0,10,
+ 255,255,255,0,
+ 1,2,255,255,255,255,0,11,40,0,8 },
+
+ // location 9
+ { "DREAMWEB.R09",
+ 9,255,22,10,
+ 255,255,255,0,
+ 4,6,255,255,255,255,0,255,255,255,9 },
+
+ // location 10
+ { "DREAMWEB.R10",
+ 10,255,33,30,
+ 255,255,255,0,
+ 2,0,255,255,2,2,4,22,30,255,10 }, // 22,30,0 switches
+ // off path 0 in skip
+ // location 11
+ { "DREAMWEB.R11",
+ 11,255,11,20,
+ 255,255,255,0,
+ 0,4,255,255,255,255,255,255,255,255,11 },
+
+ // location 12
+ { "DREAMWEB.R12",
+ 12,255,22,20,
+ 255,255,255,0,
+ 1,4,255,255,255,255,255,255,255,255,12 },
+
+ // location 13: boathouse (?)
+ { "DREAMWEB.R13",
+ 12,255,22,20,
+ 255,255,255,0,
+ 1,4,255,255,255,255,255,255,255,255,13 },
+
+ // location 14
+ { "DREAMWEB.R14",
+ 14,255,44,20,
+ 255,255,255,0,
+ 0,6,255,255,255,255,255,255,255,255,14 },
+
+ { "", 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 },
+ { "", 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 },
+ { "", 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 },
+ { "", 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 },
+
+ // location 19
+ { "DREAMWEB.R19",
+ 19,255,0,0,
+ 255,255,255,0,
+ 0,4,255,255,255,255,255,255,255,255,19 },
+
+ // location 20: Sart room (?)
+ { "DREAMWEB.R20",
+ 22,255,0,20,
+ 255,255,255,0,
+ 1,4,2,15,255,255,255,255,255,255,20 },
+
+ // location 21: lift noise audible (?)
+ { "DREAMWEB.R21",
+ 5,255,11,10, // if demo: 22,255,11,10,
+ 255,255,255,0,
+ 1,4,2,15,1,255,255,255,255,255,21 },
+
+ // location 22: pool room (?)
+ { "DREAMWEB.R22",
+ 22,255,22,10,
+ 255,255,255,0,
+ 0,4,255,255,1,255,255,255,255,255,22 },
+
+ // location 23
+ { "DREAMWEB.R23",
+ 23,255,22,30,
+ 255,255,255,0,
+ 1,4,2,15,3,255,255,255,255,255,23 },
+
+ // location 24: only room in which initialInv() is active, i.e. we get initial inventory here
+ { "DREAMWEB.R24",
+ 5,255,44,0,
+ 255,255,255,0,
+ 1,6,2,15,255,255,255,255,255,255,24 },
+
+ // location 25: helicopter (?)
+ { "DREAMWEB.R25",
+ 22,255,11,40,
+ 255,255,255,0,
+ 1,0,255,255,255,255,255,255,255,255,25 },
+
+ // location 26: reached via trap door (?)
+ { "DREAMWEB.R26",
+ 9,255,22,20,
+ 255,255,255,0,
+ 4,2,255,255,255,255,255,255,255,255,26 },
+
+ // location 27: rock room (?)
+ { "DREAMWEB.R27",
+ 22,255,11,20,
+ 255,255,255,0,
+ 0,6,255,255,255,255,255,255,255,255,27 },
+
+ // location 28: related to TV studiou (?), see resetLocation()
+ { "DREAMWEB.R28",
+ 5,255,11,30,
+ 255,255,255,0,
+ 0,0,255,255,2,255,255,255,255,255,28 },
+
+ // location 29: aide (?)
+ { "DREAMWEB.R29",
+ 22,255,11,10,
+ 255,255,255,0,
+ 0,2,255,255,255,255,255,255,255,255,29 },
+
+
+ // location 30
+ { "DREAMWEB.R05", // Duplicate of hotel lobby, but emerging from the lift.
+ 5,255,22,10, // if demo: 22,255,22,10
+ 255,255,255,0,
+ 1,4,1,15,255,255,255,255,255,255,5 },
+
+ // location 31
+ { "DREAMWEB.R04", // Duplicate of pool hall lobby,
+ 23,255,22,20, // but emerging from the lift.
+ 255,255,255,0,
+ 1,4,2,15,255,255,255,255,255,255,4 },
+
+ // location 32
+ { "DREAMWEB.R10", // entering alley via skip
+ 10,255,22,30,
+ 255,255,255,0,
+ 3,6,255,255,255,255,255,255,255,255,10 },
+
+ // location 33
+ { "DREAMWEB.R12", // on the beach, getting up.
+ 12,255,22,20,
+ 255,255,255,0,
+ 0,2,255,255,255,255,255,255,255,255,12 },
+
+ // location 34
+ { "DREAMWEB.R03", // Duplicate of Eden's lobby
+ 5,255,44,0, // but emerging from the lift
+ 255,255,255,0,
+ 1,6,2,255,4,255,255,255,255,255,3 },
+
+ // location 35: Location when starting the game, after dream (?)
+ { "DREAMWEB.R24", // Duplicate of Eden's flat
+ 5,255,22,0, // but starting on the bed
+ 255,255,255,0,
+ 3,6,0,255,255,255,255,33,0,3,24 }, // 33,0,3 turns off path for lift
+
+ // location 36
+ { "DREAMWEB.R22", // Duplicate
+ 22,255,22,20, // of hotel but in pool room
+ 255,255,255,0,
+ 1,4,255,255,255,255,255,255,255,255,22 },
+
+ // location 37
+ { "DREAMWEB.R22", // Duplicate
+ 22,255,22,20, // of hotel but in pool room
+ 255,255,255,0, // coming out of bedroom
+ 0,2,255,255,255,255,255,255,255,255,22 },
+
+ // location 38
+ { "DREAMWEB.R11", // Duplicate
+ 11,255,22,30, // of carpark but getting
+ 255,255,255,0, // up off the floor
+ 0,0,255,255,255,255,255,255,255,255,11 },
+
+ // location 39
+ { "DREAMWEB.R28",
+ 5,255,11,20,
+ 255,255,255,0,
+ 0,6,255,255,2,255,255,255,255,255,28 },
+
+ // location 40
+ { "DREAMWEB.R21",
+ 5,255,11,10, // if demo: 22,255,11,10
+ 255,255,255,0,
+ 1,4,2,15,1,255,255,255,255,255,21 },
+
+ // location 41
+ { "DREAMWEB.R26",
+ 9,255,0,40,
+ 255,255,255,0,
+ 0,0,255,255,255,255,255,255,255,255,26 },
+
+ // location 42
+ { "DREAMWEB.R19",
+ 19,255,0,0,
+ 255,255,255,0,
+ 2,2,255,255,255,255,255,255,255,255,19 },
+
+ // location 43
+ { "DREAMWEB.R08", // leaving tvstudio into street
+ 8,255,11,40,
+ 255,255,255,0,
+ 0,4,255,255,255,255,255,255,255,255,8 },
+
+ // location 44
+ { "DREAMWEB.R01",
+ 1,255,44,10,
+ 255,255,255,0,
+ 3,6,255,255,255,255,255,255,255,255,1 },
+
+
+ // location 45
+ { "DREAMWEB.R45", // Dream room
+ 35,255,22,30,
+ 255,255,255,0,
+ 0,6,255,255,255,255,255,255,255,255,45 },
+
+ // location 46
+ { "DREAMWEB.R46", // Dream room
+ 35,255,22,40,
+ 255,255,255,0,
+ 0,4,255,255,255,255,255,255,255,255,46 },
+
+ // location 47
+ { "DREAMWEB.R47", // Dream room
+ 35,255,0,0,
+ 255,255,255,0,
+ 0,0,255,255,255,255,255,255,255,255,47 },
+
+ // location 48
+ { "DREAMWEB.R45", // Dream room
+ 35,255,22,30,
+ 255,255,255,0,
+ 4,0,255,255,255,255,255,255,255,255,45 },
+
+ // location 49
+ { "DREAMWEB.R46", // Dream room
+ 35,255,22,50,
+ 255,255,255,0,
+ 0,4,255,255,255,255,255,255,255,255,46 },
+
+
+ // location 50
+ { "DREAMWEB.R50", // Intro sequence one
+ 35,255,22,30,
+ 255,255,255,0,
+ 0,0,255,255,255,255,255,255,255,255,50 },
+
+ { "DREAMWEB.R51", // Intro sequence two
+ 35,255,11,30,
+ 255,255,255,0,
+ 0,0,255,255,255,255,255,255,255,255,51 },
+
+ { "DREAMWEB.R52", // Intro sequence three
+ 35,255,22,30,
+ 255,255,255,0,
+ 0,0,255,255,255,255,255,255,255,255,52 },
+
+ { "DREAMWEB.R53", // Intro sequence four
+ 35,255,33,0,
+ 255,255,255,0,
+ 0,0,255,255,255,255,255,255,255,255,53 },
+
+ { "DREAMWEB.R54", // Intro sequence five - wasteland
+ 35,255,0,0,
+ 255,255,255,0,
+ 0,0,255,255,255,255,255,255,255,255,54 },
+
+ { "DREAMWEB.R55", // End sequence
+ 14,255,44,0,
+ 255,255,255,0,
+ 0,0,255,255,255,255,255,255,255,255,55 }
+};
+
+static const Atmosphere g_atmosphereList[] = {
+ // location,map x,y,sound,repeat
+ { 0,33,10,15,255 },
+ { 0,22,10,15,255 },
+ { 0,22,0,15,255 },
+ { 0,11,0,15,255 },
+ { 0,11,10,15,255 },
+ { 0,0,10,15,255 },
+
+ { 1,44,10,6,255 },
+ { 1,44,0,13,255 },
+
+ { 2,33,0,6,255 },
+ { 2,22,0,5,255 },
+ { 2,22,10,16,255 },
+ { 2,11,10,16,255 },
+
+ { 3,44,0,15,255 },
+ { 3,33,10,6,255 },
+ { 3,33,0,5,255 },
+
+ { 4,11,30,6,255 },
+ { 4,22,30,5,255 },
+ { 4,22,20,13,255 },
+
+ { 10,33,30,6,255 },
+ { 10,22,30,6,255 },
+
+ { 9,22,10,6,255 },
+ { 9,22,20,16,255 },
+ { 9,22,30,16,255 },
+ { 9,22,40,16,255 },
+ { 9,22,50,16,255 },
+
+ { 6,11,30,6,255 },
+ { 6,0,10,15,255 },
+ { 6,0,20,15,255 },
+ { 6,11,20,15,255 },
+ { 6,22,20,15,255 },
+
+ { 7,11,20,6,255 },
+ { 7,0,20,6,255 },
+ { 7,0,30,6,255 },
+
+ { 55,44,0,5,255 },
+ { 55,44,10,5,255 },
+
+ { 5,22,30,6,255 },
+ { 5,22,20,15,255 }, // if demo: { 5,22,20,16,255 },
+ { 5,22,10,15,255 }, // if demo: { 5,22,10,16,255 },
+
+ { 24,22,0,15,255 },
+ { 24,33,0,15,255 },
+ { 24,44,0,15,255 },
+ { 24,33,10,15,255 },
+
+ { 8,0,10,6,255 },
+ { 8,11,10,6,255 },
+ { 8,22,10,6,255 },
+ { 8,33,10,6,255 },
+ { 8,33,20,6,255 },
+ { 8,33,30,6,255 },
+ { 8,33,40,6,255 },
+ { 8,22,40,6,255 },
+ { 8,11,40,6,255 },
+
+ { 11,11,20,12,255 },
+ { 11,11,30,12,255 },
+ { 11,22,20,12,255 },
+ { 11,22,30,12,255 },
+
+ { 12,22,20,12,255 },
+ { 13,22,20,12,255 },
+ { 13,33,20,12,255 },
+
+ { 14,44,20,12,255 },
+ { 14,33,0,12,255 },
+ { 14,33,10,12,255 },
+ { 14,33,20,12,255 },
+ { 14,33,30,12,255 },
+ { 14,33,40,12,255 },
+ { 14,22,0,16,255 },
+
+ { 19,0,0,12,255 },
+
+ { 20,0,20,16,255 },
+ { 20,0,30,16,255 },
+ { 20,11,30,16,255 },
+ { 20,0,40,16,255 },
+ { 20,11,40,16,255 },
+
+ { 21,11,10,15,255 }, // if demo: { 21,11,10,16,255 },
+ { 21,11,20,15,255 }, // if demo: { 21,11,20,16,255 },
+ { 21, 0,20,15,255 }, // if demo: { 21,0,20,16,255 },
+ { 21,22,20,15,255 }, // if demo: { 21,22,20,16,255 },
+ { 21,33,20,15,255 }, // if demo: { 21,33,20,16,255 },
+ { 21,44,20,15,255 }, // if demo: { 21,44,20,16,255 },
+ { 21,44,10,15,255 }, // if demo: { 21,44,10,16,255 },
+
+ { 22,22,10,16,255 },
+ { 22,22,20,16,255 },
+
+ { 23,22,30,13,255 },
+ { 23,22,40,13,255 },
+ { 23,33,40,13,255 },
+ { 23,11,40,13,255 },
+ { 23,0,40,13,255 },
+ { 23,0,50,13,255 },
+
+ { 25,11,40,16,255 },
+ { 25,11,50,16,255 },
+ { 25,0,50,16,255 },
+
+ { 27,11,20,16,255 },
+ { 27,11,30,16,255 },
+
+ { 29,11,10,16,255 },
+
+ { 45,22,30,12,255 },
+ { 45,22,40,12,255 },
+ { 45,22,50,12,255 },
+
+ { 46,22,40,12,255 },
+ { 46,11,50,12,255 },
+ { 46,22,50,12,255 },
+ { 46,33,50,12,255 },
+
+ { 47,0,0,12,255 },
+
+ { 26,22,20,16,255 },
+ { 26,33,10,16,255 },
+ { 26,33,20,16,255 },
+ { 26,33,30,16,255 },
+ { 26,44,30,16,255 },
+ { 26,22,30,16,255 },
+ { 26,11,30,16,255 },
+ { 26,11,20,16,255 },
+ { 26,0,20,16,255 },
+ { 26,11,40,16,255 },
+ { 26,0,40,16,255 },
+ { 26,22,40,16,255 },
+ { 26,11,50,16,255 },
+
+ { 28,0,30,15,255 },
+ { 28,0,20,15,255 },
+ { 28,0,40,15,255 },
+ { 28,11,30,15,255 },
+ { 28,11,20,15,255 },
+ { 28,22,30,15,255 },
+ { 28,22,20,15,255 },
+
+ { 255,255,255,255,255 }
+
+};
+
+void DreamWebEngine::dreamwebFinalize() {
+ // The engine will need some cleaner finalization (destructor?), let's put
+ // it here for now
+
+ getRidOfAll();
+
+ _icons1.clear();
+ _icons2.clear();
+ _charset1.clear();
+ _mainSprites.clear();
+
+ // clear local graphics, just in case
+ _keypadGraphics.clear();
+ _menuGraphics.clear();
+ _menuGraphics2.clear();
+ _folderGraphics.clear();
+ _folderGraphics2.clear();
+ _folderGraphics3.clear();
+ _folderCharset.clear();
+ _symbolGraphics.clear();
+ _diaryGraphics.clear();
+ _diaryCharset.clear();
+ _monitorGraphics.clear();
+ _monitorCharset.clear();
+ _newplaceGraphics.clear();
+ _newplaceGraphics2.clear();
+ _newplaceGraphics3.clear();
+ _cityGraphics.clear();
+ _saveGraphics.clear();
+
+ _exFrames.clear();
+ _exText.clear();
+
+ _setFrames.clear();
+ _freeFrames.clear();
+ _reel1.clear();
+ _reel2.clear();
+ _reel3.clear();
+ _setDesc.clear();
+ _blockDesc.clear();
+ _roomDesc.clear();
+ _freeDesc.clear();
+ _personText.clear();
+
+ _textFile1.clear();
+ _textFile2.clear();
+ _textFile3.clear();
+ _travelText.clear();
+ _puzzleText.clear();
+ _commandText.clear();
+}
+
+void DreamWebEngine::dreamweb() {
+ switch(getLanguage()) {
+ case Common::EN_ANY:
+ case Common::EN_GRB:
+ case Common::EN_USA:
+ _foreignRelease = false;
+ break;
+ default:
+ _foreignRelease = true;
+ break;
+ }
+
+ allocateBuffers();
+
+ // setMouse
+ _oldPointerX = 0xffff;
+
+ fadeDOS();
+ getTime();
+ clearBuffers();
+ clearPalette();
+ set16ColPalette();
+ readSetData();
+ _wonGame = false;
+
+ loadSounds(0, "V99"); // basic sample
bool firstLoop = true;
int savegameId = Common::ConfigManager::instance().getInt("save_slot");
while (true) {
-
- scanfornames();
+ uint count = scanForNames();
bool startNewGame = true;
if (firstLoop && savegameId >= 0) {
-
// loading a savegame requested from launcher/command line
cls();
- setmode();
- loadpalfromiff();
- clearpalette();
-
- ax = savegameId;
- doload();
- worktoscreen();
- fadescreenup();
+ setMode();
+ loadPalFromIFF();
+ clearPalette();
+
+ doLoad(savegameId);
+ workToScreen();
+ fadeScreenUp();
startNewGame = false;
- } else if (al == 0 && firstLoop) {
+ } else if (count == 0 && firstLoop) {
// no savegames found, and we're not restarting.
- setmode();
- loadpalfromiff();
+ setMode();
+ loadPalFromIFF();
} else {
- // "dodecisions"
+ // "doDecisions"
// Savegames found, so ask if we should load one.
// (If we're restarting after game over, we also always show these
// options.)
cls();
- setmode();
+ setMode();
decide();
- if (data.byte(kQuitrequested))
- return; // exit game
+ if (_quitRequested)
+ return;
- if (data.byte(kGetback) == 4)
+ if (_getBack == 4)
startNewGame = false; // savegame has been loaded
-
}
firstLoop = false;
if (startNewGame) {
- // "playgame"
-
- titles();
- if (data.byte(kQuitrequested))
- return; // exit game
- credits();
-
- if (data.byte(kQuitrequested))
- return; // exit game
-
- 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) = (uint8)-1;
- data.byte(kCommandtype) = 255;
+ // "playGame"
+ // "titles"
+ // TODO: In the demo version, titles() did nothing
+ clearPalette();
+ bibleQuote();
+ if (!_quitRequested) // "titlesearly"
+ intro();
+
+ if (_quitRequested)
+ return;
+
+ // "credits"
+ clearPalette();
+ realCredits();
+
+ if (_quitRequested)
+ return;
+
+ clearChanges();
+ setMode();
+ loadPalFromIFF();
+ _vars._location = 255;
+ _vars._roomAfterDream = 1;
+ _newLocation = 35;
+ _volume = 7;
+ loadRoom();
+ clearSprites();
+ initMan();
+ entryTexts();
+ entryAnims();
+ _destPos = 3;
+ initialInv();
+ _lastFlag = 32;
+ startup1();
+ _volumeTo = 0;
+ _volumeDirection = -1;
+ _commandType = 255;
}
// main loop
while (true) {
+ if (_quitRequested)
+ return;
- if (data.byte(kQuitrequested))
- return; // exit game
+ screenUpdate();
- screenupdate();
+ if (_quitRequested)
+ return;
- if (data.byte(kWongame) != 0) {
+ if (_wonGame) {
// "endofgame"
- clearbeforeload();
- fadescreendowns();
- hangon(200);
- endgame();
- quickquit2();
+ clearBeforeLoad();
+ fadeScreenDowns();
+ hangOn(200);
+ endGame();
return;
}
- if (data.byte(kMandead) == 1 || data.byte(kMandead) == 2)
+ if (_vars._manDead == 1 || _vars._manDead == 2)
break;
- if (data.word(kWatchingtime) > 0) {
- if (data.byte(kFinaldest) == data.byte(kManspath))
- data.word(kWatchingtime)--;
+ if (_vars._watchingTime > 0) {
+ if (_finalDest == _mansPath)
+ _vars._watchingTime--;
}
- if (data.word(kWatchingtime) == 0) {
- // "notwatching"
+ if (_vars._watchingTime == 0) {
+ // "notWatching"
- if (data.byte(kMandead) == 4)
+ if (_vars._manDead == 4)
break;
- if (data.byte(kNewlocation) != 255) {
- // "loadnew"
- clearbeforeload();
- loadroom();
- clearsprites();
- initman();
- entrytexts();
- entryanims();
- data.byte(kNewlocation) = 255;
+ if (_newLocation != 255) {
+ // "loadNew"
+ clearBeforeLoad();
+ loadRoom();
+ clearSprites();
+ initMan();
+ entryTexts();
+ entryAnims();
+ _newLocation = 255;
startup();
- data.byte(kCommandtype) = 255;
- worktoscreenm();
+ _commandType = 255;
+ workToScreenM();
}
}
}
- // "gameover"
- clearbeforeload();
- showgun();
- fadescreendown();
- hangon(100);
+ // "gameOver"
+ clearBeforeLoad();
+ showGun();
+ fadeScreenDown();
+ hangOn(100);
}
}
-static 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::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 DreamWebEngine::loadTextFile(TextFile &file, const char *suffix) {
+ Common::String fileName = getDatafilePrefix() + suffix;
+ FileHeader header;
-void DreamGenContext::keyboardread() {
- ::error("keyboardread"); //this keyboard int handler, must never be called
-}
+ Common::File f;
+ f.open(fileName);
+ f.read((uint8 *)&header, sizeof(FileHeader));
+ uint16 sizeInBytes = header.len(0);
+ assert(sizeInBytes >= 2*66);
-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;
-}
+ delete[] file._text;
+ file._text = new char[sizeInBytes - 2*66];
-void DreamGenContext::createfile() {
- ::error("createfile");
+ f.read(file._offsetsLE, 2*66);
+ f.read(file._text, sizeInBytes - 2*66);
}
-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() {
- uint16 x, y, state;
- engine->mouseCall(&x, &y, &state);
- cx = x;
- dx = y;
- bx = state;
-}
-
-void DreamGenContext::readmouse() {
- data.word(kOldbutton) = data.word(kMousebutton);
- data.word(kOldx) = data.word(kMousex);
- data.word(kOldy) = data.word(kMousey);
- uint16 x, y, state;
- engine->mouseCall(&x, &y, &state);
- data.word(kMousex) = x;
- data.word(kMousey) = y;
- data.word(kMousebutton) = state;
-}
-
-void DreamGenContext::readmouse1() {
- data.word(kOldx) = data.word(kMousex);
- data.word(kOldy) = data.word(kMousey);
- uint16 x, y, state;
- engine->mouseCall(&x, &y, &state);
- data.word(kMousex) = x;
- data.word(kMousey) = y;
- data.word(kMousebutton1) = state;
-}
+void DreamWebEngine::screenUpdate() {
+ newPlace();
+ mainScreen();
+ if (_quitRequested)
+ return;
+ animPointer();
-void DreamGenContext::readmouse2() {
- data.word(kOldx) = data.word(kMousex);
- data.word(kOldy) = data.word(kMousey);
- uint16 x, y, state;
- engine->mouseCall(&x, &y, &state);
- data.word(kMousex) = x;
- data.word(kMousey) = y;
- data.word(kMousebutton2) = state;
+ showPointer();
+ if ((_vars._watchingTime == 0) && (_newLocation != 0xff))
+ return;
+ vSync();
+ uint16 mouseState = 0;
+ mouseState |= readMouseState();
+ dumpPointer();
+
+ dumpTextLine();
+ delPointer();
+ autoLook();
+ spriteUpdate();
+ watchCount();
+ zoom();
+
+ showPointer();
+ if (_wonGame)
+ return;
+ vSync();
+ mouseState |= readMouseState();
+ dumpPointer();
+
+ dumpZoom();
+ delPointer();
+ delEverything();
+ printSprites();
+ reelsOnScreen();
+ afterNewRoom();
+
+ showPointer();
+ vSync();
+ mouseState |= readMouseState();
+ dumpPointer();
+
+ dumpMap();
+ dumpTimedText();
+ delPointer();
+
+ showPointer();
+ vSync();
+ _oldButton = _mouseButton;
+ mouseState |= readMouseState();
+ _mouseButton = mouseState;
+ dumpPointer();
+
+ dumpWatch();
+ delPointer();
+}
+
+void DreamWebEngine::startup() {
+ _currentKey = 0;
+ _mainMode = 0;
+ createPanel();
+ _vars._newObs = 1;
+ drawFloor();
+ showIcon();
+ getUnderZoom();
+ spriteUpdate();
+ printSprites();
+ underTextLine();
+ reelsOnScreen();
+ atmospheres();
+}
+
+void DreamWebEngine::startup1() {
+ clearPalette();
+ _vars._throughDoor = 0;
+
+ startup();
+
+ workToScreen();
+ fadeScreenUp();
+}
+
+void DreamWebEngine::switchRyanOn() {
+ _vars._ryanOn = 255;
+}
+
+void DreamWebEngine::switchRyanOff() {
+ _vars._ryanOn = 1;
+}
+
+void DreamWebEngine::loadGraphicsFile(GraphicsFile &file, const char *suffix) {
+ Common::String fileName = getDatafilePrefix() + suffix;
+ FileHeader header;
+
+ Common::File f;
+ f.open(fileName);
+ f.read((uint8 *)&header, sizeof(FileHeader));
+ uint16 sizeInBytes = header.len(0);
+
+ assert(sizeInBytes >= kFrameBlocksize);
+ file.clear();
+ file._data = new uint8[sizeInBytes - kFrameBlocksize];
+ file._frames = new Frame[kGraphicsFileFrameSize];
+ f.read((uint8 *)file._frames, kFrameBlocksize);
+ f.read(file._data, sizeInBytes - kFrameBlocksize);
+}
+
+void DreamWebEngine::loadGraphicsSegment(GraphicsFile &file, Common::File &inFile, unsigned int len) {
+ assert(len >= kFrameBlocksize);
+ file.clear();
+ file._data = new uint8[len - kFrameBlocksize];
+ file._frames = new Frame[kGraphicsFileFrameSize];
+ inFile.read((uint8 *)file._frames, kFrameBlocksize);
+ inFile.read(file._data, len - kFrameBlocksize);
+}
+
+void DreamWebEngine::loadTextSegment(TextFile &file, Common::File &inFile, unsigned int len) {
+ const uint headerSize = 2 * file._size;
+ assert(len >= headerSize);
+ delete[] file._text;
+ file._text = new char[len - headerSize];
+ inFile.read((uint8 *)file._offsetsLE, headerSize);
+ inFile.read((uint8 *)file._text, len - headerSize);
+}
+
+void DreamWebEngine::hangOnCurs(uint16 frameCount) {
+ for (uint16 i = 0; i < frameCount; ++i) {
+ printCurs();
+ vSync();
+ delCurs();
+ }
}
-void DreamGenContext::readmouse3() {
- data.word(kOldx) = data.word(kMousex);
- data.word(kOldy) = data.word(kMousey);
- uint16 x, y, state;
- engine->mouseCall(&x, &y, &state);
- data.word(kMousex) = x;
- data.word(kMousey) = y;
- data.word(kMousebutton3) = state;
+void DreamWebEngine::readMouse() {
+ _oldButton = _mouseButton;
+ uint16 state = readMouseState();
+ _mouseButton = state;
}
-void DreamGenContext::readmouse4() {
- data.word(kOldbutton) = data.word(kMousebutton);
- data.word(kOldx) = data.word(kMousex);
- data.word(kOldy) = data.word(kMousey);
+uint16 DreamWebEngine::readMouseState() {
+ _oldX = _mouseX;
+ _oldY = _mouseY;
uint16 x, y, state;
- engine->mouseCall(&x, &y, &state);
- data.word(kMousex) = x;
- data.word(kMousey) = y;
- data.word(kMousebutton) = state | data.word(kMousebutton1) | data.word(kMousebutton2) | data.word(kMousebutton3);
+ mouseCall(&x, &y, &state);
+ _mouseX = x;
+ _mouseY = y;
+ return state;
}
-void DreamGenContext::setmouse() {
- data.word(kOldpointerx) = 0xffff;
-}
-
-void DreamGenContext::dumptextline() {
- if (data.byte(kNewtextline) != 1)
+void DreamWebEngine::dumpTextLine() {
+ if (_newTextLine != 1)
return;
- data.byte(kNewtextline) = 0;
- uint16 x = data.word(kTextaddressx);
- uint16 y = data.word(kTextaddressy);
- if (data.byte(kForeignrelease) != 0)
+ _newTextLine = 0;
+ uint16 x = _textAddressX;
+ uint16 y = _textAddressY;
+ if (_foreignRelease)
y -= 3;
- multidump(x, y, 228, 13);
+ multiDump(x, y, 228, 13);
}
-void DreamGenContext::getundertimed() {
- uint16 y = data.byte(kTimedy);
- if (data.byte(kForeignrelease))
- y -= 3;
- ds = data.word(kBuffers);
- si = kUndertimedtext;
- multiget(ds.ptr(si, 0), data.byte(kTimedx), y, 240, kUndertimedysize);
+void DreamWebEngine::getUnderTimed() {
+ if (_foreignRelease)
+ multiGet(_underTimedText, _timedTemp._x, _timedTemp._y - 3, 240, kUnderTimedTextSizeY_f);
+ else
+ multiGet(_underTimedText, _timedTemp._x, _timedTemp._y, 240, kUnderTimedTextSizeY);
}
-void DreamGenContext::putundertimed() {
- uint16 y = data.byte(kTimedy);
- if (data.byte(kForeignrelease))
- y -= 3;
- ds = data.word(kBuffers);
- si = kUndertimedtext;
- multiput(ds.ptr(si, 0), data.byte(kTimedx), y, 240, kUndertimedysize);
+void DreamWebEngine::putUnderTimed() {
+ if (_foreignRelease)
+ multiPut(_underTimedText, _timedTemp._x, _timedTemp._y - 3, 240, kUnderTimedTextSizeY_f);
+ else
+ multiPut(_underTimedText, _timedTemp._x, _timedTemp._y, 240, kUnderTimedTextSizeY);
+}
+
+void DreamWebEngine::triggerMessage(uint16 index) {
+ multiGet(_mapStore, 174, 153, 200, 63);
+ const uint8 *string = (const uint8 *)_puzzleText.getString(index);
+ uint16 y = 156;
+ printDirect(&string, 174, &y, 141, true);
+ hangOn(140);
+ workToScreen();
+ hangOn(340);
+ multiPut(_mapStore, 174, 153, 200, 63);
+ workToScreen();
+ _vars._lastTrigger = 0;
+}
+
+void DreamWebEngine::processTrigger() {
+ if (_vars._lastTrigger == '1') {
+ setLocation(8);
+ triggerMessage(45);
+ } else if (_vars._lastTrigger == '2') {
+ setLocation(9);
+ triggerMessage(55);
+ } else if (_vars._lastTrigger == '3') {
+ setLocation(2);
+ triggerMessage(59);
+ }
}
-void DreamGenContext::usetimedtext() {
- if (data.word(kTimecount) == 0)
- return;
- --data.word(kTimecount);
- if (data.word(kTimecount) == 0) {
- putundertimed();
- data.byte(kNeedtodumptimed) = 1;
- return;
- }
+void DreamWebEngine::useTimedText() {
+ if (_previousTimedTemp._string) {
+ // TODO: It might be nice to make subtitles wait for the speech
+ // to finish (_channel1Playing) when we're in speech+subtitles mode,
+ // instead of waiting the pre-specified amount of time.
- if (data.word(kTimecount) == data.word(kCounttotimed))
- getundertimed();
- else if (data.word(kTimecount) > data.word(kCounttotimed))
- return;
- es = data.word(kTimedseg);
- si = data.word(kTimedoffset);
- const uint8 *string = es.ptr(si, 0);
- uint16 y = data.byte(kTimedy);
- printdirect(&string, data.byte(kTimedx), &y, 237, true);
- data.byte(kNeedtodumptimed) = 1;
-}
-
-void DreamGenContext::setuptimedtemp() {
- setuptimedtemp(al, ah, bl, bh, cx, dx);
-}
-
-void DreamGenContext::setuptimedtemp(uint8 textIndex, uint8 voiceIndex, uint8 x, uint8 y, uint16 countToTimed, uint16 timeCount) {
-#if 1 // if cd
- if (voiceIndex != 0) {
- push(ax);
- push(bx);
- push(cx);
- push(dx);
- dl = 'T';
- dh = voiceIndex;
- cl = 'T';
- ah = 0;
- loadspeech();
- if (data.byte(kSpeechloaded) == 1) {
- al = 50+12;
- playchannel1();
- }
- dx = pop();
- cx = pop();
- bx = pop();
- ax = pop();
- if ((data.byte(kSpeechloaded) == 1) && (data.byte(kSubtitles) != 1))
- return;
- }
-#endif
+ // Ugly... (Maybe make this an argument to putUnderTimed()?)
+ TimedTemp t = _timedTemp;
+ _timedTemp = _previousTimedTemp;
- if (data.word(kTimecount) != 0)
- return;
- data.byte(kTimedy) = y;
- data.byte(kTimedx) = x;
- data.word(kCounttotimed) = countToTimed;
- data.word(kTimecount) = timeCount + countToTimed;
- data.word(kTimedseg) = data.word(kTextfile1);
- data.word(kTimedoffset) = kTextstart + segRef(data.word(kTextfile1)).word(textIndex * 2);
- const uint8 *string = segRef(data.word(kTextfile1)).ptr(data.word(kTimedoffset), 0);
- debug(1, "setuptimedtemp: (%d, %d) => '%s'", textIndex, voiceIndex, string);
-}
-
-void DreamGenContext::dumptimedtext() {
- if (data.byte(kNeedtodumptimed) != 1)
- return;
- uint8 y = data.byte(kTimedy);
- if (data.byte(kForeignrelease) != 0)
- y -= 3;
+ // Force-reset the previous string to make room for the next one
+ putUnderTimed();
- multidump(data.byte(kTimedx), y, 240, kUndertimedysize);
- data.byte(kNeedtodumptimed) = 0;
-}
-
-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() {
- ax = allocatemem(bx);
-}
-
-uint16 DreamGenContext::allocatemem(uint16 paragraphs) {
- uint size = (paragraphs + 2) * 16;
- debug(1, "allocate mem, %u bytes", size);
- flags._c = false;
- SegmentRef seg = allocateSegment(size);
- uint16 result = (uint16)seg;
- debug(1, "\tsegment address -> %04x", result);
- return result;
-}
-
-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)
+ _timedTemp = t;
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:
+ if (_timeCount == 0)
+ return;
+ --_timeCount;
+ if (_timeCount == 0) {
+ putUnderTimed();
+ _needToDumpTimed = 1;
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();
-}
+ if (_timeCount == _timedTemp._countToTimed)
+ getUnderTimed();
+ else if (_timeCount > _timedTemp._countToTimed)
+ return;
-void DreamGenContext::savefilewrite() {
- ax = engine->writeToSaveFile(ds.ptr(dx, cx), cx);
+ const uint8 *string = (const uint8 *)_timedTemp._string;
+ printDirect(string, _timedTemp._x, _timedTemp._y, 237, true);
+ _needToDumpTimed = 1;
}
-void DreamGenContext::savefileread() {
- ax = engine->readFromSaveFile(ds.ptr(dx, cx), cx);
-}
+void DreamWebEngine::setupTimedTemp(uint8 textIndex, uint8 voiceIndex, uint8 x, uint8 y, uint16 countToTimed, uint16 timeCount) {
-void DreamGenContext::loadseg() {
- ax = es.word(di);
- di += 2;
+ if (hasSpeech() && voiceIndex != 0) {
+ if (loadSpeech('T', voiceIndex, 'T', textIndex)) {
+ playChannel1(50+12);
+ }
- uint16 dst_offset = dx;
- uint16 size = ax;
+ if (_speechLoaded && !_subtitles)
+ return;
- debug(1, "loadseg(%04x:%u, %u)", (uint16)ds, dst_offset, size);
- ax = engine->readFromFile(ds.ptr(dst_offset, size), size);
- flags._c = false;
-}
+ if (_timeCount != 0) {
+ // store previous TimedTemp for deletion
+ _previousTimedTemp = _timedTemp;
+ _timeCount = 0;
+ }
+ }
-void DreamGenContext::error() {
- ::error("error");
-}
+ if (_timeCount != 0)
+ return;
-void DreamGenContext::generalerror() {
- ::error("generalerror");
+ _timedTemp._y = y;
+ _timedTemp._x = x;
+ _timedTemp._countToTimed = countToTimed;
+ _timeCount = _timedTemp._timeCount = timeCount + countToTimed;
+ _timedTemp._string = _textFile1.getString(textIndex);
+ debug(1, "setupTimedTemp: (%d, %d) => '%s'", textIndex, voiceIndex, _timedTemp._string);
}
-void DreamGenContext::dosreturn() {
-
- _cmp(data.byte(kCommandtype), 250);
- if (!flags.z()) {
- data.byte(kCommandtype) = 250;
- al = 46;
- commandonly();
- }
+void DreamWebEngine::dumpTimedText() {
+ const TimedTemp *tt;
+ if (_previousTimedTemp._string) {
+ assert(!_needToDumpTimed);
- ax = data.word(kMousebutton);
- _and(ax, 1);
- if (flags.z())
+ tt = &_previousTimedTemp;
+ _previousTimedTemp._string = 0;
+ _previousTimedTemp._timeCount = 0;
+ } else if (_needToDumpTimed != 1) {
return;
+ } else {
+ tt = &_timedTemp;
+ _needToDumpTimed = 0;
+ }
- data.word(kMousebutton) = 0;
- engine->quit();
-}
+ const uint16 kUndertimedysize = 30;
+ uint8 y = tt->_y;
+ if (_foreignRelease)
+ y -= 3;
-void DreamGenContext::set16colpalette() {
+ multiDump(tt->_x, y, 240, kUndertimedysize);
}
-void DreamGenContext::mode640x480() {
- // Video mode 12h: 640x480 pixels, 16 colors, I believe
- al = 0x12 + 128;
- ah = 0;
- initGraphics(640, 480, true);
+void DreamWebEngine::getTime() {
+ TimeDate t;
+ g_system->getTimeAndDate(t);
+ debug(1, "\tgettime: %02d:%02d:%02d", t.tm_hour, t.tm_min, t.tm_sec);
+ _vars._secondCount = t.tm_sec;
+ _vars._minuteCount = t.tm_min;
+ _vars._hourCount = t.tm_hour;
}
-void DreamGenContext::showgroup() {
- engine->setPalette();
-}
+void DreamWebEngine::DOSReturn() {
+ commandOnlyCond(46, 250);
-void DreamGenContext::fadedos() {
- engine->fadeDos();
+ if (_mouseButton & 1) {
+ _mouseButton = 0;
+ quit();
+ }
}
-void DreamGenContext::eraseoldobs() {
- if (data.byte(kNewobs) == 0)
+void DreamWebEngine::eraseOldObs() {
+ if (_vars._newObs == 0)
return;
- Sprite *sprites = spritetable();
- for (size_t i=0; i < 16; ++i) {
- Sprite &sprite = sprites[i];
- if (sprite.objData() != 0xffff) {
- memset(&sprite, 0xff, sizeof(Sprite));
- }
+ // Note: the original didn't delete sprites here, but marked the
+ // entries as unused, to be filled again by makeSprite. This can
+ // change the order of entries, but since they are drawn based on the
+ // priority field, this shouldn't matter.
+ Common::List<Sprite>::iterator i;
+ for (i = _spriteTable.begin(); i != _spriteTable.end(); ) {
+ Sprite &sprite = *i;
+ if (sprite._objData)
+ i = _spriteTable.erase(i);
+ else
+ ++i;
}
}
-void DreamGenContext::modifychar() {
- al = engine->modifyChar(al);
-}
-
-void DreamGenContext::lockmon() {
+void DreamWebEngine::lockMon() {
// Pressing space pauses text output in the monitor. We use the "hard"
// key because calling readkey() drains characters from the input
// buffer, we we want the user to be able to type ahead while the text
// is being printed.
- if (data.byte(kLasthardkey) == 57) {
+ if (_lastHardKey == 57) {
// Clear the keyboard buffer. Otherwise the space that caused
// the pause will be read immediately unpause the game.
do {
- readkey();
- } while (data.byte(kCurrentkey) != 0);
-
- locklighton();
- while (!engine->shouldQuit()) {
- engine->waitForVSync();
- readkey();
- if (data.byte(kCurrentkey) == ' ')
+ readKey();
+ } while (_currentKey != 0);
+
+ lockLightOn();
+ while (!shouldQuit()) {
+ waitForVSync();
+ readKey();
+ if (_currentKey == ' ')
break;
}
// Forget the last "hard" key, otherwise the space that caused
// the unpausing will immediately re-pause the game.
- data.byte(kLasthardkey) = 0;
- locklightoff();
+ _lastHardKey = 0;
+ lockLightOff();
}
}
-void DreamGenContext::cancelch0() {
- data.byte(kCh0repeat) = 0;
- data.word(kCh0blockstocopy) = 0;
- data.byte(kCh0playing) = 255;
- engine->stopSound(0);
-}
-
-void DreamGenContext::cancelch1() {
- data.word(kCh1blockstocopy) = 0;
- data.byte(kCh1playing) = 255;
- engine->stopSound(1);
+void DreamWebEngine::startLoading(const Room &room) {
+ _vars._combatCount = 0;
+ _roomsSample = room.roomsSample;
+ _mapX = room.mapX;
+ _mapY = room.mapY;
+ _vars._liftFlag = room.liftFlag;
+ _mansPath = room.b21;
+ _destination = room.b21;
+ _finalDest = room.b21;
+ _facing = room.facing;
+ _turnToFace = room.facing;
+ _vars._countToOpen = room.countToOpen;
+ _vars._liftPath = room.liftPath;
+ _vars._doorPath = room.doorPath;
+ _vars._lastWeapon = (uint8)-1;
+ _realLocation = room.realLocation;
+
+ loadRoomData(room, false);
+
+ findRoomInLoc();
+ deleteTaken();
+ setAllChanges();
+ autoAppear();
+// const Room &newRoom = g_roomData[_newLocation];
+ _vars._lastWeapon = (uint8)-1;
+ _vars._manDead = 0;
+ _lookCounter = 160;
+ _newLocation = 255;
+ _linePointer = 254;
+ if (room.b27 != 255) {
+ _mansPath = room.b27;
+ autoSetWalk();
+ }
+ findXYFromPath();
}
-void DreamGenContext::makebackob(SetObject *objData) {
- if (data.byte(kNewobs) == 0)
- return;
- uint8 priority = objData->priority;
- uint8 type = objData->type;
- Sprite *sprite = makesprite(data.word(kObjectx), data.word(kObjecty), addr_backobject, data.word(kSetframes), 0);
-
- uint16 objDataOffset = (uint8 *)objData - segRef(data.word(kSetdat)).ptr(0, 0);
- assert(objDataOffset % sizeof(SetObject) == 0);
- assert(objDataOffset < 128 * sizeof(SetObject));
- sprite->setObjData(objDataOffset);
- if (priority == 255)
- priority = 0;
- sprite->priority = priority;
- sprite->type = type;
- sprite->b16 = 0;
- sprite->delay = 0;
- sprite->frame = 0;
-}
-
-void DreamGenContext::getroomdata() {
- bx = kRoomdata + sizeof(Room) * al;
-}
-
-void DreamGenContext::startloading() {
- const Room *room = (Room *)cs.ptr(bx, sizeof(Room));
- startloading(room);
-}
-
-void DreamGenContext::readheader() {
- ax = engine->readFromFile(cs.ptr(kFileheader, kHeaderlen), kHeaderlen);
- es = cs;
- di = kFiledata;
-}
-
-void DreamGenContext::startloading(const Room *room) {
- data.byte(kCombatcount) = 0;
- data.byte(kRoomssample) = room->roomsSample;
- data.byte(kMapx) = room->mapX;
- data.byte(kMapy) = room->mapY;
- data.byte(kLiftflag) = room->liftFlag;
- data.byte(kManspath) = room->b21;
- data.byte(kDestination) = room->b21;
- data.byte(kFinaldest) = room->b21;
- data.byte(kFacing) = room->b22;
- data.byte(kTurntoface) = room->b22;
- data.byte(kCounttoopen) = room->countToOpen;
- data.byte(kLiftpath) = room->liftPath;
- data.byte(kDoorpath) = room->doorPath;
- data.byte(kLastweapon) = (uint8)-1;
- al = room->b27;
- push(ax);
- al = room->b31;
- ah = data.byte(kReallocation);
- data.byte(kReallocation) = al;
- dx = bx;
- Common::String name = getFilename(*this);
- engine->openFile(name);
- cs.word(kHandle) = 1; //only one handle
- flags._c = false;
- 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) = (uint8)-1;
- data.byte(kMandead) = 0;
- data.word(kLookcounter) = 160;
- data.byte(kNewlocation) = 255;
- data.byte(kLinepointer) = 254;
- ax = pop();
- if (al != 255) {
- data.byte(kManspath) = al;
- push(bx);
- autosetwalk();
- bx = pop();
- }
- findxyfrompath();
-}
-
-void DreamGenContext::fillspace() {
- memset(ds.ptr(dx, cx), al, cx);
-}
-
-void DreamGenContext::dealwithspecial(uint8 firstParam, uint8 secondParam) {
+void DreamWebEngine::dealWithSpecial(uint8 firstParam, uint8 secondParam) {
uint8 type = firstParam - 220;
if (type == 0) {
- placesetobject(secondParam);
- data.byte(kHavedoneobs) = 1;
+ placeSetObject(secondParam);
+ _haveDoneObs = 1;
} else if (type == 1) {
- removesetobject(secondParam);
- data.byte(kHavedoneobs) = 1;
+ removeSetObject(secondParam);
+ _haveDoneObs = 1;
} else if (type == 2) {
- al = secondParam;
- placefreeobject();
- data.byte(kHavedoneobs) = 1;
+ placeFreeObject(secondParam);
+ _haveDoneObs = 1;
} else if (type == 3) {
- al = secondParam;
- removefreeobject();
- data.byte(kHavedoneobs) = 1;
+ removeFreeObject(secondParam);
+ _haveDoneObs = 1;
} else if (type == 4) {
- switchryanoff();
+ switchRyanOff();
} else if (type == 5) {
- data.byte(kTurntoface) = secondParam;
- data.byte(kFacing) = secondParam;
- switchryanon();
+ _turnToFace = secondParam;
+ _facing = secondParam;
+ switchRyanOn();
} else if (type == 6) {
- data.byte(kNewlocation) = secondParam;
+ _newLocation = secondParam;
} else {
- movemap(secondParam);
+ moveMap(secondParam);
}
}
-void DreamGenContext::plotreel() {
- Reel *reel = getreelstart();
- while (true) {
- if (reel->x < 220)
- break;
- if (reel->x == 255)
- break;
- dealwithspecial(reel->x, reel->y);
- ++data.word(kReelpointer);
+void DreamWebEngine::plotReel(uint16 &reelPointer) {
+ Reel *reel = getReelStart(reelPointer);
+ while (reel->x >= 220 && reel->x != 255) {
+ dealWithSpecial(reel->x, reel->y);
+ ++reelPointer;
reel += 8;
}
for (size_t i = 0; i < 8; ++i) {
if (reel->frame() != 0xffff)
- showreelframe(reel);
+ showReelFrame(reel);
++reel;
}
- push(es);
- push(bx);
- soundonreels();
- bx = pop();
- es = pop();
-}
-
-void DreamGenContext::crosshair() {
- uint8 frame;
- if ((data.byte(kCommandtype) != 3) && (data.byte(kCommandtype) < 10)) {
- frame = 9;
- } else {
- frame = 29;
- }
- const Frame *src = (const Frame *)segRef(data.word(kIcons1)).ptr(0, 0);
- showframe(src, kZoomx + 24, kZoomy + 19, frame, 0);
+ soundOnReels(reelPointer);
}
-void DreamGenContext::deltextline() {
- uint16 x = data.word(kTextaddressx);
- uint16 y = data.word(kTextaddressy);
- if (data.byte(kForeignrelease) != 0)
- y -= 3;
- multiput(segRef(data.word(kBuffers)).ptr(kTextunder, 0), x, y, kUndertextsizex, kUndertextsizey);
-}
-
-void DreamGenContext::commandonly() {
- commandonly(al);
+void DreamWebEngine::delTextLine() {
+ if (_foreignRelease)
+ multiPut(_textUnder, _textAddressX, _textAddressY - 3, kUnderTextSizeX_f, kUnderTextSizeY_f);
+ else
+ multiPut(_textUnder, _textAddressX, _textAddressY, kUnderTextSizeX, kUnderTextSizeY);
}
-void DreamGenContext::commandonly(uint8 command) {
- deltextline();
- uint16 index = command * 2;
- uint16 offset = kTextstart + segRef(data.word(kCommandtext)).word(index);
- uint16 y = data.word(kTextaddressy);
- const uint8 *string = segRef(data.word(kCommandtext)).ptr(offset, 0);
- printdirect(&string, data.word(kTextaddressx), &y, data.byte(kTextlen), (bool)(data.byte(kTextlen) & 1));
- data.byte(kNewtextline) = 1;
+void DreamWebEngine::commandOnlyCond(uint8 command, uint8 commandType) {
+ if (_commandType != commandType) {
+ _commandType = commandType;
+ commandOnly(command);
+ }
}
-void DreamGenContext::checkifperson() {
- flags._z = !checkifperson(al, ah);
+void DreamWebEngine::commandOnly(uint8 command) {
+ delTextLine();
+ const uint8 *string = (const uint8 *)_commandText.getString(command);
+ printDirect(string, _textAddressX, _textAddressY, _textLen, (bool)(_textLen & 1));
+ _newTextLine = 1;
}
-bool DreamGenContext::checkifperson(uint8 x, uint8 y) {
- People *people = (People *)segRef(data.word(kBuffers)).ptr(kPeoplelist, 0);
-
- for (size_t i = 0; i < 12; ++i, ++people) {
- if (people->b4 == 255)
- continue;
- data.word(kReelpointer) = people->reelPointer();
- Reel *reel = getreelstart();
+bool DreamWebEngine::checkIfPerson(uint8 x, uint8 y) {
+ Common::List<People>::iterator i;
+ for (i = _peopleList.begin(); i != _peopleList.end(); ++i) {
+ People &people = *i;
+ Reel *reel = getReelStart(people._reelPointer);
if (reel->frame() == 0xffff)
++reel;
- const Frame *frame = getreelframeax(reel->frame());
+ const Frame *frame = getReelFrameAX(reel->frame());
uint8 xmin = reel->x + frame->x;
uint8 ymin = reel->y + frame->y;
uint8 xmax = xmin + frame->width;
@@ -999,89 +1213,58 @@ bool DreamGenContext::checkifperson(uint8 x, uint8 y) {
continue;
if (y >= ymax)
continue;
- data.word(kPersondata) = people->routinePointer();
- obname(people->b4, 5);
+ _personData = people._routinePointer;
+ obName(people.b4, 5);
return true;
}
return false;
}
-void DreamGenContext::checkiffree() {
- flags._z = !checkiffree(al, ah);
-}
-
-bool DreamGenContext::checkiffree(uint8 x, uint8 y) {
- const ObjPos *freeList = (const ObjPos *)segRef(data.word(kBuffers)).ptr(kFreelist, 80 * sizeof(ObjPos));
- for (size_t i = 0; i < 80; ++i) {
- const ObjPos *objPos = freeList + 79 - i;
- if (objPos->index == 0xff)
+bool DreamWebEngine::checkIfFree(uint8 x, uint8 y) {
+ Common::List<ObjPos>::const_iterator i;
+ for (i = _freeList.reverse_begin(); i != _freeList.end(); --i) {
+ const ObjPos &pos = *i;
+ assert(pos.index != 0xff);
+ if (!pos.contains(x,y))
continue;
- if (x < objPos->xMin)
- continue;
- if (x >= objPos->xMax)
- continue;
- if (y < objPos->yMin)
- continue;
- if (y >= objPos->yMax)
- continue;
- obname(objPos->index, 2);
+ obName(pos.index, 2);
return true;
}
return false;
}
-void DreamGenContext::checkifex() {
- flags._z = !checkifex(al, ah);
-}
-
-bool DreamGenContext::checkifex(uint8 x, uint8 y) {
- const ObjPos *exList = (const ObjPos *)segRef(data.word(kBuffers)).ptr(kExlist, 100 * sizeof(ObjPos));
- for (size_t i = 0; i < 100; ++i) {
- const ObjPos *objPos = exList + 99 - i;
- if (objPos->index == 0xff)
- continue;
- if (x < objPos->xMin)
- continue;
- if (x >= objPos->xMax)
+bool DreamWebEngine::checkIfEx(uint8 x, uint8 y) {
+ Common::List<ObjPos>::const_iterator i;
+ for (i = _exList.reverse_begin(); i != _exList.end(); --i) {
+ const ObjPos &pos = *i;
+ assert(pos.index != 0xff);
+ if (!pos.contains(x,y))
continue;
- if (y < objPos->yMin)
- continue;
- if (y >= objPos->yMax)
- continue;
- obname(objPos->index, 4);
+ obName(pos.index, 4);
return true;
}
return false;
}
-const uint8 *DreamGenContext::findobname(uint8 type, uint8 index) {
- if (type == 5) {
- uint16 i = 64 * 2 * (index & 127);
- uint16 offset = segRef(data.word(kPeople)).word(kPersontxtdat + i) + kPersontext;
- return segRef(data.word(kPeople)).ptr(offset, 0);
- } else if (type == 4) {
- uint16 offset = segRef(data.word(kExtras)).word(kExtextdat + index * 2) + kExtext;
- return segRef(data.word(kExtras)).ptr(offset, 0);
- } else if (type == 2) {
- uint16 offset = segRef(data.word(kFreedesc)).word(kFreetextdat + index * 2) + kFreetext;
- return segRef(data.word(kFreedesc)).ptr(offset, 0);
- } else if (type == 1) {
- uint16 offset = segRef(data.word(kSetdesc)).word(kSettextdat + index * 2) + kSettext;
- return segRef(data.word(kSetdesc)).ptr(offset, 0);
- } else {
- uint16 offset = segRef(data.word(kBlockdesc)).word(kBlocktextdat + index * 2) + kBlocktext;
- return segRef(data.word(kBlockdesc)).ptr(offset, 0);
+const uint8 *DreamWebEngine::findObName(uint8 type, uint8 index) {
+ switch (type) {
+ case 5:
+ return (const uint8 *)_personText.getString(64 * (index & 127));
+ case kExObjectType:
+ return (const uint8 *)_exText.getString(index);
+ case kFreeObjectType:
+ return (const uint8 *)_freeDesc.getString(index);
+ case kSetObjectType1:
+ return (const uint8 *)_setDesc.getString(index);
+ default:
+ return (const uint8 *)_blockDesc.getString(index);
}
}
-void DreamGenContext::copyname() {
- copyname(ah, al, cs.ptr(di, 0));
-}
-
-void DreamGenContext::copyname(uint8 type, uint8 index, uint8 *dst) {
- const uint8 *src = findobname(type, index);
+void DreamWebEngine::copyName(uint8 type, uint8 index, uint8 *dst) {
+ const uint8 *src = findObName(type, index);
size_t i;
- for (i = 0; i < 28; ++i) {
+ for (i = 0; i < 28; ++i) {
char c = src[i];
if (c == ':')
break;
@@ -1092,751 +1275,551 @@ void DreamGenContext::copyname(uint8 type, uint8 index, uint8 *dst) {
dst[i] = 0;
}
-void DreamGenContext::commandwithob() {
- commandwithob(al, bh, bl);
-}
-
-void DreamGenContext::commandwithob(uint8 command, uint8 type, uint8 index) {
+void DreamWebEngine::commandWithOb(uint8 command, uint8 type, uint8 index) {
uint8 commandLine[64] = "OBJECT NAME ONE ";
- deltextline();
- uint16 commandText = kTextstart + segRef(data.word(kCommandtext)).word(command * 2);
- uint8 textLen = data.byte(kTextlen);
- {
- const uint8 *string = segRef(data.word(kCommandtext)).ptr(commandText, 0);
- printdirect(string, data.word(kTextaddressx), data.word(kTextaddressy), textLen, (bool)(textLen & 1));
- }
- copyname(type, index, commandLine);
- uint16 x = data.word(kLastxpos);
- if (command != 0)
- x += 5;
- printdirect(commandLine, x, data.word(kTextaddressy), textLen, (bool)(textLen & 1));
- data.byte(kNewtextline) = 1;
-}
+ delTextLine();
+ uint8 textLen = _textLen;
-void DreamGenContext::examineobtext() {
- commandwithob(1, data.byte(kCommandtype), data.byte(kCommand));
-}
+ const uint8 *string = (const uint8 *)_commandText.getString(command);
+ printDirect(string, _textAddressX, _textAddressY, textLen, (bool)(textLen & 1));
-void DreamGenContext::showpanel() {
- Frame *frame = (Frame *)segRef(data.word(kIcons1)).ptr(0, sizeof(Frame));
- showframe(frame, 72, 0, 19, 0);
- showframe(frame, 192, 0, 19, 0);
+ copyName(type, index, commandLine);
+ uint16 x = _lastXPos;
+ if (command != 0)
+ x += 5;
+ printDirect(commandLine, x, _textAddressY, textLen, (bool)(textLen & 1));
+ _newTextLine = 1;
}
-void DreamGenContext::blocknametext() {
- commandwithob(0, data.byte(kCommandtype), data.byte(kCommand));
+void DreamWebEngine::examineObText() {
+ commandWithOb(1, _commandType, _command);
}
-void DreamGenContext::personnametext() {
- commandwithob(2, data.byte(kCommandtype), data.byte(kCommand) & 127);
+void DreamWebEngine::blockNameText() {
+ commandWithOb(0, _commandType, _command);
}
-void DreamGenContext::walktotext() {
- commandwithob(3, data.byte(kCommandtype), data.byte(kCommand));
+void DreamWebEngine::personNameText() {
+ commandWithOb(2, _commandType, _command & 127);
}
-void DreamGenContext::findormake() {
- uint8 b0 = al;
- uint8 b2 = cl;
- uint8 b3 = ch;
- findormake(b0, b2, b3);
+void DreamWebEngine::walkToText() {
+ commandWithOb(3, _commandType, _command);
}
-void DreamGenContext::findormake(uint8 index, uint8 value, uint8 type) {
- Change *change = (Change *)segRef(data.word(kBuffers)).ptr(kListofchanges, sizeof(Change));
- while (true) {
- if (change->index == 0xff) {
- change->index = index;
- change->location = data.byte(kReallocation);
- change->value = value;
- change->type = type;
- return;
- }
- if ((index == change->index) && (data.byte(kReallocation) == change->location) && (type == change->type)) {
+void DreamWebEngine::findOrMake(uint8 index, uint8 value, uint8 type) {
+ Change *change = _listOfChanges;
+ for (; change->index != 0xff; ++change) {
+ if (index == change->index && _realLocation == change->location && type == change->type) {
change->value = value;
return;
}
- ++change;
}
+
+ change->index = index;
+ change->location = _realLocation;
+ change->value = value;
+ change->type = type;
}
-void DreamGenContext::setallchanges() {
- Change *change = (Change *)segRef(data.word(kBuffers)).ptr(kListofchanges, sizeof(Change));
- while (change->index != 0xff) {
- if (change->location == data.byte(kReallocation))
- dochange(change->index, change->value, change->type);
- ++change;
- }
+void DreamWebEngine::setAllChanges() {
+ Change *change = _listOfChanges;
+ for (; change->index != 0xff; ++change)
+ if (change->location == _realLocation)
+ doChange(change->index, change->value, change->type);
}
-DynObject *DreamGenContext::getfreead(uint8 index) {
- return (DynObject *)segRef(data.word(kFreedat)).ptr(0, 0) + index;
+DynObject *DreamWebEngine::getFreeAd(uint8 index) {
+ return &_freeDat[index];
}
-DynObject *DreamGenContext::getexad(uint8 index) {
- return (DynObject *)segRef(data.word(kExtras)).ptr(kExdata, 0) + index;
+DynObject *DreamWebEngine::getExAd(uint8 index) {
+ return &_exData[index];
}
-DynObject *DreamGenContext::geteitheradCPP() {
- if (data.byte(kObjecttype) == 4)
- return getexad(data.byte(kItemframe));
+DynObject *DreamWebEngine::getEitherAd() {
+ if (_objectType == kExObjectType)
+ return getExAd(_itemFrame);
else
- return getfreead(data.byte(kItemframe));
+ return getFreeAd(_itemFrame);
}
-void *DreamGenContext::getanyad(uint8 *value1, uint8 *value2) {
- if (data.byte(kObjecttype) == 4) {
- DynObject *exObject = getexad(data.byte(kCommand));
- *value1 = exObject->b7;
- *value2 = exObject->b8;
+void *DreamWebEngine::getAnyAd(uint8 *slotSize, uint8 *slotCount) {
+ if (_objectType == kExObjectType) {
+ DynObject *exObject = getExAd(_command);
+ *slotSize = exObject->slotSize;
+ *slotCount = exObject->slotCount;
return exObject;
- } else if (data.byte(kObjecttype) == 2) {
- DynObject *freeObject = getfreead(data.byte(kCommand));
- *value1 = freeObject->b7;
- *value2 = freeObject->b8;
+ } else if (_objectType == kFreeObjectType) {
+ DynObject *freeObject = getFreeAd(_command);
+ *slotSize = freeObject->slotSize;
+ *slotCount = freeObject->slotCount;
return freeObject;
- } else {
- SetObject *setObject = getsetad(data.byte(kCommand));
- *value1 = setObject->b4;
- *value2 = setObject->priority;
+ } else { // 1 or 3. 0 should never happen
+ SetObject *setObject = getSetAd(_command);
+ // Note: the original returned slotCount/priority (bytes 4 and 5)
+ // instead of slotSize/slotCount (bytes 3 and 4).
+ // Changed this for consistency with the Ex/Free cases, and also
+ // with getOpenedSize()
+ *slotSize = setObject->slotSize;
+ *slotCount = setObject->slotCount;
return setObject;
}
}
-void *DreamGenContext::getanyaddir(uint8 index, uint8 flag) {
- if (flag == 4)
- return getexad(index);
- else if (flag == 2)
- return getfreead(index);
+void *DreamWebEngine::getAnyAdDir(uint8 index, uint8 flag) {
+ if (flag == kExObjectType)
+ return getExAd(index);
+ else if (flag == kFreeObjectType)
+ return getFreeAd(index);
else
- return getsetad(index);
+ return getSetAd(index);
}
-SetObject *DreamGenContext::getsetad(uint8 index) {
- return (SetObject *)segRef(data.word(kSetdat)).ptr(0, 0) + index;
+SetObject *DreamWebEngine::getSetAd(uint8 index) {
+ return &_setDat[index];
}
-void DreamGenContext::dochange() {
- dochange(al, cl, ch);
-}
-
-void DreamGenContext::dochange(uint8 index, uint8 value, uint8 type) {
+void DreamWebEngine::doChange(uint8 index, uint8 value, uint8 type) {
if (type == 0) { //object
- getsetad(index)->mapad[0] = value;
- } else if (type == 1) { //freeobject
- DynObject *freeObject = getfreead(index);
+ getSetAd(index)->mapad[0] = value;
+ } else if (type == 1) { //freeObject
+ DynObject *freeObject = getFreeAd(index);
if (freeObject->mapad[0] == 0xff)
freeObject->mapad[0] = value;
} else { //path
- bx = kPathdata + (type - 100) * 144 + index * 8;
- es = data.word(kReels);
- es.byte(bx+6) = value;
+ _pathData[type - 100].nodes[index].on = value;
}
}
-void DreamGenContext::deletetaken() {
- const DynObject *extraObjects = (const DynObject *)segRef(data.word(kExtras)).ptr(kExdata, 0);
- DynObject *freeObjects = (DynObject *)segRef(data.word(kFreedat)).ptr(0, 0);
- for(size_t i = 0; i < kNumexobjects; ++i) {
- uint8 location = extraObjects[i].initialLocation;
- if (location == data.byte(kReallocation)) {
- uint8 index = extraObjects[i].index;
- freeObjects[index].mapad[0] = 0xfe;
+void DreamWebEngine::deleteTaken() {
+ for (size_t i = 0; i < kNumexobjects; ++i) {
+ uint8 location = _exData[i].initialLocation;
+ if (location == _realLocation) {
+ uint8 index = _exData[i].index;
+ _freeDat[index].mapad[0] = 0xfe;
}
}
}
-void DreamGenContext::getexpos() {
- es = data.word(kExtras);
- const DynObject *objects = (const DynObject *)segRef(data.word(kExtras)).ptr(kExdata, sizeof(DynObject));
+uint8 DreamWebEngine::getExPos() {
+ DynObject *objects = _exData;
for (size_t i = 0; i < kNumexobjects; ++i) {
- if (objects[i].mapad[0] == 0xff) {
- data.byte(kExpos) = i;
- di = kExdata + i * sizeof(DynObject);
- return;
- }
+ if (objects[i].mapad[0] == 0xff)
+ return i;
}
- data.byte(kExpos) = kNumexobjects;
- di = kExdata + kNumexobjects * sizeof(DynObject);
-}
-
-void DreamGenContext::placesetobject() {
- placesetobject(al);
-}
-
-void DreamGenContext::placesetobject(uint8 index) {
- findormake(index, 0, 0);
- getsetad(index)->mapad[0] = 0;
+ error("Out of Ex object positions");
}
-void DreamGenContext::removesetobject() {
- removesetobject(al);
+void DreamWebEngine::placeSetObject(uint8 index) {
+ findOrMake(index, 0, 0);
+ getSetAd(index)->mapad[0] = 0;
}
-void DreamGenContext::removesetobject(uint8 index) {
- findormake(index, 0xff, 0);
- getsetad(index)->mapad[0] = 0xff;
+void DreamWebEngine::removeSetObject(uint8 index) {
+ findOrMake(index, 0xff, 0);
+ getSetAd(index)->mapad[0] = 0xff;
}
-void DreamGenContext::finishedwalking() {
- flags._z = finishedwalkingCPP();
+bool DreamWebEngine::finishedWalking() {
+ return (_linePointer == 254) && (_facing == _turnToFace);
}
-bool DreamGenContext::finishedwalkingCPP() {
- return (data.byte(kLinepointer) == 254) && (data.byte(kFacing) == data.byte(kTurntoface));
-}
-
-void DreamGenContext::getflagunderp() {
- uint8 flag, flagEx;
- getflagunderp(&flag, &flagEx);
- cl = flag;
- ch = flagEx;
-}
-
-void DreamGenContext::getflagunderp(uint8 *flag, uint8 *flagEx) {
+void DreamWebEngine::getFlagUnderP(uint8 *flag, uint8 *flagEx) {
uint8 type, flagX, flagY;
- checkone(data.word(kMousex) - data.word(kMapadx), data.word(kMousey) - data.word(kMapady), flag, flagEx, &type, &flagX, &flagY);
- cl = data.byte(kLastflag) = *flag;
- ch = data.byte(kLastflagex) = *flagEx;
+ checkOne(_mouseX - _mapAdX, _mouseY - _mapAdY, flag, flagEx, &type, &flagX, &flagY);
+ _lastFlag = *flag;
}
-void DreamGenContext::walkandexamine() {
- if (! finishedwalkingCPP())
+void DreamWebEngine::walkAndExamine() {
+ if (!finishedWalking())
return;
- data.byte(kCommandtype) = data.byte(kWalkexamtype);
- data.byte(kCommand) = data.byte(kWalkexamnum);
- data.byte(kWalkandexam) = 0;
- if (data.byte(kCommandtype) != 5)
- examineob();
-}
-
-void DreamGenContext::obname() {
- obname(al, ah);
-}
-
-void DreamGenContext::obname(uint8 command, uint8 commandType) {
- if (data.byte(kReasseschanges) == 0) {
- if ((commandType == data.byte(kCommandtype)) && (command == data.byte(kCommand))) {
- if (data.byte(kWalkandexam) == 1) {
- walkandexamine();
+ _commandType = _walkExamType;
+ _command = _walkExamNum;
+ _walkAndExam = 0;
+ if (_commandType != 5)
+ examineOb();
+}
+
+void DreamWebEngine::obName(uint8 command, uint8 commandType) {
+ if (_reAssesChanges == 0) {
+ if ((commandType == _commandType) && (command == _command)) {
+ if (_walkAndExam == 1) {
+ walkAndExamine();
return;
- } else if (data.word(kMousebutton) == 0)
+ } else if (_mouseButton == 0)
return;
- else if ((data.byte(kCommandtype) == 3) && (data.byte(kLastflag) < 2))
+ else if ((_commandType == 3) && (_lastFlag < 2))
return;
- else if ((data.byte(kManspath) != data.byte(kPointerspath)) || (data.byte(kCommandtype) == 3)) {
- setwalk();
- data.byte(kReasseschanges) = 1;
+ else if ((_mansPath != _pointersPath) || (_commandType == 3)) {
+ setWalk();
+ _reAssesChanges = 1;
return;
- } else if (! finishedwalkingCPP())
+ } else if (!finishedWalking())
return;
- else if (data.byte(kCommandtype) == 5) {
- if (data.word(kWatchingtime) == 0)
+ else if (_commandType == 5) {
+ if (_vars._watchingTime == 0)
talk();
return;
} else {
- if (data.word(kWatchingtime) == 0)
- examineob();
+ if (_vars._watchingTime == 0)
+ examineOb();
return;
}
}
} else
- data.byte(kReasseschanges) = 0;
+ _reAssesChanges = 0;
- data.byte(kCommand) = command;
- data.byte(kCommandtype) = commandType;
- if ((data.byte(kLinepointer) != 254) || (data.word(kWatchingtime) != 0) || (data.byte(kFacing) != data.byte(kTurntoface))) {
- blocknametext();
+ _command = command;
+ _commandType = commandType;
+ if ((_linePointer != 254) || (_vars._watchingTime != 0) || (_facing != _turnToFace)) {
+ blockNameText();
return;
- } else if (data.byte(kCommandtype) != 3) {
- if (data.byte(kManspath) != data.byte(kPointerspath)) {
- walktotext();
+ } else if (_commandType != 3) {
+ if (_mansPath != _pointersPath) {
+ walkToText();
return;
- } else if (data.byte(kCommandtype) == 3) {
- blocknametext();
+ } else if (_commandType == 3) {
+ blockNameText();
return;
- } else if (data.byte(kCommandtype) == 5) {
- personnametext();
+ } else if (_commandType == 5) {
+ personNameText();
return;
} else {
- examineobtext();
+ examineObText();
return;
}
}
- if (data.byte(kManspath) == data.byte(kPointerspath)) {
+ if (_mansPath == _pointersPath) {
uint8 flag, flagEx, type, flagX, flagY;
- checkone(data.byte(kRyanx) + 12, data.byte(kRyany) + 12, &flag, &flagEx, &type, &flagX, &flagY);
+ checkOne(_ryanX + 12, _ryanY + 12, &flag, &flagEx, &type, &flagX, &flagY);
if (flag < 2) {
- blocknametext();
+ blockNameText();
return;
}
}
- getflagunderp();
- if (data.byte(kLastflag) < 2) {
- blocknametext();
+ uint8 flag, flagEx;
+ getFlagUnderP(&flag, &flagEx);
+ if (_lastFlag < 2) {
+ blockNameText();
return;
- } else if (data.byte(kLastflag) >= 128) {
- blocknametext();
+ } else if (_lastFlag >= 128) {
+ blockNameText();
return;
} else {
- walktotext();
+ walkToText();
return;
}
}
-void DreamGenContext::delpointer() {
- if (data.word(kOldpointerx) == 0xffff)
+void DreamWebEngine::delPointer() {
+ if (_oldPointerX == 0xffff)
return;
- data.word(kDelherex) = data.word(kOldpointerx);
- data.word(kDelherey) = data.word(kOldpointery);
- data.byte(kDelxs) = data.byte(kPointerxs);
- data.byte(kDelys) = data.byte(kPointerys);
- multiput(segRef(data.word(kBuffers)).ptr(kPointerback, 0), data.word(kDelherex), data.word(kDelherey), data.byte(kPointerxs), data.byte(kPointerys));
+ _delHereX = _oldPointerX;
+ _delHereY = _oldPointerY;
+ _delXS = _pointerXS;
+ _delYS = _pointerYS;
+ multiPut(_pointerBack, _delHereX, _delHereY, _pointerXS, _pointerYS);
}
-void DreamGenContext::showblink() {
- if (data.byte(kManisoffscreen) == 1)
+void DreamWebEngine::showBlink() {
+ if (_manIsOffScreen == 1)
return;
- ++data.byte(kBlinkcount);
- if (data.byte(kShadeson) != 0)
+ ++_blinkCount;
+ if (_vars._shadesOn != 0)
return;
- if (data.byte(kReallocation) >= 50) // eyesshut
+ if (_realLocation >= 50) // eyesshut
return;
- if (data.byte(kBlinkcount) != 3)
+ if (_blinkCount != 3)
return;
- data.byte(kBlinkcount) = 0;
- uint8 blinkFrame = data.byte(kBlinkframe);
+ _blinkCount = 0;
+ uint8 blinkFrame = _blinkFrame;
++blinkFrame; // Implicit %256
- data.byte(kBlinkframe) = blinkFrame;
+ _blinkFrame = blinkFrame;
if (blinkFrame > 6)
blinkFrame = 6;
static const uint8 blinkTab[] = { 16,18,18,17,16,16,16 };
uint8 width, height;
- showframe((Frame *)segRef(data.word(kIcons1)).ptr(0, 0), 44, 32, blinkTab[blinkFrame], 0, &width, &height);
+ showFrame(_icons1, 44, 32, blinkTab[blinkFrame], 0, &width, &height);
}
-void DreamGenContext::dumpblink() {
- if (data.byte(kShadeson) != 0)
+void DreamWebEngine::dumpBlink() {
+ if (_vars._shadesOn != 0)
return;
- if (data.byte(kBlinkcount) != 0)
+ if (_blinkCount != 0)
return;
- if (data.byte(kBlinkframe) >= 6)
- return;
- multidump(44, 32, 16, 12);
-}
-
-void DreamGenContext::dumppointer() {
- dumpblink();
- multidump(data.word(kDelherex), data.word(kDelherey), data.byte(kDelxs), data.byte(kDelys));
- if ((data.word(kOldpointerx) != data.word(kDelherex)) || (data.word(kOldpointery) != data.word(kDelherey)))
- multidump(data.word(kOldpointerx), data.word(kOldpointery), data.byte(kPointerxs), data.byte(kPointerys));
-}
-
-void DreamGenContext::checkcoords() {
- checkcoords((const RectWithCallback *)cs.ptr(bx, 0));
-}
-
-void DreamGenContext::checkcoords(const RectWithCallback *rectWithCallbacks) {
- if (data.byte(kNewlocation) != 0xff)
+ if (_blinkFrame >= 6)
return;
-
- const RectWithCallback *rectWithCallback = rectWithCallbacks;
- while (rectWithCallback->xMin() != 0xffff) {
- if (rectWithCallback->contains(data.word(kMousex), data.word(kMousey))) {
- uint16 callback = rectWithCallback->callback();
-
- // common
- if(callback == addr_blank)
- blank();
- else if(callback == addr_getbackfromob)
- getbackfromob();
- else if(callback == addr_incryanpage)
- incryanpage();
- else if(callback == addr_getback1)
- getback1();
- else if(callback == addr_quitkey)
- quitkey();
- else if(callback == addr_dosreturn)
- dosreturn();
- else if(callback == addr_getbacktoops)
- getbacktoops();
- else if(callback == addr_selectslot)
- selectslot();
- // examlist
- else if(callback == addr_useobject)
- useobject();
- else if(callback == addr_selectopenob)
- selectopenob();
- else if(callback == addr_setpickup)
- setpickup();
- else if(callback == addr_examinventory)
- examinventory();
- // invlist1
- else if(callback == addr_dropobject)
- dropobject();
- else if(callback == addr_useopened)
- useopened();
- else if(callback == addr_setpickup)
- setpickup();
- else if(callback == addr_intoinv)
- intoinv();
- // withlist1
- else if(callback == addr_selectob)
- selectob();
- // talklist
- else if(callback == addr_moretalk)
- moretalk();
- // quitlist
- // destlist
- else if(callback == addr_nextdest)
- nextdest();
- else if(callback == addr_lastdest)
- lastdest();
- else if(callback == addr_lookatplace)
- lookatplace();
- else if(callback == addr_destselect)
- destselect();
- // keypadlist
- else if(callback == addr_buttonone)
- buttonone();
- else if(callback == addr_buttontwo)
- buttontwo();
- else if(callback == addr_buttonthree)
- buttonthree();
- else if(callback == addr_buttonfour)
- buttonfour();
- else if(callback == addr_buttonfive)
- buttonfive();
- else if(callback == addr_buttonsix)
- buttonsix();
- else if(callback == addr_buttonseven)
- buttonseven();
- else if(callback == addr_buttoneight)
- buttoneight();
- else if(callback == addr_buttonnine)
- buttonnine();
- else if(callback == addr_buttonnought)
- buttonnought();
- else if(callback == addr_buttonenter)
- buttonenter();
- // menulist
- // folderlist
- else if(callback == addr_nextfolder)
- nextfolder();
- else if(callback == addr_lastfolder)
- lastfolder();
- // symbollist
- else if(callback == addr_quitsymbol)
- quitsymbol();
- else if(callback == addr_settopleft)
- settopleft();
- else if(callback == addr_settopright)
- settopright();
- else if(callback == addr_setbotleft)
- setbotleft();
- else if(callback == addr_setbotright)
- setbotright();
- // diarylist
- else if(callback == addr_diarykeyn)
- diarykeyn();
- else if(callback == addr_diarykeyp)
- diarykeyp();
- else if(callback == addr_quitkey)
- quitkey();
- // opslist
- else if(callback == addr_getbackfromops)
- getbackfromops();
- else if(callback == addr_discops)
- discops();
- // discopslist
- else if(callback == addr_loadgame)
- loadgame();
- else if(callback == addr_savegame)
- savegame();
- // mainlist, mainlist2
- else if(callback == addr_look)
- look();
- else if(callback == addr_inventory)
- inventory();
- else if(callback == addr_zoomonoff)
- zoomonoff();
- else if(callback == addr_saveload)
- saveload();
- else if(callback == addr_madmanrun)
- madmanrun();
- else if(callback == addr_identifyob)
- identifyob();
- // decidelist
- else if(callback == addr_newgame)
- newgame();
- else if(callback == addr_loadold)
- loadold();
- // loadlist
- else if(callback == addr_actualload)
- actualload();
- // savelist
- else if(callback == addr_actualsave)
- actualsave();
- else {
- debug("__dispatch_call remaining in checkcoords! %d", (int)callback);
- __dispatch_call(callback);
- }
- return;
- }
- ++rectWithCallback;
- }
-}
-
-void DreamGenContext::showpointer() {
- showblink();
- const Frame *icons1 = ((const Frame *)segRef(data.word(kIcons1)).ptr(0, 0));
- uint16 x = data.word(kMousex);
- data.word(kOldpointerx) = data.word(kMousex);
- uint16 y = data.word(kMousey);
- data.word(kOldpointery) = data.word(kMousey);
- if (data.byte(kPickup) == 1) {
- const Frame *frames;
- if (data.byte(kObjecttype) != 4)
- frames = (const Frame *)segRef(data.word(kFreeframes)).ptr(0, 0);
+ multiDump(44, 32, 16, 12);
+}
+
+void DreamWebEngine::dumpPointer() {
+ dumpBlink();
+ multiDump(_delHereX, _delHereY, _delXS, _delYS);
+ if ((_oldPointerX != _delHereX) || (_oldPointerY != _delHereY))
+ multiDump(_oldPointerX, _oldPointerY, _pointerXS, _pointerYS);
+}
+
+void DreamWebEngine::showPointer() {
+ showBlink();
+ uint16 x = _mouseX;
+ _oldPointerX = _mouseX;
+ uint16 y = _mouseY;
+ _oldPointerY = _mouseY;
+ if (_pickUp == 1) {
+ const GraphicsFile *frames;
+ if (_objectType != kExObjectType)
+ frames = &_freeFrames;
else
- frames = (const Frame *)segRef(data.word(kExtras)).ptr(0, 0);
- const Frame *frame = frames + (3 * data.byte(kItemframe) + 1);
+ frames = &_exFrames;
+ const Frame *frame = &frames->_frames[(3 * _itemFrame + 1)];
+
uint8 width = frame->width;
uint8 height = frame->height;
if (width < 12)
width = 12;
if (height < 12)
height = 12;
- data.byte(kPointerxs) = width;
- data.byte(kPointerys) = height;
+ _pointerXS = width;
+ _pointerYS = height;
uint16 xMin = (x >= width / 2) ? x - width / 2 : 0;
uint16 yMin = (y >= height / 2) ? y - height / 2 : 0;
- data.word(kOldpointerx) = xMin;
- data.word(kOldpointery) = yMin;
- multiget(segRef(data.word(kBuffers)).ptr(kPointerback, 0), xMin, yMin, width, height);
- showframe(frames, x, y, 3 * data.byte(kItemframe) + 1, 128);
- showframe(icons1, x, y, 3, 128);
+ _oldPointerX = xMin;
+ _oldPointerY = yMin;
+ multiGet(_pointerBack, xMin, yMin, width, height);
+ showFrame(*frames, x, y, 3 * _itemFrame + 1, 128);
+ showFrame(_icons1, x, y, 3, 128);
} else {
- const Frame *frame = icons1 + (data.byte(kPointerframe) + 20);
+ const Frame *frame = &_icons1._frames[_pointerFrame + 20];
uint8 width = frame->width;
uint8 height = frame->height;
if (width < 12)
width = 12;
if (height < 12)
height = 12;
- data.byte(kPointerxs) = width;
- data.byte(kPointerys) = height;
- multiget(segRef(data.word(kBuffers)).ptr(kPointerback, 0), x, y, width, height);
- showframe(icons1, x, y, data.byte(kPointerframe) + 20, 0);
+ _pointerXS = width;
+ _pointerYS = height;
+ multiGet(_pointerBack, x, y, width, height);
+ showFrame(_icons1, x, y, _pointerFrame + 20, 0);
}
}
-void DreamGenContext::animpointer() {
+void DreamWebEngine::animPointer() {
- if (data.byte(kPointermode) == 2) {
- data.byte(kPointerframe) = 0;
- if ((data.byte(kReallocation) == 14) && (data.byte(kCommandtype) == 211))
- data.byte(kPointerframe) = 5;
+ if (_pointerMode == 2) {
+ _pointerFrame = 0;
+ if ((_realLocation == 14) && (_commandType == 211))
+ _pointerFrame = 5;
return;
- } else if (data.byte(kPointermode) == 3) {
- if (data.byte(kPointerspeed) != 0) {
- --data.byte(kPointerspeed);
+ } else if (_pointerMode == 3) {
+ if (_pointerSpeed != 0) {
+ --_pointerSpeed;
} else {
- data.byte(kPointerspeed) = 5;
- ++data.byte(kPointercount);
- if (data.byte(kPointercount) == 16)
- data.byte(kPointercount) = 0;
+ _pointerSpeed = 5;
+ ++_pointerCount;
+ if (_pointerCount == 16)
+ _pointerCount = 0;
}
static const uint8 flashMouseTab[] = { 1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2 };
- data.byte(kPointerframe) = flashMouseTab[data.byte(kPointercount)];
+ _pointerFrame = flashMouseTab[_pointerCount];
return;
}
- if (data.word(kWatchingtime) != 0) {
- data.byte(kPointerframe) = 11;
+ if (_vars._watchingTime != 0) {
+ _pointerFrame = 11;
return;
}
- data.byte(kPointerframe) = 0;
- if (data.byte(kInmaparea) == 0)
+ _pointerFrame = 0;
+ if (_inMapArea == 0)
return;
- if (data.byte(kPointerfirstpath) == 0)
+ if (_pointerFirstPath == 0)
return;
uint8 flag, flagEx;
- getflagunderp(&flag, &flagEx);
+ getFlagUnderP(&flag, &flagEx);
if (flag < 2)
return;
if (flag >= 128)
return;
if (flag & 4) {
- data.byte(kPointerframe) = 3;
+ _pointerFrame = 3;
return;
}
if (flag & 16) {
- data.byte(kPointerframe) = 4;
+ _pointerFrame = 4;
return;
}
if (flag & 2) {
- data.byte(kPointerframe) = 5;
+ _pointerFrame = 5;
return;
}
if (flag & 8) {
- data.byte(kPointerframe) = 6;
+ _pointerFrame = 6;
return;
}
- data.byte(kPointerframe) = 8;
+ _pointerFrame = 8;
}
-void DreamGenContext::printmessage() {
- printmessage(di, bx, al, dl, (bool)(dl & 1));
+void DreamWebEngine::printMessage(uint16 x, uint16 y, uint8 index, uint8 maxWidth, bool centered) {
+ const uint8 *string = (const uint8 *)_commandText.getString(index);
+ printDirect(string, x, y, maxWidth, centered);
}
-void DreamGenContext::printmessage(uint16 x, uint16 y, uint8 index, uint8 maxWidth, bool centered) {
- uint16 offset = kTextstart + segRef(data.word(kCommandtext)).word(index * 2);
- const uint8 *string = segRef(data.word(kCommandtext)).ptr(offset, 0);
- printdirect(&string, x, &y, maxWidth, centered);
-}
-
-void DreamGenContext::compare() {
- char id[4] = { cl, ch, dl, dh };
- flags._z = compare(al, ah, id);
+void DreamWebEngine::printMessage2(uint16 x, uint16 y, uint8 index, uint8 maxWidth, bool centered, uint8 count) {
+ const uint8 *string = (const uint8 *)_commandText.getString(index);
+ while (count--) {
+ findNextColon(&string);
+ }
+ printDirect(string, x, y, maxWidth, centered);
}
-bool DreamGenContext::compare(uint8 index, uint8 flag, const char id[4]) {
- void *ptr = getanyaddir(index, flag);
- const char *objId = (const char *)(((const uint8 *)ptr) + 12); // whether it is a DynObject or a SetObject
+bool DreamWebEngine::objectMatches(void *object, const char *id) {
+ const char *objId = (const char *)object + 12; // whether it is a DynObject or a SetObject
for (size_t i = 0; i < 4; ++i) {
- if(id[i] != objId[i] + 'A')
+ if (id[i] != objId[i] + 'A')
return false;
}
return true;
}
-bool DreamGenContext::isitdescribed(const ObjPos *pos) {
- uint16 offset = segRef(data.word(kSetdesc)).word(kSettextdat + pos->index * 2);
- uint8 result = segRef(data.word(kSetdesc)).byte(kSettext + offset);
- return result != 0;
+bool DreamWebEngine::compare(uint8 index, uint8 flag, const char id[4]) {
+ return objectMatches(getAnyAdDir(index, flag), id);
}
-bool DreamGenContext::isCD() {
- // The original sources has two codepaths depending if the game is 'if cd' or not
- // This is a hack to guess which version to use with the assumption that if we have a cd version
- // we managed to load the speech. At least it is isolated in this function and can be changed.
- // Maybe detect the version during game id?
- return (data.byte(kSpeechloaded) == 1);
+uint16 DreamWebEngine::findSetObject(const char *id) {
+ for (uint16 index = 0; index < 128; index++) {
+ if (objectMatches(getSetAd(index), id))
+ return index;
+ }
+
+ return 128;
}
-void DreamGenContext::checkifset() {
- flags._z = !checkifset(al, ah);
+uint16 DreamWebEngine::findExObject(const char *id) {
+ for (uint16 index = 0; index < kNumexobjects; index++) {
+ if (objectMatches(getExAd(index), id))
+ return index;
+ }
+
+ return kNumexobjects;
}
-bool DreamGenContext::checkifset(uint8 x, uint8 y) {
- const ObjPos *setList = (const ObjPos *)segRef(data.word(kBuffers)).ptr(kSetlist, sizeof(ObjPos) * 128);
- for (size_t i = 0; i < 128; ++i) {
- const ObjPos *pos = setList + 127 - i;
- if (pos->index == 0xff)
- continue;
- if (x < pos->xMin)
- continue;
- if (x >= pos->xMax)
- continue;
- if (y < pos->yMin)
- continue;
- if (y >= pos->yMax)
- continue;
- if (! pixelcheckset(pos, x, y))
- continue;
- if (! isitdescribed(pos))
- continue;
- obname(pos->index, 1);
- return true;
+bool DreamWebEngine::isRyanHolding(const char *id) {
+ for (uint16 index = 0; index < kNumexobjects; index++) {
+ DynObject *object = getExAd(index);
+ if (object->mapad[0] == 4 && objectMatches(object, id))
+ return true;
}
+
return false;
}
-void DreamGenContext::showryanpage() {
- Frame *icons1 = (Frame *)segRef(data.word(kIcons1)).ptr(0, 0);
- showframe(icons1, kInventx + 167, kInventy - 12, 12, 0);
- showframe(icons1, kInventx + 167 + 18 * data.byte(kRyanpage), kInventy - 12, 13 + data.byte(kRyanpage), 0);
+bool DreamWebEngine::isItDescribed(const ObjPos *pos) {
+ const char *string = _setDesc.getString(pos->index);
+ return string[0] != 0;
}
-void DreamGenContext::findallryan() {
- findallryan(es.ptr(di, 60));
+void DreamWebEngine::showIcon() {
+ if (_realLocation < 50) {
+ showPanel();
+ showMan();
+ roomName();
+ panelIcons1();
+ zoomIcon();
+ } else {
+ error("Unimplemented tempsprites code called");
+ // the tempsprites segment is never initialized, but used here.
+/*
+ Frame *tempSprites = (Frame *)getSegment(data.word(kTempsprites)).ptr(0, 0);
+ showFrame(tempSprites, 72, 2, 45, 0);
+ showFrame(tempSprites, 72+47, 2, 46, 0);
+ showFrame(tempSprites, 69-10, 21, 49, 0);
+ showFrame(tempSprites, 160+88, 2, 45, 4 & 0xfe);
+ showFrame(tempSprites, 160+43, 2, 46, 4 & 0xfe);
+ showFrame(tempSprites, 160+101, 21, 49, 4 & 0xfe);
+
+ // middle panel
+ showFrame(tempSprites, 72 + 47 + 20, 0, 48, 0);
+ showFrame(tempSprites, 72 + 19, 21, 47, 0);
+ showFrame(tempSprites, 160 + 23, 0, 48, 4);
+ showFrame(tempSprites, 160 + 71, 21, 47, 4);
+*/
+ }
}
-void DreamGenContext::findallryan(uint8 *inv) {
- memset(inv, 0xff, 60);
- for (size_t i = 0; i < kNumexobjects; ++i) {
- DynObject *extra = getexad(i);
- if (extra->mapad[0] != 4)
+bool DreamWebEngine::checkIfSet(uint8 x, uint8 y) {
+ Common::List<ObjPos>::const_iterator i;
+ for (i = _setList.reverse_begin(); i != _setList.end(); --i) {
+ const ObjPos &pos = *i;
+ assert(pos.index != 0xff);
+ if (!pos.contains(x,y))
+ continue;
+ if (!pixelCheckSet(&pos, x, y))
continue;
- if (extra->mapad[1] != 0xff)
+ if (!isItDescribed(&pos))
continue;
- uint8 slot = extra->mapad[2];
- assert(slot < 30);
- inv[2 * slot + 0] = i;
- inv[2 * slot + 1] = 4;
+ obName(pos.index, 1);
+ return true;
}
+ return false;
}
-void DreamGenContext::hangon() {
- hangon(cx);
+void DreamWebEngine::hangOn(uint16 frameCount) {
+ while (frameCount) {
+ vSync();
+ --frameCount;
+ if (_quitRequested)
+ break;
+ }
}
-void DreamGenContext::hangon(uint16 frameCount) {
+void DreamWebEngine::hangOnW(uint16 frameCount) {
while (frameCount) {
- vsync();
+ delPointer();
+ readMouse();
+ animPointer();
+ showPointer();
+ vSync();
+ dumpPointer();
--frameCount;
- if (data.byte(kQuitrequested))
+ if (_quitRequested)
break;
}
}
-void DreamGenContext::hangonp() {
- hangonp(cx);
-}
-
-void DreamGenContext::hangonp(uint16 count) {
- data.word(kMaintimer) = 0;
- uint8 pointerFrame = data.byte(kPointerframe);
- uint8 pickup = data.byte(kPickup);
- data.byte(kPointermode) = 3;
- data.byte(kPickup) = 0;
- data.byte(kCommandtype) = 255;
- readmouse();
- animpointer();
- showpointer();
- vsync();
- dumppointer();
- uint32 counter = count; // silence a signed/unsigned MSVC warning below
- for (uint32 i = 0; i < counter * 3; ++i) {
- delpointer();
- readmouse();
- animpointer();
- showpointer();
- vsync();
- dumppointer();
- if (data.byte(kQuitrequested))
+void DreamWebEngine::hangOnP(uint16 count) {
+ _mainTimer = 0;
+ uint8 pointerFrame = _pointerFrame;
+ uint8 pickup = _pickUp;
+ _pointerMode = 3;
+ _pickUp = 0;
+ _commandType = 255;
+ readMouse();
+ animPointer();
+ showPointer();
+ vSync();
+ dumpPointer();
+
+ count *= 3;
+ for (uint16 i = 0; i < count; ++i) {
+ delPointer();
+ readMouse();
+ animPointer();
+ showPointer();
+ vSync();
+ dumpPointer();
+ if (_quitRequested)
break;
- if (data.word(kMousebutton) == 0)
- continue;
- if (data.word(kMousebutton) != data.word(kOldbutton))
+ if (_mouseButton != 0 && _mouseButton != _oldButton)
break;
}
- delpointer();
- data.byte(kPointerframe) = pointerFrame;
- data.byte(kPickup) = pickup;
- data.byte(kPointermode) = 0;
-}
-
-void DreamGenContext::findnextcolon() {
- uint8 *initialString = es.ptr(si, 0);
- uint8 *string = initialString;
- al = findnextcolon(&string);
- si += (string - initialString);
+ delPointer();
+ _pointerFrame = pointerFrame;
+ _pickUp = pickup;
+ _pointerMode = 0;
}
-uint8 DreamGenContext::findnextcolon(uint8 **string) {
+uint8 DreamWebEngine::findNextColon(const uint8 **string) {
uint8 c;
do {
c = **string;
@@ -1845,46 +1828,1372 @@ uint8 DreamGenContext::findnextcolon(uint8 **string) {
return c;
}
-uint8 *DreamGenContext::getobtextstartCPP() {
- push(es);
- push(si);
- getobtextstart();
- uint8 *result = es.ptr(si, 0);
- si = pop();
- es = pop();
- return result;
+void DreamWebEngine::zoomOnOff() {
+ if (_vars._watchingTime != 0 || _pointerMode == 2) {
+ blank();
+ return;
+ }
+
+ commandOnlyCond(39, 222);
+
+ if (!(_mouseButton & 1) || (_mouseButton == _oldButton))
+ return;
+
+ _vars._zoomOn ^= 1;
+ createPanel();
+ _vars._newObs = 0;
+ drawFloor();
+ printSprites();
+ reelsOnScreen();
+ showIcon();
+ getUnderZoom();
+ underTextLine();
+ commandOnly(39);
+ readMouse();
+ workToScreenM();
+}
+
+void DreamWebEngine::sortOutMap() {
+ const uint8 *src = workspace();
+ uint8 *dst = _mapData;
+ for (uint16 y = 0; y < kMapHeight; ++y) {
+ memcpy(dst, src, kMapWidth);
+ dst += kMapWidth;
+ src += 132;
+ }
+}
+
+void DreamWebEngine::mainScreen() {
+ _inMapArea = 0;
+ if (_vars._watchOn == 1) {
+ RectWithCallback mainList[] = {
+ { 44,70,32,46,&DreamWebEngine::look },
+ { 0,50,0,180,&DreamWebEngine::inventory },
+ { 226,244,10,26,&DreamWebEngine::zoomOnOff },
+ { 226,244,26,40,&DreamWebEngine::saveLoad },
+ { 240,260,100,124,&DreamWebEngine::madmanRun },
+ { 0,320,0,200,&DreamWebEngine::identifyOb },
+ { 0xFFFF,0,0,0,0 }
+ };
+ checkCoords(mainList);
+ } else {
+ RectWithCallback mainList2[] = {
+ { 44,70,32,46,&DreamWebEngine::look },
+ { 0,50,0,180,&DreamWebEngine::inventory },
+ { 226+48,244+48,10,26,&DreamWebEngine::zoomOnOff },
+ { 226+48,244+48,26,40,&DreamWebEngine::saveLoad },
+ { 240,260,100,124,&DreamWebEngine::madmanRun },
+ { 0,320,0,200,&DreamWebEngine::identifyOb },
+ { 0xFFFF,0,0,0,0 }
+ };
+ checkCoords(mainList2);
+ }
+
+ if (_walkAndExam != 0)
+ walkAndExamine();
+}
+
+void DreamWebEngine::showWatch() {
+ if (_vars._watchOn) {
+ showFrame(_icons1, 250, 1, 6, 0);
+ showTime();
+ }
+}
+
+void DreamWebEngine::dumpWatch() {
+ if (_watchDump != 1)
+ return;
+ multiDump(256, 21, 40, 12);
+ _watchDump = 0;
+}
+
+void DreamWebEngine::showTime() {
+ if (_vars._watchOn == 0)
+ return;
+
+ int seconds = _vars._secondCount;
+ int minutes = _vars._minuteCount;
+ int hours = _vars._hourCount;
+
+ showFrame(_charset1, 282+5, 21, 91*3+10 + seconds / 10, 0);
+ showFrame(_charset1, 282+9, 21, 91*3+10 + seconds % 10, 0);
+
+ showFrame(_charset1, 270+5, 21, 91*3 + minutes / 10, 0);
+ showFrame(_charset1, 270+11, 21, 91*3 + minutes % 10, 0);
+
+ showFrame(_charset1, 256+5, 21, 91*3 + hours / 10, 0);
+ showFrame(_charset1, 256+11, 21, 91*3 + hours % 10, 0);
+
+ showFrame(_charset1, 267+5, 21, 91*3+20, 0);
+}
+
+void DreamWebEngine::watchCount() {
+ if (_vars._watchOn == 0)
+ return;
+ ++_timerCount;
+ if (_timerCount == 9) {
+ showFrame(_charset1, 268+4, 21, 91*3+21, 0);
+ _watchDump = 1;
+ } else if (_timerCount == 18) {
+ _timerCount = 0;
+ ++_vars._secondCount;
+ if (_vars._secondCount == 60) {
+ _vars._secondCount = 0;
+ ++_vars._minuteCount;
+ if (_vars._minuteCount == 60) {
+ _vars._minuteCount = 0;
+ ++_vars._hourCount;
+ if (_vars._hourCount == 24)
+ _vars._hourCount = 0;
+ }
+ }
+ showTime();
+ _watchDump = 1;
+ }
}
-void DreamGenContext::zoomonoff() {
- if (data.word(kWatchingtime) != 0) {
+void DreamWebEngine::roomName() {
+ printMessage(88, 18, 53, 240, false);
+ uint16 textIndex = _roomNum;
+ if (textIndex >= 32)
+ textIndex -= 32;
+ _lineSpacing = 7;
+ uint8 maxWidth = (_vars._watchOn == 1) ? 120 : 160;
+ const uint8 *string = (const uint8 *)_roomDesc.getString(textIndex);
+ printDirect(string, 88, 25, maxWidth, false);
+ _lineSpacing = 10;
+ useCharset1();
+}
+
+void DreamWebEngine::loadRoom() {
+ _roomLoaded = 1;
+ _timeCount = 0;
+ _mainTimer = 0;
+ _mapOffsetX = 104;
+ _mapOffsetY = 38;
+ _textAddressX = 13;
+ _textAddressY = 182;
+ _textLen = 240;
+ _vars._location = _newLocation;
+ const Room &room = g_roomData[_newLocation];
+ startLoading(room);
+ loadRoomsSample();
+ switchRyanOn();
+ drawFlags();
+
+ uint8 mapXstart, mapYstart;
+ uint8 mapXsize, mapYsize;
+ getDimension(&mapXstart, &mapYstart, &mapXsize, &mapYsize);
+}
+
+void DreamWebEngine::readSetData() {
+ loadGraphicsFile(_charset1, "C00");
+ loadGraphicsFile(_icons1, "G00");
+ loadGraphicsFile(_icons2, "G01");
+ loadGraphicsFile(_mainSprites, "S00");
+ loadTextFile(_puzzleText, "T80");
+ loadTextFile(_commandText, "T84");
+ useCharset1();
+
+ // FIXME: Why is this commented out?
+ //openFile(getDatafilePrefix() + "VOL");
+ //uint8 *volumeTab = getSegment(data.word(kSoundbuffer)).ptr(16384, 0);
+ //readFromFile(volumeTab, 2048-256);
+ //closeFile();
+}
+
+void DreamWebEngine::findRoomInLoc() {
+ uint8 x = _mapX / 11;
+ uint8 y = _mapY / 10;
+ uint8 roomNum = y * 6 + x;
+ _roomNum = roomNum;
+}
+
+void DreamWebEngine::autoLook() {
+ if ((_mouseX != _oldX) || (_mouseY != _oldY)) {
+ _lookCounter = 1000;
+ return;
+ }
+
+ --_lookCounter;
+ if (_lookCounter)
+ return;
+ if (_vars._watchingTime)
+ return;
+ doLook();
+}
+
+void DreamWebEngine::look() {
+ if (_vars._watchingTime || (_pointerMode == 2)) {
blank();
return;
}
- if (data.byte(kPointermode) == 2) {
+ commandOnlyCond(25, 241);
+ if ((_mouseButton == 1) && (_mouseButton != _oldButton))
+ doLook();
+}
+
+void DreamWebEngine::doLook() {
+ createPanel();
+ showIcon();
+ underTextLine();
+ workToScreenM();
+ _commandType = 255;
+ dumpTextLine();
+ uint8 index = _roomNum & 31;
+ const uint8 *string = (const uint8 *)_roomDesc.getString(index);
+ findNextColon(&string);
+ uint16 x;
+ if (_realLocation < 50)
+ x = 66;
+ else
+ x = 40;
+ if (printSlow(string, x, 80, 241, true) != 1)
+ hangOnP(400);
+
+ _pointerMode = 0;
+ _commandType = 0;
+ redrawMainScrn();
+ workToScreenM();
+}
+
+void DreamWebEngine::useCharset1() {
+ _currentCharset = &_charset1;
+}
+
+void DreamWebEngine::useTempCharset(GraphicsFile *charset) {
+ _currentCharset = charset;
+}
+
+void DreamWebEngine::getRidOfTempText() {
+ _textFile1.clear();
+}
+
+void DreamWebEngine::getRidOfAll() {
+ delete[] _backdropBlocks;
+ _backdropBlocks = 0;
+
+ _setFrames.clear();
+ _reel1.clear();
+ _reel2.clear();
+ _reel3.clear();
+ delete[] _reelList;
+ _reelList = 0;
+ _personText.clear();
+ _setDesc.clear();
+ _blockDesc.clear();
+ _roomDesc.clear();
+ _freeFrames.clear();
+ _freeDesc.clear();
+}
+
+// if skipDat, skip clearing and loading Setdat and Freedat
+void DreamWebEngine::loadRoomData(const Room &room, bool skipDat) {
+ processEvents();
+ Common::File file;
+ if (!file.open(room.name))
+ error("cannot open file %s", room.name);
+
+ FileHeader header;
+ file.read((uint8 *)&header, sizeof(FileHeader));
+
+ // read segment lengths from room file header
+ unsigned int len[15];
+ for (int i = 0; i < 15; ++i)
+ len[i] = header.len(i);
+
+ assert(len[0] >= 192);
+ _backdropBlocks = new uint8[len[0] - 192];
+ file.read((uint8 *)_backdropFlags, 192);
+ file.read(_backdropBlocks, len[0] - 192);
+
+ assert(len[1] <= 132*66); // 132*66 = maplen
+ memset(workspace(), 0, 132*66);
+ file.read(workspace(), len[1]);
+
+ sortOutMap();
+
+ loadGraphicsSegment(_setFrames, file, len[2]);
+ if (!skipDat) {
+ const uint16 kSetdatlen = 64*128;
+ assert(len[3] <= kSetdatlen);
+ memset(_setDat, 255, kSetdatlen);
+ file.read(_setDat, len[3]);
+ } else {
+ file.skip(len[3]);
+ }
+ // NB: The skipDat version of this function as called by restoreall
+ // had a 'call bloc' instead of 'call loadseg' for reel1,
+ // but 'bloc' was not defined.
+ loadGraphicsSegment(_reel1, file, len[4]);
+ loadGraphicsSegment(_reel2, file, len[5]);
+ loadGraphicsSegment(_reel3, file, len[6]);
+
+ // segment 7 consists of 36 RoomPaths followed by 'reelList'
+ delete[] _reelList;
+ if (len[7] <= 36*sizeof(RoomPaths)) {
+ file.read((uint8 *)_pathData, len[7]);
+ _reelList = 0;
+ } else {
+ file.read((uint8 *)_pathData, 36*sizeof(RoomPaths));
+ unsigned int reelLen = len[7] - 36*sizeof(RoomPaths);
+ unsigned int reelCount = (reelLen + sizeof(Reel) - 1) / sizeof(Reel);
+ _reelList = new Reel[reelCount];
+ file.read((uint8 *)_reelList, reelLen);
+ }
+
+ // segment 8 consists of 12 personFrames followed by a TextFile
+ file.read((uint8 *)_personFramesLE, 24);
+ loadTextSegment(_personText, file, len[8] - 24);
+
+ loadTextSegment(_setDesc, file, len[9]);
+ loadTextSegment(_blockDesc, file, len[10]);
+ loadTextSegment(_roomDesc, file, len[11]);
+ loadGraphicsSegment(_freeFrames, file, len[12]);
+ if (!skipDat) {
+ const uint16 kFreedatlen = 16*80;
+ assert(len[13] <= kFreedatlen);
+ memset(_freeDat, 255, kFreedatlen);
+ file.read(_freeDat, len[13]);
+ } else {
+ file.skip(len[13]);
+ }
+ loadTextSegment(_freeDesc, file, len[14]);
+
+ processEvents();
+}
+
+void DreamWebEngine::restoreAll() {
+ const Room &room = g_roomData[_vars._location];
+ loadRoomData(room, true);
+ setAllChanges();
+}
+
+void DreamWebEngine::restoreReels() {
+ if (_roomLoaded == 0)
+ return;
+
+ const Room &room = g_roomData[_realLocation];
+
+ processEvents();
+ Common::File file;
+ if (!file.open(room.name))
+ error("cannot open file %s", room.name);
+
+ FileHeader header;
+ file.read((uint8 *)&header, sizeof(FileHeader));
+
+ // read segment lengths from room file header
+ int len[15];
+ for (int i = 0; i < 15; ++i)
+ len[i] = header.len(i);
+
+ file.skip(len[0]);
+ file.skip(len[1]);
+ file.skip(len[2]);
+ file.skip(len[3]);
+ loadGraphicsSegment(_reel1, file, len[4]);
+ loadGraphicsSegment(_reel2, file, len[5]);
+ loadGraphicsSegment(_reel3, file, len[6]);
+
+ processEvents();
+}
+
+void DreamWebEngine::showExit() {
+ showFrame(_icons1, 274, 154, 11, 0);
+}
+
+void DreamWebEngine::showMan() {
+ showFrame(_icons1, 0, 0, 0, 0);
+ showFrame(_icons1, 0, 114, 1, 0);
+ if (_vars._shadesOn)
+ showFrame(_icons1, 28, 25, 2, 0);
+}
+
+void DreamWebEngine::panelIcons1() {
+ uint16 x;
+ if (_vars._watchOn != 1)
+ x = 48;
+ else
+ x = 0;
+ showFrame(_icons2, 204 + x, 4, 2, 0);
+ if (_vars._zoomOn != 1)
+ showFrame(_icons1, 228 + x, 8, 5, 0);
+ showWatch();
+}
+
+void DreamWebEngine::examIcon() {
+ showFrame(_icons2, 254, 5, 3, 0);
+}
+
+const uint8 *DreamWebEngine::getTextInFile1(uint16 index) {
+ return (const uint8 *)_textFile1.getString(index);
+}
+
+void DreamWebEngine::loadTravelText() {
+ loadTextFile(_travelText, "T81"); // location descs
+}
+
+void DreamWebEngine::loadTempText(const char *suffix) {
+ loadTextFile(_textFile1, suffix);
+}
+
+void DreamWebEngine::drawFloor() {
+ eraseOldObs();
+ drawFlags();
+ calcMapAd();
+ doBlocks();
+ showAllObs();
+ showAllFree();
+ showAllEx();
+ panelToMap();
+ initRain();
+ _vars._newObs = 0;
+}
+
+void DreamWebEngine::allocateBuffers() {
+ _exFrames.clear();
+ _exFrames._data = new uint8[kExframeslen];
+ _exFrames._frames = new Frame[kGraphicsFileFrameSize];
+ _exText.clear();
+ _exText._text = new char[kExtextlen];
+}
+
+void DreamWebEngine::workToScreenM() {
+ animPointer();
+ readMouse();
+ showPointer();
+ vSync();
+ workToScreen();
+ delPointer();
+}
+
+void DreamWebEngine::atmospheres() {
+
+ const Atmosphere *a = &g_atmosphereList[0];
+
+ for (; a->_location != 255; ++a) {
+ if (a->_location != _realLocation)
+ continue;
+ if (a->_mapX != _mapX || a->_mapY != _mapY)
+ continue;
+ if (a->_sound != _channel0Playing) {
+
+ if (_vars._location == 45 && _vars._reelToWatch == 45)
+ continue; // "web"
+
+ playChannel0(a->_sound, a->_repeat);
+
+ // NB: The asm here reads
+ // cmp reallocation,2
+ // cmp mapy,0
+ // jz fullvol
+ // jnz notlouisvol
+ // I'm interpreting this as if the cmp reallocation is below the jz
+
+ if (_mapY == 0) {
+ _volume = 0; // "fullvol"
+ return;
+ }
+
+ if (_realLocation == 2 && _mapX == 22 && _mapY == 10)
+ _volume = 5; // "louisvol"
+
+ if (hasSpeech() && _realLocation == 14) {
+ if (_mapX == 33) {
+ _volume = 0; // "ismad2"
+ return;
+ }
+
+ if (_mapX == 22) {
+ _volume = 5;
+ return;
+ }
+
+ }
+ }
+
+ if (_realLocation == 2) {
+ if (_mapX == 22) {
+ _volume = 5; // "louisvol"
+ return;
+ }
+
+ if (_mapX == 11) {
+ _volume = 0; // "fullvol"
+ return;
+ }
+ }
+ return;
+ }
+
+ cancelCh0();
+}
+
+void DreamWebEngine::readKey() {
+ uint16 bufOut = _bufferOut;
+
+ if (bufOut == _bufferIn) {
+ // empty buffer
+ _currentKey = 0;
+ return;
+ }
+
+ bufOut = (bufOut + 1) & 15; // The buffer has size 16
+ _currentKey = g_keyBuffer[bufOut];
+ _bufferOut = bufOut;
+}
+
+void DreamWebEngine::newGame() {
+ commandOnlyCond(47, 251);
+
+ if (_mouseButton == 1)
+ _getBack = 3;
+}
+
+void DreamWebEngine::pickupOb(uint8 command, uint8 pos) {
+ _lastInvPos = pos;
+ _objectType = kFreeObjectType;
+ _itemFrame = command;
+ _command = command;
+ //uint8 dummy;
+ //getAnyAd(&dummy, &dummy); // was in the original source, seems useless here
+ transferToEx(command);
+}
+
+void DreamWebEngine::initialInv() {
+ if (_realLocation != 24)
+ return;
+
+ pickupOb(11, 5);
+ pickupOb(12, 6);
+ pickupOb(13, 7);
+ pickupOb(14, 8);
+ pickupOb(18, 0);
+ pickupOb(19, 1);
+ pickupOb(20, 9);
+ pickupOb(16, 2);
+ _vars._watchMode = 1;
+ _vars._reelToHold = 0;
+ _vars._endOfHoldReel = 6;
+ _vars._watchSpeed = 1;
+ _vars._speedCount = 1;
+ switchRyanOff();
+}
+
+void DreamWebEngine::walkIntoRoom() {
+ if (_vars._location == 14 && _mapX == 22) {
+ _destination = 1;
+ _finalDest = 1;
+ autoSetWalk();
+ }
+}
+
+void DreamWebEngine::afterIntroRoom() {
+ if (_nowInNewRoom == 0)
+ return; // notnewintro
+
+ clearWork();
+ findRoomInLoc();
+ _vars._newObs = 1;
+ drawFloor();
+ reelsOnScreen();
+ spriteUpdate();
+ printSprites();
+ workToScreen();
+ _nowInNewRoom = 0;
+}
+
+void DreamWebEngine::redrawMainScrn() {
+ _timeCount = 0;
+ createPanel();
+ _vars._newObs = 0;
+ drawFloor();
+ printSprites();
+ reelsOnScreen();
+ showIcon();
+ getUnderZoom();
+ underTextLine();
+ readMouse();
+ _commandType = 255;
+}
+
+void DreamWebEngine::blank() {
+ commandOnlyCond(0, 199);
+}
+
+void DreamWebEngine::allPointer() {
+ readMouse();
+ showPointer();
+ dumpPointer();
+}
+
+void DreamWebEngine::makeMainScreen() {
+ createPanel();
+ _vars._newObs = 1;
+ drawFloor();
+ spriteUpdate();
+ printSprites();
+ reelsOnScreen();
+ showIcon();
+ getUnderZoom();
+ underTextLine();
+ _commandType = 255;
+ animPointer();
+ workToScreenM();
+ _commandType = 200;
+ _manIsOffScreen = 0;
+}
+
+void DreamWebEngine::openInv() {
+ _invOpen = 1;
+ printMessage(80, 58 - 10, 61, 240, (240 & 1));
+ fillRyan();
+ _commandType = 255;
+}
+
+void DreamWebEngine::obsThatDoThings() {
+ if (!compare(_command, _objectType, "MEMB"))
+ return; // notlouiscard
+
+ if (getLocation(4) != 1) {
+ setLocation(4);
+ lookAtCard();
+ }
+}
+
+void DreamWebEngine::describeOb() {
+ const uint8 *obText = getObTextStart();
+ uint16 y = 92;
+ if (_foreignRelease && _objectType == kSetObjectType1)
+ y = 82;
+ _charShift = 91 + 91;
+ printDirect(&obText, 33, &y, 241, 241 & 1);
+ _charShift = 0;
+ y = 104;
+ if (_foreignRelease && _objectType == kSetObjectType1)
+ y = 94;
+ printDirect(&obText, 36, &y, 241, 241 & 1);
+ obsThatDoThings();
+
+ // Additional text
+ if (compare(_command, _objectType, "CUPE")) {
+ // Empty cup
+ const uint8 *string = (const uint8 *)_puzzleText.getString(40);
+ printDirect(string, 36, y + 10, 241, 241 & 1);
+ } else if (compare(_command, _objectType, "CUPF")) {
+ // Full cup
+ const uint8 *string = (const uint8 *)_puzzleText.getString(39);
+ printDirect(string, 36, y + 10, 241, 241 & 1);
+ }
+}
+
+void DreamWebEngine::delEverything() {
+ if (_mapYSize + _mapOffsetY < 182) {
+ mapToPanel();
+ } else {
+ // Big room
+ _mapYSize -= 8;
+ mapToPanel();
+ _mapYSize += 8;
+ }
+}
+
+void DreamWebEngine::errorMessage1() {
+ delPointer();
+ printMessage(76, 21, 58, 240, (240 & 1));
+ readMouse();
+ showPointer();
+ workToScreen();
+ delPointer();
+ hangOnP(50);
+ showPanel();
+ showMan();
+ examIcon();
+ readMouse();
+ useOpened();
+ showPointer();
+ workToScreen();
+ delPointer();
+}
+
+void DreamWebEngine::errorMessage2() {
+ _commandType = 255;
+ delPointer();
+ printMessage(76, 21, 59, 240, (240 & 1));
+ readMouse();
+ showPointer();
+ workToScreen();
+ delPointer();
+ hangOnP(50);
+ showPanel();
+ showMan();
+ examIcon();
+ readMouse();
+ useOpened();
+ showPointer();
+ workToScreen();
+ delPointer();
+}
+
+void DreamWebEngine::errorMessage3() {
+ delPointer();
+ printMessage(76, 21, 60, 240, (240 & 1));
+ workToScreenM();
+ hangOnP(50);
+ showPanel();
+ showMan();
+ examIcon();
+ readMouse();
+ useOpened();
+ showPointer();
+ workToScreen();
+ delPointer();
+}
+
+void DreamWebEngine::reExFromOpen() {
+
+}
+
+void DreamWebEngine::putBackObStuff() {
+ createPanel();
+ showPanel();
+ showMan();
+ obIcons();
+ showExit();
+ obPicture();
+ describeOb();
+ underTextLine();
+ _commandType = 255;
+ readMouse();
+ showPointer();
+ workToScreen();
+ delPointer();
+}
+
+bool DreamWebEngine::isSetObOnMap(uint8 index) {
+ return (getSetAd(index)->mapad[0] == 0);
+}
+
+void DreamWebEngine::examineInventory() {
+ commandOnlyCond(32, 249);
+
+ if (!(_mouseButton & 1))
+ return;
+
+ createPanel();
+ showPanel();
+ showMan();
+ showExit();
+ examIcon();
+ _pickUp = 0;
+ _invOpen = 2;
+ openInv();
+ workToScreenM();
+}
+
+void DreamWebEngine::middlePanel() {
+}
+
+void DreamWebEngine::underTextLine() {
+ if (_foreignRelease)
+ multiGet(_textUnder, _textAddressX, _textAddressY - 3, kUnderTextSizeX_f, kUnderTextSizeY_f);
+ else
+ multiGet(_textUnder, _textAddressX, _textAddressY, kUnderTextSizeX, kUnderTextSizeY);
+}
+
+void DreamWebEngine::showWatchReel() {
+ uint16 reelPointer = _vars._reelToWatch;
+ plotReel(reelPointer);
+ _vars._reelToWatch = reelPointer;
+
+ // check for shake
+ if (_realLocation == 26 && reelPointer == 104)
+ _vars._shakeCounter = 0xFF;
+}
+
+void DreamWebEngine::watchReel() {
+ if (_vars._reelToWatch != 0xFFFF) {
+ if (_mansPath != _finalDest)
+ return; // Wait until stopped walking
+ if (_turnToFace != _facing)
+ return;
+
+ if (--_vars._speedCount != 0xFF) {
+ showWatchReel();
+ return;
+ }
+ _vars._speedCount = _vars._watchSpeed;
+ if (_vars._reelToWatch != _vars._endWatchReel) {
+ ++_vars._reelToWatch;
+ showWatchReel();
+ return;
+ }
+ if (_vars._watchingTime) {
+ showWatchReel();
+ return;
+ }
+ _vars._reelToWatch = 0xFFFF;
+ _vars._watchMode = 0xFF;
+ if (_vars._reelToHold == 0xFFFF)
+ return; // No more reel
+ _vars._watchMode = 1;
+ } else if (_vars._watchMode != 1) {
+ if (_vars._watchMode != 2)
+ return; // "notreleasehold"
+ if (--_vars._speedCount == 0xFF) {
+ _vars._speedCount = _vars._watchSpeed;
+ ++_vars._reelToHold;
+ }
+ if (_vars._reelToHold == _vars._endOfHoldReel) {
+ _vars._reelToHold = 0xFFFF;
+ _vars._watchMode = 0xFF;
+ _destination = _vars._destAfterHold;
+ _finalDest = _vars._destAfterHold;
+ autoSetWalk();
+ return;
+ }
+ }
+
+ uint16 reelPointer = _vars._reelToHold;
+ plotReel(reelPointer);
+}
+
+void DreamWebEngine::afterNewRoom() {
+ if (_nowInNewRoom == 0)
+ return; // notnew
+
+ _timeCount = 0;
+ createPanel();
+ _commandType = 0;
+ findRoomInLoc();
+ if (_vars._ryanOn != 1) {
+ _mansPath = findPathOfPoint(_ryanX + 12, _ryanY + 12);
+ findXYFromPath();
+ _resetManXY = 1;
+ }
+ _vars._newObs = 1;
+ drawFloor();
+ _lookCounter = 160;
+ _nowInNewRoom = 0;
+ showIcon();
+ spriteUpdate();
+ printSprites();
+ underTextLine();
+ reelsOnScreen();
+ mainScreen();
+ getUnderZoom();
+ zoom();
+ workToScreenM();
+ walkIntoRoom();
+ edensFlatReminders();
+ atmospheres();
+}
+
+void DreamWebEngine::madmanRun() {
+ if (_vars._location != 14 ||
+ _mapX != 22 ||
+ _pointerMode != 2 ||
+ _vars._madmanFlag != 0) {
+ identifyOb();
+ return;
+ }
+
+ commandOnlyCond(52, 211);
+
+ if (_mouseButton == 1 &&
+ _mouseButton != _oldButton)
+ _vars._lastWeapon = 8;
+}
+
+
+void DreamWebEngine::decide() {
+ setMode();
+ loadPalFromIFF();
+ clearPalette();
+ _pointerMode = 0;
+ _vars._watchingTime = 0;
+ _pointerFrame = 0;
+ _textAddressX = 70;
+ _textAddressY = 182 - 8;
+ _textLen = 181;
+ _manIsOffScreen = 1;
+ loadSaveBox();
+ showDecisions();
+ workToScreen();
+ fadeScreenUp();
+ _getBack = 0;
+
+ RectWithCallback decideList[] = {
+ { kOpsx+69,kOpsx+124,kOpsy+30,kOpsy+76,&DreamWebEngine::newGame },
+ { kOpsx+20,kOpsx+87,kOpsy+10,kOpsy+59,&DreamWebEngine::DOSReturn },
+ { kOpsx+123,kOpsx+190,kOpsy+10,kOpsy+59,&DreamWebEngine::loadOld },
+ { 0,320,0,200,&DreamWebEngine::blank },
+ { 0xFFFF,0,0,0,0 }
+ };
+
+ do {
+ if (_quitRequested)
+ return;
+
+ readMouse();
+ showPointer();
+ vSync();
+ dumpPointer();
+ dumpTextLine();
+ delPointer();
+ checkCoords(decideList);
+ } while (!_getBack);
+
+ if (_getBack != 4)
+ _saveGraphics.clear(); // room not loaded
+
+ _textAddressX = 13;
+ _textAddressY = 182;
+ _textLen = 240;
+}
+
+void DreamWebEngine::showGun() {
+ _addToRed = 0;
+ _addToGreen = 0;
+ _addToBlue = 0;
+ palToStartPal();
+ palToEndPal();
+ greyscaleSum();
+ _fadeDirection = 1;
+ _fadeCount = 63;
+ _colourPos = 0;
+ _numToFade = 128;
+ hangOn(130);
+ endPalToStart();
+ clearEndPal();
+ _fadeDirection = 1;
+ _fadeCount = 63;
+ _colourPos = 0;
+ _numToFade = 128;
+ hangOn(200);
+ _roomsSample = 34;
+ loadRoomsSample();
+ _volume = 0;
+ GraphicsFile graphics;
+ loadGraphicsFile(graphics, "G13");
+ createPanel2();
+ showFrame(graphics, 100, 4, 0, 0);
+ showFrame(graphics, 158, 106, 1, 0);
+ workToScreen();
+ graphics.clear();
+ fadeScreenUp();
+ hangOn(160);
+ playChannel0(12, 0);
+ loadTempText("T83");
+ rollEndCreditsGameLost();
+ getRidOfTempText();
+}
+
+void DreamWebEngine::dropError() {
+ _commandType = 255;
+ delPointer();
+ printMessage(76, 21, 56, 240, 240 & 1);
+ workToScreenM();
+ hangOnP(50);
+ showPanel();
+ showMan();
+ examIcon();
+ _commandType = 255;
+ workToScreenM();
+}
+
+void DreamWebEngine::cantDrop() {
+ _commandType = 255;
+ delPointer();
+ printMessage(76, 21, 24, 240, 240 & 1);
+ workToScreenM();
+ hangOnP(50);
+ showPanel();
+ showMan();
+ examIcon();
+ _commandType = 255;
+ workToScreenM();
+}
+
+void DreamWebEngine::getBack1() {
+ if (_pickUp != 0) {
blank();
return;
}
- if (data.byte(kCommandtype) != 222) {
- data.byte(kCommandtype) = 222;
- commandonly(39);
+
+
+ commandOnlyCond(26, 202);
+
+ if (_mouseButton == _oldButton)
+ return;
+
+ if (_mouseButton & 1) {
+ // Get back
+ _getBack = 1;
+ _pickUp = 0;
}
- if (data.word(kMousebutton) == data.word(kOldbutton))
+}
+
+void DreamWebEngine::autoAppear() {
+ if (_vars._location == 32) {
+ // In alley
+ resetLocation(5);
+ setLocation(10);
+ _destPos = 10;
return;
- if ((data.word(kMousebutton) & 1) == 0)
+ }
+
+ if (_realLocation == 24) {
+ // In Eden's apartment
+ if (_vars._generalDead == 1) {
+ _vars._generalDead++;
+ placeSetObject(44);
+ placeSetObject(18);
+ placeSetObject(93);
+ removeSetObject(92);
+ removeSetObject(55);
+ removeSetObject(75);
+ removeSetObject(84);
+ removeSetObject(85);
+ } else if (_vars._sartainDead == 1) {
+ // Eden's part 2
+ removeSetObject(44);
+ removeSetObject(93);
+ placeSetObject(55);
+ _vars._sartainDead++;
+ }
+ } else {
+ // Not in Eden's
+ if (_realLocation == 25) {
+ // Sart roof
+ _vars._newsItem = 3;
+ resetLocation(6);
+ setLocation(11);
+ _destPos = 11;
+ } else {
+ if (_realLocation == 2 && _vars._rockstarDead != 0)
+ placeSetObject(23);
+ }
+ }
+}
+
+void DreamWebEngine::setupTimedUse(uint16 textIndex, uint16 countToTimed, uint16 timeCount, byte x, byte y) {
+ if (_timeCount != 0)
+ return; // can't setup
+
+ _timedTemp._y = y;
+ _timedTemp._x = x;
+ _timedTemp._countToTimed = countToTimed;
+ _timeCount = _timedTemp._timeCount = timeCount + countToTimed;
+ _timedTemp._string = _puzzleText.getString(textIndex);
+ debug(1, "setupTimedUse: %d => '%s'", textIndex, _timedTemp._string);
+}
+
+void DreamWebEngine::entryTexts() {
+ switch (_vars._location) {
+ case 21:
+ setupTimedUse(28, 60, 11, 68, 64);
+ break;
+ case 30:
+ setupTimedUse(27, 60, 11, 68, 64);
+ break;
+ case 23:
+ setupTimedUse(29, 60, 11, 68, 64);
+ break;
+ case 31:
+ setupTimedUse(30, 60, 11, 68, 64);
+ break;
+ case 20: // Sarter's 2
+ setupTimedUse(31, 60, 11, 68, 64);
+ break;
+ case 24: // Eden's lobby
+ setupTimedUse(32, 60, 3, 68, 64);
+ break;
+ case 34: // Eden 2
+ setupTimedUse(33, 60, 3, 68, 64);
+ break;
+ default:
+ break;
+ }
+}
+
+void DreamWebEngine::entryAnims() {
+ _vars._reelToWatch = 0xFFFF;
+ _vars._watchMode = (byte)-1;
+
+ switch (_vars._location) {
+ case 33: // beach
+ switchRyanOff();
+ _vars._watchingTime = 76 * 2;
+ _vars._reelToWatch = 0;
+ _vars._endWatchReel = 76;
+ _vars._watchSpeed = 1;
+ _vars._speedCount = 1;
+ break;
+ case 44: // Sparky's
+ resetLocation(8);
+ _vars._watchingTime = 50*2;
+ _vars._reelToWatch = 247;
+ _vars._endWatchReel = 297;
+ _vars._watchSpeed = 1;
+ _vars._speedCount = 1;
+ switchRyanOff();
+ break;
+ case 22: // lift
+ _vars._watchingTime = 31 * 2;
+ _vars._reelToWatch = 0;
+ _vars._endWatchReel = 30;
+ _vars._watchSpeed = 1;
+ _vars._speedCount = 1;
+ switchRyanOff();
+ break;
+ case 26: // under church
+ _symbolTopNum = 2;
+ _symbolBotNum = 1;
+ break;
+ case 45: // entered Dreamweb
+ _vars._keeperFlag = 0;
+ _vars._watchingTime = 296;
+ _vars._reelToWatch = 45;
+ _vars._endWatchReel = 198;
+ _vars._watchSpeed = 1;
+ _vars._speedCount = 1;
+ switchRyanOff();
+ break;
+ default:
+ if (_realLocation == 46 && _vars._sartainDead == 1) { // Crystal
+ removeFreeObject(0);
+ } else if (_vars._location == 9 && !checkIfPathIsOn(2) && _vars._aideDead != 0) {
+ // Top of church
+ if (checkIfPathIsOn(3))
+ turnPathOn(2);
+
+ // Make doors open
+ removeSetObject(4);
+ placeSetObject(5);
+ } else if (_vars._location == 47) { // Dream centre
+ placeSetObject(4);
+ placeSetObject(5);
+ } else if (_vars._location == 38) { // Car park
+ _vars._watchingTime = 57 * 2;
+ _vars._reelToWatch = 4;
+ _vars._endWatchReel = 57;
+ _vars._watchSpeed = 1;
+ _vars._speedCount = 1;
+ switchRyanOff();
+ } else if (_vars._location == 32) { // Alley
+ _vars._watchingTime = 66 * 2;
+ _vars._reelToWatch = 0;
+ _vars._endWatchReel = 66;
+ _vars._watchSpeed = 1;
+ _vars._speedCount = 1;
+ switchRyanOff();
+ } else if (_vars._location == 24) { // Eden's again
+ turnAnyPathOn(2, _roomNum - 1);
+ }
+ }
+}
+
+void DreamWebEngine::lookAtCard() {
+ _manIsOffScreen = 1;
+ getRidOfReels();
+ loadKeypad();
+ createPanel2();
+ showFrame(_keypadGraphics, 160, 80, 42, 128);
+ const uint8 *obText = getObTextStart();
+ findNextColon(&obText);
+ findNextColon(&obText);
+ findNextColon(&obText);
+ uint16 y = 124;
+ printDirect(&obText, 36, &y, 241, 241 & 1);
+ workToScreenM();
+ hangOnW(280);
+ createPanel2();
+ showFrame(_keypadGraphics, 160, 80, 42, 128);
+ printDirect(obText, 36, 130, 241, 241 & 1);
+ workToScreenM();
+ hangOnW(200);
+ _manIsOffScreen = 0;
+ _keypadGraphics.clear();
+ restoreReels();
+ putBackObStuff();
+}
+
+void DreamWebEngine::clearBuffers() {
+ clearChanges();
+}
+
+void DreamWebEngine::clearChanges() {
+ memset(_listOfChanges, 0xFF, sizeof(_listOfChanges));
+
+ setupInitialReelRoutines();
+
+ setupInitialVars();
+
+ _vars._exFramePos = 0;
+ _vars._exTextPos = 0;
+
+ memset(_exFrames._frames, 0xFF, kFrameBlocksize);
+ memset(_exFrames._data, 0xFF, kExframeslen);
+ memset(_exData, 0xFF, sizeof(_exData));
+ memset(_exText._offsetsLE, 0xFF, 2*(kNumexobjects+2));
+ memset(_exText._text, 0xFF, kExtextlen);
+
+ const uint8 initialRoomsCanGo[16] = { 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
+
+ assert(sizeof(_roomsCanGo) == sizeof(initialRoomsCanGo));
+ memcpy(_roomsCanGo, initialRoomsCanGo, sizeof(initialRoomsCanGo));
+}
+
+void DreamWebEngine::setupInitialVars() {
+ _vars._startVars = 0;
+ _vars._progressPoints = 0;
+ _vars._watchOn = 0;
+ _vars._shadesOn = 0;
+ _vars._secondCount = 0;
+ _vars._minuteCount = 30;
+ _vars._hourCount = 19;
+ _vars._zoomOn = 1;
+ _vars._location = 0;
+ _vars._exPos = 0;
+ _vars._exFramePos = 0;
+ _vars._exTextPos = 0;
+ _vars._card1Money = 0;
+ _vars._listPos = 0;
+ _vars._ryanPage = 0;
+ _vars._watchingTime = 0;
+ _vars._reelToWatch = (uint16)-1;
+ _vars._endWatchReel = 0;
+ _vars._speedCount = 0;
+ _vars._watchSpeed = 0;
+ _vars._reelToHold = (uint16)-1;
+ _vars._endOfHoldReel = (uint16)-1;
+ _vars._watchMode = (uint8)-1;
+ _vars._destAfterHold = 0;
+ _vars._newsItem = 0;
+ _vars._liftFlag = 0;
+ _vars._liftPath = 0;
+ _vars._lockStatus = 1;
+ _vars._doorPath = 0;
+ _vars._countToOpen = 0;
+ _vars._countToClose = 0;
+ _vars._rockstarDead = 0;
+ _vars._generalDead = 0;
+ _vars._sartainDead = 0;
+ _vars._aideDead = 0;
+ _vars._beenMugged = 0;
+ _vars._gunPassFlag = 0;
+ _vars._canMoveAltar = 0;
+ _vars._talkedToAttendant = 0;
+ _vars._talkedToSparky = 0;
+ _vars._talkedToBoss = 0;
+ _vars._talkedToRecep = 0;
+ _vars._cardPassFlag = 0;
+ _vars._madmanFlag = 0;
+ _vars._keeperFlag = 0;
+ _vars._lastTrigger = 0;
+ _vars._manDead = 0;
+ _vars._seed1 = 1;
+ _vars._seed2 = 2;
+ _vars._seed3 = 3;
+ _vars._needToTravel = 0;
+ _vars._throughDoor = 0;
+ _vars._newObs = 0;
+ _vars._ryanOn = 255;
+ _vars._combatCount = 0;
+ _vars._lastWeapon = (uint8)-1;
+ _vars._dreamNumber = 0;
+ _vars._roomAfterDream = 0;
+ _vars._shakeCounter = 48;
+}
+
+void DreamWebEngine::edensFlatReminders() {
+ if (_realLocation != 24 || _mapX != 44)
+ return; // not in Eden's lift
+
+ if (_vars._progressPoints)
+ return; // not the first time in Eden's apartment
+
+ uint16 exObjextIndex = findExObject("CSHR");
+ if (!isRyanHolding("DKEY") || exObjextIndex == kNumexobjects) {
+ setupTimedUse(50, 48, 8, 54, 70); // forgot something
return;
- data.byte(kZoomon) ^= 1;
- createpanel();
- data.byte(kNewobs) = 0;
- drawfloor();
- printsprites();
- reelsonscreen();
- showicon();
- getunderzoom();
- undertextline();
- commandonly(39);
- readmouse();
- worktoscreenm();
-}
-
-} /*namespace dreamgen */
+ }
+
+ DynObject *object = getExAd(exObjextIndex);
+
+ if (object->mapad[0] != 4) {
+ setupTimedUse(50, 48, 8, 54, 70); // forgot something
+ return;
+ } else if (object->mapad[1] != 255) {
+ if (!compare(object->mapad[1], object->mapad[0], "PURS")) {
+ setupTimedUse(50, 48, 8, 54, 70); // forgot something
+ return;
+ }
+ }
+
+ _vars._progressPoints++; // got card
+}
+
+void DreamWebEngine::incRyanPage() {
+ commandOnlyCond(31, 222);
+
+ if (_mouseButton == _oldButton || !(_mouseButton & 1))
+ return;
+
+ _vars._ryanPage = (_mouseX - (kInventx + 167)) / 18;
+
+ delPointer();
+ fillRyan();
+ readMouse();
+ showPointer();
+ workToScreen();
+ delPointer();
+
+}
+
+void DreamWebEngine::emergencyPurge() {
+ while (true) {
+ if (_vars._exFramePos + 4000 < kExframeslen) {
+ // Not near frame end
+ if (_vars._exTextPos + 400 < kExtextlen)
+ return; // notneartextend
+ }
+
+ purgeAnItem();
+ }
+}
+
+void DreamWebEngine::purgeAnItem() {
+ const DynObject *extraObjects = _exData;
+
+ for (size_t i = 0; i < kNumexobjects; ++i) {
+ if (extraObjects[i].mapad[0] && extraObjects[i].objId[0] == 255 &&
+ extraObjects[i].initialLocation != _realLocation) {
+ deleteExObject(i);
+ return;
+ }
+ }
+
+ for (size_t i = 0; i < kNumexobjects; ++i) {
+ if (extraObjects[i].mapad[0] && extraObjects[i].objId[0] == 255) {
+ deleteExObject(i);
+ return;
+ }
+ }
+}
+
+void DreamWebEngine::checkCoords(const RectWithCallback *rectWithCallbacks) {
+ if (_newLocation != 0xff)
+ return;
+ const RectWithCallback *r;
+ for (r = rectWithCallbacks; r->_xMin != 0xffff; ++r) {
+ if (r->contains(_mouseX, _mouseY)) {
+ (this->*(r->_callback))();
+ return;
+ }
+ }
+}
+} // End of namespace DreamWeb
diff --git a/engines/dreamweb/stubs.h b/engines/dreamweb/stubs.h
deleted file mode 100644
index ac7e1a5b91..0000000000
--- a/engines/dreamweb/stubs.h
+++ /dev/null
@@ -1,249 +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.
- *
- */
- uint16 allocatemem(uint16 paragraphs);
- uint8 *workspace();
- void allocatework();
- void clearwork();
- void multidump();
- void multidump(uint16 x, uint16 y, uint8 width, uint8 height);
- void frameoutv(uint8 *dst, const uint8 *src, uint16 pitch, uint16 width, uint16 height, int16 x, int16 y);
- void frameoutnm(uint8 *dst, const uint8 *src, uint16 pitch, uint16 width, uint16 height, uint16 x, uint16 y);
- void frameoutbh(uint8 *dst, const uint8 *src, uint16 pitch, uint16 width, uint16 height, uint16 x, uint16 y);
- void frameoutfx(uint8 *dst, const uint8 *src, uint16 pitch, uint16 width, uint16 height, uint16 x, uint16 y);
- void worktoscreen();
- void multiget();
- void multiget(uint8 *dst, uint16 x, uint16 y, uint8 width, uint8 height);
- void convertkey();
- void cls();
- void printsprites();
- void quickquit();
- void readoneblock();
- void printundermon();
- void seecommandtail();
- void randomnumber();
- void quickquit2();
- uint8 getnextword(const Frame *charSet, const uint8 *string, uint8 *totalWidth, uint8 *charCount);
- void printboth(const Frame* charSet, uint16 *x, uint16 y, uint8 c, uint8 nextChar);
- void printchar();
- void printchar(const Frame* charSet, uint16 *x, uint16 y, uint8 c, uint8 nextChar, uint8 *width, uint8 *height);
- void printdirect();
- void printdirect(const uint8** string, uint16 x, uint16 *y, uint8 maxWidth, bool centered);
- void printdirect(const uint8* string, uint16 x, uint16 y, uint8 maxWidth, bool centered);
- void printmessage(uint16 x, uint16 y, uint8 index, uint8 maxWidth, bool centered);
- void printmessage();
- void usetimedtext();
- void dumptimedtext();
- void setuptimedtemp();
- void setuptimedtemp(uint8 textIndex, uint8 voiceIndex, uint8 x, uint8 y, uint16 countToTimed, uint16 timeCount);
- void getundertimed();
- void putundertimed();
- uint8 printslow(const uint8 *string, uint16 x, uint16 y, uint8 maxWidth, bool centered);
- void printslow();
- void dumptextline();
- void getnumber();
- uint8 getnumber(const Frame *charSet, const uint8 *string, uint16 maxWidth, bool centered, uint16 *offset);
- uint8 kernchars(uint8 firstChar, uint8 secondChar, uint8 width);
- void getroomdata();
- void readheader();
- void fillspace();
- void startloading();
- void startloading(const Room *room);
- Sprite *spritetable();
- void showframe();
- void showframe(const Frame *frameData, uint16 x, uint16 y, uint16 frameNumber, uint8 effectsFlag, uint8 *width, uint8 *height);
- void showframe(const Frame *frameData, uint16 x, uint16 y, uint16 frameNumber, uint8 effectsFlag);
- void printasprite(const Sprite *sprite);
- void width160();
- void multiput(const uint8 *src, uint16 x, uint16 y, uint8 width, uint8 height);
- void multiput();
- void eraseoldobs();
- void clearsprites();
- Sprite *makesprite(uint8 x, uint8 y, uint16 updateCallback, uint16 frameData, uint16 somethingInDi);
- void spriteupdate();
- void initman();
- void mainman(Sprite *sprite);
- void facerightway();
- void walking(Sprite *sprite);
- void autosetwalk();
- void checkdest(const RoomPaths *roomsPaths);
- void aboutturn(Sprite *sprite);
- void backobject(Sprite *sprite);
- void constant(Sprite *sprite, SetObject *objData);
- void steady(Sprite *sprite, SetObject *objData);
- void random(Sprite *sprite, SetObject *objData);
- void dodoor();
- void dodoor(Sprite *sprite, SetObject *objData);
- void doorway(Sprite *sprite, SetObject *objData);
- void widedoor(Sprite *sprite, SetObject *objData);
- void lockeddoorway(Sprite *sprite, SetObject *objData);
- void liftsprite(Sprite *sprite, SetObject *objData);
- void findsource();
- Frame *findsourceCPP();
- void showgamereel();
- void showgamereel(ReelRoutine *routine);
- void showreelframe();
- void showreelframe(Reel *reel);
- const Frame *getreelframeax(uint16 frame);
- void turnpathon(uint8 param);
- void turnpathoff(uint8 param);
- void turnpathon();
- void turnpathoff();
- void turnanypathon(uint8 param, uint8 room);
- void turnanypathoff(uint8 param, uint8 room);
- void turnanypathon();
- void turnanypathoff();
- RoomPaths *getroomspaths();
- void makebackob(SetObject *objData);
- void modifychar();
- void lockmon();
- void cancelch0();
- void cancelch1();
- void plotreel();
- Reel *getreelstart();
- void dealwithspecial(uint8 firstParam, uint8 secondParam);
- void zoom();
- void crosshair();
- void showrain();
- void deltextline();
- void commandonly();
- void commandonly(uint8 command);
- void doblocks();
- void checkifperson();
- bool checkifperson(uint8 x, uint8 y);
- void checkiffree();
- bool checkiffree(uint8 x, uint8 y);
- void checkifex();
- bool checkifex(uint8 x, uint8 y);
- const uint8 *findobname(uint8 type, uint8 index);
- void copyname();
- void copyname(uint8 type, uint8 index, uint8 *dst);
- void commandwithob();
- void commandwithob(uint8 command, uint8 type, uint8 index);
- void showpanel();
- void updatepeople();
- void madmantext();
- void madmode();
- void movemap(uint8 param);
- bool addalong(const uint8 *mapFlags);
- bool addlength(const uint8 *mapFlags);
- void getdimension();
- void getdimension(uint8 *mapXstart, uint8 *mapYstart, uint8 *mapXsize, uint8 *mapYsize);
- void getmapad();
- void calcmapad();
- uint8 getmapad(const uint8 *setData);
- uint8 getxad(const uint8 *setData, uint8 *result);
- uint8 getyad(const uint8 *setData, uint8 *result);
- void calcfrframe();
- void calcfrframe(uint8* width, uint8* height);
- void finalframe();
- void finalframe(uint16 *x, uint16 *y);
- void showallobs();
- void blocknametext();
- void walktotext();
- void personnametext();
- void findxyfrompath();
- void findormake();
- void findormake(uint8 index, uint8 value, uint8 type);
- DynObject *getfreead(uint8 index);
- DynObject *getexad(uint8 index);
- DynObject *geteitheradCPP();
- SetObject *getsetad(uint8 index);
- void *getanyad(uint8 *value1, uint8 *value2);
- void *getanyaddir(uint8 index, uint8 flag);
- void setallchanges();
- void dochange();
- void dochange(uint8 index, uint8 value, uint8 type);
- void deletetaken();
- bool isCD();
- void placesetobject();
- void placesetobject(uint8 index);
- void removesetobject();
- void removesetobject(uint8 index);
- void showallfree();
- void showallex();
- bool finishedwalkingCPP();
- void finishedwalking();
- void checkone();
- void checkone(uint8 x, uint8 y, uint8 *flag, uint8 *flagEx, uint8 *type, uint8 *flagX, uint8 *flagY);
- void getflagunderp();
- void getflagunderp(uint8 *flag, uint8 *flagEx);
- void walkandexamine();
- void obname();
- void obname(uint8 command, uint8 commandType);
- void delpointer();
- void showblink();
- void dumpblink();
- void dumppointer();
- void showpointer();
- void animpointer();
- void checkcoords();
- void checkcoords(const RectWithCallback *rectWithCallbacks);
- void readmouse();
- void readmouse1();
- void readmouse2();
- void readmouse3();
- void readmouse4();
- uint16 waitframes();
- void drawflags();
- void addtopeoplelist();
- void addtopeoplelist(ReelRoutine *routine);
- void getexpos();
- void paneltomap();
- void maptopanel();
- void dumpmap();
- void obpicture();
- void transferinv();
- void obicons();
- void compare();
- bool compare(uint8 index, uint8 flag, const char id[4]);
- bool pixelcheckset(const ObjPos *pos, uint8 x, uint8 y);
- bool isitdescribed(const ObjPos *objPos);
- void checkifset();
- bool checkifset(uint8 x, uint8 y);
- void checkifpathison();
- bool checkifpathison(uint8 index);
- void isitworn();
- bool isitworn(const DynObject *object);
- void wornerror();
- void makeworn();
- void makeworn(DynObject *object);
- void obtoinv();
- void obtoinv(uint8 index, uint8 flag, uint16 x, uint16 y);
- void showryanpage();
- void findallryan();
- void findallryan(uint8 *inv);
- void fillryan();
- void useroutine();
- void hangon();
- void hangon(uint16 frameCount);
- void hangonp();
- void hangonp(uint16 count);
- uint8 findnextcolon(uint8 **string);
- void findnextcolon();
- uint8 *getobtextstartCPP();
- void usetext(const uint8 *string);
- void usetext();
- void getblockofpixel();
- uint8 getblockofpixel(uint8 x, uint8 y);
- void bresenhams();
- void examineobtext();
-
diff --git a/engines/dreamweb/talk.cpp b/engines/dreamweb/talk.cpp
new file mode 100644
index 0000000000..0f59cad895
--- /dev/null
+++ b/engines/dreamweb/talk.cpp
@@ -0,0 +1,263 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "dreamweb/dreamweb.h"
+
+namespace DreamWeb {
+
+void DreamWebEngine::talk() {
+ _talkPos = 0;
+ _inMapArea = 0;
+ _character = _command;
+ createPanel();
+ showPanel();
+ showMan();
+ showExit();
+ underTextLine();
+ convIcons();
+ startTalk();
+ _commandType = 255;
+ readMouse();
+ showPointer();
+ workToScreen();
+
+ RectWithCallback talkList[] = {
+ { 273,320,157,198,&DreamWebEngine::getBack1 },
+ { 240,290,2,44,&DreamWebEngine::moreTalk },
+ { 0,320,0,200,&DreamWebEngine::blank },
+ { 0xFFFF,0,0,0,0 }
+ };
+
+ do {
+ delPointer();
+ readMouse();
+ animPointer();
+ showPointer();
+ vSync();
+ dumpPointer();
+ dumpTextLine();
+ _getBack = 0;
+ checkCoords(talkList);
+ if (_quitRequested)
+ break;
+ } while (!_getBack);
+
+ if (_talkPos >= 4)
+ _personData->b7 |= 128;
+
+ redrawMainScrn();
+ workToScreenM();
+ if (_speechLoaded) {
+ cancelCh1();
+ _volumeDirection = -1;
+ _volumeTo = 0;
+ }
+}
+
+void DreamWebEngine::convIcons() {
+ uint8 index = _character & 127;
+ uint16 frame = getPersFrame(index);
+ const GraphicsFile *base = findSource(frame);
+ showFrame(*base, 234, 2, frame, 0);
+}
+
+uint16 DreamWebEngine::getPersFrame(uint8 index) {
+ return READ_LE_UINT16(&_personFramesLE[index]);
+}
+
+void DreamWebEngine::startTalk() {
+ _talkMode = 0;
+
+ const uint8 *str = getPersonText(_character & 0x7F, 0);
+ uint16 y;
+
+ _charShift = 91+91;
+ y = 64;
+ printDirect(&str, 66, &y, 241, true);
+
+ _charShift = 0;
+ y = 80;
+ printDirect(&str, 66, &y, 241, true);
+
+ if (hasSpeech()) {
+ _speechLoaded = false;
+ loadSpeech('R', _realLocation, 'C', 64*(_character & 0x7F));
+ if (_speechLoaded) {
+ _volumeDirection = 1;
+ _volumeTo = 6;
+ playChannel1(50 + 12);
+ }
+ }
+}
+
+const uint8 *DreamWebEngine::getPersonText(uint8 index, uint8 talkPos) {
+ return (const uint8 *)_personText.getString(index*64 + talkPos);
+}
+
+void DreamWebEngine::moreTalk() {
+ if (_talkMode != 0) {
+ redes();
+ return;
+ }
+
+ commandOnlyCond(49, 215);
+
+ if (_mouseButton == _oldButton)
+ return; // nomore
+
+ if (!(_mouseButton & 1))
+ return;
+
+ _talkMode = 2;
+ _talkPos = 4;
+
+ if (_character >= 100)
+ _talkPos = 48; // second part
+ doSomeTalk();
+}
+
+void DreamWebEngine::doSomeTalk() {
+ // FIXME: This is for the CD version only
+
+ while (true) {
+ const uint8 *str = getPersonText(_character & 0x7F, _talkPos);
+
+ if (*str == 0) {
+ // endheartalk
+ _pointerMode = 0;
+ return;
+ }
+
+ createPanel();
+ showPanel();
+ showMan();
+ showExit();
+ convIcons();
+
+ printDirect(str, 164, 64, 144, false);
+
+ loadSpeech('R', _realLocation, 'C', (64 * (_character & 0x7F)) + _talkPos);
+ if (_speechLoaded)
+ playChannel1(62);
+
+ _pointerMode = 3;
+ workToScreenM();
+ if (hangOnPQ())
+ return;
+
+ _talkPos++;
+
+ str = getPersonText(_character & 0x7F, _talkPos);
+ if (*str == 0) {
+ // endheartalk
+ _pointerMode = 0;
+ return;
+ }
+
+ if (*str != ':' && *str != 32) {
+ createPanel();
+ showPanel();
+ showMan();
+ showExit();
+ convIcons();
+ printDirect(str, 48, 128, 144, false);
+
+ loadSpeech('R', _realLocation, 'C', (64 * (_character & 0x7F)) + _talkPos);
+ if (_speechLoaded)
+ playChannel1(62);
+
+ _pointerMode = 3;
+ workToScreenM();
+ if (hangOnPQ())
+ return;
+ }
+
+ _talkPos++;
+ }
+}
+
+bool DreamWebEngine::hangOnPQ() {
+ _getBack = 0;
+
+ RectWithCallback quitList[] = {
+ { 273,320,157,198,&DreamWebEngine::getBack1 },
+ { 0,320,0,200,&DreamWebEngine::blank },
+ { 0xFFFF,0,0,0,0 }
+ };
+
+ uint16 speechFlag = 0;
+
+ do {
+ delPointer();
+ readMouse();
+ animPointer();
+ showPointer();
+ vSync();
+ dumpPointer();
+ dumpTextLine();
+ checkCoords(quitList);
+
+ if (_getBack == 1 || _quitRequested) {
+ // Quit conversation
+ delPointer();
+ _pointerMode = 0;
+ cancelCh1();
+ return true;
+ }
+
+ if (_speechLoaded && _channel1Playing == 255) {
+ speechFlag++;
+ if (speechFlag == 40)
+ break;
+ }
+ } while (!_mouseButton || _oldButton);
+
+ delPointer();
+ _pointerMode = 0;
+ return false;
+}
+
+void DreamWebEngine::redes() {
+ if (_channel1Playing != 255 || _talkMode != 2) {
+ blank();
+ return;
+ }
+
+ commandOnlyCond(50, 217);
+
+ if (!(_mouseButton & 1))
+ return;
+
+ delPointer();
+ createPanel();
+ showPanel();
+ showMan();
+ showExit();
+ convIcons();
+ startTalk();
+ readMouse();
+ showPointer();
+ workToScreen();
+ delPointer();
+}
+
+} // End of namespace DreamWeb
diff --git a/engines/dreamweb/titles.cpp b/engines/dreamweb/titles.cpp
new file mode 100644
index 0000000000..f7486ce687
--- /dev/null
+++ b/engines/dreamweb/titles.cpp
@@ -0,0 +1,444 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "dreamweb/dreamweb.h"
+#include "engines/util.h"
+
+namespace DreamWeb {
+
+void DreamWebEngine::endGame() {
+ loadTempText("T83");
+ monkSpeaking();
+ if (_quitRequested)
+ return;
+ gettingShot();
+ getRidOfTempText();
+ _volumeTo = 7;
+ _volumeDirection = 1;
+ hangOn(200);
+}
+
+void DreamWebEngine::monkSpeaking() {
+ _roomsSample = 35;
+ loadRoomsSample();
+ GraphicsFile graphics;
+ loadGraphicsFile(graphics, "G15");
+ clearWork();
+ showFrame(graphics, 160, 72, 0, 128); // show monk
+ workToScreen();
+ _volume = 7;
+ _volumeDirection = -1;
+ _volumeTo = hasSpeech() ? 5 : 0;
+ playChannel0(12, 255);
+ fadeScreenUps();
+ hangOn(300);
+
+ // TODO: Subtitles+speech mode
+ if (hasSpeech()) {
+ for (int i = 40; i < 48; i++) {
+ loadSpeech('T', 83, 'T', i);
+
+ playChannel1(50 + 12);
+
+ do {
+ waitForVSync();
+ if (_quitRequested)
+ return;
+ } while (_channel1Playing != 255);
+ }
+ } else {
+ for (int i = 40; i <= 44; i++) {
+ uint8 printResult = 0;
+ const uint8 *string = getTextInFile1(i);
+
+ do {
+ uint16 y = 140;
+ printResult = printDirect(&string, 36, &y, 239, 239 & 1);
+ workToScreen();
+ clearWork();
+ showFrame(graphics, 160, 72, 0, 128); // show monk
+ hangOnP(240);
+ if (_quitRequested)
+ return;
+ } while (printResult != 0);
+ }
+ }
+
+ _volumeDirection = 1;
+ _volumeTo = 7;
+ fadeScreenDowns();
+ hangOn(300);
+ graphics.clear();
+}
+
+void DreamWebEngine::gettingShot() {
+ _newLocation = 55;
+ clearPalette();
+ loadIntroRoom();
+ fadeScreenUps();
+ _volumeTo = 0;
+ _volumeDirection = -1;
+ runEndSeq();
+ clearBeforeLoad();
+}
+
+void DreamWebEngine::bibleQuote() {
+ initGraphics(640, 480, true);
+
+ showPCX("I00");
+ fadeScreenUps();
+
+ hangOne(80);
+ if (_lastHardKey == 1) {
+ _lastHardKey = 0;
+ return; // "biblequotearly"
+ }
+
+ hangOne(560);
+ if (_lastHardKey == 1) {
+ _lastHardKey = 0;
+ return; // "biblequotearly"
+ }
+
+ fadeScreenDowns();
+
+ hangOne(200);
+ if (_lastHardKey == 1) {
+ _lastHardKey = 0;
+ return; // "biblequotearly"
+ }
+
+ cancelCh0();
+
+ _lastHardKey = 0;
+}
+
+void DreamWebEngine::hangOne(uint16 delay) {
+ do {
+ vSync();
+ if (_lastHardKey == 1)
+ return; // "hangonearly"
+ } while (--delay);
+}
+
+void DreamWebEngine::intro() {
+ loadTempText("T82");
+ loadPalFromIFF();
+ setMode();
+ _newLocation = 50;
+ clearPalette();
+ loadIntroRoom();
+ _volume = 7;
+ _volumeDirection = -1;
+ _volumeTo = hasSpeech() ? 4 : 0;
+ playChannel0(12, 255);
+ fadeScreenUps();
+ runIntroSeq();
+
+ if (_lastHardKey == 1) {
+ _lastHardKey = 0;
+ return; // "introearly"
+ }
+
+ clearBeforeLoad();
+ _newLocation = 52;
+ loadIntroRoom();
+ runIntroSeq();
+
+ if (_lastHardKey == 1) {
+ _lastHardKey = 0;
+ return; // "introearly"
+ }
+
+ clearBeforeLoad();
+ _newLocation = 53;
+ loadIntroRoom();
+ runIntroSeq();
+
+ if (_lastHardKey == 1) {
+ _lastHardKey = 0;
+ return; // "introearly"
+ }
+
+ clearBeforeLoad();
+ allPalette();
+ _newLocation = 54;
+ loadIntroRoom();
+ runIntroSeq();
+
+ if (_lastHardKey == 1) {
+ _lastHardKey = 0;
+ return; // "introearly"
+ }
+
+ getRidOfTempText();
+ clearBeforeLoad();
+
+ _lastHardKey = 0;
+}
+
+void DreamWebEngine::runIntroSeq() {
+ _getBack = 0;
+
+ do {
+ vSync();
+
+ if (_lastHardKey == 1)
+ break;
+
+ spriteUpdate();
+ vSync();
+
+ if (_lastHardKey == 1)
+ break;
+
+ delEverything();
+ printSprites();
+ reelsOnScreen();
+ afterIntroRoom();
+ useTimedText();
+ vSync();
+
+ if (_lastHardKey == 1)
+ break;
+
+ dumpMap();
+ dumpTimedText();
+ vSync();
+
+ if (_lastHardKey == 1)
+ break;
+
+ } while (_getBack != 1);
+
+
+ if (_lastHardKey == 1) {
+ getRidOfTempText();
+ clearBeforeLoad();
+ }
+
+ // These were not called in this program arc
+ // in the original code.. Bug?
+ //getRidOfTempText();
+ //clearBeforeLoad();
+}
+
+void DreamWebEngine::runEndSeq() {
+ atmospheres();
+ _getBack = 0;
+
+ do {
+ vSync();
+ spriteUpdate();
+ vSync();
+ delEverything();
+ printSprites();
+ reelsOnScreen();
+ afterIntroRoom();
+ useTimedText();
+ vSync();
+ dumpMap();
+ dumpTimedText();
+ vSync();
+ } while (_getBack != 1 && !_quitRequested);
+}
+
+void DreamWebEngine::loadIntroRoom() {
+ _introCount = 0;
+ _vars._location = 255;
+ loadRoom();
+ _mapOffsetX = 72;
+ _mapOffsetY = 16;
+ clearSprites();
+ _vars._throughDoor = 0;
+ _currentKey = '0';
+ _mainMode = 0;
+ clearWork();
+ _vars._newObs = 1;
+ drawFloor();
+ reelsOnScreen();
+ spriteUpdate();
+ printSprites();
+ workToScreen();
+}
+
+void DreamWebEngine::set16ColPalette() {
+}
+
+void DreamWebEngine::realCredits() {
+ _roomsSample = 33;
+ loadRoomsSample();
+ _volume = 0;
+
+ initGraphics(640, 480, true);
+ hangOn(35);
+
+ showPCX("I01");
+ playChannel0(12, 0);
+
+ hangOne(2);
+
+ if (_lastHardKey == 1) {
+ _lastHardKey = 0;
+ return; // "realcreditsearly"
+ }
+
+ allPalette();
+ hangOne(80);
+
+ if (_lastHardKey == 1) {
+ _lastHardKey = 0;
+ return; // "realcreditsearly"
+ }
+
+ fadeScreenDowns();
+ hangOne(256);
+
+ if (_lastHardKey == 1) {
+ _lastHardKey = 0;
+ return; // "realcreditsearly"
+ }
+
+ showPCX("I02");
+ playChannel0(12, 0);
+ hangOne(2);
+
+ if (_lastHardKey == 1) {
+ _lastHardKey = 0;
+ return; // "realcreditsearly"
+ }
+
+ allPalette();
+ hangOne(80);
+
+ if (_lastHardKey == 1) {
+ _lastHardKey = 0;
+ return; // "realcreditsearly"
+ }
+
+ fadeScreenDowns();
+ hangOne(256);
+
+ if (_lastHardKey == 1) {
+ _lastHardKey = 0;
+ return; // "realcreditsearly"
+ }
+
+ showPCX("I03");
+ playChannel0(12, 0);
+ hangOne(2);
+
+ if (_lastHardKey == 1) {
+ _lastHardKey = 0;
+ return; // "realcreditsearly"
+ }
+
+ allPalette();
+ hangOne(80);
+
+ if (_lastHardKey == 1) {
+ _lastHardKey = 0;
+ return; // "realcreditsearly"
+ }
+
+ fadeScreenDowns();
+ hangOne(256);
+
+ if (_lastHardKey == 1) {
+ _lastHardKey = 0;
+ return; // "realcreditsearly"
+ }
+
+ showPCX("I04");
+ playChannel0(12, 0);
+ hangOne(2);
+
+ if (_lastHardKey == 1) {
+ _lastHardKey = 0;
+ return; // "realcreditsearly"
+ }
+
+ allPalette();
+ hangOne(80);
+
+ if (_lastHardKey == 1) {
+ _lastHardKey = 0;
+ return; // "realcreditsearly"
+ }
+
+ fadeScreenDowns();
+ hangOne(256);
+
+ if (_lastHardKey == 1) {
+ _lastHardKey = 0;
+ return; // "realcreditsearly"
+ }
+
+ showPCX("I05");
+ playChannel0(12, 0);
+ hangOne(2);
+
+ if (_lastHardKey == 1) {
+ _lastHardKey = 0;
+ return; // "realcreditsearly"
+ }
+
+ allPalette();
+ hangOne(80);
+
+ if (_lastHardKey == 1) {
+ _lastHardKey = 0;
+ return; // "realcreditsearly"
+ }
+
+ fadeScreenDowns();
+ hangOne(256);
+
+ if (_lastHardKey == 1) {
+ _lastHardKey = 0;
+ return; // "realcreditsearly"
+ }
+
+ showPCX("I06");
+ fadeScreenUps();
+ hangOne(60);
+
+ if (_lastHardKey == 1) {
+ _lastHardKey = 0;
+ return; // "realcreditsearly"
+ }
+
+ playChannel0(13, 0);
+ hangOne(350);
+
+ if (_lastHardKey == 1) {
+ _lastHardKey = 0;
+ return; // "realcreditsearly"
+ }
+
+ fadeScreenDowns();
+ hangOne(256);
+
+ _lastHardKey = 0;
+}
+
+} // End of namespace DreamWeb
diff --git a/engines/dreamweb/use.cpp b/engines/dreamweb/use.cpp
index d6648b556e..e59843539f 100644
--- a/engines/dreamweb/use.cpp
+++ b/engines/dreamweb/use.cpp
@@ -22,157 +22,1578 @@
#include "dreamweb/dreamweb.h"
-namespace DreamGen {
+namespace DreamWeb {
-typedef void (DreamGenContext::*UseCallback)(void);
+typedef void (DreamWebEngine::*UseCallback)(void);
+// Note: The callback pointer has been placed before the
+// ID to keep MSVC happy (otherwise, it throws warnings
+// that alignment of a member was sensitive to packing)
struct UseListEntry {
- uint8 id[5]; // 0-terminal because it is easier syntatically to initialize the array
UseCallback callback;
+ const char *id;
};
-void DreamGenContext::useroutine() {
+void DreamWebEngine::useRoutine() {
static const UseListEntry kUseList[] = {
- { "NETW", &DreamGenContext::usemon },
- { "ELVA", &DreamGenContext::useelevator1 },
- { "ELVB", &DreamGenContext::useelevator2 },
- { "ELVC", &DreamGenContext::useelevator3 },
- { "ELVE", &DreamGenContext::useelevator4 },
- { "ELVF", &DreamGenContext::useelevator5 },
- { "CGAT", &DreamGenContext::usechurchgate },
- { "REMO", &DreamGenContext::usestereo },
- { "BUTA", &DreamGenContext::usebuttona },
- { "CBOX", &DreamGenContext::usewinch },
- { "LITE", &DreamGenContext::uselighter },
- { "PLAT", &DreamGenContext::useplate },
- { "LIFT", &DreamGenContext::usecontrol },
- { "WIRE", &DreamGenContext::usewire },
- { "HNDL", &DreamGenContext::usehandle },
- { "HACH", &DreamGenContext::usehatch },
- { "DOOR", &DreamGenContext::useelvdoor },
- { "CSHR", &DreamGenContext::usecashcard },
- { "GUNA", &DreamGenContext::usegun },
- { "CRAA", &DreamGenContext::usecardreader1 },
- { "CRBB", &DreamGenContext::usecardreader2 },
- { "CRCC", &DreamGenContext::usecardreader3 },
- { "SEAT", &DreamGenContext::sitdowninbar },
- { "MENU", &DreamGenContext::usemenu },
- { "COOK", &DreamGenContext::usecooker },
- { "ELCA", &DreamGenContext::callhotellift },
- { "EDCA", &DreamGenContext::calledenslift },
- { "DDCA", &DreamGenContext::calledensdlift },
- { "ALTR", &DreamGenContext::usealtar },
- { "LOKA", &DreamGenContext::openhoteldoor },
- { "LOKB", &DreamGenContext::openhoteldoor2 },
- { "ENTA", &DreamGenContext::openlouis },
- { "ENTB", &DreamGenContext::openryan },
- { "ENTE", &DreamGenContext::openpoolboss },
- { "ENTC", &DreamGenContext::openyourneighbour },
- { "ENTD", &DreamGenContext::openeden },
- { "ENTH", &DreamGenContext::opensarters },
- { "WWAT", &DreamGenContext::wearwatch },
- { "POOL", &DreamGenContext::usepoolreader },
- { "WSHD", &DreamGenContext::wearshades },
- { "GRAF", &DreamGenContext::grafittidoor },
- { "TRAP", &DreamGenContext::trapdoor },
- { "CDPE", &DreamGenContext::edenscdplayer },
- { "DLOK", &DreamGenContext::opentvdoor },
- { "HOLE", &DreamGenContext::usehole },
- { "DRYR", &DreamGenContext::usedryer },
- { "HOLY", &DreamGenContext::usechurchhole },
- { "WALL", &DreamGenContext::usewall },
- { "BOOK", &DreamGenContext::usediary },
- { "AXED", &DreamGenContext::useaxe },
- { "SHLD", &DreamGenContext::useshield },
- { "BCNY", &DreamGenContext::userailing },
- { "LIDC", &DreamGenContext::usecoveredbox },
- { "LIDU", &DreamGenContext::useclearbox },
- { "LIDO", &DreamGenContext::useopenbox },
- { "PIPE", &DreamGenContext::usepipe },
- { "BALC", &DreamGenContext::usebalcony },
- { "WIND", &DreamGenContext::usewindow },
- { "PAPR", &DreamGenContext::viewfolder },
- { "UWTA", &DreamGenContext::usetrainer },
- { "UWTB", &DreamGenContext::usetrainer },
- { "STAT", &DreamGenContext::entersymbol },
- { "TLID", &DreamGenContext::opentomb },
- { "SLAB", &DreamGenContext::useslab },
- { "CART", &DreamGenContext::usecart },
- { "FCAR", &DreamGenContext::usefullcart },
- { "SLBA", &DreamGenContext::slabdoora },
- { "SLBB", &DreamGenContext::slabdoorb },
- { "SLBC", &DreamGenContext::slabdoorc },
- { "SLBD", &DreamGenContext::slabdoord },
- { "SLBE", &DreamGenContext::slabdoore },
- { "SLBF", &DreamGenContext::slabdoorf },
- { "PLIN", &DreamGenContext::useplinth },
- { "LADD", &DreamGenContext::useladder },
- { "LADB", &DreamGenContext::useladderb },
- { "GUMA", &DreamGenContext::chewy },
- { "SQEE", &DreamGenContext::wheelsound },
- { "TAPP", &DreamGenContext::runtap },
- { "GUIT", &DreamGenContext::playguitar },
- { "CONT", &DreamGenContext::hotelcontrol },
- { "BELL", &DreamGenContext::hotelbell },
+ { &DreamWebEngine::useMon, "NETW" },
+ { &DreamWebEngine::useElevator1, "ELVA" },
+ { &DreamWebEngine::useElevator2, "ELVB" },
+ { &DreamWebEngine::useElevator3, "ELVC" },
+ { &DreamWebEngine::useElevator4, "ELVE" },
+ { &DreamWebEngine::useElevator5, "ELVF" },
+ { &DreamWebEngine::useChurchGate, "CGAT" },
+ { &DreamWebEngine::useStereo, "REMO" },
+ { &DreamWebEngine::useButtonA, "BUTA" },
+ { &DreamWebEngine::useWinch, "CBOX" },
+ { &DreamWebEngine::useLighter, "LITE" },
+ { &DreamWebEngine::usePlate, "PLAT" },
+ { &DreamWebEngine::useControl, "LIFT" },
+ { &DreamWebEngine::useWire, "WIRE" },
+ { &DreamWebEngine::useHandle, "HNDL" },
+ { &DreamWebEngine::useHatch, "HACH" },
+ { &DreamWebEngine::useElvDoor, "DOOR" },
+ { &DreamWebEngine::useCashCard, "CSHR" },
+ { &DreamWebEngine::useGun, "GUNA" },
+ { &DreamWebEngine::useCardReader1, "CRAA" },
+ { &DreamWebEngine::useCardReader2, "CRBB" },
+ { &DreamWebEngine::useCardReader3, "CRCC" },
+ { &DreamWebEngine::sitDownInBar, "SEAT" },
+ { &DreamWebEngine::useMenu, "MENU" },
+ { &DreamWebEngine::useCooker, "COOK" },
+ { &DreamWebEngine::callHotelLift, "ELCA" },
+ { &DreamWebEngine::callEdensLift, "EDCA" },
+ { &DreamWebEngine::callEdensDLift, "DDCA" },
+ { &DreamWebEngine::useAltar, "ALTR" },
+ { &DreamWebEngine::openHotelDoor, "LOKA" },
+ { &DreamWebEngine::openHotelDoor2, "LOKB" },
+ { &DreamWebEngine::openLouis, "ENTA" },
+ { &DreamWebEngine::openRyan, "ENTB" },
+ { &DreamWebEngine::openPoolBoss, "ENTE" },
+ { &DreamWebEngine::openYourNeighbour, "ENTC" },
+ { &DreamWebEngine::openEden, "ENTD" },
+ { &DreamWebEngine::openSarters, "ENTH" },
+ { &DreamWebEngine::wearWatch, "WWAT" },
+ { &DreamWebEngine::usePoolReader, "POOL" },
+ { &DreamWebEngine::wearShades, "WSHD" },
+ { &DreamWebEngine::grafittiDoor, "GRAF" },
+ { &DreamWebEngine::trapDoor, "TRAP" },
+ { &DreamWebEngine::edensCDPlayer, "CDPE" },
+ { &DreamWebEngine::openTVDoor, "DLOK" },
+ { &DreamWebEngine::useHole, "HOLE" },
+ { &DreamWebEngine::useDryer, "DRYR" },
+ { &DreamWebEngine::useChurchHole, "HOLY" },
+ { &DreamWebEngine::useWall, "WALL" },
+ { &DreamWebEngine::useDiary, "BOOK" },
+ { &DreamWebEngine::useAxe, "AXED" },
+ { &DreamWebEngine::useShield, "SHLD" },
+ { &DreamWebEngine::useRailing, "BCNY" },
+ { &DreamWebEngine::useCoveredBox, "LIDC" },
+ { &DreamWebEngine::useClearBox, "LIDU" },
+ { &DreamWebEngine::useOpenBox, "LIDO" },
+ { &DreamWebEngine::usePipe, "PIPE" },
+ { &DreamWebEngine::useBalcony, "BALC" },
+ { &DreamWebEngine::useWindow, "WIND" },
+ { &DreamWebEngine::viewFolder, "PAPR" },
+ { &DreamWebEngine::useTrainer, "UWTA" },
+ { &DreamWebEngine::useTrainer, "UWTB" },
+ { &DreamWebEngine::enterSymbol, "STAT" },
+ { &DreamWebEngine::openTomb, "TLID" },
+ { &DreamWebEngine::useSlab, "SLAB" },
+ { &DreamWebEngine::useCart, "CART" },
+ { &DreamWebEngine::useFullCart, "FCAR" },
+ { &DreamWebEngine::slabDoorA, "SLBA" },
+ { &DreamWebEngine::slabDoorB, "SLBB" },
+ { &DreamWebEngine::slabDoorC, "SLBC" },
+ { &DreamWebEngine::slabDoorD, "SLBD" },
+ { &DreamWebEngine::slabDoorE, "SLBE" },
+ { &DreamWebEngine::slabDoorF, "SLBF" },
+ { &DreamWebEngine::usePlinth, "PLIN" },
+ { &DreamWebEngine::useLadder, "LADD" },
+ { &DreamWebEngine::useLadderB, "LADB" },
+ { &DreamWebEngine::chewy, "GUMA" },
+ { &DreamWebEngine::wheelSound, "SQEE" },
+ { &DreamWebEngine::runTap, "TAPP" },
+ { &DreamWebEngine::playGuitar, "GUIT" },
+ { &DreamWebEngine::hotelControl, "CONT" },
+ { &DreamWebEngine::hotelBell, "BELL" },
};
- if (data.byte(kReallocation) >= 50) {
- if (data.byte(kPointerpower) == 0)
+ if (_realLocation >= 50) {
+ if (_pointerPower == 0)
return;
- data.byte(kPointerpower) = 0;
+ _pointerPower = 0;
}
- getanyad();
- const uint8 *id = es.ptr(bx + 12, 4);
+ uint8 dummy;
+ void *obj = getAnyAd(&dummy, &dummy);
for (size_t i = 0; i < sizeof(kUseList)/sizeof(UseListEntry); ++i) {
const UseListEntry &entry = kUseList[i];
- if (('A' + id[0] == entry.id[0]) && ('A' + id[1] == entry.id[1]) && ('A' + id[2] == entry.id[2]) && ('A' + id[3] == entry.id[3])) {
+ if (objectMatches(obj, entry.id)) {
(this->*entry.callback)();
return;
}
}
- delpointer();
- uint8 *obText = getobtextstartCPP();
- if (findnextcolon(&obText) != 0) {
- if (findnextcolon(&obText) != 0) {
+ delPointer();
+ const uint8 *obText = getObTextStart();
+ if (findNextColon(&obText) != 0) {
+ if (findNextColon(&obText) != 0) {
if (*obText != 0) {
- usetext(obText);
- hangonp(400);
- putbackobstuff();
+ useText(obText);
+ hangOnP(400);
+ putBackObStuff();
return;
}
}
}
- createpanel();
- showpanel();
- showman();
- showexit();
- obicons();
- printmessage(33, 100, 63, 241, true);
- worktoscreenm();
- hangonp(50);
- putbackobstuff();
- data.byte(kCommandtype) = 255;
+ createPanel();
+ showPanel();
+ showMan();
+ showExit();
+ obIcons();
+ printMessage(33, 100, 63, 241, true);
+ workToScreenM();
+ hangOnP(50);
+ putBackObStuff();
+ _commandType = 255;
}
-void DreamGenContext::usetext() {
- usetext(es.ptr(si, 0));
+void DreamWebEngine::useText(const uint8 *string) {
+ createPanel();
+ showPanel();
+ showMan();
+ showExit();
+ obIcons();
+ printDirect(string, 36, 104, 241, true);
+ workToScreenM();
}
-void DreamGenContext::usetext(const uint8 *string) {
- createpanel();
- showpanel();
- showman();
- showexit();
- obicons();
- printdirect(string, 36, 104, 241, true);
- worktoscreenm();
+void DreamWebEngine::showFirstUse() {
+ const uint8 *obText = getObTextStart();
+ findNextColon(&obText);
+ findNextColon(&obText);
+ useText(obText);
+ hangOnP(400);
+}
+
+void DreamWebEngine::showSecondUse() {
+ const uint8 *obText = getObTextStart();
+ findNextColon(&obText);
+ findNextColon(&obText);
+ findNextColon(&obText);
+ useText(obText);
+ hangOnP(400);
+}
+
+void DreamWebEngine::edensCDPlayer() {
+ showFirstUse();
+ _vars._watchingTime = 18 * 2;
+ _vars._reelToWatch = 25;
+ _vars._endWatchReel = 42;
+ _vars._watchSpeed = 1;
+ _vars._speedCount = 1;
+ _getBack = 1;
+}
+
+void DreamWebEngine::hotelBell() {
+ playChannel1(12);
+ showFirstUse();
+ putBackObStuff();
+}
+
+void DreamWebEngine::playGuitar() {
+ playChannel1(14);
+ showFirstUse();
+ putBackObStuff();
+}
+
+void DreamWebEngine::useElevator1() {
+ showFirstUse();
+ selectLocation();
+ _getBack = 1;
+}
+
+void DreamWebEngine::useElevator2() {
+ showFirstUse();
+
+ if (_vars._location == 23) // In pool hall
+ _newLocation = 31;
+ else
+ _newLocation = 23;
+
+ _vars._countToClose = 20;
+ _vars._countToOpen = 0;
+ _vars._watchingTime = 80;
+ _getBack = 1;
+}
+
+void DreamWebEngine::useElevator3() {
+ showFirstUse();
+ _vars._countToClose = 20;
+ _newLocation = 34;
+ _vars._reelToWatch = 46;
+ _vars._endWatchReel = 63;
+ _vars._watchSpeed = 1;
+ _vars._speedCount = 1;
+ _vars._watchingTime = 80;
+ _getBack = 1;
+}
+
+void DreamWebEngine::useElevator4() {
+ showFirstUse();
+ _vars._reelToWatch = 0;
+ _vars._endWatchReel = 11;
+ _vars._watchSpeed = 1;
+ _vars._speedCount = 1;
+ _vars._countToClose = 20;
+ _vars._watchingTime = 80;
+ _getBack = 1;
+ _newLocation = 24;
+}
+
+void DreamWebEngine::useElevator5() {
+ placeSetObject(4);
+ removeSetObject(0);
+ _newLocation = 20;
+ _vars._watchingTime = 80;
+ _vars._liftFlag = 1;
+ _vars._countToClose = 8;
+ _getBack = 1;
+}
+
+void DreamWebEngine::useHatch() {
+ showFirstUse();
+ _newLocation = 40;
+ _getBack = 1;
+}
+
+void DreamWebEngine::wheelSound() {
+ playChannel1(17);
+ showFirstUse();
+ putBackObStuff();
+}
+
+void DreamWebEngine::callHotelLift() {
+ playChannel1(12);
+ showFirstUse();
+ _vars._countToOpen = 8;
+ _getBack = 1;
+ _destination = 5;
+ _finalDest = 5;
+ autoSetWalk();
+ turnPathOn(4);
+}
+
+void DreamWebEngine::useShield() {
+ if (_realLocation != 20 || _vars._combatCount == 0) {
+ // Not in Sart room
+ showFirstUse();
+ putBackObStuff();
+ } else {
+ _vars._lastWeapon = 3;
+ showSecondUse();
+ _getBack = 1;
+ _vars._progressPoints++;
+ removeObFromInv();
+ }
+}
+
+void DreamWebEngine::useCoveredBox() {
+ _vars._progressPoints++;
+ showFirstUse();
+ _vars._watchingTime = 50;
+ _vars._reelToWatch = 41;
+ _vars._endWatchReel = 66;
+ _vars._watchSpeed = 1;
+ _vars._speedCount = 1;
+ _getBack = 1;
+}
+
+void DreamWebEngine::useRailing() {
+ showFirstUse();
+ _vars._watchingTime = 80;
+ _vars._reelToWatch = 0;
+ _vars._endWatchReel = 30;
+ _vars._watchSpeed = 1;
+ _vars._speedCount = 1;
+ _getBack = 1;
+ _vars._manDead = 4;
+}
+
+void DreamWebEngine::wearWatch() {
+ if (_vars._watchOn == 1) {
+ // Already wearing watch
+ showSecondUse();
+ putBackObStuff();
+ } else {
+ showFirstUse();
+ _vars._watchOn = 1;
+ _getBack = 1;
+ uint8 dummy;
+ makeWorn((DynObject *)getAnyAd(&dummy, &dummy));
+ }
+}
+
+void DreamWebEngine::wearShades() {
+ if (_vars._shadesOn == 1) {
+ // Already wearing shades
+ showSecondUse();
+ putBackObStuff();
+ } else {
+ _vars._shadesOn = 1;
+ showFirstUse();
+ _getBack = 1;
+ uint8 dummy;
+ makeWorn((DynObject *)getAnyAd(&dummy, &dummy));
+ }
+}
+
+void DreamWebEngine::useChurchHole() {
+ showFirstUse();
+ _getBack = 1;
+ _vars._watchingTime = 28;
+ _vars._reelToWatch = 13;
+ _vars._endWatchReel = 26;
+ _vars._watchSpeed = 1;
+ _vars._speedCount = 1;
+}
+
+void DreamWebEngine::sitDownInBar() {
+ if (_vars._watchMode != 0xFF) {
+ // Sat down
+ showSecondUse();
+ putBackObStuff();
+ } else {
+ showFirstUse();
+ _vars._watchingTime = 50;
+ _vars._reelToWatch = 55;
+ _vars._endWatchReel = 71;
+ _vars._reelToHold = 73;
+ _vars._endOfHoldReel = 83;
+ _vars._watchSpeed = 1;
+ _vars._speedCount = 1;
+ _getBack = 1;
+ }
+}
+
+void DreamWebEngine::useDryer() {
+ playChannel1(12);
+ showFirstUse();
+ _getBack = 1;
+}
+
+void DreamWebEngine::useBalcony() {
+ showFirstUse();
+ turnPathOn(6);
+ turnPathOff(0);
+ turnPathOff(1);
+ turnPathOff(2);
+ turnPathOff(3);
+ turnPathOff(4);
+ turnPathOff(5);
+ _vars._progressPoints++;
+ _mansPath = 6;
+ _destination = 6;
+ _finalDest = 6;
+ findXYFromPath();
+ switchRyanOff();
+ _resetManXY = 1;
+ _vars._watchingTime = 30 * 2;
+ _vars._reelToWatch = 183;
+ _vars._endWatchReel = 212;
+ _vars._watchSpeed = 1;
+ _vars._speedCount = 1;
+ _getBack = 1;
+}
+
+void DreamWebEngine::useWindow() {
+ if (_mansPath != 6) {
+ // Not on balcony
+ showSecondUse();
+ putBackObStuff();
+ } else {
+ _vars._progressPoints++;
+ showFirstUse();
+ _newLocation = 29;
+ _getBack = 1;
+ }
+}
+
+void DreamWebEngine::trapDoor() {
+ _vars._progressPoints++;
+ showFirstUse();
+ switchRyanOff();
+ _vars._watchingTime = 20 * 2;
+ _vars._reelToWatch = 181;
+ _vars._endWatchReel = 197;
+ _newLocation = 26;
+ _vars._watchSpeed = 1;
+ _vars._speedCount = 1;
+ _getBack = 1;
+}
+
+void DreamWebEngine::callEdensLift() {
+ showFirstUse();
+ _vars._countToOpen = 8;
+ _getBack = 1;
+ turnPathOn(2);
+}
+
+void DreamWebEngine::callEdensDLift() {
+ if (_vars._liftFlag == 1) {
+ // Eden's D here
+ showSecondUse();
+ putBackObStuff();
+ } else {
+ showFirstUse();
+ _vars._countToOpen = 8;
+ _getBack = 1;
+ turnPathOn(2);
+ }
+}
+
+void DreamWebEngine::openYourNeighbour() {
+ enterCode(255, 255, 255, 255);
+ _getBack = 1;
+}
+
+void DreamWebEngine::openRyan() {
+ enterCode(5, 1, 0, 6);
+ _getBack = 1;
+}
+
+void DreamWebEngine::openPoolBoss() {
+ enterCode(5, 2, 2, 2);
+ _getBack = 1;
+}
+
+void DreamWebEngine::openEden() {
+ enterCode(2, 8, 6, 5);
+ _getBack = 1;
+}
+
+void DreamWebEngine::openSarters() {
+ enterCode(7, 8, 3, 3);
+ _getBack = 1;
+}
+
+void DreamWebEngine::openLouis() {
+ enterCode(5, 2, 3, 8);
+ _getBack = 1;
+}
+
+
+void DreamWebEngine::useWall() {
+ showFirstUse();
+
+ if (_mansPath != 3) {
+ _vars._watchingTime = 30*2;
+ _vars._reelToWatch = 2;
+ _vars._endWatchReel = 31;
+ _vars._watchSpeed = 1;
+ _vars._speedCount = 1;
+ _getBack = 1;
+ turnPathOn(3);
+ turnPathOn(4);
+ turnPathOff(0);
+ turnPathOff(1);
+ turnPathOff(2);
+ turnPathOff(5);
+ _mansPath = 3;
+ _finalDest = 3;
+ findXYFromPath();
+ _resetManXY = 1;
+ switchRyanOff();
+ } else {
+ // Go back over
+ _vars._watchingTime = 30 * 2;
+ _vars._reelToWatch = 34;
+ _vars._endWatchReel = 60;
+ _vars._watchSpeed = 1;
+ _vars._speedCount = 1;
+ _getBack = 1;
+ turnPathOff(3);
+ turnPathOff(4);
+ turnPathOn(0);
+ turnPathOn(1);
+ turnPathOn(2);
+ turnPathOn(5);
+ _mansPath = 5;
+ _finalDest = 5;
+ findXYFromPath();
+ _resetManXY = 1;
+ switchRyanOff();
+ }
+}
+
+void DreamWebEngine::useLadder() {
+ showFirstUse();
+ _mapX = _mapX - 11;
+ findRoomInLoc();
+ _facing = 6;
+ _turnToFace = 6;
+ _mansPath = 0;
+ _destination = 0;
+ _finalDest = 0;
+ findXYFromPath();
+ _resetManXY = 1;
+ _getBack = 1;
+}
+
+void DreamWebEngine::useLadderB() {
+ showFirstUse();
+ _mapX = _mapX + 11;
+ findRoomInLoc();
+ _facing = 2;
+ _turnToFace = 2;
+ _mansPath = 1;
+ _destination = 1;
+ _finalDest = 1;
+ findXYFromPath();
+ _resetManXY = 1;
+ _getBack = 1;
+}
+
+void DreamWebEngine::slabDoorA() {
+ showFirstUse();
+ _getBack = 1;
+ _vars._watchSpeed = 1;
+ _vars._speedCount = 1;
+ _vars._reelToWatch = 13;
+ if (_vars._dreamNumber != 3) {
+ // Wrong
+ _vars._watchingTime = 40;
+ _vars._endWatchReel = 34;
+ _vars._watchSpeed = 1;
+ _vars._speedCount = 1;
+ } else {
+ _vars._progressPoints++;
+ _vars._watchingTime = 60;
+ _vars._endWatchReel = 42;
+ _newLocation = 47;
+ }
+}
+
+void DreamWebEngine::slabDoorB() {
+ if (_vars._dreamNumber != 1) {
+ // Wrong
+ showFirstUse();
+ _getBack = 1;
+ _vars._watchSpeed = 1;
+ _vars._speedCount = 1;
+ _vars._reelToWatch = 44;
+ _vars._watchingTime = 40;
+ _vars._endWatchReel = 63;
+ _vars._watchSpeed = 1;
+ _vars._speedCount = 1;
+ } else {
+ if (!isRyanHolding("SHLD")) {
+ // No crystal
+ showPuzText(44, 200);
+ putBackObStuff();
+ } else {
+ // Got crystal
+ showFirstUse();
+ _vars._progressPoints++;
+ _getBack = 1;
+ _vars._watchSpeed = 1;
+ _vars._speedCount = 1;
+ _vars._reelToWatch = 44;
+ _vars._watchingTime = 60;
+ _vars._endWatchReel = 71;
+ _newLocation = 47;
+ }
+ }
+}
+
+void DreamWebEngine::slabDoorC() {
+ showFirstUse();
+ _getBack = 1;
+ _vars._watchSpeed = 1;
+ _vars._speedCount = 1;
+ _vars._reelToWatch = 108;
+ if (_vars._dreamNumber != 4) {
+ // Wrong
+ _vars._watchingTime = 40;
+ _vars._endWatchReel = 127;
+ _vars._watchSpeed = 1;
+ _vars._speedCount = 1;
+ } else {
+ _vars._progressPoints++;
+ _vars._watchingTime = 60;
+ _vars._endWatchReel = 135;
+ _newLocation = 47;
+ }
+}
+
+void DreamWebEngine::slabDoorD() {
+ showFirstUse();
+ _getBack = 1;
+ _vars._watchSpeed = 1;
+ _vars._speedCount = 1;
+ _vars._reelToWatch = 75;
+ if (_vars._dreamNumber != 0) {
+ // Wrong
+ _vars._watchingTime = 40;
+ _vars._endWatchReel = 94;
+ _vars._watchSpeed = 1;
+ _vars._speedCount = 1;
+ } else {
+ _vars._progressPoints++;
+ _vars._watchingTime = 60;
+ _vars._endWatchReel = 102;
+ _newLocation = 47;
+ }
+}
+
+void DreamWebEngine::slabDoorE() {
+ showFirstUse();
+ _getBack = 1;
+ _vars._watchSpeed = 1;
+ _vars._speedCount = 1;
+ _vars._reelToWatch = 141;
+ if (_vars._dreamNumber != 5) {
+ // Wrong
+ _vars._watchingTime = 40;
+ _vars._endWatchReel = 160;
+ _vars._watchSpeed = 1;
+ _vars._speedCount = 1;
+ } else {
+ _vars._progressPoints++;
+ _vars._watchingTime = 60;
+ _vars._endWatchReel = 168;
+ _newLocation = 47;
+ }
+}
+
+void DreamWebEngine::slabDoorF() {
+ showFirstUse();
+ _getBack = 1;
+ _vars._watchSpeed = 1;
+ _vars._speedCount = 1;
+ _vars._reelToWatch = 171;
+ if (_vars._dreamNumber != 2) {
+ // Wrong
+ _vars._watchingTime = 40;
+ _vars._endWatchReel = 189;
+ _vars._watchSpeed = 1;
+ _vars._speedCount = 1;
+ } else {
+ _vars._progressPoints++;
+ _vars._watchingTime = 60;
+ _vars._endWatchReel = 197;
+ _newLocation = 47;
+ }
+}
+
+bool DreamWebEngine::defaultUseHandler(const char *id) {
+ if (_withObject == 255) {
+ withWhat();
+ return true; // event handled
+ }
+
+ if (!compare(_withObject, _withType, id)) {
+ // Wrong item
+ showPuzText(14, 300);
+ putBackObStuff();
+ return true; // event handled
+ }
+
+ return false; // continue with the original event
+}
+
+void DreamWebEngine::useChurchGate() {
+ if (defaultUseHandler("CUTT"))
+ return;
+
+ // Cut gate
+ showFirstUse();
+ _vars._watchingTime = 64 * 2;
+ _vars._reelToWatch = 4;
+ _vars._endWatchReel = 70;
+ _vars._watchSpeed = 1;
+ _vars._speedCount = 1;
+ _getBack = 1;
+ _vars._progressPoints++;
+ turnPathOn(3);
+ if (_vars._aideDead != 0)
+ turnPathOn(2); // Open church
+}
+
+void DreamWebEngine::useGun() {
+
+ if (_objectType != kExObjectType) {
+ // gun is not taken
+ showSecondUse();
+ putBackObStuff();
+
+ } else if (_realLocation == 22) {
+ // in pool room
+ showPuzText(34, 300);
+ _vars._lastWeapon = 1;
+ _vars._combatCount = 39;
+ _getBack = 1;
+ _vars._progressPoints++;
+
+ } else if (_realLocation == 25) {
+ // helicopter
+ showPuzText(34, 300);
+ _vars._lastWeapon = 1;
+ _vars._combatCount = 19;
+ _getBack = 1;
+ _vars._dreamNumber = 2;
+ _vars._roomAfterDream = 38;
+ _vars._sartainDead = 1;
+ _vars._progressPoints++;
+
+ } else if (_realLocation == 27) {
+ // in rock room
+ showPuzText(46, 300);
+ _pointerMode = 2;
+ _vars._rockstarDead = 1;
+ _vars._lastWeapon = 1;
+ _vars._newsItem = 1;
+ _getBack = 1;
+ _vars._roomAfterDream = 32;
+ _vars._dreamNumber = 0;
+ _vars._progressPoints++;
+
+ } else if (_realLocation == 8 && _mapX == 22 && _mapY == 40
+ && !isSetObOnMap(92) && _mansPath != 9) {
+ // by studio
+ _destination = 9;
+ _finalDest = 9;
+ autoSetWalk();
+ _vars._lastWeapon = 1;
+ _getBack = 1;
+ _vars._progressPoints++;
+
+ } else if (_realLocation == 6 && _mapX == 11 && _mapY == 20
+ && isSetObOnMap(5)) {
+ // sarters
+ _destination = 1;
+ _finalDest = 1;
+ autoSetWalk();
+ removeSetObject(5);
+ placeSetObject(6);
+ turnAnyPathOn(1, _roomNum - 1);
+ _vars._liftFlag = 1;
+ _vars._watchingTime = 40*2;
+ _vars._reelToWatch = 4;
+ _vars._endWatchReel = 43;
+ _vars._watchSpeed = 1;
+ _vars._speedCount = 1;
+ _getBack = 1;
+ _vars._progressPoints++;
+
+ } else if (_realLocation == 29) {
+ // aide
+ _getBack = 1;
+ resetLocation(13);
+ setLocation(12);
+ _destPos = 12;
+ _destination = 2;
+ _finalDest = 2;
+ autoSetWalk();
+ _vars._watchingTime = 164*2;
+ _vars._reelToWatch = 3;
+ _vars._endWatchReel = 164;
+ _vars._watchSpeed = 1;
+ _vars._speedCount = 1;
+ _vars._aideDead = 1;
+ _vars._dreamNumber = 3;
+ _vars._roomAfterDream = 33;
+ _vars._progressPoints++;
+
+ } else if (_realLocation == 23 && _mapX == 0 && _mapY == 50) {
+ // with boss
+ if (_mansPath != 5) {
+ _destination = 5;
+ _finalDest = 5;
+ autoSetWalk();
+ }
+ _vars._lastWeapon = 1;
+ _getBack = 1;
+
+ } else if (_realLocation == 8 && _mapX == 11 && _mapY == 10) {
+ // tv soldier
+ if (_mansPath != 2) {
+ _destination = 2;
+ _finalDest = 2;
+ autoSetWalk();
+ }
+ _vars._lastWeapon = 1;
+ _getBack = 1;
+
+ } else {
+ showFirstUse();
+ putBackObStuff();
+ }
+}
+
+void DreamWebEngine::useFullCart() {
+ _vars._progressPoints++;
+ turnAnyPathOn(2, _roomNum + 6);
+ _mansPath = 4;
+ _facing = 4;
+ _turnToFace = 4;
+ _finalDest = 4;
+ findXYFromPath();
+ _resetManXY = 1;
+ showFirstUse();
+ _vars._watchingTime = 72 * 2;
+ _vars._reelToWatch = 58;
+ _vars._endWatchReel = 142;
+ _vars._watchSpeed = 1;
+ _vars._speedCount = 1;
+ _getBack = 1;
+}
+
+void DreamWebEngine::useClearBox() {
+ if (defaultUseHandler("RAIL"))
+ return;
+
+ // Open box
+ _vars._progressPoints++;
+ showFirstUse();
+ _vars._watchingTime = 80;
+ _vars._reelToWatch = 67;
+ _vars._endWatchReel = 105;
+ _vars._watchSpeed = 1;
+ _vars._speedCount = 1;
+ _getBack = 1;
+}
+
+void DreamWebEngine::openTVDoor() {
+ if (defaultUseHandler("ULOK"))
+ return;
+
+ // Key on TV
+ showFirstUse();
+ _vars._lockStatus = 0;
+ _getBack = 1;
+}
+
+void DreamWebEngine::usePlate() {
+ if (_withObject == 255) {
+ withWhat();
+ return;
+ }
+
+ if (compare(_withObject, _withType, "SCRW")) {
+ // Unscrew plate
+ playChannel1(20);
+ showFirstUse();
+ placeSetObject(28);
+ placeSetObject(24);
+ removeSetObject(25);
+ placeFreeObject(0);
+ _vars._progressPoints++;
+ _getBack = 1;
+ } else if (compare(_withObject, _withType, "KNFE")) {
+ // Tried knife
+ showPuzText(54, 300);
+ putBackObStuff();
+ } else {
+ // Wrong item
+ showPuzText(14, 300);
+ putBackObStuff();
+ }
+}
+
+void DreamWebEngine::usePlinth() {
+ if (_withObject == 255) {
+ withWhat();
+ return;
+ }
+
+ if (!compare(_withObject, _withType, "DKEY")) {
+ // Wrong key
+ showFirstUse();
+ putBackObStuff();
+ } else {
+ _vars._progressPoints++;
+ showSecondUse();
+ _vars._watchingTime = 220;
+ _vars._reelToWatch = 0;
+ _vars._endWatchReel = 104;
+ _vars._watchSpeed = 1;
+ _vars._speedCount = 1;
+ _getBack = 1;
+ _newLocation = _vars._roomAfterDream;
+ }
+}
+
+void DreamWebEngine::useElvDoor() {
+ if (defaultUseHandler("AXED"))
+ return;
+
+ // Axe on door
+ showPuzText(15, 300);
+ _vars._progressPoints++;
+ _vars._watchingTime = 46 * 2;
+ _vars._reelToWatch = 31;
+ _vars._endWatchReel = 77;
+ _vars._watchSpeed = 1;
+ _vars._speedCount = 1;
+ _getBack = 1;
+}
+
+void DreamWebEngine::useObject() {
+ _withObject = 255;
+
+ if (_commandType != 229) {
+ _commandType = 229;
+ commandWithOb(51, _objectType, _command);
+ }
+
+ if (_mouseButton == _oldButton)
+ return; // nouse
+
+ if (_mouseButton & 1)
+ useRoutine();
+}
+
+void DreamWebEngine::useWinch() {
+ uint16 contentIndex = checkInside(40, 1);
+ if (contentIndex == kNumexobjects || !compare(contentIndex, kExObjectType, "FUSE")) {
+ // No winch
+ showFirstUse();
+ putBackObStuff();
+ return;
+ }
+
+ _vars._watchingTime = 217 * 2;
+ _vars._reelToWatch = 0;
+ _vars._endWatchReel = 217;
+ _vars._watchSpeed = 1;
+ _vars._speedCount = 1;
+ _destPos = 1;
+ _newLocation = 45;
+ _vars._dreamNumber = 1;
+ _vars._roomAfterDream = 44;
+ _vars._generalDead = 1;
+ _vars._newsItem = 2;
+ _getBack = 1;
+ _vars._progressPoints++;
+}
+
+void DreamWebEngine::useCart() {
+ if (defaultUseHandler("ROCK"))
+ return;
+
+ DynObject *exObject = getExAd(_withObject);
+ exObject->mapad[0] = 0;
+ removeSetObject(_command);
+ placeSetObject(_command + 1);
+ _vars._progressPoints++;
+ playChannel1(17);
+ showFirstUse();
+ _getBack = 1;
+}
+
+void DreamWebEngine::useTrainer() {
+ uint8 dummy;
+ DynObject *object = (DynObject *)getAnyAd(&dummy, &dummy);
+ if (object->mapad[0] != 4) {
+ notHeldError();
+ } else {
+ _vars._progressPoints++;
+ makeWorn(object);
+ showSecondUse();
+ putBackObStuff();
+ }
+}
+
+void DreamWebEngine::chewy() {
+ // Chewing a gum
+ showFirstUse();
+ uint8 dummy;
+ DynObject *object = (DynObject *)getAnyAd(&dummy, &dummy);
+ object->mapad[0] = 255;
+ _getBack = 1;
+}
+
+void DreamWebEngine::useHole() {
+ if (defaultUseHandler("HNDA"))
+ return;
+
+ showFirstUse();
+ removeSetObject(86);
+ DynObject *exObject = getExAd(_withObject);
+ exObject->mapad[0] = 255;
+ _vars._canMoveAltar = 1;
+ _getBack = 1;
+}
+
+void DreamWebEngine::openHotelDoor() {
+ if (defaultUseHandler("KEYA"))
+ return;
+
+ playChannel1(16);
+ showFirstUse();
+ _vars._lockStatus = 0;
+ _getBack = 1;
+}
+
+void DreamWebEngine::openHotelDoor2() {
+ if (defaultUseHandler("KEYA"))
+ return;
+
+ playChannel1(16);
+ showFirstUse();
+ putBackObStuff();
+}
+
+void DreamWebEngine::grafittiDoor() {
+ if (defaultUseHandler("APEN"))
+ return;
+
+ showFirstUse();
+ putBackObStuff();
+}
+
+void DreamWebEngine::usePoolReader() {
+ if (defaultUseHandler("MEMB"))
+ return;
+
+ if (_vars._talkedToAttendant != 1) {
+ // Can't open pool
+ showSecondUse();
+ putBackObStuff();
+ } else {
+ playChannel1(17);
+ showFirstUse();
+ _vars._countToOpen = 6;
+ _getBack = 1;
+ }
+}
+
+void DreamWebEngine::useCardReader1() {
+ if (defaultUseHandler("CSHR"))
+ return;
+
+ if (_vars._talkedToSparky == 0) {
+ // Not yet
+ showFirstUse();
+ putBackObStuff();
+ } else if (_vars._card1Money != 0) {
+ // No cash
+ showPuzText(17, 300);
+ putBackObStuff();
+ } else {
+ // Get cash
+ playChannel1(16);
+ showPuzText(18, 300);
+ _vars._progressPoints++;
+ _vars._card1Money = 12432;
+ _getBack = 1;
+ }
+}
+
+void DreamWebEngine::useCardReader2() {
+ if (defaultUseHandler("CSHR"))
+ return;
+
+ if (_vars._talkedToBoss == 0) {
+ // Haven't talked to boss
+ showFirstUse();
+ putBackObStuff();
+ } else if (_vars._card1Money == 0) {
+ // No cash
+ showPuzText(20, 300);
+ putBackObStuff();
+ } else if (_vars._gunPassFlag == 2) {
+ // Already got new
+ showPuzText(22, 300);
+ putBackObStuff();
+ } else {
+ playChannel1(18);
+ showPuzText(19, 300);
+ placeSetObject(94);
+ _vars._gunPassFlag = 1;
+ _vars._card1Money -= 2000;
+ _vars._progressPoints++;
+ _getBack = 1;
+ }
+}
+
+void DreamWebEngine::useCardReader3() {
+ if (defaultUseHandler("CSHR"))
+ return;
+
+ if (_vars._talkedToRecep == 0) {
+ // Haven't talked to receptionist
+ showFirstUse();
+ putBackObStuff();
+ } else if (_vars._cardPassFlag != 0) {
+ // Already used it
+ showPuzText(26, 300);
+ putBackObStuff();
+ } else {
+ playChannel1(16);
+ showPuzText(25, 300);
+ _vars._progressPoints++;
+ _vars._card1Money -= 8300;
+ _vars._cardPassFlag = 1;
+ _getBack = 1;
+ }
+}
+
+void DreamWebEngine::useLighter() {
+ if (_withObject == 255) {
+ withWhat();
+ return;
+ }
+
+ if (!compare(_withObject, _withType, "SMKE")) {
+ showFirstUse();
+ putBackObStuff();
+ } else {
+ showPuzText(9, 300);
+ DynObject *withObj = getExAd(_withObject);
+ withObj->mapad[0] = 255;
+ _getBack = 1;
+ }
+}
+
+void DreamWebEngine::useWire() {
+ if (_withObject == 255) {
+ withWhat();
+ return;
+ }
+
+ if (compare(_withObject, _withType, "KNFE")) {
+ removeSetObject(51);
+ placeSetObject(52);
+ showPuzText(11, 300);
+ _vars._progressPoints++;
+ _getBack = 1;
+ return;
+ }
+
+ if (compare(_withObject, _withType, "AXED")) {
+ showPuzText(16, 300);
+ putBackObStuff();
+ return;
+ }
+
+ showPuzText(14, 300);
+ putBackObStuff();
+}
+
+void DreamWebEngine::openTomb() {
+ _vars._progressPoints++;
+ showFirstUse();
+ _vars._watchingTime = 35 * 2;
+ _vars._reelToWatch = 1;
+ _vars._endWatchReel = 33;
+ _vars._watchSpeed = 1;
+ _vars._speedCount = 1;
+ _getBack = 1;
+}
+
+void DreamWebEngine::hotelControl() {
+ if (_realLocation != 21 || _mapX != 33)
+ showSecondUse(); // Not right control
+ else
+ showFirstUse();
+
+ putBackObStuff();
+}
+
+void DreamWebEngine::useCooker() {
+ if (checkInside(_command, _objectType) == kNumexobjects)
+ showFirstUse();
+ else
+ showSecondUse(); // Food inside
+
+ putBackObStuff();
+}
+
+void DreamWebEngine::placeFreeObject(uint8 index) {
+ findOrMake(index, 0, 1);
+ getFreeAd(index)->mapad[0] = 0;
+}
+
+void DreamWebEngine::removeFreeObject(uint8 index) {
+ getFreeAd(index)->mapad[0] = 0xFF;
+}
+
+void DreamWebEngine::useControl() {
+ if (_withObject == 255) {
+ withWhat();
+ return;
+ }
+
+ if (compare(_withObject, _withType, "KEYA")) { // Right key
+ playChannel1(16);
+ if (_vars._location == 21) { // Going down
+ showPuzText(3, 300);
+ _newLocation = 30;
+ } else {
+ showPuzText(0, 300);
+ _newLocation = 21;
+ }
+
+ _vars._countToClose = 8;
+ _vars._countToOpen = 0;
+ _vars._watchingTime = 80;
+ _getBack = 1;
+ return;
+ }
+
+ if (_realLocation == 21) {
+ if (compare(_withObject, _withType, "KNFE")) {
+ // Jimmy controls
+ placeSetObject(50);
+ placeSetObject(51);
+ placeSetObject(26);
+ placeSetObject(30);
+ removeSetObject(16);
+ removeSetObject(17);
+ playChannel1(14);
+ showPuzText(10, 300);
+ _vars._progressPoints++;
+ _getBack = 1;
+ } else if (compare(_withObject, _withType, "AXED")) {
+ // Axe on controls
+ showPuzText(16, 300);
+ _vars._progressPoints++;
+ putBackObStuff();
+ } else {
+ // Balls
+ showFirstUse();
+ putBackObStuff();
+ }
+ } else {
+ // Balls
+ showFirstUse();
+ putBackObStuff();
+ }
+}
+
+void DreamWebEngine::useSlab() {
+ if (_withObject == 255) {
+ withWhat();
+ return;
+ }
+
+ if (!compare(_withObject, _withType, "JEWL")) {
+ showPuzText(14, 300);
+ putBackObStuff();
+ return;
+ }
+
+ DynObject *exObject = getExAd(_withObject);
+ exObject->mapad[0] = 0;
+
+ removeSetObject(_command);
+ placeSetObject(_command + 1);
+ if (_command + 1 == 54) {
+ // Last slab
+ turnPathOn(0);
+ _vars._watchingTime = 22;
+ _vars._reelToWatch = 35;
+ _vars._endWatchReel = 48;
+ _vars._watchSpeed = 1;
+ _vars._speedCount = 1;
+ }
+
+ _vars._progressPoints++;
+ showFirstUse();
+ _getBack = 1;
+}
+
+void DreamWebEngine::usePipe() {
+ if (_withObject == 255) {
+ withWhat();
+ return;
+ }
+
+ if (compare(_withObject, _withType, "CUPE")) {
+ // Fill cup
+ showPuzText(36, 300);
+ putBackObStuff();
+ DynObject *exObject = getExAd(_withObject);
+ exObject->objId[3] = 'F'-'A'; // CUPE (empty cup) -> CUPF (full cup)
+ return;
+ } else if (compare(_withObject, _withType, "CUPF")) {
+ // Already full
+ showPuzText(35, 300);
+ putBackObStuff();
+ } else {
+ showPuzText(14, 300);
+ putBackObStuff();
+ }
+}
+
+void DreamWebEngine::useOpenBox() {
+ if (_withObject == 255) {
+ withWhat();
+ return;
+ }
+
+ if (compare(_withObject, _withType, "CUPF")) {
+ // Destroy open box
+ _vars._progressPoints++;
+ showPuzText(37, 300);
+ DynObject *exObject = getExAd(_withObject);
+ exObject->objId[3] = 'E'-'A'; // CUPF (full cup) -> CUPE (empty cup)
+ _vars._watchingTime = 140;
+ _vars._reelToWatch = 105;
+ _vars._endWatchReel = 181;
+ _vars._watchSpeed = 1;
+ _vars._speedCount = 1;
+ turnPathOn(4);
+ _getBack = 1;
+ return;
+ }
+
+ if (compare(_withObject, _withType, "CUPE")) {
+ // Open box wrong
+ showPuzText(38, 300);
+ putBackObStuff();
+ return;
+ }
+
+ showFirstUse();
+}
+
+void DreamWebEngine::runTap() {
+ if (_withObject == 255) {
+ withWhat();
+ return;
+ }
+
+ if (compare(_withObject, _withType, "CUPE")) {
+ // Fill cup from tap
+ DynObject *exObject = getExAd(_withObject);
+ exObject->objId[3] = 'F'-'A'; // CUPE (empty cup) -> CUPF (full cup)
+ playChannel1(8);
+ showPuzText(57, 300);
+ putBackObStuff();
+ return;
+ }
+
+ if (compare(_withObject, _withType, "CUPF")) {
+ // Cup from tap full
+ showPuzText(58, 300);
+ putBackObStuff();
+ return;
+ }
+
+ showPuzText(56, 300);
+ putBackObStuff();
+}
+
+void DreamWebEngine::useAxe() {
+ if (_realLocation != 22) {
+ // Not in pool
+ showFirstUse();
+ return;
+ }
+
+ if (_mapY == 10) {
+ // Axe on door
+ showPuzText(15, 300);
+ _vars._progressPoints++;
+ _vars._watchingTime = 46*2;
+ _vars._reelToWatch = 31;
+ _vars._endWatchReel = 77;
+ _vars._watchSpeed = 1;
+ _vars._speedCount = 1;
+ _getBack = 1;
+ return;
+ }
+
+ showSecondUse();
+ _vars._progressPoints++;
+ _vars._lastWeapon = 2;
+ _getBack = 1;
+ removeObFromInv();
+}
+
+void DreamWebEngine::useHandle() {
+ SetObject *object = getSetAd(findSetObject("CUTW"));
+ if (object->mapad[0] == 255) {
+ // Wire not cut
+ showPuzText(12, 300);
+ } else {
+ // Wire has been cut
+ showPuzText(13, 300);
+ _newLocation = 22;
+ }
+
+ _getBack = 1;
+}
+
+void DreamWebEngine::useAltar() {
+ if (findExObject("CNDA") == 114 || findExObject("CNDB") == 114) {
+ // Things on altar
+ showFirstUse();
+ _getBack = 1;
+ return;
+ }
+
+ if (_vars._canMoveAltar == 1) {
+ // Move altar
+ _vars._progressPoints++;
+ showSecondUse();
+ _vars._watchingTime = 160;
+ _vars._reelToWatch = 81;
+ _vars._endWatchReel = 174;
+ _vars._watchSpeed = 1;
+ _vars._speedCount = 1;
+ setupTimedUse(47, 32, 98, 52, 76);
+ _getBack = 1;
+ } else {
+ showPuzText(23, 300);
+ _getBack = 1;
+ }
+}
+
+void DreamWebEngine::withWhat() {
+ uint8 commandLine[64] = "OBJECT NAME ONE ";
+
+ createPanel();
+ showPanel();
+ showMan();
+ showExit();
+
+ copyName(_objectType, _command, commandLine);
+ printMessage2(100, 21, 63, 200, false, 2);
+ uint16 x = _lastXPos + 5;
+ printDirect(commandLine, x, 21, 220, false);
+ printMessage2(_lastXPos + 5, 21, 63, 200, false, 3);
+
+ fillRyan();
+ _commandType = 255;
+ readMouse();
+ showPointer();
+ workToScreen();
+ delPointer();
+ _invOpen = 2;
+}
+
+void DreamWebEngine::notHeldError() {
+ createPanel();
+ showPanel();
+ showMan();
+ showExit();
+ obIcons();
+ printMessage2(64, 100, 63, 200 + 1, true, 1);
+ workToScreenM();
+ hangOnP(50);
+ putBackObStuff();
+}
+
+void DreamWebEngine::useCashCard() {
+ getRidOfReels();
+ loadKeypad();
+ createPanel();
+ showPanel();
+ showExit();
+ showMan();
+ uint16 y = (!_foreignRelease) ? 120 : 120 - 3;
+ showFrame(_keypadGraphics, 114, y, 39, 0);
+ const uint8 *obText = getObTextStart();
+ findNextColon(&obText);
+ findNextColon(&obText);
+ y = 98;
+ printDirect(&obText, 36, &y, 36, 36 & 1);
+ char amountStr[10];
+ sprintf(amountStr, "%04d", _vars._card1Money / 10);
+ _charShift = 91 * 2 + 75;
+ printDirect((const uint8 *)amountStr, 160, 155, 240, 240 & 1);
+ sprintf(amountStr, "%02d", (_vars._card1Money % 10) * 10);
+ _charShift = 91 * 2 + 85;
+ printDirect((const uint8 *)amountStr, 187, 155, 240, 240 & 1);
+ _charShift = 0;
+ workToScreenM();
+ hangOnP(400);
+ _keypadGraphics.clear();
+ restoreReels();
+ putBackObStuff();
+}
+
+void DreamWebEngine::useStereo() {
+ // Handles the stereo in Ryan's apartment (accessible from the remote on
+ // the couch)
+
+ if (_vars._location != 0) {
+ showPuzText(4, 400);
+ putBackObStuff();
+ } else if (_mapX != 11) {
+ showPuzText(5, 400);
+ putBackObStuff();
+ } else if (checkInside(findSetObject("CDPL"), 1) == kNumexobjects) {
+ // No CD inside
+ showPuzText(6, 400);
+ putBackObStuff();
+ uint8 dummy;
+ DynObject *object = (DynObject *)getAnyAd(&dummy, &dummy);
+ object->turnedOn = 255;
+ } else {
+ // CD inside
+ uint8 dummy;
+ DynObject *object = (DynObject *)getAnyAd(&dummy, &dummy);
+ object->turnedOn ^= 1;
+ if (object->turnedOn != 255)
+ showPuzText(7, 400); // Stereo off
+ else
+ showPuzText(8, 400); // Stereo on
+
+ putBackObStuff();
+ }
+}
+
+uint16 DreamWebEngine::checkInside(uint16 command, uint16 type) {
+ for (uint16 index = 0; index < kNumexobjects; index++) {
+ DynObject *object = getExAd(index);
+ if (object->mapad[1] == command && object->mapad[0] == type)
+ return index;
+ }
+
+ return kNumexobjects;
+}
+
+void DreamWebEngine::showPuzText(uint16 command, uint16 count) {
+ createPanel();
+ showPanel();
+ showMan();
+ showExit();
+ obIcons();
+ const uint8 *string = (const uint8 *)_puzzleText.getString(command);
+ printDirect(string, 36, 104, 241, 241 & 1);
+ workToScreenM();
+ hangOnP(count);
+}
+
+void DreamWebEngine::useButtonA() {
+ if (!isSetObOnMap(95)) {
+ showFirstUse();
+ turnAnyPathOn(0, _roomNum - 1);
+ removeSetObject(9);
+ placeSetObject(95);
+ _vars._watchingTime = 15 * 2;
+ _vars._reelToWatch = 71;
+ _vars._endWatchReel = 85;
+ _vars._watchSpeed = 1;
+ _vars._speedCount = 1;
+ _getBack = 1;
+ _vars._progressPoints++;
+ } else {
+ // Done this bit
+ showSecondUse();
+ putBackObStuff();
+ }
}
-} /*namespace dreamgen */
+} // End of namespace DreamWeb
diff --git a/engines/dreamweb/vgafades.cpp b/engines/dreamweb/vgafades.cpp
new file mode 100644
index 0000000000..e8999ab18c
--- /dev/null
+++ b/engines/dreamweb/vgafades.cpp
@@ -0,0 +1,284 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "dreamweb/dreamweb.h"
+
+namespace DreamWeb {
+
+void DreamWebEngine::clearStartPal() {
+ memset(_startPal, 0, 256 * 3);
+}
+
+void DreamWebEngine::clearEndPal() {
+ memset(_endPal, 0, 256 * 3);
+}
+
+void DreamWebEngine::palToStartPal() {
+ memcpy(_startPal, _mainPal, 256 * 3);
+}
+
+void DreamWebEngine::endPalToStart() {
+ memcpy(_startPal, _endPal, 256 * 3);
+}
+
+void DreamWebEngine::startPalToEnd() {
+ memcpy(_endPal, _startPal, 256 * 3);
+}
+
+void DreamWebEngine::palToEndPal() {
+ memcpy(_endPal, _mainPal, 256 * 3);
+}
+
+void DreamWebEngine::fadeDOS() {
+ return; // FIXME later
+
+ waitForVSync();
+ //processEvents will be called from vsync
+ uint8 *dst = _startPal;
+ 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::doFade() {
+ if (_fadeDirection == 0)
+ return;
+
+ processEvents();
+ uint8 *src = _startPal + 3 * _colourPos;
+ setPalette(src, _colourPos, _numToFade);
+
+ _colourPos += _numToFade;
+ if (_colourPos == 0)
+ fadeCalculation();
+}
+
+void DreamWebEngine::fadeCalculation() {
+ if (_fadeCount == 0) {
+ _fadeDirection = 0;
+ return;
+ }
+
+ uint8 *startPal = _startPal;
+ const uint8 *endPal = _endPal;
+ for (size_t i = 0; i < 256 * 3; ++i) {
+ uint8 s = startPal[i];
+ uint8 e = endPal[i];
+ if (s == e)
+ continue;
+ else if (s > e)
+ --startPal[i];
+ else {
+ if (_fadeCount <= e)
+ ++startPal[i];
+ }
+ }
+ --_fadeCount;
+}
+
+void DreamWebEngine::fadeUpYellows() {
+ palToEndPal();
+ memset(_endPal + 231 * 3, 0, 8 * 3);
+ memset(_endPal + 246 * 3, 0, 1 * 3);
+ _fadeDirection = 1;
+ _fadeCount = 63;
+ _colourPos = 0;
+ _numToFade = 128;
+ hangOn(128);
+}
+
+void DreamWebEngine::fadeUpMonFirst() {
+ palToStartPal();
+ palToEndPal();
+ memset(_startPal + 231 * 3, 0, 8 * 3);
+ memset(_startPal + 246 * 3, 0, 1 * 3);
+ _fadeDirection = 1;
+ _fadeCount = 63;
+ _colourPos = 0;
+ _numToFade = 128;
+ hangOn(64);
+ playChannel1(26);
+ hangOn(64);
+}
+
+
+void DreamWebEngine::fadeDownMon() {
+ palToStartPal();
+ palToEndPal();
+ memset(_endPal + 231 * 3, 0, 8 * 3);
+ memset(_endPal + 246 * 3, 0, 1 * 3);
+ _fadeDirection = 1;
+ _fadeCount = 63;
+ _colourPos = 0;
+ _numToFade = 128;
+ hangOn(64);
+}
+
+void DreamWebEngine::fadeUpMon() {
+ palToStartPal();
+ palToEndPal();
+ memset(_startPal + 231 * 3, 0, 8 * 3);
+ memset(_startPal + 246 * 3, 0, 1 * 3);
+ _fadeDirection = 1;
+ _fadeCount = 63;
+ _colourPos = 0;
+ _numToFade = 128;
+ hangOn(128);
+}
+
+void DreamWebEngine::initialMonCols() {
+ palToStartPal();
+ memset(_startPal + 230 * 3, 0, 9 * 3);
+ memset(_startPal + 246 * 3, 0, 1 * 3);
+ processEvents();
+ setPalette(_startPal + 230 * 3, 230, 18);
+}
+
+void DreamWebEngine::fadeScreenUp() {
+ clearStartPal();
+ palToEndPal();
+ _fadeDirection = 1;
+ _fadeCount = 63;
+ _colourPos = 0;
+ _numToFade = 128;
+}
+
+void DreamWebEngine::fadeScreenUps() {
+ clearStartPal();
+ palToEndPal();
+ _fadeDirection = 1;
+ _fadeCount = 63;
+ _colourPos = 0;
+ _numToFade = 64;
+}
+
+void DreamWebEngine::fadeScreenUpHalf() {
+ endPalToStart();
+ palToEndPal();
+ _fadeDirection = 1;
+ _fadeCount = 31;
+ _colourPos = 0;
+ _numToFade = 32;
+}
+
+void DreamWebEngine::fadeScreenDown() {
+ palToStartPal();
+ clearEndPal();
+ _fadeDirection = 1;
+ _fadeCount = 63;
+ _colourPos = 0;
+ _numToFade = 128;
+}
+
+void DreamWebEngine::fadeScreenDowns() {
+ palToStartPal();
+ clearEndPal();
+ _fadeDirection = 1;
+ _fadeCount = 63;
+ _colourPos = 0;
+ _numToFade = 64;
+}
+
+void DreamWebEngine::fadeScreenDownHalf() {
+ palToStartPal();
+ palToEndPal();
+
+ const uint8 *startPal = _startPal;
+ uint8 *endPal = _endPal;
+ for (int i = 0; i < 256 * 3; ++i) {
+ *endPal >>= 1;
+ endPal++;
+ }
+
+ memcpy(endPal + (56*3), startPal + (56*3), 3*5);
+ memcpy(endPal + (77*3), startPal + (77*3), 3*2);
+
+ _fadeDirection = 1;
+ _fadeCount = 31;
+ _colourPos = 0;
+ _numToFade = 32;
+}
+
+
+void DreamWebEngine::clearPalette() {
+ _fadeDirection = 0;
+ clearStartPal();
+ dumpCurrent();
+}
+
+// Converts palette to grey scale, summed using formula
+// .20xred + .59xGreen + .11xBlue
+void DreamWebEngine::greyscaleSum() {
+ byte *src = _mainPal;
+ byte *dst = _endPal;
+
+ for (int i = 0; i < 256; ++i) {
+ const unsigned int r = 20 * *src++;
+ const unsigned int g = 59 * *src++;
+ const unsigned int b = 11 * *src++;
+ const byte grey = (r + b + g) / 100;
+ byte tmp;
+
+ tmp = grey;
+ //if (tmp != 0) // FIXME: The assembler code has this check commented out. Bug or feature?
+ tmp += _addToRed;
+ *dst++ = tmp;
+
+ tmp = grey;
+ if (tmp != 0)
+ tmp += _addToGreen;
+ *dst++ = tmp;
+
+ tmp = grey;
+ if (tmp != 0)
+ tmp += _addToBlue;
+ *dst++ = tmp;
+ }
+}
+
+void DreamWebEngine::allPalette() {
+ memcpy(_startPal, _mainPal, 3 * 256);
+ dumpCurrent();
+}
+
+void DreamWebEngine::dumpCurrent() {
+ uint8 *pal = _startPal;
+
+ waitForVSync();
+ processEvents();
+ setPalette(pal, 0, 128);
+
+ pal += 128 * 3;
+
+ waitForVSync();
+ processEvents();
+ setPalette(pal, 128, 128);
+}
+
+} // End of namespace DreamWeb
diff --git a/engines/dreamweb/vgagrafx.cpp b/engines/dreamweb/vgagrafx.cpp
index 53db811313..a66f156a1d 100644
--- a/engines/dreamweb/vgagrafx.cpp
+++ b/engines/dreamweb/vgagrafx.cpp
@@ -24,25 +24,12 @@
#include "engines/util.h"
#include "graphics/surface.h"
-namespace DreamGen {
+namespace DreamWeb {
-uint8 *DreamGenContext::workspace() {
- uint8 *result = segRef(data.word(kWorkspace)).ptr(0, 0);
- return result;
-}
-
-void DreamGenContext::allocatework() {
- data.word(kWorkspace) = allocatemem(0x1000);
-}
-
-void DreamGenContext::multiget() {
- multiget(ds.ptr(si, 0), di, bx, cl, ch);
- si += cl * ch;
- di += bx * kScreenwidth + kScreenwidth * ch;
- cx = 0;
-}
+const uint16 kZoomx = 8;
+const uint16 kZoomy = 132;
-void DreamGenContext::multiget(uint8 *dst, uint16 x, uint16 y, uint8 w, uint8 h) {
+void DreamWebEngine::multiGet(uint8 *dst, uint16 x, uint16 y, uint8 w, uint8 h) {
assert(x < 320);
assert(y < 200);
const uint8 *src = workspace() + x + y * kScreenwidth;
@@ -50,22 +37,15 @@ void DreamGenContext::multiget(uint8 *dst, uint16 x, uint16 y, uint8 w, uint8 h)
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) {
+ //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) {
const uint8 *src_p = src + kScreenwidth * l;
uint8 *dst_p = dst + w * l;
memcpy(dst_p, src_p, w);
}
}
-void DreamGenContext::multiput() {
- multiput(ds.ptr(si, 0), di, bx, cl, ch);
- si += cl * ch;
- di += bx * kScreenwidth + kScreenwidth * ch;
- cx = 0;
-}
-
-void DreamGenContext::multiput(const uint8 *src, uint16 x, uint16 y, uint8 w, uint8 h) {
+void DreamWebEngine::multiPut(const uint8 *src, uint16 x, uint16 y, uint8 w, uint8 h) {
assert(x < 320);
assert(y < 200);
uint8 *dst = workspace() + x + y * kScreenwidth;
@@ -73,43 +53,25 @@ void DreamGenContext::multiput(const uint8 *src, uint16 x, uint16 y, uint8 w, ui
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) {
+ //debug(1, "multiPut %ux%u -> segment: %04x->%04x", w, h, (uint16)ds, (uint16)es);
+ for (unsigned l = 0; l < h; ++l) {
const uint8 *src_p = src + w * l;
uint8 *dst_p = dst + kScreenwidth * l;
memcpy(dst_p, src_p, w);
}
}
-void DreamGenContext::multidump(uint16 x, uint16 y, uint8 width, uint8 height) {
+void DreamWebEngine::multiDump(uint16 x, uint16 y, uint8 width, uint8 height) {
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(workspace() + offset, kScreenwidth, x, y, width, height);
-}
-
-void DreamGenContext::multidump() {
- multidump(di, bx, cl, ch);
- unsigned offset = di + bx * kScreenwidth;
- si = di = offset + ch * kScreenwidth;
- cx = 0;
-}
-
-void DreamGenContext::worktoscreen() {
- uint size = 320 * 200;
- engine->blit(workspace(), 320, 0, 0, 320, 200);
- di = si = size;
- cx = 0;
-}
-
-void DreamGenContext::printundermon() {
- engine->printUnderMonitor();
+ //debug(1, "multiDump %ux%u(segment: %04x) -> %d,%d(address: %d)", w, h, (uint16)ds, x, y, offset);
+ blit(workspace() + offset, kScreenwidth, x, y, width, height);
}
-void DreamGenContext::cls() {
- engine->cls();
+void DreamWebEngine::workToScreen() {
+ blit(workspace(), 320, 0, 0, 320, 200);
}
-void DreamGenContext::frameoutnm(uint8 *dst, const uint8 *src, uint16 pitch, uint16 width, uint16 height, uint16 x, uint16 y) {
+void DreamWebEngine::frameOutNm(uint8 *dst, const uint8 *src, uint16 pitch, uint16 width, uint16 height, uint16 x, uint16 y) {
dst += pitch * y + x;
for (uint16 j = 0; j < height; ++j) {
@@ -119,7 +81,7 @@ void DreamGenContext::frameoutnm(uint8 *dst, const uint8 *src, uint16 pitch, uin
}
}
-void DreamGenContext::frameoutbh(uint8 *dst, const uint8 *src, uint16 pitch, uint16 width, uint16 height, uint16 x, uint16 y) {
+void DreamWebEngine::frameOutBh(uint8 *dst, const uint8 *src, uint16 pitch, uint16 width, uint16 height, uint16 x, uint16 y) {
uint16 stride = pitch - width;
dst += y * pitch + x;
@@ -135,7 +97,7 @@ void DreamGenContext::frameoutbh(uint8 *dst, const uint8 *src, uint16 pitch, uin
}
}
-void DreamGenContext::frameoutfx(uint8 *dst, const uint8 *src, uint16 pitch, uint16 width, uint16 height, uint16 x, uint16 y) {
+void DreamWebEngine::frameOutFx(uint8 *dst, const uint8 *src, uint16 pitch, uint16 width, uint16 height, uint16 x, uint16 y) {
uint16 stride = pitch - width;
dst += y * pitch + x;
dst -= width;
@@ -152,8 +114,8 @@ void DreamGenContext::frameoutfx(uint8 *dst, const uint8 *src, uint16 pitch, uin
}
}
-void DreamGenContext::doshake() {
- uint8 &counter = data.byte(kShakecounter);
+void DreamWebEngine::doShake() {
+ uint8 &counter = _vars._shakeCounter;
if (counter == 48)
return;
@@ -177,46 +139,22 @@ void DreamGenContext::doshake() {
0, -2, 3, -2, 0, 2, 4, -1,
1, -3, 3, 0,
};
+ assert(counter < ARRAYSIZE(shakeTable));
int offset = shakeTable[counter];
- engine->setShakePos(offset >= 0 ? offset : -offset);
+ 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 DreamWebEngine::vSync() {
+ waitForVSync();
}
-void DreamGenContext::setmode() {
- vsync();
+void DreamWebEngine::setMode() {
+ waitForVSync();
initGraphics(320, 200, false);
}
-static 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::showpcx() {
- Common::String name = getFilename(*this);
+void DreamWebEngine::showPCX(const Common::String &suffix) {
+ Common::String name = getDatafilePrefix() + suffix;
Common::File pcxFile;
if (!pcxFile.open(name)) {
@@ -224,20 +162,19 @@ void DreamGenContext::showpcx() {
return;
}
- uint8 *maingamepal;
+ 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);
+ mainGamePal = _mainPal;
+ pcxFile.read(mainGamePal, 48);
- memset(maingamepal + 48, 0xff, 720);
+ memset(mainGamePal + 48, 0xff, 720);
for (i = 0; i < 48; i++) {
- maingamepal[i] >>= 2;
+ mainGamePal[i] >>= 2;
}
// Decode the image data.
@@ -285,31 +222,31 @@ void DreamGenContext::showpcx() {
pcxFile.close();
}
-void DreamGenContext::frameoutv(uint8 *dst, const uint8 *src, uint16 pitch, uint16 width, uint16 height, int16 x, int16 y) {
+void DreamWebEngine::frameOutV(uint8 *dst, const uint8 *src, uint16 pitch, uint16 width, uint16 height, int16 x, int16 y) {
// NB : These resilience checks were not in the original engine, but did they result in undefined behaviour
// or was something broken during porting to C++?
assert(pitch == 320);
- if(x < 0) {
+ if (x < 0) {
assert(width >= -x);
width -= -x;
src += -x;
x = 0;
}
- if(y < 0) {
+ if (y < 0) {
assert(height >= -y);
height -= -y;
src += (-y) * width;
y = 0;
}
- if(x >= 320)
+ if (x >= 320)
return;
- if(y >= 200)
+ if (y >= 200)
return;
- if(x + width > 320) {
+ if (x + width > 320) {
width = 320 - x;
}
- if(y + height > 200) {
+ if (y + height > 200) {
height = 200 - y;
}
@@ -327,92 +264,114 @@ void DreamGenContext::frameoutv(uint8 *dst, const uint8 *src, uint16 pitch, uint
}
}
-void DreamGenContext::showframe(const Frame *frameData, uint16 x, uint16 y, uint16 frameNumber, uint8 effectsFlag) {
+void DreamWebEngine::showFrame(const GraphicsFile &frameData, uint16 x, uint16 y, uint16 frameNumber, uint8 effectsFlag) {
uint8 width, height;
- showframe(frameData, x, y, frameNumber, effectsFlag, &width, &height);
+ showFrame(frameData, x, y, frameNumber, effectsFlag, &width, &height);
}
-void DreamGenContext::showframe(const Frame *frameData, uint16 x, uint16 y, uint16 frameNumber, uint8 effectsFlag, uint8 *width, uint8 *height) {
- const Frame *frame = frameData + frameNumber;
- if ((frame->width == 0) && (frame->height == 0)) {
- *width = 0;
- *height = 0;
- return;
- }
-
-//notblankshow:
- if ((effectsFlag & 128) == 0) {
- x += frame->x;
- y += frame->y;
- }
-//skipoffsets:
-
- *width = frame->width;
- *height = frame->height;
- const uint8 *pSrc = ((const uint8 *)frameData) + frame->ptr() + 2080;
-
+void DreamWebEngine::showFrameInternal(const uint8 *pSrc, uint16 x, uint16 y, uint8 effectsFlag, uint8 width, uint8 height) {
if (effectsFlag) {
if (effectsFlag & 128) { //centred
- x -= *width / 2;
- y -= *height / 2;
- }
- if (effectsFlag & 64) { //diffdest
- frameoutfx(es.ptr(0, dx * *height), pSrc, dx, *width, *height, x, y);
- return;
+ x -= width / 2;
+ y -= height / 2;
}
- if (effectsFlag & 8) { //printlist
+ if (effectsFlag & 64) { // diffDest
+ error("Unsupported DreamWebEngine::showFrame effectsFlag %d", effectsFlag);
/*
- push(ax);
- al = x - data.word(kMapadx);
- ah = y - data.word(kMapady);
- //addtoprintlist(); // NB: Commented in the original asm
- ax = pop();
+ frameOutFx(es.ptr(0, dx * *height), pSrc, dx, *width, *height, x, y);
+ return;
*/
}
- if (effectsFlag & 4) { //flippedx
- frameoutfx(workspace(), pSrc, 320, *width, *height, x, y);
+ if (effectsFlag & 8) { // printList
+ //addToPrintList(x - _mapAdX, y - _mapAdY); // NB: Commented in the original asm
+ }
+ if (effectsFlag & 4) { // flippedX
+ frameOutFx(workspace(), pSrc, 320, width, height, x, y);
return;
}
- if (effectsFlag & 2) { //nomask
- frameoutnm(workspace(), pSrc, 320, *width, *height, x, y);
+ if (effectsFlag & 2) { // noMask
+ frameOutNm(workspace(), pSrc, 320, width, height, x, y);
return;
}
if (effectsFlag & 32) {
- frameoutbh(workspace(), pSrc, 320, *width, *height, x, y);
+ frameOutBh(workspace(), pSrc, 320, width, height, x, y);
return;
}
}
-//noeffects:
- frameoutv(workspace(), pSrc, 320, *width, *height, x, y);
- return;
+ // "noEffects"
+ frameOutV(workspace(), pSrc, 320, width, height, x, y);
}
-void DreamGenContext::showframe() {
- uint8 width, height;
- showframe((Frame *)ds.ptr(0, 0), di, bx, ax & 0x1ff, ah & 0xfe, &width, &height);
- cl = width;
- ch = height;
+void DreamWebEngine::showFrame(const GraphicsFile &frameData, uint16 x, uint16 y, uint16 frameNumber, uint8 effectsFlag, uint8 *width, uint8 *height) {
+ const Frame *frame = &frameData._frames[frameNumber];
+ if ((frame->width == 0) && (frame->height == 0)) {
+ *width = 0;
+ *height = 0;
+ return;
+ }
+
+ // "notBlankShow"
+ if ((effectsFlag & 128) == 0) {
+ x += frame->x;
+ y += frame->y;
+ }
+
+ // "skipOffsets"
+ *width = frame->width;
+ *height = frame->height;
+ const uint8 *pSrc = frameData.getFrameData(frameNumber);
+
+ showFrameInternal(pSrc, x, y, effectsFlag, *width, *height);
}
-void DreamGenContext::clearwork() {
+void DreamWebEngine::clearWork() {
memset(workspace(), 0, 320*200);
}
-void DreamGenContext::zoom() {
- if (data.word(kWatchingtime) != 0)
+void DreamWebEngine::dumpZoom() {
+ if (_vars._zoomOn == 1)
+ multiDump(kZoomx + 5, kZoomy + 4, 46, 40);
+}
+
+void DreamWebEngine::crosshair() {
+ uint8 frame;
+ if ((_commandType != 3) && (_commandType < 10)) {
+ frame = 9;
+ } else {
+ frame = 29;
+ }
+ showFrame(_icons1, kZoomx + 24, kZoomy + 19, frame, 0);
+}
+
+void DreamWebEngine::getUnderZoom() {
+ multiGet(_zoomSpace, kZoomx + 5, kZoomy + 4, 46, 40);
+}
+
+void DreamWebEngine::putUnderZoom() {
+ multiPut(_zoomSpace, kZoomx + 5, kZoomy + 4, 46, 40);
+}
+
+void DreamWebEngine::zoomIcon() {
+ if (_vars._zoomOn == 0)
+ return;
+ showFrame(_icons1, kZoomx, kZoomy-1, 8, 0);
+}
+
+void DreamWebEngine::zoom() {
+ if (_vars._watchingTime != 0)
return;
- if (data.byte(kZoomon) != 1)
+ if (_vars._zoomOn != 1)
return;
- if (data.byte(kCommandtype) >= 199) {
- putunderzoom();
+ if (_commandType >= 199) {
+ putUnderZoom();
return;
}
- uint16 srcOffset = (data.word(kOldpointery) - 9) * 320 + (data.word(kOldpointerx) - 11);
+ uint16 srcOffset = (_oldPointerY - 9) * 320 + (_oldPointerX - 11);
uint16 dstOffset = (kZoomy + 4) * 320 + (kZoomx + 5);
const uint8 *src = workspace() + srcOffset;
uint8 *dst = workspace() + dstOffset;
- for(size_t i=0; i<20; ++i) {
- for(size_t j=0; j<23; ++j) {
+ for (size_t i = 0; i < 20; ++i) {
+ for (size_t j = 0; j < 23; ++j) {
uint8 v = src[j];
dst[2*j+0] = v;
dst[2*j+1] = v;
@@ -423,46 +382,88 @@ void DreamGenContext::zoom() {
dst += 320*2;
}
crosshair();
- data.byte(kDidzoom) = 1;
+ _didZoom = 1;
}
-void DreamGenContext::paneltomap() {
- multiget(segRef(data.word(kMapstore)).ptr(0, 0), data.word(kMapxstart) + data.word(kMapadx), data.word(kMapystart) + data.word(kMapady), data.byte(kMapxsize), data.byte(kMapysize));
+void DreamWebEngine::panelToMap() {
+ multiGet(_mapStore, _mapXStart + _mapAdX, _mapYStart + _mapAdY, _mapXSize, _mapYSize);
}
-void DreamGenContext::maptopanel() {
- multiput(segRef(data.word(kMapstore)).ptr(0, 0), data.word(kMapxstart) + data.word(kMapadx), data.word(kMapystart) + data.word(kMapady), data.byte(kMapxsize), data.byte(kMapysize));
+void DreamWebEngine::mapToPanel() {
+ multiPut(_mapStore, _mapXStart + _mapAdX, _mapYStart + _mapAdY, _mapXSize, _mapYSize);
}
-void DreamGenContext::dumpmap() {
- multidump(data.word(kMapxstart) + data.word(kMapadx), data.word(kMapystart) + data.word(kMapady), data.byte(kMapxsize), data.byte(kMapysize));
+void DreamWebEngine::dumpMap() {
+ multiDump(_mapXStart + _mapAdX, _mapYStart + _mapAdY, _mapXSize, _mapYSize);
}
-void DreamGenContext::transferinv() {
- const Frame *freeFrames = (const Frame *)segRef(data.word(kFreeframes)).ptr(kFrframedata, 0);
- const Frame *freeFrame = freeFrames + (3 * data.byte(kItemtotran) + 1);
- Frame *exFrames = (Frame *)segRef(data.word(kExtras)).ptr(kExframedata, 0);
- Frame *exFrame = exFrames + (3 * data.byte(kExpos) + 1);
- exFrame->width = freeFrame->width;
- exFrame->height = freeFrame->height;
- exFrame->x = freeFrame->x;
- exFrame->y = freeFrame->y;
- uint16 byteCount = freeFrame->width * freeFrame->height;
- const uint8 *src = segRef(data.word(kFreeframes)).ptr(kFrframes + freeFrame->ptr(), byteCount);
- uint8 *dst = segRef(data.word(kExtras)).ptr(kExframes + data.word(kExframepos), byteCount);
- memcpy(dst, src, byteCount);
- exFrame->setPtr(data.word(kExframepos));
- data.word(kExframepos) += byteCount;
-}
-
-bool DreamGenContext::pixelcheckset(const ObjPos *pos, uint8 x, uint8 y) {
+bool DreamWebEngine::pixelCheckSet(const ObjPos *pos, uint8 x, uint8 y) {
x -= pos->xMin;
y -= pos->yMin;
- SetObject *setObject = getsetad(pos->index);
- Frame *frame = (Frame *)segRef(data.word(kSetframes)).ptr(kFramedata, 0) + setObject->index;
- const uint8 *ptr = segRef(data.word(kSetframes)).ptr(kFrames, 0) + frame->ptr() + y * frame->width + x;
+ SetObject *setObject = getSetAd(pos->index);
+ const Frame &frame = _setFrames._frames[setObject->index];
+ const uint8 *ptr = _setFrames.getFrameData(setObject->index) + y * frame.width + x;
return *ptr != 0;
}
-} /*namespace dreamgen */
+void DreamWebEngine::loadPalFromIFF() {
+ Common::File palFile;
+ uint8* buf = new uint8[2000];
+ palFile.open(getDatafilePrefix() + "PAL");
+ palFile.read(buf, 2000);
+ palFile.close();
+
+ const uint8 *src = buf + 0x30;
+ uint8 *dst = _mainPal;
+ for (size_t i = 0; i < 256*3; ++i) {
+ uint8 c = src[i] / 4;
+ if (_brightPalette) {
+ if (c) {
+ c = c + c / 2 + c / 4;
+ if (c > 63)
+ c = 63;
+ }
+ }
+ dst[i] = c;
+ }
+
+ delete[] buf;
+}
+
+void DreamWebEngine::createPanel() {
+ showFrame(_icons2, 0, 8, 0, 2);
+ showFrame(_icons2, 160, 8, 0, 2);
+ showFrame(_icons2, 0, 104, 0, 2);
+ showFrame(_icons2, 160, 104, 0, 2);
+}
+
+void DreamWebEngine::createPanel2() {
+ createPanel();
+ showFrame(_icons2, 0, 0, 5, 2);
+ showFrame(_icons2, 160, 0, 5, 2);
+}
+
+void DreamWebEngine::showPanel() {
+ showFrame(_icons1, 72, 0, 19, 0);
+ showFrame(_icons1, 192, 0, 19, 0);
+}
+
+void DreamWebEngine::transferFrame(uint8 from, uint8 to, uint8 offset) {
+ const Frame &freeFrame = _freeFrames._frames[3*from + offset];
+ Frame &exFrame = _exFrames._frames[3*to + offset];
+
+ exFrame.width = freeFrame.width;
+ exFrame.height = freeFrame.height;
+ exFrame.x = freeFrame.x;
+ exFrame.y = freeFrame.y;
+ uint16 byteCount = freeFrame.width * freeFrame.height;
+
+ const uint8 *src = _freeFrames.getFrameData(3*from + offset);
+ uint8 *dst = _exFrames._data + _vars._exFramePos;
+ memcpy(dst, src, byteCount);
+
+ exFrame.setPtr(_vars._exFramePos);
+ _vars._exFramePos += byteCount;
+}
+} // End of namespace DreamWeb
diff --git a/engines/engine.cpp b/engines/engine.cpp
index ee1d53fa9c..2ef4ecab60 100644
--- a/engines/engine.cpp
+++ b/engines/engine.cpp
@@ -45,6 +45,8 @@
#include "common/textconsole.h"
#include "common/translation.h"
+#include "backends/keymapper/keymapper.h"
+
#include "gui/debugger.h"
#include "gui/dialog.h"
#include "gui/message.h"
@@ -418,12 +420,16 @@ void Engine::openMainMenuDialog() {
// (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);
+ if (_saveSlotToLoad >= 0) {
+ Common::Error status = loadGameState(_saveSlotToLoad);
+ if (status.getCode() != Common::kNoError) {
+ Common::String failMessage = Common::String::format(_("Gamestate load failed (%s)! "
+ "Please consult the README for basic information, and for "
+ "instructions on how to obtain further assistance."), status.getDesc().c_str());
+ GUI::MessageDialog dialog(failMessage);
+ dialog.runModal();
+ }
+ }
syncSoundSettings();
}
@@ -479,16 +485,32 @@ void Engine::syncSoundSettings() {
if (ConfMan.hasKey("mute"))
mute = ConfMan.getBool("mute");
+ // We need to handle the speech mute separately here. This is because the
+ // engine code should be able to rely on all speech sounds muted when the
+ // user specified subtitles only mode, which results in "speech_mute" to
+ // be set to "true". The global mute setting has precedence over the
+ // speech mute setting though.
+ bool speechMute = mute;
+ if (!speechMute)
+ speechMute = ConfMan.getBool("speech_mute");
+
_mixer->muteSoundType(Audio::Mixer::kPlainSoundType, mute);
_mixer->muteSoundType(Audio::Mixer::kMusicSoundType, mute);
_mixer->muteSoundType(Audio::Mixer::kSFXSoundType, mute);
- _mixer->muteSoundType(Audio::Mixer::kSpeechSoundType, mute);
+ _mixer->muteSoundType(Audio::Mixer::kSpeechSoundType, speechMute);
+
_mixer->setVolumeForSoundType(Audio::Mixer::kPlainSoundType, Audio::Mixer::kMaxMixerVolume);
_mixer->setVolumeForSoundType(Audio::Mixer::kMusicSoundType, soundVolumeMusic);
_mixer->setVolumeForSoundType(Audio::Mixer::kSFXSoundType, soundVolumeSFX);
_mixer->setVolumeForSoundType(Audio::Mixer::kSpeechSoundType, soundVolumeSpeech);
}
+void Engine::deinitKeymap() {
+#ifdef ENABLE_KEYMAPPER
+ _eventMan->getKeymapper()->cleanupGameKeymaps();
+#endif
+}
+
void Engine::flipMute() {
// Mute will be set to true by default here. This has two reasons:
// - if the game already has an "mute" config entry, it will be overwritten anyway.
diff --git a/engines/engine.h b/engines/engine.h
index 2796df5c4f..4f4223384a 100644
--- a/engines/engine.h
+++ b/engines/engine.h
@@ -24,6 +24,8 @@
#include "common/scummsys.h"
#include "common/str.h"
+#include "common/language.h"
+#include "common/platform.h"
class OSystem;
@@ -180,6 +182,16 @@ public:
*/
virtual void syncSoundSettings();
+ /*
+ * Initialize any engine-specific keymaps.
+ */
+ virtual void initKeymap() {}
+
+ /*
+ * Cleanup any engine-specific keymaps.
+ */
+ virtual void deinitKeymap();
+
/**
* Flip mute all sound option.
*/
diff --git a/engines/engines.mk b/engines/engines.mk
index 32306b2573..5b0bb3bdef 100644
--- a/engines/engines.mk
+++ b/engines/engines.mk
@@ -87,6 +87,10 @@ MODULES += engines/kyra
ifdef ENABLE_LOL
DEFINES += -DENABLE_LOL
endif
+
+ifdef ENABLE_EOB
+DEFINES += -DENABLE_EOB
+endif
endif
ifdef ENABLE_LASTEXPRESS
@@ -99,11 +103,6 @@ DEFINES += -DENABLE_LURE=$(ENABLE_LURE)
MODULES += engines/lure
endif
-ifdef ENABLE_M4
-DEFINES += -DENABLE_M4=$(ENABLE_M4)
-MODULES += engines/m4
-endif
-
ifdef ENABLE_MADE
DEFINES += -DENABLE_MADE=$(ENABLE_MADE)
MODULES += engines/made
@@ -198,6 +197,11 @@ DEFINES += -DENABLE_TINSEL=$(ENABLE_TINSEL)
MODULES += engines/tinsel
endif
+ifdef ENABLE_TOLTECS
+DEFINES += -DENABLE_TOLTECS=$(ENABLE_TOLTECS)
+MODULES += engines/toltecs
+endif
+
ifdef ENABLE_TOON
DEFINES += -DENABLE_TOON=$(ENABLE_TOON)
MODULES += engines/toon
diff --git a/engines/game.cpp b/engines/game.cpp
index be15240745..4bfd8f3bf2 100644
--- a/engines/game.cpp
+++ b/engines/game.cpp
@@ -21,6 +21,7 @@
*/
#include "engines/game.h"
+#include "common/gui_options.h"
const PlainGameDescriptor *findPlainGameDescriptor(const char *gameid, const PlainGameDescriptor *list) {
diff --git a/engines/game.h b/engines/game.h
index 23512e89b8..3417203ea7 100644
--- a/engines/game.h
+++ b/engines/game.h
@@ -26,7 +26,8 @@
#include "common/array.h"
#include "common/hash-str.h"
#include "common/str.h"
-#include "common/util.h"
+#include "common/language.h"
+#include "common/platform.h"
/**
* A simple structure used to map gameids (like "monkey", "sword1", ...) to
@@ -65,12 +66,12 @@ enum GameSupportLevel {
class GameDescriptor : public Common::StringMap {
public:
GameDescriptor();
- GameDescriptor(const PlainGameDescriptor &pgd, Common::String guioptions = "");
+ GameDescriptor(const PlainGameDescriptor &pgd, Common::String guioptions = Common::String());
GameDescriptor(const Common::String &gameid,
const Common::String &description,
Common::Language language = Common::UNK_LANG,
Common::Platform platform = Common::kPlatformUnknown,
- Common::String guioptions = "",
+ Common::String guioptions = Common::String(),
GameSupportLevel gsl = kStableGame);
/**
diff --git a/engines/gob/aniobject.cpp b/engines/gob/aniobject.cpp
index a01fe43672..0ca850d1fb 100644
--- a/engines/gob/aniobject.cpp
+++ b/engines/gob/aniobject.cpp
@@ -111,6 +111,36 @@ void ANIObject::getFrameSize(int16 &width, int16 &height) const {
height = animation.frameAreas[_frame].bottom - animation.frameAreas[_frame].top + 1;
}
+bool ANIObject::isIn(int16 x, int16 y) const {
+ if (!isVisible())
+ return false;
+
+ int16 frameX, frameY, frameWidth, frameHeight;
+ getFramePosition(frameX, frameY);
+ getFrameSize(frameWidth, frameHeight);
+
+ if ((x < frameX) || (y < frameY))
+ return false;
+ if ((x > (frameX + frameWidth)) || (y > (frameY + frameHeight)))
+ return false;
+
+ return true;
+}
+
+bool ANIObject::isIn(const ANIObject &obj) const {
+ if (!isVisible() || !obj.isVisible())
+ return false;
+
+ int16 frameX, frameY, frameWidth, frameHeight;
+ getFramePosition(frameX, frameY);
+ getFrameSize(frameWidth, frameHeight);
+
+ return obj.isIn(frameX , frameY ) ||
+ obj.isIn(frameX + frameWidth - 1, frameY ) ||
+ obj.isIn(frameX , frameY + frameHeight - 1) ||
+ obj.isIn(frameX + frameWidth - 1, frameY + frameHeight - 1);
+}
+
void ANIObject::draw(Surface &dest, int16 &left, int16 &top,
int16 &right, int16 &bottom) {
diff --git a/engines/gob/aniobject.h b/engines/gob/aniobject.h
index 28103007a6..e3fe301400 100644
--- a/engines/gob/aniobject.h
+++ b/engines/gob/aniobject.h
@@ -69,6 +69,11 @@ public:
/** Return the current frame size. */
void getFrameSize(int16 &width, int16 &height) const;
+ /** Are there coordinates within the animation sprite? */
+ bool isIn(int16 x, int16 y) const;
+ /** Is this object within the animation sprite? */
+ bool isIn(const ANIObject &obj) const;
+
/** Set the animation number. */
void setAnimation(uint16 animation);
diff --git a/devtools/create_mads/parser.h b/engines/gob/cheater.cpp
index a7141c497a..5c1f555389 100644
--- a/devtools/create_mads/parser.h
+++ b/engines/gob/cheater.cpp
@@ -20,9 +20,15 @@
*
*/
-#ifndef CREATE_MADS_PARSER
-#define CREATE_MADS_PARSER
+#include "gob/gob.h"
+#include "gob/cheater.h"
-bool Compile(const char *srcFilename, const char *destFilename);
+namespace Gob {
-#endif
+Cheater::Cheater(GobEngine *vm) : _vm(vm) {
+}
+
+Cheater::~Cheater() {
+}
+
+} // End of namespace Gob
diff --git a/engines/gob/cheater.h b/engines/gob/cheater.h
new file mode 100644
index 0000000000..334a5e88eb
--- /dev/null
+++ b/engines/gob/cheater.h
@@ -0,0 +1,62 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef GOB_CHEATER_H
+#define GOB_CHEATER_H
+
+namespace GUI {
+ class Debugger;
+}
+
+namespace Gob {
+
+namespace Geisha {
+ class Diving;
+}
+
+class GobEngine;
+
+class Cheater {
+public:
+ Cheater(GobEngine *vm);
+ virtual ~Cheater();
+
+ virtual bool cheat(GUI::Debugger &console) = 0;
+
+protected:
+ GobEngine *_vm;
+};
+
+class Cheater_Geisha : public Cheater {
+public:
+ Cheater_Geisha(GobEngine *vm, Geisha::Diving *diving);
+ ~Cheater_Geisha();
+
+ bool cheat(GUI::Debugger &console);
+
+private:
+ Geisha::Diving *_diving;
+};
+
+} // End of namespace Gob
+
+#endif // GOB_CHEATER_H
diff --git a/engines/gob/cheater_geisha.cpp b/engines/gob/cheater_geisha.cpp
new file mode 100644
index 0000000000..3d8c56707d
--- /dev/null
+++ b/engines/gob/cheater_geisha.cpp
@@ -0,0 +1,66 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "gui/debugger.h"
+
+#include "gob/gob.h"
+#include "gob/cheater.h"
+#include "gob/inter.h"
+
+#include "gob/minigames/geisha/diving.h"
+
+namespace Gob {
+
+Cheater_Geisha::Cheater_Geisha(GobEngine *vm, Geisha::Diving *diving) :
+ Cheater(vm), _diving(diving) {
+
+}
+
+Cheater_Geisha::~Cheater_Geisha() {
+}
+
+bool Cheater_Geisha::cheat(GUI::Debugger &console) {
+ // A cheat to get around the Diving minigame
+ if (_diving->isPlaying()) {
+ _diving->cheatWin();
+ return false;
+ }
+
+ // A cheat to get around the mastermind puzzle
+ if (_vm->isCurrentTot("hard.tot") && _vm->_inter->_variables) {
+ uint32 digit1 = READ_VARO_UINT32(0x768);
+ uint32 digit2 = READ_VARO_UINT32(0x76C);
+ uint32 digit3 = READ_VARO_UINT32(0x770);
+ uint32 digit4 = READ_VARO_UINT32(0x774);
+ uint32 digit5 = READ_VARO_UINT32(0x778);
+
+ if (digit1 && digit2 && digit3 && digit4 && digit5)
+ console.DebugPrintf("Mastermind solution: %d %d %d %d %d\n",
+ digit1, digit2, digit3, digit4, digit5);
+
+ return true;
+ }
+
+ return true;
+}
+
+} // End of namespace Gob
diff --git a/engines/gob/console.cpp b/engines/gob/console.cpp
index e7296fb81b..76ccb70dca 100644
--- a/engines/gob/console.cpp
+++ b/engines/gob/console.cpp
@@ -24,22 +24,32 @@
#include "gob/gob.h"
#include "gob/inter.h"
#include "gob/dataio.h"
+#include "gob/cheater.h"
namespace Gob {
-GobConsole::GobConsole(GobEngine *vm) : GUI::Debugger(), _vm(vm) {
+GobConsole::GobConsole(GobEngine *vm) : GUI::Debugger(), _vm(vm), _cheater(0) {
DCmd_Register("varSize", WRAP_METHOD(GobConsole, cmd_varSize));
DCmd_Register("dumpVars", WRAP_METHOD(GobConsole, cmd_dumpVars));
DCmd_Register("var8", WRAP_METHOD(GobConsole, cmd_var8));
DCmd_Register("var16", WRAP_METHOD(GobConsole, cmd_var16));
DCmd_Register("var32", WRAP_METHOD(GobConsole, cmd_var32));
DCmd_Register("varString", WRAP_METHOD(GobConsole, cmd_varString));
+ DCmd_Register("cheat", WRAP_METHOD(GobConsole, cmd_cheat));
DCmd_Register("listArchives", WRAP_METHOD(GobConsole, cmd_listArchives));
}
GobConsole::~GobConsole() {
}
+void GobConsole::registerCheater(Cheater *cheater) {
+ _cheater = cheater;
+}
+
+void GobConsole::unregisterCheater() {
+ _cheater = 0;
+}
+
bool GobConsole::cmd_varSize(int argc, const char **argv) {
DebugPrintf("Size of the variable space: %d bytes\n", _vm->_inter->_variables->getSize());
return true;
@@ -155,6 +165,13 @@ bool GobConsole::cmd_varString(int argc, const char **argv) {
return true;
}
+bool GobConsole::cmd_cheat(int argc, const char **argv) {
+ if (_cheater)
+ return _cheater->cheat(*this);
+
+ return true;
+}
+
bool GobConsole::cmd_listArchives(int argc, const char **argv) {
Common::Array<ArchiveInfo> info;
diff --git a/engines/gob/console.h b/engines/gob/console.h
index b9c3f5ed70..5b6f0255dd 100644
--- a/engines/gob/console.h
+++ b/engines/gob/console.h
@@ -28,15 +28,21 @@
namespace Gob {
class GobEngine;
+class Cheater;
class GobConsole : public GUI::Debugger {
public:
GobConsole(GobEngine *vm);
virtual ~GobConsole(void);
+ void registerCheater(Cheater *cheater);
+ void unregisterCheater();
+
private:
GobEngine *_vm;
+ Cheater *_cheater;
+
bool cmd_varSize(int argc, const char **argv);
bool cmd_dumpVars(int argc, const char **argv);
bool cmd_var8(int argc, const char **argv);
@@ -44,6 +50,8 @@ private:
bool cmd_var32(int argc, const char **argv);
bool cmd_varString(int argc, const char **argv);
+ bool cmd_cheat(int argc, const char **argv);
+
bool cmd_listArchives(int argc, const char **argv);
};
diff --git a/engines/gob/databases.h b/engines/gob/databases.h
index fb65d8cf96..cde123e6a8 100644
--- a/engines/gob/databases.h
+++ b/engines/gob/databases.h
@@ -26,7 +26,7 @@
#include "common/str.h"
#include "common/hashmap.h"
#include "common/hash-str.h"
-#include "common/util.h"
+#include "common/language.h"
#include "gob/dbase.h"
diff --git a/engines/gob/dataio.cpp b/engines/gob/dataio.cpp
index 1633a1edb7..2071c0f1be 100644
--- a/engines/gob/dataio.cpp
+++ b/engines/gob/dataio.cpp
@@ -414,7 +414,7 @@ Common::SeekableReadStream *DataIO::getFile(File &file) {
return 0;
Common::SeekableReadStream *rawData =
- new Common::SafeSubReadStream(&file.archive->file, file.offset, file.offset + file.size);
+ new Common::SafeSeekableSubReadStream(&file.archive->file, file.offset, file.offset + file.size);
if (file.compression == 0)
return rawData;
diff --git a/engines/gob/detection_tables.h b/engines/gob/detection_tables.h
index 636044975a..5c6e919e12 100644
--- a/engines/gob/detection_tables.h
+++ b/engines/gob/detection_tables.h
@@ -3258,7 +3258,7 @@ static const GOBGameDescription gameDescriptions[] = {
EN_GRB,
kPlatformPC,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NOSPEECH)
+ GUIO2(GUIO_NOSPEECH, GUIO_NOASPECT)
},
kGameTypeWoodruff,
kFeatures640x480,
@@ -3272,7 +3272,7 @@ static const GOBGameDescription gameDescriptions[] = {
DE_DEU,
kPlatformPC,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NOSPEECH)
+ GUIO2(GUIO_NOSPEECH, GUIO_NOASPECT)
},
kGameTypeWoodruff,
kFeatures640x480,
@@ -3286,7 +3286,7 @@ static const GOBGameDescription gameDescriptions[] = {
FR_FRA,
kPlatformPC,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NOSPEECH)
+ GUIO2(GUIO_NOSPEECH, GUIO_NOASPECT)
},
kGameTypeWoodruff,
kFeatures640x480,
@@ -3300,7 +3300,7 @@ static const GOBGameDescription gameDescriptions[] = {
IT_ITA,
kPlatformPC,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NOSPEECH)
+ GUIO2(GUIO_NOSPEECH, GUIO_NOASPECT)
},
kGameTypeWoodruff,
kFeatures640x480,
@@ -3314,7 +3314,7 @@ static const GOBGameDescription gameDescriptions[] = {
ES_ESP,
kPlatformPC,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NOSPEECH)
+ GUIO2(GUIO_NOSPEECH, GUIO_NOASPECT)
},
kGameTypeWoodruff,
kFeatures640x480,
@@ -3328,7 +3328,7 @@ static const GOBGameDescription gameDescriptions[] = {
EN_GRB,
kPlatformPC,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NOSPEECH)
+ GUIO2(GUIO_NOSPEECH, GUIO_NOASPECT)
},
kGameTypeWoodruff,
kFeatures640x480,
@@ -3342,7 +3342,7 @@ static const GOBGameDescription gameDescriptions[] = {
DE_DEU,
kPlatformPC,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NOSPEECH)
+ GUIO2(GUIO_NOSPEECH, GUIO_NOASPECT)
},
kGameTypeWoodruff,
kFeatures640x480,
@@ -3356,7 +3356,7 @@ static const GOBGameDescription gameDescriptions[] = {
FR_FRA,
kPlatformPC,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NOSPEECH)
+ GUIO2(GUIO_NOSPEECH, GUIO_NOASPECT)
},
kGameTypeWoodruff,
kFeatures640x480,
@@ -3370,7 +3370,7 @@ static const GOBGameDescription gameDescriptions[] = {
IT_ITA,
kPlatformPC,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NOSPEECH)
+ GUIO2(GUIO_NOSPEECH, GUIO_NOASPECT)
},
kGameTypeWoodruff,
kFeatures640x480,
@@ -3384,7 +3384,7 @@ static const GOBGameDescription gameDescriptions[] = {
ES_ESP,
kPlatformPC,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NOSPEECH)
+ GUIO2(GUIO_NOSPEECH, GUIO_NOASPECT)
},
kGameTypeWoodruff,
kFeatures640x480,
@@ -3398,7 +3398,7 @@ static const GOBGameDescription gameDescriptions[] = {
DE_DEU,
kPlatformPC,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NOSPEECH)
+ GUIO2(GUIO_NOSPEECH, GUIO_NOASPECT)
},
kGameTypeWoodruff,
kFeatures640x480,
@@ -3412,7 +3412,7 @@ static const GOBGameDescription gameDescriptions[] = {
ES_ESP,
kPlatformPC,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NOSPEECH)
+ GUIO2(GUIO_NOSPEECH, GUIO_NOASPECT)
},
kGameTypeWoodruff,
kFeatures640x480,
@@ -3426,7 +3426,7 @@ static const GOBGameDescription gameDescriptions[] = {
EN_GRB,
kPlatformPC,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NOSPEECH)
+ GUIO2(GUIO_NOSPEECH, GUIO_NOASPECT)
},
kGameTypeWoodruff,
kFeatures640x480,
@@ -3440,7 +3440,7 @@ static const GOBGameDescription gameDescriptions[] = {
DE_DEU,
kPlatformPC,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NOSPEECH)
+ GUIO2(GUIO_NOSPEECH, GUIO_NOASPECT)
},
kGameTypeWoodruff,
kFeatures640x480,
@@ -3454,7 +3454,7 @@ static const GOBGameDescription gameDescriptions[] = {
FR_FRA,
kPlatformPC,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NOSPEECH)
+ GUIO2(GUIO_NOSPEECH, GUIO_NOASPECT)
},
kGameTypeWoodruff,
kFeatures640x480,
@@ -3468,7 +3468,7 @@ static const GOBGameDescription gameDescriptions[] = {
IT_ITA,
kPlatformPC,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NOSPEECH)
+ GUIO2(GUIO_NOSPEECH, GUIO_NOASPECT)
},
kGameTypeWoodruff,
kFeatures640x480,
@@ -3482,7 +3482,7 @@ static const GOBGameDescription gameDescriptions[] = {
IT_ITA,
kPlatformPC,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NOSPEECH)
+ GUIO2(GUIO_NOSPEECH, GUIO_NOASPECT)
},
kGameTypeWoodruff,
kFeatures640x480,
@@ -3496,7 +3496,7 @@ static const GOBGameDescription gameDescriptions[] = {
DE_DEU,
kPlatformPC,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NOSPEECH)
+ GUIO2(GUIO_NOSPEECH, GUIO_NOASPECT)
},
kGameTypeWoodruff,
kFeatures640x480,
@@ -3510,7 +3510,7 @@ static const GOBGameDescription gameDescriptions[] = {
FR_FRA,
kPlatformPC,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NOSPEECH)
+ GUIO2(GUIO_NOSPEECH, GUIO_NOASPECT)
},
kGameTypeWoodruff,
kFeatures640x480,
@@ -3524,7 +3524,7 @@ static const GOBGameDescription gameDescriptions[] = {
EN_GRB,
kPlatformPC,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NOSPEECH)
+ GUIO2(GUIO_NOSPEECH, GUIO_NOASPECT)
},
kGameTypeWoodruff,
kFeatures640x480,
@@ -3538,7 +3538,7 @@ static const GOBGameDescription gameDescriptions[] = {
DE_DEU,
kPlatformPC,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NOSPEECH)
+ GUIO2(GUIO_NOSPEECH, GUIO_NOASPECT)
},
kGameTypeWoodruff,
kFeatures640x480,
@@ -3552,7 +3552,7 @@ static const GOBGameDescription gameDescriptions[] = {
FR_FRA,
kPlatformPC,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NOSPEECH)
+ GUIO2(GUIO_NOSPEECH, GUIO_NOASPECT)
},
kGameTypeWoodruff,
kFeatures640x480,
@@ -3566,7 +3566,7 @@ static const GOBGameDescription gameDescriptions[] = {
IT_ITA,
kPlatformPC,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NOSPEECH)
+ GUIO2(GUIO_NOSPEECH, GUIO_NOASPECT)
},
kGameTypeWoodruff,
kFeatures640x480,
@@ -3580,7 +3580,7 @@ static const GOBGameDescription gameDescriptions[] = {
ES_ESP,
kPlatformPC,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NOSPEECH)
+ GUIO2(GUIO_NOSPEECH, GUIO_NOASPECT)
},
kGameTypeWoodruff,
kFeatures640x480,
@@ -3594,7 +3594,7 @@ static const GOBGameDescription gameDescriptions[] = {
PL_POL,
kPlatformPC,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NOSPEECH)
+ GUIO2(GUIO_NOSPEECH, GUIO_NOASPECT)
},
kGameTypeWoodruff,
kFeatures640x480,
@@ -3612,7 +3612,7 @@ static const GOBGameDescription gameDescriptions[] = {
EN_ANY,
kPlatformPC,
ADGF_NO_FLAGS,
- GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH)
+ GUIO3(GUIO_NOSUBTITLES, GUIO_NOSPEECH, GUIO_NOASPECT)
},
kGameTypeWoodruff,
kFeatures640x480 | kFeaturesSCNDemo,
@@ -3626,7 +3626,7 @@ static const GOBGameDescription gameDescriptions[] = {
EN_USA,
kPlatformPC,
ADGF_NO_FLAGS,
- GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH)
+ GUIO3(GUIO_NOSUBTITLES, GUIO_NOSPEECH, GUIO_NOASPECT)
},
kGameTypeDynasty,
kFeatures640x480,
@@ -3640,7 +3640,7 @@ static const GOBGameDescription gameDescriptions[] = {
EN_USA,
kPlatformPC,
ADGF_NO_FLAGS,
- GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH)
+ GUIO3(GUIO_NOSUBTITLES, GUIO_NOSPEECH, GUIO_NOASPECT)
},
kGameTypeDynasty,
kFeatures640x480,
@@ -3654,7 +3654,7 @@ static const GOBGameDescription gameDescriptions[] = {
FR_FRA,
kPlatformPC,
ADGF_NO_FLAGS,
- GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH)
+ GUIO3(GUIO_NOSUBTITLES, GUIO_NOSPEECH, GUIO_NOASPECT)
},
kGameTypeDynasty,
kFeatures640x480,
@@ -3668,7 +3668,7 @@ static const GOBGameDescription gameDescriptions[] = {
FR_FRA,
kPlatformPC,
ADGF_NO_FLAGS,
- GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH)
+ GUIO3(GUIO_NOSUBTITLES, GUIO_NOSPEECH, GUIO_NOASPECT)
},
kGameTypeDynasty,
kFeatures640x480,
@@ -3682,7 +3682,7 @@ static const GOBGameDescription gameDescriptions[] = {
DE_DEU,
kPlatformPC,
ADGF_NO_FLAGS,
- GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH)
+ GUIO3(GUIO_NOSUBTITLES, GUIO_NOSPEECH, GUIO_NOASPECT)
},
kGameTypeDynasty,
kFeatures640x480,
@@ -3696,7 +3696,7 @@ static const GOBGameDescription gameDescriptions[] = {
EN_USA,
kPlatformPC,
ADGF_DEMO,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
kGameTypeDynasty,
kFeatures640x480,
@@ -3710,7 +3710,7 @@ static const GOBGameDescription gameDescriptions[] = {
UNK_LANG,
kPlatformWindows,
ADGF_DEMO,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
kGameTypeDynasty,
kFeatures640x480,
@@ -3724,7 +3724,7 @@ static const GOBGameDescription gameDescriptions[] = {
DE_DEU,
kPlatformWindows,
ADGF_DEMO,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
kGameTypeDynasty,
kFeatures640x480,
@@ -3738,7 +3738,7 @@ static const GOBGameDescription gameDescriptions[] = {
EN_USA,
kPlatformPC,
ADGF_NO_FLAGS,
- GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH)
+ GUIO3(GUIO_NOSUBTITLES, GUIO_NOSPEECH, GUIO_NOASPECT)
},
kGameTypeUrban,
kFeatures640x480 | kFeaturesTrueColor,
@@ -3752,7 +3752,7 @@ static const GOBGameDescription gameDescriptions[] = {
EN_USA,
kPlatformPC,
ADGF_NO_FLAGS,
- GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH)
+ GUIO3(GUIO_NOSUBTITLES, GUIO_NOSPEECH, GUIO_NOASPECT)
},
kGameTypeUrban,
kFeatures640x480 | kFeaturesTrueColor,
@@ -3766,7 +3766,7 @@ static const GOBGameDescription gameDescriptions[] = {
FR_FRA,
kPlatformPC,
ADGF_NO_FLAGS,
- GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH)
+ GUIO3(GUIO_NOSUBTITLES, GUIO_NOSPEECH, GUIO_NOASPECT)
},
kGameTypeUrban,
kFeatures640x480 | kFeaturesTrueColor,
@@ -3780,7 +3780,7 @@ static const GOBGameDescription gameDescriptions[] = {
ES_ESP,
kPlatformPC,
ADGF_NO_FLAGS,
- GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH)
+ GUIO3(GUIO_NOSUBTITLES, GUIO_NOSPEECH, GUIO_NOASPECT)
},
kGameTypeUrban,
kFeatures640x480 | kFeaturesTrueColor,
@@ -3794,7 +3794,7 @@ static const GOBGameDescription gameDescriptions[] = {
IT_ITA,
kPlatformPC,
ADGF_NO_FLAGS,
- GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH)
+ GUIO3(GUIO_NOSUBTITLES, GUIO_NOSPEECH, GUIO_NOASPECT)
},
kGameTypeUrban,
kFeatures640x480 | kFeaturesTrueColor,
@@ -3808,7 +3808,7 @@ static const GOBGameDescription gameDescriptions[] = {
IT_ITA,
kPlatformPC,
ADGF_NO_FLAGS,
- GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH)
+ GUIO3(GUIO_NOSUBTITLES, GUIO_NOSPEECH, GUIO_NOASPECT)
},
kGameTypeUrban,
kFeatures640x480 | kFeaturesTrueColor,
@@ -3822,7 +3822,7 @@ static const GOBGameDescription gameDescriptions[] = {
DE_DEU,
kPlatformPC,
ADGF_NO_FLAGS,
- GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH)
+ GUIO3(GUIO_NOSUBTITLES, GUIO_NOSPEECH, GUIO_NOASPECT)
},
kGameTypeUrban,
kFeatures640x480 | kFeaturesTrueColor,
@@ -3841,7 +3841,7 @@ static const GOBGameDescription gameDescriptions[] = {
EN_ANY,
kPlatformPC,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
kGameTypeUrban,
kFeatures640x480 | kFeaturesTrueColor | kFeaturesSCNDemo,
@@ -3859,7 +3859,7 @@ static const GOBGameDescription gameDescriptions[] = {
FR_FRA,
kPlatformPC,
ADGF_NO_FLAGS,
- GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH)
+ GUIO3(GUIO_NOSUBTITLES, GUIO_NOSPEECH, GUIO_NOASPECT)
},
kGameTypePlaytoons,
kFeatures640x480,
@@ -3877,7 +3877,7 @@ static const GOBGameDescription gameDescriptions[] = {
FR_FRA,
kPlatformPC,
ADGF_NO_FLAGS,
- GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH)
+ GUIO3(GUIO_NOSUBTITLES, GUIO_NOSPEECH, GUIO_NOASPECT)
},
kGameTypePlaytoons,
kFeatures640x480,
@@ -3895,7 +3895,7 @@ static const GOBGameDescription gameDescriptions[] = {
DE_DEU,
kPlatformPC,
ADGF_NO_FLAGS,
- GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH)
+ GUIO3(GUIO_NOSUBTITLES, GUIO_NOSPEECH, GUIO_NOASPECT)
},
kGameTypePlaytoons,
kFeatures640x480,
@@ -3913,7 +3913,7 @@ static const GOBGameDescription gameDescriptions[] = {
EN_ANY,
kPlatformPC,
ADGF_NO_FLAGS,
- GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH)
+ GUIO3(GUIO_NOSUBTITLES, GUIO_NOSPEECH, GUIO_NOASPECT)
},
kGameTypePlaytoons,
kFeatures640x480,
@@ -3936,7 +3936,7 @@ static const GOBGameDescription gameDescriptions[] = {
EN_ANY,
kPlatformPC,
ADGF_NO_FLAGS,
- GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH)
+ GUIO3(GUIO_NOSUBTITLES, GUIO_NOSPEECH, GUIO_NOASPECT)
},
kGameTypePlaytoons,
kFeatures640x480 | kFeaturesSCNDemo,
@@ -3954,7 +3954,7 @@ static const GOBGameDescription gameDescriptions[] = {
EN_ANY,
kPlatformPC,
ADGF_NO_FLAGS,
- GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH)
+ GUIO3(GUIO_NOSUBTITLES, GUIO_NOSPEECH, GUIO_NOASPECT)
},
kGameTypePlaytoons,
kFeatures640x480 | kFeaturesSCNDemo,
@@ -3976,7 +3976,7 @@ static const GOBGameDescription gameDescriptions[] = {
IT_ITA,
kPlatformPC,
ADGF_NO_FLAGS,
- GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH)
+ GUIO3(GUIO_NOSUBTITLES, GUIO_NOSPEECH, GUIO_NOASPECT)
},
kGameTypePlaytoons,
kFeatures640x480 | kFeaturesSCNDemo,
@@ -3997,7 +3997,7 @@ static const GOBGameDescription gameDescriptions[] = {
ES_ESP,
kPlatformPC,
ADGF_NO_FLAGS,
- GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH)
+ GUIO3(GUIO_NOSUBTITLES, GUIO_NOSPEECH, GUIO_NOASPECT)
},
kGameTypePlaytoons,
kFeatures640x480 | kFeaturesSCNDemo,
@@ -4015,7 +4015,7 @@ static const GOBGameDescription gameDescriptions[] = {
EN_ANY,
kPlatformPC,
ADGF_NO_FLAGS,
- GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH)
+ GUIO3(GUIO_NOSUBTITLES, GUIO_NOSPEECH, GUIO_NOASPECT)
},
kGameTypePlaytoons,
kFeatures640x480,
@@ -4033,7 +4033,7 @@ static const GOBGameDescription gameDescriptions[] = {
FR_FRA,
kPlatformPC,
ADGF_NO_FLAGS,
- GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH)
+ GUIO3(GUIO_NOSUBTITLES, GUIO_NOSPEECH, GUIO_NOASPECT)
},
kGameTypePlaytoons,
kFeatures640x480,
@@ -4051,7 +4051,25 @@ static const GOBGameDescription gameDescriptions[] = {
DE_DEU,
kPlatformPC,
ADGF_NO_FLAGS,
- GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH)
+ GUIO3(GUIO_NOSUBTITLES, GUIO_NOSPEECH, GUIO_NOASPECT)
+ },
+ kGameTypePlaytoons,
+ kFeatures640x480,
+ "intro2.stk", 0, 0
+ },
+ { // Supplied by Hkz
+ {
+ "playtoons2",
+ "",
+ {
+ {"playtoon.stk", 0, "2572685400852d12759a2fbf09ec88eb", 9698780},
+ {"spirou.stk", 0, "d3cfeff920b6343a2ece55088f530dba", 7076608},
+ {0, 0, 0, 0}
+ },
+ IT_ITA,
+ kPlatformPC,
+ ADGF_NO_FLAGS,
+ GUIO3(GUIO_NOSUBTITLES, GUIO_NOSPEECH, GUIO_NOASPECT)
},
kGameTypePlaytoons,
kFeatures640x480,
@@ -4069,7 +4087,7 @@ static const GOBGameDescription gameDescriptions[] = {
EN_ANY,
kPlatformPC,
ADGF_NO_FLAGS,
- GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH)
+ GUIO3(GUIO_NOSUBTITLES, GUIO_NOSPEECH, GUIO_NOASPECT)
},
kGameTypePlaytoons,
kFeatures640x480,
@@ -4087,7 +4105,7 @@ static const GOBGameDescription gameDescriptions[] = {
FR_FRA,
kPlatformPC,
ADGF_NO_FLAGS,
- GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH)
+ GUIO3(GUIO_NOSUBTITLES, GUIO_NOSPEECH, GUIO_NOASPECT)
},
kGameTypePlaytoons,
kFeatures640x480,
@@ -4105,7 +4123,7 @@ static const GOBGameDescription gameDescriptions[] = {
EN_ANY,
kPlatformPC,
ADGF_NO_FLAGS,
- GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH)
+ GUIO3(GUIO_NOSUBTITLES, GUIO_NOSPEECH, GUIO_NOASPECT)
},
kGameTypePlaytoons,
kFeatures640x480,
@@ -4123,7 +4141,7 @@ static const GOBGameDescription gameDescriptions[] = {
FR_FRA,
kPlatformPC,
ADGF_NO_FLAGS,
- GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH)
+ GUIO3(GUIO_NOSUBTITLES, GUIO_NOSPEECH, GUIO_NOASPECT)
},
kGameTypePlaytoons,
kFeatures640x480,
@@ -4141,7 +4159,7 @@ static const GOBGameDescription gameDescriptions[] = {
DE_DEU,
kPlatformPC,
ADGF_NO_FLAGS,
- GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH)
+ GUIO3(GUIO_NOSUBTITLES, GUIO_NOSPEECH, GUIO_NOASPECT)
},
kGameTypePlaytoons,
kFeatures640x480,
@@ -4159,7 +4177,7 @@ static const GOBGameDescription gameDescriptions[] = {
EN_ANY,
kPlatformPC,
ADGF_NO_FLAGS,
- GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH)
+ GUIO3(GUIO_NOSUBTITLES, GUIO_NOSPEECH, GUIO_NOASPECT)
},
kGameTypePlaytoons,
kFeatures640x480,
@@ -4177,7 +4195,7 @@ static const GOBGameDescription gameDescriptions[] = {
FR_FRA,
kPlatformPC,
ADGF_NO_FLAGS,
- GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH)
+ GUIO3(GUIO_NOSUBTITLES, GUIO_NOSPEECH, GUIO_NOASPECT)
},
kGameTypePlaytoons,
kFeatures640x480,
@@ -4195,7 +4213,7 @@ static const GOBGameDescription gameDescriptions[] = {
EN_ANY,
kPlatformPC,
ADGF_NO_FLAGS,
- GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH)
+ GUIO3(GUIO_NOSUBTITLES, GUIO_NOSPEECH, GUIO_NOASPECT)
},
kGameTypePlaytoons,
kFeatures640x480,
@@ -4213,7 +4231,7 @@ static const GOBGameDescription gameDescriptions[] = {
FR_FRA,
kPlatformPC,
ADGF_NO_FLAGS,
- GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH)
+ GUIO3(GUIO_NOSUBTITLES, GUIO_NOSPEECH, GUIO_NOASPECT)
},
kGameTypePlaytoons,
kFeatures640x480,
@@ -4231,7 +4249,7 @@ static const GOBGameDescription gameDescriptions[] = {
FR_FRA,
kPlatformPC,
ADGF_NO_FLAGS,
- GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH)
+ GUIO3(GUIO_NOSUBTITLES, GUIO_NOSPEECH, GUIO_NOASPECT)
},
kGameTypeBambou,
kFeatures640x480,
@@ -4249,7 +4267,7 @@ static const GOBGameDescription gameDescriptions[] = {
FR_FRA,
kPlatformPC,
ADGF_NO_FLAGS,
- GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH)
+ GUIO3(GUIO_NOSUBTITLES, GUIO_NOSPEECH, GUIO_NOASPECT)
},
kGameTypePlaytoons,
kFeatures640x480,
@@ -4267,7 +4285,7 @@ static const GOBGameDescription gameDescriptions[] = {
FR_FRA,
kPlatformPC,
ADGF_NO_FLAGS,
- GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH)
+ GUIO3(GUIO_NOSUBTITLES, GUIO_NOSPEECH, GUIO_NOASPECT)
},
kGameTypePlaytoons,
kFeatures640x480,
@@ -4285,7 +4303,7 @@ static const GOBGameDescription gameDescriptions[] = {
FR_FRA,
kPlatformPC,
ADGF_NO_FLAGS,
- GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH)
+ GUIO3(GUIO_NOSUBTITLES, GUIO_NOSPEECH, GUIO_NOASPECT)
},
kGameTypePlaytoons,
kFeatures640x480,
@@ -4299,7 +4317,7 @@ static const GOBGameDescription gameDescriptions[] = {
FR_FRA,
kPlatformPC,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO0()
},
kGameTypeAdi2,
kFeaturesNone,
@@ -4313,7 +4331,7 @@ static const GOBGameDescription gameDescriptions[] = {
FR_FRA,
kPlatformPC,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
kGameTypeAdi2,
kFeatures640x480,
@@ -4327,7 +4345,7 @@ static const GOBGameDescription gameDescriptions[] = {
FR_FRA,
kPlatformPC,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
kGameTypeAdi2,
kFeatures640x480,
@@ -4341,7 +4359,7 @@ static const GOBGameDescription gameDescriptions[] = {
EN_ANY,
kPlatformAmiga,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO0()
},
kGameTypeAdi2,
kFeaturesNone,
@@ -4355,7 +4373,7 @@ static const GOBGameDescription gameDescriptions[] = {
ES_ESP,
kPlatformPC,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
kGameTypeAdi2,
kFeatures640x480,
@@ -4369,7 +4387,7 @@ static const GOBGameDescription gameDescriptions[] = {
FR_FRA,
kPlatformPC,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
kGameTypeAdi2,
kFeatures640x480,
@@ -4383,7 +4401,7 @@ static const GOBGameDescription gameDescriptions[] = {
FR_FRA,
kPlatformPC,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
kGameTypeAdi2,
kFeatures640x480,
@@ -4397,7 +4415,7 @@ static const GOBGameDescription gameDescriptions[] = {
FR_FRA,
kPlatformPC,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
kGameTypeAdi2,
kFeatures640x480,
@@ -4411,7 +4429,7 @@ static const GOBGameDescription gameDescriptions[] = {
DE_DEU,
kPlatformPC,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
kGameTypeAdi2,
kFeatures640x480,
@@ -4425,7 +4443,7 @@ static const GOBGameDescription gameDescriptions[] = {
FR_FRA,
kPlatformPC,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
kGameTypeAdi2,
kFeatures640x480,
@@ -4445,7 +4463,7 @@ static const GOBGameDescription gameDescriptions[] = {
EN_ANY,
kPlatformPC,
ADGF_NO_FLAGS,
- GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH)
+ GUIO3(GUIO_NOSUBTITLES, GUIO_NOSPEECH, GUIO_NOASPECT)
},
kGameTypeAdi2,
kFeatures640x480 | kFeaturesSCNDemo,
@@ -4459,7 +4477,7 @@ static const GOBGameDescription gameDescriptions[] = {
DE_DEU,
kPlatformPC,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
kGameTypeAdi4,
kFeatures640x480,
@@ -4473,7 +4491,7 @@ static const GOBGameDescription gameDescriptions[] = {
DE_DEU,
kPlatformPC,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
kGameTypeAdi4,
kFeatures640x480,
@@ -4487,7 +4505,7 @@ static const GOBGameDescription gameDescriptions[] = {
FR_FRA,
kPlatformPC,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
kGameTypeAdi4,
kFeatures640x480,
@@ -4501,7 +4519,7 @@ static const GOBGameDescription gameDescriptions[] = {
FR_FRA,
kPlatformPC,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
kGameTypeAdi4,
kFeatures640x480,
@@ -4515,7 +4533,7 @@ static const GOBGameDescription gameDescriptions[] = {
FR_FRA,
kPlatformPC,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
kGameTypeAdi4,
kFeatures640x480,
@@ -4529,7 +4547,7 @@ static const GOBGameDescription gameDescriptions[] = {
FR_FRA,
kPlatformPC,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
kGameTypeAdi4,
kFeatures640x480,
@@ -4543,7 +4561,7 @@ static const GOBGameDescription gameDescriptions[] = {
EN_GRB,
kPlatformPC,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
kGameTypeAdi4,
kFeaturesNone,
@@ -4557,7 +4575,7 @@ static const GOBGameDescription gameDescriptions[] = {
FR_FRA,
kPlatformPC,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
kGameTypeAdi4,
kFeaturesNone,
@@ -4571,7 +4589,7 @@ static const GOBGameDescription gameDescriptions[] = {
FR_FRA,
kPlatformPC,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
kGameTypeAdi4,
kFeaturesNone,
@@ -4585,7 +4603,7 @@ static const GOBGameDescription gameDescriptions[] = {
DE_DEU,
kPlatformPC,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
kGameTypeAdi4,
kFeatures640x480,
@@ -4599,10 +4617,10 @@ static const GOBGameDescription gameDescriptions[] = {
FR_FRA,
kPlatformPC,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
kGameTypeAdi4,
- kFeaturesNone,
+ kFeatures640x480,
0, 0, 0
},
{
@@ -4613,7 +4631,7 @@ static const GOBGameDescription gameDescriptions[] = {
FR_FRA,
kPlatformPC,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
kGameTypeAdi4,
kFeatures640x480,
@@ -4627,7 +4645,7 @@ static const GOBGameDescription gameDescriptions[] = {
FR_FRA,
kPlatformPC,
ADGF_DEMO,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
kGameTypeAdi4,
kFeatures640x480,
@@ -4669,7 +4687,7 @@ static const GOBGameDescription gameDescriptions[] = {
FR_FRA,
kPlatformPC,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO0()
},
kGameTypeAdibou2,
kFeaturesNone,
@@ -4683,7 +4701,7 @@ static const GOBGameDescription gameDescriptions[] = {
FR_FRA,
kPlatformPC,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO0()
},
kGameTypeAdibou2,
kFeaturesNone,
@@ -4697,7 +4715,7 @@ static const GOBGameDescription gameDescriptions[] = {
DE_DEU,
kPlatformPC,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO0()
},
kGameTypeAdibou2,
kFeaturesNone,
@@ -4711,7 +4729,7 @@ static const GOBGameDescription gameDescriptions[] = {
IT_ITA,
kPlatformPC,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO0()
},
kGameTypeAdibou2,
kFeaturesNone,
@@ -4725,7 +4743,7 @@ static const GOBGameDescription gameDescriptions[] = {
FR_FRA,
kPlatformPC,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO0()
},
kGameTypeAdibou2,
kFeaturesNone,
@@ -4739,7 +4757,7 @@ static const GOBGameDescription gameDescriptions[] = {
FR_FRA,
kPlatformPC,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO0()
},
kGameTypeAdibou2,
kFeaturesNone,
@@ -4753,7 +4771,7 @@ static const GOBGameDescription gameDescriptions[] = {
FR_FRA,
kPlatformPC,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO0()
},
kGameTypeAdibou2,
kFeaturesNone,
@@ -4767,7 +4785,7 @@ static const GOBGameDescription gameDescriptions[] = {
FR_FRA,
kPlatformPC,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO0()
},
kGameTypeAdibou2,
kFeaturesNone,
@@ -4781,7 +4799,7 @@ static const GOBGameDescription gameDescriptions[] = {
FR_FRA,
kPlatformPC,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO0()
},
kGameTypeAdibou2,
kFeaturesNone,
@@ -4795,7 +4813,7 @@ static const GOBGameDescription gameDescriptions[] = {
FR_FRA,
kPlatformPC,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO0()
},
kGameTypeAdibou2,
kFeaturesNone,
@@ -4813,7 +4831,7 @@ static const GOBGameDescription gameDescriptions[] = {
EN_GRB,
kPlatformPC,
ADGF_DEMO,
- GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH)
+ GUIO3(GUIO_NOSUBTITLES, GUIO_NOSPEECH, GUIO_NOASPECT)
},
kGameTypeAdibou2,
kFeatures640x480 | kFeaturesSCNDemo,
@@ -4831,7 +4849,7 @@ static const GOBGameDescription gameDescriptions[] = {
DE_DEU,
kPlatformPC,
ADGF_DEMO,
- GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH)
+ GUIO3(GUIO_NOSUBTITLES, GUIO_NOSPEECH, GUIO_NOASPECT)
},
kGameTypeAdibou2,
kFeatures640x480 | kFeaturesSCNDemo,
@@ -4849,7 +4867,7 @@ static const GOBGameDescription gameDescriptions[] = {
FR_FRA,
kPlatformPC,
ADGF_DEMO,
- GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH)
+ GUIO3(GUIO_NOSUBTITLES, GUIO_NOSPEECH, GUIO_NOASPECT)
},
kGameTypeAdibou2,
kFeatures640x480 | kFeaturesSCNDemo,
@@ -4979,7 +4997,7 @@ static const GOBGameDescription fallbackDescs[] = {
UNK_LANG,
kPlatformPC,
ADGF_NO_FLAGS,
- GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH)
+ GUIO3(GUIO_NOSUBTITLES, GUIO_NOSPEECH, GUIO_NOASPECT)
},
kGameTypeWoodruff,
kFeatures640x480,
@@ -5035,7 +5053,7 @@ static const GOBGameDescription fallbackDescs[] = {
UNK_LANG,
kPlatformPC,
ADGF_NO_FLAGS,
- GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH)
+ GUIO3(GUIO_NOSUBTITLES, GUIO_NOSPEECH, GUIO_NOASPECT)
},
kGameTypeUrban,
kFeatures640x480 | kFeaturesTrueColor,
@@ -5049,7 +5067,7 @@ static const GOBGameDescription fallbackDescs[] = {
UNK_LANG,
kPlatformPC,
ADGF_NO_FLAGS,
- GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH)
+ GUIO3(GUIO_NOSUBTITLES, GUIO_NOSPEECH, GUIO_NOASPECT)
},
kGameTypePlaytoons,
kFeatures640x480,
@@ -5063,7 +5081,7 @@ static const GOBGameDescription fallbackDescs[] = {
UNK_LANG,
kPlatformPC,
ADGF_NO_FLAGS,
- GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH)
+ GUIO3(GUIO_NOSUBTITLES, GUIO_NOSPEECH, GUIO_NOASPECT)
},
kGameTypePlaytoons,
kFeatures640x480,
@@ -5077,7 +5095,7 @@ static const GOBGameDescription fallbackDescs[] = {
UNK_LANG,
kPlatformPC,
ADGF_NO_FLAGS,
- GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH)
+ GUIO3(GUIO_NOSUBTITLES, GUIO_NOSPEECH, GUIO_NOASPECT)
},
kGameTypePlaytoons,
kFeatures640x480,
@@ -5091,7 +5109,7 @@ static const GOBGameDescription fallbackDescs[] = {
UNK_LANG,
kPlatformPC,
ADGF_NO_FLAGS,
- GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH)
+ GUIO3(GUIO_NOSUBTITLES, GUIO_NOSPEECH, GUIO_NOASPECT)
},
kGameTypePlaytoons,
kFeatures640x480,
@@ -5105,7 +5123,7 @@ static const GOBGameDescription fallbackDescs[] = {
UNK_LANG,
kPlatformPC,
ADGF_NO_FLAGS,
- GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH)
+ GUIO3(GUIO_NOSUBTITLES, GUIO_NOSPEECH, GUIO_NOASPECT)
},
kGameTypePlaytoons,
kFeatures640x480,
@@ -5119,7 +5137,7 @@ static const GOBGameDescription fallbackDescs[] = {
UNK_LANG,
kPlatformPC,
ADGF_NO_FLAGS,
- GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH)
+ GUIO3(GUIO_NOSUBTITLES, GUIO_NOSPEECH, GUIO_NOASPECT)
},
kGameTypePlaytoons,
kFeatures640x480,
@@ -5133,7 +5151,7 @@ static const GOBGameDescription fallbackDescs[] = {
UNK_LANG,
kPlatformPC,
ADGF_NO_FLAGS,
- GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH)
+ GUIO3(GUIO_NOSUBTITLES, GUIO_NOSPEECH, GUIO_NOASPECT)
},
kGameTypeBambou,
kFeatures640x480,
@@ -5175,7 +5193,7 @@ static const GOBGameDescription fallbackDescs[] = {
UNK_LANG,
kPlatformPC,
ADGF_NO_FLAGS,
- GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH)
+ GUIO3(GUIO_NOSUBTITLES, GUIO_NOSPEECH, GUIO_NOASPECT)
},
kGameTypeAdi2,
kFeatures640x480,
@@ -5189,7 +5207,7 @@ static const GOBGameDescription fallbackDescs[] = {
UNK_LANG,
kPlatformPC,
ADGF_NO_FLAGS,
- GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH)
+ GUIO3(GUIO_NOSUBTITLES, GUIO_NOSPEECH, GUIO_NOASPECT)
},
kGameTypeAdi4,
kFeatures640x480,
@@ -5203,7 +5221,7 @@ static const GOBGameDescription fallbackDescs[] = {
UNK_LANG,
kPlatformPC,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
kGameTypeUrban,
kFeaturesAdLib | kFeatures640x480 | kFeaturesSCNDemo,
diff --git a/engines/gob/draw_v1.cpp b/engines/gob/draw_v1.cpp
index 8cb88b522c..fb15fdbc19 100644
--- a/engines/gob/draw_v1.cpp
+++ b/engines/gob/draw_v1.cpp
@@ -251,7 +251,7 @@ void Draw_v1::printTotText(int16 id) {
cmd = ptrEnd[17] & 0x7F;
if (cmd == 0) {
val = READ_LE_UINT16(ptrEnd + 18) * 4;
- sprintf(buf, "%d", VAR_OFFSET(val));
+ sprintf(buf, "%d", (int32)VAR_OFFSET(val));
} else if (cmd == 1) {
val = READ_LE_UINT16(ptrEnd + 18) * 4;
@@ -259,7 +259,7 @@ void Draw_v1::printTotText(int16 id) {
} else {
val = READ_LE_UINT16(ptrEnd + 18) * 4;
- sprintf(buf, "%d", VAR_OFFSET(val));
+ sprintf(buf, "%d", (int32)VAR_OFFSET(val));
if (buf[0] == '-') {
while (strlen(buf) - 1 < (uint32)ptrEnd[17]) {
_vm->_util->insertStr("0", buf, 1);
diff --git a/engines/gob/draw_v2.cpp b/engines/gob/draw_v2.cpp
index 6e64d6fd06..78702f2ec9 100644
--- a/engines/gob/draw_v2.cpp
+++ b/engines/gob/draw_v2.cpp
@@ -553,13 +553,13 @@ void Draw_v2::printTotText(int16 id) {
cmd = ptrEnd[17] & 0x7F;
if (cmd == 0) {
val = READ_LE_UINT16(ptrEnd + 18) * 4;
- sprintf(buf, "%d", VAR_OFFSET(val));
+ sprintf(buf, "%d", (int32)VAR_OFFSET(val));
} else if (cmd == 1) {
val = READ_LE_UINT16(ptrEnd + 18) * 4;
Common::strlcpy(buf, GET_VARO_STR(val), 20);
} else {
val = READ_LE_UINT16(ptrEnd + 18) * 4;
- sprintf(buf, "%d", VAR_OFFSET(val));
+ sprintf(buf, "%d", (int32)VAR_OFFSET(val));
if (buf[0] == '-') {
while (strlen(buf) - 1 < (uint32)ptrEnd[17]) {
_vm->_util->insertStr("0", buf, 1);
diff --git a/engines/gob/gob.cpp b/engines/gob/gob.cpp
index 51a117b7ec..4e7aa467b5 100644
--- a/engines/gob/gob.cpp
+++ b/engines/gob/gob.cpp
@@ -147,9 +147,9 @@ GobEngine::GobEngine(OSystem *syst) : Engine(syst), _rnd("gob") {
}
GobEngine::~GobEngine() {
- delete _console;
-
deinitGameParts();
+
+ delete _console;
}
const char *GobEngine::getLangDesc(int16 language) const {
diff --git a/engines/gob/gob.h b/engines/gob/gob.h
index 74c882e021..ea2323807a 100644
--- a/engines/gob/gob.h
+++ b/engines/gob/gob.h
@@ -160,7 +160,6 @@ private:
GameType _gameType;
int32 _features;
Common::Platform _platform;
- GobConsole *_console;
uint32 _pauseStart;
@@ -194,6 +193,8 @@ public:
bool _copyProtection;
bool _noMusic;
+ GobConsole *_console;
+
Global *_global;
Util *_util;
DataIO *_dataIO;
diff --git a/engines/gob/hotspots.cpp b/engines/gob/hotspots.cpp
index 5e0af847de..9a89f11923 100644
--- a/engines/gob/hotspots.cpp
+++ b/engines/gob/hotspots.cpp
@@ -477,7 +477,7 @@ void Hotspots::call(uint16 offset) {
_shouldPush = true;
- int16 stackSize = _stack.size();
+ Common::Stack<StackEntry>::size_type stackSize = _stack.size();
_vm->_inter->funcBlock(0);
diff --git a/engines/gob/iniconfig.cpp b/engines/gob/iniconfig.cpp
index 9b8f1c703e..bba531723c 100644
--- a/engines/gob/iniconfig.cpp
+++ b/engines/gob/iniconfig.cpp
@@ -90,7 +90,7 @@ bool INIConfig::openConfig(const Common::String &file, Config &config) {
bool INIConfig::createConfig(const Common::String &file, Config &config) {
config.config = new Common::ConfigFile();
- config.created = true;;
+ config.created = true;
_configs.setVal(file, config);
diff --git a/engines/gob/inter.h b/engines/gob/inter.h
index 6fd4dc2187..c79b6e2260 100644
--- a/engines/gob/inter.h
+++ b/engines/gob/inter.h
@@ -33,6 +33,8 @@
namespace Gob {
+class Cheater_Geisha;
+
namespace Geisha {
class Diving;
class Penetration;
@@ -371,6 +373,8 @@ protected:
private:
Geisha::Diving *_diving;
Geisha::Penetration *_penetration;
+
+ Cheater_Geisha *_cheater;
};
class Inter_v2 : public Inter_v1 {
diff --git a/engines/gob/inter_geisha.cpp b/engines/gob/inter_geisha.cpp
index c5b91a484b..7f21ceb91d 100644
--- a/engines/gob/inter_geisha.cpp
+++ b/engines/gob/inter_geisha.cpp
@@ -34,6 +34,7 @@
#include "gob/game.h"
#include "gob/draw.h"
#include "gob/video.h"
+#include "gob/cheater.h"
#include "gob/save/saveload.h"
#include "gob/sound/sound.h"
#include "gob/sound/sounddesc.h"
@@ -53,9 +54,17 @@ Inter_Geisha::Inter_Geisha(GobEngine *vm) : Inter_v1(vm),
_diving = new Geisha::Diving(vm);
_penetration = new Geisha::Penetration(vm);
+
+ _cheater = new Cheater_Geisha(vm, _diving);
+
+ _vm->_console->registerCheater(_cheater);
}
Inter_Geisha::~Inter_Geisha() {
+ _vm->_console->unregisterCheater();
+
+ delete _cheater;
+
delete _penetration;
delete _diving;
}
@@ -280,7 +289,7 @@ void Inter_Geisha::oGeisha_gameDiving(OpGobParams &params) {
bool result = _diving->play(playerCount, hasPearlLocation);
- WRITE_VAR_UINT32(resultVar, result ? 1 : 0);
+ WRITE_VAR_UINT32(resultVar, result ? 0 : 1);
}
void Inter_Geisha::oGeisha_loadTitleMusic(OpGobParams &params) {
diff --git a/engines/gob/inter_playtoons.cpp b/engines/gob/inter_playtoons.cpp
index e05cae354c..f76ba8e97b 100644
--- a/engines/gob/inter_playtoons.cpp
+++ b/engines/gob/inter_playtoons.cpp
@@ -148,7 +148,7 @@ void Inter_Playtoons::oPlaytoons_printText(OpFuncParams &params) {
case TYPE_VAR_INT32:
case TYPE_ARRAY_INT32:
sprintf(buf + i, "%d",
- VAR_OFFSET(_vm->_game->_script->readVarIndex()));
+ (int32)VAR_OFFSET(_vm->_game->_script->readVarIndex()));
break;
case TYPE_VAR_STR:
diff --git a/engines/gob/inter_v1.cpp b/engines/gob/inter_v1.cpp
index 0eb8be1a03..9aa190a456 100644
--- a/engines/gob/inter_v1.cpp
+++ b/engines/gob/inter_v1.cpp
@@ -658,20 +658,6 @@ void Inter_v1::o1_callSub(OpFuncParams &params) {
return;
}
- // A cheat to get around the stupid mastermind puzzle in Geisha,
- // while we're still testing it
- if ((_vm->getGameType() == kGameTypeGeisha) && (offset == 12934) &&
- _vm->isCurrentTot("hard.tot") && _vm->_inter->_variables) {
-
- uint32 digit1 = READ_VARO_UINT32(0x768);
- uint32 digit2 = READ_VARO_UINT32(0x76C);
- uint32 digit3 = READ_VARO_UINT32(0x770);
- uint32 digit4 = READ_VARO_UINT32(0x774);
- uint32 digit5 = READ_VARO_UINT32(0x778);
-
- warning("Mastermind solution: %d %d %d %d %d", digit1, digit2, digit3, digit4, digit5);
- }
-
// Skipping the copy protection screen in Gobliiins
if (!_vm->_copyProtection && (_vm->getGameType() == kGameTypeGob1) && (offset == 3905) &&
_vm->isCurrentTot(_vm->_startTot)) {
@@ -945,7 +931,7 @@ void Inter_v1::o1_printText(OpFuncParams &params) {
case TYPE_VAR_INT32:
case TYPE_ARRAY_INT32:
sprintf(buf + i, "%d",
- VAR_OFFSET(_vm->_game->_script->readVarIndex()));
+ (int32)VAR_OFFSET(_vm->_game->_script->readVarIndex()));
break;
case TYPE_VAR_STR:
diff --git a/engines/gob/inter_v2.cpp b/engines/gob/inter_v2.cpp
index 2fea18343d..1e5b7bb24c 100644
--- a/engines/gob/inter_v2.cpp
+++ b/engines/gob/inter_v2.cpp
@@ -1104,7 +1104,7 @@ void Inter_v2::o2_printText(OpFuncParams &params) {
case TYPE_VAR_INT32:
case TYPE_ARRAY_INT32:
sprintf(buf + i, "%d",
- VAR_OFFSET(_vm->_game->_script->readVarIndex()));
+ (int32)VAR_OFFSET(_vm->_game->_script->readVarIndex()));
break;
case TYPE_VAR_STR:
diff --git a/engines/gob/inter_v7.cpp b/engines/gob/inter_v7.cpp
index a36154fe5e..81547f7362 100644
--- a/engines/gob/inter_v7.cpp
+++ b/engines/gob/inter_v7.cpp
@@ -135,7 +135,7 @@ void Inter_v7::o7_intToString() {
uint16 valueIndex = _vm->_game->_script->readVarIndex();
uint16 destIndex = _vm->_game->_script->readVarIndex();
- sprintf(GET_VARO_STR(destIndex), "%d", READ_VARO_UINT32(valueIndex));
+ sprintf(GET_VARO_STR(destIndex), "%d", (int32)READ_VARO_UINT32(valueIndex));
}
void Inter_v7::o7_callFunction() {
diff --git a/engines/gob/map.cpp b/engines/gob/map.cpp
index 57f5f7af48..e58cd3c9a3 100644
--- a/engines/gob/map.cpp
+++ b/engines/gob/map.cpp
@@ -373,7 +373,7 @@ void Map::findNearestWalkable(int16 &gobDestX, int16 &gobDestY,
int i;
mapWidth = _screenWidth / _tilesWidth;
- mapHeight = _vm->_width / _tilesHeight;
+ mapHeight = _vm->_height / _tilesHeight;
direction = 0;
for (i = 1; i <= gobDestX; i++)
diff --git a/engines/gob/minigames/geisha/diving.cpp b/engines/gob/minigames/geisha/diving.cpp
index e3bc69a503..6f4c6e168a 100644
--- a/engines/gob/minigames/geisha/diving.cpp
+++ b/engines/gob/minigames/geisha/diving.cpp
@@ -23,6 +23,7 @@
#include "common/list.h"
#include "gob/global.h"
+#include "gob/palanim.h"
#include "gob/draw.h"
#include "gob/video.h"
#include "gob/decfile.h"
@@ -31,93 +32,210 @@
#include "gob/sound/sound.h"
#include "gob/minigames/geisha/evilfish.h"
+#include "gob/minigames/geisha/oko.h"
+#include "gob/minigames/geisha/meter.h"
#include "gob/minigames/geisha/diving.h"
namespace Gob {
namespace Geisha {
-static const int kEvilFishTypeCount = 3;
+static const uint8 kAirDecreaseRate = 15;
+
+static const byte kPalette[48] = {
+ 0x00, 0x02, 0x12,
+ 0x01, 0x04, 0x1D,
+ 0x05, 0x08, 0x28,
+ 0x0C, 0x0D, 0x33,
+ 0x15, 0x14, 0x3F,
+ 0x00, 0x3F, 0x00,
+ 0x3F, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x21, 0x0D, 0x00,
+ 0x2F, 0x1A, 0x04,
+ 0x3D, 0x2B, 0x0D,
+ 0x10, 0x10, 0x10,
+ 0x1A, 0x1A, 0x1A,
+ 0x24, 0x24, 0x24,
+ 0x00, 0x01, 0x0F,
+ 0x3F, 0x3F, 0x3F
+};
+
+enum Animation {
+ kAnimationLungs = 0,
+ kAnimationHeart = 1,
+ kAnimationPearl = 4,
+ kAnimationJellyfish = 6,
+ kAnimationWater = 7,
+ kAnimationShot = 17,
+ kAnimationSwarmRedGreen = 32,
+ kAnimationSwarmOrange = 33
+};
-static const int kEvilFishTypes[kEvilFishTypeCount][5] = {
+
+const uint16 Diving::kEvilFishTypes[kEvilFishTypeCount][5] = {
{ 0, 14, 8, 9, 3}, // Shark
{15, 1, 12, 13, 3}, // Moray
{16, 2, 10, 11, 3} // Ray
};
+const uint16 Diving::kPlantLevel1[] = { 18, 19, 20, 21 };
+const uint16 Diving::kPlantLevel2[] = { 22, 23, 24, 25 };
+const uint16 Diving::kPlantLevel3[] = { 26, 27, 28, 29, 30 };
+
+const Diving::PlantLevel Diving::kPlantLevels[] = {
+ { 150, ARRAYSIZE(kPlantLevel1), kPlantLevel1 },
+ { 120, ARRAYSIZE(kPlantLevel2), kPlantLevel2 },
+ { 108, ARRAYSIZE(kPlantLevel3), kPlantLevel3 },
+};
+
Diving::Diving(GobEngine *vm) : _vm(vm), _background(0),
- _objects(0), _gui(0), _oko(0), _lungs(0), _heart(0),
- _blackPearl(0), _whitePearlCount(0), _blackPearlCount(0) {
+ _objects(0), _gui(0), _okoAnim(0), _water(0), _lungs(0), _heart(0),
+ _blackPearl(0), _airMeter(0), _healthMeter(0), _isPlaying(false) {
_blackPearl = new Surface(11, 8, 1);
+
+ _airMeter = new Meter(3 , 195, 40, 2, 5, 7, 40, Meter::kFillToLeft);
+ _healthMeter = new Meter(275, 195, 40, 2, 6, 7, 4, Meter::kFillToLeft);
+
+ for (uint i = 0; i < kEvilFishCount; i++)
+ _evilFish[i].evilFish = 0;
+
+ for (uint i = 0; i < kDecorFishCount; i++)
+ _decorFish[i].decorFish = 0;
+
+ for (uint i = 0; i < kPlantCount; i++)
+ _plant[i].plant = 0;
+
+ for (uint i = 0; i < kMaxShotCount; i++)
+ _shot[i] = 0;
+
+ _pearl.pearl = 0;
+
+ _oko = 0;
}
Diving::~Diving() {
+ delete _airMeter;
+ delete _healthMeter;
+
delete _blackPearl;
deinit();
}
bool Diving::play(uint16 playerCount, bool hasPearlLocation) {
+ _hasPearlLocation = hasPearlLocation;
+ _isPlaying = true;
+
+ // Fade to black
+ _vm->_palAnim->fade(0, 0, 0);
+
+ // Initialize our playing field
init();
initScreen();
initCursor();
+ initPlants();
+
+ updateAirMeter();
+ updateAnims();
_vm->_draw->blitInvalidated();
_vm->_video->retrace();
+ // Fade in
+ _vm->_palAnim->fade(_vm->_global->_pPaletteDesc, 0, 0);
+
while (!_vm->shouldQuit()) {
- checkShots();
+ checkShots(); // Check if a shot hit something
+ checkOkoHurt(); // Check if Oko was hurt
+
+ // Is Oko dead?
+ if (_oko->isPaused())
+ break;
+
+ // Update all objects and animations
+ updateAirMeter();
updateEvilFish();
updateDecorFish();
+ updatePlants();
+ updatePearl();
updateAnims();
_vm->_draw->animateCursor(1);
+ // Draw and wait for the end of the frame
_vm->_draw->blitInvalidated();
-
_vm->_util->waitEndFrame();
+
+ // Handle input
_vm->_util->processInput();
int16 mouseX, mouseY;
MouseButtons mouseButtons;
int16 key = checkInput(mouseX, mouseY, mouseButtons);
+
+ // Aborting the game
if (key == kKeyEscape)
break;
+ // Shoot the gun
if (mouseButtons == kMouseButtonsLeft)
shoot(mouseX, mouseY);
+ // Oko
+ handleOko(key);
+
+ // Game end check
if ((_whitePearlCount >= 20) || (_blackPearlCount >= 2))
break;
}
deinit();
+
+ _isPlaying = false;
+
+ // The game succeeded when we got 2 black pearls
return _blackPearlCount >= 2;
}
+bool Diving::isPlaying() const {
+ return _isPlaying;
+}
+
+void Diving::cheatWin() {
+ _blackPearlCount = 2;
+}
+
void Diving::init() {
+ // Load sounds
+ _vm->_sound->sampleLoad(&_soundShoot , SOUND_SND, "tirgim.snd");
+ _vm->_sound->sampleLoad(&_soundBreathe , SOUND_SND, "respir.snd");
+ _vm->_sound->sampleLoad(&_soundWhitePearl, SOUND_SND, "virtou.snd");
+ _vm->_sound->sampleLoad(&_soundBlackPearl, SOUND_SND, "trouve.snd");
+
+ // Load and initialize sprites and animations
_background = new DECFile(_vm, "tperle.dec" , 320, 200);
_objects = new ANIFile(_vm, "tperle.ani" , 320);
_gui = new ANIFile(_vm, "tperlcpt.ani", 320);
- _oko = new ANIFile(_vm, "tplonge.ani" , 320);
+ _okoAnim = new ANIFile(_vm, "tplonge.ani" , 320);
_water = new ANIObject(*_objects);
_lungs = new ANIObject(*_gui);
_heart = new ANIObject(*_gui);
- _water->setAnimation(7);
+ _water->setAnimation(kAnimationWater);
_water->setPosition();
_water->setVisible(true);
- _lungs->setAnimation(0);
+ _lungs->setAnimation(kAnimationLungs);
_lungs->setPosition();
_lungs->setVisible(true);
_lungs->setPause(true);
- _heart->setAnimation(1);
+ _heart->setAnimation(kAnimationHeart);
_heart->setPosition();
_heart->setVisible(true);
_heart->setPause(true);
@@ -135,22 +253,39 @@ void Diving::init() {
_decorFish[i].decorFish = new ANIObject(*_objects);
}
- _decorFish[0].decorFish->setAnimation( 6); // Jellyfish
+ for (uint i = 0; i < kPlantCount; i++) {
+ _plant[i].level = i / kPlantPerLevelCount;
+ _plant[i].deltaX = (kPlantLevelCount - _plant[i].level) * -2;
+
+ _plant[i].x = -1;
+ _plant[i].y = -1;
+
+ _plant[i].plant = new ANIObject(*_objects);
+ }
+
+ _pearl.pearl = new ANIObject(*_objects);
+ _pearl.black = false;
+
+ _pearl.pearl->setAnimation(kAnimationPearl);
+
+ _decorFish[0].decorFish->setAnimation(kAnimationJellyfish);
_decorFish[0].deltaX = 0;
- _decorFish[1].decorFish->setAnimation(32); // Swarm of red/green fish
- _decorFish[1].deltaX = -6;
+ _decorFish[1].decorFish->setAnimation(kAnimationSwarmRedGreen);
+ _decorFish[1].deltaX = -5;
- _decorFish[2].decorFish->setAnimation(33); // Swarm of orange fish
- _decorFish[2].deltaX = -6;
+ _decorFish[2].decorFish->setAnimation(kAnimationSwarmOrange);
+ _decorFish[2].deltaX = -5;
for (uint i = 0; i < kMaxShotCount; i++) {
_shot[i] = new ANIObject(*_objects);
- _shot[i]->setAnimation(17);
+ _shot[i]->setAnimation(kAnimationShot);
_shot[i]->setMode(ANIObject::kModeOnce);
}
+ _oko = new Oko(*_okoAnim, *_vm->_sound, _soundBreathe);
+
Surface tmp(320, 103, 1);
_vm->_video->drawPackedSprite("tperlobj.cmp", tmp);
@@ -161,20 +296,30 @@ void Diving::init() {
_currentShot = 0;
+ // Add the animations to our animation list
_anims.push_back(_water);
for (uint i = 0; i < kMaxShotCount; i++)
_anims.push_back(_shot[i]);
+ _anims.push_back(_pearl.pearl);
for (uint i = 0; i < kDecorFishCount; i++)
_anims.push_back(_decorFish[i].decorFish);
for (uint i = 0; i < kEvilFishCount; i++)
_anims.push_back(_evilFish[i].evilFish);
+ for (int i = kPlantCount - 1; i >= 0; i--)
+ _anims.push_back(_plant[i].plant);
+ _anims.push_back(_oko);
_anims.push_back(_lungs);
_anims.push_back(_heart);
- _vm->_sound->sampleLoad(&_soundShoot , SOUND_SND, "tirgim.snd");
- _vm->_sound->sampleLoad(&_soundBreathe , SOUND_SND, "respir.snd");
- _vm->_sound->sampleLoad(&_soundWhitePearl, SOUND_SND, "virtou.snd");
- _vm->_sound->sampleLoad(&_soundBlackPearl, SOUND_SND, "trouve.snd");
+ // Air and health meter
+ _airMeter->setMaxValue();
+ _healthMeter->setMaxValue();
+
+ _airCycle = 0;
+ _hurtGracePeriod = 0;
+
+ _whitePearlCount = 0;
+ _blackPearlCount = 0;
}
void Diving::deinit() {
@@ -208,11 +353,23 @@ void Diving::deinit() {
_decorFish[i].decorFish = 0;
}
+ for (uint i = 0; i < kPlantCount; i++) {
+ delete _plant[i].plant;
+
+ _plant[i].plant = 0;
+ }
+
+ delete _pearl.pearl;
+ _pearl.pearl = 0;
+
+ delete _oko;
+ _oko = 0;
+
delete _heart;
delete _lungs;
delete _water;
- delete _oko;
+ delete _okoAnim;
delete _gui;
delete _objects;
delete _background;
@@ -221,24 +378,30 @@ void Diving::deinit() {
_heart = 0;
_lungs = 0;
- _oko = 0;
+ _okoAnim = 0;
_gui = 0;
_objects = 0;
_background = 0;
}
void Diving::initScreen() {
+ // Set framerate
_vm->_util->setFrameRate(15);
- _vm->_video->setFullPalette(_vm->_global->_pPaletteDesc);
+ // Set palette
+ memcpy(_vm->_draw->_vgaPalette , kPalette, sizeof(kPalette));
+ memcpy(_vm->_draw->_vgaSmallPalette, kPalette, sizeof(kPalette));
+ // Draw background decal
_vm->_draw->_backSurface->clear();
_background->draw(*_vm->_draw->_backSurface);
+ // Draw heart and lung boxes
int16 left, top, right, bottom;
_lungs->draw(*_vm->_draw->_backSurface, left, top, right, bottom);
_heart->draw(*_vm->_draw->_backSurface, left, top, right, bottom);
+ // Mark everything as dirty
_vm->_draw->dirtiedRect(_vm->_draw->_backSurface, 0, 0, 319, 199);
}
@@ -259,6 +422,89 @@ void Diving::initCursor() {
_vm->_draw->_cursorHotspotY = 8;
}
+
+void Diving::initPlants() {
+ // Create initial plantlife
+ for (uint i = 0; i < kPlantLevelCount; i++) {
+ for (uint j = 0; j < kPlantPerLevelCount; j++) {
+ int16 prevPlantX = -100;
+ if (j > 0)
+ prevPlantX = _plant[i * kPlantPerLevelCount + j - 1].x;
+
+ enterPlant(_plant[i * kPlantPerLevelCount + j], prevPlantX);
+ }
+ }
+}
+
+void Diving::enterPlant(ManagedPlant &plant, int16 prevPlantX) {
+ // Create a new plant outside the borders of the screen to scroll in
+
+ const PlantLevel &level = kPlantLevels[plant.level];
+ const uint anim = level.plants[_vm->_util->getRandom(kPlantLevels[plant.level].plantCount)];
+
+ plant.plant->setAnimation(anim);
+ plant.plant->rewind();
+
+ int16 width, height;
+ plant.plant->getFrameSize(width, height);
+
+ // The new plant is created 140 - 160 pixels to the right of the right-most plant
+ plant.x = prevPlantX + 150 - 10 + _vm->_util->getRandom(21);
+ plant.y = kPlantLevels[plant.level].y - height;
+
+ plant.plant->setPosition(plant.x, plant.y);
+ plant.plant->setVisible(true);
+ plant.plant->setPause(false);
+
+ // If the plant is outside of the screen, create a pearl too if necessary
+ if (plant.x > 320)
+ enterPearl(plant.x);
+}
+
+void Diving::enterPearl(int16 x) {
+ // Create a pearl outside the borders of the screen to scroll in
+
+ // Only one pearl is ever visible
+ if (_pearl.pearl->isVisible())
+ return;
+
+ // Only every 4th potential pearl position has a pearl
+ if (_vm->_util->getRandom(4) != 0)
+ return;
+
+ // Every 5th pearl is a black one, but only if the location is correct
+ _pearl.black = _hasPearlLocation && (_vm->_util->getRandom(5) == 0);
+
+ // Set the pearl about in the middle of two bottom-level plants
+ _pearl.pearl->setPosition(x + 80, 130);
+
+ _pearl.pearl->setVisible(true);
+ _pearl.pearl->setPause(false);
+ _pearl.picked = false;
+}
+
+void Diving::updateAirMeter() {
+ if (_oko->isBreathing()) {
+ // If Oko is breathing, increase the air meter and play the lungs animation
+ _airCycle = 0;
+ _airMeter->increase();
+ _lungs->setPause(false);
+ return;
+ } else
+ // Otherwise, don't play the lungs animation
+ _lungs->setPause(true);
+
+ // Update the air cycle and decrease the air meter when the cycle ended
+ _airCycle = (_airCycle + 1) % kAirDecreaseRate;
+
+ if (_airCycle == 0)
+ _airMeter->decrease();
+
+ // Without any air, Oko dies
+ if (_airMeter->getValue() == 0)
+ _oko->die();
+}
+
void Diving::updateEvilFish() {
for (uint i = 0; i < kEvilFishCount; i++) {
ManagedEvilFish &fish = _evilFish[i];
@@ -283,6 +529,7 @@ void Diving::updateEvilFish() {
fish.enterAt = _vm->_util->getTimeKey() + 2000 + _vm->_util->getRandom(8000);
if (_vm->_util->getTimeKey() >= fish.enterAt) {
+ // The new fish has a random type
int fishType = _vm->_util->getRandom(kEvilFishTypeCount);
fish.evilFish->mutate(kEvilFishTypes[fishType][0], kEvilFishTypes[fishType][1],
kEvilFishTypes[fishType][2], kEvilFishTypes[fishType][3],
@@ -333,9 +580,100 @@ void Diving::updateDecorFish() {
}
}
+void Diving::updatePlants() {
+ // When Oko isn't moving, the plants don't continue to scroll by
+ if (!_oko->isMoving())
+ return;
+
+ for (uint i = 0; i < kPlantCount; i++) {
+ ManagedPlant &plant = _plant[i];
+
+ if (plant.plant->isVisible()) {
+ // Move the plant
+ plant.plant->setPosition(plant.x += plant.deltaX, plant.y);
+
+ // Check if the plant has left the screen
+ int16 x, y, width, height;
+ plant.plant->getFramePosition(x, y);
+ plant.plant->getFrameSize(width, height);
+
+ if ((x + width) <= 0) {
+ plant.plant->setVisible(false);
+ plant.plant->setPause(true);
+
+ plant.x = 0;
+ }
+
+ } else {
+ // Find the right-most plant in this level and enter the plant to the right of it
+
+ int16 rightX = 320;
+ for (uint j = 0; j < kPlantPerLevelCount; j++)
+ rightX = MAX(rightX, _plant[plant.level * kPlantPerLevelCount + j].x);
+
+ enterPlant(plant, rightX);
+ }
+ }
+}
+
+void Diving::updatePearl() {
+ if (!_pearl.pearl->isVisible())
+ return;
+
+ // When Oko isn't moving, the pearl doesn't continue to scroll by
+ if (!_oko->isMoving())
+ return;
+
+ // Picking the pearl
+ if (_pearl.picked && (_oko->getState() == Oko::kStatePick) && (_oko->getFrame() == 8)) {
+ // Remove the pearl
+ _pearl.pearl->setVisible(false);
+ _pearl.pearl->setPause(true);
+
+ // Add the pearl to our found pearls repository
+ if (_pearl.black)
+ foundBlackPearl();
+ else
+ foundWhitePearl();
+
+ return;
+ }
+
+ // Move the pearl
+ int16 x, y, width, height;
+ _pearl.pearl->getPosition(x, y);
+ _pearl.pearl->setPosition(x - 5, y);
+
+ // Check if the pearl has left the screen
+ _pearl.pearl->getFramePosition(x, y);
+ _pearl.pearl->getFrameSize(width, height);
+
+ if ((x + width) <= 0) {
+ _pearl.pearl->setVisible(false);
+ _pearl.pearl->setPause(true);
+ }
+}
+
+void Diving::getPearl() {
+ if (!_pearl.pearl->isVisible())
+ return;
+
+ // Make sure the pearl is within Oko's grasp
+
+ int16 x, y, width, height;
+ _pearl.pearl->getFramePosition(x, y);
+ _pearl.pearl->getFrameSize(width, height);
+
+ if ((x > 190) || ((x + width) < 140))
+ return;
+
+ _pearl.picked = true;
+}
+
void Diving::foundBlackPearl() {
_blackPearlCount++;
+ // Put the black pearl drawing into the black pearl box
if (_blackPearlCount == 1) {
_vm->_draw->_backSurface->blit(*_blackPearl, 0, 0, 10, 7, 147, 179, 0);
_vm->_draw->dirtiedRect(_vm->_draw->_backSurface, 147, 179, 157, 186);
@@ -343,17 +681,22 @@ void Diving::foundBlackPearl() {
_vm->_draw->_backSurface->blit(*_blackPearl, 0, 0, 10, 7, 160, 179, 0);
_vm->_draw->dirtiedRect(_vm->_draw->_backSurface, 147, 179, 160, 186);
}
+
+ _vm->_sound->blasterPlay(&_soundBlackPearl, 1, 0);
}
void Diving::foundWhitePearl() {
_whitePearlCount++;
+ // Put the white pearl drawing into the white pearl box
int16 x = 54 + (_whitePearlCount - 1) * 8;
if (_whitePearlCount > 10)
x += 48;
_background->drawLayer(*_vm->_draw->_backSurface, 0, 2, x, 177, 0);
_vm->_draw->dirtiedRect(_vm->_draw->_backSurface, x, 177, x + 3, 180);
+
+ _vm->_sound->blasterPlay(&_soundWhitePearl, 1, 0);
}
void Diving::updateAnims() {
@@ -376,6 +719,13 @@ void Diving::updateAnims() {
(*a)->advance();
}
+
+ // Draw the meters
+ _airMeter->draw(*_vm->_draw->_backSurface, left, top, right, bottom);
+ _vm->_draw->dirtiedRect(_vm->_draw->_backSurface, left, top, right, bottom);
+
+ _healthMeter->draw(*_vm->_draw->_backSurface, left, top, right, bottom);
+ _vm->_draw->dirtiedRect(_vm->_draw->_backSurface, left, top, right, bottom);
}
int16 Diving::checkInput(int16 &mouseX, int16 &mouseY, MouseButtons &mouseButtons) {
@@ -410,6 +760,7 @@ void Diving::shoot(int16 mouseX, int16 mouseY) {
void Diving::checkShots() {
Common::List<int>::iterator activeShot = _activeShots.begin();
+ // Check if we hit something with our shots
while (activeShot != _activeShots.end()) {
ANIObject &shot = *_shot[*activeShot];
@@ -418,6 +769,7 @@ void Diving::checkShots() {
shot.getPosition(x, y);
+ // When we hit an evil fish, it dies
for (uint i = 0; i < kEvilFishCount; i++) {
EvilFish &evilFish = *_evilFish[i].evilFish;
@@ -434,6 +786,48 @@ void Diving::checkShots() {
}
}
+void Diving::handleOko(int16 key) {
+ if (key == kKeyDown) {
+ // Oko sinks down a level or picks up a pearl if already at the bottom
+ _oko->sink();
+
+ if ((_oko->getState() == Oko::kStatePick) && (_oko->getFrame() == 0))
+ getPearl();
+
+ } else if (key == kKeyUp)
+ // Oko raises up a level or surfaces to breathe if already at the top
+ _oko->raise();
+}
+
+void Diving::checkOkoHurt() {
+ if (_oko->getState() != Oko::kStateSwim)
+ return;
+
+ // Give Oko a grace period after being hurt
+ if (_hurtGracePeriod > 0) {
+ _hurtGracePeriod--;
+ return;
+ }
+
+ // Check for a fish/Oko-collision
+ for (uint i = 0; i < kEvilFishCount; i++) {
+ EvilFish &evilFish = *_evilFish[i].evilFish;
+
+ if (!evilFish.isDead() && evilFish.isIn(*_oko)) {
+ _healthMeter->decrease();
+
+ // If the health reached 0, Oko dies. Otherwise, she gets hurt
+ if (_healthMeter->getValue() == 0)
+ _oko->die();
+ else
+ _oko->hurt();
+
+ _hurtGracePeriod = 10;
+ break;
+ }
+ }
+}
+
} // End of namespace Geisha
} // End of namespace Gob
diff --git a/engines/gob/minigames/geisha/diving.h b/engines/gob/minigames/geisha/diving.h
index e386d783d7..089d60b260 100644
--- a/engines/gob/minigames/geisha/diving.h
+++ b/engines/gob/minigames/geisha/diving.h
@@ -40,6 +40,8 @@ class ANIObject;
namespace Geisha {
class EvilFish;
+class Oko;
+class Meter;
/** Geisha's "Diving" minigame. */
class Diving {
@@ -49,11 +51,34 @@ public:
bool play(uint16 playerCount, bool hasPearlLocation);
+ bool isPlaying() const;
+ void cheatWin();
+
private:
static const uint kEvilFishCount = 3;
static const uint kDecorFishCount = 3;
static const uint kMaxShotCount = 10;
+ static const uint kEvilFishTypeCount = 3;
+ static const uint16 kEvilFishTypes[kEvilFishTypeCount][5];
+
+ struct PlantLevel {
+ int16 y;
+ uint plantCount;
+ const uint16 *plants;
+ };
+
+ static const uint kPlantLevelCount = 3;
+ static const uint kPlantPerLevelCount = 5;
+
+ static const uint16 kPlantLevel1[];
+ static const uint16 kPlantLevel2[];
+ static const uint16 kPlantLevel3[];
+
+ static const PlantLevel kPlantLevels[kPlantLevelCount];
+
+ static const uint kPlantCount = kPlantLevelCount * kPlantPerLevelCount;
+
struct ManagedEvilFish {
EvilFish *evilFish;
@@ -68,12 +93,27 @@ private:
int8 deltaX;
};
+ struct ManagedPlant {
+ ANIObject *plant;
+
+ uint level;
+ int8 deltaX;
+ int16 x, y;
+ };
+
+ struct ManagedPearl {
+ ANIObject *pearl;
+
+ bool picked;
+ bool black;
+ };
+
GobEngine *_vm;
DECFile *_background;
ANIFile *_objects;
ANIFile *_gui;
- ANIFile *_oko;
+ ANIFile *_okoAnim;
ANIObject *_water;
ANIObject *_lungs;
@@ -81,6 +121,10 @@ private:
ManagedEvilFish _evilFish[kEvilFishCount];
ManagedDecorFish _decorFish[kDecorFishCount];
+ ManagedPlant _plant[kPlantCount];
+ ManagedPearl _pearl;
+
+ Oko *_oko;
ANIObject *_shot[kMaxShotCount];
@@ -93,6 +137,12 @@ private:
uint8 _whitePearlCount;
uint8 _blackPearlCount;
+ Meter *_airMeter;
+ Meter *_healthMeter;
+
+ uint8 _airCycle;
+ uint8 _hurtGracePeriod;
+
uint8 _currentShot;
SoundDesc _soundShoot;
@@ -100,24 +150,40 @@ private:
SoundDesc _soundWhitePearl;
SoundDesc _soundBlackPearl;
+ bool _hasPearlLocation;
+ bool _isPlaying;
+
void init();
void deinit();
void initScreen();
void initCursor();
+ void initPlants();
+
+ void enterPlant(ManagedPlant &plant, int16 prevPlantX);
+ void enterPearl(int16 x);
+
+ void getPearl();
void foundBlackPearl();
void foundWhitePearl();
+ void updateAirMeter();
void updateEvilFish();
void updateDecorFish();
+ void updatePlants();
+ void updatePearl();
void updateAnims();
int16 checkInput(int16 &mouseX, int16 &mouseY, MouseButtons &mouseButtons);
void shoot(int16 mouseX, int16 mouseY);
void checkShots();
+
+ void handleOko(int16 key);
+
+ void checkOkoHurt();
};
} // End of namespace Geisha
diff --git a/engines/gob/minigames/geisha/evilfish.cpp b/engines/gob/minigames/geisha/evilfish.cpp
index e9503f4aed..c7ef9d5622 100644
--- a/engines/gob/minigames/geisha/evilfish.cpp
+++ b/engines/gob/minigames/geisha/evilfish.cpp
@@ -39,19 +39,6 @@ EvilFish::EvilFish(const ANIFile &ani, uint16 screenWidth,
EvilFish::~EvilFish() {
}
-bool EvilFish::isIn(int16 x, int16 y) const {
- int16 frameX, frameY, frameWidth, frameHeight;
- getFramePosition(frameX, frameY);
- getFrameSize(frameWidth, frameHeight);
-
- if ((x < frameX) || (y < frameY))
- return false;
- if ((x > (frameX + frameWidth)) || (y > (frameY + frameHeight)))
- return false;
-
- return true;
-}
-
void EvilFish::enter(Direction from, int16 y) {
_shouldLeave = false;
@@ -184,6 +171,10 @@ void EvilFish::mutate(uint16 animSwimLeft, uint16 animSwimRight,
}
}
+bool EvilFish::isDead() {
+ return !isVisible() || (_state == kStateNone) || (_state == kStateDie);
+}
+
} // End of namespace Geisha
} // End of namespace Gob
diff --git a/engines/gob/minigames/geisha/evilfish.h b/engines/gob/minigames/geisha/evilfish.h
index 223645f47f..81efb676e2 100644
--- a/engines/gob/minigames/geisha/evilfish.h
+++ b/engines/gob/minigames/geisha/evilfish.h
@@ -42,9 +42,6 @@ public:
uint16 animTurnLeft, uint16 animTurnRight, uint16 animDie);
~EvilFish();
- /** Are there coordinates within the fish's sprite? */
- bool isIn(int16 x, int16 y) const;
-
/** Enter from this direction / screen edge. */
void enter(Direction from, int16 y);
/** Leave the screen in the current direction. */
@@ -60,6 +57,9 @@ public:
void mutate(uint16 animSwimLeft, uint16 animSwimRight,
uint16 animTurnLeft, uint16 animTurnRight, uint16 animDie);
+ /** Is the fish dead? */
+ bool isDead();
+
private:
enum State {
kStateNone,
diff --git a/engines/gob/minigames/geisha/meter.cpp b/engines/gob/minigames/geisha/meter.cpp
new file mode 100644
index 0000000000..e3b9bd1ccf
--- /dev/null
+++ b/engines/gob/minigames/geisha/meter.cpp
@@ -0,0 +1,116 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "common/util.h"
+
+#include "gob/surface.h"
+
+#include "gob/minigames/geisha/meter.h"
+
+namespace Gob {
+
+namespace Geisha {
+
+Meter::Meter(int16 x, int16 y, int16 width, int16 height, uint8 frontColor,
+ uint8 backColor, int32 maxValue, Direction direction) :
+ _x(x), _y(y), _width(width), _height(height), _frontColor(frontColor),
+ _backColor(backColor), _value(0), _maxValue(maxValue), _direction(direction),
+ _needUpdate(true), _surface(0) {
+
+}
+
+Meter::~Meter() {
+ delete _surface;
+}
+
+int32 Meter::getValue() const {
+ return _value;
+}
+
+void Meter::setValue(int32 value) {
+ value = CLIP<int32>(value, 0, _maxValue);
+ if (_value == value)
+ return;
+
+ _value = value;
+ _needUpdate = true;
+}
+
+void Meter::setMaxValue() {
+ setValue(_maxValue);
+}
+
+void Meter::increase(int32 n) {
+ int32 value = CLIP<int32>(_value + n, 0, _maxValue);
+ if (_value == value)
+ return;
+
+ _value = value;
+ _needUpdate = true;
+}
+
+void Meter::decrease(int32 n) {
+ int32 value = CLIP<int32>(_value - n, 0, _maxValue);
+ if (_value == value)
+ return;
+
+ _value = value;
+ _needUpdate = true;
+}
+
+void Meter::draw(Surface &dest, int16 &left, int16 &top, int16 &right, int16 &bottom) {
+ if (!_surface) {
+ _surface = new Surface(_width, _height, dest.getBPP());
+ _needUpdate = true;
+ }
+
+ update();
+
+ left = CLIP<int16>(_x , 0, dest.getWidth () - 1);
+ top = CLIP<int16>(_y , 0, dest.getHeight() - 1);
+ right = CLIP<int16>(_x + _width - 1, 0, dest.getWidth () - 1);
+ bottom = CLIP<int16>(_y + _height - 1, 0, dest.getHeight() - 1);
+
+ dest.blit(*_surface, left - _x, top - _y, _width, _height, left, top);
+}
+
+void Meter::update() {
+ if (!_needUpdate)
+ return;
+
+ _needUpdate = false;
+
+ _surface->fill(_backColor);
+
+ int32 n = (int32)floor((((float) _width) / _maxValue * _value) + 0.5);
+ if (n <= 0)
+ return;
+
+ if (_direction == kFillToLeft)
+ _surface->fillRect(_width - n, 0, _width - 1, _height - 1, _frontColor);
+ else
+ _surface->fillRect(0 , 0, n - 1, _height - 1, _frontColor);
+}
+
+} // End of namespace Geisha
+
+} // End of namespace Gob
diff --git a/engines/gob/minigames/geisha/meter.h b/engines/gob/minigames/geisha/meter.h
new file mode 100644
index 0000000000..a9bdb14d0f
--- /dev/null
+++ b/engines/gob/minigames/geisha/meter.h
@@ -0,0 +1,89 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef GOB_MINIGAMES_GEISHA_METER_H
+#define GOB_MINIGAMES_GEISHA_METER_H
+
+#include "gob/aniobject.h"
+
+namespace Gob {
+
+class Surface;
+
+namespace Geisha {
+
+/** A meter measuring a value. */
+class Meter {
+public:
+ enum Direction {
+ kFillToLeft,
+ kFillToRight
+ };
+
+ Meter(int16 x, int16 y, int16 width, int16 height,
+ uint8 frontColor, uint8 backColor, int32 maxValue,
+ Direction direction);
+ ~Meter();
+
+ /** Return the current value the meter is measuring. */
+ int32 getValue() const;
+
+ /** Set the current value the meter is measuring. */
+ void setValue(int32 value);
+
+ /** Set the current value the meter is measuring to the max value. */
+ void setMaxValue();
+
+ /** Increase the current value the meter is measuring. */
+ void increase(int32 n = 1);
+ /** Decrease the current value the meter is measuring. */
+ void decrease(int32 n = 1);
+
+ /** Draw the meter onto the surface and return the affected rectangle. */
+ void draw(Surface &dest, int16 &left, int16 &top, int16 &right, int16 &bottom);
+
+private:
+ int16 _x;
+ int16 _y;
+ int16 _width;
+ int16 _height;
+
+ uint8 _frontColor;
+ uint8 _backColor;
+
+ int32 _value;
+ int32 _maxValue;
+
+ Direction _direction;
+
+ bool _needUpdate;
+
+ Surface *_surface;
+
+ void update();
+};
+
+} // End of namespace Geisha
+
+} // End of namespace Gob
+
+#endif // GOB_MINIGAMES_GEISHA_METER_H
diff --git a/engines/gob/minigames/geisha/oko.cpp b/engines/gob/minigames/geisha/oko.cpp
new file mode 100644
index 0000000000..7ad8be6fa2
--- /dev/null
+++ b/engines/gob/minigames/geisha/oko.cpp
@@ -0,0 +1,170 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "gob/sound/sound.h"
+
+#include "gob/minigames/geisha/oko.h"
+
+namespace Gob {
+
+namespace Geisha {
+
+enum kOkoAnimation {
+ kOkoAnimationEnter = 0,
+ kOkoAnimationSwim = 1,
+ kOkoAnimationSink = 8,
+ kOkoAnimationRaise = 7,
+ kOkoAnimationBreathe = 2,
+ kOkoAnimationPick = 3,
+ kOkoAnimationHurt = 4,
+ kOkoAnimationDie0 = 17,
+ kOkoAnimationDie1 = 18,
+ kOkoAnimationDie2 = 19
+};
+
+static const int16 kOkoPositionX = 110;
+
+static const uint kLevelCount = 3;
+static const int16 kLevelPositionX[kLevelCount] = { 44, 84, 124 };
+
+
+Oko::Oko(const ANIFile &ani, Sound &sound, SoundDesc &breathe) :
+ ANIObject(ani), _sound(&sound), _breathe(&breathe), _state(kStateEnter), _level(0) {
+
+ setAnimation(kOkoAnimationEnter);
+ setVisible(true);
+}
+
+Oko::~Oko() {
+}
+
+void Oko::advance() {
+ bool wasLastFrame = lastFrame();
+
+ if ((_state == kStateDead) && wasLastFrame) {
+ setPause(true);
+ return;
+ }
+
+ ANIObject::advance();
+
+ switch (_state) {
+ case kStateEnter:
+ if (wasLastFrame) {
+ setAnimation(kOkoAnimationSwim);
+ setPosition(kOkoPositionX, kLevelPositionX[_level]);
+ _state = kStateSwim;
+ }
+ break;
+
+ case kStateBreathe:
+ if ((getFrame() == 6) || (getFrame() == 23))
+ _sound->blasterPlay(_breathe, 1, 0);
+ case kStateSink:
+ case kStateRaise:
+ case kStateHurt:
+ if (wasLastFrame) {
+ setAnimation(kOkoAnimationSwim);
+ setPosition(kOkoPositionX, kLevelPositionX[_level]);
+ _state = kStateSwim;
+ }
+ break;
+
+ case kStatePick:
+ if (wasLastFrame) {
+ _level = 1;
+ setAnimation(kOkoAnimationSwim);
+ setPosition(kOkoPositionX, kLevelPositionX[_level]);
+ _state = kStateSwim;
+ }
+ break;
+
+ default:
+ break;
+ }
+}
+
+void Oko::sink() {
+ if (_state != kStateSwim)
+ return;
+
+ if (_level >= (kLevelCount - 1)) {
+ setAnimation(kOkoAnimationPick);
+ _state = kStatePick;
+ return;
+ }
+
+ setAnimation(kOkoAnimationSink);
+ setPosition(kOkoPositionX, kLevelPositionX[_level]);
+ _state = kStateSink;
+
+ _level++;
+}
+
+void Oko::raise() {
+ if (_state != kStateSwim)
+ return;
+
+ if (_level == 0) {
+ setAnimation(kOkoAnimationBreathe);
+ _state = kStateBreathe;
+ return;
+ }
+
+ setAnimation(kOkoAnimationRaise);
+ setPosition(kOkoPositionX, kLevelPositionX[_level]);
+ _state = kStateSink;
+
+ _level--;
+}
+
+void Oko::hurt() {
+ if (_state != kStateSwim)
+ return;
+
+ setAnimation(kOkoAnimationHurt);
+ _state = kStateHurt;
+}
+
+void Oko::die() {
+ if (_state != kStateSwim)
+ return;
+
+ setAnimation(kOkoAnimationDie0 + _level);
+ _state = kStateDead;
+}
+
+Oko::State Oko::getState() const {
+ return _state;
+}
+
+bool Oko::isBreathing() const {
+ return (_state == kStateBreathe) && ((getFrame() >= 9) && (getFrame() <= 30));
+}
+
+bool Oko::isMoving() const {
+ return (_state != kStateBreathe) && (_state != kStateHurt) && (_state != kStateDead);
+}
+
+} // End of namespace Geisha
+
+} // End of namespace Gob
diff --git a/engines/gob/minigames/geisha/oko.h b/engines/gob/minigames/geisha/oko.h
new file mode 100644
index 0000000000..82c6f59be4
--- /dev/null
+++ b/engines/gob/minigames/geisha/oko.h
@@ -0,0 +1,84 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef GOB_MINIGAMES_GEISHA_OKO_H
+#define GOB_MINIGAMES_GEISHA_OKO_H
+
+#include "gob/aniobject.h"
+
+namespace Gob {
+
+class Sound;
+class SoundDesc;
+
+namespace Geisha {
+
+/** Oko, the person you control, in Geisha's "Diving" minigame. */
+class Oko : public ANIObject {
+public:
+ enum State {
+ kStateEnter,
+ kStateSwim,
+ kStateSink,
+ kStateRaise,
+ kStateBreathe,
+ kStatePick,
+ kStateHurt,
+ kStateDead
+ };
+
+ Oko(const ANIFile &ani, Sound &sound, SoundDesc &breathe);
+ ~Oko();
+
+ /** Advance the animation to the next frame. */
+ void advance();
+
+ /** Oko should sink a level. */
+ void sink();
+ /** Oko should raise a level. */
+ void raise();
+
+ /** Oko should get hurt. */
+ void hurt();
+
+ /** Oko should die. */
+ void die();
+
+ State getState() const;
+
+ bool isBreathing() const;
+ bool isMoving() const;
+
+private:
+ Sound *_sound;
+ SoundDesc *_breathe;
+
+ State _state;
+
+ uint8 _level;
+};
+
+} // End of namespace Geisha
+
+} // End of namespace Gob
+
+#endif // GOB_MINIGAMES_GEISHA_OKO_H
diff --git a/engines/gob/module.mk b/engines/gob/module.mk
index bf040c5428..1c83b4ae40 100644
--- a/engines/gob/module.mk
+++ b/engines/gob/module.mk
@@ -3,6 +3,8 @@ MODULE := engines/gob
MODULE_OBJS := \
anifile.o \
aniobject.o \
+ cheater.o \
+ cheater_geisha.o \
console.o \
dataio.o \
databases.o \
@@ -74,6 +76,8 @@ MODULE_OBJS := \
demos/scnplayer.o \
demos/batplayer.o \
minigames/geisha/evilfish.o \
+ minigames/geisha/oko.o \
+ minigames/geisha/meter.o \
minigames/geisha/diving.o \
minigames/geisha/penetration.o \
save/savefile.o \
diff --git a/engines/gob/sound/bgatmosphere.h b/engines/gob/sound/bgatmosphere.h
index e88b91d540..23fcc8a71a 100644
--- a/engines/gob/sound/bgatmosphere.h
+++ b/engines/gob/sound/bgatmosphere.h
@@ -24,6 +24,7 @@
#define GOB_SOUND_BGATMOSPHERE_H
#include "audio/mixer.h"
+#include "common/array.h"
#include "common/mutex.h"
#include "common/random.h"
diff --git a/engines/groovie/detection.cpp b/engines/groovie/detection.cpp
index f8414ac455..1a3b313649 100644
--- a/engines/groovie/detection.cpp
+++ b/engines/groovie/detection.cpp
@@ -52,7 +52,7 @@ static const GroovieGameDescription gameDescriptions[] = {
"t7g", "",
AD_ENTRY1s("script.grv", "d1b8033b40aa67c076039881eccce90d", 16659),
Common::EN_ANY, Common::kPlatformPC, ADGF_NO_FLAGS,
- GUIO3(GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIGM)
+ GUIO4(GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIGM, GUIO_NOASPECT)
},
kGroovieT7G, 0
},
@@ -63,7 +63,7 @@ static const GroovieGameDescription gameDescriptions[] = {
"t7g", "",
AD_ENTRY1s("T7GMac", "acdc4a58dd3f007f65e99b99d78e0bce", 1814029),
Common::EN_ANY, Common::kPlatformMacintosh, ADGF_MACRESFORK,
- GUIO3(GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIGM)
+ GUIO4(GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIGM, GUIO_NOASPECT)
},
kGroovieT7G, 0
},
@@ -79,7 +79,7 @@ static const GroovieGameDescription gameDescriptions[] = {
"t7g", "",
AD_ENTRY1s("T7GMac", "6bdee8d0f9eef6d58d02fcd7deec3fb2", 1830783),
Common::EN_ANY, Common::kPlatformMacintosh, ADGF_MACRESFORK,
- GUIO3(GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIGM)
+ GUIO4(GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIGM, GUIO_NOASPECT)
},
kGroovieT7G, 0
},
@@ -90,7 +90,7 @@ static const GroovieGameDescription gameDescriptions[] = {
"t7g", "",
AD_ENTRY1s("T7GMac", "0d595d4b44ae1814082938d051e5174e", 1830783),
Common::EN_ANY, Common::kPlatformMacintosh, ADGF_MACRESFORK,
- GUIO3(GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIGM)
+ GUIO4(GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIGM, GUIO_NOASPECT)
},
kGroovieT7G, 0
},
@@ -106,7 +106,7 @@ static const GroovieGameDescription gameDescriptions[] = {
{ NULL, 0, NULL, 0}
},
Common::RU_RUS, Common::kPlatformPC, ADGF_NO_FLAGS,
- GUIO3(GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIGM)
+ GUIO4(GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIGM, GUIO_NOASPECT)
},
kGroovieT7G, 0
},
@@ -120,7 +120,7 @@ static const GroovieGameDescription gameDescriptions[] = {
{ NULL, 0, NULL, 0}
},
Common::EN_ANY, Common::kPlatformIOS, ADGF_NO_FLAGS,
- GUIO1(GUIO_NOMIDI)
+ GUIO2(GUIO_NOMIDI, GUIO_NOASPECT)
},
kGroovieT7G, 0
},
@@ -132,7 +132,7 @@ static const GroovieGameDescription gameDescriptions[] = {
"11h", "",
AD_ENTRY1s("disk.1", "5c0428cd3659fc7bbcd0aa16485ed5da", 227),
Common::EN_ANY, Common::kPlatformPC, ADGF_UNSTABLE,
- GUIO3(GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIGM)
+ GUIO4(GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIGM, GUIO_NOASPECT)
},
kGroovieV2, 1
},
@@ -143,7 +143,7 @@ static const GroovieGameDescription gameDescriptions[] = {
"11h", "Demo",
AD_ENTRY1s("disk.1", "aacb32ce07e0df2894bd83a3dee40c12", 70),
Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO | ADGF_UNSTABLE,
- GUIO4(GUIO_NOLAUNCHLOAD, GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIGM)
+ GUIO5(GUIO_NOLAUNCHLOAD, GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIGM, GUIO_NOASPECT)
},
kGroovieV2, 1
},
@@ -153,7 +153,8 @@ static const GroovieGameDescription gameDescriptions[] = {
{
"11h", "Making Of",
AD_ENTRY1s("disk.1", "5c0428cd3659fc7bbcd0aa16485ed5da", 227),
- Common::EN_ANY, Common::kPlatformPC, ADGF_UNSTABLE, GUIO2(GUIO_NOMIDI, GUIO_NOLAUNCHLOAD)
+ Common::EN_ANY, Common::kPlatformPC, ADGF_UNSTABLE,
+ GUIO3(GUIO_NOMIDI, GUIO_NOLAUNCHLOAD, GUIO_NOASPECT)
},
kGroovieV2, 2
},
@@ -163,7 +164,8 @@ static const GroovieGameDescription gameDescriptions[] = {
{
"clandestiny", "Trailer",
AD_ENTRY1s("disk.1", "5c0428cd3659fc7bbcd0aa16485ed5da", 227),
- Common::EN_ANY, Common::kPlatformPC, ADGF_UNSTABLE, GUIO2(GUIO_NOMIDI, GUIO_NOLAUNCHLOAD)
+ Common::EN_ANY, Common::kPlatformPC, ADGF_UNSTABLE,
+ GUIO3(GUIO_NOMIDI, GUIO_NOLAUNCHLOAD, GUIO_NOASPECT)
},
kGroovieV2, 3
},
@@ -173,7 +175,8 @@ static const GroovieGameDescription gameDescriptions[] = {
{
"clandestiny", "",
AD_ENTRY1s("disk.1", "f79fc1515174540fef6a34132efc4c53", 76),
- Common::EN_ANY, Common::kPlatformPC, ADGF_UNSTABLE, GUIO1(GUIO_NOMIDI)
+ Common::EN_ANY, Common::kPlatformPC, ADGF_UNSTABLE,
+ GUIO2(GUIO_NOMIDI, GUIO_NOASPECT)
},
kGroovieV2, 1
},
@@ -183,7 +186,8 @@ static const GroovieGameDescription gameDescriptions[] = {
{
"unclehenry", "",
AD_ENTRY1s("disk.1", "0e1b1d3cecc4fc7efa62a968844d1f7a", 72),
- Common::EN_ANY, Common::kPlatformPC, ADGF_UNSTABLE, GUIO1(GUIO_NOMIDI)
+ Common::EN_ANY, Common::kPlatformPC, ADGF_UNSTABLE,
+ GUIO2(GUIO_NOMIDI, GUIO_NOASPECT)
},
kGroovieV2, 1
},
@@ -193,7 +197,8 @@ static const GroovieGameDescription gameDescriptions[] = {
{
"tlc", "",
AD_ENTRY1s("disk.1", "32a1afa68478f1f9d2b25eeea427f2e3", 84),
- Common::EN_ANY, Common::kPlatformPC, ADGF_UNSTABLE, GUIO1(GUIO_NOMIDI)
+ Common::EN_ANY, Common::kPlatformPC, ADGF_UNSTABLE,
+ GUIO2(GUIO_NOMIDI, GUIO_NOASPECT)
},
kGroovieV2, 1
},
@@ -216,7 +221,7 @@ public:
// to the detection entries. In the latter case, this TODO should be
// replaced with an according explanation.
_flags = kADFlagUseExtraAsHint;
- _guioptions = GUIO2(GUIO_NOSUBTITLES, GUIO_NOSFX);
+ _guioptions = GUIO3(GUIO_NOSUBTITLES, GUIO_NOSFX, GUIO_NOASPECT);
}
const char *getName() const {
diff --git a/engines/groovie/roq.cpp b/engines/groovie/roq.cpp
index ca896a8d21..53f335ce68 100644
--- a/engines/groovie/roq.cpp
+++ b/engines/groovie/roq.cpp
@@ -138,9 +138,7 @@ void ROQPlayer::buildShowBuf() {
}
// Swap buffers
- Graphics::Surface *tmp = _prevBuf;
- _prevBuf = _currBuf;
- _currBuf = tmp;
+ SWAP(_prevBuf, _currBuf);
}
bool ROQPlayer::playFrameInternal() {
diff --git a/engines/groovie/script.cpp b/engines/groovie/script.cpp
index 9003a58ab8..68415233f4 100644
--- a/engines/groovie/script.cpp
+++ b/engines/groovie/script.cpp
@@ -373,7 +373,7 @@ bool Script::hotspot(Common::Rect rect, uint16 address, uint8 cursor) {
DebugMan.isDebugChannelEnabled(kGroovieDebugAll)) {
rect.translate(0, -80);
_vm->_graphicsMan->_foreground.frameRect(rect, 250);
- _vm->_system->copyRectToScreen((byte*)_vm->_graphicsMan->_foreground.getBasePtr(0, 0), _vm->_graphicsMan->_foreground.pitch, 0, 80, 640, 320);
+ _vm->_system->copyRectToScreen((byte *)_vm->_graphicsMan->_foreground.getBasePtr(0, 0), _vm->_graphicsMan->_foreground.pitch, 0, 80, 640, 320);
_vm->_system->updateScreen();
}
@@ -590,9 +590,9 @@ bool Script::playvideofromref(uint32 fileref) {
if (_videoFile) {
_videoRef = fileref;
- // If teeth cursor, and in main script, mark video prefer low-speed
- // filename check as sometimes teeth used for puzzle movements (bishops)
- if (_version == kGroovieT7G && _lastCursor == 7 && _scriptFile == "script.grv")
+ // If teeth or mask cursor, and in main script, mark video prefer low-speed.
+ // Filename check as sometimes teeth used for puzzle movements (bishops)
+ if (_version == kGroovieT7G && (_lastCursor == 7 || _lastCursor == 4) && _scriptFile == "script.grv")
_bitflags |= (1 << 15);
_vm->_videoPlayer->load(_videoFile, _bitflags);
} else {
diff --git a/engines/hugo/detection.cpp b/engines/hugo/detection.cpp
index 43e688bba4..90708163f5 100644
--- a/engines/hugo/detection.cpp
+++ b/engines/hugo/detection.cpp
@@ -63,7 +63,7 @@ static const HugoGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformPC,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO0()
},
kGameTypeHugo1
},
@@ -75,7 +75,7 @@ static const HugoGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
GF_PACKED,
- GUIO1(GUIO_NONE)
+ GUIO0()
},
kGameTypeHugo1
},
@@ -87,7 +87,7 @@ static const HugoGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformPC,
GF_PACKED,
- GUIO1(GUIO_NONE)
+ GUIO0()
},
kGameTypeHugo2
},
@@ -99,7 +99,7 @@ static const HugoGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
GF_PACKED,
- GUIO1(GUIO_NONE)
+ GUIO0()
},
kGameTypeHugo2
},
@@ -111,7 +111,7 @@ static const HugoGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformPC,
GF_PACKED,
- GUIO1(GUIO_NONE)
+ GUIO0()
},
kGameTypeHugo3
},
@@ -123,7 +123,7 @@ static const HugoGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
GF_PACKED,
- GUIO1(GUIO_NONE)
+ GUIO0()
},
kGameTypeHugo3
},
diff --git a/engines/hugo/game.h b/engines/hugo/game.h
index 5db57789dc..b1c5f407b3 100644
--- a/engines/hugo/game.h
+++ b/engines/hugo/game.h
@@ -66,7 +66,7 @@ enum cycle_t {kCycleInvisible, kCycleAlmostInvisible, kCycleNotCycling, kCycleFo
/**
* Enumerate sequence index matching direction of travel
*/
-enum {RIGHT, LEFT, DOWN, _UP};
+enum {SEQ_RIGHT, SEQ_LEFT, SEQ_DOWN, SEQ_UP};
enum font_t {LARGE_ROMAN, MED_ROMAN, NUM_GDI_FONTS, INIT_FONTS, DEL_FONTS};
diff --git a/engines/hugo/object.h b/engines/hugo/object.h
index c0933729eb..84c20db041 100644
--- a/engines/hugo/object.h
+++ b/engines/hugo/object.h
@@ -117,7 +117,7 @@ protected:
void restoreSeq(object_t *obj);
inline bool checkBoundary(int16 x, int16 y);
- template <typename T>
+ template<typename T>
inline int sign(T a) { if ( a < 0) return -1; else return 1; }
};
diff --git a/engines/hugo/object_v1d.cpp b/engines/hugo/object_v1d.cpp
index ecdbb3b4c6..831dc88dea 100644
--- a/engines/hugo/object_v1d.cpp
+++ b/engines/hugo/object_v1d.cpp
@@ -205,15 +205,15 @@ void ObjectHandler_v1d::moveObjects() {
if (!obj->vx) { // Got 4 directions
if (obj->vx != obj->oldvx) {// vx just stopped
if (dy > 0)
- obj->currImagePtr = obj->seqList[DOWN].seqPtr;
+ obj->currImagePtr = obj->seqList[SEQ_DOWN].seqPtr;
else
- obj->currImagePtr = obj->seqList[_UP].seqPtr;
+ obj->currImagePtr = obj->seqList[SEQ_UP].seqPtr;
}
} else if (obj->vx != obj->oldvx) {
if (dx > 0)
- obj->currImagePtr = obj->seqList[RIGHT].seqPtr;
+ obj->currImagePtr = obj->seqList[SEQ_RIGHT].seqPtr;
else
- obj->currImagePtr = obj->seqList[LEFT].seqPtr;
+ obj->currImagePtr = obj->seqList[SEQ_LEFT].seqPtr;
}
}
@@ -239,15 +239,15 @@ void ObjectHandler_v1d::moveObjects() {
if (!obj->vx && (obj->seqNumb > 2)) {
if (obj->vx != obj->oldvx) { // vx just stopped
if (obj->vy > 0)
- obj->currImagePtr = obj->seqList[DOWN].seqPtr;
+ obj->currImagePtr = obj->seqList[SEQ_DOWN].seqPtr;
else
- obj->currImagePtr = obj->seqList[_UP].seqPtr;
+ obj->currImagePtr = obj->seqList[SEQ_UP].seqPtr;
}
} else if (obj->vx != obj->oldvx) {
if (obj->vx > 0)
- obj->currImagePtr = obj->seqList[RIGHT].seqPtr;
+ obj->currImagePtr = obj->seqList[SEQ_RIGHT].seqPtr;
else
- obj->currImagePtr = obj->seqList[LEFT].seqPtr;
+ obj->currImagePtr = obj->seqList[SEQ_LEFT].seqPtr;
}
if (obj->vx || obj->vy)
diff --git a/engines/hugo/object_v1w.cpp b/engines/hugo/object_v1w.cpp
index 11c09176e5..4388ef5520 100644
--- a/engines/hugo/object_v1w.cpp
+++ b/engines/hugo/object_v1w.cpp
@@ -208,24 +208,24 @@ void ObjectHandler_v1w::moveObjects() {
if (!obj->vx) { // Got 4 directions
if (obj->vx != obj->oldvx) { // vx just stopped
if (dy >= 0)
- obj->currImagePtr = obj->seqList[DOWN].seqPtr;
+ obj->currImagePtr = obj->seqList[SEQ_DOWN].seqPtr;
else
- obj->currImagePtr = obj->seqList[_UP].seqPtr;
+ obj->currImagePtr = obj->seqList[SEQ_UP].seqPtr;
}
} else if (obj->vx != obj->oldvx) {
if (dx > 0)
- obj->currImagePtr = obj->seqList[RIGHT].seqPtr;
+ obj->currImagePtr = obj->seqList[SEQ_RIGHT].seqPtr;
else
- obj->currImagePtr = obj->seqList[LEFT].seqPtr;
+ obj->currImagePtr = obj->seqList[SEQ_LEFT].seqPtr;
}
break;
case 3:
case 2:
if (obj->vx != obj->oldvx) { // vx just stopped
if (dx > 0) // Left & right only
- obj->currImagePtr = obj->seqList[RIGHT].seqPtr;
+ obj->currImagePtr = obj->seqList[SEQ_RIGHT].seqPtr;
else
- obj->currImagePtr = obj->seqList[LEFT].seqPtr;
+ obj->currImagePtr = obj->seqList[SEQ_LEFT].seqPtr;
}
break;
}
@@ -252,15 +252,15 @@ void ObjectHandler_v1w::moveObjects() {
if (!obj->vx && (obj->seqNumb >= 4)) {
if (obj->vx != obj->oldvx) { // vx just stopped
if (obj->vy > 0)
- obj->currImagePtr = obj->seqList[DOWN].seqPtr;
+ obj->currImagePtr = obj->seqList[SEQ_DOWN].seqPtr;
else
- obj->currImagePtr = obj->seqList[_UP].seqPtr;
+ obj->currImagePtr = obj->seqList[SEQ_UP].seqPtr;
}
} else if (obj->vx != obj->oldvx) {
if (obj->vx > 0)
- obj->currImagePtr = obj->seqList[RIGHT].seqPtr;
+ obj->currImagePtr = obj->seqList[SEQ_RIGHT].seqPtr;
else
- obj->currImagePtr = obj->seqList[LEFT].seqPtr;
+ obj->currImagePtr = obj->seqList[SEQ_LEFT].seqPtr;
}
}
obj->oldvx = obj->vx;
diff --git a/engines/hugo/object_v2d.cpp b/engines/hugo/object_v2d.cpp
index c9e5104972..4a22fab2c0 100644
--- a/engines/hugo/object_v2d.cpp
+++ b/engines/hugo/object_v2d.cpp
@@ -211,24 +211,24 @@ void ObjectHandler_v2d::moveObjects() {
if (!obj->vx) { // Got 4 directions
if (obj->vx != obj->oldvx) { // vx just stopped
if (dy > 0)
- obj->currImagePtr = obj->seqList[DOWN].seqPtr;
+ obj->currImagePtr = obj->seqList[SEQ_DOWN].seqPtr;
else
- obj->currImagePtr = obj->seqList[_UP].seqPtr;
+ obj->currImagePtr = obj->seqList[SEQ_UP].seqPtr;
}
} else if (obj->vx != obj->oldvx) {
if (dx > 0)
- obj->currImagePtr = obj->seqList[RIGHT].seqPtr;
+ obj->currImagePtr = obj->seqList[SEQ_RIGHT].seqPtr;
else
- obj->currImagePtr = obj->seqList[LEFT].seqPtr;
+ obj->currImagePtr = obj->seqList[SEQ_LEFT].seqPtr;
}
break;
case 3:
case 2:
if (obj->vx != obj->oldvx) { // vx just stopped
if (dx > 0) // Left & right only
- obj->currImagePtr = obj->seqList[RIGHT].seqPtr;
+ obj->currImagePtr = obj->seqList[SEQ_RIGHT].seqPtr;
else
- obj->currImagePtr = obj->seqList[LEFT].seqPtr;
+ obj->currImagePtr = obj->seqList[SEQ_LEFT].seqPtr;
}
break;
}
@@ -255,15 +255,15 @@ void ObjectHandler_v2d::moveObjects() {
if (!obj->vx && (obj->seqNumb >= 4)) {
if (obj->vx != obj->oldvx) { // vx just stopped
if (obj->vy > 0)
- obj->currImagePtr = obj->seqList[DOWN].seqPtr;
+ obj->currImagePtr = obj->seqList[SEQ_DOWN].seqPtr;
else
- obj->currImagePtr = obj->seqList[_UP].seqPtr;
+ obj->currImagePtr = obj->seqList[SEQ_UP].seqPtr;
}
} else if (obj->vx != obj->oldvx) {
if (obj->vx > 0)
- obj->currImagePtr = obj->seqList[RIGHT].seqPtr;
+ obj->currImagePtr = obj->seqList[SEQ_RIGHT].seqPtr;
else
- obj->currImagePtr = obj->seqList[LEFT].seqPtr;
+ obj->currImagePtr = obj->seqList[SEQ_LEFT].seqPtr;
}
}
obj->oldvx = obj->vx;
diff --git a/engines/hugo/object_v3d.cpp b/engines/hugo/object_v3d.cpp
index 07bd5e0c7f..cde7f5fd62 100644
--- a/engines/hugo/object_v3d.cpp
+++ b/engines/hugo/object_v3d.cpp
@@ -92,24 +92,24 @@ void ObjectHandler_v3d::moveObjects() {
if (!obj->vx) { // Got 4 directions
if (obj->vx != obj->oldvx) { // vx just stopped
if (dy >= 0)
- obj->currImagePtr = obj->seqList[DOWN].seqPtr;
+ obj->currImagePtr = obj->seqList[SEQ_DOWN].seqPtr;
else
- obj->currImagePtr = obj->seqList[_UP].seqPtr;
+ obj->currImagePtr = obj->seqList[SEQ_UP].seqPtr;
}
} else if (obj->vx != obj->oldvx) {
if (dx > 0)
- obj->currImagePtr = obj->seqList[RIGHT].seqPtr;
+ obj->currImagePtr = obj->seqList[SEQ_RIGHT].seqPtr;
else
- obj->currImagePtr = obj->seqList[LEFT].seqPtr;
+ obj->currImagePtr = obj->seqList[SEQ_LEFT].seqPtr;
}
break;
case 3:
case 2:
if (obj->vx != obj->oldvx) { // vx just stopped
if (dx > 0) // Left & right only
- obj->currImagePtr = obj->seqList[RIGHT].seqPtr;
+ obj->currImagePtr = obj->seqList[SEQ_RIGHT].seqPtr;
else
- obj->currImagePtr = obj->seqList[LEFT].seqPtr;
+ obj->currImagePtr = obj->seqList[SEQ_LEFT].seqPtr;
}
break;
}
@@ -136,15 +136,15 @@ void ObjectHandler_v3d::moveObjects() {
if (!obj->vx && (obj->seqNumb >= 4)) {
if (obj->vx != obj->oldvx) { // vx just stopped
if (obj->vy > 0)
- obj->currImagePtr = obj->seqList[DOWN].seqPtr;
+ obj->currImagePtr = obj->seqList[SEQ_DOWN].seqPtr;
else
- obj->currImagePtr = obj->seqList[_UP].seqPtr;
+ obj->currImagePtr = obj->seqList[SEQ_UP].seqPtr;
}
} else if (obj->vx != obj->oldvx) {
if (obj->vx > 0)
- obj->currImagePtr = obj->seqList[RIGHT].seqPtr;
+ obj->currImagePtr = obj->seqList[SEQ_RIGHT].seqPtr;
else
- obj->currImagePtr = obj->seqList[LEFT].seqPtr;
+ obj->currImagePtr = obj->seqList[SEQ_LEFT].seqPtr;
}
}
obj->oldvx = obj->vx;
diff --git a/engines/hugo/parser.cpp b/engines/hugo/parser.cpp
index bbf6c39f13..4eaed6fecf 100644
--- a/engines/hugo/parser.cpp
+++ b/engines/hugo/parser.cpp
@@ -271,7 +271,7 @@ void Parser::keyHandler(Common::Event event) {
status_t &gameStatus = _vm->getGameStatus();
uint16 nChar = event.kbd.keycode;
- if ((event.kbd.hasFlags(Common::KBD_ALT)) || (event.kbd.hasFlags(Common::KBD_SCRL)))
+ if (event.kbd.flags & (Common::KBD_ALT | Common::KBD_SCRL))
return;
if (event.kbd.hasFlags(Common::KBD_CTRL)) {
@@ -391,8 +391,6 @@ 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/route.cpp b/engines/hugo/route.cpp
index af8ec3427d..281aacf031 100644
--- a/engines/hugo/route.cpp
+++ b/engines/hugo/route.cpp
@@ -67,35 +67,35 @@ void Route::setDirection(const uint16 keyCode) {
switch (keyCode) {
case Common::KEYCODE_UP:
case Common::KEYCODE_KP8:
- obj->currImagePtr = obj->seqList[_UP].seqPtr;
+ obj->currImagePtr = obj->seqList[SEQ_UP].seqPtr;
break;
case Common::KEYCODE_DOWN:
case Common::KEYCODE_KP2:
- obj->currImagePtr = obj->seqList[DOWN].seqPtr;
+ obj->currImagePtr = obj->seqList[SEQ_DOWN].seqPtr;
break;
case Common::KEYCODE_LEFT:
case Common::KEYCODE_KP4:
- obj->currImagePtr = obj->seqList[LEFT].seqPtr;
+ obj->currImagePtr = obj->seqList[SEQ_LEFT].seqPtr;
break;
case Common::KEYCODE_RIGHT:
case Common::KEYCODE_KP6:
- obj->currImagePtr = obj->seqList[RIGHT].seqPtr;
+ obj->currImagePtr = obj->seqList[SEQ_RIGHT].seqPtr;
break;
case Common::KEYCODE_HOME:
case Common::KEYCODE_KP7:
- obj->currImagePtr = obj->seqList[LEFT].seqPtr;
+ obj->currImagePtr = obj->seqList[SEQ_LEFT].seqPtr;
break;
case Common::KEYCODE_END:
case Common::KEYCODE_KP1:
- obj->currImagePtr = obj->seqList[LEFT].seqPtr;
+ obj->currImagePtr = obj->seqList[SEQ_LEFT].seqPtr;
break;
case Common::KEYCODE_PAGEUP:
case Common::KEYCODE_KP9:
- obj->currImagePtr = obj->seqList[RIGHT].seqPtr;
+ obj->currImagePtr = obj->seqList[SEQ_RIGHT].seqPtr;
break;
case Common::KEYCODE_PAGEDOWN:
case Common::KEYCODE_KP3:
- obj->currImagePtr = obj->seqList[RIGHT].seqPtr;
+ obj->currImagePtr = obj->seqList[SEQ_RIGHT].seqPtr;
break;
}
}
@@ -231,48 +231,48 @@ void Route::segment(int16 x, int16 y) {
if (_vm->_hero->x < x1) {
// Hero x not in segment, search x1..x2
// Find all segments above current
- for (x = x1; !(_routeFoundFl | _fullStackFl | _fullSegmentFl) && x <= x2; x++) {
+ for (x = x1; !(_routeFoundFl || _fullStackFl || _fullSegmentFl) && x <= x2; x++) {
if (_boundaryMap[y - 1][x] == 0)
segment(x, y - 1);
}
// Find all segments below current
- for (x = x1; !(_routeFoundFl | _fullStackFl | _fullSegmentFl) && x <= x2; x++) {
+ for (x = x1; !(_routeFoundFl || _fullStackFl || _fullSegmentFl) && x <= x2; x++) {
if (_boundaryMap[y + 1][x] == 0)
segment(x, y + 1);
}
} else if (_vm->_hero->x + kHeroMaxWidth > x2) {
// Hero x not in segment, search x1..x2
// Find all segments above current
- for (x = x2; !(_routeFoundFl | _fullStackFl | _fullSegmentFl) && x >= x1; x--) {
+ for (x = x2; !(_routeFoundFl || _fullStackFl || _fullSegmentFl) && x >= x1; x--) {
if (_boundaryMap[y - 1][x] == 0)
segment(x, y - 1);
}
// Find all segments below current
- for (x = x2; !(_routeFoundFl | _fullStackFl | _fullSegmentFl) && x >= x1; x--) {
+ for (x = x2; !(_routeFoundFl || _fullStackFl || _fullSegmentFl) && x >= x1; x--) {
if (_boundaryMap[y + 1][x] == 0)
segment(x, y + 1);
}
} else {
// Organize search around hero x position - this gives
// better chance for more direct route.
- for (x = _vm->_hero->x; !(_routeFoundFl | _fullStackFl | _fullSegmentFl) && x <= x2; x++) {
+ for (x = _vm->_hero->x; !(_routeFoundFl || _fullStackFl || _fullSegmentFl) && x <= x2; x++) {
if (_boundaryMap[y - 1][x] == 0)
segment(x, y - 1);
}
- for (x = x1; !(_routeFoundFl | _fullStackFl | _fullSegmentFl) && x < _vm->_hero->x; x++) {
+ for (x = x1; !(_routeFoundFl || _fullStackFl || _fullSegmentFl) && x < _vm->_hero->x; x++) {
if (_boundaryMap[y - 1][x] == 0)
segment(x, y - 1);
}
- for (x = _vm->_hero->x; !(_routeFoundFl | _fullStackFl | _fullSegmentFl) && x <= x2; x++) {
+ for (x = _vm->_hero->x; !(_routeFoundFl || _fullStackFl || _fullSegmentFl) && x <= x2; x++) {
if (_boundaryMap[y + 1][x] == 0)
segment(x, y + 1);
}
- for (x = x1; !(_routeFoundFl | _fullStackFl | _fullSegmentFl) && x < _vm->_hero->x; x++) {
+ for (x = x1; !(_routeFoundFl || _fullStackFl || _fullSegmentFl) && x < _vm->_hero->x; x++) {
if (_boundaryMap[y + 1][x] == 0)
segment(x, y + 1);
}
diff --git a/engines/hugo/schedule.cpp b/engines/hugo/schedule.cpp
index 384b3ace8f..896e8fa2ce 100644
--- a/engines/hugo/schedule.cpp
+++ b/engines/hugo/schedule.cpp
@@ -1104,7 +1104,7 @@ void Scheduler::restoreEvents(Common::ReadStream *f) {
if ((index == -1) && (subElem == -1))
_events[i].action = 0;
else
- _events[i].action = (act*)&_actListArr[index][subElem];
+ _events[i].action = (act *)&_actListArr[index][subElem];
_events[i].localActionFl = (f->readByte() == 1) ? true : false;
_events[i].time = f->readUint32BE();
@@ -1539,7 +1539,7 @@ void Scheduler_v1d::promptAction(act *action) {
response.toLowercase();
char resp[256];
- strncpy(resp, response.c_str(), 256);
+ Common::strlcpy(resp, response.c_str(), 256);
if (action->a3.encodedFl)
decodeString(resp);
@@ -1585,12 +1585,9 @@ void Scheduler_v2d::promptAction(act *action) {
bool found = false;
const char *tmpStr; // General purpose string ptr
- char resp[256];
- strncpy(resp, response.c_str(), 256);
-
for (int dx = 0; !found && (action->a3.responsePtr[dx] != -1); dx++) {
tmpStr = _vm->_file->fetchString(action->a3.responsePtr[dx]);
- if (strstr(Utils::strlwr(resp), tmpStr))
+ if (response.contains(tmpStr))
found = true;
}
diff --git a/engines/hugo/sound.cpp b/engines/hugo/sound.cpp
index 9dcd7d346a..d0b4e3dfe8 100644
--- a/engines/hugo/sound.cpp
+++ b/engines/hugo/sound.cpp
@@ -256,7 +256,7 @@ void SoundHandler::checkMusic() {
}
void SoundHandler::loopPlayer(void *refCon) {
- ((SoundHandler*)refCon)->pcspkr_player();
+ ((SoundHandler *)refCon)->pcspkr_player();
}
/**
diff --git a/engines/hugo/sound.h b/engines/hugo/sound.h
index 1e504fbdea..cb6d4e3168 100644
--- a/engines/hugo/sound.h
+++ b/engines/hugo/sound.h
@@ -43,6 +43,12 @@ public:
void pause(bool p);
void play(uint8 *stream, uint16 size);
+ // The following line prevents compiler warnings about hiding the pause()
+ // method from the parent class.
+ // FIXME: Maybe the pause(bool p) method should be removed and the
+ // pause/resume methods of the parent class be used instead?
+ virtual void pause() { Audio::MidiPlayer::pause(); }
+
uint32 getBaseTempo();
// Overload Audio::MidiPlayer method
diff --git a/engines/hugo/util.cpp b/engines/hugo/util.cpp
index 6dc9890c3a..fdc676e6a7 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(static_cast<unsigned char>(*buffer)))
+ if (Common::isUpper(*buffer))
*buffer = tolower(*buffer);
buffer++;
}
diff --git a/engines/kyra/animator_hof.cpp b/engines/kyra/animator_hof.cpp
index 741e358143..5a2378f4d0 100644
--- a/engines/kyra/animator_hof.cpp
+++ b/engines/kyra/animator_hof.cpp
@@ -115,15 +115,14 @@ void KyraEngine_HoF::refreshAnimObjects(int force) {
void KyraEngine_HoF::updateItemAnimations() {
bool nextFrame = false;
- if (_itemAnimData[0].itemIndex == -1 || _inventorySaved)
+ if (_itemAnimDefinition[0].itemIndex == -1 || _inventorySaved)
return;
- const ItemAnimData_v2 *s = &_itemAnimData[_nextAnimItem];
+ const ItemAnimDefinition *s = &_itemAnimDefinition[_nextAnimItem];
ActiveItemAnim *a = &_activeItemAnim[_nextAnimItem];
- _nextAnimItem = (_nextAnimItem + 1) % _itemAnimDataSize;
+ _nextAnimItem = (_nextAnimItem + 1) % _itemAnimDefinitionSize;
- uint32 ctime = _system->getMillis();
- if (ctime < a->nextFrame)
+ if (_system->getMillis() < a->nextFrameTime)
return;
uint16 shpIdx = s->frames[a->currentFrame].index + 64;
@@ -164,7 +163,7 @@ void KyraEngine_HoF::updateItemAnimations() {
}
if (nextFrame) {
- a->nextFrame = _system->getMillis() + (s->frames[a->currentFrame].delay * _tickLength);
+ a->nextFrameTime = _system->getMillis() + (s->frames[a->currentFrame].delay * _tickLength);
a->currentFrame = (a->currentFrame + 1) % s->numFrames;
}
}
diff --git a/engines/kyra/animator_lok.cpp b/engines/kyra/animator_lok.cpp
index 4126681bbe..c246eebd46 100644
--- a/engines/kyra/animator_lok.cpp
+++ b/engines/kyra/animator_lok.cpp
@@ -100,7 +100,7 @@ void Animator_LoK::initAnimStateList() {
for (int i = 16; i < 28; ++i) {
animStates[i].index = i;
animStates[i].flags = 0;
- animStates[i].background = _vm->_shapes[345+i];
+ animStates[i].background = _vm->_shapes[345 + i];
animStates[i].rectSize = _screen->getRectSize(3, 24);
animStates[i].width = 3;
animStates[i].height = 16;
@@ -352,10 +352,10 @@ void Animator_LoK::copyChangedObjectsForward(int refreshFlag) {
if (curObject->active) {
if (curObject->refreshFlag || refreshFlag) {
int xpos = 0, ypos = 0, width = 0, height = 0;
- xpos = (curObject->x1>>3) - (curObject->width2>>3) - 1;
+ xpos = (curObject->x1 >> 3) - (curObject->width2 >> 3) - 1;
ypos = curObject->y1 - curObject->height2;
- width = curObject->width + (curObject->width2>>3) + 2;
- height = curObject->height + curObject->height2*2;
+ width = curObject->width + (curObject->width2 >> 3) + 2;
+ height = curObject->height + curObject->height2 * 2;
if (xpos < 1)
xpos = 1;
@@ -412,7 +412,7 @@ void Animator_LoK::animAddGameItem(int index, uint16 sceneId) {
animObj->refreshFlag = 1;
animObj->bkgdChangeFlag = 1;
animObj->drawY = currentRoom->itemsYPos[index];
- animObj->sceneAnimPtr = _vm->_shapes[216+currentRoom->itemsTable[index]];
+ animObj->sceneAnimPtr = _vm->_shapes[216 + currentRoom->itemsTable[index]];
animObj->animFrameNumber = -1;
animObj->x1 = currentRoom->itemsXPos[index];
animObj->y1 = currentRoom->itemsYPos[index];
@@ -438,8 +438,8 @@ void Animator_LoK::animAddNPC(int character) {
animObj->bkgdChangeFlag = 1;
animObj->drawY = ch->y1;
animObj->sceneAnimPtr = _vm->_shapes[ch->currentAnimFrame];
- animObj->x1 = animObj->x2 = ch->x1 + _vm->_defaultShapeTable[ch->currentAnimFrame-7].xOffset;
- animObj->y1 = animObj->y2 = ch->y1 + _vm->_defaultShapeTable[ch->currentAnimFrame-7].yOffset;
+ animObj->x1 = animObj->x2 = ch->x1 + _vm->_defaultShapeTable[ch->currentAnimFrame - 7].xOffset;
+ animObj->y1 = animObj->y2 = ch->y1 + _vm->_defaultShapeTable[ch->currentAnimFrame - 7].yOffset;
if (ch->facing >= 1 && ch->facing <= 3)
animObj->flags |= 1;
@@ -543,13 +543,13 @@ void Animator_LoK::makeBrandonFaceMouse() {
int16 Animator_LoK::fetchAnimWidth(const uint8 *shape, int16 mult) {
if (_vm->gameFlags().useAltShapeHeader)
shape += 2;
- return (((int16)READ_LE_UINT16((shape+3))) * mult) >> 8;
+ return (((int16)READ_LE_UINT16((shape + 3))) * mult) >> 8;
}
int16 Animator_LoK::fetchAnimHeight(const uint8 *shape, int16 mult) {
if (_vm->gameFlags().useAltShapeHeader)
shape += 2;
- return (int16)(((int8)*(shape+2)) * mult) >> 8;
+ return (int16)(((int8)*(shape + 2)) * mult) >> 8;
}
void Animator_LoK::setBrandonAnimSeqSize(int width, int height) {
@@ -603,8 +603,8 @@ void Animator_LoK::animRefreshNPC(int character) {
}
}
- int xOffset = _vm->_defaultShapeTable[ch->currentAnimFrame-7].xOffset;
- int yOffset = _vm->_defaultShapeTable[ch->currentAnimFrame-7].yOffset;
+ int xOffset = _vm->_defaultShapeTable[ch->currentAnimFrame - 7].xOffset;
+ int yOffset = _vm->_defaultShapeTable[ch->currentAnimFrame - 7].yOffset;
if (_vm->_scaleMode) {
animObj->x1 = ch->x1;
diff --git a/engines/kyra/animator_mr.cpp b/engines/kyra/animator_mr.cpp
index 31c5cd1a53..29fa3aba80 100644
--- a/engines/kyra/animator_mr.cpp
+++ b/engines/kyra/animator_mr.cpp
@@ -187,15 +187,14 @@ void KyraEngine_MR::refreshAnimObjects(int force) {
void KyraEngine_MR::updateItemAnimations() {
bool nextFrame = false;
- if (_itemAnimData[0].itemIndex == -1)
+ if (_itemAnimDefinition[0].itemIndex == -1)
return;
- const ItemAnimData_v2 *s = &_itemAnimData[_nextAnimItem];
+ const ItemAnimDefinition *s = &_itemAnimDefinition[_nextAnimItem];
ActiveItemAnim *a = &_activeItemAnim[_nextAnimItem];
_nextAnimItem = (_nextAnimItem + 1) % 10;
- uint32 ctime = _system->getMillis();
- if (ctime < a->nextFrame)
+ if (_system->getMillis() < a->nextFrameTime)
return;
uint16 shpIdx = s->frames[a->currentFrame].index + 248;
@@ -230,7 +229,7 @@ void KyraEngine_MR::updateItemAnimations() {
}
if (nextFrame) {
- a->nextFrame = _system->getMillis() + (s->frames[a->currentFrame].delay * _tickLength);
+ a->nextFrameTime = _system->getMillis() + (s->frames[a->currentFrame].delay * _tickLength);
a->currentFrame = (a->currentFrame + 1) % s->numFrames;
}
}
diff --git a/engines/kyra/animator_v2.cpp b/engines/kyra/animator_v2.cpp
index 334356e261..f7ae6749cf 100644
--- a/engines/kyra/animator_v2.cpp
+++ b/engines/kyra/animator_v2.cpp
@@ -26,10 +26,10 @@
namespace Kyra {
void KyraEngine_v2::allocAnimObjects(int actors, int anims, int items) {
- _animObjects = new AnimObj[actors+anims+items];
+ _animObjects = new AnimObj[actors + anims + items];
assert(_animObjects);
- memset(_animObjects, 0, sizeof(AnimObj)*(actors+anims+items));
+ memset(_animObjects, 0, sizeof(AnimObj) * (actors + anims + items));
_animActor = _animObjects;
_animAnims = _animObjects + actors;
diff --git a/engines/kyra/chargen.cpp b/engines/kyra/chargen.cpp
new file mode 100644
index 0000000000..54e1abcc2c
--- /dev/null
+++ b/engines/kyra/chargen.cpp
@@ -0,0 +1,1951 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifdef ENABLE_EOB
+
+#include "kyra/eobcommon.h"
+#include "kyra/resource.h"
+#include "kyra/sound_intern.h"
+
+#include "common/savefile.h"
+#include "common/str-array.h"
+
+#include "common/config-manager.h"
+#include "base/plugins.h"
+#include "engines/metaengine.h"
+#include "engines/game.h"
+
+namespace Kyra {
+
+// Character Generator
+
+class CharacterGenerator {
+public:
+ CharacterGenerator(EoBCoreEngine *vm, Screen_EoB *screen);
+ ~CharacterGenerator();
+
+ bool start(EoBCharacter *characters, uint8 ***faceShapes);
+
+private:
+ void init();
+ void initButtonsFromList(int first, int numButtons);
+ void initButton(int index, int x, int y, int w, int h, int keyCode);
+ void checkForCompleteParty();
+ void toggleSpecialButton(int index, int bodyCustom, int pageNum);
+ void processSpecialButton(int index);
+ int viewDeleteCharacter();
+ void createPartyMember();
+ int raceSexMenu();
+ int classMenu(int raceSex);
+ int alignmentMenu(int cClass);
+ int getInput(Button *buttonList);
+ void updateMagicShapes();
+ void generateStats(int index);
+ void modifyMenu();
+ void statsAndFacesMenu();
+ void faceSelectMenu();
+ int getNextFreeFaceShape(int shpIndex, int charSex, int step, int8 *selectedPortraits);
+ void processFaceMenuSelection(int index);
+ void printStats(int index, int mode);
+ void processNameInput(int index, int len, int textColor);
+ int rollDice();
+ int modifyStat(int index, int8 *stat1, int8 *stat2);
+ int getMaxHp(int cclass, int constitution, int level1, int level2, int level3);
+ int getMinHp(int cclass, int constitution, int level1, int level2, int level3);
+ void finish();
+
+ uint8 **_chargenMagicShapes;
+ uint8 *_chargenButtonLabels[17];
+ int _activeBox;
+ int _magicShapesBox;
+ int _updateBoxShapesIndex;
+ int _lastUpdateBoxShapesIndex;
+ uint32 _chargenMagicShapeTimer;
+ int8 _chargenSelectedPortraits[4];
+ int8 _chargenSelectedPortraits2[4];
+
+ uint16 _chargenMinStats[7];
+ uint16 _chargenMaxStats[7];
+
+ const char *const *_chargenStrings1;
+ const char *const *_chargenStrings2;
+ const char *const *_chargenStatStrings;
+ const char *const *_chargenRaceSexStrings;
+ const char *const *_chargenClassStrings;
+ const char *const *_chargenAlignmentStrings;
+ const char *const *_chargenEnterGameStrings;
+
+ const uint8 *_chargenStartLevels;
+ const uint8 *_chargenClassMinStats;
+ const uint8 *_chargenRaceMinStats;
+ const uint16 *_chargenRaceMaxStats;
+
+ static const EoBChargenButtonDef _chargenButtonDefs[];
+ static const CreatePartyModButton _chargenModButtons[];
+ static const EoBRect8 _chargenButtonBodyCoords[];
+ static const int16 _chargenBoxX[];
+ static const int16 _chargenBoxY[];
+ static const int16 _chargenNameFieldX[];
+ static const int16 _chargenNameFieldY[];
+
+ static const int32 _classMenuMasks[];
+ static const int32 _alignmentMenuMasks[];
+
+ static const int16 _raceModifiers[];
+
+ EoBCharacter *_characters;
+ uint8 **_faceShapes;
+
+ EoBCoreEngine *_vm;
+ Screen_EoB *_screen;
+};
+
+CharacterGenerator::CharacterGenerator(EoBCoreEngine *vm, Screen_EoB *screen) : _vm(vm), _screen(screen),
+ _characters(0), _faceShapes(0), _chargenMagicShapes(0), _chargenMagicShapeTimer(0),
+ _updateBoxShapesIndex(0), _lastUpdateBoxShapesIndex(0), _magicShapesBox(6), _activeBox(0) {
+
+ _chargenStatStrings = _vm->_chargenStatStrings;
+ _chargenRaceSexStrings = _vm->_chargenRaceSexStrings;
+ _chargenClassStrings = _vm->_chargenClassStrings;
+ _chargenAlignmentStrings = _vm->_chargenAlignmentStrings;
+
+ memset(_chargenSelectedPortraits, -1, sizeof(_chargenSelectedPortraits));
+ memset(_chargenSelectedPortraits2, 0, sizeof(_chargenSelectedPortraits2));
+ memset(_chargenMinStats, 0, sizeof(_chargenMinStats));
+ memset(_chargenMaxStats, 0, sizeof(_chargenMaxStats));
+
+ int temp;
+ _chargenStrings1 = _vm->staticres()->loadStrings(kEoBBaseChargenStrings1, temp);
+ _chargenStrings2 = _vm->staticres()->loadStrings(kEoBBaseChargenStrings2, temp);
+ _chargenStartLevels = _vm->staticres()->loadRawData(kEoBBaseChargenStartLevels, temp);
+ _chargenEnterGameStrings = _vm->staticres()->loadStrings(kEoBBaseChargenEnterGameStrings, temp);
+ _chargenClassMinStats = _vm->staticres()->loadRawData(kEoBBaseChargenClassMinStats, temp);
+ _chargenRaceMinStats = _vm->staticres()->loadRawData(kEoBBaseChargenRaceMinStats, temp);
+ _chargenRaceMaxStats = _vm->staticres()->loadRawDataBe16(kEoBBaseChargenRaceMaxStats, temp);
+}
+
+CharacterGenerator::~CharacterGenerator() {
+ if (_chargenMagicShapes) {
+ for (int i = 0; i < 10; i++)
+ delete[] _chargenMagicShapes[i];
+ delete[] _chargenMagicShapes;
+ }
+
+ for (int i = 0; i < 17; i++)
+ delete[] _chargenButtonLabels[i];
+}
+
+bool CharacterGenerator::start(EoBCharacter *characters, uint8 ***faceShapes) {
+ if (!characters && !faceShapes)
+ return true;
+
+ _characters = characters;
+ _faceShapes = *faceShapes;
+
+ _vm->snd_stopSound();
+ _vm->delay(_vm->_tickLength);
+
+ init();
+
+ _screen->setScreenDim(2);
+
+ checkForCompleteParty();
+ initButtonsFromList(0, 5);
+
+ _vm->snd_playSong(_vm->game() == GI_EOB1 ? 20 : 13);
+ _activeBox = 0;
+
+ for (bool loop = true; loop && (!_vm->shouldQuit());) {
+ _vm->_gui->updateBoxFrameHighLight(_activeBox + 6);
+ int inputFlag = getInput(_vm->_activeButtons);
+ _vm->removeInputTop();
+
+ if (inputFlag) {
+ if (inputFlag == _vm->_keyMap[Common::KEYCODE_LEFT] || inputFlag == _vm->_keyMap[Common::KEYCODE_RIGHT]) {
+ _activeBox ^= 1;
+ } else if (inputFlag == _vm->_keyMap[Common::KEYCODE_UP] || inputFlag == _vm->_keyMap[Common::KEYCODE_DOWN]) {
+ _activeBox ^= 2;
+ } else if (inputFlag == _vm->_keyMap[Common::KEYCODE_ESCAPE]) {
+ // Unlike the original we allow returning to the main menu
+ _vm->snd_stopSound();
+ return false;
+ }
+ _vm->_gui->updateBoxFrameHighLight(-1);
+ }
+
+ if (inputFlag & 0x8000) {
+ inputFlag = (inputFlag & 0x0f) - 1;
+ if (inputFlag == 4) {
+ loop = false;
+ } else {
+ _activeBox = inputFlag;
+ inputFlag = _vm->_keyMap[Common::KEYCODE_RETURN];
+ }
+ }
+
+ if (inputFlag == _vm->_keyMap[Common::KEYCODE_RETURN] || inputFlag == _vm->_keyMap[Common::KEYCODE_SPACE] || inputFlag == _vm->_keyMap[Common::KEYCODE_KP5]) {
+ _vm->_gui->updateBoxFrameHighLight(-1);
+ if (_characters[_activeBox].name[0]) {
+ int b = _activeBox;
+ if (viewDeleteCharacter())
+ loop = false;
+ if (b != _activeBox && !_characters[_activeBox].name[0])
+ createPartyMember();
+ } else {
+ createPartyMember();
+ }
+
+ initButtonsFromList(0, 5);
+ checkForCompleteParty();
+ }
+
+ if (loop == false) {
+ for (int i = 0; i < 4; i++) {
+ if (!_characters[i].name[0])
+ loop = true;
+ }
+ }
+ }
+
+ if (!_vm->shouldQuit()) {
+ processSpecialButton(15);
+ finish();
+ }
+
+ if (_vm->game() == GI_EOB2)
+ _vm->snd_fadeOut();
+
+ *faceShapes = _faceShapes;
+ return true;
+}
+
+void CharacterGenerator::init() {
+ _screen->loadShapeSetBitmap("CHARGENA", 3, 3);
+ if (_faceShapes) {
+ for (int i = 0; i < 44; i++)
+ delete[] _faceShapes[i];
+ delete[] _faceShapes;
+ }
+
+ _faceShapes = new uint8*[44];
+ for (int i = 0; i < 44; i++)
+ _faceShapes[i] = _screen->encodeShape((i % 10) << 2, (i / 10) << 5, 4, 32, true, _vm->_cgaMappingDefault);
+ _screen->_curPage = 0;
+
+ _screen->loadEoBBitmap("CHARGEN", _vm->_cgaMappingDefault, 3, 3, 0);
+ _screen->loadShapeSetBitmap("CHARGENB", 3, 3);
+ if (_chargenMagicShapes) {
+ for (int i = 0; i < 10; i++)
+ delete[] _chargenMagicShapes[i];
+ delete[] _chargenMagicShapes;
+ }
+
+ _chargenMagicShapes = new uint8*[10];
+ for (int i = 0; i < 10; i++)
+ _chargenMagicShapes[i] = _screen->encodeShape(i << 2, 0, 4, 32, true, _vm->_cgaMappingDefault);
+
+ for (int i = 0; i < 17; i++) {
+ const CreatePartyModButton *c = &_chargenModButtons[i];
+ _chargenButtonLabels[i] = c->labelW ? _screen->encodeShape(c->encodeLabelX, c->encodeLabelY, c->labelW, c->labelH, true, _vm->_cgaMappingDefault) : 0;
+ }
+
+ _screen->convertPage(3, 2, _vm->_cgaMappingDefault);
+ _screen->_curPage = 0;
+ _screen->copyRegion(144, 64, 0, 0, 180, 128, 0, 2, Screen::CR_NO_P_CHECK);
+ _screen->updateScreen();
+}
+
+void CharacterGenerator::initButtonsFromList(int first, int numButtons) {
+ _vm->gui_resetButtonList();
+
+ for (int i = 0; i < numButtons; i++) {
+ const EoBChargenButtonDef *e = &_chargenButtonDefs[first + i];
+ initButton(i, e->x, e->y, e->w, e->h, e->keyCode);
+ }
+
+ _vm->gui_notifyButtonListChanged();
+}
+
+void CharacterGenerator::initButton(int index, int x, int y, int w, int h, int keyCode) {
+ Button *b = 0;
+ int cnt = 1;
+
+ if (_vm->_activeButtons) {
+ Button *n = _vm->_activeButtons;
+ while (n->nextButton) {
+ ++cnt;
+ n = n->nextButton;
+ }
+
+ ++cnt;
+ b = n->nextButton = &_vm->_activeButtonData[cnt];
+ } else {
+ b = &_vm->_activeButtonData[0];
+ _vm->_activeButtons = b;
+ }
+
+ *b = Button();
+ b->flags = 0x1100;
+ b->data0Val2 = 12;
+ b->data1Val2 = b->data2Val2 = 15;
+ b->data3Val2 = 8;
+
+ b->index = index + 1;
+ b->x = x << 3;
+ b->y = y;
+ b->width = w;
+ b->height = h;
+ b->keyCode = keyCode;
+ b->keyCode2 = keyCode | 0x100;
+}
+
+void CharacterGenerator::checkForCompleteParty() {
+ _screen->copyRegion(0, 0, 160, 0, 160, 128, 2, 2, Screen::CR_NO_P_CHECK);
+ int cp = _screen->setCurPage(2);
+ _screen->printShadedText(_chargenStrings1[8], 168, 16, 15, 0);
+ _screen->setCurPage(cp);
+ _screen->copyRegion(160, 0, 144, 64, 160, 128, 2, 0, Screen::CR_NO_P_CHECK);
+
+ int numChars = 0;
+ for (int i = 0; i < 4; i++) {
+ if (_characters[i].name[0])
+ numChars++;
+ }
+
+ if (numChars == 4) {
+ _screen->setCurPage(2);
+ _screen->printShadedText(_chargenStrings1[0], 168, 61, 15, 0);
+ _screen->setCurPage(0);
+ _screen->copyRegion(168, 61, 152, 125, 136, 40, 2, 0, Screen::CR_NO_P_CHECK);
+ toggleSpecialButton(15, 0, 0);
+ } else {
+ toggleSpecialButton(14, 0, 0);
+ }
+
+ _screen->updateScreen();
+}
+
+void CharacterGenerator::toggleSpecialButton(int index, int bodyCustom, int pageNum) {
+ if (index >= 17)
+ return;
+
+ const CreatePartyModButton *c = &_chargenModButtons[index];
+ const EoBRect8 *p = &_chargenButtonBodyCoords[c->bodyIndex + bodyCustom];
+
+ int x2 = 20;
+ int y2 = 0;
+
+ if (pageNum) {
+ x2 = c->destX + 2;
+ y2 = c->destY - 64;
+ }
+
+ _screen->copyRegion(p->x << 3, p->y, x2 << 3, y2, p->w << 3, p->h, 2, 2, Screen::CR_NO_P_CHECK);
+ if (c->labelW)
+ _screen->drawShape(2, _chargenButtonLabels[index], (x2 << 3) + c->labelX, y2 + c->labelY, 0);
+
+ if (pageNum == 2)
+ return;
+
+ _screen->copyRegion(160, 0, c->destX << 3, c->destY, p->w << 3, p->h, 2, 0, Screen::CR_NO_P_CHECK);
+ _screen->updateScreen();
+}
+
+void CharacterGenerator::processSpecialButton(int index) {
+ toggleSpecialButton(index, 1, 0);
+ _vm->snd_playSoundEffect(76);
+ _vm->_system->delayMillis(80);
+ toggleSpecialButton(index, 0, 0);
+}
+
+int CharacterGenerator::viewDeleteCharacter() {
+ initButtonsFromList(0, 7);
+ _vm->removeInputTop();
+
+ _vm->_gui->updateBoxFrameHighLight(-1);
+ printStats(_activeBox, 2);
+
+ int res = 0;
+ for (bool loop = true; loop && _characters[_activeBox].name[0] && !_vm->shouldQuit();) {
+ _vm->_gui->updateBoxFrameHighLight(_activeBox + 6);
+ int inputFlag = getInput(_vm->_activeButtons);
+ int cbx = _activeBox;
+ _vm->removeInputTop();
+
+ if (inputFlag == _vm->_keyMap[Common::KEYCODE_RETURN] || inputFlag == _vm->_keyMap[Common::KEYCODE_SPACE] || inputFlag == _vm->_keyMap[Common::KEYCODE_KP5] || inputFlag == _vm->_keyMap[Common::KEYCODE_ESCAPE]) {
+ processSpecialButton(9);
+ res = 0;
+ loop = false;
+ } else if (inputFlag == _vm->_keyMap[Common::KEYCODE_LEFT] || inputFlag == _vm->_keyMap[Common::KEYCODE_RIGHT]) {
+ cbx ^= 1;
+ } else if (inputFlag == _vm->_keyMap[Common::KEYCODE_UP] || inputFlag == _vm->_keyMap[Common::KEYCODE_DOWN]) {
+ cbx ^= 2;
+ }
+
+ if (inputFlag & 0x8000) {
+ inputFlag = (inputFlag & 0x0f) - 1;
+ if (inputFlag == 4) {
+ res = 1;
+ loop = false;
+ } else if (inputFlag == 5) {
+ processSpecialButton(9);
+ res = 0;
+ loop = false;
+ } else if (inputFlag == 6) {
+ if (_characters[_activeBox].name[0]) {
+ processSpecialButton(16);
+ _characters[_activeBox].name[0] = 0;
+ processNameInput(_activeBox, 1, 12);
+ processFaceMenuSelection(_activeBox + 50);
+ }
+ } else {
+ cbx = inputFlag;
+ }
+ }
+
+ if (loop == false)
+ _vm->_gui->updateBoxFrameHighLight(-1);
+
+ if (!_characters[cbx].name[0])
+ loop = false;
+
+ if (cbx != _activeBox) {
+ _activeBox = cbx;
+ _vm->_gui->updateBoxFrameHighLight(-1);
+ if (loop)
+ printStats(_activeBox, 2);
+ }
+ }
+
+ return res;
+}
+
+void CharacterGenerator::createPartyMember() {
+ _screen->setScreenDim(2);
+ assert(_vm->_gui);
+
+ for (int i = 0; i != 3 && !_vm->shouldQuit(); i++) {
+ bool bck = false;
+
+ switch (i) {
+ case 0:
+ _characters[_activeBox].raceSex = raceSexMenu();
+ break;
+ case 1:
+ _characters[_activeBox].cClass = classMenu(_characters[_activeBox].raceSex);
+ if (_characters[_activeBox].cClass == _vm->_keyMap[Common::KEYCODE_ESCAPE])
+ bck = true;
+ break;
+ case 2:
+ _characters[_activeBox].alignment = alignmentMenu(_characters[_activeBox].cClass);
+ if (_characters[_activeBox].alignment == _vm->_keyMap[Common::KEYCODE_ESCAPE])
+ bck = true;
+ break;
+ default:
+ break;
+ }
+
+ if (bck)
+ i -= 2;
+ };
+
+ if (!_vm->shouldQuit()) {
+ generateStats(_activeBox);
+ statsAndFacesMenu();
+
+ for (_characters[_activeBox].name[0] = 0; _characters[_activeBox].name[0] == 0 && !_vm->shouldQuit();) {
+ processFaceMenuSelection(_chargenMinStats[6]);
+ printStats(_activeBox, 0);
+ _screen->printShadedText(_chargenStrings2[11], 149, 100, 9, 0);
+ if (!_vm->shouldQuit())
+ processNameInput(_activeBox, _vm->_gui->getTextInput(_characters[_activeBox].name, 24, 100, 10, 15, 0, 8), 2);
+ }
+ }
+}
+
+int CharacterGenerator::raceSexMenu() {
+ _screen->drawBox(_chargenBoxX[_activeBox], _chargenBoxY[_activeBox], _chargenBoxX[_activeBox] + 32, _chargenBoxY[_activeBox] + 33, 12);
+ _screen->copyRegion(0, 0, 144, 64, 160, 128, 2, 0, Screen::CR_NO_P_CHECK);
+ _screen->printShadedText(_chargenStrings2[8], 147, 67, 9, 0);
+ _vm->removeInputTop();
+
+ _vm->_gui->simpleMenu_setup(1, 0, _chargenRaceSexStrings, -1, 0, 0);
+ int16 res = -1;
+
+ while (res == -1 && !_vm->shouldQuit()) {
+ res = _vm->_gui->simpleMenu_process(1, _chargenRaceSexStrings, 0, -1, 0);
+ updateMagicShapes();
+ }
+
+ return res;
+}
+
+int CharacterGenerator::classMenu(int raceSex) {
+ int32 itemsMask = -1;
+
+ for (int i = 0; i < 4; i++) {
+ // check for evil characters
+ if (_characters[i].name[0] && _characters[i].alignment > 5)
+ itemsMask = 0xFFFB;
+ }
+
+ _vm->removeInputTop();
+ updateMagicShapes();
+
+ _screen->copyRegion(0, 0, 144, 64, 160, 128, 2, 0, Screen::CR_NO_P_CHECK);
+ _screen->printShadedText(_chargenStrings2[9], 147, 67, 9, 0);
+
+ toggleSpecialButton(5, 0, 0);
+
+ itemsMask &= _classMenuMasks[raceSex / 2];
+ _vm->_gui->simpleMenu_setup(2, 15, _chargenClassStrings, itemsMask, 0, 0);
+
+ _vm->_mouseX = _vm->_mouseY = 0;
+ int16 res = -1;
+
+ while (res == -1 && !_vm->shouldQuit()) {
+ updateMagicShapes();
+ int in = getInput(0) & 0xff;
+ Common::Point mp = _vm->getMousePos();
+
+ if (in == _vm->_keyMap[Common::KEYCODE_ESCAPE] || _vm->_gui->_menuLastInFlags == _vm->_keyMap[Common::KEYCODE_ESCAPE] || _vm->_gui->_menuLastInFlags == _vm->_keyMap[Common::KEYCODE_b]) {
+ res = _vm->_keyMap[Common::KEYCODE_ESCAPE];
+ } else if (_vm->posWithinRect(mp.x, mp.y, 264, 171, 303, 187)) {
+ if (in == 199 || in == 201)
+ res = _vm->_keyMap[Common::KEYCODE_ESCAPE];
+ else
+ _vm->removeInputTop();
+ } else {
+ res = _vm->_gui->simpleMenu_process(2, _chargenClassStrings, 0, itemsMask, 0);
+ }
+ }
+
+ _vm->removeInputTop();
+
+ if (res == _vm->_keyMap[Common::KEYCODE_ESCAPE])
+ processSpecialButton(5);
+
+ return res;
+}
+
+int CharacterGenerator::alignmentMenu(int cClass) {
+ int32 itemsMask = -1;
+
+ for (int i = 0; i < 4; i++) {
+ // check for paladins
+ if (_characters[i].name[0] && _characters[i].cClass == 2)
+ itemsMask = 0xFE3F;
+ }
+
+ _vm->removeInputTop();
+ updateMagicShapes();
+
+ _screen->copyRegion(0, 0, 144, 64, 160, 128, 2, 0, Screen::CR_NO_P_CHECK);
+ _screen->printShadedText(_chargenStrings2[10], 147, 67, 9, 0);
+
+ toggleSpecialButton(5, 0, 0);
+
+ itemsMask &= _alignmentMenuMasks[cClass];
+ _vm->_gui->simpleMenu_setup(3, 9, _chargenAlignmentStrings, itemsMask, 0, 0);
+
+ _vm->_mouseX = _vm->_mouseY = 0;
+ int16 res = -1;
+
+ while (res == -1 && !_vm->shouldQuit()) {
+ updateMagicShapes();
+ int in = getInput(0) & 0xff;
+ Common::Point mp = _vm->getMousePos();
+
+ if (in == _vm->_keyMap[Common::KEYCODE_ESCAPE] || _vm->_gui->_menuLastInFlags == _vm->_keyMap[Common::KEYCODE_ESCAPE] || _vm->_gui->_menuLastInFlags == _vm->_keyMap[Common::KEYCODE_b]) {
+ res = _vm->_keyMap[Common::KEYCODE_ESCAPE];
+ } else if (_vm->posWithinRect(mp.x, mp.y, 264, 171, 303, 187)) {
+ if (in == 199 || in == 201)
+ res = _vm->_keyMap[Common::KEYCODE_ESCAPE];
+ else
+ _vm->removeInputTop();
+ } else {
+ res = _vm->_gui->simpleMenu_process(3, _chargenAlignmentStrings, 0, itemsMask, 0);
+ }
+ }
+
+ _vm->removeInputTop();
+
+ if (res == _vm->_keyMap[Common::KEYCODE_ESCAPE])
+ processSpecialButton(5);
+
+ return res;
+}
+
+int CharacterGenerator::getInput(Button *buttonList) {
+ if (_vm->game() == GI_EOB1 && _vm->sound()->checkTrigger()) {
+ _vm->sound()->resetTrigger();
+ _vm->snd_playSong(20);
+ } else if (_vm->game() == GI_EOB2 && !_vm->sound()->isPlaying()) {
+ // WORKAROUND for EOB II: The original implements the same sound trigger check as in EOB I.
+ // However, Westwood seems to have forgotten to set the trigger at the end of the AdLib song,
+ // so that the music will not loop. We simply check whether the sound driver is still playing.
+ _vm->delay(3 * _vm->_tickLength);
+ _vm->snd_playSong(13);
+ }
+ return _vm->checkInput(buttonList, false, 0);
+}
+
+void CharacterGenerator::updateMagicShapes() {
+ if (_magicShapesBox != _activeBox) {
+ _chargenMagicShapeTimer = 0;
+ _magicShapesBox = _activeBox;
+ }
+
+ if (_chargenMagicShapeTimer < _vm->_system->getMillis()) {
+ if (++_updateBoxShapesIndex > 9)
+ _updateBoxShapesIndex = 0;
+ _chargenMagicShapeTimer = _vm->_system->getMillis() + 2 * _vm->_tickLength;
+ }
+
+ if (_updateBoxShapesIndex == _lastUpdateBoxShapesIndex)
+ return;
+
+ _screen->copyRegion(_activeBox << 5, 128, 288, 128, 32, 32, 2, 2, Screen::CR_NO_P_CHECK);
+ _screen->drawShape(2, _chargenMagicShapes[_updateBoxShapesIndex], 288, 128, 0);
+ _screen->copyRegion(288, 128, _chargenBoxX[_activeBox], _chargenBoxY[_activeBox] + 1, 32, 32, 2, 0, Screen::CR_NO_P_CHECK);
+ _screen->updateScreen();
+
+ _lastUpdateBoxShapesIndex = _updateBoxShapesIndex;
+}
+
+void CharacterGenerator::generateStats(int index) {
+ EoBCharacter *c = &_characters[index];
+
+ for (int i = 0; i < 3; i++) {
+ c->level[i] = _chargenStartLevels[(c->cClass << 2) + i];
+ c->experience[i] = (_vm->game() == GI_EOB2 ? 69000 : 5000) / _chargenStartLevels[(c->cClass << 2) + 3];
+ }
+
+ int rc = c->raceSex >> 1;
+ for (int i = 0; i < 6; i++) {
+ _chargenMinStats[i] = MAX(_chargenClassMinStats[c->cClass * 6 + i], _chargenRaceMinStats[rc * 6 + i]);
+ _chargenMaxStats[i] = _chargenRaceMaxStats[rc * 6 + i];
+ }
+
+ if (_vm->_charClassModifier[c->cClass])
+ _chargenMaxStats[0] = 18;
+
+ uint16 sv[6];
+ for (int i = 0; i < 6; i++) {
+ sv[i] = MAX<uint16>(rollDice() + _raceModifiers[rc * 6 + i], _chargenMinStats[i]);
+ if (!i && sv[i] == 18)
+ sv[i] |= (uint16)(_vm->rollDice(1, 100) << 8);
+ if (sv[i] > _chargenMaxStats[i])
+ sv[i] = _chargenMaxStats[i];
+ }
+
+ c->strengthCur = c->strengthMax = sv[0] & 0xff;
+ c->strengthExtCur = c->strengthExtMax = sv[0] >> 8;
+ c->intelligenceCur = c->intelligenceMax = sv[1] & 0xff;
+ c->wisdomCur = c->wisdomMax = sv[2] & 0xff;
+ c->dexterityCur = c->dexterityMax = sv[3] & 0xff;
+ c->constitutionCur = c->constitutionMax = sv[4] & 0xff;
+ c->charismaCur = c->charismaMax = sv[5] & 0xff;
+ c->armorClass = 10 + _vm->getDexterityArmorClassModifier(sv[3] & 0xff);
+ c->hitPointsCur = 0;
+
+ for (int l = 0; l < 3; l++) {
+ for (int i = 0; i < c->level[l]; i++)
+ c->hitPointsCur += _vm->generateCharacterHitpointsByLevel(index, 1 << l);
+ }
+
+ c->hitPointsMax = c->hitPointsCur;
+}
+
+void CharacterGenerator::modifyMenu() {
+ _vm->removeInputTop();
+ printStats(_activeBox, 3);
+
+ EoBCharacter *c = &_characters[_activeBox];
+ int8 hpLO = c->hitPointsCur;
+
+ for (int i = 0; i >= 0 && i < 7;) {
+ switch (i) {
+ case 0:
+ i = modifyStat(i, &c->strengthCur, &c->strengthExtCur);
+ break;
+ case 1:
+ i = modifyStat(i, &c->intelligenceCur, 0);
+ break;
+ case 2:
+ i = modifyStat(i, &c->wisdomCur, 0);
+ break;
+ case 3:
+ i = modifyStat(i, &c->dexterityCur, 0);
+ break;
+ case 4:
+ i = modifyStat(i, &c->constitutionCur, 0);
+ break;
+ case 5:
+ i = modifyStat(i, &c->charismaCur, 0);
+ break;
+ case 6:
+ hpLO = c->hitPointsCur;
+ i = modifyStat(i, &hpLO, 0);
+ c->hitPointsCur = hpLO;
+ break;
+ default:
+ break;
+ }
+
+ if (i == -2 || _vm->shouldQuit())
+ break;
+ else if (i < 0)
+ i = 6;
+ i %= 7;
+
+ printStats(_activeBox, 3);
+ }
+
+ printStats(_activeBox, 1);
+}
+
+void CharacterGenerator::statsAndFacesMenu() {
+ faceSelectMenu();
+ printStats(_activeBox, 1);
+ initButtonsFromList(27, 4);
+ _vm->removeInputTop();
+ int in = 0;
+
+ while (!in && !_vm->shouldQuit()) {
+ updateMagicShapes();
+ in = getInput(_vm->_activeButtons);
+ _vm->removeInputTop();
+
+ if (in == 0x8001) {
+ processSpecialButton(4);
+ updateMagicShapes();
+ generateStats(_activeBox);
+ in = -1;
+ } else if (in == 0x8002) {
+ processSpecialButton(7);
+ modifyMenu();
+ in = -1;
+ } else if (in == 0x8003) {
+ processSpecialButton(8);
+ faceSelectMenu();
+ in = -1;
+ } else if (in == 0x8004 || in == _vm->_keyMap[Common::KEYCODE_KP5]) {
+ processSpecialButton(6);
+ in = 1;
+ } else {
+ in = 0;
+ }
+
+ if (in & 0x8000) {
+ printStats(_activeBox, 1);
+ initButtonsFromList(27, 4);
+ in = 0;
+ }
+ }
+
+ _vm->_gui->updateBoxFrameHighLight(6 + _activeBox);
+ _vm->_gui->updateBoxFrameHighLight(-1);
+}
+
+void CharacterGenerator::faceSelectMenu() {
+ int8 sp[4];
+ memcpy(sp, _chargenSelectedPortraits2, sizeof(sp));
+ _vm->removeInputTop();
+ initButtonsFromList(21, 6);
+
+ int charSex = _characters[_activeBox].raceSex % 2;
+ int8 shp = charSex ? 26 : 0;
+
+ printStats(_activeBox, 4);
+ toggleSpecialButton(12, 0, 0);
+ toggleSpecialButton(13, 0, 0);
+ _vm->_gui->updateBoxFrameHighLight(-1);
+
+ shp = getNextFreeFaceShape(shp, charSex, 1, _chargenSelectedPortraits);
+
+ int res = -1;
+ int box = 1;
+
+ while (res == -1 && !_vm->shouldQuit()) {
+ int8 shpOld = shp;
+
+ for (int i = 0; i < 4; i++) {
+ sp[i] = shp;
+ _screen->drawShape(0, _faceShapes[sp[i]], 176 + (i << 5), 66, 0);
+ shp = getNextFreeFaceShape(shp + 1, charSex, 1, _chargenSelectedPortraits);
+ }
+
+ shp = shpOld;
+ int in = 0;
+
+ while (!in && !_vm->shouldQuit()) {
+ updateMagicShapes();
+ in = getInput(_vm->_activeButtons);
+ _vm->removeInputTop();
+
+ _vm->_gui->updateBoxFrameHighLight(box + 10);
+
+ if (in == 0x8002 || in == _vm->_keyMap[Common::KEYCODE_RIGHT]) {
+ processSpecialButton(13);
+ in = 2;
+ } else if (in > 0x8002 && in < 0x8007) {
+ box = (in & 7) - 3;
+ in = 3;
+ } else if (in == 0x8001 || in == _vm->_keyMap[Common::KEYCODE_LEFT]) {
+ processSpecialButton(12);
+ in = 1;
+ } else if (in == _vm->_keyMap[Common::KEYCODE_RETURN] || in == _vm->_keyMap[Common::KEYCODE_KP5]) {
+ in = 3;
+ } else if (in & 0x8000) {
+ in &= 0xff;
+ } else {
+ in = 0;
+ }
+ }
+
+ _vm->_gui->updateBoxFrameHighLight(-1);
+
+ if (in == 1)
+ shp = getNextFreeFaceShape(shp - 1, charSex, -1, _chargenSelectedPortraits);
+ else if (in == 2)
+ shp = getNextFreeFaceShape(shp + 1, charSex, 1, _chargenSelectedPortraits);
+ else if (in == 3)
+ res = box;
+ }
+
+ if (!_vm->shouldQuit()) {
+ _vm->_gui->updateBoxFrameHighLight(-1);
+ updateMagicShapes();
+
+ _chargenSelectedPortraits[_activeBox] = sp[res];
+ _characters[_activeBox].portrait = sp[res];
+ _characters[_activeBox].faceShape = _faceShapes[sp[res]];
+
+ printStats(_activeBox, 1);
+ }
+}
+
+int CharacterGenerator::getNextFreeFaceShape(int shpIndex, int charSex, int step, int8 *selectedPortraits) {
+ int shpCur = ((shpIndex < 0) ? 43 : shpIndex) % 44;
+ bool notUsable = false;
+
+ do {
+ notUsable = false;
+ for (int i = 0; i < 4; i++) {
+ if (_characters[i].name[0] && selectedPortraits[i] == shpCur)
+ notUsable = true;
+ }
+
+ if ((charSex && (shpCur < 26)) || (!charSex && (shpCur > 28)))
+ notUsable = true;
+
+ if (notUsable) {
+ shpCur += step;
+ shpCur = ((shpCur < 0) ? 43 : shpCur) % 44;
+ }
+ } while (notUsable);
+
+ return shpCur;
+}
+
+void CharacterGenerator::processFaceMenuSelection(int index) {
+ _vm->_gui->updateBoxFrameHighLight(-1);
+ if (index <= 48)
+ _screen->drawShape(0, _characters[_activeBox].faceShape, _chargenBoxX[_activeBox], _chargenBoxY[_activeBox] + 1, 0);
+ else
+ toggleSpecialButton(index - 50, 0, 0);
+}
+
+void CharacterGenerator::printStats(int index, int mode) {
+ _screen->copyRegion(0, 0, 160, 0, 160, 128, 2, 2, Screen::CR_NO_P_CHECK);
+ _screen->_curPage = 2;
+
+ EoBCharacter *c = &_characters[index];
+
+ if (mode != 4)
+ _screen->drawShape(2, c->faceShape, 224, 2, 0);
+
+ _screen->printShadedText(c->name, 160 + ((20 - strlen(c->name)) << 2), 35, 15, 0);
+ _screen->printShadedText(_chargenRaceSexStrings[c->raceSex], 160 + ((20 - strlen(_chargenRaceSexStrings[c->raceSex])) << 2), 45, 15, 0);
+ _screen->printShadedText(_chargenClassStrings[c->cClass], 160 + ((20 - strlen(_chargenClassStrings[c->cClass])) << 2), 54, 15, 0);
+
+ for (int i = 0; i < 6; i++)
+ _screen->printShadedText(_chargenStatStrings[i], 163, (i + 8) << 3, 15, 0);
+
+ _screen->printShadedText(_chargenStrings1[2], 248, 64, 15, 0);
+
+ Common::String str = Common::String::format(_chargenStrings1[3], _vm->getCharStrength(c->strengthCur, c->strengthExtCur).c_str(), c->intelligenceCur, c->wisdomCur, c->dexterityCur, c->constitutionCur, c->charismaCur);
+ _screen->printShadedText(str.c_str(), 192, 64, 15, 0);
+
+ str = Common::String::format(_chargenStrings1[4], c->armorClass, c->hitPointsMax);
+ _screen->printShadedText(str.c_str(), 280, 64, 15, 0);
+
+ const char *lvlStr = c->level[2] ? _chargenStrings1[7] : (c->level[1] ? _chargenStrings1[6] : _chargenStrings1[5]);
+ str = Common::String::format(lvlStr, c->level[0], c->level[1], c->level[2]);
+ _screen->printShadedText(str.c_str(), 280, 80, 15, 0);
+
+ switch (mode) {
+ case 1:
+ toggleSpecialButton(4, 0, 2);
+ toggleSpecialButton(7, 0, 2);
+ toggleSpecialButton(8, 0, 2);
+ toggleSpecialButton(6, 0, 2);
+ break;
+
+ case 2:
+ toggleSpecialButton(16, 0, 2);
+ toggleSpecialButton(9, 0, 2);
+ break;
+
+ case 3:
+ toggleSpecialButton(10, 0, 2);
+ toggleSpecialButton(11, 0, 2);
+ toggleSpecialButton(9, 0, 2);
+ break;
+
+ default:
+ break;
+ }
+
+ _screen->copyRegion(160, 0, 144, 64, 160, 128, 2, 0, Screen::CR_NO_P_CHECK);
+
+ if (mode != 3)
+ _screen->updateScreen();
+
+ _screen->_curPage = 0;
+}
+
+void CharacterGenerator::processNameInput(int index, int len, int textColor) {
+ Screen::FontId of = _screen->setFont(Screen::FID_6_FNT);
+
+ // WORKAROUND for bug in original code:
+ len = strlen(_characters[index].name);
+
+ int xOffs = (60 - _screen->getFontWidth() * len) >> 1;
+ _screen->printText(_chargenStrings1[1], _chargenNameFieldX[index], _chargenNameFieldY[index], 12, 12);
+ _screen->printText(_characters[index].name, _chargenNameFieldX[index] + xOffs, _chargenNameFieldY[index], textColor, 0);
+ _screen->updateScreen();
+ _screen->setFont(of);
+}
+
+int CharacterGenerator::rollDice() {
+ int res = 0;
+ int min = 10;
+
+ for (int i = 0; i < 4; i++) {
+ int d = _vm->rollDice(1, 6, 0);
+ res += d;
+ if (d < min)
+ min = d;
+ }
+
+ res -= min;
+ return res;
+}
+
+int CharacterGenerator::modifyStat(int index, int8 *stat1, int8 *stat2) {
+ uint8 *s1 = (uint8 *)stat1;
+ uint8 *s2 = (uint8 *)stat2;
+
+ initButtonsFromList(31, 10);
+ Button *b = _vm->gui_getButton(_vm->_activeButtons, index + 1);
+
+ printStats(_activeBox, 3);
+ _vm->removeInputTop();
+
+ Common::String statStr = index ? Common::String::format("%d", *s1) : _vm->getCharStrength(*s1, *s2);
+
+ _screen->copyRegion(b->x - 112, b->y - 64, b->x + 32, b->y, 40, b->height, 2, 0, Screen::CR_NO_P_CHECK);
+ _screen->printShadedText(statStr.c_str(), b->x + 32, b->y, 6, 0);
+ _screen->updateScreen();
+
+ EoBCharacter *c = &_characters[_activeBox];
+
+ int ci = index;
+ uint8 v2 = s2 ? *s2 : 0;
+
+ if (index == 6) {
+ _chargenMaxStats[6] = getMaxHp(c->cClass, c->constitutionCur, c->level[0], c->level[1], c->level[2]);
+ _chargenMinStats[6] = getMinHp(c->cClass, c->constitutionCur, c->level[0], c->level[1], c->level[2]);
+ }
+
+ for (bool loop = true; loop && !_vm->shouldQuit();) {
+ uint8 v1 = *s1;
+ updateMagicShapes();
+ int inputFlag = getInput(_vm->_activeButtons);
+ _vm->removeInputTop();
+
+ if (inputFlag == _vm->_keyMap[Common::KEYCODE_LEFT] || inputFlag == _vm->_keyMap[Common::KEYCODE_KP4] || inputFlag == _vm->_keyMap[Common::KEYCODE_MINUS] || inputFlag == _vm->_keyMap[Common::KEYCODE_KP_MINUS] || inputFlag == 0x8009) {
+ processSpecialButton(11);
+ v1--;
+
+ } else if (inputFlag == _vm->_keyMap[Common::KEYCODE_RIGHT] || inputFlag == _vm->_keyMap[Common::KEYCODE_KP6] || inputFlag == _vm->_keyMap[Common::KEYCODE_PLUS] || inputFlag == _vm->_keyMap[Common::KEYCODE_KP_PLUS] || inputFlag == 0x8008) {
+ processSpecialButton(10);
+ v1++;
+
+ } else if (inputFlag == _vm->_keyMap[Common::KEYCODE_UP] || inputFlag == _vm->_keyMap[Common::KEYCODE_KP8]) {
+ ci = (ci - 1) % 7;
+ loop = false;
+
+ } else if (inputFlag == _vm->_keyMap[Common::KEYCODE_DOWN] || inputFlag == _vm->_keyMap[Common::KEYCODE_KP2]) {
+ ci = (ci + 1) % 7;
+ loop = false;
+
+ } else if (inputFlag == _vm->_keyMap[Common::KEYCODE_o] || inputFlag == _vm->_keyMap[Common::KEYCODE_KP5] || inputFlag == _vm->_keyMap[Common::KEYCODE_ESCAPE] || inputFlag == 0x800A) {
+ processSpecialButton(9);
+ loop = false;
+ ci = -2;
+
+ } else if (inputFlag & 0x8000) {
+ inputFlag = (inputFlag & 0x0f) - 1;
+ if (index != inputFlag) {
+ ci = inputFlag;
+ loop = false;
+ }
+ }
+
+ if (v1 == *s1)
+ continue;
+
+ if (!index) {
+ while (v1 > 18) {
+ v1--;
+ v2++;
+ }
+ while (v2 > 0 && v1 < 18) {
+ v1++;
+ v2--;
+ }
+
+ v1 = CLIP<uint8>(v1, _chargenMinStats[index], _chargenMaxStats[index] & 0xff);
+ v2 = (v1 == 18 && _chargenMaxStats[index] >= 19) ? CLIP<uint8>(v2, 0, 100) : 0;
+ if (s2)
+ *s2 = v2;
+ else
+ error("CharacterGenerator::modifyStat:...");
+ } else {
+ v1 = CLIP<uint8>(v1, _chargenMinStats[index], _chargenMaxStats[index]);
+ }
+
+ *s1 = v1;
+
+ if (index == 6)
+ _characters[_activeBox].hitPointsMax = v1;
+
+ statStr = index ? Common::String::format("%d", *s1) : _vm->getCharStrength(*s1, *s2);
+
+ _screen->copyRegion(b->x - 112, b->y - 64, b->x + 32, b->y, 40, b->height, 2, 0, Screen::CR_NO_P_CHECK);
+ _screen->printShadedText(statStr.c_str(), b->x + 32, b->y, 6, 0);
+ _screen->updateScreen();
+
+ if (index == 4) {
+ int oldVal = c->hitPointsCur;
+ _chargenMaxStats[6] = getMaxHp(c->cClass, c->constitutionCur, c->level[0], c->level[1], c->level[2]);
+ _chargenMinStats[6] = getMinHp(c->cClass, c->constitutionCur, c->level[0], c->level[1], c->level[2]);
+ c->hitPointsMax = c->hitPointsCur = CLIP<int16>(c->hitPointsCur, _chargenMinStats[6], _chargenMaxStats[6]);
+
+ if (c->hitPointsCur != oldVal) {
+ statStr = Common::String::format("%d", c->hitPointsCur);
+ _screen->copyRegion(120, 72, 264, 136, 40, 8, 2, 0, Screen::CR_NO_P_CHECK);
+ _screen->printShadedText(statStr.c_str(), 264, 136, 15, 0);
+ _screen->updateScreen();
+ }
+
+ } else if (index == 3) {
+ int oldVal = c->armorClass;
+ c->armorClass = _vm->getDexterityArmorClassModifier(v1) + 10;
+
+ if (c->armorClass != oldVal) {
+ statStr = Common::String::format("%d", c->armorClass);
+ _screen->copyRegion(120, 64, 264, 128, 40, 8, 2, 0, Screen::CR_NO_P_CHECK);
+ _screen->printShadedText(statStr.c_str(), 264, 128, 15, 0);
+ _screen->updateScreen();
+ }
+ }
+
+ if (loop == false) {
+ statStr = index ? Common::String::format("%d", *s1) : _vm->getCharStrength(*s1, *s2);
+ _screen->printText(statStr.c_str(), b->x + 32, b->y, 15, 0);
+ _screen->updateScreen();
+ }
+ }
+
+ return ci;
+}
+
+int CharacterGenerator::getMaxHp(int cclass, int constitution, int level1, int level2, int level3) {
+ int res = 0;
+ constitution = _vm->getClassAndConstHitpointsModifier(cclass, constitution);
+
+ int m = _vm->getCharacterClassType(cclass, 0);
+ if (m != -1)
+ res = _vm->getModifiedHpLimits(m, constitution, level1, false);
+
+ m = _vm->getCharacterClassType(cclass, 1);
+ if (m != -1)
+ res += _vm->getModifiedHpLimits(m, constitution, level2, false);
+
+ m = _vm->getCharacterClassType(cclass, 2);
+ if (m != -1)
+ res += _vm->getModifiedHpLimits(m, constitution, level3, false);
+
+ res /= _vm->_numLevelsPerClass[cclass];
+
+ return res;
+}
+
+int CharacterGenerator::getMinHp(int cclass, int constitution, int level1, int level2, int level3) {
+ int res = 0;
+ constitution = _vm->getClassAndConstHitpointsModifier(cclass, constitution);
+
+ int m = _vm->getCharacterClassType(cclass, 0);
+ if (m != -1)
+ res = _vm->getModifiedHpLimits(m, constitution, level1, true);
+
+ m = _vm->getCharacterClassType(cclass, 1);
+ if (m != -1)
+ res += _vm->getModifiedHpLimits(m, constitution, level2, true);
+
+ m = _vm->getCharacterClassType(cclass, 2);
+ if (m != -1)
+ res += _vm->getModifiedHpLimits(m, constitution, level3, true);
+
+ res /= _vm->_numLevelsPerClass[cclass];
+
+ return res;
+}
+
+void CharacterGenerator::finish() {
+ _screen->copyRegion(0, 0, 160, 0, 160, 128, 2, 2, Screen::CR_NO_P_CHECK);
+ int cp = _screen->setCurPage(2);
+ _screen->printShadedText(_chargenEnterGameStrings[0], 168, 32, 15, 0);
+ _screen->setCurPage(cp);
+ _screen->copyRegion(160, 0, 144, 64, 160, 128, 2, 0, Screen::CR_NO_P_CHECK);
+ _screen->updateScreen();
+
+ if (_vm->game() == GI_EOB1) {
+ static const int8 classDefaultItemsList[] = {
+ 1, 17, 2, 17, 46, -1, 4, -1, 5, -1, 6,
+ 2, 7, -1, 8, -1, 9, 21, 10, 2, 31, 2
+ };
+
+ static const int8 classDefaultItemsListIndex[] = {
+ 4, 8, 0, -1, 4, 3, 0, -1, 4, 10,
+ 0, 8, 3, 6, 1, -1, 2, 7, 0, -1,
+ 4, 5, 0, -1, 4, 7, 0, 8, 4, 5,
+ 0, 8, 4, 6, 8, 8, 4, 6, 5, 8,
+ 3, 6, 5, -1, 2, 7, 5, 0, 4, 6,
+ 7, 0, 4, 3, 7, 0, 2, 6, 7, 1
+ };
+
+ _characters[0].inventory[2] = _vm->duplicateItem(35);
+
+ for (int i = 0; i < 4; i++) {
+ EoBCharacter *c = &_characters[i];
+ c->flags = 1;
+ c->food = 100;
+ c->id = i;
+ c->inventory[3] = _vm->duplicateItem(10);
+
+ for (int ii = 0; ii < 4; ii++) {
+ int l = classDefaultItemsListIndex[(c->cClass << 2) + ii] << 1;
+ if (classDefaultItemsList[l] == -1)
+ continue;
+
+ int d = classDefaultItemsList[l];
+ int slot = classDefaultItemsList[l + 1];
+
+ if (slot < 0) {
+ slot = 0;
+ if (c->inventory[slot])
+ slot++;
+ if (c->inventory[slot])
+ slot++;
+ }
+
+ if (slot != 2 && c->inventory[slot])
+ continue;
+
+ if (d == 5 && (c->raceSex >> 1) == 3)
+ d = 36;
+
+ if (slot == 2) {
+ while (c->inventory[slot])
+ slot++;
+ }
+
+ c->inventory[slot] = _vm->duplicateItem(d);
+ }
+
+ _vm->recalcArmorClass(i);
+ }
+
+ } else {
+ static const uint8 classDefaultItemsListIndex[] = { 0, 0, 0, 1, 2, 3, 0, 0, 0, 0, 3, 2, 0, 0, 2 };
+ static const int8 itemList0[] = { 3, 36, 0, 17, -1, 0, 0, 56, 1, 17, 31, 0, 1, 23, 1, 17, 31, 1, 1 };
+ static const int8 itemList1[] = { 1, 2, 0, 17, -1, 0, 0 };
+ static const int8 itemList2[] = { 2, 56, 1, 17, 31, 0, 1, 23, 1, 17, 31, 0, 1 };
+ static const int8 itemList3[] = { 2, 1, 1, 17, 31, 1, 1, 1, 0, 17, 31, 2, 1 };
+ static const int8 *itemList[] = { itemList0, itemList1, itemList2, itemList3 };
+
+ for (int i = 0; i < 4; i++) {
+ EoBCharacter *c = &_characters[i];
+ c->flags = 1;
+ c->food = 100;
+ c->id = i;
+ const int8 *df = itemList[classDefaultItemsListIndex[c->cClass]];
+ int v1 = _vm->rollDice(1, *df++, -1);
+
+ df = &df[v1 * 6];
+ for (int ii = 0; ii < 2; ii++) {
+ if (df[0] == -1)
+ break;
+ _vm->createInventoryItem(c, df[0], df[1], df[2]);
+ df = &df[3];
+ }
+
+ uint16 m = _vm->_classModifierFlags[c->cClass];
+ v1 = _vm->rollDice(1, 2, -1);
+
+ int ival = 0;
+ int itype = 0;
+
+ if (m & 0x31) {
+ if ((c->raceSex >> 1) == 3) {
+ itype = 22;
+ ival = 1;
+ } else {
+ if (v1 == 0) {
+ itype = 5;
+ ival = 1;
+ } else {
+ itype = 34;
+ }
+ }
+ } else if (m & 0x04) {
+ itype = 26;
+ if (v1 != 0)
+ ival = 1;
+ } else if (m & 0x08) {
+ ival = 1;
+ itype = ((c->raceSex >> 1) == 3) ? 22 : 5;
+ } else {
+ if (v1 == 0) {
+ itype = 3;
+ } else {
+ itype = 4;
+ ival = 1;
+ }
+ }
+
+ _vm->createInventoryItem(c, itype, ival, 0);
+ _vm->createInventoryItem(c, 10, -1, 2);
+ _vm->createInventoryItem(c, 10, -1, 2);
+ _vm->createInventoryItem(c, 24, 2, 2);
+
+ if (_vm->_classModifierFlags[c->cClass] & 2) {
+ _vm->createInventoryItem(c, 7, -1, 1);
+ _vm->createInventoryItem(c, 21, 4, 2);
+ _vm->createInventoryItem(c, 21, 13, 2);
+ }
+
+ if (_vm->_classModifierFlags[c->cClass] & 0x14) {
+ if (c->cClass == 2)
+ _vm->createInventoryItem(c, 27, -1, 1);
+ else
+ _vm->createInventoryItem(c, 8, -1, 1);
+
+ _vm->createInventoryItem(c, 20, 49, 1);
+ }
+
+ if (_vm->_classModifierFlags[c->cClass] & 8)
+ _vm->createInventoryItem(c, 6, -1, 1);
+
+ if (i == 0)
+ _vm->createInventoryItem(c, 93, -1, 2);
+
+ _vm->recalcArmorClass(i);
+ }
+ }
+
+ for (int i = 0; i < 4; i++) {
+ if (_vm->_classModifierFlags[_characters[i].cClass] & 2)
+ _characters[i].mageSpellsAvailableFlags = (_vm->game() == GI_EOB2) ? 0x81CB6 : 0x26C;
+
+ if (_vm->_classModifierFlags[_characters[i].cClass] & 0x14 && _vm->game() == GI_EOB2) {
+ // Cleric/Paladin: Add Turn Undead spell
+ _characters[i].clericSpells[0] = 29;
+ }
+ }
+
+ for (int i = 0; i < 4; i++) {
+ EoBCharacter *c = &_characters[i];
+ c->strengthMax = c->strengthCur;
+ c->strengthExtMax = c->strengthExtCur;
+ c->intelligenceMax = c->intelligenceCur;
+ c->wisdomMax = c->wisdomCur;
+ c->dexterityMax = c->dexterityCur;
+ c->constitutionMax = c->constitutionCur;
+ c->charismaMax = c->charismaCur;
+ c->hitPointsMax = c->hitPointsCur;
+ }
+
+ _vm->gui_resetButtonList();
+
+ if (_faceShapes) {
+ for (int i = 0; i < 44; i++) {
+ bool del = true;
+ for (int ii = 0; ii < 4; ii++) {
+ if (_characters[ii].faceShape == _faceShapes[i])
+ del = false;
+ }
+ if (del)
+ delete[] _faceShapes[i];
+ }
+ delete[] _faceShapes;
+ _faceShapes = 0;
+ }
+
+ if (_chargenMagicShapes) {
+ for (int i = 0; i < 10; i++)
+ delete[] _chargenMagicShapes[i];
+ delete[] _chargenMagicShapes;
+ _chargenMagicShapes = 0;
+ }
+
+ for (int i = 0; i < 17; i++) {
+ delete[] _chargenButtonLabels[i];
+ _chargenButtonLabels[i] = 0;
+ }
+}
+
+const EoBChargenButtonDef CharacterGenerator::_chargenButtonDefs[] = {
+ { 0x01, 0x37, 0x31, 0x32, 0x70 },
+ { 0x09, 0x37, 0x31, 0x32, 0x71 },
+ { 0x01, 0x77, 0x31, 0x32, 0x72 },
+ { 0x09, 0x77, 0x31, 0x32, 0x73 },
+ { 0x03, 0xB5, 0x53, 0x10, 0x1A },
+ { 0x21, 0xAC, 0x26, 0x10, 0x19 },
+ { 0x1C, 0xAC, 0x26, 0x10, 0x21 },
+ { 0x21, 0xAC, 0x26, 0x10, 0x32 },
+ { 0x13, 0x50, 0x9A, 0x08, 0x00 },
+ { 0x13, 0x58, 0x9A, 0x08, 0x00 },
+ { 0x13, 0x60, 0x9A, 0x08, 0x00 },
+ { 0x13, 0x68, 0x9A, 0x08, 0x00 },
+ { 0x13, 0x70, 0x9A, 0x08, 0x00 },
+ { 0x13, 0x78, 0x9A, 0x08, 0x00 },
+ { 0x13, 0x80, 0x9A, 0x08, 0x00 },
+ { 0x13, 0x88, 0x9A, 0x08, 0x00 },
+ { 0x13, 0x90, 0x9A, 0x08, 0x00 },
+ { 0x13, 0x98, 0x9A, 0x08, 0x00 },
+ { 0x13, 0xA0, 0x9A, 0x08, 0x00 },
+ { 0x13, 0xA8, 0x9A, 0x08, 0x00 },
+ { 0x13, 0xB0, 0x9A, 0x08, 0x00 },
+ { 0x12, 0x42, 0x20, 0x10, 0x00 },
+ { 0x12, 0x52, 0x20, 0x10, 0x00 },
+ { 0x16, 0x42, 0x20, 0x20, 0x00 },
+ { 0x1A, 0x42, 0x20, 0x20, 0x00 },
+ { 0x1E, 0x42, 0x20, 0x20, 0x00 },
+ { 0x22, 0x42, 0x20, 0x20, 0x00 },
+ { 0x1C, 0x9C, 0x26, 0x10, 0x14 },
+ { 0x21, 0x9C, 0x26, 0x10, 0x34 },
+ { 0x1C, 0xAC, 0x26, 0x10, 0x22 },
+ { 0x21, 0xAC, 0x26, 0x10, 0x26 },
+ { 0x12, 0x80, 0x35, 0x08, 0x00 },
+ { 0x12, 0x88, 0x35, 0x08, 0x00 },
+ { 0x12, 0x90, 0x35, 0x08, 0x00 },
+ { 0x12, 0x98, 0x35, 0x08, 0x00 },
+ { 0x12, 0xA0, 0x35, 0x08, 0x00 },
+ { 0x12, 0xA8, 0x35, 0x08, 0x00 },
+ { 0x1D, 0x88, 0x35, 0x08, 0x00 },
+ { 0x1B, 0xAC, 0x15, 0x10, 0x0D },
+ { 0x1E, 0xAC, 0x15, 0x10, 0x0C },
+ { 0x21, 0xAC, 0x25, 0x10, 0x19 }
+};
+
+const CreatePartyModButton CharacterGenerator::_chargenModButtons[] = {
+ { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x40 },
+ { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x0A, 0x40 },
+ { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x80 },
+ { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x0A, 0x80 },
+ { 0x00, 0xC0, 0x04, 0x05, 0x07, 0x05, 0x08, 0x1C, 0x9C },
+ { 0x04, 0xC0, 0x03, 0x05, 0x0A, 0x05, 0x08, 0x21, 0xAC },
+ { 0x07, 0xC0, 0x03, 0x05, 0x0B, 0x05, 0x08, 0x21, 0xAC },
+ { 0x0A, 0xC0, 0x04, 0x05, 0x06, 0x05, 0x08, 0x21, 0x9C },
+ { 0x18, 0xC0, 0x03, 0x05, 0x09, 0x05, 0x08, 0x1C, 0xAC },
+ { 0x0E, 0xC0, 0x02, 0x05, 0x0F, 0x05, 0x08, 0x21, 0xAC },
+ { 0x10, 0xC0, 0x01, 0x05, 0x09, 0x05, 0x04, 0x1B, 0xAC },
+ { 0x11, 0xC0, 0x01, 0x01, 0x09, 0x07, 0x04, 0x1E, 0xAC },
+ { 0x12, 0xC0, 0x03, 0x07, 0x07, 0x04, 0x06, 0x12, 0x42 },
+ { 0x15, 0xC0, 0x03, 0x07, 0x07, 0x04, 0x06, 0x12, 0x52 },
+ { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x03, 0xB5 },
+ { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x03, 0xB5 },
+ { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x1C, 0xAC }
+};
+
+const EoBRect8 CharacterGenerator::_chargenButtonBodyCoords[] = {
+ { 0x00, 0x80, 0x04, 0x20 },
+ { 0x04, 0x80, 0x04, 0x20 },
+ { 0x08, 0x80, 0x04, 0x20 },
+ { 0x0C, 0x80, 0x04, 0x20 },
+ { 0x0E, 0xA0, 0x03, 0x10 },
+ { 0x0B, 0xA0, 0x03, 0x10 },
+ { 0x10, 0x80, 0x04, 0x10 },
+ { 0x10, 0x90, 0x04, 0x10 },
+ { 0x11, 0xA0, 0x05, 0x10 },
+ { 0x11, 0xB0, 0x05, 0x10 },
+ { 0x16, 0xA0, 0x05, 0x10 },
+ { 0x16, 0xB0, 0x05, 0x10 },
+ { 0x00, 0xA0, 0x0B, 0x10 },
+ { 0x14, 0x80, 0x0B, 0x10 },
+ { 0x14, 0x90, 0x0B, 0x10 }
+};
+
+const int16 CharacterGenerator::_chargenBoxX[] = { 0x10, 0x50, 0x10, 0x50 };
+const int16 CharacterGenerator::_chargenBoxY[] = { 0x3F, 0x3F, 0x7F, 0x7F };
+const int16 CharacterGenerator::_chargenNameFieldX[] = { 0x02, 0x42, 0x02, 0x42 };
+const int16 CharacterGenerator::_chargenNameFieldY[] = { 0x6B, 0x6B, 0xAB, 0xAB };
+
+const int32 CharacterGenerator::_classMenuMasks[] = {
+ 0x003F, 0x07BB, 0x77FB, 0x00F1, 0x08F1, 0x00B1
+};
+
+const int32 CharacterGenerator::_alignmentMenuMasks[] = {
+ 0x01FF, 0x0007, 0x0001, 0x01FF, 0x01FF, 0x01FE, 0x01FF, 0x01FE,
+ 0x01FF, 0x01FE, 0x01FE, 0x01FE, 0x01FF, 0x0007, 0x01FF
+};
+
+const int16 CharacterGenerator::_raceModifiers[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, -1, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 1, -1, 0, 1, -1, 0, 0, 0, -1, 0, 0, 1, 0, 0
+};
+
+// Transfer Party
+
+class TransferPartyWiz {
+public:
+ TransferPartyWiz(EoBCoreEngine *vm, Screen_EoB *screen);
+ ~TransferPartyWiz();
+
+ bool start();
+
+private:
+ bool selectAndLoadTransferFile();
+ bool transferFileDialogue(Common::String &dest);
+
+
+ int selectCharactersMenu();
+ void drawCharPortraitWithStats(int charIndex, bool enabled);
+ void updateHighlight(int index);
+
+ void convertStats();
+ void convertInventory();
+ Item convertItem(Item eob1Item);
+ void giveKhelbensCoin();
+
+ EoBCoreEngine *_vm;
+ Screen_EoB *_screen;
+
+ int _highlight;
+ EoBItem *_oldItems;
+
+ const uint16 *_portraitFrames;
+ const uint8 *_convertTable;
+ const uint8 *_itemTable;
+ const uint32 *_expTable;
+ const char *const *_strings1;
+ const char *const *_strings2;
+ const char *const *_labels;
+};
+
+TransferPartyWiz::TransferPartyWiz(EoBCoreEngine *vm, Screen_EoB *screen) : _vm(vm), _screen(screen) {
+ int temp;
+ _portraitFrames = _vm->staticres()->loadRawDataBe16(kEoB2TransferPortraitFrames, temp);
+ _convertTable = _vm->staticres()->loadRawData(kEoB2TransferConvertTable, temp);
+ _itemTable = _vm->staticres()->loadRawData(kEoB2TransferItemTable, temp);
+ _expTable = _vm->staticres()->loadRawDataBe32(kEoB2TransferExpTable, temp);
+ _strings1 = _vm->staticres()->loadStrings(kEoB2TransferStrings1, temp);
+ _strings2 = _vm->staticres()->loadStrings(kEoB2TransferStrings2, temp);
+ _labels = _vm->staticres()->loadStrings(kEoB2TransferLabels, temp);
+ _highlight = -1;
+ _oldItems = 0;
+}
+
+TransferPartyWiz::~TransferPartyWiz() {
+ delete[] _oldItems;
+}
+
+bool TransferPartyWiz::start() {
+ _screen->copyPage(0, _vm->_useHiResDithering ? 1 : 12);
+
+ if (!selectAndLoadTransferFile())
+ return false;
+
+ convertStats();
+
+ _oldItems = new EoBItem[600];
+ memcpy(_oldItems, _vm->_items, sizeof(EoBItem) * 600);
+ _vm->loadItemDefs();
+
+ int selection = selectCharactersMenu();
+ if (selection == 0) {
+ for (int i = 0; i < 6; i++)
+ delete[] _vm->_characters[i].faceShape;
+ memset(_vm->_characters, 0, sizeof(EoBCharacter) * 6);
+ return false;
+ }
+
+ int ch = 0;
+ for (int i = 0; i < 6; i++) {
+ if (selection & (1 << i)) {
+ if (ch != i) {
+ delete[] _vm->_characters[ch].faceShape;
+ memcpy(&_vm->_characters[ch], &_vm->_characters[i], sizeof(EoBCharacter));
+ _vm->_characters[i].faceShape = 0;
+ }
+ ch++;
+ }
+ }
+ memset(&_vm->_characters[4], 0, sizeof(EoBCharacter) * 2);
+
+ convertInventory();
+ giveKhelbensCoin();
+
+ return true;
+}
+
+bool TransferPartyWiz::selectAndLoadTransferFile() {
+ do {
+ _screen->copyPage(_vm->_useHiResDithering ? 1 : 12, 0);
+ if (transferFileDialogue(_vm->_savegameFilename))
+ break;
+ } while (_vm->_gui->confirmDialogue2(15, 68, 1));
+
+ if (_vm->_savegameFilename.empty())
+ return false;
+
+ if (_vm->loadGameState(-1).getCode() != Common::kNoError)
+ return false;
+
+ return true;
+}
+
+ bool TransferPartyWiz::transferFileDialogue(Common::String &dest) {
+ _vm->_gui->transferWaitBox();
+
+ Common::Array<Common::String> eobTargets;
+ const Common::ConfigManager::DomainMap dom = ConfMan.getGameDomains();
+
+ for (Common::ConfigManager::DomainMap::const_iterator i = dom.begin(); i != dom.end(); ++i) {
+ if (ConfMan.get("gameid", i->_key).equals("eob"))
+ eobTargets.push_back(i->_key);
+ _vm->updateInput();
+ }
+
+ if (eobTargets.empty())
+ return false;
+
+ Common::String target = _vm->_gui->transferTargetMenu(eobTargets);
+ _screen->copyPage(_vm->_useHiResDithering ? 1 : 12, 0);
+
+ if (target.empty())
+ return true;
+
+ dest = target + ".fin";
+ Common::InSaveFile *in = _vm->_saveFileMan->openForLoading(dest);
+ if (in) {
+ delete in;
+ if (_vm->_gui->confirmDialogue2(15, -2, 1))
+ return true;
+ }
+
+ _screen->copyPage(_vm->_useHiResDithering ? 1 : 12, 0);
+
+ bool result = _vm->_gui->transferFileMenu(target, dest);
+ _screen->copyPage(_vm->_useHiResDithering ? 1 : 12, 0);
+
+ return result;
+}
+
+int TransferPartyWiz::selectCharactersMenu() {
+ _screen->setCurPage(2);
+ _screen->setFont(Screen::FID_6_FNT);
+ _screen->clearCurPage();
+
+ _vm->gui_drawBox(0, 0, 320, 163, _vm->guiSettings()->colors.frame1, _vm->guiSettings()->colors.frame2, _vm->guiSettings()->colors.fill);
+ _screen->printText(_strings2[0], 5, 3, 15, 0);
+ _screen->printText(_strings2[1], 5, 10, 15, 0);
+
+ for (int i = 0; i < 6; i++)
+ drawCharPortraitWithStats(i, 0);
+
+ _vm->gui_drawBox(4, 148, 43, 12, _vm->guiSettings()->colors.frame1, _vm->guiSettings()->colors.frame2, _vm->guiSettings()->colors.fill);
+ _vm->gui_drawBox(272, 148, 43, 12, _vm->guiSettings()->colors.frame1, _vm->guiSettings()->colors.frame2, _vm->guiSettings()->colors.fill);
+
+ _screen->printShadedText(_labels[0], 9, 151, 15, 0);
+ _screen->printShadedText(_labels[1], 288, 151, 15, 0);
+
+ _screen->setCurPage(0);
+ _screen->copyRegion(0, 0, 0, 0, 320, 200, 2, 0, Screen::CR_NO_P_CHECK);
+ _screen->updateScreen();
+
+ int selection = 0;
+ int highlight = 0;
+ bool update = false;
+
+ for (bool loop = true; loop && (!_vm->shouldQuit());) {
+ int inputFlag = _vm->checkInput(0, false, 0) & 0x8ff;
+ _vm->removeInputTop();
+
+ if (inputFlag) {
+ if (inputFlag == _vm->_keyMap[Common::KEYCODE_LEFT] || inputFlag == _vm->_keyMap[Common::KEYCODE_RIGHT]) {
+ highlight ^= 1;
+ } else if (inputFlag == _vm->_keyMap[Common::KEYCODE_UP]) {
+ highlight -= 2;
+ if (highlight < 0)
+ highlight += 8;
+ } else if (inputFlag == _vm->_keyMap[Common::KEYCODE_DOWN]) {
+ highlight += 2;
+ if (highlight >= 8)
+ highlight -= 8;
+ } else if (inputFlag == _vm->_keyMap[Common::KEYCODE_RETURN] || inputFlag == _vm->_keyMap[Common::KEYCODE_SPACE]) {
+ update = true;
+ } else if (inputFlag == _vm->_keyMap[Common::KEYCODE_ESCAPE]) {
+ update = true;
+ highlight = 6;
+ } else if (inputFlag == 199) {
+ for (int i = 0; i < 8; i++) {
+ int t = i << 2;
+ if (_vm->posWithinRect(_vm->_mouseX, _vm->_mouseY, _portraitFrames[t], _portraitFrames[t + 1], _portraitFrames[t + 2], _portraitFrames[t + 3])) {
+ highlight = i;
+ update = true;
+ break;
+ }
+ }
+ }
+ }
+
+ updateHighlight(highlight);
+
+ if (!update)
+ continue;
+
+ update = false;
+
+ if (highlight < 6) {
+ if (_vm->_characters[highlight].flags & 1) {
+ selection ^= (1 << highlight);
+ drawCharPortraitWithStats(highlight, (selection & (1 << highlight)) ? true : false);
+ _screen->updateScreen();
+ }
+ continue;
+ }
+
+ int x = (highlight - 6) * 268 + 4;
+ _vm->gui_drawBox(x, 148, 43, 12, _vm->guiSettings()->colors.fill, _vm->guiSettings()->colors.fill, -1);
+ _screen->updateScreen();
+ _vm->_system->delayMillis(80);
+ _vm->gui_drawBox(x, 148, 43, 12, _vm->guiSettings()->colors.frame1, _vm->guiSettings()->colors.frame2, -1);
+ _screen->updateScreen();
+
+ if (highlight == 6 || _vm->shouldQuit()) {
+ _screen->setFont(Screen::FID_8_FNT);
+ return 0;
+ }
+
+ int count = 0;
+ for (int i = 0; i < 6; i++) {
+ if (selection & (1 << i))
+ count++;
+ }
+
+ if (count == 4 || _vm->shouldQuit())
+ loop = false;
+ else
+ _vm->_gui->messageDialogue(16, count < 4 ? 69 : 70, 6);
+
+ _screen->updateScreen();
+ }
+
+ _screen->setFont(Screen::FID_8_FNT);
+ if (_vm->shouldQuit())
+ return 0;
+ else
+ _vm->_gui->messageDialogue(16, 71, 6);
+
+ return selection;
+}
+
+void TransferPartyWiz::drawCharPortraitWithStats(int charIndex, bool enabled) {
+ int16 x = (charIndex % 2) * 159;
+ int16 y = (charIndex / 2) * 40;
+ EoBCharacter *c = &_vm->_characters[charIndex];
+
+ _screen->fillRect(x + 4, y + 24, x + 36, y + 57, 12);
+ _vm->gui_drawBox(x + 40, y + 24, 118, 34, _vm->guiSettings()->colors.frame1, _vm->guiSettings()->colors.frame2, _vm->guiSettings()->colors.fill);
+
+ if (!(c->flags & 1))
+ return;
+
+ _screen->drawShape(_screen->_curPage, c->faceShape, x + 4, y + 25, 0);
+
+ int color1 = 15;
+ int color2 = 12;
+
+ if (enabled) {
+ color1 = 6;
+ color2 = 15;
+ } else {
+ _screen->drawShape(_screen->_curPage, _vm->_disabledCharGrid, x + 4, y + 25, 0);
+ }
+
+ _screen->printShadedText(c->name, x + 44, y + 27, color1, 0);
+ _screen->printText(_vm->_chargenRaceSexStrings[c->raceSex], x + 43, y + 36, color2, 0);
+ _screen->printText(_vm->_chargenClassStrings[c->cClass], x + 43, y + 43, color2, 0);
+
+ Common::String tmp = Common::String::format(_strings1[0], c->level[0]);
+ for (int i = 1; i < _vm->_numLevelsPerClass[c->cClass]; i++)
+ tmp += Common::String::format(_strings1[1], c->level[i]);
+ _screen->printText(tmp.c_str(), x + 43, y + 50, color2, 0);
+}
+
+void TransferPartyWiz::updateHighlight(int index) {
+ static const int16 xPos[] = { 9, 288 };
+ if (_highlight > 5 && _highlight != index)
+ _screen->printText(_labels[_highlight - 6], xPos[_highlight - 6], 151, 15, 0);
+
+ if (index < 6) {
+ _vm->_gui->updateBoxFrameHighLight(14 + index);
+ _highlight = index;
+ return;
+ }
+
+ if (_highlight == index)
+ return;
+
+ if (_highlight < 6)
+ _vm->_gui->updateBoxFrameHighLight(-1);
+
+ _screen->printText(_labels[index - 6], xPos[index - 6], 151, 6, 0);
+ _screen->updateScreen();
+ _highlight = index;
+}
+
+void TransferPartyWiz::convertStats() {
+ for (int i = 0; i < 6; i++) {
+ EoBCharacter *c = &_vm->_characters[i];
+ uint32 aflags = 0;
+
+ for (int ii = 0; ii < 25; ii++) {
+ if (c->mageSpellsAvailableFlags & (1 << ii)) {
+ int8 f = (int8)_convertTable[ii + 1] - 1;
+ if (f != -1)
+ aflags |= (1 << f);
+ }
+ }
+ c->mageSpellsAvailableFlags = aflags;
+
+ c->armorClass = 0;
+ c->disabledSlots = 0;
+ c->flags &= 1;
+ c->hitPointsCur = c->hitPointsMax;
+ c->food = 100;
+
+ c->effectFlags = 0;
+ c->damageTaken = 0;
+ memset(c->clericSpells, 0, sizeof(int8) * 80);
+ memset(c->mageSpells, 0, sizeof(int8) * 80);
+ memset(c->timers, 0, sizeof(uint32) * 10);
+ memset(c->events, 0, sizeof(int8) * 10);
+ memset(c->effectsRemainder, 0, sizeof(uint8) * 4);
+ memset(c->slotStatus, 0, sizeof(int8) * 5);
+
+ for (int ii = 0; ii < 3; ii++) {
+ int t = _vm->getCharacterClassType(c->cClass, ii);
+ if (t == -1)
+ continue;
+ if (c->experience[ii] > _expTable[t])
+ c->experience[ii] = _expTable[t];
+ }
+ }
+}
+
+void TransferPartyWiz::convertInventory() {
+ for (int i = 0; i < 4; i++) {
+ EoBCharacter *c = &_vm->_characters[i];
+
+ for (int slot = 0; slot < 27; slot++) {
+ Item itm = c->inventory[slot];
+ if (slot == 16) {
+ Item first = itm;
+ c->inventory[slot] = 0;
+
+ for (bool forceLoop = true; (itm && (itm != first)) || forceLoop; itm = _oldItems[itm].prev) {
+ forceLoop = false;
+ _vm->setItemPosition(&c->inventory[slot], -2, convertItem(itm), 0);
+ }
+ } else {
+ c->inventory[slot] = convertItem(itm);
+ }
+ }
+ }
+}
+
+Item TransferPartyWiz::convertItem(Item eob1Item) {
+ if (!eob1Item)
+ return 0;
+
+ EoBItem *itm1 = &_oldItems[eob1Item];
+
+ if (!_itemTable[itm1->type])
+ return 0;
+
+ Item newItem = _vm->duplicateItem(1);
+ EoBItem *itm2 = &_vm->_items[newItem];
+ bool match = false;
+
+ itm2->flags = itm1->flags | 0x40;
+ itm2->icon = itm1->icon;
+ itm2->type = itm1->type;
+ itm2->level = 0xff;
+
+ switch (itm2->type) {
+ case 35:
+ itm1->value += 25;
+ // fall through
+ case 34:
+ itm2->value = _convertTable[itm1->value];
+ if (!itm2->value) {
+ itm2->block = -1;
+ return 0;
+ }
+ break;
+ case 39:
+ itm2->value = itm1->value - 1;
+ break;
+ case 48:
+ if (itm1->value == 5) {
+ memset(itm2, 0, sizeof(EoBItem));
+ itm2->block = -1;
+ return 0;
+ }
+ itm2->value = itm1->value;
+ itm2->flags = ((itm1->flags & 0x3f) + 3) | 0x40;
+ break;
+ case 18:
+ itm2->icon = 19;
+ // fall through
+ default:
+ itm2->value = itm1->value;
+ break;
+ }
+
+ switch ((_vm->_itemTypes[itm2->type].extraProperties & 0x7f) - 1) {
+ case 0:
+ case 1:
+ case 2:
+ if (itm2->value)
+ itm2->flags |= 0x80;
+ break;
+ case 4:
+ case 5:
+ case 8:
+ case 9:
+ case 13:
+ case 15:
+ case 17:
+ itm2->flags |= 0x80;
+ break;
+ default:
+ break;
+ }
+
+ for (int i = 1; i < 600; i++) {
+ if (i == 60 || i == 62 || i == 63 || i == 83)
+ continue;
+ EoBItem *tmp = &_vm->_items[i];
+ if (tmp->level || tmp->block == -2 || tmp->type != itm2->type || tmp->icon != itm2->icon)
+ continue;
+ itm2->nameUnid = tmp->nameUnid;
+ itm2->nameId = tmp->nameId;
+ match = true;
+ break;
+ }
+
+ if (!match) {
+ for (int i = 1; i < 600; i++) {
+ if (i == 60 || i == 62 || i == 63 || i == 83)
+ continue;
+ EoBItem *tmp = &_vm->_items[i];
+ if (tmp->level || tmp->block == -2 || tmp->type != itm2->type)
+ continue;
+ itm2->nameUnid = tmp->nameUnid;
+ itm2->nameId = tmp->nameId;
+ match = true;
+ break;
+ }
+ }
+
+ if (!match) {
+ memset(itm2, 0, sizeof(EoBItem));
+ itm2->block = -1;
+ return 0;
+ }
+
+ itm2->level = 0;
+ return newItem;
+}
+
+void TransferPartyWiz::giveKhelbensCoin() {
+ bool success = false;
+ for (int i = 0; i < 4 && !success; i++) {
+ EoBCharacter *c = &_vm->_characters[i];
+
+ for (int slot = 2; slot < 16; slot++) {
+ if (c->inventory[slot])
+ continue;
+ _vm->createInventoryItem(c, 93, -1, slot);
+ success = true;
+ break;
+ }
+ }
+
+ if (!success) {
+ _vm->_characters[0].inventory[2] = 0;
+ _vm->createInventoryItem(&_vm->_characters[0], 93, -1, 2);
+ }
+}
+
+// Start functions
+
+bool EoBCoreEngine::startCharacterGeneration() {
+ return CharacterGenerator(this, _screen).start(_characters, &_faceShapes);
+}
+
+bool EoBCoreEngine::startPartyTransfer() {
+ return TransferPartyWiz(this, _screen).start();
+}
+
+} // End of namespace Kyra
+
+#endif // ENABLE_EOB
diff --git a/engines/kyra/darkmoon.cpp b/engines/kyra/darkmoon.cpp
new file mode 100644
index 0000000000..16bd3dad58
--- /dev/null
+++ b/engines/kyra/darkmoon.cpp
@@ -0,0 +1,471 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifdef ENABLE_EOB
+
+#include "kyra/darkmoon.h"
+#include "kyra/resource.h"
+#include "kyra/sound.h"
+
+namespace Kyra {
+
+DarkMoonEngine::DarkMoonEngine(OSystem *system, const GameFlags &flags) : EoBCoreEngine(system, flags) {
+ _animIntro = _animFinale = 0;
+ _shapesIntro = _shapesFinale = 0;
+ _dscDoorType5Offs = 0;
+ _numSpells = 70;
+ _menuChoiceInit = 4;
+
+ _introStrings = _cpsFilesIntro = _cpsFilesFinale = _finaleStrings = _kheldranStrings = _npcStrings[0] = _npcStrings[1] = _hornStrings = 0;
+ _shapesIntro = _shapesFinale = 0;
+ _creditsData = _npcShpData = _dscDoorType5Offs = _hornSounds = 0;
+ _dreamSteps = 0;
+}
+
+DarkMoonEngine::~DarkMoonEngine() {
+ delete[] _animIntro;
+ delete[] _animFinale;
+ delete[] _shapesIntro;
+ delete[] _shapesFinale;
+}
+
+Common::Error DarkMoonEngine::init() {
+ Common::Error err = EoBCoreEngine::init();
+ if (err.getCode() != Common::kNoError)
+ return err;
+
+ initStaticResource();
+
+ _monsterProps = new EoBMonsterProperty[10];
+
+ if (_configRenderMode == Common::kRenderEGA) {
+ Palette pal(16);
+ _screen->loadPalette(_egaDefaultPalette, pal, 16);
+ _screen->setScreenPalette(pal);
+ }
+
+ _screen->loadPalette("PALETTE.COL", _screen->getPalette(0));
+ _screen->setScreenPalette(_screen->getPalette(0));
+
+ return Common::kNoError;
+}
+
+void DarkMoonEngine::startupNew() {
+ _currentLevel = 4;
+ _currentSub = 0;
+ loadLevel(4, 0);
+ _currentBlock = 171;
+ _currentDirection = 2;
+ setHandItem(0);
+ EoBCoreEngine::startupNew();
+}
+
+void DarkMoonEngine::drawNpcScene(int npcIndex) {
+ const uint8 *shpDef = &_npcShpData[npcIndex << 3];
+ for (int i = npcIndex; i != 255; i = shpDef[7]) {
+ shpDef = &_npcShpData[i << 3];
+ _screen->_curPage = 2;
+ const uint8 *shp = _screen->encodeShape(READ_LE_UINT16(shpDef), shpDef[2], shpDef[3], shpDef[4]);
+ _screen->_curPage = 0;
+ _screen->drawShape(0, shp, 88 + shpDef[5] - (shp[2] << 2), 104 + shpDef[6] - shp[1], 5);
+ delete[] shp;
+ }
+}
+
+void DarkMoonEngine::runNpcDialogue(int npcIndex) {
+ if (npcIndex == 0) {
+ snd_playSoundEffect(57);
+ if (npcJoinDialogue(0, 1, 3, 2))
+ setScriptFlags(0x40);
+ } else if (npcIndex == 1) {
+ snd_playSoundEffect(53);
+ gui_drawDialogueBox();
+
+ _txt->printDialogueText(4, 0);
+ int r = runDialogue(-1, 2, _npcStrings[0][0], _npcStrings[0][1]) - 1;
+
+ if (r == 0) {
+ snd_stopSound();
+ delay(3 * _tickLength);
+ snd_playSoundEffect(91);
+ npcJoinDialogue(1, 5, 6, 7);
+ } else if (r == 1) {
+ setScriptFlags(0x20);
+ }
+
+ } else if (npcIndex == 2) {
+ snd_playSoundEffect(55);
+ gui_drawDialogueBox();
+
+ _txt->printDialogueText(8, 0);
+ int r = runDialogue(-1, 2, _npcStrings[1][0], _npcStrings[1][1]) - 1;
+
+ if (r == 0) {
+ if (rollDice(1, 2, -1))
+ _txt->printDialogueText(9, _okStrings[0]);
+ else
+ npcJoinDialogue(2, 102, 103, 104);
+ setScriptFlags(8);
+ } else if (r == 1) {
+ _currentDirection = 0;
+ }
+ }
+}
+
+void DarkMoonEngine::updateUsedCharacterHandItem(int charIndex, int slot) {
+ EoBItem *itm = &_items[_characters[charIndex].inventory[slot]];
+ if (itm->type == 48 || itm->type == 62) {
+ if (itm->value == 5)
+ return;
+ int charges = itm->flags & 0x3f;
+ if (--charges)
+ --itm->flags;
+ else
+ deleteInventoryItem(charIndex, slot);
+ } else if (itm->type == 26 || itm->type == 34 || itm->type == 35) {
+ deleteInventoryItem(charIndex, slot);
+ }
+}
+
+void DarkMoonEngine::generateMonsterPalettes(const char *file, int16 monsterIndex) {
+ int cp = _screen->setCurPage(2);
+ _screen->loadShapeSetBitmap(file, 3, 3);
+ uint8 tmpPal[16];
+ uint8 newPal[16];
+
+ for (int i = 0; i < 6; i++) {
+ int dci = monsterIndex + i;
+ memcpy(tmpPal, _monsterShapes[dci] + 4, 16);
+ int colx = 302 + 3 * i;
+
+ for (int ii = 0; ii < 16; ii++) {
+ // Don't use getPagePixel() here, since in EGA mode it will try to
+ // undither the pixel (although the shape bitmap is undithered already)
+ uint8 col = _screen->getCPagePtr(_screen->_curPage | 1)[(184 + ii) * Screen::SCREEN_W + colx];
+
+ int iii = 0;
+ for (; iii < 16; iii++) {
+ if (tmpPal[iii] == col) {
+ newPal[ii] = iii;
+ break;
+ }
+ }
+
+ if (iii == 16)
+ newPal[ii] = 0;
+ }
+
+ for (int ii = 1; ii < 3; ii++) {
+ memcpy(tmpPal, _monsterShapes[dci] + 4, 16);
+
+ for (int iii = 0; iii < 16; iii++) {
+ // Don't use getPagePixel() here, since in EGA mode it will try to
+ // undither the pixel (although the shape bitmap is undithered already)
+ uint8 col = _screen->getCPagePtr(_screen->_curPage | 1)[(184 + iii) * Screen::SCREEN_W + colx + ii];
+ if (newPal[iii])
+ tmpPal[newPal[iii]] = col;
+ }
+
+ int c = i;
+ if (monsterIndex >= 18)
+ c += 6;
+
+ c = (c << 1) + (ii - 1);
+ assert(c < 24);
+ memcpy(_monsterPalettes[c], tmpPal, 16);
+ }
+ }
+
+ _screen->setCurPage(cp);
+}
+
+void DarkMoonEngine::loadMonsterDecoration(const char *file, int16 monsterIndex) {
+ Common::SeekableReadStream *s = _res->createReadStream(Common::String::format("%s.dcr", file));
+ if (!s)
+ return;
+
+ int len = s->readUint16LE();
+
+ for (int i = 0; i < len; i++) {
+ for (int ii = 0; ii < 6; ii++) {
+ uint8 dc[6];
+ s->read(dc, 6);
+ if (!dc[2] || !dc[3])
+ continue;
+
+ SpriteDecoration *m = &_monsterDecorations[i * 6 + ii + monsterIndex];
+
+ m->shp = _screen->encodeShape(dc[0], dc[1], dc[2], dc[3]);
+ m->x = (int8)dc[4];
+ m->y = (int8)dc[5];
+ }
+ }
+
+ delete s;
+}
+
+void DarkMoonEngine::replaceMonster(int unit, uint16 block, int pos, int dir, int type, int shpIndex, int mode, int h2, int randItem, int fixedItem) {
+ uint8 flg = _levelBlockProperties[block].flags & 7;
+
+ if (flg == 7 || _currentBlock == block || (flg && (_monsterProps[type].u30 || pos == 4)))
+ return;
+
+ for (int i = 0; i < 30; i++) {
+ if (_monsters[i].block != block)
+ continue;
+ if (_monsters[i].pos == 4 || _monsterProps[_monsters[i].type].u30)
+ return;
+ }
+
+ int index = -1;
+ int maxDist = 0;
+
+ for (int i = 0; i < 30; i++) {
+ if (_monsters[i].hitPointsCur <= 0) {
+ index = i;
+ break;
+ }
+
+ if (_monsters[i].flags & 0x40)
+ continue;
+
+ int dist = getBlockDistance(_monsters[i].block, _currentBlock);
+
+ if (dist > maxDist) {
+ maxDist = dist;
+ index = i;
+ }
+ }
+
+ if (index == -1)
+ return;
+
+ if (_monsters[index].hitPointsCur > 0)
+ killMonster(&_monsters[index], false);
+
+ initMonster(index, unit, block, pos, dir, type, shpIndex, mode, h2, randItem, fixedItem);
+}
+
+bool DarkMoonEngine::killMonsterExtra(EoBMonsterInPlay *m) {
+ if (_currentLevel == 16 && _currentSub == 1 && (_monsterProps[m->type].capsFlags & 4)) {
+ if (m->type) {
+ _playFinale = true;
+ _runFlag = false;
+ delay(850);
+ } else {
+ m->hitPointsCur = 150;
+ m->curRemoteWeapon = 0;
+ m->numRemoteAttacks = 255;
+ m->shpIndex++;
+ m->type++;
+ seq_dranDragonTransformation();
+ }
+ return false;
+ }
+ return true;
+}
+
+const uint8 *DarkMoonEngine::loadDoorShapes(const char *filename, int doorIndex, const uint8 *shapeDefs) {
+ _screen->loadShapeSetBitmap(filename, 3, 3);
+ for (int i = 0; i < 3; i++) {
+ _doorShapes[doorIndex * 3 + i] = _screen->encodeShape(READ_LE_UINT16(shapeDefs), READ_LE_UINT16(shapeDefs + 2), READ_LE_UINT16(shapeDefs + 4), READ_LE_UINT16(shapeDefs + 6));
+ shapeDefs += 8;
+ }
+
+ for (int i = 0; i < 2; i++) {
+ _doorSwitches[doorIndex * 3 + i].shp = _screen->encodeShape(READ_LE_UINT16(shapeDefs), READ_LE_UINT16(shapeDefs + 2), READ_LE_UINT16(shapeDefs + 4), READ_LE_UINT16(shapeDefs + 6));
+ shapeDefs += 8;
+ _doorSwitches[doorIndex * 3 + i].x = *shapeDefs;
+ shapeDefs += 2;
+ _doorSwitches[doorIndex * 3 + i].y = *shapeDefs;
+ shapeDefs += 2;
+ }
+ _screen->_curPage = 0;
+ return shapeDefs;
+}
+
+void DarkMoonEngine::drawDoorIntern(int type, int, int x, int y, int w, int wall, int mDim, int16, int16) {
+ int shapeIndex = type * 3 + 2 - mDim;
+ uint8 *shp = _doorShapes[shapeIndex];
+ if (!shp)
+ return;
+
+ if ((_doorType[type] == 0) || (_doorType[type] == 1)) {
+ y = _dscDoorY1[mDim] - shp[1];
+ x -= (shp[2] << 2);
+
+ if (_doorType[type] == 1) {
+ drawBlockObject(0, 2, shp, x, y, 5);
+ shp = _doorShapes[3 + shapeIndex];
+ }
+
+ y -= ((wall - _dscDoorScaleOffs[wall]) * _dscDoorScaleMult1[mDim]);
+
+ if (_specialWallTypes[wall] == 5)
+ y -= _dscDoorType5Offs[shapeIndex];
+
+ } else if (_doorType[type] == 2) {
+ x -= (shp[2] << 2);
+ y = _dscDoorY2[mDim] - ((wall - _dscDoorScaleOffs[wall]) * _dscDoorScaleMult3[mDim]);
+ }
+
+ drawBlockObject(0, 2, shp, x, y, 5);
+
+ if (_wllShapeMap[wall] == -1 && !_noDoorSwitch[type])
+ drawBlockObject(0, 2, _doorSwitches[shapeIndex].shp, _doorSwitches[shapeIndex].x + w, _doorSwitches[shapeIndex].y, 5);
+}
+
+void DarkMoonEngine::restParty_npc() {
+ int insalId = -1;
+ int numChar = 0;
+
+ for (int i = 0; i < 6; i++) {
+ if (!testCharacter(i, 1))
+ continue;
+ if (testCharacter(i, 2) && _characters[i].portrait == -1)
+ insalId = i;
+ numChar++;
+ }
+
+ if (insalId == -1 || numChar < 5)
+ return;
+
+ removeCharacterFromParty(insalId);
+ if (insalId < 4)
+ exchangeCharacters(insalId, testCharacter(5, 1) ? 5 : 4);
+
+ clearScriptFlags(6);
+
+ if (!stripPartyItems(1, 1, 1, 1))
+ stripPartyItems(2, 1, 1, 1);
+ stripPartyItems(31, 0, 1, 3);
+ stripPartyItems(39, 1, 0, 3);
+ stripPartyItems(47, 0, 1, 2);
+
+ _items[createItemOnCurrentBlock(28)].value = 26;
+
+ gui_drawPlayField(false);
+ gui_drawAllCharPortraitsWithStats();
+
+ _screen->setClearScreenDim(10);
+ _gui->messageDialogue2(11, 63, 6);
+ _gui->messageDialogue2(11, 64, 6);
+}
+
+bool DarkMoonEngine::restParty_extraAbortCondition() {
+ if (_currentLevel != 3)
+ return false;
+
+ seq_nightmare();
+
+ return true;
+}
+
+void DarkMoonEngine::useHorn(int charIndex, int weaponSlot) {
+ int v = _items[_characters[charIndex].inventory[weaponSlot]].value - 1;
+ _txt->printMessage(_hornStrings[v]);
+ snd_playSoundEffect(_hornSounds[v]);
+}
+
+bool DarkMoonEngine::checkPartyStatusExtra() {
+ if (checkScriptFlags(0x100000))
+ seq_kheldran();
+ return _gui->confirmDialogue2(14, 67, 1);
+}
+
+void DarkMoonEngine::drawLightningColumn() {
+ int f = rollDice(1, 2, -1);
+ int y = 0;
+
+ for (int i = 0; i < 6; i++) {
+ f ^= 1;
+ drawBlockObject(f, 2, _lightningColumnShape, 72, y, 5);
+ y += 64;
+ }
+}
+
+int DarkMoonEngine::resurrectionSelectDialogue() {
+ countResurrectionCandidates();
+
+ _rrNames[_rrCount] = _abortStrings[0];
+ _rrId[_rrCount++] = 99;
+
+ int r = _rrId[runDialogue(-1, 9, _rrNames[0], _rrNames[1], _rrNames[2], _rrNames[3], _rrNames[4], _rrNames[5], _rrNames[6], _rrNames[7], _rrNames[8]) - 1];
+ if (r == 99)
+ return 0;
+
+ if (r < 0) {
+ r = -r;
+ if (prepareForNewPartyMember(33, r))
+ initNpc(r - 1);
+ } else {
+ _characters[r].hitPointsCur = 1;
+ }
+
+ return 1;
+}
+
+int DarkMoonEngine::charSelectDialogue() {
+ int cnt = 0;
+ const char *namesList[7];
+ memset(namesList, 0, 7 * sizeof(const char *));
+
+ for (int i = 0; i < 6; i++) {
+ if (!testCharacter(i, 3))
+ continue;
+ namesList[cnt++] = _characters[i].name;
+ }
+
+ namesList[cnt++] = _abortStrings[0];
+
+ int r = runDialogue(-1, 7, namesList[0], namesList[1], namesList[2], namesList[3], namesList[4], namesList[5], namesList[6]) - 1;
+ if (r == cnt - 1)
+ return 99;
+
+ for (cnt = 0; cnt < 6; cnt++) {
+ if (!testCharacter(cnt, 3))
+ continue;
+ if (--r < 0)
+ break;
+ }
+ return cnt;
+}
+
+void DarkMoonEngine::characterLevelGain(int charIndex) {
+ EoBCharacter *c = &_characters[charIndex];
+ int s = _numLevelsPerClass[c->cClass];
+ for (int i = 0; i < s; i++) {
+ uint32 er = getRequiredExperience(c->cClass, i, c->level[i] + 1);
+ if (er == 0xffffffff)
+ continue;
+
+ increaseCharacterExperience(charIndex, er - c->experience[i] + 1);
+ }
+}
+
+const KyraRpgGUISettings *DarkMoonEngine::guiSettings() {
+ return &_guiSettings;
+}
+
+} // End of namespace Kyra
+
+#endif // ENABLE_EOB
diff --git a/engines/kyra/darkmoon.h b/engines/kyra/darkmoon.h
new file mode 100644
index 0000000000..f6e7b3ed2c
--- /dev/null
+++ b/engines/kyra/darkmoon.h
@@ -0,0 +1,147 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifdef ENABLE_EOB
+
+#ifndef KYRA_EOB2_H
+#define KYRA_EOB2_H
+
+#include "kyra/eobcommon.h"
+
+namespace Kyra {
+
+class DarkmoonSequenceHelper;
+
+struct DarkMoonAnimCommand {
+ uint8 command;
+ uint8 obj;
+ int16 x1;
+ uint8 y1;
+ uint8 delay;
+ uint8 pal;
+ uint8 x2;
+ uint8 y2;
+ uint8 w;
+ uint8 h;
+};
+
+class DarkMoonEngine : public EoBCoreEngine {
+friend class GUI_EoB;
+friend class DarkmoonSequenceHelper;
+public:
+ DarkMoonEngine(OSystem *system, const GameFlags &flags);
+ ~DarkMoonEngine();
+
+private:
+ // Init / Release
+ Common::Error init();
+ void initStaticResource();
+ void initSpells();
+
+ // Main Menu
+ int mainMenu();
+ int mainMenuLoop();
+
+ int _menuChoiceInit;
+
+ // Main loop
+ void startupNew();
+ void startupLoad() {}
+
+ // Intro/Outro
+ void seq_playIntro();
+ void seq_playFinale();
+ void seq_playCredits(DarkmoonSequenceHelper *sq, const uint8 *data, int sd, int backupPage, int tempPage, int speed);
+
+ const char * const *_introStrings;
+ const char * const *_cpsFilesIntro;
+ const DarkMoonAnimCommand **_animIntro;
+ const DarkMoonShapeDef **_shapesIntro;
+
+ const char * const *_finaleStrings;
+ const uint8 *_creditsData;
+ const char * const *_cpsFilesFinale;
+ const DarkMoonAnimCommand **_animFinale;
+ const DarkMoonShapeDef **_shapesFinale;
+
+ static const char *_palFilesIntroVGA[];
+ static const char *_palFilesIntroEGA[];
+ static const char *_palFilesFinaleVGA[];
+ static const char *_palFilesFinaleEGA[];
+
+ // Ingame sequence
+ void seq_nightmare();
+ void seq_kheldran();
+ void seq_dranDragonTransformation();
+
+ const int8 *_dreamSteps;
+ const char *const *_kheldranStrings;
+
+ // characters
+ void drawNpcScene(int npcIndex);
+ void runNpcDialogue(int npcIndex);
+
+ const uint8 *_npcShpData;
+ const char *const *_npcStrings[2];
+
+ // items
+ void updateUsedCharacterHandItem(int charIndex, int slot);
+
+ // Monsters
+ void generateMonsterPalettes(const char *file, int16 monsterIndex);
+ void loadMonsterDecoration(const char *file, int16 monsterIndex);
+ void replaceMonster(int unit, uint16 block, int d, int dir, int type, int shpIndex, int mode, int h2, int randItem, int fixedItem);
+ bool killMonsterExtra(EoBMonsterInPlay *m);
+
+ // Level
+ void loadDoorShapes(int doorType1, int shapeId1, int doorType2, int shapeId2) {}
+ const uint8 *loadDoorShapes(const char *filename, int doorIndex, const uint8 *shapeDefs);
+ void drawDoorIntern(int type, int, int x, int y, int w, int wall, int mDim, int16, int16);
+
+ const uint8 *_dscDoorType5Offs;
+
+ // Rest party
+ void restParty_npc();
+ bool restParty_extraAbortCondition();
+
+ // misc
+ void useHorn(int charIndex, int weaponSlot);
+ bool checkPartyStatusExtra();
+ void drawLightningColumn();
+ int resurrectionSelectDialogue();
+ int charSelectDialogue();
+ void characterLevelGain(int charIndex);
+
+ const KyraRpgGUISettings *guiSettings();
+
+ const char *const *_hornStrings;
+ const uint8 *_hornSounds;
+
+ static const KyraRpgGUISettings _guiSettings;
+ static const uint8 _egaDefaultPalette[];
+};
+
+} // End of namespace Kyra
+
+#endif
+
+#endif // ENABLE_EOB
diff --git a/engines/kyra/debugger.cpp b/engines/kyra/debugger.cpp
index dfc2a9f868..c0a91ac098 100644
--- a/engines/kyra/debugger.cpp
+++ b/engines/kyra/debugger.cpp
@@ -26,25 +26,30 @@
#include "kyra/timer.h"
#include "kyra/resource.h"
#include "kyra/lol.h"
+#include "kyra/eobcommon.h"
#include "common/system.h"
+#include "common/config-manager.h"
+
+#include "gui/message.h"
namespace Kyra {
Debugger::Debugger(KyraEngine_v1 *vm)
- : ::GUI::Debugger() {
- _vm = vm;
+ : ::GUI::Debugger(), _vm(vm) {
+}
- DCmd_Register("continue", WRAP_METHOD(Debugger, Cmd_Exit));
- DCmd_Register("screen_debug_mode", WRAP_METHOD(Debugger, cmd_setScreenDebug));
- DCmd_Register("load_palette", WRAP_METHOD(Debugger, cmd_loadPalette));
- DCmd_Register("facings", WRAP_METHOD(Debugger, cmd_showFacings));
- DCmd_Register("gamespeed", WRAP_METHOD(Debugger, cmd_gameSpeed));
- DCmd_Register("flags", WRAP_METHOD(Debugger, cmd_listFlags));
- DCmd_Register("toggleflag", WRAP_METHOD(Debugger, cmd_toggleFlag));
- DCmd_Register("queryflag", WRAP_METHOD(Debugger, cmd_queryFlag));
- DCmd_Register("timers", WRAP_METHOD(Debugger, cmd_listTimers));
- DCmd_Register("settimercountdown", WRAP_METHOD(Debugger, cmd_setTimerCountdown));
+void Debugger::initialize() {
+ DCmd_Register("continue", WRAP_METHOD(Debugger, Cmd_Exit));
+ DCmd_Register("screen_debug_mode", WRAP_METHOD(Debugger, cmd_setScreenDebug));
+ DCmd_Register("load_palette", WRAP_METHOD(Debugger, cmd_loadPalette));
+ DCmd_Register("facings", WRAP_METHOD(Debugger, cmd_showFacings));
+ DCmd_Register("gamespeed", WRAP_METHOD(Debugger, cmd_gameSpeed));
+ DCmd_Register("flags", WRAP_METHOD(Debugger, cmd_listFlags));
+ DCmd_Register("toggleflag", WRAP_METHOD(Debugger, cmd_toggleFlag));
+ DCmd_Register("queryflag", WRAP_METHOD(Debugger, cmd_queryFlag));
+ DCmd_Register("timers", WRAP_METHOD(Debugger, cmd_listTimers));
+ DCmd_Register("settimercountdown", WRAP_METHOD(Debugger, cmd_setTimerCountdown));
}
bool Debugger::cmd_setScreenDebug(int argc, const char **argv) {
@@ -134,7 +139,7 @@ bool Debugger::cmd_gameSpeed(int argc, const char **argv) {
}
bool Debugger::cmd_listFlags(int argc, const char **argv) {
- for (int i = 0, p = 0; i < (int)sizeof(_vm->_flagsTable)*8; i++, ++p) {
+ for (int i = 0, p = 0; i < (int)sizeof(_vm->_flagsTable) * 8; i++, ++p) {
DebugPrintf("(%-3i): %-2i", i, _vm->queryGameFlag(i));
if (p == 5) {
DebugPrintf("\n");
@@ -196,10 +201,14 @@ bool Debugger::cmd_setTimerCountdown(int argc, const char **argv) {
Debugger_LoK::Debugger_LoK(KyraEngine_LoK *vm)
: Debugger(vm), _vm(vm) {
- DCmd_Register("enter", WRAP_METHOD(Debugger_LoK, cmd_enterRoom));
- DCmd_Register("scenes", WRAP_METHOD(Debugger_LoK, cmd_listScenes));
- DCmd_Register("give", WRAP_METHOD(Debugger_LoK, cmd_giveItem));
- DCmd_Register("birthstones", WRAP_METHOD(Debugger_LoK, cmd_listBirthstones));
+}
+
+void Debugger_LoK::initialize() {
+ DCmd_Register("enter", WRAP_METHOD(Debugger_LoK, cmd_enterRoom));
+ DCmd_Register("scenes", WRAP_METHOD(Debugger_LoK, cmd_listScenes));
+ DCmd_Register("give", WRAP_METHOD(Debugger_LoK, cmd_giveItem));
+ DCmd_Register("birthstones", WRAP_METHOD(Debugger_LoK, cmd_listBirthstones));
+ Debugger::initialize();
}
bool Debugger_LoK::cmd_enterRoom(int argc, const char **argv) {
@@ -209,7 +218,7 @@ bool Debugger_LoK::cmd_enterRoom(int argc, const char **argv) {
// game will crash if entering a non-existent room
if (room >= _vm->_roomTableSize) {
- DebugPrintf("room number must be any value between (including) 0 and %d\n", _vm->_roomTableSize-1);
+ DebugPrintf("room number must be any value between (including) 0 and %d\n", _vm->_roomTableSize - 1);
return true;
}
@@ -281,12 +290,16 @@ bool Debugger_LoK::cmd_listBirthstones(int argc, const char **argv) {
#pragma mark -
Debugger_v2::Debugger_v2(KyraEngine_v2 *vm) : Debugger(vm), _vm(vm) {
- DCmd_Register("character_info", WRAP_METHOD(Debugger_v2, cmd_characterInfo));
- DCmd_Register("enter", WRAP_METHOD(Debugger_v2, cmd_enterScene));
- DCmd_Register("scenes", WRAP_METHOD(Debugger_v2, cmd_listScenes));
- DCmd_Register("scene_info", WRAP_METHOD(Debugger_v2, cmd_sceneInfo));
- DCmd_Register("scene_to_facing", WRAP_METHOD(Debugger_v2, cmd_sceneToFacing));
- DCmd_Register("give", WRAP_METHOD(Debugger_v2, cmd_giveItem));
+}
+
+void Debugger_v2::initialize() {
+ DCmd_Register("character_info", WRAP_METHOD(Debugger_v2, cmd_characterInfo));
+ DCmd_Register("enter", WRAP_METHOD(Debugger_v2, cmd_enterScene));
+ DCmd_Register("scenes", WRAP_METHOD(Debugger_v2, cmd_listScenes));
+ DCmd_Register("scene_info", WRAP_METHOD(Debugger_v2, cmd_sceneInfo));
+ DCmd_Register("scene_to_facing", WRAP_METHOD(Debugger_v2, cmd_sceneToFacing));
+ DCmd_Register("give", WRAP_METHOD(Debugger_v2, cmd_giveItem));
+ Debugger::initialize();
}
bool Debugger_v2::cmd_enterScene(int argc, const char **argv) {
@@ -296,7 +309,7 @@ bool Debugger_v2::cmd_enterScene(int argc, const char **argv) {
// game will crash if entering a non-existent scene
if (scene >= _vm->_sceneListSize) {
- DebugPrintf("scene number must be any value between (including) 0 and %d\n", _vm->_sceneListSize-1);
+ DebugPrintf("scene number must be any value between (including) 0 and %d\n", _vm->_sceneListSize - 1);
return true;
}
@@ -358,8 +371,8 @@ bool Debugger_v2::cmd_sceneInfo(int argc, const char **argv) {
DebugPrintf("This scene has %d special exits.\n", _vm->_specialExitCount);
for (int i = 0; i < _vm->_specialExitCount; ++i) {
DebugPrintf("SpecialExit%d: facing %d, position (x1/y1/x2/y2): %d/%d/%d/%d\n", i,
- _vm->_specialExitTable[20+i], _vm->_specialExitTable[0+i], _vm->_specialExitTable[5+i],
- _vm->_specialExitTable[10+i], _vm->_specialExitTable[15+i]);
+ _vm->_specialExitTable[20 + i], _vm->_specialExitTable[0 + i], _vm->_specialExitTable[5 + i],
+ _vm->_specialExitTable[10 + i], _vm->_specialExitTable[15 + i]);
}
}
@@ -433,7 +446,11 @@ bool Debugger_v2::cmd_giveItem(int argc, const char **argv) {
#pragma mark -
Debugger_HoF::Debugger_HoF(KyraEngine_HoF *vm) : Debugger_v2(vm), _vm(vm) {
- DCmd_Register("pass_codes", WRAP_METHOD(Debugger_HoF, cmd_passcodes));
+}
+
+void Debugger_HoF::initialize() {
+ DCmd_Register("pass_codes", WRAP_METHOD(Debugger_HoF, cmd_passcodes));
+ Debugger_v2::initialize();
}
bool Debugger_HoF::cmd_passcodes(int argc, const char **argv) {
@@ -460,4 +477,36 @@ Debugger_LoL::Debugger_LoL(LoLEngine *vm) : Debugger(vm), _vm(vm) {
}
#endif // ENABLE_LOL
+#ifdef ENABLE_EOB
+Debugger_EoB::Debugger_EoB(EoBCoreEngine *vm) : Debugger(vm), _vm(vm) {
+}
+
+void Debugger_EoB::initialize() {
+ DCmd_Register("import_savefile", WRAP_METHOD(Debugger_EoB, cmd_importSaveFile));
+}
+
+bool Debugger_EoB::cmd_importSaveFile(int argc, const char **argv) {
+ if (!_vm->_allowImport) {
+ DebugPrintf("This command may only be used from the main menu.\n");
+ return true;
+ }
+
+ if (argc == 3) {
+ int slot = atoi(argv[1]);
+ if (slot < -1 || slot > 989) {
+ DebugPrintf("slot must be between (including) -1 and 989 \n");
+ return true;
+ }
+
+ DebugPrintf(_vm->importOriginalSaveFile(slot, argv[2]) ? "Success.\n" : "Failure.\n");
+ _vm->loadItemDefs();
+ } else {
+ DebugPrintf("Syntax: import_savefile <dest slot> <source file>\n (Imports source save game file to dest slot.)\n import_savefile -1\n (Imports all original save game files found and puts them into the first available slots.)\n\n");
+ }
+
+ return true;
+}
+
+#endif // ENABLE_EOB
+
} // End of namespace Kyra
diff --git a/engines/kyra/debugger.h b/engines/kyra/debugger.h
index 09ddd89a7a..2b1dcbe505 100644
--- a/engines/kyra/debugger.h
+++ b/engines/kyra/debugger.h
@@ -37,6 +37,8 @@ public:
Debugger(KyraEngine_v1 *vm);
virtual ~Debugger() {} // we need this for __SYMBIAN32__ archaic gcc/UIQ
+ virtual void initialize();
+
protected:
KyraEngine_v1 *_vm;
@@ -56,6 +58,7 @@ public:
Debugger_LoK(KyraEngine_LoK *vm);
virtual ~Debugger_LoK() {} // we need this for __SYMBIAN32__ archaic gcc/UIQ
+ virtual void initialize();
protected:
KyraEngine_LoK *_vm;
@@ -70,6 +73,7 @@ public:
Debugger_v2(KyraEngine_v2 *vm);
virtual ~Debugger_v2() {}
+ virtual void initialize();
protected:
KyraEngine_v2 *_vm;
@@ -85,6 +89,7 @@ class Debugger_HoF : public Debugger_v2 {
public:
Debugger_HoF(KyraEngine_HoF *vm);
+ virtual void initialize();
protected:
KyraEngine_HoF *_vm;
@@ -103,6 +108,21 @@ protected:
};
#endif // ENABLE_LOL
+#ifdef ENABLE_EOB
+class EoBCoreEngine;
+
+class Debugger_EoB : public Debugger {
+public:
+ Debugger_EoB(EoBCoreEngine *vm);
+
+ virtual void initialize();
+protected:
+ EoBCoreEngine *_vm;
+
+ bool cmd_importSaveFile(int argc, const char **argv);
+};
+#endif // ENABLE_EOB
+
} // End of namespace Kyra
#endif
diff --git a/engines/kyra/detection.cpp b/engines/kyra/detection.cpp
index 68eb08210e..46dfec84ff 100644
--- a/engines/kyra/detection.cpp
+++ b/engines/kyra/detection.cpp
@@ -17,12 +17,15 @@
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
*/
#include "kyra/kyra_lok.h"
#include "kyra/lol.h"
#include "kyra/kyra_hof.h"
#include "kyra/kyra_mr.h"
+#include "kyra/eob.h"
+#include "kyra/darkmoon.h"
#include "common/config-manager.h"
#include "common/system.h"
@@ -42,7 +45,7 @@ struct KYRAGameDescription {
namespace {
-const char * const directoryGlobs[] = {
+const char *const directoryGlobs[] = {
"malcolm",
0
};
@@ -63,9 +66,12 @@ public:
const char *getOriginalCopyright() const {
return "The Legend of Kyrandia (C) Westwood Studios"
#ifdef ENABLE_LOL
- "\nLands of Lore (C) Westwood Studios"
+ "\nLands of Lore (C) Westwood Studios"
+#endif
+#ifdef ENABLE_EOB
+ "\nEye of the Beholder (C) TSR, Inc., (C) Strategic Simulations, Inc."
#endif
- ;
+ ;
}
bool hasFeature(MetaEngineFeature f) const;
@@ -78,19 +84,19 @@ public:
bool KyraMetaEngine::hasFeature(MetaEngineFeature f) const {
return
- (f == kSupportsListSaves) ||
- (f == kSupportsLoadingDuringStartup) ||
- (f == kSupportsDeleteSave) ||
- (f == kSavesSupportMetaInfo) ||
- (f == kSavesSupportThumbnail);
+ (f == kSupportsListSaves) ||
+ (f == kSupportsLoadingDuringStartup) ||
+ (f == kSupportsDeleteSave) ||
+ (f == kSavesSupportMetaInfo) ||
+ (f == kSavesSupportThumbnail);
}
bool Kyra::KyraEngine_v1::hasFeature(EngineFeature f) const {
return
- (f == kSupportsRTL) ||
- (f == kSupportsLoadingDuringRuntime) ||
- (f == kSupportsSavingDuringRuntime) ||
- (f == kSupportsSubtitleOptions);
+ (f == kSupportsRTL) ||
+ (f == kSupportsLoadingDuringRuntime) ||
+ (f == kSupportsSavingDuringRuntime) ||
+ (f == kSupportsSubtitleOptions);
}
bool KyraMetaEngine::createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const {
@@ -129,6 +135,16 @@ bool KyraMetaEngine::createInstance(OSystem *syst, Engine **engine, const ADGame
*engine = new Kyra::LoLEngine(syst, flags);
break;
#endif // ENABLE_LOL
+#ifdef ENABLE_EOB
+ case Kyra::GI_EOB1:
+ *engine = new Kyra::EoBEngine(syst, flags);
+ break;
+ case Kyra::GI_EOB2:
+ if (Common::parseRenderMode(ConfMan.get("render_mode")) == Common::kRenderEGA)
+ flags.useHiRes = true;
+ *engine = new Kyra::DarkMoonEngine(syst, flags);
+ break;
+#endif // ENABLE_EOB
default:
res = false;
warning("Kyra engine: unknown gameID");
@@ -145,10 +161,14 @@ SaveStateList KyraMetaEngine::listSaves(const char *target) const {
Common::StringArray filenames;
filenames = saveFileMan->listSavefiles(pattern);
- Common::sort(filenames.begin(), filenames.end()); // Sort (hopefully ensuring we are sorted numerically..)
+ Common::sort(filenames.begin(), filenames.end()); // Sort (hopefully ensuring we are sorted numerically..)
SaveStateList saveList;
for (Common::StringArray::const_iterator file = filenames.begin(); file != filenames.end(); ++file) {
+ // Skip automatic final saves made by EOB for the purpose of party transfer
+ if (!scumm_stricmp(file->c_str() + file->size() - 3, "fin"))
+ continue;
+
// Obtain the last 3 digits of the filename, since they correspond to the save slot
int slotNum = atoi(file->c_str() + file->size() - 3);
@@ -171,13 +191,15 @@ SaveStateList KyraMetaEngine::listSaves(const char *target) const {
return saveList;
}
-int KyraMetaEngine::getMaximumSaveSlot() const { return 999; }
+int KyraMetaEngine::getMaximumSaveSlot() const {
+ return 999;
+}
void KyraMetaEngine::removeSaveState(const char *target, int slot) const {
// In Kyra games slot 0 can't be deleted, it's for restarting the game(s).
// An exception makes Lands of Lore here, it does not have any way to restart the
// game except via its main menu.
- if (slot == 0 && !ConfMan.getDomain(target)->getVal("gameid").equalsIgnoreCase("lol"))
+ if (slot == 0 && !ConfMan.getDomain(target)->getVal("gameid").equalsIgnoreCase("lol") && !ConfMan.getDomain(target)->getVal("gameid").equalsIgnoreCase("eob") && !ConfMan.getDomain(target)->getVal("gameid").equalsIgnoreCase("eob2"))
return;
Common::String filename = Kyra::KyraEngine_v1::getSavegameFilename(target, slot);
@@ -187,7 +209,7 @@ void KyraMetaEngine::removeSaveState(const char *target, int slot) const {
SaveStateDescriptor KyraMetaEngine::querySaveMetaInfos(const char *target, int slot) const {
Common::String filename = Kyra::KyraEngine_v1::getSavegameFilename(target, slot);
Common::InSaveFile *in = g_system->getSavefileManager()->openForLoading(filename);
- const bool lolGame = ConfMan.getDomain(target)->getVal("gameid").equalsIgnoreCase("lol");
+ const bool nonKyraGame = ConfMan.getDomain(target)->getVal("gameid").equalsIgnoreCase("lol") || ConfMan.getDomain(target)->getVal("gameid").equalsIgnoreCase("eob") || ConfMan.getDomain(target)->getVal("gameid").equalsIgnoreCase("eob2");
if (in) {
Kyra::KyraEngine_v1::SaveHeader header;
@@ -201,12 +223,12 @@ SaveStateDescriptor KyraMetaEngine::querySaveMetaInfos(const char *target, int s
// Slot 0 is used for the 'restart game' save in all three Kyrandia games, thus
// we prevent it from being deleted.
- desc.setDeletableFlag(slot != 0 || lolGame);
+ desc.setDeletableFlag(slot != 0 || nonKyraGame);
// We don't allow quick saves (slot 990 till 998) to be overwritten.
// The same goes for the 'Autosave', which is slot 999. Slot 0 will also
// be protected in Kyra 1-3, since it's the 'restart game' save.
- desc.setWriteProtectedFlag((slot == 0 && !lolGame) || slot >= 990);
+ desc.setWriteProtectedFlag((slot == 0 && !nonKyraGame) || slot >= 990);
desc.setThumbnail(header.thumbnail);
return desc;
@@ -218,7 +240,7 @@ SaveStateDescriptor KyraMetaEngine::querySaveMetaInfos(const char *target, int s
// We don't allow quick saves (slot 990 till 998) to be overwritten.
// The same goes for the 'Autosave', which is slot 999. Slot 0 will also
// be protected in Kyra 1-3, since it's the 'restart game' save.
- desc.setWriteProtectedFlag((slot == 0 && !lolGame) || slot >= 990);
+ desc.setWriteProtectedFlag((slot == 0 && !nonKyraGame) || slot >= 990);
return desc;
}
diff --git a/engines/kyra/detection_tables.h b/engines/kyra/detection_tables.h
index 5c1e9df408..204c49cd2c 100644
--- a/engines/kyra/detection_tables.h
+++ b/engines/kyra/detection_tables.h
@@ -57,6 +57,9 @@ namespace {
#define LOL_DEMO_FLAGS FLAGS(true, true, false, false, false, false, false, false, Kyra::GI_LOL)
#define LOL_KYRA2_DEMO_FLAGS FLAGS(true, false, false, false, false, false, false, false, Kyra::GI_KYRA2)
+#define EOB_FLAGS FLAGS(false, false, false, false, false, false, false, false, Kyra::GI_EOB1)
+#define EOB2_FLAGS FLAGS(false, false, false, false, false, false, false, false, Kyra::GI_EOB2)
+
const KYRAGameDescription adGameDescs[] = {
/* disable these targets until they get supported
{
@@ -94,7 +97,7 @@ const KYRAGameDescription adGameDescs[] = {
Common::EN_ANY,
Common::kPlatformPC,
ADGF_NO_FLAGS,
- GUIO4(GUIO_NOSPEECH, GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIPCSPK)
+ GUIO5(GUIO_NOSPEECH, GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIPCSPK, GUIO_RENDERVGA)
},
KYRA1_FLOPPY_FLAGS
},
@@ -107,7 +110,7 @@ const KYRAGameDescription adGameDescs[] = {
Common::EN_ANY,
Common::kPlatformPC,
ADGF_NO_FLAGS,
- GUIO4(GUIO_NOSPEECH, GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIPCSPK)
+ GUIO5(GUIO_NOSPEECH, GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIPCSPK, GUIO_RENDERVGA)
},
KYRA1_FLOPPY_FLAGS
},
@@ -119,7 +122,7 @@ const KYRAGameDescription adGameDescs[] = {
Common::FR_FRA,
Common::kPlatformPC,
ADGF_NO_FLAGS,
- GUIO4(GUIO_NOSPEECH, GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIPCSPK)
+ GUIO5(GUIO_NOSPEECH, GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIPCSPK, GUIO_RENDERVGA)
},
KYRA1_FLOPPY_FLAGS
},
@@ -131,7 +134,7 @@ const KYRAGameDescription adGameDescs[] = {
Common::DE_DEU,
Common::kPlatformPC,
ADGF_NO_FLAGS,
- GUIO4(GUIO_NOSPEECH, GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIPCSPK)
+ GUIO5(GUIO_NOSPEECH, GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIPCSPK, GUIO_RENDERVGA)
},
KYRA1_FLOPPY_FLAGS
},
@@ -143,7 +146,7 @@ const KYRAGameDescription adGameDescs[] = {
Common::DE_DEU,
Common::kPlatformPC,
ADGF_NO_FLAGS,
- GUIO4(GUIO_NOSPEECH, GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIPCSPK)
+ GUIO5(GUIO_NOSPEECH, GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIPCSPK, GUIO_RENDERVGA)
},
KYRA1_FLOPPY_FLAGS
},
@@ -155,7 +158,7 @@ const KYRAGameDescription adGameDescs[] = {
Common::RU_RUS,
Common::kPlatformPC,
ADGF_NO_FLAGS,
- GUIO4(GUIO_NOSPEECH, GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIPCSPK)
+ GUIO5(GUIO_NOSPEECH, GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIPCSPK, GUIO_RENDERVGA)
},
KYRA1_OLDFLOPPY_FLAGS
},
@@ -167,7 +170,7 @@ const KYRAGameDescription adGameDescs[] = {
Common::ES_ESP,
Common::kPlatformPC,
ADGF_NO_FLAGS,
- GUIO4(GUIO_NOSPEECH, GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIPCSPK)
+ GUIO5(GUIO_NOSPEECH, GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIPCSPK, GUIO_RENDERVGA)
},
KYRA1_FLOPPY_FLAGS
},
@@ -179,7 +182,7 @@ const KYRAGameDescription adGameDescs[] = {
Common::ES_ESP,
Common::kPlatformPC,
ADGF_NO_FLAGS,
- GUIO4(GUIO_NOSPEECH, GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIPCSPK)
+ GUIO5(GUIO_NOSPEECH, GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIPCSPK, GUIO_RENDERVGA)
},
KYRA1_FLOPPY_FLAGS
},
@@ -191,7 +194,7 @@ const KYRAGameDescription adGameDescs[] = {
Common::IT_ITA,
Common::kPlatformPC,
ADGF_NO_FLAGS,
- GUIO4(GUIO_NOSPEECH, GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIPCSPK)
+ GUIO5(GUIO_NOSPEECH, GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIPCSPK, GUIO_RENDERVGA)
},
KYRA1_FLOPPY_FLAGS
},
@@ -208,7 +211,7 @@ const KYRAGameDescription adGameDescs[] = {
Common::EN_ANY,
Common::kPlatformAmiga,
ADGF_NO_FLAGS,
- GUIO2(GUIO_NOSPEECH, GUIO_MIDIAMIGA)
+ GUIO3(GUIO_NOSPEECH, GUIO_MIDIAMIGA, GUIO_RENDERAMIGA)
},
KYRA1_AMIGA_FLAGS
},
@@ -225,7 +228,7 @@ const KYRAGameDescription adGameDescs[] = {
Common::DE_DEU,
Common::kPlatformAmiga,
ADGF_NO_FLAGS,
- GUIO2(GUIO_NOSPEECH, GUIO_MIDIAMIGA)
+ GUIO3(GUIO_NOSPEECH, GUIO_MIDIAMIGA, GUIO_RENDERAMIGA)
},
KYRA1_AMIGA_FLAGS
},
@@ -242,7 +245,7 @@ const KYRAGameDescription adGameDescs[] = {
Common::EN_ANY,
Common::kPlatformMacintosh,
ADGF_NO_FLAGS,
- GUIO2(GUIO_NOSPEECH, GUIO_MIDIGM)
+ GUIO3(GUIO_NOSPEECH, GUIO_MIDIGM, GUIO_RENDERVGA)
},
KYRA1_FLOPPY_FLAGS
},
@@ -259,7 +262,7 @@ const KYRAGameDescription adGameDescs[] = {
Common::EN_ANY,
Common::kPlatformFMTowns,
ADGF_NO_FLAGS,
- GUIO2(GUIO_NOSPEECH, GUIO_MIDITOWNS)
+ GUIO3(GUIO_NOSPEECH, GUIO_MIDITOWNS, GUIO_RENDERFMTOWNS)
},
KYRA1_TOWNS_FLAGS
},
@@ -275,7 +278,7 @@ const KYRAGameDescription adGameDescs[] = {
Common::JA_JPN,
Common::kPlatformFMTowns,
ADGF_NO_FLAGS,
- GUIO2(GUIO_NOSPEECH, GUIO_MIDITOWNS)
+ GUIO3(GUIO_NOSPEECH, GUIO_MIDITOWNS, GUIO_RENDERFMTOWNS)
},
KYRA1_TOWNS_SJIS_FLAGS
},
@@ -294,7 +297,7 @@ const KYRAGameDescription adGameDescs[] = {
Common::JA_JPN,
Common::kPlatformPC98,
ADGF_NO_FLAGS,
- GUIO2(GUIO_NOSPEECH, GUIO_MIDIPC98)
+ GUIO4(GUIO_NOSPEECH, GUIO_MIDIPC98, GUIO_RENDERPC9821, GUIO_RENDERPC9801)
},
KYRA1_TOWNS_SJIS_FLAGS
},
@@ -307,7 +310,7 @@ const KYRAGameDescription adGameDescs[] = {
Common::EN_ANY,
Common::kPlatformPC,
ADGF_CD,
- GUIO3(GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIPCSPK)
+ GUIO4(GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIPCSPK, GUIO_RENDERVGA)
},
KYRA1_CD_FLAGS
},
@@ -319,7 +322,7 @@ const KYRAGameDescription adGameDescs[] = {
Common::DE_DEU,
Common::kPlatformPC,
ADGF_CD,
- GUIO3(GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIPCSPK)
+ GUIO4(GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIPCSPK, GUIO_RENDERVGA)
},
KYRA1_CD_FLAGS
},
@@ -331,7 +334,7 @@ const KYRAGameDescription adGameDescs[] = {
Common::FR_FRA,
Common::kPlatformPC,
ADGF_CD,
- GUIO3(GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIPCSPK)
+ GUIO4(GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIPCSPK, GUIO_RENDERVGA)
},
KYRA1_CD_FLAGS
},
@@ -344,7 +347,7 @@ const KYRAGameDescription adGameDescs[] = {
Common::IT_ITA,
Common::kPlatformPC,
ADGF_CD,
- GUIO3(GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIPCSPK)
+ GUIO4(GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIPCSPK, GUIO_RENDERVGA)
},
KYRA1_CD_FLAGS
},
@@ -361,7 +364,7 @@ const KYRAGameDescription adGameDescs[] = {
Common::EN_ANY,
Common::kPlatformMacintosh,
ADGF_CD,
- GUIO1(GUIO_NONE)
+ GUIO0()
},
KYRA1_CD_FLAGS
},
@@ -377,7 +380,7 @@ const KYRAGameDescription adGameDescs[] = {
Common::DE_DEU,
Common::kPlatformMacintosh,
ADGF_CD,
- GUIO1(GUIO_NONE)
+ GUIO0()
},
KYRA1_CD_FLAGS
},
@@ -393,7 +396,7 @@ const KYRAGameDescription adGameDescs[] = {
Common::FR_FRA,
Common::kPlatformMacintosh,
ADGF_CD,
- GUIO1(GUIO_NONE)
+ GUIO0()
},
KYRA1_CD_FLAGS
},
@@ -406,7 +409,7 @@ const KYRAGameDescription adGameDescs[] = {
Common::EN_ANY,
Common::kPlatformPC,
ADGF_DEMO,
- GUIO4(GUIO_NOSPEECH, GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIPCSPK)
+ GUIO5(GUIO_NOSPEECH, GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIPCSPK, GUIO_RENDERVGA)
},
KYRA1_DEMO_FLAGS
},
@@ -419,7 +422,7 @@ const KYRAGameDescription adGameDescs[] = {
Common::EN_ANY,
Common::kPlatformPC,
ADGF_DEMO | ADGF_CD,
- GUIO3(GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIPCSPK)
+ GUIO4(GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIPCSPK, GUIO_RENDERVGA)
},
KYRA1_DEMO_CD_FLAGS
},
@@ -432,7 +435,7 @@ const KYRAGameDescription adGameDescs[] = {
Common::EN_ANY,
Common::kPlatformPC,
ADGF_NO_FLAGS,
- GUIO5(GUIO_NOSPEECH, GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIGM, GUIO_MIDIPCSPK)
+ GUIO6(GUIO_NOSPEECH, GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIGM, GUIO_MIDIPCSPK, GUIO_RENDERVGA)
},
KYRA2_FLOPPY_CMP_FLAGS
},
@@ -445,7 +448,7 @@ const KYRAGameDescription adGameDescs[] = {
Common::DE_DEU,
Common::kPlatformPC,
ADGF_NO_FLAGS,
- GUIO5(GUIO_NOSPEECH, GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIGM, GUIO_MIDIPCSPK)
+ GUIO6(GUIO_NOSPEECH, GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIGM, GUIO_MIDIPCSPK, GUIO_RENDERVGA)
},
KYRA2_FLOPPY_CMP_FLAGS
},
@@ -458,7 +461,7 @@ const KYRAGameDescription adGameDescs[] = {
Common::EN_ANY,
Common::kPlatformPC,
ADGF_NO_FLAGS,
- GUIO5(GUIO_NOSPEECH, GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIGM, GUIO_MIDIPCSPK)
+ GUIO6(GUIO_NOSPEECH, GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIGM, GUIO_MIDIPCSPK, GUIO_RENDERVGA)
},
KYRA2_FLOPPY_FLAGS
},
@@ -471,7 +474,7 @@ const KYRAGameDescription adGameDescs[] = {
Common::DE_DEU,
Common::kPlatformPC,
ADGF_NO_FLAGS,
- GUIO5(GUIO_NOSPEECH, GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIGM, GUIO_MIDIPCSPK)
+ GUIO6(GUIO_NOSPEECH, GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIGM, GUIO_MIDIPCSPK, GUIO_RENDERVGA)
},
KYRA2_FLOPPY_FLAGS
},
@@ -484,7 +487,7 @@ const KYRAGameDescription adGameDescs[] = {
Common::FR_FRA,
Common::kPlatformPC,
ADGF_NO_FLAGS,
- GUIO5(GUIO_NOSPEECH, GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIGM, GUIO_MIDIPCSPK)
+ GUIO6(GUIO_NOSPEECH, GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIGM, GUIO_MIDIPCSPK, GUIO_RENDERVGA)
},
KYRA2_FLOPPY_FLAGS
},
@@ -497,7 +500,7 @@ const KYRAGameDescription adGameDescs[] = {
Common::IT_ITA,
Common::kPlatformPC,
ADGF_NO_FLAGS,
- GUIO5(GUIO_NOSPEECH, GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIGM, GUIO_MIDIPCSPK)
+ GUIO6(GUIO_NOSPEECH, GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIGM, GUIO_MIDIPCSPK, GUIO_RENDERVGA)
},
KYRA2_FLOPPY_FLAGS
},
@@ -510,7 +513,7 @@ const KYRAGameDescription adGameDescs[] = {
Common::RU_RUS,
Common::kPlatformPC,
ADGF_NO_FLAGS,
- GUIO5(GUIO_NOSPEECH, GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIGM, GUIO_MIDIPCSPK)
+ GUIO6(GUIO_NOSPEECH, GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIGM, GUIO_MIDIPCSPK, GUIO_RENDERVGA)
},
KYRA2_FLOPPY_FAN_FLAGS(Common::RU_RUS, Common::EN_ANY)
},
@@ -523,7 +526,7 @@ const KYRAGameDescription adGameDescs[] = {
Common::RU_RUS,
Common::kPlatformPC,
ADGF_NO_FLAGS,
- GUIO5(GUIO_NOSPEECH, GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIGM, GUIO_MIDIPCSPK)
+ GUIO6(GUIO_NOSPEECH, GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIGM, GUIO_MIDIPCSPK, GUIO_RENDERVGA)
},
KYRA2_FLOPPY_FAN_FLAGS(Common::RU_RUS, Common::EN_ANY)
},
@@ -536,7 +539,7 @@ const KYRAGameDescription adGameDescs[] = {
Common::EN_ANY,
Common::kPlatformPC,
ADGF_DROPLANGUAGE | ADGF_CD,
- GUIO4(GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIGM, GUIO_MIDIPCSPK)
+ GUIO5(GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIGM, GUIO_MIDIPCSPK, GUIO_RENDERVGA)
},
KYRA2_CD_FLAGS
},
@@ -548,7 +551,7 @@ const KYRAGameDescription adGameDescs[] = {
Common::DE_DEU,
Common::kPlatformPC,
ADGF_DROPLANGUAGE | ADGF_CD,
- GUIO4(GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIGM, GUIO_MIDIPCSPK)
+ GUIO5(GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIGM, GUIO_MIDIPCSPK, GUIO_RENDERVGA)
},
KYRA2_CD_FLAGS
},
@@ -560,7 +563,7 @@ const KYRAGameDescription adGameDescs[] = {
Common::FR_FRA,
Common::kPlatformPC,
ADGF_DROPLANGUAGE | ADGF_CD,
- GUIO4(GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIGM, GUIO_MIDIPCSPK)
+ GUIO5(GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIGM, GUIO_MIDIPCSPK, GUIO_RENDERVGA)
},
KYRA2_CD_FLAGS
},
@@ -574,7 +577,7 @@ const KYRAGameDescription adGameDescs[] = {
Common::IT_ITA,
Common::kPlatformPC,
ADGF_DROPLANGUAGE | ADGF_CD,
- GUIO4(GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIGM, GUIO_MIDIPCSPK)
+ GUIO5(GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIGM, GUIO_MIDIPCSPK, GUIO_RENDERVGA)
},
KYRA2_CD_FAN_FLAGS(Common::IT_ITA, Common::EN_ANY)
},
@@ -586,7 +589,7 @@ const KYRAGameDescription adGameDescs[] = {
Common::DE_DEU,
Common::kPlatformPC,
ADGF_DROPLANGUAGE | ADGF_CD,
- GUIO4(GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIGM, GUIO_MIDIPCSPK)
+ GUIO5(GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIGM, GUIO_MIDIPCSPK, GUIO_RENDERVGA)
},
KYRA2_CD_FAN_FLAGS(Common::IT_ITA, Common::EN_ANY)
},
@@ -598,7 +601,7 @@ const KYRAGameDescription adGameDescs[] = {
Common::FR_FRA,
Common::kPlatformPC,
ADGF_DROPLANGUAGE | ADGF_CD,
- GUIO4(GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIGM, GUIO_MIDIPCSPK)
+ GUIO5(GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIGM, GUIO_MIDIPCSPK, GUIO_RENDERVGA)
},
KYRA2_CD_FAN_FLAGS(Common::IT_ITA, Common::EN_ANY)
},
@@ -611,7 +614,7 @@ const KYRAGameDescription adGameDescs[] = {
Common::IT_ITA,
Common::kPlatformPC,
ADGF_DROPLANGUAGE | ADGF_CD,
- GUIO4(GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIGM, GUIO_MIDIPCSPK)
+ GUIO5(GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIGM, GUIO_MIDIPCSPK, GUIO_RENDERVGA)
},
KYRA2_CD_FAN_FLAGS(Common::IT_ITA, Common::EN_ANY)
},
@@ -624,7 +627,7 @@ const KYRAGameDescription adGameDescs[] = {
Common::DE_DEU,
Common::kPlatformPC,
ADGF_DROPLANGUAGE | ADGF_CD,
- GUIO4(GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIGM, GUIO_MIDIPCSPK)
+ GUIO5(GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIGM, GUIO_MIDIPCSPK, GUIO_RENDERVGA)
},
KYRA2_CD_FAN_FLAGS(Common::IT_ITA, Common::EN_ANY)
},
@@ -637,11 +640,25 @@ const KYRAGameDescription adGameDescs[] = {
Common::FR_FRA,
Common::kPlatformPC,
ADGF_DROPLANGUAGE | ADGF_CD,
- GUIO4(GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIGM, GUIO_MIDIPCSPK)
+ GUIO5(GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIGM, GUIO_MIDIPCSPK, GUIO_RENDERVGA)
},
KYRA2_CD_FAN_FLAGS(Common::IT_ITA, Common::EN_ANY)
},
+ // Russian fan translation
+ { // CD version
+ {
+ "kyra2",
+ "CD",
+ AD_ENTRY1("FERRY.CPS", "763e2103858347d4ffffc329910d323f"),
+ Common::RU_RUS,
+ Common::kPlatformPC,
+ ADGF_DROPLANGUAGE | ADGF_CD,
+ GUIO5(GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIGM, GUIO_MIDIPCSPK, GUIO_RENDERVGA)
+ },
+ KYRA2_CD_FAN_FLAGS(Common::RU_RUS, Common::EN_ANY)
+ },
+
{ // Interactive Demo
{
"kyra2",
@@ -650,7 +667,7 @@ const KYRAGameDescription adGameDescs[] = {
Common::EN_ANY,
Common::kPlatformPC,
ADGF_DROPLANGUAGE | ADGF_CD | ADGF_DEMO,
- GUIO4(GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIGM, GUIO_MIDIPCSPK)
+ GUIO5(GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIGM, GUIO_MIDIPCSPK, GUIO_RENDERVGA)
},
KYRA2_CD_DEMO_FLAGS
},
@@ -663,7 +680,7 @@ const KYRAGameDescription adGameDescs[] = {
Common::DE_DEU,
Common::kPlatformPC,
ADGF_DROPLANGUAGE | ADGF_CD | ADGF_DEMO,
- GUIO4(GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIGM, GUIO_MIDIPCSPK)
+ GUIO5(GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIGM, GUIO_MIDIPCSPK, GUIO_RENDERVGA)
},
KYRA2_CD_DEMO_FLAGS
},
@@ -676,7 +693,7 @@ const KYRAGameDescription adGameDescs[] = {
Common::FR_FRA,
Common::kPlatformPC,
ADGF_DROPLANGUAGE | ADGF_CD | ADGF_DEMO,
- GUIO4(GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIGM, GUIO_MIDIPCSPK)
+ GUIO5(GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIGM, GUIO_MIDIPCSPK, GUIO_RENDERVGA)
},
KYRA2_CD_DEMO_FLAGS
},
@@ -689,7 +706,7 @@ const KYRAGameDescription adGameDescs[] = {
Common::EN_ANY,
Common::kPlatformPC,
ADGF_DEMO,
- GUIO4(GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIGM, GUIO_MIDIPCSPK)
+ GUIO5(GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIGM, GUIO_MIDIPCSPK, GUIO_RENDERVGA)
},
KYRA2_DEMO_FLAGS
},
@@ -702,7 +719,7 @@ const KYRAGameDescription adGameDescs[] = {
Common::EN_ANY,
Common::kPlatformFMTowns,
ADGF_NO_FLAGS,
- GUIO2(GUIO_NOSPEECH, GUIO_MIDITOWNS)
+ GUIO3(GUIO_NOSPEECH, GUIO_MIDITOWNS, GUIO_RENDERFMTOWNS)
},
KYRA2_TOWNS_FLAGS
},
@@ -714,7 +731,7 @@ const KYRAGameDescription adGameDescs[] = {
Common::JA_JPN,
Common::kPlatformFMTowns,
ADGF_NO_FLAGS,
- GUIO2(GUIO_NOSPEECH, GUIO_MIDITOWNS)
+ GUIO3(GUIO_NOSPEECH, GUIO_MIDITOWNS, GUIO_RENDERFMTOWNS)
},
KYRA2_TOWNS_SJIS_FLAGS
},
@@ -726,7 +743,7 @@ const KYRAGameDescription adGameDescs[] = {
Common::EN_ANY,
Common::kPlatformPC98,
ADGF_CD,
- GUIO2(GUIO_NOSPEECH, GUIO_MIDIPC98)
+ GUIO3(GUIO_NOSPEECH, GUIO_MIDIPC98, GUIO_RENDERPC9821)
},
KYRA2_TOWNS_FLAGS
},
@@ -738,7 +755,7 @@ const KYRAGameDescription adGameDescs[] = {
Common::JA_JPN,
Common::kPlatformPC98,
ADGF_CD,
- GUIO2(GUIO_NOSPEECH, GUIO_MIDIPC98)
+ GUIO3(GUIO_NOSPEECH, GUIO_MIDIPC98, GUIO_RENDERPC9821)
},
KYRA2_TOWNS_SJIS_FLAGS
},
@@ -758,7 +775,7 @@ const KYRAGameDescription adGameDescs[] = {
Common::EN_ANY,
Common::kPlatformPC,
ADGF_DROPLANGUAGE,
- GUIO1(GUIO_NOMIDI)
+ GUIO2(GUIO_NOMIDI, GUIO_RENDERVGA)
},
KYRA3_CD_FLAGS
},
@@ -774,7 +791,7 @@ const KYRAGameDescription adGameDescs[] = {
Common::DE_DEU,
Common::kPlatformPC,
ADGF_DROPLANGUAGE,
- GUIO1(GUIO_NOMIDI)
+ GUIO2(GUIO_NOMIDI, GUIO_RENDERVGA)
},
KYRA3_CD_FLAGS
},
@@ -790,7 +807,7 @@ const KYRAGameDescription adGameDescs[] = {
Common::FR_FRA,
Common::kPlatformPC,
ADGF_DROPLANGUAGE,
- GUIO1(GUIO_NOMIDI)
+ GUIO2(GUIO_NOMIDI, GUIO_RENDERVGA)
},
KYRA3_CD_FLAGS
},
@@ -808,7 +825,7 @@ const KYRAGameDescription adGameDescs[] = {
Common::EN_ANY,
Common::kPlatformPC,
ADGF_DROPLANGUAGE,
- GUIO1(GUIO_NOMIDI)
+ GUIO2(GUIO_NOMIDI, GUIO_RENDERVGA)
},
KYRA3_CD_INS_FLAGS
},
@@ -824,7 +841,7 @@ const KYRAGameDescription adGameDescs[] = {
Common::DE_DEU,
Common::kPlatformPC,
ADGF_DROPLANGUAGE,
- GUIO1(GUIO_NOMIDI)
+ GUIO2(GUIO_NOMIDI, GUIO_RENDERVGA)
},
KYRA3_CD_INS_FLAGS
},
@@ -840,7 +857,7 @@ const KYRAGameDescription adGameDescs[] = {
Common::FR_FRA,
Common::kPlatformPC,
ADGF_DROPLANGUAGE,
- GUIO1(GUIO_NOMIDI)
+ GUIO2(GUIO_NOMIDI, GUIO_RENDERVGA)
},
KYRA3_CD_INS_FLAGS
},
@@ -858,7 +875,7 @@ const KYRAGameDescription adGameDescs[] = {
Common::EN_ANY,
Common::kPlatformMacintosh,
ADGF_DROPLANGUAGE,
- GUIO1(GUIO_NOMIDI)
+ GUIO2(GUIO_NOMIDI, GUIO_RENDERVGA)
},
KYRA3_CD_INS_FLAGS
},
@@ -874,7 +891,7 @@ const KYRAGameDescription adGameDescs[] = {
Common::DE_DEU,
Common::kPlatformMacintosh,
ADGF_DROPLANGUAGE,
- GUIO1(GUIO_NOMIDI)
+ GUIO2(GUIO_NOMIDI, GUIO_RENDERVGA)
},
KYRA3_CD_INS_FLAGS
},
@@ -890,7 +907,7 @@ const KYRAGameDescription adGameDescs[] = {
Common::FR_FRA,
Common::kPlatformMacintosh,
ADGF_DROPLANGUAGE,
- GUIO1(GUIO_NOMIDI)
+ GUIO2(GUIO_NOMIDI, GUIO_RENDERVGA)
},
KYRA3_CD_INS_FLAGS
},
@@ -908,7 +925,7 @@ const KYRAGameDescription adGameDescs[] = {
Common::ES_ESP,
Common::kPlatformPC,
ADGF_DROPLANGUAGE,
- GUIO1(GUIO_NOMIDI)
+ GUIO2(GUIO_NOMIDI, GUIO_RENDERVGA)
},
KYRA3_CD_FAN_FLAGS(Common::ES_ESP, Common::EN_ANY)
},
@@ -924,7 +941,7 @@ const KYRAGameDescription adGameDescs[] = {
Common::DE_DEU,
Common::kPlatformPC,
ADGF_DROPLANGUAGE,
- GUIO1(GUIO_NOMIDI)
+ GUIO2(GUIO_NOMIDI, GUIO_RENDERVGA)
},
KYRA3_CD_FAN_FLAGS(Common::ES_ESP, Common::EN_ANY)
},
@@ -940,7 +957,7 @@ const KYRAGameDescription adGameDescs[] = {
Common::FR_FRA,
Common::kPlatformPC,
ADGF_DROPLANGUAGE,
- GUIO1(GUIO_NOMIDI)
+ GUIO2(GUIO_NOMIDI, GUIO_RENDERVGA)
},
KYRA3_CD_FAN_FLAGS(Common::ES_ESP, Common::EN_ANY)
},
@@ -958,7 +975,7 @@ const KYRAGameDescription adGameDescs[] = {
Common::EN_ANY,
Common::kPlatformPC,
ADGF_DROPLANGUAGE,
- GUIO1(GUIO_NOMIDI)
+ GUIO2(GUIO_NOMIDI, GUIO_RENDERVGA)
},
KYRA3_CD_FAN_FLAGS(Common::IT_ITA, Common::FR_FRA)
},
@@ -974,7 +991,7 @@ const KYRAGameDescription adGameDescs[] = {
Common::DE_DEU,
Common::kPlatformPC,
ADGF_DROPLANGUAGE,
- GUIO1(GUIO_NOMIDI)
+ GUIO2(GUIO_NOMIDI, GUIO_RENDERVGA)
},
KYRA3_CD_FAN_FLAGS(Common::IT_ITA, Common::FR_FRA)
},
@@ -990,7 +1007,7 @@ const KYRAGameDescription adGameDescs[] = {
Common::IT_ITA,
Common::kPlatformPC,
ADGF_DROPLANGUAGE,
- GUIO1(GUIO_NOMIDI)
+ GUIO2(GUIO_NOMIDI, GUIO_RENDERVGA)
},
KYRA3_CD_FAN_FLAGS(Common::IT_ITA, Common::FR_FRA)
},
@@ -1009,7 +1026,7 @@ const KYRAGameDescription adGameDescs[] = {
Common::EN_ANY,
Common::kPlatformPC,
ADGF_DROPLANGUAGE | ADGF_CD,
- GUIO4(GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIGM, GUIO_MIDIPCSPK)
+ GUIO5(GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIGM, GUIO_MIDIPCSPK, GUIO_RENDERVGA)
},
LOL_CD_FLAGS
},
@@ -1026,7 +1043,7 @@ const KYRAGameDescription adGameDescs[] = {
Common::DE_DEU,
Common::kPlatformPC,
ADGF_DROPLANGUAGE | ADGF_CD,
- GUIO4(GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIGM, GUIO_MIDIPCSPK)
+ GUIO5(GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIGM, GUIO_MIDIPCSPK, GUIO_RENDERVGA)
},
LOL_CD_FLAGS
},
@@ -1043,7 +1060,7 @@ const KYRAGameDescription adGameDescs[] = {
Common::FR_FRA,
Common::kPlatformPC,
ADGF_DROPLANGUAGE | ADGF_CD,
- GUIO4(GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIGM, GUIO_MIDIPCSPK)
+ GUIO5(GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIGM, GUIO_MIDIPCSPK, GUIO_RENDERVGA)
},
LOL_CD_FLAGS
},
@@ -1060,7 +1077,7 @@ const KYRAGameDescription adGameDescs[] = {
Common::EN_ANY,
Common::kPlatformPC,
ADGF_DROPLANGUAGE | ADGF_CD,
- GUIO4(GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIGM, GUIO_MIDIPCSPK)
+ GUIO5(GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIGM, GUIO_MIDIPCSPK, GUIO_RENDERVGA)
},
LOL_CD_FLAGS
},
@@ -1077,7 +1094,7 @@ const KYRAGameDescription adGameDescs[] = {
Common::DE_DEU,
Common::kPlatformPC,
ADGF_DROPLANGUAGE | ADGF_CD,
- GUIO4(GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIGM, GUIO_MIDIPCSPK)
+ GUIO5(GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIGM, GUIO_MIDIPCSPK, GUIO_RENDERVGA)
},
LOL_CD_FLAGS
},
@@ -1094,7 +1111,7 @@ const KYRAGameDescription adGameDescs[] = {
Common::FR_FRA,
Common::kPlatformPC,
ADGF_DROPLANGUAGE | ADGF_CD,
- GUIO4(GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIGM, GUIO_MIDIPCSPK)
+ GUIO5(GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIGM, GUIO_MIDIPCSPK, GUIO_RENDERVGA)
},
LOL_CD_FLAGS
},
@@ -1112,7 +1129,7 @@ const KYRAGameDescription adGameDescs[] = {
Common::EN_ANY,
Common::kPlatformPC,
ADGF_DROPLANGUAGE | ADGF_CD,
- GUIO4(GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIGM, GUIO_MIDIPCSPK)
+ GUIO5(GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIGM, GUIO_MIDIPCSPK, GUIO_RENDERVGA)
},
LOL_CD_FAN_FLAGS(Common::RU_RUS, Common::DE_DEU)
},
@@ -1130,7 +1147,7 @@ const KYRAGameDescription adGameDescs[] = {
Common::FR_FRA,
Common::kPlatformPC,
ADGF_DROPLANGUAGE | ADGF_CD,
- GUIO4(GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIGM, GUIO_MIDIPCSPK)
+ GUIO5(GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIGM, GUIO_MIDIPCSPK, GUIO_RENDERVGA)
},
LOL_CD_FAN_FLAGS(Common::RU_RUS, Common::DE_DEU)
},
@@ -1147,7 +1164,7 @@ const KYRAGameDescription adGameDescs[] = {
Common::RU_RUS,
Common::kPlatformPC,
ADGF_DROPLANGUAGE | ADGF_CD,
- GUIO4(GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIGM, GUIO_MIDIPCSPK)
+ GUIO5(GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIGM, GUIO_MIDIPCSPK, GUIO_RENDERVGA)
},
LOL_CD_FAN_FLAGS(Common::RU_RUS, Common::DE_DEU)
},
@@ -1165,7 +1182,7 @@ const KYRAGameDescription adGameDescs[] = {
Common::IT_ITA,
Common::kPlatformPC,
ADGF_DROPLANGUAGE | ADGF_CD,
- GUIO4(GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIGM, GUIO_MIDIPCSPK)
+ GUIO5(GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIGM, GUIO_MIDIPCSPK, GUIO_RENDERVGA)
},
LOL_CD_FAN_FLAGS(Common::IT_ITA, Common::EN_ANY)
},
@@ -1182,7 +1199,7 @@ const KYRAGameDescription adGameDescs[] = {
Common::DE_DEU,
Common::kPlatformPC,
ADGF_DROPLANGUAGE | ADGF_CD,
- GUIO4(GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIGM, GUIO_MIDIPCSPK)
+ GUIO5(GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIGM, GUIO_MIDIPCSPK, GUIO_RENDERVGA)
},
LOL_CD_FAN_FLAGS(Common::IT_ITA, Common::EN_ANY)
},
@@ -1199,7 +1216,7 @@ const KYRAGameDescription adGameDescs[] = {
Common::FR_FRA,
Common::kPlatformPC,
ADGF_DROPLANGUAGE | ADGF_CD,
- GUIO4(GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIGM, GUIO_MIDIPCSPK)
+ GUIO5(GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIGM, GUIO_MIDIPCSPK, GUIO_RENDERVGA)
},
LOL_CD_FAN_FLAGS(Common::IT_ITA, Common::EN_ANY)
},
@@ -1216,7 +1233,7 @@ const KYRAGameDescription adGameDescs[] = {
Common::IT_ITA,
Common::kPlatformPC,
ADGF_DROPLANGUAGE | ADGF_CD,
- GUIO4(GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIGM, GUIO_MIDIPCSPK)
+ GUIO5(GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIGM, GUIO_MIDIPCSPK, GUIO_RENDERVGA)
},
LOL_CD_FAN_FLAGS(Common::IT_ITA, Common::EN_ANY)
},
@@ -1233,7 +1250,7 @@ const KYRAGameDescription adGameDescs[] = {
Common::DE_DEU,
Common::kPlatformPC,
ADGF_DROPLANGUAGE | ADGF_CD,
- GUIO4(GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIGM, GUIO_MIDIPCSPK)
+ GUIO5(GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIGM, GUIO_MIDIPCSPK, GUIO_RENDERVGA)
},
LOL_CD_FAN_FLAGS(Common::IT_ITA, Common::EN_ANY)
},
@@ -1250,7 +1267,7 @@ const KYRAGameDescription adGameDescs[] = {
Common::FR_FRA,
Common::kPlatformPC,
ADGF_DROPLANGUAGE | ADGF_CD,
- GUIO4(GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIGM, GUIO_MIDIPCSPK)
+ GUIO5(GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIGM, GUIO_MIDIPCSPK, GUIO_RENDERVGA)
},
LOL_CD_FAN_FLAGS(Common::IT_ITA, Common::EN_ANY)
},
@@ -1266,7 +1283,7 @@ const KYRAGameDescription adGameDescs[] = {
Common::EN_ANY,
Common::kPlatformPC,
ADGF_NO_FLAGS,
- GUIO5(GUIO_NOSPEECH, GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIGM, GUIO_MIDIPCSPK)
+ GUIO6(GUIO_NOSPEECH, GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIGM, GUIO_MIDIPCSPK, GUIO_RENDERVGA)
},
LOL_FLOPPY_CMP_FLAGS
},
@@ -1282,7 +1299,7 @@ const KYRAGameDescription adGameDescs[] = {
Common::EN_ANY,
Common::kPlatformPC,
ADGF_NO_FLAGS,
- GUIO5(GUIO_NOSPEECH, GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIGM, GUIO_MIDIPCSPK)
+ GUIO6(GUIO_NOSPEECH, GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIGM, GUIO_MIDIPCSPK, GUIO_RENDERVGA)
},
LOL_FLOPPY_CMP_FLAGS
},
@@ -1298,7 +1315,7 @@ const KYRAGameDescription adGameDescs[] = {
Common::DE_DEU,
Common::kPlatformPC,
ADGF_NO_FLAGS,
- GUIO5(GUIO_NOSPEECH, GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIGM, GUIO_MIDIPCSPK)
+ GUIO6(GUIO_NOSPEECH, GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIGM, GUIO_MIDIPCSPK, GUIO_RENDERVGA)
},
LOL_FLOPPY_CMP_FLAGS
},
@@ -1315,7 +1332,7 @@ const KYRAGameDescription adGameDescs[] = {
Common::EN_ANY,
Common::kPlatformPC,
ADGF_NO_FLAGS,
- GUIO5(GUIO_NOSPEECH, GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIGM, GUIO_MIDIPCSPK)
+ GUIO6(GUIO_NOSPEECH, GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIGM, GUIO_MIDIPCSPK, GUIO_RENDERVGA)
},
LOL_FLOPPY_FLAGS
},
@@ -1332,7 +1349,7 @@ const KYRAGameDescription adGameDescs[] = {
Common::EN_ANY,
Common::kPlatformPC,
ADGF_NO_FLAGS,
- GUIO5(GUIO_NOSPEECH, GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIGM, GUIO_MIDIPCSPK)
+ GUIO6(GUIO_NOSPEECH, GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIGM, GUIO_MIDIPCSPK, GUIO_RENDERVGA)
},
LOL_FLOPPY_FLAGS
},
@@ -1349,7 +1366,7 @@ const KYRAGameDescription adGameDescs[] = {
Common::EN_ANY,
Common::kPlatformPC,
ADGF_NO_FLAGS,
- GUIO5(GUIO_NOSPEECH, GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIGM, GUIO_MIDIPCSPK)
+ GUIO6(GUIO_NOSPEECH, GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIGM, GUIO_MIDIPCSPK, GUIO_RENDERVGA)
},
LOL_FLOPPY_FLAGS
},
@@ -1366,7 +1383,7 @@ const KYRAGameDescription adGameDescs[] = {
Common::DE_DEU,
Common::kPlatformPC,
ADGF_NO_FLAGS,
- GUIO5(GUIO_NOSPEECH, GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIGM, GUIO_MIDIPCSPK)
+ GUIO6(GUIO_NOSPEECH, GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIGM, GUIO_MIDIPCSPK, GUIO_RENDERVGA)
},
LOL_FLOPPY_FLAGS
},
@@ -1384,7 +1401,7 @@ const KYRAGameDescription adGameDescs[] = {
Common::RU_RUS,
Common::kPlatformPC,
ADGF_NO_FLAGS,
- GUIO5(GUIO_NOSPEECH, GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIGM, GUIO_MIDIPCSPK)
+ GUIO6(GUIO_NOSPEECH, GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIGM, GUIO_MIDIPCSPK, GUIO_RENDERVGA)
},
LOL_FLOPPY_FAN_FLAGS(Common::RU_RUS, Common::EN_ANY)
},
@@ -1401,7 +1418,7 @@ const KYRAGameDescription adGameDescs[] = {
Common::JA_JPN,
Common::kPlatformPC98,
ADGF_NO_FLAGS,
- GUIO2(GUIO_NOSPEECH, GUIO_MIDIPC98)
+ GUIO3(GUIO_NOSPEECH, GUIO_MIDIPC98, GUIO_RENDERPC9801)
},
LOL_PC98_SJIS_FLAGS
},
@@ -1418,7 +1435,7 @@ const KYRAGameDescription adGameDescs[] = {
Common::EN_ANY,
Common::kPlatformPC,
ADGF_DEMO,
- GUIO4(GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIGM, GUIO_MIDIPCSPK)
+ GUIO5(GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIGM, GUIO_MIDIPCSPK, GUIO_RENDERVGA)
},
LOL_DEMO_FLAGS
},
@@ -1434,11 +1451,78 @@ const KYRAGameDescription adGameDescs[] = {
Common::EN_ANY,
Common::kPlatformPC,
ADGF_DEMO,
- GUIO4(GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIGM, GUIO_MIDIPCSPK)
+ GUIO5(GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIGM, GUIO_MIDIPCSPK, GUIO_RENDERVGA)
},
LOL_KYRA2_DEMO_FLAGS
},
#endif // ENABLE_LOL
+#ifdef ENABLE_EOB
+
+ {
+ {
+ "eob",
+ 0,
+ {
+ { "EOBDATA3.PAK", 0, "61aff543131bd61a8b7d7dc901a8278b", -1 },
+ { 0, 0, 0, 0 }
+ },
+ Common::EN_ANY,
+ Common::kPlatformPC,
+ ADGF_TESTING,
+ GUIO6(GUIO_NOSPEECH, GUIO_MIDIADLIB, GUIO_MIDIPCSPK, GUIO_RENDERVGA, GUIO_RENDEREGA, GUIO_RENDERCGA)
+ },
+ EOB_FLAGS
+ },
+
+ {
+ {
+ "eob",
+ 0,
+ {
+ { "TEXT.DAT", 0, "fb59b50f97fd1806756911d986b9b2b5", -1 },
+ { 0, 0, 0, 0 }
+ },
+ Common::DE_DEU,
+ Common::kPlatformPC,
+ ADGF_TESTING,
+ GUIO6(GUIO_NOSPEECH, GUIO_MIDIADLIB, GUIO_MIDIPCSPK, GUIO_RENDERVGA, GUIO_RENDEREGA, GUIO_RENDERCGA)
+ },
+ EOB_FLAGS
+ },
+
+ {
+ {
+ "eob2",
+ 0,
+ {
+ { "LEVEL15.INF", 0, "10f19eab75c73d0476dc58bcf70fff7a", -1 },
+ { 0, 0, 0, 0 }
+ },
+ Common::EN_ANY,
+ Common::kPlatformPC,
+ ADGF_TESTING,
+ GUIO5(GUIO_NOSPEECH, GUIO_MIDIADLIB, GUIO_MIDIPCSPK, GUIO_RENDERVGA, GUIO_RENDEREGA)
+ },
+ EOB2_FLAGS
+ },
+
+ {
+ {
+ "eob2",
+ 0,
+ {
+ { "LEVEL15.INF", 0, "ce54243ad1ca4447f521340428da2c91", -1 },
+ { 0, 0, 0, 0 }
+ },
+ Common::DE_DEU,
+ Common::kPlatformPC,
+ ADGF_TESTING,
+ GUIO5(GUIO_NOSPEECH, GUIO_MIDIADLIB, GUIO_MIDIPCSPK, GUIO_RENDERVGA, GUIO_RENDEREGA)
+ },
+ EOB2_FLAGS
+ },
+#endif // ENABLE_EOB
+
{ AD_TABLE_END_MARKER, FLAGS(0, 0, 0, 0, 0, 0, 0, 0, 0) }
};
@@ -1449,6 +1533,10 @@ const PlainGameDescriptor gameList[] = {
#ifdef ENABLE_LOL
{ "lol", "Lands of Lore: The Throne of Chaos" },
#endif // ENABLE_LOL
+#ifdef ENABLE_EOB
+ { "eob", "Eye of the Beholder" },
+ { "eob2", "Eye of the Beholder II: The Legend of Darkmoon" },
+#endif // ENABLE_EOB
{ 0, 0 }
};
diff --git a/engines/kyra/eob.cpp b/engines/kyra/eob.cpp
new file mode 100644
index 0000000000..a7bde9f1ee
--- /dev/null
+++ b/engines/kyra/eob.cpp
@@ -0,0 +1,562 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifdef ENABLE_EOB
+
+#include "kyra/eob.h"
+#include "kyra/resource.h"
+#include "kyra/sound.h"
+
+namespace Kyra {
+
+EoBEngine::EoBEngine(OSystem *system, const GameFlags &flags)
+ : EoBCoreEngine(system, flags) {
+ _numSpells = 53;
+ _menuChoiceInit = 4;
+
+ _turnUndeadString = 0;
+ _finBonusStrings = _npcStrings[1] = _npcStrings[2] = 0;
+ _npcStrings[3] = _npcStrings[4] = _npcStrings[5] = _npcStrings[6] = 0;
+ _npcStrings[7] = _npcStrings[8] = _npcStrings[9] = _npcStrings[10] = 0;
+ _npcShpData = _npcSubShpIndex1 = _npcSubShpIndex2 = _npcSubShpY = 0;
+ _dscDoorScaleMult4 = _dscDoorScaleMult5 = _dscDoorScaleMult6 = _dscDoorY3 = 0;
+ _dscDoorY4 = _dscDoorY5 = _dscDoorY6 = _dscDoorY7 = _doorShapeEncodeDefs = 0;
+ _doorSwitchShapeEncodeDefs = _doorSwitchCoords = 0;
+ _dscDoorCoordsExt = 0;
+}
+
+EoBEngine::~EoBEngine() {
+ delete[] _itemsOverlay;
+}
+
+Common::Error EoBEngine::init() {
+ Common::Error err = EoBCoreEngine::init();
+ if (err.getCode() != Common::kNoError)
+ return err;
+
+ initStaticResource();
+
+ if (_configRenderMode != Common::kRenderCGA)
+ _itemsOverlay = _res->fileData((_configRenderMode == Common::kRenderEGA) ? "ITEMRMP.EGA" : "ITEMRMP.VGA", 0);
+
+ _screen->modifyScreenDim(7, 0x01, 0xB3, 0x22, 0x12);
+ _screen->modifyScreenDim(9, 0x01, 0x7D, 0x26, 0x3F);
+ _screen->modifyScreenDim(12, 0x01, 0x04, 0x14, 0xA0);
+
+ _scriptTimersCount = 1;
+
+ if (_configRenderMode == Common::kRenderEGA) {
+ Palette pal(16);
+ _screen->loadPalette(_egaDefaultPalette, pal, 16);
+ _screen->setScreenPalette(pal);
+ } else {
+ _screen->loadPalette("PALETTE.COL", _screen->getPalette(0));
+ }
+
+ return Common::kNoError;
+}
+
+void EoBEngine::startupNew() {
+ _currentLevel = 1;
+ _currentSub = 0;
+ loadLevel(1, 0);
+ _currentBlock = 490;
+ _currentDirection = 0;
+ setHandItem(0);
+
+ EoBCoreEngine::startupNew();
+}
+
+void EoBEngine::startupLoad() {
+ _sound->loadSoundFile("ADLIB");
+}
+
+void EoBEngine::drawNpcScene(int npcIndex) {
+ _screen->copyRegion(0, 0, 0, 0, 176, 120, 6, 0, Screen::CR_NO_P_CHECK);
+ switch (npcIndex) {
+ case 0:
+ encodeDrawNpcSeqShape(2, 88, 104);
+ break;
+
+ case 1:
+ if (_npcSequenceSub == -1) {
+ encodeDrawNpcSeqShape(0, 88, 104);
+ } else {
+ encodeDrawNpcSeqShape(0, 60, 104);
+ encodeDrawNpcSeqShape(5, 116, 104);
+ }
+ break;
+
+ case 2:
+ if (_npcSequenceSub == -1) {
+ encodeDrawNpcSeqShape(3, 88, 104);
+ } else {
+ encodeDrawNpcSeqShape(3, 60, 104);
+ encodeDrawNpcSeqShape(_npcSubShpIndex1[_npcSequenceSub], 116, 104);
+ encodeDrawNpcSeqShape(_npcSubShpIndex2[_npcSequenceSub], 116, _npcSubShpY[_npcSequenceSub]);
+ }
+ break;
+
+ case 3:
+ encodeDrawNpcSeqShape(7, 88, 104);
+ break;
+
+ case 4:
+ encodeDrawNpcSeqShape(6, 88, 104);
+ break;
+
+ case 5:
+ encodeDrawNpcSeqShape(18, 88, 88);
+ break;
+
+ case 6:
+ encodeDrawNpcSeqShape(17, 88, 104);
+ break;
+
+ case 7:
+ encodeDrawNpcSeqShape(4, 88, 104);
+ break;
+
+ default:
+ break;
+ }
+}
+
+void EoBEngine::encodeDrawNpcSeqShape(int npcIndex, int drawX, int drawY) {
+ const uint8 *shpDef = &_npcShpData[npcIndex << 2];
+ _screen->_curPage = 2;
+ const uint8 *shp = _screen->encodeShape(shpDef[0], shpDef[1], shpDef[2], shpDef[3], false, _cgaMappingDefault);
+ _screen->_curPage = 0;
+ _screen->drawShape(0, shp, drawX - (shp[2] << 2), drawY - shp[1], 5);
+ delete[] shp;
+}
+
+#define DLG2(txt, buttonstr) (runDialogue(txt, 2, _npcStrings[buttonstr][0], _npcStrings[buttonstr][1]) - 1)
+#define DLG3(txt, buttonstr) (runDialogue(txt, 3, _npcStrings[buttonstr][0], _npcStrings[buttonstr][1], _npcStrings[buttonstr][2]) - 1)
+#define DLG2A3(cond, txt, buttonstr1, buttonstr2) ((cond) ? (DLG2(txt, buttonstr1) ? 2 : 0) : DLG3(txt, buttonstr2))
+#define TXT(txt) _txt->printDialogueText(txt, _moreStrings[0])
+
+void EoBEngine::runNpcDialogue(int npcIndex) {
+ int r = 0;
+ int a = 0;
+ Item itm = 0;
+
+ switch (npcIndex) {
+ case 0:
+ for (r = 1; r == 1;) {
+ gui_drawDialogueBox();
+ r = DLG2A3(checkScriptFlags(0x2000), 8, 2, 1);
+ if (r == 1) {
+ TXT(1);
+ setScriptFlags(0x2000);
+ } else if (r == 0) {
+ npcJoinDialogue(6, 12, 23, 2);
+ setScriptFlags(0x4000);
+ }
+ }
+ break;
+
+ case 1:
+ if (!checkScriptFlags(0x10000)) {
+ if (checkScriptFlags(0x8000)) {
+ a = 1;
+ } else {
+ setScriptFlags(0x8000);
+ r = DLG2(3, 3);
+ }
+ if (!r)
+ r = DLG2(a ? 13 : 4, 4);
+
+ if (!r) {
+ for (a = 0; a < 6; a++)
+ createItemOnCurrentBlock(55);
+ createItemOnCurrentBlock(62);
+ setScriptFlags(0x10000);
+ TXT(6);
+ npcJoinDialogue(7, 7, 29, 30);
+ } else {
+ TXT(5);
+ }
+ r = 1;
+ }
+
+ if (!checkScriptFlags(0x80000)) {
+ for (a = 0; a < 6; a++) {
+ if (testCharacter(a, 1) && _characters[a].portrait == -9)
+ break;
+ }
+ if (a != 6) {
+ TXT(25);
+ TXT(26);
+ setScriptFlags(0x80000);
+ r = 1;
+ }
+ }
+
+ if (!checkScriptFlags(0x100000)) {
+ if (deletePartyItems(6, -1)) {
+ //_npcSequenceSub = 0;
+ //drawNpcScene(npcIndex);
+ TXT(28);
+ createItemOnCurrentBlock(32);
+ setScriptFlags(0x100000);
+ r = 1;
+ }
+ }
+
+ if (!r)
+ _txt->printDialogueText(_npcStrings[0][0], true);
+
+ break;
+
+ case 2:
+ if (checkScriptFlags(0x10000)) {
+ if (checkScriptFlags(0x20000)) {
+ TXT(11);
+ } else {
+ r = DLG2A3(!countResurrectionCandidates(), 9, 5, 6);
+ if (r < 2) {
+ if (r == 0)
+ healParty();
+ else
+ resurrectionSelectDialogue();
+ setScriptFlags(0x20000);
+ }
+ }
+ } else {
+ TXT(24);
+ }
+ break;
+
+ case 3:
+ if (!DLG2(18, 7)) {
+ setScriptFlags(0x8400000);
+ for (a = 0; a < 30; a++) {
+ if (_monsters[a].mode == 8)
+ _monsters[a].mode = 5;
+ }
+ } else if (deletePartyItems(49, -1)) {
+ TXT(20);
+ setScriptFlags(0x400000);
+ } else {
+ TXT(19);
+ }
+ break;
+
+ case 4:
+ r = DLG3(14, 8);
+ if (r == 0)
+ setScriptFlags(0x200000);
+ else if (r == 1)
+ TXT(15);
+ setScriptFlags(0x800000);
+ break;
+
+ case 5:
+ if (!DLG2(16, 9)) {
+ TXT(17);
+ for (a = 0; a < 6; a++) {
+ for (r = 0; r < 2; r++) {
+ itm = _characters[a].inventory[r];
+ if (itm && (_items[itm].type < 51 || _items[itm].type > 56)) {
+ _characters[a].inventory[r] = 0;
+ setItemPosition((Item *)&_levelBlockProperties[_currentBlock].drawObjects, _currentBlock, itm, _dropItemDirIndex[(_currentDirection << 2) + rollDice(1, 2, -1)]);
+ }
+ }
+ }
+ }
+ setScriptFlags(0x2000000);
+ break;
+
+ case 6:
+ TXT(21);
+ setScriptFlags(0x1000000);
+ break;
+
+ case 7:
+ r = DLG3(22, 10);
+ if (r < 2) {
+ if (r == 0)
+ npcJoinDialogue(8, 27, 44, 45);
+ else
+ TXT(31);
+ setScriptFlags(0x4000000);
+ }
+ break;
+
+ default:
+ break;
+ }
+}
+
+#undef TXT
+#undef DLG2
+#undef DLG3
+#undef DLG2A3
+
+void EoBEngine::updateUsedCharacterHandItem(int charIndex, int slot) {
+ EoBItem *itm = &_items[_characters[charIndex].inventory[slot]];
+ if (itm->type == 48) {
+ int charges = itm->flags & 0x3f;
+ if (--charges)
+ --itm->flags;
+ else
+ deleteInventoryItem(charIndex, slot);
+ } else if (itm->type == 34 || itm->type == 35) {
+ deleteInventoryItem(charIndex, slot);
+ }
+}
+
+void EoBEngine::replaceMonster(int unit, uint16 block, int pos, int dir, int type, int shpIndex, int mode, int h2, int randItem, int fixedItem) {
+ if (_levelBlockProperties[block].flags & 7)
+ return;
+
+ for (int i = 0; i < 30; i++) {
+ if (_monsters[i].hitPointsCur <= 0) {
+ initMonster(i, unit, block, pos, dir, type, shpIndex, mode, h2, randItem, fixedItem);
+ break;
+ }
+ }
+}
+
+void EoBEngine::updateScriptTimersExtra() {
+ int cnt = 0;
+ for (int i = 1; i < 30; i++) {
+ if (_monsters[i].hitPointsCur <= 0)
+ cnt++;
+ }
+
+ if (!cnt) {
+ for (int i = 1; i < 30; i++) {
+ if (getBlockDistance(_monsters[i].block, _currentBlock) > 3) {
+ killMonster(&_monsters[i], true);
+ break;
+ }
+ }
+ }
+}
+
+void EoBEngine::loadDoorShapes(int doorType1, int shapeId1, int doorType2, int shapeId2) {
+ _screen->loadShapeSetBitmap("DOOR", 5, 3);
+ _screen->_curPage = 2;
+
+ if (doorType1 != 0xff) {
+ for (int i = 0; i < 3; i++) {
+ const uint8 *enc = &_doorShapeEncodeDefs[(doorType1 * 3 + i) << 2];
+ _doorShapes[shapeId1 + i] = _screen->encodeShape(enc[0], enc[1], enc[2], enc[3], false, (_flags.gameID == GI_EOB1) ? _cgaMappingLevel[_cgaLevelMappingIndex[_currentLevel - 1]] : 0);
+ enc = &_doorSwitchShapeEncodeDefs[(doorType1 * 3 + i) << 2];
+ _doorSwitches[shapeId1 + i].shp = _screen->encodeShape(enc[0], enc[1], enc[2], enc[3], false, (_flags.gameID == GI_EOB1) ? _cgaMappingLevel[_cgaLevelMappingIndex[_currentLevel - 1]] : 0);
+ _doorSwitches[shapeId1 + i].x = _doorSwitchCoords[doorType1 * 6 + i * 2];
+ _doorSwitches[shapeId1 + i].y = _doorSwitchCoords[doorType1 * 6 + i * 2 + 1];
+ }
+ }
+
+ if (doorType2 != 0xff) {
+ for (int i = 0; i < 3; i++) {
+ const uint8 *enc = &_doorShapeEncodeDefs[(doorType2 * 3 + i) << 2];
+ _doorShapes[shapeId2 + i] = _screen->encodeShape(enc[0], enc[1], enc[2], enc[3], false, (_flags.gameID == GI_EOB1) ? _cgaMappingLevel[_cgaLevelMappingIndex[_currentLevel - 1]] : 0);
+ enc = &_doorSwitchShapeEncodeDefs[(doorType2 * 3 + i) << 2];
+ _doorSwitches[shapeId2 + i].shp = _screen->encodeShape(enc[0], enc[1], enc[2], enc[3], false, (_flags.gameID == GI_EOB1) ? _cgaMappingLevel[_cgaLevelMappingIndex[_currentLevel - 1]] : 0);
+ _doorSwitches[shapeId2 + i].x = _doorSwitchCoords[doorType2 * 6 + i * 2];
+ _doorSwitches[shapeId2 + i].y = _doorSwitchCoords[doorType2 * 6 + i * 2 + 1];
+ }
+ }
+
+ _screen->_curPage = 0;
+}
+
+void EoBEngine::drawDoorIntern(int type, int index, int x, int y, int w, int wall, int mDim, int16 y1, int16 y2) {
+ int shapeIndex = type + 2 - mDim;
+ uint8 *shp = _doorShapes[shapeIndex];
+
+ int d1 = 0;
+ int d2 = 0;
+ int v = 0;
+ const ScreenDim *td = _screen->getScreenDim(5);
+
+ switch (_currentLevel) {
+ case 4:
+ case 5:
+ case 6:
+ y = _dscDoorY6[mDim] - shp[1];
+ d1 = _dscDoorCoordsExt[index << 1] >> 3;
+ d2 = _dscDoorCoordsExt[(index << 1) + 1] >> 3;
+ if (_shpDmX1 > d1)
+ d1 = _shpDmX1;
+ if (_shpDmX2 < d2)
+ d2 = _shpDmX2;
+ _screen->modifyScreenDim(5, d1, td->sy, d2 - d1, td->h);
+ v = ((wall < 30) ? (wall - _dscDoorScaleOffs[wall]) * _dscDoorScaleMult3[mDim] : _dscDoorScaleMult4[mDim]) * -1;
+ v -= (shp[2] << 3);
+ drawBlockObject(0, 2, shp, x + v, y, 5);
+ v += (shp[2] << 3);
+ drawBlockObject(1, 2, shp, x - v, y, 5);
+ if (_wllShapeMap[wall] == -1)
+ drawBlockObject(0, 2, _doorSwitches[shapeIndex].shp, _doorSwitches[shapeIndex].x + w - v, _doorSwitches[shapeIndex].y, 5);
+ break;
+
+ case 7:
+ case 8:
+ case 9:
+ y = _dscDoorY3[mDim] - _doorShapes[shapeIndex + 3][1];
+ d1 = x - (_doorShapes[shapeIndex + 3][2] << 2);
+ x -= (shp[2] << 2);
+ drawBlockObject(0, 2, _doorShapes[shapeIndex + 3], d1, y, 5);
+ setDoorShapeDim(index, y1, y2, 5);
+ y = _dscDoorY3[mDim] - ((wall < 30) ? (wall - _dscDoorScaleOffs[wall]) * _dscDoorScaleMult1[mDim] : _dscDoorScaleMult2[mDim]);
+ drawBlockObject(0, 2, shp, x, y, 5);
+ if (_wllShapeMap[wall] == -1)
+ drawBlockObject(0, 2, _doorSwitches[shapeIndex].shp, _doorSwitches[shapeIndex].x + w, _doorSwitches[shapeIndex].y, 5);
+ break;
+
+ case 10:
+ case 11:
+ v = ((wall < 30) ? (wall - _dscDoorScaleOffs[wall]) * _dscDoorScaleMult5[mDim] : _dscDoorScaleMult6[mDim]) * -1;
+ x -= (shp[2] << 2);
+ y = _dscDoorY4[mDim] + v;
+ drawBlockObject(0, 2, shp, x, y + v, 5);
+ v = (v >> 3) + (v >> 2);
+ y = _dscDoorY5[mDim];
+ drawBlockObject(0, 2, _doorShapes[shapeIndex + 3], x, y - v, 5);
+ if (_wllShapeMap[wall] == -1)
+ drawBlockObject(0, 2, _doorSwitches[shapeIndex].shp, _doorSwitches[shapeIndex].x + w, _doorSwitches[shapeIndex].y, 5);
+ break;
+
+ default:
+ y = (_currentLevel == 12 ? _dscDoorY6[mDim] : _dscDoorY1[mDim]) - shp[1];
+ x -= (shp[2] << 2);
+ y -= (wall >= 30 ? _dscDoorScaleMult2[mDim] : (wall - _dscDoorScaleOffs[wall]) * _dscDoorScaleMult1[mDim]);
+ drawBlockObject(0, 2, shp, x, y, 5);
+
+ if (_wllShapeMap[wall] == -1)
+ drawBlockObject(0, 2, _doorSwitches[shapeIndex].shp, _doorSwitches[shapeIndex].x + w, _doorSwitches[shapeIndex].y, 5);
+ break;
+ }
+}
+
+void EoBEngine::turnUndeadAuto() {
+ if (_currentLevel != 2 && _currentLevel != 7)
+ return;
+
+ int oc = _openBookChar;
+
+ for (int i = 0; i < 6; i++) {
+ if (!testCharacter(i, 0x0d))
+ continue;
+
+ EoBCharacter *c = &_characters[i];
+
+ if (_itemTypes[_items[c->inventory[0]].type].extraProperties != 6 && _itemTypes[_items[c->inventory[1]].type].extraProperties != 6)
+ continue;
+
+ int l = getCharacterLevelIndex(2, c->cClass);
+ if (l > -1) {
+ if (c->level[l] > _openBookCasterLevel) {
+ _openBookCasterLevel = c->level[l];
+ _openBookChar = i;
+ }
+ } else {
+ l = getCharacterLevelIndex(4, c->cClass);
+ if (l > -1) {
+ if ((c->level[l] - 2) > _openBookCasterLevel) {
+ _openBookCasterLevel = (c->level[l] - 2);
+ _openBookChar = i;
+ }
+ }
+ }
+ }
+
+ if (_openBookCasterLevel)
+ spellCallback_start_turnUndead();
+
+ _openBookChar = oc;
+ _openBookCasterLevel = 0;
+}
+
+void EoBEngine::turnUndeadAutoHit() {
+ _txt->printMessage(_turnUndeadString[0], -1, _characters[_openBookChar].name);
+ sparkEffectOffensive();
+}
+
+bool EoBEngine::checkPartyStatusExtra() {
+ _screen->copyPage(0, 10);
+ int cd = _screen->curDimIndex();
+ gui_drawBox(0, 121, 320, 80, guiSettings()->colors.frame1, guiSettings()->colors.frame2, guiSettings()->colors.fill);
+ _txt->setupField(9, false);
+ _txt->printMessage(_menuStringsDefeat[0]);
+ while (!shouldQuit()) {
+ removeInputTop();
+ if (checkInput(0, false, 0) & 0xff)
+ break;
+ }
+ _screen->copyPage(10, 0);
+ _eventList.clear();
+ _screen->setScreenDim(cd);
+ _txt->removePageBreakFlag();
+ return true;
+}
+
+int EoBEngine::resurrectionSelectDialogue() {
+ gui_drawDialogueBox();
+ _txt->printDialogueText(_npcStrings[0][1]);
+
+ int r = _rrId[runDialogue(-1, 9, _rrNames[0], _rrNames[1], _rrNames[2], _rrNames[3], _rrNames[4], _rrNames[5], _rrNames[6], _rrNames[7], _rrNames[8]) - 1];
+
+ if (r < 0) {
+ r = -r;
+ deletePartyItems(33, r);
+ _npcSequenceSub = r - 1;
+ drawNpcScene(2);
+ npcJoinDialogue(_npcSequenceSub, 32 + (_npcSequenceSub << 1), -1, 33 + (_npcSequenceSub << 1));
+ } else {
+ _characters[r].hitPointsCur = _characters[r].hitPointsMax;
+ }
+
+ return 1;
+}
+
+void EoBEngine::healParty() {
+ int cnt = rollDice(1, 3, 2);
+ for (int i = 0; i < 6 && cnt; i++) {
+ if (testCharacter(i, 3))
+ continue;
+
+ _characters[i].flags &= ~4;
+ neutralizePoison(i);
+
+ if (_characters[i].hitPointsCur >= _characters[i].hitPointsMax)
+ continue;
+
+ cnt--;
+ _characters[i].hitPointsCur += rollDice(1, 8, 9);
+ if (_characters[i].hitPointsCur > _characters[i].hitPointsMax)
+ _characters[i].hitPointsCur = _characters[i].hitPointsMax;
+ }
+}
+
+const KyraRpgGUISettings *EoBEngine::guiSettings() {
+ return (_configRenderMode == Common::kRenderCGA || _configRenderMode == Common::kRenderEGA) ? &_guiSettingsEGA : &_guiSettingsVGA;
+}
+
+} // End of namespace Kyra
+
+#endif // ENABLE_EOB
diff --git a/engines/kyra/eob.h b/engines/kyra/eob.h
new file mode 100644
index 0000000000..37ce483702
--- /dev/null
+++ b/engines/kyra/eob.h
@@ -0,0 +1,121 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifdef ENABLE_EOB
+
+#ifndef KYRA_EOB1_H
+#define KYRA_EOB1_H
+
+#include "kyra/eobcommon.h"
+
+namespace Kyra {
+
+class EoBEngine : public EoBCoreEngine {
+friend class GUI_EoB;
+friend class EoBIntroPlayer;
+public:
+ EoBEngine(OSystem *system, const GameFlags &flags);
+ ~EoBEngine();
+
+private:
+ // Init / Release
+ Common::Error init();
+ void initStaticResource();
+ void initSpells();
+
+ // Main Menu
+ int mainMenu();
+ int mainMenuLoop();
+ int _menuChoiceInit;
+
+ // Main loop
+ void startupNew();
+ void startupLoad();
+
+ // Intro/Outro
+ void seq_playIntro();
+ void seq_playFinale();
+ void seq_xdeath();
+
+ const char *const *_finBonusStrings;
+
+ // characters
+ void drawNpcScene(int npcIndex);
+ void encodeDrawNpcSeqShape(int npcIndex, int drawX, int drawY);
+ void runNpcDialogue(int npcIndex);
+
+ const uint8 *_npcShpData;
+ const uint8 *_npcSubShpIndex1;
+ const uint8 *_npcSubShpIndex2;
+ const uint8 *_npcSubShpY;
+ const char *const *_npcStrings[11];
+
+ // items
+ void updateUsedCharacterHandItem(int charIndex, int slot);
+
+ // Monsters
+ void replaceMonster(int unit, uint16 block, int d, int dir, int type, int shpIndex, int mode, int h2, int randItem, int fixedItem);
+ void updateScriptTimersExtra();
+
+ // Level
+ const uint8 *loadDoorShapes(const char *filename, int doorIndex, const uint8 *shapeDefs) { return 0; }
+ void loadDoorShapes(int doorType1, int shapeId1, int doorType2, int shapeId2);
+ void drawDoorIntern(int type, int index, int x, int y, int w, int wall, int mDim, int16 y1, int16 y2);
+
+ const int16 *_dscDoorCoordsExt;
+ const uint8 *_dscDoorScaleMult4;
+ const uint8 *_dscDoorScaleMult5;
+ const uint8 *_dscDoorScaleMult6;
+ const uint8 *_dscDoorY3;
+ const uint8 *_dscDoorY4;
+ const uint8 *_dscDoorY5;
+ const uint8 *_dscDoorY6;
+ const uint8 *_dscDoorY7;
+
+ const uint8 *_doorShapeEncodeDefs;
+ const uint8 *_doorSwitchShapeEncodeDefs;
+ const uint8 *_doorSwitchCoords;
+
+ // Magic
+ void turnUndeadAuto();
+ void turnUndeadAutoHit();
+
+ const char * const *_turnUndeadString;
+
+ // Misc
+ bool checkPartyStatusExtra();
+ int resurrectionSelectDialogue();
+ void healParty();
+
+ const KyraRpgGUISettings *guiSettings();
+
+ static const KyraRpgGUISettings _guiSettingsVGA;
+ static const KyraRpgGUISettings _guiSettingsEGA;
+ static const uint8 _egaDefaultPalette[];
+};
+
+
+} // End of namespace Kyra
+
+#endif
+
+#endif // ENABLE_EOB
diff --git a/engines/kyra/eobcommon.cpp b/engines/kyra/eobcommon.cpp
new file mode 100644
index 0000000000..1489e4f1f5
--- /dev/null
+++ b/engines/kyra/eobcommon.cpp
@@ -0,0 +1,2420 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifdef ENABLE_EOB
+
+#include "kyra/kyra_rpg.h"
+#include "kyra/resource.h"
+#include "kyra/sound_intern.h"
+#include "kyra/script_eob.h"
+#include "kyra/timer.h"
+#include "kyra/debugger.h"
+
+#include "common/config-manager.h"
+#include "common/translation.h"
+
+#include "audio/mididrv.h"
+#include "audio/mixer.h"
+
+#include "backends/keymapper/keymapper.h"
+
+namespace Kyra {
+
+const char *const EoBCoreEngine::kKeymapName = "eob";
+
+EoBCoreEngine::EoBCoreEngine(OSystem *system, const GameFlags &flags)
+ : KyraRpgEngine(system, flags), _numLargeItemShapes(flags.gameID == GI_EOB1 ? 14 : 11),
+ _numSmallItemShapes(flags.gameID == GI_EOB1 ? 23 : 26),
+ _numThrownItemShapes(flags.gameID == GI_EOB1 ? 12 : 9),
+ _numItemIconShapes(flags.gameID == GI_EOB1 ? 89 : 112),
+ _teleporterWallId(flags.gameID == GI_EOB1 ? 52 : 44) {
+
+ _screen = 0;
+ _gui = 0;
+ _debugger = 0;
+
+ _playFinale = false;
+ _runFlag = true;
+ _configMouse = true;
+ _loading = false;
+
+ _useHiResDithering = false;
+
+ _envAudioTimer = 0;
+ _flashShapeTimer = 0;
+ _drawSceneTimer = 0;
+
+ _largeItemShapes = _smallItemShapes = _thrownItemShapes = _spellShapes = _firebeamShapes = 0;
+ _itemIconShapes = _wallOfForceShapes = _teleporterShapes = _sparkShapes = _compassShapes = 0;
+ _redSplatShape = _greenSplatShape = _deadCharShape = _disabledCharGrid = 0;
+ _blackBoxSmallGrid = _weaponSlotGrid = _blackBoxWideGrid = _lightningColumnShape = 0;
+
+ _monsterDustStrings = 0;
+ _enemyMageSpellList = 0;
+ _enemyMageSfx = 0;
+ _beholderSpellList = 0;
+ _beholderSfx = 0;
+
+ _faceShapes = 0;
+ _characters = 0;
+ _items = 0;
+ _itemTypes = 0;
+ _itemNames = 0;
+ _itemInHand = -1;
+ _numItems = _numItemNames = 0;
+
+ _castScrollSlot = 0;
+ _currentSub = 0;
+
+ _itemsOverlay = 0;
+
+ _partyEffectFlags = 0;
+ _lastUsedItem = 0;
+
+ _levelDecorationRects = 0;
+ _doorSwitches = 0;
+ _monsterProps = 0;
+ _monsterDecorations = 0;
+ _monsterFlashOverlay = _monsterStoneOverlay = 0;
+ _monsters = 0;
+ _dstMonsterIndex = 0;
+ _preventMonsterFlash = false;
+
+ _teleporterPulse = 0;
+
+ _dscShapeCoords = 0;
+ _dscItemPosIndex = 0;
+ _dscItemShpX = 0;
+ _dscItemScaleIndex = 0;
+ _dscItemTileIndex = 0;
+ _dscItemShapeMap = 0;
+ _dscDoorScaleOffs = 0;
+ _dscDoorScaleMult1 = 0;
+ _dscDoorScaleMult2 = 0;
+ _dscDoorScaleMult3 = 0;
+ _dscDoorY1 = 0;
+ _dscDoorXE = 0;
+
+ _menuDefs = 0;
+
+ _exchangeCharacterId = -1;
+ _charExchangeSwap = 0;
+ _configHpBarGraphs = true;
+
+ memset(_dialogueLastBitmap, 0, 13);
+ _npcSequenceSub = 0;
+ _moveCounter = 0;
+ _partyResting = false;
+
+ _flyingObjects = 0;
+
+ _inf = 0;
+ _stepCounter = 0;
+ _stepsUntilScriptCall = 0;
+ _scriptTimersMode = 3;
+ _currentDirection = 0;
+
+ _openBookSpellLevel = 0;
+ _openBookSpellSelectedItem = 0;
+ _openBookSpellListOffset = 0;
+ _openBookChar = _openBookCharBackup = _openBookCasterLevel = 0;
+ _openBookType = _openBookTypeBackup = 0;
+ _openBookSpellList = 0;
+ _openBookAvailableSpells = 0;
+ _activeSpellCharId = 0;
+ _activeSpellCharacterPos = 0;
+ _activeSpell = 0;
+ _characterSpellTarget = 0;
+ _returnAfterSpellCallback = false;
+ _spells = 0;
+ _spellAnimBuffer = 0;
+ _clericSpellOffset = 0;
+ _restPartyElapsedTime = 0;
+ _allowSkip = false;
+ _allowImport = false;
+
+ _wallsOfForce = 0;
+
+ _rrCount = 0;
+ memset(_rrNames, 0, 10 * sizeof(const char *));
+ memset(_rrId, 0, 10 * sizeof(int8));
+
+ _mainMenuStrings = _levelGainStrings = _monsterSpecAttStrings = _characterGuiStringsHp = 0;
+ _characterGuiStringsWp = _characterGuiStringsWr = _characterGuiStringsSt = 0;
+ _characterGuiStringsIn = _characterStatusStrings7 = _characterStatusStrings8 = 0;
+ _characterStatusStrings9 = _characterStatusStrings12 = _characterStatusStrings13 = 0;
+ _classModifierFlags = _saveThrowLevelIndex = _saveThrowModDiv = _saveThrowModExt = 0;
+ _wandTypes = _drawObjPosIndex = _flightObjFlipIndex = _expObjectTblIndex = 0;
+ _expObjectShpStart = _expObjectTlMode = _expObjectAnimTbl1 = _expObjectAnimTbl2 = _expObjectAnimTbl3 = 0;
+ _monsterStepTable0 = _monsterStepTable1 = _monsterStepTable2 = _monsterStepTable3 = 0;
+ _projectileWeaponAmmoTypes = _flightObjShpMap = _flightObjSclIndex = 0;
+ _monsterCloseAttPosTable1 = _monsterCloseAttPosTable2 = _monsterCloseAttChkTable1 = 0;
+ _monsterCloseAttChkTable2 = _monsterCloseAttDstTable1 = _monsterCloseAttDstTable2 = 0;
+ _monsterProximityTable = _findBlockMonstersTable = _wallOfForceDsY = _wallOfForceDsNumW = 0;
+ _wallOfForceDsNumH = _wallOfForceShpId = _wllFlagPreset = _teleporterShapeCoords = 0;
+ _monsterCloseAttUnkTable = _monsterFrmOffsTable1 = _monsterFrmOffsTable2 = 0;
+ _monsterDirChangeTable = _portalSeq = 0;
+ _wallOfForceDsX = 0;
+ _expObjectAnimTbl1Size = _expObjectAnimTbl2Size = _expObjectAnimTbl3Size = 0;
+ _wllFlagPresetSize = _scriptTimersCount = _buttonList1Size = _buttonList2Size = 0;
+ _buttonList3Size = _buttonList4Size = _buttonList5Size = _buttonList6Size = 0;
+ _buttonList7Size = _buttonList8Size = 0;
+ _inventorySlotsY = _mnDef = 0;
+ _transferStringsScummVM = 0;
+ _buttonDefs = 0;
+ _npcPreset = 0;
+ _chargenStatStrings = _chargenRaceSexStrings = _chargenClassStrings = 0;
+ _chargenAlignmentStrings = _pryDoorStrings = _warningStrings = _ripItemStrings = 0;
+ _cursedString = _enchantedString = _magicObjectStrings = _magicObjectString5 = 0;
+ _patternSuffix = _patternGrFix1 = _patternGrFix2 = _validateArmorString = 0;
+ _validateCursedString = _validateNoDropString = _potionStrings = _wandStrings = 0;
+ _itemMisuseStrings = _suffixStringsRings = _suffixStringsPotions = 0;
+ _suffixStringsWands = _takenStrings = _potionEffectStrings = _yesNoStrings = 0;
+ _npcMaxStrings = _okStrings = _npcJoinStrings = _cancelStrings = 0;
+ _abortStrings = _saveLoadStrings = _mnWord = _mnPrompt = _bookNumbers = 0;
+ _mageSpellList = _clericSpellList = _spellNames = _magicStrings1 = 0;
+ _magicStrings2 = _magicStrings3 = _magicStrings4 = _magicStrings6 = 0;
+ _magicStrings7 = _magicStrings8 = 0;
+ _spellAnimBuffer = 0;
+ _sparkEffectDefSteps = _sparkEffectDefSubSteps = _sparkEffectDefShift = 0;
+ _sparkEffectDefAdd = _sparkEffectDefX = _sparkEffectDefY = _sparkEffectOfShift = 0;
+ _sparkEffectOfX = _sparkEffectOfY = _magicFlightObjectProperties = 0;
+ _turnUndeadEffect = _burningHandsDest = _coneOfColdGfxTbl = 0;
+ _sparkEffectOfFlags1 = _sparkEffectOfFlags2 = 0;
+ _coneOfColdDest1 = _coneOfColdDest2 = _coneOfColdDest3 = _coneOfColdDest4 = 0;
+ _coneOfColdGfxTblSize = 0;
+ _menuButtonDefs = 0;
+ _updateCharNum = 0;
+ _menuStringsMain = _menuStringsSaveLoad = _menuStringsOnOff = _menuStringsSpells = 0;
+ _menuStringsRest = _menuStringsDrop = _menuStringsExit = _menuStringsStarve = 0;
+ _menuStringsScribe = _menuStringsDrop2 = _menuStringsHead = _menuStringsPoison = 0;
+ _menuStringsMgc = _menuStringsPrefs = _menuStringsRest2 = _menuStringsRest3 = 0;
+ _menuStringsRest4 = _menuStringsDefeat = _menuStringsTransfer = _menuStringsSpec = 0;
+ _menuStringsSpellNo = _menuYesNoStrings = 0;
+ _errorSlotEmptyString = _errorSlotNoNameString = _menuOkString = 0;
+ _spellLevelsMage = _spellLevelsCleric = _numSpellsCleric = _numSpellsWisAdj = _numSpellsPal = _numSpellsMage = 0;
+ _mnNumWord = _numSpells = _mageSpellListSize = _spellLevelsMageSize = _spellLevelsClericSize = 0;
+ _inventorySlotsX = _slotValidationFlags = _encodeMonsterShpTable = 0;
+ _cgaMappingDefault = _cgaMappingAlt = _cgaMappingInv = _cgaLevelMappingIndex = _cgaMappingItemsL = _cgaMappingItemsS = _cgaMappingThrown = _cgaMappingIcons = _cgaMappingDeco = 0;
+ memset(_cgaMappingLevel, 0, sizeof(_cgaMappingLevel));
+ memset(_expRequirementTables, 0, sizeof(_expRequirementTables));
+ memset(_saveThrowTables, 0, sizeof(_saveThrowTables));
+ memset(_doorType, 0, sizeof(_doorType));
+ memset(_noDoorSwitch, 0, sizeof(_noDoorSwitch));
+ memset(_scriptTimers, 0, sizeof(_scriptTimers));
+ memset(_monsterBlockPosArray, 0, sizeof(_monsterBlockPosArray));
+ memset(_foundMonstersArray, 0, sizeof(_foundMonstersArray));
+
+#define DWM0 _dscWallMapping.push_back(0)
+#define DWM(x) _dscWallMapping.push_back(&_sceneDrawVar##x)
+ DWM0; DWM0; DWM(Down); DWM(Right);
+ DWM(Down); DWM(Right); DWM(Down); DWM0;
+ DWM(Down); DWM(Left); DWM(Down); DWM(Left);
+ DWM0; DWM0; DWM(Down); DWM(Right);
+ DWM(Down); DWM(Right); DWM(Down); DWM0;
+ DWM(Down); DWM(Left); DWM(Down); DWM(Left);
+ DWM(Down); DWM(Right); DWM(Down); DWM0;
+ DWM(Down); DWM(Left); DWM0; DWM(Right);
+ DWM(Down); DWM0; DWM0; DWM(Left);
+#undef DWM
+#undef DWM0
+}
+
+EoBCoreEngine::~EoBCoreEngine() {
+ releaseItemsAndDecorationsShapes();
+ releaseTempData();
+
+ if (_faceShapes) {
+ for (int i = 0; i < 44; i++) {
+ if (_characters) {
+ for (int ii = 0; ii < 6; ii++) {
+ if (_characters[ii].faceShape == _faceShapes[i])
+ _characters[ii].faceShape = 0;
+ }
+ }
+ delete[] _faceShapes[i];
+ _faceShapes[i] = 0;
+ }
+ delete[] _faceShapes;
+ }
+
+ if (_characters) {
+ for (int i = 0; i < 6; i++)
+ delete[] _characters[i].faceShape;
+ }
+
+ delete[] _characters;
+ delete[] _items;
+ delete[] _itemTypes;
+ if (_itemNames) {
+ for (int i = 0; i < 130; i++)
+ delete[] _itemNames[i];
+ }
+ delete[] _itemNames;
+ delete[] _flyingObjects;
+
+ delete[] _monsterFlashOverlay;
+ delete[] _monsterStoneOverlay;
+ delete[] _monsters;
+
+ if (_monsterDecorations) {
+ releaseMonsterShapes(0, 36);
+ delete[] _monsterShapes;
+ delete[] _monsterDecorations;
+
+ for (int i = 0; i < 24; i++)
+ delete[] _monsterPalettes[i];
+ delete[] _monsterPalettes;
+ }
+
+ delete[] _monsterProps;
+
+ if (_doorSwitches) {
+ releaseDoorShapes();
+ delete[] _doorSwitches;
+ }
+
+ releaseDecorations();
+ delete[] _levelDecorationRects;
+ _dscWallMapping.clear();
+
+ delete[] _spells;
+ delete[] _spellAnimBuffer;
+ delete[] _wallsOfForce;
+
+ delete _gui;
+ _gui = 0;
+ delete _screen;
+ _screen = 0;
+
+ delete[] _menuDefs;
+ _menuDefs = 0;
+
+ delete _inf;
+ _inf = 0;
+ delete _timer;
+ _timer = 0;
+ delete _debugger;
+ _debugger = 0;
+ delete _txt;
+ _txt = 0;
+}
+
+void EoBCoreEngine::initKeymap() {
+#ifdef ENABLE_KEYMAPPER
+ Common::Keymapper *const mapper = _eventMan->getKeymapper();
+
+ // Do not try to recreate same keymap over again
+ if (mapper->getKeymap(kKeymapName) != 0)
+ return;
+
+ Common::Keymap *const engineKeyMap = new Common::Keymap(kKeymapName);
+
+ const Common::KeyActionEntry keyActionEntries[] = {
+ { Common::KeyState(Common::KEYCODE_UP), "MVF", _("Move Forward") },
+ { Common::KeyState(Common::KEYCODE_DOWN), "MVB", _("Move Back") },
+ { Common::KeyState(Common::KEYCODE_LEFT), "MVL", _("Move Left") },
+ { Common::KeyState(Common::KEYCODE_RIGHT), "MVR", _("Move Right") },
+ { Common::KeyState(Common::KEYCODE_HOME), "TL", _("Turn Left") },
+ { Common::KeyState(Common::KEYCODE_PAGEUP), "TR", _("Turn Right") },
+ { Common::KeyState(Common::KEYCODE_i), "INV", _("Open/Close Inventory") },
+ { Common::KeyState(Common::KEYCODE_p), "SCE", _("Switch Inventory/Character screen") },
+ { Common::KeyState(Common::KEYCODE_c), "CMP", _("Camp") },
+ { Common::KeyState(Common::KEYCODE_SPACE), "CSP", _("Cast Spell") },
+ // TODO: Spell cursor, but this needs more thought, since different
+ // game versions use different keycodes.
+ { Common::KeyState(Common::KEYCODE_1), "SL1", _("Spell Level 1") },
+ { Common::KeyState(Common::KEYCODE_2), "SL2", _("Spell Level 2") },
+ { Common::KeyState(Common::KEYCODE_3), "SL3", _("Spell Level 3") },
+ { Common::KeyState(Common::KEYCODE_4), "SL4", _("Spell Level 4") },
+ { Common::KeyState(Common::KEYCODE_5), "SL5", _("Spell Level 5") }
+ };
+
+ for (uint i = 0; i < ARRAYSIZE(keyActionEntries); ++i) {
+ Common::Action *const act = new Common::Action(engineKeyMap, keyActionEntries[i].id, keyActionEntries[i].description);
+ act->addKeyEvent(keyActionEntries[i].ks);
+ }
+
+ if (_flags.gameID == GI_EOB2) {
+ Common::Action *const act = new Common::Action(engineKeyMap, "SL6", _("Spell Level 6"));
+ act->addKeyEvent(Common::KeyState(Common::KEYCODE_6));
+ }
+
+ mapper->addGameKeymap(engineKeyMap);
+#endif
+}
+
+Common::Error EoBCoreEngine::init() {
+ // In EOB the timer proc is directly invoked via interrupt 0x1c, 18.2 times per second.
+ // This makes a tick length of 54.94.
+ _tickLength = 55;
+
+ if (ConfMan.hasKey("render_mode"))
+ _configRenderMode = Common::parseRenderMode(ConfMan.get("render_mode"));
+
+ _useHiResDithering = (_configRenderMode == Common::kRenderEGA && _flags.useHiRes);
+
+ _screen = new Screen_EoB(this, _system);
+ assert(_screen);
+ _screen->setResolution();
+
+ //MidiDriverType midiDriver = MidiDriver::detectDevice(MDT_PCSPK | MDT_ADLIB);
+ _sound = new SoundAdLibPC(this, _mixer);
+ assert(_sound);
+ _sound->init();
+
+ // Setup volume settings (and read in all ConfigManager settings)
+ syncSoundSettings();
+
+ _res = new Resource(this);
+ assert(_res);
+ _res->reset();
+
+ _staticres = new StaticResource(this);
+ assert(_staticres);
+ if (!_staticres->init())
+ error("_staticres->init() failed");
+
+ if (!_screen->init())
+ error("screen()->init() failed");
+
+ if (ConfMan.hasKey("save_slot")) {
+ _gameToLoad = ConfMan.getInt("save_slot");
+ if (!saveFileLoadable(_gameToLoad))
+ _gameToLoad = -1;
+ }
+
+ setupKeyMap();
+
+ _gui = new GUI_EoB(this);
+ assert(_gui);
+ _txt = new TextDisplayer_rpg(this, _screen);
+ assert(_txt);
+ _inf = new EoBInfProcessor(this, _screen);
+ assert(_inf);
+ _debugger = new Debugger_EoB(this);
+ assert(_debugger);
+
+ _screen->loadFont(Screen::FID_6_FNT, "FONT6.FNT");
+ _screen->loadFont(Screen::FID_8_FNT, "FONT8.FNT");
+
+ if (_useHiResDithering) {
+ _vcnBlockWidth <<= 1;
+ _vcnBlockHeight <<= 1;
+ SWAP(_vcnFlip0, _vcnFlip1);
+ }
+
+ Common::Error err = KyraRpgEngine::init();
+ if (err.getCode() != Common::kNoError)
+ return err;
+
+ initButtonData();
+ initMenus();
+ initStaticResource();
+ initSpells();
+
+ _timer = new TimerManager(this, _system);
+ assert(_timer);
+ setupTimers();
+
+ _wllVmpMap[1] = 1;
+ _wllVmpMap[2] = 2;
+ memset(&_wllVmpMap[3], 3, 20);
+ _wllVmpMap[23] = 4;
+ _wllVmpMap[24] = 5;
+
+ memcpy(_wllWallFlags, _wllFlagPreset, _wllFlagPresetSize);
+
+ memset(&_specialWallTypes[3], 1, 5);
+ memset(&_specialWallTypes[13], 1, 5);
+ _specialWallTypes[8] = _specialWallTypes[18] = 6;
+
+ memset(&_wllShapeMap[3], -1, 5);
+ memset(&_wllShapeMap[13], -1, 5);
+
+ _wllVcnOffset = 16;
+
+ _monsters = new EoBMonsterInPlay[30];
+ memset(_monsters, 0, 30 * sizeof(EoBMonsterInPlay));
+
+ _characters = new EoBCharacter[6];
+ memset(_characters, 0, sizeof(EoBCharacter) * 6);
+
+ _items = new EoBItem[600];
+ memset(_items, 0, sizeof(EoBItem) * 600);
+
+ _itemNames = new char*[130];
+ for (int i = 0; i < 130; i++) {
+ _itemNames[i] = new char[35];
+ memset(_itemNames[i], 0, 35);
+ }
+
+ _flyingObjects = new EoBFlyingObject[_numFlyingObjects];
+ _flyingObjectsPtr = _flyingObjects;
+ memset(_flyingObjects, 0, _numFlyingObjects * sizeof(EoBFlyingObject));
+
+ _spellAnimBuffer = new uint8[4096];
+ memset(_spellAnimBuffer, 0, 4096);
+
+ _wallsOfForce = new WallOfForce[5];
+ memset(_wallsOfForce, 0, 5 * sizeof(WallOfForce));
+
+ memset(_doorType, 0, sizeof(_doorType));
+ memset(_noDoorSwitch, 0, sizeof(_noDoorSwitch));
+
+ _monsterShapes = new uint8*[36];
+ memset(_monsterShapes, 0, 36 * sizeof(uint8 *));
+ _monsterDecorations = new SpriteDecoration[36];
+ memset(_monsterDecorations, 0, 36 * sizeof(SpriteDecoration));
+ _monsterPalettes = new uint8*[24];
+ for (int i = 0; i < 24; i++)
+ _monsterPalettes[i] = new uint8[16];
+
+ _doorSwitches = new SpriteDecoration[6];
+ memset(_doorSwitches, 0, 6 * sizeof(SpriteDecoration));
+
+ _monsterFlashOverlay = new uint8[16];
+ _monsterStoneOverlay = new uint8[16];
+ memset(_monsterFlashOverlay, (_configRenderMode == Common::kRenderCGA) ? 0xff : 0x0f, 16 * sizeof(uint8));
+ memset(_monsterStoneOverlay, 0x0d, 16 * sizeof(uint8));
+ _monsterFlashOverlay[0] = _monsterStoneOverlay[0] = 0;
+
+ // Prevent autosave on game startup
+ _lastAutosave = _system->getMillis();
+
+#ifdef ENABLE_KEYMAPPER
+ _eventMan->getKeymapper()->pushKeymap(kKeymapName, true);
+#endif
+
+ return Common::kNoError;
+}
+
+Common::Error EoBCoreEngine::go() {
+ _debugger->initialize();
+
+ _txt->removePageBreakFlag();
+
+ _screen->setFont(Screen::FID_8_FNT);
+
+ loadItemsAndDecorationsShapes();
+ _screen->setMouseCursor(0, 0, _itemIconShapes[0]);
+
+ // Import original save game files (especially the "Quick Start Party")
+ if (ConfMan.getBool("importOrigSaves")) {
+ importOriginalSaveFile(-1);
+ ConfMan.setBool("importOrigSaves", false);
+ ConfMan.flushToDisk();
+ }
+
+ loadItemDefs();
+ int action = 0;
+
+ for (bool repeatLoop = true; repeatLoop; repeatLoop ^= true) {
+ action = 0;
+
+ if (_gameToLoad != -1) {
+ if (loadGameState(_gameToLoad).getCode() != Common::kNoError)
+ error("Couldn't load game slot %d on startup", _gameToLoad);
+ startupLoad();
+ _gameToLoad = -1;
+ } else {
+ _screen->showMouse();
+ action = mainMenu();
+ }
+
+ if (action == -1) {
+ // load game
+ repeatLoop = _gui->runLoadMenu(72, 14);
+ if (repeatLoop && !shouldQuit())
+ startupLoad();
+ } else if (action == -2) {
+ // new game
+ repeatLoop = startCharacterGeneration();
+ if (repeatLoop && !shouldQuit())
+ startupNew();
+ } else if (action == -3) {
+ // transfer party
+ repeatLoop = startPartyTransfer();
+ if (repeatLoop && !shouldQuit())
+ startupNew();
+ }
+ }
+
+ if (!shouldQuit() && action >= -3) {
+ runLoop();
+
+ if (_playFinale) {
+ // make final save for party transfer
+ saveGameStateIntern(-1, 0, 0);
+ seq_playFinale();
+ }
+ }
+
+ return Common::kNoError;
+}
+
+void EoBCoreEngine::registerDefaultSettings() {
+ KyraEngine_v1::registerDefaultSettings();
+ ConfMan.registerDefault("hpbargraphs", true);
+ ConfMan.registerDefault("importOrigSaves", true);
+}
+
+void EoBCoreEngine::readSettings() {
+ _configHpBarGraphs = ConfMan.getBool("hpbargraphs");
+ _configSounds = ConfMan.getBool("sfx_mute") ? 0 : 1;
+ _configMusic = _configSounds ? 1 : 0;
+
+ if (_sound)
+ _sound->enableSFX(_configSounds);
+}
+
+void EoBCoreEngine::writeSettings() {
+ ConfMan.setBool("hpbargraphs", _configHpBarGraphs);
+ ConfMan.setBool("sfx_mute", _configSounds == 0);
+
+ if (_sound) {
+ if (!_configSounds)
+ _sound->beginFadeOut();
+ _sound->enableMusic(_configSounds ? 1 : 0);
+ _sound->enableSFX(_configSounds);
+ }
+
+ ConfMan.flushToDisk();
+}
+
+void EoBCoreEngine::startupNew() {
+ gui_setPlayFieldButtons();
+ _screen->_curPage = 0;
+ gui_drawPlayField(false);
+ _screen->_curPage = 0;
+ gui_drawAllCharPortraitsWithStats();
+ drawScene(1);
+ _updateFlags = 0;
+ _updateCharNum = 0;
+}
+
+void EoBCoreEngine::runLoop() {
+ _envAudioTimer = _system->getMillis() + (rollDice(1, 10, 3) * 18 * _tickLength);
+ _flashShapeTimer = 0;
+ _drawSceneTimer = _system->getMillis();
+
+ _screen->setFont(Screen::FID_6_FNT);
+ _screen->setScreenDim(7);
+
+ _runFlag = true;
+
+ while (!shouldQuit() && _runFlag) {
+ checkPartyStatus(true);
+ checkInput(_activeButtons, true, 0);
+ removeInputTop();
+
+ if (!_runFlag)
+ break;
+
+ _timer->update();
+ updateScriptTimers();
+ updateWallOfForceTimers();
+
+ if (_sceneUpdateRequired)
+ drawScene(1);
+
+ if (_envAudioTimer >= _system->getMillis() || (_flags.gameID == GI_EOB1 && (_currentLevel == 0 || _currentLevel > 3)))
+ continue;
+
+ _envAudioTimer = _system->getMillis() + (rollDice(1, 10, 3) * 18 * _tickLength);
+ snd_processEnvironmentalSoundEffect(_flags.gameID == GI_EOB1 ? 30 : (rollDice(1, 2, -1) ? 27 : 28), _currentBlock + rollDice(1, 12, -1));
+ updateEnvironmentalSfx(0);
+ turnUndeadAuto();
+ }
+}
+
+bool EoBCoreEngine::checkPartyStatus(bool handleDeath) {
+ int numChars = 0;
+ for (int i = 0; i < 6; i++)
+ numChars += testCharacter(i, 13);
+
+ if (numChars)
+ return false;
+
+ if (!handleDeath)
+ return true;
+
+ gui_drawAllCharPortraitsWithStats();
+
+ if (checkPartyStatusExtra()) {
+ _screen->setFont(Screen::FID_8_FNT);
+ gui_updateControls();
+ if (_gui->runLoadMenu(0, 0)) {
+ _screen->setFont(Screen::FID_6_FNT);
+ return true;
+ }
+ }
+
+ quitGame();
+ return false;
+}
+
+void EoBCoreEngine::loadItemsAndDecorationsShapes() {
+ releaseItemsAndDecorationsShapes();
+
+ _screen->loadShapeSetBitmap("ITEML1", 5, 3);
+ _largeItemShapes = new const uint8*[_numLargeItemShapes];
+ int div = (_flags.gameID == GI_EOB1) ? 3 : 8;
+ int mul = (_flags.gameID == GI_EOB1) ? 64 : 24;
+
+ for (int i = 0; i < _numLargeItemShapes; i++)
+ _largeItemShapes[i] = _screen->encodeShape((i / div) << 3, (i % div) * mul, 8, 24, false, _cgaMappingItemsL);
+
+ _screen->loadShapeSetBitmap("ITEMS1", 5, 3);
+ _smallItemShapes = new const uint8*[_numSmallItemShapes];
+ for (int i = 0; i < _numSmallItemShapes; i++)
+ _smallItemShapes[i] = _screen->encodeShape((i / div) << 2, (i % div) * mul, 4, 24, false, _cgaMappingItemsS);
+
+ _screen->loadShapeSetBitmap("THROWN", 5, 3);
+ _thrownItemShapes = new const uint8*[_numThrownItemShapes];
+ for (int i = 0; i < _numThrownItemShapes; i++)
+ _thrownItemShapes[i] = _screen->encodeShape((i / div) << 2, (i % div) * mul, 4, 24, false, _cgaMappingThrown);
+
+ _spellShapes = new const uint8*[4];
+ for (int i = 0; i < 4; i++)
+ _spellShapes[i] = _screen->encodeShape(8, i << 5, 6, 32, false, _cgaMappingThrown);
+
+ _firebeamShapes = new const uint8*[3];
+ _firebeamShapes[0] = _screen->encodeShape(16, 0, 4, 24, false, _cgaMappingThrown);
+ _firebeamShapes[1] = _screen->encodeShape(16, 24, 4, 24, false, _cgaMappingThrown);
+ _firebeamShapes[2] = _screen->encodeShape(16, 48, 3, 24, false, _cgaMappingThrown);
+ _redSplatShape = _screen->encodeShape(16, _flags.gameID == GI_EOB1 ? 144 : 72, 5, 24, false, _cgaMappingThrown);
+ _greenSplatShape = _screen->encodeShape(16, _flags.gameID == GI_EOB1 ? 168 : 96, 5, 16, false, _cgaMappingThrown);
+
+ _screen->loadShapeSetBitmap("ITEMICN", 5, 3);
+ _itemIconShapes = new const uint8*[_numItemIconShapes];
+ for (int i = 0; i < _numItemIconShapes; i++)
+ _itemIconShapes[i] = _screen->encodeShape((i % 0x14) << 1, (i / 0x14) << 4, 2, 0x10, false, _cgaMappingIcons);
+
+ _screen->loadShapeSetBitmap("DECORATE", 5, 3);
+
+ if (_flags.gameID == GI_EOB2) {
+ _lightningColumnShape = _screen->encodeShape(18, 88, 4, 64);
+ _wallOfForceShapes = new const uint8*[6];
+ for (int i = 0; i < 6; i++)
+ _wallOfForceShapes[i] = _screen->encodeShape(_wallOfForceShapeDefs[(i << 2)], _wallOfForceShapeDefs[(i << 2) + 1], _wallOfForceShapeDefs[(i << 2) + 2], _wallOfForceShapeDefs[(i << 2) + 3]);
+ }
+
+ _teleporterShapes = new const uint8*[6];
+ for (int i = 0; i < 6; i++)
+ _teleporterShapes[i] = _screen->encodeShape(_teleporterShapeDefs[(i << 2)], _teleporterShapeDefs[(i << 2) + 1], _teleporterShapeDefs[(i << 2) + 2], _teleporterShapeDefs[(i << 2) + 3], false, _cgaMappingDefault);
+ _sparkShapes = new const uint8*[3];
+ _sparkShapes[0] = _screen->encodeShape(29, 0, 2, 16, false, _cgaMappingDeco);
+ _sparkShapes[1] = _screen->encodeShape(31, 0, 2, 16, false, _cgaMappingDeco);
+ _sparkShapes[2] = _screen->encodeShape(33, 0, 2, 16, false, _cgaMappingDeco);
+ _deadCharShape = _screen->encodeShape(0, 88, 4, 32, false, _cgaMappingDeco);
+ _disabledCharGrid = _screen->encodeShape(4, 88, 4, 32, false, _cgaMappingDeco);
+ _blackBoxSmallGrid = _screen->encodeShape(9, 88, 2, 8, false, _cgaMappingDeco);
+ _weaponSlotGrid = _screen->encodeShape(8, 88, 4, 16, false, _cgaMappingDeco);
+ _blackBoxWideGrid = _screen->encodeShape(8, 104, 4, 8, false, _cgaMappingDeco);
+
+ static const uint8 dHeight[] = { 17, 10, 10 };
+ static const uint8 dY[] = { 120, 137, 147 };
+
+ _compassShapes = new const uint8*[12];
+ for (int y = 0; y < 3; y++) {
+ for (int x = 0; x < 4; x++)
+ _compassShapes[(y << 2) + x] = _screen->encodeShape(x * 3, dY[y], 3, dHeight[y], false, _cgaMappingDeco);
+ }
+}
+
+void EoBCoreEngine::releaseItemsAndDecorationsShapes() {
+ if (_largeItemShapes) {
+ for (int i = 0; i < _numLargeItemShapes; i++) {
+ if (_largeItemShapes[i])
+ delete[] _largeItemShapes[i];
+ }
+ delete[] _largeItemShapes;
+ }
+
+ if (_smallItemShapes) {
+ for (int i = 0; i < _numSmallItemShapes; i++) {
+ if (_smallItemShapes[i])
+ delete[] _smallItemShapes[i];
+ }
+ delete[] _smallItemShapes;
+ }
+
+ if (_thrownItemShapes) {
+ for (int i = 0; i < _numThrownItemShapes; i++) {
+ if (_thrownItemShapes[i])
+ delete[] _thrownItemShapes[i];
+ }
+ delete[] _thrownItemShapes;
+ }
+
+ if (_spellShapes) {
+ for (int i = 0; i < 4; i++) {
+ if (_spellShapes[i])
+ delete [] _spellShapes[i];
+ }
+ delete[] _spellShapes;
+ }
+
+ if (_itemIconShapes) {
+ for (int i = 0; i < _numItemIconShapes; i++) {
+ if (_itemIconShapes[i])
+ delete[] _itemIconShapes[i];
+ }
+ delete[] _itemIconShapes;
+ }
+
+ if (_sparkShapes) {
+ for (int i = 0; i < 3; i++) {
+ if (_sparkShapes[i])
+ delete[] _sparkShapes[i];
+ }
+ delete[] _sparkShapes;
+ }
+
+ if (_wallOfForceShapes) {
+ for (int i = 0; i < 6; i++) {
+ if (_wallOfForceShapes[i])
+ delete[] _wallOfForceShapes[i];
+ }
+ delete[] _wallOfForceShapes;
+ }
+
+ if (_teleporterShapes) {
+ for (int i = 0; i < 6; i++) {
+ if (_teleporterShapes[i])
+ delete[] _teleporterShapes[i];
+ }
+ delete[] _teleporterShapes;
+ }
+
+ if (_compassShapes) {
+ for (int i = 0; i < 12; i++) {
+ if (_compassShapes[i])
+ delete[] _compassShapes[i];
+ }
+ delete[] _compassShapes;
+ }
+
+ if (_firebeamShapes) {
+ for (int i = 0; i < 3; i++) {
+ if (_firebeamShapes[i])
+ delete[] _firebeamShapes[i];
+ }
+ delete []_firebeamShapes;
+ }
+
+ delete[] _redSplatShape;
+ delete[] _greenSplatShape;
+ delete[] _deadCharShape;
+ delete[] _disabledCharGrid;
+ delete[] _blackBoxSmallGrid;
+ delete[] _weaponSlotGrid;
+ delete[] _blackBoxWideGrid;
+ delete[] _lightningColumnShape;
+}
+
+void EoBCoreEngine::setHandItem(Item itemIndex) {
+ if (itemIndex == -1)
+ return;
+
+ if (_screen->curDimIndex() == 7 && itemIndex) {
+ printFullItemName(itemIndex);
+ _txt->printMessage(_takenStrings[0]);
+ }
+
+ _itemInHand = itemIndex;
+ int icon = _items[_itemInHand].icon;
+ const uint8 *shp = _itemIconShapes[icon];
+ const uint8 *ovl = 0;
+
+ if (icon && (_items[_itemInHand].flags & 0x80) && (_partyEffectFlags & 2))
+ ovl = _flags.gameID == GI_EOB1 ? ((_configRenderMode == Common::kRenderCGA) ? _itemsOverlayCGA : &_itemsOverlay[icon << 4]) : _screen->generateShapeOverlay(shp, 3);
+
+ int mouseOffs = itemIndex ? 8 : 0;
+ _screen->setMouseCursor(mouseOffs, mouseOffs, shp, ovl);
+}
+
+int EoBCoreEngine::getDexterityArmorClassModifier(int dexterity) {
+ static const int8 mod[] = { 5, 5, 5, 4, 3, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, -1, -2, -3, -4, -4, -5, -5, -5, -6, -6 };
+ return mod[dexterity];
+}
+
+int EoBCoreEngine::generateCharacterHitpointsByLevel(int charIndex, int levelIndex) {
+ EoBCharacter *c = &_characters[charIndex];
+ int m = getClassAndConstHitpointsModifier(c->cClass, c->constitutionCur);
+
+ int h = 0;
+
+ for (int i = 0; i < 3; i++) {
+ if (!(levelIndex & (1 << i)))
+ continue;
+
+ int d = getCharacterClassType(c->cClass, i);
+
+ if (c->level[i] <= _hpIncrPerLevel[6 + i])
+ h += rollDice(1, (d >= 0) ? _hpIncrPerLevel[d] : 0);
+ else
+ h += _hpIncrPerLevel[12 + i];
+
+ h += m;
+ }
+
+ h /= _numLevelsPerClass[c->cClass];
+
+ if (h < 1)
+ h = 1;
+
+ return h;
+}
+
+int EoBCoreEngine::getClassAndConstHitpointsModifier(int cclass, int constitution) {
+ int res = _hpConstModifiers[constitution];
+ // This also applies to EOB1 despite being coded differently there
+ if (res <= 2 || (_classModifierFlags[cclass] & 0x31))
+ return res;
+
+ return 2;
+}
+
+int EoBCoreEngine::getCharacterClassType(int cclass, int levelIndex) {
+ return _characterClassType[cclass * 3 + levelIndex];
+}
+
+int EoBCoreEngine::getModifiedHpLimits(int hpModifier, int constModifier, int level, bool mode) {
+ int s = _hpIncrPerLevel[6 + hpModifier] > level ? level : _hpIncrPerLevel[6 + hpModifier];
+ int res = s;
+
+ if (!mode)
+ res *= (hpModifier >= 0 ? _hpIncrPerLevel[hpModifier] : 0);
+
+ if (level > s) {
+ s = level - s;
+ res += (s * _hpIncrPerLevel[12 + hpModifier]);
+ }
+
+ if (!mode || (constModifier > 0))
+ res += (level * constModifier);
+
+ return res;
+}
+
+Common::String EoBCoreEngine::getCharStrength(int str, int strExt) {
+ if (strExt) {
+ if (strExt == 100)
+ strExt = 0;
+ _strenghtStr = Common::String::format("%d/%02d", str, strExt);
+ } else {
+ _strenghtStr = Common::String::format("%d", str);
+ }
+
+ return _strenghtStr;
+}
+
+int EoBCoreEngine::testCharacter(int16 index, int flags) {
+ if (index == -1)
+ return 0;
+
+ EoBCharacter *c = &_characters[index];
+ int res = 1;
+
+ if (flags & 1)
+ res &= (c->flags & 1);
+
+ if (flags & 2)
+ res &= ((c->hitPointsCur <= -10) || (c->flags & 8)) ? 0 : 1;
+
+ if (flags & 4)
+ res &= ((c->hitPointsCur <= 0) || (c->flags & 8)) ? 0 : 1;
+
+ if (flags & 8)
+ res &= (c->flags & 12) ? 0 : 1;
+
+ if (flags & 0x20)
+ res &= (c->flags & 4) ? 0 : 1;
+
+ if (flags & 0x10)
+ res &= (c->flags & 2) ? 0 : 1;
+
+ if (flags & 0x40)
+ res &= (c->food <= 0) ? 0 : 1;
+
+ return res;
+}
+
+int EoBCoreEngine::getNextValidCharIndex(int curCharIndex, int searchStep) {
+ do {
+ curCharIndex += searchStep;
+ if (curCharIndex < 0)
+ curCharIndex = 5;
+ if (curCharIndex > 5)
+ curCharIndex = 0;
+ } while (!testCharacter(curCharIndex, 1));
+
+ return curCharIndex;
+}
+
+void EoBCoreEngine::recalcArmorClass(int index) {
+ EoBCharacter *c = &_characters[index];
+ int acm = getDexterityArmorClassModifier(c->dexterityCur);
+ c->armorClass = 10 + acm;
+
+ static uint8 slot[] = { 17, 0, 1, 18 };
+ for (int i = 0; i < 4; i++) {
+ int itm = c->inventory[slot[i]];
+ if (!itm)
+ continue;
+
+ if (i == 2) {
+ if (!validateWeaponSlotItem(index, 1))
+ continue;
+ }
+
+ int tp = _items[itm].type;
+
+ if (!(_itemTypes[tp].allowedClasses & _classModifierFlags[c->cClass]) || (_itemTypes[tp].extraProperties & 0x7f) || (i >= 1 && i <= 2 && tp != 27 && !(_flags.gameID == GI_EOB2 && tp == 57)))
+ continue;
+
+ c->armorClass += _itemTypes[tp].armorClass;
+ c->armorClass -= _items[itm].value;
+ }
+
+ if (!_items[c->inventory[17]].value) {
+ int8 m1 = 0;
+ int8 m2 = 0;
+
+ if (c->inventory[25]) {
+ if (!(_itemTypes[_items[c->inventory[25]].type].extraProperties & 0x7f))
+ m1 = _items[c->inventory[25]].value;
+ }
+
+ if (c->inventory[26]) {
+ if (!(_itemTypes[_items[c->inventory[26]].type].extraProperties & 0x7f))
+ m2 = _items[c->inventory[26]].value;
+ }
+
+ c->armorClass -= MAX(m1, m2);
+ }
+
+ if (c->effectsRemainder[0] > 0) {
+ if (c->armorClass <= (acm + 6))
+ c->effectsRemainder[0] = 0;
+ else
+ c->armorClass = (acm + 6);
+ }
+
+ // shield
+ if ((c->effectFlags & 8) && (c->armorClass > 4))
+ c->armorClass = 4;
+
+ // magical vestment
+ if (c->effectFlags & 0x4000) {
+ int8 m1 = 5;
+
+ if (getClericPaladinLevel(index) > 5)
+ m1 += ((getClericPaladinLevel(index) - 5) / 3);
+
+ if (c->armorClass > m1)
+ c->armorClass = m1;
+ }
+
+ if (c->armorClass < -10)
+ c->armorClass = -10;
+}
+
+int EoBCoreEngine::validateWeaponSlotItem(int index, int slot) {
+ EoBCharacter *c = &_characters[index];
+ int itm1 = c->inventory[0];
+ int r = itemUsableByCharacter(index, itm1);
+ int tp1 = _items[itm1].type;
+
+ if (!slot)
+ return (!itm1 || r) ? 1 : 0;
+
+ int itm2 = c->inventory[1];
+ r = itemUsableByCharacter(index, itm2);
+ int tp2 = _items[itm2].type;
+
+ if (itm1 && _itemTypes[tp1].requiredHands == 2)
+ return 0;
+
+ if (!itm2)
+ return 1;
+
+ int f = (_itemTypes[tp2].extraProperties & 0x7f);
+ if (f <= 0 || f > 3)
+ return r;
+
+ if (_itemTypes[tp2].requiredHands)
+ return 0;
+
+ return r;
+}
+
+int EoBCoreEngine::getClericPaladinLevel(int index) {
+ if (_castScrollSlot)
+ return 9;
+
+ if (index == -1)
+ return (_currentLevel < 7) ? 5 : 9;
+
+ int l = getCharacterLevelIndex(2, _characters[index].cClass);
+ if (l > -1)
+ return _characters[index].level[l];
+
+ l = getCharacterLevelIndex(4, _characters[index].cClass);
+ if (l > -1) {
+ if (_characters[index].level[l] > 8)
+ return _characters[index].level[l] - 8;
+ }
+
+ return 1;
+}
+
+int EoBCoreEngine::getMageLevel(int index) {
+ if (_castScrollSlot)
+ return 9;
+
+ if (index == -1)
+ return (_currentLevel < 7) ? 5 : 9;
+
+ int l = getCharacterLevelIndex(1, _characters[index].cClass);
+ return (l > -1) ? _characters[index].level[l] : 1;
+}
+
+int EoBCoreEngine::getCharacterLevelIndex(int type, int cClass) {
+ if (getCharacterClassType(cClass, 0) == type)
+ return 0;
+
+ if (getCharacterClassType(cClass, 1) == type)
+ return 1;
+
+ if (getCharacterClassType(cClass, 2) == type)
+ return 2;
+
+ return -1;
+}
+
+int EoBCoreEngine::countCharactersWithSpecificItems(int16 itemType, int16 itemValue) {
+ int res = 0;
+ for (int i = 0; i < 6; i++) {
+ if (!testCharacter(i, 1))
+ continue;
+ if (checkInventoryForItem(i, itemType, itemValue) != -1)
+ res++;
+ }
+ return res;
+}
+
+int EoBCoreEngine::checkInventoryForItem(int character, int16 itemType, int16 itemValue) {
+ if (character < 0)
+ return -1;
+
+ for (int i = 0; i < 27; i++) {
+ uint16 inv = _characters[character].inventory[i];
+ if (!inv)
+ continue;
+ if (_items[inv].type != itemType && itemType != -1)
+ continue;
+ if (_items[inv].value == itemValue || itemValue == -1)
+ return i;
+ }
+ return -1;
+}
+
+void EoBCoreEngine::modifyCharacterHitpoints(int character, int16 points) {
+ if (!testCharacter(character, 3))
+ return;
+
+ EoBCharacter *c = &_characters[character];
+ c->hitPointsCur += points;
+ if (c->hitPointsCur > c->hitPointsMax)
+ c->hitPointsCur = c->hitPointsMax;
+
+ gui_drawHitpoints(character);
+ gui_drawCharPortraitWithStats(character);
+}
+
+void EoBCoreEngine::neutralizePoison(int character) {
+ _characters[character].flags &= ~2;
+ _characters[character].effectFlags &= ~0x2000;
+ deleteCharEventTimer(character, -34);
+ gui_drawCharPortraitWithStats(character);
+}
+
+void EoBCoreEngine::npcSequence(int npcIndex) {
+ _screen->loadShapeSetBitmap("OUTTAKE", 5, 3);
+ _screen->copyRegion(0, 0, 0, 0, 176, 120, 0, 6, Screen::CR_NO_P_CHECK);
+
+ drawNpcScene(npcIndex);
+
+ Common::SeekableReadStream *s = _res->createReadStream("TEXT.DAT");
+ _screen->loadFileDataToPage(s, 5, 32000);
+ delete s;
+
+ gui_drawBox(0, 121, 320, 79, guiSettings()->colors.frame1, guiSettings()->colors.frame2, guiSettings()->colors.fill);
+ _txt->setupField(9, true);
+ _txt->resetPageBreakString();
+
+ runNpcDialogue(npcIndex);
+
+ _txt->removePageBreakFlag();
+ gui_restorePlayField();
+}
+
+void EoBCoreEngine::initNpc(int npcIndex) {
+ EoBCharacter *c = _characters;
+ int i = 0;
+ for (; i < 6; i++) {
+ if (!(_characters[i].flags & 1)) {
+ c = &_characters[i];
+ break;
+ }
+ }
+
+ delete[] c->faceShape;
+ memcpy(c, &_npcPreset[npcIndex], sizeof(EoBCharacter));
+ recalcArmorClass(i);
+
+ for (i = 0; i < 25; i++) {
+ if (!c->inventory[i])
+ continue;
+ c->inventory[i] = duplicateItem(c->inventory[i]);
+ }
+
+ _screen->loadShapeSetBitmap(_flags.gameID == GI_EOB2 ? "OUTPORTS" : "OUTTAKE", 3, 3);
+ _screen->_curPage = 2;
+ c->faceShape = _screen->encodeShape(npcIndex << 2, _flags.gameID == GI_EOB2 ? 0 : 160, 4, 32, true, _cgaMappingDefault);
+ _screen->_curPage = 0;
+}
+
+int EoBCoreEngine::npcJoinDialogue(int npcIndex, int queryJoinTextId, int confirmJoinTextId, int noJoinTextId) {
+ gui_drawDialogueBox();
+ _txt->printDialogueText(queryJoinTextId, 0);
+
+ int r = runDialogue(-1, 2, _yesNoStrings[0], _yesNoStrings[1]) - 1;
+ if (r == 0) {
+ if (confirmJoinTextId == -1) {
+ Common::String tmp = Common::String::format(_npcJoinStrings[0], _npcPreset[npcIndex].name);
+ _txt->printDialogueText(tmp.c_str(), true);
+ } else {
+ _txt->printDialogueText(confirmJoinTextId, _okStrings[0]);
+ }
+
+ if (prepareForNewPartyMember(33, npcIndex + 1))
+ initNpc(npcIndex);
+
+ } else if (r == 1) {
+ _txt->printDialogueText(noJoinTextId, _okStrings[0]);
+ }
+
+ return r ^ 1;
+}
+
+int EoBCoreEngine::prepareForNewPartyMember(int16 itemType, int16 itemValue) {
+ int numChars = 0;
+ for (int i = 0; i < 6; i++)
+ numChars += (_characters[i].flags & 1);
+
+ if (numChars < 6) {
+ deletePartyItems(itemType, itemValue);
+ } else {
+ gui_drawDialogueBox();
+ _txt->printDialogueText(_npcMaxStrings[0]);
+ int r = runDialogue(-1, 7, _characters[0].name, _characters[1].name, _characters[2].name, _characters[3].name,
+ _characters[4].name, _characters[5].name, _abortStrings[0]) - 1;
+
+ if (r == 6)
+ return 0;
+
+ deletePartyItems(itemType, itemValue);
+ removeCharacterFromParty(r);
+ }
+
+ return 1;
+}
+
+void EoBCoreEngine::dropCharacter(int charIndex) {
+ if (!testCharacter(charIndex, 1))
+ return;
+
+ removeCharacterFromParty(charIndex);
+
+ if (charIndex < 5)
+ exchangeCharacters(charIndex, testCharacter(5, 1) ? 5 : 4);
+
+ gui_processCharPortraitClick(0);
+ gui_setPlayFieldButtons();
+ setupCharacterTimers();
+}
+
+void EoBCoreEngine::removeCharacterFromParty(int charIndex) {
+ EoBCharacter *c = &_characters[charIndex];
+ c->flags = 0;
+
+ for (int i = 0; i < 27; i++) {
+ if (i == 16 || !c->inventory[i])
+ continue;
+
+ setItemPosition((Item *)&_levelBlockProperties[_currentBlock & 0x3ff].drawObjects, _currentBlock, c->inventory[i], _dropItemDirIndex[(_currentDirection << 2) + rollDice(1, 2, -1)]);
+ c->inventory[i] = 0;
+ }
+
+ while (c->inventory[16])
+ setItemPosition((Item *)&_levelBlockProperties[_currentBlock & 0x3ff].drawObjects, _currentBlock, getQueuedItem(&c->inventory[16], 0, -1), _dropItemDirIndex[(_currentDirection << 2) + rollDice(1, 2, -1)]);
+
+ c->inventory[16] = 0;
+
+ if (_updateCharNum == charIndex)
+ _updateCharNum = 0;
+
+ setupCharacterTimers();
+}
+
+void EoBCoreEngine::exchangeCharacters(int charIndex1, int charIndex2) {
+ EoBCharacter temp;
+ memcpy(&temp, &_characters[charIndex1], sizeof(EoBCharacter));
+ memcpy(&_characters[charIndex1], &_characters[charIndex2], sizeof(EoBCharacter));
+ memcpy(&_characters[charIndex2], &temp, sizeof(EoBCharacter));
+}
+
+void EoBCoreEngine::increasePartyExperience(int16 points) {
+ int cnt = 0;
+ for (int i = 0; i < 6; i++) {
+ if (testCharacter(i, 3))
+ cnt++;
+ }
+
+ if (cnt <= 0)
+ return;
+
+ points /= cnt;
+
+ for (int i = 0; i < 6; i++) {
+ if (!testCharacter(i, 3))
+ continue;
+ increaseCharacterExperience(i, points);
+ }
+}
+
+void EoBCoreEngine::increaseCharacterExperience(int charIndex, int32 points) {
+ int cl = _characters[charIndex].cClass;
+ points /= _numLevelsPerClass[cl];
+
+ for (int i = 0; i < 3; i++) {
+ if (getCharacterClassType(cl, i) == -1)
+ continue;
+ _characters[charIndex].experience[i] += points;
+
+ uint32 er = getRequiredExperience(cl, i, _characters[charIndex].level[i] + 1);
+ if (er == 0xffffffff)
+ continue;
+
+ if (_characters[charIndex].experience[i] >= er)
+ increaseCharacterLevel(charIndex, i);
+ }
+}
+
+uint32 EoBCoreEngine::getRequiredExperience(int cClass, int levelIndex, int level) {
+ cClass = getCharacterClassType(cClass, levelIndex);
+ if (cClass == -1)
+ return 0xffffffff;
+
+ const uint32 *tbl = _expRequirementTables[cClass];
+ return tbl[level - 1];
+}
+
+void EoBCoreEngine::increaseCharacterLevel(int charIndex, int levelIndex) {
+ _characters[charIndex].level[levelIndex]++;
+ int hpInc = generateCharacterHitpointsByLevel(charIndex, 1 << levelIndex);
+ _characters[charIndex].hitPointsCur += hpInc;
+ _characters[charIndex].hitPointsMax += hpInc;
+
+ gui_drawCharPortraitWithStats(charIndex);
+ _txt->printMessage(_levelGainStrings[0], -1, _characters[charIndex].name);
+ snd_playSoundEffect(23);
+}
+
+void EoBCoreEngine::setWeaponSlotStatus(int charIndex, int mode, int slot) {
+ if (mode == 0 || mode == 2)
+ _characters[charIndex].disabledSlots ^= (1 << slot);
+ else if (mode != 1)
+ return;
+
+ _characters[charIndex].slotStatus[slot] = 0;
+ gui_drawCharPortraitWithStats(charIndex);
+}
+
+void EoBCoreEngine::setupDialogueButtons(int presetfirst, int numStr, va_list &args) {
+ _dialogueNumButtons = numStr;
+ _dialogueHighlightedButton = 0;
+
+ for (int i = 0; i < numStr; i++) {
+ const char *s = va_arg(args, const char *);
+ if (s)
+ _dialogueButtonString[i] = s;
+ else
+ _dialogueNumButtons = numStr = i;
+ }
+
+ static const uint16 prsX[] = { 59, 166, 4, 112, 220, 4, 112, 220, 4, 112, 220, 4, 112, 220 };
+ static const uint8 prsY[] = { 0, 0, 0, 0, 0, 12, 12, 12, 24, 24, 24, 36, 36, 36 };
+
+ const ScreenDim *dm = screen()->_curDim;
+ int yOffs = (_txt->lineCount() + 1) * _screen->getFontHeight() + dm->sy + 4;
+
+ _dialogueButtonPosX = &prsX[presetfirst];
+ _dialogueButtonPosY = &prsY[presetfirst];
+ _dialogueButtonYoffs = yOffs;
+
+ drawDialogueButtons();
+
+ if (!shouldQuit())
+ removeInputTop();
+}
+
+void EoBCoreEngine::initDialogueSequence() {
+ _npcSequenceSub = -1;
+ _txt->setWaitButtonMode(0);
+ _dialogueField = true;
+
+ _dialogueLastBitmap[0] = 0;
+
+ _txt->resetPageBreakString();
+ gui_updateControls();
+ //_allowSkip = true;
+
+ snd_stopSound();
+ Common::SeekableReadStream *s = _res->createReadStream("TEXT.DAT");
+ _screen->loadFileDataToPage(s, 5, 32000);
+ _txt->setupField(9, 0);
+ delete s;
+}
+
+void EoBCoreEngine::restoreAfterDialogueSequence() {
+ _txt->allowPageBreak(false);
+ _dialogueField = false;
+
+ _dialogueLastBitmap[0] = 0;
+
+ gui_restorePlayField();
+ //_allowSkip = false;
+ _screen->setScreenDim(7);
+
+ if (_flags.gameID == GI_EOB2)
+ snd_playSoundEffect(2);
+
+ _sceneUpdateRequired = true;
+}
+
+void EoBCoreEngine::drawSequenceBitmap(const char *file, int destRect, int x1, int y1, int flags) {
+ static const uint8 frameX[] = { 1, 0 };
+ static const uint8 frameY[] = { 8, 0 };
+ static const uint8 frameW[] = { 20, 40 };
+ static const uint8 frameH[] = { 96, 121 };
+
+ int page = ((flags & 2) || destRect) ? 0 : 6;
+
+ if (scumm_stricmp(_dialogueLastBitmap, file)) {
+ if (!destRect) {
+ if (!(flags & 1)) {
+ _screen->loadEoBBitmap("BORDER", 0, 3, 3, 2);
+ _screen->copyRegion(0, 0, 0, 0, 184, 121, 2, page, Screen::CR_NO_P_CHECK);
+ } else {
+ _screen->copyRegion(0, 0, 0, 0, 184, 121, 0, page, Screen::CR_NO_P_CHECK);
+ }
+
+ if (!page)
+ _screen->copyRegion(0, 0, 0, 0, 184, 121, 2, 6, Screen::CR_NO_P_CHECK);
+ }
+
+ _screen->loadEoBBitmap(file, 0, 3, 3, 2);
+ strcpy(_dialogueLastBitmap, file);
+ }
+
+ if (flags & 2)
+ _screen->crossFadeRegion(x1 << 3, y1, frameX[destRect] << 3, frameY[destRect], frameW[destRect] << 3, frameH[destRect], 2, page);
+ else
+ _screen->copyRegion(x1 << 3, y1, frameX[destRect] << 3, frameY[destRect], frameW[destRect] << 3, frameH[destRect], 2, page, Screen::CR_NO_P_CHECK);
+
+ if (page == 6)
+ _screen->copyRegion(0, 0, 0, 0, 184, 121, 6, 0, Screen::CR_NO_P_CHECK);
+
+ _screen->updateScreen();
+}
+
+int EoBCoreEngine::runDialogue(int dialogueTextId, int numStr, ...) {
+ if (dialogueTextId != -1)
+ txt()->printDialogueText(dialogueTextId, 0);
+
+ va_list args;
+ va_start(args, numStr);
+ if (numStr > 2)
+ setupDialogueButtons(2, numStr, args);
+ else
+ setupDialogueButtons(0, numStr, args);
+ va_end(args);
+
+ int res = 0;
+ while (res == 0 && !shouldQuit())
+ res = processDialogue();
+
+ gui_drawDialogueBox();
+
+ return res;
+}
+
+void EoBCoreEngine::restParty_displayWarning(const char *str) {
+ int od = _screen->curDimIndex();
+ _screen->setScreenDim(7);
+ Screen::FontId of = _screen->setFont(Screen::FID_6_FNT);
+ _screen->setCurPage(0);
+
+ _txt->printMessage(Common::String::format("\r%s\r", str).c_str());
+
+ _screen->setFont(of);
+ _screen->setScreenDim(od);
+}
+
+bool EoBCoreEngine::restParty_updateMonsters() {
+ bool sfxEnabled = _sound->sfxEnabled();
+ bool musicEnabled = _sound->musicEnabled();
+ _sound->enableSFX(false);
+ _sound->enableMusic(false);
+
+ for (int i = 0; i < 5; i++) {
+ _partyResting = true;
+ Screen::FontId of = _screen->setFont(Screen::FID_6_FNT);
+ int od = _screen->curDimIndex();
+ _screen->setScreenDim(7);
+ updateMonsters(0);
+ updateMonsters(1);
+ timerProcessFlyingObjects(0);
+ _screen->setScreenDim(od);
+ _screen->setFont(of);
+ _partyResting = false;
+
+ for (int ii = 0; ii < 30; ii++) {
+ if (_monsters[ii].mode == 8)
+ continue;
+ if (getBlockDistance(_currentBlock, _monsters[ii].block) >= 2)
+ continue;
+
+ restParty_displayWarning(_menuStringsRest4[0]);
+ _sound->enableSFX(sfxEnabled);
+ _sound->enableMusic(musicEnabled);
+ return true;
+ }
+ }
+
+ _sound->enableSFX(sfxEnabled);
+ _sound->enableMusic(musicEnabled);
+ return false;
+}
+
+int EoBCoreEngine::restParty_getCharacterWithLowestHp() {
+ int lhp = 900;
+ int res = -1;
+
+ for (int i = 0; i < 6; i++) {
+ if (!testCharacter(i, 3))
+ continue;
+ if (_characters[i].hitPointsCur >= _characters[i].hitPointsMax)
+ continue;
+ if (_characters[i].hitPointsCur < lhp) {
+ lhp = _characters[i].hitPointsCur;
+ res = i;
+ }
+ }
+
+ return res + 1;
+}
+
+bool EoBCoreEngine::restParty_checkHealSpells(int charIndex) {
+ static const uint8 eob1healSpells[] = { 2, 15, 20 };
+ static const uint8 eob2healSpells[] = { 3, 16, 20 };
+ const uint8 *spells = _flags.gameID == GI_EOB1 ? eob1healSpells : eob2healSpells;
+ const int8 *list = _characters[charIndex].clericSpells;
+
+ for (int i = 0; i < 80; i++) {
+ int s = list[i] < 0 ? -list[i] : list[i];
+ if (s == spells[0] || s == spells[1] || s == spells[2])
+ return true;
+ }
+
+ return false;
+}
+
+bool EoBCoreEngine::restParty_checkSpellsToLearn() {
+ for (int i = 0; i < 6; i++) {
+ if (!testCharacter(i, 0x43))
+ continue;
+
+ if ((getCharacterLevelIndex(2, _characters[i].cClass) != -1 || getCharacterLevelIndex(4, _characters[i].cClass) != -1) && (checkInventoryForItem(i, 30, -1) != -1)) {
+ for (int ii = 0; ii < 80; ii++) {
+ if (_characters[i].clericSpells[ii] < 0)
+ return true;
+ }
+ }
+
+ if ((getCharacterLevelIndex(1, _characters[i].cClass) != -1) && (checkInventoryForItem(i, 29, -1) != -1)) {
+ for (int ii = 0; ii < 80; ii++) {
+ if (_characters[i].mageSpells[ii] < 0)
+ return true;
+ }
+ }
+ }
+
+ return false;
+}
+
+bool EoBCoreEngine::restParty_extraAbortCondition() {
+ return false;
+}
+
+void EoBCoreEngine::delay(uint32 millis, bool, bool) {
+ while (millis && !shouldQuit() && !(_allowSkip && skipFlag())) {
+ updateInput();
+ uint32 step = MIN<uint32>(millis, (_tickLength / 5));
+ _system->delayMillis(step);
+ millis -= step;
+ }
+}
+
+void EoBCoreEngine::displayParchment(int id) {
+ _txt->setWaitButtonMode(1);
+ _txt->resetPageBreakString();
+ gui_updateControls();
+
+ if (id >= 0) {
+ // display text
+ Common::SeekableReadStream *s = _res->createReadStream("TEXT.DAT");
+ _screen->loadFileDataToPage(s, 5, 32000);
+ gui_drawBox(0, 0, 176, 175, guiSettings()->colors.frame1, guiSettings()->colors.frame2, guiSettings()->colors.fill);
+ _txt->setupField(12, 1);
+ if (_flags.gameID == GI_EOB2)
+ id++;
+ _txt->printDialogueText(id, _okStrings[0]);
+
+ } else {
+ // display bitmap
+ id = -id - 1;
+ static const uint8 x[] = { 0, 20, 0 };
+ static const uint8 y[] = { 0, 0, 96 };
+ drawSequenceBitmap("MAP", 0, x[id], y[id], 0);
+
+ removeInputTop();
+ while (!shouldQuit()) {
+ delay(_tickLength);
+ if (checkInput(0, false, 0) & 0xff)
+ break;
+ removeInputTop();
+ }
+ removeInputTop();
+ }
+
+ restoreAfterDialogueSequence();
+}
+
+int EoBCoreEngine::countResurrectionCandidates() {
+ _rrCount = 0;
+ memset(_rrNames, 0, 10 * sizeof(const char *));
+
+ for (int i = 0; i < 6; i++) {
+ if (!testCharacter(i, 1))
+ continue;
+ if (_characters[i].hitPointsCur != -10)
+ continue;
+
+ _rrNames[_rrCount] = _characters[i].name;
+ _rrId[_rrCount++] = i;
+ }
+
+ for (int i = 0; i < 6; i++) {
+ if (!testCharacter(i, 1))
+ continue;
+
+ for (int ii = 0; ii < 27; ii++) {
+ uint16 inv = _characters[i].inventory[ii];
+ if (!inv)
+ continue;
+
+ if ((_flags.gameID == GI_EOB1 && ((_itemTypes[_items[inv].type].extraProperties & 0x7f) != 8)) || (_flags.gameID == GI_EOB2 && _items[inv].type != 33))
+ continue;
+
+ _rrNames[_rrCount] = _npcPreset[_items[inv].value - 1].name;
+ _rrId[_rrCount++] = -_items[inv].value;
+ }
+ }
+
+ if (_itemInHand > 0) {
+ if ((_flags.gameID == GI_EOB1 && ((_itemTypes[_items[_itemInHand].type].extraProperties & 0x7f) == 8)) || (_flags.gameID == GI_EOB2 && _items[_itemInHand].type == 33)) {
+ _rrNames[_rrCount] = _npcPreset[_items[_itemInHand].value - 1].name;
+ _rrId[_rrCount++] = -_items[_itemInHand].value;
+ }
+ }
+
+ return _rrCount;
+}
+
+void EoBCoreEngine::seq_portal() {
+ uint8 *shapes1[5];
+ uint8 *shapes2[5];
+ uint8 *shapes3[5];
+ uint8 *shape0;
+
+ _screen->loadShapeSetBitmap("PORTALA", 5, 3);
+
+ for (int i = 0; i < 5; i++) {
+ shapes1[i] = _screen->encodeShape(i * 3, 0, 3, 75, false, _cgaMappingDefault);
+ shapes2[i] = _screen->encodeShape(i * 3, 80, 3, 75, false, _cgaMappingDefault);
+ shapes3[i] = _screen->encodeShape(15, i * 18, 15, 18, false, _cgaMappingDefault);
+ }
+
+ shape0 = _screen->encodeShape(30, 0, 8, 77, false, _cgaMappingDefault);
+ _screen->loadEoBBitmap("PORTALB", _cgaMappingDefault, 5, 3, 2);
+
+ snd_playSoundEffect(33);
+ snd_playSoundEffect(19);
+ _screen->copyRegion(24, 0, 24, 0, 144, 104, 2, 5, Screen::CR_NO_P_CHECK);
+ _screen->copyRegion(24, 0, 24, 0, 144, 104, 0, 2, Screen::CR_NO_P_CHECK);
+ _screen->drawShape(2, shapes3[0], 28, 9, 0);
+ _screen->drawShape(2, shapes1[0], 34, 28, 0);
+ _screen->drawShape(2, shapes2[0], 120, 28, 0);
+ _screen->drawShape(2, shape0, 56, 27, 0);
+ _screen->crossFadeRegion(24, 0, 24, 0, 144, 104, 2, 0);
+ _screen->copyRegion(24, 0, 24, 0, 144, 104, 5, 2, Screen::CR_NO_P_CHECK);
+ delay(30 * _tickLength);
+
+ for (const int8 *pos = _portalSeq; *pos > -1 && !shouldQuit();) {
+ int s = *pos++;
+ _screen->drawShape(0, shapes3[s], 28, 9, 0);
+ _screen->drawShape(0, shapes1[s], 34, 28, 0);
+ _screen->drawShape(0, shapes2[s], 120, 28, 0);
+
+ if ((s == 1) && (pos >= _portalSeq + 3)) {
+ if (*(pos - 3) == 0) {
+ snd_playSoundEffect(24);
+ snd_playSoundEffect(86);
+ }
+ }
+
+ s = *pos++;
+ if (s == 0) {
+ _screen->drawShape(0, shape0, 56, 27, 0);
+ } else {
+ s--;
+ _screen->copyRegion((s % 5) << 6, s / 5 * 77, 56, 27, 64, 77, 2, 0, Screen::CR_NO_P_CHECK);
+ }
+
+ if (s == 1)
+ snd_playSoundEffect(31);
+ else if (s == 3) {
+ if (*(pos - 2) == 3)
+ snd_playSoundEffect(90);
+ }
+
+ _screen->updateScreen();
+ delay(2 * _tickLength);
+ }
+
+ delete[] shape0;
+ for (int i = 0; i < 5; i++) {
+ delete[] shapes1[i];
+ delete[] shapes2[i];
+ delete[] shapes3[i];
+ }
+}
+
+bool EoBCoreEngine::checkPassword() {
+ char answ[20];
+ Screen::FontId of = _screen->setFont(Screen::FID_8_FNT);
+ _screen->copyPage(0, _useHiResDithering ? 4 : 10);
+
+ _screen->setScreenDim(13);
+ gui_drawBox(_screen->_curDim->sx << 3, _screen->_curDim->sy, _screen->_curDim->w << 3, _screen->_curDim->h, guiSettings()->colors.frame1, guiSettings()->colors.frame2, -1);
+ gui_drawBox((_screen->_curDim->sx << 3) + 1, _screen->_curDim->sy + 1, (_screen->_curDim->w << 3) - 2, _screen->_curDim->h - 2, guiSettings()->colors.frame1, guiSettings()->colors.frame2, guiSettings()->colors.fill);
+ _screen->modifyScreenDim(13, _screen->_curDim->sx + 1, _screen->_curDim->sy + 2, _screen->_curDim->w - 2, _screen->_curDim->h - 16);
+
+ for (int i = 0; i < 3; i++) {
+ _screen->fillRect(_screen->_curDim->sx << 3, _screen->_curDim->sy, ((_screen->_curDim->sx + _screen->_curDim->w) << 3) - 1, (_screen->_curDim->sy + _screen->_curDim->h) - 1, guiSettings()->colors.fill);
+ int c = rollDice(1, _mnNumWord - 1, -1);
+ const uint8 *shp = (_mnDef[c << 2] < _numLargeItemShapes) ? _largeItemShapes[_mnDef[c << 2]] : (_mnDef[c << 2] < 15 ? 0 : _smallItemShapes[_mnDef[c << 2] - 15]);
+ assert(shp);
+ _screen->drawShape(0, shp, 100, 2, 13);
+ _screen->printShadedText(Common::String::format(_mnPrompt[0], _mnDef[(c << 2) + 1], _mnDef[(c << 2) + 2]).c_str(), (_screen->_curDim->sx + 1) << 3, _screen->_curDim->sy, _screen->_curDim->unk8, guiSettings()->colors.fill);
+ memset(answ, 0, 20);
+ gui_drawBox(76, 100, 133, 14, guiSettings()->colors.frame2, guiSettings()->colors.frame1, -1);
+ gui_drawBox(77, 101, 131, 12, guiSettings()->colors.frame2, guiSettings()->colors.frame1, -1);
+ if (_gui->getTextInput(answ, 10, 103, 15, _screen->_curDim->unk8, guiSettings()->colors.fill, 8) < 0)
+ i = 3;
+ if (!scumm_stricmp(_mnWord[c], answ))
+ break;
+ else if (i == 2)
+ return false;
+ }
+
+ _screen->modifyScreenDim(13, _screen->_curDim->sx - 1, _screen->_curDim->sy - 2, _screen->_curDim->w + 2, _screen->_curDim->h + 16);
+ _screen->setFont(of);
+ _screen->copyPage(_useHiResDithering ? 4 : 10, 0);
+ return true;
+}
+
+void EoBCoreEngine::useSlotWeapon(int charIndex, int slotIndex, Item item) {
+ EoBCharacter *c = &_characters[charIndex];
+ int tp = item ? _items[item].type : 0;
+
+ if (c->effectFlags & 0x40)
+ removeCharacterEffect(10, charIndex, 1); // remove invisibility effect
+
+ int ep = _itemTypes[tp].extraProperties & 0x7f;
+ int8 inflict = 0;
+
+ if (ep == 1) {
+ inflict = closeDistanceAttack(charIndex, item);
+ if (!inflict)
+ inflict = -1;
+ snd_playSoundEffect(32);
+ } else if (ep == 2) {
+ inflict = thrownAttack(charIndex, slotIndex, item);
+ } else if (ep == 3) {
+ inflict = projectileWeaponAttack(charIndex, item);
+ gui_drawCharPortraitWithStats(charIndex);
+ }
+
+ if (inflict > 0) {
+ if (_items[item].flags & 8) {
+ c->hitPointsCur += inflict;
+ gui_drawCharPortraitWithStats(charIndex);
+ }
+
+ if (_items[item].flags & 0x10)
+ c->inventory[slotIndex] = 0;
+
+ inflictMonsterDamage(&_monsters[_dstMonsterIndex], inflict, true);
+ }
+
+ c->disabledSlots ^= (1 << slotIndex);
+ c->slotStatus[slotIndex] = inflict;
+
+ gui_drawCharPortraitWithStats(charIndex);
+ setCharEventTimer(charIndex, 18, inflict >= -2 ? slotIndex + 2 : slotIndex, 1);
+}
+
+int EoBCoreEngine::closeDistanceAttack(int charIndex, Item item) {
+ if (charIndex > 1)
+ return -3;
+
+ uint16 d = calcNewBlockPosition(_currentBlock, _currentDirection);
+ int r = getClosestMonster(charIndex, d);
+
+ if (r == -1) {
+ uint8 w = _specialWallTypes[_levelBlockProperties[d].walls[_sceneDrawVarDown]];
+ if (w == 0xff) {
+ if (_flags.gameID == GI_EOB1) {
+ _levelBlockProperties[d].walls[_sceneDrawVarDown]++;
+ _levelBlockProperties[d].walls[_sceneDrawVarDown ^ 2]++;
+
+ } else {
+ for (int i = 0; i < 4; i++) {
+ if (_specialWallTypes[_levelBlockProperties[d].walls[i]] == 0xff)
+ _levelBlockProperties[d].walls[i]++;
+ }
+ }
+ _sceneUpdateRequired = true;
+
+ } else if ((_flags.gameID == GI_EOB1) || (_flags.gameID == GI_EOB2 && w != 8 && w != 9)) {
+ return -1;
+ }
+
+ return (_flags.gameID == GI_EOB2 && ((_itemTypes[_items[item].type].allowedClasses & 4) || !item)) ? -5 : -2;
+
+ } else {
+ if (_monsters[r].flags & 0x20) {
+ killMonster(&_monsters[r], 1);
+ _txt->printMessage(_monsterDustStrings[0]);
+ return -2;
+ }
+
+ if (!characterAttackHitTest(charIndex, r, item, 1))
+ return -1;
+
+ uint16 flg = 0x100;
+
+ if (isMagicEffectItem(item))
+ flg |= 1;
+
+ _dstMonsterIndex = r;
+ return calcMonsterDamage(&_monsters[r], charIndex, item, 1, flg, 5, 3);
+ }
+
+ return 0;
+}
+
+int EoBCoreEngine::thrownAttack(int charIndex, int slotIndex, Item item) {
+ int d = charIndex > 3 ? charIndex - 2 : charIndex;
+ if (!launchObject(charIndex, item, _currentBlock, _dropItemDirIndex[(_currentDirection << 2) + d], _currentDirection, _items[item].type))
+ return 0;
+
+ snd_playSoundEffect(11);
+ _characters[charIndex].inventory[slotIndex] = 0;
+ reloadWeaponSlot(charIndex, slotIndex, -1, 0);
+ _sceneUpdateRequired = true;
+ return 0;
+}
+
+int EoBCoreEngine::projectileWeaponAttack(int charIndex, Item item) {
+ int tp = _items[item].type;
+
+ if (_flags.gameID == GI_EOB1)
+ assert(tp >= 7);
+
+ int t = _projectileWeaponAmmoTypes[_flags.gameID == GI_EOB1 ? tp - 7 : tp];
+ Item ammoItem = 0;
+
+ if (t == 16) {
+ if (_characters[charIndex].inventory[0] && _items[_characters[charIndex].inventory[0]].type == 16)
+ SWAP(ammoItem, _characters[charIndex].inventory[0]);
+ else if (_characters[charIndex].inventory[1] && _items[_characters[charIndex].inventory[1]].type == 16)
+ SWAP(ammoItem, _characters[charIndex].inventory[1]);
+ else if (_characters[charIndex].inventory[16])
+ ammoItem = getQueuedItem(&_characters[charIndex].inventory[16], 0, -1);
+
+ } else {
+ for (int i = 0; i < 27; i++) {
+ if (_items[_characters[charIndex].inventory[i]].type == t) {
+ SWAP(ammoItem, _characters[charIndex].inventory[i]);
+ if (i < 2)
+ gui_drawCharPortraitWithStats(charIndex);
+ break;
+ }
+ }
+ }
+
+ if (!ammoItem)
+ return -4;
+
+ int c = charIndex;
+ if (c > 3)
+ c -= 2;
+
+ if (launchObject(charIndex, ammoItem, _currentBlock, _dropItemDirIndex[(_currentDirection << 2) + c], _currentDirection, tp)) {
+ snd_playSoundEffect(tp == 7 ? 26 : 11);
+ _sceneUpdateRequired = true;
+ }
+
+ return 0;
+}
+
+void EoBCoreEngine::inflictMonsterDamage(EoBMonsterInPlay *m, int damage, bool giveExperience) {
+ m->hitPointsCur -= damage;
+ m->flags = (m->flags & 0xf7) | 1;
+
+ if (_monsterProps[m->type].capsFlags & 0x2000) {
+ explodeMonster(m);
+ checkSceneUpdateNeed(m->block);
+ m->hitPointsCur = 0;
+ } else {
+ if (checkSceneUpdateNeed(m->block)) {
+ m->flags |= 2;
+ if (_preventMonsterFlash)
+ return;
+ flashMonsterShape(m);
+ }
+ }
+
+ if (m->hitPointsCur <= 0)
+ killMonster(m, giveExperience);
+ else if (getBlockDistance(m->block, _currentBlock) < 4)
+ m->dest = _currentBlock;
+}
+
+void EoBCoreEngine::calcAndInflictMonsterDamage(EoBMonsterInPlay *m, int times, int pips, int offs, int flags, int savingThrowType, int savingThrowEffect) {
+ int dmg = calcMonsterDamage(m, times, pips, offs, flags, savingThrowType, savingThrowEffect);
+ if (dmg > 0)
+ inflictMonsterDamage(m, dmg, flags & 0x800 ? true : false);
+}
+
+void EoBCoreEngine::calcAndInflictCharacterDamage(int charIndex, int times, int itemOrPips, int useStrModifierOrBase, int flags, int savingThrowType, int savingThrowEffect) {
+ int dmg = calcCharacterDamage(charIndex, times, itemOrPips, useStrModifierOrBase, flags, savingThrowType, savingThrowEffect);
+ if (dmg)
+ inflictCharacterDamage(charIndex, dmg);
+}
+
+int EoBCoreEngine::calcCharacterDamage(int charIndex, int times, int itemOrPips, int useStrModifierOrBase, int flags, int savingThrowType, int savingThrowEffect) {
+ int s = (flags & 0x100) ? calcDamageModifers(times, 0, itemOrPips, _items[itemOrPips].type, useStrModifierOrBase) : rollDice(times, itemOrPips, useStrModifierOrBase);
+ EoBCharacter *c = &_characters[charIndex];
+
+ if (savingThrowType != 5) {
+ if (trySavingThrow(c, _charClassModifier[c->cClass], c->level[0], savingThrowType, c->raceSex >> 1 /*fix bug in original code by adding a right shift*/))
+ s = savingThrowReduceDamage(savingThrowEffect, s);
+ }
+
+ if ((flags & 0x110) == 0x110) {
+ if (!calcDamageCheckItemType(_items[itemOrPips].type))
+ s = 1;
+ }
+
+ if (flags & 4) {
+ if (checkInventoryForRings(charIndex, 3))
+ s = 0;
+ }
+
+ if (flags & 0x400) {
+ if (c->effectFlags & 0x2000)
+ s = 0;
+ else
+ _txt->printMessage(_characterStatusStrings8[0], -1, c->name);
+ }
+
+ return s;
+}
+
+void EoBCoreEngine::inflictCharacterDamage(int charIndex, int damage) {
+ EoBCharacter *c = &_characters[charIndex];
+ if (!testCharacter(charIndex, 3))
+ return;
+
+ if (c->effectsRemainder[3])
+ c->effectsRemainder[3] = (damage < c->effectsRemainder[3]) ? (c->effectsRemainder[3] - damage) : 0;
+
+ c->hitPointsCur -= damage;
+ c->damageTaken = damage;
+
+ if (c->hitPointsCur > -10) {
+ snd_playSoundEffect(21);
+ } else {
+ c->hitPointsCur = -10;
+ c->flags &= 1;
+ c->food = 0;
+ removeAllCharacterEffects(charIndex);
+ snd_playSoundEffect(22);
+ }
+
+ if (c->effectsRemainder[0]) {
+ c->effectsRemainder[0] = (damage < c->effectsRemainder[0]) ? (c->effectsRemainder[0] - damage) : 0;
+ if (!c->effectsRemainder[0])
+ removeCharacterEffect(1, charIndex, 1);
+ }
+
+ if (_currentControlMode)
+ gui_drawFaceShape(charIndex);
+ else
+ gui_drawCharPortraitWithStats(charIndex);
+
+ if (c->hitPointsCur <= 0 && _updateFlags == 1 && charIndex == _openBookChar) {
+ Button b;
+ clickedSpellbookAbort(&b);
+ }
+
+ setCharEventTimer(charIndex, 18, 6, 1);
+}
+
+bool EoBCoreEngine::characterAttackHitTest(int charIndex, int monsterIndex, int item, int attackType) {
+ if (charIndex < 0)
+ return true;
+
+ int p = item ? (_flags.gameID == GI_EOB1 ? _items[item].type : (_itemTypes[_items[item].type].extraProperties & 0x7f)) : 0;
+
+ if (_monsters[monsterIndex].flags & 0x20)
+ return true;// EOB 2 only ?
+
+ int t = _monsters[monsterIndex].type;
+ int d = (p < 1 || p > 3) ? 0 : _items[item].value;
+
+ if (_flags.gameID == GI_EOB2) {
+ if ((p > 0 && p < 4) || !item) {
+ if (((_monsterProps[t].immunityFlags & 0x200) && (d <= 0)) || ((_monsterProps[t].immunityFlags & 0x1000) && (d <= 1)))
+ return false;
+ }
+ }
+
+ d += (attackType ? getStrHitChanceModifier(charIndex) : getDexHitChanceModifier(charIndex));
+
+ int m = getMonsterAcHitChanceModifier(charIndex, _monsterProps[t].armorClass) - d;
+ int s = rollDice(1, 20);
+
+ _monsters[monsterIndex].flags |= 1;
+
+ if (_flags.gameID == GI_EOB1) {
+ if (_partyEffectFlags & 0x30)
+ s++;
+ if (_characters[charIndex].effectFlags & 0x40)
+ s++;
+ } else if ((_partyEffectFlags & 0x8400) || (_characters[charIndex].effectFlags & 0x1000)) {
+ s++;
+ }
+
+ s = CLIP(s, 1, 20);
+
+ return s < m ? false : true;
+}
+
+bool EoBCoreEngine::monsterAttackHitTest(EoBMonsterInPlay *m, int charIndex) {
+ int tp = m->type;
+ EoBMonsterProperty *p = &_monsterProps[tp];
+
+ int r = rollDice(1, 20);
+ if (r != 20) {
+ // Prot from evil
+ if (_characters[charIndex].effectFlags & 0x800)
+ r -= 2;
+ // blur
+ if (_characters[charIndex].effectFlags & 0x10)
+ r -= 2;
+ // prayer
+ if (_partyEffectFlags & 0x8000)
+ r--;
+ }
+
+ return ((r == 20) || (r >= (p->hitChance - _characters[charIndex].armorClass)));
+}
+
+bool EoBCoreEngine::flyingObjectMonsterHit(EoBFlyingObject *fo, int monsterIndex) {
+ if (fo->attackerId != -1) {
+ if (!characterAttackHitTest(fo->attackerId, monsterIndex, fo->item, 0))
+ return false;
+ }
+ calcAndInflictMonsterDamage(&_monsters[monsterIndex], fo->attackerId, fo->item, 0, (fo->attackerId == -1) ? 0x110 : 0x910, 5, 3);
+ return true;
+}
+
+bool EoBCoreEngine::flyingObjectPartyHit(EoBFlyingObject *fo) {
+ int ps = _dscItemPosIndex[(_currentDirection << 2) + (_items[fo->item].pos & 3)];
+ bool res = false;
+
+ bool b = ((_currentDirection == fo->direction || _currentDirection == (fo->direction ^ 2)) && ps > 2);
+ int s = ps << 1;
+ if (ps > 2)
+ s += rollDice(1, 2, -1);
+
+ static const int8 charId[] = { 0, -1, 1, -1, 2, 4, 3, 5 };
+
+ for (int i = 0; i < 2; i++) {
+ int c = charId[s];
+ s ^= 1;
+ if (!testCharacter(c, 3))
+ continue;
+ calcAndInflictCharacterDamage(c, -1, fo->item, 0, 0x110, 5, 3);
+ res = true;
+ if (ps < 2 || b == 0)
+ break;
+ }
+
+ return res;
+}
+
+void EoBCoreEngine::monsterCloseAttack(EoBMonsterInPlay *m) {
+ int first = _monsterCloseAttDstTable1[(_currentDirection << 2) + m->dir] * 12;
+ int v = (m->pos == 4) ? rollDice(1, 2, -1) : _monsterCloseAttChkTable2[(m->dir << 2) + m->pos];
+ if (!v)
+ first += 6;
+
+ int last = first + 6;
+ for (int i = first; i < last; i++) {
+ int c = _monsterCloseAttDstTable2[i];
+ if (!testCharacter(c, 3))
+ continue;
+
+ // Character Invisibility
+ if ((_characters[c].effectFlags & 0x140) && (rollDice(1, 20) >= 5))
+ continue;
+
+ int dmg = 0;
+ for (int ii = 0; ii < _monsterProps[m->type].attacksPerRound; ii++) {
+ if (!monsterAttackHitTest(m, c))
+ continue;
+ dmg += rollDice(_monsterProps[m->type].dmgDc[ii].times, _monsterProps[m->type].dmgDc[ii].pips, _monsterProps[m->type].dmgDc[ii].base);
+ if (_characters[c].effectsRemainder[1]) {
+ if (--_characters[c].effectsRemainder[1])
+ dmg = 0;
+ }
+ }
+
+ if (dmg > 0) {
+ if ((_monsterProps[m->type].capsFlags & 0x80) && rollDice(1, 4, -1) != 3) {
+ int slot = rollDice(1, 27, -1);
+ for (int iii = 0; iii < 27; iii++) {
+ Item itm = _characters[c].inventory[slot];
+ if (!itm || !(_itemTypes[_items[itm].type].extraProperties & 0x80)) {
+ if (++slot == 27)
+ slot = 0;
+ continue;
+ }
+
+ _characters[c].inventory[slot] = 0;
+ _txt->printMessage(_ripItemStrings[(_characters[c].raceSex & 1) ^ 1], -1, _characters[c].name);
+ printFullItemName(itm);
+ _txt->printMessage(_ripItemStrings[2]);
+ break;
+ }
+ gui_drawCharPortraitWithStats(c);
+ }
+
+ inflictCharacterDamage(c, dmg);
+
+ if (_monsterProps[m->type].capsFlags & 0x10) {
+ statusAttack(c, 2, _monsterSpecAttStrings[_flags.gameID == GI_EOB1 ? 3 : 2], 0, 1, 8, 1);
+ _characters[c].effectFlags &= ~0x2000;
+ }
+
+ if (_monsterProps[m->type].capsFlags & 0x20)
+ statusAttack(c, 4, _monsterSpecAttStrings[_flags.gameID == GI_EOB1 ? 4 : 3], 2, 5, 9, 1);
+
+ if (_monsterProps[m->type].capsFlags & 0x8000)
+ statusAttack(c, 8, _monsterSpecAttStrings[4], 2, 0, 0, 1);
+
+ }
+
+ if (!(_monsterProps[m->type].capsFlags & 0x4000))
+ return;
+ }
+}
+
+void EoBCoreEngine::monsterSpellCast(EoBMonsterInPlay *m, int type) {
+ launchMagicObject(-1, type, m->block, m->pos, m->dir);
+ snd_processEnvironmentalSoundEffect(_spells[_magicFlightObjectProperties[type << 2]].sound, m->block);
+}
+
+void EoBCoreEngine::statusAttack(int charIndex, int attackStatusFlags, const char *attackStatusString, int savingThrowType, uint32 effectDuration, int restoreEvent, int noRefresh) {
+ EoBCharacter *c = &_characters[charIndex];
+ if ((c->flags & attackStatusFlags) && noRefresh)
+ return;
+ if (!testCharacter(charIndex, 3))
+ return;
+
+ if (savingThrowType != 5 && specialAttackSavingThrow(charIndex, savingThrowType))
+ return;
+
+ if (attackStatusFlags & 8) {
+ removeAllCharacterEffects(charIndex);
+ c->flags = (c->flags & 1) | 8;
+ } else {
+ c->flags |= attackStatusFlags;
+ }
+
+ if ((attackStatusFlags & 0x0c) && (_openBookChar == charIndex) && _updateFlags) {
+ Button b;
+ clickedSpellbookAbort(&b);
+ }
+
+ if (effectDuration)
+ setCharEventTimer(charIndex, effectDuration * 546, restoreEvent, 1);
+
+ gui_drawCharPortraitWithStats(charIndex);
+ _txt->printMessage(_characterStatusStrings13[0], -1, c->name, attackStatusString);
+}
+
+int EoBCoreEngine::calcMonsterDamage(EoBMonsterInPlay *m, int times, int pips, int offs, int flags, int savingThrowType, int savingThrowEffect) {
+ int s = flags & 0x100 ? calcDamageModifers(times, m, pips, _items[pips].type, offs) : rollDice(times, pips, offs);
+ EoBMonsterProperty *p = &_monsterProps[m->type];
+
+ if (savingThrowType != 5) {
+ if (trySavingThrow(m, 0, p->level, savingThrowType, 6))
+ s = savingThrowReduceDamage(savingThrowEffect, s);
+ }
+
+ if ((flags & 0x110) == 0x110) {
+ if (!calcDamageCheckItemType(_items[pips].type))
+ s = 1;
+ }
+
+ if ((flags & 0x100) && (!(_itemTypes[_items[pips].type].allowedClasses & 4 /* bug in original code ??*/))
+ && ((_flags.gameID == GI_EOB2 && (p->immunityFlags & 0x100)) || (_flags.gameID == GI_EOB1 && (p->capsFlags & 4))))
+ s >>= 1;
+
+ if (p->immunityFlags & 0x2000) {
+ if (flags & 0x100) {
+ if (_items[pips].value < 3)
+ s >>= 2;
+ if (_items[pips].value == 3)
+ s >>= 1;
+ if (s == 0)
+ s = _items[pips].value;
+
+ } else {
+ s >>= 1;
+ }
+ }
+
+ if (flags & 1) {
+ if (tryMonsterAttackEvasion(m))
+ s = 0;
+ }
+
+ if (_flags.gameID == GI_EOB1)
+ return s;
+
+ static const uint16 damageImmunityFlags[] = { 0x01, 0x10, 0x02, 0x20, 0x80, 0x400, 0x20, 0x800, 0x40, 0x80, 0x400, 0x40 };
+ for (int i = 0; i < 12; i += 2) {
+ if ((flags & damageImmunityFlags[i]) && (p->immunityFlags & damageImmunityFlags[i + 1]))
+ s = 0;
+ }
+
+ return s;
+}
+
+int EoBCoreEngine::calcDamageModifers(int charIndex, EoBMonsterInPlay *m, int item, int itemType, int useStrModifier) {
+ int s = (useStrModifier && (charIndex != -1)) ? getStrDamageModifier(charIndex) : 0;
+ if (item) {
+ EoBItemType *p = &_itemTypes[itemType];
+ int t = m ? m->type : 0;
+ s += ((m && (_monsterProps[t].capsFlags & 1)) ? rollDice(p->dmgNumDiceL, p->dmgNumPipsL, p->dmgIncS /* bug in original code ? */) :
+ rollDice(p->dmgNumDiceS, p->dmgNumPipsS, p->dmgIncS));
+ s += _items[item].value;
+ } else {
+ s += rollDice(1, 2);
+ }
+
+ return (s < 0) ? 0 : s;
+}
+
+bool EoBCoreEngine::trySavingThrow(void *target, int hpModifier, int level, int type, int race) {
+ static const int8 constMod[] = { 0, 0, 0, 0, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 4, 4, 4, 4, 5, 5 };
+
+ if (type == 5)
+ return false;
+
+ int s = getSaveThrowModifier(hpModifier, level, type);
+ if (((race == 3 || race == 5) && (type == 4 || type == 1 || type == 0)) || (race == 4 && (type == 4 || type == 1))) {
+ EoBCharacter *c = (EoBCharacter *)target;
+ s -= constMod[c->constitutionCur];
+ }
+
+ return rollDice(1, 20) < s ? false : true;
+}
+
+bool EoBCoreEngine::specialAttackSavingThrow(int charIndex, int type) {
+ return trySavingThrow(&_characters[charIndex], _charClassModifier[_characters[charIndex].cClass], _characters[charIndex].level[0], type, _characters[charIndex].raceSex >> 1);
+}
+
+int EoBCoreEngine::getSaveThrowModifier(int hpModifier, int level, int type) {
+ const uint8 *tbl = _saveThrowTables[hpModifier];
+ if (_saveThrowLevelIndex[hpModifier] < level)
+ level = _saveThrowLevelIndex[hpModifier];
+ level /= _saveThrowModDiv[hpModifier];
+ level += (_saveThrowModExt[hpModifier] * type);
+
+ return tbl[level];
+}
+
+bool EoBCoreEngine::calcDamageCheckItemType(int itemType) {
+ itemType = _itemTypes[itemType].extraProperties & 0x7f;
+ return (itemType == 2 || itemType == 3) ? true : false;
+}
+
+int EoBCoreEngine::savingThrowReduceDamage(int savingThrowEffect, int damage) {
+ if (savingThrowEffect == 3)
+ return 0;
+
+ if (savingThrowEffect == 0 || savingThrowEffect == 1)
+ return damage >> 1;
+
+ return damage;
+}
+
+bool EoBCoreEngine::tryMonsterAttackEvasion(EoBMonsterInPlay *m) {
+ return rollDice(1, 100) < _monsterProps[m->type].dmgModifierEvade ? true : false;
+}
+
+int EoBCoreEngine::getStrHitChanceModifier(int charIndex) {
+ static const int8 strExtLimit[] = { 1, 51, 76, 91, 100 };
+ static const int8 strExtMod[] = { 1, 2, 2, 2, 3 };
+ static const int8 strMod[] = { -4, -3, -3, -2, -2, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 3, 3, 4, 4, 5, 6, 7 };
+
+ int r = strMod[_characters[charIndex].strengthCur - 1];
+ if (_characters[charIndex].strengthExtCur) {
+ for (int i = 0; i < 5; i++) {
+ if (_characters[charIndex].strengthExtCur >= strExtLimit[i])
+ r = strExtMod[i];
+ }
+ }
+
+ return r;
+}
+
+int EoBCoreEngine::getStrDamageModifier(int charIndex) {
+ static const int8 strExtLimit[] = { 1, 51, 76, 91, 100 };
+ static const int8 strExtMod[] = { 3, 3, 4, 5, 6 };
+ static const int8 strMod[] = { -3, -2, -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 2, 7, 8, 9, 10, 11, 12, 14 };
+
+ int r = strMod[_characters[charIndex].strengthCur - 1];
+ if (_characters[charIndex].strengthExtCur) {
+ for (int i = 0; i < 5; i++) {
+ if (_characters[charIndex].strengthExtCur >= strExtLimit[i])
+ r = strExtMod[i];
+ }
+ }
+
+ return r;
+}
+
+int EoBCoreEngine::getDexHitChanceModifier(int charIndex) {
+ static const int8 dexMod[] = { -5, -4, -3, -2, -1, 0, 0, 0, 0, 0, 0, 1, 2, 2, 3, 3, 4, 4, 4 };
+ return dexMod[_characters[charIndex].dexterityCur - 1];
+}
+
+int EoBCoreEngine::getMonsterAcHitChanceModifier(int charIndex, int monsterAc) {
+ static const uint8 mod1[] = { 1, 3, 3, 2 };
+ static const uint8 mod2[] = { 1, 1, 2, 1 };
+
+ int l = _characters[charIndex].level[0] - 1;
+ int cm = _charClassModifier[_characters[charIndex].cClass];
+
+ return (20 - ((l / mod1[cm]) * mod2[cm])) - monsterAc;
+}
+
+void EoBCoreEngine::explodeMonster(EoBMonsterInPlay *m) {
+ m->flags |= 2;
+ if (getBlockDistance(m->block, _currentBlock) < 2) {
+ explodeObject(0, _currentBlock, 2);
+ for (int i = 0; i < 6; i++)
+ calcAndInflictCharacterDamage(i, 6, 6, 0, 8, 1, 0);
+ } else {
+ explodeObject(0, m->block, 2);
+ }
+ m->flags &= ~2;
+}
+
+void EoBCoreEngine::snd_playSong(int track) {
+ _sound->playTrack(track);
+}
+
+void EoBCoreEngine::snd_playSoundEffect(int track, int volume) {
+ if ((track < 1) || (_flags.gameID == GI_EOB2 && track > 119) || shouldQuit())
+ return;
+
+ _sound->playSoundEffect(track, volume);
+}
+
+void EoBCoreEngine::snd_stopSound() {
+ _sound->haltTrack();
+ _sound->stopAllSoundEffects();
+}
+
+void EoBCoreEngine::snd_fadeOut() {
+ _sound->beginFadeOut();
+}
+
+} // End of namespace Kyra
+
+#endif // ENABLE_EOB
diff --git a/engines/kyra/eobcommon.h b/engines/kyra/eobcommon.h
new file mode 100644
index 0000000000..050fe2b794
--- /dev/null
+++ b/engines/kyra/eobcommon.h
@@ -0,0 +1,1164 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public 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 KYRA_EOBCOMMON_H
+#define KYRA_EOBCOMMON_H
+
+#if defined(ENABLE_EOB) || defined(ENABLE_LOL)
+#include "kyra/kyra_rpg.h"
+#endif // (ENABLE_EOB || ENABLE_LOL)
+
+#ifdef ENABLE_EOB
+
+namespace Kyra {
+
+struct DarkMoonShapeDef {
+ int16 index;
+ uint8 x, y, w, h;
+};
+
+struct CreatePartyModButton {
+ uint8 encodeLabelX;
+ uint8 encodeLabelY;
+ uint8 labelW;
+ uint8 labelH;
+ uint8 labelX;
+ uint8 labelY;
+ uint8 bodyIndex;
+ uint8 destX;
+ uint8 destY;
+};
+
+struct EoBRect8 {
+ uint8 x;
+ uint8 y;
+ uint8 w;
+ uint8 h;
+};
+
+struct EoBChargenButtonDef {
+ uint8 x;
+ uint8 y;
+ uint8 w;
+ uint8 h;
+ uint8 keyCode;
+};
+
+struct EoBGuiButtonDef {
+ uint16 keyCode;
+ uint16 keyCode2;
+ uint16 flags;
+ uint16 x;
+ uint8 y;
+ uint16 w;
+ uint8 h;
+ uint16 arg;
+};
+
+struct EoBCharacter {
+ uint8 id;
+ uint8 flags;
+ char name[11];
+ int8 strengthCur;
+ int8 strengthMax;
+ int8 strengthExtCur;
+ int8 strengthExtMax;
+ int8 intelligenceCur;
+ int8 intelligenceMax;
+ int8 wisdomCur;
+ int8 wisdomMax;
+ int8 dexterityCur;
+ int8 dexterityMax;
+ int8 constitutionCur;
+ int8 constitutionMax;
+ int8 charismaCur;
+ int8 charismaMax;
+ int16 hitPointsCur;
+ int16 hitPointsMax;
+ int8 armorClass;
+ uint8 disabledSlots;
+ uint8 raceSex;
+ uint8 cClass;
+ uint8 alignment;
+ int8 portrait;
+ uint8 food;
+ uint8 level[3];
+ uint32 experience[3];
+ uint8 *faceShape;
+
+ int8 mageSpells[80];
+ int8 clericSpells[80];
+ uint32 mageSpellsAvailableFlags;
+
+ Item inventory[27];
+ uint32 timers[10];
+ int8 events[10];
+ uint8 effectsRemainder[4];
+ uint32 effectFlags;
+ uint8 damageTaken;
+ int8 slotStatus[5];
+};
+
+struct EoBItem {
+ uint8 nameUnid;
+ uint8 nameId;
+ uint8 flags;
+ int8 icon;
+ int8 type;
+ int8 pos;
+ int16 block;
+ Item next;
+ Item prev;
+ uint8 level;
+ int8 value;
+};
+
+struct EoBItemType {
+ uint16 invFlags;
+ uint16 handFlags;
+ int8 armorClass;
+ int8 allowedClasses;
+ int8 requiredHands;
+ int8 dmgNumDiceS;
+ int8 dmgNumPipsS;
+ int8 dmgIncS;
+ int8 dmgNumDiceL;
+ int8 dmgNumPipsL;
+ int8 dmgIncL;
+ uint8 unk1;
+ uint16 extraProperties;
+};
+
+struct SpriteDecoration {
+ uint8 *shp;
+ int16 x;
+ int16 y;
+};
+
+struct EoBMonsterProperty {
+ int8 armorClass;
+ int8 hitChance;
+ int8 level;
+ uint8 hpDcTimes;
+ uint8 hpDcPips;
+ uint8 hpDcBase;
+ uint8 attacksPerRound;
+ struct DmgDc {
+ uint8 times;
+ uint8 pips;
+ int8 base;
+ } dmgDc[3];
+ uint16 immunityFlags;
+ uint32 capsFlags;
+ uint32 typeFlags;
+ int32 experience;
+
+ uint8 u30;
+ int8 sound1;
+ int8 sound2;
+ uint8 numRemoteAttacks;
+ uint8 remoteWeaponChangeMode;
+ uint8 numRemoteWeapons;
+
+ int8 remoteWeapons[5];
+
+ int8 tuResist;
+ uint8 dmgModifierEvade;
+
+ uint8 decorations[3];
+};
+
+struct EoBMonsterInPlay {
+ uint8 type;
+ uint8 unit;
+ uint16 block;
+ uint8 pos;
+ int8 dir;
+ uint8 animStep;
+ uint8 shpIndex;
+ int8 mode;
+ int8 f_9;
+ int8 curAttackFrame;
+ int8 spellStatusLeft;
+ int16 hitPointsMax;
+ int16 hitPointsCur;
+ uint16 dest;
+ uint16 randItem;
+ uint16 fixedItem;
+ uint8 flags;
+ uint8 idleAnimState;
+ uint8 curRemoteWeapon;
+ uint8 numRemoteAttacks;
+ int8 palette;
+ uint8 directionChanged;
+ uint8 stepsTillRemoteAttack;
+ uint8 sub;
+};
+
+struct ScriptTimer {
+ uint16 func;
+ uint16 ticks;
+ uint32 next;
+};
+
+struct EoBMenuDef {
+ int8 titleStrId;
+ uint8 dim;
+ uint8 firstButtonStrId;
+ int8 numButtons;
+ int8 titleCol;
+};
+struct EoBMenuButtonDef {
+ int8 labelId;
+ int16 x;
+ int8 y;
+ uint8 width;
+ uint8 height;
+ int16 keyCode;
+ int16 flags;
+};
+
+class EoBInfProcessor;
+
+class EoBCoreEngine : public KyraRpgEngine {
+friend class TextDisplayer_rpg;
+friend class GUI_EoB;
+friend class Debugger_EoB;
+friend class EoBInfProcessor;
+friend class DarkmoonSequenceHelper;
+friend class CharacterGenerator;
+friend class TransferPartyWiz;
+public:
+ EoBCoreEngine(OSystem *system, const GameFlags &flags);
+ virtual ~EoBCoreEngine();
+
+ virtual void initKeymap();
+
+ Screen *screen() { return _screen; }
+ GUI *gui() const { return _gui; }
+
+protected:
+ // Startup
+ virtual Common::Error init();
+ Common::Error go();
+
+ // Main Menu, Intro, Finale
+ virtual int mainMenu() = 0;
+ virtual void seq_xdeath() {};
+ virtual void seq_playFinale() = 0;
+ bool _playFinale;
+
+ //Init, config
+ void loadItemsAndDecorationsShapes();
+ void releaseItemsAndDecorationsShapes();
+
+ void initButtonData();
+ void initMenus();
+ void initStaticResource();
+ virtual void initSpells();
+
+ void registerDefaultSettings();
+ void readSettings();
+ void writeSettings();
+
+ const uint8 **_largeItemShapes;
+ const uint8 **_smallItemShapes;
+ const uint8 **_thrownItemShapes;
+ const int _numLargeItemShapes;
+ const int _numSmallItemShapes;
+ const int _numThrownItemShapes;
+ const int _numItemIconShapes;
+
+ const uint8 **_spellShapes;
+ const uint8 **_firebeamShapes;
+ const uint8 *_redSplatShape;
+ const uint8 *_greenSplatShape;
+ const uint8 **_wallOfForceShapes;
+ const uint8 **_teleporterShapes;
+ const uint8 **_sparkShapes;
+ const uint8 *_deadCharShape;
+ const uint8 *_disabledCharGrid;
+ const uint8 *_blackBoxSmallGrid;
+ const uint8 *_weaponSlotGrid;
+ const uint8 *_blackBoxWideGrid;
+ const uint8 *_lightningColumnShape;
+
+ uint8 *_itemsOverlay;
+ static const uint8 _itemsOverlayCGA[];
+
+ static const uint8 _teleporterShapeDefs[];
+ static const uint8 _wallOfForceShapeDefs[];
+
+ const char *const *_mainMenuStrings;
+
+ // Main loop
+ virtual void startupNew();
+ virtual void startupLoad() = 0;
+ void runLoop();
+ void update() { screen()->updateScreen(); }
+ bool checkPartyStatus(bool handleDeath);
+
+ bool _runFlag;
+
+ // Character generation / party transfer
+ bool startCharacterGeneration();
+ bool startPartyTransfer();
+
+ uint8 **_faceShapes;
+
+ static const int8 _characterClassType[];
+ static const uint8 _hpIncrPerLevel[];
+ static const uint8 _numLevelsPerClass[];
+ static const int16 _hpConstModifiers[];
+ static const uint8 _charClassModifier[];
+
+ const uint8 *_classModifierFlags;
+
+ // timers
+ void setupTimers();
+ void setCharEventTimer(int charIndex, uint32 countdown, int evnt, int updateExistingTimer);
+ void deleteCharEventTimer(int charIndex, int evnt);
+ void setupCharacterTimers();
+ void advanceTimers(uint32 millis);
+
+ void timerProcessMonsters(int timerNum);
+ void timerSpecialCharacterUpdate(int timerNum);
+ void timerProcessFlyingObjects(int timerNum);
+ void timerProcessCharacterExchange(int timerNum);
+ void timerUpdateTeleporters(int timerNum);
+ void timerUpdateFoodStatus(int timerNum);
+ void timerUpdateMonsterIdleAnim(int timerNum);
+
+ uint8 getClock2Timer(int index) { return index < _numClock2Timers ? _clock2Timers[index] : 0; }
+ uint8 getNumClock2Timers() { return _numClock2Timers; }
+
+ static const uint8 _clock2Timers[];
+ static const uint8 _numClock2Timers;
+
+ int32 _restPartyElapsedTime;
+
+ // Mouse
+ void setHandItem(Item itemIndex);
+
+ // Characters
+ int getDexterityArmorClassModifier(int dexterity);
+ int generateCharacterHitpointsByLevel(int charIndex, int levelIndex);
+ int getClassAndConstHitpointsModifier(int cclass, int constitution);
+ int getCharacterClassType(int cclass, int levelIndex);
+ int getModifiedHpLimits(int hpModifier, int constModifier, int level, bool mode);
+ Common::String getCharStrength(int str, int strExt);
+ int testCharacter(int16 index, int flags);
+ int getNextValidCharIndex(int curCharIndex, int searchStep);
+
+ void recalcArmorClass(int index);
+ int validateWeaponSlotItem(int index, int slot);
+
+ int getClericPaladinLevel(int index);
+ int getMageLevel(int index);
+ int getCharacterLevelIndex(int type, int cClass);
+
+ int countCharactersWithSpecificItems(int16 itemType, int16 itemValue);
+ int checkInventoryForItem(int character, int16 itemType, int16 itemValue);
+ void modifyCharacterHitpoints(int character, int16 points);
+ void neutralizePoison(int character);
+
+ void npcSequence(int npcIndex);
+ virtual void drawNpcScene(int npcIndex) = 0;
+ virtual void runNpcDialogue(int npcIndex) = 0;
+ void initNpc(int npcIndex);
+ int npcJoinDialogue(int npcIndex, int queryJoinTextId, int confirmJoinTextId, int noJoinTextId);
+ int prepareForNewPartyMember(int16 itemType, int16 itemValue);
+ void dropCharacter(int charIndex);
+ void removeCharacterFromParty(int charIndex);
+ void exchangeCharacters(int charIndex1, int charIndex2);
+
+ void increasePartyExperience(int16 points);
+ void increaseCharacterExperience(int charIndex, int32 points);
+ uint32 getRequiredExperience(int cClass, int levelIndex, int level);
+ void increaseCharacterLevel(int charIndex, int levelIndex);
+
+ void setWeaponSlotStatus(int charIndex, int mode, int slot);
+
+ EoBCharacter *_characters;
+ Common::String _strenghtStr;
+ int _castScrollSlot;
+ int _exchangeCharacterId;
+
+ const char *const *_levelGainStrings;
+ const uint32 *_expRequirementTables[6];
+
+ const uint8 *_saveThrowTables[6];
+ const uint8 *_saveThrowLevelIndex;
+ const uint8 *_saveThrowModDiv;
+ const uint8 *_saveThrowModExt;
+
+ const EoBCharacter *_npcPreset;
+ int _npcSequenceSub;
+ bool _partyResting;
+ bool _loading;
+
+ // Items
+ void loadItemDefs();
+ Item duplicateItem(Item itemIndex);
+ void setItemPosition(Item *itemQueue, int block, Item item, int pos);
+ Item createItemOnCurrentBlock(Item itemIndex);
+ void createInventoryItem(EoBCharacter *c, Item itemIndex, int16 itemValue, int preferedInventorySlot);
+ int deleteInventoryItem(int charIndex, int slot);
+ void deleteBlockItem(uint16 block, int type);
+ int validateInventorySlotForItem(Item item, int charIndex, int slot);
+ int stripPartyItems(int16 itemType, int16 itemValue, int handleValueMode, int numItems);
+ bool deletePartyItems(int16 itemType, int16 itemValue);
+ virtual void updateUsedCharacterHandItem(int charIndex, int slot) = 0;
+ int itemUsableByCharacter(int charIndex, Item item);
+ int countQueuedItems(Item itemQueue, int16 id, int16 type, int count, int includeFlyingItems);
+ int getQueuedItem(Item *items, int pos, int id);
+ void printFullItemName(Item item);
+ void identifyQueuedItems(Item itemQueue);
+ void drawItemIconShape(int pageNum, Item itemId, int x, int y);
+ bool isMagicEffectItem(Item itemIndex);
+ bool checkInventoryForRings(int charIndex, int itemValue);
+ void eatItemInHand(int charIndex);
+
+ bool launchObject(int charIndex, Item item, uint16 startBlock, int startPos, int dir, int type);
+ void launchMagicObject(int charIndex, int type, uint16 startBlock, int startPos, int dir);
+ bool updateObjectFlight(EoBFlyingObject *fo, int block, int pos);
+ bool updateFlyingObjectHitTest(EoBFlyingObject *fo, int block, int pos);
+ void explodeObject(EoBFlyingObject *fo, int block, Item item);
+ void endObjectFlight(EoBFlyingObject *fo);
+ void checkFlyingObjects();
+
+ void reloadWeaponSlot(int charIndex, int slotIndex, int itemType, int arrowOrDagger);
+
+ EoBItem *_items;
+ uint16 _numItems;
+ EoBItemType *_itemTypes;
+ char **_itemNames;
+ uint16 _numItemNames;
+ uint32 _partyEffectFlags;
+ Item _lastUsedItem;
+
+ const uint16 *_slotValidationFlags;
+ const int8 *_projectileWeaponAmmoTypes;
+ const uint8 *_wandTypes;
+
+ EoBFlyingObject *_flyingObjects;
+ const uint8 *_drawObjPosIndex;
+ const uint8 *_flightObjFlipIndex;
+ const int8 *_flightObjShpMap;
+ const int8 *_flightObjSclIndex;
+
+ const uint8 *_expObjectTlMode;
+ const uint8 *_expObjectTblIndex;
+ const uint8 *_expObjectShpStart;
+ const uint8 *_expObjectAnimTbl1;
+ int _expObjectAnimTbl1Size;
+ const uint8 *_expObjectAnimTbl2;
+ int _expObjectAnimTbl2Size;
+ const uint8 *_expObjectAnimTbl3;
+ int _expObjectAnimTbl3Size;
+
+ // Monsters
+ void loadMonsterShapes(const char *filename, int monsterIndex, bool hasDecorations, int encodeTableIndex);
+ void releaseMonsterShapes(int first, int num);
+ virtual void generateMonsterPalettes(const char *file, int16 monsterIndex) {}
+ virtual void loadMonsterDecoration(const char *file, int16 monsterIndex) {}
+ const uint8 *loadMonsterProperties(const uint8 *data);
+ const uint8 *loadActiveMonsterData(const uint8 *data, int level);
+ void initMonster(int index, int unit, uint16 block, int pos, int dir, int type, int shpIndex, int mode, int i, int randItem, int fixedItem);
+ void placeMonster(EoBMonsterInPlay *m, uint16 block, int dir);
+ virtual void replaceMonster(int b, uint16 block, int pos, int dir, int type, int shpIndex, int mode, int h2, int randItem, int fixedItem) = 0;
+ void killMonster(EoBMonsterInPlay *m, bool giveExperience);
+ virtual bool killMonsterExtra(EoBMonsterInPlay *m);
+ int countSpecificMonsters(int type);
+ void updateAttackingMonsterFlags();
+
+ const int8 *getMonstersOnBlockPositions(uint16 block);
+ int getClosestMonster(int charIndex, int block);
+
+ bool blockHasMonsters(uint16 block);
+ bool isMonsterOnPos(EoBMonsterInPlay *m, uint16 block, int pos, int checkPos4);
+ const int16 *findBlockMonsters(uint16 block, int pos, int dir, int blockDamage, int singleTargetCheckAdjacent);
+
+ void drawBlockObject(int flipped, int page, const uint8 *shape, int x, int y, int sd, uint8 *ovl = 0);
+ void drawMonsterShape(const uint8 *shape, int x, int y, int flipped, int flags, int palIndex);
+ void flashMonsterShape(EoBMonsterInPlay *m);
+ void updateAllMonsterShapes();
+ void drawBlockItems(int index);
+ void drawDoor(int index);
+ virtual void drawDoorIntern(int type, int index, int x, int y, int w, int wall, int mDim, int16 y1, int16 y2) = 0;
+ void drawMonsters(int index);
+ void drawWallOfForce(int index);
+ void drawFlyingObjects(int index);
+ void drawTeleporter(int index);
+
+ void updateMonsters(int unit);
+ void updateMonsterDest(EoBMonsterInPlay *m);
+ void updateMonsterAttackMode(EoBMonsterInPlay *m);
+ void updateAllMonsterDests();
+ void turnFriendlyMonstersHostile();
+ int getNextMonsterDirection(int curBlock, int destBlock);
+ int getNextMonsterPos(EoBMonsterInPlay *m, int block);
+ int findFreeMonsterPos(int block, int size);
+ void updateMoveMonster(EoBMonsterInPlay *m);
+ bool updateMonsterTryDistanceAttack(EoBMonsterInPlay *m);
+ bool updateMonsterTryCloseAttack(EoBMonsterInPlay *m, int block);
+ void walkMonster(EoBMonsterInPlay *m, int destBlock);
+ bool walkMonsterNextStep(EoBMonsterInPlay *m, int destBlock, int direction);
+ void updateMonsterFollowPath(EoBMonsterInPlay *m, int turnSteps);
+ void updateMonstersStraying(EoBMonsterInPlay *m, int a);
+ void updateMonstersSpellStatus(EoBMonsterInPlay *m);
+ void setBlockMonsterDirection(int block, int dir);
+
+ uint8 *_monsterFlashOverlay;
+ uint8 *_monsterStoneOverlay;
+
+ SpriteDecoration *_monsterDecorations;
+ EoBMonsterProperty *_monsterProps;
+
+ EoBMonsterInPlay *_monsters;
+
+ const int8 *_monsterStepTable0;
+ const int8 *_monsterStepTable1;
+ const int8 *_monsterStepTable2;
+ const int8 *_monsterStepTable3;
+ const uint8 *_monsterCloseAttPosTable1;
+ const uint8 *_monsterCloseAttPosTable2;
+ const int8 *_monsterCloseAttUnkTable;
+ const uint8 *_monsterCloseAttChkTable1;
+ const uint8 *_monsterCloseAttChkTable2;
+ const uint8 *_monsterCloseAttDstTable1;
+ const uint8 *_monsterCloseAttDstTable2;
+
+ const uint8 *_monsterProximityTable;
+ const uint8 *_findBlockMonstersTable;
+ const char *const *_monsterDustStrings;
+
+ const uint8 *_enemyMageSpellList;
+ const uint8 *_enemyMageSfx;
+ const uint8 *_beholderSpellList;
+ const uint8 *_beholderSfx;
+ const char *const *_monsterSpecAttStrings;
+
+ const int8 *_monsterFrmOffsTable1;
+ const int8 *_monsterFrmOffsTable2;
+
+ const uint16 *_encodeMonsterShpTable;
+ const uint8 _teleporterWallId;
+
+ const int16 *_wallOfForceDsX;
+ const uint8 *_wallOfForceDsY;
+ const uint8 *_wallOfForceDsNumW;
+ const uint8 *_wallOfForceDsNumH;
+ const uint8 *_wallOfForceShpId;
+
+ const int8 *_monsterDirChangeTable;
+
+ // Level
+ void loadLevel(int level, int sub);
+ void readLevelFileData(int level);
+ Common::String initLevelData(int sub);
+ void addLevelItems();
+ void loadVcnData(const char *file, const uint8 *cgaMapping);
+ void loadBlockProperties(const char *mazFile);
+ const uint8 *getBlockFileData(int levelIndex = 0);
+ Common::String getBlockFileName(int levelIndex, int sub);
+ const uint8 *getBlockFileData(const char *mazFile);
+ void loadDecorations(const char *cpsFile, const char *decFile);
+ void assignWallsAndDecorations(int wallIndex, int vmpIndex, int decDataIndex, int specialType, int flags);
+ void releaseDecorations();
+ void releaseDoorShapes();
+ void toggleWallState(int wall, int flags);
+ virtual void loadDoorShapes(int doorType1, int shapeId1, int doorType2, int shapeId2) = 0;
+ virtual const uint8 *loadDoorShapes(const char *filename, int doorIndex, const uint8 *shapeDefs) = 0;
+
+ void drawScene(int refresh);
+ void drawSceneShapes(int start = 0);
+ void drawDecorations(int index);
+
+ int calcNewBlockPositionAndTestPassability(uint16 curBlock, uint16 direction);
+ void notifyBlockNotPassable();
+ void moveParty(uint16 block);
+
+ int clickedDoorSwitch(uint16 block, uint16 direction);
+ int clickedDoorPry(uint16 block, uint16 direction);
+ int clickedDoorNoPry(uint16 block, uint16 direction);
+ int clickedNiche(uint16 block, uint16 direction);
+
+ int specialWallAction(int block, int direction);
+
+ void openDoor(int block);
+ void closeDoor(int block);
+
+ int16 _doorType[2];
+ int16 _noDoorSwitch[2];
+
+ EoBRect8 *_levelDecorationRects;
+ SpriteDecoration *_doorSwitches;
+
+ int8 _currentSub;
+ Common::String _curGfxFile;
+ Common::String _curBlockFile;
+
+ uint32 _drawSceneTimer;
+ uint32 _flashShapeTimer;
+ uint32 _envAudioTimer;
+ uint16 _teleporterPulse;
+
+ Common::Array<const int16 *> _dscWallMapping;
+ const int16 *_dscShapeCoords;
+
+ const uint8 *_dscItemPosIndex;
+ const int16 *_dscItemShpX;
+ const uint8 *_dscItemScaleIndex;
+ const uint8 *_dscItemTileIndex;
+ const uint8 *_dscItemShapeMap;
+
+ const uint8 *_dscDoorScaleOffs;
+ const uint8 *_dscDoorScaleMult1;
+ const uint8 *_dscDoorScaleMult2;
+ const uint8 *_dscDoorScaleMult3;
+ const uint8 *_dscDoorY1;
+ const uint8 *_dscDoorXE;
+
+ const uint8 *_wllFlagPreset;
+ int _wllFlagPresetSize;
+ const uint8 *_teleporterShapeCoords;
+ const int8 *_portalSeq;
+
+ // Script
+ void runLevelScript(int block, int flags);
+ void setScriptFlags(uint32 flags);
+ void clearScriptFlags(uint32 flags);
+ bool checkScriptFlags(uint32 flags);
+
+ const uint8 *initScriptTimers(const uint8 *pos);
+ void updateScriptTimers();
+ virtual void updateScriptTimersExtra() {}
+
+ EoBInfProcessor *_inf;
+ int _stepCounter;
+ int _stepsUntilScriptCall;
+ ScriptTimer _scriptTimers[5];
+ int _scriptTimersCount;
+ uint8 _scriptTimersMode;
+
+ // Gui
+ void gui_drawPlayField(bool refresh);
+ void gui_restorePlayField();
+ void gui_drawAllCharPortraitsWithStats();
+ void gui_drawCharPortraitWithStats(int index);
+ void gui_drawFaceShape(int index);
+ void gui_drawWeaponSlot(int charIndex, int slot);
+ void gui_drawWeaponSlotStatus(int x, int y, int status);
+ void gui_drawHitpoints(int index);
+ void gui_drawFoodStatusGraph(int index);
+ void gui_drawHorizontalBarGraph(int x, int y, int w, int h, int32 curVal, int32 maxVal, int col1, int col2);
+ void gui_drawCharPortraitStatusFrame(int index);
+ void gui_drawInventoryItem(int slot, int special, int pageNum);
+ void gui_drawCompass(bool force);
+ void gui_drawDialogueBox();
+ void gui_drawSpellbook();
+ void gui_drawSpellbookScrollArrow(int x, int y, int direction);
+ void gui_updateSlotAfterScrollUse();
+ void gui_updateControls();
+ void gui_toggleButtons();
+ void gui_setPlayFieldButtons();
+ void gui_setInventoryButtons();
+ void gui_setStatsListButtons();
+ void gui_setSwapCharacterButtons();
+ void gui_setCastOnWhomButtons();
+ void gui_initButton(int index, int x = -1, int y = -1, int val = -1);
+ Button *gui_getButton(Button *buttonList, int index);
+
+ int clickedInventoryNextPage(Button *button);
+ int clickedPortraitRestore(Button *button);
+ int clickedCharPortraitDefault(Button *button);
+ int clickedCamp(Button *button);
+ int clickedSceneDropPickupItem(Button *button);
+ int clickedCharPortrait2(Button *button);
+ int clickedWeaponSlot(Button *button);
+ int clickedCharNameLabelRight(Button *button);
+ int clickedInventorySlot(Button *button);
+ int clickedEatItem(Button *button);
+ int clickedInventoryPrevChar(Button *button);
+ int clickedInventoryNextChar(Button *button);
+ int clickedSpellbookTab(Button *button);
+ int clickedSpellbookList(Button *button);
+ int clickedCastSpellOnCharacter(Button *button);
+ int clickedUpArrow(Button *button);
+ int clickedDownArrow(Button *button);
+ int clickedLeftArrow(Button *button);
+ int clickedRightArrow(Button *button);
+ int clickedTurnLeftArrow(Button *button);
+ int clickedTurnRightArrow(Button *button);
+ int clickedAbortCharSwitch(Button *button);
+ int clickedSceneThrowItem(Button *button);
+ int clickedSceneSpecial(Button *button);
+ int clickedSpellbookAbort(Button *button);
+ int clickedSpellbookScroll(Button *button);
+ int clickedUnk(Button *button);
+
+ void gui_processCharPortraitClick(int index);
+ void gui_processWeaponSlotClickLeft(int charIndex, int slotIndex);
+ void gui_processWeaponSlotClickRight(int charIndex, int slotIndex);
+ void gui_processInventorySlotClick(int slot);
+
+ static const int16 _buttonList1[];
+ int _buttonList1Size;
+ static const int16 _buttonList2[];
+ int _buttonList2Size;
+ static const int16 _buttonList3[];
+ int _buttonList3Size;
+ static const int16 _buttonList4[];
+ int _buttonList4Size;
+ static const int16 _buttonList5[];
+ int _buttonList5Size;
+ static const int16 _buttonList6[];
+ int _buttonList6Size;
+ static const int16 _buttonList7[];
+ int _buttonList7Size;
+ static const int16 _buttonList8[];
+ int _buttonList8Size;
+
+ const EoBGuiButtonDef *_buttonDefs;
+
+ const char *const *_characterGuiStringsHp;
+ const char *const *_characterGuiStringsWp;
+ const char *const *_characterGuiStringsWr;
+ const char *const *_characterGuiStringsSt;
+ const char *const *_characterGuiStringsIn;
+
+ const char *const *_characterStatusStrings7;
+ const char *const *_characterStatusStrings8;
+ const char *const *_characterStatusStrings9;
+ const char *const *_characterStatusStrings12;
+ const char *const *_characterStatusStrings13;
+
+ const uint16 *_inventorySlotsX;
+ const uint8 *_inventorySlotsY;
+ const uint8 **_compassShapes;
+ uint8 _charExchangeSwap;
+ bool _configHpBarGraphs;
+
+ // text
+ void setupDialogueButtons(int presetfirst, int numStr, va_list &args);
+ void initDialogueSequence();
+ void restoreAfterDialogueSequence();
+ void drawSequenceBitmap(const char *file, int destRect, int x1, int y1, int flags);
+ int runDialogue(int dialogueTextId, int numStr, ...);
+
+ char _dialogueLastBitmap[13];
+ int _moveCounter;
+
+ const char *const *_chargenStatStrings;
+ const char *const *_chargenRaceSexStrings;
+ const char *const *_chargenClassStrings;
+ const char *const *_chargenAlignmentStrings;
+
+ const char *const *_pryDoorStrings;
+ const char *const *_warningStrings;
+
+ const char *const *_ripItemStrings;
+ const char *const *_cursedString;
+ const char *const *_enchantedString;
+ const char *const *_magicObjectStrings;
+ const char *const *_magicObjectString5;
+ const char *const *_patternSuffix;
+ const char *const *_patternGrFix1;
+ const char *const *_patternGrFix2;
+ const char *const *_validateArmorString;
+ const char *const *_validateCursedString;
+ const char *const *_validateNoDropString;
+ const char *const *_potionStrings;
+ const char *const *_wandStrings;
+ const char *const *_itemMisuseStrings;
+
+ const char *const *_suffixStringsRings;
+ const char *const *_suffixStringsPotions;
+ const char *const *_suffixStringsWands;
+
+ const char *const *_takenStrings;
+ const char *const *_potionEffectStrings;
+
+ const char *const *_yesNoStrings;
+ const char *const *_npcMaxStrings;
+ const char *const *_okStrings;
+ const char *const *_npcJoinStrings;
+ const char *const *_cancelStrings;
+ const char *const *_abortStrings;
+
+ // Rest party
+ void restParty_displayWarning(const char *str);
+ bool restParty_updateMonsters();
+ int restParty_getCharacterWithLowestHp();
+ bool restParty_checkHealSpells(int charIndex);
+ bool restParty_checkSpellsToLearn();
+ virtual void restParty_npc() {}
+ virtual bool restParty_extraAbortCondition();
+
+ // misc
+ void delay(uint32 millis, bool doUpdate = false, bool isMainLoop = false);
+
+ void displayParchment(int id);
+ int countResurrectionCandidates();
+
+ void seq_portal();
+ bool checkPassword();
+
+ virtual int resurrectionSelectDialogue() = 0;
+ virtual void useHorn(int charIndex, int weaponSlot) {}
+ virtual bool checkPartyStatusExtra() = 0;
+ virtual void drawLightningColumn() {}
+ virtual int charSelectDialogue() { return -1; }
+ virtual void characterLevelGain(int charIndex) {}
+
+ Common::Error loadGameState(int slot);
+ Common::Error saveGameStateIntern(int slot, const char *saveName, const Graphics::Surface *thumbnail);
+
+ const uint8 *_cgaMappingDefault;
+ const uint8 *_cgaMappingAlt;
+ const uint8 *_cgaMappingInv;
+ const uint8 *_cgaMappingItemsL;
+ const uint8 *_cgaMappingItemsS;
+ const uint8 *_cgaMappingThrown;
+ const uint8 *_cgaMappingIcons;
+ const uint8 *_cgaMappingDeco;
+ const uint8 *_cgaMappingLevel[5];
+ const uint8 *_cgaLevelMappingIndex;
+
+ bool _useHiResDithering;
+
+ // Default parameters will import all present original save files and push them to the top of the save dialog.
+ bool importOriginalSaveFile(int destSlot, const char *sourceFile = 0);
+ Common::String readOriginalSaveFile(Common::String &file);
+
+ void *generateMonsterTempData(LevelTempData *tmp);
+ void restoreMonsterTempData(LevelTempData *tmp);
+ void releaseMonsterTempData(LevelTempData *tmp);
+ void *generateWallOfForceTempData(LevelTempData *tmp);
+ void restoreWallOfForceTempData(LevelTempData *tmp);
+ void releaseWallOfForceTempData(LevelTempData *tmp);
+
+ const char * const *_saveLoadStrings;
+
+ const uint8 *_mnDef;
+ const char * const *_mnWord;
+ const char * const *_mnPrompt;
+ int _mnNumWord;
+
+ int _rrCount;
+ const char *_rrNames[10];
+ int8 _rrId[10];
+
+ bool _allowSkip;
+ bool _allowImport;
+
+ Screen_EoB *_screen;
+ GUI_EoB *_gui;
+
+ // fight
+ void useSlotWeapon(int charIndex, int slotIndex, Item item);
+ int closeDistanceAttack(int charIndex, Item item);
+ int thrownAttack(int charIndex, int slotIndex, Item item);
+ int projectileWeaponAttack(int charIndex, Item item);
+
+ void inflictMonsterDamage(EoBMonsterInPlay *m, int damage, bool giveExperience);
+ void calcAndInflictMonsterDamage(EoBMonsterInPlay *m, int times, int pips, int offs, int flags, int savingThrowType, int savingThrowEffect);
+ void calcAndInflictCharacterDamage(int charIndex, int times, int itemOrPips, int useStrModifierOrBase, int flags, int savingThrowType, int savingThrowEffect);
+ int calcCharacterDamage(int charIndex, int times, int itemOrPips, int useStrModifierOrBase, int flags, int savingThrowType, int damageType) ;
+ void inflictCharacterDamage(int charIndex, int damage);
+
+ bool characterAttackHitTest(int charIndex, int monsterIndex, int item, int attackType);
+ bool monsterAttackHitTest(EoBMonsterInPlay *m, int charIndex);
+ bool flyingObjectMonsterHit(EoBFlyingObject *fo, int monsterIndex);
+ bool flyingObjectPartyHit(EoBFlyingObject *fo);
+
+ void monsterCloseAttack(EoBMonsterInPlay *m);
+ void monsterSpellCast(EoBMonsterInPlay *m, int type);
+ void statusAttack(int charIndex, int attackStatusFlags, const char *attackStatusString, int savingThrowType, uint32 effectDuration, int restoreEvent, int noRefresh);
+
+ int calcMonsterDamage(EoBMonsterInPlay *m, int times, int pips, int offs, int flags, int savingThrowType, int savingThrowEffect);
+ int calcDamageModifers(int charIndex, EoBMonsterInPlay *m, int item, int itemType, int useStrModifier);
+ bool trySavingThrow(void *target, int hpModifier, int level, int type, int race);
+ bool specialAttackSavingThrow(int charIndex, int type);
+ int getSaveThrowModifier(int hpModifier, int level, int type);
+ bool calcDamageCheckItemType(int itemType);
+ int savingThrowReduceDamage(int savingThrowEffect, int damage);
+ bool tryMonsterAttackEvasion(EoBMonsterInPlay *m);
+ int getStrHitChanceModifier(int charIndex);
+ int getStrDamageModifier(int charIndex);
+ int getDexHitChanceModifier(int charIndex);
+ int getMonsterAcHitChanceModifier(int charIndex, int monsterAc);
+ void explodeMonster(EoBMonsterInPlay *m);
+
+ int _dstMonsterIndex;
+ bool _preventMonsterFlash;
+ int16 _foundMonstersArray[5];
+ int8 _monsterBlockPosArray[6];
+
+ // magic
+ void useMagicBookOrSymbol(int charIndex, int type);
+ void useMagicScroll(int charIndex, int type, int weaponSlot);
+ void usePotion(int charIndex, int weaponSlot);
+ void useWand(int charIndex, int weaponSlot);
+
+ virtual void turnUndeadAuto() {};
+ virtual void turnUndeadAutoHit() {};
+
+ void castSpell(int spell, int weaponSlot);
+ void removeCharacterEffect(int spell, int charIndex, int showWarning);
+ void removeAllCharacterEffects(int charIndex);
+ void castOnWhomDialogue();
+ void startSpell(int spell);
+
+ void sparkEffectDefensive(int charIndex);
+ void sparkEffectOffensive();
+ void setSpellEventTimer(int spell, int timerBaseFactor, int timerLength, int timerLevelFactor, int updateExistingTimer);
+ void sortCharacterSpellList(int charIndex);
+
+ bool magicObjectDamageHit(EoBFlyingObject *fo, int dcTimes, int dcPips, int dcOffs, int level);
+ bool magicObjectStatusHit(EoBMonsterInPlay *m, int type, bool tryEvade, int mod);
+ bool turnUndeadHit(EoBMonsterInPlay *m, int hitChance, int casterLevel);
+ void causeWounds(int dcTimes, int dcPips, int dcOffs);
+
+ int getMagicWeaponSlot(int charIndex);
+ int createMagicWeaponType(int invFlags, int handFlags, int armorClass, int allowedClasses, int dmgNum, int dmgPips, int dmgInc, int extraProps);
+ Item createMagicWeaponItem(int flags, int icon, int value, int type);
+ void removeMagicWeaponItem(Item item);
+
+ void updateWallOfForceTimers();
+ void destroyWallOfForce(int index);
+
+ int findSingleSpellTarget(int dist);
+
+ int findFirstCharacterSpellTarget();
+ int findNextCharacterSpellTarget(int curCharIndex);
+ int charDeathSavingThrow(int charIndex, int div);
+
+ void printWarning(const char *str);
+ void printNoEffectWarning();
+
+ void spellCallback_start_empty() {}
+ bool spellCallback_end_empty(void *) { return true; }
+ void spellCallback_start_armor();
+ void spellCallback_start_burningHands();
+ void spellCallback_start_detectMagic();
+ bool spellCallback_end_detectMagic(void *);
+ void spellCallback_start_magicMissile();
+ bool spellCallback_end_magicMissile(void *obj);
+ void spellCallback_start_shockingGrasp();
+ bool spellCallback_end_shockingGraspFlameBlade(void *obj);
+ void spellCallback_start_improvedIdentify();
+ void spellCallback_start_melfsAcidArrow();
+ bool spellCallback_end_melfsAcidArrow(void *obj);
+ void spellCallback_start_dispelMagic();
+ void spellCallback_start_fireball();
+ bool spellCallback_end_fireball(void *obj);
+ void spellCallback_start_flameArrow();
+ bool spellCallback_end_flameArrow(void *obj);
+ void spellCallback_start_holdPerson();
+ bool spellCallback_end_holdPerson(void *obj);
+ void spellCallback_start_lightningBolt();
+ bool spellCallback_end_lightningBolt(void *obj);
+ void spellCallback_start_vampiricTouch();
+ bool spellCallback_end_vampiricTouch(void *obj);
+ void spellCallback_start_fear();
+ void spellCallback_start_iceStorm();
+ bool spellCallback_end_iceStorm(void *obj);
+ void spellCallback_start_stoneSkin();
+ void spellCallback_start_removeCurse();
+ void spellCallback_start_coneOfCold();
+ void spellCallback_start_holdMonster();
+ bool spellCallback_end_holdMonster(void *obj);
+ void spellCallback_start_wallOfForce();
+ void spellCallback_start_disintegrate();
+ void spellCallback_start_fleshToStone();
+ void spellCallback_start_stoneToFlesh();
+ void spellCallback_start_trueSeeing();
+ bool spellCallback_end_trueSeeing(void *);
+ void spellCallback_start_slayLiving();
+ void spellCallback_start_powerWordStun();
+ void spellCallback_start_causeLightWounds();
+ void spellCallback_start_cureLightWounds();
+ void spellCallback_start_aid();
+ bool spellCallback_end_aid(void *obj);
+ void spellCallback_start_flameBlade();
+ void spellCallback_start_slowPoison();
+ bool spellCallback_end_slowPoison(void *obj);
+ void spellCallback_start_createFood();
+ void spellCallback_start_removeParalysis();
+ void spellCallback_start_causeSeriousWounds();
+ void spellCallback_start_cureSeriousWounds();
+ void spellCallback_start_neutralizePoison();
+ void spellCallback_start_causeCriticalWounds();
+ void spellCallback_start_cureCriticalWounds();
+ void spellCallback_start_flameStrike();
+ bool spellCallback_end_flameStrike(void *obj);
+ void spellCallback_start_raiseDead();
+ void spellCallback_start_harm();
+ void spellCallback_start_heal();
+ void spellCallback_start_layOnHands();
+ void spellCallback_start_turnUndead();
+ bool spellCallback_end_monster_lightningBolt(void *obj);
+ bool spellCallback_end_monster_fireball1(void *obj);
+ bool spellCallback_end_monster_fireball2(void *obj);
+ bool spellCallback_end_monster_deathSpell(void *obj);
+ bool spellCallback_end_monster_disintegrate(void *obj);
+ bool spellCallback_end_monster_causeCriticalWounds(void *obj);
+ bool spellCallback_end_monster_fleshToStone(void *obj);
+
+ int8 _openBookSpellLevel;
+ int8 _openBookSpellSelectedItem;
+ int8 _openBookSpellListOffset;
+ uint8 _openBookChar;
+ uint8 _openBookType;
+ uint8 _openBookCharBackup;
+ uint8 _openBookTypeBackup;
+ uint8 _openBookCasterLevel;
+ const char *const *_openBookSpellList;
+ int8 *_openBookAvailableSpells;
+ uint8 _activeSpellCharId;
+ uint8 _activeSpellCharacterPos;
+ int _activeSpell;
+ int _characterSpellTarget;
+ bool _returnAfterSpellCallback;
+
+ typedef void (EoBCoreEngine::*SpellStartCallback)();
+ typedef bool (EoBCoreEngine::*SpellEndCallback)(void *obj);
+
+ struct EoBSpell {
+ const char *name;
+ SpellStartCallback startCallback;
+ uint16 flags;
+ const uint16 *timingPara;
+ SpellEndCallback endCallback;
+ uint8 sound;
+ uint32 effectFlags;
+ uint16 damageFlags;
+ };
+
+ EoBSpell *_spells;
+ int _numSpells;
+
+ struct WallOfForce {
+ uint16 block;
+ uint32 duration;
+ };
+
+ WallOfForce *_wallsOfForce;
+
+ const char *const *_bookNumbers;
+ const char *const *_mageSpellList;
+ int _mageSpellListSize;
+ int _clericSpellOffset;
+ const char *const *_clericSpellList;
+ const char *const *_spellNames;
+ const char *const *_magicStrings1;
+ const char *const *_magicStrings2;
+ const char *const *_magicStrings3;
+ const char *const *_magicStrings4;
+ const char *const *_magicStrings6;
+ const char *const *_magicStrings7;
+ const char *const *_magicStrings8;
+
+ uint8 *_spellAnimBuffer;
+
+ const uint8 *_sparkEffectDefSteps;
+ const uint8 *_sparkEffectDefSubSteps;
+ const uint8 *_sparkEffectDefShift;
+ const uint8 *_sparkEffectDefAdd;
+ const uint8 *_sparkEffectDefX;
+ const uint8 *_sparkEffectDefY;
+ const uint32 *_sparkEffectOfFlags1;
+ const uint32 *_sparkEffectOfFlags2;
+ const uint8 *_sparkEffectOfShift;
+ const uint8 *_sparkEffectOfX;
+ const uint8 *_sparkEffectOfY;
+
+ const uint8 *_magicFlightObjectProperties;
+ const uint8 *_turnUndeadEffect;
+ const uint8 *_burningHandsDest;
+ const int8 *_coneOfColdDest1;
+ const int8 *_coneOfColdDest2;
+ const int8 *_coneOfColdDest3;
+ const int8 *_coneOfColdDest4;
+ const uint8 *_coneOfColdGfxTbl;
+ int _coneOfColdGfxTblSize;
+
+ // Menu
+ EoBMenuDef *_menuDefs;
+ const EoBMenuButtonDef *_menuButtonDefs;
+
+ bool _configMouse;
+
+ const char *const *_menuStringsMain;
+ const char *const *_menuStringsSaveLoad;
+ const char *const *_menuStringsOnOff;
+ const char *const *_menuStringsSpells;
+ const char *const *_menuStringsRest;
+ const char *const *_menuStringsDrop;
+ const char *const *_menuStringsExit;
+ const char *const *_menuStringsStarve;
+ const char *const *_menuStringsScribe;
+ const char *const *_menuStringsDrop2;
+ const char *const *_menuStringsHead;
+ const char *const *_menuStringsPoison;
+ const char *const *_menuStringsMgc;
+ const char *const *_menuStringsPrefs;
+ const char *const *_menuStringsRest2;
+ const char *const *_menuStringsRest3;
+ const char *const *_menuStringsRest4;
+ const char *const *_menuStringsDefeat;
+ const char *_errorSlotEmptyString;
+ const char *_errorSlotNoNameString;
+ const char *_menuOkString;
+
+ const char *const *_menuStringsTransfer;
+ const char *const *_transferStringsScummVM;
+ const char *const *_menuStringsSpec;
+ const char *const *_menuStringsSpellNo;
+ const char *const *_menuYesNoStrings;
+
+ const uint8 *_spellLevelsMage;
+ int _spellLevelsMageSize;
+ const uint8 *_spellLevelsCleric;
+ int _spellLevelsClericSize;
+ const uint8 *_numSpellsCleric;
+ const uint8 *_numSpellsWisAdj;
+ const uint8 *_numSpellsPal;
+ const uint8 *_numSpellsMage;
+
+ // sound
+ void snd_playSong(int id);
+ void snd_playSoundEffect(int id, int volume=0xFF);
+ void snd_stopSound();
+ void snd_fadeOut();
+
+ // keymap
+ static const char *const kKeymapName;
+};
+
+} // End of namespace Kyra
+
+#endif // ENABLE_EOB
+
+#endif
diff --git a/engines/kyra/gui.cpp b/engines/kyra/gui.cpp
index 7fd9880dce..1156b17957 100644
--- a/engines/kyra/gui.cpp
+++ b/engines/kyra/gui.cpp
@@ -20,377 +20,62 @@
*
*/
-#include "kyra/gui.h"
-#include "kyra/text.h"
-#include "kyra/wsamovie.h"
+#include "kyra/gui.h"
+#include "kyra/kyra_v1.h"
+#include "kyra/util.h"
#include "common/savefile.h"
#include "common/system.h"
-namespace Kyra {
-
-GUI::GUI(KyraEngine_v1 *kyra)
- : _vm(kyra), _screen(kyra->screen()), _text(kyra->text()) {
- _menuButtonList = 0;
-
- _redrawButtonFunctor = BUTTON_FUNCTOR(GUI, this, &GUI::redrawButtonCallback);
- _redrawShadedButtonFunctor = BUTTON_FUNCTOR(GUI, this, &GUI::redrawShadedButtonCallback);
-}
-
-Button *GUI::addButtonToList(Button *list, Button *newButton) {
- if (!newButton)
- return list;
-
- newButton->nextButton = 0;
-
- if (list) {
- Button *cur = list;
- while (cur->nextButton)
- cur = cur->nextButton;
- cur->nextButton = newButton;
- } else {
- list = newButton;
- }
-
- return list;
-}
-
-void GUI::initMenuLayout(Menu &menu) {
- if (menu.x == -1)
- menu.x = (320 - menu.width) >> 1;
- if (menu.y == -1)
- menu.y = (200 - menu.height) >> 1;
-
- for (int i = 0; i < menu.numberOfItems; ++i) {
- if (menu.item[i].x == -1)
- menu.item[i].x = (menu.width - menu.item[i].width) >> 1;
- }
-}
-
-void GUI::initMenu(Menu &menu) {
- _menuButtonList = 0;
-
- _screen->hideMouse();
-
- int textX;
- int textY;
-
- int menu_x2 = menu.width + menu.x - 1;
- int menu_y2 = menu.height + menu.y - 1;
-
- _screen->fillRect(menu.x + 2, menu.y + 2, menu_x2 - 2, menu_y2 - 2, menu.bkgdColor);
- _screen->drawShadedBox(menu.x, menu.y, menu_x2, menu_y2, menu.color1, menu.color2);
-
- if (menu.titleX != -1)
- textX = menu.titleX;
- else
- textX = getMenuCenterStringX(getMenuTitle(menu), menu.x, menu_x2);
-
- textY = menu.y + menu.titleY;
-
- if (_vm->game() == GI_LOL) {
- printMenuText(getMenuTitle(menu), textX, textY, menu.textColor, 0, 9);
- } else {
- if (_vm->gameFlags().platform != Common::kPlatformAmiga)
- printMenuText(getMenuTitle(menu), textX - 1, textY + 1, defaultColor1(), defaultColor2(), 0);
- printMenuText(getMenuTitle(menu), textX, textY, menu.textColor, 0, 0);
- }
-
- int x1, y1, x2, y2;
- for (int i = 0; i < menu.numberOfItems; ++i) {
- if (!menu.item[i].enabled)
- continue;
-
- x1 = menu.x + menu.item[i].x;
- y1 = menu.y + menu.item[i].y;
-
- x2 = x1 + menu.item[i].width - 1;
- y2 = y1 + menu.item[i].height - 1;
-
- if (i < 7) {
- Button *menuButtonData = getButtonListData() + i;
- menuButtonData->nextButton = 0;
- menuButtonData->x = x1;
- menuButtonData->y = y1;
- menuButtonData->width = menu.item[i].width - 1;
- menuButtonData->height = menu.item[i].height - 1;
- menuButtonData->buttonCallback = menu.item[i].callback;
- menuButtonData->keyCode = menu.item[i].keyCode;
- menuButtonData->keyCode2 = 0;
- menuButtonData->arg = menu.item[i].itemId;
-
- _menuButtonList = addButtonToList(_menuButtonList, menuButtonData);
- }
-
- _screen->fillRect(x1, y1, x2, y2, menu.item[i].bkgdColor);
- _screen->drawShadedBox(x1, y1, x2, y2, menu.item[i].color1, menu.item[i].color2);
-
- if (getMenuItemTitle(menu.item[i])) {
- if (menu.item[i].titleX != -1)
- textX = x1 + menu.item[i].titleX + 3;
- else
- textX = getMenuCenterStringX(getMenuItemTitle(menu.item[i]), x1, x2);
-
- textY = y1 + 2;
- if (_vm->game() == GI_LOL) {
- textY++;
- if (i == menu.highlightedItem)
- printMenuText(getMenuItemTitle(menu.item[i]), textX, textY, menu.item[i].highlightColor, 0, 8);
- else
- printMenuText(getMenuItemTitle(menu.item[i]), textX, textY, menu.item[i].textColor, 0, 8);
- } else {
- Screen::FontId of = _screen->_currentFont;
- if (menu.item[i].saveSlot > 0)
- _screen->setFont(Screen::FID_8_FNT);
-
- if (_vm->gameFlags().platform != Common::kPlatformAmiga)
- printMenuText(getMenuItemTitle(menu.item[i]), textX - 1, textY + 1, defaultColor1(), 0, 0);
-
- if (i == menu.highlightedItem)
- printMenuText(getMenuItemTitle(menu.item[i]), textX, textY, menu.item[i].highlightColor, 0, 0);
- else
- printMenuText(getMenuItemTitle(menu.item[i]), textX, textY, menu.item[i].textColor, 0, 0);
-
- _screen->setFont(of);
- }
- }
- }
-
- for (int i = 0; i < menu.numberOfItems; ++i) {
- if (getMenuItemLabel(menu.item[i])) {
- if (_vm->game() == GI_LOL) {
- menu.item[i].labelX = menu.item[i].x - 1;
- menu.item[i].labelY = menu.item[i].y + 3;
- printMenuText(getMenuItemLabel(menu.item[i]), menu.x + menu.item[i].labelX, menu.y + menu.item[i].labelY, menu.item[i].textColor, 0, 10);
- } else {
- if (_vm->gameFlags().platform != Common::kPlatformAmiga)
- printMenuText(getMenuItemLabel(menu.item[i]), menu.x + menu.item[i].labelX - 1, menu.y + menu.item[i].labelY + 1, defaultColor1(), 0, 0);
- printMenuText(getMenuItemLabel(menu.item[i]), menu.x + menu.item[i].labelX, menu.y + menu.item[i].labelY, menu.item[i].textColor, 0, 0);
- }
- }
- }
-
- if (menu.scrollUpButtonX != -1) {
- Button *scrollUpButton = getScrollUpButton();
- scrollUpButton->x = menu.scrollUpButtonX + menu.x;
- scrollUpButton->y = menu.scrollUpButtonY + menu.y;
- scrollUpButton->buttonCallback = getScrollUpButtonHandler();
- scrollUpButton->nextButton = 0;
- scrollUpButton->mouseWheel = -1;
-
- _menuButtonList = addButtonToList(_menuButtonList, scrollUpButton);
- updateMenuButton(scrollUpButton);
-
- Button *scrollDownButton = getScrollDownButton();
- scrollDownButton->x = menu.scrollDownButtonX + menu.x;
- scrollDownButton->y = menu.scrollDownButtonY + menu.y;
- scrollDownButton->buttonCallback = getScrollDownButtonHandler();
- scrollDownButton->nextButton = 0;
- scrollDownButton->mouseWheel = 1;
-
- _menuButtonList = addButtonToList(_menuButtonList, scrollDownButton);
- updateMenuButton(scrollDownButton);
- }
-
- _screen->showMouse();
- _screen->updateScreen();
-}
-
-void GUI::processHighlights(Menu &menu) {
- int x1, y1, x2, y2;
- Common::Point p = _vm->getMousePos();
- int mouseX = p.x;
- int mouseY = p.y;
-
- if (_vm->game() == GI_LOL && menu.highlightedItem != 255) {
- // LoL doesnt't have default highlighted items.
- // We use a highlightedItem value of 255 for this.
-
- // With LoL no highlighting should take place unless the
- // mouse cursor moves over a button. The highlighting should end
- // when the mouse cursor leaves the button.
- if (menu.item[menu.highlightedItem].enabled)
- redrawText(menu);
- }
-
- for (int i = 0; i < menu.numberOfItems; ++i) {
- if (!menu.item[i].enabled)
- continue;
-
- x1 = menu.x + menu.item[i].x;
- y1 = menu.y + menu.item[i].y;
-
- x2 = x1 + menu.item[i].width;
- y2 = y1 + menu.item[i].height;
-
- if (mouseX > x1 && mouseX < x2 &&
- mouseY > y1 && mouseY < y2) {
-
- if (menu.highlightedItem != i || _vm->game() == GI_LOL) {
- if (_vm->game() != GI_LOL) {
- if (menu.item[menu.highlightedItem].enabled)
- redrawText(menu);
- }
-
- menu.highlightedItem = i;
- redrawHighlight(menu);
- }
- }
- }
-
- _screen->updateScreen();
-}
-
-void GUI::redrawText(const Menu &menu) {
- int textX;
- int i = menu.highlightedItem;
-
- int x1 = menu.x + menu.item[i].x;
- int y1 = menu.y + menu.item[i].y;
-
- int x2 = x1 + menu.item[i].width - 1;
- if (menu.item[i].titleX >= 0)
- textX = x1 + menu.item[i].titleX + 3;
- else
- textX = getMenuCenterStringX(getMenuItemTitle(menu.item[i]), x1, x2);
+namespace Kyra {
- int textY = y1 + 2;
- if (_vm->game() == GI_LOL) {
- textY++;
- printMenuText(getMenuItemTitle(menu.item[i]), textX, textY, menu.item[i].textColor, 0, 8);
- } else {
- Screen::FontId of = _screen->_currentFont;
- if (menu.item[i].saveSlot > 0)
- _screen->setFont(Screen::FID_8_FNT);
- if (_vm->gameFlags().platform != Common::kPlatformAmiga)
- printMenuText(getMenuItemTitle(menu.item[i]), textX - 1, textY + 1, defaultColor1(), 0, 0);
- printMenuText(getMenuItemTitle(menu.item[i]), textX, textY, menu.item[i].textColor, 0, 0);
- _screen->setFont(of);
- }
+GUI::GUI(KyraEngine_v1 *kyra) : _vm(kyra), _screen(kyra->screen()) {
+ _saveSlotsListUpdateNeeded = true;
+ _savegameListSize = 0;
+ _savegameList = 0;
}
-void GUI::redrawHighlight(const Menu &menu) {
- int textX;
- int i = menu.highlightedItem;
-
- int x1 = menu.x + menu.item[i].x;
- int y1 = menu.y + menu.item[i].y;
-
- int x2 = x1 + menu.item[i].width - 1;
-
- if (menu.item[i].titleX != -1)
- textX = x1 + menu.item[i].titleX + 3;
- else
- textX = getMenuCenterStringX(getMenuItemTitle(menu.item[i]), x1, x2);
-
- int textY = y1 + 2;
-
- if (_vm->game() == GI_LOL) {
- textY++;
- printMenuText(getMenuItemTitle(menu.item[i]), textX, textY, menu.item[i].highlightColor, 0, 8);
- } else {
- Screen::FontId of = _screen->_currentFont;
- if (menu.item[i].saveSlot > 0)
- _screen->setFont(Screen::FID_8_FNT);
- if (_vm->gameFlags().platform != Common::kPlatformAmiga)
- printMenuText(getMenuItemTitle(menu.item[i]), textX - 1, textY + 1, defaultColor1(), 0, 0);
- printMenuText(getMenuItemTitle(menu.item[i]), textX, textY, menu.item[i].highlightColor, 0, 0);
- _screen->setFont(of);
+GUI::~GUI() {
+ if (_savegameList) {
+ for (int i = 0; i < _savegameListSize; i++)
+ delete[] _savegameList[i];
+ delete[] _savegameList;
+ _savegameList = 0;
}
}
-void GUI::updateAllMenuButtons() {
- for (Button *cur = _menuButtonList; cur; cur = cur->nextButton)
- updateMenuButton(cur);
-}
-
-void GUI::updateMenuButton(Button *button) {
- if (!_displayMenu)
- return;
-
- _screen->hideMouse();
- updateButton(button);
- _screen->updateScreen();
- _screen->showMouse();
-}
-
-void GUI::updateButton(Button *button) {
- if (!button || (button->flags & 8))
- return;
-
- if (button->flags2 & 1)
- button->flags2 &= 0xFFF7;
- else
- button->flags2 |= 8;
-
- button->flags2 &= 0xFFFC;
-
- if (button->flags2 & 4)
- button->flags2 |= 0x10;
- else
- button->flags2 &= 0xEEEF;
-
- button->flags2 &= 0xFFFB;
-
- processButton(button);
-}
-
-int GUI::redrawButtonCallback(Button *button) {
- if (!_displayMenu)
- return 0;
-
- _screen->hideMouse();
- if (_vm->gameFlags().platform == Common::kPlatformAmiga)
- _screen->drawBox(button->x + 1, button->y + 1, button->x + button->width - 1, button->y + button->height - 1, 17);
- else
- _screen->drawBox(button->x + 1, button->y + 1, button->x + button->width - 1, button->y + button->height - 1, 0xF8);
- _screen->showMouse();
-
- return 0;
-}
-
-int GUI::redrawShadedButtonCallback(Button *button) {
- if (!_displayMenu)
- return 0;
-
- _screen->hideMouse();
- if (_vm->gameFlags().platform == Common::kPlatformAmiga)
- _screen->drawShadedBox(button->x, button->y, button->x + button->width, button->y + button->height, 31, 18);
- else
- _screen->drawShadedBox(button->x, button->y, button->x + button->width, button->y + button->height, 0xF9, 0xFA);
- _screen->showMouse();
-
- return 0;
-}
-
-void GUI::updateSaveList(bool excludeQuickSaves) {
- Common::String pattern = _vm->_targetName + ".???";
+void GUI::updateSaveFileList(Common::String targetName, bool excludeQuickSaves) {
+ Common::String pattern = targetName + ".???";
Common::StringArray saveFileList = _vm->_saveFileMan->listSavefiles(pattern);
_saveSlots.clear();
for (Common::StringArray::const_iterator i = saveFileList.begin(); i != saveFileList.end(); ++i) {
char s1 = 0, s2 = 0, s3 = 0;
- s1 = (*i)[i->size()-3];
- s2 = (*i)[i->size()-2];
- s3 = (*i)[i->size()-1];
- if (!isdigit(static_cast<unsigned char>(s1)) || !isdigit(static_cast<unsigned char>(s2)) || !isdigit(static_cast<unsigned char>(s3)))
+ s1 = (*i)[i->size() - 3];
+ s2 = (*i)[i->size() - 2];
+ s3 = (*i)[i->size() - 1];
+ if (!Common::isDigit(s1) || !Common::isDigit(s2) || !Common::isDigit(s3))
continue;
s1 -= '0';
s2 -= '0';
s3 -= '0';
if (excludeQuickSaves && s1 == 9 && s2 == 9)
continue;
- _saveSlots.push_back(s1*100+s2*10+s3);
+ _saveSlots.push_back(s1 * 100 + s2 * 10 + s3);
}
if (_saveSlots.begin() == _saveSlots.end())
return;
+ sortSaveSlots();
+}
+
+void GUI::sortSaveSlots() {
Common::sort(_saveSlots.begin(), _saveSlots.end(), Common::Less<int>());
if (_saveSlots.size() > 2)
- Common::sort(_saveSlots.begin()+1, _saveSlots.end(), Common::Greater<int>());
+ Common::sort(_saveSlots.begin() + 1, _saveSlots.end(), Common::Greater<int>());
}
int GUI::getNextSavegameSlot() {
@@ -408,266 +93,49 @@ int GUI::getNextSavegameSlot() {
return 0;
}
-void GUI::checkTextfieldInput() {
- Common::Event event;
-
- uint32 now = _vm->_system->getMillis();
-
- bool running = true;
- int keys = 0;
- while (running && _vm->_eventMan->pollEvent(event)) {
- switch (event.type) {
- case Common::EVENT_KEYDOWN:
- if (event.kbd.keycode == Common::KEYCODE_q && event.kbd.hasFlags(Common::KBD_CTRL))
- _vm->quitGame();
- else
- _keyPressed = event.kbd;
- running = false;
- break;
-
- case Common::EVENT_LBUTTONDOWN:
- case Common::EVENT_LBUTTONUP: {
- Common::Point pos = _vm->getMousePos();
- _vm->_mouseX = pos.x;
- _vm->_mouseY = pos.y;
- keys = event.type == Common::EVENT_LBUTTONDOWN ? 199 : (200 | 0x800);
- running = false;
- } break;
-
- case Common::EVENT_MOUSEMOVE: {
- Common::Point pos = _vm->getMousePos();
- _vm->_mouseX = pos.x;
- _vm->_mouseY = pos.y;
-
- _vm->_system->updateScreen();
- _lastScreenUpdate = now;
- } break;
-
- default:
- break;
- }
- }
-
- if (now - _lastScreenUpdate > 50) {
- _vm->_system->updateScreen();
- _lastScreenUpdate = now;
- }
-
- processButtonList(_menuButtonList, keys | 0x8000, 0);
- _vm->_system->delayMillis(3);
-}
-
-void GUI::printMenuText(const char *str, int x, int y, uint8 c0, uint8 c1, uint8 c2) {
- _text->printText(str, x, y, c0, c1, c2);
-}
-
-int GUI::getMenuCenterStringX(const char *str, int x1, int x2) {
- return _text->getCenterStringX(str, x1, x2);
-}
-
-#pragma mark -
-
-MainMenu::MainMenu(KyraEngine_v1 *vm) : _vm(vm), _screen(0) {
- _screen = _vm->screen();
- _nextUpdate = 0;
- _system = g_system;
-}
-
-void MainMenu::init(StaticData data, Animation anim) {
- _static = data;
- _anim = anim;
- _animIntern.curFrame = _anim.startFrame;
- _animIntern.direction = 1;
-}
-
-void MainMenu::updateAnimation() {
- if (_anim.anim) {
- uint32 now = _system->getMillis();
- if (now > _nextUpdate) {
- _nextUpdate = now + _anim.delay * _vm->tickLength();
-
- _anim.anim->displayFrame(_animIntern.curFrame, 0, 0, 0, 0, 0, 0);
- _animIntern.curFrame += _animIntern.direction;
- if (_animIntern.curFrame < _anim.startFrame) {
- _animIntern.curFrame = _anim.startFrame;
- _animIntern.direction = 1;
- } else if (_animIntern.curFrame > _anim.endFrame) {
- _animIntern.curFrame = _anim.endFrame;
- _animIntern.direction = -1;
- }
- }
- }
-
- _screen->updateScreen();
-}
-
-bool MainMenu::getInput() {
- Common::Event event;
- Common::EventManager *eventMan = _vm->getEventManager();
-
- bool updateScreen = false;
-
- while (eventMan->pollEvent(event)) {
- switch (event.type) {
- case Common::EVENT_LBUTTONUP:
- return true;
+void GUI::updateSaveSlotsList(Common::String targetName, bool force) {
+ if (!_saveSlotsListUpdateNeeded && !force)
+ return;
- case Common::EVENT_MOUSEMOVE:
- updateScreen = true;
- break;
+ _saveSlotsListUpdateNeeded = false;
- default:
- break;
- }
+ if (_savegameList) {
+ for (int i = 0; i < _savegameListSize; i++)
+ delete[] _savegameList[i];
+ delete[] _savegameList;
}
- if (updateScreen)
- _system->updateScreen();
- return false;
-}
-
-int MainMenu::handle(int dim) {
- int command = -1;
-
- uint8 colorMap[16];
- memset(colorMap, 0, sizeof(colorMap));
- _screen->setTextColorMap(colorMap);
-
- Screen::FontId oldFont = _screen->setFont(_static.font);
- int charWidthBackUp = _screen->_charWidth;
-
- if (_vm->game() != GI_LOL)
- _screen->_charWidth = -2;
- _screen->setScreenDim(dim);
-
- int backUpX = _screen->_curDim->sx;
- int backUpY = _screen->_curDim->sy;
- int backUpWidth = _screen->_curDim->w;
- int backUpHeight = _screen->_curDim->h;
- _screen->copyRegion(backUpX, backUpY, backUpX, backUpY, backUpWidth, backUpHeight, 0, 3);
-
- int x = _screen->_curDim->sx << 3;
- int y = _screen->_curDim->sy;
- int width = _screen->_curDim->w << 3;
- int height = _screen->_curDim->h;
+ updateSaveFileList(targetName, true);
+ int numSaves = _savegameListSize = _saveSlots.size();
+ bool allowEmptySlots = (_vm->game() == GI_EOB1 || _vm->game() == GI_EOB2);
- drawBox(x, y, width, height, 1);
- drawBox(x + 1, y + 1, width - 2, height - 2, 0);
+ if (_savegameListSize) {
+ if (allowEmptySlots)
+ _savegameListSize = 990;
- int selected = 0;
+ KyraEngine_v1::SaveHeader header;
+ Common::InSaveFile *in;
- draw(selected);
+ _savegameList = new char*[_savegameListSize];
+ memset(_savegameList, 0, _savegameListSize * sizeof(char *));
- while (!_screen->isMouseVisible())
- _screen->showMouse();
-
- int fh = _screen->getFontHeight();
- if (_vm->gameFlags().lang == Common::JA_JPN)
- fh++;
-
- int textPos = ((_screen->_curDim->w >> 1) + _screen->_curDim->sx) << 3;
-
- Common::Rect menuRect(x + 16, y + 4, x + width - 16, y + 4 + fh * _static.menuTable[3]);
-
- while (!_vm->shouldQuit()) {
- updateAnimation();
- bool mousePressed = getInput();
-
- Common::Point mouse = _vm->getMousePos();
- if (menuRect.contains(mouse)) {
- int item = (mouse.y - menuRect.top) / fh;
-
- if (item != selected) {
- printString("%s", textPos, menuRect.top + selected * fh, _static.menuTable[5], 0, 5, _static.strings[selected]);
- printString("%s", textPos, menuRect.top + item * fh, _static.menuTable[6], 0, 5, _static.strings[item]);
-
- selected = item;
- }
-
- if (mousePressed) {
- for (int i = 0; i < 3; i++) {
- printString("%s", textPos, menuRect.top + selected * fh, _static.menuTable[5], 0, 5, _static.strings[selected]);
- _screen->updateScreen();
- _system->delayMillis(50);
- printString("%s", textPos, menuRect.top + selected * fh, _static.menuTable[6], 0, 5, _static.strings[selected]);
- _screen->updateScreen();
- _system->delayMillis(50);
- }
- command = item;
- break;
+ for (int i = 0; i < numSaves; i++) {
+ in = _vm->openSaveForReading(_vm->getSavegameFilename(targetName, _saveSlots[i]).c_str(), header, targetName == _vm->_targetName);
+ char **listEntry = &_savegameList[allowEmptySlots ? _saveSlots[i] : i];
+ if (in) {
+ *listEntry = new char[header.description.size() + 1];
+ Common::strlcpy(*listEntry, header.description.c_str(), header.description.size() + 1);
+ Util::convertISOToDOS(*listEntry);
+ delete in;
+ } else {
+ *listEntry = 0;
+ error("GUI::updateSavegameList(): Unexpected missing save file for slot: %d.", _saveSlots[i]);
}
}
- _system->delayMillis(10);
- }
- if (_vm->shouldQuit())
- command = -1;
-
- _screen->copyRegion(backUpX, backUpY, backUpX, backUpY, backUpWidth, backUpHeight, 3, 0);
- _screen->_charWidth = charWidthBackUp;
- _screen->setFont(oldFont);
-
- return command;
-}
-
-void MainMenu::draw(int select) {
- int top = _screen->_curDim->sy;
- top += _static.menuTable[1];
- int fh = _screen->getFontHeight();
- if (_vm->gameFlags().lang == Common::JA_JPN)
- fh++;
-
- for (int i = 0; i < _static.menuTable[3]; ++i) {
- int curY = top + i * fh;
- int color = (i == select) ? _static.menuTable[6] : _static.menuTable[5];
- printString("%s", ((_screen->_curDim->w >> 1) + _screen->_curDim->sx) << 3, curY, color, 0, 5, _static.strings[i]);
- }
-}
-
-void MainMenu::drawBox(int x, int y, int w, int h, int fill) {
- --w; --h;
-
- if (fill)
- _screen->fillRect(x, y, x+w, y+h, _static.colorTable[0]);
-
- _screen->drawClippedLine(x, y+h, x+w, y+h, _static.colorTable[1]);
- _screen->drawClippedLine(x+w, y, x+w, y+h, _static.colorTable[1]);
- _screen->drawClippedLine(x, y, x+w, y, _static.colorTable[2]);
- _screen->drawClippedLine(x, y, x, y+h, _static.colorTable[2]);
-
- _screen->setPagePixel(_screen->_curPage, x, y+h, _static.colorTable[3]);
- _screen->setPagePixel(_screen->_curPage, x+w, y, _static.colorTable[3]);
-}
-
-void MainMenu::printString(const char *format, int x, int y, int col1, int col2, int flags, ...) {
- if (!format)
- return;
-
- va_list vaList;
- va_start(vaList, flags);
- Common::String string = Common::String::vformat(format, vaList);
- va_end(vaList);
-
- if (flags & 1)
- x -= _screen->getTextWidth(string.c_str()) >> 1;
-
- if (flags & 2)
- x -= _screen->getTextWidth(string.c_str());
-
- if (_vm->gameFlags().use16ColorMode)
- flags &= 3;
-
- if (flags & 4) {
- _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.c_str(), x - 1, y, 227, col2);
- _screen->printText(string.c_str(), x, y + 1, 227, col2);
+ } else {
+ _savegameList = 0;
}
-
- _screen->printText(string.c_str(), x, y, col1, col2);
}
} // End of namespace Kyra
diff --git a/engines/kyra/gui.h b/engines/kyra/gui.h
index 1efbdde394..854f10e85d 100644
--- a/engines/kyra/gui.h
+++ b/engines/kyra/gui.h
@@ -40,10 +40,10 @@ struct Button {
typedef Common::Functor1<Button *, int> CallbackFunctor;
typedef Common::SharedPtr<CallbackFunctor> Callback;
- Button() : nextButton(0), index(0), keyCode(0), keyCode2(0), data0Val1(0), data1Val1(0), data2Val1(0), flags(0),
+ Button() : nextButton(0), index(0), keyCode(0), keyCode2(0), data0Val1(0), data1Val1(0), data2Val1(0), data3Val1(0), flags(0),
data0ShapePtr(0), data1ShapePtr(0), data2ShapePtr(0), data0Callback(), data1Callback(), data2Callback(),
dimTableIndex(0), x(0), y(0), width(0), height(0), data0Val2(0), data0Val3(0), data1Val2(0), data1Val3(0),
- data2Val2(0), data2Val3(0), flags2(0), mouseWheel(0), buttonCallback(), arg(0) {}
+ data2Val2(0), data2Val3(0), data3Val2(0), data3Val3(0), flags2(0), mouseWheel(0), buttonCallback(), extButtonDef(0), arg(0) {}
Button *nextButton;
uint16 index;
@@ -54,6 +54,7 @@ struct Button {
byte data0Val1;
byte data1Val1;
byte data2Val1;
+ byte data3Val1;
uint16 flags;
@@ -78,63 +79,18 @@ struct Button {
uint8 data2Val2;
uint8 data2Val3;
+ uint8 data3Val2;
+ uint8 data3Val3;
+
uint16 flags2;
int8 mouseWheel;
Callback buttonCallback;
- uint16 arg;
-};
-
-struct MenuItem {
- bool enabled;
-
- const char *itemString;
- uint16 itemId;
-
- int16 x, y;
- uint16 width, height;
-
- uint8 textColor, highlightColor;
-
- int16 titleX;
-
- uint8 color1, color2;
- uint8 bkgdColor;
-
- Button::Callback callback;
-
- int16 saveSlot;
-
- const char *labelString;
- uint16 labelId;
- int16 labelX, labelY;
-
- uint16 keyCode;
-};
-
-struct Menu {
- int16 x, y;
- uint16 width, height;
-
- uint8 bkgdColor;
- uint8 color1, color2;
-
- const char *menuNameString;
- uint16 menuNameId;
-
- uint8 textColor;
- int16 titleX, titleY;
+ const void *extButtonDef;
- uint8 highlightedItem;
-
- uint8 numberOfItems;
-
- int16 scrollUpButtonX, scrollUpButtonY;
- int16 scrollDownButtonX, scrollDownButtonY;
-
- MenuItem item[7];
+ uint16 arg;
};
class Screen;
@@ -143,123 +99,39 @@ class TextDisplayer;
class GUI {
public:
GUI(KyraEngine_v1 *vm);
- virtual ~GUI() {}
+ virtual ~GUI();
// button specific
- virtual Button *addButtonToList(Button *list, Button *newButton);
-
virtual void processButton(Button *button) = 0;
virtual int processButtonList(Button *buttonList, uint16 inputFlags, int8 mouseWheel) = 0;
- virtual int redrawShadedButtonCallback(Button *button);
- virtual int redrawButtonCallback(Button *button);
-
- // menu specific
- virtual void initMenuLayout(Menu &menu);
- void initMenu(Menu &menu);
-
- void processHighlights(Menu &menu);
-
// utilities for thumbnail creation
virtual void createScreenThumbnail(Graphics::Surface &dst) = 0;
+ void notifyUpdateSaveSlotsList() { _saveSlotsListUpdateNeeded = true; }
+
protected:
KyraEngine_v1 *_vm;
Screen *_screen;
- TextDisplayer *_text;
-
- Button *_menuButtonList;
- bool _displayMenu;
- bool _displaySubMenu;
- bool _cancelSubMenu;
-
- virtual void printMenuText(const char *str, int x, int y, uint8 c0, uint8 c1, uint8 c2);
- virtual int getMenuCenterStringX(const char *str, int x1, int x2);
-
- Button::Callback _redrawShadedButtonFunctor;
- Button::Callback _redrawButtonFunctor;
-
- virtual Button *getButtonListData() = 0;
- virtual Button *getScrollUpButton() = 0;
- virtual Button *getScrollDownButton() = 0;
-
- virtual Button::Callback getScrollUpButtonHandler() const = 0;
- virtual Button::Callback getScrollDownButtonHandler() const = 0;
-
- virtual uint8 defaultColor1() const = 0;
- virtual uint8 defaultColor2() const = 0;
-
- virtual const char *getMenuTitle(const Menu &menu) = 0;
- virtual const char *getMenuItemTitle(const MenuItem &menuItem) = 0;
- virtual const char *getMenuItemLabel(const MenuItem &menuItem) = 0;
-
- void updateAllMenuButtons();
- void updateMenuButton(Button *button);
- virtual void updateButton(Button *button);
-
- void redrawText(const Menu &menu);
- void redrawHighlight(const Menu &menu);
+ // The engine expects a list of contiguous savegame indices.
+ // Since ScummVM's savegame indices aren't, we re-index them.
+ // The integers stored in _saveSlots are ScummVM savegame indices.
Common::Array<int> _saveSlots;
- void updateSaveList(bool excludeQuickSaves = false);
+ void updateSaveFileList(Common::String targetName, bool excludeQuickSaves = false);
int getNextSavegameSlot();
+ void updateSaveSlotsList(Common::String targetName, bool force = false);
- uint32 _lastScreenUpdate;
- Common::KeyState _keyPressed;
- void checkTextfieldInput();
-};
-
-class Movie;
+ virtual void sortSaveSlots();
-class MainMenu {
-public:
- MainMenu(KyraEngine_v1 *vm);
- virtual ~MainMenu() {}
-
- struct Animation {
- Animation() : anim(0), startFrame(0), endFrame(0), delay(0) {}
-
- Movie *anim;
- int startFrame;
- int endFrame;
- int delay;
- };
-
- struct StaticData {
- const char *strings[5];
-
- uint8 menuTable[7];
- uint8 colorTable[4];
-
- Screen::FontId font;
- uint8 altColor;
- };
-
- void init(StaticData data, Animation anim);
- int handle(int dim);
-private:
- KyraEngine_v1 *_vm;
- Screen *_screen;
- OSystem *_system;
-
- StaticData _static;
- struct AnimIntern {
- int curFrame;
- int direction;
- };
- Animation _anim;
- AnimIntern _animIntern;
-
- uint32 _nextUpdate;
-
- void updateAnimation();
- void draw(int select);
- void drawBox(int x, int y, int w, int h, int fill);
- bool getInput();
+ uint32 _lastScreenUpdate;
+ char **_savegameList;
+ int _savegameListSize;
+ bool _saveSlotsListUpdateNeeded;
- void printString(const char *string, int x, int y, int col1, int col2, int flags, ...) GCC_PRINTF(2, 8);
+ Common::KeyState _keyPressed;
};
-} // end of namesapce Kyra
+} // End of namespace Kyra
#endif
diff --git a/engines/kyra/gui_eob.cpp b/engines/kyra/gui_eob.cpp
new file mode 100644
index 0000000000..e8e69d5b1f
--- /dev/null
+++ b/engines/kyra/gui_eob.cpp
@@ -0,0 +1,4093 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifdef ENABLE_EOB
+
+#include "kyra/eobcommon.h"
+#include "kyra/gui_eob.h"
+#include "kyra/script_eob.h"
+#include "kyra/text_rpg.h"
+#include "kyra/timer.h"
+#include "kyra/util.h"
+
+#include "backends/keymapper/keymapper.h"
+#include "common/system.h"
+#include "common/savefile.h"
+#include "graphics/scaler.h"
+
+namespace Kyra {
+
+Button *EoBCoreEngine::gui_getButton(Button *buttonList, int index) {
+ while (buttonList) {
+ if (buttonList->index == index)
+ return buttonList;
+ buttonList = buttonList->nextButton;
+ }
+
+ return 0;
+}
+
+void EoBCoreEngine::gui_drawPlayField(bool refresh) {
+ _screen->loadEoBBitmap("PLAYFLD", _cgaMappingDeco, 5, 3, 2);
+ int cp = _screen->setCurPage(2);
+ gui_drawCompass(true);
+
+ if (refresh && !_sceneDrawPage2)
+ drawScene(0);
+
+ _screen->setCurPage(cp);
+ _screen->copyRegion(0, 0, 0, 0, 320, 200, 2, 0, Screen::CR_NO_P_CHECK);
+
+ if (!_loading)
+ _screen->updateScreen();
+
+ _screen->loadEoBBitmap("INVENT", _cgaMappingInv, 5, 3, 2);
+}
+
+void EoBCoreEngine::gui_restorePlayField() {
+ loadVcnData(0, (_flags.gameID == GI_EOB1) ? _cgaMappingLevel[_cgaLevelMappingIndex[_currentLevel - 1]] : 0);
+ _screen->_curPage = 0;
+ gui_drawPlayField(true);
+ gui_drawAllCharPortraitsWithStats();
+}
+
+void EoBCoreEngine::gui_drawAllCharPortraitsWithStats() {
+ for (int i = 0; i < 6; i++)
+ gui_drawCharPortraitWithStats(i);
+}
+
+void EoBCoreEngine::gui_drawCharPortraitWithStats(int index) {
+ if (!testCharacter(index, 1))
+ return;
+
+ static const uint16 charPortraitPosX[] = { 8, 80, 184, 256 };
+ static const uint16 charPortraitPosY[] = { 2, 54, 106 };
+
+ EoBCharacter *c = &_characters[index];
+ int txtCol1 = 12;
+ int txtCol2 = 15;
+
+ if ((_flags.gameID == GI_EOB1 && c->flags & 6) || (_flags.gameID == GI_EOB2 && c->flags & 0x0e)) {
+ txtCol1 = 8;
+ txtCol2 = 6;
+ }
+
+ if (_currentControlMode == 0) {
+ int x2 = charPortraitPosX[index & 1];
+ int y2 = charPortraitPosY[index >> 1];
+ Screen::FontId cf = _screen->setFont(Screen::FID_6_FNT);
+
+ _screen->copyRegion(176, 168, x2 , y2, 64, 24, 2, 2, Screen::CR_NO_P_CHECK);
+ _screen->copyRegion(240, 168, x2, y2 + 24, 64, 26, 2, 2, Screen::CR_NO_P_CHECK);
+ int cp = _screen->setCurPage(2);
+
+ if (index == _exchangeCharacterId)
+ _screen->printText(_characterGuiStringsSt[0], x2 + 2, y2 + 2, 8, guiSettings()->colors.fill);
+ else
+ _screen->printText(c->name, x2 + 2, y2 + 2, txtCol1, guiSettings()->colors.fill);
+
+ gui_drawFaceShape(index);
+ gui_drawWeaponSlot(index, 0);
+ gui_drawWeaponSlot(index, 1);
+ gui_drawHitpoints(index);
+
+ if (testCharacter(index, 2))
+ gui_drawCharPortraitStatusFrame(index);
+
+ if (c->damageTaken > 0) {
+ _screen->drawShape(2, _redSplatShape, x2 + 13, y2 + 30, 0);
+ Common::String tmpStr = Common::String::format("%d", c->damageTaken);
+ _screen->printText(tmpStr.c_str(), x2 + 34 - tmpStr.size() * 3, y2 + 42, (_configRenderMode == Common::kRenderCGA) ? 12 : 15, 0);
+ }
+
+ _screen->setCurPage(cp);
+ _screen->setFont(cf);
+
+ if (!cp) {
+ _screen->copyRegion(x2, y2, charPortraitPosX[2 + (index & 1)], y2, 64, 50, 2, 0, Screen::CR_NO_P_CHECK);
+ _screen->updateScreen();
+ }
+ } else if ((_currentControlMode == 1 || _currentControlMode == 2) && index == _updateCharNum) {
+ _screen->copyRegion(176, 0, 0, 0, 144, 168, 2, 2, Screen::CR_NO_P_CHECK);
+ _screen->_curPage = 2;
+ gui_drawFaceShape(index);
+ _screen->printShadedText(c->name, 219, 6, txtCol2, guiSettings()->colors.fill);
+ gui_drawHitpoints(index);
+ gui_drawFoodStatusGraph(index);
+
+ if (_currentControlMode == 1) {
+ if (c->hitPointsCur == -10)
+ _screen->printShadedText(_characterGuiStringsSt[1], 247, 158, 6, guiSettings()->colors.extraFill);
+ else if (c->hitPointsCur < 1)
+ _screen->printShadedText(_characterGuiStringsSt[2], 226, 158, 6, guiSettings()->colors.extraFill);
+ else if (c->effectFlags & (_flags.gameID == GI_EOB1 ? 0x80 : 0x2000))
+ _screen->printShadedText(_characterGuiStringsSt[3], 220, 158, 6, guiSettings()->colors.extraFill);
+ else if (c->flags & 2)
+ _screen->printShadedText(_characterGuiStringsSt[4], 235, 158, 6, guiSettings()->colors.extraFill);
+ else if (c->flags & 4)
+ _screen->printShadedText(_characterGuiStringsSt[5], 232, 158, 6, guiSettings()->colors.extraFill);
+ else if (c->flags & 8)
+ _screen->printShadedText(_characterGuiStringsSt[6], 232, 158, 6, guiSettings()->colors.extraFill);
+
+ for (int i = 0; i < 27; i++)
+ gui_drawInventoryItem(i, 0, 2);
+ gui_drawInventoryItem(16, 1, 2);
+
+ } else {
+ static const uint16 cm2X1[] = { 179, 272, 301 };
+ static const uint16 cm2Y1[] = { 36, 51, 51 };
+ static const uint16 cm2X2[] = { 271, 300, 318 };
+ static const uint16 cm2Y2[] = { 165, 165, 147 };
+
+ for (int i = 0; i < 3; i++)
+ _screen->fillRect(cm2X1[i], cm2Y1[i], cm2X2[i], cm2Y2[i], guiSettings()->colors.extraFill);
+
+ _screen->printShadedText(_characterGuiStringsIn[0], 183, 42, 15, guiSettings()->colors.extraFill);
+ _screen->printText(_chargenClassStrings[c->cClass], 183, 55, 12, guiSettings()->colors.extraFill);
+ _screen->printText(_chargenAlignmentStrings[c->alignment], 183, 62, 12, guiSettings()->colors.extraFill);
+ _screen->printText(_chargenRaceSexStrings[c->raceSex], 183, 69, 12, guiSettings()->colors.extraFill);
+
+ for (int i = 0; i < 6; i++)
+ _screen->printText(_chargenStatStrings[6 + i], 183, 82 + i * 7, 12, guiSettings()->colors.extraFill);
+
+ _screen->printText(_characterGuiStringsIn[1], 183, 124, 12, guiSettings()->colors.extraFill);
+ _screen->printText(_characterGuiStringsIn[2], 239, 138, 12, guiSettings()->colors.extraFill);
+ _screen->printText(_characterGuiStringsIn[3], 278, 138, 12, guiSettings()->colors.extraFill);
+
+ _screen->printText(getCharStrength(c->strengthCur, c->strengthExtCur).c_str(), 275, 82, 15, guiSettings()->colors.extraFill);
+ _screen->printText(Common::String::format("%d", c->intelligenceCur).c_str(), 275, 89, 15, guiSettings()->colors.extraFill);
+ _screen->printText(Common::String::format("%d", c->wisdomCur).c_str(), 275, 96, 15, guiSettings()->colors.extraFill);
+ _screen->printText(Common::String::format("%d", c->dexterityCur).c_str(), 275, 103, 15, guiSettings()->colors.extraFill);
+ _screen->printText(Common::String::format("%d", c->constitutionCur).c_str(), 275, 110, 15, guiSettings()->colors.extraFill);
+ _screen->printText(Common::String::format("%d", c->charismaCur).c_str(), 275, 117, 15, guiSettings()->colors.extraFill);
+ _screen->printText(Common::String::format("%d", c->armorClass).c_str(), 275, 124, 15, guiSettings()->colors.extraFill);
+
+ for (int i = 0; i < 3; i++) {
+ int t = getCharacterClassType(c->cClass, i);
+ if (t == -1)
+ continue;
+
+ _screen->printText(_chargenClassStrings[t + 15], 180, 145 + 7 * i, 12, guiSettings()->colors.extraFill);
+ Common::String tmpStr = Common::String::format("%d", c->experience[i]);
+ _screen->printText(tmpStr.c_str(), 251 - tmpStr.size() * 3, 145 + 7 * i, 15, guiSettings()->colors.extraFill);
+ tmpStr = Common::String::format("%d", c->level[i]);
+ _screen->printText(tmpStr.c_str(), 286 - tmpStr.size() * 3, 145 + 7 * i, 15, guiSettings()->colors.extraFill);
+ }
+ }
+
+ _screen->_curPage = 0;
+ _screen->copyRegion(176, 0, 176, 0, 144, 168, 2, 0, Screen::CR_NO_P_CHECK);
+ _screen->copyRegion(0, 0, 176, 0, 144, 168, 2, 2, Screen::CR_NO_P_CHECK);
+ _screen->updateScreen();
+ }
+}
+
+void EoBCoreEngine::gui_drawFaceShape(int index) {
+ if (!testCharacter(index, 1))
+ return;
+
+ static const uint8 xCoords[] = { 8, 80 };
+ static const uint8 yCoords[] = { 11, 63, 115 };
+
+ int x = xCoords[index & 1];
+ int y = yCoords[index >> 1];
+
+ if (!_screen->_curPage)
+ x += 176;
+
+ if (_currentControlMode) {
+ if (_updateCharNum != index)
+ return;
+
+ x = 181;
+ y = 3;
+ }
+
+ EoBCharacter *c = &_characters[index];
+
+ if (c->hitPointsCur == -10) {
+ _screen->drawShape(_screen->_curPage, _deadCharShape, x, y, 0);
+ return;
+ }
+
+ if (_flags.gameID == GI_EOB1) {
+ if (c->effectFlags & 4) {
+ _screen->fillRect(x, y, x + 31, y + 31, 12);
+ return;
+ }
+ } else {
+ if (c->effectFlags & 0x140) {
+ _screen->setFadeTableIndex(1);
+ _screen->setShapeFadeMode(1, true);
+ }
+
+ if (c->flags & 2) {
+ _screen->setFadeTableIndex(0);
+ _screen->setShapeFadeMode(1, true);
+ }
+
+ if (c->flags & 8) {
+ _screen->setFadeTableIndex(2);
+ _screen->setShapeFadeMode(1, true);
+ }
+ }
+
+ _screen->drawShape(_screen->_curPage, c->faceShape, x, y, 0);
+
+ if (c->hitPointsCur < 1)
+ _screen->drawShape(_screen->_curPage, _disabledCharGrid, x, y, 0);
+
+ _screen->setFadeTableIndex(4);
+ _screen->setShapeFadeMode(1, false);
+}
+
+void EoBCoreEngine::gui_drawWeaponSlot(int charIndex, int slot) {
+ static const uint8 xCoords[] = { 40, 112 };
+ static const uint8 yCoords[] = { 11, 27, 63, 79, 115, 131 };
+
+ int x = xCoords[charIndex & 1];
+ int y = yCoords[(charIndex & 6) + slot];
+
+ if (!_screen->_curPage)
+ x += 176;
+
+ int itm = _characters[charIndex].inventory[slot];
+ gui_drawBox(x, y, 31, 16, guiSettings()->colors.frame1, guiSettings()->colors.frame2, guiSettings()->colors.fill);
+
+ if (_characters[charIndex].slotStatus[slot]) {
+ gui_drawWeaponSlotStatus(x, y, _characters[charIndex].slotStatus[slot]);
+ return;
+ }
+
+ if (itm)
+ drawItemIconShape(_screen->_curPage, itm, x + 8, y);
+ else if (!slot && _flags.gameID == GI_EOB2 && checkScriptFlags(0x80000000))
+ _screen->drawShape(_screen->_curPage, _itemIconShapes[103], x + 8, y, 0);
+ else
+ _screen->drawShape(_screen->_curPage, _itemIconShapes[85 + slot], x + 8, y, 0);
+
+ if ((_characters[charIndex].disabledSlots & (1 << slot)) || !validateWeaponSlotItem(charIndex, slot) || (_characters[charIndex].hitPointsCur <= 0) || (_characters[charIndex].flags & 0x0c))
+ _screen->drawShape(_screen->_curPage, _weaponSlotGrid, x, y, 0);
+}
+
+void EoBCoreEngine::gui_drawWeaponSlotStatus(int x, int y, int status) {
+ Common::String tmpStr;
+ Common::String tmpStr2;
+
+ if (status > -3 || status == -5)
+ _screen->drawShape(_screen->_curPage, _greenSplatShape, x - 1, y, 0);
+ else
+ gui_drawBox(x, y, 31, 16, guiSettings()->colors.warningFrame1, guiSettings()->colors.warningFrame2, guiSettings()->colors.warningFill);
+
+ switch (status + 5) {
+ case 0:
+ tmpStr = _characterGuiStringsWp[2];
+ break;
+ case 1:
+ tmpStr = _characterGuiStringsWr[2];
+ tmpStr2 = _characterGuiStringsWr[3];
+ break;
+ case 2:
+ tmpStr = _characterGuiStringsWr[0];
+ tmpStr2 = _characterGuiStringsWr[1];
+ break;
+ case 3:
+ tmpStr = _characterGuiStringsWp[1];
+ break;
+ case 4:
+ tmpStr = _characterGuiStringsWp[0];
+ break;
+ default:
+ tmpStr = Common::String::format("%d", status);
+ break;
+ }
+
+ int textColor= (_configRenderMode == Common::kRenderCGA) ? 2 : 15;
+
+ if (!tmpStr2.empty()) {
+ _screen->printText(tmpStr.c_str(), x + (16 - tmpStr.size() * 3), y + 2, textColor, 0);
+ _screen->printText(tmpStr2.c_str(), x + (16 - tmpStr.size() * 3), y + 9, textColor, 0);
+ } else {
+ _screen->printText(tmpStr.c_str(), x + (16 - tmpStr.size() * 3), y + 5, textColor, 0);
+ }
+}
+
+void EoBCoreEngine::gui_drawHitpoints(int index) {
+ if (!testCharacter(index, 1))
+ return;
+
+ if (_currentControlMode && (index != _updateCharNum))
+ return;
+
+ static const uint8 xCoords[] = { 23, 95 };
+ static const uint8 yCoords[] = { 46, 98, 150 };
+ static const uint8 barColor[] = { 3, 5, 8 };
+
+ int x = xCoords[index & 1];
+ int y = yCoords[index >> 1];
+ int w = 38;
+ int h = 3;
+
+ if (!_screen->_curPage)
+ x += 176;
+
+ if (_currentControlMode) {
+ x = 250;
+ y = 16;
+ w = 51;
+ h = 5;
+ }
+
+ EoBCharacter *c = &_characters[index];
+
+ if (_configHpBarGraphs) {
+ int bgCur = c->hitPointsCur + 10;
+ int bgMax = c->hitPointsMax + 10;
+ int col = ((bgMax / 3) > bgCur) ? 1 : 0;
+ if (bgCur <= 10)
+ col = 2;
+
+ if (!_currentControlMode)
+ _screen->printText(_characterGuiStringsHp[0], x - 13, y - 1, 12, 0);
+
+
+ gui_drawHorizontalBarGraph(x, y, w, h, bgCur, bgMax, barColor[col], guiSettings()->colors.barGraph);
+
+ } else {
+ Common::String tmpString = Common::String::format(_characterGuiStringsHp[1], c->hitPointsCur, c->hitPointsMax);
+
+ if (!_currentControlMode) {
+ x -= 13;
+ y -= 1;
+ }
+
+ _screen->printText(tmpString.c_str(), x, y, 12, guiSettings()->colors.fill);
+ }
+}
+
+void EoBCoreEngine::gui_drawFoodStatusGraph(int index) {
+ if (!_currentControlMode)
+ return;
+
+ if (!testCharacter(index, 1))
+ return;
+
+ EoBCharacter *c = &_characters[index];
+ if (!(c->flags & 1))
+ return;
+
+ if (index != _updateCharNum)
+ return;
+
+ uint8 col = c->food < 20 ? 8 : (c->food < 33 ? 5 : 3);
+ gui_drawHorizontalBarGraph(250, 25, 51, 5, c->food, 100, col, guiSettings()->colors.barGraph);
+}
+
+void EoBCoreEngine::gui_drawHorizontalBarGraph(int x, int y, int w, int h, int32 curVal, int32 maxVal, int col1, int col2) {
+ gui_drawBox(x - 1, y - 1, w + 3, h + 2, guiSettings()->colors.frame2, guiSettings()->colors.frame1, -1);
+ KyraRpgEngine::gui_drawHorizontalBarGraph(x, y, w + 2, h, curVal, maxVal, col1, col2);
+}
+
+void EoBCoreEngine::gui_drawCharPortraitStatusFrame(int index) {
+ uint8 redGreenColor = (_partyEffectFlags & 0x20000) ? 4 : ((_configRenderMode == Common::kRenderCGA) ? 3 : 6);
+
+ static const uint8 xCoords[] = { 8, 80 };
+ static const uint8 yCoords[] = { 2, 54, 106 };
+ int x = xCoords[index & 1];
+ int y = yCoords[index >> 1];
+ int xOffset = (_configRenderMode == Common::kRenderCGA) ? 0 : 1;
+
+ if (!_screen->_curPage)
+ x += 176;
+
+ EoBCharacter *c = &_characters[index];
+
+ bool redGreen = ((c->effectFlags & 0x4818) || (_partyEffectFlags & 0x20000) || c->effectsRemainder[0] || c->effectsRemainder[1]) ? true : false;
+ bool yellow = ((c->effectFlags & 0x13000) || (_partyEffectFlags & 0x8420)) ? true : false;
+
+ if (redGreen || yellow) {
+ if (redGreen && !yellow) {
+ _screen->drawBox(x, y, x + 63, y + 49, redGreenColor);
+ return;
+ }
+
+ if (yellow && !redGreen) {
+ _screen->drawBox(x, y, x + 63, y + 49, 5);
+ return;
+ }
+
+ int iX = x;
+ int iY = y;
+
+ for (int i = 0; i < 64; i += 16) {
+ x = iX + i;
+ if (redGreen) {
+ _screen->drawClippedLine(x, y, x + 7, y, redGreenColor);
+ _screen->drawClippedLine(x + 8, y + 49, x + 15, y + 49, redGreenColor);
+ }
+ if (yellow) {
+ _screen->drawClippedLine(x + 8, y, x + 15, y, 5);
+ _screen->drawClippedLine(x, y + 49, x + 7, y + 49, 5);
+ }
+ }
+
+ x = iX;
+
+ for (int i = 1; i < 48; i += 12) {
+ y = iY + i - 1;
+
+ if (yellow) {
+ _screen->drawClippedLine(x, y + 1, x, y + 6, 5);
+ _screen->drawClippedLine(x + 63, y + 7, x + 63, y + 12, 5);
+ }
+ if (redGreen) {
+ _screen->drawClippedLine(x, y + 7, x, y + 12, redGreenColor);
+ _screen->drawClippedLine(x + 63, y + 1, x + 63, y + 6, redGreenColor);
+ }
+ }
+
+ } else {
+ _screen->drawClippedLine(x, y, x + 62, y, guiSettings()->colors.frame2);
+ _screen->drawClippedLine(x, y + 49, x + 62, y + 49, guiSettings()->colors.frame1);
+ _screen->drawClippedLine(x - xOffset, y, x - xOffset, y + 50, 12);
+ _screen->drawClippedLine(x + 63, y, x + 63, y + 50, 12);
+ }
+}
+
+void EoBCoreEngine::gui_drawInventoryItem(int slot, int special, int pageNum) {
+ int x = _inventorySlotsX[slot];
+ int y = _inventorySlotsY[slot];
+
+ int item = _characters[_updateCharNum].inventory[slot];
+ int cp = _screen->setCurPage(pageNum);
+
+ if (special) {
+ int wh = (slot == 25 || slot == 26) ? 10 : 18;
+
+ uint8 col1 = guiSettings()->colors.frame1;
+ uint8 col2 = guiSettings()->colors.frame2;
+ if (_configRenderMode == Common::kRenderCGA ) {
+ col1 = 1;
+ col2 = 3;
+ }
+
+ gui_drawBox(x - 1, y - 1, wh, wh, col1, col2, slot == 16 ? -1 : guiSettings()->colors.fill);
+
+ if (slot == 16) {
+ _screen->fillRect(227, 65, 238, 69, 12);
+ int cnt = countQueuedItems(_characters[_updateCharNum].inventory[slot], -1, -1, 1, 1);
+ x = cnt >= 10 ? 227 : 233;
+ Common::String str = Common::String::format("%d", cnt);
+ _screen->printText(str.c_str(), x, 65, 15, 0);
+ }
+ }
+
+ if (slot != 16 && item) {
+ if (slot == 25 || slot == 26) {
+ x -= 4;
+ y -= 4;
+ }
+ drawItemIconShape(pageNum, item, x, y);
+ }
+ _screen->_curPage = cp;
+ _screen->updateScreen();
+}
+
+void EoBCoreEngine::gui_drawCompass(bool force) {
+ if (_currentDirection == _compassDirection && !force)
+ return;
+
+ static const uint8 shpX[2][3] = { { 0x70, 0x4D, 0x95 }, { 0x72, 0x4F, 0x97 } };
+ static const uint8 shpY[2][3] = { { 0x7F, 0x9A, 0x9A }, { 0x83, 0x9E, 0x9E } };
+ int g = _flags.gameID == GI_EOB1 ? 0 : 1;
+
+ for (int i = 0; i < 3; i++)
+ _screen->drawShape(_screen->_curPage, _compassShapes[(i << 2) + _currentDirection], shpX[g][i], shpY[g][i], 0);
+
+ _compassDirection = _currentDirection;
+}
+
+void EoBCoreEngine::gui_drawDialogueBox() {
+ gui_drawBox(0, 121, 320, 79, guiSettings()->colors.frame1, guiSettings()->colors.frame2, guiSettings()->colors.fill);
+ txt()->clearCurDim();
+}
+
+void EoBCoreEngine::gui_drawSpellbook() {
+ _screen->setCurPage(2);
+ int numTab = (_flags.gameID == GI_EOB1) ? 5 : 6;
+ _screen->copyRegion(64, 121, 64, 121, 112, 56, 0, 2, Screen::CR_NO_P_CHECK);
+
+ for (int i = 0; i < numTab; i++) {
+ int col1 = 0;
+ int col2 = 1;
+ int col3 = 2;
+
+ if (_configRenderMode == Common::kRenderCGA) {
+ if (i == _openBookSpellLevel) {
+ col1 = 1;
+ col2 = 2;
+ col3 = 3;
+ }
+ } else {
+ col1 = guiSettings()->colors.inactiveTabFrame1;
+ col2 = guiSettings()->colors.inactiveTabFrame2;
+ col3 = guiSettings()->colors.inactiveTabFill;
+
+ if (i == _openBookSpellLevel) {
+ col1 = guiSettings()->colors.frame1;
+ col2 = guiSettings()->colors.frame2;
+ col3 = guiSettings()->colors.fill;
+ }
+ }
+
+ if (_flags.gameID == GI_EOB1) {
+ gui_drawBox(i * 21 + 71, 122, 21, 9, col1, col2, col3);
+ _screen->printText(_magicStrings7[i], i * 21 + 73, 123, 12, 0);
+ } else {
+ gui_drawBox(i * 18 + 68, 121, 18, 9, col1, col2, col3);
+ _screen->printText(Common::String::format("%d", i + 1).c_str(), i * 18 + 75, 123, 12, 0);
+ }
+ }
+
+ if (_flags.gameID == GI_EOB1)
+ gui_drawBox(71, 131, 105, 44, guiSettings()->colors.frame1, guiSettings()->colors.frame2, guiSettings()->colors.fill);
+ else {
+ gui_drawBox(68, 130, 108, 47, guiSettings()->colors.frame1, guiSettings()->colors.frame2, guiSettings()->colors.fill);
+ gui_drawBox(68, 168, 78, 9, guiSettings()->colors.extraFrame1, guiSettings()->colors.extraFrame2, guiSettings()->colors.extraFill);
+ gui_drawBox(146, 168, 14, 9, guiSettings()->colors.extraFrame1, guiSettings()->colors.extraFrame2, guiSettings()->colors.extraFill);
+ gui_drawBox(160, 168, 16, 9, guiSettings()->colors.extraFrame1, guiSettings()->colors.extraFrame2, guiSettings()->colors.extraFill);
+ gui_drawSpellbookScrollArrow(150, 169, 0);
+ gui_drawSpellbookScrollArrow(165, 169, 1);
+ }
+
+ int textCol1 = (_configRenderMode == Common::kRenderCGA) ? 3 : 15;
+ int textCol2 = 8;
+ int textXa = 74;
+ int textXs = 71;
+ int textY = 170;
+ int col3 = (_configRenderMode == Common::kRenderCGA) ? 2 : guiSettings()->colors.fill;
+ int col4 = guiSettings()->colors.extraFill;
+ int col5 = 12;
+
+ if (_flags.gameID == GI_EOB1) {
+ textCol2 = (_configRenderMode == Common::kRenderCGA) ? 12 : 11;
+ textXa = textXs = 73;
+ textY = 168;
+ col4 = col3;
+ col5 = textCol1;
+ }
+
+ for (int i = 0; i < 7; i++) {
+ int d = _openBookAvailableSpells[_openBookSpellLevel * 10 + _openBookSpellListOffset + i];
+ if (_openBookSpellSelectedItem == i) {
+ if (d >= 0 && i < 6 && (i + _openBookSpellListOffset) < 9) {
+ _screen->printText(_openBookSpellList[d], textXs, 132 + 6 * i, textCol1, textCol2);
+ } else if (i == 6) {
+ if (_flags.gameID == GI_EOB2)
+ _screen->fillRect(69, 169, 144, 175, textCol2);
+ _screen->printText(_magicStrings1[0], textXa, textY, textCol1, textCol2);
+ }
+ } else {
+ if (d >= 0 && i < 6 && (i + _openBookSpellListOffset) < 9)
+ _screen->printText(_openBookSpellList[d], textXs, 132 + 6 * i, textCol1, col3);
+ else
+ _screen->printText(_magicStrings1[0], textXa, textY, col5, col4);
+ }
+ }
+
+ if (_characters[_openBookChar].disabledSlots & 4) {
+ static const uint8 xpos[] = { 0x44, 0x62, 0x80, 0x90 };
+ static const uint8 ypos[] = { 0x82, 0x92, 0x98 };
+ for (int yc = 0; yc < 3; yc++) {
+ for (int xc = 0; xc < 4; xc++)
+ _screen->drawShape(_screen->_curPage, _weaponSlotGrid, xpos[xc], ypos[yc], 0);
+ }
+ }
+
+ if (_openBookAvailableSpells[_openBookSpellLevel * 10 + 6] <= 0)
+ _screen->drawShape(2, _blackBoxWideGrid, 146, 168, 0);
+
+ _screen->setCurPage(0);
+ _screen->copyRegion(64, 121, 64, 121, 112, 56, 2, 0, Screen::CR_NO_P_CHECK);
+ if (!_loading)
+ _screen->updateScreen();
+}
+
+void EoBCoreEngine::gui_drawSpellbookScrollArrow(int x, int y, int direction) {
+ static const uint8 x1[] = { 0, 2, 1, 0, 2, 2 };
+ static const uint8 x2[] = { 2, 4, 5, 6, 4, 4 };
+ if (direction) {
+ _screen->setPagePixel(_screen->_curPage, x + 3, y + 5, 12);
+ for (int i = 1; i < 6; i++)
+ _screen->drawClippedLine(x + x1[i], (5 - i) + y, x + x2[i], (5 - i) + y, 12);
+ } else {
+ _screen->setPagePixel(_screen->_curPage, x + 3, y, 12);
+ for (int i = 1; i < 6; i++)
+ _screen->drawClippedLine(x + x1[i], y + i, x + x2[i], y + i, 12);
+ }
+}
+
+void EoBCoreEngine::gui_updateSlotAfterScrollUse() {
+ _characters[_openBookChar].disabledSlots ^= (1 << (--_castScrollSlot));
+ setCharEventTimer(_openBookChar, 18, _castScrollSlot + 2, 1);
+ gui_drawCharPortraitWithStats(_openBookChar);
+ _openBookChar = _openBookCharBackup;
+ _openBookType = _openBookTypeBackup;
+ _castScrollSlot = 0;
+ gui_toggleButtons();
+}
+
+void EoBCoreEngine::gui_updateControls() {
+ Button b;
+ if (_currentControlMode)
+ clickedPortraitRestore(&b);
+ if (_updateFlags)
+ clickedSpellbookAbort(&b);
+}
+
+void EoBCoreEngine::gui_toggleButtons() {
+ if (_currentControlMode == 0)
+ gui_setPlayFieldButtons();
+ else if (_currentControlMode == 1)
+ gui_setInventoryButtons();
+ else if (_currentControlMode == 2)
+ gui_setStatsListButtons();
+}
+
+void EoBCoreEngine::gui_setPlayFieldButtons() {
+ gui_resetButtonList();
+ gui_initButtonsFromList(_updateFlags ? _buttonList2 : _buttonList1);
+}
+
+void EoBCoreEngine::gui_setInventoryButtons() {
+ gui_resetButtonList();
+ gui_initButtonsFromList(_updateFlags ? _buttonList5 : _buttonList3);
+}
+
+void EoBCoreEngine::gui_setStatsListButtons() {
+ gui_resetButtonList();
+ gui_initButtonsFromList(_updateFlags ? _buttonList6 : _buttonList4);
+}
+
+void EoBCoreEngine::gui_setSwapCharacterButtons() {
+ gui_resetButtonList();
+ gui_initButtonsFromList(_buttonList7);
+}
+
+void EoBCoreEngine::gui_setCastOnWhomButtons() {
+ gui_resetButtonList();
+ gui_initButtonsFromList(_buttonList8);
+}
+
+void EoBCoreEngine::gui_initButton(int index, int, int, int) {
+ Button *b = 0;
+ int cnt = 1;
+
+ if (_flags.gameID == GI_EOB1 && index > 92)
+ return;
+
+ if (_activeButtons) {
+ Button *n = _activeButtons;
+ while (n->nextButton) {
+ ++cnt;
+ n = n->nextButton;
+ }
+
+ ++cnt;
+ b = n->nextButton = &_activeButtonData[cnt];
+ } else {
+ b = &_activeButtonData[0];
+ _activeButtons = b;
+ }
+
+ *b = Button();
+ b->data0Val2 = 12;
+ b->data1Val2 = b->data2Val2 = 15;
+ b->data3Val2 = 8;
+
+ b->index = index + 1;
+
+ const EoBGuiButtonDef *d = &_buttonDefs[index];
+ b->buttonCallback = _buttonCallbacks[index];
+
+ if (_flags.gameID == GI_EOB1) {
+ // EOB1 spellbook modifications
+ if (index > 60 && index < 66) {
+ d = &_buttonDefs[index + 34];
+ b->buttonCallback = _buttonCallbacks[index + 34];
+ } else if (index == 88) {
+ d = &_buttonDefs[index + 12];
+ b->buttonCallback = _buttonCallbacks[index + 12];
+ }
+ }
+
+ b->x = d->x;
+ b->y = d->y;
+ b->width = d->w;
+ b->height = d->h;
+
+ // EOB1 spellbook modifications
+ if (_flags.gameID == GI_EOB1 && ((index > 66 && index < 73) || (index > 76 && index < 79)))
+ b->y++;
+
+ b->flags = d->flags;
+ b->keyCode = d->keyCode;
+ b->keyCode2 = d->keyCode2;
+ b->arg = d->arg;
+}
+
+int EoBCoreEngine::clickedCharPortraitDefault(Button *button) {
+ if (!testCharacter(button->arg, 1))
+ return 1;
+
+ gui_processCharPortraitClick(button->arg);
+ return 0;
+}
+
+int EoBCoreEngine::clickedCamp(Button *button) {
+ gui_updateControls();
+ disableSysTimer(2);
+ int cd = _screen->curDimIndex();
+
+ for (int i = 0; i < 6; i++) {
+ if (!testCharacter(i, 1))
+ continue;
+ _characters[i].damageTaken = 0;
+ _characters[i].slotStatus[0] = _characters[i].slotStatus[1] = 0;
+ gui_drawCharPortraitWithStats(i);
+ }
+
+ _screen->copyPage(0, 7);
+ _screen->copyRegion(0, 120, 0, 0, 176, 24, 0, _useHiResDithering ? 1 : 12, Screen::CR_NO_P_CHECK);
+
+ _gui->runCampMenu();
+
+ _screen->copyRegion(0, 0, 0, 120, 176, 24, _useHiResDithering ? 1 : 12, 2, Screen::CR_NO_P_CHECK);
+ _screen->setScreenDim(cd);
+ drawScene(0);
+
+ for (int i = 0; i < 6; i++)
+ sortCharacterSpellList(i);
+
+ _screen->setCurPage(0);
+ const ScreenDim *dm = _screen->getScreenDim(10);
+ _screen->copyRegion(dm->sx << 3, dm->sy, dm->sx << 3, dm->sy, dm->w << 3, dm->h, 2, 0, Screen::CR_NO_P_CHECK);
+
+ _screen->updateScreen();
+
+ enableSysTimer(2);
+ advanceTimers(_restPartyElapsedTime);
+ _restPartyElapsedTime = 0;
+
+ checkPartyStatus(true);
+
+ return button->arg;
+}
+
+int EoBCoreEngine::clickedSceneDropPickupItem(Button *button) {
+ uint16 block = _currentBlock;
+ if (button->arg > 1) {
+ block = calcNewBlockPosition(_currentBlock, _currentDirection);
+ int f = _wllWallFlags[_levelBlockProperties[block].walls[_sceneDrawVarDown]];
+ if (!(f & 0x0b))
+ return 1;
+ }
+ int d = _dropItemDirIndex[(_currentDirection << 2) + button->arg];
+
+ if (_itemInHand) {
+ setItemPosition((Item *)&_levelBlockProperties[block & 0x3ff].drawObjects, block, _itemInHand, d);
+ setHandItem(0);
+ runLevelScript(block, 4);
+ } else {
+ d = getQueuedItem((Item *)&_levelBlockProperties[block].drawObjects, d, -1);
+ if (!d)
+ return 1;
+ setHandItem(d);
+ runLevelScript(block, 8);
+ }
+
+ _sceneUpdateRequired = true;
+ return 1;
+}
+
+int EoBCoreEngine::clickedCharPortrait2(Button *button) {
+ if (!_gui->_progress) {
+ if (!testCharacter(button->arg, 1))
+ return button->index;
+ }
+
+ _currentControlMode = 1;
+ if (!_gui->_progress)
+ _updateCharNum = button->arg;
+
+ _screen->copyRegion(176, 0, 0, 0, 144, 168, 0, 5, Screen::CR_NO_P_CHECK);
+ gui_drawCharPortraitWithStats(_updateCharNum);
+ gui_setInventoryButtons();
+
+ return button->index;
+}
+
+int EoBCoreEngine::clickedWeaponSlot(Button *button) {
+ if (!testCharacter(button->arg, 1))
+ return 1;
+
+ // Fix this using the coordinates from gui_drawWeaponSlot().
+ // The coordinates used in the original are slightly wrong
+ // (most noticeable for characters 5 and 6).
+ static const uint8 sY[] = { 27, 27, 79, 79, 131, 131 };
+ int slot = sY[button->arg] > _mouseY ? 0 : 1;
+
+ if ((_gui->_flagsMouseLeft & 0x7f) == 1)
+ gui_processWeaponSlotClickLeft(button->arg, slot);
+ else
+ gui_processWeaponSlotClickRight(button->arg, slot);
+
+ return 1;
+}
+
+int EoBCoreEngine::clickedCharNameLabelRight(Button *button) {
+ if (!testCharacter(button->arg, 1))
+ return button->index;
+
+ if (_updateFlags) {
+ Button b;
+ clickedSpellbookAbort(&b);
+ }
+
+ if (_exchangeCharacterId == -1) {
+ _exchangeCharacterId = button->arg;
+ gui_setSwapCharacterButtons();
+ gui_drawCharPortraitWithStats(_exchangeCharacterId);
+ enableTimer(0);
+ } else {
+ int d = _exchangeCharacterId;
+ _exchangeCharacterId = -1;
+ exchangeCharacters(d, button->arg);
+
+ _timer->disable(0);
+ gui_drawCharPortraitWithStats(d);
+ gui_processCharPortraitClick(button->arg);
+ gui_drawCharPortraitWithStats(button->arg);
+ gui_setPlayFieldButtons();
+ setupCharacterTimers();
+ }
+
+ return button->index;
+}
+
+int EoBCoreEngine::clickedInventorySlot(Button *button) {
+ gui_processInventorySlotClick(button->arg);
+ return button->index;
+}
+
+int EoBCoreEngine::clickedEatItem(Button *button) {
+ eatItemInHand(_updateCharNum);
+ return button->index;
+}
+
+int EoBCoreEngine::clickedInventoryPrevChar(Button *button) {
+ if (_gui->_progress == 1)
+ _updateCharNum = 0;
+ else if (_gui->_progress == 2)
+ _updateCharNum = 1;
+ else
+ _updateCharNum = getNextValidCharIndex(_updateCharNum, -1);
+
+ gui_drawCharPortraitWithStats(_updateCharNum);
+ return button->index;
+}
+
+int EoBCoreEngine::clickedInventoryNextChar(Button *button) {
+ int oldVal = _updateCharNum;
+ int v = button->arg == 2 ? 2 : 0;
+
+ if (_gui->_progress == 1)
+ _updateCharNum = v + 2;
+ else if (_gui->_progress == 2)
+ _updateCharNum = v + 3;
+ else
+ _updateCharNum = getNextValidCharIndex(_updateCharNum, 1);
+
+ if (!testCharacter(_updateCharNum, 1)) {
+ _updateCharNum = oldVal;
+ return 1;
+ }
+
+ gui_drawCharPortraitWithStats(_updateCharNum);
+ return button->index;
+}
+
+int EoBCoreEngine::clickedSpellbookTab(Button *button) {
+ _openBookSpellLevel = button->arg;
+ _openBookSpellListOffset = 0;
+
+ for (_openBookSpellSelectedItem = 0; _openBookSpellSelectedItem < 6; _openBookSpellSelectedItem++) {
+ if (_openBookAvailableSpells[_openBookSpellLevel * 10 + _openBookSpellSelectedItem] > 0)
+ break;
+ }
+
+ gui_drawSpellbook();
+
+ _characters[_openBookChar].slotStatus[3] = _openBookSpellLevel;
+ _characters[_openBookChar].slotStatus[2] = _openBookSpellSelectedItem;
+ _characters[_openBookChar].slotStatus[4] = _openBookSpellListOffset;
+
+ return button->index;
+}
+
+int EoBCoreEngine::clickedSpellbookList(Button *button) {
+ int listIndex = button->arg;
+ bool spellLevelAvailable = false;
+
+ if (listIndex == 6) {
+ for (int i = 0; i < 10; i++) {
+ if (_openBookAvailableSpells[_openBookSpellLevel * 10 + i] > 0) {
+ spellLevelAvailable = true;
+ break;
+ }
+ }
+ if (!spellLevelAvailable)
+ return button->index;
+
+ int v = (_gui->_progress == 1) ? -1 : ((_gui->_progress == 2) ? 1 : 0);
+
+ _openBookSpellSelectedItem += _openBookSpellListOffset;
+ if (_openBookSpellSelectedItem == 12 || (_openBookSpellSelectedItem == 6 && _openBookSpellListOffset == 0))
+ _openBookSpellSelectedItem = 9;
+
+ do {
+ _openBookSpellSelectedItem += v;
+ int s = (_openBookSpellSelectedItem >= 0) ? _openBookSpellSelectedItem : 9;
+ _openBookSpellSelectedItem = (s <= 9) ? s : 0;
+ } while (_openBookAvailableSpells[_openBookSpellLevel * 10 + _openBookSpellSelectedItem] <= 0 && _openBookSpellSelectedItem != 9);
+
+ if (_openBookSpellSelectedItem >= 6) {
+ _openBookSpellListOffset = 6;
+ if (_openBookSpellSelectedItem == 9)
+ _openBookSpellSelectedItem = 6;
+ else
+ _openBookSpellSelectedItem -= 6;
+ } else {
+ _openBookSpellListOffset = 0;
+ }
+
+ if (_openBookSpellListOffset == 6 && _openBookAvailableSpells[_openBookSpellLevel * 10 + 6] <= 0)
+ _openBookSpellListOffset = 0;
+
+ gui_drawSpellbook();
+
+ } else {
+ if (listIndex == 7 || _openBookAvailableSpells[_openBookSpellLevel * 10 + _openBookSpellListOffset + listIndex] > 0) {
+ if (listIndex < 6) {
+ if (_openBookSpellListOffset + listIndex < 9)
+ _openBookSpellSelectedItem = listIndex;
+ else if (listIndex != 7)
+ return button->index;
+ } else if (listIndex != 7) {
+ return button->index;
+ }
+
+ if (_openBookSpellSelectedItem < 6 && ((_openBookSpellSelectedItem + _openBookSpellListOffset) < 9)) {
+ if (_characters[_openBookChar].disabledSlots & 4)
+ return button->index;
+
+ gui_drawSpellbook();
+
+ int s = _openBookAvailableSpells[_openBookSpellLevel * 10 + _openBookSpellListOffset + _openBookSpellSelectedItem];
+ if (_openBookType == 1)
+ s += _clericSpellOffset;
+
+ castSpell(s, 0);
+
+ } else if ((_openBookSpellSelectedItem == 6 && listIndex == 7) || (_openBookSpellSelectedItem != 6 && listIndex == 6)) {
+ Button b;
+ clickedSpellbookAbort(&b);
+ }
+ }
+ }
+
+ _characters[_openBookChar].slotStatus[2] = _openBookSpellSelectedItem;
+ _characters[_openBookChar].slotStatus[4] = _openBookSpellListOffset;
+ return button->index;
+}
+
+int EoBCoreEngine::clickedCastSpellOnCharacter(Button *button) {
+ _activeSpellCharId = button->arg & 0xff;
+
+ if (_activeSpellCharId == 0xff) {
+ printWarning(_magicStrings3[_flags.gameID == GI_EOB1 ? 2 : 1]);
+ if (_castScrollSlot) {
+ gui_updateSlotAfterScrollUse();
+ } else {
+ gui_toggleButtons();
+ gui_drawSpellbook();
+ }
+ } else {
+ if (_characters[_activeSpellCharId].flags & 1)
+ startSpell(_activeSpell);
+ }
+
+ return button->index;
+}
+
+int EoBCoreEngine::clickedInventoryNextPage(Button *button) {
+ if (_currentControlMode == 2) {
+ gui_setInventoryButtons();
+ _currentControlMode = 1;
+ } else {
+ gui_setStatsListButtons();
+ _currentControlMode = 2;
+ }
+
+ gui_drawCharPortraitWithStats(_updateCharNum);
+ return button->index;
+}
+
+int EoBCoreEngine::clickedPortraitRestore(Button *button) {
+ _currentControlMode = 0;
+ _screen->_curPage = 2;
+ _screen->copyRegion(0, 0, 0, 0, 144, 168, 5, _screen->_curPage, Screen::CR_NO_P_CHECK);
+ gui_drawAllCharPortraitsWithStats();
+ _screen->_curPage = 0;
+ _screen->copyRegion(0, 0, 176, 0, 144, 168, 2, 0, Screen::CR_NO_P_CHECK);
+ _screen->updateScreen();
+ gui_setPlayFieldButtons();
+ return button->index;
+}
+
+int EoBCoreEngine::clickedUpArrow(Button *button) {
+ int b = calcNewBlockPositionAndTestPassability(_currentBlock, _currentDirection);
+
+ if (b == -1) {
+ notifyBlockNotPassable();
+ } else {
+ moveParty(b);
+ _sceneDefaultUpdate = 1;
+ }
+
+ return button->index;
+}
+
+int EoBCoreEngine::clickedDownArrow(Button *button) {
+ int b = calcNewBlockPositionAndTestPassability(_currentBlock, (_currentDirection + 2) & 3);
+
+ if (b == -1) {
+ notifyBlockNotPassable();
+ } else {
+ moveParty(b);
+ _sceneDefaultUpdate = 1;
+ }
+
+ return button->index;
+}
+
+int EoBCoreEngine::clickedLeftArrow(Button *button) {
+ int b = calcNewBlockPositionAndTestPassability(_currentBlock, (_currentDirection - 1) & 3);
+
+ if (b == -1) {
+ notifyBlockNotPassable();
+ } else {
+ moveParty(b);
+ _sceneDefaultUpdate = 1;
+ }
+
+ return button->index;
+}
+
+int EoBCoreEngine::clickedRightArrow(Button *button) {
+ int b = calcNewBlockPositionAndTestPassability(_currentBlock, (_currentDirection + 1) & 3);
+
+ if (b == -1) {
+ notifyBlockNotPassable();
+ } else {
+ moveParty(b);
+ _sceneDefaultUpdate = 1;
+ }
+
+ return button->index;
+}
+
+int EoBCoreEngine::clickedTurnLeftArrow(Button *button) {
+ _currentDirection = (_currentDirection - 1) & 3;
+ //_keybControlUnk = -1;
+ _sceneDefaultUpdate = 1;
+ _sceneUpdateRequired = true;
+ return button->index;
+}
+
+int EoBCoreEngine::clickedTurnRightArrow(Button *button) {
+ _currentDirection = (_currentDirection + 1) & 3;
+ //_keybControlUnk = -1;
+ _sceneDefaultUpdate = 1;
+ _sceneUpdateRequired = true;
+ return button->index;
+}
+
+int EoBCoreEngine::clickedAbortCharSwitch(Button *button) {
+ _timer->disable(0);
+ int c = _exchangeCharacterId;
+ _exchangeCharacterId = -1;
+ gui_drawCharPortraitWithStats(c);
+ gui_setPlayFieldButtons();
+ return button->index;
+}
+
+int EoBCoreEngine::clickedSceneThrowItem(Button *button) {
+ if (!_itemInHand)
+ return button->index;
+
+ if (launchObject(_updateCharNum, _itemInHand, _currentBlock, _dropItemDirIndex[(_currentDirection << 2) + button->arg], _currentDirection, _items[_itemInHand].type)) {
+ setHandItem(0);
+ _sceneUpdateRequired = true;
+ }
+
+ return button->index;
+}
+
+int EoBCoreEngine::clickedSceneSpecial(Button *button) {
+ _clickedSpecialFlag = 0x40;
+ return specialWallAction(calcNewBlockPosition(_currentBlock, _currentDirection), _currentDirection);
+}
+
+int EoBCoreEngine::clickedSpellbookAbort(Button *button) {
+ _updateFlags = 0;
+ _screen->copyRegion(0, 0, 64, 121, 112, 56, _useHiResDithering ? 4 : 10, 0, Screen::CR_NO_P_CHECK);
+ _screen->updateScreen();
+ gui_drawCompass(true);
+ gui_toggleButtons();
+ return button->index;
+}
+
+int EoBCoreEngine::clickedSpellbookScroll(Button *button) {
+ if (_openBookAvailableSpells[_openBookSpellLevel * 10] > 0) {
+ _openBookSpellListOffset ^= 6;
+ _openBookSpellSelectedItem = 0;
+ } else {
+ _openBookSpellListOffset = 6;
+ }
+
+ _characters[_openBookChar].slotStatus[2] = _openBookSpellSelectedItem;
+ _characters[_openBookChar].slotStatus[4] = _openBookSpellListOffset;
+
+ gui_drawSpellbook();
+
+ return button->index;
+}
+
+int EoBCoreEngine::clickedUnk(Button *button) {
+ return button->index;
+}
+
+void EoBCoreEngine::gui_processCharPortraitClick(int index) {
+ if (index == _updateCharNum)
+ return;
+
+ int a = _updateCharNum;
+ _updateCharNum = index;
+
+ gui_drawCharPortraitWithStats(a);
+ gui_drawCharPortraitWithStats(index);
+}
+
+void EoBCoreEngine::gui_processWeaponSlotClickLeft(int charIndex, int slotIndex) {
+ int itm = _characters[charIndex].inventory[slotIndex];
+ if (_items[itm].flags & 0x20)
+ return;
+
+ int ih = _itemInHand;
+ int t = _items[ih].type;
+ uint16 v = (ih) ? _itemTypes[t].invFlags : 0xffff;
+
+ if (v & _slotValidationFlags[slotIndex]) {
+ setHandItem(itm);
+ _characters[charIndex].inventory[slotIndex] = ih;
+ gui_drawCharPortraitWithStats(charIndex);
+ }
+
+ recalcArmorClass(charIndex);
+}
+
+void EoBCoreEngine::gui_processWeaponSlotClickRight(int charIndex, int slotIndex) {
+ if (!testCharacter(charIndex, 0x0d))
+ return;
+
+ Item itm = _characters[charIndex].inventory[slotIndex];
+ int wslot = slotIndex < 2 ? slotIndex : -1;
+
+ if (slotIndex < 2 && (!validateWeaponSlotItem(charIndex, slotIndex) || (!_currentControlMode && (_characters[charIndex].disabledSlots & (1 << slotIndex)))))
+ return;
+
+ if (!itemUsableByCharacter(charIndex, itm))
+ _txt->printMessage(_itemMisuseStrings[0], -1, _characters[charIndex].name);
+
+ if (!itm && slotIndex > 1)
+ return;
+
+ int8 tp = _items[itm].type;
+ int8 vl = _items[itm].value;
+ uint8 ep = _itemTypes[tp].extraProperties & 0x7f;
+
+ switch (ep) {
+ case 0:
+ case 16:
+ // Item automatically used when worn
+ _txt->printMessage(_itemMisuseStrings[1]);
+ break;
+
+ case 1:
+ case 2:
+ case 3:
+ // Weapons
+ if (!_currentControlMode)
+ useSlotWeapon(charIndex, slotIndex, itm);
+ break;
+
+ case 4:
+ case 8:
+ case 12:
+ case 13:
+ case 15:
+ // Item not used that way
+ _txt->printMessage(_itemMisuseStrings[2]);
+ break;
+
+ case 5:
+ case 6:
+ // Cleric holy symbol / mage spell book
+ if (!_currentControlMode)
+ useMagicBookOrSymbol(charIndex, ep == 6 ? 1 : 0);
+ break;
+
+ case 7:
+ // Food ration
+ // Don't do anything if mouse control is enabled (we don't support anything else)
+ // eatItemInHand(charIndex);
+ break;
+
+ case 10:
+ if (_flags.gameID == GI_EOB1)
+ vl += _clericSpellOffset;
+ // drop through
+ case 9:
+ // Mage/Cleric Scroll
+ if (!_currentControlMode)
+ useMagicScroll(charIndex, vl, wslot);
+ break;
+
+ case 11:
+ // Letters, Notes, Maps
+ displayParchment(vl);
+ break;
+
+ case 14:
+ // Potion
+ usePotion(charIndex, wslot);
+ break;
+
+ case 18:
+ useWand(charIndex, wslot);
+ break;
+
+ case 19:
+ // eob2 horn
+ useHorn(charIndex, wslot);
+ break;
+
+ case 20:
+ if (vl == 1)
+ inflictCharacterDamage(charIndex, 200);
+ else
+ useMagicScroll(charIndex, 55, wslot);
+ deleteInventoryItem(charIndex, wslot);
+ break;
+
+ default:
+ break;
+ }
+
+ if (_flags.gameID == GI_EOB1 || (ep == 1 && charIndex >= 2))
+ return;
+
+ _lastUsedItem = itm;
+ runLevelScript(calcNewBlockPosition(_currentBlock, _currentDirection), 0x100);
+ _lastUsedItem = 0;
+}
+
+void EoBCoreEngine::gui_processInventorySlotClick(int slot) {
+ int itm = _characters[_updateCharNum].inventory[slot];
+ int ih = _itemInHand;
+ if (!validateInventorySlotForItem(ih, _updateCharNum, slot))
+ return;
+
+ if (slot == 16) {
+ if (ih) {
+ setItemPosition(&_characters[_updateCharNum].inventory[16], -2, ih, 0);
+ gui_drawInventoryItem(slot, 1, 0);
+ setHandItem(0);
+
+ } else {
+ itm = getQueuedItem(&_characters[_updateCharNum].inventory[16], 0, -1);
+ gui_drawInventoryItem(slot, 1, 0);
+ setHandItem(itm);
+ }
+
+ } else {
+ setHandItem(itm);
+ _characters[_updateCharNum].inventory[slot] = ih;
+ gui_drawInventoryItem(slot, 1, 0);
+ recalcArmorClass(_updateCharNum);
+ }
+}
+
+GUI_EoB::GUI_EoB(EoBCoreEngine *vm) : GUI(vm), _vm(vm), _screen(vm->_screen) {
+ _menuStringsPrefsTemp = new char*[4];
+ memset(_menuStringsPrefsTemp, 0, 4 * sizeof(char *));
+
+ _saveSlotStringsTemp = new char*[6];
+ for (int i = 0; i < 6; i++) {
+ _saveSlotStringsTemp[i] = new char[20];
+ memset(_saveSlotStringsTemp[i], 0, 20);
+ }
+ _saveSlotIdTemp = new int16[6];
+ _savegameOffset = 0;
+ _saveSlotX = _saveSlotY = 0;
+
+ _specialProcessButton = _backupButtonList = 0;
+ _flagsMouseLeft = _flagsMouseRight = _flagsModifier = 0;
+ _backupButtonList = 0;
+ _progress = 0;
+ _prcButtonUnk3 = 1;
+ _cflag = 0xffff;
+
+ _menuLineSpacing = 0;
+ _menuLastInFlags = 0;
+ _menuCur = 0;
+ _menuNumItems = 0;
+
+ _numPages = (_vm->game() == GI_EOB2) ? 8 : 5;
+ _numVisPages = (_vm->game() == GI_EOB2) ? 6 : 5;
+ _clericSpellAvltyFlags = (_vm->game() == GI_EOB2) ? 0xf7ffffff : 0x7bffff;
+ _paladinSpellAvltyFlags = (_vm->game() == GI_EOB2) ? 0xa9bbd1d : 0x800ff2;
+ _numAssignedSpellsOfType = new int8[72];
+ memset(_numAssignedSpellsOfType, 0, 72);
+
+ _charSelectRedraw = false;
+
+ _highLightColorTable = (_vm->game() == GI_EOB1 && (_vm->_configRenderMode == Common::kRenderCGA || _vm->_configRenderMode == Common::kRenderEGA)) ? _highlightColorTableEGA : _highlightColorTableVGA;
+ _updateBoxIndex = -1;
+ _highLightBoxTimer = 0;
+ _updateBoxColorIndex = 0;
+
+ _needRest = false;
+}
+
+GUI_EoB::~GUI_EoB() {
+ if (_menuStringsPrefsTemp) {
+ for (int i = 0; i < 4; i++)
+ delete[] _menuStringsPrefsTemp[i];
+ delete[] _menuStringsPrefsTemp;
+ }
+
+ if (_saveSlotStringsTemp) {
+ for (int i = 0; i < 6; i++)
+ delete[] _saveSlotStringsTemp[i];
+ delete[] _saveSlotStringsTemp;
+ }
+
+ delete[] _saveSlotIdTemp;
+
+ delete[] _numAssignedSpellsOfType;
+}
+
+void GUI_EoB::processButton(Button *button) {
+ if (!button->data0Val1 && !button->data2Val1 && !button->data1Val1)
+ return;
+
+ if ((button->flags & 0x18) == 0x18)
+ return;
+
+ int sd = button->dimTableIndex;
+ const ScreenDim *dm = _screen->getScreenDim(sd);
+
+ int fx = button->x;
+ if (fx < 0)
+ fx += (dm->w << 3);
+
+ int sx = fx + (dm->sx << 3);
+
+ int fy = button->y;
+ if (fy < 0)
+ fy += dm->h;
+
+ int sy = fy + dm->sy;
+
+ uint16 fw = button->width;
+ uint16 fh = button->height;
+
+ uint8 col1 = button->data1Val1;
+ uint8 col2 = button->data1Val3;
+
+ int fx2 = sx + fw - 1;
+ int fy2 = sy + fh - 1;
+
+ if (button->flags2 & 1) {
+ if (button->data1Val1 == 1) {
+ if (button->data0Val1 == 1) {
+ _screen->drawShape(_screen->_curPage, button->data1ShapePtr, fx, fy, sd);
+ } else if (button->data0Val1 == 2) {
+ if (!(button->flags2 & 4))
+ _screen->printText((const char *)button->data1ShapePtr, sx, sy, col1, col2);
+ } else if (button->data0Val1 == 3) {
+ // nullsub (at least EOBII)
+ } else if (button->data0Val1 == 4) {
+ if (button->data1Callback)
+ (*button->data1Callback.get())(button);
+ }
+ } else if (button->data1Val1 == 2) {
+ if (!(button->flags2 & 4))
+ _screen->drawBox(sx, sy, fx2, fy2, col1);
+ } else if (button->data1Val1 == 3) {
+ // nullsub (at least EOBII)
+ } else if (button->data1Val1 == 4) {
+ if (button->data1Callback)
+ (*button->data1Callback.get())(button);
+ }
+ }
+
+ if (button->flags2 & 4) {
+ if (button->data2Val1 == 1) {
+ if (button->data0Val1 == 1) {
+ _screen->drawShape(_screen->_curPage, button->data2ShapePtr, fx, fy, sd);
+ } else if (button->data0Val1 == 2) {
+ if (button->flags2 & 1)
+ _screen->printText((const char *)button->data2ShapePtr, sx, sy, button->data3Val2, button->data3Val3);
+ else
+ _screen->printText((const char *)button->data2ShapePtr, sx, sy, button->data2Val2, button->data2Val3);
+ } else if (button->data0Val1 == 3) {
+ // nullsub (at least EOBII)
+ } else if (button->data0Val1 == 4) {
+ if (button->data2Callback)
+ (*button->data2Callback.get())(button);
+ }
+ } else if (button->data2Val1 == 2) {
+ _screen->drawBox(sx, sy, fx2, fy2, (button->flags2 & 1) ? button->data3Val2 : button->data2Val2);
+ } else if (button->data2Val1 == 3) {
+ // nullsub (at least EOBII)
+ } else if (button->data2Val1 == 4) {
+ if (button->data2Callback)
+ (*button->data2Callback.get())(button);
+ }
+ }
+
+ if (!(button->flags2 & 5)) {
+ if (button->data0Val1 == 1) {
+ _screen->drawShape(_screen->_curPage, button->data0ShapePtr, fx, fy, sd);
+ } else if (button->data0Val1 == 2) {
+ _screen->printText((const char *)button->data0ShapePtr, sx, sy, button->data0Val2, button->data0Val3);
+ } else if (button->data0Val1 == 3) {
+ // nullsub (at least EOBII)
+ } else if (button->data0Val1 == 4) {
+ if (button->data0Callback)
+ (*button->data0Callback.get())(button);
+ } else if (button->data0Val1 == 5) {
+ _screen->drawBox(sx, sy, fx2, fy2, button->data0Val2);
+ } else {
+ if (!button->data0Val1) {
+ if (button->data1Val1 == 2 || button->data2Val1 == 2) {
+ _screen->drawBox(sx, sy, fx2, fy2, button->data0Val2);
+ } else {
+ // nullsub (at least EOBII)
+ }
+ }
+ }
+ }
+}
+
+int GUI_EoB::processButtonList(Kyra::Button *buttonList, uint16 inputFlags, int8 mouseWheel) {
+ _progress = 0;
+ uint16 in = inputFlags & 0xff;
+ uint16 buttonReleaseFlag = 0;
+ bool clickEvt = false;
+ //_vm->_processingButtons = true;
+ _flagsMouseLeft = (_vm->_mouseClick == 1) ? 2 : 4;
+ _flagsMouseRight = (_vm->_mouseClick == 2) ? 2 : 4;
+ _vm->_mouseClick = 0;
+
+ if (mouseWheel) {
+ return 204 + mouseWheel;
+ } else if (in >= 199 && in <= 202) {
+ buttonReleaseFlag = (inputFlags & 0x800) ? 3 : 1;
+ if (in < 201)
+ _flagsMouseLeft = buttonReleaseFlag;
+ else
+ _flagsMouseRight = buttonReleaseFlag;
+
+ ////////////////////////////
+ if (!buttonList && !(inputFlags & 0x800))
+ return inputFlags & 0xff;
+ ////////////////////////////
+
+ inputFlags = 0;
+ clickEvt = true;
+ } else if (inputFlags & 0x8000) {
+ inputFlags &= 0xff;
+ }
+
+ uint16 result = 0;
+ bool runLoop = true;
+
+ if (!buttonList)
+ return inputFlags;
+
+ if (_vm->_buttonListChanged || (buttonList != _backupButtonList)) {
+ _backupButtonList = buttonList;
+ _flagsModifier = 0;
+
+ while (runLoop) {
+ processButton(buttonList);
+ _flagsModifier |= (buttonList->flags & 0xAA04);
+
+ // UNUSED
+ //if (buttonList->flags2 & 0x20) {
+ //if (_processButtonListExtraCallback)
+ // this->*_processButtonListExtraCallback(buttonList);
+ //}
+
+ if (buttonList->nextButton)
+ buttonList = buttonList->nextButton;
+ else
+ runLoop = false;
+ }
+
+ _vm->_buttonListChanged = false;
+
+ _specialProcessButton = 0;
+ _prcButtonUnk3 = 1;
+ _cflag = 0xffff;
+ }
+
+ int sd = 0;
+ const ScreenDim *dm = _screen->getScreenDim(sd);
+
+ int x1 = dm->sx << 3;
+ int y1 = dm->sy;
+ int w1 = dm->w << 3;
+ int h1 = dm->h;
+
+ uint16 v8 = 0;
+ uint16 v18 = 0;
+ uint16 v16 = 0;
+
+ if (_specialProcessButton)
+ buttonList = _specialProcessButton;
+
+ while (runLoop) {
+ if (buttonList->flags & 8) {
+ buttonList = buttonList->nextButton;
+ runLoop = buttonList ? true : false;
+ continue;
+ }
+
+ int vc = 0;
+ int v6 = 0;
+ uint16 iFlag = buttonList->index | 0x8000;
+ uint16 flgs2 = buttonList->flags2;
+ uint16 flgs = buttonList->flags;
+
+ if (flgs2 & 1)
+ flgs2 |= 8;
+ else
+ flgs2 &= 0xfff7;
+
+ if (flgs2 & 4)
+ flgs2 |= 0x10;
+ else
+ flgs2 &= 0xffef;
+
+ uint16 vL = 0;
+ uint16 vR = 0;
+
+ if (inputFlags) {
+ if (buttonList->keyCode == inputFlags) {
+ _progress = 1;
+ _flagsMouseLeft = 1;
+ flgs2 ^= 1;
+ result = iFlag;
+ v6 = 1;
+ } else if (buttonList->keyCode2 == inputFlags) {
+ _progress = 2;
+ _flagsMouseRight = 1;
+ result = iFlag;
+ v6 = 1;
+ }
+ } else if (_flagsModifier || clickEvt) {
+ vL = flgs & 0xf00;
+ vR = flgs & 0xf000;
+
+ if (_prcButtonUnk3) {
+ if (sd != buttonList->dimTableIndex) {
+ sd = buttonList->dimTableIndex;
+ dm = _screen->getScreenDim(sd);
+ x1 = dm->sx << 3;
+ y1 = dm->sy;
+ w1 = dm->w << 3;
+ h1 = dm->h;
+ }
+
+ int x2 = x1;
+ if (buttonList->x < 0)
+ x2 += w1;
+ x2 += buttonList->x;
+
+ int y2 = y1;
+ if (buttonList->y < 0)
+ y2 += h1;
+ y2 += buttonList->y;
+
+ if (_vm->_mouseX >= x2 && _vm->_mouseX <= (x2 + buttonList->width) && _vm->_mouseY >= y2 && _vm->_mouseY <= (y2 + buttonList->height)) {
+ flgs2 |= 2;
+
+ if (vL) {
+ switch (_flagsMouseLeft - 1) {
+ case 0:
+ v18 = 1;
+
+ if ((flgs & 4) && buttonList->data2Val1) {
+ flgs2 |= 4;
+ vc = 1;
+ } else {
+ flgs2 &= 0xfffb;
+ }
+
+ if (flgs & 0x100) {
+ v6 = 1;
+ if (!(flgs & 1)) {
+ flgs2 ^= 1;
+ result = iFlag;
+ }
+ }
+
+ if (flgs & 0x40) {
+ _specialProcessButton = buttonList;
+ v8 = 1;
+ }
+
+ _cflag = flgs;
+ break;
+
+ case 1:
+ if (flgs != _cflag)
+ break;
+
+ if ((flgs & 4) && buttonList->data2Val1) {
+ flgs2 |= 4;
+ vc = 1;
+ } else {
+ flgs2 &= 0xfffb;
+ }
+
+ if (!(flgs & 0x200))
+ break;
+
+ v6 = 1;
+
+ if (flgs & 1)
+ break;
+
+ flgs2 |= 1;
+ result = iFlag;
+ break;
+
+ case 2:
+ if (_cflag != flgs)
+ break;
+
+ if (flgs & 0x400) {
+ v6 = 1;
+ if (flgs & 1) {
+ flgs2 ^= 1;
+ result = iFlag;
+ }
+ }
+
+ if ((flgs & 2) && (flgs2 & 1))
+ flgs2 &= 0xfffe;
+ break;
+
+ case 3:
+ if ((flgs & 4) || (!buttonList->data2Val1))
+ flgs2 &= 0xfffb;
+ else
+ flgs2 |= 4;
+
+ if (flgs & 0x800) {
+ v6 = 1;
+ break;
+ }
+
+ if ((flgs & 2) && (flgs2 & 1))
+ flgs2 &= 0xfffe;
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ if (vR && !v6 && !vc) {
+ switch (_flagsMouseRight - 1) {
+ case 0:
+ v18 = 1;
+
+ if ((flgs & 4) && buttonList->data2Val1)
+ flgs2 |= 4;
+ else
+ flgs2 &= 0xfffb;
+
+ if (flgs & 0x1000) {
+ v6 = 1;
+ if (!(flgs & 1)) {
+ flgs2 ^= 1;
+ result = iFlag;
+ }
+ }
+
+ if (flgs & 0x40) {
+ _specialProcessButton = buttonList;
+ v8 = 1;
+ }
+
+ _cflag = flgs;
+ break;
+
+ case 1:
+ if (flgs != _cflag)
+ break;
+
+ if ((flgs & 4) && buttonList->data2Val1)
+ flgs2 |= 4;
+ else
+ flgs2 &= 0xfffb;
+
+ if (!(flgs & 0x2000))
+ break;
+
+ v6 = 1;
+
+ if (flgs & 1)
+ break;
+
+ flgs2 |= 1;
+ result = iFlag;
+ break;
+ case 2:
+ if (_cflag != flgs)
+ break;
+
+ if (flgs & 0x4000) {
+ v6 = 1;
+ if (flgs & 1) {
+ flgs2 ^= 1;
+ result = iFlag;
+ }
+ }
+
+ if ((flgs & 2) && (flgs2 & 1))
+ flgs2 &= 0xfffe;
+ break;
+
+ case 3:
+ if ((flgs & 4) || (!buttonList->data2Val1))
+ flgs2 &= 0xfffb;
+ else
+ flgs2 |= 4;
+
+ if (flgs & 0x8000) {
+ v6 = 1;
+ break;
+ }
+
+ if ((flgs & 2) && (flgs2 & 1))
+ flgs2 &= 0xfffe;
+ break;
+
+ default:
+ break;
+ }
+ }
+ } else { // if (_vm->_mouseX >= x2 && _vm->_mouseX <= (x2 + buttonList->width)....)
+ flgs2 &= 0xfff9;
+
+ if ((flgs & 0x40) && (!(flgs & 0x80)) && _specialProcessButton && !v8) {
+ static const uint16 flagsTable[] = { 0x100, 0x200, 0x400, 0x800, 0x1000, 0x2000, 0x4000, 0x8000 };
+
+ if (vL) {
+ v16 = flagsTable[_flagsMouseLeft - 1];
+ if (v16 & flgs)
+ v6 = 1;
+ }
+
+ if (vR && !v6) {
+ v16 = flagsTable[_flagsMouseRight + 3];
+ if (v16 & flgs)
+ v6 = 1;
+ }
+
+ if (!v6) {
+ _specialProcessButton = 0;
+ _prcButtonUnk3 = 1;
+ }
+ }
+
+ if ((flgs & 2) && (flgs2 & 1))
+ flgs2 &= 0xfffe;
+ } // end if (_vm->_mouseX >= x2 && _vm->_mouseX <= (x2 + buttonList->width)....)
+ } // end if (_prcButtonUnk3)
+ } // end if (_flagsModifier || clickEvt)
+
+ buttonList->flags = flgs;
+ buttonList->flags2 = flgs2;
+
+ bool f21 = (flgs2 & 8) ? true : false;
+ bool f22 = (flgs2 & 1) ? true : false;
+ bool f23 = (flgs2 & 0x10) ? true : false;
+ bool f24 = (flgs2 & 4) ? true : false;
+
+ if (f21 != f22 || f23 != f24)
+ processButton(buttonList);
+
+ if (v6 && buttonList->buttonCallback)
+ runLoop = ((*buttonList->buttonCallback.get())(buttonList)) ? false : true;
+
+ if ((flgs2 & 2) && (flgs & 0x20))
+ runLoop = false;
+
+ if (_specialProcessButton && ((vL && _flagsMouseLeft == 3) || (vR && _flagsMouseRight == 3))) {
+ _specialProcessButton = 0;
+ _prcButtonUnk3 = 1;
+ runLoop = false;
+ }
+
+ if (_specialProcessButton && !v8)
+ runLoop = false;
+
+ buttonList = buttonList->nextButton;
+ if (!buttonList)
+ runLoop = false;
+ };
+
+ if ((_flagsMouseLeft == 1 || _flagsMouseRight == 1) && !v18)
+ _cflag = 0xffff;
+
+ if (!result)
+ result = inputFlags;
+
+ return result;
+}
+
+void GUI_EoB::simpleMenu_setup(int sd, int maxItem, const char *const *strings, int32 menuItemsMask, int itemOffset, int lineSpacing) {
+ simpleMenu_initMenuItemsMask(sd, maxItem, menuItemsMask, itemOffset);
+
+ const ScreenDim *dm = _screen->getScreenDim(19 + sd);
+ int x = (_screen->_curDim->sx + dm->sx) << 3;
+ int y = _screen->_curDim->sy + dm->sy;
+
+ int v = simpleMenu_getMenuItem(_menuCur, menuItemsMask, itemOffset);
+
+ for (int i = 0; i < _menuNumItems; i++) {
+ int item = simpleMenu_getMenuItem(i, menuItemsMask, itemOffset);
+ int ty = y + i * (lineSpacing + _screen->getFontHeight());
+ _screen->printShadedText(strings[item], x, ty, (_vm->_configRenderMode == Common::kRenderCGA) ? 1 : dm->unkA, 0);
+ if (item == v)
+ _screen->printText(strings[item], x, ty, dm->unkC, 0);
+ }
+
+ _screen->updateScreen();
+ _menuLineSpacing = lineSpacing;
+ _menuLastInFlags = 0;
+ _vm->removeInputTop();
+}
+
+int GUI_EoB::simpleMenu_process(int sd, const char *const *strings, void *b, int32 menuItemsMask, int itemOffset) {
+ const ScreenDim *dm = _screen->getScreenDim(19 + sd);
+ int h = _menuNumItems - 1;
+ int currentItem = _menuCur % _menuNumItems;
+ int newItem = currentItem;
+ int result = -1;
+ int lineH = (_menuLineSpacing + _screen->getFontHeight());
+ int lineS1 = _menuLineSpacing >> 1;
+ int x = (_screen->_curDim->sx + dm->sx) << 3;
+ int y = _screen->_curDim->sy + dm->sy;
+
+ int inFlag = _vm->checkInput(0, false, 0) & 0x8ff;
+ _vm->removeInputTop();
+ Common::Point mousePos = _vm->getMousePos();
+
+ int x1 = (_screen->_curDim->sx << 3) + (dm->sx * _screen->getFontWidth());
+ int y1 = _screen->_curDim->sy + dm->sy - lineS1;
+ int x2 = x1 + (dm->w * _screen->getFontWidth()) - 1;
+ int y2 = y1 + _menuNumItems * lineH - 1;
+ if (_vm->posWithinRect(mousePos.x, mousePos.y, x1, y1, x2, y2))
+ newItem = (mousePos.y - y1) / lineH;
+
+ if (inFlag == 199 || inFlag == 201) {
+ if (_vm->posWithinRect(_vm->_mouseX, _vm->_mouseY, x1, y1, x2, y2))
+ result = newItem = (_vm->_mouseY - y1) / lineH;
+ } else if (inFlag == _vm->_keyMap[Common::KEYCODE_RETURN] || inFlag == _vm->_keyMap[Common::KEYCODE_SPACE] || inFlag == _vm->_keyMap[Common::KEYCODE_KP5]) {
+ result = newItem;
+ } else if (inFlag == _vm->_keyMap[Common::KEYCODE_HOME] || inFlag == _vm->_keyMap[Common::KEYCODE_KP7] || inFlag == _vm->_keyMap[Common::KEYCODE_PAGEUP] || inFlag == _vm->_keyMap[Common::KEYCODE_KP9]) {
+ newItem = 0;
+ } else if (inFlag == _vm->_keyMap[Common::KEYCODE_END] || inFlag == _vm->_keyMap[Common::KEYCODE_KP1] || inFlag == _vm->_keyMap[Common::KEYCODE_PAGEDOWN] || inFlag == _vm->_keyMap[Common::KEYCODE_KP3]) {
+ newItem = h;
+ } else if (inFlag == _vm->_keyMap[Common::KEYCODE_UP] || inFlag == _vm->_keyMap[Common::KEYCODE_KP8]) {
+ if (--newItem < 0)
+ newItem = h;
+ } else if (inFlag == _vm->_keyMap[Common::KEYCODE_DOWN] || inFlag == _vm->_keyMap[Common::KEYCODE_KP2]) {
+ if (++newItem > h)
+ newItem = 0;
+ } else {
+ _menuLastInFlags = inFlag;
+ }
+
+ if (newItem != currentItem) {
+ _screen->printText(strings[simpleMenu_getMenuItem(currentItem, menuItemsMask, itemOffset)], x, y + currentItem * lineH, (_vm->_configRenderMode == Common::kRenderCGA) ? 1 : dm->unkA, 0);
+ _screen->printText(strings[simpleMenu_getMenuItem(newItem, menuItemsMask, itemOffset)], x, y + newItem * lineH , dm->unkC, 0);
+ _screen->updateScreen();
+ }
+
+ if (result != -1) {
+ result = simpleMenu_getMenuItem(result, menuItemsMask, itemOffset);
+ simpleMenu_flashSelection(strings[result], x, y + newItem * lineH, dm->unkA, dm->unkC, 0);
+ }
+
+ _menuCur = newItem;
+
+ return result;
+}
+
+int GUI_EoB::simpleMenu_getMenuItem(int index, int32 menuItemsMask, int itemOffset) {
+ if (menuItemsMask == -1)
+ return index;
+
+ int res = 0;
+ int i = index;
+
+ for (; i; res++) {
+ if (menuItemsMask & (1 << (res + itemOffset)))
+ i--;
+ }
+
+ while (!(menuItemsMask & (1 << (res + itemOffset))))
+ res++;
+
+ return res;
+}
+
+void GUI_EoB::simpleMenu_flashSelection(const char *str, int x, int y, int color1, int color2, int color3) {
+ for (int i = 0; i < 3; i++) {
+ _screen->printText(str, x, y, color2, color3);
+ _screen->updateScreen();
+ _vm->_system->delayMillis(32);
+ _screen->printText(str, x, y, color1, color3);
+ _screen->updateScreen();
+ _vm->_system->delayMillis(32);
+ }
+}
+
+void GUI_EoB::runCampMenu() {
+ Screen::FontId of = _screen->setFont(Screen::FID_8_FNT);
+
+ Button *highlightButton = 0;
+ Button *prevHighlightButton = 0;
+
+ int newMenu = 0;
+ int lastMenu = -1;
+ bool redrawPortraits = false;
+
+ _charSelectRedraw = false;
+ _needRest = false;
+ Button *buttonList = 0;
+
+ for (bool runLoop = true; runLoop && !_vm->shouldQuit();) {
+ if (newMenu == 2)
+ updateOptionsStrings();
+
+ if (newMenu != -1) {
+ releaseButtons(buttonList);
+
+ _vm->_menuDefs[0].titleStrId = newMenu ? 1 : 56;
+ if (newMenu == 2)
+ _vm->_menuDefs[2].titleStrId = 57;
+ else if (newMenu == 1)
+ _vm->_menuDefs[1].titleStrId = 58;
+
+ buttonList = initMenu(newMenu);
+
+ if (newMenu != lastMenu) {
+ highlightButton = buttonList;
+ prevHighlightButton = 0;
+ }
+
+ lastMenu = newMenu;
+ newMenu = -1;
+ }
+
+ int inputFlag = _vm->checkInput(buttonList, false, 0) & 0x80ff;
+ _vm->removeInputTop();
+
+ if (inputFlag == _vm->_keyMap[Common::KEYCODE_ESCAPE])
+ inputFlag = 0x8007;
+ else if (inputFlag == _vm->_keyMap[Common::KEYCODE_KP5] || inputFlag == _vm->_keyMap[Common::KEYCODE_SPACE] || inputFlag == _vm->_keyMap[Common::KEYCODE_RETURN]) {
+ inputFlag = 0x8000 + prevHighlightButton->index;
+ }
+
+ Button *clickedButton = _vm->gui_getButton(buttonList, inputFlag & 0x7fff);
+
+ if (clickedButton) {
+ drawMenuButton(prevHighlightButton, false, false, true);
+ drawMenuButton(clickedButton, true, true, true);
+ _screen->updateScreen();
+ _vm->_system->delayMillis(80);
+ drawMenuButton(clickedButton, false, true, true);
+ _screen->updateScreen();
+ highlightButton = clickedButton;
+ prevHighlightButton = 0;
+ }
+
+ if (inputFlag == _vm->_keyMap[Common::KEYCODE_KP3] || inputFlag == _vm->_keyMap[Common::KEYCODE_PAGEDOWN] || inputFlag == _vm->_keyMap[Common::KEYCODE_KP1] || inputFlag == _vm->_keyMap[Common::KEYCODE_END]) {
+ highlightButton = _vm->gui_getButton(buttonList, _vm->_menuDefs[lastMenu].firstButtonStrId + _vm->_menuDefs[lastMenu].numButtons);
+ inputFlag = _vm->_keyMap[Common::KEYCODE_UP];
+ } else if (inputFlag == _vm->_keyMap[Common::KEYCODE_KP7] || inputFlag == _vm->_keyMap[Common::KEYCODE_HOME] || inputFlag == _vm->_keyMap[Common::KEYCODE_KP9] || inputFlag == _vm->_keyMap[Common::KEYCODE_PAGEUP]) {
+ highlightButton = _vm->gui_getButton(buttonList, _vm->_menuDefs[lastMenu].firstButtonStrId + 1);
+ } else if (inputFlag == _vm->_keyMap[Common::KEYCODE_KP8] || inputFlag == _vm->_keyMap[Common::KEYCODE_UP] || inputFlag == _vm->_keyMap[Common::KEYCODE_KP2] || inputFlag == _vm->_keyMap[Common::KEYCODE_DOWN]) {
+ if (prevHighlightButton) {
+ int dir = (inputFlag == _vm->_keyMap[Common::KEYCODE_UP]) ? -1 : 1;
+ int s = prevHighlightButton->index + dir;
+ int a = _vm->_menuDefs[lastMenu].firstButtonStrId + 1;
+ int b = a + _vm->_menuDefs[lastMenu].numButtons - 1;
+
+ do {
+ if (s < a)
+ s = b;
+ if (s > b)
+ s = a;
+ if (_vm->_menuButtonDefs[s - 1].flags & 2)
+ break;
+ s += dir;
+ } while (!_vm->shouldQuit());
+
+ highlightButton = _vm->gui_getButton(buttonList, s);
+ }
+
+ } else if (inputFlag > 0x8000 && inputFlag < 0x8010) {
+ int i = 0;
+ int cnt = 0;
+
+ switch (inputFlag) {
+ case 0x8001:
+ if (restParty())
+ runLoop = false;
+ else
+ _needRest = false;
+ redrawPortraits = true;
+ newMenu = 0;
+ break;
+
+ case 0x8002:
+ runMemorizePrayMenu(selectCharacterDialogue(23), 0);
+ newMenu = 0;
+ break;
+
+ case 0x8003:
+ runMemorizePrayMenu(selectCharacterDialogue(26), 1);
+ newMenu = 0;
+ break;
+
+ case 0x8004:
+ scribeScrollDialogue();
+ newMenu = 0;
+ break;
+
+ case 0x8005:
+ newMenu = 2;
+ break;
+
+ case 0x8006:
+ newMenu = 1;
+ break;
+
+ case 0x8007:
+ if (_needRest)
+ displayTextBox(44);
+ // fall through
+
+ case 0x800c:
+ case 0x800f:
+ if (lastMenu == 1 || lastMenu == 2)
+ newMenu = 0;
+ else if (inputFlag == _vm->_keyMap[Common::KEYCODE_ESCAPE])
+ newMenu = 0;
+ else
+ runLoop = false;
+ break;
+
+ case 0x8008:
+ if (runLoadMenu(0, 0))
+ runLoop = false;
+ else
+ newMenu = 1;
+ break;
+
+ case 0x8009:
+ if (runSaveMenu(0, 0))
+ displayTextBox(14);
+ newMenu = 1;
+ break;
+
+ case 0x800a:
+ for (; i < 6; i++) {
+ if (_vm->testCharacter(i, 1))
+ cnt++;
+ }
+
+ if (cnt > 4) {
+ _vm->dropCharacter(selectCharacterDialogue(53));
+ _vm->gui_drawPlayField(false);
+ _screen->copyRegion(0, 120, 0, 0, 176, 24, 0, _vm->_useHiResDithering ? 1 : 12, Screen::CR_NO_P_CHECK);
+ _screen->setFont(Screen::FID_6_FNT);
+ _vm->gui_drawAllCharPortraitsWithStats();
+ _screen->setFont(Screen::FID_8_FNT);
+ } else {
+ displayTextBox(45);
+ }
+
+ newMenu = 0;
+ break;
+
+ case 0x800b:
+ if (confirmDialogue(46))
+ _vm->quitGame();
+ newMenu = 0;
+ break;
+
+ case 0x800d:
+ _vm->_configSounds ^= true;
+ _vm->_configMusic = _vm->_configSounds ? 1 : 0;
+ newMenu = 2;
+ break;
+
+ case 0x800e:
+ _vm->_configHpBarGraphs ^= true;
+ newMenu = 2;
+ redrawPortraits = true;
+ break;
+
+ default:
+ break;
+ }
+
+ lastMenu = -1;
+
+ } else {
+ Common::Point p = _vm->getMousePos();
+ for (Button *b = buttonList; b; b = b->nextButton) {
+ if ((b->arg & 2) && _vm->posWithinRect(p.x, p.y, b->x, b->y, b->x + b->width, b->y + b->height))
+ highlightButton = b;
+ }
+ }
+
+ if (_charSelectRedraw || redrawPortraits) {
+ for (int i = 0; i < 6; i++) {
+ _vm->gui_drawCharPortraitWithStats(i);
+ _vm->sortCharacterSpellList(i);
+ }
+ }
+
+ _charSelectRedraw = redrawPortraits = false;
+
+ if (prevHighlightButton != highlightButton && newMenu == -1 && runLoop) {
+ drawMenuButton(prevHighlightButton, false, false, true);
+ drawMenuButton(highlightButton, false, true, true);
+ _screen->updateScreen();
+ prevHighlightButton = highlightButton;
+ }
+ }
+
+ _screen->setFont(of);
+ releaseButtons(buttonList);
+ _vm->writeSettings();
+}
+
+bool GUI_EoB::runLoadMenu(int x, int y) {
+ const ScreenDim *dm = _screen->getScreenDim(11);
+ int xo = dm->sx;
+ int yo = dm->sy;
+ bool result = false;
+
+ _screen->modifyScreenDim(11, dm->sx + (x >> 3), dm->sy + y, dm->w, dm->h);
+
+ for (bool runLoop = true; runLoop && !_vm->shouldQuit();) {
+ updateSaveSlotsList(_vm->_targetName);
+ int slot = selectSaveSlotDialogue(x, y, 1);
+ if (slot > 5) {
+ runLoop = result = false;
+ } else if (slot >= 0) {
+ if (_saveSlotIdTemp[slot] == -1) {
+ messageDialogue(11, 65, 6);
+ } else {
+ if (_vm->loadGameState(_saveSlotIdTemp[slot]).getCode() != Common::kNoError)
+ messageDialogue(11, 16, 6);
+ runLoop = false;
+ result = true;
+ }
+ }
+ }
+
+ _screen->modifyScreenDim(11, xo, yo, dm->w, dm->h);
+ return result;
+}
+
+bool GUI_EoB::confirmDialogue2(int dim, int id, int deflt) {
+ int od = _screen->curDimIndex();
+ Screen::FontId of = _screen->setFont(Screen::FID_8_FNT);
+ _screen->setScreenDim(dim);
+
+ drawTextBox(dim, id);
+
+ int16 x[2];
+ x[0] = (_screen->_curDim->sx << 3) + 8;
+ x[1] = (_screen->_curDim->sx + _screen->_curDim->w - 5) << 3;
+ int16 y = _screen->_curDim->sy + _screen->_curDim->h - 21;
+ int newHighlight = deflt ^ 1;
+ int lastHighlight = -1;
+
+ for (int i = 0; i < 2; i++)
+ drawMenuButtonBox(x[i], y, 32, 14, false, false);
+
+ for (bool runLoop = true; runLoop && !_vm->shouldQuit();) {
+ Common::Point p = _vm->getMousePos();
+ if (_vm->posWithinRect(p.x, p.y, x[0], y, x[0] + 32, y + 14))
+ newHighlight = 0;
+ else if (_vm->posWithinRect(p.x, p.y, x[1], y, x[1] + 32, y + 14))
+ newHighlight = 1;
+
+ int inputFlag = _vm->checkInput(0, false, 0) & 0x8ff;
+ _vm->removeInputTop();
+
+ if (inputFlag == _vm->_keyMap[Common::KEYCODE_SPACE] || inputFlag == _vm->_keyMap[Common::KEYCODE_RETURN]) {
+ runLoop = false;
+ } else if (inputFlag == _vm->_keyMap[Common::KEYCODE_LEFT] || inputFlag == _vm->_keyMap[Common::KEYCODE_KP4] || inputFlag == _vm->_keyMap[Common::KEYCODE_RIGHT] || inputFlag == _vm->_keyMap[Common::KEYCODE_KP6]) {
+ newHighlight ^= 1;
+ } else if (inputFlag == _vm->_keyMap[Common::KEYCODE_n]) {
+ newHighlight = 1;
+ runLoop = false;
+ } else if (inputFlag == _vm->_keyMap[Common::KEYCODE_y]) {
+ newHighlight = 0;
+ runLoop = false;
+ } else if (inputFlag == 199 || inputFlag == 201) {
+ if (_vm->posWithinRect(p.x, p.y, x[0], y, x[0] + 32, y + 14)) {
+ newHighlight = 0;
+ runLoop = false;
+ } else if (_vm->posWithinRect(p.x, p.y, x[1], y, x[1] + 32, y + 14)) {
+ newHighlight = 1;
+ runLoop = false;
+ }
+ }
+
+ if (newHighlight != lastHighlight) {
+ for (int i = 0; i < 2; i++)
+ _screen->printShadedText(_vm->_menuYesNoStrings[i], x[i] + 16 - (strlen(_vm->_menuYesNoStrings[i]) << 2) + 1, y + 3, i == newHighlight ? 6 : 15, 0);
+ _screen->updateScreen();
+ lastHighlight = newHighlight;
+ }
+ }
+
+ drawMenuButtonBox(x[newHighlight], y, 32, 14, true, true);
+ _screen->updateScreen();
+ _vm->_system->delayMillis(80);
+ drawMenuButtonBox(x[newHighlight], y, 32, 14, false, true);
+ _screen->updateScreen();
+
+ _screen->copyRegion(0, _screen->_curDim->h, _screen->_curDim->sx << 3, _screen->_curDim->sy, _screen->_curDim->w << 3, _screen->_curDim->h, 2, 0, Screen::CR_NO_P_CHECK);
+ _screen->setFont(of);
+ _screen->setScreenDim(od);
+
+ return newHighlight ? false : true;
+}
+
+void GUI_EoB::messageDialogue(int dim, int id, int buttonTextCol) {
+ int od = _screen->curDimIndex();
+ _screen->setScreenDim(dim);
+ Screen::FontId of = _screen->setFont(Screen::FID_8_FNT);
+
+ drawTextBox(dim, id);
+ const ScreenDim *dm = _screen->getScreenDim(dim);
+
+ int bx = ((dm->sx + dm->w) << 3) - ((strlen(_vm->_menuOkString) << 3) + 16);
+ int by = dm->sy + dm->h - 19;
+ int bw = (strlen(_vm->_menuOkString) << 3) + 7;
+
+ drawMenuButtonBox(bx, by, bw, 14, false, false);
+ _screen->printShadedText(_vm->_menuOkString, bx + 4, by + 3, buttonTextCol, 0);
+ _screen->updateScreen();
+
+ for (bool runLoop = true; runLoop && !_vm->shouldQuit();) {
+ int inputFlag = _vm->checkInput(0, false, 0) & 0x8ff;
+ _vm->removeInputTop();
+
+ if (inputFlag == 199 || inputFlag == 201) {
+ if (_vm->posWithinRect(_vm->_mouseX, _vm->_mouseY, bx, by, bx + bw, by + 14))
+ runLoop = false;
+ } else if (inputFlag == _vm->_keyMap[Common::KEYCODE_SPACE] || inputFlag == _vm->_keyMap[Common::KEYCODE_RETURN] || inputFlag == _vm->_keyMap[Common::KEYCODE_o]) {
+ runLoop = false;
+ }
+ }
+
+ drawMenuButtonBox(bx, by, bw, 14, true, true);
+ _screen->updateScreen();
+ _vm->_system->delayMillis(80);
+ drawMenuButtonBox(bx, by, bw, 14, false, true);
+ _screen->updateScreen();
+
+ _screen->copyRegion(0, dm->h, dm->sx << 3, dm->sy, dm->w << 3, dm->h, 2, 0, Screen::CR_NO_P_CHECK);
+ _screen->setScreenDim(od);
+ _screen->setFont(of);
+ dm = _screen->getScreenDim(dim);
+}
+
+void GUI_EoB::messageDialogue2(int dim, int id, int buttonTextCol) {
+ drawMenuButtonBox(_screen->_curDim->sx << 3, _screen->_curDim->sy, _screen->_curDim->w << 3, _screen->_curDim->h, false, false);
+
+ _screen->_curPage = 2;
+ _screen->setClearScreenDim(dim);
+ drawMenuButtonBox(_screen->_curDim->sx << 3, _screen->_curDim->sy, _screen->_curDim->w << 3, _screen->_curDim->h, false, false);
+ _screen->printShadedText(getMenuString(id), (_screen->_curDim->sx << 3) + 5, _screen->_curDim->sy + 5, 15, 0);
+ _screen->_curPage = 0;
+ _screen->copyRegion(_screen->_curDim->sx << 3, _screen->_curDim->sy, _screen->_curDim->sx << 3, _screen->_curDim->sy, _screen->_curDim->w << 3, _screen->_curDim->h, 2, 0, Screen::CR_NO_P_CHECK);
+
+ int x = (_screen->_curDim->sx << 3) + (_screen->_curDim->w << 2) - (strlen(_vm->_menuOkString) << 2);
+ int y = _screen->_curDim->sy + _screen->_curDim->h - 21;
+ int w = (strlen(_vm->_menuOkString) << 3) + 8;
+ drawMenuButtonBox(x, y, w, 14, false, false);
+ _screen->printShadedText(_vm->_menuOkString, x + 4, y + 3, buttonTextCol, 0);
+ _screen->updateScreen();
+
+ for (bool runLoop = true; runLoop && !_vm->shouldQuit();) {
+ int inputFlag = _vm->checkInput(0, false, 0) & 0x8ff;
+ _vm->removeInputTop();
+
+ if (inputFlag == 199 || inputFlag == 201) {
+ if (_vm->posWithinRect(_vm->_mouseX, _vm->_mouseY, x, y, x + w, y + 14))
+ runLoop = false;
+ } else if (inputFlag == _vm->_keyMap[Common::KEYCODE_SPACE] || inputFlag == _vm->_keyMap[Common::KEYCODE_RETURN] || inputFlag == _vm->_keyMap[Common::KEYCODE_o]) {
+ runLoop = false;
+ }
+ }
+
+ _vm->gui_drawBox(x, y, w, 14, _vm->guiSettings()->colors.frame2, _vm->guiSettings()->colors.fill, -1);
+ _screen->updateScreen();
+ _vm->_system->delayMillis(80);
+ drawMenuButtonBox(x, y, w, 14, false, false);
+ _screen->printShadedText(_vm->_menuOkString, x + 4, y + 3, buttonTextCol, 0);
+ _screen->updateScreen();
+
+}
+
+void GUI_EoB::updateBoxFrameHighLight(int box) {
+ if (_updateBoxIndex == box) {
+ if (_updateBoxIndex == -1)
+ return;
+
+ if (_vm->_system->getMillis() <= _highLightBoxTimer)
+ return;
+
+ if (!_highLightColorTable[_updateBoxColorIndex])
+ _updateBoxColorIndex = 0;
+
+ const EoBRect16 *r = &_highlightFrames[_updateBoxIndex];
+ _screen->drawBox(r->x1, r->y1, r->x2, r->y2, _highLightColorTable[_updateBoxColorIndex++]);
+ _screen->updateScreen();
+
+ _highLightBoxTimer = _vm->_system->getMillis() + _vm->_tickLength;
+
+ } else {
+ if (_updateBoxIndex != -1) {
+ const EoBRect16 *r = &_highlightFrames[_updateBoxIndex];
+ _screen->drawBox(r->x1, r->y1, r->x2, r->y2, 12);
+ _screen->updateScreen();
+ }
+
+ _updateBoxColorIndex = 0;
+ _updateBoxIndex = box;
+ _highLightBoxTimer = _vm->_system->getMillis();
+ }
+}
+
+int GUI_EoB::getTextInput(char *dest, int x, int y, int destMaxLen, int textColor1, int textColor2, int cursorColor) {
+#ifdef ENABLE_KEYMAPPER
+ Common::Keymapper *const keymapper = _vm->getEventManager()->getKeymapper();
+ keymapper->pushKeymap(Common::kGlobalKeymapName);
+#endif
+
+ uint8 cursorState = 1;
+ char sufx[] = " ";
+
+ int len = strlen(dest);
+ if (len > destMaxLen) {
+ len = destMaxLen;
+ dest[destMaxLen] = 0;
+ }
+
+ int pos = len;
+ if (len >= destMaxLen)
+ pos--;
+
+ _screen->copyRegion((x - 1) << 3, y, 0, 191, (destMaxLen + 2) << 3, 9, 0, 2, Screen::CR_NO_P_CHECK);
+ _screen->printShadedText(dest, x << 3, y, textColor1, textColor2);
+
+ uint32 next = _vm->_system->getMillis() + 2 * _vm->_tickLength;
+ sufx[0] = (pos < len) ? dest[pos] : 32;
+ _screen->printText(sufx, (x + pos) << 3, y, textColor1, cursorColor);
+
+ int in = 0;
+
+ do {
+ in = 0;
+ _keyPressed.reset();
+
+ while (!in && !_vm->shouldQuit()) {
+ if (next <= _vm->_system->getMillis()) {
+ if (cursorState) {
+ _screen->copyRegion((pos + 1) << 3, 191, (x + pos) << 3, y, 8, 9, 2, 0, Screen::CR_NO_P_CHECK);
+ _screen->printShadedText(sufx, (x + pos) << 3, y, textColor1, textColor2);
+ } else {
+ _screen->printText(sufx, (x + pos) << 3, y, textColor1, cursorColor);
+ }
+
+ _screen->updateScreen();
+ cursorState ^= 1;
+ next = _vm->_system->getMillis() + 2 * _vm->_tickLength;
+ }
+
+ _vm->updateInput();
+ for (Common::List<KyraEngine_v1::Event>::const_iterator evt = _vm->_eventList.begin(); evt != _vm->_eventList.end(); ++evt) {
+ if (evt->event.type == Common::EVENT_KEYDOWN) {
+ _keyPressed = evt->event.kbd;
+ in = _keyPressed.ascii;
+ }
+ }
+ _vm->removeInputTop();
+ }
+
+ if (_keyPressed.keycode == Common::KEYCODE_BACKSPACE) {
+ if (pos >= len && len > 0) {
+ dest[--len] = 0;
+ pos--;
+
+ } else if (pos > 0) {
+ for (int i = pos; i < destMaxLen; i++)
+ dest[i - 1] = dest[i];
+ dest[--len] = 0;
+ pos--;
+ }
+
+ } else if (_keyPressed.keycode == Common::KEYCODE_LEFT || _keyPressed.keycode == Common::KEYCODE_KP4) {
+ if (pos > 0)
+ pos--;
+
+ } else if (_keyPressed.keycode == Common::KEYCODE_RIGHT || _keyPressed.keycode == Common::KEYCODE_KP6) {
+ if (pos < len && pos < (destMaxLen - 1))
+ pos++;
+
+ } else if (in > 31 && in < 126) {
+ if (!(in == 32 && pos == 0)) {
+ if (in >= 97 && in <= 122)
+ in -= 32;
+
+ if (pos < len) {
+ for (int i = destMaxLen - 1; i >= pos; i--)
+ dest[i + 1] = dest[i];
+
+ dest[pos++] = in;
+
+ if (len == destMaxLen)
+ dest[len] = 0;
+
+ } else {
+ if (pos == destMaxLen) {
+ pos--;
+ len--;
+ }
+
+ dest[pos++] = in;
+ dest[pos] = 0;
+ }
+
+ if (++len > destMaxLen)
+ len = destMaxLen;
+
+ if (pos > (destMaxLen - 1))
+ pos = (destMaxLen - 1);
+ }
+ }
+
+ _screen->copyRegion(0, 191, (x - 1) << 3, y, (destMaxLen + 2) << 3, 9, 2, 0, Screen::CR_NO_P_CHECK);
+ _screen->printShadedText(dest, x << 3, y, textColor1, textColor2);
+ sufx[0] = (pos < len) ? dest[pos] : 32;
+
+ if (cursorState)
+ _screen->printText(sufx, (x + pos) << 3, y, textColor1, cursorColor);
+ else
+ _screen->printShadedText(sufx, (x + pos) << 3, y, textColor1, textColor2);
+ _screen->updateScreen();
+
+ } while (_keyPressed.keycode != Common::KEYCODE_RETURN && _keyPressed.keycode != Common::KEYCODE_ESCAPE && !_vm->shouldQuit());
+
+#ifdef ENABLE_KEYMAPPER
+ keymapper->popKeymap(Common::kGlobalKeymapName);
+#endif
+
+ return _keyPressed.keycode == Common::KEYCODE_ESCAPE ? -1 : len;
+}
+
+void GUI_EoB::transferWaitBox() {
+ const ScreenDim *dm = _screen->getScreenDim(11);
+ int xo = dm->sx;
+ int yo = dm->sy;
+ _screen->modifyScreenDim(11, dm->sx + 9, dm->sy + 24, dm->w, dm->h);
+ displayTextBox(-4);
+ _screen->modifyScreenDim(11, xo, yo, dm->w, dm->h);
+}
+
+Common::String GUI_EoB::transferTargetMenu(Common::Array<Common::String> &targets) {
+ if (_savegameList) {
+ for (int i = 0; i < _savegameListSize; i++)
+ delete[] _savegameList[i];
+ delete[] _savegameList;
+ }
+
+ _savegameListSize = targets.size();
+ _savegameList = new char*[_savegameListSize];
+ memset(_savegameList, 0, _savegameListSize * sizeof(char *));
+
+ Common::StringArray::iterator ii = targets.begin();
+ for (int i = 0; i < _savegameListSize; ++i) {
+ _savegameList[i] = new char[(*ii).size() + 1];
+ strcpy(_savegameList[i], (*ii++).c_str());
+ }
+
+ const ScreenDim *dm = _screen->getScreenDim(11);
+ int xo = dm->sx;
+ int yo = dm->sy;
+ _screen->modifyScreenDim(11, dm->sx + 9, dm->sy + 14, dm->w, dm->h);
+
+ int slot = 0;
+ do {
+ slot = selectSaveSlotDialogue(72, 14, 2);
+ if (slot == 6)
+ break;
+ } while (_saveSlotIdTemp[slot] == -1);
+
+ _screen->copyRegion(72, 14, 72, 14, 176, 144, _vm->_useHiResDithering ? 7 : 12, 0, Screen::CR_NO_P_CHECK);
+ _screen->modifyScreenDim(11, xo, yo, dm->w, dm->h);
+
+ return (slot < 6) ? _savegameList[_savegameOffset + slot] : Common::String();
+}
+
+bool GUI_EoB::transferFileMenu(Common::String &targetName, Common::String &selection) {
+ updateSaveSlotsList(targetName, true);
+ _saveSlotsListUpdateNeeded = true;
+ selection.clear();
+
+ if (!_savegameListSize)
+ return false;
+
+ const ScreenDim *dm = _screen->getScreenDim(11);
+ int xo = dm->sx;
+ int yo = dm->sy;
+ _screen->modifyScreenDim(11, dm->sx + 9, dm->sy + 14, dm->w, dm->h);
+
+ int slot = 0;
+ do {
+ slot = selectSaveSlotDialogue(72, 14, 4);
+ if (slot == 6)
+ break;
+
+ if (_saveSlotIdTemp[slot] == -1)
+ messageDialogue(11, 65, 6);
+ else {
+ _screen->modifyScreenDim(11, xo, yo, dm->w, dm->h);
+ selection = _vm->getSavegameFilename(targetName, _saveSlotIdTemp[slot]);
+ return true;
+ }
+ } while (_saveSlotIdTemp[slot] == -1);
+
+ _screen->modifyScreenDim(11, xo, yo, dm->w, dm->h);
+ return true;
+}
+
+void GUI_EoB::createScreenThumbnail(Graphics::Surface &dst) {
+ uint8 *screenPal = new uint8[768];
+ _screen->getRealPalette(0, screenPal);
+ uint16 width = Screen::SCREEN_W;
+ uint16 height = Screen::SCREEN_H;
+ if (_vm->_useHiResDithering) {
+ width <<= 1;
+ height <<= 1;
+ }
+
+ ::createThumbnail(&dst, _screen->getCPagePtr(7), width, height, screenPal);
+ delete[] screenPal;
+}
+
+void GUI_EoB::simpleMenu_initMenuItemsMask(int menuId, int maxItem, int32 menuItemsMask, int itemOffset) {
+ if (menuItemsMask == -1) {
+ _menuNumItems = _screen->getScreenDim(19 + menuId)->h;
+ _menuCur = _screen->getScreenDim(19 + menuId)->unk8;
+ return;
+ }
+
+ _menuNumItems = 0;
+
+ for (int i = 0; i < maxItem; i++) {
+ if (menuItemsMask & (1 << (i + itemOffset)))
+ _menuNumItems++;
+ }
+
+ _menuCur = 0;
+}
+
+bool GUI_EoB::runSaveMenu(int x, int y) {
+ const ScreenDim *dm = _screen->getScreenDim(11);
+ int xo = dm->sx;
+ int yo = dm->sy;
+ bool result = false;
+
+ _screen->modifyScreenDim(11, dm->sx + (x >> 3), dm->sy + y, dm->w, dm->h);
+
+ for (bool runLoop = true; runLoop && !_vm->shouldQuit();) {
+ updateSaveSlotsList(_vm->_targetName);
+ int slot = selectSaveSlotDialogue(x, y, 0);
+ if (slot > 5) {
+ runLoop = result = false;
+ } else if (slot >= 0) {
+ bool useSlot = (_saveSlotIdTemp[slot] == -1);
+ if (useSlot)
+ _saveSlotStringsTemp[slot][0] = 0;
+ else
+ useSlot = confirmDialogue2(11, 55, 1);
+
+ if (!useSlot)
+ continue;
+
+ int fx = (x + 1) << 3;
+ int fy = y + slot * 17 + 23;
+
+ for (int in = -1; in == -1 && !_vm->shouldQuit();) {
+ _screen->fillRect(fx - 2, fy, fx + 160, fy + 8, _vm->guiSettings()->colors.fill);
+ in = getTextInput(_saveSlotStringsTemp[slot], x + 1, fy, 19, 2, 0, 8);
+ if (!strlen(_saveSlotStringsTemp[slot])) {
+ messageDialogue(11, 54, 6);
+ in = -1;
+ }
+ };
+
+ _screen->fillRect(fx - 2, fy, fx + 160, fy + 8, _vm->guiSettings()->colors.fill);
+ _screen->printShadedText(_saveSlotStringsTemp[slot], (x + 1) << 3, fy, 15, 0);
+
+ Graphics::Surface thumb;
+ createScreenThumbnail(thumb);
+ Common::Error err = _vm->saveGameStateIntern(_savegameOffset + slot, _saveSlotStringsTemp[slot], &thumb);
+ thumb.free();
+
+ if (err.getCode() == Common::kNoError)
+ result = true;
+ else
+ messageDialogue(11, 15, 6);
+
+ runLoop = false;
+ }
+ }
+
+ _screen->modifyScreenDim(11, xo, yo, dm->w, dm->h);
+ return result;
+}
+
+int GUI_EoB::selectSaveSlotDialogue(int x, int y, int id) {
+ _saveSlotX = _saveSlotY = 0;
+ int col1 = (_vm->_configRenderMode == Common::kRenderCGA) ? 1 : 15;
+ _screen->setCurPage(2);
+
+ _savegameOffset = 0;
+
+ drawMenuButtonBox(0, 0, 176, 144, false, false);
+ const char *title = (id < 2) ? _vm->_saveLoadStrings[2 + id] : _vm->_transferStringsScummVM[id - 1];
+ _screen->printShadedText(title, 52, 5, col1, 0);
+
+ _screen->copyRegion(0, 0, x, y, 176, 144, 2, 0, Screen::CR_NO_P_CHECK);
+ _screen->setCurPage(0);
+ _screen->updateScreen();
+
+ _saveSlotX = x;
+ _saveSlotY = y;
+ int lastHighlight = -1;
+ int lastOffset = -1;
+ int newHighlight = 0;
+ int slot = -1;
+
+ for (bool runLoop = true; runLoop && !_vm->shouldQuit();) {
+ int inputFlag = _vm->checkInput(0, false, 0) & 0x8ff;
+ _vm->removeInputTop();
+
+ if (inputFlag == _vm->_keyMap[Common::KEYCODE_SPACE] || inputFlag == _vm->_keyMap[Common::KEYCODE_RETURN]) {
+ runLoop = false;
+ } else if (inputFlag == _vm->_keyMap[Common::KEYCODE_ESCAPE]) {
+ newHighlight = 6;
+ runLoop = false;
+ } else if (inputFlag == _vm->_keyMap[Common::KEYCODE_DOWN] || inputFlag == _vm->_keyMap[Common::KEYCODE_KP2]) {
+ if (++newHighlight > 5) {
+ newHighlight = 5;
+ if (++_savegameOffset > 984)
+ _savegameOffset = 984;
+ else
+ lastOffset = -1;
+ }
+ } else if (inputFlag == _vm->_keyMap[Common::KEYCODE_UP] || inputFlag == _vm->_keyMap[Common::KEYCODE_KP8]) {
+ if (--newHighlight < 0) {
+ newHighlight = 0;
+ if (--_savegameOffset < 0)
+ _savegameOffset = 0;
+ else
+ lastOffset = -1;
+ }
+ } else if (inputFlag == _vm->_keyMap[Common::KEYCODE_PAGEDOWN] || inputFlag == _vm->_keyMap[Common::KEYCODE_KP1]) {
+ _savegameOffset += 6;
+ if (_savegameOffset > 984)
+ _savegameOffset = 984;
+ else
+ lastOffset = -1;
+ } else if (inputFlag == _vm->_keyMap[Common::KEYCODE_PAGEUP] || inputFlag == _vm->_keyMap[Common::KEYCODE_KP7]) {
+ _savegameOffset -= 6;
+ if (_savegameOffset < 0)
+ _savegameOffset = 0;
+ else
+ lastOffset = -1;
+ } else if (inputFlag == 205) {
+ if (++_savegameOffset > 984)
+ _savegameOffset = 984;
+ else
+ lastOffset = -1;
+ } else if (inputFlag == 203) {
+ if (--_savegameOffset < 0)
+ _savegameOffset = 0;
+ else
+ lastOffset = -1;
+ } else {
+ slot = getHighlightSlot();
+ if (slot != -1) {
+ newHighlight = slot;
+ if (inputFlag == 199)
+ runLoop = false;
+ }
+ }
+
+ if (lastOffset != _savegameOffset) {
+ lastHighlight = -1;
+ setupSaveMenuSlots();
+ for (int i = 0; i < 7; i++)
+ drawSaveSlotButton(i, 1, col1);
+ lastOffset = _savegameOffset;
+ }
+
+ if (lastHighlight != newHighlight) {
+ drawSaveSlotButton(lastHighlight, 0, col1);
+ drawSaveSlotButton(newHighlight, 0, 6);
+
+ // Display highlighted slot index in the bottom left corner to avoid people getting lost with the 990 save slots
+ _screen->setFont(Screen::FID_6_FNT);
+ int sli = (newHighlight == 6) ? _savegameOffset : (_savegameOffset + newHighlight);
+ _screen->printText(Common::String::format("%03d/989", sli).c_str(), _saveSlotX + 5, _saveSlotY + 135, _vm->guiSettings()->colors.frame2, _vm->guiSettings()->colors.fill);
+ _screen->setFont(Screen::FID_8_FNT);
+
+ _screen->updateScreen();
+ lastHighlight = newHighlight;
+ }
+ }
+
+ drawSaveSlotButton(newHighlight, 2, 6);
+ _screen->updateScreen();
+ _vm->_system->delayMillis(80);
+ drawSaveSlotButton(newHighlight, 1, 6);
+ _screen->updateScreen();
+
+ return newHighlight;
+}
+
+void GUI_EoB::runMemorizePrayMenu(int charIndex, int spellType) {
+ if (charIndex == -1)
+ return;
+
+ uint8 np[8];
+ memset(np, 0, sizeof(np));
+ uint32 avltyFlags = 0;
+ int li = 0;
+ int lv = 0;
+
+ EoBCharacter *c = &_vm->_characters[charIndex];
+ int8 wm = c->wisdomCur - 12;
+ if (wm < 0)
+ wm = 0;
+
+ if (spellType) {
+ li = _vm->getCharacterLevelIndex(2, c->cClass);
+
+ if (li == -1) {
+ li = _vm->getCharacterLevelIndex(4, c->cClass);
+
+ if (li != -1) {
+ lv = c->level[li] - 1;
+ if (lv < 0)
+ lv = 0;
+
+ for (int i = 0; i < _numPages; i++)
+ np[i] = _vm->_numSpellsPal[lv * _numPages + i];
+
+ avltyFlags = _paladinSpellAvltyFlags;
+ }
+
+ } else {
+ lv = c->level[li] - 1;
+ for (int i = 0; i < _numPages; i++) {
+ np[i] = _vm->_numSpellsCleric[lv * _numPages + i];
+ if (np[i])
+ np[i] += _vm->_numSpellsWisAdj[wm * _numPages + i];
+ }
+ avltyFlags = _clericSpellAvltyFlags;
+ }
+
+ } else {
+ li = _vm->getCharacterLevelIndex(1, c->cClass);
+
+ if (li == -1) {
+ if (_vm->checkInventoryForRings(charIndex, 1)) {
+ np[3] <<= 1;
+ np[4] <<= 1;
+ }
+
+ } else {
+ lv = c->level[li] - 1;
+ for (int i = 0; i < _numPages; i++)
+ np[i] = _vm->_numSpellsMage[lv * _numPages + i];
+
+ avltyFlags = c->mageSpellsAvailableFlags;
+ }
+ }
+
+ int8 *menuSpellMap = new int8[88];
+ memset(menuSpellMap, 0, 88);
+ int8 *numAssignedSpellsPerBookPage = new int8[8];
+ memset(numAssignedSpellsPerBookPage, 0, 8);
+ memset(_numAssignedSpellsOfType, 0, 72);
+ int8 *lh = new int8[40];
+ memset(lh, 0, 40);
+
+ memcpy(lh, spellType ? _vm->_spellLevelsCleric : _vm->_spellLevelsMage, spellType ? _vm->_spellLevelsClericSize : _vm->_spellLevelsMageSize);
+ int8 *charSpellList = spellType ? c->clericSpells : c->mageSpells;
+
+ for (int i = 0; i < 80; i++) {
+ int8 s = charSpellList[i];
+ if (s == 0 || (_vm->game() == GI_EOB2 && s == 29))
+ continue;
+
+ if (s < 0)
+ s = -s;
+ else
+ _numAssignedSpellsOfType[s * 2 - 1]++;
+
+ s--;
+ _numAssignedSpellsOfType[s * 2]++;
+ numAssignedSpellsPerBookPage[lh[s] - 1]++;
+ }
+
+ for (int i = 0; i < 32; i++) {
+ if (!(avltyFlags & (1 << i)))
+ continue;
+
+ int d = lh[i] - 1;
+ if (d < 0)
+ continue;
+
+ if (!spellType || (spellType && np[d])) {
+ menuSpellMap[d * 11]++;
+ menuSpellMap[d * 11 + menuSpellMap[d * 11]] = i + 1;
+ }
+ }
+
+ Button *buttonList = initMenu(4);
+
+ int lastHighLightText = -1;
+ int lastHighLightButton = -1;
+ int newHighLightButton = 0;
+ int newHighLightText = 0;
+ bool updateDesc = true;
+ bool updateList = true;
+
+ for (bool runLoop = true; runLoop && !_vm->shouldQuit();) {
+ updateBoxFrameHighLight(charIndex);
+
+ if (newHighLightButton < 0)
+ newHighLightButton = 7;
+ if (newHighLightButton > 7)
+ newHighLightButton = 0;
+
+ Button *b = 0;
+
+ if (lastHighLightButton != newHighLightButton) {
+ if (lastHighLightButton >= 0)
+ drawMenuButton(_vm->gui_getButton(buttonList, lastHighLightButton + 26), false, false, true);
+ drawMenuButton(_vm->gui_getButton(buttonList, newHighLightButton + 26), false, true, true);
+ newHighLightText = 0;
+ lastHighLightText = -1;
+ lastHighLightButton = newHighLightButton;
+ updateDesc = updateList = true;
+ }
+
+ if (updateList) {
+ updateList = false;
+ _screen->setCurPage(2);
+ for (int ii = 1; ii < 9; ii++)
+ memorizePrayMenuPrintString(menuSpellMap[lastHighLightButton * 11 + ii], ii - 1, spellType, false, false);
+
+ _screen->setCurPage(0);
+ _screen->copyRegion(0, 50, 0, 50, 176, 72, 2, 0, Screen::CR_NO_P_CHECK);
+ lastHighLightText = -1;
+ }
+
+ if (updateDesc) {
+ updateDesc = false;
+ _screen->printShadedText(Common::String::format(_vm->_menuStringsMgc[1], np[lastHighLightButton] - numAssignedSpellsPerBookPage[lastHighLightButton], np[lastHighLightButton]).c_str(), 8, 38, 9, _vm->guiSettings()->colors.fill);
+ }
+
+ if (newHighLightText < 0)
+ newHighLightText = menuSpellMap[lastHighLightButton * 11] - 1;
+
+ if (menuSpellMap[lastHighLightButton * 11] <= newHighLightText)
+ newHighLightText = 0;
+
+ if (newHighLightText != lastHighLightText) {
+ memorizePrayMenuPrintString(menuSpellMap[lastHighLightButton * 11 + lastHighLightText + 1], lastHighLightText, spellType, true, false);
+ memorizePrayMenuPrintString(menuSpellMap[lastHighLightButton * 11 + newHighLightText + 1], newHighLightText, spellType, true, true);
+ lastHighLightText = newHighLightText;
+ }
+
+ int inputFlag = _vm->checkInput(buttonList, false, 0) & 0x80ff;
+ _vm->removeInputTop();
+
+ if (inputFlag == _vm->_keyMap[Common::KEYCODE_KP6] || inputFlag == _vm->_keyMap[Common::KEYCODE_RIGHT]) {
+ inputFlag = 0x801a + ((lastHighLightButton + 1) % _numVisPages);
+ } else if (inputFlag == _vm->_keyMap[Common::KEYCODE_KP4] || inputFlag == _vm->_keyMap[Common::KEYCODE_LEFT]) {
+ inputFlag = lastHighLightButton ? 0x8019 + lastHighLightButton : 0x8019 + _numVisPages;
+ } else if (inputFlag == _vm->_keyMap[Common::KEYCODE_ESCAPE]) {
+ inputFlag = 0x8018;
+ } else {
+ Common::Point p = _vm->getMousePos();
+ if (_vm->posWithinRect(p.x, p.y, 8, 50, 168, 122)) {
+ newHighLightText = (p.y - 50) / 9;
+ if (menuSpellMap[lastHighLightButton * 11] - 1 < newHighLightText)
+ newHighLightText = menuSpellMap[lastHighLightButton * 11] - 1;
+ }
+ }
+
+ if (inputFlag & 0x8000) {
+ b = _vm->gui_getButton(buttonList, inputFlag & 0x7fff);
+ drawMenuButton(b, true, true, true);
+ _screen->updateScreen();
+ _vm->_system->delayMillis(80);
+ drawMenuButton(b, false, false, true);
+ _screen->updateScreen();
+ }
+
+ if (inputFlag == 0x8019 || inputFlag == _vm->_keyMap[Common::KEYCODE_KP_PLUS] || inputFlag == _vm->_keyMap[Common::KEYCODE_PLUS] || inputFlag == _vm->_keyMap[Common::KEYCODE_KP5] || inputFlag == _vm->_keyMap[Common::KEYCODE_SPACE] || inputFlag == _vm->_keyMap[Common::KEYCODE_RETURN]) {
+ if (np[lastHighLightButton] > numAssignedSpellsPerBookPage[lastHighLightButton] && lastHighLightText != -1) {
+ _numAssignedSpellsOfType[menuSpellMap[lastHighLightButton * 11 + lastHighLightText + 1] * 2 - 2]++;
+ numAssignedSpellsPerBookPage[lastHighLightButton]++;
+ memorizePrayMenuPrintString(menuSpellMap[lastHighLightButton * 11 + lastHighLightText + 1], lastHighLightText, spellType, false, true);
+ updateDesc = true;
+ }
+
+ } else if (inputFlag == _vm->_keyMap[Common::KEYCODE_KP_MINUS] || inputFlag == _vm->_keyMap[Common::KEYCODE_MINUS]) {
+ if (np[lastHighLightButton] && _numAssignedSpellsOfType[menuSpellMap[lastHighLightButton * 11 + lastHighLightText + 1] * 2 - 2]) {
+ _numAssignedSpellsOfType[menuSpellMap[lastHighLightButton * 11 + lastHighLightText + 1] * 2 - 2]--;
+ numAssignedSpellsPerBookPage[lastHighLightButton]--;
+ memorizePrayMenuPrintString(menuSpellMap[lastHighLightButton * 11 + lastHighLightText + 1], lastHighLightText, spellType, false, true);
+ updateDesc = true;
+ }
+
+ } else if (inputFlag == _vm->_keyMap[Common::KEYCODE_UP] || inputFlag == _vm->_keyMap[Common::KEYCODE_KP8]) {
+ newHighLightText = lastHighLightText - 1;
+ } else if (inputFlag == _vm->_keyMap[Common::KEYCODE_DOWN] || inputFlag == _vm->_keyMap[Common::KEYCODE_KP2]) {
+ newHighLightText = lastHighLightText + 1;
+ } else if (inputFlag == _vm->_keyMap[Common::KEYCODE_END] || inputFlag == _vm->_keyMap[Common::KEYCODE_KP1]) {
+ newHighLightText = menuSpellMap[lastHighLightButton * 11] - 1;
+ } else if (inputFlag == _vm->_keyMap[Common::KEYCODE_HOME] || inputFlag == _vm->_keyMap[Common::KEYCODE_KP7]) {
+ newHighLightText = 0;
+ } else if (inputFlag == 0x8017) {
+ if (numAssignedSpellsPerBookPage[lastHighLightButton]) {
+ for (int i = 1; i <= menuSpellMap[lastHighLightButton * 11]; i++) {
+ numAssignedSpellsPerBookPage[lastHighLightButton] -= _numAssignedSpellsOfType[menuSpellMap[lastHighLightButton * 11 + i] * 2 - 2];
+ _numAssignedSpellsOfType[menuSpellMap[lastHighLightButton * 11 + i] * 2 - 2] = 0;
+ }
+
+ updateDesc = updateList = true;
+ }
+
+ } else if (inputFlag == 0x8018) {
+ _vm->gui_drawAllCharPortraitsWithStats();
+ runLoop = false;
+
+ } else if (inputFlag & 0x8000) {
+ newHighLightButton = inputFlag - 0x801a;
+ if (newHighLightButton == lastHighLightButton)
+ drawMenuButton(_vm->gui_getButton(buttonList, inputFlag & 0x7fff), false, true, true);
+ }
+ }
+
+ releaseButtons(buttonList);
+ updateBoxFrameHighLight(-1);
+
+ _screen->setFont(Screen::FID_6_FNT);
+ _vm->gui_drawCharPortraitWithStats(charIndex);
+ _screen->setFont(Screen::FID_8_FNT);
+
+ memset(charSpellList, 0, 80);
+ if (spellType && _vm->game() == GI_EOB2)
+ charSpellList[0] = 29;
+
+ for (int i = 0; i < 32; i++) {
+ if (_numAssignedSpellsOfType[i * 2] < _numAssignedSpellsOfType[i * 2 + 1])
+ _numAssignedSpellsOfType[i * 2 + 1] = _numAssignedSpellsOfType[i * 2];
+
+ if (_numAssignedSpellsOfType[i * 2 + 1]) {
+ _numAssignedSpellsOfType[i * 2]--;
+ _numAssignedSpellsOfType[i * 2 + 1]--;
+
+ int pg = lh[i] - 1;
+ for (int ii = 0; ii < 10; ii++) {
+ if (!charSpellList[pg * 10 + ii]) {
+ charSpellList[pg * 10 + ii] = i + 1;
+ break;
+ }
+ }
+ i--;
+
+ } else if (_numAssignedSpellsOfType[i * 2]) {
+ _numAssignedSpellsOfType[i * 2]--;
+
+ _needRest = true;
+ int pg = lh[i] - 1;
+ for (int ii = 0; ii < 10; ii++) {
+ if (!charSpellList[pg * 10 + ii]) {
+ charSpellList[pg * 10 + ii] = -(i + 1);
+ break;
+ }
+ }
+ i--;
+ }
+ }
+
+ delete[] menuSpellMap;
+ delete[] numAssignedSpellsPerBookPage;
+ delete[] lh;
+}
+
+
+void GUI_EoB::scribeScrollDialogue() {
+ int16 *scrollInvSlot = new int16[32];
+ int16 *scrollCharacter = new int16[32];
+ int16 *menuItems = new int16[6];
+ int numScrolls = 0;
+
+ for (int i = 0; i < 32; i++) {
+ for (int ii = 0; ii < 6; ii++) {
+ scrollInvSlot[i] = _vm->checkInventoryForItem(ii, 34, i + 1) + 1;
+ if (scrollInvSlot[i] > 0) {
+ numScrolls++;
+ scrollCharacter[i] = ii;
+ break;
+ }
+ }
+ }
+
+ if (numScrolls) {
+ int csel = selectCharacterDialogue(49);
+ if (csel != -1) {
+
+ EoBCharacter *c = &_vm->_characters[csel];
+ int s = 0;
+
+ for (int i = 0; i < 32 && s < 6; i++) {
+ if (!scrollInvSlot[i])
+ continue;
+
+ if (c->mageSpellsAvailableFlags & (1 << i))
+ scrollInvSlot[i] = 0;
+ else
+ menuItems[s++] = i + 1;
+ }
+
+ if (s) {
+ Button *buttonList = 0;
+ bool redraw = true;
+ int lastHighLight = -1;
+ int newHighLight = 0;
+
+ while (s && !_vm->shouldQuit()) {
+ if (redraw) {
+ s = 0;
+ for (int i = 0; i < 32 && s < 6; i++) {
+ if (!scrollInvSlot[i])
+ continue;
+ menuItems[s++] = i + 1;
+ }
+
+ if (!s)
+ break;
+
+ releaseButtons(buttonList);
+ buttonList = initMenu(6);
+
+ for (int i = 0; i < s; i++)
+ _screen->printShadedText(_vm->_mageSpellList[menuItems[i]], 8, 9 * i + 50, 15, 0);
+
+ redraw = false;
+ lastHighLight = -1;
+ newHighLight = 0;
+ }
+
+ if (lastHighLight != newHighLight) {
+ if (lastHighLight >= 0)
+ _screen->printText(_vm->_mageSpellList[menuItems[lastHighLight]], 8, 9 * lastHighLight + 50, 15, 0);
+ lastHighLight = newHighLight;
+ _screen->printText(_vm->_mageSpellList[menuItems[lastHighLight]], 8, 9 * lastHighLight + 50, 6, 0);
+ _screen->updateScreen();
+ }
+
+ int inputFlag = _vm->checkInput(buttonList, false, 0);
+ _vm->removeInputTop();
+
+ if (inputFlag == 0) {
+ Common::Point p = _vm->getMousePos();
+ if (_vm->posWithinRect(p.x, p.y, 8, 50, 176, s * 9 + 49))
+ newHighLight = (p.y - 50) / 9;
+ } else if (inputFlag == _vm->_keyMap[Common::KEYCODE_KP2] || inputFlag == _vm->_keyMap[Common::KEYCODE_DOWN]) {
+ newHighLight = (newHighLight + 1) % s;
+ } else if (inputFlag == _vm->_keyMap[Common::KEYCODE_KP8] || inputFlag == _vm->_keyMap[Common::KEYCODE_UP]) {
+ newHighLight = (newHighLight + s - 1) % s;
+ } else if (inputFlag == 0x8023 || inputFlag == _vm->_keyMap[Common::KEYCODE_ESCAPE]) {
+ s = 0;
+ } else if (inputFlag == 0x8024) {
+ newHighLight = (_vm->_mouseY - 50) / 9;
+ if (newHighLight >= 0 && newHighLight < s) {
+ inputFlag = _vm->_keyMap[Common::KEYCODE_SPACE];
+ } else {
+ inputFlag = 0;
+ newHighLight = lastHighLight;
+ }
+ }
+
+ if (inputFlag == _vm->_keyMap[Common::KEYCODE_SPACE] || inputFlag == _vm->_keyMap[Common::KEYCODE_RETURN] || inputFlag == _vm->_keyMap[Common::KEYCODE_KP5]) {
+ int t = menuItems[newHighLight] - 1;
+ Item scItem = _vm->_characters[scrollCharacter[t]].inventory[scrollInvSlot[t] - 1];
+ c->mageSpellsAvailableFlags |= (1 << t);
+ _vm->_characters[scrollCharacter[t]].inventory[scrollInvSlot[t] - 1] = 0;
+ _vm->gui_drawCharPortraitWithStats(_vm->_characters[scrollCharacter[t]].id);
+ scrollInvSlot[t] = 0;
+ _vm->_items[scItem].block = -1;
+ redraw = true;
+ s--;
+ }
+ }
+
+ releaseButtons(buttonList);
+
+ } else {
+ displayTextBox(51);
+ }
+ }
+ } else {
+ displayTextBox(50);
+ }
+
+ delete[] menuItems;
+ delete[] scrollCharacter;
+ delete[] scrollInvSlot;
+}
+
+bool GUI_EoB::restParty() {
+ static const int8 eob1healSpells[] = { 2, 15, 20, 24 };
+ static const int8 eob2healSpells[] = { 3, 16, 20, 28 };
+ const int8 *spells = _vm->game() == GI_EOB1 ? eob1healSpells : eob2healSpells;
+
+ uint8 crs[6];
+ memset(crs, 0, 6);
+ int hours = 0;
+
+ if (_vm->_inf->preventRest()) {
+ assert(_vm->_menuStringsRest3[0]);
+ _vm->restParty_displayWarning(_vm->_menuStringsRest3[0]);
+ return true;
+ }
+
+ if (_vm->restParty_updateMonsters())
+ return true;
+
+ if (_vm->restParty_extraAbortCondition())
+ return true;
+
+ drawMenuButtonBox(_screen->_curDim->sx << 3, _screen->_curDim->sy, _screen->_curDim->w << 3, _screen->_curDim->h, false, false);
+
+ int nonPoisoned = 0;
+ for (int i = 0; i < 6; i++) {
+ if (!_vm->testCharacter(i, 1))
+ continue;
+ nonPoisoned |= _vm->testCharacter(i, 0x10);
+ }
+
+ if (!nonPoisoned) {
+ if (!confirmDialogue(59))
+ return false;
+ }
+
+ int8 *list = 0;
+ bool useHealers = false;
+ bool res = false;
+ bool restLoop = true;
+ bool restContinue = false;
+ int injured = _vm->restParty_getCharacterWithLowestHp();
+
+ if (injured > 0) {
+ for (int i = 0; i < 6; i++) {
+ if (!_vm->testCharacter(i, 13))
+ continue;
+ if (_vm->getCharacterLevelIndex(2, _vm->_characters[i].cClass) == -1 && _vm->getCharacterLevelIndex(4, _vm->_characters[i].cClass) == -1)
+ continue;
+ if (_vm->checkInventoryForItem(i, 30, -1) == -1)
+ continue;
+ if (_vm->restParty_checkHealSpells(i)) {
+ useHealers = confirmDialogue(40);
+ break;
+ }
+ }
+ }
+
+ _screen->setClearScreenDim(7);
+ _screen->setFont(Screen::FID_6_FNT);
+
+ restParty_updateRestTime(hours, true);
+
+ for (int l = 0; !res && restLoop && !_vm->shouldQuit();) {
+ l++;
+
+ // Regenerate spells
+ for (int i = 0; i < 6; i++) {
+ crs[i]++;
+
+ if (!_vm->_characters[i].food)
+ continue;
+ if (!_vm->testCharacter(i, 5))
+ continue;
+
+ if (_vm->checkInventoryForItem(i, 30, -1) != -1) {
+ list = _vm->_characters[i].clericSpells;
+
+ for (int ii = 0; ii < 80; ii++) {
+ if ((ii / 10 + 48) >= crs[i])
+ break;
+
+ if (*list >= 0) {
+ list++;
+ continue;
+ }
+
+ *list *= -1;
+ crs[i] = 48;
+ _vm->_txt->printMessage(Common::String::format(_vm->_menuStringsRest2[0], _vm->_characters[i].name, _vm->_spells[_vm->_clericSpellOffset + *list].name).c_str());
+ _vm->delay(80);
+ break;
+ }
+ }
+
+ if (_vm->checkInventoryForItem(i, 29, -1) != -1) {
+ list = _vm->_characters[i].mageSpells;
+
+ for (int ii = 0; ii < 80; ii++) {
+ if ((ii / 6 + 48) >= crs[i])
+ break;
+
+ if (*list >= 0) {
+ list++;
+ continue;
+ }
+
+ *list *= -1;
+ crs[i] = 48;
+ _vm->_txt->printMessage(Common::String::format(_vm->_menuStringsRest2[1], _vm->_characters[i].name, _vm->_spells[*list].name).c_str());
+ _vm->delay(80);
+ break;
+ }
+ }
+ }
+
+ // Heal party members
+ if (useHealers) {
+ for (int i = 0; i < 6 && injured; i++) {
+ if (_vm->getCharacterLevelIndex(2, _vm->_characters[i].cClass) == -1 && _vm->getCharacterLevelIndex(4, _vm->_characters[i].cClass) == -1)
+ continue;
+ if (_vm->checkInventoryForItem(i, 30, -1) == -1)
+ continue;
+
+ list = 0;
+ if (crs[i] >= 48) {
+ for (int ii = 0; !list && ii < 3; ii++)
+ list = (int8 *)memchr(_vm->_characters[i].clericSpells, -spells[ii], 80);
+ }
+
+ if (list)
+ break;
+
+ list = _vm->_characters[i].clericSpells;
+ for (int ii = 0; ii < 80 && injured; ii++) {
+ int healHp = 0;
+ if (*list == spells[0])
+ healHp = _vm->rollDice(1, 8, 0);
+ else if (*list == spells[1])
+ healHp = _vm->rollDice(2, 8, 1);
+ else if (*list == spells[2])
+ healHp = _vm->rollDice(3, 8, 3);
+
+ if (!healHp) {
+ list++;
+ continue;
+ }
+
+ *list *= -1;
+ list++;
+
+ crs[i] = 0;
+ injured--;
+
+ _vm->_txt->printMessage(Common::String::format(_vm->_menuStringsRest2[2], _vm->_characters[i].name, _vm->_characters[injured].name).c_str());
+ _vm->delay(80);
+
+ _vm->_characters[injured].hitPointsCur += healHp;
+ if (_vm->_characters[injured].hitPointsCur > _vm->_characters[injured].hitPointsMax)
+ _vm->_characters[injured].hitPointsCur = _vm->_characters[injured].hitPointsMax;
+
+ _vm->gui_drawCharPortraitWithStats(injured++);
+ }
+ }
+ }
+
+ if (l == 6) {
+ l = 0;
+ restParty_updateRestTime(++hours, false);
+ _vm->_restPartyElapsedTime += (32760 * _vm->_tickLength);
+
+ // Update poisoning
+ for (int i = 0; i < 6; i++) {
+ if (!_vm->testCharacter(i, 1))
+ continue;
+ if (_vm->testCharacter(i, 16))
+ continue;
+ _vm->inflictCharacterDamage(i, 10);
+ _vm->delayWithTicks(5);
+ }
+
+ if (!(hours % 8)) {
+ bool starving = false;
+ for (int i = 0; i < 6; i++) {
+ // Add Lay On Hands spell
+ if (_vm->_characters[i].cClass == 2) {
+ list = (int8 *)memchr(_vm->_characters[i].clericSpells, spells[3], 10);
+ if (list) {
+ *list = spells[3];
+ } else {
+ list = (int8 *)memchr(_vm->_characters[i].clericSpells, -spells[3], 10);
+ if (list) {
+ *list = spells[3];
+ } else if (!memchr(_vm->_characters[i].clericSpells, spells[3], 10)) {
+ list = (int8 *)memchr(_vm->_characters[i].clericSpells, 0, 10);
+ *list = spells[3];
+ }
+ }
+ }
+
+ if (!_vm->testCharacter(i, 3))
+ continue;
+
+ // Update hitpoints and food status
+ if (_vm->_characters[i].food) {
+ if (_vm->_characters[i].hitPointsCur < _vm->_characters[i].hitPointsMax) {
+ _vm->_characters[i].hitPointsCur++;
+ _screen->setFont(Screen::FID_6_FNT);
+ _vm->gui_drawCharPortraitWithStats(i);
+ }
+
+ if (!_vm->checkInventoryForRings(i, 2)) {
+ if (_vm->_characters[i].food <= 5) {
+ _vm->_characters[i].food = 0;
+ starving = true;
+ } else {
+ _vm->_characters[i].food -= 5;
+ }
+ }
+ } else {
+ if ((hours % 24) || (_vm->_characters[i].hitPointsCur <= -10))
+ continue;
+ _vm->inflictCharacterDamage(i, 1);
+ starving = true;
+ _screen->setFont(Screen::FID_6_FNT);
+ _vm->gui_drawCharPortraitWithStats(i);
+ }
+ }
+
+ if (starving) {
+ if (!confirmDialogue(47)) {
+ restContinue = false;
+ restLoop = false;
+ }
+ restParty_updateRestTime(hours, true);
+ }
+ injured = restLoop ? _vm->restParty_getCharacterWithLowestHp() : 0;
+ }
+ }
+
+ if (!_vm->restParty_checkSpellsToLearn() && restLoop && !restContinue && injured) {
+ restContinue = confirmDialogue(41);
+ restParty_updateRestTime(hours, true);
+ if (!restContinue)
+ restLoop = false;
+ }
+
+ int in = _vm->checkInput(0, false, 0);
+ _vm->removeInputTop();
+ if (in)
+ restLoop = false;
+
+ if (restLoop) {
+ res = _vm->restParty_updateMonsters();
+ if (!res)
+ res = _vm->checkPartyStatus(false);
+ }
+
+ if (!_vm->restParty_checkSpellsToLearn()) {
+ if (!restContinue) {
+ if (!useHealers)
+ restLoop = false;
+ }
+ if (!injured)
+ restLoop = false;
+ }
+ }
+
+ _vm->removeInputTop();
+ _screen->setScreenDim(4);
+ _screen->setFont(Screen::FID_8_FNT);
+
+ if (!res) {
+ if (!injured)
+ displayTextBox(43);
+ if (hours > 4)
+ _vm->restParty_npc();
+ }
+
+ return res;
+}
+
+bool GUI_EoB::confirmDialogue(int id) {
+ int od = _screen->curDimIndex();
+ Screen::FontId of = _screen->setFont(Screen::FID_8_FNT);
+
+ Button *buttonList = initMenu(5);
+
+ _screen->printShadedText(getMenuString(id), (_screen->_curDim->sx + 1) << 3, _screen->_curDim->sy + 4, 15, 0);
+
+ int newHighlight = 0;
+ int lastHighlight = -1;
+ bool result = false;
+
+ for (bool runLoop = true; runLoop && !_vm->shouldQuit();) {
+ if (newHighlight != lastHighlight) {
+ if (lastHighlight != -1)
+ drawMenuButton(_vm->gui_getButton(buttonList, lastHighlight + 33), false, false, true);
+ drawMenuButton(_vm->gui_getButton(buttonList, newHighlight + 33), false, true, true);
+ _screen->updateScreen();
+ lastHighlight = newHighlight;
+ }
+
+ int inputFlag = _vm->checkInput(buttonList, false, 0) & 0x80ff;
+ _vm->removeInputTop();
+
+ if (inputFlag == _vm->_keyMap[Common::KEYCODE_KP5] || inputFlag == _vm->_keyMap[Common::KEYCODE_SPACE] || inputFlag == _vm->_keyMap[Common::KEYCODE_RETURN]) {
+ result = lastHighlight ? false : true;
+ inputFlag = 0x8021 + lastHighlight;
+ runLoop = false;
+ } else if (inputFlag == _vm->_keyMap[Common::KEYCODE_KP4] || inputFlag == _vm->_keyMap[Common::KEYCODE_LEFT] || inputFlag == _vm->_keyMap[Common::KEYCODE_KP6] || inputFlag == _vm->_keyMap[Common::KEYCODE_RIGHT]) {
+ newHighlight ^= 1;
+ } else if (inputFlag == 0x8021) {
+ result = true;
+ runLoop = false;
+ } else if (inputFlag == 0x8022) {
+ result = false;
+ runLoop = false;
+ } else {
+ Common::Point p = _vm->getMousePos();
+ for (Button *b = buttonList; b; b = b->nextButton) {
+ if ((b->arg & 2) && _vm->posWithinRect(p.x, p.y, b->x, b->y, b->x + b->width, b->y + b->height))
+ newHighlight = b->index - 33;
+ }
+ }
+
+ if (!runLoop) {
+ Button *b = _vm->gui_getButton(buttonList, lastHighlight + 33);
+ drawMenuButton(b, true, true, true);
+ _screen->updateScreen();
+ _vm->_system->delayMillis(80);
+ drawMenuButton(b, false, true, true);
+ _screen->updateScreen();
+ }
+ }
+
+ releaseButtons(buttonList);
+
+ _screen->setFont(of);
+ _screen->setScreenDim(od);
+
+ return result;
+}
+
+int GUI_EoB::selectCharacterDialogue(int id) {
+ uint8 flags = (id == 26) ? (_vm->game() == GI_EOB1 ? 0x04 : 0x14) : 0x02;
+ _vm->removeInputTop();
+
+ _charSelectRedraw = false;
+ bool starvedUnconscious = false;
+ int count = 0;
+ int result = -1;
+ int found[6];
+
+ for (int i = 0; i < 6; i++) {
+ found[i] = -1;
+
+ if (!_vm->testCharacter(i, 1))
+ continue;
+
+ if (!(_vm->_classModifierFlags[_vm->_characters[i].cClass] & flags) && (id != 53))
+ continue;
+
+ if (id != 53 && (!_vm->_characters[i].food || !_vm->testCharacter(i, 4))) {
+ starvedUnconscious = true;
+ } else {
+ found[i] = 0;
+ result = i;
+ count++;
+ }
+ }
+
+ if (!count) {
+ int eid = 0;
+ if (id == 23)
+ eid = (starvedUnconscious || _vm->game() == GI_EOB1) ? 28 : 72;
+ else if (id == 26)
+ eid = (starvedUnconscious || _vm->game() == GI_EOB1) ? 27 : 73;
+ else if (id == 49)
+ eid = 52;
+
+ displayTextBox(eid);
+ return -1;
+ }
+
+ static const uint16 selX[] = { 184, 256, 184, 256, 184, 256 };
+ static const uint8 selY[] = { 2, 2, 54, 54, 106, 106};
+
+ for (int i = 0; i < 6; i++) {
+ if (found[i] != -1 || !_vm->testCharacter(i, 1))
+ continue;
+
+ _screen->drawShape(0, _vm->_blackBoxSmallGrid, selX[i], selY[i], 0);
+ _screen->drawShape(0, _vm->_blackBoxSmallGrid, selX[i] + 16, selY[i], 0);
+ _screen->drawShape(0, _vm->_blackBoxSmallGrid, selX[i] + 32, selY[i], 0);
+ _screen->drawShape(0, _vm->_blackBoxSmallGrid, selX[i] + 48, selY[i], 0);
+ _charSelectRedraw = true;
+ }
+
+ if (count == 1) {
+ int l = _vm->getCharacterLevelIndex(4, _vm->_characters[result].cClass);
+
+ if (l == -1)
+ return result;
+
+ if (_vm->_characters[result].level[l] > 8)
+ return result;
+
+ displayTextBox(24);
+ return -1;
+ }
+
+ _vm->_menuDefs[3].titleStrId = id;
+ Button *buttonList = initMenu(3);
+
+ result = -2;
+ int hlCur = -1;
+ Screen::FontId of = _screen->setFont(Screen::FID_6_FNT);
+
+ while (result == -2 && !_vm->shouldQuit()) {
+ int inputFlag = _vm->checkInput(buttonList, false, 0);
+ _vm->removeInputTop();
+
+ updateBoxFrameHighLight(hlCur);
+
+ if (inputFlag == _vm->_keyMap[Common::KEYCODE_KP4] || inputFlag == _vm->_keyMap[Common::KEYCODE_LEFT] || inputFlag == _vm->_keyMap[Common::KEYCODE_KP8] || inputFlag == _vm->_keyMap[Common::KEYCODE_UP] || inputFlag == _vm->_keyMap[Common::KEYCODE_a] || inputFlag == _vm->_keyMap[Common::KEYCODE_w]) {
+ updateBoxFrameHighLight(-1);
+ _vm->gui_drawCharPortraitWithStats(hlCur--);
+ if (hlCur < 0)
+ hlCur = 5;
+ while (found[hlCur]) {
+ if (--hlCur < 0)
+ hlCur = 5;
+ }
+
+ } else if (inputFlag == _vm->_keyMap[Common::KEYCODE_KP6] || inputFlag == _vm->_keyMap[Common::KEYCODE_RIGHT] || inputFlag == _vm->_keyMap[Common::KEYCODE_KP2] || inputFlag == _vm->_keyMap[Common::KEYCODE_DOWN] || inputFlag == _vm->_keyMap[Common::KEYCODE_z] || inputFlag == _vm->_keyMap[Common::KEYCODE_s]) {
+ updateBoxFrameHighLight(-1);
+ _vm->gui_drawCharPortraitWithStats(hlCur++);
+ if (hlCur == 6)
+ hlCur = 0;
+ while (found[hlCur]) {
+ if (++hlCur == 6)
+ hlCur = 0;
+ }
+
+ } else if (inputFlag == _vm->_keyMap[Common::KEYCODE_KP5] || inputFlag == _vm->_keyMap[Common::KEYCODE_RETURN]) {
+ if (hlCur >= 0)
+ result = hlCur;
+
+ } else if (inputFlag == _vm->_keyMap[Common::KEYCODE_ESCAPE] || inputFlag == 0x8010) {
+ _screen->setFont(Screen::FID_8_FNT);
+ drawMenuButton(buttonList, true, true, true);
+ _screen->updateScreen();
+ _vm->_system->delayMillis(80);
+ drawMenuButton(buttonList, false, false, true);
+ _screen->updateScreen();
+ _screen->setFont(Screen::FID_6_FNT);
+ result = -1;
+
+ } else if (inputFlag > 0x8010 && inputFlag < 0x8017) {
+ result = inputFlag - 0x8011;
+ if (found[result])
+ result = -2;
+ }
+ }
+
+ updateBoxFrameHighLight(-1);
+ if (hlCur >= 0)
+ _vm->gui_drawCharPortraitWithStats(hlCur);
+
+ _screen->setFont(Screen::FID_8_FNT);
+
+ if (result != -1 && id != 53) {
+ if (flags & 4) {
+ int lv = _vm->getCharacterLevelIndex(4, _vm->_characters[result].cClass);
+ if (lv != -1) {
+ if (_vm->_characters[result].level[lv] < 9) {
+ displayTextBox(24);
+ result = -1;
+ }
+ }
+ } else {
+ if (_vm->checkInventoryForItem(result, 29, -1) == -1) {
+ displayTextBox(25);
+ result = -1;
+ }
+ }
+ }
+
+ releaseButtons(buttonList);
+ _screen->setFont(of);
+
+ return result;
+}
+
+void GUI_EoB::displayTextBox(int id) {
+ int op = _screen->setCurPage(2);
+ int od = _screen->curDimIndex();
+ Screen::FontId of = _screen->setFont(Screen::FID_8_FNT);
+ _screen->setClearScreenDim(11);
+ const ScreenDim *dm = _screen->getScreenDim(11);
+
+ drawMenuButtonBox(dm->sx << 3, dm->sy, dm->w << 3, dm->h, false, false);
+ _screen->printShadedText(getMenuString(id), (dm->sx << 3) + 5, dm->sy + 5, 15, 0);
+ _screen->copyRegion(dm->sx << 3, dm->sy, dm->sx << 3, dm->sy, dm->w << 3, dm->h, 2, 0, Screen::CR_NO_P_CHECK);
+ _screen->updateScreen();
+
+ for (uint32 timeOut = _vm->_system->getMillis() + 1440; _vm->_system->getMillis() < timeOut && !_vm->shouldQuit();) {
+ int in = _vm->checkInput(0, false, 0);
+ _vm->removeInputTop();
+ if (in && !(in & 0x800))
+ break;
+ _vm->_system->delayMillis(4);
+ }
+
+ _screen->setCurPage(op);
+ _screen->setFont(of);
+ _screen->setScreenDim(od);
+}
+
+Button *GUI_EoB::initMenu(int id) {
+ _screen->setCurPage(2);
+
+ EoBMenuDef *m = &_vm->_menuDefs[id];
+
+ if (m->dim) {
+ const ScreenDim *dm = _screen->getScreenDim(m->dim);
+ _screen->fillRect(dm->sx << 3, dm->sy, ((dm->sx + dm->w) << 3) - 1, (dm->sy + dm->h) - 1, _vm->guiSettings()->colors.fill);
+ _screen->setScreenDim(m->dim);
+ drawMenuButtonBox(dm->sx << 3, dm->sy, dm->w << 3, dm->h, false, false);
+ }
+
+ _screen->printShadedText(getMenuString(m->titleStrId), 5, 5, m->titleCol, 0);
+
+ Button *buttons = 0;
+ for (int i = 0; i < m->numButtons; i++) {
+ const EoBMenuButtonDef *df = &_vm->_menuButtonDefs[m->firstButtonStrId + i];
+ Button *b = new Button;
+ b->index = m->firstButtonStrId + i + 1;
+ if (id == 4 && _vm->game() == GI_EOB1)
+ b->index -= 14;
+
+ b->data0Val2 = 12;
+ b->data1Val2 = b->data2Val2 = 15;
+ b->data3Val2 = 8;
+ b->flags = 0x1100;
+ b->keyCode = df->keyCode;
+ b->keyCode2 = df->keyCode | 0x100;
+ b->x = df->x;
+ b->y = df->y;
+ b->width = df->width;
+ b->height = df->height;
+ b->extButtonDef = df;
+ b->arg = df->flags;
+
+ drawMenuButton(b, false, false, false);
+ buttons = linkButton(buttons, b);
+ }
+
+ _screen->copyRegion(_screen->_curDim->sx << 3, _screen->_curDim->sy, _screen->_curDim->sx << 3, _screen->_curDim->sy, _screen->_curDim->w << 3, _screen->_curDim->h, 2, 0, Screen::CR_NO_P_CHECK);
+ _vm->gui_notifyButtonListChanged();
+ _screen->setCurPage(0);
+ _screen->updateScreen();
+
+ return buttons;
+}
+
+void GUI_EoB::drawMenuButton(Button *b, bool clicked, bool highlight, bool noFill) {
+ if (!b)
+ return;
+
+ const EoBMenuButtonDef *d = (const EoBMenuButtonDef *)b->extButtonDef;
+
+ if (d->flags & 1)
+ drawMenuButtonBox(b->x, b->y, b->width, b->height, clicked, noFill);
+
+ if (d->labelId) {
+ const char *s = getMenuString(d->labelId);
+
+ int xOffs = 4;
+ int yOffs = 3;
+
+ if (d->flags & 4) {
+ xOffs = ((b->width - (strlen(s) << 3)) >> 1) + 1;
+ yOffs = (b->height - 7) >> 1;
+ }
+
+ int col1 = (_vm->_configRenderMode == Common::kRenderCGA) ? 1 : 15;
+
+ if (noFill || clicked)
+ _screen->printText(s, b->x + xOffs, b->y + yOffs, highlight ? 6 : col1, 0);
+ else
+ _screen->printShadedText(s, b->x + xOffs, b->y + yOffs, highlight ? 6 : col1, 0);
+ }
+}
+
+void GUI_EoB::drawMenuButtonBox(int x, int y, int w, int h, bool clicked, bool noFill) {
+ uint8 col1 = _vm->guiSettings()->colors.frame1;
+ uint8 col2 = _vm->guiSettings()->colors.frame2;
+
+ if (clicked)
+ col1 = col2 = _vm->guiSettings()->colors.fill;
+
+ _vm->gui_drawBox(x, y, w, h, col1, col2, -1);
+ _vm->gui_drawBox(x + 1, y + 1, w - 2, h - 2, _vm->guiSettings()->colors.frame1, _vm->guiSettings()->colors.frame2, noFill ? -1 : _vm->guiSettings()->colors.fill);
+}
+
+void GUI_EoB::drawTextBox(int dim, int id) {
+ int od = _screen->curDimIndex();
+ _screen->setScreenDim(dim);
+ const ScreenDim *dm = _screen->getScreenDim(dim);
+ Screen::FontId of = _screen->setFont(Screen::FID_8_FNT);
+
+ if (dm->w <= 22 && dm->h <= 84)
+ _screen->copyRegion(dm->sx << 3, dm->sy, 0, dm->h, dm->w << 3, dm->h, 0, 2, Screen::CR_NO_P_CHECK);
+
+ _screen->setCurPage(2);
+
+ drawMenuButtonBox(0, 0, dm->w << 3, dm->h, false, false);
+ _screen->printShadedText(getMenuString(id), 5, 5, 15, 0);
+
+ _screen->setCurPage(0);
+ _screen->copyRegion(0, 0, dm->sx << 3, dm->sy, dm->w << 3, dm->h, 2, 0, Screen::CR_NO_P_CHECK);
+ _screen->updateScreen();
+ _screen->setScreenDim(od);
+ _screen->setFont(of);
+}
+
+void GUI_EoB::drawSaveSlotButton(int slot, int redrawBox, int textCol) {
+ if (slot < 0)
+ return;
+
+ int x = _saveSlotX + 4;
+ int y = _saveSlotY + slot * 17 + 20;
+ int w = 167;
+ const char *s = (slot < 6) ? _saveSlotStringsTemp[slot] : _vm->_saveLoadStrings[0];
+
+ if (slot >= 6) {
+ x = _saveSlotX + 118;
+ y = _saveSlotY + 126;
+ w = 53;
+ }
+
+ if (redrawBox)
+ drawMenuButtonBox(x, y, w, 14, (redrawBox - 1) ? true : false, false);
+
+ _screen->printShadedText(s, x + 4, y + 3, textCol, 0);
+}
+
+void GUI_EoB::memorizePrayMenuPrintString(int spellId, int bookPageIndex, int spellType, bool noFill, bool highLight) {
+ if (bookPageIndex < 0)
+ return;
+
+ int y = bookPageIndex * 9 + 50;
+ int col1 = (_vm->_configRenderMode == Common::kRenderCGA) ? 1 : 15;
+
+ if (spellId) {
+ Common::String s(Common::String::format(_vm->_menuStringsMgc[0], spellType ? _vm->_clericSpellList[spellId] : _vm->_mageSpellList[spellId], _numAssignedSpellsOfType[spellId * 2 - 2]));
+ if (noFill)
+ _screen->printText(s.c_str(), 8, y, highLight ? 6 : col1, 0);
+ else
+ _screen->printShadedText(s.c_str(), 8, y, highLight ? 6 : col1, _vm->guiSettings()->colors.fill);
+
+ } else {
+ _screen->fillRect(6, y, 168, y + 8, _vm->guiSettings()->colors.fill);
+ }
+}
+
+void GUI_EoB::updateOptionsStrings() {
+ for (int i = 0; i < 4; i++) {
+ delete[] _menuStringsPrefsTemp[i];
+ _menuStringsPrefsTemp[i] = new char[strlen(_vm->_menuStringsPrefs[i]) + 8];
+ }
+
+ Common::strlcpy(_menuStringsPrefsTemp[0], Common::String::format(_vm->_menuStringsPrefs[0], _vm->_menuStringsOnOff[_vm->_configMusic ? 0 : 1]).c_str(), strlen(_vm->_menuStringsPrefs[0]) + 8);
+ Common::strlcpy(_menuStringsPrefsTemp[1], Common::String::format(_vm->_menuStringsPrefs[1], _vm->_menuStringsOnOff[_vm->_configSounds ? 0 : 1]).c_str(), strlen(_vm->_menuStringsPrefs[1]) + 8);
+ Common::strlcpy(_menuStringsPrefsTemp[2], Common::String::format(_vm->_menuStringsPrefs[2], _vm->_menuStringsOnOff[_vm->_configHpBarGraphs ? 0 : 1]).c_str(), strlen(_vm->_menuStringsPrefs[2]) + 8);
+ Common::strlcpy(_menuStringsPrefsTemp[3], Common::String::format(_vm->_menuStringsPrefs[3], _vm->_menuStringsOnOff[_vm->_configMouse ? 0 : 1]).c_str(), strlen(_vm->_menuStringsPrefs[3]) + 8);
+}
+
+const char *GUI_EoB::getMenuString(int id) {
+ static const char empty[] = "";
+
+ if (id >= 69)
+ return _vm->_menuStringsTransfer[id - 69];
+ else if (id == 68)
+ return _vm->_transferStringsScummVM[0];
+ else if (id == 67)
+ return _vm->_menuStringsDefeat[0];
+ else if (id == 66)
+ return _vm->_errorSlotEmptyString;
+ else if (id == 65)
+ return _vm->_errorSlotEmptyString;
+ else if (id >= 63)
+ return _vm->_menuStringsSpec[id - 63];
+ else if (id >= 60)
+ return _vm->_menuStringsSpellNo[id - 60];
+ else if (id == 59)
+ return _vm->_menuStringsPoison[0];
+ else if (id >= 56)
+ return _vm->_menuStringsHead[id - 56];
+ else if (id == 55)
+ return _vm->_menuStringsDrop2[_vm->game() == GI_EOB1 ? 1 : 2];
+ else if (id == 54)
+ return _vm->_errorSlotNoNameString;
+ else if (id == 53)
+ return _vm->_menuStringsDrop2[0];
+ else if (id >= 48)
+ return _vm->_menuStringsScribe[id - 48];
+ else if (id == 47)
+ return _vm->_menuStringsStarve[0];
+ else if (id == 46)
+ return _vm->_menuStringsExit[0];
+ else if (id == 45)
+ return _vm->_menuStringsDrop[0];
+ else if (id >= 40)
+ return _vm->_menuStringsRest[id - 40];
+ else if (id >= 23)
+ return _vm->_menuStringsSpells[id - 23];
+ else if (id >= 21)
+ return _vm->_menuStringsOnOff[id - 21];
+ else if (id >= 17)
+ return _menuStringsPrefsTemp[id - 17];
+ else if (id >= 9)
+ return _vm->_menuStringsSaveLoad[id - 9];
+ else if (id >= 1)
+ return _vm->_menuStringsMain[id - 1];
+ else if (id < 0)
+ return _vm->_transferStringsScummVM[-id];
+ return empty;
+}
+
+Button *GUI_EoB::linkButton(Button *list, Button *newbt) {
+ if (!list) {
+ list = newbt;
+ return list;
+ }
+
+ if (!newbt)
+ return list;
+
+ Button *resList = list;
+ while (list->nextButton)
+ list = list->nextButton;
+ list->nextButton = newbt;
+ newbt->nextButton = 0;
+
+ return resList;
+}
+
+void GUI_EoB::releaseButtons(Button *list) {
+ while (list) {
+ Button *n = list->nextButton;
+ delete list;
+ list = n;
+ }
+ _vm->gui_notifyButtonListChanged();
+}
+
+void GUI_EoB::setupSaveMenuSlots() {
+ for (int i = 0; i < 6; ++i) {
+ if (_savegameOffset + i < _savegameListSize) {
+ if (_savegameList[i + _savegameOffset]) {
+ Common::strlcpy(_saveSlotStringsTemp[i], _savegameList[i + _savegameOffset], 20);
+ _saveSlotIdTemp[i] = i + _savegameOffset;
+ continue;
+ }
+ }
+ Common::strlcpy(_saveSlotStringsTemp[i], _vm->_saveLoadStrings[1], 20);
+ _saveSlotIdTemp[i] = -1;
+ }
+}
+
+int GUI_EoB::getHighlightSlot() {
+ int res = -1;
+ Common::Point p = _vm->getMousePos();
+
+ for (int i = 0; i < 6; i++) {
+ int y = _saveSlotY + i * 17 + 20;
+ if (_vm->posWithinRect(p.x, p.y, _saveSlotX + 4, y, _saveSlotX + 167, y + 14)) {
+ res = i;
+ break;
+ }
+ }
+
+ if (_vm->posWithinRect(p.x, p.y, _saveSlotX + 118, _saveSlotY + 126, _saveSlotX + 171, _saveSlotY + 140))
+ res = 6;
+
+ return res;
+}
+
+void GUI_EoB::sortSaveSlots() {
+ Common::sort(_saveSlots.begin(), _saveSlots.end(), Common::Less<int>());
+}
+
+void GUI_EoB::restParty_updateRestTime(int hours, bool init) {
+ Screen::FontId of = _screen->setFont(Screen::FID_8_FNT);
+ int od = _screen->curDimIndex();
+ _screen->setScreenDim(10);
+
+ if (init) {
+ _screen->setCurPage(0);
+ _vm->_txt->clearCurDim();
+ drawMenuButtonBox(_screen->_curDim->sx << 3, _screen->_curDim->sy, _screen->_curDim->w << 3, _screen->_curDim->h, false, false);
+ _screen->copyRegion(_screen->_curDim->sx << 3, _screen->_curDim->sy, _screen->_curDim->sx << 3, _screen->_curDim->sy, _screen->_curDim->w << 3, _screen->_curDim->h, 0, 2, Screen::CR_NO_P_CHECK);
+ _screen->printShadedText(getMenuString(42), (_screen->_curDim->sx + 1) << 3, _screen->_curDim->sy + 5, 9, 0);
+ }
+
+ _screen->setCurPage(2);
+ _screen->printShadedText(Common::String::format(_vm->_menuStringsRest2[3], hours).c_str(), (_screen->_curDim->sx + 1) << 3, _screen->_curDim->sy + 20, 15, _vm->guiSettings()->colors.fill);
+ _screen->setCurPage(0);
+ _screen->copyRegion(((_screen->_curDim->sx + 1) << 3) - 1, _screen->_curDim->sy + 20, ((_screen->_curDim->sx + 1) << 3) - 1, _screen->_curDim->sy + 20, 144, 8, 2, 0, Screen::CR_NO_P_CHECK);
+ _screen->updateScreen();
+
+ _vm->delay(160);
+
+ _screen->setScreenDim(od);
+ _screen->setFont(of);
+}
+
+const EoBRect16 GUI_EoB::_highlightFrames[] = {
+ { 0x00B7, 0x0001, 0x00F7, 0x0034 },
+ { 0x00FF, 0x0001, 0x013F, 0x0034 },
+ { 0x00B7, 0x0035, 0x00F7, 0x0068 },
+ { 0x00FF, 0x0035, 0x013F, 0x0068 },
+ { 0x00B7, 0x0069, 0x00F7, 0x009C },
+ { 0x00FF, 0x0069, 0x013F, 0x009C },
+ { 0x0010, 0x003F, 0x0030, 0x0060 },
+ { 0x0050, 0x003F, 0x0070, 0x0060 },
+ { 0x0010, 0x007F, 0x0030, 0x00A0 },
+ { 0x0050, 0x007F, 0x0070, 0x00A0 },
+ { 0x00B0, 0x0042, 0x00D0, 0x0061 },
+ { 0x00D0, 0x0042, 0x00F0, 0x0061 },
+ { 0x00F0, 0x0042, 0x0110, 0x0061 },
+ { 0x0110, 0x0042, 0x0130, 0x0061 },
+ { 0x0004, 0x0018, 0x0024, 0x0039 },
+ { 0x00A3, 0x0018, 0x00C3, 0x0039 },
+ { 0x0004, 0x0040, 0x0024, 0x0061 },
+ { 0x00A3, 0x0040, 0x00C3, 0x0061 },
+ { 0x0004, 0x0068, 0x0024, 0x0089 },
+ { 0x00A3, 0x0068, 0x00C3, 0x0089 }
+};
+
+const uint8 GUI_EoB::_highlightColorTableVGA[] = { 0x0F, 0xB0, 0xB2, 0xB4, 0xB6, 0xB8, 0xBA, 0xBC, 0x0C, 0xBC, 0xBA, 0xB8, 0xB6, 0xB4, 0xB2, 0xB0, 0x00 };
+
+const uint8 GUI_EoB::_highlightColorTableEGA[] = { 0x0C, 0x0D, 0x0E, 0x0F, 0x0E, 0x0D, 0x00 };
+
+} // End of namespace Kyra
+
+#endif // ENABLE_EOB
diff --git a/engines/kyra/gui_eob.h b/engines/kyra/gui_eob.h
new file mode 100644
index 0000000000..f6be18ffbb
--- /dev/null
+++ b/engines/kyra/gui_eob.h
@@ -0,0 +1,165 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#if defined(ENABLE_EOB) || defined(ENABLE_LOL)
+
+#ifndef KYRA_GUI_EOB_H
+#define KYRA_GUI_EOB_H
+
+#include "kyra/gui.h"
+
+#ifdef ENABLE_EOB
+
+namespace Kyra {
+
+struct EoBRect16 {
+ int16 x1;
+ int16 y1;
+ uint16 x2;
+ uint16 y2;
+};
+
+class DarkMoonEngine;
+class Screen_EoB;
+
+class GUI_EoB : public GUI {
+ friend class EoBCoreEngine;
+ friend class CharacterGenerator;
+public:
+ GUI_EoB(EoBCoreEngine *vm);
+ virtual ~GUI_EoB();
+
+ void initStaticData() {}
+
+ // button specific
+ void processButton(Button *button);
+ int processButtonList(Button *buttonList, uint16 inputFlags, int8 mouseWheel);
+
+ // Non button based menu handling (main menu, character generation)
+ void simpleMenu_setup(int sd, int maxItem, const char *const *strings, int32 menuItemsMask, int unk, int lineSpacing);
+ int simpleMenu_process(int sd, const char *const *strings, void *b, int32 menuItemsMask, int unk);
+
+ // Button based menus (camp menu, load menu)
+ void runCampMenu();
+ bool runLoadMenu(int x, int y);
+
+ bool confirmDialogue2(int dim, int id, int deflt);
+ void messageDialogue(int dim, int id, int buttonTextCol);
+ void messageDialogue2(int dim, int id, int buttonTextCol);
+
+ void updateBoxFrameHighLight(int box);
+
+ int getTextInput(char *dest, int x, int y, int destMaxLen, int textColor1, int textColor2, int cursorColor);
+
+ // Transfer party
+ void transferWaitBox();
+ Common::String transferTargetMenu(Common::Array<Common::String> &targets);
+ bool transferFileMenu(Common::String &targetName, Common::String &selection);
+
+ // utilities for thumbnail creation
+ void createScreenThumbnail(Graphics::Surface &dst);
+
+private:
+ int simpleMenu_getMenuItem(int index, int32 menuItemsMask, int itemOffset);
+ void simpleMenu_flashSelection(const char *str, int x, int y, int color1, int color2, int color3);
+ void simpleMenu_initMenuItemsMask(int menuId, int maxItem, int32 menuItemsMask, int unk);
+
+ bool runSaveMenu(int x, int y);
+ int selectSaveSlotDialogue(int x, int y, int id);
+ void runMemorizePrayMenu(int charIndex, int spellType);
+ void scribeScrollDialogue();
+ bool restParty();
+
+ bool confirmDialogue(int id);
+ int selectCharacterDialogue(int id);
+ void displayTextBox(int id);
+
+ Button *initMenu(int id);
+ void drawMenuButton(Button *b, bool clicked, bool highlight, bool noFill);
+ void drawMenuButtonBox(int x, int y, int w, int h, bool clicked, bool noFill);
+ void drawTextBox(int dim, int id);
+ void drawSaveSlotButton(int slot, int redrawBox, int textCol);
+ void memorizePrayMenuPrintString(int spellId, int bookPageIndex, int spellType, bool noFill, bool highLight);
+ void updateOptionsStrings();
+ const char *getMenuString(int id);
+
+ Button *linkButton(Button *list, Button *newbt);
+ void releaseButtons(Button *list);
+
+ void setupSaveMenuSlots();
+ int getHighlightSlot();
+ void sortSaveSlots();
+
+ void restParty_updateRestTime(int hours, bool init);
+
+ char **_menuStringsPrefsTemp;
+ char **_saveSlotStringsTemp;
+ int16 *_saveSlotIdTemp;
+ int _savegameOffset;
+ int16 _saveSlotX;
+ int16 _saveSlotY;
+
+ EoBCoreEngine *_vm;
+ Screen_EoB *_screen;
+
+ bool _pressFlag;
+
+ Button *_specialProcessButton;
+ Button *_backupButtonList;
+ uint16 _flagsMouseLeft;
+ uint16 _flagsMouseRight;
+ uint16 _flagsModifier;
+ uint16 _progress;
+ uint16 _prcButtonUnk3;
+ uint16 _cflag;
+
+ int _menuLineSpacing;
+ int _menuLastInFlags;
+
+ uint8 _numPages;
+ uint8 _numVisPages;
+ int8 *_numAssignedSpellsOfType;
+ uint32 _clericSpellAvltyFlags;
+ uint32 _paladinSpellAvltyFlags;
+ bool _needRest;
+
+ int _menuCur;
+ int _menuNumItems;
+ bool _charSelectRedraw;
+
+ int _updateBoxIndex;
+ int _updateBoxColorIndex;
+ const uint8 *_highLightColorTable;
+ uint32 _highLightBoxTimer;
+
+ static const EoBRect16 _highlightFrames[];
+ static const uint8 _highlightColorTableVGA[];
+ static const uint8 _highlightColorTableEGA[];
+};
+
+} // End of namespace Kyra
+
+#endif // ENABLE_EOB
+
+#endif
+
+#endif // ENABLE_EOB || ENABLE_LOL
diff --git a/engines/kyra/gui_hof.cpp b/engines/kyra/gui_hof.cpp
index a1e0ce66bf..c1bfee066f 100644
--- a/engines/kyra/gui_hof.cpp
+++ b/engines/kyra/gui_hof.cpp
@@ -1148,7 +1148,7 @@ int GUI_HoF::sliderHandler(Button *caller) {
}
int GUI_HoF::loadMenu(Button *caller) {
- updateSaveList();
+ updateSaveFileList(_vm->_targetName);
if (!_vm->_menuDirectlyToLoad) {
updateMenuButton(caller);
diff --git a/engines/kyra/gui_lok.cpp b/engines/kyra/gui_lok.cpp
index 4a2d51faa3..18470e5d76 100644
--- a/engines/kyra/gui_lok.cpp
+++ b/engines/kyra/gui_lok.cpp
@@ -62,7 +62,7 @@ int KyraEngine_LoK::buttonInventoryCallback(Button *caller) {
snd_playSoundEffect(0x35);
_screen->hideMouse();
_screen->fillRect(_itemPosX[itemOffset], _itemPosY[itemOffset], _itemPosX[itemOffset] + 15, _itemPosY[itemOffset] + 15, _flags.platform == Common::kPlatformAmiga ? 19 : 12);
- _screen->drawShape(0, _shapes[216+_itemInHand], _itemPosX[itemOffset], _itemPosY[itemOffset], 0, 0);
+ _screen->drawShape(0, _shapes[216 + _itemInHand], _itemPosX[itemOffset], _itemPosY[itemOffset], 0, 0);
setMouseItem(inventoryItem);
// TODO: Proper support for both taken strings in Amiga version
if (_flags.platform == Common::kPlatformAmiga)
@@ -75,7 +75,7 @@ int KyraEngine_LoK::buttonInventoryCallback(Button *caller) {
} else {
snd_playSoundEffect(0x32);
_screen->hideMouse();
- _screen->drawShape(0, _shapes[216+_itemInHand], _itemPosX[itemOffset], _itemPosY[itemOffset], 0, 0);
+ _screen->drawShape(0, _shapes[216 + _itemInHand], _itemPosX[itemOffset], _itemPosY[itemOffset], 0, 0);
_screen->setMouseCursor(1, 1, _shapes[0]);
updateSentenceCommand(_itemList[getItemListIndex(_itemInHand)], _placedList[0], 179);
_screen->showMouse();
@@ -107,7 +107,7 @@ int KyraEngine_LoK::buttonAmuletCallback(Button *caller) {
characterSays(2001, _waitForAmulet[0], 0, -2);
return 1;
}
- if (!queryGameFlag(0x55+jewel)) {
+ if (!queryGameFlag(0x55 + jewel)) {
assert(_blackJewel);
_animator->makeBrandonFaceMouse();
drawJewelPress(jewel, 1);
@@ -130,7 +130,7 @@ int KyraEngine_LoK::buttonAmuletCallback(Button *caller) {
return 1;
_unkAmuletVar = 1;
- switch (jewel-1) {
+ switch (jewel - 1) {
case 0:
if (_brandonStatusBit & 1) {
seq_brandonHealing2();
@@ -184,7 +184,7 @@ int KyraEngine_LoK::buttonAmuletCallback(Button *caller) {
#pragma mark -
-GUI_LoK::GUI_LoK(KyraEngine_LoK *vm, Screen_LoK *screen) : GUI(vm), _vm(vm), _screen(screen) {
+GUI_LoK::GUI_LoK(KyraEngine_LoK *vm, Screen_LoK *screen) : GUI_v1(vm), _vm(vm), _screen(screen) {
_lastScreenUpdate = 0;
_menu = 0;
_pressFlag = false;
@@ -198,7 +198,7 @@ GUI_LoK::~GUI_LoK() {
}
void GUI_LoK::createScreenThumbnail(Graphics::Surface &dst) {
- uint8 *screen = new uint8[Screen::SCREEN_W*Screen::SCREEN_H];
+ uint8 *screen = new uint8[Screen::SCREEN_W * Screen::SCREEN_H];
if (screen) {
_screen->queryPageFromDisk("SEENPAGE.TMP", 0, screen);
uint8 screenPal[768];
@@ -579,7 +579,7 @@ void GUI_LoK::setupSavegames(Menu &menu, int num) {
// Trim long GMM save descriptions to fit our save slots
_screen->_charWidth = -2;
int fC = _screen->getTextWidth(_savegameNames[i]);
- while (_savegameNames[i][0] && (fC > 240 )) {
+ while (_savegameNames[i][0] && (fC > 240)) {
_savegameNames[i][strlen(_savegameNames[i]) - 1] = 0;
fC = _screen->getTextWidth(_savegameNames[i]);
}
@@ -596,7 +596,7 @@ void GUI_LoK::setupSavegames(Menu &menu, int num) {
}
int GUI_LoK::saveGameMenu(Button *button) {
- updateSaveList();
+ updateSaveFileList(_vm->_targetName);
updateMenuButton(button);
_menu[2].item[5].enabled = true;
@@ -605,7 +605,7 @@ int GUI_LoK::saveGameMenu(Button *button) {
_screen->savePageToDisk("SEENPAGE.TMP", 0);
_menu[2].menuNameString = _vm->_guiStrings[8]; // Select a position to save to:
- _specialSavegameString = _vm->_guiStrings[_vm->gameFlags().platform == Common::kPlatformPC98 ? 10: 9]; // [ EMPTY SLOT ]
+ _specialSavegameString = _vm->_guiStrings[_vm->gameFlags().platform == Common::kPlatformPC98 ? 10 : 9]; // [ EMPTY SLOT ]
for (int i = 0; i < 5; i++)
_menu[2].item[i].callback = BUTTON_FUNCTOR(GUI_LoK, this, &GUI_LoK::saveGame);
@@ -636,7 +636,7 @@ int GUI_LoK::saveGameMenu(Button *button) {
}
int GUI_LoK::loadGameMenu(Button *button) {
- updateSaveList();
+ updateSaveFileList(_vm->_targetName);
if (_vm->_menuDirectlyToLoad) {
_menu[2].item[5].enabled = false;
@@ -710,15 +710,15 @@ void GUI_LoK::updateSavegameString() {
Util::convertISOToDOS(inputKey);
if ((uint8)inputKey > 31 && (uint8)inputKey < (_vm->gameFlags().lang == Common::JA_JPN ? 128 : 226)) {
- if ((length < ARRAYSIZE(_savegameName)-1) && (width <= 240)) {
+ if ((length < ARRAYSIZE(_savegameName) - 1) && (width <= 240)) {
_savegameName[length] = inputKey;
- _savegameName[length+1] = 0;
+ _savegameName[length + 1] = 0;
redrawTextfield();
}
} else if (_keyPressed.keycode == Common::KEYCODE_BACKSPACE ||
_keyPressed.keycode == Common::KEYCODE_DELETE) {
if (length > 0) {
- _savegameName[length-1] = 0;
+ _savegameName[length - 1] = 0;
redrawTextfield();
}
} else if (_keyPressed.keycode == Common::KEYCODE_RETURN ||
@@ -733,7 +733,7 @@ void GUI_LoK::updateSavegameString() {
int GUI_LoK::saveGame(Button *button) {
g_system->setFeatureState(OSystem::kFeatureVirtualKeyboard, true);
updateMenuButton(button);
- _vm->_gameToLoad = _menu[2].item[button->index-0xC].saveSlot;
+ _vm->_gameToLoad = _menu[2].item[button->index - 0xC].saveSlot;
_screen->loadPageFromDisk("SEENPAGE.TMP", 0);
_screen->savePageToDisk("SEENPAGE.TMP", 0);
@@ -800,7 +800,7 @@ int GUI_LoK::savegameConfirm(Button *button) {
int GUI_LoK::loadGame(Button *button) {
updateMenuButton(button);
_displaySubMenu = false;
- _vm->_gameToLoad = _menu[2].item[button->index-0xC].saveSlot;
+ _vm->_gameToLoad = _menu[2].item[button->index - 0xC].saveSlot;
return 0;
}
@@ -914,15 +914,15 @@ int GUI_LoK::gameControlsMenu(Button *button) {
void GUI_LoK::setupControls(Menu &menu) {
switch (_vm->_configMusic) {
- case 0:
- menu.item[0].itemString = _offString; //"Off"
- break;
- case 1:
- menu.item[0].itemString = _onString; //"On"
- break;
- case 2:
- menu.item[0].itemString = _onCDString; //"On + CD"
- break;
+ case 0:
+ menu.item[0].itemString = _offString; //"Off"
+ break;
+ case 1:
+ menu.item[0].itemString = _onString; //"On"
+ break;
+ case 2:
+ menu.item[0].itemString = _onCDString; //"On + CD"
+ break;
}
if (_vm->_configSounds)
diff --git a/engines/kyra/gui_lok.h b/engines/kyra/gui_lok.h
index 5a8d6ab532..d3e0beaa9e 100644
--- a/engines/kyra/gui_lok.h
+++ b/engines/kyra/gui_lok.h
@@ -23,7 +23,7 @@
#ifndef KYRA_GUI_LOK_H
#define KYRA_GUI_LOK_H
-#include "kyra/gui.h"
+#include "kyra/gui_v1.h"
#include "kyra/screen_lok.h"
namespace Kyra {
@@ -92,7 +92,7 @@ namespace Kyra {
class KyraEngine_LoK;
-class GUI_LoK : public GUI {
+class GUI_LoK : public GUI_v1 {
friend class KyraEngine_LoK;
public:
GUI_LoK(KyraEngine_LoK *vm, Screen_LoK *screen);
diff --git a/engines/kyra/gui_lol.cpp b/engines/kyra/gui_lol.cpp
index 3ab52b9940..b025aefbd0 100644
--- a/engines/kyra/gui_lol.cpp
+++ b/engines/kyra/gui_lol.cpp
@@ -32,8 +32,11 @@
#include "common/savefile.h"
#include "common/system.h"
#include "common/config-manager.h"
+
#include "graphics/scaler.h"
+#include "backends/keymapper/keymapper.h"
+
#include "base/version.h"
namespace Kyra {
@@ -184,7 +187,7 @@ void LoLEngine::gui_displayCharInventory(int charNum) {
static const uint16 statusFlags[] = { 0x0080, 0x0000, 0x1000, 0x0002, 0x100, 0x0001, 0x0000, 0x0000 };
- memset(_charStatusFlags, 0xffff, sizeof(_charStatusFlags));
+ memset(_charStatusFlags, 0xFF, sizeof(_charStatusFlags));
int x = 0;
int32 c = 0;
@@ -213,9 +216,9 @@ void LoLEngine::gui_displayCharInventory(int charNum) {
}
if (_flags.use16ColorMode)
- gui_drawBarGraph(154, 66 + i * 8, 34, 5, b, e, 0x88, 0);
+ gui_drawHorizontalBarGraph(154, 66 + i * 8, 34, 5, b, e, 0x88, 0);
else
- gui_drawBarGraph(154, 64 + i * 10, 34, 5, b, e, 132, 0);
+ gui_drawHorizontalBarGraph(154, 64 + i * 10, 34, 5, b, e, 132, 0);
}
_screen->drawClippedLine(14, 120, 194, 120, 1);
@@ -343,31 +346,6 @@ void LoLEngine::gui_drawCharInventoryItem(int itemIndex) {
_screen->drawShape(_screen->_curPage, getItemIconShapePtr(i), x + 1, y + 1, 0, 0);
}
-void LoLEngine::gui_drawBarGraph(int x, int y, int w, int h, int32 cur, int32 max, int col1, int col2) {
- if (max < 1)
- return;
- if (cur < 0)
- cur = 0;
-
- int32 e = MIN(cur, max);
-
- if (!--w)
- return;
- if (!--h)
- return;
-
- int32 t = (e * w) / max;
-
- if (!t && e)
- t++;
-
- if (t)
- _screen->fillRect(x, y, x + t - 1, y + h, col1);
-
- if (t < w && col2)
- _screen->fillRect(x + t, y, x + w, y + h, col2);
-}
-
void LoLEngine::gui_drawAllCharPortraitsWithStats() {
int numChars = countActiveCharacters();
if (!numChars)
@@ -402,9 +380,9 @@ void LoLEngine::gui_drawCharPortraitWithStats(int charNum) {
int spellLevels = 0;
if (_availableSpells[_selectedSpell] != -1) {
for (int i = 0; i < 4; i++) {
- if (_spellProperties[_availableSpells[_selectedSpell]].mpRequired[i] <= _characters[charNum].magicPointsCur &&
- _spellProperties[_availableSpells[_selectedSpell]].hpRequired[i] <= _characters[charNum].hitPointsCur)
- spellLevels++;
+ if (_spellProperties[_availableSpells[_selectedSpell]].mpRequired[i] <= _characters[charNum].magicPointsCur
+ && _spellProperties[_availableSpells[_selectedSpell]].hpRequired[i] <= _characters[charNum].hitPointsCur)
+ spellLevels++;
}
}
@@ -460,17 +438,6 @@ void LoLEngine::gui_drawCharPortraitWithStats(int charNum) {
_screen->setFont(tmpFid);
}
-void LoLEngine::gui_drawBox(int x, int y, int w, int h, int frameColor1, int frameColor2, int fillColor) {
- w--; h--;
- if (fillColor != -1)
- _screen->fillRect(x + 1, y + 1, x + w - 1, y + h - 1, fillColor);
-
- _screen->drawClippedLine(x + 1, y, x + w, y, frameColor2);
- _screen->drawClippedLine(x + w, y, x + w, y + h - 1, frameColor2);
- _screen->drawClippedLine(x, y, x, y + h, frameColor1);
- _screen->drawClippedLine(x, y + h, x + w, y + h, frameColor1);
-}
-
void LoLEngine::gui_drawCharFaceShape(int charNum, int x, int y, int pageNum) {
if (_characters[charNum].curFaceFrame < 7 && _characters[charNum].tempFaceFrame)
_characters[charNum].curFaceFrame = _characters[charNum].tempFaceFrame;
@@ -853,19 +820,6 @@ void LoLEngine::gui_triggerEvent(int eventType) {
_preserveEvents = true;
}
-void LoLEngine::removeInputTop() {
- if (!_eventList.empty()) {
- if (_eventList.begin()->event.type == Common::EVENT_LBUTTONDOWN)
- _gui->_mouseClick = 1;
- else if (_eventList.begin()->event.type == Common::EVENT_RBUTTONDOWN)
- _gui->_mouseClick = 2;
- else
- _gui->_mouseClick = 0;
-
- _eventList.erase(_eventList.begin());
- }
-}
-
void LoLEngine::gui_enableDefaultPlayfieldButtons() {
gui_resetButtonList();
gui_initButtonsFromList(_buttonList1);
@@ -911,19 +865,6 @@ void LoLEngine::gui_enableCharInventoryButtons(int charNum) {
gui_setFaceFramesControlButtons(21, 0);
}
-void LoLEngine::gui_resetButtonList() {
- for (uint i = 0; i < ARRAYSIZE(_activeButtonData); ++i)
- _activeButtonData[i].nextButton = 0;
-
- gui_notifyButtonListChanged();
- _activeButtons = 0;
-}
-
-void LoLEngine::gui_initButtonsFromList(const int16 *list) {
- while (*list != -1)
- gui_initButton(*list++);
-}
-
void LoLEngine::gui_setFaceFramesControlButtons(int index, int xOffs) {
int c = countActiveCharacters();
for (int i = 0; i < c; i++)
@@ -1009,14 +950,6 @@ void LoLEngine::gui_initButton(int index, int x, int y, int val) {
b->buttonCallback = _buttonCallbacks[index];
}
-void LoLEngine::gui_notifyButtonListChanged() {
- if (_gui) {
- if (!_gui->_buttonListChanged && !_preserveEvents)
- removeInputTop();
- _gui->_buttonListChanged = true;
- }
-}
-
int LoLEngine::clickedUpArrow(Button *button) {
if (button->arg && !_floatingCursorsEnabled)
return 0;
@@ -1229,7 +1162,7 @@ int LoLEngine::clickedPortraitLeft(Button *button) {
int LoLEngine::clickedLiveMagicBarsLeft(Button *button) {
gui_highlightPortraitFrame(button->arg);
_txt->printMessage(0, getLangString(0x4047), _characters[button->arg].name, _characters[button->arg].hitPointsCur,
- _characters[button->arg].hitPointsMax, _characters[button->arg].magicPointsCur, _characters[button->arg].magicPointsMax);
+ _characters[button->arg].hitPointsMax, _characters[button->arg].magicPointsCur, _characters[button->arg].magicPointsMax);
return 1;
}
@@ -1333,7 +1266,6 @@ int LoLEngine::clickedExitCharInventory(Button *button) {
int LoLEngine::clickedSceneDropItem(Button *button) {
static const uint8 offsX[] = { 0x40, 0xC0, 0x40, 0xC0 };
static const uint8 offsY[] = { 0x40, 0x40, 0xC0, 0xC0 };
- static const uint8 dirIndex[] = { 0, 1, 2, 3, 1, 3, 0, 2, 3, 2, 1, 0, 2, 0, 3, 1 };
if ((_updateFlags & 1) || !_itemInHand)
return 0;
@@ -1348,7 +1280,7 @@ int LoLEngine::clickedSceneDropItem(Button *button) {
uint16 x = 0;
uint16 y = 0;
- int i = dirIndex[(_currentDirection << 2) + button->arg];
+ int i = _dropItemDirIndex[(_currentDirection << 2) + button->arg];
calcCoordinates(x, y, block, offsX[i], offsY[i]);
setItemPosition(_itemInHand, x, y, 0, 1);
@@ -1404,7 +1336,7 @@ int LoLEngine::clickedInventorySlot(Button *button) {
int hItem = _itemInHand;
if ((_itemsInPlay[hItem].itemPropertyIndex == 281 || _itemsInPlay[slotItem].itemPropertyIndex == 281) &&
- (_itemsInPlay[hItem].itemPropertyIndex == 220 || _itemsInPlay[slotItem].itemPropertyIndex == 220)) {
+ (_itemsInPlay[hItem].itemPropertyIndex == 220 || _itemsInPlay[slotItem].itemPropertyIndex == 220)) {
// merge ruby of truth
WSAMovie_v2 *wsa = new WSAMovie_v2(this);
@@ -1908,20 +1840,16 @@ int LoLEngine::clickedStatusIcon(Button *button) {
return 1;
}
-GUI_LoL::GUI_LoL(LoLEngine *vm) : GUI(vm), _vm(vm), _screen(vm->_screen) {
+GUI_LoL::GUI_LoL(LoLEngine *vm) : GUI_v1(vm), _vm(vm), _screen(vm->_screen) {
_scrollUpFunctor = BUTTON_FUNCTOR(GUI_LoL, this, &GUI_LoL::scrollUp);
_scrollDownFunctor = BUTTON_FUNCTOR(GUI_LoL, this, &GUI_LoL::scrollDown);
- _redrawButtonFunctor = BUTTON_FUNCTOR(GUI, this, &GUI::redrawButtonCallback);
- _redrawShadedButtonFunctor = BUTTON_FUNCTOR(GUI, this, &GUI::redrawShadedButtonCallback);
+ _redrawButtonFunctor = BUTTON_FUNCTOR(GUI_v1, this, &GUI_v1::redrawButtonCallback);
+ _redrawShadedButtonFunctor = BUTTON_FUNCTOR(GUI_v1, this, &GUI_v1::redrawShadedButtonCallback);
_specialProcessButton = _backUpButtonList = 0;
_flagsModifier = 0;
- _mouseClick = 0;
_sliderSfx = 11;
- _buttonListChanged = false;
- _savegameList = 0;
- _savegameListSize = 0;
}
void GUI_LoL::processButton(Button *button) {
@@ -2015,18 +1943,18 @@ int GUI_LoL::processButtonList(Button *buttonList, uint16 inputFlag, int8 mouseW
if (!buttonList)
return inputFlag & 0x7FFF;
- if (_backUpButtonList != buttonList || _buttonListChanged) {
+ if (_backUpButtonList != buttonList || _vm->_buttonListChanged) {
_specialProcessButton = 0;
_flagsModifier = 0;
- if (_mouseClick == 1)
+ if (_vm->_mouseClick == 1)
_flagsModifier |= 0x200;
- if (_mouseClick == 2)
+ if (_vm->_mouseClick == 2)
_flagsModifier |= 0x2000;
- _mouseClick = 0;
+ _vm->_mouseClick = 0;
_backUpButtonList = buttonList;
- _buttonListChanged = false;
+ _vm->_buttonListChanged = false;
while (buttonList) {
processButton(buttonList);
@@ -2088,7 +2016,7 @@ int GUI_LoL::processButtonList(Button *buttonList, uint16 inputFlag, int8 mouseW
bool progress = false;
- if (mouseX >= x && mouseY >= y && mouseX <= x+buttonList->width && mouseY <= y+buttonList->height)
+ if (mouseX >= x && mouseY >= y && mouseX <= x + buttonList->width && mouseY <= y + buttonList->height)
progress = true;
buttonList->flags2 &= ~0x80;
@@ -2296,13 +2224,13 @@ int GUI_LoL::runMenu(Menu &menu) {
// Instead, the respevtive struct entry is used to determine whether
// a menu has scroll buttons or slider bars.
uint8 hasSpecialButtons = 0;
- _savegameListUpdateNeeded = true;
+ _saveSlotsListUpdateNeeded = true;
while (_displayMenu) {
_vm->_mouseX = _vm->_mouseY = 0;
if (_currentMenu == &_loadMenu || _currentMenu == &_saveMenu || _currentMenu == &_deleteMenu) {
- updateSavegameList();
+ updateSaveSlotsList(_vm->_targetName);
setupSaveMenuSlots(*_currentMenu, 4);
}
@@ -2572,11 +2500,11 @@ void GUI_LoL::setupSaveMenuSlots(Menu &menu, int num) {
slotOffs = 1;
}
- int saveSlotMaxLen = ((_screen->getScreenDim(8))->w << 3) - _screen->getCharWidth('W');
-
+ int saveSlotMaxLen = ((_screen->getScreenDim(8))->w << 3) - _screen->getCharWidth('W');
+
for (int i = startSlot; i < num && _savegameOffset + i - slotOffs < _savegameListSize; ++i) {
- if (_savegameList[_saveSlots[i + _savegameOffset - slotOffs]]) {
- Common::strlcpy(s, _savegameList[_saveSlots[i + _savegameOffset - slotOffs]], 80);
+ if (_savegameList[i + _savegameOffset - slotOffs]) {
+ Common::strlcpy(s, _savegameList[i + _savegameOffset - slotOffs], 80);
// Trim long GMM save descriptions to fit our save slots
int fC = _screen->getTextWidth(s);
@@ -2602,45 +2530,8 @@ void GUI_LoL::setupSaveMenuSlots(Menu &menu, int num) {
}
}
-void GUI_LoL::updateSavegameList() {
- if (!_savegameListUpdateNeeded)
- return;
-
- _savegameListUpdateNeeded = false;
-
- if (_savegameList) {
- for (int i = 0; i < _savegameListSize; i++)
- delete[] _savegameList[i];
- delete[] _savegameList;
- }
-
- updateSaveList(true);
- _savegameListSize = _saveSlots.size();
-
- if (_savegameListSize) {
- Common::sort(_saveSlots.begin(), _saveSlots.end(), Common::Greater<int>());
-
- LoLEngine::SaveHeader header;
- Common::InSaveFile *in;
-
- _savegameList = new char *[_savegameListSize];
-
- for (int i = 0; i < _savegameListSize; i++) {
- in = _vm->openSaveForReading(_vm->getSavegameFilename(i), header);
- if (in) {
- _savegameList[i] = new char[header.description.size() + 1];
- Common::strlcpy(_savegameList[i], header.description.c_str(), header.description.size() + 1);
- Util::convertISOToDOS(_savegameList[i]);
- delete in;
- } else {
- _savegameList[i] = 0;
- error("GUI_LoL::updateSavegameList(): Unexpected missing save file for slot: %d.", i);
- }
- }
-
- } else {
- _savegameList = 0;
- }
+void GUI_LoL::sortSaveSlots() {
+ Common::sort(_saveSlots.begin(), _saveSlots.end(), Common::Greater<int>());
}
void GUI_LoL::printMenuText(const char *str, int x, int y, uint8 c0, uint8 c1, uint8 flags) {
@@ -2660,6 +2551,11 @@ int GUI_LoL::getInput() {
if (!_displayMenu)
return 0;
+#ifdef ENABLE_KEYMAPPER
+ Common::Keymapper *const keymapper = _vm->getEventManager()->getKeymapper();
+ keymapper->pushKeymap(Common::kGlobalKeymapName);
+#endif
+
Common::Point p = _vm->getMousePos();
_vm->_mouseX = p.x;
_vm->_mouseY = p.y;
@@ -2675,7 +2571,7 @@ int GUI_LoL::getInput() {
int inputFlag = _vm->checkInput(_menuButtonList);
- if (_currentMenu == &_savenameMenu && _keyPressed.ascii){
+ if (_currentMenu == &_savenameMenu && _keyPressed.ascii) {
char inputKey = _keyPressed.ascii;
Util::convertISOToDOS(inputKey);
@@ -2696,6 +2592,11 @@ int GUI_LoL::getInput() {
_displayMenu = false;
_vm->delay(8);
+
+#ifdef ENABLE_KEYMAPPER
+ keymapper->popKeymap(Common::kGlobalKeymapName);
+#endif
+
return inputFlag & 0x8000 ? 1 : 0;
}
@@ -2825,7 +2726,7 @@ int GUI_LoL::clickedOptionsMenu(Button *button) {
delete[] _vm->_landsFile;
_vm->_landsFile = _vm->resource()->fileData(filename.c_str(), 0);
_newMenu = _lastMenu;
- } break;
+ } break;
default:
// TODO: Is there anything we should do if we hit this case?
break;
@@ -2944,11 +2845,11 @@ int GUI_LoL::clickedChoiceMenu(Button *button) {
if (*i >= 990)
break;
Common::String oldName = _vm->getSavegameFilename(*i);
- Common::String newName = _vm->getSavegameFilename(*i-1);
+ Common::String newName = _vm->getSavegameFilename(*i - 1);
_vm->_saveFileMan->renameSavefile(oldName, newName);
}
_newMenu = &_mainMenu;
- _savegameListUpdateNeeded = true;
+ _saveSlotsListUpdateNeeded = true;
}
} else if (button->arg == _choiceMenu.item[1].itemId) {
_newMenu = &_mainMenu;
diff --git a/engines/kyra/gui_lol.h b/engines/kyra/gui_lol.h
index 0686926534..dbf54e41f0 100644
--- a/engines/kyra/gui_lol.h
+++ b/engines/kyra/gui_lol.h
@@ -25,7 +25,7 @@
#ifndef KYRA_GUI_LOL_H
#define KYRA_GUI_LOL_H
-#include "kyra/gui.h"
+#include "kyra/gui_v1.h"
namespace Kyra {
#define GUI_LOL_MENU(menu, a, b, c, d, e, f, g, i) \
@@ -88,7 +88,7 @@ namespace Kyra {
class LoLEngine;
class Screen_LoL;
-class GUI_LoL : public GUI {
+class GUI_LoL : public GUI_v1 {
friend class LoLEngine;
public:
GUI_LoL(LoLEngine *vm);
@@ -112,7 +112,6 @@ private:
void restorePage0();
void setupSaveMenuSlots(Menu &menu, int num);
- void updateSavegameList();
void printMenuText(const char *str, int x, int y, uint8 c0, uint8 c1, uint8 flags);
int getMenuCenterStringX(const char *str, int x1, int x2);
@@ -162,9 +161,7 @@ private:
Button *_specialProcessButton;
Button *_backUpButtonList;
- bool _buttonListChanged;
uint16 _flagsModifier;
- uint8 _mouseClick;
int _savegameOffset;
int _sliderSfx;
@@ -172,9 +169,7 @@ private:
Button::Callback _scrollUpFunctor;
Button::Callback _scrollDownFunctor;
- char **_savegameList;
- int _savegameListSize;
- bool _savegameListUpdateNeeded;
+ virtual void sortSaveSlots();
};
} // End of namespace Kyra
diff --git a/engines/kyra/gui_mr.cpp b/engines/kyra/gui_mr.cpp
index 82082961e9..e88b7fdffb 100644
--- a/engines/kyra/gui_mr.cpp
+++ b/engines/kyra/gui_mr.cpp
@@ -1277,7 +1277,7 @@ int GUI_MR::optionsButton(Button *button) {
}
int GUI_MR::loadMenu(Button *caller) {
- updateSaveList();
+ updateSaveFileList(_vm->_targetName);
if (!_vm->_menuDirectlyToLoad) {
updateMenuButton(caller);
diff --git a/engines/kyra/gui_rpg.cpp b/engines/kyra/gui_rpg.cpp
new file mode 100644
index 0000000000..be40050bb1
--- /dev/null
+++ b/engines/kyra/gui_rpg.cpp
@@ -0,0 +1,134 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#if defined(ENABLE_EOB) || defined(ENABLE_LOL)
+
+#include "kyra/kyra_rpg.h"
+
+namespace Kyra {
+
+void KyraRpgEngine::removeInputTop() {
+ if (!_eventList.empty()) {
+ if (_eventList.begin()->event.type == Common::EVENT_LBUTTONDOWN)
+ _mouseClick = 1;
+ else if (_eventList.begin()->event.type == Common::EVENT_RBUTTONDOWN)
+ _mouseClick = 2;
+ else
+ _mouseClick = 0;
+
+ _eventList.erase(_eventList.begin());
+ }
+}
+
+void KyraRpgEngine::gui_drawBox(int x, int y, int w, int h, int frameColor1, int frameColor2, int fillColor) {
+ w--;
+ h--;
+ if (fillColor != -1)
+ screen()->fillRect(x + 1, y + 1, x + w - 1, y + h - 1, fillColor);
+
+ screen()->drawClippedLine(x + 1, y, x + w, y, frameColor2);
+ screen()->drawClippedLine(x + w, y, x + w, y + h - 1, frameColor2);
+ screen()->drawClippedLine(x, y, x, y + h, frameColor1);
+ screen()->drawClippedLine(x, y + h, x + w, y + h, frameColor1);
+}
+
+void KyraRpgEngine::gui_drawHorizontalBarGraph(int x, int y, int w, int h, int32 cur, int32 max, int col1, int col2) {
+ if (max < 1)
+ return;
+ if (cur < 0)
+ cur = 0;
+
+ int32 e = MIN(cur, max);
+
+ if (!--w)
+ return;
+ if (!--h)
+ return;
+
+ int32 t = (e * w) / max;
+
+ if (!t && e)
+ t++;
+
+ if (t)
+ screen()->fillRect(x, y, x + t - 1, y + h, col1);
+
+ if (t < w && col2)
+ screen()->fillRect(x + t, y, x + w - 1, y + h, col2);
+}
+
+void KyraRpgEngine::gui_initButtonsFromList(const int16 *list) {
+ while (*list != -1)
+ gui_initButton(*list++);
+}
+
+void KyraRpgEngine::gui_resetButtonList() {
+ for (uint i = 0; i < ARRAYSIZE(_activeButtonData); ++i)
+ _activeButtonData[i].nextButton = 0;
+
+ gui_notifyButtonListChanged();
+ _activeButtons = 0;
+}
+
+void KyraRpgEngine::gui_notifyButtonListChanged() {
+ if (gui()) {
+ if (!_buttonListChanged && !_preserveEvents)
+ removeInputTop();
+ _buttonListChanged = true;
+ }
+}
+
+bool KyraRpgEngine::clickedShape(int shapeIndex) {
+ if (_clickedSpecialFlag != 0x40)
+ return true;
+
+ for (; shapeIndex; shapeIndex = _levelDecorationProperties[shapeIndex].next) {
+ if (_flags.gameID != GI_LOL)
+ shapeIndex--;
+
+ uint16 s = _levelDecorationProperties[shapeIndex].shapeIndex[1];
+
+ if (s == 0xffff)
+ continue;
+
+ int w = _flags.gameID == GI_LOL ? _levelDecorationShapes[s][3] : (_levelDecorationShapes[s][2] << 3);
+ int h = _levelDecorationShapes[s][_flags.gameID == GI_LOL ? 2 : 1];
+ int x = _levelDecorationProperties[shapeIndex].shapeX[1] + _clickedShapeXOffs;
+ int y = _levelDecorationProperties[shapeIndex].shapeY[1] + _clickedShapeYOffs;
+
+ if (_levelDecorationProperties[shapeIndex].flags & 1) {
+ if (_flags.gameID == GI_LOL)
+ w <<= 1;
+ else
+ x = 176 - x - w;
+ }
+
+ if (posWithinRect(_mouseX, _mouseY, x - 4, y - 4, x + w + 8, y + h + 8))
+ return true;
+ }
+
+ return false;
+}
+
+} // End of namespace Kyra
+
+#endif // defined(ENABLE_EOB) || defined(ENABLE_LOL)
diff --git a/engines/kyra/gui_v1.cpp b/engines/kyra/gui_v1.cpp
new file mode 100644
index 0000000000..f3459ddfe3
--- /dev/null
+++ b/engines/kyra/gui_v1.cpp
@@ -0,0 +1,629 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "kyra/gui_v1.h"
+
+#include "kyra/text.h"
+#include "kyra/wsamovie.h"
+
+#include "common/savefile.h"
+#include "common/system.h"
+
+namespace Kyra {
+
+GUI_v1::GUI_v1(KyraEngine_v1 *kyra) : GUI(kyra), _text(kyra->text()) {
+ _menuButtonList = 0;
+
+ _redrawButtonFunctor = BUTTON_FUNCTOR(GUI_v1, this, &GUI_v1::redrawButtonCallback);
+ _redrawShadedButtonFunctor = BUTTON_FUNCTOR(GUI_v1, this, &GUI_v1::redrawShadedButtonCallback);
+}
+
+Button *GUI_v1::addButtonToList(Button *list, Button *newButton) {
+ if (!newButton)
+ return list;
+
+ newButton->nextButton = 0;
+
+ if (list) {
+ Button *cur = list;
+ while (cur->nextButton)
+ cur = cur->nextButton;
+ cur->nextButton = newButton;
+ } else {
+ list = newButton;
+ }
+
+ return list;
+}
+
+void GUI_v1::initMenuLayout(Menu &menu) {
+ if (menu.x == -1)
+ menu.x = (320 - menu.width) >> 1;
+ if (menu.y == -1)
+ menu.y = (200 - menu.height) >> 1;
+
+ for (int i = 0; i < menu.numberOfItems; ++i) {
+ if (menu.item[i].x == -1)
+ menu.item[i].x = (menu.width - menu.item[i].width) >> 1;
+ }
+}
+
+void GUI_v1::initMenu(Menu &menu) {
+ _menuButtonList = 0;
+
+ _screen->hideMouse();
+
+ int textX;
+ int textY;
+
+ int menu_x2 = menu.width + menu.x - 1;
+ int menu_y2 = menu.height + menu.y - 1;
+
+ _screen->fillRect(menu.x + 2, menu.y + 2, menu_x2 - 2, menu_y2 - 2, menu.bkgdColor);
+ _screen->drawShadedBox(menu.x, menu.y, menu_x2, menu_y2, menu.color1, menu.color2);
+
+ if (menu.titleX != -1)
+ textX = menu.titleX;
+ else
+ textX = getMenuCenterStringX(getMenuTitle(menu), menu.x, menu_x2);
+
+ textY = menu.y + menu.titleY;
+
+ if (_vm->game() == GI_LOL) {
+ printMenuText(getMenuTitle(menu), textX, textY, menu.textColor, 0, 9);
+ } else {
+ if (_vm->gameFlags().platform != Common::kPlatformAmiga)
+ printMenuText(getMenuTitle(menu), textX - 1, textY + 1, defaultColor1(), defaultColor2(), 0);
+ printMenuText(getMenuTitle(menu), textX, textY, menu.textColor, 0, 0);
+ }
+
+ int x1, y1, x2, y2;
+ for (int i = 0; i < menu.numberOfItems; ++i) {
+ if (!menu.item[i].enabled)
+ continue;
+
+ x1 = menu.x + menu.item[i].x;
+ y1 = menu.y + menu.item[i].y;
+
+ x2 = x1 + menu.item[i].width - 1;
+ y2 = y1 + menu.item[i].height - 1;
+
+ if (i < 7) {
+ Button *menuButtonData = getButtonListData() + i;
+ menuButtonData->nextButton = 0;
+ menuButtonData->x = x1;
+ menuButtonData->y = y1;
+ menuButtonData->width = menu.item[i].width - 1;
+ menuButtonData->height = menu.item[i].height - 1;
+ menuButtonData->buttonCallback = menu.item[i].callback;
+ menuButtonData->keyCode = menu.item[i].keyCode;
+ menuButtonData->keyCode2 = 0;
+ menuButtonData->arg = menu.item[i].itemId;
+
+ _menuButtonList = addButtonToList(_menuButtonList, menuButtonData);
+ }
+
+ _screen->fillRect(x1, y1, x2, y2, menu.item[i].bkgdColor);
+ _screen->drawShadedBox(x1, y1, x2, y2, menu.item[i].color1, menu.item[i].color2);
+
+ if (getMenuItemTitle(menu.item[i])) {
+ if (menu.item[i].titleX != -1)
+ textX = x1 + menu.item[i].titleX + 3;
+ else
+ textX = getMenuCenterStringX(getMenuItemTitle(menu.item[i]), x1, x2);
+
+ textY = y1 + 2;
+ if (_vm->game() == GI_LOL) {
+ textY++;
+ if (i == menu.highlightedItem)
+ printMenuText(getMenuItemTitle(menu.item[i]), textX, textY, menu.item[i].highlightColor, 0, 8);
+ else
+ printMenuText(getMenuItemTitle(menu.item[i]), textX, textY, menu.item[i].textColor, 0, 8);
+ } else {
+ Screen::FontId of = _screen->_currentFont;
+ if (menu.item[i].saveSlot > 0)
+ _screen->setFont(Screen::FID_8_FNT);
+
+ if (_vm->gameFlags().platform != Common::kPlatformAmiga)
+ printMenuText(getMenuItemTitle(menu.item[i]), textX - 1, textY + 1, defaultColor1(), 0, 0);
+
+ if (i == menu.highlightedItem)
+ printMenuText(getMenuItemTitle(menu.item[i]), textX, textY, menu.item[i].highlightColor, 0, 0);
+ else
+ printMenuText(getMenuItemTitle(menu.item[i]), textX, textY, menu.item[i].textColor, 0, 0);
+
+ _screen->setFont(of);
+ }
+ }
+ }
+
+ for (int i = 0; i < menu.numberOfItems; ++i) {
+ if (getMenuItemLabel(menu.item[i])) {
+ if (_vm->game() == GI_LOL) {
+ menu.item[i].labelX = menu.item[i].x - 1;
+ menu.item[i].labelY = menu.item[i].y + 3;
+ printMenuText(getMenuItemLabel(menu.item[i]), menu.x + menu.item[i].labelX, menu.y + menu.item[i].labelY, menu.item[i].textColor, 0, 10);
+ } else {
+ if (_vm->gameFlags().platform != Common::kPlatformAmiga)
+ printMenuText(getMenuItemLabel(menu.item[i]), menu.x + menu.item[i].labelX - 1, menu.y + menu.item[i].labelY + 1, defaultColor1(), 0, 0);
+ printMenuText(getMenuItemLabel(menu.item[i]), menu.x + menu.item[i].labelX, menu.y + menu.item[i].labelY, menu.item[i].textColor, 0, 0);
+ }
+ }
+ }
+
+ if (menu.scrollUpButtonX != -1) {
+ Button *scrollUpButton = getScrollUpButton();
+ scrollUpButton->x = menu.scrollUpButtonX + menu.x;
+ scrollUpButton->y = menu.scrollUpButtonY + menu.y;
+ scrollUpButton->buttonCallback = getScrollUpButtonHandler();
+ scrollUpButton->nextButton = 0;
+ scrollUpButton->mouseWheel = -1;
+
+ _menuButtonList = addButtonToList(_menuButtonList, scrollUpButton);
+ updateMenuButton(scrollUpButton);
+
+ Button *scrollDownButton = getScrollDownButton();
+ scrollDownButton->x = menu.scrollDownButtonX + menu.x;
+ scrollDownButton->y = menu.scrollDownButtonY + menu.y;
+ scrollDownButton->buttonCallback = getScrollDownButtonHandler();
+ scrollDownButton->nextButton = 0;
+ scrollDownButton->mouseWheel = 1;
+
+ _menuButtonList = addButtonToList(_menuButtonList, scrollDownButton);
+ updateMenuButton(scrollDownButton);
+ }
+
+ _screen->showMouse();
+ _screen->updateScreen();
+}
+
+void GUI_v1::processHighlights(Menu &menu) {
+ int x1, y1, x2, y2;
+ Common::Point p = _vm->getMousePos();
+ int mouseX = p.x;
+ int mouseY = p.y;
+
+ if (_vm->game() == GI_LOL && menu.highlightedItem != 255) {
+ // LoL doesnt't have default highlighted items.
+ // We use a highlightedItem value of 255 for this.
+
+ // With LoL no highlighting should take place unless the
+ // mouse cursor moves over a button. The highlighting should end
+ // when the mouse cursor leaves the button.
+ if (menu.item[menu.highlightedItem].enabled)
+ redrawText(menu);
+ }
+
+ for (int i = 0; i < menu.numberOfItems; ++i) {
+ if (!menu.item[i].enabled)
+ continue;
+
+ x1 = menu.x + menu.item[i].x;
+ y1 = menu.y + menu.item[i].y;
+
+ x2 = x1 + menu.item[i].width;
+ y2 = y1 + menu.item[i].height;
+
+ if (mouseX > x1 && mouseX < x2 &&
+ mouseY > y1 && mouseY < y2) {
+
+ if (menu.highlightedItem != i || _vm->game() == GI_LOL) {
+ if (_vm->game() != GI_LOL) {
+ if (menu.item[menu.highlightedItem].enabled)
+ redrawText(menu);
+ }
+
+ menu.highlightedItem = i;
+ redrawHighlight(menu);
+ }
+ }
+ }
+
+ _screen->updateScreen();
+}
+
+void GUI_v1::redrawText(const Menu &menu) {
+ int textX;
+ int i = menu.highlightedItem;
+
+ int x1 = menu.x + menu.item[i].x;
+ int y1 = menu.y + menu.item[i].y;
+
+ int x2 = x1 + menu.item[i].width - 1;
+
+ if (menu.item[i].titleX >= 0)
+ textX = x1 + menu.item[i].titleX + 3;
+ else
+ textX = getMenuCenterStringX(getMenuItemTitle(menu.item[i]), x1, x2);
+
+ int textY = y1 + 2;
+ if (_vm->game() == GI_LOL) {
+ textY++;
+ printMenuText(getMenuItemTitle(menu.item[i]), textX, textY, menu.item[i].textColor, 0, 8);
+ } else {
+ Screen::FontId of = _screen->_currentFont;
+ if (menu.item[i].saveSlot > 0)
+ _screen->setFont(Screen::FID_8_FNT);
+ if (_vm->gameFlags().platform != Common::kPlatformAmiga)
+ printMenuText(getMenuItemTitle(menu.item[i]), textX - 1, textY + 1, defaultColor1(), 0, 0);
+ printMenuText(getMenuItemTitle(menu.item[i]), textX, textY, menu.item[i].textColor, 0, 0);
+ _screen->setFont(of);
+ }
+}
+
+void GUI_v1::redrawHighlight(const Menu &menu) {
+ int textX;
+ int i = menu.highlightedItem;
+
+ int x1 = menu.x + menu.item[i].x;
+ int y1 = menu.y + menu.item[i].y;
+
+ int x2 = x1 + menu.item[i].width - 1;
+
+ if (menu.item[i].titleX != -1)
+ textX = x1 + menu.item[i].titleX + 3;
+ else
+ textX = getMenuCenterStringX(getMenuItemTitle(menu.item[i]), x1, x2);
+
+ int textY = y1 + 2;
+
+ if (_vm->game() == GI_LOL) {
+ textY++;
+ printMenuText(getMenuItemTitle(menu.item[i]), textX, textY, menu.item[i].highlightColor, 0, 8);
+ } else {
+ Screen::FontId of = _screen->_currentFont;
+ if (menu.item[i].saveSlot > 0)
+ _screen->setFont(Screen::FID_8_FNT);
+ if (_vm->gameFlags().platform != Common::kPlatformAmiga)
+ printMenuText(getMenuItemTitle(menu.item[i]), textX - 1, textY + 1, defaultColor1(), 0, 0);
+ printMenuText(getMenuItemTitle(menu.item[i]), textX, textY, menu.item[i].highlightColor, 0, 0);
+ _screen->setFont(of);
+ }
+}
+
+void GUI_v1::updateAllMenuButtons() {
+ for (Button *cur = _menuButtonList; cur; cur = cur->nextButton)
+ updateMenuButton(cur);
+}
+
+void GUI_v1::updateMenuButton(Button *button) {
+ if (!_displayMenu)
+ return;
+
+ _screen->hideMouse();
+ updateButton(button);
+ _screen->updateScreen();
+ _screen->showMouse();
+}
+
+void GUI_v1::updateButton(Button *button) {
+ if (!button || (button->flags & 8))
+ return;
+
+ if (button->flags2 & 1)
+ button->flags2 &= 0xFFF7;
+ else
+ button->flags2 |= 8;
+
+ button->flags2 &= 0xFFFC;
+
+ if (button->flags2 & 4)
+ button->flags2 |= 0x10;
+ else
+ button->flags2 &= 0xEEEF;
+
+ button->flags2 &= 0xFFFB;
+
+ processButton(button);
+}
+
+int GUI_v1::redrawButtonCallback(Button *button) {
+ if (!_displayMenu)
+ return 0;
+
+ _screen->hideMouse();
+ if (_vm->gameFlags().platform == Common::kPlatformAmiga)
+ _screen->drawBox(button->x + 1, button->y + 1, button->x + button->width - 1, button->y + button->height - 1, 17);
+ else
+ _screen->drawBox(button->x + 1, button->y + 1, button->x + button->width - 1, button->y + button->height - 1, 0xF8);
+ _screen->showMouse();
+
+ return 0;
+}
+
+int GUI_v1::redrawShadedButtonCallback(Button *button) {
+ if (!_displayMenu)
+ return 0;
+
+ _screen->hideMouse();
+ if (_vm->gameFlags().platform == Common::kPlatformAmiga)
+ _screen->drawShadedBox(button->x, button->y, button->x + button->width, button->y + button->height, 31, 18);
+ else
+ _screen->drawShadedBox(button->x, button->y, button->x + button->width, button->y + button->height, 0xF9, 0xFA);
+ _screen->showMouse();
+
+ return 0;
+}
+
+void GUI_v1::checkTextfieldInput() {
+ Common::Event event;
+
+ uint32 now = _vm->_system->getMillis();
+
+ bool running = true;
+ int keys = 0;
+ while (_vm->_eventMan->pollEvent(event) && running) {
+ switch (event.type) {
+ case Common::EVENT_KEYDOWN:
+ if (event.kbd.keycode == Common::KEYCODE_q && event.kbd.hasFlags(Common::KBD_CTRL))
+ _vm->quitGame();
+ else
+ _keyPressed = event.kbd;
+ running = false;
+ break;
+
+ case Common::EVENT_LBUTTONDOWN:
+ case Common::EVENT_LBUTTONUP: {
+ Common::Point pos = _vm->getMousePos();
+ _vm->_mouseX = pos.x;
+ _vm->_mouseY = pos.y;
+ keys = event.type == Common::EVENT_LBUTTONDOWN ? 199 : (200 | 0x800);
+ running = false;
+ } break;
+
+ case Common::EVENT_MOUSEMOVE: {
+ Common::Point pos = _vm->getMousePos();
+ _vm->_mouseX = pos.x;
+ _vm->_mouseY = pos.y;
+
+ _vm->_system->updateScreen();
+ _lastScreenUpdate = now;
+ } break;
+
+ default:
+ break;
+ }
+ }
+
+ if (now - _lastScreenUpdate > 50) {
+ _vm->_system->updateScreen();
+ _lastScreenUpdate = now;
+ }
+
+ processButtonList(_menuButtonList, keys | 0x8000, 0);
+ _vm->_system->delayMillis(3);
+}
+
+void GUI_v1::printMenuText(const char *str, int x, int y, uint8 c0, uint8 c1, uint8 c2) {
+ _text->printText(str, x, y, c0, c1, c2);
+}
+
+int GUI_v1::getMenuCenterStringX(const char *str, int x1, int x2) {
+ return _text->getCenterStringX(str, x1, x2);
+}
+
+#pragma mark -
+
+MainMenu::MainMenu(KyraEngine_v1 *vm) : _vm(vm), _screen(0) {
+ _screen = _vm->screen();
+ _nextUpdate = 0;
+ _system = g_system;
+}
+
+void MainMenu::init(StaticData data, Animation anim) {
+ _static = data;
+ _anim = anim;
+ _animIntern.curFrame = _anim.startFrame;
+ _animIntern.direction = 1;
+}
+
+void MainMenu::updateAnimation() {
+ if (_anim.anim) {
+ uint32 now = _system->getMillis();
+ if (now > _nextUpdate) {
+ _nextUpdate = now + _anim.delay * _vm->tickLength();
+
+ _anim.anim->displayFrame(_animIntern.curFrame, 0, 0, 0, 0, 0, 0);
+ _animIntern.curFrame += _animIntern.direction;
+ if (_animIntern.curFrame < _anim.startFrame) {
+ _animIntern.curFrame = _anim.startFrame;
+ _animIntern.direction = 1;
+ } else if (_animIntern.curFrame > _anim.endFrame) {
+ _animIntern.curFrame = _anim.endFrame;
+ _animIntern.direction = -1;
+ }
+ }
+ }
+
+ _screen->updateScreen();
+}
+
+bool MainMenu::getInput() {
+ Common::Event event;
+ Common::EventManager *eventMan = _vm->getEventManager();
+
+ bool updateScreen = false;
+
+ while (eventMan->pollEvent(event)) {
+ switch (event.type) {
+ case Common::EVENT_LBUTTONUP:
+ return true;
+
+ case Common::EVENT_MOUSEMOVE:
+ updateScreen = true;
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ if (updateScreen)
+ _system->updateScreen();
+ return false;
+}
+
+int MainMenu::handle(int dim) {
+ int command = -1;
+
+ uint8 colorMap[16];
+ memset(colorMap, 0, sizeof(colorMap));
+ _screen->setTextColorMap(colorMap);
+
+ Screen::FontId oldFont = _screen->setFont(_static.font);
+ int charWidthBackUp = _screen->_charWidth;
+
+ if (_vm->game() != GI_LOL)
+ _screen->_charWidth = -2;
+ _screen->setScreenDim(dim);
+
+ int backUpX = _screen->_curDim->sx;
+ int backUpY = _screen->_curDim->sy;
+ int backUpWidth = _screen->_curDim->w;
+ int backUpHeight = _screen->_curDim->h;
+ _screen->copyRegion(backUpX, backUpY, backUpX, backUpY, backUpWidth, backUpHeight, 0, 3);
+
+ int x = _screen->_curDim->sx << 3;
+ int y = _screen->_curDim->sy;
+ int width = _screen->_curDim->w << 3;
+ int height = _screen->_curDim->h;
+
+ drawBox(x, y, width, height, 1);
+ drawBox(x + 1, y + 1, width - 2, height - 2, 0);
+
+ int selected = 0;
+
+ draw(selected);
+
+ while (!_screen->isMouseVisible())
+ _screen->showMouse();
+
+ int fh = _screen->getFontHeight();
+ if (_vm->gameFlags().lang == Common::JA_JPN)
+ fh++;
+
+ int textPos = ((_screen->_curDim->w >> 1) + _screen->_curDim->sx) << 3;
+
+ Common::Rect menuRect(x + 16, y + 4, x + width - 16, y + 4 + fh * _static.menuTable[3]);
+
+ while (!_vm->shouldQuit()) {
+ updateAnimation();
+ bool mousePressed = getInput();
+
+ Common::Point mouse = _vm->getMousePos();
+ if (menuRect.contains(mouse)) {
+ int item = (mouse.y - menuRect.top) / fh;
+
+ if (item != selected) {
+ printString("%s", textPos, menuRect.top + selected * fh, _static.menuTable[5], 0, 5, _static.strings[selected]);
+ printString("%s", textPos, menuRect.top + item * fh, _static.menuTable[6], 0, 5, _static.strings[item]);
+
+ selected = item;
+ }
+
+ if (mousePressed) {
+ for (int i = 0; i < 3; i++) {
+ printString("%s", textPos, menuRect.top + selected * fh, _static.menuTable[5], 0, 5, _static.strings[selected]);
+ _screen->updateScreen();
+ _system->delayMillis(50);
+ printString("%s", textPos, menuRect.top + selected * fh, _static.menuTable[6], 0, 5, _static.strings[selected]);
+ _screen->updateScreen();
+ _system->delayMillis(50);
+ }
+ command = item;
+ break;
+ }
+ }
+ _system->delayMillis(10);
+ }
+
+ if (_vm->shouldQuit())
+ command = -1;
+
+ _screen->copyRegion(backUpX, backUpY, backUpX, backUpY, backUpWidth, backUpHeight, 3, 0);
+ _screen->_charWidth = charWidthBackUp;
+ _screen->setFont(oldFont);
+
+ return command;
+}
+
+void MainMenu::draw(int select) {
+ int top = _screen->_curDim->sy;
+ top += _static.menuTable[1];
+ int fh = _screen->getFontHeight();
+ if (_vm->gameFlags().lang == Common::JA_JPN)
+ fh++;
+
+ for (int i = 0; i < _static.menuTable[3]; ++i) {
+ int curY = top + i * fh;
+ int color = (i == select) ? _static.menuTable[6] : _static.menuTable[5];
+ printString("%s", ((_screen->_curDim->w >> 1) + _screen->_curDim->sx) << 3, curY, color, 0, 5, _static.strings[i]);
+ }
+}
+
+void MainMenu::drawBox(int x, int y, int w, int h, int fill) {
+ --w; --h;
+
+ if (fill)
+ _screen->fillRect(x, y, x + w, y + h, _static.colorTable[0]);
+
+ _screen->drawClippedLine(x, y + h, x + w, y + h, _static.colorTable[1]);
+ _screen->drawClippedLine(x + w, y, x + w, y + h, _static.colorTable[1]);
+ _screen->drawClippedLine(x, y, x + w, y, _static.colorTable[2]);
+ _screen->drawClippedLine(x, y, x, y + h, _static.colorTable[2]);
+
+ _screen->setPagePixel(_screen->_curPage, x, y + h, _static.colorTable[3]);
+ _screen->setPagePixel(_screen->_curPage, x + w, y, _static.colorTable[3]);
+}
+
+void MainMenu::printString(const char *format, int x, int y, int col1, int col2, int flags, ...) {
+ if (!format)
+ return;
+
+ va_list vaList;
+ va_start(vaList, flags);
+ Common::String string = Common::String::vformat(format, vaList);
+ va_end(vaList);
+
+ if (flags & 1)
+ x -= _screen->getTextWidth(string.c_str()) >> 1;
+
+ if (flags & 2)
+ x -= _screen->getTextWidth(string.c_str());
+
+ if (_vm->gameFlags().use16ColorMode)
+ flags &= 3;
+
+ if (flags & 4) {
+ _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.c_str(), x - 1, y, 227, col2);
+ _screen->printText(string.c_str(), x, y + 1, 227, col2);
+ }
+
+ _screen->printText(string.c_str(), x, y, col1, col2);
+}
+
+} // End of namespace Kyra
diff --git a/engines/kyra/gui_v1.h b/engines/kyra/gui_v1.h
new file mode 100644
index 0000000000..260edae8e5
--- /dev/null
+++ b/engines/kyra/gui_v1.h
@@ -0,0 +1,197 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef KYRA_GUI_V1_H
+#define KYRA_GUI_V1_H
+
+#include "kyra/gui.h"
+
+namespace Kyra {
+
+struct MenuItem {
+ bool enabled;
+
+ const char *itemString;
+ uint16 itemId;
+
+ int16 x, y;
+ uint16 width, height;
+
+ uint8 textColor, highlightColor;
+
+ int16 titleX;
+
+ uint8 color1, color2;
+ uint8 bkgdColor;
+
+ Button::Callback callback;
+
+ int16 saveSlot;
+
+ const char *labelString;
+ uint16 labelId;
+ int16 labelX, labelY;
+
+ uint16 keyCode;
+};
+
+struct Menu {
+ int16 x, y;
+ uint16 width, height;
+
+ uint8 bkgdColor;
+ uint8 color1, color2;
+
+ const char *menuNameString;
+ uint16 menuNameId;
+
+ uint8 textColor;
+ int16 titleX, titleY;
+
+ uint8 highlightedItem;
+
+ uint8 numberOfItems;
+
+ int16 scrollUpButtonX, scrollUpButtonY;
+ int16 scrollDownButtonX, scrollDownButtonY;
+
+ MenuItem item[7];
+};
+
+class TextDisplayer;
+
+class GUI_v1 : public GUI {
+public:
+ GUI_v1(KyraEngine_v1 *vm);
+ virtual ~GUI_v1() {}
+
+ // button specific
+ virtual Button *addButtonToList(Button *list, Button *newButton);
+
+ virtual void processButton(Button *button) = 0;
+ virtual int processButtonList(Button *buttonList, uint16 inputFlags, int8 mouseWheel) = 0;
+
+ virtual int redrawShadedButtonCallback(Button *button);
+ virtual int redrawButtonCallback(Button *button);
+
+ // menu specific
+ virtual void initMenuLayout(Menu &menu);
+ void initMenu(Menu &menu);
+
+ void processHighlights(Menu &menu);
+
+ // utilities for thumbnail creation
+ virtual void createScreenThumbnail(Graphics::Surface &dst) = 0;
+
+protected:
+ TextDisplayer *_text;
+
+ Button *_menuButtonList;
+ bool _displayMenu;
+ bool _displaySubMenu;
+ bool _cancelSubMenu;
+
+ virtual void printMenuText(const char *str, int x, int y, uint8 c0, uint8 c1, uint8 c2);
+ virtual int getMenuCenterStringX(const char *str, int x1, int x2);
+
+ Button::Callback _redrawShadedButtonFunctor;
+ Button::Callback _redrawButtonFunctor;
+
+ virtual Button *getButtonListData() = 0;
+ virtual Button *getScrollUpButton() = 0;
+ virtual Button *getScrollDownButton() = 0;
+
+ virtual Button::Callback getScrollUpButtonHandler() const = 0;
+ virtual Button::Callback getScrollDownButtonHandler() const = 0;
+
+ virtual uint8 defaultColor1() const = 0;
+ virtual uint8 defaultColor2() const = 0;
+
+ virtual const char *getMenuTitle(const Menu &menu) = 0;
+ virtual const char *getMenuItemTitle(const MenuItem &menuItem) = 0;
+ virtual const char *getMenuItemLabel(const MenuItem &menuItem) = 0;
+
+ void updateAllMenuButtons();
+ void updateMenuButton(Button *button);
+ virtual void updateButton(Button *button);
+
+ void redrawText(const Menu &menu);
+ void redrawHighlight(const Menu &menu);
+
+ uint32 _lastScreenUpdate;
+ void checkTextfieldInput();
+};
+
+class Movie;
+
+class MainMenu {
+public:
+ MainMenu(KyraEngine_v1 *vm);
+ virtual ~MainMenu() {}
+
+ struct Animation {
+ Animation() : anim(0), startFrame(0), endFrame(0), delay(0) {}
+
+ Movie *anim;
+ int startFrame;
+ int endFrame;
+ int delay;
+ };
+
+ struct StaticData {
+ const char *strings[5];
+
+ uint8 menuTable[7];
+ uint8 colorTable[4];
+
+ Screen::FontId font;
+ uint8 altColor;
+ };
+
+ void init(StaticData data, Animation anim);
+ int handle(int dim);
+private:
+ KyraEngine_v1 *_vm;
+ Screen *_screen;
+ OSystem *_system;
+
+ StaticData _static;
+ struct AnimIntern {
+ int curFrame;
+ int direction;
+ };
+ Animation _anim;
+ AnimIntern _animIntern;
+
+ uint32 _nextUpdate;
+
+ void updateAnimation();
+ void draw(int select);
+ void drawBox(int x, int y, int w, int h, int fill);
+ bool getInput();
+
+ void printString(const char *string, int x, int y, int col1, int col2, int flags, ...) GCC_PRINTF(2, 8);
+};
+
+} // end of namesapce Kyra
+
+#endif
diff --git a/engines/kyra/gui_v2.cpp b/engines/kyra/gui_v2.cpp
index c0477f29f1..580adb0e5d 100644
--- a/engines/kyra/gui_v2.cpp
+++ b/engines/kyra/gui_v2.cpp
@@ -30,7 +30,7 @@
namespace Kyra {
-GUI_v2::GUI_v2(KyraEngine_v2 *vm) : GUI(vm), _vm(vm), _screen(vm->screen_v2()) {
+GUI_v2::GUI_v2(KyraEngine_v2 *vm) : GUI_v1(vm), _vm(vm), _screen(vm->screen_v2()) {
_backUpButtonList = _specialProcessButton = 0;
_buttonListChanged = false;
_lastScreenUpdate = 0;
@@ -48,7 +48,7 @@ GUI_v2::GUI_v2(KyraEngine_v2 *vm) : GUI(vm), _vm(vm), _screen(vm->screen_v2()) {
}
Button *GUI_v2::addButtonToList(Button *list, Button *newButton) {
- list = GUI::addButtonToList(list, newButton);
+ list = GUI_v1::addButtonToList(list, newButton);
_buttonListChanged = true;
return list;
}
@@ -211,7 +211,7 @@ int GUI_v2::processButtonList(Button *buttonList, uint16 inputFlag, int8 mouseWh
bool progress = false;
- if (mouseX >= x && mouseY >= y && mouseX <= x+buttonList->width && mouseY <= y+buttonList->height)
+ if (mouseX >= x && mouseY >= y && mouseX <= x + buttonList->width && mouseY <= y + buttonList->height)
progress = true;
buttonList->flags2 &= ~0x80;
@@ -425,7 +425,7 @@ void GUI_v2::renewHighlight(Menu &menu) {
int x = item.x + menu.x; int y = item.y + menu.y;
int x2 = x + item.width - 1; int y2 = y + item.height - 1;
redrawText(menu);
- _screen->fillRect(x+2, y+2, x2-2, y2-2, item.bkgdColor);
+ _screen->fillRect(x + 2, y + 2, x2 - 2, y2 - 2, item.bkgdColor);
redrawHighlight(menu);
_screen->updateScreen();
}
@@ -594,7 +594,7 @@ int GUI_v2::cancelLoadMenu(Button *caller) {
}
int GUI_v2::saveMenu(Button *caller) {
- updateSaveList();
+ updateSaveFileList(_vm->_targetName);
updateMenuButton(caller);
@@ -690,7 +690,7 @@ int GUI_v2::cancelSaveMenu(Button *caller) {
}
int GUI_v2::deleteMenu(Button *caller) {
- updateSaveList();
+ updateSaveFileList(_vm->_targetName);
updateMenuButton(caller);
if (_saveSlots.size() < 2) {
@@ -736,10 +736,10 @@ int GUI_v2::deleteMenu(Button *caller) {
break;
// We are only renaming all savefiles until we get some slots missing
// Also not rename quicksave slot filenames
- if (*(i-1) != *i || *i >= 990)
+ if (*(i - 1) != *i || *i >= 990)
break;
Common::String oldName = _vm->getSavegameFilename(*i);
- Common::String newName = _vm->getSavegameFilename(*i-1);
+ Common::String newName = _vm->getSavegameFilename(*i - 1);
_vm->_saveFileMan->renameSavefile(oldName, newName);
}
_saveMenu.menuNameId = _vm->gameFlags().isTalkie ? 9 : 17;
@@ -845,7 +845,7 @@ int GUI_v2::getCharWidth(uint8 c) {
}
void GUI_v2::drawTextfieldBlock(int x, int y, uint8 c) {
- _screen->fillRect(x+1, y+1, x+7, y+8, c);
+ _screen->fillRect(x + 1, y + 1, x + 7, y + 8, c);
}
bool GUI_v2::choiceDialog(int name, bool type) {
diff --git a/engines/kyra/gui_v2.h b/engines/kyra/gui_v2.h
index ef95c0301a..bdbcce1c4f 100644
--- a/engines/kyra/gui_v2.h
+++ b/engines/kyra/gui_v2.h
@@ -23,7 +23,7 @@
#ifndef KYRA_GUI_V2_H
#define KYRA_GUI_V2_H
-#include "kyra/gui.h"
+#include "kyra/gui_v1.h"
namespace Kyra {
@@ -99,7 +99,7 @@ namespace Kyra {
class KyraEngine_v2;
class Screen_v2;
-class GUI_v2 : public GUI {
+class GUI_v2 : public GUI_v1 {
public:
GUI_v2(KyraEngine_v2 *vm);
diff --git a/engines/kyra/items_eob.cpp b/engines/kyra/items_eob.cpp
new file mode 100644
index 0000000000..0994e12e4f
--- /dev/null
+++ b/engines/kyra/items_eob.cpp
@@ -0,0 +1,731 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifdef ENABLE_EOB
+
+#include "kyra/eobcommon.h"
+#include "kyra/resource.h"
+#include "kyra/sound.h"
+
+namespace Kyra {
+
+void EoBCoreEngine::loadItemDefs() {
+ Common::SeekableReadStream *s = _res->createReadStream("item.dat");
+ memset(_items, 0, sizeof(EoBItem) * 600);
+ _numItems = s->readUint16LE();
+
+ for (int i = 0; i < 600; i++)
+ _items[i].block = -1;
+
+ for (int i = 0; i < _numItems; i++) {
+ _items[i].nameUnid = s->readByte();
+ _items[i].nameId = s->readByte();
+ _items[i].flags = s->readByte();
+ _items[i].icon = s->readSByte();
+ _items[i].type = s->readSByte();
+ _items[i].pos = s->readSByte();
+ _items[i].block = s->readSint16LE();
+ _items[i].next = s->readSint16LE();
+ _items[i].prev = s->readSint16LE();
+ _items[i].level = s->readSByte();
+ _items[i].value = s->readSByte();
+ }
+
+ _numItemNames = s->readUint16LE();
+ for (int i = 0; i < _numItemNames; i++)
+ s->read(_itemNames[i], 35);
+
+ delete s;
+
+ s = _res->createReadStream("itemtype.dat");
+ uint16 numTypes = s->readUint16LE();
+
+ delete[] _itemTypes;
+ _itemTypes = new EoBItemType[65];
+ memset(_itemTypes, 0, sizeof(EoBItemType) * 65);
+
+ for (int i = 0; i < numTypes; i++) {
+ _itemTypes[i].invFlags = s->readUint16LE();
+ _itemTypes[i].handFlags = s->readUint16LE();
+ _itemTypes[i].armorClass = s->readSByte();
+ _itemTypes[i].allowedClasses = s->readSByte();
+ _itemTypes[i].requiredHands = s->readSByte();
+ _itemTypes[i].dmgNumDiceS = s->readSByte();
+ _itemTypes[i].dmgNumPipsS = s->readSByte();
+ _itemTypes[i].dmgIncS = s->readSByte();
+ _itemTypes[i].dmgNumDiceL = s->readSByte();
+ _itemTypes[i].dmgNumPipsL = s->readSByte();
+ _itemTypes[i].dmgIncL = s->readSByte();
+ _itemTypes[i].unk1 = s->readByte();
+ _itemTypes[i].extraProperties = s->readUint16LE();
+ }
+
+ delete s;
+}
+
+Kyra::Item EoBCoreEngine::duplicateItem(Item itemIndex) {
+ EoBItem *itm = &_items[itemIndex];
+
+ if (itm->block == -1)
+ return 0;
+
+ Item i = 1;
+ bool foundSlot = false;
+
+ for (; i < 600; i++) {
+ if (_items[i].block == -1) {
+ foundSlot = true;
+ break;
+ }
+ }
+
+ if (!foundSlot)
+ return 0;
+
+ memcpy(&_items[i], itm, sizeof(EoBItem));
+ return i;
+}
+
+Item EoBCoreEngine::createItemOnCurrentBlock(Item itemIndex) {
+ Item itm = duplicateItem(itemIndex);
+ setItemPosition((Item *)&_levelBlockProperties[_currentBlock].drawObjects, _currentBlock, itm, _dropItemDirIndex[(_currentDirection << 2) + rollDice(1, 2, -1)]);
+ return itm;
+}
+
+void EoBCoreEngine::setItemPosition(Item *itemQueue, int block, Item item, int pos) {
+ if (!item)
+ return;
+
+ EoBItem *itm = &_items[item];
+ itm->pos = pos;
+ itm->block = block;
+ itm->level = block < 0 ? 0xff : _currentLevel;
+
+ if (!*itemQueue) {
+ *itemQueue = itm->next = itm->prev = item;
+ } else {
+ EoBItem *itmQ = &_items[*itemQueue];
+ EoBItem *itmQN = &_items[itmQ->next];
+ itm->prev = itmQN->prev;
+ itm->next = itmQ->next;
+ *itemQueue = itmQN->prev = itmQ->next = item;
+ }
+}
+
+void EoBCoreEngine::createInventoryItem(EoBCharacter *c, Item itemIndex, int16 itemValue, int preferedInventorySlot) {
+ if (itemIndex <= 0)
+ return;
+
+ itemIndex = duplicateItem(itemIndex);
+ _items[itemIndex].flags |= 0x40;
+
+ if (itemValue != -1)
+ _items[itemIndex].value = itemValue;
+
+ if (itemValue && ((_itemTypes[_items[itemIndex].type].extraProperties & 0x7f) < 4))
+ _items[itemIndex].flags |= 0x80;
+
+ if (c->inventory[preferedInventorySlot]) {
+ for (int i = 2; i < 16; i++) {
+ if (!c->inventory[i]) {
+ c->inventory[i] = itemIndex;
+ return;
+ }
+ }
+ } else {
+ c->inventory[preferedInventorySlot] = itemIndex;
+ }
+}
+
+int EoBCoreEngine::deleteInventoryItem(int charIndex, int slot) {
+ int itm = (slot == -1) ? _itemInHand : _characters[charIndex].inventory[slot];
+ _items[itm].block = -1;
+
+ if (slot == -1) {
+ setHandItem(0);
+ } else {
+ _characters[charIndex].inventory[slot] = 0;
+
+ if (_currentControlMode == 1)
+ gui_drawInventoryItem(slot, 1, 0);
+
+ if (_currentControlMode == 0)
+ gui_drawCharPortraitWithStats(charIndex);
+ }
+
+ return _items[itm].value;
+}
+
+void EoBCoreEngine::deleteBlockItem(uint16 block, int type) {
+ uint16 itm = _levelBlockProperties[block].drawObjects;
+ if (!itm)
+ return;
+
+ _levelBlockProperties[block].drawObjects = 0;
+
+ for (uint16 i2 = itm, i = 0; itm != i2 || !i; i++) {
+ if (type == _items[itm].type || type == -1) {
+ _items[itm].block = -1;
+ _items[itm].level = 0;
+ uint16 i3 = itm;
+ itm = _items[itm].prev;
+ _items[i3].prev = _items[i3].next = 0;
+ } else {
+ uint16 i3 = itm;
+ itm = _items[itm].prev;
+ _items[i3].prev = _items[i3].next = 0;
+ setItemPosition((Item *)&_levelBlockProperties[block].drawObjects, block, i3, _items[i3].pos);
+ }
+ }
+}
+
+int EoBCoreEngine::validateInventorySlotForItem(Item item, int charIndex, int slot) {
+ if (item < 0)
+ return 0;
+
+ if (slot == 17 && item && !itemUsableByCharacter(charIndex, item)) {
+ _txt->printMessage(_validateArmorString[0], -1, _characters[charIndex].name);
+ return 0;
+ }
+
+ int itm = _characters[charIndex].inventory[slot];
+ int ex = _itemTypes[_items[itm].type].extraProperties & 0x7f;
+
+ if (_items[itm].flags & 0x20 && (_flags.gameID == GI_EOB1 || slot < 2)) {
+ if (_flags.gameID == GI_EOB2 && ex > 0 && ex < 4)
+ _txt->printMessage(_validateCursedString[0], -1, _characters[charIndex].name);
+ return 0;
+ }
+
+ uint16 v = item ? _itemTypes[_items[item].type].invFlags : 0xffff;
+ if (v & _slotValidationFlags[slot])
+ return 1;
+
+ _txt->printMessage(_validateNoDropString[0]);
+ return 0;
+}
+
+int EoBCoreEngine::stripPartyItems(int16 itemType, int16 itemValue, int handleValueMode, int numItems) {
+ int itemsLeft = numItems;
+
+ for (bool runloop = true; runloop && itemsLeft;) {
+ runloop = false;
+ for (int i = 0; i < 6 && itemsLeft; i++) {
+ if (!testCharacter(i, 1))
+ continue;
+
+ for (int ii = 0; ii < 27 && itemsLeft; ii++) {
+ if (ii == 16)
+ continue;
+
+ Item itm = _characters[i].inventory[ii];
+ if ((_items[itm].type == itemType) && ((handleValueMode == -1 && _items[itm].value <= itemValue) || (handleValueMode == 0 && _items[itm].value == itemValue) || (handleValueMode == 1 && _items[itm].value >= itemValue))) {
+ _characters[i].inventory[ii] = 0;
+ _items[itm].block = -1;
+ itemsLeft--;
+ runloop = true;
+ }
+ }
+ }
+ }
+
+ return numItems - itemsLeft;
+}
+
+bool EoBCoreEngine::deletePartyItems(int16 itemType, int16 itemValue) {
+ bool res = false;
+ for (int i = 0; i < 6; i++) {
+ if (!testCharacter(i, 1))
+ continue;
+
+ EoBCharacter *c = &_characters[i];
+ for (int slot = checkInventoryForItem(i, itemType, itemValue); slot != -1; slot = checkInventoryForItem(i, itemType, itemValue)) {
+ int itm = c->inventory[slot];
+ _items[itm].block = -1;
+ c->inventory[slot] = 0;
+ res = true;
+
+ if (!_dialogueField) {
+ if (_currentControlMode == 0 && slot < 2 && i < 5)
+ gui_drawWeaponSlot(i, slot);
+
+ if (_currentControlMode == 1 && i == _updateCharNum)
+ gui_drawInventoryItem(slot, 1, 0);
+ }
+ }
+ }
+
+ if (_itemInHand > 0) {
+ if ((itemType == -1 || itemType == _items[_itemInHand].type) && (itemValue == -1 || itemValue == _items[_itemInHand].value)) {
+ _items[_itemInHand].block = -1;
+ setHandItem(0);
+ res = true;
+ }
+ }
+
+ return res;
+}
+
+int EoBCoreEngine::itemUsableByCharacter(int charIndex, Item item) {
+ if (!item)
+ return 1;
+
+ return (_itemTypes[_items[item].type].allowedClasses & _classModifierFlags[_characters[charIndex].cClass]);
+}
+
+int EoBCoreEngine::countQueuedItems(Item itemQueue, int16 id, int16 type, int count, int includeFlyingItems) {
+ uint16 o1 = itemQueue;
+ uint16 o2 = o1;
+
+ if (!o1)
+ return 0;
+
+ int res = 0;
+
+ for (bool forceLoop = true; o1 != o2 || forceLoop; o1 = _items[o1].prev) {
+ EoBItem *itm = &_items[o1];
+ forceLoop = false;
+ if (id != -1 || type != -1) {
+ if (((id != -1) || (id == -1 && type != itm->type)) && ((type != -1) || (type == -1 && id != o1)))
+ continue;
+ }
+
+ if (!includeFlyingItems) {
+ if (itm->pos > 3 && itm->pos < 8)
+ continue;
+ }
+
+ if (!count)
+ return o1;
+
+ res++;
+ }
+
+ return res;
+}
+
+int EoBCoreEngine::getQueuedItem(Item *items, int pos, int id) {
+ Item o1 = *items;
+ Item o2 = o1;
+
+ if (!o1)
+ return 0;
+
+ EoBItem *itm = &_items[o1];
+
+ for (bool forceLoop = true; o1 != o2 || forceLoop; o1 = itm->prev) {
+ itm = &_items[o1];
+ forceLoop = false;
+ if ((id != -1 || (id == -1 && itm->pos != pos)) && id != o1)
+ continue;
+
+ Item n = itm->next;
+ Item p = itm->prev;
+ _items[n].prev = p;
+ _items[p].next = n;
+ itm->next = itm->prev = itm->block = 0;
+ itm->level = 0;
+ if (o1 == *items)
+ *items = p;
+ if (o1 == *items)
+ *items = 0;
+
+ return o1;
+ }
+
+ return 0;
+}
+
+void EoBCoreEngine::printFullItemName(Item item) {
+ EoBItem *itm = &_items[item];
+ const char *nameUnid = _itemNames[itm->nameUnid];
+ const char *nameId = _itemNames[itm->nameId];
+ uint8 f = _itemTypes[itm->type].extraProperties & 0x7f;
+ int8 v = itm->value;
+
+ const char *tstr2 = 0;
+ const char *tstr3 = 0;
+
+ bool correctSuffixCase = false;
+
+ Common::String tmpString;
+
+ if ((itm->flags & 0x40) && !strlen(nameId)) {
+ switch (f) {
+ case 0:
+ case 1:
+ case 2:
+ case 3:
+ if (v == 0)
+ tmpString = nameUnid;
+ else if (v < 0)
+ tmpString = _flags.gameID == GI_EOB1 ? Common::String::format(_cursedString[0], nameUnid, v) : Common::String::format(_cursedString[0], v, nameUnid);
+ else
+ tmpString = _flags.gameID == GI_EOB1 ? Common::String::format(_enchantedString[0], nameUnid, v) : Common::String::format(_enchantedString[0], v, nameUnid);
+ break;
+
+ case 9:
+ tstr2 = _magicObjectStrings[0];
+ tstr3 = _spells[v].name;
+ correctSuffixCase = true;
+ break;
+
+ case 10:
+ tstr2 = _magicObjectStrings[1];
+ tstr3 = _spells[_flags.gameID == GI_EOB1 ? (_clericSpellOffset + v) : v].name;
+ correctSuffixCase = true;
+ break;
+
+ case 14:
+ tstr2 = _magicObjectStrings[3];
+ if (_flags.gameID == GI_EOB1)
+ v--;
+ tstr3 = _suffixStringsPotions[v];
+ break;
+
+ case 16:
+ tstr2 = _magicObjectStrings[2];
+ tstr3 = _suffixStringsRings[v];
+ break;
+
+ case 18:
+ if (_flags.gameID == GI_EOB2 && v == 5) {
+ if (_flags.lang == Common::DE_DEU)
+ tstr2 = _magicObjectString5[0];
+ else
+ tstr3 = _magicObjectString5[0];
+ correctSuffixCase = true;
+ } else {
+ tstr2 = _magicObjectStrings[4];
+ }
+ tstr3 = _suffixStringsWands[v];
+ break;
+
+ default:
+ tmpString = nameUnid;
+ break;
+ }
+
+
+ if (tstr3) {
+ if (!tstr2) {
+ tmpString = tstr3;
+ } else {
+ if (correctSuffixCase) {
+ if (tstr2 == _magicObjectString5[0])
+ tmpString = Common::String::format(_patternGrFix2[0], tstr2, tstr3);
+ else
+ tmpString = Common::String::format(_patternGrFix1[0], tstr2, tstr3);
+ } else {
+ tmpString = Common::String::format(_patternSuffix[0], tstr2, tstr3);
+ }
+ }
+ }
+ } else {
+ tmpString = (itm->flags & 0x40) ? nameId : nameUnid;
+ }
+
+ _txt->printMessage(tmpString.c_str());
+}
+
+void EoBCoreEngine::identifyQueuedItems(Item itemQueue) {
+ if (!itemQueue)
+ return;
+
+ Item first = itemQueue;
+ do {
+ _items[itemQueue].flags |= 0x40;
+ itemQueue = _items[itemQueue].prev;
+
+ } while (first != itemQueue);
+}
+
+void EoBCoreEngine::drawItemIconShape(int pageNum, Item itemId, int x, int y) {
+ int icn = _items[itemId].icon;
+ bool applyBluePal = ((_partyEffectFlags & 2) && (_items[itemId].flags & 0x80)) ? true : false;
+ const uint8 *ovl = 0;
+
+ if (applyBluePal) {
+ if (_flags.gameID == GI_EOB1) {
+ ovl = (_configRenderMode == Common::kRenderCGA) ? _itemsOverlayCGA : &_itemsOverlay[icn << 4];
+ } else {
+ _screen->setFadeTableIndex(3);
+ _screen->setShapeFadeMode(1, true);
+ }
+ }
+
+ _screen->drawShape(pageNum, _itemIconShapes[icn], x, y, 0, ovl ? 2 : 0, ovl);
+
+ if (applyBluePal) {
+ _screen->setFadeTableIndex(4);
+ _screen->setShapeFadeMode(1, false);
+ }
+}
+
+bool EoBCoreEngine::isMagicEffectItem(Item itemIndex) {
+ return (itemIndex > 10 && itemIndex < 18);
+}
+
+bool EoBCoreEngine::checkInventoryForRings(int charIndex, int itemValue) {
+ for (int i = 25; i <= 26; i++) {
+ int itm = _characters[charIndex].inventory[i];
+ if (itm && _items[itm].type == 47 && _items[itm].value == itemValue)
+ return true;
+ }
+ return false;
+}
+
+void EoBCoreEngine::eatItemInHand(int charIndex) {
+ EoBCharacter *c = &_characters[charIndex];
+ if (!testCharacter(charIndex, 5)) {
+ _txt->printMessage(_warningStrings[1], -1, c->name);
+ } else if (_itemInHand && _items[_itemInHand].type != 31 && !(_flags.gameID == GI_EOB1 && _items[_itemInHand].type == 49)) {
+ _txt->printMessage(_warningStrings[_flags.gameID == GI_EOB1 ? 2 : 3]);
+ } else if (_items[_itemInHand].value == -1) {
+ printWarning(_warningStrings[2]);
+ } else {
+ c->food += _items[_itemInHand].value;
+ if (c->food > 100)
+ c->food = 100;
+
+ _items[_itemInHand].block = -1;
+ setHandItem(0);
+ gui_drawFoodStatusGraph(charIndex);
+ _screen->updateScreen();
+ snd_playSoundEffect(9);
+ }
+}
+
+bool EoBCoreEngine::launchObject(int charIndex, Item item, uint16 startBlock, int startPos, int dir, int type) {
+ EoBFlyingObject *t = _flyingObjects;
+ int slot = 0;
+ for (; slot < 10; slot++) {
+ if (!t->enable)
+ break;
+ t++;
+ }
+
+ if (slot == 10)
+ return false;
+
+ setItemPosition((Item *)&_levelBlockProperties[startBlock].drawObjects, startBlock, item, startPos | 4);
+
+ t->enable = 1;
+ t->starting = 1;
+ t->flags = 0;
+ t->direction = dir;
+ t->distance = 12;
+ t->curBlock = startBlock;
+ t->curPos = startPos;
+ t->item = item;
+ t->objectType = type;
+ t->attackerId = charIndex;
+ t->callBackIndex = 0;
+
+ snd_playSoundEffect(type == 7 ? 26 : 11);
+ return true;
+}
+
+void EoBCoreEngine::launchMagicObject(int charIndex, int type, uint16 startBlock, int startPos, int dir) {
+ EoBFlyingObject *t = _flyingObjects;
+ int slot = 0;
+ for (; slot < 10; slot++) {
+ if (!t->enable)
+ break;
+ t++;
+ }
+
+ if (slot == 10)
+ return;
+
+ t->enable = 2;
+ t->starting = 1;
+ t->flags = _magicFlightObjectProperties[(type << 2) + 2];
+ t->direction = dir;
+ t->distance = _magicFlightObjectProperties[(type << 2) + 1];
+ t->curBlock = startBlock;
+ t->curPos = startPos;
+ t->item = type;
+ t->objectType = _magicFlightObjectProperties[(type << 2) + 3];
+ t->attackerId = charIndex;
+ t->callBackIndex = _magicFlightObjectProperties[type << 2];
+ _sceneUpdateRequired = true;
+}
+
+bool EoBCoreEngine::updateObjectFlight(EoBFlyingObject *fo, int block, int pos) {
+ uint8 wallFlags = _wllWallFlags[_levelBlockProperties[block].walls[fo->direction ^ 2]];
+ if (fo->enable == 1) {
+ if ((wallFlags & 1) || (fo->starting) || ((wallFlags & 2) && (_dscItemShapeMap[_items[fo->item].icon] >= 15))) {
+ getQueuedItem((Item *)&_levelBlockProperties[fo->curBlock].drawObjects, 0, fo->item);
+ setItemPosition((Item *)&_levelBlockProperties[block].drawObjects, block, fo->item, pos | 4);
+ fo->curBlock = block;
+ fo->curPos = pos;
+ fo->distance--;
+ return true;
+
+ } else {
+ _clickedSpecialFlag = 0x10;
+ specialWallAction(block, fo->direction);
+ return false;
+ }
+
+ } else {
+ if (!(wallFlags & 1) && (fo->curBlock != block))
+ return false;
+ fo->curBlock = block;
+ fo->curPos = pos;
+ if (fo->distance != 255)
+ fo->distance--;
+ }
+ return true;
+}
+
+bool EoBCoreEngine::updateFlyingObjectHitTest(EoBFlyingObject *fo, int block, int pos) {
+ if (fo->starting && (fo->curBlock != _currentBlock || fo->attackerId >= 0) && (!blockHasMonsters(fo->curBlock) || fo->attackerId < 0))
+ return false;
+
+ if (fo->enable == 2) {
+ if (fo->callBackIndex)
+ return (this->*_spells[fo->callBackIndex].endCallback)(fo);
+ }
+
+ if (blockHasMonsters(block)) {
+ for (int i = 0; i < 30; i++) {
+ if (!isMonsterOnPos(&_monsters[i], block, pos, 1))
+ continue;
+ if (flyingObjectMonsterHit(fo, i))
+ return true;
+ }
+
+ } else if (block == _currentBlock) {
+ return flyingObjectPartyHit(fo);
+ }
+
+ return false;
+}
+
+void EoBCoreEngine::explodeObject(EoBFlyingObject *fo, int block, Item item) {
+ if (_partyResting) {
+ snd_processEnvironmentalSoundEffect(35, _currentBlock);
+ return;
+ }
+
+ const uint8 *table = (_expObjectTblIndex[item] == 0) ? _expObjectAnimTbl1 : ((_expObjectTblIndex[item] == 1) ? _expObjectAnimTbl2 : _expObjectAnimTbl3);
+ int tableSize = (_expObjectTblIndex[item] == 0) ? _expObjectAnimTbl1Size : ((_expObjectTblIndex[item] == 1) ? _expObjectAnimTbl2Size : _expObjectAnimTbl3Size);
+
+ int tl = 0;
+ for (; tl < 18; tl++) {
+ if (_visibleBlockIndex[tl] == block)
+ break;
+ }
+
+ if (tl == 18)
+ return;
+
+ int b = _expObjectTlMode ? _expObjectTlMode[tl] : 2;
+
+ if (b == 0 || (b == 1 && (fo->direction & 1) == (_currentDirection & 1))) {
+ snd_processEnvironmentalSoundEffect(35, _currentBlock);
+ return;
+ }
+
+ uint8 dm = _dscDimMap[tl];
+ int16 x1 = 0;
+ int16 x2 = 0;
+
+ setLevelShapesDim(tl, x1, x2, 5);
+
+ if (x2 < x1)
+ return;
+
+ if (fo)
+ fo->enable = 0;
+
+ drawScene(1);
+
+ if (fo)
+ fo->enable = 2;
+
+ _screen->fillRect(0, 0, 176, 120, 0, 2);
+ uint8 col = _screen->getPagePixel(2, 0, 0);
+ drawSceneShapes(_expObjectShpStart[dm]);
+
+ setLevelShapesDim(tl, x1, x2, 5);
+ _screen->updateScreen();
+
+ _screen->setGfxParameters(_dscShapeCoords[(tl * 5 + 4) << 1] + 88, 48, col);
+ snd_processEnvironmentalSoundEffect(35, _currentBlock);
+
+ disableSysTimer(2);
+ if (dm == 0) {
+ _screen->drawExplosion(3, 147, 35, 20, 7, table, tableSize);
+ } else if (dm == 1) {
+ _screen->drawExplosion(2, 147, 35, 20, 7, table, tableSize);
+ } else if (dm == 2) {
+ _screen->drawExplosion(1, 147, 35, 20, 7, table, tableSize);
+ } else if (dm == 3) {
+ _screen->drawExplosion(0, 460, 50, 20, 4, table, tableSize);
+ }
+ enableSysTimer(2);
+}
+
+void EoBCoreEngine::endObjectFlight(EoBFlyingObject *fo) {
+ if (fo->enable == 1) {
+ _items[fo->item].pos &= 3;
+ runLevelScript(fo->curBlock, 4);
+ updateEnvironmentalSfx(18);
+ }
+ memset(fo, 0, sizeof(EoBFlyingObject));
+}
+
+void EoBCoreEngine::checkFlyingObjects() {
+ if (!_runFlag)
+ return;
+
+ for (int i = 0; i < 10; i++) {
+ EoBFlyingObject *fo = &_flyingObjects[i];
+ if (!fo->enable)
+ continue;
+ if (updateFlyingObjectHitTest(fo, fo->curBlock, fo->curPos))
+ endObjectFlight(fo);
+ }
+}
+
+void EoBCoreEngine::reloadWeaponSlot(int charIndex, int slotIndex, int itemType, int arrowOrDagger) {
+ if (arrowOrDagger && _characters[charIndex].inventory[16]) {
+ _characters[charIndex].inventory[slotIndex] = getQueuedItem(&_characters[charIndex].inventory[16], 0, -1);
+ } else {
+ for (int i = 24; i >= 22; i--) {
+ if (!_characters[charIndex].inventory[i])
+ continue;
+ if (_items[_characters[charIndex].inventory[i]].type == itemType && itemType != -1)
+ continue;
+ _characters[charIndex].inventory[slotIndex] = _characters[charIndex].inventory[i];
+ _characters[charIndex].inventory[i] = 0;
+ return;
+ }
+ }
+}
+
+} // End of namespace Kyra
+
+#endif // ENABLE_EOB
diff --git a/engines/kyra/items_lok.cpp b/engines/kyra/items_lok.cpp
index d598a17cf1..2937038463 100644
--- a/engines/kyra/items_lok.cpp
+++ b/engines/kyra/items_lok.cpp
@@ -38,7 +38,7 @@ int KyraEngine_LoK::findDuplicateItemShape(int shape) {
while (dupTable[i] != 0xFF) {
if (dupTable[i] == shape)
- return dupTable[i+1];
+ return dupTable[i + 1];
i += 2;
}
return -1;
@@ -180,7 +180,7 @@ void KyraEngine_LoK::setMouseItem(Item item) {
if (item == kItemNone)
_screen->setMouseCursor(1, 1, _shapes[6]);
else
- _screen->setMouseCursor(8, 15, _shapes[216+item]);
+ _screen->setMouseCursor(8, 15, _shapes[216 + item]);
}
void KyraEngine_LoK::wipeDownMouseItem(int xpos, int ypos) {
@@ -196,16 +196,16 @@ void KyraEngine_LoK::wipeDownMouseItem(int xpos, int ypos) {
while (height >= 0) {
restoreItemRect1(xpos, ypos);
- _screen->setNewShapeHeight(_shapes[216+_itemInHand], height);
+ _screen->setNewShapeHeight(_shapes[216 + _itemInHand], height);
uint32 nextTime = _system->getMillis() + 1 * _tickLength;
- _screen->drawShape(0, _shapes[216+_itemInHand], xpos, y, 0, 0);
+ _screen->drawShape(0, _shapes[216 + _itemInHand], xpos, y, 0, 0);
_screen->updateScreen();
y += 2;
height -= 2;
delayUntil(nextTime);
}
restoreItemRect1(xpos, ypos);
- _screen->resetShapeHeight(_shapes[216+_itemInHand]);
+ _screen->resetShapeHeight(_shapes[216 + _itemInHand]);
removeHandItem();
_screen->showMouse();
}
@@ -517,7 +517,7 @@ void KyraEngine_LoK::itemDropDown(int x, int y, int destX, int destY, byte freeI
drawY = tempY - 16;
backUpItemRect0(drawX, drawY);
uint32 nextTime = _system->getMillis() + 1 * _tickLength;
- _screen->drawShape(0, _shapes[216+item], drawX, drawY, 0, 0);
+ _screen->drawShape(0, _shapes[216 + item], drawX, drawY, 0, 0);
_screen->updateScreen();
delayUntil(nextTime);
}
@@ -554,7 +554,7 @@ void KyraEngine_LoK::itemDropDown(int x, int y, int destX, int destY, byte freeI
drawY = tempY - 16;
backUpItemRect0(drawX, drawY);
uint32 nextTime = _system->getMillis() + 1 * _tickLength;
- _screen->drawShape(0, _shapes[216+item], drawX, drawY, 0, 0);
+ _screen->drawShape(0, _shapes[216 + item], drawX, drawY, 0, 0);
_screen->updateScreen();
delayUntil(nextTime);
}
@@ -575,7 +575,7 @@ void KyraEngine_LoK::dropItem(int unk1, int item, int x, int y, int unk2) {
if (processItemDrop(_currentCharacter->sceneId, item, x, y, unk1, unk2))
return;
snd_playSoundEffect(54);
-
+
// Old floppy versions don't print warning messages and don't have the necessary string resources.
// These versions will only play the warning sound effect.
if (_flags.isOldFloppy && !_noDropList)
@@ -597,7 +597,7 @@ void KyraEngine_LoK::itemSpecialFX(int x, int y, int item) {
}
void KyraEngine_LoK::itemSpecialFX1(int x, int y, int item) {
- uint8 *shape = _shapes[216+item];
+ uint8 *shape = _shapes[216 + item];
x -= 8;
int startY = y;
y -= 15;
@@ -635,7 +635,7 @@ void KyraEngine_LoK::itemSpecialFX2(int x, int y, int item) {
for (int i = 204; i >= 201; --i) {
restoreItemRect0(x, y);
uint32 nextTime = _system->getMillis() + 3 * _tickLength;
- _screen->drawShape(0, _shapes[216+item], x, y, 0, 0);
+ _screen->drawShape(0, _shapes[216 + item], x, y, 0, 0);
_screen->drawShape(0, _shapes[i], x, y + yAdd, 0, 0);
_screen->updateScreen();
delayUntil(nextTime);
@@ -687,7 +687,7 @@ void KyraEngine_LoK::magicOutMouseItem(int animIndex, int itemPos) {
for (int shape = _magicMouseItemStartFrame[animIndex]; shape <= _magicMouseItemEndFrame[animIndex]; ++shape) {
restoreItemRect1(x, y);
uint32 nextTime = _system->getMillis() + 4 * _tickLength;
- _screen->drawShape(0, _shapes[216+_itemInHand], x + 4, y + 3, 0, 0);
+ _screen->drawShape(0, _shapes[216 + _itemInHand], x + 4, y + 3, 0, 0);
if (tableIndex == -1)
_screen->drawShape(0, _shapes[shape], x, y, 0, 0);
else
@@ -705,7 +705,7 @@ void KyraEngine_LoK::magicOutMouseItem(int animIndex, int itemPos) {
for (int shape = _magicMouseItemStartFrame2[animIndex]; shape <= _magicMouseItemEndFrame2[animIndex]; ++shape) {
restoreItemRect1(x, y);
uint32 nextTime = _system->getMillis() + 4 * _tickLength;
- _screen->drawShape(0, _shapes[216+_itemInHand], x + 4, y + 3, 0, 0);
+ _screen->drawShape(0, _shapes[216 + _itemInHand], x + 4, y + 3, 0, 0);
if (tableIndex == -1)
_screen->drawShape(0, _shapes[shape], x, y, 0, 0);
else
@@ -789,12 +789,12 @@ void KyraEngine_LoK::magicInMouseItem(int animIndex, int item, int itemPos) {
}
restoreItemRect1(x, y);
if (itemPos == -1) {
- _screen->setMouseCursor(8, 15, _shapes[216+item]);
+ _screen->setMouseCursor(8, 15, _shapes[216 + item]);
_itemInHand = item;
} else {
_characterList[0].inventoryItems[itemPos] = item;
_screen->hideMouse();
- _screen->drawShape(0, _shapes[216+item], _itemPosX[itemPos], _itemPosY[itemPos], 0, 0);
+ _screen->drawShape(0, _shapes[216 + item], _itemPosX[itemPos], _itemPosY[itemPos], 0, 0);
_screen->showMouse();
}
_screen->showMouse();
@@ -847,7 +847,7 @@ void KyraEngine_LoK::updatePlayerItemsForScene() {
if (_itemInHand > 33)
_itemInHand = 33;
_screen->hideMouse();
- _screen->setMouseCursor(8, 15, _shapes[216+_itemInHand]);
+ _screen->setMouseCursor(8, 15, _shapes[216 + _itemInHand]);
_screen->showMouse();
}
@@ -890,7 +890,7 @@ void KyraEngine_LoK::redrawInventory(int page) {
if (_currentCharacter->inventoryItems[i] != kItemNone) {
uint8 item = _currentCharacter->inventoryItems[i];
- _screen->drawShape(page, _shapes[216+item], _itemPosX[i], _itemPosY[i], 0, 0);
+ _screen->drawShape(page, _shapes[216 + item], _itemPosX[i], _itemPosY[i], 0, 0);
}
}
_screen->showMouse();
@@ -899,23 +899,23 @@ void KyraEngine_LoK::redrawInventory(int page) {
}
void KyraEngine_LoK::backUpItemRect0(int xpos, int ypos) {
- _screen->rectClip(xpos, ypos, 3<<3, 24);
- _screen->copyRegionToBuffer(_screen->_curPage, xpos, ypos, 3<<3, 24, _itemBkgBackUp[0]);
+ _screen->rectClip(xpos, ypos, 3 << 3, 24);
+ _screen->copyRegionToBuffer(_screen->_curPage, xpos, ypos, 3 << 3, 24, _itemBkgBackUp[0]);
}
void KyraEngine_LoK::restoreItemRect0(int xpos, int ypos) {
- _screen->rectClip(xpos, ypos, 3<<3, 24);
- _screen->copyBlockToPage(_screen->_curPage, xpos, ypos, 3<<3, 24, _itemBkgBackUp[0]);
+ _screen->rectClip(xpos, ypos, 3 << 3, 24);
+ _screen->copyBlockToPage(_screen->_curPage, xpos, ypos, 3 << 3, 24, _itemBkgBackUp[0]);
}
void KyraEngine_LoK::backUpItemRect1(int xpos, int ypos) {
- _screen->rectClip(xpos, ypos, 4<<3, 32);
- _screen->copyRegionToBuffer(_screen->_curPage, xpos, ypos, 4<<3, 32, _itemBkgBackUp[1]);
+ _screen->rectClip(xpos, ypos, 4 << 3, 32);
+ _screen->copyRegionToBuffer(_screen->_curPage, xpos, ypos, 4 << 3, 32, _itemBkgBackUp[1]);
}
void KyraEngine_LoK::restoreItemRect1(int xpos, int ypos) {
- _screen->rectClip(xpos, ypos, 4<<3, 32);
- _screen->copyBlockToPage(_screen->_curPage, xpos, ypos, 4<<3, 32, _itemBkgBackUp[1]);
+ _screen->rectClip(xpos, ypos, 4 << 3, 32);
+ _screen->copyBlockToPage(_screen->_curPage, xpos, ypos, 4 << 3, 32, _itemBkgBackUp[1]);
}
int KyraEngine_LoK::getItemListIndex(Item item) {
diff --git a/engines/kyra/items_lol.cpp b/engines/kyra/items_lol.cpp
index 7e9ae439fc..ea2acaf64d 100644
--- a/engines/kyra/items_lol.cpp
+++ b/engines/kyra/items_lol.cpp
@@ -27,6 +27,68 @@
namespace Kyra {
+LoLObject *LoLEngine::findObject(uint16 index) {
+ if (index & 0x8000)
+ return &_monsters[index & 0x7fff];
+ else
+ return &_itemsInPlay[index];
+}
+
+int LoLEngine::calcObjectPosition(LoLObject *i, uint16 direction) {
+ int x = i->x;
+ int y = i->y;
+
+ calcSpriteRelPosition(_partyPosX, _partyPosY, x, y, direction);
+
+ if (y < 0)
+ y = 0;
+
+ int res = (i->flyingHeight << 12);
+ res |= (4095 - y);
+
+ return res;
+}
+
+void LoLEngine::removeAssignedObjectFromBlock(LevelBlockProperty *l, uint16 id) {
+ uint16 *blockItemIndex = &l->assignedObjects;
+ LoLObject *i = 0;
+
+ while (*blockItemIndex) {
+ if (*blockItemIndex == id) {
+ i = findObject(id);
+ *blockItemIndex = i->nextAssignedObject;
+ i->nextAssignedObject = 0;
+ return;
+ }
+
+ i = findObject(*blockItemIndex);
+ blockItemIndex = &i->nextAssignedObject;
+ }
+}
+
+void LoLEngine::removeDrawObjectFromBlock(LevelBlockProperty *l, uint16 id) {
+ uint16 *blockItemIndex = &l->drawObjects;
+ LoLObject *i = 0;
+
+ while (*blockItemIndex) {
+ if (*blockItemIndex == id) {
+ i = findObject(id);
+ *blockItemIndex = i->nextDrawObject;
+ i->nextDrawObject = 0;
+ return;
+ }
+
+ i = findObject(*blockItemIndex);
+ blockItemIndex = &i->nextDrawObject;
+ }
+}
+
+void LoLEngine::assignObjectToBlock(uint16 *assignedBlockObjects, uint16 id) {
+ LoLObject *t = findObject(id);
+ t->nextAssignedObject = *assignedBlockObjects;
+ *assignedBlockObjects = id;
+}
+
void LoLEngine::giveCredits(int credits, int redraw) {
if (redraw)
snd_playSoundEffect(101, -1);
@@ -127,14 +189,8 @@ Item LoLEngine::makeItem(int itemType, int curFrame, int flags) {
continue;
bool t = false;
- Item ii = i;
- while (ii && !t) {
- t = testUnkItemFlags(ii);
- if (t)
- break;
- else
- ii = _itemsInPlay[ii - 1].nextAssignedObject;
- }
+ for (Item ii = i; ii && !t; ii = _itemsInPlay[ii].nextAssignedObject)
+ t = isItemMoveable(ii);
if (t) {
cnt = diff;
@@ -144,29 +200,25 @@ Item LoLEngine::makeItem(int itemType, int curFrame, int flags) {
Item slot = i;
if (cnt) {
- slot = r;
- if (testUnkItemFlags(r)) {
+ slot = 0;
+ if (isItemMoveable(r)) {
if (_itemsInPlay[r].nextAssignedObject)
_itemsInPlay[_itemsInPlay[r].nextAssignedObject].level = _itemsInPlay[r].level;
deleteItem(r);
slot = r;
} else {
- uint16 ii = _itemsInPlay[slot].nextAssignedObject;
- while (ii) {
- if (testUnkItemFlags(ii)) {
- _itemsInPlay[slot].nextAssignedObject = _itemsInPlay[ii].nextAssignedObject;
- deleteItem(ii);
- slot = ii;
- break;
- } else {
- slot = ii;
- }
- ii = _itemsInPlay[slot].nextAssignedObject;
+ for (uint16 ii = _itemsInPlay[r].nextAssignedObject; ii; ii = _itemsInPlay[ii].nextAssignedObject) {
+ if (!isItemMoveable(ii))
+ continue;
+ _itemsInPlay[r].nextAssignedObject = _itemsInPlay[ii].nextAssignedObject;
+ deleteItem(ii);
+ slot = ii;
+ break;
}
}
}
- memset(&_itemsInPlay[slot], 0, sizeof(ItemInPlay));
+ memset(&_itemsInPlay[slot], 0, sizeof(LoLItem));
_itemsInPlay[slot].itemPropertyIndex = itemType;
_itemsInPlay[slot].shpCurFrame_flg = (curFrame & 0x1fff) | flags;
@@ -219,7 +271,7 @@ bool LoLEngine::addItemToInventory(Item itemIndex) {
return true;
}
-bool LoLEngine::testUnkItemFlags(Item itemIndex) {
+bool LoLEngine::isItemMoveable(Item itemIndex) {
if (!(_itemsInPlay[itemIndex].shpCurFrame_flg & 0x4000))
return false;
@@ -231,17 +283,10 @@ bool LoLEngine::testUnkItemFlags(Item itemIndex) {
}
void LoLEngine::deleteItem(Item itemIndex) {
- memset(&_itemsInPlay[itemIndex], 0, sizeof(ItemInPlay));
+ memset(&_itemsInPlay[itemIndex], 0, sizeof(LoLItem));
_itemsInPlay[itemIndex].shpCurFrame_flg |= 0x8000;
}
-ItemInPlay *LoLEngine::findObject(uint16 index) {
- if (index & 0x8000)
- return (ItemInPlay *)&_monsters[index & 0x7fff];
- else
- return &_itemsInPlay[index];
-}
-
void LoLEngine::runItemScript(int charNum, Item item, int flags, int next, int reg4) {
EMCState scriptState;
memset(&scriptState, 0, sizeof(EMCState));
@@ -304,7 +349,7 @@ bool LoLEngine::itemEquipped(int charNum, uint16 itemType) {
return false;
}
-void LoLEngine::setItemPosition(Item item, uint16 x, uint16 y, int flyingHeight, int b) {
+void LoLEngine::setItemPosition(Item item, uint16 x, uint16 y, int flyingHeight, int moveable) {
if (!flyingHeight) {
x = (x & 0xffc0) | 0x40;
y = (y & 0xffc0) | 0x40;
@@ -316,7 +361,7 @@ void LoLEngine::setItemPosition(Item item, uint16 x, uint16 y, int flyingHeight,
_itemsInPlay[item].block = block;
_itemsInPlay[item].flyingHeight = flyingHeight;
- if (b)
+ if (moveable)
_itemsInPlay[item].shpCurFrame_flg |= 0x4000;
else
_itemsInPlay[item].shpCurFrame_flg &= 0xbfff;
@@ -325,7 +370,7 @@ void LoLEngine::setItemPosition(Item item, uint16 x, uint16 y, int flyingHeight,
assignItemToBlock(&_levelBlockProperties[block].assignedObjects, item);
reassignDrawObjects(_currentDirection, item, &_levelBlockProperties[block], false);
- if (b)
+ if (moveable)
runLevelScriptCustom(block, 0x80, -1, item, 0, 0);
checkSceneUpdateNeed(block);
@@ -352,7 +397,7 @@ bool LoLEngine::launchObject(int objectType, Item item, int startX, int startY,
}
int csp = checkDrawObjectSpace(_partyPosX, _partyPosY, t->x, t->y);
- if (csp > sp){
+ if (csp > sp) {
sp = csp;
slot = i;
}
@@ -453,7 +498,7 @@ void LoLEngine::objectFlightProcessHits(FlyingObject *t, int x, int y, int objec
if (_itemProperties[_itemsInPlay[t->item].itemPropertyIndex].flags & 0x4000) {
int o = _levelBlockProperties[_itemsInPlay[t->item].block].assignedObjects;
while (o & 0x8000) {
- ItemInPlay *i = findObject(o);
+ LoLObject *i = findObject(o);
o = i->nextAssignedObject;
runItemScript(t->attackerId, t->item, 0x8000, o, 0);
}
@@ -483,7 +528,7 @@ void LoLEngine::updateFlyingObject(FlyingObject *t) {
getNextStepCoords(t->x, t->y, x, y, t->direction);
/* WORKAROUND:
Large fireballs cast by the "birds" in white tower level 2 and by the "wraith knights" in castle cimmeria
- level 1 (or possible other objects with flag 0x4000) could not fly through corridors in ScummVM and would
+ level 1 (or possible other objects with flag 0x4000) could not fly through corridors in ScummVM and would
be terminated prematurely. The original code (all versions) involuntarily circumvents this via a bug in the
next line of code.
The original checks for _itemProperties[t->item].flags instead of _itemProperties[_itemsInPlay[t->item].itemPropertyIndex].flags.
@@ -494,7 +539,7 @@ void LoLEngine::updateFlyingObject(FlyingObject *t) {
at least.
Other methods of working around this issue don't make too much sense. An object with a width of 256
- could never fly through corridors, since 256 is also the width of a block. Aligning the fireballs to the
+ could never fly through corridors, since 256 is also the width of a block. Aligning the fireballs to the
middle of a block (or making the monsters align to the middle before casting them) wouldn't help here
(and wouldn't be faithful to the original either).
*/
@@ -512,13 +557,13 @@ void LoLEngine::updateFlyingObject(FlyingObject *t) {
void LoLEngine::assignItemToBlock(uint16 *assignedBlockObjects, int id) {
while (*assignedBlockObjects & 0x8000) {
- ItemInPlay *tmp = findObject(*assignedBlockObjects);
+ LoLObject *tmp = findObject(*assignedBlockObjects);
assignedBlockObjects = &tmp->nextAssignedObject;
}
- ItemInPlay *newObject = findObject(id);
+ LoLObject *newObject = findObject(id);
newObject->nextAssignedObject = *assignedBlockObjects;
- newObject->level = -1;
+ ((LoLItem *)newObject)->level = -1;
*assignedBlockObjects = id;
}
@@ -541,7 +586,7 @@ int LoLEngine::checkSceneForItems(uint16 *blockDrawObjects, int color) {
return *blockDrawObjects;
}
- ItemInPlay *i = findObject(*blockDrawObjects);
+ LoLObject *i = findObject(*blockDrawObjects);
blockDrawObjects = &i->nextDrawObject;
}
diff --git a/engines/kyra/kyra_hof.cpp b/engines/kyra/kyra_hof.cpp
index 4497ab8019..0ba173d9d0 100644
--- a/engines/kyra/kyra_hof.cpp
+++ b/engines/kyra/kyra_hof.cpp
@@ -88,7 +88,7 @@ KyraEngine_HoF::KyraEngine_HoF(OSystem *system, const GameFlags &flags) : KyraEn
_currentTalkSections.ENDTim = 0;
memset(&_invWsa, 0, sizeof(_invWsa));
- _itemAnimData = 0;
+ _itemAnimDefinition = 0;
_demoAnimData = 0;
_nextAnimItem = 0;
@@ -211,8 +211,8 @@ void KyraEngine_HoF::pauseEngineIntern(bool pause) {
_nextIdleAnim += pausedTime;
- for (int x = 0; x < _itemAnimDataSize; x++)
- _activeItemAnim[x].nextFrame += pausedTime;
+ for (int x = 0; x < _itemAnimDefinitionSize; x++)
+ _activeItemAnim[x].nextFrameTime += pausedTime;
_tim->refreshTimersAfterPause(pausedTime);
}
@@ -223,11 +223,12 @@ Common::Error KyraEngine_HoF::init() {
assert(_screen);
_screen->setResolution();
+ _debugger = new Debugger_HoF(this);
+ assert(_debugger);
+
KyraEngine_v1::init();
initStaticResource();
- _debugger = new Debugger_HoF(this);
- assert(_debugger);
_text = new TextDisplayer_HoF(this, _screen);
assert(_text);
_gui = new GUI_HoF(this);
@@ -285,7 +286,7 @@ Common::Error KyraEngine_HoF::go() {
if (_flags.isDemo && !_flags.isTalkie) {
#ifdef ENABLE_LOL
if (_flags.gameID == GI_LOL)
- seq_playSequences(kSequenceLolDemoScene1, kSequenceLolDemoScene6);
+ seq_playSequences(kSequenceLoLDemoScene1, kSequenceLoLDemoScene6);
else
#endif // ENABLE_LOL
seq_playSequences(kSequenceDemoVirgin, kSequenceDemoFisher);
@@ -455,6 +456,9 @@ void KyraEngine_HoF::startup() {
}
void KyraEngine_HoF::runLoop() {
+ // Initialize debugger since how it should be fully usable
+ _debugger->initialize();
+
_screen->updateScreen();
_runFlag = true;
@@ -1083,7 +1087,7 @@ void KyraEngine_HoF::loadNPCScript() {
#pragma mark -
void KyraEngine_HoF::resetScaleTable() {
- Common::set_to(_scaleTable, ARRAYEND(_scaleTable), 0x100);
+ Common::fill(_scaleTable, ARRAYEND(_scaleTable), 0x100);
}
void KyraEngine_HoF::setScaleTableItem(int item, int data) {
@@ -1473,7 +1477,7 @@ void KyraEngine_HoF::snd_playVoiceFile(int id) {
char vocFile[9];
assert(id >= 0 && id <= 9999999);
sprintf(vocFile, "%07d", id);
- if (_sound->voiceFileIsPresent(vocFile)) {
+ if (_sound->isVoicePresent(vocFile)) {
snd_stopVoice();
while (!_sound->voicePlay(vocFile, &_speechHandle)) {
@@ -1673,7 +1677,7 @@ void KyraEngine_HoF::setCauldronState(uint8 state, bool paletteFade) {
}
void KyraEngine_HoF::clearCauldronTable() {
- Common::set_to(_cauldronTable, ARRAYEND(_cauldronTable), -1);
+ Common::fill(_cauldronTable, ARRAYEND(_cauldronTable), -1);
}
void KyraEngine_HoF::addFrontCauldronTable(int item) {
diff --git a/engines/kyra/kyra_hof.h b/engines/kyra/kyra_hof.h
index 916cac0c9d..182854cdf1 100644
--- a/engines/kyra/kyra_hof.h
+++ b/engines/kyra/kyra_hof.h
@@ -95,18 +95,18 @@ enum NestedSequencesDemo {
};
#ifdef ENABLE_LOL
-enum SequencesLolDemo {
- kSequenceLolDemoScene1 = 0,
- kSequenceLolDemoText1,
- kSequenceLolDemoScene2,
- kSequenceLolDemoText2,
- kSequenceLolDemoScene3,
- kSequenceLolDemoText3,
- kSequenceLolDemoScene4,
- kSequenceLolDemoText4,
- kSequenceLolDemoScene5,
- kSequenceLolDemoText5,
- kSequenceLolDemoScene6
+enum SequencesLoLDemo {
+ kSequenceLoLDemoScene1 = 0,
+ kSequenceLoLDemoText1,
+ kSequenceLoLDemoScene2,
+ kSequenceLoLDemoText2,
+ kSequenceLoLDemoScene3,
+ kSequenceLoLDemoText3,
+ kSequenceLoLDemoScene4,
+ kSequenceLoLDemoText4,
+ kSequenceLoLDemoScene5,
+ kSequenceLoLDemoText5,
+ kSequenceLoLDemoScene6
};
#endif // ENABLE_LOL
@@ -874,8 +874,8 @@ protected:
const char * const *_ingameTimJpStr;
int _ingameTimJpStrSize;
const HofSeqData *_sequences;
- const ItemAnimData_v2 *_itemAnimData;
- int _itemAnimDataSize;
+ const ItemAnimDefinition *_itemAnimDefinition;
+ int _itemAnimDefinitionSize;
const ItemAnimData_v1 *_demoAnimData;
int _demoAnimSize;
diff --git a/engines/kyra/kyra_lok.cpp b/engines/kyra/kyra_lok.cpp
index 27d0849e5f..ece4a0daba 100644
--- a/engines/kyra/kyra_lok.cpp
+++ b/engines/kyra/kyra_lok.cpp
@@ -40,8 +40,8 @@ namespace Kyra {
KyraEngine_LoK::KyraEngine_LoK(OSystem *system, const GameFlags &flags)
: KyraEngine_v1(system, flags) {
- _seq_Forest = _seq_KallakWriting = _seq_KyrandiaLogo = _seq_KallakMalcolm =
- _seq_MalcolmTree = _seq_WestwoodLogo = _seq_Demo1 = _seq_Demo2 = _seq_Demo3 =
+ _seq_Forest = _seq_KallakWriting = _seq_KyrandiaLogo = _seq_KallakMalcolm = 0;
+ _seq_MalcolmTree = _seq_WestwoodLogo = _seq_Demo1 = _seq_Demo2 = _seq_Demo3 = 0;
_seq_Demo4 = 0;
_seq_WSATable = _seq_CPSTable = _seq_COLTable = _seq_textsTable = 0;
@@ -167,13 +167,16 @@ KyraEngine_LoK::~KyraEngine_LoK() {
}
Common::Error KyraEngine_LoK::init() {
- if (_flags.platform == Common::kPlatformPC98 && _flags.useHiResOverlay && ConfMan.getBool("16_color"))
+ if (Common::parseRenderMode(ConfMan.get("render_mode")) == Common::kRenderPC9801)
_screen = new Screen_LoK_16(this, _system);
else
_screen = new Screen_LoK(this, _system);
assert(_screen);
_screen->setResolution();
+ _debugger = new Debugger_LoK(this);
+ assert(_debugger);
+
KyraEngine_v1::init();
_sprites = new Sprites(this, _system);
@@ -212,7 +215,7 @@ Common::Error KyraEngine_LoK::init() {
_currentCharacter = 0;
_characterList = new Character[11];
assert(_characterList);
- memset(_characterList, 0, sizeof(Character)*11);
+ memset(_characterList, 0, sizeof(Character) * 11);
for (int i = 0; i < 11; ++i)
memset(_characterList[i].inventoryItems, 0xFF, sizeof(_characterList[i].inventoryItems));
@@ -229,8 +232,6 @@ Common::Error KyraEngine_LoK::init() {
memset(&_scriptMain, 0, sizeof(EMCState));
memset(&_scriptClick, 0, sizeof(EMCState));
- _debugger = new Debugger_LoK(this);
- assert(_debugger);
memset(_shapes, 0, sizeof(_shapes));
for (int i = 0; i < ARRAYSIZE(_movieObjects); ++i)
@@ -254,7 +255,7 @@ Common::Error KyraEngine_LoK::init() {
_poisonDeathCounter = 0;
memset(_itemHtDat, 0, sizeof(_itemHtDat));
- memset(_exitList, 0xFFFF, sizeof(_exitList));
+ memset(_exitList, 0xFF, sizeof(_exitList));
_exitListPtr = 0;
_pathfinderFlag = _pathfinderFlag2 = 0;
_lastFindWayRet = 0;
@@ -369,7 +370,7 @@ void KyraEngine_LoK::startup() {
// XXX
for (int i = 0; i < 12; ++i) {
int size = _screen->getRectSize(3, 24);
- _shapes[361+i] = new byte[size];
+ _shapes[361 + i] = new byte[size];
}
_itemBkgBackUp[0] = new uint8[_screen->getRectSize(3, 24)];
@@ -436,6 +437,9 @@ void KyraEngine_LoK::startup() {
}
void KyraEngine_LoK::mainLoop() {
+ // Initialize debugger since how it should be fully usable
+ _debugger->initialize();
+
_eventList.clear();
while (!shouldQuit()) {
@@ -506,6 +510,9 @@ void KyraEngine_LoK::delay(uint32 amount, bool update, bool isMainLoop) {
updateTextFade();
updateMousePointer();
} else {
+ // We need to do Screen::updateScreen here, since client code
+ // relies on this method to copy screen changes to the actual
+ // screen since at least 0af418e7ea3a41f93fcc551a45ee5bae822d812a.
_screen->updateScreen();
}
@@ -578,23 +585,23 @@ void KyraEngine_LoK::setupShapes123(const Shape *shapeTable, int endShape, int f
uint8 curImage = 0xFF;
int curPageBackUp = _screen->_curPage;
- _screen->_curPage = 8; // we are using page 8 here in the original page 2 was backuped and then used for this stuff
+ _screen->_curPage = 8; // we are using page 8 here in the original page 2 was backuped and then used for this stuff
int shapeFlags = 2;
if (flags)
shapeFlags = 3;
- for (int i = 123; i < 123+endShape; ++i) {
- uint8 newImage = shapeTable[i-123].imageIndex;
+ for (int i = 123; i < 123 + endShape; ++i) {
+ uint8 newImage = shapeTable[i - 123].imageIndex;
if (newImage != curImage && newImage != 0xFF) {
assert(_characterImageTable);
_screen->loadBitmap(_characterImageTable[newImage], 8, 8, 0);
curImage = newImage;
}
- _shapes[i] = _screen->encodeShape(shapeTable[i-123].x<<3, shapeTable[i-123].y, shapeTable[i-123].w<<3, shapeTable[i-123].h, shapeFlags);
- assert(i-7 < _defaultShapeTableSize);
- _defaultShapeTable[i-7].xOffset = shapeTable[i-123].xOffset;
- _defaultShapeTable[i-7].yOffset = shapeTable[i-123].yOffset;
- _defaultShapeTable[i-7].w = shapeTable[i-123].w;
- _defaultShapeTable[i-7].h = shapeTable[i-123].h;
+ _shapes[i] = _screen->encodeShape(shapeTable[i - 123].x << 3, shapeTable[i - 123].y, shapeTable[i - 123].w << 3, shapeTable[i - 123].h, shapeFlags);
+ assert(i - 7 < _defaultShapeTableSize);
+ _defaultShapeTable[i - 7].xOffset = shapeTable[i - 123].xOffset;
+ _defaultShapeTable[i - 7].yOffset = shapeTable[i - 123].yOffset;
+ _defaultShapeTable[i - 7].w = shapeTable[i - 123].w;
+ _defaultShapeTable[i - 7].h = shapeTable[i - 123].h;
}
_screen->_curPage = curPageBackUp;
}
@@ -784,7 +791,7 @@ void KyraEngine_LoK::updateMousePointer(bool forceUpdate) {
}
if (mouse.x >= _entranceMouseCursorTracks[0] && mouse.y >= _entranceMouseCursorTracks[1]
- && mouse.x <= _entranceMouseCursorTracks[2] && mouse.y <= _entranceMouseCursorTracks[3]) {
+ && mouse.x <= _entranceMouseCursorTracks[2] && mouse.y <= _entranceMouseCursorTracks[3]) {
switch (_entranceMouseCursorTracks[4]) {
case 0:
newMouseState = -6;
@@ -840,7 +847,7 @@ void KyraEngine_LoK::updateMousePointer(bool forceUpdate) {
if (_itemInHand == kItemNone)
_screen->setMouseCursor(1, 1, _shapes[0]);
else
- _screen->setMouseCursor(8, 15, _shapes[216+_itemInHand]);
+ _screen->setMouseCursor(8, 15, _shapes[216 + _itemInHand]);
_screen->showMouse();
}
}
@@ -880,8 +887,8 @@ int KyraEngine_LoK::checkForNPCScriptRun(int xpos, int ypos) {
int charLeft = 0, charRight = 0, charTop = 0, charBottom = 0;
int scaleFactor = _scaleTable[currentChar->y1];
- int addX = (((scaleFactor*8)*3)>>8)>>1;
- int addY = ((scaleFactor*3)<<4)>>8;
+ int addX = (((scaleFactor * 8) * 3) >> 8) >> 1;
+ int addY = ((scaleFactor * 3) << 4) >> 8;
charLeft = currentChar->x1 - addX;
charRight = currentChar->x1 + addX;
@@ -904,7 +911,7 @@ int KyraEngine_LoK::checkForNPCScriptRun(int xpos, int ypos) {
charRight = currentChar->x1 + 11;
charTop = currentChar->y1 - 48;
// if (!i)
- // charBottom = currentChar->y2 - 16;
+ // charBottom = currentChar->y2 - 16;
// else
charBottom = currentChar->y1;
@@ -953,9 +960,6 @@ void KyraEngine_LoK::registerDefaultSettings() {
// Most settings already have sensible defaults. This one, however, is
// specific to the Kyra engine.
ConfMan.registerDefault("walkspeed", 2);
-
- if (_flags.platform == Common::kPlatformPC98 && _flags.useHiResOverlay)
- ConfMan.registerDefault("16_color", false);
}
void KyraEngine_LoK::readSettings() {
@@ -964,13 +968,13 @@ void KyraEngine_LoK::readSettings() {
// The default talk speed is 60. This should be mapped to "Normal".
if (talkspeed == 0)
- _configTextspeed = 3; // Clickable
+ _configTextspeed = 3; // Clickable
if (talkspeed <= 50)
- _configTextspeed = 0; // Slow
+ _configTextspeed = 0; // Slow
else if (talkspeed <= 150)
- _configTextspeed = 1; // Normal
+ _configTextspeed = 1; // Normal
else
- _configTextspeed = 2; // Fast
+ _configTextspeed = 2; // Fast
KyraEngine_v1::readSettings();
}
@@ -979,16 +983,16 @@ void KyraEngine_LoK::writeSettings() {
int talkspeed;
switch (_configTextspeed) {
- case 0: // Slow
+ case 0: // Slow
talkspeed = 1;
break;
- case 1: // Normal
+ case 1: // Normal
talkspeed = 60;
break;
- case 2: // Fast
+ case 2: // Fast
talkspeed = 255;
break;
- default: // Clickable
+ default: // Clickable
talkspeed = 0;
}
diff --git a/engines/kyra/kyra_lok.h b/engines/kyra/kyra_lok.h
index 57e6bd39ab..e5fb3cddca 100644
--- a/engines/kyra/kyra_lok.h
+++ b/engines/kyra/kyra_lok.h
@@ -29,10 +29,6 @@
#include "kyra/gui_lok.h"
#include "kyra/item.h"
-namespace Graphics {
-struct Surface;
-}
-
namespace Kyra {
class Movie;
@@ -416,7 +412,7 @@ protected:
Movie *_movieObjects[10];
- uint16 _entranceMouseCursorTracks[8];
+ uint16 _entranceMouseCursorTracks[5];
uint16 _walkBlockNorth;
uint16 _walkBlockEast;
uint16 _walkBlockSouth;
diff --git a/engines/kyra/kyra_mr.cpp b/engines/kyra/kyra_mr.cpp
index 5798e99a1f..39ed0d038a 100644
--- a/engines/kyra/kyra_mr.cpp
+++ b/engines/kyra/kyra_mr.cpp
@@ -205,12 +205,12 @@ Common::Error KyraEngine_MR::init() {
assert(_screen);
_screen->setResolution();
- KyraEngine_v1::init();
- initStaticResource();
-
_debugger = new Debugger_v2(this);
assert(_debugger);
+ KyraEngine_v1::init();
+ initStaticResource();
+
_soundDigital = new SoundDigital(this, _mixer);
assert(_soundDigital);
if (!_soundDigital->init())
@@ -887,6 +887,9 @@ bool KyraEngine_MR::checkCharCollision(int x, int y) {
#pragma mark -
void KyraEngine_MR::runLoop() {
+ // Initialize debugger since how it should be fully usable
+ _debugger->initialize();
+
_eventList.clear();
_runFlag = true;
diff --git a/engines/kyra/kyra_mr.h b/engines/kyra/kyra_mr.h
index 473c0371dc..004236ca04 100644
--- a/engines/kyra/kyra_mr.h
+++ b/engines/kyra/kyra_mr.h
@@ -219,7 +219,7 @@ private:
bool _nextIdleType;
void showIdleAnim();
- const ItemAnimData_v2 *_itemAnimData;
+ const ItemAnimDefinition *_itemAnimDefinition;
ActiveItemAnim _activeItemAnim[10];
int _nextAnimItem;
diff --git a/engines/kyra/kyra_rpg.cpp b/engines/kyra/kyra_rpg.cpp
new file mode 100644
index 0000000000..f1d9550e8f
--- /dev/null
+++ b/engines/kyra/kyra_rpg.cpp
@@ -0,0 +1,367 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#if defined(ENABLE_EOB) || defined(ENABLE_LOL)
+
+#include "kyra/kyra_rpg.h"
+#include "kyra/sound.h"
+
+#include "common/system.h"
+
+namespace Kyra {
+
+KyraRpgEngine::KyraRpgEngine(OSystem *system, const GameFlags &flags) : KyraEngine_v1(system, flags), _numFlyingObjects(_flags.gameID == GI_LOL ? 8 : 10) {
+ _txt = 0;
+ _mouseClick = 0;
+ _preserveEvents = _buttonListChanged = false;
+
+ _sceneXoffset = 0;
+ _sceneShpDim = 5;
+
+ _activeButtons = 0;
+
+ _currentLevel = 0;
+
+ _vcnBlocks = 0;
+ _vcfBlocks = 0;
+ _vcnTransitionMask = 0;
+ _vcnShift = 0;
+ _vcnColTable = 0;
+ _vcnBlockWidth = 4;
+ _vcnBlockHeight = 8;
+ _vcnFlip0 = 0;
+ _vcnFlip1 = 1;
+ _vmpPtr = 0;
+ _vmpSize = 0;
+ _blockBrightness = _wllVcnOffset = 0;
+ _blockDrawingBuffer = 0;
+ _sceneWindowBuffer = 0;
+ _monsterShapes = _monsterPalettes = 0;
+
+ _doorShapes = 0;
+
+ _levelDecorationProperties = 0;
+ _levelDecorationData = 0;
+ _levelDecorationShapes = 0;
+ _decorationCount = 0;
+ _mappedDecorationsCount = 0;
+ memset(_visibleBlockIndex, 0, sizeof(_visibleBlockIndex));
+
+ _lvlShapeTop = _lvlShapeBottom = _lvlShapeLeftRight = 0;
+ _levelBlockProperties = 0;
+ _hasTempDataFlags = 0;
+
+ _wllVmpMap = _specialWallTypes = _wllWallFlags = 0;
+ _wllShapeMap = 0;
+
+ _sceneDrawVarDown = _sceneDrawVarRight = _sceneDrawVarLeft = _wllProcessFlag = 0;
+
+ _currentBlock = 0;
+ _currentDirection = 0;
+ _compassDirection = -1;
+ _updateFlags = _clickedSpecialFlag = 0;
+ _sceneDefaultUpdate = 0;
+ _sceneUpdateRequired = false;
+
+ _flyingObjectsPtr = 0;
+ _flyingObjectStructSize = sizeof(EoBFlyingObject);
+
+ _clickedShapeXOffs = _clickedShapeYOffs = 0;
+
+ _dscShapeX = 0;
+ _dscTileIndex = 0;
+ _dscUnk2 = 0;
+ _dscDim1 = 0;
+ _dscDim2 = 0;
+ _dscBlockMap = 0;
+ _dscBlockIndex = 0;
+ _dscShapeIndex = 0;
+ _dscDimMap = 0;
+ _dscDoorShpIndex = 0;
+ _dscDoorY2 = 0;
+ _dscDoorFrameY1 = 0;
+ _dscDoorFrameY2 = 0;
+ _dscDoorFrameIndex1 = 0;
+ _dscDoorFrameIndex2 = 0;
+
+ _shpDmX1 = _shpDmX2 = 0;
+
+ memset(_openDoorState, 0, sizeof(_openDoorState));
+ memset(_dialogueButtonString, 0, 3 * sizeof(const char *));
+ _dialogueButtonPosX = 0;
+ _dialogueButtonPosY = 0;
+ _dialogueNumButtons = _dialogueButtonYoffs = _dialogueHighlightedButton = 0;
+ _currentControlMode = 0;
+ _specialSceneFlag = 0;
+ _updateCharNum = -1;
+ _activeVoiceFileTotalTime = 0;
+ _updatePortraitSpeechAnimDuration = _resetPortraitAfterSpeechAnim = _needSceneRestore = 0;
+ _fadeText = false;
+
+ memset(_lvlTempData, 0, sizeof(_lvlTempData));
+
+ _dialogueField = false;
+
+ _environmentSfx = _environmentSfxVol = _envSfxDistThreshold = 0;
+ _monsterStepCounter = _monsterStepMode = 0;
+}
+
+KyraRpgEngine::~KyraRpgEngine() {
+ delete[] _wllVmpMap;
+ delete[] _wllShapeMap;
+ delete[] _specialWallTypes;
+ delete[] _wllWallFlags;
+
+ delete[] _vmpPtr;
+ delete[] _vcnColTable;
+ delete[] _vcnBlocks;
+ delete[] _vcfBlocks;
+ delete[] _vcnTransitionMask;
+ delete[] _vcnShift;
+ delete[] _blockDrawingBuffer;
+ delete[] _sceneWindowBuffer;
+
+ delete[] _lvlShapeTop;
+ delete[] _lvlShapeBottom;
+ delete[] _lvlShapeLeftRight;
+
+ delete[] _doorShapes;
+
+ delete[] _levelDecorationShapes;
+ delete[] _levelDecorationData;
+ delete[] _levelDecorationProperties;
+ delete[] _levelBlockProperties;
+}
+
+Common::Error KyraRpgEngine::init() {
+ gui_resetButtonList();
+
+ _levelDecorationProperties = new LevelDecorationProperty[100];
+ memset(_levelDecorationProperties, 0, 100 * sizeof(LevelDecorationProperty));
+ _levelDecorationShapes = new uint8*[400];
+ memset(_levelDecorationShapes, 0, 400 * sizeof(uint8 *));
+ _levelBlockProperties = new LevelBlockProperty[1025];
+ memset(_levelBlockProperties, 0, 1025 * sizeof(LevelBlockProperty));
+
+ _wllVmpMap = new uint8[256];
+ memset(_wllVmpMap, 0, 256);
+ _wllShapeMap = new int8[256];
+ memset(_wllShapeMap, 0, 256);
+ _specialWallTypes = new uint8[256];
+ memset(_specialWallTypes, 0, 256);
+ _wllWallFlags = new uint8[256];
+ memset(_wllWallFlags, 0, 256);
+
+ _blockDrawingBuffer = new uint16[1320];
+ memset(_blockDrawingBuffer, 0, 1320 * sizeof(uint16));
+ uint32 swbSize = 22 * _vcnBlockWidth * 2 * 15 * _vcnBlockHeight;
+ _sceneWindowBuffer = new uint8[swbSize];
+ memset(_sceneWindowBuffer, 0, swbSize);
+
+ _lvlShapeTop = new int16[18];
+ memset(_lvlShapeTop, 0, 18 * sizeof(int16));
+ _lvlShapeBottom = new int16[18];
+ memset(_lvlShapeBottom, 0, 18 * sizeof(int16));
+ _lvlShapeLeftRight = new int16[36];
+ memset(_lvlShapeLeftRight, 0, 36 * sizeof(int16));
+
+ _vcnColTable = new uint8[128];
+ for (int i = 0; i < 128; i++)
+ _vcnColTable[i] = i & 0x0f;
+
+ _doorShapes = new uint8*[6];
+ memset(_doorShapes, 0, 6 * sizeof(uint8 *));
+
+ initStaticResource();
+
+ _envSfxDistThreshold = (_sound->getSfxType() == Sound::kAdLib || _sound->getSfxType() == Sound::kPCSpkr) ? 15 : 3;
+
+ _dialogueButtonLabelColor1 = guiSettings()->buttons.labelColor1;
+ _dialogueButtonLabelColor2 = guiSettings()->buttons.labelColor2;
+ _dialogueButtonWidth = guiSettings()->buttons.width;
+
+ return Common::kNoError;
+}
+
+bool KyraRpgEngine::posWithinRect(int posX, int posY, int x1, int y1, int x2, int y2) {
+ if (posX < x1 || posX > x2 || posY < y1 || posY > y2)
+ return false;
+ return true;
+}
+
+void KyraRpgEngine::drawDialogueButtons() {
+ int cp = screen()->setCurPage(0);
+ Screen::FontId of = screen()->setFont(gameFlags().use16ColorMode ? Screen::FID_SJIS_FNT : Screen::FID_6_FNT);
+
+ for (int i = 0; i < _dialogueNumButtons; i++) {
+ int x = _dialogueButtonPosX[i];
+ if (gameFlags().use16ColorMode) {
+ gui_drawBox(x, ((_dialogueButtonYoffs + _dialogueButtonPosY[i]) & ~7) - 1, 74, 10, 0xee, 0xcc, -1);
+ screen()->printText(_dialogueButtonString[i], (x + 37 - (screen()->getTextWidth(_dialogueButtonString[i])) / 2) & ~3,
+ ((_dialogueButtonYoffs + _dialogueButtonPosY[i]) + 2) & ~7, _dialogueHighlightedButton == i ? 0xc1 : 0xe1, 0);
+ } else {
+ gui_drawBox(x, (_dialogueButtonYoffs + _dialogueButtonPosY[i]), _dialogueButtonWidth, guiSettings()->buttons.height, guiSettings()->colors.frame1, guiSettings()->colors.frame2, guiSettings()->colors.fill);
+ screen()->printText(_dialogueButtonString[i], x + (_dialogueButtonWidth >> 1) - (screen()->getTextWidth(_dialogueButtonString[i])) / 2,
+ (_dialogueButtonYoffs + _dialogueButtonPosY[i]) + 2, _dialogueHighlightedButton == i ? _dialogueButtonLabelColor1 : _dialogueButtonLabelColor2, 0);
+ }
+ }
+ screen()->setFont(of);
+ screen()->setCurPage(cp);
+}
+
+uint16 KyraRpgEngine::processDialogue() {
+ int df = _dialogueHighlightedButton;
+ int res = 0;
+
+ for (int i = 0; i < _dialogueNumButtons; i++) {
+ int x = _dialogueButtonPosX[i];
+ int y = (gameFlags().use16ColorMode ? ((_dialogueButtonYoffs + _dialogueButtonPosY[i]) & ~7) - 1 : (_dialogueButtonYoffs + _dialogueButtonPosY[i]));
+ Common::Point p = getMousePos();
+ if (posWithinRect(p.x, p.y, x, y, x + _dialogueButtonWidth, y + guiSettings()->buttons.height)) {
+ _dialogueHighlightedButton = i;
+ break;
+ }
+ }
+
+ if (_dialogueNumButtons == 0) {
+ int e = checkInput(0, false) & 0xFF;
+ removeInputTop();
+
+ if (e) {
+ gui_notifyButtonListChanged();
+
+ if (e == _keyMap[Common::KEYCODE_SPACE] || e == _keyMap[Common::KEYCODE_RETURN]) {
+ snd_stopSpeech(true);
+ }
+ }
+
+ if (snd_updateCharacterSpeech() != 2) {
+ res = 1;
+ if (!shouldQuit()) {
+ removeInputTop();
+ gui_notifyButtonListChanged();
+ }
+ }
+ } else {
+ int e = checkInput(0, false, 0) & 0xFF;
+ removeInputTop();
+ if (e)
+ gui_notifyButtonListChanged();
+
+ if ((_flags.gameID == GI_LOL && (e == 200 || e == 202)) || (_flags.gameID != GI_LOL && (e == 199 || e == 201))) {
+ for (int i = 0; i < _dialogueNumButtons; i++) {
+ int x = _dialogueButtonPosX[i];
+ int y = (gameFlags().use16ColorMode ? ((_dialogueButtonYoffs + _dialogueButtonPosY[i]) & ~7) - 1 : (_dialogueButtonYoffs + _dialogueButtonPosY[i]));
+ Common::Point p = getMousePos();
+ if (posWithinRect(p.x, p.y, x, y, x + _dialogueButtonWidth, y + guiSettings()->buttons.height)) {
+ _dialogueHighlightedButton = i;
+ res = _dialogueHighlightedButton + 1;
+ break;
+ }
+ }
+ } else if (e == _keyMap[Common::KEYCODE_SPACE] || e == _keyMap[Common::KEYCODE_RETURN]) {
+ snd_stopSpeech(true);
+ res = _dialogueHighlightedButton + 1;
+ } else if (e == _keyMap[Common::KEYCODE_LEFT] || e == _keyMap[Common::KEYCODE_DOWN]) {
+ if (_dialogueNumButtons > 1 && _dialogueHighlightedButton > 0)
+ _dialogueHighlightedButton--;
+ } else if (e == _keyMap[Common::KEYCODE_RIGHT] || e == _keyMap[Common::KEYCODE_UP]) {
+ if (_dialogueNumButtons > 1 && _dialogueHighlightedButton < (_dialogueNumButtons - 1))
+ _dialogueHighlightedButton++;
+ }
+ }
+
+ if (df != _dialogueHighlightedButton)
+ drawDialogueButtons();
+
+ screen()->updateScreen();
+
+ if (res == 0)
+ return 0;
+
+ stopPortraitSpeechAnim();
+
+ if (game() == GI_LOL) {
+ if (!textEnabled() && _currentControlMode) {
+ screen()->setScreenDim(5);
+ const ScreenDim *d = screen()->getScreenDim(5);
+ screen()->fillRect(d->sx, d->sy + d->h - 9, d->sx + d->w - 1, d->sy + d->h - 1, d->unkA);
+ } else {
+ const ScreenDim *d = screen()->_curDim;
+ if (gameFlags().use16ColorMode)
+ screen()->fillRect(d->sx, d->sy, d->sx + d->w - 3, d->sy + d->h - 2, d->unkA);
+ else
+ screen()->fillRect(d->sx, d->sy, d->sx + d->w - 2, d->sy + d->h - 1, d->unkA);
+ txt()->clearDim(4);
+ txt()->resetDimTextPositions(4);
+ }
+ }
+
+ return res;
+}
+
+void KyraRpgEngine::delayUntil(uint32 time, bool, bool doUpdate, bool isMainLoop) {
+ uint32 curTime = _system->getMillis();
+ if (time > curTime)
+ delay(time - curTime, doUpdate, isMainLoop);
+}
+
+int KyraRpgEngine::rollDice(int times, int pips, int inc) {
+ if (times <= 0 || pips <= 0)
+ return inc;
+
+ int res = 0;
+ while (times--)
+ res += _rnd.getRandomNumberRng(1, pips);
+
+ return res + inc;
+}
+
+bool KyraRpgEngine::snd_processEnvironmentalSoundEffect(int soundId, int block) {
+ if (!_sound->sfxEnabled() || shouldQuit())
+ return false;
+
+ if (_environmentSfx)
+ snd_playSoundEffect(_environmentSfx, _environmentSfxVol);
+
+ int dist = 0;
+ if (block) {
+ dist = getBlockDistance(_currentBlock, block);
+ if (dist > _envSfxDistThreshold) {
+ _environmentSfx = 0;
+ return false;
+ }
+ }
+
+ _environmentSfx = soundId;
+ _environmentSfxVol = (15 - ((block || (_flags.gameID == GI_LOL && dist < 2)) ? dist : 0)) << 4;
+
+ return true;
+}
+
+void KyraRpgEngine::updateEnvironmentalSfx(int soundId) {
+ snd_processEnvironmentalSoundEffect(soundId, _currentBlock);
+}
+
+} // End of namespace Kyra
+
+#endif // ENABLE_EOB || ENABLE_LOL
diff --git a/engines/kyra/kyra_rpg.h b/engines/kyra/kyra_rpg.h
new file mode 100644
index 0000000000..50a4c9bdc1
--- /dev/null
+++ b/engines/kyra/kyra_rpg.h
@@ -0,0 +1,392 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public 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 KYRA_RPG_H
+#define KYRA_RPG_H
+
+#if defined(ENABLE_EOB) || defined(ENABLE_LOL)
+
+#include "kyra/kyra_v1.h"
+#include "kyra/screen_eob.h"
+#include "kyra/gui_eob.h"
+#include "kyra/text_lol.h"
+
+namespace Kyra {
+
+struct LevelDecorationProperty {
+ uint16 shapeIndex[10];
+ uint8 scaleFlag[10];
+ int16 shapeX[10];
+ int16 shapeY[10];
+ int8 next;
+ uint8 flags;
+};
+
+struct LevelBlockProperty {
+ uint8 walls[4];
+ uint16 assignedObjects;
+ uint16 drawObjects;
+ uint8 direction;
+ uint16 flags;
+};
+
+struct OpenDoorState {
+ uint16 block;
+ int8 wall;
+ int8 state;
+};
+
+struct LevelTempData {
+ uint8 *wallsXorData;
+ uint16 *flags;
+ void *monsters;
+ void *flyingObjects;
+ void *wallsOfForce;
+ uint8 monsterDifficulty;
+};
+
+struct EoBFlyingObject {
+ uint8 enable;
+ uint8 objectType;
+ int16 attackerId;
+ Item item;
+ uint16 curBlock;
+ uint16 starting;
+ uint8 u1;
+ uint8 direction;
+ uint8 distance;
+ int8 callBackIndex;
+ uint8 curPos;
+ uint8 flags;
+ uint8 unused;
+};
+
+struct KyraRpgGUISettings {
+ struct DialogueButtons {
+ uint8 labelColor1;
+ uint8 labelColor2;
+ uint16 width;
+ uint16 height;
+ int waitReserve;
+ uint16 waitX[2];
+ uint8 waitY[2];
+ uint16 waitWidth[2];
+ } buttons;
+
+ struct Colors {
+ uint8 frame1;
+ uint8 frame2;
+ int fill;
+
+ uint8 unused;
+ uint8 barGraph;
+
+ uint8 warningFrame1;
+ uint8 warningFrame2;
+ int warningFill;
+
+ uint8 extraFrame1;
+ uint8 extraFrame2;
+ int extraFill;
+
+ uint8 inactiveTabFrame1;
+ uint8 inactiveTabFrame2;
+ int inactiveTabFill;
+ } colors;
+};
+
+class KyraRpgEngine : public KyraEngine_v1 {
+friend class TextDisplayer_rpg;
+public:
+ KyraRpgEngine(OSystem *system, const GameFlags &flags);
+ virtual ~KyraRpgEngine();
+
+ virtual Screen *screen() = 0;
+ virtual GUI *gui() const = 0;
+
+protected:
+ // Startup
+ virtual Common::Error init();
+ virtual Common::Error go() = 0;
+
+ // Init
+ void initStaticResource();
+
+ const uint8 **_itemIconShapes;
+
+ // Main loop
+ virtual void update() = 0;
+ void updateEnvironmentalSfx(int soundId);
+
+ // timers
+ virtual void setupTimers() = 0;
+ void enableSysTimer(int sysTimer);
+ void disableSysTimer(int sysTimer);
+ void enableTimer(int id);
+ virtual uint8 getClock2Timer(int index) = 0;
+ virtual uint8 getNumClock2Timers() = 0;
+
+ void timerProcessDoors(int timerNum);
+
+ // mouse
+ bool posWithinRect(int posX, int posY, int x1, int y1, int x2, int y2);
+ virtual void setHandItem(Item itemIndex) = 0;
+
+ // Characters
+ int _updateCharNum;
+ int _updatePortraitSpeechAnimDuration;
+ bool _fadeText;
+ int _resetPortraitAfterSpeechAnim;
+ int _needSceneRestore;
+
+ // Items
+ int _itemInHand;
+
+ // Monsters
+ int getBlockDistance(uint16 block1, uint16 block2);
+
+ uint8 **_monsterPalettes;
+ uint8 **_monsterShapes;
+
+ int16 _shpDmX1;
+ int16 _shpDmX2;
+
+ int _monsterStepCounter;
+ int _monsterStepMode;
+
+ // Level
+ virtual void addLevelItems() = 0;
+ virtual void loadBlockProperties(const char *file) = 0;
+
+ virtual void drawScene(int pageNum) = 0;
+ virtual void drawSceneShapes(int start) = 0;
+ virtual void drawDecorations(int index) = 0;
+
+ virtual const uint8 *getBlockFileData(int levelIndex) = 0;
+ void setLevelShapesDim(int index, int16 &x1, int16 &x2, int dim);
+ void setDoorShapeDim(int index, int16 &y1, int16 &y2, int dim);
+ void drawLevelModifyScreenDim(int dim, int16 x1, int16 y1, int16 x2, int16 y2);
+ void generateBlockDrawingBuffer();
+ void generateVmpTileData(int16 startBlockX, uint8 startBlockY, uint8 wllVmpIndex, int16 vmpOffset, uint8 numBlocksX, uint8 numBlocksY);
+ void generateVmpTileDataFlipped(int16 startBlockX, uint8 startBlockY, uint8 wllVmpIndex, int16 vmpOffset, uint8 numBlocksX, uint8 numBlocksY);
+ bool hasWall(int index);
+ void assignVisibleBlocks(int block, int direction);
+ bool checkSceneUpdateNeed(int block);
+ void drawVcnBlocks();
+ uint16 calcNewBlockPosition(uint16 curBlock, uint16 direction);
+
+ virtual int clickedDoorSwitch(uint16 block, uint16 direction) = 0;
+ int clickedWallShape(uint16 block, uint16 direction);
+ int clickedLeverOn(uint16 block, uint16 direction);
+ int clickedLeverOff(uint16 block, uint16 direction);
+ int clickedWallOnlyScript(uint16 block);
+ virtual int clickedNiche(uint16 block, uint16 direction) = 0;
+
+ void processDoorSwitch(uint16 block, int openClose);
+ void openCloseDoor(int block, int openClose);
+ void completeDoorOperations();
+
+ uint8 *_wllVmpMap;
+ int8 *_wllShapeMap;
+ uint8 *_specialWallTypes;
+ uint8 *_wllWallFlags;
+
+ int _sceneXoffset;
+ int _sceneShpDim;
+
+ LevelBlockProperty *_levelBlockProperties;
+ LevelBlockProperty *_visibleBlocks[18];
+ LevelDecorationProperty *_levelDecorationData;
+ uint16 _levelDecorationDataSize;
+ LevelDecorationProperty *_levelDecorationProperties;
+ uint8 **_levelDecorationShapes;
+ uint16 _decorationCount;
+ int16 _mappedDecorationsCount;
+ uint16 *_vmpPtr;
+ uint16 _vmpSize;
+ uint8 *_vcnBlocks;
+ uint8 *_vcfBlocks;
+ uint8 *_vcnTransitionMask;
+ uint8 *_vcnShift;
+ uint8 *_vcnColTable;
+ uint16 *_blockDrawingBuffer;
+ uint8 *_sceneWindowBuffer;
+ uint8 _blockBrightness;
+ uint8 _wllVcnOffset;
+ uint8 _vcnBlockWidth;
+ uint8 _vcnBlockHeight;
+ uint8 _vcnFlip0;
+ uint8 _vcnFlip1;
+
+ uint8 **_doorShapes;
+
+ uint8 _currentLevel;
+ uint16 _currentBlock;
+ uint16 _currentDirection;
+ int _sceneDefaultUpdate;
+ bool _sceneUpdateRequired;
+
+ int16 _visibleBlockIndex[18];
+ int16 *_lvlShapeLeftRight;
+ int16 *_lvlShapeTop;
+ int16 *_lvlShapeBottom;
+
+ char _lastBlockDataFile[13];
+ uint32 _hasTempDataFlags;
+
+ int16 _sceneDrawVarDown;
+ int16 _sceneDrawVarRight;
+ int16 _sceneDrawVarLeft;
+ int _wllProcessFlag;
+
+ OpenDoorState _openDoorState[3];
+
+ int _sceneDrawPage1;
+ int _sceneDrawPage2;
+
+ const int8 *_dscShapeIndex;
+ const uint8 *_dscDimMap;
+ const int8 *_dscDim1;
+ const int8 *_dscDim2;
+ const int16 *_dscShapeX;
+ const uint8 *_dscUnk2;
+ const uint8 *_dscBlockMap;
+ const int8 *_dscBlockIndex;
+ const uint8 *_dscTileIndex;
+
+ const uint8 *_dscDoorShpIndex;
+ int _dscDoorShpIndexSize;
+ const uint8 *_dscDoorY2;
+ const uint8 *_dscDoorFrameY1;
+ const uint8 *_dscDoorFrameY2;
+ const uint8 *_dscDoorFrameIndex1;
+ const uint8 *_dscDoorFrameIndex2;
+
+ // Script
+ virtual void runLevelScript(int block, int flags) = 0;
+
+ // Gui
+ void removeInputTop();
+ void gui_drawBox(int x, int y, int w, int h, int frameColor1, int frameColor2, int fillColor);
+ virtual void gui_drawHorizontalBarGraph(int x, int y, int w, int h, int32 curVal, int32 maxVal, int col1, int col2);
+ void gui_initButtonsFromList(const int16 *list);
+ virtual void gui_initButton(int index, int x = -1, int y = -1, int val = -1) = 0;
+ void gui_resetButtonList();
+ void gui_notifyButtonListChanged();
+
+ bool clickedShape(int shapeIndex);
+
+ virtual const KyraRpgGUISettings *guiSettings() = 0;
+
+ int _clickedShapeXOffs;
+ int _clickedShapeYOffs;
+
+ Button *_activeButtons;
+ Button _activeButtonData[70];
+ Common::Array<Button::Callback> _buttonCallbacks;
+ //bool _processingButtons;
+
+ uint8 _mouseClick;
+ bool _preserveEvents;
+ bool _buttonListChanged;
+
+ int _updateFlags;
+ int _clickedSpecialFlag;
+
+ int _compassDirection;
+
+ static const uint8 _dropItemDirIndex[];
+
+ // text
+ void drawDialogueButtons();
+ uint16 processDialogue();
+
+ TextDisplayer_rpg *_txt;
+ virtual TextDisplayer_rpg *txt() { return _txt; }
+
+ bool _dialogueField;
+
+ const char *_dialogueButtonString[9];
+ const uint16 *_dialogueButtonPosX;
+ const uint8 *_dialogueButtonPosY;
+ int16 _dialogueButtonYoffs;
+ uint16 _dialogueButtonWidth;
+ int _dialogueNumButtons;
+ int _dialogueHighlightedButton;
+ int _currentControlMode;
+ int _specialSceneFlag;
+ uint8 _dialogueButtonLabelColor1;
+ uint8 _dialogueButtonLabelColor2;
+
+ const char *const *_moreStrings;
+
+ // misc
+ virtual void delay(uint32 millis, bool doUpdate = false, bool isMainLoop = false) = 0;
+ void delayUntil(uint32 time, bool unused = false, bool doUpdate = false, bool isMainLoop = false);
+ int rollDice(int times, int pips, int inc = 0);
+
+ virtual Common::Error loadGameState(int slot) = 0;
+ virtual Common::Error saveGameStateIntern(int slot, const char *saveName, const Graphics::Surface *thumbnail) = 0;
+
+ void generateTempData();
+ virtual void restoreBlockTempData(int levelIndex);
+ void releaseTempData();
+ virtual void *generateMonsterTempData(LevelTempData *tmp) = 0;
+ virtual void restoreMonsterTempData(LevelTempData *tmp) = 0;
+ virtual void releaseMonsterTempData(LevelTempData *tmp) = 0;
+ void restoreFlyingObjectTempData(LevelTempData *tmp);
+ void *generateFlyingObjectTempData(LevelTempData *tmp);
+ void releaseFlyingObjectTempData(LevelTempData *tmp);
+ virtual void *generateWallOfForceTempData(LevelTempData *tmp) { return 0; }
+ virtual void restoreWallOfForceTempData(LevelTempData *tmp) {}
+ virtual void releaseWallOfForceTempData(LevelTempData *tmp) {}
+
+ LevelTempData *_lvlTempData[29];
+ const int _numFlyingObjects;
+ uint32 _flyingObjectStructSize;
+ void *_flyingObjectsPtr;
+
+ // sound
+ virtual bool snd_processEnvironmentalSoundEffect(int soundId, int block);
+ virtual void snd_stopSpeech(bool) {}
+ virtual int snd_updateCharacterSpeech() { return 0; }
+ virtual void stopPortraitSpeechAnim() {}
+ virtual void setupOpcodeTable() {}
+ virtual void snd_playVoiceFile(int) {}
+
+ int _environmentSfx;
+ int _environmentSfxVol;
+ int _envSfxDistThreshold;
+
+ uint32 _activeVoiceFileTotalTime;
+
+ // unused
+ void setWalkspeed(uint8) {}
+ void removeHandItem() {}
+ bool lineIsPassable(int, int) { return false; }
+};
+
+} // End of namespace Kyra
+
+#endif // ENABLE_EOB || ENABLE_LOL
+
+#endif
diff --git a/engines/kyra/kyra_v1.cpp b/engines/kyra/kyra_v1.cpp
index c950612a42..2672618c67 100644
--- a/engines/kyra/kyra_v1.cpp
+++ b/engines/kyra/kyra_v1.cpp
@@ -42,6 +42,8 @@ KyraEngine_v1::KyraEngine_v1(OSystem *system, const GameFlags &flags)
_emc = 0;
_debugger = 0;
+ _configRenderMode = Common::kRenderDefault;
+
if (_flags.platform == Common::kPlatformAmiga)
_gameSpeed = 50;
else
@@ -85,8 +87,9 @@ KyraEngine_v1::KyraEngine_v1(OSystem *system, const GameFlags &flags)
void KyraEngine_v1::pauseEngineIntern(bool pause) {
Engine::pauseEngineIntern(pause);
if (_sound)
- _sound->pause(pause);
- _timer->pause(pause);
+ _sound->pause(pause);
+ if (_timer)
+ _timer->pause(pause);
}
Common::Error KyraEngine_v1::init() {
@@ -162,6 +165,9 @@ Common::Error KyraEngine_v1::init() {
if (_sound)
_sound->updateVolumeSettings();
+ if (ConfMan.hasKey("render_mode"))
+ _configRenderMode = Common::parseRenderMode(ConfMan.get("render_mode"));
+
_res = new Resource(this);
assert(_res);
_res->reset();
@@ -183,6 +189,7 @@ Common::Error KyraEngine_v1::init() {
assert(_staticres);
if (!_staticres->init())
error("_staticres->init() failed");
+ assert(screen());
if (!screen()->init())
error("screen()->init() failed");
_timer = new TimerManager(this, _system);
@@ -223,10 +230,10 @@ KyraEngine_v1::~KyraEngine_v1() {
delete _debugger;
}
-Common::Point KyraEngine_v1::getMousePos() const {
+Common::Point KyraEngine_v1::getMousePos() {
Common::Point mouse = _eventMan->getMousePos();
- if (_flags.useHiResOverlay) {
+ if (_flags.useHiRes) {
mouse.x >>= 1;
mouse.y >>= 1;
}
@@ -235,7 +242,7 @@ Common::Point KyraEngine_v1::getMousePos() const {
}
void KyraEngine_v1::setMousePos(int x, int y) {
- if (_flags.useHiResOverlay) {
+ if (_flags.useHiRes) {
x <<= 1;
y <<= 1;
}
@@ -260,7 +267,7 @@ int KyraEngine_v1::checkInput(Button *buttonList, bool mainLoop, int eventFlag)
switch (event.type) {
case Common::EVENT_KEYDOWN:
if (event.kbd.keycode >= Common::KEYCODE_1 && event.kbd.keycode <= Common::KEYCODE_9 &&
- (event.kbd.hasFlags(Common::KBD_CTRL) || event.kbd.hasFlags(Common::KBD_ALT)) && mainLoop) {
+ (event.kbd.hasFlags(Common::KBD_CTRL) || event.kbd.hasFlags(Common::KBD_ALT)) && mainLoop) {
int saveLoadSlot = 9 - (event.kbd.keycode - Common::KEYCODE_0) + 990;
if (event.kbd.hasFlags(Common::KBD_CTRL)) {
@@ -283,10 +290,13 @@ int KyraEngine_v1::checkInput(Button *buttonList, bool mainLoop, int eventFlag)
}
} else {
KeyMap::const_iterator keycode = _keyMap.find(event.kbd.keycode);
- if (keycode != _keyMap.end())
+ if (keycode != _keyMap.end()) {
keys = keycode->_value;
- else
+ if (event.kbd.flags & Common::KBD_SHIFT)
+ keys |= 0x100;
+ } else {
keys = 0;
+ }
// When we got an keypress, which we might need to handle,
// break the event loop and pass it to GUI code.
@@ -299,7 +309,7 @@ int KyraEngine_v1::checkInput(Button *buttonList, bool mainLoop, int eventFlag)
case Common::EVENT_LBUTTONUP: {
_mouseX = event.mouse.x;
_mouseY = event.mouse.y;
- if (_flags.useHiResOverlay) {
+ if (_flags.useHiRes) {
_mouseX >>= 1;
_mouseY >>= 1;
}
@@ -311,7 +321,7 @@ int KyraEngine_v1::checkInput(Button *buttonList, bool mainLoop, int eventFlag)
case Common::EVENT_RBUTTONUP: {
_mouseX = event.mouse.x;
_mouseY = event.mouse.y;
- if (_flags.useHiResOverlay) {
+ if (_flags.useHiRes) {
_mouseX >>= 1;
_mouseY >>= 1;
}
@@ -352,14 +362,14 @@ int KyraEngine_v1::checkInput(Button *buttonList, bool mainLoop, int eventFlag)
}
void KyraEngine_v1::setupKeyMap() {
- struct KeyMapEntry {
+ struct KeyCodeMapEntry {
Common::KeyCode kcScummVM;
int16 kcDOS;
int16 kcPC98;
};
#define KC(x) Common::KEYCODE_##x
- static const KeyMapEntry keys[] = {
+ static const KeyCodeMapEntry keys[] = {
{ KC(SPACE), 61, 53 },
{ KC(RETURN), 43, 29 },
{ KC(UP), 96, 68 },
@@ -375,13 +385,58 @@ void KyraEngine_v1::setupKeyMap() {
{ KC(KP7), 91, 67 },
{ KC(PAGEUP), 101, 69 },
{ KC(KP9), 101, 69 },
+ { KC(END), 93, 0/*unknown*/ },
+ { KC(KP1), 93, 0/*unknown*/ },
+ { KC(PAGEDOWN), 103, 0/*unknown*/ },
+ { KC(KP3), 103, 0/*unknown*/ },
{ KC(F1), 112, 99 },
{ KC(F2), 113, 100 },
{ KC(F3), 114, 101 },
+ { KC(F4), 115, 102 },
+ { KC(F5), 116, 103 },
+ { KC(F6), 117, 104 },
+ { KC(a), 31, 31 },
+ { KC(b), 50, 50 },
+ { KC(c), 48, 48 },
+ { KC(d), 33, 33 },
+ { KC(e), 19, 19 },
+ { KC(f), 34, 34 },
+ { KC(i), 24, 24 },
+ { KC(k), 38, 38 },
+ { KC(m), 52, 52 },
+ { KC(n), 51, 51 },
{ KC(o), 25, 25 },
+ { KC(p), 26, 26 },
{ KC(r), 20, 20 },
+ { KC(s), 32, 32 },
+ { KC(w), 18, 18 },
+ { KC(y), 22, 22 },
+ { KC(z), 46, 46 },
+ { KC(1), 2, 0/*unknown*/ },
+ { KC(2), 3, 0/*unknown*/ },
+ { KC(3), 4, 0/*unknown*/ },
+ { KC(4), 5, 0/*unknown*/ },
+ { KC(5), 6, 0/*unknown*/ },
+ { KC(6), 7, 0/*unknown*/ },
+ { KC(7), 8, 0/*unknown*/ },
{ KC(SLASH), 55, 55 },
{ KC(ESCAPE), 110, 1 },
+ { KC(MINUS), 12, 0/*unknown*/ },
+ { KC(KP_MINUS), 105, 0/*unknown*/ },
+ { KC(PLUS), 13, 0/*unknown*/ },
+ { KC(KP_PLUS), 106, 0/*unknown*/ },
+
+ // Multiple mappings for the keys to the right of the 'M' key,
+ // since these are different for QWERTZ, QWERTY and AZERTY keyboards.
+ // QWERTZ
+ { KC(COMMA), 53, 0/*unknown*/ },
+ { KC(PERIOD), 54, 0/*unknown*/ },
+ // AZERTY
+ { KC(SEMICOLON), 53, 0/*unknown*/ },
+ { KC(COLON), 54, 0/*unknown*/ },
+ // QWERTY
+ { KC(LESS), 53, 0/*unknown*/ },
+ { KC(GREATER), 54, 0/*unknown*/ }
};
#undef KC
@@ -400,10 +455,10 @@ void KyraEngine_v1::updateInput() {
switch (event.type) {
case Common::EVENT_KEYDOWN:
if (event.kbd.keycode == Common::KEYCODE_PERIOD || event.kbd.keycode == Common::KEYCODE_ESCAPE ||
- event.kbd.keycode == Common::KEYCODE_SPACE || event.kbd.keycode == Common::KEYCODE_RETURN ||
- event.kbd.keycode == Common::KEYCODE_UP || event.kbd.keycode == Common::KEYCODE_RIGHT ||
- event.kbd.keycode == Common::KEYCODE_DOWN || event.kbd.keycode == Common::KEYCODE_LEFT)
- _eventList.push_back(Event(event, true));
+ event.kbd.keycode == Common::KEYCODE_SPACE || event.kbd.keycode == Common::KEYCODE_RETURN ||
+ event.kbd.keycode == Common::KEYCODE_UP || event.kbd.keycode == Common::KEYCODE_RIGHT ||
+ event.kbd.keycode == Common::KEYCODE_DOWN || event.kbd.keycode == Common::KEYCODE_LEFT)
+ _eventList.push_back(Event(event, true));
else if (event.kbd.keycode == Common::KEYCODE_q && event.kbd.hasFlags(Common::KBD_CTRL))
quitGame();
else
@@ -534,11 +589,11 @@ void KyraEngine_v1::readSettings() {
bool subtitles = ConfMan.getBool("subtitles");
if (!speechMute && subtitles)
- _configVoice = 2; // Voice & Text
+ _configVoice = 2; // Voice & Text
else if (!speechMute && !subtitles)
- _configVoice = 1; // Voice only
+ _configVoice = 1; // Voice only
else
- _configVoice = 0; // Text only
+ _configVoice = 0; // Text only
setWalkspeed(_configWalkspeed);
}
@@ -553,15 +608,15 @@ void KyraEngine_v1::writeSettings() {
ConfMan.setBool("sfx_mute", _configSounds == 0);
switch (_configVoice) {
- case 0: // Text only
+ case 0: // Text only
speechMute = true;
subtitles = true;
break;
- case 1: // Voice only
+ case 1: // Voice only
speechMute = false;
subtitles = false;
break;
- default: // Voice & Text
+ default: // Voice & Text
speechMute = false;
subtitles = true;
}
diff --git a/engines/kyra/kyra_v1.h b/engines/kyra/kyra_v1.h
index 584176e08c..0033969047 100644
--- a/engines/kyra/kyra_v1.h
+++ b/engines/kyra/kyra_v1.h
@@ -28,8 +28,9 @@
#include "common/array.h"
#include "common/error.h"
#include "common/events.h"
-#include "common/random.h"
#include "common/hashmap.h"
+#include "common/random.h"
+#include "common/rendermode.h"
#include "audio/mixer.h"
@@ -52,14 +53,16 @@ class KyraMetaEngine;
*
* Status of this engine:
*
- * The KYRA engine supports all three Kyrandia games by Westwood. It also supports Westwood's
- * Lands of Lore. There are various platform ports of the different games, almost all of them are
- * fully supported. Only the Macintosh port of Kyrandia 1 makes a difference here, which lacks
- * support for sound effects and music.
+ * The KYRA engine supports all three Kyrandia games by Westwood. It also
+ * supports Westwood's Lands of Lore. There are various platform ports of
+ * the different games, almost all of them are fully supported. Only the
+ * Macintosh port of Kyrandia 1 makes a difference here, which lacks support
+ * for sound effects and music.
*
- * The different translations of the games are mostly supported, since every translation
- * requires some work for kyra.dat for example, it is almost impossible to support translations,
- * without owning them. There a currently a few reported unsupported translations:
+ * The different translations of the games are mostly supported, since every
+ * translation requires some work for kyra.dat for example, it is almost
+ * impossible to support translations, without owning them. There a currently
+ * a few reported unsupported translations:
*
* - Official translations
* None known.
@@ -69,24 +72,30 @@ class KyraMetaEngine;
* Kyrandia 1 Korean (feature request #1758252 "KYRA1: Add support for Korean/DOS version")
* Kyrandia 2 Polish (feature request #2146192 "KYRA2: Add support for Polish floppy version")
* - Fan translations:
- * Kyrandia 1 Russian (no feature request)
- * Kyrandia 2 Russian (no feature request)
* Kyrandia 3 Russian (feature request #2812792 "Kyrandia3 Russian")
*
- * The engine is maintained by _athrxx.
+ * 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.
*
- * 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. 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.
+ * 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. 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.
+ * He also contributed the VQA player for Kyrandia 3.
*
- * 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
+ * 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.
*
* Games using this engine:
@@ -110,7 +119,7 @@ struct GameFlags {
bool useAltShapeHeader : 1; // alternative shape header (uses 2 bytes more, those are unused though)
bool isTalkie : 1;
bool isOldFloppy : 1;
- bool useHiResOverlay : 1;
+ bool useHiRes : 1;
bool use16ColorMode : 1;
bool useDigSound : 1;
bool useInstallerPackage : 1;
@@ -126,7 +135,9 @@ enum {
GI_KYRA1 = 0,
GI_KYRA2 = 1,
GI_KYRA3 = 2,
- GI_LOL = 4
+ GI_LOL = 4,
+ GI_EOB1 = 5,
+ GI_EOB2 = 6
};
struct AudioDataStruct {
@@ -174,7 +185,10 @@ class KyraEngine_v1 : public Engine {
friend class Debugger;
friend class ::KyraMetaEngine;
friend class GUI;
+friend class GUI_v1;
+friend class GUI_EoB;
friend class SoundMidiPC; // For _eventMan
+friend class TransferPartyWiz; // For save state API
public:
KyraEngine_v1(OSystem *system, const GameFlags &flags);
virtual ~KyraEngine_v1();
@@ -197,7 +211,7 @@ public:
// input
void setMousePos(int x, int y);
- Common::Point getMousePos() const;
+ Common::Point getMousePos();
// config specific
bool speechEnabled();
@@ -293,6 +307,8 @@ protected:
bool _configSounds;
uint8 _configVoice;
+ Common::RenderMode _configRenderMode;
+
// game speed
virtual bool skipFlag() const;
virtual void resetSkipFlag(bool removeEvent = true);
@@ -413,7 +429,7 @@ protected:
Common::Error saveGameState(int slot, const Common::String &desc) { return saveGameStateIntern(slot, desc.c_str(), 0); }
virtual Common::Error saveGameStateIntern(int slot, const char *saveName, const Graphics::Surface *thumbnail) = 0;
- Common::SeekableReadStream *openSaveForReading(const char *filename, SaveHeader &header);
+ Common::SeekableReadStream *openSaveForReading(const char *filename, SaveHeader &header, bool checkID = true);
Common::WriteStream *openSaveForWriting(const char *filename, const char *saveName, const Graphics::Surface *thumbnail) const;
// TODO: Consider moving this to Screen
diff --git a/engines/kyra/kyra_v2.cpp b/engines/kyra/kyra_v2.cpp
index e8cb9b4370..75b568a00a 100644
--- a/engines/kyra/kyra_v2.cpp
+++ b/engines/kyra/kyra_v2.cpp
@@ -121,7 +121,7 @@ KyraEngine_v2::~KyraEngine_v2() {
delete[] _animObjects;
- for (Common::Array<const Opcode*>::iterator i = _opcodesAnimation.begin(); i != _opcodesAnimation.end(); ++i)
+ for (Common::Array<const Opcode *>::iterator i = _opcodesAnimation.begin(); i != _opcodesAnimation.end(); ++i)
delete *i;
_opcodesAnimation.clear();
@@ -162,8 +162,8 @@ void KyraEngine_v2::delay(uint32 amount, bool updateGame, bool isMainLoop) {
}
bool KyraEngine_v2::checkSpecialSceneExit(int num, int x, int y) {
- if (_specialExitTable[0+num] > x || _specialExitTable[5+num] > y ||
- _specialExitTable[10+num] < x || _specialExitTable[15+num] < y)
+ if (_specialExitTable[0 + num] > x || _specialExitTable[5 + num] > y ||
+ _specialExitTable[10 + num] < x || _specialExitTable[15 + num] < y)
return false;
return true;
}
diff --git a/engines/kyra/kyra_v2.h b/engines/kyra/kyra_v2.h
index 56391d151a..563416bf1e 100644
--- a/engines/kyra/kyra_v2.h
+++ b/engines/kyra/kyra_v2.h
@@ -24,7 +24,7 @@
#define KYRA_KYRA_V2_H
#include "kyra/kyra_v1.h"
-#include "kyra/gui.h"
+#include "kyra/gui_v1.h"
#include "kyra/wsamovie.h"
#include "kyra/item.h"
@@ -38,7 +38,7 @@ struct FrameControl {
uint16 delay;
};
-struct ItemAnimData_v2 {
+struct ItemAnimDefinition {
Item itemIndex;
uint8 numFrames;
const FrameControl *frames;
@@ -46,7 +46,7 @@ struct ItemAnimData_v2 {
struct ActiveItemAnim {
uint16 currentFrame;
- uint32 nextFrame;
+ uint32 nextFrameTime;
};
class Screen_v2;
@@ -224,7 +224,7 @@ protected:
// Sequences
EMCData _animationScriptData;
EMCState _animationScriptState;
- Common::Array<const Opcode*> _opcodesAnimation;
+ Common::Array<const Opcode *> _opcodesAnimation;
void runAnimationScript(const char *filename, int allowSkip, int resetChar, int newShapes, int shapeUnload);
diff --git a/engines/kyra/lol.cpp b/engines/kyra/lol.cpp
index 5aba264ceb..38e9d33259 100644
--- a/engines/kyra/lol.cpp
+++ b/engines/kyra/lol.cpp
@@ -34,13 +34,17 @@
#include "common/config-manager.h"
#include "common/system.h"
+#include "common/translation.h"
+
+#include "backends/keymapper/keymapper.h"
namespace Kyra {
-LoLEngine::LoLEngine(OSystem *system, const GameFlags &flags) : KyraEngine_v1(system, flags) {
+const char *const LoLEngine::kKeymapName = "lol";
+
+LoLEngine::LoLEngine(OSystem *system, const GameFlags &flags) : KyraRpgEngine(system, flags) {
_screen = 0;
_gui = 0;
- _txt = 0;
_tim = 0;
_lang = 0;
@@ -92,15 +96,11 @@ LoLEngine::LoLEngine(OSystem *system, const GameFlags &flags) : KyraEngine_v1(sy
memset(_inventory, 0, sizeof(_inventory));
memset(_charStatusFlags, 0, sizeof(_charStatusFlags));
_inventoryCurItem = 0;
- _currentControlMode = 0;
- _specialSceneFlag = 0;
_lastCharInventory = -1;
_emcLastItem = -1;
_itemIconShapes = _itemShapes = _gameShapes = _thrownShapes = _effectShapes = _fireballShapes = _healShapes = _healiShapes = 0;
_levelShpList = _levelDatList = 0;
- _monsterShapes = _monsterPalettes = 0;
- _monsterShapesEx = 0;
_gameShapeMap = 0;
memset(_monsterAnimType, 0, 3);
_healOverlay = 0;
@@ -111,10 +111,8 @@ LoLEngine::LoLEngine(OSystem *system, const GameFlags &flags) : KyraEngine_v1(sy
_charSelection = -1;
_characters = 0;
_spellProperties = 0;
- _updateFlags = 0;
_selectedSpell = 0;
- _updateCharNum = _updatePortraitSpeechAnimDuration = _portraitSpeechAnimMode = _resetPortraitAfterSpeechAnim = _textColorFlag = _needSceneRestore = 0;
- _fadeText = false;
+ _updateCharNum = _portraitSpeechAnimMode = _textColorFlag = 0;
_palUpdateTimer = _updatePortraitNext = 0;
_lampStatusTimer = 0xffffffff;
@@ -123,66 +121,42 @@ LoLEngine::LoLEngine(OSystem *system, const GameFlags &flags) : KyraEngine_v1(sy
_lastButtonShape = 0;
_buttonPressTimer = 0;
_selectedCharacter = 0;
- _suspendScript = _sceneUpdateRequired = false;
+ _suspendScript = false;
_scriptDirection = 0;
- _currentDirection = 0;
- _currentBlock = 0;
- _compassDirection = _compassDirectionIndex = -1;
+ _compassDirectionIndex = -1;
_compassStep = 0;
- memset(_visibleBlockIndex, 0, sizeof(_visibleBlockIndex));
_smoothScrollModeNormal = 1;
- _wllVmpMap = _specialWallTypes = _wllBuffer4 = _wllWallFlags = 0;
- _wllShapeMap = 0;
- _lvlShapeTop = _lvlShapeBottom = _lvlShapeLeftRight = 0;
- _levelBlockProperties = 0;
+ _wllAutomapData = 0;
+ _sceneXoffset = 112;
+ _sceneShpDim = 13;
_monsters = 0;
_monsterProperties = 0;
- _lvlBlockIndex = _lvlShapeIndex = 0;
+ _lvlShapeIndex = 0;
_partyAwake = true;
- _vcnBlocks = 0;
- _vcnShift = 0;
- _vcnExpTable = 0;
- _vmpPtr = 0;
- _vcfBlocks = 0;
_transparencyTable2 = 0;
_transparencyTable1 = 0;
- _levelShapeProperties = 0;
- _levelShapes = 0;
_specialGuiShape = 0;
_specialGuiShapeX = _specialGuiShapeY = _specialGuiShapeMirrorFlag = 0;
- _blockDrawingBuffer = 0;
- _sceneWindowBuffer = 0;
- memset(_doorShapes, 0, sizeof(_doorShapes));
memset(_characterFaceShapes, 0, sizeof(_characterFaceShapes));
_lampEffect = _brightness = _lampOilStatus = 0;
_lampStatusSuspended = false;
- _blockBrightness = 0;
_tempBuffer5120 = 0;
_flyingObjects = 0;
_monsters = 0;
_lastMouseRegion = 0;
- _objectLastDirection = _monsterStepCounter = _monsterStepMode = 0;
+ _objectLastDirection = 0;
_monsterCurBlock = 0;
_seqWindowX1 = _seqWindowY1 = _seqWindowX2 = _seqWindowY2 = _seqTrigger = 0;
_spsWindowX = _spsWindowY = _spsWindowW = _spsWindowH = 0;
- _dscUnk1 = 0;
- _dscShapeIndex = 0;
+ _dscWalls = 0;
_dscOvlMap = 0;
_dscShapeScaleW = 0;
_dscShapeScaleH = 0;
- _dscShapeX = 0;
_dscShapeY = 0;
- _dscTileIndex = 0;
- _dscUnk2 = 0;
- _dscDoorShpIndex = 0;
- _dscDim1 = 0;
- _dscDim2 = 0;
- _dscBlockMap = _dscDoor1 = _dscShapeOvlIndex = 0;
- _dscBlockIndex = 0;
- _dscDimMap = 0;
+ _dscShapeOvlIndex = 0;
_dscDoorMonsterX = _dscDoorMonsterY = 0;
_dscDoor4 = 0;
@@ -193,38 +167,29 @@ LoLEngine::LoLEngine(OSystem *system, const GameFlags &flags) : KyraEngine_v1(sy
_curMusicTheme = -1;
_curMusicFileExt = 0;
_curMusicFileIndex = -1;
- _environmentSfx = _environmentSfxVol = _envSfxDistThreshold = 0;
_envSfxUseQueue = false;
_envSfxNumTracksInQueue = 0;
memset(_envSfxQueuedTracks, 0, sizeof(_envSfxQueuedTracks));
memset(_envSfxQueuedBlocks, 0, sizeof(_envSfxQueuedBlocks));
- _sceneDrawVarDown = _sceneDrawVarRight = _sceneDrawVarLeft = _wllProcessFlag = 0;
_partyPosX = _partyPosY = 0;
_shpDmX = _shpDmY = _dmScaleW = _dmScaleH = 0;
_floatingCursorControl = _currentFloatingCursor = 0;
memset(_activeTim, 0, sizeof(_activeTim));
- memset(_openDoorState, 0, sizeof(_openDoorState));
memset(&_activeSpell, 0, sizeof(_activeSpell));
- _activeVoiceFileTotalTime = 0;
_pageBuffer1 = _pageBuffer2 = 0;
memset(_charStatsTemp, 0, sizeof(_charStatsTemp));
_compassBroken = _drainMagic = 0;
- _dialogueField = false;
_buttonData = 0;
- _activeButtons = 0;
- gui_resetButtonList();
_preserveEvents = false;
_buttonList1 = _buttonList2 = _buttonList3 = _buttonList4 = _buttonList5 = _buttonList6 = _buttonList7 = _buttonList8 = 0;
- memset(_lvlTempData, 0, sizeof(_lvlTempData));
-
_mapOverlay = 0;
_automapShapes = 0;
_defaultLegendData = 0;
@@ -245,6 +210,7 @@ LoLEngine::LoLEngine(OSystem *system, const GameFlags &flags) : KyraEngine_v1(sy
LoLEngine::~LoLEngine() {
setupPrologueData(false);
+ releaseTempData();
delete[] _landsFile;
delete[] _levelLangFile;
@@ -313,12 +279,24 @@ LoLEngine::~LoLEngine() {
delete[] _healiShapes;
}
- for (int i = 0; i < 3; i++)
- releaseMonsterShapes(i);
+ if (_monsterDecorationShapes) {
+ for (int i = 0; i < 3; i++)
+ releaseMonsterShapes(i);
- delete[] _monsterShapes;
- delete[] _monsterPalettes;
- delete[] _monsterShapesEx;
+ delete[] _monsterShapes;
+ _monsterShapes = 0;
+ delete[] _monsterPalettes;
+ _monsterPalettes = 0;
+ delete[] _monsterDecorationShapes;
+ _monsterDecorationShapes = 0;
+ }
+
+ for (int i = 0; i < 6; i++) {
+ delete[] _doorShapes[i];
+ _doorShapes[i] = 0;
+ }
+
+ releaseDecorations();
delete[] _automapShapes;
@@ -334,43 +312,16 @@ LoLEngine::~LoLEngine() {
delete *i;
_timIngameOpcodes.clear();
-
- delete[] _wllVmpMap;
- delete[] _wllShapeMap;
- delete[] _specialWallTypes;
- delete[] _wllBuffer4;
- delete[] _wllWallFlags;
- delete[] _lvlShapeTop;
- delete[] _lvlShapeBottom;
- delete[] _lvlShapeLeftRight;
+ delete[] _wllAutomapData;
delete[] _tempBuffer5120;
delete[] _flyingObjects;
delete[] _monsters;
- delete[] _levelBlockProperties;
delete[] _monsterProperties;
- delete[] _levelFileData;
- delete[] _vcnExpTable;
- delete[] _vcnBlocks;
- delete[] _vcnShift;
- delete[] _vmpPtr;
- delete[] _vcfBlocks;
delete[] _transparencyTable2;
delete[] _transparencyTable1;
- delete[] _levelShapeProperties;
- delete[] _blockDrawingBuffer;
- delete[] _sceneWindowBuffer;
delete[] _lightningProps;
- if (_levelShapes) {
- for (int i = 0; i < 400; i++)
- delete[] _levelShapes[i];
- delete[] _levelShapes;
- }
-
- for (int i = 0; i < 2; i++)
- delete[] _doorShapes[i];
-
delete _lvlShpFileHandle;
if (_ingameSoundList) {
@@ -379,16 +330,6 @@ LoLEngine::~LoLEngine() {
delete[] _ingameSoundList;
}
- for (int i = 0; i < 29; i++) {
- if (_lvlTempData[i]) {
- delete[] _lvlTempData[i]->wallsXorData;
- delete[] _lvlTempData[i]->flags;
- delete[] _lvlTempData[i]->monsters;
- delete[] _lvlTempData[i]->flyingObjects;
- delete _lvlTempData[i];
- }
- }
-
for (int i = 0; i < 3; i++) {
for (int ii = 0; ii < 40; ii++)
delete[] _characterFaceShapes[ii][i];
@@ -425,11 +366,12 @@ Common::Error LoLEngine::init() {
assert(_screen);
_screen->setResolution();
+ _debugger = new Debugger_LoL(this);
+ assert(_debugger);
+
KyraEngine_v1::init();
initStaticResource();
- _envSfxDistThreshold = _sound->getSfxType() == Sound::kAdLib ? 15 : 3;
-
_gui = new GUI_LoL(this);
assert(_gui);
_gui->initStaticData();
@@ -444,8 +386,8 @@ Common::Error LoLEngine::init() {
_pageBuffer2 = new uint8[0xfa00];
memset(_pageBuffer2, 0, 0xfa00);
- _itemsInPlay = new ItemInPlay[400];
- memset(_itemsInPlay, 0, sizeof(ItemInPlay) * 400);
+ _itemsInPlay = new LoLItem[400];
+ memset(_itemsInPlay, 0, sizeof(LoLItem) * 400);
_characters = new LoLCharacter[4];
memset(_characters, 0, sizeof(LoLCharacter) * 4);
@@ -453,69 +395,46 @@ Common::Error LoLEngine::init() {
if (!_sound->init())
error("Couldn't init sound");
- _wllVmpMap = new uint8[80];
- memset(_wllVmpMap, 0, 80);
- _wllShapeMap = new int8[80];
- memset(_wllShapeMap, 0, 80);
- _specialWallTypes = new uint8[80];
- memset(_specialWallTypes, 0, 80);
- _wllBuffer4 = new uint8[80];
- memset(_wllBuffer4, 0, 80);
- _wllWallFlags = new uint8[80];
- memset(_wllWallFlags, 0, 80);
- _lvlShapeTop = new int16[18];
- memset(_lvlShapeTop, 0, 18 * sizeof(int16));
- _lvlShapeBottom = new int16[18];
- memset(_lvlShapeBottom, 0, 18 * sizeof(int16));
- _lvlShapeLeftRight = new int16[36];
- memset(_lvlShapeLeftRight, 0, 36 * sizeof(int16));
- _levelShapeProperties = new LevelShapeProperty[100];
- memset(_levelShapeProperties, 0, 100 * sizeof(LevelShapeProperty));
- _levelShapes = new uint8 *[400];
- memset(_levelShapes, 0, 400 * sizeof(uint8 *));
- _blockDrawingBuffer = new uint16[1320];
- memset(_blockDrawingBuffer, 0, 1320 * sizeof(uint16));
- _sceneWindowBuffer = new uint8[21120];
- memset(_sceneWindowBuffer, 0, 21120);
-
- _levelBlockProperties = new LevelBlockProperty[1025];
- memset(_levelBlockProperties, 0, 1025 * sizeof(LevelBlockProperty));
- _monsters = new MonsterInPlay[30];
- memset(_monsters, 0, 30 * sizeof(MonsterInPlay));
- _monsterProperties = new MonsterProperty[5];
- memset(_monsterProperties, 0, 5 * sizeof(MonsterProperty));
-
- _vcnExpTable = new uint8[128];
- for (int i = 0; i < 128; i++)
- _vcnExpTable[i] = i & 0x0f;
+ KyraRpgEngine::init();
+
+ _wllAutomapData = new uint8[80];
+ memset(_wllAutomapData, 0, 80);
+
+ _monsters = new LoLMonster[30];
+ memset(_monsters, 0, 30 * sizeof(LoLMonster));
+ _monsterProperties = new LoLMonsterProperty[5];
+ memset(_monsterProperties, 0, 5 * sizeof(LoLMonsterProperty));
_tempBuffer5120 = new uint8[5120];
memset(_tempBuffer5120, 0, 5120);
- _flyingObjects = new FlyingObject[8];
- memset(_flyingObjects, 0, 8 * sizeof(FlyingObject));
+ _flyingObjects = new FlyingObject[_numFlyingObjects];
+ _flyingObjectsPtr = _flyingObjects;
+ _flyingObjectStructSize = sizeof(FlyingObject);
+ memset(_flyingObjects, 0, _numFlyingObjects * sizeof(FlyingObject));
memset(_globalScriptVars, 0, sizeof(_globalScriptVars));
- _levelFileData = 0;
_lvlShpFileHandle = 0;
_sceneDrawPage1 = 2;
_sceneDrawPage2 = 6;
- _monsterShapes = new uint8 *[48];
+ _clickedShapeXOffs = 136;
+ _clickedShapeYOffs = 8;
+ _clickedSpecialFlag = 0x40;
+
+ _monsterShapes = new uint8*[48];
memset(_monsterShapes, 0, 48 * sizeof(uint8 *));
- _monsterPalettes = new uint8 *[48];
+ _monsterPalettes = new uint8*[48];
memset(_monsterPalettes, 0, 48 * sizeof(uint8 *));
-
- _monsterShapesEx = new uint8 *[576];
- memset(_monsterShapesEx, 0, 576 * sizeof(uint8 *));
+ _monsterDecorationShapes = new uint8*[576];
+ memset(_monsterDecorationShapes, 0, 576 * sizeof(uint8 *));
memset(&_scriptData, 0, sizeof(EMCData));
- _hasTempDataFlags = 0;
_activeMagicMenu = -1;
- _automapShapes = new const uint8 *[109];
+ _automapShapes = new const uint8*[109];
_mapOverlay = new uint8[256];
memset(_availableSpells, -1, 8);
@@ -538,12 +457,48 @@ Common::Error LoLEngine::init() {
_spellProcs.push_back(new SpellProc(this, 0));
_spellProcs.push_back(new SpellProc(this, &LoLEngine::castGuardian));
- _debugger = new Debugger_LoL(this);
- assert(_debugger);
+#ifdef ENABLE_KEYMAPPER
+ _eventMan->getKeymapper()->pushKeymap(kKeymapName, true);
+#endif
return Common::kNoError;
}
+void LoLEngine::initKeymap() {
+#ifdef ENABLE_KEYMAPPER
+ Common::Keymapper *const mapper = _eventMan->getKeymapper();
+
+ // Do not try to recreate same keymap over again
+ if (mapper->getKeymap(kKeymapName) != 0)
+ return;
+
+ Common::Keymap *const engineKeyMap = new Common::Keymap(kKeymapName);
+
+ const Common::KeyActionEntry keyActionEntries[] = {
+ {Common::KeyState(Common::KEYCODE_F1, Common::ASCII_F1), "AT1", _("Attack 1")},
+ {Common::KeyState(Common::KEYCODE_F2, Common::ASCII_F2), "AT2", _("Attack 2")},
+ {Common::KeyState(Common::KEYCODE_F3, Common::ASCII_F3), "AT3", _("Attack 3")},
+ {Common::KeyState(Common::KEYCODE_UP), "MVF", _("Move Forward")},
+ {Common::KeyState(Common::KEYCODE_DOWN), "MVB", _("Move Back")},
+ {Common::KeyState(Common::KEYCODE_LEFT), "SLL", _("Slide Left")},
+ {Common::KeyState(Common::KEYCODE_RIGHT), "SLR", _("Slide Right")},
+ {Common::KeyState(Common::KEYCODE_HOME), "TL", _("Turn Left")},
+ {Common::KeyState(Common::KEYCODE_PAGEUP), "TR", _("Turn Right")},
+ {Common::KeyState(Common::KEYCODE_r), "RST", _("Rest")},
+ {Common::KeyState(Common::KEYCODE_o), "OPT", _("Options")},
+ {Common::KeyState(Common::KEYCODE_SLASH), "SPL", _("Choose Spell")},
+ {Common::KeyState(), 0, 0}
+ };
+
+ for (const Common::KeyActionEntry *entry = keyActionEntries; entry->id; ++entry) {
+ Common::Action *const act = new Common::Action(engineKeyMap, entry->id, entry->description);
+ act->addKeyEvent(entry->ks);
+ }
+
+ mapper->addGameKeymap(engineKeyMap);
+#endif
+}
+
Common::Error LoLEngine::go() {
int action = -1;
@@ -634,7 +589,7 @@ void LoLEngine::loadItemIconShapes() {
_screen->loadBitmap("ITEMICN.SHP", 3, 3, 0);
const uint8 *shp = _screen->getCPagePtr(3);
_numItemIconShapes = READ_LE_UINT16(shp);
- _itemIconShapes = new uint8 *[_numItemIconShapes];
+ _itemIconShapes = new uint8*[_numItemIconShapes];
for (int i = 0; i < _numItemIconShapes; i++)
_itemIconShapes[i] = _screen->makeShapeCopy(shp, i);
@@ -644,7 +599,7 @@ void LoLEngine::loadItemIconShapes() {
_screen->loadBitmap("GAMESHP.SHP", 3, 3, 0);
shp = _screen->getCPagePtr(3);
_numGameShapes = READ_LE_UINT16(shp);
- _gameShapes = new uint8 *[_numGameShapes];
+ _gameShapes = new uint8*[_numGameShapes];
for (int i = 0; i < _numGameShapes; i++)
_gameShapes[i] = _screen->makeShapeCopy(shp, i);
}
@@ -664,12 +619,6 @@ void LoLEngine::setMouseCursorToItemInHand() {
_screen->setMouseCursor(o, o, getItemIconShapePtr(_itemInHand));
}
-bool LoLEngine::posWithinRect(int mouseX, int mouseY, int x1, int y1, int x2, int y2) {
- if (mouseX < x1 || mouseX > x2 || mouseY < y1 || mouseY > y2)
- return false;
- return true;
-}
-
void LoLEngine::checkFloatingPointerRegions() {
if (!_floatingCursorsEnabled)
return;
@@ -824,46 +773,46 @@ void LoLEngine::startup() {
_screen->loadBitmap("ITEMSHP.SHP", 3, 3, 0);
const uint8 *shp = _screen->getCPagePtr(3);
_numItemShapes = READ_LE_UINT16(shp);
- _itemShapes = new uint8 *[_numItemShapes];
+ _itemShapes = new uint8*[_numItemShapes];
for (int i = 0; i < _numItemShapes; i++)
_itemShapes[i] = _screen->makeShapeCopy(shp, i);
_screen->loadBitmap("THROWN.SHP", 3, 3, 0);
shp = _screen->getCPagePtr(3);
_numThrownShapes = READ_LE_UINT16(shp);
- _thrownShapes = new uint8 *[_numThrownShapes];
+ _thrownShapes = new uint8*[_numThrownShapes];
for (int i = 0; i < _numThrownShapes; i++)
_thrownShapes[i] = _screen->makeShapeCopy(shp, i);
_screen->loadBitmap("ICE.SHP", 3, 3, 0);
shp = _screen->getCPagePtr(3);
_numEffectShapes = READ_LE_UINT16(shp);
- _effectShapes = new uint8 *[_numEffectShapes];
+ _effectShapes = new uint8*[_numEffectShapes];
for (int i = 0; i < _numEffectShapes; i++)
_effectShapes[i] = _screen->makeShapeCopy(shp, i);
_screen->loadBitmap("FIREBALL.SHP", 3, 3, 0);
shp = _screen->getCPagePtr(3);
_numFireballShapes = READ_LE_UINT16(shp);
- _fireballShapes = new uint8 *[_numFireballShapes];
+ _fireballShapes = new uint8*[_numFireballShapes];
for (int i = 0; i < _numFireballShapes; i++)
_fireballShapes[i] = _screen->makeShapeCopy(shp, i);
_screen->loadBitmap("HEAL.SHP", 3, 3, 0);
shp = _screen->getCPagePtr(3);
_numHealShapes = READ_LE_UINT16(shp);
- _healShapes = new uint8 *[_numHealShapes];
+ _healShapes = new uint8*[_numHealShapes];
for (int i = 0; i < _numHealShapes; i++)
_healShapes[i] = _screen->makeShapeCopy(shp, i);
_screen->loadBitmap("HEALI.SHP", 3, 3, 0);
shp = _screen->getCPagePtr(3);
_numHealiShapes = READ_LE_UINT16(shp);
- _healiShapes = new uint8 *[_numHealiShapes];
+ _healiShapes = new uint8*[_numHealiShapes];
for (int i = 0; i < _numHealiShapes; i++)
_healiShapes[i] = _screen->makeShapeCopy(shp, i);
- memset(_itemsInPlay, 0, 400 * sizeof(ItemInPlay));
+ memset(_itemsInPlay, 0, 400 * sizeof(LoLItem));
for (int i = 0; i < 400; i++)
_itemsInPlay[i].shpCurFrame_flg |= 0x8000;
@@ -896,7 +845,7 @@ void LoLEngine::startupNew() {
_availableSpells[0] = 0;
setupScreenDims();
- memset(_globalScriptVars2, 0x100, 8);
+ Common::fill(_globalScriptVars2, ARRAYEND(_globalScriptVars2), 0x100);
static const int selectIds[] = { -9, -1, -8, -5 };
assert(_charSelection >= 0);
@@ -911,12 +860,14 @@ void LoLEngine::startupNew() {
}
void LoLEngine::runLoop() {
+ // Initialize debugger since how it should be fully usable
+ _debugger->initialize();
+
enableSysTimer(2);
- bool _runFlag = true;
_flagsTable[73] |= 0x08;
- while (!shouldQuit() && _runFlag) {
+ while (!shouldQuit()) {
if (_gameToLoad != -1) {
// FIXME: Instead of throwing away the error returned by
// loadGameState, we should use it / augment it.
@@ -993,6 +944,10 @@ void LoLEngine::writeSettings() {
void LoLEngine::readSettings() {
_monsterDifficulty = ConfMan.getInt("monster_difficulty");
+ if (_monsterDifficulty < 0 || _monsterDifficulty > 2) {
+ _monsterDifficulty = CLIP(_monsterDifficulty, 0, 2);
+ warning("LoLEngine: Config file contains invalid difficulty setting.");
+ }
_smoothScrollingEnabled = ConfMan.getBool("smooth_scrolling");
_floatingCursorsEnabled = ConfMan.getBool("floating_cursors");
@@ -1058,7 +1013,7 @@ uint8 *LoLEngine::getTableEntry(uint8 *buffer, uint16 id) {
if (!buffer)
return 0;
- return buffer + READ_LE_UINT16(buffer + (id<<1));
+ return buffer + READ_LE_UINT16(buffer + (id << 1));
}
void LoLEngine::decodeSjis(const char *src, char *dst) {
@@ -1086,7 +1041,7 @@ void LoLEngine::decodeSjis(const char *src, char *dst) {
int LoLEngine::decodeCyrillic(const char *src, char *dst) {
static const uint8 decodeTable1[] = {
- 0x20, 0xAE, 0xA5, 0xA0, 0xE2, 0xAD, 0xA8, 0xE0, 0xE1, 0xAB, 0xA2,
+ 0x20, 0xAE, 0xA5, 0xA0, 0xE2, 0xAD, 0xA8, 0xE0, 0xE1, 0xAB, 0xA2,
0xA4, 0xAC, 0xAA, 0xE3, 0x2E
};
@@ -1117,7 +1072,7 @@ int LoLEngine::decodeCyrillic(const char *src, char *dst) {
assert(cChar < sizeof(decodeTable2));
cChar = decodeTable2[cChar];
} else if (cChar >= 0x70) {
- cChar = *src++;
+ cChar = *src++;
} else if (cChar >= 0x30) {
if (cChar < 0x60)
cChar -= 0x30;
@@ -1133,8 +1088,10 @@ int LoLEngine::decodeCyrillic(const char *src, char *dst) {
}
bool LoLEngine::addCharacter(int id) {
- const uint16 *cdf[] = { _charDefsMan, _charDefsMan, _charDefsMan, _charDefsWoman,
- _charDefsMan, _charDefsMan, _charDefsWoman, _charDefsKieran, _charDefsAkshel };
+ const uint16 *cdf[] = {
+ _charDefsMan, _charDefsMan, _charDefsMan, _charDefsWoman,
+ _charDefsMan, _charDefsMan, _charDefsWoman, _charDefsKieran, _charDefsAkshel
+ };
int numChars = countActiveCharacters();
if (numChars == 4)
@@ -1193,6 +1150,7 @@ void LoLEngine::setCharacterUpdateEvent(int charNum, int updateType, int updateD
l->characterUpdateEvents[i] = updateType;
l->characterUpdateDelay[i] = updateDelay;
_timer->setNextRun(3, _system->getMillis());
+ _timer->resetNextRun();
_timer->enable(3);
break;
}
@@ -1724,44 +1682,6 @@ void LoLEngine::fadeText() {
_fadeText = false;
}
-void LoLEngine::transformRegion(int x1, int y1, int x2, int y2, int w, int h, int srcPage, int dstPage) {
- uint16 *p1 = (uint16 *)_tempBuffer5120;
- uint16 *p2 = (uint16 *)(_tempBuffer5120 + 640);
-
- for (int i = 0; i < w; i++)
- p1[i] = i;
-
- for (int i = 0; i < h; i++)
- p2[i] = i;
-
- for (int i = 0; i < w; i++)
- SWAP(p1[_rnd.getRandomNumberRng(0, w - 1)], p1[i]);
-
- for (int i = 0; i < h; i++)
- SWAP(p2[_rnd.getRandomNumberRng(0, h - 1)], p2[i]);
-
- for (int i = 0; i < h; i++) {
- int i2 = i;
-
- for (int ii = 0; ii < w; ii++) {
- int dx1 = x1 + p1[ii];
- int dy1 = y1 + p2[i2];
- int dx2 = x2 + p1[ii];
- int dy2 = y2 + p2[i2];
-
- if (++i2 == h)
- i2 = 0;
-
- _screen->setPagePixel(dstPage, dx2, dy2, _screen->getPagePixel(srcPage, dx1, dy1));
- }
-
- if (!dstPage && (i & 5) == 5) {
- updateInput();
- _screen->updateScreen();
- }
- }
-}
-
void LoLEngine::setPaletteBrightness(const Palette &srcPal, int brightness, int modifier) {
generateBrightnessPalette(srcPal, _screen->getPalette(1), brightness, modifier);
_screen->fadePalette(_screen->getPalette(1), 5, 0);
@@ -1885,7 +1805,7 @@ int LoLEngine::characterSays(int track, int charId, bool redraw) {
charId = 0;
} else {
int i = 0;
- for (;i < 4; i++) {
+ for (; i < 4; i++) {
if (charId != _characters[i].id || !(_characters[i].flags & 1))
continue;
charId = i;
@@ -1922,8 +1842,7 @@ int LoLEngine::playCharacterScriptChat(int charId, int mode, int restorePortrait
stopPortraitSpeechAnim();
if (charId < 0) {
- charId = ch = (_rnd.getRandomNumber(0x7fff) * countActiveCharacters()) / 0x8000;
- ch = _rnd.getRandomNumber(countActiveCharacters() - 1);
+ charId = ch = _rnd.getRandomNumber(countActiveCharacters() - 1);
} else if (charId > 0) {
int i = 0;
@@ -1981,7 +1900,46 @@ int LoLEngine::playCharacterScriptChat(int charId, int mode, int restorePortrait
return 1;
}
-void LoLEngine::giveItemToMonster(MonsterInPlay *monster, Item item) {
+void LoLEngine::setupDialogueButtons(int numStr, const char *s1, const char *s2, const char *s3) {
+ screen()->setScreenDim(5);
+
+ if (numStr == 1 && speechEnabled()) {
+ _dialogueNumButtons = 0;
+ _dialogueButtonString[0] = _dialogueButtonString[1] = _dialogueButtonString[2] = 0;
+ } else {
+ _dialogueNumButtons = numStr;
+ _dialogueButtonString[0] = s1;
+ _dialogueButtonString[1] = s2;
+ _dialogueButtonString[2] = s3;
+ _dialogueHighlightedButton = 0;
+
+ const ScreenDim *d = screen()->getScreenDim(5);
+
+ static uint16 posX[3];
+ static uint8 posY[3];
+
+ memset(posY, d->sy + d->h - 9, 3);
+
+ _dialogueButtonPosX = posX;
+ _dialogueButtonPosY = posY;
+
+ if (numStr == 1) {
+ posX[0] = posX[1] = posX[2] = d->sx + d->w - (_dialogueButtonWidth + 3);
+ } else {
+ int xOffs = d->w / numStr;
+ posX[0] = d->sx + (xOffs >> 1) - 37;
+ posX[1] = posX[0] + xOffs;
+ posX[2] = posX[1] + xOffs;
+ }
+
+ drawDialogueButtons();
+ }
+
+ if (!shouldQuit())
+ removeInputTop();
+}
+
+void LoLEngine::giveItemToMonster(LoLMonster *monster, Item item) {
uint16 *c = &monster->assignedItems;
while (*c)
c = &_itemsInPlay[*c].nextAssignedObject;
@@ -2014,19 +1972,8 @@ void LoLEngine::delay(uint32 millis, bool doUpdate, bool) {
}
}
-int LoLEngine::rollDice(int times, int pips) {
- if (times <= 0 || pips <= 0)
- return 0;
-
- int res = 0;
- while (times--)
- res += _rnd.getRandomNumberRng(1, pips);
-
- return res;
-}
-
-void LoLEngine::updateEnvironmentalSfx(int soundId) {
- snd_processEnvironmentalSoundEffect(soundId, _currentBlock);
+const KyraRpgGUISettings *LoLEngine::guiSettings() {
+ return &_guiSettings;
}
// spells
@@ -2259,7 +2206,7 @@ int LoLEngine::processMagicHeal(int charNum, int spellLevel) {
int ch = 0;
int n = 4;
- if (charNum != -1){
+ if (charNum != -1) {
ch = charNum;
n = charNum + 1;
}
@@ -2443,7 +2390,7 @@ int LoLEngine::processMagicIce(int charNum, int spellLevel) {
int might = rollDice(iceDamageMin[spellLevel], iceDamageMax[spellLevel]) + iceDamageAdd[spellLevel];
int dmg = calcInflictableDamagePerItem(charNum, 0, might, 3, 2);
- MonsterInPlay *m = &_monsters[o & 0x7fff];
+ LoLMonster *m = &_monsters[o & 0x7fff];
if (m->hitPoints <= dmg) {
increaseExperience(charNum, 2, m->hitPoints);
o = m->nextAssignedObject;
@@ -2522,7 +2469,7 @@ int LoLEngine::processMagicFireball(int charNum, int spellLevel) {
while (o & 0x8000) {
static const uint8 fireballDamage[] = { 20, 40, 80, 100 };
int dmg = calcInflictableDamagePerItem(charNum, o, fireballDamage[spellLevel], 4, 1);
- MonsterInPlay *m = &_monsters[o & 0x7fff];
+ LoLMonster *m = &_monsters[o & 0x7fff];
o = m->nextAssignedObject;
_envSfxUseQueue = true;
inflictDamage(m->id | 0x8000, dmg, charNum, 2, 4);
@@ -2687,7 +2634,7 @@ int LoLEngine::processMagicHandOfFate(int spellLevel) {
uint16 o = _levelBlockProperties[b1].assignedObjects;
while (o & 0x8000) {
uint16 o2 = o;
- MonsterInPlay *m = &_monsters[o & 0x7fff];
+ LoLMonster *m = &_monsters[o & 0x7fff];
o = findObject(o)->nextAssignedObject;
int nX = 0;
int nY = 0;
@@ -2920,7 +2867,7 @@ int LoLEngine::processMagicVaelansCube() {
uint16 a = sp1[i * 3 + 1] + 16;
tmpPal2[i * 3 + 1] = (a > 58) ? 58 : a;
tmpPal2[i * 3] = sp1[i * 3];
- a = sp1[i * 3 + 2] + 16;
+ a = sp1[i * 3 + 2] + 16;
tmpPal2[i * 3 + 2] = (a > 63) ? 63 : a;
}
} else {
@@ -2928,7 +2875,7 @@ int LoLEngine::processMagicVaelansCube() {
uint16 a = sp1[i * 3] + 16;
tmpPal2[i * 3] = (a > 60) ? 60 : a;
tmpPal2[i * 3 + 1] = sp1[i * 3 + 1];
- a = sp1[i * 3 + 2] + 19;
+ a = sp1[i * 3 + 2] + 19;
tmpPal2[i * 3 + 2] = (a > 60) ? 60 : a;
}
}
@@ -2956,7 +2903,7 @@ int LoLEngine::processMagicVaelansCube() {
uint16 o = _levelBlockProperties[bl].assignedObjects;
while (o & 0x8000) {
- MonsterInPlay *m = &_monsters[o & 0x7fff];
+ LoLMonster *m = &_monsters[o & 0x7fff];
if (m->properties->flags & 0x1000) {
inflictDamage(o, 100, 0xffff, 0, 0x80);
v = 1;
@@ -3436,7 +3383,7 @@ int LoLEngine::calcInflictableDamage(int16 attacker, int16 target, int hitType)
}
int LoLEngine::inflictDamage(uint16 target, int damage, uint16 attacker, int skill, int flags) {
- MonsterInPlay *m = 0;
+ LoLMonster *m = 0;
LoLCharacter *c = 0;
if (target & 0x8000) {
@@ -3653,7 +3600,7 @@ void LoLEngine::checkForPartyDeath() {
}
}
-void LoLEngine::applyMonsterAttackSkill(MonsterInPlay *monster, int16 target, int16 damage) {
+void LoLEngine::applyMonsterAttackSkill(LoLMonster *monster, int16 target, int16 damage) {
if (rollDice(1, 100) > monster->properties->attackSkillChance)
return;
@@ -3723,7 +3670,7 @@ void LoLEngine::applyMonsterAttackSkill(MonsterInPlay *monster, int16 target, in
}
}
-void LoLEngine::applyMonsterDefenseSkill(MonsterInPlay *monster, int16 attacker, int flags, int skill, int damage) {
+void LoLEngine::applyMonsterDefenseSkill(LoLMonster *monster, int16 attacker, int flags, int skill, int damage) {
if (rollDice(1, 100) > monster->properties->defenseSkillChance)
return;
@@ -3982,7 +3929,7 @@ uint16 LoLEngine::getNearestMonsterFromCharacterForBlock(uint16 block, int charN
int o = _levelBlockProperties[block].assignedObjects;
while (o & 0x8000) {
- MonsterInPlay *m = &_monsters[o & 0x7fff];
+ LoLMonster *m = &_monsters[o & 0x7fff];
if (m->mode >= 13) {
o = m->nextAssignedObject;
continue;
@@ -4048,7 +3995,7 @@ void LoLEngine::displayAutomap() {
_currentMapLevel = _currentLevel;
uint8 *tmpWll = new uint8[80];
- memcpy(tmpWll, _wllBuffer4, 80);
+ memcpy(tmpWll, _wllAutomapData, 80);
_screen->loadBitmap("parch.cps", 2, 2, &_screen->getPalette(3));
_screen->loadBitmap("autobut.shp", 3, 5, 0);
@@ -4112,7 +4059,7 @@ void LoLEngine::displayAutomap() {
if (f == 0x30) {
for (int i = 0; i < 1024; i++)
- _levelBlockProperties[i].flags |= 7;
+ _levelBlockProperties[i].flags |= 7;
_mapUpdateNeeded = true;
} else if (f == _keyMap[Common::KEYCODE_ESCAPE]) {
exitAutomap = true;
@@ -4129,7 +4076,7 @@ void LoLEngine::displayAutomap() {
_screen->fadeToBlack(10);
loadLevelWallData(_currentLevel, false);
- memcpy(_wllBuffer4, tmpWll, 80);
+ memcpy(_wllAutomapData, tmpWll, 80);
delete[] tmpWll;
restoreBlockTempData(_currentLevel);
addLevelItems();
@@ -4170,7 +4117,7 @@ bool LoLEngine::updateAutoMapIntern(uint16 block, uint16 x, uint16 y, int16 xOff
uint16 b = block + blockPosTable[6 + xOffs];
if (fx != -1) {
- if (_wllBuffer4[_levelBlockProperties[b].walls[fx]] & 0xc0)
+ if (_wllAutomapData[_levelBlockProperties[b].walls[fx]] & 0xc0)
return false;
}
@@ -4178,13 +4125,13 @@ bool LoLEngine::updateAutoMapIntern(uint16 block, uint16 x, uint16 y, int16 xOff
b = block + blockPosTable[9 + yOffs];
if (fy != -1) {
- if (_wllBuffer4[_levelBlockProperties[b].walls[fy]] & 0xc0)
+ if (_wllAutomapData[_levelBlockProperties[b].walls[fy]] & 0xc0)
return false;
}
b = block + blockPosTable[6 + xOffs] + blockPosTable[9 + yOffs];
- if ((fx != -1) && (fy != -1) && (_wllBuffer4[_levelBlockProperties[b].walls[fx]] & 0xc0) && (_wllBuffer4[_levelBlockProperties[b].walls[fy]] & 0xc0))
+ if ((fx != -1) && (fy != -1) && (_wllAutomapData[_levelBlockProperties[b].walls[fx]] & 0xc0) && (_wllAutomapData[_levelBlockProperties[b].walls[fy]] & 0xc0))
return false;
_levelBlockProperties[b].flags |= 7;
@@ -4247,7 +4194,7 @@ void LoLEngine::drawMapPage(int pageNum) {
for (; bl < 1024; bl++) {
uint8 *w = _levelBlockProperties[bl].walls;
- if ((_levelBlockProperties[bl].flags & 7) == 7 && (!(_wllBuffer4[w[0]] & 0xc0)) && (!(_wllBuffer4[w[2]] & 0xc0)) && (!(_wllBuffer4[w[1]] & 0xc0))&& (!(_wllBuffer4[w[3]] & 0xc0))) {
+ if ((_levelBlockProperties[bl].flags & 7) == 7 && (!(_wllAutomapData[w[0]] & 0xc0)) && (!(_wllAutomapData[w[2]] & 0xc0)) && (!(_wllAutomapData[w[1]] & 0xc0)) && (!(_wllAutomapData[w[3]] & 0xc0))) {
uint16 b0 = calcNewBlockPosition(bl, 0);
uint16 b2 = calcNewBlockPosition(bl, 2);
uint16 b1 = calcNewBlockPosition(bl, 1);
@@ -4264,25 +4211,25 @@ void LoLEngine::drawMapPage(int pageNum) {
// draw north wall
drawMapBlockWall(b3, w31, sx, sy, 3);
drawMapShape(w31, sx, sy, 3);
- if (_wllBuffer4[w31] & 0xc0)
+ if (_wllAutomapData[w31] & 0xc0)
_screen->copyBlockAndApplyOverlay(_screen->_curPage, sx, sy, _screen->_curPage, sx, sy, 1, 6, 0, _mapOverlay);
// draw west wall
drawMapBlockWall(b1, w13, sx, sy, 1);
drawMapShape(w13, sx, sy, 1);
- if (_wllBuffer4[w13] & 0xc0)
+ if (_wllAutomapData[w13] & 0xc0)
_screen->copyBlockAndApplyOverlay(_screen->_curPage, sx + 6, sy, _screen->_curPage, sx + 6, sy, 1, 6, 0, _mapOverlay);
// draw east wall
drawMapBlockWall(b0, w02, sx, sy, 0);
drawMapShape(w02, sx, sy, 0);
- if (_wllBuffer4[w02] & 0xc0)
+ if (_wllAutomapData[w02] & 0xc0)
_screen->copyBlockAndApplyOverlay(_screen->_curPage, sx, sy, _screen->_curPage, sx, sy, 7, 1, 0, _mapOverlay);
//draw south wall
drawMapBlockWall(b2, w20, sx, sy, 2);
drawMapShape(w20, sx, sy, 2);
- if (_wllBuffer4[w20] & 0xc0)
+ if (_wllAutomapData[w20] & 0xc0)
_screen->copyBlockAndApplyOverlay(_screen->_curPage, sx, sy + 5, _screen->_curPage, sx, sy + 5, 7, 1, 0, _mapOverlay);
}
@@ -4449,7 +4396,7 @@ void LoLEngine::redrawMapCursor() {
}
void LoLEngine::drawMapBlockWall(uint16 block, uint8 wall, int x, int y, int direction) {
- if (((1 << direction) & _levelBlockProperties[block].flags) || ((_wllBuffer4[wall] & 0x1f) != 13))
+ if (((1 << direction) & _levelBlockProperties[block].flags) || ((_wllAutomapData[wall] & 0x1f) != 13))
return;
int cp = _screen->_curPage;
@@ -4459,7 +4406,7 @@ void LoLEngine::drawMapBlockWall(uint16 block, uint8 wall, int x, int y, int dir
}
void LoLEngine::drawMapShape(uint8 wall, int x, int y, int direction) {
- int l = _wllBuffer4[wall] & 0x1f;
+ int l = _wllAutomapData[wall] & 0x1f;
if (l == 0x1f)
return;
@@ -4552,48 +4499,7 @@ void LoLEngine::printMapExitButtonText() {
_screen->setCurPage(cp);
}
-void LoLEngine::generateTempData() {
- int l = _currentLevel - 1;
- if (_lvlTempData[l]) {
- delete[] _lvlTempData[l]->wallsXorData;
- delete[] _lvlTempData[l]->flags;
- delete[] _lvlTempData[l]->monsters;
- delete[] _lvlTempData[l]->flyingObjects;
- delete _lvlTempData[l];
- }
-
- _lvlTempData[l] = new LevelTempData;
-
- _lvlTempData[l]->wallsXorData = new uint8[4096];
- _lvlTempData[l]->flags = new uint8[1024];
- _lvlTempData[l]->monsters = new MonsterInPlay[30];
- _lvlTempData[l]->flyingObjects = new FlyingObject[8];
-
- Common::String filename = Common::String::format("LEVEL%d.CMZ", _currentLevel);
-
- _screen->loadBitmap(filename.c_str(), 15, 15, 0);
- const uint8 *p = _screen->getCPagePtr(14);
- uint16 len = READ_LE_UINT16(p + 4);
- p += 6;
- memset(_lvlTempData[l]->wallsXorData, 0, 4096);
- memset(_lvlTempData[l]->flags, 0, 1024);
- uint8 *d = _lvlTempData[l]->wallsXorData;
- uint8 *df = _lvlTempData[l]->flags;
-
- for (int i = 0; i < 1024; i++) {
- for (int ii = 0; ii < 4; ii++)
- *d++ = p[i * len + ii] ^ _levelBlockProperties[i].walls[ii];
- *df++ = _levelBlockProperties[i].flags;
- }
-
- memcpy(_lvlTempData[l]->monsters, _monsters, sizeof(MonsterInPlay) * 30);
- memcpy(_lvlTempData[l]->flyingObjects, _flyingObjects, sizeof(FlyingObject) * 8);
-
- _lvlTempData[l]->monsterDifficulty =_monsterDifficulty;
-
- _hasTempDataFlags |= (1 << l);
-}
} // End of namespace Kyra
diff --git a/engines/kyra/lol.h b/engines/kyra/lol.h
index 164f030a1d..dbd461267f 100644
--- a/engines/kyra/lol.h
+++ b/engines/kyra/lol.h
@@ -25,7 +25,7 @@
#ifndef KYRA_LOL_H
#define KYRA_LOL_H
-#include "kyra/kyra_v1.h"
+#include "kyra/kyra_rpg.h"
#include "kyra/script_tim.h"
#include "kyra/script.h"
#include "kyra/gui_lol.h"
@@ -86,15 +86,7 @@ struct SpellProperty {
uint16 flags;
};
-struct LevelBlockProperty {
- uint8 walls[4];
- uint16 assignedObjects;
- uint16 drawObjects;
- uint8 direction;
- uint8 flags;
-};
-
-struct MonsterProperty {
+struct LoLMonsterProperty {
uint8 shapeIndex;
uint8 maxWidth;
uint16 fightingStats[9];
@@ -116,21 +108,24 @@ struct MonsterProperty {
uint8 sounds[3];
};
-struct MonsterInPlay {
+struct LoLObject {
uint16 nextAssignedObject;
uint16 nextDrawObject;
uint8 flyingHeight;
uint16 block;
uint16 x;
uint16 y;
+};
+
+struct LoLMonster : public LoLObject {
+ uint8 destDirection;
int8 shiftStep;
uint16 destX;
uint16 destY;
- uint8 destDirection;
+
int8 hitOffsX;
int8 hitOffsY;
uint8 currentSubFrame;
-
uint8 mode;
int8 fightCurTick;
uint8 id;
@@ -138,11 +133,10 @@ struct MonsterInPlay {
uint8 facing;
uint16 flags;
uint16 damageReceived;
- //uint8 field_1C;
int16 hitPoints;
uint8 speedTick;
uint8 type;
- MonsterProperty *properties;
+ LoLMonsterProperty *properties;
uint8 numDistAttacks;
uint8 curDistWeapon;
int8 distAttackTick;
@@ -150,20 +144,10 @@ struct MonsterInPlay {
uint8 equipmentShapes[4];
};
-struct ItemInPlay {
- uint16 nextAssignedObject;
- uint16 nextDrawObject;
- uint8 flyingHeight;
- uint16 block;
- uint16 x;
- uint16 y;
+struct LoLItem : public LoLObject {
int8 level;
uint16 itemPropertyIndex;
uint16 shpCurFrame_flg;
- uint8 destDirection;
- int8 hitOffsX;
- int8 hitOffsY;
- uint8 currentSubFrame;
};
struct ItemProperty {
@@ -179,15 +163,6 @@ struct ItemProperty {
uint8 unkD;
};
-struct LevelShapeProperty {
- uint16 shapeIndex[10];
- uint8 scaleFlag[10];
- int16 shapeX[10];
- int16 shapeY[10];
- int8 next;
- uint8 flags;
-};
-
struct CompassDef {
uint8 shapeIndex;
int8 x;
@@ -195,7 +170,7 @@ struct CompassDef {
uint8 flags;
};
-struct ButtonDef {
+struct LoLButtonDef {
uint16 buttonflags;
uint16 keyCode;
uint16 keyCode2;
@@ -207,12 +182,6 @@ struct ButtonDef {
uint16 screenDim;
};
-struct OpenDoorState {
- uint16 block;
- int8 wall;
- int8 state;
-};
-
struct ActiveSpell {
uint8 spell;
const SpellProperty *p;
@@ -245,14 +214,6 @@ struct FlyingObjectShape {
uint8 flipFlags;
};
-struct LevelTempData {
- uint8 *wallsXorData;
- uint8 *flags;
- MonsterInPlay *monsters;
- FlyingObject *flyingObjects;
- uint8 monsterDifficulty;
-};
-
struct MapLegendData {
uint8 shapeIndex;
bool enable;
@@ -296,7 +257,7 @@ struct MistOfDoomAnimData {
uint8 sound;
};
-class LoLEngine : public KyraEngine_v1 {
+class LoLEngine : public KyraRpgEngine {
friend class GUI_LoL;
friend class TextDisplayer_LoL;
friend class TIMInterpreter_LoL;
@@ -305,7 +266,9 @@ friend class Debugger_LoL;
friend class HistoryPlayer;
public:
LoLEngine(OSystem *system, const GameFlags &flags);
- ~LoLEngine();
+ virtual ~LoLEngine();
+
+ virtual void initKeymap();
Screen *screen();
GUI *gui() const;
@@ -333,6 +296,8 @@ private:
void writeSettings();
void readSettings();
+ static const char *const kKeymapName;
+
const char *const *_pakFileList;
int _pakFileListSize;
@@ -344,13 +309,11 @@ private:
// main loop
void runLoop();
void update();
- void updateEnvironmentalSfx(int soundId);
// mouse
void setMouseCursorToIcon(int icon);
void setMouseCursorToItemInHand();
uint8 *getItemIconShapePtr(int index);
- bool posWithinRect(int mouseX, int mouseY, int x1, int y1, int x2, int y2);
void checkFloatingPointerRegions();
int _floatingCursorControl;
@@ -439,11 +402,7 @@ private:
// timers
void setupTimers();
- void enableTimer(int id);
- void enableSysTimer(int sysTimer);
- void disableSysTimer(int sysTimer);
- void timerProcessDoors(int timerNum);
void timerProcessMonsters(int timerNum);
void timerSpecialCharacterUpdate(int timerNum);
void timerProcessFlyingObjects(int timerNum);
@@ -453,6 +412,9 @@ private:
void timerUpdateLampState(int timerNum);
void timerFadeMessageText(int timerNum);
+ uint8 getClock2Timer(int index) { return index < _numClock2Timers ? _clock2Timers[index] : 0; }
+ uint8 getNumClock2Timers() { return _numClock2Timers; }
+
static const uint8 _clock2Timers[];
static const uint8 _numClock2Timers;
@@ -466,7 +428,7 @@ private:
int snd_updateCharacterSpeech();
void snd_stopSpeech(bool setFlag);
void snd_playSoundEffect(int track, int volume);
- void snd_processEnvironmentalSoundEffect(int soundId, int block);
+ bool snd_processEnvironmentalSoundEffect(int soundId, int block);
void snd_queueEnvironmentalSoundEffect(int soundId, int block);
void snd_playQueuedEffects();
void snd_loadSoundFile(int track);
@@ -475,14 +437,10 @@ private:
int _lastSpeechId;
int _lastSpeaker;
- uint32 _activeVoiceFileTotalTime;
int _lastSfxTrack;
int _lastMusicTrack;
int _curMusicFileIndex;
char _curMusicFileExt;
- int _environmentSfx;
- int _environmentSfxVol;
- int _envSfxDistThreshold;
bool _envSfxUseQueue;
int _envSfxNumTracksInQueue;
uint16 _envSfxQueuedTracks[10];
@@ -498,9 +456,7 @@ private:
int _ingameSoundListSize;
const uint8 *_musicTrackMap;
- int _musicTrackMapSize;
const uint16 *_ingameSoundIndex;
- int _ingameSoundIndexSize;
const uint8 *_ingameGMSoundIndex;
int _ingameGMSoundIndexSize;
const uint8 *_ingameMT32SoundIndex;
@@ -515,7 +471,6 @@ private:
void gui_drawScene(int pageNum);
void gui_drawAllCharPortraitsWithStats();
void gui_drawCharPortraitWithStats(int charNum);
- void gui_drawBox(int x, int y, int w, int h, int frameColor1, int frameColor2, int fillColor);
void gui_drawCharFaceShape(int charNum, int x, int y, int pageNum);
void gui_highlightPortraitFrame(int charNum);
void gui_drawLiveMagicBar(int x, int y, int curPoints, int unk, int maxPoints, int w, int h, int col1, int col2, int flag);
@@ -530,7 +485,6 @@ private:
void gui_printCharacterStats(int index, int redraw, int value);
void gui_changeCharacterStats(int charNum);
void gui_drawCharInventoryItem(int itemIndex);
- void gui_drawBarGraph(int x, int y, int w, int h, int32 curVal, int32 maxVal, int col1, int col2);
int gui_enableControls();
int gui_disableControls(int controlMode);
@@ -544,37 +498,27 @@ private:
int _lastButtonShape;
uint32 _buttonPressTimer;
int _selectedCharacter;
- int _compassDirection;
int _compassStep;
int _compassDirectionIndex;
uint32 _compassTimer;
int _charInventoryUnk;
const CompassDef *_compassDefs;
- int _compassDefsSize;
void gui_updateInput();
void gui_triggerEvent(int eventType);
- void removeInputTop();
void gui_enableDefaultPlayfieldButtons();
void gui_enableSequenceButtons(int x, int y, int w, int h, int enableFlags);
void gui_specialSceneRestoreButtons();
void gui_enableCharInventoryButtons(int charNum);
- void gui_resetButtonList();
- void gui_initButtonsFromList(const int16 *list);
void gui_setFaceFramesControlButtons(int index, int xOffs);
void gui_initCharInventorySpecialButtons(int charNum);
void gui_initMagicScrollButtons();
void gui_initMagicSubmenu(int charNum);
void gui_initButton(int index, int x = -1, int y = -1, int val = -1);
- void gui_notifyButtonListChanged();
- Common::Array<Button::Callback> _buttonCallbacks;
- Button *_activeButtons;
- Button _activeButtonData[70];
- ButtonDef _sceneWindowButton;
- bool _preserveEvents;
+ LoLButtonDef _sceneWindowButton;
int clickedUpArrow(Button *button);
int clickedDownArrow(Button *button);
@@ -609,45 +553,33 @@ private:
int clickedLamp(Button *button);
int clickedStatusIcon(Button *button);
- const ButtonDef *_buttonData;
- int _buttonDataSize;
+ const LoLButtonDef *_buttonData;
const int16 *_buttonList1;
- int _buttonList1Size;
const int16 *_buttonList2;
- int _buttonList2Size;
const int16 *_buttonList3;
- int _buttonList3Size;
const int16 *_buttonList4;
- int _buttonList4Size;
const int16 *_buttonList5;
- int _buttonList5Size;
const int16 *_buttonList6;
- int _buttonList6Size;
const int16 *_buttonList7;
- int _buttonList7Size;
const int16 *_buttonList8;
- int _buttonList8Size;
// text
int characterSays(int track, int charId, bool redraw);
int playCharacterScriptChat(int charId, int mode, int restorePortrait, char *str, EMCState *script, const uint16 *paramList, int16 paramIndex);
+ void setupDialogueButtons(int numStr, const char *s1, const char *s2, const char *s3);
TextDisplayer_LoL *_txt;
+ TextDisplayer_rpg *txt() { return _txt; }
// emc scripts
void runInitScript(const char *filename, int optionalFunc);
void runInfScript(const char *filename);
void runLevelScript(int block, int flags);
void runLevelScriptCustom(int block, int flags, int charNum, int item, int reg3, int reg4);
- bool checkSceneUpdateNeed(int func);
EMCData _scriptData;
bool _suspendScript;
uint16 _scriptDirection;
- uint16 _currentDirection;
- uint16 _currentBlock;
- bool _sceneUpdateRequired;
- int16 _visibleBlockIndex[18];
int16 _globalScriptVars[24];
// emc opcode
@@ -698,7 +630,7 @@ private:
int olol_checkEquippedItemScriptFlags(EMCState *script);
int olol_setDoorState(EMCState *script);
int olol_updateBlockAnimations(EMCState *script);
- int olol_mapShapeToBlock(EMCState *script);
+ int olol_assignLevelDecorationShape(EMCState *script);
int olol_resetBlockShapeAssignment(EMCState *script);
int olol_copyRegion(EMCState *script);
int olol_initMonster(EMCState *script);
@@ -712,7 +644,7 @@ private:
int olol_battleHitSkillTest(EMCState *script);
int olol_inflictDamage(EMCState *script);
int olol_moveMonster(EMCState *script);
- int olol_dialogueBox(EMCState *script);
+ int olol_setupDialogueButtons(EMCState *script);
int olol_giveTakeMoney(EMCState *script);
int olol_checkMoney(EMCState *script);
int olol_setScriptTimer(EMCState *script);
@@ -759,7 +691,7 @@ private:
int olol_distanceAttack(EMCState *script);
int olol_removeCharacterEffects(EMCState *script);
int olol_checkInventoryFull(EMCState *script);
- int olol_objectLeavesLevel(EMCState *script);
+ int olol_moveBlockObjects(EMCState *script);
int olol_addSpellToScroll(EMCState *script);
int olol_playDialogueText(EMCState *script);
int olol_playDialogueTalkText(EMCState *script);
@@ -788,7 +720,7 @@ private:
int olol_assignCustomSfx(EMCState *script);
int olol_findAssignedMonster(EMCState *script);
int olol_checkBlockForMonster(EMCState *script);
- int olol_transformRegion(EMCState *script);
+ int olol_crossFadeRegion(EMCState *script);
int olol_calcCoordinatesAddDirectionOffset(EMCState *script);
int olol_resetPortraitsAndDisableSysTimer(EMCState *script);
int olol_enableSysTimer(EMCState *script);
@@ -816,7 +748,7 @@ private:
int olol_shakeScene(EMCState *script);
int olol_gasExplosion(EMCState *script);
int olol_calcNewBlockPosition(EMCState *script);
- int olol_fadeScene(EMCState *script);
+ int olol_crossFadeScene(EMCState *script);
int olol_updateDrawPage2(EMCState *script);
int olol_setMouseCursor(EMCState *script);
int olol_characterSays(EMCState *script);
@@ -896,7 +828,6 @@ private:
void createTransparencyTables();
void updateSequenceBackgroundAnimations();
- bool _dialogueField;
uint8 **_itemIconShapes;
int _numItemIconShapes;
uint8 **_itemShapes;
@@ -909,7 +840,6 @@ private:
int _numEffectShapes;
const int8 *_gameShapeMap;
- int _gameShapeMapSize;
uint8 *_characterFaceShapes[40][3];
@@ -938,19 +868,13 @@ private:
LoLCharacter *_characters;
uint16 _activeCharsXpos[3];
- int _updateFlags;
- int _updateCharNum;
- int _updatePortraitSpeechAnimDuration;
+
int _portraitSpeechAnimMode;
- int _resetPortraitAfterSpeechAnim;
int _textColorFlag;
- bool _fadeText;
- int _needSceneRestore;
uint32 _palUpdateTimer;
uint32 _updatePortraitNext;
int _loadLevelFlag;
- int _hasTempDataFlags;
int _activeMagicMenu;
uint16 _scriptCharacterCycle;
int _charStatsTemp[5];
@@ -959,15 +883,10 @@ private:
int _charDefaultsSize;
const uint16 *_charDefsMan;
- int _charDefsManSize;
const uint16 *_charDefsWoman;
- int _charDefsWomanSize;
const uint16 *_charDefsKieran;
- int _charDefsKieranSize;
const uint16 *_charDefsAkshel;
- int _charDefsAkshelSize;
const int32 *_expRequirements;
- int _expRequirementsSize;
// lamp
void resetLampStatus();
@@ -979,18 +898,18 @@ private:
int _lampOilStatus;
uint32 _lampStatusTimer;
bool _lampStatusSuspended;
- uint8 _blockBrightness;
// level
void loadLevel(int index);
void addLevelItems();
- void loadLevelWallData(int index, bool mapShapes);
- void assignBlockObject(LevelBlockProperty *l, uint16 item);
- int assignLevelShapes(int index);
- uint8 *getLevelShapes(int index);
- void restoreBlockTempData(int index);
+ void loadLevelWallData(int fileIndex, bool mapShapes);
+ void assignBlockItem(LevelBlockProperty *l, uint16 item);
+ int assignLevelDecorationShapes(int index);
+ uint8 *getLevelDecorationShapes(int index);
+ void releaseDecorations(int first = 0, int num = 400);
void restoreTempDataAdjustMonsterStrength(int index);
void loadBlockProperties(const char *cmzFile);
+ const uint8 *getBlockFileData(int levelIndex);
void loadLevelShpDat(const char *shpFile, const char *datFile, bool flag);
void loadLevelGraphics(const char *file, int specialColor, int weight, int vcnLen, int vmpLen, const char *palFile);
@@ -1002,17 +921,7 @@ private:
void drawScene(int pageNum);
- void generateBlockDrawingBuffer();
- void generateVmpTileData(int16 startBlockX, uint8 startBlockY, uint8 wllVmpIndex, int16 vmpOffset, uint8 numBlocksX, uint8 numBlocksY);
- void generateVmpTileDataFlipped(int16 startBlockX, uint8 startBlockY, uint8 wllVmpIndex, int16 vmpOffset, uint8 numBlocksX, uint8 numBlocksY);
- bool hasWall(int index);
- void assignVisibleBlocks(int block, int direction);
-
- void drawVcnBlocks();
- void drawSceneShapes();
- void setLevelShapesDim(int index, int16 &x1, int16 &x2, int dim);
- void scaleLevelShapesDim(int index, int16 &y1, int16 &y2, int dim);
- void drawLevelModifyScreenDim(int dim, int16 x1, int16 y1, int16 x2, int16 y2);
+ void drawSceneShapes(int start = 0);
void drawDecorations(int index);
void drawBlockEffects(int index, int type);
void drawSpecialGuiShape(int pageNum);
@@ -1029,27 +938,17 @@ private:
void updateCompass();
void moveParty(uint16 direction, int unk1, int unk2, int buttonShape);
- bool checkBlockPassability(uint16 block, uint16 direction);
void notifyBlockNotPassable(int scrollFlag);
+ virtual bool checkBlockPassability(uint16 block, uint16 direction);
- uint16 calcNewBlockPosition(uint16 curBlock, uint16 direction);
uint16 calcBlockIndex(uint16 x, uint16 y);
void calcCoordinates(uint16 &x, uint16 &y, int block, uint16 xOffs, uint16 yOffs);
void calcCoordinatesForSingleCharacter(int charNum, uint16 &x, uint16 &y);
void calcCoordinatesAddDirectionOffset(uint16 &x, uint16 &y, int direction);
- int clickedWallShape(uint16 block, uint16 direction);
- int clickedLeverOn(uint16 block, uint16 direction);
- int clickedLeverOff(uint16 block, uint16 direction);
- int clickedWallOnlyScript(uint16 block);
int clickedDoorSwitch(uint16 block, uint16 direction);
int clickedNiche(uint16 block, uint16 direction);
- bool clickedShape(int shapeIndex);
- void processDoorSwitch(uint16 block, int unk);
- void openCloseDoor(uint16 block, int openClose);
- void completeDoorOperations();
-
void movePartySmoothScrollBlocked(int speed);
void movePartySmoothScrollUp(int speed);
void movePartySmoothScrollDown(int speed);
@@ -1065,79 +964,40 @@ private:
int smoothScrollDrawSpecialGuiShape(int pageNum);
- OpenDoorState _openDoorState[3];
int _blockDoor;
int _smoothScrollModeNormal;
const uint8 *_scrollXTop;
- int _scrollXTopSize;
const uint8 *_scrollYTop;
- int _scrollYTopSize;
const uint8 *_scrollXBottom;
- int _scrollXBottomSize;
const uint8 *_scrollYBottom;
- int _scrollYBottomSize;
int _nextScriptFunc;
- uint8 _currentLevel;
- int _sceneDefaultUpdate;
- int _lvlBlockIndex;
int _lvlShapeIndex;
bool _partyAwake;
- uint8 *_vcnBlocks;
- uint8 *_vcnShift;
- uint8 *_vcnExpTable;
- uint16 *_vmpPtr;
- uint8 *_vcfBlocks;
- uint16 *_blockDrawingBuffer;
- uint8 *_sceneWindowBuffer;
- LevelShapeProperty *_levelShapeProperties;
- uint8 **_levelShapes;
uint8 *_specialGuiShape;
uint16 _specialGuiShapeX;
uint16 _specialGuiShapeY;
uint16 _specialGuiShapeMirrorFlag;
- char _lastBlockDataFile[12];
char _lastOverridePalFile[12];
char *_lastOverridePalFilePtr;
int _lastSpecialColor;
int _lastSpecialColorWeight;
- int _sceneDrawVarDown;
- int _sceneDrawVarRight;
- int _sceneDrawVarLeft;
- int _wllProcessFlag;
-
uint8 *_transparencyTable2;
uint8 *_transparencyTable1;
int _loadSuppFilesFlag;
-
- uint8 *_wllVmpMap;
- int8 *_wllShapeMap;
- uint8 *_specialWallTypes;
- uint8 *_wllBuffer4;
- uint8 *_wllWallFlags;
-
- int16 *_lvlShapeTop;
- int16 *_lvlShapeBottom;
- int16 *_lvlShapeLeftRight;
-
- LevelBlockProperty *_levelBlockProperties;
- LevelBlockProperty *_visibleBlocks[18];
+ uint8 *_wllAutomapData;
uint16 _partyPosX;
uint16 _partyPosY;
Common::SeekableReadStream *_lvlShpFileHandle;
- uint16 _lvlShpNum;
- uint16 _levelFileDataSize;
- LevelShapeProperty *_levelFileData;
- uint8 *_doorShapes[2];
int _shpDmX;
int _shpDmY;
uint16 _dmScaleW;
@@ -1150,55 +1010,27 @@ private:
uint8 *_tempBuffer5120;
const char * const *_levelDatList;
- int _levelDatListSize;
const char * const *_levelShpList;
- int _levelShpListSize;
- const int8 *_dscUnk1;
- int _dscUnk1Size;
- const int8 *_dscShapeIndex;
- int _dscShapeIndexSize;
+ const int8 *_dscWalls;
+
const uint8 *_dscOvlMap;
- int _dscOvlMapSize;
+ const uint8 *_dscShapeOvlIndex;
const uint16 *_dscShapeScaleW;
- int _dscShapeScaleWSize;
const uint16 *_dscShapeScaleH;
- int _dscShapeScaleHSize;
- const int16 *_dscShapeX;
- int _dscShapeXSize;
const int8 *_dscShapeY;
- int _dscShapeYSize;
- const uint8 *_dscTileIndex;
- int _dscTileIndexSize;
- const uint8 *_dscUnk2;
- int _dscUnk2Size;
- const uint8 *_dscDoorShpIndex;
- int _dscDoorShpIndexSize;
- const int8 *_dscDim1;
- int _dscDim1Size;
- const int8 *_dscDim2;
- int _dscDim2Size;
- const uint8 *_dscBlockMap;
- int _dscBlockMapSize;
- const uint8 *_dscDimMap;
- int _dscDimMapSize;
+
const uint16 *_dscDoorMonsterScaleTable;
- int _dscDoorMonsterScaleTableSize;
const uint16 *_dscDoor4;
- int _dscDoor4Size;
- const uint8 *_dscShapeOvlIndex;
- int _dscShapeOvlIndexSize;
- const int8 *_dscBlockIndex;
- int _dscBlockIndexSize;
- const uint8 *_dscDoor1;
- int _dscDoor1Size;
const int16 *_dscDoorMonsterX;
- int _dscDoorMonsterXSize;
const int16 *_dscDoorMonsterY;
- int _dscDoorMonsterYSize;
- int _sceneDrawPage1;
- int _sceneDrawPage2;
+ // objects (item/monster common)
+ LoLObject *findObject(uint16 index);
+ int calcObjectPosition(LoLObject *obj, uint16 direction);
+ void removeAssignedObjectFromBlock(LevelBlockProperty *l, uint16 id);
+ void removeDrawObjectFromBlock(LevelBlockProperty *l, uint16 id);
+ void assignObjectToBlock(uint16 *assignedBlockObjects, uint16 id);
// items
void giveCredits(int credits, int redraw);
@@ -1206,14 +1038,13 @@ private:
Item makeItem(int itemType, int curFrame, int flags);
void placeMoveLevelItem(Item itemIndex, int level, int block, int xOffs, int yOffs, int flyingHeight);
bool addItemToInventory(Item itemIndex);
- bool testUnkItemFlags(Item itemIndex);
+ bool isItemMoveable(Item itemIndex);
void deleteItem(Item itemIndex);
- ItemInPlay *findObject(uint16 index);
void runItemScript(int charNum, Item item, int flags, int next, int reg4);
void setHandItem(Item itemIndex);
bool itemEquipped(int charNum, uint16 itemType);
- void setItemPosition(Item item, uint16 x, uint16 y, int flyingHeight, int b);
+ void setItemPosition(Item item, uint16 x, uint16 y, int flyingHeight, int moveable);
void removeLevelItem(Item item, int block);
bool launchObject(int objectType, Item item, int startX, int startY, int flyingHeight, int direction, int, int attackerId, int c);
void endObjectFlight(FlyingObject *t, int x, int y, int collisionObject);
@@ -1229,14 +1060,13 @@ private:
uint8 _moneyColumnHeight[5];
uint16 _credits;
- ItemInPlay *_itemsInPlay;
+ LoLItem *_itemsInPlay;
ItemProperty *_itemProperties;
Item _itemInHand;
Item _inventory[48];
Item _inventoryCurItem;
- int _currentControlMode;
- int _specialSceneFlag;
+
int _lastCharInventory;
uint16 _charStatusFlags[3];
int _emcLastItem;
@@ -1246,34 +1076,24 @@ private:
EMCData _itemScript;
const uint8 *_charInvIndex;
- int _charInvIndexSize;
const uint8 *_charInvDefs;
- int _charInvDefsSize;
const uint16 *_inventorySlotDesc;
- int _inventorySlotDescSize;
const uint16 *_itemCost;
- int _itemCostSize;
const uint8 *_stashSetupData;
- int _stashSetupDataSize;
const int8 *_sceneItemOffs;
- int _sceneItemOffsSize;
const FlyingObjectShape *_flyingItemShapes;
- int _flyingItemShapesSize;
// monsters
void loadMonsterShapes(const char *file, int monsterIndex, int b);
void releaseMonsterShapes(int monsterIndex);
int deleteMonstersFromBlock(int block);
- void setMonsterMode(MonsterInPlay *monster, int mode);
- bool updateMonsterAdjustBlocks(MonsterInPlay *monster);
- void placeMonster(MonsterInPlay *monster, uint16 x, uint16 y);
+ void setMonsterMode(LoLMonster *monster, int mode);
+ bool updateMonsterAdjustBlocks(LoLMonster *monster);
+ void placeMonster(LoLMonster *monster, uint16 x, uint16 y);
int calcMonsterDirection(uint16 x1, uint16 y1, uint16 x2, uint16 y2);
- void setMonsterDirection(MonsterInPlay *monster, int dir);
- void monsterDropItems(MonsterInPlay *monster);
- void removeAssignedObjectFromBlock(LevelBlockProperty *l, uint16 id);
- void removeDrawObjectFromBlock(LevelBlockProperty *l, uint16 id);
- void assignMonsterToBlock(uint16 *assignedBlockObjects, uint16 id);
- void giveItemToMonster(MonsterInPlay *monster, Item item);
+ void setMonsterDirection(LoLMonster *monster, int dir);
+ void monsterDropItems(LoLMonster *monster);
+ void giveItemToMonster(LoLMonster *monster, Item item);
int checkBlockBeforeObjectPlacement(uint16 x, uint16 y, uint16 objectWidth, uint16 testFlag, uint16 wallFlag);
int checkBlockForWallsAndSufficientSpace(int block, int x, int y, int objectWidth, int testFlag, int wallFlag);
int calcMonsterSkillLevel(int id, int a);
@@ -1284,57 +1104,46 @@ private:
void drawBlockObjects(int blockArrayIndex);
void drawMonster(uint16 id);
- int getMonsterCurFrame(MonsterInPlay *m, uint16 dirFlags);
+ int getMonsterCurFrame(LoLMonster *m, uint16 dirFlags);
void reassignDrawObjects(uint16 direction, uint16 itemIndex, LevelBlockProperty *l, bool flag);
void redrawSceneItem();
- int calcItemMonsterPosition(ItemInPlay *i, uint16 direction);
void calcSpriteRelPosition(uint16 x1, uint16 y1, int &x2, int &y2, uint16 direction);
void drawDoor(uint8 *shape, uint8 *doorPalette, int index, int unk2, int w, int h, int flags);
void drawDoorOrMonsterEquipment(uint8 *shape, uint8 *objectPalette, int x, int y, int flags, const uint8 *brightnessOverlay);
uint8 *drawItemOrMonster(uint8 *shape, uint8 *monsterPalette, int x, int y, int fineX, int fineY, int flags, int tblValue, bool vflip);
int calcDrawingLayerParameters(int srcX, int srcY, int &x2, int &y2, uint16 &w, uint16 &h, uint8 *shape, int vflip);
- void updateMonster(MonsterInPlay *monster);
- void moveMonster(MonsterInPlay *monster);
- void walkMonster(MonsterInPlay *monster);
- bool chasePartyWithDistanceAttacks(MonsterInPlay *monster);
- void chasePartyWithCloseAttacks(MonsterInPlay *monster);
- int walkMonsterCalcNextStep(MonsterInPlay *monster);
- int getMonsterDistance(uint16 block1, uint16 block2);
+ void updateMonster(LoLMonster *monster);
+ void moveMonster(LoLMonster *monster);
+ void walkMonster(LoLMonster *monster);
+ bool chasePartyWithDistanceAttacks(LoLMonster *monster);
+ void chasePartyWithCloseAttacks(LoLMonster *monster);
+ int walkMonsterCalcNextStep(LoLMonster *monster);
int checkForPossibleDistanceAttack(uint16 monsterBlock, int direction, int distance, uint16 curBlock);
- int walkMonsterCheckDest(int x, int y, MonsterInPlay *monster, int unk);
+ int walkMonsterCheckDest(int x, int y, LoLMonster *monster, int unk);
void getNextStepCoords(int16 monsterX, int16 monsterY, int &newX, int &newY, uint16 direction);
- void rearrangeAttackingMonster(MonsterInPlay *monster);
- void moveStrayingMonster(MonsterInPlay *monster);
- void killMonster(MonsterInPlay *monster);
-
- MonsterInPlay *_monsters;
- MonsterProperty *_monsterProperties;
- uint8 **_monsterShapes;
- uint8 **_monsterPalettes;
- uint8 **_monsterShapesEx;
+ void rearrangeAttackingMonster(LoLMonster *monster);
+ void moveStrayingMonster(LoLMonster *monster);
+ void killMonster(LoLMonster *monster);
+
+ LoLMonster *_monsters;
+ LoLMonsterProperty *_monsterProperties;
+ uint8 **_monsterDecorationShapes;
uint8 _monsterAnimType[3];
uint16 _monsterCurBlock;
int _objectLastDirection;
- int _monsterStepCounter;
- int _monsterStepMode;
const uint16 *_monsterModifiers;
- int _monsterModifiersSize;
const int8 *_monsterShiftOffs;
- int _monsterShiftOffsSize;
const uint8 *_monsterDirFlags;
- int _monsterDirFlagsSize;
const uint8 *_monsterScaleX;
- int _monsterScaleXSize;
const uint8 *_monsterScaleY;
- int _monsterScaleYSize;
const uint16 *_monsterScaleWH;
- int _monsterScaleWHSize;
// misc
void delay(uint32 millis, bool doUpdate = false, bool isMainLoop = false);
- int rollDice(int times, int pips);
+
+ const KyraRpgGUISettings *guiSettings();
uint8 _compassBroken;
uint8 _drainMagic;
@@ -1343,6 +1152,8 @@ private:
uint8 *_pageBuffer1;
uint8 *_pageBuffer2;
+ static const KyraRpgGUISettings _guiSettings;
+
// spells
typedef Common::Functor1Mem<ActiveSpell *, int, LoLEngine> SpellProc;
Common::Array<const SpellProc *> _spellProcs;
@@ -1394,7 +1205,7 @@ private:
int8 _availableSpells[8];
int _selectedSpell;
const SpellProperty *_spellProperties;
- int _spellPropertiesSize;
+ //int _spellPropertiesSize;
int _subMenuIndex;
LightningProperty *_lightningProps;
@@ -1416,13 +1227,9 @@ private:
static const MistOfDoomAnimData _mistAnimData[];
const uint8 *_updateSpellBookCoords;
- int _updateSpellBookCoordsSize;
const uint8 *_updateSpellBookAnimData;
- int _updateSpellBookAnimDataSize;
const uint8 *_healShapeFrames;
- int _healShapeFramesSize;
const int16 *_fireBallCoords;
- int _fireBallCoordsSize;
// fight
int battleHitSkillTest(int16 attacker, int16 target, int skill);
@@ -1433,8 +1240,8 @@ private:
int calcInflictableDamagePerItem(int16 attacker, int16 target, uint16 itemMight, int index, int hitType);
void checkForPartyDeath();
- void applyMonsterAttackSkill(MonsterInPlay *monster, int16 target, int16 damage);
- void applyMonsterDefenseSkill(MonsterInPlay *monster, int16 attacker, int flags, int skill, int damage);
+ void applyMonsterAttackSkill(LoLMonster *monster, int16 target, int16 damage);
+ void applyMonsterDefenseSkill(LoLMonster *monster, int16 attacker, int flags, int skill, int damage);
int removeCharacterItem(int charNum, int itemFlags);
int paralyzePoisonCharacter(int charNum, int typeFlag, int immunityFlags, int hitChance, int redraw);
void paralyzePoisonAllCharacters(int typeFlag, int immunityFlags, int hitChance);
@@ -1474,7 +1281,6 @@ private:
uint8 *_mapOverlay;
const uint8 **_automapShapes;
const uint16 *_autoMapStrings;
- int _autoMapStringsSize;
MapLegendData *_defaultLegendData;
uint8 *_mapCursorOverlay;
uint8 _automapTopLeftX;
@@ -1491,10 +1297,12 @@ private:
Common::Error loadGameState(int slot);
Common::Error saveGameStateIntern(int slot, const char *saveName, const Graphics::Surface *thumbnail);
- Graphics::Surface *generateSaveThumbnail() const;
+ void *generateMonsterTempData(LevelTempData *tmp);
+ void restoreBlockTempData(int levelIndex);
+ void restoreMonsterTempData(LevelTempData *tmp);
+ void releaseMonsterTempData(LevelTempData *tmp);
- void generateTempData();
- LevelTempData *_lvlTempData[29];
+ Graphics::Surface *generateSaveThumbnail() const;
};
class HistoryPlayer {
diff --git a/engines/kyra/magic_eob.cpp b/engines/kyra/magic_eob.cpp
new file mode 100644
index 0000000000..985286854b
--- /dev/null
+++ b/engines/kyra/magic_eob.cpp
@@ -0,0 +1,1382 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifdef ENABLE_EOB
+
+#include "kyra/eobcommon.h"
+#include "kyra/resource.h"
+#include "common/system.h"
+
+namespace Kyra {
+
+void EoBCoreEngine::useMagicBookOrSymbol(int charIndex, int type) {
+ EoBCharacter *c = &_characters[charIndex];
+ _openBookSpellLevel = c->slotStatus[3];
+ _openBookSpellSelectedItem = c->slotStatus[2];
+ _openBookSpellListOffset = c->slotStatus[4];
+ _openBookChar = charIndex;
+ _openBookType = type;
+ _openBookSpellList = (type == 1) ? _clericSpellList : _mageSpellList;
+ _openBookAvailableSpells = (type == 1) ? c->clericSpells : c->mageSpells;
+ int8 *tmp = _openBookAvailableSpells + _openBookSpellLevel * 10 + _openBookSpellListOffset + _openBookSpellSelectedItem;
+
+ if (*tmp <= 0) {
+ for (bool loop = true; loop && _openBookSpellSelectedItem < 10;) {
+ tmp = _openBookAvailableSpells + _openBookSpellLevel * 10 + _openBookSpellListOffset + _openBookSpellSelectedItem;
+ if (*tmp > 0) {
+ if (_openBookSpellSelectedItem > 5) {
+ _openBookSpellListOffset = 6;
+ _openBookSpellSelectedItem -= 6;
+ }
+ loop = false;
+ } else {
+ _openBookSpellSelectedItem++;
+ }
+ }
+
+ if (_openBookSpellSelectedItem == 10) {
+ _openBookSpellListOffset = 0;
+ _openBookSpellSelectedItem = 6;
+ }
+ }
+
+ if (!_updateFlags)
+ _screen->copyRegion(64, 121, 0, 0, 112, 56, 0, _useHiResDithering ? 4 : 10, Screen::CR_NO_P_CHECK);
+ _updateFlags = 1;
+ gui_setPlayFieldButtons();
+ gui_drawSpellbook();
+}
+
+void EoBCoreEngine::useMagicScroll(int charIndex, int type, int weaponSlot) {
+ _openBookCharBackup = _openBookChar;
+ _openBookTypeBackup = _openBookType;
+ _castScrollSlot = weaponSlot + 1;
+ _openBookChar = charIndex;
+ _openBookType = type <= _clericSpellOffset ? 0 : 1;
+ castSpell(type, weaponSlot);
+}
+
+void EoBCoreEngine::usePotion(int charIndex, int weaponSlot) {
+ EoBCharacter *c = &_characters[charIndex];
+
+ int val = deleteInventoryItem(charIndex, weaponSlot);
+ snd_playSoundEffect(10);
+
+ if (_flags.gameID == GI_EOB1)
+ val--;
+
+ switch (val) {
+ case 0:
+ sparkEffectDefensive(charIndex);
+ c->strengthCur = 22;
+ c->strengthExtCur = 0;
+ setCharEventTimer(charIndex, 546 * rollDice(1, 4, 4), 7, 1);
+ break;
+
+ case 1:
+ sparkEffectDefensive(charIndex);
+ modifyCharacterHitpoints(charIndex, rollDice(2, 4, 2));
+ break;
+
+ case 2:
+ sparkEffectDefensive(charIndex);
+ modifyCharacterHitpoints(charIndex, rollDice(3, 8, 3));
+ break;
+
+ case 3:
+ statusAttack(charIndex, 2, _potionStrings[0], 0, 1, 8, 1);
+ c->effectFlags &= ~0x2000;
+ if (c->flags & 2)
+ return;
+ break;
+
+ case 4:
+ sparkEffectDefensive(charIndex);
+ c->food = 100;
+ if (_currentControlMode)
+ gui_drawCharPortraitWithStats(charIndex);
+ break;
+
+ case 5:
+ sparkEffectDefensive(charIndex);
+ c->effectFlags |= 0x10000;
+ setCharEventTimer(charIndex, 546 * rollDice(1, 4, 4), 12, 1);
+ snd_playSoundEffect(100);
+ gui_drawCharPortraitWithStats(charIndex);
+ break;
+
+ case 6:
+ sparkEffectDefensive(charIndex);
+ c->effectFlags |= 0x40;
+ gui_drawCharPortraitWithStats(charIndex);
+ break;
+
+ case 7:
+ sparkEffectDefensive(charIndex);
+ neutralizePoison(charIndex);
+ break;
+
+ default:
+ break;
+ }
+
+ _txt->printMessage(_potionStrings[1], -1, c->name, _potionEffectStrings[val]);
+}
+
+void EoBCoreEngine::useWand(int charIndex, int weaponSlot) {
+ int v = _items[_characters[charIndex].inventory[weaponSlot]].value;
+ if (!v) {
+ _txt->printMessage(_wandStrings[0]);
+ return;
+ }
+
+ if (v != 5)
+ useMagicScroll(charIndex, _wandTypes[v], weaponSlot);
+ else if (_flags.gameID == GI_EOB2)
+ useMagicScroll(charIndex, 64, weaponSlot);
+ else {
+ uint16 bl1 = calcNewBlockPosition(_currentBlock, _currentDirection);
+ uint16 bl2 = calcNewBlockPosition(bl1, _currentDirection);
+ snd_playSoundEffect(98);
+ sparkEffectOffensive();
+
+ if ((_wllWallFlags[_levelBlockProperties[bl2].walls[_currentDirection ^ 2]] & 4) && !(_levelBlockProperties[bl2].flags & 7) && (_levelBlockProperties[bl1].flags & 7)) {
+ for (int i = 0; i < 30; i++) {
+ if (_monsters[i].block != bl1)
+ continue;
+ placeMonster(&_monsters[i], bl2, -1);
+ _sceneUpdateRequired = true;
+ }
+ } else {
+ _txt->printMessage(_wandStrings[1]);
+ }
+ }
+}
+
+void EoBCoreEngine::castSpell(int spell, int weaponSlot) {
+ EoBSpell *s = &_spells[spell];
+ EoBCharacter *c = &_characters[_openBookChar];
+ _activeSpell = spell;
+
+ if ((s->flags & 0x100) && (c->effectFlags & 0x40))
+ // remove invisibility effect
+ removeCharacterEffect(10, _openBookChar, 1);
+
+ int ci = _openBookChar;
+ if (ci > 3)
+ ci -= 2;
+
+ _activeSpellCharacterPos = _dropItemDirIndex[(_currentDirection << 2) + ci];
+
+ if (s->flags & 0x400) {
+ if (c->inventory[0] && c->inventory[1]) {
+ printWarning(_magicStrings1[2]);
+ return;
+ }
+
+ if (isMagicEffectItem(c->inventory[0]) || isMagicEffectItem(c->inventory[1])) {
+ printWarning(_magicStrings1[3]);
+ return;
+ }
+ }
+
+ if (!(_flags.gameID == GI_EOB2 && _activeSpell == 62)) {
+ if (!_castScrollSlot) {
+ int8 tmp = _openBookAvailableSpells[_openBookSpellLevel * 10 + _openBookSpellListOffset + _openBookSpellSelectedItem];
+ if (_openBookSpellListOffset + _openBookSpellSelectedItem < 8)
+ memmove(&_openBookAvailableSpells[_openBookSpellLevel * 10 + _openBookSpellListOffset + _openBookSpellSelectedItem], &_openBookAvailableSpells[_openBookSpellLevel * 10 + _openBookSpellListOffset + _openBookSpellSelectedItem + 1], 8 - (_openBookSpellListOffset + _openBookSpellSelectedItem));
+ _openBookAvailableSpells[_openBookSpellLevel * 10 + 8] = -tmp;
+ if (_openBookAvailableSpells[_openBookSpellLevel * 10 + _openBookSpellListOffset + _openBookSpellSelectedItem] < 0) {
+ if (--_openBookSpellSelectedItem == -1) {
+ if (_openBookSpellListOffset) {
+ _openBookSpellListOffset = 0;
+ _openBookSpellSelectedItem = 5;
+ } else {
+ _openBookSpellSelectedItem = 6;
+ }
+ }
+ }
+ } else if (weaponSlot != -1) {
+ updateUsedCharacterHandItem(_openBookChar, weaponSlot);
+ }
+ }
+
+ _txt->printMessage(_magicStrings1[4], -1, c->name, s->name);
+
+ if (s->flags & 0x20) {
+ castOnWhomDialogue();
+ return;
+ }
+
+ _activeSpellCharId = _openBookChar;
+ startSpell(spell);
+}
+
+void EoBCoreEngine::removeCharacterEffect(int spell, int charIndex, int showWarning) {
+ assert(spell >= 0);
+ EoBCharacter *c = &_characters[charIndex];
+ EoBSpell *s = &_spells[spell];
+
+ if (showWarning) {
+ int od = _screen->curDimIndex();
+ Screen::FontId of = _screen->setFont(Screen::FID_6_FNT);
+ _screen->setScreenDim(7);
+ printWarning(Common::String::format(_magicStrings3[_flags.gameID == GI_EOB1 ? 3 : 2], c->name, s->name).c_str());
+ _screen->setScreenDim(od);
+ _screen->setFont(of);
+ }
+
+ if (s->endCallback)
+ (this->*s->endCallback)(c);
+
+ if (s->flags & 1)
+ c->effectFlags &= ~s->effectFlags;
+
+ if (s->flags & 4)
+ _partyEffectFlags &= ~s->effectFlags;
+
+ if (s->flags & 0x200) {
+ for (int i = 0; i < 6; i++) {
+ if (!testCharacter(i, 1))
+ continue;
+ if (!testCharacter(i, 2) && !(s->flags & 0x800))
+ continue;
+ _characters[i].effectFlags &= ~s->effectFlags;
+ }
+ }
+
+ if (s->flags & 0x2)
+ recalcArmorClass(_activeSpellCharId);
+
+ if (showWarning) {
+ if (s->flags & 0x20A0)
+ gui_drawCharPortraitWithStats(charIndex);
+ else if (s->flags & 0x40)
+ gui_drawAllCharPortraitsWithStats();
+ }
+}
+
+void EoBCoreEngine::removeAllCharacterEffects(int charIndex) {
+ EoBCharacter *c = &_characters[charIndex];
+ c->effectFlags = 0;
+ memset(c->effectsRemainder, 0, 4);
+
+ for (int i = 0; i < 10; i++) {
+ if (c->events[i] < 0) {
+ removeCharacterEffect(-c->events[i], charIndex, 0);
+ c->timers[i] = 0;
+ c->events[i] = 0;
+ }
+ }
+
+ setupCharacterTimers();
+ recalcArmorClass(charIndex);
+ c->disabledSlots = 0;
+ c->slotStatus[0] = c->slotStatus[1] = 0;
+ c->damageTaken = 0;
+ c->strengthCur = c->strengthMax;
+ c->strengthExtCur = c->strengthExtMax;
+ gui_drawAllCharPortraitsWithStats();
+}
+
+void EoBCoreEngine::castOnWhomDialogue() {
+ printWarning(_magicStrings3[0]);
+ gui_setCastOnWhomButtons();
+}
+
+void EoBCoreEngine::startSpell(int spell) {
+ EoBSpell *s = &_spells[spell];
+ EoBCharacter *c = &_characters[_activeSpellCharId];
+ snd_playSoundEffect(s->sound);
+
+ if (s->flags & 0xa0)
+ sparkEffectDefensive(_activeSpellCharId);
+ else if (s->flags & 0x40)
+ sparkEffectDefensive(-1);
+ else if (s->flags & 0x1000)
+ sparkEffectOffensive();
+
+ if (s->flags & 0x20) {
+ _txt->printMessage(c->name);
+ _txt->printMessage(_flags.gameID == GI_EOB1 ? _magicStrings3[1] : _magicStrings1[5]);
+ }
+
+ if ((s->flags & 0x30) && (s->effectFlags & c->effectFlags)) {
+ if (_flags.gameID == GI_EOB2)
+ printWarning(Common::String::format(_magicStrings7[0], c->name, s->name).c_str());
+ } else if ((s->flags & 0x50) && (s->effectFlags & _partyEffectFlags)) {
+ if (_flags.gameID == GI_EOB1 && s->effectFlags == 0x400)
+ // EOB 1 only warns in case of a bless spell
+ printWarning(_magicStrings8[1]);
+ else
+ printWarning(Common::String::format(_magicStrings7[1], s->name).c_str());
+ } else {
+ if (s->flags & 8)
+ setSpellEventTimer(spell, s->timingPara[0], s->timingPara[1], s->timingPara[2], s->timingPara[3]);
+
+ _returnAfterSpellCallback = false;
+ if (s->startCallback)
+ (this->*s->startCallback)();
+ if (_returnAfterSpellCallback)
+ return;
+
+ if (s->flags & 1)
+ c->effectFlags |= s->effectFlags;
+ if (s->flags & 4)
+ _partyEffectFlags |= s->effectFlags;
+
+ if (s->flags & 0x200) {
+ for (int i = 0; i < 6; i++) {
+ if (!testCharacter(i, 1))
+ continue;
+ if (!testCharacter(i, 2) && !(s->flags & 0x800))
+ continue;
+ _characters[i].effectFlags |= s->effectFlags;
+ }
+ }
+
+ if (s->flags & 2)
+ recalcArmorClass(_activeSpellCharId);
+
+ if (s->flags & 0x20A0)
+ gui_drawCharPortraitWithStats(_activeSpellCharId);
+ if (s->flags & 0x40)
+ gui_drawAllCharPortraitsWithStats();
+ }
+
+ if (_castScrollSlot) {
+ gui_updateSlotAfterScrollUse();
+ } else {
+ _characters[_openBookChar].disabledSlots |= 4;
+ setCharEventTimer(_openBookChar, 72, 11, 1);
+ gui_toggleButtons();
+ gui_drawSpellbook();
+ }
+
+ if (_flags.gameID == GI_EOB2) {
+ //_castSpellWd1 = spell;
+ runLevelScript(_currentBlock, 0x800);
+ //_castSpellWd1 = 0;
+ }
+}
+
+void EoBCoreEngine::sparkEffectDefensive(int charIndex) {
+ int first = charIndex;
+ int last = charIndex;
+ if (charIndex == -1) {
+ first = 0;
+ last = 5;
+ }
+
+ for (int i = 0; i < 8; i++) {
+ for (int ii = first; ii <= last; ii++) {
+ if (!testCharacter(ii, 1) || (_currentControlMode && ii != _updateCharNum))
+ continue;
+
+ gui_drawCharPortraitWithStats(ii);
+
+ for (int iii = 0; iii < 4; iii++) {
+ int shpIndex = ((_sparkEffectDefSteps[i] & _sparkEffectDefSubSteps[iii]) >> _sparkEffectDefShift[iii]);
+ if (!shpIndex)
+ continue;
+ int x = _sparkEffectDefAdd[iii * 2] - 8;
+ int y = _sparkEffectDefAdd[iii * 2 + 1];
+ if (_currentControlMode) {
+ x += 181;
+ y += 3;
+ } else {
+ x += (_sparkEffectDefX[ii] << 3);
+ y += _sparkEffectDefY[ii];
+ }
+ _screen->drawShape(0, _sparkShapes[shpIndex - 1], x, y, 0);
+ _screen->updateScreen();
+ }
+ }
+ delay(2 * _tickLength);
+ }
+
+ for (int i = first; i < last; i++)
+ gui_drawCharPortraitWithStats(i);
+}
+
+void EoBCoreEngine::sparkEffectOffensive() {
+ disableSysTimer(2);
+ _screen->copyRegion(0, 0, 0, 0, 176, 120, 0, 2, Screen::CR_NO_P_CHECK);
+
+ for (int i = 0; i < 16; i++)
+ _screen->copyRegionToBuffer(0, _sparkEffectOfX[i], _sparkEffectOfY[i], 16, 16, &_spellAnimBuffer[i << 8]);
+ _screen->updateScreen();
+
+ for (int i = 0; i < 11; i++) {
+ for (int ii = 0; ii < 16; ii++)
+ _screen->copyBlockToPage(2, _sparkEffectOfX[ii], _sparkEffectOfY[ii], 16, 16, &_spellAnimBuffer[ii << 8]);
+
+ for (int ii = 0; ii < 16; ii++) {
+ int shpIndex = (_sparkEffectOfFlags1[i] & _sparkEffectOfFlags2[ii]) >> _sparkEffectOfShift[ii];
+ if (shpIndex)
+ _screen->drawShape(2, _sparkShapes[shpIndex - 1], _sparkEffectOfX[ii], _sparkEffectOfY[ii], 0);
+ }
+ delay(2 * _tickLength);
+ _screen->copyRegion(0, 0, 0, 0, 176, 120, 2, 0, Screen::CR_NO_P_CHECK);
+ _screen->updateScreen();
+ }
+
+ for (int i = 0; i < 16; i++)
+ _screen->copyBlockToPage(0, _sparkEffectOfX[i], _sparkEffectOfY[i], 16, 16, &_spellAnimBuffer[i << 8]);
+
+ _screen->updateScreen();
+ enableSysTimer(2);
+}
+
+void EoBCoreEngine::setSpellEventTimer(int spell, int timerBaseFactor, int timerLength, int timerLevelFactor, int updateExistingTimer) {
+ assert(spell >= 0);
+ int l = _openBookType == 1 ? getClericPaladinLevel(_openBookChar) : getMageLevel(_openBookChar);
+ uint32 countdown = timerLength * timerBaseFactor + timerLength * l * timerLevelFactor;
+ setCharEventTimer(_activeSpellCharId, countdown, -spell, updateExistingTimer);
+}
+
+void EoBCoreEngine::sortCharacterSpellList(int charIndex) {
+ int8 *list = _characters[charIndex].mageSpells;
+
+ for (int i = 0; i < 16;) {
+ bool p = false;
+ for (int ii = 0; ii < 9; ii++) {
+ int8 *pos = &list[ii];
+
+ int s1 = pos[0];
+ int s2 = pos[1];
+
+ if (s1 == 0)
+ s1 = 80;
+ else if (s1 < 0)
+ s1 = s1 * -1 + 40;
+
+ if (s2 == 0)
+ s2 = 80;
+ else if (s2 < 0)
+ s2 = s2 * -1 + 40;
+
+ if (s1 > s2) {
+ SWAP(pos[0], pos[1]);
+ p = true;
+ }
+ }
+
+ if (p)
+ continue;
+
+ list += 10;
+ if (++i == 8)
+ list = _characters[charIndex].clericSpells;
+ }
+}
+
+bool EoBCoreEngine::magicObjectDamageHit(EoBFlyingObject *fo, int dcTimes, int dcPips, int dcOffs, int level) {
+ int ignoreAttackerId = fo->flags & 0x10;
+ int singleTargetCheckAdjacent = fo->flags & 1;
+ int blockDamage = fo->flags & 2;
+ int hitTest = fo->flags & 4;
+
+ int savingThrowType = 5;
+ int savingThrowEffect = 3;
+ if (fo->flags & 8) {
+ savingThrowType = 4;
+ savingThrowEffect = 0;
+ }
+
+ int dmgFlag = _spells[fo->callBackIndex].damageFlags;
+ if (fo->attackerId >= 0)
+ dmgFlag |= 0x800;
+
+ bool res = false;
+ if (!level)
+ level = 1;
+
+ if ((_levelBlockProperties[fo->curBlock].flags & 7) && (fo->attackerId >= 0 || ignoreAttackerId)) {
+ _preventMonsterFlash = true;
+
+ for (const int16 *m = findBlockMonsters(fo->curBlock, fo->curPos, fo->direction, blockDamage, singleTargetCheckAdjacent); *m != -1; m++) {
+ int dmg = rollDice(dcTimes, dcPips, dcOffs) * level;
+
+ if (hitTest) {
+ if (!characterAttackHitTest(fo->attackerId, *m, 0, 0))
+ continue;
+ }
+
+ calcAndInflictMonsterDamage(&_monsters[*m], 0, 0, dmg, dmgFlag, savingThrowType, savingThrowEffect);
+ res = true;
+ }
+ updateAllMonsterShapes();
+
+ } else if (fo->curBlock == _currentBlock && (fo->attackerId < 0 || ignoreAttackerId)) {
+ if (blockDamage) {
+ for (int i = 0; i < 6; i++) {
+ if (!testCharacter(i, 1))
+ continue;
+ if (hitTest && !monsterAttackHitTest(&_monsters[0], i))
+ continue;
+
+ int dmg = rollDice(dcTimes, dcPips, dcOffs) * level;
+ res = true;
+
+ calcAndInflictCharacterDamage(i, 0, 0, dmg, dmgFlag, savingThrowType, savingThrowEffect);
+ }
+ } else {
+ int c = _dscItemPosIndex[(_currentDirection << 2) + (fo->curPos & 3)];
+ if ((c > 2) && (testCharacter(4, 1) || testCharacter(5, 1)) && rollDice(1, 2, -1))
+ c += 2;
+
+ if (!fo->item && (_characters[c].effectFlags & 8)) {
+ res = true;
+ } else {
+ if ((_characters[c].flags & 1) && (!hitTest || monsterAttackHitTest(&_monsters[0], c))) {
+ int dmg = rollDice(dcTimes, dcPips, dcOffs) * level;
+ res = true;
+ calcAndInflictCharacterDamage(c, 0, 0, dmg, dmgFlag, savingThrowType, savingThrowEffect);
+ }
+ }
+ }
+ }
+
+ if (res && (fo->flags & 0x40))
+ explodeObject(fo, fo->curBlock, fo->item);
+ else if ((_flags.gameID == GI_EOB1 && fo->item == 5) || (_flags.gameID == GI_EOB2 && fo->item == 4))
+ res = false;
+
+ return res;
+}
+
+bool EoBCoreEngine::magicObjectStatusHit(EoBMonsterInPlay *m, int type, bool tryEvade, int mod) {
+ EoBMonsterProperty *p = &_monsterProps[m->type];
+ if (tryEvade) {
+ if (tryMonsterAttackEvasion(m) || (p->immunityFlags & 0x10))
+ return true;
+ }
+
+ if (trySavingThrow(m, 0, p->level, mod, 6))
+ return false;
+
+ int para = 0;
+
+ switch (type) {
+ case 0:
+ case 1:
+ case 2:
+ para = (type == 0) ? ((p->typeFlags & 1) ? 1 : 0) : ((type == 1) ? ((p->typeFlags & 2) ? 1 : 0) : 1);
+ if (para && !(p->immunityFlags & 2)) {
+ m->mode = 10;
+ m->spellStatusLeft = 15;
+ }
+
+ break;
+
+ case 3:
+ if (!(p->immunityFlags & 8))
+ inflictMonsterDamage(m, 1000, true);
+ break;
+
+ case 4:
+ inflictMonsterDamage(m, 1000, true);
+ break;
+
+ case 5:
+ m->flags |= 0x20;
+ _sceneUpdateRequired = true;
+ break;
+
+ case 6:
+ if (!(_flags.gameID == GI_EOB1 && !(p->typeFlags & 3)) && !(p->immunityFlags & 4) && m->mode != 7 && m->mode != 8 && m->mode != 10) {
+ m->mode = 0;
+ m->spellStatusLeft = 20;
+ m->flags |= 8;
+ walkMonsterNextStep(m, -1, (getNextMonsterDirection(m->block, _currentBlock) ^ 4) >> 1);
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ return true;
+}
+
+bool EoBCoreEngine::turnUndeadHit(EoBMonsterInPlay *m, int hitChance, int casterLevel) {
+ assert(_monsterProps[m->type].tuResist > 0);
+ uint8 e = _turnUndeadEffect[_monsterProps[m->type].tuResist * 14 + MIN(casterLevel, 14)];
+
+ if (e == 0xff) {
+ calcAndInflictMonsterDamage(m, 0, 0, 500, 0x200, 5, 3);
+ } else if (hitChance < e) {
+ return false;
+ } else {
+ m->mode = 0;
+ m->flags |= 8;
+ m->spellStatusLeft = 40;
+ m->dir = (getNextMonsterDirection(m->block, _currentBlock) ^ 4) >> 1;
+ }
+
+ return true;
+}
+
+int EoBCoreEngine::getMagicWeaponSlot(int charIndex) {
+ return _characters[charIndex].inventory[1] ? 0 : 1;
+}
+
+void EoBCoreEngine::causeWounds(int dcTimes, int dcPips, int dcOffs) {
+ if (_openBookChar == 0 || _openBookChar == 1) {
+ int d = getClosestMonster(_openBookChar, calcNewBlockPosition(_currentBlock, _currentDirection));
+ if (d != -1) {
+ if (!characterAttackHitTest(_openBookChar, d, 0, 1))
+ return;
+
+ if (dcTimes == -1) {
+ dcOffs = _monsters[d].hitPointsMax - rollDice(1, 4);
+ dcTimes = dcPips = 0;
+ }
+ calcAndInflictMonsterDamage(&_monsters[d], dcTimes, dcPips, dcOffs, 0x801, 4, 2);
+ } else {
+ printWarning(Common::String::format(_magicStrings3[_flags.gameID == GI_EOB1 ? 4 : 3], _characters[_openBookChar].name).c_str());
+ }
+ } else {
+ printWarning(Common::String::format(_magicStrings3[_flags.gameID == GI_EOB1 ? 5 : 4], _characters[_openBookChar].name).c_str());
+ }
+}
+
+int EoBCoreEngine::createMagicWeaponType(int invFlags, int handFlags, int armorClass, int allowedClasses, int dmgNumDice, int dmgPips, int dmgInc, int extraProps) {
+ int i = 51;
+ for (; i < 57; i++) {
+ if (_itemTypes[i].armorClass == -30)
+ break;
+ }
+
+ if (i == 57)
+ return -1;
+
+ EoBItemType *tp = &_itemTypes[i];
+ tp->invFlags = invFlags;
+ tp->requiredHands = 0;
+ tp->handFlags = handFlags;
+ tp->armorClass = armorClass;
+ tp->allowedClasses = allowedClasses;
+ tp->dmgNumDiceL = tp->dmgNumDiceS = dmgNumDice;
+ tp->dmgNumPipsL = tp->dmgNumPipsS = dmgPips;
+ tp->dmgIncL = tp->dmgIncS = dmgInc;
+ tp->extraProperties = extraProps;
+
+ return i;
+}
+
+Item EoBCoreEngine::createMagicWeaponItem(int flags, int icon, int value, int type) {
+ Item i = 11;
+ for (; i < 17; i++) {
+ if (_items[i].block == -2)
+ break;
+ }
+
+ if (i == 17)
+ return -1;
+
+ EoBItem *itm = &_items[i];
+ itm->flags = 0x20 | flags;
+ itm->icon = icon;
+ itm->value = value;
+ itm->type = type;
+ itm->pos = 0;
+ itm->block = 0;
+ itm->nameId = itm->nameUnid = 0;
+ itm->prev = itm->next = 0;
+
+ return i;
+}
+
+void EoBCoreEngine::removeMagicWeaponItem(Item item) {
+ _itemTypes[_items[item].type].armorClass = -30;
+ _items[item].block = -2;
+ _items[item].level = 0xff;
+}
+
+void EoBCoreEngine::updateWallOfForceTimers() {
+ uint32 ct = _system->getMillis();
+ for (int i = 0; i < 5; i++) {
+ if (!_wallsOfForce[i].block)
+ continue;
+ if (_wallsOfForce[i].duration < ct)
+ destroyWallOfForce(i);
+ }
+}
+
+void EoBCoreEngine::destroyWallOfForce(int index) {
+ memset(_levelBlockProperties[_wallsOfForce[index].block].walls, 0, 4);
+ _wallsOfForce[index].block = 0;
+ _sceneUpdateRequired = true;
+}
+
+int EoBCoreEngine::findSingleSpellTarget(int dist) {
+ uint16 bl = _currentBlock;
+ int res = -1;
+
+ for (int i = 0; i < dist && res == -1; i++) {
+ bl = calcNewBlockPosition(bl, _currentDirection);
+ res = getClosestMonster(_openBookChar, bl);
+ if (!(_wllWallFlags[_levelBlockProperties[bl].walls[_sceneDrawVarDown]] & 1)) {
+ i = dist;
+ res = -1;
+ }
+ }
+
+ return res;
+}
+
+int EoBCoreEngine::findFirstCharacterSpellTarget() {
+ int curCharIndex = rollDice(1, 6, -1);
+ for (_characterSpellTarget = 0; _characterSpellTarget < 6; _characterSpellTarget++) {
+ if (testCharacter(curCharIndex, 3))
+ return curCharIndex;
+ if (++curCharIndex == 6)
+ curCharIndex = 0;
+ }
+ return -1;
+}
+
+int EoBCoreEngine::findNextCharacterSpellTarget(int curCharIndex) {
+ for (_characterSpellTarget++; _characterSpellTarget < 6;) {
+ if (++curCharIndex == 6)
+ curCharIndex = 0;
+ if (testCharacter(curCharIndex, 3))
+ return curCharIndex;
+ }
+ return -1;
+}
+
+int EoBCoreEngine::charDeathSavingThrow(int charIndex, int div) {
+ bool _beholderOrgBhv = true;
+ // Due to a bug in the original code the saving throw result is completely ignored
+ // here. The Beholders' disintegrate spell will alway succeed while their flesh to
+ // stone spell will always fail.
+ if (_beholderOrgBhv)
+ div >>= 1;
+ else
+ div = specialAttackSavingThrow(charIndex, 4) ? 1 : 0;
+ return div;
+}
+
+void EoBCoreEngine::printWarning(const char *str) {
+ _txt->printMessage(str);
+ snd_playSoundEffect(79);
+}
+
+void EoBCoreEngine::printNoEffectWarning() {
+ printWarning(_magicStrings4[0]);
+}
+
+void EoBCoreEngine::spellCallback_start_armor() {
+ _characters[_activeSpellCharId].effectsRemainder[0] = getMageLevel(_openBookChar) + 8;
+ if ((getDexterityArmorClassModifier(_characters[_activeSpellCharId].dexterityCur) + 6) >= _characters[_activeSpellCharId].armorClass)
+ printWarning(Common::String::format(_magicStrings6[0], _characters[_activeSpellCharId].name).c_str());
+}
+
+void EoBCoreEngine::spellCallback_start_burningHands() {
+ static const int16 bX[] = { 0, 152, 24, 120, 56, 88 };
+ static const int8 bY[] = { 64, 64, 56, 56, 56, 56 };
+
+ for (int i = 0; i < 6; i++)
+ drawBlockObject(i & 1, 0, _firebeamShapes[(5 - i) >> 1], bX[i], bY[i], 0);
+ _screen->updateScreen();
+ delay(2 * _tickLength);
+
+ int cl = getMageLevel(_openBookChar);
+ int bl = calcNewBlockPosition(_currentBlock, _currentDirection);
+
+ const int8 *pos = getMonstersOnBlockPositions(bl);
+ _preventMonsterFlash = true;
+
+ int numDest = (_flags.gameID == GI_EOB1) ? 2 : 6;
+ const uint8 *d = &_burningHandsDest[_currentDirection * (_flags.gameID == GI_EOB1 ? 2 : 8)];
+
+ for (int i = 0; i < numDest; i++, d++) {
+ if (pos[*d] == -1)
+ continue;
+ calcAndInflictMonsterDamage(&_monsters[pos[*d]], 1, 3, cl << 1, 0x21, 4, 0);
+ }
+
+ updateAllMonsterShapes();
+ _sceneUpdateRequired = true;
+}
+
+void EoBCoreEngine::spellCallback_start_detectMagic() {
+ setHandItem(_itemInHand);
+}
+
+bool EoBCoreEngine::spellCallback_end_detectMagic(void *) {
+ setHandItem(_itemInHand);
+ return true;
+}
+
+void EoBCoreEngine::spellCallback_start_magicMissile() {
+ launchMagicObject(_openBookChar, 0, _currentBlock, _activeSpellCharacterPos, _currentDirection);
+}
+
+bool EoBCoreEngine::spellCallback_end_magicMissile(void *obj) {
+ EoBFlyingObject *fo = (EoBFlyingObject *)obj;
+ return magicObjectDamageHit(fo, 1, 4, 1, (getMageLevel(fo->attackerId) - 1) >> 1);
+}
+
+void EoBCoreEngine::spellCallback_start_shockingGrasp() {
+ int t = createMagicWeaponType(0, 0, 0, 0x0f, 1, 8, getMageLevel(_openBookChar), 1);
+ Item i = (t != -1) ? createMagicWeaponItem(0x10, 82, 0, t) : -1;
+ if (t == -1 || i == -1) {
+ if (_flags.gameID == GI_EOB2)
+ printWarning(_magicStrings8[0]);
+ removeCharacterEffect(_activeSpell, _activeSpellCharId, 0);
+ deleteCharEventTimer(_activeSpellCharId, -_activeSpell);
+ _returnAfterSpellCallback = true;
+ } else {
+ _characters[_activeSpellCharId].inventory[getMagicWeaponSlot(_activeSpellCharId)] = i;
+ }
+}
+
+bool EoBCoreEngine::spellCallback_end_shockingGraspFlameBlade(void *obj) {
+ EoBCharacter *c = (EoBCharacter *)obj;
+ for (int i = 0; i < 2; i++) {
+ if (isMagicEffectItem(c->inventory[i])) {
+ removeMagicWeaponItem(c->inventory[i]);
+ c->inventory[i] = 0;
+ }
+ }
+ return true;
+}
+
+void EoBCoreEngine::spellCallback_start_improvedIdentify() {
+ for (int i = 0; i < 2; i++) {
+ Item itm = _characters[_activeSpellCharId].inventory[i];
+ if (itm)
+ _items[itm].flags |= 0x40;
+ }
+}
+
+void EoBCoreEngine::spellCallback_start_melfsAcidArrow() {
+ launchMagicObject(_openBookChar, 1, _currentBlock, _activeSpellCharacterPos, _currentDirection);
+}
+
+bool EoBCoreEngine::spellCallback_end_melfsAcidArrow(void *obj) {
+ EoBFlyingObject *fo = (EoBFlyingObject *)obj;
+ assert(fo);
+ return magicObjectDamageHit(fo, 2, 4, 0, getMageLevel(fo->attackerId) / 3);
+}
+
+void EoBCoreEngine::spellCallback_start_dispelMagic() {
+ for (int i = 0; i < 6; i++) {
+ if (testCharacter(i, 1))
+ removeAllCharacterEffects(i);
+ }
+}
+
+void EoBCoreEngine::spellCallback_start_fireball() {
+ launchMagicObject(_openBookChar, 2, _currentBlock, _activeSpellCharacterPos, _currentDirection);
+}
+
+bool EoBCoreEngine::spellCallback_end_fireball(void *obj) {
+ EoBFlyingObject *fo = (EoBFlyingObject *)obj;
+ return magicObjectDamageHit(fo, 1, 6, 0, getMageLevel(fo->attackerId));
+}
+
+void EoBCoreEngine::spellCallback_start_flameArrow() {
+ launchMagicObject(_openBookChar, 3, _currentBlock, _activeSpellCharacterPos, _currentDirection);
+}
+
+bool EoBCoreEngine::spellCallback_end_flameArrow(void *obj) {
+ EoBFlyingObject *fo = (EoBFlyingObject *)obj;
+ return magicObjectDamageHit(fo, 5, 6, 0, getMageLevel(fo->attackerId));
+}
+
+void EoBCoreEngine::spellCallback_start_holdPerson() {
+ launchMagicObject(_openBookChar, _flags.gameID == GI_EOB1 ? 4 : 3, _currentBlock, _activeSpellCharacterPos, _currentDirection);
+}
+
+bool EoBCoreEngine::spellCallback_end_holdPerson(void *obj) {
+ EoBFlyingObject *fo = (EoBFlyingObject *)obj;
+ bool res = false;
+
+ if (_flags.gameID == GI_EOB2 && fo->curBlock == _currentBlock) {
+ // party hit
+ int numChar = rollDice(1, 4, 0);
+ int charIndex = rollDice(1, 6, -1);
+ for (int i = 0; i < 6 && numChar; i++) {
+ if (testCharacter(charIndex, 3)) {
+ statusAttack(charIndex, 4, _magicStrings8[1], 4, 5, 9, 1);
+ numChar--;
+ }
+ charIndex = (charIndex + 1) % 6;
+ }
+ res = true;
+
+ } else {
+ // monster hit
+ for (const int16 *m = findBlockMonsters(fo->curBlock, fo->curPos, fo->direction, 1, 1); *m != -1; m++)
+ res |= magicObjectStatusHit(&_monsters[*m], 0, true, 4);
+ }
+
+ return res;
+}
+
+void EoBCoreEngine::spellCallback_start_lightningBolt() {
+ launchMagicObject(_openBookChar, _flags.gameID == GI_EOB1 ? 5 : 4, _currentBlock, _activeSpellCharacterPos, _currentDirection);
+}
+
+bool EoBCoreEngine::spellCallback_end_lightningBolt(void *obj) {
+ EoBFlyingObject *fo = (EoBFlyingObject *)obj;
+ return magicObjectDamageHit(fo, 1, 6, 0, getMageLevel(fo->attackerId));
+}
+
+void EoBCoreEngine::spellCallback_start_vampiricTouch() {
+ int t = createMagicWeaponType(0, 0, 0, 0x0f, getMageLevel(_openBookChar) >> 1, 6, 0, 1);
+ Item i = (t != -1) ? createMagicWeaponItem(0x18, 83, 0, t) : -1;
+ if (t == -1 || i == -1) {
+ if (_flags.gameID == GI_EOB2)
+ printWarning(_magicStrings8[2]);
+ removeCharacterEffect(_activeSpell, _activeSpellCharId, 0);
+ deleteCharEventTimer(_activeSpellCharId, -_activeSpell);
+ _returnAfterSpellCallback = true;
+ } else {
+ _characters[_activeSpellCharId].inventory[getMagicWeaponSlot(_activeSpellCharId)] = i;
+ }
+}
+
+bool EoBCoreEngine::spellCallback_end_vampiricTouch(void *obj) {
+ EoBCharacter *c = (EoBCharacter *)obj;
+ if (c->hitPointsCur > c->hitPointsMax)
+ c->hitPointsCur = c->hitPointsMax;
+ spellCallback_end_shockingGraspFlameBlade(obj);
+ return true;
+}
+
+void EoBCoreEngine::spellCallback_start_fear() {
+ sparkEffectOffensive();
+ uint16 bl = calcNewBlockPosition(_currentBlock, _currentDirection);
+ for (int i = 0; i < 30; i++) {
+ if (_monsters[i].block == bl)
+ magicObjectStatusHit(&_monsters[i], 6, true, 4);
+ }
+}
+
+void EoBCoreEngine::spellCallback_start_iceStorm() {
+ launchMagicObject(_openBookChar, _flags.gameID == GI_EOB1 ? 6 : 5, _currentBlock, _activeSpellCharacterPos, _currentDirection);
+}
+
+bool EoBCoreEngine::spellCallback_end_iceStorm(void *obj) {
+ EoBFlyingObject *fo = (EoBFlyingObject *)obj;
+ static int8 blockAdv[] = { -32, 32, 1, -1 };
+ bool res = magicObjectDamageHit(fo, 1, 6, 0, getMageLevel(fo->attackerId));
+ if (res) {
+ for (int i = 0; i < 4; i++) {
+ uint16 bl = fo->curBlock;
+ fo->curBlock = (fo->curBlock + blockAdv[i]) & 0x3ff;
+ magicObjectDamageHit(fo, 1, 6, 0, getMageLevel(fo->attackerId));
+ fo->curBlock = bl;
+ }
+ }
+ return res;
+}
+
+void EoBCoreEngine::spellCallback_start_stoneSkin() {
+ _characters[_activeSpellCharId].effectsRemainder[1] = (getMageLevel(_openBookChar) >> 1) + rollDice(1, 4);
+}
+
+void EoBCoreEngine::spellCallback_start_removeCurse() {
+ for (int i = 0; i < 27; i++) {
+ Item itm = _characters[_activeSpellCharId].inventory[i];
+ if (itm && (_items[itm].flags & 0x20) && !isMagicEffectItem(itm))
+ _items[itm].flags = (_items[itm].flags & ~0x20) | 0x40;
+ }
+}
+
+void EoBCoreEngine::spellCallback_start_coneOfCold() {
+ const int8 *dirTables[] = { _coneOfColdDest1, _coneOfColdDest2, _coneOfColdDest3, _coneOfColdDest4 };
+
+ int cl = getMageLevel(_openBookChar);
+
+ _screen->setCurPage(2);
+ _screen->fillRect(0, 0, 176, 120, 0);
+ _screen->setGfxParameters(0, 0, _screen->getPagePixel(2, 0, 0));
+ drawSceneShapes(7);
+ _screen->setCurPage(0);
+ disableSysTimer(2);
+ _screen->drawVortex(150, 50, 10, 1, 100, _coneOfColdGfxTbl, _coneOfColdGfxTblSize);
+ enableSysTimer(2);
+
+ const int8 *tbl = dirTables[_currentDirection];
+ _preventMonsterFlash = true;
+
+ for (int i = 0; i < 7; i++) {
+ for (const int16 *m = findBlockMonsters((_currentBlock + tbl[i]) & 0x3ff, 4, _currentDirection, 1, 1); *m != -1; m++)
+ calcAndInflictMonsterDamage(&_monsters[*m], cl, 4, cl, 0x41, 5, 0);
+ }
+
+ updateAllMonsterShapes();
+}
+
+void EoBCoreEngine::spellCallback_start_holdMonster() {
+ launchMagicObject(_openBookChar, _flags.gameID == GI_EOB1 ? 7 : 6, _currentBlock, _activeSpellCharacterPos, _currentDirection);
+}
+
+bool EoBCoreEngine::spellCallback_end_holdMonster(void *obj) {
+ EoBFlyingObject *fo = (EoBFlyingObject *)obj;
+ bool res = false;
+ for (const int16 *m = findBlockMonsters(fo->curBlock, fo->curPos, fo->direction, 1, 1); *m != -1; m++)
+ res |= magicObjectStatusHit(&_monsters[*m], 1, true, 4);
+ return res;
+}
+
+void EoBCoreEngine::spellCallback_start_wallOfForce() {
+ uint16 bl = calcNewBlockPosition(_currentBlock, _currentDirection);
+ LevelBlockProperty *l = &_levelBlockProperties[bl];
+ if (l->walls[0] || l->walls[1] || l->walls[2] || l->walls[3] || (l->flags & 7)) {
+ printWarning(_magicStrings8[3]);
+ return;
+ }
+
+ uint32 dur = 0xffffffff;
+ int s = 0;
+ int i = 0;
+
+ for (; i < 5; i++) {
+ if (!_wallsOfForce[i].block)
+ break;
+ if (_wallsOfForce[i].duration < dur) {
+ dur = _wallsOfForce[i].duration;
+ s = i;
+ }
+ }
+
+ if (i == 5)
+ destroyWallOfForce(s);
+
+ memset(_levelBlockProperties[bl].walls, 74, 4);
+ _wallsOfForce[s].block = bl;
+ _wallsOfForce[s].duration = _system->getMillis() + (((getMageLevel(_openBookChar) * 546) >> 1) + 546) * _tickLength;
+ _sceneUpdateRequired = true;
+}
+
+void EoBCoreEngine::spellCallback_start_disintegrate() {
+ int d = findSingleSpellTarget(1);
+ if (d != -1)
+ magicObjectStatusHit(&_monsters[d], 4, true, 4);
+ memset(_visibleBlocks[13]->walls, 0, 4);
+ _sceneUpdateRequired = true;
+}
+
+void EoBCoreEngine::spellCallback_start_fleshToStone() {
+ sparkEffectOffensive();
+ int t = getClosestMonster(_openBookChar, calcNewBlockPosition(_currentBlock, _currentDirection));
+ if (t != -1)
+ magicObjectStatusHit(&_monsters[t], 5, true, 4);
+ else
+ printWarning(_magicStrings8[4]);
+}
+
+void EoBCoreEngine::spellCallback_start_stoneToFlesh() {
+ if (_characters[_activeSpellCharId].flags & 8)
+ _characters[_activeSpellCharId].flags &= ~8;
+ else
+ printNoEffectWarning();
+}
+
+void EoBCoreEngine::spellCallback_start_trueSeeing() {
+ _wllVmpMap[46] = 0;
+}
+
+bool EoBCoreEngine::spellCallback_end_trueSeeing(void *) {
+ _wllVmpMap[46] = 1;
+ return true;
+}
+
+void EoBCoreEngine::spellCallback_start_slayLiving() {
+ int d = findSingleSpellTarget(2);
+ if (d != -1) {
+ if (!magicObjectStatusHit(&_monsters[d], 3, true, 4))
+ inflictMonsterDamage(&_monsters[d], rollDice(2, 8, 1), true);
+ }
+}
+
+void EoBCoreEngine::spellCallback_start_powerWordStun() {
+ int d = findSingleSpellTarget(2);
+ if (d != -1) {
+ if (_monsters[d].hitPointsCur < 90)
+ magicObjectStatusHit(&_monsters[d], 5, true, 4);
+ }
+}
+
+void EoBCoreEngine::spellCallback_start_causeLightWounds() {
+ causeWounds(1, 8, 0);
+}
+
+void EoBCoreEngine::spellCallback_start_cureLightWounds() {
+ modifyCharacterHitpoints(_activeSpellCharId, rollDice(1, 8));
+}
+
+void EoBCoreEngine::spellCallback_start_aid() {
+ if (!testCharacter(_activeSpellCharId, 3)) {
+ printNoEffectWarning();
+ } else if (_characters[_activeSpellCharId].effectsRemainder[3]) {
+ printWarning(Common::String::format(_magicStrings8[(_flags.gameID == GI_EOB1) ? 2 : 5], _characters[_activeSpellCharId].name).c_str());
+ } else {
+ _characters[_activeSpellCharId].effectsRemainder[3] = rollDice(1, 8);
+ _characters[_activeSpellCharId].hitPointsCur += _characters[_activeSpellCharId].effectsRemainder[3];
+ _characters[_activeSpellCharId].effectFlags |= 0x1000;
+ return;
+ }
+
+ removeCharacterEffect(_activeSpell, _activeSpellCharId, 0);
+ deleteCharEventTimer(_activeSpellCharId, -_activeSpell);
+}
+
+bool EoBCoreEngine::spellCallback_end_aid(void *obj) {
+ EoBCharacter *c = (EoBCharacter *)obj;
+ c->hitPointsCur -= c->effectsRemainder[3];
+ c->effectsRemainder[3] = 0;
+ c->effectFlags &= ~0x1000;
+ return true;
+}
+
+void EoBCoreEngine::spellCallback_start_flameBlade() {
+ int t = createMagicWeaponType(0, 0, 0, 0x0f, 1, 4, 4, 1);
+ Item i = (t != -1) ? createMagicWeaponItem(0, 84, 0, t) : -1;
+ if (t == -1 || i == -1) {
+ if (_flags.gameID == GI_EOB2)
+ printWarning(_magicStrings8[0]);
+ removeCharacterEffect(_activeSpell, _activeSpellCharId, 0);
+ deleteCharEventTimer(_activeSpellCharId, -_activeSpell);
+ _returnAfterSpellCallback = true;
+ } else {
+ _characters[_activeSpellCharId].inventory[getMagicWeaponSlot(_activeSpellCharId)] = i;
+ }
+}
+
+void EoBCoreEngine::spellCallback_start_slowPoison() {
+ if (_characters[_activeSpellCharId].flags & 2) {
+ _characters[_activeSpellCharId].effectFlags |= 0x2000;
+ setSpellEventTimer(_activeSpell, 1, 32760, 1, 1);
+ } else {
+ printNoEffectWarning();
+ }
+}
+
+bool EoBCoreEngine::spellCallback_end_slowPoison(void *obj) {
+ EoBCharacter *c = (EoBCharacter *)obj;
+ c->effectFlags &= ~0x2000;
+ return true;
+}
+
+void EoBCoreEngine::spellCallback_start_createFood() {
+ for (int i = 0; i < 6; i++) {
+ if (!testCharacter(i, 3))
+ continue;
+ _characters[i].food = 100;
+ }
+}
+
+void EoBCoreEngine::spellCallback_start_removeParalysis() {
+ int numChar = 4;
+ for (int i = 0; i < 6; i++) {
+ if (!(_characters[i].flags & 4) || !numChar)
+ continue;
+ _characters[i].flags &= ~4;
+ numChar--;
+ }
+}
+
+void EoBCoreEngine::spellCallback_start_causeSeriousWounds() {
+ causeWounds(2, 8, 1);
+}
+
+void EoBCoreEngine::spellCallback_start_cureSeriousWounds() {
+ modifyCharacterHitpoints(_activeSpellCharId, rollDice(2, 8, 1));
+}
+
+void EoBCoreEngine::spellCallback_start_neutralizePoison() {
+ if (_characters[_activeSpellCharId].flags & 2)
+ neutralizePoison(_activeSpellCharId);
+ else
+ printNoEffectWarning();
+}
+
+void EoBCoreEngine::spellCallback_start_causeCriticalWounds() {
+ causeWounds(3, 8, 3);
+}
+
+void EoBCoreEngine::spellCallback_start_cureCriticalWounds() {
+ modifyCharacterHitpoints(_activeSpellCharId, rollDice(3, 8, 3));
+}
+
+void EoBCoreEngine::spellCallback_start_flameStrike() {
+ launchMagicObject(_openBookChar, _flags.gameID == GI_EOB1 ? 8 : 7, _currentBlock, _activeSpellCharacterPos, _currentDirection);
+}
+
+bool EoBCoreEngine::spellCallback_end_flameStrike(void *obj) {
+ EoBFlyingObject *fo = (EoBFlyingObject *)obj;
+ return magicObjectDamageHit(fo, 6, 8, 0, 0);
+}
+
+void EoBCoreEngine::spellCallback_start_raiseDead() {
+ if (_characters[_activeSpellCharId].hitPointsCur == -10 && ((_characters[_activeSpellCharId].raceSex >> 1) != 1)) {
+ _characters[_activeSpellCharId].hitPointsCur = 1;
+ gui_drawCharPortraitWithStats(_activeSpellCharId);
+ } else {
+ printNoEffectWarning();
+ }
+}
+
+void EoBCoreEngine::spellCallback_start_harm() {
+ causeWounds(-1, -1, -1);
+}
+
+void EoBCoreEngine::spellCallback_start_heal() {
+ EoBCharacter *c = &_characters[_activeSpellCharId];
+ if (c->hitPointsMax <= c->hitPointsCur)
+ printWarning(_magicStrings4[0]);
+ else
+ modifyCharacterHitpoints(_activeSpellCharId, c->hitPointsMax - c->hitPointsCur);
+}
+
+void EoBCoreEngine::spellCallback_start_layOnHands() {
+ modifyCharacterHitpoints(_activeSpellCharId, _characters[_openBookChar].level[0] << 1);
+}
+
+void EoBCoreEngine::spellCallback_start_turnUndead() {
+ uint16 bl = calcNewBlockPosition(_currentBlock, _currentDirection);
+ if (!(_levelBlockProperties[bl].flags & 7))
+ return;
+
+ int cl = _openBookCasterLevel ? _openBookCasterLevel : getClericPaladinLevel(_openBookChar);
+ int r = rollDice(1, 20);
+ bool hit = false;
+
+ for (const int16 *m = findBlockMonsters(bl, 4, 4, 1, 1); *m != -1; m++) {
+ if ((_monsterProps[_monsters[*m].type].typeFlags & 4) && !(_monsters[*m].flags & 0x10)) {
+ _preventMonsterFlash = true;
+ _monsters[*m].flags |= 0x10;
+ hit |= turnUndeadHit(&_monsters[*m], r, cl);
+ }
+ }
+
+ if (hit) {
+ turnUndeadAutoHit();
+ snd_playSoundEffect(95);
+ updateAllMonsterShapes();
+ }
+
+ _preventMonsterFlash = false;
+}
+
+bool EoBCoreEngine::spellCallback_end_monster_lightningBolt(void *obj) {
+ EoBFlyingObject *fo = (EoBFlyingObject *)obj;
+ return magicObjectDamageHit(fo, 0, 0, 12, 1);
+}
+
+bool EoBCoreEngine::spellCallback_end_monster_fireball1(void *obj) {
+ EoBFlyingObject *fo = (EoBFlyingObject *)obj;
+ bool res = false;
+ if (_partyEffectFlags & 0x20000) {
+ res = magicObjectDamageHit(fo, 4, 10, 6, 0);
+ if (res) {
+ gui_drawAllCharPortraitsWithStats();
+ _partyEffectFlags &= ~0x20000;
+ }
+ } else {
+ res = magicObjectDamageHit(fo, 12, 10, 6, 0);
+ }
+ return res;
+}
+
+bool EoBCoreEngine::spellCallback_end_monster_fireball2(void *obj) {
+ EoBFlyingObject *fo = (EoBFlyingObject *)obj;
+ return magicObjectDamageHit(fo, 0, 0, 18, 0);
+}
+
+bool EoBCoreEngine::spellCallback_end_monster_deathSpell(void *obj) {
+ EoBFlyingObject *fo = (EoBFlyingObject *)obj;
+ if (fo->curBlock != _currentBlock)
+ return false;
+
+ int numDest = rollDice(1, 4);
+ _txt->printMessage(_magicStrings2[2]);
+ for (int d = findFirstCharacterSpellTarget(); d != -1 && numDest; d = findNextCharacterSpellTarget(d)) {
+ if (_characters[d].level[0] < 8) {
+ inflictCharacterDamage(d, 300);
+ numDest--;
+ }
+ }
+
+ return true;
+}
+
+bool EoBCoreEngine::spellCallback_end_monster_disintegrate(void *obj) {
+ EoBFlyingObject *fo = (EoBFlyingObject *)obj;
+ if (fo->curBlock != _currentBlock)
+ return false;
+
+ int d = findFirstCharacterSpellTarget();
+ if (d != -1) {
+ if (!charDeathSavingThrow(d, 1)) {
+ inflictCharacterDamage(d, 300);
+ _txt->printMessage(_magicStrings2[1], -1, _characters[d].name);
+ }
+ }
+
+ return true;
+}
+
+bool EoBCoreEngine::spellCallback_end_monster_causeCriticalWounds(void *obj) {
+ EoBFlyingObject *fo = (EoBFlyingObject *)obj;
+ if (fo->curBlock != _currentBlock)
+ return false;
+
+ int d = findFirstCharacterSpellTarget();
+ if (d != -1) {
+ _txt->printMessage(_magicStrings2[3], -1, _characters[d].name);
+ inflictCharacterDamage(d, rollDice(3, 8, 3));
+ }
+
+ return true;
+}
+
+bool EoBCoreEngine::spellCallback_end_monster_fleshToStone(void *obj) {
+ EoBFlyingObject *fo = (EoBFlyingObject *)obj;
+ if (fo->curBlock != _currentBlock)
+ return false;
+
+ int d = findFirstCharacterSpellTarget();
+ while (d != -1) {
+ if (!charDeathSavingThrow(d, 2)) {
+ statusAttack(d, 8, _magicStrings2[4], 5, 0, 0, 1);
+ d = -1;
+ } else {
+ d = findNextCharacterSpellTarget(d);
+ }
+ }
+
+ return true;
+}
+
+} // End of namespace Kyra
+
+#endif // ENABLE_EOB
diff --git a/engines/kyra/module.mk b/engines/kyra/module.mk
index abd535ee29..21e3ba3dff 100644
--- a/engines/kyra/module.mk
+++ b/engines/kyra/module.mk
@@ -9,6 +9,7 @@ MODULE_OBJS := \
debugger.o \
detection.o \
gui.o \
+ gui_v1.o \
gui_lok.o \
gui_v2.o \
gui_hof.o \
@@ -72,8 +73,19 @@ MODULE_OBJS := \
vqa.o \
wsamovie.o
+KYRARPG_COMMON_OBJ = \
+ gui_rpg.o \
+ kyra_rpg.o \
+ saveload_rpg.o \
+ scene_rpg.o \
+ sprites_rpg.o \
+ staticres_rpg.o \
+ text_rpg.o \
+ timer_rpg.o
+
ifdef ENABLE_LOL
MODULE_OBJS += \
+ $(KYRARPG_COMMON_OBJ) \
gui_lol.o \
items_lol.o \
lol.o \
@@ -89,6 +101,30 @@ MODULE_OBJS += \
timer_lol.o
endif
+ifdef ENABLE_EOB
+ifndef ENABLE_LOL
+MODULE_OBJS += \
+ $(KYRARPG_COMMON_OBJ)
+endif
+MODULE_OBJS += \
+ chargen.o \
+ eobcommon.o \
+ eob.o \
+ darkmoon.o \
+ gui_eob.o \
+ items_eob.o \
+ magic_eob.o \
+ saveload_eob.o \
+ scene_eob.o \
+ screen_eob.o \
+ script_eob.o \
+ sequences_eob.o \
+ sequences_darkmoon.o \
+ sprites_eob.o \
+ staticres_eob.o \
+ timer_eob.o
+endif
+
# This module can be built as a plugin
ifeq ($(ENABLE_KYRA), DYNAMIC_PLUGIN)
PLUGIN := 1
diff --git a/engines/kyra/resource.cpp b/engines/kyra/resource.cpp
index a35ec3d81b..adb3063344 100644
--- a/engines/kyra/resource.cpp
+++ b/engines/kyra/resource.cpp
@@ -59,14 +59,14 @@ bool Resource::reset() {
if (!dir.exists() || !dir.isDirectory())
error("invalid game path '%s'", dir.getPath().c_str());
- if (_vm->game() == GI_KYRA1) {
+ if (_vm->game() == GI_KYRA1 || _vm->game() == GI_EOB1) {
// We only need kyra.dat for the demo.
if (_vm->gameFlags().isDemo && !_vm->gameFlags().isTalkie)
return true;
if (!_vm->gameFlags().isDemo && _vm->gameFlags().isTalkie) {
// List of files in the talkie version, which can never be unload.
- static const char * const list[] = {
+ static const char *const list[] = {
"ADL.PAK", "CHAPTER1.VRM", "COL.PAK", "FINALE.PAK", "INTRO1.PAK", "INTRO2.PAK",
"INTRO3.PAK", "INTRO4.PAK", "MISC.PAK", "SND.PAK", "STARTUP.PAK", "XMI.PAK",
"CAVE.APK", "DRAGON1.APK", "DRAGON2.APK", "LAGOON.APK", 0
@@ -84,7 +84,7 @@ bool Resource::reset() {
name.toUppercase();
// No PAK file
- if (name == "TWMUSIC.PAK")
+ if (name == "TWMUSIC.PAK" || name == "EYE.PAK")
continue;
// We need to only load the script archive for the language the user specified
@@ -122,15 +122,15 @@ bool Resource::reset() {
_files.add("installer", loadInstallerArchive("WESTWOOD", "%d", 0), 2, false);
if (!_vm->gameFlags().isTalkie && !_vm->gameFlags().isDemo) {
- static const char * const list[] = {
+ static const char *const list[] = {
"GENERAL.PAK", 0
};
loadProtectedFiles(list);
}
- } else {
+ } else if (_vm->game() != GI_EOB2) {
error("Unknown game id: %d", _vm->game());
- return false; // for compilers that don't support NORETURN
+ return false; // for compilers that don't support NORETURN
}
return true;
@@ -173,7 +173,7 @@ bool Resource::loadFileList(const Common::String &filedata) {
f->seek(filenameOffset, SEEK_SET);
uint8 buffer[13];
- f->read(buffer, sizeof(buffer)-1);
+ f->read(buffer, sizeof(buffer) - 1);
buffer[12] = 0;
f->seek(offset + 16, SEEK_SET);
@@ -189,7 +189,7 @@ bool Resource::loadFileList(const Common::String &filedata) {
} else if (!loadPakFile(filename)) {
delete f;
error("couldn't load file '%s'", filename.c_str());
- return false; // for compilers that don't support NORETURN
+ return false; // for compilers that don't support NORETURN
}
}
}
@@ -198,21 +198,21 @@ bool Resource::loadFileList(const Common::String &filedata) {
return true;
}
-bool Resource::loadFileList(const char * const *filelist, uint32 numFiles) {
+bool Resource::loadFileList(const char *const *filelist, uint32 numFiles) {
if (!filelist)
return false;
while (numFiles--) {
if (!loadPakFile(filelist[numFiles])) {
error("couldn't load file '%s'", filelist[numFiles]);
- return false; // for compilers that don't support NORETURN
+ return false; // for compilers that don't support NORETURN
}
}
return true;
}
-bool Resource::loadProtectedFiles(const char * const * list) {
+bool Resource::loadProtectedFiles(const char *const *list) {
for (uint i = 0; list[i]; ++i) {
Common::ArchiveMemberPtr file = _files.getMember(list[i]);
if (!file)
diff --git a/engines/kyra/resource.h b/engines/kyra/resource.h
index c2a697f18d..f2bc4e8146 100644
--- a/engines/kyra/resource.h
+++ b/engines/kyra/resource.h
@@ -35,6 +35,7 @@
#include "common/archive.h"
#include "kyra/kyra_v1.h"
+#include "kyra/darkmoon.h"
#include "kyra/lol.h"
#include "kyra/kyra_hof.h"
@@ -250,91 +251,490 @@ enum KyraResources {
k3ItemMagicTable,
k3ItemStringMap,
-#ifdef ENABLE_LOL
- kLolIngamePakFiles,
- kLolCharacterDefs,
- kLolIngameSfxFiles,
- kLolIngameSfxIndex,
- kLolMusicTrackMap,
- kLolIngameGMSfxIndex,
- kLolIngameMT32SfxIndex,
- kLolIngamePcSpkSfxIndex,
- kLolSpellProperties,
- kLolGameShapeMap,
- kLolSceneItemOffs,
- kLolCharInvIndex,
- kLolCharInvDefs,
- kLolCharDefsMan,
- kLolCharDefsWoman,
- kLolCharDefsKieran,
- kLolCharDefsAkshel,
- kLolExpRequirements,
- kLolMonsterModifiers,
- kLolMonsterShiftOffsets,
- kLolMonsterDirFlags,
- kLolMonsterScaleY,
- kLolMonsterScaleX,
- kLolMonsterScaleWH,
- kLolFlyingObjectShp,
- kLolInventoryDesc,
-
- kLolLevelShpList,
- kLolLevelDatList,
- kLolCompassDefs,
- kLolItemPrices,
- kLolStashSetup,
-
- kLolDscUnk1,
- kLolDscShapeIndex,
- kLolDscOvlMap,
- kLolDscScaleWidthData,
- kLolDscScaleHeightData,
- kLolDscX,
- kLolDscY,
- kLolDscTileIndex,
- kLolDscUnk2,
- kLolDscDoorShapeIndex,
- kLolDscDimData1,
- kLolDscDimData2,
- kLolDscBlockMap,
- kLolDscDimMap,
- kLolDscDoor1,
- kLolDscDoorScale,
- kLolDscDoor4,
- kLolDscDoorX,
- kLolDscDoorY,
- kLolDscOvlIndex,
- kLolDscBlockIndex,
-
- kLolScrollXTop,
- kLolScrollYTop,
- kLolScrollXBottom,
- kLolScrollYBottom,
-
- kLolButtonDefs,
- kLolButtonList1,
- kLolButtonList2,
- kLolButtonList3,
- kLolButtonList4,
- kLolButtonList5,
- kLolButtonList6,
- kLolButtonList7,
- kLolButtonList8,
-
- kLolLegendData,
- kLolMapCursorOvl,
- kLolMapStringId,
-
- kLolSpellbookAnim,
- kLolSpellbookCoords,
- kLolHealShapeFrames,
- kLolLightningDefs,
- kLolFireballCoords,
-
- kLolCredits,
-
- kLolHistory,
-#endif
+#if defined(ENABLE_EOB) || defined(ENABLE_LOL)
+ kRpgCommonMoreStrings,
+ kRpgCommonDscShapeIndex,
+ kRpgCommonDscX,
+ kRpgCommonDscTileIndex,
+ kRpgCommonDscUnk2,
+ kRpgCommonDscDoorShapeIndex,
+ kRpgCommonDscDimData1,
+ kRpgCommonDscDimData2,
+ kRpgCommonDscBlockMap,
+ kRpgCommonDscDimMap,
+ kRpgCommonDscDoorY2,
+ kRpgCommonDscDoorFrameY1,
+ kRpgCommonDscDoorFrameY2,
+ kRpgCommonDscDoorFrameIndex1,
+ kRpgCommonDscDoorFrameIndex2,
+ kRpgCommonDscBlockIndex,
+
+ kEoBBaseChargenStrings1,
+ kEoBBaseChargenStrings2,
+ kEoBBaseChargenStartLevels,
+ kEoBBaseChargenStatStrings,
+ kEoBBaseChargenRaceSexStrings,
+ kEoBBaseChargenClassStrings,
+ kEoBBaseChargenAlignmentStrings,
+ kEoBBaseChargenEnterGameStrings,
+ kEoBBaseChargenClassMinStats,
+ kEoBBaseChargenRaceMinStats,
+ kEoBBaseChargenRaceMaxStats,
+
+ kEoBBaseSaveThrowTable1,
+ kEoBBaseSaveThrowTable2,
+ kEoBBaseSaveThrowTable3,
+ kEoBBaseSaveThrowTable4,
+ kEoBBaseSaveThrwLvlIndex,
+ kEoBBaseSaveThrwModDiv,
+ kEoBBaseSaveThrwModExt,
+
+ kEoBBasePryDoorStrings,
+ kEoBBaseWarningStrings,
+
+ kEoBBaseItemSuffixStringsRings,
+ kEoBBaseItemSuffixStringsPotions,
+ kEoBBaseItemSuffixStringsWands,
+
+ kEoBBaseRipItemStrings,
+ kEoBBaseCursedString,
+ kEoBBaseEnchantedString,
+ kEoBBaseMagicObjectStrings,
+ kEoBBaseMagicObjectString5,
+ kEoBBasePatternSuffix,
+ kEoBBasePatternGrFix1,
+ kEoBBasePatternGrFix2,
+ kEoBBaseValidateArmorString,
+ kEoBBaseValidateCursedString,
+ kEoBBaseValidateNoDropString,
+ kEoBBasePotionStrings,
+ kEoBBaseWandStrings,
+ kEoBBaseItemMisuseStrings,
+
+ kEoBBaseTakenStrings,
+ kEoBBasePotionEffectStrings,
+
+ kEoBBaseYesNoStrings,
+ kEoBBaseNpcMaxStrings,
+ kEoBBaseOkStrings,
+ kEoBBaseNpcJoinStrings,
+ kEoBBaseCancelStrings,
+ kEoBBaseAbortStrings,
+
+ kEoBBaseMenuStringsMain,
+ kEoBBaseMenuStringsSaveLoad,
+ kEoBBaseMenuStringsOnOff,
+ kEoBBaseMenuStringsSpells,
+ kEoBBaseMenuStringsRest,
+ kEoBBaseMenuStringsDrop,
+ kEoBBaseMenuStringsExit,
+ kEoBBaseMenuStringsStarve,
+ kEoBBaseMenuStringsScribe,
+ kEoBBaseMenuStringsDrop2,
+ kEoBBaseMenuStringsHead,
+ kEoBBaseMenuStringsPoison,
+ kEoBBaseMenuStringsMgc,
+ kEoBBaseMenuStringsPrefs,
+ kEoBBaseMenuStringsRest2,
+ kEoBBaseMenuStringsRest3,
+ kEoBBaseMenuStringsRest4,
+ kEoBBaseMenuStringsDefeat,
+ kEoBBaseMenuStringsTransfer,
+ kEoBBaseMenuStringsSpec,
+ kEoBBaseMenuStringsSpellNo,
+ kEoBBaseMenuYesNoStrings,
+
+ kEoBBaseSpellLevelsMage,
+ kEoBBaseSpellLevelsCleric,
+ kEoBBaseNumSpellsCleric,
+ kEoBBaseNumSpellsWisAdj,
+ kEoBBaseNumSpellsPal,
+ kEoBBaseNumSpellsMage,
+
+ kEoBBaseCharGuiStringsHp,
+ kEoBBaseCharGuiStringsWp1,
+ kEoBBaseCharGuiStringsWp2,
+ kEoBBaseCharGuiStringsWr,
+ kEoBBaseCharGuiStringsSt1,
+ kEoBBaseCharGuiStringsSt2,
+ kEoBBaseCharGuiStringsIn,
+
+ kEoBBaseCharStatusStrings7,
+ kEoBBaseCharStatusStrings81,
+ kEoBBaseCharStatusStrings82,
+ kEoBBaseCharStatusStrings9,
+ kEoBBaseCharStatusStrings12,
+ kEoBBaseCharStatusStrings131,
+ kEoBBaseCharStatusStrings132,
+
+ kEoBBaseLevelGainStrings,
+ kEoBBaseExperienceTable0,
+ kEoBBaseExperienceTable1,
+ kEoBBaseExperienceTable2,
+ kEoBBaseExperienceTable3,
+ kEoBBaseExperienceTable4,
+
+ kEoBBaseClassModifierFlags,
+
+ kEoBBaseMonsterStepTable01,
+ kEoBBaseMonsterStepTable02,
+ kEoBBaseMonsterStepTable1,
+ kEoBBaseMonsterStepTable2,
+ kEoBBaseMonsterStepTable3,
+ kEoBBaseMonsterCloseAttPosTable1,
+ kEoBBaseMonsterCloseAttPosTable21,
+ kEoBBaseMonsterCloseAttPosTable22,
+ kEoBBaseMonsterCloseAttUnkTable,
+ kEoBBaseMonsterCloseAttChkTable1,
+ kEoBBaseMonsterCloseAttChkTable2,
+ kEoBBaseMonsterCloseAttDstTable1,
+ kEoBBaseMonsterCloseAttDstTable2,
+
+ kEoBBaseMonsterProximityTable,
+ kEoBBaseFindBlockMonstersTable,
+ kEoBBaseMonsterDirChangeTable,
+ kEoBBaseMonsterDistAttStrings,
+
+ kEoBBaseEncodeMonsterDefs,
+ kEoBBaseNpcPresets,
+
+ kEoBBaseWllFlagPreset,
+ kEoBBaseDscShapeCoords,
+
+ kEoBBaseDscDoorScaleOffs,
+ kEoBBaseDscDoorScaleMult1,
+ kEoBBaseDscDoorScaleMult2,
+ kEoBBaseDscDoorScaleMult3,
+ kEoBBaseDscDoorScaleMult4,
+ kEoBBaseDscDoorScaleMult5,
+ kEoBBaseDscDoorScaleMult6,
+ kEoBBaseDscDoorType5Offs,
+ kEoBBaseDscDoorXE,
+ kEoBBaseDscDoorY1,
+ kEoBBaseDscDoorY3,
+ kEoBBaseDscDoorY4,
+ kEoBBaseDscDoorY5,
+ kEoBBaseDscDoorY6,
+ kEoBBaseDscDoorY7,
+ kEoBBaseDscDoorCoordsExt,
+
+ kEoBBaseDscItemPosIndex,
+ kEoBBaseDscItemShpX,
+ kEoBBaseDscItemScaleIndex,
+ kEoBBaseDscItemTileIndex,
+ kEoBBaseDscItemShapeMap,
+
+ kEoBBaseDscMonsterFrmOffsTbl1,
+ kEoBBaseDscMonsterFrmOffsTbl2,
+
+ kEoBBaseInvSlotX,
+ kEoBBaseInvSlotY,
+ kEoBBaseSlotValidationFlags,
+
+ kEoBBaseProjectileWeaponTypes,
+ kEoBBaseWandTypes,
+
+ kEoBBaseDrawObjPosIndex,
+ kEoBBaseFlightObjFlipIndex,
+ kEoBBaseFlightObjShpMap,
+ kEoBBaseFlightObjSclIndex,
+
+ kEoBBaseDscTelptrShpCoords,
+
+ kEoBBasePortalSeqData,
+ kEoBBaseManDef,
+ kEoBBaseManWord,
+ kEoBBaseManPrompt,
+
+ kEoBBaseBookNumbers,
+ kEoBBaseMageSpellsList,
+ kEoBBaseClericSpellsList,
+ kEoBBaseSpellNames,
+ kEoBBaseMagicStrings1,
+ kEoBBaseMagicStrings2,
+ kEoBBaseMagicStrings3,
+ kEoBBaseMagicStrings4,
+ kEoBBaseMagicStrings6,
+ kEoBBaseMagicStrings7,
+ kEoBBaseMagicStrings8,
+
+ kEoBBaseExpObjectTlMode,
+ kEoBBaseExpObjectTblIndex,
+ kEoBBaseExpObjectShpStart,
+ kEoBBaseExpObjectTbl1,
+ kEoBBaseExpObjectTbl2,
+ kEoBBaseExpObjectTbl3,
+ kEoBBaseExpObjectY,
+
+ kEoBBaseSparkDefSteps,
+ kEoBBaseSparkDefSubSteps,
+ kEoBBaseSparkDefShift,
+ kEoBBaseSparkDefAdd,
+ kEoBBaseSparkDefX,
+ kEoBBaseSparkDefY,
+ kEoBBaseSparkOfFlags1,
+ kEoBBaseSparkOfFlags2,
+ kEoBBaseSparkOfShift,
+ kEoBBaseSparkOfX,
+ kEoBBaseSparkOfY,
+
+ kEoBBaseSpellProperties,
+ kEoBBaseMagicFlightProps,
+ kEoBBaseTurnUndeadEffect,
+ kEoBBaseBurningHandsDest,
+ kEoBBaseConeOfColdDest1,
+ kEoBBaseConeOfColdDest2,
+ kEoBBaseConeOfColdDest3,
+ kEoBBaseConeOfColdDest4,
+ kEoBBaseConeOfColdGfxTbl,
+
+ kEoB1MainMenuStrings,
+ kEoB1BonusStrings,
+
+ kEoB1IntroFilesOpening,
+ kEoB1IntroFilesTower,
+ kEoB1IntroFilesOrb,
+ kEoB1IntroFilesWdEntry,
+ kEoB1IntroFilesKing,
+ kEoB1IntroFilesHands,
+ kEoB1IntroFilesWdExit,
+ kEoB1IntroFilesTunnel,
+ kEoB1IntroOpeningFrmDelay,
+ kEoB1IntroWdEncodeX,
+ kEoB1IntroWdEncodeY,
+ kEoB1IntroWdEncodeWH,
+ kEoB1IntroWdDsX,
+ kEoB1IntroWdDsY,
+ kEoB1IntroTvlX1,
+ kEoB1IntroTvlY1,
+ kEoB1IntroTvlX2,
+ kEoB1IntroTvlY2,
+ kEoB1IntroTvlW,
+ kEoB1IntroTvlH,
+
+ kEoB1DoorShapeDefs,
+ kEoB1DoorSwitchShapeDefs,
+ kEoB1DoorSwitchCoords,
+ kEoB1MonsterProperties,
+
+ kEoB1EnemyMageSpellList,
+ kEoB1EnemyMageSfx,
+ kEoB1BeholderSpellList,
+ kEoB1BeholderSfx,
+ kEoB1TurnUndeadString,
+
+ kEoB1CgaMappingDefault,
+ kEoB1CgaMappingAlt,
+ kEoB1CgaMappingInv,
+ kEoB1CgaMappingItemsL,
+ kEoB1CgaMappingItemsS,
+ kEoB1CgaMappingThrown,
+ kEoB1CgaMappingIcons,
+ kEoB1CgaMappingDeco,
+ kEoB1CgaLevelMappingIndex,
+ kEoB1CgaMappingLevel0,
+ kEoB1CgaMappingLevel1,
+ kEoB1CgaMappingLevel2,
+ kEoB1CgaMappingLevel3,
+ kEoB1CgaMappingLevel4,
+
+ kEoB1NpcShpData,
+ kEoB1NpcSubShpIndex1,
+ kEoB1NpcSubShpIndex2,
+ kEoB1NpcSubShpY,
+ kEoB1Npc0Strings,
+ kEoB1Npc11Strings,
+ kEoB1Npc12Strings,
+ kEoB1Npc21Strings,
+ kEoB1Npc22Strings,
+ kEoB1Npc31Strings,
+ kEoB1Npc32Strings,
+ kEoB1Npc4Strings,
+ kEoB1Npc5Strings,
+ kEoB1Npc6Strings,
+ kEoB1Npc7Strings,
+
+ kEoB2MainMenuStrings,
+
+ kEoB2TransferPortraitFrames,
+ kEoB2TransferConvertTable,
+ kEoB2TransferItemTable,
+ kEoB2TransferExpTable,
+ kEoB2TransferStrings1,
+ kEoB2TransferStrings2,
+ kEoB2TransferLabels,
+
+ kEoB2IntroStrings,
+ kEoB2IntroCPSFiles,
+ kEob2IntroAnimData00,
+ kEob2IntroAnimData01,
+ kEob2IntroAnimData02,
+ kEob2IntroAnimData03,
+ kEob2IntroAnimData04,
+ kEob2IntroAnimData05,
+ kEob2IntroAnimData06,
+ kEob2IntroAnimData07,
+ kEob2IntroAnimData08,
+ kEob2IntroAnimData09,
+ kEob2IntroAnimData10,
+ kEob2IntroAnimData11,
+ kEob2IntroAnimData12,
+ kEob2IntroAnimData13,
+ kEob2IntroAnimData14,
+ kEob2IntroAnimData15,
+ kEob2IntroAnimData16,
+ kEob2IntroAnimData17,
+ kEob2IntroAnimData18,
+ kEob2IntroAnimData19,
+ kEob2IntroAnimData20,
+ kEob2IntroAnimData21,
+ kEob2IntroAnimData22,
+ kEob2IntroAnimData23,
+ kEob2IntroAnimData24,
+ kEob2IntroAnimData25,
+ kEob2IntroAnimData26,
+ kEob2IntroAnimData27,
+ kEob2IntroAnimData28,
+ kEob2IntroAnimData29,
+ kEob2IntroAnimData30,
+ kEob2IntroAnimData31,
+ kEob2IntroAnimData32,
+ kEob2IntroAnimData33,
+ kEob2IntroAnimData34,
+ kEob2IntroAnimData35,
+ kEob2IntroAnimData36,
+ kEob2IntroAnimData37,
+ kEob2IntroAnimData38,
+ kEob2IntroAnimData39,
+ kEob2IntroAnimData40,
+ kEob2IntroAnimData41,
+ kEob2IntroAnimData42,
+ kEob2IntroAnimData43,
+ kEoB2IntroShapes00,
+ kEoB2IntroShapes01,
+ kEoB2IntroShapes04,
+ kEoB2IntroShapes07,
+
+ kEoB2FinaleStrings,
+ kEoB2CreditsData,
+ kEoB2FinaleCPSFiles,
+ kEob2FinaleAnimData00,
+ kEob2FinaleAnimData01,
+ kEob2FinaleAnimData02,
+ kEob2FinaleAnimData03,
+ kEob2FinaleAnimData04,
+ kEob2FinaleAnimData05,
+ kEob2FinaleAnimData06,
+ kEob2FinaleAnimData07,
+ kEob2FinaleAnimData08,
+ kEob2FinaleAnimData09,
+ kEob2FinaleAnimData10,
+ kEob2FinaleAnimData11,
+ kEob2FinaleAnimData12,
+ kEob2FinaleAnimData13,
+ kEob2FinaleAnimData14,
+ kEob2FinaleAnimData15,
+ kEob2FinaleAnimData16,
+ kEob2FinaleAnimData17,
+ kEob2FinaleAnimData18,
+ kEob2FinaleAnimData19,
+ kEob2FinaleAnimData20,
+ kEoB2FinaleShapes00,
+ kEoB2FinaleShapes03,
+ kEoB2FinaleShapes07,
+ kEoB2FinaleShapes09,
+ kEoB2FinaleShapes10,
+
+ kEoB2NpcShapeData,
+ kEoB2Npc1Strings,
+ kEoB2Npc2Strings,
+ kEoB2MonsterDustStrings,
+
+ kEoB2DreamSteps,
+ kEoB2KheldranStrings,
+ kEoB2HornStrings,
+ kEoB2HornSounds,
+
+ kEoB2WallOfForceDsX,
+ kEoB2WallOfForceDsY,
+ kEoB2WallOfForceNumW,
+ kEoB2WallOfForceNumH,
+ kEoB2WallOfForceShpId,
+
+ kLoLIngamePakFiles,
+ kLoLCharacterDefs,
+ kLoLIngameSfxFiles,
+ kLoLIngameSfxIndex,
+ kLoLMusicTrackMap,
+ kLoLIngameGMSfxIndex,
+ kLoLIngameMT32SfxIndex,
+ kLoLIngamePcSpkSfxIndex,
+ kLoLSpellProperties,
+ kLoLGameShapeMap,
+ kLoLSceneItemOffs,
+ kLoLCharInvIndex,
+ kLoLCharInvDefs,
+ kLoLCharDefsMan,
+ kLoLCharDefsWoman,
+ kLoLCharDefsKieran,
+ kLoLCharDefsAkshel,
+ kLoLExpRequirements,
+ kLoLMonsterModifiers,
+ kLoLMonsterShiftOffsets,
+ kLoLMonsterDirFlags,
+ kLoLMonsterScaleY,
+ kLoLMonsterScaleX,
+ kLoLMonsterScaleWH,
+ kLoLFlyingObjectShp,
+ kLoLInventoryDesc,
+
+ kLoLLevelShpList,
+ kLoLLevelDatList,
+ kLoLCompassDefs,
+ kLoLItemPrices,
+ kLoLStashSetup,
+
+ kLoLDscWalls,
+ kLoLDscOvlMap,
+ kLoLDscScaleWidthData,
+ kLoLDscScaleHeightData,
+ kLoLBaseDscY,
+
+ kLoLDscDoorScale,
+ kLoLDscDoor4,
+ kLoLDscDoorX,
+ kLoLDscDoorY,
+ kLoLDscOvlIndex,
+
+ kLoLScrollXTop,
+ kLoLScrollYTop,
+ kLoLScrollXBottom,
+ kLoLScrollYBottom,
+
+ kLoLButtonDefs,
+ kLoLButtonList1,
+ kLoLButtonList2,
+ kLoLButtonList3,
+ kLoLButtonList4,
+ kLoLButtonList5,
+ kLoLButtonList6,
+ kLoLButtonList7,
+ kLoLButtonList8,
+
+ kLoLLegendData,
+ kLoLMapCursorOvl,
+ kLoLMapStringId,
+
+ kLoLSpellbookAnim,
+ kLoLSpellbookCoords,
+ kLoLHealShapeFrames,
+ kLoLLightningDefs,
+ kLoLFireballCoords,
+
+ kLoLCredits,
+
+ kLoLHistory,
+#endif // ENABLE_EOB || ENABLE_LOL
kMaxResIDs
};
@@ -362,16 +762,23 @@ public:
const Room *loadRoomTable(int id, int &entries);
const HofSeqData *loadHofSequenceData(int id, int &entries);
const ItemAnimData_v1 *loadShapeAnimData_v1(int id, int &entries);
- const ItemAnimData_v2 *loadShapeAnimData_v2(int id, int &entries);
+ const ItemAnimDefinition *loadItemAnimDefinition(int id, int &entries);
+#if defined(ENABLE_EOB) || defined(ENABLE_LOL)
+ const uint16 *loadRawDataBe16(int id, int &entries);
+ const uint32 *loadRawDataBe32(int id, int &entries);
+#endif // (ENABLE_EOB || ENABLE_LOL)
#ifdef ENABLE_LOL
const LoLCharacter *loadCharData(int id, int &entries);
const SpellProperty *loadSpellData(int id, int &entries);
const CompassDef *loadCompassData(int id, int &entries);
const FlyingObjectShape *loadFlyingObjectData(int id, int &entries);
- const uint16 *loadRawDataBe16(int id, int &entries);
- const uint32 *loadRawDataBe32(int id, int &entries);
- const ButtonDef *loadButtonDefs(int id, int &entries);
+ const LoLButtonDef *loadButtonDefs(int id, int &entries);
#endif // ENABLE_LOL
+#ifdef ENABLE_EOB
+ const DarkMoonAnimCommand *loadEoB2SeqData(int id, int &entries);
+ const DarkMoonShapeDef *loadEoB2ShapeData(int id, int &entries);
+ const EoBCharacter *loadEoBNpcData(int id, int &entries);
+#endif // ENABLE_EOB
// use '-1' to prefetch/unload all ids
// prefetchId retruns false if only on of the resources
@@ -390,6 +797,7 @@ private:
const FileType *getFiletype(int type);
const void *getData(int id, int requesttype, int &size);
+ bool loadDummy(Common::SeekableReadStream &stream, void *&ptr, int &size);
bool loadStringTable(Common::SeekableReadStream &stream, void *&ptr, int &size);
bool loadRawData(Common::SeekableReadStream &stream, void *&ptr, int &size);
bool loadShapeTable(Common::SeekableReadStream &stream, void *&ptr, int &size);
@@ -397,17 +805,25 @@ private:
bool loadRoomTable(Common::SeekableReadStream &stream, void *&ptr, int &size);
bool loadHofSequenceData(Common::SeekableReadStream &stream, void *&ptr, int &size);
bool loadShapeAnimData_v1(Common::SeekableReadStream &stream, void *&ptr, int &size);
- bool loadShapeAnimData_v2(Common::SeekableReadStream &stream, void *&ptr, int &size);
+ bool loadItemAnimDefinition(Common::SeekableReadStream &stream, void *&ptr, int &size);
+#if defined(ENABLE_EOB) || defined(ENABLE_LOL)
+ bool loadRawDataBe16(Common::SeekableReadStream &stream, void *&ptr, int &size);
+ bool loadRawDataBe32(Common::SeekableReadStream &stream, void *&ptr, int &size);
+#endif // (ENABLE_LOL || ENABLE_EOB)
#ifdef ENABLE_LOL
bool loadCharData(Common::SeekableReadStream &stream, void *&ptr, int &size);
bool loadSpellData(Common::SeekableReadStream &stream, void *&ptr, int &size);
bool loadCompassData(Common::SeekableReadStream &stream, void *&ptr, int &size);
bool loadFlyingObjectData(Common::SeekableReadStream &stream, void *&ptr, int &size);
- bool loadRawDataBe16(Common::SeekableReadStream &stream, void *&ptr, int &size);
- bool loadRawDataBe32(Common::SeekableReadStream &stream, void *&ptr, int &size);
bool loadButtonDefs(Common::SeekableReadStream &stream, void *&ptr, int &size);
#endif // ENABLE_LOL
+#ifdef ENABLE_EOB
+ bool loadEoB2SeqData(Common::SeekableReadStream &stream, void *&ptr, int &size);
+ bool loadEoB2ShapeData(Common::SeekableReadStream &stream, void *&ptr, int &size);
+ bool loadEoBNpcData(Common::SeekableReadStream &stream, void *&ptr, int &size);
+#endif // ENABLE_EOB
+ void freeDummy(void *&ptr, int &size);
void freeRawData(void *&ptr, int &size);
void freeStringTable(void *&ptr, int &size);
void freeShapeTable(void *&ptr, int &size);
@@ -415,16 +831,23 @@ private:
void freeRoomTable(void *&ptr, int &size);
void freeHofSequenceData(void *&ptr, int &size);
void freeHofShapeAnimDataV1(void *&ptr, int &size);
- void freeHofShapeAnimDataV2(void *&ptr, int &size);
+ void freeItemAnimDefinition(void *&ptr, int &size);
+#if defined(ENABLE_EOB) || defined(ENABLE_LOL)
+ void freeRawDataBe16(void *&ptr, int &size);
+ void freeRawDataBe32(void *&ptr, int &size);
+#endif // (ENABLE_EOB || ENABLE_LOL)
#ifdef ENABLE_LOL
void freeCharData(void *&ptr, int &size);
void freeSpellData(void *&ptr, int &size);
void freeCompassData(void *&ptr, int &size);
void freeFlyingObjectData(void *&ptr, int &size);
- void freeRawDataBe16(void *&ptr, int &size);
- void freeRawDataBe32(void *&ptr, int &size);
void freeButtonDefs(void *&ptr, int &size);
#endif // ENABLE_LOL
+#ifdef ENABLE_EOB
+ void freeEoB2SeqData(void *&ptr, int &size);
+ void freeEoB2ShapeData(void *&ptr, int &size);
+ void freeEoBNpcData(void *&ptr, int &size);
+#endif // ENABLE_EOB
enum ResTypes {
kStringList = 0,
@@ -435,15 +858,19 @@ private:
k2SeqData = 5,
k2ShpAnimDataV1 = 6,
- k2ShpAnimDataV2 = 7,
-
- kLolCharData = 8,
- kLolSpellData = 9,
- kLolCompassData = 10,
- kLolFlightShpData = 11,
- kLolButtonData = 12,
- kLolRawDataBe16 = 13,
- kLolRawDataBe32 = 14
+ k2ItemAnimDefinition = 7,
+
+ kLoLCharData = 8,
+ kLoLSpellData = 9,
+ kLoLCompassData = 10,
+ kLoLFlightShpData = 11,
+ kLoLButtonData = 12,
+ kRawDataBe16 = 13,
+ kRawDataBe32 = 14,
+
+ kEoB2SequenceData = 15,
+ kEoB2ShapeData = 16,
+ kEoBNpcData = 17
};
struct FileType {
diff --git a/engines/kyra/resource_intern.cpp b/engines/kyra/resource_intern.cpp
index 482bd1a5d6..6f7591ccf1 100644
--- a/engines/kyra/resource_intern.cpp
+++ b/engines/kyra/resource_intern.cpp
@@ -37,11 +37,11 @@ PlainArchive::PlainArchive(Common::ArchiveMemberPtr file)
: _file(file), _files() {
}
-bool PlainArchive::hasFile(const Common::String &name) {
+bool PlainArchive::hasFile(const Common::String &name) const {
return (_files.find(name) != _files.end());
}
-int PlainArchive::listMembers(Common::ArchiveMemberList &list) {
+int PlainArchive::listMembers(Common::ArchiveMemberList &list) const {
int count = 0;
for (FileMap::const_iterator i = _files.begin(); i != _files.end(); ++i) {
@@ -52,7 +52,7 @@ int PlainArchive::listMembers(Common::ArchiveMemberList &list) {
return count;
}
-Common::ArchiveMemberPtr PlainArchive::getMember(const Common::String &name) {
+const Common::ArchiveMemberPtr PlainArchive::getMember(const Common::String &name) const {
if (!hasFile(name))
return Common::ArchiveMemberPtr();
@@ -92,11 +92,11 @@ TlkArchive::~TlkArchive() {
delete[] _fileEntries;
}
-bool TlkArchive::hasFile(const Common::String &name) {
+bool TlkArchive::hasFile(const Common::String &name) const {
return (findFile(name) != 0);
}
-int TlkArchive::listMembers(Common::ArchiveMemberList &list) {
+int TlkArchive::listMembers(Common::ArchiveMemberList &list) const {
uint count = 0;
for (; count < _entryCount; ++count) {
@@ -107,7 +107,7 @@ int TlkArchive::listMembers(Common::ArchiveMemberList &list) {
return count;
}
-Common::ArchiveMemberPtr TlkArchive::getMember(const Common::String &name) {
+const Common::ArchiveMemberPtr TlkArchive::getMember(const Common::String &name) const {
if (!hasFile(name))
return Common::ArchiveMemberPtr();
@@ -186,11 +186,11 @@ CachedArchive::~CachedArchive() {
_files.clear();
}
-bool CachedArchive::hasFile(const Common::String &name) {
+bool CachedArchive::hasFile(const Common::String &name) const {
return (_files.find(name) != _files.end());
}
-int CachedArchive::listMembers(Common::ArchiveMemberList &list) {
+int CachedArchive::listMembers(Common::ArchiveMemberList &list) const {
int count = 0;
for (FileMap::const_iterator i = _files.begin(); i != _files.end(); ++i) {
@@ -201,7 +201,7 @@ int CachedArchive::listMembers(Common::ArchiveMemberList &list) {
return count;
}
-Common::ArchiveMemberPtr CachedArchive::getMember(const Common::String &name) {
+const Common::ArchiveMemberPtr CachedArchive::getMember(const Common::String &name) const {
if (!hasFile(name))
return Common::ArchiveMemberPtr();
@@ -254,6 +254,8 @@ bool ResLoaderPak::isLoadable(const Common::String &filename, Common::SeekableRe
offset = SWAP_BYTES_32(offset);
}
+ int32 firstOffset = offset;
+
Common::String file;
while (!stream.eos()) {
// The start offset of a file should never be in the filelist
@@ -276,7 +278,7 @@ bool ResLoaderPak::isLoadable(const Common::String &filename, Common::SeekableRe
firstFile = false;
offset = switchEndian ? stream.readUint32BE() : stream.readUint32LE();
- if (!offset || offset == filesize)
+ if (!offset || offset == filesize || firstOffset == stream.pos())
break;
}
@@ -297,6 +299,7 @@ Common::Archive *ResLoaderPak::load(Common::ArchiveMemberPtr memberFile, Common:
bool firstFile = true;
startoffset = stream.readUint32LE();
+ int32 firstOffset = startoffset;
if (startoffset > filesize || startoffset < 0) {
switchEndian = true;
startoffset = SWAP_BYTES_32(startoffset);
@@ -330,12 +333,12 @@ Common::Archive *ResLoaderPak::load(Common::ArchiveMemberPtr memberFile, Common:
firstFile = false;
endoffset = switchEndian ? stream.readUint32BE() : stream.readUint32LE();
- if (endoffset < 0) {
+ if (endoffset < 0 && stream.pos() != firstOffset) {
warning("PAK file '%s' is corrupted", memberFile->getDisplayName().c_str());
return 0;
}
- if (!endoffset)
+ if (!endoffset || stream.pos() == firstOffset)
endoffset = filesize;
if (startoffset != endoffset)
@@ -353,7 +356,7 @@ Common::Archive *ResLoaderPak::load(Common::ArchiveMemberPtr memberFile, Common:
const uint32 magic = stream.readUint32BE();
- if (magic != MKTAG('S','C','V','M'))
+ if (magic != MKTAG('S', 'C', 'V', 'M'))
error("LINKLIST file does not contain 'SCVM' header");
const uint32 links = stream.readUint32BE();
@@ -388,10 +391,10 @@ bool ResLoaderInsMalcolm::isLoadable(const Common::String &filename, Common::See
stream.seek(3, SEEK_SET);
int32 size = stream.readUint32LE();
- if (size+7 > stream.size())
+ if (size + 7 > stream.size())
return false;
- stream.seek(size+5, SEEK_SET);
+ stream.seek(size + 5, SEEK_SET);
uint8 buffer[2];
stream.read(&buffer, 2);
@@ -493,7 +496,7 @@ public:
void advSrcBitsBy1();
void advSrcBitsByIndex(uint8 newIndex);
- uint8 getKeyLower() { return _key & 0xff; }
+ uint8 getKeyLower() const { return _key & 0xff; }
void setIndex(uint8 index) { _index = index; }
uint16 getKeyMasked(uint8 newIndex);
uint16 keyMaskedAlign(uint16 val);
@@ -697,7 +700,7 @@ bool FileExpander::process(uint8 *dst, const uint8 *src, uint32 outsize, uint32
_src->copyBytes(d);
postprocess = false;
needrefresh = true;
- } else if (mode == 0){
+ } else if (mode == 0) {
uint8 *d2 = _tables[0];
memset(d2, 8, 144);
memset(d2 + 144, 9, 112);
@@ -841,7 +844,7 @@ void FileExpander::generateTables(uint8 srcIndex, uint8 dstIndex, uint8 dstIndex
cnt--;
s = tbl1 + cnt;
d = &_tables16[2][cnt];
- uint16 * bt = (uint16 *)tbl3;
+ uint16 *bt = (uint16 *)tbl3;
uint16 inc = 0;
uint16 cnt2 = 0;
diff --git a/engines/kyra/resource_intern.h b/engines/kyra/resource_intern.h
index 03c9d871e8..9d9574d823 100644
--- a/engines/kyra/resource_intern.h
+++ b/engines/kyra/resource_intern.h
@@ -49,9 +49,9 @@ public:
Entry getFileEntry(const Common::String &name) const;
// Common::Archive API implementation
- bool hasFile(const Common::String &name);
- int listMembers(Common::ArchiveMemberList &list);
- Common::ArchiveMemberPtr getMember(const Common::String &name);
+ bool hasFile(const Common::String &name) const;
+ int listMembers(Common::ArchiveMemberList &list) const;
+ const Common::ArchiveMemberPtr getMember(const Common::String &name) const;
Common::SeekableReadStream *createReadStreamForMember(const Common::String &name) const;
private:
typedef Common::HashMap<Common::String, Entry, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> FileMap;
@@ -65,9 +65,9 @@ public:
TlkArchive(Common::ArchiveMemberPtr file, uint16 entryCount, const uint32 *fileEntries);
~TlkArchive();
- bool hasFile(const Common::String &name);
- int listMembers(Common::ArchiveMemberList &list);
- Common::ArchiveMemberPtr getMember(const Common::String &name);
+ bool hasFile(const Common::String &name) const;
+ int listMembers(Common::ArchiveMemberList &list) const;
+ const Common::ArchiveMemberPtr getMember(const Common::String &name) const;
Common::SeekableReadStream *createReadStreamForMember(const Common::String &name) const;
private:
Common::ArchiveMemberPtr _file;
@@ -92,9 +92,9 @@ public:
CachedArchive(const FileInputList &files);
~CachedArchive();
- bool hasFile(const Common::String &name);
- int listMembers(Common::ArchiveMemberList &list);
- Common::ArchiveMemberPtr getMember(const Common::String &name);
+ bool hasFile(const Common::String &name) const;
+ int listMembers(Common::ArchiveMemberList &list) const;
+ const Common::ArchiveMemberPtr getMember(const Common::String &name) const;
Common::SeekableReadStream *createReadStreamForMember(const Common::String &name) const;
private:
struct Entry {
diff --git a/engines/kyra/saveload.cpp b/engines/kyra/saveload.cpp
index 42c5d3e8a8..41ba1e5e50 100644
--- a/engines/kyra/saveload.cpp
+++ b/engines/kyra/saveload.cpp
@@ -29,7 +29,7 @@
#include "graphics/thumbnail.h"
#include "graphics/surface.h"
-#define CURRENT_SAVE_VERSION 16
+#define CURRENT_SAVE_VERSION 17
#define GF_FLOPPY (1 << 0)
#define GF_TALKIE (1 << 1)
@@ -44,22 +44,25 @@ KyraEngine_v1::kReadSaveHeaderError KyraEngine_v1::readSaveHeader(Common::Seekab
header.flags = 0;
header.thumbnail = 0;
- if (type == MKTAG('K','Y','R','A') || type == MKTAG('A','R','Y','K')) { // old Kyra1 header ID
+ if (type == MKTAG('K', 'Y', 'R', 'A') || type == MKTAG('A', 'R', 'Y', 'K')) { // old Kyra1 header ID
header.gameID = GI_KYRA1;
header.oldHeader = true;
- } else if (type == MKTAG('H','O','F','S')) { // old Kyra2 header ID
+ } else if (type == MKTAG('H', 'O', 'F', 'S')) { // old Kyra2 header ID
header.gameID = GI_KYRA2;
header.oldHeader = true;
- } else if (type == MKTAG('W','W','S','V')) {
+ } else if (type == MKTAG('W', 'W', 'S', 'V')) {
header.gameID = in->readByte();
} else {
// try checking for original save header
- const int descriptionSize[2] = { 30, 80 };
+ const int descriptionSize[3] = { 30, 80, 60 };
char descriptionBuffer[81];
bool saveOk = false;
for (uint i = 0; i < ARRAYSIZE(descriptionSize) && !saveOk; ++i) {
+ if (in->size() < descriptionSize[i] + 6)
+ continue;
+
in->seek(0, SEEK_SET);
in->read(descriptionBuffer, descriptionSize[i]);
descriptionBuffer[descriptionSize[i]] = 0;
@@ -68,16 +71,26 @@ KyraEngine_v1::kReadSaveHeaderError KyraEngine_v1::readSaveHeader(Common::Seekab
type = in->readUint32BE();
header.version = in->readUint16LE();
- if (type == MKTAG('M','B','L','3') && header.version == 100) {
+ if (type == MKTAG('M', 'B', 'L', '3') && header.version == 100) {
saveOk = true;
header.description = descriptionBuffer;
header.gameID = GI_KYRA2;
break;
- } else if (type == MKTAG('M','B','L','4') && header.version == 102) {
+ } else if (type == MKTAG('M', 'B', 'L', '4') && header.version == 102) {
saveOk = true;
header.description = descriptionBuffer;
header.gameID = GI_KYRA3;
break;
+ } else if (type == MKTAG('C','D','0','4')) {
+ header.version = in->readUint32BE();
+ // We don't check the minor version, since the original doesn't do that either and it isn't required.
+ if (header.version != MKTAG(' ','C','D','1'))
+ continue;
+ saveOk = true;
+ header.description = descriptionBuffer;
+ header.gameID = GI_LOL;
+ in->seek(6, SEEK_CUR);
+ break;
}
}
@@ -91,7 +104,7 @@ KyraEngine_v1::kReadSaveHeaderError KyraEngine_v1::readSaveHeader(Common::Seekab
}
header.version = in->readUint32BE();
- if (header.version > CURRENT_SAVE_VERSION || (header.oldHeader && header.version > 8) || (type == MKTAG('A','R','Y','K') && header.version > 3))
+ if (header.version > CURRENT_SAVE_VERSION || (header.oldHeader && header.version > 8) || (type == MKTAG('A', 'R', 'Y', 'K') && header.version > 3))
return kRSHEInvalidVersion;
// Versions prior to 9 are using a fixed length description field
@@ -122,7 +135,7 @@ KyraEngine_v1::kReadSaveHeaderError KyraEngine_v1::readSaveHeader(Common::Seekab
return ((in->err() || in->eos()) ? kRSHEIoError : kRSHENoError);
}
-Common::SeekableReadStream *KyraEngine_v1::openSaveForReading(const char *filename, SaveHeader &header) {
+Common::SeekableReadStream *KyraEngine_v1::openSaveForReading(const char *filename, SaveHeader &header, bool checkID) {
Common::SeekableReadStream *in = 0;
if (!(in = _saveFileMan->openForLoading(filename)))
return 0;
@@ -142,7 +155,7 @@ Common::SeekableReadStream *KyraEngine_v1::openSaveForReading(const char *filena
if (!header.originalSave) {
if (!header.oldHeader) {
- if (header.gameID != _flags.gameID) {
+ if (header.gameID != _flags.gameID && checkID) {
warning("Trying to load game state from other game (save game: %u, running game: %u)", header.gameID, _flags.gameID);
delete in;
return 0;
@@ -182,10 +195,10 @@ Common::WriteStream *KyraEngine_v1::openSaveForWriting(const char *filename, con
}
// Savegame version
- out->writeUint32BE(MKTAG('W','W','S','V'));
+ out->writeUint32BE(MKTAG('W', 'W', 'S', 'V'));
out->writeByte(_flags.gameID);
out->writeUint32BE(CURRENT_SAVE_VERSION);
- out->write(saveName, strlen(saveName)+1);
+ out->write(saveName, strlen(saveName) + 1);
if (_flags.isTalkie)
out->writeUint32BE(GF_TALKIE);
else if (_flags.platform == Common::kPlatformFMTowns || _flags.platform == Common::kPlatformPC98)
diff --git a/engines/kyra/saveload_eob.cpp b/engines/kyra/saveload_eob.cpp
new file mode 100644
index 0000000000..f7d7d95b57
--- /dev/null
+++ b/engines/kyra/saveload_eob.cpp
@@ -0,0 +1,909 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifdef ENABLE_EOB
+
+#include "kyra/resource.h"
+#include "kyra/script_eob.h"
+
+#include "common/system.h"
+#include "common/savefile.h"
+#include "common/substream.h"
+#include "common/config-manager.h"
+#include "common/translation.h"
+
+#include "gui/message.h"
+
+namespace Kyra {
+
+Common::Error EoBCoreEngine::loadGameState(int slot) {
+ // Special slot id -1 for EOB1 party transfer
+ const char *fileName = (slot == -1) ? _savegameFilename.c_str() : getSavegameFilename(slot);
+
+ SaveHeader header;
+ Common::InSaveFile *saveFile = openSaveForReading(fileName, header, (slot != -1));
+ if (!saveFile)
+ return Common::Error(Common::kReadingFailed);
+
+ Common::SeekableSubReadStreamEndian in(saveFile, saveFile->pos(), saveFile->size(), !header.originalSave, DisposeAfterUse::YES);
+ _loading = true;
+
+ if (slot != -1)
+ _screen->fadeToBlack(10);
+
+ for (int i = 0; i < 6; i++) {
+ EoBCharacter *c = &_characters[i];
+ c->id = in.readByte();
+ c->flags = in.readByte();
+ in.read(c->name, 11);
+ c->strengthCur = in.readSByte();
+ c->strengthMax = in.readSByte();
+ c->strengthExtCur = in.readSByte();
+ c->strengthExtMax = in.readSByte();
+ c->intelligenceCur = in.readSByte();
+ c->intelligenceMax = in.readSByte();
+ c->wisdomCur = in.readSByte();
+ c->wisdomMax = in.readSByte();
+ c->dexterityCur = in.readSByte();
+ c->dexterityMax = in.readSByte();
+ c->constitutionCur = in.readSByte();
+ c->constitutionMax = in.readSByte();
+ c->charismaCur = in.readSByte();
+ c->charismaMax = in.readSByte();
+ c->hitPointsCur = in.readSint16BE();
+ c->hitPointsMax = in.readSint16BE();
+ c->armorClass = in.readSByte();
+ c->disabledSlots = in.readByte();
+ c->raceSex = in.readByte();
+ c->cClass = in.readByte();
+ c->alignment = in.readByte();
+ c->portrait = in.readSByte();
+ if (slot == -1 && c->portrait < 0)
+ c->portrait = -c->portrait + 43;
+ c->food = in.readByte();
+ in.read(c->level, 3);
+ for (int ii = 0; ii < 3; ii++)
+ c->experience[ii] = in.readUint32BE();
+ delete[] c->faceShape;
+ c->faceShape = 0;
+ in.read(c->mageSpells, 80);
+ in.read(c->clericSpells, 80);
+ c->mageSpellsAvailableFlags = in.readUint32BE();
+ for (int ii = 0; ii < 27; ii++)
+ c->inventory[ii] = in.readSint16BE();
+ uint32 ct = _system->getMillis();
+ for (int ii = 0; ii < 10; ii++) {
+ c->timers[ii] = in.readUint32BE();
+ if (c->timers[ii])
+ c->timers[ii] += ct;
+ }
+ in.read(c->events, 10);
+ in.read(c->effectsRemainder, 4);
+ c->effectFlags = in.readUint32BE();
+ c->damageTaken = in.readByte();
+ in.read(c->slotStatus, 5);
+ }
+
+ setupCharacterTimers();
+
+ _screen->loadShapeSetBitmap("CHARGENA", 3, 3);
+ for (int i = 0; i < 6; i++) {
+ EoBCharacter *c = &_characters[i];
+ if (!c->flags || c->portrait < 0)
+ continue;
+ c->faceShape = _screen->encodeShape((c->portrait % 10) << 2, (c->portrait / 10) << 5, 4, 32, true, _cgaMappingDefault);
+ }
+
+ _screen->loadShapeSetBitmap(_flags.gameID == GI_EOB2 ? "OUTPORTS" : "OUTTAKE", 3, 3);
+ for (int i = 0; i < 6; i++) {
+ EoBCharacter *c = &_characters[i];
+ if (!c->flags || c->portrait >= 0)
+ continue;
+ c->faceShape = _screen->encodeShape((-(c->portrait + 1)) << 2, _flags.gameID == GI_EOB2 ? 0 : 160, 4, 32, true, _cgaMappingDefault);
+ }
+ _screen->_curPage = 0;
+
+ if (slot == -1) {
+ // Skip all settings which aren't necessary for party transfer.
+ // Jump directly to the items list.
+ in.skip(108);
+ } else {
+ _currentLevel = in.readByte();
+ _currentSub = in.readSByte();
+ _currentBlock = in.readUint16BE();
+ _currentDirection = in.readUint16BE();
+ _itemInHand = in.readSint16BE();
+ _hasTempDataFlags = in.readUint32BE();
+ _partyEffectFlags = in.readUint32BE();
+
+ _updateFlags = in.readUint16BE();
+ _compassDirection = in.readUint16BE();
+ _currentControlMode = in.readUint16BE();
+ _updateCharNum = in.readSint16BE();
+ _openBookSpellLevel = in.readSByte();
+ _openBookSpellSelectedItem = in.readSByte();
+ _openBookSpellListOffset = in.readSByte();
+ _openBookChar = in.readByte();
+ _openBookType = in.readByte();
+ _openBookCharBackup = in.readByte();
+ _openBookTypeBackup = in.readByte();
+ _activeSpellCharId = in.readByte();
+ _activeSpellCharacterPos = in.readByte();
+ _activeSpell = in.readByte();
+ _returnAfterSpellCallback = in.readByte() ? true : false;
+
+ _inf->loadState(in);
+ }
+
+ for (int i = 0; i < 600; i++) {
+ EoBItem *t = &_items[i];
+ t->nameUnid = in.readByte();
+ t->nameId = in.readByte();
+ t->flags = in.readByte();
+ t->icon = in.readSByte();
+ t->type = in.readSByte();
+ t->pos = in.readSByte();
+ t->block = in.readSint16BE();
+ t->next = in.readSint16BE();
+ t->prev = in.readSint16BE();
+ t->level = in.readByte();
+ t->value = in.readSByte();
+ }
+
+ // No more data needed for party transfer
+ if (slot == -1) {
+ _loading = false;
+ return Common::kNoError;
+ }
+
+ for (int i = 51; i < 65; i++) {
+ EoBItemType *t = &_itemTypes[i];
+ t->invFlags = in.readUint16BE();
+ t->handFlags = in.readUint16BE();
+ t->armorClass = in.readSByte();
+ t->allowedClasses = in.readSByte();
+ t->requiredHands = in.readSByte();
+ t->dmgNumDiceS = in.readSByte();
+ t->dmgNumPipsS = in.readSByte();
+ t->dmgIncS = in.readSByte();
+ t->dmgNumDiceL = in.readSByte();
+ t->dmgNumPipsL = in.readSByte();
+ t->dmgIncL = in.readSByte();
+ t->unk1 = in.readByte();
+ t->extraProperties = in.readUint16BE();
+ }
+
+ for (int i = 0; i < 18; i++) {
+ if (!(_hasTempDataFlags & (1 << i)))
+ continue;
+
+ if (_lvlTempData[i]) {
+ delete[] _lvlTempData[i]->wallsXorData;
+ delete[] _lvlTempData[i]->flags;
+ releaseMonsterTempData(_lvlTempData[i]);
+ releaseFlyingObjectTempData(_lvlTempData[i]);
+ releaseWallOfForceTempData(_lvlTempData[i]);
+ delete _lvlTempData[i];
+ }
+
+ _lvlTempData[i] = new LevelTempData;
+ LevelTempData *l = _lvlTempData[i];
+ l->wallsXorData = new uint8[4096];
+ l->flags = new uint16[1024];
+ EoBMonsterInPlay *lm = new EoBMonsterInPlay[30];
+ l->monsters = lm;
+ EoBFlyingObject *lf = new EoBFlyingObject[_numFlyingObjects];
+ l->flyingObjects = lf;
+ WallOfForce *lw = new WallOfForce[5];
+ l->wallsOfForce = lw;
+
+ in.read(l->wallsXorData, 4096);
+ for (int ii = 0; ii < 1024; ii++)
+ l->flags[ii] = in.readByte();
+
+ for (int ii = 0; ii < 30; ii++) {
+ EoBMonsterInPlay *m = &lm[ii];
+ m->type = in.readByte();
+ m->unit = in.readByte();
+ m->block = in.readUint16BE();
+ m->pos = in.readByte();
+ m->dir = in.readSByte();
+ m->animStep = in.readByte();
+ m->shpIndex = in.readByte();
+ m->mode = in.readSByte();
+ m->f_9 = in.readSByte();
+ m->curAttackFrame = in.readSByte();
+ m->spellStatusLeft = in.readSByte();
+ m->hitPointsMax = in.readSint16BE();
+ m->hitPointsCur = in.readSint16BE();
+ m->dest = in.readUint16BE();
+ m->randItem = in.readUint16BE();
+ m->fixedItem = in.readUint16BE();
+ m->flags = in.readByte();
+ m->idleAnimState = in.readByte();
+ m->curRemoteWeapon = in.readByte();
+ m->numRemoteAttacks = in.readByte();
+ m->palette = in.readSByte();
+ m->directionChanged = in.readByte();
+ m->stepsTillRemoteAttack = in.readByte();
+ m->sub = in.readByte();
+ }
+
+ for (int ii = 0; ii < _numFlyingObjects; ii++) {
+ EoBFlyingObject *m = &lf[ii];
+ m->enable = in.readByte();
+ m->objectType = in.readByte();
+ m->attackerId = in.readSint16BE();
+ m->item = in.readSint16BE();
+ m->curBlock = in.readUint16BE();
+ m->starting = in.readUint16BE();
+ m->u1 = in.readByte();
+ m->direction = in.readByte();
+ m->distance = in.readByte();
+ m->callBackIndex = in.readSByte();
+ m->curPos = in.readByte();
+ m->flags = in.readByte();
+ m->unused = in.readByte();
+ }
+
+ for (int ii = 0; ii < 5; ii++) {
+ WallOfForce *w = &lw[ii];
+ w->block = in.readUint16BE();
+ w->duration = in.readUint32BE();
+ }
+ }
+
+ loadLevel(_currentLevel, _currentSub);
+ _sceneUpdateRequired = true;
+ _screen->setFont(Screen::FID_6_FNT);
+
+ for (int i = 0; i < 6; i++) {
+ for (int ii = 0; ii < 10; ii++) {
+ if (_characters[i].events[ii] == -57)
+ spellCallback_start_trueSeeing();
+ }
+ }
+
+ _screen->setCurPage(0);
+ gui_drawPlayField(false);
+
+ if (_currentControlMode)
+ _screen->copyRegion(176, 0, 0, 0, 144, 168, 0, 5, Screen::CR_NO_P_CHECK);
+
+ _screen->setCurPage(0);
+ gui_drawAllCharPortraitsWithStats();
+ drawScene(1);
+
+ if (_updateFlags) {
+ _updateFlags = 0;
+ useMagicBookOrSymbol(_openBookChar, _openBookType);
+ }
+
+ _screen->copyRegion(0, 120, 0, 0, 176, 24, 0, _useHiResDithering ? 1 : 12, Screen::CR_NO_P_CHECK);
+
+ gui_toggleButtons();
+ setHandItem(_itemInHand);
+
+ while (!_screen->isMouseVisible())
+ _screen->showMouse();
+
+ _loading = false;
+ _screen->fadeFromBlack(20);
+ removeInputTop();
+
+ return Common::kNoError;
+}
+
+Common::Error EoBCoreEngine::saveGameStateIntern(int slot, const char *saveName, const Graphics::Surface *thumbnail) {
+ Common::String saveNameTmp;
+ const char *fileName = 0;
+
+ // Special slot id -1 to create final save for party transfer
+ if (slot == -1) {
+ _savegameFilename = _targetName + Common::String(".fin");
+ fileName = _savegameFilename.c_str();
+ saveNameTmp = _targetName + Common::String(" final");
+ saveNameTmp.toUppercase();
+ saveName = saveNameTmp.c_str();
+ } else {
+ fileName = getSavegameFilename(slot);
+ }
+
+ Common::OutSaveFile *out = openSaveForWriting(fileName, saveName, thumbnail);
+ if (!out)
+ return _saveFileMan->getError();
+
+ completeDoorOperations();
+ generateTempData();
+ advanceTimers(_restPartyElapsedTime);
+ _restPartyElapsedTime = 0;
+
+ for (int i = 0; i < 6; i++)
+ timerSpecialCharacterUpdate(0x30 + i);
+
+ for (int i = 0; i < 6; i++) {
+ EoBCharacter *c = &_characters[i];
+
+ out->writeByte(c->id);
+ out->writeByte(c->flags);
+ out->write(c->name, 11);
+ out->writeSByte(c->strengthCur);
+ out->writeSByte(c->strengthMax);
+ out->writeSByte(c->strengthExtCur);
+ out->writeSByte(c->strengthExtMax);
+ out->writeSByte(c->intelligenceCur);
+ out->writeSByte(c->intelligenceMax);
+ out->writeSByte(c->wisdomCur);
+ out->writeSByte(c->wisdomMax);
+ out->writeSByte(c->dexterityCur);
+ out->writeSByte(c->dexterityMax);
+ out->writeSByte(c->constitutionCur);
+ out->writeSByte(c->constitutionMax);
+ out->writeSByte(c->charismaCur);
+ out->writeSByte(c->charismaMax);
+ out->writeSint16BE(c->hitPointsCur);
+ out->writeSint16BE(c->hitPointsMax);
+ out->writeSByte(c->armorClass);
+ out->writeByte(c->disabledSlots);
+ out->writeByte(c->raceSex);
+ out->writeByte(c->cClass);
+ out->writeByte(c->alignment);
+ out->writeByte(c->portrait);
+ out->writeByte(c->food);
+ out->write(c->level, 3);
+ for (int ii = 0; ii < 3; ii++)
+ out->writeUint32BE(c->experience[ii]);
+ out->write(c->mageSpells, 80);
+ out->write(c->clericSpells, 80);
+ out->writeUint32BE(c->mageSpellsAvailableFlags);
+ for (int ii = 0; ii < 27; ii++)
+ out->writeSint16BE(c->inventory[ii]);
+ uint32 ct = _system->getMillis();
+ for (int ii = 0; ii < 10; ii++)
+ out->writeUint32BE((c->timers[ii] && c->timers[ii] > ct) ? c->timers[ii] - ct : 0);
+
+ out->write(c->events, 10);
+ out->write(c->effectsRemainder, 4);
+ out->writeUint32BE(c->effectFlags);
+ out->writeByte(c->damageTaken);
+ out->write(c->slotStatus, 5);
+ }
+
+ out->writeByte(_currentLevel);
+ out->writeSByte(_currentSub);
+ out->writeUint16BE(_currentBlock);
+ out->writeUint16BE(_currentDirection);
+ out->writeSint16BE(_itemInHand);
+ out->writeUint32BE(_hasTempDataFlags);
+ out->writeUint32BE(_partyEffectFlags);
+
+ out->writeUint16BE(_updateFlags);
+ out->writeUint16BE(_compassDirection);
+ out->writeUint16BE(_currentControlMode);
+ out->writeSint16BE(_updateCharNum);
+ out->writeSByte(_openBookSpellLevel);
+ out->writeSByte(_openBookSpellSelectedItem);
+ out->writeSByte(_openBookSpellListOffset);
+ out->writeByte(_openBookChar);
+ out->writeByte(_openBookType);
+ out->writeByte(_openBookCharBackup);
+ out->writeByte(_openBookTypeBackup);
+ out->writeByte(_activeSpellCharId);
+ out->writeByte(_activeSpellCharacterPos);
+ out->writeByte(_activeSpell);
+ out->writeByte(_returnAfterSpellCallback ? 1 : 0);
+
+ _inf->saveState(out);
+
+ for (int i = 0; i < 600; i++) {
+ EoBItem *t = &_items[i];
+ out->writeByte(t->nameUnid);
+ out->writeByte(t->nameId);
+ out->writeByte(t->flags);
+ out->writeSByte(t->icon);
+ out->writeSByte(t->type);
+ out->writeSByte(t->pos);
+ out->writeSint16BE(t->block);
+ out->writeSint16BE(t->next);
+ out->writeSint16BE(t->prev);
+ out->writeByte(t->level);
+ out->writeSByte(t->value);
+ }
+
+ for (int i = 51; i < 65; i++) {
+ EoBItemType *t = &_itemTypes[i];
+ out->writeUint16BE(t->invFlags);
+ out->writeUint16BE(t->handFlags);
+ out->writeSByte(t->armorClass);
+ out->writeSByte(t->allowedClasses);
+ out->writeSByte(t->requiredHands);
+ out->writeSByte(t->dmgNumDiceS);
+ out->writeSByte(t->dmgNumPipsS);
+ out->writeSByte(t->dmgIncS);
+ out->writeSByte(t->dmgNumDiceL);
+ out->writeSByte(t->dmgNumPipsL);
+ out->writeSByte(t->dmgIncL);
+ out->writeByte(t->unk1);
+ out->writeUint16BE(t->extraProperties);
+ }
+
+ for (int i = 0; i < 18; i++) {
+ LevelTempData *l = _lvlTempData[i];
+ if (!l || !(_hasTempDataFlags & (1 << i)))
+ continue;
+
+ out->write(l->wallsXorData, 4096);
+ for (int ii = 0; ii < 1024; ii++)
+ out->writeByte(l->flags[ii] & 0xff);
+
+ EoBMonsterInPlay *lm = (EoBMonsterInPlay *)_lvlTempData[i]->monsters;
+ EoBFlyingObject *lf = (EoBFlyingObject *)_lvlTempData[i]->flyingObjects;
+ WallOfForce *lw = (WallOfForce *)_lvlTempData[i]->wallsOfForce;
+
+ for (int ii = 0; ii < 30; ii++) {
+ EoBMonsterInPlay *m = &lm[ii];
+ out->writeByte(m->type);
+ out->writeByte(m->unit);
+ out->writeUint16BE(m->block);
+ out->writeByte(m->pos);
+ out->writeSByte(m->dir);
+ out->writeByte(m->animStep);
+ out->writeByte(m->shpIndex);
+ out->writeSByte(m->mode);
+ out->writeSByte(m->f_9);
+ out->writeSByte(m->curAttackFrame);
+ out->writeSByte(m->spellStatusLeft);
+ out->writeSint16BE(m->hitPointsMax);
+ out->writeSint16BE(m->hitPointsCur);
+ out->writeUint16BE(m->dest);
+ out->writeUint16BE(m->randItem);
+ out->writeUint16BE(m->fixedItem);
+ out->writeByte(m->flags);
+ out->writeByte(m->idleAnimState);
+ out->writeByte(m->curRemoteWeapon);
+ out->writeByte(m->numRemoteAttacks);
+ out->writeSByte(m->palette);
+ out->writeByte(m->directionChanged);
+ out->writeByte(m->stepsTillRemoteAttack);
+ out->writeByte(m->sub);
+ }
+
+ for (int ii = 0; ii < _numFlyingObjects; ii++) {
+ EoBFlyingObject *m = &lf[ii];
+ out->writeByte(m->enable);
+ out->writeByte(m->objectType);
+ out->writeSint16BE(m->attackerId);
+ out->writeSint16BE(m->item);
+ out->writeUint16BE(m->curBlock);
+ out->writeUint16BE(m->starting);
+ out->writeByte(m->u1);
+ out->writeByte(m->direction);
+ out->writeByte(m->distance);
+ out->writeSByte(m->callBackIndex);
+ out->writeByte(m->curPos);
+ out->writeByte(m->flags);
+ out->writeByte(m->unused);
+ }
+
+ for (int ii = 0; ii < 5; ii++) {
+ WallOfForce *w = &lw[ii];
+ out->writeUint16BE(w->block);
+ out->writeUint32BE(w->duration);
+ }
+ }
+
+ out->finalize();
+
+ // check for errors
+ if (out->err()) {
+ warning("Can't write file '%s'. (Disk full?)", fileName);
+ return Common::kUnknownError;
+ } else {
+ debugC(1, kDebugLevelMain, "Saved game '%s.'", saveName);
+ }
+
+ delete out;
+
+ _gui->notifyUpdateSaveSlotsList();
+
+ return Common::kNoError;
+}
+
+bool EoBCoreEngine::importOriginalSaveFile(int destSlot, const char *sourceFile) {
+ Common::Array<Common::String> origFiles;
+ Common::Array<int> newSlots;
+
+ if (sourceFile) {
+ // If a source file is specified via the console command we just check whether it exists.
+ if (Common::File::exists(sourceFile))
+ origFiles.push_back(sourceFile);
+ else
+ return false;
+ } else {
+ // Check for original save files in the game path (usually at least the "Quick Start Party" file will be present).
+ int numMax = (_flags.gameID == GI_EOB1) ? 1 : 6;
+ const char *pattern = (_flags.gameID == GI_EOB1) ? "EOBDATA.SAV" : "EOBDATA%d.SAV";
+ for (int i = 0; i < numMax; ++i) {
+ Common::String temp = Common::String::format(pattern, i);
+ Common::SeekableReadStream *fs = _res->createReadStream(temp);
+ if (fs) {
+ Common::String dsc;
+ if (_flags.gameID == GI_EOB2) {
+ char descStr[20];
+ fs->read(descStr, 20);
+ dsc = Common::String::format("(\"%s\")", descStr).c_str();
+ }
+
+ delete fs;
+ ::GUI::MessageDialog dialog(Common::String::format(_("The following original save game file has been found in your game path:\n\n%s %s\n\nDo you wish to use this save game file with ScummVM?\n\n"), temp.c_str(), dsc.c_str()), _("Yes"), _("No"));
+ if (dialog.runModal())
+ origFiles.push_back(temp);
+ }
+ }
+ }
+
+ int numFilesFound = origFiles.size();
+ if (!numFilesFound)
+ return false;
+
+ _gui->updateSaveSlotsList(_targetName, true);
+
+ // Find free save slots for the original save files
+ if (destSlot == -1) {
+ int assignedSlots = 0;
+ for (int testSlot = 0; testSlot < 990 && assignedSlots < numFilesFound; testSlot++) {
+ if (Common::find(_gui->_saveSlots.begin(), _gui->_saveSlots.end(), testSlot) == _gui->_saveSlots.end()) {
+ newSlots.push_back(testSlot);
+ assignedSlots++;
+ }
+ }
+
+ // This will probably never happen, since we do have 990 save slots
+ if (assignedSlots != numFilesFound)
+ warning("%d original save files could not be converted due to missing save game slots", numFilesFound - assignedSlots);
+
+ } else {
+ newSlots.push_back(destSlot);
+ }
+
+ if (destSlot != -1) {
+ if (Common::find(_gui->_saveSlots.begin(), _gui->_saveSlots.end(), destSlot) != _gui->_saveSlots.end()) {
+ ::GUI::MessageDialog dialog(Common::String::format(_("A save game file was found in the specified slot %d. Overwrite?\n\n"), destSlot), _("Yes"), _("No"));
+ if (!dialog.runModal())
+ return false;
+ }
+ }
+
+ int importedCount = 0;
+ for (int i = 0; i < numFilesFound; i++) {
+ Common::String desc = readOriginalSaveFile(origFiles[i]);
+ if (desc.empty()) {
+ warning("Unable to import original save file '%s'", origFiles[i].c_str());
+ } else {
+ // We can't make thumbnails here, since we do not want to load all the level data, monsters, etc. for each save we convert.
+ // Instead, we use an empty surface to avoid that createThumbnailFromScreen() makes a completely pointless thumbnail from
+ // whatever screen that is currently shown when this function is called.
+ Graphics::Surface dummy;
+ saveGameStateIntern(newSlots[i], desc.c_str(), &dummy);
+ warning("Imported original save file '%s' ('%s')", origFiles[i].c_str(), desc.c_str());
+ importedCount++;
+ }
+ }
+
+ _currentLevel = 0;
+ _currentSub = 0;
+ _currentBlock = 0;
+ _currentDirection = 0;
+ _itemInHand = 0;
+ _hasTempDataFlags = 0;
+ _partyEffectFlags = 0;
+ memset(_characters, 0, sizeof(EoBCharacter) * 6);
+ _inf->reset();
+
+ if (destSlot == -1 && importedCount) {
+ ::GUI::MessageDialog dialog(Common::String::format(_("%d original save game files have been successfully imported into\nScummVM. If you want to manually import original save game files later you will\nneed to open the ScummVM debug console and use the command 'import_savefile'.\n\n"), importedCount));
+ dialog.runModal();
+ }
+
+ return true;
+}
+
+Common::String EoBCoreEngine::readOriginalSaveFile(Common::String &file) {
+ Common::String desc;
+
+ Common::SeekableReadStream *fs = _res->createReadStream(file);
+ if (!fs)
+ return desc;
+
+ Common::SeekableSubReadStreamEndian in(fs, 0, fs->size(), _flags.platform == Common::kPlatformAmiga, DisposeAfterUse::YES);
+
+ if (_flags.gameID == GI_EOB1) {
+ // Nothing to read here for EOB 1. Original EOB 1 has
+ // only one save slot without save file description.
+ desc = "<IMPORTED GAME>";
+ } else {
+ char tempStr[20];
+ in.read(tempStr, 20);
+ desc = tempStr;
+ }
+
+ for (int i = 0; i < 6; i++) {
+ EoBCharacter *c = &_characters[i];
+ c->id = in.readByte();
+ c->flags = in.readByte();
+ in.read(c->name, 11);
+ c->strengthCur = in.readSByte();
+ c->strengthMax = in.readSByte();
+ c->strengthExtCur = in.readSByte();
+ c->strengthExtMax = in.readSByte();
+ c->intelligenceCur = in.readSByte();
+ c->intelligenceMax = in.readSByte();
+ c->wisdomCur = in.readSByte();
+ c->wisdomMax = in.readSByte();
+ c->dexterityCur = in.readSByte();
+ c->dexterityMax = in.readSByte();
+ c->constitutionCur = in.readSByte();
+ c->constitutionMax = in.readSByte();
+ c->charismaCur = in.readSByte();
+ c->charismaMax = in.readSByte();
+ c->hitPointsCur = (_flags.gameID == GI_EOB1) ? in.readSByte() : in.readSint16();
+ c->hitPointsMax = (_flags.gameID == GI_EOB1) ? in.readSByte() : in.readSint16();
+ c->armorClass = in.readSByte();
+ c->disabledSlots = in.readByte();
+ c->raceSex = in.readByte();
+ c->cClass = in.readByte();
+ c->alignment = in.readByte();
+ c->portrait = in.readSByte();
+ c->food = in.readByte();
+ in.read(c->level, 3);
+ for (int ii = 0; ii < 3; ii++)
+ c->experience[ii] = in.readUint32();
+ in.skip(4);
+ delete[] c->faceShape;
+ c->faceShape = 0;
+ in.read(c->mageSpells, (_flags.gameID == GI_EOB1) ? 30 :80);
+ in.read(c->clericSpells, (_flags.gameID == GI_EOB1) ? 30 : 80);
+ c->mageSpellsAvailableFlags = in.readUint32();
+ for (int ii = 0; ii < 27; ii++)
+ c->inventory[ii] = in.readSint16();
+ uint32 ct = _system->getMillis();
+ for (int ii = 0; ii < 10; ii++) {
+ c->timers[ii] = in.readUint32() * _tickLength;
+ if (c->timers[ii])
+ c->timers[ii] += ct;
+ }
+ in.read(c->events, 10);
+ in.read(c->effectsRemainder, 4);
+ c->effectFlags = in.readUint32();
+ if (c->effectFlags && _flags.gameID == GI_EOB1) {
+ warning("EoBCoreEngine::readOriginalSaveFile(): Unhandled character effect flags encountered in original EOB1 save file '%s' ('%s')", file.c_str(), desc.c_str());
+ c->effectFlags = 0;
+ }
+ c->damageTaken = in.readByte();
+ in.read(c->slotStatus, 5);
+ in.skip(6);
+ }
+
+ setupCharacterTimers();
+
+ _currentLevel = in.readUint16();
+ _currentSub = (_flags.gameID == GI_EOB1) ? 0 : in.readSint16();
+ _currentBlock = in.readUint16();
+ _currentDirection = in.readUint16();
+ _itemInHand = in.readSint16();
+ _hasTempDataFlags = (_flags.gameID == GI_EOB1) ? in.readUint16() : in.readUint32();
+ _partyEffectFlags = (_flags.gameID == GI_EOB1) ? in.readUint16() : in.readUint32();
+ if (_partyEffectFlags && _flags.gameID == GI_EOB1) {
+ warning("EoBCoreEngine::readOriginalSaveFile(): Unhandled party effect flags encountered in original EOB1 save file '%s' ('%s')", file.c_str(), desc.c_str());
+ _partyEffectFlags = 0;
+ }
+ if (_flags.gameID == GI_EOB2)
+ in.skip(1);
+
+ _inf->loadState(in, true);
+
+ int numItems = (_flags.gameID == GI_EOB1) ? 500 : 600;
+ for (int i = 0; i < numItems; i++) {
+ EoBItem *t = &_items[i];
+ t->nameUnid = in.readByte();
+ t->nameId = in.readByte();
+ t->flags = in.readByte();
+ t->icon = in.readSByte();
+ t->type = in.readSByte();
+ t->pos = in.readSByte();
+ t->block = in.readSint16();
+ t->next = in.readSint16();
+ t->prev = in.readSint16();
+ t->level = in.readByte();
+ t->value = in.readSByte();
+ }
+
+ int numParts = (_flags.gameID == GI_EOB1) ? 13 : 18;
+ int partSize = (_flags.gameID == GI_EOB1) ? 2040 : 2130;
+ uint32 nextPart = in.pos();
+ uint8 *cmpData = new uint8[1200];
+
+ for (int i = 0; i < numParts; i++) {
+ in.seek(nextPart);
+ nextPart += partSize;
+
+ if (!(_hasTempDataFlags & (1 << i)))
+ continue;
+
+ if (_lvlTempData[i]) {
+ delete[] _lvlTempData[i]->wallsXorData;
+ delete[] _lvlTempData[i]->flags;
+ releaseMonsterTempData(_lvlTempData[i]);
+ releaseFlyingObjectTempData(_lvlTempData[i]);
+ releaseWallOfForceTempData(_lvlTempData[i]);
+ delete _lvlTempData[i];
+ }
+
+ _lvlTempData[i] = new LevelTempData;
+ LevelTempData *l = _lvlTempData[i];
+ l->wallsXorData = new uint8[4096];
+ l->flags = new uint16[1024];
+ memset(l->flags, 0, 1024 * sizeof(uint16));
+ EoBMonsterInPlay *lm = new EoBMonsterInPlay[30];
+ l->monsters = lm;
+ EoBFlyingObject *lf = new EoBFlyingObject[_numFlyingObjects];
+ memset(lf, 0, _numFlyingObjects * sizeof(EoBFlyingObject));
+ l->flyingObjects = lf;
+ WallOfForce *lw = new WallOfForce[5];
+ memset(lw, 0, 5 * sizeof(WallOfForce));
+ l->wallsOfForce = lw;
+
+ in.read(cmpData, 1200);
+ _screen->decodeFrame4(cmpData, l->wallsXorData, 4096);
+ _curBlockFile = getBlockFileName(i + 1, 0);
+ const uint8 *p = getBlockFileData();
+ uint16 len = READ_LE_UINT16(p + 4);
+ p += 6;
+
+ uint8 *d = l->wallsXorData;
+ for (int ii = 0; ii < 1024; ii++) {
+ for (int iii = 0; iii < 4; iii++)
+ *d++ ^= p[ii * len + iii];
+ }
+
+ for (int ii = 0; ii < 30; ii++) {
+ EoBMonsterInPlay *m = &lm[ii];
+ m->type = in.readByte();
+ m->unit = in.readByte();
+ m->block = in.readUint16();
+ m->pos = in.readByte();
+ m->dir = in.readSByte();
+ m->animStep = in.readByte();
+ m->shpIndex = in.readByte();
+ m->mode = in.readSByte();
+ m->f_9 = in.readSByte();
+ m->curAttackFrame = in.readSByte();
+ m->spellStatusLeft = in.readSByte();
+ m->hitPointsMax = in.readSint16();
+ m->hitPointsCur = in.readSint16();
+ m->dest = in.readUint16();
+ m->randItem = in.readUint16();
+ m->fixedItem = in.readUint16();
+ m->flags = in.readByte();
+ m->idleAnimState = in.readByte();
+
+ if (_flags.gameID == GI_EOB1)
+ m->stepsTillRemoteAttack = in.readByte();
+ else
+ m->curRemoteWeapon = in.readByte();
+
+ m->numRemoteAttacks = in.readByte();
+ m->palette = in.readSByte();
+
+ if (_flags.gameID == GI_EOB1) {
+ in.skip(1);
+ } else {
+ m->directionChanged = in.readByte();
+ m->stepsTillRemoteAttack = in.readByte();
+ m->sub = in.readByte();
+ }
+
+ _levelBlockProperties[m->block].flags++;
+ }
+
+ if (_flags.gameID == GI_EOB1)
+ continue;
+
+ for (int ii = 0; ii < 5; ii++) {
+ WallOfForce *w = &lw[ii];
+ w->block = in.readUint16();
+ w->duration = in.readUint32();
+ }
+ }
+
+ delete[] cmpData;
+
+ restoreBlockTempData(_currentLevel);
+
+ in.skip(3);
+
+ delete[] _itemTypes;
+ _itemTypes = new EoBItemType[65];
+ memset(_itemTypes, 0, sizeof(EoBItemType) * 65);
+
+ if (_flags.gameID == GI_EOB1)
+ return desc;
+
+ for (int i = 51; i < 65; i++) {
+ EoBItemType *t = &_itemTypes[i];
+ t->invFlags = in.readUint16();
+ t->handFlags = in.readUint16();
+ t->armorClass = in.readSByte();
+ t->allowedClasses = in.readSByte();
+ t->requiredHands = in.readSByte();
+ t->dmgNumDiceS = in.readSByte();
+ t->dmgNumPipsS = in.readSByte();
+ t->dmgIncS = in.readSByte();
+ t->dmgNumDiceL = in.readSByte();
+ t->dmgNumPipsL = in.readSByte();
+ t->dmgIncL = in.readSByte();
+ t->unk1 = in.readByte();
+ t->extraProperties = in.readUint16();
+ }
+
+ return in.err() ? Common::String() : desc;
+}
+
+void *EoBCoreEngine::generateMonsterTempData(LevelTempData *tmp) {
+ EoBMonsterInPlay *m = new EoBMonsterInPlay[30];
+ memcpy(m, _monsters, sizeof(EoBMonsterInPlay) * 30);
+ return m;
+}
+
+void EoBCoreEngine::restoreMonsterTempData(LevelTempData *tmp) {
+ memcpy(_monsters, tmp->monsters, sizeof(EoBMonsterInPlay) * 30);
+}
+
+void EoBCoreEngine::releaseMonsterTempData(LevelTempData *tmp) {
+ EoBMonsterInPlay *p = (EoBMonsterInPlay *)tmp->monsters;
+ delete[] p;
+}
+
+void *EoBCoreEngine::generateWallOfForceTempData(LevelTempData *tmp) {
+ WallOfForce *w = new WallOfForce[5];
+ memcpy(w, _wallsOfForce, sizeof(WallOfForce) * 5);
+ uint32 ct = _system->getMillis();
+ for (int i = 0; i < 5; i++)
+ w[i].duration = (w[i].duration > ct) ? w[i].duration - ct : _tickLength;
+ return w;
+}
+
+void EoBCoreEngine::restoreWallOfForceTempData(LevelTempData *tmp) {
+ memcpy(_wallsOfForce, tmp->wallsOfForce, sizeof(WallOfForce) * 5);
+ uint32 ct = _system->getMillis();
+ for (int i = 0; i < 5; i++)
+ _wallsOfForce[i].duration += ct;
+}
+
+void EoBCoreEngine::releaseWallOfForceTempData(LevelTempData *tmp) {
+ WallOfForce *p = (WallOfForce *)tmp->wallsOfForce;
+ delete[] p;
+}
+
+} // End of namespace Kyra
+
+#endif // ENABLE_EOB
diff --git a/engines/kyra/saveload_lok.cpp b/engines/kyra/saveload_lok.cpp
index 22d412e7f6..b76d1da52a 100644
--- a/engines/kyra/saveload_lok.cpp
+++ b/engines/kyra/saveload_lok.cpp
@@ -163,7 +163,7 @@ Common::Error KyraEngine_LoK::loadGameState(int slot) {
if (!queryGameFlag(0xF1)) {
for (int i = 0x55; i <= 0x5A; ++i) {
if (queryGameFlag(i))
- seq_createAmuletJewel(i-0x55, 10, 1, 1);
+ seq_createAmuletJewel(i - 0x55, 10, 1, 1);
}
}
diff --git a/engines/kyra/saveload_lol.cpp b/engines/kyra/saveload_lol.cpp
index 1bf26477e6..b6840663e9 100644
--- a/engines/kyra/saveload_lol.cpp
+++ b/engines/kyra/saveload_lol.cpp
@@ -27,6 +27,7 @@
#include "common/savefile.h"
#include "common/substream.h"
+#include "common/memstream.h"
#include "graphics/scaler.h"
@@ -44,6 +45,9 @@ Common::Error LoLEngine::loadGameState(int slot) {
return Common::kNoError;
}
+ if (header.originalSave)
+ warning("Trying to load savegame from original interpreter, while this is possible, it is not officially supported");
+
_screen->fadeClearSceneWindow(10);
completeDoorOperations();
_screen->fillRect(112, 0, 287, 119, 0, 0);
@@ -53,38 +57,40 @@ Common::Error LoLEngine::loadGameState(int slot) {
for (int i = 0; i < 4; i++) {
LoLCharacter *c = &_characters[i];
- c->flags = in.readUint16BE();
+ c->flags = in.readUint16();
in.read(c->name, 11);
c->raceClassSex = in.readByte();
- c->id = in.readSint16BE();
+ c->id = in.readSint16();
c->curFaceFrame = in.readByte();
c->tempFaceFrame = in.readByte();
c->screamSfx = in.readByte();
+ if (header.originalSave)
+ in.skip(4);
for (int ii = 0; ii < 8; ii++)
- c->itemsMight[ii] = in.readUint16BE();
+ c->itemsMight[ii] = in.readUint16();
for (int ii = 0; ii < 8; ii++)
- c->protectionAgainstItems[ii] = in.readUint16BE();
- c->itemProtection = in.readUint16BE();
- c->hitPointsCur = in.readSint16BE();
- c->hitPointsMax = in.readUint16BE();
- c->magicPointsCur = in.readSint16BE();
- c->magicPointsMax = in.readUint16BE();
+ c->protectionAgainstItems[ii] = in.readUint16();
+ c->itemProtection = in.readUint16();
+ c->hitPointsCur = in.readSint16();
+ c->hitPointsMax = in.readUint16();
+ c->magicPointsCur = in.readSint16();
+ c->magicPointsMax = in.readUint16();
c->field_41 = in.readByte();
- c->damageSuffered = in.readUint16BE();
- c->weaponHit = in.readUint16BE();
- c->totalMightModifier = in.readUint16BE();
- c->totalProtectionModifier = in.readUint16BE();
- c->might = in.readUint16BE();
- c->protection = in.readUint16BE();
- c->nextAnimUpdateCountdown = in.readSint16BE();
+ c->damageSuffered = in.readUint16();
+ c->weaponHit = in.readUint16();
+ c->totalMightModifier = in.readUint16();
+ c->totalProtectionModifier = in.readUint16();
+ c->might = in.readUint16();
+ c->protection = in.readUint16();
+ c->nextAnimUpdateCountdown = in.readSint16();
for (int ii = 0; ii < 11; ii++)
- c->items[ii] = in.readUint16BE();
+ c->items[ii] = in.readUint16();
for (int ii = 0; ii < 3; ii++)
c->skillLevels[ii] = in.readByte();
for (int ii = 0; ii < 3; ii++)
c->skillModifiers[ii] = in.readSByte();
for (int ii = 0; ii < 3; ii++)
- c->experiencePts[ii] = in.readUint32BE();
+ c->experiencePts[ii] = in.readUint32();
for (int ii = 0; ii < 5; ii++)
c->characterUpdateEvents[ii] = in.readByte();
for (int ii = 0; ii < 5; ii++)
@@ -96,39 +102,48 @@ Common::Error LoLEngine::loadGameState(int slot) {
}
}
- in.read(_wllBuffer4, 80);
+ if (header.version < 17)
+ in.skip(80);
- _currentBlock = in.readUint16BE();
- _partyPosX = in.readUint16BE();
- _partyPosY = in.readUint16BE();
- _updateFlags = in.readUint16BE();
+ _currentBlock = in.readUint16();
+ _partyPosX = in.readUint16();
+ _partyPosY = in.readUint16();
+ _updateFlags = in.readUint16();
_scriptDirection = in.readByte();
_selectedSpell = in.readByte();
+
+ if (header.originalSave)
+ in.skip(2);
+
_sceneDefaultUpdate = in.readByte();
_compassBroken = in.readByte();
_drainMagic = in.readByte();
- _currentDirection = in.readUint16BE();
- _compassDirection = in.readUint16BE();
+ _currentDirection = in.readUint16();
+ _compassDirection = in.readUint16();
_selectedCharacter = in.readSByte();
+
+ if (header.originalSave)
+ in.skip(1);
+
_currentLevel = in.readByte();
for (int i = 0; i < 48; i++)
- _inventory[i] = in.readSint16BE();
- _inventoryCurItem = in.readSint16BE();
- _itemInHand = in.readSint16BE();
- _lastMouseRegion = in.readSint16BE();
+ _inventory[i] = in.readSint16();
+ _inventoryCurItem = in.readSint16();
+ _itemInHand = in.readSint16();
+ _lastMouseRegion = in.readSint16();
- if (header.version <= 15) {
+ if (header.originalSave || header.version <= 15) {
uint16 flags[40];
memset(flags, 0, sizeof(flags));
if (header.version == 14) {
for (int i = 0; i < 16; i++)
- flags[i] = in.readUint16BE();
- flags[26] = in.readUint16BE();
- flags[36] = in.readUint16BE();
- } else if (header.version == 15) {
+ flags[i] = in.readUint16();
+ flags[26] = in.readUint16();
+ flags[36] = in.readUint16();
+ } else if (header.originalSave || header.version == 15) {
for (int i = 0; i < 40; i++)
- flags[i] = in.readUint16BE();
+ flags[i] = in.readUint16();
}
memset(_flagsTable, 0, sizeof(_flagsTable));
@@ -139,37 +154,52 @@ Common::Error LoLEngine::loadGameState(int slot) {
}
}
} else {
- uint32 flagsSize = in.readUint32BE();
+ uint32 flagsSize = in.readUint32();
assert(flagsSize <= sizeof(_flagsTable));
in.read(_flagsTable, flagsSize);
}
+ if (header.originalSave)
+ in.skip(120);
+
for (int i = 0; i < 24; i++)
- _globalScriptVars[i] = in.readUint16BE();
+ _globalScriptVars[i] = in.readUint16();
+
+ if (header.originalSave)
+ in.skip(152);
+
_brightness = in.readByte();
_lampOilStatus = in.readByte();
_lampEffect = in.readSByte();
- _credits = in.readUint16BE();
+
+ if (header.originalSave)
+ in.skip(1);
+
+ _credits = in.readUint16();
for (int i = 0; i < 8; i++)
- _globalScriptVars2[i] = in.readUint16BE();
+ _globalScriptVars2[i] = in.readUint16();
in.read(_availableSpells, 7);
- _hasTempDataFlags = in.readUint32BE();
+ _hasTempDataFlags = in.readUint32();
+
+ uint8 *origCmp = 0;
+ if (header.originalSave) {
+ in.skip(6);
+ origCmp = new uint8[2496];
+ }
for (int i = 0; i < 400; i++) {
- ItemInPlay *t = &_itemsInPlay[i];
- t->nextAssignedObject = in.readUint16BE();
- t->nextDrawObject = in.readUint16BE();
+ LoLItem *t = &_itemsInPlay[i];
+ t->nextAssignedObject = in.readUint16();
+ t->nextDrawObject = in.readUint16();
t->flyingHeight = in.readByte();
- t->block = in.readUint16BE();
- t->x = in.readUint16BE();
- t->y = in.readUint16BE();
+ t->block = in.readUint16();
+ t->x = in.readUint16();
+ t->y = in.readUint16();
t->level = in.readSByte();
- t->itemPropertyIndex = in.readUint16BE();
- t->shpCurFrame_flg = in.readUint16BE();
- t->destDirection = in.readByte();
- t->hitOffsX = in.readSByte();
- t->hitOffsY = in.readSByte();
- t->currentSubFrame = in.readByte();
+ t->itemPropertyIndex = in.readUint16();
+ t->shpCurFrame_flg = in.readUint16();
+ if (header.version < 17)
+ in.skip(4);
}
for (int i = 0; i < 1024; i++) {
@@ -179,38 +209,61 @@ Common::Error LoLEngine::loadGameState(int slot) {
}
for (int i = 0; i < 29; i++) {
- if (!(_hasTempDataFlags & (1 << i)))
+ if (!(_hasTempDataFlags & (1 << i))) {
+ if (header.originalSave) {
+ if (in.size() - in.pos() >= 2500)
+ in.skip(2500);
+ }
continue;
+ }
if (_lvlTempData[i]) {
delete[] _lvlTempData[i]->wallsXorData;
delete[] _lvlTempData[i]->flags;
- delete[] _lvlTempData[i]->monsters;
- delete[] _lvlTempData[i]->flyingObjects;
+ releaseMonsterTempData(_lvlTempData[i]);
+ releaseFlyingObjectTempData(_lvlTempData[i]);
+ releaseWallOfForceTempData(_lvlTempData[i]);
delete _lvlTempData[i];
}
_lvlTempData[i] = new LevelTempData;
_lvlTempData[i]->wallsXorData = new uint8[4096];
- _lvlTempData[i]->flags = new uint8[1024];
- _lvlTempData[i]->monsters = new MonsterInPlay[30];
- _lvlTempData[i]->flyingObjects = new FlyingObject[8];
+ _lvlTempData[i]->flags = new uint16[1024];
+ LoLMonster *lm = new LoLMonster[30];
+ _lvlTempData[i]->monsters = lm;
+ FlyingObject *lf = new FlyingObject[_numFlyingObjects];
+ _lvlTempData[i]->flyingObjects = lf;
LevelTempData *l = _lvlTempData[i];
- in.read(l->wallsXorData, 4096);
- in.read(l->flags, 1024);
+ uint32 next = in.pos() + 2500;
+
+ if (header.originalSave) {
+ in.skip(4);
+ in.read(origCmp, in.readUint16());
+ _screen->decodeFrame4(origCmp, _tempBuffer5120, 5120);
+ memcpy(l->wallsXorData, _tempBuffer5120, 4096);
+ for (int ii = 0; ii < 1024; ii++)
+ l->flags[ii] = _tempBuffer5120[4096 + ii];
+ } else {
+ in.read(l->wallsXorData, 4096);
+ for (int ii = 0; ii < 1024; ii++)
+ l->flags[ii] = in.readByte();
+ }
+
+ if (header.originalSave)
+ l->monsterDifficulty = in.readUint16();
for (int ii = 0; ii < 30; ii++) {
- MonsterInPlay *m = &l->monsters[ii];
- m->nextAssignedObject = in.readUint16BE();
- m->nextDrawObject = in.readUint16BE();
+ LoLMonster *m = &lm[ii];
+ m->nextAssignedObject = in.readUint16();
+ m->nextDrawObject = in.readUint16();
m->flyingHeight = in.readByte();
- m->block = in.readUint16BE();
- m->x = in.readUint16BE();
- m->y = in.readUint16BE();
+ m->block = in.readUint16();
+ m->x = in.readUint16();
+ m->y = in.readUint16();
m->shiftStep = in.readSByte();
- m->destX = in.readUint16BE();
- m->destY = in.readUint16BE();
+ m->destX = in.readUint16();
+ m->destY = in.readUint16();
m->destDirection = in.readByte();
m->hitOffsX = in.readSByte();
m->hitOffsY = in.readSByte();
@@ -220,27 +273,31 @@ Common::Error LoLEngine::loadGameState(int slot) {
m->id = in.readByte();
m->direction = in.readByte();
m->facing = in.readByte();
- m->flags = in.readUint16BE();
- m->damageReceived = in.readUint16BE();
- m->hitPoints = in.readSint16BE();
+ m->flags = in.readUint16();
+ m->damageReceived = in.readUint16();
+ m->hitPoints = in.readSint16();
m->speedTick = in.readByte();
m->type = in.readByte();
+
+ if (header.originalSave)
+ in.skip(4);
+
m->numDistAttacks = in.readByte();
m->curDistWeapon = in.readByte();
m->distAttackTick = in.readSByte();
- m->assignedItems = in.readUint16BE();
+ m->assignedItems = in.readUint16();
m->properties = &_monsterProperties[m->type];
in.read(m->equipmentShapes, 4);
}
- for (int ii = 0; ii < 8; ii++) {
- FlyingObject *m = &l->flyingObjects[ii];
+ for (int ii = 0; ii < _numFlyingObjects; ii++) {
+ FlyingObject *m = &lf[ii];
m->enable = in.readByte();
m->objectType = in.readByte();
- m->attackerId = in.readUint16BE();
- m->item = in.readSint16BE();
- m->x = in.readUint16BE();
- m->y = in.readUint16BE();
+ m->attackerId = in.readUint16();
+ m->item = in.readSint16();
+ m->x = in.readUint16();
+ m->y = in.readUint16();
m->flyingHeight = in.readByte();
m->direction = in.readByte();
m->distance = in.readByte();
@@ -249,9 +306,15 @@ Common::Error LoLEngine::loadGameState(int slot) {
m->flags = in.readByte();
m->wallFlags = in.readByte();
}
- l->monsterDifficulty = in.readByte();
+
+ if (header.originalSave)
+ in.seek(next, SEEK_SET);
+ else
+ l->monsterDifficulty = in.readByte();
}
+ delete[] origCmp;
+
calcCharPortraitXpos();
memset(_moneyColumnHeight, 0, sizeof(_moneyColumnHeight));
int t = _credits;
@@ -319,8 +382,6 @@ Common::Error LoLEngine::saveGameStateIntern(int slot, const char *saveName, con
out->writeByte(c->characterUpdateDelay[ii]);
}
- out->write(_wllBuffer4, 80);
-
out->writeUint16BE(_currentBlock);
out->writeUint16BE(_partyPosX);
out->writeUint16BE(_partyPosY);
@@ -355,7 +416,7 @@ Common::Error LoLEngine::saveGameStateIntern(int slot, const char *saveName, con
resetItems(0);
for (int i = 0; i < 400; i++) {
- ItemInPlay *t = &_itemsInPlay[i];
+ LoLItem *t = &_itemsInPlay[i];
out->writeUint16BE(t->nextAssignedObject);
out->writeUint16BE(t->nextDrawObject);
out->writeByte(t->flyingHeight);
@@ -365,10 +426,6 @@ Common::Error LoLEngine::saveGameStateIntern(int slot, const char *saveName, con
out->writeSByte(t->level);
out->writeUint16BE(t->itemPropertyIndex);
out->writeUint16BE(t->shpCurFrame_flg);
- out->writeByte(t->destDirection);
- out->writeSByte(t->hitOffsX);
- out->writeSByte(t->hitOffsY);
- out->writeByte(t->currentSubFrame);
}
addLevelItems();
@@ -379,10 +436,14 @@ Common::Error LoLEngine::saveGameStateIntern(int slot, const char *saveName, con
continue;
out->write(l->wallsXorData, 4096);
- out->write(l->flags, 1024);
+ for (int ii = 0; ii < 1024; ii++)
+ out->writeByte(l->flags[ii] & 0xff);
+
+ LoLMonster *lm = (LoLMonster *)_lvlTempData[i]->monsters;
+ FlyingObject *lf = (FlyingObject *)_lvlTempData[i]->flyingObjects;
for (int ii = 0; ii < 30; ii++) {
- MonsterInPlay *m = &l->monsters[ii];
+ LoLMonster *m = &lm[ii];
out->writeUint16BE(m->nextAssignedObject);
out->writeUint16BE(m->nextDrawObject);
out->writeByte(m->flyingHeight);
@@ -413,8 +474,8 @@ Common::Error LoLEngine::saveGameStateIntern(int slot, const char *saveName, con
out->write(m->equipmentShapes, 4);
}
- for (int ii = 0; ii < 8; ii++) {
- FlyingObject *m = &l->flyingObjects[ii];
+ for (int ii = 0; ii < _numFlyingObjects; ii++) {
+ FlyingObject *m = &lf[ii];
out->writeByte(m->enable);
out->writeByte(m->objectType);
out->writeUint16BE(m->attackerId);
@@ -469,6 +530,54 @@ Graphics::Surface *LoLEngine::generateSaveThumbnail() const {
return dst;
}
+void LoLEngine::restoreBlockTempData(int levelIndex) {
+ memset(_tempBuffer5120, 0, 5120);
+ KyraRpgEngine::restoreBlockTempData(levelIndex);
+ restoreTempDataAdjustMonsterStrength(levelIndex - 1);
+}
+
+void *LoLEngine::generateMonsterTempData(LevelTempData *tmp) {
+ LoLMonster *m = new LoLMonster[30];
+ memcpy(m, _monsters, sizeof(LoLMonster) * 30);
+ tmp->monsterDifficulty = _monsterDifficulty;
+ return m;
+}
+
+void LoLEngine::restoreTempDataAdjustMonsterStrength(int index) {
+ if (_lvlTempData[index]->monsterDifficulty == _monsterDifficulty)
+ return;
+
+ uint16 d = (_monsterModifiers[_lvlTempData[index]->monsterDifficulty] << 8) / _monsterModifiers[_monsterDifficulty];
+
+ for (int i = 0; i < 30; i++) {
+ if (_monsters[i].mode >= 14 || _monsters[i].block == 0 || _monsters[i].hitPoints <= 0)
+ continue;
+
+ _monsters[i].hitPoints = (d * _monsters[i].hitPoints) >> 8;
+ if (_monsterDifficulty < _lvlTempData[index]->monsterDifficulty)
+ _monsters[i].hitPoints++;
+ if (_monsters[i].hitPoints == 0)
+ _monsters[i].hitPoints = 1;
+ }
+}
+
+void LoLEngine::restoreMonsterTempData(LevelTempData *tmp) {
+ memcpy(_monsters, tmp->monsters, sizeof(LoLMonster) * 30);
+
+ for (int i = 0; i < 30; i++) {
+ if (_monsters[i].block) {
+ _monsters[i].block = 0;
+ _monsters[i].properties = &_monsterProperties[_monsters[i].type];
+ placeMonster(&_monsters[i], _monsters[i].x, _monsters[i].y);
+ }
+ }
+}
+
+void LoLEngine::releaseMonsterTempData(LevelTempData *tmp) {
+ LoLMonster *p = (LoLMonster *)tmp->monsters;
+ delete[] p;
+}
+
} // End of namespace Kyra
#endif // ENABLE_LOL
diff --git a/engines/kyra/saveload_rpg.cpp b/engines/kyra/saveload_rpg.cpp
new file mode 100644
index 0000000000..d22c50dbeb
--- /dev/null
+++ b/engines/kyra/saveload_rpg.cpp
@@ -0,0 +1,127 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#if defined(ENABLE_EOB) || defined(ENABLE_LOL)
+
+#include "kyra/resource.h"
+#include "kyra/script_eob.h"
+
+#include "common/system.h"
+#include "common/savefile.h"
+#include "common/substream.h"
+
+namespace Kyra {
+
+void KyraRpgEngine::generateTempData() {
+ int l = _currentLevel - 1;
+ if (_lvlTempData[l]) {
+ delete[] _lvlTempData[l]->wallsXorData;
+ delete[] _lvlTempData[l]->flags;
+ releaseMonsterTempData(_lvlTempData[l]);
+ releaseFlyingObjectTempData(_lvlTempData[l]);
+ releaseWallOfForceTempData(_lvlTempData[l]);
+ delete _lvlTempData[l];
+ }
+
+ _lvlTempData[l] = new LevelTempData;
+
+ _lvlTempData[l]->wallsXorData = new uint8[4096];
+ _lvlTempData[l]->flags = new uint16[1024];
+
+ const uint8 *p = getBlockFileData(_currentLevel);
+ uint16 len = READ_LE_UINT16(p + 4);
+ p += 6;
+
+ memset(_lvlTempData[l]->wallsXorData, 0, 4096);
+ memset(_lvlTempData[l]->flags, 0, 1024 * sizeof(uint16));
+ uint8 *d = _lvlTempData[l]->wallsXorData;
+ uint16 *df = _lvlTempData[l]->flags;
+
+ for (int i = 0; i < 1024; i++) {
+ for (int ii = 0; ii < 4; ii++)
+ *d++ = p[i * len + ii] ^ _levelBlockProperties[i].walls[ii];
+ *df++ = _levelBlockProperties[i].flags;
+ }
+
+ _lvlTempData[l]->monsters = generateMonsterTempData(_lvlTempData[l]);
+ _lvlTempData[l]->flyingObjects = generateFlyingObjectTempData(_lvlTempData[l]);
+ _lvlTempData[l]->wallsOfForce = generateWallOfForceTempData(_lvlTempData[l]);
+
+ _hasTempDataFlags |= (1 << l);
+}
+
+void KyraRpgEngine::restoreBlockTempData(int levelIndex) {
+ int l = levelIndex - 1;
+ const uint8 *p = getBlockFileData(levelIndex);
+ uint16 len = READ_LE_UINT16(p + 4);
+ p += 6;
+
+ memset(_levelBlockProperties, 0, 1024 * sizeof(LevelBlockProperty));
+
+ uint8 *t = _lvlTempData[l]->wallsXorData;
+ uint16 *t2 = _lvlTempData[l]->flags;
+
+ for (int i = 0; i < 1024; i++) {
+ for (int ii = 0; ii < 4; ii++)
+ _levelBlockProperties[i].walls[ii] = p[i * len + ii] ^ *t++;
+ _levelBlockProperties[i].flags = *t2++;
+ }
+
+ restoreMonsterTempData(_lvlTempData[l]);
+ restoreFlyingObjectTempData(_lvlTempData[l]);
+ restoreWallOfForceTempData(_lvlTempData[l]);
+}
+
+void KyraRpgEngine::releaseTempData() {
+ for (int i = 0; i < 29; i++) {
+ if (_lvlTempData[i]) {
+ delete[] _lvlTempData[i]->wallsXorData;
+ delete[] _lvlTempData[i]->flags;
+ releaseMonsterTempData(_lvlTempData[i]);
+ releaseFlyingObjectTempData(_lvlTempData[i]);
+ releaseWallOfForceTempData(_lvlTempData[i]);
+ delete _lvlTempData[i];
+ _lvlTempData[i] = 0;
+ }
+ }
+}
+
+void *KyraRpgEngine::generateFlyingObjectTempData(LevelTempData *tmp) {
+ assert(_flyingObjectStructSize == sizeof(EoBFlyingObject));
+ EoBFlyingObject *f = new EoBFlyingObject[_numFlyingObjects];
+ memcpy(f, _flyingObjectsPtr, sizeof(EoBFlyingObject) * _numFlyingObjects);
+ return f;
+}
+
+void KyraRpgEngine::restoreFlyingObjectTempData(LevelTempData *tmp) {
+ assert(_flyingObjectStructSize == sizeof(EoBFlyingObject));
+ memcpy(_flyingObjectsPtr, tmp->flyingObjects, sizeof(EoBFlyingObject) * _numFlyingObjects);
+}
+
+void KyraRpgEngine::releaseFlyingObjectTempData(LevelTempData *tmp) {
+ EoBFlyingObject *p = (EoBFlyingObject *)tmp->flyingObjects;
+ delete[] p;
+}
+
+} // End of namespace Kyra
+
+#endif // ENABLE_EOB || ENABLE_LOL
diff --git a/engines/kyra/scene_eob.cpp b/engines/kyra/scene_eob.cpp
new file mode 100644
index 0000000000..3db055db90
--- /dev/null
+++ b/engines/kyra/scene_eob.cpp
@@ -0,0 +1,890 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifdef ENABLE_EOB
+
+#include "kyra/eobcommon.h"
+#include "kyra/resource.h"
+#include "kyra/script_eob.h"
+#include "kyra/timer.h"
+#include "kyra/sound.h"
+
+#include "common/system.h"
+
+
+namespace Kyra {
+
+void EoBCoreEngine::loadLevel(int level, int sub) {
+ _currentLevel = level;
+ _currentSub = sub;
+ uint32 end = _system->getMillis() + 500;
+
+ readLevelFileData(level);
+
+ Common::String gfxFile;
+ // Work around for issue with corrupt (incomplete) monster property data
+ // when loading a savegame saved in a sub level
+ for (int i = 0; i <= sub; i++)
+ gfxFile = initLevelData(i);
+
+ const uint8 *data = _screen->getCPagePtr(5);
+ const uint8 *pos = data + READ_LE_UINT16(data);
+ uint16 len = READ_LE_UINT16(pos);
+ uint16 len2 = len;
+ pos += 2;
+
+ if (_flags.gameID == GI_EOB2) {
+ if (*pos++ == 0xEC)
+ pos = loadActiveMonsterData(pos, level);
+ else if (!(_hasTempDataFlags & (1 << (level - 1))))
+ memset(_monsters, 0, 30 * sizeof(EoBMonsterInPlay));
+
+ len2 = len - (pos - data);
+ _inf->loadData(pos, len2);
+ } else {
+ _inf->loadData(data, READ_LE_UINT16(data));
+ }
+
+ _screen->setCurPage(2);
+ addLevelItems();
+
+ if (_flags.gameID == GI_EOB2) {
+ pos = data + len;
+ len2 = READ_LE_UINT16(pos);
+ pos += 2;
+ }
+
+ for (uint16 i = 0; i < len2; i++) {
+ LevelBlockProperty *p = &_levelBlockProperties[READ_LE_UINT16(pos)];
+ pos += 2;
+ if (_flags.gameID == GI_EOB2) {
+ p->flags |= READ_LE_UINT16(pos);
+ pos += 2;
+ } else {
+ p->flags |= *pos++;
+ }
+ p->assignedObjects = READ_LE_UINT16(pos);
+ pos += 2;
+ }
+
+ loadVcnData(gfxFile.c_str(), (_flags.gameID == GI_EOB1) ? _cgaMappingLevel[_cgaLevelMappingIndex[level - 1]] : 0);
+ _screen->loadEoBBitmap("INVENT", _cgaMappingInv, 5, 3, 2);
+ delayUntil(end);
+ snd_stopSound();
+
+ enableSysTimer(2);
+ _sceneDrawPage1 = 2;
+ _sceneDrawPage2 = 1;
+ _screen->setCurPage(0);
+}
+
+void EoBCoreEngine::readLevelFileData(int level) {
+ Common::String file;
+ Common::SeekableReadStream *s = 0;
+ static const char *suffix[] = { "INF", "DRO", "ELO", 0 };
+
+ for (const char *const *sf = suffix; *sf && !s; sf++) {
+ file = Common::String::format("LEVEL%d.%s", level, *sf);
+ s = _res->createReadStream(file);
+ }
+
+ if (!s)
+ error("Failed to load level file LEVEL%d.INF/DRO/ELO", level);
+
+ if (s->readUint16LE() + 2 == s->size()) {
+ if (s->readUint16LE() == 4) {
+ delete s;
+ s = 0;
+ _screen->loadBitmap(file.c_str(), 5, 5, 0);
+ }
+ }
+
+ if (s) {
+ s->seek(0);
+ _screen->loadFileDataToPage(s, 5, 15000);
+ delete s;
+ }
+}
+
+Common::String EoBCoreEngine::initLevelData(int sub) {
+ const uint8 *data = _screen->getCPagePtr(5) + 2;
+ const uint8 *pos = data;
+
+ int slen = (_flags.gameID == GI_EOB1) ? 12 : 13;
+
+ for (int i = 0; i < sub; i++)
+ pos = data + READ_LE_UINT16(pos);
+
+ pos += 2;
+ if (*pos++ == 0xEC || _flags.gameID == GI_EOB1) {
+ if (_flags.gameID == GI_EOB1)
+ pos -= 3;
+
+ loadBlockProperties((const char *)pos);
+ pos += slen;
+
+ const char *vmpPattern = (_flags.gameID == GI_EOB1 && (_configRenderMode == Common::kRenderEGA || _configRenderMode == Common::kRenderCGA)) ? "%s.EMP" : "%s.VMP";
+ Common::SeekableReadStream *s = _res->createReadStream(Common::String::format(vmpPattern, (const char *)pos));
+ _vmpSize = s->readUint16LE();
+ delete[] _vmpPtr;
+ _vmpPtr = new uint16[_vmpSize];
+ for (int i = 0; i < _vmpSize; i++)
+ _vmpPtr[i] = s->readUint16LE();
+ delete s;
+
+ const char *paletteFilePattern = (_flags.gameID == GI_EOB2 && _configRenderMode == Common::kRenderEGA) ? "%s.EGA" : "%s.PAL";
+
+ Common::String tmpStr = Common::String::format(paletteFilePattern, (const char *)pos);
+ _curGfxFile = (const char *)pos;
+ pos += slen;
+
+ if (*pos++ != 0xff && _flags.gameID == GI_EOB2) {
+ tmpStr = Common::String::format(paletteFilePattern, (const char *)pos);
+ pos += 13;
+ }
+
+ if (_flags.gameID == GI_EOB1) {
+ pos += 11;
+ _screen->setShapeFadeMode(0, false);
+ _screen->setShapeFadeMode(1, false);
+ }
+
+ if (_flags.gameID == GI_EOB2 || _configRenderMode != Common::kRenderEGA)
+ _screen->loadPalette(tmpStr.c_str(), _screen->getPalette(0));
+
+ if (_configRenderMode != Common::kRenderCGA) {
+ Palette backupPal(256);
+ backupPal.copy(_screen->getPalette(0), 224, 32, 224);
+ _screen->getPalette(0).fill(224, 32, 0x3f);
+ uint8 *src = _screen->getPalette(0).getData();
+
+ _screen->createFadeTable(src, _screen->getFadeTable(0), 4, 75); // green
+ _screen->createFadeTable(src, _screen->getFadeTable(1), 12, 200); // black
+ _screen->createFadeTable(src, _screen->getFadeTable(2), 10, 85); // blue
+ _screen->createFadeTable(src, _screen->getFadeTable(3), 11, 125); // light blue
+
+ _screen->getPalette(0).copy(backupPal, 224, 32, 224);
+ _screen->createFadeTable(src, _screen->getFadeTable(4), 12, 85); // grey (shadow)
+ _screen->setFadeTableIndex(4);
+ if (_flags.gameID == GI_EOB2 && _configRenderMode == Common::kRenderEGA)
+ _screen->setScreenPalette(_screen->getPalette(0));
+ }
+ }
+
+ if (_flags.gameID == GI_EOB2) {
+ delay(3 * _tickLength);
+ _sound->loadSoundFile((const char *)pos);
+ pos += 13;
+ }
+
+ releaseDoorShapes();
+ releaseMonsterShapes(0, 36);
+ releaseDecorations();
+
+ if (_flags.gameID == GI_EOB1) {
+ loadDoorShapes(pos[0], pos[1], pos[2], pos[3]);
+ pos += 4;
+ _scriptTimersMode = *pos++;
+ _scriptTimers[0].ticks = READ_LE_UINT16(pos);
+ _scriptTimers[0].func = 0;
+ _scriptTimers[0].next = _system->getMillis() + _scriptTimers[0].ticks * _tickLength;
+ pos += 2;
+ } else {
+ for (int i = 0; i < 2; i++) {
+ int a = (*pos == 0xEC) ? 0 : ((*pos == 0xEA) ? 1 : -1);
+ pos++;
+ if (a == -1)
+ continue;
+ toggleWallState(pos[13], a);
+ _doorType[pos[13]] = pos[14];
+ _noDoorSwitch[pos[13]] = pos[15];
+ pos = loadDoorShapes((const char *)pos, pos[13], pos + 16);
+ }
+ }
+
+ _stepsUntilScriptCall = READ_LE_UINT16(pos);
+ pos += 2;
+ _stepCounter = 0;
+
+ for (int i = 0; i < 2; i++) {
+ if (_flags.gameID == GI_EOB1) {
+ if (*pos != 0xFF)
+ loadMonsterShapes((const char *)(pos + 1), i * 18, false, *pos * 18);
+ pos += 13;
+ } else {
+ if (*pos++ != 0xEC)
+ continue;
+ loadMonsterShapes((const char *)(pos + 2), pos[1] * 18, pos[15] ? true : false, *pos * 18);
+ pos += 16;
+ }
+ }
+
+ if (_flags.gameID == GI_EOB1)
+ pos = loadActiveMonsterData(pos, _currentLevel) - 1;
+ else
+ pos = loadMonsterProperties(pos);
+
+ if (*pos++ == 0xEC || _flags.gameID == GI_EOB1) {
+ int num = READ_LE_UINT16(pos);
+ pos += 2;
+
+ for (int i = 0; i < num; i++) {
+ if (*pos++ == 0xEC) {
+ loadDecorations((const char *)pos, (const char *)(pos + slen));
+ pos += (slen << 1);
+ } else {
+ assignWallsAndDecorations(pos[0], pos[1], (int8)pos[2], pos[3], pos[4]);
+ pos += 5;
+ }
+ }
+ }
+
+ if (_flags.gameID == GI_EOB2)
+ pos = initScriptTimers(pos);
+
+ return _curGfxFile;
+}
+
+void EoBCoreEngine::addLevelItems() {
+ for (int i = 0; i < 1024; i++)
+ _levelBlockProperties[i].drawObjects = 0;
+
+ for (int i = 0; i < 600; i++) {
+ if (_items[i].level != _currentLevel || _items[i].block <= 0)
+ continue;
+ setItemPosition((Item *)&_levelBlockProperties[_items[i].block & 0x3ff].drawObjects, _items[i].block, i, _items[i].pos);
+ }
+}
+
+void EoBCoreEngine::loadVcnData(const char *file, const uint8 *cgaMapping) {
+ if (file)
+ strcpy(_lastBlockDataFile, file);
+
+ const char *filePattern = (_flags.gameID == GI_EOB1 && (_configRenderMode == Common::kRenderEGA || _configRenderMode == Common::kRenderCGA)) ? "%s.ECN" : "%s.VCN";
+ _screen->loadBitmap(Common::String::format(filePattern, _lastBlockDataFile).c_str(), 3, 3, 0);
+ const uint8 *pos = _screen->getCPagePtr(3);
+
+ uint32 vcnSize = READ_LE_UINT16(pos) * _vcnBlockWidth * _vcnBlockHeight;
+ pos += 2;
+
+ const uint8 *colMap = pos;
+ pos += 32;
+
+ delete[] _vcnBlocks;
+ _vcnBlocks = new uint8[vcnSize];
+
+ if (_flags.gameID == GI_EOB2 && _configRenderMode == Common::kRenderEGA) {
+ const uint8 *egaTable = _screen->getEGADitheringTable();
+ assert(_vmpPtr);
+ assert(egaTable);
+
+ delete[] _vcnTransitionMask;
+ _vcnTransitionMask = new uint8[vcnSize];
+
+ for (int i = 0; i < _vmpSize; i++) {
+ uint16 vcnOffs = _vmpPtr[i] & 0x3FFF;
+ const uint8 *src = &pos[vcnOffs << 5];
+ uint8 *dst1 = &_vcnBlocks[vcnOffs << 7];
+ uint8 *dst3 = &_vcnTransitionMask[vcnOffs << 7];
+ int palOffset = (i < 330) ? 0 : _wllVcnOffset;
+
+ for (int y = 0; y < 8; y++) {
+ uint8 *dst2 = dst1 + 8;
+ uint8 *dst4 = dst3 + 8;
+
+ for (int x = 0; x < 4; x++) {
+ uint8 in = *src++;
+
+ dst1[0] = dst2[0] = egaTable[colMap[(in >> 4) + palOffset]];
+ dst1[1] = dst2[1] = egaTable[colMap[(in & 0x0f) + palOffset]];
+ dst3[0] = dst4[0] = (in & 0xf0) ? 0 : 0xff;
+ dst3[1] = dst4[1] = (in & 0x0f) ? 0 : 0xff;
+
+ dst1 += 2;
+ dst2 += 2;
+ dst3 += 2;
+ dst4 += 2;
+ }
+
+ dst1 += 8;
+ dst3 += 8;
+ }
+ }
+ } else if (_configRenderMode == Common::kRenderCGA) {
+ uint8 *tmp = _screen->encodeShape(0, 0, 1, 8, false, cgaMapping);
+ delete[] tmp;
+
+ delete[] _vcnTransitionMask;
+ _vcnTransitionMask = new uint8[vcnSize];
+ uint8 tblSwitch = 0;
+ uint8 *dst = _vcnBlocks;
+ uint8 *dst2 = _vcnTransitionMask;
+
+ while (dst < _vcnBlocks + vcnSize) {
+ const uint16 *table = _screen->getCGADitheringTable((tblSwitch++) & 1);
+ for (int ii = 0; ii < 2; ii++) {
+ *dst++ = ((table[pos[0]] & 0x000f) << 4) | ((table[pos[0]] & 0x0f00) >> 8);
+ *dst++= ((table[pos[1]] & 0x000f) << 4) | ((table[pos[1]] & 0x0f00) >> 8);
+
+ uint8 msk = 0;
+ if (pos[0] & 0xf0)
+ msk |= 0x30;
+ if (pos[0] & 0x0f)
+ msk |= 0x03;
+ *dst2++ = msk ^ 0x33;
+
+ msk = 0;
+ if (pos[1] & 0xf0)
+ msk |= 0x30;
+ if (pos[1] & 0x0f)
+ msk |= 0x03;
+ *dst2++ = msk ^ 0x33;
+
+ pos += 2;
+ }
+ }
+ } else {
+ if (_configRenderMode != Common::kRenderEGA)
+ memcpy(_vcnColTable, colMap, 32);
+ memcpy(_vcnBlocks, pos, vcnSize);
+ }
+}
+
+void EoBCoreEngine::loadBlockProperties(const char *mazFile) {
+ memset(_levelBlockProperties, 0, 1024 * sizeof(LevelBlockProperty));
+ const uint8 *p = getBlockFileData(mazFile) + 6;
+
+ if (_hasTempDataFlags & (1 << (_currentLevel - 1))) {
+ restoreBlockTempData(_currentLevel);
+ return;
+ }
+
+ for (int i = 0; i < 1024; i++) {
+ for (int ii = 0; ii < 4; ii++)
+ _levelBlockProperties[i].walls[ii] = *p++;
+ }
+}
+
+const uint8 *EoBCoreEngine::getBlockFileData(int) {
+ Common::SeekableReadStream *s = _res->createReadStream(_curBlockFile);
+ _screen->loadFileDataToPage(s, 15, s->size());
+ delete s;
+ return _screen->getCPagePtr(15);
+}
+
+Common::String EoBCoreEngine::getBlockFileName(int levelIndex, int sub) {
+ readLevelFileData(levelIndex);
+ const uint8 *data = _screen->getCPagePtr(5) + 2;
+ const uint8 *pos = data;
+
+ for (int i = 0; i < sub; i++)
+ pos = data + READ_LE_UINT16(pos);
+
+ pos += 2;
+
+ if (*pos++ == 0xEC || _flags.gameID == GI_EOB1) {
+ if (_flags.gameID == GI_EOB1)
+ pos -= 3;
+
+ return Common::String((const char *)pos);
+ }
+
+ return Common::String();
+}
+
+const uint8 *EoBCoreEngine::getBlockFileData(const char *mazFile) {
+ _curBlockFile = mazFile;
+ return getBlockFileData();
+}
+
+void EoBCoreEngine::loadDecorations(const char *cpsFile, const char *decFile) {
+ _screen->loadShapeSetBitmap(cpsFile, 5, 3);
+ Common::SeekableReadStream *s = _res->createReadStream(decFile);
+
+ _levelDecorationDataSize = s->readUint16LE();
+ delete[] _levelDecorationData;
+ _levelDecorationData = new LevelDecorationProperty[_levelDecorationDataSize];
+ memset(_levelDecorationData, 0, _levelDecorationDataSize * sizeof(LevelDecorationProperty));
+
+ for (int i = 0; i < _levelDecorationDataSize; i++) {
+ LevelDecorationProperty *l = &_levelDecorationData[i];
+ for (int ii = 0; ii < 10; ii++) {
+ l->shapeIndex[ii] = s->readByte();
+ if (l->shapeIndex[ii] == 0xff)
+ l->shapeIndex[ii] = 0xffff;
+ }
+ l->next = s->readByte();
+ l->flags = s->readByte();
+ for (int ii = 0; ii < 10; ii++)
+ l->shapeX[ii] = s->readSint16LE();
+ for (int ii = 0; ii < 10; ii++)
+ l->shapeY[ii] = s->readSint16LE();
+ }
+
+ int len = s->readUint16LE();
+ delete[] _levelDecorationRects;
+ _levelDecorationRects = new EoBRect8[len];
+ for (int i = 0; i < len; i++) {
+ EoBRect8 *l = &_levelDecorationRects[i];
+ l->x = s->readUint16LE();
+ l->y = s->readUint16LE();
+ l->w = s->readUint16LE();
+ l->h = s->readUint16LE();
+ }
+
+ delete s;
+}
+
+void EoBCoreEngine::assignWallsAndDecorations(int wallIndex, int vmpIndex, int decIndex, int specialType, int flags) {
+ _wllVmpMap[wallIndex] = vmpIndex;
+ for (int i = 0; i < 6; i++) {
+ for (int ii = 0; ii < 10; ii++) {
+ if (_characters[i].events[ii] == -57)
+ spellCallback_start_trueSeeing();
+ }
+ }
+ _wllShapeMap[wallIndex] = _mappedDecorationsCount + 1;
+ _specialWallTypes[wallIndex] = specialType;
+ _wllWallFlags[wallIndex] = flags ^ 4;
+
+ if (decIndex == -1) {
+ _wllShapeMap[wallIndex] = 0;
+ return;
+ }
+
+ do {
+ assert(decIndex < _levelDecorationDataSize);
+ memcpy(&_levelDecorationProperties[_mappedDecorationsCount], &_levelDecorationData[decIndex], sizeof(LevelDecorationProperty));
+
+ for (int i = 0; i < 10; i++) {
+ uint16 t = _levelDecorationProperties[_mappedDecorationsCount].shapeIndex[i];
+ if (t == 0xffff)
+ continue;
+
+ if (_levelDecorationShapes[t])
+ continue;
+
+ EoBRect8 *r = &_levelDecorationRects[t];
+ if (r->w == 0 || r->h == 0)
+ error("Error trying to make decoration %d (x: %d, y: %d, w: %d, h: %d)", decIndex, r->x, r->y, r->w, r->h);
+
+ _levelDecorationShapes[t] = _screen->encodeShape(r->x, r->y, r->w, r->h, false, (_flags.gameID == GI_EOB1) ? _cgaMappingLevel[_cgaLevelMappingIndex[_currentLevel - 1]] : 0);
+ }
+
+ decIndex = _levelDecorationProperties[_mappedDecorationsCount++].next;
+
+ if (decIndex)
+ _levelDecorationProperties[_mappedDecorationsCount - 1].next = _mappedDecorationsCount + 1;
+ else
+ decIndex = -1;
+
+ } while (decIndex != -1);
+}
+
+void EoBCoreEngine::releaseDecorations() {
+ if (_levelDecorationShapes) {
+ for (int i = 0; i < 400; i++) {
+ delete[] _levelDecorationShapes[i];
+ _levelDecorationShapes[i] = 0;
+ }
+ }
+ _mappedDecorationsCount = 0;
+}
+
+void EoBCoreEngine::releaseDoorShapes() {
+ for (int i = 0; i < 6; i++) {
+ delete[] _doorShapes[i];
+ _doorShapes[i] = 0;
+ delete[] _doorSwitches[i].shp;
+ _doorSwitches[i].shp = 0;
+ }
+}
+
+void EoBCoreEngine::toggleWallState(int wall, int toggle) {
+ wall = wall * 10 + 3;
+
+ for (int i = 0; i < 9 ; i++) {
+ if (i == 4)
+ continue;
+
+ if (toggle)
+ _wllWallFlags[wall + i] |= 2;
+ else
+ _wllWallFlags[wall + i] &= 0xfd;
+ }
+}
+
+void EoBCoreEngine::drawScene(int refresh) {
+ generateBlockDrawingBuffer();
+ drawVcnBlocks();
+ drawSceneShapes();
+
+ if (_sceneDrawPage2) {
+ if (refresh)
+ _screen->fillRect(0, 0, 176, 120, 12);
+
+ if (!_loading)
+ _screen->setScreenPalette(_screen->getPalette(0));
+
+ _sceneDrawPage2 = 0;
+ }
+
+ uint32 ct = _system->getMillis();
+ if (_flashShapeTimer > ct) {
+ int diff = _flashShapeTimer - ct;
+ while ((diff > 0) && !shouldQuit()) {
+ updateInput();
+ uint32 step = MIN<uint32>(diff, _tickLength / 5);
+ _system->delayMillis(step);
+ diff -= step;
+ }
+ }
+
+ if (_sceneDefaultUpdate)
+ delayUntil(_drawSceneTimer);
+
+ if (refresh && !_partyResting)
+ _screen->copyRegion(0, 0, 0, 0, 176, 120, 2, 0, Screen::CR_NO_P_CHECK);
+
+ updateEnvironmentalSfx(0);
+
+ if (!_dialogueField && refresh && !_updateFlags)
+ gui_drawCompass(false);
+
+ if (refresh && !_partyResting && !_loading)
+ _screen->updateScreen();
+
+ if (_sceneDefaultUpdate) {
+ _sceneDefaultUpdate = false;
+ _drawSceneTimer = _system->getMillis() + 4 * _tickLength;
+ }
+
+ _sceneUpdateRequired = false;
+}
+
+void EoBCoreEngine::drawSceneShapes(int start) {
+ for (int i = start; i < 18; i++) {
+ uint8 t = _dscTileIndex[i];
+ uint8 s = _visibleBlocks[t]->walls[_sceneDrawVarDown];
+
+ _shpDmX1 = 0;
+ _shpDmX2 = 0;
+
+ setLevelShapesDim(t, _shpDmX1, _shpDmX2, _sceneShpDim);
+
+ if (_shpDmX2 <= _shpDmX1)
+ continue;
+
+ drawDecorations(t);
+
+ if (_visibleBlocks[t]->drawObjects)
+ drawBlockItems(t);
+
+ if (t < 15) {
+ uint16 w = _wllWallFlags[s];
+
+ if (w & 8)
+ drawDoor(t);
+
+ if (_visibleBlocks[t]->flags & 7) {
+ const ScreenDim *dm = _screen->getScreenDim(5);
+ _screen->modifyScreenDim(5, dm->sx, _lvlShapeTop[t], dm->w, _lvlShapeBottom[t] - _lvlShapeTop[t]);
+ drawMonsters(t);
+ drawLevelModifyScreenDim(5, _lvlShapeLeftRight[(t << 1)], 0, _lvlShapeLeftRight[(t << 1) + 1], 15);
+ }
+
+ if (_flags.gameID == GI_EOB2 && s == 74)
+ drawWallOfForce(t);
+ }
+
+ drawFlyingObjects(t);
+
+ if (s == _teleporterWallId)
+ drawTeleporter(t);
+ }
+}
+
+void EoBCoreEngine::drawDecorations(int index) {
+ for (int i = 1; i >= 0; i--) {
+ int s = index * 2 + i;
+ if (_dscWallMapping[s]) {
+ int16 d = *_dscWallMapping[s];
+ int8 l = _wllShapeMap[_visibleBlocks[index]->walls[d]];
+
+ uint8 *shapeData = 0;
+
+ int x = 0;
+
+ while (l > 0) {
+ l--;
+ int8 ix = _dscShapeIndex[s];
+ uint8 shpIx = ABS(ix) - 1;
+ uint8 flg = _levelDecorationProperties[l].flags;
+
+ if ((i == 0) && (flg & 1 || ((flg & 2) && _wllProcessFlag)))
+ ix = -ix;
+
+ if (_levelDecorationProperties[l].shapeIndex[shpIx] == 0xffff) {
+ l = _levelDecorationProperties[l].next;
+ continue;
+ }
+
+ shapeData = _levelDecorationShapes[_levelDecorationProperties[l].shapeIndex[shpIx]];
+ if (shapeData) {
+ x = 0;
+ if (i == 0) {
+ if (flg & 4)
+ x += _dscShapeCoords[(index * 5 + 4) << 1];
+ else
+ x += _dscShapeX[index];
+ }
+
+ if (ix < 0) {
+ x += (176 - _levelDecorationProperties[l].shapeX[shpIx] - (shapeData[2] << 3));
+ drawBlockObject(1, 2, shapeData, x, _levelDecorationProperties[l].shapeY[shpIx], _sceneShpDim);
+ } else {
+ x += _levelDecorationProperties[l].shapeX[shpIx];
+ drawBlockObject(0, 2, shapeData, x, _levelDecorationProperties[l].shapeY[shpIx], _sceneShpDim);
+
+ }
+ }
+ l = _levelDecorationProperties[l].next;
+ continue;
+ }
+ }
+ }
+}
+
+int EoBCoreEngine::calcNewBlockPositionAndTestPassability(uint16 curBlock, uint16 direction) {
+ uint16 b = calcNewBlockPosition(curBlock, direction);
+ int w = _levelBlockProperties[b].walls[direction ^ 2];
+ int f = _wllWallFlags[w];
+
+ assert((_flags.gameID == GI_EOB1 && w < 70) || (_flags.gameID == GI_EOB2 && w < 80));
+
+ if (_flags.gameID == GI_EOB2 && w == 74 && _currentBlock == curBlock) {
+ for (int i = 0; i < 5; i++) {
+ if (_wallsOfForce[i].block == b) {
+ destroyWallOfForce(i);
+ f = _wllWallFlags[0];
+ }
+ }
+ }
+
+ if (!(f & 1) || _levelBlockProperties[b].flags & 7)
+ return -1;
+
+ return b;
+}
+
+void EoBCoreEngine::notifyBlockNotPassable() {
+ _txt->printMessage(_warningStrings[0]);
+ snd_playSoundEffect(29);
+ removeInputTop();
+}
+
+void EoBCoreEngine::moveParty(uint16 block) {
+ updateAllMonsterDests();
+ uint16 old = _currentBlock;
+ _currentBlock = block;
+
+ runLevelScript(old, 2);
+
+ if (++_moveCounter > 3) {
+ _txt->printMessage("\r");
+ _moveCounter = 0;
+ }
+
+ runLevelScript(block, 1);
+
+ if (_flags.gameID == GI_EOB2 && _levelBlockProperties[block].walls[0] == 26)
+ memset(_levelBlockProperties[block].walls, 0, 4);
+
+ updateAllMonsterDests();
+ _stepCounter++;
+ //_keybControlUnk = -1;
+ _sceneUpdateRequired = true;
+
+ checkFlyingObjects();
+}
+
+int EoBCoreEngine::clickedDoorSwitch(uint16 block, uint16 direction) {
+ uint8 v = _visibleBlocks[13]->walls[_sceneDrawVarDown];
+ SpriteDecoration *d = &_doorSwitches[((v > 12 && v < 23) || v == 31) ? 3 : 0];
+ int x1 = d->x + _dscShapeCoords[138] - 4;
+ int y1 = d->y - 4;
+
+ if (_flags.gameID == GI_EOB1 && _currentLevel >= 4 && _currentLevel <= 6) {
+ if (v >= 30)
+ x1 += 4;
+ else
+ x1 += ((v - _dscDoorXE[v]) * 9);
+ }
+
+ if (!posWithinRect(_mouseX, _mouseY, x1, y1, x1 + (d->shp[2] << 3) + 8, y1 + d->shp[1] + 8) && (_clickedSpecialFlag == 0x40))
+ return clickedDoorNoPry(block, direction);
+
+ processDoorSwitch(block, 0);
+ snd_playSoundEffect(6);
+
+ return 1;
+}
+
+int EoBCoreEngine::clickedNiche(uint16 block, uint16 direction) {
+ uint8 v = _wllShapeMap[_levelBlockProperties[block].walls[direction]];
+ if (!clickedShape(v))
+ return 0;
+
+ if (_itemInHand) {
+ if (_dscItemShapeMap[_items[_itemInHand].icon] <= 14) {
+ _txt->printMessage(_pryDoorStrings[5]);
+ } else {
+ setItemPosition((Item *)&_levelBlockProperties[block & 0x3ff].drawObjects, block, _itemInHand, 8);
+ runLevelScript(block, 4);
+ setHandItem(0);
+ _sceneUpdateRequired = true;
+ }
+ } else {
+ int d = getQueuedItem((Item *)&_levelBlockProperties[block].drawObjects, 8, -1);
+ if (!d)
+ return 1;
+ runLevelScript(block, 8);
+ setHandItem(d);
+ _sceneUpdateRequired = true;
+ }
+
+ return 1;
+}
+
+int EoBCoreEngine::clickedDoorPry(uint16 block, uint16 direction) {
+ if (!posWithinRect(_mouseX, _mouseY, 40, 16, 136, 88) && (_clickedSpecialFlag == 0x40))
+ return 0;
+
+ int d = -1;
+ for (int i = 0; i < 6; i++) {
+ if (!testCharacter(i, 0x0d))
+ continue;
+ if (d >= 0) {
+ int s1 = _characters[i].strengthCur + _characters[i].strengthExtCur;
+ int s2 = _characters[d].strengthCur + _characters[d].strengthExtCur;
+ if (s1 >= s2)
+ d = i;
+ } else {
+ d = i;
+ }
+ }
+
+ if (d == -1) {
+ _txt->printMessage(_pryDoorStrings[_flags.gameID == GI_EOB2 ? 1 : 0]);
+ return 1;
+ }
+
+ static const uint8 forceDoorChanceTable[] = { 1, 1, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 10, 11, 12, 13 };
+ int s = _characters[d].strengthCur > 18 ? 18 : _characters[d].strengthCur;
+
+ if (rollDice(1, 20) < forceDoorChanceTable[s]) {
+ _txt->printMessage(_pryDoorStrings[_flags.gameID == GI_EOB2 ? 2 : 1]);
+ _levelBlockProperties[block].walls[direction] = _levelBlockProperties[block].walls[direction ^ 2] =
+ (_levelBlockProperties[block].walls[direction] == (_flags.gameID == GI_EOB2 ? 51 : 30)) ? 8 : 18;
+ openDoor(block);
+ } else {
+ _txt->printMessage(_pryDoorStrings[3]);
+ }
+
+ return 1;
+}
+
+int EoBCoreEngine::clickedDoorNoPry(uint16 block, uint16 direction) {
+ if (!posWithinRect(_mouseX, _mouseY, 40, 16, 136, 88) && (_clickedSpecialFlag == 0x40))
+ return 0;
+
+ if (!(_wllWallFlags[_levelBlockProperties[block].walls[direction]] & 0x20))
+ return 0;
+ _txt->printMessage(_pryDoorStrings[6]);
+ return 1;
+}
+
+int EoBCoreEngine::specialWallAction(int block, int direction) {
+ direction ^= 2;
+ uint8 type = _specialWallTypes[_levelBlockProperties[block].walls[direction]];
+ if (!type || !(_clickedSpecialFlag & (((_levelBlockProperties[block].flags & 0xf8) >> 3) | 0xe0)))
+ return 0;
+
+ int res = 0;
+ switch (type) {
+ case 1:
+ res = clickedDoorSwitch(block, direction);
+ break;
+
+ case 2:
+ case 8:
+ res = clickedWallShape(block, direction);
+ break;
+
+ case 3:
+ res = clickedLeverOn(block, direction);
+ break;
+
+ case 4:
+ res = clickedLeverOff(block, direction);
+ break;
+
+ case 5:
+ res = clickedDoorPry(block, direction);
+ break;
+
+ case 6:
+ res = clickedDoorNoPry(block, direction);
+ break;
+
+ case 7:
+ case 9:
+ res = clickedWallOnlyScript(block);
+ break;
+
+ case 10:
+ res = clickedNiche(block, direction);
+ break;
+
+ default:
+ break;
+ }
+
+ _clickedSpecialFlag = 0;
+ _sceneUpdateRequired = true;
+
+ return res;
+}
+
+void EoBCoreEngine::openDoor(int block) {
+ openCloseDoor(block, 1);
+}
+
+void EoBCoreEngine::closeDoor(int block) {
+ if (block == _currentBlock || _levelBlockProperties[block].flags & 7)
+ return;
+ openCloseDoor(block, -1);
+}
+
+} // End of namespace Kyra
+
+#endif // ENABLE_EOB
diff --git a/engines/kyra/scene_lok.cpp b/engines/kyra/scene_lok.cpp
index a926f8493f..ea09091af7 100644
--- a/engines/kyra/scene_lok.cpp
+++ b/engines/kyra/scene_lok.cpp
@@ -131,7 +131,7 @@ void KyraEngine_LoK::enterNewScene(int sceneId, int facing, int unk1, int unk2,
_emc->run(&_scriptClick);
}
- memset(_entranceMouseCursorTracks, 0xFFFF, sizeof(uint16)*4);
+ memset(_entranceMouseCursorTracks, 0xFF, sizeof(_entranceMouseCursorTracks));
_currentCharacter->sceneId = sceneId;
assert(sceneId < _roomTableSize);
@@ -158,7 +158,7 @@ void KyraEngine_LoK::enterNewScene(int sceneId, int facing, int unk1, int unk2,
_walkBlockWest = currentRoom->westExit;
if (_walkBlockNorth == 0xFFFF)
- _screen->blockOutRegion(0, 0, 320, (_northExitHeight & 0xFF)+3);
+ _screen->blockOutRegion(0, 0, 320, (_northExitHeight & 0xFF) + 3);
if (_walkBlockEast == 0xFFFF)
_screen->blockOutRegion(312, 0, 8, 139);
if (_walkBlockSouth == 0xFFFF)
@@ -348,22 +348,22 @@ void KyraEngine_LoK::setCharacterPositionHelper(int character, int *facingTable)
};
if (facing == 0) {
- if (maxAnimationFrame[36+character] > ch->currentAnimFrame)
- ch->currentAnimFrame = maxAnimationFrame[36+character];
- if (maxAnimationFrame[30+character] < ch->currentAnimFrame)
- ch->currentAnimFrame = maxAnimationFrame[36+character];
+ if (maxAnimationFrame[36 + character] > ch->currentAnimFrame)
+ ch->currentAnimFrame = maxAnimationFrame[36 + character];
+ if (maxAnimationFrame[30 + character] < ch->currentAnimFrame)
+ ch->currentAnimFrame = maxAnimationFrame[36 + character];
} else if (facing == 4) {
- if (maxAnimationFrame[18+character] > ch->currentAnimFrame)
- ch->currentAnimFrame = maxAnimationFrame[18+character];
- if (maxAnimationFrame[12+character] < ch->currentAnimFrame)
- ch->currentAnimFrame = maxAnimationFrame[18+character];
+ if (maxAnimationFrame[18 + character] > ch->currentAnimFrame)
+ ch->currentAnimFrame = maxAnimationFrame[18 + character];
+ if (maxAnimationFrame[12 + character] < ch->currentAnimFrame)
+ ch->currentAnimFrame = maxAnimationFrame[18 + character];
} else {
- if (maxAnimationFrame[18+character] < ch->currentAnimFrame)
- ch->currentAnimFrame = maxAnimationFrame[30+character];
+ if (maxAnimationFrame[18 + character] < ch->currentAnimFrame)
+ ch->currentAnimFrame = maxAnimationFrame[30 + character];
if (maxAnimationFrame[character] == ch->currentAnimFrame)
- ch->currentAnimFrame = maxAnimationFrame[6+character];
+ ch->currentAnimFrame = maxAnimationFrame[6 + character];
if (maxAnimationFrame[character] < ch->currentAnimFrame)
- ch->currentAnimFrame = maxAnimationFrame[6+character]+2;
+ ch->currentAnimFrame = maxAnimationFrame[6 + character] + 2;
}
if (character == 0 && (_brandonStatusBit & 0x10))
@@ -596,7 +596,7 @@ void KyraEngine_LoK::initSceneObjectList(int brandonAlive) {
curAnimState->drawY = _currentCharacter->y1;
curAnimState->sceneAnimPtr = _shapes[_currentCharacter->currentAnimFrame];
curAnimState->animFrameNumber = _currentCharacter->currentAnimFrame;
- startAnimFrame = _currentCharacter->currentAnimFrame-7;
+ startAnimFrame = _currentCharacter->currentAnimFrame - 7;
int xOffset = _defaultShapeTable[startAnimFrame].xOffset;
int yOffset = _defaultShapeTable[startAnimFrame].yOffset;
@@ -638,7 +638,7 @@ void KyraEngine_LoK::initSceneObjectList(int brandonAlive) {
curAnimState->drawY = ch->y1;
curAnimState->sceneAnimPtr = _shapes[ch->currentAnimFrame];
curAnimState->animFrameNumber = ch->currentAnimFrame;
- startAnimFrame = ch->currentAnimFrame-7;
+ startAnimFrame = ch->currentAnimFrame - 7;
xOffset = _defaultShapeTable[startAnimFrame].xOffset;
yOffset = _defaultShapeTable[startAnimFrame].yOffset;
if (_scaleMode) {
@@ -714,7 +714,7 @@ void KyraEngine_LoK::initSceneObjectList(int brandonAlive) {
byte curItem = curRoom->itemsTable[i];
if (curItem != 0xFF) {
curAnimState->drawY = curRoom->itemsYPos[i];
- curAnimState->sceneAnimPtr = _shapes[216+curItem];
+ curAnimState->sceneAnimPtr = _shapes[216 + curItem];
curAnimState->animFrameNumber = (int16)0xFFFF;
curAnimState->y1 = curRoom->itemsYPos[i];
curAnimState->x1 = curRoom->itemsXPos[i];
@@ -780,10 +780,10 @@ void KyraEngine_LoK::initSceneScreen(int brandonAlive) {
} else {
if (_unkScreenVar1 && !queryGameFlag(0xA0)) {
for (int i = 0; i < 60; ++i) {
- uint16 col = _screen->getPalette(0)[684+i];
- col += _screen->getPalette(1)[684+i] << 1;
+ uint16 col = _screen->getPalette(0)[684 + i];
+ col += _screen->getPalette(1)[684 + i] << 1;
col >>= 2;
- _screen->getPalette(0)[684+i] = col;
+ _screen->getPalette(0)[684 + i] = col;
}
_screen->setScreenPalette(_screen->getPalette(0));
}
@@ -847,7 +847,7 @@ int KyraEngine_LoK::handleSceneChange(int xpos, int ypos, int unk1, int frameRes
}
}
- if (ypos <= (_northExitHeight&0xFF)+2) {
+ if (ypos <= (_northExitHeight & 0xFF) + 2) {
if (_roomTable[sceneId].northExit != 0xFFFF) {
xpos = _sceneExits.northXPos;
ypos = _northExitHeight & 0xFF;
@@ -1093,7 +1093,7 @@ void KyraEngine_LoK::setCharactersInDefaultScene() {
Character *cur = &_characterList[i];
//cur->field_20 = 0;
- const uint32 *curTable = defaultSceneTable[i-1];
+ const uint32 *curTable = defaultSceneTable[i - 1];
cur->sceneId = curTable[0];
if (cur->sceneId == _currentCharacter->sceneId)
diff --git a/engines/kyra/scene_lol.cpp b/engines/kyra/scene_lol.cpp
index a5a2562448..628654f127 100644
--- a/engines/kyra/scene_lol.cpp
+++ b/engines/kyra/scene_lol.cpp
@@ -42,8 +42,8 @@ void LoLEngine::loadLevel(int index) {
stopPortraitSpeechAnim();
for (int i = 0; i < 400; i++) {
- delete[] _levelShapes[i];
- _levelShapes[i] = 0;
+ delete[] _levelDecorationShapes[i];
+ _levelDecorationShapes[i] = 0;
}
_emc->unload(&_scriptData);
@@ -105,16 +105,16 @@ void LoLEngine::addLevelItems() {
if (_itemsInPlay[i].level != _currentLevel)
continue;
- assignBlockObject(&_levelBlockProperties[_itemsInPlay[i].block], i);
+ assignBlockItem(&_levelBlockProperties[_itemsInPlay[i].block], i);
_levelBlockProperties[_itemsInPlay[i].block].direction = 5;
_itemsInPlay[i].nextDrawObject = 0;
}
}
-void LoLEngine::assignBlockObject(LevelBlockProperty *l, uint16 item) {
+void LoLEngine::assignBlockItem(LevelBlockProperty *l, uint16 item) {
uint16 *index = &l->assignedObjects;
- ItemInPlay *tmp = 0;
+ LoLObject *tmp = 0;
while (*index & 0x8000) {
tmp = findObject(*index);
@@ -122,7 +122,7 @@ void LoLEngine::assignBlockObject(LevelBlockProperty *l, uint16 item) {
}
tmp = findObject(item);
- tmp->level = -1;
+ ((LoLItem *)tmp)->level = -1;
uint16 ix = *index;
@@ -160,7 +160,7 @@ void LoLEngine::loadLevelWallData(int index, bool mapShapes) {
if (mapShapes) {
int16 sh = (int16) READ_LE_UINT16(d);
if (sh > 0)
- _wllShapeMap[c] = assignLevelShapes(sh);
+ _wllShapeMap[c] = assignLevelDecorationShapes(sh);
else
_wllShapeMap[c] = *d;
}
@@ -169,7 +169,7 @@ void LoLEngine::loadLevelWallData(int index, bool mapShapes) {
d += 2;
_wllWallFlags[c] = *d;
d += 2;
- _wllBuffer4[c] = *d;
+ _wllAutomapData[c] = *d;
d += 2;
}
@@ -179,7 +179,7 @@ void LoLEngine::loadLevelWallData(int index, bool mapShapes) {
_lvlShpFileHandle = 0;
}
-int LoLEngine::assignLevelShapes(int index) {
+int LoLEngine::assignLevelDecorationShapes(int index) {
uint16 *p1 = (uint16 *)_tempBuffer5120;
uint16 *p2 = (uint16 *)(_tempBuffer5120 + 4000);
@@ -187,34 +187,35 @@ int LoLEngine::assignLevelShapes(int index) {
if (r)
return r;
- uint16 o = _lvlBlockIndex++;
+ uint16 o = _mappedDecorationsCount++;
- memcpy(&_levelShapeProperties[o], &_levelFileData[index], sizeof(LevelShapeProperty));
+ memcpy(&_levelDecorationProperties[o], &_levelDecorationData[index], sizeof(LevelDecorationProperty));
for (int i = 0; i < 10; i++) {
- uint16 t = _levelShapeProperties[o].shapeIndex[i];
+ uint16 t = _levelDecorationProperties[o].shapeIndex[i];
if (t == 0xffff)
continue;
uint16 pv = p1[t];
if (pv) {
- _levelShapeProperties[o].shapeIndex[i] = pv;
+ _levelDecorationProperties[o].shapeIndex[i] = pv;
} else {
- _levelShapes[_lvlShapeIndex] = getLevelShapes(t);
+ releaseDecorations(_lvlShapeIndex, 1);
+ _levelDecorationShapes[_lvlShapeIndex] = getLevelDecorationShapes(t);
p1[t] = _lvlShapeIndex;
- _levelShapeProperties[o].shapeIndex[i] = _lvlShapeIndex++;
+ _levelDecorationProperties[o].shapeIndex[i] = _lvlShapeIndex++;
}
}
p2[index] = o;
- if (_levelShapeProperties[o].next)
- _levelShapeProperties[o].next = assignLevelShapes(_levelShapeProperties[o].next);
+ if (_levelDecorationProperties[o].next)
+ _levelDecorationProperties[o].next = assignLevelDecorationShapes(_levelDecorationProperties[o].next);
return o;
}
-uint8 *LoLEngine::getLevelShapes(int shapeIndex) {
- if (_lvlShpNum <= shapeIndex)
+uint8 *LoLEngine::getLevelDecorationShapes(int shapeIndex) {
+ if (_decorationCount <= shapeIndex)
return 0;
_lvlShpFileHandle->seek(shapeIndex * 4 + 2, SEEK_SET);
@@ -232,57 +233,10 @@ uint8 *LoLEngine::getLevelShapes(int shapeIndex) {
return res;
}
-void LoLEngine::restoreBlockTempData(int index) {
- memset(_tempBuffer5120, 0, 5120);
- int l = index - 1;
-
- memcpy(_monsters, _lvlTempData[l]->monsters, sizeof(MonsterInPlay) * 30);
- memcpy(_flyingObjects, _lvlTempData[l]->flyingObjects, sizeof(FlyingObject) * 8);
-
- Common::String filename = Common::String::format("LEVEL%d.CMZ", index);
-
- _screen->loadBitmap(filename.c_str(), 3, 3, 0);
- const uint8 *p = _screen->getCPagePtr(2);
- uint16 len = READ_LE_UINT16(p + 4);
- p += 6;
-
- memset(_levelBlockProperties, 0, 1024 * sizeof(LevelBlockProperty));
-
- uint8 *t = _lvlTempData[l]->wallsXorData;
- uint8 *t2 = _lvlTempData[l]->flags;
-
- for (int i = 0; i < 1024; i++) {
- for (int ii = 0; ii < 4; ii++)
- _levelBlockProperties[i].walls[ii] = p[i * len + ii] ^ *t++;
- _levelBlockProperties[i].flags = *t2++;
- }
-
- for (int i = 0; i < 30; i++) {
- if (_monsters[i].block) {
- _monsters[i].block = 0;
- _monsters[i].properties = &_monsterProperties[_monsters[i].type];
- placeMonster(&_monsters[i], _monsters[i].x, _monsters[i].y);
- }
- }
-
- restoreTempDataAdjustMonsterStrength(l);
-}
-
-void LoLEngine::restoreTempDataAdjustMonsterStrength(int index) {
- if (_lvlTempData[index]->monsterDifficulty == _monsterDifficulty)
- return;
-
- uint16 d = (_monsterModifiers[_lvlTempData[index]->monsterDifficulty] << 8) / _monsterModifiers[_monsterDifficulty];
-
- for (int i = 0; i < 30; i++) {
- if (_monsters[i].mode >= 14 || _monsters[i].block == 0 || _monsters[i].hitPoints <= 0)
- continue;
-
- _monsters[i].hitPoints = (d * _monsters[i].hitPoints) >> 8;
- if (_monsterDifficulty < _lvlTempData[index]->monsterDifficulty)
- _monsters[i].hitPoints++;
- if (_monsters[i].hitPoints == 0)
- _monsters[i].hitPoints = 1;
+void LoLEngine::releaseDecorations(int first, int num) {
+ for (int i = first; i < (first + num); i++) {
+ delete[] _levelDecorationShapes[i];
+ _levelDecorationShapes[i] = 0;
}
}
@@ -299,26 +253,31 @@ void LoLEngine::loadBlockProperties(const char *cmzFile) {
_levelBlockProperties[i].direction = 5;
- if (_wllBuffer4[_levelBlockProperties[i].walls[0]] == 17) {
+ if (_wllAutomapData[_levelBlockProperties[i].walls[0]] == 17) {
_levelBlockProperties[i].flags &= 0xef;
_levelBlockProperties[i].flags |= 0x20;
}
}
}
+const uint8 *LoLEngine::getBlockFileData(int levelIndex) {
+ _screen->loadBitmap(Common::String::format("LEVEL%d.CMZ", levelIndex).c_str(), 15, 15, 0);
+ return _screen->getCPagePtr(14);
+}
+
void LoLEngine::loadLevelShpDat(const char *shpFile, const char *datFile, bool flag) {
memset(_tempBuffer5120, 0, 5120);
_lvlShpFileHandle = _res->createReadStream(shpFile);
- _lvlShpNum = _lvlShpFileHandle->readUint16LE();
+ _decorationCount = _lvlShpFileHandle->readUint16LE();
Common::SeekableReadStream *s = _res->createReadStream(datFile);
- _levelFileDataSize = s->readUint16LE();
- delete[] _levelFileData;
- _levelFileData = new LevelShapeProperty[_levelFileDataSize];
- for (int i = 0; i < _levelFileDataSize; i++) {
- LevelShapeProperty * l = &_levelFileData[i];
+ _levelDecorationDataSize = s->readUint16LE();
+ delete[] _levelDecorationData;
+ _levelDecorationData = new LevelDecorationProperty[_levelDecorationDataSize];
+ for (int i = 0; i < _levelDecorationDataSize; i++) {
+ LevelDecorationProperty *l = &_levelDecorationData[i];
for (int ii = 0; ii < 10; ii++)
l->shapeIndex[ii] = s->readUint16LE();
for (int ii = 0; ii < 10; ii++)
@@ -334,7 +293,7 @@ void LoLEngine::loadLevelShpDat(const char *shpFile, const char *datFile, bool f
delete s;
if (!flag) {
- _lvlBlockIndex = 1;
+ _mappedDecorationsCount = 1;
_lvlShapeIndex = 1;
}
}
@@ -399,7 +358,7 @@ void LoLEngine::loadLevelGraphics(const char *file, int specialColor, int weight
memcpy(_vcnShift, v, tlen);
v += tlen;
- memcpy(_vcnExpTable, v, 128);
+ memcpy(_vcnColTable, v, 128);
v += 128;
if (_lastOverridePalFilePtr) {
@@ -492,7 +451,7 @@ void LoLEngine::loadLevelGraphics(const char *file, int specialColor, int weight
for (int i = 0; i < 8; i++) {
uint8 *pl = _screen->getLevelOverlay(7 - i);
for (int ii = 0; ii < 16; ii++)
- _vcnExpTable[(i << 4) + ii] = pl[(ii << 4) | ii];
+ _vcnColTable[(i << 4) + ii] = pl[(ii << 4) | ii];
}
}
@@ -515,17 +474,17 @@ void LoLEngine::resetItems(int flag) {
for (int i = 0; i < 1024; i++) {
_levelBlockProperties[i].direction = 5;
uint16 id = _levelBlockProperties[i].assignedObjects;
- MonsterInPlay *r = 0;
+ LoLObject *r = 0;
while (id & 0x8000) {
- r = (MonsterInPlay *)findObject(id);
+ r = findObject(id);
id = r->nextAssignedObject;
}
if (!id)
continue;
- ItemInPlay *it = &_itemsInPlay[id];
+ LoLItem *it = &_itemsInPlay[id];
it->level = _currentLevel;
it->block = i;
if (r)
@@ -537,7 +496,7 @@ void LoLEngine::resetItems(int flag) {
}
void LoLEngine::disableMonsters() {
- memset(_monsters, 0, 30 * sizeof(MonsterInPlay));
+ memset(_monsters, 0, 30 * sizeof(LoLMonster));
for (int i = 0; i < 30; i++)
_monsters[i].mode = 0x10;
}
@@ -751,11 +710,6 @@ void LoLEngine::moveParty(uint16 direction, int unk1, int unk2, int buttonShape)
updateAutoMap(_currentBlock);
}
-uint16 LoLEngine::calcNewBlockPosition(uint16 curBlock, uint16 direction) {
- static const int16 blockPosTable[] = { -32, 1, 32, -1 };
- return (curBlock + blockPosTable[direction]) & 0x3ff;
-}
-
uint16 LoLEngine::calcBlockIndex(uint16 x, uint16 y) {
return (((y & 0xff00) >> 3) | (x >> 8)) & 0x3ff;
}
@@ -827,51 +781,6 @@ void LoLEngine::notifyBlockNotPassable(int scrollFlag) {
snd_playSoundEffect(19, -1);
}
-int LoLEngine::clickedWallShape(uint16 block, uint16 direction) {
- uint8 v = _wllShapeMap[_levelBlockProperties[block].walls[direction]];
- if (!clickedShape(v))
- return 0;
-
- snd_stopSpeech(true);
- runLevelScript(block, 0x40);
-
- return 1;
-}
-
-int LoLEngine::clickedLeverOn(uint16 block, uint16 direction) {
- uint8 v = _wllShapeMap[_levelBlockProperties[block].walls[direction]];
- if (!clickedShape(v))
- return 0;
-
- _levelBlockProperties[block].walls[direction]++;
- _sceneUpdateRequired = true;
-
- snd_playSoundEffect(30, -1);
-
- runLevelScript(block, 0x40);
-
- return 1;
-}
-
-int LoLEngine::clickedLeverOff(uint16 block, uint16 direction) {
- uint8 v = _wllShapeMap[_levelBlockProperties[block].walls[direction]];
- if (!clickedShape(v))
- return 0;
-
- _levelBlockProperties[block].walls[direction]--;
- _sceneUpdateRequired = true;
-
- snd_playSoundEffect(29, -1);
-
- runLevelScript(block, 0x40);
- return 1;
-}
-
-int LoLEngine::clickedWallOnlyScript(uint16 block) {
- runLevelScript(block, 0x40);
- return 1;
-}
-
int LoLEngine::clickedDoorSwitch(uint16 block, uint16 direction) {
uint8 v = _wllShapeMap[_levelBlockProperties[block].walls[direction]];
if (!clickedShape(v))
@@ -903,119 +812,6 @@ int LoLEngine::clickedNiche(uint16 block, uint16 direction) {
return 1;
}
-bool LoLEngine::clickedShape(int shapeIndex) {
- while (shapeIndex) {
- uint16 s = _levelShapeProperties[shapeIndex].shapeIndex[1];
-
- if (s == 0xffff) {
- shapeIndex = _levelShapeProperties[shapeIndex].next;
- continue;
- }
-
- int w = _levelShapes[s][3];
- int h = _levelShapes[s][2];
- int x = _levelShapeProperties[shapeIndex].shapeX[1] + 136;
- int y = _levelShapeProperties[shapeIndex].shapeY[1] + 8;
-
- if (_levelShapeProperties[shapeIndex].flags & 1)
- w <<= 1;
-
- if (posWithinRect(_mouseX, _mouseY, x - 4, y - 4, x + w + 8, y + h + 8))
- return true;
-
- shapeIndex = _levelShapeProperties[shapeIndex].next;
- }
-
- return false;
-}
-
-void LoLEngine::processDoorSwitch(uint16 block, int openClose) {
- if ((block == _currentBlock) || (_levelBlockProperties[block].assignedObjects & 0x8000))
- return;
-
- if (openClose == 0) {
- for (int i = 0; i < 3; i++) {
- if (_openDoorState[i].block != block)
- continue;
- openClose = -_openDoorState[i].state;
- break;
- }
- }
-
- if (openClose == 0)
- openClose = (_wllWallFlags[_levelBlockProperties[block].walls[_wllWallFlags[_levelBlockProperties[block].walls[0]] & 8 ? 0 : 1]] & 1) ? 1 : -1;
-
- openCloseDoor(block, openClose);
-}
-
-void LoLEngine::openCloseDoor(uint16 block, int openClose) {
- int s1 = -1;
- int s2 = -1;
-
- int c = (_wllWallFlags[_levelBlockProperties[block].walls[0]] & 8) ? 0 : 1;
- int v = _levelBlockProperties[block].walls[c];
- int flg = (openClose == 1) ? 0x10 : (openClose == -1 ? 0x20 : 0);
-
- if (_wllWallFlags[v] & flg)
- return;
-
- for (int i = 0; i < 3; i++) {
- if (_openDoorState[i].block == block) {
- s1 = i;
- break;
- } else if (_openDoorState[i].block == 0 && s2 == -1) {
- s2 = i;
- }
- }
-
- if (s1 != -1 || s2 != -1) {
- if (s1 == -1)
- s1 = s2;
-
- _openDoorState[s1].block = block;
- _openDoorState[s1].state = openClose;
- _openDoorState[s1].wall = c;
-
- flg = (-openClose == 1) ? 0x10 : (-openClose == -1 ? 0x20 : 0);
-
- if (_wllWallFlags[v] & flg) {
- _levelBlockProperties[block].walls[c] += openClose;
- _levelBlockProperties[block].walls[c ^ 2] += openClose;
-
- int snd = (openClose == -1) ? 32 : 31;
-
- snd_processEnvironmentalSoundEffect(snd, block);
- if (!checkSceneUpdateNeed(block))
- updateEnvironmentalSfx(0);
- }
-
- enableTimer(0);
-
- } else {
- while (!(flg & _wllWallFlags[v]))
- v += openClose;
-
- _levelBlockProperties[block].walls[c] = _levelBlockProperties[block].walls[c ^ 2] = v;
- checkSceneUpdateNeed(block);
- }
-}
-
-void LoLEngine::completeDoorOperations() {
- for (int i = 0; i < 3; i++) {
- if (!_openDoorState[i].block)
- continue;
-
- uint16 b = _openDoorState[i].block;
-
- do {
- _levelBlockProperties[b].walls[_openDoorState[i].wall] += _openDoorState[i].state;
- _levelBlockProperties[b].walls[_openDoorState[i].wall ^ 2] += _openDoorState[i].state;
- } while (!(_wllWallFlags[_levelBlockProperties[b].walls[_openDoorState[i].wall]] & 0x30));
-
- _openDoorState[i].block = 0;
- }
-}
-
void LoLEngine::movePartySmoothScrollBlocked(int speed) {
if (!_smoothScrollingEnabled || (_smoothScrollingEnabled && _needSceneRestore))
return;
@@ -1447,7 +1243,7 @@ void LoLEngine::setWallType(int block, int wall, int val) {
if (wall == -1) {
for (int i = 0; i < 4; i++)
_levelBlockProperties[block].walls[i] = val;
- if (_wllBuffer4[val] == 17) {
+ if (_wllAutomapData[val] == 17) {
_levelBlockProperties[block].flags &= 0xef;
_levelBlockProperties[block].flags |= 0x20;
} else {
@@ -1603,334 +1399,20 @@ void LoLEngine::setDefaultButtonState() {
_lampStatusSuspended = false;
}
-void LoLEngine::generateBlockDrawingBuffer() {
- _sceneDrawVarDown = _dscBlockMap[_currentDirection];
- _sceneDrawVarRight = _dscBlockMap[_currentDirection + 4];
- _sceneDrawVarLeft = _dscBlockMap[_currentDirection + 8];
-
- /*******************************************
- * _visibleBlocks map *
- * *
- * | | | | | | *
- * 00 | 01 | 02 | 03 | 04 | 05 | 06 *
- * ____|_____|_____|_____|_____|_____|_____ *
- * | | | | | | *
- * | 07 | 08 | 09 | 10 | 11 | *
- * |_____|_____|_____|_____|_____| *
- * | | | | *
- * | 12 | 13 | 14 | *
- * |_____|_____|_____| *
- * | | *
- * 15 | 16 | 17 *
- * | (P) | *
- ********************************************/
-
- memset(_blockDrawingBuffer, 0, 660 * sizeof(uint16));
-
- _wllProcessFlag = ((_currentBlock >> 5) + (_currentBlock & 0x1f) + _currentDirection) & 1;
-
- if (_wllProcessFlag) // floor and ceiling
- generateVmpTileDataFlipped(0, 15, 1, -330, 22, 15);
- else
- generateVmpTileData(0, 15, 1, -330, 22, 15);
-
- assignVisibleBlocks(_currentBlock, _currentDirection);
-
- uint8 t = _visibleBlocks[0]->walls[_sceneDrawVarRight];
- if (t)
- generateVmpTileData(-2, 3, t, 102, 3, 5);
-
- t = _visibleBlocks[6]->walls[_sceneDrawVarLeft];
- if (t)
- generateVmpTileDataFlipped(21, 3, t, 102, 3, 5);
-
- t = _visibleBlocks[1]->walls[_sceneDrawVarRight];
- uint8 t2 = _visibleBlocks[2]->walls[_sceneDrawVarDown];
-
- if (hasWall(t) && !(_wllWallFlags[t2] & 8))
- generateVmpTileData(2, 3, t, 102, 3, 5);
- else if (t && (_wllWallFlags[t2] & 8))
- generateVmpTileData(2, 3, t2, 102, 3, 5);
-
- t = _visibleBlocks[5]->walls[_sceneDrawVarLeft];
- t2 = _visibleBlocks[4]->walls[_sceneDrawVarDown];
-
- if (hasWall(t) && !(_wllWallFlags[t2] & 8))
- generateVmpTileDataFlipped(17, 3, t, 102, 3, 5);
- else if (t && (_wllWallFlags[t2] & 8))
- generateVmpTileDataFlipped(17, 3, t2, 102, 3, 5);
-
- t = _visibleBlocks[2]->walls[_sceneDrawVarRight];
- if (t)
- generateVmpTileData(8, 3, t, 97, 1, 5);
-
- t = _visibleBlocks[4]->walls[_sceneDrawVarLeft];
- if (t)
- generateVmpTileDataFlipped(13, 3, t, 97, 1, 5);
-
- t = _visibleBlocks[1]->walls[_sceneDrawVarDown];
- if (hasWall(t))
- generateVmpTileData(-4, 3, t, 129, 6, 5);
-
- t = _visibleBlocks[5]->walls[_sceneDrawVarDown];
- if (hasWall(t))
- generateVmpTileData(20, 3, t, 129, 6, 5);
-
- t = _visibleBlocks[2]->walls[_sceneDrawVarDown];
- if (hasWall(t))
- generateVmpTileData(2, 3, t, 129, 6, 5);
-
- t = _visibleBlocks[4]->walls[_sceneDrawVarDown];
- if (hasWall(t))
- generateVmpTileData(14, 3, t, 129, 6, 5);
-
- t = _visibleBlocks[3]->walls[_sceneDrawVarDown];
- if (t)
- generateVmpTileData(8, 3, t, 129, 6, 5);
-
- t = _visibleBlocks[7]->walls[_sceneDrawVarRight];
- if (t)
- generateVmpTileData(0, 3, t, 117, 2, 6);
-
- t = _visibleBlocks[11]->walls[_sceneDrawVarLeft];
- if (t)
- generateVmpTileDataFlipped(20, 3, t, 117, 2, 6);
-
- t = _visibleBlocks[8]->walls[_sceneDrawVarRight];
- if (t)
- generateVmpTileData(6, 2, t, 81, 2, 8);
-
- t = _visibleBlocks[10]->walls[_sceneDrawVarLeft];
- if (t)
- generateVmpTileDataFlipped(14, 2, t, 81, 2, 8);
-
- t = _visibleBlocks[8]->walls[_sceneDrawVarDown];
- if (hasWall(t))
- generateVmpTileData(-4, 2, t, 159, 10, 8);
-
- t = _visibleBlocks[10]->walls[_sceneDrawVarDown];
- if (hasWall(t))
- generateVmpTileData(16, 2, t, 159, 10, 8);
-
- t = _visibleBlocks[9]->walls[_sceneDrawVarDown];
- if (t)
- generateVmpTileData(6, 2, t, 159, 10, 8);
-
- t = _visibleBlocks[12]->walls[_sceneDrawVarRight];
- if (t)
- generateVmpTileData(3, 1, t, 45, 3, 12);
-
- t = _visibleBlocks[14]->walls[_sceneDrawVarLeft];
- if (t)
- generateVmpTileDataFlipped(16, 1, t, 45, 3, 12);
-
- t = _visibleBlocks[12]->walls[_sceneDrawVarDown];
- if (!(_wllWallFlags[t] & 8))
- generateVmpTileData(-13, 1, t, 239, 16, 12);
-
- t = _visibleBlocks[14]->walls[_sceneDrawVarDown];
- if (!(_wllWallFlags[t] & 8))
- generateVmpTileData(19, 1, t, 239, 16, 12);
-
- t = _visibleBlocks[13]->walls[_sceneDrawVarDown];
- if (t)
- generateVmpTileData(3, 1, t, 239, 16, 12);
-
- t = _visibleBlocks[15]->walls[_sceneDrawVarRight];
- t2 = _visibleBlocks[17]->walls[_sceneDrawVarLeft];
- if (t)
- generateVmpTileData(0, 0, t, 0, 3, 15);
- if (t2)
- generateVmpTileDataFlipped(19, 0, t2, 0, 3, 15);
-}
-
-void LoLEngine::generateVmpTileData(int16 startBlockX, uint8 startBlockY, uint8 vmpMapIndex, int16 vmpOffset, uint8 numBlocksX, uint8 numBlocksY) {
- if (!_wllVmpMap[vmpMapIndex])
- return;
-
- uint16 *vmp = &_vmpPtr[(_wllVmpMap[vmpMapIndex] - 1) * 431 + vmpOffset + 330];
-
- for (int i = 0; i < numBlocksY; i++) {
- uint16 *bl = &_blockDrawingBuffer[(startBlockY + i) * 22 + startBlockX];
- for (int ii = 0; ii < numBlocksX; ii++) {
- if ((startBlockX + ii >= 0) && (startBlockX + ii < 22) && *vmp)
- *bl = *vmp;
- bl++;
- vmp++;
- }
- }
-}
-
-void LoLEngine::generateVmpTileDataFlipped(int16 startBlockX, uint8 startBlockY, uint8 vmpMapIndex, int16 vmpOffset, uint8 numBlocksX, uint8 numBlocksY) {
- if (!_wllVmpMap[vmpMapIndex])
- return;
-
- uint16 *vmp = &_vmpPtr[(_wllVmpMap[vmpMapIndex] - 1) * 431 + vmpOffset + 330];
-
- for (int i = 0; i < numBlocksY; i++) {
- for (int ii = 0; ii < numBlocksX; ii++) {
- if ((startBlockX + ii) < 0 || (startBlockX + ii) > 21)
- continue;
-
- uint16 v = vmp[i * numBlocksX + (numBlocksX - 1 - ii)];
- if (!v)
- continue;
-
- if (v & 0x4000)
- v -= 0x4000;
- else
- v |= 0x4000;
-
- _blockDrawingBuffer[(startBlockY + i) * 22 + startBlockX + ii] = v;
- }
- }
-}
-
-bool LoLEngine::hasWall(int index) {
- if (!index || (_wllWallFlags[index] & 8))
- return false;
- return true;
-}
-
-void LoLEngine::assignVisibleBlocks(int block, int direction) {
- for (int i = 0; i < 18; i++) {
- uint16 t = (block + _dscBlockIndex[direction * 18 + i]) & 0x3ff;
- _visibleBlockIndex[i] = t;
-
- _visibleBlocks[i] = &_levelBlockProperties[t];
- _lvlShapeLeftRight[i] = _lvlShapeLeftRight[18 + i] = -1;
- }
-}
-
-void LoLEngine::drawVcnBlocks() {
- uint8 *d = _sceneWindowBuffer;
- uint16 *bdb = _blockDrawingBuffer;
-
- for (int y = 0; y < 15; y++) {
- for (int x = 0; x < 22; x++) {
- bool horizontalFlip = false;
- int remainder = 0;
-
- uint16 vcnOffset = *bdb++;
-
- if (vcnOffset & 0x8000) {
- // this renders a wall block over the transparent pixels of a floor/ceiling block
- remainder = vcnOffset - 0x8000;
- vcnOffset = 0;
- }
-
- if (vcnOffset & 0x4000) {
- horizontalFlip = true;
- vcnOffset &= 0x3fff;
- }
-
- uint8 *src = 0;
- if (vcnOffset) {
- src = &_vcnBlocks[vcnOffset << 5];
- } else {
- // floor/ceiling blocks
- vcnOffset = bdb[329];
- if (vcnOffset & 0x4000) {
- horizontalFlip = true;
- vcnOffset &= 0x3fff;
- }
-
- src = (_vcfBlocks ? _vcfBlocks : _vcnBlocks) + (vcnOffset << 5);
- }
-
- uint8 shift = _vcnShift ? _vcnShift[vcnOffset] : _blockBrightness;
-
- if (horizontalFlip) {
- for (int blockY = 0; blockY < 8; blockY++) {
- src += 3;
- for (int blockX = 0; blockX < 4; blockX++) {
- uint8 t = *src--;
- *d++ = _vcnExpTable[(t & 0x0f) | shift];
- *d++ = _vcnExpTable[(t >> 4) | shift];
- }
- src += 5;
- d += 168;
- }
- } else {
- for (int blockY = 0; blockY < 8; blockY++) {
- for (int blockX = 0; blockX < 4; blockX++) {
- uint8 t = *src++;
- *d++ = _vcnExpTable[(t >> 4) | shift];
- *d++ = _vcnExpTable[(t & 0x0f) | shift];
- }
- d += 168;
- }
- }
- d -= 1400;
-
- if (remainder) {
- d -= 8;
- horizontalFlip = false;
-
- if (remainder & 0x4000) {
- remainder &= 0x3fff;
- horizontalFlip = true;
- }
-
- shift = _vcnShift ? _vcnShift[remainder] : _blockBrightness;
- src = &_vcnBlocks[remainder << 5];
-
- if (horizontalFlip) {
- for (int blockY = 0; blockY < 8; blockY++) {
- src += 3;
- for (int blockX = 0; blockX < 4; blockX++) {
- uint8 t = *src--;
- uint8 h = _vcnExpTable[(t & 0x0f) | shift];
- uint8 l = _vcnExpTable[(t >> 4) | shift];
- if (h)
- *d = h;
- d++;
- if (l)
- *d = l;
- d++;
- }
- src += 5;
- d += 168;
- }
- } else {
- for (int blockY = 0; blockY < 8; blockY++) {
- for (int blockX = 0; blockX < 4; blockX++) {
- uint8 t = *src++;
- uint8 h = _vcnExpTable[(t >> 4) | shift];
- uint8 l = _vcnExpTable[(t & 0x0f) | shift];
- if (h)
- *d = h;
- d++;
- if (l)
- *d = l;
- d++;
- }
- d += 168;
- }
- }
- d -= 1400;
- }
- }
- d += 1232;
- }
-
- _screen->copyBlockToPage(_sceneDrawPage1, 112, 0, 176, 120, _sceneWindowBuffer);
-}
-
-void LoLEngine::drawSceneShapes() {
+void LoLEngine::drawSceneShapes(int) {
for (int i = 0; i < 18; i++) {
uint8 t = _dscTileIndex[i];
uint8 s = _visibleBlocks[t]->walls[_sceneDrawVarDown];
- int16 x1 = 0;
- int16 x2 = 0;
+ _shpDmX1 = 0;
+ _shpDmX2 = 0;
int16 dimY1 = 0;
int16 dimY2 = 0;
- setLevelShapesDim(t, x1, x2, 13);
+ setLevelShapesDim(t, _shpDmX1, _shpDmX2, _sceneShpDim);
- if (x2 <= x1)
+ if (_shpDmX2 <= _shpDmX1)
continue;
drawDecorations(t);
@@ -1954,104 +1436,12 @@ void LoLEngine::drawSceneShapes() {
if (v > 80)
v = 80;
- scaleLevelShapesDim(t, dimY1, dimY2, 13);
+ setDoorShapeDim(t, dimY1, dimY2, _sceneShpDim);
drawDoor(_doorShapes[(s < 23 ? _dscDoorShpIndex[s] : 0)], 0, t, 10, 0, -v, 2);
- setLevelShapesDim(t, dimY1, dimY2, 13);
+ setLevelShapesDim(t, dimY1, dimY2, _sceneShpDim);
}
}
-void LoLEngine::setLevelShapesDim(int index, int16 &x1, int16 &x2, int dim) {
- if (_lvlShapeLeftRight[index << 1] == -1) {
- x1 = 0;
- x2 = 22;
-
- int16 y1 = 0;
- int16 y2 = 120;
-
- int m = index * 18;
-
- for (int i = 0; i < 18; i++) {
- uint8 d = _visibleBlocks[i]->walls[_sceneDrawVarDown];
- uint8 a = _wllWallFlags[d];
-
- if (a & 8) {
- int t = _dscDim2[(m + i) << 1];
-
- if (t > x1) {
- x1 = t;
- if (!(a & 0x10))
- scaleLevelShapesDim(index, y1, y2, -1);
- }
-
- t = _dscDim2[((m + i) << 1) + 1];
-
- if (t < x2) {
- x2 = t;
- if (!(a & 0x10))
- scaleLevelShapesDim(index, y1, y2, -1);
- }
- } else {
- int t = _dscDim1[m + i];
-
- if (!_wllVmpMap[d] || t == -40)
- continue;
-
- if (t == -41) {
- x1 = 22;
- x2 = 0;
- break;
- }
-
- if (t > 0 && x2 > t)
- x2 = t;
-
- if (t < 0 && x1 < -t)
- x1 = -t;
- }
-
- if (x2 < x1)
- break;
- }
-
- x1 += 14;
- x2 += 14;
-
- _lvlShapeTop[index] = y1;
- _lvlShapeBottom[index] = y2;
- _lvlShapeLeftRight[index << 1] = x1;
- _lvlShapeLeftRight[(index << 1) + 1] = x2;
- } else {
- x1 = _lvlShapeLeftRight[index << 1];
- x2 = _lvlShapeLeftRight[(index << 1) + 1];
- }
-
- drawLevelModifyScreenDim(dim, x1, 0, x2, 15);
-}
-
-void LoLEngine::scaleLevelShapesDim(int index, int16 &y1, int16 &y2, int dim) {
- static const int8 dscY1[] = { 0x1E, 0x18, 0x10, 0x00 };
- static const int8 dscY2[] = { 0x3B, 0x47, 0x56, 0x78 };
-
- uint8 a = _dscDimMap[index];
-
- if (dim == -1 && a != 3)
- a++;
-
- y1 = dscY1[a];
- y2 = dscY2[a];
-
- if (dim == -1)
- return;
-
- const ScreenDim *cDim = _screen->getScreenDim(dim);
-
- _screen->modifyScreenDim(dim, cDim->sx, y1, cDim->w, y2 - y1);
-}
-
-void LoLEngine::drawLevelModifyScreenDim(int dim, int16 x1, int16 y1, int16 x2, int16 y2) {
- _screen->modifyScreenDim(dim, x1, y1 << 3, x2 - x1, (y2 - y1) << 3);
-}
-
void LoLEngine::drawDecorations(int index) {
for (int i = 1; i >= 0; i--) {
int s = index * 2 + i;
@@ -2066,7 +1456,7 @@ void LoLEngine::drawDecorations(int index) {
if (!scaleW || !scaleH)
continue;
- uint8 d = (_currentDirection + _dscUnk1[s]) & 3;
+ uint8 d = (_currentDirection + _dscWalls[s]) & 3;
int8 l = _wllShapeMap[_visibleBlocks[index]->walls[d]];
uint8 *shapeData = 0;
@@ -2076,21 +1466,21 @@ void LoLEngine::drawDecorations(int index) {
int flags = 0;
while (l > 0) {
- if ((_levelShapeProperties[l].flags & 8) && index != 3 && index != 9 && index != 13) {
- l = _levelShapeProperties[l].next;
+ if ((_levelDecorationProperties[l].flags & 8) && index != 3 && index != 9 && index != 13) {
+ l = _levelDecorationProperties[l].next;
continue;
}
- if (_dscOvlMap[shpIx] == 1 && ((_levelShapeProperties[l].flags & 2) || ((_levelShapeProperties[l].flags & 4) && _wllProcessFlag)))
+ if (_dscOvlMap[shpIx] == 1 && ((_levelDecorationProperties[l].flags & 2) || ((_levelDecorationProperties[l].flags & 4) && _wllProcessFlag)))
ix = -ix;
int xOffs = 0;
int yOffs = 0;
uint8 *ovl = 0;
- if (_levelShapeProperties[l].scaleFlag[shpIx] & 1) {
- xOffs = _levelShapeProperties[l].shapeX[shpIx];
- yOffs = _levelShapeProperties[l].shapeY[shpIx];
+ if (_levelDecorationProperties[l].scaleFlag[shpIx] & 1) {
+ xOffs = _levelDecorationProperties[l].shapeX[shpIx];
+ yOffs = _levelDecorationProperties[l].shapeY[shpIx];
shpIx = _dscOvlMap[shpIx];
int ov = ovlIndex;
if (_flags.use16ColorMode) {
@@ -2101,7 +1491,7 @@ void LoLEngine::drawDecorations(int index) {
ov = 0;
}
ovl = _screen->getLevelOverlay(ov);
- } else if (_levelShapeProperties[l].shapeIndex[shpIx] != 0xffff) {
+ } else if (_levelDecorationProperties[l].shapeIndex[shpIx] != 0xffff) {
scaleW = scaleH = 0x100;
int ov = 7;
if (_flags.use16ColorMode) {
@@ -2114,34 +1504,34 @@ void LoLEngine::drawDecorations(int index) {
ovl = _screen->getLevelOverlay(ov);
}
- if (_levelShapeProperties[l].shapeIndex[shpIx] != 0xffff) {
- shapeData = _levelShapes[_levelShapeProperties[l].shapeIndex[shpIx]];
+ if (_levelDecorationProperties[l].shapeIndex[shpIx] != 0xffff) {
+ shapeData = _levelDecorationShapes[_levelDecorationProperties[l].shapeIndex[shpIx]];
if (shapeData) {
if (ix < 0) {
- x = _dscShapeX[s] + xOffs + ((_levelShapeProperties[l].shapeX[shpIx] * scaleW) >> 8);
+ x = _dscShapeX[s] + xOffs + ((_levelDecorationProperties[l].shapeX[shpIx] * scaleW) >> 8);
if (ix == _dscShapeIndex[s]) {
- x = _dscShapeX[s] - ((_levelShapeProperties[l].shapeX[shpIx] * scaleW) >> 8) -
- _screen->getShapeScaledWidth(shapeData, scaleW) - xOffs;
+ x = _dscShapeX[s] - ((_levelDecorationProperties[l].shapeX[shpIx] * scaleW) >> 8) -
+ _screen->getShapeScaledWidth(shapeData, scaleW) - xOffs;
}
flags = 0x105;
} else {
- x = _dscShapeX[s] + xOffs + ((_levelShapeProperties[l].shapeX[shpIx] * scaleW) >> 8);
+ x = _dscShapeX[s] + xOffs + ((_levelDecorationProperties[l].shapeX[shpIx] * scaleW) >> 8);
flags = 0x104;
}
- y = _dscShapeY[s] + yOffs + ((_levelShapeProperties[l].shapeY[shpIx] * scaleH) >> 8);
- _screen->drawShape(_sceneDrawPage1, shapeData, x + 112, y, 13, flags, ovl, 1, scaleW, scaleH);
+ y = _dscShapeY[s] + yOffs + ((_levelDecorationProperties[l].shapeY[shpIx] * scaleH) >> 8);
+ _screen->drawShape(_sceneDrawPage1, shapeData, x + 112, y, _sceneShpDim, flags, ovl, 1, scaleW, scaleH);
- if ((_levelShapeProperties[l].flags & 1) && shpIx < 4) {
+ if ((_levelDecorationProperties[l].flags & 1) && shpIx < 4) {
//draw shadow
x += (_screen->getShapeScaledWidth(shapeData, scaleW));
flags ^= 1;
- _screen->drawShape(_sceneDrawPage1, shapeData, x + 112, y, 13, flags, ovl, 1, scaleW, scaleH);
+ _screen->drawShape(_sceneDrawPage1, shapeData, x + 112, y, _sceneShpDim, flags, ovl, 1, scaleW, scaleH);
}
}
}
- l = _levelShapeProperties[l].next;
+ l = _levelDecorationProperties[l].next;
shpIx = (_dscShapeIndex[s] < 0) ? -_dscShapeIndex[s] : _dscShapeIndex[s];
}
}
diff --git a/engines/kyra/scene_mr.cpp b/engines/kyra/scene_mr.cpp
index 74d2e89e6e..d6df523f82 100644
--- a/engines/kyra/scene_mr.cpp
+++ b/engines/kyra/scene_mr.cpp
@@ -83,7 +83,7 @@ void KyraEngine_MR::enterNewScene(uint16 sceneId, int facing, int unk1, int unk2
}
_specialExitCount = 0;
- Common::set_to(_specialExitTable, ARRAYEND(_specialExitTable), 0xFFFF);
+ Common::fill(_specialExitTable, ARRAYEND(_specialExitTable), 0xFFFF);
_mainCharacter.sceneId = sceneId;
_sceneList[sceneId].flags &= ~1;
@@ -388,7 +388,7 @@ void KyraEngine_MR::initSceneScript(int unk1) {
strcat(filename, ".CPS");
_screen->loadBitmap(filename, 3, 3, 0);
- Common::set_to(_specialSceneScriptState, ARRAYEND(_specialSceneScriptState), false);
+ Common::fill(_specialSceneScriptState, ARRAYEND(_specialSceneScriptState), false);
_sceneEnterX1 = 160;
_sceneEnterY1 = 0;
_sceneEnterX2 = 296;
diff --git a/engines/kyra/scene_rpg.cpp b/engines/kyra/scene_rpg.cpp
new file mode 100644
index 0000000000..3a694e05fe
--- /dev/null
+++ b/engines/kyra/scene_rpg.cpp
@@ -0,0 +1,637 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#if defined(ENABLE_EOB) || defined(ENABLE_LOL)
+
+#include "kyra/kyra_rpg.h"
+#include "kyra/resource.h"
+#include "kyra/timer.h"
+#include "kyra/sound.h"
+
+#include "common/system.h"
+
+namespace Kyra {
+
+void KyraRpgEngine::setLevelShapesDim(int index, int16 &x1, int16 &x2, int dim) {
+ if (_lvlShapeLeftRight[index << 1] == -1) {
+ x1 = 0;
+ x2 = 22;
+
+ int16 y1 = 0;
+ int16 y2 = 120;
+
+ int m = index * 18;
+
+ for (int i = 0; i < 18; i++) {
+ uint8 d = _visibleBlocks[i]->walls[_sceneDrawVarDown];
+ uint8 a = _wllWallFlags[d];
+
+ if (a & 8) {
+ int t = _dscDim2[(m + i) << 1];
+
+ if (t > x1) {
+ x1 = t;
+ if (!(a & 0x10))
+ setDoorShapeDim(index, y1, y2, -1);
+ }
+
+ t = _dscDim2[((m + i) << 1) + 1];
+
+ if (t < x2) {
+ x2 = t;
+ if (!(a & 0x10))
+ setDoorShapeDim(index, y1, y2, -1);
+ }
+ } else {
+ int t = _dscDim1[m + i];
+
+ if (!_wllVmpMap[d] || t == -40)
+ continue;
+
+ if (t == -41) {
+ x1 = 22;
+ x2 = 0;
+ break;
+ }
+
+ if (t > 0 && x2 > t)
+ x2 = t;
+
+ if (t < 0 && x1 < -t)
+ x1 = -t;
+ }
+
+ if (x2 < x1)
+ break;
+ }
+
+ x1 += (_sceneXoffset >> 3);
+ x2 += (_sceneXoffset >> 3);
+
+
+ _lvlShapeTop[index] = y1;
+ _lvlShapeBottom[index] = y2;
+ _lvlShapeLeftRight[index << 1] = x1;
+ _lvlShapeLeftRight[(index << 1) + 1] = x2;
+ } else {
+ x1 = _lvlShapeLeftRight[index << 1];
+ x2 = _lvlShapeLeftRight[(index << 1) + 1];
+ }
+
+ drawLevelModifyScreenDim(dim, x1, 0, x2, 15);
+}
+
+void KyraRpgEngine::setDoorShapeDim(int index, int16 &y1, int16 &y2, int dim) {
+ uint8 a = _dscDimMap[index];
+
+ if (_flags.gameID != GI_EOB1 && dim == -1 && a != 3)
+ a++;
+
+ uint8 b = a;
+ if (_flags.gameID == GI_EOB1) {
+ a += _dscDoorFrameIndex1[_currentLevel - 1];
+ b += _dscDoorFrameIndex2[_currentLevel - 1];
+ }
+
+ y1 = _dscDoorFrameY1[a];
+ y2 = _dscDoorFrameY2[b];
+
+ if (dim == -1)
+ return;
+
+ const ScreenDim *cDim = screen()->getScreenDim(dim);
+
+ screen()->modifyScreenDim(dim, cDim->sx, y1, cDim->w, y2 - y1);
+}
+
+void KyraRpgEngine::drawLevelModifyScreenDim(int dim, int16 x1, int16 y1, int16 x2, int16 y2) {
+ screen()->modifyScreenDim(dim, x1, y1 << 3, x2 - x1, (y2 - y1) << 3);
+}
+
+void KyraRpgEngine::generateBlockDrawingBuffer() {
+ _sceneDrawVarDown = _dscBlockMap[_currentDirection];
+ _sceneDrawVarRight = _dscBlockMap[_currentDirection + 4];
+ _sceneDrawVarLeft = _dscBlockMap[_currentDirection + 8];
+
+ /*******************************************
+ * _visibleBlocks map *
+ * *
+ * | | | | | | *
+ * 00 | 01 | 02 | 03 | 04 | 05 | 06 *
+ * ____|_____|_____|_____|_____|_____|_____ *
+ * | | | | | | *
+ * | 07 | 08 | 09 | 10 | 11 | *
+ * |_____|_____|_____|_____|_____| *
+ * | | | | *
+ * | 12 | 13 | 14 | *
+ * |_____|_____|_____| *
+ * | | *
+ * 15 | 16 | 17 *
+ * | (P) | *
+ ********************************************/
+
+ memset(_blockDrawingBuffer, 0, 660 * sizeof(uint16));
+
+ _wllProcessFlag = ((_currentBlock >> 5) + (_currentBlock & 0x1f) + _currentDirection) & 1;
+
+ if (_wllProcessFlag) // floor and ceiling
+ generateVmpTileDataFlipped(0, 15, 1, -330, 22, 15);
+ else
+ generateVmpTileData(0, 15, 1, -330, 22, 15);
+
+ assignVisibleBlocks(_currentBlock, _currentDirection);
+
+ uint8 t = _visibleBlocks[0]->walls[_sceneDrawVarRight];
+ if (t)
+ generateVmpTileData(-2, 3, t, 102, 3, 5);
+
+ t = _visibleBlocks[6]->walls[_sceneDrawVarLeft];
+ if (t)
+ generateVmpTileDataFlipped(21, 3, t, 102, 3, 5);
+
+ t = _visibleBlocks[1]->walls[_sceneDrawVarRight];
+ uint8 t2 = _visibleBlocks[2]->walls[_sceneDrawVarDown];
+
+ if (hasWall(t) && !(_wllWallFlags[t2] & 8))
+ generateVmpTileData(2, 3, t, 102, 3, 5);
+ else if (t && (_wllWallFlags[t2] & 8))
+ generateVmpTileData(2, 3, t2, 102, 3, 5);
+
+ t = _visibleBlocks[5]->walls[_sceneDrawVarLeft];
+ t2 = _visibleBlocks[4]->walls[_sceneDrawVarDown];
+
+ if (hasWall(t) && !(_wllWallFlags[t2] & 8))
+ generateVmpTileDataFlipped(17, 3, t, 102, 3, 5);
+ else if (t && (_wllWallFlags[t2] & 8))
+ generateVmpTileDataFlipped(17, 3, t2, 102, 3, 5);
+
+ t = _visibleBlocks[2]->walls[_sceneDrawVarRight];
+ if (t)
+ generateVmpTileData(8, 3, t, 97, 1, 5);
+
+ t = _visibleBlocks[4]->walls[_sceneDrawVarLeft];
+ if (t)
+ generateVmpTileDataFlipped(13, 3, t, 97, 1, 5);
+
+ t = _visibleBlocks[1]->walls[_sceneDrawVarDown];
+ if (hasWall(t))
+ generateVmpTileData(-4, 3, t, 129, 6, 5);
+
+ t = _visibleBlocks[5]->walls[_sceneDrawVarDown];
+ if (hasWall(t))
+ generateVmpTileData(20, 3, t, 129, 6, 5);
+
+ t = _visibleBlocks[2]->walls[_sceneDrawVarDown];
+ if (hasWall(t))
+ generateVmpTileData(2, 3, t, 129, 6, 5);
+
+ t = _visibleBlocks[4]->walls[_sceneDrawVarDown];
+ if (hasWall(t))
+ generateVmpTileData(14, 3, t, 129, 6, 5);
+
+ t = _visibleBlocks[3]->walls[_sceneDrawVarDown];
+ if (t)
+ generateVmpTileData(8, 3, t, 129, 6, 5);
+
+ t = _visibleBlocks[7]->walls[_sceneDrawVarRight];
+ if (t)
+ generateVmpTileData(0, 3, t, 117, 2, 6);
+
+ t = _visibleBlocks[11]->walls[_sceneDrawVarLeft];
+ if (t)
+ generateVmpTileDataFlipped(20, 3, t, 117, 2, 6);
+
+ t = _visibleBlocks[8]->walls[_sceneDrawVarRight];
+ if (t)
+ generateVmpTileData(6, 2, t, 81, 2, 8);
+
+ t = _visibleBlocks[10]->walls[_sceneDrawVarLeft];
+ if (t)
+ generateVmpTileDataFlipped(14, 2, t, 81, 2, 8);
+
+ t = _visibleBlocks[8]->walls[_sceneDrawVarDown];
+ if (hasWall(t))
+ generateVmpTileData(-4, 2, t, 159, 10, 8);
+
+ t = _visibleBlocks[10]->walls[_sceneDrawVarDown];
+ if (hasWall(t))
+ generateVmpTileData(16, 2, t, 159, 10, 8);
+
+ t = _visibleBlocks[9]->walls[_sceneDrawVarDown];
+ if (t)
+ generateVmpTileData(6, 2, t, 159, 10, 8);
+
+ t = _visibleBlocks[12]->walls[_sceneDrawVarRight];
+ if (t)
+ generateVmpTileData(3, 1, t, 45, 3, 12);
+
+ t = _visibleBlocks[14]->walls[_sceneDrawVarLeft];
+ if (t)
+ generateVmpTileDataFlipped(16, 1, t, 45, 3, 12);
+
+ t = _visibleBlocks[12]->walls[_sceneDrawVarDown];
+ if (!(_wllWallFlags[t] & 8))
+ generateVmpTileData(-13, 1, t, 239, 16, 12);
+
+ t = _visibleBlocks[14]->walls[_sceneDrawVarDown];
+ if (!(_wllWallFlags[t] & 8))
+ generateVmpTileData(19, 1, t, 239, 16, 12);
+
+ t = _visibleBlocks[13]->walls[_sceneDrawVarDown];
+ if (t)
+ generateVmpTileData(3, 1, t, 239, 16, 12);
+
+ t = _visibleBlocks[15]->walls[_sceneDrawVarRight];
+ t2 = _visibleBlocks[17]->walls[_sceneDrawVarLeft];
+ if (t)
+ generateVmpTileData(0, 0, t, 0, 3, 15);
+ if (t2)
+ generateVmpTileDataFlipped(19, 0, t2, 0, 3, 15);
+}
+
+void KyraRpgEngine::generateVmpTileData(int16 startBlockX, uint8 startBlockY, uint8 vmpMapIndex, int16 vmpOffset, uint8 numBlocksX, uint8 numBlocksY) {
+ if (!_wllVmpMap[vmpMapIndex])
+ return;
+
+ uint16 *vmp = &_vmpPtr[(_wllVmpMap[vmpMapIndex] - 1) * 431 + vmpOffset + 330];
+
+ for (int i = 0; i < numBlocksY; i++) {
+ uint16 *bl = &_blockDrawingBuffer[(startBlockY + i) * 22 + startBlockX];
+ for (int ii = 0; ii < numBlocksX; ii++) {
+ if ((startBlockX + ii >= 0) && (startBlockX + ii < 22) && *vmp)
+ *bl = *vmp;
+ bl++;
+ vmp++;
+ }
+ }
+}
+
+void KyraRpgEngine::generateVmpTileDataFlipped(int16 startBlockX, uint8 startBlockY, uint8 vmpMapIndex, int16 vmpOffset, uint8 numBlocksX, uint8 numBlocksY) {
+ if (!_wllVmpMap[vmpMapIndex])
+ return;
+
+ uint16 *vmp = &_vmpPtr[(_wllVmpMap[vmpMapIndex] - 1) * 431 + vmpOffset + 330];
+
+ for (int i = 0; i < numBlocksY; i++) {
+ for (int ii = 0; ii < numBlocksX; ii++) {
+ if ((startBlockX + ii) < 0 || (startBlockX + ii) > 21)
+ continue;
+
+ uint16 v = vmp[i * numBlocksX + (numBlocksX - 1 - ii)];
+ if (!v)
+ continue;
+
+ if (v & 0x4000)
+ v -= 0x4000;
+ else
+ v |= 0x4000;
+
+ _blockDrawingBuffer[(startBlockY + i) * 22 + startBlockX + ii] = v;
+ }
+ }
+}
+
+bool KyraRpgEngine::hasWall(int index) {
+ if (!index || (_wllWallFlags[index] & 8))
+ return false;
+ return true;
+}
+
+void KyraRpgEngine::assignVisibleBlocks(int block, int direction) {
+ for (int i = 0; i < 18; i++) {
+ uint16 t = (block + _dscBlockIndex[direction * 18 + i]) & 0x3ff;
+ _visibleBlockIndex[i] = t;
+
+ _visibleBlocks[i] = &_levelBlockProperties[t];
+ _lvlShapeLeftRight[i] = _lvlShapeLeftRight[18 + i] = -1;
+ }
+}
+
+bool KyraRpgEngine::checkSceneUpdateNeed(int block) {
+ if (_sceneUpdateRequired)
+ return true;
+
+ for (int i = 0; i < 15; i++) {
+ if (_visibleBlockIndex[i] == block) {
+ _sceneUpdateRequired = true;
+ return true;
+ }
+ }
+
+ if (_currentBlock == block) {
+ _sceneUpdateRequired = true;
+ return true;
+ }
+
+ return false;
+}
+
+void KyraRpgEngine::drawVcnBlocks() {
+ uint8 *d = _sceneWindowBuffer;
+ uint16 *bdb = _blockDrawingBuffer;
+ uint16 pitch = 22 * _vcnBlockWidth * 2;
+ uint8 pxl[2];
+ pxl[0] = pxl[1] = 0;
+
+ for (int y = 0; y < 15; y++) {
+ for (int x = 0; x < 22; x++) {
+ bool horizontalFlip = false;
+ uint16 vcnOffset = *bdb++;
+ uint16 vcnExtraOffsetWll = 0;
+ int wllVcnOffset = 0;
+ int wllVcnRmdOffset = 0;
+
+ if (vcnOffset & 0x8000) {
+ // this renders a wall block over the transparent pixels of a floor/ceiling block
+ vcnExtraOffsetWll = vcnOffset - 0x8000;
+ vcnOffset = 0;
+ wllVcnRmdOffset = _wllVcnOffset;
+ }
+
+ if (vcnOffset & 0x4000) {
+ horizontalFlip = true;
+ vcnOffset &= 0x3fff;
+ }
+
+ uint8 *src = 0;
+ if (vcnOffset) {
+ src = &_vcnBlocks[vcnOffset * _vcnBlockWidth * _vcnBlockHeight];
+ wllVcnOffset = _wllVcnOffset;
+ } else {
+ // floor/ceiling blocks
+ vcnOffset = bdb[329];
+ if (vcnOffset & 0x4000) {
+ horizontalFlip = true;
+ vcnOffset &= 0x3fff;
+ }
+
+ src = (_vcfBlocks ? _vcfBlocks : _vcnBlocks) + (vcnOffset * _vcnBlockWidth * _vcnBlockHeight);
+ }
+
+ uint8 shift = _vcnShift ? _vcnShift[vcnOffset] : _blockBrightness;
+
+ if (horizontalFlip) {
+ for (int blockY = 0; blockY < _vcnBlockHeight; blockY++) {
+ src += (_vcnBlockWidth - 1);
+ for (int blockX = 0; blockX < _vcnBlockWidth; blockX++) {
+ uint8 bl = *src--;
+ d[_vcnFlip0] = _vcnColTable[((bl & 0x0f) + wllVcnOffset) | shift];
+ d[_vcnFlip1] = _vcnColTable[((bl >> 4) + wllVcnOffset) | shift];
+ d += 2;
+ }
+ src += (_vcnBlockWidth + 1);
+ d += (pitch - 2 * _vcnBlockWidth);
+ }
+ } else {
+ for (int blockY = 0; blockY < _vcnBlockHeight; blockY++) {
+ for (int blockX = 0; blockX < _vcnBlockWidth; blockX++) {
+ uint8 bl = *src++;
+ *d++ = _vcnColTable[((bl >> 4) + wllVcnOffset) | shift];
+ *d++ = _vcnColTable[((bl & 0x0f) + wllVcnOffset) | shift];
+ }
+ d += (pitch - 2 * _vcnBlockWidth);
+ }
+ }
+ d -= (pitch * _vcnBlockHeight - 2 * _vcnBlockWidth);
+
+ if (vcnExtraOffsetWll) {
+ d -= (2 * _vcnBlockWidth);
+ horizontalFlip = false;
+
+ if (vcnExtraOffsetWll & 0x4000) {
+ vcnExtraOffsetWll &= 0x3fff;
+ horizontalFlip = true;
+ }
+
+ shift = _vcnShift ? _vcnShift[vcnExtraOffsetWll] : _blockBrightness;
+ src = &_vcnBlocks[vcnExtraOffsetWll * _vcnBlockWidth * _vcnBlockHeight];
+ uint8 *maskTable = _vcnTransitionMask ? &_vcnTransitionMask[vcnExtraOffsetWll * _vcnBlockWidth * _vcnBlockHeight] : 0;
+
+ if (horizontalFlip) {
+ for (int blockY = 0; blockY < _vcnBlockHeight; blockY++) {
+ src += (_vcnBlockWidth - 1);
+ maskTable += (_vcnBlockWidth - 1);
+ for (int blockX = 0; blockX < _vcnBlockWidth; blockX++) {
+ uint8 bl = *src--;
+ uint8 mask = _vcnTransitionMask ? *maskTable-- : 0;
+ pxl[_vcnFlip0] = _vcnColTable[((bl & 0x0f) + wllVcnRmdOffset) | shift];
+ pxl[_vcnFlip1] = _vcnColTable[((bl >> 4) + wllVcnRmdOffset) | shift];
+
+ if (_vcnTransitionMask)
+ *d = (*d & (mask & 0x0f)) | pxl[0];
+ else if (pxl[0])
+ *d = pxl[0];
+ d++;
+
+ if (_vcnTransitionMask)
+ *d = (*d & (mask >> 4)) | pxl[1];
+ else if (pxl[1])
+ *d = pxl[1];
+ d++;
+ }
+ src += (_vcnBlockWidth + 1);
+ maskTable += (_vcnBlockWidth + 1);
+ d += (pitch - 2 * _vcnBlockWidth);
+ }
+ } else {
+ for (int blockY = 0; blockY < _vcnBlockHeight; blockY++) {
+ for (int blockX = 0; blockX < _vcnBlockWidth; blockX++) {
+ uint8 bl = *src++;
+ uint8 mask = _vcnTransitionMask ? *maskTable++ : 0;
+ uint8 h = _vcnColTable[((bl >> 4) + wllVcnRmdOffset) | shift];
+ uint8 l = _vcnColTable[((bl & 0x0f) + wllVcnRmdOffset) | shift];
+
+ if (_vcnTransitionMask)
+ *d = (*d & (mask >> 4)) | h;
+ else if (h)
+ *d = h;
+ d++;
+
+ if (_vcnTransitionMask)
+ *d = (*d & (mask & 0x0f)) | l;
+ else if (l)
+ *d = l;
+ d++;
+ }
+ d += (pitch - 2 * _vcnBlockWidth);
+ }
+ }
+ d -= (pitch * _vcnBlockHeight - 2 * _vcnBlockWidth);
+ }
+ }
+ d += (pitch * (_vcnBlockHeight - 1));
+ }
+
+ screen()->copyBlockToPage(_sceneDrawPage1, _sceneXoffset, 0, 176, 120, _sceneWindowBuffer);
+}
+
+uint16 KyraRpgEngine::calcNewBlockPosition(uint16 curBlock, uint16 direction) {
+ static const int16 blockPosTable[] = { -32, 1, 32, -1 };
+ return (curBlock + blockPosTable[direction]) & 0x3ff;
+}
+
+int KyraRpgEngine::clickedWallShape(uint16 block, uint16 direction) {
+ uint8 v = _wllShapeMap[_levelBlockProperties[block].walls[direction]];
+ if (!clickedShape(v))
+ return 0;
+
+ snd_stopSpeech(true);
+ runLevelScript(block, 0x40);
+
+ return 1;
+}
+
+int KyraRpgEngine::clickedLeverOn(uint16 block, uint16 direction) {
+ uint8 v = _wllShapeMap[_levelBlockProperties[block].walls[direction]];
+ if (!clickedShape(v))
+ return 0;
+
+ _levelBlockProperties[block].walls[direction]++;
+ _sceneUpdateRequired = true;
+
+ if (_flags.gameID == GI_LOL)
+ snd_playSoundEffect(30, -1);
+
+ runLevelScript(block, _clickedSpecialFlag);
+
+ return 1;
+}
+
+int KyraRpgEngine::clickedLeverOff(uint16 block, uint16 direction) {
+ uint8 v = _wllShapeMap[_levelBlockProperties[block].walls[direction]];
+ if (!clickedShape(v))
+ return 0;
+
+ _levelBlockProperties[block].walls[direction]--;
+ _sceneUpdateRequired = true;
+
+ if (_flags.gameID == GI_LOL)
+ snd_playSoundEffect(29, -1);
+
+ runLevelScript(block, _clickedSpecialFlag);
+ return 1;
+}
+
+int KyraRpgEngine::clickedWallOnlyScript(uint16 block) {
+ runLevelScript(block, _clickedSpecialFlag);
+ return 1;
+}
+
+void KyraRpgEngine::processDoorSwitch(uint16 block, int openClose) {
+ if (block == _currentBlock)
+ return;
+
+ if ((_flags.gameID == GI_LOL && (_levelBlockProperties[block].assignedObjects & 0x8000)) || (_flags.gameID != GI_LOL && (_levelBlockProperties[block].flags & 7)))
+ return;
+
+ if (openClose == 0) {
+ for (int i = 0; i < 3; i++) {
+ if (_openDoorState[i].block != block)
+ continue;
+ openClose = -_openDoorState[i].state;
+ break;
+ }
+ }
+
+ if (openClose == 0) {
+ openClose = (_wllWallFlags[_levelBlockProperties[block].walls[_wllWallFlags[_levelBlockProperties[block].walls[0]] & 8 ? 0 : 1]] & 1) ? 1 : -1;
+ if (_flags.gameID != GI_LOL)
+ openClose *= -1;
+ }
+
+ openCloseDoor(block, openClose);
+}
+
+void KyraRpgEngine::openCloseDoor(int block, int openClose) {
+ int s1 = -1;
+ int s2 = -1;
+
+ int c = (_wllWallFlags[_levelBlockProperties[block].walls[0]] & 8) ? 0 : 1;
+ int v = _levelBlockProperties[block].walls[c];
+ int flg = (openClose == 1) ? 0x10 : (openClose == -1 ? 0x20 : 0);
+
+ if (_wllWallFlags[v] & flg)
+ return;
+
+ for (int i = 0; i < 3; i++) {
+ if (_openDoorState[i].block == block) {
+ s1 = i;
+ break;
+ } else if (_openDoorState[i].block == 0 && s2 == -1) {
+ s2 = i;
+ }
+ }
+
+ if (s1 != -1 || s2 != -1) {
+ if (s1 == -1)
+ s1 = s2;
+
+ _openDoorState[s1].block = block;
+ _openDoorState[s1].state = openClose;
+ _openDoorState[s1].wall = c;
+
+ flg = (-openClose == 1) ? 0x10 : (-openClose == -1 ? 0x20 : 0);
+
+ if (_wllWallFlags[v] & flg) {
+ _levelBlockProperties[block].walls[c] += openClose;
+ _levelBlockProperties[block].walls[c ^ 2] += openClose;
+
+ int snd = (openClose == -1) ? 4 : 3;
+ if (_flags.gameID == GI_LOL) {
+ snd_processEnvironmentalSoundEffect(snd + 28, _currentBlock);
+ if (!checkSceneUpdateNeed(block))
+ updateEnvironmentalSfx(0);
+ } else {
+ updateEnvironmentalSfx(snd);
+ }
+ }
+
+ enableTimer(_flags.gameID == GI_LOL ? 0 : 4);
+
+ } else {
+ while (!(flg & _wllWallFlags[v]))
+ v += openClose;
+
+ _levelBlockProperties[block].walls[c] = _levelBlockProperties[block].walls[c ^ 2] = v;
+ checkSceneUpdateNeed(block);
+ }
+}
+
+void KyraRpgEngine::completeDoorOperations() {
+ for (int i = 0; i < 3; i++) {
+ if (!_openDoorState[i].block)
+ continue;
+
+ uint16 b = _openDoorState[i].block;
+
+ do {
+ _levelBlockProperties[b].walls[_openDoorState[i].wall] += _openDoorState[i].state;
+ _levelBlockProperties[b].walls[_openDoorState[i].wall ^ 2] += _openDoorState[i].state;
+ } while (!(_wllWallFlags[_levelBlockProperties[b].walls[_openDoorState[i].wall]] & 0x30));
+
+ _openDoorState[i].block = 0;
+ }
+}
+
+} // End of namespace Kyra
+
+#endif // ENABLE_EOB || ENABLE_LOL
diff --git a/engines/kyra/scene_v1.cpp b/engines/kyra/scene_v1.cpp
index 5319d4e657..36798970e3 100644
--- a/engines/kyra/scene_v1.cpp
+++ b/engines/kyra/scene_v1.cpp
@@ -115,7 +115,7 @@ int KyraEngine_v1::findWay(int x, int y, int toX, int toY, int *moveTable, int m
delete[] pathTable2;
return 0x7D00;
}
- memcpy(&moveTable[lastUsedEntry], pathTable1, temp*sizeof(int));
+ memcpy(&moveTable[lastUsedEntry], pathTable1, temp * sizeof(int));
lastUsedEntry += temp;
} else {
if (lastUsedEntry + tempValue > moveTableSize) {
@@ -123,7 +123,7 @@ int KyraEngine_v1::findWay(int x, int y, int toX, int toY, int *moveTable, int m
delete[] pathTable2;
return 0x7D00;
}
- memcpy(&moveTable[lastUsedEntry], pathTable2, tempValue*sizeof(int));
+ memcpy(&moveTable[lastUsedEntry], pathTable2, tempValue * sizeof(int));
lastUsedEntry += tempValue;
}
x = curX;
@@ -161,16 +161,16 @@ int KyraEngine_v1::findSubPath(int x, int y, int toX, int toY, int *moveTable, i
while (position != end) {
int newFacing2 = newFacing;
while (true) {
- changePosTowardsFacing(xpos1, ypos1, facingTable1[start*8 + newFacing2]);
+ changePosTowardsFacing(xpos1, ypos1, facingTable1[start * 8 + newFacing2]);
if (!lineIsPassable(xpos1, ypos1)) {
- if (facingTable1[start*8 + newFacing2] == newFacing)
+ if (facingTable1[start * 8 + newFacing2] == newFacing)
return 0x7D00;
- newFacing2 = facingTable1[start*8 + newFacing2];
+ newFacing2 = facingTable1[start * 8 + newFacing2];
xpos1 = x;
ypos1 = y;
continue;
}
- newFacing = facingTable1[start*8 + newFacing2];
+ newFacing = facingTable1[start * 8 + newFacing2];
break;
}
// debug drawing
@@ -200,7 +200,7 @@ int KyraEngine_v1::findSubPath(int x, int y, int toX, int toY, int *moveTable, i
if (xpos1 == xpos2 && ypos1 == ypos2)
break;
- newFacing = facingTable3[start*8 + newFacing];
+ newFacing = facingTable3[start * 8 + newFacing];
}
return 0x7D00;
@@ -277,7 +277,7 @@ void KyraEngine_v1::changePosTowardsFacing(int &x, int &y, int facing) {
}
int KyraEngine_v1::getMoveTableSize(int *moveTable) {
- int retValue = 0;
+ int tableSize = 0;
if (moveTable[0] == 8)
return 0;
@@ -298,11 +298,11 @@ int KyraEngine_v1::getMoveTableSize(int *moveTable) {
int *oldPosition = moveTable;
int *tempPosition = moveTable;
int *curPosition = moveTable + 1;
- retValue = 1;
+ tableSize = 1;
while (*curPosition != 8) {
if (*oldPosition == facingTable[*curPosition]) {
- retValue -= 2;
+ tableSize -= 2;
*oldPosition = 9;
*curPosition = 9;
@@ -313,7 +313,7 @@ int KyraEngine_v1::getMoveTableSize(int *moveTable) {
}
if (tempPosition == moveTable && *tempPosition == 9) {
- while (*tempPosition != 8 && *tempPosition == 9)
+ while (*tempPosition == 9)
++tempPosition;
if (*tempPosition == 8)
@@ -321,53 +321,40 @@ int KyraEngine_v1::getMoveTableSize(int *moveTable) {
}
oldPosition = tempPosition;
- curPosition = oldPosition+1;
+ curPosition = oldPosition + 1;
- while (*curPosition != 8 && *curPosition == 9)
+ while (*curPosition == 9)
++curPosition;
-
- continue;
- }
-
- if (unkTable[*curPosition+((*oldPosition)*8)] != -1) {
- --retValue;
- *oldPosition = unkTable[*curPosition+((*oldPosition)*8)];
+ } else if (unkTable[*curPosition + *oldPosition * 8] != -1) {
+ --tableSize;
+ *oldPosition = unkTable[*curPosition + *oldPosition * 8];
*curPosition = 9;
if (tempPosition != oldPosition) {
curPosition = oldPosition;
oldPosition = tempPosition;
- while (true) {
- if (tempPosition == moveTable)
- break;
-
+ while (tempPosition != moveTable) {
--tempPosition;
if (*tempPosition != 9)
break;
-
}
} else {
- while (true) {
+ do {
++curPosition;
- if (*curPosition != 9)
- break;
- }
+ } while (*curPosition == 9);
}
- continue;
- }
-
- tempPosition = oldPosition;
- oldPosition = curPosition;
- ++retValue;
+ } else {
+ tempPosition = oldPosition;
+ oldPosition = curPosition;
+ ++tableSize;
- while (true) {
- ++curPosition;
- if (*curPosition != 9)
- break;
+ do {
+ ++curPosition;
+ } while (*curPosition == 9);
}
}
- return retValue;
+ return tableSize;
}
} // End of namespace Kyra
diff --git a/engines/kyra/scene_v2.cpp b/engines/kyra/scene_v2.cpp
index 061ce4c21a..9b6897f2ab 100644
--- a/engines/kyra/scene_v2.cpp
+++ b/engines/kyra/scene_v2.cpp
@@ -42,7 +42,7 @@ void KyraEngine_v2::updateSpecialSceneScripts() {
while (_system->getMillis() <= nextTime) {
if (_sceneSpecialScriptsTimer[_lastProcessedSceneScript] <= _system->getMillis() &&
- !_specialSceneScriptState[_lastProcessedSceneScript]) {
+ !_specialSceneScriptState[_lastProcessedSceneScript]) {
_specialSceneScriptRunFlag = true;
while (_specialSceneScriptRunFlag && _sceneSpecialScriptsTimer[_lastProcessedSceneScript] <= _system->getMillis()) {
@@ -52,7 +52,7 @@ void KyraEngine_v2::updateSpecialSceneScripts() {
}
if (!_emc->isValid(&_sceneSpecialScripts[_lastProcessedSceneScript])) {
- _emc->start(&_sceneSpecialScripts[_lastProcessedSceneScript], _desc.firstAnimSceneScript+_lastProcessedSceneScript);
+ _emc->start(&_sceneSpecialScripts[_lastProcessedSceneScript], _desc.firstAnimSceneScript + _lastProcessedSceneScript);
_specialSceneScriptRunFlag = false;
}
@@ -155,14 +155,14 @@ int KyraEngine_v2::pathfinderInitPositionTable(int *moveTable) {
}
lastEntry = pathfinderAddToPositionTable(lastEntry, newX, newY);
- _pathfinderPositionTable[lastEntry*2+0] = -1;
- _pathfinderPositionTable[lastEntry*2+1] = -1;
+ _pathfinderPositionTable[lastEntry * 2 + 0] = -1;
+ _pathfinderPositionTable[lastEntry * 2 + 1] = -1;
return lastEntry;
}
int KyraEngine_v2::pathfinderAddToPositionTable(int index, int v1, int v2) {
- _pathfinderPositionTable[index<<1] = v1;
- _pathfinderPositionTable[(index<<1)+1] = v2;
+ _pathfinderPositionTable[index << 1] = v1;
+ _pathfinderPositionTable[(index << 1) + 1] = v2;
++index;
if (index >= 199)
--index;
@@ -173,23 +173,23 @@ int KyraEngine_v2::pathfinderInitPositionIndexTable(int tableLen, int x, int y)
int x1 = 0, y1 = 0;
int x2 = 0, y2 = 0;
int lastEntry = 0;
- int index2 = tableLen-1, index1 = 0;
+ int index2 = tableLen - 1, index1 = 0;
while (index2 > index1) {
- x1 = _pathfinderPositionTable[index1*2+0] + x;
- y1 = _pathfinderPositionTable[index1*2+1] + y;
- x2 = _pathfinderPositionTable[index2*2+0] + x;
- y2 = _pathfinderPositionTable[index2*2+1] + y;
+ x1 = _pathfinderPositionTable[index1 * 2 + 0] + x;
+ y1 = _pathfinderPositionTable[index1 * 2 + 1] + y;
+ x2 = _pathfinderPositionTable[index2 * 2 + 0] + x;
+ y2 = _pathfinderPositionTable[index2 * 2 + 1] + y;
if (directLinePassable(x1, y1, x2, y2)) {
lastEntry = pathfinderAddToPositionIndexTable(lastEntry, index2);
- if (tableLen-1 == index2)
+ if (tableLen - 1 == index2)
break;
index1 = index2;
- index2 = tableLen-1;
- } else if (index1+1 == index2) {
+ index2 = tableLen - 1;
+ } else if (index1 + 1 == index2) {
lastEntry = pathfinderAddToPositionIndexTable(lastEntry, index2);
index1 = index2;
- index2 = tableLen-1;
+ index2 = tableLen - 1;
} else {
--index2;
}
@@ -212,14 +212,14 @@ void KyraEngine_v2::pathfinderFinializePath(int *moveTable, int tableLen, int x,
int sizeLeft = moveTableSize;
for (int i = 0; i < tableLen; ++i) {
index2 = _pathfinderPositionIndexTable[i];
- x1 = _pathfinderPositionTable[index1*2+0] + x;
- y1 = _pathfinderPositionTable[index1*2+1] + y;
- x2 = _pathfinderPositionTable[index2*2+0] + x;
- y2 = _pathfinderPositionTable[index2*2+1] + y;
+ x1 = _pathfinderPositionTable[index1 * 2 + 0] + x;
+ y1 = _pathfinderPositionTable[index1 * 2 + 1] + y;
+ x2 = _pathfinderPositionTable[index2 * 2 + 0] + x;
+ y2 = _pathfinderPositionTable[index2 * 2 + 1] + y;
int wayLen = findWay(x1, y1, x2, y2, moveTable, sizeLeft);
moveTable += wayLen;
- sizeLeft -= wayLen; // unlike the original we want to be sure that the size left is correct
+ sizeLeft -= wayLen; // unlike the original we want to be sure that the size left is correct
index1 = index2;
}
}
diff --git a/engines/kyra/screen.cpp b/engines/kyra/screen.cpp
index 4eae89e0d4..d3b4d6f943 100644
--- a/engines/kyra/screen.cpp
+++ b/engines/kyra/screen.cpp
@@ -27,6 +27,7 @@
#include "common/endian.h"
#include "common/memstream.h"
#include "common/system.h"
+#include "common/config-manager.h"
#include "engines/util.h"
@@ -36,9 +37,9 @@
namespace Kyra {
-Screen::Screen(KyraEngine_v1 *vm, OSystem *system)
- : _system(system), _vm(vm), _sjisInvisibleColor(0),
- _cursorColorKey((vm->game() == GI_KYRA1) ? 0xFF : 0x00) {
+Screen::Screen(KyraEngine_v1 *vm, OSystem *system, const ScreenDim *dimTable, const int dimTableSize)
+ : _system(system), _vm(vm), _sjisInvisibleColor(0), _dimTable(dimTable), _dimTableCount(dimTableSize),
+ _cursorColorKey((vm->game() == GI_KYRA1 || vm->game() == GI_EOB1 || vm->game() == GI_EOB2) ? 0xFF : 0) {
_debugEnabled = false;
_maskMinY = _maskMaxY = -1;
@@ -49,8 +50,18 @@ Screen::Screen(KyraEngine_v1 *vm, OSystem *system)
memset(_fonts, 0, sizeof(_fonts));
+ memset(_pagePtrs, 0, sizeof(_pagePtrs));
+ // Set scale factor to 1 (no scaling) for all pages
+ memset(_pageScaleFactor, 1, sizeof(_pageScaleFactor));
+ // In VGA mode the odd and even page pointers point to the same buffers.
+ for (int i = 0; i < SCREEN_PAGE_NUM; i++)
+ _pageMapping[i] = i & ~1;
+
+ _renderMode = Common::kRenderDefault;
+
_currentFont = FID_8_FNT;
_paletteChanged = true;
+ _curDim = 0;
}
Screen::~Screen() {
@@ -69,6 +80,10 @@ Screen::~Screen() {
for (uint i = 0; i < _palettes.size(); ++i)
delete _palettes[i];
+
+ for (int i = 0; i < _dimTableCount; ++i)
+ delete _customDimTable[i];
+ delete[] _customDimTable;
}
bool Screen::init() {
@@ -79,10 +94,21 @@ bool Screen::init() {
_useSJIS = false;
_use16ColorMode = _vm->gameFlags().use16ColorMode;
_isAmiga = (_vm->gameFlags().platform == Common::kPlatformAmiga);
+
+ if (ConfMan.hasKey("render_mode"))
+ _renderMode = Common::parseRenderMode(ConfMan.get("render_mode"));
+
+ // CGA and EGA modes use additional pages to do the CGA/EGA specific graphics conversions.
+ if (_renderMode == Common::kRenderCGA || _renderMode == Common::kRenderEGA) {
+ for (int i = 0; i < 8; i++)
+ _pageMapping[i] = i;
+ }
+
memset(_fonts, 0, sizeof(_fonts));
- if (_vm->gameFlags().useHiResOverlay) {
- _useOverlays = true;
+ _useOverlays = (_vm->gameFlags().useHiRes && _renderMode != Common::kRenderEGA);
+
+ if (_useOverlays) {
_useSJIS = (_vm->gameFlags().lang == Common::JA_JPN);
_sjisInvisibleColor = (_vm->game() == GI_KYRA1) ? 0x80 : 0xF6;
@@ -105,15 +131,36 @@ bool Screen::init() {
}
_curPage = 0;
- uint8 *pagePtr = new uint8[SCREEN_PAGE_SIZE * 8];
- for (int pageNum = 0; pageNum < SCREEN_PAGE_NUM; pageNum += 2)
- _pagePtrs[pageNum] = _pagePtrs[pageNum + 1] = pagePtr + (pageNum >> 1) * SCREEN_PAGE_SIZE;
- memset(pagePtr, 0, SCREEN_PAGE_SIZE * 8);
+
+ Common::Array<uint8> realPages;
+ for (int i = 0; i < SCREEN_PAGE_NUM; i++) {
+ if (Common::find(realPages.begin(), realPages.end(), _pageMapping[i]) == realPages.end())
+ realPages.push_back(_pageMapping[i]);
+ }
+
+ int numPages = realPages.size();
+ uint32 bufferSize = 0;
+ for (int i = 0; i < numPages; i++)
+ bufferSize += (SCREEN_PAGE_SIZE * _pageScaleFactor[realPages[i]] * _pageScaleFactor[realPages[i]]);
+
+ uint8 *pagePtr = new uint8[bufferSize];
+ memset(pagePtr, 0, bufferSize);
+
+ memset(_pagePtrs, 0, sizeof(_pagePtrs));
+ for (int i = 0; i < SCREEN_PAGE_NUM; i++) {
+ if (_pagePtrs[_pageMapping[i]]) {
+ _pagePtrs[i] = _pagePtrs[_pageMapping[i]];
+ } else {
+ _pagePtrs[i] = pagePtr;
+ pagePtr += (SCREEN_PAGE_SIZE * _pageScaleFactor[i] * _pageScaleFactor[i]);
+ }
+ }
memset(_shapePages, 0, sizeof(_shapePages));
const int paletteCount = _isAmiga ? 13 : 4;
- const int numColors = _use16ColorMode ? 16 : (_isAmiga ? 32 : 256);
+ // We allow 256 color palettes in EGA mode, since original EOB II code does the same and requires it
+ const int numColors = _use16ColorMode ? 16 : (_isAmiga ? 32 : (_renderMode == Common::kRenderCGA ? 4 : 256));
_interfacePaletteEnabled = false;
@@ -126,6 +173,15 @@ bool Screen::init() {
assert(_palettes[i]);
}
+ // Setup CGA colors (if CGA mode is selected)
+ if (_renderMode == Common::kRenderCGA) {
+ Palette pal(5);
+ pal.setCGAPalette(1, Palette::kIntensityHigh);
+ // create additional black color 4 for use with the mouse cursor manager
+ pal.fill(4, 1, 0);
+ Screen::setScreenPalette(pal);
+ }
+
_internFadePalette = new Palette(numColors);
assert(_internFadePalette);
@@ -145,6 +201,10 @@ bool Screen::init() {
_system->getPaletteManager()->setPalette(palette, 16, 8);
}
+ _customDimTable = new ScreenDim *[_dimTableCount];
+ memset(_customDimTable, 0, sizeof(ScreenDim *) * _dimTableCount);
+
+ _curDimIndex = -1;
_curDim = 0;
_charWidth = 0;
_charOffset = 0;
@@ -182,7 +242,7 @@ void Screen::setResolution() {
int width = 320, height = 200;
bool defaultTo1xScaler = false;
- if (_vm->gameFlags().useHiResOverlay) {
+ if (_vm->gameFlags().useHiRes) {
defaultTo1xScaler = true;
height = 400;
@@ -217,7 +277,7 @@ void Screen::updateScreen() {
needRealUpdate = true;
if (!_useOverlays)
- _system->copyRectToScreen(getPagePtr(2), SCREEN_W, 320, 0, SCREEN_W, SCREEN_H);
+ _system->copyRectToScreen(getPagePtr(2), SCREEN_W, 320, 0, SCREEN_W * _pageScaleFactor[2], SCREEN_H * _pageScaleFactor[2]);
else
_system->copyRectToScreen(getPagePtr(2), SCREEN_W, 640, 0, SCREEN_W, SCREEN_H);
}
@@ -228,12 +288,12 @@ void Screen::updateScreen() {
void Screen::updateDirtyRects() {
if (_forceFullUpdate) {
- _system->copyRectToScreen(getCPagePtr(0), SCREEN_W, 0, 0, SCREEN_W, SCREEN_H);
+ _system->copyRectToScreen(getCPagePtr(0), SCREEN_W * _pageScaleFactor[0], 0, 0, SCREEN_W * _pageScaleFactor[0], SCREEN_H * _pageScaleFactor[0]);
} else {
const byte *page0 = getCPagePtr(0);
Common::List<Common::Rect>::iterator it;
for (it = _dirtyRects.begin(); it != _dirtyRects.end(); ++it) {
- _system->copyRectToScreen(page0 + it->top * SCREEN_W + it->left, SCREEN_W, it->left, it->top, it->width(), it->height());
+ _system->copyRectToScreen(page0 + it->top * SCREEN_W * _pageScaleFactor[0] + it->left, SCREEN_W * _pageScaleFactor[0], it->left, it->top, it->width(), it->height());
}
}
_forceFullUpdate = false;
@@ -374,6 +434,29 @@ void Screen::mergeOverlay(int x, int y, int w, int h) {
}
}
+const ScreenDim *Screen::getScreenDim(int dim) const {
+ assert(dim < _dimTableCount);
+ return _customDimTable[dim] ? _customDimTable[dim] : &_dimTable[dim];
+}
+
+void Screen::modifyScreenDim(int dim, int x, int y, int w, int h) {
+ if (!_customDimTable[dim])
+ _customDimTable[dim] = new ScreenDim;
+
+ memcpy(_customDimTable[dim], &_dimTable[dim], sizeof(ScreenDim));
+ _customDimTable[dim]->sx = x;
+ _customDimTable[dim]->sy = y;
+ _customDimTable[dim]->w = w;
+ _customDimTable[dim]->h = h;
+ if (dim == _curDimIndex || _vm->game() == GI_LOL)
+ setScreenDim(dim);
+}
+
+void Screen::setScreenDim(int dim) {
+ _curDim = getScreenDim(dim);
+ _curDimIndex = dim;
+}
+
uint8 *Screen::getPagePtr(int pageNum) {
assert(pageNum < SCREEN_PAGE_NUM);
return _pagePtrs[pageNum];
@@ -395,7 +478,7 @@ void Screen::clearPage(int pageNum) {
assert(pageNum < SCREEN_PAGE_NUM);
if (pageNum == 0 || pageNum == 1)
_forceFullUpdate = true;
- memset(getPagePtr(pageNum), 0, SCREEN_PAGE_SIZE);
+ memset(getPagePtr(pageNum), 0, SCREEN_PAGE_SIZE * _pageScaleFactor[_curPage] * _pageScaleFactor[_curPage]);
clearOverlayPage(pageNum);
}
@@ -409,7 +492,7 @@ int Screen::setCurPage(int pageNum) {
void Screen::clearCurPage() {
if (_curPage == 0 || _curPage == 1)
_forceFullUpdate = true;
- memset(getPagePtr(_curPage), 0, SCREEN_PAGE_SIZE);
+ memset(getPagePtr(_curPage), 0, SCREEN_PAGE_SIZE * _pageScaleFactor[_curPage] * _pageScaleFactor[_curPage]);
clearOverlayPage(_curPage);
}
@@ -565,12 +648,17 @@ uint8 Screen::getPagePixel(int pageNum, int x, int y) {
void Screen::setPagePixel(int pageNum, int x, int y, uint8 color) {
assert(pageNum < SCREEN_PAGE_NUM);
assert(x >= 0 && x < SCREEN_W && y >= 0 && y < SCREEN_H);
+
if (pageNum == 0 || pageNum == 1)
addDirtyRect(x, y, 1, 1);
if (_use16ColorMode) {
color &= 0x0F;
color |= (color << 4);
+ } else if (_renderMode == Common::kRenderCGA) {
+ color &= 0x03;
+ } else if (_renderMode == Common::kRenderEGA) {
+ color &= 0x0F;
}
_pagePtrs[pageNum][y * SCREEN_W + x] = color;
@@ -581,13 +669,22 @@ void Screen::fadeFromBlack(int delay, const UpdateFunctor *upFunc) {
}
void Screen::fadeToBlack(int delay, const UpdateFunctor *upFunc) {
+ if (_renderMode == Common::kRenderEGA)
+ return;
+
Palette pal(getPalette(0).getNumColors());
fadePalette(pal, delay, upFunc);
}
void Screen::fadePalette(const Palette &pal, int delay, const UpdateFunctor *upFunc) {
+ if (_renderMode == Common::kRenderEGA)
+ setScreenPalette(pal);
+
updateScreen();
+ if (_renderMode == Common::kRenderCGA || _renderMode == Common::kRenderEGA)
+ return;
+
int diff = 0, delayInc = 0;
getFadeParams(pal, delay, delayInc, diff);
@@ -769,16 +866,26 @@ void Screen::copyToPage0(int y, int h, uint8 page, uint8 *seqBuf) {
}
void Screen::copyRegion(int x1, int y1, int x2, int y2, int w, int h, int srcPage, int dstPage, int flags) {
+ // Since we don't (need to) do any actual scaling, we check for compatible pages here
+ assert(_pageScaleFactor[srcPage] == _pageScaleFactor[dstPage]);
+
+ x1 *= _pageScaleFactor[srcPage];
+ y1 *= _pageScaleFactor[srcPage];
+ x2 *= _pageScaleFactor[dstPage];
+ y2 *= _pageScaleFactor[dstPage];
+ w *= _pageScaleFactor[srcPage];
+ h *= _pageScaleFactor[srcPage];
+
if (x2 < 0) {
if (x2 <= -w)
return;
w += x2;
x1 -= x2;
x2 = 0;
- } else if (x2 + w >= SCREEN_W) {
- if (x2 > SCREEN_W)
+ } else if (x2 + w >= SCREEN_W * _pageScaleFactor[dstPage]) {
+ if (x2 > SCREEN_W * _pageScaleFactor[dstPage])
return;
- w = SCREEN_W - x2;
+ w = SCREEN_W * _pageScaleFactor[srcPage] - x2;
}
if (y2 < 0) {
@@ -787,14 +894,17 @@ void Screen::copyRegion(int x1, int y1, int x2, int y2, int w, int h, int srcPag
h += y2;
y1 -= y2;
y2 = 0;
- } else if (y2 + h >= SCREEN_H) {
- if (y2 > SCREEN_H)
+ } else if (y2 + h >= SCREEN_H * _pageScaleFactor[dstPage]) {
+ if (y2 > SCREEN_H * _pageScaleFactor[dstPage])
return;
- h = SCREEN_H - y2;
+ h = SCREEN_H * _pageScaleFactor[srcPage] - y2;
}
- const uint8 *src = getPagePtr(srcPage) + y1 * SCREEN_W + x1;
- uint8 *dst = getPagePtr(dstPage) + y2 * SCREEN_W + x2;
+ const uint8 *src = getPagePtr(srcPage) + y1 * SCREEN_W * _pageScaleFactor[srcPage] + x1;
+ uint8 *dst = getPagePtr(dstPage) + y2 * SCREEN_W * _pageScaleFactor[dstPage] + x2;
+
+ if (src == dst)
+ return;
if (dstPage == 0 || dstPage == 1)
addDirtyRect(x2, y2, w, h);
@@ -803,9 +913,9 @@ void Screen::copyRegion(int x1, int y1, int x2, int y2, int w, int h, int srcPag
if (flags & CR_NO_P_CHECK) {
while (h--) {
- memcpy(dst, src, w);
- src += SCREEN_W;
- dst += SCREEN_W;
+ memmove(dst, src, w);
+ src += SCREEN_W * _pageScaleFactor[srcPage];
+ dst += SCREEN_W * _pageScaleFactor[dstPage];
}
} else {
while (h--) {
@@ -813,19 +923,24 @@ void Screen::copyRegion(int x1, int y1, int x2, int y2, int w, int h, int srcPag
if (src[i])
dst[i] = src[i];
}
- src += SCREEN_W;
- dst += SCREEN_W;
+ src += SCREEN_W * _pageScaleFactor[srcPage];
+ dst += SCREEN_W * _pageScaleFactor[dstPage];
}
}
}
void Screen::copyRegionToBuffer(int pageNum, int x, int y, int w, int h, uint8 *dest) {
+ x *= _pageScaleFactor[pageNum];
+ y *= _pageScaleFactor[pageNum];
+ w *= _pageScaleFactor[pageNum];
+ h *= _pageScaleFactor[pageNum];
+
if (y < 0) {
dest += (-y) * w;
h += y;
y = 0;
} else if (y + h > SCREEN_H) {
- h = SCREEN_H - y;
+ h = SCREEN_H * _pageScaleFactor[pageNum] - y;
}
if (x < 0) {
@@ -833,7 +948,7 @@ void Screen::copyRegionToBuffer(int pageNum, int x, int y, int w, int h, uint8 *
w += x;
x = 0;
} else if (x + w > SCREEN_W) {
- w = SCREEN_W - x;
+ w = SCREEN_W * _pageScaleFactor[pageNum] - x;
}
if (w < 0 || h < 0)
@@ -842,13 +957,17 @@ void Screen::copyRegionToBuffer(int pageNum, int x, int y, int w, int h, uint8 *
uint8 *pagePtr = getPagePtr(pageNum);
for (int i = y; i < y + h; ++i)
- memcpy(dest + (i - y) * w, pagePtr + i * SCREEN_W + x, w);
+ memcpy(dest + (i - y) * w, pagePtr + i * SCREEN_W * _pageScaleFactor[pageNum] + x, w);
}
void Screen::copyPage(uint8 srcPage, uint8 dstPage) {
+ // Since we don't (need to) do any actual scaling, we check for compatible pages here
+ assert(_pageScaleFactor[srcPage] == _pageScaleFactor[dstPage]);
+
uint8 *src = getPagePtr(srcPage);
uint8 *dst = getPagePtr(dstPage);
- memcpy(dst, src, SCREEN_W * SCREEN_H);
+ if (src != dst)
+ memcpy(dst, src, SCREEN_W * _pageScaleFactor[srcPage] * SCREEN_H * _pageScaleFactor[srcPage]);
copyOverlayRegion(0, 0, 0, 0, SCREEN_W, SCREEN_H, srcPage, dstPage);
if (dstPage == 0 || dstPage == 1)
@@ -875,7 +994,12 @@ void Screen::copyBlockToPage(int pageNum, int x, int y, int w, int h, const uint
if (w < 0 || h < 0)
return;
- uint8 *dst = getPagePtr(pageNum) + y * SCREEN_W + x;
+ x *= _pageScaleFactor[pageNum];
+ y *= _pageScaleFactor[pageNum];
+ w *= _pageScaleFactor[pageNum];
+ h *= _pageScaleFactor[pageNum];
+
+ uint8 *dst = getPagePtr(pageNum) + y * SCREEN_W * _pageScaleFactor[pageNum] + x;
if (pageNum == 0 || pageNum == 1)
addDirtyRect(x, y, w, h);
@@ -884,7 +1008,7 @@ void Screen::copyBlockToPage(int pageNum, int x, int y, int w, int h, const uint
while (h--) {
memcpy(dst, src, w);
- dst += SCREEN_W;
+ dst += SCREEN_W * _pageScaleFactor[pageNum];
src += w;
}
}
@@ -960,6 +1084,10 @@ void Screen::fillRect(int x1, int y1, int x2, int y2, uint8 color, int pageNum,
if (_use16ColorMode) {
color &= 0x0F;
color |= (color << 4);
+ } else if (_renderMode == Common::kRenderCGA) {
+ color &= 0x03;
+ } else if (_renderMode == Common::kRenderEGA) {
+ color &= 0x0F;
}
if (xored) {
@@ -1037,6 +1165,10 @@ void Screen::drawLine(bool vertical, int x, int y, int length, int color) {
if (_use16ColorMode) {
color &= 0x0F;
color |= (color << 4);
+ } else if (_renderMode == Common::kRenderCGA) {
+ color &= 0x03;
+ } else if (_renderMode == Common::kRenderEGA) {
+ color &= 0x0F;
}
if (vertical) {
@@ -1044,7 +1176,7 @@ void Screen::drawLine(bool vertical, int x, int y, int length, int color) {
int currLine = 0;
while (currLine < length) {
*ptr = color;
- ptr += SCREEN_W;
+ ptr += SCREEN_W * _pageScaleFactor[_curPage];
currLine++;
}
} else {
@@ -1088,6 +1220,10 @@ bool Screen::loadFont(FontId fontId, const char *filename) {
if (!fnt) {
if (_isAmiga)
fnt = new AMIGAFont();
+#ifdef ENABLE_EOB
+ else if (_vm->game() == GI_EOB1 || _vm->game() == GI_EOB2)
+ fnt = new OldDOSFont(_renderMode, _vm->gameFlags().useHiRes);
+#endif // ENABLE_EOB
else
fnt = new DOSFont();
@@ -1173,12 +1309,12 @@ void Screen::printText(const char *str, int x, int y, uint8 color1, uint8 color2
break;
} else if (c == '\r') {
x = x_start;
- y += charHeightFnt + _charOffset;
+ y += (charHeightFnt + _charOffset);
} else {
int charWidth = getCharWidth(c);
if (x + charWidth > SCREEN_W) {
x = x_start;
- y += charHeightFnt + _charOffset;
+ y += (charHeightFnt + _charOffset);
if (y >= SCREEN_H)
break;
}
@@ -1215,6 +1351,9 @@ void Screen::drawChar(uint16 c, int x, int y) {
if (x + charWidth > SCREEN_W || y + charHeight > SCREEN_H)
return;
+ x *= _pageScaleFactor[_curPage];
+ y *= _pageScaleFactor[_curPage];
+
if (useOverlay) {
uint8 *destPage = getOverlayPtr(_curPage);
if (!destPage) {
@@ -1226,11 +1365,11 @@ void Screen::drawChar(uint16 c, int x, int y) {
fnt->drawChar(c, destPage, 640);
} else {
- fnt->drawChar(c, getPagePtr(_curPage) + y * SCREEN_W + x, SCREEN_W);
+ fnt->drawChar(c, getPagePtr(_curPage) + y * SCREEN_W * _pageScaleFactor[_curPage] + x, SCREEN_W * _pageScaleFactor[_curPage]);
}
if (_curPage == 0 || _curPage == 1)
- addDirtyRect(x, y, charWidth, charHeight);
+ addDirtyRect(x, y, charWidth * _pageScaleFactor[_curPage], charHeight * _pageScaleFactor[_curPage]);
}
void Screen::drawShape(uint8 pageNum, const uint8 *shapeData, int x, int y, int sd, int flags, ...) {
@@ -1298,6 +1437,8 @@ void Screen::drawShape(uint8 pageNum, const uint8 *shapeData, int x, int y, int
if ((flags & 0x2000) && _vm->game() != GI_KYRA1)
_dsTable5 = va_arg(args, uint8 *);
+ va_end(args);
+
static const DsMarginSkipFunc dsMarginFunc[] = {
&Screen::drawShapeMarginNoScaleUpwind,
&Screen::drawShapeMarginNoScaleDownwind,
@@ -1383,7 +1524,6 @@ void Screen::drawShape(uint8 pageNum, const uint8 *shapeData, int x, int y, int
warning("Missing drawShape plotting method type %d", ppc);
if (dsPlot3 != dsPlot2 && !dsPlot3)
warning("Missing drawShape plotting method type %d", (((flags >> 8) & 0xF7) & 0x3F));
- va_end(args);
return;
}
@@ -1416,10 +1556,8 @@ void Screen::drawShape(uint8 pageNum, const uint8 *shapeData, int x, int y, int
shapeHeight = (shapeHeight * _dsScaleH) >> 8;
shpWidthScaled1 = shpWidthScaled2 = (shapeWidth * _dsScaleW) >> 8;
- if (!shapeHeight || !shpWidthScaled1) {
- va_end(args);
+ if (!shapeHeight || !shpWidthScaled1)
return;
- }
}
if (flags & DSF_CENTER) {
@@ -1449,7 +1587,6 @@ void Screen::drawShape(uint8 pageNum, const uint8 *shapeData, int x, int y, int
if (t < 0) {
shapeHeight += t;
if (shapeHeight <= 0) {
- va_end(args);
return;
}
@@ -1483,10 +1620,8 @@ void Screen::drawShape(uint8 pageNum, const uint8 *shapeData, int x, int y, int
}
t = (flags & 2) ? y + shapeHeight - y1 : y2 - y;
- if (t <= 0) {
- va_end(args);
+ if (t <= 0)
return;
- }
if (t < shapeHeight) {
shapeHeight = t;
@@ -1498,20 +1633,16 @@ void Screen::drawShape(uint8 pageNum, const uint8 *shapeData, int x, int y, int
if (x < 0) {
shpWidthScaled1 += x;
_dsOffscreenLeft = -x;
- if (_dsOffscreenLeft >= shpWidthScaled2) {
- va_end(args);
+ if (_dsOffscreenLeft >= shpWidthScaled2)
return;
- }
x = 0;
}
_dsOffscreenRight = 0;
t = x2 - x;
- if (t <= 0) {
- va_end(args);
+ if (t <= 0)
return;
- }
if (t < shpWidthScaled1) {
shpWidthScaled1 = t;
@@ -1591,8 +1722,6 @@ void Screen::drawShape(uint8 pageNum, const uint8 *shapeData, int x, int y, int
scaleCounterV -= 0x100;
} while (scaleCounterV & 0xFF00);
}
-
- va_end(args);
}
int Screen::drawShapeMarginNoScaleUpwind(uint8 *&dst, const uint8 *&src, int &cnt) {
@@ -1994,6 +2123,86 @@ void Screen::drawShapePlotType52(uint8 *dst, uint8 cmd) {
*dst = cmd;
}
+void Screen::decodeFrame1(const uint8 *src, uint8 *dst, uint32 size) {
+ const uint8 *dstEnd = dst + size;
+
+ struct Pattern {
+ const uint8 *pos;
+ uint16 len;
+ };
+
+ Pattern *patterns = new Pattern[3840];
+ uint16 numPatterns = 0;
+ uint8 nib = 0;
+
+ uint16 code = decodeEGAGetCode(src, nib);
+ uint8 last = code & 0xff;
+
+ uint8 *dstPrev = dst;
+ uint16 count = 1;
+ uint16 countPrev = 1;
+
+ *dst++ = last;
+
+ while (dst < dstEnd) {
+ code = decodeEGAGetCode(src, nib);
+ uint8 cmd = code >> 8;
+
+ if (cmd--) {
+ code = (cmd << 8) | (code & 0xff);
+ uint8 *tmpDst = dst;
+
+ if (code < numPatterns) {
+ const uint8 *tmpSrc = patterns[code].pos;
+ countPrev = patterns[code].len;
+ last = *tmpSrc;
+ for (int i = 0; i < countPrev; i++)
+ *dst++ = *tmpSrc++;
+
+ } else {
+ const uint8 *tmpSrc = dstPrev;
+ count = countPrev;
+ for (int i = 0; i < countPrev; i++)
+ *dst++ = *tmpSrc++;
+ *dst++ = last;
+ countPrev++;
+ }
+
+ if (numPatterns < 3840) {
+ patterns[numPatterns].pos = dstPrev;
+ patterns[numPatterns++].len = ++count;
+ }
+
+ dstPrev = tmpDst;
+ count = countPrev;
+
+ } else {
+ *dst++ = last = (code & 0xff);
+
+ if (numPatterns < 3840) {
+ patterns[numPatterns].pos = dstPrev;
+ patterns[numPatterns++].len = ++count;
+ }
+
+ dstPrev = dst - 1;
+ count = 1;
+ countPrev = 1;
+ }
+ }
+ delete[] patterns;
+}
+
+uint16 Screen::decodeEGAGetCode(const uint8 *&pos, uint8 &nib) {
+ uint16 res = READ_BE_UINT16(pos++);
+ if ((++nib) & 1) {
+ res >>= 4;
+ } else {
+ pos++;
+ res &= 0xfff;
+ }
+ return res;
+}
+
void Screen::decodeFrame3(const uint8 *src, uint8 *dst, uint32 size) {
const uint8 *dstEnd = dst + size;
while (dst < dstEnd) {
@@ -2070,7 +2279,7 @@ void Screen::decodeFrameDelta(uint8 *dst, const uint8 *src, bool noXor) {
wrapped_decodeFrameDelta<false>(dst, src);
}
-template <bool noXor>
+template<bool noXor>
void Screen::wrapped_decodeFrameDelta(uint8 *dst, const uint8 *src) {
while (1) {
uint8 code = *src++;
@@ -2683,21 +2892,20 @@ void Screen::setMouseCursor(int x, int y, const byte *shape) {
if (_vm->gameFlags().useAltShapeHeader)
shape -= 2;
- if (_vm->gameFlags().useHiResOverlay) {
+ if (_vm->gameFlags().useHiRes) {
x <<= 1;
y <<= 1;
mouseWidth <<= 1;
mouseHeight <<= 1;
}
-
uint8 *cursor = new uint8[mouseHeight * mouseWidth];
fillRect(0, 0, mouseWidth, mouseHeight, _cursorColorKey, 8);
drawShape(8, shape, 0, 0, 0, 0);
int xOffset = 0;
- if (_vm->gameFlags().useHiResOverlay) {
+ if (_vm->gameFlags().useHiRes) {
xOffset = mouseWidth;
scale2x(getPagePtr(8) + mouseWidth, SCREEN_W, getPagePtr(8), SCREEN_W, mouseWidth, mouseHeight);
postProcessCursor(getPagePtr(8) + mouseWidth, mouseWidth, mouseHeight, SCREEN_W);
@@ -2859,7 +3067,7 @@ void Screen::loadBitmap(const char *filename, int tempPage, int dstPage, Palette
const char *ext = filename + strlen(filename) - 3;
uint8 compType = srcData[2];
- uint32 imgSize = scumm_stricmp(ext, "CMP") ? READ_LE_UINT32(srcData + 4) : READ_LE_UINT16(srcData);
+ uint32 imgSize = (_vm->game() == GI_KYRA2 && !scumm_stricmp(ext, "CMP")) ? READ_LE_UINT16(srcData) : READ_LE_UINT32(srcData + 4);
uint16 palSize = READ_LE_UINT16(srcData + 8);
if (pal && palSize)
@@ -2875,6 +3083,9 @@ void Screen::loadBitmap(const char *filename, int tempPage, int dstPage, Palette
case 0:
memcpy(dstData, srcPtr, imgSize);
break;
+ case 1:
+ Screen::decodeFrame1(srcPtr, dstData, imgSize);
+ break;
case 3:
Screen::decodeFrame3(srcPtr, dstData, imgSize);
break;
@@ -2899,6 +3110,9 @@ void Screen::loadBitmap(const char *filename, int tempPage, int dstPage, Palette
}
bool Screen::loadPalette(const char *filename, Palette &pal) {
+ if (_renderMode == Common::kRenderCGA)
+ return true;
+
Common::SeekableReadStream *stream = _vm->resource()->createReadStream(filename);
if (!stream)
@@ -2915,6 +3129,12 @@ bool Screen::loadPalette(const char *filename, Palette &pal) {
} else if (_vm->gameFlags().platform == Common::kPlatformPC98 && _use16ColorMode) {
numCols = stream->size() / Palette::kPC98BytesPerColor;
pal.loadPC98Palette(*stream, 0, MIN(maxCols, numCols));
+ } else if (_renderMode == Common::kRenderEGA) {
+ numCols = stream->size();
+ // There aren't any 16 color EGA palette files. So this shouldn't ever get triggered.
+ assert (numCols != 16);
+ numCols /= Palette::kVGABytesPerColor;
+ pal.loadVGAPalette(*stream, 0, numCols);
} else {
numCols = stream->size() / Palette::kVGABytesPerColor;
pal.loadVGAPalette(*stream, 0, MIN(maxCols, numCols));
@@ -2962,7 +3182,14 @@ void Screen::loadPalette(const byte *data, Palette &pal, int bytes) {
pal.loadAmigaPalette(stream, 0, stream.size() / Palette::kAmigaBytesPerColor);
else if (_vm->gameFlags().platform == Common::kPlatformPC98 && _use16ColorMode)
pal.loadPC98Palette(stream, 0, stream.size() / Palette::kPC98BytesPerColor);
- else
+ else if (_renderMode == Common::kRenderEGA) {
+ // EOB II checks the number of palette bytes to distinguish between real EGA palettes
+ // and normal palettes (which are used to generate a color map).
+ if (stream.size() == 16)
+ pal.loadEGAPalette(stream, 0, stream.size());
+ else
+ pal.loadVGAPalette(stream, 0, stream.size() / Palette::kVGABytesPerColor);
+ } else
pal.loadVGAPalette(stream, 0, stream.size() / Palette::kVGABytesPerColor);
}
@@ -2977,7 +3204,7 @@ void Screen::addDirtyRect(int x, int y, int w, int h) {
Common::Rect r(x, y, x + w, y + h);
// Clip rectangle
- r.clip(SCREEN_W, SCREEN_H);
+ r.clip(SCREEN_W * _pageScaleFactor[0], SCREEN_H * _pageScaleFactor[0]);
// If it is empty after clipping, we are done
if (r.isEmpty())
@@ -3080,6 +3307,59 @@ void Screen::copyOverlayRegion(int x, int y, int x2, int y2, int w, int h, int s
}
}
+void Screen::crossFadeRegion(int x1, int y1, int x2, int y2, int w, int h, int srcPage, int dstPage) {
+ if (srcPage > 13 || dstPage > 13)
+ error("Screen::crossFadeRegion(): attempting to use temp page as source or dest page.");
+
+ assert(_pageScaleFactor[srcPage] == _pageScaleFactor[dstPage]);
+
+ hideMouse();
+
+ uint16 *wB = (uint16 *)_pagePtrs[14];
+ uint8 *hB = _pagePtrs[14] + 640;
+
+ for (int i = 0; i < w; i++)
+ wB[i] = i;
+
+ for (int i = 0; i < h; i++)
+ hB[i] = i;
+
+ for (int i = 0; i < w; i++)
+ SWAP(wB[_vm->_rnd.getRandomNumberRng(0, w - 1)], wB[i]);
+
+ for (int i = 0; i < h; i++)
+ SWAP(hB[_vm->_rnd.getRandomNumberRng(0, h - 1)], hB[i]);
+
+ for (int i = 0; i < h; i++) {
+ int iH = i;
+ uint32 end = _system->getMillis() + 3;
+ for (int ii = 0; ii < w; ii++) {
+ int sX = (x1 + wB[ii]);
+ int sY = (y1 + hB[iH]);
+ int dX = (x2 + wB[ii]);
+ int dY = (y2 + hB[iH]);
+
+ if (++iH >= h)
+ iH = 0;
+
+ setPagePixel(dstPage, dX, dY, getPagePixel(srcPage, sX, sY));
+ }
+
+ // This tries to speed things up, to get similiar speeds as in DOSBox etc.
+ // We can't write single pixels directly into the video memory like the original did.
+ // We also (unlike the original) want to aim at similiar speeds for all platforms.
+ if (!(i % 10))
+ updateScreen();
+
+ uint32 cur = _system->getMillis();
+ if (end > cur)
+ _system->delayMillis(end - cur);
+ }
+
+ updateScreen();
+ showMouse();
+}
+
#pragma mark -
DOSFont::DOSFont() {
@@ -3379,7 +3659,27 @@ Palette::~Palette() {
void Palette::loadVGAPalette(Common::ReadStream &stream, int startIndex, int colors) {
assert(startIndex + colors <= _numColors);
- stream.read(_palData + startIndex * 3, colors * 3);
+ uint8 *pos = _palData + startIndex * 3;
+ for (int i = 0 ; i < colors * 3; i++)
+ *pos++ = stream.readByte() & 0x3f;
+}
+
+void Palette::loadEGAPalette(Common::ReadStream &stream, int startIndex, int colors) {
+ assert(startIndex + colors <= 16);
+
+ uint8 *dst = _palData + startIndex * 3;
+ for (int i = 0; i < colors; i++) {
+ uint8 index = stream.readByte();
+ assert(index < _egaNumColors);
+ memcpy(dst, &_egaColors[index * 3], 3);
+ dst += 3;
+ }
+}
+
+void Palette::setCGAPalette(int palIndex, CGAIntensity intensity) {
+ assert(_numColors >= _cgaNumColors);
+ assert(!(palIndex & ~1));
+ memcpy(_palData, _cgaColors[palIndex * 2 + intensity], _numColors * 3);
}
void Palette::loadAmigaPalette(Common::ReadStream &stream, int startIndex, int colors) {
@@ -3458,4 +3758,22 @@ uint8 *Palette::fetchRealPalette() const {
return buffer;
}
+const uint8 Palette::_egaColors[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0x00, 0xAA, 0x00, 0x00, 0xAA, 0xAA,
+ 0xAA, 0x00, 0x00, 0xAA, 0x00, 0xAA, 0xAA, 0x55, 0x00, 0xAA, 0xAA, 0xAA,
+ 0x55, 0x55, 0x55, 0x55, 0x55, 0xFF, 0x55, 0xFF, 0x55, 0x55, 0xFF, 0xFF,
+ 0xFF, 0x55, 0x55, 0xFF, 0x55, 0xFF, 0xFF, 0xFF, 0x55, 0xFF, 0xFF, 0xFF
+};
+
+const int Palette::_egaNumColors = ARRAYSIZE(_egaColors) / 3;
+
+const uint8 Palette::_cgaColors[4][12] = {
+ { 0x00, 0x00, 0x00, 0x00, 0x2A, 0x00, 0x2A, 0x00, 0x00, 0x2A, 0x15, 0x00 },
+ { 0x00, 0x00, 0x00, 0x15, 0x3F, 0x15, 0x3F, 0x15, 0x15, 0x3F, 0x3F, 0x15 },
+ { 0x00, 0x00, 0x00, 0x00, 0x2A, 0x2A, 0x2A, 0x00, 0x2A, 0x2A, 0x2A, 0x2A },
+ { 0x00, 0x00, 0x00, 0x15, 0x3F, 0x3F, 0x3F, 0x15, 0x3F, 0x3F, 0x3F, 0x3F }
+};
+
+const int Palette::_cgaNumColors = ARRAYSIZE(_cgaColors[0]) / 3;
+
} // End of namespace Kyra
diff --git a/engines/kyra/screen.h b/engines/kyra/screen.h
index 51a9a7f744..b064c72bb0 100644
--- a/engines/kyra/screen.h
+++ b/engines/kyra/screen.h
@@ -28,6 +28,7 @@
#include "common/list.h"
#include "common/array.h"
#include "common/rect.h"
+#include "common/rendermode.h"
#include "common/stream.h"
class OSystem;
@@ -137,6 +138,44 @@ private:
uint16 *_bitmapOffsets;
};
+#ifdef ENABLE_EOB
+/**
+ * Implementation of the Font interface for old DOS fonts used
+ * in EOB and EOB II.
+ *
+ */
+class OldDOSFont : public Font {
+public:
+ OldDOSFont(Common::RenderMode mode, bool useHiResEGADithering);
+ ~OldDOSFont();
+
+ bool load(Common::SeekableReadStream &file);
+ int getHeight() const { return _height; }
+ int getWidth() const { return _width; }
+ int getCharWidth(uint16 c) const;
+ void setColorMap(const uint8 *src) { _colorMap = src; }
+ void drawChar(uint16 c, byte *dst, int pitch) const;
+
+private:
+ void unload();
+
+ uint8 *_data;
+ uint16 *_bitmapOffsets;
+
+ int _width, _height;
+ const uint8 *_colorMap;
+
+ int _numGlyphs;
+
+ Common::RenderMode _renderMode;
+ bool _useHiResEGADithering;
+ bool _useLoResEGA;
+
+ static uint16 *_cgaDitheringTable;
+ static int _numRef;
+};
+#endif // ENABLE_EOB
+
/**
* Implementation of the Font interface for AMIGA fonts.
*/
@@ -221,6 +260,21 @@ public:
void loadVGAPalette(Common::ReadStream &stream, int startIndex, int colors);
/**
+ * Load a EGA palette from the given stream.
+ */
+ void loadEGAPalette(Common::ReadStream &stream, int startIndex, int colors);
+
+ /**
+ * Set default CGA palette. We only need the cyan/magenta/grey mode.
+ */
+ enum CGAIntensity {
+ kIntensityLow = 0,
+ kIntensityHigh = 1
+ };
+
+ void setCGAPalette(int palIndex, CGAIntensity intensity);
+
+ /**
* Load a AMIGA palette from the given stream.
*/
void loadAmigaPalette(Common::ReadStream &stream, int startIndex, int colors);
@@ -294,9 +348,15 @@ public:
*/
uint8 *getData() { return _palData; }
const uint8 *getData() const { return _palData; }
+
private:
uint8 *_palData;
const int _numColors;
+
+ static const uint8 _egaColors[];
+ static const int _egaNumColors;
+ static const uint8 _cgaColors[4][12];
+ static const int _cgaNumColors;
};
class Screen {
@@ -335,7 +395,7 @@ public:
FID_NUM
};
- Screen(KyraEngine_v1 *vm, OSystem *system);
+ Screen(KyraEngine_v1 *vm, OSystem *system, const ScreenDim *dimTable, const int dimTableSize);
virtual ~Screen();
// init
@@ -367,12 +427,12 @@ public:
void copyBlockToPage(int pageNum, int x, int y, int w, int h, const uint8 *src);
void shuffleScreen(int sx, int sy, int w, int h, int srcPage, int dstPage, int ticks, bool transparent);
- void fillRect(int x1, int y1, int x2, int y2, uint8 color, int pageNum = -1, bool xored = false);
+ virtual void fillRect(int x1, int y1, int x2, int y2, uint8 color, int pageNum = -1, bool xored = false);
void clearPage(int pageNum);
- uint8 getPagePixel(int pageNum, int x, int y);
- void setPagePixel(int pageNum, int x, int y, uint8 color);
+ virtual uint8 getPagePixel(int pageNum, int x, int y);
+ virtual void setPagePixel(int pageNum, int x, int y, uint8 color);
const uint8 *getCPagePtr(int pageNum) const;
uint8 *getPageRect(int pageNum, int x, int y, int w, int h);
@@ -393,12 +453,12 @@ public:
void enableInterfacePalette(bool e);
void setInterfacePalette(const Palette &pal, uint8 r, uint8 g, uint8 b);
- void getRealPalette(int num, uint8 *dst);
+ virtual void getRealPalette(int num, uint8 *dst);
Palette &getPalette(int num);
void copyPalette(const int dst, const int src);
// gui specific (processing on _curPage)
- void drawLine(bool vertical, int x, int y, int length, int color);
+ virtual void drawLine(bool vertical, int x, int y, int length, int color);
void drawClippedLine(int x1, int y1, int x2, int y2, int color);
virtual void drawShadedBox(int x1, int y1, int x2, int y2, int color1, int color2);
void drawBox(int x1, int y1, int x2, int y2, int color);
@@ -413,14 +473,17 @@ public:
int getCharWidth(uint16 c) const;
int getTextWidth(const char *str) const;
- void printText(const char *str, int x, int y, uint8 color1, uint8 color2);
+ virtual void printText(const char *str, int x, int y, uint8 color1, uint8 color2);
virtual void setTextColorMap(const uint8 *cmap) = 0;
void setTextColor(const uint8 *cmap, int a, int b);
- virtual void setScreenDim(int dim) = 0;
- virtual const ScreenDim *getScreenDim(int dim) = 0;
- virtual int screenDimTableCount() const = 0;
+ const ScreenDim *getScreenDim(int dim) const;
+ void modifyScreenDim(int dim, int x, int y, int w, int h);
+ int screenDimTableCount() const { return _dimTableCount; }
+
+ void setScreenDim(int dim);
+ int curDimIndex() const { return _curDimIndex; }
const ScreenDim *_curDim;
@@ -430,13 +493,13 @@ public:
int setNewShapeHeight(uint8 *shape, int height);
int resetShapeHeight(uint8 *shape);
- void drawShape(uint8 pageNum, const uint8 *shapeData, int x, int y, int sd, int flags, ...);
+ virtual void drawShape(uint8 pageNum, const uint8 *shapeData, int x, int y, int sd, int flags, ...);
// mouse handling
void hideMouse();
void showMouse();
bool isMouseVisible() const;
- void setMouseCursor(int x, int y, const byte *shape);
+ virtual void setMouseCursor(int x, int y, const byte *shape);
// rect handling
virtual int getRectSize(int w, int h) = 0;
@@ -446,9 +509,9 @@ public:
// misc
void loadBitmap(const char *filename, int tempPage, int dstPage, Palette *pal, bool skip=false);
- bool loadPalette(const char *filename, Palette &pal);
+ virtual bool loadPalette(const char *filename, Palette &pal);
bool loadPaletteTable(const char *filename, int firstPalette);
- void loadPalette(const byte *data, Palette &pal, int bytes);
+ virtual void loadPalette(const byte *data, Palette &pal, int bytes);
void setAnimBlockPtr(int size);
@@ -471,6 +534,9 @@ public:
FontId _currentFont;
// decoding functions
+ static void decodeFrame1(const uint8 *src, uint8 *dst, uint32 size);
+ static uint16 decodeEGAGetCode(const uint8 *&pos, uint8 &nib);
+
static void decodeFrame3(const uint8 *src, uint8 *dst, uint32 size);
static uint decodeFrame4(const uint8 *src, uint8 *dst, uint32 dstSize);
static void decodeFrameDelta(uint8 *dst, const uint8 *src, bool noXor = false);
@@ -479,6 +545,9 @@ public:
static void convertAmigaGfx(uint8 *data, int w, int h, int depth = 5, bool wsa = false, int bytesPerPlane = -1);
static void convertAmigaMsc(uint8 *data);
+ // RPG specific, this does not belong here
+ void crossFadeRegion(int x1, int y1, int x2, int y2, int w, int h, int srcPage, int dstPage);
+
protected:
uint8 *getPagePtr(int pageNum);
void updateDirtyRects();
@@ -505,11 +574,16 @@ protected:
uint8 *_pagePtrs[16];
uint8 *_sjisOverlayPtrs[SCREEN_OVLS_NUM];
+ uint8 _pageScaleFactor[SCREEN_PAGE_NUM];
+ uint8 _pageMapping[SCREEN_PAGE_NUM];
bool _useOverlays;
bool _useSJIS;
bool _use16ColorMode;
+ bool _useHiResEGADithering;
+ bool _useLoResEGA;
bool _isAmiga;
+ Common::RenderMode _renderMode;
uint8 _sjisInvisibleColor;
@@ -526,6 +600,12 @@ protected:
uint8 *_animBlockPtr;
int _animBlockSize;
+ // dimension handling
+ const ScreenDim * const _dimTable;
+ ScreenDim **_customDimTable;
+ const int _dimTableCount;
+ int _curDimIndex;
+
// mouse handling
int _mouseLockCount;
const uint8 _cursorColorKey;
diff --git a/engines/kyra/screen_eob.cpp b/engines/kyra/screen_eob.cpp
new file mode 100644
index 0000000000..e06ca42c40
--- /dev/null
+++ b/engines/kyra/screen_eob.cpp
@@ -0,0 +1,1781 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+
+#if !defined(ENABLE_EOB)
+#include "kyra/screen.h"
+#endif
+
+#ifdef ENABLE_EOB
+
+#include "kyra/eobcommon.h"
+#include "kyra/resource.h"
+
+#include "common/system.h"
+
+#include "graphics/cursorman.h"
+#include "graphics/palette.h"
+
+namespace Kyra {
+
+Screen_EoB::Screen_EoB(EoBCoreEngine *vm, OSystem *system) : Screen(vm, system, _screenDimTable, _screenDimTableCount) {
+ _shapeFadeMode[0] = _shapeFadeMode[1] = 0;
+ _shapeFadeInternal = 0;
+ _fadeData = 0;
+ _fadeDataIndex = 0;
+ _dsX1 = _dsX2 = _dsY1 = _dsY2 = 0;
+ _gfxX = _gfxY = 0;
+ _gfxCol = 0;
+ _dsTempPage = 0;
+ _dsDiv = 0;
+ _dsRem = 0;
+ _dsScaleTrans = 0;
+ _cgaScaleTable = 0;
+ _gfxMaxY = 0;
+ _egaDitheringTable = 0;
+ _egaPixelValueTable = 0;
+ _cgaMappingDefault = 0;
+ _cgaDitheringTables[0] = _cgaDitheringTables[1] = 0;
+ _useLoResEGA = _useHiResEGADithering = false;
+}
+
+Screen_EoB::~Screen_EoB() {
+ delete[] _fadeData;
+ delete[] _dsTempPage;
+ delete[] _cgaScaleTable;
+ delete[] _egaDitheringTable;
+ delete[] _egaPixelValueTable;
+ delete[] _cgaDitheringTables[0];
+ delete[] _cgaDitheringTables[1];
+}
+
+bool Screen_EoB::init() {
+ // Define hi-res pages for EGA mode in EOB II
+ if (_vm->gameFlags().useHiRes) {
+ for (int i = 0; i < 8; i++)
+ _pageScaleFactor[i] = 2;
+ }
+
+ if (Screen::init()) {
+ int temp;
+ _gfxMaxY = _vm->staticres()->loadRawData(kEoBBaseExpObjectY, temp);
+
+ if (_renderMode != Common::kRenderCGA && _renderMode != Common::kRenderEGA)
+ _fadeData = _vm->resource()->fileData("FADING.DAT", 0);
+
+ if (!_fadeData) {
+ _fadeData = new uint8[0x700];
+ memset(_fadeData, 0, 0x700);
+ if (_renderMode != Common::kRenderCGA && _renderMode != Common::kRenderEGA) {
+ uint8 *pal = _vm->resource()->fileData("PALETTE1.PAL", 0);
+ for (int i = 0; i < 7; i++)
+ createFadeTable(pal, &_fadeData[i << 8], 18, (i + 1) * 36);
+ delete[] pal;
+ }
+ }
+
+ _dsTempPage = new uint8[12000];
+
+ if (_vm->gameFlags().useHiRes && _renderMode == Common::kRenderEGA) {
+ _useHiResEGADithering = true;
+ _egaDitheringTable = new uint8[256];
+ _egaPixelValueTable = new uint8[256];
+ for (int i = 0; i < 256; i++) {
+ _egaDitheringTable[i] = i & 0x0f;
+ _egaPixelValueTable[i] = i & 0x0f;
+ }
+ } else if (_renderMode == Common::kRenderEGA) {
+ _useLoResEGA = true;
+ } else if (_renderMode == Common::kRenderCGA) {
+ _cgaMappingDefault = _vm->staticres()->loadRawData(kEoB1CgaMappingDefault, temp);
+ _cgaDitheringTables[0] = new uint16[256];
+ memset(_cgaDitheringTables[0], 0, 256 * sizeof(uint16));
+ _cgaDitheringTables[1] = new uint16[256];
+ memset(_cgaDitheringTables[1], 0, 256 * sizeof(uint16));
+
+ _cgaScaleTable = new uint8[256];
+ memset(_cgaScaleTable, 0, 256 * sizeof(uint8));
+ for (int i = 0; i < 256; i++)
+ _cgaScaleTable[i] = ((i & 0xf0) >> 2) | (i & 0x03);
+ }
+
+ return true;
+ }
+ return false;
+}
+
+void Screen_EoB::setClearScreenDim(int dim) {
+ setScreenDim(dim);
+ clearCurDim();
+}
+
+void Screen_EoB::clearCurDim() {
+ fillRect(_curDim->sx << 3, _curDim->sy, ((_curDim->sx + _curDim->w) << 3) - 1, (_curDim->sy + _curDim->h) - 1, _curDim->unkA);
+}
+
+void Screen_EoB::setMouseCursor(int x, int y, const byte *shape) {
+ setMouseCursor(x, y, shape, 0);
+}
+
+void Screen_EoB::setMouseCursor(int x, int y, const byte *shape, const uint8 *ovl) {
+ if (!shape)
+ return;
+
+ int mouseW = (shape[2] << 3);
+ int mouseH = (shape[3]);
+ int colorKey = (_renderMode == Common::kRenderCGA) ? 0 : _cursorColorKey;
+
+ uint8 *cursor = new uint8[mouseW * _pageScaleFactor[6] * mouseH * _pageScaleFactor[6]];
+ // We use memset and copyBlockToPage instead of fillRect to make sure that the
+ // color key 0xFF doesn't get converted into EGA color
+ memset(cursor, colorKey, mouseW * _pageScaleFactor[6] * mouseH * _pageScaleFactor[6]);
+ copyBlockToPage(6, 0, 0, mouseW, mouseH, cursor);
+ drawShape(6, shape, 0, 0, 0, 2, ovl);
+ CursorMan.showMouse(false);
+ copyRegionToBuffer(6, 0, 0, mouseW, mouseH, cursor);
+
+ // Mouse cursor post processing for CGA mode. Unlike the original (which uses drawShape for the mouse cursor)
+ // the cursor manager cannot know whether a pixel value of 0 is supposed to be black or transparent. Thus, we
+ // go over the transparency mask again and turn the black pixels to color 4.
+ if (_renderMode == Common::kRenderCGA) {
+ const uint8 *maskTbl = shape + 4 + ((mouseW * mouseH) >> 2);
+ uint8 *dst = cursor;
+ uint8 trans = 0;
+ uint8 shift = 6;
+
+ uint16 mH = mouseH;
+ while (mH--) {
+ uint16 mW = mouseW;
+ while (mW--) {
+ if (shift == 6)
+ trans = *maskTbl++;
+ if (!*dst && !((trans >> shift) & 3))
+ *dst = 4;
+ dst++;
+ shift = (shift - 2) & 7;
+ }
+ }
+ }
+
+ CursorMan.replaceCursor(cursor, mouseW * _pageScaleFactor[6], mouseH * _pageScaleFactor[6], x, y, colorKey);
+ if (isMouseVisible())
+ CursorMan.showMouse(true);
+ delete[] cursor;
+
+ // makes sure that the cursor is drawn
+ // we do not use Screen::updateScreen here
+ // so we can be sure that changes to page 0
+ // are NOT updated on the real screen here
+ _system->updateScreen();
+}
+
+void Screen_EoB::loadFileDataToPage(Common::SeekableReadStream *s, int pageNum, uint32 size) {
+ s->read(_pagePtrs[pageNum], size);
+}
+
+void Screen_EoB::printText(const char *str, int x, int y, uint8 color1, uint8 color2) {
+ if (_useHiResEGADithering) {
+ // This is sort of an abuse of the text color map. But since EOB doesn't use it anyway
+ // and the font drawing code needs access to both the original color values and the
+ // EGA dithering colors we pass them on like this.
+ uint8 cmap[2];
+ cmap[0] = _egaDitheringTable[color2];
+ cmap[1] = _egaDitheringTable[color1];
+ setTextColor(cmap, 2, 3);
+ }
+ Screen::printText(str, x, y, color1, color2);
+}
+
+void Screen_EoB::printShadedText(const char *string, int x, int y, int col1, int col2) {
+ printText(string, x - 1, y, 12, col2);
+ printText(string, x, y + 1, 12, 0);
+ printText(string, x - 1, y + 1, 12, 0);
+ printText(string, x, y, col1, 0);
+}
+
+void Screen_EoB::loadShapeSetBitmap(const char *file, int tempPage, int destPage) {
+ loadEoBBitmap(file, _cgaMappingDefault, tempPage, destPage, -1);
+ _curPage = 2;
+}
+
+void Screen_EoB::loadEoBBitmap(const char *file, const uint8 *cgaMapping, int tempPage, int destPage, int convertToPage) {
+ const char *filePattern = (_vm->game() == GI_EOB1 && (_renderMode == Common::kRenderEGA || _renderMode == Common::kRenderCGA)) ? "%s.EGA" : "%s.CPS";
+ Common::String tmp = Common::String::format(filePattern, file);
+ Common::SeekableReadStream *s = _vm->resource()->createReadStream(tmp);
+ bool loadAlternative = false;
+ if (s) {
+ // This additional check is necessary since some localized versions of EOB II seem to contain invalid (size zero) cps files
+ if (s->size())
+ loadBitmap(tmp.c_str(), tempPage, destPage, 0);
+ else
+ loadAlternative = true;
+
+ delete s;
+ } else {
+ loadAlternative = true;
+ }
+
+ if (loadAlternative) {
+ if (_vm->game() == GI_EOB1) {
+ tmp.insertChar('1', tmp.size() - 4);
+ loadBitmap(tmp.c_str(), tempPage, destPage, 0);
+ } else {
+ tmp.setChar('X', 0);
+ s = _vm->resource()->createReadStream(tmp);
+ if (!s)
+ error("Screen_EoB::loadEoBBitmap(): Failed to load file '%s'", file);
+ s->seek(768);
+ loadFileDataToPage(s, destPage, 64000);
+ delete s;
+ }
+ }
+
+ if (convertToPage == -1) {
+ return;
+ } else if (convertToPage == 2 && _renderMode == Common::kRenderCGA) {
+ convertPage(destPage, 4, cgaMapping);
+ copyRegion(0, 0, 0, 0, 320, 200, 4, 2, Screen::CR_NO_P_CHECK);
+ } else if (convertToPage == 0) {
+ convertPage(destPage, 2, cgaMapping);
+ copyRegion(0, 0, 0, 0, 320, 200, 2, 0, Screen::CR_NO_P_CHECK);
+ } else {
+ convertPage(destPage, convertToPage, cgaMapping);
+ }
+}
+
+void Screen_EoB::convertPage(int srcPage, int dstPage, const uint8 *cgaMapping) {
+ uint8 *src = getPagePtr(srcPage);
+ uint8 *dst = getPagePtr(dstPage);
+ if (src == dst)
+ return;
+
+ if (_renderMode == Common::kRenderCGA) {
+ if (cgaMapping)
+ generateCGADitheringTables(cgaMapping);
+
+ uint16 *d = (uint16*)dst;
+ uint8 tblSwitch = 0;
+ for (int height = SCREEN_H; height; height--) {
+ const uint16 *table = _cgaDitheringTables[(tblSwitch++) & 1];
+ for (int width = SCREEN_W / 2; width; width--) {
+ WRITE_LE_UINT16(d++, table[((src[1] & 0x0f) << 4) | (src[0] & 0x0f)]);
+ src += 2;
+ }
+ }
+
+ } else if (_useHiResEGADithering) {
+ for (int height = SCREEN_H; height; height--) {
+ uint8 *dst2 = dst + SCREEN_W * 2;
+ for (int width = SCREEN_W; width; width--) {
+ uint8 in = _egaDitheringTable[*src++];
+ *dst++ = *dst2++ = in >> 4;
+ *dst++ = *dst2++ = in & 0x0f;
+ }
+ dst += (SCREEN_W * 2);
+ }
+
+ } else if (_renderMode == Common::kRenderEGA) {
+ uint32 len = SCREEN_W * SCREEN_H;
+ while (len--)
+ *dst++ = *src++ & 0x0f;
+
+ } else {
+ copyPage(srcPage, dstPage);
+ }
+
+ if (dstPage == 0 || dstPage == 1)
+ _forceFullUpdate = true;
+}
+
+void Screen_EoB::fillRect(int x1, int y1, int x2, int y2, uint8 color, int pageNum, bool xored) {
+ if (!_useHiResEGADithering) {
+ Screen::fillRect(x1, y1, x2, y2, color, pageNum, xored);
+ return;
+ }
+
+ assert(x2 < SCREEN_W && y2 < SCREEN_H);
+ if (pageNum == -1)
+ pageNum = _curPage;
+
+ uint16 pitch = (SCREEN_W - (x2 - x1 + 1)) * _pageScaleFactor[pageNum];
+ uint8 col1 = (_egaDitheringTable[color] >> 4);
+ uint8 col2 = (_egaDitheringTable[color] & 0x0f);
+
+ x1 *= _pageScaleFactor[pageNum];
+ y1 *= _pageScaleFactor[pageNum];
+ x2 *= _pageScaleFactor[pageNum];
+ y2 *= _pageScaleFactor[pageNum];
+ uint16 w = x2 - x1 + _pageScaleFactor[pageNum];
+ uint16 h = y2 - y1 + _pageScaleFactor[pageNum];
+
+ uint8 *dst = getPagePtr(pageNum) + y1 * SCREEN_W * _pageScaleFactor[pageNum] + x1;
+ if (pageNum == 0 || pageNum == 1)
+ addDirtyRect(x1, y1, w, h);
+
+ while (h--) {
+ for (uint16 w1 = w; w1; w1 -= 2) {
+ *dst++ = col1;
+ *dst++ = col2;
+ }
+ dst += pitch;
+ }
+}
+
+void Screen_EoB::drawLine(bool vertical, int x, int y, int length, int color) {
+ if (!_useHiResEGADithering) {
+ Screen::drawLine(vertical, x, y, length, color);
+ return;
+ }
+
+ uint16 pitch = (SCREEN_W - 1) * _pageScaleFactor[_curPage];
+ uint8 col1 = (_egaDitheringTable[color] >> 4);
+ uint8 col2 = (_egaDitheringTable[color] & 0x0f);
+
+ x *= _pageScaleFactor[_curPage];
+ y *= _pageScaleFactor[_curPage];
+ length *= _pageScaleFactor[_curPage];
+ uint8 *ptr = getPagePtr(_curPage) + y * SCREEN_W * _pageScaleFactor[_curPage] + x;
+ uint8 *ptr2 = ptr + SCREEN_W * _pageScaleFactor[_curPage];
+
+ if (vertical) {
+ assert((y + length) <= SCREEN_H * _pageScaleFactor[_curPage]);
+ int currLine = 0;
+ while (currLine < length) {
+ *ptr++ = col1;
+ *ptr++ = col2;
+ ptr += pitch;
+ currLine++;
+ }
+ } else {
+ assert((x + length) <= SCREEN_W * _pageScaleFactor[_curPage]);
+ int currLine = 0;
+ while (currLine < length) {
+ *ptr++ = *ptr2++ = col1;
+ *ptr++ = *ptr2++ = col2;
+ currLine += 2;
+ }
+ }
+
+ if (_curPage == 0 || _curPage == 1)
+ addDirtyRect(x, y, (vertical) ? _pageScaleFactor[_curPage] : length, (vertical) ? length : _pageScaleFactor[_curPage]);
+}
+
+uint8 Screen_EoB::getPagePixel(int pageNum, int x, int y) {
+ if (!_useHiResEGADithering)
+ return Screen::getPagePixel(pageNum, x, y);
+
+ x *= _pageScaleFactor[_curPage];
+ y *= _pageScaleFactor[_curPage];
+ uint8 *pos = &_pagePtrs[pageNum][y * SCREEN_W * _pageScaleFactor[_curPage] + x];
+
+ return _egaPixelValueTable[(pos[0] << 4) | (pos[1] & 0x0f)];
+}
+
+void Screen_EoB::setPagePixel(int pageNum, int x, int y, uint8 color) {
+ if (!_useHiResEGADithering) {
+ Screen::setPagePixel(pageNum, x, y, color);
+ return;
+ }
+
+ assert(pageNum < SCREEN_PAGE_NUM);
+ assert(x >= 0 && x < SCREEN_W && y >= 0 && y < SCREEN_H);
+
+ x *= _pageScaleFactor[_curPage];
+ y *= _pageScaleFactor[_curPage];
+
+ if (pageNum == 0 || pageNum == 1)
+ addDirtyRect(x, y, _pageScaleFactor[pageNum], _pageScaleFactor[pageNum]);
+
+ uint8 *pos = &_pagePtrs[pageNum][y * SCREEN_W * _pageScaleFactor[_curPage] + x];
+ uint8 *pos2 = pos + SCREEN_W * _pageScaleFactor[_curPage];
+ pos[0] = pos2[0] = _egaDitheringTable[color] >> 4;
+ pos[1] = pos2[1] = _egaDitheringTable[color] & 0x0f;
+}
+
+void Screen_EoB::setScreenPalette(const Palette &pal) {
+ if (_useHiResEGADithering && pal.getNumColors() != 16) {
+ generateEGADitheringTable(pal);
+ } else if (_renderMode == Common::kRenderEGA && pal.getNumColors() == 16) {
+ _screenPalette->copy(pal);
+ _system->getPaletteManager()->setPalette(_screenPalette->getData(), 0, _screenPalette->getNumColors());
+ } else if (_renderMode != Common::kRenderCGA && _renderMode != Common::kRenderEGA) {
+ Screen::setScreenPalette(pal);
+ }
+}
+
+void Screen_EoB::getRealPalette(int num, uint8 *dst) {
+ if (_renderMode == Common::kRenderCGA || _renderMode == Common::kRenderEGA) {
+ const uint8 *pal = _screenPalette->getData();
+ for (int i = 0; i < 16; ++i) {
+ dst[0] = (pal[0] << 2) | (pal[0] & 3);
+ dst[1] = (pal[1] << 2) | (pal[1] & 3);
+ dst[2] = (pal[2] << 2) | (pal[2] & 3);
+ dst += 3;
+ pal += 3;
+ }
+ } else {
+ Screen::getRealPalette(num, dst);
+ }
+}
+
+uint8 *Screen_EoB::encodeShape(uint16 x, uint16 y, uint16 w, uint16 h, bool encode8bit, const uint8 *cgaMapping) {
+ uint8 *shp = 0;
+ uint16 shapesize = 0;
+
+ uint8 *srcLineStart = getPagePtr(_curPage | 1) + y * 320 + (x << 3);
+ uint8 *src = srcLineStart;
+
+ if (_useLoResEGA)
+ encode8bit = false;
+
+ if (_renderMode == Common::kRenderCGA) {
+ if (cgaMapping)
+ generateCGADitheringTables(cgaMapping);
+ shapesize = h * (w << 2) + 4;
+ shp = new uint8[shapesize];
+ memset(shp, 0, shapesize);
+ uint8 *dst = shp;
+
+ *dst++ = 4;
+ *dst++ = (h & 0xff);
+ *dst++ = (w & 0xff);
+ *dst++ = (h & 0xff);
+
+ uint8 *dst2 = dst + (h * (w << 1));
+
+ uint8 tblSwitch = 0;
+ uint16 h1 = h;
+ while (h1--) {
+ uint16 w1 = w << 1;
+ const uint16 *table = _cgaDitheringTables[(tblSwitch++) & 1];
+
+ while (w1--) {
+ uint16 p0 = table[((src[1] & 0x0f) << 4) | (src[0] & 0x0f)];
+ uint16 p1 = table[((src[3] & 0x0f) << 4) | (src[2] & 0x0f)];
+
+ *dst++ = ((p0 & 0x0003) << 6) | ((p0 & 0x0300) >> 4) | ((p1 & 0x0003) << 2) | ((p1 & 0x0300) >> 8);
+
+ uint8 msk = 0;
+ for (int i = 0; i < 4; i++) {
+ if (!src[3 - i])
+ msk |= (3 << (i << 1));
+ }
+ *dst2++ = msk;
+ src += 4;
+ }
+ srcLineStart += SCREEN_W;
+ src = srcLineStart;
+ }
+
+ } else if (encode8bit) {
+ uint16 h1 = h;
+ while (h1--) {
+ uint8 *lineEnd = src + (w << 3);
+ do {
+ if (!*src++) {
+ shapesize++;
+ uint8 *startZeroPos = src;
+ while (src != lineEnd && *src == 0)
+ src++;
+
+ uint16 numZero = src - startZeroPos + 1;
+ if (numZero >> 8)
+ shapesize += 2;
+ }
+ shapesize++;
+ } while (src != lineEnd);
+
+ srcLineStart += SCREEN_W;
+ src = srcLineStart;
+ }
+
+ shapesize += 4;
+
+ shp = new uint8[shapesize];
+ memset(shp, 0, shapesize);
+ uint8 *dst = shp;
+
+ *dst++ = 8;
+ *dst++ = (h & 0xff);
+ *dst++ = (w & 0xff);
+ *dst++ = (h & 0xff);
+
+ srcLineStart = getPagePtr(_curPage | 1) + y * 320 + (x << 3);
+ src = srcLineStart;
+
+ h1 = h;
+ while (h1--) {
+ uint8 *lineEnd = src + (w << 3);
+ do {
+ uint8 val = *src++;
+ if (!val) {
+ *dst++ = 0;
+ uint8 *startZeroPos = src;
+
+ while (src != lineEnd && *src == 0)
+ src++;
+
+ uint16 numZero = src - startZeroPos + 1;
+ if (numZero >> 8) {
+ *dst++ = 255;
+ *dst++ = 0;
+ numZero -= 255;
+ }
+ val = numZero & 0xff;
+ }
+ *dst++ = val;
+ } while (src != lineEnd);
+
+ srcLineStart += SCREEN_W;
+ src = srcLineStart;
+ }
+
+ } else {
+ uint8 nib = 0, col = 0;
+ uint8 *colorMap = 0;
+
+ if (_renderMode != Common::kRenderEGA || _useHiResEGADithering) {
+ colorMap = new uint8[0x100];
+ memset(colorMap, 0xff, 0x100);
+ }
+
+ shapesize = h * (w << 2) + 20;
+ shp = new uint8[shapesize];
+ memset(shp, 0, shapesize);
+ uint8 *dst = shp;
+
+ *dst++ = 2;
+ *dst++ = (h & 0xff);
+ *dst++ = (w & 0xff);
+ *dst++ = (h & 0xff);
+
+ if (_useLoResEGA) {
+ for (int i = 0; i < 16; i++)
+ dst[i] = i;
+ } else {
+ memset(dst, 0xff, 0x10);
+ }
+
+ uint8 *pal = dst;
+ dst += 16;
+ nib = col = 0;
+
+ uint16 h1 = h;
+ while (h1--) {
+ uint16 w1 = w << 3;
+ while (w1--) {
+ uint8 s = *src++;
+ uint8 c = s & 0x0f;
+ if (colorMap) {
+ c = colorMap[s];
+ if (c == 0xff) {
+ if (col < 0x10) {
+ *pal++ = s;
+ c = colorMap[s] = col++;
+ if (!col)
+ c = 0;
+ } else {
+ c = 0;
+ }
+ }
+ }
+
+ if (++nib & 1)
+ *dst = c << 4;
+ else
+ *dst++ |= c;
+ }
+ srcLineStart += SCREEN_W;
+ src = srcLineStart;
+ }
+ delete [] colorMap;
+ }
+
+ return shp;
+}
+
+void Screen_EoB::drawShape(uint8 pageNum, const uint8 *shapeData, int x, int y, int sd, int flags, ...) {
+ uint8 *dst = getPagePtr(pageNum);
+ const uint8 *src = shapeData;
+
+ if (!src)
+ return;
+
+ va_list args;
+ va_start(args, flags);
+ uint8 *ovl = (flags & 2) ? va_arg(args, uint8 *) : 0;
+ va_end(args);
+
+ if (sd != -1) {
+ const ScreenDim *dm = getScreenDim(sd);
+ setShapeFrame(dm->sx, dm->sy, dm->sx + dm->w, dm->sy + dm->h);
+ x += (_dsX1 << 3);
+ y += _dsY1;
+ }
+
+ dst += (_dsX1 << 3) * _pageScaleFactor[pageNum];
+ int16 dX = x - (_dsX1 << 3);
+ int16 dY = y;
+ int16 dW = _dsX2 - _dsX1;
+ uint8 pixelsPerByte = *src++ ;
+
+ uint16 dH = *src++;
+ uint16 width = (*src++) << 3;
+ uint16 transOffset = (pixelsPerByte == 4) ? (dH * width) >> 2 : 0;
+ src++;
+
+ int rX = x;
+ int rY = y;
+ int rW = width + 8;
+ int rH = dH;
+
+ uint16 w2 = width;
+ int d = dY - _dsY1;
+
+ int pixelStep = (flags & 1) ? -1 : 1;
+
+ if (pixelsPerByte == 8) {
+ uint16 marginLeft = 0;
+ uint16 marginRight = 0;
+
+ if (d < 0) {
+ dH += d;
+ if (dH <= 0)
+ return;
+ d = -d;
+
+ for (int i = 0; i < d; i++) {
+ marginLeft = width;
+ for (int ii = 0; ii < marginLeft; ii++) {
+ if (!*src++)
+ marginLeft = marginLeft + 1 - *src++;
+ }
+ }
+ dY = _dsY1;
+ }
+
+ d = _dsY2 - dY;
+
+ if (d < 1)
+ return;
+
+ if (d < dH)
+ dH = d;
+
+ marginLeft = 0;
+
+ if (dX < 0) {
+ width += dX;
+ marginLeft = -dX;
+
+ if (marginLeft >= w2)
+ return;
+
+ dX = 0;
+ }
+
+ marginRight = 0;
+ d = (dW << 3) - dX;
+
+ if (d < 1)
+ return;
+
+ if (d < width) {
+ width = d;
+ marginRight = w2 - marginLeft - width;
+ }
+
+ dst += (dY * SCREEN_W * _pageScaleFactor[pageNum] * _pageScaleFactor[pageNum] + dX * _pageScaleFactor[pageNum]);
+ uint8 *dstL = dst;
+
+ if (pageNum == 0 || pageNum == 1)
+ addDirtyRect(rX * _pageScaleFactor[pageNum], rY * _pageScaleFactor[pageNum], rW * _pageScaleFactor[pageNum], rH * _pageScaleFactor[pageNum]);
+
+ while (dH--) {
+ int16 xpos = (int16) marginLeft;
+
+ if (flags & 1) {
+ for (int i = 0; i < w2; i++) {
+ if (*src++ == 0) {
+ i += (*src - 1);
+ src += (*src - 1);
+ }
+ }
+ src--;
+ }
+ const uint8 *src2 = src;
+
+ if (xpos) {
+ do {
+ uint8 val = (flags & 1) ? *(src - 1) : *src;
+ while (val && xpos) {
+ src += pixelStep;
+ xpos--;
+ val = (flags & 1) ? *(src - 1) : *src;
+ }
+
+ val = (flags & 1) ? *(src - 1) : *src;
+ if (!val) {
+ src += pixelStep;
+ uint8 bt = (flags & 1) ? src[1] : src[0];
+ src += pixelStep;
+ xpos = xpos - bt;
+ }
+ } while (xpos > 0);
+ }
+
+ dst -= (xpos * _pageScaleFactor[pageNum]);
+ xpos += width;
+
+ while (xpos > 0) {
+ uint8 c = *src;
+ uint8 m = (flags & 1) ? *(src - 1) : c;
+ src += pixelStep;
+
+ if (m) {
+ drawShapeSetPixel(dst, c, SCREEN_W * _pageScaleFactor[pageNum]);
+ dst += _pageScaleFactor[pageNum];
+ xpos--;
+ } else {
+ uint8 len = (flags & 1) ? src[1] : src[0];
+ dst += (len * _pageScaleFactor[pageNum]);
+ xpos -= len;
+ src += pixelStep;
+ }
+ }
+ xpos += marginRight;
+
+ if (xpos) {
+ do {
+ uint8 val = (flags & 1) ? *(src - 1) : *src;
+ while (val && xpos) {
+ src += pixelStep;
+ xpos--;
+ val = (flags & 1) ? *(src - 1) : *src;
+ }
+
+ val = (flags & 1) ? *(src - 1) : *src;
+ if (!val) {
+ src += pixelStep;
+ uint8 bt = (flags & 1) ? src[1] : src[0];
+ src += pixelStep;
+ xpos = xpos - bt;
+ }
+ } while (xpos > 0);
+ }
+
+ dstL += SCREEN_W * _pageScaleFactor[pageNum] * _pageScaleFactor[pageNum];
+ dst = dstL;
+ if (flags & 1)
+ src = src2 + 1;
+ }
+ } else {
+ const uint8 *pal = 0;
+ uint8 cgaPal[4];
+ memset(cgaPal, 0, 4);
+
+ if (pixelsPerByte == 2) {
+ pal = ovl ? ovl : src;
+ src += 16;
+ } else {
+ static const uint8 cgaDefOvl[] = { 0x00, 0x55, 0xaa, 0xff };
+ pal = ovl ? ovl : cgaDefOvl;
+ for (int i = 0; i < 4; i++)
+ cgaPal[i] = pal[i] & 3;
+ pal = cgaPal;
+ }
+
+ if (d < 0) {
+ d = -d;
+ if (d >= dH)
+ return;
+ src += (d * (width / pixelsPerByte));
+ d = dY + dH - _dsY1;
+ if (d >= 0) {
+ dH = d;
+ dY = _dsY1;
+ d = _dsY2 - dY;
+ }
+ } else {
+ d = _dsY2 - dY;
+ }
+
+ if (d < 1)
+ return;
+
+ if (d < dH)
+ dH = d;
+
+ bool trimL = false;
+ uint8 dXbitAlign = dX & (pixelsPerByte - 1);
+
+ if (dX < 0) {
+ width += dX;
+ d = -dX;
+ if (flags & 1)
+ src -= (d / pixelsPerByte);
+ else
+ src += (d / pixelsPerByte);
+
+ if (d >= w2)
+ return;
+
+ dX = 0;
+ trimL = true;
+ }
+
+ d = (dW << 3) - dX;
+
+ if (d < 1)
+ return;
+
+ if (d < width)
+ width = d;
+
+ dst += (dY * _pageScaleFactor[pageNum] * SCREEN_W * _pageScaleFactor[pageNum] + dX * _pageScaleFactor[pageNum]);
+
+ if (pageNum == 0 || pageNum == 1)
+ addDirtyRect(rX * _pageScaleFactor[pageNum], rY * _pageScaleFactor[pageNum], rW * _pageScaleFactor[pageNum], rH * _pageScaleFactor[pageNum]);
+
+ int pitch = SCREEN_W * _pageScaleFactor[pageNum] * _pageScaleFactor[pageNum] - width * _pageScaleFactor[pageNum];
+ int16 lineSrcStep = (w2 - width) / pixelsPerByte;
+ uint8 lineSrcStepRemainder = (w2 - width) % pixelsPerByte;
+
+ w2 /= pixelsPerByte;
+ if (flags & 1)
+ src += (w2 - 1);
+
+ uint8 pixelPacking = 8 / pixelsPerByte;
+ uint8 pixelPackingMask = 0;
+
+ for (int i = 0; i < pixelPacking; i++)
+ pixelPackingMask |= (1 << i);
+
+ if (trimL && (dXbitAlign > lineSrcStepRemainder))
+ lineSrcStep--;
+
+ uint8 bitShDef = 8 - pixelPacking;
+ if (flags & 1) {
+ lineSrcStep = (w2 << 1) - lineSrcStep;
+ bitShDef = 0;
+ }
+
+ uint8 bitShLineStart = bitShDef;
+ if (trimL)
+ bitShLineStart -= (dXbitAlign * pixelStep * pixelPacking);
+
+ while (dH--) {
+ int16 wd = width;
+ uint8 in = 0;
+ uint8 trans = 0;
+ uint8 shift = bitShLineStart;
+ uint8 shSwtch = bitShLineStart;
+
+ while (wd--) {
+ if (shift == shSwtch) {
+ in = *src;
+ trans = src[transOffset];
+ src += pixelStep;
+ shSwtch = bitShDef;
+ }
+ uint8 col = (pixelsPerByte == 2) ? pal[(in >> shift) & pixelPackingMask] : (*dst & ((trans >> shift) & (pixelPackingMask))) | pal[(in >> shift) & pixelPackingMask];
+ if (col || pixelsPerByte == 4)
+ drawShapeSetPixel(dst, col, SCREEN_W * _pageScaleFactor[pageNum]);
+ dst += _pageScaleFactor[pageNum];
+ shift = ((shift - (pixelStep * pixelPacking)) & 7);
+ }
+ src += lineSrcStep;
+ dst += pitch;
+ }
+ }
+}
+
+const uint8 *Screen_EoB::scaleShape(const uint8 *shapeData, int steps) {
+ setShapeFadeMode(1, steps ? true : false);
+
+ while (shapeData && steps--)
+ shapeData = scaleShapeStep(shapeData);
+
+ return shapeData;
+}
+
+const uint8 *Screen_EoB::scaleShapeStep(const uint8 *shp) {
+ uint8 *dst = (shp != _dsTempPage) ? _dsTempPage : _dsTempPage + 6000;
+ uint8 *d = dst;
+ uint8 pixelsPerByte = *d++ = *shp++;
+ assert (pixelsPerByte > 1);
+
+ uint16 h = shp[0] + 1;
+ d[0] = d[2] = (h << 1) / 3;
+
+ uint16 w = shp[1];
+ uint16 w2 = (w << 3) / pixelsPerByte;
+ uint16 t = ((w << 1) % 3) ? 1 : 0;
+ d[1] = ((w << 1) / 3) + t;
+
+ uint32 transOffsetSrc = (pixelsPerByte == 4) ? (shp[0] * shp[1]) << 1 : 0;
+ uint32 transOffsetDst = (pixelsPerByte == 4) ? (d[0] * d[1]) << 1 : 0;
+ shp += 3;
+ d += 3;
+
+ if (pixelsPerByte == 2) {
+ int i = 0;
+ while (i < 16) {
+ if (!shp[i]) {
+ i = -i;
+ break;
+ }
+ i++;
+ }
+
+ if (i >= 0)
+ i = 0;
+ else
+ i = -i;
+
+ _dsScaleTrans = (i << 4) | (i & 0x0f);
+ for (int ii = 0; ii < 16; ii++)
+ *d++ = *shp++;
+ }
+
+ _dsDiv = w2 / 3;
+ _dsRem = w2 % 3;
+
+ while (--h) {
+ if (pixelsPerByte == 2)
+ scaleShapeProcessLine4Bit(d, shp);
+ else
+ scaleShapeProcessLine2Bit(d, shp, transOffsetDst, transOffsetSrc);
+ if (!--h)
+ break;
+ if (pixelsPerByte == 2)
+ scaleShapeProcessLine4Bit(d, shp);
+ else
+ scaleShapeProcessLine2Bit(d, shp, transOffsetDst, transOffsetSrc);
+ if (!--h)
+ break;
+ shp += w2;
+ }
+
+ return (const uint8*)dst;
+}
+
+const uint8 *Screen_EoB::generateShapeOverlay(const uint8 *shp, int paletteOverlayIndex) {
+ if (*shp != 2)
+ return 0;
+
+ shp += 4;
+ uint8 *ovl = getFadeTable(paletteOverlayIndex);
+ for (int i = 0; i < 16; i++)
+ _shapeOverlay[i] = ovl[shp[i]];
+ return _shapeOverlay;
+}
+
+void Screen_EoB::setShapeFrame(int x1, int y1, int x2, int y2) {
+ _dsX1 = x1;
+ _dsY1 = y1;
+ _dsX2 = x2;
+ _dsY2 = y2;
+}
+
+void Screen_EoB::setShapeFadeMode(uint8 i, bool b) {
+ if (!i || i == 1)
+ _shapeFadeMode[i] = b;
+}
+
+void Screen_EoB::setGfxParameters(int x, int y, int col) {
+ _gfxX = x;
+ _gfxY = y;
+ _gfxCol = col;
+}
+
+void Screen_EoB::drawExplosion(int scale, int radius, int numElements, int stepSize, int aspectRatio, const uint8 *colorTable, int colorTableSize) {
+ int ymin = 0;
+ int ymax = _gfxMaxY[scale];
+ int xmin = -100;
+ int xmax = 276;
+
+ if (scale)
+ --scale;
+
+ hideMouse();
+
+ const ScreenDim *dm = getScreenDim(5);
+ int rX1 = dm->sx << 3;
+ int rY1 = dm->sy;
+ int rX2 = rX1 + (dm->w << 3);
+ int rY2 = rY1 + dm->h - 1;
+
+ int16 gx2 = _gfxX;
+ int16 gy2 = _gfxY;
+
+ int16 *ptr2 = (int16 *)_dsTempPage;
+ int16 *ptr3 = (int16 *)&_dsTempPage[300];
+ int16 *ptr4 = (int16 *)&_dsTempPage[600];
+ int16 *ptr5 = (int16 *)&_dsTempPage[900];
+ int16 *ptr6 = (int16 *)&_dsTempPage[1200];
+ int16 *ptr7 = (int16 *)&_dsTempPage[1500];
+ int16 *ptr8 = (int16 *)&_dsTempPage[1800];
+
+ if (numElements > 150)
+ numElements = 150;
+
+ for (int i = 0; i < numElements; i++) {
+ ptr2[i] = ptr3[i] = 0;
+ ptr4[i] = _vm->_rnd.getRandomNumberRng(0, radius) - (radius >> 1);
+ ptr5[i] = _vm->_rnd.getRandomNumberRng(0, radius) - (radius >> 1) - (radius >> (8 - aspectRatio));
+ ptr7[i] = _vm->_rnd.getRandomNumberRng(1024 / stepSize, 2048 / stepSize);
+ ptr8[i] = scale << 8;
+ }
+
+ for (int l = 2; l;) {
+ if (l != 2) {
+ for (int i = numElements - 1; i >= 0; i--) {
+ int16 px = ((ptr2[i] >> 6) >> scale) + gx2;
+ int16 py = ((ptr3[i] >> 6) >> scale) + gy2;
+ if (py > ymax)
+ py = ymax;
+ if (posWithinRect(px, py, rX1, rY1, rX2, rY2))
+ setPagePixel(0, px, py, ptr6[i]);
+ }
+ }
+
+ l = 0;
+
+ for (int i = 0; i < numElements; i++) {
+ uint32 end = _system->getMillis() + 1;
+ if (ptr4[i] <= 0)
+ ptr4[i]++;
+ else
+ ptr4[i]--;
+ ptr2[i] += ptr4[i];
+ ptr5[i] += 5;
+ ptr3[i] += ptr5[i];
+ ptr8[i] += ptr7[i];
+
+ int16 px = ((ptr2[i] >> 6) >> scale) + gx2;
+ int16 py = ((ptr3[i] >> 6) >> scale) + gy2;
+ if (py >= ymax || py < ymin)
+ ptr5[i] = -(ptr5[i] >> 1);
+ if (px >= xmax || px < xmin)
+ ptr4[i] = -(ptr4[i] >> 1);
+
+ if (py > ymax)
+ py = ymax;
+
+ int pxVal1 = 0;
+ if (posWithinRect(px, py, 0, 0, 319, 199)) {
+ pxVal1 = getPagePixel(2, px, py);
+ ptr6[i] = getPagePixel(0, px, py);
+ }
+
+ assert((ptr8[i] >> 8) < colorTableSize);
+ int pxVal2 = colorTable[ptr8[i] >> 8];
+ if (pxVal2) {
+ l = 1;
+ if (pxVal1 == _gfxCol && posWithinRect(px, py, rX1, rY1, rX2, rY2)) {
+ setPagePixel(0, px, py, pxVal2);
+ if (i % 5 == 0) {
+ updateScreen();
+ uint32 cur = _system->getMillis();
+ if (end > cur)
+ _system->delayMillis(end - cur);
+ }
+ }
+ } else {
+ ptr7[i] = 0;
+ }
+ }
+ }
+
+ showMouse();
+}
+
+void Screen_EoB::drawVortex(int numElements, int radius, int stepSize, int, int disorder, const uint8 *colorTable, int colorTableSize) {
+ int16 *xCoords = (int16 *)_dsTempPage;
+ int16 *yCoords = (int16 *)&_dsTempPage[300];
+ int16 *xMod = (int16 *)&_dsTempPage[600];
+ int16 *yMod = (int16 *)&_dsTempPage[900];
+ int16 *pixBackup = (int16 *)&_dsTempPage[1200];
+ int16 *colTableStep = (int16 *)&_dsTempPage[1500];
+ int16 *colTableIndex = (int16 *)&_dsTempPage[1800];
+ int16 *pixDelay = (int16 *)&_dsTempPage[2100];
+
+ hideMouse();
+ int cp = _curPage;
+
+ if (numElements > 150)
+ numElements = 150;
+
+ int cx = 88;
+ int cy = 48;
+ radius <<= 6;
+
+ for (int i = 0; i < numElements; i++) {
+ int16 v38 = _vm->_rnd.getRandomNumberRng(radius >> 2, radius);
+ int16 stepSum = 0;
+ int16 sqsum = 0;
+ while (sqsum < v38) {
+ stepSum += stepSize;
+ sqsum += stepSum;
+ }
+
+ switch (_vm->_rnd.getRandomNumber(255) & 3) {
+ case 0:
+ xCoords[i] = 32;
+ yCoords[i] = sqsum;
+ xMod[i] = stepSum;
+ yMod[i] = 0;
+ break;
+
+ case 1:
+ xCoords[i] = sqsum;
+ yCoords[i] = 32;
+ xMod[i] = 0;
+ yMod[i] = stepSum;
+ break;
+
+ case 2:
+ xCoords[i] = 32;
+ yCoords[i] = -sqsum;
+ xMod[i] = stepSum;
+ yMod[i] = 0;
+ break;
+
+ default:
+ xCoords[i] = -sqsum;
+ yCoords[i] = 32;
+ xMod[i] = 0;
+ yMod[i] = stepSum;
+ break;
+ }
+
+ if (_vm->_rnd.getRandomBit()) {
+ xMod[i] *= -1;
+ yMod[i] *= -1;
+ }
+
+ colTableStep[i] = _vm->_rnd.getRandomNumberRng(1024 / disorder, 2048 / disorder);
+ colTableIndex[i] = 0;
+ pixDelay[i] = _vm->_rnd.getRandomNumberRng(0, disorder >> 2);
+ }
+
+ int d = 0;
+ for (int i = 2; i;) {
+ if (i != 2) {
+ for (int ii = numElements - 1; ii >= 0; ii--) {
+ int16 px = CLIP((xCoords[ii] >> 6) + cx, 0, SCREEN_W - 1);
+ int16 py = CLIP((yCoords[ii] >> 6) + cy, 0, SCREEN_H - 1);
+ setPagePixel(0, px, py, pixBackup[ii]);
+ }
+ }
+
+ i = 0;
+ int r = (stepSize >> 1) + (stepSize >> 2) + (stepSize >> 3);
+ uint32 nextDelay = _system->getMillis() + 1;
+
+ for (int ii = 0; ii < numElements; ii++) {
+ if (pixDelay[ii] == 0) {
+ if (xCoords[ii] > 0) {
+ xMod[ii] -= ((xMod[ii] > 0) ? stepSize : r);
+ } else {
+ xMod[ii] += ((xMod[ii] < 0) ? stepSize : r);
+ }
+
+ if (yCoords[ii] > 0) {
+ yMod[ii] -= ((yMod[ii] > 0) ? stepSize : r);
+ } else {
+ yMod[ii] += ((yMod[ii] < 0) ? stepSize : r);
+ }
+
+ xCoords[ii] += xMod[ii];
+ yCoords[ii] += yMod[ii];
+ colTableIndex[ii] += colTableStep[ii];
+
+ } else {
+ pixDelay[ii]--;
+ }
+
+ int16 px = CLIP((xCoords[ii] >> 6) + cx, 0, SCREEN_W - 1);
+ int16 py = CLIP((yCoords[ii] >> 6) + cy, 0, SCREEN_H - 1);
+
+ uint8 tc1 = ((disorder >> 2) <= d) ? getPagePixel(2, px, py) : 0;
+ pixBackup[ii] = getPagePixel(0, px, py);
+ uint8 tblIndex = CLIP(colTableIndex[ii] >> 8, 0, colorTableSize - 1);
+ uint8 tc2 = colorTable[tblIndex];
+
+ if (tc2) {
+ i = 1;
+ if (tc1 == _gfxCol && !pixDelay[ii]) {
+ setPagePixel(0, px, py, tc2);
+ if (ii % 15 == 0) {
+ updateScreen();
+ uint32 cur = _system->getMillis();
+ if (nextDelay > cur)
+ _system->delayMillis(nextDelay - cur);
+ nextDelay += 1;
+ }
+ }
+ } else {
+ colTableStep[ii] = 0;
+ }
+ }
+ d++;
+ }
+
+ _curPage = cp;
+ showMouse();
+}
+
+void Screen_EoB::fadeTextColor(Palette *pal, int color1, int rate) {
+ uint8 *col = pal->getData();
+
+ for (bool loop = true; loop;) {
+ loop = true;
+ uint32 end = _system->getMillis() + _vm->tickLength();
+
+ loop = false;
+ for (int ii = 0; ii < 3; ii++) {
+ uint8 c = col[color1 * 3 + ii];
+ if (c > rate) {
+ col[color1 * 3 + ii] -= rate;
+ loop = true;
+ } else if (c) {
+ col[color1 * 3 + ii] = 0;
+ loop = true;
+ }
+ }
+
+ if (loop) {
+ setScreenPalette(*pal);
+ updateScreen();
+ uint32 cur = _system->getMillis();
+ if (end > cur)
+ _system->delayMillis(end - cur);
+ }
+ }
+}
+
+bool Screen_EoB::delayedFadePalStep(Palette *fadePal, Palette *destPal, int rate) {
+ bool res = false;
+
+ uint8 *s = fadePal->getData();
+ uint8 *d = destPal->getData();
+
+ for (int i = 0; i < 765; i++) {
+ int fadeVal = *s++;
+ int dstCur = *d;
+ int diff = ABS(fadeVal - dstCur);
+
+ if (diff == 0) {
+ d++;
+ continue;
+ }
+
+ res = true;
+ diff = MIN(diff, rate);
+
+ if (dstCur < fadeVal)
+ *d += diff;
+ else
+ *d -= diff;
+ d++;
+ }
+
+ return res;
+}
+
+int Screen_EoB::getRectSize(int w, int h) {
+ return w * h;
+}
+
+void Screen_EoB::setFadeTableIndex(int index) {
+ _fadeDataIndex = (CLIP(index, 0, 7) << 8);
+}
+
+void Screen_EoB::createFadeTable(uint8 *palData, uint8 *dst, uint8 rootColor, uint8 weight) {
+ if (!palData)
+ return;
+
+ uint8 *src = palData + 3 * rootColor;
+ uint8 r = *src++;
+ uint8 g = *src++;
+ uint8 b = *src;
+ uint8 tr, tg, tb;
+ src = palData + 3;
+
+ *dst++ = 0;
+ weight >>= 1;
+
+ for (uint8 i = 1; i; i++) {
+ uint16 tmp = (uint16)((*src - r) * weight) << 1;
+ tr = *src++ - ((tmp >> 8) & 0xff);
+ tmp = (uint16)((*src - g) * weight) << 1;
+ tg = *src++ - ((tmp >> 8) & 0xff);
+ tmp = (uint16)((*src - b) * weight) << 1;
+ tb = *src++ - ((tmp >> 8) & 0xff);
+
+ uint8 *d = palData + 3;
+ uint16 v = 0xffff;
+ uint8 col = rootColor;
+
+ for (uint8 ii = 1; ii; ii++) {
+ int a = *d++ - tr;
+ int t = a * a;
+ a = *d++ - tg;
+ t += (a * a);
+ a = *d++ - tb;
+ t += (a * a);
+
+ if (t <= v && (ii == rootColor || ii != i)) {
+ v = t;
+ col = ii ;
+ }
+ }
+ *dst++ = col;
+ }
+}
+
+uint8 *Screen_EoB::getFadeTable(int index) {
+ return (index >= 0 && index < 5) ? &_fadeData[index << 8] : 0;
+}
+
+const uint16 *Screen_EoB::getCGADitheringTable(int index) {
+ return !(index & ~1) ? _cgaDitheringTables[index] : 0;
+}
+
+const uint8 *Screen_EoB::getEGADitheringTable() {
+ return _egaDitheringTable;
+}
+
+void Screen_EoB::drawShapeSetPixel(uint8 *dst, uint8 col, uint16 pitch) {
+ if ((_renderMode != Common::kRenderCGA && _renderMode != Common::kRenderEGA) || _useHiResEGADithering) {
+ if (_shapeFadeMode[0]) {
+ if (_shapeFadeMode[1]) {
+ col = _useHiResEGADithering ? _egaPixelValueTable[(dst[0] << 4) | (dst[1] & 0x0f)] : *dst;
+ } else {
+ _shapeFadeInternal &= 7;
+ col = _useHiResEGADithering ? _egaPixelValueTable[(dst[_shapeFadeInternal] << 4) | (dst[_shapeFadeInternal + 1] & 0x0f)] : dst[_shapeFadeInternal];
+ _shapeFadeInternal++;
+ }
+ }
+
+ if (_shapeFadeMode[1]) {
+ uint8 cnt = _shapeFadeMode[1];
+ while (cnt--)
+ col = _fadeData[_fadeDataIndex + col];
+ }
+ }
+
+ if (_useHiResEGADithering) {
+ col = _egaDitheringTable[col];
+ dst[0] = dst[pitch] = col >> 4;
+ dst[1] = dst[pitch + 1] = col & 0x0f;
+ } else {
+ *dst = col;
+ }
+}
+
+void Screen_EoB::scaleShapeProcessLine2Bit(uint8 *&shpDst, const uint8 *&shpSrc, uint32 transOffsetDst, uint32 transOffsetSrc) {
+ for (int i = 0; i < _dsDiv; i++) {
+ shpDst[0] = (_cgaScaleTable[shpSrc[0]] << 2) | (shpSrc[1] >> 6);
+ shpDst[1] = ((shpSrc[1] & 0x0f) << 4) | ((shpSrc[2] >> 2) & 0x0f);
+ shpDst[transOffsetDst] = (_cgaScaleTable[shpSrc[transOffsetSrc]] << 2) | (shpSrc[transOffsetSrc + 1] >> 6);
+ shpDst[transOffsetDst + 1] = ((shpSrc[transOffsetSrc + 1] & 0x0f) << 4) | ((shpSrc[transOffsetSrc + 2] >> 2) & 0x0f);
+ shpSrc += 3;
+ shpDst += 2;
+ }
+
+ if (_dsRem == 1) {
+ shpDst[0] = _cgaScaleTable[shpSrc[0]] << 2;
+ shpDst[1] = 0;
+ shpDst[transOffsetDst] = (_cgaScaleTable[shpSrc[transOffsetSrc]] << 2) | 3;
+ shpDst[transOffsetDst + 1] = 0xff;
+ shpSrc++;
+ shpDst += 2;
+
+ } else if (_dsRem == 2) {
+ shpDst[0] = (_cgaScaleTable[shpSrc[0]] << 2) | (shpSrc[1] >> 6);
+ shpDst[1] = (shpSrc[1] & 0x3f) << 2;
+ shpDst[transOffsetDst] = (_cgaScaleTable[shpSrc[transOffsetSrc]] << 2) | (shpSrc[transOffsetSrc + 1] >> 6);
+ shpDst[transOffsetDst + 1] = ((shpSrc[transOffsetSrc + 1] & 0x3f) << 2) | 3;
+ shpSrc += 2;
+ shpDst += 2;
+ }
+}
+
+void Screen_EoB::scaleShapeProcessLine4Bit(uint8 *&dst, const uint8 *&src) {
+ for (int i = 0; i < _dsDiv; i++) {
+ *dst++ = *src++;
+ *dst++ = (READ_BE_UINT16(src) >> 4) & 0xff;
+ src += 2;
+ }
+
+ if (_dsRem == 1) {
+ *dst++ = *src++;
+ *dst++ = _dsScaleTrans;
+ } else if (_dsRem == 2) {
+ *dst++ = (src[0] & 0xf0) | (src[1] >> 4);
+ src += 2;
+ *dst++ = _dsScaleTrans;
+ *dst++ = _dsScaleTrans;
+ *dst++ = _dsScaleTrans;
+ }
+}
+
+bool Screen_EoB::posWithinRect(int posX, int posY, int x1, int y1, int x2, int y2) {
+ if (posX < x1 || posX > x2 || posY < y1 || posY > y2)
+ return false;
+ return true;
+}
+
+void Screen_EoB::generateEGADitheringTable(const Palette &pal) {
+ assert(_egaDitheringTable);
+ const uint8 *src = pal.getData();
+ uint8 *dst = _egaDitheringTable;
+
+ for (int i = 256; i; i--) {
+ int r = *src++;
+ int g = *src++;
+ int b = *src++;
+
+ uint8 col = 0;
+ uint16 min = 0x2E83;
+
+ for (int ii = 256; ii; ii--) {
+ const uint8 *palEntry = _egaMatchTable + (ii - 1) * 3;
+ if (*palEntry == 0xff)
+ continue;
+
+ int e_r = palEntry[0] - r;
+ int e_g = palEntry[1] - g;
+ int e_b = palEntry[2] - b;
+
+ uint16 s = (e_r * e_r) + (e_g * e_g) + (e_b * e_b);
+
+ if (s <= min) {
+ min = s;
+ col = ii - 1;
+ }
+ }
+ *dst++ = col;
+ }
+
+ memset(_egaPixelValueTable, 0, 256);
+ for (int i = 0; i < 256; i++)
+ _egaPixelValueTable[_egaDitheringTable[i]] = i;
+}
+
+void Screen_EoB::generateCGADitheringTables(const uint8 *mappingData) {
+ for (int i = 0; i < 256; i++) {
+ _cgaDitheringTables[0][i] = (mappingData[(i >> 4) + 16] << 8) | mappingData[i & 0x0f];
+ _cgaDitheringTables[1][i] = (mappingData[i >> 4] << 8) | mappingData[(i & 0x0f) + 16];
+ }
+}
+
+const uint8 Screen_EoB::_egaMatchTable[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x1E, 0x00, 0x00, 0x1E, 0x1E, 0x1E, 0x00, 0x00, 0x1E,
+ 0x00, 0x1E, 0x1E, 0x0F, 0x00, 0x1E, 0x1E, 0x1E, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x2D, 0x0F, 0x2D,
+ 0x0F, 0x0F, 0x2D, 0x2D, 0x2D, 0x0F, 0x0F, 0x2D, 0x0F, 0x2D, 0x2D, 0x2D, 0x0F, 0x2D, 0x2D, 0x2D,
+ 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x2A, 0x00, 0x1E, 0x1E, 0x00, 0x1E, 0x2A, 0x1E, 0x00, 0x1E, 0x1E,
+ 0x00, 0x2A, 0x1E, 0x0F, 0x1E, 0x1E, 0x1E, 0x2A, 0x0F, 0x0F, 0x21, 0x0F, 0x0F, 0x36, 0x0F, 0x2D,
+ 0x21, 0x0F, 0x2D, 0x36, 0x2D, 0x0F, 0x21, 0x2D, 0x0F, 0x36, 0x2D, 0x2D, 0x21, 0x2D, 0x2D, 0x36,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x2A, 0x00, 0x00, 0x2A, 0x1E, 0x1E, 0x1E, 0x00, 0x1E,
+ 0x1E, 0x1E, 0x1E, 0x21, 0x00, 0x1E, 0x2A, 0x1E, 0x0F, 0x21, 0x0F, 0x0F, 0x21, 0x2D, 0x0F, 0x36,
+ 0x0F, 0x0F, 0x36, 0x2D, 0x2D, 0x21, 0x0F, 0x2D, 0x21, 0x2D, 0x2D, 0x36, 0x0F, 0x2D, 0x36, 0x2D,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x2A, 0x2A, 0x1E, 0x1E, 0x1E, 0x1E,
+ 0x1E, 0x2A, 0x1E, 0x21, 0x1E, 0x1E, 0x2A, 0x2A, 0x0F, 0x21, 0x21, 0x0F, 0x21, 0x36, 0x0F, 0x36,
+ 0x21, 0x0F, 0x36, 0x36, 0x2D, 0x21, 0x21, 0x2D, 0x21, 0x36, 0x2D, 0x36, 0x21, 0x2D, 0x36, 0x36,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x2A, 0x00, 0x00, 0x2A,
+ 0x00, 0x1E, 0x2A, 0x0F, 0x00, 0x2A, 0x1E, 0x1E, 0x21, 0x0F, 0x0F, 0x21, 0x0F, 0x2D, 0x21, 0x2D,
+ 0x0F, 0x21, 0x2D, 0x2D, 0x36, 0x0F, 0x0F, 0x36, 0x0F, 0x2D, 0x36, 0x2D, 0x0F, 0x36, 0x2D, 0x2D,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x2A,
+ 0x00, 0x2A, 0x2A, 0x0F, 0x1E, 0x2A, 0x1E, 0x2A, 0x21, 0x0F, 0x21, 0x21, 0x0F, 0x36, 0x21, 0x2D,
+ 0x21, 0x21, 0x2D, 0x36, 0x36, 0x0F, 0x21, 0x36, 0x0F, 0x36, 0x36, 0x2D, 0x21, 0x36, 0x2D, 0x36,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0x2A, 0x15, 0x00, 0x2A, 0x21, 0x1E, 0x21, 0x15, 0x0F, 0x21, 0x15, 0x2D, 0x21, 0x2F,
+ 0x0F, 0x21, 0x2F, 0x2D, 0x36, 0x15, 0x0F, 0x36, 0x15, 0x2D, 0x36, 0x2F, 0x0F, 0x36, 0x2F, 0x2D,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x2A, 0x2A, 0x2A, 0x21, 0x21, 0x21, 0x21, 0x21, 0x36, 0x21, 0x36,
+ 0x21, 0x21, 0x36, 0x36, 0x36, 0x21, 0x21, 0x36, 0x21, 0x36, 0x36, 0x36, 0x21, 0x36, 0x36, 0x36,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x15, 0x15, 0x15, 0x15, 0x15, 0x2F, 0x15, 0x2F,
+ 0x15, 0x15, 0x2F, 0x2F, 0x2F, 0x15, 0x15, 0x2F, 0x15, 0x2F, 0x2F, 0x2F, 0x15, 0x2F, 0x2F, 0x2F,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x15, 0x15, 0x3F, 0x15, 0x2F,
+ 0x2F, 0x15, 0x2F, 0x3F, 0x2F, 0x15, 0x2F, 0x2F, 0x15, 0x3F, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F, 0x3F,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x15, 0x3F,
+ 0x15, 0x15, 0x3F, 0x2F, 0x2F, 0x2F, 0x15, 0x2F, 0x2F, 0x2F, 0x2F, 0x3F, 0x15, 0x2F, 0x3F, 0x2F,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0x15, 0x3F, 0x3F, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F, 0x3F, 0x2F, 0x3F, 0x2F, 0x2F, 0x3F, 0x3F,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0x15, 0x15, 0x3F, 0x15, 0x2F, 0x3F, 0x2F, 0x15, 0x3F, 0x2F, 0x2F,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0x15, 0x3F, 0x3F, 0x2F, 0x2F, 0x3F, 0x2F, 0x3F,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0x3F, 0x15, 0x3F, 0x3F, 0x2F,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0x3F, 0x3F
+};
+
+uint16 *OldDOSFont::_cgaDitheringTable = 0;
+int OldDOSFont::_numRef = 0;
+
+OldDOSFont::OldDOSFont(Common::RenderMode mode, bool useHiResEGADithering) : _renderMode(mode), _useHiResEGADithering(useHiResEGADithering) {
+ _data = 0;
+ _width = _height = _numGlyphs = 0;
+ _bitmapOffsets = 0;
+ _useLoResEGA = (_renderMode == Common::kRenderEGA && !_useHiResEGADithering);
+
+ _numRef++;
+ if (!_cgaDitheringTable && _numRef == 1) {
+ _cgaDitheringTable = new uint16[256];
+ memset(_cgaDitheringTable, 0, 256 * sizeof(uint16));
+ static const uint bits[] = { 0, 3, 12, 15 };
+ for (int i = 0; i < 256; i++)
+ _cgaDitheringTable[i] = (bits[i & 3] << 8) | (bits[(i >> 2) & 3] << 12) | (bits[(i >> 4) & 3] << 0) | (bits[(i >> 6) & 3] << 4);
+ }
+}
+
+OldDOSFont::~OldDOSFont() {
+ unload();
+
+ if (_numRef)
+ --_numRef;
+
+ if (_cgaDitheringTable && !_numRef) {
+ delete[] _cgaDitheringTable;
+ _cgaDitheringTable = 0;
+ }
+}
+
+bool OldDOSFont::load(Common::SeekableReadStream &file) {
+ unload();
+
+ _data = new uint8[file.size()];
+ assert(_data);
+
+ file.read(_data, file.size());
+ if (file.err())
+ return false;
+
+ if (file.size() - 2 != READ_LE_UINT16(_data))
+ return false;
+
+ _width = _data[0x103];
+ _height = _data[0x102];
+ _numGlyphs = 255;
+
+ _bitmapOffsets = (uint16 *)(_data + 2);
+
+ for (int i = 0; i < _numGlyphs; ++i)
+ _bitmapOffsets[i] = READ_LE_UINT16(&_bitmapOffsets[i]);
+
+ return true;
+}
+
+int OldDOSFont::getCharWidth(uint16 c) const {
+ if (c >= _numGlyphs)
+ return 0;
+ return _width;
+}
+
+void OldDOSFont::drawChar(uint16 c, byte *dst, int pitch) const {
+ static const uint8 renderMaskTable6[] = { 0xFC, 0x00, 0x7E, 0x00, 0x3F, 0x00, 0x1F, 0x80, 0x0F, 0xC0, 0x07, 0xE0, 0x03, 0xF0, 0x01, 0xF8 };
+ static const uint8 renderMaskTable8[] = { 0xFF, 0x00, 0x7F, 0x80, 0x3F, 0xC0, 0x1F, 0xE0, 0x0F, 0xF0, 0x07, 0xF8, 0x03, 0xFC, 0x01, 0xFE };
+
+ if (_width != 8 && _width != 6)
+ error("EOB font rendering not implemented for other font widths than 6 and 8.");
+
+ if (_width == 6) {
+ switch (c) {
+ case 0x81:
+ case 0x9a:
+ c = 0x5d;
+ break;
+ case 0x84:
+ case 0x8e:
+ c = 0x5b;
+ break;
+ case 0x94:
+ case 0x99:
+ c = 0x40;
+ case 0xe1:
+ // TODO: recheck this: no conversion for 'ß' ?
+ break;
+ }
+ } else if (_width == 8) {
+ switch (c) {
+ case 0x81:
+ case 0x9a:
+ case 0x5d:
+ c = 0x1d;
+ break;
+ case 0x84:
+ case 0x5b:
+ c = 0x1e;
+ break;
+ case 0x94:
+ case 0x40:
+ c = 0x1f;
+ break;
+ case 0x8e:
+ c = 0x1b;
+ break;
+ case 0x99:
+ c = 0x1c;
+ break;
+ case 0xe1:
+ c = 0x19;
+ break;
+ }
+ }
+
+ const uint8 *src = &_data[_bitmapOffsets[c]];
+ uint8 *dst2 = dst + pitch;
+
+ int w = (_width - 1) >> 3;
+ pitch -= _width;
+
+ if (_useHiResEGADithering)
+ pitch *= 2;
+
+ uint8 color1 = _colorMap[1];
+ uint8 color2 = _colorMap[0];
+
+ uint8 colEGA11 = _colorMap[3] >> 4;
+ uint8 colEGA12 = _colorMap[3] & 0x0f;
+ uint8 colEGA21 = _colorMap[2] >> 4;
+ uint8 colEGA22 = _colorMap[2] & 0x0f;
+
+ static const uint16 cgaColorMask[] = { 0, 0x5555, 0xAAAA, 0xFFFF };
+ uint16 cgaMask1 = cgaColorMask[color1 & 3];
+ uint16 cgaMask2 = cgaColorMask[color2 & 3];
+
+ if (_renderMode == Common::kRenderCGA || _useLoResEGA) {
+ color1 &= 0x0f;
+ color2 &= 0x0f;
+ }
+
+ int cH = _height;
+ while (cH--) {
+ int cW = w;
+ uint8 last = 0;
+ const uint8 *mtbl = _width == 8 ? renderMaskTable8 : renderMaskTable6;
+
+ if (_renderMode == Common::kRenderCGA) {
+ uint8 s = *src++;
+ uint8 m = *mtbl++;
+
+ uint8 in = s | last;
+ uint16 cmp1 = 0;
+ uint16 cmp2 = 0;
+
+ if (color1) {
+ in &= m;
+ cmp1 = _cgaDitheringTable[in];
+ }
+
+ if (color2) {
+ in = ~in & m;
+ cmp2 = _cgaDitheringTable[in];
+ }
+
+ uint16 cDst = 0;
+ uint8 sh = 6;
+ for (int i = 0; i < _width; i++) {
+ cDst |= ((dst[i] & 3) << sh);
+ sh = (sh - 2) & 0x0f;
+ }
+
+ uint16 out = (~(cmp1 | cmp2) & cDst) | (cmp1 & cgaMask1) | (cmp2 & cgaMask2);
+
+ sh = 6;
+ for (int i = 0; i < _width; i++) {
+ *dst++ = (out >> sh) & 3;
+ sh = (sh - 2) & 0x0f;
+ }
+
+ last = s;
+
+ } else {
+ for (bool runWidthLoop = true; runWidthLoop;) {
+ uint8 s = *src++;
+ uint8 m = *mtbl++;
+
+ for (uint8 i = 0x80; i; i >>= 1) {
+ if (!(m & i)) {
+ runWidthLoop = false;
+ break;
+ }
+
+ if (_useHiResEGADithering) {
+ if (s & i) {
+ if (color1) {
+ dst[0] = dst2[0] = colEGA11;
+ dst[1] = dst2[1] = colEGA12;
+ }
+ } else if (color2) {
+ dst[0] = dst2[0] = colEGA21;
+ dst[1] = dst2[1] = colEGA22;
+ }
+ dst += 2;
+ dst2 += 2;
+ } else {
+ if (s & i) {
+ if (color1)
+ *dst = color1;
+ } else if (color2) {
+ *dst = color2;
+ }
+ dst++;
+ }
+ }
+
+ if (cW)
+ cW--;
+ else
+ runWidthLoop = false;
+ }
+ }
+
+ dst += pitch;
+ dst2 += pitch;
+ }
+}
+
+void OldDOSFont::unload() {
+ delete[] _data;
+ _data = 0;
+ _width = _height = _numGlyphs = 0;
+ _bitmapOffsets = 0;
+}
+
+} // End of namespace Kyra
+
+#endif // ENABLE_EOB
diff --git a/engines/kyra/screen_eob.h b/engines/kyra/screen_eob.h
new file mode 100644
index 0000000000..fc40cfe903
--- /dev/null
+++ b/engines/kyra/screen_eob.h
@@ -0,0 +1,129 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef KYRA_SCREEN_EOB_H
+#define KYRA_SCREEN_EOB_H
+
+#ifdef ENABLE_EOB
+
+#include "kyra/screen.h"
+
+namespace Kyra {
+
+class EoBCoreEngine;
+class Screen_EoB : public Screen {
+public:
+ Screen_EoB(EoBCoreEngine *vm, OSystem *system);
+ virtual ~Screen_EoB();
+
+ bool init();
+
+ void setClearScreenDim(int dim);
+ void clearCurDim();
+
+ void setMouseCursor(int x, int y, const byte *shape);
+ void setMouseCursor(int x, int y, const byte *shape, const uint8 *ovl);
+
+ void loadFileDataToPage(Common::SeekableReadStream *s, int pageNum, uint32 size);
+
+ void printText(const char *str, int x, int y, uint8 color1, uint8 color2);
+ void printShadedText(const char *string, int x, int y, int col1, int col2);
+
+ void loadEoBBitmap(const char *file, const uint8 *cgaMapping, int tempPage, int destPage, int convertToPage);
+ void loadShapeSetBitmap(const char *file, int tempPage, int destPage);
+
+ void convertPage(int srcPage, int dstPage, const uint8 *cgaMapping);
+
+ void fillRect(int x1, int y1, int x2, int y2, uint8 color, int pageNum = -1, bool xored = false);
+ void drawLine(bool vertical, int x, int y, int length, int color);
+ uint8 getPagePixel(int pageNum, int x, int y);
+ void setPagePixel(int pageNum, int x, int y, uint8 color);
+
+ void setScreenPalette(const Palette &pal);
+ void getRealPalette(int num, uint8 *dst);
+
+ uint8 *encodeShape(uint16 x, uint16 y, uint16 w, uint16 h, bool encode8bit = false, const uint8 *cgaMapping = 0);
+ void drawShape(uint8 pageNum, const uint8 *shapeData, int x, int y, int sd = -1, int flags = 0, ...);
+ const uint8 *scaleShape(const uint8 *shapeData, int blockDistance);
+ const uint8 *scaleShapeStep(const uint8 *shp);
+ const uint8 *generateShapeOverlay(const uint8 *shp, int paletteOverlayIndex);
+
+ void setShapeFrame(int x1, int y1, int x2, int y2);
+ void setShapeFadeMode (uint8 i, bool b);
+
+ void setGfxParameters(int x, int y, int col);
+ void drawExplosion(int scale, int radius, int numElements, int stepSize, int aspectRatio, const uint8 *colorTable, int colorTableSize);
+ void drawVortex(int numElements, int radius, int stepSize, int, int disorder, const uint8 *colorTable, int colorTableSize);
+
+ void fadeTextColor(Palette *pal, int color1, int fadeTextColor);
+ bool delayedFadePalStep(Palette *fadePal, Palette *destPal, int rate);
+
+ void setTextColorMap(const uint8 *cmap) {}
+ int getRectSize(int w, int h);
+
+ void setFadeTableIndex(int index);
+ void createFadeTable(uint8 *palData, uint8 *dst, uint8 rootColor, uint8 weight);
+ uint8 *getFadeTable(int index);
+
+ const uint16 *getCGADitheringTable(int index);
+ const uint8 *getEGADitheringTable();
+
+private:
+ void drawShapeSetPixel(uint8 *dst, uint8 col, uint16 pitch);
+ void scaleShapeProcessLine2Bit(uint8 *&shpDst, const uint8 *&shpSrc, uint32 transOffsetDst, uint32 transOffsetSrc);
+ void scaleShapeProcessLine4Bit(uint8 *&dst, const uint8 *&src);
+ bool posWithinRect(int posX, int posY, int x1, int y1, int x2, int y2);
+
+ void generateEGADitheringTable(const Palette &pal);
+ void generateCGADitheringTables(const uint8 *mappingData);
+
+ int _dsDiv, _dsRem, _dsScaleTrans;
+ uint8 *_cgaScaleTable;
+ int16 _gfxX, _gfxY;
+ uint8 _gfxCol;
+ const uint8 *_gfxMaxY;
+
+ int16 _dsX1, _dsX2, _dsY1, _dsY2;
+ bool _shapeFadeMode[2];
+ uint16 _shapeFadeInternal;
+ uint8 *_fadeData;
+ int _fadeDataIndex;
+ uint8 _shapeOverlay[16];
+
+ uint8 *_dsTempPage;
+
+ uint16 *_cgaDitheringTables[2];
+ const uint8 *_cgaMappingDefault;
+
+ uint8 *_egaDitheringTable;
+ uint8 *_egaPixelValueTable;
+
+ static const uint8 _egaMatchTable[];
+ static const ScreenDim _screenDimTable[];
+ static const int _screenDimTableCount;
+};
+
+} // End of namespace Kyra
+
+#endif // ENABLE_EOB
+
+#endif
diff --git a/engines/kyra/screen_hof.cpp b/engines/kyra/screen_hof.cpp
index 24e0751c0e..ac6ee5eb77 100644
--- a/engines/kyra/screen_hof.cpp
+++ b/engines/kyra/screen_hof.cpp
@@ -26,17 +26,7 @@
namespace Kyra {
Screen_HoF::Screen_HoF(KyraEngine_HoF *vm, OSystem *system)
- : Screen_v2(vm, system), _vm(vm) {
-}
-
-void Screen_HoF::setScreenDim(int dim) {
- assert(dim < _screenDimTableCount);
- _curDim = &_screenDimTable[dim];
-}
-
-const ScreenDim *Screen_HoF::getScreenDim(int dim) {
- assert(dim < _screenDimTableCount);
- return &_screenDimTable[dim];
+ : Screen_v2(vm, system, _screenDimTable, _screenDimTableCount), _vm(vm) {
}
void Screen_HoF::generateGrayOverlay(const Palette &srcPal, uint8 *grayOverlay, int factor, int addR, int addG, int addB, int lastColor, bool flag) {
diff --git a/engines/kyra/screen_hof.h b/engines/kyra/screen_hof.h
index edcb339da9..51c6a001fa 100644
--- a/engines/kyra/screen_hof.h
+++ b/engines/kyra/screen_hof.h
@@ -34,10 +34,6 @@ friend class Debugger_v2;
public:
Screen_HoF(KyraEngine_HoF *vm, OSystem *system);
- void setScreenDim(int dim);
- const ScreenDim *getScreenDim(int dim);
- int screenDimTableCount() const { return _screenDimTableCount; }
-
// sequence player
void generateGrayOverlay(const Palette &pal, uint8 *grayOverlay, int factor, int addR, int addG, int addB, int lastColor, bool flag);
void cmpFadeFrameStep(int srcPage, int srcW, int srcH, int srcX, int srcY, int dstPage, int dstW, int dstH, int dstX, int dstY, int cmpW, int cmpH, int cmpPage);
diff --git a/engines/kyra/screen_lok.cpp b/engines/kyra/screen_lok.cpp
index 106ef5df29..f32a898dd9 100644
--- a/engines/kyra/screen_lok.cpp
+++ b/engines/kyra/screen_lok.cpp
@@ -30,7 +30,7 @@
namespace Kyra {
Screen_LoK::Screen_LoK(KyraEngine_LoK *vm, OSystem *system)
- : Screen(vm, system) {
+ : Screen(vm, system, _screenDimTable, _screenDimTableCount) {
_vm = vm;
_unkPtr1 = _unkPtr2 = 0;
_bitBlitNum = 0;
@@ -70,16 +70,6 @@ bool Screen_LoK::init() {
return true;
}
-void Screen_LoK::setScreenDim(int dim) {
- assert(dim < _screenDimTableCount);
- _curDim = &_screenDimTable[dim];
-}
-
-const ScreenDim *Screen_LoK::getScreenDim(int dim) {
- assert(dim < _screenDimTableCount);
- return &_screenDimTable[dim];
-}
-
void Screen_LoK::fadeSpecialPalette(int palIndex, int startIndex, int size, int fadeTime) {
if (_vm->gameFlags().platform == Common::kPlatformAmiga)
return;
@@ -90,7 +80,7 @@ void Screen_LoK::fadeSpecialPalette(int palIndex, int startIndex, int size, int
tempPal.copy(getPalette(0));
tempPal.copy(_vm->palTable1()[palIndex], 0, size, startIndex);
- fadePalette(tempPal, fadeTime*18);
+ fadePalette(tempPal, fadeTime * 18);
getPalette(0).copy(tempPal, startIndex, size);
setScreenPalette(getPalette(0));
@@ -118,16 +108,16 @@ void Screen_LoK::bitBlitRects() {
}
void Screen_LoK::savePageToDisk(const char *file, int page) {
- if (!_saveLoadPage[page/2]) {
- _saveLoadPage[page/2] = new uint8[SCREEN_W * SCREEN_H];
- assert(_saveLoadPage[page/2]);
+ if (!_saveLoadPage[page / 2]) {
+ _saveLoadPage[page / 2] = new uint8[SCREEN_W * SCREEN_H];
+ assert(_saveLoadPage[page / 2]);
}
- memcpy(_saveLoadPage[page/2], getPagePtr(page), SCREEN_W * SCREEN_H);
+ memcpy(_saveLoadPage[page / 2], getPagePtr(page), SCREEN_W * SCREEN_H);
if (_useOverlays) {
- if (!_saveLoadPageOvl[page/2]) {
- _saveLoadPageOvl[page/2] = new uint8[SCREEN_OVL_SJIS_SIZE];
- assert(_saveLoadPageOvl[page/2]);
+ if (!_saveLoadPageOvl[page / 2]) {
+ _saveLoadPageOvl[page / 2] = new uint8[SCREEN_OVL_SJIS_SIZE];
+ assert(_saveLoadPageOvl[page / 2]);
}
uint8 *srcPage = getOverlayPtr(page);
@@ -136,49 +126,49 @@ void Screen_LoK::savePageToDisk(const char *file, int page) {
return;
}
- memcpy(_saveLoadPageOvl[page/2], srcPage, SCREEN_OVL_SJIS_SIZE);
+ memcpy(_saveLoadPageOvl[page / 2], srcPage, SCREEN_OVL_SJIS_SIZE);
}
}
void Screen_LoK::loadPageFromDisk(const char *file, int page) {
- if (!_saveLoadPage[page/2]) {
+ if (!_saveLoadPage[page / 2]) {
warning("trying to restore page %d, but no backup found", page);
return;
}
- copyBlockToPage(page, 0, 0, SCREEN_W, SCREEN_H, _saveLoadPage[page/2]);
- delete[] _saveLoadPage[page/2];
- _saveLoadPage[page/2] = 0;
+ copyBlockToPage(page, 0, 0, SCREEN_W, SCREEN_H, _saveLoadPage[page / 2]);
+ delete[] _saveLoadPage[page / 2];
+ _saveLoadPage[page / 2] = 0;
- if (_saveLoadPageOvl[page/2]) {
+ if (_saveLoadPageOvl[page / 2]) {
uint8 *dstPage = getOverlayPtr(page);
if (!dstPage) {
warning("trying to restore unsupported overlay page %d", page);
return;
}
- memcpy(dstPage, _saveLoadPageOvl[page/2], SCREEN_OVL_SJIS_SIZE);
- delete[] _saveLoadPageOvl[page/2];
- _saveLoadPageOvl[page/2] = 0;
+ memcpy(dstPage, _saveLoadPageOvl[page / 2], SCREEN_OVL_SJIS_SIZE);
+ delete[] _saveLoadPageOvl[page / 2];
+ _saveLoadPageOvl[page / 2] = 0;
}
}
void Screen_LoK::queryPageFromDisk(const char *file, int page, uint8 *buffer) {
- if (!_saveLoadPage[page/2]) {
+ if (!_saveLoadPage[page / 2]) {
warning("trying to query page %d, but no backup found", page);
return;
}
- memcpy(buffer, _saveLoadPage[page/2], SCREEN_W*SCREEN_H);
+ memcpy(buffer, _saveLoadPage[page / 2], SCREEN_W * SCREEN_H);
}
void Screen_LoK::deletePageFromDisk(int page) {
- delete[] _saveLoadPage[page/2];
- _saveLoadPage[page/2] = 0;
+ delete[] _saveLoadPage[page / 2];
+ _saveLoadPage[page / 2] = 0;
- if (_saveLoadPageOvl[page/2]) {
- delete[] _saveLoadPageOvl[page/2];
- _saveLoadPageOvl[page/2] = 0;
+ if (_saveLoadPageOvl[page / 2]) {
+ delete[] _saveLoadPageOvl[page / 2];
+ _saveLoadPageOvl[page / 2] = 0;
}
}
@@ -204,16 +194,16 @@ void Screen_LoK::copyBackgroundBlock(int x, int page, int flag) {
copyRegionToBuffer(_curPage, 8, 8, 8, height, ptr2);
for (int i = 0; i < 19; ++i) {
int tempX = curX + 1;
- copyRegionToBuffer(_curPage, tempX<<3, 8, 8, height, ptr1);
- copyBlockToPage(_curPage, tempX<<3, 8, 8, height, ptr2);
+ copyRegionToBuffer(_curPage, tempX << 3, 8, 8, height, ptr1);
+ copyBlockToPage(_curPage, tempX << 3, 8, 8, height, ptr2);
int newXPos = curX + x;
if (newXPos > 37)
newXPos = newXPos % 38;
tempX = newXPos + 1;
- copyRegionToBuffer(_curPage, tempX<<3, 8, 8, height, ptr2);
- copyBlockToPage(_curPage, tempX<<3, 8, 8, height, ptr1);
- curX += x*2;
+ copyRegionToBuffer(_curPage, tempX << 3, 8, 8, height, ptr2);
+ copyBlockToPage(_curPage, tempX << 3, 8, 8, height, ptr1);
+ curX += x * 2;
if (curX > 37) {
curX = curX % 38;
}
@@ -241,7 +231,7 @@ int Screen_LoK::getRectSize(int x, int y) {
else if (y > 200)
y = 200;
- return ((x*y) << 3);
+ return ((x * y) << 3);
}
void Screen_LoK::postProcessCursor(uint8 *data, int width, int height, int pitch) {
@@ -342,7 +332,7 @@ void Screen_LoK_16::getFadeParams(const Palette &pal, int delay, int &delayInc,
int Screen_LoK_16::fadePalStep(const Palette &pal, int diff) {
error("Screen_LoK_16::fadePalStep called");
- return 0; // for compilers that don't support NORETURN
+ return 0; // for compilers that don't support NORETURN
}
void Screen_LoK_16::paletteMap(uint8 idx, int r, int g, int b) {
diff --git a/engines/kyra/screen_lok.h b/engines/kyra/screen_lok.h
index 3b74912986..3cb92543e5 100644
--- a/engines/kyra/screen_lok.h
+++ b/engines/kyra/screen_lok.h
@@ -38,10 +38,6 @@ public:
int getRectSize(int w, int h);
- void setScreenDim(int dim);
- const ScreenDim *getScreenDim(int dim);
- int screenDimTableCount() const { return _screenDimTableCount; }
-
void setTextColorMap(const uint8 *cmap);
void fadeSpecialPalette(int palIndex, int startIndex, int size, int fadeTime);
diff --git a/engines/kyra/screen_lol.cpp b/engines/kyra/screen_lol.cpp
index 6d0460e0a1..08b232f400 100644
--- a/engines/kyra/screen_lol.cpp
+++ b/engines/kyra/screen_lol.cpp
@@ -31,7 +31,7 @@
namespace Kyra {
-Screen_LoL::Screen_LoL(LoLEngine *vm, OSystem *system) : Screen_v2(vm, system), _vm(vm) {
+Screen_LoL::Screen_LoL(LoLEngine *vm, OSystem *system) : Screen_v2(vm, system, vm->gameFlags().use16ColorMode ? _screenDimTable16C : _screenDimTable256C, _screenDimTableCount), _vm(vm) {
_paletteOverlay1 = new uint8[0x100];
_paletteOverlay2 = new uint8[0x100];
_grayOverlay = new uint8[0x100];
@@ -43,14 +43,9 @@ Screen_LoL::Screen_LoL(LoLEngine *vm, OSystem *system) : Screen_v2(vm, system),
_levelOverlays[i] = new uint8[256];
_fadeFlag = 2;
- _curDimIndex = 0;
}
Screen_LoL::~Screen_LoL() {
- for (int i = 0; i < _screenDimTableCount; i++)
- delete _customDimTable[i];
- delete[] _customDimTable;
-
for (int i = 0; i < 8; i++)
delete[] _levelOverlays[i];
@@ -59,39 +54,6 @@ Screen_LoL::~Screen_LoL() {
delete[] _grayOverlay;
}
-bool Screen_LoL::init() {
- if (Screen::init()) {
- _screenDimTable = _use16ColorMode ? _screenDimTable16C : _screenDimTable256C;
- _customDimTable = new ScreenDim*[_screenDimTableCount];
- memset(_customDimTable, 0, sizeof(ScreenDim *)* _screenDimTableCount);
- return true;
- }
- return false;
-}
-
-
-void Screen_LoL::setScreenDim(int dim) {
- assert(dim < _screenDimTableCount);
- _curDim = _customDimTable[dim] ? (const ScreenDim *)_customDimTable[dim] : &_screenDimTable[dim];
- _curDimIndex = dim;
-}
-
-const ScreenDim *Screen_LoL::getScreenDim(int dim) {
- assert(dim < _screenDimTableCount);
- return _customDimTable[dim] ? (const ScreenDim *)_customDimTable[dim] : &_screenDimTable[dim];
-}
-
-void Screen_LoL::modifyScreenDim(int dim, int x, int y, int w, int h) {
- delete _customDimTable[dim];
- _customDimTable[dim] = new ScreenDim;
- memcpy(_customDimTable[dim], &_screenDimTable[dim], sizeof(ScreenDim));
- _customDimTable[dim]->sx = x;
- _customDimTable[dim]->sy = y;
- _customDimTable[dim]->w = w;
- _customDimTable[dim]->h = h;
- setScreenDim(dim);
-}
-
void Screen_LoL::fprintString(const char *format, int x, int y, uint8 col1, uint8 col2, uint16 flags, ...) {
if (!format)
return;
@@ -142,8 +104,8 @@ void Screen_LoL::fprintStringIntro(const char *format, int x, int y, uint8 c1, u
x -= getTextWidth(buffer);
if ((flags & 0x00F0) == 0x20) {
- printText(buffer, x-1, y, c3, c2);
- printText(buffer, x, y+1, c3, c2);
+ printText(buffer, x - 1, y, c3, c2);
+ printText(buffer, x, y + 1, c3, c2);
}
printText(buffer, x, y, c1, c2);
diff --git a/engines/kyra/screen_lol.h b/engines/kyra/screen_lol.h
index 02b78606b9..3bba9f8b70 100644
--- a/engines/kyra/screen_lol.h
+++ b/engines/kyra/screen_lol.h
@@ -36,14 +36,6 @@ public:
Screen_LoL(LoLEngine *vm, OSystem *system);
~Screen_LoL();
- bool init();
-
- void setScreenDim(int dim);
- const ScreenDim *getScreenDim(int dim);
- int curDimIndex() const { return _curDimIndex; }
- void modifyScreenDim(int dim, int x, int y, int w, int h);
- int screenDimTableCount() const { return _screenDimTableCount; }
-
void fprintString(const char *format, int x, int y, uint8 col1, uint8 col2, uint16 flags, ...) GCC_PRINTF(2, 8);
void fprintStringIntro(const char *format, int x, int y, uint8 c1, uint8 c2, uint8 c3, uint16 flags, ...) GCC_PRINTF(2, 9);
@@ -99,14 +91,9 @@ public:
private:
LoLEngine *_vm;
- const ScreenDim *_screenDimTable;
- static const int _screenDimTableCount;
-
static const ScreenDim _screenDimTable256C[];
static const ScreenDim _screenDimTable16C[];
-
- ScreenDim **_customDimTable;
- int _curDimIndex;
+ static const int _screenDimTableCount;
uint8 *_levelOverlays[8];
diff --git a/engines/kyra/screen_mr.cpp b/engines/kyra/screen_mr.cpp
index 2687dc8041..337860db30 100644
--- a/engines/kyra/screen_mr.cpp
+++ b/engines/kyra/screen_mr.cpp
@@ -25,22 +25,13 @@
namespace Kyra {
-Screen_MR::Screen_MR(KyraEngine_MR *vm, OSystem *system) : Screen_v2(vm, system) {
+Screen_MR::Screen_MR(KyraEngine_MR *vm, OSystem *system)
+ : Screen_v2(vm, system, _screenDimTable, _screenDimTableCount) {
}
Screen_MR::~Screen_MR() {
}
-void Screen_MR::setScreenDim(int dim) {
- assert(dim < _screenDimTableCount);
- _curDim = &_screenDimTable[dim];
-}
-
-const ScreenDim *Screen_MR::getScreenDim(int dim) {
- assert(dim < _screenDimTableCount);
- return &_screenDimTable[dim];
-}
-
int Screen_MR::getLayer(int x, int y) {
if (x < 0)
x = 0;
diff --git a/engines/kyra/screen_mr.h b/engines/kyra/screen_mr.h
index 0cb3240954..e10afcc5d2 100644
--- a/engines/kyra/screen_mr.h
+++ b/engines/kyra/screen_mr.h
@@ -34,10 +34,6 @@ public:
Screen_MR(KyraEngine_MR *vm, OSystem *system);
~Screen_MR();
- void setScreenDim(int dim);
- const ScreenDim *getScreenDim(int dim);
- int screenDimTableCount() const { return _screenDimTableCount; }
-
int getLayer(int x, int y);
byte getShapeFlag1(int x, int y);
diff --git a/engines/kyra/screen_v2.cpp b/engines/kyra/screen_v2.cpp
index 57581fa750..dde22498eb 100644
--- a/engines/kyra/screen_v2.cpp
+++ b/engines/kyra/screen_v2.cpp
@@ -26,7 +26,8 @@
namespace Kyra {
-Screen_v2::Screen_v2(KyraEngine_v1 *vm, OSystem *system) : Screen(vm, system), _wsaFrameAnimBuffer(0) {
+Screen_v2::Screen_v2(KyraEngine_v1 *vm, OSystem *system, const ScreenDim *dimTable, const int dimTableSize)
+ : Screen(vm, system, dimTable, dimTableSize), _wsaFrameAnimBuffer(0) {
_wsaFrameAnimBuffer = new uint8[1024];
assert(_wsaFrameAnimBuffer);
}
@@ -186,7 +187,7 @@ uint8 *Screen_v2::getPtrToShape(uint8 *shpFile, int shape) {
int Screen_v2::getShapeScaledWidth(const uint8 *shpFile, int scale) {
if (!shpFile)
return 0;
- int width = READ_LE_UINT16(shpFile+3);
+ int width = READ_LE_UINT16(shpFile + 3);
return (width * scale) >> 8;
}
@@ -200,7 +201,7 @@ int Screen_v2::getShapeScaledHeight(const uint8 *shpFile, int scale) {
uint16 Screen_v2::getShapeSize(const uint8 *shp) {
if (!shp)
return 0;
- return READ_LE_UINT16(shp+6);
+ return READ_LE_UINT16(shp + 6);
}
uint8 *Screen_v2::makeShapeCopy(const uint8 *src, int index) {
@@ -241,7 +242,7 @@ int Screen_v2::getLayer(int x, int y) {
int Screen_v2::getRectSize(int w, int h) {
if (w > 320 || h > 200)
return 0;
- return w*h;
+ return w * h;
}
void Screen_v2::setTextColorMap(const uint8 *cmap) {
@@ -249,7 +250,7 @@ void Screen_v2::setTextColorMap(const uint8 *cmap) {
}
void Screen_v2::wsaFrameAnimationStep(int x1, int y1, int x2, int y2,
- int w1, int h1, int w2, int h2, int srcPage, int dstPage, int dim) {
+ int w1, int h1, int w2, int h2, int srcPage, int dstPage, int dim) {
if (!(w1 || h1 || w2 || h2))
return;
@@ -280,7 +281,7 @@ void Screen_v2::wsaFrameAnimationStep(int x1, int y1, int x2, int y2,
memcpy(dt, s, w2);
} else if (t > 0) {
if (w1 == 1) {
- memset(dt, *s, w2);
+ memset(dt, *s, w2);
} else {
t = ((((((w2 - w1 + 1) & 0xffff) << 8) / w1) + 0x100) & 0xffff) << 8;
int bp = 0;
@@ -352,7 +353,7 @@ bool Screen_v2::calcBounds(int w0, int h0, int &x1, int &y1, int &w1, int &h1, i
h1 = t;
y1 = 0;
}
- t = h0 - y1;
+ t = h0 - y1;
if (t < 1) {
w1 = h1 = -1;
} else {
diff --git a/engines/kyra/screen_v2.h b/engines/kyra/screen_v2.h
index d85c762038..f84c923128 100644
--- a/engines/kyra/screen_v2.h
+++ b/engines/kyra/screen_v2.h
@@ -30,7 +30,7 @@ namespace Kyra {
class Screen_v2 : public Screen {
public:
- Screen_v2(KyraEngine_v1 *vm, OSystem *system);
+ Screen_v2(KyraEngine_v1 *vm, OSystem *system, const ScreenDim *dimTable, const int dimTableSize);
~Screen_v2();
// screen page handling
diff --git a/engines/kyra/script.h b/engines/kyra/script.h
index 5bd75f7b80..ccbe733e4d 100644
--- a/engines/kyra/script.h
+++ b/engines/kyra/script.h
@@ -81,6 +81,23 @@ public:
// Both lead to some problems in our IFF parser, either reading after the end
// of file or producing a "Chunk overread" error message. To work around this
// we need to adjust the size field properly.
+
+ // Fix for certain Russian fan translations:
+ // Westwood's original code completely ignores the FORM chunk and its size
+ // setting. After opening a TIM or EMC file they just check whether the FORM
+ // chunk exists (as a kind of file type verification) and then immediately seek
+ // behind the FORM chunk.
+ // This means that their parser is immune to weird fan translation scripts
+ // where the file size doesn't match the form chunk size. In our implemetation
+ // this would produce "Chunk overread" errors.
+ // Westwood also always pads all chunk sizes to 2 byte alignment after reading
+ // them from the file (not with FORM though, since they completely ignore it).
+ // This seems to do the trick for our FORM chunk size issue with the Russian
+ // fan translations. Another method which I have tried and which seems to work
+ // well would be simply setting _formChunk.size to the file size (-12 for TIM).
+
+ _formChunk.size = (_formChunk.size + 1) & ~1;
+
if (_formType == MKTAG('E','M','C','2'))
_formChunk.size -= 8;
else if (_formType == MKTAG('A','V','F','S'))
diff --git a/engines/kyra/script_eob.cpp b/engines/kyra/script_eob.cpp
new file mode 100644
index 0000000000..c07c41f706
--- /dev/null
+++ b/engines/kyra/script_eob.cpp
@@ -0,0 +1,1611 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifdef ENABLE_EOB
+
+#include "kyra/eobcommon.h"
+#include "kyra/screen_eob.h"
+#include "kyra/script_eob.h"
+#include "kyra/resource.h"
+#include "kyra/sound.h"
+
+#include "common/system.h"
+
+namespace Kyra {
+
+void EoBCoreEngine::runLevelScript(int block, int flags) {
+ _inf->run(block, flags);
+}
+
+void EoBCoreEngine::setScriptFlags(uint32 flags) {
+ _inf->setFlags(flags);
+}
+
+void EoBCoreEngine::clearScriptFlags(uint32 flags) {
+ _inf->clearFlags(flags);
+}
+
+bool EoBCoreEngine::checkScriptFlags(uint32 flags) {
+ return _inf->checkFlags(flags);
+}
+
+const uint8 *EoBCoreEngine::initScriptTimers(const uint8 *pos) {
+ _scriptTimersCount = 0;
+
+ while (((int16)READ_LE_UINT16(pos)) != -1) {
+ _scriptTimers[_scriptTimersCount].func = READ_LE_UINT16(pos);
+ pos += 2;
+ uint16 ticks = READ_LE_UINT16(pos) * 18;
+ _scriptTimers[_scriptTimersCount].ticks = ticks;
+ pos += 2;
+ _scriptTimers[_scriptTimersCount++].next = _system->getMillis() + ticks * _tickLength;
+ }
+
+ return pos;
+}
+
+void EoBCoreEngine::updateScriptTimers() {
+ bool timerUpdate = false;
+ if ((_scriptTimersMode & 2) && _stepsUntilScriptCall && _stepCounter > _stepsUntilScriptCall) {
+ _inf->run(0, 0x20);
+ _stepCounter = 0;
+ timerUpdate = true;
+ }
+
+ if (_scriptTimersMode & 1) {
+ for (int i = 0; i < _scriptTimersCount; i++) {
+ if (_scriptTimers[i].next < _system->getMillis()) {
+ _inf->run(_scriptTimers[i].func, _flags.gameID == GI_EOB1 ? 0x20 : 0x80);
+ _scriptTimers[i].next = _system->getMillis() + _scriptTimers[i].ticks * _tickLength;
+ _sceneUpdateRequired = true;
+ timerUpdate = true;
+ }
+ }
+ }
+
+ if (timerUpdate)
+ updateScriptTimersExtra();
+}
+
+EoBInfProcessor::EoBInfProcessor(EoBCoreEngine *engine, Screen_EoB *screen) : _vm(engine), _screen(screen),
+ _commandMin(engine->game() == GI_EOB1 ? -27 : -31) {
+
+#define Opcode(x) _opcodes.push_back(new InfOpcode(new InfProc(this, &EoBInfProcessor::x), #x))
+#define OpcodeAlt(x) if (_vm->game() == GI_EOB1) { Opcode(x##_v1); } else { Opcode(x##_v2); }
+ Opcode(oeob_setWallType);
+ Opcode(oeob_toggleWallState);
+ Opcode(oeob_openDoor);
+ Opcode(oeob_closeDoor);
+ Opcode(oeob_replaceMonster);
+ Opcode(oeob_movePartyOrObject);
+ Opcode(oeob_moveInventoryItemToBlock);
+ OpcodeAlt(oeob_printMessage);
+ Opcode(oeob_setFlags);
+ Opcode(oeob_playSoundEffect);
+ Opcode(oeob_removeFlags);
+ Opcode(oeob_modifyCharacterHitPoints);
+ Opcode(oeob_calcAndInflictCharacterDamage);
+ Opcode(oeob_jump);
+ Opcode(oeob_end);
+ Opcode(oeob_returnFromSubroutine);
+ Opcode(oeob_callSubroutine);
+ OpcodeAlt(oeob_eval);
+ Opcode(oeob_deleteItem);
+ Opcode(oeob_loadNewLevelOrMonsters);
+ Opcode(oeob_increasePartyExperience);
+ OpcodeAlt(oeob_createItem);
+ Opcode(oeob_launchObject);
+ Opcode(oeob_changeDirection);
+ Opcode(oeob_identifyItems);
+ Opcode(oeob_sequence);
+ Opcode(oeob_delay);
+ Opcode(oeob_drawScene);
+ Opcode(oeob_dialogue);
+ Opcode(oeob_specialEvent);
+#undef Opcode
+#undef OpcodeAlt
+
+ _scriptData = 0;
+ _scriptSize = 0;
+
+ _abortScript = 0;
+ _abortAfterSubroutine = 0;
+ _dlgResult = 0;
+ _preventRest = 0;
+
+ _lastScriptFunc = 0;
+ _lastScriptFlags = 0;
+
+ _subroutineStack = new int8*[10];
+ memset(_subroutineStack, 0, 10 * sizeof(int8 *));
+ _subroutineStackPos = 0;
+
+ _flagTable = new uint32[18];
+ memset(_flagTable, 0, 18 * sizeof(uint32));
+
+ _stack = new int16[30];
+ memset(_stack, 0, 30 * sizeof(int16));
+ _stackIndex = 0;
+
+ _activeCharacter = -1;
+}
+
+EoBInfProcessor::~EoBInfProcessor() {
+ delete[] _subroutineStack;
+ delete[] _flagTable;
+ delete[] _stack;
+ delete[] _scriptData;
+
+ for (Common::Array<const InfOpcode *>::const_iterator a = _opcodes.begin(); a != _opcodes.end(); ++a)
+ delete *a;
+
+ _opcodes.clear();
+}
+
+void EoBInfProcessor::loadData(const uint8 *data, uint32 dataSize) {
+ delete[] _scriptData;
+ _scriptSize = dataSize;
+ _scriptData = new int8[_scriptSize];
+ memcpy(_scriptData, data, _scriptSize);
+}
+
+void EoBInfProcessor::run(int func, int flags) {
+ int o = _vm->_levelBlockProperties[func].assignedObjects;
+ if (!o)
+ return;
+
+ uint16 f = _vm->_levelBlockProperties[func].flags;
+
+ uint16 subFlags = ((f & 0xfff8) >> 3) | 0xe0;
+ if (!(flags & subFlags))
+ return;
+
+ _abortScript = 0;
+ _abortAfterSubroutine = 0;
+ _dlgResult = 0;
+ _activeCharacter = -1;
+
+ _lastScriptFunc = func;
+ _lastScriptFlags = flags;
+
+ int8 *pos = (int8 *)(_scriptData + o);
+
+ do {
+ int8 cmd = *pos++;
+ if (cmd <= _commandMin || cmd >= 0)
+ continue;
+ debugC(3, kDebugLevelScript, "[0x%.04X] EoBInfProcessor::%s()", (uint32)(pos - _scriptData), _opcodes[-(cmd + 1)]->desc.c_str());
+ pos += (*_opcodes[-(cmd + 1)]->proc)(pos);
+ } while (!_abortScript && !_abortAfterSubroutine);
+}
+
+void EoBInfProcessor::setFlags(uint32 flags) {
+ _flagTable[17] |= flags;
+}
+
+void EoBInfProcessor::clearFlags(uint32 flags) {
+ _flagTable[17] &= ~flags;
+}
+
+bool EoBInfProcessor::checkFlags(uint32 flags) const {
+ return ((_flagTable[17] & flags) == flags) ? true : false;
+}
+
+bool EoBInfProcessor::preventRest() const {
+ return _preventRest ? true : false;
+}
+
+void EoBInfProcessor::loadState(Common::SeekableSubReadStreamEndian &in, bool origFile) {
+ _preventRest = (_vm->game() == GI_EOB1 && origFile) ? 0 : in.readByte();
+ int numFlags = (_vm->game() == GI_EOB1 && origFile) ? 13 : 18;
+ for (int i = 0; i < numFlags; i++)
+ _flagTable[i] = in.readUint32();
+}
+
+void EoBInfProcessor::saveState(Common::OutSaveFile *out) {
+ out->writeByte(_preventRest);
+ for (int i = 0; i < 18; i++)
+ out->writeUint32BE(_flagTable[i]);
+}
+
+void EoBInfProcessor::reset() {
+ _preventRest = 0;
+ memset(_flagTable, 0, 18 * sizeof(uint32));
+}
+
+const char *EoBInfProcessor::getString(uint16 index) {
+ if (index == 0xffff)
+ return 0;
+
+ int8 *res = _scriptData + READ_LE_UINT16(_scriptData);
+
+ while (index) {
+ if (*res++)
+ continue;
+ index--;
+ }
+
+ return (const char *)res;
+}
+
+int EoBInfProcessor::oeob_setWallType(int8 *data) {
+ int8 *pos = data;
+
+ uint16 block = 0;
+ int8 dir = 0;
+
+ switch (*pos++) {
+ case -23:
+ block = READ_LE_UINT16(pos);
+ pos += 2;
+ dir = *pos++;
+ _vm->_levelBlockProperties[block].walls[dir] = *pos++;
+ _vm->checkSceneUpdateNeed(block);
+ break;
+
+ case -19:
+ _vm->_currentDirection = *pos++;
+ break;
+
+ case -9:
+ block = READ_LE_UINT16(pos);
+ pos += 2;
+ dir = *pos++;
+ memset(_vm->_levelBlockProperties[block].walls, dir, 4 * sizeof(uint8));
+ _vm->checkSceneUpdateNeed(block);
+ break;
+
+ default:
+ break;
+ }
+
+ return pos - data;
+}
+
+int EoBInfProcessor::oeob_toggleWallState(int8 *data) {
+ int8 *pos = data;
+
+ uint16 block = 0;
+ int8 dir = 0;
+ uint8 a = 0;
+ uint8 b = 0;
+
+ switch (*pos++) {
+ case -23:
+ block = READ_LE_UINT16(pos);
+ pos += 2;
+ dir = *pos++;
+ a = (uint8)*pos++;
+ b = (uint8)*pos++;
+ a = (_vm->_levelBlockProperties[block].walls[dir] == a) ? b : a;
+ _vm->_levelBlockProperties[block].walls[dir] = a;
+ _vm->checkSceneUpdateNeed(block);
+ break;
+
+ case -22:
+ _vm->processDoorSwitch(READ_LE_UINT16(pos), 0);
+ pos += 2;
+ break;
+
+ case -9:
+ block = READ_LE_UINT16(pos);
+ pos += 2;
+ a = (uint8)*pos++;
+ b = (uint8)*pos++;
+ a = (_vm->_levelBlockProperties[block].walls[dir] == a) ? b : a;
+ memset(_vm->_levelBlockProperties[block].walls, a, 4 * sizeof(uint8));
+ _vm->checkSceneUpdateNeed(block);
+ break;
+
+ default:
+ break;
+ }
+
+ return pos - data;
+}
+
+int EoBInfProcessor::oeob_openDoor(int8 *data) {
+ int8 *pos = data;
+ _vm->openDoor(READ_LE_UINT16(pos));
+ pos += 2;
+ return pos - data;
+}
+
+int EoBInfProcessor::oeob_closeDoor(int8 *data) {
+ int8 *pos = data;
+ _vm->closeDoor(READ_LE_UINT16(pos));
+ pos += 2;
+ return pos - data;
+}
+
+int EoBInfProcessor::oeob_replaceMonster(int8 *data) {
+ int8 *pos = data;
+ _vm->replaceMonster(pos[1], READ_LE_UINT16(pos + 2), pos[4], pos[5], pos[6], pos[7], pos[8], pos[9], READ_LE_UINT16(pos + 10), READ_LE_UINT16(pos + 12));
+ pos += 14;
+ return pos - data;
+}
+
+int EoBInfProcessor::oeob_movePartyOrObject(int8 *data) {
+ int8 *pos = data;
+
+ int8 a = *pos++;
+ uint16 b = 0xffff;
+ uint16 c = 0;
+ uint16 d = 0;
+
+ if (_vm->game() == GI_EOB2 && a == -31) {
+ b = READ_LE_UINT16(pos);
+ pos += 2;
+ }
+
+ if (_vm->game() == GI_EOB1) {
+ if (a != -15) {
+ c = READ_LE_UINT16(pos);
+ pos += 2;
+ }
+ d = READ_LE_UINT16(pos);
+ pos += 2;
+ }
+
+ if (_vm->game() == GI_EOB2 && a != -31 && a != -11) {
+ c = READ_LE_UINT16(pos);
+ pos += 2;
+ d = READ_LE_UINT16(pos);
+ pos += 2;
+ }
+
+ if (a == -13) {
+ // move monster from block c to block d
+ for (int i = 0; i < 30; i++) {
+ if (_vm->_monsters[i].block != c)
+ continue;
+ _vm->placeMonster(&_vm->_monsters[i], d, _vm->_monsters[i].pos);
+ }
+ debugC(5, kDebugLevelScript, " - move monsters on block '0x%.04X' to block '0x%.04X'", c, d);
+
+ } else if (a == -24) {
+ // move party to block d
+ int ba = _dlgResult;
+ int bb = _lastScriptFunc;
+ int bc = _lastScriptFlags;
+ int bd = _abortScript;
+ int be = _activeCharacter;
+ int bf = _subroutineStackPos;
+
+ _vm->moveParty(d);
+ debugC(5, kDebugLevelScript, " - move party to block '0x%.04X'", d);
+
+ _dlgResult = ba;
+ _lastScriptFunc = bb;
+ _lastScriptFlags = bc;
+ _abortScript = bd;
+ _activeCharacter = be;
+ if (!_abortAfterSubroutine)
+ _subroutineStackPos = bf;
+ _vm->_sceneDefaultUpdate = 0;
+
+ } else if ((a == -31 && _vm->game() == GI_EOB2) || a == -11) {
+ // move item
+ int8 e = _vm->_currentLevel;
+ int8 f = _vm->_currentLevel;
+
+ if (_vm->game() == GI_EOB2) {
+ e = (*pos++ == -21) ? _vm->_currentLevel : *pos++;
+ c = READ_LE_UINT16(pos);
+ pos += 2;
+ f = (*pos++ == -21) ? _vm->_currentLevel : *pos++;
+ d = READ_LE_UINT16(pos);
+ pos += 2;
+ }
+
+ if (e == _vm->_currentLevel) {
+ int i = _vm->countQueuedItems(_vm->_levelBlockProperties[c].drawObjects, -1, (int16)b, 0, 1);
+ while (i) {
+ int p = _vm->_items[i].pos;
+ _vm->getQueuedItem((Item *)&_vm->_levelBlockProperties[c].drawObjects, 0, i);
+ if (_vm->_currentLevel == f) {
+ _vm->setItemPosition((Item *)&_vm->_levelBlockProperties[d].drawObjects, d, i, p);
+ } else {
+ _vm->_items[i].level = f;
+ _vm->_items[i].block = d;
+ if (p < 8)
+ _vm->_items[i].pos = p & 3;
+ }
+ i = _vm->countQueuedItems(_vm->_levelBlockProperties[c].drawObjects, -1, (int16)b, 0, 1);
+ }
+
+ for (i = 0; i < 10; i++) {
+ if (_vm->_flyingObjects[i].enable != 1 || _vm->_flyingObjects[i].curBlock != c)
+ continue;
+ if (f == _vm->_currentLevel || _vm->game() == GI_EOB1)
+ _vm->_flyingObjects[i].curBlock = d;
+ else
+ _vm->_flyingObjects[i].enable = 0;
+ }
+
+ } else {
+ for (int i = 0; i < 600; i++) {
+ if (_vm->_items[i].level != e || _vm->_items[i].block != c)
+ continue;
+ _vm->_items[i].level = f;
+ _vm->_items[i].block = d;
+ }
+ }
+ debugC(5, kDebugLevelScript, " - move items from level '%d', block '0x%.04X' to level '%d', block '0x%.04X'", c, e, d, f);
+ }
+
+ _vm->_sceneUpdateRequired = true;
+ return pos - data;
+}
+
+int EoBInfProcessor::oeob_moveInventoryItemToBlock(int8 *data) {
+ int8 *pos = data;
+ int8 c = *pos++;
+ uint16 block = READ_LE_UINT16(pos);
+ pos += 2;
+ int8 p = *pos++;
+
+ if (c == -1)
+ c = _vm->rollDice(1, 6, -1);
+
+ while (!(_vm->_characters[c].flags & 1)) {
+ if (++c == 5)
+ c = 0;
+ }
+
+ if (_vm->_currentControlMode && (_vm->_updateCharNum == c))
+ return pos - data;
+
+ int slot = _vm->rollDice(1, 27, 0);
+ int itm = 0;
+ int i = 0;
+
+ for (; i < 27; i++) {
+ if ((!_vm->_currentControlMode && slot > 1) || slot == 16)
+ continue;
+
+ itm = _vm->_characters[c].inventory[slot];
+
+ if (!itm)
+ continue;
+
+ if (_vm->_dscItemShapeMap[_vm->_items[itm].icon] >= 15)
+ break;
+
+ if (++slot == 27)
+ slot = 0;
+ }
+
+ if (i < 27 && itm) {
+ _vm->_characters[c].inventory[slot] = 0;
+ _vm->setItemPosition((Item *)&_vm->_levelBlockProperties[block].drawObjects, block, itm, p);
+ }
+
+ return pos - data;
+}
+
+int EoBInfProcessor::oeob_printMessage_v1(int8 *data) {
+ static const char colorConfig[] = "\x6\x21\x2\x21";
+ char col[5];
+ int8 *pos = data;
+
+ strcpy(col, colorConfig);
+ const char *str = (const char *)pos;
+ pos += (strlen(str) + 1);
+
+ col[1] = *pos++;
+ col[3] = *pos++;
+ _vm->txt()->printMessage(col);
+ _vm->txt()->printMessage(str);
+
+ col[1] = _screen->_curDim->unk8;
+ col[3] = _screen->_curDim->unkA;
+ _vm->txt()->printMessage(col);
+ _vm->txt()->printMessage("\r");
+
+ return pos - data;
+}
+
+int EoBInfProcessor::oeob_printMessage_v2(int8 *data) {
+ int8 *pos = data;
+ uint16 str = READ_LE_UINT16(pos);
+ pos += 2;
+ uint8 col = (uint8)*pos;
+ pos += 2;
+
+ int c = 0;
+ if (_activeCharacter == -1) {
+ c = _vm->rollDice(1, 6, -1);
+ while (!_vm->testCharacter(c, 3))
+ c = (c + 1) % 6;
+ } else {
+ c = _activeCharacter;
+ }
+
+ _vm->txt()->printMessage(getString(str), col, _vm->_characters[c].name);
+ _vm->txt()->printMessage("\r");
+
+ return pos - data;
+}
+
+int EoBInfProcessor::oeob_setFlags(int8 *data) {
+ int8 *pos = data;
+ int8 b = 0;
+
+ switch (*pos++) {
+ case -47:
+ _preventRest = 0;
+ debugC(5, kDebugLevelScript, " - set preventRest to 0");
+ break;
+
+ case -28:
+ _dlgResult = 1;
+ debugC(5, kDebugLevelScript, " - set dlgResult to 1");
+ break;
+
+ case -17:
+ _flagTable[_vm->_currentLevel] |= (1 << (*pos++));
+ debugC(5, kDebugLevelScript, " - set level flag '%d' for current level (current level = '%d')", *(pos - 1), _vm->_currentLevel);
+ break;
+
+ case -16:
+ _flagTable[17] |= (1 << (*pos++));
+ debugC(5, kDebugLevelScript, " - set global flag '%d'", *(pos - 1));
+ break;
+
+ case -13:
+ b = *pos++;
+ _vm->_monsters[b].flags |= (1 << (*pos++));
+ _vm->_monsters[b].mode = 0;
+ debugC(5, kDebugLevelScript, " - set monster flag '%d' for monster '%d'", *(pos - 1), b);
+ break;
+
+ default:
+ break;
+ }
+
+ return pos - data;
+}
+
+int EoBInfProcessor::oeob_playSoundEffect(int8 *data) {
+ int8 *pos = data;
+ uint16 block = READ_LE_UINT16(pos + 1);
+
+ if (block) {
+ _vm->snd_processEnvironmentalSoundEffect(pos[0], block);
+ } else {
+ _vm->snd_playSoundEffect(pos[0]);
+ }
+
+ pos += 3;
+ return pos - data;
+}
+
+int EoBInfProcessor::oeob_removeFlags(int8 *data) {
+ int8 *pos = data;
+ int8 a = *pos++;
+
+ switch (a) {
+ case -47:
+ _preventRest = 1;
+ debugC(5, kDebugLevelScript, " - set preventRest to 1");
+ break;
+
+ case -28:
+ _dlgResult = 0;
+ debugC(5, kDebugLevelScript, " - set dlgResult to 0");
+ break;
+
+ case -17:
+ _flagTable[_vm->_currentLevel] &= ~(1 << (*pos++));
+ debugC(5, kDebugLevelScript, " - clear level flag '%d' for current level (current level = '%d')", *(pos - 1), _vm->_currentLevel);
+ break;
+
+ case -16:
+ _flagTable[17] &= ~(1 << (*pos++));
+ debugC(5, kDebugLevelScript, " - clear global flag '%d'", *(pos - 1));
+ break;
+
+ default:
+ break;
+ }
+
+ return pos - data;
+}
+
+int EoBInfProcessor::oeob_modifyCharacterHitPoints(int8 *data) {
+ int8 *pos = data;
+ int8 c = *pos++;
+ int8 p = *pos++;
+
+ if (c == -1) {
+ for (c = 0; c < 6; c++)
+ _vm->modifyCharacterHitpoints(c, p);
+ } else {
+ _vm->modifyCharacterHitpoints(c, p);
+ }
+
+ return pos - data;
+}
+
+int EoBInfProcessor::oeob_calcAndInflictCharacterDamage(int8 *data) {
+ int8 *pos = data;
+ int charIndex = *pos++;
+ int times = *pos++;
+ int itemOrPips = *pos++;
+ int useStrModifierOrBase = *pos++;
+
+ int flg = (charIndex == -1) ? 4 : 0;
+ int savingThrowType = 5;
+ int savingThrowEffect = 1;
+
+ if (_vm->game() == GI_EOB2) {
+ flg = *pos++;
+ savingThrowType = *pos++;
+ savingThrowEffect = *pos++;
+ } else if (!itemOrPips) {
+ useStrModifierOrBase = times;
+ times = 0;
+ }
+
+ if (charIndex == -1) {
+ for (int i = 0; i < 6; i++)
+ _vm->calcAndInflictCharacterDamage(i, times, itemOrPips, useStrModifierOrBase, flg, savingThrowType, savingThrowEffect);
+ } else {
+ _vm->calcAndInflictCharacterDamage(charIndex, times, itemOrPips, useStrModifierOrBase, flg, savingThrowType, savingThrowEffect);
+ }
+ return pos - data;
+}
+
+int EoBInfProcessor::oeob_jump(int8 *data) {
+ int8 *pos = data;
+ pos = _scriptData + READ_LE_UINT16(pos);
+ return pos - data;
+}
+
+int EoBInfProcessor::oeob_end(int8 *data) {
+ _abortScript = 1;
+ _subroutineStackPos = 0;
+ return 0;
+}
+
+int EoBInfProcessor::oeob_returnFromSubroutine(int8 *data) {
+ int8 *pos = data;
+
+ if (_subroutineStackPos)
+ pos = _subroutineStack[--_subroutineStackPos];
+ else
+ _abortScript = 1;
+
+ return pos - data;
+}
+
+int EoBInfProcessor::oeob_callSubroutine(int8 *data) {
+ int8 *pos = data;
+ uint16 offs = READ_LE_UINT16(pos);
+ assert(offs < _scriptSize);
+ pos += 2;
+
+ if (_subroutineStackPos < 10) {
+ _subroutineStack[_subroutineStackPos++] = pos;
+ pos = _scriptData + offs;
+ }
+
+ return pos - data;
+}
+
+int EoBInfProcessor::oeob_eval_v1(int8 *data) {
+ int8 *pos = data;
+ int8 cmd = *pos++;
+
+ int a = 0;
+ int b = 0;
+ int i = 0;
+ EoBItem *itm = &_vm->_items[_vm->_itemInHand];
+ Common::String tempString1;
+ Common::String tempString2;
+
+ while (cmd != -18) {
+ switch (cmd + 38) {
+ case 0:
+ a = 1;
+ for (i = 0; i < 6; i++) {
+ if (!(_vm->_characters[i].flags & 1))
+ continue;
+ if (_vm->_characters[i].effectFlags & 0x40)
+ continue;
+ a = 0;
+ break;
+ }
+ _stack[_stackIndex++] = a;
+ debugC(5, kDebugLevelScript, " - check if whole party is invisible - PUSH result: '%d'", a);
+ break;
+
+ case 1:
+ _stack[_stackIndex++] = _vm->rollDice(pos[0], pos[1], pos[2]);
+ debugC(9, kDebugLevelScript, " - throw dice(s): num = '%d', pips = '%d', offset = '%d' - PUSH result: '%d'", pos[0], pos[1], pos[2], _stack[_stackIndex - 1]);
+ pos += 3;
+ break;
+
+ case 2:
+ cmd = *pos++;
+ b = 0;
+ for (i = 0; i < 6; i++) {
+ if (!(_vm->_characters[i].flags & 1))
+ continue;
+ if (_vm->_classModifierFlags[_vm->_characters[i].cClass] & cmd) {
+ b = 1;
+ break;
+ }
+ }
+ _stack[_stackIndex++] = b;
+ debugC(5, kDebugLevelScript, " - check if character with class flags '0x%.02X' is present - PUSH result: '%d'", cmd, b);
+ break;
+
+ case 3:
+ cmd = *pos++;
+ b = 0;
+ for (i = 0; i < 6; i++) {
+ if (!(_vm->_characters[i].flags & 1))
+ continue;
+ if ((_vm->_characters[i].raceSex >> 1) == cmd) {
+ b = 1;
+ break;
+ }
+ }
+ _stack[_stackIndex++] = b;
+ debugC(5, kDebugLevelScript, " - check if character with race '%d' is present - PUSH result: '%d'", cmd, b);
+ break;
+
+ case 6:
+ _stack[_stackIndex++] = _lastScriptFlags;
+ debugC(5, kDebugLevelScript, " - get script execution flags - PUSH result: '%d'", _lastScriptFlags);
+ break;
+
+ case 13:
+ itm = &_vm->_items[_vm->_itemInHand];
+ switch (*pos++) {
+ case -31:
+ _stack[_stackIndex++] = itm->type;
+ debugC(5, kDebugLevelScript, " - get hand item type (hand item number = '%d') - PUSH result: '%d'", _vm->_itemInHand, itm->type);
+ break;
+
+ case -11:
+ _stack[_stackIndex++] = _vm->_itemInHand;
+ debugC(5, kDebugLevelScript, " - get hand item number - PUSH result: '%d'", _vm->_itemInHand);
+ break;
+
+ default:
+ _stack[_stackIndex++] = itm->value;
+ debugC(5, kDebugLevelScript, " - get hand item value (hand item number = '%d') - PUSH result: '%d'", _vm->_itemInHand, itm->value);
+ break;
+ }
+ break;
+
+ case 15:
+ _stack[_stackIndex++] = _vm->_levelBlockProperties[READ_LE_UINT16(pos + 1)].walls[pos[0]];
+ debugC(5, kDebugLevelScript, " - get wall index for block '0x%.04X', direction '%d' - PUSH result: '%d'", READ_LE_UINT16(pos + 1), pos[0], _stack[_stackIndex - 1]);
+ pos += 3;
+ break;
+
+ case 19:
+ _stack[_stackIndex++] = _vm->_currentDirection;
+ debugC(5, kDebugLevelScript, " - get current direction - PUSH result: '%d'", _vm->_currentDirection);
+ break;
+
+ case 21:
+ _stack[_stackIndex++] = (_flagTable[_vm->_currentLevel] & (1 << (*pos++))) ? 1 : 0;
+ debugC(5, kDebugLevelScript, " - test level flag '%d' (current level = '%d') - PUSH result: '%d'", *(pos - 1), _vm->_currentLevel, _stack[_stackIndex - 1]);
+ break;
+
+ case 22:
+ _stack[_stackIndex++] = (_flagTable[17] & (1 << (*pos++))) ? 1 : 0;
+ debugC(5, kDebugLevelScript, " - test global flag '%d' - PUSH result: '%d'", *(pos - 1), _stack[_stackIndex - 1]);
+ break;
+
+ case 23:
+ _stack[_stackIndex++] = (_vm->_currentBlock == READ_LE_UINT16(pos)) ? 1 : 0;
+ debugC(5, kDebugLevelScript, " - compare current block with block '0x%.04X' (current block = '0x%.04X') - PUSH result: '%d'", _vm->_currentBlock, READ_LE_UINT16(pos), _stack[_stackIndex - 1]);
+ pos += 2;
+ break;
+
+ case 24:
+ a = (int16)READ_LE_UINT16(pos);
+ pos += 2;
+ b = READ_LE_UINT16(pos);
+ pos += 2;
+ _stack[_stackIndex++] = _vm->countQueuedItems(_vm->_levelBlockProperties[b].drawObjects, a, -1, 0, 1);
+ debugC(5, kDebugLevelScript, " - find item number '%d' on block '0x%.04X' - PUSH result: '%d'", a, b, _stack[_stackIndex - 1]);
+ break;
+
+ case 25:
+ _stack[_stackIndex++] = (_vm->_levelBlockProperties[READ_LE_UINT16(pos)].flags & 1) ? 1 : 0;
+ debugC(5, kDebugLevelScript, " - test block flag '1' for block '0x%.04X' - PUSH result: '%d'", READ_LE_UINT16(pos), _stack[_stackIndex - 1]);
+ pos += 2;
+ break;
+
+ case 27:
+ b = *pos++;
+ i = READ_LE_UINT16(pos);
+ pos += 2;
+ _stack[_stackIndex++] = _vm->countQueuedItems(_vm->_levelBlockProperties[i].drawObjects, -1, b, 1, 1);
+ debugC(5, kDebugLevelScript, " - count items of type '%d' on block '0x%.04X' - PUSH result: '%d'", b, i, _stack[_stackIndex - 1]);
+ break;
+
+ case 29:
+ _stack[_stackIndex++] = _vm->_levelBlockProperties[READ_LE_UINT16(pos)].walls[0];
+ debugC(5, kDebugLevelScript, " - get wall index 0 for block '0x%.04X' - PUSH result: '%d'", READ_LE_UINT16(pos), _stack[_stackIndex - 1]);
+ pos += 2;
+ break;
+
+ case 30:
+ a = _stack[--_stackIndex];
+ b = _stack[--_stackIndex];
+ _stack[_stackIndex++] = (a || b) ? 1 : 0;
+ debugC(5, kDebugLevelScript, " - evaluate: POP('%d') || POP('%d') - PUSH result: '%d'", a, b, _stack[_stackIndex - 1]);
+ break;
+
+ case 31:
+ a = _stack[--_stackIndex];
+ b = _stack[--_stackIndex];
+ _stack[_stackIndex++] = (a && b) ? 1 : 0;
+ debugC(5, kDebugLevelScript, " - evaluate: POP('%d') && POP('%d') - PUSH result: '%d'", a, b, _stack[_stackIndex - 1]);
+ break;
+
+ case 32:
+ a = _stack[--_stackIndex];
+ b = _stack[--_stackIndex];
+ _stack[_stackIndex++] = (a <= b) ? 1 : 0;
+ debugC(5, kDebugLevelScript, " - evaluate: POP('%d') <= POP('%d') - PUSH result: '%d'", a, b, _stack[_stackIndex - 1]);
+ break;
+
+ case 33:
+ a = _stack[--_stackIndex];
+ b = _stack[--_stackIndex];
+ _stack[_stackIndex++] = (a < b) ? 1 : 0;
+ debugC(5, kDebugLevelScript, " - evaluate: POP('%d') < POP('%d') - PUSH result: '%d'", a, b, _stack[_stackIndex - 1]);
+ break;
+
+ case 34:
+ a = _stack[--_stackIndex];
+ b = _stack[--_stackIndex];
+ _stack[_stackIndex++] = (a >= b) ? 1 : 0;
+ debugC(5, kDebugLevelScript, " - evaluate: POP('%d') >= POP('%d') - PUSH result: '%d'", a, b, _stack[_stackIndex - 1]);
+ break;
+
+ case 35:
+ a = _stack[--_stackIndex];
+ b = _stack[--_stackIndex];
+ _stack[_stackIndex++] = (a > b) ? 1 : 0;
+ debugC(5, kDebugLevelScript, " - evaluate: POP('%d') > POP('%d') - PUSH result: '%d'", a, b, _stack[_stackIndex - 1]);
+ break;
+
+ case 36:
+ a = _stack[--_stackIndex];
+ b = _stack[--_stackIndex];
+ _stack[_stackIndex++] = (a != b) ? 1 : 0;
+ debugC(5, kDebugLevelScript, " - evaluate: POP('%d') != POP('%d') - PUSH result: '%d'", a, b, _stack[_stackIndex - 1]);
+ break;
+
+ case 37:
+ a = _stack[--_stackIndex];
+ b = _stack[--_stackIndex];
+ _stack[_stackIndex++] = (a == b) ? 1 : 0;
+ debugC(5, kDebugLevelScript, " - evaluate: POP('%d') == POP('%d') - PUSH result: '%d'", a, b, _stack[_stackIndex - 1]);
+ break;
+
+ default:
+ a = cmd;
+ if (a >= 0 && a < 128)
+ _stack[_stackIndex++] = a;
+ debugC(5, kDebugLevelScript, " - PUSH value: '%d'", a);
+ break;
+ }
+ cmd = *pos++;
+ }
+
+ cmd = _stack[--_stackIndex];
+ if (cmd)
+ pos += 2;
+ else
+ pos = _scriptData + READ_LE_UINT16(pos);
+ debugC(5, kDebugLevelScript, " - conditional jump depending on POP('%d')", cmd);
+
+ return pos - data;
+}
+
+int EoBInfProcessor::oeob_eval_v2(int8 *data) {
+ int8 *pos = data;
+ int8 cmd = *pos++;
+
+ int a = 0;
+ int b = 0;
+ int i = 0;
+ EoBItem *itm = (_vm->_itemInHand != -1) ? &_vm->_items[_vm->_itemInHand] : 0;
+ Common::String tempString1;
+ Common::String tempString2;
+
+ while (cmd != -18) {
+ switch (cmd + 50) {
+ case 0:
+ a = 0;
+ b = *pos++;
+
+ for (i = 0; i < 6; i++) {
+ if (!_vm->testCharacter(i, 5))
+ continue;
+
+ if (_vm->_characters[i].portrait != b) {
+ a = 1;
+ _activeCharacter = i;
+ break;
+ }
+ }
+
+ _stack[_stackIndex++] = a;
+ break;
+
+ case 4:
+ _stack[_stackIndex++] = (int16)READ_LE_UINT16(pos);
+ pos += 2;
+ break;
+
+ case 9:
+ switch (*pos++) {
+ case -36:
+ _stack[_stackIndex++] = _vm->_itemTypes[_vm->_items[_vm->_lastUsedItem].type].extraProperties & 0x7f;
+ break;
+ case -31:
+ _stack[_stackIndex++] = _vm->_items[_vm->_lastUsedItem].type;
+ break;
+ case -11:
+ _stack[_stackIndex++] = _vm->_lastUsedItem;
+ break;
+ case -10:
+ _stack[_stackIndex++] = _vm->_items[_vm->_lastUsedItem].value;
+ break;
+ default:
+ break;
+ }
+ break;
+
+ case 12:
+ a = 1;
+ for (i = 0; i < 6; i++) {
+ if (!(_vm->_characters[i].flags & 1))
+ continue;
+ if (_vm->_characters[i].effectFlags & 0x40)
+ continue;
+ a = 0;
+ break;
+ }
+ _stack[_stackIndex++] = a;
+ break;
+
+ case 13:
+ _stack[_stackIndex++] = _vm->rollDice(pos[0], pos[1], pos[2]);
+ pos += 3;
+ break;
+
+ case 14:
+ cmd = *pos++;
+ a = _vm->rollDice(1, 6);
+ b = 0;
+ for (i = 0; i < 6 && b == 0; i++) {
+ if (++a > 5)
+ a = 0;
+ if (_vm->testCharacter(a, 5)) {
+ if (_vm->_classModifierFlags[_vm->_characters[a].cClass] & cmd) {
+ _activeCharacter = a;
+ b = 1;
+ }
+ }
+ }
+ _stack[_stackIndex++] = b;
+ break;
+
+ case 15:
+ cmd = *pos++;
+ a = _vm->rollDice(1, 6);
+ b = 0;
+ for (i = 0; i < 6; i++) {
+ if (++a > 5)
+ a = 0;
+ if (_vm->testCharacter(a, 5)) {
+ if ((_vm->_characters[a].raceSex >> 1) == cmd) {
+ _activeCharacter = a;
+ b = 1;
+ }
+ }
+ }
+ _stack[_stackIndex++] = b;
+ break;
+
+ case 17:
+ _stack[_stackIndex++] = _vm->_activeSpell;
+ break;
+
+ case 18:
+ _stack[_stackIndex++] = _lastScriptFlags;
+ break;
+
+ case 22:
+ _stack[_stackIndex++] = _dlgResult;
+ break;
+
+ case 25:
+ itm = &_vm->_items[_vm->_itemInHand];
+
+ switch (*pos++) {
+ case -49:
+ a = *pos++;
+ tempString1 = _vm->_itemNames[itm->nameId];
+ tempString1.toUppercase();
+ tempString2 = (const char *)pos;
+ tempString2.toUppercase();
+ pos += a;
+ _stack[_stackIndex++] = tempString1.contains(tempString2) ? 1 : 0;
+ break;
+
+ case -48:
+ a = *pos++;
+ tempString1 = _vm->_itemNames[itm->nameUnid];
+ tempString1.toUppercase();
+ tempString2 = (const char *)pos;
+ tempString2.toUppercase();
+ pos += a;
+ _stack[_stackIndex++] = tempString1.contains(tempString2) ? 1 : 0;
+ break;
+
+ case -31:
+ _stack[_stackIndex++] = itm->type;
+ break;
+
+ case -11:
+ _stack[_stackIndex++] = _vm->_itemInHand;
+ break;
+
+ case -10:
+ _stack[_stackIndex++] = itm->value;
+ break;
+
+ default:
+ break;
+ }
+
+ break;
+
+ case 26:
+ a = 0;
+ for (i = 0; i < 6; i++) {
+ if (_vm->testCharacter(i, 0x0f))
+ a++;
+ }
+ _stack[_stackIndex++] = a;
+ break;
+
+ case 27:
+ _stack[_stackIndex++] = _vm->_levelBlockProperties[READ_LE_UINT16(pos + 1)].walls[pos[0]];
+ pos += 3;
+ break;
+
+ case 31:
+ _stack[_stackIndex++] = _vm->_currentDirection;
+ break;
+
+ case 33:
+ _stack[_stackIndex++] = (_flagTable[_vm->_currentLevel] & (1 << (*pos++))) ? 1 : 0;
+ break;
+
+ case 34:
+ _stack[_stackIndex++] = (_flagTable[17] & (1 << (*pos++))) ? 1 : 0;
+ break;
+
+ case 35:
+ if (*pos++ == -11) {
+ a = (int16)READ_LE_UINT16(pos);
+ pos += 2;
+ b = (int16)READ_LE_UINT16(pos);
+ pos += 2;
+ _stack[_stackIndex++] = _vm->countCharactersWithSpecificItems(a, b);
+ } else {
+ _stack[_stackIndex++] = (_vm->_currentBlock == READ_LE_UINT16(pos)) ? 1 : 0;
+ pos += 2;
+ }
+ break;
+
+ case 36:
+ a = (int16)READ_LE_UINT16(pos);
+ pos += 2;
+ b = READ_LE_UINT16(pos);
+ pos += 2;
+ _stack[_stackIndex++] = _vm->countQueuedItems(_vm->_levelBlockProperties[b].drawObjects, a, -1, 0, 0);
+ break;
+
+ case 37:
+ if (*pos++ == -1) {
+ _stack[_stackIndex++] = _vm->_levelBlockProperties[READ_LE_UINT16(pos)].flags & 7;
+ pos += 2;
+ } else {
+ do {
+ a += _vm->countSpecificMonsters(*pos++);
+ } while (*pos != -1);
+ pos++;
+ _stack[_stackIndex++] = a;
+ }
+ break;
+
+ case 39:
+ a = *pos++;
+ b = *pos++;
+ i = READ_LE_UINT16(pos);
+ pos += 2;
+ _stack[_stackIndex++] = _vm->countQueuedItems(_vm->_levelBlockProperties[i].drawObjects, -1, b, 1, a);
+ break;
+
+ case 41:
+ _stack[_stackIndex++] = _vm->_levelBlockProperties[READ_LE_UINT16(pos)].walls[0];
+ pos += 2;
+ break;
+
+ case 42:
+ a = _stack[--_stackIndex];
+ b = _stack[--_stackIndex];
+ _stack[_stackIndex++] = (a || b) ? 1 : 0;
+ break;
+
+ case 43:
+ a = _stack[--_stackIndex];
+ b = _stack[--_stackIndex];
+ _stack[_stackIndex++] = (a && b) ? 1 : 0;
+ break;
+
+ case 44:
+ a = _stack[--_stackIndex];
+ b = _stack[--_stackIndex];
+ _stack[_stackIndex++] = (a <= b) ? 1 : 0;
+ break;
+
+ case 45:
+ a = _stack[--_stackIndex];
+ b = _stack[--_stackIndex];
+ _stack[_stackIndex++] = (a < b) ? 1 : 0;
+ break;
+
+ case 46:
+ a = _stack[--_stackIndex];
+ b = _stack[--_stackIndex];
+ _stack[_stackIndex++] = (a >= b) ? 1 : 0;
+ break;
+
+ case 47:
+ a = _stack[--_stackIndex];
+ b = _stack[--_stackIndex];
+ _stack[_stackIndex++] = (a > b) ? 1 : 0;
+ break;
+
+ case 48:
+ a = _stack[--_stackIndex];
+ b = _stack[--_stackIndex];
+ _stack[_stackIndex++] = (a != b) ? 1 : 0;
+ break;
+
+ case 49:
+ a = _stack[--_stackIndex];
+ b = _stack[--_stackIndex];
+ _stack[_stackIndex++] = (a == b) ? 1 : 0;
+ break;
+
+ default:
+ break;
+ }
+ cmd = *pos++;
+ }
+
+ cmd = _stack[--_stackIndex];
+ if (cmd)
+ pos += 2;
+ else
+ pos = _scriptData + READ_LE_UINT16(pos);
+
+ return pos - data;
+}
+
+int EoBInfProcessor::oeob_deleteItem(int8 *data) {
+ int8 *pos = data;
+ int8 c = *pos++;
+
+ if (c == -1) {
+ _vm->deleteInventoryItem(0, -1);
+ debugC(5, kDebugLevelScript, " - delete hand item");
+ } else {
+ _vm->deleteBlockItem(READ_LE_UINT16(pos), (c == -2) ? -1 : c);
+ debugC(5, kDebugLevelScript, " - delete item(s) of type '%d' on block '0x%.04X'", (c == -2) ? -1 : c, READ_LE_UINT16(pos));
+ pos += 2;
+ }
+
+ return pos - data;
+}
+
+int EoBInfProcessor::oeob_loadNewLevelOrMonsters(int8 *data) {
+ int8 *pos = data;
+ _vm->gui_updateControls();
+
+ int8 cmd = *pos++;
+ int8 index = *pos++;
+ int res = 0;
+
+ if (cmd == -27 || _vm->game() == GI_EOB1) {
+ cmd = _vm->game() == GI_EOB2 ? *pos++ : 0;
+ _vm->_currentBlock = READ_LE_UINT16(pos);
+ pos += 2;
+ uint8 dir = (uint8)*pos++;
+
+ if (dir != 0xff)
+ _vm->_currentDirection = dir;
+
+ for (int i = 0; i < 30; i++)
+ _vm->_monsters[i].curAttackFrame = 0;
+
+ for (int i = 0; i < 10; i++) {
+ EoBFlyingObject *fo = &_vm->_flyingObjects[i];
+ if (fo->enable == 1) {
+ _vm->_items[fo->item].pos &= 3;
+ run(_vm->_items[fo->item].block, 4);
+ }
+ fo->enable = 0;
+ }
+
+ _vm->completeDoorOperations();
+
+ _vm->generateTempData();
+ _vm->txt()->removePageBreakFlag();
+ _screen->setScreenDim(7);
+
+ _vm->loadLevel(index, cmd);
+ debugC(5, kDebugLevelScript, " - entering level '%d', sub level '%d', start block '0x%.04X', start direction '%d'", index, cmd, _vm->_currentBlock, _vm->_currentDirection);
+
+ if (_vm->_dialogueField)
+ _vm->restoreAfterDialogueSequence();
+
+ _vm->moveParty(_vm->_currentBlock);
+
+ _abortScript = 1;
+ _abortAfterSubroutine = 1;
+ _vm->_sceneUpdateRequired = true;
+
+ _vm->gui_drawAllCharPortraitsWithStats();
+ _subroutineStackPos = 0;
+
+ } else {
+ cmd = *pos++;
+ _vm->releaseMonsterShapes(cmd * 18, 18);
+ _vm->loadMonsterShapes((const char *)pos, cmd * 18, true, index * 18);
+ debugC(5, kDebugLevelScript, " - loading monster shapes '%s', monster number '%d', encode type '%d'", (const char *)pos, cmd, index);
+ pos += 13;
+ _vm->gui_restorePlayField();
+ res = pos - data;
+ }
+
+ return res;
+}
+
+int EoBInfProcessor::oeob_increasePartyExperience(int8 *data) {
+ int8 *pos = data;
+ if (*pos++ == -30) {
+ _vm->increasePartyExperience((int16)READ_LE_UINT16(pos));
+ debugC(5, kDebugLevelScript, " - award '%d' experience points", READ_LE_UINT16(pos));
+ pos += 2;
+ }
+ return pos - data;
+}
+
+int EoBInfProcessor::oeob_createItem_v1(int8 *data) {
+ int8 *pos = data;
+ uint16 itm = _vm->duplicateItem(READ_LE_UINT16(pos));
+ pos += 2;
+ uint16 block = READ_LE_UINT16(pos);
+ pos += 2;
+ uint8 itmPos = *pos++;
+
+ if (itm) {
+ if (block == 0xffff && !_vm->_itemInHand) {
+ _vm->setHandItem(itm);
+ debugC(5, kDebugLevelScript, " - create hand item '%d'", itm);
+ } else if (block != 0xffff) {
+ _vm->setItemPosition((Item *)&_vm->_levelBlockProperties[block & 0x3ff].drawObjects, block, itm, itmPos);
+ debugC(5, kDebugLevelScript, " - create item '%d' on block '0x%.04X', position '%d'", itm, block, itmPos);
+ }
+ }
+
+ return pos - data;
+}
+
+int EoBInfProcessor::oeob_createItem_v2(int8 *data) {
+ static const uint8 _itemPos[] = { 0, 1, 2, 3, 1, 3, 0, 2, 3, 2, 1, 0, 2, 0, 3, 1 };
+ int8 *pos = data;
+
+ uint16 itm = _vm->duplicateItem(READ_LE_UINT16(pos));
+ pos += 2;
+ uint16 block = READ_LE_UINT16(pos);
+ pos += 2;
+ uint8 itmPos = *pos++;
+ uint8 flg = *pos++;
+
+ if (flg & 1)
+ _vm->_items[itm].value = *pos++;
+
+ if (flg & 2)
+ _vm->_items[itm].flags = *pos++;
+
+ if (flg & 4)
+ _vm->_items[itm].icon = *pos++;
+
+ if (!itm)
+ return pos - data;
+
+ if (block == 0xffff) {
+ if (!_vm->_itemInHand) {
+ _vm->setHandItem(itm);
+ debugC(5, kDebugLevelScript, " - create hand item '%d' (value '%d', flags '0x%X', icon number '%d')", itm, _vm->_items[itm].value, _vm->_items[itm].flags, _vm->_items[itm].icon);
+ } else {
+ _vm->setItemPosition((Item *)&_vm->_levelBlockProperties[_vm->_currentBlock & 0x3ff].drawObjects, _vm->_currentBlock, itm, _itemPos[_vm->rollDice(1, 2, -1)]);
+ debugC(5, kDebugLevelScript, " - create item '%d' (value '%d', flags '0x%X', icon number '%d') on current block", itm, _vm->_items[itm].value, _vm->_items[itm].flags, _vm->_items[itm].icon);
+ }
+ } else if (block == 0xfffe) {
+ _vm->setItemPosition((Item *)&_vm->_levelBlockProperties[_vm->_currentBlock & 0x3ff].drawObjects, _vm->_currentBlock, itm, _itemPos[(_vm->_currentDirection << 2) + _vm->rollDice(1, 2, -1)]);
+ debugC(5, kDebugLevelScript, " - create item '%d' (value '%d', flags '0x%X', icon number '%d') on current block", itm, _vm->_items[itm].value, _vm->_items[itm].flags, _vm->_items[itm].icon);
+ } else {
+ _vm->setItemPosition((Item *)&_vm->_levelBlockProperties[block & 0x3ff].drawObjects, block, itm, itmPos);
+ debugC(5, kDebugLevelScript, " - create item '%d' (value '%d', flags '0x%X', icon number '%d') on block '0x%.04X', position '%d'", itm, _vm->_items[itm].value, _vm->_items[itm].flags, _vm->_items[itm].icon, block, itmPos);
+ }
+
+ return pos - data;
+}
+
+int EoBInfProcessor::oeob_launchObject(int8 *data) {
+ static const uint8 startPos[] = { 2, 3, 0, 2, 1, 0, 3, 1 };
+
+ int8 *pos = data;
+ bool m = (*pos++ == -33);
+ int i = READ_LE_UINT16(pos);
+ pos += 2;
+ uint16 block = READ_LE_UINT16(pos);
+ pos += 2;
+ int dir = *pos++;
+ int dirOffs = *pos++;
+
+ if (m) {
+ uint8 openBookType = _vm->_openBookType;
+ _vm->_openBookType = 0;
+ _vm->launchMagicObject(-1, i, block, startPos[dir * 2 + dirOffs], dir);
+ _vm->_openBookType = openBookType;
+ } else {
+ Item itm = _vm->duplicateItem(i);
+ if (itm) {
+ if (!_vm->launchObject(-1, itm, block, startPos[dir * 2 + dirOffs], dir, _vm->_items[itm].type))
+ _vm->_items[itm].block = -1;
+ }
+ }
+
+ return pos - data;
+}
+
+int EoBInfProcessor::oeob_changeDirection(int8 *data) {
+ int8 *pos = data;
+
+ int8 cmd = *pos++;
+ int8 dir = *pos++;
+
+ if (cmd == -15) {
+ _vm->_currentDirection = (_vm->_currentDirection + dir) & 3;
+ //_vm->_keybControlUnk = -1;
+ _vm->_sceneUpdateRequired = true;
+
+ } else if (cmd == -11) {
+ for (int i = 0; i < 10; i++) {
+ if (_vm->_flyingObjects[i].enable)
+ _vm->_flyingObjects[i].direction = (_vm->_flyingObjects[i].direction + dir) & 3;
+ }
+ }
+
+ return pos - data;
+}
+
+int EoBInfProcessor::oeob_identifyItems(int8 *data) {
+ int8 *pos = data;
+ uint16 block = READ_LE_UINT16(pos);
+
+ if (block == _vm->_currentBlock) {
+ for (int i = 0; i < 6; i++) {
+ if (!(_vm->_characters[i].flags & 1))
+ continue;
+
+ for (int ii = 0; ii < 27; ii++) {
+ int inv = _vm->_characters[i].inventory[ii];
+ if (inv)
+ _vm->_items[inv].flags |= 0x40;
+ }
+
+ _vm->identifyQueuedItems(_vm->_characters[i].inventory[16]);
+ }
+ }
+
+ _vm->identifyQueuedItems(_vm->_levelBlockProperties[block].drawObjects);
+ return pos - data;
+}
+
+int EoBInfProcessor::oeob_sequence(int8 *data) {
+ int8 *pos = data;
+ _vm->_npcSequenceSub = -1;
+ _vm->txt()->setWaitButtonMode(0);
+ _vm->gui_updateControls();
+ _vm->drawScene(1);
+
+ int cmd = *pos++;
+
+ if (_vm->game() == GI_EOB1) {
+ if (cmd == 10)
+ cmd = -1;
+ else if (cmd == 9)
+ cmd = -3;
+ else if (cmd == 8)
+ cmd = -2;
+ }
+
+ switch (cmd) {
+ case -3:
+ _vm->seq_xdeath();
+ _vm->_runFlag = false;
+ _vm->_playFinale = true;
+ _abortScript = 1;
+ return 0;
+
+ case -2:
+ _vm->seq_portal();
+ break;
+
+ case -1:
+ _vm->_runFlag = _vm->checkPassword();
+ break;
+
+ default:
+ _vm->npcSequence(cmd);
+ break;
+ }
+ _vm->screen()->setScreenDim(7);
+ return pos - data;
+}
+
+int EoBInfProcessor::oeob_delay(int8 *data) {
+ int8 *pos = data;
+ _vm->delay(READ_LE_UINT16(pos) * _vm->tickLength());
+ pos += 2;
+ return pos - data;
+}
+
+int EoBInfProcessor::oeob_drawScene(int8 *data) {
+ _vm->drawScene(1);
+ return 0;
+}
+
+int EoBInfProcessor::oeob_dialogue(int8 *data) {
+ int8 *pos = data;
+
+ switch (*pos++) {
+ case -45:
+ _vm->drawSequenceBitmap((const char *)pos, pos[13], READ_LE_UINT16(pos + 14), READ_LE_UINT16(pos + 16), READ_LE_UINT16(pos + 18));
+ pos += 20;
+ break;
+
+ case -44:
+ _vm->restoreAfterDialogueSequence();
+ break;
+
+ case -43:
+ _vm->initDialogueSequence();
+ break;
+
+ case -42:
+ _vm->gui_drawDialogueBox();
+ break;
+
+ case -40:
+ _dlgResult = _vm->runDialogue(READ_LE_UINT16(pos), READ_LE_UINT16(pos + 6) == 0xffff ? 2 : 3, getString(READ_LE_UINT16(pos + 2)), getString(READ_LE_UINT16(pos + 4)), getString(READ_LE_UINT16(pos + 6)));
+ pos += 8;
+ break;
+
+ case -8:
+ _vm->txt()->printDialogueText(READ_LE_UINT16(pos), getString(READ_LE_UINT16(pos + 2)));
+ pos += 4;
+ break;
+
+ default:
+ break;
+ }
+
+ return pos - data;
+}
+
+int EoBInfProcessor::oeob_specialEvent(int8 *data) {
+ int8 *pos = data;
+ uint16 cmd = READ_LE_UINT16(pos);
+ pos += 2;
+
+ uint32 endTime = 0;
+ int i = 0;
+
+ switch (cmd) {
+ case 0:
+ _vm->drawScene(1);
+ _screen->_curPage = 2;
+ _screen->copyRegion(72, 0, 0, 0, 32, 120, 2, 12, Screen::CR_NO_P_CHECK);
+
+ for (; i < 4; i++) {
+ endTime = _vm->_system->getMillis() + _vm->_tickLength;
+ _vm->drawLightningColumn();
+ _screen->copyRegion(72, 0, 72, 0, 32, 120, 2, 0, Screen::CR_NO_P_CHECK);
+ _screen->updateScreen();
+ _screen->copyRegion(0, 0, 72, 0, 32, 120, 12, 2, Screen::CR_NO_P_CHECK);
+ _vm->delayUntil(endTime);
+ }
+
+ _screen->_curPage = 0;
+ _vm->_sceneUpdateRequired = true;
+ break;
+
+ case 1:
+ _dlgResult = _vm->charSelectDialogue();
+ break;
+
+ case 2:
+ _vm->characterLevelGain(_dlgResult);
+ break;
+
+ case 3:
+ _dlgResult = _vm->resurrectionSelectDialogue();
+ break;
+
+ case 4:
+ if (_vm->prepareForNewPartyMember(33, 5))
+ _vm->initNpc(4);
+ break;
+
+ case 5:
+ _vm->deletePartyItems(46, 5);
+ _vm->deletePartyItems(46, 6);
+ break;
+
+ case 6:
+ _vm->loadVcnData(0, 0);
+ break;
+
+ default:
+ break;
+ }
+
+ return pos - data;
+}
+
+} // End of namespace Kyra
+
+#endif // ENABLE_EOB
diff --git a/engines/kyra/script_eob.h b/engines/kyra/script_eob.h
new file mode 100644
index 0000000000..fc8b4cfc31
--- /dev/null
+++ b/engines/kyra/script_eob.h
@@ -0,0 +1,132 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ *
+ */
+
+#ifdef ENABLE_EOB
+
+#ifndef KYRA_SCRIPT_EOB_H
+#define KYRA_SCRIPT_EOB_H
+
+#include "common/func.h"
+#include "common/substream.h"
+#include "common/savefile.h"
+
+namespace Kyra {
+
+class KyraRpgEngine;
+
+class EoBInfProcessor {
+public:
+ EoBInfProcessor(EoBCoreEngine *engine, Screen_EoB *_screen);
+ ~EoBInfProcessor();
+
+ void loadData(const uint8 *data, uint32 dataSize);
+ void run(int func, int flags);
+
+ void setFlags(uint32 flags);
+ void clearFlags(uint32 flags);
+ bool checkFlags(uint32 flags) const;
+ bool preventRest() const;
+
+ void loadState(Common::SeekableSubReadStreamEndian &in, bool origFile = false);
+ void saveState(Common::OutSaveFile *out);
+ void reset();
+
+private:
+ const char *getString(uint16 index);
+
+ int oeob_setWallType(int8 *data);
+ int oeob_toggleWallState(int8 *data);
+ int oeob_openDoor(int8 *data);
+ int oeob_closeDoor(int8 *data);
+ int oeob_replaceMonster(int8 *data);
+ int oeob_movePartyOrObject(int8 *data);
+ int oeob_moveInventoryItemToBlock(int8 *data);
+ int oeob_printMessage_v1(int8 *data);
+ int oeob_printMessage_v2(int8 *data);
+ int oeob_setFlags(int8 *data);
+ int oeob_playSoundEffect(int8 *data);
+ int oeob_removeFlags(int8 *data);
+ int oeob_modifyCharacterHitPoints(int8 *data);
+ int oeob_calcAndInflictCharacterDamage(int8 *data);
+ int oeob_jump(int8 *data);
+ int oeob_end(int8 *data);
+ int oeob_returnFromSubroutine(int8 *data);
+ int oeob_callSubroutine(int8 *data);
+ int oeob_eval_v1(int8 *data);
+ int oeob_eval_v2(int8 *data);
+ int oeob_deleteItem(int8 *data);
+ int oeob_loadNewLevelOrMonsters(int8 *data);
+ int oeob_increasePartyExperience(int8 *data);
+ int oeob_createItem_v1(int8 *data);
+ int oeob_createItem_v2(int8 *data);
+ int oeob_launchObject(int8 *data);
+ int oeob_changeDirection(int8 *data);
+ int oeob_identifyItems(int8 *data);
+ int oeob_sequence(int8 *data);
+ int oeob_delay(int8 *data);
+ int oeob_drawScene(int8 *data);
+ int oeob_dialogue(int8 *data);
+ int oeob_specialEvent(int8 *data);
+
+ EoBCoreEngine *_vm;
+ Screen_EoB *_screen;
+
+ typedef Common::Functor1Mem<int8*, int, EoBInfProcessor> InfProc;
+ struct InfOpcode : private Common::NonCopyable {
+ InfOpcode(InfProc *p, const char *d) : proc(p), desc(d) {}
+ ~InfOpcode() { delete proc; }
+
+ InfProc *proc;
+ Common::String desc;
+ };
+ Common::Array<const InfOpcode *> _opcodes;
+
+ int8 *_scriptData;
+ uint16 _scriptSize;
+
+ uint8 _abortScript;
+ uint16 _abortAfterSubroutine;
+ int _dlgResult;
+ uint8 _preventRest;
+
+ uint16 _lastScriptFunc;
+ uint16 _lastScriptFlags;
+
+ int8 **_subroutineStack;
+ int _subroutineStackPos;
+
+ uint32 *_flagTable;
+
+ int16 *_stack;
+ int _stackIndex;
+
+ int8 _activeCharacter;
+
+ const int _commandMin;
+};
+
+} // End of namespace Kyra
+
+#endif
+
+#endif // ENABLE_EOB
diff --git a/engines/kyra/script_hof.cpp b/engines/kyra/script_hof.cpp
index 296cd4002b..b80b8105a1 100644
--- a/engines/kyra/script_hof.cpp
+++ b/engines/kyra/script_hof.cpp
@@ -1397,7 +1397,6 @@ int KyraEngine_HoF::o2_demoFinale(EMCState *script) {
_screen->copyRegion(0, 0, 0, 0, 320, 200, 2, 0);
_screen->_curPage = 0;
- _screen->setFont(Screen::FID_6_FNT);
int y = _lang == 1 ? 70 : 65;
for (int i = 0; i < 6; i++)
_text->printText(strings[i], _text->getCenterStringX(strings[i], 1, 319), y + i * 10, 255, 207, 0);
@@ -1406,7 +1405,7 @@ int KyraEngine_HoF::o2_demoFinale(EMCState *script) {
_screen->updateScreen();
_eventList.clear();
- while (!skipFlag())
+ while (!skipFlag() && !shouldQuit())
delay(10);
_sound->beginFadeOut();
diff --git a/engines/kyra/script_lok.cpp b/engines/kyra/script_lok.cpp
index 4d40971124..8342bccab6 100644
--- a/engines/kyra/script_lok.cpp
+++ b/engines/kyra/script_lok.cpp
@@ -326,7 +326,7 @@ int KyraEngine_LoK::o1_delaySecs(EMCState *script) {
} else {
debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_delaySecs(%p) (%d)", (const void *)script, stackPos(0));
if (stackPos(0) >= 0 && !skipFlag())
- delay(stackPos(0)*1000, true);
+ delay(stackPos(0) * 1000, true);
}
resetSkipFlag();
@@ -689,7 +689,7 @@ int KyraEngine_LoK::o1_displayWSASequentialFrames(EMCState *script) {
if (specialTime) {
uint32 voiceTime = snd_getVoicePlayTime();
if (voiceTime) {
- int displayFrames = ABS(endFrame-startFrame)+1;
+ int displayFrames = ABS(endFrame - startFrame) + 1;
displayFrames *= maxTime;
assert(displayFrames != 0);
@@ -720,14 +720,19 @@ int KyraEngine_LoK::o1_displayWSASequentialFrames(EMCState *script) {
if (maxTime - 1 <= 0)
maxTime = 1;
- // Workaround for bug #1498221 "KYRA1: Glitches when meeting Zanthia"
- // the original didn't do a forced screen update after displaying a wsa frame
- // while we have to do it, which make brandon disappear for a short moment,
- // what shouldn't happen. So we're not updating the screen for this special
- // case too.
- if (startFrame == 18 && endFrame == 18 && _currentRoom == 45) {
+ // WORKAROUND for bug #1498221 "KYRA1: Glitches when meeting Zanthia".
+ // The original did not do a forced screen update after displaying a WSA
+ // frame while we have to do it, which makes Brandon disappear for a short
+ // moment. That is not supposed to happen. So we're not updating the
+ // screen for this special case.
+ // This is only an issue for the CD version, but since the floppy version
+ // does not use the specified paramaeters like these, it is safe to enable
+ // it for all versions.
+ if (startFrame == 18 && endFrame == 18 && waitTime == 10 && wsaIndex == 0 && _currentRoom == 45) {
_movieObjects[wsaIndex]->displayFrame(18, 0, xpos, ypos, 0, 0, 0);
- delay(waitTime * _tickLength);
+ // We call delayMillis manually here to avoid the screen getting
+ // updated.
+ _system->delayMillis(waitTime * _tickLength);
return 0;
}
@@ -1085,7 +1090,7 @@ int KyraEngine_LoK::o1_sceneAnimationActive(EMCState *script) {
int KyraEngine_LoK::o1_setCharacterMovementDelay(EMCState *script) {
debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_setCharacterMovementDelay(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1));
- _timer->setDelay(stackPos(0)+5, stackPos(1));
+ _timer->setDelay(stackPos(0) + 5, stackPos(1));
return 0;
}
@@ -1124,7 +1129,7 @@ int KyraEngine_LoK::o1_findBrightestFireberry(EMCState *script) {
// return a glow value of "29" over here, when we are running a CD version.
if (_flags.isTalkie) {
if (_currentCharacter->sceneId == 133 || _currentCharacter->sceneId == 137 ||
- _currentCharacter->sceneId == 165 || _currentCharacter->sceneId == 173)
+ _currentCharacter->sceneId == 165 || _currentCharacter->sceneId == 173)
return 29;
}
@@ -1173,7 +1178,7 @@ int KyraEngine_LoK::o1_setFireberryGlowPalette(EMCState *script) {
case -1:
// The original seemed to draw some lines on page 2 here, which looks strange...
//if (!(_brandonStatusBit & 2))
- // warning("Unimplemented case for o1_setFireberryGlowPalette");
+ // warning("Unimplemented case for o1_setFireberryGlowPalette");
palIndex = 9;
break;
@@ -1190,7 +1195,7 @@ int KyraEngine_LoK::o1_setFireberryGlowPalette(EMCState *script) {
palIndex = 9;
break;
- case 28: case 29: default:
+ case 28: case 29: default:
palIndex = 6;
}
@@ -1227,8 +1232,8 @@ int KyraEngine_LoK::o1_setFireberryGlowPalette(EMCState *script) {
if (_brandonStatusBit & 2) {
if (_currentCharacter->sceneId != 133 && _currentCharacter->sceneId != 137 &&
- _currentCharacter->sceneId != 165 && _currentCharacter->sceneId != 173 &&
- (_currentCharacter->sceneId < 187 || _currentCharacter->sceneId > 198)) {
+ _currentCharacter->sceneId != 165 && _currentCharacter->sceneId != 173 &&
+ (_currentCharacter->sceneId < 187 || _currentCharacter->sceneId > 198)) {
palIndex = 14;
}
}
@@ -1291,12 +1296,12 @@ int KyraEngine_LoK::o1_drawItemShapeIntoScene(EMCState *script) {
flags = 1;
if (onlyHidPage) {
- _screen->drawShape(2, _shapes[216+item], x, y, 0, flags);
+ _screen->drawShape(2, _shapes[216 + item], x, y, 0, flags);
} else {
_screen->hideMouse();
_animator->restoreAllObjectBackgrounds();
- _screen->drawShape(2, _shapes[216+item], x, y, 0, flags);
- _screen->drawShape(0, _shapes[216+item], x, y, 0, flags);
+ _screen->drawShape(2, _shapes[216 + item], x, y, 0, flags);
+ _screen->drawShape(0, _shapes[216 + item], x, y, 0, flags);
_animator->flagAllObjectsForBkgdChange();
_animator->preserveAnyChangedBackgrounds();
_animator->flagAllObjectsForRefresh();
@@ -1409,7 +1414,7 @@ int KyraEngine_LoK::o1_fillFlaskWithWater(EMCState *script) {
int KyraEngine_LoK::o1_getCharacterMovementDelay(EMCState *script) {
debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_getCharacterMovementDelay(%p) (%d)", (const void *)script, stackPos(0));
- return _timer->getDelay(stackPos(0)+5);
+ return _timer->getDelay(stackPos(0) + 5);
}
int KyraEngine_LoK::o1_getBirthstoneGem(EMCState *script) {
@@ -1715,13 +1720,13 @@ int KyraEngine_LoK::o1_pauseMusicSeconds(EMCState *script) {
debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_pauseMusicSeconds(%p) ()", (const void *)script);
// if music disabled
// return
- delay(stackPos(0)*1000, true);
+ delay(stackPos(0) * 1000, true);
return 0;
}
int KyraEngine_LoK::o1_resetMaskRegion(EMCState *script) {
debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_resetMaskRegion(%p) (%d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4));
- _screen->fillRect(stackPos(1), stackPos(2), stackPos(1)+stackPos(3), stackPos(2)+stackPos(4), 0, 5);
+ _screen->fillRect(stackPos(1), stackPos(2), stackPos(1) + stackPos(3), stackPos(2) + stackPos(4), 0, 5);
return 0;
}
diff --git a/engines/kyra/script_lol.cpp b/engines/kyra/script_lol.cpp
index b4b8f00022..c5d1d49030 100644
--- a/engines/kyra/script_lol.cpp
+++ b/engines/kyra/script_lol.cpp
@@ -93,25 +93,6 @@ void LoLEngine::runLevelScriptCustom(int block, int flags, int charNum, int item
checkSceneUpdateNeed(block);
}
-bool LoLEngine::checkSceneUpdateNeed(int func) {
- if (_sceneUpdateRequired)
- return true;
-
- for (int i = 0; i < 15; i++) {
- if (_visibleBlockIndex[i] == func) {
- _sceneUpdateRequired = true;
- return true;
- }
- }
-
- if (_currentBlock == func){
- _sceneUpdateRequired = true;
- return true;
- }
-
- return false;
-}
-
int LoLEngine::olol_setWallType(EMCState *script) {
debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_setWallType(%p) (%d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2));
if (stackPos(2) != -1) {
@@ -124,7 +105,7 @@ int LoLEngine::olol_setWallType(EMCState *script) {
int LoLEngine::olol_getWallType(EMCState *script) {
debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_getWallType(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1));
- return _levelBlockProperties[stackPos(0)].walls[stackPos(1) & 3];
+ return (int8)_levelBlockProperties[stackPos(0)].walls[stackPos(1) & 3];
}
int LoLEngine::olol_drawScene(EMCState *script) {
@@ -286,13 +267,13 @@ int LoLEngine::olol_makeItem(EMCState *script) {
}
int LoLEngine::olol_placeMoveLevelItem(EMCState *script) {
- debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_setItemProperty(%p) (%d, %d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5));
+ debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_placeMoveLevelItem(%p) (%d, %d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5));
placeMoveLevelItem(stackPos(0), stackPos(1), stackPos(2), stackPos(3) & 0xff, stackPos(4) & 0xff, stackPos(5));
return 1;
}
int LoLEngine::olol_createLevelItem(EMCState *script) {
- debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_setItemProperty(%p) (%d, %d, %d, %d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5), stackPos(6), stackPos(7));
+ debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_createLevelItem(%p) (%d, %d, %d, %d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5), stackPos(6), stackPos(7));
int item = makeItem(stackPos(0), stackPos(1), stackPos(2));
if (item == -1)
return item;
@@ -305,7 +286,7 @@ int LoLEngine::olol_getItemPara(EMCState *script) {
if (!stackPos(0))
return 0;
- ItemInPlay *i = &_itemsInPlay[stackPos(0)];
+ LoLItem *i = &_itemsInPlay[stackPos(0)];
ItemProperty *p = &_itemProperties[i->itemPropertyIndex];
switch (stackPos(1)) {
@@ -676,6 +657,8 @@ int LoLEngine::olol_getGlobalVar(EMCState *script) {
return _drainMagic;
case 13:
return getVolume(kVolumeSpeech) - 2;
+ case 14:
+ return _tim->_abortFlag;
default:
break;
}
@@ -794,9 +777,9 @@ int LoLEngine::olol_updateBlockAnimations(EMCState *script) {
return 0;
}
-int LoLEngine::olol_mapShapeToBlock(EMCState *script) {
- debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_mapShapeToBlock(%p) (%d)", (const void *)script, stackPos(0));
- return assignLevelShapes(stackPos(0));
+int LoLEngine::olol_assignLevelDecorationShape(EMCState *script) {
+ debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_assignLevelDecorationShape(%p) (%d)", (const void *)script, stackPos(0));
+ return assignLevelDecorationShapes(stackPos(0));
}
int LoLEngine::olol_resetBlockShapeAssignment(EMCState *script) {
@@ -809,7 +792,7 @@ int LoLEngine::olol_resetBlockShapeAssignment(EMCState *script) {
int LoLEngine::olol_copyRegion(EMCState *script) {
debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_copyRegion(%p) (%d, %d, %d, %d, %d, %d, %d, %d)",
- (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5), stackPos(6), stackPos(7));
+ (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5), stackPos(6), stackPos(7));
_screen->copyRegion(stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5), stackPos(6), stackPos(7), Screen::CR_NO_P_CHECK);
if (!stackPos(7))
_screen->updateScreen();
@@ -818,7 +801,7 @@ int LoLEngine::olol_copyRegion(EMCState *script) {
int LoLEngine::olol_initMonster(EMCState *script) {
debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_initMonster(%p) (%d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d)", (const void *)script,
- stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5), stackPos(6), stackPos(7), stackPos(8), stackPos(9), stackPos(10));
+ stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5), stackPos(6), stackPos(7), stackPos(8), stackPos(9), stackPos(10));
uint16 x = 0;
uint16 y = 0;
calcCoordinates(x, y, stackPos(0), stackPos(1), stackPos(2));
@@ -828,11 +811,11 @@ int LoLEngine::olol_initMonster(EMCState *script) {
return -1;
for (uint8 i = 0; i < 30; i++) {
- MonsterInPlay *l = &_monsters[i];
+ LoLMonster *l = &_monsters[i];
if (l->hitPoints || l->mode == 13)
continue;
- memset(l, 0, sizeof(MonsterInPlay));
+ memset(l, 0, sizeof(LoLMonster));
l->id = i;
l->x = x;
l->y = y;
@@ -842,7 +825,7 @@ int LoLEngine::olol_initMonster(EMCState *script) {
l->direction = l->facing << 1;
l->hitPoints = (l->properties->hitPoints * _monsterModifiers[_monsterDifficulty]) >> 8;
- if (_currentLevel == 12 && l->type == 2)
+ if (_currentLevel != 12 || l->type != 2)
l->hitPoints = (l->hitPoints * (rollDice(1, 128) + 192)) >> 8;
l->numDistAttacks = l->properties->numDistAttacks;
@@ -859,7 +842,7 @@ int LoLEngine::olol_initMonster(EMCState *script) {
l->destDirection = l->direction;
for (int ii = 0; ii < 4; ii++)
- l->equipmentShapes[ii] = stackPos(7 + ii);
+ l->equipmentShapes[ii] = stackPos(7 + ii) & 0xff;
checkSceneUpdateNeed(l->block);
return i;
@@ -936,14 +919,14 @@ int LoLEngine::olol_dummy0(EMCState *script) {
int LoLEngine::olol_loadMonsterProperties(EMCState *script) {
debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_loadMonsterProperties(%p) (%d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d)",
- (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5),
- stackPos(6), stackPos(7), stackPos(8), stackPos(9), stackPos(10), stackPos(11), stackPos(12), stackPos(13),
- stackPos(14), stackPos(15), stackPos(16), stackPos(17), stackPos(18), stackPos(19), stackPos(20),
- stackPos(21), stackPos(22), stackPos(23), stackPos(24), stackPos(25), stackPos(26), stackPos(27),
- stackPos(28), stackPos(29), stackPos(30), stackPos(31), stackPos(32), stackPos(33), stackPos(34),
- stackPos(35), stackPos(36), stackPos(37), stackPos(38), stackPos(39), stackPos(40), stackPos(41));
-
- MonsterProperty *l = &_monsterProperties[stackPos(0)];
+ (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5),
+ stackPos(6), stackPos(7), stackPos(8), stackPos(9), stackPos(10), stackPos(11), stackPos(12), stackPos(13),
+ stackPos(14), stackPos(15), stackPos(16), stackPos(17), stackPos(18), stackPos(19), stackPos(20),
+ stackPos(21), stackPos(22), stackPos(23), stackPos(24), stackPos(25), stackPos(26), stackPos(27),
+ stackPos(28), stackPos(29), stackPos(30), stackPos(31), stackPos(32), stackPos(33), stackPos(34),
+ stackPos(35), stackPos(36), stackPos(37), stackPos(38), stackPos(39), stackPos(40), stackPos(41));
+
+ LoLMonsterProperty *l = &_monsterProperties[stackPos(0)];
l->shapeIndex = stackPos(1) & 0xff;
int shpWidthMax = 0;
@@ -956,14 +939,14 @@ int LoLEngine::olol_loadMonsterProperties(EMCState *script) {
l->maxWidth = shpWidthMax;
- l->fightingStats[0] = (stackPos(2) << 8) / 100; // hit chance
- l->fightingStats[1] = 256; //
- l->fightingStats[2] = (stackPos(3) << 8) / 100; // protection
- l->fightingStats[3] = stackPos(4); // evade chance
- l->fightingStats[4] = (stackPos(5) << 8) / 100; // speed
- l->fightingStats[5] = (stackPos(6) << 8) / 100; //
- l->fightingStats[6] = (stackPos(7) << 8) / 100; //
- l->fightingStats[7] = (stackPos(8) << 8) / 100; //
+ l->fightingStats[0] = (stackPos(2) << 8) / 100; // hit chance
+ l->fightingStats[1] = 256; //
+ l->fightingStats[2] = (stackPos(3) << 8) / 100; // protection
+ l->fightingStats[3] = stackPos(4); // evade chance
+ l->fightingStats[4] = (stackPos(5) << 8) / 100; // speed
+ l->fightingStats[5] = (stackPos(6) << 8) / 100; //
+ l->fightingStats[6] = (stackPos(7) << 8) / 100; //
+ l->fightingStats[7] = (stackPos(8) << 8) / 100; //
l->fightingStats[8] = 0;
for (int i = 0; i < 8; i++) {
@@ -1015,7 +998,7 @@ int LoLEngine::olol_inflictDamage(EMCState *script) {
int LoLEngine::olol_moveMonster(EMCState *script) {
debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_moveMonster(%p) (%d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4));
- MonsterInPlay *m = &_monsters[stackPos(0)];
+ LoLMonster *m = &_monsters[stackPos(0)];
if (m->mode == 1 || m->mode == 2) {
calcCoordinates(m->destX, m->destY, stackPos(1), stackPos(2), stackPos(3));
@@ -1027,10 +1010,9 @@ int LoLEngine::olol_moveMonster(EMCState *script) {
return 1;
}
-int LoLEngine::olol_dialogueBox(EMCState *script) {
- debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_dialogueBox(%p) (%d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3));
-
- _tim->drawDialogueBox(stackPos(0), getLangString(stackPos(1)), getLangString(stackPos(2)), getLangString(stackPos(3)));
+int LoLEngine::olol_setupDialogueButtons(EMCState *script) {
+ debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_setupDialogueButtons(%p) (%d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3));
+ setupDialogueButtons(stackPos(0), getLangString(stackPos(1)), getLangString(stackPos(2)), getLangString(stackPos(3)));
return 1;
}
@@ -1192,7 +1174,7 @@ int LoLEngine::olol_playSoundEffect(EMCState *script) {
int LoLEngine::olol_processDialogue(EMCState *script) {
debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_processDialogue(%p)", (const void *)script);
- return _tim->processDialogue();
+ return processDialogue();
}
int LoLEngine::olol_stopTimScript(EMCState *script) {
@@ -1211,7 +1193,7 @@ int LoLEngine::olol_changeMonsterStat(EMCState *script) {
if (stackPos(0) == -1)
return 1;
- MonsterInPlay *m = &_monsters[stackPos(0) & 0x7fff];
+ LoLMonster *m = &_monsters[stackPos(0) & 0x7fff];
int16 d = stackPos(2);
uint16 x = 0;
@@ -1252,7 +1234,7 @@ int LoLEngine::olol_getMonsterStat(EMCState *script) {
if (stackPos(0) == -1)
return 0;
- MonsterInPlay *m = &_monsters[stackPos(0) & 0x7fff];
+ LoLMonster *m = &_monsters[stackPos(0) & 0x7fff];
int d = stackPos(1);
switch (d) {
@@ -1383,14 +1365,14 @@ int LoLEngine::olol_countBlockItems(EMCState *script) {
return res;
}
-int LoLEngine::olol_characterSkillTest(EMCState *script){
+int LoLEngine::olol_characterSkillTest(EMCState *script) {
debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_characterSkillTest(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1));
int skill = stackPos(0);
int n = countActiveCharacters();
int m = 0;
int c = 0;
- for (int i = 0; i < n; i++) {
+ for (int i = 0; i < n; i++) {
int v = _characters[i].skillModifiers[skill] + _characters[i].skillLevels[skill] + 25;
if (v > m) {
m = v;
@@ -1401,7 +1383,7 @@ int LoLEngine::olol_characterSkillTest(EMCState *script){
return (rollDice(1, 100) > m) ? -1 : c;
}
-int LoLEngine::olol_countAllMonsters(EMCState *script){
+int LoLEngine::olol_countAllMonsters(EMCState *script) {
debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_countAllMonsters(%p)", (const void *)script);
int res = 0;
@@ -1413,7 +1395,7 @@ int LoLEngine::olol_countAllMonsters(EMCState *script){
return res;
}
-int LoLEngine::olol_playEndSequence(EMCState *script){
+int LoLEngine::olol_playEndSequence(EMCState *script) {
debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_playEndSequence(%p)", (const void *)script);
int c = 0;
@@ -1538,12 +1520,12 @@ int LoLEngine::olol_checkInventoryFull(EMCState *script) {
return 1;
}
-int LoLEngine::olol_objectLeavesLevel(EMCState *script) {
- debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_objectLeavesLevel(%p) (%d, %d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5));
+int LoLEngine::olol_moveBlockObjects(EMCState *script) {
+ debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_moveBlockObjects(%p) (%d, %d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5));
int o = _levelBlockProperties[stackPos(0)].assignedObjects;
int res = 0;
int level = stackPos(2);
- int block = stackPos(1);
+ int destBlock = stackPos(1);
int runScript = stackPos(4);
int includeMonsters = stackPos(3);
int includeItems = stackPos(5);
@@ -1551,9 +1533,9 @@ int LoLEngine::olol_objectLeavesLevel(EMCState *script) {
// WORKAROUND for script bug
// Items would vanish when thrown towards the stairs
// in white tower level 3.
- if (_currentLevel == 21 && level == 21 && block == 0x3e0) {
+ if (_currentLevel == 21 && level == 21 && destBlock == 0x3e0) {
level = 20;
- block = 0x0247;
+ destBlock = 0x0247;
}
while (o) {
@@ -1565,7 +1547,7 @@ int LoLEngine::olol_objectLeavesLevel(EMCState *script) {
l &= 0x7fff;
- MonsterInPlay *m = &_monsters[l];
+ LoLMonster *m = &_monsters[l];
setMonsterMode(m, 14);
checkSceneUpdateNeed(m->block);
@@ -1577,15 +1559,13 @@ int LoLEngine::olol_objectLeavesLevel(EMCState *script) {
if (!(_itemsInPlay[l].shpCurFrame_flg & 0x4000) || !includeItems)
continue;
- placeMoveLevelItem(l, level, block, _itemsInPlay[l].x & 0xff, _itemsInPlay[l].y & 0xff, _itemsInPlay[l].flyingHeight);
+ placeMoveLevelItem(l, level, destBlock, _itemsInPlay[l].x & 0xff, _itemsInPlay[l].y & 0xff, _itemsInPlay[l].flyingHeight);
+ res = 1;
- if (!runScript || level != _currentLevel) {
- res = 1;
+ if (!runScript || level != _currentLevel)
continue;
- }
- runLevelScriptCustom(block, 0x80, -1, l, 0, 0);
- res = 1;
+ runLevelScriptCustom(destBlock, 0x80, -1, l, 0, 0);
}
}
@@ -1638,7 +1618,7 @@ int LoLEngine::olol_dummy1(EMCState *script) {
int LoLEngine::olol_suspendMonster(EMCState *script) {
debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_suspendMonster(%p) (%d)", (const void *)script, stackPos(0));
- MonsterInPlay *m = &_monsters[stackPos(0) & 0x7fff];
+ LoLMonster *m = &_monsters[stackPos(0) & 0x7fff];
setMonsterMode(m, 14);
checkSceneUpdateNeed(m->block);
placeMonster(m, 0, 0);
@@ -1705,7 +1685,7 @@ int LoLEngine::olol_countSpecificMonsters(EMCState *script) {
int LoLEngine::olol_updateBlockAnimations2(EMCState *script) {
debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_updateBlockAnimations2(%p) (%d, %d, %d, %d, ...)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3));
int numFrames = stackPos(3);
- assert (numFrames <= 97);
+ assert(numFrames <= 97);
int curFrame = stackPos(2) % numFrames;
setWallType(stackPos(0), stackPos(1), stackPos(4 + curFrame));
return 0;
@@ -1889,9 +1869,9 @@ int LoLEngine::olol_checkBlockForMonster(EMCState *script) {
return -1;
}
-int LoLEngine::olol_transformRegion(EMCState *script) {
- debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_transformRegion(%p) (%d, %d, %d, %d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5), stackPos(6), stackPos(7));
- transformRegion(stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5), stackPos(6), stackPos(7));
+int LoLEngine::olol_crossFadeRegion(EMCState *script) {
+ debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_crossFadeRegion(%p) (%d, %d, %d, %d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5), stackPos(6), stackPos(7));
+ _screen->crossFadeRegion(stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5), stackPos(6), stackPos(7));
return 1;
}
@@ -1984,7 +1964,7 @@ int LoLEngine::olol_getAnimationLastPart(EMCState *script) {
int LoLEngine::olol_assignSpecialGuiShape(EMCState *script) {
debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_assignSpecialGuiShape(%p) (%d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4));
if (stackPos(0)) {
- _specialGuiShape = _levelShapes[_levelShapeProperties[_wllShapeMap[stackPos(0)]].shapeIndex[stackPos(1)]];
+ _specialGuiShape = _levelDecorationShapes[_levelDecorationProperties[_wllShapeMap[stackPos(0)]].shapeIndex[stackPos(1)]];
_specialGuiShapeX = stackPos(2);
_specialGuiShapeY = stackPos(3);
_specialGuiShapeMirrorFlag = stackPos(4);
@@ -2012,7 +1992,7 @@ int LoLEngine::olol_findInventoryItem(EMCState *script) {
cur = 0;
last = 4;
}
- for (;cur < last; cur++) {
+ for (; cur < last; cur++) {
if (!(_characters[cur].flags & 1))
continue;
for (int i = 0; i < 11; i++) {
@@ -2055,18 +2035,17 @@ int LoLEngine::olol_changeItemTypeOrFlag(EMCState *script) {
if (stackPos(0) < 1)
return 0;
- ItemInPlay *i = &_itemsInPlay[stackPos(0)];
- int r = stackPos(2) & 0x1fff;
+ LoLItem *i = &_itemsInPlay[stackPos(0)];
+ int16 val = stackPos(2);
- if (stackPos(1) == 4) {
- i->itemPropertyIndex = r;
- return r;
- } else if (stackPos(1) == 15) {
- i->shpCurFrame_flg = (i->shpCurFrame_flg & 0xe000) | r;
- return r;
- }
+ if (stackPos(1) == 4)
+ i->itemPropertyIndex = val;
+ else if (stackPos(1) == 15)
+ i->shpCurFrame_flg = (i->shpCurFrame_flg & 0xe000) | (val & 0x1fff);
+ else
+ val = -1;
- return -1;
+ return val;
}
int LoLEngine::olol_placeInventoryItemInHand(EMCState *script) {
@@ -2292,10 +2271,10 @@ int LoLEngine::olol_calcNewBlockPosition(EMCState *script) {
return calcNewBlockPosition(stackPos(0), stackPos(1));
}
-int LoLEngine::olol_fadeScene(EMCState *script) {
- debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_fadeScene(%p)", (const void *)script);
+int LoLEngine::olol_crossFadeScene(EMCState *script) {
+ debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_crossFadeScene(%p)", (const void *)script);
gui_drawScene(2);
- transformRegion(112, 0, 112, 0, 176, 120, 2, 0);
+ _screen->crossFadeRegion(112, 0, 112, 0, 176, 120, 2, 0);
updateDrawPage2();
return 1;
}
@@ -2377,7 +2356,7 @@ int LoLEngine::tlol_setupPaletteFade(const TIM *tim, const uint16 *param) {
int LoLEngine::tlol_loadPalette(const TIM *tim, const uint16 *param) {
debugC(3, kDebugLevelScriptFuncs, "LoLEngine::tlol_loadPalette(%p, %p) (%d)", (const void *)tim, (const void *)param, param[0]);
- const char *palFile = (const char *)(tim->text + READ_LE_UINT16(tim->text + (param[0]<<1)));
+ const char *palFile = (const char *)(tim->text + READ_LE_UINT16(tim->text + (param[0] << 1)));
_screen->loadPalette(palFile, _screen->getPalette(0));
return 1;
}
@@ -2393,7 +2372,7 @@ int LoLEngine::tlol_setupPaletteFadeEx(const TIM *tim, const uint16 *param) {
int LoLEngine::tlol_processWsaFrame(const TIM *tim, const uint16 *param) {
debugC(3, kDebugLevelScriptFuncs, "LoLEngine::tlol_processWsaFrame(%p, %p) (%d, %d, %d, %d, %d)",
- (const void *)tim, (const void *)param, param[0], param[1], param[2], param[3], param[4]);
+ (const void *)tim, (const void *)param, param[0], param[1], param[2], param[3], param[4]);
const int animIndex = tim->wsa[param[0]].anim - 1;
const int frame = param[1];
@@ -2591,8 +2570,8 @@ int LoLEngine::tlol_stopBackgroundAnimation(const TIM *tim, const uint16 *param)
int LoLEngine::tlol_fadeInScene(const TIM *tim, const uint16 *param) {
debugC(3, kDebugLevelScriptFuncs, "LoLEngine::tlol_fadeInScene(%p, %p) (%d, %d)", (const void *)tim, (const void *)param, param[0], param[1]);
- const char *sceneFile = (const char *)(tim->text + READ_LE_UINT16(tim->text + (param[0]<<1)));
- const char *overlayFile = (const char *)(tim->text + READ_LE_UINT16(tim->text + (param[1]<<1)));
+ const char *sceneFile = (const char *)(tim->text + READ_LE_UINT16(tim->text + (param[0] << 1)));
+ const char *overlayFile = (const char *)(tim->text + READ_LE_UINT16(tim->text + (param[1] << 1)));
_screen->copyRegion(0, 0, 0, 0, 320, 200, 0, 2, Screen::CR_NO_P_CHECK);
@@ -2643,7 +2622,7 @@ int LoLEngine::tlol_unusedResourceFunc(const TIM *tim, const uint16 *param) {
int LoLEngine::tlol_fadeInPalette(const TIM *tim, const uint16 *param) {
debugC(3, kDebugLevelScriptFuncs, "LoLEngine::tlol_fadeInPalette(%p, %p) (%d, %d)", (const void *)tim, (const void *)param, param[0], param[1]);
- const char *bitmap = (const char *)(tim->text + READ_LE_UINT16(tim->text + (param[0]<<1)));
+ const char *bitmap = (const char *)(tim->text + READ_LE_UINT16(tim->text + (param[0] << 1)));
Palette pal(_screen->getPalette(0).getNumColors());
_screen->loadBitmap(bitmap, 3, 3, &pal);
@@ -2785,7 +2764,7 @@ void LoLEngine::setupOpcodeTable() {
// 0x34
Opcode(olol_updateBlockAnimations);
- Opcode(olol_mapShapeToBlock);
+ Opcode(olol_assignLevelDecorationShape);
Opcode(olol_resetBlockShapeAssignment);
Opcode(olol_copyRegion);
@@ -2809,7 +2788,7 @@ void LoLEngine::setupOpcodeTable() {
// 0x44
Opcode(olol_moveMonster);
- Opcode(olol_dialogueBox);
+ Opcode(olol_setupDialogueButtons);
Opcode(olol_giveTakeMoney);
Opcode(olol_checkMoney);
@@ -2881,7 +2860,7 @@ void LoLEngine::setupOpcodeTable() {
// 0x74
Opcode(olol_checkInventoryFull);
- Opcode(olol_objectLeavesLevel);
+ Opcode(olol_moveBlockObjects);
OpcodeUnImpl();
OpcodeUnImpl();
@@ -2934,7 +2913,7 @@ void LoLEngine::setupOpcodeTable() {
Opcode(olol_checkBlockForMonster);
// 0x98
- Opcode(olol_transformRegion);
+ Opcode(olol_crossFadeRegion);
Opcode(olol_calcCoordinatesAddDirectionOffset);
Opcode(olol_resetPortraitsAndDisableSysTimer);
Opcode(olol_enableSysTimer);
@@ -2982,7 +2961,7 @@ void LoLEngine::setupOpcodeTable() {
Opcode(olol_calcNewBlockPosition);
// 0xB8
- Opcode(olol_fadeScene);
+ Opcode(olol_crossFadeScene);
Opcode(olol_updateDrawPage2);
Opcode(olol_setMouseCursor);
Opcode(olol_characterSays);
diff --git a/engines/kyra/script_mr.cpp b/engines/kyra/script_mr.cpp
index 8ab094ac0c..afe11aba02 100644
--- a/engines/kyra/script_mr.cpp
+++ b/engines/kyra/script_mr.cpp
@@ -405,7 +405,7 @@ int KyraEngine_MR::o3_updateConversations(EMCState *script) {
}
int convs[4];
- Common::set_to(convs, convs+4, -1);
+ Common::fill(convs, convs+4, -1);
if (_currentChapter == 1) {
switch (_mainCharacter.dlgIndex) {
diff --git a/engines/kyra/script_tim.cpp b/engines/kyra/script_tim.cpp
index 83d03d1f63..177d7993a0 100644
--- a/engines/kyra/script_tim.cpp
+++ b/engines/kyra/script_tim.cpp
@@ -833,18 +833,6 @@ int TIMInterpreter::cmd_stopFuncNow(const uint16 *param) {
return 1;
}
-int TIMInterpreter::cmd_stopAllFuncs(const uint16 *param) {
- while (_currentTim->dlgFunc == -1 && _currentTim->clickedButton == 0 && !_vm->shouldQuit()) {
- update();
- _currentTim->clickedButton = processDialogue();
- }
-
- for (int i = 0; i < TIM::kCountFuncs; ++i)
- _currentTim->func[i].ip = 0;
-
- return -1;
-}
-
// TODO: Consider moving to another file
#ifdef ENABLE_LOL
@@ -905,12 +893,10 @@ TIMInterpreter_LoL::TIMInterpreter_LoL(LoLEngine *engine, Screen_v2 *screen_v2,
_screen = engine->_screen;
+ delete _animator;
_animator = new TimAnimator(engine, screen_v2, system, true);
_drawPage2 = 0;
-
- memset(_dialogueButtonString, 0, 3 * sizeof(const char *));
- _dialogueButtonPosX = _dialogueButtonPosY = _dialogueNumButtons = _dialogueButtonXoffs = _dialogueHighlightedButton = 0;
}
int TIMInterpreter_LoL::initAnimStruct(int index, const char *filename, int x, int y, int frameDelay, int, uint16 wsaFlags) {
@@ -978,157 +964,12 @@ void TIMInterpreter_LoL::advanceToOpcode(int opcode) {
f->nextTime = _system->getMillis();
}
-void TIMInterpreter_LoL::drawDialogueBox(int numStr, const char *s1, const char *s2, const char *s3) {
- _screen->setScreenDim(5);
-
- if (numStr == 1 && _vm->speechEnabled()) {
- _dialogueNumButtons = 0;
- _dialogueButtonString[0] = _dialogueButtonString[1] = _dialogueButtonString[2] = 0;
- } else {
- _dialogueNumButtons = numStr;
- _dialogueButtonString[0] = s1;
- _dialogueButtonString[1] = s2;
- _dialogueButtonString[2] = s3;
- _dialogueHighlightedButton = 0;
-
- const ScreenDim *d = _screen->getScreenDim(5);
- _dialogueButtonPosY = d->sy + d->h - 9;
-
- if (numStr == 1) {
- _dialogueButtonXoffs = 0;
- _dialogueButtonPosX = d->sx + d->w - 77;
- } else {
- _dialogueButtonXoffs = d->w / numStr;
- _dialogueButtonPosX = d->sx + (_dialogueButtonXoffs >> 1) - 37;
- }
-
- drawDialogueButtons();
- }
-
- if (!_vm->shouldQuit())
- _vm->removeInputTop();
-}
-
-void TIMInterpreter_LoL::drawDialogueButtons() {
- int cp = _screen->setCurPage(0);
- Screen::FontId of = _screen->setFont(_vm->gameFlags().use16ColorMode ? Screen::FID_SJIS_FNT : Screen::FID_6_FNT);
-
- int x = _dialogueButtonPosX;
-
- for (int i = 0; i < _dialogueNumButtons; i++) {
- if (_vm->gameFlags().use16ColorMode) {
- _vm->gui_drawBox(x, (_dialogueButtonPosY & ~7) - 1, 74, 10, 0xee, 0xcc, -1);
- _screen->printText(_dialogueButtonString[i], (x + 37 - (_screen->getTextWidth(_dialogueButtonString[i])) / 2) & ~3,
- (_dialogueButtonPosY + 2) & ~7, _dialogueHighlightedButton == i ? 0xc1 : 0xe1, 0);
- } else {
- _vm->gui_drawBox(x, _dialogueButtonPosY, 74, 9, 136, 251, -1);
- _screen->printText(_dialogueButtonString[i], x + 37 - (_screen->getTextWidth(_dialogueButtonString[i])) / 2,
- _dialogueButtonPosY + 2, _dialogueHighlightedButton == i ? 144 : 254, 0);
- }
-
- x += _dialogueButtonXoffs;
- }
- _screen->setFont(of);
- _screen->setCurPage(cp);
-}
-
-uint16 TIMInterpreter_LoL::processDialogue() {
- int df = _dialogueHighlightedButton;
- int res = 0;
- int x = _dialogueButtonPosX;
- int y = (_vm->gameFlags().use16ColorMode ? (_dialogueButtonPosY & ~7) - 1 : _dialogueButtonPosY);
-
- for (int i = 0; i < _dialogueNumButtons; i++) {
- Common::Point p = _vm->getMousePos();
- if (_vm->posWithinRect(p.x, p.y, x, y, x + 74, y + 9)) {
- _dialogueHighlightedButton = i;
- break;
- }
- x += _dialogueButtonXoffs;
- }
-
- if (_dialogueNumButtons == 0) {
- int e = _vm->checkInput(0, false) & 0xFF;
- _vm->removeInputTop();
-
- if (e) {
- _vm->gui_notifyButtonListChanged();
-
- if (e == 43 || e == 61) {
- _vm->snd_stopSpeech(true);
- }
- }
-
- if (_vm->snd_updateCharacterSpeech() != 2) {
- res = 1;
- if (!_vm->shouldQuit()) {
- _vm->removeInputTop();
- _vm->gui_notifyButtonListChanged();
- }
- }
- } else {
- int e = _vm->checkInput(0, false) & 0xFF;
- _vm->removeInputTop();
- if (e)
- _vm->gui_notifyButtonListChanged();
-
- if (e == 200 || e == 202) {
- x = _dialogueButtonPosX;
-
- for (int i = 0; i < _dialogueNumButtons; i++) {
- Common::Point p = _vm->getMousePos();
- if (_vm->posWithinRect(p.x, p.y, x, y, x + 74, y + 9)) {
- _dialogueHighlightedButton = i;
- res = _dialogueHighlightedButton + 1;
- break;
- }
- x += _dialogueButtonXoffs;
- }
- } else if (e == _vm->_keyMap[Common::KEYCODE_SPACE] || e == _vm->_keyMap[Common::KEYCODE_RETURN]) {
- _vm->snd_stopSpeech(true);
- res = _dialogueHighlightedButton + 1;
- } else if (e == _vm->_keyMap[Common::KEYCODE_LEFT] || e == _vm->_keyMap[Common::KEYCODE_DOWN]) {
- if (_dialogueNumButtons > 1 && _dialogueHighlightedButton > 0)
- _dialogueHighlightedButton--;
- } else if (e == _vm->_keyMap[Common::KEYCODE_RIGHT] || e == _vm->_keyMap[Common::KEYCODE_UP]) {
- if (_dialogueNumButtons > 1 && _dialogueHighlightedButton < (_dialogueNumButtons - 1))
- _dialogueHighlightedButton++;
- }
- }
-
- if (df != _dialogueHighlightedButton)
- drawDialogueButtons();
-
- _screen->updateScreen();
-
- if (res == 0)
- return 0;
-
- _vm->stopPortraitSpeechAnim();
-
- if (!_vm->textEnabled() && _vm->_currentControlMode) {
- _screen->setScreenDim(5);
- const ScreenDim *d = _screen->getScreenDim(5);
- _screen->fillRect(d->sx, d->sy + d->h - 9, d->sx + d->w - 1, d->sy + d->h - 1, d->unkA);
- } else {
- const ScreenDim *d = _screen->_curDim;
- if (_vm->gameFlags().use16ColorMode)
- _screen->fillRect(d->sx, d->sy, d->sx + d->w - 3, d->sy + d->h - 2, d->unkA);
- else
- _screen->fillRect(d->sx, d->sy, d->sx + d->w - 2, d->sy + d->h - 1, d->unkA);
- _vm->_txt->clearDim(4);
- _vm->_txt->resetDimTextPositions(4);
- }
-
- return res;
-}
-
void TIMInterpreter_LoL::resetDialogueState(TIM *tim) {
if (!tim)
return;
tim->procFunc = 0;
- tim->procParam = _dialogueNumButtons ? _dialogueNumButtons : 1;
+ tim->procParam = _vm->_dialogueNumButtons ? _vm->_dialogueNumButtons : 1;
tim->clickedButton = 0;
tim->dlgFunc = -1;
}
@@ -1168,6 +1009,18 @@ int TIMInterpreter_LoL::execCommand(int cmd, const uint16 *param) {
return (this->*_commands[cmd].proc)(param);
}
+int TIMInterpreter_LoL::cmd_stopAllFuncs(const uint16 *param) {
+ while (_currentTim->dlgFunc == -1 && _currentTim->clickedButton == 0 && !_vm->shouldQuit()) {
+ update();
+ _currentTim->clickedButton = _vm->processDialogue();
+ }
+
+ for (int i = 0; i < TIM::kCountFuncs; ++i)
+ _currentTim->func[i].ip = 0;
+
+ return -1;
+}
+
int TIMInterpreter_LoL::cmd_setLoopIp(const uint16 *param) {
if (_vm->speechEnabled()) {
if (_vm->snd_updateCharacterSpeech() == 2)
@@ -1201,7 +1054,7 @@ int TIMInterpreter_LoL::cmd_continueLoop(const uint16 *param) {
}
int TIMInterpreter_LoL::cmd_processDialogue(const uint16 *param) {
- int res = processDialogue();
+ int res = _vm->processDialogue();
if (!res || !_currentTim->procParam)
return res;
@@ -1238,7 +1091,7 @@ int TIMInterpreter_LoL::cmd_dialogueBox(const uint16 *param) {
}
}
- drawDialogueBox(cnt, tmpStr[0], tmpStr[1], tmpStr[2]);
+ _vm->setupDialogueButtons(cnt, tmpStr[0], tmpStr[1], tmpStr[2]);
_vm->gui_notifyButtonListChanged();
return -3;
diff --git a/engines/kyra/script_tim.h b/engines/kyra/script_tim.h
index 11b716c3a9..aa512daae8 100644
--- a/engines/kyra/script_tim.h
+++ b/engines/kyra/script_tim.h
@@ -186,8 +186,6 @@ public:
void displayText(uint16 textId, int16 flags, uint8 color);
void setupTextPalette(uint index, int fadePalette);
- virtual void drawDialogueBox(int numStr, const char *s1, const char *s2, const char *s3) {}
- virtual uint16 processDialogue() { return 1; }
virtual void resetDialogueState(TIM *tim) {}
int _drawPage2;
@@ -255,7 +253,6 @@ protected:
int cmd_execOpcode(const uint16 *param);
int cmd_initFuncNow(const uint16 *param);
int cmd_stopFuncNow(const uint16 *param);
- int cmd_stopAllFuncs(const uint16 *param);
#define cmd_return(n, v) \
int cmd_return_##n(const uint16 *){ return v; }
cmd_return( 1, 1)
@@ -273,8 +270,6 @@ public:
int initAnimStruct(int index, const char *filename, int x, int y, int frameDelay, int, uint16 wsaCopyParams);
int freeAnimStruct(int index);
- void drawDialogueBox(int numStr, const char *s1, const char *s2, const char *s3);
- uint16 processDialogue();
void resetDialogueState(TIM *tim);
private:
@@ -284,18 +279,9 @@ private:
char *getTableString(int id);
void advanceToOpcode(int opcode);
- void drawDialogueButtons();
-
LoLEngine *_vm;
Screen_LoL *_screen;
- const char *_dialogueButtonString[3];
- uint16 _dialogueButtonPosX;
- uint16 _dialogueButtonPosY;
- int _dialogueNumButtons;
- uint16 _dialogueButtonXoffs;
- int _dialogueHighlightedButton;
-
virtual int execCommand(int cmd, const uint16 *param);
typedef int (TIMInterpreter_LoL::*CommandProc)(const uint16 *);
@@ -307,6 +293,7 @@ private:
const CommandEntry *_commands;
int _commandsSize;
+ int cmd_stopAllFuncs(const uint16 *param);
int cmd_setLoopIp(const uint16 *param);
int cmd_continueLoop(const uint16 *param);
int cmd_processDialogue(const uint16 *param);
diff --git a/engines/kyra/script_v1.cpp b/engines/kyra/script_v1.cpp
index 4cfbdf8ab8..aaa07e6d61 100644
--- a/engines/kyra/script_v1.cpp
+++ b/engines/kyra/script_v1.cpp
@@ -106,13 +106,13 @@ int KyraEngine_v1::o1_fillRect(EMCState *script) {
int KyraEngine_v1::o1_blockInWalkableRegion(EMCState *script) {
debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_blockInWalkableRegion(%p) (%d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3));
- screen()->blockInRegion(stackPos(0), stackPos(1), stackPos(2)-stackPos(0)+1, stackPos(3)-stackPos(1)+1);
+ screen()->blockInRegion(stackPos(0), stackPos(1), stackPos(2) - stackPos(0) + 1, stackPos(3) - stackPos(1) + 1);
return 0;
}
int KyraEngine_v1::o1_blockOutWalkableRegion(EMCState *script) {
debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_blockOutWalkableRegion(%p) (%d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3));
- screen()->blockOutRegion(stackPos(0), stackPos(1), stackPos(2)-stackPos(0)+1, stackPos(3)-stackPos(1)+1);
+ screen()->blockOutRegion(stackPos(0), stackPos(1), stackPos(2) - stackPos(0) + 1, stackPos(3) - stackPos(1) + 1);
return 0;
}
diff --git a/engines/kyra/script_v2.cpp b/engines/kyra/script_v2.cpp
index e42cdf9ff4..c38a144537 100644
--- a/engines/kyra/script_v2.cpp
+++ b/engines/kyra/script_v2.cpp
@@ -57,7 +57,7 @@ int KyraEngine_v2::o2_setCharacterFacingOverwrite(EMCState *script) {
int KyraEngine_v2::o2_trySceneChange(EMCState *script) {
debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_trySceneChange(%p) (%d, %d, %d, %d)", (const void *)script,
- stackPos(0), stackPos(1), stackPos(2), stackPos(3));
+ stackPos(0), stackPos(1), stackPos(2), stackPos(3));
_unkHandleSceneChangeFlag = 1;
int success = inputSceneChange(stackPos(0), stackPos(1), stackPos(2), stackPos(3));
@@ -87,7 +87,7 @@ int KyraEngine_v2::o2_checkForItem(EMCState *script) {
int KyraEngine_v2::o2_defineItem(EMCState *script) {
debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_defineItem(%p) (%d, %d, %d, %d)", (const void *)script,
- stackPos(0), stackPos(1), stackPos(2), stackPos(3));
+ stackPos(0), stackPos(1), stackPos(2), stackPos(3));
int freeItem = findFreeItem();
if (freeItem >= 0) {
@@ -102,13 +102,13 @@ int KyraEngine_v2::o2_defineItem(EMCState *script) {
int KyraEngine_v2::o2_addSpecialExit(EMCState *script) {
debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_addSpecialExit(%p) (%d, %d, %d, %d, %d)", (const void *)script,
- stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4));
+ stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4));
if (_specialExitCount < 5) {
- _specialExitTable[_specialExitCount+0] = stackPos(0);
- _specialExitTable[_specialExitCount+5] = stackPos(1);
- _specialExitTable[_specialExitCount+10] = stackPos(2) + stackPos(0) - 1;
- _specialExitTable[_specialExitCount+15] = stackPos(3) + stackPos(1) - 1;
- _specialExitTable[_specialExitCount+20] = stackPos(4);
+ _specialExitTable[_specialExitCount + 0] = stackPos(0);
+ _specialExitTable[_specialExitCount + 5] = stackPos(1);
+ _specialExitTable[_specialExitCount + 10] = stackPos(2) + stackPos(0) - 1;
+ _specialExitTable[_specialExitCount + 15] = stackPos(3) + stackPos(1) - 1;
+ _specialExitTable[_specialExitCount + 20] = stackPos(4);
++_specialExitCount;
}
return 0;
@@ -226,7 +226,7 @@ int KyraEngine_v2::o2_defineRoomEntrance(EMCState *script) {
int KyraEngine_v2::o2_runAnimationScript(EMCState *script) {
debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_runAnimationScript(%p) ('%s', %d, %d, %d)", (const void *)script, stackPosString(0), stackPos(1),
- stackPos(2), stackPos(3));
+ stackPos(2), stackPos(3));
runAnimationScript(stackPosString(0), stackPos(3), stackPos(2) ? 1 : 0, stackPos(1), stackPos(2));
return 0;
@@ -241,7 +241,7 @@ int KyraEngine_v2::o2_setSpecialSceneScriptRunTime(EMCState *script) {
int KyraEngine_v2::o2_defineScene(EMCState *script) {
debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_defineScene(%p) (%d, '%s', %d, %d, %d, %d, %d, %d)",
- (const void *)script, stackPos(0), stackPosString(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5), stackPos(6), stackPos(7));
+ (const void *)script, stackPos(0), stackPosString(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5), stackPos(6), stackPos(7));
const int scene = stackPos(0);
strcpy(_sceneList[scene].filename1, stackPosString(1));
strcpy(_sceneList[scene].filename2, stackPosString(1));
@@ -323,7 +323,7 @@ int KyraEngine_v2::o2_getVocHigh(EMCState *script) {
int KyraEngine_v2::o2a_setAnimationShapes(EMCState *script) {
debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2a_setAnimationShapes(%p) ('%s', %d, %d, %d, %d, %d)", (const void *)script,
- stackPosString(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5));
+ stackPosString(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5));
strcpy(_animShapeFilename, stackPosString(0));
_animShapeLastEntry = stackPos(1);
_animShapeWidth = stackPos(2);
diff --git a/engines/kyra/seqplayer.cpp b/engines/kyra/seqplayer.cpp
index 531d864293..1f9097d09d 100644
--- a/engines/kyra/seqplayer.cpp
+++ b/engines/kyra/seqplayer.cpp
@@ -375,15 +375,14 @@ void SeqPlayer::s1_copyRegionSpecial() {
_screen->copyRegion(152, 56, 152, 56, 48, 48, 2, 0);
break;
case 4: {
- _screen->_charWidth = -2;
- const int x = (Screen::SCREEN_W - _screen->getTextWidth(copyStr)) / 2;
- const int y = 179;
- _screen->setTextColorMap(colorMap);
- if (_vm->gameFlags().platform != Common::kPlatformAmiga)
- _screen->printText(copyStr, x + 1, y + 1, 0xB, 0xC);
- _screen->printText(copyStr, x, y, 0xF, 0xC);
- }
- break;
+ _screen->_charWidth = -2;
+ const int x = (Screen::SCREEN_W - _screen->getTextWidth(copyStr)) / 2;
+ const int y = 179;
+ _screen->setTextColorMap(colorMap);
+ if (_vm->gameFlags().platform != Common::kPlatformAmiga)
+ _screen->printText(copyStr, x + 1, y + 1, 0xB, 0xC);
+ _screen->printText(copyStr, x, y, 0xF, 0xC);
+ } break;
case 5:
_screen->_curPage = 2;
break;
@@ -624,7 +623,7 @@ bool SeqPlayer::playSequence(const uint8 *seqData, bool skipSeq) {
if (_vm->gameFlags().lang == Common::JA_JPN)
charStr[1] = _vm->seqTextsTable()[_seqDisplayedText][++_seqDisplayedChar];
_screen->printText(charStr, _seqDisplayedTextX, 180, 0xF, 0xC);
- _seqDisplayedTextX += _screen->getCharWidth(charStr[0]);
+ _seqDisplayedTextX += _screen->getCharWidth((uint8)charStr[0]);
++_seqDisplayedChar;
if (_vm->seqTextsTable()[_seqDisplayedText][_seqDisplayedChar] == '\0')
diff --git a/engines/kyra/sequences_darkmoon.cpp b/engines/kyra/sequences_darkmoon.cpp
new file mode 100644
index 0000000000..d4f5c847fd
--- /dev/null
+++ b/engines/kyra/sequences_darkmoon.cpp
@@ -0,0 +1,1436 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifdef ENABLE_EOB
+
+#include "kyra/darkmoon.h"
+#include "kyra/screen_eob.h"
+#include "kyra/resource.h"
+#include "kyra/sound.h"
+
+#include "common/system.h"
+
+#include "base/version.h"
+
+namespace Kyra {
+
+class DarkmoonSequenceHelper {
+friend class DarkMoonEngine;
+public:
+ enum Mode {
+ kIntro,
+ kFinale
+ };
+
+ struct Config {
+ Config(Mode m, const char *const *str, const char *const *cps, const char *const *pal, const DarkMoonShapeDef **shp, const DarkMoonAnimCommand **anim, bool paletteFading) : mode(m), strings(str), cpsFiles(cps), palFiles(pal), shapeDefs(shp), animData(anim), palFading(paletteFading) {}
+ Mode mode;
+ const char *const *strings;
+ const char *const *cpsFiles;
+ const char *const *palFiles;
+ const DarkMoonShapeDef **shapeDefs;
+ const DarkMoonAnimCommand **animData;
+ bool palFading;
+ };
+
+ DarkmoonSequenceHelper(OSystem *system, DarkMoonEngine *vm, Screen_EoB *screen, const Config *config);
+ ~DarkmoonSequenceHelper();
+
+ void loadScene(int index, int pageNum);
+ void animCommand(int index, int del = -1);
+
+ void printText(int index, int color);
+ void fadeText();
+
+ void update(int srcPage);
+
+ void setPalette(int index);
+ void fadePalette(int index, int del);
+ void copyPalette(int srcIndex, int destIndex);
+
+ void initDelayedPaletteFade(int palIndex, int rate);
+ bool processDelayedPaletteFade();
+
+ void delay(uint32 ticks);
+ void waitForSongNotifier(int index, bool introUpdateAnim = false);
+
+private:
+ void setPaletteWithoutTextColor(int index);
+
+ OSystem *_system;
+ DarkMoonEngine *_vm;
+ Screen_EoB *_screen;
+ const Config *_config;
+
+ Palette *_palettes[12];
+
+ const uint8 **_shapes;
+
+ uint32 _fadePalTimer;
+ int _fadePalRate;
+ int _fadePalIndex;
+};
+
+int DarkMoonEngine::mainMenu() {
+ int menuChoice = _menuChoiceInit;
+ _menuChoiceInit = 0;
+
+ _sound->loadSoundFile("INTRO");
+ Screen::FontId of = _screen->_currentFont;
+ int op = 0;
+ Common::SeekableReadStream *s = 0;
+
+ while (menuChoice >= 0 && !shouldQuit()) {
+ switch (menuChoice) {
+ case 0: {
+ s = _res->createReadStream("XENU.CPS");
+ if (s) {
+ s->read(_screen->getPalette(0).getData(), 768);
+ _screen->loadFileDataToPage(s, 3, 64000);
+ delete s;
+ } else {
+ _screen->loadBitmap("MENU.CPS", 3, 3, &_screen->getPalette(0));
+ }
+
+ if (_configRenderMode == Common::kRenderEGA)
+ _screen->loadPalette("MENU.EGA", _screen->getPalette(0));
+
+ _screen->setScreenPalette(_screen->getPalette(0));
+ _screen->convertPage(3, 2, 0);
+
+ of = _screen->setFont(Screen::FID_6_FNT);
+ op = _screen->setCurPage(2);
+ Common::String versionString(Common::String::format("ScummVM %s", gScummVMVersion));
+ _screen->printText(versionString.c_str(), 267 - versionString.size() * 6, 160, 13, 0);
+ _screen->setFont(of);
+ _screen->_curPage = op;
+ _screen->copyRegion(0, 0, 0, 0, 320, 200, 2, 0, Screen::CR_NO_P_CHECK);
+ _screen->updateScreen();
+ _allowImport = true;
+ menuChoice = mainMenuLoop();
+ _allowImport = false;
+ } break;
+
+ case 1:
+ // load game in progress
+ menuChoice = -1;
+ break;
+
+ case 2:
+ // create new party
+ menuChoice = -2;
+ break;
+
+ case 3:
+ // transfer party
+ //seq_playFinale();
+ menuChoice = -3;
+ break;
+
+ case 4:
+ // play intro
+ seq_playIntro();
+ menuChoice = 0;
+ break;
+
+ case 5:
+ // quit
+ menuChoice = -5;
+ break;
+ }
+ }
+
+ return shouldQuit() ? -5 : menuChoice;
+}
+
+int DarkMoonEngine::mainMenuLoop() {
+ int sel = -1;
+ do {
+ _screen->setScreenDim(6);
+ _gui->simpleMenu_setup(6, 0, _mainMenuStrings, -1, 0, 0);
+
+ while (sel == -1 && !shouldQuit())
+ sel = _gui->simpleMenu_process(6, _mainMenuStrings, 0, -1, 0);
+ } while ((sel < 0 || sel > 5) && !shouldQuit());
+
+ return sel + 1;
+}
+
+void DarkMoonEngine::seq_playIntro() {
+ DarkmoonSequenceHelper::Config config(DarkmoonSequenceHelper::kIntro, _introStrings, _cpsFilesIntro, _configRenderMode == Common::kRenderEGA ? _palFilesIntroEGA : _palFilesIntroVGA, _shapesIntro, _animIntro, false);
+ DarkmoonSequenceHelper sq(_system, this, _screen, &config);
+
+ _screen->setCurPage(0);
+ _screen->clearCurPage();
+
+ snd_stopSound();
+
+ sq.loadScene(4, 2);
+ sq.loadScene(0, 2);
+ sq.delay(1);
+
+ if (!skipFlag() && !shouldQuit())
+ snd_playSong(12);
+
+ _screen->copyRegion(0, 0, 8, 8, 304, 128, 2, 0, Screen::CR_NO_P_CHECK);
+ sq.setPalette(9);
+ sq.fadePalette(0, 3);
+
+ _screen->setCurPage(2);
+ _screen->setClearScreenDim(17);
+ _screen->setCurPage(0);
+
+ removeInputTop();
+ sq.delay(18);
+
+ sq.animCommand(3, 18);
+ sq.animCommand(6, 18);
+ sq.animCommand(0);
+
+ sq.waitForSongNotifier(1);
+
+ sq.animCommand(_configRenderMode == Common::kRenderEGA ? 12 : 11);
+ sq.animCommand(7, 6);
+ sq.animCommand(2, 6);
+
+ sq.waitForSongNotifier(2);
+
+ sq.animCommand(_configRenderMode == Common::kRenderEGA ? 39 : 38);
+ sq.animCommand(3);
+ sq.animCommand(8);
+ sq.animCommand(1, 10);
+ sq.animCommand(0, 6);
+ sq.animCommand(2);
+
+ sq.waitForSongNotifier(3);
+
+ _screen->setClearScreenDim(17);
+ _screen->setCurPage(2);
+ _screen->setClearScreenDim(17);
+ _screen->setCurPage(0);
+
+ sq.animCommand(_configRenderMode == Common::kRenderEGA ? 41 : 40);
+ sq.animCommand(7, 18);
+
+ sq.printText(0, 16); // You were settling...
+ sq.animCommand(7, 90);
+ sq.fadeText();
+
+ sq.printText(1, 16); // Then a note was slipped to you
+ sq.animCommand(8);
+ sq.animCommand(2, 72);
+ sq.fadeText();
+
+ sq.printText(2, 16); // It was from your friend Khelben Blackstaff...
+ sq.animCommand(2);
+ sq.animCommand(6, 36);
+ sq.animCommand(3);
+ sq.fadeText();
+
+ sq.printText(3, 16); // The message was urgent.
+
+ sq.loadScene(1, 2);
+ sq.waitForSongNotifier(4);
+
+ // intro scroll
+ if (!skipFlag() && !shouldQuit()) {
+ if (_configRenderMode == Common::kRenderEGA) {
+ for (int i = 0; i < 35; i++) {
+ uint32 endtime = _system->getMillis() + 2 * _tickLength;
+ _screen->copyRegion(16, 8, 8, 8, 296, 128, 0, 0, Screen::CR_NO_P_CHECK);
+ _screen->copyRegion(i << 3, 0, 304, 8, 8, 128, 2, 0, Screen::CR_NO_P_CHECK);
+ _screen->updateScreen();
+ if (i == 12)
+ sq.animCommand(42);
+ else if (i == 25)
+ snd_playSoundEffect(11);
+ delayUntil(endtime);
+ }
+ } else {
+ for (int i = 0; i < 280; i += 3) {
+ uint32 endtime = _system->getMillis() + _tickLength;
+ _screen->copyRegion(11, 8, 8, 8, 301, 128, 0, 0, Screen::CR_NO_P_CHECK);
+ _screen->copyRegion(i, 0, 309, 8, 3, 128, 2, 0, Screen::CR_NO_P_CHECK);
+ _screen->updateScreen();
+ if (i == 96)
+ sq.animCommand(42);
+ delayUntil(endtime);
+ }
+ }
+ }
+
+ _screen->copyRegion(8, 8, 0, 0, 304, 128, 0, 2, Screen::CR_NO_P_CHECK);
+ sq.animCommand(4);
+ sq.fadeText();
+ sq.delay(10);
+
+ sq.loadScene(2, 2);
+ sq.update(2);
+ sq.delay(10);
+
+ sq.printText(4, 16); // What could Khelben want?
+ sq.delay(25);
+
+ sq.loadScene(3, 2);
+ sq.delay(54);
+ sq.animCommand(13);
+ _screen->copyRegion(104, 16, 96, 8, 120, 100, 0, 2, Screen::CR_NO_P_CHECK);
+ sq.fadeText();
+
+ sq.printText(5, 15); // Welcome, please come in
+ sq.animCommand(10);
+ sq.animCommand(10);
+ sq.animCommand(9);
+ sq.animCommand(9);
+ sq.fadeText();
+
+ sq.printText(6, 15); // Khelben awaits you in his study
+ for (int i = 0; i < 3; i++)
+ sq.animCommand(10);
+ sq.animCommand(9);
+ sq.animCommand(14);
+ sq.loadScene(5, 2);
+
+ sq.waitForSongNotifier(5);
+
+ sq.fadeText();
+ _screen->clearCurPage();
+ _screen->updateScreen();
+
+ for (int i = 0; i < 6; i++)
+ sq.animCommand(15);
+
+ if (_configRenderMode == Common::kRenderEGA && !skipFlag() && !shouldQuit()) {
+ _screen->loadPalette("INTRO.EGA", _screen->getPalette(0));
+ _screen->setScreenPalette(_screen->getPalette(0));
+ }
+
+ sq.loadScene(6, 2);
+ sq.loadScene(7, 2);
+ _screen->clearCurPage();
+ sq.update(2);
+
+ sq.animCommand(16);
+ sq.printText(7, 15); // Thank you for coming so quickly
+ sq.animCommand(16);
+ sq.animCommand(17);
+ for (int i = 0; i < 3; i++)
+ sq.animCommand(16);
+ sq.fadeText();
+ sq.animCommand(16);
+
+ sq.loadScene(8, 2);
+ sq.update(2);
+ sq.animCommand(32);
+ sq.printText(8, 15); // I am troubled my friend
+ sq.animCommand(33);
+ sq.animCommand(33);
+ for (int i = 0; i < 4; i++)
+ sq.animCommand(32);
+ sq.fadeText();
+
+ sq.printText(9, 15); // Ancient evil stirs in the Temple Darkmoon
+ sq.animCommand(33);
+ sq.animCommand(43);
+ sq.animCommand(33);
+ for (int i = 0; i < 3; i++)
+ sq.animCommand(32);
+ sq.fadeText();
+
+ sq.printText(10, 15); // I fear for the safety of our city
+ for (int i = 0; i < 4; i++)
+ sq.animCommand(33);
+ sq.animCommand(32);
+ sq.animCommand(32);
+
+ sq.loadScene(9, 2);
+ sq.fadeText();
+
+ sq.waitForSongNotifier(6);
+
+ sq.update(2);
+ sq.animCommand(34);
+
+ sq.printText(11, 15); // I need your help
+ for (int i = 0; i < 3; i++)
+ sq.animCommand(34);
+ sq.animCommand(35);
+ for (int i = 0; i < 4; i++)
+ sq.animCommand(34);
+ sq.fadeText();
+
+ sq.loadScene(12, 2);
+ sq.update(2);
+ sq.loadScene(6, 2);
+ sq.animCommand(18);
+
+ sq.printText(12, 15); // Three nights ago I sent forth a scout
+ sq.animCommand(19);
+ sq.animCommand(20);
+ sq.animCommand(22);
+ sq.animCommand(19);
+ sq.animCommand(20);
+ sq.animCommand(18);
+ sq.fadeText();
+
+ sq.printText(13, 15); // She has not yet returned
+ sq.animCommand(20);
+ sq.animCommand(19);
+ sq.animCommand(23);
+ sq.animCommand(24);
+ sq.animCommand(20);
+ sq.animCommand(19);
+ sq.animCommand(17);
+ sq.animCommand(18);
+ sq.fadeText();
+
+ sq.printText(14, 15); // I fear for her safety
+ sq.animCommand(19);
+ sq.animCommand(20);
+ sq.animCommand(20);
+ sq.animCommand(18);
+ sq.animCommand(25);
+ sq.animCommand(18);
+ sq.animCommand(18);
+ sq.fadeText();
+ sq.animCommand(18);
+ sq.animCommand(18);
+
+ sq.printText(15, 15); // Take this coin
+ sq.animCommand(28);
+ sq.animCommand(19);
+ sq.animCommand(20);
+ sq.animCommand(18);
+ sq.animCommand(18);
+ sq.fadeText();
+
+ sq.loadScene(10, 2);
+ _screen->clearCurPage();
+ _screen->updateScreen();
+
+ sq.animCommand(37, 18);
+ sq.animCommand(36, 36);
+
+ sq.loadScene(12, 2);
+ _screen->clearCurPage();
+ sq.update(2);
+
+ sq.loadScene(11, 2);
+ sq.printText(16, 15); // I will use it to contact you
+ sq.animCommand(19);
+ sq.animCommand(20);
+ sq.animCommand(20);
+ sq.animCommand(18);
+ sq.animCommand(18);
+ sq.fadeText();
+
+ sq.printText(17, 15); // You must act quickly
+ sq.animCommand(19);
+ sq.animCommand(20);
+ sq.animCommand(19);
+ sq.animCommand(18);
+ sq.animCommand(18);
+ sq.fadeText();
+ sq.animCommand(18);
+
+ sq.printText(18, 15); // I will teleport you near Darkmoon
+ sq.animCommand(20);
+ sq.animCommand(27);
+ sq.animCommand(20);
+ sq.animCommand(19);
+ sq.animCommand(18);
+ sq.animCommand(18);
+ sq.fadeText();
+ sq.animCommand(18);
+
+ sq.printText(19, 15); // May luck be with you my friend
+ sq.animCommand(19);
+ sq.animCommand(19);
+ sq.animCommand(20);
+ sq.animCommand(18);
+ sq.fadeText();
+ sq.animCommand(29);
+
+ sq.waitForSongNotifier(7);
+
+ sq.animCommand(30);
+ sq.animCommand(31);
+
+ sq.waitForSongNotifier(8, true);
+
+ if (skipFlag() || shouldQuit()) {
+ snd_fadeOut();
+ } else {
+ _screen->setScreenDim(17);
+ _screen->clearCurDim();
+ snd_playSoundEffect(14);
+
+ if (_configRenderMode != Common::kRenderEGA)
+ sq.fadePalette(10, 1);
+ _screen->setClearScreenDim(18);
+ sq.delay(6);
+ if (_configRenderMode != Common::kRenderEGA)
+ sq.fadePalette(9, 1);
+ _screen->clearCurPage();
+ }
+ sq.fadePalette(9, 10);
+}
+
+void DarkMoonEngine::seq_playFinale() {
+ DarkmoonSequenceHelper::Config config(DarkmoonSequenceHelper::kFinale, _finaleStrings, _cpsFilesFinale, _configRenderMode == Common::kRenderEGA ? _palFilesFinaleEGA : _palFilesFinaleVGA, _shapesFinale, _animFinale, true);
+ DarkmoonSequenceHelper sq(_system, this, _screen, &config);
+
+ _screen->setCurPage(0);
+ _screen->setFont(Screen::FID_8_FNT);
+
+ _sound->loadSoundFile("FINALE1");
+ snd_stopSound();
+ sq.delay(3);
+
+ _screen->clearCurPage();
+ _screen->updateScreen();
+
+ sq.loadScene(0, 2);
+ sq.delay(18);
+
+ if (!skipFlag() && !shouldQuit())
+ snd_playSong(1);
+ sq.update(2);
+
+ sq.loadScene(1, 2);
+
+ sq.animCommand(0);
+ sq.animCommand(0);
+ for (int i = 0; i < 3; i++)
+ sq.animCommand(2);
+ sq.animCommand(1);
+ sq.animCommand(2);
+ sq.animCommand(2);
+
+ sq.printText(0, 10); // Finally, Dran has been defeated
+ for (int i = 0; i < 7; i++)
+ sq.animCommand(2);
+ sq.fadeText();
+ sq.animCommand(2);
+
+ sq.waitForSongNotifier(1);
+
+ sq.printText(1, 10); // Suddenly, your friend Khelben appears
+ sq.animCommand(4);
+ for (int i = 0; i < 3; i++)
+ sq.animCommand(2);
+ sq.fadeText();
+
+ sq.printText(2, 15); // Greetings, my victorious friends
+ for (int i = 0; i < 4; i++)
+ sq.animCommand(5);
+ sq.animCommand(2);
+ sq.animCommand(2);
+ sq.fadeText();
+ sq.animCommand(6);
+
+ sq.printText(3, 15); // You have defeated Dran
+ for (int i = 0; i < 5; i++)
+ sq.animCommand(5);
+ sq.animCommand(2);
+ sq.animCommand(2);
+ sq.fadeText();
+
+ sq.printText(4, 15); // I did not know Dran was a dragon
+ for (int i = 0; i < 4; i++)
+ sq.animCommand(5);
+ sq.animCommand(2);
+ sq.animCommand(2);
+ sq.fadeText();
+
+ sq.printText(5, 15); // He must have been over 300 years old
+ for (int i = 0; i < 4; i++)
+ sq.animCommand(5);
+ sq.animCommand(2);
+ sq.animCommand(2);
+ sq.fadeText();
+
+ sq.printText(6, 15); // His power is gone
+ for (int i = 0; i < 3; i++)
+ sq.animCommand(5);
+ sq.animCommand(2);
+ sq.animCommand(2);
+ sq.fadeText();
+
+ sq.printText(7, 15); // But Darkmoon is still a source of great evil
+ for (int i = 0; i < 4; i++)
+ sq.animCommand(5);
+ sq.animCommand(2);
+ sq.animCommand(2);
+ sq.fadeText();
+
+ sq.printText(8, 15); // And many of his minions remain
+ for (int i = 0; i < 4; i++)
+ sq.animCommand(5);
+ sq.animCommand(2);
+ sq.animCommand(2);
+ sq.fadeText();
+
+ sq.loadScene(2, 2);
+ sq.update(2);
+ sq.loadScene(3, 2);
+ _screen->copyRegion(8, 8, 0, 0, 304, 128, 0, 2, Screen::CR_NO_P_CHECK);
+
+ sq.printText(9, 15); // Now we must leave this place
+ sq.animCommand(7);
+ sq.animCommand(8);
+ sq.animCommand(7);
+ sq.animCommand(7, 36);
+ sq.fadeText();
+
+ sq.printText(10, 15); // So my forces can destroy it..
+ for (int i = 0; i < 3; i++)
+ sq.animCommand(7);
+ sq.animCommand(8);
+ sq.animCommand(7);
+ sq.animCommand(7, 36);
+ sq.animCommand(8, 18);
+ sq.fadeText();
+
+ sq.printText(11, 15); // Follow me
+ sq.animCommand(7, 18);
+ sq.animCommand(9, 18);
+ sq.animCommand(8, 18);
+ sq.fadeText();
+
+ sq.loadScene(7, 2);
+
+ if (_configRenderMode != Common::kRenderEGA)
+ sq.copyPalette(3, 0);
+
+ sq.loadScene(4, 2);
+
+ sq.waitForSongNotifier(2);
+
+ _screen->clearCurPage();
+ sq.update(2);
+
+ sq.loadScene(8, 2);
+ sq.loadScene(6, 6);
+ sq.delay(10);
+
+ sq.printText(12, 10); // Powerful mages stand ready for the final assault...
+ sq.delay(90);
+ sq.fadeText();
+
+ sq.waitForSongNotifier(3);
+
+ if (!skipFlag() && !shouldQuit())
+ snd_playSoundEffect(7);
+ sq.delay(8);
+
+ sq.animCommand(10);
+ sq.animCommand(13);
+ sq.initDelayedPaletteFade(4, 1);
+
+ sq.animCommand(14);
+ sq.animCommand(13);
+ sq.animCommand(14);
+ sq.animCommand(14);
+ sq.animCommand(13);
+ sq.initDelayedPaletteFade(2, 1);
+
+ sq.animCommand(15);
+ sq.animCommand(14);
+ sq.animCommand(13);
+ sq.animCommand(15);
+ sq.animCommand(15);
+ sq.animCommand(11);
+
+ sq.printText(13, 10); // The temple's evil is very strong
+ sq.delay(72);
+ sq.fadeText();
+
+ sq.printText(14, 10); // It must not be allowed...
+ sq.delay(72);
+ sq.fadeText();
+
+ sq.waitForSongNotifier(4);
+
+ if (!skipFlag() && !shouldQuit())
+ snd_playSoundEffect(7);
+ sq.delay(8);
+
+ sq.animCommand(10);
+ sq.initDelayedPaletteFade(5, 1);
+ sq.animCommand(13);
+ sq.animCommand(14);
+ sq.animCommand(13);
+ sq.animCommand(14);
+ sq.animCommand(13);
+ sq.animCommand(13);
+ sq.animCommand(14);
+ sq.animCommand(14);
+ sq.animCommand(13);
+ sq.animCommand(12);
+ for (int i = 0; i < 4; i++)
+ sq.animCommand(16);
+ sq.animCommand(17);
+ sq.animCommand(18);
+
+ sq.printText(15, 10); // The temple ceases to exist
+ sq.initDelayedPaletteFade(6, 1);
+ sq.delay(36);
+
+ if (!skipFlag() && !shouldQuit())
+ snd_playSoundEffect(11);
+
+ sq.delay(54);
+ sq.fadeText();
+ sq.loadScene(12, 2);
+
+ sq.waitForSongNotifier(5);
+
+ if (!skipFlag() && !shouldQuit())
+ snd_playSoundEffect(6);
+
+ if (!skipFlag() && !shouldQuit()) {
+ if (_configRenderMode != Common::kRenderEGA)
+ sq.setPaletteWithoutTextColor(0);
+ _screen->crossFadeRegion(0, 0, 8, 8, 304, 128, 2, 0);
+ }
+ sq.delay(18);
+
+ sq.printText(16, 15); // My friends, our work is done
+ sq.animCommand(20);
+ sq.animCommand(19);
+ sq.animCommand(19, 36);
+ if (!skipFlag() && !shouldQuit())
+ snd_playSoundEffect(12);
+ sq.fadeText();
+
+ sq.printText(17, 15); // Thank you
+ sq.animCommand(19);
+ sq.animCommand(20, 36);
+ sq.fadeText();
+
+ sq.printText(18, 15); // You have earned my deepest respect
+ if (!skipFlag() && !shouldQuit())
+ snd_playSoundEffect(11);
+ sq.animCommand(20);
+ sq.animCommand(19);
+ sq.animCommand(19);
+ if (!skipFlag() && !shouldQuit())
+ snd_playSoundEffect(11);
+ sq.delay(36);
+ sq.fadeText();
+
+ sq.printText(19, 15); // We will remember you always
+ sq.animCommand(19);
+ sq.animCommand(19, 18);
+ if (!skipFlag() && !shouldQuit())
+ snd_playSoundEffect(11);
+ sq.animCommand(20, 18);
+ sq.fadeText();
+
+ sq.delay(28);
+ if (!skipFlag() && !shouldQuit())
+ snd_playSoundEffect(12);
+ sq.delay(3);
+
+ sq.loadScene(5, 2);
+ if (skipFlag() || shouldQuit()) {
+ _screen->copyRegion(0, 0, 8, 8, 304, 128, 2, 0, Screen::CR_NO_P_CHECK);
+ } else {
+ snd_playSoundEffect(6);
+ if (_configRenderMode != Common::kRenderEGA)
+ sq.setPaletteWithoutTextColor(0);
+ _screen->crossFadeRegion(0, 0, 8, 8, 304, 128, 2, 0);
+ }
+
+ if (!skipFlag() && !shouldQuit())
+ snd_playSoundEffect(12);
+ sq.delay(5);
+ if (!skipFlag() && !shouldQuit())
+ snd_playSoundEffect(11);
+ sq.delay(11);
+ if (!skipFlag() && !shouldQuit())
+ snd_playSoundEffect(12);
+ sq.delay(7);
+ if (!skipFlag() && !shouldQuit())
+ snd_playSoundEffect(11);
+ sq.delay(12);
+ if (!skipFlag() && !shouldQuit())
+ snd_playSoundEffect(12);
+
+ removeInputTop();
+ resetSkipFlag(true);
+
+ sq.loadScene(10, 2);
+ sq.loadScene(9, 2);
+ snd_stopSound();
+ sq.delay(3);
+
+ _sound->loadSoundFile("FINALE2");
+
+ sq.delay(18);
+ if (!skipFlag() && !shouldQuit())
+ snd_playSong(1);
+
+ seq_playCredits(&sq, _creditsData, 18, 2, 6, 2);
+
+ sq.delay(90);
+
+ resetSkipFlag(true);
+
+ if (_configRenderMode != Common::kRenderEGA) {
+ sq.setPalette(11);
+ sq.fadePalette(9, 10);
+ }
+
+ _screen->clearCurPage();
+ sq.loadScene(11, 2);
+
+ static const uint8 finPortraitPos[] = { 0x50, 0x50, 0xD0, 0x50, 0x50, 0x90, 0xD0, 0x90, 0x90, 0x50, 0x90, 0x90 };
+
+ for (int i = 0; i < 6; i++) {
+ if (!testCharacter(i, 1))
+ continue;
+ if (i > 3)
+ _screen->drawShape(2, sq._shapes[6 + i], finPortraitPos[i << 1] - 16, finPortraitPos[(i << 1) + 1] - 16, 0);
+ _screen->drawShape(2, _characters[i].faceShape, finPortraitPos[i << 1], finPortraitPos[(i << 1) + 1], 0);
+ }
+
+ _screen->copyRegion(0, 0, 0, 0, 320, 200, 2, 0, Screen::CR_NO_P_CHECK);
+
+ sq.setPalette(9);
+ sq.fadePalette(0, 18);
+
+ while (!skipFlag() && !shouldQuit())
+ delay(_tickLength);
+
+ snd_stopSound();
+ sq.fadePalette(9, 10);
+}
+
+void DarkMoonEngine::seq_playCredits(DarkmoonSequenceHelper *sq, const uint8 *data, int sd, int backupPage, int tempPage, int speed) {
+ if (!data)
+ return;
+
+ _screen->setScreenDim(sd);
+ const ScreenDim *dm = _screen->_curDim;
+
+ _screen->copyRegion(dm->sx << 3, dm->sy, dm->sx << 3, dm->sy, dm->w << 3, dm->h, 0, backupPage, Screen::CR_NO_P_CHECK);
+
+ struct CreditsDataItem {
+ int16 x;
+ int16 y;
+ const void *data;
+ char *str;
+ uint8 crlf;
+ uint8 size;
+ uint8 dataType;
+ } items[36];
+ memset(items, 0, sizeof(items));
+
+ const char *pos = (const char *)data;
+ uint32 end = _system->getMillis();
+ uint32 cur = 0;
+ int i = 0;
+
+ do {
+ for (bool loop = true; loop;) {
+ sq->processDelayedPaletteFade();
+ cur = _system->getMillis();
+ if (end <= cur)
+ break;
+ delay(MIN<uint32>(_tickLength, end - cur));
+ }
+
+ end = _system->getMillis() + speed * _tickLength;
+
+ for (; i < 35 && *pos; i++) {
+ int16 nextY = i ? items[i].y + items[i].size + (items[i].size >> 2) : dm->h;
+
+ const char *posOld = pos;
+ pos = strchr(pos, 0x0d);
+ if (!pos)
+ pos = strchr(posOld, 0x00);
+
+ items[i + 1].crlf = *pos++;
+
+ if (*posOld == 2) {
+ const uint8 *shp = sq->_shapes[(*++posOld) - 1];
+ items[i + 1].data = shp;
+ items[i + 1].size = shp[1];
+ items[i + 1].x = (dm->w - shp[2]) << 2 ;
+ items[i + 1].dataType = 1;
+ delete[] items[i + 1].str;
+ items[i + 1].str = 0;
+
+ } else {
+ if (*posOld == 1) {
+ posOld++;
+ items[i + 1].size = 6;
+ } else {
+ items[i + 1].size = _screen->getFontWidth();
+ }
+
+ items[i + 1].dataType = 0;
+
+ int l = pos - posOld;
+ if (items[i + 1].crlf != 0x0d)
+ l++;
+
+ delete[] items[i + 1].str;
+ items[i + 1].str = new char[l];
+ memcpy(items[i + 1].str, posOld, l);
+ items[i + 1].str[l - 1] = 0;
+ items[i + 1].data = 0;
+ items[i + 1].x = (((dm->w << 3) - (strlen(items[i + 1].str) * items[i + 1].size)) >> 1) + 1;
+ }
+
+ items[i + 1].y = nextY;
+ }
+
+ _screen->copyRegion(dm->sx << 3, dm->sy, dm->sx << 3, dm->sy, dm->w << 3, dm->h, backupPage, tempPage, Screen::CR_NO_P_CHECK);
+
+ for (int h = 0; h < i; h++) {
+ if (items[h + 1].y < dm->h) {
+ if (items[h + 1].dataType == 1) {
+ _screen->drawShape(tempPage, (const uint8 *)items[h + 1].data, items[h + 1].x, items[h + 1].y, sd);
+ } else {
+ _screen->setCurPage(tempPage);
+
+ if (items[h + 1].size == 6)
+ _screen->setFont(Screen::FID_6_FNT);
+
+ _screen->printText(items[h + 1].str, (dm->sx << 3) + items[h + 1].x - 1, dm->sy + items[h + 1].y + 1, 12, 0);
+ _screen->printText(items[h + 1].str, (dm->sx << 3) + items[h + 1].x, dm->sy + items[h + 1].y, 240, 0);
+
+ if (items[h + 1].size == 6)
+ _screen->setFont(Screen::FID_8_FNT);
+
+ _screen->setCurPage(0);
+ }
+ }
+
+ items[h + 1].y -= 2;
+ }
+
+ _screen->copyRegion(dm->sx << 3, dm->sy, dm->sx << 3, dm->sy, dm->w << 3, dm->h, tempPage, 0, Screen::CR_NO_P_CHECK);
+ _screen->updateScreen();
+
+ if (-items[1].size > items[1].y) {
+ delete[] items[1].str;
+ --i;
+ for (int t = 1; t <= i; t++)
+ memcpy(&items[t], &items[t + 1], sizeof(CreditsDataItem));
+ items[i + 1].str = 0;
+ }
+
+ if (i < 35 && ((items[i].y + items[i].size) < (dm->sy + dm->h))) {
+ resetSkipFlag(true);
+ break;
+ }
+
+ sq->processDelayedPaletteFade();
+ } while (!skipFlag() && i && !shouldQuit());
+
+ for (i = 0; i < 35; i++)
+ delete[] items[i].str;
+}
+
+DarkmoonSequenceHelper::DarkmoonSequenceHelper(OSystem *system, DarkMoonEngine *vm, Screen_EoB *screen, const Config *config) :
+ _system(system), _vm(vm), _screen(screen), _config(config) {
+
+ for (int i = 0; _config->palFiles[i]; i++) {
+ if (i < 4)
+ _palettes[i] = &_screen->getPalette(i);
+ else
+ _palettes[i] = new Palette(256);
+ _screen->loadPalette(_config->palFiles[i], *_palettes[i]);
+ }
+
+ _palettes[9] = new Palette(256);
+ _palettes[9]->fill(0, 256, 0);
+ _palettes[10] = new Palette(256);
+ _palettes[10]->fill(0, 256, 63);
+ _palettes[11] = new Palette(256);
+ _palettes[11]->fill(0, 256, 0);
+
+ _shapes = new const uint8*[30];
+ memset(_shapes, 0, 30 * sizeof(uint8 *));
+
+ _fadePalTimer = 0;
+ _fadePalRate = 0;
+
+ _screen->setScreenPalette(*_palettes[0]);
+ _screen->setFont(Screen::FID_8_FNT);
+ _screen->hideMouse();
+
+ _vm->delay(150);
+ _vm->_eventList.clear();
+ _vm->_allowSkip = true;
+}
+
+DarkmoonSequenceHelper::~DarkmoonSequenceHelper() {
+ for (int i = 4; _config->palFiles[i]; i++)
+ delete _palettes[i];
+ delete _palettes[9];
+ delete _palettes[10];
+ delete _palettes[11];
+
+ for (int i = 0; i < 30; i++)
+ delete[] _shapes[i];
+ delete[] _shapes;
+
+ _screen->clearCurPage();
+ _screen->showMouse();
+ _screen->updateScreen();
+
+ _system->delayMillis(150);
+ _vm->resetSkipFlag(true);
+ _vm->_allowSkip = false;
+}
+
+void DarkmoonSequenceHelper::loadScene(int index, int pageNum) {
+ char file[13];
+ strcpy(file, _config->cpsFiles[index]);
+
+ Common::SeekableReadStream *s = _vm->resource()->createReadStream(file);
+ uint32 chunkID = 0;
+ if (s) {
+ chunkID = s->readUint32LE();
+ s->seek(0);
+ }
+
+ if (s && chunkID == MKTAG('F', 'O', 'R', 'M')) {
+ // The original code also handles files with FORM chunks and ILBM and PBM sub chunks. This will probably be necessary for Amiga versions.
+ // The DOS versions do not need this, but still have the code for it. We error out for now.
+ error("DarkmoonSequenceHelper::loadScene(): CPS file loading failure in scene %d - unhandled FORM chunk encountered", index);
+ } else if (s && file[0] != 'X') {
+ delete s;
+ _screen->loadBitmap(_config->cpsFiles[index], pageNum | 1, pageNum | 1, _palettes[0]);
+ } else {
+ if (!s) {
+ file[0] = 'X';
+ s = _vm->resource()->createReadStream(file);
+ }
+
+ if (!s)
+ error("DarkmoonSequenceHelper::loadScene(): CPS file loading failure in scene %d", index);
+
+ if (_config->mode == kFinale)
+ s->read(_palettes[0]->getData(), 768);
+ else
+ s->seek(768);
+ _screen->loadFileDataToPage(s, 3, 64000);
+ delete s;
+ }
+
+ int cp = _screen->setCurPage(pageNum);
+
+ if (_config->shapeDefs[index]) {
+ for (const DarkMoonShapeDef *df = _config->shapeDefs[index]; df->w; df++) {
+ uint16 shapeIndex = (df->index < 0) ? df->index * -1 : df->index;
+ if (_shapes[shapeIndex])
+ delete[] _shapes[shapeIndex];
+ _shapes[shapeIndex] = _screen->encodeShape(df->x, df->y, df->w, df->h, (df->index >> 8) != 0);
+ }
+ }
+
+ _screen->setCurPage(cp);
+
+ if (_vm->_configRenderMode == Common::kRenderEGA)
+ setPalette(0);
+
+ _screen->convertPage(pageNum | 1, pageNum, 0);
+
+ if ((pageNum == 0 || pageNum == 1) && !_vm->skipFlag() && !_vm->shouldQuit())
+ _screen->updateScreen();
+}
+
+void DarkmoonSequenceHelper::animCommand(int index, int del) {
+ if (_vm->skipFlag() || _vm->shouldQuit())
+ return;
+
+ uint32 end = 0;
+
+ for (const DarkMoonAnimCommand *s = _config->animData[index]; s->command != 0xff && !_vm->skipFlag() && !_vm->shouldQuit(); s++) {
+ int palIndex = _config->mode == kFinale ? (s->pal + 1) : s->pal;
+ int x = s->x1;
+ int y = s->y1;
+ int x2 = 0;
+ uint16 shapeW = 0;
+ uint16 shapeH = 0;
+
+ switch (s->command) {
+ case 0:
+ // flash palette
+ if (_vm->_configRenderMode != Common::kRenderEGA && s->pal)
+ setPaletteWithoutTextColor(palIndex);
+ delay(s->delay);
+ if (_vm->_configRenderMode != Common::kRenderEGA && _config->mode == kIntro && s->pal)
+ setPaletteWithoutTextColor(0);
+ break;
+
+ case 1:
+ // draw shape, then restore background
+ shapeW = _shapes[s->obj][2];
+ shapeH = _shapes[s->obj][3];
+
+ if (_config->mode == kFinale) {
+ _screen->setScreenDim(18);
+ x -= (_screen->_curDim->sx << 3);
+ y -= _screen->_curDim->sy;
+ if (x < 0)
+ shapeW -= ((-x >> 3) + 1);
+ else
+ x2 = x;
+ }
+
+ _screen->drawShape(0, _shapes[s->obj], x, y, _config->mode == kIntro ? 0 : 18);
+
+ if (_vm->_configRenderMode != Common::kRenderEGA && s->pal)
+ setPaletteWithoutTextColor(palIndex);
+ else
+ _screen->updateScreen();
+
+ delay(s->delay);
+
+ if (_config->mode == kIntro) {
+ if (_vm->_configRenderMode != Common::kRenderEGA && s->pal)
+ setPaletteWithoutTextColor(0);
+ _screen->copyRegion(x - 8, y - 8, x, y, (shapeW + 1) << 3, shapeH, 2, 0, Screen::CR_NO_P_CHECK);
+ } else {
+ _screen->copyRegion(x2, y, x2 + (_screen->_curDim->sx << 3), y + _screen->_curDim->sy, (shapeW + 1) << 3, shapeH, 2, 0, Screen::CR_NO_P_CHECK);
+ }
+
+ _screen->updateScreen();
+ break;
+
+ case 2:
+ // draw shape
+ _screen->drawShape(_screen->_curPage, _shapes[s->obj], x, y, 0);
+
+ if (_vm->_configRenderMode != Common::kRenderEGA && s->pal)
+ setPaletteWithoutTextColor(palIndex);
+ else if (!_screen->_curPage)
+ _screen->updateScreen();
+
+ delay(s->delay);
+
+ if (_vm->_configRenderMode != Common::kRenderEGA && _config->mode == kIntro && s->pal)
+ setPaletteWithoutTextColor(0);
+ break;
+
+ case 3:
+ case 4:
+ // fade shape in or out or restore background
+ if (_config->mode == kFinale)
+ break;
+
+ if (_vm->_configRenderMode == Common::kRenderEGA) {
+ if (palIndex)
+ _screen->drawShape(0, _shapes[s->obj], s->x1, y, 0);
+ else
+ _screen->copyRegion(s->x1 - 8, s->y1 - 8, s->x1, s->y1, (_shapes[s->obj][2] + 1) << 3, _shapes[s->obj][3], 2, 0, Screen::CR_NO_P_CHECK);
+ _screen->updateScreen();
+ delay(s->delay /** 7*/);
+ } else {
+ _screen->setShapeFadeMode(0, true);
+ _screen->setShapeFadeMode(1, true);
+
+ end = _system->getMillis() + s->delay * _vm->tickLength();
+
+ if (palIndex) {
+ _screen->setFadeTableIndex(palIndex - 1);
+
+ _screen->copyRegion(s->x1 - 8, s->y1 - 8, 0, 0, (_shapes[s->obj][2] + 1) << 3, _shapes[s->obj][3], 2, 4, Screen::CR_NO_P_CHECK);
+ _screen->drawShape(4, _shapes[s->obj], s->x1 & 7, 0, 0);
+ _screen->copyRegion(0, 0, s->x1, s->y1, (_shapes[s->obj][2] + 1) << 3, _shapes[s->obj][3], 4, 0, Screen::CR_NO_P_CHECK);
+ } else {
+ _screen->copyRegion(s->x1 - 8, s->y1 - 8, s->x1, s->y1, (_shapes[s->obj][2] + 1) << 3, _shapes[s->obj][3], 2, 0, Screen::CR_NO_P_CHECK);
+ }
+ _screen->updateScreen();
+
+ _vm->delayUntil(end);
+ _screen->setShapeFadeMode(0, false);
+ _screen->setShapeFadeMode(1, false);
+ }
+ break;
+
+ case 5:
+ // copy region
+ if (_config->mode == kFinale && s->pal)
+ setPaletteWithoutTextColor(palIndex);
+
+ _screen->copyRegion(s->x2 << 3, s->y2, s->x1, s->y1, s->w << 3, s->h, (s->obj && _config->mode == kFinale) ? 6 : 2, 0, Screen::CR_NO_P_CHECK);
+ _screen->updateScreen();
+ delay(s->delay);
+ break;
+
+ case 6:
+ // play sound effect
+ if (s->obj != 0xff)
+ _vm->snd_playSoundEffect(s->obj);
+ break;
+
+ case 7:
+ // restore background (only used in EGA mode)
+ delay(s->delay);
+ _screen->copyRegion(s->x1 - 8, s->y1 - 8, s->x1, s->y1, (_shapes[s->obj][2] + 1) << 3, _shapes[s->obj][3], 2, 0, Screen::CR_NO_P_CHECK);
+ _screen->updateScreen();
+ break;
+
+ default:
+ error("DarkmoonSequenceHelper::animCommand(): Unknown animation opcode encountered.");
+ break;
+ }
+ }
+
+ if (del > 0)
+ delay(del);
+}
+
+void DarkmoonSequenceHelper::printText(int index, int color) {
+ if (_vm->skipFlag() || _vm->shouldQuit())
+ return;
+
+ _screen->setClearScreenDim(17);
+ uint8 col1 = 15;
+
+ if (_vm->_configRenderMode != Common::kRenderEGA) {
+ _palettes[0]->copy(*_palettes[0], color, 1, 255);
+ setPalette(0);
+ col1 = 255;
+ }
+
+ char *temp = new char[strlen(_config->strings[index]) + 1];
+ char *str = temp;
+ strcpy(str, _config->strings[index]);
+
+ const ScreenDim *dm = _screen->_curDim;
+
+ for (int yOffs = 0; *str; yOffs += 9) {
+ char *cr = strchr(str, 13);
+
+ if (cr)
+ *cr = 0;
+
+ uint32 len = strlen(str);
+ _screen->printText(str, (dm->sx + ((dm->w - len) >> 1)) << 3, dm->sy + yOffs, col1, dm->unkA);
+
+ if (cr) {
+ *cr = 13;
+ str = cr + 1;
+ } else {
+ str += len;
+ }
+ }
+
+ delete[] temp;
+ _screen->updateScreen();
+}
+
+void DarkmoonSequenceHelper::fadeText() {
+ if (_vm->skipFlag() || _vm->shouldQuit())
+ return;
+ if (_vm->_configRenderMode != Common::kRenderEGA)
+ _screen->fadeTextColor(_palettes[0], 255, 8);
+ _screen->clearCurDim();
+}
+
+void DarkmoonSequenceHelper::update(int srcPage) {
+ if (_vm->skipFlag() || _vm->shouldQuit())
+ return;
+
+ _screen->copyRegion(0, 0, 8, 8, 304, 128, srcPage, 0, Screen::CR_NO_P_CHECK);
+
+ if (_vm->_configRenderMode != Common::kRenderEGA)
+ setPaletteWithoutTextColor(0);
+}
+
+void DarkmoonSequenceHelper::setPaletteWithoutTextColor(int index) {
+ if (_vm->_configRenderMode == Common::kRenderEGA || _vm->skipFlag() || _vm->shouldQuit())
+ return;
+
+ if (!memcmp(_palettes[11]->getData(), _palettes[index]->getData(), 765))
+ return;
+
+ _palettes[11]->copy(*_palettes[index], 0, 255);
+ _palettes[11]->copy(*_palettes[0], 255, 1, 255);
+ setPalette(11);
+
+ _screen->updateScreen();
+ _system->delayMillis(10);
+}
+
+void DarkmoonSequenceHelper::setPalette(int index) {
+ _screen->setScreenPalette(*_palettes[index]);
+}
+
+void DarkmoonSequenceHelper::fadePalette(int index, int del) {
+ if (_vm->skipFlag() || _vm->shouldQuit())
+ return;
+ if (_vm->_configRenderMode == Common::kRenderEGA) {
+ setPalette(index);
+ _screen->updateScreen();
+ } else {
+ _screen->fadePalette(*_palettes[index], del * _vm->tickLength());
+ }
+}
+
+void DarkmoonSequenceHelper::copyPalette(int srcIndex, int destIndex) {
+ _palettes[destIndex]->copy(*_palettes[srcIndex]);
+}
+
+void DarkmoonSequenceHelper::initDelayedPaletteFade(int palIndex, int rate) {
+ _palettes[11]->copy(*_palettes[0]);
+
+ _fadePalIndex = palIndex;
+ _fadePalRate = rate;
+ _fadePalTimer = _system->getMillis() + 2 * _vm->_tickLength;
+}
+
+bool DarkmoonSequenceHelper::processDelayedPaletteFade() {
+ if (_vm->skipFlag() || _vm->shouldQuit())
+ return true;
+
+ if (_vm->_configRenderMode == Common::kRenderEGA || !_fadePalRate || (_system->getMillis() <= _fadePalTimer))
+ return false;
+
+ if (_screen->delayedFadePalStep(_palettes[_fadePalIndex], _palettes[0], _fadePalRate)) {
+ setPaletteWithoutTextColor(0);
+ _fadePalTimer = _system->getMillis() + 3 * _vm->_tickLength;
+ } else {
+ _fadePalRate = 0;
+ }
+
+ return false;
+}
+
+void DarkmoonSequenceHelper::delay(uint32 ticks) {
+ if (_vm->skipFlag() || _vm->shouldQuit())
+ return;
+
+ uint32 end = _system->getMillis() + ticks * _vm->_tickLength;
+
+ if (_config->palFading) {
+ do {
+ if (processDelayedPaletteFade())
+ break;
+ _vm->updateInput();
+ } while (end > _system->getMillis());
+ processDelayedPaletteFade();
+
+ } else {
+ _vm->delayUntil(end);
+ }
+}
+
+void DarkmoonSequenceHelper::waitForSongNotifier(int index, bool introUpdateAnim) {
+ int seq = 0;
+ while (_vm->sound()->checkTrigger() < index && !(_vm->skipFlag() || _vm->shouldQuit())) {
+ if (introUpdateAnim) {
+ animCommand(30 | seq);
+ seq ^= 1;
+ }
+
+ if (_config->palFading)
+ processDelayedPaletteFade();
+
+ _vm->updateInput();
+ }
+}
+
+void DarkMoonEngine::seq_nightmare() {
+ Screen::FontId of = _screen->setFont(Screen::FID_6_FNT);
+ _screen->copyRegion(0, 0, 0, 120, 176, 24, 12, 2, Screen::CR_NO_P_CHECK);
+
+ initDialogueSequence();
+ gui_drawDialogueBox();
+
+ _txt->printDialogueText(99, 0);
+ snd_playSoundEffect(54);
+
+ static const uint8 seqX[] = { 0, 20, 0, 20 };
+ static const uint8 seqY[] = { 0, 0, 96, 96 };
+ static const uint8 seqDelay[] = { 12, 7, 7, 12 };
+
+ for (const int8 *i = _dreamSteps; *i != -1; ++i) {
+ drawSequenceBitmap("DREAM", 0, seqX[*i], seqY[*i], 0);
+ delay(seqDelay[*i] * _tickLength);
+ }
+
+ _txt->printDialogueText(20, _okStrings[0]);
+
+ restoreAfterDialogueSequence();
+
+ _screen->setFont(of);
+}
+
+void DarkMoonEngine::seq_kheldran() {
+ Screen::FontId of = _screen->setFont(Screen::FID_6_FNT);
+
+ initDialogueSequence();
+ gui_drawDialogueBox();
+
+ static const char file[] = "KHELDRAN";
+ _txt->printDialogueText(_kheldranStrings[0]);
+ drawSequenceBitmap(file, 0, 0, 0, 0);
+ _txt->printDialogueText(20, _moreStrings[0]);
+ snd_playSoundEffect(56);
+ drawSequenceBitmap(file, 0, 20, 0, 0);
+ delay(10 * _tickLength);
+ drawSequenceBitmap(file, 0, 0, 96, 0);
+ delay(10 * _tickLength);
+ drawSequenceBitmap(file, 0, 20, 96, 0);
+ delay(7 * _tickLength);
+ _txt->printDialogueText(76, _okStrings[0]);
+
+ restoreAfterDialogueSequence();
+
+ _screen->setFont(of);
+}
+
+void DarkMoonEngine::seq_dranDragonTransformation() {
+ Screen::FontId of = _screen->setFont(Screen::FID_6_FNT);
+
+ initDialogueSequence();
+ gui_drawDialogueBox();
+
+ static const char file[] = "DRANX";
+ drawSequenceBitmap(file, 0, 0, 0, 0);
+ _txt->printDialogueText(120, _moreStrings[0]);
+ snd_playSoundEffect(56);
+ drawSequenceBitmap(file, 0, 20, 0, 0);
+ delay(7 * _tickLength);
+ drawSequenceBitmap(file, 0, 0, 96, 0);
+ delay(7 * _tickLength);
+ drawSequenceBitmap(file, 0, 20, 96, 0);
+ delay(18 * _tickLength);
+
+ restoreAfterDialogueSequence();
+
+ _screen->setFont(of);
+}
+
+} // End of namespace Kyra
+
+#endif // ENABLE_EOB
diff --git a/engines/kyra/sequences_eob.cpp b/engines/kyra/sequences_eob.cpp
new file mode 100644
index 0000000000..4a9f7d8a65
--- /dev/null
+++ b/engines/kyra/sequences_eob.cpp
@@ -0,0 +1,1152 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifdef ENABLE_EOB
+
+#include "kyra/eob.h"
+#include "kyra/screen_eob.h"
+#include "kyra/resource.h"
+#include "kyra/sound.h"
+
+#include "common/system.h"
+
+#include "base/version.h"
+
+namespace Kyra {
+
+class EoBIntroPlayer {
+public:
+ EoBIntroPlayer(EoBEngine *vm, Screen_EoB *screen);
+ ~EoBIntroPlayer() {}
+
+ void start();
+
+private:
+ void openingCredits();
+ void tower();
+ void orb();
+ void waterdeepEntry();
+ void king();
+ void hands();
+ void waterdeepExit();
+ void tunnel();
+
+ void loadAndSetPalette(const char *filename);
+ void copyBlurRegion(int x1, int y1, int x2, int y2, int w, int h, int step);
+ void boxMorphTransition(int targetDestX, int targetDestY, int targetFinalX, int targetFinalY, int targetSrcX, int targetSrcY, int targetFinalW, int targetFinalH, int originX1, int originY1, int originW, int originH);
+ void whirlTransition();
+
+ EoBEngine *_vm;
+ Screen_EoB *_screen;
+
+ const char *const *_filesOpening;
+ const char *const *_filesTower;
+ const char *const *_filesOrb;
+ const char *const *_filesWdEntry;
+ const char *const *_filesKing;
+ const char *const *_filesHands;
+ const char *const *_filesWdExit;
+ const char *const *_filesTunnel;
+ const uint8 *_openingFrmDelay;
+ const uint8 *_wdEncodeX;
+ const uint8 *_wdEncodeY;
+ const uint8 *_wdEncodeWH;
+ const uint16 *_wdDsX;
+ const uint8 *_wdDsY;
+ const uint8 *_tvlX1;
+ const uint8 *_tvlY1;
+ const uint8 *_tvlX2;
+ const uint8 *_tvlY2;
+ const uint8 *_tvlW;
+ const uint8 *_tvlH;
+};
+
+EoBIntroPlayer::EoBIntroPlayer(EoBEngine *vm, Screen_EoB *screen) : _vm(vm), _screen(screen) {
+ int temp = 0;
+ _filesOpening = _vm->staticres()->loadStrings(kEoB1IntroFilesOpening, temp);
+ _filesTower = _vm->staticres()->loadStrings(kEoB1IntroFilesTower, temp);
+ _filesOrb = _vm->staticres()->loadStrings(kEoB1IntroFilesOrb, temp);
+ _filesWdEntry = _vm->staticres()->loadStrings(kEoB1IntroFilesWdEntry, temp);
+ _filesKing = _vm->staticres()->loadStrings(kEoB1IntroFilesKing, temp);
+ _filesHands = _vm->staticres()->loadStrings(kEoB1IntroFilesHands, temp);
+ _filesWdExit = _vm->staticres()->loadStrings(kEoB1IntroFilesWdExit, temp);
+ _filesTunnel = _vm->staticres()->loadStrings(kEoB1IntroFilesTunnel, temp);
+ _openingFrmDelay = _vm->staticres()->loadRawData(kEoB1IntroOpeningFrmDelay, temp);
+ _wdEncodeX = _vm->staticres()->loadRawData(kEoB1IntroWdEncodeX, temp);
+ _wdEncodeY = _vm->staticres()->loadRawData(kEoB1IntroWdEncodeY, temp);
+ _wdEncodeWH = _vm->staticres()->loadRawData(kEoB1IntroWdEncodeWH, temp);
+ _wdDsX = _vm->staticres()->loadRawDataBe16(kEoB1IntroWdDsX, temp);
+ _wdDsY = _vm->staticres()->loadRawData(kEoB1IntroWdDsY, temp);
+ _tvlX1 = _vm->staticres()->loadRawData(kEoB1IntroTvlX1, temp);
+ _tvlY1 = _vm->staticres()->loadRawData(kEoB1IntroTvlY1, temp);
+ _tvlX2 = _vm->staticres()->loadRawData(kEoB1IntroTvlX2, temp);
+ _tvlY2 = _vm->staticres()->loadRawData(kEoB1IntroTvlY2, temp);
+ _tvlW = _vm->staticres()->loadRawData(kEoB1IntroTvlW, temp);
+ _tvlH = _vm->staticres()->loadRawData(kEoB1IntroTvlH, temp);
+}
+
+void EoBIntroPlayer::start() {
+ _vm->_allowSkip = true;
+ openingCredits();
+
+ if (!_vm->shouldQuit() && !_vm->skipFlag()) {
+ _vm->snd_playSong(2);
+ _screen->loadBitmap((_vm->_configRenderMode == Common::kRenderCGA || _vm->_configRenderMode == Common::kRenderEGA) ? "TITLE-E.CMP" : "TITLE-V.CMP", 3, 5, 0);
+ _screen->convertPage(5, 2, _vm->_cgaMappingDefault);
+ _screen->crossFadeRegion(0, 0, 0, 0, 320, 200, 2, 0);
+ _vm->delay(120 * _vm->_tickLength);
+ }
+
+ Common::SeekableReadStream *s = _vm->resource()->createReadStream("TEXT.RAW");
+ if (s) {
+ s->seek(768);
+ _screen->loadFileDataToPage(s, 5, s->size() - 768);
+ delete s;
+ } else {
+ _screen->loadBitmap("TEXT.CMP", 3, 5, 0);
+ }
+ _screen->convertPage(5, 6, _vm->_cgaMappingAlt);
+
+ tower();
+ orb();
+ waterdeepEntry();
+ king();
+ hands();
+ waterdeepExit();
+ tunnel();
+
+ whirlTransition();
+ _vm->snd_stopSound();
+ _vm->_allowSkip = false;
+}
+
+void EoBIntroPlayer::openingCredits() {
+ loadAndSetPalette(_filesOpening[5]);
+
+ _screen->loadBitmap(_filesOpening[4], 5, 3, 0);
+ _screen->convertPage(3, 0, _vm->_cgaMappingAlt);
+ _screen->updateScreen();
+
+ _vm->snd_playSong(1);
+ _vm->delay(_openingFrmDelay[0] * _vm->_tickLength);
+
+ for (int i = 0; i < 4 && !_vm->shouldQuit() && !_vm->skipFlag(); i++) {
+ _screen->loadBitmap(_filesOpening[i], 5, 3, 0);
+ uint32 nextFrameTimer = _vm->_system->getMillis() + _openingFrmDelay[i + 1] * _vm->_tickLength;
+ _screen->convertPage(3, 4, _vm->_cgaMappingAlt);
+ _screen->crossFadeRegion(0, 50, 0, 50, 320, 102, 4, 0);
+ _vm->delayUntil(nextFrameTimer);
+ }
+}
+
+void EoBIntroPlayer::tower() {
+ if (_vm->shouldQuit() || _vm->skipFlag())
+ return;
+
+ _screen->loadBitmap(_filesTower[1], 5, 3, 0);
+ _screen->setCurPage(2);
+ uint8 *shp = _screen->encodeShape(0, 0, 16, 56, true, _vm->_cgaMappingAlt);
+ _screen->convertPage(3, 4, _vm->_cgaMappingAlt);
+ _screen->clearCurPage();
+
+ for (int i = 0; i < 200; i += 64)
+ _screen->copyRegion(128, 104, 96, i, 128, 64, 4, 2, Screen::CR_NO_P_CHECK);
+
+ _screen->fillRect(0, 184, 319, 199, 12);
+ int cp = _screen->setCurPage(0);
+ whirlTransition();
+ loadAndSetPalette(_filesTower[0]);
+
+ _screen->setCurPage(cp);
+ _screen->clearCurPage();
+
+ for (int i = 0; i < 200; i += 64)
+ _screen->copyRegion(128, 104, 0, i, 128, 64, 4, 2, Screen::CR_NO_P_CHECK);
+
+ _screen->setCurPage(0);
+
+ for (int i = 0; i < 64 && !_vm->shouldQuit() && !_vm->skipFlag(); i += 2) {
+ uint32 end = _vm->_system->getMillis() + 2 * _vm->_tickLength;
+ _screen->copyRegion(0, 142 - i, 96, 0, 128, i + 1, 4, 0, Screen::CR_NO_P_CHECK);
+ _screen->copyRegion(0, 0, 96, i + 1, 128, 167 - i, 2, 0, Screen::CR_NO_P_CHECK);
+ if (!i)
+ _screen->copyRegion(0, 0, 0, 168, 320, 32, 6, 0, Screen::CR_NO_P_CHECK);
+ _screen->updateScreen();
+ _vm->delayUntil(end);
+ }
+
+ for (int i = 0; i < 24 && !_vm->shouldQuit() && !_vm->skipFlag(); i += 2) {
+ uint32 end = _vm->_system->getMillis() + 2 * _vm->_tickLength;
+ _screen->copyRegion(0, 79 - i, 96, 0, 24, 65 + i, 4, 0, Screen::CR_NO_P_CHECK);
+ _screen->copyRegion(104, 79 - i, 200, 0, 24, 65 + i, 4, 0, Screen::CR_NO_P_CHECK);
+ _screen->copyRegion(24, 110, 120, i + 31, 80, 34, 4, 0, Screen::CR_NO_P_CHECK);
+ _screen->copyRegion(152, 0, 120, 32, 80, i + 1, 4, 0, Screen::CR_NO_P_CHECK);
+ _screen->copyRegion(0, 0, 96, 65 + i, 128, 103 - i, 2, 0, Screen::CR_NO_P_CHECK);
+ _screen->updateScreen();
+ _vm->delayUntil(end);
+ }
+
+ for (int i = 0; i < 56 && !_vm->shouldQuit() && !_vm->skipFlag(); i += 2) {
+ uint32 end = _vm->_system->getMillis() + 2 * _vm->_tickLength;
+ _screen->copyRegion(0, 56, 96, i, 24, 54, 4, 0, Screen::CR_NO_P_CHECK);
+ _screen->copyRegion(104, 56, 200, i, 24, 54, 4, 0, Screen::CR_NO_P_CHECK);
+ _screen->copyRegion(0, 110, 96, 54 + i, 128, 34, 4, 0, Screen::CR_NO_P_CHECK);
+
+ if (i < 32) {
+ _screen->fillRect(128, 0, 255, i + 1, 12, 2);
+ _screen->copyRegion(152, 0, 120, 32, 80, i + 25, 4, 0, Screen::CR_NO_P_CHECK);
+ } else {
+ _screen->fillRect(128, 0, 255, i + 1, 12, 2);
+ _screen->copyRegion(152, i + 1, 120, 32 + i + 1, 80, 23, 4, 0, Screen::CR_NO_P_CHECK);
+ _screen->copyRegion(152, 0, 152, 32, 80, i + 1, 4, 2, Screen::CR_NO_P_CHECK);
+ }
+
+ _screen->drawShape(2, shp, 128, i - 55, 0);
+ _screen->copyRegion(128, 0, 96, 0, 128, i + 1, 2, 0, Screen::CR_NO_P_CHECK);
+ _screen->copyRegion(0, 0, 96, i + 89, 128, 79 - i, 2, 0, Screen::CR_NO_P_CHECK);
+ _screen->updateScreen();
+ _vm->delayUntil(end);
+ }
+
+ _screen->copyRegion(0, 32, 0, 168, 320, 32, 6, 0, Screen::CR_NO_P_CHECK);
+ _screen->updateScreen();
+ _vm->delay(65 * _vm->_tickLength);
+ delete[] shp;
+}
+
+void EoBIntroPlayer::orb() {
+ if (_vm->shouldQuit() || _vm->skipFlag())
+ return;
+
+ uint8 *shp[5];
+ _screen->loadBitmap(_filesOrb[0], 5, 3, 0);
+ _screen->setCurPage(2);
+ shp[4] = _screen->encodeShape(0, 0, 20, 136, true, _vm->_cgaMappingAlt);
+ _screen->loadBitmap(_filesOrb[1], 5, 3, 0);
+ shp[3] = _screen->encodeShape(16, 0, 16, 104, true, _vm->_cgaMappingAlt);
+
+ _screen->fillRect(0, 0, 127, 103, 12);
+ for (int i = 1; i < 4; i++) {
+ copyBlurRegion(128, 0, 0, 0, 128, 104, i);
+ shp[3 - i] = _screen->encodeShape(0, 0, 16, 104, true, _vm->_cgaMappingAlt);
+ }
+
+ _screen->fillRect(0, 0, 159, 135, 12);
+ _screen->setCurPage(0);
+ _screen->convertPage(3, 4, _vm->_cgaMappingAlt);
+ _screen->clearCurPage();
+
+ _vm->snd_playSoundEffect(6);
+
+ for (int i = -1; i < 4 && !_vm->shouldQuit() && !_vm->skipFlag(); i++) {
+ uint32 end = _vm->_system->getMillis() + 3 * _vm->_tickLength;
+ if (i >= 0)
+ _screen->drawShape(2, shp[i], 16, 16, 0);
+ _screen->drawShape(2, shp[4], 0, 0, 0);
+ _screen->copyRegion(0, 0, 80, 24, 160, 136, 2, 0, Screen::CR_NO_P_CHECK);
+ _screen->updateScreen();
+ _vm->delayUntil(end);
+ }
+
+ _screen->copyRegion(0, 64, 0, 168, 320, 16, 6, 0, Screen::CR_NO_P_CHECK);
+ _screen->updateScreen();
+ _vm->delay(40 * _vm->_tickLength);
+
+ _vm->snd_playSoundEffect(6);
+
+ for (int i = 3; i > -2 && !_vm->shouldQuit() && !_vm->skipFlag(); i--) {
+ uint32 end = _vm->_system->getMillis() + 3 * _vm->_tickLength;
+ _screen->fillRect(16, 16, 143, 119, 12, 2);
+ if (i >= 0)
+ _screen->drawShape(2, shp[i], 16, 16, 0);
+ _screen->drawShape(2, shp[4], 0, 0, 0);
+ _screen->copyRegion(0, 0, 80, 24, 160, 136, 2, 0, Screen::CR_NO_P_CHECK);
+ _screen->updateScreen();
+ _vm->delayUntil(end);
+ }
+
+ _vm->delay(40 * _vm->_tickLength);
+
+ for (int i = 0; i < 5; i++)
+ delete[] shp[i];
+}
+
+void EoBIntroPlayer::waterdeepEntry() {
+ if (_vm->shouldQuit() || _vm->skipFlag())
+ return;
+
+ uint8 *shp[4];
+ uint8 *shp2[31];
+ uint8 *shp3[3];
+
+ loadAndSetPalette(_filesWdEntry[0]);
+ _screen->loadBitmap(_filesWdEntry[1], 5, 3, 0);
+ _screen->setCurPage(2);
+ shp[3] = _screen->encodeShape(0, 0, 20, 136, true, _vm->_cgaMappingAlt);
+ for (int i = 1; i < 4; i++) {
+ copyBlurRegion(0, 0, 0, 0, 160, 136, i);
+ shp[3 - i] = _screen->encodeShape(0, 0, 20, 136, true, _vm->_cgaMappingAlt);
+ }
+ _screen->setCurPage(0);
+
+ _screen->convertPage(3, 4, _vm->_cgaMappingAlt);
+ _screen->fillRect(0, 168, 319, 199, 12, 0);
+ _vm->snd_playSoundEffect(6);
+
+ for (int i = 0; i < 4 && !_vm->shouldQuit() && !_vm->skipFlag(); i++) {
+ uint32 end = _vm->_system->getMillis() + 3 * _vm->_tickLength;
+ _screen->drawShape(0, shp[i], 80, 24, 0);
+ delete[] shp[i];
+ _screen->updateScreen();
+ _vm->delayUntil(end);
+ }
+
+ _screen->copyRegion(0, 80, 0, 168, 320, 16, 6, 0, Screen::CR_NO_P_CHECK);
+ _screen->updateScreen();
+ _vm->delay(50 * _vm->_tickLength);
+
+ _screen->setCurPage(2);
+ shp[0] = _screen->encodeShape(20, 0, 20, 136, true, _vm->_cgaMappingAlt);
+ _screen->loadBitmap(_filesWdEntry[2], 5, 3, 0);
+ shp[1] = _screen->encodeShape(0, 0, 20, 136, true, _vm->_cgaMappingAlt);
+ shp[2] = _screen->encodeShape(20, 0, 20, 136, true, _vm->_cgaMappingAlt);
+ _screen->loadBitmap(_filesWdEntry[3], 5, 3, 0);
+
+ for (int i = 0; i < 31; i++)
+ shp2[i] = _screen->encodeShape(_wdEncodeX[i], 136 + (_wdEncodeY[i] << 3), _wdEncodeWH[i], _wdEncodeWH[i] << 3, true, _vm->_cgaMappingAlt);
+ for (int i = 0; i < 3; i++)
+ shp3[i] = _screen->encodeShape(5 * i, 152, 5, 32, true, _vm->_cgaMappingAlt);
+
+ _screen->convertPage(3, 4, _vm->_cgaMappingAlt);
+
+ for (int i = 0; i < 3 && !_vm->shouldQuit() && !_vm->skipFlag(); i++) {
+ uint32 end = _vm->_system->getMillis() + 3 * _vm->_tickLength;
+ _screen->fillRect(0, 0, 159, 135, 12, 2);
+ _screen->drawShape(2, shp[i], 0, 0, 0);
+ _screen->copyRegion(0, 0, 80, 24, 160, 136, 2, 0, Screen::CR_NO_P_CHECK);
+ _screen->updateScreen();
+ _vm->delayUntil(end);
+ }
+
+ _screen->copyRegion(0, 0, 80, 24, 160, 136, 4, 0, Screen::CR_NO_P_CHECK);
+ _screen->updateScreen();
+ _vm->delay(4 * _vm->_tickLength);
+ _screen->copyRegion(160, 0, 80, 24, 160, 136, 4, 0, Screen::CR_NO_P_CHECK);
+ _screen->fillRect(0, 168, 319, 199, 12, 0);
+ _screen->updateScreen();
+ _vm->delay(4 * _vm->_tickLength);
+ _screen->copyRegion(0, 184, 40, 184, 232, 16, 4, 0, Screen::CR_NO_P_CHECK);
+
+ int cx = 264;
+ int cy = 11;
+
+ for (int i = 0; i < 70 && !_vm->shouldQuit() && !_vm->skipFlag(); i++) {
+ uint32 end = _vm->_system->getMillis() + 3 * _vm->_tickLength;
+
+ _screen->copyRegion(cx - 2, cy - 2, 0, 0, 48, 36, 4, 4, Screen::CR_NO_P_CHECK);
+ _screen->drawShape(4, shp3[((i & 3) == 3) ? 1 : (i & 3)], cx, cy, 0);
+ _screen->copyRegion(cx - 2, cy - 2, cx - 82, cy + 22, 48, 36, 4, 0, Screen::CR_NO_P_CHECK);
+ _screen->copyRegion(0, 0, cx - 2, cy - 2, 48, 36, 4, 4, Screen::CR_NO_P_CHECK);
+ cx--;
+ cy++;
+
+ for (int ii = 0; ii < 5; ii++) {
+ int s = _vm->_rnd.getRandomNumber(255) % 31;
+ _screen->drawShape(0, shp2[s], _wdDsX[s] - 80, _wdDsY[s] + 24, 0);
+ }
+
+ if (!(_vm->_rnd.getRandomNumber(255) & 7))
+ _vm->snd_playSoundEffect(_vm->_rnd.getRandomBit() ? 5 : 14);
+
+ _screen->updateScreen();
+ _vm->delayUntil(end);
+ }
+
+ for (int i = 0; i < 3; i++) {
+ delete[] shp[i];
+ delete[] shp3[i];
+ }
+
+ for (int i = 0; i < 31; i++)
+ delete[] shp2[i];
+}
+
+void EoBIntroPlayer::king() {
+ if (_vm->shouldQuit() || _vm->skipFlag())
+ return;
+
+ _screen->loadBitmap(_filesKing[0], 5, 3, 0);
+ _screen->convertPage(3, 4, _vm->_cgaMappingAlt);
+
+ int x = 15;
+ int y = 14;
+ int w = 1;
+ int h = 1;
+
+ for (int i = 0; i < 10 && !_vm->shouldQuit() && !_vm->skipFlag(); i++) {
+ uint32 end = _vm->_system->getMillis() + _vm->_tickLength;
+ _screen->copyRegion(x << 3, y << 3, x << 3, y << 3, w << 3, h << 3, 4, 0, Screen::CR_NO_P_CHECK);
+ if (x > 6)
+ x --;
+ if (y > 0)
+ y -= 2;
+ w += 3;
+ if (x + w > 34)
+ w = 34 - x;
+ h += 3;
+ if (y + h > 23)
+ h = 23 - y;
+ _screen->updateScreen();
+ _vm->delayUntil(end);
+ }
+
+ _vm->delay(25 * _vm->_tickLength);
+
+ uint8 *shp[4];
+ int16 dy[4];
+ int16 stepY[4];
+
+ static const uint8 advEncX[] = { 0, 6, 12, 19 };
+ static const uint8 advEncW[] = { 6, 6, 7, 6 };
+ static const int8 modY[] = { -4, -8, -2, -2, 1, 0, 0, 0 };
+
+ _screen->loadBitmap(_filesKing[1], 5, 3, 0);
+ _screen->setCurPage(2);
+ for (int i = 0; i < 4; i++) {
+ shp[i] = _screen->encodeShape(advEncX[i], 0, advEncW[i], 98, true, _vm->_cgaMappingAlt);
+ dy[i] = 180 + ((_vm->_rnd.getRandomNumber(255) & 3) << 3);
+ stepY[i] = (i * 5) & 3;
+ }
+
+ _screen->copyPage(0, 4);
+
+ for (bool runloop = true; runloop && !_vm->shouldQuit() && !_vm->skipFlag();) {
+ runloop = false;
+ uint32 end = _vm->_system->getMillis() + 2 * _vm->_tickLength;
+
+ for (int i = 0; i < 4; i++) {
+ if (dy[i] <= 82)
+ continue;
+ stepY[i] = (stepY[i] + 1) & 7;
+ dy[i] += modY[stepY[i]];
+
+ if (dy[i] < 82)
+ dy[i] = 82;
+
+ if (dy[i] < 180) {
+ _screen->copyRegion((advEncX[i] + 8) << 3, dy[i] - 2, 0, dy[i] - 2, advEncW[i] << 3, 182 - dy[i], 4, 4, Screen::CR_NO_P_CHECK);
+ _screen->drawShape(4, shp[i], 0, dy[i], 0);
+ _screen->copyRegion(0, dy[i] - 2, (advEncX[i] + 8) << 3, dy[i] - 2, advEncW[i] << 3, 182 - dy[i], 4, 0, Screen::CR_NO_P_CHECK);
+ }
+
+ runloop = true;
+ }
+
+ if (!(_vm->_rnd.getRandomNumber(255) & 3))
+ _vm->snd_playSoundEffect(7);
+
+ _screen->updateScreen();
+ _vm->delayUntil(end);
+ }
+
+ _screen->copyRegion(0, 96, 0, 160, 320, 32, 6, 0, Screen::CR_NO_P_CHECK);
+ _screen->updateScreen();
+ _vm->delay(70 * _vm->_tickLength);
+
+ for (int i = 0; i < 4; i++)
+ delete[] shp[i];
+}
+
+void EoBIntroPlayer::hands() {
+ if (_vm->shouldQuit() || _vm->skipFlag())
+ return;
+
+ _screen->setCurPage(2);
+ uint8 *shp1 = _screen->encodeShape(0, 140, 21, 60, true, _vm->_cgaMappingAlt);
+ uint8 *shp2 = _screen->encodeShape(21, 140, 12, 60, true, _vm->_cgaMappingAlt);
+ _screen->loadBitmap(_filesHands[0], 3, 5, 0);
+
+ _screen->fillRect(0, 160, 319, 199, 12, 0);
+ _screen->fillRect(0, 0, 191, 63, 157, 2);
+ _screen->drawShape(2, shp1, 0, 4, 0);
+ _screen->drawShape(2, shp2, 151, 4, 0);
+ boxMorphTransition(25, 8, 18, 4, 3, 0, 21, 8, 6, 0, 28, 23);
+ _screen->copyRegion(0, 128, 0, 176, 320, 16, 6, 0, Screen::CR_NO_P_CHECK);
+
+ _screen->updateScreen();
+ _vm->delay(15 * _vm->_tickLength);
+ _vm->snd_playSoundEffect(11);
+
+ for (int i = -22; i <= 20 && !_vm->shouldQuit() && !_vm->skipFlag(); i += 4) {
+ uint32 end = _vm->_system->getMillis() + _vm->_tickLength;
+ _screen->fillRect(0, 0, 167, 63, 157);
+ _screen->drawShape(2, shp1, i, 4, 0);
+ _screen->drawShape(2, shp2, 105 - i, 4, 0);
+ _screen->copyRegion(0, 0, 144, 32, 168, 64, 2, 0, Screen::CR_NO_P_CHECK);
+ _screen->updateScreen();
+ _vm->delayUntil(end);
+ }
+
+ _vm->snd_playSoundEffect(10);
+
+ delete[] shp1;
+ delete[] shp2;
+ _vm->delay(15 * _vm->_tickLength);
+
+ _screen->setCurPage(4);
+ shp1 = _screen->encodeShape(17, 0, 11, 120, true, _vm->_cgaMappingAlt);
+ shp2 = _screen->encodeShape(28, 112, 1, 31, true, _vm->_cgaMappingAlt);
+ uint8 *shp3 = _screen->encodeShape(9, 138, 14, 54, true, _vm->_cgaMappingAlt);
+
+ _screen->setCurPage(2);
+ _screen->fillRect(0, 0, 135, 63, 157);
+ _screen->drawShape(2, shp1, 32, -80, 0);
+ _screen->drawShape(2, shp2, 40, -16, 0);
+ boxMorphTransition(18, 16, 10, 12, 0, 0, 17, 8, 17, 3, 25, 10);
+ _vm->delay(15 * _vm->_tickLength);
+
+ for (int i = -80; i <= 0 && !_vm->shouldQuit() && !_vm->skipFlag(); i += 4) {
+ uint32 end = _vm->_system->getMillis() + _vm->_tickLength;
+ _screen->fillRect(0, 0, 135, 63, 157);
+ _screen->drawShape(2, shp1, 32, i, 0);
+ _screen->drawShape(2, shp2, 40, i + 64, 0);
+ _screen->copyRegion(0, 0, 80, 96, 136, 64, 2, 0, Screen::CR_NO_P_CHECK);
+ _screen->updateScreen();
+ _vm->delayUntil(end);
+ }
+
+ _vm->snd_playSoundEffect(12);
+ _vm->delay(5 * _vm->_tickLength);
+
+ for (int i = 0; i > -54 && !_vm->shouldQuit() && !_vm->skipFlag(); i -= 4) {
+ uint32 end = _vm->_system->getMillis() + _vm->_tickLength;
+ _screen->fillRect(0, 0, 135, 63, 157);
+ _screen->drawShape(2, shp3, 12, 64 + i, 0);
+ _screen->drawShape(2, shp1, 32, i, 0);
+ _screen->copyRegion(0, 0, 80, 96, 136, 64, 2, 0, Screen::CR_NO_P_CHECK);
+ _screen->updateScreen();
+ _vm->delayUntil(end);
+ }
+
+ delete[] shp1;
+ delete[] shp2;
+ delete[] shp3;
+ _vm->delay(15 * _vm->_tickLength);
+
+ _screen->setCurPage(4);
+ shp1 = _screen->encodeShape(0, 0, 17, 136, true, _vm->_cgaMappingAlt);
+ shp2 = _screen->encodeShape(0, 136, 9, 48, true, _vm->_cgaMappingAlt);
+
+ _screen->setCurPage(2);
+ _screen->fillRect(0, 0, 143, 95, 157);
+ _screen->drawShape(2, shp1, -56, -56, 0);
+ _screen->drawShape(2, shp2, 52, 49, 0);
+ boxMorphTransition(9, 6, 0, 0, 0, 0, 18, 12, 8, 11, 21, 10);
+ _vm->delay(15 * _vm->_tickLength);
+ _vm->snd_playSoundEffect(11);
+
+ for (int i = -56; i <= -8 && !_vm->shouldQuit() && !_vm->skipFlag(); i += 4) {
+ uint32 end = _vm->_system->getMillis() + _vm->_tickLength;
+ _screen->fillRect(0, 0, 143, 95, 157);
+ _screen->drawShape(2, shp1, i, i, 0);
+ _screen->drawShape(2, shp2, (i == -8) ? 55 : 52, (i == -8) ? 52 : 49, 0);
+ _screen->copyRegion(0, 0, 0, 0, 144, 96, 2, 0, Screen::CR_NO_P_CHECK);
+ _screen->updateScreen();
+ _vm->delayUntil(end);
+ }
+
+ _vm->snd_playSoundEffect(10);
+ delete[] shp1;
+ delete[] shp2;
+ _vm->delay(30 * _vm->_tickLength);
+
+ _screen->setCurPage(4);
+ shp1 = _screen->encodeShape(28, 0, 11, 40, true, _vm->_cgaMappingAlt);
+ shp2 = _screen->encodeShape(28, 40, 10, 72, true, _vm->_cgaMappingAlt);
+
+ _screen->setCurPage(2);
+ _screen->fillRect(0, 0, 87, 112, 157);
+ _screen->drawShape(2, shp2, 0, 90, 0);
+ boxMorphTransition(20, 13, 15, 6, 0, 0, 11, 14, 0, 0, 24, 16);
+ _vm->delay(15 * _vm->_tickLength);
+
+ int dy = 90;
+ for (int i = -40; i <= 0 && !_vm->shouldQuit() && !_vm->skipFlag(); i += 4) {
+ uint32 end = _vm->_system->getMillis() + _vm->_tickLength;
+ _screen->fillRect(0, 0, 87, 112, 157);
+ _screen->drawShape(2, shp2, 0, dy, 0);
+ _screen->copyRegion(0, 0, 120, 48, 88, 112, 2, 0, Screen::CR_NO_P_CHECK);
+ _screen->updateScreen();
+ _vm->delayUntil(end);
+ dy -= 5;
+ }
+
+ _vm->snd_playSoundEffect(13);
+
+ for (int i = -40; i <= 0 && !_vm->shouldQuit() && !_vm->skipFlag(); i += 4) {
+ uint32 end = _vm->_system->getMillis() + _vm->_tickLength;
+ _screen->fillRect(0, 0, 87, 39, 157);
+ _screen->drawShape(2, shp1, 0, i, 0);
+ _screen->copyRegion(0, 0, 120, 48, 88, 112, 2, 0, Screen::CR_NO_P_CHECK);
+ _screen->updateScreen();
+ _vm->delayUntil(end);
+ }
+
+ delete[] shp1;
+ delete[] shp2;
+ _vm->delay(48 * _vm->_tickLength);
+}
+
+void EoBIntroPlayer::waterdeepExit() {
+ if (_vm->shouldQuit() || _vm->skipFlag())
+ return;
+
+ uint8 *shp2[31];
+ uint8 *shp3[3];
+
+ _screen->loadBitmap(_filesWdExit[0], 5, 3, 0);
+ _screen->setCurPage(2);
+ for (int i = 0; i < 31; i++)
+ shp2[i] = _screen->encodeShape(_wdEncodeX[i], 136 + (_wdEncodeY[i] << 3), _wdEncodeWH[i], _wdEncodeWH[i] << 3, true, _vm->_cgaMappingAlt);
+ for (int i = 0; i < 3; i++)
+ shp3[i] = _screen->encodeShape(5 * i + 15, 152, 5, 32, true, _vm->_cgaMappingAlt);
+ uint8 *shp1 = _screen->encodeShape(31, 136, 5, 32, true, _vm->_cgaMappingAlt);
+ _screen->convertPage(3, 4, _vm->_cgaMappingAlt);
+ _screen->copyRegion(0, 0, 0, 136, 48, 36, 4, 4, Screen::CR_NO_P_CHECK);
+ _screen->fillRect(0, 168, 319, 199, 12, 0);
+ _screen->copyRegion(160, 0, 80, 24, 160, 136, 4, 0, Screen::CR_NO_P_CHECK);
+
+ int cx = 140;
+ int cy = 128;
+
+ for (int i = 0; i < 70 && !_vm->shouldQuit() && !_vm->skipFlag(); i++) {
+ uint32 end = _vm->_system->getMillis() + 3 * _vm->_tickLength;
+ int fx = cx - 2;
+ if (fx < 160)
+ fx = 160;
+ int fy = cy - 2;
+ if (fy > 98)
+ fy = 98;
+
+ _screen->copyRegion(fx, fy, 0, 0, 48, 36, 4, 4, Screen::CR_NO_P_CHECK);
+ _screen->drawShape(4, shp3[((i & 3) == 3) ? 1 : (i & 3)], cx, cy, 0);
+ _screen->drawShape(4, shp1, 160, 104, 0);
+ _screen->copyRegion(fx, fy, fx - 80, fy + 24, 48, 36, 4, 0, Screen::CR_NO_P_CHECK);
+ _screen->copyRegion(0, 0, fx, fy, 48, 36, 4, 4, Screen::CR_NO_P_CHECK);
+ cx++;
+ cy--;
+
+ for (int ii = 0; ii < 5; ii++) {
+ int s = _vm->_rnd.getRandomNumber(255) % 31;
+ _screen->drawShape(0, shp2[s], _wdDsX[s] - 80, _wdDsY[s] + 24, 0);
+ }
+
+ if (!(_vm->_rnd.getRandomNumber(255) & 7))
+ _vm->snd_playSoundEffect(_vm->_rnd.getRandomBit() ? 5 : 14);
+
+ _screen->updateScreen();
+ _vm->delayUntil(end);
+ }
+
+ for (int i = 0; i < 3; i++)
+ delete[] shp3[i];
+
+ for (int i = 0; i < 31; i++)
+ delete[] shp2[i];
+ delete[] shp1;
+
+ _screen->setCurPage(0);
+ _screen->fillRect(0, 168, 319, 199, 12, 0);
+ _screen->copyRegion(0, 136, 0, 0, 48, 36, 0, 4, Screen::CR_NO_P_CHECK);
+
+ loadAndSetPalette(_filesWdExit[1]);
+ _screen->loadBitmap(_filesWdExit[2], 3, 5, 0);
+ _screen->convertPage(5, 2, _vm->_cgaMappingAlt);
+ whirlTransition();
+ _vm->delay(6 * _vm->_tickLength);
+
+ _screen->copyRegion(0, 144, 0, 184, 320, 16, 6, 0, Screen::CR_NO_P_CHECK);
+
+ cx = 0;
+ cy = 136;
+ int dy = 0;
+ for (int i = 0; i < 19 && !_vm->shouldQuit() && !_vm->skipFlag(); i++) {
+ uint32 end = _vm->_system->getMillis() + _vm->_tickLength;
+ _screen->copyRegion(cx, cy, 80, dy + 16, 160, 8, 2, 0, Screen::CR_NO_P_CHECK);
+ cy += 8;
+ dy += 8;
+ if (i == 6) {
+ cx = 160;
+ cy = 0;
+ }
+ _screen->updateScreen();
+ _vm->delayUntil(end);
+ }
+
+ _vm->snd_playSong(3);
+ _vm->delay(60 * _vm->_tickLength);
+
+ for (int i = 0; i < 56 && !_vm->shouldQuit() && !_vm->skipFlag(); i++) {
+ uint32 end = _vm->_system->getMillis() +_vm->_tickLength;
+ _screen->copyRegion(0, 136 + i, 80, 16, 160, 56 - i, 2, 0, Screen::CR_NO_P_CHECK);
+ _screen->copyRegion(160, 0, 80, 72 - i, 160, 96 + i, 2, 0, Screen::CR_NO_P_CHECK);
+ _screen->updateScreen();
+ _vm->delayUntil(end);
+ }
+
+ for (int i = 1; i < 48 && !_vm->shouldQuit() && !_vm->skipFlag(); i++) {
+ uint32 end = _vm->_system->getMillis() + _vm->_tickLength;
+ _screen->copyRegion(160, i, 80, 16, 160, 152, 2, 0, Screen::CR_NO_P_CHECK);
+ _screen->updateScreen();
+ _vm->delayUntil(end);
+ }
+
+ _screen->loadBitmap(_filesWdExit[3], 3, 5, 0);
+ _screen->convertPage(5, 2, _vm->_cgaMappingAlt);
+ _vm->delay(30 * _vm->_tickLength);
+ _screen->setCurPage(0);
+ _screen->fillRect(0, 16, 319, 31, 12);
+ _screen->fillRect(0, 136, 319, 199, 12);
+ _screen->copyRegion(0, 0, 80, 32, 160, 120, 2, 0, Screen::CR_NO_P_CHECK);
+ loadAndSetPalette(_filesWdExit[4]);
+ _screen->updateScreen();
+ _vm->delay(50 * _vm->_tickLength);
+}
+
+void EoBIntroPlayer::tunnel() {
+ if (_vm->shouldQuit() || _vm->skipFlag())
+ return;
+
+ _screen->setCurPage(4);
+ uint8 *shp2 = _screen->encodeShape(20, 0, 20, 120, true, _vm->_cgaMappingAlt);
+ uint8 *shp1 = _screen->encodeShape(0, 0, 20, 120, true, _vm->_cgaMappingAlt);
+ _vm->drawBlockObject(1, 4, shp2, 160, 0, 0);
+ _vm->drawBlockObject(1, 4, shp1, 0, 0, 0);
+ delete[] shp1;
+ delete[] shp2;
+
+ for (int i = 0; i < 3 && !_vm->shouldQuit() && !_vm->skipFlag(); i++) {
+ uint32 end = _vm->_system->getMillis() + 8 * _vm->_tickLength;
+ _screen->copyRegion(0, 0, 80, 32, 160, 120, 4, 0, Screen::CR_NO_P_CHECK);
+ _vm->snd_playSoundEffect(7);
+ _screen->updateScreen();
+ _vm->delayUntil(end);
+ _screen->copyRegion(0, 0, 80, 32, 160, 120, 2, 0, Screen::CR_NO_P_CHECK);
+ _vm->snd_playSoundEffect(7);
+ end = _vm->_system->getMillis() + 8 * _vm->_tickLength;
+ _screen->updateScreen();
+ _vm->delayUntil(end);
+ }
+
+ _screen->copyRegion(0, 160, 0, 184, 320, 16, 6, 0, Screen::CR_NO_P_CHECK);
+ _screen->updateScreen();
+ _vm->delay(18 * _vm->_tickLength);
+ _screen->copyRegion(160, 0, 80, 32, 160, 120, 2, 0, Screen::CR_NO_P_CHECK);
+ _screen->updateScreen();
+ _vm->delay(5 * _vm->_tickLength);
+ _screen->copyRegion(0, 122, 80, 32, 160, 60, 2, 0, Screen::CR_NO_P_CHECK);
+ _screen->copyRegion(160, 122, 80, 92, 160, 60, 2, 0, Screen::CR_NO_P_CHECK);
+ _screen->updateScreen();
+ _vm->delay(5 * _vm->_tickLength);
+ _screen->copyRegion(160, 0, 80, 32, 160, 120, 4, 0, Screen::CR_NO_P_CHECK);
+ for (int i = 0; i < 6; i++)
+ _screen->copyRegion(i * 48, 185, 56, (i << 3) + 24, 48, 8, 2, 2, Screen::CR_NO_P_CHECK);
+ _screen->updateScreen();
+ _vm->delay(5 * _vm->_tickLength);
+ _screen->copyRegion(0, 0, 80, 32, 160, 120, 2, 0, Screen::CR_NO_P_CHECK);
+
+ _screen->loadBitmap(_filesTunnel[0], 5, 3, 0);
+ _screen->convertPage(3, 4, _vm->_cgaMappingAlt);
+ _screen->updateScreen();
+ _vm->delay(40 * _vm->_tickLength);
+
+ _screen->copyRegion(264, 0, 136, 56, 48, 48, 4, 0, Screen::CR_NO_P_CHECK);
+ _vm->snd_playSoundEffect(8);
+ _screen->copyRegion(0, 0, 0, 0, 320, 184, 0, 2, Screen::CR_NO_P_CHECK);
+ _screen->updateScreen();
+ _vm->delay(16 * _vm->_tickLength);
+ _vm->snd_playSoundEffect(4);
+
+ for (int i = 0; i < 30 && !_vm->shouldQuit() && !_vm->skipFlag(); i++) {
+ uint32 end = _vm->_system->getMillis() + _vm->_tickLength;
+ if (i == 0)
+ _screen->fillRect(0, 168, 319, 199, 12, 0);
+ _screen->copyRegion(80, 25 + (_vm->_rnd.getRandomNumber(255) & 7), 80, 24, 160, 144, 2, 0, Screen::CR_NO_P_CHECK);
+ _screen->updateScreen();
+ _vm->delayUntil(end);
+ }
+
+ _vm->snd_playSoundEffect(9);
+
+ for (int i = 0; i < 6 && !_vm->shouldQuit() && !_vm->skipFlag(); i++) {
+ uint32 end = _vm->_system->getMillis() + _vm->_tickLength;
+ _screen->copyRegion(_tvlX1[i] << 3, _tvlY1[i], _tvlX2[i] << 3, _tvlY2[i], _tvlW[i] << 3, _tvlH[i], 4, 2, Screen::CR_NO_P_CHECK);
+ for (int ii = 0; ii < 4 && !_vm->shouldQuit() && !_vm->skipFlag(); ii++) {
+ _screen->updateScreen();
+ _vm->delayUntil(end);
+ end = _vm->_system->getMillis() + _vm->_tickLength;
+ _screen->copyRegion(80, 25 + (_vm->_rnd.getRandomNumber(255) & 7), 80, 24, 160, 144, 2, 0, Screen::CR_NO_P_CHECK);
+ }
+ }
+ _screen->copyRegion(0, 0, 0, 0, 320, 168, 2, 0, Screen::CR_NO_P_CHECK);
+ _screen->updateScreen();
+ _vm->delay(40 * _vm->_tickLength);
+
+ _screen->loadBitmap(_filesTunnel[1], 5, 3, 0);
+ _screen->convertPage(3, 4, _vm->_cgaMappingAlt);
+ _vm->snd_playSoundEffect(6);
+ _screen->copyRegion(0, 0, 80, 32, 160, 120, 4, 0, Screen::CR_NO_P_CHECK);
+ _screen->updateScreen();
+ _vm->delay(2 * _vm->_tickLength);
+ _screen->copyRegion(160, 0, 80, 32, 160, 120, 4, 0, Screen::CR_NO_P_CHECK);
+ _screen->updateScreen();
+ _vm->delay(2 * _vm->_tickLength);
+ _screen->copyRegion(0, 120, 80, 30, 160, 64, 4, 0, Screen::CR_NO_P_CHECK);
+ _screen->copyRegion(160, 120, 80, 94, 160, 64, 4, 0, Screen::CR_NO_P_CHECK);
+ _screen->copyRegion(0, 176, 0, 184, 320, 16, 6, 0, Screen::CR_NO_P_CHECK);
+ _screen->setCurPage(0);
+ _screen->updateScreen();
+ _vm->delay(50 * _vm->_tickLength);
+}
+
+void EoBIntroPlayer::loadAndSetPalette(const char *filename) {
+ if (_vm->_configRenderMode == Common::kRenderCGA || _vm->_configRenderMode == Common::kRenderEGA)
+ return;
+ _screen->loadPalette(filename, _screen->getPalette(0));
+ _screen->getPalette(0).fill(0, 1, 0);
+ _screen->setScreenPalette(_screen->getPalette(0));
+}
+
+void EoBIntroPlayer::copyBlurRegion(int x1, int y1, int x2, int y2, int w, int h, int step) {
+ const uint8 *ptr2 = _screen->getCPagePtr(3) + y1 * 320 + x1;
+
+ if (step == 1) {
+ while (h > 0) {
+ int dx = x2;
+ for (int i = 0; i < w; i += 2) {
+ _screen->setPagePixel(3, dx++, y2, ptr2[i]);
+ _screen->setPagePixel(3, dx++, y2, 0);
+ }
+ dx = x2;
+ y2++;
+ ptr2 += 320;
+ for (int i = 0; i < w; i += 2) {
+ _screen->setPagePixel(3, dx++, y2, 0);
+ _screen->setPagePixel(3, dx++, y2, ptr2[i + 1]);
+ }
+ y2++;
+ ptr2 += 320;
+ h -= 2;
+ }
+ } else if (step == 2) {
+ while (h > 0) {
+ int dx = x2;
+ for (int i = 0; i < w; i += 2) {
+ _screen->setPagePixel(3, dx++, y2, ptr2[i]);
+ _screen->setPagePixel(3, dx++, y2, 0);
+ }
+ dx = x2;
+ y2++;
+ ptr2 += 320;
+ for (int i = 0; i < w; i++)
+ _screen->setPagePixel(3, dx++, y2, 0);
+
+ y2++;
+ ptr2 += 320;
+ h -= 2;
+ }
+ } else if (step == 3) {
+ for (int i = 0; i < h; i++) {
+ int dx = x2;
+ if ((i % 3) == 0) {
+ int ii = 0;
+ for (; ii < w - 3; ii += 3) {
+ _screen->setPagePixel(3, dx++, y2, ptr2[ii]);
+ _screen->setPagePixel(3, dx++, y2, 0);
+ _screen->setPagePixel(3, dx++, y2, 0);
+ }
+ for (; ii < w; ii++)
+ _screen->setPagePixel(3, dx++, y2, 0);
+ } else {
+ for (int ii = 0; ii < w; ii++)
+ _screen->setPagePixel(3, dx++, y2, 0);
+ }
+ y2++;
+ ptr2 += 320;
+ }
+ }
+}
+
+void EoBIntroPlayer::boxMorphTransition(int targetDestX, int targetDestY, int targetFinalX, int targetFinalY, int targetSrcX, int targetSrcY, int targetFinalW, int targetFinalH, int originX1, int originY1, int originW, int originH) {
+ int originX2 = originX1 + originW;
+ int originY2 = originY1 + originH;
+ if (originY2 > 21)
+ originY2 = 21;
+
+ int w = 1;
+ int h = 1;
+ for (bool runloop = true; runloop && !_vm->shouldQuit() && !_vm->skipFlag();) {
+ uint32 end = _vm->_system->getMillis() + _vm->_tickLength;
+ _screen->copyRegion(targetSrcX << 3, targetSrcY << 3, targetDestX << 3, targetDestY << 3, w << 3, h << 3, 2, 0, Screen::CR_NO_P_CHECK);
+ if (originX1 < targetDestX)
+ _screen->copyRegion(312, 0, originX1 << 3, 0, 8, 176, 0, 0, Screen::CR_NO_P_CHECK);
+ if (originY1 < targetDestY)
+ _screen->copyRegion(0, 192, 0, originY1 << 3, 320, 8, 0, 0, Screen::CR_NO_P_CHECK);
+ if ((targetFinalX + targetFinalW) <= originX2)
+ _screen->copyRegion(312, 0, originX2 << 3, 0, 8, 176, 0, 0, Screen::CR_NO_P_CHECK);
+ if ((targetFinalY + targetFinalH) <= originY2)
+ _screen->copyRegion(0, 192, 0, originY2 << 3, 320, 8, 0, 0, Screen::CR_NO_P_CHECK);
+
+ if (!(targetDestX != targetFinalX || targetDestY != targetFinalY || w != targetFinalW || h != targetFinalH || originX1 < targetFinalX || originY1 < targetFinalY || (targetFinalX + targetFinalW) < originX2 || (targetFinalY + targetFinalH) < originY2))
+ runloop = false;
+
+ int v = targetFinalX - targetDestX;
+ v = (v < 0) ? -1 : ((v > 0) ? 1 : 0);
+ targetDestX += v;
+ v = targetFinalY - targetDestY;
+ v = (v < 0) ? -1 : ((v > 0) ? 1 : 0);
+ targetDestY += v;
+
+ if (w != targetFinalW)
+ w += 2;
+ if (w > targetFinalW)
+ w = targetFinalW;
+
+ if (h != targetFinalH)
+ h += 2;
+ if (h > targetFinalH)
+ h = targetFinalH;
+
+ if (++originX1 > targetFinalX)
+ originX1 = targetFinalX;
+
+ if (++originY1 > targetFinalY)
+ originY1 = targetFinalY;
+
+ if ((targetFinalX + targetFinalW) < originX2)
+ originX2--;
+
+ if ((targetFinalY + targetFinalH) < originY2)
+ originY2--;
+
+ _screen->updateScreen();
+ _vm->delayUntil(end);
+ }
+}
+
+void EoBIntroPlayer::whirlTransition() {
+ for (int i = 0; i < 2; i++) {
+ for (int ii = 0; ii < 8; ii++) {
+ uint32 e = _vm->_system->getMillis() + 3;
+ if (ii & 1) {
+ for (int iii = i + ii; iii < 320; iii += 8)
+ _screen->drawClippedLine(iii, 0, iii, 199, 12);
+ } else {
+ for (int iii = i + ii; iii < 200; iii += 8)
+ _screen->drawClippedLine(0, iii, 319, iii, 12);
+ }
+ _screen->updateScreen();
+ uint32 c = _vm->_system->getMillis();
+ if (e > c)
+ _vm->_system->delayMillis(e - c);
+ }
+ }
+}
+
+int EoBEngine::mainMenu() {
+ int menuChoice = _menuChoiceInit;
+ _menuChoiceInit = 0;
+
+ Screen::FontId of = _screen->_currentFont;
+
+ while (menuChoice >= 0 && !shouldQuit()) {
+ switch (menuChoice) {
+ case 0: {
+ if (_configRenderMode != Common::kRenderEGA)
+ _screen->loadPalette("EOBPAL.COL", _screen->getPalette(0));
+ _screen->loadEoBBitmap("INTRO", _cgaMappingDefault, 5, 3, 2);
+ _screen->setScreenPalette(_screen->getPalette(0));
+ _screen->_curPage = 2;
+ of = _screen->setFont(Screen::FID_6_FNT);
+ Common::String versionString(Common::String::format("ScummVM %s", gScummVMVersion));
+ _screen->printText(versionString.c_str(), 280 - versionString.size() * 6, 153, _screen->getPagePixel(2, 0, 0), 0);
+ _screen->setFont(of);
+ _screen->fillRect(0, 159, 319, 199, _screen->getPagePixel(2, 0, 0));
+ gui_drawBox(77, 165, 173, 29, 14, 13, 12);
+ gui_drawBox(76, 164, 175, 31, 14, 13, -1);
+ _screen->_curPage = 0;
+ _screen->copyRegion(0, 0, 0, 0, 320, 200, 2, 0, Screen::CR_NO_P_CHECK);
+ _screen->updateScreen();
+ _allowImport = true;
+ menuChoice = mainMenuLoop();
+ _allowImport = false;
+ } break;
+
+ case 1:
+ // load game in progress
+ menuChoice = -1;
+ break;
+
+ case 2:
+ // create new party
+ menuChoice = -2;
+ break;
+
+ case 3:
+ // quit
+ menuChoice = -5;
+ break;
+
+ case 4:
+ // intro
+ _sound->loadSoundFile("SOUND");
+ _screen->hideMouse();
+ seq_playIntro();
+ _screen->showMouse();
+ _sound->loadSoundFile("ADLIB");
+ menuChoice = 0;
+ break;
+ }
+ }
+
+ return shouldQuit() ? -5 : menuChoice;
+}
+
+int EoBEngine::mainMenuLoop() {
+ int sel = -1;
+ do {
+ _screen->setScreenDim(28);
+ _gui->simpleMenu_setup(8, 0, _mainMenuStrings, -1, 0, 0);
+
+ while (sel == -1 && !shouldQuit())
+ sel = _gui->simpleMenu_process(8, _mainMenuStrings, 0, -1, 0);
+ } while ((sel < 0 || sel > 5) && !shouldQuit());
+
+ return sel + 1;
+}
+
+void EoBEngine::seq_playIntro() {
+ EoBIntroPlayer(this, _screen).start();
+}
+
+void EoBEngine::seq_playFinale() {
+ Common::SeekableReadStream *s = _res->createReadStream("TEXT.DAT");
+ _screen->loadFileDataToPage(s, 5, 32000);
+ delete s;
+
+ snd_playSoundEffect(20);
+
+ _txt->resetPageBreakString();
+ _txt->setWaitButtonMode(1);
+ _txt->setupField(12, true);
+ gui_drawBox(0, 0, 176, 175, guiSettings()->colors.frame1, guiSettings()->colors.frame2, guiSettings()->colors.fill);
+ _txt->printDialogueText(51, _moreStrings[0]);
+
+ if (!checkScriptFlags(0x1ffe)) {
+ _screen->fadeToBlack();
+ return;
+ }
+
+ _txt->printDialogueText(_finBonusStrings[0]);
+ for (int i = 0; i < 6; i++) {
+ _txt->printDialogueText(_finBonusStrings[1]);
+ if (_characters[i].flags & 1)
+ _txt->printDialogueText(_characters[i].name);
+ }
+
+ uint32 password = 0;
+ for (int i = 0; i < 4; i++) {
+ if (!(_characters[i].flags & 1))
+ continue;
+
+ int len = strlen(_characters[i].name);
+ for (int ii = 0; ii < len; ii++) {
+ uint32 c = _characters[i].name[ii];
+ password += (c * c);
+ }
+ }
+
+ _txt->printDialogueText(Common::String::format(_finBonusStrings[2], password).c_str(), true);
+ _screen->fadeToBlack();
+}
+
+void EoBEngine::seq_xdeath() {
+ uint8 *shapes1[5];
+ uint8 *shapes2;
+
+ _screen->loadShapeSetBitmap("XDEATH2", 5, 3);
+ for (int i = 0; i < 4; i++)
+ shapes1[i] = _screen->encodeShape(i / 2 * 14, i / 2 * 88, 14, 88, true, _cgaMappingDefault);
+ _screen->loadShapeSetBitmap("XDEATH3", 5, 3);
+ shapes2 = _screen->encodeShape(22, 0, 16, 95, true, _cgaMappingDefault);
+ _screen->loadEoBBitmap("XDEATH1", _cgaMappingDefault, 5, 3, -1);
+ _screen->convertPage(3, 2, _cgaMappingDefault);
+ _screen->setCurPage(0);
+
+ for (int i = 0; i < 10; i++) {
+ if (i == 2)
+ snd_playSoundEffect(72);
+ else if (i == 4 || i == 6)
+ snd_playSoundEffect(54);
+ else
+ snd_playSoundEffect(34);
+
+ if (i < 6) {
+ _screen->copyRegion((i % 3) * 104, i / 3 * 88, 32, 10, 104, 88, 2, 0, Screen::CR_NO_P_CHECK);
+ } else {
+ snd_playSoundEffect(42);
+ _screen->drawShape(0, shapes1[i - 6], 32, 10, 0);
+ }
+
+ _screen->updateScreen();
+ delay(4 * _tickLength);
+ }
+
+ const ScreenDim *dm = _screen->getScreenDim(5);
+ _screen->modifyScreenDim(5, dm->sx, 8, dm->w, dm->h);
+ _screen->copyRegion(0, 0, 0, 0, 176, 120, 0, 5, Screen::CR_NO_P_CHECK);
+
+ for (int i = 0; i < 19; i++) {
+ snd_playSoundEffect(119);
+ _screen->copyRegion(0, 0, 0, 0, 176, 120, 5, 2, Screen::CR_NO_P_CHECK);
+ _screen->drawShape(2, shapes2, 24, i * 5 - 90, 5);
+ _screen->copyRegion(0, 0, 0, 0, 176, 120, 2, 0, Screen::CR_NO_P_CHECK);
+ _screen->updateScreen();
+ delay(2 * _tickLength);
+ }
+
+ _screen->modifyScreenDim(5, dm->sx, 0, dm->w, dm->h);
+
+ snd_playSoundEffect(5);
+ delay(60 * _tickLength);
+
+ for (int i = 0; i < 4; i++)
+ delete[] shapes1[i];
+ delete[] shapes2;
+
+ gui_drawPlayField(false);
+ gui_drawAllCharPortraitsWithStats();
+}
+
+} // End of namespace Kyra
+
+#endif // ENABLE_EOB
diff --git a/engines/kyra/sequences_hof.cpp b/engines/kyra/sequences_hof.cpp
index 50b5db78fc..686c3c9320 100644
--- a/engines/kyra/sequences_hof.cpp
+++ b/engines/kyra/sequences_hof.cpp
@@ -234,6 +234,8 @@ void KyraEngine_HoF::seq_playSequences(int startSeq, int endSeq) {
int32 dly = _tickLength - (now - _seqSubFrameStartTime);
if (dly > 0)
delay(MIN<uint32>(dly, tdiff));
+ else
+ updateInput();
}
}
@@ -263,6 +265,8 @@ void KyraEngine_HoF::seq_playSequences(int startSeq, int endSeq) {
int32 dly = _tickLength - (now - _seqSubFrameStartTime);
if (dly > 0)
delay(MIN<uint32>(dly, tdiff));
+ else
+ updateInput();
}
seq_sequenceCommand(cseq.finalCommand);
@@ -2622,7 +2626,7 @@ void KyraEngine_HoF::seq_displayScrollText(uint8 *data, const ScreenDim *d, int
while (*str2) {
cChar[0] = *str2;
_screen->printText(cChar, x, y, col1++, 0);
- x += _screen->getCharWidth(*str2++);
+ x += _screen->getCharWidth((uint8)*str2++);
}
palCycle = true;
} else if (!strcmp(str, specialData[1])) {
@@ -2631,7 +2635,7 @@ void KyraEngine_HoF::seq_displayScrollText(uint8 *data, const ScreenDim *d, int
while (*str2) {
cChar[0] = *str2;
_screen->printText(cChar, x, y, col1--, 0);
- x += _screen->getCharWidth(*str2++);
+ x += _screen->getCharWidth((uint8)*str2++);
}
palCycle = true;
} else {
@@ -2773,15 +2777,15 @@ void KyraEngine_HoF::seq_init() {
return;
if (_flags.isDemo && !_flags.isTalkie) {
- _demoAnimData = _staticres->loadShapeAnimData_v1(k2SeqplayShapeAnimData, _itemAnimDataSize);
+ _demoAnimData = _staticres->loadShapeAnimData_v1(k2SeqplayShapeAnimData, _itemAnimDefinitionSize);
uint8 *shp = _res->fileData("icons.shp", 0);
uint32 outsize = READ_LE_UINT16(shp + 4);
_animShapeFiledata = new uint8[outsize];
Screen::decodeFrame4(shp + 10, _animShapeFiledata, outsize);
delete[] shp;
- for (int numShp = 0; getShapePtr(numShp); ++numShp)
- addShapeToPool(_screen->getPtrToShape(_animShapeFiledata, numShp), numShp);
+ for (int i = 0; i < 20; i++)
+ addShapeToPool(_screen->getPtrToShape(_animShapeFiledata, i), i);
} else {
const MainMenu::StaticData data = {
{ _sequenceStrings[97], _sequenceStrings[96], _sequenceStrings[95], _sequenceStrings[98], 0 },
diff --git a/engines/kyra/sequences_lok.cpp b/engines/kyra/sequences_lok.cpp
index 2de0565a74..3475402a98 100644
--- a/engines/kyra/sequences_lok.cpp
+++ b/engines/kyra/sequences_lok.cpp
@@ -381,10 +381,10 @@ void KyraEngine_LoK::seq_createAmuletJewel(int jewel, int page, int noSound, int
}
}
}
- _screen->drawShape(page, _shapes[323+jewel], _amuletX2[jewel], _amuletY2[jewel], 0, 0);
+ _screen->drawShape(page, _shapes[323 + jewel], _amuletX2[jewel], _amuletY2[jewel], 0, 0);
_screen->updateScreen();
_screen->showMouse();
- setGameFlag(0x55+jewel);
+ setGameFlag(0x55 + jewel);
}
void KyraEngine_LoK::seq_brandonHealing() {
@@ -764,7 +764,7 @@ void KyraEngine_LoK::seq_makeBrandonWisp() {
if (_flags.platform == Common::kPlatformAmiga) {
if ((_currentCharacter->sceneId >= 229 && _currentCharacter->sceneId <= 245) ||
- (_currentCharacter->sceneId >= 118 && _currentCharacter->sceneId <= 186))
+ (_currentCharacter->sceneId >= 118 && _currentCharacter->sceneId <= 186))
_screen->fadePalette(_screen->getPalette(10), 0x54);
} else {
if (_currentCharacter->sceneId >= 229 && _currentCharacter->sceneId <= 245)
@@ -1322,7 +1322,7 @@ void KyraEngine_LoK::seq_playCredits() {
_screen->copyRegion(0, 32, 0, 32, 320, 128, 4, 2, Screen::CR_NO_P_CHECK);
bottom = 0;
- for (CreditsLineList::iterator it = lines.begin(); it != lines.end(); ++it) {
+ for (CreditsLineList::iterator it = lines.begin(); it != lines.end();) {
if (it->y < 0) {
it = lines.erase(it);
continue;
@@ -1338,6 +1338,8 @@ void KyraEngine_LoK::seq_playCredits() {
it->y--;
if (it->y > bottom)
bottom = it->y;
+
+ ++it;
}
_screen->copyRegion(0, 32, 0, 32, 320, 128, 2, 0, Screen::CR_NO_P_CHECK);
@@ -1728,7 +1730,7 @@ int KyraEngine_LoK::handleBeadState() {
if (_system->getMillis() > _beadStateTimer2 && _malcolmFlag == 7 && !_unkAmuletVar && !_text->printed()) {
snd_playSoundEffect(0x0B);
if (_currentCharacter->x1 > 233 && _currentCharacter->x1 < 305 && _currentCharacter->y1 > 85 && _currentCharacter->y1 < 105 &&
- (_brandonStatusBit & 0x20)) {
+ (_brandonStatusBit & 0x20)) {
_beadState1.unk8 = 290;
_beadState1.unk9 = 40;
_beadStateVar = 5;
diff --git a/engines/kyra/sequences_lol.cpp b/engines/kyra/sequences_lol.cpp
index 83d525d400..a06f2077ba 100644
--- a/engines/kyra/sequences_lol.cpp
+++ b/engines/kyra/sequences_lol.cpp
@@ -55,6 +55,8 @@ int LoLEngine::processPrologue() {
preInit();
+ Common::String versionString(Common::String::format("ScummVM %s", gScummVMVersion));
+
int processSelection = -1;
while (!shouldQuit() && processSelection == -1) {
_screen->loadBitmap("TITLE.CPS", 2, 2, &_screen->getPalette(0));
@@ -62,8 +64,8 @@ int LoLEngine::processPrologue() {
_screen->setFont(Screen::FID_6_FNT);
// Original version: (260|193) "V CD1.02 D"
- const int width = _screen->getTextWidth(gScummVMVersion);
- _screen->fprintString("SVM %s", 300 - width, 193, 0x67, 0x00, 0x04, gScummVMVersion);
+ const int width = _screen->getTextWidth(versionString.c_str());
+ _screen->fprintString("%s", 320 - width, 193, 0x67, 0x00, 0x04, versionString.c_str());
_screen->setFont(_flags.lang == Common::JA_JPN ? Screen::FID_SJIS_FNT : Screen::FID_9_FNT);
_screen->fadePalette(_screen->getPalette(0), 0x1E);
@@ -88,25 +90,25 @@ int LoLEngine::processPrologue() {
// quit instantly.
break;
- case 0: // New game
+ case 0: // New game
processSelection = 0;
break;
- case 1: // Show intro
+ case 1: // Show intro
showIntro();
break;
- case 2: { // "Lore of the Lands" (only CD version)
+ case 2: { // "Lore of the Lands" (only CD version)
HistoryPlayer history(this);
history.play();
- } break;
+ } break;
- case 3: // Load game
+ case 3: // Load game
if (_gui->runMenu(_gui->_loadMenu))
processSelection = 3;
break;
- case 4: // Quit game
+ case 4: // Quit game
default:
quitGame();
updateInput();
@@ -127,17 +129,17 @@ int LoLEngine::processPrologue() {
}
void LoLEngine::setupPrologueData(bool load) {
- static const char * const fileListCD[] = {
+ static const char *const fileListCD[] = {
"GENERAL.PAK", "INTROVOC.PAK", "STARTUP.PAK", "INTRO1.PAK",
"INTRO2.PAK", "INTRO3.PAK", "INTRO4.PAK", "INTRO5.PAK",
"INTRO6.PAK", "INTRO7.PAK", "INTRO8.PAK", "INTRO9.PAK",
"HISTORY.PAK", 0
};
- static const char * const fileListFloppy[] = {
+ static const char *const fileListFloppy[] = {
"INTRO.PAK", "INTROVOC.PAK", 0
};
- const char * const *fileList = _flags.isTalkie ? fileListCD : fileListFloppy;
+ const char *const *fileList = _flags.isTalkie ? fileListCD : fileListFloppy;
char filename[32];
for (uint i = 0; fileList[i]; ++i) {
@@ -408,10 +410,10 @@ void LoLEngine::kingSelectionIntro() {
index = MAX(index, 4);
_chargenWSA->displayFrame(_chargenFrameTable[index], 0, 113, 0, 0, 0, 0);
- _screen->copyRegion(_selectionPosTable[_selectionChar1IdxTable[index]*2+0], _selectionPosTable[_selectionChar1IdxTable[index]*2+1], _charPreviews[0].x, _charPreviews[0].y, 32, 32, 4, 0);
- _screen->copyRegion(_selectionPosTable[_selectionChar2IdxTable[index]*2+0], _selectionPosTable[_selectionChar2IdxTable[index]*2+1], _charPreviews[1].x, _charPreviews[1].y, 32, 32, 4, 0);
- _screen->copyRegion(_selectionPosTable[_selectionChar3IdxTable[index]*2+0], _selectionPosTable[_selectionChar3IdxTable[index]*2+1], _charPreviews[2].x, _charPreviews[2].y, 32, 32, 4, 0);
- _screen->copyRegion(_selectionPosTable[_selectionChar4IdxTable[index]*2+0], _selectionPosTable[_selectionChar4IdxTable[index]*2+1], _charPreviews[3].x, _charPreviews[3].y, 32, 32, 4, 0);
+ _screen->copyRegion(_selectionPosTable[_selectionChar1IdxTable[index] * 2 + 0], _selectionPosTable[_selectionChar1IdxTable[index] * 2 + 1], _charPreviews[0].x, _charPreviews[0].y, 32, 32, 4, 0);
+ _screen->copyRegion(_selectionPosTable[_selectionChar2IdxTable[index] * 2 + 0], _selectionPosTable[_selectionChar2IdxTable[index] * 2 + 1], _charPreviews[1].x, _charPreviews[1].y, 32, 32, 4, 0);
+ _screen->copyRegion(_selectionPosTable[_selectionChar3IdxTable[index] * 2 + 0], _selectionPosTable[_selectionChar3IdxTable[index] * 2 + 1], _charPreviews[2].x, _charPreviews[2].y, 32, 32, 4, 0);
+ _screen->copyRegion(_selectionPosTable[_selectionChar4IdxTable[index] * 2 + 0], _selectionPosTable[_selectionChar4IdxTable[index] * 2 + 1], _charPreviews[3].x, _charPreviews[3].y, 32, 32, 4, 0);
_screen->updateScreen();
uint32 waitEnd = _system->getMillis() + 7 * _tickLength;
@@ -428,7 +430,7 @@ void LoLEngine::kingSelectionIntro() {
resetSkipFlag();
- _chargenWSA->displayFrame(0x10, 0,113, 0, 0, 0, 0);
+ _chargenWSA->displayFrame(0x10, 0, 113, 0, 0, 0, 0);
_screen->updateScreen();
_sound->voiceStop(&_speechHandle);
}
@@ -450,11 +452,11 @@ void LoLEngine::kingSelectionReminder() {
int index = 0;
while ((!speechEnabled() || (speechEnabled() && _sound->voiceIsPlaying(&_speechHandle))) && _charSelection == -1 && !shouldQuit() && index < 15) {
- _chargenWSA->displayFrame(_chargenFrameTable[index+9], 0, 113, 0, 0, 0, 0);
- _screen->copyRegion(_selectionPosTable[_reminderChar1IdxTable[index]*2+0], _selectionPosTable[_reminderChar1IdxTable[index]*2+1], _charPreviews[0].x, _charPreviews[0].y, 32, 32, 4, 0);
- _screen->copyRegion(_selectionPosTable[_reminderChar2IdxTable[index]*2+0], _selectionPosTable[_reminderChar2IdxTable[index]*2+1], _charPreviews[1].x, _charPreviews[1].y, 32, 32, 4, 0);
- _screen->copyRegion(_selectionPosTable[_reminderChar3IdxTable[index]*2+0], _selectionPosTable[_reminderChar3IdxTable[index]*2+1], _charPreviews[2].x, _charPreviews[2].y, 32, 32, 4, 0);
- _screen->copyRegion(_selectionPosTable[_reminderChar4IdxTable[index]*2+0], _selectionPosTable[_reminderChar4IdxTable[index]*2+1], _charPreviews[3].x, _charPreviews[3].y, 32, 32, 4, 0);
+ _chargenWSA->displayFrame(_chargenFrameTable[index + 9], 0, 113, 0, 0, 0, 0);
+ _screen->copyRegion(_selectionPosTable[_reminderChar1IdxTable[index] * 2 + 0], _selectionPosTable[_reminderChar1IdxTable[index] * 2 + 1], _charPreviews[0].x, _charPreviews[0].y, 32, 32, 4, 0);
+ _screen->copyRegion(_selectionPosTable[_reminderChar2IdxTable[index] * 2 + 0], _selectionPosTable[_reminderChar2IdxTable[index] * 2 + 1], _charPreviews[1].x, _charPreviews[1].y, 32, 32, 4, 0);
+ _screen->copyRegion(_selectionPosTable[_reminderChar3IdxTable[index] * 2 + 0], _selectionPosTable[_reminderChar3IdxTable[index] * 2 + 1], _charPreviews[2].x, _charPreviews[2].y, 32, 32, 4, 0);
+ _screen->copyRegion(_selectionPosTable[_reminderChar4IdxTable[index] * 2 + 0], _selectionPosTable[_reminderChar4IdxTable[index] * 2 + 1], _charPreviews[3].x, _charPreviews[3].y, 32, 32, 4, 0);
_screen->updateScreen();
uint32 waitEnd = _system->getMillis() + 8 * _tickLength;
@@ -524,7 +526,7 @@ void LoLEngine::updateSelectionAnims() {
continue;
const int index = _selectionAnimIndexTable[_selectionAnimFrames[i] + i * 2];
- _screen->copyRegion(_selectionPosTable[index*2+0], _selectionPosTable[index*2+1], _charPreviews[i].x, _charPreviews[i].y, 32, 32, 4, 0);
+ _screen->copyRegion(_selectionPosTable[index * 2 + 0], _selectionPosTable[index * 2 + 1], _charPreviews[i].x, _charPreviews[i].y, 32, 32, 4, 0);
int delayTime = 0;
if (_selectionAnimFrames[i] == 1)
@@ -581,12 +583,12 @@ int LoLEngine::selectionCharInfo(int character) {
if (_flags.platform == Common::kPlatformPC98) {
for (int i = 0; i < 5; ++i)
- _screen->printText(_tim->getCTableEntry(idx+i), 60, 128 + i * 8, 0x41, 0x00);
+ _screen->printText(_tim->getCTableEntry(idx + i), 60, 128 + i * 8, 0x41, 0x00);
_screen->printText(_tim->getCTableEntry(69), 112, 168, 0x01, 0x00);
} else {
for (int i = 0; i < 5; ++i)
- _screen->fprintStringIntro("%s", 50, 127 + i * 10, 0x53, 0x00, 0xCF, 0x20, _tim->getCTableEntry(idx+i));
+ _screen->fprintStringIntro("%s", 50, 127 + i * 10, 0x53, 0x00, 0xCF, 0x20, _tim->getCTableEntry(idx + i));
_screen->fprintStringIntro("%s", 100, 168, 0x32, 0x00, 0xCF, 0x20, _tim->getCTableEntry(69));
}
@@ -613,10 +615,10 @@ int LoLEngine::selectionCharInfo(int character) {
if (_flags.platform == Common::kPlatformPC98) {
for (int i = 0; i < 5; ++i)
- _screen->printText(_tim->getCTableEntry(64+i), 16, 32 + i * 8, 0xC1, 0x00);
+ _screen->printText(_tim->getCTableEntry(64 + i), 16, 32 + i * 8, 0xC1, 0x00);
} else {
for (int i = 0; i < 5; ++i)
- _screen->fprintStringIntro("%s", 3, 28 + i * 10, 0x32, 0x00, 0x9C, 0x20, _tim->getCTableEntry(64+i));
+ _screen->fprintStringIntro("%s", 3, 28 + i * 10, 0x32, 0x00, 0x9C, 0x20, _tim->getCTableEntry(64 + i));
}
resetSkipFlag();
@@ -668,7 +670,7 @@ int LoLEngine::getCharSelection() {
if (inputFlag == 200) {
for (int i = 0; i < 4; ++i) {
if (_charPreviews[i].x <= _mouseX && _mouseX <= _charPreviews[i].x + 31 &&
- _charPreviews[i].y <= _mouseY && _mouseY <= _charPreviews[i].y + 31)
+ _charPreviews[i].y <= _mouseY && _mouseY <= _charPreviews[i].y + 31)
return i;
}
}
@@ -752,7 +754,7 @@ HistoryPlayer::~HistoryPlayer() {
void HistoryPlayer::play() {
int dataSize = 0;
- const char *data = (const char *)_vm->staticres()->loadRawData(kLolHistory, dataSize);
+ const char *data = (const char *)_vm->staticres()->loadRawData(kLoLHistory, dataSize);
if (!data)
error("Could not load history data");
@@ -788,7 +790,7 @@ void HistoryPlayer::play() {
for (; voiceFilename[3] <= '9' && !_vm->shouldQuit() && !_vm->skipFlag(); ++voiceFilename[3], voiceFilename[4] = 'a') {
while (!_vm->shouldQuit() && !_vm->skipFlag()) {
- if (!sound->voiceFileIsPresent(voiceFilename))
+ if (!sound->isVoicePresent(voiceFilename))
break;
if (data[part * 15] == voiceFilename[3] && data[part * 15 + 1] == voiceFilename[4]) {
@@ -998,16 +1000,16 @@ void HistoryPlayer::updateFire() {
// outro
void LoLEngine::setupEpilogueData(bool load) {
- static const char * const fileListCD[] = {
+ static const char *const fileListCD[] = {
"GENERAL.PAK", "INTROVOC.PAK", "STARTUP.PAK",
"FINALE.PAK", "FINALE1.PAK", "FINALE2.PAK", 0
};
- static const char * const fileListFloppy[] = {
+ static const char *const fileListFloppy[] = {
"GENERAL.PAK", "INTRO.PAK", "FINALE1.PAK", "FINALE2.PAK", 0
};
- const char * const *fileList = _flags.isTalkie ? fileListCD : fileListFloppy;
+ const char *const *fileList = _flags.isTalkie ? fileListCD : fileListFloppy;
assert(fileList);
char filename[32];
@@ -1195,14 +1197,14 @@ void LoLEngine::showCredits() {
if (_flags.platform == Common::kPlatformPC98) {
int size = 0;
- const uint8 *internCredits = _staticres->loadRawData(kLolCredits, size);
+ const uint8 *internCredits = _staticres->loadRawData(kLoLCredits, size);
assert(size > 0);
credits = new char[size];
assert(credits);
memcpy(credits, internCredits, size);
- _staticres->unloadId(kLolCredits);
+ _staticres->unloadId(kLoLCredits);
} else {
credits = (char *)_res->fileData("CREDITS.TXT", 0);
}
@@ -1446,7 +1448,7 @@ void LoLEngine::processCredits(char *t, int dimState, int page, int delayTime) {
}
for (int i = 0; i < countStrings; ++i) {
- CreditsString &s = strings[i+1];
+ CreditsString &s = strings[i + 1];
int x = s.x, y = s.y;
if (y < _screen->_curDim->h) {
@@ -1512,7 +1514,7 @@ void LoLEngine::loadOutroShapes(int file, uint8 **storage) {
if (i < 8)
storage[i] = _screen->makeShapeCopy(_screen->getCPagePtr(5), i);
else
- storage[i] = _screen->makeShapeCopy(_screen->getCPagePtr(5), i+4);
+ storage[i] = _screen->makeShapeCopy(_screen->getCPagePtr(5), i + 4);
}
}
diff --git a/engines/kyra/sound.cpp b/engines/kyra/sound.cpp
index 0e83c1cb1f..73c20ee6df 100644
--- a/engines/kyra/sound.cpp
+++ b/engines/kyra/sound.cpp
@@ -43,25 +43,30 @@ Sound::Sound(KyraEngine_v1 *vm, Audio::Mixer *mixer)
Sound::~Sound() {
}
-bool Sound::voiceFileIsPresent(const char *file) {
- for (int i = 0; _supportedCodecs[i].fileext; ++i) {
- Common::String f = file;
- f += _supportedCodecs[i].fileext;
- if (_vm->resource()->getFileSize(f.c_str()) > 0)
- return true;
- }
+Sound::kType Sound::getSfxType() const {
+ return getMusicType();
+}
+void Sound::setSoundList(const AudioDataStruct *list) {
+ _soundDataList = list;
+}
+
+bool Sound::hasSoundFile(uint file) const {
+ return (fileListEntry(file) != 0);
+}
+
+bool Sound::isPlaying() const {
return false;
}
-bool Sound::isVoicePresent(const char *file) {
- char filenamebuffer[25];
+bool Sound::isVoicePresent(const char *file) const {
+ Common::String filename;
for (int i = 0; _supportedCodecs[i].fileext; ++i) {
- strcpy(filenamebuffer, file);
- strcat(filenamebuffer, _supportedCodecs[i].fileext);
+ filename = file;
+ filename += _supportedCodecs[i].fileext;
- if (_vm->resource()->exists(filenamebuffer))
+ if (_vm->resource()->exists(filename.c_str()))
return true;
}
@@ -80,15 +85,15 @@ int32 Sound::voicePlay(const char *file, Audio::SoundHandle *handle, uint8 volum
return playTime;
}
-Audio::SeekableAudioStream *Sound::getVoiceStream(const char *file) {
- char filenamebuffer[25];
+Audio::SeekableAudioStream *Sound::getVoiceStream(const char *file) const {
+ Common::String filename;
Audio::SeekableAudioStream *audioStream = 0;
for (int i = 0; _supportedCodecs[i].fileext; ++i) {
- strcpy(filenamebuffer, file);
- strcat(filenamebuffer, _supportedCodecs[i].fileext);
+ filename = file;
+ filename += _supportedCodecs[i].fileext;
- Common::SeekableReadStream *stream = _vm->resource()->createReadStream(filenamebuffer);
+ Common::SeekableReadStream *stream = _vm->resource()->createReadStream(filename);
if (!stream)
continue;
@@ -136,7 +141,7 @@ void Sound::voiceStop(const Audio::SoundHandle *handle) {
}
}
-bool Sound::voiceIsPlaying(const Audio::SoundHandle *handle) {
+bool Sound::voiceIsPlaying(const Audio::SoundHandle *handle) const {
if (!handle) {
for (int h = 0; h < kNumChannelHandles; ++h) {
if (_mixer->isSoundHandleActive(_soundChannels[h]))
@@ -149,7 +154,7 @@ bool Sound::voiceIsPlaying(const Audio::SoundHandle *handle) {
return false;
}
-bool Sound::allVoiceChannelsPlaying() {
+bool Sound::allVoiceChannelsPlaying() const {
for (int i = 0; i < kNumChannelHandles; ++i)
if (!_mixer->isSoundHandleActive(_soundChannels[i]))
return false;
@@ -158,6 +163,91 @@ bool Sound::allVoiceChannelsPlaying() {
#pragma mark -
+MixedSoundDriver::MixedSoundDriver(KyraEngine_v1 *vm, Audio::Mixer *mixer, Sound *music, Sound *sfx)
+ : Sound(vm, mixer), _music(music), _sfx(sfx) {
+}
+
+MixedSoundDriver::~MixedSoundDriver() {
+ delete _music;
+ delete _sfx;
+}
+
+Sound::kType MixedSoundDriver::getMusicType() const {
+ return _music->getMusicType();
+}
+
+Sound::kType MixedSoundDriver::getSfxType() const {
+ return _sfx->getSfxType();
+}
+
+bool MixedSoundDriver::init() {
+ return (_music->init() && _sfx->init());
+}
+
+void MixedSoundDriver::process() {
+ _music->process();
+ _sfx->process();
+}
+
+void MixedSoundDriver::updateVolumeSettings() {
+ _music->updateVolumeSettings();
+ _sfx->updateVolumeSettings();
+}
+
+void MixedSoundDriver::setSoundList(const AudioDataStruct *list) {
+ _music->setSoundList(list);
+ _sfx->setSoundList(list);
+}
+
+bool MixedSoundDriver::hasSoundFile(uint file) const {
+ return _music->hasSoundFile(file) && _sfx->hasSoundFile(file);
+}
+
+void MixedSoundDriver::loadSoundFile(uint file) {
+ _music->loadSoundFile(file);
+ _sfx->loadSoundFile(file);
+}
+
+void MixedSoundDriver::loadSoundFile(Common::String file) {
+ _music->loadSoundFile(file);
+ _sfx->loadSoundFile(file);
+}
+
+void MixedSoundDriver::loadSfxFile(Common::String file) {
+ _sfx->loadSoundFile(file);
+}
+
+void MixedSoundDriver::playTrack(uint8 track) {
+ _music->playTrack(track);
+}
+
+void MixedSoundDriver::haltTrack() {
+ _music->haltTrack();
+}
+
+bool MixedSoundDriver::isPlaying() const {
+ return _music->isPlaying() | _sfx->isPlaying();
+}
+
+void MixedSoundDriver::playSoundEffect(uint8 track, uint8 volume) {
+ _sfx->playSoundEffect(track, volume);
+}
+
+void MixedSoundDriver::stopAllSoundEffects() {
+ _sfx->stopAllSoundEffects();
+}
+
+void MixedSoundDriver::beginFadeOut() {
+ _music->beginFadeOut();
+}
+
+void MixedSoundDriver::pause(bool paused) {
+ _music->pause(paused);
+ _sfx->pause(paused);
+}
+
+#pragma mark -
+
void KyraEngine_v1::snd_playTheme(int file, int track) {
if (_curMusicTheme == file)
return;
@@ -176,7 +266,7 @@ void KyraEngine_v1::snd_playTheme(int file, int track) {
}
void KyraEngine_v1::snd_playSoundEffect(int track, int volume) {
- _sound->playSoundEffect(track);
+ _sound->playSoundEffect(track, volume);
}
void KyraEngine_v1::snd_playWanderScoreViaMap(int command, int restart) {
@@ -244,16 +334,7 @@ namespace {
// A simple wrapper to create VOC streams the way like creating MP3, OGG/Vorbis and FLAC streams.
// Possible TODO: Think of making this complete and moving it to sound/voc.cpp ?
Audio::SeekableAudioStream *makeVOCStream(Common::SeekableReadStream *stream, DisposeAfterUse::Flag disposeAfterUse) {
-
-#ifdef STREAM_AUDIO_FROM_DISK
Audio::SeekableAudioStream *as = Audio::makeVOCStream(stream, Audio::FLAG_UNSIGNED, disposeAfterUse);
-#else
- Audio::SeekableAudioStream *as = Audio::makeVOCStream(stream, Audio::FLAG_UNSIGNED, DisposeAfterUse::NO);
-
- if (disposeAfterUse)
- delete stream;
-#endif
-
return as;
}
diff --git a/engines/kyra/sound.h b/engines/kyra/sound.h
index c3c32331be..63cec48d00 100644
--- a/engines/kyra/sound.h
+++ b/engines/kyra/sound.h
@@ -58,7 +58,7 @@ public:
};
virtual kType getMusicType() const = 0;
- virtual kType getSfxType() const { return getMusicType(); }
+ virtual kType getSfxType() const;
/**
* Initializes the output device.
@@ -83,7 +83,7 @@ public:
*
* @param list soundfile list
*/
- virtual void setSoundList(const AudioDataStruct *list) { _soundDataList = list; }
+ virtual void setSoundList(const AudioDataStruct *list);
/**
* Checks if a given sound file is present.
@@ -91,7 +91,7 @@ public:
* @param track track number
* @return true if available, false otherwise
*/
- virtual bool hasSoundFile(uint file) const { return (fileListEntry(file) != 0); }
+ virtual bool hasSoundFile(uint file) const;
/**
* Load a specifc sound file for use of
@@ -128,7 +128,7 @@ public:
*
* @param track sound effect id
*/
- virtual void playSoundEffect(uint8 track) = 0;
+ virtual void playSoundEffect(uint8 track, uint8 volume = 0xff) = 0;
/**
* Stop playback of all sfx tracks.
@@ -140,7 +140,7 @@ public:
*
* @return true if playing, false otherwise
*/
- virtual bool isPlaying() const { return false; }
+ virtual bool isPlaying() const;
/**
* Starts fading out the volume.
@@ -163,15 +163,13 @@ public:
void enableSFX(bool enable) { _sfxEnabled = enable; }
bool sfxEnabled() const { return _sfxEnabled; }
- virtual bool voiceFileIsPresent(const char *file);
-
/**
* Checks whether a voice file with the given name is present
*
* @param file file name
* @return true if available, false otherwise
*/
- bool isVoicePresent(const char *file);
+ bool isVoicePresent(const char *file) const;
/**
* Plays the specified voice file.
@@ -188,7 +186,7 @@ public:
*/
virtual int32 voicePlay(const char *file, Audio::SoundHandle *handle = 0, uint8 volume = 255, bool isSfx = false);
- Audio::SeekableAudioStream *getVoiceStream(const char *file);
+ Audio::SeekableAudioStream *getVoiceStream(const char *file) const;
bool playVoiceStream(Audio::AudioStream *stream, Audio::SoundHandle *handle = 0, uint8 volume = 255, bool isSfx = false);
@@ -197,21 +195,21 @@ public:
*
* @return true when playing, else false
*/
- bool voiceIsPlaying(const Audio::SoundHandle *handle = 0);
+ bool voiceIsPlaying(const Audio::SoundHandle *handle = 0) const;
/**
* Checks if all voice handles are used.
*
* @return false when a handle is free, else true
*/
- bool allVoiceChannelsPlaying();
+ bool allVoiceChannelsPlaying() const;
/**
* Checks how long a voice has been playing
*
* @return time in milliseconds
*/
- uint32 voicePlayedTime(const Audio::SoundHandle &handle) {
+ uint32 voicePlayedTime(const Audio::SoundHandle &handle) const {
return _mixer->getSoundElapsedTime(handle);
}
@@ -219,6 +217,16 @@ public:
* Stops playback of the current voice.
*/
void voiceStop(const Audio::SoundHandle *handle = 0);
+
+ /**
+ * Receive notifications from a song at certain points.
+ */
+ virtual int checkTrigger() { return 0; }
+
+ /**
+ * Reset sound trigger.
+ */
+ virtual void resetTrigger() {}
protected:
const char *fileListEntry(int file) const { return (_soundDataList != 0 && file >= 0 && file < _soundDataList->fileListLen) ? _soundDataList->fileList[file] : ""; }
int fileListLen() const { return _soundDataList->fileListLen; }
@@ -253,34 +261,34 @@ private:
class MixedSoundDriver : public Sound {
public:
- MixedSoundDriver(KyraEngine_v1 *vm, Audio::Mixer *mixer, Sound *music, Sound *sfx) : Sound(vm, mixer), _music(music), _sfx(sfx) {}
- ~MixedSoundDriver() { delete _music; delete _sfx; }
+ MixedSoundDriver(KyraEngine_v1 *vm, Audio::Mixer *mixer, Sound *music, Sound *sfx);
+ ~MixedSoundDriver();
- kType getMusicType() const { return _music->getMusicType(); }
- kType getSfxType() const { return _sfx->getSfxType(); }
+ virtual kType getMusicType() const;
+ virtual kType getSfxType() const;
- bool init() { return (_music->init() && _sfx->init()); }
- void process() { _music->process(); _sfx->process(); }
+ virtual bool init();
+ virtual void process();
- void updateVolumeSettings() { _music->updateVolumeSettings(); _sfx->updateVolumeSettings(); }
+ virtual void updateVolumeSettings();
- void setSoundList(const AudioDataStruct * list) { _music->setSoundList(list); _sfx->setSoundList(list); }
- bool hasSoundFile(uint file) const { return _music->hasSoundFile(file) && _sfx->hasSoundFile(file); }
- void loadSoundFile(uint file) { _music->loadSoundFile(file); _sfx->loadSoundFile(file); }
- void loadSoundFile(Common::String file) { _music->loadSoundFile(file); _sfx->loadSoundFile(file); }
+ virtual void setSoundList(const AudioDataStruct *list);
+ virtual bool hasSoundFile(uint file) const;
+ virtual void loadSoundFile(uint file);
+ virtual void loadSoundFile(Common::String file);
- void loadSfxFile(Common::String file) { _sfx->loadSoundFile(file); }
+ virtual void loadSfxFile(Common::String file);
- void playTrack(uint8 track) { _music->playTrack(track); }
- void haltTrack() { _music->haltTrack(); }
- bool isPlaying() const { return _music->isPlaying() | _sfx->isPlaying(); }
+ virtual void playTrack(uint8 track);
+ virtual void haltTrack();
+ virtual bool isPlaying() const;
- void playSoundEffect(uint8 track) { _sfx->playSoundEffect(track); }
+ virtual void playSoundEffect(uint8 track, uint8 volume = 0xff);
- void stopAllSoundEffects() { _sfx->stopAllSoundEffects(); }
+ virtual void stopAllSoundEffects();
- void beginFadeOut() { _music->beginFadeOut(); }
- void pause(bool paused) { _music->pause(paused); _sfx->pause(paused); }
+ virtual void beginFadeOut();
+ virtual void pause(bool paused);
private:
Sound *_music, *_sfx;
};
diff --git a/engines/kyra/sound_adlib.cpp b/engines/kyra/sound_adlib.cpp
index 8976eba99c..668e662413 100644
--- a/engines/kyra/sound_adlib.cpp
+++ b/engines/kyra/sound_adlib.cpp
@@ -42,6 +42,7 @@
#include "common/system.h"
#include "common/mutex.h"
+#include "common/config-manager.h"
#include "audio/mixer.h"
#include "audio/fmopl.h"
@@ -56,10 +57,17 @@ namespace Kyra {
class AdLibDriver : public Audio::AudioStream {
public:
- AdLibDriver(Audio::Mixer *mixer, bool v2);
+ AdLibDriver(Audio::Mixer *mixer, int version);
~AdLibDriver();
- int callback(int opcode, ...);
+ void initDriver();
+ void setSoundData(uint8 *data);
+ void queueTrack(int track, int volume);
+ bool isChannelPlaying(int channel) const;
+ void stopAllChannels();
+ int getSoundTrigger() const { return _soundTrigger; }
+ void resetSoundTrigger() { _soundTrigger = 0; }
+
void callback();
// AudioStream API
@@ -92,40 +100,14 @@ public:
void setSyncJumpMask(uint16 mask) { _syncJumpMask = mask; }
-private:
- struct OpcodeEntry {
- typedef int (AdLibDriver::*DriverOpcode)(va_list &list);
- DriverOpcode function;
- const char *name;
- };
-
- void setupOpcodeList();
- const OpcodeEntry *_opcodeList;
- int _opcodesEntries;
-
- int snd_ret0x100(va_list &list);
- int snd_ret0x1983(va_list &list);
- int snd_initDriver(va_list &list);
- int snd_deinitDriver(va_list &list);
- int snd_setSoundData(va_list &list);
- int snd_unkOpcode1(va_list &list);
- int snd_startSong(va_list &list);
- int snd_isChannelPlaying(va_list &list);
- int snd_stopChannel(va_list &list);
- int snd_readByte(va_list &list);
- int snd_writeByte(va_list &list);
- int snd_getSoundTrigger(va_list &list);
- int snd_unkOpcode4(va_list &list);
- int snd_dummy(va_list &list);
- int snd_getNullvar4(va_list &list);
- int snd_setNullvar3(va_list &list);
- int snd_setFlag(va_list &list);
- int snd_clearFlag(va_list &list);
+ void setMusicVolume(uint8 volume);
+ void setSfxVolume(uint8 volume);
+private:
// These variables have not yet been named, but some of them are partly
// known nevertheless:
//
- // unk16 - Sound-related. Possibly some sort of pitch bend.
+ // pitchBend - Sound-related. Possibly some sort of pitch bend.
// unk18 - Sound-effect. Used for secondaryEffect1()
// unk19 - Sound-effect. Used for secondaryEffect1()
// unk20 - Sound-effect. Used for secondaryEffect1()
@@ -194,7 +176,8 @@ private:
uint16 offset;
uint8 tempoReset;
uint8 rawNote;
- int8 unk16;
+ int8 pitchBend;
+ uint8 volumeModifier;
};
void primaryEffect1(Channel &channel);
@@ -241,7 +224,7 @@ private:
}
uint8 *getInstrument(int instrumentId) {
- return _soundData + READ_LE_UINT16(_soundData + (_v2 ? 1000 : 500) + 2 * instrumentId);
+ return getProgram(_numPrograms + instrumentId);
}
void setupPrograms();
@@ -297,7 +280,7 @@ private:
int updateCallback38(uint8 *&dataptr, Channel &channel, uint8 value);
int updateCallback39(uint8 *&dataptr, Channel &channel, uint8 value);
int update_removePrimaryEffect2(uint8 *&dataptr, Channel &channel, uint8 value);
- int updateCallback41(uint8 *&dataptr, Channel &channel, uint8 value);
+ int update_pitchBend(uint8 *&dataptr, Channel &channel, uint8 value);
int update_resetToGlobalTempo(uint8 *&dataptr, Channel &channel, uint8 value);
int update_nop(uint8 *&dataptr, Channel &channel, uint8 value);
int update_setDurationRandomness(uint8 *&dataptr, Channel &channel, uint8 value);
@@ -335,7 +318,7 @@ private:
// _unkValue18 - Unknown. Rhythm section volume?
// _unkValue19 - Unknown. Rhythm section volume?
// _unkValue20 - Unknown. Rhythm section volume?
- // _unkTable[] - Probably frequences for the 12-tone scale.
+ // _freqTable[] - Probably frequences for the 12-tone scale.
// _unkTable2[] - Unknown. Currently only used by updateCallback46()
// _unkTable2_1[] - One of the tables in _unkTable2[]
// _unkTable2_2[] - One of the tables in _unkTable2[]
@@ -346,11 +329,8 @@ private:
int32 _samplesTillCallback;
int32 _samplesTillCallbackRemainder;
- int _lastProcessed;
- int8 _flagTrigger;
int _curChannel;
uint8 _soundTrigger;
- int _soundsPlaying;
uint16 _rnd;
@@ -375,12 +355,28 @@ private:
uint8 _unkValue19;
uint8 _unkValue20;
- int _flags;
FM_OPL *_adlib;
uint8 *_soundData;
- uint8 _soundIdTable[0x10];
+ struct QueueEntry {
+ QueueEntry() : data(0), id(0), volume(0) {}
+ QueueEntry(uint8 *ptr, uint8 track, uint8 vol) : data(ptr), id(track), volume(vol) {}
+ uint8 *data;
+ uint8 id;
+ uint8 volume;
+ };
+
+ QueueEntry _programQueue[16];
+ int _programStartTimeout;
+ int _programQueueStart, _programQueueEnd;
+ bool _retrySounds;
+
+ void adjustSfxData(uint8 *data, int volume);
+ uint8 *_sfxPointer;
+ int _sfxPriority;
+ int _sfxVelocity;
+
Channel _channels[10];
uint8 _vibratoAndAMDepthBits;
@@ -393,12 +389,12 @@ private:
const uint8 *_tablePtr2;
static const uint8 _regOffset[];
- static const uint16 _unkTable[];
+ static const uint16 _freqTable[];
static const uint8 *const _unkTable2[];
static const uint8 _unkTable2_1[];
static const uint8 _unkTable2_2[];
static const uint8 _unkTable2_3[];
- static const uint8 _unkTables[][32];
+ static const uint8 _pitchBendTables[][32];
uint16 _syncJumpMask;
@@ -406,18 +402,20 @@ private:
Audio::Mixer *_mixer;
Audio::SoundHandle _soundHandle;
- bool _v2;
+ uint8 _musicVolume, _sfxVolume;
+
+ int _numPrograms;
+ int _version;
};
-AdLibDriver::AdLibDriver(Audio::Mixer *mixer, bool v2) {
- setupOpcodeList();
+AdLibDriver::AdLibDriver(Audio::Mixer *mixer, int version) {
setupParserOpcodeTable();
- _v2 = v2;
+ _version = version;
+ _numPrograms = (_version == 1) ? 150 : ((_version == 4) ? 500 : 250);
_mixer = mixer;
- _flags = 0;
_adlib = makeAdLibOPL(getRate());
assert(_adlib);
@@ -426,12 +424,12 @@ AdLibDriver::AdLibDriver(Audio::Mixer *mixer, bool v2) {
_vibratoAndAMDepthBits = _curRegOffset = 0;
- _lastProcessed = _flagTrigger = _curChannel = _rhythmSectionBits = 0;
- _soundsPlaying = 0;
+ _curChannel = _rhythmSectionBits = 0;
_rnd = 0x1234;
_tempo = 0;
_soundTrigger = 0;
+ _programStartTimeout = 0;
_callbackTimer = 0xFF;
_unkValue1 = _unkValue2 = _unkValue4 = _unkValue5 = 0;
@@ -441,14 +439,7 @@ AdLibDriver::AdLibDriver(Audio::Mixer *mixer, bool v2) {
_tablePtr1 = _tablePtr2 = 0;
- // HACK: We use MusicSoundType here for now so we can adjust the volume in the launcher dialog.
- // This affects SFX too, but if we want to support different volumes for SFX and music we would
- // have to change our player implementation, currently we setup the volume for an AdLib channel
- // in AdLibDriver::adjustVolume, so if that would be called, we would have to know if the channel
- // is used by SFX or music, and then adjust the volume accordingly. Since Kyrandia 2 supports
- // different volumes for SFX and music, looking at the disasm and checking how the original does it
- // would be a good idea.
- _mixer->playStream(Audio::Mixer::kMusicSoundType, &_soundHandle, this, -1, Audio::Mixer::kMaxChannelVolume, 0, DisposeAfterUse::NO, true);
+ _mixer->playStream(Audio::Mixer::kPlainSoundType, &_soundHandle, this, -1, Audio::Mixer::kMaxChannelVolume, 0, DisposeAfterUse::NO, true);
_samplesPerCallback = getRate() / CALLBACKS_PER_SECOND;
_samplesPerCallbackRemainder = getRate() % CALLBACKS_PER_SECOND;
@@ -456,6 +447,14 @@ AdLibDriver::AdLibDriver(Audio::Mixer *mixer, bool v2) {
_samplesTillCallbackRemainder = 0;
_syncJumpMask = 0;
+
+ _musicVolume = 0;
+ _sfxVolume = 0;
+
+ _sfxPointer = 0;
+
+ _programQueueStart = _programQueueEnd = 0;
+ _retrySounds = false;
}
AdLibDriver::~AdLibDriver() {
@@ -464,100 +463,110 @@ AdLibDriver::~AdLibDriver() {
_adlib = 0;
}
-int AdLibDriver::callback(int opcode, ...) {
+void AdLibDriver::setMusicVolume(uint8 volume) {
Common::StackLock lock(_mutex);
- if (opcode >= _opcodesEntries || opcode < 0) {
- warning("AdLibDriver: calling unknown opcode '%d'", opcode);
- return 0;
+
+ _musicVolume = volume;
+
+ for (uint i = 0; i < 6; ++i) {
+ Channel &chan = _channels[i];
+ chan.volumeModifier = volume;
+
+ const uint8 regOffset = _regOffset[i];
+
+ // Level Key Scaling / Total Level
+ writeOPL(0x40 + regOffset, calculateOpLevel1(chan));
+ writeOPL(0x43 + regOffset, calculateOpLevel2(chan));
}
- debugC(9, kDebugLevelSound, "Calling opcode '%s' (%d)", _opcodeList[opcode].name, opcode);
+ // For now we use the music volume for both sfx and music in Kyra1 and EoB
+ if (_version < 4) {
+ _sfxVolume = volume;
- va_list args;
- va_start(args, opcode);
- int returnValue = (this->*(_opcodeList[opcode].function))(args);
- va_end(args);
- return returnValue;
-}
+ for (uint i = 6; i < 9; ++i) {
+ Channel &chan = _channels[i];
+ chan.volumeModifier = volume;
-// Opcodes
+ const uint8 regOffset = _regOffset[i];
-int AdLibDriver::snd_ret0x100(va_list &list) {
- return 0x100;
+ // Level Key Scaling / Total Level
+ writeOPL(0x40 + regOffset, calculateOpLevel1(chan));
+ writeOPL(0x43 + regOffset, calculateOpLevel2(chan));
+ }
+ }
}
-int AdLibDriver::snd_ret0x1983(va_list &list) {
- return 0x1983;
-}
+void AdLibDriver::setSfxVolume(uint8 volume) {
+ // We only support sfx volume in version 4 games.
+ if (_version < 4)
+ return;
-int AdLibDriver::snd_initDriver(va_list &list) {
- _lastProcessed = _soundsPlaying = 0;
- resetAdLibState();
- return 0;
+ Common::StackLock lock(_mutex);
+
+ _sfxVolume = volume;
+
+ for (uint i = 6; i < 9; ++i) {
+ Channel &chan = _channels[i];
+ chan.volumeModifier = volume;
+
+ const uint8 regOffset = _regOffset[i];
+
+ // Level Key Scaling / Total Level
+ writeOPL(0x40 + regOffset, calculateOpLevel1(chan));
+ writeOPL(0x43 + regOffset, calculateOpLevel2(chan));
+ }
}
-int AdLibDriver::snd_deinitDriver(va_list &list) {
+void AdLibDriver::initDriver() {
+ Common::StackLock lock(_mutex);
resetAdLibState();
- return 0;
}
-int AdLibDriver::snd_setSoundData(va_list &list) {
+void AdLibDriver::setSoundData(uint8 *data) {
+ Common::StackLock lock(_mutex);
+
+ // Drop all tracks that are still queued. These would point to the old
+ // sound data.
+ _programQueueStart = _programQueueEnd = 0;
+ memset(_programQueue, 0, sizeof(_programQueue));
+
if (_soundData) {
delete[] _soundData;
- _soundData = 0;
+ _soundData = _sfxPointer = 0;
}
- _soundData = va_arg(list, uint8 *);
- return 0;
-}
-int AdLibDriver::snd_unkOpcode1(va_list &list) {
- warning("unimplemented snd_unkOpcode1");
- return 0;
+ _soundData = data;
}
-int AdLibDriver::snd_startSong(va_list &list) {
- int songId = va_arg(list, int);
- _flags |= 8;
- _flagTrigger = 1;
+void AdLibDriver::queueTrack(int track, int volume) {
+ Common::StackLock lock(_mutex);
- uint8 *ptr = getProgram(songId);
- assert(ptr);
- uint8 chan = *ptr;
+ uint8 *trackData = getProgram(track);
+ if (!trackData)
+ return;
- if ((songId << 1) != 0) {
- if (chan == 9) {
- if (_flags & 2)
- return 0;
- } else {
- if (_flags & 1)
- return 0;
- }
+ // Don't drop tracks in EoB. The queue is always full there if a couple of monsters are around.
+ // If we drop the incoming tracks we get no sound effects, but tons of warnings instead.
+ if (_version >= 3 && _programQueueEnd == _programQueueStart && _programQueue[_programQueueEnd].data != 0) {
+ warning("AdLibDriver: Program queue full, dropping track %d", track);
+ return;
}
- _soundIdTable[_soundsPlaying++] = songId;
- _soundsPlaying &= 0x0F;
-
- return 0;
+ _programQueue[_programQueueEnd] = QueueEntry(trackData, track, volume);
+ _programQueueEnd = (_programQueueEnd + 1) & 15;
}
-int AdLibDriver::snd_isChannelPlaying(va_list &list) {
- int channel = va_arg(list, int);
+bool AdLibDriver::isChannelPlaying(int channel) const {
+ Common::StackLock lock(_mutex);
+
assert(channel >= 0 && channel <= 9);
- return (_channels[channel].dataptr != 0) ? 1 : 0;
+ return (_channels[channel].dataptr != 0);
}
-int AdLibDriver::snd_stopChannel(va_list &list) {
- int channel = va_arg(list, int);
-
- int maxChannel;
- if (channel < 0) {
- channel = 0;
- maxChannel = 9;
- } else {
- maxChannel = channel;
- }
+void AdLibDriver::stopAllChannels() {
+ Common::StackLock lock(_mutex);
- for (; channel <= maxChannel; ++channel) {
+ for (int channel = 0; channel <= 9; ++channel) {
_curChannel = channel;
Channel &chan = _channels[_curChannel];
@@ -567,71 +576,17 @@ int AdLibDriver::snd_stopChannel(va_list &list) {
if (channel != 9)
noteOff(chan);
}
-
- return 0;
-}
-
-int AdLibDriver::snd_readByte(va_list &list) {
- int a = va_arg(list, int);
- int b = va_arg(list, int);
- uint8 *ptr = getProgram(a) + b;
- assert(ptr);
- return *ptr;
-}
-
-int AdLibDriver::snd_writeByte(va_list &list) {
- int a = va_arg(list, int);
- int b = va_arg(list, int);
- uint8 value = va_arg(list, int);
- uint8 *ptr = getProgram(a) + b;
- assert(ptr);
- SWAP(*ptr, value);
- return value;
-}
-
-int AdLibDriver::snd_getSoundTrigger(va_list &list) {
- return _soundTrigger;
-}
-
-int AdLibDriver::snd_unkOpcode4(va_list &list) {
- warning("unimplemented snd_unkOpcode4");
- return 0;
-}
-
-int AdLibDriver::snd_dummy(va_list &list) {
- return 0;
-}
-
-int AdLibDriver::snd_getNullvar4(va_list &list) {
- warning("unimplemented snd_getNullvar4");
- return 0;
-}
-
-int AdLibDriver::snd_setNullvar3(va_list &list) {
- warning("unimplemented snd_setNullvar3");
- return 0;
-}
-
-int AdLibDriver::snd_setFlag(va_list &list) {
- int oldFlags = _flags;
- _flags |= va_arg(list, int);
- return oldFlags;
-}
-
-int AdLibDriver::snd_clearFlag(va_list &list) {
- int oldFlags = _flags;
- _flags &= ~(va_arg(list, int));
- return oldFlags;
+ _retrySounds = false;
}
// timer callback
void AdLibDriver::callback() {
Common::StackLock lock(_mutex);
- --_flagTrigger;
- if (_flagTrigger < 0)
- _flags &= ~8;
- setupPrograms();
+ if (_programStartTimeout)
+ --_programStartTimeout;
+ else
+ setupPrograms();
executePrograms();
uint8 temp = _callbackTimer;
@@ -645,33 +600,99 @@ void AdLibDriver::callback() {
}
void AdLibDriver::setupPrograms() {
- while (_lastProcessed != _soundsPlaying) {
- uint8 *ptr = getProgram(_soundIdTable[_lastProcessed]);
- uint8 chan = *ptr++;
- uint8 priority = *ptr++;
-
- // Only start this sound if its priority is higher than the one
- // already playing.
-
- Channel &channel = _channels[chan];
-
- if (priority >= channel.priority) {
- initChannel(channel);
- channel.priority = priority;
- channel.dataptr = ptr;
- channel.tempo = 0xFF;
- channel.position = 0xFF;
- channel.duration = 1;
- unkOutput2(chan);
- }
+ // If there is no program queued, we skip this.
+ if (_programQueueStart == _programQueueEnd)
+ return;
+
+ uint8 *ptr = _programQueue[_programQueueStart].data;
+
+ // The AdLib driver (in its old versions used for EOB) is not suitable for modern (fast) CPUs.
+ // The stop sound track (track 0 which has a priority of 50) will often still be busy when the
+ // next sound (with a lower priority) starts which will cause that sound to be skipped. We simply
+ // restart incoming sounds during stop sound execution.
+ // UPDATE: This stilly applies after introduction of the _programQueue.
+ QueueEntry retrySound;
+ if (_version < 3 && _programQueue[_programQueueStart].id == 0)
+ _retrySounds = true;
+ else if (_retrySounds)
+ retrySound = _programQueue[_programQueueStart];
+
+ // Adjust data in case we hit a sound effect.
+ adjustSfxData(ptr, _programQueue[_programQueueStart].volume);
+
+ // Clear the queue entry
+ _programQueue[_programQueueStart].data = 0;
+ _programQueueStart = (_programQueueStart + 1) & 15;
+
+ const int chan = *ptr++;
+ const int priority = *ptr++;
+
+ // Only start this sound if its priority is higher than the one
+ // already playing.
+
+ Channel &channel = _channels[chan];
+
+ if (priority >= channel.priority) {
+ initChannel(channel);
+ channel.priority = priority;
+ channel.dataptr = ptr;
+ channel.tempo = 0xFF;
+ channel.position = 0xFF;
+ channel.duration = 1;
+
+ if (chan <= 5)
+ channel.volumeModifier = _musicVolume;
+ else
+ channel.volumeModifier = _sfxVolume;
+
+ unkOutput2(chan);
+
+ // We need to wait two callback calls till we can start another track.
+ // This is (probably) required to assure that the sfx are started with
+ // the correct priority and velocity.
+ _programStartTimeout = 2;
- // What we have set up now is, probably, the controlling
- // channel for the sound. It is assumed that this program will
- // set up all the other channels it needs, clearing their locks
- // along the way.
+ retrySound = QueueEntry();
+ }
- ++_lastProcessed;
- _lastProcessed &= 0x0F;
+ if (retrySound.data) {
+ debugC(9, kDebugLevelSound, "AdLibDriver::setupPrograms(): WORKAROUND - Restarting skipped sound %d)", retrySound.id);
+ queueTrack(retrySound.id, retrySound.volume);
+ }
+}
+
+void AdLibDriver::adjustSfxData(uint8 *ptr, int volume) {
+ // Check whether we need to reset the data of an old sfx which has been
+ // started.
+ if (_sfxPointer) {
+ _sfxPointer[1] = _sfxPriority;
+ _sfxPointer[3] = _sfxVelocity;
+ _sfxPointer = 0;
+ }
+
+ // Only music tracks are started on channel 9, thus we need to make sure
+ // we do not have a music track here.
+ if (*ptr == 9)
+ return;
+
+ // Store the pointer so we can reset the data when a new program is started.
+ _sfxPointer = ptr;
+
+ // Store the old values.
+ _sfxPriority = ptr[1];
+ _sfxVelocity = ptr[3];
+
+ // Adjust the values.
+ if (volume != 0xff) {
+ if (_version >= 3) {
+ int newVal = ((((ptr[3]) + 63) * volume) >> 8) & 0xFF;
+ ptr[3] = -newVal + 63;
+ ptr[1] = ((ptr[1] * volume) >> 8) & 0xFF;
+ } else {
+ int newVal = ((_sfxVelocity << 2) ^ 0xff) * volume;
+ ptr[3] = (newVal >> 10) ^ 0x3f;
+ ptr[1] = newVal >> 11;
+ }
}
}
@@ -984,20 +1005,20 @@ void AdLibDriver::setupNote(uint8 rawNote, Channel &channel, bool flag) {
// octave bits, and that could possibly have been used in some sound.
// But as it is now, I can't see any way it would happen.
- uint16 freq = _unkTable[note] + channel.baseFreq;
+ uint16 freq = _freqTable[note] + channel.baseFreq;
// When called from callback 41, the behavior is slightly different:
- // We adjust the frequency, even when channel.unk16 is 0.
+ // We adjust the frequency, even when channel.pitchBend is 0.
- if (channel.unk16 || flag) {
+ if (channel.pitchBend || flag) {
const uint8 *table;
- if (channel.unk16 >= 0) {
- table = _unkTables[(channel.rawNote & 0x0F) + 2];
- freq += table[channel.unk16];
+ if (channel.pitchBend >= 0) {
+ table = _pitchBendTables[(channel.rawNote & 0x0F) + 2];
+ freq += table[channel.pitchBend];
} else {
- table = _unkTables[channel.rawNote & 0x0F];
- freq -= table[-channel.unk16];
+ table = _pitchBendTables[channel.rawNote & 0x0F];
+ freq -= table[-channel.pitchBend];
}
}
@@ -1273,9 +1294,21 @@ uint8 AdLibDriver::calculateOpLevel1(Channel &channel) {
if (channel.twoChan) {
value += channel.opExtraLevel1;
value += channel.opExtraLevel2;
- value += channel.opExtraLevel3;
+
+ uint16 level3 = (channel.opExtraLevel3 ^ 0x3F) * channel.volumeModifier;
+ if (level3) {
+ level3 += 0x3F;
+ level3 >>= 8;
+ }
+
+ value += level3 ^ 0x3F;
}
+ value = CLIP<int8>(value, 0, 0x3F);
+
+ if (!channel.volumeModifier)
+ value = 0x3F;
+
// Preserve the scaling level bits from opLevel1
return checkValue(value) | (channel.opLevel1 & 0xC0);
@@ -1286,7 +1319,19 @@ uint8 AdLibDriver::calculateOpLevel2(Channel &channel) {
value += channel.opExtraLevel1;
value += channel.opExtraLevel2;
- value += channel.opExtraLevel3;
+
+ uint16 level3 = (channel.opExtraLevel3 ^ 0x3F) * channel.volumeModifier;
+ if (level3) {
+ level3 += 0x3F;
+ level3 >>= 8;
+ }
+
+ value += level3 ^ 0x3F;
+
+ value = CLIP<int8>(value, 0, 0x3F);
+
+ if (!channel.volumeModifier)
+ value = 0x3F;
// Preserve the scaling level bits from opLevel2
@@ -1323,14 +1368,22 @@ int AdLibDriver::update_setupProgram(uint8 *&dataptr, Channel &channel, uint8 va
Channel &channel2 = _channels[chan];
if (priority >= channel2.priority) {
- _flagTrigger = 1;
- _flags |= 8;
+ // We keep new tracks from being started for two further iterations of
+ // the callback. This assures the correct velocity is used for this
+ // program.
+ _programStartTimeout = 2;
initChannel(channel2);
channel2.priority = priority;
channel2.dataptr = ptr;
channel2.tempo = 0xFF;
channel2.position = 0xFF;
channel2.duration = 1;
+
+ if (chan <= 5)
+ channel2.volumeModifier = _musicVolume;
+ else
+ channel2.volumeModifier = _sfxVolume;
+
unkOutput2(chan);
}
@@ -1345,7 +1398,10 @@ int AdLibDriver::update_setNoteSpacing(uint8 *&dataptr, Channel &channel, uint8
int AdLibDriver::update_jump(uint8 *&dataptr, Channel &channel, uint8 value) {
--dataptr;
int16 add = READ_LE_UINT16(dataptr); dataptr += 2;
- dataptr += add;
+ if (_version == 1)
+ dataptr = _soundData + add - 191;
+ else
+ dataptr += add;
if (_syncJumpMask & (1 << (&channel - _channels)))
channel.lock = true;
return 0;
@@ -1355,7 +1411,10 @@ int AdLibDriver::update_jumpToSubroutine(uint8 *&dataptr, Channel &channel, uint
--dataptr;
int16 add = READ_LE_UINT16(dataptr); dataptr += 2;
channel.dataptrStack[channel.dataptrStackPos++] = dataptr;
- dataptr += add;
+ if (_version < 3)
+ dataptr = _soundData + add - 191;
+ else
+ dataptr += add;
return 0;
}
@@ -1405,7 +1464,21 @@ int AdLibDriver::update_setupSecondaryEffect1(uint8 *&dataptr, Channel &channel,
channel.unk19 = value;
channel.unk20 = channel.unk21 = *dataptr++;
channel.unk22 = *dataptr++;
- channel.offset = READ_LE_UINT16(dataptr); dataptr += 2;
+ // WORKAROUND: The original code reads a true offset which later gets translated via xlat (in
+ // the current segment). This means that the outcome depends on the sound data offset.
+ // Unfortunately this offset is different in most implementations of the audio driver and
+ // probably also different from the offset assumed by the sequencer.
+ // It seems that the driver assumes an offset of 191 which is wrong for all the game driver
+ // implementations.
+ // This bug has probably not been noticed, since the effect is hardly used and the sounds are
+ // not necessarily worse. I noticed the difference between ScummVM and DOSBox for the EOB II
+ // teleporter sound. I also found the location of the table which is supposed to be used here
+ // (simple enough: it is located at the end of the track after the 0x88 ending opcode).
+ // Teleporters in EOB I and II now sound exactly the same which I am sure was the intended way,
+ // since the sound data is exactly the same.
+ // In DOSBox the teleporters will sound different in EOB I and II, due to different sound
+ // data offsets.
+ channel.offset = READ_LE_UINT16(dataptr) - 191; dataptr += 2;
channel.secondaryEffect = &AdLibDriver::secondaryEffect1;
return 0;
}
@@ -1647,8 +1720,8 @@ int AdLibDriver::update_removePrimaryEffect2(uint8 *&dataptr, Channel &channel,
return 0;
}
-int AdLibDriver::updateCallback41(uint8 *&dataptr, Channel &channel, uint8 value) {
- channel.unk16 = value;
+int AdLibDriver::update_pitchBend(uint8 *&dataptr, Channel &channel, uint8 value) {
+ channel.pitchBend = value;
setupNote(channel.rawNote, channel, true);
return 0;
}
@@ -1911,32 +1984,6 @@ int AdLibDriver::updateCallback56(uint8 *&dataptr, Channel &channel, uint8 value
#define COMMAND(x) { &AdLibDriver::x, #x }
-void AdLibDriver::setupOpcodeList() {
- static const OpcodeEntry opcodeList[] = {
- COMMAND(snd_ret0x100),
- COMMAND(snd_ret0x1983),
- COMMAND(snd_initDriver),
- COMMAND(snd_deinitDriver),
- COMMAND(snd_setSoundData),
- COMMAND(snd_unkOpcode1),
- COMMAND(snd_startSong),
- COMMAND(snd_isChannelPlaying),
- COMMAND(snd_stopChannel),
- COMMAND(snd_readByte),
- COMMAND(snd_writeByte),
- COMMAND(snd_getSoundTrigger),
- COMMAND(snd_unkOpcode4),
- COMMAND(snd_dummy),
- COMMAND(snd_getNullvar4),
- COMMAND(snd_setNullvar3),
- COMMAND(snd_setFlag),
- COMMAND(snd_clearFlag)
- };
-
- _opcodeList = opcodeList;
- _opcodesEntries = ARRAYSIZE(opcodeList);
-}
-
void AdLibDriver::setupParserOpcodeTable() {
static const ParserOpcode parserOpcodeTable[] = {
// 0
@@ -2025,7 +2072,7 @@ void AdLibDriver::setupParserOpcodeTable() {
// 56
COMMAND(update_stopChannel),
- COMMAND(updateCallback41),
+ COMMAND(update_pitchBend),
COMMAND(update_resetToGlobalTempo),
COMMAND(update_nop),
@@ -2066,11 +2113,10 @@ const uint8 AdLibDriver::_regOffset[] = {
0x12
};
-// Given the size of this table, and the range of its values, it's probably the
-// F-Numbers (10 bits) for the notes of the 12-tone scale. However, it does not
-// match the table in the AdLib documentation I've seen.
+//These are the F-Numbers (10 bits) for the notes of the 12-tone scale.
+// However, it does not match the table in the AdLib documentation I've seen.
-const uint16 AdLibDriver::_unkTable[] = {
+const uint16 AdLibDriver::_freqTable[] = {
0x0134, 0x0147, 0x015A, 0x016F, 0x0184, 0x019C, 0x01B4, 0x01CE, 0x01E9,
0x0207, 0x0225, 0x0246
};
@@ -2148,13 +2194,11 @@ const uint8 AdLibDriver::_unkTable2_3[] = {
};
// This table is used to modify the frequency of the notes, depending on the
-// note value and unk16. In theory, we could very well try to access memory
-// outside this table, but in reality that probably won't happen.
+// note value and the pitch bend value. In theory, we could very well try to
+// access memory outside this table, but in reality that probably won't happen.
//
-// This could be some sort of pitch bend, but I have yet to see it used for
-// anything so it's hard to say.
-const uint8 AdLibDriver::_unkTables[][32] = {
+const uint8 AdLibDriver::_pitchBendTables[][32] = {
// 0
{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x08,
0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10,
@@ -2243,21 +2287,36 @@ const int SoundAdLibPC::_kyra1NumSoundTriggers = ARRAYSIZE(SoundAdLibPC::_kyra1S
SoundAdLibPC::SoundAdLibPC(KyraEngine_v1 *vm, Audio::Mixer *mixer)
: Sound(vm, mixer), _driver(0), _trackEntries(), _soundDataPtr(0) {
memset(_trackEntries, 0, sizeof(_trackEntries));
- _v2 = (_vm->game() == GI_KYRA2) || (_vm->game() == GI_LOL && !_vm->gameFlags().isDemo);
- _driver = new AdLibDriver(mixer, _v2);
- assert(_driver);
+ _soundTriggers = 0;
+ _numSoundTriggers = 0;
_sfxPlayingSound = -1;
_soundFileLoaded.clear();
- if (_v2) {
- // TODO: Figure out if Kyra 2 uses sound triggers at all.
- _soundTriggers = 0;
- _numSoundTriggers = 0;
- } else {
+ switch (vm->game()) {
+ case GI_LOL:
+ _version = _vm->gameFlags().isDemo ? 3 : 4;
+ break;
+ case GI_KYRA2:
+ _version = 4;
+ break;
+ case GI_KYRA1:
+ _version = 3;
_soundTriggers = _kyra1SoundTriggers;
_numSoundTriggers = _kyra1NumSoundTriggers;
+ break;
+ case GI_EOB2:
+ _version = 2;
+ break;
+ case GI_EOB1:
+ _version = 1;
+ break;
+ default:
+ break;
}
+
+ _driver = new AdLibDriver(mixer, _version);
+ assert(_driver);
}
SoundAdLibPC::~SoundAdLibPC() {
@@ -2266,13 +2325,12 @@ SoundAdLibPC::~SoundAdLibPC() {
}
bool SoundAdLibPC::init() {
- _driver->callback(2);
- _driver->callback(16, int(4));
+ _driver->initDriver();
return true;
}
void SoundAdLibPC::process() {
- uint8 trigger = _driver->callback(11);
+ int trigger = _driver->getSoundTrigger();
if (trigger < _numSoundTriggers) {
int soundId = _soundTriggers[trigger];
@@ -2285,6 +2343,23 @@ void SoundAdLibPC::process() {
}
}
+void SoundAdLibPC::updateVolumeSettings() {
+ bool mute = false;
+ if (ConfMan.hasKey("mute"))
+ mute = ConfMan.getBool("mute");
+
+ int newMusicVolume = mute ? 0 : ConfMan.getInt("music_volume");
+ //newMusicVolume = (newMusicVolume * 145) / Audio::Mixer::kMaxMixerVolume + 110;
+ newMusicVolume = CLIP(newMusicVolume, 0, 255);
+
+ int newSfxVolume = mute ? 0 : ConfMan.getInt("sfx_volume");
+ //newSfxVolume = (newSfxVolume * 200) / Audio::Mixer::kMaxMixerVolume + 55;
+ newSfxVolume = CLIP(newSfxVolume, 0, 255);
+
+ _driver->setMusicVolume(newMusicVolume);
+ _driver->setSfxVolume(newSfxVolume);
+}
+
void SoundAdLibPC::playTrack(uint8 track) {
if (_musicEnabled) {
// WORKAROUND: There is a bug in the Kyra 1 "Pool of Sorrow"
@@ -2296,90 +2371,49 @@ void SoundAdLibPC::playTrack(uint8 track) {
_driver->setSyncJumpMask(0x000F);
else
_driver->setSyncJumpMask(0);
- play(track);
+ play(track, 0xff);
}
}
void SoundAdLibPC::haltTrack() {
- playSoundEffect(0);
- playSoundEffect(0);
+ play(0, 0);
+ play(0, 0);
//_vm->_system->delayMillis(3 * 60);
}
bool SoundAdLibPC::isPlaying() const {
- return _driver->callback(7, int(0)) != 0;
+ return _driver->isChannelPlaying(0);
}
-void SoundAdLibPC::playSoundEffect(uint8 track) {
+void SoundAdLibPC::playSoundEffect(uint8 track, uint8 volume) {
if (_sfxEnabled)
- play(track);
+ play(track, volume);
}
-void SoundAdLibPC::play(uint8 track) {
+void SoundAdLibPC::play(uint8 track, uint8 volume) {
uint16 soundId = 0;
- if (_v2)
+ if (_version == 4)
soundId = READ_LE_UINT16(&_trackEntries[track<<1]);
else
soundId = _trackEntries[track];
- if ((soundId == 0xFFFF && _v2) || (soundId == 0xFF && !_v2) || !_soundDataPtr)
+ if ((soundId == 0xFFFF && _version == 4) || (soundId == 0xFF && _version < 4) || !_soundDataPtr)
return;
- // HACK: Since we might call this when the engines is paused (on game load via GMM)
- // we must unpause the engine here, so this will work properly
-
- int pauseCount = 0;
- while (_vm->isPaused()) {
- ++pauseCount;
- _vm->pauseEngine(false);
- }
-
- while ((_driver->callback(16, 0) & 8)) {
- // We call the system delay and not the game delay to avoid concurrency issues.
- _vm->_system->delayMillis(10);
- }
-
- while (pauseCount--)
- _vm->pauseEngine(true);
-
- if (_sfxPlayingSound != -1) {
- // Restore the sounds's normal values.
- _driver->callback(10, _sfxPlayingSound, int(1), int(_sfxPriority));
- _driver->callback(10, _sfxPlayingSound, int(3), int(_sfxFourthByteOfSong));
- _sfxPlayingSound = -1;
- }
+ _driver->queueTrack(soundId, volume);
+}
- int chan = _driver->callback(9, soundId, int(0));
-
- if (chan != 9) {
- _sfxPlayingSound = soundId;
- _sfxPriority = _driver->callback(9, soundId, int(1));
- _sfxFourthByteOfSong = _driver->callback(9, soundId, int(3));
-
- // In the cases I've seen, the mysterious fourth byte has been
- // the parameter for the update_setExtraLevel3() callback.
- //
- // The extra level is part of the channels "total level", which
- // is a six-bit value where larger values means softer volume.
- //
- // So what seems to be happening here is that sounds which are
- // started by this function are given a slightly lower priority
- // and a slightly higher (i.e. softer) extra level 3 than they
- // would have if they were started from anywhere else. Strange.
-
- int newVal = ((((-_sfxFourthByteOfSong) + 63) * 0xFF) >> 8) & 0xFF;
- newVal = -newVal + 63;
- _driver->callback(10, soundId, int(3), newVal);
- newVal = ((_sfxPriority * 0xFF) >> 8) & 0xFF;
- _driver->callback(10, soundId, int(1), newVal);
- }
+void SoundAdLibPC::beginFadeOut() {
+ play(_version > 2 ? 1 : 15, 0xff);
+}
- _driver->callback(6, soundId);
+int SoundAdLibPC::checkTrigger() {
+ return _driver->getSoundTrigger();
}
-void SoundAdLibPC::beginFadeOut() {
- playSoundEffect(1);
+void SoundAdLibPC::resetTrigger() {
+ _driver->resetSoundTrigger();
}
void SoundAdLibPC::loadSoundFile(uint file) {
@@ -2391,7 +2425,7 @@ void SoundAdLibPC::loadSoundFile(Common::String file) {
}
void SoundAdLibPC::internalLoadFile(Common::String file) {
- file += ".ADL";
+ file += ((_version == 1) ? ".DAT" : ".ADL");
if (_soundFileLoaded == file)
return;
@@ -2409,13 +2443,13 @@ void SoundAdLibPC::internalLoadFile(Common::String file) {
playSoundEffect(0);
playSoundEffect(0);
- _driver->callback(8, int(-1));
+ _driver->stopAllChannels();
_soundDataPtr = 0;
int soundDataSize = fileSize;
uint8 *p = fileData;
- if (_v2) {
+ if (_version == 4) {
memcpy(_trackEntries, p, 500);
p += 500;
soundDataSize -= 500;
@@ -2434,7 +2468,7 @@ void SoundAdLibPC::internalLoadFile(Common::String file) {
fileData = p = 0;
fileSize = 0;
- _driver->callback(4, _soundDataPtr);
+ _driver->setSoundData(_soundDataPtr);
_soundFileLoaded = file;
}
diff --git a/engines/kyra/sound_adlib.h b/engines/kyra/sound_adlib.h
index c09fec997e..8492f3b99a 100644
--- a/engines/kyra/sound_adlib.h
+++ b/engines/kyra/sound_adlib.h
@@ -62,39 +62,40 @@ public:
SoundAdLibPC(KyraEngine_v1 *vm, Audio::Mixer *mixer);
~SoundAdLibPC();
- kType getMusicType() const { return kAdLib; }
+ virtual kType getMusicType() const { return kAdLib; }
- bool init();
- void process();
+ virtual bool init();
+ virtual void process();
- void loadSoundFile(uint file);
- void loadSoundFile(Common::String file);
- void loadSoundFile(const uint8 *soundData, int dataSize) {}
+ virtual void updateVolumeSettings();
- void playTrack(uint8 track);
- void haltTrack();
- bool isPlaying() const;
+ virtual void loadSoundFile(uint file);
+ virtual void loadSoundFile(Common::String file);
- void playSoundEffect(uint8 track);
+ virtual void playTrack(uint8 track);
+ virtual void haltTrack();
+ virtual bool isPlaying() const;
- void beginFadeOut();
+ virtual void playSoundEffect(uint8 track, uint8 volume = 0xff);
+
+ virtual void beginFadeOut();
+
+ virtual int checkTrigger();
+ virtual void resetTrigger();
private:
void internalLoadFile(Common::String file);
- void play(uint8 track);
+ void play(uint8 track, uint8 volume);
AdLibDriver *_driver;
- bool _v2;
+ int _version;
uint8 _trackEntries[500];
uint8 *_soundDataPtr;
int _sfxPlayingSound;
Common::String _soundFileLoaded;
- uint8 _sfxPriority;
- uint8 _sfxFourthByteOfSong;
-
int _numSoundTriggers;
const int *_soundTriggers;
diff --git a/engines/kyra/sound_amiga.cpp b/engines/kyra/sound_amiga.cpp
index dfb0aa8bf3..ec2748dd38 100644
--- a/engines/kyra/sound_amiga.cpp
+++ b/engines/kyra/sound_amiga.cpp
@@ -173,7 +173,7 @@ void SoundAmiga::beginFadeOut() {
_driver->setVolume(0x40);
}
-void SoundAmiga::playSoundEffect(uint8 track) {
+void SoundAmiga::playSoundEffect(uint8 track, uint8) {
debugC(5, kDebugLevelSound, "SoundAmiga::playSoundEffect(%d)", track);
const AmigaSfxTable *sfx = 0;
bool pan = false;
diff --git a/engines/kyra/sound_intern.h b/engines/kyra/sound_intern.h
index be3c09de96..427bef66e2 100644
--- a/engines/kyra/sound_intern.h
+++ b/engines/kyra/sound_intern.h
@@ -67,7 +67,7 @@ public:
void haltTrack();
bool isPlaying() const;
- void playSoundEffect(uint8 track);
+ void playSoundEffect(uint8 track, uint8 volume = 0xff);
void stopAllSoundEffects();
void beginFadeOut();
@@ -116,7 +116,7 @@ public:
void playTrack(uint8 track);
void haltTrack();
- void playSoundEffect(uint8);
+ void playSoundEffect(uint8 track, uint8 volume = 0xff);
void stopAllSoundEffects();
void beginFadeOut();
@@ -166,7 +166,7 @@ public:
void beginFadeOut();
int32 voicePlay(const char *file, Audio::SoundHandle *handle, uint8 volume, bool isSfx) { return -1; }
- void playSoundEffect(uint8);
+ void playSoundEffect(uint8 track, uint8 volume = 0xff);
void updateVolumeSettings();
@@ -195,7 +195,7 @@ public:
void beginFadeOut();
int32 voicePlay(const char *file, Audio::SoundHandle *handle, uint8 volume, bool isSfx);
- void playSoundEffect(uint8 track);
+ void playSoundEffect(uint8 track, uint8 volume = 0xff);
void updateVolumeSettings();
@@ -304,7 +304,7 @@ public:
void beginFadeOut();
int32 voicePlay(const char *file, Audio::SoundHandle *handle, uint8 volume, bool isSfx) { return -1; }
- void playSoundEffect(uint8);
+ void playSoundEffect(uint8 track, uint8 volume = 0xff);
protected:
Audio::MaxTrax *_driver;
diff --git a/engines/kyra/sound_lol.cpp b/engines/kyra/sound_lol.cpp
index efa844968d..cb9be43b07 100644
--- a/engines/kyra/sound_lol.cpp
+++ b/engines/kyra/sound_lol.cpp
@@ -98,12 +98,12 @@ bool LoLEngine::snd_playCharacterSpeech(int id, int8 speaker, int) {
_speechList = newSpeechList;
_activeVoiceFileTotalTime = 0;
- for (SpeechList::iterator i = _speechList.begin(); i != _speechList.end(); ++i) {
+ for (SpeechList::iterator i = _speechList.begin(); i != _speechList.end();) {
// Just in case any file loading failed: Remove the bad streams here.
if (!*i)
i = _speechList.erase(i);
else
- _activeVoiceFileTotalTime += (*i)->getLength().msecs();
+ _activeVoiceFileTotalTime += (*i++)->getLength().msecs();
}
_sound->playVoiceStream(*_speechList.begin(), &_speechHandle);
@@ -167,8 +167,8 @@ void LoLEngine::snd_playSoundEffect(int track, int volume) {
volume &= 0xff;
int16 volIndex = (int16)READ_LE_UINT16(&_ingameSoundIndex[track * 2 + 1]);
- volume = (volIndex > 0) ? (volIndex * volume) >> 8 : -volIndex;
- volume = CLIP(volume >> 4, 2, 13) * 7 + 164;
+ uint16 vocLevel = (volIndex > 0) ? (volIndex * volume) >> 8 : -volIndex;
+ vocLevel = CLIP(volume >> 4, 2, 13) * 7 + 164;
int16 vocIndex = (int16)READ_LE_UINT16(&_ingameSoundIndex[track * 2]);
@@ -180,7 +180,7 @@ void LoLEngine::snd_playSoundEffect(int track, int volume) {
if (hasVocFile) {
if (_sound->isVoicePresent(_ingameSoundList[vocIndex]))
- _sound->voicePlay(_ingameSoundList[vocIndex], 0, volume & 0xff, true);
+ _sound->voicePlay(_ingameSoundList[vocIndex], 0, vocLevel & 0xff, true);
} else if (_flags.platform == Common::kPlatformPC) {
if (_sound->getSfxType() == Sound::kMidiMT32)
track = (track < _ingameMT32SoundIndexSize) ? (_ingameMT32SoundIndex[track] - 1) : -1;
@@ -197,24 +197,9 @@ void LoLEngine::snd_playSoundEffect(int track, int volume) {
}
}
-void LoLEngine::snd_processEnvironmentalSoundEffect(int soundId, int block) {
- if (!_sound->sfxEnabled() || shouldQuit())
- return;
-
- if (_environmentSfx)
- snd_playSoundEffect(_environmentSfx, _environmentSfxVol);
-
- int dist = 0;
- if (block) {
- dist = getMonsterDistance(_currentBlock, block);
- if (dist > _envSfxDistThreshold) {
- _environmentSfx = 0;
- return;
- }
- }
-
- _environmentSfx = soundId;
- _environmentSfxVol = (15 - ((block || dist < 2) ? dist : 0)) << 4;
+bool LoLEngine::snd_processEnvironmentalSoundEffect(int soundId, int block) {
+ if (!KyraRpgEngine::snd_processEnvironmentalSoundEffect(soundId, block))
+ return false;
if (block != _currentBlock) {
static const int8 blockShiftTable[] = { -32, -31, 1, 33, 32, 31, -1, -33 };
@@ -231,9 +216,9 @@ void LoLEngine::snd_processEnvironmentalSoundEffect(int soundId, int block) {
}
if (!soundId || _sceneUpdateRequired)
- return;
+ return false;
- snd_processEnvironmentalSoundEffect(0, 0);
+ return snd_processEnvironmentalSoundEffect(0, 0);
}
void LoLEngine::snd_queueEnvironmentalSoundEffect(int soundId, int block) {
diff --git a/engines/kyra/sound_midi.cpp b/engines/kyra/sound_midi.cpp
index 1a5c2f94ac..0004395f6f 100644
--- a/engines/kyra/sound_midi.cpp
+++ b/engines/kyra/sound_midi.cpp
@@ -684,7 +684,7 @@ bool SoundMidiPC::isPlaying() const {
return _music->isPlaying();
}
-void SoundMidiPC::playSoundEffect(uint8 track) {
+void SoundMidiPC::playSoundEffect(uint8 track, uint8) {
if (!_sfxEnabled)
return;
diff --git a/engines/kyra/sound_towns.cpp b/engines/kyra/sound_towns.cpp
index c851842f22..2f996de1ac 100644
--- a/engines/kyra/sound_towns.cpp
+++ b/engines/kyra/sound_towns.cpp
@@ -125,7 +125,7 @@ void SoundTowns::loadSoundFile(uint file) {
_sfxFileData = _vm->resource()->fileData(fileListEntry(file), 0);
}
-void SoundTowns::playSoundEffect(uint8 track) {
+void SoundTowns::playSoundEffect(uint8 track, uint8) {
if (!_sfxEnabled || !_sfxFileData)
return;
@@ -414,14 +414,9 @@ void SoundPC98::playTrack(uint8 track) {
beginFadeOut();
- char musicfile[13];
- sprintf(musicfile, fileListEntry(0), track);
- if (fileListLen() == 1)
- sprintf(musicfile, fileListEntry(0), track);
- else
- strcpy(musicfile, fileListEntry(track));
+ Common::String musicFile = fileListLen() == 1 ? Common::String::format(fileListEntry(0), track) : fileListEntry(track);
delete[] _musicTrackData;
- _musicTrackData = _vm->resource()->fileData(musicfile, 0);
+ _musicTrackData = _vm->resource()->fileData(musicFile.c_str(), 0);
if (_musicEnabled)
_driver->loadMusicData(_musicTrackData);
@@ -446,7 +441,7 @@ void SoundPC98::beginFadeOut() {
haltTrack();
}
-void SoundPC98::playSoundEffect(uint8 track) {
+void SoundPC98::playSoundEffect(uint8 track, uint8) {
if (!_sfxTrackData)
return;
@@ -537,17 +532,12 @@ void SoundTownsPC98_v2::playTrack(uint8 track) {
beginFadeOut();
- char musicfile[13];
- if (fileListLen() == 1) {
- sprintf(musicfile, fileListEntry(0), track);
- } else {
- strcpy(musicfile, fileListEntry(track));
- if (!musicfile[0])
- return;
- }
+ Common::String musicFile = fileListLen() == 1 ? Common::String::format(fileListEntry(0), track) : fileListEntry(track);
+ if (musicFile.empty())
+ return;
delete[] _musicTrackData;
- _musicTrackData = _vm->resource()->fileData(musicfile, 0);
+ _musicTrackData = _vm->resource()->fileData(musicFile.c_str(), 0);
_driver->loadMusicData(_musicTrackData, true);
if (_musicEnabled == 2 && trackNum != -1) {
@@ -592,11 +582,9 @@ int32 SoundTownsPC98_v2::voicePlay(const char *file, Audio::SoundHandle *handle,
return 0;
}
- char filename[13];
- const char *pattern = _vm->game() == GI_LOL ? patternLOL : patternHOF;
- sprintf(filename, pattern, file);
+ Common::String fileName = Common::String::format( _vm->game() == GI_LOL ? patternLOL : patternHOF, file);
- uint8 *data = _vm->resource()->fileData(filename, 0);
+ uint8 *data = _vm->resource()->fileData(fileName.c_str(), 0);
uint8 *src = data;
if (!src)
return 0;
@@ -650,7 +638,7 @@ int32 SoundTownsPC98_v2::voicePlay(const char *file, Audio::SoundHandle *handle,
return 1;
}
-void SoundTownsPC98_v2::playSoundEffect(uint8 track) {
+void SoundTownsPC98_v2::playSoundEffect(uint8 track, uint8) {
if (!_useFmSfx || !_sfxTrackData)
return;
diff --git a/engines/kyra/sprites_eob.cpp b/engines/kyra/sprites_eob.cpp
new file mode 100644
index 0000000000..5c679f5cb4
--- /dev/null
+++ b/engines/kyra/sprites_eob.cpp
@@ -0,0 +1,1259 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifdef ENABLE_EOB
+
+#include "kyra/eobcommon.h"
+#include "kyra/script_eob.h"
+#include "kyra/resource.h"
+#include "kyra/timer.h"
+
+#include "common/system.h"
+
+
+namespace Kyra {
+
+void EoBCoreEngine::loadMonsterShapes(const char *filename, int monsterIndex, bool hasDecorations, int encodeTableIndex) {
+ _screen->loadShapeSetBitmap(filename, 3, 3);
+ const uint16 *enc = &_encodeMonsterShpTable[encodeTableIndex << 2];
+
+ for (int i = 0; i < 6; i++, enc += 4)
+ _monsterShapes[monsterIndex + i] = _screen->encodeShape(enc[0], enc[1], enc[2], enc[3], false, _cgaMappingDefault);
+
+ generateMonsterPalettes(filename, monsterIndex);
+
+ if (hasDecorations)
+ loadMonsterDecoration(filename, monsterIndex);
+
+ _screen->_curPage = 0;
+}
+
+void EoBCoreEngine::releaseMonsterShapes(int first, int num) {
+ for (int i = first; i < first + num; i++) {
+ delete[] _monsterShapes[i];
+ _monsterShapes[i] = 0;
+ delete[] _monsterDecorations[i].shp;
+ _monsterDecorations[i].shp = 0;
+ }
+}
+
+const uint8 *EoBCoreEngine::loadMonsterProperties(const uint8 *data) {
+ uint8 cmd = *data++;
+ while (cmd != 0xff) {
+ EoBMonsterProperty *d = &_monsterProps[cmd];
+ d->armorClass = (int8)*data++;
+ d->hitChance = (int8)*data++;
+ d->level = (int8)*data++;
+ d->hpDcTimes = *data++;
+ d->hpDcPips = *data++;
+ d->hpDcBase = *data++;
+ d->attacksPerRound = *data++;
+ d->dmgDc[0].times = *data++;
+ d->dmgDc[0].pips = *data++;
+ d->dmgDc[0].base = (int8)*data++;
+ d->dmgDc[1].times = *data++;
+ d->dmgDc[1].pips = *data++;
+ d->dmgDc[1].base = (int8)*data++;
+ d->dmgDc[2].times = *data++;
+ d->dmgDc[2].pips = *data++;
+ d->dmgDc[2].base = (int8)*data++;
+ d->immunityFlags = READ_LE_UINT16(data);
+ data += 2;
+ d->capsFlags = READ_LE_UINT16(data);
+ data += 2;
+ d->typeFlags = READ_LE_UINT16(data);
+ data += 2;
+ d->experience = READ_LE_UINT16(data);
+ data += 2;
+
+ d->u30 = *data++;
+ d->sound1 = (int8)*data++;
+ d->sound2 = (int8)*data++;
+ d->numRemoteAttacks = *data++;
+
+ if (*data++ != 0xff) {
+ d->remoteWeaponChangeMode = *data++;
+ d->numRemoteWeapons = *data++;
+
+ for (int i = 0; i < d->numRemoteWeapons; i++) {
+ d->remoteWeapons[i] = (int8)*data;
+ data += 2;
+ }
+ }
+
+ d->tuResist = (int8)*data++;
+ d->dmgModifierEvade = *data++;
+
+ for (int i = 0; i < 3; i++)
+ d->decorations[i] = *data++;
+
+ cmd = *data++;
+ }
+
+ return data;
+}
+
+const uint8 *EoBCoreEngine::loadActiveMonsterData(const uint8 *data, int level) {
+ for (uint8 p = *data++; p != 0xff; p = *data++) {
+ uint8 v = *data++;
+ _timer->setCountdown(0x20 + (p << 1), v);
+ _timer->setCountdown(0x21 + (p << 1), v);
+ }
+
+ uint32 ct = _system->getMillis();
+ for (int i = 0x20; i < 0x24; i++) {
+ int32 del = _timer->getDelay(i);
+ _timer->setNextRun(i, (i & 1) ? ct + (del >> 1) * _tickLength : ct + del * _tickLength);
+ }
+ _timer->resetNextRun();
+
+ if (_hasTempDataFlags & (1 << (level - 1)))
+ return data + 420;
+
+ memset(_monsters, 0, 30 * sizeof(EoBMonsterInPlay));
+
+ for (int i = 0; i < 30; i++, data += 14) {
+ if (*data == 0xff)
+ continue;
+
+ initMonster(data[0], data[1], READ_LE_UINT16(&data[2]), data[4], (int8)data[5], data[6], data[7], data[8], data[9], READ_LE_UINT16(&data[10]), READ_LE_UINT16(&data[12]));
+ _monsters[data[0]].flags |= 0x40;
+ }
+
+ return data;
+}
+
+void EoBCoreEngine::initMonster(int index, int unit, uint16 block, int pos, int dir, int type, int shpIndex, int mode, int i, int randItem, int fixedItem) {
+ EoBMonsterInPlay *m = &_monsters[index];
+ EoBMonsterProperty *p = &_monsterProps[type];
+ memset(m, 0, sizeof(EoBMonsterInPlay));
+
+ if (!block)
+ return;
+
+ unit <<= 1;
+ if (index & 1)
+ unit++;
+
+ m->stepsTillRemoteAttack = _flags.gameID == GI_EOB2 ? rollDice(1, 3, 0) : 5;
+ m->type = type;
+ m->numRemoteAttacks = p->numRemoteAttacks;
+ m->curRemoteWeapon = 0;
+ m->unit = unit;
+ m->pos = pos;
+ m->shpIndex = shpIndex;
+ m->mode = mode;
+ m->spellStatusLeft = i;
+ m->dir = dir;
+ m->palette = _flags.gameID == GI_EOB2 ? (index % 3) : 0;
+ m->hitPointsCur = m->hitPointsMax = _flags.gameID == GI_EOB2 ? rollDice(p->hpDcTimes, p->hpDcPips, p->hpDcBase) : (p->level == -1 ? rollDice(1, 4, 0) : rollDice(p->level, 8, 0));
+ m->randItem = randItem;
+ m->fixedItem = fixedItem;
+ m->sub = _currentSub;
+
+ placeMonster(m, block, dir);
+}
+
+void EoBCoreEngine::placeMonster(EoBMonsterInPlay *m, uint16 block, int dir) {
+ if (block != 0xffff) {
+ checkSceneUpdateNeed(m->block);
+ if (_levelBlockProperties[m->block].flags & 7) {
+ _levelBlockProperties[m->block].flags--;
+ if (_flags.gameID == GI_EOB2)
+ runLevelScript(m->block, 0x400);
+ }
+ m->block = block;
+ _levelBlockProperties[block].flags++;
+ if (_flags.gameID == GI_EOB2)
+ runLevelScript(m->block, 0x200);
+ }
+
+ if (dir != -1) {
+ m->dir = dir;
+ block = m->block;
+ }
+
+ checkSceneUpdateNeed(block);
+}
+
+void EoBCoreEngine::killMonster(EoBMonsterInPlay *m, bool giveExperience) {
+ m->hitPointsCur = -1;
+ int pos = (m->pos == 4) ? rollDice(1, 4, -1) : m->pos;
+
+ if (m->randItem) {
+ if (rollDice(1, 10, 0) == 1)
+ setItemPosition((Item *)&_levelBlockProperties[m->block & 0x3ff].drawObjects, m->block, duplicateItem(m->randItem), pos);
+ }
+
+ if (m->fixedItem)
+ setItemPosition((Item *)&_levelBlockProperties[m->block & 0x3ff].drawObjects, m->block, duplicateItem(m->fixedItem), pos);
+
+ if (giveExperience)
+ increasePartyExperience(_monsterProps[m->type].experience);
+
+ if (killMonsterExtra(m)) {
+ placeMonster(m, 0, -1);
+
+ if ((_flags.gameID == GI_EOB1) && (m->type == 21)) {
+ _playFinale = true;
+ _runFlag = false;
+ }
+
+ if (m->mode == 8)
+ updateAttackingMonsterFlags();
+ }
+}
+
+bool EoBCoreEngine::killMonsterExtra(EoBMonsterInPlay *) {
+ return true;
+}
+
+int EoBCoreEngine::countSpecificMonsters(int type) {
+ int res = 0;
+ for (int i = 0; i < 30; i++) {
+ if (_monsters[i].type != type || _monsters[i].sub != _currentSub || _monsters[i].hitPointsCur < 0)
+ continue;
+ res++;
+ }
+ return res;
+}
+
+void EoBCoreEngine::updateAttackingMonsterFlags() {
+ EoBMonsterInPlay *m2 = 0;
+ for (EoBMonsterInPlay *m = _monsters; m < &_monsters[30]; m++) {
+ if (m->mode != 8)
+ continue;
+ m->mode = 0;
+ m->dest = _currentBlock;
+ m2 = m;
+ }
+
+ if (m2->type == 7)
+ setScriptFlags(4);
+
+ if (m2->type == 12)
+ setScriptFlags(0x800);
+}
+
+const int8 *EoBCoreEngine::getMonstersOnBlockPositions(uint16 block) {
+ memset(_monsterBlockPosArray, -1, sizeof(_monsterBlockPosArray));
+ for (int8 i = 0; i < 30; i++) {
+ if (_monsters[i].block != block)
+ continue;
+ assert(_monsters[i].pos < sizeof(_monsterBlockPosArray));
+ _monsterBlockPosArray[_monsters[i].pos] = i;
+ }
+ return _monsterBlockPosArray;
+}
+
+int EoBCoreEngine::getClosestMonster(int charIndex, int block) {
+ const int8 *pos = getMonstersOnBlockPositions(block);
+ if (pos[4] != -1)
+ return pos[4];
+
+ const uint8 *p = &_monsterProximityTable[(_currentDirection << 3) + ((charIndex & 1) << 2)];
+ for (int i = 0; i < 4; i++) {
+ if (pos[p[i]] != -1)
+ return pos[p[i]];
+ }
+ return -1;
+}
+
+bool EoBCoreEngine::blockHasMonsters(uint16 block) {
+ return _levelBlockProperties[block].flags & 7 ? true : false;
+}
+
+bool EoBCoreEngine::isMonsterOnPos(EoBMonsterInPlay *m, uint16 block, int pos, int checkPos4) {
+ return (m->block == block && (m->pos == pos || (m->pos == 4 && checkPos4))) ? true : false;
+}
+
+const int16 *EoBCoreEngine::findBlockMonsters(uint16 block, int pos, int dir, int blockDamage, int singleTargetCheckAdjacent) {
+ static const uint8 cpos4[] = { 0, 0, 1, 1, 1, 0, 1, 0, 1, 1, 0, 0, 0, 1, 0, 1 };
+ int include4 = (pos < 4) ? cpos4[(dir << 2) + pos] : 1;
+ int16 *dst = _foundMonstersArray;
+
+ if (blockDamage) {
+ for (int i = 0; i < 30; i++) {
+ if (_monsters[i].block == block && (_monsters[i].pos != 4 || include4))
+ *dst++ = i;
+ }
+
+ } else if (singleTargetCheckAdjacent) {
+ int16 r = -1;
+ int f = 5;
+
+ for (int i = 0; i < 30; i++) {
+ const uint8 *tbl = &_findBlockMonstersTable[(dir << 4) + (pos << 2)];
+
+ if (_monsters[i].block != block)
+ continue;
+
+ if (_monsters[i].pos == pos) {
+ r = i;
+ break;
+ }
+
+ for (int ii = 0; ii < 4; ii++) {
+ if (_monsters[i].pos == tbl[ii] && ii < f) {
+ f = ii;
+ r = i;
+ }
+ }
+ }
+
+ *dst++ = r;
+
+ } else {
+ for (int i = 0; i < 30; i++) {
+ if (isMonsterOnPos(&_monsters[i], block, pos, include4))
+ *dst++ = i;
+ }
+ }
+
+ *dst = -1;
+ return _foundMonstersArray;
+}
+
+void EoBCoreEngine::drawBlockObject(int flipped, int page, const uint8 *shape, int x, int y, int sd, uint8 *ovl) {
+ const ScreenDim *d = _screen->getScreenDim(sd);
+ if (_flags.gameID == GI_EOB1)
+ x &= ~1;
+ _screen->drawShape(page, shape, x - (d->sx << 3), y - d->sy, sd, flipped | (ovl ? 2 : 0), ovl);
+}
+
+void EoBCoreEngine::drawMonsterShape(const uint8 *shape, int x, int y, int flipped, int flags, int palIndex) {
+ uint8 *ovl = 0;
+
+ if (flags & 2)
+ ovl = _monsterFlashOverlay;
+ else if (_flags.gameID == GI_EOB2 && flags & 0x20)
+ ovl = _monsterStoneOverlay;
+ else if (palIndex != -1)
+ ovl = _monsterPalettes[palIndex];
+
+ drawBlockObject(flipped, 2, shape, x, y, 5, ovl);
+}
+
+void EoBCoreEngine::flashMonsterShape(EoBMonsterInPlay *m) {
+ disableSysTimer(2);
+ _flashShapeTimer = 0;
+ drawScene(1);
+ m->flags &= 0xfd;
+ _flashShapeTimer = _system->getMillis() + _tickLength;
+ enableSysTimer(2);
+
+ _sceneUpdateRequired = true;
+}
+
+void EoBCoreEngine::updateAllMonsterShapes() {
+ drawScene(1);
+ bool updateShp = false;
+
+ for (EoBMonsterInPlay *m = _monsters; m < &_monsters[30]; m++) {
+ if (m->flags & 2) {
+ m->flags &= ~2;
+ updateShp = true;
+ if (m->hitPointsCur <= 0)
+ killMonster(m, true);
+ }
+ }
+
+ if (updateShp) {
+ _sceneUpdateRequired = true;
+ _flashShapeTimer = _system->getMillis() + _tickLength;
+ } else {
+ _sceneUpdateRequired = false;
+ }
+ _preventMonsterFlash = false;
+}
+
+void EoBCoreEngine::drawBlockItems(int index) {
+ uint16 o = _visibleBlocks[index]->drawObjects;
+ uint8 w = _visibleBlocks[index]->walls[_sceneDrawVarDown];
+ uint8 flg = (index == 16) ? 0x80 : _wllWallFlags[w];
+
+ if (_wllVmpMap[w] && !(flg & 0x80))
+ return;
+
+ uint16 o2 = o = _items[o].next;
+ bool forceLoop = true;
+ static const int8 itemPosYNiche[] = { 0x25, 0x31, 0x38, 0x00 };
+ static const int8 itemPosFin[] = { 0, -2, 1, -1, 2, 0, 1, -1 };
+ int tile2 = 0;
+
+ while (o != o2 || forceLoop) {
+ EoBItem *itm = &_items[o];
+ if (itm->pos == 8 || itm->pos < 4) {
+ tile2 = -1;
+
+ uint8 ps = (itm->pos == 8) ? 4 : _dscItemPosIndex[(_currentDirection << 2) + (itm->pos & 3)];
+ uint16 wo = (index * 5 + ps) << 1;
+ int x = _dscShapeCoords[wo] + 88;
+ int y = 0;
+
+ if (itm->pos == 8) {
+ x = _dscItemShpX[index];
+ y = itemPosYNiche[_dscDimMap[index]];
+ ps = 0;
+ } else {
+ y = _dscShapeCoords[wo + 1] + 124;
+ }
+
+ int8 scaleSteps = (int8)_dscItemScaleIndex[(_dscDimMap[index] << 2) + ps];
+ if ((flg & 8) && ps < 2 && scaleSteps) {
+ tile2 = _dscItemTileIndex[index];
+ if (tile2 != -1)
+ setLevelShapesDim(tile2, _shpDmX1, _shpDmX2, 5);
+ y -= 4;
+ }
+
+ if (scaleSteps >= 0) {
+ const uint8 *shp = _screen->scaleShape(_dscItemShapeMap[itm->icon] < _numLargeItemShapes ? _largeItemShapes[_dscItemShapeMap[itm->icon]] : (_dscItemShapeMap[itm->icon] < 15 ? 0 : _smallItemShapes[_dscItemShapeMap[itm->icon] - 15]), scaleSteps);
+ x = x + (itemPosFin[o & 7] << 1) - ((shp[2] << 3) >> 1);
+ y -= shp[1];
+
+ if (itm->pos != 8)
+ y += itemPosFin[(o >> 1) & 7];
+
+ drawBlockObject(0, 2, shp, x, y, 5);
+ _screen->setShapeFadeMode(1, false);
+ }
+ }
+
+ o = itm->next;
+ forceLoop = false;
+ if (tile2 != -1)
+ setLevelShapesDim(index, _shpDmX1, _shpDmX2, 5);
+ }
+}
+
+void EoBCoreEngine::drawDoor(int index) {
+ int s = _visibleBlocks[index]->walls[_sceneDrawVarDown];
+
+ if (_flags.gameID == GI_EOB1 && s == 0x85)
+ s = 0;
+
+ if (s >= _dscDoorShpIndexSize)
+ return;
+
+ int type = _dscDoorShpIndex[s];
+ int d = _dscDimMap[index];
+ int w = _dscShapeCoords[(index * 5 + 4) << 1];
+
+ int x = 88 + w;
+ int y = 0;
+
+ int16 y1 = 0;
+ int16 y2 = 0;
+ setDoorShapeDim(index, y1, y2, 5);
+ drawDoorIntern(type, index, x, y, w, s, d, y1, y2);
+ drawLevelModifyScreenDim(5, _shpDmX1, 0, _shpDmX2, 15);
+}
+
+void EoBCoreEngine::drawMonsters(int index) {
+ static const uint8 distMap[] = { 2, 1, 0, 4 };
+ static const uint8 yAdd[] = { 20, 12, 4, 4, 2, 0, 0 };
+
+ int blockDistance = distMap[_dscDimMap[index]];
+
+ uint16 bl = _visibleBlockIndex[index];
+ if (!bl)
+ return;
+
+ int drawObjDirIndex = _currentDirection * 5;
+ int cDirOffs = _currentDirection << 2;
+
+ EoBMonsterInPlay *drawObj[5];
+ memset(drawObj, 0, 5 * sizeof(EoBMonsterInPlay *));
+
+ for (int i = 0; i < 30; i++) {
+ if (_monsters[i].block != bl)
+ continue;
+ drawObj[_drawObjPosIndex[drawObjDirIndex + _monsters[i].pos]] = &_monsters[i];
+ }
+
+ for (int i = 0; i < 5; i++) {
+ EoBMonsterInPlay *d = drawObj[i];
+ if (!d)
+ continue;
+
+ EoBMonsterProperty *p = &_monsterProps[d->type];
+
+ if (_flags.gameID == GI_EOB2 && (p->capsFlags & 0x100) && !(_partyEffectFlags & 0x220) && !(d->flags & 2))
+ continue;
+
+ int f = (d->animStep << 4) + cDirOffs + d->dir;
+ f = (p->capsFlags & 2) ? _monsterFrmOffsTable1[f] : _monsterFrmOffsTable2[f];
+
+ if (!blockDistance && d->curAttackFrame < 0)
+ f = d->curAttackFrame + 7;
+
+ int subFrame = ABS(f);
+ int shpIndex = d->shpIndex ? 18 : 0;
+ int palIndex = d->palette ? ((((shpIndex == 18) ? subFrame + 5 : subFrame - 1) << 1) + (d->palette - 1)) : -1;
+
+ const uint8 *shp = _screen->scaleShape(_monsterShapes[subFrame + shpIndex - 1], blockDistance);
+
+ int v30 = (subFrame == 1 || subFrame > 3) ? 1 : 0;
+ int v1e = (d->pos == 4) ? 4 : _dscItemPosIndex[cDirOffs + d->pos];
+ int posIndex = (index * 5 + v1e) << 1;
+
+ int x = _dscShapeCoords[posIndex] + 88;
+ int y = _dscShapeCoords[posIndex + 1] + 127;
+
+ if (p->u30 == 1) {
+ if (v30) {
+ if (_flags.gameID == GI_EOB2)
+ posIndex = ((posIndex >> 1) - v1e) << 1;
+ y = _dscShapeCoords[posIndex + 1] + 127 + yAdd[blockDistance + ((v1e == 4 || _flags.gameID == GI_EOB1) ? 0 : 3)];
+ } else {
+ if (_flags.gameID == GI_EOB2)
+ posIndex = ((posIndex >> 1) - v1e + 4) << 1;
+ x = _dscShapeCoords[posIndex] + 88;
+ }
+ }
+
+ int w = shp[2] << 3;
+ int h = shp[1];
+
+ x = x - (w >> 1) + (d->idleAnimState >> 4);
+ y = y - h + (d->idleAnimState & 0x0f);
+
+ drawMonsterShape(shp, x, y, f >= 0 ? 0 : 1, d->flags, palIndex);
+
+ if (_flags.gameID == GI_EOB1) {
+ _screen->setShapeFadeMode(1, false);
+ continue;
+ }
+
+ for (int ii = 0; ii < 3; ii++) {
+ if (!p->decorations[ii])
+ continue;
+
+ SpriteDecoration *dcr = &_monsterDecorations[(p->decorations[ii] - 1) * 6 + subFrame + shpIndex - 1];
+
+ if (!dcr)
+ continue;
+ if (!dcr->shp)
+ continue;
+
+ shp = _screen->scaleShape(dcr->shp, blockDistance);
+ int dx = dcr->x;
+ int dy = dcr->y;
+
+ for (int iii = 0; iii < blockDistance; iii++) {
+ dx = (dx << 1) / 3;
+ dy = (dy << 1) / 3;
+ }
+
+ drawMonsterShape(shp, x + ((f < 0) ? (w - dx - (shp[2] << 3)) : dx), y + dy, f >= 0 ? 0 : 1, d->flags, -1);
+ }
+ _screen->setShapeFadeMode(1, false);
+ }
+}
+
+void EoBCoreEngine::drawWallOfForce(int index) {
+ int d = _dscDimMap[index];
+ assert(d < 3);
+ int dH = _wallOfForceDsNumH[d];
+ int dW = _wallOfForceDsNumW[d];
+ int y = _wallOfForceDsY[d];
+ int shpId = _wallOfForceShpId[d] + _teleporterPulse;
+ int h = _wallOfForceShapes[shpId][1];
+ int w = _wallOfForceShapes[shpId][2] << 3;
+
+ for (int i = 0; i < dH; i++) {
+ int x = _wallOfForceDsX[index];
+ for (int ii = 0; ii < dW; ii++) {
+ drawBlockObject(0, 2, _wallOfForceShapes[shpId], x, y, 5);
+ x += w;
+ }
+ y += h;
+ shpId ^= 1;
+ }
+}
+
+void EoBCoreEngine::drawFlyingObjects(int index) {
+ LevelBlockProperty *bl = _visibleBlocks[index];
+ int blockIndex = _visibleBlockIndex[index];
+ int w = bl->walls[_sceneDrawVarDown];
+
+ if (_wllVmpMap[w] && !(_wllWallFlags[w] & 0x80))
+ return;
+
+ EoBFlyingObject *drawObj[5];
+ memset(drawObj, 0, 5 * sizeof(EoBFlyingObject *));
+
+ for (int i = 0; i < 10; i++) {
+ if (!_flyingObjects[i].enable || blockIndex != _flyingObjects[i].curBlock)
+ continue;
+ drawObj[_drawObjPosIndex[_currentDirection * 5 + (_flyingObjects[i].curPos & 3)]] = &_flyingObjects[i];
+ }
+
+ for (int i = 0; i < 5; i++) {
+ EoBFlyingObject *fo = drawObj[i];
+ if (!fo)
+ continue;
+
+ int p = _dscItemPosIndex[(_currentDirection << 2) + (fo->curPos & 3)];
+ int x = _dscShapeCoords[(index * 5 + p) << 1] + 88;
+ int y = 39;
+
+ int sclValue = _flightObjSclIndex[(index << 2) + p];
+ int flipped = 0;
+
+ if (sclValue < 0) {
+ _screen->setShapeFadeMode(1, false);
+ continue;
+ }
+
+ const uint8 *shp = 0;
+ bool rstFade = false;
+
+ if (fo->enable == 1) {
+ int shpIx = _dscItemShapeMap[_items[fo->item].icon];
+ int dirOffs = (fo->direction == _currentDirection) ? 0 : ((fo->direction == (_currentDirection ^ 2)) ? 1 : -1);
+
+ if (dirOffs == -1 || _flightObjShpMap[shpIx] == -1) {
+ shp = shpIx < _numLargeItemShapes ? _largeItemShapes[shpIx] : (shpIx < 15 ? 0 : _smallItemShapes[shpIx - 15]);
+ flipped = fo->direction == ((_currentDirection + 1) & 3) ? 1 : 0;
+ } else {
+ shp = (_flightObjShpMap[shpIx] + dirOffs) < _numThrownItemShapes ? _thrownItemShapes[_flightObjShpMap[shpIx] + dirOffs] : _spellShapes[_flightObjShpMap[shpIx - _numThrownItemShapes] + dirOffs];
+ flipped = _flightObjFlipIndex[(fo->direction << 2) + (fo->curPos & 3)];
+ }
+
+ } else {
+ rstFade = true;
+ shp = (fo->objectType < _numThrownItemShapes) ? _thrownItemShapes[fo->objectType] : _spellShapes[fo->objectType - _numThrownItemShapes];
+ flipped = _flightObjFlipIndex[(fo->direction << 2) + (fo->curPos & 3)];
+
+ if (fo->flags & 0x40) {
+ x = _dscShapeCoords[(index * 5 + 4) << 1] + 88;
+ y = 44;
+ }
+ }
+
+ shp = _screen->scaleShape(shp, sclValue);
+
+ if (rstFade) {
+ _screen->setShapeFadeMode(1, false);
+ rstFade = false;
+ }
+
+ x -= (shp[2] << 2);
+ y -= (y == 44 ? (shp[1] >> 1) : shp[1]);
+
+ drawBlockObject(flipped, 2, shp, x, y, 5);
+ _screen->setShapeFadeMode(1, false);
+ }
+}
+
+void EoBCoreEngine::drawTeleporter(int index) {
+ static const uint8 telprtX[] = { 0x28, 0x1C, 0x12 };
+ static const uint8 telprtY[] = { 0x0D, 0x15, 0x1A };
+
+ int t = 2 - _dscDimMap[index];
+ if (t < 0)
+ return;
+
+ int16 x1 = _dscItemShpX[index] - telprtX[t];
+ int16 y1 = telprtY[t];
+
+ for (int i = 0; i < 2; i++) {
+
+ int16 x2 = 0;
+ int16 y2 = 0;
+ int d = (t << 1) + i;
+ if (!d)
+ x2 = y2 = -4;
+
+ const uint8 *shp = _teleporterShapes[d ^ _teleporterPulse];
+
+ for (int ii = 0; ii < 13; ii++)
+ drawBlockObject(0, 2, shp, x1 + x2 + _teleporterShapeCoords[d * 26 + ii * 2], y1 + y2 + _teleporterShapeCoords[d * 26 + ii * 2 + 1], 5);
+ }
+}
+
+void EoBCoreEngine::updateMonsters(int unit) {
+ for (int i = 0; i < 30; i++) {
+ EoBMonsterInPlay *m = &_monsters[i];
+ if (m->unit == unit) {
+ if (m->hitPointsCur <= 0 || m->flags & 0x20)
+ continue;
+ if (m->directionChanged) {
+ m->directionChanged = 0;
+ continue;
+ }
+
+ updateMonsterDest(m);
+
+ if (m->mode > 0)
+ updateMonsterAttackMode(m);
+
+ switch (m->mode) {
+ case 0:
+ updateMoveMonster(m);
+ break;
+ case 1:
+ updateMonsterFollowPath(m, 2);
+ break;
+ case 2:
+ updateMonsterFollowPath(m, -1);
+ break;
+ case 3:
+ updateMonsterFollowPath(m, 1);
+ break;
+ case 5:
+ updateMonstersStraying(m, -1);
+ break;
+ case 6:
+ updateMonstersStraying(m, 1);
+ break;
+ case 7:
+ case 10:
+ updateMonstersSpellStatus(m);
+ break;
+ default:
+ break;
+ }
+
+ if (m->mode != 4 && m->mode != 7 && m->mode != 8)
+ m->animStep ^= 1;
+
+ if (_monsterProps[m->type].u30 == 1)
+ setBlockMonsterDirection(m->block, m->dir);
+ }
+ }
+ checkFlyingObjects();
+}
+
+void EoBCoreEngine::updateMonsterDest(EoBMonsterInPlay *m) {
+ if (m->mode >= 7 && m->mode <= 10)
+ return;
+ int dist = getBlockDistance(m->block, _currentBlock);
+ if (dist >= 4)
+ return;
+
+ int s = getNextMonsterDirection(m->block, _currentBlock) - (m->dir << 1) - 3;
+
+ if (s < 0)
+ s += 8;
+
+ if (s <= 2 && dist >= 2)
+ return;
+
+ m->mode = 0;
+ m->dest = _currentBlock;
+}
+
+void EoBCoreEngine::updateMonsterAttackMode(EoBMonsterInPlay *m) {
+ if (!(m->flags & 1) || m->mode == 10)
+ return;
+ if (m->mode == 8) {
+ turnFriendlyMonstersHostile();
+ return;
+ }
+ m->mode = 0;
+ m->dest = _currentBlock;
+}
+
+void EoBCoreEngine::updateAllMonsterDests() {
+ for (int i = 0; i < 30; i++)
+ updateMonsterDest(&_monsters[i]);
+}
+
+void EoBCoreEngine::turnFriendlyMonstersHostile() {
+ EoBMonsterInPlay *m = 0;
+ for (int i = 0; i < 30; i++) {
+ if (_monsters[i].mode == 8) {
+ _monsters[i].mode = 0;
+ _monsters[i].dest = _currentBlock;
+ m = &_monsters[i];
+ }
+ }
+
+ if (m) {
+ if (m->type == 7)
+ setScriptFlags(0x40000);
+ else if (m->type == 12)
+ setScriptFlags(0x8000000);
+ }
+}
+
+int EoBCoreEngine::getNextMonsterDirection(int curBlock, int destBlock) {
+ uint8 c = destBlock % 32;
+ uint8 d = destBlock / 32;
+ uint8 e = curBlock % 32;
+ uint8 f = curBlock / 32;
+
+ int r = 0;
+
+ int s1 = f - d;
+ int d1 = ABS(s1);
+ s1 <<= 1;
+ int s2 = c - e;
+ int d2 = ABS(s2);
+ s2 <<= 1;
+
+ if (s1 >= d2)
+ r |= 8;
+ if (-s1 >= d2)
+ r |= 4;
+ if (s2 >= d1)
+ r |= 2;
+ if (-s2 >= d1)
+ r |= 1;
+
+ return _monsterDirChangeTable[r];
+}
+
+int EoBCoreEngine::getNextMonsterPos(EoBMonsterInPlay *m, int block) {
+ if ((_flags.gameID == GI_EOB1 && _monsterProps[m->type].u30 != 0) || (_flags.gameID == GI_EOB2 && _monsterProps[m->type].u30 == 2))
+ return -1;
+ int d = findFreeMonsterPos(block, _monsterProps[m->type].u30);
+ if (d < 0)
+ return -1;
+
+ int dir = m->dir;
+ if (_flags.gameID == GI_EOB2) {
+ if (_monsterProps[m->type].u30 == 1) {
+ if (d == 9)
+ return -1;
+
+ int v = _monsterCloseAttUnkTable[d];
+ if (v != -1)
+ //////
+ m->dir = 0;
+ return v;
+ }
+ } else {
+ dir &= 1;
+ }
+
+ for (int i = 0; i < 4; i++) {
+ int v = m->dir ^ _monsterCloseAttPosTable2[(dir << 2) + i];
+ if (!(d & (1 << v)))
+ return v;
+ }
+
+ return -1;
+}
+
+int EoBCoreEngine::findFreeMonsterPos(int block, int size) {
+ int nm = _levelBlockProperties[block].flags & 7;
+ if (nm == 4)
+ return -2;
+
+ int res = 0;
+
+ for (int i = 0; i < 30; i++) {
+ EoBMonsterInPlay *m = &_monsters[i];
+ if (m->block != block)
+ continue;
+ if (_monsterProps[m->type].u30 != size)
+ return -1;
+
+ if (m->pos == 4 && !(_flags.gameID == GI_EOB2 && m->flags & 0x20))
+ m->pos = (_flags.gameID == GI_EOB2 && _monsterProps[m->type].u30 == 1) ? 0 : _monsterCloseAttPosTable1[m->dir];
+
+ res |= (1 << m->pos);
+ if (--nm == 0)
+ break;
+ }
+
+ return res;
+}
+
+void EoBCoreEngine::updateMoveMonster(EoBMonsterInPlay *m) {
+ EoBMonsterProperty *p = &_monsterProps[m->type];
+ int d = getNextMonsterDirection(m->block, _currentBlock);
+
+ if ((_flags.gameID == GI_EOB2) && (p->capsFlags & 0x800) && !(d & 1))
+ d >>= 1;
+ else
+ d = m->dir;
+
+ d = calcNewBlockPosition(m->block, d);
+
+ if (m->dest == d && _currentBlock != d) {
+ m->mode = rollDice(1, 2, -1) + 5;
+ return;
+ }
+
+ if (updateMonsterTryDistanceAttack(m))
+ return;
+
+ if (updateMonsterTryCloseAttack(m, d))
+ return;
+
+ m->curAttackFrame = 0;
+ walkMonster(m, m->dest);
+
+ if (p->capsFlags & 8)
+ updateMonsterTryCloseAttack(m, -1);
+}
+
+bool EoBCoreEngine::updateMonsterTryDistanceAttack(EoBMonsterInPlay *m) {
+ EoBMonsterProperty *p = &_monsterProps[m->type];
+ if (!m->numRemoteAttacks || ((_flags.gameID == GI_EOB1) && !(p->capsFlags & 0x40)))
+ return false;
+
+ if ((_flags.gameID == GI_EOB1 && m->stepsTillRemoteAttack < 5) || (_flags.gameID == GI_EOB2 && (rollDice(1, 3) > m->stepsTillRemoteAttack))) {
+ m->stepsTillRemoteAttack++;
+ return false;
+ }
+
+ if (getBlockDistance(m->block, _currentBlock) > 3 || getNextMonsterDirection(m->block, _currentBlock) != (m->dir << 1))
+ return false;
+
+ int d = m->dir;
+ int bl = calcNewBlockPosition(m->block, d);
+
+ while (bl != _currentBlock) {
+ if (!(_wllWallFlags[_levelBlockProperties[bl].walls[d ^ 2]] & 3) || (_levelBlockProperties[bl].flags & 7))
+ return false;
+ bl = calcNewBlockPosition(bl, d);
+ }
+
+ Item itm = 0;
+ if (_flags.gameID == GI_EOB1) {
+ switch (m->type - 4) {
+ case 0:
+ launchMagicObject(-1, 9, m->block, m->pos, m->dir);
+ snd_processEnvironmentalSoundEffect(31, m->block);
+ break;
+ case 10:
+ launchMagicObject(-1, _enemyMageSpellList[m->numRemoteAttacks], m->block, m->pos, m->dir);
+ snd_processEnvironmentalSoundEffect(_enemyMageSfx[m->numRemoteAttacks], m->block);
+ break;
+ case 11:
+ itm = duplicateItem(60);
+ if (itm) {
+ if (!launchObject(-1, itm, m->block, m->pos, m->dir, _items[itm].type))
+ _items[itm].block = -1;
+ }
+ break;
+ case 12:
+ launchMagicObject(-1, 0, m->block, m->pos, m->dir);
+ snd_processEnvironmentalSoundEffect(85, m->block);
+ break;
+ case 13:
+ snd_processEnvironmentalSoundEffect(83, m->block);
+ _txt->printMessage(_monsterSpecAttStrings[1]);
+ for (int i = 0; i < 6; i++)
+ statusAttack(i, 4, _monsterSpecAttStrings[2], 1, 5, 9, 1);
+ break;
+ case 17:
+ d = rollDice(1, 4, -1);
+ if (d >= 3) {
+ for (int i = 0; i < 6; i++) {
+ if (!testCharacter(i, 3))
+ continue;
+ _txt->printMessage(_monsterSpecAttStrings[0], -1, _characters[i].name);
+ inflictCharacterDamage(i, rollDice(2, 8, 1));
+ }
+ snd_processEnvironmentalSoundEffect(108, m->block);
+ } else {
+ launchMagicObject(-1, _beholderSpellList[d], m->block, m->pos, m->dir);
+ snd_processEnvironmentalSoundEffect(_beholderSfx[d], m->block);
+ }
+ break;
+ default:
+ break;
+ }
+
+ } else {
+ int cw = 0;
+ if (p->remoteWeaponChangeMode == 1) {
+ cw = m->curRemoteWeapon++;
+ if (m->curRemoteWeapon == p->numRemoteWeapons)
+ m->curRemoteWeapon = 0;
+ } else if (p->remoteWeaponChangeMode == 2) {
+ cw = rollDice(1, p->numRemoteWeapons, -1);
+ }
+
+ int s = p->remoteWeapons[cw];
+ if (s >= 0) {
+ if (s < 20) {
+ monsterSpellCast(m, s);
+ } else if (s == 20) {
+ snd_processEnvironmentalSoundEffect(103, m->block);
+ _txt->printMessage(_monsterSpecAttStrings[0]);
+ for (int i = 0; i < 6; i++)
+ statusAttack(i, 4, _monsterSpecAttStrings[1], 1, 5, 9, 1);
+ }
+ } else {
+ itm = duplicateItem(-s);
+ if (itm) {
+ if (!launchObject(-1, itm, m->block, m->pos, m->dir, _items[itm].type))
+ _items[itm].block = -1;
+ }
+ }
+ }
+
+ if (m->numRemoteAttacks != 255)
+ m->numRemoteAttacks--;
+ m->stepsTillRemoteAttack = 0;
+ return true;
+}
+
+bool EoBCoreEngine::updateMonsterTryCloseAttack(EoBMonsterInPlay *m, int block) {
+ if (block == -1)
+ block = calcNewBlockPosition(m->block, m->dir);
+
+ if (block != _currentBlock)
+ return false;
+
+ int r = (m->pos == 4 || (_flags.gameID == GI_EOB2 && _monsterProps[m->type].u30 == 1)) ? 1 : _monsterCloseAttChkTable1[(m->dir << 2) + m->pos];
+
+ if (r) {
+ m->flags ^= 4;
+ if (!(m->flags & 4))
+ return true;
+
+ bool facing = (m->block == _visibleBlockIndex[13]);
+
+ if (facing) {
+ disableSysTimer(2);
+ if (m->type == 4)
+ updateEnvironmentalSfx(_monsterProps[m->type].sound1);
+ m->curAttackFrame = -2;
+ _flashShapeTimer = 0;
+ drawScene(1);
+ m->curAttackFrame = -1;
+ if (m->type != 4)
+ updateEnvironmentalSfx(_monsterProps[m->type].sound1);
+ _flashShapeTimer = _system->getMillis() + 8 * _tickLength;
+ drawScene(1);
+ } else {
+ updateEnvironmentalSfx(_monsterProps[m->type].sound1);
+ }
+
+ monsterCloseAttack(m);
+
+ if (facing) {
+ m->curAttackFrame = 0;
+ m->animStep ^= 1;
+ _sceneUpdateRequired = 1;
+ enableSysTimer(2);
+ _flashShapeTimer = _system->getMillis() + 8 * _tickLength;
+ }
+ } else {
+ int b = m->block;
+ if ((_levelBlockProperties[b].flags & 7) == 1) {
+ m->pos = 4;
+ } else {
+ b = getNextMonsterPos(m, b);
+ if (b >= 0)
+ m->pos = b;
+ }
+ checkSceneUpdateNeed(m->block);
+ }
+
+ return true;
+}
+
+void EoBCoreEngine::walkMonster(EoBMonsterInPlay *m, int destBlock) {
+ if (++_monsterStepCounter > 10) {
+ _monsterStepCounter = 0;
+ _monsterStepMode ^= 1;
+ }
+
+ const int8 *tbl = _monsterStepMode ? _monsterStepTable3 : _monsterStepTable2;
+
+ int s = m->dir << 1;
+ int b = m->block;
+ int d = getNextMonsterDirection(b, destBlock);
+ if (d == -1)
+ return;
+
+ if (m->flags & 8) {
+ // Interestingly, the fear spell in EOB 1 does not expire.
+ // I don't know whether this is intended or not.
+ if (_flags.gameID == GI_EOB1) {
+ d ^= 4;
+ } else if (m->spellStatusLeft > 0) {
+ if (--m->spellStatusLeft == 0)
+ m->flags &= ~8;
+ else
+ d ^= 4;
+ }
+ }
+
+ int d2 = (d - s) & 7;
+
+ if (_flags.gameID == GI_EOB1) {
+ if ((b + _monsterStepTable0[d >> 1] == _currentBlock) && !(d & 1)) {
+ if (d2 >= 5)
+ s = m->dir - 1;
+ else if (d2 != 0)
+ s = m->dir + 1;
+ walkMonsterNextStep(m, -1, s & 3);
+ return;
+ }
+ } else if (_flags.gameID == GI_EOB2) {
+ if (b + _monsterStepTable0[d] == destBlock) {
+ if (d & 1) {
+ int e = _monsterStepTable1[((d - 1) << 1) + m->dir];
+ if (e && (!(_monsterProps[m->type].capsFlags & 0x200) || (rollDice(1, 4) < 4))) {
+ if (walkMonsterNextStep(m, b + e, -1))
+ return;
+ }
+ } else {
+ walkMonsterNextStep(m, -1, d >> 1);
+ return;
+ }
+ }
+ }
+
+ if (d2) {
+ if (d2 >= 5)
+ s -= (1 + ((d & 1) ^ 1));
+ else
+ s += (1 + ((d & 1) ^ 1));
+ s &= 7;
+ }
+
+ for (int i = 7; i > -1; i--) {
+ s = (s + tbl[i]) & 7;
+ uint16 b2 = (s & 1) ? 0 : calcNewBlockPosition(b, s >> 1);
+ if (!b2)
+ continue;
+ if (walkMonsterNextStep(m, b2, s >> 1))
+ return;
+ }
+}
+
+bool EoBCoreEngine::walkMonsterNextStep(EoBMonsterInPlay *m, int destBlock, int direction) {
+ EoBMonsterProperty *p = &_monsterProps[m->type];
+ int obl = m->block;
+
+ if (destBlock != m->block && destBlock != -1) {
+ if (m->flags & 8) {
+ if (getBlockDistance(destBlock, _currentBlock) < getBlockDistance(m->block, _currentBlock))
+ return false;
+ }
+
+ if (destBlock == _currentBlock)
+ return false;
+
+ if (direction == -1)
+ direction = m->dir;
+
+ LevelBlockProperty *l = &_levelBlockProperties[destBlock];
+ uint8 w = l->walls[direction ^ 2];
+
+ if (!(_wllWallFlags[w] & 4)) {
+ if (_flags.gameID == GI_EOB1 || !(p->capsFlags & 0x1000) || _wllShapeMap[w] != -1)
+ return false;
+
+ if (_wllWallFlags[w] & 0x20) {
+ if (p->capsFlags & 4 && m->type == 1)
+ l->walls[direction] = l->walls[direction ^ 2] = 72;
+ else
+ openDoor(destBlock);
+ }
+
+ if (direction != -1) {
+ m->dir = direction;
+ checkSceneUpdateNeed(m->block);
+ }
+ return true;
+ }
+
+ if ((l->flags & 7) && destBlock) {
+ int pos = getNextMonsterPos(m, destBlock);
+ if (pos == -1)
+ return false;
+ m->pos = pos;
+ }
+
+ placeMonster(m, destBlock, direction);
+ direction = -1;
+ }
+
+ if (direction != -1)
+ m->dir = direction;
+
+ checkSceneUpdateNeed(obl);
+ if (!_partyResting && p->sound2 > 0)
+ snd_processEnvironmentalSoundEffect(p->sound2, m->block);
+
+ return true;
+}
+
+void EoBCoreEngine::updateMonsterFollowPath(EoBMonsterInPlay *m, int turnSteps) {
+ if (!walkMonsterNextStep(m, calcNewBlockPosition(m->block, m->dir), -1)) {
+ m->dir = (m->dir + turnSteps) & 3;
+ walkMonsterNextStep(m, -1, m->dir);
+ }
+}
+
+void EoBCoreEngine::updateMonstersStraying(EoBMonsterInPlay *m, int a) {
+ if (m->f_9 >= 0) {
+ if (m->f_9 == 0)
+ updateMonsterFollowPath(m, -a);
+
+ int8 d = (m->dir + a) & 3;
+ uint16 bl = calcNewBlockPosition(m->block, d);
+ uint8 flg = _wllWallFlags[_levelBlockProperties[bl].walls[_dscBlockMap[d]]] & 4;
+
+ if (m->f_9 == 0) {
+ if (!flg)
+ m->f_9 = -1;
+ return;
+ }
+
+ if (flg) {
+ walkMonsterNextStep(m, -1, d);
+ m->f_9 = -1;
+ return;
+ }
+ }
+
+ if (walkMonsterNextStep(m, calcNewBlockPosition(m->block, m->dir), -1)) {
+ m->f_9 = 1;
+ } else {
+ walkMonsterNextStep(m, -1, (m->dir - a) & 3);
+ m->f_9 = 0;
+ }
+}
+
+void EoBCoreEngine::updateMonstersSpellStatus(EoBMonsterInPlay *m) {
+ if (m->spellStatusLeft) {
+ if (!--m->spellStatusLeft)
+ m->mode = 0;
+ }
+}
+
+void EoBCoreEngine::setBlockMonsterDirection(int block, int dir) {
+ for (int i = 0; i < 30; i++) {
+ if (_monsters[i].block != block || _monsters[i].dir == dir)
+ continue;
+ _monsters[i].dir = dir;
+ _monsters[i].directionChanged = 1;
+ }
+}
+
+} // End of namespace Kyra
+
+#endif // ENABLE_EOB
diff --git a/engines/kyra/sprites_lol.cpp b/engines/kyra/sprites_lol.cpp
index fbf4c7c5c2..5a05d81a22 100644
--- a/engines/kyra/sprites_lol.cpp
+++ b/engines/kyra/sprites_lol.cpp
@@ -59,7 +59,7 @@ void LoLEngine::loadMonsterShapes(const char *file, int monsterIndex, int animTy
for (int i = 0; i < 4; i++) {
for (int ii = 0; ii < 16; ii++) {
- uint8 **of = &_monsterShapesEx[monsterIndex * 192 + i * 48 + ii * 3];
+ uint8 **of = &_monsterDecorationShapes[monsterIndex * 192 + i * 48 + ii * 3];
int s = (i << 4) + ii + 17;
of[0] = _screen->makeShapeCopy(p, s);
of[1] = _screen->makeShapeCopy(p, s + 1);
@@ -97,7 +97,7 @@ void LoLEngine::loadMonsterShapes(const char *file, int monsterIndex, int animTy
uint8 *cl = (uint8 *)memchr(tmpPal1, tmpPal2[1 + ii], 64);
if (!cl)
continue;
- tmpPal3[ii] = (uint16) (cl - tmpPal1);
+ tmpPal3[ii] = (uint16)(cl - tmpPal1);
}
for (int ii = 0; ii < 8; ii++) {
@@ -140,9 +140,9 @@ void LoLEngine::releaseMonsterShapes(int monsterIndex) {
for (int i = 0; i < 192; i++) {
int pos = (monsterIndex * 192) + i;
- if (_monsterShapesEx[pos]) {
- delete[] _monsterShapesEx[pos];
- _monsterShapesEx[pos] = 0;
+ if (_monsterDecorationShapes[pos]) {
+ delete[] _monsterDecorationShapes[pos];
+ _monsterDecorationShapes[pos] = 0;
}
}
}
@@ -159,7 +159,7 @@ int LoLEngine::deleteMonstersFromBlock(int block) {
continue;
}
- MonsterInPlay *m = &_monsters[i & 0x7fff];
+ LoLMonster *m = &_monsters[i & 0x7fff];
cnt++;
setMonsterMode(m, 14);
@@ -173,7 +173,7 @@ int LoLEngine::deleteMonstersFromBlock(int block) {
return cnt;
}
-void LoLEngine::setMonsterMode(MonsterInPlay *monster, int mode) {
+void LoLEngine::setMonsterMode(LoLMonster *monster, int mode) {
if (monster->mode == 13 && mode != 14)
return;
@@ -210,7 +210,7 @@ void LoLEngine::setMonsterMode(MonsterInPlay *monster, int mode) {
}
}
-bool LoLEngine::updateMonsterAdjustBlocks(MonsterInPlay *monster) {
+bool LoLEngine::updateMonsterAdjustBlocks(LoLMonster *monster) {
static const uint8 dims[] = { 0, 13, 9, 3 };
if (monster->properties->flags & 8)
return true;
@@ -251,7 +251,7 @@ bool LoLEngine::updateMonsterAdjustBlocks(MonsterInPlay *monster) {
return (fx1 >= fx2) ? false : true;
}
-void LoLEngine::placeMonster(MonsterInPlay *monster, uint16 x, uint16 y) {
+void LoLEngine::placeMonster(LoLMonster *monster, uint16 x, uint16 y) {
bool cont = true;
int t = monster->block;
if (monster->block) {
@@ -273,7 +273,7 @@ void LoLEngine::placeMonster(MonsterInPlay *monster, uint16 x, uint16 y) {
if (monster->block == 0)
return;
- assignMonsterToBlock(&_levelBlockProperties[monster->block].assignedObjects, ((uint16)monster->id) | 0x8000);
+ assignObjectToBlock(&_levelBlockProperties[monster->block].assignedObjects, ((uint16)monster->id) | 0x8000);
_levelBlockProperties[monster->block].direction = 5;
checkSceneUpdateNeed(monster->block);
@@ -329,7 +329,7 @@ int LoLEngine::calcMonsterDirection(uint16 x1, uint16 y1, uint16 x2, uint16 y2)
return retVal[r];
}
-void LoLEngine::setMonsterDirection(MonsterInPlay *monster, int dir) {
+void LoLEngine::setMonsterDirection(LoLMonster *monster, int dir) {
monster->direction = dir;
if (!(dir & 1) || ((monster->direction - (monster->facing << 1)) >= 2))
@@ -338,7 +338,7 @@ void LoLEngine::setMonsterDirection(MonsterInPlay *monster, int dir) {
checkSceneUpdateNeed(monster->block);
}
-void LoLEngine::monsterDropItems(MonsterInPlay *monster) {
+void LoLEngine::monsterDropItems(LoLMonster *monster) {
uint16 a = monster->assignedItems;
while (a) {
uint16 b = a;
@@ -347,46 +347,6 @@ void LoLEngine::monsterDropItems(MonsterInPlay *monster) {
}
}
-void LoLEngine::removeAssignedObjectFromBlock(LevelBlockProperty *l, uint16 id) {
- uint16 *blockItemIndex = &l->assignedObjects;
- ItemInPlay *i = 0;
-
- while (*blockItemIndex) {
- if (*blockItemIndex == id) {
- i = findObject(id);
- *blockItemIndex = i->nextAssignedObject;
- i->nextAssignedObject = 0;
- return;
- }
-
- i = findObject(*blockItemIndex);
- blockItemIndex = &i->nextAssignedObject;
- }
-}
-
-void LoLEngine::removeDrawObjectFromBlock(LevelBlockProperty *l, uint16 id) {
- uint16 *blockItemIndex = &l->drawObjects;
- ItemInPlay *i = 0;
-
- while (*blockItemIndex) {
- if (*blockItemIndex == id) {
- i = findObject(id);
- *blockItemIndex = i->nextDrawObject;
- i->nextDrawObject = 0;
- return;
- }
-
- i = findObject(*blockItemIndex);
- blockItemIndex = &i->nextDrawObject;
- }
-}
-
-void LoLEngine::assignMonsterToBlock(uint16 *assignedBlockObjects, uint16 id) {
- ItemInPlay *t = findObject(id);
- t->nextAssignedObject = *assignedBlockObjects;
- *assignedBlockObjects = id;
-}
-
int LoLEngine::checkBlockBeforeObjectPlacement(uint16 x, uint16 y, uint16 objectWidth, uint16 testFlag, uint16 wallFlag) {
_objectLastDirection = 0;
uint16 x2 = 0;
@@ -503,7 +463,7 @@ int LoLEngine::checkBlockForWallsAndSufficientSpace(int block, int x, int y, int
uint16 b = _levelBlockProperties[block].assignedObjects;
while (b & 0x8000) {
- MonsterInPlay *monster = &_monsters[b & 0x7fff];
+ LoLMonster *monster = &_monsters[b & 0x7fff];
if (monster->mode < 13) {
int r = checkDrawObjectSpace(x, y, monster->x, monster->y);
@@ -554,7 +514,7 @@ int LoLEngine::checkBlockOccupiedByParty(int x, int y, int testFlag) {
void LoLEngine::drawBlockObjects(int blockArrayIndex) {
LevelBlockProperty *l = _visibleBlocks[blockArrayIndex];
uint16 s = l->assignedObjects;
- ItemInPlay *i = findObject(s);
+ LoLObject *obj = findObject(s);
if (l->direction != _currentDirection) {
l->drawObjects = 0;
@@ -562,8 +522,8 @@ void LoLEngine::drawBlockObjects(int blockArrayIndex) {
while (s) {
reassignDrawObjects(_currentDirection, s, l, true);
- i = findObject(s);
- s = i->nextAssignedObject;
+ obj = findObject(s);
+ s = obj->nextAssignedObject;
}
}
@@ -575,7 +535,7 @@ void LoLEngine::drawBlockObjects(int blockArrayIndex) {
drawMonster(s);
s = _monsters[s].nextDrawObject;
} else {
- i = &_itemsInPlay[s];
+ LoLItem *i = &_itemsInPlay[s];
int fx = _sceneItemOffs[s & 7] << 1;
int fy = _sceneItemOffs[(s >> 1) & 7] + 5;
@@ -634,7 +594,7 @@ void LoLEngine::drawBlockObjects(int blockArrayIndex) {
} else {
shp = (_itemProperties[i->itemPropertyIndex].flags & 0x40) ? _gameShapes[_itemProperties[i->itemPropertyIndex].shpIndex] :
- _itemShapes[_gameShapeMap[_itemProperties[i->itemPropertyIndex].shpIndex << 1]];
+ _itemShapes[_gameShapeMap[_itemProperties[i->itemPropertyIndex].shpIndex << 1]];
}
if (shp)
@@ -645,7 +605,7 @@ void LoLEngine::drawBlockObjects(int blockArrayIndex) {
}
void LoLEngine::drawMonster(uint16 id) {
- MonsterInPlay *m = &_monsters[id];
+ LoLMonster *m = &_monsters[id];
int16 flg = _monsterDirFlags[(_currentDirection << 2) + m->facing];
int curFrm = getMonsterCurFrame(m, flg & 0xffef);
uint8 *shp = 0;
@@ -665,12 +625,12 @@ void LoLEngine::drawMonster(uint16 id) {
uint8 *monsterPalette = d ? _monsterPalettes[(m->properties->shapeIndex << 4) + (curFrm & 0x0f)] + (shp[10] * (d - 1)) : 0;
uint8 *brightnessOverlay = drawItemOrMonster(shp, monsterPalette, m->x + _monsterShiftOffs[m->shiftStep << 1], m->y + _monsterShiftOffs[(m->shiftStep << 1) + 1], 0, 0, flg | 1, -1, flip);
- for (int i = 0; i < 4; i++) {
+ for (int i = 0; i < 4; i++) {
int v = m->equipmentShapes[i] - 1;
if (v == -1)
break;
- uint8 *shp2 = _monsterShapesEx[m->properties->shapeIndex * 192 + v * 48 + curFrm * 3];
+ uint8 *shp2 = _monsterDecorationShapes[m->properties->shapeIndex * 192 + v * 48 + curFrm * 3];
if (!shp2)
continue;
@@ -721,7 +681,7 @@ void LoLEngine::drawMonster(uint16 id) {
delete[] tbl;
}
-int LoLEngine::getMonsterCurFrame(MonsterInPlay *m, uint16 dirFlags) {
+int LoLEngine::getMonsterCurFrame(LoLMonster *m, uint16 dirFlags) {
int tmp = 0;
switch (_monsterAnimType[m->properties->shapeIndex]) {
case 0:
@@ -796,19 +756,19 @@ void LoLEngine::reassignDrawObjects(uint16 direction, uint16 itemIndex, LevelBlo
return;
}
- ItemInPlay *newObject = findObject(itemIndex);
- int r = calcItemMonsterPosition(newObject, direction);
+ LoLObject *newObject = findObject(itemIndex);
+ int r = calcObjectPosition(newObject, direction);
uint16 *b = &l->drawObjects;
- ItemInPlay *lastObject = 0;
+ LoLObject *lastObject = 0;
while (*b) {
lastObject = findObject(*b);
if (flag) {
- if (calcItemMonsterPosition(lastObject, direction) >= r)
+ if (calcObjectPosition(lastObject, direction) >= r)
break;
} else {
- if (calcItemMonsterPosition(lastObject, direction) > r)
+ if (calcObjectPosition(lastObject, direction) > r)
break;
}
@@ -838,7 +798,7 @@ void LoLEngine::redrawSceneItem() {
if (s & 0x8000) {
s = _monsters[s & 0x7fff].nextDrawObject;
} else {
- ItemInPlay *item = &_itemsInPlay[s];
+ LoLItem *item = &_itemsInPlay[s];
if (item->shpCurFrame_flg & 0x4000) {
if (checkDrawObjectSpace(item->x, item->y, _partyPosX, _partyPosY) < 320) {
@@ -848,7 +808,7 @@ void LoLEngine::redrawSceneItem() {
fy -= ((item->flyingHeight - 1) * 6);
uint8 *shp = (_itemProperties[item->itemPropertyIndex].flags & 0x40) ? _gameShapes[_itemProperties[item->itemPropertyIndex].shpIndex] :
- _itemShapes[_gameShapeMap[_itemProperties[item->itemPropertyIndex].shpIndex << 1]];
+ _itemShapes[_gameShapeMap[_itemProperties[item->itemPropertyIndex].shpIndex << 1]];
drawItemOrMonster(shp, 0, item->x, item->y, fx, fy, 0, t, 0);
_screen->updateScreen();
@@ -862,21 +822,6 @@ void LoLEngine::redrawSceneItem() {
}
}
-int LoLEngine::calcItemMonsterPosition(ItemInPlay *i, uint16 direction) {
- int x = i->x;
- int y = i->y;
-
- calcSpriteRelPosition(_partyPosX, _partyPosY, x, y, direction);
-
- if (y < 0)
- y = 0;
-
- int res = (i->flyingHeight << 12);
- res |= (4095 - y);
-
- return res;
-}
-
void LoLEngine::calcSpriteRelPosition(uint16 x1, uint16 y1, int &x2, int &y2, uint16 direction) {
int a = x2 - x1;
int b = y1 - y2;
@@ -901,7 +846,7 @@ void LoLEngine::drawDoor(uint8 *shape, uint8 *doorPalette, int index, int unk2,
if (!shape)
return;
- uint8 c = _dscDoor1[(_currentDirection << 5) + unk2];
+ uint8 c = _dscDoorY2[(_currentDirection << 5) + unk2];
int r = (c / 5) + 5 * _dscDimMap[index];
uint16 d = _dscShapeOvlIndex[r];
uint16 t = (index << 5) + c;
@@ -910,7 +855,7 @@ void LoLEngine::drawDoor(uint8 *shape, uint8 *doorPalette, int index, int unk2,
if (flags & 1) {
// TODO / UNUSED
- flags |=1;
+ flags |= 1;
}
int u = 0;
@@ -1080,7 +1025,7 @@ int LoLEngine::calcDrawingLayerParameters(int x1, int y1, int &x2, int &y2, uint
return l;
}
-void LoLEngine::updateMonster(MonsterInPlay *monster) {
+void LoLEngine::updateMonster(LoLMonster *monster) {
static const uint8 flags[] = { 1, 0, 1, 3, 3, 0, 0, 3, 4, 1, 0, 0, 4, 0, 0 };
if (monster->mode > 14)
return;
@@ -1182,7 +1127,7 @@ void LoLEngine::updateMonster(MonsterInPlay *monster) {
// first recovery phase after delivering an attack
if (++monster->fightCurTick > 2) {
setMonsterMode(monster, 5);
- monster->fightCurTick = (int8) ((((8 << 8) / monster->properties->fightingStats[4]) * _monsterModifiers[6 + _monsterDifficulty]) >> 8);
+ monster->fightCurTick = (int8)((((8 << 8) / monster->properties->fightingStats[4]) * _monsterModifiers[6 + _monsterDifficulty]) >> 8);
}
checkSceneUpdateNeed(monster->block);
break;
@@ -1228,7 +1173,7 @@ void LoLEngine::updateMonster(MonsterInPlay *monster) {
monster->flags &= 0xffef;
}
-void LoLEngine::moveMonster(MonsterInPlay *monster) {
+void LoLEngine::moveMonster(LoLMonster *monster) {
static const int8 turnPos[] = { 0, 2, 6, 6, 0, 2, 4, 4, 2, 2, 4, 6, 0, 0, 4, 6, 0 };
if (monster->x != monster->destX || monster->y != monster->destY) {
walkMonster(monster);
@@ -1238,7 +1183,7 @@ void LoLEngine::moveMonster(MonsterInPlay *monster) {
}
}
-void LoLEngine::walkMonster(MonsterInPlay *monster) {
+void LoLEngine::walkMonster(LoLMonster *monster) {
if (monster->properties->flags & 0x400)
return;
@@ -1253,7 +1198,7 @@ void LoLEngine::walkMonster(MonsterInPlay *monster) {
} else {
setMonsterDirection(monster, s);
if (monster->numDistAttacks) {
- if (getMonsterDistance(monster->block, _currentBlock) >= 2) {
+ if (getBlockDistance(monster->block, _currentBlock) >= 2) {
if (checkForPossibleDistanceAttack(monster->block, monster->direction, 3, _currentBlock) != 5) {
if (monster->distAttackTick)
return;
@@ -1269,7 +1214,7 @@ void LoLEngine::walkMonster(MonsterInPlay *monster) {
placeMonster(monster, fx, fy);
}
-bool LoLEngine::chasePartyWithDistanceAttacks(MonsterInPlay *monster) {
+bool LoLEngine::chasePartyWithDistanceAttacks(LoLMonster *monster) {
if (!monster->numDistAttacks)
return false;
@@ -1295,7 +1240,7 @@ bool LoLEngine::chasePartyWithDistanceAttacks(MonsterInPlay *monster) {
int flyingObject = monster->properties->distWeapons[s];
if (flyingObject & 0xc000) {
- if (getMonsterDistance(monster->block, _currentBlock) > 1) {
+ if (getBlockDistance(monster->block, _currentBlock) > 1) {
int type = flyingObject & 0x4000 ? 0 : 1;
flyingObject = makeItem(flyingObject & 0x3fff, 0, 0);
@@ -1305,7 +1250,7 @@ bool LoLEngine::chasePartyWithDistanceAttacks(MonsterInPlay *monster) {
}
}
} else if (!(flyingObject & 0x2000)) {
- if (getMonsterDistance(monster->block, _currentBlock) > 1)
+ if (getBlockDistance(monster->block, _currentBlock) > 1)
return false;
if (flyingObject == 1) {
@@ -1326,7 +1271,7 @@ bool LoLEngine::chasePartyWithDistanceAttacks(MonsterInPlay *monster) {
} else if (flyingObject == 3) {
// shriek
for (int i = 0; i < 30; i++) {
- if (getMonsterDistance(monster->block, _monsters[i].block) < 7)
+ if (getBlockDistance(monster->block, _monsters[i].block) < 7)
setMonsterMode(monster, 7);
}
_txt->printMessage(2, "%s", getLangString(0x401a));
@@ -1347,7 +1292,7 @@ bool LoLEngine::chasePartyWithDistanceAttacks(MonsterInPlay *monster) {
return true;
}
-void LoLEngine::chasePartyWithCloseAttacks(MonsterInPlay *monster) {
+void LoLEngine::chasePartyWithCloseAttacks(LoLMonster *monster) {
if (!(monster->flags & 8)) {
int dir = calcMonsterDirection(monster->x & 0xff00, monster->y & 0xff00, _partyPosX & 0xff00, _partyPosY & 0xff00);
int x1 = _partyPosX;
@@ -1365,7 +1310,7 @@ void LoLEngine::chasePartyWithCloseAttacks(MonsterInPlay *monster) {
if (hit) {
int mx = calcInflictableDamage(m, dst, hit);
- int dmg = rollDice(2, mx );
+ int dmg = rollDice(2, mx);
inflictDamage(dst, dmg, m, 0, 0);
applyMonsterAttackSkill(monster, dst, dmg);
}
@@ -1389,7 +1334,7 @@ void LoLEngine::chasePartyWithCloseAttacks(MonsterInPlay *monster) {
}
}
-int LoLEngine::walkMonsterCalcNextStep(MonsterInPlay *monster) {
+int LoLEngine::walkMonsterCalcNextStep(LoLMonster *monster) {
static const int8 walkMonsterTable1[] = { 7, -6, 5, -4, 3, -2, 1, 0 };
static const int8 walkMonsterTable2[] = { -7, 6, -5, 4, -3, 2, -1, 0 };
@@ -1445,23 +1390,8 @@ int LoLEngine::walkMonsterCalcNextStep(MonsterInPlay *monster) {
return -1;
}
-int LoLEngine::getMonsterDistance(uint16 block1, uint16 block2) {
- int b1x = block1 & 0x1f;
- int b1y = block1 >> 5;
- int b2x = block2 & 0x1f;
- int b2y = block2 >> 5;
-
- uint8 dy = ABS(b2y - b1y);
- uint8 dx = ABS(b2x - b1x);
-
- if (dx > dy)
- SWAP(dx, dy);
-
- return (dx >> 1) + dy;
-}
-
int LoLEngine::checkForPossibleDistanceAttack(uint16 monsterBlock, int direction, int distance, uint16 curBlock) {
- int mdist = getMonsterDistance(curBlock, monsterBlock);
+ int mdist = getBlockDistance(curBlock, monsterBlock);
if (mdist > distance)
return 5;
@@ -1494,7 +1424,7 @@ int LoLEngine::checkForPossibleDistanceAttack(uint16 monsterBlock, int direction
return 5;
}
-int LoLEngine::walkMonsterCheckDest(int x, int y, MonsterInPlay *monster, int unk) {
+int LoLEngine::walkMonsterCheckDest(int x, int y, LoLMonster *monster, int unk) {
uint8 m = monster->mode;
monster->mode = 15;
@@ -1512,7 +1442,7 @@ void LoLEngine::getNextStepCoords(int16 srcX, int16 srcY, int &newX, int &newY,
newY = (srcY + shiftTableY[direction]) & 0x1fff;
}
-void LoLEngine::rearrangeAttackingMonster(MonsterInPlay *monster) {
+void LoLEngine::rearrangeAttackingMonster(LoLMonster *monster) {
int t = (monster->direction >> 1);
uint16 mx = monster->x;
uint16 my = monster->y;
@@ -1579,7 +1509,7 @@ void LoLEngine::rearrangeAttackingMonster(MonsterInPlay *monster) {
placeMonster(monster, mx, my);
}
-void LoLEngine::moveStrayingMonster(MonsterInPlay *monster) {
+void LoLEngine::moveStrayingMonster(LoLMonster *monster) {
int x = 0;
int y = 0;
@@ -1616,13 +1546,13 @@ void LoLEngine::moveStrayingMonster(MonsterInPlay *monster) {
}
}
-void LoLEngine::killMonster(MonsterInPlay *monster) {
+void LoLEngine::killMonster(LoLMonster *monster) {
setMonsterMode(monster, 14);
monsterDropItems(monster);
checkSceneUpdateNeed(monster->block);
uint8 w = _levelBlockProperties[monster->block].walls[0];
- uint8 f = _levelBlockProperties[monster->block].flags;
+ uint16 f = _levelBlockProperties[monster->block].flags;
if (_wllVmpMap[w] == 0 && _wllShapeMap[w] == 0 && !(f & 0x40) && !(monster->properties->flags & 0x1000))
_levelBlockProperties[monster->block].flags |= 0x80;
diff --git a/engines/kyra/sprites_rpg.cpp b/engines/kyra/sprites_rpg.cpp
new file mode 100644
index 0000000000..0c4fcb09ab
--- /dev/null
+++ b/engines/kyra/sprites_rpg.cpp
@@ -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.
+ *
+ */
+
+#if defined(ENABLE_EOB) || defined(ENABLE_LOL)
+
+#include "kyra/kyra_rpg.h"
+
+namespace Kyra {
+
+int KyraRpgEngine::getBlockDistance(uint16 block1, uint16 block2) {
+ int b1x = block1 & 0x1f;
+ int b1y = block1 >> 5;
+ int b2x = block2 & 0x1f;
+ int b2y = block2 >> 5;
+
+ uint8 dy = ABS(b2y - b1y);
+ uint8 dx = ABS(b2x - b1x);
+
+ if (dx > dy)
+ SWAP(dx, dy);
+
+ return (dx >> 1) + dy;
+}
+
+} // namespace Kyra
+
+#endif
diff --git a/engines/kyra/staticres.cpp b/engines/kyra/staticres.cpp
index e03369f700..423b827092 100644
--- a/engines/kyra/staticres.cpp
+++ b/engines/kyra/staticres.cpp
@@ -38,7 +38,7 @@
namespace Kyra {
-#define RESFILE_VERSION 78
+#define RESFILE_VERSION 82
namespace {
bool checkKyraDat(Common::SeekableReadStream *file) {
@@ -75,7 +75,9 @@ const IndexTable iGameTable[] = {
{ GI_KYRA1, 0 },
{ GI_KYRA2, 1 },
{ GI_KYRA3, 2 },
- { GI_LOL, 3 },
+ { GI_EOB1, 3 },
+ { GI_EOB2, 4 },
+ { GI_LOL, 5 },
{ -1, -1 }
};
@@ -245,17 +247,34 @@ bool StaticResource::init() {
{ k2SeqData, proc(loadHofSequenceData), proc(freeHofSequenceData) },
{ k2ShpAnimDataV1, proc(loadShapeAnimData_v1), proc(freeHofShapeAnimDataV1) },
- { k2ShpAnimDataV2, proc(loadShapeAnimData_v2), proc(freeHofShapeAnimDataV2) },
+ { k2ItemAnimDefinition, proc(loadItemAnimDefinition), proc(freeItemAnimDefinition) },
#ifdef ENABLE_LOL
- { kLolCharData, proc(loadCharData), proc(freeCharData) },
- { kLolSpellData, proc(loadSpellData), proc(freeSpellData) },
- { kLolCompassData, proc(loadCompassData), proc(freeCompassData) },
- { kLolFlightShpData, proc(loadFlyingObjectData), proc(freeFlyingObjectData) },
- { kLolRawDataBe16, proc(loadRawDataBe16), proc(freeRawDataBe16) },
- { kLolRawDataBe32, proc(loadRawDataBe32), proc(freeRawDataBe32) },
- { kLolButtonData, proc(loadButtonDefs), proc(freeButtonDefs) },
-#endif // ENABLE_LOL
+ { kLoLCharData, proc(loadCharData), proc(freeCharData) },
+ { kLoLSpellData, proc(loadSpellData), proc(freeSpellData) },
+ { kLoLCompassData, proc(loadCompassData), proc(freeCompassData) },
+ { kLoLFlightShpData, proc(loadFlyingObjectData), proc(freeFlyingObjectData) },
+#else
+ { kLoLCharData, proc(loadDummy), proc(freeDummy) },
+ { kLoLSpellData, proc(loadDummy), proc(freeDummy) },
+ { kLoLCompassData, proc(loadDummy), proc(freeDummy) },
+ { kLoLFlightShpData, proc(loadDummy), proc(freeDummy) },
+#endif
+#if defined(ENABLE_EOB) || defined(ENABLE_LOL)
+ { kRawDataBe16, proc(loadRawDataBe16), proc(freeRawDataBe16) },
+ { kRawDataBe32, proc(loadRawDataBe32), proc(freeRawDataBe32) },
+#endif
+#ifdef ENABLE_LOL
+ { kLoLButtonData, proc(loadButtonDefs), proc(freeButtonDefs) },
+#else
+ { kLoLButtonData, proc(loadDummy), proc(freeDummy) },
+#endif
+
+#ifdef ENABLE_EOB
+ { kEoB2SequenceData, proc(loadEoB2SeqData), proc(freeEoB2SeqData) },
+ { kEoB2ShapeData, proc(loadEoB2ShapeData), proc(freeEoB2ShapeData) },
+ { kEoBNpcData, proc(loadEoBNpcData), proc(freeEoBNpcData) },
+#endif
{ 0, 0, 0 }
};
@@ -269,7 +288,7 @@ void StaticResource::deinit() {
unloadId(-1);
}
-const char * const *StaticResource::loadStrings(int id, int &strings) {
+const char *const *StaticResource::loadStrings(int id, int &strings) {
return (const char * const *)getData(id, kStringList, strings);
}
@@ -297,8 +316,8 @@ const ItemAnimData_v1 *StaticResource::loadShapeAnimData_v1(int id, int &entries
return (const ItemAnimData_v1 *)getData(id, k2ShpAnimDataV1, entries);
}
-const ItemAnimData_v2 *StaticResource::loadShapeAnimData_v2(int id, int &entries) {
- return (const ItemAnimData_v2 *)getData(id, k2ShpAnimDataV2, entries);
+const ItemAnimDefinition *StaticResource::loadItemAnimDefinition(int id, int &entries) {
+ return (const ItemAnimDefinition *)getData(id, k2ItemAnimDefinition, entries);
}
bool StaticResource::prefetchId(int id) {
@@ -403,6 +422,10 @@ const void *StaticResource::getData(int id, int requesttype, int &size) {
return 0;
}
+bool StaticResource::loadDummy(Common::SeekableReadStream &stream, void *&ptr, int &size) {
+ return true;
+}
+
bool StaticResource::loadStringTable(Common::SeekableReadStream &stream, void *&ptr, int &size) {
uint32 count = stream.readUint32BE();
size = count;
@@ -415,7 +438,7 @@ bool StaticResource::loadStringTable(Common::SeekableReadStream &stream, void *&
while ((c = (char)stream.readByte()) != 0)
string += c;
- output[i] = new char[string.size()+1];
+ output[i] = new char[string.size() + 1];
strcpy(output[i], string.c_str());
}
@@ -479,10 +502,10 @@ bool StaticResource::loadRoomTable(Common::SeekableReadStream &stream, void *&pt
loadTo[i].eastExit = stream.readUint16BE();
loadTo[i].southExit = stream.readUint16BE();
loadTo[i].westExit = stream.readUint16BE();
- memset(&loadTo[i].itemsTable[0], 0xFF, sizeof(byte)*6);
- memset(&loadTo[i].itemsTable[6], 0, sizeof(byte)*6);
- memset(loadTo[i].itemsXPos, 0, sizeof(uint16)*12);
- memset(loadTo[i].itemsYPos, 0, sizeof(uint8)*12);
+ memset(&loadTo[i].itemsTable[0], 0xFF, sizeof(byte) * 6);
+ memset(&loadTo[i].itemsTable[6], 0, sizeof(byte) * 6);
+ memset(loadTo[i].itemsXPos, 0, sizeof(uint16) * 12);
+ memset(loadTo[i].itemsYPos, 0, sizeof(uint8) * 12);
memset(loadTo[i].needInit, 0, sizeof(loadTo[i].needInit));
}
@@ -587,9 +610,9 @@ bool StaticResource::loadShapeAnimData_v1(Common::SeekableReadStream &stream, vo
return true;
}
-bool StaticResource::loadShapeAnimData_v2(Common::SeekableReadStream &stream, void *&ptr, int &size) {
+bool StaticResource::loadItemAnimDefinition(Common::SeekableReadStream &stream, void *&ptr, int &size) {
size = stream.readByte();
- ItemAnimData_v2 *loadTo = new ItemAnimData_v2[size];
+ ItemAnimDefinition *loadTo = new ItemAnimDefinition[size];
assert(loadTo);
for (int i = 0; i < size; i++) {
@@ -607,6 +630,9 @@ bool StaticResource::loadShapeAnimData_v2(Common::SeekableReadStream &stream, vo
return true;
}
+void StaticResource::freeDummy(void *&ptr, int &size) {
+}
+
void StaticResource::freeRawData(void *&ptr, int &size) {
uint8 *data = (uint8 *)ptr;
delete[] data;
@@ -665,7 +691,7 @@ void StaticResource::freeHofSequenceData(void *&ptr, int &size) {
}
void StaticResource::freeHofShapeAnimDataV1(void *&ptr, int &size) {
- ItemAnimData_v1 *d= (ItemAnimData_v1 *)ptr;
+ ItemAnimData_v1 *d = (ItemAnimData_v1 *)ptr;
for (int i = 0; i < size; i++)
delete[] d[i].frames;
delete[] d;
@@ -673,8 +699,8 @@ void StaticResource::freeHofShapeAnimDataV1(void *&ptr, int &size) {
size = 0;
}
-void StaticResource::freeHofShapeAnimDataV2(void *&ptr, int &size) {
- ItemAnimData_v2 *d= (ItemAnimData_v2 *)ptr;
+void StaticResource::freeItemAnimDefinition(void *&ptr, int &size) {
+ ItemAnimDefinition *d = (ItemAnimDefinition *)ptr;
for (int i = 0; i < size; i++)
delete[] d[i].frames;
delete[] d;
@@ -774,7 +800,7 @@ void KyraEngine_LoK::initStaticResource() {
_roomTable = new Room[_roomTableSize];
assert(_roomTable);
- memcpy(_roomTable, tempRoomList, _roomTableSize*sizeof(Room));
+ memcpy(_roomTable, tempRoomList, _roomTableSize * sizeof(Room));
tempRoomList = 0;
_staticres->unloadId(k1RoomList);
@@ -787,7 +813,7 @@ void KyraEngine_LoK::initStaticResource() {
_defaultShapeTable = new Shape[_defaultShapeTableSize];
assert(_defaultShapeTable);
- memcpy(_defaultShapeTable, tempShapeTable, _defaultShapeTableSize*sizeof(Shape));
+ memcpy(_defaultShapeTable, tempShapeTable, _defaultShapeTableSize * sizeof(Shape));
tempShapeTable = 0;
_staticres->unloadId(k1DefaultShapes);
@@ -848,7 +874,7 @@ void KyraEngine_LoK::loadCharacterShapes() {
assert(i < _defaultShapeTableSize);
Shape *shape = &_defaultShapeTable[i];
if (shape->imageIndex == 0xFF) {
- _shapes[i+7] = 0;
+ _shapes[i + 7] = 0;
continue;
}
if (shape->imageIndex != curImage) {
@@ -856,7 +882,7 @@ void KyraEngine_LoK::loadCharacterShapes() {
_screen->loadBitmap(_characterImageTable[shape->imageIndex], 3, 3, 0);
curImage = shape->imageIndex;
}
- _shapes[i+7] = _screen->encodeShape(shape->x<<3, shape->y, shape->w<<3, shape->h, 1);
+ _shapes[i + 7] = _screen->encodeShape(shape->x << 3, shape->y, shape->w << 3, shape->h, 1);
}
_screen->_curPage = videoPage;
}
@@ -867,16 +893,16 @@ void KyraEngine_LoK::loadSpecialEffectShapes() {
int currShape;
for (currShape = 173; currShape < 183; currShape++)
- _shapes[currShape] = _screen->encodeShape((currShape-173) * 24, 0, 24, 24, 1);
+ _shapes[currShape] = _screen->encodeShape((currShape - 173) * 24, 0, 24, 24, 1);
for (currShape = 183; currShape < 190; currShape++)
- _shapes[currShape] = _screen->encodeShape((currShape-183) * 24, 24, 24, 24, 1);
+ _shapes[currShape] = _screen->encodeShape((currShape - 183) * 24, 24, 24, 24, 1);
for (currShape = 190; currShape < 201; currShape++)
- _shapes[currShape] = _screen->encodeShape((currShape-190) * 24, 48, 24, 24, 1);
+ _shapes[currShape] = _screen->encodeShape((currShape - 190) * 24, 48, 24, 24, 1);
for (currShape = 201; currShape < 206; currShape++)
- _shapes[currShape] = _screen->encodeShape((currShape-201) * 16, 106, 16, 16, 1);
+ _shapes[currShape] = _screen->encodeShape((currShape - 201) * 16, 106, 16, 16, 1);
}
void KyraEngine_LoK::loadItems() {
@@ -891,22 +917,22 @@ void KyraEngine_LoK::loadItems() {
_shapes[323 + shape] = _screen->encodeShape((shape - 1) * 32, 0, 32, 17, 0);
for (shape = 330; shape <= 334; shape++)
- _shapes[shape] = _screen->encodeShape((shape-330) * 32, 102, 32, 17, 0);
+ _shapes[shape] = _screen->encodeShape((shape - 330) * 32, 102, 32, 17, 0);
for (shape = 335; shape <= 339; shape++)
- _shapes[shape] = _screen->encodeShape((shape-335) * 32, 17, 32, 17, 0);
+ _shapes[shape] = _screen->encodeShape((shape - 335) * 32, 17, 32, 17, 0);
for (shape = 340; shape <= 344; shape++)
- _shapes[shape] = _screen->encodeShape((shape-340) * 32, 34, 32, 17, 0);
+ _shapes[shape] = _screen->encodeShape((shape - 340) * 32, 34, 32, 17, 0);
for (shape = 345; shape <= 349; shape++)
- _shapes[shape] = _screen->encodeShape((shape-345) * 32, 51, 32, 17, 0);
+ _shapes[shape] = _screen->encodeShape((shape - 345) * 32, 51, 32, 17, 0);
for (shape = 350; shape <= 354; shape++)
- _shapes[shape] = _screen->encodeShape((shape-350) * 32, 68, 32, 17, 0);
+ _shapes[shape] = _screen->encodeShape((shape - 350) * 32, 68, 32, 17, 0);
for (shape = 355; shape <= 359; shape++)
- _shapes[shape] = _screen->encodeShape((shape-355) * 32, 85, 32, 17, 0);
+ _shapes[shape] = _screen->encodeShape((shape - 355) * 32, 85, 32, 17, 0);
_screen->loadBitmap("ITEMS.CPS", 3, 3, 0);
@@ -918,7 +944,7 @@ void KyraEngine_LoK::loadItems() {
if (shape != -1)
_shapes[216 + i] = _shapes[216 + shape];
else
- _shapes[216 + i] = _screen->encodeShape( (i % 20) * 16, i/20 * 16, 16, 16, 0);
+ _shapes[216 + i] = _screen->encodeShape((i % 20) * 16, i / 20 * 16, 16, 16, 0);
}
_res->loadFileToBuf("_ITEM_HT.DAT", &_itemHtDat, sizeof(_itemHtDat));
@@ -981,7 +1007,7 @@ void KyraEngine_HoF::initStaticResource() {
_cdaTrackTableFinale = _staticres->loadRawData(k2SeqplayFinaleCDA, _cdaTrackTableFinaleSize);
_ingameTalkObjIndex = (const uint16 *)_staticres->loadRawData(k2IngameTalkObjIndex, _ingameTalkObjIndexSize);
_ingameTimJpStr = _staticres->loadStrings(k2IngameTimJpStrings, _ingameTimJpStrSize);
- _itemAnimData = _staticres->loadShapeAnimData_v2(k2IngameShapeAnimData, _itemAnimDataSize);
+ _itemAnimDefinition = _staticres->loadItemAnimDefinition(k2IngameShapeAnimData, _itemAnimDefinitionSize);
// replace sequence talkie files with localized versions
const char *const *seqSoundList = _staticres->loadStrings(k2SeqplaySfxFiles, _sequenceSoundListSize);
@@ -997,7 +1023,7 @@ void KyraEngine_HoF::initStaticResource() {
if (tlkfiles && len > 1) {
for (int ii = 0; ii < tmpSize; ii++) {
if (strlen(tlkfiles[ii]) > 1 && !scumm_stricmp(&seqSoundList[i][1], &tlkfiles[ii][1]))
- strcpy(tmpSndLst[i], tlkfiles[ii]);
+ strcpy(tmpSndLst[i], tlkfiles[ii]);
}
}
@@ -1052,8 +1078,8 @@ void KyraEngine_HoF::initStaticResource() {
// setup sequence data
_sequences = _staticres->loadHofSequenceData(k2SeqplaySeqData, tmpSize);
- static const SeqProc hofSequenceCallbacks[] = { 0,
- &KyraEngine_HoF::seq_introWestwood,
+ static const SeqProc hofSequenceCallbacks[] = {
+ 0, &KyraEngine_HoF::seq_introWestwood,
&KyraEngine_HoF::seq_introTitle, &KyraEngine_HoF::seq_introOverview,
&KyraEngine_HoF::seq_introLibrary, &KyraEngine_HoF::seq_introHand,
&KyraEngine_HoF::seq_introPoint, &KyraEngine_HoF::seq_introZanfaun,
@@ -1087,26 +1113,27 @@ void KyraEngine_HoF::initStaticResource() {
};
#ifdef ENABLE_LOL
- static const SeqProc kLolDemoSequenceCallbacks[] = {
+ static const SeqProc kLoLDemoSequenceCallbacks[] = {
&KyraEngine_HoF::seq_lolDemoScene1, 0, &KyraEngine_HoF::seq_lolDemoScene2, 0,
&KyraEngine_HoF::seq_lolDemoScene3, 0, &KyraEngine_HoF::seq_lolDemoScene4, 0,
&KyraEngine_HoF::seq_lolDemoScene5, &KyraEngine_HoF::seq_lolDemoText5,
&KyraEngine_HoF::seq_lolDemoScene6, 0
};
- static const SeqProc kLolDemoNestedSequenceCallbacks[] = { 0 };
+ static const SeqProc kLoLDemoNestedSequenceCallbacks[] = { 0 };
#endif // ENABLE_LOL
_callbackS =
#ifdef ENABLE_LOL
- _flags.gameID == GI_LOL ? kLolDemoSequenceCallbacks :
+ _flags.gameID == GI_LOL ? kLoLDemoSequenceCallbacks :
#endif // ENABLE_LOL
- ((_flags.isDemo && !_flags.isTalkie) ? hofDemoSequenceCallbacks : hofSequenceCallbacks);
+ ((_flags.isDemo && !_flags.isTalkie) ? hofDemoSequenceCallbacks : hofSequenceCallbacks);
+
_callbackN =
#ifdef ENABLE_LOL
- _flags.gameID == GI_LOL ? kLolDemoNestedSequenceCallbacks :
+ _flags.gameID == GI_LOL ? kLoLDemoNestedSequenceCallbacks :
#endif // ENABLE_LOL
- ((_flags.isDemo && !_flags.isTalkie) ? hofDemoNestedSequenceCallbacks : hofNestedSequenceCallbacks);
+ ((_flags.isDemo && !_flags.isTalkie) ? hofDemoNestedSequenceCallbacks : hofNestedSequenceCallbacks);
}
void KyraEngine_MR::initStaticResource() {
@@ -1116,7 +1143,7 @@ void KyraEngine_MR::initStaticResource() {
_scoreTable = _staticres->loadRawData(k3ScoreTable, _scoreTableSize);
_sfxFileList = _staticres->loadStrings(k3SfxFiles, _sfxFileListSize);
_sfxFileMap = _staticres->loadRawData(k3SfxMap, _sfxFileMapSize);
- _itemAnimData = _staticres->loadShapeAnimData_v2(k3ItemAnimData, tmp);
+ _itemAnimDefinition = _staticres->loadItemAnimDefinition(k3ItemAnimData, tmp);
_itemMagicTable = _staticres->loadRawData(k3ItemMagicTable, tmp);
_itemStringMap = _staticres->loadRawData(k3ItemStringMap, _itemStringMapSize);
}
@@ -1158,7 +1185,7 @@ const ScreenDim Screen_HoF::_screenDimTable[] = {
{ 0x00, 0x00, 0x28, 0x88, 0xC7, 0xCF, 0x00, 0x00 },
{ 0x00, 0x08, 0x28, 0xB8, 0xC7, 0xCF, 0x00, 0x00 },
{ 0x01, 0x28, 0x26, 0x46, 0xC7, 0xCC, 0x00, 0x00 },
- { 0x0A, 0x96, 0x14, 0x30, 0x19, 0xF0, 0x00, 0x00 } // menu, just present for current menu code
+ { 0x0A, 0x96, 0x14, 0x30, 0x19, 0xF0, 0x00, 0x00 } // menu, just present for current menu code
};
const int Screen_HoF::_screenDimTableCount = ARRAYSIZE(Screen_HoF::_screenDimTable);
@@ -1227,7 +1254,7 @@ void GUI_LoK::initStaticResource() {
_menu[0].item[3].callback = quitPlayingFunctor;
_menu[0].item[4].callback = BUTTON_FUNCTOR(GUI_LoK, this, &GUI_LoK::resumeGame);
- GUI_V1_MENU(_menu[1], -1, -1, 0x140, 0x38, 248, 249, 250, 0, 254,-1, 8, 0, 2, -1, -1, -1, -1);
+ GUI_V1_MENU(_menu[1], -1, -1, 0x140, 0x38, 248, 249, 250, 0, 254, -1, 8, 0, 2, -1, -1, -1, -1);
GUI_V1_MENU_ITEM(_menu[1].item[0], 1, 0, 0, 0, 0x18, 0, 0x1E, 0x48, 0x0F, 252, 253, -1, 255, 248, 249, 250, -1, 0, 0, 0, 0, 0);
GUI_V1_MENU_ITEM(_menu[1].item[1], 1, 0, 0, 0, 0xD8, 0, 0x1E, 0x48, 0x0F, 252, 253, -1, 255, 248, 249, 250, -1, 0, 0, 0, 0, 0);
_menu[1].item[0].callback = BUTTON_FUNCTOR(GUI_LoK, this, &GUI_LoK::quitConfirmYes);
@@ -1320,7 +1347,7 @@ void KyraEngine_LoK::setupButtonData() {
_buttonData[i].buttonCallback = amuletFunctor;
for (int i = 1; i < 15; ++i)
- _buttonDataListPtr[i-1] = &_buttonData[i];
+ _buttonDataListPtr[i - 1] = &_buttonData[i];
_buttonDataListPtr[14] = 0;
}
@@ -1391,7 +1418,7 @@ const char *const KyraEngine_HoF::_languageExtension[] = {
"ENG",
"FRE",
"GER",/*,
- "ITA", Italian and Spanish were never included
+ "ITA", Italian and Spanish were never included
"SPA"*/
"JPN",
};
@@ -1400,7 +1427,7 @@ const char *const KyraEngine_HoF::_scriptLangExt[] = {
"EMC",
"FMC",
"GMC",/*,
- "IMC", Italian and Spanish were never included
+ "IMC", Italian and Spanish were never included
"SMC"*/
"JMC"
};
@@ -1579,7 +1606,7 @@ void KyraEngine_HoF::initInventoryButtonList() {
GUI_V2_BUTTON(_inventoryButtons[1], 0x2, 0x00, 0, 1, 1, 1, 0x4487, 0, 0x104, 0x90, 0x3C, 0x2C, 0xC7, 0xCF, 0xC7, 0xCF, 0xC7, 0xCF, 0);
_inventoryButtons[1].buttonCallback = BUTTON_FUNCTOR(KyraEngine_HoF, this, &KyraEngine_HoF::cauldronButton);
- GUI_V2_BUTTON(_inventoryButtons[2], 0x5, 0x00, 0, 1, 1, 1, 0x4487, 0, 0x0FA, 0x90, 0x0A, 0x2C, 0xC7, 0xCF, 0xC7, 0xCF, 0xC7, 0xCF, 0);
+ GUI_V2_BUTTON(_inventoryButtons[2], 0x5, 0x00, 0, 1, 1, 1, 0x4487, 0, 0x0FA, 0x90, 0x0A, 0x2C, 0xC7, 0xCF, 0xC7, 0xCF, 0xC7, 0xCF, 0);
_inventoryButtons[2].buttonCallback = BUTTON_FUNCTOR(KyraEngine_HoF, this, &KyraEngine_HoF::cauldronClearButton);
GUI_V2_BUTTON(_inventoryButtons[3], 0x3, 0x00, 0, 1, 1, 1, 0x4487, 0, 0x0CE, 0x90, 0x2C, 0x2C, 0xC7, 0xCF, 0xC7, 0xCF, 0xC7, 0xCF, 0);
@@ -1613,14 +1640,14 @@ void GUI_HoF::initStaticData() {
GUI_V2_BUTTON(_scrollDownButton, 0x18, 0, 0, 1, 1, 1, 0x4487, 0, 0, 0, 0x18, 0x0F, 0xC7, 0xCF, 0xC7, 0xCF, 0xC7, 0xCF, 0);
for (int i = 0; i < 4; ++i)
- GUI_V2_BUTTON(_sliderButtons[0][i], 0x18+i, 0, 0, 1, 1, 1, 0x4487, 0, 0, 0, 0x0A, 0x0E, 0xC7, 0xCF, 0xC7, 0xCF, 0xC7, 0xCF, 0);
+ GUI_V2_BUTTON(_sliderButtons[0][i], 0x18 + i, 0, 0, 1, 1, 1, 0x4487, 0, 0, 0, 0x0A, 0x0E, 0xC7, 0xCF, 0xC7, 0xCF, 0xC7, 0xCF, 0);
for (int i = 0; i < 4; ++i)
- GUI_V2_BUTTON(_sliderButtons[1][i], 0x1C+i, 0, 0, 1, 1, 1, 0x4487, 0, 0, 0, 0x0A, 0x0E, 0xC7, 0xCF, 0xC7, 0xCF, 0xC7, 0xCF, 0);
+ GUI_V2_BUTTON(_sliderButtons[1][i], 0x1C + i, 0, 0, 1, 1, 1, 0x4487, 0, 0, 0, 0x0A, 0x0E, 0xC7, 0xCF, 0xC7, 0xCF, 0xC7, 0xCF, 0);
for (int i = 0; i < 4; ++i)
- GUI_V2_BUTTON(_sliderButtons[2][i], 0x20+i, 0, 0, 0, 0, 0, 0x2200, 0, 0, 0, 0x6E, 0x0E, 0xC7, 0xCF, 0xC7, 0xCF, 0xC7, 0xCF, 0);
+ GUI_V2_BUTTON(_sliderButtons[2][i], 0x20 + i, 0, 0, 0, 0, 0, 0x2200, 0, 0, 0, 0x6E, 0x0E, 0xC7, 0xCF, 0xC7, 0xCF, 0xC7, 0xCF, 0);
for (uint i = 0; i < ARRAYSIZE(_menuButtons); ++i)
- GUI_V2_BUTTON(_menuButtons[i], 0x10+i, 0, 0, 1, 1, 1, 0x4487, 0, 0, 0, 0, 0, 0xC7, 0xCF, 0xC7, 0xCF, 0xC7, 0xCF, 0);
+ GUI_V2_BUTTON(_menuButtons[i], 0x10 + i, 0, 0, 1, 1, 1, 0x4487, 0, 0, 0, 0, 0, 0xC7, 0xCF, 0xC7, 0xCF, 0xC7, 0xCF, 0);
Button::Callback clickLoadSlotFunctor = BUTTON_FUNCTOR(GUI_HoF, this, &GUI_HoF::clickLoadSlot);
Button::Callback clickSaveSlotFunctor = BUTTON_FUNCTOR(GUI_HoF, this, &GUI_HoF::clickSaveSlot);
@@ -1653,7 +1680,7 @@ void GUI_HoF::initStaticData() {
_mainMenu.numberOfItems = 6;
_mainMenu.item[6].enabled = false;
for (int i = 4; i < 6; ++i)
- _mainMenu.item[i].callback = _mainMenu.item[i+1].callback;
+ _mainMenu.item[i].callback = _mainMenu.item[i + 1].callback;
_mainMenu.item[3].callback = BUTTON_FUNCTOR(GUI_HoF, this, &GUI_HoF::gameOptions);
_mainMenu.item[6].callback = Button::Callback();
_mainMenu.item[5].y = 0x7F;
@@ -1755,25 +1782,25 @@ void GUI_HoF::initStaticData() {
}
const uint16 GUI_HoF::_menuStringsTalkie[] = {
- 0x001, 0x002, 0x003, 0x023, 0x004, 0x025, 0x005, 0x006, // Main Menu String IDs
- 0x025, 0x000, 0x000, 0x000, 0x010, 0x000, 0x000, 0x000, // Options Menu String IDs
- 0x007, 0x000, 0x000, 0x000, 0x010, 0x000, 0x000, 0x000, // Audio Menu String IDs
- 0x000, 0x014, 0x013, 0x000, 0x000, 0x000, 0x000, 0x000, // Menu3 Menu String IDs
- 0x008, 0x029, 0x02A, 0x02B, 0x02C, 0x02D, 0x00B, 0x000, // Load Menu String IDs
- 0x009, 0x029, 0x02A, 0x02B, 0x02C, 0x02D, 0x00B, 0x000, // Save Menu String IDs
- 0x00C, 0x00D, 0x00B, 0x000, 0x000, 0x000, 0x000, 0x000, // Menu6 Menu String IDs
- 0x00E, 0x002, 0x005, 0x000, 0x000, 0x000, 0x000, 0x000 // Death Menu String IDs
+ 0x001, 0x002, 0x003, 0x023, 0x004, 0x025, 0x005, 0x006, // Main Menu String IDs
+ 0x025, 0x000, 0x000, 0x000, 0x010, 0x000, 0x000, 0x000, // Options Menu String IDs
+ 0x007, 0x000, 0x000, 0x000, 0x010, 0x000, 0x000, 0x000, // Audio Menu String IDs
+ 0x000, 0x014, 0x013, 0x000, 0x000, 0x000, 0x000, 0x000, // Menu3 Menu String IDs
+ 0x008, 0x029, 0x02A, 0x02B, 0x02C, 0x02D, 0x00B, 0x000, // Load Menu String IDs
+ 0x009, 0x029, 0x02A, 0x02B, 0x02C, 0x02D, 0x00B, 0x000, // Save Menu String IDs
+ 0x00C, 0x00D, 0x00B, 0x000, 0x000, 0x000, 0x000, 0x000, // Menu6 Menu String IDs
+ 0x00E, 0x002, 0x005, 0x000, 0x000, 0x000, 0x000, 0x000 // Death Menu String IDs
};
const uint16 GUI_HoF::_menuStringsOther[] = {
- 0x009, 0x00A, 0x00B, 0x001, 0x00C, 0x00D, 0x00E, 0x000, // Main Menu String IDs
- 0x00F, 0x02B, 0x02C, 0x02D, 0x02E, 0x018, 0x000, 0x000, // Options Menu String IDs
- 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, // Dummy
- 0x000, 0x01C, 0x01B, 0x000, 0x000, 0x000, 0x000, 0x000, // Menu3 Menu String IDs
- 0x010, 0x02F, 0x030, 0x031, 0x032, 0x033, 0x013, 0x000, // Load Menu String IDs
- 0x011, 0x02F, 0x030, 0x031, 0x032, 0x033, 0x013, 0x000, // Save Menu String IDs
- 0x014, 0x015, 0x013, 0x3E8, 0x000, 0x000, 0x000, 0x000, // Menu6 String IDs
- 0x016, 0x00A, 0x00D, 0x000, 0x000, 0x000, 0x000, 0x000 // Death Menu String IDs
+ 0x009, 0x00A, 0x00B, 0x001, 0x00C, 0x00D, 0x00E, 0x000, // Main Menu String IDs
+ 0x00F, 0x02B, 0x02C, 0x02D, 0x02E, 0x018, 0x000, 0x000, // Options Menu String IDs
+ 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, // Dummy
+ 0x000, 0x01C, 0x01B, 0x000, 0x000, 0x000, 0x000, 0x000, // Menu3 Menu String IDs
+ 0x010, 0x02F, 0x030, 0x031, 0x032, 0x033, 0x013, 0x000, // Load Menu String IDs
+ 0x011, 0x02F, 0x030, 0x031, 0x032, 0x033, 0x013, 0x000, // Save Menu String IDs
+ 0x014, 0x015, 0x013, 0x3E8, 0x000, 0x000, 0x000, 0x000, // Menu6 String IDs
+ 0x016, 0x00A, 0x00D, 0x000, 0x000, 0x000, 0x000, 0x000 // Death Menu String IDs
};
const uint16 KyraEngine_HoF::_itemMagicTable[] = {
@@ -1889,20 +1916,20 @@ const char *const KyraEngine_MR::_languageExtension[] = {
"TRE",
"TRF",
"TRG"/*,
- "TRI", Italian and Spanish were never included, the supported fan translations are using
- "TRS" English/French extensions thus overwriting these languages */
+ "TRI", Italian and Spanish were never included, the supported fan translations are using
+ "TRS" English/French extensions thus overwriting these languages */
};
const int KyraEngine_MR::_languageExtensionSize = ARRAYSIZE(KyraEngine_MR::_languageExtension);
-const char * const KyraEngine_MR::_mainMenuSpanishFan[] = {
+const char *const KyraEngine_MR::_mainMenuSpanishFan[] = {
"Nueva Partida",
"Ver Intro",
"Restaurar",
"Finalizar"
};
-const char * const KyraEngine_MR::_mainMenuItalianFan[] = {
+const char *const KyraEngine_MR::_mainMenuItalianFan[] = {
"Nuova Partita",
"Introduzione",
"Carica una partita",
@@ -1998,13 +2025,13 @@ void KyraEngine_MR::initMainButtonList(bool disable) {
Button::Callback buttonInventoryFunctor = BUTTON_FUNCTOR(KyraEngine_MR, this, &KyraEngine_MR::buttonInventory);
for (int i = 0; i < 5; ++i) {
- GUI_V2_BUTTON(_mainButtonData[i+4], i+5, 0, 0, 0, 0, 0, 0x1100, 0, 67+i*28, 155, 27, 21, 0xFF, 0xF0, 0xFF, 0xF0, 0xFF, 0xF0, 0);
- _mainButtonData[i+4].buttonCallback = buttonInventoryFunctor;
+ GUI_V2_BUTTON(_mainButtonData[i + 4], i + 5, 0, 0, 0, 0, 0, 0x1100, 0, 67 + i * 28, 155, 27, 21, 0xFF, 0xF0, 0xFF, 0xF0, 0xFF, 0xF0, 0);
+ _mainButtonData[i + 4].buttonCallback = buttonInventoryFunctor;
}
for (int i = 0; i < 5; ++i) {
- GUI_V2_BUTTON(_mainButtonData[i+9], i+10, 0, 0, 0, 0, 0, 0x1100, 0, 67+i*28, 177, 27, 21, 0xFF, 0xF0, 0xFF, 0xF0, 0xFF, 0xF0, 0);
- _mainButtonData[i+9].buttonCallback = buttonInventoryFunctor;
+ GUI_V2_BUTTON(_mainButtonData[i + 9], i + 10, 0, 0, 0, 0, 0, 0x1100, 0, 67 + i * 28, 177, 27, 21, 0xFF, 0xF0, 0xFF, 0xF0, 0xFF, 0xF0, 0);
+ _mainButtonData[i + 9].buttonCallback = buttonInventoryFunctor;
}
for (int i = 0; i < 14; ++i)
@@ -2026,14 +2053,14 @@ void GUI_MR::initStaticData() {
GUI_V2_BUTTON(_scrollDownButton, 23, 0, 0, 4, 4, 4, 0x4487, 0, 0, 0, 0x18, 0x0F, 0xFF, 0xF0, 0xFF, 0xF0, 0xFF, 0xF0, 0);
for (int i = 0; i < 4; ++i)
- GUI_V2_BUTTON(_sliderButtons[0][i], 0x18+i, 0, 0, 1, 1, 1, 0x4487, 0, 0, 0, 0x0A, 0x0E, 0xFF, 0xF0, 0xFF, 0xF0, 0xFF, 0xF0, 0);
+ GUI_V2_BUTTON(_sliderButtons[0][i], 0x18 + i, 0, 0, 1, 1, 1, 0x4487, 0, 0, 0, 0x0A, 0x0E, 0xFF, 0xF0, 0xFF, 0xF0, 0xFF, 0xF0, 0);
for (int i = 0; i < 4; ++i)
- GUI_V2_BUTTON(_sliderButtons[1][i], 0x1C+i, 0, 0, 1, 1, 1, 0x4487, 0, 0, 0, 0x0A, 0x0E, 0xFF, 0xF0, 0xFF, 0xF0, 0xFF, 0xF0, 0);
+ GUI_V2_BUTTON(_sliderButtons[1][i], 0x1C + i, 0, 0, 1, 1, 1, 0x4487, 0, 0, 0, 0x0A, 0x0E, 0xFF, 0xF0, 0xFF, 0xF0, 0xFF, 0xF0, 0);
for (int i = 0; i < 4; ++i)
- GUI_V2_BUTTON(_sliderButtons[2][i], 0x20+i, 0, 0, 0, 0, 0, 0x2200, 0, 0, 0, 0x6E, 0x0E, 0xFF, 0xF0, 0xFF, 0xF0, 0xFF, 0xF0, 0);
+ GUI_V2_BUTTON(_sliderButtons[2][i], 0x20 + i, 0, 0, 0, 0, 0, 0x2200, 0, 0, 0, 0x6E, 0x0E, 0xFF, 0xF0, 0xFF, 0xF0, 0xFF, 0xF0, 0);
for (uint i = 0; i < ARRAYSIZE(_menuButtons); ++i)
- GUI_V2_BUTTON(_menuButtons[i], 0x0F+i, 0, 0, 1, 1, 1, 0x4487, 0, 0, 0, 0, 0, 0xFF, 0xF0, 0xFF, 0xF0, 0xFF, 0xF0, 0);
+ GUI_V2_BUTTON(_menuButtons[i], 0x0F + i, 0, 0, 1, 1, 1, 0x4487, 0, 0, 0, 0, 0, 0xFF, 0xF0, 0xFF, 0xF0, 0xFF, 0xF0, 0);
Button::Callback clickLoadSlotFunctor = BUTTON_FUNCTOR(GUI_MR, this, &GUI_MR::clickLoadSlot);
Button::Callback clickSaveSlotFunctor = BUTTON_FUNCTOR(GUI_MR, this, &GUI_MR::clickSaveSlot);
@@ -2132,7 +2159,7 @@ void GUI_MR::initStaticData() {
}
const int8 KyraEngine_MR::_albumWSAX[] = {
- 0, 77, -50, 99, -61, 82, -58, 85,
+ 0, 77, -50, 99, -61, 82, -58, 85,
-64, 80, -63, 88, -63, 88, -64, 0
};
diff --git a/engines/kyra/staticres_eob.cpp b/engines/kyra/staticres_eob.cpp
new file mode 100644
index 0000000000..7a5012f117
--- /dev/null
+++ b/engines/kyra/staticres_eob.cpp
@@ -0,0 +1,1356 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ *
+ */
+
+#include "kyra/eob.h"
+#include "kyra/resource.h"
+
+
+namespace Kyra {
+
+#ifdef ENABLE_EOB
+const DarkMoonAnimCommand *StaticResource::loadEoB2SeqData(int id, int &entries) {
+ return (const DarkMoonAnimCommand *)getData(id, kEoB2SequenceData, entries);
+}
+
+const DarkMoonShapeDef *StaticResource::loadEoB2ShapeData(int id, int &entries) {
+ return (const DarkMoonShapeDef *)getData(id, kEoB2ShapeData, entries);
+}
+
+const EoBCharacter *StaticResource::loadEoBNpcData(int id, int &entries) {
+ return (const EoBCharacter *)getData(id, kEoBNpcData, entries);
+}
+
+bool StaticResource::loadEoB2SeqData(Common::SeekableReadStream &stream, void *&ptr, int &size) {
+ size = stream.size() / 11;
+
+ DarkMoonAnimCommand *s = new DarkMoonAnimCommand[size];
+
+ for (int i = 0; i < size; i++) {
+ s[i].command = stream.readByte();
+ s[i].obj = stream.readByte();
+ s[i].x1 = stream.readSint16BE();
+ s[i].y1 = stream.readByte();
+ s[i].delay = stream.readByte();
+ s[i].pal = stream.readByte();
+ s[i].x2 = stream.readByte();
+ s[i].y2 = stream.readByte();
+ s[i].w = stream.readByte();
+ s[i].h = stream.readByte();
+ }
+
+ ptr = s;
+ return true;
+}
+
+bool StaticResource::loadEoB2ShapeData(Common::SeekableReadStream &stream, void *&ptr, int &size) {
+ size = stream.size() / 6;
+
+ DarkMoonShapeDef *s = new DarkMoonShapeDef[size];
+
+ for (int i = 0; i < size; i++) {
+ s[i].index = stream.readSint16BE();
+ s[i].x = stream.readByte();
+ s[i].y = stream.readByte();
+ s[i].w = stream.readByte();
+ s[i].h = stream.readByte();
+ }
+
+ ptr = s;
+ return true;
+}
+
+bool StaticResource::loadEoBNpcData(Common::SeekableReadStream &stream, void *&ptr, int &size) {
+ size = stream.readUint16BE();
+
+ EoBCharacter *e = new EoBCharacter[size];
+ memset(e, 0, size * sizeof(EoBCharacter));
+ EoBCharacter *s = e;
+
+ for (int i = 0; i < size; i++, s++) {
+ s->id = stream.readByte();
+ s->flags = stream.readByte();
+ stream.read(s->name, 11);
+ s->strengthCur = stream.readSByte();
+ s->strengthMax = stream.readSByte();
+ s->strengthExtCur = stream.readSByte();
+ s->strengthExtMax = stream.readSByte();
+ s->intelligenceCur = stream.readSByte();
+ s->intelligenceMax = stream.readSByte();
+ s->wisdomCur = stream.readSByte();
+ s->wisdomMax = stream.readSByte();
+ s->dexterityCur = stream.readSByte();
+ s->dexterityMax = stream.readSByte();
+ s->constitutionCur = stream.readSByte();
+ s->constitutionMax = stream.readSByte();
+ s->charismaCur = stream.readSByte();
+ s->charismaMax = stream.readSByte();
+ s->hitPointsCur = stream.readSint16BE();
+ s->hitPointsMax = stream.readSint16BE();
+ s->armorClass = stream.readSByte();
+ s->disabledSlots = stream.readByte();
+ s->raceSex = stream.readByte();
+ s->cClass = stream.readByte();
+ s->alignment = stream.readByte();
+ s->portrait = stream.readSByte();
+ s->food = stream.readByte();
+ stream.read(s->level, 3);
+ s->experience[0] = stream.readUint32BE();
+ s->experience[1] = stream.readUint32BE();
+ s->experience[2] = stream.readUint32BE();
+ s->mageSpellsAvailableFlags = stream.readUint32BE();
+ for (int ii = 0; ii < 27; ii++)
+ s->inventory[ii] = stream.readSint16BE();
+ }
+
+ ptr = e;
+ return true;
+}
+
+void StaticResource::freeEoB2SeqData(void *&ptr, int &size) {
+ DarkMoonAnimCommand *d = (DarkMoonAnimCommand *)ptr;
+ delete[] d;
+ ptr = 0;
+ size = 0;
+}
+
+void StaticResource::freeEoB2ShapeData(void *&ptr, int &size) {
+ DarkMoonShapeDef *d = (DarkMoonShapeDef *)ptr;
+ delete[] d;
+ ptr = 0;
+ size = 0;
+}
+
+void StaticResource::freeEoBNpcData(void *&ptr, int &size) {
+ EoBCharacter *d = (EoBCharacter *)ptr;
+ delete[] d;
+ ptr = 0;
+ size = 0;
+}
+
+const ScreenDim Screen_EoB::_screenDimTable[] = {
+ { 0x00, 0x00, 0x28, 0xC8, 0x0F, 0x0C, 0x00, 0x00 },
+ { 0x08, 0x48, 0x18, 0x38, 0x0E, 0x0C, 0x00, 0x00 },
+ { 0x13, 0x40, 0x14, 0x80, 0x06, 0x0C, 0x00, 0x00 },
+ { 0x1D, 0x78, 0x08, 0x40, 0x0F, 0x0D, 0x00, 0x00 },
+ { 0x02, 0x18, 0x14, 0x78, 0x0F, 0x02, 0x03, 0x00 },
+ { 0x00, 0x00, 0x16, 0x78, 0x0F, 0x0D, 0x00, 0x00 },
+ { 0x0A, 0x6C, 0x15, 0x28, 0x0F, 0x00, 0x00, 0x00 },
+ { 0x01, 0xB4, 0x22, 0x12, 0x0F, 0x0C, 0x00, 0x00 },
+ { 0x02, 0x18, 0x14, 0x00, 0x0F, 0x02, 0x03, 0x00 },
+ { 0x01, 0x7D, 0x26, 0x40, 0x0F, 0x00, 0x03, 0x00 },
+ { 0x00, 0x00, 0x16, 0x90, 0x0F, 0x02, 0x00, 0x00 },
+ { 0x01, 0x14, 0x14, 0x38, 0x0F, 0x02, 0x00, 0x00 },
+ { 0x01, 0x04, 0x14, 0x9C, 0x0F, 0x02, 0x00, 0x00 },
+ { 0x01, 0x19, 0x26, 0x64, 0x0F, 0x02, 0x00, 0x00 },
+ { 0x01, 0x14, 0x14, 0x58, 0x0F, 0x02, 0x00, 0x00 },
+ { 0x02, 0x06, 0x23, 0x78, 0x0F, 0x02, 0x00, 0x00 },
+ { 0x09, 0x14, 0x16, 0x38, 0x0F, 0x02, 0x00, 0x00 },
+ { 0x01, 0x96, 0x26, 0x31, 0x0F, 0x00, 0x00, 0x00 },
+ { 0x01, 0x08, 0x26, 0x80, 0x0C, 0x0F, 0x00, 0x00 },
+ { 0x01, 0x10, 0x26, 0x14, 0x00, 0x0F, 0x06, 0x00 },
+ { 0x00, 0x10, 0x10, 0x0C, 0x00, 0x0F, 0x06, 0x00 },
+ { 0x00, 0x10, 0x17, 0x00, 0x00, 0x0F, 0x06, 0x00 },
+ { 0x00, 0x10, 0x10, 0x00, 0x00, 0x0F, 0x06, 0x00 },
+ { 0x00, 0x10, 0x07, 0x04, 0x00, 0x0F, 0x06, 0x00 },
+ { 0x00, 0x00, 0x11, 0x05, 0x00, 0x0F, 0x06, 0x00 },
+ { 0x00, 0x00, 0x15, 0x05, 0x00, 0x0F, 0x06, 0x00 },
+ { 0x00, 0x00, 0x11, 0x08, 0x00, 0x0F, 0x06, 0x00 },
+ { 0x00, 0x00, 0x15, 0x03, 0x00, 0x0F, 0x06, 0x00 },
+ { 0x0A, 0xA8, 0x15, 0x18, 0x0F, 0x0C, 0x00, 0x00 }
+};
+
+const int Screen_EoB::_screenDimTableCount = ARRAYSIZE(Screen_EoB::_screenDimTable);
+
+const uint8 EoBCoreEngine::_hpIncrPerLevel[] = { 10, 4, 8, 6, 10, 10, 9, 10, 9, 10, 9, 9, 3, 1, 2, 2, 3, 3 };
+
+const uint8 EoBCoreEngine::_numLevelsPerClass[] = { 1, 1, 1, 1, 1, 1, 2, 2, 2, 3, 2, 2, 3, 2, 2 };
+
+const int8 EoBCoreEngine::_characterClassType[] = {
+ 0, -1, -1, 5, -1, -1, 4, -1, -1, 1, -1, -1, 2, -1, -1, 3, -1, -1, 0,
+ 2, -1, 0, 3, -1, 0, 1, -1, 0, 1, 3, 3, 1, -1, 2, 3, -1, 0, 2, 1, 5,
+ 2, -1, 2, 1, -1
+};
+
+const int16 EoBCoreEngine::_hpConstModifiers[] = { -1, -3, -2, -2, -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 6, 6, 7, 7 };
+
+const uint8 EoBCoreEngine::_charClassModifier[] = {
+ 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x00, 0x00, 0x00, 0x00, 0x03, 0x02,
+ 0x00, 0x00, 0x02
+};
+
+const uint8 EoBCoreEngine::_itemsOverlayCGA[] = {
+ 0x00, 0x55, 0x55, 0xFF
+};
+
+const uint8 EoBCoreEngine::_teleporterShapeDefs[] = {
+ 0x0C, 0x58, 0x02, 0x0E,
+ 0x0C, 0x67, 0x01, 0x07,
+ 0x0C, 0x6F, 0x01, 0x07,
+ 0x0C, 0x77, 0x01, 0x05,
+ 0x0C, 0x7D, 0x01, 0x05,
+ 0x0C, 0x83, 0x01, 0x03
+};
+
+const uint8 EoBCoreEngine::_wallOfForceShapeDefs[] = {
+ 0x00, 0x00, 0x04, 0x08,
+ 0x00, 0x08, 0x04, 0x08,
+ 0x04, 0x00, 0x04, 0x08,
+ 0x04, 0x08, 0x04, 0x08,
+ 0x08, 0x00, 0x05, 0x10,
+ 0x0C, 0x00, 0x05, 0x10
+};
+
+const int16 EoBCoreEngine::_buttonList1[] = {
+ 58, 0, 1, 2, 3, 90, 91, 4, 5, 6, 7, 8, 9, 10, 11, 12, 78, 79, 13, 14, 15, 16,
+ 80, 81, 17, 18, 19, 20, 82, 83, 49, 50, 51, 52, 53, 54, 56, 57, -1
+};
+
+const int16 EoBCoreEngine::_buttonList2[] = {
+ 58, 61, 62, 63, 64, 65, 93, 94, 66, 67, 68, 69, 70, 71, 76, 77, 88, 0, 1, 2, 3,
+ 90, 91, 4, 5, 6, 7, 8, 9, 10, 11, 12, 78, 79, 13, 14, 15, 16, 80, 81, 17, 18,
+ 19, 20, 82, 83, 49, 50, 51, 52, 53, 54, 56, 57, -1
+};
+
+const int16 EoBCoreEngine::_buttonList3[] = {
+ 58, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
+ 40, 41, 42, 43, 44, 45, 84, 85, 46, 47, 48, 60, 59, 92, 4, 5, 6, 7, 8, 49, 50,
+ 51, 52, 53, 54, 56, 57, -1
+};
+
+const int16 EoBCoreEngine::_buttonList4[] = {
+ 58, 47, 48, 60, 59, 92, 4, 5, 6, 7, 8, 49, 50, 51, 52, 53, 54, 56, 57, -1
+};
+
+const int16 EoBCoreEngine::_buttonList5[] = {
+ 58, 61, 62, 63, 64, 65, 93, 66, 67, 68, 69, 70, 71, 88, 21, 22, 23, 24, 25, 26,
+ 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 84,
+ 85, 46, 47, 48, 60, 59, 92, 4, 5, 6, 7, 8, 49, 50, 51, 52, 53, 54, 56, 57, -1
+};
+
+const int16 EoBCoreEngine::_buttonList6[] = {
+ 58, 61, 62, 63, 64, 65, 93, 66, 67, 68, 69, 70, 71, 88, 46, 47, 48, 60, 59, 92,
+ 4, 5, 6, 7, 8, 49, 50, 51, 52, 53, 54, 56, 57, -1
+};
+
+const int16 EoBCoreEngine::_buttonList7[] = {
+ 17, 18, 19, 20, 82, 83, 55, -1
+};
+
+const int16 EoBCoreEngine::_buttonList8[] = {
+ 72, 73, 74, 75, 86, 87, 89, -1
+};
+
+const uint8 EoBCoreEngine::_clock2Timers[] = {
+ 0x00, 0x01, 0x20, 0x21, 0x22, 0x22,
+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
+ 0x04, 0x05, 0x06, 0x07
+};
+
+const uint8 EoBCoreEngine::_numClock2Timers = ARRAYSIZE(EoBCoreEngine::_clock2Timers);
+
+void EoBCoreEngine::initStaticResource() {
+ int temp;
+ _chargenStatStrings = _staticres->loadStrings(kEoBBaseChargenStatStrings, temp);
+ _chargenRaceSexStrings = _staticres->loadStrings(kEoBBaseChargenRaceSexStrings, temp);
+ _chargenClassStrings = _staticres->loadStrings(kEoBBaseChargenClassStrings, temp);
+ _chargenAlignmentStrings = _staticres->loadStrings(kEoBBaseChargenAlignmentStrings, temp);
+
+ _pryDoorStrings = _staticres->loadStrings(kEoBBasePryDoorStrings, temp);
+ _warningStrings = _staticres->loadStrings(kEoBBaseWarningStrings, temp);
+
+ _suffixStringsRings = _staticres->loadStrings(kEoBBaseItemSuffixStringsRings, temp);
+ _suffixStringsPotions = _staticres->loadStrings(kEoBBaseItemSuffixStringsPotions, temp);
+ _suffixStringsWands = _staticres->loadStrings(kEoBBaseItemSuffixStringsWands, temp);
+
+ _ripItemStrings = _staticres->loadStrings(kEoBBaseRipItemStrings, temp);
+ _cursedString = _staticres->loadStrings(kEoBBaseCursedString, temp);
+ _enchantedString = _staticres->loadStrings(kEoBBaseEnchantedString, temp);
+ _magicObjectStrings = _staticres->loadStrings(kEoBBaseMagicObjectStrings, temp);
+ _magicObjectString5 = _staticres->loadStrings(kEoBBaseMagicObjectString5, temp);
+ _patternSuffix = _staticres->loadStrings(kEoBBasePatternSuffix, temp);
+ _patternGrFix1 = _staticres->loadStrings(kEoBBasePatternGrFix1, temp);
+ _patternGrFix2 = _staticres->loadStrings(kEoBBasePatternGrFix2, temp);
+ _validateArmorString = _staticres->loadStrings(kEoBBaseValidateArmorString, temp);
+ _validateCursedString = _staticres->loadStrings(kEoBBaseValidateCursedString, temp);
+ _validateNoDropString = _staticres->loadStrings(kEoBBaseValidateNoDropString, temp);
+ _potionStrings = _staticres->loadStrings(kEoBBasePotionStrings, temp);
+ _wandStrings = _staticres->loadStrings(kEoBBaseWandStrings, temp);
+ _itemMisuseStrings = _staticres->loadStrings(kEoBBaseItemMisuseStrings, temp);
+
+ _takenStrings = _staticres->loadStrings(kEoBBaseTakenStrings, temp);
+ _potionEffectStrings = _staticres->loadStrings(kEoBBasePotionEffectStrings, temp);
+
+ _yesNoStrings = _staticres->loadStrings(kEoBBaseYesNoStrings, temp);
+ _npcMaxStrings = _staticres->loadStrings(kEoBBaseNpcMaxStrings, temp);
+ _okStrings = _staticres->loadStrings(_flags.gameID == GI_EOB2 ? kEoBBaseOkStrings : kRpgCommonMoreStrings, temp);
+ _npcJoinStrings = _staticres->loadStrings(kEoBBaseNpcJoinStrings, temp);
+ _cancelStrings = _staticres->loadStrings(kEoBBaseCancelStrings, temp);
+ _abortStrings = _staticres->loadStrings(_flags.gameID == GI_EOB2 ? kEoBBaseAbortStrings : kEoBBaseCancelStrings, temp);
+
+ _menuStringsMain = _staticres->loadStrings(kEoBBaseMenuStringsMain, temp);
+ _menuStringsSaveLoad = _staticres->loadStrings(kEoBBaseMenuStringsSaveLoad, temp);
+ _menuStringsOnOff = _staticres->loadStrings(kEoBBaseMenuStringsOnOff, temp);
+ _menuStringsSpells = _staticres->loadStrings(kEoBBaseMenuStringsSpells, temp);
+ _menuStringsRest = _staticres->loadStrings(kEoBBaseMenuStringsRest, temp);
+ _menuStringsDrop = _staticres->loadStrings(kEoBBaseMenuStringsDrop, temp);
+ _menuStringsExit = _staticres->loadStrings(kEoBBaseMenuStringsExit, temp);
+ _menuStringsStarve = _staticres->loadStrings(kEoBBaseMenuStringsStarve, temp);
+ _menuStringsScribe = _staticres->loadStrings(kEoBBaseMenuStringsScribe, temp);
+ _menuStringsDrop2 = _staticres->loadStrings(kEoBBaseMenuStringsDrop2, temp);
+ _menuStringsHead = _staticres->loadStrings(kEoBBaseMenuStringsHead, temp);
+ _menuStringsPoison = _staticres->loadStrings(kEoBBaseMenuStringsPoison, temp);
+ _menuStringsMgc = _staticres->loadStrings(kEoBBaseMenuStringsMgc, temp);
+ _menuStringsPrefs = _staticres->loadStrings(kEoBBaseMenuStringsPrefs, temp);
+ _menuStringsRest2 = _staticres->loadStrings(kEoBBaseMenuStringsRest2, temp);
+ _menuStringsRest3 = _staticres->loadStrings(kEoBBaseMenuStringsRest3, temp);
+ _menuStringsRest4 = _staticres->loadStrings(kEoBBaseMenuStringsRest4, temp);
+ _menuStringsDefeat = _staticres->loadStrings(kEoBBaseMenuStringsDefeat, temp);
+ _menuStringsTransfer = _staticres->loadStrings(kEoBBaseMenuStringsTransfer, temp);
+ _menuStringsSpec = _staticres->loadStrings(kEoBBaseMenuStringsSpec, temp);
+ _menuStringsSpellNo = _staticres->loadStrings(kEoBBaseMenuStringsSpellNo, temp);
+ _menuYesNoStrings = _staticres->loadStrings(kEoBBaseMenuYesNoStrings, temp);
+
+ _spellLevelsMage = _staticres->loadRawData(kEoBBaseSpellLevelsMage, _spellLevelsMageSize);
+ _spellLevelsCleric = _staticres->loadRawData(kEoBBaseSpellLevelsCleric, _spellLevelsClericSize);
+ _numSpellsCleric = _staticres->loadRawData(kEoBBaseNumSpellsCleric, temp);
+ _numSpellsWisAdj = _staticres->loadRawData(kEoBBaseNumSpellsWisAdj, temp);
+ _numSpellsPal = _staticres->loadRawData(kEoBBaseNumSpellsPal, temp);
+ _numSpellsMage = _staticres->loadRawData(kEoBBaseNumSpellsMage, temp);
+
+ _characterGuiStringsHp = _staticres->loadStrings(kEoBBaseCharGuiStringsHp, temp);
+ _characterGuiStringsWp = _staticres->loadStrings(_flags.gameID == GI_EOB2 ? kEoBBaseCharGuiStringsWp2 : kEoBBaseCharGuiStringsWp1, temp);
+ _characterGuiStringsWr = _staticres->loadStrings(kEoBBaseCharGuiStringsWr, temp);
+ _characterGuiStringsSt = _staticres->loadStrings(_flags.gameID == GI_EOB2 ? kEoBBaseCharGuiStringsSt2 : kEoBBaseCharGuiStringsSt1, temp);
+ _characterGuiStringsIn = _staticres->loadStrings(kEoBBaseCharGuiStringsIn, temp);
+
+ _characterStatusStrings7 = _staticres->loadStrings(kEoBBaseCharStatusStrings7, temp);
+ _characterStatusStrings8 = _staticres->loadStrings(_flags.gameID == GI_EOB2 ? kEoBBaseCharStatusStrings82 : kEoBBaseCharStatusStrings81, temp);
+ _characterStatusStrings9 = _staticres->loadStrings(kEoBBaseCharStatusStrings9, temp);
+ _characterStatusStrings12 = _staticres->loadStrings(kEoBBaseCharStatusStrings12, temp);
+ _characterStatusStrings13 = _staticres->loadStrings(_flags.gameID == GI_EOB2 ? kEoBBaseCharStatusStrings132 : kEoBBaseCharStatusStrings131, temp);
+
+ _levelGainStrings = _staticres->loadStrings(kEoBBaseLevelGainStrings, temp);
+ for (int i = 0; i < 5; i++)
+ _expRequirementTables[i] = _staticres->loadRawDataBe32(kEoBBaseExperienceTable0 + i, temp);
+ _expRequirementTables[5] = _staticres->loadRawDataBe32(kEoBBaseExperienceTable4, temp);
+
+ _classModifierFlags = _staticres->loadRawData(kEoBBaseClassModifierFlags, temp);
+
+ _saveThrowTables[0] = _saveThrowTables[4] = _saveThrowTables[5] = _staticres->loadRawData(kEoBBaseSaveThrowTable1, temp);
+ _saveThrowTables[1] = _staticres->loadRawData(kEoBBaseSaveThrowTable2, temp);
+ _saveThrowTables[2] = _staticres->loadRawData(kEoBBaseSaveThrowTable3, temp);
+ _saveThrowTables[3] = _staticres->loadRawData(kEoBBaseSaveThrowTable4, temp);
+ _saveThrowLevelIndex = _staticres->loadRawData(kEoBBaseSaveThrwLvlIndex, temp);
+ _saveThrowModDiv = _staticres->loadRawData(kEoBBaseSaveThrwModDiv, temp);
+ _saveThrowModExt = _staticres->loadRawData(kEoBBaseSaveThrwModExt, temp);
+
+ _encodeMonsterShpTable = _staticres->loadRawDataBe16(kEoBBaseEncodeMonsterDefs, temp);
+ _npcPreset = _staticres->loadEoBNpcData(kEoBBaseNpcPresets, temp);
+
+ _teleporterShapeCoords = _staticres->loadRawData(kEoBBaseDscTelptrShpCoords, temp);
+ _portalSeq = (const int8 *)_staticres->loadRawData(kEoBBasePortalSeqData, temp);
+ _mnDef = _staticres->loadRawData(kEoBBaseManDef, temp);
+ _mnWord = _staticres->loadStrings(kEoBBaseManWord, _mnNumWord);
+ _mnPrompt = _staticres->loadStrings(kEoBBaseManPrompt, temp);
+
+ _monsterStepTable0 = (const int8 *)_staticres->loadRawData(_flags.gameID == GI_EOB2 ? kEoBBaseMonsterStepTable02 : kEoBBaseMonsterStepTable01, temp);
+ _monsterStepTable1 = (const int8 *)_staticres->loadRawData(kEoBBaseMonsterStepTable1, temp);
+ _monsterStepTable2 = (const int8 *)_staticres->loadRawData(kEoBBaseMonsterStepTable2, temp);
+ _monsterStepTable3 = (const int8 *)_staticres->loadRawData(kEoBBaseMonsterStepTable3, temp);
+ _monsterCloseAttPosTable1 = _staticres->loadRawData(kEoBBaseMonsterCloseAttPosTable1, temp);
+ _monsterCloseAttPosTable2 = _staticres->loadRawData(_flags.gameID == GI_EOB2 ? kEoBBaseMonsterCloseAttPosTable22 : kEoBBaseMonsterCloseAttPosTable21, temp);
+ _monsterCloseAttUnkTable = (const int8 *)_staticres->loadRawData(kEoBBaseMonsterCloseAttUnkTable, temp);
+ _monsterCloseAttChkTable1 = _staticres->loadRawData(kEoBBaseMonsterCloseAttChkTable1, temp);
+ _monsterCloseAttChkTable2 = _staticres->loadRawData(kEoBBaseMonsterCloseAttChkTable2, temp);
+ _monsterCloseAttDstTable1 = _staticres->loadRawData(kEoBBaseMonsterCloseAttDstTable1, temp);
+ _monsterCloseAttDstTable2 = _staticres->loadRawData(kEoBBaseMonsterCloseAttDstTable2, temp);
+
+ _monsterProximityTable = _staticres->loadRawData(kEoBBaseMonsterProximityTable, temp);
+ _findBlockMonstersTable = _staticres->loadRawData(kEoBBaseFindBlockMonstersTable, temp);
+ _monsterDirChangeTable = (const int8 *)_staticres->loadRawData(kEoBBaseMonsterDirChangeTable, temp);
+ _monsterSpecAttStrings = _staticres->loadStrings(kEoBBaseMonsterDistAttStrings, temp);
+
+ _monsterFrmOffsTable1 = (const int8 *)_staticres->loadRawData(kEoBBaseDscMonsterFrmOffsTbl1, temp);
+ _monsterFrmOffsTable2 = (const int8 *)_staticres->loadRawData(kEoBBaseDscMonsterFrmOffsTbl2, temp);
+
+ _inventorySlotsX = _staticres->loadRawDataBe16(kEoBBaseInvSlotX, temp);
+ _inventorySlotsY = _staticres->loadRawData(kEoBBaseInvSlotY, temp);
+ _slotValidationFlags = _staticres->loadRawDataBe16(kEoBBaseSlotValidationFlags, temp);
+
+ _projectileWeaponAmmoTypes = (const int8 *)_staticres->loadRawData(kEoBBaseProjectileWeaponTypes, temp);
+ _wandTypes = _staticres->loadRawData(kEoBBaseWandTypes, temp);
+
+ _drawObjPosIndex = _staticres->loadRawData(kEoBBaseDrawObjPosIndex, temp);
+ _flightObjFlipIndex = _staticres->loadRawData(kEoBBaseFlightObjFlipIndex, temp);
+ _flightObjShpMap = (const int8 *)_staticres->loadRawData(kEoBBaseFlightObjShpMap, temp);
+ _flightObjSclIndex = (const int8 *)_staticres->loadRawData(kEoBBaseFlightObjSclIndex, temp);
+
+ _wllFlagPreset = _staticres->loadRawData(kEoBBaseWllFlagPreset, _wllFlagPresetSize);
+ _dscShapeCoords = (const int16 *)_staticres->loadRawDataBe16(kEoBBaseDscShapeCoords, temp);
+
+ _dscDoorScaleOffs = _staticres->loadRawData(kEoBBaseDscDoorScaleOffs, temp);
+ _dscDoorScaleMult1 = _staticres->loadRawData(kEoBBaseDscDoorScaleMult1, temp);
+ _dscDoorScaleMult2 = _staticres->loadRawData(kEoBBaseDscDoorScaleMult2, temp);
+ _dscDoorScaleMult3 = _staticres->loadRawData(kEoBBaseDscDoorScaleMult3, temp);
+ _dscDoorY1 = _staticres->loadRawData(kEoBBaseDscDoorY1, temp);
+ _dscDoorXE = _staticres->loadRawData(kEoBBaseDscDoorXE, temp);
+
+ _dscItemPosIndex = _staticres->loadRawData(kEoBBaseDscItemPosIndex, temp);
+ _dscItemShpX = (const int16 *)_staticres->loadRawDataBe16(kEoBBaseDscItemShpX, temp);
+ _dscItemScaleIndex = _staticres->loadRawData(kEoBBaseDscItemScaleIndex, temp);
+ _dscItemTileIndex = _staticres->loadRawData(kEoBBaseDscItemTileIndex, temp);
+ _dscItemShapeMap = _staticres->loadRawData(kEoBBaseDscItemShapeMap, temp);
+
+ _bookNumbers = _staticres->loadStrings(kEoBBaseBookNumbers, temp);
+ _mageSpellList = _staticres->loadStrings(kEoBBaseMageSpellsList, _mageSpellListSize);
+ _clericSpellList = _staticres->loadStrings(kEoBBaseClericSpellsList, temp);
+ _spellNames = _staticres->loadStrings(kEoBBaseSpellNames, temp);
+
+ _magicStrings1 = _staticres->loadStrings(kEoBBaseMagicStrings1, temp);
+ _magicStrings2 = _staticres->loadStrings(kEoBBaseMagicStrings2, temp);
+ _magicStrings3 = _staticres->loadStrings(kEoBBaseMagicStrings3, temp);
+ _magicStrings4 = _staticres->loadStrings(kEoBBaseMagicStrings4, temp);
+ _magicStrings6 = _staticres->loadStrings(kEoBBaseMagicStrings6, temp);
+ _magicStrings7 = _staticres->loadStrings(kEoBBaseMagicStrings7, temp);
+ _magicStrings8 = _staticres->loadStrings(kEoBBaseMagicStrings8, temp);
+
+ _expObjectTlMode = _staticres->loadRawData(kEoBBaseExpObjectTlMode, temp);
+ _expObjectTblIndex = _staticres->loadRawData(kEoBBaseExpObjectTblIndex, temp);
+ _expObjectShpStart = _staticres->loadRawData(kEoBBaseExpObjectShpStart, temp);
+ _expObjectAnimTbl1 = _staticres->loadRawData(kEoBBaseExpObjectTbl1, _expObjectAnimTbl1Size);
+ _expObjectAnimTbl2 = _staticres->loadRawData(kEoBBaseExpObjectTbl2, _expObjectAnimTbl2Size);
+ _expObjectAnimTbl3 = _staticres->loadRawData(kEoBBaseExpObjectTbl3, _expObjectAnimTbl3Size);
+
+ _sparkEffectDefSteps = _staticres->loadRawData(kEoBBaseSparkDefSteps, temp);
+ _sparkEffectDefSubSteps = _staticres->loadRawData(kEoBBaseSparkDefSubSteps, temp);
+ _sparkEffectDefShift = _staticres->loadRawData(kEoBBaseSparkDefShift, temp);
+ _sparkEffectDefAdd = _staticres->loadRawData(kEoBBaseSparkDefAdd, temp);
+ _sparkEffectDefX = _staticres->loadRawData(kEoBBaseSparkDefX, temp);
+ _sparkEffectDefY = _staticres->loadRawData(kEoBBaseSparkDefY, temp);
+ _sparkEffectOfFlags1 = _staticres->loadRawDataBe32(kEoBBaseSparkOfFlags1, temp);
+ _sparkEffectOfFlags2 = _staticres->loadRawDataBe32(kEoBBaseSparkOfFlags2, temp);
+ _sparkEffectOfShift = _staticres->loadRawData(kEoBBaseSparkOfShift, temp);
+ _sparkEffectOfX = _staticres->loadRawData(kEoBBaseSparkOfX, temp);
+ _sparkEffectOfY = _staticres->loadRawData(kEoBBaseSparkOfY, temp);
+ _magicFlightObjectProperties = _staticres->loadRawData(kEoBBaseMagicFlightProps, temp);
+ _turnUndeadEffect = _staticres->loadRawData(kEoBBaseTurnUndeadEffect, temp);
+ _burningHandsDest = _staticres->loadRawData(kEoBBaseBurningHandsDest, temp);
+ _coneOfColdDest1 = (const int8 *)_staticres->loadRawData(kEoBBaseConeOfColdDest1, temp);
+ _coneOfColdDest2 = (const int8 *)_staticres->loadRawData(kEoBBaseConeOfColdDest2, temp);
+ _coneOfColdDest3 = (const int8 *)_staticres->loadRawData(kEoBBaseConeOfColdDest3, temp);
+ _coneOfColdDest4 = (const int8 *)_staticres->loadRawData(kEoBBaseConeOfColdDest4, temp);
+ _coneOfColdGfxTbl = _staticres->loadRawData(kEoBBaseConeOfColdGfxTbl, _coneOfColdGfxTblSize);
+
+ // Hard code the following strings, since EOB I doesn't have them in the original.
+ // EOB I doesn't have load and save menus, because there is only one single
+ // save slot. Instead of emulating this we provide a menu similiar to EOB II.
+
+ static const char *saveLoadStrings[3][4] = {
+ { "Cancel", "Empty Slot", "Save Game", "Load Game" },
+ { "Abbr.", "Leerer Slot", "Speichern", " Laden" },
+ { 0, 0, 0, 0 }
+ };
+
+ static const char *errorSlotEmptyString[3] = {
+ "There is no game\rsaved in that slot!",
+ "Hier ist noch kein\rSpiel gespeichert!",
+ 0
+ };
+
+ _saveLoadStrings = saveLoadStrings[(_flags.lang == Common::EN_ANY) ? 0 : ((_flags.lang == Common::DE_DEU) ? 1 : 2)];
+ _errorSlotEmptyString = errorSlotEmptyString[(_flags.lang == Common::EN_ANY) ? 0 : ((_flags.lang == Common::DE_DEU) ? 1 : 2)];
+ _menuOkString = "OK";
+}
+
+void EoBCoreEngine::initButtonData() {
+ static const EoBGuiButtonDef buttonDefs[] = {
+ { 112, 0, 0x1100, 184, 2, 63, 50, 0 },
+ { 113, 0, 0x1100, 256, 2, 63, 50, 1 },
+ { 114, 0, 0x1100, 184, 54, 63, 50, 2 },
+ { 115, 0, 0x1100, 256, 54, 63, 50, 3 },
+ { 48, 110, 0x1100, 289, 177, 31, 21, 0 },
+ { 0, 0, 0x1100, 0, 102, 88, 18, 0 },
+ { 0, 0, 0x1100, 89, 102, 88, 18, 1 },
+ { 0, 0, 0x1100, 0, 72, 88, 29, 2 },
+ { 0, 0, 0x1100, 89, 72, 88, 29, 3 },
+ { 24, 0, 0x1100, 184, 10, 33, 33, 0 },
+ { 0, 0, 0x1100, 256, 10, 33, 33, 1 },
+ { 0, 0, 0x1100, 184, 62, 33, 33, 2 },
+ { 0, 0, 0x1100, 256, 62, 33, 33, 3 },
+ { 0, 0, 0x1100, 216, 10, 31, 33, 0 },
+ { 0, 0, 0x1100, 288, 10, 31, 33, 1 },
+ { 0, 0, 0x1100, 216, 62, 31, 33, 2 },
+ { 0, 0, 0x1100, 288, 62, 31, 33, 3 },
+ { 368, 0, 0x1000, 184, 2, 63, 8, 0 },
+ { 369, 0, 0x1000, 256, 2, 63, 8, 1 },
+ { 370, 0, 0x1000, 184, 54, 63, 8, 2 },
+ { 371, 0, 0x1000, 256, 54, 63, 8, 3 },
+ { 0, 0, 0x1100, 230, 116, 16, 16, 0 },
+ { 0, 0, 0x1100, 278, 116, 16, 16, 1 },
+ { 0, 0, 0x1100, 181, 40, 16, 16, 2 },
+ { 0, 0, 0x1100, 199, 40, 16, 16, 3 },
+ { 0, 0, 0x1100, 181, 58, 16, 16, 4 },
+ { 0, 0, 0x1100, 199, 58, 16, 16, 5 },
+ { 0, 0, 0x1100, 181, 76, 16, 16, 6 },
+ { 0, 0, 0x1100, 199, 76, 16, 16, 7 },
+ { 0, 0, 0x1100, 181, 94, 16, 16, 8 },
+ { 0, 0, 0x1100, 199, 94, 16, 16, 9 },
+ { 0, 0, 0x1100, 181, 112, 16, 16, 10 },
+ { 0, 0, 0x1100, 199, 112, 16, 16, 11 },
+ { 0, 0, 0x1100, 181, 130, 16, 16, 12 },
+ { 0, 0, 0x1100, 199, 130, 16, 16, 13 },
+ { 0, 0, 0x1100, 181, 148, 16, 16, 14 },
+ { 0, 0, 0x1100, 199, 148, 16, 16, 15 },
+ { 0, 0, 0x1100, 225, 55, 16, 16, 16 },
+ { 0, 0, 0x1100, 224, 76, 16, 16, 17 },
+ { 0, 0, 0x1100, 225, 96, 16, 16, 18 },
+ { 0, 0, 0x1100, 298, 55, 16, 16, 19 },
+ { 0, 0, 0x1100, 287, 75, 16, 16, 20 },
+ { 0, 0, 0x1100, 277, 137, 16, 16, 21 },
+ { 0, 0, 0x1100, 300, 94, 16, 16, 22 },
+ { 0, 0, 0x1100, 300, 112, 16, 16, 23 },
+ { 0, 0, 0x1100, 300, 130, 16, 16, 24 },
+ { 0, 0, 0x1100, 236, 37, 31, 16, 25 },
+ { 26, 0, 0x1100, 291, 149, 25, 17, 25 },
+ { 110, 24, 0x1100, 181, 3, 32, 32, 25 },
+ { 96, 352, 0x1100, 24, 128, 21, 16, 25 },
+ { 98, 97, 0x1100, 24, 144, 21, 16, 25 },
+ { 92, 348, 0x1100, 3, 144, 21, 16, 25 },
+ { 102, 358, 0x1100, 45, 144, 21, 16, 25 },
+ { 91, 0, 0x1100, 3, 128, 21, 16, 25 },
+ { 101, 0, 0x1100, 45, 128, 21, 16, 25 },
+ { 110, 0, 0x1100, 184, 0, 136, 120, 0 },
+ { 0, 0, 0x1100, 0, 8, 88, 48, 0 },
+ { 0, 0, 0x1100, 88, 8, 88, 48, 1 },
+ { 0, 0, 0x1100, 24, 8, 128, 96, 1 },
+ { 112, 113, 0x1100, 274, 35, 20, 15, 1 },
+ { 114, 115, 0x1100, 297, 35, 20, 15, 1 },
+ { 2, 0, 0x1100, 68, 121, 18, 10, 0 },
+ { 3, 0, 0x1100, 86, 121, 18, 10, 1 },
+ { 4, 0, 0x1100, 104, 121, 15, 10, 2 },
+ { 5, 0, 0x1100, 122, 121, 15, 10, 3 },
+ { 6, 0, 0x1100, 140, 121, 15, 10, 4 },
+ { 0, 0, 0x1100, 75, 131, 97, 6, 0 },
+ { 0, 0, 0x1100, 75, 137, 97, 6, 1 },
+ { 0, 0, 0x1100, 75, 143, 97, 6, 2 },
+ { 0, 0, 0x1100, 75, 149, 97, 6, 3 },
+ { 0, 0, 0x1100, 75, 155, 97, 6, 4 },
+ { 0, 0, 0x1100, 75, 161, 97, 6, 5 },
+ { 112, 0, 0x1100, 184, 2, 63, 50, 0 },
+ { 113, 0, 0x1100, 256, 2, 63, 50, 1 },
+ { 114, 0, 0x1100, 184, 54, 63, 50, 2 },
+ { 115, 0, 0x1100, 256, 54, 63, 50, 3 },
+ { 53, 54, 0x1100, 320, 200, 0, 0, 6 },
+ { 61, 0, 0x1100, 320, 200, 0, 0, 7 },
+ { 0, 0, 0x1100, 184, 114, 33, 33, 4 },
+ { 0, 0, 0x1100, 256, 114, 33, 33, 5 },
+ { 0, 0, 0x1100, 216, 114, 31, 33, 4 },
+ { 0, 0, 0x1100, 288, 114, 31, 33, 5 },
+ { 372, 0, 0x1000, 184, 106, 63, 8, 4 },
+ { 373, 0, 0x1000, 256, 106, 63, 8, 5 },
+ { 0, 0, 0x1100, 227, 135, 10, 10, 25 },
+ { 0, 0, 0x1100, 239, 135, 10, 10, 26 },
+ { 116, 0, 0x1100, 184, 106, 63, 50, 4 },
+ { 117, 0, 0x1100, 256, 106, 63, 50, 5 },
+ { 110, 0, 0x1100, 68, 168, 78, 10, 0 },
+ { 110, 0, 0x1100, 68, 168, 78, 10, 65535 },
+ { 116, 0, 0x1100, 184, 106, 63, 50, 4 },
+ { 117, 0, 0x1100, 256, 106, 63, 50, 5 },
+ { 116, 117, 0x1100, 320, 200, 1, 1, 2 },
+ { 7, 0, 0x1100, 158, 121, 15, 10, 5 },
+ { 0, 0, 0x1100, 146, 168, 32, 10, 0 },
+
+ // EOB1 spellbook modifications
+ { 2, 0, 0x1100, 71, 122, 20, 8, 0 },
+ { 3, 0, 0x1100, 92, 122, 20, 8, 1 },
+ { 4, 0, 0x1100, 113, 122, 20, 8, 2 },
+ { 5, 0, 0x1100, 134, 122, 20, 8, 3 },
+ { 6, 0, 0x1100, 155, 122, 20, 8, 4 },
+ { 110, 0, 0x1100, 75, 168, 97, 6, 0 }
+ };
+
+ _buttonDefs = buttonDefs;
+ _buttonCallbacks.clear();
+ _buttonCallbacks.reserve(ARRAYSIZE(buttonDefs));
+
+#define EOB_CBN(x, y) _buttonCallbacks.push_back(BUTTON_FUNCTOR(EoBCoreEngine, this, &EoBCoreEngine::y)); for (int l = 0; l < (x - 1); l++) { _buttonCallbacks.push_back(_buttonCallbacks[_buttonCallbacks.size() - 1 - l]); }
+#define EOB_CBI(x, y) for (int l = x; l; l--) { _buttonCallbacks.push_back(_buttonCallbacks[y]); }
+ EOB_CBN(4, clickedCharPortraitDefault);
+ EOB_CBN(1, clickedCamp);
+ EOB_CBN(4, clickedSceneDropPickupItem);
+ EOB_CBN(4, clickedCharPortrait2);
+ EOB_CBN(4, clickedWeaponSlot);
+ EOB_CBN(4, clickedCharNameLabelRight);
+ EOB_CBN(25, clickedInventorySlot);
+ EOB_CBN(1, clickedEatItem);
+ EOB_CBN(1, clickedInventoryNextPage);
+ EOB_CBN(1, clickedPortraitRestore);
+ EOB_CBN(1, clickedUpArrow);
+ EOB_CBN(1, clickedDownArrow);
+ EOB_CBN(1, clickedLeftArrow);
+ EOB_CBN(1, clickedRightArrow);
+ EOB_CBN(1, clickedTurnLeftArrow);
+ EOB_CBN(1, clickedTurnRightArrow);
+ EOB_CBN(1, clickedAbortCharSwitch);
+ EOB_CBN(2, clickedSceneThrowItem);
+ EOB_CBN(1, clickedSceneSpecial);
+ EOB_CBN(1, clickedInventoryPrevChar);
+ EOB_CBN(1, clickedInventoryNextChar);
+ EOB_CBN(5, clickedSpellbookTab);
+ EOB_CBN(6, clickedSpellbookList);
+ EOB_CBN(4, clickedCastSpellOnCharacter);
+ EOB_CBI(2, 66);
+ EOB_CBI(2, 9);
+ EOB_CBI(2, 13);
+ EOB_CBI(2, 17);
+ EOB_CBI(2, 21);
+ EOB_CBI(2, 72);
+ EOB_CBN(1, clickedSpellbookAbort);
+ EOB_CBI(1, 72);
+ EOB_CBI(2, 0);
+ EOB_CBI(1, 60);
+ EOB_CBI(1, 61);
+ EOB_CBN(1, clickedSpellbookScroll);
+ EOB_CBI(5, 61);
+ EOB_CBI(1, 88);
+#undef EOB_CBI
+#undef EOB_CBN
+}
+
+void EoBCoreEngine::initMenus() {
+ static const EoBMenuButtonDef buttonDefs[] = {
+ { 2, 12, 20, 158, 14, 20, 3 },
+ { 3, 12, 37, 158, 14, 52, 3 },
+ { 4, 12, 54, 158, 14, 26, 3 },
+ { 5, 12, 71, 158, 14, 32, 3 },
+ { 6, 12, 88, 158, 14, 0, 3 },
+ { 7, 12, 105, 158, 14, 35, 3 },
+ { 8, 128, 122, 40, 14, 19, 7 },
+ { 9, 12, 20, 158, 14, 39, 3 },
+ { 10, 12, 37, 158, 14, 32, 3 },
+ { 11, 12, 54, 158, 14, 33, 3 },
+ { 12, 12, 71, 158, 14, 17, 3 },
+ { 8, 128, 122, 40, 14, 19, 7 },
+ { 18, 12, 20, 158, 14, 32, 3 },
+ { 19, 12, 37, 158, 14, 50, 3 },
+ { 8, 128, 122, 40, 14, 19, 7 },
+ { 8, 128, 122, 40, 14, 19, 5 },
+ { 0, 184, 0, 64, 48, 112, 0 },
+ { 0, 256, 0, 64, 48, 113, 0 },
+ { 0, 184, 56, 64, 48, 114, 0 },
+ { 0, 256, 56, 64, 48, 115, 0 },
+ { 0, 184, 112, 64, 48, 116, 0 },
+ { 0, 256, 112, 64, 48, 117, 0 },
+ { 36, 8, 126, 48, 14, 48, 5 },
+ { 8, 128, 126, 40, 14, 19, 5 },
+ { 0, 0, 50, 168, 72, 61, 0 },
+ { 31, 11, 16, 20, 18, 2, 5 },
+ { 32, 38, 16, 20, 18, 3, 5 },
+ { 33, 65, 16, 20, 18, 4, 5 },
+ { 34, 92, 16, 20, 18, 5, 5 },
+ { 35, 119, 16, 20, 18, 6, 5 },
+ { 60, 146, 16, 20, 18, 7, 5 },
+ { 61, 150, 16, 20, 18, 8, 5 },
+ { 38, 16, 57, 32, 14, 22, 7 },
+ { 39, 128, 57, 32, 14, 51, 7 },
+ { 8, 128, 126, 40, 14, 19, 7 },
+ { 0, 0, 50, 168, 72, 61, 0 },
+ // EOB 1 memorize/pray menu:
+ { 36, 8, 126, 48, 14, 48, 5 },
+ { 8, 128, 126, 40, 14, 19, 5 },
+ { 0, 0, 50, 168, 72, 61, 0 },
+ { 31, 8, 16, 24, 20, 2, 5 },
+ { 32, 40, 16, 24, 20, 3, 5 },
+ { 33, 72, 16, 24, 20, 4, 5 },
+ { 34, 104, 16, 24, 20, 5, 5 },
+ { 35, 136, 16, 24, 20, 6, 5 }
+ };
+
+ _menuButtonDefs = buttonDefs;
+
+ static const EoBMenuDef menuDefs[] = {
+ { 1, 10, 0, 7, 9 },
+ { 1, 10, 7, 5, 9 },
+ { 1, 10, 12, 3, 9 },
+ { 0, 10, 15, 7, 15 },
+ { 37, 10, 22, 9, 9 },
+ { 0, 11, 32, 2, 15 },
+ { 48, 10, 34, 2, 9 }
+ };
+
+ delete[] _menuDefs;
+ _menuDefs = new EoBMenuDef[ARRAYSIZE(menuDefs)];
+ memcpy(_menuDefs, menuDefs, sizeof(menuDefs));
+
+ if (_flags.gameID == GI_EOB1) {
+ // assign EOB 1 style memorize/pray menu
+ _menuDefs[4].numButtons = 8;
+ _menuDefs[4].firstButtonStrId = 36;
+ }
+}
+
+
+void EoBCoreEngine::initSpells() {
+#define mpn magicTimingParaAssign.push_back(0);
+#define mp1n if (_flags.gameID == GI_EOB1) magicTimingParaAssign.push_back(0);
+#define mp2n if (_flags.gameID == GI_EOB2) magicTimingParaAssign.push_back(0);
+#define mp(x) magicTimingParaAssign.push_back(&magicTimingPara[x << 2]);
+#define mp1(x) if (_flags.gameID == GI_EOB1) magicTimingParaAssign.push_back(&magicTimingPara[x << 2]);
+#define mp2(x) if (_flags.gameID == GI_EOB2) magicTimingParaAssign.push_back(&magicTimingPara[x << 2]);
+
+#define sc(x) startCallback.push_back(&EoBCoreEngine::spellCallback_start_##x);
+#define sc1(x) if (_flags.gameID == GI_EOB1) startCallback.push_back(&EoBCoreEngine::spellCallback_start_##x);
+#define sc2(x) if (_flags.gameID == GI_EOB2) startCallback.push_back(&EoBCoreEngine::spellCallback_start_##x);
+#define ec(x) endCallback.push_back(&EoBCoreEngine::spellCallback_end_##x);
+#define ec1(x) if (_flags.gameID == GI_EOB1) endCallback.push_back(&EoBCoreEngine::spellCallback_end_##x);
+#define ec2(x) if (_flags.gameID == GI_EOB2) endCallback.push_back(&EoBCoreEngine::spellCallback_end_##x);
+
+ static const uint16 magicTimingPara[] = {
+ 0, 546, 2, 1, // 0 detect magic
+ 0, 546, 5, 1, // 1 shield, detect invis, magical vestment
+ 0, 546, 1, 1, // 2 shocking grasp, vamp touch, true seeing, prayer
+ 3, 546, 1, 1, // 3 blur, haste
+ 5, 546, 1, 1, // 4 imp invisibility
+ 6, 546, 0, 1, // 5 bless
+ 0, 546, 3, 1, // 6 prot from evil
+ 1, 546, 1, 1, // 7 aid
+ 4, 546, 1, 1, // 8 flame blade
+ 0, 32760, 1, 1, // 9 slow poison
+ 1, 546, 0, 1, // 10 mystic defense
+ };
+
+ Common::Array<const uint16 *> magicTimingParaAssign;
+ mpn;
+ mpn;
+ mpn;
+ mp(0); // Detect Magic
+ mpn; // Magic Missile
+ mp1n;
+ mp(1); // Shield
+ mp(2); // Shocking Grasp
+ mp2(3); // Blur
+ mp2(1); // Detect Invis
+ mp2n; // Imp Identify
+ mpn; // Invis
+ mp1n;
+ mpn; // Melf
+ mp1n; // Stinking Cloud
+ mpn; // Dispel Magic
+ mpn; // Fireball
+ mp1n; // Flame Arrow
+ mp(3); // Haste
+ mpn; // Hold Person
+ mpn; // Invisibility
+ mpn; // Lightning Bolt
+ mp(2); // Vampiric Touch
+ mpn; // Fear
+ mpn; // Ice Storm
+ mp1n; // Stone Skin
+ mp1n; // Cloud Kill
+ mp2(4); // Improved Invisibility
+ mp2n; // remove Curse
+ mpn; // Cone of Cold
+ mpn; // Hold Monster
+ mp2n; // Wall of Force
+ mp2n; // Disintegrate
+ mp2n; // Flesh To Stone
+ mp2n; // Stone To Flesh
+ mp2(2); // True Seeing
+ mp2n; // Finger of Death
+ mp2n; // Power Word Stun
+ mp2n; // Bigby's Fist
+ mp2n; // empty
+ mp(5); // Bless
+ mpn; // EOB1: cure, EOB2: cause
+ mpn; // EOB1: cause, EOB2: cure
+ mp(0); // Detect Magic
+ mp(6); // Prot from Evil
+ mp(7); // Aid
+ mp(8); // Flame Blad
+ mpn; // Hold Person
+ mp(9); // Slow Poison
+ mpn; // Create Food
+ mpn; // Dispel Magic
+ mp(1); // Magical Vestment
+ mp(2); // Prayer
+ mpn; // Remove Paralysis
+ mpn; // EOB1: cure, EOB2: cause
+ mpn; // EOB1: cause, EOB2: cure
+ mpn; // Neutral Poison
+ mp(6); // Prot From Evil 10'
+ mp1n; // Prot From Lightning
+ mpn; // EOB1: cure, EOB2: cause
+ mpn; // EOB1: cause, EOB2: cure
+ mpn; // Flame Strike
+ mpn; // Raise Dead
+ mp2n; // Slay Living
+ mp2(2); // True Seeing
+ mp2n; // Harm
+ mp2n; // Heal
+ mp2n; // Resurrect
+ mpn; // Lay on Hands
+ mp2n; // Turn Undead
+ mpn; // Lightning Bolt (EOB1) / Fireball 1(EOB2) passive
+ mp2(10);// Mystic Defense
+ mp2n; // Fireball 2 passive
+ mpn; // death spell passive
+ mpn; // disintegrate passive
+ mp2n; // cause critical passive
+ mp2n; // flesh to stone passive
+
+ Common::Array<SpellStartCallback> startCallback;
+ sc(empty);
+ sc(armor);
+ sc(burningHands);
+ sc(detectMagic);
+ sc(magicMissile);
+ sc1(empty);
+ sc(empty);
+ sc(shockingGrasp);
+ sc(empty);
+ sc2(empty);
+ sc2(improvedIdentify);
+ sc(empty);
+ sc(melfsAcidArrow);
+ sc1(empty); // Stinking Cloud
+ sc(dispelMagic);
+ sc(fireball);
+ sc1(flameArrow);
+ sc(empty);
+ sc(holdPerson);
+ sc(empty);
+ sc(lightningBolt);
+ sc(vampiricTouch);
+ sc(fear);
+ sc(iceStorm);
+ sc1(stoneSkin); // stone skin
+ sc2(empty); // imp invisibility
+ sc1(empty); // Cloudkill
+ sc2(removeCurse);
+ sc(coneOfCold);
+ sc(holdMonster);
+ sc2(wallOfForce);
+ sc2(disintegrate);
+ sc2(fleshToStone);
+ sc2(stoneToFlesh);
+ sc2(trueSeeing);
+ sc2(slayLiving);
+ sc2(powerWordStun);
+ sc2(empty);
+ sc2(empty);
+ sc(empty); // Bless
+ sc2(causeLightWounds);
+ sc(cureLightWounds);
+ sc1(causeLightWounds);
+ sc(detectMagic);
+ sc(empty);
+ sc(aid);
+ sc(flameBlade);
+ sc(holdPerson);
+ sc(slowPoison);
+ sc(createFood);
+ sc(dispelMagic);
+ sc(empty);
+ sc(empty);
+ sc(removeParalysis);
+ sc2(causeSeriousWounds);
+ sc(cureSeriousWounds);
+ sc1(causeSeriousWounds);
+ sc(neutralizePoison);
+ sc(empty);
+ sc1(empty);
+ sc2(causeCriticalWounds);
+ sc(cureCriticalWounds);
+ sc1(causeCriticalWounds);
+ sc(flameStrike);
+ sc(raiseDead);
+ sc2(slayLiving);
+ sc2(trueSeeing);
+ sc2(harm);
+ sc2(heal);
+ sc2(empty);
+ sc(layOnHands);
+ sc2(turnUndead);
+ sc(empty);
+ sc2(empty);
+ sc2(empty);
+ sc(empty);
+ sc(empty);
+ sc2(empty);
+ sc2(empty);
+
+ Common::Array<SpellEndCallback> endCallback;
+ ec(empty);
+ ec(empty);
+ ec(empty);
+ ec(detectMagic);
+ ec(magicMissile);
+ ec1(empty);
+ ec(empty);
+ ec(shockingGraspFlameBlade);
+ ec(empty);
+ ec(empty);
+ ec2(empty);
+ ec2(empty);
+ ec(melfsAcidArrow);
+ ec1(empty); // Stinking Cloud
+ ec(empty);
+ ec(fireball);
+ ec1(flameArrow);
+ ec(empty);
+ ec(holdPerson);
+ ec(empty);
+ ec(lightningBolt);
+ ec(vampiricTouch);
+ ec(empty);
+ ec(iceStorm);
+ ec(empty); // EOB1: stone skin, EOB2: imp invisibility
+ ec(empty); // EOB1: cloud kill, EOB2: remove curse
+ ec(empty);
+ ec(holdMonster);
+ ec2(empty);
+ ec2(empty);
+ ec2(empty);
+ ec2(empty);
+ ec2(trueSeeing);
+ ec2(empty);
+ ec2(empty);
+ ec2(empty);
+ ec2(empty);
+ ec(empty); // Bless
+ ec(empty);
+ ec(empty);
+ ec(detectMagic);
+ ec(empty);
+ ec(aid);
+ ec(shockingGraspFlameBlade);
+ ec(holdPerson);
+ ec(slowPoison);
+ ec(empty);
+ ec(empty);
+ ec(empty);
+ ec(empty);
+ ec(empty);
+ ec(empty);
+ ec(empty);
+ ec(empty);
+ ec(empty);
+ ec1(empty); // Prot from Lightning
+ ec(empty);
+ ec(empty);
+ ec(flameStrike);
+ ec(empty);
+ ec2(empty);
+ ec2(trueSeeing);
+ ec2(empty);
+ ec2(empty);
+ ec2(empty);
+ ec(empty);
+ ec2(empty);
+ ec1(monster_lightningBolt);
+ ec2(monster_fireball1);
+ ec2(empty);
+ ec2(monster_fireball2);
+ ec(monster_deathSpell);
+ ec(monster_disintegrate);
+ ec2(monster_causeCriticalWounds);
+ ec2(monster_fleshToStone);
+
+ _spells = new EoBSpell[_numSpells];
+ memset(_spells, 0, _numSpells * sizeof(EoBSpell));
+
+ for (int i = 0, n = 0; i < _numSpells; i++, n++) {
+ EoBSpell *s = &_spells[i];
+
+ // Fix EoB 1 spell names
+ bool skip = false;
+ if (i == 5 || i == 9) {
+ n--;
+ skip = true;
+ }
+
+ s->name = _flags.gameID == GI_EOB2 ? ((i == 0 || i == _mageSpellListSize) ? _mageSpellList[0] : ((i < (_mageSpellListSize + 1)) ? _spellNames[i - 1] : _spellNames[i - 2])) : (skip ? _spellNames[0] : _spellNames[n]);
+ s->startCallback = startCallback[i];
+ s->timingPara = magicTimingParaAssign[i];
+ s->endCallback = endCallback[i];
+ }
+
+ magicTimingParaAssign.clear();
+ startCallback.clear();
+ endCallback.clear();
+
+ _clericSpellOffset = _mageSpellListSize;
+
+#undef mpn
+#undef mp1n
+#undef mp2n
+#undef mp
+#undef mp1
+#undef mp2
+#undef sc
+#undef sc1
+#undef sc2
+#undef ec
+#undef ec1
+#undef ec2
+}
+
+void EoBEngine::initStaticResource() {
+ int temp;
+ _mainMenuStrings = _staticres->loadStrings(kEoB1MainMenuStrings, temp);
+ _finBonusStrings = _staticres->loadStrings(kEoB1BonusStrings, temp);
+
+ _doorShapeEncodeDefs = _staticres->loadRawData(kEoB1DoorShapeDefs, temp);
+ _doorSwitchShapeEncodeDefs = _staticres->loadRawData(kEoB1DoorSwitchShapeDefs, temp);
+ _doorSwitchCoords = _staticres->loadRawData(kEoB1DoorSwitchCoords, temp);
+
+ _dscDoorScaleMult4 = _staticres->loadRawData(kEoBBaseDscDoorScaleMult4, temp);
+ _dscDoorScaleMult5 = _staticres->loadRawData(kEoBBaseDscDoorScaleMult5, temp);
+ _dscDoorScaleMult6 = _staticres->loadRawData(kEoBBaseDscDoorScaleMult6, temp);
+ _dscDoorY3 = _staticres->loadRawData(kEoBBaseDscDoorY3, temp);
+ _dscDoorY4 = _staticres->loadRawData(kEoBBaseDscDoorY4, temp);
+ _dscDoorY5 = _staticres->loadRawData(kEoBBaseDscDoorY5, temp);
+ _dscDoorY6 = _staticres->loadRawData(kEoBBaseDscDoorY6, temp);
+ _dscDoorY7 = _staticres->loadRawData(kEoBBaseDscDoorY7, temp);
+ _dscDoorCoordsExt = (const int16 *)_staticres->loadRawDataBe16(kEoBBaseDscDoorCoordsExt, temp);
+
+ _enemyMageSpellList = _staticres->loadRawData(kEoB1EnemyMageSpellList, temp);
+ _enemyMageSfx = _staticres->loadRawData(kEoB1EnemyMageSfx, temp);
+ _beholderSpellList = _staticres->loadRawData(kEoB1BeholderSpellList, temp);
+ _beholderSfx = _staticres->loadRawData(kEoB1BeholderSfx, temp);
+
+ _cgaMappingDefault = _staticres->loadRawData(kEoB1CgaMappingDefault, temp);
+ _cgaMappingAlt = _staticres->loadRawData(kEoB1CgaMappingAlt, temp);
+ _cgaMappingInv = _staticres->loadRawData(kEoB1CgaMappingInv, temp);
+ _cgaMappingItemsL = _staticres->loadRawData(kEoB1CgaMappingItemsL, temp);
+ _cgaMappingItemsS = _staticres->loadRawData(kEoB1CgaMappingItemsS, temp);
+ _cgaMappingThrown = _staticres->loadRawData(kEoB1CgaMappingThrown, temp);
+ _cgaMappingIcons = _staticres->loadRawData(kEoB1CgaMappingIcons, temp);
+ _cgaMappingDeco = _staticres->loadRawData(kEoB1CgaMappingDeco, temp);
+ _cgaLevelMappingIndex = _staticres->loadRawData(kEoB1CgaLevelMappingIndex, temp);
+ for (int i = 0; i < 5; i++)
+ _cgaMappingLevel[i] = _staticres->loadRawData(kEoB1CgaMappingLevel0 + i, temp);
+
+ _turnUndeadString = _staticres->loadStrings(kEoB1TurnUndeadString, temp);
+
+ _npcShpData = _staticres->loadRawData(kEoB1NpcShpData, temp);
+ _npcSubShpIndex1 = _staticres->loadRawData(kEoB1NpcSubShpIndex1, temp);
+ _npcSubShpIndex2 = _staticres->loadRawData(kEoB1NpcSubShpIndex2, temp);
+ _npcSubShpY = _staticres->loadRawData(kEoB1NpcSubShpY, temp);
+ for (int i = 0; i < 11; i++)
+ _npcStrings[i] = _staticres->loadStrings(kEoB1Npc0Strings + i, temp);
+
+ const uint8 *ps = _staticres->loadRawData(kEoB1MonsterProperties, temp);
+ temp /= 27;
+ _monsterProps = new EoBMonsterProperty[temp];
+ memset(_monsterProps, 0, temp * sizeof(EoBMonsterProperty));
+ // Convert EOB1 (hard coded) monster properties to EOB2 type monster properties.
+ for (int i = 0; i < temp; i++) {
+ EoBMonsterProperty *p = &_monsterProps[i];
+ p->armorClass = (int8)*ps++;
+ p->hitChance = (int8)*ps++;
+ p->level = (int8)*ps++;
+ p->attacksPerRound = *ps++;
+ p->dmgDc[0].times = *ps++;
+ p->dmgDc[0].pips = *ps++;
+ p->dmgDc[0].base = (int8)*ps++;
+ p->dmgDc[1].times = *ps++;
+ p->dmgDc[1].pips = *ps++;
+ p->dmgDc[1].base = (int8)*ps++;
+ p->dmgDc[2].times = *ps++;
+ p->dmgDc[2].pips = *ps++;
+ p->dmgDc[2].base = (int8)*ps++;
+ ps++;
+ p->capsFlags = *ps++;
+ p->typeFlags = READ_LE_UINT16(ps);
+ ps += 2;
+ ps++;
+ ps++;
+ p->experience = READ_LE_UINT16(ps);
+ ps += 2;
+ p->u30 = *ps++;
+ p->sound1 = (int8)*ps++;
+ p->sound2 = (int8)*ps++;
+ p->numRemoteAttacks = *ps++;
+ p->tuResist = (int8)*ps++;
+ p->dmgModifierEvade = *ps++;
+ }
+
+ static const char *errorSlotNoNameString[3] = {
+ " You must specify\r a name for your\r save game!",
+ " Spielstaende mues-\r sen einen Namen\r haben!",
+ 0
+ };
+
+ _errorSlotNoNameString = errorSlotNoNameString[(_flags.lang == Common::EN_ANY) ? 0 : ((_flags.lang == Common::DE_DEU) ? 1 : 2)];
+}
+
+void EoBEngine::initSpells() {
+ EoBCoreEngine::initSpells();
+
+ struct FlagTableEntry {
+ uint16 typeFlag;
+ uint32 effectFlag;
+ uint8 damageFlag;
+ };
+
+ static const FlagTableEntry flagTable[] = {
+ { 0x0000, 0x000000, 0x00 }, // dummy
+ { 0x0033, 0x000001, 0x00 }, // armor
+ { 0x0100, 0x000000, 0x21 }, // burning hands
+ { 0x004c, 0x000002, 0x00 }, // detect magic
+ { 0x0100, 0x000000, 0x01 }, // magic missile
+ { 0x0000, 0x000000, 0x00 }, // dummy
+ { 0x008b, 0x000008, 0x00 }, // shield
+ { 0x0488, 0x000000, 0x03 }, // shocking grasp
+ { 0x0021, 0x000040, 0x00 }, // invisibility
+ { 0x0000, 0x000000, 0x00 }, // dummy
+ { 0x0100, 0x000000, 0x11 }, // melf's acid arrow
+ { 0x0000, 0x000000, 0x00 }, // STINKING CLOUD
+ { 0x1000, 0x000000, 0x00 }, // dispel magic
+ { 0x0100, 0x000000, 0x21 }, // fireball
+ { 0x0100, 0x000000, 0x11 }, // FLAME ARROW
+ { 0x0248, 0x010000, 0x00 }, // haste
+ { 0x0100, 0x000000, 0x00 }, // hold person
+ { 0x0240, 0x000040, 0x00 }, // inv 10'
+ { 0x0100, 0x000000, 0x03 }, // lightning bolt
+ { 0x0488, 0x000000, 0x01 }, // vampiric touch
+ { 0x0100, 0x000000, 0x00 }, // fear
+ { 0x0100, 0x000000, 0x41 }, // ice storm
+ { 0x0033, 0x000001, 0x00 }, // STONE SKIN
+ { 0x0000, 0x000000, 0x00 }, // CLOUD KILL
+ { 0x0100, 0x000000, 0x41 }, // cone of cold
+ { 0x0100, 0x000000, 0x00 }, // hold monster
+ { 0x005c, 0x000400, 0x00 }, // bless
+ { 0x0020, 0x000000, 0x00 }, // cure light wounds
+ { 0x0100, 0x000000, 0x01 }, // cause light wounds
+ { 0x004c, 0x000002, 0x00 }, // detect magic
+ { 0x0029, 0x000800, 0x00 }, // prot from evil
+ { 0x0039, 0x000000, 0x00 }, // aid
+ { 0x2408, 0x000000, 0x21 }, // flame blade
+ { 0x0100, 0x000000, 0x00 }, // hold person
+ { 0x0028, 0x002000, 0x00 }, // slow poison
+ { 0x0040, 0x000000, 0x00 }, // create food
+ { 0x1000, 0x000000, 0x00 }, // dispel magic
+ { 0x0099, 0x004000, 0x00 }, // magical vestment
+ { 0x004c, 0x008000, 0x00 }, // prayer
+ { 0x0040, 0x000000, 0x00 }, // remove paralysis
+ { 0x0020, 0x000000, 0x00 }, // cure serious
+ { 0x0100, 0x000000, 0x01 }, // cause serious
+ { 0x0020, 0x000000, 0x00 }, // neutralize poison
+ { 0x0248, 0x000800, 0x00 }, // prot from evil 10'
+ { 0x0000, 0x000000, 0x00 }, // PROT FROM LIGHTNING
+ { 0x0020, 0x000000, 0x00 }, // cure critical
+ { 0x0100, 0x000000, 0x01 }, // cause critical
+ { 0x0100, 0x000000, 0x21 }, // flame strike
+ { 0x0020, 0x000000, 0x00 }, // raise dead
+ { 0x0020, 0x000000, 0x00 }, // lay on hands
+ { 0x0000, 0x000000, 0x00 }, // obj hit passive
+ { 0x0000, 0x000000, 0x00 }, // disintegrate passive
+ { 0x0000, 0x000000, 0x00 } // death spell passive
+ };
+
+ int temp;
+ const uint8 *src = _staticres->loadRawData(kEoBBaseSpellProperties, temp);
+ _clericSpellOffset -= 1;
+
+ for (int i = 0; i < _numSpells; i++) {
+ EoBSpell *s = &_spells[i];
+ src += 4;
+ s->flags = flagTable[i].typeFlag;
+ s->damageFlags = flagTable[i].damageFlag;
+ s->effectFlags = flagTable[i].effectFlag;
+ s->sound = src[13];
+ src += 15;
+ }
+}
+
+const KyraRpgGUISettings EoBEngine::_guiSettingsVGA = {
+ { 9, 15, 95, 9, 7, { 285, 139 }, { 189, 162 }, { 31, 31 } },
+ { 135, 130, 132, 133, 133, 17, 23, 20, 184, 177, 180, 184, 177, 180 }
+};
+
+const KyraRpgGUISettings EoBEngine::_guiSettingsEGA = {
+ { 9, 15, 95, 9, 7, { 285, 139 }, { 189, 162 }, { 31, 31 } },
+ { 13, 9, 2, 133, 2, 6, 13, 8, 13, 15, 14, 13, 15, 14 }
+};
+
+const uint8 EoBEngine::_egaDefaultPalette[] = {
+ 0, 5, 3, 2, 10, 14, 12, 6, 4, 11, 9, 1, 0, 8, 7, 15
+};
+
+void DarkMoonEngine::initStaticResource() {
+ int temp;
+ _mainMenuStrings = _staticres->loadStrings(kEoB2MainMenuStrings, temp);
+ _introStrings = _staticres->loadStrings(kEoB2IntroStrings, temp);
+ _cpsFilesIntro = _staticres->loadStrings(kEoB2IntroCPSFiles, temp);
+
+ _animIntro = new const DarkMoonAnimCommand*[44];
+ for (int i = 0; i < 44; i++)
+ _animIntro[i] = _staticres->loadEoB2SeqData(kEob2IntroAnimData00 + i, temp);
+
+ _shapesIntro = new const DarkMoonShapeDef*[13];
+ memset(_shapesIntro, 0, sizeof(DarkMoonShapeDef*) * 13);
+ _shapesIntro[0] = _staticres->loadEoB2ShapeData(kEoB2IntroShapes00, temp);
+ _shapesIntro[1] = _staticres->loadEoB2ShapeData(kEoB2IntroShapes01, temp);
+ _shapesIntro[4] = _staticres->loadEoB2ShapeData(kEoB2IntroShapes04, temp);
+ _shapesIntro[7] = _staticres->loadEoB2ShapeData(kEoB2IntroShapes07, temp);
+
+ _finaleStrings = _staticres->loadStrings(kEoB2FinaleStrings, temp);
+ _creditsData = _staticres->loadRawData(kEoB2CreditsData, temp);
+ _cpsFilesFinale = _staticres->loadStrings(kEoB2FinaleCPSFiles, temp);
+
+ _animFinale = new const DarkMoonAnimCommand*[21];
+ for (int i = 0; i < 21; i++)
+ _animFinale[i] = _staticres->loadEoB2SeqData(kEob2FinaleAnimData00 + i, temp);
+
+ _shapesFinale = new const DarkMoonShapeDef*[13];
+ memset(_shapesFinale, 0, sizeof(DarkMoonShapeDef*) * 13);
+ _shapesFinale[0] = _staticres->loadEoB2ShapeData(kEoB2FinaleShapes00, temp);
+ _shapesFinale[3] = _staticres->loadEoB2ShapeData(kEoB2FinaleShapes03, temp);
+ _shapesFinale[7] = _staticres->loadEoB2ShapeData(kEoB2FinaleShapes07, temp);
+ _shapesFinale[9] = _staticres->loadEoB2ShapeData(kEoB2FinaleShapes09, temp);
+ _shapesFinale[10] = _staticres->loadEoB2ShapeData(kEoB2FinaleShapes10, temp);
+
+ _dscDoorType5Offs = _staticres->loadRawData(kEoBBaseDscDoorType5Offs, temp);
+
+ _npcShpData = _staticres->loadRawData(kEoB2NpcShapeData, temp);
+ _npcStrings[0] = _staticres->loadStrings(kEoB2Npc1Strings, temp);
+ _npcStrings[1] = _staticres->loadStrings(kEoB2Npc2Strings, temp);
+ _monsterDustStrings = _staticres->loadStrings(kEoB2MonsterDustStrings, temp);
+ _dreamSteps = (const int8 *)_staticres->loadRawData(kEoB2DreamSteps, temp);
+ _kheldranStrings = _staticres->loadStrings(kEoB2KheldranStrings, temp);
+ _hornStrings = _staticres->loadStrings(kEoB2HornStrings, temp);
+ _hornSounds = _staticres->loadRawData(kEoB2HornSounds, temp);
+
+ _wallOfForceDsX = (const int16 *)_staticres->loadRawDataBe16(kEoB2WallOfForceDsX, temp);
+ _wallOfForceDsY = _staticres->loadRawData(kEoB2WallOfForceDsY, temp);
+ _wallOfForceDsNumW = _staticres->loadRawData(kEoB2WallOfForceNumW, temp);
+ _wallOfForceDsNumH = _staticres->loadRawData(kEoB2WallOfForceNumH, temp);
+ _wallOfForceShpId = _staticres->loadRawData(kEoB2WallOfForceShpId, temp);
+
+ static const char *errorSlotNoNameString[3] = {
+ " You must specify\r a name for your\r save game!",
+ " Spielst[nde m]ssen\r einen Namen haben!",
+ 0
+ };
+
+ _errorSlotNoNameString = errorSlotNoNameString[(_flags.lang == Common::EN_ANY) ? 0 : ((_flags.lang == Common::DE_DEU) ? 1 : 2)];
+
+ // ScummVM specific
+ static const char *transferStringsScummVM[3][5] = {
+ {
+ "\r We cannot find any EOB save game\r file. Please make sure that the\r save game file with the party\r you wish to transfer is located\r in your ScummVM save game\r directory. If you have set up\r multiple save directories you\r have to copy the EOB save file\r into your EOB II save directory.\r Do you wish to try again?",
+ "Game ID",
+ "\r It seems that you have already\r defeated Xanathar here. Do you\r wish to transfer the party that\r finished the game? If not, you\r will be able to select a save\r game from the save game\r dialogue.",
+ "Select File",
+ "\r\r Please wait..."
+ },
+ {
+ "\r Kein EOB-Spielstand zu finden.\r Bitte Spielstandsdatei mit der\r zu ]bernehmenden Gruppe in das\r ScummVM Spielstands-Verzeichnis\r kopieren. Bei mehreren Spiel-\r stands-Verzeichnissen bitte\r den EOB-Spielstand in das\r EOB II-Spielstands-Verzeichnis\r kopieren. Nochmal versuchen?",
+ "Game ID",
+ "\r Wie es scheint, wurde Xanathar\r hier bereits besiegt. Soll die\r Gruppe, mit der das Spiel be-\r endet wurde, ]bernommen werden?\r Falls nicht, kann ein Spielstand\r aus der Spielstandsliste gew[hlt\r werden.",
+ "Spiel W[hlen",
+ "\r\r Bitte warten..."
+ },
+ {
+ 0, 0, 0, 0
+ }
+ };
+
+ _transferStringsScummVM = transferStringsScummVM[(_flags.lang == Common::EN_ANY) ? 0 : ((_flags.lang == Common::DE_DEU) ? 1 : 2)];
+}
+
+void DarkMoonEngine::initSpells() {
+ EoBCoreEngine::initSpells();
+
+ int temp;
+ const uint8 *src = _staticres->loadRawData(kEoBBaseSpellProperties, temp);
+
+ for (int i = 0; i < _numSpells; i++) {
+ EoBSpell *s = &_spells[i];
+ src += 8;
+ s->flags = READ_LE_UINT16(src);
+ src += 10;
+ s->sound = *src++;
+ s->effectFlags = READ_LE_UINT32(src);
+ src += 4;
+ s->damageFlags = READ_LE_UINT16(src);
+ src += 2;
+ }
+}
+
+const char *DarkMoonEngine::_palFilesIntroVGA[] = {
+ "PALETTE1.PAL",
+ "PALETTE3.PAL",
+ "PALETTE2.PAL",
+ "PALETTE4.PAL",
+ 0
+};
+
+const char *DarkMoonEngine::_palFilesIntroEGA[] = {
+ "PALETTE0.PAL",
+ "PALETTE3.PAL",
+ "PALETTE2.PAL",
+ "PALETTE4.PAL",
+ 0
+};
+
+const char *DarkMoonEngine::_palFilesFinaleVGA[] = {
+ "FINALE_0.PAL",
+ "FINALE_0.PAL",
+ "FINALE_1.PAL",
+ "FINALE_2.PAL",
+ "FINALE_3.PAL",
+ "FINALE_4.PAL",
+ "FINALE_5.PAL",
+ "FINALE_6.PAL",
+ "FINALE_7.PAL",
+ 0
+};
+
+const char *DarkMoonEngine::_palFilesFinaleEGA[] = {
+ "FINALE_0.PAL",
+ "FINALE_0.PAL",
+ "FINALE_1.PAL",
+ "FINALE_2.PAL",
+ "FINALE_3.PAL",
+ "FINALE_4.PAL",
+ "FINALE_5.PAL",
+ "FINALE_0.PAL",
+ "FINALE_0.PAL",
+ 0
+};
+
+const KyraRpgGUISettings DarkMoonEngine::_guiSettings = {
+ { 9, 15, 95, 9, 7, { 221, 76 }, { 189, 162 }, { 95, 95 } },
+ { 186, 181, 183, 133, 184, 17, 23, 20, 186, 181, 183, 182, 177, 180 }
+};
+
+const uint8 DarkMoonEngine::_egaDefaultPalette[] = {
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
+};
+
+#endif // ENABLE_EOB
+
+} // End of namespace Kyra
diff --git a/engines/kyra/staticres_lol.cpp b/engines/kyra/staticres_lol.cpp
index bf838cd572..63bc7fa99b 100644
--- a/engines/kyra/staticres_lol.cpp
+++ b/engines/kyra/staticres_lol.cpp
@@ -30,31 +30,23 @@
namespace Kyra {
const LoLCharacter *StaticResource::loadCharData(int id, int &entries) {
- return (const LoLCharacter *)getData(id, kLolCharData, entries);
+ return (const LoLCharacter *)getData(id, kLoLCharData, entries);
}
const SpellProperty *StaticResource::loadSpellData(int id, int &entries) {
- return (const SpellProperty *)getData(id, kLolSpellData, entries);
+ return (const SpellProperty *)getData(id, kLoLSpellData, entries);
}
const CompassDef *StaticResource::loadCompassData(int id, int &entries) {
- return (const CompassDef *)getData(id, kLolCompassData, entries);
+ return (const CompassDef *)getData(id, kLoLCompassData, entries);
}
const FlyingObjectShape *StaticResource::loadFlyingObjectData(int id, int &entries) {
- return (const FlyingObjectShape *)getData(id, kLolFlightShpData, entries);
+ return (const FlyingObjectShape *)getData(id, kLoLFlightShpData, entries);
}
-const uint16 *StaticResource::loadRawDataBe16(int id, int &entries) {
- return (const uint16 *)getData(id, kLolRawDataBe16, entries);
-}
-
-const uint32 *StaticResource::loadRawDataBe32(int id, int &entries) {
- return (const uint32 *)getData(id, kLolRawDataBe32, entries);
-}
-
-const ButtonDef *StaticResource::loadButtonDefs(int id, int &entries) {
- return (const ButtonDef *)getData(id, kLolButtonData, entries);
+const LoLButtonDef *StaticResource::loadButtonDefs(int id, int &entries) {
+ return (const LoLButtonDef *)getData(id, kLoLButtonData, entries);
}
bool StaticResource::loadCharData(Common::SeekableReadStream &stream, void *&ptr, int &size) {
@@ -164,34 +156,10 @@ bool StaticResource::loadFlyingObjectData(Common::SeekableReadStream &stream, vo
return true;
}
-bool StaticResource::loadRawDataBe16(Common::SeekableReadStream &stream, void *&ptr, int &size) {
- size = stream.size() >> 1;
-
- uint16 *r = new uint16[size];
-
- for (int i = 0; i < size; i++)
- r[i] = stream.readUint16BE();
-
- ptr = r;
- return true;
-}
-
-bool StaticResource::loadRawDataBe32(Common::SeekableReadStream &stream, void *&ptr, int &size) {
- size = stream.size() >> 2;
-
- uint32 *r = new uint32[size];
-
- for (int i = 0; i < size; i++)
- r[i] = stream.readUint32BE();
-
- ptr = r;
- return true;
-}
-
bool StaticResource::loadButtonDefs(Common::SeekableReadStream &stream, void *&ptr, int &size) {
size = stream.size() / 18;
- ButtonDef *r = new ButtonDef[size];
+ LoLButtonDef *r = new LoLButtonDef[size];
for (int i = 0; i < size; i++) {
r[i].buttonflags = stream.readUint16BE();
@@ -237,23 +205,8 @@ void StaticResource::freeFlyingObjectData(void *&ptr, int &size) {
size = 0;
}
-
-void StaticResource::freeRawDataBe16(void *&ptr, int &size) {
- uint16 *data = (uint16 *)ptr;
- delete[] data;
- ptr = 0;
- size = 0;
-}
-
-void StaticResource::freeRawDataBe32(void *&ptr, int &size) {
- uint32 *data = (uint32 *)ptr;
- delete[] data;
- ptr = 0;
- size = 0;
-}
-
void StaticResource::freeButtonDefs(void *&ptr, int &size) {
- ButtonDef *d = (ButtonDef *)ptr;
+ LoLButtonDef *d = (LoLButtonDef *)ptr;
delete[] d;
ptr = 0;
size = 0;
@@ -289,88 +242,79 @@ void LoLEngine::initStaticResource() {
if (_flags.isDemo)
return;
- _pakFileList = _staticres->loadStrings(kLolIngamePakFiles, _pakFileListSize);
- _charDefaults = _staticres->loadCharData(kLolCharacterDefs, _charDefaultsSize);
- _ingameSoundIndex = (const uint16 *)_staticres->loadRawData(kLolIngameSfxIndex, _ingameSoundIndexSize);
- _musicTrackMap = _staticres->loadRawData(kLolMusicTrackMap, _musicTrackMapSize);
- _ingameGMSoundIndex = _staticres->loadRawData(kLolIngameGMSfxIndex, _ingameGMSoundIndexSize);
- _ingameMT32SoundIndex = _staticres->loadRawData(kLolIngameMT32SfxIndex, _ingameMT32SoundIndexSize);
- _ingamePCSpeakerSoundIndex = _staticres->loadRawData(kLolIngamePcSpkSfxIndex, _ingamePCSpeakerSoundIndexSize);
- _spellProperties = _staticres->loadSpellData(kLolSpellProperties, _spellPropertiesSize);
- _gameShapeMap = (const int8 *)_staticres->loadRawData(kLolGameShapeMap, _gameShapeMapSize);
- _sceneItemOffs = (const int8 *)_staticres->loadRawData(kLolSceneItemOffs, _sceneItemOffsSize);
- _charInvIndex = _staticres->loadRawData(kLolCharInvIndex, _charInvIndexSize);
- _charInvDefs = _staticres->loadRawData(kLolCharInvDefs, _charInvDefsSize);
- _charDefsMan = _staticres->loadRawDataBe16(kLolCharDefsMan, _charDefsManSize);
- _charDefsWoman = _staticres->loadRawDataBe16(kLolCharDefsWoman, _charDefsWomanSize);
- _charDefsKieran = _staticres->loadRawDataBe16(kLolCharDefsKieran, _charDefsKieranSize);
- _charDefsAkshel = _staticres->loadRawDataBe16(kLolCharDefsAkshel, _charDefsAkshelSize);
- _expRequirements = (const int32 *)_staticres->loadRawDataBe32(kLolExpRequirements, _expRequirementsSize);
- _monsterModifiers = _staticres->loadRawDataBe16(kLolMonsterModifiers, _monsterModifiersSize);
- _monsterShiftOffs = (const int8 *)_staticres->loadRawData(kLolMonsterShiftOffsets, _monsterShiftOffsSize);
- _monsterDirFlags = _staticres->loadRawData(kLolMonsterDirFlags, _monsterDirFlagsSize);
- _monsterScaleX = _staticres->loadRawData(kLolMonsterScaleX, _monsterScaleXSize);
- _monsterScaleY = _staticres->loadRawData(kLolMonsterScaleY, _monsterScaleYSize);
- _monsterScaleWH = _staticres->loadRawDataBe16(kLolMonsterScaleWH, _monsterScaleWHSize);
- _inventorySlotDesc = _staticres->loadRawDataBe16(kLolInventoryDesc, _inventorySlotDescSize);
- _levelShpList = _staticres->loadStrings(kLolLevelShpList, _levelShpListSize);
- _levelDatList = _staticres->loadStrings(kLolLevelDatList, _levelDatListSize);
- _compassDefs = _staticres->loadCompassData(kLolCompassDefs, _compassDefsSize);
- _flyingItemShapes = _staticres->loadFlyingObjectData(kLolFlyingObjectShp, _flyingItemShapesSize);
- _itemCost = _staticres->loadRawDataBe16(kLolItemPrices, _itemCostSize);
- _stashSetupData = _staticres->loadRawData(kLolStashSetup, _stashSetupDataSize);
-
- _dscUnk1 = (const int8 *)_staticres->loadRawData(kLolDscUnk1, _dscUnk1Size);
- _dscShapeIndex = (const int8 *)_staticres->loadRawData(kLolDscShapeIndex, _dscShapeIndexSize);
- _dscOvlMap = _staticres->loadRawData(kLolDscOvlMap, _dscOvlMapSize);
- _dscShapeScaleW = _staticres->loadRawDataBe16(kLolDscScaleWidthData, _dscShapeScaleWSize);
- _dscShapeScaleH = _staticres->loadRawDataBe16(kLolDscScaleHeightData, _dscShapeScaleHSize);
- _dscShapeX = (const int16 *)_staticres->loadRawDataBe16(kLolDscX, _dscShapeXSize);
- _dscShapeY = (const int8 *)_staticres->loadRawData(kLolDscY, _dscShapeYSize);
- _dscTileIndex = _staticres->loadRawData(kLolDscTileIndex, _dscTileIndexSize);
- _dscUnk2 = _staticres->loadRawData(kLolDscUnk2, _dscUnk2Size);
- _dscDoorShpIndex = _staticres->loadRawData(kLolDscDoorShapeIndex, _dscDoorShpIndexSize);
- _dscDim1 = (const int8 *)_staticres->loadRawData(kLolDscDimData1, _dscDim1Size);
- _dscDim2 = (const int8 *)_staticres->loadRawData(kLolDscDimData2, _dscDim2Size);
- _dscBlockMap = _staticres->loadRawData(kLolDscBlockMap, _dscBlockMapSize);
- _dscDimMap = _staticres->loadRawData(kLolDscDimMap, _dscDimMapSize);
- _dscDoorMonsterScaleTable = _staticres->loadRawDataBe16(kLolDscDoorScale, _dscDoorMonsterScaleTableSize);
- _dscShapeOvlIndex = _staticres->loadRawData(kLolDscOvlIndex, _dscShapeOvlIndexSize);
- _dscDoor4 = _staticres->loadRawDataBe16(kLolDscDoor4, _dscDoor4Size);
- _dscBlockIndex = (const int8 *)_staticres->loadRawData(kLolDscBlockIndex, _dscBlockIndexSize);
- _dscDoor1 = _staticres->loadRawData(kLolDscDoor1, _dscDoor1Size);
- _dscDoorMonsterX = (const int16 *)_staticres->loadRawDataBe16(kLolDscDoorX, _dscDoorMonsterXSize);
- _dscDoorMonsterY = (const int16 *)_staticres->loadRawDataBe16(kLolDscDoorY, _dscDoorMonsterYSize);
-
- _scrollXTop = _staticres->loadRawData(kLolScrollXTop, _scrollXTopSize);
- _scrollYTop = _staticres->loadRawData(kLolScrollYTop, _scrollYTopSize);
- _scrollXBottom = _staticres->loadRawData(kLolScrollXBottom, _scrollXBottomSize);
- _scrollYBottom = _staticres->loadRawData(kLolScrollYBottom, _scrollYBottomSize);
-
- const char *const *tmpSndList = _staticres->loadStrings(kLolIngameSfxFiles, _ingameSoundListSize);
+ int tempSize;
+ _pakFileList = _staticres->loadStrings(kLoLIngamePakFiles, _pakFileListSize);
+ _charDefaults = _staticres->loadCharData(kLoLCharacterDefs, _charDefaultsSize);
+ _ingameSoundIndex = (const uint16 *)_staticres->loadRawData(kLoLIngameSfxIndex, tempSize);
+ _musicTrackMap = _staticres->loadRawData(kLoLMusicTrackMap, tempSize);
+ _ingameGMSoundIndex = _staticres->loadRawData(kLoLIngameGMSfxIndex, _ingameGMSoundIndexSize);
+ _ingameMT32SoundIndex = _staticres->loadRawData(kLoLIngameMT32SfxIndex, _ingameMT32SoundIndexSize);
+ _ingamePCSpeakerSoundIndex = _staticres->loadRawData(kLoLIngamePcSpkSfxIndex, _ingamePCSpeakerSoundIndexSize);
+ _spellProperties = _staticres->loadSpellData(kLoLSpellProperties, tempSize);
+ _gameShapeMap = (const int8 *)_staticres->loadRawData(kLoLGameShapeMap, tempSize);
+ _sceneItemOffs = (const int8 *)_staticres->loadRawData(kLoLSceneItemOffs, tempSize);
+ _charInvIndex = _staticres->loadRawData(kLoLCharInvIndex, tempSize);
+ _charInvDefs = _staticres->loadRawData(kLoLCharInvDefs, tempSize);
+ _charDefsMan = _staticres->loadRawDataBe16(kLoLCharDefsMan, tempSize);
+ _charDefsWoman = _staticres->loadRawDataBe16(kLoLCharDefsWoman, tempSize);
+ _charDefsKieran = _staticres->loadRawDataBe16(kLoLCharDefsKieran, tempSize);
+ _charDefsAkshel = _staticres->loadRawDataBe16(kLoLCharDefsAkshel, tempSize);
+ _expRequirements = (const int32 *)_staticres->loadRawDataBe32(kLoLExpRequirements, tempSize);
+ _monsterModifiers = _staticres->loadRawDataBe16(kLoLMonsterModifiers, tempSize);
+ _monsterShiftOffs = (const int8 *)_staticres->loadRawData(kLoLMonsterShiftOffsets, tempSize);
+ _monsterDirFlags = _staticres->loadRawData(kLoLMonsterDirFlags, tempSize);
+ _monsterScaleX = _staticres->loadRawData(kLoLMonsterScaleX, tempSize);
+ _monsterScaleY = _staticres->loadRawData(kLoLMonsterScaleY, tempSize);
+ _monsterScaleWH = _staticres->loadRawDataBe16(kLoLMonsterScaleWH, tempSize);
+ _inventorySlotDesc = _staticres->loadRawDataBe16(kLoLInventoryDesc, tempSize);
+ _levelShpList = _staticres->loadStrings(kLoLLevelShpList, tempSize);
+ _levelDatList = _staticres->loadStrings(kLoLLevelDatList, tempSize);
+ _compassDefs = _staticres->loadCompassData(kLoLCompassDefs, tempSize);
+ _flyingItemShapes = _staticres->loadFlyingObjectData(kLoLFlyingObjectShp, tempSize);
+ _itemCost = _staticres->loadRawDataBe16(kLoLItemPrices, tempSize);
+ _stashSetupData = _staticres->loadRawData(kLoLStashSetup, tempSize);
+
+ _dscWalls = (const int8 *)_staticres->loadRawData(kLoLDscWalls, tempSize);
+
+ _dscOvlMap = _staticres->loadRawData(kLoLDscOvlMap, tempSize);
+ _dscShapeOvlIndex = _staticres->loadRawData(kLoLDscOvlIndex, tempSize);
+ _dscShapeScaleW = _staticres->loadRawDataBe16(kLoLDscScaleWidthData, tempSize);
+ _dscShapeScaleH = _staticres->loadRawDataBe16(kLoLDscScaleHeightData, tempSize);
+ _dscShapeY = (const int8 *)_staticres->loadRawData(kLoLBaseDscY, tempSize);
+
+ _dscDoorMonsterScaleTable = _staticres->loadRawDataBe16(kLoLDscDoorScale, tempSize);
+ _dscDoor4 = _staticres->loadRawDataBe16(kLoLDscDoor4, tempSize);
+ _dscDoorMonsterX = (const int16 *)_staticres->loadRawDataBe16(kLoLDscDoorX, tempSize);
+ _dscDoorMonsterY = (const int16 *)_staticres->loadRawDataBe16(kLoLDscDoorY, tempSize);
+
+ _scrollXTop = _staticres->loadRawData(kLoLScrollXTop, tempSize);
+ _scrollYTop = _staticres->loadRawData(kLoLScrollYTop, tempSize);
+ _scrollXBottom = _staticres->loadRawData(kLoLScrollXBottom, tempSize);
+ _scrollYBottom = _staticres->loadRawData(kLoLScrollYBottom, tempSize);
+
+ const char *const *tmpSndList = _staticres->loadStrings(kLoLIngameSfxFiles, _ingameSoundListSize);
if (tmpSndList) {
- _ingameSoundList = new char *[_ingameSoundListSize];
+ _ingameSoundList = new char*[_ingameSoundListSize];
for (int i = 0; i < _ingameSoundListSize; i++) {
_ingameSoundList[i] = new char[strlen(tmpSndList[i]) + 1];
strcpy(_ingameSoundList[i], tmpSndList[i]);
}
- _staticres->unloadId(kLolIngameSfxFiles);
+ _staticres->unloadId(kLoLIngameSfxFiles);
}
- _buttonData = _staticres->loadButtonDefs(kLolButtonDefs, _buttonDataSize);
- _buttonList1 = (const int16 *)_staticres->loadRawDataBe16(kLolButtonList1, _buttonList1Size);
- _buttonList2 = (const int16 *)_staticres->loadRawDataBe16(kLolButtonList2, _buttonList2Size);
- _buttonList3 = (const int16 *)_staticres->loadRawDataBe16(kLolButtonList3, _buttonList3Size);
- _buttonList4 = (const int16 *)_staticres->loadRawDataBe16(kLolButtonList4, _buttonList4Size);
- _buttonList5 = (const int16 *)_staticres->loadRawDataBe16(kLolButtonList5, _buttonList5Size);
- _buttonList6 = (const int16 *)_staticres->loadRawDataBe16(kLolButtonList6, _buttonList6Size);
- _buttonList7 = (const int16 *)_staticres->loadRawDataBe16(kLolButtonList7, _buttonList7Size);
- _buttonList8 = (const int16 *)_staticres->loadRawDataBe16(kLolButtonList8, _buttonList8Size);
+ _buttonData = _staticres->loadButtonDefs(kLoLButtonDefs, tempSize);
+ _buttonList1 = (const int16 *)_staticres->loadRawDataBe16(kLoLButtonList1, tempSize);
+ _buttonList2 = (const int16 *)_staticres->loadRawDataBe16(kLoLButtonList2, tempSize);
+ _buttonList3 = (const int16 *)_staticres->loadRawDataBe16(kLoLButtonList3, tempSize);
+ _buttonList4 = (const int16 *)_staticres->loadRawDataBe16(kLoLButtonList4, tempSize);
+ _buttonList5 = (const int16 *)_staticres->loadRawDataBe16(kLoLButtonList5, tempSize);
+ _buttonList6 = (const int16 *)_staticres->loadRawDataBe16(kLoLButtonList6, tempSize);
+ _buttonList7 = (const int16 *)_staticres->loadRawDataBe16(kLoLButtonList7, tempSize);
+ _buttonList8 = (const int16 *)_staticres->loadRawDataBe16(kLoLButtonList8, tempSize);
- _autoMapStrings = _staticres->loadRawDataBe16(kLolMapStringId, _autoMapStringsSize);
+ _autoMapStrings = _staticres->loadRawDataBe16(kLoLMapStringId, tempSize);
- int tempSize;
- const uint8 *tmp = _staticres->loadRawData(kLolLegendData, tempSize);
+ const uint8 *tmp = _staticres->loadRawData(kLoLLegendData, tempSize);
uint8 entrySize = tempSize / 12;
tempSize /= entrySize;
if (tempSize) {
@@ -382,19 +326,21 @@ void LoLEngine::initStaticResource() {
_defaultLegendData[i].stringId = READ_LE_UINT16(tmp);
tmp += 2;
}
- _staticres->unloadId(kLolLegendData);
+ _staticres->unloadId(kLoLLegendData);
}
- tmp = _staticres->loadRawData(kLolMapCursorOvl, tempSize);
- _mapCursorOverlay = new uint8[tempSize];
- memcpy(_mapCursorOverlay, tmp, tempSize);
- _staticres->unloadId(kLolMapCursorOvl);
+ tmp = _staticres->loadRawData(kLoLMapCursorOvl, tempSize);
+ if (tmp) {
+ _mapCursorOverlay = new uint8[tempSize];
+ memcpy(_mapCursorOverlay, tmp, tempSize);
+ _staticres->unloadId(kLoLMapCursorOvl);
+ }
- _updateSpellBookCoords = _staticres->loadRawData(kLolSpellbookCoords, _updateSpellBookCoordsSize);
- _updateSpellBookAnimData = _staticres->loadRawData(kLolSpellbookAnim, _updateSpellBookAnimDataSize);
- _healShapeFrames = _staticres->loadRawData(kLolHealShapeFrames, _healShapeFramesSize);
+ _updateSpellBookCoords = _staticres->loadRawData(kLoLSpellbookCoords, tempSize);
+ _updateSpellBookAnimData = _staticres->loadRawData(kLoLSpellbookAnim, tempSize);
+ _healShapeFrames = _staticres->loadRawData(kLoLHealShapeFrames, tempSize);
- tmp = _staticres->loadRawData(kLolLightningDefs, tempSize);
+ tmp = _staticres->loadRawData(kLoLLightningDefs, tempSize);
if (tmp) {
_lightningProps = new LightningProperty[5];
for (int i = 0; i < 5; i++) {
@@ -402,10 +348,10 @@ void LoLEngine::initStaticResource() {
_lightningProps[i].frameDiv = tmp[(i << 2) + 1];
_lightningProps[i].sfxId = READ_LE_UINT16(&tmp[(i << 2) + 2]);
}
- _staticres->unloadId(kLolLightningDefs);
+ _staticres->unloadId(kLoLLightningDefs);
}
- _fireBallCoords = (const int16 *)_staticres->loadRawDataBe16(kLolFireballCoords, _fireBallCoordsSize);
+ _fireBallCoords = (const int16 *)_staticres->loadRawDataBe16(kLoLFireballCoords, tempSize);
_buttonCallbacks.clear();
_buttonCallbacks.reserve(95);
@@ -519,7 +465,7 @@ void GUI_LoL::initStaticData() {
if (_vm->gameFlags().isTalkie)
GUI_LOL_MENU(_mainMenu, 9, 0x4000, 0, 7, -1, -1, -1, -1);
- else
+ else
GUI_LOL_MENU(_mainMenu, 17, 0x4000, 0, 6, -1, -1, -1, -1);
GUI_LOL_MENU_ITEM(_mainMenu.item[0], 0x4001, 16, 23, 176, 15, 0, 0);
@@ -681,7 +627,7 @@ const ScreenDim Screen_LoL::_screenDimTable16C[] = {
const int Screen_LoL::_screenDimTableCount = ARRAYSIZE(Screen_LoL::_screenDimTable256C);
-const char * const LoLEngine::_languageExt[] = {
+const char *const LoLEngine::_languageExt[] = {
"ENG",
"FRE",
"GER"
@@ -818,6 +764,11 @@ const int8 LoLEngine::_mapCoords[12][4] = {
{ 3, 1, 3, 1 }, { -1, 6, -1, -8 }, { -7, -1, 5, -1 }
};
+const KyraRpgGUISettings LoLEngine::_guiSettings = {
+ { 144, 254, 74, 9, 80, { 0, 0 }, { 0, 0 }, { 0, 0 } },
+ { 136, 251, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
+};
+
const MistOfDoomAnimData LoLEngine::_mistAnimData[] = {
{ 0, 7, 7, 13, 155 },
{ 0, 16, 16, 17, 155 },
@@ -826,7 +777,7 @@ const MistOfDoomAnimData LoLEngine::_mistAnimData[] = {
{ 0, 16, 16, 17, 175 },
};
-const char * const LoLEngine::_outroShapeFileTable[] = {
+const char *const LoLEngine::_outroShapeFileTable[] = {
"AMAZON.SHP", "ARCHRSLG.SHP", "AVIANWRM.SHP", "BANDIT.SHP", "BOAR.SHP", "CABAL.SHP",
"GUARD.SHP", "HAG.SHP", "HORNET.SHP", "HURZELL.SHP", "IRONGRZR.SHP", "KNOWLES.SHP",
"LIZARD.SHP", "MANTHA.SHP", "MINOTAUR.SHP", "MORIBUND.SHP", "ORC.SHP", "ORCLDR.SHP",
diff --git a/engines/kyra/staticres_rpg.cpp b/engines/kyra/staticres_rpg.cpp
new file mode 100644
index 0000000000..a30cbf7d05
--- /dev/null
+++ b/engines/kyra/staticres_rpg.cpp
@@ -0,0 +1,100 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ *
+ */
+
+#include "kyra/resource.h"
+
+
+namespace Kyra {
+
+#if defined(ENABLE_EOB) || defined(ENABLE_LOL)
+const uint16 *StaticResource::loadRawDataBe16(int id, int &entries) {
+ return (const uint16 *)getData(id, kRawDataBe16, entries);
+}
+
+const uint32 *StaticResource::loadRawDataBe32(int id, int &entries) {
+ return (const uint32 *)getData(id, kRawDataBe32, entries);
+}
+
+bool StaticResource::loadRawDataBe16(Common::SeekableReadStream &stream, void *&ptr, int &size) {
+ size = stream.size() >> 1;
+
+ uint16 *r = new uint16[size];
+
+ for (int i = 0; i < size; i++)
+ r[i] = stream.readUint16BE();
+
+ ptr = r;
+ return true;
+}
+
+bool StaticResource::loadRawDataBe32(Common::SeekableReadStream &stream, void *&ptr, int &size) {
+ size = stream.size() >> 2;
+
+ uint32 *r = new uint32[size];
+
+ for (int i = 0; i < size; i++)
+ r[i] = stream.readUint32BE();
+
+ ptr = r;
+ return true;
+}
+
+void StaticResource::freeRawDataBe16(void *&ptr, int &size) {
+ uint16 *data = (uint16 *)ptr;
+ delete[] data;
+ ptr = 0;
+ size = 0;
+}
+
+void StaticResource::freeRawDataBe32(void *&ptr, int &size) {
+ uint32 *data = (uint32 *)ptr;
+ delete[] data;
+ ptr = 0;
+ size = 0;
+}
+
+const uint8 KyraRpgEngine::_dropItemDirIndex[] = { 0, 1, 2, 3, 1, 3, 0, 2, 3, 2, 1, 0, 2, 0, 3, 1 };
+
+void KyraRpgEngine::initStaticResource() {
+ int temp;
+ _dscShapeX = (const int16 *)_staticres->loadRawDataBe16(kRpgCommonDscX, temp);
+ _dscShapeIndex = (const int8 *)_staticres->loadRawData(kRpgCommonDscShapeIndex, temp);
+ _dscTileIndex = _staticres->loadRawData(kRpgCommonDscTileIndex, temp);
+ _dscDim1 = (const int8 *)_staticres->loadRawData(kRpgCommonDscDimData1, temp);
+ _dscDim2 = (const int8 *)_staticres->loadRawData(kRpgCommonDscDimData2, temp);
+ _dscUnk2 = _staticres->loadRawData(kRpgCommonDscUnk2, temp);
+ _dscBlockMap = _staticres->loadRawData(kRpgCommonDscBlockMap, temp);
+ _dscBlockIndex = (const int8 *)_staticres->loadRawData(kRpgCommonDscBlockIndex, temp);
+ _dscDimMap = _staticres->loadRawData(kRpgCommonDscDimMap, temp);
+ _dscDoorShpIndex = _staticres->loadRawData(kRpgCommonDscDoorShapeIndex, _dscDoorShpIndexSize);
+ _dscDoorY2 = _staticres->loadRawData(kRpgCommonDscDoorY2, temp);
+ _dscDoorFrameY1 = _staticres->loadRawData(kRpgCommonDscDoorFrameY1, temp);
+ _dscDoorFrameY2 = _staticres->loadRawData(kRpgCommonDscDoorFrameY2, temp);
+ _dscDoorFrameIndex1 = _staticres->loadRawData(kRpgCommonDscDoorFrameIndex1, temp);
+ _dscDoorFrameIndex2 = _staticres->loadRawData(kRpgCommonDscDoorFrameIndex2, temp);
+ _moreStrings = _staticres->loadStrings(kRpgCommonMoreStrings, temp);
+}
+
+#endif // (ENABLE_EOB || ENABLE_LOL)
+
+} // End of namespace Kyra
diff --git a/engines/kyra/text_lok.cpp b/engines/kyra/text_lok.cpp
index 0ee3574903..62bdf18816 100644
--- a/engines/kyra/text_lok.cpp
+++ b/engines/kyra/text_lok.cpp
@@ -188,7 +188,7 @@ int8 KyraEngine_LoK::getChatPartnerNum() {
for (int i = 1; i < 6; i++) {
if (_currentCharacter->sceneId == sceneTable[pos]) {
- partner = sceneTable[pos+1];
+ partner = sceneTable[pos + 1];
break;
}
pos += 2;
@@ -342,12 +342,12 @@ void KyraEngine_LoK::drawSentenceCommand(const char *sentence, int color) {
_currSentenceColor[2] = 0x3F;
_screen->setInterfacePalette(_screen->getPalette(1),
- _currSentenceColor[0], _currSentenceColor[1], _currSentenceColor[2]);
+ _currSentenceColor[0], _currSentenceColor[1], _currSentenceColor[2]);
}
} else if (_startSentencePalIndex != color || _fadeText != false) {
- _currSentenceColor[0] = _screen->getPalette(0)[765] = _screen->getPalette(0)[color*3+0];
- _currSentenceColor[1] = _screen->getPalette(0)[766] = _screen->getPalette(0)[color*3+1];
- _currSentenceColor[2] = _screen->getPalette(0)[767] = _screen->getPalette(0)[color*3+2];
+ _currSentenceColor[0] = _screen->getPalette(0)[765] = _screen->getPalette(0)[color * 3 + 0];
+ _currSentenceColor[1] = _screen->getPalette(0)[766] = _screen->getPalette(0)[color * 3 + 1];
+ _currSentenceColor[2] = _screen->getPalette(0)[767] = _screen->getPalette(0)[color * 3 + 2];
_screen->setScreenPalette(_screen->getPalette(0));
_startSentencePalIndex = color;
@@ -377,16 +377,15 @@ void KyraEngine_LoK::updateTextFade() {
for (int i = 0; i < 3; i++) {
if (_currSentenceColor[i] > 4)
_currSentenceColor[i] -= 4;
- else
- if (_currSentenceColor[i]) {
- _currSentenceColor[i] = 0;
- finished = true;
- }
+ else if (_currSentenceColor[i]) {
+ _currSentenceColor[i] = 0;
+ finished = true;
+ }
}
if (_flags.platform == Common::kPlatformAmiga) {
_screen->setInterfacePalette(_screen->getPalette(1),
- _currSentenceColor[0], _currSentenceColor[1], _currSentenceColor[2]);
+ _currSentenceColor[0], _currSentenceColor[1], _currSentenceColor[2]);
} else {
_screen->getPalette(0)[765] = _currSentenceColor[0];
_screen->getPalette(0)[766] = _currSentenceColor[1];
diff --git a/engines/kyra/text_lol.cpp b/engines/kyra/text_lol.cpp
index 1c2167b892..ee42d6db92 100644
--- a/engines/kyra/text_lol.cpp
+++ b/engines/kyra/text_lol.cpp
@@ -32,36 +32,18 @@
namespace Kyra {
-TextDisplayer_LoL::TextDisplayer_LoL(LoLEngine *vm, Screen_LoL *screen) : _vm(vm), _screen(screen),
- _scriptTextParameter(0), _lineCount(0), _printFlag(false), _lineWidth(0), _numCharsTotal(0),
- _numCharsLeft(0), _numCharsPrinted(0), _sjisLineBreakFlag(false) {
+TextDisplayer_LoL::TextDisplayer_LoL(LoLEngine *engine, Screen_LoL *screenLoL) : TextDisplayer_rpg(engine, screenLoL),
+ _vm(engine), _screen(screenLoL), _scriptTextParameter(0) {
memset(_stringParameters, 0, 15 * sizeof(char *));
_buffer = new char[600];
memset(_buffer, 0, 600);
- _dialogueBuffer = new char[1024];
- memset(_dialogueBuffer, 0, 1024);
-
- _currentLine = new char[85];
- memset(_currentLine, 0, 85);
-
- _textDimData = new TextDimData[_screen->screenDimTableCount()];
-
- for (int i = 0; i < _screen->screenDimTableCount(); i++){
- const ScreenDim *d = _screen->getScreenDim(i);
- _textDimData[i].color1 = d->unk8;
- _textDimData[i].color2 = d->unkA;
- _textDimData[i].line = d->unkC;
- _textDimData[i].column = d->unkE;
- }
+ _waitButtonSpace = 0;
}
TextDisplayer_LoL::~TextDisplayer_LoL() {
delete[] _buffer;
- delete[] _dialogueBuffer;
- delete[] _currentLine;
- delete[] _textDimData;
}
void TextDisplayer_LoL::setupField(bool mode) {
@@ -151,20 +133,6 @@ void TextDisplayer_LoL::expandField() {
}
}
-int TextDisplayer_LoL::clearDim(int dim) {
- int res = _screen->curDimIndex();
- _screen->setScreenDim(dim);
- _textDimData[dim].color1 = _screen->_curDim->unk8;
- _textDimData[dim].color2 = _screen->_curDim->unkA;
- clearCurDim();
- return res;
-}
-
-void TextDisplayer_LoL::resetDimTextPositions(int dim) {
- _textDimData[dim].column = 0;
- _textDimData[dim].line = 0;
-}
-
void TextDisplayer_LoL::printDialogueText(int dim, char *str, EMCState *script, const uint16 *paramList, int16 paramIndex) {
int oldDim = 0;
@@ -201,10 +169,9 @@ void TextDisplayer_LoL::printDialogueText(int dim, char *str, EMCState *script,
displayText(_dialogueBuffer);
_screen->setScreenDim(oldDim);
- _lineCount = 0;
_screen->setCurPage(cp);
_screen->setFont(of);
-
+ _lineCount = 0;
_vm->_fadeText = false;
}
@@ -336,7 +303,7 @@ void TextDisplayer_LoL::preprocessString(char *str, EMCState *script, const uint
switch (para) {
case 'a':
- snprintf(dst, 7, "%d", _scriptTextParameter);
+ strcpy(dst, Common::String::format("%d", _scriptTextParameter).c_str());
dst += strlen(dst);
break;
@@ -354,7 +321,7 @@ void TextDisplayer_LoL::preprocessString(char *str, EMCState *script, const uint
case 'd':
case 'u':
case 'x':
- snprintf(dst, 7, "%d", script ? script->stack[script->sp + paramIndex] : paramList[paramIndex]);
+ strcpy(dst, Common::String::format("%d", script ? script->stack[script->sp + paramIndex] : paramList[paramIndex]).c_str());
dst += strlen(dst);
break;
@@ -366,465 +333,17 @@ void TextDisplayer_LoL::preprocessString(char *str, EMCState *script, const uint
*dst = 0;
}
-void TextDisplayer_LoL::displayText(char *str, ...) {
- const bool isPc98 = (_vm->gameFlags().platform == Common::kPlatformPC98);
-
- _printFlag = false;
-
- _lineWidth = 0;
- _numCharsLeft = 0;
- _numCharsPrinted = 0;
-
- _tempString1 = str;
- _tempString2 = 0;
-
- _currentLine[0] = 0;
- memset(_ctrl, 0, 3);
-
- char c = parseCommand();
-
- va_list args;
- va_start(args, str);
-
- const ScreenDim *sd = _screen->_curDim;
- int sdx = _screen->curDimIndex();
-
- bool pc98PrintFlag = (isPc98 && (sdx == 3 || sdx == 4 || sdx == 5 || sdx == 15)) ? true : false;
- uint16 charsPerLine = (sd->w << 3) / (_screen->getFontWidth() + _screen->_charWidth);
-
- while (c) {
- char a = tolower(_ctrl[1]);
-
- if (!_tempString2 && c == '%') {
- if (a == 'd') {
- snprintf(_scriptParaString, 11, "%d", va_arg(args, int));
- _tempString2 = _scriptParaString;
- } else if (a == 's') {
- _tempString2 = va_arg(args, char *);
- } else {
- break;
- }
-
- _ctrl[0] = _ctrl[2];
- _ctrl[2] = _ctrl[1] = 0;
- c = parseCommand();
- }
-
- if (isPc98) {
- uint8 cu = (uint8) c;
- if (cu >= 0xE0 || (cu > 0x80 && cu < 0xA0)) {
- _currentLine[_numCharsLeft++] = c;
- _currentLine[_numCharsLeft++] = parseCommand();
- _currentLine[_numCharsLeft] = '\0';
- _lineWidth += 8;
- if ((_textDimData[sdx].column + _lineWidth) > (sd->w << 3))
- printLine(_currentLine);
- c = parseCommand();
- continue;
- }
- }
-
- uint16 dv = _textDimData[sdx].column / (_screen->getFontWidth() + _screen->_charWidth);
-
- switch (c - 1) {
- case 0:
- printLine(_currentLine);
- textPageBreak();
- _numCharsPrinted = 0;
- break;
-
- case 1:
- printLine(_currentLine);
- _textDimData[sdx].color2 = parseCommand();
- break;
-
- case 5:
- printLine(_currentLine);
- _textDimData[sdx].color1 = parseCommand();
- break;
-
- case 8:
- printLine(_currentLine);
- dv = _textDimData[sdx].column / (_screen->getFontWidth() + _screen->_charWidth);
- dv = ((dv + 8) & 0xfff8) - 1;
- if (dv >= charsPerLine)
- dv = 0;
- _textDimData[sdx].column = (_screen->getFontWidth() + _screen->_charWidth) * dv;
- break;
-
- case 11:
- // TODO (UNUSED)
- break;
-
- case 12:
- if (isPc98)
- _sjisLineBreakFlag = true;
- printLine(_currentLine);
- _sjisLineBreakFlag = false;
- _lineCount++;
- _textDimData[sdx].column = 0;
- _textDimData[sdx].line++;
- break;
-
- case 18:
- // TODO (UNUSED)
- break;
-
- case 23:
- // TODO (UNUSED)
- break;
-
- case 24:
- // TODO (UNUSED)
- break;
-
- case 26:
- // TODO (UNUSED)
- break;
-
- case 28:
- // TODO (UNUSED)
- break;
-
- default:
- _lineWidth += (pc98PrintFlag ? 4 : _screen->getCharWidth((uint8)c));
- _currentLine[_numCharsLeft++] = c;
- _currentLine[_numCharsLeft] = 0;
-
- if ((_textDimData[sdx].column + _lineWidth) > (sd->w << 3))
- printLine(_currentLine);
- }
-
- c = parseCommand();
- }
-
- va_end(args);
-
- if (_numCharsLeft)
- printLine(_currentLine);
-}
-
-char TextDisplayer_LoL::parseCommand() {
- if (!_ctrl[1])
- readNextPara();
-
- char res = _ctrl[1];
- _ctrl[1] = _ctrl[2];
- _ctrl[2] = 0;
-
- if (!_ctrl[1])
- readNextPara();
-
- return res;
+KyraRpgEngine *TextDisplayer_LoL::vm() {
+ return _vm;
}
-void TextDisplayer_LoL::readNextPara() {
- char d = 0;
-
- if (_tempString2) {
- if (*_tempString2) {
- d = *_tempString2++;
- } else {
- _tempString2 = 0;
- d = _ctrl[0];
- }
- }
-
- if (!d && _tempString1) {
- if (*_tempString1)
- d = *_tempString1++;
- else
- _tempString1 = 0;
- }
-
- _ctrl[1] = d;
- _ctrl[2] = 0;
-}
-
-void TextDisplayer_LoL::printLine(char *str) {
- const bool isPc98 = (_vm->gameFlags().platform == Common::kPlatformPC98);
- const ScreenDim *sd = _screen->_curDim;
- int sdx = _screen->curDimIndex();
- bool pc98PrintFlag = (isPc98 && (sdx == 3 || sdx == 4 || sdx == 5 || sdx == 15)) ? true : false;
-
- int fh = (_screen->_currentFont == Screen::FID_SJIS_FNT) ? 9 : (_screen->getFontHeight() + _screen->_charOffset);
- int lines = (sd->h - _screen->_charOffset) / fh;
-
- while (_textDimData[sdx].line >= lines) {
- if (lines <= _lineCount) {
- _lineCount = 0;
- textPageBreak();
- _numCharsPrinted = 0;
- }
-
- int h1 = ((sd->h / fh) - 1) * fh;
- int h2 = sd->h - fh;
-
- if (h2)
- _screen->copyRegion(sd->sx << 3, sd->sy + fh, sd->sx << 3, sd->sy, sd->w << 3, h2, _screen->_curPage, _screen->_curPage, Screen::CR_NO_P_CHECK);
-
- _screen->fillRect(sd->sx << 3, sd->sy + h1, (sd->sx + sd->w - 1) << 3, sd->sy + sd->h - 1, _textDimData[sdx].color2);
- if (_textDimData[sdx].line)
- _textDimData[sdx].line--;
- }
-
- int x1 = (sd->sx << 3) + _textDimData[sdx].column;
- int y = sd->sy + (pc98PrintFlag ? (_textDimData[sdx].line << 3) : (fh * _textDimData[sdx].line));
- int w = sd->w << 3;
- int lw = _lineWidth;
- int s = _numCharsLeft;
- char c = 0;
-
- if (pc98PrintFlag) {
- bool ct = true;
-
- if ((lw + _textDimData[sdx].column) > w) {
- if ((lines - 1) <= _lineCount)
- // cut off line to leave space for "MORE" button
- w -= 80;
- } else {
- if (!_sjisLineBreakFlag || (_lineCount + 1 < lines - 1))
- ct = false;
- else
- // cut off line to leave space for "MORE" button
- w -= 80;
- }
-
- if (ct) {
- w -= _textDimData[sdx].column;
-
- int n2 = 0;
- int n1 = (w / 4) - 1;
-
- while (n2 < n1 && n2 < s) {
- c = str[n2];
- uint8 cu = (uint8) c;
- if (cu >= 0xE0 || (cu > 0x80 && cu < 0xA0))
- n2++;
- n2++;
- }
- s = n2;
- }
- } else {
- if ((lw + _textDimData[sdx].column) > w) {
- if ((lines - 1) <= _lineCount)
- // cut off line to leave space for "MORE" button
- w -= (10 * (_screen->getFontWidth() + _screen->_charWidth));
-
- w -= _textDimData[sdx].column;
-
- int n2 = 0;
- int n1 = s - 1;
-
- while (n1 > 0) {
- //cut off line after last space
- c = str[n1];
-
- lw -= _screen->getCharWidth((uint8)c);
-
- if (!n2 && lw <= w)
- n2 = n1;
-
- if (n2 && c == ' ') {
- s = n1;
- _printFlag = false;
- break;
- }
- n1--;
- }
-
- if (!n1) {
- if (_textDimData[sdx].column && !_printFlag) {
- s = lw = 0;
- _printFlag = true;
- } else {
- s = n2;
- }
- }
- }
- }
-
- c = str[s];
- str[s] = 0;
-
- uint8 col = _textDimData[sdx].color1;
- if (isPc98 && (sdx == 2 || sdx == 3 || sdx == 4 || sdx == 5 || sdx == 15)) {
- switch (_textDimData[sdx].color1) {
- case 0x88:
- col = 0x41;
- break;
- case 0x55:
- col = 0x81;
- break;
- case 0xaa:
- col = 0x21;
- break;
- case 0x99:
- col = 0xa1;
- break;
- case 0x33:
- col = 0xe1;
- break;
- case 0x18:
- col = 0x61;
- break;
- default:
- col = 1;
- break;
- }
- _screen->printText(str, x1 & ~3, (y + 8) & ~7, col, 0);
- } else {
- _screen->printText(str, x1, y, col, _textDimData[sdx].color2);
- }
-
- _textDimData[sdx].column += lw;
- _numCharsPrinted += strlen(str);
-
- str[s] = c;
-
- if (c == ' ')
- s++;
-
- if (str[s] == ' ')
- s++;
-
- uint32 len = strlen(&str[s]);
- for (uint32 i = 0; i < len; i++)
- str[i] = str[s + i];
- str[len] = 0;
-
- _numCharsLeft = strlen(str);
- _lineWidth = pc98PrintFlag ? (_numCharsLeft << 2) : _screen->getTextWidth(str);
-
- if (!_numCharsLeft && _textDimData[sdx].column < (sd->w << 3))
- return;
-
- _textDimData[sdx].column = 0;
- _textDimData[sdx].line++;
- _lineCount++;
-
- printLine(str);
+Screen *TextDisplayer_LoL::screen() {
+ return _screen;
}
void TextDisplayer_LoL::textPageBreak() {
- int cp = _screen->setCurPage(0);
- Screen::FontId cf = _screen->setFont(_vm->gameFlags().use16ColorMode ? Screen::FID_SJIS_FNT : Screen::FID_6_FNT);
-
- _vm->_timer->pauseSingleTimer(11, true);
-
- _vm->_fadeText = false;
- int resetPortraitAfterSpeechAnim = 0;
- int updatePortraitSpeechAnimDuration = 0;
-
- if (_vm->_updateCharNum != -1) {
- resetPortraitAfterSpeechAnim = _vm->_resetPortraitAfterSpeechAnim;
- _vm->_resetPortraitAfterSpeechAnim = 0;
- updatePortraitSpeechAnimDuration = _vm->_updatePortraitSpeechAnimDuration;
- if (_vm->_updatePortraitSpeechAnimDuration > 36)
- _vm->_updatePortraitSpeechAnimDuration = 36;
- }
-
- uint32 speechPartTime = 0;
- if (_vm->speechEnabled() && _vm->_activeVoiceFileTotalTime && _numCharsTotal)
- speechPartTime = _vm->_system->getMillis() + ((_numCharsPrinted * _vm->_activeVoiceFileTotalTime) / _numCharsTotal);
-
- const ScreenDim *dim = _screen->getScreenDim(_screen->curDimIndex());
-
- int x = ((dim->sx + dim->w) << 3) - 77;
- int y = 0;
-
- if (_vm->_needSceneRestore && (_vm->_updateFlags & 2)) {
- if (_vm->_currentControlMode || !(_vm->_updateFlags & 2)) {
- y = dim->sy + dim->h - 5;
- } else {
- x += 6;
- y = dim->sy + dim->h - 2;
- }
- } else {
- y = dim->sy + dim->h - 10;
- }
-
- char *txt = _vm->getLangString(0x4073);
- if (_vm->gameFlags().use16ColorMode) {
- _vm->gui_drawBox(x + 8, (y & ~7) - 1, 66, 10, 0xee, 0xcc, -1);
- _vm->_screen->printText(txt, (x + 37 - (strlen(txt) << 1) + 4) & ~3, (y + 2) & ~7, 0xc1, 0);
- } else {
- _vm->gui_drawBox(x, y, 74, 9, 136, 251, -1);
- _vm->_screen->printText(txt, x + 37 - (_vm->_screen->getTextWidth(txt) >> 1), y + 2, 144, 0);
- }
-
- _vm->removeInputTop();
-
- bool loop = true;
- bool target = false;
-
- do {
- int inputFlag = _vm->checkInput(0, false) & 0xFF;
- _vm->removeInputTop();
-
- while (!inputFlag) {
- _vm->update();
-
- if (_vm->speechEnabled()) {
- if (((_vm->_system->getMillis() > speechPartTime) || (_vm->snd_updateCharacterSpeech() != 2)) && speechPartTime) {
- loop = false;
- inputFlag = _vm->_keyMap[Common::KEYCODE_RETURN];
- break;
- }
- }
-
- inputFlag = _vm->checkInput(0, false) & 0xFF;
- _vm->removeInputTop();
- }
-
- _vm->gui_notifyButtonListChanged();
-
- if (inputFlag == _vm->_keyMap[Common::KEYCODE_SPACE] || inputFlag == _vm->_keyMap[Common::KEYCODE_RETURN]) {
- loop = false;
- } else if (inputFlag == 199 || inputFlag == 201) {
- if (_vm->posWithinRect(_vm->_mouseX, _vm->_mouseY, x, y, x + 74, y + 9))
- target = true;
- } else if (inputFlag == 200 || inputFlag == 202) {
- if (target)
- loop = false;
- }
- } while (loop);
-
-
- if (_vm->gameFlags().use16ColorMode)
- _screen->fillRect(x + 8, y, x + 57, y + 9, _textDimData[_screen->curDimIndex()].color2);
- else
- _screen->fillRect(x, y, x + 73, y + 8, _textDimData[_screen->curDimIndex()].color2);
-
- clearCurDim();
-
- _vm->_timer->pauseSingleTimer(11, false);
-
- if (_vm->_updateCharNum != -1) {
- _vm->_resetPortraitAfterSpeechAnim = resetPortraitAfterSpeechAnim;
- if (updatePortraitSpeechAnimDuration > 36)
- updatePortraitSpeechAnimDuration -= 36;
- else
- updatePortraitSpeechAnimDuration >>= 1;
-
- _vm->_updatePortraitSpeechAnimDuration = updatePortraitSpeechAnimDuration;
- }
-
- _screen->setFont(cf);
- _screen->setCurPage(cp);
- _vm->removeInputTop();
-}
-
-void TextDisplayer_LoL::clearCurDim() {
- int d = _screen->curDimIndex();
- const ScreenDim *tmp = _screen->getScreenDim(d);
- if (_vm->gameFlags().use16ColorMode) {
- _screen->fillRect(tmp->sx << 3, tmp->sy, ((tmp->sx + tmp->w) << 3) - 2, (tmp->sy + tmp->h) - 2, _textDimData[d].color2);
- } else
- _screen->fillRect(tmp->sx << 3, tmp->sy, ((tmp->sx + tmp->w) << 3) - 1, (tmp->sy + tmp->h) - 1, _textDimData[d].color2);
-
- _lineCount = 0;
- _textDimData[d].column = _textDimData[d].line = 0;
+ strcpy(_pageBreakString, _vm->getLangString(0x4073));
+ TextDisplayer_rpg::textPageBreak();
}
} // End of namespace Kyra
diff --git a/engines/kyra/text_lol.h b/engines/kyra/text_lol.h
index 3e59bc90fe..e2b10e8d4d 100644
--- a/engines/kyra/text_lol.h
+++ b/engines/kyra/text_lol.h
@@ -20,80 +20,51 @@
*
*/
-#ifdef ENABLE_LOL
-
#ifndef KYRA_TEXT_LOL_H
#define KYRA_TEXT_LOL_H
+#if defined(ENABLE_EOB) || defined(ENABLE_LOL)
+#include "kyra/text_rpg.h"
+#endif
#include "common/scummsys.h"
+#ifdef ENABLE_LOL
+
namespace Kyra {
class Screen_LoL;
class LoLEngine;
struct EMCState;
-class TextDisplayer_LoL {
-friend class LoLEngine;
+class TextDisplayer_LoL : public TextDisplayer_rpg {
public:
- TextDisplayer_LoL(LoLEngine *vm, Screen_LoL *screen);
+ TextDisplayer_LoL(LoLEngine *engine, Screen_LoL *screenLoL);
~TextDisplayer_LoL();
void setupField(bool mode);
void expandField();
- int clearDim(int dim);
- void resetDimTextPositions(int dim);
-
void printDialogueText(int dim, char *str, EMCState *script, const uint16 *paramList, int16 paramIndex);
void printMessage(uint16 type, const char *str, ...) GCC_PRINTF(3, 4);
int16 _scriptTextParameter;
private:
- void displayText(char *str, ...);
- char parseCommand();
- void readNextPara();
- void printLine(char *str);
+ virtual KyraRpgEngine *vm();
+ virtual Screen *screen();
+
void preprocessString(char *str, EMCState *script, const uint16 *paramList, int16 paramIndex);
void textPageBreak();
- void clearCurDim();
-
char *_stringParameters[15];
char *_buffer;
- char *_dialogueBuffer;
- char *_tempString1;
- char *_tempString2;
- char *_currentLine;
- char _ctrl[3];
-
- char _scriptParaString[11];
-
- uint16 _lineWidth;
- int _lineCount;
- uint32 _numCharsTotal;
- uint32 _numCharsLeft;
- uint32 _numCharsPrinted;
-
- bool _printFlag;
- bool _sjisLineBreakFlag;
LoLEngine *_vm;
Screen_LoL *_screen;
-
- struct TextDimData {
- uint8 color1;
- uint8 color2;
- uint16 column;
- uint8 line;
- };
-
- TextDimData *_textDimData;
};
} // End of namespace Kyra
-#endif
-
#endif // ENABLE_LOL
+
+#endif
diff --git a/engines/kyra/text_rpg.cpp b/engines/kyra/text_rpg.cpp
new file mode 100644
index 0000000000..52c14c7223
--- /dev/null
+++ b/engines/kyra/text_rpg.cpp
@@ -0,0 +1,671 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ *
+ */
+
+#if defined(ENABLE_EOB) || defined(ENABLE_LOL)
+
+#include "kyra/kyra_rpg.h"
+#include "kyra/timer.h"
+
+#include "common/system.h"
+
+namespace Kyra {
+
+enum {
+ kEoBTextBufferSize = 2048
+};
+
+TextDisplayer_rpg::TextDisplayer_rpg(KyraRpgEngine *engine, Screen *scr) : _vm(engine), _screen(scr),
+ _lineCount(0), _printFlag(false), _lineWidth(0), _numCharsTotal(0), _allowPageBreak(true),
+ _numCharsLeft(0), _numCharsPrinted(0), _sjisLineBreakFlag(false), _waitButtonMode(1) {
+
+ _dialogueBuffer = new char[kEoBTextBufferSize];
+ memset(_dialogueBuffer, 0, kEoBTextBufferSize);
+
+ _currentLine = new char[85];
+ memset(_currentLine, 0, 85);
+
+ _textDimData = new TextDimData[_screen->screenDimTableCount()];
+
+ for (int i = 0; i < _screen->screenDimTableCount(); i++) {
+ const ScreenDim *d = _screen->getScreenDim(i);
+ _textDimData[i].color1 = d->unk8;
+ _textDimData[i].color2 = d->unkA;
+ _textDimData[i].line = d->unkC;
+ _textDimData[i].column = d->unkE;
+ }
+
+ _table1 = new char[128];
+ memset(_table1, 0, 128);
+ _table2 = new char[16];
+ memset(_table2, 0, 16);
+
+ _waitButtonSpace = 0;
+}
+
+TextDisplayer_rpg::~TextDisplayer_rpg() {
+ delete[] _dialogueBuffer;
+ delete[] _currentLine;
+ delete[] _textDimData;
+ delete[] _table1;
+ delete[] _table2;
+}
+
+void TextDisplayer_rpg::setupField(int dim, bool mode) {
+ setPageBreakFlag();
+
+ _textDimData[dim].color2 = _vm->guiSettings()->colors.fill;
+ _screen->setScreenDim(dim);
+
+ if (mode)
+ clearCurDim();
+ else
+ resetDimTextPositions(dim);
+}
+
+void TextDisplayer_rpg::resetDimTextPositions(int dim) {
+ _textDimData[dim].column = 0;
+ _textDimData[dim].line = 0;
+}
+
+void TextDisplayer_rpg::resetPageBreakString() {
+ if (vm()->_moreStrings)
+ strcpy(_pageBreakString, vm()->_moreStrings[0]);
+}
+
+void TextDisplayer_rpg::setPageBreakFlag() {
+ _allowPageBreak = true;
+ _lineCount = 0;
+}
+
+void TextDisplayer_rpg::removePageBreakFlag() {
+ _allowPageBreak = false;
+}
+
+void TextDisplayer_rpg::displayText(char *str, ...) {
+ const bool isPc98 = (_vm->gameFlags().platform == Common::kPlatformPC98);
+
+ _printFlag = false;
+
+ _lineWidth = 0;
+ _numCharsLeft = 0;
+ _numCharsPrinted = 0;
+
+ _tempString1 = str;
+ _tempString2 = 0;
+
+ _currentLine[0] = 0;
+
+ memset(_ctrl, 0, 3);
+
+ char c = parseCommand();
+
+ va_list args;
+ va_start(args, str);
+
+ const ScreenDim *sd = _screen->_curDim;
+ int sdx = _screen->curDimIndex();
+
+ bool pc98PrintFlag = (isPc98 && (sdx == 3 || sdx == 4 || sdx == 5 || sdx == 15)) ? true : false;
+ uint16 charsPerLine = (sd->w << 3) / (_screen->getFontWidth() + _screen->_charWidth);
+
+ while (c) {
+ char a = tolower(_ctrl[1]);
+
+ if (!_tempString2 && c == '%') {
+ if (a == 'd') {
+ strcpy(_scriptParaString, Common::String::format("%d", va_arg(args, int)).c_str());
+ _tempString2 = _scriptParaString;
+ } else if (a == 's') {
+ _tempString2 = va_arg(args, char *);
+ } else {
+ break;
+ }
+
+ _ctrl[0] = _ctrl[2];
+ _ctrl[2] = _ctrl[1] = 0;
+ c = parseCommand();
+ }
+
+ if (isPc98) {
+ uint8 cu = (uint8) c;
+ if (cu >= 0xE0 || (cu > 0x80 && cu < 0xA0)) {
+ _currentLine[_numCharsLeft++] = c;
+ _currentLine[_numCharsLeft++] = parseCommand();
+ _currentLine[_numCharsLeft] = '\0';
+ _lineWidth += 8;
+ if ((_textDimData[sdx].column + _lineWidth) > (sd->w << 3))
+ printLine(_currentLine);
+ c = parseCommand();
+ continue;
+ }
+ }
+
+ uint16 dv = _textDimData[sdx].column / (_screen->getFontWidth() + _screen->_charWidth);
+
+ switch (c - 1) {
+ case 0:
+ printLine(_currentLine);
+ textPageBreak();
+ _numCharsPrinted = 0;
+ break;
+
+ case 1:
+ printLine(_currentLine);
+ _textDimData[sdx].color2 = parseCommand();
+ break;
+
+ case 5:
+ printLine(_currentLine);
+ _textDimData[sdx].color1 = parseCommand();
+ break;
+
+ case 8:
+ printLine(_currentLine);
+ dv = _textDimData[sdx].column / (_screen->getFontWidth() + _screen->_charWidth);
+ dv = ((dv + 8) & 0xfff8) - 1;
+ if (dv >= charsPerLine)
+ dv = 0;
+ _textDimData[sdx].column = (_screen->getFontWidth() + _screen->_charWidth) * dv;
+ break;
+
+ case 12:
+ if (isPc98)
+ _sjisLineBreakFlag = true;
+ printLine(_currentLine);
+ _sjisLineBreakFlag = false;
+ _lineCount++;
+ _textDimData[sdx].column = 0;
+ _textDimData[sdx].line++;
+ break;
+
+ case 11: case 18: case 23:
+ case 24: case 26: case 28:
+ // These are at the time of writing this comment not known to be
+ // used. In case there is some use of them in some odd version
+ // we display this warning here.
+ warning("TextDisplayer_rpg::displayText: Triggered stub function %d", c - 1);
+ break;
+
+ default:
+ if (_vm->game() == GI_LOL || (unsigned char)c > 30) {
+ _lineWidth += (pc98PrintFlag ? 4 : _screen->getCharWidth((uint8)c));
+ _currentLine[_numCharsLeft++] = c;
+ _currentLine[_numCharsLeft] = 0;
+
+ if ((_textDimData[sdx].column + _lineWidth) > (sd->w << 3))
+ printLine(_currentLine);
+ }
+ }
+
+ c = parseCommand();
+ }
+
+ va_end(args);
+
+ if (_numCharsLeft)
+ printLine(_currentLine);
+}
+
+char TextDisplayer_rpg::parseCommand() {
+ if (!_ctrl[1])
+ readNextPara();
+
+ char res = _ctrl[1];
+ _ctrl[1] = _ctrl[2];
+ _ctrl[2] = 0;
+
+ if (!_ctrl[1])
+ readNextPara();
+
+ return res;
+}
+
+void TextDisplayer_rpg::readNextPara() {
+ char c = 0;
+ char d = 0;
+
+ if (_tempString2) {
+ if (*_tempString2) {
+ d = *_tempString2++;
+ } else {
+ _tempString2 = 0;
+ d = _ctrl[0];
+ }
+ }
+
+ if (!d && _tempString1) {
+ if (*_tempString1)
+ d = *_tempString1++;
+ else
+ _tempString1 = 0;
+ }
+
+ // This seems to be some sort of character conversion mechanism. The original doesn't make any use of it, however.
+ // All necessary conversions take place somewhere else. This code actually causes issues if the character conversions
+ // don't take place before calling displayText(). So we disable it for now. If some (not yet supported) localized
+ // versions depend on this code we'll have to look at this again.
+#if 0
+ if ((_vm->game() != GI_LOL) && (d & 0x80)) {
+ d &= 0x7f;
+ c = d & 7;
+ d = (d & 0x78) >> 3;
+ uint8 l = d;
+ c = _table1[(l << 3) + c];
+ d = _table2[l];
+ }
+#endif
+
+ _ctrl[1] = d;
+ _ctrl[2] = c;
+}
+
+void TextDisplayer_rpg::printLine(char *str) {
+ const bool isPc98 = (_vm->gameFlags().platform == Common::kPlatformPC98);
+ const ScreenDim *sd = _screen->_curDim;
+ int sdx = _screen->curDimIndex();
+ bool pc98PrintFlag = (isPc98 && (sdx == 3 || sdx == 4 || sdx == 5 || sdx == 15)) ? true : false;
+
+ int fh = (_screen->_currentFont == Screen::FID_SJIS_FNT) ? 9 : (_screen->getFontHeight() + _screen->_charOffset);
+ int lines = (sd->h - _screen->_charOffset) / fh;
+
+ while (_textDimData[sdx].line >= lines) {
+ if ((lines - _waitButtonSpace) <= _lineCount && _allowPageBreak) {
+ _lineCount = 0;
+ textPageBreak();
+ _numCharsPrinted = 0;
+ }
+
+ int h1 = ((sd->h / fh) - 1) * fh;
+ int h2 = sd->h - fh;
+
+ if (h2)
+ _screen->copyRegion(sd->sx << 3, sd->sy + fh, sd->sx << 3, sd->sy, sd->w << 3, h2, _screen->_curPage, _screen->_curPage, Screen::CR_NO_P_CHECK);
+
+ _screen->fillRect(sd->sx << 3, sd->sy + h1, ((sd->sx + sd->w) << 3) - 1, sd->sy + sd->h - 1, _textDimData[sdx].color2);
+ if (_textDimData[sdx].line)
+ _textDimData[sdx].line--;
+ }
+
+ int x1 = (sd->sx << 3) + _textDimData[sdx].column;
+ int y = sd->sy + (pc98PrintFlag ? (_textDimData[sdx].line << 3) : (fh * _textDimData[sdx].line));
+ int w = sd->w << 3;
+ int lw = _lineWidth;
+ int s = _numCharsLeft;
+ char c = 0;
+
+ if (pc98PrintFlag) {
+ bool ct = true;
+
+ if ((lw + _textDimData[sdx].column) > w) {
+ if ((lines - 1 - (_waitButtonSpace << 1)) <= _lineCount)
+ // cut off line to leave space for "MORE" button
+ w -= vm()->guiSettings()->buttons.waitReserve;
+ } else {
+ if (!_sjisLineBreakFlag || (_lineCount + 1 < lines - 1))
+ ct = false;
+ else
+ // cut off line to leave space for "MORE" button
+ w -= vm()->guiSettings()->buttons.waitReserve;
+ }
+
+ if (ct) {
+ w -= _textDimData[sdx].column;
+
+ int n2 = 0;
+ int n1 = (w / 4) - 1;
+
+ while (n2 < n1 && n2 < s) {
+ c = str[n2];
+ uint8 cu = (uint8) c;
+ if (cu >= 0xE0 || (cu > 0x80 && cu < 0xA0))
+ n2++;
+ n2++;
+ }
+ s = n2;
+ }
+ } else {
+ if ((lw + _textDimData[sdx].column) > w) {
+ if ((lines - 1) <= _lineCount && _allowPageBreak)
+ // cut off line to leave space for "MORE" button
+ w -= vm()->guiSettings()->buttons.waitReserve;
+
+ w -= _textDimData[sdx].column;
+
+ int n2 = 0;
+ int n1 = s - 1;
+
+ while (n1 > 0) {
+ //cut off line after last space
+ c = str[n1];
+
+ lw -= _screen->getCharWidth((uint8)c);
+
+ if (!n2 && lw <= w)
+ n2 = n1;
+
+ if (n2 && c == ' ') {
+ s = n1;
+ _printFlag = false;
+ break;
+ }
+ n1--;
+ }
+
+ if (!n1) {
+ if (_textDimData[sdx].column && !_printFlag) {
+ s = lw = 0;
+ _printFlag = true;
+ } else {
+ s = n2;
+ }
+ }
+ }
+ }
+
+ c = str[s];
+ str[s] = 0;
+
+ uint8 col = _textDimData[sdx].color1;
+ if (isPc98 && (sdx == 2 || sdx == 3 || sdx == 4 || sdx == 5 || sdx == 15)) {
+ switch (_textDimData[sdx].color1) {
+ case 0x88:
+ col = 0x41;
+ break;
+ case 0x55:
+ col = 0x81;
+ break;
+ case 0xaa:
+ col = 0x21;
+ break;
+ case 0x99:
+ col = 0xa1;
+ break;
+ case 0x33:
+ col = 0xe1;
+ break;
+ case 0x18:
+ col = 0x61;
+ break;
+ default:
+ col = 1;
+ break;
+ }
+ _screen->printText(str, x1 & ~3, (y + 8) & ~7, col, 0);
+ } else {
+ _screen->printText(str, x1, y, col, _textDimData[sdx].color2);
+ }
+
+ _textDimData[sdx].column += lw;
+ _numCharsPrinted += strlen(str);
+
+ str[s] = c;
+
+ if (c == ' ')
+ s++;
+
+ if (str[s] == ' ')
+ s++;
+
+ uint32 len = strlen(&str[s]);
+ for (uint32 i = 0; i < len; i++)
+ str[i] = str[s + i];
+ str[len] = 0;
+
+ _numCharsLeft = strlen(str);
+ _lineWidth = pc98PrintFlag ? (_numCharsLeft << 2) : _screen->getTextWidth(str);
+
+ if (!_numCharsLeft && _textDimData[sdx].column < (sd->w << 3))
+ return;
+
+ _textDimData[sdx].column = 0;
+ _textDimData[sdx].line++;
+ _lineCount++;
+
+ printLine(str);
+}
+
+void TextDisplayer_rpg::printDialogueText(int stringId, const char *pageBreakString) {
+ const char *str = (const char *)(_screen->getCPagePtr(5) + READ_LE_UINT16(&_screen->getCPagePtr(5)[(stringId - 1) << 1]));
+ assert(strlen(str) < kEoBTextBufferSize);
+ Common::strlcpy(_dialogueBuffer, str, kEoBTextBufferSize);
+
+ displayText(_dialogueBuffer);
+
+ if (pageBreakString) {
+ if (pageBreakString[0]) {
+ strcpy(_pageBreakString, pageBreakString);
+ displayWaitButton();
+ resetPageBreakString();
+ }
+ }
+}
+
+void TextDisplayer_rpg::printDialogueText(const char *str, bool wait) {
+ assert(strlen(str) < kEoBTextBufferSize);
+ Common::strlcpy(_dialogueBuffer, str, kEoBTextBufferSize);
+
+ strcpy(_dialogueBuffer, str);
+ displayText(_dialogueBuffer);
+ if (wait)
+ displayWaitButton();
+}
+
+void TextDisplayer_rpg::printMessage(const char *str, int textColor, ...) {
+ int tc = _textDimData[_screen->curDimIndex()].color1;
+
+ if (textColor != -1)
+ _textDimData[_screen->curDimIndex()].color1 = textColor;
+
+ va_list args;
+ va_start(args, textColor);
+ vsnprintf(_dialogueBuffer, kEoBTextBufferSize - 1, str, args);
+ va_end(args);
+
+ displayText(_dialogueBuffer);
+
+ if (vm()->game() != GI_EOB1)
+ _textDimData[_screen->curDimIndex()].color1 = tc;
+
+ if (!_screen->_curPage)
+ _screen->updateScreen();
+}
+
+int TextDisplayer_rpg::clearDim(int dim) {
+ int res = _screen->curDimIndex();
+ _screen->setScreenDim(dim);
+ _textDimData[dim].color1 = _screen->_curDim->unk8;
+ _textDimData[dim].color2 = vm()->game() == GI_LOL ? _screen->_curDim->unkA : vm()->guiSettings()->colors.fill;
+ clearCurDim();
+ return res;
+}
+
+void TextDisplayer_rpg::clearCurDim() {
+ int d = _screen->curDimIndex();
+ const ScreenDim *tmp = _screen->getScreenDim(d);
+ if (vm()->gameFlags().use16ColorMode) {
+ _screen->fillRect(tmp->sx << 3, tmp->sy, ((tmp->sx + tmp->w) << 3) - 2, (tmp->sy + tmp->h) - 2, _textDimData[d].color2);
+ } else
+ _screen->fillRect(tmp->sx << 3, tmp->sy, ((tmp->sx + tmp->w) << 3) - 1, (tmp->sy + tmp->h) - 1, _textDimData[d].color2);
+
+ _lineCount = 0;
+ _textDimData[d].column = _textDimData[d].line = 0;
+}
+
+void TextDisplayer_rpg::textPageBreak() {
+ if (vm()->game() != GI_LOL)
+ SWAP(vm()->_dialogueButtonLabelColor1, vm()->_dialogueButtonLabelColor2);
+
+ int cp = _screen->setCurPage(0);
+ Screen::FontId cf = _screen->setFont(vm()->gameFlags().use16ColorMode ? Screen::FID_SJIS_FNT : Screen::FID_6_FNT);
+
+ if (vm()->game() == GI_LOL)
+ vm()->_timer->pauseSingleTimer(11, true);
+
+ vm()->_fadeText = false;
+ int resetPortraitAfterSpeechAnim = 0;
+ int updatePortraitSpeechAnimDuration = 0;
+
+ if (vm()->_updateCharNum != -1) {
+ resetPortraitAfterSpeechAnim = vm()->_resetPortraitAfterSpeechAnim;
+ vm()->_resetPortraitAfterSpeechAnim = 0;
+ updatePortraitSpeechAnimDuration = vm()->_updatePortraitSpeechAnimDuration;
+ if (vm()->_updatePortraitSpeechAnimDuration > 36)
+ vm()->_updatePortraitSpeechAnimDuration = 36;
+ }
+
+ uint32 speechPartTime = 0;
+ if (vm()->speechEnabled() && vm()->_activeVoiceFileTotalTime && _numCharsTotal)
+ speechPartTime = vm()->_system->getMillis() + ((_numCharsPrinted * vm()->_activeVoiceFileTotalTime) / _numCharsTotal);
+
+ const ScreenDim *dim = _screen->getScreenDim(_screen->curDimIndex());
+
+ int x = ((dim->sx + dim->w) << 3) - (_vm->_dialogueButtonWidth + 3);
+ int y = 0;
+ int w = vm()->_dialogueButtonWidth;
+
+ if (vm()->game() == GI_LOL) {
+ if (vm()->_needSceneRestore && (vm()->_updateFlags & 2)) {
+ if (vm()->_currentControlMode || !(vm()->_updateFlags & 2)) {
+ y = dim->sy + dim->h - 5;
+ } else {
+ x += 6;
+ y = dim->sy + dim->h - 2;
+ }
+ } else {
+ y = dim->sy + dim->h - 10;
+ }
+ } else {
+ y = vm()->guiSettings()->buttons.waitY[_waitButtonMode];
+ x = vm()->guiSettings()->buttons.waitX[_waitButtonMode];
+ w = vm()->guiSettings()->buttons.waitWidth[_waitButtonMode];
+ }
+
+ if (vm()->gameFlags().use16ColorMode) {
+ vm()->gui_drawBox(x + 8, (y & ~7) - 1, 66, 10, 0xee, 0xcc, -1);
+ _screen->printText(_pageBreakString, (x + 37 - (strlen(_pageBreakString) << 1) + 4) & ~3, (y + 2) & ~7, 0xc1, 0);
+ } else {
+ vm()->gui_drawBox(x, y, w, vm()->guiSettings()->buttons.height, vm()->guiSettings()->colors.frame1, vm()->guiSettings()->colors.frame2, vm()->guiSettings()->colors.fill);
+ _screen->printText(_pageBreakString, x + (w >> 1) - (vm()->screen()->getTextWidth(_pageBreakString) >> 1), y + 2, vm()->_dialogueButtonLabelColor1, 0);
+ }
+
+ vm()->removeInputTop();
+
+ bool loop = true;
+ bool target = false;
+
+ do {
+ int inputFlag = vm()->checkInput(0, false) & 0xFF;
+ vm()->removeInputTop();
+
+ while (!inputFlag && !_vm->shouldQuit()) {
+ vm()->update();
+
+ if (vm()->speechEnabled()) {
+ if (((vm()->_system->getMillis() > speechPartTime) || (vm()->snd_updateCharacterSpeech() != 2)) && speechPartTime) {
+ loop = false;
+ inputFlag = vm()->_keyMap[Common::KEYCODE_RETURN];
+ break;
+ }
+ }
+
+ inputFlag = vm()->checkInput(0, false) & 0xFF;
+ vm()->removeInputTop();
+ }
+
+ vm()->gui_notifyButtonListChanged();
+
+ if (inputFlag == vm()->_keyMap[Common::KEYCODE_SPACE] || inputFlag == vm()->_keyMap[Common::KEYCODE_RETURN]) {
+ loop = false;
+ } else if (inputFlag == 199 || inputFlag == 201) {
+ if (vm()->posWithinRect(vm()->_mouseX, vm()->_mouseY, x, y, x + w, y + 9)) {
+ if (_vm->game() == GI_LOL)
+ target = true;
+ else
+ loop = false;
+ }
+ } else if (inputFlag == 200 || inputFlag == 202) {
+ if (target)
+ loop = false;
+ }
+ } while (loop && !_vm->shouldQuit());
+
+ if (vm()->gameFlags().use16ColorMode)
+ _screen->fillRect(x + 8, y, x + 57, y + 9, _textDimData[_screen->curDimIndex()].color2);
+ else
+ _screen->fillRect(x, y, x + w - 1, y + 8, _textDimData[_screen->curDimIndex()].color2);
+
+ clearCurDim();
+ _screen->updateScreen();
+
+ if (vm()->game() == GI_LOL)
+ vm()->_timer->pauseSingleTimer(11, false);
+
+ if (vm()->_updateCharNum != -1) {
+ vm()->_resetPortraitAfterSpeechAnim = resetPortraitAfterSpeechAnim;
+ if (updatePortraitSpeechAnimDuration > 36)
+ updatePortraitSpeechAnimDuration -= 36;
+ else
+ updatePortraitSpeechAnimDuration >>= 1;
+
+ vm()->_updatePortraitSpeechAnimDuration = updatePortraitSpeechAnimDuration;
+ }
+
+ _screen->setFont(cf);
+ _screen->setCurPage(cp);
+
+ if (vm()->game() != GI_LOL)
+ SWAP(vm()->_dialogueButtonLabelColor1, vm()->_dialogueButtonLabelColor2);
+
+ vm()->removeInputTop();
+}
+
+void TextDisplayer_rpg::displayWaitButton() {
+ vm()->_dialogueNumButtons = 1;
+ vm()->_dialogueButtonString[0] = _pageBreakString;
+ vm()->_dialogueButtonString[1] = 0;
+ vm()->_dialogueButtonString[2] = 0;
+ vm()->_dialogueHighlightedButton = 0;
+
+ vm()->_dialogueButtonPosX = &vm()->guiSettings()->buttons.waitX[_waitButtonMode];
+ vm()->_dialogueButtonPosY = &vm()->guiSettings()->buttons.waitY[_waitButtonMode];
+ vm()->_dialogueButtonWidth = vm()->guiSettings()->buttons.waitWidth[_waitButtonMode];
+ vm()->_dialogueButtonYoffs = 0;
+
+ SWAP(vm()->_dialogueButtonLabelColor1, vm()->_dialogueButtonLabelColor2);
+ vm()->drawDialogueButtons();
+
+ if (!vm()->shouldQuit())
+ vm()->removeInputTop();
+
+ while (!vm()->processDialogue() && !vm()->shouldQuit()) {}
+
+ _screen->fillRect(vm()->_dialogueButtonPosX[0], vm()->_dialogueButtonPosY[0], vm()->_dialogueButtonPosX[0] + vm()->_dialogueButtonWidth - 1, vm()->_dialogueButtonPosY[0] + vm()->guiSettings()->buttons.height - 1, vm()->guiSettings()->colors.fill);
+ _screen->updateScreen();
+ vm()->_dialogueButtonWidth = 95;
+ SWAP(vm()->_dialogueButtonLabelColor1, vm()->_dialogueButtonLabelColor2);
+ clearCurDim();
+}
+
+} // End of namespace Kyra
+
+#endif // (ENABLE_EOB || ENABLE_LOL)
diff --git a/engines/kyra/text_rpg.h b/engines/kyra/text_rpg.h
new file mode 100644
index 0000000000..5ad8899484
--- /dev/null
+++ b/engines/kyra/text_rpg.h
@@ -0,0 +1,115 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are to numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#if defined(ENABLE_EOB) || defined(ENABLE_LOL)
+
+#ifndef KYRA_TEXT_EOB_H
+#define KYRA_TEXT_EOB_H
+
+#include "common/scummsys.h"
+
+namespace Kyra {
+
+class Screen;
+class KyraRpgEngine;
+
+class TextDisplayer_rpg {
+public:
+ TextDisplayer_rpg(KyraRpgEngine *engine, Screen *scr);
+ virtual ~TextDisplayer_rpg();
+
+ void setupField(int dim, bool mode);
+
+ void printDialogueText(int stringId, const char *pageBreakString);
+ void printDialogueText(const char *str, bool wait = false);
+ void printMessage(const char *str, int textColor = -1, ...);
+
+ int clearDim(int dim);
+ void clearCurDim();
+
+ void resetDimTextPositions(int dim);
+ void resetPageBreakString();
+ void setPageBreakFlag();
+ void removePageBreakFlag();
+
+ void allowPageBreak(bool mode) { _allowPageBreak = mode; }
+ void setWaitButtonMode(int mode) { _waitButtonMode = mode; }
+ int lineCount() { return _lineCount; }
+
+protected:
+ virtual KyraRpgEngine *vm() { return _vm; }
+ virtual Screen *screen() { return _screen; }
+
+ void displayText(char *str, ...);
+ char parseCommand();
+ void readNextPara();
+ void printLine(char *str);
+ virtual void textPageBreak();
+ void displayWaitButton();
+
+ char *_dialogueBuffer;
+
+ char *_tempString1;
+ char *_tempString2;
+ char *_currentLine;
+ char _ctrl[3];
+
+ uint16 _lineWidth;
+ uint32 _numCharsTotal;
+ uint32 _numCharsLeft;
+ uint32 _numCharsPrinted;
+
+ bool _printFlag;
+ bool _sjisLineBreakFlag;
+
+ char _pageBreakString[20];
+ char _scriptParaString[11];
+ int _lineCount;
+
+ bool _allowPageBreak;
+ int _waitButtonSpace;
+ int _waitButtonMode;
+
+ static const char _pageBreakDefault[3][5];
+
+ struct TextDimData {
+ uint8 color1;
+ uint8 color2;
+ uint16 column;
+ uint8 line;
+ };
+
+ TextDimData *_textDimData;
+
+private:
+ KyraRpgEngine *_vm;
+ Screen *_screen;
+
+ char *_table1;
+ char *_table2;
+};
+
+} // End of namespace Kyra
+
+#endif
+
+#endif // ENABLE_EOB || ENABLE_LOL
diff --git a/engines/kyra/timer.cpp b/engines/kyra/timer.cpp
index 9834646a45..95c283f063 100644
--- a/engines/kyra/timer.cpp
+++ b/engines/kyra/timer.cpp
@@ -149,6 +149,8 @@ void TimerManager::setCountdown(uint8 id, int32 countdown) {
uint32 curTime = _system->getMillis();
timer->lastUpdate = curTime;
timer->nextRun = curTime + countdown * _vm->tickLength();
+ if (timer->enabled & 2)
+ timer->pauseStartTime = curTime;
_nextRun = MIN(_nextRun, timer->nextRun);
}
@@ -177,6 +179,8 @@ int32 TimerManager::getDelay(uint8 id) const {
void TimerManager::setNextRun(uint8 id, uint32 nextRun) {
Iterator timer = Common::find_if(_timers.begin(), _timers.end(), TimerEqual(id));
if (timer != _timers.end()) {
+ if (timer->enabled & 2)
+ timer->pauseStartTime = _system->getMillis();
timer->nextRun = nextRun;
return;
}
@@ -217,7 +221,7 @@ void TimerManager::pauseSingleTimer(uint8 id, bool p) {
bool TimerManager::isEnabled(uint8 id) const {
CIterator timer = Common::find_if(_timers.begin(), _timers.end(), TimerEqual(id));
if (timer != _timers.end())
- return (timer->enabled == 1);
+ return (timer->enabled & 1);
warning("TimerManager::isEnabled: No timer %d", id);
return false;
diff --git a/engines/kyra/timer_eob.cpp b/engines/kyra/timer_eob.cpp
new file mode 100644
index 0000000000..de1becfa72
--- /dev/null
+++ b/engines/kyra/timer_eob.cpp
@@ -0,0 +1,360 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "kyra/eobcommon.h"
+#include "kyra/timer.h"
+
+#include "common/system.h"
+
+#ifdef ENABLE_EOB
+
+namespace Kyra {
+
+#define TimerV2(x) new Common::Functor1Mem<int, void, EoBCoreEngine>(this, &EoBCoreEngine::x)
+
+void EoBCoreEngine::setupTimers() {
+ _timer->addTimer(0, TimerV2(timerProcessCharacterExchange), 9, false);
+ _timer->addTimer(1, TimerV2(timerProcessFlyingObjects), 3, true);
+ _timer->addTimer(0x20, TimerV2(timerProcessMonsters), 20, true);
+ _timer->addTimer(0x21, TimerV2(timerProcessMonsters), 20, true);
+ _timer->addTimer(0x22, TimerV2(timerProcessMonsters), 20, true);
+ _timer->addTimer(0x23, TimerV2(timerProcessMonsters), 20, true);
+ _timer->setNextRun(0x20, _system->getMillis());
+ _timer->setNextRun(0x21, _system->getMillis() + 7 * _tickLength);
+ _timer->setNextRun(0x22, _system->getMillis() + 14 * _tickLength);
+ _timer->setNextRun(0x23, _system->getMillis() + 14 * _tickLength);
+ _timer->addTimer(0x30, TimerV2(timerSpecialCharacterUpdate), 50, false);
+ _timer->addTimer(0x31, TimerV2(timerSpecialCharacterUpdate), 50, false);
+ _timer->addTimer(0x32, TimerV2(timerSpecialCharacterUpdate), 50, false);
+ _timer->addTimer(0x33, TimerV2(timerSpecialCharacterUpdate), 50, false);
+ _timer->addTimer(0x34, TimerV2(timerSpecialCharacterUpdate), 50, false);
+ _timer->addTimer(0x35, TimerV2(timerSpecialCharacterUpdate), 50, false);
+ _timer->addTimer(4, TimerV2(timerProcessDoors), 5, true);
+ _timer->addTimer(5, TimerV2(timerUpdateTeleporters), 10, true);
+ _timer->addTimer(6, TimerV2(timerUpdateFoodStatus), 1080, true);
+ _timer->addTimer(7, TimerV2(timerUpdateMonsterIdleAnim), 25, true);
+ _timer->resetNextRun();
+}
+
+void EoBCoreEngine::setCharEventTimer(int charIndex, uint32 countdown, int evnt, int updateExistingTimer) {
+ uint32 ntime = _system->getMillis() + countdown * _tickLength;
+ uint8 timerId = 0x30 | (charIndex & 0x0f);
+ EoBCharacter *c = &_characters[charIndex];
+
+ if (!_timer->isEnabled(timerId)) {
+ c->timers[0] = ntime;
+ c->events[0] = evnt;
+ _timer->setCountdown(timerId, countdown);
+ enableTimer(timerId);
+ return;
+ }
+
+ if (ntime < _timer->getNextRun(timerId))
+ _timer->setNextRun(timerId, ntime);
+ _timer->resetNextRun();
+
+ if (updateExistingTimer) {
+ bool updated = false;
+ int d = -1;
+
+ for (int i = 0; i < 10 && updated == false; i++) {
+ if (d == -1 && !c->timers[i])
+ d = i;
+
+ if (!updated && c->events[i] == evnt) {
+ d = i;
+ updated = true;
+ }
+ }
+
+ assert(d != -1);
+
+ c->timers[d] = ntime;
+ c->events[d] = evnt;
+ } else {
+ for (int i = 0; i < 10; i++) {
+ if (c->timers[i])
+ continue;
+ c->timers[i] = ntime;
+ c->events[i] = evnt;
+ return;
+ }
+ }
+}
+
+void EoBCoreEngine::deleteCharEventTimer(int charIndex, int evnt) {
+ EoBCharacter *c = &_characters[charIndex];
+ for (int i = 0; i < 10; i++) {
+ if (c->events[i] == evnt) {
+ c->events[i] = 0;
+ c->timers[i] = 0;
+ }
+ }
+ setupCharacterTimers();
+}
+
+void EoBCoreEngine::setupCharacterTimers() {
+ for (int i = 0; i < 6; i++) {
+ EoBCharacter *c = &_characters[i];
+ if (!testCharacter(i, 1))
+ continue;
+
+ uint32 nextTimer = 0xffffffff;
+
+ for (int ii = 0; ii < 10; ii++) {
+ if (c->timers[ii] && c->timers[ii] < nextTimer)
+ nextTimer = c->timers[ii];
+ }
+ uint32 ctime = _system->getMillis();
+
+ if (nextTimer == 0xffffffff)
+ _timer->disable(0x30 | i);
+ else {
+ enableTimer(0x30 | i);
+ _timer->setCountdown(0x30 | i, (nextTimer - ctime) / _tickLength);
+ }
+ }
+ _timer->resetNextRun();
+}
+
+void EoBCoreEngine::advanceTimers(uint32 millis) {
+ uint32 ct = _system->getMillis();
+ for (int i = 0; i < 6; i++) {
+ EoBCharacter *c = &_characters[i];
+ for (int ii = 0; ii < 10; ii++) {
+ if (c->timers[ii] > ct) {
+ uint32 chrt = c->timers[ii] - ct;
+ c->timers[ii] = chrt > millis ? ct + chrt - millis : ct;
+ }
+ }
+ }
+
+ setupCharacterTimers();
+
+ if (_scriptTimersMode & 1) {
+ for (int i = 0; i < _scriptTimersCount; i++) {
+ if (_scriptTimers[i].next > ct) {
+ uint32 chrt = _scriptTimers[i].next - ct;
+ _scriptTimers[i].next = chrt > millis ? ct + chrt - millis : ct;
+ }
+ }
+ }
+
+ for (int i = 0; i < 5; i++) {
+ if (_wallsOfForce[i].duration > ct) {
+ uint32 chrt = _wallsOfForce[i].duration - ct;
+ _wallsOfForce[i].duration = chrt > millis ? ct + chrt - millis : ct;
+ }
+ }
+}
+
+void EoBCoreEngine::timerProcessCharacterExchange(int timerNum) {
+ _charExchangeSwap ^= 1;
+ if (_charExchangeSwap) {
+ int index = _exchangeCharacterId;
+ _exchangeCharacterId = -1;
+ gui_drawCharPortraitWithStats(index);
+ _exchangeCharacterId = index;
+ } else {
+ gui_drawCharPortraitWithStats(_exchangeCharacterId);
+ }
+}
+
+void EoBCoreEngine::timerProcessFlyingObjects(int timerNum) {
+ static const uint8 dirPosIndex[] = { 0x82, 0x83, 0x00, 0x01, 0x01, 0x80, 0x03, 0x82, 0x02, 0x03, 0x80, 0x81, 0x81, 0x00, 0x83, 0x02 };
+ for (int i = 0; i < 10; i++) {
+ EoBFlyingObject *fo = &_flyingObjects[i];
+ if (!fo->enable)
+ continue;
+
+ bool endFlight = fo->distance ? false : true;
+
+ uint8 pos = dirPosIndex[(fo->direction << 2) + (fo->curPos & 3)];
+ uint16 bl = fo->curBlock;
+ bool newBl = (pos & 0x80) ? true : false;
+
+ if (newBl) {
+ bl = calcNewBlockPosition(fo->curBlock, fo->direction);
+ pos &= 3;
+ fo->starting = 0;
+ }
+
+ if (updateObjectFlight(fo, bl, pos)) {
+ if (newBl)
+ runLevelScript(bl, 0x10);
+ if (updateFlyingObjectHitTest(fo, bl, pos))
+ endFlight = true;
+ } else {
+ if (fo->flags & 0x20) {
+ if (!updateFlyingObjectHitTest(fo, fo->curBlock, fo->curPos))
+ explodeObject(fo, fo->curBlock, fo->item);
+ }
+ endFlight = true;
+ }
+
+ if (endFlight)
+ endObjectFlight(fo);
+
+ _sceneUpdateRequired = true;
+ }
+}
+
+void EoBCoreEngine::timerProcessMonsters(int timerNum) {
+ updateMonsters(timerNum & 0x0f);
+}
+
+void EoBCoreEngine::timerSpecialCharacterUpdate(int timerNum) {
+ int charIndex = timerNum & 0x0f;
+ EoBCharacter *c = &_characters[charIndex];
+ uint32 ctime = _system->getMillis();
+
+ for (int i = 0; i < 10; i++) {
+ if (!c->timers[i])
+ continue;
+ if (c->timers[i] > ctime)
+ continue;
+
+ c->timers[i] = 0;
+ int evt = c->events[i];
+
+ if (evt < 0) {
+ removeCharacterEffect(-evt, charIndex, 1);
+ continue;
+ }
+
+ int od = _screen->curDimIndex();
+ Screen::FontId of = _screen->setFont(Screen::FID_6_FNT);
+ _screen->setScreenDim(7);
+
+ switch (evt) {
+ case 2:
+ case 3:
+ setCharEventTimer(charIndex, (c->effectFlags & 0x10000) ? 9 : 36, evt + 2, 1);
+ case 0:
+ case 1:
+ case 4:
+ case 5:
+ setWeaponSlotStatus(charIndex, evt / 2, evt & 1);
+ break;
+
+ case 6:
+ c->damageTaken = 0;
+ gui_drawCharPortraitWithStats(charIndex);
+ break;
+
+ case 7:
+ _txt->printMessage(_characterStatusStrings7[0], -1, c->name);
+ c->strengthCur = c->strengthMax;
+ c->strengthExtCur = c->strengthExtMax;
+ if (_currentControlMode == 2)
+ gui_drawCharPortraitWithStats(charIndex);
+ break;
+
+ case 8:
+ if (c->flags & 2) {
+ calcAndInflictCharacterDamage(charIndex, 0, 0, 5, 0x400, 5, 3);
+ setCharEventTimer(charIndex, 546, 8, 1);
+ } else {
+ c->flags &= ~2;
+ gui_drawCharPortraitWithStats(charIndex);
+ }
+ break;
+
+ case 9:
+ if (c->flags & 4) {
+ _txt->printMessage(_characterStatusStrings9[0], -1, c->name);
+ c->flags &= ~4;
+ gui_drawCharPortraitWithStats(charIndex);
+ }
+ break;
+
+ case 11:
+ if (c->disabledSlots & 4) {
+ c->disabledSlots &= ~4;
+ if (_openBookChar == charIndex && _updateFlags)
+ gui_drawSpellbook();
+ }
+ break;
+
+ case 12:
+ c->effectFlags &= ~0x1000;
+ if (_characterStatusStrings12)
+ _txt->printMessage(_characterStatusStrings12[0], -1, c->name);
+ break;
+
+ default:
+ break;
+ }
+
+ _screen->setScreenDim(od);
+ _screen->setFont(of);
+ }
+
+ uint32 nextTimer = 0xffffffff;
+ for (int i = 0; i < 10; i++) {
+ if (c->timers[i] && c->timers[i] < nextTimer)
+ nextTimer = c->timers[i];
+ }
+
+ if (nextTimer == 0xffffffff)
+ _timer->disable(timerNum);
+ else
+ _timer->setCountdown(timerNum, (nextTimer - ctime) / _tickLength);
+}
+
+void EoBCoreEngine::timerUpdateTeleporters(int timerNum) {
+ _teleporterPulse ^= 1;
+ for (int i = 0; i < 18; i++) {
+ uint8 w = _visibleBlocks[i]->walls[_sceneDrawVarDown];
+ if ((w == _teleporterWallId) || (_flags.gameID == GI_EOB2 && w == 74)) {
+ _sceneUpdateRequired = true;
+ return;
+ }
+ }
+}
+
+void EoBCoreEngine::timerUpdateFoodStatus(int timerNum) {
+ for (int i = 0; i < 6; i++) {
+ // Ring of Sustenance check
+ if (checkInventoryForRings(i, 2))
+ continue;
+ EoBCharacter *c = &_characters[i];
+ if (c->food != 0 && c->flags & 1 && c->hitPointsCur > -10) {
+ c->food--;
+ gui_drawFoodStatusGraph(i);
+ }
+ }
+}
+
+void EoBCoreEngine::timerUpdateMonsterIdleAnim(int timerNum) {
+ for (int i = 0; i < 18; i++) {
+ EoBMonsterInPlay *m = &_monsters[i];
+ if (m->mode == 7 || m->mode == 10 || (m->flags & 0x20) || (rollDice(1, 2, 0) != 1))
+ continue;
+ m->idleAnimState = (rollDice(1, 2, 0) << 4) | rollDice(1, 2, 0);
+ checkSceneUpdateNeed(m->block);
+ }
+}
+
+} // End of namespace Kyra
+
+#endif // ENABLE_EOB
diff --git a/engines/kyra/timer_lok.cpp b/engines/kyra/timer_lok.cpp
index 555b3680e2..13f5403618 100644
--- a/engines/kyra/timer_lok.cpp
+++ b/engines/kyra/timer_lok.cpp
@@ -155,7 +155,7 @@ void KyraEngine_LoK::setTextFadeTimerCountdown(int16 countdown) {
if (countdown == -1)
countdown = 32000;
- _timer->setCountdown(31, countdown*60);
+ _timer->setCountdown(31, countdown * 60);
}
void KyraEngine_LoK::timerAsInvisibleTimeout(int timerNum) {
diff --git a/engines/kyra/timer_lol.cpp b/engines/kyra/timer_lol.cpp
index 3221556e6d..a3df8dbe00 100644
--- a/engines/kyra/timer_lol.cpp
+++ b/engines/kyra/timer_lol.cpp
@@ -45,58 +45,7 @@ void LoLEngine::setupTimers() {
_timer->addTimer(9, TimerV2(timerUpdatePortraitAnimations), 10, true);
_timer->addTimer(10, TimerV2(timerUpdateLampState), 360, true);
_timer->addTimer(11, TimerV2(timerFadeMessageText), 360, false);
-}
-
-void LoLEngine::enableTimer(int id) {
- _timer->enable(id);
- _timer->setCountdown(id, _timer->getDelay(id));
-}
-
-void LoLEngine::enableSysTimer(int sysTimer) {
- if (sysTimer != 2)
- return;
-
- for (int i = 0; i < _numClock2Timers; i++)
- _timer->pauseSingleTimer(_clock2Timers[i], false);
-}
-
-void LoLEngine::disableSysTimer(int sysTimer) {
- if (sysTimer != 2)
- return;
-
- for (int i = 0; i < _numClock2Timers; i++)
- _timer->pauseSingleTimer(_clock2Timers[i], true);
-}
-
-void LoLEngine::timerProcessDoors(int timerNum) {
- for (int i = 0; i < 3; i++) {
- uint16 b = _openDoorState[i].block;
- if (!b)
- continue;
-
- int v = _openDoorState[i].state;
- int c = _openDoorState[i].wall;
-
- _levelBlockProperties[b].walls[c] += v;
- _levelBlockProperties[b].walls[c ^ 2] += v;
-
- int snd = 31;
-
- int flg = _wllWallFlags[_levelBlockProperties[b].walls[c]];
- if (flg & 0x20)
- snd = 33;
- else if (v == -1)
- snd = 32;
-
- if (!(_updateFlags & 1)) {
- snd_processEnvironmentalSoundEffect(snd, b);
- if (!checkSceneUpdateNeed(b))
- updateEnvironmentalSfx(0);
- }
-
- if (flg & 0x30)
- _openDoorState[i].block = 0;
- }
+ _timer->resetNextRun();
}
void LoLEngine::timerProcessMonsters(int timerNum) {
@@ -209,7 +158,7 @@ void LoLEngine::timerRegeneratePoints(int timerNum) {
int hInc = (_characters[i].flags & 8) ? 0 : (itemEquipped(i, 228) ? 4 : 1);
// check for Talba ring
int mInc = _drainMagic ? ((_characters[i].magicPointsMax >> 5) * -1) :
- ((_characters[i].flags & 8) ? 0 : (itemEquipped(i, 227) ? (_characters[i].magicPointsMax / 10) : 1));
+ ((_characters[i].flags & 8) ? 0 : (itemEquipped(i, 227) ? (_characters[i].magicPointsMax / 10) : 1));
_characters[i].magicPointsCur = CLIP<int16>(_characters[i].magicPointsCur + mInc, 0, _characters[i].magicPointsMax);
diff --git a/engines/kyra/timer_rpg.cpp b/engines/kyra/timer_rpg.cpp
new file mode 100644
index 0000000000..02c2669436
--- /dev/null
+++ b/engines/kyra/timer_rpg.cpp
@@ -0,0 +1,90 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#if defined(ENABLE_EOB) || defined(ENABLE_LOL)
+
+#include "kyra/kyra_rpg.h"
+#include "kyra/timer.h"
+
+#include "common/system.h"
+
+namespace Kyra {
+
+void KyraRpgEngine::enableSysTimer(int sysTimer) {
+ if (sysTimer != 2)
+ return;
+
+ for (int i = 0; i < getNumClock2Timers(); i++)
+ _timer->pauseSingleTimer(getClock2Timer(i), false);
+}
+
+void KyraRpgEngine::disableSysTimer(int sysTimer) {
+ if (sysTimer != 2)
+ return;
+
+ for (int i = 0; i < getNumClock2Timers(); i++)
+ _timer->pauseSingleTimer(getClock2Timer(i), true);
+}
+
+void KyraRpgEngine::enableTimer(int id) {
+ _timer->enable(id);
+ _timer->setCountdown(id, _timer->getDelay(id));
+}
+
+void KyraRpgEngine::timerProcessDoors(int timerNum) {
+ for (int i = 0; i < 3; i++) {
+ uint16 b = _openDoorState[i].block;
+ if (!b)
+ continue;
+
+ int v = _openDoorState[i].state;
+ int c = _openDoorState[i].wall;
+
+ _levelBlockProperties[b].walls[c] += v;
+ _levelBlockProperties[b].walls[c ^ 2] += v;
+
+ int snd = 3;
+ int flg = _wllWallFlags[_levelBlockProperties[b].walls[c]];
+ if (flg & 0x20)
+ snd = 5;
+ else if (v == -1)
+ snd = 4;
+
+ if (_flags.gameID == GI_LOL) {
+ if (!(_updateFlags & 1)) {
+ snd_processEnvironmentalSoundEffect(snd + 28, b);
+ if (!checkSceneUpdateNeed(b))
+ updateEnvironmentalSfx(0);
+ }
+ } else {
+ checkSceneUpdateNeed(b);
+ updateEnvironmentalSfx(snd);
+ }
+
+ if (flg & 0x30)
+ _openDoorState[i].block = 0;
+ }
+}
+
+} // namespace Kyra
+
+#endif
diff --git a/engines/kyra/wsamovie.cpp b/engines/kyra/wsamovie.cpp
index 21ff80f033..f6aca2bb82 100644
--- a/engines/kyra/wsamovie.cpp
+++ b/engines/kyra/wsamovie.cpp
@@ -28,10 +28,12 @@
namespace Kyra {
WSAMovie_v1::WSAMovie_v1(KyraEngine_v1 *vm)
- : Movie(vm), _frameData(0), _frameOffsTable(0), _offscreenBuffer(0), _deltaBuffer(0) {
+ : Movie(vm), _frameData(0), _frameOffsTable(0), _offscreenBuffer(0), _deltaBuffer(0) {
}
-WSAMovie_v1::~WSAMovie_v1() { close(); }
+WSAMovie_v1::~WSAMovie_v1() {
+ close();
+}
int WSAMovie_v1::open(const char *filename, int offscreenDecode, Palette *palBuf) {
close();
@@ -95,7 +97,7 @@ int WSAMovie_v1::open(const char *filename, int offscreenDecode, Palette *palBuf
for (int i = 1; i < _numFrames + 2; ++i) {
_frameOffsTable[i] = READ_LE_UINT32(wsaData);
- if (_frameOffsTable[i])
+ if (_frameOffsTable[i])
_frameOffsTable[i] -= frameDataOffs;
wsaData += 4;
}
@@ -251,7 +253,7 @@ void WSAMovieAmiga::displayFrame(int frameNum, int pageNum, int x, int y, uint16
uint8 *dst;
dst = _buffer;
- memset(_buffer, 0, _width*_height);
+ memset(_buffer, 0, _width * _height);
if (_currentFrame == _numFrames) {
if (!(_flags & WF_NO_FIRST_FRAME)) {
@@ -330,7 +332,7 @@ void WSAMovieAmiga::processFrame(int frameNum, uint8 *dst) {
return;
assert(frameNum <= _numFrames);
- memset(dst, 0, _width*_height);
+ memset(dst, 0, _width * _height);
const uint8 *src = _frameData + _frameOffsTable[frameNum];
Screen::decodeFrame4(src, _deltaBuffer, _deltaBufferSize);
diff --git a/engines/lastexpress/data/archive.cpp b/engines/lastexpress/data/archive.cpp
index 3aa5584ca4..908d58254a 100644
--- a/engines/lastexpress/data/archive.cpp
+++ b/engines/lastexpress/data/archive.cpp
@@ -74,11 +74,11 @@ HPFArchive::HPFArchive(const Common::String &path) {
delete archive;
}
-bool HPFArchive::hasFile(const Common::String &name) {
+bool HPFArchive::hasFile(const Common::String &name) const {
return (_files.find(name) != _files.end());
}
-int HPFArchive::listMembers(Common::ArchiveMemberList &list) {
+int HPFArchive::listMembers(Common::ArchiveMemberList &list) const {
int numMembers = 0;
for (FileMap::const_iterator i = _files.begin(); i != _files.end(); ++i) {
@@ -89,7 +89,7 @@ int HPFArchive::listMembers(Common::ArchiveMemberList &list) {
return numMembers;
}
-Common::ArchiveMemberPtr HPFArchive::getMember(const Common::String &name) {
+const Common::ArchiveMemberPtr HPFArchive::getMember(const Common::String &name) const {
if (!hasFile(name))
return Common::ArchiveMemberPtr();
diff --git a/engines/lastexpress/data/archive.h b/engines/lastexpress/data/archive.h
index 8e0c46f183..011c830668 100644
--- a/engines/lastexpress/data/archive.h
+++ b/engines/lastexpress/data/archive.h
@@ -46,9 +46,9 @@ class HPFArchive : public Common::Archive {
public:
HPFArchive(const Common::String &path);
- bool hasFile(const Common::String &name);
- int listMembers(Common::ArchiveMemberList &list);
- Common::ArchiveMemberPtr getMember(const Common::String &name);
+ bool hasFile(const Common::String &name) const;
+ int listMembers(Common::ArchiveMemberList &list) const;
+ const Common::ArchiveMemberPtr getMember(const Common::String &name) const;
Common::SeekableReadStream *createReadStreamForMember(const Common::String &name) const;
int count() { return _files.size(); }
diff --git a/engines/lastexpress/data/scene.h b/engines/lastexpress/data/scene.h
index 0c0d12b9c0..69a1417459 100644
--- a/engines/lastexpress/data/scene.h
+++ b/engines/lastexpress/data/scene.h
@@ -76,10 +76,6 @@ class SeekableReadStream;
class String;
}
-namespace Graphics {
-struct Surface;
-}
-
namespace LastExpress {
class Scene;
diff --git a/engines/lastexpress/detection.cpp b/engines/lastexpress/detection.cpp
index e2133c0929..82a6520522 100644
--- a/engines/lastexpress/detection.cpp
+++ b/engines/lastexpress/detection.cpp
@@ -48,7 +48,7 @@ static const ADGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformUnknown,
ADGF_UNSTABLE,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
// The Last Express (English) - UK Broderbund Release
@@ -66,7 +66,7 @@ static const ADGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformUnknown,
ADGF_UNSTABLE,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
// The Last Express (English) - Interplay Release
@@ -84,7 +84,7 @@ static const ADGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformUnknown,
ADGF_UNSTABLE,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
// The Last Express (Demo - English) - Broderbund
@@ -99,7 +99,7 @@ static const ADGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformUnknown,
ADGF_DEMO | ADGF_UNSTABLE,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
// The Last Express (French) - Broderbund Release
@@ -117,7 +117,7 @@ static const ADGameDescription gameDescriptions[] = {
Common::FR_FRA,
Common::kPlatformUnknown,
ADGF_UNSTABLE,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
// The Last Express (German)
@@ -135,7 +135,7 @@ static const ADGameDescription gameDescriptions[] = {
Common::DE_DEU,
Common::kPlatformUnknown,
ADGF_UNSTABLE,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
// The Last Express (Spanish)
@@ -153,7 +153,7 @@ static const ADGameDescription gameDescriptions[] = {
Common::ES_ESP,
Common::kPlatformUnknown,
ADGF_UNSTABLE,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
// The Last Express (Italian)
@@ -171,7 +171,7 @@ static const ADGameDescription gameDescriptions[] = {
Common::IT_ITA,
Common::kPlatformUnknown,
ADGF_UNSTABLE,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
// The Last Express (Russian)
@@ -189,7 +189,7 @@ static const ADGameDescription gameDescriptions[] = {
Common::RU_RUS,
Common::kPlatformUnknown,
ADGF_UNSTABLE,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
AD_TABLE_END_MARKER
diff --git a/engines/lastexpress/entities/abbot.cpp b/engines/lastexpress/entities/abbot.cpp
index c5c6f2a44d..301c52e142 100644
--- a/engines/lastexpress/entities/abbot.cpp
+++ b/engines/lastexpress/entities/abbot.cpp
@@ -841,7 +841,7 @@ IMPLEMENT_FUNCTION(31, Abbot, function31)
case kActionNone:
if (params->param4 != kTimeInvalid && params->param2 < getState()->time) {
- if (getState()->time < getState()->time) {
+ if (params->param3 < getState()->time) {
params->param4 = kTimeInvalid;
setCallback(1);
diff --git a/engines/lastexpress/entities/alexei.cpp b/engines/lastexpress/entities/alexei.cpp
index 073ca3f175..54c2d87b89 100644
--- a/engines/lastexpress/entities/alexei.cpp
+++ b/engines/lastexpress/entities/alexei.cpp
@@ -355,7 +355,7 @@ IMPLEMENT_FUNCTION_IS(16, Alexei, function16, TimeValue)
break;
case kActionDefault:
- getEntities()->drawSequenceLeft(kEntityAlexei, (char*)&params->seq);
+ getEntities()->drawSequenceLeft(kEntityAlexei, (char *)&params->seq);
getObjects()->update(kObjectCompartment2, kEntityAlexei, kObjectLocation1, kCursorHandKnock, kCursorHand);
getObjects()->update(kObjectHandleInsideBathroom, kEntityAlexei, kObjectLocation1, kCursorHandKnock, kCursorHand);
break;
diff --git a/engines/lastexpress/entities/august.cpp b/engines/lastexpress/entities/august.cpp
index eb3b09af59..cfde8a2d6f 100644
--- a/engines/lastexpress/entities/august.cpp
+++ b/engines/lastexpress/entities/august.cpp
@@ -2118,7 +2118,7 @@ IMPLEMENT_FUNCTION_II(41, August, function41, CarIndex, EntityPosition)
&& getEntities()->isDistanceBetweenEntities(kEntityAugust, kEntityPlayer, 1000)
&& !getEntities()->isInsideCompartments(kEntityPlayer)
&& !getEntities()->checkFields10(kEntityPlayer)) {
- if (getData()->car == kCarGreenSleeping || getData()->car == kCarGreenSleeping) {
+ if (getData()->car == kCarGreenSleeping || getData()->car == kCarRedSleeping) {
getAction()->playAnimation(kEventAugustMerchandise);
getEntities()->loadSceneFromEntityPosition(getData()->car, (EntityPosition)(getData()->entityPosition + (750 * (getData()->direction == kDirectionUp ? -1 : 1))), getData()->direction == kDirectionUp);
diff --git a/engines/lastexpress/entities/entity_intern.h b/engines/lastexpress/entities/entity_intern.h
index bf75e022de..2da0da15b3 100644
--- a/engines/lastexpress/entities/entity_intern.h
+++ b/engines/lastexpress/entities/entity_intern.h
@@ -94,7 +94,7 @@ void class::setup_##name() { \
// Expose parameters and check validity
#define EXPOSE_PARAMS(type) \
- type *params = (type*)_data->getCurrentParameters(); \
+ type *params = (type *)_data->getCurrentParameters(); \
if (!params) \
error("[EXPOSE_PARAMS] Trying to call an entity function with invalid parameters"); \
@@ -307,7 +307,7 @@ void class::setup_##name() { \
//////////////////////////////////////////////////////////////////////////
#define RESET_ENTITY_STATE(entity, class, function) \
getEntities()->resetState(entity); \
- ((class*)getEntities()->get(entity))->function();
+ ((class *)getEntities()->get(entity))->function();
//////////////////////////////////////////////////////////////////////////
// Parameters macros (for default IIII parameters)
diff --git a/engines/lastexpress/entities/francois.cpp b/engines/lastexpress/entities/francois.cpp
index 2b170d93a3..46cd790ffb 100644
--- a/engines/lastexpress/entities/francois.cpp
+++ b/engines/lastexpress/entities/francois.cpp
@@ -450,7 +450,7 @@ label_callback:
if (isNight())
getAction()->playAnimation(getData()->entityPosition <= getEntityData(kEntityPlayer)->entityPosition ? kEventFrancoisWhistleNightD : kEventFrancoisWhistleNight);
else
- getAction()->playAnimation(getData()->entityPosition <= getEntityData(kEntityPlayer)->entityPosition ? kEventFrancoisWhistleD : kEventFrancoisWhistleD);
+ getAction()->playAnimation(getData()->entityPosition <= getEntityData(kEntityPlayer)->entityPosition ? kEventFrancoisWhistleD : kEventFrancoisWhistle);
}
getEntities()->loadSceneFromEntityPosition(getData()->car, (EntityPosition)(getData()->entityPosition + 750 * (getData()->direction == kDirectionUp ? -1 : 1)), getData()->direction == kDirectionUp);
break;
diff --git a/engines/lastexpress/entities/mertens.cpp b/engines/lastexpress/entities/mertens.cpp
index e222af4805..d88962fce2 100644
--- a/engines/lastexpress/entities/mertens.cpp
+++ b/engines/lastexpress/entities/mertens.cpp
@@ -390,7 +390,7 @@ IMPLEMENT_FUNCTION_II(10, Mertens, updateEntity, CarIndex, EntityPosition)
break;
case kActionDefault:
- if ((!getProgress().eventCorpseFound && !getEvent(kEventMertensAskTylerCompartment) && !getEvent(kEventMertensAskTylerCompartment))
+ if ((!getProgress().eventCorpseFound && !getEvent(kEventMertensAskTylerCompartment) && !getEvent(kEventMertensAskTylerCompartmentD))
|| (ENTITY_PARAM(0, 4) && getProgress().jacket == kJacketGreen && !getEvent(kEventMertensDontMakeBed) && !getProgress().eventCorpseThrown))
params->param3 = 1;
diff --git a/engines/lastexpress/game/action.cpp b/engines/lastexpress/game/action.cpp
index 2ef4c20d70..98d74dd1a7 100644
--- a/engines/lastexpress/game/action.cpp
+++ b/engines/lastexpress/game/action.cpp
@@ -1806,7 +1806,7 @@ CursorStyle Action::getCursor(const SceneHotspot &hotspot) const {
if (getProgress().jacket != kJacketGreen)
return kCursorNormal;
- if ((getEvent(kEventCathLookOutsideWindowDay) || getEvent(kEventCathLookOutsideWindowDay) || getObjects()->get(kObjectCompartment1).location2 == kObjectLocation1)
+ if ((getEvent(kEventCathLookOutsideWindowDay) || getEvent(kEventCathLookOutsideWindowNight) || getObjects()->get(kObjectCompartment1).location2 == kObjectLocation1)
&& getProgress().isTrainRunning
&& (object != kObjectOutsideAnnaCompartment || (getEntities()->isInsideCompartment(kEntityRebecca, kCarRedSleeping, kPosition_4840) && getObjects()->get(kObjectOutsideBetweenCompartments).location == 2))
&& getInventory()->getSelectedItem() != kItemBriefcase && getInventory()->getSelectedItem() != kItemFirebird)
diff --git a/engines/lastexpress/game/entities.cpp b/engines/lastexpress/game/entities.cpp
index 1b31339b7b..f27087a609 100644
--- a/engines/lastexpress/game/entities.cpp
+++ b/engines/lastexpress/game/entities.cpp
@@ -87,16 +87,15 @@ static const EntityPosition objectsPosition[8] = {kPosition_8200, kPosition_7500
kPosition_4840, kPosition_4070,
kPosition_3050, kPosition_2740};
-static const EntityPosition entityPositions[41] = {
- kPositionNone, kPosition_851, kPosition_1430, kPosition_2110, kPositionNone,
- kPosition_2410, kPosition_2980, kPosition_3450, kPosition_3760, kPosition_4100,
- kPosition_4680, kPosition_5140, kPosition_5440, kPosition_5810, kPosition_6410,
- kPosition_6850, kPosition_7160, kPosition_7510, kPosition_8514, kPositionNone,
- kPositionNone, kPositionNone, kPosition_2086, kPosition_2690, kPositionNone,
- kPosition_3110, kPosition_3390, kPosition_3890, kPosition_4460, kPosition_4770,
- kPosition_5090, kPosition_5610, kPosition_6160, kPosition_6460, kPosition_6800,
- kPosition_7320, kPosition_7870, kPosition_8160, kPosition_8500, kPosition_9020,
- kPosition_9269};
+static const EntityPosition entityPositions[41] = {kPositionNone, kPosition_851, kPosition_1430, kPosition_2110, kPositionNone,
+ kPosition_2410, kPosition_2980, kPosition_3450, kPosition_3760, kPosition_4100,
+ kPosition_4680, kPosition_5140, kPosition_5440, kPosition_5810, kPosition_6410,
+ kPosition_6850, kPosition_7160, kPosition_7510, kPosition_8514, kPositionNone,
+ kPositionNone, kPositionNone, kPosition_2086, kPosition_2690, kPositionNone,
+ kPosition_3110, kPosition_3390, kPosition_3890, kPosition_4460, kPosition_4770,
+ kPosition_5090, kPosition_5610, kPosition_6160, kPosition_6460, kPosition_6800,
+ kPosition_7320, kPosition_7870, kPosition_8160, kPosition_8500, kPosition_9020,
+ kPosition_9269};
#define ADD_ENTITY(class) \
_entities.push_back(new class(engine));
@@ -105,7 +104,7 @@ static const EntityPosition entityPositions[41] = {
sequenceTo = sequenceFrom; \
for (int seqIdx = 0; seqIdx < 7; seqIdx++) \
sequenceTo.deleteLastChar(); \
- if (isInsideTrainCar(entityIndex, kCarGreenSleeping) || isInsideTrainCar(entityIndex, kCarGreenSleeping)) { \
+ if (isInsideTrainCar(entityIndex, kCarGreenSleeping) || isInsideTrainCar(entityIndex, kCarRedSleeping)) { \
if (data->car < getData(kEntityPlayer)->car || (data->car == getData(kEntityPlayer)->car && data->entityPosition < getData(kEntityPlayer)->entityPosition)) \
sequenceTo += "R.SEQ"; \
else \
@@ -616,9 +615,9 @@ void Entities::resetSequences(EntityIndex entityIndex) const {
getData(entityIndex)->field_4A9 = false;
getData(entityIndex)->field_4AA = false;
- strcpy((char*)&getData(entityIndex)->sequenceNameCopy, "");
- strcpy((char*)&getData(entityIndex)->sequenceName, "");
- strcpy((char*)&getData(entityIndex)->sequenceName2, "");
+ strcpy((char *)&getData(entityIndex)->sequenceNameCopy, "");
+ strcpy((char *)&getData(entityIndex)->sequenceName, "");
+ strcpy((char *)&getData(entityIndex)->sequenceName2, "");
getScenes()->resetQueue();
}
diff --git a/engines/lastexpress/game/savegame.cpp b/engines/lastexpress/game/savegame.cpp
index 57c18b5697..9c464feb6e 100644
--- a/engines/lastexpress/game/savegame.cpp
+++ b/engines/lastexpress/game/savegame.cpp
@@ -154,11 +154,11 @@ void SaveLoad::loadStream(GameId id) {
error("[SaveLoad::loadStream] Savegame stream is invalid");
// Load all savegame data
- uint8* buf = new uint8[8192];
+ uint8 *buf = new uint8[8192];
while (!save->eos() && !save->err()) {
_engine->pollEvents();
- uint32 count = save->read(buf, sizeof(buf));
+ uint32 count = save->read(buf, 8192);
if (count) {
uint32 w = _savegame->write(buf, count);
assert (w == count);
diff --git a/engines/lastexpress/resource.cpp b/engines/lastexpress/resource.cpp
index 3910aaa010..ee4885e34e 100644
--- a/engines/lastexpress/resource.cpp
+++ b/engines/lastexpress/resource.cpp
@@ -148,8 +148,8 @@ Common::SeekableReadStream *ResourceManager::getFileStream(const Common::String
//////////////////////////////////////////////////////////////////////////
// Archive functions
//////////////////////////////////////////////////////////////////////////
-bool ResourceManager::hasFile(const Common::String &name) {
- for (Common::Array<HPFArchive *>::iterator it = _archives.begin(); it != _archives.end(); ++it) {
+bool ResourceManager::hasFile(const Common::String &name) const {
+ for (Common::Array<HPFArchive *>::const_iterator it = _archives.begin(); it != _archives.end(); ++it) {
if ((*it)->hasFile(name))
return true;
}
@@ -157,10 +157,10 @@ bool ResourceManager::hasFile(const Common::String &name) {
return false;
}
-int ResourceManager::listMembers(Common::ArchiveMemberList &list) {
+int ResourceManager::listMembers(Common::ArchiveMemberList &list) const {
int count = 0;
- for (Common::Array<HPFArchive *>::iterator it = _archives.begin(); it != _archives.end(); ++it) {
+ for (Common::Array<HPFArchive *>::const_iterator it = _archives.begin(); it != _archives.end(); ++it) {
Common::ArchiveMemberList members;
count += (*it)->listMembers(members);
@@ -171,7 +171,7 @@ int ResourceManager::listMembers(Common::ArchiveMemberList &list) {
return count;
}
-Common::ArchiveMemberPtr ResourceManager::getMember(const Common::String &name) {
+const Common::ArchiveMemberPtr ResourceManager::getMember(const Common::String &name) const {
if (!hasFile(name))
return Common::ArchiveMemberPtr();
diff --git a/engines/lastexpress/resource.h b/engines/lastexpress/resource.h
index 9e05a90399..f2f5d63bce 100644
--- a/engines/lastexpress/resource.h
+++ b/engines/lastexpress/resource.h
@@ -45,9 +45,9 @@ public:
Common::SeekableReadStream *getFileStream(const Common::String &name);
// Archive functions
- bool hasFile(const Common::String &name);
- int listMembers(Common::ArchiveMemberList &list);
- Common::ArchiveMemberPtr getMember(const Common::String &name);
+ bool hasFile(const Common::String &name) const;
+ int listMembers(Common::ArchiveMemberList &list) const;
+ const Common::ArchiveMemberPtr getMember(const Common::String &name) const;
Common::SeekableReadStream *createReadStreamForMember(const Common::String &name) const;
// Resource loading
diff --git a/engines/lure/decode.cpp b/engines/lure/decode.cpp
index 59390e6e91..1338559534 100644
--- a/engines/lure/decode.cpp
+++ b/engines/lure/decode.cpp
@@ -34,12 +34,18 @@ namespace Lure {
/* Provides the functionality for decoding screens */
/*--------------------------------------------------------------------------*/
+/**
+ * Write a single byte to the output buffer
+ */
void PictureDecoder::writeByte(MemoryBlock *dest, byte v) {
if (outputOffset == dest->size())
error("Decoded data exceeded allocated output buffer size");
dest->data()[outputOffset++] = v;
}
+/**
+ * Writes out a specified byte a given number of times to the output
+ */
void PictureDecoder::writeBytes(MemoryBlock *dest, byte v, uint16 numBytes) {
if (outputOffset + numBytes > dest->size())
error("Decoded data exceeded allocated output buffer size");
@@ -47,6 +53,9 @@ void PictureDecoder::writeBytes(MemoryBlock *dest, byte v, uint16 numBytes) {
outputOffset += numBytes;
}
+/**
+ * Gets a byte from the compressed source using the first data pointer
+ */
byte PictureDecoder::DSSI(bool incr) {
if (dataPos > dataIn->size())
error("PictureDecoder went beyond end of source data");
@@ -57,6 +66,9 @@ byte PictureDecoder::DSSI(bool incr) {
return result;
}
+/**
+ * Gets a byte from the compressed source using the second data pointer
+ */
byte PictureDecoder::ESBX(bool incr) {
if (dataPos2 >= dataIn->size())
error("PictureDecoder went beyond end of source data");
@@ -227,56 +239,61 @@ MemoryBlock *PictureDecoder::vgaDecode(MemoryBlock *src, uint32 maxOutputSize) {
CH = ESBX();
CL = 9;
-Loc754:
- AL = DSSI();
- writeByte(dest, AL);
- BP = ((uint16) AL) << 2;
-
-Loc755:
- decrCtr();
- if (shlCarry()) goto Loc761;
- decrCtr();
- if (shlCarry()) goto Loc759;
- AL = dataIn->data()[BP];
-
-Loc758:
- writeByte(dest, AL);
- BP = ((uint16) AL) << 2;
- goto Loc755;
-
-Loc759:
- AL = (byte) (BP >> 2);
- AH = DSSI();
- if (AH == 0) goto Loc768;
-
- writeBytes(dest, AL, AH);
- goto Loc755;
-
-Loc761:
- decrCtr();
- if (shlCarry()) goto Loc765;
- decrCtr();
-
- if (shlCarry()) goto Loc764;
- AL = dataIn->data()[BP+1];
- goto Loc758;
-
-Loc764:
- AL = dataIn->data()[BP+2];
- goto Loc758;
-
-Loc765:
- decrCtr();
- if (shlCarry()) goto Loc767;
- AL = dataIn->data()[BP+3];
- goto Loc758;
-
-Loc767:
- goto Loc754;
-
-Loc768:
- AL = DSSI();
- if (AL != 0) goto Loc755;
+ // Main decoding loop
+ bool loopFlag = true;
+ while (loopFlag) {
+ AL = DSSI();
+ writeByte(dest, AL);
+ BP = ((uint16) AL) << 2;
+
+ // Inner loop
+ for (;;) {
+ decrCtr();
+ if (shlCarry()) {
+ decrCtr();
+ if (shlCarry()) {
+ decrCtr();
+ if (shlCarry())
+ break;
+
+ AL = dataIn->data()[BP + 3];
+ } else {
+ decrCtr();
+ if (shlCarry())
+ AL = dataIn->data()[BP + 2];
+ else
+ AL = dataIn->data()[BP + 1];
+ }
+ } else {
+ decrCtr();
+ if (shlCarry()) {
+ AL = (byte) (BP >> 2);
+ AH = DSSI();
+ if (AH == 0) {
+ AL = DSSI();
+ if (AL == 0) {
+ // Finally done
+ loopFlag = false;
+ break;
+ } else {
+ // Keep going
+ continue;
+ }
+ } else {
+ // Write out byte sequence
+ writeBytes(dest, AL, AH);
+ continue;
+ }
+ } else {
+ AL = dataIn->data()[BP];
+ }
+ }
+
+ // Write out the next byte
+ writeByte(dest, AL);
+ BP = ((uint16) AL) << 2;
+ }
+ }
// Resize the output to be the number of outputed bytes and return it
if (outputOffset < dest->size()) dest->reallocate(outputOffset);
@@ -355,106 +372,54 @@ uint32 AnimationDecoder::decode_data(MemoryBlock *src, MemoryBlock *dest, uint32
currData <<= 4;
dx = 1;
- for (;;) {
- carry = false;
- rcl(currData, carry);
- if (--bitCtr == 0) {
- GET_BYTE;
- bitCtr = 8;
- }
- if (carry) goto loc_1441;
- tableOffset = BX_VAL(0);
-
-loc_1439:
- dx ^= 1;
- if ((dx & 1) != 0) {
- SET_HI_BYTE(dx, tableOffset << 4);
- *pDest = dx >> 8;
- } else {
- *pDest++ |= tableOffset;
- }
- continue;
-
-loc_1441:
- rcl(currData, carry);
- if (--bitCtr == 0) {
- GET_BYTE;
- bitCtr = 8;
- }
- if (!carry) {
+ // Main loop
+ bool loopFlag = true;
+ while (loopFlag) {
+ for (;;) {
+ carry = false;
rcl(currData, carry);
if (--bitCtr == 0) {
GET_BYTE;
bitCtr = 8;
}
-
if (!carry) {
- tableOffset = BX_VAL(0x10);
- } else {
- tableOffset = BX_VAL(0x20);
+ tableOffset = BX_VAL(0);
+ break;
}
- goto loc_1439;
- }
-
- rcl(currData, carry);
- if (--bitCtr == 0) {
- GET_BYTE;
- bitCtr = 8;
- }
- if (!carry) {
- tableOffset = BX_VAL(0x30);
- goto loc_1439;
- }
- SET_HI_BYTE(dx, currData >> 12);
- carry = false;
- for (int ctr = 0; ctr < 4; ++ctr) {
rcl(currData, carry);
if (--bitCtr == 0) {
GET_BYTE;
bitCtr = 8;
}
- }
-
- byte dxHigh = dx >> 8;
- if (dxHigh == BX_VAL(0)) {
- tempReg1 = bitCtr;
- tempReg2 = dx;
- decode_data_2(src, pSrc, currData, bitCtr, dx, carry);
-
- SET_LO_BYTE(dx, dx >> 8);
- decode_data_2(src, pSrc, currData, bitCtr, dx, carry);
- SET_HI_BYTE(bitCtr, dx & 0xff);
- SET_LO_BYTE(bitCtr, dx >> 8);
- dx = tempReg2;
-
- if (bitCtr == 0)
- // Exit out of infinite loop
- break;
-
- } else if (dxHigh == BX_VAL(0x10)) {
- tempReg1 = bitCtr;
- decode_data_2(src, pSrc, currData, bitCtr, dx, carry);
- bitCtr = dx >> 8;
-
- } else if (dxHigh == BX_VAL(0x20)) {
- SET_HI_BYTE(dx, currData >> 10);
-
- for (v = 0; v < 6; ++v) {
+ if (!carry) {
rcl(currData, carry);
if (--bitCtr == 0) {
GET_BYTE;
bitCtr = 8;
}
- }
- tempReg1 = bitCtr;
- bitCtr = dx >> 8;
+ if (!carry) {
+ tableOffset = BX_VAL(0x10);
+ } else {
+ tableOffset = BX_VAL(0x20);
+ }
+ break;
+ }
- } else if (dxHigh == BX_VAL(0x30)) {
- SET_HI_BYTE(dx, currData >> 11);
+ rcl(currData, carry);
+ if (--bitCtr == 0) {
+ GET_BYTE;
+ bitCtr = 8;
+ }
+ if (!carry) {
+ tableOffset = BX_VAL(0x30);
+ break;
+ }
- for (v = 0; v < 5; ++v) {
+ SET_HI_BYTE(dx, currData >> 12);
+ carry = false;
+ for (int ctr = 0; ctr < 4; ++ctr) {
rcl(currData, carry);
if (--bitCtr == 0) {
GET_BYTE;
@@ -462,34 +427,92 @@ loc_1441:
}
}
- tempReg1 = bitCtr;
- bitCtr = dx >> 8;
+ byte dxHigh = dx >> 8;
+ if (dxHigh == BX_VAL(0)) {
+ tempReg1 = bitCtr;
+ tempReg2 = dx;
+ decode_data_2(src, pSrc, currData, bitCtr, dx, carry);
+
+ SET_LO_BYTE(dx, dx >> 8);
+ decode_data_2(src, pSrc, currData, bitCtr, dx, carry);
+ SET_HI_BYTE(bitCtr, dx & 0xff);
+ SET_LO_BYTE(bitCtr, dx >> 8);
+ dx = tempReg2;
+
+ if (bitCtr == 0) {
+ // End of decompression
+ loopFlag = false;
+ break;
+ }
+ } else if (dxHigh == BX_VAL(0x10)) {
+ tempReg1 = bitCtr;
+ decode_data_2(src, pSrc, currData, bitCtr, dx, carry);
+ bitCtr = dx >> 8;
+
+ } else if (dxHigh == BX_VAL(0x20)) {
+ SET_HI_BYTE(dx, currData >> 10);
+
+ for (v = 0; v < 6; ++v) {
+ rcl(currData, carry);
+ if (--bitCtr == 0) {
+ GET_BYTE;
+ bitCtr = 8;
+ }
+ }
+
+ tempReg1 = bitCtr;
+ bitCtr = dx >> 8;
- } else {
- tableOffset = dx >> 8;
- goto loc_1439;
- }
+ } else if (dxHigh == BX_VAL(0x30)) {
+ SET_HI_BYTE(dx, currData >> 11);
- if ((dx & 1) == 1) {
- *pDest++ |= tableOffset;
- --bitCtr;
- dx &= 0xfffe;
- }
+ for (v = 0; v < 5; ++v) {
+ rcl(currData, carry);
+ if (--bitCtr == 0) {
+ GET_BYTE;
+ bitCtr = 8;
+ }
+ }
- SET_HI_BYTE(dx, tableOffset << 4);
- tableOffset |= dx >> 8;
+ tempReg1 = bitCtr;
+ bitCtr = dx >> 8;
- v = bitCtr >> 1;
- while (v-- > 0) *pDest++ = tableOffset;
+ } else {
+ tableOffset = dx >> 8;
+ break;
+ }
- bitCtr &= 1;
- if (bitCtr != 0) {
- *pDest = tableOffset & 0xf0;
- dx |= 1; //dx.l
+ if ((dx & 1) == 1) {
+ *pDest++ |= tableOffset;
+ --bitCtr;
+ dx &= 0xfffe;
+ }
+
+ SET_HI_BYTE(dx, tableOffset << 4);
+ tableOffset |= dx >> 8;
+
+ v = bitCtr >> 1;
+ while (v-- > 0) *pDest++ = tableOffset;
+
+ bitCtr &= 1;
+ if (bitCtr != 0) {
+ *pDest = tableOffset & 0xf0;
+ dx |= 1; //dx.l
+ }
+
+ bitCtr = tempReg1;
+ tableOffset &= 0x0f;
}
- bitCtr = tempReg1;
- tableOffset &= 0x0f;
+ if (loopFlag) {
+ dx ^= 1;
+ if ((dx & 1) != 0) {
+ SET_HI_BYTE(dx, tableOffset << 4);
+ *pDest = dx >> 8;
+ } else {
+ *pDest++ |= tableOffset;
+ }
+ }
}
// Return number of bytes written
diff --git a/engines/lure/detection.cpp b/engines/lure/detection.cpp
index 276b2d77af..ab7615c265 100644
--- a/engines/lure/detection.cpp
+++ b/engines/lure/detection.cpp
@@ -72,7 +72,7 @@ static const LureGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformPC,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO0()
},
GF_FLOPPY,
},
@@ -85,7 +85,7 @@ static const LureGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformPC,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO0()
},
GF_FLOPPY | GF_EGA,
},
@@ -98,7 +98,7 @@ static const LureGameDescription gameDescriptions[] = {
Common::IT_ITA,
Common::kPlatformPC,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO0()
},
GF_FLOPPY,
},
@@ -111,7 +111,7 @@ static const LureGameDescription gameDescriptions[] = {
Common::IT_ITA,
Common::kPlatformPC,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO0()
},
GF_FLOPPY | GF_EGA,
},
@@ -124,7 +124,7 @@ static const LureGameDescription gameDescriptions[] = {
Common::DE_DEU,
Common::kPlatformPC,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO0()
},
GF_FLOPPY,
},
@@ -137,7 +137,7 @@ static const LureGameDescription gameDescriptions[] = {
Common::DE_DEU,
Common::kPlatformPC,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO0()
},
GF_FLOPPY,
},
@@ -150,7 +150,7 @@ static const LureGameDescription gameDescriptions[] = {
Common::FR_FRA,
Common::kPlatformPC,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO0()
},
GF_FLOPPY,
},
@@ -163,7 +163,7 @@ static const LureGameDescription gameDescriptions[] = {
Common::ES_ESP,
Common::kPlatformPC,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO0()
},
GF_FLOPPY,
},
diff --git a/engines/lure/hotspots.cpp b/engines/lure/hotspots.cpp
index 96e5e088ab..c7e7e81900 100644
--- a/engines/lure/hotspots.cpp
+++ b/engines/lure/hotspots.cpp
@@ -179,7 +179,6 @@ Hotspot::Hotspot(): _pathFinder(NULL) {
_walkFlag = false;
_skipFlag = false;
_roomNumber = 0;
- _destHotspotId = 0;
_startX = 0;
_startY = 0;
_destX = 0;
@@ -2335,9 +2334,11 @@ void Hotspot::saveToStream(Common::WriteStream *stream) {
void Hotspot::loadFromStream(Common::ReadStream *stream) {
if (_data)
_data->npcSchedule.loadFromStream(stream);
- else
+ else {
// Dummy read of terminator for empty actions list
- assert(stream->readByte() == 0xff);
+ byte dummy = stream->readByte();
+ assert(dummy == 0xff);
+ }
_pathFinder.loadFromStream(stream);
@@ -4165,6 +4166,7 @@ PathFinderResult PathFinder::process() {
bool altFlag;
uint16 *pCurrent;
PathFinderResult result = PF_UNFINISHED;
+ bool skipToFinalStep = false;
if (!_inProgress) {
// Following code only done during first call to method
@@ -4187,188 +4189,190 @@ PathFinderResult PathFinder::process() {
_inProgress = false;
result = PF_OK;
- goto final_step;
- }
-
- // Path finding
+ skipToFinalStep = true;
+ } else {
+ // Path finding
- _destX >>= 3;
- _destY >>= 3;
- _pSrc = &_layer[(_yCurrent + 1) * DECODED_PATHS_WIDTH + 1 + _xCurrent];
- _pDest = &_layer[(_yDestCurrent + 1) * DECODED_PATHS_WIDTH + 1 + _xDestCurrent];
+ _destX >>= 3;
+ _destY >>= 3;
+ _pSrc = &_layer[(_yCurrent + 1) * DECODED_PATHS_WIDTH + 1 + _xCurrent];
+ _pDest = &_layer[(_yDestCurrent + 1) * DECODED_PATHS_WIDTH + 1 + _xDestCurrent];
- // Flag starting/ending cells
- *_pSrc = 1;
- _destOccupied = *_pDest != 0;
- result = _destOccupied ? PF_DEST_OCCUPIED : PF_OK;
- *_pDest = 0;
+ // Flag starting/ending cells
+ *_pSrc = 1;
+ _destOccupied = *_pDest != 0;
+ result = _destOccupied ? PF_DEST_OCCUPIED : PF_OK;
+ *_pDest = 0;
- // Set up the current pointer, adjusting away from edges if necessary
+ // Set up the current pointer, adjusting away from edges if necessary
- if (_xCurrent >= _xDestCurrent) {
- _xChangeInc = -1;
- _xChangeStart = ROOM_PATHS_WIDTH;
- } else {
- _xChangeInc = 1;
- _xChangeStart = 1;
- }
+ if (_xCurrent >= _xDestCurrent) {
+ _xChangeInc = -1;
+ _xChangeStart = ROOM_PATHS_WIDTH;
+ } else {
+ _xChangeInc = 1;
+ _xChangeStart = 1;
+ }
- if (_yCurrent >= _yDestCurrent) {
- _yChangeInc = -1;
- _yChangeStart = ROOM_PATHS_HEIGHT;
- } else {
- _yChangeInc = 1;
- _yChangeStart = 1;
+ if (_yCurrent >= _yDestCurrent) {
+ _yChangeInc = -1;
+ _yChangeStart = ROOM_PATHS_HEIGHT;
+ } else {
+ _yChangeInc = 1;
+ _yChangeStart = 1;
+ }
}
}
- // Major loop to populate data
- _cellPopulated = false;
-
- while (1) {
- // Loop through to process cells in the given area
- if (!returnFlag) _yCtr = 0;
- while (returnFlag || (_yCtr < ROOM_PATHS_HEIGHT)) {
- if (!returnFlag) _xCtr = 0;
+ if (!skipToFinalStep) {
+ // Major loop to populate data
+ _cellPopulated = false;
- while (returnFlag || (_xCtr < ROOM_PATHS_WIDTH)) {
- if (!returnFlag) {
- processCell(&_layer[(_yChangeStart + _yCtr * _yChangeInc) * DECODED_PATHS_WIDTH +
- (_xChangeStart + _xCtr * _xChangeInc)]);
- if (breakFlag && (_countdownCtr <= 0)) return PF_UNFINISHED;
- } else {
- returnFlag = false;
+ while (1) {
+ // Loop through to process cells in the given area
+ if (!returnFlag) _yCtr = 0;
+ while (returnFlag || (_yCtr < ROOM_PATHS_HEIGHT)) {
+ if (!returnFlag) _xCtr = 0;
+
+ while (returnFlag || (_xCtr < ROOM_PATHS_WIDTH)) {
+ if (!returnFlag) {
+ processCell(&_layer[(_yChangeStart + _yCtr * _yChangeInc) * DECODED_PATHS_WIDTH +
+ (_xChangeStart + _xCtr * _xChangeInc)]);
+ if (breakFlag && (_countdownCtr <= 0)) return PF_UNFINISHED;
+ } else {
+ returnFlag = false;
+ }
+ ++_xCtr;
}
- ++_xCtr;
+ ++_yCtr;
}
- ++_yCtr;
- }
- // If the destination cell has been filled in, then break out of loop
- if (*_pDest != 0) break;
+ // If the destination cell has been filled in, then break out of loop
+ if (*_pDest != 0) break;
- if (_cellPopulated) {
- // At least one cell populated, so go repeat loop
- _cellPopulated = false;
- } else {
- result = PF_PART_PATH;
- scanFlag = true;
- break;
+ if (_cellPopulated) {
+ // At least one cell populated, so go repeat loop
+ _cellPopulated = false;
+ } else {
+ result = PF_PART_PATH;
+ scanFlag = true;
+ break;
+ }
}
- }
- _inProgress = false;
+ _inProgress = false;
- if (scanFlag || _destOccupied) {
- // Adjust the end point if necessary to stop character walking into occupied area
+ if (scanFlag || _destOccupied) {
+ // Adjust the end point if necessary to stop character walking into occupied area
- // Restore destination's occupied state if necessary
- if (_destOccupied) {
- *_pDest = 0xffff;
- _destOccupied = false;
- }
+ // Restore destination's occupied state if necessary
+ if (_destOccupied) {
+ *_pDest = 0xffff;
+ _destOccupied = false;
+ }
- // Scan through lines
- v = 0xff;
- pTemp = _pDest;
- scanLine(_destX, -1, pTemp, v);
- scanLine(ROOM_PATHS_WIDTH - _destX, 1, pTemp, v);
- scanLine(_destY, -DECODED_PATHS_WIDTH, pTemp, v);
- scanLine(ROOM_PATHS_HEIGHT - _destY, DECODED_PATHS_WIDTH, pTemp, v);
+ // Scan through lines
+ v = 0xff;
+ pTemp = _pDest;
+ scanLine(_destX, -1, pTemp, v);
+ scanLine(ROOM_PATHS_WIDTH - _destX, 1, pTemp, v);
+ scanLine(_destY, -DECODED_PATHS_WIDTH, pTemp, v);
+ scanLine(ROOM_PATHS_HEIGHT - _destY, DECODED_PATHS_WIDTH, pTemp, v);
+
+ if (pTemp == _pDest) {
+ clear();
+ return PF_NO_WALK;
+ }
- if (pTemp == _pDest) {
- clear();
- return PF_NO_WALK;
+ _pDest = pTemp;
}
- _pDest = pTemp;
- }
-
- // ****DEBUG****
- if (_hotspot->hotspotId() == PLAYER_ID) {
- for (int ctr = 0; ctr < DECODED_PATHS_WIDTH * DECODED_PATHS_HEIGHT; ++ctr)
- Room::getReference().tempLayer[ctr] = _layer[ctr];
- }
+ // ****DEBUG****
+ if (_hotspot->hotspotId() == PLAYER_ID) {
+ for (int ctr = 0; ctr < DECODED_PATHS_WIDTH * DECODED_PATHS_HEIGHT; ++ctr)
+ Room::getReference().tempLayer[ctr] = _layer[ctr];
+ }
- // Determine the walk path by working backwards from the destination, adding in the
- // walking steps in reverse order until source is reached
- int stageCtr;
- for (stageCtr = 0; stageCtr < 3; ++stageCtr) {
- // Clear out any previously determined directions
- clear();
+ // Determine the walk path by working backwards from the destination, adding in the
+ // walking steps in reverse order until source is reached
+ int stageCtr;
+ for (stageCtr = 0; stageCtr < 3; ++stageCtr) {
+ // Clear out any previously determined directions
+ clear();
- altFlag = stageCtr == 1;
- pCurrent = _pDest;
+ altFlag = stageCtr == 1;
+ pCurrent = _pDest;
+
+ numSteps = 0;
+ currDirection = NO_DIRECTION;
+ while (1) {
+ v = *pCurrent - 1;
+ if (v == 0) break;
+
+ newDirection = NO_DIRECTION;
+ if (!altFlag && (currDirection != LEFT) && (currDirection != RIGHT)) {
+ // Standard order direction checking
+ if (*(pCurrent - DECODED_PATHS_WIDTH) == v) newDirection = DOWN;
+ else if (*(pCurrent + DECODED_PATHS_WIDTH) == v) newDirection = UP;
+ else if (*(pCurrent + 1) == v) newDirection = LEFT;
+ else if (*(pCurrent - 1) == v) newDirection = RIGHT;
+ } else {
+ // Alternate order direction checking
+ if (*(pCurrent + 1) == v) newDirection = LEFT;
+ else if (*(pCurrent - 1) == v) newDirection = RIGHT;
+ else if (*(pCurrent - DECODED_PATHS_WIDTH) == v) newDirection = DOWN;
+ else if (*(pCurrent + DECODED_PATHS_WIDTH) == v) newDirection = UP;
+ }
+ if (newDirection == NO_DIRECTION)
+ error("Path finding process failed");
- numSteps = 0;
- currDirection = NO_DIRECTION;
- while (1) {
- v = *pCurrent - 1;
- if (v == 0) break;
-
- newDirection = NO_DIRECTION;
- if (!altFlag && (currDirection != LEFT) && (currDirection != RIGHT)) {
- // Standard order direction checking
- if (*(pCurrent - DECODED_PATHS_WIDTH) == v) newDirection = DOWN;
- else if (*(pCurrent + DECODED_PATHS_WIDTH) == v) newDirection = UP;
- else if (*(pCurrent + 1) == v) newDirection = LEFT;
- else if (*(pCurrent - 1) == v) newDirection = RIGHT;
- } else {
- // Alternate order direction checking
- if (*(pCurrent + 1) == v) newDirection = LEFT;
- else if (*(pCurrent - 1) == v) newDirection = RIGHT;
- else if (*(pCurrent - DECODED_PATHS_WIDTH) == v) newDirection = DOWN;
- else if (*(pCurrent + DECODED_PATHS_WIDTH) == v) newDirection = UP;
- }
- if (newDirection == NO_DIRECTION)
- error("Path finding process failed");
+ // Process for the specified direction
+ if (newDirection != currDirection) add(newDirection, 0);
- // Process for the specified direction
- if (newDirection != currDirection) add(newDirection, 0);
+ switch (newDirection) {
+ case UP:
+ pCurrent += DECODED_PATHS_WIDTH;
+ break;
- switch (newDirection) {
- case UP:
- pCurrent += DECODED_PATHS_WIDTH;
- break;
+ case DOWN:
+ pCurrent -= DECODED_PATHS_WIDTH;
+ break;
- case DOWN:
- pCurrent -= DECODED_PATHS_WIDTH;
- break;
+ case LEFT:
+ ++pCurrent;
+ break;
- case LEFT:
- ++pCurrent;
- break;
+ case RIGHT:
+ --pCurrent;
+ break;
- case RIGHT:
- --pCurrent;
- break;
+ default:
+ break;
+ }
- default:
- break;
+ ++numSteps;
+ top().rawSteps() += 8;
+ currDirection = newDirection;
}
- ++numSteps;
- top().rawSteps() += 8;
- currDirection = newDirection;
+ if (stageCtr == 0)
+ // Save the number of steps needed
+ savedSteps = numSteps;
+ if ((stageCtr == 1) && (numSteps <= savedSteps))
+ // Less steps were needed, so break out
+ break;
}
- if (stageCtr == 0)
- // Save the number of steps needed
- savedSteps = numSteps;
- if ((stageCtr == 1) && (numSteps <= savedSteps))
- // Less steps were needed, so break out
- break;
- }
-
- // Add final movement if necessary
+ // Add final movement if necessary
- if (result == PF_OK) {
- if (_xDestPos < 0)
- addBack(LEFT, -_xDestPos);
- else if (_xDestPos > 0)
- addBack(RIGHT, _xDestPos);
+ if (result == PF_OK) {
+ if (_xDestPos < 0)
+ addBack(LEFT, -_xDestPos);
+ else if (_xDestPos > 0)
+ addBack(RIGHT, _xDestPos);
+ }
}
-final_step:
+ // Final Step
if (_xPos < 0) add(RIGHT, -_xPos);
else if (_xPos > 0) add(LEFT, _xPos);
diff --git a/engines/lure/menu.cpp b/engines/lure/menu.cpp
index 9919471c76..61de2bf165 100644
--- a/engines/lure/menu.cpp
+++ b/engines/lure/menu.cpp
@@ -515,7 +515,9 @@ uint16 PopupMenu::Show(int numEntries, const char *actions[]) {
r.top = Surface::textY();
r.bottom = s->height() - Surface::textY() + 1;
- for (;;) {
+ bool bailOut = false;
+
+ while (!bailOut) {
if (refreshFlag) {
// Set up the contents of the menu
s->fillRect(r, bgColor);
@@ -546,8 +548,8 @@ uint16 PopupMenu::Show(int numEntries, const char *actions[]) {
while (e.pollEvent()) {
if (engine.shouldQuit()) {
selectedIndex = 0xffff;
- goto bail_out;
-
+ bailOut = true;
+ break;
} else if (e.type() == Common::EVENT_WHEELUP) {
// Scroll upwards
if (selectedIndex > 0) {
@@ -571,10 +573,12 @@ uint16 PopupMenu::Show(int numEntries, const char *actions[]) {
++selectedIndex;
refreshFlag = true;
} else if ((keycode == Common::KEYCODE_RETURN) || (keycode == Common::KEYCODE_KP_ENTER)) {
- goto bail_out;
+ bailOut = true;
+ break;
} else if (keycode == Common::KEYCODE_ESCAPE) {
selectedIndex = 0xffff;
- goto bail_out;
+ bailOut = true;
+ break;
}
#ifdef LURE_CLICKABLE_MENUS
@@ -586,46 +590,51 @@ uint16 PopupMenu::Show(int numEntries, const char *actions[]) {
if (r.contains(x, y)) {
selectedIndex = (y - r.top) / FONT_HEIGHT;
if (e.type() == Common::EVENT_LBUTTONDOWN)
- goto bail_out;
+ bailOut = true;
+ break;
}
#else
} else if ((e.type() == Common::EVENT_LBUTTONDOWN) ||
(e.type() == Common::EVENT_MBUTTONDOWN)) {
//mouse.waitForRelease();
- goto bail_out;
+ bailOut = true;
+ break;
#endif
} else if (e.type() == Common::EVENT_RBUTTONDOWN) {
mouse.waitForRelease();
selectedIndex = 0xffff;
- goto bail_out;
+ bailOut = true;
+ break;
}
}
+ if (!bailOut) {
#ifndef LURE_CLICKABLE_MENUS
- // Warping the mouse to "neutral" even if the top/bottom menu
- // entry has been reached has both pros and cons. It makes the
- // menu behave a bit more sensibly, but it also makes it harder
- // to move the mouse pointer out of the ScummVM window.
-
- if (mouse.y() < yMiddle - POPMENU_CHANGE_SENSITIVITY) {
- if (selectedIndex > 0) {
- --selectedIndex;
- refreshFlag = true;
- }
- mouse.setPosition(FULL_SCREEN_WIDTH / 2, yMiddle);
- } else if (mouse.y() > yMiddle + POPMENU_CHANGE_SENSITIVITY) {
- if (selectedIndex < numEntries - 1) {
- ++selectedIndex;
- refreshFlag = true;
+ // Warping the mouse to "neutral" even if the top/bottom menu
+ // entry has been reached has both pros and cons. It makes the
+ // menu behave a bit more sensibly, but it also makes it harder
+ // to move the mouse pointer out of the ScummVM window.
+
+ if (mouse.y() < yMiddle - POPMENU_CHANGE_SENSITIVITY) {
+ if (selectedIndex > 0) {
+ --selectedIndex;
+ refreshFlag = true;
+ }
+ mouse.setPosition(FULL_SCREEN_WIDTH / 2, yMiddle);
+ } else if (mouse.y() > yMiddle + POPMENU_CHANGE_SENSITIVITY) {
+ if (selectedIndex < numEntries - 1) {
+ ++selectedIndex;
+ refreshFlag = true;
+ }
+ mouse.setPosition(FULL_SCREEN_WIDTH / 2, yMiddle);
}
- mouse.setPosition(FULL_SCREEN_WIDTH / 2, yMiddle);
- }
#endif
- system.delayMillis(20);
+ system.delayMillis(20);
+ }
}
-bail_out:
+ // bailOut
delete s;
#ifndef LURE_CLICKABLE_MENUS
diff --git a/engines/lure/res.cpp b/engines/lure/res.cpp
index fbf9f33b87..6328301233 100644
--- a/engines/lure/res.cpp
+++ b/engines/lure/res.cpp
@@ -408,7 +408,7 @@ byte *Resources::getCursor(uint8 cursorNum) {
if (!LureEngine::getReference().isEGA())
return _cursors->data() + (cursorNum * CURSOR_SIZE);
- Common::set_to(&_cursor[0], &_cursor[0] + CURSOR_SIZE, 0);
+ Common::fill(&_cursor[0], &_cursor[0] + CURSOR_SIZE, 0);
byte *pSrc = _cursors->data() + (cursorNum * 64);
byte *pDest = &_cursor[0];
diff --git a/engines/lure/room.cpp b/engines/lure/room.cpp
index 2cb871d73f..219ed0263d 100644
--- a/engines/lure/room.cpp
+++ b/engines/lure/room.cpp
@@ -43,7 +43,7 @@ RoomLayer::RoomLayer(uint16 screenId, bool backgroundLayer):
int cellIndex = 0;
// Reset all the cells to unused
- Common::set_to((uint8 *) _cells, (uint8 *) _cells + GRID_SIZE, 0xff);
+ Common::fill((uint8 *) _cells, (uint8 *) _cells + GRID_SIZE, 0xff);
// Load up the screen data
MemoryBlock *rawData = disk.getEntry(screenId);
diff --git a/engines/lure/scripts.cpp b/engines/lure/scripts.cpp
index 22656dd3fe..df2f06df96 100644
--- a/engines/lure/scripts.cpp
+++ b/engines/lure/scripts.cpp
@@ -499,7 +499,7 @@ void Script::fixGoewin(uint16 v1, uint16 v2, uint16 v3) {
hotspot->currentActions().clear();
hotspot->currentActions().addFront(DISPATCH_ACTION, entry, hotspot->roomNumber());
- hotspot->setActions(hotspot->resource()->actions & !(1 << (TELL - 1)));
+ hotspot->setActions(hotspot->resource()->actions & ~(1 << (TELL - 1)));
hotspot->setActionCtr(0);
hotspot->setDelayCtr(0);
hotspot->setCharacterMode(CHARMODE_NONE);
diff --git a/engines/lure/sound.cpp b/engines/lure/sound.cpp
index 85b86a8400..bf0abdea07 100644
--- a/engines/lure/sound.cpp
+++ b/engines/lure/sound.cpp
@@ -53,7 +53,7 @@ SoundManager::SoundManager() {
_isRoland = MidiDriver::getMusicType(dev) != MT_ADLIB;
_nativeMT32 = ((MidiDriver::getMusicType(dev) == MT_MT32) || ConfMan.getBool("native_mt32"));
- Common::set_to(_channelsInUse, _channelsInUse + NUM_CHANNELS, false);
+ Common::fill(_channelsInUse, _channelsInUse + NUM_CHANNELS, false);
_driver = MidiDriver::createMidi(dev);
int statusCode = _driver->open();
@@ -182,7 +182,7 @@ void SoundManager::killSounds() {
// Clear the active sounds
_activeSounds.clear();
- Common::set_to(_channelsInUse, _channelsInUse + NUM_CHANNELS, false);
+ Common::fill(_channelsInUse, _channelsInUse + NUM_CHANNELS, false);
}
void SoundManager::addSound(uint8 soundIndex, bool tidyFlag) {
@@ -221,7 +221,7 @@ void SoundManager::addSound(uint8 soundIndex, bool tidyFlag) {
}
// Mark the found channels as in use
- Common::set_to(_channelsInUse+channelCtr, _channelsInUse+channelCtr + numChannels, true);
+ Common::fill(_channelsInUse+channelCtr, _channelsInUse+channelCtr + numChannels, true);
SoundDescResource *newEntry = new SoundDescResource();
newEntry->soundNumber = rec.soundNumber;
@@ -342,7 +342,7 @@ void SoundManager::tidySounds() {
++i;
else {
// Mark the channels that it used as now being free
- Common::set_to(_channelsInUse+rec->channel, _channelsInUse+rec->channel+rec->numChannels, false);
+ Common::fill(_channelsInUse+rec->channel, _channelsInUse+rec->channel+rec->numChannels, false);
i = _activeSounds.erase(i);
}
@@ -373,7 +373,7 @@ void SoundManager::restoreSounds() {
SoundDescResource *rec = (*i).get();
if ((rec->numChannels != 0) && ((rec->flags & SF_RESTORE) != 0)) {
- Common::set_to(_channelsInUse+rec->channel, _channelsInUse+rec->channel+rec->numChannels, true);
+ Common::fill(_channelsInUse+rec->channel, _channelsInUse+rec->channel+rec->numChannels, true);
musicInterface_Play(rec->soundNumber, rec->channel, rec->numChannels);
musicInterface_SetVolume(rec->channel, rec->volume);
@@ -635,7 +635,7 @@ MidiMusic::MidiMusic(MidiDriver *driver, ChannelEntry channels[NUM_CHANNELS],
for (uint i = 0; i < packedSize; i++)
#if defined(SCUMM_NEED_ALIGNMENT)
- memcpy(dataDest++, (byte*)((byte*)data + *(idx + i) * sizeof(uint16)), sizeof(uint16));
+ memcpy(dataDest++, (byte *)((byte *)data + *(idx + i) * sizeof(uint16)), sizeof(uint16));
#else
*dataDest++ = data[*(idx + i)];
#endif
diff --git a/engines/m4/actor.cpp b/engines/m4/actor.cpp
deleted file mode 100644
index 80a3624475..0000000000
--- a/engines/m4/actor.cpp
+++ /dev/null
@@ -1,199 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#include "common/system.h"
-#include "common/array.h"
-#include "common/textconsole.h"
-#include "m4/actor.h"
-#include "m4/m4_views.h"
-#include "m4/assets.h"
-
-namespace M4 {
-
-#define WALKER_BURGER "Wilbur0%i" // wilbur, with a number denoting his current direction
-
-Actor::Actor(MadsM4Engine *vm) : _vm(vm) {
- _scaling = 100;
- _direction = 5;
- _walkerSprites.resize(10);
- loadWalkers();
-}
-
-Actor::~Actor() {
- unloadWalkers();
-}
-
-int Actor::getWalkerWidth() { return _walkerSprites[kFacingSouth]->getFrame(0)->width(); }
-int Actor::getWalkerHeight() { return _walkerSprites[kFacingSouth]->getFrame(0)->height(); }
-
-void Actor::placeWalkerSpriteAt(int spriteNum, int x, int y) {
- if (_direction < 1 || _direction > 9) {
- warning("Direction is %i, fixing", _direction);
- _direction = 1; // TODO: this is a temporary fix
- }
- SpriteInfo info;
- info.sprite = _walkerSprites[_direction]->getFrame(spriteNum);
- info.hotX = info.hotY = 0;
- info.width = info.sprite->width();
- info.height = info.sprite->height();
- info.scaleX = info.scaleY = _scaling;
- info.palette = _walkerSprites[_direction]->getPalette();
- info.inverseColorTable = _m4Vm->scene()->getInverseColorTable();
-
- _vm->_scene->drawSprite(x, y, info, Common::Rect(640, 400));
-}
-
-void Actor::loadWalkers() {
- for (uint8 i = 1; i < 10; i++) {
- if (i == 6)
- continue; // walker sprite 6 is unused
- loadWalkerDirection(i);
- }
-}
-
-void Actor::loadWalkerDirection(uint8 direction) {
- char name[20];
- Common::SeekableReadStream *walkerS;
-
- if (_vm->getGameType() == GType_Burger) {
- sprintf(name, WALKER_BURGER, direction);
- } else {
- //warning("Actor::loadWalkerDirection: unspecified walker type, not loading walker");
- // TODO: Master Lu walkers
- return;
- }
-
- walkerS = _vm->res()->get(name);
- _walkerSprites.insert_at(direction, new SpriteAsset(_vm, walkerS, walkerS->size(), name));
- _vm->res()->toss(name);
-}
-
-void Actor::unloadWalkers() {
- for (uint8 i = 9; i > 0; i--) {
- if (i == 6)
- continue; // walker sprite 6 is unused
- SpriteAsset *tempSprite = _walkerSprites[i];
- _walkerSprites.remove_at(i);
- delete tempSprite;
- }
-}
-
-void Actor::setWalkerPalette() {
- _vm->_palette->setPalette(_walkerSprites[kFacingSouthEast]->getPalette(), 0,
- _walkerSprites[kFacingSouthEast]->getColorCount());
-}
-
-Inventory::Inventory(MadsM4Engine *vm) : _vm(vm) {
-}
-
-Inventory::~Inventory() {
- _inventory.clear();
-}
-
-void Inventory::registerObject(char* name, int32 scene, int32 icon) {
- InventoryObject *newObject = new InventoryObject();
- int newObjectIndex = 0;
-
- // Capitalize registered inventory object names
- str_upper(name);
-
- newObject->name = strdup(name);
- newObject->scene = scene;
- newObject->icon = icon;
-
- newObjectIndex = _inventory.size();
-
- _inventory.push_back(newObject);
-
- if (scene == BACKPACK)
- addToBackpack(newObjectIndex);
-}
-
-void Inventory::moveObject(char* name, int32 scene) {
- uint i = 0;
-
- for (i = 0; i < _inventory.size(); i++) {
- if (!scumm_stricmp(_inventory[i]->name, name)) {
- if (_inventory[i]->scene == BACKPACK && scene != BACKPACK)
- removeFromBackpack(i);
-
- _inventory[i]->scene = scene;
-
- if (scene == BACKPACK)
- addToBackpack(i);
-
- return;
- }
- }
-}
-
-void Inventory::addToBackpack(uint32 objectIndex) {
- _m4Vm->scene()->getInterface()->inventoryAdd(_inventory[objectIndex]->name, "", _inventory[objectIndex]->icon);
-}
-
-void Inventory::removeFromBackpack(uint32 objectIndex) {
- _m4Vm->scene()->getInterface()->inventoryRemove(_inventory[objectIndex]->name);
-}
-
-bool Inventory::isInCurrentScene(char* name) {
- return (getScene(name) == _vm->_scene->getCurrentScene());
-}
-
-int Inventory::getScene(char* name) {
- uint i = 0;
-
- for (i = 0; i < _inventory.size(); i++) {
- if (!scumm_stricmp(_inventory[i]->name, name))
- return _inventory[i]->scene;
- }
- return UNKNOWN_OBJECT;
-}
-
-int Inventory::getIcon(char* name) {
- uint i = 0;
-
- for (i = 0; i < _inventory.size(); i++) {
- if (!scumm_stricmp(_inventory[i]->name, name))
- return _inventory[i]->icon;
- }
- return UNKNOWN_OBJECT;
-}
-
-int Inventory::getIndex(char* name) {
- uint i = 0;
-
- for (i = 0; i < _inventory.size(); i++) {
- if (!scumm_stricmp(_inventory[i]->name, name))
- return i;
- }
- return UNKNOWN_OBJECT;
-}
-
-void Inventory::clear() {
- for (uint i = 0; i < _inventory.size(); i++) {
- delete _inventory[i]->name;
- delete _inventory[i];
- _inventory.remove_at(i);
- }
-}
-
-} // End of namespace M4
diff --git a/engines/m4/actor.h b/engines/m4/actor.h
deleted file mode 100644
index e28c522df8..0000000000
--- a/engines/m4/actor.h
+++ /dev/null
@@ -1,114 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#ifndef M4_ACTOR_H
-#define M4_ACTOR_H
-
-#include "common/array.h"
-
-#include "m4/m4.h"
-#include "m4/scene.h"
-#include "m4/graphics.h"
-#include "m4/assets.h"
-
-namespace M4 {
-
-struct InventoryObject {
- const char* name;
- int32 scene;
- int32 icon;
-};
-
-enum inventoryObjectFlags {
- UNKNOWN_OBJECT = 997,
- BACKPACK = 998,
- NOWHERE = 999
-};
-
-enum WalkerDirection {
- kFacingNorth = 1, // has shadow
- kFacingNorthEast = 2, // has shadow
- kFacingEast = 3, // has shadow
- kFacingSouthEast = 4, // has shadow
- kFacingSouth = 5, // has shadow
- // 6 is unused
- kFacingSouthAlt = 7, // no shadow
- kFacingSouthWest = 8, // no shadow
- kFacingWest = 9 // no shadow
-};
-
-class Actor {
-public:
- Actor(MadsM4Engine *vm);
- ~Actor();
- void placeWalkerSpriteAt(int spriteNum, int x, int y);
- void setWalkerScaling(int scaling) { _scaling = scaling; }
- int getWalkerScaling() { return _scaling; }
- void setWalkerDirection(uint8 direction) { _direction = direction; }
- uint8 getWalkerDirection() { return _direction; }
- void setWalkerPalette();
- int getWalkerWidth();
- int getWalkerHeight();
-private:
- MadsM4Engine *_vm;
- int _scaling;
- uint8 _direction;
- Common::Array<SpriteAsset*> _walkerSprites;
-
- void loadWalkers();
- void loadWalkerDirection(uint8 direction);
- void unloadWalkers();
-};
-
-// TODO: perhaps the inventory and its view could be merged?
-// TODO: the original game capitalizes all inventory object names
-// internally, which we do as well, but perhaps we could make sure
-// that all object names are parsed with the same case and avoid
-// case-insensitive string comparing through scumm_stricmp, using
-// the normal strcmp method instead
-class Inventory {
-public:
- Inventory(MadsM4Engine *vm);
- ~Inventory();
- void clear();
- void registerObject(char* name, int32 scene, int32 icon);
- void moveObject(char* name, int32 scene);
- void giveToPlayer(char* name) { moveObject(name, BACKPACK); }
- void addToBackpack(uint32 objectIndex);
- void removeFromBackpack(uint32 objectIndex);
- bool isInBackpack(char* name) { return (getScene(name) == BACKPACK); }
- bool isInScene(char* name, int32 scene) { return (getScene(name) == scene); }
- bool isInCurrentScene(char* name);
- int getScene(char* name);
- int getIcon(char* name);
- int getIndex(char* name);
- int getTotalItems() { return _inventory.size(); }
-
-private:
- MadsM4Engine *_vm;
- Common::Array<InventoryObject *> _inventory;
-};
-
-} // End of namespace M4
-
-
-#endif
diff --git a/engines/m4/animation.cpp b/engines/m4/animation.cpp
deleted file mode 100644
index 4f315dd396..0000000000
--- a/engines/m4/animation.cpp
+++ /dev/null
@@ -1,535 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#include "common/textconsole.h"
-
-#include "m4/assets.h"
-#include "m4/animation.h"
-#include "m4/compression.h"
-#include "m4/mads_scene.h"
-
-namespace M4 {
-
-// TODO: this code needs cleanup
-
-MadsAnimation::MadsAnimation(MadsM4Engine *vm, MadsView *view): Animation(vm), _view(view) {
- _font = NULL;
- _resetFlag = false;
- _freeFlag = false;
- _skipLoad = false;
- _unkIndex = -1;
- _messageCtr= 0;
- _field12 = 0;
-
- _currentFrame = 0;
- _oldFrameEntry = 0;
- _nextFrameTimer = _madsVm->_currentTimer;
- _nextScrollTimer = 0;
-}
-
-MadsAnimation::~MadsAnimation() {
- for (uint i = 0; i < _messages.size(); ++i) {
- if (_messages[i].kernelMsgIndex >= 0)
- _view->_kernelMessages.remove(_messages[i].kernelMsgIndex);
- }
-
- // Further deletion logic
- if (_field12) {
- _view->_spriteSlots.deleteSprites(_spriteListIndexes[_spriteListIndex]);
- }
-}
-
-#define FILENAME_SIZE 13
-
-/**
- * Initializes and loads the data of an animation
- */
-void MadsAnimation::initialize(const Common::String &filename, uint16 flags, M4Surface *surface, M4Surface *depthSurface) {
- MadsPack anim(filename.c_str(), _vm);
- bool madsRes = filename[0] == '*';
- char buffer[20];
- int streamIndex = 1;
-
- // Chunk 1: header
- // header
-
- Common::SeekableReadStream *animStream = anim.getItemStream(0);
-
- int spriteListCount = animStream->readUint16LE();
- int miscEntriesCount = animStream->readUint16LE();
- int frameEntryCount = animStream->readUint16LE();
- int messagesCount = animStream->readUint16LE();
- animStream->skip(1);
- _flags = animStream->readByte();
-
- animStream->skip(2);
- _animMode = animStream->readUint16LE();
- _roomNumber = animStream->readUint16LE();
- animStream->skip(2);
- _field12 = animStream->readUint16LE() != 0;
- _spriteListIndex = animStream->readUint16LE();
- _scrollX = animStream->readSint16LE();
- _scrollY = animStream->readSint16LE();
- _scrollTicks = animStream->readUint16LE();
- animStream->skip(8);
-
- animStream->read(buffer, FILENAME_SIZE);
- buffer[FILENAME_SIZE] = '\0';
- _interfaceFile = Common::String(buffer);
-
- for (int i = 0; i < 10; ++i) {
- animStream->read(buffer, FILENAME_SIZE);
- buffer[FILENAME_SIZE] = '\0';
- _spriteSetNames[i] = Common::String(buffer);
- }
-
- animStream->skip(81);
- animStream->read(buffer, FILENAME_SIZE);
- buffer[FILENAME_SIZE] = '\0';
- _lbmFilename = Common::String(buffer);
-
- animStream->skip(365);
- animStream->read(buffer, FILENAME_SIZE);
- buffer[FILENAME_SIZE] = '\0';
- _spritesFilename = Common::String(buffer);
-
- animStream->skip(48);
- animStream->read(buffer, FILENAME_SIZE);
- buffer[FILENAME_SIZE] = '\0';
- _soundName = Common::String(buffer);
-
- animStream->skip(13);
- animStream->read(buffer, FILENAME_SIZE);
- buffer[FILENAME_SIZE] = '\0';
- _dsrName = Common::String(buffer);
-
- animStream->read(buffer, FILENAME_SIZE);
- buffer[FILENAME_SIZE] = '\0';
- Common::String fontResource(buffer);
-
- if (_animMode == 4)
- flags |= 0x4000;
- if (flags & 0x100)
- loadInterface(surface, depthSurface);
-
- // Initialize the reference list
- for (int i = 0; i < spriteListCount; ++i)
- _spriteListIndexes.push_back(-1);
-
- delete animStream;
-
- if (messagesCount > 0) {
- // Chunk 2
- // Following is a list of any messages for the animation
-
- animStream = anim.getItemStream(streamIndex++);
-
- for (int i = 0; i < messagesCount; ++i) {
- AnimMessage rec;
- rec.soundId = animStream->readSint16LE();
- animStream->read(rec.msg, 64);
- animStream->skip(4);
- rec.pos.x = animStream->readSint16LE();
- rec.pos.y = animStream->readSint16LE();
- rec.flags = animStream->readUint16LE();
- rec.rgb1.r = animStream->readByte() << 2;
- rec.rgb1.g = animStream->readByte() << 2;
- rec.rgb1.b = animStream->readByte() << 2;
- rec.rgb2.r = animStream->readByte() << 2;
- rec.rgb2.g = animStream->readByte() << 2;
- rec.rgb2.b = animStream->readByte() << 2;
- animStream->skip(2); // Space for kernelMsgIndex
- rec.kernelMsgIndex = -1;
- animStream->skip(6);
- rec.startFrame = animStream->readUint16LE();
- rec.endFrame = animStream->readUint16LE();
- animStream->skip(2);
-
- _messages.push_back(rec);
- }
-
- delete animStream;
- }
-
- if (frameEntryCount > 0) {
- // Chunk 3: animation frame info
- animStream = anim.getItemStream(streamIndex++);
-
- for (int i = 0; i < frameEntryCount; i++) {
- AnimFrameEntry rec;
- rec.frameNumber = animStream->readUint16LE();
- rec.seqIndex = animStream->readByte();
- rec.spriteSlot.spriteListIndex = animStream->readByte();
- rec.spriteSlot.frameNumber = animStream->readUint16LE();
- rec.spriteSlot.xp = animStream->readSint16LE();
- rec.spriteSlot.yp = animStream->readSint16LE();
- rec.spriteSlot.depth = animStream->readSByte();
- rec.spriteSlot.scale = (int8)animStream->readByte();
-
- _frameEntries.push_back(rec);
- }
-
- delete animStream;
- }
-
- if (miscEntriesCount > 0) {
- // Chunk 4: Misc Data
- animStream = anim.getItemStream(streamIndex);
-
- for (int i = 0; i < miscEntriesCount; ++i) {
- AnimMiscEntry rec;
- rec.soundNum = animStream->readByte();
- rec.msgIndex = animStream->readSByte();
- rec.numTicks = animStream->readUint16LE();
- rec.posAdjust.x = animStream->readUint16LE();
- rec.posAdjust.y = animStream->readUint16LE();
- animStream->readUint16LE();
-
- _miscEntries.push_back(rec);
- }
-
- delete animStream;
- }
-
- // If the animation specifies a font, then load it for access
- if (_flags & ANIM_CUSTOM_FONT) {
- Common::String fontName;
- if (madsRes)
- fontName += "*";
- fontName += fontResource;
-
- if (fontName != "")
- _font = _vm->_font->getFont(fontName.c_str());
- else
- warning("Attempted to set a font with an empty name");
- }
-
- // If a speech file is specified, then load it
- if (!_dsrName.empty())
- _vm->_sound->loadDSRFile(_dsrName.c_str());
-
- // 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
- continue;
-
- _spriteListIndexes[i] = _view->_spriteSlots.addSprites(_spriteSetNames[i].c_str());
- }
-
-
- if (_field12) {
- Common::String resName;
- if (madsRes)
- resName += "*";
- resName += _spriteSetNames[_spriteListIndex];
-
- _spriteListIndexes[_spriteListIndex] = _view->_spriteSlots.addSprites(resName.c_str());
- }
-
- // TODO: Unknown section about handling sprite set list combined with messages size
-
- // TODO: The original has two separate loops for the loop below based on _animMode == 4. Is it
- // perhaps that in that mode the sprite frames has a different format..?
-
- // Remap the sprite list index fields from the initial value to the indexes of the loaded
- // sprite sets for the animation
- for (uint i = 0; i < _frameEntries.size(); ++i) {
- int idx = _frameEntries[i].spriteSlot.spriteListIndex;
- _frameEntries[i].spriteSlot.spriteListIndex = _spriteListIndexes[idx];
- }
-
- if (hasScroll())
- _nextScrollTimer = _madsVm->_currentTimer + _scrollTicks;
-}
-
-/**
- * Loads an animation file for display
- */
-void MadsAnimation::load(const Common::String &filename, int abortTimers) {
- initialize(filename, 0, NULL, NULL);
- _messageCtr = 0;
- _skipLoad = true;
-
-/* TODO: figure out extra stuff in this routine
- if (_field12) {
- _unkIndex = -1;
- int listIndex = _spriteListIndexes[_spriteListIndex];
- SpriteAsset &spriteSet = _view->_spriteSlots.getSprite(listIndex);
- ..?..
- }
-*/
-
- // Initialize miscellaneous fields
- _currentFrame = 0;
- _oldFrameEntry = 0;
- _nextFrameTimer = _madsVm->_currentTimer;
- _abortTimers = abortTimers;
- _abortMode = _madsVm->scene()->_abortTimersMode2;
-
- if (_madsVm->_scene)
- _actionNouns = _madsVm->scene()->_action._action;
-
- // Initialize kernel message list
- for (uint i = 0; i < _messages.size(); ++i)
- _messages[i].kernelMsgIndex = -1;
-}
-
-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;
- if (_frameEntries[idx].spriteSlot.spriteListIndex == spriteListIndex)
- newIndex = _frameEntries[idx].spriteSlot.frameNumber;
- }
-
- if (newIndex >= 0)
- load1(newIndex);
- }
-
- // Check for scroll change
- bool screenChanged = false;
-
- // Handle any scrolling of the screen surface
- if (hasScroll() && (_madsVm->_currentTimer >= _nextScrollTimer)) {
- _view->_bgSurface->scrollX(_scrollX);
- _view->_bgSurface->scrollY(_scrollY);
-
- _nextScrollTimer = _madsVm->_currentTimer + _scrollTicks;
- screenChanged = true;
- }
-
- // If it's not time for the next frame, then exit
- if (_madsVm->_currentTimer < _nextFrameTimer) {
- if (screenChanged)
- _view->_spriteSlots.fullRefresh();
- return;
- }
-
- // Loop checks for any prior animation sprite slots to be expired
- for (int slotIndex = 0; slotIndex < _view->_spriteSlots.startIndex; ++slotIndex) {
- if (_view->_spriteSlots[slotIndex].seqIndex >= 0x80) {
- // Flag the frame as animation sprite slot
- _view->_spriteSlots[slotIndex].spriteType = EXPIRED_SPRITE;
- }
- }
-
- // Validate the current frame
- if (_currentFrame >= (int)_miscEntries.size()) {
- // Is the animation allowed to be repeated?
- if (_resetFlag) {
- _currentFrame = 0;
- _oldFrameEntry = 0;
- } else {
- _freeFlag = true;
- return;
- }
- }
-
- // Handle starting any sound for this frame
- AnimMiscEntry &misc = _miscEntries[_currentFrame];
- if (misc.soundNum)
- _vm->_sound->playSound(misc.soundNum);
-
- // Handle any offset adjustment for sprites as of this frame
- if (_view->_posAdjust.x != misc.posAdjust.x) {
- _view->_posAdjust.x = misc.posAdjust.x;
- screenChanged = true;
- }
- if (_view->_posAdjust.y != misc.posAdjust.y) {
- _view->_posAdjust.y = misc.posAdjust.y;
- screenChanged = true;
- }
-
-
- if (screenChanged) {
- // Signal the entire screen needs refreshing
- _view->_spriteSlots.fullRefresh();
- }
-
- int spriteSlotsMax = _view->_spriteSlots.startIndex;
-
- // Main frame animation loop - frames get animated by being placed, as necessary, into the
- // main sprite slot array
- while ((uint)_oldFrameEntry < _frameEntries.size()) {
- if (_frameEntries[_oldFrameEntry].frameNumber > _currentFrame)
- break;
- else if (_frameEntries[_oldFrameEntry].frameNumber == _currentFrame) {
- // Found the correct frame
- int spriteSlotIndex = 0;
- int index = 0;
-
- for (;;) {
- if ((spriteSlotIndex == 0) && (index < spriteSlotsMax)) {
- int seqIndex = _frameEntries[_oldFrameEntry].seqIndex - _view->_spriteSlots[index].seqIndex;
- if (seqIndex == 0x80) {
- if (_view->_spriteSlots[index] == _frameEntries[_oldFrameEntry].spriteSlot) {
- _view->_spriteSlots[index].spriteType = SPRITE_ZERO;
- spriteSlotIndex = -1;
- }
- }
- ++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;
- }
- break;
- }
- }
-
- ++_oldFrameEntry;
- }
-
- // Handle the display of any messages
- for (uint idx = 0; idx < _messages.size(); ++idx) {
- if (_messages[idx].kernelMsgIndex >= 0) {
- // Handle currently active message
- if ((_currentFrame < _messages[idx].startFrame) || (_currentFrame > _messages[idx].endFrame)) {
- _view->_kernelMessages.remove(_messages[idx].kernelMsgIndex);
- _messages[idx].kernelMsgIndex = -1;
- --_messageCtr;
- }
- } else if ((_currentFrame >= _messages[idx].startFrame) && (_currentFrame <= _messages[idx].endFrame)) {
- // Start displaying the message
- AnimMessage &me = _messages[idx];
-
- // The color index to use is dependant on how many messages are currently on-screen
- uint8 colIndex;
- switch (_messageCtr) {
- case 1:
- colIndex = 252;
- break;
- case 2:
- colIndex = 16;
- break;
- default:
- colIndex = 250;
- break;
- }
-
- _vm->_palette->setEntry(colIndex, me.rgb1.r, me.rgb1.g, me.rgb1.b);
- _vm->_palette->setEntry(colIndex + 1, me.rgb2.r, me.rgb2.g, me.rgb2.b);
-
- // Add a kernel message to display the given text
- me.kernelMsgIndex = _view->_kernelMessages.add(me.pos, colIndex * 0x101 + 0x100, 0, 0, INDEFINITE_TIMEOUT, me.msg);
- assert(me.kernelMsgIndex >= 0);
-
- // Play the associated sound, if it exists
- if (me.soundId > 0)
- _vm->_sound->playDSRSound(me.soundId - 1, 255, false);
- ++_messageCtr;
- }
- }
-
- // Move to the next frame
- _currentFrame++;
- if (_currentFrame >= (int)_miscEntries.size()) {
- // Animation is complete
- if (_abortTimers != 0) {
- _view->_abortTimers = _abortTimers;
- _view->_abortTimersMode = _abortMode;
-
- if (_abortMode != ABORTMODE_1) {
- // Copy the noun list
- if (_madsVm->_scene)
- _madsVm->scene()->_action._action = _actionNouns;
- }
- }
- }
-
- int frameNum = MIN(_currentFrame, (int)_miscEntries.size() - 1);
- _nextFrameTimer = _madsVm->_currentTimer + _miscEntries[frameNum].numTicks;
-}
-
-void MadsAnimation::setCurrentFrame(int frameNumber) {
- _currentFrame = frameNumber;
- _oldFrameEntry = 0;
- _freeFlag = false;
-
- _nextScrollTimer = _nextFrameTimer = _madsVm->_currentTimer;
-}
-
-int MadsAnimation::getCurrentFrame() {
- return _currentFrame;
-}
-
-void MadsAnimation::load1(int frameNumber) {
- if (_skipLoad)
- return;
-
- Common::Point pt;
- int listIndex = _spriteListIndexes[_spriteListIndex];
- SpriteAsset &spriteSet = _view->_spriteSlots.getSprite(listIndex);
-
- if (_unkIndex < 0) {
- M4Surface *frame = spriteSet.getFrame(0);
- pt.x = frame->bounds().left;
- pt.y = frame->bounds().top;
- } else {
- pt.x = _unkList[_unkIndex].x;
- pt.y = _unkList[_unkIndex].y;
- _unkIndex = 1 - _unkIndex;
- }
-
- if (proc1(spriteSet, pt, frameNumber))
- error("proc1 failure");
-}
-
-bool MadsAnimation::proc1(SpriteAsset &spriteSet, const Common::Point &pt, int frameNumber) {
- return 0;
-}
-
-void MadsAnimation::loadInterface(M4Surface *&interfaceSurface, M4Surface *&depthSurface) {
- if (_animMode <= 2) {
- MadsSceneResources sceneResources;
- sceneResources.load(_roomNumber, _interfaceFile.c_str(), 0, depthSurface, interfaceSurface);
-
- } else if (_animMode == 4) {
- // Load a scene interface
- interfaceSurface->madsLoadInterface(_interfaceFile);
- } else {
- // This mode allocates two large surfaces for the animation
- // TODO: Are these ever properly freed?
-error("Anim mode %d - need to check free logic", _animMode);
- assert(!interfaceSurface);
- assert(!depthSurface);
- depthSurface = new M4Surface(MADS_SURFACE_WIDTH, MADS_SCREEN_HEIGHT);
- interfaceSurface = new M4Surface(MADS_SURFACE_WIDTH, MADS_SCREEN_HEIGHT);
- depthSurface->clear();
- interfaceSurface->clear();
- }
-}
-
-} // End of namespace M4
diff --git a/engines/m4/animation.h b/engines/m4/animation.h
deleted file mode 100644
index 68a2883241..0000000000
--- a/engines/m4/animation.h
+++ /dev/null
@@ -1,127 +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 M4_ANIMATION_H
-#define M4_ANIMATION_H
-
-#include "m4/m4.h"
-#include "m4/graphics.h"
-#include "m4/assets.h"
-#include "m4/mads_views.h"
-#include "common/array.h"
-
-namespace M4 {
-
-class MadsView;
-class SpriteSlotSubset;
-
-class AnimMessage {
-public:
- int16 soundId;
- char msg[64];
- Common::Point pos;
- RGB8 rgb1, rgb2;
- uint16 flags;
- int startFrame, endFrame;
- int kernelMsgIndex;
-};
-
-class AnimFrameEntry {
-public:
- int frameNumber;
- int seqIndex;
- SpriteSlotSubset spriteSlot;
-};
-
-class AnimMiscEntry {
-public:
- int soundNum;
- int msgIndex;
- int numTicks;
- Common::Point posAdjust;
-};
-
-#define ANIM_SPRITE_SET_SIZE 50
-
-enum MadsAnimationFlags {ANIM_CUSTOM_FONT = 0x20, ANIM_HAS_SOUND = 0x8000};
-
-class MadsAnimation: public Animation {
-private:
- MadsView *_view;
-
- int _spriteListCount;
- Common::Array<AnimMessage> _messages;
- Common::Array<AnimFrameEntry> _frameEntries;
- Common::Array<AnimMiscEntry> _miscEntries;
- Font *_font;
-
- uint8 _flags;
- int _animMode;
- int _roomNumber;
- bool _field12;
- int _spriteListIndex;
- int _scrollX;
- int _scrollY;
- int _scrollTicks;
- Common::String _interfaceFile;
- Common::String _spriteSetNames[10];
- Common::String _lbmFilename;
- Common::String _spritesFilename;
- Common::String _soundName;
- Common::String _dsrName;
- Common::Array<int> _spriteListIndexes;
-
- int _currentFrame, _oldFrameEntry;
- bool _resetFlag;
- bool _freeFlag;
- bool _skipLoad;
- int _unkIndex;
- Common::Point _unkList[2];
- uint32 _nextFrameTimer;
- uint32 _nextScrollTimer;
- int _messageCtr;
- int _abortTimers;
- AbortTimerMode _abortMode;
- ActionDetails _actionNouns;
-
- void load1(int frameNumber);
- bool proc1(SpriteAsset &spriteSet, const Common::Point &pt, int frameNumber);
- void loadInterface(M4Surface *&interfaceSurface, M4Surface *&depthSurface);
- bool hasScroll() const { return (_scrollX != 0) || (_scrollY != 0); }
-public:
- MadsAnimation(MadsM4Engine *vm, MadsView *view);
- virtual ~MadsAnimation();
-
- virtual void initialize(const Common::String &filename, uint16 flags, M4Surface *surface, M4Surface *depthSurface);
- virtual void load(const Common::String &filename, int abortTimers);
- virtual void update();
- virtual void setCurrentFrame(int frameNumber);
- virtual int getCurrentFrame();
-
- bool freeFlag() const { return _freeFlag; }
- bool getAnimMode() const { return _animMode; }
- int roomNumber() const { return _roomNumber; }
-};
-
-} // End of namespace M4
-
-#endif
diff --git a/engines/m4/assets.cpp b/engines/m4/assets.cpp
deleted file mode 100644
index d6cc71e133..0000000000
--- a/engines/m4/assets.cpp
+++ /dev/null
@@ -1,650 +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 "m4/assets.h"
-#include "m4/globals.h"
-#include "m4/compression.h"
-#include "m4/graphics.h"
-
-#include "common/memstream.h"
-
-namespace M4 {
-
-BaseAsset::BaseAsset(MadsM4Engine *vm) : _vm(vm) {
-}
-
-BaseAsset::~BaseAsset() {
-}
-
-MachineAsset::MachineAsset(MadsM4Engine *vm, Common::SeekableReadStream* stream, int size, const char *name) : BaseAsset(vm) {
- uint32 stateCount = stream->readUint32LE();
- for (uint32 curState = 0; curState < stateCount; curState++) {
- uint32 stateOffset = stream->readUint32LE();
- _stateTable.push_back(stateOffset);
- }
- _codeSize = size - 4 - 4 * stateCount;
- _code = new byte[_codeSize];
- stream->read(_code, _codeSize);
-}
-
-MachineAsset::~MachineAsset() {
- delete[] _code;
-}
-
-void MachineAsset::getCode(byte *&code, uint32 &codeSize) {
- code = _code;
- codeSize = _codeSize;
-}
-
-uint32 MachineAsset::getStateOffset(uint32 state) {
- assert(state < _stateTable.size());
- return _stateTable[state];
-}
-
-SequenceAsset::SequenceAsset(MadsM4Engine *vm, Common::SeekableReadStream* stream, int size, const char *name) : BaseAsset(vm) {
- _localVarCount = stream->readUint32LE();
- _codeSize = size - 4;
- _code = new byte[_codeSize];
- stream->read(_code, _codeSize);
-}
-
-SequenceAsset::~SequenceAsset() {
- delete[] _code;
-}
-
-void SequenceAsset::getCode(byte *&code, uint32 &codeSize) {
- code = _code;
- codeSize = _codeSize;
-}
-
-
-DataAsset::DataAsset(MadsM4Engine *vm, Common::SeekableReadStream* stream, int size, const char *name) : BaseAsset(vm) {
-
- _recCount = stream->readUint32LE();
- _recSize = stream->readUint32LE();
- _dataSize = _recCount * _recSize;
- _data = new long[_dataSize];
- for (uint32 i = 0; i < _dataSize; i++)
- _data[i] = (long)stream->readUint32LE();
-
-}
-
-DataAsset::~DataAsset() {
- delete _data;
-}
-
-long *DataAsset::getRow(int index) {
- assert(index < _recCount);
- return &_data[_recSize * index];
-}
-
-SpriteAsset::SpriteAsset(MadsM4Engine *vm, Common::SeekableReadStream* stream, int size, const char *name,
- bool asStream, int flags) :
- BaseAsset(vm) {
- _stream = stream;
- _palInterface = NULL;
- _paletteData = NULL;
-
- if (_vm->isM4()) {
- loadM4SpriteAsset(vm, stream, asStream);
- } else {
- loadMadsSpriteAsset(vm, stream, flags);
- }
-}
-
-SpriteAsset::SpriteAsset(MadsM4Engine *vm, const char *name): BaseAsset(vm) {
- _stream = vm->res()->get(name);
- _palInterface = NULL;
- _paletteData = NULL;
-
- if (_vm->isM4()) {
- loadM4SpriteAsset(vm, _stream, true);
- } else {
- loadMadsSpriteAsset(vm, _stream, 0);
- }
-
- vm->res()->toss(name);
-}
-
-SpriteAsset::~SpriteAsset() {
- if (_palInterface) {
- // Internally stored palette translation data, so release it
- _palInterface->deleteRange(_paletteData);
- delete _paletteData;
- }
-
- // Delete the individual frames
- for (Common::Array<SpriteAssetFrame>::iterator it = _frames.begin(); it != _frames.end(); ++it) {
- delete (*it).frame;
- }
-
- delete _charInfo;
-}
-
-void SpriteAsset::loadM4SpriteAsset(MadsM4Engine *vm, Common::SeekableReadStream* stream, bool asStream) {
- bool isBigEndian = false;
- uint32 frameOffset;
-
- uint32 header = _stream->readUint32LE();
- if (header == HEAD_M4SS) {
- debugC(kDebugGraphics, "LE-encoded sprite\n");
- } else {
- debugC(kDebugGraphics, "BE-encoded sprite\n");
- isBigEndian = true;
- }
-
- _srcSize = parseSprite(isBigEndian);
-
- _stream->readUint32LE();
- _frameRate = (!isBigEndian) ? _stream->readUint32LE() : _stream->readUint32BE();
- _pixelSpeed = (!isBigEndian) ? _stream->readUint32LE() : _stream->readUint32BE();
- _maxWidth = (!isBigEndian) ? _stream->readUint32LE() : _stream->readUint32BE();
- _maxHeight = (!isBigEndian) ? _stream->readUint32LE() : _stream->readUint32BE();
- _stream->skip(6 * 4);
- _frameCount = (!isBigEndian) ? _stream->readUint32LE() : _stream->readUint32BE();
-
- debugC(kDebugGraphics, "SpriteAsset::SpriteAsset() srcSize = %d; frameRate = %04X; pixelSpeed = %04X; maxWidth = %d; maxHeight = %d; frameCount = %d\n", _srcSize, _frameRate, _pixelSpeed, _maxWidth, _maxHeight, _frameCount);
-
- for (int curFrame = 0; curFrame < _frameCount; curFrame++) {
- frameOffset = (!isBigEndian) ? _stream->readUint32LE() : _stream->readUint32BE();
- _frameOffsets.push_back(frameOffset);
- }
- _frameOffsets.push_back(_srcSize - 48 - _frameCount * 4);
-
- _frameStartOffset = _stream->pos();
-
- // We don't need to load frames when streaming
- if (asStream)
- return;
-
- for (int curFrame = 0; curFrame < _frameCount; curFrame++) {
- frameOffset = _frameStartOffset + _frameOffsets[curFrame];
- _stream->seek(frameOffset);
-
- SpriteAssetFrame frame;
- loadFrameHeader(frame, isBigEndian);
-
- // Load & unpack RLE data if it's not a streaming animation
- if (frame.stream != 1) {
-
- frame.frame = new M4Sprite(stream, frame.x, frame.y, frame.w, frame.h, true, frame.comp);
-#if 0
- char fn[512];
- sprintf(fn, "%04d.raw", curFrame);
- FILE *h = fopen(fn, "wb");
- fwrite((byte*)frame.frame->getBasePtr(), frame.w * frame.h, 1, h);
- fclose(h);
-#endif
- }
-
- _frames.push_back(frame);
-
- }
-
-}
-
-void SpriteAsset::loadMadsSpriteAsset(MadsM4Engine *vm, Common::SeekableReadStream* stream, int flags) {
- int curFrame = 0;
- uint32 frameOffset = 0;
- MadsPack sprite(stream);
- _frameRate = 0;
- _pixelSpeed = 0;
- _maxWidth = 0;
- _maxHeight = 0;
-
- Common::SeekableReadStream *spriteStream = sprite.getItemStream(0);
- _mode = spriteStream->readByte();
- spriteStream->skip(1);
- int type1 = spriteStream->readUint16LE();
- int type2 = spriteStream->readUint16LE();
- _isBackground = (type1 != 0) && (type2 < 4);
- spriteStream->skip(32);
- _frameCount = spriteStream->readUint16LE();
-
- if (_vm->isM4() || ((flags & SPRITE_SET_CHAR_INFO) == 0))
- _charInfo = NULL;
- else
- _charInfo = new MadsSpriteSetCharInfo(spriteStream);
-
- delete spriteStream;
-
- // Get the palette data
- spriteStream = sprite.getItemStream(2);
- int numColors = 0;
- RGB8 *palData = Palette::decodeMadsPalette(spriteStream, &numColors);
- Common::copy(palData, &palData[numColors], &_palette[0]);
- if (numColors < 256)
- Common::set_to((byte *)&_palette[numColors], (byte *)&_palette[256], 0);
- _colorCount = numColors;
- delete[] palData;
- delete spriteStream;
-
- spriteStream = sprite.getItemStream(1);
- Common::SeekableReadStream *spriteDataStream = sprite.getItemStream(3);
- SpriteAssetFrame frame;
- Common::Array<int> frameSizes;
- for (curFrame = 0; curFrame < _frameCount; curFrame++) {
- frame.stream = 0;
- frame.comp = 0;
- frameOffset = spriteStream->readUint32LE();
- _frameOffsets.push_back(frameOffset);
- uint32 frameSize = spriteStream->readUint32LE();
- frameSizes.push_back(frameSize);
-
- frame.x = spriteStream->readUint16LE();
- frame.y = spriteStream->readUint16LE();
- frame.w = spriteStream->readUint16LE();
- frame.h = spriteStream->readUint16LE();
- if (curFrame == 0)
- debugC(1, kDebugGraphics, "%i frames, x = %i, y = %i, w = %i, h = %i\n", _frameCount, frame.x, frame.y, frame.w, frame.h);
-
- if (_mode == 0) {
- // Create a frame and decompress the raw pixel data
- uint32 currPos = (uint32)spriteDataStream->pos();
- frame.frame = new M4Sprite(spriteDataStream, frame.x, frame.y, frame.w, frame.h, false);
- assert((uint32)spriteDataStream->pos() == (currPos + frameSize));
- }
-
- _frames.push_back(frame);
- }
-
- if (_mode != 0) {
- // Handle decompressing Fab encoded data
- for (curFrame = 0; curFrame < _frameCount; curFrame++) {
- FabDecompressor fab;
-
- int srcSize = (curFrame == (_frameCount - 1)) ? spriteDataStream->size() - _frameOffsets[curFrame] :
- _frameOffsets[curFrame + 1] - _frameOffsets[curFrame];
- byte *srcData = (byte *)malloc(srcSize);
- assert(srcData);
- spriteDataStream->read(srcData, srcSize);
-
- byte *destData = (byte *)malloc(frameSizes[curFrame]);
- assert(destData);
-
- fab.decompress(srcData, srcSize, destData, frameSizes[curFrame]);
-
- // 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].w, _frames[curFrame].h, false);
- delete rs;
-
- free(srcData);
- free(destData);
- }
- }
-
-
- delete spriteStream;
- delete spriteDataStream;
-}
-
-int32 SpriteAsset::parseSprite(bool isBigEndian) {
-
- uint32 format, chunkType, chunkSize = 0;
-
- _colorCount = 0;
-
- format = (!isBigEndian) ? _stream->readUint32LE() : _stream->readUint32BE();
-
- chunkType = (!isBigEndian) ? _stream->readUint32LE() : _stream->readUint32BE();
-
- if (chunkType == CELS__PAL) {
- chunkSize = (!isBigEndian) ? _stream->readUint32LE() : _stream->readUint32BE();
- uint32 numColors = (!isBigEndian) ? _stream->readUint32LE() : _stream->readUint32BE();
- // TODO
- //if (palette) {
- // TODO: A sprite set palette specifies the indexes, which need not start at
- // index 0. For now, I'm simply preloading the currently active palette
- // before starting to replace existing entries
-
- _vm->_palette->grabPalette((byte *) _palette, 0, 256);
- _colorCount = 0;
-
- for (uint32 i = 0; i < numColors; i++) {
- uint32 paletteEntry = (!isBigEndian) ? _stream->readUint32LE() : _stream->readUint32BE();
- uint index = (paletteEntry >> 24) & 0xFF;
-
- _palette[index].r = ((paletteEntry >> 16) & 0xFF) << 2;
- _palette[index].g = ((paletteEntry >> 8) & 0xFF) << 2;
- _palette[index].b = (paletteEntry & 0xFF) << 2;
-
- _colorCount = MAX<int>(_colorCount, index);
- }
-
- /*
- } else {
- stream.seek(colorCount, )
- data += colorCount * 4;
- }
- */
- chunkType = (!isBigEndian) ? _stream->readUint32LE() : _stream->readUint32BE();
- }
-
- if (chunkType == CELS___SS) {
- chunkSize = (!isBigEndian) ? _stream->readUint32LE() : _stream->readUint32BE();
- } else {
- debugC(kDebugGraphics, "SpriteAsset::parseSprite() Expected chunk type %08X, got %08X", CELS___SS, chunkType);
- }
-
- return chunkSize;
-
-}
-
-void SpriteAsset::loadFrameHeader(SpriteAssetFrame &frameHeader, bool isBigEndian) {
- _stream->readUint32LE();
- frameHeader.stream = (!isBigEndian) ? _stream->readUint32LE() : _stream->readUint32BE();
- frameHeader.x = (!isBigEndian) ? _stream->readUint32LE() : _stream->readUint32BE();
- frameHeader.y = (!isBigEndian) ? _stream->readUint32LE() : _stream->readUint32BE();
- frameHeader.w = (!isBigEndian) ? _stream->readUint32LE() : _stream->readUint32BE();
- frameHeader.h = (!isBigEndian) ? _stream->readUint32LE() : _stream->readUint32BE();
- frameHeader.comp = (!isBigEndian) ? _stream->readUint32LE() : _stream->readUint32BE();
- frameHeader.frame = NULL;
- _stream->seek(8 * 4, SEEK_CUR);
- //debugC(kDebugGraphics, "SpriteAsset::loadFrameHeader() stream = %d; x = %d; y = %d; w = %d; h = %d; comp = %d\n", frameHeader.stream, frameHeader.x, frameHeader.y, frameHeader.w, frameHeader.h, frameHeader.comp);
-}
-
-M4Sprite *SpriteAsset::getFrame(int frameIndex) {
- if ((uint)frameIndex < _frames.size()) {
- return _frames[frameIndex].frame;
- } else {
- debugC(kDebugGraphics, "SpriteAsset::getFrame: Invalid frame %d, out of %d", frameIndex, _frames.size());
- return _frames[_frames.size() - 1].frame;
- }
-}
-
-void SpriteAsset::loadStreamingFrame(M4Sprite *frame, int frameIndex, int destX, int destY) {
- uint32 frameOffset = _frameStartOffset + _frameOffsets[frameIndex];
- _stream->seek(frameOffset);
-
- SpriteAssetFrame frameHeader;
- loadFrameHeader(frameHeader);
-
- if (frameHeader.w > 0 && frameHeader.h > 0) {
- Common::SeekableReadStream *frameData = _stream->readStream(getFrameSize(frameIndex));
- if (frameHeader.stream) {
- frame->loadDeltaRle(frameData, destX - frameHeader.x, destY - frameHeader.y);
- } else {
- frame->loadRle(frameData);
- }
- delete frameData;
- }
-
-}
-
-RGBList *SpriteAsset::getRgbList() {
- RGBList *result = new RGBList(_colorCount);
- Common::copy((byte *)&_palette[0], (byte *)&_palette[_colorCount], (byte *)result->data());
- return result;
-}
-
-void SpriteAsset::translate(RGBList *list, bool isTransparent) {
- for (int frameIndex = 0; frameIndex < _frameCount; ++frameIndex)
- _frames[frameIndex].frame->translate(list, isTransparent);
-}
-
-void SpriteAsset::translate(Palette *palette) {
- _palInterface = palette;
- _paletteData = this->getRgbList();
- palette->addRange(_paletteData);
- this->translate(_paletteData, true);
-}
-
-
-int32 SpriteAsset::getFrameSize(int index) {
- /*
- if (index + 1 == _frameCount) {
- } else {
-
- }
- */
- return _frameOffsets[index + 1] - _frameOffsets[index];
-}
-
-AssetManager::AssetManager(MadsM4Engine *vm) {
-
- _vm = vm;
-
- /* Initialize asset arrays */
- for (int i = 0; i < 256; i++) {
- _MACH[i] = NULL;
- _SEQU[i] = NULL;
- _DATA[i] = NULL;
- _CELS[i] = NULL;
- }
-
-}
-
-AssetManager::~AssetManager() {
- // unload all remaining assets
- clearAssets(kAssetTypeMACH, 0, 255);
- clearAssets(kAssetTypeSEQU, 0, 255);
- clearAssets(kAssetTypeCELS, 0, 255);
- clearAssets(kAssetTypeDATA, 0, 255);
-}
-
-bool AssetManager::clearAssets(AssetType assetType, int32 minHash, int32 maxHash) {
-
- minHash = MAX<int>(0, minHash);
- maxHash = MIN<int>(maxHash, 255);
-
- switch (assetType) {
- case kAssetTypeMACH:
- for (int i = minHash; i <= maxHash; i++)
- if (_MACH[i]) {
- delete _MACH[i];
- _MACH[i] = NULL;
- }
- break;
- case kAssetTypeSEQU:
- for (int i = minHash; i <= maxHash; i++)
- if (_SEQU[i]) {
- delete _SEQU[i];
- _SEQU[i] = NULL;
- }
- break;
- case kAssetTypeDATA:
- for (int i = minHash; i <= maxHash; i++)
- if (_DATA[i]) {
- delete _DATA[i];
- _DATA[i] = NULL;
- }
- break;
- case kAssetTypeCELS:
- for (int i = minHash; i <= maxHash; i++)
- if (_CELS[i]) {
- delete _CELS[i];
- _CELS[i] = NULL;
- }
- break;
- }
-
- // FIXME: no value is returned, returning true for now
- return true;
-}
-
-bool AssetManager::loadAsset(const char *assetName, RGB8 *palette) {
-
- debugC(kDebugGraphics, "AssetManager::loadAsset() %s\n", assetName);
-
- // TODO, better use MemoryReadStreamEndian?
- //convertAssetToLE(assetData, assetSize);
-
- Common::SeekableReadStream *assetS = _vm->res()->get(assetName);
-
- while (assetS->pos() + 12 < assetS->size()) {
- uint32 chunkType, chunkSize, chunkHash;
-
- chunkType = assetS->readUint32LE();
- chunkSize = assetS->readUint32LE() - 12; // sub 12 for the chunk header
- chunkHash = assetS->readUint32LE();
-
- debugC(kDebugGraphics, "hash = %d\n", chunkHash);
-
- // Until loading code is complete, so that chunks not fully read are skipped correctly
- uint32 nextOfs = assetS->pos() + chunkSize;
-
- switch (chunkType) {
- case CHUNK_MACH:
- debugC(kDebugGraphics, "MACH\n");
- clearAssets(kAssetTypeMACH, chunkHash, chunkHash);
- _MACH[chunkHash] = new MachineAsset(_vm, assetS, chunkSize, assetName);
- break;
- case CHUNK_SEQU:
- debugC(kDebugGraphics, "SEQU\n");
- clearAssets(kAssetTypeSEQU, chunkHash, chunkHash);
- _SEQU[chunkHash] = new SequenceAsset(_vm, assetS, chunkSize, assetName);
- break;
- case CHUNK_DATA:
- debugC(kDebugGraphics, "DATA\n");
- clearAssets(kAssetTypeDATA, chunkHash, chunkHash);
- _DATA[chunkHash] = new DataAsset(_vm, assetS, chunkSize, assetName);
- break;
- case CHUNK_CELS:
- debugC(kDebugGraphics, "CELS\n");
- clearAssets(kAssetTypeCELS, chunkHash, chunkHash);
- _CELS[chunkHash] = new SpriteAsset(_vm, assetS, chunkSize, assetName);
- break;
- default:
- debugC(kDebugGraphics, "AssetManager::loadAsset() Unknown chunk type %08X\n", chunkType);
- }
-
- // Until loading code is complete (see above)
- assetS->seek(nextOfs);
-
- }
-
- _vm->res()->toss(assetName);
-
- // FIXME: no value is returned, returning true for now
- return true;
-}
-
-int32 AssetManager::addSpriteAsset(const char *assetName, int32 hash, RGB8 *palette) {
-
- bool alreadyLoaded = false;
-
- if (hash < 0) {
- for (int i = 0; i <= 255; i++) {
- if (_CELS[i] != NULL) {
- if (_CELS[i]->getName() == assetName) {
- alreadyLoaded = true;
- hash = i;
- break;
- }
- } else {
- hash = i;
- break;
- }
- }
- } else {
- alreadyLoaded = _CELS[hash] != NULL && _CELS[hash]->getName() == assetName;
- }
-
- /* Not loaded and no empty slots */
- if (hash < 0)
- return -1;
-
- if (!alreadyLoaded) {
-
- debugC(kDebugGraphics, "AssetManager::addSpriteAsset() asset %s not loaded, loading into %d\n", assetName, hash);
-
- clearAssets(kAssetTypeCELS, hash, hash);
-
- Common::SeekableReadStream *assetS = _vm->res()->get(assetName);
- _CELS[hash] = new SpriteAsset(_vm, assetS, assetS->size(), assetName);
- _vm->res()->toss(assetName);
-
- } else {
-
- debugC(kDebugGraphics, "AssetManager::addSpriteAsset() asset %s already loaded in %d\n", assetName, hash);
-
- /* TODO/FIXME
- if (_CELS[hash].palOffset >= 0 && palette)
- restorePalette(palette, _CELS[hash].data + _CELS[hash].palOffset);
- */
-
- }
-
- return hash;
-
-}
-
-void AssetManager::restorePalette(RGB8 *palette, byte *data) {
- // TODO
-}
-
-void AssetManager::convertAssetToLE(byte *assetData, uint32 assetSize) {
-
-}
-
-MachineAsset *AssetManager::getMachine(int32 hash) {
- assert(_MACH[hash] != NULL);
- return _MACH[hash];
-}
-
-SequenceAsset *AssetManager::getSequence(int32 hash) {
- assert(_SEQU[hash] != NULL);
- return _SEQU[hash];
-}
-
-DataAsset *AssetManager::getData(int32 hash) {
- assert(_DATA[hash] != NULL);
- return _DATA[hash];
-}
-
-SpriteAsset *AssetManager::getSprite(int32 hash) {
- assert(_CELS[hash] != NULL);
- return _CELS[hash];
-}
-
-M4Sprite *AssetManager::getSpriteFrame(int32 hash, int frameIndex) {
- assert(_CELS[hash] != NULL);
- return _CELS[hash]->getFrame(frameIndex);
-}
-
-int32 AssetManager::getSpriteFrameCount(int32 hash) {
- assert(_CELS[hash] != NULL);
- return _CELS[hash]->getCount();
-}
-
-//--------------------------------------------------------------------------
-
-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)
- _frameList2[i] = s->readUint16LE();
- for (int i = 0; i < 16; ++i)
- _ticksList[i] = s->readUint16LE();
-
- _unk1 = s->readUint16LE();
- _ticksAmount = s->readByte();
- _yScale = s->readByte();
-}
-
-} // End of namespace M4
diff --git a/engines/m4/assets.h b/engines/m4/assets.h
deleted file mode 100644
index 25996a421e..0000000000
--- a/engines/m4/assets.h
+++ /dev/null
@@ -1,212 +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 M4_ASSETS_H
-#define M4_ASSETS_H
-
-#include "common/scummsys.h"
-#include "common/stream.h"
-
-#include "m4/sprite.h"
-
-namespace M4 {
-
-// Sequence chunks
-#define CHUNK_SCEN MKTAG('S','C','E','N')
-#define CHUNK_MACH MKTAG('M','A','C','H')
-#define CHUNK_SEQU MKTAG('S','E','Q','U')
-#define CHUNK_DATA MKTAG('D','A','T','A')
-#define CHUNK_CELS MKTAG('C','E','L','S')
-
-// Sprite chunks
-#define HEAD_M4SS MKTAG('M','4','S','S') //'M4SS'
-#define CELS__PAL MKTAG(' ','P','A','L') //' PAL'
-#define CELS___SS MKTAG(' ',' ','S','S') //' SS'
-
-#define SPRITE_SET_CHAR_INFO 4
-
-class MadsM4Engine;
-class Palette;
-
-class BaseAsset {
-public:
- BaseAsset(MadsM4Engine *vm);
- ~BaseAsset();
- const Common::String getName() const { return _name; }
-protected:
- MadsM4Engine *_vm;
- Common::String _name;
-};
-
-class MachineAsset : public BaseAsset {
-public:
- MachineAsset(MadsM4Engine *vm, Common::SeekableReadStream* stream, int size, const char *name);
- ~MachineAsset();
- void getCode(byte *&code, uint32 &codeSize);
- uint32 getStateOffset(uint32 state);
-protected:
- Common::Array<uint32> _stateTable;
- byte *_code;
- uint32 _codeSize;
-};
-
-class SequenceAsset : public BaseAsset {
-public:
- SequenceAsset(MadsM4Engine *vm, Common::SeekableReadStream* stream, int size, const char *name);
- ~SequenceAsset();
- void getCode(byte *&code, uint32 &codeSize);
- int localVarCount() const { return _localVarCount; }
-protected:
- int _localVarCount;
- byte *_code;
- uint32 _codeSize;
-};
-
-class DataAsset : public BaseAsset {
-public:
- DataAsset(MadsM4Engine *vm, Common::SeekableReadStream* stream, int size, const char *name);
- ~DataAsset();
- int getCount() const { return _recCount; }
- long *getRow(int index);
-protected:
- long *_data;
- uint32 _recSize, _dataSize;
- int _recCount;
-};
-
-struct SpriteAssetFrame {
- uint32 stream;
- int x, y, w, h;
- uint32 comp;
- M4Sprite *frame;
-};
-
-class MadsSpriteSetCharInfo {
-public:
- MadsSpriteSetCharInfo(Common::SeekableReadStream *s);
-
- int _totalFrames;
- int _numEntries;
- int _frameList2[16];
- int _frameList[16];
- int _ticksList[16];
- int _unk1;
- int _ticksAmount;
- int _yScale;
-};
-
-class SpriteAsset : public BaseAsset {
-public:
- SpriteAsset(MadsM4Engine *vm, Common::SeekableReadStream* stream, int size, const char *name,
- bool asStream = false, int flags = 0);
- SpriteAsset(MadsM4Engine *vm, const char *name);
- ~SpriteAsset();
- void loadM4SpriteAsset(MadsM4Engine *vm, Common::SeekableReadStream* stream, bool asStream);
- void loadMadsSpriteAsset(MadsM4Engine *vm, Common::SeekableReadStream* stream, int flags);
- int32 getCount() { return _frameCount; }
- int32 getFrameRate() const { return _frameRate; }
- int32 getPixelSpeed() const { return _pixelSpeed; }
- int32 getFrameWidth(int index);
- int32 getFrameHeight(int index);
- int32 getMaxFrameWidth() const { return _maxWidth; }
- int32 getMaxFrameHeight() const { return _maxHeight; }
- bool isBackground() const { return _isBackground; }
- M4Sprite *getFrame(int frameIndex);
- void loadStreamingFrame(M4Sprite *frame, int frameIndex, int destX, int destY);
- RGB8* getPalette() { return _palette; }
- int getColorCount() { return _colorCount; }
- RGBList *getRgbList();
- void translate(RGBList *list, bool isTransparent = false);
- void translate(Palette *palette);
- int32 getFrameSize(int index);
- M4Sprite *operator[](int index) { return getFrame(index); }
-public:
- MadsSpriteSetCharInfo *_charInfo;
-protected:
- Common::SeekableReadStream *_stream;
- RGB8 _palette[256];
- uint32 _colorCount;
- uint32 _srcSize;
- int32 _frameRate, _pixelSpeed;
- int _maxWidth, _maxHeight;
- int _frameCount;
- Common::Array<uint32> _frameOffsets;
- Common::Array<SpriteAssetFrame> _frames;
- uint32 _frameStartOffset;
-
- // MADS sprite set fields
- uint8 _mode;
- bool _isBackground;
-
- int32 parseSprite(bool isBigEndian = false);
- void loadFrameHeader(SpriteAssetFrame &frameHeader, bool isBigEndian = false);
-private:
- RGBList *_paletteData;
- Palette *_palInterface;
-};
-
-enum AssetType {
- kAssetTypeMACH,
- kAssetTypeSEQU,
- kAssetTypeDATA,
- kAssetTypeCELS
-};
-
-enum CallbackHandlers {
- kCallbackTriggerDispatch
-};
-
-class AssetManager {
-public:
-
- AssetManager(MadsM4Engine *vm);
- ~AssetManager();
-
- bool clearAssets(AssetType assetType, int32 minHash, int32 maxHash);
- bool loadAsset(const char *assetName, RGB8 *palette);
- int32 addSpriteAsset(const char *assetName, int32 hash, RGB8 *palette);
-
- // TODO: Move to Palette class
- void restorePalette(RGB8 *palette, byte *data);
-
- MachineAsset *getMachine(int32 hash);
- SequenceAsset *getSequence(int32 hash);
- DataAsset *getData(int32 hash);
- SpriteAsset *getSprite(int32 hash);
- M4Sprite *getSpriteFrame(int32 hash, int frameIndex);
- int32 getSpriteFrameCount(int32 hash);
-
-protected:
- // TODO: Check if we need _vm
- MadsM4Engine *_vm;
-
- MachineAsset *_MACH[256];
- SequenceAsset *_SEQU[256];
- DataAsset *_DATA[256];
- SpriteAsset *_CELS[256];
-
- void convertAssetToLE(byte *assetData, uint32 assetSize);
-
-};
-
-} // End of namespace M4
-
-#endif
diff --git a/engines/m4/burger_data.h b/engines/m4/burger_data.h
deleted file mode 100644
index d30e546023..0000000000
--- a/engines/m4/burger_data.h
+++ /dev/null
@@ -1,82 +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 M4_BURGER_DATA_H
-#define M4_BURGER_DATA_H
-
-#include "m4/graphics.h"
-#include "m4/actor.h"
-
-namespace M4 {
-
-InventoryObject burger_inventory [] = {
- // name scene icon
- //-------------------- ----- -----
- { "empty jug", 303, 14 },
- { "distilled juice", 999, 15 },
- { "broken puz dispenser", 999, 16 },
- { "puz dispenser", 999, 17 },
- { "broken mouse trap", 999, 18 },
- { "mouse trap", 999, 19 },
- { "kindling", 999, 20 },
- { "burning kindling", 999, 21 },
- { "lights", 508, 22 },
- { "lights on", 508, 23 },
- { "bottle", 999, 24 },
- { "carrot juice", 999, 25 },
- { "soapy water", 999, 26 },
- { "iron filings", 999, 27 },
- { "waxed hair", 999, 28 },
- { "fish", 999, 29 },
- { "hook", 999, 30 },
- { "keys", 999, 31 },
- { "records", 999, 32 },
- { "collar", 999, 33 },
- { "amp", 999, 34 },
- { "rubber gloves", 999, 35 },
- { "sock", 504, 36 },
- { "jaws of life", 999, 37 },
- { "deed", 999, 38 },
- { "burger morsel", 999, 39 },
- { "whistle", 999, 40 },
- { "coin", 999, 41 },
- { "matches", 999, 42 },
- { "phone cord", 999, 43 },
- { "kibble", 602, 44 }, // picked up from tray
- { "pantyhose", 999, 45 },
- { "fan belt", 999, 46 },
- { "spring", 999, 47 },
- { "mirror", 999, 48 },
- { "grate", 999, 49 },
- { "ray gun", 604, 50 }, // given to Wilbur when he enters 604
- { "grasshoppers", 999, 51 },
- { "rolling pin", 999, 52 },
- { "rubber duck", 999, 53 },
- { "ladder", 999, 54 },
- { "money", 999, 55 },
- { "crow bar", 999, 56 },
- { "Wilbur", 999, 57 }
-};
-
-} // End of namespace M4
-
-#endif
diff --git a/engines/m4/compression.cpp b/engines/m4/compression.cpp
deleted file mode 100644
index 65a25c14e3..0000000000
--- a/engines/m4/compression.cpp
+++ /dev/null
@@ -1,190 +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 "m4/compression.h"
-#include "m4/m4.h"
-
-#include "common/memstream.h"
-#include "common/textconsole.h"
-
-namespace M4 {
-
-const char *madsPackString = "MADSPACK";
-
-bool MadsPack::isCompressed(Common::SeekableReadStream *stream) {
- // Check whether the passed stream is packed
-
- char tempBuffer[8];
- stream->seek(0);
- if (stream->read(tempBuffer, 8) == 8) {
- if (!strncmp(tempBuffer, madsPackString, 8))
- return true;
- }
-
- return false;
-}
-
-MadsPack::MadsPack(Common::SeekableReadStream *stream) {
- initialize(stream);
-}
-
-MadsPack::MadsPack(const char *resourceName, MadsM4Engine* vm) {
- Common::SeekableReadStream *stream = vm->_resourceManager->get(resourceName);
- initialize(stream);
- vm->_resourceManager->toss(resourceName);
-}
-
-void MadsPack::initialize(Common::SeekableReadStream *stream) {
- if (!MadsPack::isCompressed(stream))
- error("Attempted to decompress a resource that was not MadsPacked");
-
- stream->seek(14);
- _count = stream->readUint16LE();
- _items = new MadsPackEntry[_count];
-
- byte *headerData = new byte[0xA0];
- byte *header = headerData;
- stream->read(headerData, 0xA0);
-
- for (int i = 0; i < _count; ++i, header += 10) {
- // Get header data
- _items[i].hash = READ_LE_UINT16(header);
- _items[i].size = READ_LE_UINT32(header + 2);
- _items[i].compressedSize = READ_LE_UINT32(header + 6);
-
- _items[i].data = new byte[_items[i].size];
- if (_items[i].size == _items[i].compressedSize) {
- // Entry isn't compressed
- stream->read(_items[i].data, _items[i].size);
- } else {
- // Decompress the entry
- byte *compressedData = new byte[_items[i].compressedSize];
- stream->read(compressedData, _items[i].compressedSize);
-
- FabDecompressor fab;
- fab.decompress(compressedData, _items[i].compressedSize, _items[i].data, _items[i].size);
- delete[] compressedData;
- }
- }
-
- delete[] headerData;
- _dataOffset = stream->pos();
-}
-
-Common::SeekableReadStream *MadsPack::getItemStream(int index) {
- return new Common::MemoryReadStream(_items[index].data, _items[index].size, DisposeAfterUse::NO);
-}
-
-MadsPack::~MadsPack() {
- for (int i = 0; i < _count; ++i)
- delete[] _items[i].data;
- delete[] _items;
-}
-
-//--------------------------------------------------------------------------
-
-void FabDecompressor::decompress(const byte *srcData, int srcSize, byte *destData, int destSize) {
- byte copyLen, copyOfsShift, copyOfsMask, copyLenMask;
- unsigned long copyOfs;
- byte *destP;
-
- // Validate that the data starts with the FAB header
- if (strncmp((const char *)srcData, "FAB", 3) != 0)
- error("FabDecompressor - Invalid compressed data");
-
- int shiftVal = srcData[3];
- if ((shiftVal < 10) || (shiftVal > 13))
- error("FabDecompressor - Invalid shift start");
-
- copyOfsShift = 16 - shiftVal;
- copyOfsMask = 0xFF << (shiftVal - 8);
- copyLenMask = (1 << copyOfsShift) - 1;
- copyOfs = 0xFFFF0000;
- destP = destData;
-
- // Initialize data fields
- _srcData = srcData;
- _srcP = _srcData + 6;
- _srcSize = srcSize;
- _bitsLeft = 16;
- _bitBuffer = READ_LE_UINT16(srcData + 4);
-
- for (;;) {
- if (getBit() == 0) {
- if (getBit() == 0) {
- copyLen = ((getBit() << 1) | getBit()) + 2;
- copyOfs = *_srcP++ | 0xFFFFFF00;
- } else {
- copyOfs = (((_srcP[1] >> copyOfsShift) | copyOfsMask) << 8) | _srcP[0];
- copyLen = _srcP[1] & copyLenMask;
- _srcP += 2;
- if (copyLen == 0) {
- copyLen = *_srcP++;
- if (copyLen == 0)
- break;
- else if (copyLen == 1)
- continue;
- else
- copyLen++;
- } else {
- copyLen += 2;
- }
- copyOfs |= 0xFFFF0000;
- }
- while (copyLen-- > 0) {
- if (destP - destData == destSize)
- error("FabDecompressor - Decompressed data exceeded specified size");
-
- *destP = destP[(signed int)copyOfs];
- destP++;
- }
- } else {
- if (_srcP - srcData == srcSize)
- error("FabDecompressor - Passed end of input buffer during decompression");
- if (destP - destData == destSize)
- error("FabDecompressor - Decompressed data exceeded specified size");
-
- *destP++ = *_srcP++;
- }
- }
-
- if (destP - destData != destSize)
- error("FabDecompressor - Decompressed data does not match header decompressed size");
-}
-
-int FabDecompressor::getBit() {
- _bitsLeft--;
- if (_bitsLeft == 0) {
- if (_srcP - _srcData == _srcSize)
- error("FabDecompressor - Passed end of input buffer during decompression");
-
- _bitBuffer = (READ_LE_UINT16(_srcP) << 1) | (_bitBuffer & 1);
- _srcP += 2;
- _bitsLeft = 16;
- }
-
- int bit = _bitBuffer & 1;
- _bitBuffer >>= 1;
- return bit;
-}
-
-} // End of namespace M4
diff --git a/engines/m4/compression.h b/engines/m4/compression.h
deleted file mode 100644
index cb0ef74eb7..0000000000
--- a/engines/m4/compression.h
+++ /dev/null
@@ -1,77 +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 M4_COMPRESSION_H
-#define M4_COMPRESSION_H
-
-#include "common/scummsys.h"
-#include "common/stream.h"
-#include "common/endian.h"
-
-#include "m4/m4.h"
-
-namespace M4 {
-
-struct MadsPackEntry {
-public:
- uint16 hash;
- uint32 size;
- uint32 compressedSize;
- byte *data;
-};
-
-class MadsPack {
-private:
- MadsPackEntry *_items;
- int _count;
- int _dataOffset;
-
- void initialize(Common::SeekableReadStream *stream);
-public:
- static bool isCompressed(Common::SeekableReadStream *stream);
- MadsPack(Common::SeekableReadStream *stream);
- MadsPack(const char *resourceName, MadsM4Engine *vm);
- ~MadsPack();
-
- int getCount() const { return _count; }
- MadsPackEntry &getItem(int index) const { return _items[index]; }
- MadsPackEntry &operator[](int index) const { return _items[index]; }
- Common::SeekableReadStream *getItemStream(int index);
- int getDataOffset() const { return _dataOffset; }
-};
-
-class FabDecompressor {
-private:
- int _bitsLeft;
- uint32 _bitBuffer;
- const byte *_srcData, *_srcP;
- int _srcSize;
-
- int getBit();
-public:
- void decompress(const byte *srcData, int srcSize, byte *destData, int destSize);
-};
-
-} // End of namespace M4
-
-
-#endif
diff --git a/engines/m4/console.cpp b/engines/m4/console.cpp
deleted file mode 100644
index fa4ca6d121..0000000000
--- a/engines/m4/console.cpp
+++ /dev/null
@@ -1,428 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#include "common/textconsole.h"
-
-#include "m4/m4.h"
-#include "m4/console.h"
-#include "m4/dialogs.h"
-#include "m4/scene.h"
-#include "m4/staticres.h"
-
-namespace M4 {
-
-Console::Console(MadsM4Engine *vm) : GUI::Debugger() {
- _vm = vm;
-
- DCmd_Register("scene", WRAP_METHOD(Console, cmdLoadScene));
- DCmd_Register("start", WRAP_METHOD(Console, cmdStartingScene));
- DCmd_Register("show_hotspots", WRAP_METHOD(Console, cmdShowHotSpots));
- DCmd_Register("list_hotspots", WRAP_METHOD(Console, cmdListHotSpots));
- DCmd_Register("play_sound", WRAP_METHOD(Console, cmdPlaySound));
- DCmd_Register("play_dsr_sound", WRAP_METHOD(Console, cmdPlayDSRSound));
- DCmd_Register("show_resources", WRAP_METHOD(Console, cmdShowResources));
- DCmd_Register("show_codes", WRAP_METHOD(Console, cmdShowCodes));
- DCmd_Register("dump_file", WRAP_METHOD(Console, cmdDumpFile));
- DCmd_Register("sprite", WRAP_METHOD(Console, cmdShowSprite));
- DCmd_Register("start_conv", WRAP_METHOD(Console, cmdStartConversation));
- DCmd_Register("textview", WRAP_METHOD(Console, cmdShowTextview));
- DCmd_Register("animview", WRAP_METHOD(Console, cmdShowAnimview));
-}
-
-Console::~Console() {
-}
-
-static int strToInt(const char *s) {
- if (!*s)
- // No string at all
- return 0;
- else if (toupper(s[strlen(s) - 1]) != 'H')
- // Standard decimal string
- return atoi(s);
-
- // Hexadecimal string
- uint tmp = 0;
- int read = sscanf(s, "%xh", &tmp);
- if (read < 1)
- error("strToInt failed on string \"%s\"", s);
- return (int)tmp;
-}
-
-bool Console::cmdLoadScene(int argc, const char **argv) {
- if (argc != 2) {
- DebugPrintf("Usage: %s <scene number>\n", argv[0]);
- return true;
- } else {
- if (_vm->isM4())
- _vm->_kernel->newRoom = atoi(argv[1]);
- else
- _vm->_scene->loadScene(atoi(argv[1]));
- return false;
- }
-}
-
-bool Console::cmdStartingScene(int argc, const char **argv) {
- if (_vm->getGameType() != GType_Riddle) {
- if (_vm->isM4())
- _vm->_kernel->newRoom = FIRST_SCENE;
- else
- _vm->_scene->loadScene(FIRST_SCENE);
- return false;
- } else {
- DebugPrintf("%s: Riddle of Master Lu is not supported", argv[0]);
- return true;
- }
-}
-
-bool Console::cmdShowHotSpots(int argc, const char **argv) {
- _vm->_scene->showHotSpots();
- return false;
-}
-
-bool Console::cmdListHotSpots(int argc, const char **argv) {
- DebugPrintf("Scene hotspots\n");
- _vm->_scene->getSceneResources().hotspots->dump();
- if (_vm->isM4()) {
- DebugPrintf("Scene parallax\n");
- _m4Vm->scene()->getSceneResources().parallax->dump();
- DebugPrintf("Scene dynamic hotspots\n");
- _vm->_scene->getSceneResources().dynamicHotspots->dump();
- }
- return true;
-}
-
-bool Console::cmdPlaySound(int argc, const char **argv) {
- if (argc != 2) {
- DebugPrintf("Usage: %s <sound file>\n", argv[0]);
- } else {
- _vm->_sound->playSound(argv[1], 255, false);
- }
- return true;
-}
-
-bool Console::cmdPlayDSRSound(int argc, const char **argv) {
- if (argc != 2 && argc != 3) {
- DebugPrintf("Usage: %s <sound index> <DSR file>\n", argv[0]);
- DebugPrintf("The DSR file parameter is optional, and specifies which DSR to load\n");
- } else {
- if (argc == 3)
- _vm->_sound->loadDSRFile(argv[2]);
- _vm->_sound->playDSRSound(atoi(argv[1]), 255, false);
- }
- return true;
-}
-
-bool Console::cmdShowResources(int argc, const char **argv) {
- _vm->res()->dump();
- return true;
-}
-
-bool Console::cmdShowCodes(int argc, const char **argv) {
- _vm->_scene->showCodes();
- return false;
-}
-
-bool Console::cmdDumpFile(int argc, const char **argv) {
- if (argc != 2 && argc != 3) {
- DebugPrintf("Usage: %s <file> <uncompress>\n", argv[0]);
- DebugPrintf("If uncompress is 1, the file is uncompressed (for MADS games)\n");
- } else {
- if (argc == 2) {
- _vm->dumpFile(argv[1], false);
- } else {
- if (argc == 3 && atoi(argv[2]) == 1)
- _vm->dumpFile(argv[1], true);
- else
- _vm->dumpFile(argv[1], false);
- }
- }
- return true;
-}
-
-bool Console::cmdShowSprite(int argc, const char **argv) {
- View *view = _vm->_viewManager->getView(VIEWID_SCENE);
- if (view == NULL)
- DebugPrintf("The scene view isn't currently active\n");
- else if (argc < 2)
- DebugPrintf("Usage: %s resource_name\n", argv[0]);
- else {
- char resourceName[20];
- strncpy(resourceName, argv[1], 15);
- resourceName[15] = '\0';
- if (!strchr(resourceName, '.'))
- strcat(resourceName, ".SS");
-
- _vm->_viewManager->moveToFront(view);
- Common::SeekableReadStream *data = _vm->res()->get(resourceName);
- SpriteAsset *asset = new SpriteAsset(_vm, data, data->size(), resourceName);
- _vm->res()->toss(resourceName);
-
- RGBList *palData = new RGBList(asset->getColorCount(), asset->getPalette(), true);
- _vm->_palette->addRange(palData);
-
- // Get the scene background surface
- M4Surface *bg = _vm->_scene->getBackgroundSurface();
-
- // Write the sprite onto the screen
- int x = 0, y = 0, yMax = 0;
- for (int index = 0; index < asset->getCount(); index++) {
- M4Sprite *spr = asset->getFrame(index);
- spr->translate(palData); // sprite pixel translation
-
- if ((x + spr->width() >= bg->width()) && (yMax != 0)) {
- x = 0;
- y += yMax;
- yMax = 0;
- }
-
- if (y >= bg->height())
- break;
-
- spr->copyTo(bg, x, y, (int)spr->getTransparencyIndex());
-
- x += spr->width();
- yMax = MAX(yMax, spr->height());
- }
-
- view->restore(0, 0, view->width(), view->height());
- return false;
- }
-
- return true;
-}
-
-bool Console::cmdStartConversation(int argc, const char **argv) {
- if (argc != 2) {
- DebugPrintf("Usage: %s <conversation file name>\n", argv[0]);
- return true;
- } else if (_vm->isM4()) {
- ((M4Engine *)_vm)->_converse->startConversation(argv[1]);
- return false;
- } else {
- error("MADS engine does not support conversations yet");
- return false;
- }
-}
-
-bool Console::cmdShowTextview(int argc, const char **argv) {
- if (argc != 2) {
- DebugPrintf("Usage: %s <txr resource>\n", argv[0]);
- return true;
- }
-
- _vm->_viewManager->showTextView(argv[1], false);
- return false;
-}
-
-bool Console::cmdShowAnimview(int argc, const char **argv) {
- if (argc != 2) {
- DebugPrintf("Usage: %s <res resource>\n", argv[0]);
- return true;
- }
-
- char resName[80];
- strcpy(resName, "@");
- strcat(resName, *argv[1] == '@' ? argv[1] + 1 : argv[1]);
-
- _vm->_viewManager->showAnimView(resName, false);
- return false;
-}
-
-/*--------------------------------------------------------------------------*/
-
-MadsConsole::MadsConsole(MadsEngine *vm): Console(vm) {
- _vm = vm;
-
- DCmd_Register("object", WRAP_METHOD(MadsConsole, cmdObject));
- DCmd_Register("message", WRAP_METHOD(MadsConsole, cmdMessage));
- DCmd_Register("scene_info", WRAP_METHOD(MadsConsole, cmdSceneInfo));
- DCmd_Register("anim", WRAP_METHOD(MadsConsole, cmdPlayAnimation));
-}
-
-bool MadsConsole::cmdObject(int argc, const char **argv) {
- if (argc == 1) {
- DebugPrintf("Usage: object ['list' | '#objnum' | 'add #objnum']\n");
- } else if (!strcmp(argv[1], "list")) {
- // List of objects
- for (uint objStart = 0; objStart < _vm->globals()->getObjectsSize(); objStart += 5) {
- DebugPrintf("%2d - ", objStart);
- for (uint objId = objStart; objId < MIN<uint>(_vm->globals()->getObjectsSize(), objStart + 5); ++objId) {
- if (objId != objStart) DebugPrintf(", ");
- uint16 descId = _vm->globals()->getObject(objId)->_descId;
- DebugPrintf("%s", _vm->globals()->getVocab(descId));
- }
-
- DebugPrintf("\n");
- }
-
- DebugPrintf("\n");
- } else if (!strcmp(argv[1], "add") && (argc == 3)) {
- // Add the specified object to the player's inventory
- int objNum = strToInt(argv[2]);
-
- if ((objNum < 0) || (objNum >= (int)_vm->globals()->getObjectsSize()))
- DebugPrintf("Invalid object specified\n");
- else if (_vm->isM4())
- DebugPrintf("Not implemented for M4 games\n");
- else {
- _vm->_scene->getInterface()->addObjectToInventory(objNum);
- return false;
- }
-
- } else {
- // Print the details of a specific object
- int objNum = strToInt(argv[1]);
-
- if ((objNum < 0) || (objNum >= (int)_vm->globals()->getObjectsSize()))
- DebugPrintf("Invalid object specified\n");
- else {
- const MadsObject *obj = _vm->globals()->getObject(objNum);
-
- DebugPrintf("Object #%d (%s) room=%d article=%d/%s vocabs=%d", objNum, _vm->globals()->getVocab(obj->_descId),
- obj->_roomNumber, (int)obj->_article, englishMADSArticleList[obj->_article], obj->_vocabCount);
-
- if (obj->_vocabCount > 0) {
- DebugPrintf(" - ");
- for (int i = 0; i < obj->_vocabCount; ++i) {
- if (i != 0) DebugPrintf(", ");
- DebugPrintf("%s (%d)/%d,%d", _vm->globals()->getVocab(obj->_vocabList[i].vocabId),
- obj->_vocabList[i].vocabId, obj->_vocabList[i].flags1, obj->_vocabList[i].flags2);
- }
- }
- DebugPrintf("\n");
- }
- }
-
- return true;
-}
-
-bool MadsConsole::cmdMessage(int argc, const char **argv) {
- if (argc == 1) {
- DebugPrintf("message 'objnum'\n");
- } else if (!strcmp(argv[1], "list_quotes")) {
- // Dump the quotes list
-#if 0
- // FIXME: The following code is not portable and hence has been disabled.
- // Try replacing FILE by Common::DumpFile.
- FILE *destFile = fopen("mads_quotes.txt", "wb");
- for (uint i = 0; i < _vm->globals()->getQuotesSize(); ++i)
- fprintf(destFile, "%.3d - %s\n", i, _vm->globals()->getQuote(i));
- fclose(destFile);
-#endif
-
- } else if (!strcmp(argv[1], "list_vocab")) {
- // Dump the vocab list
-#if 0
- // FIXME: The following code is not portable and hence has been disabled.
- // Try replacing FILE by Common::DumpFile.
- FILE *destFile = fopen("mads_vocab.txt", "wb");
- for (uint i = 1; i <= _vm->globals()->getVocabSize(); ++i)
- fprintf(destFile, "%.3d/%.3x - %s\n", i, i, _vm->globals()->getVocab(i));
- fclose(destFile);
-#endif
-
- } else {
- int messageIdx = strToInt(argv[1]);
-
- if ((argc != 3) || (strcmp(argv[2], "idx") != 0))
- messageIdx = _vm->globals()->messageIndexOf(messageIdx);
-
- const char *msg = _vm->globals()->loadMessage(messageIdx);
- if (!msg)
- DebugPrintf("Unknown message\n");
- else {
- Dialog *dlg = new Dialog(_vm, msg, "TEST DIALOG");
-
- _vm->_viewManager->addView(dlg);
- _vm->_viewManager->moveToFront(dlg);
-
- return false;
- }
- }
-
- return true;
-}
-
-bool MadsConsole::cmdSceneInfo(int argc, const char **argv) {
- DebugPrintf("Current scene is: %i\n", _vm->_scene->getCurrentScene());
-
- return true;
-}
-
-bool MadsConsole::cmdPlayAnimation(int argc, const char **argv) {
- View *view = _vm->_viewManager->getView(VIEWID_SCENE);
- if (view == NULL) {
- DebugPrintf("The scene view isn't currently active\n");
- } else if (argc != 2 && argc != 3) {
- DebugPrintf("Usage: %s <anim resource (*.aa)> <fullscreen>\n", argv[0]);
- DebugPrintf("If fullscreen is 1, the screen palette is replaced with the palette of the animation\n");
- } else {
- char resourceName[20];
- strncpy(resourceName, argv[1], 15);
- resourceName[15] = '\0';
- if (!strchr(resourceName, '.'))
- strcat(resourceName, ".AA");
-
- _vm->_viewManager->moveToFront(view);
- if (argc == 3 && atoi(argv[2]) == 1)
- _madsVm->_palette->deleteAllRanges();
-
- _madsVm->scene()->_sceneAnimation->load(resourceName, 0);
-
- view->restore(0, 0, view->width(), view->height());
- return false;
- }
-
- return true;
-}
-
-/*--------------------------------------------------------------------------*/
-
-M4Console::M4Console(M4Engine *vm): Console(vm) {
- _vm = vm;
-
- DCmd_Register("scene_info", WRAP_METHOD(M4Console, cmdSceneInfo));
-}
-
-bool M4Console::cmdSceneInfo(int argc, const char **argv) {
- DebugPrintf("Current scene is: %i\n", _m4Vm->scene()->getCurrentScene());
-
- DebugPrintf("Scene resources:\n");
- DebugPrintf("artBase: %s\n", _m4Vm->scene()->getSceneResources().artBase);
- DebugPrintf("pictureBase: %s\n", _m4Vm->scene()->getSceneResources().pictureBase);
- DebugPrintf("hotspotCount: %i\n", _m4Vm->scene()->getSceneResources().hotspots->size());
- DebugPrintf("parallaxCount: %i\n", _m4Vm->scene()->getSceneResources().parallaxCount);
- DebugPrintf("dynHotspotCount: %i\n", _m4Vm->scene()->getSceneResources().dynamicHotspots->size());
- DebugPrintf("frontY: %i\n", _m4Vm->scene()->getSceneResources().frontY);
- DebugPrintf("backY: %i\n", _m4Vm->scene()->getSceneResources().backY);
- DebugPrintf("frontScale: %i\n", _m4Vm->scene()->getSceneResources().frontScale);
- DebugPrintf("backScale: %i\n", _m4Vm->scene()->getSceneResources().backScale);
- DebugPrintf("depthTable: ");
- for (uint i = 0; i < 16; i++)
- DebugPrintf("%i ", _m4Vm->scene()->getSceneResources().depthTable[i]);
- DebugPrintf("\n");
- DebugPrintf("railNodeCount: %i\n", _m4Vm->scene()->getSceneResources().railNodeCount);
-
- return true;
-}
-
-} // End of namespace M4
diff --git a/engines/m4/console.h b/engines/m4/console.h
deleted file mode 100644
index fc473b6464..0000000000
--- a/engines/m4/console.h
+++ /dev/null
@@ -1,83 +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 M4_CONSOLE_H
-#define M4_CONSOLE_H
-
-#include "gui/debugger.h"
-
-namespace M4 {
-
-class MadsM4Engine;
-class MadsEngine;
-
-class Console : public GUI::Debugger {
-private:
- MadsM4Engine *_vm;
-
- bool cmdLoadScene(int argc, const char **argv);
- bool cmdStartingScene(int argc, const char **argv);
- bool cmdShowHotSpots(int argc, const char **argv);
- bool cmdListHotSpots(int argc, const char **argv);
- bool cmdPlaySound(int argc, const char **argv);
- bool cmdPlayDSRSound(int argc, const char **argv);
- bool cmdShowResources(int argc, const char **argv);
- bool cmdShowCodes(int argc, const char **argv);
- bool cmdDumpFile(int argc, const char **argv);
- bool cmdShowSprite(int argc, const char **argv);
- bool cmdStartConversation(int argc, const char **argv);
- bool cmdShowTextview(int argc, const char **argv);
- bool cmdShowAnimview(int argc, const char **argv);
-
-public:
- Console(MadsM4Engine *vm);
- virtual ~Console();
-};
-
-class MadsConsole : public Console {
-private:
- MadsEngine *_vm;
-
- bool cmdObject(int argc, const char **argv);
- bool cmdMessage(int argc, const char **argv);
- bool cmdSceneInfo(int argc, const char **argv);
- bool cmdPlayAnimation(int argc, const char **argv);
-
-public:
- MadsConsole(MadsEngine *vm);
- virtual ~MadsConsole() {}
-};
-
-class M4Console : public Console {
-private:
- M4Engine *_vm;
-
- bool cmdSceneInfo(int argc, const char **argv);
-public:
- M4Console(M4Engine *vm);
- virtual ~M4Console() {}
-};
-
-} // End of namespace M4
-
-
-#endif
diff --git a/engines/m4/converse.cpp b/engines/m4/converse.cpp
deleted file mode 100644
index bdce7928ac..0000000000
--- a/engines/m4/converse.cpp
+++ /dev/null
@@ -1,1239 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#include "common/array.h"
-#include "common/hashmap.h"
-#include "common/substream.h"
-#include "common/textconsole.h"
-
-#include "m4/converse.h"
-#include "m4/resource.h"
-#include "m4/globals.h"
-#include "m4/m4_views.h"
-#include "m4/compression.h"
-
-namespace M4 {
-
-#define CONV_ENTRIES_X_OFFSET 20
-#define CONV_ENTRIES_Y_OFFSET 4
-#define CONV_ENTRIES_HEIGHT 20
-#define CONV_MAX_SHOWN_ENTRIES 5
-
-#define CONVERSATION_ENTRY_HIGHLIGHTED 22
-#define CONVERSATION_ENTRY_NORMAL 3
-
-// Conversation chunks
-// Header
-#define HEAD_CONV MKTAG('C','O','N','V') // conversation
-#define CHUNK_DECL MKTAG('D','E','C','L') // declaration
-#define CHUNK_NODE MKTAG('N','O','D','E') // node
-#define CHUNK_LNOD MKTAG('L','N','O','D') // linear node
-#define CHUNK_ETRY MKTAG('E','T','R','Y') // entry
-#define CHUNK_TEXT MKTAG('T','E','X','T') // text
-#define CHUNK_MESG MKTAG('M','E','S','G') // message
-// Conversation chunks - entry related (unconditional)
-#define CHUNK_RPLY MKTAG('R','P','L','Y') // reply
-#define CHUNK_HIDE MKTAG('H','I','D','E') // hide entry
-#define CHUNK_UHID MKTAG('U','H','I','D') // unhide entry
-#define CHUNK_DSTR MKTAG('D','S','T','R') // destroy entry
-// Conversation chunks - entry related (conditional)
-#define CHUNK_CRPL MKTAG('C','R','P','L') // reply
-#define CHUNK_CHDE MKTAG('C','H','D','E') // hide entry
-#define CHUNK_CUHD MKTAG('C','U','H','D') // unhide entry
-#define CHUNK_CDST MKTAG('D','D','T','S') // destroy entry
-// Conversation chunks - branching and logic (unconditional)
-#define CHUNK_ASGN MKTAG('A','S','G','N') // assign
-#define CHUNK_GOTO MKTAG('G','O','T','O') // goto chunk
-#define CHUNK_EXIT MKTAG('E','X','I','T') // exit/return from goto
-// Conversation chunks - branching and logic (conditional)
-#define CHUNK_CASN MKTAG('C','A','S','N') // assign
-#define CHUNK_CCGO MKTAG('C','C','G','O') // goto chunk
-#define CHUNK_CEGO MKTAG('C','E','G','O') // exit/return from goto
-// Others
-#define CHUNK_FALL MKTAG('F','A','L','L') // fallthrough
-#define CHUNK_WRPL MKTAG('W','R','P','L') // weighted reply chunk
-#define CHUNK_WPRL MKTAG('W','P','R','L') // weighted preply chunk
-
-
-ConversationView::ConversationView(MadsM4Engine *vm): View(vm, Common::Rect(0,
- vm->_screen->height() - INTERFACE_HEIGHT, vm->_screen->width(), vm->_screen->height())) {
-
- _screenType = VIEWID_CONVERSATION;
- _screenFlags.layer = LAYER_INTERFACE;
- _screenFlags.visible = false;
- _screenFlags.get = SCREVENT_MOUSE;
- _conversationState = kNoConversation;
- _currentHandle = NULL;
-}
-
-ConversationView::~ConversationView() {
- _activeItems.clear();
-}
-
-void ConversationView::setNode(int32 nodeIndex) {
- _highlightedIndex = -1;
- _xEnd = CONV_ENTRIES_X_OFFSET;
- _vm->_font->setFont(FONT_CONVERSATION);
-
- // TODO: Conversation styles and colors
- _vm->_font->current()->setColors(2, 1, 3);
-
- _currentNodeIndex = nodeIndex;
-
- _activeItems.clear();
-
- if (nodeIndex != -1) {
- ConvEntry *node = _m4Vm->_converse->getNode(nodeIndex);
-
- for (uint i = 0; i < node->entries.size(); ++i) {
- if (!node->entries[i]->visible)
- continue;
-
- if ((int)_activeItems.size() > CONV_MAX_SHOWN_ENTRIES) {
- warning("TODO: scrolling. Max shown entries are %i, skipping entry %i",
- CONV_MAX_SHOWN_ENTRIES, i);
- }
-
- // Add node to active items list
- _activeItems.push_back(node->entries[i]);
-
- if (node->entries[i]->autoSelect || strlen(node->entries[i]->text) == 0) {
- //warning(kDebugConversations, "Auto selecting entry %i of node %i\n", i, nodeIndex);
- selectEntry(i);
- return;
- }
-
- // Figure out the longest string to determine where option highlighting ends
- int tempX = _vm->_font->current()->getWidth(node->entries[i]->text, 0) +
- CONV_ENTRIES_X_OFFSET + 10;
- _xEnd = MAX(_xEnd, tempX);
- }
-
- // Make sure that there aren't too many entries
- //assert((int)_activeItems.size() < (height() - CONV_ENTRIES_Y_OFFSET) / CONV_ENTRIES_HEIGHT);
-
- // Fallthrough
- if (node->fallthroughMinEntries >= 0 && node->fallthroughOffset >= 0) {
- //warning(kDebugConversations, "Current node falls through node at offset %i when entries are less or equal than %i\n",
- // node->fallthroughOffset, node->fallthroughMinEntries);
- if (_activeItems.size() <= (uint32)node->fallthroughMinEntries) {
- const EntryInfo *entryInfo = _m4Vm->_converse->getEntryInfo(node->fallthroughOffset);
- //warning(kDebugConversations, "Entries are less than or equal to %i, falling through to node at offset %i, index %i\n",
- // node->fallthroughMinEntries, node->fallthroughOffset, entryInfo->nodeIndex);
- setNode(entryInfo->nodeIndex);
- return;
- }
- }
-
- _entriesShown = true;
- _conversationState = kConversationOptionsShown;
- }
-}
-
-void ConversationView::onRefresh(RectList *rects, M4Surface *destSurface) {
- //if (!this->isVisible())
- // return;
- clear();
-
- if (_entriesShown) {
- // Write out the conversation options
- _vm->_font->setFont(FONT_CONVERSATION);
- for (int i = 0; i < (int)_activeItems.size(); ++i) {
- // TODO: scrolling
- if (i > CONV_MAX_SHOWN_ENTRIES - 1)
- break;
-
- _vm->_font->current()->setColor((_highlightedIndex == i) ? CONVERSATION_ENTRY_HIGHLIGHTED :
- CONVERSATION_ENTRY_NORMAL);
-
- _vm->_font->current()->writeString(this, _activeItems[i]->text, CONV_ENTRIES_X_OFFSET,
- CONV_ENTRIES_Y_OFFSET + CONV_ENTRIES_HEIGHT * i, 0, 0);
- }
- }
- View::onRefresh(rects, destSurface);
-}
-
-bool ConversationView::onEvent(M4EventType eventType, int32 param, int x, int y, bool &captureEvents) {
- //if (!this->isVisible())
- // return false;
- if (!_entriesShown)
- return false;
- if (eventType == KEVENT_KEY)
- return false;
-
- int localY = y - _coords.top;
- int selectedIndex = _highlightedIndex;
-
- switch (eventType) {
- case MEVENT_MOVE:
- if ((x < CONV_ENTRIES_X_OFFSET) || (x >= _xEnd) || (localY < CONV_ENTRIES_Y_OFFSET))
- _highlightedIndex = -1;
- else {
- int index = (localY - CONV_ENTRIES_Y_OFFSET) / CONV_ENTRIES_HEIGHT;
- _highlightedIndex = (index >= (int)_activeItems.size()) ? -1 : index;
- }
- break;
-
- case MEVENT_LEFT_RELEASE:
- if (_highlightedIndex != -1) {
- selectEntry(selectedIndex);
- }
- break;
-
- default:
- break;
- }
-
- return true;
-}
-
-void ConversationView::selectEntry(int entryIndex) {
- char buffer[20];
- sprintf(buffer, "%s.raw", _activeItems[entryIndex]->voiceFile);
-
- _entriesShown = false;
- _conversationState = kEntryIsActive;
- _vm->_player->setCommandsAllowed(false);
- // Necessary, as entries can be selected programmatically
- _highlightedIndex = entryIndex;
-
- // Play the selected entry's voice
- if (strlen(_activeItems[entryIndex]->voiceFile) > 0) {
- _currentHandle = _vm->_sound->getHandle();
- _vm->_sound->playVoice(buffer, 255);
- } else {
- _currentHandle = NULL;
- }
-
- // Hide selected entry, unless it has a persistent flag set
- if (!(_activeItems[entryIndex]->flags & kEntryPersists)) {
- //debugCN(kDebugConversations, "Hiding selected entry\n");
- _m4Vm->_converse->getNode(_currentNodeIndex)->entries[entryIndex]->visible = false;
- } else {
- //debugCN(kDebugConversations, "Selected entry is persistent, not hiding it\n");
- }
-}
-
-void ConversationView::updateState() {
- switch (_conversationState) {
- case kConversationOptionsShown:
- return;
- case kEntryIsActive:
- case kReplyIsActive:
- // FIXME: for now, we determine whether a conversation entry is
- // finished by waiting for its associated speech file to finish playing
- if (_currentHandle != NULL && _vm->_sound->isHandleActive(_currentHandle)) {
- return;
- } else {
- playNextReply();
- } // end else
- break;
- case kNoConversation:
- return;
- default:
- error("Unknown converstation state");
- break;
- }
-}
-
-void ConversationView::playNextReply() {
- char buffer[20];
-
- assert(_highlightedIndex >= 0);
-
- // Start playing the first reply
- for (uint32 i = 0; i < _activeItems[_highlightedIndex]->entries.size(); i++) {
- ConvEntry *currentEntry = _activeItems[_highlightedIndex]->entries[i];
-
- if (currentEntry->isConditional) {
- if (!_m4Vm->_converse->evaluateCondition(
- _m4Vm->_converse->getValue(currentEntry->condition.offset),
- currentEntry->condition.op, currentEntry->condition.val))
- continue; // don't play this reply
- }
-
- if (currentEntry->entryType != kWeightedReply) {
- sprintf(buffer, "%s.raw", currentEntry->voiceFile);
- if (strlen(currentEntry->voiceFile) > 0) {
- _currentHandle = _vm->_sound->getHandle();
- _vm->_sound->playVoice(buffer, 255);
- // Remove reply from the list of replies
- _activeItems[_highlightedIndex]->entries.remove_at(i);
- _conversationState = kReplyIsActive;
- return;
- } else {
- _currentHandle = NULL;
- }
- } else {
- int selectedWeight = _vm->_random->getRandomNumber(currentEntry->totalWeight - 1) + 1;
- //debugCN(kDebugConversations, "Selected weight: %i\n", selectedWeight);
- int previousWeight = 1;
- int currentWeight = 0;
-
- for (uint32 j = 0; j < currentEntry->entries.size(); j++) {
- currentWeight += currentEntry->entries[j]->weight;
- if (selectedWeight >= previousWeight && selectedWeight <= currentWeight) {
- sprintf(buffer, "%s.raw", currentEntry->entries[j]->voiceFile);
- if (strlen(currentEntry->entries[j]->voiceFile) > 0) {
- _currentHandle = _vm->_sound->getHandle();
- _vm->_sound->playVoice(buffer, 255);
- // Remove reply from the list of replies
- _activeItems[_highlightedIndex]->entries.remove_at(i);
- _conversationState = kReplyIsActive;
- return;
- } else {
- _currentHandle = NULL;
- }
- break;
- }
- previousWeight += currentWeight;
- } // end for j
- } // end if
- } // end for i
-
- // If we reached here, there are no more replies, so perform the active entry's actions
-
- //debugCN(kDebugConversations, "Current selection does %i actions\n", _activeItems[entryIndex]->actions.size());
- for (uint32 i = 0; i < _activeItems[_highlightedIndex]->actions.size(); i++) {
- if (!_m4Vm->_converse->performAction(_activeItems[_highlightedIndex]->actions[i]))
- break;
- } // end for
-
- // Refresh the conversation node, in case it hasn't changed
- setNode(_currentNodeIndex);
-
- _entriesShown = true;
- _vm->_player->setCommandsAllowed(true);
-
- // Check if the conversation has been ended
- if (_currentNodeIndex == -1) {
- _conversationState = kNoConversation;
- }
-}
-
-//--------------------------------------------------------------------------
-
-void Converse::startConversation(const char *convName, bool showConverseBox, ConverseStyle style) {
- if (_vm->isM4())
- loadConversation(convName);
- else
- loadConversationMads(convName);
-
- if (!_vm->isM4()) showConverseBox = false; // TODO: remove
-
- _playerCommandsAllowed = _vm->_player->commandsAllowed;
- if (_vm->isM4()) // TODO: remove (interface not implemented yet in MADS games)
- _interfaceWasVisible = _m4Vm->scene()->getInterface()->isVisible();
- _vm->_player->setCommandsAllowed(false);
- _style = style;
-
- if (showConverseBox) {
- _vm->_conversationView->show();
- _vm->_mouse->lockCursor(CURSOR_ARROW);
-
- if (_interfaceWasVisible)
- _m4Vm->scene()->getInterface()->hide();
-
- _vm->_conversationView->setNode(0);
- _vm->_conversationView->show();
- }
-}
-
-void Converse::endConversation() {
- _vm->_conversationView->setNode(-1);
- _vm->_conversationView->hide();
- // TODO: do a more proper cleanup here
- _convNodes.clear();
- _variables.clear();
- _offsetMap.clear();
- _vm->_player->setCommandsAllowed(_playerCommandsAllowed);
- if (_interfaceWasVisible)
- _m4Vm->scene()->getInterface()->show();
-}
-
-void Converse::loadConversation(const char *convName) {
- char name[40];
- char buffer[256];
- sprintf(name, "%s.chk", convName);
- Common::SeekableReadStream *convS = _vm->res()->get(name);
- uint32 header = convS->readUint32LE();
- uint32 size;
- uint32 chunk;
- uint32 data = 0;
- uint32 i = 0;
- ConvEntry* curEntry = NULL;
- ConvEntry* replyEntry = NULL;
- int32 currentWeightedEntry = -1;
- EntryAction* curAction = NULL;
- uint32 curNode = 0;
- uint32 chunkPos = 0;
- uint32 val;
- int32 autoSelectIndex = -1;
- int returnAddress = -1;
-
- bool debugFlag = false; // set to true for debug messages
-
- // Conversation *.chk files contain a 'CONV' header in LE format
- if (header != HEAD_CONV) {
- warning("Unexpected conversation file external header");
- return;
- }
- size = convS->readUint32LE(); // is this used at all?
- if (debugFlag) debugCN(kDebugConversations, "Conv chunk size (external header): %i\n", size);
-
- // Conversation name, which is the conversation file's name
- // without the extension
- convS->read(buffer, 8);
- if (debugFlag) debugCN(kDebugConversations, "Conversation name: %s\n", buffer);
-
- while (true) {
- chunkPos = convS->pos();
- chunk = convS->readUint32LE(); // read chunk
- if (convS->eos()) break;
-
- if (debugFlag) debugC(kDebugConversations, "***** Pos: %i -> ", chunkPos);
- switch (chunk) {
- case CHUNK_DECL: // Declare
- if (debugFlag) debugCN(kDebugConversations, "DECL chunk\n");
- data = convS->readUint32LE();
- if (debugFlag) debugCN(kDebugConversations, "Tag: %i\n", data);
- if (data > 0)
- warning("Tag > 0 in DECL chunk, value is: %i", data); // TODO
- val = convS->readUint32LE();
- if (debugFlag) debugCN(kDebugConversations, "Value: %i\n", val);
- data = convS->readUint32LE();
- if (debugFlag) debugCN(kDebugConversations, "Flags: %i\n", data);
- if (data > 0)
- warning("Flags != 0 in DECL chunk, value is %i", data); // TODO
- setValue(chunkPos, val);
- break;
- // ----------------------------------------------------------------------------
- case CHUNK_NODE: // Node
- case CHUNK_LNOD: // Linear node
- // Create new node
- curEntry = new ConvEntry();
- curEntry->offset = chunkPos;
- curEntry->entryType = (chunk == CHUNK_NODE) ? kNode : kLinearNode;
- curEntry->fallthroughMinEntries = -1;
- curEntry->fallthroughOffset = -1;
- if (chunk == CHUNK_NODE) {
- if (debugFlag) debugCN(kDebugConversations, "NODE chunk\n");
- } else {
- if (debugFlag) debugCN(kDebugConversations, "LNOD chunk\n");
- }
- curNode = convS->readUint32LE();
- if (debugFlag) debugCN(kDebugConversations, "Node number: %i\n", curNode);
- data = convS->readUint32LE();
- if (debugFlag) debugCN(kDebugConversations, "Tag: %i\n", data);
- if (chunk == CHUNK_LNOD) {
- autoSelectIndex = convS->readUint32LE();
- if (debugFlag) debugCN(kDebugConversations, "Autoselect entry number: %i\n", autoSelectIndex);
- }
- size = convS->readUint32LE();
- if (debugFlag) debugCN(kDebugConversations, "Number of entries: %i\n", size);
- for (i = 0; i < size; i++) {
- data = convS->readUint32LE();
- if (debugFlag) debugCN(kDebugConversations, "Entry %i: %i\n", i + 1, data);
- }
- _convNodes.push_back(curEntry);
- setEntryInfo(curEntry->offset, curEntry->entryType, curNode, -1);
- break;
- case CHUNK_ETRY: // Entry
- // Create new entry
- curEntry = new ConvEntry();
- curEntry->offset = chunkPos;
- curEntry->entryType = kEntry;
- strcpy(curEntry->voiceFile, "");
- strcpy(curEntry->text, "");
- if (debugFlag) debugCN(kDebugConversations, "ETRY chunk\n");
- data = convS->readUint32LE();
- if (debugFlag) debugCN(kDebugConversations, "Unknown (attributes perhaps?): %i\n", data);
- data = convS->readUint32LE();
- if (debugFlag) debugCN(kDebugConversations, "Entry flags: ");
- if (debugFlag) if (data & kEntryInitial) debugCN(kDebugConversations, "Initial ");
- if (debugFlag) if (data & kEntryPersists) debugCN(kDebugConversations, "Persists ");
- if (debugFlag) debugCN(kDebugConversations, "\n");
- curEntry->flags = data;
- curEntry->visible = (curEntry->flags & kEntryInitial) ? true : false;
- if (autoSelectIndex >= 0) {
- if (_convNodes[curNode]->entries.size() == (uint32)autoSelectIndex) {
- curEntry->autoSelect = true;
- autoSelectIndex = -1;
- } else {
- curEntry->autoSelect = false;
- }
- } else {
- curEntry->autoSelect = false;
- }
- _convNodes[curNode]->entries.push_back(curEntry);
- setEntryInfo(curEntry->offset, curEntry->entryType,
- curNode, _convNodes[curNode]->entries.size() - 1);
- replyEntry = NULL;
- break;
- case CHUNK_WPRL: // Weighted preply
- // WPRL chunks are random entries that the character would say, not an NPC
- // They don't seem to be used in Orion Burger
- warning("WPRL chunk - treating as WRPL chunk");
- case CHUNK_WRPL: // Weighted reply
- case CHUNK_CRPL: // Conditional reply
- case CHUNK_RPLY: // Reply
- {
- ConvEntry* weightedEntry = NULL;
- // Create new reply
- replyEntry = new ConvEntry();
- replyEntry->offset = chunkPos;
- strcpy(replyEntry->voiceFile, "");
-
- // Conditional part
- if (chunk == CHUNK_CRPL) {
- replyEntry->isConditional = true;
- replyEntry->condition.offset = convS->readUint32LE();
- replyEntry->condition.op = convS->readUint32LE();
- replyEntry->condition.val = convS->readUint32LE();
- } else {
- replyEntry->isConditional = false;
- }
-
- if (chunk == CHUNK_WPRL || chunk == CHUNK_WRPL) {
- replyEntry->entryType = kWeightedReply;
- replyEntry->totalWeight = 0;
- if (debugFlag) debugCN(kDebugConversations, "WRPL chunk\n");
- size = convS->readUint32LE();
- if (debugFlag) debugCN(kDebugConversations, "Weighted reply %i - %i entries:\n", i, size);
- for (i = 0; i < size; i++) {
- weightedEntry = new ConvEntry();
- weightedEntry->offset = chunkPos;
- strcpy(weightedEntry->voiceFile, "");
- weightedEntry->entryType = kWeightedReply;
- data = convS->readUint32LE();
- if (debugFlag) debugCN(kDebugConversations, "- Weight: %i ", data);
- weightedEntry->weight = data;
- replyEntry->totalWeight += weightedEntry->weight;
- data = convS->readUint32LE();
- if (debugFlag) debugCN(kDebugConversations, "offset: %i\n", data);
- replyEntry->entries.push_back(weightedEntry);
- }
- currentWeightedEntry = 0;
- } else {
- replyEntry->entryType = kReply;
- if (debugFlag) debugCN(kDebugConversations, "RPLY chunk\n");
- data = convS->readUint32LE();
- if (debugFlag) debugCN(kDebugConversations, "Reply data offset: %i\n", data);
- }
-
- if (!curEntry)
- error("Converse::loadConversation(): curEntry is NULL while adding a reply");
-
- curEntry->entries.push_back(replyEntry);
- setEntryInfo(replyEntry->offset, replyEntry->entryType,
- curNode, _convNodes[curNode]->entries.size() - 1);
- // Seek to chunk data (i.e. TEXT/MESG tag, which is usually right
- // after this chunk but it can be further on in conditional reply chunks
- assert((int)data >= convS->pos());
- // If the entry's data is not right after the entry, remember the position
- // to return to after the data is read
- if (chunk == CHUNK_CRPL && (int)data != convS->pos())
- returnAddress = convS->pos();
- convS->seek(data, SEEK_SET);
- }
- break;
- // ----------------------------------------------------------------------------
- case CHUNK_TEXT: // Text (contains text and voice)
- case CHUNK_MESG: // Message (contains voice only)
- {
- ConvEntry* parentEntry = NULL;
- if (chunk == CHUNK_TEXT) {
- if (debugFlag) debugCN(kDebugConversations, "TEXT chunk\n");
- } else {
- if (debugFlag) debugCN(kDebugConversations, "MESG chunk\n");
- }
-
- if (replyEntry == NULL) {
- parentEntry = curEntry;
- } else if (replyEntry != NULL && replyEntry->entryType != kWeightedReply) {
- parentEntry = replyEntry;
- } else if (replyEntry != NULL && replyEntry->entryType == kWeightedReply) {
- parentEntry = replyEntry->entries[currentWeightedEntry];
- currentWeightedEntry++;
- } else {
- error("Converse::loadConversation(): Unexpected reply entry while processing TEXT/MESG chunk");
- }
-
- size = convS->readUint32LE();
- if (debugFlag) debugCN(kDebugConversations, "Entry data size: %i\n", size);
- convS->read(buffer, 8);
- size -= 8; // subtract maximum length of voice file name
- // If the file name is 8 characters, it will not be 0-terminated, so use strncpy
- strncpy(parentEntry->voiceFile, buffer, 8);
- parentEntry->voiceFile[8] = '\0';
- if (debugFlag) debugCN(kDebugConversations, "Voice file: %s\n", parentEntry->voiceFile);
-
- if (chunk == CHUNK_TEXT) {
- convS->read(buffer, size);
- if (debugFlag) debugCN(kDebugConversations, "Text: %s\n", buffer);
- sprintf(parentEntry->text, "%s", buffer);
- } else {
- while (size > 0) {
- data = convS->readUint32LE();
- if (debugFlag) debugCN(kDebugConversations, "Unknown: %i\n", data); // TODO
- size -= 4;
- }
- }
- // Now that the data chunk has been read, if we skipped a reply node,
- // jump back to it
- if (returnAddress != -1) {
- convS->seek(returnAddress, SEEK_SET);
- returnAddress = -1;
- }
- }
- break;
- // ----------------------------------------------------------------------------
- // Entry action chunks
- case CHUNK_CASN: // Conditional assign
- case CHUNK_ASGN: { // Assign
- curAction = new EntryAction();
- if (debugFlag) debugCN(kDebugConversations, "ASGN chunk\n");
- curAction->actionType = kAssignValue;
-
- // Conditional part
- if (chunk == CHUNK_CASN) {
- curAction->isConditional = true;
- curAction->condition.offset = convS->readUint32LE();
- curAction->condition.op = convS->readUint32LE();
- curAction->condition.val = convS->readUint32LE();
- } else {
- curAction->isConditional = false;
- }
-
- curAction->targetOffset = convS->readUint32LE();
- int op = convS->readUint32LE();
- assert(op == kOpAssign);
- curAction->value = convS->readUint32LE();
- break;
- }
- case CHUNK_CCGO: // Conditional go to entry
- case CHUNK_CHDE: // Conditional hide entry
- case CHUNK_CUHD: // Conditional unhide entry
- case CHUNK_CDST: // Conditional destroy entry
- case CHUNK_CEGO: // Conditional exit conversation / go to
-
- case CHUNK_GOTO: // Go to entry
- case CHUNK_HIDE: // Hide entry
- case CHUNK_UHID: // Unhide entry
- case CHUNK_DSTR: // Destroy entry
- case CHUNK_EXIT: // Exit conversation
- curAction = new EntryAction();
-
- // Conditional part
- if (chunk == CHUNK_CCGO || chunk == CHUNK_CHDE || chunk == CHUNK_CUHD ||
- chunk == CHUNK_CDST || chunk == CHUNK_CEGO) {
- curAction->isConditional = true;
- curAction->condition.offset = convS->readUint32LE();
- curAction->condition.op = convS->readUint32LE();
- curAction->condition.val = convS->readUint32LE();
- } else {
- curAction->isConditional = false;
- }
-
- if (chunk == CHUNK_GOTO || chunk == CHUNK_CCGO) {
- curAction->actionType = kGotoEntry;
- if (debugFlag) debugCN(kDebugConversations, "GOTO chunk\n");
- } else if (chunk == CHUNK_HIDE || chunk == CHUNK_CHDE) {
- curAction->actionType = kHideEntry;
- if (debugFlag) debugCN(kDebugConversations, "HIDE chunk\n");
- } else if (chunk == CHUNK_UHID || chunk == CHUNK_CUHD) {
- curAction->actionType = kUnhideEntry;
- if (debugFlag) debugCN(kDebugConversations, "UHID chunk\n");
- } else if (chunk == CHUNK_DSTR || chunk == CHUNK_CDST) {
- curAction->actionType = kDestroyEntry;
- if (debugFlag) debugCN(kDebugConversations, "DSTR chunk\n");
- } else if (chunk == CHUNK_EXIT || chunk == CHUNK_CEGO) {
- curAction->actionType = kExitConv;
- if (debugFlag) debugCN(kDebugConversations, "EXIT chunk\n");
- }
- data = convS->readUint32LE();
- if (debugFlag) debugCN(kDebugConversations, "Offset: %i\n", data);
- curAction->targetOffset = data;
- curEntry->actions.push_back(curAction);
- break;
- case CHUNK_FALL: // Fallthrough
- if (debugFlag) debugCN(kDebugConversations, "FALL chunk\n");
- size = convS->readUint32LE();
- if (debugFlag) debugCN(kDebugConversations, "Minimum nodes: %i\n", size);
- _convNodes[curNode]->fallthroughMinEntries = size;
- data = convS->readUint32LE();
- if (debugFlag) debugCN(kDebugConversations, "Offset: %i\n", data);
- _convNodes[curNode]->fallthroughOffset = data;
- break;
- // ----------------------------------------------------------------------------
- default:
- // Should never happen
- error("Unknown conversation chunk");
- break;
- }
- }
-
- _vm->res()->toss(name);
-}
-
-void Converse::loadConversationMads(const char *convName) {
- char name[40];
- char buffer[256];
- char *buf;
- Common::SeekableReadStream *convS;
- int curPos = 0;
- int unk = 0;
- uint32 stringIndex = 0;
- uint32 stringCount = 0;
- int flags = 0;
- int count = 0;
- uint32 i, j;
- ConvEntry* curEntry = NULL;
- MessageEntry *curMessage;
- Common::Array<char *> messageList;
- // TODO
-
- // CND file
- sprintf(name, "%s.cnd", convName);
- MadsPack convDataD(name, _vm);
-
- // ------------------------------------------------------------
- // Chunk 0
- convS = convDataD.getItemStream(0);
- debugCN(kDebugConversations, "Chunk 0\n");
- debugCN(kDebugConversations, "Conv stream size: %i\n", convS->size());
-
- while (!convS->eos()) { // FIXME (eos changed)
- debugCN(kDebugConversations, "%i ", convS->readByte());
- }
- debugCN(kDebugConversations, "\n");
-
- // ------------------------------------------------------------
- // Chunk 1
- convS = convDataD.getItemStream(1);
- debugCN(kDebugConversations, "Chunk 1\n");
- debugCN(kDebugConversations, "Conv stream size: %i\n", convS->size());
-
- while (!convS->eos()) { // FIXME (eos changed)
- debugCN(kDebugConversations, "%i ", convS->readByte());
- }
- debugCN(kDebugConversations, "\n");
-
- // ------------------------------------------------------------
- // Chunk 2
- convS = convDataD.getItemStream(2);
- debugCN(kDebugConversations, "Chunk 2\n");
- debugCN(kDebugConversations, "Conv stream size: %i\n", convS->size());
-
- while (!convS->eos()) { // FIXME (eos changed)
- debugCN(kDebugConversations, "%i ", convS->readByte());
- }
- debugCN(kDebugConversations, "\n");
-
- // ------------------------------------------------------------
- // CNV file
- sprintf(name, "%s.cnv", convName);
- MadsPack convData(name, _vm);
- // *.cnv files have 7 chunks
- // Here is the chunk output of conv001.cnv (from the dump_file command)
- /*
- Dumping conv001.cnv, size: 3431
- Dumping compressed chunk 1 of 7, size is 150
- Dumping compressed chunk 2 of 7, size is 130
- Dumping compressed chunk 3 of 7, size is 224
- Dumping compressed chunk 4 of 7, size is 92
- Dumping compressed chunk 5 of 7, size is 168
- Dumping compressed chunk 6 of 7, size is 4064
- Dumping compressed chunk 7 of 7, size is 2334
- */
-
- // ------------------------------------------------------------
- // TODO: finish this
- // Chunk 0
- convS = convData.getItemStream(0);
- debugCN(kDebugConversations, "Chunk 0\n");
- debugCN(kDebugConversations, "Conv stream size: %i\n", convS->size());
- debugCN(kDebugConversations, "%i ", convS->readUint16LE());
- debugCN(kDebugConversations, "%i ", convS->readUint16LE());
- debugCN(kDebugConversations, "%i ", convS->readUint16LE());
- debugCN(kDebugConversations, "%i ", convS->readUint16LE());
- debugCN(kDebugConversations, "%i ", convS->readUint16LE());
- debugCN(kDebugConversations, "%i ", convS->readUint16LE());
- debugCN(kDebugConversations, "\n");
- count = convS->readUint16LE(); // conversation face count (usually 2)
- debugCN(kDebugConversations, "Conversation faces: %i\n", count);
- for (i = 0; i < 5; i++) {
- convS->read(buffer, 16);
- debugCN(kDebugConversations, "Face %i: %s ", i + 1, buffer);
- }
- debugCN(kDebugConversations, "\n");
-
- // 5 face slots
- // 1 = face slot has a face (with the filename specified above)
- // 0 = face slot doesn't contain face data
- for (i = 0; i < 5; i++) {
- debugCN(kDebugConversations, "%i ", convS->readUint16LE());
- }
- debugCN(kDebugConversations, "\n");
-
- convS->read(buffer, 14); // speech file
- debugCN(kDebugConversations, "Speech file: %s\n", buffer);
-
- while (!convS->eos()) { // FIXME: eos changed
- debugCN(kDebugConversations, "%i ", convS->readByte());
- }
- debugCN(kDebugConversations, "\n");
-
- delete convS;
-
- // ------------------------------------------------------------
- // Chunk 1: Conversation nodes
- convS = convData.getItemStream(1);
- debugCN(kDebugConversations, "Chunk 1: conversation nodes\n");
- debugCN(kDebugConversations, "Conv stream size: %i\n", convS->size());
-
- while (true) {
- uint16 id = convS->readUint16LE();
- if (convS->eos()) break;
-
- curEntry = new ConvEntry();
- curEntry->id = id;
- curEntry->entryCount = convS->readUint16LE();
- curEntry->flags = convS->readUint16LE();
- if (curEntry->entryCount == 1 && curEntry->flags != 65535) {
- warning("Entry count is 1 and flags is not 65535 (it's %i)", flags);
- } else if (curEntry->entryCount != 1 && flags != 0) {
- warning("Entry count > 1 and flags is not 0 (it's %i)", flags);
- }
- unk = convS->readUint16LE();
- assert (unk == 65535);
- unk = convS->readUint16LE();
- assert (unk == 65535);
- _convNodes.push_back(curEntry);
- debugCN(kDebugConversations, "Node %i, ID %i, entries %i\n", _convNodes.size(), curEntry->id, curEntry->entryCount);
- // flags = 0: node has more than 1 entry
- // flags = 65535: node has 1 entry
- }
- debugCN(kDebugConversations, "Conversation has %i nodes\n", _convNodes.size());
- debugCN(kDebugConversations, "\n");
-
- delete convS;
-
- // ------------------------------------------------------------
- // Chunk 4 contains the conversation string offsets of chunk 5
- // (unused, as it's unneeded - we find the offsets ourselves)
-
- // ------------------------------------------------------------
- // Chunk 5 contains the conversation strings
- convS = convData.getItemStream(5);
- //debugCN(kDebugConversations, "Chunk 5: conversation strings\n");
- //debugCN(kDebugConversations, "Conv stream size: %i\n", convS->size());
-
- *buffer = 0;
-
- while (true) {
- //if (curPos == 0)
- // debugCN(kDebugConversations, "%i: Offset %i: ", _convStrings.size(), convS->pos());
- uint8 b = convS->readByte();
- if (convS->eos()) break;
-
- buffer[curPos++] = b;
- if (buffer[curPos - 1] == '~') { // filter out special characters
- curPos--;
- continue;
- }
- if (buffer[curPos - 1] == '\0') {
- // end of string
- //debugCN(kDebugConversations, "%s\n", buffer);
- buf = new char[strlen(buffer) + 1];
- strcpy(buf, buffer);
- _convStrings.push_back(buf);
- curPos = 0;
- *buffer = 0;
- }
- }
-
- delete convS;
-
- // ------------------------------------------------------------
- // Chunk 2: entry data
- convS = convData.getItemStream(2);
- //debugCN(kDebugConversations, "Chunk 2 - entry data\n");
- //debugCN(kDebugConversations, "Conv stream size: %i\n", convS->size());
-
- for (i = 0; i < _convNodes.size(); i++) {
- for (j = 0; j < _convNodes[i]->entryCount; j++) {
- curEntry = new ConvEntry();
- stringIndex = convS->readUint16LE();
- if (stringIndex != 65535)
- sprintf(curEntry->text, "%s", _convStrings[stringIndex]);
- else
- *curEntry->text = 0;
- curEntry->id = convS->readUint16LE();
- curEntry->offset = convS->readUint16LE();
- curEntry->size = convS->readUint16LE();
-
- _convNodes[i]->entries.push_back(curEntry);
- //debugCN(kDebugConversations, "Node %i, entry %i, id %i, offset %i, size %i, text: %s\n",
- // i, j, curEntry->id, curEntry->offset, curEntry->size, curEntry->text);
- }
- }
-
- delete convS;
-
- // ------------------------------------------------------------
- // Chunk 3: message (MESG) chunks, created from the strings of chunk 5
- convS = convData.getItemStream(3);
- //debugCN(kDebugConversations, "Chunk 3 - MESG chunk data\n");
- //debugCN(kDebugConversations, "Conv stream size: %i\n", convS->size());
-
- while (true) {
- uint16 index = convS->readUint16LE();
- if (convS->eos()) break;
-
- curMessage = new MessageEntry();
- stringIndex = index;
- stringCount = convS->readUint16LE();
- *buffer = 0;
- //debugCN(kDebugConversations, "Message: %i\n", _madsMessageList.size());
- for (i = stringIndex; i < stringIndex + stringCount; i++) {
- //debugCN(kDebugConversations, "%i: %s\n", i, _convStrings[i]);
- curMessage->messageStrings.push_back(_convStrings[i]);
- }
- _madsMessageList.push_back(curMessage);
- //debugCN(kDebugConversations, "----------\n");
- }
- //debugCN(kDebugConversations, "\n");
-
- delete convS;
-
- // ------------------------------------------------------------
- // TODO: finish this
- // Chunk 6: conversation script
- convS = convData.getItemStream(6);
- debugCN(kDebugConversations, "Chunk 6\n");
- debugCN(kDebugConversations, "Conv stream size: %i\n", convS->size());
- /*while (!convS->eos()) { // FIXME (eos changed)
- debugCN(kDebugConversations, "%i ", convS->readByte());
- debugCN(kDebugConversations, "%i ", convS->readByte());
- debugCN(kDebugConversations, "%i ", convS->readByte());
- debugCN(kDebugConversations, "%i ", convS->readByte());
- debugCN(kDebugConversations, "%i ", convS->readByte());
- debugCN(kDebugConversations, "%i ", convS->readByte());
- debugCN(kDebugConversations, "%i ", convS->readByte());
- debugCN(kDebugConversations, "%i ", convS->readByte());
- debugCN(kDebugConversations, "%i ", convS->readByte());
- debugCN(kDebugConversations, "%i ", convS->readByte());
- debugCN(kDebugConversations, "\n");
- }
- return;*/
-
- for (i = 0; i < _convNodes.size(); i++) {
- for (j = 0; j < _convNodes[i]->entryCount; j++) {
- debugCN(kDebugConversations, "*** Node %i entry %i data size %i\n", i, j, _convNodes[i]->entries[j]->size);
- debugCN(kDebugConversations, "Entry ID %i, text %s\n", _convNodes[i]->entries[j]->id, _convNodes[i]->entries[j]->text);
- Common::ReadStream *entryStream = new Common::SubReadStream(convS, _convNodes[i]->entries[j]->size);
- readConvEntryActions(entryStream, _convNodes[i]->entries[j]);
- delete entryStream;
- debugCN(kDebugConversations, "--------------------\n");
- }
- }
-
- delete convS;
-}
-
-void Converse::readConvEntryActions(Common::ReadStream *convS, ConvEntry *curEntry) {
- uint8 chunk;
- uint8 type; // 255: normal, 11: conditional
- uint8 hasText1, hasText2;
- int target;
- int count = 0;
- int var, val;
- int messageIndex = 0;
- int unk = 0;
-
- while (true) {
- chunk = convS->readByte();
- if (convS->eos()) break;
-
- type = convS->readByte();
-
- switch (chunk) {
- case 1:
- debugCN(kDebugConversations, "TODO: chunk type %i\n", chunk);
- break;
- case 2:
- debugCN(kDebugConversations, "HIDE\n");
- convS->readByte();
- count = convS->readByte();
- debugCN(kDebugConversations, "%i entries: ", count);
- for (int i = 0; i < count; i++)
- debugCN(kDebugConversations, "%i %d", i, convS->readUint16LE());
- debugCN(kDebugConversations, "\n");
- break;
- case 3:
- debugCN(kDebugConversations, "UNHIDE\n");
- convS->readByte();
- count = convS->readByte();
- debugCN(kDebugConversations, "%i entries: ", count);
- for (int i = 0; i < count; i++)
- debugCN(kDebugConversations, "%i %d", i, convS->readUint16LE());
- debugCN(kDebugConversations, "\n");
- break;
- case 4: // MESSAGE
- debugCN(kDebugConversations, "MESSAGE\n");
-
- if (type == 255) {
- //debugCN(kDebugConversations, "unconditional\n");
- } else if (type == 11) {
- //debugCN(kDebugConversations, "conditional\n");
- } else {
- debugCN(kDebugConversations, "unknown type: %i\n", type);
- }
-
- // Conditional part
- if (type == 11) {
- unk = convS->readUint16LE(); // 1
- if (unk != 1)
- debugCN(kDebugConversations, "Message: unk != 1 (it's %i)\n", unk);
-
- var = convS->readUint16LE();
- val = convS->readUint16LE();
- debugCN(kDebugConversations, "Var %i == %i\n", var, val);
- }
- unk = convS->readUint16LE(); // 256
- if (unk != 256)
- debugCN(kDebugConversations, "Message: unk != 256 (it's %i)\n", unk);
-
- // it seems that the first text entry is set when the message
- // chunk is supposed to be shown unconditionally, whereas the second text
- // entry is set when the message is supposed to be shown conditionally
- hasText1 = convS->readByte();
- hasText2 = convS->readByte();
-
- if (hasText1 == 1) {
- messageIndex = convS->readUint16LE();
- debugCN(kDebugConversations, "Message 1 index: %i, text:\n", messageIndex);
- for (uint32 i = 0; i < _madsMessageList[messageIndex]->messageStrings.size(); i++) {
- debugCN(kDebugConversations, "%s\n", _madsMessageList[messageIndex]->messageStrings[i]);
- }
- }
-
- if (hasText2 == 1) {
- messageIndex = convS->readUint16LE();
- if (hasText1 == 0) {
- debugCN(kDebugConversations, "Message 2 index: %i, text:\n", messageIndex);
- for (uint32 i = 0; i < _madsMessageList[messageIndex]->messageStrings.size(); i++) {
- debugCN(kDebugConversations, "%s\n", _madsMessageList[messageIndex]->messageStrings[i]);
- }
- }
- }
-
- break;
- case 5: // AUTO
- debugCN(kDebugConversations, "AUTO\n");
- for (int k = 0; k < 4; k++)
- convS->readByte();
- messageIndex = convS->readUint16LE();
- debugCN(kDebugConversations, "Message index: %i, text:\n", messageIndex);
- for (uint32 i = 0; i < _madsMessageList[messageIndex]->messageStrings.size(); i++) {
- debugCN(kDebugConversations, "%s\n", _madsMessageList[messageIndex]->messageStrings[i]);
- }
-
- convS->readUint16LE();
- break;
- case 6:
- debugCN(kDebugConversations, "TODO: chunk type %i\n", chunk);
- break;
- case 7: // GOTO
- unk = convS->readUint32LE(); // 0
- if (unk != 0 && unk != 1)
- debugCN(kDebugConversations, "Goto: unk != 0 or 1 (it's %i)\n", unk);
-
- target = convS->readUint16LE();
- convS->readUint16LE(); // 255
-
- if (unk != 0)
- debugCN(kDebugConversations, "Goto: unk != 0 (it's %i)\n", unk);
-
- if (target != 65535)
- debugCN(kDebugConversations, "GOTO node %i\n", target);
- else
- debugCN(kDebugConversations, "GOTO exit\n");
- break;
- case 8:
- debugCN(kDebugConversations, "TODO: chunk type %i\n", chunk);
- break;
- case 9: // ASSIGN
- //debugCN(kDebugConversations, "ASSIGN\n");
- unk = convS->readUint32LE(); // 0
-
- if (unk != 0)
- debugCN(kDebugConversations, "Assign: unk != 0 (it's %i)\n", unk);
-
- val = convS->readUint16LE();
- var = convS->readUint16LE();
- //debugCN(kDebugConversations, "Var %i = %i\n", var, val);
- break;
- default:
- debugCN(kDebugConversations, "Unknown chunk type! (%i)\n", chunk);
- break;
- }
- }
- debugCN(kDebugConversations, "\n");
-}
-
-void Converse::setEntryInfo(int32 offset, EntryType type, int32 nodeIndex, int32 entryIndex) {
- char hashOffset[10];
- sprintf(hashOffset, "%i", offset);
- EntryInfo info;
- info.targetType = type;
- info.nodeIndex = nodeIndex;
- info.entryIndex = entryIndex;
- _offsetMap[hashOffset] = info;
- //debugCN(kDebugConversations, "Set entry info: offset %i, type %i, node %i, entry %i\n", offset, type, nodeIndex, entryIndex);
-}
-
-const EntryInfo* Converse::getEntryInfo(int32 offset) {
- char hashOffset[10];
- sprintf(hashOffset, "%i", offset);
- OffsetHashMap::const_iterator entry = _offsetMap.find(hashOffset);
- if (entry != _offsetMap.end())
- return &(entry->_value);
- else
- error("Undeclared entry offset: %i", offset);
-}
-
-void Converse::setValue(int32 offset, int32 value) {
- char hashOffset[10];
- sprintf(hashOffset, "%i", offset);
- _variables[hashOffset] = value;
-}
-
-int32 Converse::getValue(int32 offset) {
- char hashOffset[10];
- sprintf(hashOffset, "%i", offset);
- ConvVarHashMap::const_iterator entry = _variables.find(hashOffset);
- if (entry != _variables.end())
- return entry->_value;
- else
- error("Undeclared variable offset: %i", offset);
-}
-
-bool Converse::evaluateCondition(int32 leftVal, int32 op, int32 rightVal) {
- switch (op) {
- case kOpPercent:
- return (leftVal % rightVal == 0);
- case kOpGreaterOrEqual:
- return leftVal >= rightVal;
- case kOpLessOrEqual:
- return leftVal <= rightVal;
- case kOpGreaterThan:
- return leftVal > rightVal;
- case kOpLessThan:
- return leftVal < rightVal;
- case kOpNotEqual:
- case kOpCondNotEqual:
- return leftVal != rightVal;
- case kOpAssign:
- return leftVal == rightVal;
- case kOpAnd:
- return leftVal && rightVal;
- case kOpOr:
- return leftVal || rightVal;
- default:
- error("Unknown conditional operator: %i", op);
- }
-}
-
-bool Converse::performAction(EntryAction *action) {
- if (action->isConditional) {
- if (!evaluateCondition(getValue(action->condition.offset),
- action->condition.op, action->condition.val))
- return true; // don't perform this action
- }
-
- if (action->actionType == kAssignValue) {
- //debugCN(kDebugConversations, "Assigning variable at offset %i to value %i\n",
- // action->targetOffset, action->value);
- setValue(action->targetOffset, action->value);
- return true; // nothing else to do in an assignment action
- }
-
- const EntryInfo *entryInfo = getEntryInfo(action->targetOffset);
- ConvEntry *targetEntry;
-
- if (entryInfo->nodeIndex >= 0 && entryInfo->entryIndex >= 0)
- targetEntry = getNode(entryInfo->nodeIndex)->entries[entryInfo->entryIndex];
- else if (entryInfo->nodeIndex >= 0)
- targetEntry = getNode(entryInfo->nodeIndex);
- else
- error("Target node id is negative");
-
- switch (action->actionType) {
- case kGotoEntry:
- //debugCN(kDebugConversations, "Goto entry at offset %i. Associated node is %i, entry %i\n",
- // action->targetOffset, entryInfo->nodeIndex, entryInfo->entryIndex);
- _vm->_conversationView->setNode(entryInfo->nodeIndex);
- if (entryInfo->entryIndex >= 0)
- _vm->_conversationView->selectEntry(entryInfo->entryIndex);
- return false;
- case kHideEntry:
- //debugCN(kDebugConversations, "Hide entry at offset %i. Associated node is %i, entry %i\n",
- // targetEntry->offset, entryInfo->nodeIndex, entryInfo->entryIndex);
- targetEntry->visible = false;
- return true;
- case kUnhideEntry:
- //debugCN(kDebugConversations, "Show entry at offset %i. Associated node is %i, entry %i\n",
- // targetEntry->offset, entryInfo->nodeIndex, entryInfo->entryIndex);
- targetEntry->visible = true;
- return true;
- case kDestroyEntry:
- //debugCN(kDebugConversations, "Destroy entry at offset %i. Associated node is %i, entry %i\n",
- // targetEntry->offset, entryInfo->nodeIndex, entryInfo->entryIndex);
- if (entryInfo->entryIndex >= 0)
- getNode(entryInfo->nodeIndex)->entries.remove_at(entryInfo->entryIndex);
- else
- warning("Target entry is a node, not destroying it");
- targetEntry->visible = true;
- return true;
- case kExitConv:
- //debugCN(kDebugConversations, "Exit conversation\n");
- endConversation();
- return false;
- default:
- warning("Unknown entry action");
- return false;
- } // end switch
-}
-
-/*--------------------------------------------------------------------------*/
-
-MadsConversation::MadsConversation() {
- for (int i = 0; i < MADS_TALK_SIZE; ++i) {
- _talkList[i].desc = NULL;
- _talkList[i].id = 0;
- }
-}
-
-
-} // End of namespace M4
diff --git a/engines/m4/converse.h b/engines/m4/converse.h
deleted file mode 100644
index b47e8d2a6b..0000000000
--- a/engines/m4/converse.h
+++ /dev/null
@@ -1,214 +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 M4_CONVERSE_H
-#define M4_CONVERSE_H
-
-#include "common/array.h"
-#include "common/hashmap.h"
-
-#include "m4/globals.h"
-#include "m4/viewmgr.h"
-#include "m4/sound.h"
-
-namespace M4 {
-
-enum ConversationState {
- kConversationOptionsShown = 0,
- kEntryIsActive = 1,
- kReplyIsActive = 2,
- kNoConversation = 3
-};
-
-enum EntryType {
- kVariable = 0,
- kNode = 1,
- kLinearNode = 2,
- kEntry = 3,
- kReply = 4,
- kWeightedReply = 5
-};
-
-// Flags are:
-// bit 0: if it's 1, the entry is "initial", i.e. not hidden when the dialog starts
-// bit 1: if it's 1, the entry persists if selected
-enum EntryFlags {
- kEntryInitial = 1, // byte 0
- kEntryPersists = 2 // byte 1
-};
-
-enum EntryActionType {
- kUnknownAction = 0,
- kGotoEntry = 1,
- kHideEntry = 2,
- kUnhideEntry = 3,
- kDestroyEntry = 4,
- kAssignValue = 5,
- kExitConv = 6
-};
-
-enum LogicOp {
- kOpPercent = 405,
- kOpGreaterOrEqual = 421,
- kOpLessOrEqual = 420,
- kOpGreaterThan = 413,
- kOpLessThan = 412,
- kOpNotEqual = 422,
- kOpCondNotEqual = 448,
- kOpAssign = 407,
- kOpAnd = 444,
- kOpOr = 445
-};
-
-struct Condition {
- int32 offset;
- int32 op;
- int32 val;
-};
-
-struct EntryAction {
- int32 targetOffset; // absolute offset (inside the *.chk file) of the action's target
- int32 value; // the value set by assignment chunks
- EntryActionType actionType;
- EntryType targetType;
- int32 nodeId;
- int32 entryId;
- bool isConditional;
- Condition condition;
-};
-
-struct ConvEntry {
- EntryType entryType;
- int32 id;
- int32 offset; // absolute offset inside the *.chk file, referenced by other chunks
- int32 size; // entry action data size (for MADS games)
- int32 flags;
- int32 fallthroughMinEntries;
- int32 fallthroughOffset;
- int32 weight; // weight for weighted replies
- int32 totalWeight;
- uint16 entryCount; // entries inside this node (for MADS games)
- char voiceFile[10];
- char text[512];
- bool autoSelect;
- bool visible;
- bool isConditional;
- Condition condition;
- Common::Array<EntryAction*>actions;
- Common::Array<ConvEntry*>entries;
-};
-
-struct EntryInfo {
- EntryType targetType;
- int32 nodeIndex;
- int32 entryIndex;
-};
-
-struct MessageEntry {
- Common::Array<char*>messageStrings;
-};
-
-enum ConverseStyle {CONVSTYLE_EARTH, CONVSTYLE_SPACE};
-
-typedef Common::HashMap<Common::String,EntryInfo,Common::IgnoreCase_Hash,Common::IgnoreCase_EqualTo> OffsetHashMap;
-typedef Common::HashMap<Common::String,int32,Common::IgnoreCase_Hash,Common::IgnoreCase_EqualTo> ConvVarHashMap;
-
-class ConversationView : public View {
-public:
- ConversationView(MadsM4Engine *vm);
- ~ConversationView();
- void setNode(int32 nodeIndex);
-
- void onRefresh(RectList *rects, M4Surface *destSurface);
- bool onEvent(M4EventType eventType, int32 param, int x, int y, bool &captureEvents);
- int32 getCurrentNodeIndex() { return _currentNodeIndex; }
- void selectEntry(int entryIndex);
-
-private:
- void updateState();
- void playNextReply();
-
- int32 _currentNodeIndex;
- Common::Array<ConvEntry *> _activeItems;
- int _highlightedIndex;
- int _xEnd;
- bool _entriesShown;
- ConversationState _conversationState;
- SndHandle *_currentHandle;
-};
-
-class Converse {
-
-public:
- Converse(MadsM4Engine *vm) : _vm(vm) {}
- ~Converse() {}
-
- void startConversation(const char *convName, bool showConversebox = true, ConverseStyle style = CONVSTYLE_EARTH );
- void endConversation();
- const EntryInfo* getEntryInfo(int32 offset);
- ConvEntry *getNode(int32 index) { return _convNodes[index]; }
-
- void setValue(int32 offset, int32 value);
- int32 getValue(int32 offset);
- bool evaluateCondition(int32 leftVal, int32 op, int32 rightVal);
- bool performAction(EntryAction *action);
- /*
- void resume() { play(); }
- void play();
- */
-private:
- MadsM4Engine *_vm;
- Common::Array<ConvEntry*>_convNodes;
- Common::Array<MessageEntry*>_madsMessageList;
- Common::Array<char *>_convStrings;
- bool _playerCommandsAllowed;
- bool _interfaceWasVisible;
- ConverseStyle _style;
- OffsetHashMap _offsetMap;
- ConvVarHashMap _variables;
-
- void loadConversation(const char *convName);
- void loadConversationMads(const char *convName);
- void readConvEntryActions(Common::ReadStream *convS, ConvEntry *curEntry);
- void setEntryInfo(int32 offset, EntryType type, int32 nodeIndex, int32 entryIndex);
-};
-
-
-struct MadsTalkEntry {
- uint16 id;
- const char *desc;
-};
-
-#define MADS_TALK_SIZE 5
-
-class MadsConversation {
-private:
- MadsTalkEntry _talkList[MADS_TALK_SIZE];
-public:
- MadsConversation();
-
- MadsTalkEntry &operator[](int index) { return _talkList[index]; }
-};
-
-} // End of namespace M4
-
-#endif
diff --git a/engines/m4/detection.cpp b/engines/m4/detection.cpp
deleted file mode 100644
index 58a5db6c89..0000000000
--- a/engines/m4/detection.cpp
+++ /dev/null
@@ -1,419 +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 "base/plugins.h"
-
-#include "engines/advancedDetector.h"
-
-#include "m4/m4.h"
-#include "m4/resource.h"
-
-namespace M4 {
-
-struct M4GameDescription {
- ADGameDescription desc;
-
- int gameType;
- uint32 features;
-};
-
-int MadsM4Engine::getGameType() const { return _gameDescription->gameType; }
-uint32 MadsM4Engine::getFeatures() const { return _gameDescription->features; }
-Common::Language MadsM4Engine::getLanguage() const { return _gameDescription->desc.language; }
-Common::Platform MadsM4Engine::getPlatform() const { return _gameDescription->desc.platform; }
-
-} // End of namespace M4
-
-static const PlainGameDescriptor m4Games[] = {
- {"m4", "MADS/M4 engine game"},
- {"riddle", "Ripley's Believe It or Not!: The Riddle of Master Lu"},
- {"burger", "Orion Burger"},
- {"rex", "Rex Nebular and the Cosmic Gender Bender"},
- {"dragon", "DragonSphere"},
- {"dragoncd", "DragonSphere CD"},
- {"phantom", "Return of the Phantom"},
- {"phantomcd", "Return of the Phantom CD"},
- {0, 0}
-};
-
-namespace M4 {
-
-const char *MadsM4Engine::getGameFile(int fileType) {
- for (int i = 0; _gameDescription->desc.filesDescriptions[i].fileName; i++) {
- if (_gameDescription->desc.filesDescriptions[i].fileType == fileType)
- return _gameDescription->desc.filesDescriptions[i].fileName;
- }
- return NULL;
-}
-
-static const M4GameDescription gameDescriptions[] = {
- {
- {
- "burger",
- "",
- {
- { "burger.has", kFileTypeHash, "10c8064e9c771072122f50737ac97245", 730771},
- { NULL, 0, NULL, 0}
- },
- Common::EN_ANY,
- Common::kPlatformPC,
- ADGF_UNSTABLE,
- GUIO1(GUIO_NONE)
- },
- GType_Burger,
- kFeaturesCD
- },
- {
- {
- "burger",
- "",
- {
- { "burger.has", kFileTypeHash, "55be8693a4c36e7efcdca0f0c77758ae", 724191},
- { NULL, 0, NULL, 0}
- },
- Common::DE_DEU,
- Common::kPlatformPC,
- ADGF_UNSTABLE,
- GUIO1(GUIO_NONE)
- },
- GType_Burger,
- kFeaturesCD
- },
- {
- {
- "burger",
- "",
- {
- { "burger.has", kFileTypeHash, "795c98a74e351ec437a396bb29897daf", 730771},
- { NULL, 0, NULL, 0}
- },
- Common::RU_RUS,
- Common::kPlatformPC,
- ADGF_UNSTABLE,
- GUIO1(GUIO_NONE)
- },
- GType_Burger,
- kFeaturesCD
- },
- {
- {
- "burger",
- "Demo",
- {
- { "burger.has", kFileTypeHash, "fc3f363b6153240a448bd3b7be9318da", 62159},
- { NULL, 0, NULL, 0}
- },
- Common::EN_ANY,
- Common::kPlatformPC,
- ADGF_DEMO | ADGF_UNSTABLE,
- GUIO1(GUIO_NONE)
- },
- GType_Burger,
- kFeaturesDemo
- },
- {
- {
- "burger",
- "Demo",
- {
- { "overview.has", kFileTypeHash, "57aa43a3ef88a934a43e9b1890ef5e17", 10519},
- { NULL, 0, NULL, 0}
- },
- Common::EN_ANY,
- Common::kPlatformPC,
- ADGF_DEMO | ADGF_UNSTABLE,
- GUIO1(GUIO_NONE)
- },
- GType_Burger,
- kFeaturesDemo
- },
- {
- {
- "riddle",
- "",
- {
- { "ripley.has", kFileTypeHash, "056d517360c89eb4c297a319f21a7071", 700469},
- { NULL, 0, NULL, 0}
- },
- Common::EN_ANY,
- Common::kPlatformPC,
- ADGF_UNSTABLE,
- GUIO1(GUIO_NONE)
- },
- GType_Riddle,
- kFeaturesCD
- },
- {
- {
- "riddle",
- "",
- {
- { "ripley.has", kFileTypeHash, "d073582c9011d44dd0d7e2ede317a86d", 700469},
- { NULL, 0, NULL, 0}
- },
- Common::EN_ANY,
- Common::kPlatformPC,
- ADGF_UNSTABLE,
- GUIO1(GUIO_NONE)
- },
- GType_Riddle,
- kFeaturesCD
- },
- {
- {
- "riddle",
- "",
- {
- { "ripley.has", kFileTypeHash, "d9e9f8befec432a047b1047fb2bc7aea", 710997},
- { NULL, 0, NULL, 0}
- },
- Common::DE_DEU,
- Common::kPlatformPC,
- ADGF_UNSTABLE,
- GUIO1(GUIO_NONE)
- },
- GType_Riddle,
- kFeaturesCD
- },
- {
- {
- "riddle",
- "",
- {
- { "ripley.has", kFileTypeHash, "3d48c5700785d11e6a5bc832b95be918", 701973},
- { NULL, 0, NULL, 0}
- },
- Common::FR_FRA,
- Common::kPlatformPC,
- ADGF_UNSTABLE,
- GUIO1(GUIO_NONE)
- },
- GType_Riddle,
- kFeaturesCD
- },
- {
- {
- "riddle",
- "",
- {
- { "ripley.has", kFileTypeHash, "5ee011cff7178dae3ddf6f9b7d4102ac", 701691},
- { NULL, 0, NULL, 0}
- },
- Common::ES_ESP,
- Common::kPlatformPC,
- ADGF_UNSTABLE,
- GUIO1(GUIO_NONE)
- },
- GType_Riddle,
- kFeaturesCD
- },
- { // Demo
- {
- "riddle",
- "Demo",
- {
- { "ripley.has", kFileTypeHash, "3a90dd7052860b6e246ec7e0aaf202f6", 104527},
- { NULL, 0, NULL, 0}
- },
- Common::EN_ANY,
- Common::kPlatformPC,
- ADGF_DEMO | ADGF_UNSTABLE,
- GUIO1(GUIO_NONE)
- },
- GType_Riddle,
- kFeaturesDemo
- },
- {
- {
- "rex",
- "",
- {
- { "global.hag", kFileTypeHAG, "0530cbeee109fc79cc24421128dea1ce", 2083078},
- { NULL, 0, NULL, 0}
- },
- Common::EN_ANY,
- Common::kPlatformPC,
- ADGF_UNSTABLE,
- GUIO1(GUIO_NOSPEECH)
- },
- GType_RexNebular,
- kFeaturesNone
- },
- { // Demo
- {
- "rex",
- "Demo",
- {
- { "global.hag", kFileTypeHAG, "d5a481d14bc1bda66e46965a39badcc7", 220429},
- { NULL, 0, NULL, 0}
- },
- Common::EN_ANY,
- Common::kPlatformPC,
- ADGF_DEMO | ADGF_UNSTABLE,
- GUIO1(GUIO_NONE)
- },
- GType_RexNebular,
- kFeaturesDemo
- },
- {
- {
- "dragon",
- "",
- {
- { "global.hag", kFileTypeHAG, "c3a6877665e7f21bf3d2b1e667155562", 2320567},
- { NULL, 0, NULL, 0}
- },
- Common::EN_ANY,
- Common::kPlatformPC,
- ADGF_UNSTABLE,
- GUIO1(GUIO_NOSPEECH)
- },
- GType_DragonSphere,
- kFeaturesNone
- },
- { // CD version
- {
- "dragoncd",
- "",
- {
- { "global.hag", kFileTypeHAG, "c3a6877665e7f21bf3d2b1e667155562", 2320567},
- { "speech.hag", kFileTypeHAG, NULL, -1},
- { NULL, 0, NULL, 0}
- },
- Common::EN_ANY,
- Common::kPlatformPC,
- ADGF_UNSTABLE,
- GUIO1(GUIO_NONE)
- },
- GType_DragonSphere,
- kFeaturesCD
- },
- { // Demo
- {
- "dragon",
- "Demo",
- {
- { "global.hag", kFileTypeHAG, "541e12d8e9aad0c65d65f150de47582e", 212718},
- { NULL, 0, NULL, 0}
- },
- Common::EN_ANY,
- Common::kPlatformPC,
- ADGF_DEMO | ADGF_UNSTABLE,
- GUIO1(GUIO_NONE)
- },
- GType_DragonSphere,
- kFeaturesDemo
- },
- {
- {
- "phantom",
- "",
- {
- { "global.hag", kFileTypeHAG, "bdce9ca93a015f0883d1bc0fabd0cdfa", 812150},
- { NULL, 0, NULL, 0}
- },
- Common::EN_ANY,
- Common::kPlatformPC,
- ADGF_UNSTABLE,
- GUIO1(GUIO_NOSPEECH)
- },
- GType_Phantom,
- kFeaturesNone
- },
- { // CD version
- {
- "phantomcd",
- "",
- {
- { "global.hag", kFileTypeHAG, "8a51c984eb4c64e8b30a7e6670f6bddb", 101154000},
- { NULL, 0, NULL, 0}
- },
- Common::EN_ANY,
- Common::kPlatformPC,
- ADGF_UNSTABLE,
- GUIO1(GUIO_NONE)
- },
- GType_Phantom,
- kFeaturesCD
- },
- { // CD version
- {
- "phantom",
- "Demo",
- {
- { "global.hag", kFileTypeHAG, "e810adbc6fac77ac2fec841a9ec5e20e", 115266},
- { NULL, 0, NULL, 0}
- },
- Common::EN_ANY,
- Common::kPlatformPC,
- ADGF_DEMO | ADGF_UNSTABLE,
- GUIO1(GUIO_NONE)
- },
- GType_Phantom,
- kFeaturesDemo
- },
- { AD_TABLE_END_MARKER, 0, 0 }
-};
-
-} // End of namespace M4
-
-static const char *directoryGlobs[] = {
- "option1",
- 0
-};
-
-class M4MetaEngine : public AdvancedMetaEngine {
-public:
- M4MetaEngine() : AdvancedMetaEngine(M4::gameDescriptions, sizeof(M4::M4GameDescription), m4Games) {
- _singleid = "m4";
- _guioptions = GUIO1(GUIO_NOMIDI);
- _maxScanDepth = 2;
- _directoryGlobs = directoryGlobs;
- }
-
- virtual const char *getName() const {
- return "MADS/M4";
- }
-
- virtual const char *getOriginalCopyright() const {
- return "Riddle of Master Lu & Orion Burger (C) Sanctuary Woods";
- }
-
- virtual bool createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const;
-};
-
-bool M4MetaEngine::createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const {
- const M4::M4GameDescription *gd = (const M4::M4GameDescription *)desc;
- if (gd) {
- if ((gd->gameType == M4::GType_Burger) || (gd->gameType == M4::GType_Riddle))
- *engine = new M4::M4Engine(syst, gd);
- else
- *engine = new M4::MadsEngine(syst, gd);
- }
- return gd != 0;
-}
-
-#if PLUGIN_ENABLED_DYNAMIC(M4)
- REGISTER_PLUGIN_DYNAMIC(M4, PLUGIN_TYPE_ENGINE, M4MetaEngine);
-#else
- REGISTER_PLUGIN_STATIC(M4, PLUGIN_TYPE_ENGINE, M4MetaEngine);
-#endif
diff --git a/engines/m4/dialogs.cpp b/engines/m4/dialogs.cpp
deleted file mode 100644
index 2b2c479673..0000000000
--- a/engines/m4/dialogs.cpp
+++ /dev/null
@@ -1,560 +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 "m4/dialogs.h"
-#include "common/file.h"
-#include "common/textconsole.h"
-
-namespace M4 {
-
-static void strToUpper(char *s) {
- while (*s) {
- *s = toupper(*s);
- ++s;
- }
-}
-
-static void strToLower(char *s) {
- while (*s) {
- *s = tolower(*s);
- ++s;
- }
-}
-
-const RGB8 DIALOG_PALETTE[8] = {
- {0x80, 0x80, 0x80}, {0x90, 0x90, 0x90}, {0x70, 0x70, 0x70}, {0x9c, 0x9c, 0x9c},
- {0x80, 0x80, 0x80}, {0x90, 0x90, 0x90}, {0xDC, 0xDC, 0xDC}, {0x00, 0x00, 0x00}
-};
-
-#define ROR16(v,amt) (((uint16)(v) >> amt) | ((uint16)(v) << (16 - amt)))
-
-const int DIALOG_SPACING = 1;
-
-/**
- * Handles any dialog initialisation
- */
-void Dialog::initDialog() {
- incLine();
-}
-
-/**
- * Adds a new line to the dialog output
- */
-void Dialog::incLine() {
- _lineX = 0;
- _widthX = 0;
-
- _lines.push_back(*new DialogLine());
- assert(_lines.size() <= 20);
-}
-
-/**
- * Writes some text to the dialog output, taking care of word wrapping if the text size
- * exceeds the dialog's width
- */
-void Dialog::writeChars(const char *srcLine) {
- char wordStr[80];
- char line[80];
- int lineLen, lineWidth;
- const char *srcP = srcLine;
-
- while (*srcP) {
- bool wordEndedP = false, newlineP = false;
- char *destP = &wordStr[0];
- Common::set_to(&wordStr[0], &wordStr[80], 0);
-
- // Try and get the next word
- for (;;) {
- char v = *srcP;
- *destP++ = v;
-
- if (v == '\0') break;
- if (v == '\n') {
- newlineP = true;
- ++srcP;
- --destP;
- break;
- }
-
- if (v == ' ') {
- // Word separator
- ++srcP;
- --destP;
- wordEndedP = true;
- } else {
- // Standard character
- if (!wordEndedP)
- // Still in the initial word
- ++srcP;
- else {
- // First character of next word, so time to break
- --destP;
- break;
- }
- }
- }
-
- if (destP < &wordStr[0])
- destP = &wordStr[0];
- *destP = '\0';
-
- lineLen = strlen(wordStr);
-
- strcpy(line, "");
- if (_lineX > 0)
- strcat(line, " ");
- strcat(line, wordStr);
-
- lineLen = strlen(line);
- lineWidth = _vm->_font->current()->getWidth(line, DIALOG_SPACING);
-
- if (((_lineX + lineLen) > _widthChars) || ((_widthX + lineWidth) > _dialogWidth)) {
- incLine();
- appendText(wordStr);
- } else {
- appendText(line);
- }
-
- if (newlineP)
- incLine();
- }
-}
-
-/**
- * Appends some text to the current dialog line
- */
-void Dialog::appendText(const char *line) {
- _lineX += strlen(line);
- _widthX += _vm->_font->current()->getWidth(line, DIALOG_SPACING);
-
- strcat(_lines[_lines.size() - 1].data, line);
-}
-
-/**
- * Adds a line of text to the dialog lines list
- */
-void Dialog::addLine(const char *line, bool underlineP) {
- if ((_widthX > 0) || (_lineX > 0))
- incLine();
-
- int lineWidth = _vm->_font->current()->getWidth(line, DIALOG_SPACING);
- int lineLen = strlen(line);
-
- if ((lineWidth > _dialogWidth) || (lineLen >= _widthChars))
- writeChars(line);
- else {
- _lines[_lines.size() - 1].xp = (_dialogWidth - 10 - lineWidth) / 2;
- strcpy(_lines[_lines.size() - 1].data, line);
- }
-
- if (underlineP)
- _lines[_lines.size() - 1].underline = true;
-
- incLine();
-}
-
-/**
- * Adds a bar separation line to the dialog lines list
- */
-void Dialog::addBarLine() {
- if ((_widthX > 0) || (_lineX > 0))
- incLine();
-
- // Flag the line as being a bar separator
- _lines[_lines.size() - 1].barLine = true;
- incLine();
-}
-
-/**
- * Retrieves a specified vocab entry
- */
-void Dialog::getVocab(int vocabId, char **line) {
- assert(vocabId > 0);
- const char *vocabStr = _madsVm->globals()->getVocab(vocabId);
- strcpy(*line, vocabStr);
-
- if (_commandCase)
- strToUpper(*line);
- else
- strToLower(*line);
-
- // Move the string pointer to after the added string
- while (!**line)
- ++*line;
-}
-
-bool Dialog::handleNounSuffix(char *destP, int nounNum, const char *srcP) {
- char srcLine[40];
-
- // The next source character must be a colon in front of the first verb
- if (*srcP != ':')
- return false;
-
- // Copy the remainder of the line into a temporary buffer to get the seperate verbs
- strcpy(srcLine, ++srcP);
- char *altP = strchr(srcLine, ':');
- if (altP)
- *altP = '\0';
-
- if (*srcP != '\0') {
- while (*srcP != ':') {
- ++srcP;
- if (!*srcP) break;
- }
- }
-
- if (*srcP != '\0')
- ++srcP;
-
- //
- char var_FC[40];
- char tempLine[40];
- strcpy(var_FC, srcP);
- char *tmpP = &tempLine[0];
- char *tmp2P = tmpP;
-
- uint16 _vocabIds[2] = {1, 1}; // FIXME/TODO: Proper vocab ids
- getVocab(_vocabIds[nounNum], &tmpP);
-
- if ((*(tmpP - 1) != 'S') && (*(tmpP - 1) != 's')) {
- // Singular object
- tmpP = &var_FC[0];
- } else if (!strcmp(tempLine, "a ")) {
- // Pontially plural
- char ch = tolower(*tmp2P);
-
- if (!((ch > 'U') || ((ch != 'A') && (ch != 'E') && (ch != 'I') && (ch != 'O'))))
- strcpy(tempLine, "an ");
- }
-
- strcpy(destP, tmpP);
- return true;
-}
-
-/**
- * Sets up an area within the dialog for textual input
- */
-void Dialog::setupInputArea() {
- _askPosition.x = _lineX + 1;
- _askPosition.y = _lines.size();
-
- incLine();
-}
-
-/**
- * Checks whether the start of an extracted command matches a specified given command constant
- */
-bool Dialog::matchCommand(const char *s1, const char *s2) {
- bool result = scumm_strnicmp(s1, s2, strlen(s2)) == 0;
- _commandCase = isupper(static_cast<unsigned char>(*s1));
- return result;
-}
-
-Dialog::Dialog(MadsM4Engine *vm, const char *msgData, const char *title): View(vm, Common::Rect(0, 0, 0, 0)) {
- assert(msgData);
- _vm->_font->setFont(FONT_INTERFACE_MADS);
-
- const char *srcP = msgData;
- bool skipLine = false;
- bool initFlag = false;
- bool cmdFlag = false;
- bool crFlag = false;
- bool underline = false;
-
- _screenType = LAYER_DIALOG;
- _widthChars = 0;
- _dialogIndex = 0;
- _askPosition.x = 0;
- _askPosition.y = 0;
- _lineX = 0;
- _widthX = 0;
- _dialogWidth = 0;
- _commandCase = false;
-
- char dialogLine[256];
- char cmdText[80];
- char *lineP = &dialogLine[0];
- char *cmdP = NULL;
-
- while (srcP && *(srcP - 1) != '\0') {
- if ((*srcP == '\n') || (*srcP == '\0')) {
- // Line completed
- *lineP = '\0';
- ++srcP;
-
- if (!initFlag) {
- initDialog();
- initFlag = true;
- }
-
- if (!skipLine)
- writeChars(dialogLine);
- else {
- addLine(dialogLine, underline);
-
- if (crFlag)
- incLine();
- }
-
- // Clear the current line contents
- dialogLine[0] = '\0';
- lineP = &dialogLine[0];
- skipLine = crFlag = underline = false;
- continue;
-
- } else if (*srcP == '[') {
- // Start of a command sequence
- cmdFlag = true;
- cmdP = &cmdText[0];
- ++srcP;
- continue;
- } else if (*srcP == ']') {
- // End of a command sequence
- *cmdP = '\0';
- cmdFlag = false;
- strToUpper(cmdText);
-
- if (matchCommand(cmdText, "ASK")) {
- setupInputArea();
-
- } else if (matchCommand(cmdText, "BAR")) {
- // Adds a full-width line instead of normal text
- addBarLine();
-
- } else if (matchCommand(cmdText, "CENTER")) {
- // Center command
- skipLine = true;
-
- } else if (matchCommand(cmdText, "CR")) {
- // CR command
- if (skipLine)
- crFlag = true;
- else if (!initFlag) {
- initDialog();
- initFlag = true;
- }
-
- } else if (matchCommand(cmdText, "NOUN1")) {
- // Noun command 1
- handleNounSuffix(lineP, 1, cmdText + 5);
-
- } else if (matchCommand(cmdText, "NOUN2")) {
- // Noun command 2
- handleNounSuffix(lineP, 2, cmdText + 5);
-
- } else if (matchCommand(cmdText, "SENTENCE")) {
- // Sentence command - loads the title into the line buffer
- strcpy(dialogLine, title);
- strToUpper(dialogLine);
- lineP += strlen(dialogLine) + 1;
-
- } else if (matchCommand(cmdText, "TAB")) {
- // Specifies the X offset for the current line
- _lines[_lines.size() - 1].xp = atoi(cmdText + 3);
-
- } else if (matchCommand(cmdText, "TITLE")) {
- // Title command - specifies the dialog width in number of characters
- skipLine = true;
- crFlag = true;
- underline = true;
-
- int id = atoi(cmdText + 5);
- if (id > 0) {
- // Suffix provided - specifies the dialog width in number of chars
- _widthChars = id * 2;
- _dialogWidth = id * (_vm->_font->current()->getMaxWidth() + DIALOG_SPACING) + 10;
- }
-
- } else if (matchCommand(cmdText, "UNDER")) {
- // Underline command
- underline = true;
-
- } else if (matchCommand(cmdText, "VERB")) {
- // Verb/vocab retrieval
- int verbId = 1; // TODO: Get correct vocab
- getVocab(verbId, &lineP);
-
-
- } else if (matchCommand(cmdText, "INDEX")) {
- // Index command
- _dialogIndex = atoi(cmdText + 5);
- } else {
- error("Unknown dialog command '%s' encountered", cmdText);
- }
- }
-
- *lineP++ = *srcP;
- if (cmdFlag)
- *cmdP++ = *srcP;
- ++srcP;
- }
-
- draw();
-}
-
-Dialog::Dialog(MadsM4Engine *vm, int widthChars): View(vm, Common::Rect(0, 0, 0, 0)) {
- _vm->_font->setFont(FONT_INTERFACE_MADS);
- _widthChars = widthChars * 2;
- _dialogWidth = widthChars * (_vm->_font->current()->getMaxWidth() + DIALOG_SPACING) + 10;
- _screenType = LAYER_DIALOG;
- _lineX = 0;
- _widthX = 0;
- _askPosition.x = 0;
- _askPosition.y = 0;
-}
-
-Dialog::~Dialog() {
- _vm->_palette->deleteRange(_palette);
- delete _palette;
-}
-
-void Dialog::draw() {
- assert(_widthChars != 0);
-
- // Set up the palette for this view
- _palette = new RGBList(8, NULL);
- _palette->setRange(0, 8, DIALOG_PALETTE);
- _vm->_palette->addRange(_palette);
-
- // Calculate bounds
- int dlgWidth = _dialogWidth;
- int dlgHeight = _lines.size() * (_vm->_font->current()->getHeight() + 1) + 10;
- int dialogX = (_vm->_screen->width() - dlgWidth) / 2;
- int dialogY = (_vm->_screen->height() - dlgHeight) / 2;
-
- // Create the surface for the dialog
- create(dlgWidth, dlgHeight, Graphics::PixelFormat::createFormatCLUT8());
- _coords.left = dialogX;
- _coords.top = dialogY;
- _coords.right = dialogX + dlgWidth + 1;
- _coords.bottom = dialogY + dlgHeight + 1;
-
- // Set up the dialog
- fillRect(Common::Rect(0, 0, width(), height()), 3);
- setColor(2);
- hLine(1, width() - 1, height() - 2); // Bottom edge
- hLine(0, width(), height() - 1);
- vLine(width() - 2, 2, height()); // Right edge
- vLine(width() - 1, 1, height());
-
- // Render dialog interior
- uint16 seed = 0xb78e;
- for (int yp = 2; yp < (height() - 2); ++yp) {
- byte *destP = this->getBasePtr(2, yp);
-
- for (int xp = 2; xp < (width() - 2); ++xp) {
- // Adjust the random seed
- uint16 v = seed;
- seed += 0x181D;
- v = ROR16(v, 9);
- seed = (seed ^ v) + ROR16(v, 3);
-
- *destP++ = ((seed & 0x10) != 0) ? 1 : 0;
- }
- }
-
- // If an ask position is set, create the input area frame
- if (_askPosition.y > 0) {
-
- }
-
- // Handle drawing the text contents
- _vm->_font->current()->setColors(7, 7, 7);
- setColor(7);
-
- for (uint lineCtr = 0, yp = 5; lineCtr < _lines.size(); ++lineCtr, yp += _vm->_font->current()->getHeight() + 1) {
-
- if (_lines[lineCtr].barLine) {
- // Bar separation line
- hLine(5, width() - 6, ((_vm->_font->current()->getHeight() + 1) >> 1) + yp);
- } else {
- // Standard line
- Common::Point pt(_lines[lineCtr].xp + 5, yp);
- if (_lines[lineCtr].xp & 0x40)
- ++pt.y;
-
- _vm->_font->current()->writeString(this, _lines[lineCtr].data, pt.x, pt.y, 0, DIALOG_SPACING);
-
- if (_lines[lineCtr].underline)
- // Underline needed
- hLine(pt.x, pt.x + _vm->_font->current()->getWidth(_lines[lineCtr].data, DIALOG_SPACING),
- pt.y + _vm->_font->current()->getHeight());
- }
- }
-
- // Do final translation of the dialog to game palette
- this->translate(_palette);
-}
-
-bool Dialog::onEvent(M4EventType eventType, int32 param1, int x, int y, bool &captureEvents) {
- if (_vm->_mouse->getCursorNum() != CURSOR_ARROW)
- _vm->_mouse->setCursorNum(CURSOR_ARROW);
-
- captureEvents = true;
-
- if (eventType == MEVENT_LEFT_CLICK) {
- captureEvents = false;
- _vm->_viewManager->deleteView(this);
- }
-
- return true;
-}
-
-void Dialog::display(MadsM4Engine *vm, int widthChars, const char **descEntries) {
- Dialog *dlg = new Dialog(vm, widthChars);
-
- while (*descEntries != NULL) {
- dlg->incLine();
- dlg->writeChars(*descEntries);
-
- int lineWidth = vm->_font->current()->getWidth(*descEntries, DIALOG_SPACING);
- dlg->_lines[dlg->_lines.size() - 1].xp = (dlg->_dialogWidth - 10 - lineWidth) / 2;
- ++descEntries;
- }
-
- dlg->_lines[0].underline = true;
-
- dlg->draw();
- vm->_viewManager->addView(dlg);
- vm->_viewManager->moveToFront(dlg);
-}
-
-void Dialog::getValue(MadsM4Engine *vm, const char *title, const char *text, int numChars, int currentValue) {
- int titleLen = strlen(title);
- Dialog *dlg = new Dialog(vm, titleLen + 4);
-
- dlg->addLine(title, true);
- dlg->writeChars("\n");
-
- dlg->writeChars(text);
- dlg->setupInputArea();
- dlg->writeChars("\n");
-
- dlg->draw();
- vm->_viewManager->addView(dlg);
- vm->_viewManager->moveToFront(dlg);
-
- // TODO: How to wait until the dialog is closed
-
-}
-
-} // End of namespace M4
diff --git a/engines/m4/dialogs.h b/engines/m4/dialogs.h
deleted file mode 100644
index ea3519c9e3..0000000000
--- a/engines/m4/dialogs.h
+++ /dev/null
@@ -1,80 +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 M4_DIALOGS_H
-#define M4_DIALOGS_H
-
-#include "m4/m4.h"
-#include "m4/viewmgr.h"
-#include "common/list.h"
-
-namespace M4 {
-
-class DialogLine {
-public:
- char data[100];
- uint8 xp;
- bool underline;
- bool barLine;
-
- DialogLine() { data[0] = '\0'; xp = 0; underline = barLine = false; }
-};
-
-typedef void (*GetValueFn)(MadsM4Engine *vm, int result);
-
-class Dialog : public View {
-private:
- Common::Array<DialogLine> _lines;
- int _widthChars;
- int _dialogWidth;
- int _dialogIndex;
- Common::Point _askPosition;
- RGBList *_palette;
- int _lineX;
- int _widthX;
- bool _commandCase;
-
- void initDialog();
- void incLine();
- bool matchCommand(const char *s1, const char *s2);
- void writeChars(const char *line);
- void addLine(const char *line, bool underlineP = false);
- void appendText(const char *line);
- void addBarLine();
- void getVocab(int vocabId, char **line);
- bool handleNounSuffix(char *destP, int nounNum, const char *srcP);
- void setupInputArea();
- void draw();
-public:
- Dialog(MadsM4Engine *vm, const char *msgData, const char *title = NULL);
- Dialog(MadsM4Engine *vm, int widthChars);
- virtual ~Dialog();
-
- static void display(MadsM4Engine *vm, int widthChars, const char **descEntries);
- static void getValue(MadsM4Engine *vm, const char *title, const char *text, int numChars, int currentValue);
-
- bool onEvent(M4EventType eventType, int32 param1, int x, int y, bool &captureEvents);
-};
-
-} // End of namespace M4
-
-#endif
diff --git a/engines/m4/events.cpp b/engines/m4/events.cpp
deleted file mode 100644
index b476d08c9c..0000000000
--- a/engines/m4/events.cpp
+++ /dev/null
@@ -1,365 +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.
- *
- */
-
-// TODO: There is a 'please_hyperwalk' variable that gets accessed that is meant to be global, but
-// at the moment it's implemented as a local variable
-
-#include "graphics/cursorman.h"
-
-#include "m4/events.h"
-#include "m4/graphics.h"
-#include "m4/scene.h"
-#include "m4/viewmgr.h"
-#include "m4/m4.h"
-
-namespace M4 {
-
-bool please_hyperwalk = false;
-
-/*--------------------------------------------------------------------------*
- * Events *
- * *
- * Implements an interface to the event system *
- *--------------------------------------------------------------------------*/
-
-Events::Events(MadsM4Engine *vm) : _vm(vm) {
- _mouseState = MSTATE_NO_EVENT;
- quitFlag = false;
- _keyCode = 0;
- _mouseButtons = 0;
- _ctrlFlag = false;
-
- if (_vm->isM4())
- _console = new M4Console(_m4Vm);
- else
- _console = new MadsConsole(_madsVm);
-}
-
-Events::~Events() {
- delete _console;
-}
-
-M4EventType Events::handleEvents() {
- static int oldX = -1, oldY = -1;
- static uint32 dclickTime = 0;
-
- // Handle event types
- while (g_system->getEventManager()->pollEvent(_event)) {
- switch (_event.type) {
- case Common::EVENT_QUIT:
- quitFlag = true;
- break;
- case Common::EVENT_KEYDOWN:
- // Note: The Ctrl-D ScummVM shortcut has been specialised so it will only activate the debugger
- // if it's the first key pressed after the Ctrl key is held down
- if ((_event.kbd.keycode == Common::KEYCODE_LCTRL) || (_event.kbd.keycode == Common::KEYCODE_RCTRL))
- _ctrlFlag = true;
-
- else if (_event.kbd.hasFlags(Common::KBD_CTRL)) {
- if ((_event.kbd.keycode == Common::KEYCODE_d) && _ctrlFlag) {
- _console->attach();
- _console->onFrame();
- }
- _ctrlFlag = false;
- }
- _keyCode = (int32)_event.kbd.keycode | ((_event.kbd.flags & (Common::KBD_CTRL | Common::KBD_ALT | Common::KBD_SHIFT)) << 24);
-
-
- break;
- case Common::EVENT_LBUTTONDOWN:
- case Common::EVENT_LBUTTONUP:
- case Common::EVENT_RBUTTONDOWN:
- case Common::EVENT_RBUTTONUP:
- case Common::EVENT_MBUTTONDOWN:
- case Common::EVENT_MBUTTONUP:
- case Common::EVENT_MOUSEMOVE:
- case Common::EVENT_WHEELUP:
- case Common::EVENT_WHEELDOWN:
- _vm->_mouse->handleEvent(_event);
- break;
- default:
- break;
- }
- }
-
- _mouseButtons = g_system->getEventManager()->getButtonState();
-
- // State machine for moving between states
- switch (_mouseState) {
- case MSTATE_NO_EVENT:
- if (_mouseButtons & LEFT_BUTTON_DOWN) {
- if ((dclickTime != 0) && (g_system->getMillis() < dclickTime)) {
- _mouseState = MSTATE_DOUBLECLICK_DOWN;
- dclickTime = 0;
- return MEVENT_DOUBLECLICK;
- }
- dclickTime = 0;
- _mouseState = MSTATE_LEFT_CLICK_DOWN;
- return MEVENT_LEFT_CLICK;
- }
- if (_mouseButtons & RIGHT_BUTTON_DOWN) {
- _mouseState = MSTATE_RIGHT_CLICK_DOWN;
- return MEVENT_RIGHT_CLICK;
- }
- if ((_event.mouse.x != oldX) || (_event.mouse.y != oldY)) {
- oldX = _event.mouse.x; oldY = _event.mouse.y;
- return MEVENT_MOVE;
- }
- return MEVENT_NO_EVENT;
-
- case MSTATE_LEFT_CLICK_DOWN:
- if (!(_mouseButtons & LEFT_BUTTON_DOWN)) {
- dclickTime = g_system->getMillis() + 1000 * 15 / 60;
- _mouseState = MSTATE_NO_EVENT;
- return MEVENT_LEFT_RELEASE;
- }
- if ((_event.mouse.x != oldX) || (_event.mouse.y != oldY)) {
- oldX = _event.mouse.x; oldY = _event.mouse.y;
- return MEVENT_LEFT_DRAG;
- }
- return MEVENT_LEFT_HOLD;
-
- case MSTATE_RIGHT_CLICK_DOWN:
- if (!(_mouseButtons & RIGHT_BUTTON_DOWN)) {
- _mouseState = MSTATE_NO_EVENT;
- please_hyperwalk = true;
- return MEVENT_RIGHT_RELEASE;
- }
- if ((_event.mouse.x != oldX) || (_event.mouse.y != oldY)) {
- oldX = _event.mouse.x; oldY = _event.mouse.y;
- return MEVENT_RIGHT_DRAG;
- }
- return MEVENT_RIGHT_HOLD;
-
- case MSTATE_DOUBLECLICK_DOWN:
- if (!(_mouseButtons & LEFT_BUTTON_DOWN)) {
- _mouseState = MSTATE_NO_EVENT;
- return MEVENT_DOUBLECLICK_RELEASE;
- }
- if ((_event.mouse.x != oldX) || (_event.mouse.y != oldY)) {
- oldX = _event.mouse.x; oldY = _event.mouse.y;
- return MEVENT_DOUBLECLICK_DRAG;
- }
- return MEVENT_DOUBLECLICK_HOLD;
-
- default:
- return MEVENT_NO_EVENT;
- }
-}
-
-bool Events::kbdCheck(uint32 &keyCode) {
- if (_keyCode == 0)
- return false;
-
- keyCode = _keyCode;
- _keyCode = 0;
- return true;
-}
-
-
-/*--------------------------------------------------------------------------*
- * Mouse *
- * *
- * Implements an interface to the mouse *
- *--------------------------------------------------------------------------*/
-
-Mouse::Mouse(MadsM4Engine *vm) : _vm(vm) {
- _locked = false;
- _cursorOn = false;
- _cursor = NULL;
- _cursorSprites = NULL;
- resetMouse();
-}
-
-Mouse::~Mouse() {
- delete _cursorSprites;
-}
-
-bool Mouse::init(const char *seriesName, RGB8 *palette) {
- Common::SeekableReadStream *stream = _vm->res()->get(seriesName);
- int colorCount = 0;
- RGB8* cursorPalette;
-
- _cursorSprites = new SpriteAsset(_vm, stream, stream->size(), seriesName);
-
- // Remove cursor special pixels and set the mouse cursor hotspot in MADS games
- if (!_vm->isM4()) {
- byte *data = NULL;
- for (int i = 0; i < _cursorSprites->getCount(); i++) {
- bool hotSpotSet = false;
-
- for (int x = 0; x < _cursorSprites->getFrame(i)->width(); x++) {
- for (int y = 0; y < _cursorSprites->getFrame(i)->height(); y++) {
- data = _cursorSprites->getFrame(i)->getBasePtr(x, y);
- if (*data == 1) {
- // It seems that some cursors have more than one hotspot
- // In such a case, the first hotspot seems to set the x and
- // the second one the y hotspot offset
- if (!hotSpotSet) {
- _cursorSprites->getFrame(i)->xOffset = x;
- _cursorSprites->getFrame(i)->yOffset = y;
- hotSpotSet = true;
- } else {
- _cursorSprites->getFrame(i)->yOffset = y;
- }
- *data = 0;
- }
- } // for y
- } // for x
- } // for i
- }
-
- colorCount = _cursorSprites->getColorCount();
- cursorPalette = _cursorSprites->getPalette();
- _vm->_palette->setPalette(cursorPalette, 0, colorCount);
-
- //debugCN(kDebugCore, "Cursor count: %d\n", _cursorSprites->getCount());
-
- _vm->res()->toss(seriesName);
-
- _currentCursor = -1;
- return true;
-}
-
-bool Mouse::setCursorNum(int cursorIndex) {
- if ((cursorIndex < 0) || (cursorIndex >= (int)_cursorSprites->getCount()))
- return false;
-
- _lockedCursor = cursorIndex;
- if (_locked)
- // Cursor is locked, so don't go ahead with changing cursor
- return true;
-
- _currentCursor = _lockedCursor;
- _cursor = _cursorSprites->getFrame(cursorIndex);
-
- // Set the cursor to the sprite
- CursorMan.replaceCursor((const byte *)_cursor->getBasePtr(), _cursor->width(), _cursor->height(),
- _cursor->xOffset, _cursor->yOffset, TRANSPARENT_COLOR_INDEX);
-
- return true;
-}
-
-int Mouse::cursorCount() {
- return _cursorSprites->getCount();
-}
-
-void Mouse::cursorOn() {
- _cursorOn = true;
- CursorMan.showMouse(!inHideArea());
-}
-
-void Mouse::cursorOff() {
- _cursorOn = false;
- CursorMan.showMouse(false);
-}
-
-void Mouse::lockCursor(int cursorIndex) {
- _locked = false;
- setCursorNum(cursorIndex);
- _locked = true;
-}
-
-void Mouse::unlockCursor() {
- _locked = false;
- setCursorNum(_lockedCursor);
-}
-
-const char *Mouse::getVerb() {
- switch (_vm->_mouse->getCursorNum()) {
- case CURSOR_LOOK:
- return "LOOK AT";
- case CURSOR_TAKE:
- return "TAKE";
- case CURSOR_USE:
- return "GEAR";
- default:
- return NULL;
- }
-}
-
-void Mouse::resetMouse() {
- _hideRect.left = -1;
- _hideRect.top = -1;
- _hideRect.right = -1;
- _hideRect.bottom = -1;
- _showRect.left = -1;
- _showRect.top = -1;
- _showRect.right = -1;
- _showRect.bottom = -1;
-}
-
-void Mouse::setHideRect(Common::Rect &r) {
- _hideRect = r;
-}
-
-void Mouse::setShowRect(Common::Rect &r) {
- _showRect = r;
-}
-
-const Common::Rect *Mouse::getHideRect() {
- return &_hideRect;
-}
-
-const Common::Rect *Mouse::getShowRect() {
- if ((_showRect.top == -1) || (_showRect.left == -1)) {
- // Show rectangle uninitialised - set it to current screen dimensions
- _showRect.top = 0;
- _showRect.left = 0;
- _showRect.right = _vm->_screen->width() - 1;
- _showRect.bottom = _vm->_screen->height() -1;
- }
-
- return &_showRect;
-}
-
-void Mouse::handleEvent(Common::Event &event) {
- _currentPos.x = event.mouse.x;
- _currentPos.y = event.mouse.y;
-
- // If mouse is turned on, check to see if the position is in the hide rect, or outside the show rect.
- // If so, handle toggling the visibility of the mouse
- bool showFlag = !inHideArea();
- if (_cursorOn && (CursorMan.isVisible() != showFlag)) {
- CursorMan.showMouse(showFlag);
- }
-}
-
-bool Mouse::inHideArea() {
- // Returns true if the mouse is inside a specified hide rect, or if a show rect is specified and
- // the mouse is currently outside it
- if ((_currentPos.x >= _hideRect.left) && (_currentPos.x <= _hideRect.right) &&
- (_currentPos.y >= _hideRect.top) && (_currentPos.y <= _hideRect.bottom))
- // Inside a hide area
- return true;
-
-
- if ((_showRect.top == -1) && (_showRect.left == -1))
- // No show rect defined
- return false;
-
- // Return true if the mouse is outside the show area
- return (_currentPos.x < _showRect.left) || (_currentPos.x > _showRect.right) ||
- (_currentPos.y < _showRect.top) || (_currentPos.y > _showRect.bottom);
-}
-
-} // End of namespace M4
diff --git a/engines/m4/events.h b/engines/m4/events.h
deleted file mode 100644
index 6e7cf68555..0000000000
--- a/engines/m4/events.h
+++ /dev/null
@@ -1,132 +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 M4_EVENTS_H
-#define M4_EVENTS_H
-
-#include "common/events.h"
-#include "common/rect.h"
-
-#include "m4/globals.h"
-#include "m4/assets.h"
-#include "m4/sprite.h"
-#include "m4/graphics.h"
-#include "m4/console.h"
-
-namespace M4 {
-
-#define LEFT_BUTTON_DOWN 1 << 0
-#define RIGHT_BUTTON_DOWN 1 << 1
-
-enum M4EventType {
- MEVENT_NO_EVENT, MEVENT_MOVE,
- MEVENT_LEFT_CLICK, MEVENT_LEFT_HOLD, MEVENT_LEFT_DRAG, MEVENT_LEFT_RELEASE,
- MEVENT_RIGHT_CLICK, MEVENT_RIGHT_HOLD, MEVENT_RIGHT_DRAG, MEVENT_RIGHT_RELEASE,
- MEVENT_BOTH_CLICK, MEVENT_BOTH_HOLD, MEVENT_BOTH_DRAG, MEVENT_BOTH_RELEASE,
- MEVENT_DOUBLECLICK, MEVENT_DOUBLECLICK_HOLD, MEVENT_DOUBLECLICK_DRAG, MEVENT_DOUBLECLICK_RELEASE,
- KEVENT_KEY
-};
-
-enum M4MouseState {
- MSTATE_NO_EVENT, MSTATE_LEFT_CLICK_DOWN, MSTATE_RIGHT_CLICK_DOWN, MSTATE_BOTH_CLICK_DOWN,
- MSTATE_DOUBLECLICK_DOWN
-};
-
-enum M4CommonCursors {
- CURSOR_ARROW = 0,
- CURSOR_WAIT = 1,
- CURSOR_HOURGLASS = 5,
- CURSOR_LOOK = 6,
- CURSOR_TAKE = 8,
- CURSOR_USE = 9
-};
-
-class M4Sprite;
-class SpriteAsset;
-
-class Events {
-private:
- MadsM4Engine *_vm;
- Common::Event _event;
- M4MouseState _mouseState;
- int32 _keyCode;
- int _mouseButtons;
- Console *_console;
- bool _ctrlFlag;
-public:
- bool quitFlag;
- Events(MadsM4Engine *vm);
- virtual ~Events();
-
- Common::Event &event() { return _event; }
- Common::EventType type() { return _event.type; }
-
- // M4-centric methods
- M4EventType handleEvents();
- bool kbdCheck(uint32 &keyCode);
- int getMouseButtonsState() { return _mouseButtons; }
- Console* getConsole() { return _console; }
-};
-
-
-class Mouse {
-private:
- MadsM4Engine *_vm;
- int _currentCursor, _lockedCursor;
- bool _locked;
- bool _cursorOn;
- M4Sprite *_cursor;
- SpriteAsset *_cursorSprites;
- Common::Rect _hideRect, _showRect;
- Common::Point _currentPos;
-
- void handleEvent(Common::Event &event);
- bool inHideArea();
- friend class Events;
-public:
- Mouse(MadsM4Engine *vm);
- ~Mouse();
-
- bool init(const char *seriesName, RGB8 *palette);
- bool setCursorNum(int cursorIndex);
- int getCursorNum() { return _currentCursor; }
- int cursorCount();
- Common::Point currentPos() const { return _currentPos; }
- M4Sprite *cursor() { return _cursor; }
- void cursorOn();
- void cursorOff();
- bool getCursorOn() { return _cursorOn; }
- void lockCursor(int cursorIndex);
- void unlockCursor();
-
- const char *getVerb();
-
- void resetMouse();
- void setHideRect(Common::Rect &r);
- void setShowRect(Common::Rect &r);
- const Common::Rect *getHideRect();
- const Common::Rect *getShowRect();
-};
-
-}
-
-#endif
diff --git a/engines/m4/font.cpp b/engines/m4/font.cpp
deleted file mode 100644
index d4ba714d73..0000000000
--- a/engines/m4/font.cpp
+++ /dev/null
@@ -1,291 +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 "m4/font.h"
-#include "m4/m4.h"
-#include "m4/compression.h"
-
-namespace M4 {
-
-FontManager::~FontManager() {
- for (uint i = 0; i < _entries.size(); ++i)
- delete _entries[i];
- _entries.clear();
-}
-
-Font *FontManager::getFont(const char *filename) {
- // Append an extension if the filename doesn't already have one
- char buffer[20];
- strncpy(buffer, filename, 19);
- if (!strchr(buffer, '.'))
- strcat(buffer, ".ff");
-
- // Check if the font is already loaded
- for (uint i = 0; i < _entries.size(); ++i) {
- if (!strcmp(_entries[i]->_filename, buffer))
- return _entries[i];
- }
-
- Font *f = new Font(_vm, buffer);
- _entries.push_back(f);
- return f;
-}
-
-void FontManager::setFont(const char *filename) {
- _currentFont = getFont(filename);
-}
-
-//--------------------------------------------------------------------------
-
-Font::Font(MadsM4Engine *vm, const char *filename) : _vm(vm) {
- _sysFont = true;
- strncpy(_filename, filename, 19);
- _filename[19] = '\0';
-
- //TODO: System font
- _fontColors[0] = _vm->_palette->BLACK;
- _fontColors[1] = _vm->_palette->WHITE;
- _fontColors[2] = _vm->_palette->BLACK;
- _fontColors[3] = _vm->_palette->DARK_GRAY;
-
- _sysFont = false;
-
- if (_vm->isM4())
- setFontM4(filename);
- else
- setFontMads(filename);
-}
-
-void Font::setFontM4(const char *filename) {
- Common::SeekableReadStream *fontFile = _vm->res()->openFile(filename);
-
- if (fontFile->readUint32LE() != MKTAG('F','O','N','T')) {
- debugCN(kDebugGraphics, "Font::Font: FONT tag expected\n");
- return;
- }
-
- _maxHeight = fontFile->readByte();
- _maxWidth = fontFile->readByte();
- uint32 fontSize = fontFile->readUint32LE();
-
- //debugCN(kDebugGraphics, "Font::Font: _maxWidth = %d, _maxHeight = %d, fontSize = %d\n", _maxWidth, _maxHeight, fontSize);
-
- if (fontFile->readUint32LE() != MKTAG('W','I','D','T')) {
- debugCN(kDebugGraphics, "Font::Font: WIDT tag expected\n");
- return;
- }
-
- _charWidths = new uint8[256];
- fontFile->read(_charWidths, 256);
-
- if (fontFile->readUint32LE() != MKTAG('O','F','F','S')) {
- debugCN(kDebugGraphics, "Font::Font: OFFS tag expected\n");
- return;
- }
-
- _charOffs = new uint16[256];
-
- for (int i = 0; i < 256; i++)
- _charOffs[i] = fontFile->readUint16LE();
-
- if (fontFile->readUint32LE() != MKTAG('P','I','X','S')) {
- debugCN(kDebugGraphics, "Font::Font: PIXS tag expected\n");
- return;
- }
-
- _charData = new uint8[fontSize];
- fontFile->read(_charData, fontSize);
-
- _vm->res()->toss(filename);
-}
-
-void Font::setFontMads(const char *filename) {
- MadsPack fontData(filename, _vm);
- Common::SeekableReadStream *fontFile = fontData.getItemStream(0);
-
- _maxHeight = fontFile->readByte();
- _maxWidth = fontFile->readByte();
-
- _charWidths = new uint8[128];
- // Char data is shifted by 1
- _charWidths[0] = 0;
- fontFile->read(_charWidths + 1, 127);
- fontFile->readByte(); // remainder
-
- _charOffs = new uint16[128];
-
- uint32 startOffs = 2 + 128 + 256;
- uint32 fontSize = fontFile->size() - startOffs;
-
- // Char data is shifted by 1
- _charOffs[0] = 0;
- for (int i = 1; i < 128; i++)
- _charOffs[i] = fontFile->readUint16LE() - startOffs;
- fontFile->readUint16LE(); // remainder
-
- _charData = new uint8[fontSize];
- fontFile->read(_charData, fontSize);
-
- delete fontFile;
-}
-
-Font::~Font() {
- if (!_sysFont) {
- delete[] _charWidths;
- delete[] _charOffs;
- delete[] _charData;
- }
-}
-
-void Font::setColor(uint8 color) {
- if (_sysFont)
- _fontColors[1] = color;
- else
- _fontColors[3] = color;
-}
-
-void Font::setColors(uint8 col1, uint8 col2, uint8 col3) {
- if (_sysFont)
- _fontColors[1] = col3;
- else {
- _fontColors[0] = 0xFF;
- _fontColors[1] = col1;
- _fontColors[2] = col2;
- _fontColors[3] = col3;
- }
-}
-
-int32 Font::write(M4Surface *surface, const char *text, int x, int y, int width, int spaceWidth, uint8 colors[]) {
-
- /*TODO
- if (custom_ascii_converter) { // if there is a function to convert the extended ASCII characters
- custom_ascii_converter(out_string); // call it with the string
- }
- */
-
- int right;
- if (width > 0)
- right = MIN(surface->width(), x + width + 1);
- else
- right = surface->width();
-
- x++;
- y++;
-
- int skipY = 0;
- if (y < 0) {
- skipY = -y;
- y = 0;
- }
-
- int height = MAX(0, _maxHeight - skipY);
- if (height == 0)
- return x;
-
- int bottom = y + height - 1;
- if (bottom > surface->height() - 1) {
- height -= MIN(height, bottom - (surface->height() - 1));
- }
-
- if (height <= 0)
- return x;
-
- uint8 *destPtr = (uint8*)surface->getBasePtr(x, y);
- uint8 *oldDestPtr = destPtr;
-
- int xPos = x;
-
- while (*text) {
-
- unsigned char theChar = (*text++) & 0x7F;
- int charWidth = _charWidths[theChar];
-
- if (charWidth > 0) {
-
- if (xPos + charWidth > right)
- return xPos;
-
- uint8 *charData = &_charData[_charOffs[theChar]];
- int bpp = charWidth / 4 + 1;
-
- if (!_vm->isM4()) {
- if (charWidth > 12)
- bpp = 4;
- else if (charWidth > 8)
- bpp = 3;
- else if (charWidth > 4)
- bpp = 2;
- else
- bpp = 1;
- }
-
- if (skipY != 0)
- charData += bpp * skipY;
-
- for (int i = 0; i < height; i++) {
- for (int j = 0; j < bpp; j++) {
- if (*charData & 0xc0)
- *destPtr = colors[(*charData & 0xc0) >> 6];
- destPtr++;
- if (*charData & 0x30)
- *destPtr = colors[(*charData & 0x30) >> 4];
- destPtr++;
- if (*charData & 0x0C)
- *destPtr = colors[(*charData & 0x0C) >> 2];
- destPtr++;
- if (*charData & 0x03)
- *destPtr = colors[*charData & 0x03];
- destPtr++;
- charData++;
- }
-
- destPtr += surface->width() - bpp * 4;
-
- }
-
- destPtr = oldDestPtr + charWidth + spaceWidth;
- oldDestPtr = destPtr;
-
- }
-
- xPos += charWidth + spaceWidth;
-
- }
-
- surface->freeData();
- return xPos;
-
-}
-
-int32 Font::getWidth(const char *text, int spaceWidth) {
- /*
- if (custom_ascii_converter) { // if there is a function to convert the extended ASCII characters
- custom_ascii_converter(out_string); // call it with the string
- }
- */
- int width = -spaceWidth; // Accomodate final character not needing spacing
- while (*text)
- width += _charWidths[*text++ & 0x7F] + spaceWidth;
- return width;
-}
-
-} // End of namespace M4
diff --git a/engines/m4/font.h b/engines/m4/font.h
deleted file mode 100644
index 5a9c73e5d5..0000000000
--- a/engines/m4/font.h
+++ /dev/null
@@ -1,119 +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 M4_FONT_H
-#define M4_FONT_H
-
-#include "common/util.h"
-#include "common/endian.h"
-
-#include "m4/graphics.h"
-
-/*
- TODO:
- - make a FontSystem class that creates/manages the fonts
- (similar to FileSystem)
-*/
-
-namespace M4 {
-
-#define FONT_MENU "fontmenu.fnt"
-#define FONT_INTERFACE "fontintr.fnt"
-#define FONT_TINY "small.fnt"
-#define FONT_SMALL "small.fnt"
-#define FONT_MEDIUM "medium.fnt"
-#define FONT_LINE "fontline.fnt"
-#define FONT_CONVERSATION "fontconv.fnt"
-#define FONT_4X6 "4x6pp.fnt"
-#define FONT_5X6 "5x6pp.fnt"
-
-#define FONT_CONVERSATION_MADS "fontconv.ff"
-#define FONT_INTERFACE_MADS "fontintr.ff"
-#define FONT_MAIN_MADS "fontmain.ff"
-#define FONT_MENU_MADS "fontmenu.ff" // Not in Rex (uses bitmap files for menu strings)
-#define FONT_MISC_MADS "fontmisc.ff"
-#define FONT_TELE_MADS "fonttele.ff" // Not in Phantom
-#define FONT_PHAN_MADS "fontphan.ff" // Phantom only
-
-class Font {
-public:
- Font(MadsM4Engine *vm, const char *filename);
- ~Font();
-
- void setColor(uint8 color);
- void setColors(uint8 col1, uint8 col2, uint8 col3);
-
- int32 getWidth(const char *text, int spaceWidth = -1);
- int32 getHeight() const { return _maxHeight; }
- int32 getMaxWidth() const { return _maxWidth; }
- int32 write(M4Surface *surface, const char *text, int x, int y, int width, int spaceWidth, uint8 colors[]);
- int32 writeString(M4Surface *surface, const char *text, int x, int y, int width = 0, int spaceWidth = -1) {
- return write(surface, text, x, y, width, spaceWidth, _fontColors);
- }
-public:
- char _filename[20];
-private:
- void setFontM4(const char *filename);
- void setFontMads(const char *filename);
-
- MadsM4Engine *_vm;
- uint8 _maxWidth, _maxHeight;
- uint8 *_charWidths;
- uint16 *_charOffs;
- uint8 *_charData;
- bool _sysFont;
- uint8 _fontColors[4];
-};
-
-class FontEntry {
-public:
- Font *_font;
-
- FontEntry() {
- _font = NULL;
- }
- ~FontEntry() {
- delete _font;
- }
-};
-
-class FontManager {
-private:
- MadsM4Engine *_vm;
- Common::Array<Font *> _entries;
- Font *_currentFont;
-public:
- FontManager(MadsM4Engine *vm): _vm(vm) { _currentFont = NULL; }
- ~FontManager();
-
- Font *getFont(const char *filename);
- void setFont(const char *filename);
-
- Font *current() {
- assert(_currentFont);
- return _currentFont;
- }
-};
-
-} // End of namespace M4
-
-#endif
diff --git a/engines/m4/globals.cpp b/engines/m4/globals.cpp
deleted file mode 100644
index 7a0b776eb8..0000000000
--- a/engines/m4/globals.cpp
+++ /dev/null
@@ -1,554 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#include "common/textconsole.h"
-
-#include "m4/m4.h"
-#include "m4/globals.h"
-#include "m4/graphics.h"
-#include "m4/gui.h"
-#include "m4/viewmgr.h"
-#include "m4/script.h"
-#include "m4/m4_views.h"
-#include "m4/compression.h"
-
-namespace M4 {
-
-Kernel::Kernel(MadsM4Engine *vm) : _vm(vm) {
- daemonTriggerAvailable = true;
- firstFadeColorIndex = 0;
- paused = false;
- betweenRooms = false;
- currentSection = 0;
- newSection = 0;
- previousSection = 0;
- currentRoom = 0;
- newRoom = 0;
- previousRoom = 0;
- trigger = 0;
- triggerMode = KT_DAEMON;
-
- _globalDaemonFn = NULL;
- _globalParserFn = NULL;
-
- _sectionInitFn = NULL;
- _sectionDaemonFn = NULL;
- _sectionParserFn = NULL;
-
- _roomInitFn = NULL;
- _roomDaemonFn = NULL;
- _roomPreParserFn = NULL;
- _roomParserFn = NULL;
-
-}
-
-int32 Kernel::createTrigger(int32 triggerNum) {
- if (triggerNum < 0)
- return triggerNum;
- else
- return triggerNum | (currentRoom << 16) | (triggerMode << 28);
-}
-
-bool Kernel::sendTrigger(int32 triggerNum) {
- return handleTrigger(createTrigger(triggerNum));
-}
-
-bool Kernel::handleTrigger(int32 triggerNum) {
-
- debugCN(kDebugScript, "betweenRooms = %d; triggerNum = %08X\n", betweenRooms, (uint)triggerNum);
-
- if (betweenRooms)
- return true;
-
- if (triggerNum < 0)
- return false;
-
- KernelTriggerType saveTriggerMode = triggerMode;
- int32 saveTrigger = trigger;
- bool result = false;
-
- int room = (triggerNum >> 16) & 0xFFF;
-
- debugCN(kDebugScript, "room = %d; currentRoom = %d\n", room, currentRoom);
-
- if (room != currentRoom) {
- debugCN(kDebugScript, "Kernel::handleTrigger() Trigger from another room\n");
- return false;
- }
-
- trigger = triggerNum & 0xFFFF;
- KernelTriggerType mode = (KernelTriggerType)(triggerNum >> 28);
-
- switch (mode) {
-
- case KT_PREPARSE:
- if (trigger < 32000) {
- triggerMode = KT_PREPARSE;
- roomPreParser();
- result = true;
- }
- break;
-
- case KT_PARSE:
- if (trigger < 32000) {
- triggerMode = KT_PARSE;
- // TODO player.commandReady = TRUE;
- roomParser();
- /* TODO
- if (player.commandReady)
- globalParser();
- */
- result = true;
- }
- break;
-
- case KT_DAEMON:
- debugCN(kDebugScript, "KT_DAEMON\n");
- triggerMode = KT_DAEMON;
- daemonTriggerAvailable = false;
- roomDaemon();
- if (daemonTriggerAvailable) {
- daemonTriggerAvailable = false;
- sectionDaemon();
- }
- if (daemonTriggerAvailable) {
- daemonTriggerAvailable = false;
- globalDaemon();
- }
-
- break;
-
- default:
- debugCN(kDebugScript, "Kernel::handleTrigger() Unknown trigger mode %d\n", mode);
-
- }
-
- triggerMode = saveTriggerMode;
- trigger = saveTrigger;
-
- return result;
-}
-
-void Kernel::loadGlobalScriptFunctions() {
- _globalDaemonFn = _vm->_script->loadFunction("global_daemon");
- _globalParserFn = _vm->_script->loadFunction("global_parser");
-}
-
-void Kernel::loadSectionScriptFunctions() {
- Common::String tempFnName;
- tempFnName = Common::String::format("section_init_%d", currentSection);
- _sectionInitFn = _vm->_script->loadFunction(tempFnName);
- tempFnName = Common::String::format("section_daemon_%d", currentSection);
- _sectionDaemonFn = _vm->_script->loadFunction(tempFnName);
- tempFnName = Common::String::format("section_parser_%d", currentSection);
- _sectionParserFn = _vm->_script->loadFunction(tempFnName);
-}
-
-void Kernel::loadRoomScriptFunctions() {
- Common::String tempFnName;
- tempFnName = Common::String::format("room_init_%d", currentRoom);
- _roomInitFn = _vm->_script->loadFunction(tempFnName);
- tempFnName = Common::String::format("room_daemon_%d", currentRoom);
- _roomDaemonFn = _vm->_script->loadFunction(tempFnName);
- tempFnName = Common::String::format("room_pre_parser_%d", currentRoom);
- _roomPreParserFn = _vm->_script->loadFunction(tempFnName);
- tempFnName = Common::String::format("room_parser_%d", currentRoom);
- _roomParserFn = _vm->_script->loadFunction(tempFnName);
-}
-
-void Kernel::globalDaemon() {
- if (_globalDaemonFn)
- _vm->_script->runFunction(_globalDaemonFn);
- else {
- debugCN(kDebugScript, "Kernel::globalDaemon() _globalDaemonFn is NULL\n");
- }
-}
-
-void Kernel::globalParser() {
- if (_globalParserFn)
- _vm->_script->runFunction(_globalParserFn);
- else {
- debugCN(kDebugScript, "Kernel::globalParser() _globalParserFn is NULL\n");
- }
-}
-
-void Kernel::sectionInit() {
- if (_sectionInitFn)
- _vm->_script->runFunction(_sectionInitFn);
- else {
- debugCN(kDebugScript, "Kernel::sectionInit() _sectionInitFn is NULL\n");
- }
-}
-
-void Kernel::sectionDaemon() {
- if (_sectionDaemonFn)
- _vm->_script->runFunction(_sectionDaemonFn);
- else {
- debugCN(kDebugScript, "Kernel::sectionDaemon() _sectionDaemonFn is NULL\n");
- }
-}
-
-void Kernel::sectionParser() {
- if (_sectionParserFn)
- _vm->_script->runFunction(_sectionParserFn);
- else {
- debugCN(kDebugScript, "Kernel::sectionParser() _sectionParserFn is NULL\n");
- }
-}
-
-void Kernel::roomInit() {
- if (_roomInitFn)
- _vm->_script->runFunction(_roomInitFn);
- else {
- debugCN(kDebugScript, "Kernel::roomInit() _roomInitFn is NULL\n");
- }
-}
-
-void Kernel::roomDaemon() {
- if (_roomDaemonFn)
- _vm->_script->runFunction(_roomDaemonFn);
- else {
- debugCN(kDebugScript, "Kernel::roomDaemon() _roomDaemonFn is NULL\n");
- }
-}
-
-void Kernel::roomPreParser() {
- if (_roomPreParserFn)
- _vm->_script->runFunction(_roomPreParserFn);
- else {
- debugCN(kDebugScript, "Kernel::roomPreParser() _roomPreParserFn is NULL\n");
- }
-}
-
-void Kernel::roomParser() {
- if (_roomParserFn)
- _vm->_script->runFunction(_roomParserFn);
- else {
- debugCN(kDebugScript, "Kernel::roomParser() _roomParserFn is NULL\n");
- }
-}
-
-void Kernel::pauseGame(bool value) {
- paused = value;
-
- if (paused) pauseEngines();
- else unpauseEngines();
-}
-
-void Kernel::pauseEngines() {
- // TODO: A proper implementation of game pausing. At the moment I'm using a hard-coded
- // check in events.cpp on Kernel::paused to prevent any events going to the scene
-}
-
-void Kernel::unpauseEngines() {
- // TODO: A proper implementation of game unpausing
-}
-
-/*--------------------------------------------------------------------------*/
-
-Globals::Globals(MadsM4Engine *vm): _vm(vm) {
-}
-
-bool Globals::isInterfaceVisible() {
- return _m4Vm->scene()->getInterface()->isVisible();
-}
-
-/*--------------------------------------------------------------------------*/
-
-MadsGlobals::MadsGlobals(MadsEngine *vm): Globals(vm) {
- _vm = vm;
-
- playerSpriteChanged = false;
- dialogType = DIALOG_NONE;
- sceneNumber = -1;
- for (int i = 0; i < 3; ++i)
- actionNouns[i] = 0;
- _difficultyLevel = 0;
-}
-
-MadsGlobals::~MadsGlobals() {
- uint32 i;
-
- for (i = 0; i < _madsVocab.size(); i++)
- free(_madsVocab[i]);
- _madsVocab.clear();
-
- for (i = 0; i < _madsQuotes.size(); i++)
- free(_madsQuotes[i]);
- _madsQuotes.clear();
-
- _madsMessages.clear();
-}
-
-void MadsGlobals::loadMadsVocab() {
- Common::SeekableReadStream *vocabS = _vm->res()->get("vocab.dat");
- int curPos = 0;
-
- char buffer[30];
- strcpy(buffer, "");
-
- while (true) {
- uint8 b = vocabS->readByte();
- if (vocabS->eos()) break;
-
- buffer[curPos++] = b;
- if (buffer[curPos - 1] == '\0') {
- // end of string, add it to the strings list
- _madsVocab.push_back(strdup(buffer));
- curPos = 0;
- strcpy(buffer, "");
- }
- }
-
- _vm->res()->toss("vocab.dat");
-}
-
-void MadsGlobals::loadQuotes() {
- Common::SeekableReadStream *quoteS = _vm->res()->get("quotes.dat");
- int curPos = 0;
-
- char buffer[128];
- strcpy(buffer, "");
-
- while (true) {
- uint8 b = quoteS->readByte();
- if (quoteS->eos()) break;
-
- buffer[curPos++] = b;
- if (buffer[curPos - 1] == '\0') {
- // end of string, add it to the strings list
- _madsQuotes.push_back(strdup(buffer));
- curPos = 0;
- strcpy(buffer, "");
- }
- }
-
- _vm->res()->toss("quotes.dat");
-}
-
-void MadsGlobals::loadMadsMessagesInfo() {
- Common::SeekableReadStream *messageS = _vm->res()->get("messages.dat");
-
- int16 count = messageS->readUint16LE();
- //debugCN(kDebugScript, "%i messages\n", count);
-
- for (int i = 0; i < count; i++) {
- MessageItem curMessage;
- curMessage.id = messageS->readUint32LE();
- curMessage.offset = messageS->readUint32LE();
- curMessage.uncompSize = messageS->readUint16LE();
-
- if (i > 0)
- _madsMessages[i - 1].compSize = curMessage.offset - _madsMessages[i - 1].offset;
-
- if (i == count - 1)
- curMessage.compSize = messageS->size() - curMessage.offset;
-
- //debugCN(kDebugScript, "id: %i, offset: %i, uncomp size: %i\n", curMessage->id, curMessage->offset, curMessage->uncompSize);
- _madsMessages.push_back(curMessage);
- }
-
- _vm->res()->toss("messages.dat");
-}
-
-void MadsGlobals::loadMadsObjects() {
- Common::SeekableReadStream *objList = _vm->res()->get("objects.dat");
- int numObjects = objList->readUint16LE();
-
- for (int i = 0; i < numObjects; ++i)
- _madsObjects.push_back(MadsObjectArray::value_type(new MadsObject(objList)));
-
- _vm->res()->toss("objects.dat");
-}
-
-int MadsGlobals::getObjectIndex(uint16 descId) {
- for (uint i = 0; i < _madsObjects.size(); ++i) {
- if (_madsObjects[i].get()->_descId == descId)
- return i;
- }
-
- return -1;
-}
-
-int MadsGlobals::messageIndexOf(uint32 messageId) {
- for (uint i = 0; i < _madsMessages.size(); ++i)
- {
- if (_madsMessages[i].id == messageId)
- return i;
- }
- return -1;
-}
-
-const char *MadsGlobals::loadMessage(uint index) {
- if (index > _madsMessages.size() - 1) {
- warning("Invalid message index: %i", index);
- return NULL;
- }
-
- FabDecompressor fab;
- byte *compData = new byte[_madsMessages[index].compSize];
- byte *buffer = new byte[_madsMessages[index].uncompSize];
-
- Common::SeekableReadStream *messageS = _vm->res()->get("messages.dat");
- messageS->seek(_madsMessages[index].offset, SEEK_SET);
- messageS->read(compData, _madsMessages[index].compSize);
- fab.decompress(compData, _madsMessages[index].compSize, buffer, _madsMessages[index].uncompSize);
-
- for (int i = 0; i < _madsMessages[index].uncompSize - 1; i++)
- if (buffer[i] == '\0') buffer[i] = '\n';
-
- _vm->res()->toss("messages.dat");
- delete[] compData;
-
- return (char*)buffer;
-}
-
-/**
- * Adds the specified scene number to list of scenes previously visited
- */
-void MadsGlobals::addVisitedScene(int newSceneNumber) {
- if (!isSceneVisited(newSceneNumber))
- _visitedScenes.push_back(newSceneNumber);
-}
-
-/**
- * Returns true if the specified scene has been previously visited
- */
-bool MadsGlobals::isSceneVisited(int checkSceneNumber) {
- Common::List<int>::iterator i;
- for (i = _visitedScenes.begin(); i != _visitedScenes.end(); ++i)
- if (*i == checkSceneNumber)
- return true;
- return false;
-}
-
-void MadsGlobals::removeVisitedScene(int oldSceneNumber) {
- _visitedScenes.remove(oldSceneNumber);
-}
-
-/*--------------------------------------------------------------------------*/
-
-M4Globals::M4Globals(M4Engine *vm): Globals(vm) {
- _vm = vm;
-}
-
-/*--------------------------------------------------------------------------*/
-
-Player::Player(MadsM4Engine *vm) : _vm(vm) {
- commandsAllowed = true;
- needToWalk = false;
- readyToWalk = false;
- waitingForWalk = false;
- commandReady = false;
- strcpy(verb, "");
- strcpy(noun, "");
- strcpy(prep, "");
- strcpy(object, "");
-}
-
-void Player::setCommandsAllowed(bool value) {
- setCommandsAllowedFlag = true;
- commandsAllowed = value;
- if (value) {
- // Player commands are enabled again
- _vm->_mouse->lockCursor(CURSOR_ARROW);
- //_m4Vm->scene()->getInterface()->cancelSentence();
- } else {
- // Player commands are disabled, so show hourglass cursor
- _vm->_mouse->lockCursor(CURSOR_HOURGLASS);
- }
-}
-
-bool Player::said(const char *word1, const char *word2, const char *word3) {
- const char *words[3];
- words[0] = word1;
- words[1] = word2;
- words[2] = word2;
- for (int i = 0; i < 3; i++) {
- if (words[i])
- if ((scumm_stricmp(noun, words[i])) &&
- (scumm_stricmp(object, words[i])) &&
- (scumm_stricmp(verb, words[i])))
- return false;
- }
- return true;
-}
-
-bool Player::saidAny(const char *word1, const char *word2, const char *word3,
- const char *word4, const char *word5, const char *word6, const char *word7,
- const char *word8, const char *word9, const char *word10) {
- const char *words[10];
- words[0] = word1;
- words[1] = word2;
- words[2] = word3;
- words[3] = word4;
- words[4] = word5;
- words[5] = word6;
- words[6] = word7;
- words[7] = word8;
- words[8] = word9;
- words[9] = word10;
- for (int i = 0; i < 10; i++) {
- if (words[i]) {
- if (!scumm_stricmp(noun, words[i]))
- return true;
- if (!scumm_stricmp(object, words[i]))
- return true;
- if (!scumm_stricmp(verb, words[i]))
- return true;
- }
- }
- return false;
-}
-
-/*--------------------------------------------------------------------------*/
-
-MadsObject::MadsObject(Common::SeekableReadStream *stream) {
- load(stream);
-}
-
-void MadsObject::load(Common::SeekableReadStream *stream) {
- // Get the next data block
- uint8 obj[0x30];
- stream->read(obj, 0x30);
-
- // Extract object data fields
- _descId = READ_LE_UINT16(&obj[0]);
- _roomNumber = READ_LE_UINT16(&obj[2]);
- _article = (MADSArticles)obj[4];
- _vocabCount = obj[5] & 0x7f;
- // Phantom / Dragon
- if (_vocabCount > 3)
- warning("MadsObject::load(), vocab cound > 3 (it's %d)", _vocabCount);
-
- for (int i = 0; i < _vocabCount; ++i) {
- _vocabList[i].flags1 = obj[6 + i * 4];
- _vocabList[i].flags2 = obj[7 + i * 4];
- _vocabList[i].vocabId = READ_LE_UINT16(&obj[8 + i * 4]);
- }
-}
-
-void MadsObject::setRoom(int roomNumber) {
-
-}
-
-} // End of namespace M4
diff --git a/engines/m4/globals.h b/engines/m4/globals.h
deleted file mode 100644
index 693dc9d6c9..0000000000
--- a/engines/m4/globals.h
+++ /dev/null
@@ -1,346 +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 M4_GLOBALS_H
-#define M4_GLOBALS_H
-
-#include "common/scummsys.h"
-#include "common/array.h"
-#include "common/hashmap.h"
-#include "common/rect.h"
-#include "common/list.h"
-#include "common/ptr.h"
-
-namespace Common {
-class SeekableReadStream;
-}
-
-namespace M4 {
-
-class MadsM4Engine;
-class M4Engine;
-class MadsEngine;
-class ScriptInterpreter;
-class ScriptFunction;
-
-// Globals
-enum WoodScriptGlobals {
- kGlobTime = 0,
- kGlobTimeDelta = 1,
- kGlobMinY = 2,
- kGlobMaxY = 3,
- kGlobMinScale = 4,
- kGlobMaxScale = 5,
- kGlobScaler = 6,
- kGlobTemp1 = 7,
- kGlobTemp2 = 8,
- kGlobTemp3 = 9,
- kGlobTemp4 = 10,
- kGlobTemp5 = 11,
- kGlobTemp6 = 12,
- kGlobTemp7 = 13,
- kGlobTemp8 = 14,
- kGlobTemp9 = 15,
- kGlobTemp10 = 16,
- kGlobTemp11 = 17,
- kGlobTemp12 = 18,
- kGlobTemp13 = 19,
- kGlobTemp14 = 20,
- kGlobTemp15 = 21,
- kGlobTemp16 = 22,
- kGlobTemp17 = 23,
- kGlobTemp18 = 24,
- kGlobTemp19 = 25,
- kGlobTemp20 = 26,
- kGlobTemp21 = 27,
- kGlobTemp22 = 28,
- kGlobTemp23 = 29,
- kGlobTemp24 = 30,
- kGlobTemp25 = 31,
- kGlobTemp26 = 32,
- kGlobTemp27 = 33,
- kGlobTemp28 = 34,
- kGlobTemp29 = 35,
- kGlobTemp30 = 36,
- kGlobTemp31 = 37,
- kGlobTemp32 = 38
-};
-
-const uint32 SERIES_FORWARD = 0;
-const uint32 SERIES_PINGPONG = 1;
-const uint32 SERIES_BACKWARD = 2;
-const uint32 SERIES_RANDOM = 4;
-const uint32 SERIES_NO_TOSS = 8;
-const uint32 SERIES_STICK = 16;
-const uint32 SERIES_LOOP_TRIGGER = 32;
-const uint32 SERIES_LOAD_PALETTE = 64;
-const uint32 SERIES_HORZ_FLIP =128;
-
-enum KernelTriggerType {
- KT_PARSE = 1,
- KT_DAEMON,
- KT_PREPARSE
-};
-
-class Kernel {
-private:
- MadsM4Engine *_vm;
- ScriptFunction *_globalDaemonFn, *_globalParserFn;
- ScriptFunction *_sectionInitFn, *_sectionDaemonFn, *_sectionParserFn;
- ScriptFunction *_roomInitFn, *_roomDaemonFn, *_roomPreParserFn, *_roomParserFn;
- void pauseEngines();
- void unpauseEngines();
-public:
- Kernel(MadsM4Engine *vm);
-
- // TODO: Move to some palette/fading class
- int fadeUpDuration, firstFadeColorIndex;
- int minPalEntry, maxPalEntry;
-
- bool paused;
- //machine* myWalker;
- bool repeatedlyCallDeamon;
- bool daemonTriggerAvailable;
- bool betweenRooms;
- int currentSection, newSection, previousSection;
- int currentRoom, newRoom, previousRoom;
-
- int32 trigger;
- KernelTriggerType triggerMode;
-
- int32 createTrigger(int32 triggerNum);
- bool sendTrigger(int32 triggerNum);
- bool handleTrigger(int32 triggerNum);
-
- void loadGlobalScriptFunctions();
- void loadSectionScriptFunctions();
- void loadRoomScriptFunctions();
-
- void globalDaemon();
- void globalParser();
-
- void sectionInit();
- void sectionDaemon();
- void sectionParser();
-
- void roomInit();
- void roomDaemon();
- void roomPreParser();
- void roomParser();
-
- void pauseGame(bool value);
-};
-
-#define TOTAL_NUM_VARIABLES 210
-
-#define PLAYER_INVENTORY 2
-
-enum MADSArticles {
- kArticleNone = 0,
- kArticleWith = 1,
- kArticleTo = 2,
- kArticleAt = 3,
- kArticleFrom = 4,
- kArticleOn = 5,
- kArticleIn = 6,
- kArticleUnder = 7,
- kArticleBehind = 8
-};
-
-struct VocabEntry {
- uint8 flags1;
- uint8 flags2;
- uint16 vocabId;
-};
-
-class MadsObject {
-public:
- MadsObject() {}
- MadsObject(Common::SeekableReadStream *stream);
- void load(Common::SeekableReadStream *stream);
- bool isInInventory() const { return _roomNumber == PLAYER_INVENTORY; }
- void setRoom(int roomNumber);
-
- uint16 _descId;
- uint16 _roomNumber;
- MADSArticles _article;
- uint8 _vocabCount;
- VocabEntry _vocabList[3];
-};
-
-typedef Common::Array<Common::SharedPtr<MadsObject> > MadsObjectArray;
-
-class Globals {
-private:
- MadsM4Engine *_vm;
-public:
- Globals(MadsM4Engine *vm);
- virtual ~Globals() {}
-
- bool isInterfaceVisible();
-
-};
-
-class M4Globals : public Globals {
-private:
- M4Engine *_vm;
-public:
- M4Globals(M4Engine *vm);
- virtual ~M4Globals() {}
-
- bool invSuppressClickSound;
-};
-
-enum RexPlayerSex { SEX_MALE = 0, SEX_FEMALE = 2, SEX_UNKNOWN = 1};
-
-enum MadsDialogType { DIALOG_NONE = 0, DIALOG_GAME_MENU = 1, DIALOG_SAVE = 2, DIALOG_RESTORE = 3, DIALOG_OPTIONS = 4,
- DIALOG_DIFFICULTY = 5, DIALOG_ERROR = 6};
-
-struct MadsConfigData {
- bool musicFlag;
- bool soundFlag;
- bool easyMouse;
- bool invObjectsStill;
- bool textWindowStill;
- int storyMode;
- int screenFades;
-};
-
-#define GET_GLOBAL(x) (_madsVm->globals()->_globals[x])
-#define GET_GLOBAL32(x) (((uint32)_madsVm->globals()->_globals[x + 1] << 16) | _madsVm->globals()->_globals[x])
-#define SET_GLOBAL(x,y) _madsVm->globals()->_globals[x] = y
-#define SET_GLOBAL32(x,y) { _madsVm->globals()->_globals[x] = (y) & 0xffff; _madsVm->globals()->_globals[(x) + 1] = (y) >> 16; }
-
-typedef int (*IntFunctionPtr)();
-
-union DataMapEntry {
- bool *boolValue;
- uint16 *uint16Value;
- int *intValue;
- IntFunctionPtr fnPtr;
-};
-
-typedef Common::HashMap<uint16, uint16> DataMapHash;
-
-class MadsGlobals : public Globals {
-private:
- struct MessageItem {
- uint32 id;
- uint32 offset;
- uint16 uncompSize;
- uint16 compSize;
- };
-
- MadsEngine *_vm;
- Common::Array<char* > _madsVocab;
- Common::Array<char* > _madsQuotes;
- Common::Array<MessageItem> _madsMessages;
- MadsObjectArray _madsObjects;
- Common::List<int> _visitedScenes;
-public:
- MadsGlobals(MadsEngine *vm);
- ~MadsGlobals();
-
- // MADS variables
- uint16 _globals[TOTAL_NUM_VARIABLES];
- MadsConfigData _config;
- bool playerSpriteChanged;
- MadsDialogType dialogType;
- int sceneNumber;
- int previousScene;
- int16 _nextSceneId;
- uint16 actionNouns[3];
- DataMapHash _dataMap;
- int _difficultyLevel;
-
- void loadMadsVocab();
- uint32 getVocabSize() { return _madsVocab.size(); }
- const char *getVocab(uint32 index) {
- // Vocab list is 1-based, so always subtract one from index provided
- assert((index > 0) && (index <= _madsVocab.size()));
- return _madsVocab[index - 1];
- }
-
- void loadQuotes();
- uint32 getQuotesSize() { return _madsQuotes.size(); }
- const char *getQuote(uint32 index) { return _madsQuotes[index - 1]; }
- // DEPRECATED: ScummVM re-implementation keeps all the quotes loaded, so the methods below are stubs
- void clearQuotes() {}
- void loadQuoteRange(int startNum, int endNum) {}
- void loadQuoteSet(...) {}
- void loadQuote(int quoteNum) {}
-
- void loadMadsMessagesInfo();
- uint32 getMessagesSize() { return _madsMessages.size(); }
- int messageIndexOf(uint32 messageId);
- const char *loadMessage(uint index);
-
- void loadMadsObjects();
- uint32 getObjectsSize() { return _madsObjects.size(); }
- MadsObject *getObject(uint32 index) { return _madsObjects[index].get(); }
- int getObjectIndex(uint16 descId);
- int getObjectFolder(uint32 folderId) { warning("TODO: getObjectFolder"); return -1; }
-
- void addVisitedScene(int sceneNumber);
- bool isSceneVisited(int sceneNumber);
- void removeVisitedScene(int sceneNumber);
-};
-
-#define PLAYER_FIELD_LENGTH 40
-
-class Player {
-public:
- Player(MadsM4Engine *vm);
- void setCommandsAllowed(bool value);
-
- // Variables
- Common::Point position; // Player's current position
- int facing; // Facing direction
-
- char verb[PLAYER_FIELD_LENGTH]; // Action strings
- char noun[PLAYER_FIELD_LENGTH];
- char prep[PLAYER_FIELD_LENGTH];
- char object[PLAYER_FIELD_LENGTH];
- Common::String assetName, shadowName;
- int walkerType, shadowType;
- bool needToWalk, readyToWalk, waitingForWalk;
- bool commandsAllowed;
- bool commandReady;
- bool visible;
- bool beenInRoomBefore;
- bool walkerInCurrentRoom;
- int32 walkerTriggerNum;
- int walkFacing;
- bool setCommandsAllowedFlag;
-
- bool said(const char *word1, const char *word2 = NULL, const char *word3 = NULL);
- bool saidAny(const char *word1, const char *word2, const char *word3,
- const char *word4, const char *word5, const char *word6, const char *word7,
- const char *word8, const char *word9, const char *word10);
-
-private:
- MadsM4Engine *_vm;
-};
-
-} // End of namespace M4
-
-#endif
diff --git a/engines/m4/graphics.cpp b/engines/m4/graphics.cpp
deleted file mode 100644
index 4c272de32c..0000000000
--- a/engines/m4/graphics.cpp
+++ /dev/null
@@ -1,1361 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#include "common/system.h"
-#include "common/util.h"
-#include "common/ptr.h"
-#include "common/textconsole.h"
-
-#include "graphics/palette.h"
-
-#include "m4/globals.h"
-#include "m4/graphics.h"
-#include "m4/sprite.h"
-#include "m4/m4.h"
-#include "m4/compression.h"
-
-namespace M4 {
-
-RGBList::RGBList(int numEntries, RGB8 *srcData, bool freeData) {
- _size = numEntries;
- assert(numEntries <= 256);
-
- if (srcData == NULL) {
- _data = new RGB8[numEntries];
- _freeData = true;
- } else {
- _data = srcData;
- _freeData = freeData;
- }
-
- _palIndexes = new byte[numEntries];
- Common::set_to(&_palIndexes[0], &_palIndexes[numEntries], 0);
-}
-
-RGBList::~RGBList() {
- if (_freeData)
- delete[] _data;
- delete[] _palIndexes;
-}
-
-void RGBList::setRange(int start, int count, const RGB8 *src) {
- assert((start + count) <= _size);
-
- Common::copy(&src[0], &src[count], &_data[start]);
-}
-
-/**
- * Creates a duplicate of the given rgb list
- */
-RGBList *RGBList::clone() const {
- RGBList *dest = new RGBList(_size, _data, false);
- _madsVm->_palette->addRange(dest);
- return dest;
-}
-
-//--------------------------------------------------------------------------
-
-#define VGA_COLOR_TRANS(x) (x == 0x3f ? 255 : x << 2)
-
-M4Surface::~M4Surface() {
- if (_rgbList) {
- _madsVm->_palette->deleteRange(_rgbList);
- delete _rgbList;
- }
- if (_ownsData)
- free();
-}
-
-void M4Surface::loadCodesM4(Common::SeekableReadStream *source) {
- if (!source) {
- free();
- return;
- }
-
- uint16 widthVal = source->readUint16LE();
- uint16 heightVal = source->readUint16LE();
-
- create(widthVal, heightVal, Graphics::PixelFormat::createFormatCLUT8());
- source->read(pixels, widthVal * heightVal);
-}
-
-void M4Surface::loadCodesMads(Common::SeekableReadStream *source) {
- if (!source) {
- free();
- return;
- }
-
- uint16 widthVal = 320;
- uint16 heightVal = 156;
- byte *walkMap = new byte[source->size()];
-
- create(widthVal, heightVal, Graphics::PixelFormat::createFormatCLUT8());
- source->read(walkMap, source->size());
-
- byte *ptr = (byte *)getBasePtr(0, 0);
-
- for (int y = 0; y < heightVal; y++) {
- for (int x = 0; x < widthVal; x++) {
- int ofs = x + (y * widthVal);
- if ((walkMap[ofs / 8] << (ofs % 8)) & 0x80)
- *ptr++ = 1; // walkable
- else
- *ptr++ = 0;
- }
- }
-
- delete[] walkMap;
-}
-
-// Sprite related methods
-
-void M4Surface::vLine(int x, int y1, int y2) {
- Graphics::Surface::vLine(x, y1, y2, _color);
-}
-
-void M4Surface::hLine(int x1, int x2, int y) {
- Graphics::Surface::hLine(x1, y, x2, _color);
-}
-
-void M4Surface::vLineXor(int x, int y1, int y2) {
- // Clipping
- if (x < 0 || x >= w)
- return;
-
- if (y2 < y1)
- SWAP(y2, y1);
-
- if (y1 < 0)
- y1 = 0;
- if (y2 >= h)
- y2 = h - 1;
-
- byte *ptr = (byte *)getBasePtr(x, y1);
- while (y1++ <= y2) {
- *ptr ^= 0xFF;
- ptr += pitch;
- }
-
-}
-
-void M4Surface::hLineXor(int x1, int x2, int y) {
- // Clipping
- if (y < 0 || y >= h)
- return;
-
- if (x2 < x1)
- SWAP(x2, x1);
-
- if (x1 < 0)
- x1 = 0;
- if (x2 >= w)
- x2 = w - 1;
-
- if (x2 < x1)
- return;
-
- byte *ptr = (byte *)getBasePtr(x1, y);
- while (x1++ <= x2)
- *ptr++ ^= 0xFF;
-
-}
-
-void M4Surface::drawLine(int x1, int y1, int x2, int y2, byte color) {
- Graphics::Surface::drawLine(x1, y1, x2, y2, color);
-}
-
-
-void M4Surface::frameRect(int x1, int y1, int x2, int y2) {
- Graphics::Surface::frameRect(Common::Rect(x1, y1, x2, y2), _color);
-}
-
-void M4Surface::fillRect(int x1, int y1, int x2, int y2) {
- Graphics::Surface::fillRect(Common::Rect(x1, y1, x2, y2), _color);
-}
-
-void M4Surface::drawSprite(int x, int y, SpriteInfo &info, const Common::Rect &clipRect) {
-
- enum {
- kStatusSkip,
- kStatusScale,
- kStatusDraw
- };
-
- // NOTE: The current clipping code assumes that the top left corner of the clip
- // rectangle is always 0, 0
- assert(clipRect.top == 0 && clipRect.left == 0);
-
- // TODO: Put err* and scaled* into SpriteInfo
- int errX = info.hotX * info.scaleX % 100;
- int errY = info.hotY * info.scaleY % 100;
- int scaledWidth = scaleValue(info.width, info.scaleX, errX);
- int scaledHeight = scaleValue(info.height, info.scaleY, errY);
-
- /*
- debugCN(kDebugGraphics, "M4Surface::drawSprite() info.width = %d; info.scaleX = %d; info.height = %d; info.scaleY = %d; scaledWidth = %d; scaledHeight = %d\n",
- info.width, info.scaleX, info.height, info.scaleY, scaledWidth, scaledHeight);
- */
-
- int clipX = 0, clipY = 0;
- // Clip the sprite's width and height according to the clip rectangle's dimensions
- // This clips the sprite to the bottom and right
- if (x >= 0) {
- scaledWidth = MIN<int>(x + scaledWidth, clipRect.right) - x;
- } else {
- clipX = x;
- scaledWidth = x + scaledWidth;
- }
- if (y >= 0) {
- scaledHeight = MIN<int>(y + scaledHeight, clipRect.bottom) - y;
- } else {
- clipY = y;
- scaledHeight = y + scaledHeight;
- }
-
- //debugCN(kDebugGraphics, "M4Surface::drawSprite() width = %d; height = %d; scaledWidth = %d; scaledHeight = %d\n", info.width, info.height, scaledWidth, scaledHeight);
-
- // Check if sprite is inside the screen. If it's not, there's no need to draw it
- if (scaledWidth + x <= 0 || scaledHeight + y <= 0) // check left and top (in case x,y are negative)
- return;
- if (scaledWidth <= 0 || scaledHeight <= 0) // check right and bottom
- return;
- int heightAmt = scaledHeight;
-
- byte *src = info.sprite->getBasePtr();
- byte *dst = getBasePtr(x - info.hotX - clipX, y - info.hotY - clipY);
-
- int status = kStatusSkip;
- byte *scaledLineBuf = new byte[scaledWidth];
-
- while (heightAmt > 0) {
-
- if (status == kStatusSkip) {
- // Skip line
- errY -= info.scaleY;
- if (errY < 0)
- status = kStatusScale;
- else
- src += info.width;
- } else {
-
- if (status == kStatusScale) {
- // Scale current line
- byte *lineDst = scaledLineBuf;
- int curErrX = errX;
- int widthVal = scaledWidth;
- byte *tempSrc = src;
- int startX = clipX;
- while (widthVal > 0) {
- byte pixel = *tempSrc++;
- curErrX -= info.scaleX;
- while (curErrX < 0) {
- if (startX == 0) {
- *lineDst++ = pixel;
- widthVal--;
- } else {
- startX++;
- }
- curErrX += 100;
- }
- }
- src += info.width;
- status = kStatusDraw;
- }
-
- if (status == kStatusDraw && clipY == 0) {
- // Draw previously scaled line
- // TODO Implement different drawing types (depth, shadow etc.)
- byte *tempDst = dst;
- for (int lineX = 0; lineX < scaledWidth; lineX++) {
- byte pixel = scaledLineBuf[lineX];
-
- if (info.encoding & 0x80) {
-
- if (pixel == 0x80) {
- pixel = 0;
- } else {
- byte destPixel = *tempDst;
- byte r, g, b;
- r = CLIP((info.palette[destPixel].r * pixel) >> 10, 0, 31);
- g = CLIP((info.palette[destPixel].g * pixel) >> 10, 0, 31);
- b = CLIP((info.palette[destPixel].b * pixel) >> 10, 0, 31);
- pixel = info.inverseColorTable[(b << 10) | (g << 5) | r];
- }
- }
-
- if (pixel)
- *tempDst = pixel;
-
- tempDst++;
- }
- dst += pitch;
- heightAmt--;
- // TODO depth etc.
- //depthAddress += Destination -> Width;
-
- errY += 100;
- if (errY >= 0)
- status = kStatusSkip;
- } else if (status == kStatusDraw && clipY < 0) {
- clipY++;
-
- errY += 100;
- if (errY >= 0)
- status = kStatusSkip;
- }
-
- }
-
- }
-
- delete[] scaledLineBuf;
-
-}
-
-// Surface methods
-
-void M4Surface::freeData() {
-}
-
-void M4Surface::clear() {
- Common::set_to((byte *)pixels, (byte *)pixels + w * h, _vm->_palette->BLACK);
-}
-
-void M4Surface::reset() {
- ::free(pixels);
- pixels = NULL;
- if (_rgbList) {
- _vm->_palette->deleteRange(_rgbList);
- delete _rgbList;
- _rgbList = NULL;
- }
-}
-
-void M4Surface::frameRect(const Common::Rect &r, uint8 color) {
- Graphics::Surface::frameRect(r, color);
-}
-
-void M4Surface::fillRect(const Common::Rect &r, uint8 color) {
- Graphics::Surface::fillRect(r, color);
-}
-
-void M4Surface::copyFrom(M4Surface *src, const Common::Rect &srcBounds, int destX, int destY,
- int transparentColor) {
- // Validation of the rectangle and position
- if ((destX >= w) || (destY >= h))
- return;
-
- Common::Rect copyRect = srcBounds;
- if (destX < 0) {
- copyRect.left += -destX;
- destX = 0;
- } else if (destX + copyRect.width() > w) {
- copyRect.right -= destX + copyRect.width() - w;
- }
- if (destY < 0) {
- copyRect.top += -destY;
- destY = 0;
- } else if (destY + copyRect.height() > h) {
- copyRect.bottom -= destY + copyRect.height() - h;
- }
-
- if (!copyRect.isValidRect())
- return;
-
- // Copy the specified area
-
- byte *data = src->getBasePtr();
- byte *srcPtr = data + (src->width() * copyRect.top + copyRect.left);
- byte *destPtr = (byte *)pixels + (destY * width()) + destX;
-
- for (int rowCtr = 0; rowCtr < copyRect.height(); ++rowCtr) {
- if (transparentColor == -1)
- // No transparency, so copy line over
- Common::copy(srcPtr, srcPtr + copyRect.width(), destPtr);
- else {
- // Copy each byte one at a time checking for the transparency color
- for (int xCtr = 0; xCtr < copyRect.width(); ++xCtr)
- if (srcPtr[xCtr] != transparentColor) destPtr[xCtr] = srcPtr[xCtr];
- }
-
- srcPtr += src->width();
- destPtr += width();
- }
-
- src->freeData();
-}
-
-/**
- * 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,
- M4Surface *depthsSurface, int scale, int transparentColor) {
-
- if (scale == 100) {
- // Copy the specified area
- Common::Rect copyRect(0, 0, src->width(), src->height());
-
- if (destX < 0) {
- copyRect.left += -destX;
- destX = 0;
- } else if (destX + copyRect.width() > w) {
- copyRect.right -= destX + copyRect.width() - w;
- }
- if (destY < 0) {
- copyRect.top += -destY;
- destY = 0;
- } else if (destY + copyRect.height() > h) {
- copyRect.bottom -= destY + copyRect.height() - h;
- }
-
- if (!copyRect.isValidRect())
- return;
-
- byte *data = src->getBasePtr();
- byte *srcPtr = data + (src->width() * copyRect.top + copyRect.left);
- byte *depthsData = depthsSurface->getBasePtr();
- byte *depthsPtr = depthsData + (depthsSurface->pitch * destY) + destX;
- byte *destPtr = (byte *)pixels + (destY * pitch) + destX;
-
- // 100% scaling variation
- for (int rowCtr = 0; rowCtr < copyRect.height(); ++rowCtr) {
- // Copy each byte one at a time checking against the depth
- for (int xCtr = 0; xCtr < copyRect.width(); ++xCtr) {
- if ((depth <= (depthsPtr[xCtr] & 0x7f)) && (srcPtr[xCtr] != transparentColor))
- destPtr[xCtr] = srcPtr[xCtr];
- }
-
- srcPtr += src->width();
- depthsPtr += depthsSurface->width();
- destPtr += width();
- }
-
- src->freeData();
- depthsSurface->freeData();
- return;
- }
-
- // Start of draw logic for scaled sprites
- const byte *srcPixelsP = src->getBasePtr();
-
- int destRight = this->width() - 1;
- int destBottom = this->height() - 1;
- bool normalFrame = true; // TODO: false for negative frame numbers
- int frameWidth = src->width();
- int frameHeight = src->height();
-
- int highestDim = MAX(frameWidth, frameHeight);
- bool lineDist[MADS_SURFACE_WIDTH];
- int distIndex = 0;
- int distXCount = 0, distYCount = 0;
-
- int distCtr = 0;
- do {
- distCtr += scale;
- if (distCtr < 100) {
- lineDist[distIndex] = false;
- } else {
- lineDist[distIndex] = true;
- distCtr -= 100;
-
- if (distIndex < frameWidth)
- ++distXCount;
-
- if (distIndex < frameHeight)
- ++distYCount;
- }
- } while (++distIndex < highestDim);
-
- destX -= distXCount / 2;
- destY -= distYCount - 1;
-
- // Check x bounding area
- int spriteLeft = 0;
- int spriteWidth = distXCount;
- int widthAmount = destX + distXCount - 1;
-
- if (destX < 0) {
- spriteWidth += destX;
- spriteLeft -= destX;
- }
- widthAmount -= destRight;
- if (widthAmount > 0)
- spriteWidth -= widthAmount;
-
- int spriteRight = spriteLeft + spriteWidth;
- if (spriteWidth <= 0)
- return;
- if (!normalFrame) {
- destX += distXCount - 1;
- spriteLeft = -(distXCount - spriteRight);
- spriteRight = (-spriteLeft + spriteWidth);
- }
-
- // Check y bounding area
- int spriteTop = 0;
- int spriteHeight = distYCount;
- int heightAmount = destY + distYCount - 1;
-
- if (destY < 0) {
- spriteHeight += destY;
- spriteTop -= destY;
- }
- heightAmount -= destBottom;
- if (heightAmount > 0)
- spriteHeight -= heightAmount;
- int spriteBottom = spriteTop + spriteHeight;
-
- if (spriteHeight <= 0)
- return;
-
- byte *destPixelsP = this->getBasePtr(destX + spriteLeft, destY + spriteTop);
- const byte *depthPixelsP = depthsSurface->getBasePtr(destX + spriteLeft, destY + spriteTop);
-
- spriteLeft = (spriteLeft * (normalFrame ? 1 : -1));
-
- // Loop through the lines of the sprite
- for (int yp = 0, sprY = -1; yp < frameHeight; ++yp, srcPixelsP += src->pitch) {
- if (!lineDist[yp])
- // Not a display line, so skip it
- continue;
- // Check whether the sprite line is in the display range
- ++sprY;
- if ((sprY >= spriteBottom) || (sprY < spriteTop))
- continue;
-
- // Found a line to display. Loop through the pixels
- const byte *srcP = srcPixelsP;
- const byte *depthP = depthPixelsP;
- byte *destP = destPixelsP;
- for (int xp = 0, sprX = 0; xp < frameWidth; ++xp, ++srcP) {
- if (xp < spriteLeft)
- // Not yet reached start of display area
- continue;
- if (!lineDist[sprX++])
- // Not a display pixel
- continue;
-
- if ((*srcP != transparentColor) && (depth <= (*depthP & 0x7f)))
- *destP = *srcP;
-
- ++destP;
- ++depthP;
- }
-
- // Move to the next destination line
- destPixelsP += this->pitch;
- depthPixelsP += depthsSurface->pitch;
- }
-
- src->freeData();
- depthsSurface->freeData();
- this->freeData();
-}
-
-void M4Surface::loadBackgroundRiddle(const char *sceneName) {
- char resourceName[20];
- Common::SeekableReadStream *stream;
- // Loads a Riddle scene
- sprintf(resourceName, "%s.tt", sceneName);
- stream = _vm->_resourceManager->get(resourceName);
- m4LoadBackground(stream);
- _vm->_resourceManager->toss(resourceName);
-}
-
-void M4Surface::loadBackground(int sceneNumber, RGBList **palData) {
- if (_vm->isM4() || (_vm->getGameType() == GType_RexNebular)) {
- char resourceName[20];
- Common::SeekableReadStream *stream;
-
- if (_vm->getGameType() == GType_RexNebular) {
- // Load Rex Nebular screen
- bool hasPalette = palData != NULL;
- if (!hasPalette)
- palData = &_rgbList;
-
- sprintf(resourceName, "rm%d.art", sceneNumber);
- stream = _vm->_resourceManager->get(resourceName);
- rexLoadBackground(stream, palData);
-
- if (!hasPalette) {
- _vm->_palette->addRange(_rgbList);
- this->translate(_rgbList);
- }
- } else {
- // Loads M4 game scene
- if (palData)
- *palData = NULL;
- sprintf(resourceName, "%i.tt", sceneNumber);
- stream = _vm->_resourceManager->get(resourceName);
- m4LoadBackground(stream);
- }
-
- _vm->_resourceManager->toss(resourceName);
-
- } else {
- madsLoadBackground(sceneNumber, palData);
- }
-}
-
-void M4Surface::madsLoadBackground(int roomNumber, RGBList **palData) {
- // Get a MadsPack reference to the tile set and mapping
- char resourceName[20];
- int i;
-
- // Uncompressed tile map resource
- sprintf(resourceName, "rm%d.mm", roomNumber);
- MadsPack tileMapFile(resourceName, _vm);
- Common::SeekableReadStream *mapStream = tileMapFile.getItemStream(0);
-
- // Get the details of the tiles and map
- mapStream->readUint32LE();
- int tileCountX = mapStream->readUint16LE();
- int tileCountY = mapStream->readUint16LE();
- int tileWidthMap = mapStream->readUint16LE();
- int tileHeightMap = mapStream->readUint16LE();
- int screenWidth = mapStream->readUint16LE();
- int screenHeight = mapStream->readUint16LE();
- int tileCountMap = tileCountX * tileCountY;
- delete mapStream;
-
- // Obtain tile map information
- typedef Common::List<Common::SharedPtr<M4Surface> > TileSetList;
- typedef TileSetList::iterator TileSetIterator;
- TileSetList tileSet;
- uint16 *tileMap = new uint16[tileCountMap];
- mapStream = tileMapFile.getItemStream(1);
- for (i = 0; i < tileCountMap; ++i)
- tileMap[i] = mapStream->readUint16LE();
- delete mapStream;
- _vm->res()->toss(resourceName);
-
- // --------------------------------------------------------------------------------
-
- // Tile map data, which needs to be kept compressed, as the tile offsets refer to
- // the compressed data. Each tile is then uncompressed separately
- sprintf(resourceName, "rm%d.tt", roomNumber);
- Common::SeekableReadStream *tileDataComp = _vm->_resourceManager->get(resourceName);
- MadsPack tileData(tileDataComp);
- Common::SeekableReadStream *tileDataUncomp = tileData.getItemStream(0);
-
- // Validate that the data matches between the tiles and tile map file and is valid
- int tileCount = tileDataUncomp->readUint16LE();
- int tileWidth = tileDataUncomp->readUint16LE();
- int tileHeight = tileDataUncomp->readUint16LE();
- delete tileDataUncomp;
- assert(tileCountMap == tileCount);
- assert(tileWidth == tileWidthMap);
- assert(tileHeight == tileHeightMap);
- assert(screenWidth == _vm->_screen->width());
- assert(screenHeight <= _vm->_screen->height());
-
- // --------------------------------------------------------------------------------
-
- // Get the palette to use
- tileDataUncomp = tileData.getItemStream(2);
- // Set palette
- if (!palData) {
- _vm->_palette->setMadsPalette(tileDataUncomp, 4);
- } else {
- int numColors;
- RGB8 *rgbList = _vm->_palette->decodeMadsPalette(tileDataUncomp, &numColors);
- *palData = new RGBList(numColors, rgbList, true);
- }
- delete tileDataUncomp;
-
- // --------------------------------------------------------------------------------
-
- // Get tile data
-
- tileDataUncomp = tileData.getItemStream(1);
- FabDecompressor fab;
- uint32 compressedTileDataSize = 0;
-
- for (i = 0; i < tileCount; i++) {
- tileDataUncomp->seek(i * 4, SEEK_SET);
- uint32 tileOfs = tileDataUncomp->readUint32LE();
- M4Surface* newTile = new M4Surface(tileWidth, tileHeight);
-
- if (i == tileCount - 1)
- compressedTileDataSize = tileDataComp->size() - tileOfs;
- else
- compressedTileDataSize = tileDataUncomp->readUint32LE() - tileOfs;
-
- //debugCN(kDebugGraphics, "Tile: %i, compressed size: %i\n", i, compressedTileDataSize);
-
- newTile->clear();
-
- byte *compressedTileData = new byte[compressedTileDataSize];
-
- tileDataComp->seek(tileData.getDataOffset() + tileOfs, SEEK_SET);
- tileDataComp->read(compressedTileData, compressedTileDataSize);
-
- fab.decompress(compressedTileData, compressedTileDataSize, (byte*)newTile->pixels, tileWidth * tileHeight);
- tileSet.push_back(TileSetList::value_type(newTile));
- delete[] compressedTileData;
- }
-
- delete tileDataUncomp;
-
- // --------------------------------------------------------------------------------
-
- // Loop through the mapping data to place the tiles on the screen
-
- uint16 *tIndex = &tileMap[0];
- for (int y = 0; y < tileCountY; y++) {
- for (int x = 0; x < tileCountX; x++) {
- int tileIndex = *tIndex++;
- assert(tileIndex < tileCount);
- TileSetIterator tile = tileSet.begin();
- for (i = 0; i < tileIndex; i++)
- ++tile;
- ((*tile).get())->copyTo(this, x * tileWidth, y * tileHeight);
- }
- }
- tileSet.clear();
- _vm->res()->toss(resourceName);
-}
-
-void M4Surface::rexLoadBackground(Common::SeekableReadStream *source, RGBList **palData) {
- MadsPack packData(source);
- Common::SeekableReadStream *sourceUnc = packData.getItemStream(0);
-
- int sceneWidth = sourceUnc->readUint16LE();
- int sceneHeight = sourceUnc->readUint16LE();
- int sceneSize = sceneWidth * sceneHeight;
-
- // Set palette
- if (!palData) {
- _vm->_palette->setMadsPalette(sourceUnc, 4);
- } else {
- int numColors;
- RGB8 *rgbList = _vm->_palette->decodeMadsPalette(sourceUnc, &numColors);
- *palData = new RGBList(numColors, rgbList, true);
- }
- delete sourceUnc;
-
- // Get the raw data for the background
- sourceUnc = packData.getItemStream(1);
- assert((int)sourceUnc->size() >= sceneSize);
-
- create(sceneWidth, sceneHeight, Graphics::PixelFormat::createFormatCLUT8());
- byte *pData = (byte *)pixels;
- sourceUnc->read(pData, sceneSize);
-
- freeData();
- delete sourceUnc;
-}
-
-#undef COL_TRANS
-
-void M4Surface::m4LoadBackground(Common::SeekableReadStream *source) {
- M4Surface *tileBuffer = new M4Surface();
- uint curTileX = 0, curTileY = 0;
- int clipX = 0, clipY = 0;
- RGB8 palette[256];
-
- source->readUint32LE(); // magic, unused
- /*uint32 size =*/ source->readUint32LE();
- uint32 widthVal = source->readUint32LE();
- uint32 heightVal = source->readUint32LE();
- uint32 tilesX = source->readUint32LE();
- uint32 tilesY = source->readUint32LE();
- uint32 tileWidth = source->readUint32LE();
- uint32 tileHeight = source->readUint32LE();
- uint8 blackIndex = 0;
-
- // Debug
- //debugCN(kDebugGraphics, "loadBackground(): %dx%d picture (%d bytes) - %dx%d tiles of size %dx%d\n",
- // widthVal, heightVal, size, tilesX, tilesY, tileWidth, tileHeight);
-
- // BGR data, which is converted to RGB8
- for (uint i = 0; i < 256; i++) {
- palette[i].b = source->readByte() << 2;
- palette[i].g = source->readByte() << 2;
- palette[i].r = source->readByte() << 2;
- // FIXME - Removed u field from RGB8 as the OSystem palette is now RGB.
- // If this is needed, then the system setPalette() call will need changing to skip this.
- uint8 u = source->readByte() << 2;
- if (u != 0)
- debugC(1, kDebugGraphics, "Unused u field in Palette data non-zero: %d", u);
-
- if ((blackIndex == 0) && !palette[i].r && !palette[i].g && !palette[i].b)
- blackIndex = i;
- }
-
- _vm->_palette->setPalette(palette, 0, 256);
-
- // resize or create the surface
- // note that the height of the scene in game scenes is smaller than 480, as the bottom part of the
- // screen is the inventory
- assert(width() == (int)widthVal);
- //debugCN(kDebugGraphics, "width(): %d, widthVal: %d, height(): %d, heightVal: %d\n", width(), widthVal, height(), heightVal);
-
- tileBuffer->create(tileWidth, tileHeight, Graphics::PixelFormat::createFormatCLUT8());
-
- for (curTileY = 0; curTileY < tilesY; curTileY++) {
- clipY = MIN(heightVal, (1 + curTileY) * tileHeight) - (curTileY * tileHeight);
-
- for (curTileX = 0; curTileX < tilesX; curTileX++) {
- clipX = MIN(widthVal, (1 + curTileX) * tileWidth) - (curTileX * tileWidth);
-
- // Read a tile and copy it to the destination surface
- source->read(tileBuffer->pixels, tileWidth * tileHeight);
- Common::Rect srcBounds(0, 0, clipX, clipY);
- copyFrom(tileBuffer, srcBounds, curTileX * tileWidth, curTileY * tileHeight);
- }
- }
-
- if (heightVal < (uint)height())
- fillRect(Common::Rect(0, heightVal, width(), height()), blackIndex);
-
- delete tileBuffer;
-}
-
-void M4Surface::madsLoadInterface(const Common::String &filename) {
- MadsPack intFile(filename.c_str(), _vm);
- RGB8 *palette = new RGB8[16];
-
- // Chunk 0, palette
- Common::SeekableReadStream *intStream = intFile.getItemStream(0);
-
- for (int i = 0; i < 16; i++) {
- palette[i].r = intStream->readByte() << 2;
- palette[i].g = intStream->readByte() << 2;
- palette[i].b = intStream->readByte() << 2;
- intStream->readByte();
- intStream->readByte();
- intStream->readByte();
- }
- _rgbList = new RGBList(16, palette, true);
- delete intStream;
-
- // Chunk 1, data
- intStream = intFile.getItemStream(1);
- create(320, 44, Graphics::PixelFormat::createFormatCLUT8());
- intStream->read(pixels, 320 * 44);
- delete intStream;
-
- // Translate the interface palette
- _vm->_palette->addRange(_rgbList);
- this->translate(_rgbList);
-}
-
-void M4Surface::scrollX(int xAmount) {
- if (xAmount == 0)
- return;
-
- byte buffer[80];
- int direction = (xAmount > 0) ? -1 : 1;
- int xSize = ABS(xAmount);
- assert(xSize <= 80);
-
- byte *srcP = (byte *)getBasePtr(0, 0);
-
- for (int y = 0; y < height(); ++y, srcP += pitch) {
- if (direction < 0) {
- // Copy area to be overwritten
- Common::copy(srcP, srcP + xSize, &buffer[0]);
- // Shift the remainder of the line over the given area
- Common::copy(srcP + xSize, srcP + width(), srcP);
- // Move buffered area to the end of the line
- Common::copy(&buffer[0], &buffer[xSize], srcP + width() - xSize);
- } else {
- // Copy area to be overwritten
- Common::copy_backward(srcP + width() - xSize, srcP + width(), &buffer[80]);
- // Shift the remainder of the line over the given area
- Common::copy_backward(srcP, srcP + width() - xSize, srcP + width());
- // Move buffered area to the start of the line
- Common::copy_backward(&buffer[80 - xSize], &buffer[80], srcP + xSize);
- }
- }
-}
-
-void M4Surface::scrollY(int yAmount) {
- if (yAmount == 0)
- return;
-
- int direction = (yAmount > 0) ? 1 : -1;
- int ySize = ABS(yAmount);
- assert(ySize < (height() / 2));
- assert(width() == pitch);
-
- int blockSize = ySize * width();
- byte *tempData = (byte *)malloc(blockSize);
- byte *pixelsP = (byte *)getBasePtr(0, 0);
-
- if (direction > 0) {
- // Buffer the lines to be overwritten
- byte *srcP = (byte *)getBasePtr(0, height() - ySize);
- Common::copy(srcP, srcP + (pitch * ySize), tempData);
- // Vertically shift all the lines
- Common::copy_backward(pixelsP, pixelsP + (pitch * (height() - ySize)),
- pixelsP + (pitch * height()));
- // Transfer the buffered lines top the top of the screen
- Common::copy(tempData, tempData + blockSize, pixelsP);
- } else {
- // Buffer the lines to be overwritten
- Common::copy(pixelsP, pixelsP + (pitch * ySize), tempData);
- // 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)));
- }
-
- ::free(tempData);
-}
-
-
-void M4Surface::translate(RGBList *list, bool isTransparent) {
- byte *p = getBasePtr(0, 0);
- byte *palIndexes = list->palIndexes();
-
- for (int i = 0; i < width() * height(); ++i, ++p) {
- if (!isTransparent || (*p != TRANSPARENT_COLOR_INDEX)) {
- if (*p < list->size())
- *p = palIndexes[*p];
- else
- warning("Pal index %d exceeds list size %d", *p, list->size());
- }
- }
-
- freeData();
-}
-
-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) {
- const byte *srcP = getBasePtr(width() - 1, y);
- for (int x = 0; x < width(); ++x)
- *destP++ = *srcP--;
- }
-
- return dest;
-}
-
-//--------------------------------------------------------------------------
-// Palette class
-//
-
-#define GREEN_START 32
-#define NUM_GREENS 32
-#define GREEN_END (GREEN_START + NUM_GREENS - 1)
-#define NORMAL_START 64
-#define NORMAL_END 255
-#define NUM_NORMAL (NORMAL_END - NORMAL_START + 1)
-
-// Support function for creating a list of palette indexes to change entries in the shaded range to
-
-static void makeTranslationList(RGB8 *palData, byte transList[NUM_GREENS]) {
- int i, j, minDistance;
- byte bestIndex;
-
- for (i = 0; i < NUM_GREENS; ++i) {
- bestIndex = NORMAL_START;
- minDistance = 255;
-
- uint8 findCol = palData[GREEN_START + i].g;
-
- // Find the closest matching palette color
- for (j = NORMAL_START; j <= NORMAL_END; ++j) {
- int greenVal = palData[j].g;
- if (ABS(findCol - greenVal) < minDistance) {
- minDistance = ABS(findCol - greenVal);
- bestIndex = j;
- }
-
- if (minDistance == 0)
- break;
- }
-
- transList[i] = bestIndex;
- }
-}
-
-// Support function for fading in or out
-
-static void fadeRange(MadsM4Engine *vm, RGB8 *srcPal, RGB8 *destPal, int startIndex, int endIndex,
- int numSteps, uint delayAmount) {
- RGB8 tempPal[256];
-
- // perform the fade
- for (int stepCtr = 1; stepCtr <= numSteps; ++stepCtr) {
- // Delay the specified amount
- uint32 startTime = g_system->getMillis();
- while ((g_system->getMillis() - startTime) < delayAmount) {
- vm->_events->handleEvents();
- g_system->delayMillis(10);
- }
-
- for (int i = startIndex; i <= endIndex; ++i) {
- // Handle the intermediate rgb values for fading
- tempPal[i].r = (byte) (srcPal[i].r + (destPal[i].r - srcPal[i].r) * stepCtr / numSteps);
- tempPal[i].g = (byte) (srcPal[i].g + (destPal[i].g - srcPal[i].g) * stepCtr / numSteps);
- tempPal[i].b = (byte) (srcPal[i].b + (destPal[i].b - srcPal[i].b) * stepCtr / numSteps);
- }
-
- vm->_palette->setPalette(&tempPal[startIndex], startIndex, endIndex - startIndex + 1);
- vm->_viewManager->refreshAll();
- }
-
- // Make sure the end palette exactly matches what is wanted
- vm->_palette->setPalette(&destPal[startIndex], startIndex, endIndex - startIndex + 1);
-}
-
-Palette::Palette(MadsM4Engine *vm) : _vm(vm) {
- reset();
- _fading_in_progress = false;
- Common::set_to(&_usageCount[0], &_usageCount[256], 0);
-}
-
-void Palette::setPalette(const byte *colors, uint start, uint num) {
- g_system->getPaletteManager()->setPalette(colors, start, num);
- reset();
-}
-
-void Palette::setPalette(const RGB8 *colors, uint start, uint num) {
- g_system->getPaletteManager()->setPalette((const byte *)colors, start, num);
- reset();
-}
-
-void Palette::grabPalette(byte *colors, uint start, uint num) {
- g_system->getPaletteManager()->grabPalette(colors, start, num);
-}
-
-void Palette::setEntry(uint index, uint8 r, uint8 g, uint8 b) {
- RGB8 c;
- c.r = r;
- c.g = g;
- c.b = b;
- g_system->getPaletteManager()->setPalette((const byte *)&c, index, 1);
-}
-
-uint8 Palette::palIndexFromRgb(byte r, byte g, byte b, RGB8 *paletteData) {
- byte index = 0;
- int32 minDist = 0x7fffffff;
- RGB8 palData[256];
- int Rdiff, Gdiff, Bdiff;
-
- if (paletteData == NULL) {
- g_system->getPaletteManager()->grabPalette((byte *)palData, 0, 256);
- paletteData = &palData[0];
- }
-
- for (int palIndex = 0; palIndex < 256; ++palIndex) {
- Rdiff = r - paletteData[palIndex].r;
- Gdiff = g - paletteData[palIndex].g;
- Bdiff = b - paletteData[palIndex].b;
-
- if (Rdiff * Rdiff + Gdiff * Gdiff + Bdiff * Bdiff < minDist) {
- minDist = Rdiff * Rdiff + Gdiff * Gdiff + Bdiff * Bdiff;
- index = (uint8)palIndex;
- }
- }
-
- return (uint8)index;
-}
-
-void Palette::reset() {
- RGB8 palData[256];
- g_system->getPaletteManager()->grabPalette((byte *)palData, 0, 256);
-
- BLACK = palIndexFromRgb(0, 0, 0, palData);
- BLUE = palIndexFromRgb(0, 0, 255, palData);
- GREEN = palIndexFromRgb(0, 255, 0, palData);
- CYAN = palIndexFromRgb(0, 255, 255, palData);
- RED = palIndexFromRgb(255, 0, 0, palData);
- VIOLET = palIndexFromRgb(255, 0, 255, palData);
- BROWN = palIndexFromRgb(168, 84, 84, palData);
- LIGHT_GRAY = palIndexFromRgb(168, 168, 168, palData);
- DARK_GRAY = palIndexFromRgb(84, 84, 84, palData);
- LIGHT_BLUE = palIndexFromRgb(0, 0, 127, palData);
- LIGHT_GREEN = palIndexFromRgb(0, 127, 0, palData);
- LIGHT_CYAN = palIndexFromRgb(0, 127, 127, palData);
- LIGHT_RED = palIndexFromRgb(84, 0, 0, palData);
- PINK = palIndexFromRgb(84, 0, 0, palData);
- YELLOW = palIndexFromRgb(0, 84, 84, palData);
- WHITE = palIndexFromRgb(255, 255, 255, palData);
-}
-
-void Palette::fadeToGreen(int numSteps, uint delayAmount) {
- if (_fading_in_progress)
- return;
- _fading_in_progress = true;
- byte translationList[NUM_GREENS];
-
- int i;
- byte *tempP;
- uint8 greenAmount = 0;
- RGB8 *srcPalette = (RGB8 *) &_originalPalette[0];
- RGB8 *destPalette = (RGB8 *) &_fadedPalette[0];
-
- _vm->_palette->grabPalette(srcPalette, 0, 256);
-
- // Create the destination 'greenish' palette to fade to by setting the green component
- // to the average of the RGB bytes, and leaving the Red and Blue parts as 0
-
- Common::copy(&srcPalette[0], &srcPalette[256], &destPalette[0]);
- for (i = 32; i < 256; ++i) {
- byte luminance = (byte)((destPalette[i].r + destPalette[i].g + destPalette[i].b) / 3);
- destPalette[i].g = MIN((byte)255, luminance);
- destPalette[i].r = destPalette[i].b = 0;
- }
-
- // Handle the actual fading
- fadeRange(_vm, srcPalette, destPalette, 21, 255, numSteps, delayAmount);
-
- // Create a translation table to be used in translating pixels in the game surface
- // using palette indexes in the range the range #32-63 into values from #64-255
-
- makeTranslationList(destPalette, translationList);
-
- // Use palette indexes from #32-63 for the range of possible shades
-
- for (i = GREEN_START; i <= GREEN_END; ++i, greenAmount += 8) {
- destPalette[i].g = greenAmount;
- destPalette[i].r = destPalette[i].b = 0;
- }
-
- // Remap all pixels into the #32-63 range
-
- tempP = _vm->_scene->getBasePtr();
- for (int pixelCtr = 0; pixelCtr < _vm->_scene->width() * _vm->_scene->height();
- ++pixelCtr, ++tempP) {
- // If pixel is in #32-63 range already, remap to higher palette entries
- if ((*tempP >= GREEN_START) && (*tempP <= GREEN_END))
- *tempP = translationList[*tempP - GREEN_START];
-
- *tempP = (uint8) (GREEN_START + (destPalette[*tempP].g >> 3));
- }
-
- _vm->_palette->setPalette(&destPalette[GREEN_START], GREEN_START, NUM_GREENS);
- _vm->_viewManager->refreshAll();
- _fading_in_progress = false;
-}
-
-void Palette::fadeFromGreen(int numSteps, uint delayAmount, bool fadeToBlack) {
- if (_fading_in_progress)
- return;
- _fading_in_progress = true;
- RGB8 blackPalette[256];
- RGB8 *fadedPalette = (RGB8 *) &_fadedPalette[0];
- RGB8 *destPalette = (RGB8 *) &_originalPalette[0];
-
- if (fadeToBlack) {
- Common::set_to((byte *)&blackPalette[0], (byte *)&blackPalette[256], 0);
- destPalette = &blackPalette[0];
- }
-
- // Initially restore the faded palette
- _vm->_palette->setPalette(fadedPalette, 0, 256);
- _vm->_viewManager->refreshAll();
-
- // Restore the pixel data from the original screen
- _vm->_scene->update();
-
- // Handle the actual fading
- fadeRange(_vm, fadedPalette, destPalette, GREEN_START, NORMAL_END, numSteps, delayAmount);
-
- _fading_in_progress = false;
-}
-
-void Palette::fadeIn(int numSteps, uint delayAmount, RGBList *destPalette) {
- fadeIn(numSteps, delayAmount, destPalette->data(), destPalette->size());
-}
-
-void Palette::fadeIn(int numSteps, uint delayAmount, RGB8 *destPalette, int numColors) {
- if (_fading_in_progress)
- return;
-
- _fading_in_progress = true;
- RGB8 blackPalette[256];
- Common::set_to((byte *)&blackPalette[0], (byte *)&blackPalette[256], 0);
-
- // Initially set the black palette
- _vm->_palette->setPalette(blackPalette, 0, numColors);
-
- // Handle the actual fading
- fadeRange(_vm, blackPalette, destPalette, 0, numColors - 1, numSteps, delayAmount);
-
- _fading_in_progress = false;
-}
-
-RGB8 *Palette::decodeMadsPalette(Common::SeekableReadStream *palStream, int *numColors) {
- *numColors = palStream->readUint16LE();
- assert(*numColors <= 252);
-
- RGB8 *palData = new RGB8[*numColors];
- Common::set_to((byte *)&palData[0], (byte *)&palData[*numColors], 0);
-
- for (int i = 0; i < *numColors; ++i) {
- byte r = palStream->readByte();
- byte g = palStream->readByte();
- byte b = palStream->readByte();
- palData[i].r = VGA_COLOR_TRANS(r);
- palData[i].g = VGA_COLOR_TRANS(g);
- palData[i].b = VGA_COLOR_TRANS(b);
-
- // The next 3 bytes are unused
- palStream->skip(3);
- }
-
- return palData;
-}
-
-int Palette::setMadsPalette(Common::SeekableReadStream *palStream, int indexStart) {
- int colorCount;
- RGB8 *palData = Palette::decodeMadsPalette(palStream, &colorCount);
- _vm->_palette->setPalette(palData, indexStart, colorCount);
- delete palData;
- return colorCount;
-}
-
-void Palette::setMadsSystemPalette() {
- // Rex Nebular default system palette
- resetColorCounts();
-
- RGB8 palData[4];
- palData[0].r = palData[0].g = palData[0].b = 0;
- palData[1].r = palData[1].g = palData[1].b = 0x54;
- palData[2].r = palData[2].g = palData[2].b = 0xb4;
- palData[3].r = palData[3].g = palData[3].b = 0xff;
-
- setPalette(palData, 0, 4);
- blockRange(0, 4);
-}
-
-void Palette::resetColorCounts() {
- Common::set_to(&_usageCount[0], &_usageCount[256], 0);
-}
-
-void Palette::blockRange(int startIndex, int size) {
- // Use a reference count of -1 to signal a palette index shouldn't be used
- Common::set_to(&_usageCount[startIndex], &_usageCount[startIndex + size], -1);
-}
-
-void Palette::addRange(RGBList *list) {
- RGB8 *data = list->data();
- byte *palIndexes = list->palIndexes();
- RGB8 palData[256];
- g_system->getPaletteManager()->grabPalette((byte *)&palData[0], 0, 256);
- bool paletteChanged = false;
-
- for (int colIndex = 0; colIndex < list->size(); ++colIndex) {
- // Scan through for an existing copy of the RGB value
- int palIndex = -1;
- while (++palIndex < 256) {
- if (_usageCount[palIndex] <= 0)
- // Palette index is to be skipped
- continue;
-
- if ((palData[palIndex].r == data[colIndex].r) &&
- (palData[palIndex].g == data[colIndex].g) &&
- (palData[palIndex].b == data[colIndex].b))
- // Match found
- break;
- }
-
- if (palIndex == 256) {
- // No match found, so find a free slot to use
- palIndex = -1;
- while (++palIndex < 256) {
- if (_usageCount[palIndex] == 0)
- break;
- }
-
- if (palIndex == 256)
- error("addRange - Ran out of palette space to allocate");
-
- palData[palIndex].r = data[colIndex].r;
- palData[palIndex].g = data[colIndex].g;
- palData[palIndex].b = data[colIndex].b;
- paletteChanged = true;
- }
-
- palIndexes[colIndex] = palIndex;
- ++_usageCount[palIndex];
- }
-
- if (paletteChanged) {
- g_system->getPaletteManager()->setPalette((byte *)&palData[0], 0, 256);
- reset();
- }
-}
-
-void Palette::deleteRange(RGBList *list) {
- // Release the reference count on each of the palette entries
- for (int colIndex = 0; colIndex < list->size(); ++colIndex) {
- int palIndex = list->palIndexes()[colIndex];
- assert(_usageCount[palIndex] > 0);
- --_usageCount[palIndex];
- }
-}
-
-void Palette::deleteAllRanges() {
- for (int colIndex = 0; colIndex < 255; ++colIndex)
- _usageCount[colIndex] = 0;
-}
-
-//--------------------------------------------------------------------------
-// Support methods
-
-void decompressRle(byte *rleData, int rleSize, byte *celData, int w, int h) {
- byte *src = rleData;
- byte *dst = celData;
- byte len;
- while (1) {
- len = *src++;
- if (len == 0) {
- len = *src++;
- if (len <= 2) {
- if (len == 1) // end of sprite marker
- break;
- } else {
- while (len--)
- *dst++ = *src++;
- }
- } else {
- while (len--)
- *dst++ = *src;
- src++;
- }
- }
-}
-
-int scaleValue(int value, int scale, int err) {
- int scaled = 0;
- while (value--) {
- err -= scale;
- while (err < 0) {
- scaled++;
- err += 100;
- }
- }
- return scaled;
-}
-
-} // End of namespace M4
diff --git a/engines/m4/graphics.h b/engines/m4/graphics.h
deleted file mode 100644
index f3dde454f3..0000000000
--- a/engines/m4/graphics.h
+++ /dev/null
@@ -1,270 +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 M4_GRAPHICS_H
-#define M4_GRAPHICS_H
-
-#include "common/rect.h"
-#include "common/system.h"
-#include "common/stream.h"
-#include "graphics/surface.h"
-
-#include "m4/globals.h"
-
-namespace M4 {
-
-#define MADS_SURFACE_WIDTH 320
-#define MADS_SURFACE_HEIGHT 156
-#define MADS_SCREEN_HEIGHT 200
-#define MADS_Y_OFFSET ((MADS_SCREEN_HEIGHT - MADS_SURFACE_HEIGHT) / 2)
-
-#define TRANSPARENT_COLOR_INDEX 0xFF
-
-struct BGR8 {
- uint8 b, g, r;
-};
-
-struct RGB8 {
- uint8 r, g, b;
-};
-
-//later use ScummVM's Rect?
-struct M4Rect {
- int32 x1, y1, x2, y2;
-};
-
-class M4Surface;
-
-// RGBList
-// Implements a list of RGB entries
-
-class RGBList {
-private:
- int _size;
- RGB8 *_data;
- byte *_palIndexes;
- bool _freeData;
-public:
- RGBList(int numEntries = 256, RGB8 *srcData = NULL, bool freeData = true);
- ~RGBList();
-
- RGB8 *data() { return _data; }
- byte *palIndexes() { return _palIndexes; }
- int size() { return _size; }
- RGB8 &operator[](int idx) { return _data[idx]; }
- void setRange(int start, int count, const RGB8 *src);
- RGBList *clone() const;
-};
-
-// M4Surface
-// Class representing either a buffered surface or the physical screen.
-
-class M4Sprite;
-
-struct SpriteInfo {
- M4Sprite *sprite;
- int hotX, hotY;
- int width, height;
- int scaleX, scaleY;
- uint8 encoding;
- byte *inverseColorTable;
- RGB8 *palette;
-};
-
-class M4Surface : protected Graphics::Surface {
-private:
- byte _color;
- bool _isScreen;
- RGBList *_rgbList;
- bool _ownsData;
-
- void rexLoadBackground(Common::SeekableReadStream *source, RGBList **palData = NULL);
- void madsLoadBackground(int roomNumber, RGBList **palData = NULL);
- void m4LoadBackground(Common::SeekableReadStream *source);
-public:
- M4Surface(bool isScreen = false) {
- create(g_system->getWidth(), isScreen ? g_system->getHeight() : MADS_SURFACE_HEIGHT, Graphics::PixelFormat::createFormatCLUT8());
- _isScreen = isScreen;
- _rgbList = NULL;
- _ownsData = true;
- }
- M4Surface(int width_, int height_) {
- create(width_, height_, Graphics::PixelFormat::createFormatCLUT8());
- _isScreen = false;
- _rgbList = NULL;
- _ownsData = true;
- }
- M4Surface(int width_, int height_, byte *srcPixels, int pitch_) {
- format = Graphics::PixelFormat::createFormatCLUT8();
- w = width_;
- h = height_;
- pitch = pitch_;
- pixels = srcPixels;
- _rgbList = NULL;
- _ownsData = false;
- }
-
- virtual ~M4Surface();
-
- // loads a .COD file into the M4Surface
- // TODO: maybe move this to the rail system? check where it makes sense
- // The sprite drawing needs this, too, so should be more global.
- void loadCodesM4(Common::SeekableReadStream *source);
- void loadCodesMads(Common::SeekableReadStream *source);
-
- // loads the specified background
- void loadBackground(int sceneNumber, RGBList **palData = NULL);
- void loadBackgroundRiddle(const char *sceneName);
- void madsLoadInterface(int index, RGBList **palData = NULL);
- void madsLoadInterface(const Common::String &filename);
-
- void setColor(byte value) { _color = value; }
- inline byte getColor() const { return _color; }
- void vLine(int x, int y1, int y2);
- void hLine(int x1, int x2, int y);
- void vLineXor(int x, int y1, int y2);
- void hLineXor(int x1, int x2, int y);
- void drawLine(int x1, int y1, int x2, int y2, byte color);
- void frameRect(int x1, int y1, int x2, int y2);
- void fillRect(int x1, int y1, int x2, int y2);
-
- void drawSprite(int x, int y, SpriteInfo &info, const Common::Rect &clipRect);
-
- // Surface methods
- inline Common::Rect bounds() const { return Common::Rect(0, 0, width(), height()); }
- inline int width() const { return w; }
- inline int height() const { return h; }
- inline int getPitch() const { return pitch; }
- void setSize(int sizeX, int sizeY) { create(sizeX, sizeY, Graphics::PixelFormat::createFormatCLUT8()); }
- inline byte *getBasePtr() {
- return (byte *)pixels;
- }
- inline byte *getBasePtr(int x, int y) {
- return (byte *)Graphics::Surface::getBasePtr(x, y);
- }
- inline const byte *getBasePtr(int x, int y) const {
- return (const byte *)Graphics::Surface::getBasePtr(x, y);
- }
- void freeData();
- void clear();
- void reset();
- 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,
- int scale, int transparentColor = -1);
-
- void update() {
- if (_isScreen) {
- g_system->copyRectToScreen((const byte *)pixels, pitch, 0, 0, w, h);
- g_system->updateScreen();
- }
- }
-
- // copyTo methods
- inline void copyTo(M4Surface *dest, int transparentColor = -1) {
- dest->copyFrom(this, Common::Rect(width(), height()), 0, 0, transparentColor);
- }
- inline void copyTo(M4Surface *dest, int x, int y, int transparentColor = -1) {
- dest->copyFrom(this, Common::Rect(width(), height()), x, y, transparentColor);
- }
- inline void copyTo(M4Surface *dest, const Common::Rect &srcBounds, int destX, int destY,
- int transparentColor = -1) {
- dest->copyFrom(this, srcBounds, destX, destY, transparentColor);
- }
- inline void copyTo(M4Surface *dest, int destX, int destY, int depth, M4Surface *depthsSurface, int scale,
- int transparentColor = -1) {
- dest->copyFrom(this, destX, destY, depth, depthsSurface, scale, transparentColor);
- }
-
- void scrollX(int xAmount);
- void scrollY(int yAmount);
-
- void translate(RGBList *list, bool isTransparent = false);
- M4Surface *flipHorizontal() const;
-};
-
-enum FadeType {FT_TO_GREY, FT_TO_COLOR, FT_TO_BLOCK};
-
-class Palette {
-private:
- MadsM4Engine *_vm;
- bool _colorsChanged;
- bool _fading_in_progress;
- byte _originalPalette[256 * 3];
- byte _fadedPalette[256 * 3];
- int _usageCount[256];
-
- void reset();
-public:
- Palette(MadsM4Engine *vm);
-
- void setPalette(const byte *colors, uint start, uint num);
- void setPalette(const RGB8 *colors, uint start, uint num);
- void grabPalette(byte *colors, uint start, uint num);
- void grabPalette(RGB8 *colors, uint start, uint num) {
- grabPalette((byte *)colors, start, num);
- }
- void setEntry(uint index, uint8 r, uint8 g, uint8 b);
- uint8 palIndexFromRgb(byte r, byte g, byte b, RGB8 *paletteData = NULL);
-
- void fadeToGreen(int numSteps, uint delayAmount);
- void fadeFromGreen(int numSteps, uint delayAmount, bool fadeToBlack);
- void fadeIn(int numSteps, uint delayAmount, RGB8 *destPalette, int numColors);
- void fadeIn(int numSteps, uint delayAmount, RGBList *destPalette);
- static RGB8 *decodeMadsPalette(Common::SeekableReadStream *palStream, int *numColors);
- int setMadsPalette(Common::SeekableReadStream *palStream, int indexStart = 0);
- void setMadsSystemPalette();
-
- // Methods used for reference counting color usage
- void resetColorCounts();
- void blockRange(int startIndex, int size);
- void addRange(RGBList *list);
- void deleteRange(RGBList *list);
- void deleteAllRanges();
-
- // Color indexes
- uint8 BLACK;
- uint8 BLUE;
- uint8 GREEN;
- uint8 CYAN;
- uint8 RED;
- uint8 VIOLET;
- uint8 BROWN;
- uint8 LIGHT_GRAY;
- uint8 DARK_GRAY;
- uint8 LIGHT_BLUE;
- uint8 LIGHT_GREEN;
- uint8 LIGHT_CYAN;
- uint8 LIGHT_RED;
- uint8 PINK;
- uint8 YELLOW;
- uint8 WHITE;
-};
-
-void decompressRle(byte *rleData, int rleSize, byte *celData, int w, int h);
-void decompressRle(Common::SeekableReadStream &rleData, byte *celData, int w, int h);
-int scaleValue(int value, int scale, int err);
-
-} // End of namespace M4
-
-#endif
diff --git a/engines/m4/gui.cpp b/engines/m4/gui.cpp
deleted file mode 100644
index 6bedfa7e9b..0000000000
--- a/engines/m4/gui.cpp
+++ /dev/null
@@ -1,1215 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#include "common/events.h"
-#include "common/keyboard.h"
-#include "common/textconsole.h"
-
-#include "m4/globals.h"
-#include "m4/events.h"
-#include "m4/font.h"
-#include "m4/graphics.h"
-#include "m4/viewmgr.h"
-#include "m4/gui.h"
-#include "m4/midi.h"
-#include "m4/scene.h"
-#include "m4/m4.h"
-
-namespace M4 {
-
-//--------------------------------------------------------------------------
-// DialogView class
-//
-// Defines a generic base class for dialogs, that some of the classes
-// in the object hierharchy require as a parent
-//--------------------------------------------------------------------------
-
-void DialogView::close() {
- // Default to simply destroying the given dialog
- _vm->_viewManager->deleteView(this);
-}
-
-//--------------------------------------------------------------------------
-// GUIObject class
-//
-// Defines a generic object that appears in a view
-//--------------------------------------------------------------------------
-
-GUIObject::GUIObject(View *owner, const Common::Rect &bounds) {
- _parent = owner;
- _bounds = bounds;
-}
-
-//--------------------------------------------------------------------------
-// MenuObject class
-//
-// Defines a specialised GUI object that appears in a dialog
-//--------------------------------------------------------------------------
-
-MenuObject::MenuObject(DialogView *owner, int objectId, int xs, int ys, int width, int height,
- bool greyed, bool transparent):
- GUIObject(owner, Common::Rect(xs, ys, xs + width, ys + height)) {
-
- _objectId = objectId;
- _bounds.top = ys;
- _bounds.bottom = ys + height - 1;
- _bounds.left = xs;
- _bounds.right = xs + width - 1;
- _transparent = transparent;
- _objectState = greyed ? OS_GREYED : OS_NORMAL;
- _callback = NULL;
-
- if (transparent) {
- _background = new M4Surface(width, height);
- Common::Rect srcBounds(xs, ys, xs + width - 1, ys + height - 1);
- _background->copyFrom(owner, srcBounds, 0, 0);
- } else {
- _background = NULL;
- }
-}
-
-MenuObject::~MenuObject() {
- delete _background;
-}
-
-void MenuObject::onExecute() {
- // If a callback function has been specified, then execute it
- if (_callback)
- _callback(parent(), this);
-}
-
-//--------------------------------------------------------------------------
-// MenuButton class
-//
-// Defines a button object
-//--------------------------------------------------------------------------
-
-MenuButton::MenuButton(DialogView *owner, int buttonId, int xs, int ys, int width, int height,
- MenuButton::Callback callbackFn, bool greyed, bool transparent,
- ObjectType buttonType):
- MenuObject(owner, buttonId, xs, ys, width, height, greyed, transparent) {
-
- _objectType = buttonType;
- _callback = callbackFn;
-}
-
-bool MenuButton::onEvent(M4EventType event, int32 param, int x, int y, MenuObject *&currentItem) {
- bool redrawFlag = false;
- bool callbackFlag = false;
- bool handledFlag = true;
-
- if (_objectState == OS_GREYED)
- return false;
-
- switch (event) {
- case MEVENT_LEFT_CLICK:
- case MEVENT_DOUBLECLICK:
- if (isInside(x, y)) {
- _objectState = OS_PRESSED;
- if (currentItem != NULL)
- currentItem = this;
- redrawFlag = true;
- } else {
- currentItem = NULL;
- if (_objectState != OS_NORMAL) {
- _objectState = OS_PRESSED;
- redrawFlag = true;
- }
- }
- break;
-
- case MEVENT_LEFT_DRAG:
- case MEVENT_DOUBLECLICK_DRAG:
- if (!currentItem) {
- return true;
- }
- if (isInside(x, y)) {
- if (_objectState != OS_PRESSED) {
- _objectState = OS_PRESSED;
- redrawFlag = true;
- }
- }
- else {
- if (_objectState != OS_MOUSEOVER) {
- _objectState = OS_MOUSEOVER;
- redrawFlag = true;
- }
- }
- break;
-
- case MEVENT_LEFT_RELEASE:
- case MEVENT_DOUBLECLICK_RELEASE:
- if (isInside(x, y)) {
- if (currentItem) {
- callbackFlag = true;
- if (_objectType == OBJTYPE_OM_SWITCH_ON)
- _objectType = OBJTYPE_OM_SWITCH_OFF;
- else if (_objectType == OBJTYPE_OM_SWITCH_OFF)
- _objectType = OBJTYPE_OM_SWITCH_ON;
- }
- else {
- currentItem = this;
- }
-
- _objectState = OS_MOUSEOVER;
- redrawFlag = true;
-
- } else {
- currentItem = NULL;
- _objectState = OS_MOUSEOVER;
- redrawFlag = true;
- handledFlag = false;
- }
- break;
-
- case MEVENT_MOVE:
- if (isInside(x, y)) {
- currentItem = this;
- if (_objectState != OS_MOUSEOVER) {
- _objectState = OS_MOUSEOVER;
- redrawFlag = true;
- }
- }
- else {
- currentItem = NULL;
- if (_objectState != OS_NORMAL) {
- _objectState = OS_NORMAL;
- redrawFlag = true;
- handledFlag = false;
- }
- }
- break;
-
- case MEVENT_LEFT_HOLD:
- case MEVENT_DOUBLECLICK_HOLD:
- break;
-
- default:
- break;
- }
-
- //see if we need to redraw the button
- if (redrawFlag) {
- onRefresh();
-
- // TODO: There may be a more efficient mechanism than refreshing the entire screen
- // when a menu object refreshes itself
- if (parent()->screenFlags().visible)
- _vm->_viewManager->refreshAll();
- }
-
- // If a callback is flagged, then handle it
-
- if (callbackFlag)
- onExecute();
-
- return handledFlag;
-}
-
-void MenuButton::onRefresh() {
- M4Sprite *sprite = NULL;
- SpriteAsset &sprites = *parent()->sprites();
-
- // Switch handling for the various button types
- switch (_objectType) {
- case OBJTYPE_BUTTON:
- sprite = sprites[GM_BUTTON_GREYED + _objectState];
- break;
-
- case OBJTYPE_OM_SWITCH_ON:
- switch (_objectState) {
- case OS_MOUSEOVER:
- sprite = sprites[MENU_SS_SWITCH_ON_MOUSEOVER];
- break;
- case OS_PRESSED:
- sprite = sprites[MENU_SS_SWITCH_ON_PRESSED];
- break;
- default:
- sprite = sprites[MENU_SS_SWITCH_ON_NORMAL];
- break;
- }
- break;
-
- case OBJTYPE_OM_SWITCH_OFF:
- switch (_objectState) {
- case OS_MOUSEOVER:
- sprite = sprites[MENU_SS_SWITCH_OFF_MOUSEOVER];
- break;
- case OS_PRESSED:
- sprite = sprites[MENU_SS_SWITCH_OFF_PRESSED];
- break;
- default:
- sprite = sprites[MENU_SS_SWITCH_OFF_NORMAL];
- break;
- }
- break;
-
- case OBJTYPE_OM_DONE:
- sprite = sprites[OM_DONE_BTN_GREYED + _objectState];
- break;
-
- case OBJTYPE_OM_CANCEL:
- sprite = (_objectState == OS_GREYED) ? sprites[OM_CANCEL_BTN_NORMAL] :
- sprites[OM_CANCEL_BTN_NORMAL + _objectState - 1];
- break;
-
- case OBJTYPE_SL_SAVE:
- sprite = sprites[SL_SAVE_BTN_GREYED + _objectState];
- break;
-
- case OBJTYPE_SL_LOAD:
- sprite = sprites[SL_LOAD_BTN_GREYED + _objectState];
- break;
-
- case OBJTYPE_SL_CANCEL:
- sprite = (_objectState == OS_GREYED) ? sprites[SL_CANCEL_BTN_NORMAL] :
- sprites[SL_CANCEL_BTN_NORMAL + _objectState - 1];
- break;
-
- case OBJTYPE_SL_TEXT:
- switch (_objectState) {
- case OS_MOUSEOVER:
- _vm->_font->current()->setColors(TEXT_COLOR_MOUSEOVER_SHADOW, TEXT_COLOR_MOUSEOVER_FOREGROUND,
- TEXT_COLOR_MOUSEOVER_HILIGHT);
- sprite = sprites[SL_LINE_MOUSEOVER];
- break;
-
- case OS_PRESSED:
- _vm->_font->current()->setColors(TEXT_COLOR_PRESSED_SHADOW, TEXT_COLOR_PRESSED_FOREGROUND,
- TEXT_COLOR_PRESSED_HILIGHT);
- sprite = sprites[SL_LINE_PRESSED];
- break;
-
- case OS_GREYED:
- _vm->_font->current()->setColors(TEXT_COLOR_GREYED_SHADOW, TEXT_COLOR_GREYED_FOREGROUND,
- TEXT_COLOR_GREYED_HILIGHT);
- sprite = sprites[SL_LINE_NORMAL];
- break;
-
- default:
- case OS_NORMAL:
- _vm->_font->current()->setColors(TEXT_COLOR_NORMAL_SHADOW, TEXT_COLOR_NORMAL_FOREGROUND,
- TEXT_COLOR_NORMAL_HILIGHT);
- sprite = sprites[SL_LINE_NORMAL];
- break;
- }
- break;
-
- default:
- error("Unknown object type");
- break;
- }
-
- // If no sprite object was set, then exit without doing anything
- if (!sprite)
- return;
-
- // Draw the button
- if (_transparent) {
- // Transparent button, so restore original background
- if (!_background)
- return;
- else
- _background->copyTo(parent(), _bounds.left, _bounds.top);
- }
-
- sprite->copyTo(parent(), _bounds.left, _bounds.top, 0);
-}
-
-//--------------------------------------------------------------------------
-// MenuHorizSlider class
-//
-// Defines a horizontal slider that allows selection of a percentage
-//--------------------------------------------------------------------------
-
-MenuHorizSlider::MenuHorizSlider(DialogView *owner, int objectId, int xs, int ys,
- int width, int height, int initialPercentage, Callback callbackFn, bool transparent):
- MenuObject(owner, objectId, xs, ys, width, height, false, transparent) {
-
- _objectType = OBJTYPE_SLIDER;
- _callback = callbackFn;
-
- SpriteAsset &sprites = *owner->sprites();
- _sliderState = HSLIDER_THUMB_NORMAL;
- _thumbSize.x = sprites[OM_SLIDER_BTN_NORMAL]->width();
- _thumbSize.y = sprites[OM_SLIDER_BTN_NORMAL]->height();
- _maxThumbX = width - _thumbSize.x;
- _percent = MAX(MIN(initialPercentage, 100), 0);
- _thumbX = initialPercentage * _maxThumbX / 100;
-}
-
-void MenuHorizSlider::onRefresh() {
- // If the slider is transparent, first copy in the background
- if (_transparent) {
- // Transparent button
- if (!_background)
- return;
-
- _background->copyTo(parent(), _bounds.left, _bounds.top, 0);
- }
-
- // Get the thumb sprite for the slider
- SpriteAsset &sprites = *parent()->sprites();
- M4Sprite *sprite = sprites[OM_SLIDER_BTN_NORMAL + _sliderState];
- assert(sprite);
-
- // Fill in the area to the left of the thumbnail
- if (_thumbX > 2) {
- Common::Rect leftBounds(_bounds.left + 3, _bounds.top + 9, _bounds.left + _thumbX,
- _bounds.top + _thumbSize.y - 9);
- parent()->fillRect(leftBounds, SLIDER_BAR_COLOR);
- }
-
- // Draw the thumbnail
- sprite->copyTo(parent(), _bounds.left + _thumbX, _bounds.top, 0);
-}
-
-bool MenuHorizSlider::onEvent(M4EventType event, int32 param, int x, int y, MenuObject *&currentItem) {
- static bool movingFlag = false;
- static int movingX = 0;
- bool redrawFlag = false, handledFlag = false, callbackFlag = false;
-
- if (event == KEVENT_KEY)
- return false;
-
- switch (event) {
- case MEVENT_LEFT_CLICK:
- case MEVENT_DOUBLECLICK:
- if (isInside(x, y) && (x - _bounds.left >= _thumbX) &&
- (x - _bounds.left <= _thumbX + _thumbSize.x - 1)) {
- // The thumbnail has been clicked
- _sliderState = HSLIDER_THUMB_PRESSED;
- movingFlag = true;
- movingX = x;
- currentItem = this;
- redrawFlag = true;
- } else {
- currentItem = NULL;
- _sliderState = HSLIDER_THUMB_NORMAL;
- redrawFlag = true;
- }
- redrawFlag = true;
- break;
-
- case MEVENT_LEFT_DRAG:
- case MEVENT_DOUBLECLICK_DRAG:
- if (!currentItem)
- return true;
-
- if (movingFlag) {
- if (x != movingX) {
- if (x < movingX)
- _thumbX -= MIN(_thumbX, movingX - x);
- else
- _thumbX += MIN(_maxThumbX - _thumbX, x - movingX);
- _percent = _thumbX * 100 / _maxThumbX;
- redrawFlag = callbackFlag = true;
- }
- movingX = CLIP(x, _bounds.left + _thumbX,
- _bounds.left + _thumbX + _thumbSize.x - 1);
- } else {
- currentItem = NULL;
- }
- break;
-
- case MEVENT_LEFT_RELEASE:
- case MEVENT_DOUBLECLICK_RELEASE:
- if (!currentItem)
- return true;
-
- movingFlag = false;
- if (isInside(x, y) && (x - _bounds.left >= _thumbX) &&
- (x - _bounds.left <= _thumbX + _thumbSize.x - 1)) {
- _sliderState = HSLIDER_THUMB_MOUSEOVER;
- currentItem = this;
- } else {
- _sliderState = HSLIDER_THUMB_NORMAL;
- currentItem = NULL;
- }
-
- redrawFlag = true;
- callbackFlag = true;
- break;
-
- case MEVENT_MOVE:
- if (isInside(x, y) && (x - _bounds.left >= _thumbX) &&
- (x - _bounds.left <= _thumbX + _thumbSize.x - 1)) {
- if (_sliderState != HSLIDER_THUMB_MOUSEOVER) {
- _sliderState = HSLIDER_THUMB_MOUSEOVER;
- currentItem = this;
- }
- } else {
- if (_sliderState != HSLIDER_THUMB_NORMAL) {
- _sliderState = HSLIDER_THUMB_NORMAL;
- currentItem = NULL;
- handledFlag = false;
- }
- }
- redrawFlag = true;
- break;
-
- default:
- break;
- }
-
- if (redrawFlag)
- onRefresh();
-
- if (callbackFlag)
- onExecute();
-
- return handledFlag;
-}
-
-//--------------------------------------------------------------------------
-// MenuVertSlider class
-//
-// Defines a vertical slider that's used in the save/load dialog
-//--------------------------------------------------------------------------
-
-MenuVertSlider::MenuVertSlider(DialogView *owner, int objectId, int xs, int ys,
- int width, int height, int initialPercentage, Callback callbackFn, bool transparent):
- MenuObject(owner, objectId, xs, ys, width, height, false, transparent) {
-
- _objectType = OBJTYPE_SLIDER;
- _callback = callbackFn;
-
- SpriteAsset &sprites = *owner->sprites();
- _sliderState = VSLIDER_NONE;
- _thumbSize.x = sprites[SL_SLIDER_BTN_NORMAL]->width();
- _thumbSize.y = sprites[SL_SLIDER_BTN_NORMAL]->height();
- _minThumbY = sprites[SL_UP_BTN_NORMAL]->height() + 1;
- _maxThumbY = sprites[SL_UP_BTN_NORMAL]->height() + sprites[SL_SCROLLBAR]->height() -
- sprites[SL_SLIDER_BTN_NORMAL]->height() - 1;
-
- _percent = MAX(MIN(initialPercentage, 100), 0);
- _thumbY = _minThumbY + ((_percent * (_maxThumbY - _minThumbY)) / 100);
-}
-
-MenuVertSliderState MenuVertSlider::getSliderArea(int y) {
- if (y < _minThumbY)
- return VSLIDER_UP;
- else if (y < _thumbY)
- return VSLIDER_PAGE_UP;
- else if (y < _thumbY + _thumbSize.y)
- return VSLIDER_THUMBNAIL;
- else if (y < _maxThumbY + _thumbSize.y)
- return VSLIDER_PAGE_DOWN;
- else
- return VSLIDER_DOWN;
-}
-
-void MenuVertSlider::onRefresh() {
- // If the slider is transparent, first copy in the background
- if (_transparent) {
- // Transparent button
- if (!_background)
- return;
-
- _background->copyTo(parent(), _bounds.left, _bounds.top, 0);
- }
-
- // Get the various needed sprites
- SpriteAsset &sprites = *parent()->sprites();
- M4Sprite *barSprite = sprites[SL_SCROLLBAR];
- M4Sprite *thumbSprite = sprites[SL_SLIDER_BTN_NORMAL];
- M4Sprite *upSprite = sprites[SL_UP_BTN_NORMAL];
- M4Sprite *downSprite = sprites[SL_DOWN_BTN_NORMAL];
-
- if (_objectState == OS_GREYED) {
- upSprite = sprites[SL_UP_BTN_GREYED];
- downSprite = sprites[SL_DOWN_BTN_GREYED];
- thumbSprite = NULL;
-
- } else if (_objectState == OS_MOUSEOVER) {
- if (_sliderState == VSLIDER_UP)
- upSprite = sprites[SL_UP_BTN_MOUSEOVER];
- else if (_sliderState == VSLIDER_THUMBNAIL)
- thumbSprite = sprites[SL_SLIDER_BTN_MOUSEOVER];
- else if (_sliderState == VSLIDER_DOWN)
- downSprite = sprites[SL_DOWN_BTN_MOUSEOVER];
- }
- else if (_objectState == OS_PRESSED) {
- if (_sliderState == VSLIDER_UP)
- upSprite = sprites[SL_UP_BTN_PRESSED];
- else if (_sliderState == VSLIDER_THUMBNAIL)
- thumbSprite = sprites[SL_SLIDER_BTN_PRESSED];
- else if (_sliderState == VSLIDER_DOWN)
- downSprite = sprites[SL_DOWN_BTN_PRESSED];
- }
-
- // Draw the sprites
- upSprite->copyTo(parent(), _bounds.left, _bounds.top, 0);
- barSprite->copyTo(parent(), _bounds.left, _bounds.top + upSprite->height(), 0);
- downSprite->copyTo(parent(), _bounds.left, _bounds.top + upSprite->height() + barSprite->height(), 0);
- if (thumbSprite)
- thumbSprite->copyTo(parent(), _bounds.left, _bounds.top + _thumbY, 0);
-}
-
-bool MenuVertSlider::onEvent(M4EventType event, int32 param, int x, int y, MenuObject *&currentItem) {
- static bool movingFlag = false;
- static int movingY = 0;
- static uint32 callbackTime;
- MenuVertSliderState tempState;
- int delta;
- uint32 currentTime = g_system->getMillis();
- bool redrawFlag = false;
- bool handledFlag = true;
- bool callbackFlag = false;
-
- if (event == KEVENT_KEY)
- return false;
-
- if (_objectState == OS_GREYED) {
- currentItem = NULL;
- return false;
- }
-
- switch (event) {
- case MEVENT_LEFT_CLICK:
- case MEVENT_DOUBLECLICK:
- if (isInside(x, y)) {
- currentItem = this;
- tempState = getSliderArea(y - _bounds.top);
- if (tempState == VSLIDER_THUMBNAIL) {
- movingFlag = true;
- movingY = y;
- }
- if ((tempState == VSLIDER_PAGE_UP) || (tempState == VSLIDER_PAGE_DOWN)) {
- _sliderState = tempState;
- setState(OS_NORMAL);
- } else {
- _sliderState = tempState;
- setState(OS_PRESSED);
- redrawFlag = true;
- }
- callbackFlag = true;
- } else {
- currentItem = NULL;
- setState(OS_NORMAL);
- redrawFlag = true;
- }
- break;
-
- case MEVENT_LEFT_DRAG:
- case MEVENT_DOUBLECLICK_DRAG:
- if (!currentItem)
- return true;
-
- if (movingFlag) {
- if (y < movingY) {
- delta = MIN(_thumbY - _minThumbY, movingY - y);
- if (delta > 0) {
- _thumbY -= delta;
- _percent = ((_thumbY - _minThumbY) * 100) / (_maxThumbY - _minThumbY);
- redrawFlag = true;
- callbackFlag = true;
- }
- }
- else if (y > movingY) {
- delta = MIN(_maxThumbY - _thumbY, y - movingY);
- if (delta > 0) {
- _thumbY += delta;
- _percent = ((_thumbY - _minThumbY) * 100) / (_maxThumbY - _minThumbY);
- redrawFlag = true;
- callbackFlag = true;
- }
- }
- movingY = y;
-
- if (movingY < (_thumbY + _bounds.top))
- movingY = _thumbY + _bounds.top;
- else if (movingY > (_bounds.top + _thumbY + _thumbSize.y - 1))
- movingY = _bounds.top + _thumbY + _thumbSize.y - 1;
-
- } else {
- if (isInside(x, y)) {
- tempState = getSliderArea(y - _bounds.top);
- if (_sliderState == tempState) {
- if ((tempState != VSLIDER_PAGE_UP) && (tempState != VSLIDER_PAGE_DOWN) &&
- (_objectState != OS_PRESSED)) {
- _sliderState = tempState;
- setState(OS_PRESSED);
- redrawFlag = true;
- }
- if (currentTime - callbackTime > 100)
- callbackFlag = true;
-
- } else {
- if (_objectState != OS_MOUSEOVER)
- setState(OS_MOUSEOVER);
- redrawFlag = true;
- }
- callbackFlag = true;
-
- } else {
- if (_objectState != OS_MOUSEOVER) {
- setState(OS_MOUSEOVER);
- redrawFlag = true;
- }
- }
- }
- break;
-
- case MEVENT_LEFT_RELEASE:
- case MEVENT_DOUBLECLICK_RELEASE:
- movingFlag = false;
- if (isInside(x, y)) {
- tempState = getSliderArea(y - _bounds.top);
- if ((tempState == VSLIDER_PAGE_UP) || (tempState == VSLIDER_PAGE_DOWN))
- setState(OS_NORMAL);
- else {
- setState(OS_MOUSEOVER);
- currentItem = this;
- }
- } else {
- setState(OS_NORMAL);
- currentItem = NULL;
- }
-
- redrawFlag = true;
- if (parent()->getMenuType() == LOAD_MENU)
- updateThumbnails();
- break;
-
- case MEVENT_MOVE:
- if (isInside(x, y)) {
- currentItem = this;
- tempState = getSliderArea(y - _bounds.top);
- if (_sliderState != tempState) {
- if ((tempState == VSLIDER_PAGE_UP) || (tempState == VSLIDER_PAGE_DOWN))
- _objectState = OS_NORMAL;
- else {
- _sliderState = tempState;
- _objectState = OS_MOUSEOVER;
- }
- redrawFlag = true;
- }
- } else {
- currentItem = NULL;
-
- if (_objectState != OS_NORMAL) {
- _objectState = OS_NORMAL;
- redrawFlag = true;
- handledFlag = false;
- }
- }
- break;
-
- case MEVENT_LEFT_HOLD:
- case MEVENT_DOUBLECLICK_HOLD:
- if (!currentItem)
- return true;
-
- if (isInside(x, y)) {
- tempState = getSliderArea(y - _bounds.top);
-
- if (_sliderState == tempState) {
- if (currentTime - callbackTime > 100)
- callbackFlag = true;
- }
- }
- break;
-
- default:
- break;
- }
-
- if (redrawFlag)
- onRefresh();
-
- if (callbackFlag) {
- callbackTime = currentTime;
- onExecute();
- }
-
- return handledFlag;
-}
-
-void MenuVertSlider::setPercentage(int value) {
- _percent = value;
- _thumbY = _minThumbY + ((_percent * (_maxThumbY - _minThumbY)) / 100);
- onRefresh();
-}
-
-//--------------------------------------------------------------------------
-// MenuMessage class
-//
-// Defines a message menu object
-//--------------------------------------------------------------------------
-
-MenuMessage::MenuMessage(DialogView *owner, int objectId, int xs, int ys, int width, int height,
- bool transparent):
- MenuObject(owner, objectId, xs, ys, width, height, false, transparent) {
-}
-
-void MenuMessage::onRefresh() {
- SpriteAsset &sprites = *parent()->sprites();
- M4Surface *sprite = NULL;
-
- // Get the correct sprite to use
- switch (_objectId) {
- case SLTAG_SAVELOAD_LABEL:
- sprite = (parent()->getMenuType() == SAVE_MENU) ? sprites[SL_SAVE_LABEL] :
- sprites[SL_LOAD_LABEL];
- break;
- }
- assert(sprite);
-
- // Draw the sprite
- if (_transparent) {
- // Transparent button
- if (!_background)
- return;
-
- // Restore original background and then do a transparent copy of the sprite
- _background->copyTo(parent(), _bounds.left, _bounds.top);
- }
-
- sprite->copyTo(parent(), _bounds.left, _bounds.top, 0);
-}
-
-//--------------------------------------------------------------------------
-// MenuImage class
-//
-// Defines a menu item that displays a given surface
-//--------------------------------------------------------------------------
-
-MenuImage::MenuImage(DialogView *owner, int objectId, int xs, int ys, int width, int height,
- M4Surface *image, bool transparent):
- MenuObject(owner, objectId, xs, ys, width, height, false, transparent) {
-
- _sprite = image;
-}
-
-void MenuImage::onRefresh() {
- if (!_sprite)
- return;
-
- // Draw the sprite
- if (_transparent) {
- // Transparent button
- if (!_background)
- return;
-
- // Restore original background and then do a transparent copy of the sprite
- _background->copyTo(parent(), _bounds.left, _bounds.top);
- }
-
- _sprite->copyTo(parent(), _bounds.left + (_bounds.width() - _sprite->width()) / 2,
- _bounds.top + (_bounds.height() - _sprite->height()) / 2, 0);
-}
-
-//--------------------------------------------------------------------------
-// MenuSaveLoadText class
-//
-// Defines a save/load dialog text entry
-//--------------------------------------------------------------------------
-
-MenuSaveLoadText::MenuSaveLoadText(DialogView *owner, int textId, int xs, int ys,
- int width, int height, Callback callbackFn, bool greyed, bool transparent,
- bool loadFlag, const char *displayText, int displayValue):
- MenuButton(owner, textId, xs, ys, width, height, callbackFn, greyed, transparent, OBJTYPE_SL_TEXT) {
-
- _loadFlag = loadFlag;
- _displayText = displayText;
- _displayValue = displayValue;
- _index = textId - SLTAG_SLOTS_START;
- _visible = true;
-}
-
-void MenuSaveLoadText::onRefresh() {
- if (!_visible) return;
- _vm->_font->setFont(FONT_MENU);
- MenuButton::onRefresh();
-
- if ((_objectType == OBJTYPE_SL_TEXT) && (_displayText != NULL)) {
- int xp = _bounds.left + 4;
- if (_displayValue != 0) {
- char tempBuffer[5];
- sprintf(tempBuffer, "%02d", _displayValue);
- _vm->_font->current()->writeString(_parent, tempBuffer, xp, _bounds.top + 1, 0, -1);
- xp = _bounds.left + 26;
- }
-
- _vm->_font->current()->writeString(_parent, _displayText, xp, _bounds.top + 1, 0, -1);
- }
-}
-
-bool MenuSaveLoadText::onEvent(M4::M4EventType event, int32 param, int x, int y, M4::MenuObject *&currentItem) {
- if (!_visible) return false;
- bool handledFlag = MenuButton::onEvent(event, param, x, y, currentItem);
-
- // Further handling will only be done when in load mode and a slot hasn't been selected
- if (!_loadFlag || (parent()->_selectedSlot != -1))
- return handledFlag;
-
- // Only handling for certain event types
- if ((event != MEVENT_MOVE) && (event != MEVENT_LEFT_DRAG) &&
- (event != MEVENT_LEFT_RELEASE) && (event != MEVENT_DOUBLECLICK_DRAG) &&
- (event != MEVENT_DOUBLECLICK_RELEASE))
- return handledFlag;
-
- MenuImage *thumbnail = (MenuImage *) parent()->getItem(SLTAG_THUMBNAIL);
-
- // Check whether the cursor is over the button
- if ((_objectState == OS_MOUSEOVER) || (_objectState == OS_PRESSED)) {
- if (_index != parent()->_highlightedSlot) {
- // Selected slot has changed
- if (parent()->_savegameThumbnail != NULL)
- delete parent()->_savegameThumbnail;
-
- parent()->_highlightedSlot = _index;
- parent()->_savegameThumbnail = _vm->_saveLoad->getThumbnail(_index + 1);
- thumbnail->setSprite(parent()->_savegameThumbnail);
- }
-
- } else {
- // If the mouse has moved outside the area of all the save slots, then the
- // thumbnail needs to be removed
-
- Common::Rect slotArea(50, 256, 288, 377);
- if (isInside(x, y) || !slotArea.contains(x, y)) {
- if (parent()->_savegameThumbnail) {
- delete parent()->_savegameThumbnail;
- parent()->_savegameThumbnail = NULL;
- }
-
- thumbnail->setSprite(parent()->sprites()->getFrame(SL_EMPTY_THUMBNAIL));
- parent()->_highlightedSlot = -1;
- }
- }
-
- return handledFlag;
-}
-
-void MenuSaveLoadText::setVisible(bool value) {
- _visible = value;
- parent()->refresh(_bounds);
-}
-
-//--------------------------------------------------------------------------
-// MenuTextField class
-//
-// Defines a text entry field
-//--------------------------------------------------------------------------
-
-MenuTextField::MenuTextField(DialogView *owner, int fieldId, int xs, int ys, int width,
- int height, bool greyed, Callback callbackFn,
- const char *displayText, int displayValue, bool transparent):
- MenuObject(owner, fieldId, xs, ys, width, height, greyed, transparent) {
-
- _displayValue = displayValue;
- _callback = callbackFn;
- _pixelWidth = width - 27;
- if (displayText) {
- strcpy(_displayText, displayText);
- _promptEnd = &_displayText[strlen(_displayText)];
- } else {
- _displayText[0] = '\0';
- _promptEnd = &_displayText[0];
- }
- _cursor = _promptEnd;
-}
-
-void MenuTextField::onRefresh() {
- bool focused = _objectState != OS_GREYED;
-
- // Get the thumb sprite for the slider
- SpriteAsset &sprites = *parent()->sprites();
- M4Sprite *sprite = sprites[SL_LINE_NORMAL + OS_MOUSEOVER - 1];
-
- // If the slider is transparent, first copy in the background
- if (_transparent) {
- // Transparent button
- if (!_background)
- return;
-
- _background->copyTo(parent(), _bounds.left, _bounds.top, 0);
- }
-
- // Draw the sprite
- sprite->copyTo(parent(), _bounds.left, _bounds.top, 0);
-
- // Draw the text
-
- _vm->_font->setFont(FONT_MENU);
- _vm->_font->current()->setColors(TEXT_COLOR_NORMAL_SHADOW, TEXT_COLOR_NORMAL_FOREGROUND,
- TEXT_COLOR_NORMAL_HILIGHT);
- int xp = _bounds.left + 4;
-
- if (_displayValue != 0) {
- char tempBuffer[5];
- sprintf(tempBuffer, "%02d", _displayValue);
- _vm->_font->current()->writeString(_parent, tempBuffer, xp, _bounds.top + 1, 0, -1);
- xp = _bounds.left + 26;
- }
-
- _vm->_font->current()->writeString(_parent, _displayText, xp, _bounds.top + 1, 0, -1);
-
- if (focused) {
- // Draw in the cursor
-
- if (_cursor) {
- // Get the width of the string up to the cursor position
- char tempCh = *_cursor;
- *_cursor = '\0';
- int stringWidth = _vm->_font->current()->getWidth(_displayText);
- *_cursor = tempCh;
-
- parent()->setColor(TEXT_COLOR_MOUSEOVER_FOREGROUND);
- parent()->vLine(xp + stringWidth + 1, _bounds.top + 1, _bounds.top + 12);
- }
- }
-}
-
-bool MenuTextField::onEvent(M4EventType event, int32 param, int x, int y, MenuObject *&currentItem) {
- char tempStr[MAX_SAVEGAME_NAME];
- int tempLen;
- char *tempP;
- bool handledFlag = false, redrawFlag = false, callbackFlag = false;
-
- if (_objectState == OS_GREYED)
- return false;
-
- switch (event) {
- case MEVENT_LEFT_CLICK:
- case MEVENT_DOUBLECLICK:
- parent()->_deleteSaveDesc = false;
- if (isInside(x, y))
- currentItem = this;
- break;
-
- case MEVENT_LEFT_RELEASE:
- case MEVENT_DOUBLECLICK_RELEASE:
- if (!currentItem)
- return true;
- currentItem = NULL;
-
- if (isInside(x, y)) {
- if (_objectState == OS_MOUSEOVER) {
- tempLen = strlen(_displayText);
- if (tempLen > 0) {
- strcpy(tempStr, _displayText);
- tempP = &tempStr[tempLen];
- _vm->_font->setFont(FONT_MENU);
-
- tempLen = _vm->_font->current()->getWidth(tempStr);
- while ((tempP != &tempStr[0]) && (tempLen > x - _bounds.left - 26)) {
- *--tempP = '\0';
- tempLen = _vm->_font->current()->getWidth(tempStr);
- }
-
- _cursor = &_displayText[tempP - &tempStr[0]];
- redrawFlag = true;
- }
- } else if (event == MEVENT_DOUBLECLICK_RELEASE) {
- callbackFlag = true;
- }
- }
- break;
-
- case KEVENT_KEY:
- switch (param) {
- case Common::KEYCODE_RETURN:
- case Common::KEYCODE_KP_ENTER:
- parent()->_deleteSaveDesc = false;
- callbackFlag = true;
- break;
- break;
-
- case Common::KEYCODE_HOME:
- parent()->_deleteSaveDesc = false;
- _cursor = &_displayText[0];
- redrawFlag = true;
- break;
-
- case Common::KEYCODE_END:
- parent()->_deleteSaveDesc = false;
- _cursor = _promptEnd;
- redrawFlag = true;
- break;
-
- case Common::KEYCODE_LEFT:
- case Common::KEYCODE_KP4:
- parent()->_deleteSaveDesc = false;
- if (_cursor > &_displayText[0]) {
- --_cursor;
- redrawFlag = true;
- }
- break;
-
- case Common::KEYCODE_RIGHT:
- case Common::KEYCODE_KP6:
- parent()->_deleteSaveDesc = false;
- if (_cursor < _promptEnd) {
- ++_cursor;
- redrawFlag = true;
- }
- break;
-
- case Common::KEYCODE_DELETE:
- if (parent()->_deleteSaveDesc) {
- _displayText[0] = '\0';
- _promptEnd = &_displayText[0];
- _cursor = _promptEnd;
- redrawFlag = true;
- } else if (_cursor < _promptEnd) {
- strcpy(tempStr, _cursor + 1);
- strcpy(_cursor, tempStr);
- --_promptEnd;
- redrawFlag = true;
- }
- break;
-
- case Common::KEYCODE_BACKSPACE:
- parent()->_deleteSaveDesc = false;
- if (_cursor > &_displayText[0]) {
- strcpy(tempStr, _cursor);
- --_promptEnd;
- --_cursor;
- strcpy(_cursor, tempStr);
- redrawFlag = true;
- }
- break;
-
- default:
- parent()->_deleteSaveDesc = false;
- _vm->_font->setFont(FONT_MENU);
-
- tempLen = _vm->_font->current()->getWidth(_displayText);
- if ((strlen(_displayText) < MAX_SAVEGAME_NAME - 1) &&
- (tempLen < _pixelWidth - 12) && (param >= 32) && (param <= 127)) {
-
- // Valid displayable character
- if (_cursor < _promptEnd) {
- strcpy(tempStr, _cursor);
- sprintf(_cursor, "%c%s", (char)param, tempStr);
- } else {
- *_cursor = (char)param;
- *(_cursor + 1) = '\0';
- }
- ++_cursor;
- ++_promptEnd;
-
- redrawFlag = true;
- }
- break;
- }
- break;
-
- default:
- break;
- }
-
- if (redrawFlag)
- onRefresh();
-
- if (callbackFlag)
- onExecute();
-
- return handledFlag;
-}
-
-//--------------------------------------------------------------------------
-
-
-GUITextField::GUITextField(View *owner, const Common::Rect &bounds): GUIRect(owner, bounds, 0) {
-}
-
-void GUITextField::onRefresh() {
- _parent->fillRect(_bounds, _vm->_palette->BLACK);
- _vm->_font->current()->setColors(3, 3, 3);
- _vm->_font->setFont(FONT_INTERFACE);
- _vm->_font->current()->writeString(_parent, _text.c_str(), _bounds.left, _bounds.top, 0, 1);
-}
-
-//--------------------------------------------------------------------------
-
-GUIButton::GUIButton(View *owner, const Common::Rect &bounds, int tag,
- M4Surface *normalSprite, M4Surface *mouseOverSprite, M4Surface *pressedSprite):
- GUIRect(owner, bounds, tag) {
-
- _normalSprite = normalSprite;
- _mouseOverSprite = mouseOverSprite;
- _pressedSprite = pressedSprite;
- _visible = true;
- _tracking = false;
-}
-
-void GUIButton::onRefresh() {
- _parent->fillRect(_bounds, _vm->_palette->BLACK);
-
- if (_visible) {
- switch (_buttonState) {
- case BUTTON_MOUSEOVER:
- _mouseOverSprite->copyTo(_parent, _bounds.left, _bounds.top, 0);
- break;
- case BUTTON_PRESSED:
- _pressedSprite->copyTo(_parent, _bounds.left, _bounds.top, 0);
- break;
- default:
- _normalSprite->copyTo(_parent, _bounds.left, _bounds.top, 0);
- break;
- }
- }
-}
-
-bool GUIButton::onEvent(M4EventType eventType, int32 param, int x, int y, GUIObject *&currentItem) {
- bool result = false;
- bool isPressed = (eventType == MEVENT_LEFT_CLICK) || (eventType == MEVENT_LEFT_HOLD) ||
- (eventType == MEVENT_LEFT_DRAG);
- bool isOver = isInside(x, y);
- GUIButtonState oldState = _buttonState;
-
- if (isOver) {
- if (isPressed) {
- // Button is pressed
- if (!_tracking) {
- _tracking = true;
- _buttonState = BUTTON_PRESSED;
- }
-
- if (_vm->isM4())
- _m4Vm->globals()->invSuppressClickSound = false;
- } else {
- // Button isn't pressed
- if (_tracking)
- result = true;
- else {
- result = false;
- _buttonState = BUTTON_MOUSEOVER;
- _tracking = false;
- }
- }
- } else {
- _tracking = false;
- _buttonState = BUTTON_NORMAL;
- }
-
- if (oldState != _buttonState)
- onRefresh();
-
- return result;
-}
-
-} // End of namespace M4
diff --git a/engines/m4/gui.h b/engines/m4/gui.h
deleted file mode 100644
index 2b673d624c..0000000000
--- a/engines/m4/gui.h
+++ /dev/null
@@ -1,453 +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 M4_GUI_H
-#define M4_GUI_H
-
-#include "common/list.h"
-#include "common/rect.h"
-
-#include "m4/viewmgr.h"
-#include "m4/events.h"
-#include "m4/globals.h"
-#include "m4/graphics.h"
-#include "m4/saveload.h"
-#include "m4/sprite.h"
-#include "m4/assets.h"
-
-namespace M4 {
-
-class GUIObject;
-class MenuObject;
-class GUIObjectButton;
-class SpriteAsset;
-class View;
-
-enum MenuType {GAME_MENU, OPTIONS_MENU, SAVE_MENU, LOAD_MENU, MAIN_MENU};
-
-enum {
- BTNID_QUIT = 1,
- BTNID_OPTIONS = 2,
- BTNID_RESUME = 3,
- BTNID_SAVE = 4,
- BTNID_LOAD = 5,
- BTNID_MAIN = 6,
-
- OPTIONID_DONE = 1,
- OPTIONID_CANCEL = 2,
- OPTIONID_HSLIDER_DIGI = 3,
- OPTIONID_HSLIDER_MIDI = 4,
-
- SAVELOADID_SAVE = 1,
- SAVELOADID_CANCELSAVE = 2,
- SAVELOADID_LOAD = 3,
- SAVELOADID_CANCELLOAD = 4,
-
- SLTAG_SAVELOAD = 100,
- SLTAG_SAVELOAD_LABEL = 101,
- SLTAG_CANCEL = 102,
- SLTAG_VSLIDER = 103,
- SLTAG_THUMBNAIL = 104,
-
- SLTAG_SLOTS_START = 1001,
- SLTAG_TEXTFIELD = 2000
-};
-
-enum ObjectType {
- OBJTYPE_BUTTON,
-
- OBJTYPE_SLIDER,
- OBJTYPE_OM_SWITCH_ON,
- OBJTYPE_OM_SWITCH_OFF,
- OBJTYPE_OM_DONE,
- OBJTYPE_OM_CANCEL,
-
- OBJTYPE_SL_SAVE,
- OBJTYPE_SL_LOAD,
- OBJTYPE_SL_CANCEL,
- OBJTYPE_SL_TEXT
-};
-
-enum GameMenuSpriteType {
- GM_DIALOG_BOX,
-
- GM_BUTTON_GREYED,
- GM_BUTTON_NORMAL,
- GM_BUTTON_MOUSEOVER,
- GM_BUTTON_PRESSED
-};
-
-enum OptionMenuSpriteType {
- OM_DIALOG_BOX,
-
- OM_SLIDER_BTN_NORMAL,
- OM_SLIDER_BTN_MOUSEOVER,
- OM_SLIDER_BTN_PRESSED,
- OM_SLIDER_BAR,
- OM_DONE_BTN_GREYED,
- OM_DONE_BTN_NORMAL,
- OM_DONE_BTN_MOUSEOVER,
- OM_DONE_BTN_PRESSED,
- OM_CANCEL_BTN_NORMAL,
- OM_CANCEL_BTN_MOUSEOVER,
- OM_CANCEL_BTN_PRESSED
-};
-
-
-enum SaveLoadSpriteType {
- SL_DIALOG_BOX,
- SL_EMPTY_THUMBNAIL,
-
- SL_SAVE_BTN_GREYED,
- SL_SAVE_BTN_NORMAL,
- SL_SAVE_BTN_MOUSEOVER,
- SL_SAVE_BTN_PRESSED,
-
- SL_LOAD_BTN_GREYED,
- SL_LOAD_BTN_NORMAL,
- SL_LOAD_BTN_MOUSEOVER,
- SL_LOAD_BTN_PRESSED,
-
- SL_CANCEL_BTN_NORMAL,
- SL_CANCEL_BTN_MOUSEOVER,
- SL_CANCEL_BTN_PRESSED,
-
- SL_UP_BTN_GREYED,
- SL_UP_BTN_NORMAL,
- SL_UP_BTN_MOUSEOVER,
- SL_UP_BTN_PRESSED,
-
- SL_DOWN_BTN_GREYED,
- SL_DOWN_BTN_NORMAL,
- SL_DOWN_BTN_MOUSEOVER,
- SL_DOWN_BTN_PRESSED,
-
- SL_SAVE_LABEL,
- SL_LOAD_LABEL,
-
- SL_SLIDER_BTN_NORMAL,
- SL_SLIDER_BTN_MOUSEOVER,
- SL_SLIDER_BTN_PRESSED,
-
- SL_LINE_NORMAL,
- SL_LINE_MOUSEOVER,
- SL_LINE_PRESSED,
-
- SL_SCROLLBAR
-};
-
-enum TextColors {
- TEXT_COLOR_NORMAL = 1,
- TEXT_COLOR_GREYED = 1,
- TEXT_COLOR_MOUSEOVER = 2,
- TEXT_COLOR_PRESSED = 2,
-
- TEXT_COLOR_GREYED_HILIGHT = 236,
- TEXT_COLOR_GREYED_FOREGROUND = 131,
- TEXT_COLOR_GREYED_SHADOW = 186,
-
- TEXT_COLOR_NORMAL_HILIGHT = 129,
- TEXT_COLOR_NORMAL_FOREGROUND = 130,
- TEXT_COLOR_NORMAL_SHADOW = 236,
-
- TEXT_COLOR_MOUSEOVER_HILIGHT = 129,
- TEXT_COLOR_MOUSEOVER_FOREGROUND = 130,
- TEXT_COLOR_MOUSEOVER_SHADOW = 236,
-
- TEXT_COLOR_PRESSED_HILIGHT = 236,
- TEXT_COLOR_PRESSED_FOREGROUND = 130,
- TEXT_COLOR_PRESSED_SHADOW = 129
-};
-
-#define MENU_SS_FIELD_NORMAL 5
-#define MENU_SS_FIELD_MOUSEOVER 6
-
-#define MENU_SS_H_SLIDER_NORMAL 5
-#define MENU_SS_H_SLIDER_MOUSE_OVER 6
-#define MENU_SS_H_SLIDER_PRESSED 7
-
-#define MENU_SS_SWITCH_ON_NORMAL 8
-#define MENU_SS_SWITCH_ON_MOUSEOVER 9
-#define MENU_SS_SWITCH_ON_PRESSED 13
-
-#define MENU_SS_SWITCH_OFF_PRESSED 10
-#define MENU_SS_SWITCH_OFF_NORMAL 11
-#define MENU_SS_SWITCH_OFF_MOUSEOVER 12
-
-#define MENU_GUI "gui menu"
-#define MENU_GAME "gamemenu"
-#define MENU_OPTIONS "opmenu"
-#define MENU_ERROR "errmenu"
-#define MENU_SAVELOAD "slmenu"
-#define MENU_BURGMAIN "903menu"
-#define MENU_BURGDEMOMAIN "901menu"
-
-#define SL_NUM_VISIBLE_SLOTS 8
-#define SL_THUMBNAIL_WIDTH 215
-#define SL_THUMBNAIL_HEIGHT 162
-
-enum MenuObjectState {OS_GREYED = 0, OS_NORMAL = 1, OS_MOUSEOVER = 2, OS_PRESSED = 3};
-
-class DialogView : public View {
-public:
- DialogView(MadsM4Engine *Vm, const Common::Rect &viewBounds, bool transparent = false):
- View(Vm, viewBounds, transparent) {}
- DialogView(MadsM4Engine *Vm, int x = 0, int y = 0, bool transparent = false):
- View(Vm, x, y, transparent) {}
-
- MadsM4Engine *vm() { return _vm; }
- virtual SpriteAsset *sprites() = 0;
- virtual MenuType getMenuType() = 0;
- virtual MenuObject *getItem(int objectId) { return NULL; }
- virtual void refresh(const Common::Rect &areaRect) {}
- virtual void close();
-
- int _topSaveSlotIndex, _selectedSlot;
- int _highlightedSlot;
- bool _deleteSaveDesc;
- M4Surface *_savegameThumbnail;
-};
-
-class GUIObject {
-protected:
- View *_parent;
- Common::Rect _bounds;
- M4Surface *_background;
-public:
- GUIObject(View *owner, const Common::Rect &bounds);
- virtual ~GUIObject() {}
-
- bool isInside(int x, int y) { return _bounds.contains(x, y); }
- Common::Rect getBounds() const { return _bounds; }
-
- virtual void onRefresh() {}
-};
-
-class MenuObject : public GUIObject {
-public:
- typedef void (*Callback)(DialogView *view, MenuObject *item);
-protected:
- MenuObject::Callback _callback;
- ObjectType _objectType;
- MenuObjectState _objectState;
- bool _transparent;
- int _objectId;
-public:
- MenuObject(DialogView *owner, int objectId, int xs, int ys, int width, int height,
- bool greyed = false, bool transparent = false);
- ~MenuObject();
-
- DialogView *parent() { return (DialogView *)_parent; }
- MenuObjectState getState() { return _objectState; }
- virtual void setState(MenuObjectState state) {
- _objectState = state;
- onRefresh();
- }
- int getObjectId() { return _objectId; }
-
- void onExecute();
- virtual bool onEvent(M4EventType event, int32 param, int x, int y, MenuObject *&currentItem) { return false; }
-};
-
-class MenuButton : public MenuObject {
-public:
- MenuButton(DialogView *owner, int buttonId, int xs, int ys, int width, int height,
- Callback callbackFn = NULL, bool greyed = false, bool transparent = false,
- ObjectType buttonType = OBJTYPE_BUTTON);
-
- void onRefresh();
- bool onEvent(M4EventType event, int32 param, int x, int y, MenuObject *&currentItem);
- bool getToggled() { return _objectType == OBJTYPE_OM_SWITCH_ON; }
-};
-
-enum MenuHorizSliderState {HSLIDER_THUMB_NORMAL = 0, HSLIDER_THUMB_MOUSEOVER = 1, HSLIDER_THUMB_PRESSED = 2};
-#define SLIDER_BAR_COLOR 129
-
-class MenuHorizSlider : public MenuObject {
-protected:
- MenuHorizSliderState _sliderState;
- Common::Point _thumbSize;
- int _maxThumbX;
- int _percent;
- int _thumbX;
-public:
- MenuHorizSlider(DialogView *owner, int sliderId, int xs, int ys, int width, int height,
- int initialPercentage, Callback callbackFn = NULL, bool transparent = false);
-
- void onRefresh();
- bool onEvent(M4EventType event, int32 param, int x, int y, MenuObject *&currentItem);
- int percent() { return _percent; }
-};
-
-enum MenuVertSliderState {
- VSLIDER_NONE = 0x0000,
- VSLIDER_UP = 0x0010,
- VSLIDER_PAGE_UP = 0x0020,
- VSLIDER_THUMBNAIL = 0x0030,
- VSLIDER_PAGE_DOWN = 0x0040,
- VSLIDER_DOWN = 0x0050
-};
-
-class MenuVertSlider : public MenuObject {
-protected:
- MenuVertSliderState _sliderState;
- Common::Point _thumbSize;
- int _percent;
- int _thumbY;
- int _minThumbY;
- int _maxThumbY;
-
- MenuVertSliderState getSliderArea(int y);
- void updateThumbnails() {}
-public:
- MenuVertSlider(DialogView *owner, int sliderId, int xs, int ys, int width, int height,
- int initialPercentage, Callback callbackFn = NULL, bool transparent = false);
-
- void onRefresh();
- bool onEvent(M4EventType event, int32 param, int x, int y, MenuObject *&currentItem);
- MenuVertSliderState sliderState() { return _sliderState; }
- int percent() { return _percent; }
- void setPercentage(int value);
-};
-
-class MenuMessage : public MenuObject {
-public:
- MenuMessage(DialogView *owner, int objectId, int x, int y, int w, int h, bool transparent = false);
-
- void onRefresh();
-};
-
-class MenuImage : public MenuObject {
-private:
- M4Surface *_sprite;
-public:
- MenuImage(DialogView *owner, int objectId, int xs, int ys, int width, int height,
- M4Surface *image, bool transparent = false);
-
- void onRefresh();
- const M4Surface *sprite() { return _sprite; }
- void setSprite(M4Surface *v) {
- _sprite = v;
- onRefresh();
- }
-};
-
-class MenuSaveLoadText : public MenuButton {
-private:
- bool _loadFlag;
- const char *_displayText;
- int _displayValue;
- int _index;
- bool _visible;
-public:
- MenuSaveLoadText(DialogView *owner, int textId, int xs, int ys, int width, int height,
- Callback callbackFn = NULL, bool greyed = false, bool transparent = false,
- bool loadFlag = false, const char *displayText = NULL, int displayValue = 0);
-
- void onRefresh();
- bool onEvent(M4EventType event, int32 param, int x, int y, MenuObject *&currentItem);
- void setDisplay(int value, const char *text) { _displayValue = value; _displayText = text; }
- int getIndex() { return _index; }
- const char *getText() { return _displayText; }
- bool getVisible() const { return _visible; }
- void setVisible(bool value);
-};
-
-class MenuTextField : public MenuObject {
-private:
- int _displayValue;
- char _displayText[MAX_SAVEGAME_NAME];
- int _pixelWidth;
- char *_promptEnd;
- char *_cursor;
-public:
- MenuTextField(DialogView *owner, int fieldId, int xs, int ys, int width, int height,
- bool greyed, Callback callbackFn = NULL, const char *displayText = NULL,
- int displayValue = 0, bool transparent = true);
-
- void onRefresh();
- bool onEvent(M4EventType event, int32 param, int x, int y, MenuObject *&currentItem);
-
- const char *getText() { return _displayText; }
- int getDisplayValue() { return _displayValue; }
-
-};
-
-class GUIRect : public GUIObject {
-private:
- int _tag;
-public:
- GUIRect(View *owner, const Common::Rect &bounds, int tag): GUIObject(owner, bounds) { _tag = tag; }
-
- virtual bool onEvent(M4EventType eventType, int32 param, int x, int y, GUIObject *&currentItem) { return false; }
- int getTag() const { return _tag; }
-};
-
-enum GUIButtonState {BUTTON_NORMAL, BUTTON_MOUSEOVER, BUTTON_PRESSED};
-
-class GUIButton : public GUIRect {
-protected:
- M4Surface *_normalSprite, *_mouseOverSprite, *_pressedSprite;
- GUIButtonState _buttonState;
- bool _visible;
- bool _tracking;
-public:
- GUIButton(View *owner, const Common::Rect &bounds, int tag,
- M4Surface *normalSprite, M4Surface *mouseOverSprite, M4Surface *pressedSprite);
-
- void onRefresh();
- bool onEvent(M4EventType eventType, int32 param, int x, int y, GUIObject *&currentItem);
- GUIButtonState getState() const { return _buttonState; }
-};
-
-class GUITextField : public GUIRect {
-private:
- Common::String _text;
-public:
- GUITextField(View *owner, const Common::Rect &bounds);
- void setText(const char *value) {
- _text = value;
- onRefresh();
- }
-
- void onRefresh();
-};
-
-
-class Dialogs {
-public:
- void keyMouseCollision() {}
-};
-
-class GameInterfaceView : public View {
-public:
- GameInterfaceView(MadsM4Engine *vm, const Common::Rect &rect): View(vm, rect) {}
- ~GameInterfaceView() {}
-
- virtual void initialize() {}
- virtual void setSelectedObject(int objectNumber) {}
- virtual void addObjectToInventory(int objectNumber) {}
-};
-
-}
-
-#endif
diff --git a/engines/m4/hotspot.cpp b/engines/m4/hotspot.cpp
deleted file mode 100644
index a585a9af3d..0000000000
--- a/engines/m4/hotspot.cpp
+++ /dev/null
@@ -1,283 +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 "m4/m4.h"
-#include "m4/events.h"
-#include "m4/hotspot.h"
-#include "gui/debugger.h"
-
-namespace M4 {
-
-/*
- HotSpot
-*/
-
-HotSpot::HotSpot(int x1, int y1, int x2, int y2) :
- _vocab(NULL), _verb(NULL), _prep(NULL), _sprite(NULL) {
-
- _rect.left = x1;
- _rect.top = y1;
- _rect.right = x2 + 1;
- _rect.bottom = y2 + 1;
- _active = true;
-
- _syntax = 0;
- _cursor = 0;
- _facing = 5;
- _feetX = 32767;
- _feetY = 32767;
-}
-
-HotSpot::~HotSpot() {
- free(_vocab);
-}
-
-void HotSpot::setRect(int x1, int y1, int x2, int y2) {
- _rect.left = x1;
- _rect.top = y1;
- _rect.right = x2 + 1;
- _rect.bottom = y2 + 1;
-}
-
-void HotSpot::setFeet(int x, int y) {
- _feetX = x;
- _feetY = y;
-}
-
-void HotSpot::setVocab(const char *value) {
- free(_vocab);
- _vocab = strdup(value);
-}
-
-void HotSpot::setVerb(const char *value) {
- free(_verb);
- _verb = strdup(value);
-}
-
-void HotSpot::setPrep(const char *value) {
- free(_prep);
- _prep = strdup(value);
-}
-
-void HotSpot::setSprite(const char *value) {
- free(_sprite);
- _sprite = strdup(value);
-}
-
-Common::Rect HotSpot::getRect() const {
- Common::Rect tempRect;
- tempRect.left = _rect.left;
- tempRect.top = _rect.top;
- tempRect.right = _rect.right - 1;
- tempRect.bottom = _rect.bottom - 1;
-
- return tempRect;
-}
-
-/*
- HotSpotList
-*/
-
-HotSpotList::HotSpotList() {
-}
-
-HotSpotList::~HotSpotList() {
- clear();
-}
-
-int HotSpotList::add(HotSpot *hotspot, bool head) {
- if (head || _hotspots.size() == 0) {
- _hotspots.insert_at(0, hotspot);
- return 0;
- } else {
- int32 area = hotspot->area();
- int index = _hotspots.size();
- for (uint i = 0; i < _hotspots.size(); i++) {
- if (area < _hotspots[i]->area()) {
- index = i;
- break;
- }
- }
- _hotspots.insert_at(index, hotspot);
- return index;
- }
-}
-
-void HotSpotList::remove(HotSpot *hotspot) {
- unlinkItem(hotspot);
- delete hotspot; //TODO: check this?
-}
-
-void HotSpotList::unlinkItem(HotSpot *hotspot) {
- uint index = 0;
- while (index < _hotspots.size()) {
- if (_hotspots[index] == hotspot) {
- _hotspots.remove_at(index);
- } else {
- index++;
- }
- }
-}
-
-void HotSpotList::clear() {
- for (uint i = 0; i < _hotspots.size(); i++)
- delete _hotspots[i];
- _hotspots.clear();
-}
-
-HotSpot *HotSpotList::findByXY(int x, int y) {
- for (uint i = 0; i < _hotspots.size(); i++) {
- if (_hotspots[i]->getActive() && _hotspots[i]->pointInside(x, y)) {
- return _hotspots[i];
- }
- }
- return NULL;
-}
-
-void HotSpotList::setActive(const char *name, bool active) {
- for (uint i = 0; i < _hotspots.size(); i++) {
- if (!scumm_stricmp(_hotspots[i]->_vocab, name)) {
- _hotspots[i]->setActive(active);
- }
- }
-}
-
-void HotSpotList::setActiveXY(const char *name, int x, int y, bool active) {
- for (uint i = 0; i < _hotspots.size(); i++) {
- if (_hotspots[i]->pointInside(x, y) && !scumm_stricmp(_hotspots[i]->_vocab, name)) {
- _hotspots[i]->setActive(active);
- }
- }
-}
-
-void HotSpotList::dump() {
- _vm->_events->getConsole()->DebugPrintf("%d hotspots in the list\n", _hotspots.size());
-
- for (uint index = 0; index < _hotspots.size(); index++) {
- _vm->_events->getConsole()->DebugPrintf("(%d): %p x1 = %d; y1 = %d; x2 = %d; y2 = %d\n",
- index, (void *)_hotspots[index],
- _hotspots[index]->_rect.left, _hotspots[index]->_rect.top,
- _hotspots[index]->_rect.right - 1, _hotspots[index]->_rect.bottom - 1);
- }
-}
-
-uint32 HotSpotList::readHotSpotInteger(Common::SeekableReadStream* hotspotStream) {
- if (_vm->isM4())
- return hotspotStream->readSint32LE();
- else
- return hotspotStream->readSint16LE();
-}
-
-void HotSpotList::loadHotSpots(Common::SeekableReadStream* hotspotStream, int hotspotCount) {
- HotSpot *currentHotSpot;
- uint32 x1, y1, x2, y2;
- char buffer[256];
- uint32 strLength = 0;
- uint32 index = 0;
- int feetX, feetY;
- int cursorOffset = (_vm ->isM4()) ? 0 : 1;
-
- for (int i = 0; i < hotspotCount; i++) {
- x1 = readHotSpotInteger(hotspotStream);
- y1 = readHotSpotInteger(hotspotStream);
- x2 = readHotSpotInteger(hotspotStream);
- y2 = readHotSpotInteger(hotspotStream);
- index = add(new HotSpot(x1, y1, x2, y2), i == 0);
- currentHotSpot = get(index);
- currentHotSpot->setIndex(index);
- feetX = readHotSpotInteger(hotspotStream);
- feetY = readHotSpotInteger(hotspotStream);
- currentHotSpot->setFeet(feetX, feetY);
- currentHotSpot->setFacing((uint8)hotspotStream->readByte());
- currentHotSpot->setActive(hotspotStream->readByte() != 0);
-
- if (!_vm->isM4())
- hotspotStream->readByte(); // unused (always 255)
-
- index = hotspotStream->readByte(); // cursor
- if (index == 0)
- currentHotSpot->setCursor(0);
- else
- currentHotSpot->setCursor(index - cursorOffset);
-
- // Rex Nebular doesn't have this field
- if (!_vm->isM4() && _vm->getGameType() != GType_RexNebular) {
- // This looks to be some sort of bitmask. Perhaps it signifies
- // the valid verbs for this hotspot
- index = hotspotStream->readUint16LE(); // unknown
- //debugC(kDebugCore, "%i ", index);
- }
-
- if (_vm->isM4())
- hotspotStream->readByte(); // syntax (unused)
-
- currentHotSpot->setVocabID(readHotSpotInteger(hotspotStream));
- currentHotSpot->setVerbID(readHotSpotInteger(hotspotStream));
-
- // Load hotspot related strings (verb, vocab/noun etc)
- // These are loaded inside the hotspot data in M4 games,
- // and inside the global vocab data (vocab.dat) in MADS games
- if (_vm->isM4()) {
- strLength = hotspotStream->readUint32LE(); // vocabLength
- hotspotStream->read(buffer, strLength); // vocab (the hotspot's name)
- // Capitalize the hotspot's name here
- str_upper(buffer);
- currentHotSpot->setVocab(buffer);
- // Verbs are used internally by the game scripts in Orion Burger
- strLength = hotspotStream->readUint32LE(); // verbLength
- hotspotStream->read(buffer, strLength); // verb
- // Capitalize the hotspot's verb here
- str_upper(buffer);
- currentHotSpot->setVerb(buffer);
-
- /* Hotspot names for non-English versions are stored in prep.
- Prep can be set two ways: For English versions, copy the
- text from vocab. For non-English versions, use the prep text
- from the room file.
- */
- strLength = hotspotStream->readUint32LE(); // prepLength
- hotspotStream->read(buffer, strLength); // prep
- str_upper(buffer);
-
- if (strlen(buffer) > 0 && strcmp(buffer, "--") != 0 && strcmp(buffer, "ON") != 0)
- currentHotSpot->setPrep(buffer);
- else
- currentHotSpot->setPrep(currentHotSpot->getVocab());
-
- // The following values are not used at all by Orion Burger
- strLength = hotspotStream->readUint32LE(); // spriteLength
- hotspotStream->read(buffer, strLength); // sprite
- hotspotStream->readUint16LE(); // sprite hash
- } else {
- currentHotSpot->setVocab("");
- currentHotSpot->setVerb("");
-
- if (currentHotSpot->getVocabID() > 0)
- currentHotSpot->setVocab(_madsVm->globals()->getVocab(currentHotSpot->getVocabID()));
-
- if (currentHotSpot->getVerbID() > 0)
- currentHotSpot->setVerb(_madsVm->globals()->getVocab(currentHotSpot->getVerbID()));
- }
- }
-}
-
-} // End of namespace M4
diff --git a/engines/m4/hotspot.h b/engines/m4/hotspot.h
deleted file mode 100644
index 86fe21bcab..0000000000
--- a/engines/m4/hotspot.h
+++ /dev/null
@@ -1,126 +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 M4_HOTSPOT_H
-#define M4_HOTSPOT_H
-
-#include "common/array.h"
-#include "common/rect.h"
-#include "common/util.h"
-
-/*
- TODO:
- - check if hotspot_duplicate is needed
- NOTES:
- - hotspot_add_dynamic unused in Orion Burger
-*/
-
-//???: should String be used instead of char* here?
-
-namespace M4 {
-
-class HotSpot {
- friend class HotSpotList;//just for debugging, to be removed later
-public:
-
- HotSpot(int x1 = 0, int y1 = 0, int x2 = 0, int y2 = 0);
- ~HotSpot();
-
- void setVocab(const char *value);
- void setVocabID(int32 value) { _vocabID = value; }
- void setVerb(const char *value);
- void setVerbID(int32 value) { _verbID = value; }
- void setPrep(const char *value);
- void setSprite(const char *value);
- void setActive(bool value) { _active = value; }
- void setCursor(uint8 value) { _cursor = value; }
- void setRect(int x1, int y1, int x2, int y2);
- void setFeet(int x, int y);
- void setFacing(uint8 facing) { _facing = facing; }
- void setArticle(int8 v) { _articleNumber = v; }
- char *getVocab() const { return _vocab; }
- int32 getVocabID() { return _vocabID; }
- char *getVerb() const { return _verb; }
- int32 getVerbID() { return _verbID; }
- char *getPrep() const { return _prep; }
- char *getSprite() const { return _sprite; }
- uint8 getCursor() const { return _cursor; }
- bool getActive() const { return _active; }
- uint8 getFacing() const { return _facing; }
- int getFeetX() { return _feetX; }
- int getFeetY() { return _feetY; }
- int8 getArticle() const { return _articleNumber; }
- Common::Rect getRect() const;
- int getIndex() const { return _index; }
- void setIndex(int index) { _index = index; }
-
- int32 area() const { return (_rect.width() - 1) * (_rect.height() - 1); }
- bool pointInside(int x, int y) { return _rect.contains(x, y); }
-
-private:
- char *_vocab, *_verb, *_prep, *_sprite;
- Common::Rect _rect;
- bool _active;
- int _feetX, _feetY;
- uint8 _facing, _cursor;
- int _index;
-
- // Unused in Orion Burger, used in MADS games
- uint8 _syntax;
- int32 _vocabID, _verbID;
- int8 _articleNumber;
-
- //TODO: check if this is actually needed by the game
- int16 _hash;
-};
-
-class HotSpotList {
-public:
- HotSpotList();
- ~HotSpotList();
-
- int add(HotSpot *hotspot, bool head = false);
- HotSpot *get(int index) { return _hotspots[index]; }
- HotSpot &operator[](int idx) { return *get(idx); }
- int size() const { return _hotspots.size(); }
- void remove(HotSpot *hotspot);
- void unlinkItem(HotSpot *hotspot);
- void clear();
- HotSpot *findByXY(int x, int y);
- void setActive(const char *name, bool active);
- void setActiveXY(const char *name, int x, int y, bool active);
-
- void dump();
-
- void loadHotSpots(Common::SeekableReadStream* hotspotStream, int hotspotCount);
-
- uint32 readHotSpotInteger(Common::SeekableReadStream* hotspotStream);
-private:
- typedef Common::Array<HotSpot*> HotSpotArray;
- HotSpotArray _hotspots;
-};
-
-
-} // End of namespace M4
-
-
-#endif
diff --git a/engines/m4/m4.cpp b/engines/m4/m4.cpp
deleted file mode 100644
index efc7943114..0000000000
--- a/engines/m4/m4.cpp
+++ /dev/null
@@ -1,606 +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.
- *
- */
-
-//#define SCRIPT_TEST
-//#define INTRO_TEST
-
-#include "m4/globals.h"
-#include "m4/burger_data.h"
-#include "m4/m4.h"
-#include "m4/resource.h"
-#include "m4/hotspot.h"
-#include "m4/font.h"
-#include "m4/rails.h"
-#include "m4/midi.h"
-#include "m4/events.h"
-#include "m4/graphics.h"
-#include "m4/viewmgr.h"
-#include "m4/gui.h"
-#include "m4/woodscript.h"
-#include "m4/actor.h"
-#include "m4/sound.h"
-#include "m4/script.h"
-#include "m4/compression.h"
-#include "m4/animation.h"
-#include "m4/m4_menus.h"
-#include "m4/m4_views.h"
-#include "m4/mads_anim.h"
-#include "m4/mads_menus.h"
-
-#include "common/error.h"
-#include "common/file.h"
-#include "common/fs.h"
-#include "common/system.h"
-#include "common/config-manager.h"
-#include "common/debug-channels.h"
-#include "common/textconsole.h"
-#include "engines/util.h"
-
-namespace M4 {
-
-// FIXME: remove global
-MadsM4Engine *_vm;
-MadsEngine *_madsVm;
-M4Engine *_m4Vm;
-
-void escapeHotkeyHandler(MadsM4Engine *vm, View *view, uint32 key) {
- // For now, simply exit the game
- vm->_events->quitFlag = true;
-}
-
-// Temporary hotkey handler for use in testing the TextviewView class
-
-void textviewHotkeyHandler(MadsM4Engine *vm, View *view, uint32 key) {
- // Deactivate the scene if it's currently active
- View *sceneView = vm->_viewManager->getView(VIEWID_SCENE);
- if (sceneView != NULL)
- vm->_viewManager->deleteView(sceneView);
-
- // Activate the textview view
- vm->_font->setFont(FONT_CONVERSATION_MADS);
- TextviewView *textView = new TextviewView(vm);
- vm->_viewManager->addView(textView);
- textView->setScript("quotes", NULL);
-}
-
-void saveGameHotkeyHandler(MadsM4Engine *vm, View *view, uint32 key) {
- // TODO: See CreateF2SaveMenu - save menu should only be activated when
- // certain conditions are met, such as player_commands_allowed, and isInterfaceVisible
- vm->loadMenu(SAVE_MENU, true);
-}
-
-void loadGameHotkeyHandler(MadsM4Engine *vm, View *view, uint32 key) {
- // TODO: See CreateF3LoadMenu - save menu should only be activated when
- // certain conditions are met, such as player_commands_allowed, and isInterfaceVisible
- vm->loadMenu(LOAD_MENU, true);
-}
-
-void gameMenuHotkeyHandler(MadsM4Engine *vm, View *view, uint32 key) {
- vm->loadMenu(GAME_MENU);
-}
-
-MadsM4Engine::MadsM4Engine(OSystem *syst, const M4GameDescription *gameDesc) :
- Engine(syst), _gameDescription(gameDesc) {
- // Setup mixer
- syncSoundSettings();
-
- // FIXME
- _vm = this;
- _madsVm = NULL;
-
- const Common::FSNode gameDataDir(ConfMan.get("path"));
-
- SearchMan.addSubDirectoryMatching(gameDataDir, "goodstuf");
- SearchMan.addSubDirectoryMatching(gameDataDir, "resource");
- SearchMan.addSubDirectoryMatching(gameDataDir, "option1");
-
- DebugMan.addDebugChannel(kDebugScript, "script", "Script debug level");
- DebugMan.addDebugChannel(kDebugGraphics, "graphics", "Graphics debug level");
- DebugMan.addDebugChannel(kDebugConversations, "conversations", "Conversations debugging");
- DebugMan.addDebugChannel(kDebugSound, "sound", "Sounds debug level");
- DebugMan.addDebugChannel(kDebugCore, "core", "Core debug level");
-
- _resourceManager = NULL;
- _globals = NULL;
-}
-
-
-MadsM4Engine::~MadsM4Engine() {
- delete _midi;
- delete _saveLoad;
- delete _kernel;
- delete _player;
- delete _mouse;
- delete _events;
- delete _font;
- delete _actor;
-// delete _scene; // deleted by the viewmanager
- delete _dialogs;
- delete _screen;
- delete _inventory;
- delete _viewManager;
- delete _rails;
- delete _script;
- delete _ws;
- delete _random;
- delete _palette;
- delete _globals;
- delete _sound;
- delete _resourceManager;
-}
-
-Common::Error MadsM4Engine::run() {
- // Initialize backend
- _screen = new M4Surface(true); // Special form for creating screen reference
-
- _midi = new MidiPlayer(this);
- _midi->setGM(true); // FIXME: Really? Always?
-
- _saveLoad = new SaveLoad(this);
- _palette = new Palette(this);
- _mouse = new Mouse(this);
- _events = new Events(this);
- _kernel = new Kernel(this);
- _player = new Player(this);
- _font = new FontManager(this);
- if (getGameType() == GType_Burger) {
- _actor = new Actor(this);
- _conversationView = new ConversationView(this);
- } else {
- _actor = NULL;
- }
- _rails = new Rails(); // needs to be initialized before _scene
- _dialogs = new Dialogs();
- _viewManager = new ViewManager(this);
- _inventory = new Inventory(this);
- _sound = new Sound(this, _mixer, 255);
- _script = new ScriptInterpreter(this);
- _ws = new WoodScript(this);
- //_callbacks = new Callbacks(this);
- _random = new Common::RandomSource("m4");
-
- return Common::kNoError;
-}
-
-void MadsM4Engine::eventHandler() {
- M4EventType event;
- uint32 keycode = 0;
-
- if ((event = _events->handleEvents()) != MEVENT_NO_EVENT) {
- if (_viewManager->containsViews())
- _viewManager->handleMouseEvents(event);
- }
-
- if (_events->kbdCheck(keycode))
- _viewManager->handleKeyboardEvents(keycode);
-}
-
-bool MadsM4Engine::delay(int duration, bool keyAborts, bool clickAborts) {
- uint32 endTime = g_system->getMillis() + duration;
- M4EventType event;
- uint32 keycode = 0;
-
- while (!_events->quitFlag && (g_system->getMillis() < endTime)) {
- event = _events->handleEvents();
- if (clickAborts && ((event == MEVENT_LEFT_RELEASE) || (event == MEVENT_RIGHT_RELEASE)))
- return true;
-
- if (_events->kbdCheck(keycode)) {
- if (keyAborts)
- return true;
- }
-
- g_system->delayMillis(10);
- }
-
- return false;
-}
-
-void MadsM4Engine::loadMenu(MenuType menuType, bool loadSaveFromHotkey, bool calledFromMainMenu) {
- if (isM4() && (menuType != MAIN_MENU)) {
- bool menuActive = _viewManager->getView(VIEWID_MENU) != NULL;
-
- if (!menuActive)
- _palette->fadeToGreen(M4_DIALOG_FADE_STEPS, M4_DIALOG_FADE_DELAY);
- }
-
- View *view;
-
- switch (menuType) {
- case MAIN_MENU:
- if (getGameType() == GType_RexNebular)
- view = new RexMainMenuView(this);
- else if (getGameType() == GType_DragonSphere)
- view = new DragonMainMenuView(this);
- else
- view = new MadsMainMenuView(this);
- break;
- case GAME_MENU:
- view = new OrionMenuView(this, 200, 100, GAME_MENU, calledFromMainMenu, loadSaveFromHotkey);
- break;
- case OPTIONS_MENU:
- view = new OrionMenuView(this, 172, 160, OPTIONS_MENU, calledFromMainMenu, loadSaveFromHotkey);
- break;
- case LOAD_MENU:
- case SAVE_MENU:
- view = new OrionMenuView(this, 145, 10, menuType, calledFromMainMenu, loadSaveFromHotkey);
- break;
- default:
- error("Unknown menu type");
- break;
- }
-
- _viewManager->addView(view);
- _viewManager->moveToFront(view);
-}
-
-#define DUMP_BUFFER_SIZE 1024
-
-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);
-
- int bytesRead = 0;
- warning("Dumping %s, size: %i\n", filename, fileS->size());
-
- if (!uncompress) {
- while (!fileS->eos()) {
- bytesRead = fileS->read(buffer, DUMP_BUFFER_SIZE);
- f.write(buffer, bytesRead);
- }
- } else {
- MadsPack packData(fileS);
- Common::SeekableReadStream *sourceUnc;
- for (int i = 0; i < packData.getCount(); i++) {
- sourceUnc = packData.getItemStream(i);
- debugCN(kDebugCore, "Dumping compressed chunk %i of %i, size is %i\n", i + 1, packData.getCount(), sourceUnc->size());
- while (!sourceUnc->eos()) {
- bytesRead = sourceUnc->read(buffer, DUMP_BUFFER_SIZE);
- f.write(buffer, bytesRead);
- }
- delete sourceUnc;
- }
- }
-
- f.close();
- res()->toss(filename);
- res()->purge();
-}
-
-/*--------------------------------------------------------------------------*/
-
-M4Engine::M4Engine(OSystem *syst, const M4GameDescription *gameDesc): MadsM4Engine(syst, gameDesc) {
- // FIXME
- _m4Vm = this;
-
- _globals = new M4Globals(this);
-}
-
-M4Engine::~M4Engine() {
- delete _converse;
-}
-
-Common::Error M4Engine::run() {
- // Set up the graphics mode
- initGraphics(640, 480, true);
-
- // Necessary pre-initialisation
- _resourceManager = new M4ResourceManager(this);
-
- // Set up needed common functionality
- MadsM4Engine::run();
-
- // M4 specific initialisation
- _converse = new Converse(this);
-
- _scene = new M4Scene(this);
- _script->open("m4.dat");
-
-#ifdef SCRIPT_TEST
-
-#if 0
- ScriptFunction *func = _script->loadFunction("room_parser_142");
- _script->runFunction(func);
-#endif
-
-#if 1
- ScriptFunction *func = _script->loadFunction("room_daemon_951");
- for (int i = 1; i < 58; i++) {
- _vm->_kernel->trigger = i;
- _script->runFunction(func);
- debugCN(kDebugCore, "=================================\n");
- }
-#endif
-
- return Common::kNoError;
-#endif
-
- // Set up the inventory
-
- // Set up the game interface view
- //_interfaceView->inventoryAdd("Money", "", 55); // Sample item
-
- if (getGameType() == GType_Burger) {
- for (int i = 0; i < ARRAYSIZE(burger_inventory); i++) {
- char* itemName = strdup(burger_inventory[i].name);
- _inventory->registerObject(itemName, burger_inventory[i].scene,
- burger_inventory[i].icon);
- _inventory->addToBackpack(i); // debug: this adds ALL objects to the player's backpack
- }
- }
-
- // Show intro
-
- if (getGameType() == GType_Burger) {
- _kernel->newRoom = TITLE_SCENE_BURGER;
- } else {
- _scene->getBackgroundSurface()->loadBackgroundRiddle("main menu");
- _ws->setBackgroundSurface(_scene->getBackgroundSurface());
- }
-
- _viewManager->addView(_scene);
-
- // Setup game wide hotkeys. Note that Orion Burger used F2/F3 for Save/Restore,
- // but for standardisation with most other games, F5/F7 are also mapped
-
- _viewManager->systemHotkeys().add(Common::KEYCODE_ESCAPE, &escapeHotkeyHandler);
- _viewManager->systemHotkeys().add(Common::KEYCODE_F2, &saveGameHotkeyHandler);
- _viewManager->systemHotkeys().add(Common::KEYCODE_F3, &loadGameHotkeyHandler);
- _viewManager->systemHotkeys().add(Common::KEYCODE_F5, &saveGameHotkeyHandler);
- _viewManager->systemHotkeys().add(Common::KEYCODE_F7, &loadGameHotkeyHandler);
- _viewManager->systemHotkeys().add(Common::KEYCODE_F9, &gameMenuHotkeyHandler);
-
- // Start playing Orion Burger intro music
- //_midi->playMusic("999intro", 255, false, -1, -1);
-
- // TODO: start playing intro animations
-
- // TODO: Master Lu
-
- // Test for mouse
- _mouse->init("cursor", NULL);
- _mouse->setCursorNum(0);
- _mouse->cursorOn();
-
- _ws->assets()->loadAsset("SHOW SCRIPT", NULL);
- _ws->assets()->loadAsset("STREAM SCRIPT", NULL);
-
-#ifdef INTRO_TEST
- int curPart = 0;
- Machine *mach = NULL;
-#endif
-
- _ws->setSurfaceView(_scene);
-
- uint32 nextFrame = g_system->getMillis();
- while (!_events->quitFlag) {
-
- // This should probably be moved to either Scene or Kernel
- if (_kernel->currentRoom != _kernel->newRoom) {
-
- _ws->clear();
-
- _kernel->currentSection = _kernel->newRoom / 100;
- _kernel->currentRoom = _kernel->newRoom;
-
- _scene->loadScene(_kernel->currentRoom);
-
- _ws->setBackgroundSurface(_scene->getBackgroundSurface());
- _ws->setInverseColorTable(scene()->getInverseColorTable());
-
- _kernel->loadSectionScriptFunctions();
- _kernel->loadRoomScriptFunctions();
-
- _kernel->roomInit();
-
- _scene->show();
-
-#ifdef INTRO_TEST
- if (_kernel->currentRoom == 951) {
- curPart = 0;
- mach = _ws->streamSeries("PLANET X HILLTOP A", 1, 0x1000, 0);
- }
-#endif
-
- }
-
- eventHandler();
-
- // Call the updateState method of all views
- _viewManager->updateState();
-
- // Handle frame updates
- if (g_system->getMillis() >= nextFrame) {
-#ifdef INTRO_TEST
- // Orion Burger intro test (scene 951)
- // This is ugly and bad, machine is not deleted so there's a huge memory
- // leak too. But hey, we can see some of the intro!
- if (mach && mach->getState() == -1) {
- if (curPart == 0)
- mach = _ws->streamSeries("Planet X Low Ground Shot", 1, 0x1000, 0);
- else if (curPart == 1)
- mach = _ws->streamSeries("Planet X Hilltop B", 1, 0x1000, 0);
- else if (curPart == 2)
- mach = _ws->streamSeries("Space Station Panorama A", 1, 0x1000, 0);
- else if (curPart == 3)
- mach = _ws->streamSeries("Cargo Transfer Area A", 1, 0x1000, 0);
- else if (curPart == 4)
- mach = _ws->streamSeries("VP's Office A", 1, 0x1000, 0);
- else if (curPart == 5)
- mach = _ws->streamSeries("Hologram", 1, 0x1000, 0);
- else if (curPart == 6)
- mach = _ws->streamSeries("VP's Office B", 1, 0x1000, 0);
- else if (curPart == 7)
- mach = _ws->streamSeries("Cargo Transfer Area B", 1, 0x1000, 0);
- else if (curPart == 8)
- mach = _ws->streamSeries("Cargo Transfer Controls", 1, 0x1000, 0);
- else if (curPart == 9)
- mach = _ws->streamSeries("Space Station Panorama B", 1, 0x1000, 0);
- // This last scene is from the rolling demo
- //else if (curPart == 10)
- // mach = _ws->streamSeries("Call To Action", 1, 0x1000, 0);
- curPart++;
- }
-#endif
- _ws->update();
- _viewManager->refreshAll();
- nextFrame = g_system->getMillis();// + GAME_FRAME_DELAY;
-
- // TEST STUFF ONLY
- if (_player->commandReady) {
- _kernel->roomParser();
- _player->commandReady = false;
- }
-
- }
-
- g_system->delayMillis(10);
- }
-
- return Common::kNoError;
-}
-
-/*--------------------------------------------------------------------------*/
-
-MadsEngine::MadsEngine(OSystem *syst, const M4GameDescription *gameDesc): MadsM4Engine(syst, gameDesc) {
- // FIXME
- _madsVm = this;
-
- _globals = new MadsGlobals(this);
- _currentTimer = 0;
-}
-
-MadsEngine::~MadsEngine() {
-}
-
-Common::Error MadsEngine::run() {
- // Set up the graphics mode
- initGraphics(320, 200, false);
-
- // Necessary pre-initialisation
- _resourceManager = new MADSResourceManager(this);
-
- // Set up needed common functionality
- MadsM4Engine::run();
-
- _palette->setMadsSystemPalette();
-
- _mouse->init("cursor.ss", NULL);
- _mouse->setCursorNum(0);
-
- // Load MADS data files
- MadsGlobals *globs = (MadsGlobals *)_globals;
- globs->loadMadsVocab(); // vocab.dat
- globs->loadQuotes(); // quotes.dat
- globs->loadMadsMessagesInfo(); // messages.dat
- globs->loadMadsObjects();
-
- // Setup globals
- globs->_config.easyMouse = true;
- globs->_config.invObjectsStill = false;
- globs->_config.textWindowStill = false;
- globs->_config.storyMode = 1; // Naughty
- globs->_config.screenFades = 0;
-
- // Test code to dump all messages to the console
- //for (int i = 0; i < _globals->getMessagesSize(); i++)
- //debugCN(kDebugCore, "%s\n----------\n", _globals->loadMessage(i));
-
- if (getGameType() == GType_RexNebular) {
- MadsGameLogic::initializeGlobals();
-
- _scene = NULL;
- loadMenu(MAIN_MENU);
- } else {
- // Test code
- _scene = new MadsScene(this);
-
- startScene(FIRST_SCENE);
- RGBList *_bgPalData;
- _scene->loadBackground(FIRST_SCENE, &_bgPalData);
- _palette->addRange(_bgPalData);
- _scene->translate(_bgPalData);
-
- _scene->show();
-
- _font->setFont(FONT_MAIN_MADS);
- _font->current()->setColors(2, 1, 3);
- _font->current()->writeString(_scene->getBackgroundSurface(), "Testing the M4/MADS ScummVM engine", 5, 160, 310, 2);
- _font->current()->writeString(_scene->getBackgroundSurface(), "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 5, 180, 310, 2);
-
- if (getGameType() == GType_DragonSphere) {
- //_scene->showMADSV2TextBox("Test", 10, 10, NULL);
- }
-
- _mouse->cursorOn();
- }
-
- _viewManager->systemHotkeys().add(Common::KEYCODE_ESCAPE, &escapeHotkeyHandler);
- _viewManager->systemHotkeys().add(Common::KEYCODE_KP_MULTIPLY, &textviewHotkeyHandler);
-
- uint32 nextFrame = g_system->getMillis();
- while (!_events->quitFlag) {
- eventHandler();
-
- if (g_system->getMillis() >= nextFrame) {
- nextFrame = g_system->getMillis() + GAME_FRAME_DELAY;
- ++_currentTimer;
-
- // Call the updateState method of all views
- _viewManager->updateState();
-
- // Refresh the display
- _viewManager->refreshAll();
- }
-
- g_system->delayMillis(10);
-
- if (globals()->dialogType != DIALOG_NONE)
- showDialog();
- }
-
- return Common::kNoError;
-}
-
-void MadsEngine::showDialog() {
- // Switch to showing the given dialog
- RexDialogView *dlg = NULL;
- switch (globals()->dialogType) {
- case DIALOG_GAME_MENU:
- dlg = new RexGameMenuDialog();
- break;
- case DIALOG_OPTIONS:
- dlg = new RexOptionsDialog();
- break;
- default:
- error("Unknown dialog type");
- };
-
- globals()->dialogType = DIALOG_NONE;
- _viewManager->addView(dlg);
-}
-
-} // End of namespace M4
diff --git a/engines/m4/m4.h b/engines/m4/m4.h
deleted file mode 100644
index b40ba0e878..0000000000
--- a/engines/m4/m4.h
+++ /dev/null
@@ -1,252 +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 M4_H
-#define M4_H
-
-#include "common/scummsys.h"
-#include "common/util.h"
-#include "common/random.h"
-
-#include "engines/engine.h"
-
-#include "m4/globals.h"
-#include "m4/graphics.h"
-#include "m4/resource.h"
-#include "m4/saveload.h"
-#include "m4/viewmgr.h"
-#include "m4/gui.h"
-#include "m4/events.h"
-#include "m4/font.h"
-#include "m4/scene.h"
-#include "m4/mads_player.h"
-#include "m4/mads_scene.h"
-#include "m4/m4_scene.h"
-#include "m4/actor.h"
-#include "m4/sound.h"
-#include "m4/rails.h"
-#include "m4/converse.h"
-#include "m4/animation.h"
-
-//#define DUMP_SCRIPTS
-
-/**
- * This is the namespace of the M4 engine.
- *
- * Status of this engine:
- * This engine is eventually intended to compromise two evolutions of the same engine: 'MADS' for the
- * first generation of the engine, and 'M4' for the second generation. This engine is called M4 overall
- * simply because work first began on the M4 side (focusing on the game 'Orion Burger').
- *
- * MADS Status: The current game being focused on is 'Rex Nebular' by DreamMaster, who is implementing
- * functionality as he disassembles the games original executables. Currently the engine has no particular
- * game logic implemented, although it does have the title screen implemented, and displays the initial
- * game screen and some game interface elements
- *
- * M4 Status: Work on this engine began with the game 'Orion Burger'. Some of the user interface
- * functionality has been implemented. No further work has been done on this for some time, so progress
- * on this part of the engine can be considered frozen.
- *
- * Games using this engine:
- * MADS Games: Dragonsphere, Return of the Phantom, Rex Nebular and the Cosmic Gender Bender
- * M4 Games: Orion Burger, The Riddle of Master Lu
- */
-namespace M4 {
-
-class MidiPlayer;
-class FileSystem;
-class ResourceManager;
-class Mouse;
-class Events;
-class Scene;
-class ViewManager;
-class View;
-class Inventory;
-class M4InterfaceView;
-class ConversationView;
-class Actor;
-class Converse;
-class MadsConversation;
-class ScriptInterpreter;
-class WoodScript;
-class Animation;
-
-enum M4GameType {
- GType_Riddle = 1,
- GType_Burger = 2,
- GType_RexNebular = 3,
- GType_DragonSphere = 4,
- GType_Phantom = 5
-};
-
-enum Features {
- kFeaturesNone = 0,
- kFeaturesCD = 1 << 0,
- kFeaturesDemo = 1 << 1
-};
-
-enum {
- kFileTypeHash,
- kFileTypeHAG
-};
-
-enum {
- kDebugScript = 1 << 0,
- kDebugConversations = 1 << 1,
- kDebugGraphics = 1 << 2,
- kDebugSound = 1 << 3,
- kDebugCore = 1 << 4
-};
-
-#define MESSAGE_BASIC 1
-#define MESSAGE_INTERMEDIATE 2
-#define MESSAGE_DETAILED 3
-
-struct M4GameDescription;
-
-#define GAME_FRAME_DELAY 20
-
-#define VALIDATE_MADS assert(!_vm->isM4())
-
-inline void str_lower(char *s) { while (*s) { *s = tolower(*s); s++; } }
-inline void str_upper(char *s) { while (*s) { *s = toupper(*s); s++; } }
-
-inline long FixedMul(long a, long b) { return (long)(((float)a * (float)b) / 65536.0); }
-inline long FixedDiv(long a, long b) { return (long)(((float)a / (float)b) * 65536.0); }
-
-class MadsM4Engine : public Engine {
-private:
- Common::Error goMADS();
- Common::Error goM4();
-
-protected:
- // Engine APIs
- virtual Common::Error run();
-
- void shutdown();
-
- MidiPlayer *_midi;
-
-public:
- MadsM4Engine(OSystem *syst, const M4GameDescription *gameDesc);
- virtual ~MadsM4Engine();
-
- int getGameType() const;
- uint32 getFeatures() const;
- Common::Language getLanguage() const;
- Common::Platform getPlatform() const;
- bool isM4() const { return (getGameType() == GType_Riddle) || (getGameType() == GType_Burger); }
-
- const char *getGameFile(int fileType);
- Common::EventManager *eventMan() { return _eventMan; }
-
- const M4GameDescription *_gameDescription;
-
- ResourceManager *res() const { return _resourceManager; }
- MidiPlayer *midi() { return _midi; }
- Common::SaveFileManager *saveManager() { return _saveFileMan; }
- void dumpFile(const char *filename, bool uncompress);
- void eventHandler();
- bool delay(int duration, bool keyAborts = true, bool clickAborts = true);
- void loadMenu(MenuType menuType, bool loadSaveFromHotkey = false,
- bool calledFromMainMenu = false);
-
- // TODO: eventually these have to be removed
- int32 seed;
- void imath_seed(int32 seednum) { seed = seednum; }
- uint32 imath_random() { return(seed = (25173*seed + 13849) & 0xffff); }
- int32 imath_ranged_rand(int32 a, int32 b) { return (a + (((1 + ABS<int32>(b-a))*imath_random())>>16)); }
- long imath_ranged_rand16(long a, long b) { return ((a + FixedMul(1+ABS<int32>(b-a),imath_random()))); }
- //
-
- ResourceManager *_resourceManager;
- Globals *_globals;
-
- SaveLoad *_saveLoad;
- ViewManager *_viewManager;
- Palette *_palette;
- Kernel *_kernel;
- Player *_player;
- Mouse *_mouse;
- Events *_events;
- FontManager *_font;
- Actor *_actor;
- Scene *_scene;
- Dialogs *_dialogs;
- M4Surface *_screen;
- Inventory *_inventory;
- ConversationView *_conversationView;
- Sound *_sound;
- Rails *_rails;
- ScriptInterpreter *_script;
- WoodScript *_ws;
- Common::RandomSource *_random;
-
- Scene *scene() { return _scene; }
-};
-
-class MadsEngine : public MadsM4Engine {
-private:
- void showDialog();
-public:
- MadsConversation _converse;
- uint32 _currentTimer;
- MadsPlayer _player;
-public:
- MadsEngine(OSystem *syst, const M4GameDescription *gameDesc);
- virtual ~MadsEngine();
-
- virtual Common::Error run();
-
- MadsGlobals *globals() { return (MadsGlobals *)_globals; }
- MadsScene *scene() { return (MadsScene *)_scene; }
- void startScene(int sceneNum) {
- if (!_scene) {
- _scene = new MadsScene(this);
- ((MadsScene *)_scene)->initialize();
- }
- _scene->show();
- _scene->loadScene(101);
- }
-};
-
-class M4Engine : public MadsM4Engine {
-public:
- Converse *_converse;
-public:
- M4Engine(OSystem *syst, const M4GameDescription *gameDesc);
- virtual ~M4Engine();
-
- virtual Common::Error run();
-
- M4Globals *globals() { return (M4Globals *)_globals; }
- M4Scene *scene() { return (M4Scene *)_scene; }
-};
-
-// FIXME: remove globals
-extern MadsM4Engine *_vm;
-extern MadsEngine *_madsVm;
-extern M4Engine *_m4Vm;
-
-} // End of namespace M4
-
-#endif
diff --git a/engines/m4/m4_menus.cpp b/engines/m4/m4_menus.cpp
deleted file mode 100644
index 3384a82c8b..0000000000
--- a/engines/m4/m4_menus.cpp
+++ /dev/null
@@ -1,724 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#include "common/algorithm.h" // for find()
-#include "common/textconsole.h"
-#include "common/translation.h"
-#include "gui/dialog.h"
-#include "gui/message.h"
-
-#include "m4/m4_menus.h"
-#include "m4/m4_views.h"
-#include "m4/woodscript.h"
-#include "m4/midi.h"
-
-namespace M4 {
-
-const char *EmptySaveString = "<empty>";
-
-//--------------------------------------------------------------------------
-// Callback methods
-//
-// Following is a set of callback methods used to handle the execution
-// of buttons in the various dialogs
-//--------------------------------------------------------------------------
-
-// General function which simply closes the active menu
-
-void OrionCallbacks::closeMenuFn(DialogView *view, MenuObject *item) {
- view->close();
-}
-
-void OrionCallbacks::closeMenuFn(OrionMenuView *view) {
- closeMenuFn(view, NULL);
-}
-
-/* Game menu functions */
-
-void OrionCallbacks::gameOptionsMenuFn(DialogView *view, MenuObject *item) {
- view->vm()->loadMenu(OPTIONS_MENU);
- view->close();
-}
-
-void OrionCallbacks::gameSaveGameFn(DialogView *view, MenuObject *item) {
- view->vm()->loadMenu(SAVE_MENU);
- view->close();
-}
-
-void OrionCallbacks::gameLoadGameFn(DialogView *view, MenuObject *item) {
- view->vm()->loadMenu(LOAD_MENU);
- view->close();
-}
-
-void OrionCallbacks::gameExitFn(DialogView *view, MenuObject *item) {
- view->vm()->_events->quitFlag = true;
- view->close();
-}
-
-/* Options menu */
-
-void OrionCallbacks::optionsDigiSliderFn(DialogView *view, MenuObject *item) {
- // Digi volume slider changed
- int percent = ((MenuHorizSlider *) item)->percent();
-
- view->vm()->_sound->setVolume(percent * 255 / 100);
-}
-
-void OrionCallbacks::optionsMidiSliderFn(DialogView *view, MenuObject *item) {
- // Midi volume slider changed
- int percent = ((MenuHorizSlider *) item)->percent();
-
- view->vm()->midi()->setVolume(percent * 255 / 100);
-}
-
-void OrionCallbacks::optionsScrollingFn(DialogView *view, MenuObject *item) {
- // TODO: Change current Digi volume settings here
-}
-
-void OrionCallbacks::optionsCancelFn(DialogView *view, MenuObject *item) {
- // TODO: Reset original option settings here
- OrionMenuView *vw = (OrionMenuView *) view;
-
- vw->vm()->midi()->setVolume(vw->_originalMidiVolume);
-
- vw->vm()->loadMenu(GAME_MENU);
- vw->close();
-}
-
-void OrionCallbacks::optionsDoneFn(DialogView *view, MenuObject *item) {
- view->vm()->loadMenu(GAME_MENU);
- view->close();
-}
-
-void OrionCallbacks::optionsReturnFn(OrionMenuView *view) {
- optionsDoneFn(view, NULL);
-}
-
-void OrionCallbacks::optionsEscapeFn(OrionMenuView *view) {
- optionsCancelFn(view, NULL);
-}
-
-/* Save/Load dialog functions */
-
-// Save the current game
-
-void OrionCallbacks::saveLoadSaveFn(DialogView *view, MenuObject *item) {
- if (view->_selectedSlot == -1)
- return;
-
- MenuTextField *textItem = (MenuTextField *) view->getItem(SLTAG_TEXTFIELD);
- if (!textItem)
- return;
-
- textItem->setState(OS_NORMAL);
-
- // Save the game
- bool succeeded = view->vm()->_saveLoad->save(view->_selectedSlot + 1, textItem->getText());
-
- if (!succeeded) {
- GUI::MessageDialog dialog(_("Save game failed!"));
- dialog.runModal();
- }
-
- // Close the menu
- closeMenuFn(view, item);
-}
-
-void OrionCallbacks::saveLoadLoadFn(DialogView *view, MenuObject *item) {
- // TODO: load the selected save game
- closeMenuFn(view, item);
-}
-
-void OrionCallbacks::saveLoadSlotFn(DialogView *view, MenuObject *item) {
- OrionMenuView *vw = (OrionMenuView *) view;
- MenuSaveLoadText *button = (MenuSaveLoadText *) item;
-
- view->_selectedSlot = button->getIndex();
- view->_deleteSaveDesc = true;
-
- // Disable all the slots except the selected one
- for (int index = 0; index < SL_NUM_VISIBLE_SLOTS; ++index) {
- MenuSaveLoadText *currentItem = (MenuSaveLoadText *) view->getItem(SLTAG_SLOTS_START + index);
- if (currentItem->getIndex() != button->getIndex()) {
- currentItem->setState(OS_GREYED);
- }
- }
-
- // Get a copy of the slot bounds
- Common::Rect slotBounds = button->getBounds();
-
- if (view->getMenuType() == SAVE_MENU) {
- // Add in a text field for entry of the savegame name
- vw->items().push_back(new MenuTextField(view, SLTAG_TEXTFIELD,
- slotBounds.left, slotBounds.top, slotBounds.width(), slotBounds.height(), false,
- saveLoadSaveFn, (button->getText() == EmptySaveString) ? NULL : button->getText(),
- button->getIndex() + 1));
-
- } else {
- vw->items().push_back(new MenuTextField(view, SLTAG_TEXTFIELD,
- slotBounds.left, slotBounds.top, slotBounds.width(), slotBounds.height(), true,
- saveLoadLoadFn, button->getText(), button->getIndex() + 1));
- }
-
- // Hide the existing slot
- button->setVisible(false);
-
- // Disable the slider
-
- MenuVertSlider *slider = (MenuVertSlider *) view->getItem(SLTAG_VSLIDER);
- slider->setState(OS_GREYED);
-
- // Enable the save/load button
- MenuButton *btn = (MenuButton *) view->getItem(SLTAG_SAVELOAD);
- btn->setState(OS_NORMAL);
-}
-
-void OrionCallbacks::saveLoadCancelFn(DialogView *view, MenuObject *item) {
- OrionMenuView *vw = (OrionMenuView *) view;
-
- if (view->_selectedSlot != -1) {
- // Pressed cancel with a save selected, so revert back to no selection
-
- // Re-enable all the other slots
-
- for (int index = 0; index < SL_NUM_VISIBLE_SLOTS; ++index) {
- if (index != view->_selectedSlot) {
- MenuSaveLoadText *currentItem = (MenuSaveLoadText *) view->getItem(SLTAG_SLOTS_START + index);
- currentItem->setState(OS_NORMAL);
- }
- }
-
- // Show the previously hidden slot again
- MenuSaveLoadText *slot = (MenuSaveLoadText *) view->getItem(SLTAG_SLOTS_START + view->_selectedSlot);
- slot->setVisible(true);
- slot->setState(OS_NORMAL);
-
- // Remove the text selection
- MenuTextField *textField = (MenuTextField *) view->getItem(SLTAG_TEXTFIELD);
- delete textField;
- vw->items().remove(textField);
-
- // Set button enablement
- MenuButton *btn = (MenuButton *) view->getItem(SLTAG_SAVELOAD);
- btn->setState(OS_GREYED);
- btn = (MenuButton *) view->getItem(SLTAG_CANCEL);
- btn->setState(OS_NORMAL);
-
- // Re-enable the slider
-
- MenuVertSlider *slider = (MenuVertSlider *) view->getItem(SLTAG_VSLIDER);
- slider->setState(OS_NORMAL);
-
- view->_selectedSlot = -1;
-
- } else {
- // Close the dialog
- if (vw->_loadSaveFromHotkey)
- // Since dialog was called from hotkey, return directly to the game
- closeMenuFn(view, item);
- else {
- // Return to the game menu
- view->vm()->loadMenu(GAME_MENU);
- view->close();
- }
- }
-}
-
-void OrionCallbacks::saveLoadSliderFn(DialogView *view, MenuObject *item) {
- OrionMenuView *vw = (OrionMenuView *) view;
- MenuVertSlider *slider = (MenuVertSlider *) item;
-
- if (slider->sliderState() == VSLIDER_THUMBNAIL) {
- // Callback generated by slider thumb, so set top slot using slider percentage
- vw->setTopSaveSlot(slider->percent() * 89 / 100);
-
- } else {
- int newIndex = view->_topSaveSlotIndex;
-
- switch (slider->sliderState()) {
- case VSLIDER_UP:
- if (newIndex > 0)
- --newIndex;
- break;
-
- case VSLIDER_PAGE_UP:
- if (newIndex > 0)
- newIndex = MAX(newIndex - 10, 0);
- break;
-
- case VSLIDER_PAGE_DOWN:
- if (newIndex < 89)
- newIndex = MIN(newIndex + 10, 89);
- break;
-
- case VSLIDER_DOWN:
- if (newIndex < 89)
- ++newIndex;
- break;
-
- default:
- break;
- }
-
- if (newIndex != view->_topSaveSlotIndex) {
- // Set the new top slot
- vw->setTopSaveSlot(newIndex);
-
- // Set the new slider position
- slider->setPercentage(newIndex * 100 / 89);
- }
- }
-}
-
-void OrionCallbacks::saveLoadEscapeFn(OrionMenuView *view) {
- saveLoadCancelFn(view, NULL);
-}
-
-void OrionCallbacks::saveLoadReturnFn(OrionMenuView *view) {
- MenuTextField *textItem = (MenuTextField *) view->getItem(SLTAG_TEXTFIELD);
- if (textItem) {
- if (view->getMenuType() == SAVE_MENU)
- saveLoadSaveFn(view, NULL);
- else
- saveLoadLoadFn(view, NULL);
- }
-}
-
-//--------------------------------------------------------------------------
-
-OrionMenuView::OrionMenuView(MadsM4Engine *Vm, int x, int y, MenuType menuType, bool calledFromMainMenu,
- bool loadSaveFromHotkey): DialogView(Vm, x, y, true) {
- _menuType = menuType;
- _screenType = VIEWID_MENU;
- _screenFlags.layer = LAYER_MENU;
- _screenFlags.get = SCREVENT_ALL;
- _screenFlags.blocks = SCREVENT_ALL;
- _screenFlags.immovable = true;
- //_screenFlags.immovable = false; // uncomment to make menu movable
- _coords.left = x;
- _coords.top = y;
- _currentItem = NULL;
- _escapeHandler = &OrionCallbacks::closeMenuFn;
- _returnHandler = NULL;
- _saveNames = NULL;
- _savegameThumbnail = NULL;
- _deleteSaveDesc = false;
- _closeFlag = false;
-
- _calledFromMainMenu = calledFromMainMenu;
- _loadSaveFromHotkey = loadSaveFromHotkey;
-
- _interfaceWasVisible = _m4Vm->scene()->getInterface()->isVisible();
- if (_interfaceWasVisible)
- _m4Vm->scene()->getInterface()->hide();
-
- _vm->_mouse->setCursorNum(CURSOR_ARROW);
-
- switch (menuType) {
- case GAME_MENU:
- loadSprites(MENU_GAME);
-
- // Add menu contents
- _menuObjects.push_back(new MenuButton(this, BTNID_MAIN, 45, 53, 24, 24, &OrionCallbacks::closeMenuFn));
- _menuObjects.push_back(new MenuButton(this, BTNID_OPTIONS, 45, 94, 24, 24, &OrionCallbacks::gameOptionsMenuFn));
- _menuObjects.push_back(new MenuButton(this, BTNID_RESUME, 45, 135, 24, 24, &OrionCallbacks::closeMenuFn));
- _menuObjects.push_back(new MenuButton(this, BTNID_QUIT, 141, 135, 24, 24, &OrionCallbacks::gameExitFn));
- _menuObjects.push_back(new MenuButton(this, BTNID_SAVE, 141, 53, 24, 24, &OrionCallbacks::gameSaveGameFn, _calledFromMainMenu));
- _menuObjects.push_back(new MenuButton(this, BTNID_LOAD, 141, 94, 24, 24, &OrionCallbacks::gameLoadGameFn,
- !_vm->_saveLoad->hasSaves()));
-
- _escapeHandler = &OrionCallbacks::closeMenuFn;
- _returnHandler = &OrionCallbacks::closeMenuFn;
- break;
-
- case OPTIONS_MENU:
- loadSprites(MENU_OPTIONS);
-
- // Store the original settings in case user aborts dialog
- _originalMidiVolume = _vm->midi()->getVolume();
-
- // Add menu contents
- // TODO: Currently the Digi slider isn't hooked up to anything
- _menuObjects.push_back(new MenuButton(this, OPTIONID_CANCEL, 93, 141, 74, 43,
- &OrionCallbacks::optionsCancelFn, false, false, OBJTYPE_OM_CANCEL));
- _menuObjects.push_back(new MenuButton(this, OPTIONID_DONE, 168, 141, 74, 43,
- &OrionCallbacks::optionsDoneFn, false, false, OBJTYPE_OM_DONE));
- _menuObjects.push_back(new MenuHorizSlider(this, OPTIONID_HSLIDER_MIDI, 47, 64, 212, 24,
- _originalMidiVolume * 100 / 255, &OrionCallbacks::optionsMidiSliderFn, true));
- _menuObjects.push_back(new MenuHorizSlider(this, OPTIONID_HSLIDER_DIGI, 47, 104, 212, 24,
- 0, &OrionCallbacks::optionsDigiSliderFn, true));
-
- _escapeHandler = &OrionCallbacks::optionsEscapeFn;
- _returnHandler = &OrionCallbacks::optionsReturnFn;
- break;
-
- case SAVE_MENU:
- case LOAD_MENU:
- loadSprites(MENU_SAVELOAD);
-
- // Set up the defaults for the window
- _topSaveSlotIndex = 0;
- _selectedSlot = -1;
- _highlightedSlot = -1;
- _saveNames = _vm->_saveLoad->getSaves();
-
- // Set up menu elements
- _menuObjects.push_back(new MenuMessage(this, SLTAG_SAVELOAD_LABEL, 50, 241, 70, 16));
- _menuObjects.push_back(new MenuButton(this, SLTAG_SAVELOAD, 214, 384, 72, 41,
- (menuType == SAVE_MENU) ? &OrionCallbacks::saveLoadSaveFn : &OrionCallbacks::saveLoadLoadFn,
- true, true, (menuType == SAVE_MENU) ? OBJTYPE_SL_SAVE : OBJTYPE_SL_LOAD));
- _menuObjects.push_back(new MenuButton(this, SLTAG_CANCEL, 139, 384, 74, 43,
- &OrionCallbacks::saveLoadCancelFn, false, false, OBJTYPE_SL_CANCEL));
- _menuObjects.push_back(new MenuVertSlider(this, SLTAG_VSLIDER, 291, 255, 23, 127, 0,
- &OrionCallbacks::saveLoadSliderFn));
-
- if (_menuType == SAVE_MENU)
- _savegameThumbnail = createThumbnail();
-
- _menuObjects.push_back(new MenuImage(this, SLTAG_THUMBNAIL, 66, 28, 215, 162,
- (_savegameThumbnail == NULL) ? _sprites->getFrame(SL_EMPTY_THUMBNAIL) : _savegameThumbnail));
-
-
- {
- SaveGameIterator slot = _saveNames->begin();
- for (uint slotIndex = 0; slotIndex < SL_NUM_VISIBLE_SLOTS; ++slotIndex, ++slot) {
- // Get save slot
- bool isEmpty = (slotIndex >= _saveNames->size()) || (*slot).empty();
-
- _menuObjects.push_back(new MenuSaveLoadText(this, SLTAG_SLOTS_START + slotIndex,
- 50, 256 + slotIndex * 15, 238, 15, &OrionCallbacks::saveLoadSlotFn,
- (menuType == LOAD_MENU) && isEmpty, true, (menuType == LOAD_MENU),
- isEmpty ? EmptySaveString : slot->c_str(), slotIndex + 1));
- }
- }
-
- _escapeHandler = &OrionCallbacks::saveLoadEscapeFn;
- _returnHandler = &OrionCallbacks::saveLoadReturnFn;
- break;
-
- default:
- error("Unknown menu type");
- break;
- }
-
- // Draw all the items onto the background surface
- for (MenuObjectsIterator i = _menuObjects.begin(); i != _menuObjects.end(); ++i)
- (*i)->onRefresh();
-}
-
-OrionMenuView::~OrionMenuView() {
- delete _sprites;
-
- for (MenuObjectList::iterator i = _menuObjects.begin(); i != _menuObjects.end(); ++i)
- delete *i;
- _menuObjects.clear();
-
- delete _saveNames;
- delete _savegameThumbnail;
-}
-
-bool OrionMenuView::loadSprites(const char *seriesName) {
- Common::SeekableReadStream *data = _vm->res()->get(seriesName);
- RGB8 *palette;
-
- _sprites = new SpriteAsset(_vm, data, data->size(), seriesName);
- palette = _sprites->getPalette();
- _vm->_palette->setPalette(palette, 0, _sprites->getColorCount());
-
- _vm->res()->toss(seriesName);
-
- // Update the palette
- //_vm->setPalette((byte *) _menuPalette, 59, 197);
-
- // The first sprite is the menu background
-
- M4Sprite *bg = _sprites->getFrame(0);
- this->setSize(bg->width(), bg->height());
- _coords.setWidth(bg->width());
- _coords.setHeight(bg->height());
- bg->copyTo(this);
-
- return true;
-}
-
-// Creates a thumbnail based on the current background screen
-
-M4Surface *OrionMenuView::createThumbnail() {
- M4Surface srcSurface(_vm->_screen->width(), _vm->_screen->height());
- M4Surface *result = new M4Surface(_vm->_screen->width() / 3, _vm->_screen->height() / 3);
-
- // Translate the scene data
-
- _vm->_scene->onRefresh(NULL, &srcSurface);
- byte *srcP = srcSurface.getBasePtr(0, 0);
- byte *destP = result->getBasePtr(0, 0);
-
- for (int yCtr = 0; yCtr < _vm->_scene->height() / 3; ++yCtr, srcP += g_system->getWidth() * 3) {
- byte *src0P = srcP;
- byte *src1P = srcP + _vm->_screen->width();
- byte *src2P = src1P + _vm->_screen->width();
-
- for (int xCtr = 0; xCtr < result->width(); ++xCtr) {
- *destP = (byte)((uint32)((
- *src0P + *(src0P + 1) + *(src0P + 2) +
- *src1P + *(src1P + 1) + *(src1P + 2) +
- *src2P + *(src2P + 1) + *(src2P + 2)) / 9));
- if (*destP == 0)
- *destP = 21;
-
- ++destP;
- src0P += 3;
- src1P += 3;
- src2P += 3;
- }
- }
-
- // Translate the game interface view - since it's using standard colors that can't be
- // averaged, simply take the top left pixel of every 3x3 pixel block
-
- _m4Vm->scene()->getInterface()->onRefresh(NULL, &srcSurface);
- destP = result->getBasePtr(0, 0) + (_vm->_screen->width() / 3) * (_m4Vm->scene()->getInterface()->bounds().top / 3);
-
- int yStart = _m4Vm->scene()->getInterface()->bounds().top;
- int yEnd = MIN(_vm->_screen->height() - 1, (int) _m4Vm->scene()->getInterface()->bounds().bottom - 1);
- for (int yCtr = yStart; yCtr <= yEnd; yCtr += 3) {
- srcP = (byte *)srcSurface.getBasePtr(0, yCtr) + (yCtr * _vm->_screen->width());
-
- for (int xCtr = 0; xCtr < result->width(); ++xCtr, srcP += 3)
- *destP++ = *srcP;
- }
-
- return result;
-}
-
-void OrionMenuView::destroyView() {
- MadsM4Engine *engine = _vm;
- bool interfaceVisible = _interfaceWasVisible;
- engine->_viewManager->deleteView(this);
-
- // Fade the game back in if no menu views are active (such as if a button was pressed in one menu
- // to activate another menu dialog)
- bool fadeIn = engine->_viewManager->getView(VIEWID_MENU) == NULL;
-
- if (fadeIn) {
- bool fadeToBlack = engine->_events->quitFlag;
- engine->_ws->update();
- engine->_palette->fadeFromGreen(M4_DIALOG_FADE_STEPS, M4_DIALOG_FADE_DELAY, fadeToBlack);
-
- if (interfaceVisible)
- engine->scene()->showInterface();
- }
-}
-
-bool OrionMenuView::onEvent(M4EventType eventType, int32 param, int x, int y, bool &captureEvents) {
- static Common::Point movingPos(0, 0);
- static bool movingFlag = false;
-
- bool handledFlag = false;
- int localX, localY;
- MenuObjectsIterator i;
-
- if (!_screenFlags.visible)
- return false;
-
- if (!movingFlag)
- captureEvents = false;
-
- // If the escape key is pressed, then pass onto the Escape handler
-
- if (eventType == KEVENT_KEY) {
- if ((param == Common::KEYCODE_ESCAPE) && (_escapeHandler != NULL)) {
- // Execute the Escape handler function
- _currentItem = NULL;
- captureEvents = false;
- _escapeHandler(this);
- destroyView();
- return true;
- }
-
- if (((param == Common::KEYCODE_RETURN) || (param == Common::KEYCODE_KP_ENTER)) &&
- (_returnHandler != NULL)) {
- // Execute the Return handler function
- _currentItem = NULL;
- captureEvents = false;
- _returnHandler(this);
- return true;
- }
-
- MenuTextField *textItem = (MenuTextField *) getItem(SLTAG_TEXTFIELD);
- if (textItem && textItem->onEvent(KEVENT_KEY, param, x, y, _currentItem))
- return true;
- }
-
- // Convert the screen position to a relative position within the menu surface
- localX = x - _coords.left;
- localY = y - _coords.top;
-
- // If there is an active object handling events, pass it on until it releases control
-
- if (_currentItem) {
- handledFlag = _currentItem->onEvent(eventType, param, localX, localY, _currentItem);
-
- if (_closeFlag) {
- // Dialog has been flagged to be closed
- captureEvents = false;
- destroyView();
- return true;
- }
-
- if (_currentItem) {
- captureEvents =
- (Common::find(_menuObjects.begin(), _menuObjects.end(), _currentItem) != _menuObjects.end());
- if (!captureEvents)
- // The menu object is no longer active, so reset current item
- _currentItem = NULL;
- } else {
- captureEvents = false;
- }
-
- if (handledFlag)
- return true;
- }
-
- if (eventType == KEVENT_KEY) {
- // Handle keypresses by looping through the item list to see if any of them want it
-
- for (i = _menuObjects.begin(); (i != _menuObjects.end()) && !handledFlag; ++i) {
- MenuObject *menuObj = *i;
- MenuObject *dummyItem;
- handledFlag = menuObj->onEvent(eventType, param, localX, localY, dummyItem);
- }
-
- return handledFlag;
-
- } else {
- // Handle mouse events by scanning the item list to see if the cursor is within any
-
- for (i = _menuObjects.begin(); (i != _menuObjects.end()) && !handledFlag; ++i) {
- MenuObject *menuObj = *i;
-
- if (menuObj->isInside(localX, localY)) {
- // Found an item, so pass it the event
- menuObj->onEvent(eventType, param, localX, localY, _currentItem);
-
- if (_closeFlag) {
- // Dialog has been flagged to be closed
- captureEvents = false;
- destroyView();
- return true;
- }
-
- if (_currentItem) {
- captureEvents =
- (Common::find(_menuObjects.begin(), _menuObjects.end(), _currentItem) != _menuObjects.end());
- if (!captureEvents)
- // The menu object is no longer active, so reset current item
- _currentItem = NULL;
- } else {
- captureEvents = false;
- }
-
- return true;
- }
- }
- }
-
- // None of the items have handled the event, so fall back on menu-wide event handling
-
- switch (eventType) {
- case MEVENT_LEFT_CLICK:
- case MEVENT_DOUBLECLICK:
- if (!_screenFlags.immovable) {
- // Move the entire dialog
- captureEvents = true;
- movingFlag = true;
- movingPos.x = x;
- movingPos.y = y;
- }
- break;
-
- case MEVENT_LEFT_DRAG:
- case MEVENT_DOUBLECLICK_DRAG:
- if (movingFlag) {
- moveRelative(x - movingPos.x, y - movingPos.y);
- movingPos.x = x;
- movingPos.y = y;
- }
- break;
-
- case MEVENT_LEFT_RELEASE:
- case MEVENT_DOUBLECLICK_RELEASE:
- captureEvents = false;
- movingFlag = false;
- break;
-
- default:
- break;
- }
-
- return true;
-}
-
-MenuObject *OrionMenuView::getItem(int objectId) {
- MenuObjectsIterator i;
- for (i = _menuObjects.begin(); i != _menuObjects.end(); ++i) {
- MenuObject *obj = *i;
- if (obj->getObjectId() == objectId)
- return obj;
- }
-
- return NULL;
-}
-
-void OrionMenuView::setTopSaveSlot(int slotNumber) {
- _topSaveSlotIndex = MAX(MIN(slotNumber, 89), 0);
-
- // Update the details of the load/save slots
-
- // Get save slot
- SaveGameIterator slot = _saveNames->begin();
- for (int i = 0; i < _topSaveSlotIndex; ++i)
- ++slot;
-
- for (uint index = 0; index < SL_NUM_VISIBLE_SLOTS; ++index, ++slot) {
- MenuSaveLoadText *item = (MenuSaveLoadText *) getItem(SLTAG_SLOTS_START + index);
- uint slotIndex = _topSaveSlotIndex + index;
-
- bool isEmpty = (slotIndex >= _saveNames->size()) || slot->empty();
- item->setDisplay(slotIndex + 1, isEmpty ? EmptySaveString : slot->c_str());
-
- item->setState((_menuType == SAVE_MENU) || !isEmpty ? OS_NORMAL : OS_GREYED);
- }
-}
-
-void OrionMenuView::refresh(const Common::Rect &areaRect) {
- // Copy the selected portion of the background
- _sprites->getFrame(0)->copyTo(this, areaRect, areaRect.left, areaRect.top);
-
- for (MenuObjectsIterator i = _menuObjects.begin(); i != _menuObjects.end(); ++i) {
- MenuObject *obj = *i;
- if (obj->getBounds().intersects(areaRect))
- obj->onRefresh();
- }
-}
-
-}
diff --git a/engines/m4/m4_menus.h b/engines/m4/m4_menus.h
deleted file mode 100644
index 9abf71e9db..0000000000
--- a/engines/m4/m4_menus.h
+++ /dev/null
@@ -1,103 +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 M4_M4_MENUS_H
-#define M4_M4_MENUS_H
-
-#include "common/list.h"
-#include "common/ptr.h"
-
-#include "m4/viewmgr.h"
-#include "m4/m4.h"
-#include "m4/gui.h"
-#include "m4/saveload.h"
-
-namespace M4 {
-
-#define M4_DIALOG_FADE_STEPS 5
-#define M4_DIALOG_FADE_DELAY 30
-
-typedef Common::List<MenuObject *> MenuObjectList;
-
-class OrionMenuView : public DialogView {
- typedef MenuObjectList::iterator MenuObjectsIterator;
-private:
- MenuType _menuType;
- SpriteAsset *_sprites;
- MenuObjectList _menuObjects;
- MenuObject *_currentItem;
- typedef void (*Callback)(OrionMenuView *view);
- OrionMenuView::Callback _escapeHandler, _returnHandler;
- bool _closeFlag;
- bool _calledFromMainMenu;
- bool _interfaceWasVisible;
- int _firstSlotIndex;
-
- bool loadSprites(const char *seriesName);
- M4Surface *createThumbnail();
- void destroyView();
-public:
- OrionMenuView(MadsM4Engine *vm, int x, int y, MenuType menuType, bool calledFromMainMenu,
- bool loadSaveFromHotkey);
- ~OrionMenuView();
- MenuType getMenuType() { return _menuType; }
- SpriteAsset *sprites() { return _sprites; }
- MenuObjectList &items() { return _menuObjects; }
- MenuObject *getItem(int objectId);
- void setTopSaveSlot(int slotNumber);
- void refresh(const Common::Rect &areaRect);
- void close() { _closeFlag = true; }
-
- bool onEvent(M4EventType eventType, int32 param, int x, int y, bool &captureEvents);
-
- int _originalMidiVolume;
- SaveGameList *_saveNames;
- bool _loadSaveFromHotkey;
-};
-
-class OrionCallbacks {
-public:
- static void closeMenuFn(DialogView *view, MenuObject *item);
- static void closeMenuFn(OrionMenuView *view);
- static void gameOptionsMenuFn(DialogView *view, MenuObject *item);
- static void gameSaveGameFn(DialogView *view, MenuObject *item);
- static void gameLoadGameFn(DialogView *view, MenuObject *item);
- static void gameExitFn(DialogView *view, MenuObject *item);
- static void optionsDigiSliderFn(DialogView *view, MenuObject *item);
- static void optionsMidiSliderFn(DialogView *view, MenuObject *item);
- static void optionsScrollingFn(DialogView *view, MenuObject *item);
- static void optionsCancelFn(DialogView *view, MenuObject *item);
- static void optionsDoneFn(DialogView *view, MenuObject *item);
- static void optionsReturnFn(OrionMenuView *view);
- static void optionsEscapeFn(OrionMenuView *view);
- static void saveLoadSaveFn(DialogView *view, MenuObject *item);
- static void saveLoadLoadFn(DialogView *view, MenuObject *item);
- static void saveLoadSlotFn(DialogView *view, MenuObject *item);
- static void saveLoadCancelFn(DialogView *view, MenuObject *item);
- static void saveLoadSliderFn(DialogView *view, MenuObject *item);
- static void saveLoadEscapeFn(OrionMenuView *view);
- static void saveLoadReturnFn(OrionMenuView *view);
-};
-
-}
-
-#endif
diff --git a/engines/m4/m4_scene.cpp b/engines/m4/m4_scene.cpp
deleted file mode 100644
index 1a2e00e50d..0000000000
--- a/engines/m4/m4_scene.cpp
+++ /dev/null
@@ -1,326 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#include "common/system.h"
-#include "common/textconsole.h"
-
-#include "m4/m4_scene.h"
-#include "m4/dialogs.h"
-#include "m4/globals.h"
-#include "m4/events.h"
-#include "m4/graphics.h"
-#include "m4/rails.h"
-#include "m4/font.h"
-#include "m4/m4_views.h"
-#include "m4/mads_views.h"
-#include "m4/compression.h"
-
-namespace M4 {
-
-M4Scene::M4Scene(M4Engine *vm): _sceneResources(), Scene(vm, &_sceneResources) {
- _vm = vm;
- _sceneSprites = NULL;
- _inverseColorTable = NULL;
-
- _sceneResources.hotspots = new HotSpotList();
- _sceneResources.parallax = new HotSpotList();
- _sceneResources.dynamicHotspots = new HotSpotList();
- _interfaceSurface = new M4InterfaceView(vm);
-}
-
-M4Scene::~M4Scene() {
- delete _sceneSprites;
-}
-
-void M4Scene::loadSceneSprites(int sceneNumber) {
- char filename[kM4MaxFilenameSize];
- sprintf(filename, "%i.ssb", sceneNumber);
-
- Common::SeekableReadStream *sceneS = _vm->res()->get(filename);
- _sceneSprites = new SpriteAsset(_vm, sceneS, sceneS->size(), filename);
- _vm->res()->toss(filename);
-
- debugCN(kDebugGraphics, "Scene has %d sprites, each one having %d colors\n", _sceneSprites->getCount(), _sceneSprites->getColorCount());
-}
-
-void M4Scene::loadSceneResources(int sceneNumber) {
- char filename[kM4MaxFilenameSize];
- int i = 0, x = 0, y = 0;
- sprintf(filename, "%i.chk", sceneNumber);
-
- Common::SeekableReadStream *sceneS = _vm->res()->get(filename);
-
- if (sceneS != NULL) {
- sceneS->read(_sceneResources.artBase, MAX_CHK_FILENAME_SIZE);
- sceneS->read(_sceneResources.pictureBase, MAX_CHK_FILENAME_SIZE);
- int hotspotCount = sceneS->readUint32LE();
- _sceneResources.parallaxCount = sceneS->readUint32LE();
- int dynHotspotCount = sceneS->readUint32LE();
- _sceneResources.frontY = sceneS->readUint32LE();
- _sceneResources.backY = sceneS->readUint32LE();
- _sceneResources.frontScale = sceneS->readUint32LE();
- _sceneResources.backScale = sceneS->readUint32LE();
- for (i = 0; i < 16; i++)
- _sceneResources.depthTable[i] = sceneS->readUint16LE();
- _sceneResources.railNodeCount = sceneS->readUint32LE();
-
- // Clear rails from previous scene
- _vm->_rails->clearRails();
-
- for (i = 0; i < _sceneResources.railNodeCount; i++) {
- x = sceneS->readUint32LE();
- y = sceneS->readUint32LE();
- if (_vm->_rails->addRailNode(x, y, true) < 0) {
- warning("Too many rail nodes defined for scene");
- }
- }
-
- // Clear current hotspot lists
- _sceneResources.hotspots->clear();
- _sceneResources.parallax->clear();
- _sceneResources.dynamicHotspots->clear();
-
- _sceneResources.hotspots->loadHotSpots(sceneS, hotspotCount);
- _sceneResources.parallax->loadHotSpots(sceneS, _sceneResources.parallaxCount);
- _sceneResources.dynamicHotspots->loadHotSpots(sceneS, dynHotspotCount);
-
- // Note that toss() deletes the MemoryReadStream
- _vm->res()->toss(filename);
- }
-}
-
-void M4Scene::loadSceneInverseColorTable(int sceneNumber) {
- char filename[kM4MaxFilenameSize];
- Common::SeekableReadStream *iplS;
-
- sprintf(filename, "%i.ipl", sceneNumber);
- iplS = _vm->res()->openFile(filename);
- delete[] _inverseColorTable;
- _inverseColorTable = new byte[iplS->size()];
- iplS->read(_inverseColorTable, iplS->size());
- _vm->res()->toss(filename);
-}
-
-void M4Scene::loadSceneSpriteCodes(int sceneNumber) {
- char filename[kM4MaxFilenameSize];
- sprintf(filename, "%i.ssc", sceneNumber);
-
- Common::SeekableReadStream *sceneS = _vm->res()->get(filename);
-
- // TODO
-
- if (sceneS != NULL) {
- SpriteAsset* _sceneSpriteCodes = new SpriteAsset(_vm, sceneS, sceneS->size(), filename);
- int colorCount = _sceneSpriteCodes->getColorCount();
-// RGB8* spritePalette = _sceneSpriteCodes->getPalette();
- //_vm->_palette->setPalette(spritePalette, 0, colorCount);
-
- debugCN(kDebugGraphics, "Scene has %d sprite codes, each one having %d colors\n", _sceneSpriteCodes->getCount(), colorCount);
-
- // Note that toss() deletes the MemoryReadStream
- _vm->res()->toss(filename);
- }
-}
-
-void M4Scene::loadScene(int sceneNumber) {
- Scene::loadScene(sceneNumber);
-
- _backgroundSurface->loadBackground(sceneNumber);
- _palData = NULL;
-
- if (_vm->getGameType() == GType_Burger &&
- sceneNumber != TITLE_SCENE_BURGER && sceneNumber != MAINMENU_SCENE_BURGER)
- setStatusText("");
-
- // Load scene def file (*.CHK)
- loadSceneResources(sceneNumber);
-
- // TODO: set walker scaling
- // TODO: destroy woodscript buffer
-
- // Load scene walk path file (*.COD/*.WW?)
- loadSceneCodes(sceneNumber);
-
- // Load inverse color table file (*.IPL)
- loadSceneInverseColorTable(sceneNumber);
-
- if (_vm->getGameType() != GType_Burger) {
- // Load scene sprites file (*.SSB)
- loadSceneSprites(sceneNumber);
-
- // Load scene sprite codes file (*.SSC)
- loadSceneSpriteCodes(sceneNumber);
- }
-
-
- if (sceneNumber != TITLE_SCENE_BURGER && sceneNumber != MAINMENU_SCENE_BURGER) {
- _m4Vm->scene()->getInterface()->show();
- showSprites();
- }
-
- // Purge resources
- _vm->res()->purge();
-}
-
-void M4Scene::loadSceneCodes(int sceneNumber, int index) {
- char filename[kM4MaxFilenameSize];
- Common::SeekableReadStream *sceneS;
-
- sprintf(filename, "%i.cod", sceneNumber);
- sceneS = _vm->res()->openFile(filename);
- _walkSurface->loadCodesM4(sceneS);
- _vm->res()->toss(filename);
-}
-
-void M4Scene::show() {
- Scene::show();
- _vm->_viewManager->addView(_interfaceSurface);
-}
-
-void M4Scene::leaveScene() {
- _sceneResources.parallax->clear();
-
- delete _sceneResources.parallax;
- delete[] _inverseColorTable;
-
- Scene::leaveScene();
-}
-
-void M4Scene::mouseMove(int x, int y) {
- if (_vm->getGameType() == GType_Riddle)
- return;
-
- // TODO: loads of things to do here, only the mouse cursor and the status
- // text is changed for now
-
- // Only scene hotspots are checked for now, not parallax/props, as the
- // latter ones are not used by Orion Burger
- HotSpot *currentHotSpot = _sceneResources.hotspots->findByXY(x, y);
- if (currentHotSpot != NULL && currentHotSpot->getActive()) {
- if (_vm->_mouse->getCursorNum() != CURSOR_LOOK &&
- _vm->_mouse->getCursorNum() != CURSOR_TAKE &&
- _vm->_mouse->getCursorNum() != CURSOR_USE &&
- _m4Vm->scene()->getInterface()->_inventory.getSelectedIndex() == -1) {
- _vm->_mouse->setCursorNum(currentHotSpot->getCursor());
- }
- _m4Vm->scene()->getInterface()->setStatusText(currentHotSpot->getPrep());
- } else {
- if (_vm->_mouse->getCursorNum() != CURSOR_LOOK &&
- _vm->_mouse->getCursorNum() != CURSOR_TAKE &&
- _vm->_mouse->getCursorNum() != CURSOR_USE &&
- _m4Vm->scene()->getInterface()->_inventory.getSelectedIndex() == -1) {
- _vm->_mouse->setCursorNum(0);
- } else {
-
- }
- }
-}
-
-void M4Scene::leftClick(int x, int y) {
- if (_vm->getGameType() == GType_Burger) {
- // Place a Wilbur sprite with the correct facing
- HotSpot *currentHotSpot = _sceneResources.hotspots->findByXY(x, y);
- if (currentHotSpot != NULL && currentHotSpot->getActive()) {
- update();
- _vm->_actor->setWalkerDirection(currentHotSpot->getFacing());
- /*
- int posX = currentHotSpot->getFeetX();
- int posY = currentHotSpot->getFeetY() -
- scaleValue(_vm->_actor->getWalkerHeight(), _vm->_actor->getWalkerScaling(), 0);
- //_vm->_actor->placeWalkerSpriteAt(0, posX, posY);
- */
-
- // Player said.... (for scene scripts)
- debugCN(kDebugGraphics, "Player said: %s %s\n", currentHotSpot->getVerb(), currentHotSpot->getVocab());
-
- // FIXME: This should be moved somewhere else, and is incomplete
- if (_m4Vm->scene()->getInterface()->_inventory.getSelectedIndex() == -1) {
- if (_vm->_mouse->getVerb() == NULL) {
- strcpy(_vm->_player->verb, currentHotSpot->getVerb());
- } else {
- strcpy(_vm->_player->verb, _vm->_mouse->getVerb());
- }
- } else {
- strcpy(_vm->_player->verb, _m4Vm->scene()->getInterface()->_inventory.getSelectedObjectName());
- }
- strcpy(_vm->_player->noun, currentHotSpot->getVocab());
- strcpy(_vm->_player->object, "");
- _vm->_player->commandReady = true;
-
- debugCN(kDebugGraphics, "## Player said: %s %s\n", _vm->_player->verb, _vm->_player->noun);
-
- }
- }
-}
-
-void M4Scene::rightClick(int x, int y) {
- if (_vm->getGameType() == GType_Burger) {
- nextCommonCursor();
- _m4Vm->scene()->getInterface()->_inventory.clearSelected();
- }
-}
-
-void M4Scene::setAction(int action, int objectId) {
-}
-
-void M4Scene::setStatusText(const char *text) {
- getInterface()->setStatusText(text);
-}
-
-void M4Scene::update() {
-
-}
-
-void M4Scene::nextCommonCursor() {
- int cursorIndex = _vm->_mouse->getCursorNum();
-
- switch (cursorIndex) {
- case CURSOR_ARROW:
- cursorIndex = CURSOR_LOOK;
- break;
- case CURSOR_LOOK:
- cursorIndex = CURSOR_TAKE;
- break;
- case CURSOR_TAKE:
- cursorIndex = CURSOR_USE;
- break;
- case CURSOR_USE:
- cursorIndex = CURSOR_ARROW;
- break;
- default:
- cursorIndex = CURSOR_ARROW;
- }
-
- _vm->_mouse->setCursorNum(cursorIndex);
-}
-
-void M4Scene::showHotSpots() {
- Scene::showHotSpots();
-
- // parallax (yellow)
- for (int i = 0; i < _sceneResources.parallaxCount; i++) {
- HotSpot *currentHotSpot = _sceneResources.parallax->get(i);
- _backgroundSurface->frameRect(currentHotSpot->getRect(), _vm->_palette->YELLOW);
- }
-}
-
-} // End of namespace M4
diff --git a/engines/m4/m4_scene.h b/engines/m4/m4_scene.h
deleted file mode 100644
index a0ba497cf7..0000000000
--- a/engines/m4/m4_scene.h
+++ /dev/null
@@ -1,84 +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 M4_M4_SCENE_H
-#define M4_M4_SCENE_H
-
-class View;
-
-#include "m4/scene.h"
-
-namespace M4 {
-
-#define TITLE_SCENE_BURGER 951 // 951 = intro, 901 = demo menu, 971 = first scene
-#define MAINMENU_SCENE_BURGER 903
-#define FIRST_SCENE 101
-
-class M4SceneResources : public SceneResources {
-public:
- int32 frontY, backY;
- int32 frontScale, backScale;
- int16 depthTable[16];
- int32 railNodeCount; // # of rails
-
- int32 parallaxCount;
- HotSpotList *parallax;
-};
-
-class M4Scene : public Scene {
-private:
- M4Engine *_vm;
- M4SceneResources _sceneResources;
- SpriteAsset *_sceneSprites;
- SpriteAsset *_walkerSprite;
- byte *_inverseColorTable;
-
- void loadSceneSprites(int sceneNumber);
- void loadSceneResources(int sceneNumber);
- void loadSceneInverseColorTable(int sceneNumber);
- void loadSceneSpriteCodes(int sceneNumber);
- void nextCommonCursor();
-public:
- M4Scene(M4Engine *vm);
- virtual ~M4Scene();
-
- // Methods that differ between engines
- virtual void loadScene(int sceneNumber);
- virtual void leaveScene();
- virtual void loadSceneCodes(int sceneNumber, int index = 0);
- virtual void show();
- virtual void mouseMove(int x, int y);
- virtual void leftClick(int x, int y);
- virtual void rightClick(int x, int y);
- virtual void update();
- virtual void showHotSpots();
-
- byte *getInverseColorTable() const { return _inverseColorTable; }
- M4InterfaceView *getInterface() { return (M4InterfaceView *)_interfaceSurface; }
- M4SceneResources &getSceneResources() { return _sceneResources; }
- void setStatusText(const char *text);
- void setAction(int action, int objectId = -1);
-};
-
-} // End of namespace M4
-
-#endif
diff --git a/engines/m4/m4_views.cpp b/engines/m4/m4_views.cpp
deleted file mode 100644
index 1324526ab5..0000000000
--- a/engines/m4/m4_views.cpp
+++ /dev/null
@@ -1,342 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#include "common/textconsole.h"
-
-#include "m4/m4_views.h"
-#include "m4/events.h"
-#include "m4/font.h"
-#include "m4/globals.h"
-#include "m4/m4.h"
-
-namespace M4 {
-
-GUIInventory::GUIInventory(View *owner, MadsM4Engine *vm, const Common::Rect &bounds, int horizCells,
- int vertCells, int cellWidth, int cellHeight, int tag): GUIRect(owner, bounds, tag) {
-
- _vm = vm;
- _cellCount.x = horizCells;
- _cellCount.y = vertCells;
- _cellSize.x = cellWidth;
- _cellSize.y = cellHeight;
-
- // Validate the cell settings
- if ((_cellCount.x * _cellSize.x > _bounds.width()) ||
- (_cellCount.y * _cellSize.y > _bounds.height()))
- error("Cell settings for inventory display exceeded control size");
-
- _visible = true;
- _scrollPosition = 0;
- _scrollable = false;
- _highlightedIndex = -1;
- _selectedIndex = -1;
-}
-
-void GUIInventory::onRefresh() {
- _parent->fillRect(_bounds, _vm->_palette->BLACK);
- //_parent->frameRect(_bounds, _vm->_palette->LIGHT_GRAY);
-
- if (_visible) {
- //kernel_trigger_dispatch(kernel_trigger_create(TRIG_INV_CLICK));
-
- _scrollable = false;
-
- // Get to the starting inventory position for display
- ItemsIterator i = _inventoryItems.begin();
- int index = _scrollPosition;
- while (index-- > 0) ++i;
-
- // Loop through displaying entries
- for (index = 0; (i != _inventoryItems.end()) && (index < _cellCount.x * _cellCount.y); ++index, ++i) {
- GUIInventoryItem *item = (*i).get();
- const Common::Point cellPos = getCellPosition(index);
-/* Common::Rect cellBounds(_bounds.left + cellPos.x + xOffset,
- _bounds.top + cellPos.y + yOffset,
- _bounds.left + cellPos.x + xOffset + _cellSize.x,
- _bounds.top + cellPos.y + _cellSize.y);*/
- Common::Rect cellBounds(_bounds.left + cellPos.x, _bounds.top + cellPos.y,
- _bounds.left + cellPos.x + _cellSize.x, _bounds.top + cellPos.y + _cellSize.y);
-
- Common::Point iconPt(
- cellBounds.left + (cellBounds.width() - item->icon->width()) / 2,
- cellBounds.top + (cellBounds.height() - item->icon->height()) / 2);
-
- item->icon->copyTo(_parent, iconPt.x, iconPt.y, 0);
-
- if (_highlightedIndex == index)
- _parent->frameRect(Common::Rect(iconPt.x - 2, iconPt.y - 2,
- iconPt.x + item->icon->width() + 2, iconPt.y + item->icon->height() + 2),
- _vm->_palette->LIGHT_GRAY);
- }
- }
-}
-
-bool GUIInventory::onEvent(M4EventType eventType, int32 param, int x, int y, GUIObject *&currentItem) {
- bool result = false;
- int overIndex = getInsideIndex(x, y);
- bool isPressed = (eventType == MEVENT_LEFT_CLICK) || (eventType == MEVENT_LEFT_HOLD) ||
- (eventType == MEVENT_LEFT_DRAG);
- ItemsIterator curItem = _inventoryItems.begin();
-
- if (isPressed) {
- if (_selectedIndex == -1 && overIndex != -1) {
- setHighlight(overIndex);
- _selectedIndex = overIndex;
- for (int i = 0; i < _scrollPosition + _selectedIndex; i++)
- ++curItem;
- if (_scrollPosition + _selectedIndex < (int)_inventoryItems.size())
- _vm->_mouse->setCursorNum(curItem->get()->iconIndex);
- result = true;
- } else {
- // We are over something being tracked
- if (_selectedIndex == overIndex) {
- setHighlight(overIndex);
- result = true;
- } else {
- // Otherwise reset highlighting
- setHighlight(-1);
- result = false;
- }
- }
- } else {
- // No button pressed
- if (_selectedIndex == overIndex) {
- result = (_selectedIndex != -1);
- } else {
- result = (overIndex + _scrollPosition < (int)_inventoryItems.size());
- if (result) {
- for (int i = 0; i < overIndex + _scrollPosition; i++)
- ++curItem;
- _m4Vm->scene()->getInterface()->setStatusText(curItem->get()->name);
- }
- }
-
- // Stop tracking anything
- setHighlight(overIndex);
- }
-
- return result;
-}
-
-void GUIInventory::add(const char *name, const char *verb, M4Surface *icon, int iconIndex) {
- // First scan through the list to prevent duplicate objects
- for (ItemsIterator i = _inventoryItems.begin(); i != _inventoryItems.end(); ++i) {
- if (!strcmp(name, ((*i).get())->name))
- return;
- }
-
- _inventoryItems.push_back(InventoryList::value_type(new GUIInventoryItem(name, verb, icon, iconIndex)));
-}
-
-bool GUIInventory::remove(const char *name) {
- for (ItemsIterator i = _inventoryItems.begin(); i != _inventoryItems.end(); ++i) {
- if (!strcmp(name, ((*i).get())->name)) {
- _inventoryItems.erase(i);
- _scrollPosition = 0;
- return true;
- }
- }
-
- return false;
-}
-
-int GUIInventory::getInsideIndex(int x, int y) {
- if (!_bounds.contains(x, y))
- return -1;
-
- int localX = x - _bounds.left;
- int localY = y - _bounds.top;
- return (localX / _cellSize.x) * _cellCount.y + (localY / _cellSize.y);
-}
-
-const char *GUIInventory::getSelectedObjectName() {
- if (_selectedIndex != -1) {
- ItemsIterator curItem = _inventoryItems.begin();
- for (int i = 0; i < _selectedIndex; i++)
- ++curItem;
- return curItem->get()->name;
- } else {
- return NULL;
- }
-}
-
-const Common::Point &GUIInventory::getCellPosition(int index) {
- static Common::Point result;
-
- if (_cellCount.x > _cellCount.y) {
- // Horizontal orientation
- result.x = (index / _cellCount.y) * _cellSize.x;
- result.y = (index % _cellCount.y) * _cellSize.x;
- } else {
- // Vertical orientation
- result.x = (index / _cellCount.x) * _cellSize.y;
- result.y = (index % _cellCount.x) * _cellSize.y;
- }
-
- return result;
-}
-
-void GUIInventory::setHighlight(int index) {
- if (_highlightedIndex == index)
- return;
-
- _highlightedIndex = index;
-}
-
-void GUIInventory::setScrollPosition(int value) {
- if (value < 0)
- return;
- else if (value >= (int)_inventoryItems.size() - (_cellCount.x * _cellCount.y))
- return;
-
- _scrollPosition = value;
-}
-
-//--------------------------------------------------------------------------
-
-const char *INTERFACE_SERIES = "999intr";
-
-#define SPR(x) _sprites->getFrame(x)
-
-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))),
- _inventory(GUIInventory(this, vm, Common::Rect(188, 22, 539, 97), 9, 1, 39, 75, 3)) {
-
- _screenType = VIEWID_INTERFACE;
- _screenFlags.layer = LAYER_INTERFACE;
- _screenFlags.visible = false;
- _screenFlags.get = SCREVENT_MOUSE;
- _highlightedIndex = -1;
- _selected = false;
-
- Common::SeekableReadStream *data = _vm->res()->get(INTERFACE_SERIES);
- _sprites = new SpriteAsset(_vm, data, data->size(), INTERFACE_SERIES);
-
- //RGB8 *palette = _sprites->getPalette();
- //Palette.setPalette(palette, 0, _sprites->getColorCount());
-
- _vm->res()->toss(INTERFACE_SERIES);
-
- // Setup the interface buttons
-
- _buttons.push_back(ButtonList::value_type(new GUIButton(this, Common::Rect(15, 35, 47, 66), 0, SPR(0), SPR(1), SPR(2)))); // look
- _buttons.push_back(ButtonList::value_type(new GUIButton(this, Common::Rect(60, 35, 92, 66), 1, SPR(3), SPR(4), SPR(5)))); // take
- _buttons.push_back(ButtonList::value_type(new GUIButton(this, Common::Rect(105, 35, 137, 66), 2, SPR(6), SPR(7), SPR(8)))); // manipulate
-
- _buttons.push_back(ButtonList::value_type(new GUIButton(this, Common::Rect(580, 10, 620, 69), 3, SPR(69), SPR(70), SPR(71)))); // abduction
- _buttons.push_back(ButtonList::value_type(new GUIButton(this, Common::Rect(582, 70, 619, 105), 4, SPR(76), SPR(77), SPR(78)))); // menu
-
- _buttons.push_back(ButtonList::value_type(new GUIButton(this, Common::Rect(168, 22, 188, 97), 5, SPR(60), SPR(61), SPR(62)))); // Scroll left
- _buttons.push_back(ButtonList::value_type(new GUIButton(this, Common::Rect(539, 22, 559, 97), 6, SPR(64), SPR(65), SPR(66)))); // Scroll right
-}
-
-#undef SPR
-
-M4InterfaceView::~M4InterfaceView() {
- delete _sprites;
-}
-
-void M4InterfaceView::setHighlightedButton(int index) {
- if (index == _highlightedIndex)
- return;
-
- _selected = (index == -1);
- _highlightedIndex = index;
-}
-
-bool M4InterfaceView::onEvent(M4EventType eventType, int32 param, int x, int y, bool &captureEvents) {
- static bool selectionFlag = false;
- if (eventType == MEVENT_LEFT_RELEASE)
- selectionFlag = false;
-
- captureEvents = isInside(x, y);
- if (!captureEvents)
- return false;
-
- int localX = x - _coords.left;
- int localY = y - _coords.top;
- GUIObject *currentItem;
-
- _statusText.onEvent(eventType, param, localX, localY, currentItem);
- _inventory.onEvent(eventType, param, localX, localY, currentItem);
-
- if (_vm->_mouse->getCursorNum() != CURSOR_LOOK &&
- _vm->_mouse->getCursorNum() != CURSOR_TAKE &&
- _vm->_mouse->getCursorNum() != CURSOR_USE &&
- _m4Vm->scene()->getInterface()->_inventory.getSelectedIndex() == -1) {
- if (_vm->_mouse->getCursorNum() != 0)
- _vm->_mouse->setCursorNum(0);
- }
-
- for (ButtonsIterator i = _buttons.begin(); i != _buttons.end(); ++i) {
- GUIButton *btn = (*i).get();
- btn->onEvent(eventType, param, localX, localY, currentItem);
- if ((btn->getState() == BUTTON_PRESSED) && !selectionFlag) {
- selectionFlag = true;
- _highlightedIndex = btn->getTag();
-
- switch (_highlightedIndex) {
- case 0:
- _vm->_mouse->setCursorNum(CURSOR_LOOK);
- break;
- case 1:
- _vm->_mouse->setCursorNum(CURSOR_TAKE);
- break;
- case 2:
- _vm->_mouse->setCursorNum(CURSOR_USE);
- break;
- case 3:
- // TODO: Jump to abduction
- break;
- case 4:
- _vm->loadMenu(GAME_MENU);
- break;
- case 5:
- _inventory.scrollLeft();
- break;
- case 6:
- _inventory.scrollRight();
- break;
- default:
- break;
- }
- }
- }
-
- return true;
-}
-
-void M4InterfaceView::onRefresh(RectList *rects, M4Surface *destSurface) {
- clear();
-
- _statusText.onRefresh();
- _inventory.onRefresh();
- for (ButtonsIterator i = _buttons.begin(); i != _buttons.end(); ++i)
- ((*i).get())->onRefresh();
-
- View::onRefresh(rects, destSurface);
-}
-
-
-} // End of namespace M4
diff --git a/engines/m4/m4_views.h b/engines/m4/m4_views.h
deleted file mode 100644
index 4ca2a74593..0000000000
--- a/engines/m4/m4_views.h
+++ /dev/null
@@ -1,115 +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 M4_M4_VIEWS_H
-#define M4_M4_VIEWS_H
-
-#include "m4/gui.h"
-#include "m4/viewmgr.h"
-#include "common/rect.h"
-#include "common/list.h"
-#include "common/ptr.h"
-
-namespace M4 {
-
-class GUIInventoryItem {
-public:
- const char *name;
- const char *verb;
- M4Surface *icon;
- int iconIndex;
-
- GUIInventoryItem(const char *_name, const char *_verb, M4Surface *_icon, int _iconIndex) {
- name = _name; verb = _verb; icon = _icon; iconIndex = _iconIndex;
- }
-};
-
-class GUIInventory : public GUIRect {
- typedef Common::List<Common::SharedPtr<GUIInventoryItem> > InventoryList;
- typedef InventoryList::iterator ItemsIterator;
-private:
- InventoryList _inventoryItems;
- Common::Point _cellSize;
- Common::Point _cellCount;
- bool _visible;
- bool _scrollable;
- int _scrollPosition;
- int _highlightedIndex;
- int _selectedIndex;
- MadsM4Engine *_vm;
-public:
- GUIInventory(View *owner, MadsM4Engine *vm, const Common::Rect &bounds,
- int horizCells, int vertCells, int cellWidth, int cellHeight, int tag);
-
- void onRefresh();
- bool onEvent(M4EventType eventType, int32 param, int x, int y, GUIObject *&currentItem);
-
- void add(const char *name, const char *verb, M4Surface *icon, int iconIndex);
- bool remove(const char *name);
- int getInsideIndex(int x, int y);
- int getSelectedIndex() { return _selectedIndex; }
- const char *getSelectedObjectName();
- void clearSelected() {
- _selectedIndex = -1;
- setHighlight(-1);
- }
- const Common::Point &getCellPosition(int index);
- void setHighlight(int index);
- bool needLeftButton() { return _scrollPosition != 0; }
- bool needRightButton() {
- return (uint)(_inventoryItems.size() - _scrollPosition) > (uint)(_cellCount.x * _cellCount.y);
- }
- void setScrollPosition(int value);
- void scrollLeft() { setScrollPosition(_scrollPosition - 1); }
- void scrollRight() { setScrollPosition(_scrollPosition + 1); }
- void setVisible(bool value) { _visible = value; }
-};
-
-class M4InterfaceView : public GameInterfaceView {
- typedef Common::List<Common::SharedPtr<GUIButton> > ButtonList;
- typedef ButtonList::iterator ButtonsIterator;
-public:
- SpriteAsset *_sprites;
- ButtonList _buttons;
- GUITextField _statusText;
- GUIInventory _inventory;
- int _highlightedIndex;
- bool _selected;
-private:
- void setHighlightedButton(int index);
-public:
- M4InterfaceView(MadsM4Engine *vm);
- ~M4InterfaceView();
-
- void onRefresh(RectList *rects, M4Surface *destSurface);
- bool onEvent(M4EventType eventType, int32 param, int x, int y, bool &captureEvents);
- void setStatusText(const char *text) { _statusText.setText(text); }
- void cancelSentence() { setStatusText(NULL); }
- void inventoryAdd(const char *name, const char *verb, int iconIndex) {
- _inventory.add(name, verb, _sprites->getFrame(iconIndex), iconIndex);
- }
- bool inventoryRemove(const char *name) { return _inventory.remove(name); }
-};
-
-}
-
-#endif
diff --git a/engines/m4/mads_anim.cpp b/engines/m4/mads_anim.cpp
deleted file mode 100644
index 2ea576dfa4..0000000000
--- a/engines/m4/mads_anim.cpp
+++ /dev/null
@@ -1,745 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#include "common/textconsole.h"
-
-#include "m4/mads_anim.h"
-#include "m4/m4.h"
-#include "m4/compression.h"
-
-namespace M4 {
-
-#define TEXTVIEW_LINE_SPACING 2
-#define TEXT_ANIMATION_DELAY 100
-#define TV_NUM_FADE_STEPS 40
-#define TV_FADE_DELAY_MILLI 50
-
-TextviewView::TextviewView(MadsM4Engine *vm):
- View(vm, Common::Rect(0, 0, vm->_screen->width(), vm->_screen->height())),
- _bgSurface(vm->_screen->width(), MADS_SURFACE_HEIGHT),
- _textSurface(vm->_screen->width(), MADS_SURFACE_HEIGHT + vm->_font->current()->getHeight() +
- TEXTVIEW_LINE_SPACING) {
-
- _screenType = VIEWID_TEXTVIEW;
- _screenFlags.layer = LAYER_BACKGROUND;
- _screenFlags.visible = true;
- _screenFlags.get = SCREVENT_ALL;
- _callback = NULL;
- _script = NULL;
- _spareScreen = NULL;
- _bgCurrent = NULL;
- _bgSpare = NULL;
- reset();
-
- // Set up system palette colors and the two colors for text display
- _vm->_palette->setMadsSystemPalette();
- RGB8 palData[3];
- palData[0].r = palData[0].g = palData[0].b = 0;
- palData[1].r = 0; palData[1].g = palData[1].b = 252;
- palData[2].r = 0; palData[2].g = palData[2].b = 180;
- _vm->_palette->setPalette(&palData[0], 4, 3);
- _vm->_palette->blockRange(4, 3);
-
- _vm->_font->current()->setColors(5, 6, 4);
-
- clear();
- _bgSurface.clear();
- _textSurface.clear();
-
- int y = (height() - MADS_SURFACE_HEIGHT) / 2;
- setColor(2);
- hLine(0, width() - 1, y - 2);
- hLine(0, width() - 1, height() - y + 1);
-}
-
-TextviewView::~TextviewView() {
- if (_script)
- _vm->res()->toss(_resourceName);
- delete _spareScreen;
- delete _bgCurrent;
- delete _bgSpare;
-}
-
-void TextviewView::reset() {
- _bgSurface.clear();
- _textSurface.clear();
- _animating = false;
- _panX = 0;
- _panY = 0;
- _panSpeed = 0;
- _soundDriverLoaded = false;
- Common::set_to(&_spareScreens[0], &_spareScreens[10], 0);
- _scrollCount = 0;
- _lineY = -1;
- _scrollTimeout = 0;
- _panCountdown = 0;
- _processEvents = true;
-}
-
-void TextviewView::setScript(const char *resourceName, TextviewCallback callback) {
- _callback = callback;
- if (_script)
- _vm->res()->toss(_resourceName);
- if (_spareScreen) {
- delete _spareScreen;
- _spareScreen = NULL;
- }
-
- reset();
-
- strncpy(_resourceName, resourceName, 15);
- _resourceName[15] = '\0';
- if (!strchr(_resourceName, '.'))
- strcat(_resourceName, ".txr");
-
- _script = _vm->res()->get(_resourceName);
-
- processLines();
-}
-
-bool TextviewView::onEvent(M4EventType eventType, int32 param, int x, int y, bool &captureEvents) {
- if (!_processEvents)
- return false;
-
- // Wait for the Escape key or a mouse press
- if (((eventType == KEVENT_KEY) && (param == Common::KEYCODE_ESCAPE)) ||
- (eventType == MEVENT_LEFT_RELEASE) || (eventType == MEVENT_RIGHT_RELEASE)) {
- scriptDone();
- captureEvents = false;
- return true;
- }
-
- return false;
-}
-
-void TextviewView::updateState() {
- if (!_animating)
- return;
-
- // Only update state if wait period has expired
- uint32 currTime = g_system->getMillis();
-
- // If a screen transition is in progress and it's time for another column, handle it
- if (_spareScreen) {
- byte *srcP = _spareScreen->getBasePtr(_translationX, 0);
- byte *destP = _bgSurface.getBasePtr(_translationX, 0);
-
- for (int y = 0; y < _bgSurface.height(); ++y, srcP += _spareScreen->width(),
- destP += _bgSurface.width()) {
- *destP = *srcP;
- }
-
- if (++_translationX >= _bgSurface.width()) {
- // Surface transition is complete
- delete _spareScreen;
- _spareScreen = NULL;
-
- _vm->_palette->deleteRange(_bgCurrent);
- delete _bgCurrent;
- _bgCurrent = _bgSpare;
- _bgSpare = NULL;
- }
- }
-
- // Make sure it's time for an update
- if (currTime < _scrollTimeout)
- return;
- _scrollTimeout = g_system->getMillis() + TEXT_ANIMATION_DELAY;
-
- // If any panning values are set, pan the background surface
- if ((_panX != 0) || (_panY != 0)) {
- if (_panCountdown > 0) {
- --_panCountdown;
- return;
- }
-
- // Handle horizontal panning
- if (_panX != 0) {
- byte *lineTemp = new byte[_panX];
- for (int y = 0; y < _bgSurface.height(); ++y) {
- byte *pixelsP = _bgSurface.getBasePtr(0, y);
-
- // Copy the first X pixels into temp buffer, move the rest of the line
- // to the start of the line, and then move temp buffer pixels to end of line
- Common::copy(pixelsP, pixelsP + _panX, lineTemp);
- Common::copy(pixelsP + _panX, pixelsP + _bgSurface.width(), pixelsP);
- Common::copy(lineTemp, lineTemp + _panX, pixelsP + _bgSurface.width() - _panX);
- }
-
- delete[] lineTemp;
- }
-
- // Handle vertical panning
- if (_panY != 0) {
- // Store the bottom Y lines into a temp buffer, move the rest of the lines down,
- // and then copy the stored lines back to the top of the screen
- byte *linesTemp = new byte[_panY * _bgSurface.width()];
- byte *pixelsP = _bgSurface.getBasePtr(0, _bgSurface.height() - _panY);
- Common::copy(pixelsP, pixelsP + _bgSurface.width() * _panY, linesTemp);
-
- for (int y = _bgSurface.height() - 1; y >= _panY; --y) {
- byte *destP = _bgSurface.getBasePtr(0, y);
- byte *srcP = _bgSurface.getBasePtr(0, y - _panY);
- Common::copy(srcP, srcP + _bgSurface.width(), destP);
- }
-
- Common::copy(linesTemp, linesTemp + _panY * _bgSurface.width(), _bgSurface.getBasePtr(0, 0));
- delete[] linesTemp;
- }
- }
-
- // Scroll the text surface up by one row
- byte *pixelsP = _textSurface.getBasePtr(0, 0);
- Common::copy(pixelsP + width(), pixelsP + _textSurface.width() * _textSurface.height(), pixelsP);
- pixelsP = _textSurface.getBasePtr(0, _textSurface.height() - 1);
- Common::set_to(pixelsP, pixelsP + _textSurface.width(), _vm->_palette->BLACK);
-
- if (_scrollCount > 0) {
- // Handling final scrolling of text off of screen
- if (--_scrollCount == 0) {
- scriptDone();
- return;
- }
- } else {
- // Handling a text row
- if (++_lineY == (_vm->_font->current()->getHeight() + TEXTVIEW_LINE_SPACING))
- processLines();
- }
-
- // Refresh the view
- int yp = (height() - _bgSurface.height()) / 2;
- _bgSurface.copyTo(this, 0, yp);
- _textSurface.copyTo(this, Common::Rect(0, 0, _textSurface.width(), _bgSurface.height()),
- 0, yp, _vm->_palette->BLACK);
-}
-
-void TextviewView::scriptDone() {
- TextviewCallback fn = _callback;
- MadsM4Engine *vm = _vm;
-
- // Remove this view from manager and destroy it
- _vm->_viewManager->deleteView(this);
-
- if (fn)
- fn(vm);
-}
-
-void TextviewView::processLines() {
- strncpy(_currentLine, _script->readLine().c_str(), 79);
- if (_script->eos() || _script->err())
- error("Attempted to read past end of response file");
-
- while (!_script->eos() && !_script->err()) {
- // Commented out line, so go loop for another
- if (_currentLine[0] == '#') {
- strncpy(_currentLine, _script->readLine().c_str(), 79);
- continue;
- }
-
- // Process the line
- char *cStart = strchr(_currentLine, '[');
- if (cStart) {
- while (cStart) {
- // Loop for possible multiple commands on one line
- char *cEnd = strchr(_currentLine, ']');
- if (!cEnd)
- error("Unterminated command '%s' in response file", _currentLine);
-
- *cEnd = '\0';
- processCommand();
-
- // Copy rest of line (if any) to start of buffer
- strcpy(_currentLine, cEnd + 1);
-
- cStart = strchr(_currentLine, '[');
- }
-
- if (_currentLine[0]) {
- processText();
- break;
- }
-
- } else {
- processText();
- break;
- }
-
- strncpy(_currentLine, _script->readLine().c_str(), 79);
- }
-}
-
-void TextviewView::processCommand() {
- char commandStr[80];
- char *paramP;
- strcpy(commandStr, _currentLine + 1);
- str_upper(commandStr);
-
- if (!strncmp(commandStr, "BACKGROUND", 10)) {
- // Set the background
- paramP = commandStr + 10;
- int screenId = getParameter(&paramP);
- _bgSurface.loadBackground(screenId, &_bgCurrent);
- _vm->_palette->addRange(_bgCurrent);
- _bgSurface.translate(_bgCurrent);
-
- } else if (!strncmp(commandStr, "GO", 2)) {
- _animating = true;
-
- // Grab what the final palete will be
- RGB8 destPalette[256];
- _vm->_palette->grabPalette(destPalette, 0, 256);
-
- // Copy the loaded background, if any, to the view surface
- int yp = (height() - _bgSurface.height()) / 2;
- _bgSurface.copyTo(this, 0, yp);
-
- // Handle fade-in
- _processEvents = false; // stop processing events during fade-in
- _vm->_palette->fadeIn(TV_NUM_FADE_STEPS, TV_FADE_DELAY_MILLI, destPalette, 256);
- _processEvents = true;
-
- } else if (!strncmp(commandStr, "PAN", 3)) {
- // Set panning values
- paramP = commandStr + 3;
- int panX = getParameter(&paramP);
- int panY = getParameter(&paramP);
- int panSpeed = getParameter(&paramP);
-
- if ((panX != 0) || (panY != 0)) {
- _panX = panX;
- _panY = panY;
- _panSpeed = panSpeed;
- }
-
- } else if (!strncmp(commandStr, "DRIVER", 6)) {
- // Set the driver to use
- // TODO: Handling of the sound drivers
-
- } else if (!strncmp(commandStr, "SOUND", 5)) {
- // Set sound number
- paramP = commandStr + 5;
- //int soundId = getParameter(&paramP);
-
- //TODO: Proper handling of the sound drivers/sounds
- //if (!_soundDriverLoaded)
- // error("Attempted to set sound without loading any driver");
-
- } else if (!strncmp(commandStr, "COLOR", 5) && ((commandStr[5] == '0') || (commandStr[5] == '1'))) {
- // Set the text colors
- int index = commandStr[5] - '0';
- paramP = commandStr + 6;
-
- RGB8 palEntry;
- palEntry.r = getParameter(&paramP) << 2;
- palEntry.g = getParameter(&paramP) << 2;
- palEntry.b = getParameter(&paramP) << 2;
- _vm->_palette->setPalette(&palEntry, 5 + index, 1);
-
- } else if (!strncmp(commandStr, "SPARE", 5)) {
- // Sets a secondary background number that can be later switched in with a PAGE command
- paramP = commandStr + 6;
- int spareIndex = commandStr[5] - '0';
- if ((spareIndex >= 0) && (spareIndex <= 9)) {
- int screenId = getParameter(&paramP);
-
- _spareScreens[spareIndex] = screenId;
- }
-
- } else if (!strncmp(commandStr, "PAGE", 4)) {
- // Signals to change to a previous specified secondary background
- paramP = commandStr + 4;
- int spareIndex = getParameter(&paramP);
-
- // Only allow background switches if one isn't currently in progress
- if (!_spareScreen && (_spareScreens[spareIndex] != 0)) {
- _spareScreen = new M4Surface(width(), MADS_SURFACE_HEIGHT);
- _spareScreen->loadBackground(_spareScreens[spareIndex], &_bgSpare);
- _vm->_palette->addRange(_bgSpare);
- _spareScreen->translate(_bgSpare);
-
- _translationX = 0;
- }
-
- } else {
- error("Unknown response command: '%s'", commandStr);
- }
-}
-
-int TextviewView::getParameter(char **paramP) {
- if ((**paramP != '=') && (**paramP != ','))
- return 0;
-
- int result = 0;
- ++*paramP;
- while ((**paramP >= '0') && (**paramP <= '9')) {
- result = result * 10 + (**paramP - '0');
- ++*paramP;
- }
-
- return result;
-}
-
-void TextviewView::processText() {
- int lineWidth, xStart;
-
- if (!strcmp(_currentLine, "***")) {
- // Special signifier for end of script
- _scrollCount = _vm->_font->current()->getHeight() * 13;
- _lineY = -1;
- return;
- }
-
- _lineY = 0;
-
- // Lines are always centered, except if line contains a '@', in which case the
- // '@' marks the position that must be horizontally centered
- char *centerP = strchr(_currentLine, '@');
- if (centerP) {
- *centerP = '\0';
- xStart = (width() / 2) - _vm->_font->current()->getWidth(_currentLine);
-
- // Delete the @ character and shift back the remainder of the string
- char *p = centerP + 1;
- if (*p == ' ') ++p;
- strcpy(centerP, p);
-
- } else {
- lineWidth = _vm->_font->current()->getWidth(_currentLine);
- xStart = (width() - lineWidth) / 2;
- }
-
- // Copy the text line onto the bottom of the textSurface surface, which will allow it
- // to gradually scroll onto the screen
- int yp = _textSurface.height() - _vm->_font->current()->getHeight() - TEXTVIEW_LINE_SPACING;
- _textSurface.fillRect(Common::Rect(0, yp, _textSurface.width(), _textSurface.height()),
- _vm->_palette->BLACK);
- _vm->_font->current()->writeString(&_textSurface, _currentLine, xStart, yp);
-}
-
-
-//--------------------------------------------------------------------------
-
-AnimviewView::AnimviewView(MadsM4Engine *vm):
- View(vm, Common::Rect(0, 0, vm->_screen->width(), vm->_screen->height())),
- MadsView(this), _backgroundSurface(MADS_SURFACE_WIDTH, MADS_SURFACE_HEIGHT),
- _codeSurface(MADS_SURFACE_WIDTH, MADS_SURFACE_HEIGHT) {
-
- MadsView::_bgSurface = &_backgroundSurface;
- MadsView::_depthSurface = &_codeSurface;
- MadsView::setViewport(Common::Rect(0, MADS_Y_OFFSET, MADS_SURFACE_WIDTH, MADS_Y_OFFSET + MADS_SURFACE_HEIGHT));
-
- _screenType = VIEWID_ANIMVIEW;
- _screenFlags.layer = LAYER_BACKGROUND;
- _screenFlags.visible = true;
- _screenFlags.get = SCREVENT_ALL;
- _callback = NULL;
- _script = NULL;
- _palData = NULL;
- _previousUpdate = 0;
- _transition = kTransitionNone;
- _activeAnimation = NULL;
- _bgLoadFlag = true;
- _startFrame = -1;
- _scriptDone = false;
-
- reset();
-
- // Set up system palette colors
- _vm->_palette->setMadsSystemPalette();
-
- // Block reserved palette ranges
- _vm->_palette->blockRange(16, 2);
- _vm->_palette->blockRange(250, 4);
-
- clear();
- _backgroundSurface.clear();
-
- setColor(2);
- hLine(0, width() - 1, MADS_Y_OFFSET - 2);
- hLine(0, width() - 1, MADS_Y_OFFSET + MADS_SURFACE_HEIGHT + 2);
-}
-
-AnimviewView::~AnimviewView() {
- if (_script)
- _vm->res()->toss(_resourceName);
- delete _activeAnimation;
-}
-
-void AnimviewView::reset() {
- _backgroundSurface.clear();
- _soundDriverLoaded = false;
-}
-
-void AnimviewView::setScript(const char *resourceName, AnimviewCallback callback) {
- _callback = callback;
- if (_script)
- _vm->res()->toss(_resourceName);
-
- reset();
-
- strncpy(_resourceName, resourceName, 15);
- _resourceName[15] = '\0';
- if (!strchr(_resourceName, '.'))
- strcat(_resourceName, ".res");
-
- _script = _vm->res()->get(_resourceName);
-}
-
-bool AnimviewView::onEvent(M4EventType eventType, int32 param, int x, int y, bool &captureEvents) {
- // Wait for the Escape key or a mouse press
- if (((eventType == KEVENT_KEY) && (param == Common::KEYCODE_ESCAPE)) ||
- (eventType == MEVENT_LEFT_RELEASE) || (eventType == MEVENT_RIGHT_RELEASE)) {
- scriptDone();
- captureEvents = false;
- return true;
- }
-
- return false;
-}
-
-void AnimviewView::updateState() {
- MadsView::update();
-
- if (!_script || _scriptDone)
- return;
-
- if (!_activeAnimation) {
- readNextCommand();
- assert(_activeAnimation);
- }
-
- // Update the current animation
- _activeAnimation->update();
- if (_activeAnimation->freeFlag()) {
- delete _activeAnimation;
- _activeAnimation = NULL;
-
- // Clear up current background and sprites
- _backgroundSurface.reset();
- clearLists();
-
- // Reset flags
- _startFrame = -1;
-
- readNextCommand();
-
- // Check if script is finished
- if (_scriptDone) {
- scriptDone();
- return;
- }
- }
-
- refresh();
-}
-
-void AnimviewView::readNextCommand() {
-static bool tempFlag = true;//****DEBUG - Temporarily allow me to skip several intro scenes ****
-
- while (!_script->eos() && !_script->err()) {
- if (!tempFlag) {
- tempFlag = true;
- strncpy(_currentLine, _script->readLine().c_str(), 79);
- strncpy(_currentLine, _script->readLine().c_str(), 79);
- }
-
- strncpy(_currentLine, _script->readLine().c_str(), 79);
-
- // Process any switches on the line
- char *cStart = strchr(_currentLine, '-');
- while (cStart) {
- // Loop for possible multiple commands on one line
- char *cEnd = strchr(_currentLine, ' ');
- if (!cEnd)
- error("Unterminated command '%s' in response file", _currentLine);
-
- *cEnd = '\0';
- processCommand();
-
- // Copy rest of line (if any) to start of buffer
- // Don't use strcpy() here, because if the
- // rest of the line is the longer of the two
- // strings, the memory areas will overlap.
- memmove(_currentLine, cEnd + 1, strlen(cEnd + 1) + 1);
-
- cStart = strchr(_currentLine, '-');
- }
-
- // If there's something left, presume it's a resource name to process
- if (_currentLine[0])
- break;
- }
-
- if (!_currentLine[0]) {
- // A blank line at this point means that the end of the animation has been reached
- _scriptDone = true;
- return;
- }
-
- if (strchr(_currentLine, '.') == NULL)
- strcat(_currentLine, ".aa");
-
- uint16 flags = 0;
- if (_bgLoadFlag)
- flags |= 0x100;
-
- _activeAnimation = new MadsAnimation(_vm, this);
- _activeAnimation->initialize(_currentLine, flags, &_backgroundSurface, &_codeSurface);
-
- if (_startFrame != -1)
- _activeAnimation->setCurrentFrame(_startFrame);
-
- _spriteSlots.fullRefresh();
-/*
- // Handle scene transition
- switch (_transition) {
- case kTransitionNone:
- // nothing to do
- break;
- case kTransitionFadeIn:
- case kTransitionFadeIn2:
- _vm->_palette->fadeIn(TV_NUM_FADE_STEPS, TV_FADE_DELAY_MILLI, destPalette, 256);
- break;
- case kTransitionBoxInBottomLeft:
- case kTransitionBoxInBottomRight:
- case kTransitionBoxInTopLeft:
- case kTransitionBoxInTopRight:
- // unused
- warning("Unsupported box in scene effect");
- break;
- case kTransitionPanLeftToRight:
- // TODO
- break;
- case kTransitionPanRightToLeft:
- // TODO
- break;
- case kTransitionCircleIn:
- // TODO
- break;
- default:
- // nothing to do
- break;
- }
-*/
-
- _vm->_resourceManager->toss(_currentLine);
-}
-
-
-void AnimviewView::scriptDone() {
-return;
- AnimviewCallback fn = _callback;
- MadsM4Engine *vm = _vm;
-
- // Remove this view from manager and destroy it
- _vm->_viewManager->deleteView(this);
-
- if (fn)
- fn(vm);
-}
-
-/*
-Switches are: (taken from the help of the original executable)
- -b Toggle background load status off/on.
- -c:char Specify sound card id letter.
- -f:num Specify a specific starting frame number
- -g Stay in graphics mode on exit.
- -h[:ex] Disable EMS/XMS high memory support.
- -i Switch sound interrupts mode off/on.
- -j Wait for music to finish at end.
- -k Keystroke jumps to end instead of abort.
- -m Operate in non-MADS mode.
- -o:xxx Specify opening special effect.
- -p Switch MADS path mode to CONCAT.
- -r[:abn] Resynch timer (always, beginning, never).
- -s:file Specify sound file.
- -u[:...] Use DMA speech [optional: addr,type,irq,drq].
- -w Toggle white bars off/on.
- -x Exit immediately after last frame.
- -y Do not clear screen initially
- -z Display statistics after run.
-
- Opening special effects are:
- 0: no effect
- 1: fade in
- 2: fade in (looks to be the same as 1)
- 3: box in from bottom left (unused)
- 4: box in from bottom right (unused)
- 5: box in from top left (unused)
- 6: box in from top right (unused)
- 7: pan in from left to right
- 8: pan in from right to left
- 9: circle in (new scene appears in a circle that expands)
-
- Animview is ran like this from the original games:
- animview.exe @resfilename -c:P,220,20 -u:220,20,07,01 -p -a:mainmenu -p
-
- Note that the first -p is necessary to watch the animation, otherwise
- the program just exits
-
- To watch an animation within the *.res file, just run animview like this:
- animview.exe -x -r:b -o:2 animfilename -p
-*/
-void AnimviewView::processCommand() {
- char commandStr[80];
- strcpy(commandStr, _currentLine + 1);
- str_upper(commandStr);
- char *param = commandStr;
-
- switch (commandStr[0]) {
- case 'B':
- // Toggle background load flag
- _bgLoadFlag = !_bgLoadFlag;
- break;
-
- case 'F':
- // Start animation at a specific frame
- ++param;
- assert(*param == ':');
- _startFrame = atoi(++param);
- break;
-
- case 'O':
- param = param + 2;
- //warning(kDebugGraphics, "O:%i ", atoi(param));
- _transition = atoi(param);
- break;
-
- case 'R':
- param = param + 2;
- //warning(kDebugGraphics, "R:%s ", param);
- break;
-
- case 'W':
- //warning(kDebugGraphics, "W ");
- break;
-
- case 'X':
- //warning(kDebugGraphics, "X ");
- break;
-
- default:
- error("Unknown response command: '%s'", commandStr);
- }
-}
-
-}
diff --git a/engines/m4/mads_anim.h b/engines/m4/mads_anim.h
deleted file mode 100644
index 411d575d59..0000000000
--- a/engines/m4/mads_anim.h
+++ /dev/null
@@ -1,110 +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 M4_MADS_ANIM_H
-#define M4_MADS_ANIM_H
-
-#include "m4/viewmgr.h"
-#include "m4/compression.h"
-#include "m4/animation.h"
-
-#include "common/str-array.h"
-
-namespace M4 {
-
-typedef void (*TextviewCallback)(MadsM4Engine *vm);
-
-class TextviewView : public View {
-private:
- bool _animating;
-
- char _resourceName[80];
- Common::SeekableReadStream *_script;
- uint16 _spareScreens[10];
- M4Surface *_spareScreen;
- RGBList *_bgCurrent, *_bgSpare;
- int _translationX;
- int _panX, _panY, _panSpeed;
- int _panCountdown;
- char _currentLine[80];
- uint32 _scrollTimeout;
- int _scrollCount;
- int _lineY;
- M4Surface _bgSurface;
- M4Surface _textSurface;
- TextviewCallback _callback;
- bool _soundDriverLoaded;
- bool _processEvents;
-
- void reset();
- void processLines();
- void processCommand();
- void processText();
- int getParameter(char **paramP);
-public:
- TextviewView(MadsM4Engine *vm);
- ~TextviewView();
-
- void setScript(const char *resourceName, TextviewCallback callback);
- bool isAnimating() { return _animating; }
- void scriptDone();
-
- bool onEvent(M4EventType eventType, int32 param1, int x, int y, bool &captureEvents);
- void updateState();
-};
-
-typedef void (*AnimviewCallback)(MadsM4Engine *vm);
-
-class AnimviewView : public View, MadsView {
-private:
- char _resourceName[80];
- Common::SeekableReadStream *_script;
- bool _scriptDone;
- uint32 _previousUpdate;
- char _currentLine[80];
- M4Surface _backgroundSurface;
- M4Surface _codeSurface;
- AnimviewCallback _callback;
- bool _soundDriverLoaded;
- RGBList *_palData;
- int _transition;
- MadsAnimation *_activeAnimation;
- bool _bgLoadFlag;
- int _startFrame;
-
- void reset();
- void readNextCommand();
- void processCommand();
-public:
- AnimviewView(MadsM4Engine *vm);
- ~AnimviewView();
-
- void setScript(const char *resourceName, AnimviewCallback callback);
- void scriptDone();
-
- bool onEvent(M4EventType eventType, int32 param1, int x, int y, bool &captureEvents);
- void updateState();
-};
-
-}
-
-#endif
diff --git a/engines/m4/mads_logic.cpp b/engines/m4/mads_logic.cpp
deleted file mode 100644
index 335127393e..0000000000
--- a/engines/m4/mads_logic.cpp
+++ /dev/null
@@ -1,1038 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#include "common/textconsole.h"
-
-#include "m4/m4.h"
-#include "m4/dialogs.h"
-#include "m4/mads_logic.h"
-#include "m4/scene.h"
-
-#define MAX_CALL_PARAMS 10
-
-namespace M4 {
-
-void MadsGameLogic::initializeGlobals() {
- // Clear the entire globals list
- Common::set_to(&_madsVm->globals()->_globals[0], &_madsVm->globals()->_globals[TOTAL_NUM_VARIABLES], 0);
-
- SET_GLOBAL(4, 8);
- SET_GLOBAL(33, 1);
- SET_GLOBAL(10, 0xFFFF);
- SET_GLOBAL(13, 0xFFFF);
- SET_GLOBAL(15, 0xFFFF);
- SET_GLOBAL(19, 0xFFFF);
- SET_GLOBAL(20, 0xFFFF);
- SET_GLOBAL(21, 0xFFFF);
- SET_GLOBAL(95, 0xFFFF);
-
- // TODO: unknown sub call
-
- // Put the values 0 through 3 in a random ordering in global slots 83 - 86
- for (int idx = 0; idx < 4; ) {
- int randVal = _madsVm->_random->getRandomNumber(4);
- SET_GLOBAL(83 + idx, randVal);
-
- // Check whether the given value has already been used
- bool flag = false;
- for (int idx2 = 0; idx2 < idx; ++idx2) {
- if (randVal == GET_GLOBAL(83 + idx2))
- flag = true;
- }
-
- if (!flag)
- ++idx;
- }
-
- // Put the values 0 through 3 in a random ordering in global slots 87 - 90
- for (int idx = 0; idx < 4; ) {
- int randVal = _madsVm->_random->getRandomNumber(3);
- SET_GLOBAL(87 + idx, randVal);
-
- // Check whether the given value has already been used
- bool flag = false;
- for (int idx2 = 0; idx2 < idx; ++idx2) {
- if (randVal == GET_GLOBAL(87 + idx2))
- flag = true;
- }
-
- if (!flag)
- ++idx;
- }
-
- // Miscellaneous global settings
- SET_GLOBAL(120, 501);
- SET_GLOBAL(121, 0xFFFF);
- SET_GLOBAL(110, 0xFFFF);
- SET_GLOBAL(119, 1);
- SET_GLOBAL(134, 4);
- SET_GLOBAL(190, 201);
- SET_GLOBAL(191, 301);
- SET_GLOBAL(192, 413);
- SET_GLOBAL(193, 706);
- SET_GLOBAL(194, 801);
- SET_GLOBAL(195, 551);
- SET_GLOBAL(196, 752);
-
- // Fill out the globals 200 - 209 with unique random number values less than 10000
- for (int idx = 0; idx < 10; ) {
- int randVal = _madsVm->_random->getRandomNumber(9999);
- SET_GLOBAL(200 + idx, randVal);
-
- // Check whether the given value has already been used
- bool flag = false;
- for (int idx2 = 0; idx2 < idx; ++idx2) {
- if (randVal == GET_GLOBAL(87 + idx2))
- flag = true;
- }
-
- if (!flag)
- ++idx;
- }
-
- switch (_madsVm->globals()->_difficultyLevel) {
- case 1:
- // Very hard
- SET_GLOBAL(35, 0);
- // TODO: object set room
- SET_GLOBAL(137, 5);
- SET_GLOBAL(136, 0);
- break;
-
- case 2:
- // Hard
- SET_GLOBAL(35, 0);
- // TODO: object set room
- SET_GLOBAL(136, 0xFFFF);
- SET_GLOBAL(137, 6);
- break;
-
- case 3:
- // Easy
- SET_GLOBAL(35, 2);
- // TODO: object set room
- break;
- }
-
- _madsVm->_player._direction = 8;
- _madsVm->_player._newDirection = 8;
-
- // TODO: unknown processing routine getting called for 'RXM' and 'ROX'
-}
-
-/*--------------------------------------------------------------------------*/
-
-const char *MadsSceneLogic::subFormatList[] = {"scene%d_enter", "scene%d_step", "scene%d_preaction", "scene%d_actions"};
-
-#define OPSIZE8 0x40 ///< when this bit is set - the operand size is 8 bits
-#define OPSIZE16 0x80 ///< when this bit is set - the operand size is 16 bits
-#define OPMASK 0x3F ///< mask to isolate the opcode
-
-enum Opcodes {
- OP_HALT = 0, OP_IMM = 1, OP_ZERO = 2, OP_ONE = 3, OP_MINUSONE = 4, OP_STR = 5, OP_DLOAD = 6,
- OP_DSTORE = 7, OP_PAL = 8, OP_LOAD = 9, OP_GLOAD = 10, OP_STORE = 11, OP_GSTORE = 12,
- OP_CALL = 13, OP_LIBCALL = 14, OP_RET = 15, OP_ALLOC = 16, OP_JUMP = 17, OP_JMPFALSE = 18,
- OP_JMPTRUE = 19, OP_EQUAL = 20, OP_LESS = 21, OP_LEQUAL = 22, OP_NEQUAL = 23, OP_GEQUAL = 24,
- OP_GREAT = 25, OP_PLUS = 26, OP_MINUS = 27, OP_LOR = 28, OP_MULT = 29, OP_DIV = 30,
- OP_MOD = 31, OP_AND = 32, OP_OR = 33, OP_EOR = 34, OP_LAND = 35, OP_NOT = 36, OP_COMP = 37,
- OP_NEG = 38, OP_DUP = 39,
- TOTAL_OPCODES = 40
-};
-
-const char *MadsSceneLogic::_opcodeStrings[] = {
- "HALT", "IMM", "ZERO", "ONE", "MINUSONE", "STR", "DLOAD", "DSTORE", NULL, "LOAD", "GLOAD",
- "STORE", "GSTORE", "CALL", "LIBCALL", "RET", "ALLOC", "JUMP", "JMPFALSE", "JMPTRUE", "EQUAL",
- "LESS", "LEQUAL", "NEQUAL", "GEQUAL", "GREAT", "PLUS", "MINUS", "LOR", "MULT", "DIV",
- "MOD", "AND", "OR", "EOR", "LAND", "NOT", "COMP", "NEG", "DUP"
-};
-
-/**
- * This method sets up the data map with pointers to all the common game objects. This allows the script engine to
- * convert game specific offsets for various fields in the original game's data segment into a generic data index
- * that will be common across all the MADS games
-
-void MadsSceneLogic::initializeDataMap() {
- // The unique order of these items must be maintained
-}
-*/
-
-uint32 MadsSceneLogic::getDataValue(int dataId) {
- switch (dataId) {
- case 1:
- return _madsVm->scene()->_abortTimersMode2;
- case 2:
- return _madsVm->scene()->_abortTimers;
- case 3:
- return _madsVm->_player._stepEnabled ? 0xffff : 0;
- case 4:
- return _madsVm->scene()->_nextScene;
- case 5:
- return _madsVm->scene()->_previousScene;
- case 6:
- return _madsVm->_player._playerPos.x;
- case 7:
- return _madsVm->_player._playerPos.y;
- case 8:
- return _madsVm->_player._direction;
- case 9:
- return _madsVm->_player._visible ? 0xffff : 0;
- case 10:
- return getActiveAnimationBool();
- case 11:
- return getAnimationCurrentFrame();
- case 12:
- return _madsVm->scene()->_action._inProgress;
- case 13:
- return _madsVm->globals()->_difficultyLevel;
- default:
- // All other data variables get stored in the hash table
- return _madsVm->globals()->_dataMap[dataId];
- break;
- }
-}
-
-void MadsSceneLogic::setDataValue(int dataId, uint16 dataValue) {
- switch (dataId) {
- case 1:
- _madsVm->scene()->_abortTimersMode2 = (AbortTimerMode)dataValue;
- break;
- case 2:
- _madsVm->scene()->_abortTimers = dataValue;
- break;
- case 3:
- _madsVm->_player._stepEnabled = dataValue != 0;
- break;
- case 4:
- _madsVm->scene()->_nextScene = dataValue;
- break;
- case 5:
- _madsVm->scene()->_previousScene = dataValue;
- break;
- case 6:
- _madsVm->_player._playerPos.x = dataValue;
- break;
- case 7:
- _madsVm->_player._playerPos.y = dataValue;
- break;
- case 8:
- _madsVm->_player._direction = dataValue;
- break;
- case 9:
- _madsVm->_player._visible = dataValue != 0;
- break;
- case 10:
- case 11:
- error("Tried to set read only data field %d", dataId);
- break;
- case 12:
- _madsVm->scene()->_action._inProgress = dataValue != 0;
- break;
- case 13:
- _madsVm->globals()->_difficultyLevel = dataValue;
- break;
- default:
- // All other data variables get stored in the hash table
- _madsVm->globals()->_dataMap[dataId] = dataValue;
- break;
- }
-}
-
-const char *MadsSceneLogic::formAnimName(char sepChar, int16 suffixNum) {
- return MADSResourceManager::getResourceName(sepChar, _sceneNumber, EXTTYPE_NONE, NULL, suffixNum);
-}
-
-void MadsSceneLogic::getSceneSpriteSet() {
- char prefix[100];
-
- // Room change sound
- _madsVm->_sound->playSound(5);
-
- // Set up sprite set prefix to use
- if ((_sceneNumber <= 103) || (_sceneNumber == 111)) {
- if (_madsVm->globals()->_globals[0] == SEX_FEMALE)
- strcpy(prefix, "ROX");
- else
- strcpy(prefix, "RXM");
- } else if (_sceneNumber <= 110) {
- strcpy(prefix, "RXSW");
- _madsVm->globals()->_globals[0] = SEX_UNKNOWN;
- } else if (_sceneNumber == 112)
- strcpy(prefix, "");
-
- _madsVm->globals()->playerSpriteChanged = true;
- _madsVm->_player.loadSprites(prefix);
-
-// if ((_sceneNumber == 105) ((_sceneNumber == 109) && (word_84800 != 0)))
-// _madsVm->globals()->playerSpriteChanged = true;
-
- _vm->_palette->setEntry(16, 0x38, 0xFF, 0xFF);
- _vm->_palette->setEntry(17, 0x38, 0xb4, 0xb4);
-}
-
-void MadsSceneLogic::getAnimName() {
- const char *newName = MADSResourceManager::getAAName(
- ((_sceneNumber <= 103) || (_sceneNumber > 111)) ? 0 : 1);
- strcpy(_madsVm->scene()->_aaName, newName);
-}
-
-/*--------------------------------------------------------------------------*/
-
-uint16 MadsSceneLogic::loadSpriteSet(uint16 suffixNum, uint16 sepChar) {
- assert(sepChar < 256);
- const char *resName = formAnimName((char)sepChar, (int16)suffixNum);
- return _madsVm->scene()->loadSceneSpriteSet(resName);
-}
-
-uint16 MadsSceneLogic::startReversibleSpriteSequence(uint16 srcSpriteIdx, bool flipped, int numTicks, int triggerCountdown, int timeoutTicks, int extraTicks) {
- M4Sprite *spriteFrame = _madsVm->scene()->_spriteSlots.getSprite(srcSpriteIdx).getFrame(0);
- 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,
- true, 100, depth - 1, 1, ANIMTYPE_REVERSIBLE, 0, 0);
-}
-
-uint16 MadsSceneLogic::startCycledSpriteSequence(uint16 srcSpriteIdx, bool flipped, int numTicks, int triggerCountdown, int timeoutTicks, int extraTicks) {
- M4Sprite *spriteFrame = _madsVm->scene()->_spriteSlots.getSprite(srcSpriteIdx).getFrame(0);
- 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,
- true, 100, depth - 1, 1, ANIMTYPE_CYCLED, 0, 0);
-}
-
-uint16 MadsSceneLogic::startSpriteSequence3(uint16 srcSpriteIdx, bool flipped, int numTicks, int triggerCountdown, int timeoutTicks, int extraTicks) {
- M4Sprite *spriteFrame = _madsVm->scene()->_spriteSlots.getSprite(srcSpriteIdx).getFrame(0);
- 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,
- true, 100, depth - 1, -1, ANIMTYPE_CYCLED, 0, 0);
-}
-
-void MadsSceneLogic::activateHotspot(int idx, bool active) {
- // TODO:
-}
-
-void MadsSceneLogic::getPlayerSpritesPrefix() {
- _madsVm->_sound->playSound(5);
-
- char oldName[80];
- strcpy(oldName, _madsVm->_player._spritesPrefix);
-
- if ((_madsVm->globals()->_nextSceneId <= 103) || (_madsVm->globals()->_nextSceneId == 111))
- strcpy(_madsVm->_player._spritesPrefix, (_madsVm->globals()->_globals[0] == SEX_FEMALE) ? "ROX" : "RXM");
- else if (_madsVm->globals()->_nextSceneId <= 110)
- 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) ||
- ((_madsVm->globals()->_nextSceneId == 109) && (_madsVm->globals()->_globals[15] != 0))) {
- // TODO: unknown flag setting
- _madsVm->_player._spritesChanged = true;
- }
-
- _madsVm->_palette->setEntry(16, 40, 255, 255);
- _madsVm->_palette->setEntry(17, 40, 180, 180);
-
-}
-
-void MadsSceneLogic::getPlayerSpritesPrefix2() {
- _madsVm->_sound->playSound(5);
-
- char oldName[80];
- strcpy(oldName, _madsVm->_player._spritesPrefix);
-
- if ((_madsVm->globals()->_nextSceneId == 213) || (_madsVm->globals()->_nextSceneId == 216))
- strcpy(_madsVm->_player._spritesPrefix, "");
- else if (_madsVm->globals()->_globals[0] == SEX_MALE)
- strcpy(_madsVm->_player._spritesPrefix, "RXM");
- else
- strcpy(_madsVm->_player._spritesPrefix, "ROX");
-
- // TODO: unknown flag setting for next scene Id > 212
-
- if (strcmp(oldName, _madsVm->_player._spritesPrefix) != 0)
- _madsVm->_player._spritesChanged = true;
-
-/* if ((_madsVm->globals()->_nextSceneId == 203) && (_madsVm->globals()->_nextSceneId == 204) &&
- (_madsVm->globals()->_globals[0x22] == 0))
- // TODO: unknown flag set
-*/
- _madsVm->_palette->setEntry(16, 40, 255, 255);
- _madsVm->_palette->setEntry(17, 40, 180, 180);
-}
-
-
-/*--------------------------------------------------------------------------*/
-
-/**
- * Loads the MADS.DAT file and loads the script data for the correct game/language
- */
-void MadsSceneLogic::initializeScripts() {
- Common::File f;
- if (!f.open("mads.dat")) {
- warning("Could not locate mads.dat file");
- return;
- }
-
- // Validate that the file being read is a valid mads.dat file
- char header[4];
- f.read(&header[0], 4);
- if (strncmp(header, "MADS", 4) != 0) {
- warning("Invalid mads.dat file");
- return;
- }
-
- // Get a list of the offsets of game blocks
- uint32 v;
- Common::Array<uint32> offsets;
- while ((v = f.readUint32LE()) != 0)
- offsets.push_back(v);
-
- // Check the header of each block in turn
- _scriptsData = NULL;
- _scriptsSize = 0;
-
- for (uint i = 0; i < offsets.size(); ++i) {
- // Get the block header
- f.seek(offsets[i]);
- byte gameId = f.readByte();
- byte language = f.readByte();
- f.readByte(); // Language currently unused
-
- // If this block isn't for the current game, skip it
- if (_madsVm->getGameType() != (gameId + 2))
- continue;
- if ((language != 1) || (_madsVm->getLanguage() != Common::EN_ANY))
- continue;
-
- // Found script block for the given game and language.
- _scriptsSize = (i < (offsets.size() - 1)) ? offsets[i + 1] - offsets[i] : f.size() - offsets[i];
- break;
- }
-
- if (!_scriptsSize) {
- warning("Could not find appropriate scripts block for game in mads.dat file");
- f.close();
- return;
- }
-
- // Load up the list of subroutines into a hash map
- uint32 blockOffset = f.pos() - 3;
- uint32 subsStart = 0;
- for (;;) {
- // Get next entry
- Common::String subName;
- char c;
- while ((c = (char)f.readByte()) != '\0')
- subName += c;
- if (subName.empty())
- // Reached end of subroutine list
- break;
-
- // Read in the offset of the routine
- uint32 offset = f.readUint32LE();
- if (_subroutines.empty()) {
- // The first subroutine offset is used to reduce the amount of data to later load in. In essence,
- // the subroutine index will not be separately loaded, since it's contents will be in the hash map
- subsStart = offset;
- _scriptsSize -= offset;
- }
-
- _subroutines[subName] = offset - subsStart;
- _subroutineOffsets.push_back(offset - subsStart);
- }
-
- // Read in the remaining data
- f.seek(blockOffset + subsStart, SEEK_SET);
- _scriptsData = (byte *)malloc(_scriptsSize);
- f.read(_scriptsData, _scriptsSize);
-
- f.close();
-}
-
-void MadsSceneLogic::selectScene(int sceneNum) {
- assert(sceneNum == 101);
- _sceneNumber = sceneNum;
-
- Common::set_to(&_spriteIndexes[0], &_spriteIndexes[50], 0);
-
- // If debugging is turned on, show a debug warning if any of the scene methods aren't present
- if (gDebugLevel > 0) {
- for (int i = 0; i < 4; ++i) {
- char buffer[20];
- sprintf(buffer, subFormatList[i], sceneNum);
- Common::HashMap<Common::String, uint32>::iterator it = _subroutines.find(Common::String(buffer));
- if (it == _subroutines.end())
- debugC(1, kDebugScript, "Scene method %s not found", buffer);
- }
- }
-}
-
-void MadsSceneLogic::setupScene() {
- // FIXME: This is the hardcoded logic for Rex scene 101 only
- const char *animName = formAnimName('A', -1);
- warning("anim - %s", animName);
-
-// sub_1e754(animName, 3);
-
- if ((_sceneNumber >= 101) && (_sceneNumber <= 112))
- getPlayerSpritesPrefix();
- else
- getPlayerSpritesPrefix2();
-
- getAnimName();
-}
-
-/**
- * Handles the logic when a scene is entered
- */
-void MadsSceneLogic::doEnterScene() {
- char buffer[20];
- sprintf(buffer, subFormatList[SUBFORMAT_ENTER], _sceneNumber);
- execute(Common::String(buffer));
-}
-
-/**
- * Handles the script execution which is called regularly every frame
- */
-void MadsSceneLogic::doSceneStep() {
- char buffer[20];
- sprintf(buffer, subFormatList[SUBFORMAT_STEP], _sceneNumber);
- execute(Common::String(buffer));
-}
-
-/**
- * Handles and preactions before an action is started
- */
-void MadsSceneLogic::doPreactions() {
- char buffer[20];
- sprintf(buffer, subFormatList[SUBFORMAT_PREACTIONS], _sceneNumber);
- execute(Common::String(buffer));
-}
-
-/**
- * Handles any action that has been selected
- */
-void MadsSceneLogic::doAction() {
- char buffer[20];
- sprintf(buffer, subFormatList[SUBFORMAT_ACTIONS], _sceneNumber);
- execute(Common::String(buffer));
-}
-
-/**
- * Executes the script with the specified name
- */
-void MadsSceneLogic::execute(const Common::String &scriptName) {
- Common::HashMap<Common::String, uint32>::iterator it = _subroutines.find(scriptName);
- if (it != _subroutines.end())
- execute(it->_value);
-}
-
-#define UNUSED_VAL 0xEAEAEAEA
-/**
- * Executes the script at the specified offset
- */
-void MadsSceneLogic::execute(uint32 subOffset) {
- Common::Array<ScriptVar> locals;
- Common::Stack<ScriptVar> stack;
- char opcodeBuffer[100];
- uint32 scriptOffset = subOffset;
- uint32 param;
-
- debugC(1, kDebugScript, "executing script at %xh", subOffset);
-
- bool done = false;
- while (!done) {
- param = UNUSED_VAL;
- byte opcode = _scriptsData[scriptOffset++];
- sprintf(opcodeBuffer, "%.4x[%.2d] - %s", scriptOffset - 1, stack.size(), _opcodeStrings[opcode & OPMASK]);
-
- switch (opcode & OPMASK) {
- case OP_HALT: // end of program
- case OP_RET:
- done = true;
- break;
-
- case OP_IMM: // Loads immediate value onto stack
- param = getParam(scriptOffset, opcode);
- stack.push(ScriptVar(param));
- break;
-
- case OP_ZERO: // loads zero onto stack
- stack.push(ScriptVar((uint32)0));
- break;
-
- case OP_ONE: // loads one onto stack
- stack.push(ScriptVar(1));
- break;
-
- case OP_MINUSONE: // loads minus one (0xffff) onto stack
- stack.push(ScriptVar(0xffff));
- break;
-
- case OP_DLOAD: { // Gets data variable
- param = getParam(scriptOffset, opcode);
- uint16 v = getDataValue(param);
- stack.push(ScriptVar(v));
- break;
- }
-
- case OP_DSTORE: { // Stores data variable
- 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]);
- break;
-
- case OP_STORE: // Pops a value and stores it in a local
- // Get the local index and expand the locals store if necessary
- param = getParam(scriptOffset, opcode);
- while (param >= locals.size())
- locals.push_back(ScriptVar());
-
- locals[param] = stack.pop();
- break;
-
- case OP_GLOAD: // loads global variable onto stack
- param = getParam(scriptOffset, opcode);
- assert(param < TOTAL_NUM_VARIABLES);
- stack.push(_madsVm->globals()->_globals[param]);
- break;
-
- case OP_GSTORE: // pops stack and stores in global variable
- param = getParam(scriptOffset, opcode);
- assert(param < TOTAL_NUM_VARIABLES);
- _madsVm->globals()->_globals[param] = stack.pop().get();
- break;
-
- case OP_CALL: // procedure call
- param = getParam(scriptOffset, opcode);
- assert(param < _subroutineOffsets.size());
- execute(_subroutineOffsets[param]);
- break;
-
- case OP_LIBCALL: // library procedure or function call
- param = getParam(scriptOffset, opcode);
- callSubroutine(param, stack);
- break;
-
- case OP_JUMP: // unconditional jump
- param = subOffset + getParam(scriptOffset, opcode);
- scriptOffset = param;
- break;
-
- case OP_JMPFALSE: // conditional jump
- param = subOffset + getParam(scriptOffset, opcode);
- if (stack.pop().get() == 0)
- // Condition satisfied - do the jump
- scriptOffset = param;
- break;
-
- case OP_JMPTRUE: // conditional jump
- param = subOffset + getParam(scriptOffset, opcode);
- if (stack.pop().get() != 0)
- // Condition satisfied - do the jump
- scriptOffset = param;
- break;
-
- case OP_EQUAL: // tests top two items on stack for equality
- case OP_LESS: // tests top two items on stack
- case OP_LEQUAL: // tests top two items on stack
- case OP_NEQUAL: // tests top two items on stack
- case OP_GEQUAL: // tests top two items on stack
- case OP_GREAT: // tests top two items on stack
- case OP_LOR: // logical or of top two items on stack and replaces with result
- case OP_LAND: // logical ands top two items on stack and replaces with result
- {
- uint32 param2 = stack.pop().get();
- uint32 param1 = stack.pop().get();
-
- // Do the comparison
- uint32 tmp = 0;
- switch (opcode) {
- case OP_EQUAL: tmp = (param1 == param2); break;
- case OP_LESS: tmp = (param1 < param2); break;
- case OP_LEQUAL: tmp = (param1 <= param2); break;
- case OP_NEQUAL: tmp = (param1 != param2); break;
- case OP_GEQUAL: tmp = (param1 >= param2); break;
- case OP_GREAT: tmp = (param1 > param2); break;
-
- case OP_LOR: tmp = (param1 || param2); break;
- case OP_LAND: tmp = (param1 && param2); break;
- }
-
- stack.push(ScriptVar(tmp));
- }
- break;
-
- case OP_PLUS: // adds top two items on stack and replaces with result
- case OP_MINUS: // subs top two items on stack and replaces with result
- case OP_MULT: // multiplies top two items on stack and replaces with result
- case OP_DIV: // divides top two items on stack and replaces with result
- case OP_MOD: // divides top two items on stack and replaces with modulus
- case OP_AND: // bitwise ands top two items on stack and replaces with result
- case OP_OR: // bitwise ors top two items on stack and replaces with result
- case OP_EOR: // bitwise exclusive ors top two items on stack and replaces with result
- {
- uint32 param2 = stack.pop().get();
- uint32 param1 = stack.pop().get();
-
- // replace other operand with result of operation
- switch (opcode) {
- case OP_PLUS: param1 += param2; break;
- case OP_MINUS: param1 -= param2; break;
- case OP_MULT: param1 *= param2; break;
- case OP_DIV: param1 /= param2; break;
- case OP_MOD: param1 %= param2; break;
- case OP_AND: param1 &= param2; break;
- case OP_OR: param1 |= param2; break;
- case OP_EOR: param1 ^= param2; break;
- }
-
- stack.push(ScriptVar(param1));
- }
- break;
-
- case OP_NOT: // logical nots top item on stack
- param = stack.pop().get();
- stack.push(ScriptVar((uint32)(!param) & 0xffff));
- break;
-
- case OP_COMP: // complements top item on stack
- param = stack.pop().get();
- stack.push(ScriptVar((~param) & 0xffff));
- break;
-
- case OP_NEG: // negates top item on stack
- param = stack.pop().get();
- stack.push(ScriptVar(((uint32)-(int32)param) & 0xffff));
- break;
-
- case OP_DUP: // duplicates top item on stack
- stack.push(stack.top());
- break;
-
- default:
- error("execute() - Unknown opcode");
- }
-
- // check for stack size
- assert(stack.size() < 100);
-
- if (gDebugLevel > 0) {
- if (param != UNUSED_VAL)
- sprintf(opcodeBuffer + strlen(opcodeBuffer), "\t%d", param);
- debugC(2, kDebugScript, "%s", opcodeBuffer);
- }
- }
-
- debugC(1, kDebugScript, "finished executing script");
-
- // make sure stack is unwound
- assert(stack.size() == 0);
-}
-
-uint32 MadsSceneLogic::getParam(uint32 &scriptOffset, int opcode) {
- switch (opcode & (~OPMASK)) {
- case OPSIZE8:
- return _scriptsData[scriptOffset++];
- case OPSIZE16: {
- uint16 v = READ_LE_UINT16(&_scriptsData[scriptOffset]);
- scriptOffset += sizeof(uint16);
- return v;
- }
- default: {
- uint32 v = READ_LE_UINT32(&_scriptsData[scriptOffset]);
- scriptOffset += sizeof(uint32);
- return v;
- }
- }
-}
-
-/**
- * Support method for extracting the required number of parameters needed for a library routine call
- */
-void MadsSceneLogic::getCallParameters(int numParams, Common::Stack<ScriptVar> &stack, ScriptVar *callParams) {
- assert(numParams <= MAX_CALL_PARAMS);
- for (int i = 0; i < numParams; ++i, ++callParams)
- *callParams = stack.pop();
-}
-
-#define EXTRACT_PARAMS(n) getCallParameters(n, stack, p)
-
-void MadsSceneLogic::callSubroutine(int subIndex, Common::Stack<ScriptVar> &stack) {
- ScriptVar p[MAX_CALL_PARAMS];
-
- switch (subIndex) {
- case 1: {
- // dialog_show
- EXTRACT_PARAMS(1);
- Dialog *dlg = new Dialog(_vm, p[0].getStr(), "TODO: Proper Title");
- _vm->_viewManager->addView(dlg);
- _vm->_viewManager->moveToFront(dlg);
- break;
- }
-
- case 2:
- // SequenceList_remove
- EXTRACT_PARAMS(1);
- _madsVm->scene()->_sequenceList.remove(p[0]);
- break;
-
- case 3:
- case 6:
- case 20: {
- // 3: start_reversible_sprite_sequence
- // 6: start_cycled_sprite_sequence
- // 20: start_sprite_sequence3
- EXTRACT_PARAMS(6);
- int idx;
- if (subIndex == 3)
- idx = startReversibleSpriteSequence(p[0], p[1] != 0, p[2], p[3], p[4], p[5]);
- else if (subIndex == 6)
- idx = startCycledSpriteSequence(p[0], p[1], p[2], p[3], p[4], p[5]);
- else
- idx = startSpriteSequence3(p[0], p[1] != 0, p[2], p[3], p[4], p[5]);
- stack.push(ScriptVar(idx));
- break;
- }
-
- case 4:
- // SequenceList_setAnimRange
- EXTRACT_PARAMS(3);
- _madsVm->scene()->_sequenceList.setAnimRange(p[0], p[1], p[2]);
- break;
-
- case 5:
- // SequenceList_addSubEntry
- EXTRACT_PARAMS(4);
- stack.push(ScriptVar(_madsVm->scene()->_sequenceList.addSubEntry(p[0], (SequenceSubEntryMode)p[1].get(), p[2], p[3])));
- break;
-
- case 7: {
- // quotes_get_pointer
- EXTRACT_PARAMS(1);
- const char *quoteStr = _madsVm->globals()->getQuote(p[0]);
- stack.push(ScriptVar(quoteStr));
- break;
- }
-
- case 8: {
- // KernelMessageList_add
- EXTRACT_PARAMS(8);
- int msgIndex = _madsVm->scene()->_kernelMessages.add(Common::Point(p[0], p[1]), p[2],
- p[3], p[4], p[5] | (p[6] << 16), p[7].getStr());
- stack.push(ScriptVar(msgIndex));
- break;
- }
-
- case 9:
- // SequenceList_unk3
- EXTRACT_PARAMS(1);
- // TODO: Implement unk3 method
-// stack.push(ScriptVar(_madsVm->scene()->_sequenceList.unk3(p[0])));
- break;
-
- case 10:
- // start_sound
- EXTRACT_PARAMS(1);
- _madsVm->_sound->playSound(p[0]);
- break;
-
- case 11:
- // SceneLogic_formAnimName
- EXTRACT_PARAMS(2);
- stack.push(ScriptVar(formAnimName((char)p[0], p[1])));
- break;
-
- case 12:
- // SpriteList_addSprites
- EXTRACT_PARAMS(2);
- stack.push(ScriptVar(_madsVm->scene()->_spriteSlots.addSprites(p[0].getStr(), false, p[1])));
- break;
-
- case 13:
- // hotspot_activate
- EXTRACT_PARAMS(2);
- // TODO: Implement setActive version that takes in a hotspot Id
-// _madsVm->scene()->getSceneResources().hotspots->setActive(p[0], p[1] != 0);
- break;
-
- case 14: {
- // DynamicHotspots_add
- EXTRACT_PARAMS(7);
- 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;
- }
-
- case 15:
- // SequenceList_setDepth
- EXTRACT_PARAMS(2);
- _madsVm->scene()->_sequenceList.setDepth(p[0], p[1]);
- break;
-
- case 16: {
- // quotes_load
- // Quotes loading can take an arbitrary number of quote Ids, terminated by a 0
- int firstId = -1;
- int quoteId;
- while ((quoteId = stack.pop()) != 0) {
- if (firstId == -1)
- firstId = quoteId;
- _madsVm->globals()->loadQuote(quoteId);
- }
-
- if (firstId != -1)
- stack.push(ScriptVar(_madsVm->globals()->getQuote(firstId)));
- break;
- }
-
- case 17: {
- // form_resource_name
- EXTRACT_PARAMS(4);
- const char *suffix = NULL;
- if (p[4].isInt()) {
- // If integer provided for suffix, it must be a value of 0 (NULL)
- uint32 vTemp = p[4] | stack.pop();
- assert(!vTemp);
- } else
- suffix = p[4].getStr();
-
- stack.push(ScriptVar(MADSResourceManager::getResourceName((char)p[1], p[0], (ExtensionType)p[3].get(),
- suffix, (int16)p[2])));
- break;
- }
-
- case 18:
- // MadsScene_loadAnimation
- EXTRACT_PARAMS(3);
- _madsVm->scene()->loadAnimation(p[1].getStr(), p[0]);
- break;
-
- case 19: {
- // Action_isAction
- int verbId = stack.pop();
- int objectNameId = (verbId == 0) ? 0 : stack.pop().get();
- int indirectObjectId = (objectNameId == 0) ? 0 : stack.pop().get();
-
- stack.push(ScriptVar(_madsVm->scene()->_action.isAction(verbId, objectNameId, indirectObjectId)));
- break;
- }
-
- case 21:
- // DynamicHotspots_remove
- EXTRACT_PARAMS(1);
- _madsVm->scene()->_dynamicHotspots.remove(p[0]);
- break;
-
- case 22: {
- // object_is_present
- EXTRACT_PARAMS(1);
- const MadsObject *obj = _madsVm->globals()->getObject(p[0]);
- stack.push(ScriptVar((obj->_roomNumber == _madsVm->scene()->_currentScene)));
- break;
- }
-
- case 23:
- // inventory_add
- EXTRACT_PARAMS(1);
- _madsVm->scene()->getInterface()->addObjectToInventory(p[0]);
- break;
-
- case 24: {
- // dialog_picture_show
- EXTRACT_PARAMS(3);
- int messageId = p[0] | (p[1] << 16);
- int objectNum = p[2];
- warning("TODO: Implement dialog with picture. MessageId=%d, objectNum=%d", messageId, objectNum);
- break;
- }
-
- case 25: {
- // object_is_in_inventory
- EXTRACT_PARAMS(1);
- const MadsObject *obj = _madsVm->globals()->getObject(p[0]);
- stack.push(ScriptVar(obj->isInInventory()));
- break;
- }
-
- case 26: {
- // object_set_room
- EXTRACT_PARAMS(2);
- MadsObject *obj = _madsVm->globals()->getObject(p[0]);
- obj->setRoom(p[1]);
- break;
- }
-
- case 27: {
- // object_get_id_from_desc
- EXTRACT_PARAMS(1);
- stack.push(_madsVm->globals()->getObjectIndex(p[0]));
- break;
- }
-
- case 28: {
- // object_get_folder
- EXTRACT_PARAMS(1);
- stack.push(_madsVm->globals()->getObjectFolder(p[0]));
- break;
- }
-
- case 29:
- // inventory_remove
- EXTRACT_PARAMS(1);
- _madsVm->scene()->getInterface()->addObjectToInventory(p[0]);
- break;
-
- case 30:
- // image_inter_list_call
- EXTRACT_PARAMS(1);
- warning("TODO: image_inter_list_call");
- break;
-
- case 31:
- // dialog_flags_show
- warning("todo: dialog_flags_show");
- break;
-
- default:
- error("Unknown subroutine %d called", subIndex);
- break;
- }
-}
-
-#undef EXTRACT_PARAMS
-
-}
diff --git a/engines/m4/mads_logic.h b/engines/m4/mads_logic.h
deleted file mode 100644
index 4f0b0d5ba2..0000000000
--- a/engines/m4/mads_logic.h
+++ /dev/null
@@ -1,117 +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.
- *
- * 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
- */
-
-#ifndef M4_MADS_LOGIC_H
-#define M4_MADS_LOGIC_H
-
-#include "common/hashmap.h"
-#include "common/hash-str.h"
-#include "common/stack.h"
-#include "m4/mads_views.h"
-
-namespace M4 {
-
-union ScriptVarValue {
- const char *strValue;
- uint32 intValue;
-};
-
-/**
- * Specifies a script variable that either be a 32-bit unsigned integer or a string pointer
- */
-class ScriptVar {
-private:
- ScriptVarValue _value;
- bool _isInt;
-public:
- ScriptVar(uint32 v = 0) { _value.intValue = v; _isInt = true; }
- ScriptVar(const char *s) { _value.strValue = s; _isInt = false; }
-
- void set(uint32 v) { _value.intValue = v; _isInt = true; }
- void set(const char *s) { _value.strValue = s; _isInt = false; }
- const char *getStr() const { assert(!_isInt); return _value.strValue; }
- uint32 get() const { assert(_isInt); return _value.intValue; }
- bool isInt() const { return _isInt; }
-
- operator int() { return get(); }
-};
-
-class MadsSceneLogic {
-private:
- // Library interface methods
- uint16 loadSpriteSet(uint16 suffixNum, uint16 sepChar);
- uint16 startReversibleSpriteSequence(uint16 srcSpriteIdx, bool flipped, int numTicks, int triggerCountdown, int timeoutTicks, int extraTicks);
- uint16 startCycledSpriteSequence(uint16 srcSpriteIdx, bool flipped, int numTicks, int triggerCountdown, int timeoutTicks, int extraTicks);
- uint16 startSpriteSequence3(uint16 srcSpriteIdx, bool flipped, int numTicks, int triggerCountdown, int timeoutTicks, int extraTicks);
- void activateHotspot(int idx, bool active);
- void getPlayerSpritesPrefix();
- void getPlayerSpritesPrefix2();
-private:
- int _sceneNumber;
- int16 _spriteIndexes[50];
- byte *_scriptsData;
- int _scriptsSize;
- Common::HashMap<Common::String, uint32> _subroutines;
- Common::Array<uint32> _subroutineOffsets;
-
- enum SubFormatIndex {SUBFORMAT_ENTER, SUBFORMAT_STEP, SUBFORMAT_PREACTIONS, SUBFORMAT_ACTIONS};
- static const char *subFormatList[];
- static const char *_opcodeStrings[];
-
- // Support functions
- const char *formAnimName(char sepChar, int16 suffixNum);
- void getSceneSpriteSet();
- void getAnimName();
-
- uint32 getDataValue(int dataId);
- void setDataValue(int dataId, uint16 dataValue);
- void getCallParameters(int numParams, Common::Stack<ScriptVar> &stack, ScriptVar *callParams);
-public:
- MadsSceneLogic() { _scriptsData = NULL; }
- ~MadsSceneLogic() { delete _scriptsData; }
-
- void initializeScripts();
- void selectScene(int sceneNum);
-
- void setupScene();
- void doEnterScene();
- void doPreactions();
- void doAction();
- void doSceneStep();
-
- void execute(const Common::String &scriptName);
- void execute(uint32 scriptOffset);
- uint32 getParam(uint32 &scriptOffset, int opcode);
- void callSubroutine(int subIndex, Common::Stack<ScriptVar> &stack);
-};
-
-class MadsGameLogic {
-public:
- static void initializeGlobals();
-};
-
-}
-
-#endif
diff --git a/engines/m4/mads_menus.cpp b/engines/m4/mads_menus.cpp
deleted file mode 100644
index 8a2ab67f11..0000000000
--- a/engines/m4/mads_menus.cpp
+++ /dev/null
@@ -1,1173 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#include "common/textconsole.h"
-
-#include "m4/mads_menus.h"
-#include "m4/m4.h"
-
-namespace M4 {
-
-#define REX_MENUSCREEN 990
-#define PHANTOM_MENUSCREEN 920
-#define DRAGON_MENUSCREEN 922
-
-#define DRAGON_MENU_BUTTON_W = 45
-#define DRAGON_MENU_BUTTON_H = 11
-
-RexMainMenuView::RexMainMenuView(MadsM4Engine *vm):
- View(vm, Common::Rect(0, 0, vm->_screen->width(), vm->_screen->height())) {
-
- _screenType = VIEWID_MAINMENU;
- _screenFlags.get = SCREVENT_ALL;
-
- _delayTimeout = 0;
- _menuItem = NULL;
- _menuItemIndex = 0;
- _frameIndex = 0;
- _highlightedIndex = -1;
- _skipFlag = false;
-
- // Load the background for the Rex Nebular game
- _bgSurface = new M4Surface();
- _bgSurface->loadBackground(REX_MENUSCREEN, &_bgPalData);
- _vm->_palette->addRange(_bgPalData);
- _bgSurface->translate(_bgPalData);
-
- int row = (height() - MADS_SURFACE_HEIGHT) / 2;
- _bgSurface->copyTo(this, 0, row);
-
- // Add in the bounding lines for the background
- setColor(2);
- hLine(0, width() - 1, row - 1);
- hLine(0, width() - 1, height() - row + 1);
-
- // Set up the menu item pos list
- _menuItemPosList[0] = Common::Point(12, 68);
- _menuItemPosList[1] = Common::Point(12, 87);
- _menuItemPosList[2] = Common::Point(12, 107);
- _menuItemPosList[3] = Common::Point(184, 75);
- _menuItemPosList[4] = Common::Point(245, 75);
- _menuItemPosList[5] = Common::Point(184, 99);
-}
-
-RexMainMenuView::~RexMainMenuView() {
- delete _menuItem;
-
- _vm->_palette->deleteRange(_bgPalData);
-
- delete _bgPalData;
- delete _bgSurface;
-
- for (uint i = 0; i < _itemPalData.size(); ++i) {
- _vm->_palette->deleteRange(_itemPalData[i]);
- delete _itemPalData[i];
- }
-}
-
-bool RexMainMenuView::onEvent(M4EventType eventType, int32 param, int x, int y, bool &captureEvents) {
- // Handle keypresses - these can be done at any time, even when the menu items are being drawn
- if (eventType == KEVENT_KEY) {
- switch (param) {
- case Common::KEYCODE_ESCAPE:
- case Common::KEYCODE_F6:
- handleAction(EXIT);
- break;
-
- case Common::KEYCODE_F1:
- handleAction(START_GAME);
- break;
-
- case Common::KEYCODE_F2:
- handleAction(RESUME_GAME);
- break;
-
- case Common::KEYCODE_F3:
- handleAction(SHOW_INTRO);
- break;
-
- case Common::KEYCODE_F4:
- handleAction(CREDITS);
- break;
-
- case Common::KEYCODE_F5:
- handleAction(QUOTES);
- break;
-
- case Common::KEYCODE_s:
- // Goodness knows why, but Rex has a key to restart the menuitem animations
-
- // Delete the current menu items
- delete _menuItem;
-
- _vm->_palette->deleteRange(_bgPalData);
- delete _bgPalData;
- for (uint i = 0; i < _itemPalData.size(); ++i) {
- _vm->_palette->deleteRange(_itemPalData[i]);
- delete _itemPalData[i];
- }
- _itemPalData.clear();
-
- // Reload the background surface, and restart the animation
- _bgSurface->loadBackground(REX_MENUSCREEN, &_bgPalData);
- _vm->_palette->addRange(_bgPalData);
- _bgSurface->translate(_bgPalData);
-
- _menuItemIndex = 0;
- _skipFlag = false;
- _menuItem = NULL;
- _vm->_mouse->cursorOff();
- break;
-
- default:
- // Any other key skips the menu animation
- _skipFlag = true;
- return false;
- }
-
- return true;
- }
-
- int row = (height() - MADS_SURFACE_HEIGHT) / 2;
- int menuIndex;
-
- switch (eventType) {
- case MEVENT_LEFT_CLICK:
- case MEVENT_LEFT_DRAG:
- if (_vm->_mouse->getCursorOn()) {
- menuIndex = getHighlightedItem(x, y);
- if (menuIndex != _highlightedIndex) {
- _bgSurface->copyTo(this, 0, row);
-
- _highlightedIndex = menuIndex;
- if (_highlightedIndex != -1) {
- M4Sprite *spr = _menuItem->getFrame(_highlightedIndex);
- const Common::Point &pt = _menuItemPosList[_highlightedIndex];
- spr->copyTo(this, pt.x, row + pt.y, spr->getTransparencyIndex());
- }
- }
- } else {
- // Skip the menu animation
- _skipFlag = true;
- }
- return true;
-
- case MEVENT_LEFT_RELEASE:
- if (_highlightedIndex != -1)
- handleAction((MadsGameAction) _highlightedIndex);
- return true;
-
- default:
- break;
- }
-
- return false;
-}
-
-void RexMainMenuView::updateState() {
- char resName[20];
- Common::SeekableReadStream *data;
- int row = (height() - MADS_SURFACE_HEIGHT) / 2;
- int itemSize;
-
- uint32 currTime = g_system->getMillis();
- if (currTime < _delayTimeout)
- return;
- _delayTimeout = currTime + MADS_MENU_ANIM_DELAY;
-
- // Rex Nebular handling to cycle through the animated display of the menu items
- if (_menuItemIndex == 7)
- return;
-
- // If the user has chosen to skip the menu animation, show the menu immediately
- if (_skipFlag && !_vm->_mouse->getCursorOn()) {
- // Clear any pending animation
- _bgSurface->copyTo(this, 0, row);
- // Quickly loop through all the menuitems to display each's final frame
- while (_menuItemIndex < 7) {
-
- if (_menuItem) {
- // Draw the final frame of the menuitem
- 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),
- spr->getTransparencyIndex());
-
- delete _menuItem;
- copyTo(_bgSurface, Common::Rect(0, row, width(), row + MADS_SURFACE_HEIGHT), 0, 0,
- spr->getTransparencyIndex());
- }
-
- // Get the next sprite set
- sprintf(resName, "RM%dA%d.SS", REX_MENUSCREEN, ++_menuItemIndex);
- data = _vm->res()->get(resName);
- _menuItem = new SpriteAsset(_vm, data, data->size(), resName);
- _vm->res()->toss(resName);
-
- // Slot it into available palette space
- RGBList *palData = _menuItem->getRgbList();
- _vm->_palette->addRange(palData);
- _menuItem->translate(palData, true);
- _itemPalData.push_back(palData);
- }
-
- _vm->_mouse->cursorOn();
- return;
- }
-
- if ((_menuItemIndex == 0) || (_frameIndex == 0)) {
- // Get the next menu item
- if (_menuItem) {
- delete _menuItem;
-
- // Copy over the current display surface area to the background, so the final frame
- // of the previous menuitem should be kept on the screen
- copyTo(_bgSurface, Common::Rect(0, row, width(), row + MADS_SURFACE_HEIGHT), 0, 0);
- }
-
- // Get the next menuitem resource
- sprintf(resName, "RM%dA%d.SS", REX_MENUSCREEN, ++_menuItemIndex);
- data = _vm->res()->get(resName);
- _menuItem = new SpriteAsset(_vm, data, data->size(), resName);
- _vm->res()->toss(resName);
-
- // Slot it into available palette space
- RGBList *palData = _menuItem->getRgbList();
- _vm->_palette->addRange(palData);
- _menuItem->translate(palData, true);
- _itemPalData.push_back(palData);
-
- _frameIndex = _menuItem->getCount() - 1;
-
- // If the final resource is now loaded, which contains the highlighted versions of
- // each menuitem, then the startup animation is complete
- if (_menuItemIndex == 7) {
- _vm->_mouse->cursorOn();
- return;
- }
- } else {
- --_frameIndex;
- }
-
- // Move to the next menuitem frame
-
- itemSize = _menuItem->getFrame(0)->height();
-
- _bgSurface->copyTo(this, 0, row);
- M4Sprite *spr = _menuItem->getFrame(_frameIndex);
- spr->copyTo(this, _menuItemPosList[_menuItemIndex - 1].x, _menuItemPosList[_menuItemIndex - 1].y +
- row + (itemSize / 2) - (spr->height() / 2), spr->getTransparencyIndex());
-}
-
-int RexMainMenuView::getHighlightedItem(int x, int y) {
- y -= (height() - MADS_SURFACE_HEIGHT) / 2;
-
- for (int index = 0; index < 6; ++index) {
- const Common::Point &pt = _menuItemPosList[index];
- M4Sprite *spr = _menuItem->getFrame(index);
-
- if ((x >= pt.x) && (y >= pt.y) && (x < (pt.x + spr->width())) && (y < (pt.y + spr->height())))
- return index;
- }
-
- return -1;
-}
-
-void RexMainMenuView::handleAction(MadsGameAction action) {
- MadsEngine *vm = (MadsEngine *)_vm;
- vm->_mouse->cursorOff();
- vm->_viewManager->deleteView(this);
-
- switch (action) {
- case START_GAME:
- case RESUME_GAME:
- // Load a sample starting scene - note that, currently, calling loadScene automatically
- // removes this menu screen from being displayed
- vm->_mouse->cursorOn();
- vm->startScene(101);
- return;
-
- case SHOW_INTRO:
- vm->_viewManager->showAnimView("@rexopen");
- break;
-
- case CREDITS:
- vm->_viewManager->showTextView("credits");
- return;
-
- case QUOTES:
- vm->_viewManager->showTextView("quotes");
- return;
-
- case EXIT:
- {
- // When the Exit action is done from the menu, show one of two possible advertisements
-
- // Activate the scene display with the specified scene
- bool altAdvert = vm->_random->getRandomNumber(1000) >= 500;
- vm->startScene(altAdvert ? 995 : 996);
- vm->_viewManager->addView(vm->_scene);
-
- vm->_viewManager->refreshAll();
- vm->delay(10000);
-
- vm->_events->quitFlag = true;
- return;
- }
- break;
- default:
- break;
- }
-}
-
-//--------------------------------------------------------------------------
-
-MadsMainMenuView::MadsMainMenuView(MadsM4Engine *vm):
- View(vm, Common::Rect(0, 0, vm->_screen->width(), vm->_screen->height())) {
-
-}
-
-bool MadsMainMenuView::onEvent(M4EventType eventType, int32 param, int x, int y, bool &captureEvents) {
- return false;
-}
-
-void MadsMainMenuView::updateState() {
- // TODO: Implement me
-}
-
-//--------------------------------------------------------------------------
-
-DragonMainMenuView::DragonMainMenuView(MadsM4Engine *vm):
- View(vm, Common::Rect(0, 0, vm->_screen->width(), vm->_screen->height())) {
-
- _screenType = VIEWID_MAINMENU;
- _screenFlags.get = SCREVENT_ALL;
-
- _delayTimeout = 0;
- _menuItem = NULL;
- _menuItemIndex = 0;
- _frameIndex = 0;
- _highlightedIndex = -1;
- _skipFlag = false;
-
- // Load the background for the Dragonsphere game
- this->loadBackground(942, &_bgPalData);
- _vm->_palette->addRange(_bgPalData);
- this->translate(_bgPalData);
-
- // Set up the menu item pos list
- _menuItemPosList[0] = Common::Point(46, 187);
- _menuItemPosList[1] = Common::Point(92, 187);
- _menuItemPosList[2] = Common::Point(138, 187);
- _menuItemPosList[3] = Common::Point(184, 187);
- _menuItemPosList[4] = Common::Point(230, 187);
- _menuItemPosList[5] = Common::Point(276, 187);
-}
-
-DragonMainMenuView::~DragonMainMenuView() {
- //if (_menuItem)
- // delete _menuItem;
-
- _vm->_palette->deleteRange(_bgPalData);
-
- delete _bgPalData;
-
- for (uint i = 0; i < _itemPalData.size(); ++i) {
- _vm->_palette->deleteRange(_itemPalData[i]);
- delete _itemPalData[i];
- }
-}
-
-bool DragonMainMenuView::onEvent(M4EventType eventType, int32 param, int x, int y, bool &captureEvents) {
- char resName[20];
- Common::SeekableReadStream *data;
-
- // Handle keypresses - these can be done at any time, even when the menu items are being drawn
- if (eventType == KEVENT_KEY) {
- switch (param) {
- case Common::KEYCODE_ESCAPE:
- case Common::KEYCODE_F6:
- handleAction(EXIT);
- break;
-
- case Common::KEYCODE_F1:
- handleAction(START_GAME);
- break;
-
- case Common::KEYCODE_F2:
- handleAction(RESUME_GAME);
- break;
-
- case Common::KEYCODE_F3:
- handleAction(SHOW_INTRO);
- break;
-
- case Common::KEYCODE_F4:
- handleAction(CREDITS);
- break;
-
- default:
- // Any other key skips the menu animation
- _skipFlag = true;
- return false;
- }
-
- return true;
- }
-
- int menuIndex;
-
- switch (eventType) {
- case MEVENT_LEFT_CLICK:
- case MEVENT_LEFT_DRAG:
- if (_vm->_mouse->getCursorOn()) {
- menuIndex = getHighlightedItem(x, y);
- if (menuIndex != _highlightedIndex) {
-
- _highlightedIndex = menuIndex;
- if (_highlightedIndex != -1) {
- sprintf(resName, "MAIN%d.SS", menuIndex);
- data = _vm->res()->get(resName);
- _menuItem = new SpriteAsset(_vm, data, data->size(), resName);
- _vm->res()->toss(resName);
-
- M4Sprite *spr = _menuItem->getFrame(1);
- spr->copyTo(this, spr->xOffset - 25, spr->yOffset - spr->height());
- }
- }
- } else {
- // Skip the menu animation
- _skipFlag = true;
- }
- return true;
-
- case MEVENT_LEFT_RELEASE:
- if (_highlightedIndex != -1)
- handleAction((MadsGameAction) _highlightedIndex);
- return true;
-
- default:
- break;
- }
-
- return false;
-}
-
-void DragonMainMenuView::updateState() {
- char resName[20];
- Common::SeekableReadStream *data;
- RGBList *palData;
- M4Sprite *spr;
-
- if (_menuItemIndex == 6)
- return;
-
- while (_menuItemIndex < 6) {
- sprintf(resName, "MAIN%d.SS", _menuItemIndex);
- data = _vm->res()->get(resName);
- _menuItem = new SpriteAsset(_vm, data, data->size(), resName);
- _vm->res()->toss(resName);
-
- // Slot it into available palette space
- palData = _menuItem->getRgbList();
- _vm->_palette->addRange(palData);
- _menuItem->translate(palData, true);
- _itemPalData.push_back(palData);
-
- spr = _menuItem->getFrame(0);
- spr->copyTo(this, spr->xOffset - 25, spr->yOffset - spr->height());
-
- if (_menuItemIndex != 5)
- delete _menuItem;
- _menuItemIndex++;
- }
-
- // Sphere
- sprintf(resName, "RM920X0.SS");
- data = _vm->res()->get(resName);
- _menuItem = new SpriteAsset(_vm, data, data->size(), resName);
- _vm->res()->toss(resName);
-
- // Slot it into available palette space
- palData = _menuItem->getRgbList();
- _vm->_palette->addRange(palData);
- _menuItem->translate(palData, true);
- _itemPalData.push_back(palData);
-
- spr = _menuItem->getFrame(0); // empty sphere
- spr->copyTo(this, spr->xOffset - 75, spr->yOffset - spr->height());
- spr = _menuItem->getFrame(1); // dragon inside sphere
- spr->copyTo(this, spr->xOffset - 75, spr->yOffset - spr->height());
-
- // Dragonsphere letters
- sprintf(resName, "RM920X3.SS");
- data = _vm->res()->get(resName);
- _menuItem = new SpriteAsset(_vm, data, data->size(), resName);
- _vm->res()->toss(resName);
-
- // Slot it into available palette space
- palData = _menuItem->getRgbList();
- _vm->_palette->addRange(palData);
- _menuItem->translate(palData, true);
- _itemPalData.push_back(palData);
-
- spr = _menuItem->getFrame(1);
- spr->copyTo(this, spr->xOffset - 140, spr->yOffset - spr->height(), spr->getTransparencyIndex());
-
- _vm->_mouse->cursorOn();
-}
-
-int DragonMainMenuView::getHighlightedItem(int x, int y) {
- y -= (height() - MADS_SURFACE_HEIGHT) / 2;
-
- for (int index = 0; index < 6; ++index) {
- const Common::Point &pt = _menuItemPosList[index];
- M4Sprite *spr = _menuItem->getFrame(0);
-
- if ((x >= pt.x - 25) && (y >= pt.y - spr->height()) && (x < (pt.x - 25 + spr->width())) && (y < (pt.y))) {
- debugCN(kDebugGraphics, "x = %d, y = %d, index = %d\n", x, y, index);
- return index;
- }
- }
-
- return -1;
-}
-
-void DragonMainMenuView::handleAction(MadsGameAction action) {
- MadsM4Engine *vm = _vm;
- vm->_mouse->cursorOff();
- vm->_viewManager->deleteView(this);
-
- switch (action) {
- case START_GAME:
- case RESUME_GAME:
- // Load a sample starting scene - note that, currently, calling loadScene automatically
- // removes this menu screen from being displayed
- vm->_mouse->cursorOn();
- vm->_viewManager->addView(vm->_scene);
- vm->_scene->loadScene(101);
- return;
-
- case SHOW_INTRO:
- vm->_viewManager->showAnimView("@dragon");
- break;
-
- case CREDITS:
- vm->_viewManager->showTextView("credits");
- return;
-
- case EXIT:
- vm->_events->quitFlag = true;
- return;
-
- default:
- break;
- }
-}
-
-
-/*--------------------------------------------------------------------------
- * RexDialogView is the base class for the different full-screen dialogs
- * in at least Rex Nebular
- *--------------------------------------------------------------------------
- */
-
-RexDialogView::RexDialogView(): View(_madsVm, Common::Rect(0, 0, _madsVm->_screen->width(), _madsVm->_screen->height())),
- MadsView(this) {
- _screenType = VIEWID_MENU;
-
- // Initialize class variables
- _priorSceneId = _madsVm->_scene->getCurrentScene();
- _dialogType = DIALOG_NONE;
-
- // Load necessary quotes
- _madsVm->globals()->loadQuoteRange(1, 48);
-
- initializeLines();
- initializeGraphics();
-}
-
-void RexDialogView::initializeLines() {
- // Set up a list of blank entries for use in the various dialogs
- for (int i = 0; i < DIALOG_LINES_SIZE; ++i) {
- DialogTextEntry rec;
- rec.in_use = false;
- _dialogText.push_back(rec);
- }
- _totalTextEntries = 0;
-
- // Set up a default sprite slot entry for a full screen refresh
- _spriteSlots.startIndex = 1;
- _spriteSlots[0].spriteType = FULL_SCREEN_REFRESH;
- _spriteSlots[0].seqIndex = -1;
-}
-
-void RexDialogView::initializeGraphics() {
- // Set needed palette entries
- _madsVm->_palette->blockRange(0, 16);
- _madsVm->_palette->setEntry(10, 0, 255, 0);
- _madsVm->_palette->setEntry(11, 0, 180, 0);
- _madsVm->_palette->setEntry(12, 255, 255, 0);
- _madsVm->_palette->setEntry(13, 180, 180, 0);
- _madsVm->_palette->setEntry(14, 255, 255, 180);
- _madsVm->_palette->setEntry(15, 180, 180, 180);
-
- // Load an appropriate background and menu sprites
- loadBackground();
- loadMenuSprites();
-
- // Set the current cursor
- _madsVm->_mouse->setCursorNum(CURSOR_ARROW);
-}
-
-
-RexDialogView::~RexDialogView() {
- _madsVm->_palette->deleteRange(_bgPalData);
- delete _bgPalData;
- delete _backgroundSurface;
-}
-
-void RexDialogView::loadBackground() {
- int bgIndex = _madsVm->globals()->sceneNumber / 100;
- int screenId = 0;
-
- switch (bgIndex) {
- case 1:
- case 2:
- screenId = 921;
- break;
- case 3:
- case 4:
- screenId = 922;
- break;
- case 5:
- case 6:
- case 7:
- screenId = 923;
- break;
- case 8:
- screenId = 924;
- break;
- case 9:
- screenId = 920;
- break;
- default:
- error("Unknown scene number");
- }
-
- _backgroundSurface = new M4Surface(width(), MADS_SURFACE_HEIGHT);
- _backgroundSurface->loadBackground(screenId, &_bgPalData);
- _vm->_palette->addRange(_bgPalData);
- _backgroundSurface->translate(_bgPalData);
-}
-
-void RexDialogView::loadMenuSprites() {
- const char *SPRITES_NAME = "*MENU.SS";
-
- _spriteSlots.addSprites(SPRITES_NAME);
-}
-
-
-void RexDialogView::updateState() {
-}
-
-void RexDialogView::onRefresh(RectList *rects, M4Surface *destSurface) {
- // Draw the framed base area
- fillRect(this->bounds(), _madsVm->_palette->BLACK);
- setColor(2);
- hLine(0, width(), MADS_Y_OFFSET - 2);
- hLine(0, width(), MADS_Y_OFFSET + MADS_SURFACE_HEIGHT + 2);
-
- // Add in the loaded background vertically centered
- _backgroundSurface->copyTo(this, 0, (height() - MADS_SURFACE_HEIGHT) / 2);
-
- // Check whether any of the dialog text entries need to be refreshed
- refreshText();
-
- // Handle the drawing of the various Mads elements
- refresh();
-
- View::onRefresh(rects, destSurface);
-}
-
-/**
- * Handles item selection within dialogs
- */
-bool RexDialogView::onEvent(M4EventType eventType, int32 param1, int x, int y, bool &captureEvents) {
- static bool word_7F28C = false;
- int word_7FED2 = 0;
- int word_8502A = 0;
-
- // If it's a keypress, handle it immediately
- if (eventType == KEVENT_KEY) {
- switch (param1) {
- case Common::KEYCODE_q | (Common::KBD_CTRL << 24):
- case Common::KEYCODE_q | (Common::KBD_ALT << 24):
- _madsVm->quitGame();
- return true;
- case Common::KEYCODE_RETURN:
- _enterFlag = true;
- _selectedLine = 0;
- break;
- case Common::KEYCODE_ESCAPE:
- _selectedLine = 0;
- break;
- default:
- return false;
- }
- }
-
- // Mark all the dialog text entries as not being seelcted
- for (uint i = 0; i < _dialogText.size(); ++i)
- _dialogText[i].state = STATE_DESELECTED;
-
- // Check if the mouse is over a registered screen object
- int idx = _screenObjects.scan(x, y, LAYER_GUI);
-
- if (word_7F28C) {
- if (y < _screenObjects[2].bounds.top) {
- if (eventType != MEVENT_LEFT_RELEASE)
- _dialogText[1].state = STATE_SELECTED;
- idx = 19;
- }
-
- if (y > _screenObjects[8].bounds.bottom) {
- if (eventType != MEVENT_LEFT_RELEASE)
- _dialogText[7].state = STATE_SELECTED;
- idx = 20;
- }
- }
-
- int objIndex = -1;
- if ((idx > 0) && ((eventType == MEVENT_LEFT_HOLD) || (eventType == MEVENT_LEFT_DRAG) ||
- (eventType == MEVENT_LEFT_RELEASE))) {
- objIndex = _screenObjects[idx].index;
-
- if ((_dialogType == DIALOG_SAVE) || (_dialogType == DIALOG_RESTORE)) {
- if ((objIndex > 7) && (objIndex <= 14))
- _dialogText[objIndex].state = STATE_SELECTED;
- }
-
- if (word_7FED2)
- word_7F28C = (objIndex > 0) && (objIndex <= 7);
-
- if (_screenObjects[idx].category == 1)
- _dialogText[objIndex].state = STATE_SELECTED;
- } else {
- idx = -1;
- }
-
- if (idx == 0)
- idx = -1;
-
- if (_dialogType == DIALOG_ERROR) {
- if (idx == 1)
- idx = -1;
- }
-
- if (eventType == MEVENT_LEFT_RELEASE) {
- if (!word_7F28C || (objIndex <= 18))
- _selectedLine = objIndex;
-
- word_8502A = -1;
- }
-
- return true;
-}
-
-void RexDialogView::setFrame(int frameNumber, int depth) {
- int slotIndex = _spriteSlots.getIndex();
- _spriteSlots[slotIndex].spriteType = FOREGROUND_SPRITE;
- _spriteSlots[slotIndex].seqIndex = 1;
- _spriteSlots[slotIndex].spriteListIndex = 0; //_menuSpritesIndex;
- _spriteSlots[slotIndex].frameNumber = frameNumber;
-
- M4Sprite *spr = _spriteSlots.getSprite(0).getFrame(frameNumber - 1);
- _spriteSlots[slotIndex].xp = spr->x;
- _spriteSlots[slotIndex].yp = spr->y;
- _spriteSlots[slotIndex].depth = depth;
- _spriteSlots[slotIndex].scale = 100;
-}
-
-void RexDialogView::initVars() {
- _v8502C = -1;
- _selectedLine = -1;
- _lineIndex = 0;
- _enterFlag = false;
- _textLines.clear();
-}
-
-void RexDialogView::addLine(const char *msg_p, Font *font, MadsTextAlignment alignment, int left, int top) {
- DialogTextEntry *rec = NULL;
-
- if (_lineIndex < _totalTextEntries) {
- if (strcmp(msg_p, _dialogText[_lineIndex].text) == 0) {
- rec = &_dialogText[_lineIndex];
- if (rec->textDisplay_index != 0) {
- MadsTextDisplayEntry &tdEntry = _textDisplay[rec->textDisplay_index];
- if (tdEntry.active) {
- if (_textLines.size() < 20) {
- // Add entry to line list
- _textLines.push_back(tdEntry.msg);
- tdEntry.msg = _textLines[_textLines.size() - 1].c_str();
- }
- }
- }
- }
- } else {
- if (_lineIndex < DIALOG_LINES_SIZE) {
- rec = &_dialogText[_lineIndex];
- _totalTextEntries = _lineIndex + 1;
- }
- }
-
- // Handling for if a line needs to be added
- if (rec) {
- strcpy(rec->text, msg_p);
- rec->font = font;
- rec->state = STATE_DESELECTED;
- rec->pos.y = top;
- rec->widthAdjust = -1;
- rec->in_use = true;
- rec->textDisplay_index = -1;
-
- switch (alignment) {
- case ALIGN_CENTER:
- // Center text
- rec->pos.x = (width() - font->getWidth(rec->text)) / 2 + left;
- break;
-
- case ALIGN_CHAR_CENTER: {
- // Text is center aligned on the '@' character within the string
- char *p = strchr(rec->text, '@');
-
- if (p) {
- // '@' string handling
- // Get length of string up to the '@' character
- *p = '\0';
- int strWidth = font->getWidth(rec->text, rec->widthAdjust);
- // Remove the character from the string. strcpy isn't used here because it's unsafe for
- // copying within the same string
- while ((*p = *(p + 1)) != '\0') ++p;
-
- rec->pos.x = (width() / 2) - strWidth;
- } else {
- rec->pos.x = left;
- }
- break;
- }
-
- case RIGHT_ALIGN:
- // Right align (moving left from given passed left)
- rec->pos.x = left - font->getWidth(rec->text);
- break;
-
- default:
- break;
- }
- }
-
- ++_lineIndex;
-}
-
-/**
- * Adds a line consisting of either a single quote, or the combination of two quote Ids
- */
-void RexDialogView::addQuote(Font *font, MadsTextAlignment alignment, int left, int top, int id1, int id2) {
- char buffer[80];
-
- // Copy the first quote string into the buffer
- const char *quoteStr = _madsVm->globals()->getQuote(id1);
- strcpy(buffer, quoteStr);
-
- // Handle the optional second quote Id
- if (id2 != 0) {
- quoteStr = _madsVm->globals()->getQuote(id2);
- strcat(buffer, " ");
- strcat(buffer, quoteStr);
- }
-
- // Add in the generated line
- addLine(buffer, font, alignment, left, top);
-}
-
-/**
- * Sets any previously created dialog text entries as clickable items
- */
-void RexDialogView::setClickableLines() {
- _screenObjects.clear();
-
- 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,
- _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);
- }
- }
-
- if ((_madsVm->globals()->dialogType == DIALOG_SAVE) || (_madsVm->globals()->dialogType == DIALOG_RESTORE)) {
- // Extra entries for the scroller areas of the Save and Restor dialogs
- _screenObjects.add(Common::Rect(293, 26, 312, 75), LAYER_GUI, 50, 2);
- _screenObjects.add(Common::Rect(293, 78, 312, 127), LAYER_GUI, 51, 2);
- }
-}
-
-/**
- * Handles creating text display objects for each dialog line initially, and when the selected state
- * of any entry changes
- */
-void RexDialogView::refreshText() {
- for (uint i = 0; i < _dialogText.size(); ++i) {
- if (!_dialogText[i].in_use)
- continue;
-
- // Get the item's colors
- uint color;
- if (_dialogText[i].state == STATE_DESELECTED)
- color = 0xB0A;
- else if (_dialogText[i].state == STATE_SELECTED)
- color = 0xD0C;
- else
- color = 0xF0E;
-
- // If there's an associated text display entry, check to see if it's color needs to change
- if (_dialogText[i].textDisplay_index >= 0) {
- MadsTextDisplayEntry &tdEntry = _textDisplay[_dialogText[i].textDisplay_index];
-
- if ((tdEntry.color1 == (color & 0xff)) && (tdEntry.color2 == (color >> 8)))
- // It's still the same, so no further action needed
- continue;
-
- // Flag the currently assigned text display to be expired, so it can be re-created
- _textDisplay.expire(_dialogText[i].textDisplay_index);
- _dialogText[i].textDisplay_index = -1;
- }
-
- // Create a new text display entry for the dialog text line
- _dialogText[i].textDisplay_index = _textDisplay.add(_dialogText[i].pos.x, _dialogText[i].pos.y,
- color, _dialogText[i].widthAdjust, _dialogText[i].text, _dialogText[i].font);
- }
-}
-
-/*--------------------------------------------------------------------------
- * RexGameMenuDialog is the main game dialog for the game
- *--------------------------------------------------------------------------
- */
-
-RexGameMenuDialog::RexGameMenuDialog(): RexDialogView() {
- _dialogType = DIALOG_GAME_MENU;
- setFrame(1, 2);
- initVars();
-
- _vm->_font->setFont(FONT_CONVERSATION_MADS);
- addLines();
- setClickableLines();
-}
-
-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
- top += 6;
- for (int idx = 0; idx < 5; ++idx) {
- top += _vm->_font->current()->getHeight() + 1;
- addQuote(_vm->_font->current(), ALIGN_CENTER, 0, top, 11 + idx);
- }
-}
-
-bool RexGameMenuDialog::onEvent(M4EventType eventType, int32 param1, int x, int y, bool &captureEvents) {
- // Call the parent event handler to handle line selection
- bool handled = RexDialogView::onEvent(eventType, param1, x, y, captureEvents);
-
- if (_selectedLine > 0) {
- switch (_selectedLine) {
- case 1:
- // Save Game
- _madsVm->globals()->dialogType = DIALOG_SAVE;
- break;
- case 2:
- // Restore Game
- _madsVm->globals()->dialogType = DIALOG_RESTORE;
- break;
- case 3:
- // Game Play Options
- _madsVm->globals()->dialogType = DIALOG_OPTIONS;
- break;
- case 4:
- // Resume Current Game
- _madsVm->globals()->dialogType = DIALOG_NONE;
- break;
- case 5:
- // Exit From Game
- _madsVm->quitGame();
- break;
- default:
- // TODO: Extra logic for such as resuming scene if necessary
- _madsVm->globals()->dialogType = DIALOG_NONE;
- break;
- }
-
- // Close this dialog
- _madsVm->_viewManager->deleteView(this);
- }
-
- return handled;
-}
-
-/*--------------------------------------------------------------------------
- * RexOptionsDialog is the game options dialog for Rex Nebular
- *--------------------------------------------------------------------------
- */
-
-RexOptionsDialog::RexOptionsDialog(): RexDialogView() {
- _dialogType = DIALOG_OPTIONS;
- _tempConfig = _madsVm->globals()->_config;
-
- setFrame(2, 2);
- initVars();
-
- _vm->_font->setFont(FONT_CONVERSATION_MADS);
- addLines();
- setClickableLines();
-}
-
-void RexOptionsDialog::reload() {
- for (int i = 0; i < DIALOG_LINES_SIZE; ++i)
- _dialogText[i].in_use = false;
- _totalTextEntries = 0;
- _textDisplay.clear();
- _screenObjects.clear();
-
- initVars();
-
- _vm->_font->setFont(FONT_CONVERSATION_MADS);
- addLines();
- setClickableLines();
-}
-
-void RexOptionsDialog::addLines() {
- // Add the title
- int top = MADS_Y_OFFSET - 2 - ((((_vm->_font->current()->getHeight() + 1) * 9 + 12) >> 1) - 78);
-
- addQuote(_vm->_font->current(), ALIGN_CENTER, 0, top, 16);
-
- // Music state line
- top += _vm->_font->current()->getHeight() + 1 + 6;
- addQuote(_vm->_font->current(), ALIGN_CHAR_CENTER, 0, top, 17, _tempConfig.musicFlag ? 24 : 25);
-
- // Sound state line
- top += _vm->_font->current()->getHeight() + 1;
- addQuote(_vm->_font->current(), ALIGN_CHAR_CENTER, 0, top, 18, _tempConfig.soundFlag ? 26 : 27);
-
- // Interface easy state line
- top += _vm->_font->current()->getHeight() + 1;
- addQuote(_vm->_font->current(), ALIGN_CHAR_CENTER, 0, top, 19, _tempConfig.easyMouse ? 29 : 28);
-
- // Inventory sppinng state line
- top += _vm->_font->current()->getHeight() + 1;
- addQuote(_vm->_font->current(), ALIGN_CHAR_CENTER, 0, top, 20, _tempConfig.invObjectsStill ? 31 : 30);
-
- // Text window state line
- top += _vm->_font->current()->getHeight() + 1;
- addQuote(_vm->_font->current(), ALIGN_CHAR_CENTER, 0, top, 21, _tempConfig.textWindowStill ? 33 : 32);
-
- // Screen fade state line
- top += _vm->_font->current()->getHeight() + 1;
- addQuote(_vm->_font->current(), ALIGN_CHAR_CENTER, 0, top, 22, _tempConfig.screenFades + 34);
-
- // Storyline mode line
- top += _vm->_font->current()->getHeight() + 1;
- addQuote(_vm->_font->current(), ALIGN_CHAR_CENTER, 0, top, 23, (_tempConfig.storyMode == 1) ? 37 : 38);
-
- // Add Done and Cancel button texts
- top += _vm->_font->current()->getHeight() + 1 + 6;
- addQuote(_vm->_font->current(), ALIGN_CENTER, -54, top, 1, 0);
- addQuote(_vm->_font->current(), ALIGN_CENTER, 54, top, 2, 0);
-}
-
-bool RexOptionsDialog::onEvent(M4EventType eventType, int32 param1, int x, int y, bool &captureEvents) {
- // Call the parent event handler to handle line selection
- bool handled = RexDialogView::onEvent(eventType, param1, x, y, captureEvents);
-
- if (_selectedLine > 0) {
- switch (_selectedLine) {
- case 0:
- // Enter or Escape
- _selectedLine = _enterFlag ? 8 : 9;
- return true;
- case 1:
- // Music line
- _tempConfig.musicFlag = !_tempConfig.musicFlag;
- break;
- case 2:
- // Sound line
- _tempConfig.soundFlag = !_tempConfig.soundFlag;
- break;
- case 3:
- // Interface line
- _tempConfig.easyMouse = !_tempConfig.easyMouse;
- break;
- case 4:
- // Inventory line
- _tempConfig.invObjectsStill = !_tempConfig.invObjectsStill;
- break;
- case 5:
- // Text window line
- _tempConfig.textWindowStill = !_tempConfig.textWindowStill;
- break;
- case 6:
- // Screen fades line
- if (++_tempConfig.screenFades > 2)
- _tempConfig.screenFades = 0;
- break;
- case 7:
- // Story mode line
- if (_tempConfig.storyMode == 2)
- _tempConfig.storyMode = 1;
- else if (_tempConfig.storyMode == 1)
- _tempConfig.storyMode = 2;
- break;
- case 8:
- case 9:
- // Done and Cancel buttons
- // TODO: Proper re-loading of settings if Cancel button clicked
- _madsVm->globals()->_config = _tempConfig;
-
- // Closing the dialog, so return to the game menu
- _madsVm->globals()->dialogType = DIALOG_GAME_MENU;
- _madsVm->_viewManager->deleteView(this);
- return true;
- }
-
- // Update the option selections
- reload();
- }
-
- return handled;
-}
-
-}
diff --git a/engines/m4/mads_menus.h b/engines/m4/mads_menus.h
deleted file mode 100644
index 4d3ea5da39..0000000000
--- a/engines/m4/mads_menus.h
+++ /dev/null
@@ -1,179 +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 M4_MADS_MENUS_H
-#define M4_MADS_MENUS_H
-
-#include "common/str-array.h"
-#include "m4/viewmgr.h"
-#include "m4/mads_views.h"
-#include "m4/font.h"
-
-namespace M4 {
-
-#define MADS_MENU_ANIM_DELAY 70
-
-enum MadsGameAction {START_GAME, RESUME_GAME, SHOW_INTRO, CREDITS, QUOTES, EXIT};
-
-enum MadsLayers {LAYER_GUI = 19};
-
-class RexMainMenuView : public View {
-private:
- Common::Point _menuItemPosList[6];
-private:
- M4Surface *_bgSurface;
- RGBList *_bgPalData;
- int _menuItemIndex;
- int _frameIndex;
- bool _skipFlag;
- SpriteAsset *_menuItem;
- Common::Array<RGBList *> _itemPalData;
- uint32 _delayTimeout;
- int _highlightedIndex;
-
- int getHighlightedItem(int x, int y);
- void handleAction(MadsGameAction action);
-public:
- RexMainMenuView(MadsM4Engine *vm);
- ~RexMainMenuView();
-
- bool onEvent(M4EventType eventType, int32 param, int x, int y, bool &captureEvents);
- void updateState();
-};
-
-class DragonMainMenuView : public View {
-private:
- Common::Point _menuItemPosList[6];
-private:
- //M4Surface *_bgSurface;
- RGBList *_bgPalData;
- int _menuItemIndex;
- int _frameIndex;
- bool _skipFlag;
- SpriteAsset *_menuItem;
- Common::Array<RGBList *> _itemPalData;
- uint32 _delayTimeout;
- int _highlightedIndex;
-
- int getHighlightedItem(int x, int y);
- void handleAction(MadsGameAction action);
-public:
- DragonMainMenuView(MadsM4Engine *vm);
- ~DragonMainMenuView();
-
- bool onEvent(M4EventType eventType, int32 param, int x, int y, bool &captureEvents);
- void updateState();
-};
-
-class MadsMainMenuView : public View {
-public:
- MadsMainMenuView(MadsM4Engine *vm);
-
- bool onEvent(M4EventType eventType, int32 param, int x, int y, bool &captureEvents);
- void updateState();
-};
-
-enum DialogTextState {STATE_DESELECTED = 0, STATE_SELECTED = 1, STATE_UNKNOWN = 2};
-
-class DialogTextEntry {
-public:
- bool in_use;
- DialogTextState state;
- Common::Point pos;
- char text[80];
- Font *font;
- int widthAdjust;
-
- int textDisplay_index;
-
- DialogTextEntry() { in_use = false; }
-};
-
-#define DIALOG_LINES_SIZE 20
-
-enum MadsTextAlignment { ALIGN_CENTER = -1, ALIGN_CHAR_CENTER = -2, RIGHT_ALIGN = -3 };
-
-
-class RexDialogView : public View, public MadsView {
-private:
- int _priorSceneId;
-
- void initializeLines();
- void initializeGraphics();
- void loadBackground();
- void loadMenuSprites();
-protected:
- MadsDialogType _dialogType;
- M4Surface *_backgroundSurface;
- RGBList *_bgPalData;
- SpriteAsset *_menuSprites;
-
- Common::Array<DialogTextEntry> _dialogText;
- Common::StringArray _textLines;
- int _totalTextEntries;
- int _dialogSelectedLine;
- Common::StringArray _saveList;
-
- int _v8502C;
- int _selectedLine;
- int _lineIndex;
- bool _enterFlag;
-
- void setFrame(int frameNumber, int depth);
- void initVars();
- void addLine(const char *msg_p, Font *font, MadsTextAlignment alignment, int left, int top);
- void addQuote(Font *font, MadsTextAlignment alignment, int left, int top, int id1, int id2 = 0);
- void setClickableLines();
- void refreshText();
-public:
- RexDialogView();
- ~RexDialogView();
-
- virtual void updateState();
- virtual void onRefresh(RectList *rects, M4Surface *destSurface);
- virtual bool onEvent(M4EventType eventType, int32 param1, int x, int y, bool &captureEvents);
-};
-
-class RexGameMenuDialog : public RexDialogView {
-private:
- void addLines();
-public:
- RexGameMenuDialog();
-
- virtual bool onEvent(M4EventType eventType, int32 param1, int x, int y, bool &captureEvents);
-};
-
-class RexOptionsDialog : public RexDialogView {
-private:
- MadsConfigData _tempConfig;
-
- void reload();
- void addLines();
-public:
- RexOptionsDialog();
-
- virtual bool onEvent(M4EventType eventType, int32 param1, int x, int y, bool &captureEvents);
-};
-
-}
-
-#endif
diff --git a/engines/m4/mads_player.cpp b/engines/m4/mads_player.cpp
deleted file mode 100644
index 73480088ee..0000000000
--- a/engines/m4/mads_player.cpp
+++ /dev/null
@@ -1,789 +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 "m4/m4.h"
-#include "m4/mads_player.h"
-#include "m4/mads_scene.h"
-
-namespace M4 {
-
-const int MadsPlayer::_directionListIndexes[32] = {
- 0, 7, 4, 3, 6, 0, 2, 5, 0, 1, 9, 4, 1, 2, 7, 9, 3, 8, 9, 6, 7, 2, 3, 6, 1, 7, 9, 4, 7, 8, 0, 0
-};
-
-MadsPlayer::MadsPlayer() {
- _playerPos = Common::Point(160, 78);
- _ticksAmount = 3;
- _forceRefresh = true;
- _stepEnabled = true;
- _visible = true;
- _yScale = 0;
- _moving = false;
-
- _spriteListStart = 0;
- //TODO:unknown vars
- _special = 0;
- _next = 0;
- _unk4 = false;
-
- _spritesChanged = true;
-
- _direction = 0;
- _newDirection = 0;
- _priorTimer = 0;
- _priorVisible = false;
- _visible3 = false;
- _spriteListIdx = 0;
- _currentScale = 0;
- strcpy(_spritesPrefix, "");
- for (int idx = 0; idx < 8; ++idx)
- _spriteSetsPresent[idx] = false;
- _frameNum = 0;
- _frameOffset = 0;
- _unk1 = 0;
- _frameCount = 0;
- _frameListIndex = 0;
- _actionIndex = 0;
- _routeCount = 0;
-
- resetActionList();
-}
-
-/**
- * Loads the sprite set for the player
- */
-bool MadsPlayer::loadSprites(const char *prefix) {
- const char suffixList[8] = { '8', '9', '6', '3', '2', '7', '4', '1' };
- char setName[80];
- bool result = true;
-
- if (prefix)
- strcpy(_spritesPrefix, prefix);
-
- _spriteSetCount = 0;
- int prefixLen = strlen(_spritesPrefix);
-
- if (prefixLen == 0) {
- // No player sprites at at all
- for (int idx = 0; idx < 8; ++idx)
- _spriteSetsPresent[idx] = false;
- } else {
- strcpy(setName, "*");
- strcat(setName, _spritesPrefix);
- strcat(setName, "_0.SS");
-
- char *digitP = strchr(setName, '_') + 1;
-
- for (int idx = 0; idx < 8; ++idx) {
- *digitP = suffixList[idx];
- _spriteSetsPresent[idx] = true;
-
- int setIndex = _madsVm->scene()->_spriteSlots.addSprites(setName, true, SPRITE_SET_CHAR_INFO);
- if (setIndex < 0) {
- if (idx < 5)
- break;
- _spriteSetsPresent[idx] = false;
- } else {
- ++_spriteSetCount;
- }
-
- if (idx == 0)
- _spriteListStart = setIndex;
- }
-
- result = 0;
- // TODO: Unknown flag
- _spritesChanged = false;
- }
-
- return result;
-}
-
-/**
- * Called each frame to update the display of the player
- */
-void MadsPlayer::update() {
- if (_forceRefresh || (_visible != _priorVisible)) {
- // If there's an existing player sprite visible, flag it for expiry
- int slotIndex = getSpriteSlot();
- if (slotIndex >= 0)
- _madsVm->scene()->_spriteSlots[slotIndex].spriteType = EXPIRED_SPRITE;
-
- // 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;
- }
- _currentDepth = newDepth;
-
- // Get the scale
- int newScale = getScale(_playerPos.y);
- _currentScale = MIN(newScale, 100);
-
- if (_visible) {
- // Player sprite needs to be rendered
- MadsSpriteSlot slot;
- slot.spriteType = FOREGROUND_SPRITE;
- slot.seqIndex = PLAYER_SEQ_INDEX;
- slot.spriteListIndex = _spriteListStart + _spriteListIdx;
- slot.frameNumber = _frameOffset + _frameNum;
- slot.xp = _playerPos.x;
- slot.yp = _playerPos.y + (_yScale * newScale) / 100;
- slot.depth = newDepth;
- slot.scale = newScale;
-
- if (slotIndex >= 0) {
- // Check if the existing player slot has the same details, and can be re-used
- MadsSpriteSlot &s2 = _madsVm->scene()->_spriteSlots[slotIndex];
- bool equal = (s2.seqIndex == slot.seqIndex) && (s2.spriteListIndex == slot.spriteListIndex)
- && (s2.frameNumber == slot.frameNumber) && (s2.xp == slot.xp) && (s2.yp == slot.yp)
- && (s2.depth == slot.depth) && (s2.scale == slot.scale);
-
- if (equal)
- // Undo the prior expiry of the player sprite
- s2.spriteType = SPRITE_ZERO;
- else
- slotIndex = -1;
- }
-
- if (slotIndex < 0) {
- // New slot needed, so allocate one and copy the slot data
- slotIndex = _madsVm->scene()->_spriteSlots.getIndex();
- _madsVm->scene()->_spriteSlots[slotIndex] = slot;
- }
-
- // TODO: Meaning of _v844c0 block
-
- }
- }
-
- _visible3 = _priorVisible = _visible;
- _forceRefresh = false;
-}
-
-/**
- * Updates the animation frame for the player
- */
-void MadsPlayer::updateFrame() {
- SpriteAsset &spriteSet = _madsVm->scene()->_spriteSlots.getSprite(_spriteListStart + _spriteListIdx);
- assert(spriteSet._charInfo);
-
- if (!spriteSet._charInfo->_numEntries) {
- _frameNum = 1;
- } else {
- _frameListIndex = _actionList[_actionIndex];
-
- if (!_visible) {
- _unk2 = 0;
- } else {
- _unk2 = _actionList2[_actionIndex];
-
- if (_actionIndex > 0)
- --_actionIndex;
- }
-
- // Set the player frame number
- int frameIndex = ABS(_frameListIndex);
- _frameNum = (_frameListIndex <= 0) ? spriteSet._charInfo->_frameList[frameIndex] :
- spriteSet._charInfo->_frameList2[frameIndex];
-
- // Set next waiting period in ticks
- if (frameIndex == 0)
- setTicksAmount();
- else
- _madsVm->_player._ticksAmount = spriteSet._charInfo->_ticksList[frameIndex];
- }
-}
-
-void MadsPlayer::setupFrame() {
- resetActionList();
- _frameOffset = 0;
- _spriteListIdx = _directionListIndexes[_direction];
- if (!_spriteSetsPresent[_spriteListIdx]) {
- // Direction isn't present, so use alternate direction, with entries flipped
- _spriteListIdx -= 4;
- _frameOffset = 0x8000;
- }
-
- SpriteAsset &spriteSet = _madsVm->scene()->_spriteSlots.getSprite(_spriteListStart + _spriteListIdx);
- assert(spriteSet._charInfo);
- _unk1 = MAX(spriteSet._charInfo->_unk1, 100);
- setTicksAmount();
-
- _frameCount = spriteSet._charInfo->_totalFrames;
- if (_frameCount == 0)
- _frameCount = spriteSet.getCount();
-
- _yScale = spriteSet._charInfo->_yScale;
-
- if ((_frameNum <= 0) || (_frameNum > _frameCount))
- _frameNum = 1;
- _forceRefresh = true;
-}
-
-void MadsPlayer::step() {
- if (_visible && _stepEnabled && !_moving && (_direction == _newDirection) && (_madsVm->_currentTimer >= GET_GLOBAL32(2))) {
- if (_actionIndex == 0) {
- int randVal = _vm->_random->getRandomNumber(29999);
-
- if (GET_GLOBAL(0) == SEX_MALE) {
- switch (_direction) {
- case 1:
- case 3:
- case 7:
- case 9:
- if (randVal < 200) {
- queueAction(-1, 0);
- queueAction(1, 0);
- }
- break;
-
- case 2:
- if (randVal < 500) {
- for (int i = 0; i < 10; ++i)
- queueAction((randVal < 250) ? 1 : 2, 0);
- } else if (randVal < 750) {
- for (int i = 0; i < 5; ++i)
- queueAction(1, 0);
- queueAction(0, 0);
- for (int i = 0; i < 5; ++i)
- queueAction(2, 0);
- }
- break;
-
- case 4:
- case 6:
- if (randVal < 500) {
- for (int i = 0; i < 10; ++i)
- queueAction(1, 0);
- }
- break;
-
- case 5:
- case 8:
- if (randVal < 200) {
- queueAction(-1, 0);
- queueAction(1, 0);
- }
- break;
- }
- }
- }
-
- SET_GLOBAL32(2, GET_GLOBAL32(2) + 6);
- }
-
- if (GET_GLOBAL(138) == 1) {
- uint32 diff = _madsVm->_currentTimer - GET_GLOBAL32(142);
- if (diff > 60) {
- SET_GLOBAL32(144, GET_GLOBAL32(144) + 1);
- } else {
- SET_GLOBAL32(144, GET_GLOBAL32(144) + diff);
- }
-
- SET_GLOBAL32(142, _madsVm->_currentTimer);
- }
-}
-
-void MadsPlayer::nextFrame() {
- if (_madsVm->_currentTimer >= (_priorTimer + _ticksAmount)) {
- _priorTimer = _madsVm->_currentTimer;
-
- if (_moving)
- move();
- else
- idle();
-
- // Post update logic
- if (_moving) {
- ++_frameNum;
- if (_frameNum > _frameCount)
- _frameNum = 1;
- _forceRefresh = true;
- } else if (!_forceRefresh) {
- idle();
- }
-
- // Final update
- update();
- }
-}
-
-void MadsPlayer::setDest(int destX, int destY, int facing) {
- resetActionList();
- 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,
- Common::Point(destX, destY), _madsVm->scene()->_depthSurface);
-
- bool v = _madsVm->scene()->getDepthHighBit(Common::Point(destX, destY));
- setupRoute(v);
- _next = 0;
-
- if (_routeCount > 0) {
- Common::Point srcPos = _playerPos;
- for (int routeCtr = _routeCount - 1; (routeCtr >= 0) && (_next == 0); --routeCtr) {
- int idx = _routeIndexes[routeCtr];
- const Common::Point &pt = _madsVm->scene()->getSceneResources()._nodes[idx].pt;
-
- _next = scanPath(_madsVm->scene()->_depthSurface, srcPos, pt);
- srcPos = pt;
- }
- }
-}
-
-
-int MadsPlayer::getScale(int yp) {
- MadsSceneResources &r = _madsVm->scene()->getSceneResources();
-
- int scale = (r.bandsRange() == 0) ? r._maxScale : (yp - r._yBandsStart) * r.scaleRange() / r.bandsRange()
- + r._minScale;
-
- return MIN(scale, 100);
-}
-
-/**
- * Scans through the scene's sprite slot list to find any sprite displaying the player
- */
-int MadsPlayer::getSpriteSlot() {
- MadsSpriteSlots &slots = _madsVm->scene()->_spriteSlots;
- for (int i = 0; i < slots.startIndex; ++i) {
- if ((slots[i].seqIndex == PLAYER_SEQ_INDEX) && (slots[i].spriteType >= SPRITE_ZERO))
- return i;
- }
- return -1;
-}
-
-void MadsPlayer::setTicksAmount() {
- SpriteAsset &spriteSet = _madsVm->scene()->_spriteSlots.getSprite(_spriteListStart + _spriteListIdx);
- assert(spriteSet._charInfo);
- _madsVm->_player._ticksAmount = spriteSet._charInfo->_ticksAmount;
- if (_madsVm->_player._ticksAmount == 0)
- _madsVm->_player._ticksAmount = 6;
-}
-
-void MadsPlayer::resetActionList() {
- _actionList[0] = 0;
- _actionList2[0] = 0;
- _actionIndex = 0;
- _unk2 = 0;
- _unk3 = 0;
-}
-
-int MadsPlayer::queueAction(int action1, int action2) {
- SpriteAsset &spriteSet = _madsVm->scene()->_spriteSlots.getSprite(_spriteListStart + _spriteListIdx);
- assert(spriteSet._charInfo);
-
- if ((action1 < spriteSet._charInfo->_numEntries) && (_actionIndex < 11)) {
- ++_actionIndex;
- _actionList[_actionIndex] = action1;
- _actionList2[_actionIndex] = action2;
- return false;
- }
-
- return true;
-}
-
-void MadsPlayer::idle() {
- if (_direction != _newDirection) {
- // The direction has changed, so reset for new direction
- dirChanged();
- return;
- }
-
- SpriteAsset &spriteSet = _madsVm->scene()->_spriteSlots.getSprite(_spriteListStart + _spriteListIdx);
- assert(spriteSet._charInfo);
- if (spriteSet._charInfo->_numEntries == 0)
- // No entries, so exit immediately
- return;
-
- int frameIndex = ABS(_frameListIndex);
- int direction = (_frameListIndex < 0) ? -1 : 1;
-
- if (frameIndex >= spriteSet._charInfo->_numEntries)
- // Reset back to the start of the list
- _frameListIndex = 0;
- else {
- _frameNum += direction;
- _forceRefresh = true;
-
- if (spriteSet._charInfo->_frameList2[frameIndex] < _frameNum) {
- _unk3 = _unk2;
- updateFrame();
- }
- if (spriteSet._charInfo->_frameList[frameIndex] < _frameNum) {
- _unk3 = _unk2;
- updateFrame();
- }
- }
-}
-
-void MadsPlayer::move() {
- bool routeFlag = false;
-
- if (_moving) {
- int idx = _routeCount;
- while (!_v844C0 && (_destPos.x == _playerPos.x) && (_destPos.y == _playerPos.y)) {
- if (idx != 0) {
- --idx;
- SceneNode &node = _madsVm->scene()->getSceneResources()._nodes[_routeIndexes[idx]];
- _destPos = node.pt;
- routeFlag = true;
- } else if (_v844BE == idx) {
- // End of walking path
- _routeCount = 0;
- _moving = false;
- turnToDestFacing();
- routeFlag = true;
- idx = _routeCount;
- } else {
- _v844C0 = _v844BE;
- _v844BC = true;
- _v844BE = 0;
- _stepEnabled = true;
- routeFlag = false;
- }
-
- if (!_moving)
- break;
- }
- _routeCount = idx;
- }
-
- if (routeFlag && _moving)
- startMovement();
-
- if (_newDirection != _direction)
- dirChanged();
- else if (!_moving)
- updateFrame();
-
- int var1 = _unk1;
- if (_unk4 && (_hypotenuse > 0)) {
- int v1 = -(_currentScale - 100) * (_posDiff.x - 1) / _hypotenuse + _currentScale;
- var1 = MAX(1, 10000 / (v1 * _currentScale * var1));
- }
-
- if (!_moving || (_direction != _newDirection))
- return;
-
- Common::Point newPos = _playerPos;
-
- if (_v8452E < var1) {
- do {
- if (_v8452C < _posDiff.x)
- _v8452C += _posDiff.y;
- if (_v8452C >= _posDiff.x) {
- if ((_posChange.y > 0) || (_v844C0 != 0))
- newPos.y += _yDirection;
- --_posChange.y;
- _v8452C -= _posDiff.x;
- }
-
- if (_v8452C < _posDiff.x) {
- if ((_posChange.x > 0) || (_v844C0 != 0))
- newPos.x += _xDirection;
- --_posChange.x;
- }
-
- if ((_v844BC == 0) && (_v844C0 == 0) && (_v844BE == 0)) {
- routeFlag = _madsVm->scene()->getDepthHighBit(newPos);
-
- if (_special == 0)
- _special = _madsVm->scene()->getDepthHighBits(newPos);
- }
-
- _v8452E += _v84530;
-
- } while ((_v8452E < var1) && !routeFlag && ((_posChange.x > 0) || (_posChange.y > 0) || (_v844C0 != 0)));
- }
-
- _v8452E -= var1;
-
- if (routeFlag)
- moveComplete();
- else {
- if (!_v844C0) {
- // If the move is complete, make sure the position is exactly on the given destination
- if (_posChange.x == 0)
- newPos.x = _destPos.x;
- if (_posChange.y == 0)
- newPos.y = _destPos.y;
- }
-
- _playerPos = newPos;
- }
-}
-
-void MadsPlayer::dirChanged() {
- int dirIndex = 0, dirIndex2 = 0;
- int newDir = 0, newDir2 = 0;
-
- if (_direction != _newDirection) {
- // Find the index for the given direction in the player direction list
- int tempDir = _direction;
- do {
- ++dirIndex;
- newDir += tempDir;
- tempDir = _directionListIndexes[tempDir + 10];
- } while (tempDir != _newDirection);
- }
-
-
- if (_direction != _newDirection) {
- // Find the index for the given direction in the player direction list
- int tempDir = _direction;
- do {
- ++dirIndex2;
- newDir2 += tempDir;
- tempDir = _directionListIndexes[tempDir + 20];
- } while (tempDir != _newDirection);
- }
-
- int diff = dirIndex - dirIndex2;
- if (diff == 0)
- diff = newDir - newDir2;
-
- _direction = (diff >= 0) ? _directionListIndexes[_direction + 20] : _directionListIndexes[_direction + 10];
- setupFrame();
- if ((_direction == _newDirection) && !_moving)
- updateFrame();
-
- _priorTimer += 1;
-}
-
-void MadsPlayer::moveComplete() {
- reset();
- //todo: Unknown flag
-}
-
-void MadsPlayer::reset() {
- _destPos = _playerPos;
- _destFacing = 5;
- _newDirection = _direction;
-
- _madsVm->scene()->_action._startWalkFlag = false;
- _madsVm->scene()->_action._walkFlag = false;
- _moving = false;
- _v844BC = false;
- _v844C0 = false;
- _v844BE = 0;
- _next = 0;
- _routeCount = 0;
-}
-
-/**
- * Scans along an edge connecting two points within the depths/walk surface, and returns the information of the first
- * pixel high nibble encountered with a non-zero value
- */
-int MadsPlayer::scanPath(M4Surface *depthSurface, const Common::Point &srcPos, const Common::Point &destPos) {
- // For compressed depth surfaces, always return 0
- if (_madsVm->scene()->getSceneResources()._depthStyle != 2)
- return 0;
-
- int yDiff = destPos.y - srcPos.y;
- int yAmount = MADS_SURFACE_WIDTH;
-
- if (yDiff < 0) {
- yDiff = -yDiff;
- yAmount = -yAmount;
- }
-
- int xDiff = destPos.x - srcPos.y;
- int xDirection = 1;
- int xAmount = 0;
- if (xDiff < 0) {
- xDiff = -xDiff;
- xDirection = -xDirection;
- xAmount = MIN(yDiff, xDiff);
- }
-
- ++xDiff;
- ++yDiff;
-
- const byte *srcP = depthSurface->getBasePtr(srcPos.x, srcPos.y);
- int index = xAmount;
-
- // Outer horizontal movement loop
- for (int yIndex = 0; yIndex < yDiff; ++yIndex) {
- index += yDiff;
- int v = (*srcP & 0x7F) >> 4;
- if (v)
- return v;
-
- // Inner loop for handling vertical movement
- while (index >= xDiff) {
- index -= xDiff;
-
- v = (*srcP & 0x7F) >> 4;
- if (v)
- return v;
-
- srcP += yAmount;
- }
-
- srcP += xDirection;
- }
-
- return 0;
-}
-
-/**
- * Starts a player moving to a given destination
- */
-void MadsPlayer::startMovement() {
- int xDiff = _destPos.x - _playerPos.x;
- int yDiff = _destPos.y - _playerPos.y;
- int srcScale = getScale(_playerPos.y);
- int destScale = getScale(_destPos.y);
-
- // Sets the X direction
- if (xDiff > 0)
- _xDirection = 1;
- else if (xDiff < 0)
- _xDirection = -1;
- else
- _xDirection = 0;
-
- // Sets the Y direction
- if (yDiff > 0)
- _yDirection = 1;
- else if (yDiff < 0)
- _yDirection = -1;
- else
- _yDirection = 0;
-
- xDiff = ABS(xDiff);
- yDiff = ABS(yDiff);
- int scaleDiff = ABS(srcScale - destScale);
-
- int xAmt100 = xDiff * 100;
- int yAmt100 = yDiff * 100;
- int xAmt33 = xDiff * 33;
-
- int scaleAmount = (_unk4 ? scaleDiff * 3 : 0) + 100 * yDiff / 100;
- int scaleAmount100 = scaleAmount * 100;
-
- // Figure out direction that will need to be moved in
- int majorDir;
- if (xDiff == 0)
- majorDir = 1;
- else if (yDiff == 0)
- majorDir = 3;
- else {
- if ((scaleAmount < xDiff) && ((xAmt33 / scaleAmount) >= 141))
- majorDir = 3;
- else if (yDiff <= xDiff)
- majorDir = 2;
- else if ((scaleAmount100 / xDiff) >= 141)
- majorDir = 1;
- else
- majorDir = 2;
- }
-
- switch (majorDir) {
- case 1:
- _newDirection = (_yDirection <= 0) ? 8 : 2;
- break;
- case 2: {
- _newDirection = ((_yDirection <= 0) ? 9 : 3) - ((_xDirection <= 0) ? 2 : 0);
- break;
- }
- case 3:
- _newDirection = (_xDirection <= 0) ? 4 : 6;
- break;
- default:
- break;
- }
-
- _hypotenuse = SqrtF16(xAmt100 * xAmt100 + yAmt100 * yAmt100);
- _posDiff.x = xDiff + 1;
- _posDiff.y = yDiff + 1;
- _posChange.x = xDiff;
- _posChange.y = yDiff;
-
- 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;
-}
-
-void MadsPlayer::turnToDestFacing() {
- if (_destFacing != 5)
- _newDirection = _destFacing;
-}
-
-void MadsPlayer::setupRoute(bool bitFlag) {
- // Reset the flag set of nodes in use
- SceneNodeList &nodes = _madsVm->scene()->getSceneResources()._nodes;
- for (uint i = 0; i < nodes.size(); ++i)
- nodes[i].active = false;
-
- // Start constructing route node list
- _routeLength = 0x3FFF;
- _routeCount = 0;
-
- setupRouteNode(_tempRoute, nodes.size() - 1, bitFlag ? 0xC000 : 0x8000, 0);
-}
-
-void MadsPlayer::setupRouteNode(int *routeIndexP, int nodeIndex, int flags, int routeLength) {
- SceneNodeList &nodes = _madsVm->scene()->getSceneResources()._nodes;
- SceneNode &currentNode = nodes[nodeIndex];
- currentNode.active = true;
-
- *routeIndexP++ = nodeIndex;
-
- int subIndex = nodes.size() - 2;
- int indexVal = nodes[nodeIndex].indexes[subIndex];
- if (indexVal & flags) {
- routeLength += indexVal & 0x3FFF;
- if (routeLength < _routeLength) {
- // Found a new shorter route to destination, so set up the route with the found one
- Common::copy(_tempRoute, routeIndexP, _routeIndexes);
- _routeCount = routeIndexP - _tempRoute;
- _routeLength = indexVal & 0x3FFF;
- }
- } else {
- for (int idx = nodes.size() - 2; idx > 0; --idx) {
- int nodePos = idx - 1;
- if (!nodes[nodePos].active && ((currentNode.indexes[nodePos] & flags) != 0))
- setupRouteNode(routeIndexP, nodePos, 0x8000, indexVal & 0x3fff);
- }
- }
-
- currentNode.active = false;
-}
-
-} // End of namespace M4
diff --git a/engines/m4/mads_player.h b/engines/m4/mads_player.h
deleted file mode 100644
index bbeefaf3d5..0000000000
--- a/engines/m4/mads_player.h
+++ /dev/null
@@ -1,113 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#ifndef M4_MADS_PLAYER_H
-#define M4_MADS_PLAYER_H
-
-#include "common/scummsys.h"
-#include "m4/mads_scene.h"
-
-namespace M4 {
-
-#define PLAYER_SEQ_INDEX -2
-
-class MadsPlayer {
-private:
- int getScale(int yp);
- int getSpriteSlot();
- void setTicksAmount();
- void resetActionList();
- int queueAction(int v0, int v1);
- void idle();
- void move();
- void dirChanged();
- void reset();
- int scanPath(M4Surface *depthSurface, const Common::Point &srcPos, const Common::Point &destPos);
- void startMovement();
- void setupRouteNode(int *routeIndexP, int nodeIndex, int flags, int routeLength);
-public:
- char _spritesPrefix[16];
- int _spriteSetCount;
- bool _spriteSetsPresent[8];
- Common::Point _playerPos;
- Common::Point _destPos;
- Common::Point _posChange;
- Common::Point _posDiff;
- int _hypotenuse;
- uint32 _priorTimer;
- uint _ticksAmount;
- int16 _direction, _newDirection;
- bool _stepEnabled;
- bool _visible, _priorVisible;
- bool _visible3;
- bool _forceRefresh;
- int16 _currentScale;
- int16 _yScale;
- int16 _currentDepth;
- int16 _spriteListStart, _spriteListIdx;
- bool _spritesChanged;
- uint16 _frameOffset, _frameNum;
- bool _moving;
- int _unk1;
- int _frameCount;
- int _frameListIndex;
- int _actionIndex;
- int _actionList[12];
- int _actionList2[12];
- int _unk2;
- int _unk3;
- int _xDirection, _yDirection;
- int _destFacing;
- int _special;
- int _next;
- int _routeCount;
- int _routeOffset;
- int _tempRoute[MAX_ROUTE_NODES];
- int _routeIndexes[MAX_ROUTE_NODES];
- bool _unk4;
- bool _v844BC;
- int _v844BE;
- bool _v844C0;
- int _v8452E;
- int _v8452C;
- int _v84530;
- int _routeLength;
-
- static const int _directionListIndexes[32];
-public:
- MadsPlayer();
-
- bool loadSprites(const char *prefix);
- void update();
- void updateFrame();
- void setupFrame();
- void step();
- void nextFrame();
- void setDest(int destX, int destY, int facing);
- void turnToDestFacing();
- void setupRoute(bool bitFlag);
- void moveComplete();
-};
-
-} // End of namespace M4
-
-#endif
diff --git a/engines/m4/mads_scene.cpp b/engines/m4/mads_scene.cpp
deleted file mode 100644
index 5f160aa300..0000000000
--- a/engines/m4/mads_scene.cpp
+++ /dev/null
@@ -1,1272 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#include "common/system.h"
-#include "common/textconsole.h"
-
-#include "m4/mads_scene.h"
-#include "m4/dialogs.h"
-#include "m4/globals.h"
-#include "m4/scene.h"
-#include "m4/events.h"
-#include "m4/graphics.h"
-#include "m4/rails.h"
-#include "m4/font.h"
-#include "m4/m4_views.h"
-#include "m4/mads_views.h"
-#include "m4/compression.h"
-#include "m4/staticres.h"
-#include "m4/animation.h"
-
-namespace M4 {
-
-static const int INV_ANIM_FRAME_SPEED = 2;
-static const int INVENTORY_X = 160;
-static const int INVENTORY_Y = 159;
-static const int SCROLLER_DELAY = 200;
-
-//--------------------------------------------------------------------------
-
-void SceneNode::load(Common::SeekableReadStream *stream) {
- // Get the next data block
- pt.x = stream->readUint16LE();
- pt.y = stream->readUint16LE();
-
- for (int i = 0; i < MAX_ROUTE_NODES; ++i)
- indexes[i] = stream->readUint16LE();
-}
-
-//--------------------------------------------------------------------------
-
-MadsScene::MadsScene(MadsEngine *vm): _sceneResources(), Scene(vm, &_sceneResources), MadsView(this) {
- _vm = vm;
- _activeAnimation = NULL;
-
- MadsView::_bgSurface = Scene::_backgroundSurface;
- MadsView::_depthSurface = Scene::_walkSurface;
- _interfaceSurface = new MadsInterfaceView(vm);
- _showMousePos = false;
- _mouseMsgIndex = -1;
- _previousScene = -1;
-}
-
-MadsScene::~MadsScene() {
- delete _activeAnimation;
- _activeAnimation = NULL;
- leaveScene();
- _vm->_viewManager->deleteView(_interfaceSurface);
-}
-
-/**
- * Secondary scene loading code
- */
-void MadsScene::loadScene2(const char *aaName, int sceneNumber) {
- // TODO: Completely finish
- _madsVm->globals()->previousScene = _madsVm->globals()->sceneNumber;
- _madsVm->globals()->sceneNumber = sceneNumber;
-
- _spriteSlots.clear();
- _sequenceList.clear();
- _kernelMessages.clear();
-
- // Load up the properties for the scene
- _sceneResources.load(_currentScene, NULL, 0/*word_83546*/, _walkSurface, _backgroundSurface);
-
- // Load scene walk paths
- loadSceneCodes(_currentScene);
-
- // Initialize the scene animation
- uint16 flags = 0x4100;
- if (_madsVm->globals()->_config.textWindowStill)
- flags |= 0x200;
-
- _sceneAnimation->initialize(aaName, flags, _interfaceSurface, NULL);
-}
-
-/**
- * Existing ScummVM code that needs to be eventually replaced with MADS code
- */
-void MadsScene::loadSceneTemporary() {
- /* Existing code that eventually needs to be replaced with the proper MADS code */
- // Set system palette entries
- _vm->_palette->blockRange(0, 18);
- RGB8 sysColors[3] = { {0x1f<<2, 0x2d<<2, 0x31<<2}, {0x24<<2, 0x37<<2, 0x3a<<2},
- {0x00<<2, 0x10<<2, 0x16<<2}};
- _vm->_palette->setPalette(&sysColors[0], 4, 3);
-
- _interfaceSurface->initialize();
-
- loadSceneHotspots(_currentScene);
-
- _action.clear();
-}
-
-void MadsScene::loadScene(int sceneNumber) {
- // Close the menu if it's active
- View *mainMenu = _vm->_viewManager->getView(VIEWID_MAINMENU);
- if (mainMenu != NULL) {
- _vm->_viewManager->deleteView(mainMenu);
- }
-
- // Handle common scene setting
- Scene::loadScene(sceneNumber);
- _madsVm->globals()->_nextSceneId = sceneNumber;
-
- // Existing ScummVM code that needs to be eventually replaced with MADS code
- loadSceneTemporary();
-
- _madsVm->_player._spritesChanged = true;
- _madsVm->globals()->clearQuotes();
- _dynamicHotspots.reset();
-
- // Signal the script engine what scene is to be active
- _sceneLogic.selectScene(sceneNumber);
-
- // Add the scene if necessary to the list of scenes that have been visited
- _vm->globals()->addVisitedScene(sceneNumber);
-
- if (_vm->getGameType() == GType_RexNebular)
- _sceneLogic.setupScene();
-
- // TODO: Unknown code
-
- // Secondary scene load routine
- if (_vm->getGameType() == GType_RexNebular)
- // Secondary scene load routine
- loadScene2("*I0.AA", sceneNumber);
-
- _madsVm->_player.loadSprites(NULL);
-
- switch (_madsVm->globals()->_config.screenFades) {
- case 0:
- _abortTimers2 = 2;
- break;
- case 2:
- _abortTimers2 = 21;
- break;
- default:
- _abortTimers2 = 20;
- break;
- }
- _abortTimers = 0;
- _abortTimersMode2 = ABORTMODE_1;
-
-
- // Do any scene specific setup
- if (_vm->getGameType() == GType_RexNebular)
- _sceneLogic.doEnterScene();
-
- // Miscellaneous player setup
- _madsVm->_player._destPos = _madsVm->_player._destPos;
- _madsVm->_player._newDirection = _madsVm->_player._direction;
- _madsVm->_player.setupFrame();
- _madsVm->_player.updateFrame();
-
- // Purge resources
- _vm->res()->purge();
-}
-
-void MadsScene::loadSceneHotspots(int sceneNumber) {
- char filename[kM4MaxFilenameSize];
- sprintf(filename, "rm%i.hh", sceneNumber);
- MadsPack hotSpotData(filename, _vm);
- Common::SeekableReadStream *hotspotStream = hotSpotData.getItemStream(0);
-
- int hotspotCount = hotspotStream->readUint16LE();
- delete hotspotStream;
-
- hotspotStream = hotSpotData.getItemStream(1);
-
- // Clear current hotspot lists
- _sceneResources.hotspots->clear();
- _sceneResources.hotspots->loadHotSpots(hotspotStream, hotspotCount);
-
- delete hotspotStream;
-}
-
-void MadsScene::leaveScene() {
- _sceneResources.hotspots->clear();
- _sceneResources.dynamicHotspots->clear();
-
- delete _sceneResources.hotspots;
- delete _sceneResources.dynamicHotspots;
- delete _walkSurface;
-
- if (_activeAnimation) {
- delete _activeAnimation;
- _activeAnimation = NULL;
- }
-
- Scene::leaveScene();
-}
-
-void MadsScene::show() {
- Scene::show();
- _vm->_viewManager->addView(_interfaceSurface);
-}
-
-void MadsScene::loadSceneCodes(int sceneNumber, int index) {
- char filename[kM4MaxFilenameSize];
- Common::SeekableReadStream *sceneS;
-
- if (_vm->getGameType() == GType_Phantom || _vm->getGameType() == GType_DragonSphere) {
- sprintf(filename, "rm%i.ww%i", sceneNumber, index);
- MadsPack walkData(filename, _vm);
- sceneS = walkData.getItemStream(0);
- _walkSurface->loadCodesMads(sceneS);
- _vm->res()->toss(filename);
- }
-}
-
-void MadsScene::mouseMove(int x, int y) {
- HotSpot *currentHotSpot = _sceneResources.hotspots->findByXY(x, y);
- if (currentHotSpot != NULL) {
- _vm->_mouse->setCursorNum(currentHotSpot->getCursor());
-
- _action._selectedRow = -1;
- _action._actionMode = ACTMODE_NONE;
- _action._actionMode2 = ACTMODE2_4;
- _action._hotspotId = currentHotSpot->getIndex();
-
- } else {
- _vm->_mouse->setCursorNum(0);
- }
-}
-
-void MadsScene::leftClick(int x, int y) {
- // TODO: figure out the rest of Scene_leftClick, and implements relevant parts in the interface class
- _action._v86F4C = -1;
- _action._v86F4E = 0;
- _customDest = _madsVm->_mouse->currentPos();
- _action._selectedAction = -1;
- _action._v86F4A = true;
-}
-
-void MadsScene::rightClick(int x, int y) {
- if (_vm->getGameType() == GType_RexNebular) {
- // ***DEBUG*** - sample dialog display
- int idx = 3; //_madsVm->_globals->messageIndexOf(0x277a);
- const char *msg = _madsVm->globals()->loadMessage(idx);
- Dialog *dlg = new Dialog(_vm, msg, "TEST DIALOG");
- _vm->_viewManager->addView(dlg);
- _vm->_viewManager->moveToFront(dlg);
- }
-}
-
-void MadsScene::setAction(int action, int objectId) {
- VALIDATE_MADS;
-
- error("todo");
- // TODO: Actually executing actions directly for objects. Also, some object actions are special in that
- // a second object can be selected, as in 'use gun to shoot person', with requires a target
-/*
- // Set up the new action
- strcpy(statusText, _madsVm->globals()->getVocab(action));
- statusText[0] = toupper(statusText[0]); // capitalize first letter
-
- if (objectId != -1) {
- MadsObject *obj = _madsVm->globals()->getObject(objectId);
- sprintf(statusText + strlen(statusText), " %s", _madsVm->globals()->getVocab(obj->descId));
- } else {
- _currentAction = action;
- }
-*/
-// setStatusText(statusText);
-}
-
-/**
- * Draws all the elements of the scene
- */
-void MadsScene::drawElements() {
- refresh();
-
- // Copy the user interface surface onto the surface
- _interfaceSurface->copyTo(this, 0, this->height() - _interfaceSurface->height());
-}
-
-
-void MadsScene::update() {
- // Draw all the various elements
- drawElements();
-
- _action.set();
-}
-
-void MadsScene::updateState() {
- if (!_abortTimers && !_madsVm->_player._unk3) {
- if (_dynamicHotspots._changed)
- _dynamicHotspots.refresh();
-
-// int v = (_madsVm->_player._stepEnabled && !_action._startWalkFlag && !_abortTimers2) ? 1 : 0;
-// _screenObjects.check(v, false);
- }
-
- // Handle starting off any selected action
- bool doPreAction = false;
- if ((_action._selectedAction != 0) && _madsVm->_player._stepEnabled &&
- !_action._startWalkFlag && !_abortTimers && !_madsVm->_player._unk3) {
- // Start the action
- _action.startAction();
-
- if (_action._action.verbId == kVerbLookAt) {
- _action._action.verbId = kVerbLook;
- _action._savedFields.selectedRow = 0;
- }
- doPreAction = true;
- }
- if (doPreAction || ((_abortTimers != 0) && (_abortTimersMode == ABORTMODE_2)))
- doPreactions();
-
- checkStartWalk();
-
- if (_action._inProgress && !_madsVm->_player._moving && !_action._startWalkFlag &&
- (_madsVm->_player._newDirection == _madsVm->_player._direction)) {
- // Reached the end of action movement, so ready to actually do action
- doAction();
- } else if ((_abortTimers != 0) && (_abortTimersMode == ABORTMODE_0))
- // Do an action designated by scripts
- doAction();
-
- bool freeFlag = false;
- if (_currentScene != _nextScene)
- freeFlag = true;
- else {
- doSceneStep();
-
- if (_currentScene != _nextScene)
- freeFlag = true;
- else {
- // Update the player
- _madsVm->_player.nextFrame();
-
- // Handle updating the animation
- if (!_abortTimers && (_activeAnimation))
- _activeAnimation->update();
-
- // Handle refreshing the mouse position display
- if (_mouseMsgIndex != -1)
- _madsVm->scene()->_kernelMessages.remove(_mouseMsgIndex);
- if (_showMousePos) {
- char buffer[20];
- sprintf(buffer, "(%d,%d)", _madsVm->_mouse->currentPos().x, _madsVm->_mouse->currentPos().y);
-
- _mouseMsgIndex = _madsVm->scene()->_kernelMessages.add(Common::Point(5, 5), 0x203, 0, 0, 1, buffer);
- }
- }
- }
-
- if (_madsVm->globals()->_config.easyMouse)
- _action.refresh();
-
- if ((_activeAnimation) && !_abortTimers) {
- _activeAnimation->update();
- if (((MadsAnimation *) _activeAnimation)->freeFlag() || freeFlag) {
- delete _activeAnimation;
- _activeAnimation = NULL;
- }
- }
-
- MadsView::update();
-
- // Remove the animation if it's been completed
- if ((_activeAnimation) && ((MadsAnimation *)_activeAnimation)->freeFlag())
- freeAnimation();
-
- if ((_action._selectedAction != 0) || !_madsVm->_player._stepEnabled) {
- _action.clear();
- _action._selectedAction = 0;
- }
-}
-
-void MadsScene::checkStartWalk() {
- if (_action._startWalkFlag && _action._walkFlag) {
- _madsVm->_player.setDest(_destPos.x, _destPos.y, _destFacing);
- _action._startWalkFlag = false;
- }
-}
-
-void MadsScene::doPreactions() {
- if ((_screenObjects._v832EC == 0) || (_screenObjects._v832EC == 2)) {
- _abortTimersMode2 = ABORTMODE_2;
- _action.checkAction();
-
- _sceneLogic.doPreactions();
-
- if (_abortTimersMode == ABORTMODE_2)
- _abortTimers = 0;
- }
-}
-
-void MadsScene::doSceneStep() {
- // Step through the scene
- _sceneLogic.doSceneStep();
-
- _madsVm->_player.step();
- _madsVm->_player._unk3 = 0;
-
- if (_abortTimersMode == ABORTMODE_1)
- _abortTimers = 0;
-}
-
-void MadsScene::doAction() {
- AbortTimerMode mode = ABORTMODE_0;
- _abortTimersMode2 = mode;
-
- if ((_action._inProgress || (_abortTimers != 0)) && !_action._v8453A) {
- _sceneLogic.doAction();
- mode = _action._inProgress ? ABORTMODE_0 : ABORTMODE_1;
- }
-
- if (_screenObjects._v832EC)
- _action._inProgress = false;
- else {
- if ((_action._inProgress || (_abortTimers != 0)) && (mode == ABORTMODE_0) && (_action._v8453A == mode)) {
- // TODO: sound_fn_p();
- mode = _action._inProgress ? ABORTMODE_0 : ABORTMODE_1;
-
- }
-
- if ((_action._inProgress || (_abortTimers != 0)) && (mode == ABORTMODE_0) && (_action._v8453A == mode)) {
- // Perform a core scene-indepedant action on an object
- // object_do_action
- }
- }
-
-}
-
-
-/**
- * Does extra work at cleaning up the animation, and then deletes it
- */
-void MadsScene::freeAnimation() {
- if (!_activeAnimation)
- return;
-
- MadsAnimation *anim = (MadsAnimation *)_activeAnimation;
- if (anim->freeFlag()) {
- _madsVm->scene()->_spriteSlots.clear();
- _madsVm->scene()->_spriteSlots.fullRefresh();
- _madsVm->scene()->_sequenceList.scan();
- }
-
- if (_madsVm->_player._visible) {
- _madsVm->_player._forceRefresh = true;
- _madsVm->_player.update();
- }
-
- delete _activeAnimation;
- _activeAnimation = NULL;
-}
-
-
-int MadsScene::loadSceneSpriteSet(const char *setName) {
- char resName[100];
- strcpy(resName, setName);
-
- // Append a '.SS' if it doesn't alreayd have an extension
- if (!strchr(resName, '.'))
- strcat(resName, ".SS");
-
- return _spriteSlots.addSprites(resName);
-}
-
-enum boxSprites {
- topLeft = 0,
- topRight = 1,
- bottomLeft = 2,
- bottomRight = 3,
- left = 4,
- right = 5,
- top = 6,
- bottom = 7,
- topMiddle = 8,
- filler1 = 9,
- filler2 = 10
- // TODO: finish this
-};
-
-// TODO: calculate width and height, show text, show face if it exists
-// TODO: this has been tested with Dragonsphere only, there are some differences
-// in the sprites used in Phantom
-void MadsScene::showMADSV2TextBox(char *text, int x, int y, char *faceName) {
- int repeatX = 40; // FIXME: this is hardcoded
- int repeatY = 30; // FIXME: this is hardcoded
- int curX = x, curY = y;
- int topRightX = x; // TODO: this is probably not needed
- Common::SeekableReadStream *data = _vm->res()->get("box.ss");
- SpriteAsset *boxSprites = new SpriteAsset(_vm, data, data->size(), "box.ss");
- _vm->res()->toss("box.ss");
-
- RGBList *palData = new RGBList(boxSprites->getColorCount(), boxSprites->getPalette(), true);
- _vm->_palette->addRange(palData);
-
- for (int i = 0; i < boxSprites->getCount(); i++)
- boxSprites->getFrame(i)->translate(palData); // sprite pixel translation
-
- // Top left corner
- boxSprites->getFrame(topLeft)->copyTo(_backgroundSurface, x, curY);
- curX += boxSprites->getFrame(topLeft)->width();
-
- // Top line
- for (int i = 0; i < repeatX; i++) {
- boxSprites->getFrame(top)->copyTo(_backgroundSurface, curX, curY + 3);
- curX += boxSprites->getFrame(top)->width();
- }
-
- // Top right corner
- boxSprites->getFrame(topRight)->copyTo(_backgroundSurface, curX, curY);
- topRightX = curX;
-
- // Top middle
- // FIXME: the transparent color for this is also the black border color
- boxSprites->getFrame(topMiddle)->copyTo(_backgroundSurface,
- x + (curX - x) / 2 - boxSprites->getFrame(topMiddle)->width() / 2,
- curY - 5, 167);
- curX = x;
- curY += boxSprites->getFrame(topLeft)->height();
-
- // -----------------------------------------------------------------------------------------------
-
- // Draw contents
- for (int i = 0; i < repeatY; i++) {
- for (int j = 0; j < repeatX; j++) {
- if (j == 0) {
- boxSprites->getFrame(left)->copyTo(_backgroundSurface, curX + 3, curY);
- curX += boxSprites->getFrame(left)->width();
- } else if (j == repeatX - 1) {
- curX = topRightX - 2;
- boxSprites->getFrame(right)->copyTo(_backgroundSurface, curX + 3, curY + 1);
- } else {
- // TODO: the background of the contents follows a pattern which is not understood yet
- if (j % 2 == 0) {
- boxSprites->getFrame(filler1)->copyTo(_backgroundSurface, curX + 3, curY);
- curX += boxSprites->getFrame(filler1)->width();
- } else {
- boxSprites->getFrame(filler2)->copyTo(_backgroundSurface, curX + 3, curY);
- curX += boxSprites->getFrame(filler2)->width();
- }
- }
- } // for j
- curX = x;
- curY += boxSprites->getFrame(left)->height();
- } // for i
-
- // -----------------------------------------------------------------------------------------------
- curX = x;
-
- // Bottom left corner
- boxSprites->getFrame(bottomLeft)->copyTo(_backgroundSurface, curX, curY);
- curX += boxSprites->getFrame(bottomLeft)->width();
-
- // Bottom line
- for (int i = 0; i < repeatX; i++) {
- boxSprites->getFrame(bottom)->copyTo(_backgroundSurface, curX, curY + 1);
- curX += boxSprites->getFrame(bottom)->width();
- }
-
- // Bottom right corner
- boxSprites->getFrame(bottomRight)->copyTo(_backgroundSurface, curX, curY + 1);
-}
-
-void MadsScene::loadAnimation(const Common::String &animName, int abortTimers) {
- if (_activeAnimation)
- error("Multiple active animations are not allowed");
-
- MadsAnimation *anim = new MadsAnimation(_vm, this);
- anim->load(animName.c_str(), abortTimers);
- _activeAnimation = anim;
-}
-
-bool MadsScene::getDepthHighBit(const Common::Point &pt) {
- const byte *p = _depthSurface->getBasePtr(pt.x, pt.y);
- if (_sceneResources._depthStyle == 2)
- return ((*p << 4) & 0x80) != 0;
-
- return (*p & 0x80) != 0;
-}
-
-bool MadsScene::getDepthHighBits(const Common::Point &pt) {
- if (_sceneResources._depthStyle == 2)
- return 0;
-
- const byte *p = _depthSurface->getBasePtr(pt.x, pt.y);
- return (*p & 0x70) >> 4;
-}
-
-/*--------------------------------------------------------------------------*/
-
-void MadsSceneResources::load(int sceneNumber, const char *resName, int v0, M4Surface *depthSurface, M4Surface *surface) {
- char buffer1[80];
- const char *sceneName;
-
- // TODO: Initialize spriteSet / xp_list
-
- if (sceneNumber > 0) {
- sceneName = MADSResourceManager::getResourceName(RESPREFIX_RM, sceneNumber, ".DAT");
- } else {
- strcpy(buffer1, "*");
- strcat(buffer1, resName);
- sceneName = buffer1; // TODO: Check whether this needs to be converted to 'HAG form'
- }
-
- Common::SeekableReadStream *rawStream = _vm->_resourceManager->get(sceneName);
- MadsPack sceneInfo(rawStream);
-
- // Chunk 0:
- // Basic scene info
- Common::SeekableReadStream *stream = sceneInfo.getItemStream(0);
-
- if (_vm->getGameType() == GType_RexNebular) {
- int resSceneId = stream->readUint16LE();
- assert(resSceneId == sceneNumber);
- } else {
- char roomFilename[10];
- char roomFilenameExpected[10];
- sprintf(roomFilenameExpected, "*RM%d", sceneNumber);
-
- stream->read(roomFilename, 6);
- roomFilename[6] = 0;
- assert(!strcmp(roomFilename, roomFilenameExpected));
- }
-
- // TODO: The following is wrong for Phantom/Dragon
- _artFileNum = stream->readUint16LE();
- _depthStyle = stream->readUint16LE();
- _width = stream->readUint16LE();
- _height = stream->readUint16LE();
-
- stream->skip(24);
-
- int nodeCount = stream->readUint16LE();
- _yBandsEnd = stream->readUint16LE();
- _yBandsStart = stream->readUint16LE();
- _maxScale = stream->readSint16LE();
- _minScale = stream->readSint16LE();
- for (int i = 0; i < DEPTH_BANDS_SIZE; ++i)
- _depthBands[i] = stream->readUint16LE();
- stream->skip(2);
-
- // Load in any scene objects
- for (int i = 0; i < nodeCount; ++i) {
- SceneNode rec;
- rec.load(stream);
- _nodes.push_back(rec);
- }
- for (int i = 0; i < 20 - nodeCount; ++i)
- stream->skip(48);
-
- // Add two extra nodes in that will be used for player movement
- for (int i = 0; i < 2; ++i) {
- SceneNode rec;
- _nodes.push_back(rec);
- }
-
- int setCount = stream->readUint16LE();
- stream->readUint16LE();
- for (int i = 0; i < setCount; ++i) {
- char buffer2[64];
- Common::String s(buffer2, 64);
- _setNames.push_back(s);
- }
-
- delete stream;
-
- // Initialize a copy of the surfaces if they weren't provided
- bool dsFlag = false, ssFlag = false;
- if (!surface) {
- surface = new M4Surface(_width, _height);
- ssFlag = true;
- } else if ((_width != surface->width()) || (_height != surface->height()))
- surface->setSize(_width, _height);
-
- if (!depthSurface) {
- depthSurface = new M4Surface(_width, _height);
- dsFlag = true;
- } else if ((_width != depthSurface->width()) || (_height != depthSurface->height()))
- depthSurface->setSize(_width, _height);
-
-
- // For Rex Nebular, read in the scene's compressed walk surface information
- if (_vm->getGameType() == GType_RexNebular) {
- assert(depthSurface);
- stream = sceneInfo.getItemStream(1);
- byte *walkData = (byte *)malloc(stream->size());
- stream->read(walkData, stream->size());
-
- // For Rex Nebular, the walk areas are part of the scene info
- byte *destP = depthSurface->getBasePtr(0, 0);
- const byte *srcP = walkData;
- byte runLength;
-
- // Run length encoded depth data
- while ((runLength = *srcP++) != 0) {
- if (_depthStyle == 2) {
- // 2-bit depth pixels
- byte byteVal = *srcP++;
- for (int byteCtr = 0; byteCtr < runLength; ++byteCtr) {
- byte v = byteVal;
- for (int bitCtr = 0; bitCtr < 4; ++bitCtr, v >>= 2)
- *destP++ = (((v & 1) + 1) << 3) - 1;
- }
- } else {
- // 8-bit depth pixels
- Common::set_to(destP, destP + runLength, *srcP++);
- destP += runLength;
- }
- }
-
- free(walkData);
- delete stream;
- }
-
- _vm->_resourceManager->toss(sceneName);
-
- // Load the surface artwork
- surface->loadBackground(_artFileNum);
-
- // Final cleanup
- if (ssFlag)
- delete surface;
- if (dsFlag)
- delete depthSurface;
-}
-
-void MadsSceneResources::setRouteNode(int nodeIndex, const Common::Point &pt, M4Surface *depthSurface) {
- int flags, hypotenuse;
-
- _nodes[nodeIndex].pt = pt;
-
- // Recalculate inter-node lengths
- for (uint idx = 0; idx < _nodes.size(); ++idx) {
- int entry;
- if (idx == (uint)nodeIndex) {
- entry = 0x3FFF;
- } else {
- // Process the node
- flags = getRouteFlags(pt, _nodes[idx].pt, depthSurface);
-
- int xDiff = ABS(_nodes[idx].pt.x - pt.x);
- int yDiff = ABS(_nodes[idx].pt.y - pt.y);
- hypotenuse = SqrtF16(xDiff * xDiff + yDiff * yDiff);
-
- if (hypotenuse >= 0x3FFF)
- // Shouldn't ever be this large
- hypotenuse = 0x3FFF;
-
- entry = hypotenuse | flags;
- _nodes[idx].indexes[nodeIndex] = entry;
- _nodes[nodeIndex].indexes[idx] = entry;
- }
- }
-}
-
-int MadsSceneResources::getRouteFlags(const Common::Point &src, const Common::Point &dest, M4Surface *depthSurface) {
- int result = 0x8000;
- bool flag = false;
-
- int xDiff = ABS(dest.x - src.x);
- int yDiff = ABS(dest.y - src.y);
- int xDirection = dest.x >= src.x ? 1 : -1;
- int yDirection = dest.y >= src.y ? depthSurface->width() : -depthSurface->width();
- int majorDiff = 0;
- if (dest.x < src.x)
- majorDiff = MAX(xDiff, yDiff);
- ++xDiff;
- ++yDiff;
-
- byte *srcP = depthSurface->getBasePtr(src.x, src.y);
-
- int totalCtr = majorDiff;
- for (int xCtr = 0; xCtr < xDiff; ++xCtr, srcP += xDirection) {
- totalCtr += yDiff;
-
- if ((*srcP & 0x80) == 0)
- flag = false;
- else if (!flag) {
- flag = true;
- result -= 0x4000;
- if (result == 0)
- break;
- }
-
- while (totalCtr >= xDiff) {
- totalCtr -= xDiff;
-
- if ((*srcP & 0x80) == 0)
- flag = false;
- else if (!flag) {
- flag = true;
- result -= 0x4000;
- if (result == 0)
- break;
- }
-
- srcP += yDirection;
- }
- if (result == 0)
- break;
- }
-
- return result;
-}
-
-/*--------------------------------------------------------------------------*/
-
-/*--------------------------------------------------------------------------
- * MadsInterfaceView handles the user interface section at the bottom of
- * game screens in MADS games
- *--------------------------------------------------------------------------
- */
-
-MadsInterfaceView::MadsInterfaceView(MadsM4Engine *vm): GameInterfaceView(vm,
- Common::Rect(0, MADS_SURFACE_HEIGHT, vm->_screen->width(), vm->_screen->height())) {
- _screenType = VIEWID_INTERFACE;
- _highlightedElement = -1;
- _topIndex = 0;
- _selectedObject = -1;
- _cheatKeyCtr = 0;
-
- _objectSprites = NULL;
- _objectPalData = NULL;
-
- /* Set up the rect list for screen elements */
- // Actions
- for (int i = 0; i < 10; ++i)
- _screenObjects.addRect((i / 5) * 32 + 1, (i % 5) * 8 + MADS_SURFACE_HEIGHT + 2,
- ((i / 5) + 1) * 32 + 3, ((i % 5) + 1) * 8 + MADS_SURFACE_HEIGHT + 2);
-
- // Scroller elements (up arrow, scroller, down arrow)
- _screenObjects.addRect(73, 160, 82, 167);
- _screenObjects.addRect(73, 168, 82, 190);
- _screenObjects.addRect(73, 191, 82, 198);
-
- // Inventory object names
- for (int i = 0; i < 5; ++i)
- _screenObjects.addRect(89, 158 + i * 8, 160, 166 + i * 8);
-
- // Full rectangle area for all vocab actions
- for (int i = 0; i < 5; ++i)
- _screenObjects.addRect(239, 158 + i * 8, 320, 166 + i * 8);
-}
-
-MadsInterfaceView::~MadsInterfaceView() {
- delete _objectSprites;
-}
-
-void MadsInterfaceView::setFontMode(InterfaceFontMode newMode) {
- switch (newMode) {
- case ITEM_NORMAL:
- _vm->_font->current()->setColors(4, 4, 0xff);
- break;
- case ITEM_HIGHLIGHTED:
- _vm->_font->current()->setColors(5, 5, 0xff);
- break;
- case ITEM_SELECTED:
- _vm->_font->current()->setColors(6, 6, 0xff);
- break;
- }
-}
-
-void MadsInterfaceView::initialize() {
- // Build up the inventory list
- _inventoryList.clear();
-
- for (uint i = 0; i < _madsVm->globals()->getObjectsSize(); ++i) {
- MadsObject *obj = _madsVm->globals()->getObject(i);
- if (obj->_roomNumber == PLAYER_INVENTORY)
- _inventoryList.push_back(i);
- }
-
- // If the inventory has at least one object, select it
- if (_inventoryList.size() > 0)
- setSelectedObject(_inventoryList[0]);
-}
-
-void MadsInterfaceView::setSelectedObject(int objectNumber) {
- char resName[80];
-
- // Load inventory resource
- if (_objectSprites) {
- _vm->_palette->deleteRange(_objectPalData);
- delete _objectSprites;
- }
-
- // Check to make sure the object is in the inventory, and also visible on-screen
- int idx = _inventoryList.indexOf(objectNumber);
- if (idx == -1) {
- // Object wasn't found, so return
- _selectedObject = -1;
- return;
- }
-
- // Found the object
- if (idx < _topIndex)
- _topIndex = idx;
- else if (idx >= (_topIndex + 5))
- _topIndex = MAX(0, idx - 4);
-
- _selectedObject = objectNumber;
- sprintf(resName, "*OB%.3dI.SS", objectNumber);
-
- Common::SeekableReadStream *data = _vm->res()->get(resName);
- _objectSprites = new SpriteAsset(_vm, data, data->size(), resName);
- _vm->res()->toss(resName);
-
- // Slot it into available palette space
- _objectPalData = _objectSprites->getRgbList();
- _vm->_palette->addRange(_objectPalData);
- _objectSprites->translate(_objectPalData, true);
-
- _objectFrameNumber = 0;
-}
-
-void MadsInterfaceView::addObjectToInventory(int objectNumber) {
- if (_inventoryList.indexOf(objectNumber) == -1) {
- _madsVm->globals()->getObject(objectNumber)->_roomNumber = PLAYER_INVENTORY;
- _inventoryList.push_back(objectNumber);
- }
-
- setSelectedObject(objectNumber);
-}
-
-void MadsInterfaceView::onRefresh(RectList *rects, M4Surface *destSurface) {
- _vm->_font->setFont(FONT_INTERFACE_MADS);
- char buffer[100];
-
- // Check to see if any dialog is currently active
- bool dialogVisible = _vm->_viewManager->getView(LAYER_DIALOG) != NULL;
-
- // Highlighting logic for action list
- int actionIndex = 0;
- for (int x = 0; x < 2; ++x) {
- for (int y = 0; y < 5; ++y, ++actionIndex) {
- // Determine the font color depending on whether an item is selected. Note that the first action,
- // 'Look', is always 'selected', even when another action is clicked on
- setFontMode((_highlightedElement == actionIndex) ? ITEM_HIGHLIGHTED :
- ((actionIndex == 0) ? ITEM_SELECTED : ITEM_NORMAL));
-
- // Get the verb action and capitalise it
- const char *verbStr = _madsVm->globals()->getVocab(kVerbLook + actionIndex);
- strcpy(buffer, verbStr);
- if ((buffer[0] >= 'a') && (buffer[0] <= 'z')) buffer[0] -= 'a' - 'A';
-
- // Display the verb
- const Common::Rect r(_screenObjects[actionIndex]);
- _vm->_font->current()->writeString(destSurface, buffer, r.left, r.top, r.width(), 0);
- }
- }
-
- // Check for highlighting of the scrollbar controls
- if ((_highlightedElement == SCROLL_UP) || (_highlightedElement == SCROLL_SCROLLER) || (_highlightedElement == SCROLL_DOWN)) {
- // Highlight the control's borders
- const Common::Rect r(_screenObjects[_highlightedElement]);
- destSurface->frameRect(r, 5);
- }
-
- // Draw the horizontal line in the scroller representing the current top selected
- const Common::Rect scroller(_screenObjects[SCROLL_SCROLLER]);
- int yP = (_inventoryList.size() < 2) ? 0 : (scroller.height() - 5) * _topIndex / (_inventoryList.size() - 1);
- destSurface->setColor(4);
- destSurface->hLine(scroller.left + 2, scroller.right - 3, scroller.top + 2 + yP);
-
- // List inventory items
- for (uint i = 0; i < 5; ++i) {
- if ((_topIndex + i) >= _inventoryList.size())
- break;
-
- const char *descStr = _madsVm->globals()->getVocab(_madsVm->globals()->getObject(
- _inventoryList[_topIndex + i])->_descId);
- strcpy(buffer, descStr);
- if ((buffer[0] >= 'a') && (buffer[0] <= 'z')) buffer[0] -= 'a' - 'A';
-
- const Common::Rect r(_screenObjects[INVLIST_START + i]);
-
- // Set the highlighting of the inventory item
- if (_highlightedElement == (int)(INVLIST_START + i)) setFontMode(ITEM_HIGHLIGHTED);
- else if (_selectedObject == _inventoryList[_topIndex + i]) setFontMode(ITEM_SELECTED);
- else setFontMode(ITEM_NORMAL);
-
- // Write out it's description
- _vm->_font->current()->writeString(destSurface, buffer, r.left, r.top, r.width(), 0);
- }
-
- // Handle the display of any currently selected object
- if (_objectSprites) {
- // Display object sprite. Note that the frame number isn't used directly, because it would result
- // in too fast an animation
- M4Sprite *spr = _objectSprites->getFrame(_objectFrameNumber / INV_ANIM_FRAME_SPEED);
- spr->copyTo(destSurface, INVENTORY_X, INVENTORY_Y, TRANSPARENT_COLOR_INDEX);
-
- if (!_madsVm->globals()->_config.invObjectsStill && !dialogVisible) {
- // If objects need to be animated, move to the next frame
- if (++_objectFrameNumber >= (_objectSprites->getCount() * INV_ANIM_FRAME_SPEED))
- _objectFrameNumber = 0;
- }
-
- // List the vocab actions for the currently selected object
- MadsObject *obj = _madsVm->globals()->getObject(_selectedObject);
- int yIndex = MIN(_highlightedElement - VOCAB_START, obj->_vocabCount - 1);
-
- for (int i = 0; i < obj->_vocabCount; ++i) {
- const Common::Rect r(_screenObjects[VOCAB_START + i]);
-
- // Get the vocab description and capitalise it
- const char *descStr = _madsVm->globals()->getVocab(obj->_vocabList[i].vocabId);
- strcpy(buffer, descStr);
- if ((buffer[0] >= 'a') && (buffer[0] <= 'z')) buffer[0] -= 'a' - 'A';
-
- // Set the highlighting and display the entry
- setFontMode((i == yIndex) ? ITEM_HIGHLIGHTED : ITEM_NORMAL);
- _vm->_font->current()->writeString(destSurface, buffer, r.left, r.top, r.width(), 0);
- }
- }
-}
-
-bool MadsInterfaceView::onEvent(M4EventType eventType, int32 param1, int x, int y, bool &captureEvents) {
- MadsAction &act = _madsVm->scene()->_action;
-
- // If the mouse isn't being held down, then reset the repeated scroll timer
- if (eventType != MEVENT_LEFT_HOLD)
- _nextScrollerTicks = 0;
-
- // Handle various event types
- switch (eventType) {
- case MEVENT_MOVE:
- // If the cursor isn't in "wait mode", don't do any processing
- if (_vm->_mouse->getCursorNum() == CURSOR_WAIT)
- return true;
-
- // Ensure the cursor is the standard arrow
- _vm->_mouse->setCursorNum(CURSOR_ARROW);
-
- // Check if any interface element is currently highlighted
- _highlightedElement = _screenObjects.find(Common::Point(x, y));
-
- return true;
-
- case MEVENT_LEFT_CLICK:
- // Left mouse click
- {
- // Check if an inventory object was selected
- if ((_highlightedElement >= INVLIST_START) && (_highlightedElement < (INVLIST_START + 5))) {
- // Ensure there is an inventory item listed in that cell
- uint idx = _highlightedElement - INVLIST_START;
- if ((_topIndex + idx) < _inventoryList.size()) {
- // Set the selected object
- setSelectedObject(_inventoryList[_topIndex + idx]);
- }
- } else if ((_highlightedElement >= ACTIONS_START) && (_highlightedElement < (ACTIONS_START + 10))) {
- // 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);
- int vocabIndex = MIN(_highlightedElement - VOCAB_START, obj->_vocabCount - 1);
- if (vocabIndex >= 0) {
- act._actionMode = ACTMODE_OBJECT;
- act._actionMode2 = ACTMODE2_2;
- act._flags1 = obj->_vocabList[1].flags1;
- act._flags2 = obj->_vocabList[1].flags2;
-
- act._action.verbId = _selectedObject;
- act._articleNumber = act._flags2;
- }
- }
- }
- return true;
-
- case MEVENT_LEFT_HOLD:
- // Left mouse hold
- // Handle the scroller - the up/down buttons allow for multiple actions whilst the mouse is held down
- if ((_highlightedElement == SCROLL_UP) || (_highlightedElement == SCROLL_DOWN)) {
- if ((_nextScrollerTicks == 0) || (g_system->getMillis() >= _nextScrollerTicks)) {
- // Handle scroll up/down action
- _nextScrollerTicks = g_system->getMillis() + SCROLLER_DELAY;
-
- if ((_highlightedElement == SCROLL_UP) && (_topIndex > 0))
- --_topIndex;
- if ((_highlightedElement == SCROLL_DOWN) && (_topIndex < (int)(_inventoryList.size() - 1)))
- ++_topIndex;
- }
- }
- return true;
-
- case MEVENT_LEFT_DRAG:
- // Left mouse drag
- // Handle the the the scroller area that can be dragged to adjust the top displayed index
- if (_highlightedElement == SCROLL_SCROLLER) {
- // Calculate the new top index based on the Y position
- const Common::Rect r(_screenObjects[SCROLL_SCROLLER]);
- _topIndex = CLIP((int)(_inventoryList.size() - 1) * (y - r.top - 2) / (r.height() - 5),
- 0, (int)_inventoryList.size() - 1);
- }
- return true;
-
- case KEVENT_KEY:
- if (_cheatKeyCtr == CHEAT_SEQUENCE_MAX)
- handleCheatKey(param1);
- handleKeypress(param1);
- return true;
-
- default:
- break;
- }
-
- return false;
-}
-
-bool MadsInterfaceView::handleCheatKey(int32 keycode) {
- switch (keycode) {
- case Common::KEYCODE_SPACE:
- // TODO: Move player to current destination
- return true;
-
- case Common::KEYCODE_c | (Common::KBD_CTRL << 24):
- // Toggle display of mouse position
- _madsVm->scene()->_showMousePos = !_madsVm->scene()->_showMousePos;
- break;
-
- case Common::KEYCODE_t | (Common::KBD_ALT << 24): {
- // Teleport to room
- //Scene *sceneView = (Scene *)vm->_viewManager->getView(VIEWID_SCENE);
- // TODO: Implement teleport code
-
- return true;
- }
-
- default:
- break;
- }
-
- return false;
-}
-
-const char *CHEAT_SEQUENCE = "widepipe";
-
-bool MadsInterfaceView::handleKeypress(int32 keycode) {
- int flags = keycode >> 24;
- int kc = keycode & 0xffff;
-
- // Capitalise the letter if necessary
- if (_cheatKeyCtr < CHEAT_SEQUENCE_MAX) {
- if ((flags & Common::KBD_CTRL) && (kc == CHEAT_SEQUENCE[_cheatKeyCtr])) {
- ++_cheatKeyCtr;
- if (_cheatKeyCtr == CHEAT_SEQUENCE_MAX)
- Dialog::display(_vm, 22, cheatingEnabledDesc);
- return true;
- } else {
- _cheatKeyCtr = 0;
- }
- }
-
- // Handle the various keys
- if ((keycode == Common::KEYCODE_ESCAPE) || (keycode == Common::KEYCODE_F1)) {
- // Game menu
- _madsVm->globals()->dialogType = DIALOG_GAME_MENU;
- leaveScene();
- return false;
- } else if (flags & Common::KBD_CTRL) {
- // Handling of the different control key combinations
- switch (kc) {
- case Common::KEYCODE_i:
- // Mouse to inventory
- warning("TODO: Mouse to inventory");
- break;
-
- case Common::KEYCODE_k:
- // Toggle hotspots
- warning("TODO: Toggle hotspots");
- break;
-
- case Common::KEYCODE_p:
- // Player stats
- warning("TODO: Player stats");
- break;
-
- case Common::KEYCODE_q:
- // Quit game
- break;
-
- case Common::KEYCODE_s:
- // Activate sound
- warning("TODO: Activate sound");
- break;
-
- case Common::KEYCODE_t:
- // Rotate player - This was Ctrl-U in the original, but in ScummVM Ctrl-U is a global mute key
- _madsVm->_player._newDirection = _madsVm->_player._directionListIndexes[_madsVm->_player._newDirection + 10];
- break;
-
- case Common::KEYCODE_v: {
- // Release version
- Dialog *dlg = new Dialog(_vm, GameReleaseInfoStr, GameReleaseTitleStr);
- _vm->_viewManager->addView(dlg);
- _vm->_viewManager->moveToFront(dlg);
- return false;
- }
-
- default:
- break;
- }
- } else if ((flags & Common::KBD_ALT) && (kc == Common::KEYCODE_q)) {
- // Quit Game
-
- } else {
- // Standard keypresses
- switch (kc) {
- case Common::KEYCODE_F2:
- // Save game
- _madsVm->globals()->dialogType = DIALOG_SAVE;
- leaveScene();
- break;
- case Common::KEYCODE_F3:
- // Restore game
- _madsVm->globals()->dialogType = DIALOG_RESTORE;
- leaveScene();
- break;
- }
- }
-//DIALOG_OPTIONS
- return false;
-}
-
-void MadsInterfaceView::leaveScene() {
- // Close the scene
- View *view = _madsVm->_viewManager->getView(VIEWID_SCENE);
- _madsVm->_viewManager->deleteView(view);
-}
-
-//--------------------------------------------------------------------------
-
-int getActiveAnimationBool() {
- return (_madsVm->scene()->activeAnimation()) ? 1 : 0;
-}
-
-int getAnimationCurrentFrame() {
- Animation *anim = _madsVm->scene()->activeAnimation();
- return anim ? anim->getCurrentFrame() : 0;
-}
-
-
-} // End of namespace M4
diff --git a/engines/m4/mads_scene.h b/engines/m4/mads_scene.h
deleted file mode 100644
index 9835de4daf..0000000000
--- a/engines/m4/mads_scene.h
+++ /dev/null
@@ -1,195 +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 M4_MADS_SCENE_H
-#define M4_MADS_SCENE_H
-
-#include "m4/scene.h"
-#include "m4/mads_logic.h"
-#include "m4/mads_views.h"
-
-namespace M4 {
-
-#define INTERFACE_HEIGHT 106
-class MadsInterfaceView;
-
-#define DEPTH_BANDS_SIZE 15
-#define MAX_ROUTE_NODES 22
-
-enum ScreenCategory {CAT_NONE = 0, CAT_ACTION = 1, CAT_INV_LIST = 2, CAT_INV_VOCAB, CAT_HOTSPOT = 4,
- CAT_INV_ANIM = 6, CAT_6, CAT_INV_SCROLLER = 7, CAT_12 = 12};
-
-class SceneNode {
-public:
- Common::Point pt;
- int indexes[MAX_ROUTE_NODES];
-
- bool active;
-
- SceneNode() {
- active = false;
- }
-
- void load(Common::SeekableReadStream *stream);
-};
-
-typedef Common::Array<SceneNode> SceneNodeList;
-
-class MadsSceneResources: public SceneResources {
-private:
- int getRouteFlags(const Common::Point &src, const Common::Point &dest, M4Surface *depthSurface);
-public:
- int _sceneId;
- int _artFileNum;
- int _depthStyle;
- int _width;
- int _height;
- SceneNodeList _nodes;
- Common::Array<Common::String> _setNames;
- int _yBandsStart, _yBandsEnd;
- int _maxScale, _minScale;
- int _depthBands[DEPTH_BANDS_SIZE];
-
- MadsSceneResources() {}
- ~MadsSceneResources() {}
- void load(int sceneId, const char *resName, int v0, M4Surface *depthSurface, M4Surface *surface);
- int bandsRange() const { return _yBandsEnd - _yBandsStart; }
- int scaleRange() const { return _maxScale - _minScale; }
- void setRouteNode(int nodeIndex, const Common::Point &pt, M4Surface *depthSurface);
-};
-
-class MadsScene : public Scene, public MadsView {
-private:
- MadsEngine *_vm;
- MadsSceneResources _sceneResources;
- Animation *_activeAnimation;
-
- MadsSceneLogic _sceneLogic;
- SpriteAsset *_playerSprites;
- int _mouseMsgIndex;
- int _highlightedHotspot;
-
- void drawElements();
- void loadScene2(const char *aaName, int sceneNumber);
- void loadSceneTemporary();
- void loadSceneHotspots(int sceneNumber);
- void clearAction();
- void appendActionVocab(int vocabId, bool capitalise);
- void setAction();
- void checkStartWalk();
- void doPreactions();
- void doSceneStep();
- void doAction();
-public:
- char _aaName[100];
- bool _showMousePos;
- Common::Point _destPos;
- int _destFacing;
- Common::Point _customDest;
-public:
- MadsScene(MadsEngine *vm);
- virtual ~MadsScene();
- void initialize() {
- _sceneLogic.initializeScripts();
- }
-
- // Methods that differ between engines
- virtual void loadScene(int sceneNumber);
- virtual void leaveScene();
- virtual void loadSceneCodes(int sceneNumber, int index = 0);
- virtual void show();
- virtual void mouseMove(int x, int y);
- virtual void leftClick(int x, int y);
- virtual void rightClick(int x, int y);
- virtual void setAction(int action, int objectId = -1);
- virtual void update();
-
- virtual void updateState();
-
- int loadSceneSpriteSet(const char *setName);
- void showMADSV2TextBox(char *text, int x, int y, char *faceName);
- void loadAnimation(const Common::String &animName, int abortTimers);
- Animation *activeAnimation() const { return _activeAnimation; }
- void freeAnimation();
-
- MadsInterfaceView *getInterface() { return (MadsInterfaceView *)_interfaceSurface; }
- MadsSceneResources &getSceneResources() { return _sceneResources; }
- bool getDepthHighBit(const Common::Point &pt);
- bool getDepthHighBits(const Common::Point &pt);
-};
-
-#define CHEAT_SEQUENCE_MAX 8
-
-class IntegerList : public Common::Array<int> {
-public:
- int indexOf(int v) {
- for (uint i = 0; i < size(); ++i)
- if (operator [](i) == v)
- return i;
- return -1;
- }
-};
-
-enum InterfaceFontMode {ITEM_NORMAL, ITEM_HIGHLIGHTED, ITEM_SELECTED};
-
-enum InterfaceObjects {ACTIONS_START = 0, SCROLL_UP = 10, SCROLL_SCROLLER = 11, SCROLL_DOWN = 12,
- INVLIST_START = 13, VOCAB_START = 18};
-
-class MadsInterfaceView : public GameInterfaceView {
-private:
- IntegerList _inventoryList;
- RectList _screenObjects;
- int _highlightedElement;
- int _topIndex;
- uint32 _nextScrollerTicks;
- int _cheatKeyCtr;
-
- // Object display fields
- int _selectedObject;
- SpriteAsset *_objectSprites;
- RGBList *_objectPalData;
- int _objectFrameNumber;
-
- void setFontMode(InterfaceFontMode newMode);
- bool handleCheatKey(int32 keycode);
- bool handleKeypress(int32 keycode);
- void leaveScene();
-public:
- MadsInterfaceView(MadsM4Engine *vm);
- ~MadsInterfaceView();
-
- virtual void initialize();
- virtual void setSelectedObject(int objectNumber);
- virtual void addObjectToInventory(int objectNumber);
- int getSelectedObject() { return _selectedObject; }
- int getInventoryObject(int objectIndex) { return _inventoryList[objectIndex]; }
-
- void onRefresh(RectList *rects, M4Surface *destSurface);
- bool onEvent(M4EventType eventType, int32 param1, int x, int y, bool &captureEvents);
-};
-
-extern int getActiveAnimationBool();
-extern int getAnimationCurrentFrame();
-
-} // End of namespace M4
-
-#endif
diff --git a/engines/m4/mads_views.cpp b/engines/m4/mads_views.cpp
deleted file mode 100644
index 0521903c95..0000000000
--- a/engines/m4/mads_views.cpp
+++ /dev/null
@@ -1,1632 +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 "m4/m4_views.h"
-#include "m4/animation.h"
-#include "m4/dialogs.h"
-#include "m4/events.h"
-#include "m4/font.h"
-#include "m4/globals.h"
-#include "m4/mads_menus.h"
-#include "m4/m4.h"
-#include "m4/staticres.h"
-
-#include "common/algorithm.h"
-#include "common/textconsole.h"
-
-namespace M4 {
-
-MadsAction::MadsAction(MadsView &owner): _owner(owner) {
- clear();
- _currentAction = kVerbNone;
- _startWalkFlag = false;
- _statusTextIndex = -1;
- _selectedAction = 0;
- _inProgress = false;
-}
-
-void MadsAction::clear() {
- _v83338 = 1;
- _actionMode = ACTMODE_NONE;
- _actionMode2 = ACTMODE2_0;
- _v86F42 = 0;
- _v86F4E = 0;
- _articleNumber = 0;
- _lookFlag = false;
- _v86F4A = 0;
- _statusText[0] = '\0';
- _selectedRow = -1;
- _hotspotId = -1;
- _v86F3A = -1;
- _v86F4C = -1;
- _action.verbId = -1;
- _action.objectNameId = -1;
- _action.indirectObjectId = -1;
- _textChanged = true;
- _walkFlag = false;
-}
-
-void MadsAction::appendVocab(int vocabId, bool capitalise) {
- char *s = _statusText + strlen(_statusText);
- const char *vocabStr = _madsVm->globals()->getVocab(vocabId);
- strcpy(s, vocabStr);
- if (capitalise)
- *s = toupper(*s);
-
- strcat(s, " ");
-}
-
-void MadsAction::set() {
- int hotspotCount = _madsVm->scene()->getSceneResources().hotspots->size();
- bool flag = false;
- strcpy(_statusText, "");
-
- _currentAction = -1;
- _action.objectNameId = -1;
- _action.indirectObjectId = -1;
-
- if (_actionMode == ACTMODE_TALK) {
- // Handle showing the conversation selection. Rex at least doesn't actually seem to use this
- if (_selectedRow >= 0) {
- const char *desc = _madsVm->_converse[_selectedRow].desc;
- if (desc)
- strcpy(_statusText, desc);
- }
- } else if (_lookFlag && (_selectedRow == 0)) {
- // Two 'look' actions in succession, so the action becomes 'Look around'
- strcpy(_statusText, lookAroundStr);
- } else {
- if ((_actionMode == ACTMODE_OBJECT) && (_selectedRow >= 0) && (_flags1 == 2) && (_flags2 == 0)) {
- // Use/to action
- int selectedObject = _madsVm->scene()->getInterface()->getSelectedObject();
- MadsObject *objEntry = _madsVm->globals()->getObject(selectedObject);
-
- _action.objectNameId = objEntry->_descId;
- _currentAction = objEntry->_vocabList[_selectedRow].vocabId;
-
- // Set up the status text stirng
- strcpy(_statusText, useStr);
- appendVocab(_action.objectNameId);
- strcpy(_statusText, toStr);
- appendVocab(_currentAction);
- } else {
- // Handling for if an action has been selected
- if (_selectedRow >= 0) {
- if (_actionMode == ACTMODE_VERB) {
- // Standard verb action
- _currentAction = verbList[_selectedRow].verb;
- } else {
- // Selected action on an inventory object
- int selectedObject = _madsVm->scene()->getInterface()->getSelectedObject();
- MadsObject *objEntry = _madsVm->globals()->getObject(selectedObject);
-
- _currentAction = objEntry->_vocabList[_selectedRow].vocabId;
- }
-
- appendVocab(_currentAction, true);
-
- if (_currentAction == kVerbLook) {
- // Add in the word 'add'
- strcat(_statusText, atStr);
- strcat(_statusText, " ");
- }
- }
-
- // Handling for if a hotspot has been selected/highlighted
- if ((_hotspotId >= 0) && (_selectedRow >= 0) && (_articleNumber > 0) && (_flags1 == 2)) {
- flag = true;
-
- strcat(_statusText, englishMADSArticleList[_articleNumber]);
- strcat(_statusText, " ");
- }
-
- if (_hotspotId >= 0) {
- if (_selectedRow < 0) {
- int verbId;
-
- if (_hotspotId < hotspotCount) {
- // Get the verb Id from the hotspot
- verbId = (*_madsVm->scene()->getSceneResources().hotspots)[_hotspotId].getVerbID();
- } else {
- // Get the verb Id from the scene object
- verbId = (*_madsVm->scene()->getSceneResources().dynamicHotspots)[_hotspotId - hotspotCount].getVerbID();
- }
-
- if (verbId > 0) {
- // Set the specified action
- _currentAction = verbId;
- appendVocab(_currentAction, true);
- } else {
- // Default to a standard 'walk to'
- _currentAction = kVerbWalkTo;
- strcat(_statusText, walkToStr);
- }
- }
-
- if ((_actionMode2 == ACTMODE2_2) || (_actionMode2 == ACTMODE2_5)) {
- // Get name from given inventory object
- int objectId = _madsVm->scene()->getInterface()->getInventoryObject(_hotspotId);
- _action.objectNameId = _madsVm->globals()->getObject(objectId)->_descId;
- } else if (_hotspotId < hotspotCount) {
- // Get name from scene hotspot
- _action.objectNameId = (*_madsVm->scene()->getSceneResources().hotspots)[_hotspotId].getVocabID();
- } else {
- // Get name from temporary scene hotspot
- _action.objectNameId = (*_madsVm->scene()->getSceneResources().dynamicHotspots)[_hotspotId].getVocabID();
- }
- appendVocab(_action.objectNameId);
- }
- }
-
- if ((_hotspotId >= 0) && (_articleNumber > 0) && !flag) {
- if (_articleNumber == -1) {
- if (_v86F3A >= 0) {
- int articleNum = 0;
-
- if ((_v86F42 == 2) || (_v86F42 == 5)) {
- int objectId = _madsVm->scene()->getInterface()->getInventoryObject(_hotspotId);
- articleNum = _madsVm->globals()->getObject(objectId)->_article;
- } else if (_v86F3A < hotspotCount) {
- articleNum = (*_madsVm->scene()->getSceneResources().hotspots)[_hotspotId].getArticle();
- } else {
-
- }
- }
-
- } else if ((_articleNumber == kVerbLook) || (_vm->getGameType() != GType_RexNebular) ||
- (strcmp(_madsVm->globals()->getVocab(_action.indirectObjectId), fenceStr) != 0)) {
- // Write out the article
- strcat(_statusText, englishMADSArticleList[_articleNumber]);
- } else {
- // Special case for a 'fence' entry in Rex Nebular
- strcat(_statusText, overStr);
- }
-
- strcat(_statusText, " ");
- }
-
- // Append object description if necessary
- if (_v86F3A >= 0)
- appendVocab(_action.indirectObjectId);
-
- // Remove any trailing space character
- int statusLen = strlen(_statusText);
- if ((statusLen > 0) && (_statusText[statusLen - 1] == ' '))
- _statusText[statusLen - 1] = '\0';
- }
-
- _textChanged = true;
-}
-
-void MadsAction::refresh() {
- // Exit immediately if nothing has changed
- if (!_textChanged)
- return;
-
- // Remove any old copy of the status text
- if (_statusTextIndex >= 0) {
- _owner._textDisplay.expire(_statusTextIndex);
- _statusTextIndex = -1;
- }
-
- if (strlen(_statusText) != 0) {
- if ((_owner._screenObjects._v832EC == 0) || (_owner._screenObjects._v832EC == 2)) {
- Font *font = _madsVm->_font->getFont(FONT_MAIN_MADS);
- int textSpacing = -1;
-
- int strWidth = font->getWidth(_statusText);
- if (strWidth > 320) {
- // Too large to fit, so fall back on interface font
- font = _madsVm->_font->getFont(FONT_INTERFACE_MADS);
- strWidth = font->getWidth(_statusText, 0);
- textSpacing = 0;
- }
-
- // 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),
- MADS_SURFACE_HEIGHT + _owner._posAdjust.y - 13, colors, textSpacing, _statusText, font);
- }
- }
-
- _textChanged = false;
-}
-
-void MadsAction::startAction() {
- _madsVm->_player.moveComplete();
-
- _inProgress = true;
- _v8453A = ABORTMODE_0;
- _savedFields.selectedRow = _selectedRow;
- _savedFields.articleNumber = _articleNumber;
- _savedFields.actionMode = _actionMode;
- _savedFields.actionMode2 = _actionMode2;
- _savedFields.lookFlag = _lookFlag;
- int savedHotspotId = _hotspotId;
- int savedV86F3A = _v86F3A;
- int savedV86F42 = _v86F42;
-
- // Copy the action to be active
- _activeAction = _action;
- strcpy(_dialogTitle, _statusText);
-
- if ((_savedFields.actionMode2 == ACTMODE2_4) && (savedV86F42 == 0))
- _v8453A = ABORTMODE_1;
-
- _startWalkFlag = false;
- int hotspotId = -1;
- HotSpotList &dynHotspots = *_madsVm->scene()->getSceneResources().dynamicHotspots;
- HotSpotList &hotspots = *_madsVm->scene()->getSceneResources().hotspots;
-
- if (!_savedFields.lookFlag && (_madsVm->scene()->_screenObjects._v832EC != 1)) {
- if (_savedFields.actionMode2 == ACTMODE2_4)
- hotspotId = savedHotspotId;
- else if (savedV86F42 == 4)
- hotspotId = savedV86F3A;
-
- if (hotspotId >= hotspots.size()) {
- HotSpot &hs = dynHotspots[hotspotId - hotspots.size()];
- if ((hs.getFeetX() == -1) || (hs.getFeetX() == -3)) {
- if (_v86F4A && ((hs.getFeetX() == -3) || (_savedFields.selectedRow < 0))) {
- _startWalkFlag = true;
- _madsVm->scene()->_destPos = _madsVm->scene()->_customDest;
- }
- } else if ((hs.getFeetX() >= 0) && ((_savedFields.actionMode == ACTMODE_NONE) || (hs.getCursor() < 2))) {
- _startWalkFlag = true;
- _madsVm->scene()->_destPos.x = hs.getFeetX();
- _madsVm->scene()->_destPos.y = hs.getFeetY();
- }
- _madsVm->scene()->_destFacing = hs.getFacing();
- hotspotId = -1;
- }
- }
-
- if (hotspotId >= 0) {
- HotSpot &hs = hotspots[hotspotId];
- if ((hs.getFeetX() == -1) || (hs.getFeetX() == -3)) {
- if (_v86F4A && ((hs.getFeetX() == -3) || (_savedFields.selectedRow < 0))) {
- _startWalkFlag = true;
- _madsVm->scene()->_destPos = _madsVm->scene()->_customDest;
- }
- } else if ((hs.getFeetX() >= 0) && ((_savedFields.actionMode == ACTMODE_NONE) || (hs.getCursor() < 2))) {
- _startWalkFlag = true;
- _madsVm->scene()->_destPos.x = hs.getFeetX();
- _madsVm->scene()->_destPos.y = hs.getFeetY();
- }
- _madsVm->scene()->_destFacing = hs.getFacing();
- }
-
- _walkFlag = _startWalkFlag;
-}
-
-void MadsAction::checkAction() {
- if (isAction(kVerbLookAt) || isAction(kVerbThrow))
- _startWalkFlag = 0;
-}
-
-bool MadsAction::isAction(int verbId, int objectNameId, int indirectObjectId) {
- if (_activeAction.verbId != verbId)
- return false;
- if ((objectNameId != 0) && (_activeAction.objectNameId != objectNameId))
- return false;
- if ((indirectObjectId != 0) && (_activeAction.indirectObjectId != indirectObjectId))
- return false;
- return true;
-}
-
-//--------------------------------------------------------------------------
-
-bool MadsSpriteSlot::operator==(const SpriteSlotSubset &other) const {
- return (spriteListIndex == other.spriteListIndex) && (frameNumber == other.frameNumber) &&
- (xp == other.xp) && (yp == other.yp) && (depth == other.depth) && (scale == other.scale);
-}
-
-void MadsSpriteSlot::copy(const SpriteSlotSubset &other) {
- spriteListIndex = other.spriteListIndex;
- frameNumber = other.frameNumber;
- xp = other.xp;
- yp = other.yp;
- depth = other.depth;
- scale = other.scale;
-}
-
-//--------------------------------------------------------------------------
-
-MadsSpriteSlots::MadsSpriteSlots(MadsView &owner): _owner(owner) {
- for (int i = 0; i < SPRITE_SLOTS_SIZE; ++i) {
- MadsSpriteSlot rec;
- _entries.push_back(rec);
- }
-
- startIndex = 0;
-}
-
-MadsSpriteSlots::~MadsSpriteSlots() {
- for (uint i = 0; i < _sprites.size(); ++i)
- delete _sprites[i];
-}
-
-void MadsSpriteSlots::clear() {
- _owner._textDisplay.clear();
- for (uint i = 0; i < _sprites.size(); ++i)
- delete _sprites[i];
- _sprites.clear();
-
- // Reset the sprite slots list back to a single entry for a full screen refresh
- startIndex = 1;
- _entries[0].spriteType = FULL_SCREEN_REFRESH;
- _entries[0].seqIndex = -1;
-}
-
-int MadsSpriteSlots::getIndex() {
- if (startIndex == SPRITE_SLOTS_SIZE)
- error("Run out of sprite slots");
-
- return startIndex++;
-}
-
-int MadsSpriteSlots::addSprites(const char *resName, bool suppressErrors, int flags) {
- // If errors are suppressed, first check if the resource exists
- if (suppressErrors) {
- if (!_vm->res()->resourceExists(resName))
- return -1;
- }
-
- // Append on a '.SS' suffix if the resource doesn't already have an extension
- char buffer[100];
- strncpy(buffer, resName, 95);
- buffer[95] = '\0';
- if (!strchr(buffer, '.'))
- strcat(buffer, ".SS");
-
- // Get the sprite set
- Common::SeekableReadStream *data = _vm->res()->get(buffer);
- SpriteAsset *spriteSet = new SpriteAsset(_vm, data, data->size(), buffer, false, flags);
- spriteSet->translate(_madsVm->_palette);
- assert(spriteSet != NULL);
-
- _sprites.push_back(spriteSet);
- _vm->res()->toss(buffer);
-
- return _sprites.size() - 1;
-}
-
-int MadsSpriteSlots::addSprites(SpriteAsset *spriteSet) {
- _sprites.push_back(spriteSet);
-
- return _sprites.size() - 1;
-}
-
-void MadsSpriteSlots::deleteSprites(int listIndex) {
- if (listIndex < 0)
- return;
-
- delete _sprites[listIndex];
- _sprites[listIndex] = NULL;
- if (listIndex == ((int)_sprites.size() - 1))
- _sprites.remove_at(listIndex);
-}
-
-/*
- * Deletes the sprite slot with the given timer entry
- */
-void MadsSpriteSlots::deleteTimer(int seqIndex) {
- for (int idx = 0; idx < startIndex; ++idx) {
- if (_entries[idx].seqIndex == seqIndex)
- _entries[idx].spriteType = EXPIRED_SPRITE;
- }
-}
-
-class DepthEntry {
-public:
- int depth;
- int index;
-
- DepthEntry(int depthAmt, int indexVal) { depth = depthAmt; index = indexVal; }
-};
-
-bool sortHelper(const DepthEntry &entry1, const DepthEntry &entry2) {
- return entry1.depth < entry2.depth;
-}
-
-typedef Common::List<DepthEntry> DepthList;
-
-void MadsSpriteSlots::drawBackground() {
- // Draw all active sprites onto the background surface
- for (int i = 0; i < startIndex; ++i) {
- MadsSpriteSlot &slot = _entries[i];
-
- if (slot.spriteType >= 0) {
- _owner._dirtyAreas[i].active = false;
- } else {
- _owner._dirtyAreas[i].textActive = true;
- _owner._dirtyAreas.setSpriteSlot(i, slot);
-
- if (slot.spriteType == BACKGROUND_SPRITE) {
- SpriteAsset &spriteSet = getSprite(slot.spriteListIndex);
- M4Sprite *frame = spriteSet.getFrame((slot.frameNumber & 0x7fff) - 1);
- int xp = slot.xp;
- int yp = slot.yp;
-
- if (_entries[i].scale != -1) {
- // Adjust position based on frame size
- xp -= frame->width() / 2;
- yp -= frame->height() / 2;
- }
-
- if (slot.depth > 1) {
- // Draw the frame with depth processing
- _owner._bgSurface->copyFrom(frame, xp, yp, slot.depth, _owner._depthSurface, 100,
- frame->getTransparencyIndex());
- } else {
- // No depth, so simply draw the image
- frame->copyTo(_owner._bgSurface, xp, yp, frame->getTransparencyIndex());
- }
- }
- }
- }
-
- // Flag any remaining dirty areas as inactive
- for (uint i = startIndex; i < DIRTY_AREAS_TEXT_DISPLAY_IDX; ++i)
- _owner._dirtyAreas[i].active = false;
-}
-
-void MadsSpriteSlots::drawForeground(M4Surface *viewport) {
- DepthList depthList;
-
- // Get a list of sprite object depths for active objects
- for (int i = 0; i < startIndex; ++i) {
- if (_entries[i].spriteType >= SPRITE_ZERO) {
- DepthEntry rec(16 - _entries[i].depth, i);
- depthList.push_back(rec);
- }
- }
-
- // Sort the list in order of the depth
- Common::sort(depthList.begin(), depthList.end(), sortHelper);
-
- // Loop through each of the objects
- DepthList::iterator i;
- for (i = depthList.begin(); i != depthList.end(); ++i) {
- DepthEntry &de = *i;
- MadsSpriteSlot &slot = _entries[de.index];
- assert(slot.spriteListIndex < (int)_sprites.size());
- SpriteAsset &spriteSet = *_sprites[slot.spriteListIndex];
-
- // Get the sprite frame
- int frameNumber = slot.frameNumber & 0x7fff;
- bool flipped = (slot.frameNumber & 0x8000) != 0;
- M4Sprite *sprite = spriteSet.getFrame(frameNumber - 1);
-
- M4Surface *spr = sprite;
- if (flipped) {
- // Create a flipped copy of the sprite temporarily
- spr = sprite->flipHorizontal();
- }
-
- if ((slot.scale < 100) && (slot.scale != -1)) {
- // Minimalised drawing
- viewport->copyFrom(spr, slot.xp, slot.yp, slot.depth, _owner._depthSurface, slot.scale,
- sprite->getTransparencyIndex());
- } else {
- int xp, yp;
-
- if (slot.scale == -1) {
- xp = slot.xp - _owner._posAdjust.x;
- yp = slot.yp - _owner._posAdjust.y;
- } else {
- xp = slot.xp - (spr->width() / 2) - _owner._posAdjust.x;
- yp = slot.yp - spr->height() - _owner._posAdjust.y + 1;
- }
-
- if (slot.depth > 1) {
- // Draw the frame with depth processing
- viewport->copyFrom(spr, xp, yp, slot.depth, _owner._depthSurface, 100, sprite->getTransparencyIndex());
- } else {
- // No depth, so simply draw the image
- spr->copyTo(viewport, xp, yp, sprite->getTransparencyIndex());
- }
- }
-
- // Free sprite if it was a flipped one
- if (flipped)
- delete spr;
- }
-}
-
-void MadsSpriteSlots::setDirtyAreas() {
- for (int i = 0; i < startIndex; ++i) {
- if (_entries[i].spriteType >= 0) {
- _owner._dirtyAreas.setSpriteSlot(i, _entries[i]);
-
- _owner._dirtyAreas[i].textActive = (_entries[i].spriteType <= 0) ? 0 : 1;
- _entries[i].spriteType = 0;
- }
- }
-}
-
-/**
- * Flags the entire screen to be redrawn during the next drawing cycle
- */
-void MadsSpriteSlots::fullRefresh() {
- int idx = getIndex();
-
- _entries[idx].spriteType = FULL_SCREEN_REFRESH;
- _entries[idx].seqIndex = -1;
-}
-
-/**
- * Removes any sprite slots that are no longer needed
- */
-void MadsSpriteSlots::cleanUp() {
- // Delete any entries that aren't needed
- int idx = 0;
- while (idx < startIndex) {
- if (_entries[idx].spriteType < 0) {
- _entries.remove_at(idx);
- --startIndex;
- } else {
- ++idx;
- }
- }
-
- // Original engine sprite slot list was a fixed array, so to keep the engine similiar, for
- // now I'm adding in new entries to make up the original fixed total again
- while (_entries.size() < SPRITE_SLOTS_SIZE) {
- MadsSpriteSlot rec;
- _entries.push_back(rec);
- }
-}
-
-//--------------------------------------------------------------------------
-
-MadsTextDisplay::MadsTextDisplay(MadsView &owner): _owner(owner) {
- for (int i = 0; i < TEXT_DISPLAY_SIZE; ++i) {
- MadsTextDisplayEntry rec;
- rec.active = false;
- rec.expire = 0;
- _entries.push_back(rec);
- }
-}
-
-void MadsTextDisplay::clear() {
- for (int i = 0; i < TEXT_DISPLAY_SIZE; ++i)
- _entries[i].active = false;
-}
-
-int MadsTextDisplay::add(int xp, int yp, uint fontColor, int charSpacing, const char *msg, Font *font) {
- int usedSlot = -1;
-
- for (int idx = 0; idx < TEXT_DISPLAY_SIZE; ++idx) {
- if (!_entries[idx].active) {
- usedSlot = idx;
-
- _entries[idx].bounds.left = xp;
- _entries[idx].bounds.top = yp;
- _entries[idx].font = font;
- _entries[idx].msg = msg;
- _entries[idx].bounds.setWidth(font->getWidth(msg, charSpacing));
- _entries[idx].bounds.setHeight(font->getHeight());
- _entries[idx].color1 = fontColor & 0xff;
- _entries[idx].color2 = fontColor >> 8;
- _entries[idx].spacing = charSpacing;
- _entries[idx].expire = 1;
- _entries[idx].active = true;
- break;
- }
- }
-
- return usedSlot;
-}
-
-void MadsTextDisplay::setDirtyAreas() {
- // Determine dirty areas for active text areas
- for (uint idx = 0, dirtyIdx = DIRTY_AREAS_TEXT_DISPLAY_IDX; dirtyIdx < DIRTY_AREAS_SIZE; ++idx, ++dirtyIdx) {
- if ((_entries[idx].expire >= 0) || !_entries[idx].active)
- _owner._dirtyAreas[dirtyIdx].active = false;
- else {
- _owner._dirtyAreas[dirtyIdx].textActive = true;
- _owner._dirtyAreas.setTextDisplay(dirtyIdx, _entries[idx]);
- }
- }
-}
-
-void MadsTextDisplay::setDirtyAreas2() {
- // Determine dirty areas for active text areas
- for (uint idx = 0, dirtyIdx = DIRTY_AREAS_TEXT_DISPLAY_IDX; dirtyIdx < DIRTY_AREAS_SIZE; ++idx, ++dirtyIdx) {
- if (_entries[idx].active && (_entries[idx].expire >= 0)) {
- _owner._dirtyAreas.setTextDisplay(dirtyIdx, _entries[idx]);
- _owner._dirtyAreas[dirtyIdx].textActive = (_entries[idx].expire <= 0) ? 0 : 1;
- }
- }
-}
-
-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].bounds.left, _entries[idx].bounds.top, _entries[idx].bounds.width(),
- _entries[idx].spacing);
- }
- }
-}
-
-/**
- * Deactivates any text display entries that are finished
- */
-void MadsTextDisplay::cleanUp() {
- for (uint idx = 0; idx < _entries.size(); ++idx) {
- if (_entries[idx].expire < 0) {
- _entries[idx].active = false;
- _entries[idx].expire = 0;
- }
- }
-}
-
-//--------------------------------------------------------------------------
-
-MadsKernelMessageList::MadsKernelMessageList(MadsView &owner): _owner(owner) {
- for (int i = 0; i < TIMED_TEXT_SIZE; ++i) {
- MadsKernelMessageEntry rec;
- _entries.push_back(rec);
- }
-
- _owner._textSpacing = -1;
- _talkFont = _vm->_font->getFont(FONT_CONVERSATION_MADS);
- word_8469E = 0;
-}
-
-void MadsKernelMessageList::clear() {
- for (uint i = 0; i < _entries.size(); ++i)
- _entries[i].flags = 0;
-
- _owner._textSpacing = -1;
- _talkFont = _vm->_font->getFont(FONT_CONVERSATION_MADS);
-}
-
-int MadsKernelMessageList::add(const Common::Point &pt, uint fontColor, uint8 flags, uint8 abortTimers, uint32 timeout, const char *msg) {
- // Find a free slot
- uint idx = 0;
- while ((idx < _entries.size()) && ((_entries[idx].flags & KMSG_ACTIVE) != 0))
- ++idx;
- if (idx == _entries.size()) {
- if (abortTimers == 0)
- return -1;
-
- error("MadsKernelList overflow");
- }
-
- MadsKernelMessageEntry &rec = _entries[idx];
- strcpy(rec.msg, msg);
- rec.flags = flags | KMSG_ACTIVE;
- rec.color1 = fontColor & 0xff;
- rec.color2 = fontColor >> 8;
- rec.position = pt;
- rec.textDisplayIndex = -1;
- rec.timeout = timeout;
- 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];
-
- if (flags & KMSG_PLAYER_TIMEOUT)
- rec.frameTimer = _madsVm->_player._ticksAmount + _madsVm->_player._priorTimer;
-
- return idx;
-}
-
-int MadsKernelMessageList::addQuote(int quoteId, int abortTimers, uint32 timeout) {
- const char *quoteStr = _madsVm->globals()->getQuote(quoteId);
- return add(Common::Point(0, 0), 0x1110, KMSG_PLAYER_TIMEOUT | KMSG_CENTER_ALIGN, abortTimers, timeout, quoteStr);
-}
-
-void MadsKernelMessageList::scrollMessage(int msgIndex, int numTicks, bool quoted) {
- if (msgIndex < 0)
- return;
-
- _entries[msgIndex].flags |= quoted ? (KMSG_SCROLL | KMSG_QUOTED) : KMSG_SCROLL;
- _entries[msgIndex].msgOffset = 0;
- _entries[msgIndex].numTicks = numTicks;
- _entries[msgIndex].frameTimer2 = _madsVm->_currentTimer;
-
- const char *msgP = _entries[msgIndex].msg;
- _entries[msgIndex].asciiChar = *msgP;
- _entries[msgIndex].asciiChar2 = *(msgP + 1);
-
- if (_entries[msgIndex].flags & KMSG_PLAYER_TIMEOUT)
- _entries[msgIndex].frameTimer2 = _madsVm->_player._ticksAmount + _madsVm->_player._priorTimer;
-
- _entries[msgIndex].frameTimer = _entries[msgIndex].frameTimer2;
-}
-
-void MadsKernelMessageList::setSeqIndex(int msgIndex, int seqIndex) {
- if (msgIndex >= 0) {
- _entries[msgIndex].flags |= KMSG_SEQ_ENTRY;
- _entries[msgIndex].sequenceIndex = seqIndex;
- }
-}
-
-void MadsKernelMessageList::remove(int msgIndex) {
- MadsKernelMessageEntry &rec = _entries[msgIndex];
-
- if (rec.flags & KMSG_ACTIVE) {
- if (rec.flags & KMSG_SCROLL) {
- *(rec.msg + rec.msgOffset) = rec.asciiChar;
- *(rec.msg + rec.msgOffset + 1) = rec.asciiChar2;
- }
-
- if (rec.textDisplayIndex >= 0)
- _owner._textDisplay.expire(rec.textDisplayIndex);
-
- rec.flags &= ~KMSG_ACTIVE;
- }
-}
-
-void MadsKernelMessageList::reset() {
- for (uint i = 0; i < _entries.size(); ++i)
- remove(i);
-
- // sub_20454
-}
-
-void MadsKernelMessageList::update() {
- uint32 currentTimer = _madsVm->_currentTimer;
-
- for (uint i = 0; i < _entries.size(); ++i) {
- if (((_entries[i].flags & KMSG_ACTIVE) != 0) && (currentTimer >= _entries[i].frameTimer))
- processText(i);
- }
-}
-
-void MadsKernelMessageList::processText(int msgIndex) {
- MadsKernelMessageEntry &msg = _entries[msgIndex];
- uint32 currentTimer = _madsVm->_currentTimer;
- bool flag = false;
-
- if ((msg.flags & KMSG_EXPIRE) != 0) {
- _owner._textDisplay.expire(msg.textDisplayIndex);
- msg.flags &= !KMSG_ACTIVE;
- return;
- }
-
- if ((msg.flags & KMSG_SCROLL) == 0) {
- msg.timeout -= 3;
- }
-
- if (msg.flags & KMSG_SEQ_ENTRY) {
- MadsSequenceEntry &seqEntry = _owner._sequenceList[msg.sequenceIndex];
- if (seqEntry.doneFlag || !seqEntry.active)
- msg.timeout = 0;
- }
-
- if ((msg.timeout <= 0) && (_owner._abortTimers == 0)) {
- msg.flags |= KMSG_EXPIRE;
- if (msg.abortTimers != 0) {
- _owner._abortTimers = msg.abortTimers;
- _owner._abortTimersMode = msg.abortMode;
-
- if (_owner._abortTimersMode != ABORTMODE_1) {
- for (int i = 0; i < 3; ++i)
- _madsVm->globals()->actionNouns[i] = msg.actionNouns[i];
- }
- }
- }
-
- msg.frameTimer = currentTimer + 3;
- int x1 = 0, y1 = 0;
-
- if (msg.flags & KMSG_SEQ_ENTRY) {
- MadsSequenceEntry &seqEntry = _owner._sequenceList[msg.sequenceIndex];
- if (!seqEntry.nonFixed) {
- SpriteAsset &spriteSet = _owner._spriteSlots.getSprite(seqEntry.spriteListIndex);
- M4Sprite *frame = spriteSet.getFrame(seqEntry.frameIndex - 1);
- x1 = frame->bounds().left;
- y1 = frame->bounds().top;
- } else {
- x1 = seqEntry.msgPos.x;
- y1 = seqEntry.msgPos.y;
- }
- }
-
- if (msg.flags & KMSG_PLAYER_TIMEOUT) {
- if (word_8469E != 0) {
- // TODO: Figure out various flags
- } else {
- x1 = 160;
- y1 = 78;
- }
- }
-
- x1 += msg.position.x;
- y1 += msg.position.y;
-
- if ((msg.flags & KMSG_SCROLL) && (msg.frameTimer >= currentTimer)) {
- msg.msg[msg.msgOffset] = msg.asciiChar;
- char *msgP = &msg.msg[++msg.msgOffset];
- *msgP = msg.asciiChar2;
-
- msg.asciiChar = *msgP;
- msg.asciiChar2 = *(msgP + 1);
-
- if (!msg.asciiChar) {
- // End of message
- *msgP = '\0';
- msg.flags &= ~KMSG_SCROLL;
- } else if (msg.flags & KMSG_QUOTED) {
- *msgP = '"';
- *(msgP + 1) = '\0';
- }
-
- msg.frameTimer = msg.frameTimer2 = currentTimer + msg.numTicks;
- flag = true;
- }
-
- 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;
- }
-
- // Make sure text appears entirely on-screen
- int x2 = x1 + strWidth;
- if (x2 > MADS_SURFACE_WIDTH)
- x1 -= x2 - MADS_SURFACE_WIDTH;
- if (x1 > (MADS_SURFACE_WIDTH - 1))
- x1 = MADS_SURFACE_WIDTH - 1;
- if (x1 < 0)
- x1 = 0;
-
- if (y1 > (MADS_SURFACE_HEIGHT - 1))
- y1 = MADS_SURFACE_HEIGHT - 1;
- if (y1 < 0)
- y1 = 0;
-
- if (msg.textDisplayIndex >= 0) {
- MadsTextDisplayEntry textEntry = _owner._textDisplay[msg.textDisplayIndex];
-
- if (flag || (textEntry.bounds.left != x1) || (textEntry.bounds.top != y1)) {
- // Mark the associated text entry as deleted, so it can be re-created
- _owner._textDisplay.expire(msg.textDisplayIndex);
- msg.textDisplayIndex = -1;
- }
- }
-
- if (msg.textDisplayIndex < 0) {
- // Need to create a new text display entry for this message
- int idx = _owner._textDisplay.add(x1, y1, msg.color1 | (msg.color2 << 8), _owner._textSpacing, msg.msg, _talkFont);
- if (idx >= 0)
- msg.textDisplayIndex = idx;
- }
-}
-
-//--------------------------------------------------------------------------
-
-ScreenObjects::ScreenObjects(MadsView &owner): _owner(owner) {
- _v832EC = 0;
- _v7FECA = 0;
- _v7FED6 = 0;
- _v8332A = 0;
- _yp = 0;
- _v8333C = 0;
- _selectedObject = 0;
- _category = 0;
- _objectIndex = 0;
-}
-
-/**
- * Clears the entries list
- */
-void ScreenObjects::clear() {
- _entries.clear();
-}
-
-/**
- * Adds a new entry to the list of screen objects
- */
-void ScreenObjects::add(const Common::Rect &bounds, int layer, int idx, int category) {
- ScreenObjectEntry rec;
- rec.bounds = bounds;
- rec.layer = layer;
- rec.index = idx;
- rec.category = category;
- rec.active = true;
-
- _entries.push_back(rec);
-}
-
-/**
- * Scans the list for an element that contains the given mode. The result will be 1 based for a match,
- * with 0 indicating no entry was found
- */
-int ScreenObjects::scan(int xp, int yp, int layer) {
- for (uint i = 0; i < _entries.size(); ++i) {
- if (_entries[i].active && _entries[i].bounds.contains(xp, yp) && (_entries[i].layer == layer))
- return i + 1;
- }
-
- // Entry not found
- return 0;
-}
-
-int ScreenObjects::scanBackwards(int xp, int yp, int layer) {
- for (int i = (int)_entries.size() - 1; i >= 0; --i) {
- if (_entries[i].active && _entries[i].bounds.contains(xp, yp) && (_entries[i].layer == layer))
- return i + 1;
- }
-
- // Entry not found
- return 0;
-}
-
-void ScreenObjects::setActive(int category, int idx, bool active) {
- for (uint i = 0; i < _entries.size(); ++i) {
- if (_entries[i].active && (_entries[i].category == category) && (_entries[i].index == idx))
- _entries[i].active = active;
- }
-}
-
-void ScreenObjects::check(bool scanFlag, bool mouseClick) {
- if (!mouseClick || _v832EC)
- _v7FECA = 0;
-
- if (!_v7FED6 && !_v8332A && !_yp && (_v8333C != 0)) {
- if (scanFlag) {
- _category = CAT_NONE;
- _selectedObject = scanBackwards(_madsVm->_mouse->currentPos().x, _madsVm->_mouse->currentPos().y,
- LAYER_GUI);
-
- if (_selectedObject > 0) {
- ScreenObjectEntry &obj = _entries[_selectedObject];
- _category = obj.category & 7;
- _objectIndex = obj.index;
- }
-
- // TODO: Other stuff related to the user interface
- }
- }
-
- _owner._action.refresh();
-}
-
-/*--------------------------------------------------------------------------*/
-
-MadsDynamicHotspots::MadsDynamicHotspots(MadsView &owner): _owner(owner) {
- for (int i = 0; i < DYNAMIC_HOTSPOTS_SIZE; ++i) {
- DynamicHotspot rec;
- rec.active = false;
- _entries.push_back(rec);
- }
- _changed = true;
- _count = 0;
-}
-
-int MadsDynamicHotspots::add(int descId, int field14, int seqIndex, const Common::Rect &bounds) {
- // Find a free slot
- uint idx = 0;
- while ((idx < _entries.size()) && _entries[idx].active)
- ++idx;
- if (idx == _entries.size())
- error("MadsDynamicHotspots overflow");
-
- _entries[idx].active = true;
- _entries[idx].descId = descId;
- _entries[idx].seqIndex = seqIndex;
- _entries[idx].bounds = bounds;
- _entries[idx].pos.x = -3;
- _entries[idx].pos.y = 0;
- _entries[idx].facing = 5;
- _entries[idx].field_14 = field14;
- _entries[idx].articleNumber = 6;
- _entries[idx].field_17 = 0;
-
- ++_count;
- _changed = true;
-
- if (seqIndex >= 0)
- _owner._sequenceList[seqIndex].dynamicHotspotIndex = idx;
-
- return idx;
-}
-
-int MadsDynamicHotspots::setPosition(int index, int xp, int yp, int facing) {
- if (index >= 0) {
- _entries[index].pos.x = xp;
- _entries[index].pos.y = yp;
- _entries[index].facing = facing;
- }
-
- return index;
-}
-
-int MadsDynamicHotspots::set17(int index, int v) {
- if (index >= 0)
- _entries[index].field_17 = v;
-
- return index;
-}
-
-void MadsDynamicHotspots::remove(int index) {
- if (_entries[index].active) {
- if (_entries[index].seqIndex >= 0)
- _owner._sequenceList[_entries[index].seqIndex].dynamicHotspotIndex = -1;
- _entries[index].active = false;
-
- --_count;
- _changed = true;
- }
-}
-
-void MadsDynamicHotspots::reset() {
- for (uint i = 0; i < _entries.size(); ++i)
- _entries[i].active = false;
-
- _count = 0;
- _changed = false;
-}
-
-/*--------------------------------------------------------------------------*/
-
-void MadsDirtyArea::setArea(int width, int height, int maxWidth, int maxHeight) {
- if (bounds.left % 2) {
- --bounds.left;
- ++width;
- }
-
- if (bounds.left < 0)
- bounds.left = 0;
- else if (bounds.left > maxWidth)
- bounds.left = maxWidth;
- int right = bounds.left + width;
- if (right < 0)
- right = 0;
- if (right > maxWidth)
- right = maxWidth;
-
- bounds.right = right;
- bounds2.left = bounds.width() / 2;
- bounds2.right = bounds.left + (bounds.width() + 1) / 2 - 1;
-
- if (bounds.top < 0)
- bounds.top = 0;
- else if (bounds.top > maxHeight)
- bounds.top = maxHeight;
- int bottom = bounds.top + height;
- if (bottom < 0)
- bottom = 0;
- if (bottom > maxHeight)
- bottom = maxHeight;
-
- bounds.bottom = bottom;
- bounds2.top = bounds.height() / 2;
- bounds2.bottom = bounds.top + (bounds.height() + 1) / 2 - 1;
-
- active = true;
-}
-
-/*--------------------------------------------------------------------------*/
-
-MadsDirtyAreas::MadsDirtyAreas(MadsView &owner): _owner(owner) {
- for (int i = 0; i < DIRTY_AREAS_SIZE; ++i) {
- MadsDirtyArea rec;
- rec.active = false;
- _entries.push_back(rec);
- }
-}
-
-void MadsDirtyAreas::setSpriteSlot(int dirtyIdx, const MadsSpriteSlot &spriteSlot) {
- int width, height;
- MadsDirtyArea &dirtyArea = _entries[dirtyIdx];
-
- if (spriteSlot.spriteType == FULL_SCREEN_REFRESH) {
- // Special entry to refresh the entire screen
- dirtyArea.bounds.left = 0;
- dirtyArea.bounds.top = 0;
- width = MADS_SURFACE_WIDTH;
- height = MADS_SURFACE_HEIGHT;
- } else {
- // Standard sprite slots
- dirtyArea.bounds.left = spriteSlot.xp - _owner._posAdjust.x;
- dirtyArea.bounds.top = spriteSlot.yp - _owner._posAdjust.y;
-
- 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();
- } else {
- width = frame->width() * spriteSlot.scale / 100;
- height = frame->height() * spriteSlot.scale / 100;
-
- dirtyArea.bounds.left -= width / 2;
- dirtyArea.bounds.top += -(height - 1);
- }
- }
-
- dirtyArea.setArea(width, height, MADS_SURFACE_WIDTH, MADS_SURFACE_HEIGHT);
-}
-
-void MadsDirtyAreas::setTextDisplay(int dirtyIdx, const MadsTextDisplayEntry &textDisplay) {
- MadsDirtyArea &dirtyArea = _entries[dirtyIdx];
- dirtyArea.bounds.left = textDisplay.bounds.left;
- dirtyArea.bounds.top = textDisplay.bounds.top;
-
- dirtyArea.setArea(textDisplay.bounds.width(), textDisplay.bounds.height(), MADS_SURFACE_WIDTH, MADS_SURFACE_HEIGHT);
-}
-
-/**
- * Merge together any designated dirty areas that overlap
- * @param startIndex 1-based starting dirty area starting index
- * @param count Number of entries to process
- */
-void MadsDirtyAreas::merge(int startIndex, int count) {
-return;//***DEBUG***
- if (startIndex >= count)
- return;
-
- for (int outerCtr = startIndex - 1, idx = 0; idx < count; ++outerCtr, ++idx) {
- if (!_entries[outerCtr].active)
- continue;
-
- for (int innerCtr = outerCtr + 1; innerCtr < count; ++innerCtr) {
- if (!_entries[innerCtr].active || !intersects(outerCtr, innerCtr))
- continue;
-
- if (_entries[outerCtr].textActive && _entries[innerCtr].textActive)
- mergeAreas(outerCtr, innerCtr);
- }
- }
-}
-
-/**
- * Returns true if two dirty areas intersect
- */
-bool MadsDirtyAreas::intersects(int idx1, int idx2) {
- return _entries[idx1].bounds2.intersects(_entries[idx2].bounds2);
-}
-
-void MadsDirtyAreas::mergeAreas(int idx1, int idx2) {
- MadsDirtyArea &da1 = _entries[idx1];
- MadsDirtyArea &da2 = _entries[idx2];
-
- da1.bounds.extend(da2.bounds);
-
- da1.bounds2.left = da1.bounds.width() / 2;
- da1.bounds2.right = da1.bounds.left + (da1.bounds.width() + 1) / 2 - 1;
- da1.bounds2.top = da1.bounds.height() / 2;
- da1.bounds2.bottom = da1.bounds.top + (da1.bounds.height() + 1) / 2 - 1;
-
- da2.active = false;
- da1.textActive = true;
-}
-
-void MadsDirtyAreas::copy(M4Surface *dest, M4Surface *src, const Common::Point &posAdjust) {
- for (uint i = 0; i < _entries.size(); ++i) {
- const Common::Rect &srcBounds = _entries[i].bounds;
-
- Common::Rect bounds(srcBounds.left + posAdjust.x, srcBounds.top + posAdjust.y,
- srcBounds.right + posAdjust.x, srcBounds.bottom + posAdjust.y);
-
- if (_entries[i].active && _entries[i].bounds.isValidRect())
- src->copyTo(dest, bounds, _entries[i].bounds.left, _entries[i].bounds.top);
- }
-}
-
-void MadsDirtyAreas::clear() {
- for (uint i = 0; i < _entries.size(); ++i)
- _entries[i].active = false;
-}
-
-/*--------------------------------------------------------------------------*/
-
-MadsSequenceList::MadsSequenceList(MadsView &owner): _owner(owner) {
- for (int i = 0; i < TIMER_LIST_SIZE; ++i) {
- MadsSequenceEntry rec;
- rec.active = 0;
- rec.dynamicHotspotIndex = -1;
- _entries.push_back(rec);
- }
-}
-
-void MadsSequenceList::clear() {
- for (uint i = 0; i < _entries.size(); ++i) {
- _entries[i].active = 0;
- _entries[i].dynamicHotspotIndex = -1;
- }
-}
-
-bool MadsSequenceList::addSubEntry(int index, SequenceSubEntryMode mode, int frameIndex, int abortVal) {
- if (_entries[index].entries.count >= TIMER_ENTRY_SUBSET_MAX)
- return true;
-
- int subIndex = _entries[index].entries.count++;
- _entries[index].entries.mode[subIndex] = mode;
- _entries[index].entries.frameIndex[subIndex] = frameIndex;
- _entries[index].entries.abortVal[subIndex] = abortVal;
-
- 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 frameStart) {
-
- // Find a free slot
- uint seqIndex = 0;
- while ((seqIndex < _entries.size()) && (_entries[seqIndex].active))
- ++seqIndex;
- if (seqIndex == _entries.size())
- error("TimerList full");
-
- if (frameStart <= 0)
- frameStart = 1;
- if (numSprites == 0)
- numSprites = _madsVm->scene()->_spriteSlots.getSprite(spriteListIndex).getCount();
- if (frameStart == numSprites)
- frameInc = 0;
-
- // Set the list entry fields
- _entries[seqIndex].active = true;
- _entries[seqIndex].spriteListIndex = spriteListIndex;
- _entries[seqIndex].flipped = flipped;
- _entries[seqIndex].frameIndex = frameIndex;
- _entries[seqIndex].frameStart = frameStart;
- _entries[seqIndex].numSprites = numSprites;
- _entries[seqIndex].animType = animType;
- _entries[seqIndex].frameInc = frameInc;
- _entries[seqIndex].depth = depth;
- _entries[seqIndex].scale = scale;
- _entries[seqIndex].nonFixed = nonFixed;
- _entries[seqIndex].msgPos.x = msgX;
- _entries[seqIndex].msgPos.y = msgY;
- _entries[seqIndex].numTicks = numTicks;
- _entries[seqIndex].extraTicks = extraTicks;
-
- _entries[seqIndex].timeout = _madsVm->_currentTimer + delayTicks;
-
- _entries[seqIndex].triggerCountdown = triggerCountdown;
- _entries[seqIndex].doneFlag = false;
- _entries[seqIndex].field_13 = 0;
- _entries[seqIndex].dynamicHotspotIndex = -1;
- _entries[seqIndex].entries.count = 0;
- _entries[seqIndex].abortMode = _owner._abortTimersMode2;
-
- for (int i = 0; i < 3; ++i)
- _entries[seqIndex].actionNouns[i] = _madsVm->globals()->actionNouns[i];
-
- return seqIndex;
-}
-
-void MadsSequenceList::remove(int seqIndex) {
- if (_entries[seqIndex].active) {
- if (_entries[seqIndex].dynamicHotspotIndex >= 0)
- _owner._dynamicHotspots.remove(_entries[seqIndex].dynamicHotspotIndex);
- }
-
- _entries[seqIndex].active = false;
- _owner._spriteSlots.deleteTimer(seqIndex);
-}
-
-void MadsSequenceList::setSpriteSlot(int seqIndex, MadsSpriteSlot &spriteSlot) {
- MadsSequenceEntry &timerEntry = _entries[seqIndex];
- SpriteAsset &spriteSet = _owner._spriteSlots.getSprite(timerEntry.spriteListIndex);
-
- spriteSlot.spriteType = spriteSet.isBackground() ? BACKGROUND_SPRITE : FOREGROUND_SPRITE;
- spriteSlot.seqIndex = seqIndex;
- spriteSlot.spriteListIndex = timerEntry.spriteListIndex;
- 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;
- } else {
- spriteSlot.xp = spriteSet.getFrame(timerEntry.frameIndex - 1)->x;
- spriteSlot.yp = spriteSet.getFrame(timerEntry.frameIndex - 1)->y;
- }
-}
-
-bool MadsSequenceList::loadSprites(int seqIndex) {
- MadsSequenceEntry &seqEntry = _entries[seqIndex];
- int slotIndex;
- bool result = false;
- int idx = -1;
-
- _owner._spriteSlots.deleteTimer(seqIndex);
- if (seqEntry.doneFlag) {
- remove(seqIndex);
- return false;
- }
-
- if (seqEntry.spriteListIndex == -1) {
- // Doesn't have an associated sprite anymore, so mark as done
- seqEntry.doneFlag = true;
- } else if ((slotIndex = _owner._spriteSlots.getIndex()) >= 0) {
- MadsSpriteSlot &spriteSlot = _owner._spriteSlots[slotIndex];
- setSpriteSlot(seqIndex, spriteSlot);
-
- int x2 = 0, y2 = 0;
-
- if ((seqEntry.field_13 != 0) || (seqEntry.dynamicHotspotIndex >= 0)) {
- SpriteAsset &spriteSet = _owner._spriteSlots.getSprite(seqEntry.spriteListIndex);
- M4Sprite *frame = spriteSet.getFrame(seqEntry.frameIndex - 1);
- int width = frame->width() * seqEntry.scale / 200;
- int height = frame->height() * seqEntry.scale / 100;
-
- warning("frame size %d x %d", width, height);
-
- // TODO: Missing stuff here, and I'm not certain about the dynamic hotspot stuff below
-
- if (seqEntry.dynamicHotspotIndex >= 0) {
- DynamicHotspot &dynHotspot = _owner._dynamicHotspots[seqEntry.dynamicHotspotIndex];
-
- dynHotspot.bounds.left = MAX(x2 - width, 0);
- dynHotspot.bounds.right = MAX(x2 - width, 319) - dynHotspot.bounds.left + 1;
- dynHotspot.bounds.top = MAX(y2 - height, 0);
- dynHotspot.bounds.bottom = MIN(y2, 155) - dynHotspot.bounds.top;
-
- _owner._dynamicHotspots._changed = true;
- }
- }
-
- // Frame adjustments
- if (seqEntry.frameStart != seqEntry.numSprites)
- seqEntry.frameIndex += seqEntry.frameInc;
-
- if (seqEntry.frameIndex >= seqEntry.frameStart) {
- if (seqEntry.frameIndex > seqEntry.numSprites) {
- result = true;
- if (seqEntry.animType == ANIMTYPE_CYCLED) {
- // Reset back to the starting frame (cyclic)
- seqEntry.frameIndex = seqEntry.frameStart;
- } else {
- // Switch into reverse mode
- seqEntry.frameIndex = seqEntry.numSprites - 1;
- seqEntry.frameInc = -1;
- }
- }
- } else {
- // Currently in reverse mode and moved past starting frame
- result = true;
-
- if (seqEntry.animType == ANIMTYPE_CYCLED)
- {
- // Switch back to forward direction again
- seqEntry.frameIndex = seqEntry.frameStart + 1;
- seqEntry.frameInc = 1;
- } else {
- // Otherwise reset back to last sprite for further reverse animating
- seqEntry.frameIndex = seqEntry.numSprites;
- }
- }
-
- if (result && (seqEntry.triggerCountdown != 0)) {
- if (--seqEntry.triggerCountdown == 0)
- seqEntry.doneFlag = true;
- }
- } else {
- // Out of sprite display slots, so mark entry as done
- seqEntry.doneFlag = true;
- }
-
- if (seqEntry.entries.count > 0) {
- for (int i = 0; i <= seqEntry.entries.count; ++i) {
- switch (seqEntry.entries.mode[i]) {
- case SM_0:
- case SM_1:
- if (((seqEntry.entries.mode[i] == SM_0) && seqEntry.doneFlag) ||
- ((seqEntry.entries.mode[i] == SM_1) && result))
- idx = i;
- break;
-
- case SM_FRAME_INDEX: {
- int v = seqEntry.entries.frameIndex[i];
- if ((v == seqEntry.frameIndex) || (v == 0))
- idx = i;
- }
-
- default:
- break;
- }
- }
- }
-
- if (idx >= 0) {
- _owner._abortTimers = seqEntry.entries.abortVal[idx];
- _owner._abortTimersMode = seqEntry.abortMode;
- }
-
- return result;
-}
-
-/**
- * Handles counting down entries in the timer list for action
- */
-void MadsSequenceList::tick() {
- for (uint idx = 0; idx < _entries.size(); ++idx) {
- if ((_owner._abortTimers2 == 0) && (_owner._abortTimers != 0))
- break;
-
- MadsSequenceEntry &seqEntry = _entries[idx];
- uint32 currentTimer = _madsVm->_currentTimer;
-
- if (!seqEntry.active || (currentTimer < seqEntry.timeout))
- continue;
-
- // Set the next timeout for the timer entry
- seqEntry.timeout = currentTimer + seqEntry.numTicks;
-
- // Action the sprite
- if (loadSprites(idx)) {
- seqEntry.timeout += seqEntry.extraTicks;
- }
- }
-}
-
-void MadsSequenceList::delay(uint32 v1, uint32 v2) {
- for (uint idx = 0; idx < _entries.size(); ++idx) {
- if (_entries[idx].active) {
- _entries[idx].timeout += v1 - v2;
- }
- }
-}
-
-void MadsSequenceList::setAnimRange(int seqIndex, int startVal, int endVal) {
- MadsSequenceEntry &seqEntry = _entries[seqIndex];
- SpriteAsset &spriteSet = _owner._spriteSlots.getSprite(seqEntry.spriteListIndex);
- int numSprites = spriteSet.getCount();
- int tempStart = startVal, tempEnd = endVal;
-
- switch (startVal) {
- case -2:
- tempStart = numSprites;
- break;
- case -1:
- tempStart = 1;
- break;
- }
-
- switch (endVal) {
- case -2:
- case 0:
- tempEnd = numSprites;
- break;
- case -1:
- tempEnd = 1;
- break;
- default:
- tempEnd = numSprites;
- break;
- }
-
- seqEntry.frameStart = tempStart;
- seqEntry.numSprites = tempEnd;
-
- seqEntry.frameIndex = (seqEntry.frameInc < 0) ? tempStart : tempEnd;
-}
-
-void MadsSequenceList::scan() {
- for (uint i = 0; i < _entries.size(); ++i) {
- if (!_entries[i].active && (_entries[i].spriteListIndex != -1)) {
- int idx = _owner._spriteSlots.getIndex();
- setSpriteSlot(i, _owner._spriteSlots[idx]);
- }
- }
-}
-
-/**
- * Sets the depth of the specified entry in the sequence list
- */
-void MadsSequenceList::setDepth(int seqIndex, int depth) {
- _entries[seqIndex].depth = depth;
-}
-
-//--------------------------------------------------------------------------
-
-Animation::Animation(MadsM4Engine *vm): _vm(vm) {
-}
-
-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;
- _abortTimers2 = 0;
- _abortTimersMode = ABORTMODE_0;
- _abortTimersMode2 = ABORTMODE_0;
-
- _depthSurface = NULL;
- _bgSurface = NULL;
- _viewport = NULL;
- _sceneAnimation = new MadsAnimation(_vm, this);
-}
-
-MadsView::~MadsView() {
- delete _sceneAnimation;
- delete _viewport;
-}
-
-void MadsView::refresh() {
- if (!_viewport)
- setViewport(_view->bounds());
-
- // Draw any sprites
- _dirtyAreas.clear();
- _spriteSlots.drawBackground();
-
- // Process dirty areas
- _textDisplay.setDirtyAreas();
-
- // Merge any identified dirty areas
- _dirtyAreas.merge(1, DIRTY_AREAS_SIZE);
-
- // Copy dirty areas to the main display surface
- _dirtyAreas.copy(_viewport, _bgSurface, _posAdjust);
-
- // Handle dirty areas for foreground objects
- _spriteSlots.setDirtyAreas();
- _textDisplay.setDirtyAreas2();
- _dirtyAreas.merge(1, DIRTY_AREAS_SIZE);
-
- // Draw foreground sprites
- _spriteSlots.drawForeground(_viewport);
-
- // Draw text elements onto the view
- _textDisplay.draw(_viewport);
-
- // Remove any sprite slots that are no longer needed
- _spriteSlots.cleanUp();
-
- // Deactivate any text display entries that are no longer needed
- _textDisplay.cleanUp();
-}
-
-void MadsView::update() {
- _sequenceList.tick();
- _kernelMessages.update();
-}
-
-void MadsView::clearLists() {
- _textDisplay.clear();
- _kernelMessages.clear();
- _spriteSlots.clear();
-}
-
-void MadsView::setViewport(const Common::Rect &bounds) {
- delete _viewport;
- _viewport = new M4Surface(bounds.width(), bounds.height(), _view->getBasePtr(bounds.left, bounds.top),
- _view->getPitch());
-}
-
-} // End of namespace M4
diff --git a/engines/m4/mads_views.h b/engines/m4/mads_views.h
deleted file mode 100644
index 41caaa2ded..0000000000
--- a/engines/m4/mads_views.h
+++ /dev/null
@@ -1,494 +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 M4_MADS_VIEWS_H
-#define M4_MADS_VIEWS_H
-
-#include "m4/gui.h"
-#include "m4/viewmgr.h"
-#include "common/rect.h"
-#include "common/list.h"
-#include "common/ptr.h"
-
-namespace M4 {
-
-class MadsView;
-
-enum MadsActionMode {ACTMODE_NONE = 0, ACTMODE_VERB = 1, ACTMODE_OBJECT = 3, ACTMODE_TALK = 6};
-enum MadsActionMode2 {ACTMODE2_0 = 0, ACTMODE2_2 = 2, ACTMODE2_4 = 4, ACTMODE2_5 = 5};
-enum AbortTimerMode {ABORTMODE_0 = 0, ABORTMODE_1 = 1, ABORTMODE_2 = 2};
-
-struct ActionDetails {
- int verbId;
- int objectNameId;
- int indirectObjectId;
-};
-
-struct MadsActionSavedFields {
- int articleNumber;
- int actionMode;
- int actionMode2;
- bool lookFlag;
- int selectedRow;
-};
-
-class MadsAction {
-private:
- MadsView &_owner;
- char _statusText[100];
- char _dialogTitle[100];
-
- void appendVocab(int vocabId, bool capitalise = false);
-public:
- ActionDetails _action, _activeAction;
- int _currentAction;
- int8 _flags1, _flags2;
- MadsActionMode _actionMode;
- MadsActionMode2 _actionMode2;
- int _articleNumber;
- bool _lookFlag;
- int _selectedRow;
- bool _textChanged;
- int _selectedAction;
- bool _startWalkFlag;
- int _statusTextIndex;
- int _hotspotId;
- MadsActionSavedFields _savedFields;
- bool _walkFlag;
-
- // Unknown fields
- int16 _v86F3A;
- int16 _v86F42;
- int16 _v86F4E;
- bool _v86F4A;
- int16 _v86F4C;
- int _v83338;
- bool _inProgress;
- AbortTimerMode _v8453A;
-
-public:
- MadsAction(MadsView &owner);
-
- void clear();
- void set();
- const char *statusText() const { return _statusText; }
- void refresh();
- void startAction();
- void checkAction();
- bool isAction(int verbId, int objectNameId = 0, int indirectObjectId = 0);
-};
-
-class SpriteSlotSubset {
-public:
- int spriteListIndex;
- int frameNumber;
- int xp;
- int yp;
- int depth;
- int scale;
-};
-
-class MadsSpriteSlot {
-public:
- int spriteType;
- int seqIndex;
- int spriteListIndex;
- int frameNumber;
- int xp;
- int yp;
- int depth;
- int scale;
-
- MadsSpriteSlot() { }
-
- bool operator==(const SpriteSlotSubset &other) const;
- void copy(const SpriteSlotSubset &other);
-};
-
-#define SPRITE_SLOTS_SIZE 50
-
-enum SpriteIdSpecial {
- BACKGROUND_SPRITE = -4, FULL_SCREEN_REFRESH = -2, EXPIRED_SPRITE = -1, SPRITE_ZERO = 0, FOREGROUND_SPRITE = 1
-};
-
-class MadsSpriteSlots {
-private:
- MadsView &_owner;
- Common::Array<MadsSpriteSlot> _entries;
- Common::Array<SpriteAsset *> _sprites;
-public:
- int startIndex;
-
- MadsSpriteSlots(MadsView &owner);
- ~MadsSpriteSlots();
-
- MadsSpriteSlot &operator[](int idx) {
- assert(idx < SPRITE_SLOTS_SIZE);
- return _entries[idx];
- }
- SpriteAsset &getSprite(int idx) {
- assert(idx < (int)_sprites.size());
- return *_sprites[idx];
- }
-
- int getIndex();
- int addSprites(const char *resName, bool suppressErrors = false, int flags = 0);
- int addSprites(SpriteAsset *spriteSet);
- void deleteSprites(int listIndex);
- void clear();
- void deleteTimer(int seqIndex);
-
- void drawBackground();
- void drawForeground(M4Surface *viewport);
- void setDirtyAreas();
- void fullRefresh();
- void cleanUp();
-};
-
-class MadsTextDisplayEntry {
-public:
- bool active;
- int expire;
- int spacing;
- Common::Rect bounds;
- uint8 color1;
- uint8 color2;
- Font *font;
- const char *msg;
-
- MadsTextDisplayEntry() { active = false; }
-};
-
-#define TEXT_DISPLAY_SIZE 40
-
-class MadsTextDisplay {
-private:
- MadsView &_owner;
- Common::Array<MadsTextDisplayEntry> _entries;
-public:
- MadsTextDisplay(MadsView &owner);
-
- MadsTextDisplayEntry &operator[](int idx) {
- assert(idx < TEXT_DISPLAY_SIZE);
- return _entries[idx];
- }
-
- void expire(int idx) {
- assert(idx < TEXT_DISPLAY_SIZE);
- _entries[idx].expire = -1;
- }
-
- int add(int xp, int yp, uint fontColor, int charSpacing, const char *msg, Font *font);
- void clear();
- void draw(M4Surface *view);
- void setDirtyAreas();
- void setDirtyAreas2();
- void cleanUp();
-};
-
-#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,
- KMSG_CENTER_ALIGN = 0x20, KMSG_EXPIRE = 0x40, KMSG_ACTIVE = 0x80};
-
-class MadsKernelMessageEntry {
-public:
- uint8 flags;
- int sequenceIndex;
- char asciiChar;
- char asciiChar2;
- int color1;
- int color2;
- Common::Point position;
- int textDisplayIndex;
- int msgOffset;
- int numTicks;
- uint32 frameTimer2;
- uint32 frameTimer;
- uint32 timeout;
- int abortTimers;
- AbortTimerMode abortMode;
- uint16 actionNouns[3];
- char msg[100];
-
- MadsKernelMessageEntry() {
- flags = 0;
- }
-};
-
-class MadsKernelMessageList {
-private:
- MadsView &_owner;
- Common::Array<MadsKernelMessageEntry> _entries;
- Font *_talkFont;
-public:
- int word_8469E;
-public:
- MadsKernelMessageList(MadsView &owner);
-
- void clear();
- int add(const Common::Point &pt, uint fontColor, uint8 flags, uint8 abortTimers, uint32 timeout, const char *msg);
- int addQuote(int quoteId, int abortTimers, uint32 timeout);
- void scrollMessage(int msgIndex, int numTicks, bool quoted);
- void setSeqIndex(int msgIndex, int seqIndex);
- void remove(int msgIndex);
- void reset();
- void update();
- void processText(int msgIndex);
-};
-
-class ScreenObjectEntry {
-public:
- Common::Rect bounds;
- int category;
- int index;
- int layer;
- bool active;
-
- ScreenObjectEntry() { active = false; }
-};
-
-class ScreenObjects {
-private:
- MadsView &_owner;
- Common::Array<ScreenObjectEntry> _entries;
-public:
- int _v832EC;
- int _v7FECA;
- int _v7FED6;
- int _v8332A;
- int _yp;
- int _v8333C;
- int _selectedObject;
- int _category;
- int _objectIndex;
-
- ScreenObjects(MadsView &owner);
- ScreenObjectEntry &operator[](uint idx) {
- assert(idx <= _entries.size());
- return _entries[idx - 1];
- }
-
- void clear();
- void add(const Common::Rect &bounds, int layer, int idx, int category);
- void draw(View *view);
- int scan(int xp, int yp, int layer);
- int scanBackwards(int xp, int yp, int layer);
- void setActive(int category, int idx, bool active);
- void check(bool scanFlag, bool mouseClick);
-};
-
-class DynamicHotspot {
-public:
- bool active;
- int seqIndex;
- Common::Rect bounds;
- Common::Point pos;
- int facing;
- int descId;
- int field_14;
- int articleNumber;
- int field_17;
-
- DynamicHotspot() { active = false; }
-};
-
-#define DYNAMIC_HOTSPOTS_SIZE 8
-
-class MadsDynamicHotspots {
-private:
- MadsView &_owner;
- Common::Array<DynamicHotspot> _entries;
- int _count;
-public:
- bool _changed;
-public:
- MadsDynamicHotspots(MadsView &owner);
-
- DynamicHotspot &operator[](uint idx) { return _entries[idx]; }
- int add(int descId, int field14, int seqIndex, const Common::Rect &bounds);
- int setPosition(int index, int xp, int yp, int facing);
- int set17(int index, int v);
- void remove(int index);
- void reset();
- void refresh() {
- // TODO
- }
-};
-
-class MadsDirtyArea {
-public:
- Common::Rect bounds;
- Common::Rect bounds2;
- bool textActive;
- bool active;
-
- MadsDirtyArea() { active = false; }
- void setArea(int width, int height, int maxWidth, int maxHeight);
-};
-
-#define DIRTY_AREAS_SIZE 90
-#define DIRTY_AREAS_TEXT_DISPLAY_IDX 50
-
-class MadsDirtyAreas {
-private:
- MadsView &_owner;
- Common::Array<MadsDirtyArea> _entries;
-public:
- MadsDirtyAreas(MadsView &owner);
-
- MadsDirtyArea &operator[](uint idx) {
- assert(idx < _entries.size());
- return _entries[idx];
- }
-
- void setSpriteSlot(int dirtyIdx, const MadsSpriteSlot &spriteSlot);
- void setTextDisplay(int dirtyIdx, const MadsTextDisplayEntry &textDisplay);
- void merge(int startIndex, int count);
- bool intersects(int idx1, int idx2);
- void mergeAreas(int idx1, int idx2);
- void copy(M4Surface *dest, M4Surface *src, const Common::Point &posAdjust);
- void clear();
-};
-
-enum SpriteAnimType {ANIMTYPE_CYCLED = 1, ANIMTYPE_REVERSIBLE = 2};
-
-enum SequenceSubEntryMode {SM_0 = 0, SM_1 = 1, SM_FRAME_INDEX = 2};
-
-#define TIMER_ENTRY_SUBSET_MAX 5
-
-struct MadsSequenceSubEntries {
- int count;
- SequenceSubEntryMode mode[TIMER_ENTRY_SUBSET_MAX];
- int16 frameIndex[TIMER_ENTRY_SUBSET_MAX];
- int8 abortVal[TIMER_ENTRY_SUBSET_MAX];
-};
-
-struct MadsSequenceEntry {
- int8 active;
- int8 spriteListIndex;
- bool flipped;
-
- int frameIndex;
- int frameStart;
- int numSprites;
-
- SpriteAnimType animType;
- int frameInc;
-
- int depth;
- int scale;
- int dynamicHotspotIndex;
-
- bool nonFixed;
- int field_13;
-
- Common::Point msgPos;
- int triggerCountdown;
- bool doneFlag;
- MadsSequenceSubEntries entries;
- AbortTimerMode abortMode;
-
- uint16 actionNouns[3];
- int numTicks;
- int extraTicks;
- uint32 timeout;
-};
-
-#define TIMER_LIST_SIZE 30
-
-class MadsSequenceList {
-private:
- MadsView &_owner;
- Common::Array<MadsSequenceEntry> _entries;
-public:
- MadsSequenceList(MadsView &owner);
-
- 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 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);
- void setSpriteSlot(int seqIndex, MadsSpriteSlot &spriteSlot);
- bool loadSprites(int seqIndex);
- void tick();
- void delay(uint32 v1, uint32 v2);
- void setAnimRange(int seqIndex, int startVal, int endVal);
- void scan();
- void setDepth(int seqIndex, int depth);
-};
-
-class Animation {
-protected:
- MadsM4Engine *_vm;
-public:
- Animation(MadsM4Engine *vm);
- virtual ~Animation();
- virtual void initialize(const Common::String &filename, uint16 flags, M4Surface *surface, M4Surface *depthSurface) = 0;
- virtual void load(const Common::String &filename, int v0) = 0;
- virtual void update() = 0;
- virtual void setCurrentFrame(int frameNumber) = 0;
- virtual int getCurrentFrame() = 0;
-};
-
-
-class MadsView {
-private:
- View *_view;
-public:
- Animation *_sceneAnimation;
- MadsSpriteSlots _spriteSlots;
- MadsTextDisplay _textDisplay;
- MadsKernelMessageList _kernelMessages;
- ScreenObjects _screenObjects;
- MadsDynamicHotspots _dynamicHotspots;
- MadsSequenceList _sequenceList;
- MadsDirtyAreas _dirtyAreas;
- MadsAction _action;
-
- int _textSpacing;
- uint32 _newTimeout;
- int _abortTimers;
- int8 _abortTimers2;
- AbortTimerMode _abortTimersMode;
- AbortTimerMode _abortTimersMode2;
- Common::Point _posAdjust;
-
- M4Surface *_depthSurface;
- M4Surface *_bgSurface;
- M4Surface *_viewport;
-public:
- MadsView(View *view);
- ~MadsView();
-
- void refresh();
- void update();
- void clearLists();
- void setViewport(const Common::Rect &bounds);
-};
-
-}
-
-#endif
diff --git a/engines/m4/midi.cpp b/engines/m4/midi.cpp
deleted file mode 100644
index bfe77828da..0000000000
--- a/engines/m4/midi.cpp
+++ /dev/null
@@ -1,256 +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.
- *
- */
-
-// FIXME: This is cribbed together from the SAGA music player. It needs cleanup
-// and testing.
-
-#include "m4/m4.h"
-#include "m4/midi.h"
-#include "audio/midiparser.h"
-#include "common/config-manager.h"
-#include "common/memstream.h"
-#include "common/textconsole.h"
-
-namespace M4 {
-
-MidiPlayer::MidiPlayer(MadsM4Engine *vm) : _vm(vm), _isGM(false) {
-
- MidiPlayer::createDriver();
-
- int ret = _driver->open();
- if (ret == 0) {
- _driver->setTimerCallback(this, &timerCallback);
- }
-}
-
-void MidiPlayer::send(uint32 b) {
- if ((b & 0xF0) == 0xC0 && !_isGM && !_nativeMT32) {
- b = (b & 0xFFFF00FF) | MidiDriver::_mt32ToGm[(b >> 8) & 0xFF] << 8;
- }
-
- Audio::MidiPlayer::send(b);
-}
-
-void MidiPlayer::playMusic(const char *name, int32 vol, bool loop, int32 trigger, int32 scene) {
- Common::StackLock lock(_mutex);
-
- stop();
-
- char fullname[144];
- _vm->res()->changeExtension(fullname, name, "HMP");
-
- Common::SeekableReadStream *midiFile = _vm->res()->get(fullname);
- byte *hmpData = new byte[midiFile->size()];
- uint32 smfSize;
-
- midiFile->read(hmpData, midiFile->size());
- _midiData = convertHMPtoSMF(hmpData, midiFile->size(), smfSize);
- delete[] hmpData;
- _vm->res()->toss(fullname);
- _vm->res()->purge();
-
- if (_midiData) {
- _parser = MidiParser::createParser_SMF();
- _parser->setMidiDriver(this);
- _parser->setTimerRate(_driver->getBaseTempo());
-
- _parser->loadMusic(_midiData, smfSize);
- _parser->property(MidiParser::mpAutoLoop, loop);
- }
-
- setVolume(255);
-
- _isPlaying = true;
-}
-
-// This function will convert HMP music into type 1 SMF, which our SMF parser
-// will be able to handle. It is based on Hans de Goede's HMP 2 MIDI file
-// converter, which in turn is "based on the conversion algorithms found in
-// d1x, d2x-xl and jjffe". Hans's original code is licensed under the LGPL.
-//
-// TODO: It would probably be nicer to write a MIDI parser class to deal with
-// HMP data directly. Though the multi-track nature of HMP makes that tricky.
-
-byte *MidiPlayer::convertHMPtoSMF(byte *data, uint32 inSize, uint32 &outSize) {
- Common::MemoryReadStream readS(data, inSize);
- Common::MemoryWriteStreamDynamic writeS;
-
- byte buf[8];
-
- readS.read(buf, sizeof(buf));
- if (memcmp(buf, "HMIMIDIP", 8) != 0) {
- warning("convertHMPtoSMF: Invalid HMP header");
- return NULL;
- }
-
- // Read the number of tracks. Note that all the tracks are still part
- // of the same song, just like in type 1 SMF files.
-
- readS.seek(0x30);
-
- uint32 numTracks = readS.readUint32LE();
-
- // The first track starts on offset 0x300. It's currently unknown what
- // the skipped data is for.
-
- readS.seek(0x300);
-
- // For some reason, we skip the first track entirely.
-
- byte a = readS.readByte();
- byte b = readS.readByte();
- byte c = readS.readByte();
-
- while (a != 0xFF || b != 0x2F || c != 0x00) {
- a = b;
- b = c;
- c = readS.readByte();
- }
-
- // The beginning of the MIDI header
- static const byte midiHeader1[] = { 'M', 'T', 'h', 'd', 0, 0, 0, 6, 0, 1 };
- // The last 2 bytes of the midi header and track 0
- static const byte midiHeader2[] = { 0, 0xC0, 'M', 'T', 'r', 'k', 0, 0, 0, 0x0B, 0, 0xFF, 0x51, 0x03, 0x18, 0x80, 0, 0, 0xFF, 0x2F, 0 };
-
-
- // Write the MIDI header
- writeS.write(midiHeader1, sizeof(midiHeader1));
-
- // Write the number of tracks
- writeS.writeUint16BE(numTracks);
-
- // Write the rest of the MIDI header and track 0.
- writeS.write(midiHeader2, sizeof(midiHeader2));
-
- // Read and convert all the tracks
- for (uint i = 1; i < numTracks; i++) {
- if (readS.readUint32LE() != i) {
- warning("convertHMPtoSMF: Invalid HMP track number");
- delete[] writeS.getData();
- return NULL;
- }
-
- uint32 trackLength = readS.readUint32LE() - 12;
- readS.readUint32LE(); // Unused?
-
- // Write the track header
- writeS.write("MTrk", 4);
-
- // This is where we will write the length of the track.
- uint32 trackLengthPos = writeS.pos();
- writeS.writeUint32LE(0);
-
- // In the original, this is cleared once at the beginning of
- // the function, but surely the last command does not carry
- // over to the next track?
-
- byte lastCmd = 0;
-
- // Now we can finally convert the track
- int32 endPos = readS.pos() + trackLength;
- while (readS.pos() < endPos) {
- // Convert the VLQ
- byte vlq[4];
- int j = -1;
-
- do {
- j++;
- vlq[j] = readS.readByte();
- } while (!(vlq[j] & 0x80));
-
- for (int k = 0; k <= j; k++) {
- a = vlq[j - k] & 0x7F;
- if (k != j)
- a |= 0x80;
- writeS.writeByte(a);
- }
-
- a = readS.readByte();
-
- if (a == 0xFF) {
- // META event
- b = readS.readByte();
- c = readS.readByte();
-
- writeS.writeByte(a);
- writeS.writeByte(b);
- writeS.writeByte(c);
-
- if (c > 0) {
- byte *metaBuf = new byte[c];
- readS.read(metaBuf, c);
- writeS.write(metaBuf, c);
- delete[] metaBuf;
- }
-
- if (b == 0x2F) {
- if (c != 0x00) {
- warning("convertHMPtoSMF: End of track with non-zero size");
- delete[] writeS.getData();
- return NULL;
- }
- break;
- }
- } else {
- if (a != lastCmd)
- writeS.writeByte(a);
-
- switch (a & 0xF0) {
- case 0x80:
- case 0x90:
- case 0xA0:
- case 0xB0:
- case 0xE0:
- b = readS.readByte();
- c = readS.readByte();
- writeS.writeByte(b);
- writeS.writeByte(c);
- break;
- case 0xC0:
- case 0xD0:
- b = readS.readByte();
- writeS.writeByte(b);
- break;
- default:
- warning("convertHMPtoSMF: Invalid HMP command %02X", a);
- delete[] writeS.getData();
- return NULL;
- }
-
- lastCmd = a;
- }
- }
-
- if (readS.pos() != endPos) {
- warning("convertHMPtoSMF: Invalid track length");
- delete[] writeS.getData();
- return NULL;
- }
-
- WRITE_BE_UINT32(writeS.getData() + trackLengthPos, writeS.pos() - trackLengthPos - 4);
- }
-
- outSize = writeS.size();
- return writeS.getData();
-}
-
-} // End of namespace M4
diff --git a/engines/m4/module.mk b/engines/m4/module.mk
deleted file mode 100644
index f60757ba3b..0000000000
--- a/engines/m4/module.mk
+++ /dev/null
@@ -1,49 +0,0 @@
-MODULE := engines/m4
-
-MODULE_OBJS = \
- actor.o \
- animation.o \
- assets.o \
- compression.o \
- console.o \
- converse.o \
- detection.o \
- dialogs.o \
- events.o \
- font.o \
- globals.o \
- graphics.o \
- gui.o \
- hotspot.o \
- m4.o \
- m4_menus.o \
- m4_scene.o \
- m4_views.o \
- mads_anim.o \
- mads_logic.o \
- mads_menus.o \
- mads_player.o \
- mads_scene.o \
- mads_views.o \
- midi.o \
- rails.o \
- resource.o \
- saveload.o \
- scene.o \
- script.o \
- sound.o \
- sprite.o \
- staticres.o \
- viewmgr.o \
- woodscript.o \
- ws_machine.o \
- ws_sequence.o
-
-
-# This module can be built as a plugin
-ifeq ($(ENABLE_M4), DYNAMIC_PLUGIN)
-PLUGIN := 1
-endif
-
-# Include common rules
-include $(srcdir)/rules.mk
diff --git a/engines/m4/rails.cpp b/engines/m4/rails.cpp
deleted file mode 100644
index f51d81c8f4..0000000000
--- a/engines/m4/rails.cpp
+++ /dev/null
@@ -1,358 +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.
- *
- */
-
-/*
- TODO:
- - rewrite functions (GetShortestPath etc.)
-*/
-
-#include "graphics/primitives.h"
-#include "common/list.h"
-#include "common/rect.h"
-#include "common/util.h"
-
-#include "m4/rails.h"
-#include "m4/m4.h"
-
-namespace M4 {
-
-#define TOP_EDGE 1 << 0
-#define LEFT_EDGE 1 << 1
-#define BOTTOM_EDGE 1 << 2
-#define RIGHT_EDGE 1 << 3
-
-
-Rails::Rails() {
-}
-
-
-Rails::~Rails() {
- clearRails();
-}
-
-
-void Rails::clearRails() {
- uint32 i;
- Common::List<NoWalkRect *>::iterator j;
- RailNode *tempNode;
-
- for (i = 0; i < _nodes.size(); i++) {
- tempNode = _nodes[i];
- _nodes.remove_at(i);
- delete tempNode;
- }
-
- _edges.clear();
-
- for (j = _noWalkRects.begin(); j != _noWalkRects.end(); ++j)
- delete (*j);
- _noWalkRects.clear();
-}
-
-static void checkPoint(int x, int y, int color, void *data) {
- IsWalkableData *isWalkableData = (IsWalkableData*)data;
- if (!isWalkableData->result)
- return;
- else {
- M4Surface *codes = isWalkableData->codes;
- if (x >= 0 && x < codes->width() && y >= 0 && y < codes->height()) {
- isWalkableData->result = !((*((uint8*)codes->getBasePtr(x, y))) & 0x10);
- } else {
- isWalkableData->result = false;
- }
- }
-}
-
-bool Rails::isLineWalkable(int x0, int y0, int x1, int y1) {
- IsWalkableData isWalkableData;
- isWalkableData.codes = _walkCodes;
- isWalkableData.result = true;
- Graphics::drawLine(x0, y0, x1, y1, 0, &checkPoint, &isWalkableData);
- return isWalkableData.result;
-}
-
-uint8 Rails::getDepth(const Common::Point &pt) {
- // TODO: Check based on sceneResources
- const byte *b = _walkCodes->getBasePtr(pt.x, pt.y);
- return *b & 0xf;
-}
-
-// helper function
-uint8 getEndCode(int32 x, int32 y, Common::Rect rect) {
- uint8 endCode = 0;
- endCode = (x < rect.left) ? LEFT_EDGE : endCode;
- endCode = (x > rect.right) ? RIGHT_EDGE : endCode;
- endCode = (y < rect.top) ? endCode | TOP_EDGE : endCode;
- endCode = (y > rect.bottom) ? endCode | BOTTOM_EDGE : endCode;
- return endCode;
-}
-
-bool Rails::lineCrossesRect(int32 x1, int32 y1, int32 x2, int32 y2, Common::Rect rect) {
- int32 mX, mY;
- int32 pX1 = x1, pX2 = x2, pY1 = y1, pY2 = y2;
- uint8 endCode1, endCode2, midCode;
-
- if (rect.left > rect.right || rect.top > rect.bottom)
- return false;
-
- // Cohen-Sutherland line clipping algorithm
-
- endCode1 = getEndCode(pX1, pY1, rect);
- endCode2 = getEndCode(pX2, pY2, rect);
-
- if (!endCode1 || !endCode2) // if both endcodes are zero
- return true; // point is inside the rectangle, therefore the line intersects
-
- while (true) {
- if (endCode1 & endCode2) // if both endcodes have a common bitset
- return false; // line is completely off one edge
-
- // calculate midpoint
- mX = (pX1 + pX2)>>1;
- mY = (pY1 + pY2)>>1;
-
- // avoid round-off error: make sure that the midpoint isn't the same as one of the
- // two endpoints
- if (((mX == pX1) && (mY == pY1)) || ((mX == pX2) && (mY == pY2)))
- return false;
-
- midCode = getEndCode(mX, mY, rect);
-
- if (!midCode) {
- return true;
- } else if (midCode & endCode1) {
- // the midCode and an end point form a line segment completely off one edge, so
- // remove that half of the line segment
- pX1 = mX;
- pY1 = mY;
- endCode1 = midCode;
- } else {
- pX2 = mX;
- pY2 = mY;
- endCode2 = midCode;
- }
- }
-}
-
-
-bool Rails::linePassesThroughRect(int32 x1, int32 y1, int32 x2, int32 y2) {
- if (_noWalkRects.empty())
- return false;
-
- bool intersected = false;
- Common::List<NoWalkRect *>::iterator i;
-
- for (i = _noWalkRects.begin(); i != _noWalkRects.end(); ++i) {
- intersected = lineCrossesRect(x1, y1, x2, y2, Common::Rect((*i)->x1, (*i)->y1, (*i)->x2, (*i)->y2));
- if (intersected)
- break;
- }
-
- return intersected;
-}
-
-long SqrtF16(long n) {
- uint32 r = 0, s;
- uint32 v = (uint32)n;
-
- for (int i = 15; i >= 0; --i) {
- s = r + (1L << i * 2);
- r >>= 1;
- if (s <= v) {
- v -= s;
- r |= (1L << i * 2);
- }
- }
-
- return (long)r;
-}
-
-void Rails::createEdge(int32 node1, int32 node2) {
- uint32 index;
- int32 x1, y1, x2, y2;
- bool valid;
- long deltaX, deltaY, distance;
-
- if ((node1 < 0) || (node1 >= MAXRAILNODES) || (node2 < 0) || (node2 >= MAXRAILNODES))
- return;
-
- if (node1 == node2)
- return;
-
- if (node2 < node1)
- SWAP(node1, node2); // ensure node1 < node2
-
- // Find the table entry i.e. tableWidth * node1 + node2 and then subtract
- // n(n+1)/2, since only the upper triangle of the table is stored
- index = (MAXRAILNODES-1) * node1 + node2 - 1 - (node1*(node1+1)>>1);
- if (index > _edges.size() - 1)
- _edges.resize(index + 1);
- _edges.insert_at(index, 0);
- valid = true;
-
- if (_nodes.size() <= (uint32)node1 || _nodes.size() <= (uint32)node2)
- return;
-
- x1 = _nodes[node1]->x;
- y1 = _nodes[node1]->y;
- x2 = _nodes[node2]->x;
- y2 = _nodes[node2]->y;
-
- // Make sure that the algorithm is symmetric
- if (x2 < x1) {
- SWAP(x1, x2);
- SWAP(y1, y2);
- }
-
- valid = isLineWalkable(_nodes[node1]->x, _nodes[node1]->y,
- _nodes[node2]->x, _nodes[node2]->y);
- debugCN(kDebugCore, "test code says: %d\n", valid);
-
- // Check if the line passes through a forbidden rectangle
- if (valid) {
- if (linePassesThroughRect(x1, y1, x2, y2)) {
- valid = false;
- }
- }
-
- if (valid) {
- deltaX = ABS(((long)(x2 - x1)) << 16);
- deltaY = ABS(((long)(y2 - y1)) << 16);
- if ((deltaX >= 0x800000) || (deltaY >= 0x800000)) {
- deltaX >>= 16;
- deltaY >>= 16;
- distance = (long)(SqrtF16(deltaX * deltaX + deltaY * deltaY) << 16);
- } else {
- distance = SqrtF16(FixedMul(deltaX, deltaX) + FixedMul(deltaY, deltaY)) << 8;
- }
- _edges.insert_at(index, distance >> 16);
- }
-
- debugCN(kDebugCore, "node1 = %d, node2 = %d, valid = %d\n", node1, node2, valid);
-
-}
-
-
-void Rails::restoreNodeEdges(int32 nodeID) {
- for (int32 i = 0; i < MAXRAILNODES; i++) {
- createEdge(i, nodeID);
- }
-}
-
-void Rails::restoreEdgeList() {
- int32 j;
- for (int32 i = 0; i < MAXRAILNODES; i++) {
- for (j = i + 1; j < MAXRAILNODES; j++) {
- createEdge(i, j);
- }
- }
-}
-
-int32 Rails::addRailNode(int32 x, int32 y, bool restoreEdges) {
- uint32 i = _nodes.size();
- if (i >= MAXRAILNODES)
- return -1;
-
- RailNode *newNode = new RailNode();
- newNode->nodeID = i;
- newNode->x = x;
- newNode->y = y;
- _nodes.insert_at(i, newNode);
- if (restoreEdges) {
- for (uint32 j=0; j<_nodes.size(); j++)
- createEdge(i, j);
- }
- return i;
-}
-
-bool Rails::removeRailNode(int32 nodeID, bool restoreEdges) {
- if (nodeID < 0 || nodeID >= MAXRAILNODES)
- return false;
-
- if (_nodes.empty() || _edges.empty())
- return false;
-
- RailNode *tempNode = _nodes[nodeID];
- _nodes.remove_at(nodeID);
- delete tempNode;
-
- if (restoreEdges) {
- restoreNodeEdges(nodeID);
- }
- return true;
-}
-
-int16 Rails::getEdgeLength(int32 node1, int32 node2) {
- int32 index;
- if (_edges.empty() || node1 == node2)
- return 0;
- if (node2 < node1)
- SWAP(node1, node2);
- // Find the table entry i.e. tableWidth * node1 + node2 and then subtract
- // n(n+1)/2, since only the upper triangle of the table is stored
- index = (MAXRAILNODES-1)*node1 + node2 - 1 - (node1*(node1+1)>>1);
- return _edges[index];
-}
-
-void Rails::disposePath(RailNode *pathStart) {
- RailNode *tempNode = pathStart;
- while (tempNode) {
- pathStart = pathStart->shortPath;
- delete tempNode;
- tempNode = pathStart;
- }
-}
-
-/*
-static RailNode* duplicatePath(RailNode *pathStart) {
- RailNode *newNode = NULL;
- RailNode *firstNode = NULL;
- RailNode *prevNode = NULL;
- // A valid path is assumed
- RailNode *pathNode = pathStart;
-
- while (pathNode) {
- newNode = new RailNode();
- newNode->x = pathNode->x;
- newNode->y = pathNode->y;
- newNode->shortPath = NULL;
-
- if (!firstNode)
- firstNode = newNode;
- else
- prevNode->shortPath = newNode;
-
- prevNode = newNode;
- // Get the next node
- pathNode = pathNode->shortPath;
- }
-
- return firstNode;
-}
-*/
-
-bool Rails::getShortestPath(int32 origID, int32 destID, RailNode **shortPath) {
- // TODO
- return true;
-}
-
-} // End of namespace M4
diff --git a/engines/m4/rails.h b/engines/m4/rails.h
deleted file mode 100644
index 80bb55e9de..0000000000
--- a/engines/m4/rails.h
+++ /dev/null
@@ -1,97 +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 M4_RAILS_H
-#define M4_RAILS_H
-
-#include "m4/graphics.h"
-#include "common/list.h"
-#include "common/array.h"
-#include "common/rect.h"
-
-// TODO: This needs cleaning up
-
-namespace M4 {
-
-#define MAXRAILNODES 32
-#define PATH_END 0xffff
-
-struct RailNode {
- uint8 nodeID;
- int32 x, y;
- RailNode *shortPath;
- int32 pathWeight;
-};
-
-struct NoWalkRect {
- int32 x1, y1, x2, y2;
- int32 alternateWalkToNode;
- int32 walkAroundNode1;
- int32 walkAroundNode2;
- int32 walkAroundNode3;
- int32 walkAroundNode4;
-};
-
-struct PathNode {
- PathNode *next;
- int8 nodeID;
-};
-
-struct IsWalkableData {
- M4Surface *codes;
- bool result;
-};
-
-class Rails {
-public:
- Rails();
- ~Rails();
-
- void setCodeSurface(M4Surface *surface) { _walkCodes = surface; }
- void clearRails();
- int32 addRailNode(int32 x, int32 y, bool restoreEdges);
- uint8 getDepth(const Common::Point &pt);
-
-private:
- Common::Array<RailNode *> _nodes;
- Common::Array<int16> _edges;
- Common::List<NoWalkRect *> _noWalkRects;
- M4Surface *_walkCodes;
-
- bool lineCrossesRect(int32 x1, int32 y1, int32 x2, int32 y2, Common::Rect rect);
- bool linePassesThroughRect(int32 x1, int32 y1, int32 x2, int32 y2);
- void createEdge(int32 node1, int32 node2);
- bool removeRailNode(int32 nodeID, bool restoreEdges);
- int16 getEdgeLength(int32 node1, int32 node2);
-
- void restoreNodeEdges(int32 nodeID);
- void restoreEdgeList();
- void disposePath(RailNode *pathStart);
- bool getShortestPath(int32 origID, int32 destID, RailNode **shortPath);
- bool isLineWalkable(int x0, int y0, int x1, int y1);
-};
-
-long SqrtF16(long n);
-
-} // End of namespace M4
-
-#endif
diff --git a/engines/m4/resource.cpp b/engines/m4/resource.cpp
deleted file mode 100644
index f5b2050052..0000000000
--- a/engines/m4/resource.cpp
+++ /dev/null
@@ -1,530 +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 "m4/m4.h"
-#include "m4/resource.h"
-#include "m4/events.h"
-
-#include "common/substream.h"
-#include "common/textconsole.h"
-
-namespace M4 {
-
-FileSystem::FileSystem(const char *hashFilename) {
-
- for (int i = 0; i < 10; i++) {
- _hagEntries[i].filename[0] = '\0';
- _hagEntries[i].fileIndex = 0; // Was -1
- _hagEntries[i].hagFile = 0;
- }
-
- Common::File hashFile;
- uint32 hashSize;
-
- hashFile.open(hashFilename);
-
- if (!hashFile.isOpen()) {
- debugCN(kDebugCore, "FileSystem::FileSystem: error opening hash %s\n", hashFilename);
- }
-
- hashSize = hashFile.readUint32LE();
-
- //debugCN(kDebugCore, "FileSystem::FileSystem: hashSize = %d\n", hashSize);
-
- /* load file records and add them to the hash list */
- for (uint i = 0; i < hashSize; i++) {
- HashFileEntry entry;
- hashFile.read(entry.filename, kM4MaxFilenameSize);
- str_lower(entry.filename);
- entry.hagfile = hashFile.readByte();
- hashFile.readByte();
- entry.offset = hashFile.readUint32LE();
- entry.size = hashFile.readUint32LE();
- hashFile.readUint32LE();
-
- if (entry.filename[0]) {
- /*
- debugCN(kDebugCore, " filename: %s\n", entry.filename);
- debugCN(kDebugCore, " hagfile: %d\n", entry.hagfile);
- debugCN(kDebugCore, " disks: %d\n", entry.disks);
- debugCN(kDebugCore, " offset: %08X\n", entry.offset);
- debugCN(kDebugCore, " size: %d\n", entry.size);
- debugCN(kDebugCore, " next: %08X\n", entry.next);
- */
- _fileEntries[entry.filename] = entry;
- }
-
- }
-
- /* load hagfile records and update the list */
- while (!hashFile.eos()) {
- HashHagEntry entry;
- hashFile.read(entry.filename, kM4MaxFilenameSize);
- entry.fileIndex = hashFile.readByte();
- if (hashFile.eos())
- break;
-
- changeExtension(_hagEntries[entry.fileIndex].filename, entry.filename, "HAG");
- _hagEntries[entry.fileIndex].fileIndex = entry.fileIndex;
-
- _hagEntries[entry.fileIndex].hagFile = new Common::File();
- _hagEntries[entry.fileIndex].hagFile->open(_hagEntries[entry.fileIndex].filename);
-
- if (!_hagEntries[entry.fileIndex].hagFile->isOpen()) {
- debugCN(kDebugCore, "FileSystem::FileSystem: error opening hag %s\n", _hagEntries[entry.fileIndex].filename);
- }
-
- }
-
- hashFile.close();
-
-}
-
-FileSystem::~FileSystem() {
-
- for (int i = 0; i < 10; i++) {
- if (_hagEntries[i].hagFile)
- delete _hagEntries[i].hagFile;
- }
-
-}
-
-Common::SeekableReadStream *FileSystem::loadFile(const char *resourceName, bool preloadFlag) {
- const HashFileEntry *hfe = getHashFileEntry(resourceName);
- Common::SeekableReadStream *result = NULL;
-
- if (hfe) {
- //debugCN(kDebugCore, "FileSystem::loadFile() success opening %s\n", filename);
- HashHagEntry *hagEntry = &_hagEntries[hfe->hagfile];
-
- if (preloadFlag) {
- // Creates a MemoryReadStream object that contains all of the resource in memory
- hagEntry->hagFile->seek(hfe->offset);
- result = _hagEntries[hfe->hagfile].hagFile->readStream(hfe->size);
- }
- else
- // Creates a SeekableSubReadStream, which will read the data in from disk as the
- // caller reads in data
- result = new Common::SeekableSubReadStream(hagEntry->hagFile, hfe->offset,
- hfe->offset + hfe->size);
-
- } else {
- debugCN(kDebugCore, "FileSystem::loadFile() error opening %s\n", resourceName);
- }
-
- return result;
-}
-
-const FileSystem::HashFileEntry *FileSystem::getHashFileEntry(const char *filename) {
- char resourceName[20];
- strcpy(resourceName, filename);
- str_lower(resourceName);
-
- FileHashMap::const_iterator entry = _fileEntries.find(filename);
- if (entry != _fileEntries.end())
- return &(entry->_value);
- else
- return NULL;
-}
-
-void FileSystem::changeExtension(char *destName, const char *sourceName, const char *extension) {
- if (sourceName != destName)
- strcpy(destName, sourceName);
- char *dot = strrchr(destName, '.');
- if (dot != NULL)
- *dot = 0;
-
- strcat(destName, ".");
- strcat(destName, extension);
-
- str_upper(destName);
-}
-
-//--------------------------------------------------------------------------
-
-ResourceManager::~ResourceManager() {
- ResourceIterator i;
- for (i = _resources.begin(); i != _resources.end(); ++i) {
- Resource *r = (*i).get();
- delete r->stream;
- }
-}
-
-Common::SeekableReadStream *ResourceManager::get(const char *resourceName, bool preloadFlag) {
- char lowerName[kM4MaxFilenameSize];
-
- strcpy(lowerName, resourceName);
- str_lower(lowerName);
-
- // Check whether the resource is already loaded
- ResourceIterator i;
- for (i = _resources.begin(); i != _resources.end(); ++i) {
- Resource *r = (*i).get();
- if (!strcmp(r->name, resourceName)) {
- // Just in case resource was marked to be purged, reactive it again
- r->flags &= ~kResourcePurge;
-
- // Return the existing copy of the resource
- r->stream->seek(0, SEEK_SET);
- return r->stream;
- }
- }
-
- // the resource wasn't found in the list, load it from disk
- Resource *newRes = new Resource();
- strncpy(newRes->name, resourceName, 63);
- newRes->name[63] = '\0';
- newRes->flags = 0;
- newRes->stream = loadResource(resourceName, preloadFlag);
-
- _resources.push_back(ResourceList::value_type(newRes));
- return newRes->stream;
-}
-
-void ResourceManager::toss(const char *resourceName) {
- ResourceIterator i;
- for (i = _resources.begin(); i != _resources.end(); ++i) {
- Resource *r = (*i).get();
-
- if (!strcmp(r->name, resourceName)) {
- r->flags |= kResourcePurge;
- //debugCN(kDebugCore, "M4ResourceManager::toss: mark resource %s to be purged\n", resourceName);
- }
- }
-}
-
-void ResourceManager::purge() {
- ResourceIterator i = _resources.begin();
- while (i != _resources.end()) {
- Resource *r = (*i).get();
-
- if (r->flags & kResourcePurge) {
- delete r->stream;
- i = _resources.erase(i);
- } else {
- ++i;
- }
- }
-}
-
-void ResourceManager::dump() {
- _vm->_events->getConsole()->DebugPrintf("Scene resources:\n");
-
- int index = 0;
- ResourceIterator i;
- for (i = _resources.begin(); i != _resources.end(); ++i) {
- Resource *r = (*i).get();
-
- if (!(r->flags & kResourcePurge)) {
- _vm->_events->getConsole()->DebugPrintf(
- "Resource #%i, name: %s, handle pointer: %p, size: %d, flags: %02X\n",
- index++, r->name, r->buffer, r->stream->size(), r->flags);
- }
- }
-}
-
-//--------------------------------------------------------------------------
-
-const char *madsConcatString = "MADSCONCAT";
-
-ResourceType MADSResourceManager::getResourceType(const char *resourceName) {
- if (!strncmp(resourceName, "RM", 2)) {
- // Room resource
- return RESTYPE_ROOM;
- } else if (!strncmp(resourceName, "SC", 2)) {
- // SC resource
- return RESTYPE_SC;
- } else if (strstr(resourceName, ".TXT")) {
- // Text resource
- return RESTYPE_TEXT;
- } else if (strstr(resourceName, ".QUO")) {
- // QUO resource
- return RESTYPE_QUO;
- } else if (*resourceName == 'I') {
- // I resource
- return RESTYPE_I;
- } else if (!strncmp(resourceName, "OB", 2)) {
- // OB resource
- return RESTYPE_OB;
- } else if (!strncmp(resourceName, "FONT", 4)) {
- // FONT resource
- return RESTYPE_FONT;
- } else if (!strncmp(resourceName, "SOUND", 5)) {
- // SOUND resource
- return RESTYPE_SOUND;
- } else if (!strncmp(resourceName, "SPCHC", 5)) {
- // SPEECH resource
- return RESTYPE_SPEECH;
- }
-
- // Check for a known extension
- const char *extPos = strchr(resourceName, '.');
- if (extPos) {
- ++extPos;
- if (!strcmp(extPos, "FL") || !strcmp(extPos, "LBM") || !strcmp(extPos, "ANM") ||
- !strcmp(extPos, "AA") || !strcmp(extPos, "SS")) {
- return RESTYPE_HAS_EXT;
- }
- }
-
- return RESTYPE_NO_EXT;
-}
-
-const char *MADSResourceManager::getResourceFilename(const char *resourceName) {
- static char outputFilename[64];
-
- ResourceType resType = getResourceType(resourceName);
-
- strcpy(outputFilename, "GLOBAL.HAG");
-
- if ((resType == RESTYPE_ROOM) || (resType == RESTYPE_SC)) {
- int value = atoi(resourceName + 2);
- int hagFileNum = (resType == RESTYPE_ROOM) ? value / 100 : value;
-
- if (hagFileNum > 0)
- sprintf(outputFilename, "SECTION%d.HAG", hagFileNum);
- }
-
- if (resType == RESTYPE_SPEECH)
- strcpy(outputFilename, "SPEECH.HAG");
-
- return outputFilename;
-}
-
-/**
- * Forms a resource name based on the passed specifiers
- */
-const char *MADSResourceManager::getResourceName(char asciiCh, int prefix, ExtensionType extType,
- const char *suffix, int index) {
- static char resourceName[100];
-
- if (prefix <= 0)
- strcpy(resourceName, "*");
- else {
- if (prefix < 100)
- strcpy(resourceName, "*SC");
- else
- strcpy(resourceName, "*RM");
- sprintf(resourceName + 3, "%.3d", prefix);
- }
-
- // Append the specified ascii prefix character
- char asciiStr[2];
- asciiStr[0] = asciiCh;
- asciiStr[1] = '\0';
- strcat(resourceName, asciiStr);
-
- // Add in the index specified
- if (index >= 0)
- sprintf(resourceName + strlen(resourceName), "%d", index);
-
- // Add in any suffix
- if (suffix)
- strcat(resourceName, suffix);
-
- // Handle extension types
- switch (extType) {
- case EXTTYPE_SS:
- strcat(resourceName, ".SS");
- break;
- case EXTTYPE_AA:
- strcat(resourceName, ".AA");
- break;
- case EXTTYPE_DAT:
- strcat(resourceName, ".DAT");
- break;
- case EXTTYPE_HH:
- strcat(resourceName, ".HH");
- break;
- case EXTTYPE_ART:
- strcat(resourceName, ".ART");
- break;
- case EXTTYPE_INT:
- strcat(resourceName, ".INT");
- break;
- default:
- break;
- }
-
- return &resourceName[0];
-}
-
-/**
- * Another variation for forming resource names
- */
-const char *MADSResourceManager::getResourceName(ResourcePrefixType prefixType, int idx, const char *extension) {
- static char resourceName[100];
-
- strcpy(resourceName, "*");
-
- if (extension) {
- switch (prefixType) {
- case RESPREFIX_GL:
- strcat(resourceName, "GL000");
- break;
- case RESPREFIX_SC:
- case RESPREFIX_RM:
- strcat(resourceName, (prefixType == RESPREFIX_SC) ? "SC" : "RM");
- sprintf(resourceName + 3, "%.3d", idx);
- break;
- default:
- break;
- }
-
- strcat(resourceName, extension);
- }
-
- return &resourceName[0];
-}
-
-/**
- * Forms an AA resource name based on the given passed index
- */
-const char *MADSResourceManager::getAAName(int index) {
- return getResourceName('I', 0, EXTTYPE_AA, NULL, index);
-}
-
-Common::SeekableReadStream *MADSResourceManager::loadResource(const char *resourceName, bool loadFlag) {
- Common::File hagFile;
- uint32 offset = 0, size = 0;
-
- // If the first character is a '@' then look for an external file
-
- if (*resourceName == '@') {
- ++resourceName;
-
- hagFile.open(resourceName);
- if (loadFlag)
- return hagFile.readStream(hagFile.size());
- else
- return new Common::SeekableSubReadStream(&hagFile, 0, hagFile.size());
- }
-
- // If the first character is the wildcard (resource indicator), skip over it
- if (*resourceName == '*')
- ++resourceName;
-
- char resName[20];
- strcpy(resName, resourceName);
- str_upper(resName);
-
- hagFile.open(getResourceFilename(resName));
-
- // Validate hag file header
- char headerBuffer[16];
- if ((hagFile.read(headerBuffer, 16) != 16) || (strncmp(headerBuffer, madsConcatString, 10) != 0))
- error("Invalid HAG file opened");
-
- int numEntries = hagFile.readUint16LE();
-
- int resIndex = -1;
- while (++resIndex < numEntries) {
- // Read in the details of the next resource
- char resourceBuffer[14];
- offset = hagFile.readUint32LE();
- size = hagFile.readUint32LE();
- hagFile.read(resourceBuffer, 14);
-
- if (!strcmp(resName, resourceBuffer))
- break;
- }
-
- if (resIndex == numEntries)
- error("Invalid resource '%s' specified", resourceName);
-
- // Get the resource, either loading it in it's entirely or getting a stream reference
-
- if (loadFlag) {
- hagFile.seek(offset);
- return hagFile.readStream(size);
- } else {
- return new Common::SeekableSubReadStream(&hagFile, offset, offset + size);
- }
-}
-
-bool MADSResourceManager::resourceExists(const char *resourceName) {
- Common::File hagFile;
-
- // If the first character is the wildcard (resource indicator), skip over it
- if (*resourceName == '*')
- ++resourceName;
-
- char resName[20];
- strcpy(resName, resourceName);
- str_upper(resName);
-
- hagFile.open(getResourceFilename(resName));
-
- // Validate hag file header
- char headerBuffer[16];
- if ((hagFile.read(headerBuffer, 16) != 16) || (strncmp(headerBuffer, madsConcatString, 10) != 0))
- error("Invalid HAG file opened");
-
- int numEntries = hagFile.readUint16LE();
-
- int resIndex = -1;
- while (++resIndex < numEntries) {
- // Read in the details of the next resource
- char resourceBuffer[14];
- hagFile.readUint32LE(); // offset
- hagFile.readUint32LE(); // size
- hagFile.read(resourceBuffer, 14);
-
- if (!strcmp(resName, resourceBuffer))
- break;
- }
-
- if (resIndex == numEntries)
- return false;
- else
- return true;
-}
-
-//--------------------------------------------------------------------------
-
-M4ResourceManager::M4ResourceManager(MadsM4Engine *vm): ResourceManager(vm) {
- _hfs = new FileSystem(_vm->getGameFile(kFileTypeHash));
-}
-
-M4ResourceManager::~M4ResourceManager() {
-}
-
-Common::SeekableReadStream *M4ResourceManager::loadResource(const char *resourceName, bool preloadFlag) {
- //debugCN(kDebugCore, "M4ResourceManager::loadResource() loading resource %s\n", resourceName);
- Common::SeekableReadStream* result = NULL;
- if (_hfs) {
- // actually load the resource
- result = _hfs->loadFile(resourceName, preloadFlag);
- if (!result) {
- error("M4ResourceManager::loadResource() Resource %s not found", resourceName);
- }
- } else {
- error("M4ResourceManager::loadResource() No FileSystem attached");
- }
- return result;
-}
-
-bool M4ResourceManager::resourceExists(const char *resourceName) {
- return (_hfs->getHashFileEntry(resourceName) != NULL);
-}
-
-} // End of namespace M4
diff --git a/engines/m4/resource.h b/engines/m4/resource.h
deleted file mode 100644
index c13c293544..0000000000
--- a/engines/m4/resource.h
+++ /dev/null
@@ -1,147 +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 M4_RESOURCE_H
-#define M4_RESOURCE_H
-
-#include "common/scummsys.h"
-#include "common/stream.h"
-#include "common/endian.h"
-#include "common/file.h"
-#include "common/hashmap.h"
-#include "common/hash-str.h"
-#include "common/list.h"
-#include "common/ptr.h"
-
-/*
- TODO:
- - change array to HashMap if it turns out to be slow
-*/
-
-namespace M4 {
-
-#define MAX_RESOURCES 128
-#define kM4MaxFilenameSize 33
-
-enum {
- kResourcePurge = 1 << 1
-};
-
-
-class FileSystem {
-public:
- struct HashHagEntry {
- char filename[kM4MaxFilenameSize];
- byte fileIndex;
- Common::File *hagFile;
- };
-
- struct HashFileEntry {
- char filename[kM4MaxFilenameSize];
- byte hagfile;
- uint32 offset, size;
- };
-
- FileSystem(const char *hashFilename);
- ~FileSystem();
-
- Common::SeekableReadStream *loadFile(const char *resourceName, bool preloadFlag);
- static void changeExtension(char *destName, const char *sourceName, const char *extension);
- const HashFileEntry *getHashFileEntry(const char *filename);
-
-private:
- typedef Common::HashMap<Common::String,HashFileEntry,Common::IgnoreCase_Hash,Common::IgnoreCase_EqualTo> FileHashMap;
-
- HashHagEntry _hagEntries[10]; // GLOBAL.HAG and SECTION1.HAG to SECTION9.HAG
- FileHashMap _fileEntries;
-};
-
-struct Resource {
- char name[64];
- Common::SeekableReadStream *stream;
- uint8 *buffer;
- uint8 flags;
-};
-
-class ResourceManager {
-protected:
- typedef Common::List<Common::SharedPtr<Resource> > ResourceList;
- typedef ResourceList::iterator ResourceIterator;
- ResourceList _resources;
- MadsM4Engine *_vm;
-
- virtual Common::SeekableReadStream *loadResource(const char *resourceName, bool loadFlag) = 0;
-public:
- ResourceManager(MadsM4Engine *vm): _vm(vm) {}
- virtual ~ResourceManager();
-
- Common::SeekableReadStream *get(const char *resourceName, bool loadFlag = true);
- void toss(const char *resourceName);
- void purge();
- void dump();
- virtual bool resourceExists(const char *resourceName) = 0;
-
- Common::SeekableReadStream *openFile(const char *resourceName) { return get(resourceName, false); }
- void changeExtension(char *destName, const char *sourceName, const char *extension) {
- FileSystem::changeExtension(destName, sourceName, extension);
- }
-};
-
-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,
- EXTTYPE_INT = 6, EXTTYPE_NONE = -1};
-
-enum ResourcePrefixType {RESPREFIX_GL = 1, RESPREFIX_SC = 2, RESPREFIX_RM = 3};
-
-class MADSResourceManager : public ResourceManager {
-private:
- ResourceType getResourceType(const char *resourceName);
- const char *getResourceFilename(const char *resourceName);
-protected:
- Common::SeekableReadStream *loadResource(const char *resourceName, bool loadFlag);
-public:
- MADSResourceManager(MadsM4Engine *vm): ResourceManager(vm) {}
- bool resourceExists(const char *resourceName);
-
- static const char *getResourceName(char asciiCh, int prefix, ExtensionType extType, const char *suffix, int index);
- static const char *getResourceName(ResourcePrefixType prefixType, int idx, const char *extension);
- static const char *getAAName(int index);
-};
-
-class M4ResourceManager : public ResourceManager {
-protected:
- Common::SeekableReadStream *loadResource(const char *resourceName, bool loadFlag);
-public:
- M4ResourceManager(MadsM4Engine *vm);
- ~M4ResourceManager();
- bool resourceExists(const char *resourceName);
-
-private:
- FileSystem *_hfs;
-};
-
-} // End of namespace M4
-
-
-#endif
diff --git a/engines/m4/saveload.cpp b/engines/m4/saveload.cpp
deleted file mode 100644
index a7615fa4b6..0000000000
--- a/engines/m4/saveload.cpp
+++ /dev/null
@@ -1,166 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#include "common/file.h"
-#include "common/savefile.h"
-
-#include "m4/m4.h"
-#include "m4/saveload.h"
-#include "m4/sprite.h"
-
-namespace M4 {
-
-const char *orionSavesList = "saves.dir";
-
-SaveLoad::SaveLoad(MadsM4Engine *vm) : _vm(vm) {
- // For Orion Burger, check the existance of a 'saves.dir' file to determine whether to
- // act exactly like the original. Otherwise, we'll use the ScummVM standard, where we'll
- // keep all the data for a savegame in a single file
-
- Common::File file;
- _emulateOriginal = file.exists(orionSavesList);
-}
-
-const char *SaveLoad::generateSaveName(int slotNumber) {
- static char buffer[15];
-
- sprintf(buffer, _emulateOriginal ? "burg%.3d.sav" : "burger.%.3d", slotNumber);
- return buffer;
-}
-
-bool SaveLoad::hasSaves() {
- // Return true if a savegame file exists for the first slot
-
- if (_emulateOriginal) {
- Common::File f;
- return f.exists(generateSaveName(1));
-
- } else {
- Common::ReadStream *f = _vm->saveManager()->openForLoading(generateSaveName(1));
- if (f == NULL)
- return false;
-
- delete f;
- return true;
- }
-}
-
-SaveGameList *SaveLoad::getSaves() {
- SaveGameList *result = new SaveGameList();
- char saveName[MAX_SAVEGAME_NAME];
- Common::ReadStream *f = NULL;
-
- if (_emulateOriginal) {
- Common::File *saveFile = new Common::File();
- saveFile->open(orionSavesList);
- f = saveFile;
- }
-
- for (int slotNumber = 1; slotNumber <= 99; ++slotNumber) {
- if (_emulateOriginal) {
- // Read in savegame name from save directory
- bool isPresent = (f->readByte() != 0);
- f->read(&saveName[0], MAX_SAVEGAME_NAME);
-
- if (isPresent)
- result->push_back(Common::String(saveName));
- else {
- result->push_back(Common::String());
- }
-
- } else {
- // Read in savegame name from savegame files directly
- Common::ReadStream *saveFile = _vm->saveManager()->openForLoading(
- generateSaveName(slotNumber));
- if (!saveFile) {
- // No savegame prsent at that slot
- result->push_back(Common::String());
- } else {
- // Skip over byte offset
- uint32 offset = saveFile->readUint32LE();
- assert(offset < 0x100);
-
- // Read in savegame name
- saveFile->read(&saveName[0], MAX_SAVEGAME_NAME);
- result->push_back(Common::String(saveName));
-
- delete saveFile;
- }
- }
- }
-
- if (_emulateOriginal)
- delete f;
-
- return result;
-}
-
-M4Surface *SaveLoad::getThumbnail(int slotNumber) {
- Common::SeekableReadStream *saveFile;
- uint32 dataOffset;
-
- if (_emulateOriginal) {
- // Get savegame file from original game folder
- Common::File *f = new Common::File();
- if (!f->open(generateSaveName(slotNumber))) {
- delete f;
- return NULL;
- }
-
- saveFile = f;
- } else {
- // Open up savegame for access via savefile manager
- saveFile = _vm->saveManager()->openForLoading(generateSaveName(slotNumber));
- }
- if (!saveFile)
- return NULL;
-
- dataOffset = saveFile->readUint32LE();
- assert(dataOffset < 0x100);
- saveFile->seek(dataOffset, SEEK_CUR);
-
- // Read in the sprite data
-
- saveFile->seek(16, SEEK_CUR);
- int width = saveFile->readUint32LE();
- int height = saveFile->readUint32LE();
- saveFile->seek(21, SEEK_CUR);
- saveFile->readUint32LE(); // sprite data size
-
- M4Sprite *result = new M4Sprite(saveFile, 0, 0, width, height);
- delete saveFile;
-
- return result;
-}
-
-bool SaveLoad::load(int slotNumber) {
- // TODO: Currently it's hardcoded to return a failure
- return false;
-}
-
-bool SaveLoad::save(int slotNumber, Common::String saveName) {
- // TODO: Currently it's hardcoded to return a failure
- return false;
-}
-
-
-} // End of namespace M4
diff --git a/engines/m4/scene.cpp b/engines/m4/scene.cpp
deleted file mode 100644
index be49dcb13f..0000000000
--- a/engines/m4/scene.cpp
+++ /dev/null
@@ -1,208 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#include "common/system.h"
-
-#include "m4/dialogs.h"
-#include "m4/globals.h"
-#include "m4/scene.h"
-#include "m4/events.h"
-#include "m4/graphics.h"
-#include "m4/rails.h"
-#include "m4/font.h"
-#include "m4/m4_views.h"
-#include "m4/mads_views.h"
-#include "m4/compression.h"
-#include "m4/staticres.h"
-
-namespace M4 {
-
-Scene::Scene(MadsM4Engine *vm, SceneResources *res): View(vm, Common::Rect(0, 0, vm->_screen->width(),
- vm->_screen->height())), _sceneResources(res) {
- _screenType = VIEWID_SCENE;
-
- _sceneResources->hotspots = new HotSpotList();
- _sceneResources->dynamicHotspots = new HotSpotList();
- _backgroundSurface = new M4Surface();
- _walkSurface = new M4Surface();
- _palData = NULL;
- _interfacePal = NULL;
- _interfaceSurface = NULL;
- _vm->_rails->setCodeSurface(_walkSurface);
- _currentScene = -1;
-}
-
-Scene::~Scene() {
- leaveScene();
- _vm->_scene = NULL;
-}
-
-void Scene::loadScene(int sceneNumber) {
- _previousScene = _currentScene;
- _currentScene = sceneNumber;
- _nextScene = sceneNumber;
-}
-
-void Scene::leaveScene() {
- if (_palData) {
- _vm->_palette->deleteRange(_palData);
- delete _palData;
- _palData = NULL;
- }
- if (_interfacePal) {
- _vm->_palette->deleteRange(_interfacePal);
- delete _interfacePal;
- _interfacePal = NULL;
- }
-}
-
-void Scene::show() {
- _vm->_viewManager->addView(this);
-}
-
-void Scene::showInterface() {
- _vm->_viewManager->addView(_interfaceSurface);
-}
-
-void Scene::hideInterface() {
- _vm->_viewManager->deleteView(_interfaceSurface);
-}
-
-void Scene::showSprites() {
- // TODO: This is all experimental code, it needs heavy restructuring
- // and cleanup
-
- // taken from set_walker_scaling() in adv_walk.cpp. A proper implementation will need
- // to store these in global variables
- int minScaling = FixedDiv(_sceneResources->backScale << 16, 100 << 16);
- int maxScaling = FixedDiv(_sceneResources->frontScale << 16, 100 << 16);
- int scaler;
-
- _vm->_actor->setWalkerDirection(kFacingSouthEast);
- //_vm->_actor->setWalkerPalette();
-
- // taken from set_walker_scaling() in adv_walk.cpp
- if (_sceneResources->frontY == _sceneResources->backY)
- scaler = 0;
- else
- scaler = FixedDiv(maxScaling - minScaling,
- (_sceneResources->frontY << 16) - (_sceneResources->backY << 16));
-
- // FIXME: For now, we (incorrectly) scale the walker to 50% of the scene's max scaling
- _vm->_actor->setWalkerScaling(scaler / 2);
- // Test code to display the protagonist
- _vm->_actor->placeWalkerSpriteAt(0, 320, 200);
-
- // Test code to display scene sprites
- // TODO
-}
-
-// Test function, shows all scene hotspots
-void Scene::showHotSpots() {
- int i = 0;
- HotSpot *currentHotSpot;
-
- // hotspots (green)
- for (i = 0; i < _sceneResources->hotspots->size(); i++) {
- currentHotSpot = _sceneResources->hotspots->get(i);
- _backgroundSurface->frameRect(currentHotSpot->getRect(), _vm->_palette->GREEN);
- }
-
- // Dynamic hotspots (red)
- for (i = 0; i < _sceneResources->dynamicHotspots->size(); i++) {
- currentHotSpot = _sceneResources->dynamicHotspots->get(i);
- _backgroundSurface->frameRect(currentHotSpot->getRect(), _vm->_palette->RED);
- }
-}
-
-/**
- * Debug function that shows the walkable areas by copying them over the current background surface
- */
-void Scene::showCodes() {
- if (_vm->isM4()) {
- // 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;
-
- byte colors[256 * 3];
- memset(colors, 0, sizeof(colors));
- colors[255 * 3 + 0] = 255;
- colors[255 * 3 + 1] = 255;
- colors[255 * 3 + 2] = 255;
- _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);
-
- // Show all the scene's walk nodes
- SceneNodeList &nodeList = _madsVm->scene()->getSceneResources()._nodes;
- _backgroundSurface->setColor(_madsVm->_palette->WHITE);
- for (uint i = 0; i < nodeList.size() - 2; ++i) {
- // Draw a little cross at the node's position
- _backgroundSurface->hLine(nodeList[i].pt.x - 2, nodeList[i].pt.x + 2, nodeList[i].pt.y);
- _backgroundSurface->vLine(nodeList[i].pt.x, nodeList[i].pt.y - 2, nodeList[i].pt.y + 2);
- }
-
- ((MadsScene *)this)->_spriteSlots.fullRefresh();
- }
-}
-
-void Scene::playIntro() {
-
-}
-
-void Scene::onRefresh(RectList *rects, M4Surface *destSurface) {
- update();
- View::onRefresh(rects, destSurface);
-}
-
-bool Scene::onEvent(M4EventType eventType, int32 param1, int x, int y, bool &captureEvents) {
- //if (_vm->getGameType() != GType_Burger)
- // return false;
-
- // If the game is currently paused, don't do any scene processing
- if (_vm->_kernel->paused)
- return false;
-
- switch (eventType) {
- case MEVENT_LEFT_CLICK:
- leftClick(x, y);
- break;
- case MEVENT_RIGHT_CLICK:
- rightClick(x, y);
- break;
- case MEVENT_MOVE:
- mouseMove(x, y);
- break;
- default:
- return false;
- }
-
- return true;
-}
-
-} // End of namespace M4
diff --git a/engines/m4/scene.h b/engines/m4/scene.h
deleted file mode 100644
index 5086cc0db0..0000000000
--- a/engines/m4/scene.h
+++ /dev/null
@@ -1,120 +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 M4_SCENE_H
-#define M4_SCENE_H
-
-class View;
-
-#include "m4/assets.h"
-#include "m4/font.h"
-#include "m4/hotspot.h"
-#include "m4/graphics.h"
-#include "m4/viewmgr.h"
-#include "m4/gui.h"
-#include "m4/m4_views.h"
-#include "common/array.h"
-
-namespace M4 {
-
-#define MAX_CHK_FILENAME_SIZE 144
-
-enum MADSVerbs {
- kVerbNone = 0,
- kVerbLook = 3,
- kVerbTake = 4,
- kVerbPush = 5,
- kVerbOpen = 6,
- kVerbPut = 7,
- kVerbTalkTo = 8,
- kVerbGive = 9,
- kVerbPull = 10,
- kVerbClose = 11,
- kVerbThrow = 12,
- kVerbWalkTo = 13,
- kVerbLookAt = 209
-};
-
-class SceneResources {
-public:
- char artBase[MAX_CHK_FILENAME_SIZE];
- char pictureBase[MAX_CHK_FILENAME_SIZE];
- HotSpotList *hotspots;
- HotSpotList *dynamicHotspots;
- int32 frontY, backY;
- int32 frontScale, backScale;
- int16 depthTable[16];
- int32 railNodeCount; // # of rails
-};
-
-class M4Engine;
-class MadsEngine;
-class InterfaceView;
-
-class Scene : public View {
-private:
- HotSpotList _sceneHotspots;
-protected:
- GameInterfaceView *_interfaceSurface;
- M4Surface *_backgroundSurface;
- M4Surface *_walkSurface;
- RGBList *_palData;
- RGBList *_interfacePal;
- SceneResources *_sceneResources;
-public:
- int _currentScene;
- int _previousScene;
- int _nextScene;
-public:
- Scene(MadsM4Engine *vm, SceneResources *res);
- virtual ~Scene();
-
- // Methods that differ between engines
- virtual void loadScene(int sceneNumber);
- virtual void leaveScene();
- virtual void loadSceneCodes(int sceneNumber, int index = 0) = 0;
- virtual void show();
- virtual void mouseMove(int x, int y) = 0;
- virtual void leftClick(int x, int y) = 0;
- virtual void rightClick(int x, int y) = 0;
- virtual void update() = 0;
- virtual void showHotSpots();
-
- // TODO: perhaps move playIntro() someplace else?
- void playIntro();
- void showSprites();
- void showCodes();
- int getCurrentScene() { return _currentScene; }
- M4Surface *getBackgroundSurface() const { return _backgroundSurface; }
- void showInterface();
- void hideInterface();
- GameInterfaceView *getInterface() { return _interfaceSurface; }
- SceneResources &getSceneResources() { return *_sceneResources; }
- M4Surface *getWalkSurface() const { return _walkSurface; }
-
- void onRefresh(RectList *rects, M4Surface *destSurface);
- bool onEvent(M4EventType eventType, int32 param1, int x, int y, bool &captureEvents);
-};
-
-} // End of namespace M4
-
-#endif
diff --git a/engines/m4/script.cpp b/engines/m4/script.cpp
deleted file mode 100644
index 026c025f45..0000000000
--- a/engines/m4/script.cpp
+++ /dev/null
@@ -1,1389 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#include "common/system.h"
-#include "common/textconsole.h"
-
-#include "m4/m4.h"
-#include "m4/script.h"
-#include "m4/resource.h"
-
-namespace M4 {
-
-enum OpcodeType {
- opRet = 0,
- opCall,
- opCallKernel,
- opPush,
- opPush0,
- opPush1,
- opPushNeg1,
- opPop,
- opMov,
- opAdd,
- opSub,
- opInc,
- opDec,
- opCmp,
- opJmp,
- opJmpByTable,
- opJz,
- opJnz,
- opJe,
- opJne,
- opJl,
- opJle,
- opJg,
- opJge,
- opXor,
- opShl,
- opShr,
-
- opDebug,
-
- opInvalid
-};
-
-const char *opcodeNames[] = {
- "opRet",
- "opCall",
- "opCallKernel",
- "opPush",
- "opPush0",
- "opPush1",
- "opPushNeg1",
- "opPop",
- "opMov",
- "opAdd",
- "opSub",
- "opInc",
- "opDec",
- "opCmp",
- "opJmp",
- "opJmpByTable",
- "opJz",
- "opJnz",
- "opJe",
- "opJne",
- "opJl",
- "opJle",
- "opJg",
- "opJge",
- "opXor",
- "opShl",
- "opShr",
- "opDebug",
- "opInvalid"
-};
-
-StringTable::StringTable() : _stringsData(NULL) {
-}
-
-StringTable::~StringTable() {
- delete[] _stringsData;
-}
-
-void StringTable::load(Common::File *fd) {
- int stringSize = fd->readUint32LE();
- int stringCount = fd->readUint32LE();
- _stringsData = new char[stringSize];
- fd->read(_stringsData, stringSize);
- char *stringPtr = _stringsData;
- for (int i = 0; i < stringCount; i++) {
- _strings.push_back((const char*)stringPtr);
- stringPtr += strlen(stringPtr) + 1;
- }
-}
-
-SeriesStreamBreakList::~SeriesStreamBreakList() {
-}
-
-void SeriesStreamBreakList::load(Common::File *fd) {
- uint32 count = fd->readUint32LE();
- debugCN(kDebugScript, "SeriesStreamBreakList::load() count = %d\n", count);
- for (uint32 i = 0; i < count; i++) {
- SeriesStreamBreakItem *item = new SeriesStreamBreakItem();
- item->frameNum = fd->readUint32LE();
- item->digiName = _inter->loadGlobalString(fd);
- item->digiChannel = fd->readUint32LE();
- item->digiVolume = fd->readUint32LE();
- item->trigger = fd->readUint32LE();
- item->flags = fd->readUint32LE();
- item->variable.type = kGameVar;
- item->variable.value = fd->readUint32LE();
- item->value = fd->readUint32LE();
- _items.push_back(item);
-
- debugCN(kDebugScript, "%02d: frameNum = %d; digiName = %s; digiChannel = %d; digiVolume = %d; trigger = %d; flags = %d; variable = %d; value = %d\n",
- i, item->frameNum, item->digiName, item->digiChannel, item->digiVolume, item->trigger, item->flags, item->variable.value, item->value);
-
- }
-}
-
-SaidArray::~SaidArray() {
-}
-
-void SaidArray::load(Common::File *fd) {
- uint32 count = fd->readUint32LE();
- debugCN(kDebugScript, "SaidArray::load() count = %d\n", count);
- for (uint32 i = 0; i < count; i++) {
- SaidArrayItem *item = new SaidArrayItem();
- item->itemName = _inter->loadGlobalString(fd);
- item->digiNameLook = _inter->loadGlobalString(fd);
- item->digiNameTake = _inter->loadGlobalString(fd);
- item->digiNameGear = _inter->loadGlobalString(fd);
- _items.push_back(item);
-
- debugCN(kDebugScript, "itemName = %s; digiNameLook = %s; digiNameTake = %s; digiNameGear = %s\n",
- item->itemName, item->digiNameLook, item->digiNameTake, item->digiNameGear);
-
- }
-}
-
-ParserArray::~ParserArray() {
-}
-
-void ParserArray::load(Common::File *fd) {
- uint32 count = fd->readUint32LE();
- debugCN(kDebugScript, "ParserArray::load() count = %d\n", count);
- for (uint32 i = 0; i < count; i++) {
- ParserArrayItem *item = new ParserArrayItem();
- item->w0 = _inter->loadGlobalString(fd);
- item->w1 = _inter->loadGlobalString(fd);
- item->trigger = fd->readUint32LE();
- item->testVariable.type = kGameVar;
- item->testVariable.value = fd->readUint32LE();
- item->testValue = fd->readUint32LE();
- item->variable.type = kGameVar;
- item->variable.value = fd->readUint32LE();
- item->value = fd->readUint32LE();
- _items.push_back(item);
-
- debugCN(kDebugScript, "w0 = %s; w1 = %s; trigger = %d; testVariable = %d; testValue = %d; variable = %d; value = %d\n",
- item->w0, item->w1, item->trigger, item->testVariable.value, item->testValue, item->variable.value, item->value);
-
- }
-}
-
-ScriptFunction::ScriptFunction(ScriptInterpreter *inter) : _inter(inter) {
-}
-
-ScriptFunction::~ScriptFunction() {
- delete _code;
-}
-
-void ScriptFunction::load(Common::File *fd) {
- debugCN(kDebugScript, "ScriptFunction::load()\n");
- uint32 size = fd->readUint32LE();
- debugCN(kDebugScript, "ScriptFunction::load() size = %d\n", size);
- _code = fd->readStream(size);
-}
-
-void ScriptFunction::jumpAbsolute(uint32 ofs) {
- _code->seek(ofs);
-}
-
-void ScriptFunction::jumpRelative(int32 ofs) {
- _code->seek(ofs, SEEK_CUR);
-}
-
-byte ScriptFunction::readByte() {
- return _code->readByte();
-}
-
-uint32 ScriptFunction::readUint32() {
- return _code->readUint32LE();
-}
-
-
-ScriptInterpreter::ScriptInterpreter(MadsM4Engine *vm) : _scriptFile(NULL), _vm(vm) {
- initScriptKernel();
- _dataCache = new ScriptDataCache(this);
- _runningFunction = NULL;
-}
-
-ScriptInterpreter::~ScriptInterpreter() {
- close();
- delete _dataCache;
-}
-
-void ScriptInterpreter::open(const char *filename) {
- if (_scriptFile)
- close();
- _scriptFile = new Common::File();
- _scriptFile->open(filename);
- if (!_scriptFile->isOpen())
- error("ScriptInterpreter::open() Error opening %s", filename);
-
- _scriptFile->readUint32LE(); // skip magic for now
- uint32 version = _scriptFile->readUint32LE();
- if (version != kScriptFileVersion) {
- error("ScriptInterpreter::open() DAT file version mismatch; requested %li, got %i", kScriptFileVersion, version);
- }
-
- int functionCount = _scriptFile->readUint32LE();
- debugCN(kDebugScript, "functionCount = %d\n", functionCount);
- for (int i = 0; i < functionCount; i++) {
- uint32 offset = _scriptFile->readUint32LE();
- debugCN(kDebugScript, "func(%d) offset = %08X\n", i, offset);
- uint32 len = _scriptFile->readUint32LE();
- if (len > 0) {
- char *funcName = new char[len + 1];
- _scriptFile->read(funcName, len);
- funcName[len] = '\0';
- debugCN(kDebugScript, "func(%d) name = %s\n", i, funcName);
- _functionNames[Common::String(funcName)] = _functions.size();
- // DEBUG
- _scriptFunctionNames.push_back(Common::String(funcName));
- delete[] funcName;
- }
- _functions.push_back(new ScriptFunctionEntry(offset));
- }
-
- int dataCount = _scriptFile->readUint32LE();
- debugCN(kDebugScript, "dataCount = %d\n", dataCount);
- for (int i = 0; i < dataCount; i++) {
- uint32 offset = _scriptFile->readUint32LE();
- ScriptDataType type = (ScriptDataType)_scriptFile->readUint32LE();
- debugCN(kDebugScript, "data(%d) offset = %08X; type = %d\n", i, offset, type);
- _data.push_back(new ScriptDataEntry(offset, type));
- }
-
- _globalVarCount = _scriptFile->readUint32LE();
- debugCN(kDebugScript, "_globalVarCount = %d\n", _globalVarCount);
-
- uint32 stringOfs = _scriptFile->readUint32LE();
- _scriptFile->seek(stringOfs);
- _constStrings.load(_scriptFile);
-
- for (int i = 0; i < ARRAYSIZE(_globalVars); i++) {
- _globalVars[i].type = kInteger;
- _globalVars[i].value = 0;
- }
-
- memset(_logicGlobals, 0, sizeof(_logicGlobals));
-
- memset(_registers, 0, sizeof(_registers));
- memset(_stack, 0, sizeof(_stack));
- _stackPtr = 0;
-
-}
-
-void ScriptInterpreter::close() {
- delete _scriptFile;
-}
-
-void ScriptInterpreter::initScriptKernel() {
-
-#include "m4/scripttab.h"
-
- _kernelFunctions = kernelFunctions;
- _kernelFunctionsMax = ARRAYSIZE(kernelFunctions) + 1;
-
- _kernelVars = kernelVars;
- _kernelVarsMax = ARRAYSIZE(kernelVars) + 1;
-
-}
-
-
-ScriptFunction *ScriptInterpreter::loadFunction(uint32 index) {
- //GONE WHILE DEBUGGING assert(index < _functions.size());
- if (index >= _functions.size()) return NULL;
- ScriptFunction *scriptFunction;
- scriptFunction = _functions[index]->func;
- if (!scriptFunction) {
- scriptFunction = new ScriptFunction(this);
- _scriptFile->seek(_functions[index]->offset);
- scriptFunction->load(_scriptFile);
- _functions[index]->func = scriptFunction;
- }
- return scriptFunction;
-}
-
-ScriptFunction *ScriptInterpreter::loadFunction(const Common::String &name) {
- FunctionNameMap::iterator iter = _functionNames.find(name);
- if (iter == _functionNames.end()) {
- debugCN(kDebugScript, "ScriptInterpreter::loadFunction() Function '%s' not found!\n", name.c_str());
- return NULL;
- }
- uint32 funcIndex = (*iter)._value;
- debugCN(kDebugScript, "ScriptInterpreter::loadFunction() index('%s') = %d\n", name.c_str(), funcIndex);
- return loadFunction(funcIndex);
-}
-
-void ScriptInterpreter::unloadFunctions() {
- for (uint32 i = 0; i < _functions.size(); i++) {
- if (_functions[i]->func) {
- delete _functions[i]->func;
- _functions[i]->func = NULL;
- }
- }
-}
-
-int ScriptInterpreter::runFunction(ScriptFunction *scriptFunction) {
- bool done = false;
-
- int oldLocalStackPtr = _localStackPtr;
- ScriptFunction *oldRunningFunction = _runningFunction;
-
- // TODO: Also initialize _localStackPtr
-
- _runningFunction = scriptFunction;
- _runningFunction->jumpAbsolute(0);
- while (!done) {
- byte opcode = _runningFunction->readByte();
- done = !execOpcode(opcode);
- }
-
- _localStackPtr = oldLocalStackPtr;
- _runningFunction = oldRunningFunction;
-
- return 0;
-}
-
-void ScriptInterpreter::push(const ScriptValue &value) {
- if (_stackPtr == ARRAYSIZE(_stack))
- error("ScriptInterpreter::push() Stack overflow");
- _stack[_stackPtr++] = value;
-}
-
-void ScriptInterpreter::pop(ScriptValue &value) {
- if (_stackPtr == 0)
- error("ScriptInterpreter::pop() Stack underflow");
- value = _stack[_stackPtr--];
-}
-
-void ScriptInterpreter::dumpStack() {
- debugCN(kDebugScript, "ScriptInterpreter::dumpStack()\n");
- for (int i = 0; i < _stackPtr; i++) {
- debugCN(kDebugScript, "%03d. type = %02d; value = %d\n", i, _stack[i].type, _stack[i].value);
- }
-}
-
-void ScriptInterpreter::dumpRegisters() {
- debugCN(kDebugScript, "ScriptInterpreter::dumpRegisters()\n");
- for (int i = 0; i < ARRAYSIZE(_registers); i++) {
- debugCN(kDebugScript, "%03d. type = %02d; value = %d\n", i, _registers[i].type, _registers[i].value);
- }
-}
-
-void ScriptInterpreter::dumpGlobalVars() {
- debugCN(kDebugScript, "ScriptInterpreter::dumpGlobalVars()\n");
- for (int i = 0; i < ARRAYSIZE(_globalVars); i++) {
- if (_globalVars[i].type != -1)
- debugCN(kDebugScript, "%03d. type = %02d; value = %d\n", i, _globalVars[i].type, _globalVars[i].value);
- }
-}
-
-int ScriptInterpreter::toInteger(const ScriptValue &value) {
-
- switch (value.type) {
-
- case kInteger:
- return value.value;
-
- default:
- debugCN(kDebugScript, "ScriptInterpreter::toInteger() Invalid type %d!\n", value.type);
- return 0;
-
- }
-
-}
-
-const char *ScriptInterpreter::toString(const ScriptValue &value) {
-
- switch (value.type) {
-
- case kInteger:
- return NULL;
-
- case kConstString:
- return _constStrings[value.value];
-
- default:
- debugCN(kDebugScript, "ScriptInterpreter::toString() Invalid type %d!\n", value.type);
- return NULL;
-
- }
-
-}
-
-const char *ScriptInterpreter::loadGlobalString(Common::File *fd) {
- uint32 index = fd->readUint32LE();
- if (index != 0xFFFFFFFF)
- return getGlobalString(index);
- else
- return NULL;
-}
-
-void ScriptInterpreter::test() {
-}
-
-void ScriptInterpreter::loadValue(ScriptValue &value) {
-
- value.type = (ScriptValueType)_runningFunction->readByte();
-
- switch (value.type) {
-
- case kGameVar:
- case kInteger:
- case kConstString:
- case kDataRef:
- case kLogicVar:
- case kLogicVarRef:
- case kKernelVar:
- value.value = _runningFunction->readUint32();
- break;
-
- case kRegister:
- value.value = _runningFunction->readByte();
- break;
-
- default:
- debugCN(kDebugScript, "ScriptInterpreter::loadValue() Invalid value type %d!\n", value.type);
-
- }
-
-}
-
-void ScriptInterpreter::copyValue(ScriptValue &destValue, ScriptValue &sourceValue) {
-
- if (sourceValue.type == -1) {
- debugCN(kDebugScript, "ScriptInterpreter::copyValue() Trying to read uninitialized value!\n");
- }
-
- switch (destValue.type) {
-
- case kGameVar:
- _globalVars[destValue.value] = sourceValue;
- break;
-
- case kRegister:
- _registers[destValue.value] = sourceValue;
- break;
-
- case kLogicVar:
- // TODO: Move to own method
- if (sourceValue.type == kInteger) {
- _logicGlobals[destValue.value] = sourceValue.value;
- } else {
- debugCN(kDebugScript, "ScriptInterpreter::copyValue() Invalid source value type %d!\n", sourceValue.type);
- }
- break;
-
- case kKernelVar:
- setKernelVar(destValue.value, sourceValue);
- break;
-
- default:
- debugCN(kDebugScript, "ScriptInterpreter::copyValue() Invalid dest value type %d!\n", destValue.type);
-
- }
-
-}
-
-void ScriptInterpreter::derefValue(ScriptValue &value) {
-
- switch (value.type) {
-
- case kGameVar:
- value = _globalVars[value.value];
- break;
-
- case kInteger:
- case kConstString:
- case kDataRef:
- case kLogicVarRef:
- // These need no dereferencing
- break;
-
- case kRegister:
- value = _registers[value.value];
- break;
-
- case kLogicVar:
- // TODO: Move to own method
- value = _logicGlobals[value.value];
- break;
-
- case kKernelVar:
- getKernelVar(value.value, value);
- break;
-
- default:
- debugCN(kDebugScript, "ScriptInterpreter::derefValue() Invalid value type %d!\n", value.type);
-
- }
-
-}
-
-void ScriptInterpreter::callKernelFunction(uint32 index) {
-
- debugCN(kDebugScript, "ScriptInterpreter::callKernelFunction() index = %d\n", index);
-
- if (index > _kernelFunctionsMax) {
- debugCN(kDebugScript, "ScriptInterpreter::callKernelFunction() Invalid kernel functionindex (%d)\n", index);
- return;
- }
-
- debugCN(kDebugScript, "ScriptInterpreter::callKernelFunction() name = %s\n", _kernelFunctions[index].desc);
-
- int args = (this->*(_kernelFunctions[index].proc))();
- // Now remove values from the stack if the function used any
- if (args > 4)
- _stackPtr -= args - 4;
-
- debugCN(kDebugScript, "-------------\n");
-
-}
-
-ScriptValue ScriptInterpreter::getArg(uint32 index) {
- if (index < 4) {
- return _registers[index];
- } else {
- index -= 4;
- return _stack[_stackPtr - index - 1];
- }
-}
-
-void ScriptInterpreter::dumpArgs(uint32 count) {
- debugCN(kDebugScript, "ScriptInterpreter::dumpArgs() ");
- for (uint32 i = 0; i < count; i++) {
- ScriptValue argValue = getArg(i);
- if (argValue.type == kConstString) {
- debugCN(kDebugScript, "'%s'", toString(argValue));
- } else {
- debugCN(kDebugScript, "%d", argValue.value);
- }
- if (i + 1 < count)
- debugCN(kDebugScript, ", ");
- }
- debugCN(kDebugScript, "\n");
-}
-
-void ScriptInterpreter::callFunction(uint32 index) {
- // NOTE: This is a temporary hack for script functions not yet in the m4.dat
- if (index == 0xFFFFFFFF)
- return;
- debugCN(kDebugScript, "ScriptInterpreter::callFunction() index = %d [%s]\n", index, _scriptFunctionNames[index].c_str());
- ScriptFunction *subFunction = loadFunction(index);
- if (!subFunction) {
- // This *should* never happen since the linker checks this
- debugCN(kDebugScript, "ScriptInterpreter::callFunction() Function %d could not be loaded!\n", index);
- return;
- }
- runFunction(subFunction);
-}
-
-bool ScriptInterpreter::execOpcode(byte opcode) {
-
- debugCN(kDebugScript, "opcode = %d (%s)\n", opcode, opcodeNames[opcode]);
-
- ScriptValue value1, value2, value3;
- uint32 temp;
-
- /* TODO: Put all opcodes into separate functions and into an array
- (but only after all needed opcodes are known and frozen)
- */
-
- switch (opcode) {
-
- case opRet:
- return false;
-
- case opPush:
- loadValue(value1);
- derefValue(value1);
- push(value1);
- return true;
-
- case opPush0:
- push(ScriptValue(0));
- return true;
-
- case opPush1:
- push(ScriptValue(1));
- return true;
-
- case opPushNeg1:
- push(ScriptValue(-1));
- return true;
-
- case opPop:
- loadValue(value1);
- pop(value2);
- copyValue(value1, value2);
- return true;
-
- case opMov:
- loadValue(value1);
- loadValue(value2);
- derefValue(value2);
- copyValue(value1, value2);
- return true;
-
- // Possibly join all jump variants into one opcode
-
- case opJmp:
- temp = _runningFunction->readUint32();
- debugCN(kDebugScript, "-> ofs = %08X\n", temp);
- _runningFunction->jumpAbsolute(temp);
- return true;
-
- case opJl:
- temp = _runningFunction->readUint32();
- if (_cmpFlags < 0) {
- debugCN(kDebugScript, "-> ofs = %08X\n", temp);
- _runningFunction->jumpAbsolute(temp);
- }
- return true;
-
- case opJle:
- temp = _runningFunction->readUint32();
- if (_cmpFlags <= 0) {
- debugCN(kDebugScript, "-> ofs = %08X\n", temp);
- _runningFunction->jumpAbsolute(temp);
- }
- return true;
-
- case opJg:
- temp = _runningFunction->readUint32();
- if (_cmpFlags > 0) {
- debugCN(kDebugScript, "-> ofs = %08X\n", temp);
- _runningFunction->jumpAbsolute(temp);
- }
- return true;
-
- case opJge:
- temp = _runningFunction->readUint32();
- if (_cmpFlags >= 0) {
- debugCN(kDebugScript, "-> ofs = %08X\n", temp);
- _runningFunction->jumpAbsolute(temp);
- }
- return true;
-
- case opJz:
- temp = _runningFunction->readUint32();
- if (_cmpFlags == 0) {
- debugCN(kDebugScript, "-> ofs = %08X\n", temp);
- _runningFunction->jumpAbsolute(temp);
- }
- return true;
-
- case opJnz:
- temp = _runningFunction->readUint32();
- if (_cmpFlags != 0) {
- debugCN(kDebugScript, "-> ofs = %08X\n", temp);
- _runningFunction->jumpAbsolute(temp);
- }
- return true;
-
- case opJmpByTable:
- temp = _runningFunction->readUint32();
- debugCN(kDebugScript, "-> index = %d\n", _registers[0].value);
- _runningFunction->jumpRelative(_registers[0].value * 4);
- temp = _runningFunction->readUint32();
- debugCN(kDebugScript, "-> ofs = %08X\n", temp);
- _runningFunction->jumpAbsolute(temp);
- return true;
-
- case opCmp:
- loadValue(value1);
- loadValue(value2);
- derefValue(value1);
- derefValue(value2);
- if (value1.type != kInteger || value2.type != kInteger)
- warning("ScriptInterpreter::execOpcode() Trying to compare non-integer values (%d, %d, line %d)", value1.type, value2.type, _lineNum);
- _cmpFlags = value1.value - value2.value;
- debugCN(kDebugScript, "-> cmp %d, %d\n", value1.value, value2.value);
- debugCN(kDebugScript, "-> _cmpFlags = %d\n", _cmpFlags);
- return true;
-
- case opCall:
- temp = _runningFunction->readUint32();
- callFunction(temp);
- return true;
-
- case opCallKernel:
- temp = _runningFunction->readUint32();
- callKernelFunction(temp);
- return true;
-
- case opInc:
- loadValue(value1);
- value2 = value1;
- derefValue(value2);
- value2.value++;
- copyValue(value1, value2);
- return true;
-
- case opDec:
- loadValue(value1);
- value2 = value1;
- derefValue(value2);
- value2.value--;
- copyValue(value1, value2);
- return true;
-
- case opAdd:
- loadValue(value1);
- value3 = value1;
- loadValue(value2);
- derefValue(value3);
- derefValue(value2);
- value3.value += value2.value;
- copyValue(value1, value3);
- return true;
-
- case opSub:
- loadValue(value1);
- value3 = value1;
- loadValue(value2);
- derefValue(value3);
- derefValue(value2);
- value3.value -= value2.value;
- copyValue(value1, value3);
- return true;
-
- case opDebug:
- _lineNum = (int)_runningFunction->readUint32();
- return true;
-
- default:
- debugCN(kDebugScript, "Invalid opcode %d!\n", opcode);
- return false;
-
- }
-
-}
-
-// Kernel functions
-
-#define STRING(arg) (toString(getArg(arg)))
-#define INTEGER(arg) (toInteger(getArg(arg)))
-#define DATA(arg, T) (toData<T>(getArg(arg)))
-#define RETURN(value) (_registers[0] = (value))
-
-int ScriptInterpreter::o1_handleStreamBreak() {
- return 0;
-}
-
-int ScriptInterpreter::o1_handlePlayBreak() {
- return 0;
-}
-
-int ScriptInterpreter::o1_dispatchTriggerOnSoundState() {
- return 0;
-}
-
-int ScriptInterpreter::o1_getTicks() {
- return 0;
-}
-
-int ScriptInterpreter::o1_setSoundVolume() {
- return 0;
-}
-
-int ScriptInterpreter::o1_getSoundStatus() {
- return 0;
-}
-
-int ScriptInterpreter::o1_getSoundDuration() {
- return 0;
-}
-
-int ScriptInterpreter::o1_setSeriesFrameRate() {
- return 0;
-}
-
-int ScriptInterpreter::o1_terminateMachine() {
- return 0;
-}
-
-int ScriptInterpreter::o1_sendWoodScriptMessage() {
- return 0;
-}
-
-int ScriptInterpreter::o1_runConversation() {
- return 0;
-}
-
-int ScriptInterpreter::o1_exportConversationValue() {
- return 0;
-}
-
-int ScriptInterpreter::o1_exportConversationPointer() {
- return 0;
-}
-
-int ScriptInterpreter::o1_playBreakSeries() {
- return 0;
-}
-
-int ScriptInterpreter::o1_hideWalker() {
- return 0;
-}
-
-int ScriptInterpreter::o1_showWalker() {
- return 0;
-}
-
-int ScriptInterpreter::o1_walk() {
- return 0;
-}
-
-int ScriptInterpreter::o1_overrideCrunchTime() {
- return 0;
-}
-
-int ScriptInterpreter::o1_addBlockingRect() {
- return 0;
-}
-
-int ScriptInterpreter::o1_setPlayerCommandsAllowed() {
- return 0;
-}
-
-int ScriptInterpreter::o1_getPlayerCommandsAllowed() {
- return 0;
-}
-
-int ScriptInterpreter::o1_setPlayerFacingAngle() {
- return 0;
-}
-
-int ScriptInterpreter::o1_disablePlayerFadeToBlack() {
- return 0;
-}
-
-int ScriptInterpreter::o1_enablePlayer() {
- return 0;
-}
-
-int ScriptInterpreter::o1_disablePlayer() {
- return 0;
-}
-
-int ScriptInterpreter::o1_freshenSentence() {
- return 0;
-}
-
-int ScriptInterpreter::o1_playerGiveItem() {
- return 0;
-}
-
-int ScriptInterpreter::o1_moveObject() {
- return 0;
-}
-
-int ScriptInterpreter::o1_setStopSoundsBetweenRooms() {
- return 0;
-}
-
-int ScriptInterpreter::o1_backupPalette() {
- return 0;
-}
-
-int ScriptInterpreter::o1_unloadWilburWalker() {
- return 0;
-}
-
-int ScriptInterpreter::o1_wilburTalk() {
- return 0;
-}
-
-int ScriptInterpreter::o1_wilburFinishedTalking() {
- return 0;
-}
-
-int ScriptInterpreter::o1_preloadSound() {
- const char *name = STRING(0);
- int room = INTEGER(1);
- debugCN(kDebugScript, "name = %s; room = %d\n", name, room);
- return 2;
-}
-
-int ScriptInterpreter::o1_unloadSound() {
- const char *name = STRING(0);
- int room = INTEGER(1);
- debugCN(kDebugScript, "name = %s; room = %d\n", name, room);
- return 2;
-}
-
-int ScriptInterpreter::o1_playSound() {
- const char *name = STRING(0);
- int channel = INTEGER(1);
- int volume = INTEGER(2);
- int trigger = INTEGER(3);
- int room = INTEGER(4);
- debugCN(kDebugScript, "name = %s; channel = %d; volume = %d; trigger = %d; room = %d\n",
- name, channel, volume, trigger, room);
-
- Common::String soundName = Common::String(name) + ".raw";
- _vm->_sound->playVoice(soundName.c_str(), 100);
-
- // HACK until fixed
- _vm->_kernel->sendTrigger(trigger);
-
- return 5;
-}
-
-int ScriptInterpreter::o1_playLoopingSound() {
- const char *name = STRING(0);
- int channel = INTEGER(1);
- int volume = INTEGER(2);
- int trigger = INTEGER(3);
- int room = INTEGER(4);
- debugCN(kDebugScript, "name = %s; channel = %d; volume = %d; trigger = %d; room = %d\n",
- name, channel, volume, trigger, room);
-
- // HACK until fixed
- _vm->_kernel->sendTrigger(trigger);
-
- return 5;
-}
-
-int ScriptInterpreter::o1_stopSound() {
- int channel = INTEGER(0);
- debugCN(kDebugScript, "channel = %d\n", channel);
- return 1;
-}
-
-int ScriptInterpreter::o1_fadeSetStart() {
- // skip arg 0: palette ptr
- int percent = INTEGER(1);
- debugCN(kDebugScript, "percent = %d\n", percent);
- return 2;
-}
-
-int ScriptInterpreter::o1_fadeInit() {
- // skip arg 0: palette ptr
- int first = INTEGER(1);
- int last = INTEGER(2);
- int percent = INTEGER(3);
- int ticks = INTEGER(4);
- int trigger = INTEGER(5);
- debugCN(kDebugScript, "first = %d; last = %d; percent = %d; ticks = %d; trigger = %d\n",
- first, last, percent, ticks, trigger);
-
- // HACK until palette fading is implemented
- _vm->_kernel->sendTrigger(trigger);
-
- return 6;
-}
-
-int ScriptInterpreter::o1_fadeToBlack() {
- return 0;
-}
-
-int ScriptInterpreter::o1_initPaletteCycle() {
- int first = INTEGER(0);
- int last = INTEGER(1);
- int delay = INTEGER(2);
- int ticks = INTEGER(3);
- int trigger = INTEGER(4);
- debugCN(kDebugScript, "first = %d; last = %d; delay = %d; ticks = %d; trigger = %d\n",
- first, last, delay, ticks, trigger);
-
- // HACK until palette cycling is implemented
- _vm->_kernel->sendTrigger(trigger);
-
- return 5;
-}
-
-int ScriptInterpreter::o1_stopPaletteCycle() {
- return 0;
-}
-
-int ScriptInterpreter::o1_hasPlayerSaid() {
- const char *words[3];
- for (int i = 0; i < 3; i++)
- words[i] = STRING(i);
- debugCN(kDebugScript, "'%s', '%s', '%s'\n", words[0], words[1], words[2]);
-
- int result = _vm->_player->said(words[0], words[1], words[2]);
-
- debugCN(kDebugScript, " -> '%d'\n", result);
-
- RETURN(result);
- return 3;
-}
-
-int ScriptInterpreter::o1_hasPlayerSaidAny() {
- const char *words[10];
- for (int i = 0; i < 10; i++)
- words[i] = STRING(i);
-
- debugCN(kDebugScript, "'%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s'\n",
- words[0], words[1], words[2], words[3], words[4], words[5], words[6], words[7], words[8], words[9]);
-
- int result = _vm->_player->saidAny(words[0], words[1], words[2], words[3], words[4], words[5], words[6], words[7], words[8], words[9]);
- debugCN(kDebugScript, " -> '%d'\n", result);
-
- RETURN(result);
- return 10;
-}
-
-int ScriptInterpreter::o1_updatePlayerInfo() {
- // skip arg 0: player info struct
- return 1;
-}
-
-int ScriptInterpreter::o1_playerHotspotWalkOverride() {
- int x1 = INTEGER(0);
- int y1 = INTEGER(1);
- int x2 = INTEGER(2);
- int y2 = INTEGER(3);
- debugCN(kDebugScript, "(%d, %d); (%d, %d)\n", x1, y1, x2, y2);
- return 4;
-}
-
-int ScriptInterpreter::o1_playerHasItem() {
- const char *name = STRING(0);
- debugCN(kDebugScript, "item = '%s'\n", name);
- // TODO
- RETURN(0);
- return 1;
-}
-
-int ScriptInterpreter::o1_setWalkerLocation() {
- // skip arg 0: walker
- int x = INTEGER(1);
- int y = INTEGER(2);
- debugCN(kDebugScript, "x = %d; y = %d\n", x, y);
- return 3;
-}
-
-int ScriptInterpreter::o1_setWalkerFacing() {
- // skip arg 0: walker
- int facing = INTEGER(1);
- debugCN(kDebugScript, "facing = %d\n", facing);
- return 2;
-}
-
-int ScriptInterpreter::o1_setHotspot() {
- // skip arg 0: hotspot list
- const char *name = STRING(1);
- int value = INTEGER(2);
- debugCN(kDebugScript, "name = '%s' -> %d\n", name, value);
-
- _vm->_scene->getSceneResources().hotspots->setActive(name, (value != 0));
-
- return 2;
-}
-
-int ScriptInterpreter::o1_loadConversation() {
- const char *name = STRING(0);
- //int trigger = INTEGER(1);
- //int flag = INTEGER(2);
-
- // TODO; just to show something
- _m4Vm->_converse->startConversation(name);
-
- return 3;
-}
-
-int ScriptInterpreter::o1_playSeries() {
- const char *name = STRING(0);
- int layer = INTEGER(1);
- int flags = INTEGER(2);
- int trigger = INTEGER(3);
- int frameRate = INTEGER(4);
- int loopCount = INTEGER(5);
- int scale = INTEGER(6);
- int x = INTEGER(7);
- int y = INTEGER(8);
- int firstFrame = INTEGER(9);
- int lastFrame = INTEGER(10);
-
- debugCN(kDebugScript, "name = %s; layer = %04X; flags = %08X; trigger = %d; frameRate = %d; loopCount = %d; scale = %d; x = %d; y = %d: firstFrame = %d; lastFrame = %d\n",
- name, layer, flags, trigger, frameRate, loopCount, scale, x, y, firstFrame, lastFrame);
-
- // TODO: Return the machine to the script
- _vm->_ws->playSeries(name, layer, flags, trigger, frameRate, loopCount, scale, x, y, firstFrame, lastFrame);
-
- return 11;
-}
-
-int ScriptInterpreter::o1_showSeries() {
- const char *name = STRING(0);
- int layer = INTEGER(1);
- int flags = INTEGER(2);
- int trigger = INTEGER(3);
- int duration = INTEGER(4);
- int frameIndex = INTEGER(5);
- int scale = INTEGER(6);
- int x = INTEGER(7);
- int y = INTEGER(8);
-
- debugCN(kDebugScript, "name = %s; layer = %04X; flags = %08X; trigger = %d; duration = %d; frameIndex = %d; scale = %d; x = %d; y = %d\n",
- name, layer, flags, trigger, duration, frameIndex, scale, x, y);
-
- // TODO: Return the machine to the script
- _vm->_ws->showSeries(name, layer, flags, trigger, duration, frameIndex, scale, x, y);
-
- return 9;
-}
-
-int ScriptInterpreter::o1_loadSeries() {
- const char *name = STRING(0);
- int hash = INTEGER(1);
- // skip arg 3: palette ptr
-
- debugCN(kDebugScript, "name = %s; hash = %d\n", name, hash);
-
- int result = _vm->_ws->loadSeries(name, hash, NULL);
-
- RETURN(result);
- return 3;
-}
-
-int ScriptInterpreter::o1_unloadSeries() {
- return 0;
-}
-
-int ScriptInterpreter::o1_preloadBreakSeries() {
- //const SeriesStreamBreakList& seriesStreamBreakList = DATA(0, SeriesStreamBreakList);
- return 1;
-}
-
-int ScriptInterpreter::o1_unloadBreakSeries() {
- //const SeriesStreamBreakList& seriesStreamBreakList = DATA(0, SeriesStreamBreakList);
- return 1;
-}
-
-int ScriptInterpreter::o1_startBreakSeries() {
- //const SeriesStreamBreakList& seriesStreamBreakList = DATA(0, SeriesStreamBreakList);
- return 1;
-}
-
-int ScriptInterpreter::o1_globalTriggerProc() {
- int value1 = INTEGER(0);
- int value2 = INTEGER(1);
- int value3 = INTEGER(2);
- debugCN(kDebugScript, "%d; %d; %d\n", value1, value2, value3);
- return 3;
-}
-
-int ScriptInterpreter::o1_triggerTimerProc() {
- int value1 = INTEGER(0);
- int value2 = INTEGER(1);
- int value3 = INTEGER(2);
- debugCN(kDebugScript, "%d; %d; %d\n", value1, value2, value3);
- return 3;
-}
-
-int ScriptInterpreter::o1_dispatchTrigger() {
- int trigger = INTEGER(0);
- debugCN(kDebugScript, "trigger = %d\n", trigger);
-
- _vm->_kernel->sendTrigger(trigger);
- //g_system->delayMillis(5000);
-
- return 1;
-}
-
-int ScriptInterpreter::o1_getRangedRandomValue() {
- int minValue = INTEGER(0);
- int maxValue = INTEGER(1);
- RETURN(_vm->imath_ranged_rand(minValue, maxValue));
- return 2;
-}
-
-int ScriptInterpreter::o1_wilburSaid() {
- const SaidArray& saidArray = DATA(0, SaidArray);
-
- int result = 0;
-
- // NOTE: The "Common::String soundName" stuff is just temporary until playVoice is fixed.
-
- for (int i = 0; i < saidArray.size(); i++) {
- SaidArrayItem *item = saidArray[i];
-
- if (_vm->_player->said("LOOK AT", item->itemName) && item->digiNameLook) {
- debugCN(kDebugScript, " -> LOOK AT: '%s'\n", item->digiNameLook);
- Common::String soundName = Common::String(item->digiNameLook) + ".raw";
- _vm->_sound->playVoice(soundName.c_str(), 100);
- result = 1;
- break;
- }
-
- if (_vm->_player->said("TAKE", item->itemName) && item->digiNameTake) {
- debugCN(kDebugScript, " -> TAKE: '%s'\n", item->digiNameTake);
- Common::String soundName = Common::String(item->digiNameTake) + ".raw";
- _vm->_sound->playVoice(soundName.c_str(), 100);
- result = 1;
- break;
- }
-
- if (_vm->_player->said("GEAR", item->itemName) && item->digiNameGear) {
- debugCN(kDebugScript, " -> GEAR: '%s'\n", item->digiNameGear);
- Common::String soundName = Common::String(item->digiNameGear) + ".raw";
- _vm->_sound->playVoice(soundName.c_str(), 100);
- result = 1;
- break;
- }
-
- /*
- debugCN(kDebugScript, "##### itemName = '%s'; digiNameLook = %s; digiNameTake = %s; digiNameGear = %s\n",
- item->itemName, item->digiNameLook, item->digiNameTake, item->digiNameGear);
- */
- }
- debugCN(kDebugScript, " -> '%d'\n", result);
-
- RETURN(result);
- return 1;
-}
-
-int ScriptInterpreter::o1_wilburParse() {
- //const ParserArray& parserArray = DATA(0, ParserArray);
- RETURN(0);
- return 1;
-}
-
-int ScriptInterpreter::o1_wilburSpeech() {
- const char *name = STRING(0);
- int trigger = INTEGER(1);
- int room = INTEGER(2);
- int flag = INTEGER(3);
- int volume = INTEGER(4);
- int slot = INTEGER(5);
-
- debugCN(kDebugScript, "%s; %d; %d; %d; %d; %d\n", name, trigger, room, flag, volume, slot);
- //g_system->delayMillis(5000);
-
- KernelTriggerType oldTriggerMode = _vm->_kernel->triggerMode;
-
- // TODO
- Common::String soundName = Common::String(name) + ".raw";
- _vm->_sound->playVoice(soundName.c_str(), 100);
-
- _vm->_kernel->triggerMode = oldTriggerMode;
-
- return 6;
-}
-
-// Kernel vars
-
-void ScriptInterpreter::getKernelVar(int index, ScriptValue &value) {
-
- debugCN(kDebugScript, "ScriptInterpreter::getKernelVar() index = %d\n", index);
-
- if (index > _kernelVarsMax) {
- debugCN(kDebugScript, "ScriptInterpreter::getKernelVar() Invalid kernel var index %d!\n", index);
- return;
- }
-
- debugCN(kDebugScript, "ScriptInterpreter::getKernelVar() name = %s\n", _kernelVars[index].desc);
-
- ScriptKernelVariable var = _kernelVars[index].var;
-
- switch (var) {
-
- case kKernelTrigger:
- value = _vm->_kernel->trigger;
- break;
-
- case kKernelTriggerMode:
- value = (int)_vm->_kernel->triggerMode;
- break;
-
- case kKernelContinueHandlingTrigger:
- value = (int)_vm->_kernel->daemonTriggerAvailable;
- break;
-
- case kGameVersion:
- // TODO
- value = 0;
- break;
-
- case kGameLanguage:
- // TODO
- value = 0;
- break;
-
- case kGameNewRoom:
- // TODO
- value = 0;
- break;
-
- case kPlayerCommandReady:
- value = (int)_vm->_player->commandReady;
- break;
-
- default:
- debugCN(kDebugScript, "ScriptInterpreter::getKernelVar() Invalid kernel var %d!\n", var);
- //g_system->delayMillis(2000);
-
- }
-
-}
-
-void ScriptInterpreter::setKernelVar(int index, const ScriptValue &value) {
-
- debugCN(kDebugScript, "ScriptInterpreter::setKernelVar() index = %d\n", index);
-
- if (index > _kernelVarsMax) {
- debugCN(kDebugScript, "ScriptInterpreter::setKernelVar() Invalid kernel var index %d!\n", index);
- return;
- }
-
- debugCN(kDebugScript, "ScriptInterpreter::setKernelVar() name = %s\n", _kernelVars[index].desc);
-
- ScriptKernelVariable var = _kernelVars[index].var;
-
- switch (var) {
-
- case kKernelTrigger:
- _vm->_kernel->trigger = toInteger(value);
- debugCN(kDebugScript, "kKernelTrigger -> %d\n", toInteger(value));
- break;
-
- case kKernelTriggerMode:
- _vm->_kernel->triggerMode = (KernelTriggerType)toInteger(value);
- debugCN(kDebugScript, "kKernelTrigger -> %d\n", toInteger(value));
- break;
-
- case kKernelContinueHandlingTrigger:
- _vm->_kernel->daemonTriggerAvailable = (toInteger(value) != 0);
- debugCN(kDebugScript, "kKernelContinueHandlingTrigger -> %d\n", toInteger(value));
- break;
-
- case kGameNewRoom:
- _vm->_kernel->newRoom = toInteger(value);
- debugCN(kDebugScript, "kGameNewRoom -> %d\n", toInteger(value));
- break;
-
- case kPlayerCommandReady:
- // TODO
- debugCN(kDebugScript, "kPlayerCommandReady -> %d\n", toInteger(value));
- break;
-
- default:
- debugCN(kDebugScript, "ScriptInterpreter::setKernelVar() Invalid kernel var %d!\n", var);
- //g_system->delayMillis(2000);
-
- }
-
-}
-
-} // End of namespace M4
diff --git a/engines/m4/script.h b/engines/m4/script.h
deleted file mode 100644
index 22f07fd062..0000000000
--- a/engines/m4/script.h
+++ /dev/null
@@ -1,463 +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 M4_SCRIPT_H
-#define M4_SCRIPT_H
-
-#include "common/file.h"
-#include "common/stream.h"
-#include "common/hashmap.h"
-#include "common/str.h"
-#include "common/stack.h"
-
-#include "m4/woodscript.h"
-
-namespace M4 {
-
-const unsigned long kScriptFileMagic = 0x5845344D;
-const unsigned long kScriptFileVersion = 1;
-
-enum ScriptValueType {
- kInteger,
- kConstString,
- kLogicVar,
- kLogicVarRef,
- kGameVar,
- kKernelVar,
- kDataRef,
- kRegister,
- kStackVar
-};
-
-enum ScriptDataType {
- kStreamBreakSeries,
- kStreamPlaySeries,
- kSaidArray,
- kParserArray,
- kSpeechArray,
- kCreditsArray,
- kInvObj,
- kMineRoom,
- kButtonItem
-};
-
-class ScriptInterpreter;
-
-class StringTable {
-public:
- StringTable();
- ~StringTable();
- void load(Common::File *fd);
- int size() { return _strings.size(); }
- const char *operator[](uint32 index) const {
- assert(index < _strings.size() );
- return _strings[index];
- }
-protected:
- Common::Array<const char*> _strings;
- char *_stringsData;
-};
-
-struct ScriptValue {
-
- ScriptValueType type;
-
- union {
- int value;
- };
-
- ScriptValue() : type(kInteger), value(0) {}
- ScriptValue(ScriptValueType itype, int ivalue) : type(itype), value(ivalue) {}
-
- ScriptValue(const int intValue) : type(kInteger), value(intValue) {}
-
- ScriptValue& operator=(const int intValue) {
- type = kInteger;
- value = intValue;
- return *this;
- }
-
-};
-
-class ScriptDataItem {
-public:
- ScriptDataItem() : _inter(NULL) {}
- ScriptDataItem(ScriptInterpreter *inter) : _inter(inter) {}
- virtual ~ScriptDataItem() {}
- virtual void load(Common::File *fd) = 0;
- static int type() { return -1; }
-protected:
- ScriptInterpreter *_inter;
-};
-
-class ScriptDataCache {
-public:
- ScriptDataCache(ScriptInterpreter *inter) : _inter(inter) {
- }
- ~ScriptDataCache() {
- clear();
- }
-
- // WORKAROUND: The old prototype for this function was:
- // template<class T> T *load(Common::File *fd, uint32 ofs);
- // that caused a parser error in g++ 3.3.6 used by our
- // "motoezx" target of our buildbot. The actual parser
- // error happended, when calling the function like this:
- // "T *result = _dataCache->load<T>(_scriptFile, _data[value.value]->offset);"
- // in ScriptInterpreter::toData. To work around this
- // we moved the return value as parameter instead.
- template<class T>
- void load(Common::File *fd, uint32 ofs, T *&item) {
- if (_cache.contains(ofs)) {
- item = (T*)(_cache[ofs]);
- } else {
- item = new T(_inter);
- fd->seek(ofs + 4); // "+4" skips the data size
- item->load(fd);
- _cache[ofs] = item;
- }
- }
- void clear() {
- // TODO: Free all cached items
- }
-protected:
- typedef Common::HashMap<uint32, ScriptDataItem*> CacheMap;
- CacheMap _cache;
- ScriptInterpreter *_inter;
-};
-
-struct SeriesStreamBreakItem {
- int frameNum;
- const char *digiName;
- int digiChannel;
- int digiVolume;
- int trigger;
- int flags;
- ScriptValue variable;
- int value;
-};
-
-class SeriesStreamBreakList : public ScriptDataItem {
-public:
- SeriesStreamBreakList(ScriptInterpreter *inter) : ScriptDataItem(inter) {}
- ~SeriesStreamBreakList();
- void load(Common::File *fd);
- int size() const { return _items.size(); }
- SeriesStreamBreakItem *operator[](int index) const { return _items[index]; }
- static int type() { return 0; }
-protected:
- Common::Array<SeriesStreamBreakItem*> _items;
-};
-
-struct SaidArrayItem {
- const char *itemName;
- const char *digiNameLook;
- const char *digiNameTake;
- const char *digiNameGear;
-};
-
-class SaidArray : public ScriptDataItem {
-public:
- SaidArray(ScriptInterpreter *inter) : ScriptDataItem(inter) {}
- ~SaidArray();
- void load(Common::File *fd);
- int size() const { return _items.size(); }
- SaidArrayItem *operator[](int index) const { return _items[index]; }
- static int type() { return 2; }
-protected:
- Common::Array<SaidArrayItem*> _items;
-};
-
-struct ParserArrayItem {
- const char *w0;
- const char *w1;
- int trigger;
- ScriptValue testVariable;
- int testValue;
- ScriptValue variable;
- int value;
-};
-
-class ParserArray : public ScriptDataItem {
-public:
- ParserArray(ScriptInterpreter *inter) : ScriptDataItem(inter) {}
- ~ParserArray();
- void load(Common::File *fd);
- int size() const { return _items.size(); }
- ParserArrayItem *operator[](int index) const { return _items[index]; }
- static int type() { return 3; }
-protected:
- Common::Array<ParserArrayItem*> _items;
-};
-
-class ScriptFunction {
-public:
- ScriptFunction(ScriptInterpreter *inter);
- ~ScriptFunction();
- void load(Common::File *fd);
- void jumpAbsolute(uint32 ofs);
- void jumpRelative(int32 ofs);
- byte readByte();
- uint32 readUint32();
-protected:
- ScriptInterpreter *_inter;
- Common::SeekableReadStream *_code;
-};
-
-struct ScriptFunctionEntry {
- uint32 offset;
- ScriptFunction *func;
- ScriptFunctionEntry(uint32 funcOffset) : offset(funcOffset), func(NULL) {
- }
-};
-
-struct ScriptDataEntry {
- uint32 offset;
- ScriptDataType type;
- ScriptDataEntry(uint32 dataOffset, ScriptDataType dataType) : offset(dataOffset), type(dataType) {
- }
-};
-
-enum ScriptKernelVariable {
- kGameLanguage,
- kGameVersion,
- kGameCurrentRoom,
- kGameNewRoom,
- kGamePreviousRoom,
- kGameNewSection,
- kKernelTrigger,
- kKernelTriggerMode,
- kKernelFirstFade,
- kKernelSuppressFadeUp,
- kKernelContinueHandlingTrigger,
- kKernelUseDebugMonitor,
- kPlayerPosX,
- kPlayerPosY,
- kPlayerFacing,
- kPlayerScale,
- kPlayerDepth,
- kPlayerWalkX,
- kPlayerWalkY,
- kPlayerReadyToWalk,
- kPlayerNeedToWalk,
- kPlayerCommandReady,
- kPlayerWalkerInThisScene,
- kPlayerVerb,
- kWalkerInitialized,
- kCallDaemonEveryLoop,
- kConvCurrentTalker,
- kConvCurrentNode,
- kConvCurrentEntry,
- kConvSoundToPlay,
- kInterfaceVisible
-};
-
-class ScriptInterpreter {
-public:
- ScriptInterpreter(MadsM4Engine *vm);
- ~ScriptInterpreter();
- /* Opens a M4 program file */
- void open(const char *filename);
- void close();
- /* Loads a function via the index. Creates the function object if it's not already loaded. */
- ScriptFunction *loadFunction(uint32 index);
- /* Loads a function via the exported name. */
- ScriptFunction *loadFunction(const Common::String &name);
- /* Unload all loaded functions.
- This should be called before entering a new room to free unused functions. */
- void unloadFunctions();
- //TODO void unloadData();
- /* Executes a function. */
- int runFunction(ScriptFunction *scriptFunction);
-
- void push(const ScriptValue &value);
- void pop(ScriptValue &value);
- void dumpStack();
- void dumpRegisters();
- void dumpGlobalVars();
-
- int toInteger(const ScriptValue &value);
-
- const char *toString(const ScriptValue &value);
-
- // Is this ok?
- template<class T>
- const T& toData(const ScriptValue &value) {
- debugCN(kDebugScript, "ScriptInterpreter::toData() index = %d; type = %d; max = %d\n", value.value, _data[value.value]->type, _data.size());
- assert((uint32)value.value < _data.size());
- T *result = 0;
- _dataCache->load(_scriptFile, _data[value.value]->offset, result);
- return *result;
- }
-
- const char *getGlobalString(int index) const {
- return _constStrings[index];
- }
-
- const char *loadGlobalString(Common::File *fd);
-
- void test();
-
-protected:
-
- MadsM4Engine *_vm;
-
- typedef Common::HashMap<Common::String, uint32, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> FunctionNameMap;
- Common::File *_scriptFile;
- /* An array of offset/ScriptFunction* pairs for each script function */
- Common::Array<ScriptFunctionEntry*> _functions;
-
- // DEBUG only
- Common::Array<Common::String> _scriptFunctionNames;
-
- Common::Array<ScriptDataEntry*> _data;
- /* Maps function name -> index of function in _functions array */
- FunctionNameMap _functionNames;
- StringTable _constStrings;
- /* The currently running function */
- ScriptFunction *_runningFunction;
- int _localStackPtr;
-
- ScriptValue _registers[8];
-
- ScriptValue _stack[512];
- int _stackPtr;
-
- int _globalVarCount;
- ScriptValue _globalVars[1024];
-
- int _logicGlobals[512];
-
- int _cmpFlags;
-
- ScriptDataCache *_dataCache;
-
- int _lineNum;
-
- typedef int (ScriptInterpreter::*KernelFunction)();
- struct KernelFunctionEntry {
- KernelFunction proc;
- const char *desc;
- };
- const KernelFunctionEntry *_kernelFunctions;
- uint16 _kernelFunctionsMax;
-
- struct KernelVariableEntry {
- ScriptKernelVariable var;
- const char *desc;
- };
- const KernelVariableEntry *_kernelVars;
- int16 _kernelVarsMax;
-
- void initScriptKernel();
-
- void loadValue(ScriptValue &value);
- void writeValue(ScriptValue &value);
- void copyValue(ScriptValue &destValue, ScriptValue &sourceValue);
- void derefValue(ScriptValue &value);
-
- void callKernelFunction(uint32 index);
- ScriptValue getArg(uint32 index);
- void dumpArgs(uint32 count);
-
- void callFunction(uint32 index);
-
- bool execOpcode(byte opcode);
-
- // Kernel functions
- int o1_handleStreamBreak();
- int o1_handlePlayBreak();
- int o1_dispatchTriggerOnSoundState();
- int o1_getRangedRandomValue();
- int o1_getTicks();
- int o1_preloadSound();
- int o1_unloadSound();
- int o1_stopSound();
- int o1_playSound();
- int o1_playLoopingSound();
- int o1_setSoundVolume();
- int o1_getSoundStatus();
- int o1_getSoundDuration();
- int o1_loadSeries();
- int o1_unloadSeries();
- int o1_showSeries();
- int o1_playSeries();
- int o1_setSeriesFrameRate();
- int o1_playBreakSeries();
- int o1_preloadBreakSeries();
- int o1_unloadBreakSeries();
- int o1_startBreakSeries();
- int o1_dispatchTrigger();
- int o1_terminateMachine();
- int o1_sendWoodScriptMessage();
- int o1_runConversation();
- int o1_loadConversation();
- int o1_exportConversationValue();
- int o1_exportConversationPointer();
- int o1_fadeInit();
- int o1_fadeSetStart();
- int o1_fadeToBlack();
- int o1_initPaletteCycle();
- int o1_stopPaletteCycle();
- int o1_setHotspot();
- int o1_hideWalker();
- int o1_showWalker();
- int o1_setWalkerLocation();
- int o1_setWalkerFacing();
- int o1_walk();
- int o1_overrideCrunchTime();
- int o1_addBlockingRect();
- int o1_triggerTimerProc();
- int o1_setPlayerCommandsAllowed();
- int o1_getPlayerCommandsAllowed();
- int o1_updatePlayerInfo();
- int o1_hasPlayerSaid();
- int o1_hasPlayerSaidAny();
- int o1_playerHotspotWalkOverride();
- int o1_setPlayerFacingAngle();
- int o1_disablePlayerFadeToBlack();
- int o1_enablePlayer();
- int o1_disablePlayer();
- int o1_freshenSentence();
- int o1_playerHasItem();
- int o1_playerGiveItem();
- int o1_moveObject();
- int o1_setStopSoundsBetweenRooms();
- int o1_backupPalette();
- int o1_unloadWilburWalker();
- int o1_globalTriggerProc();
- int o1_wilburSpeech();
- int o1_wilburSaid();
- int o1_wilburParse();
- int o1_wilburTalk();
- int o1_wilburFinishedTalking();
- //int ();
-
- // Kernel vars
- void getKernelVar(int index, ScriptValue &value);
- void setKernelVar(int index, const ScriptValue &value);
-
-};
-
-} // End of namespace M4
-
-#endif
diff --git a/engines/m4/scripttab.h b/engines/m4/scripttab.h
deleted file mode 100644
index 3264ae743c..0000000000
--- a/engines/m4/scripttab.h
+++ /dev/null
@@ -1,135 +0,0 @@
-/* This file has been autogenerated by the linker.
- Do not edit it or merge it with script.cpp! */
-#define FUNCTION(x) { &ScriptInterpreter::x, #x }
- static KernelFunctionEntry kernelFunctions[] = {
- /* 000 */
- FUNCTION(o1_handleStreamBreak),
- FUNCTION(o1_handlePlayBreak),
- FUNCTION(o1_dispatchTriggerOnSoundState),
- FUNCTION(o1_getRangedRandomValue),
- /* 004 */
- FUNCTION(o1_getTicks),
- FUNCTION(o1_preloadSound),
- FUNCTION(o1_unloadSound),
- FUNCTION(o1_stopSound),
- /* 008 */
- FUNCTION(o1_playSound),
- FUNCTION(o1_playLoopingSound),
- FUNCTION(o1_setSoundVolume),
- FUNCTION(o1_getSoundStatus),
- /* 012 */
- FUNCTION(o1_getSoundDuration),
- FUNCTION(o1_loadSeries),
- FUNCTION(o1_unloadSeries),
- FUNCTION(o1_showSeries),
- /* 016 */
- FUNCTION(o1_playSeries),
- FUNCTION(o1_setSeriesFrameRate),
- FUNCTION(o1_playBreakSeries),
- FUNCTION(o1_preloadBreakSeries),
- /* 020 */
- FUNCTION(o1_unloadBreakSeries),
- FUNCTION(o1_startBreakSeries),
- FUNCTION(o1_dispatchTrigger),
- FUNCTION(o1_terminateMachine),
- /* 024 */
- FUNCTION(o1_sendWoodScriptMessage),
- FUNCTION(o1_runConversation),
- FUNCTION(o1_runConversation),
- FUNCTION(o1_loadConversation),
- /* 028 */
- FUNCTION(o1_exportConversationValue),
- FUNCTION(o1_exportConversationPointer),
- FUNCTION(o1_runConversation),
- FUNCTION(o1_fadeInit),
- /* 032 */
- FUNCTION(o1_fadeSetStart),
- FUNCTION(o1_fadeToBlack),
- FUNCTION(o1_initPaletteCycle),
- FUNCTION(o1_stopPaletteCycle),
- /* 036 */
- FUNCTION(o1_setHotspot),
- FUNCTION(o1_hideWalker),
- FUNCTION(o1_showWalker),
- FUNCTION(o1_setWalkerLocation),
- /* 040 */
- FUNCTION(o1_setWalkerFacing),
- FUNCTION(o1_walk),
- FUNCTION(o1_overrideCrunchTime),
- FUNCTION(o1_addBlockingRect),
- /* 044 */
- FUNCTION(o1_triggerTimerProc),
- FUNCTION(o1_setPlayerCommandsAllowed),
- FUNCTION(o1_getPlayerCommandsAllowed),
- FUNCTION(o1_updatePlayerInfo),
- /* 048 */
- FUNCTION(o1_hasPlayerSaid),
- FUNCTION(o1_hasPlayerSaidAny),
- FUNCTION(o1_playerHotspotWalkOverride),
- FUNCTION(o1_setPlayerFacingAngle),
- /* 052 */
- FUNCTION(o1_disablePlayerFadeToBlack),
- FUNCTION(o1_enablePlayer),
- FUNCTION(o1_disablePlayer),
- FUNCTION(o1_freshenSentence),
- /* 056 */
- FUNCTION(o1_playerHasItem),
- FUNCTION(o1_playerGiveItem),
- FUNCTION(o1_moveObject),
- FUNCTION(o1_setStopSoundsBetweenRooms),
- /* 060 */
- FUNCTION(o1_backupPalette),
- FUNCTION(o1_unloadWilburWalker),
- FUNCTION(o1_globalTriggerProc),
- FUNCTION(o1_wilburSpeech),
- /* 064 */
- FUNCTION(o1_wilburParse),
- FUNCTION(o1_wilburSaid),
- FUNCTION(o1_wilburTalk),
- FUNCTION(o1_wilburFinishedTalking)
- };
-#undef FUNCTION
-
-#define VARIABLE(x) { x, #x }
- static KernelVariableEntry kernelVars[] = {
- /* 000 */
- VARIABLE(kGameLanguage),
- VARIABLE(kGameVersion),
- VARIABLE(kGameCurrentRoom),
- VARIABLE(kGameNewRoom),
- /* 004 */
- VARIABLE(kGamePreviousRoom),
- VARIABLE(kGameNewSection),
- VARIABLE(kKernelTrigger),
- VARIABLE(kKernelTriggerMode),
- /* 008 */
- VARIABLE(kKernelFirstFade),
- VARIABLE(kKernelSuppressFadeUp),
- VARIABLE(kKernelContinueHandlingTrigger),
- VARIABLE(kKernelUseDebugMonitor),
- /* 012 */
- VARIABLE(kPlayerPosX),
- VARIABLE(kPlayerPosY),
- VARIABLE(kPlayerFacing),
- VARIABLE(kPlayerScale),
- /* 016 */
- VARIABLE(kPlayerDepth),
- VARIABLE(kPlayerWalkX),
- VARIABLE(kPlayerWalkY),
- VARIABLE(kPlayerReadyToWalk),
- /* 020 */
- VARIABLE(kPlayerNeedToWalk),
- VARIABLE(kPlayerCommandReady),
- VARIABLE(kPlayerWalkerInThisScene),
- VARIABLE(kPlayerVerb),
- /* 024 */
- VARIABLE(kWalkerInitialized),
- VARIABLE(kCallDaemonEveryLoop),
- VARIABLE(kConvCurrentTalker),
- VARIABLE(kConvCurrentNode),
- /* 028 */
- VARIABLE(kConvCurrentEntry),
- VARIABLE(kConvSoundToPlay),
- VARIABLE(kInterfaceVisible)
- };
-#undef VARIABLE
diff --git a/engines/m4/sound.cpp b/engines/m4/sound.cpp
deleted file mode 100644
index 76eae8a661..0000000000
--- a/engines/m4/sound.cpp
+++ /dev/null
@@ -1,276 +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 "m4/m4.h"
-#include "m4/sound.h"
-#include "m4/compression.h"
-
-#include "common/stream.h"
-#include "common/textconsole.h"
-
-#include "audio/audiostream.h"
-#include "audio/mixer.h"
-#include "audio/decoders/raw.h"
-
-namespace M4 {
-
-Sound::Sound(MadsM4Engine *vm, Audio::Mixer *mixer, int volume) :
- _vm(vm), _mixer(mixer) {
-
- for (int i = 0; i < SOUND_HANDLES; i++)
- _handles[i].type = kFreeHandle;
-
- _dsrFileLoaded = false;
-
- setVolume(volume);
-}
-
-Sound::~Sound() {
- unloadDSRFile();
-}
-
-SndHandle *Sound::getHandle() {
- for (int i = 0; i < SOUND_HANDLES; i++) {
- if (_handles[i].type == kFreeHandle)
- return &_handles[i];
-
- if (!_mixer->isSoundHandleActive(_handles[i].handle)) {
- _handles[i].type = kFreeHandle;
- return &_handles[i];
- }
- }
-
- error("Sound::getHandle(): Too many sound handles");
- return NULL; // for compilers that don't support NORETURN
-}
-
-bool Sound::isHandleActive(SndHandle *handle) {
- return (_mixer->isSoundHandleActive(handle->handle));
-}
-
-void Sound::playSound(const char *soundName, int volume, bool loop, int channel) {
- Common::SeekableReadStream *soundStream = _vm->res()->get(soundName);
- SndHandle *handle;
- if (channel < 0) {
- handle = getHandle();
- } else {
- if (_handles[channel].type == kFreeHandle) {
- handle = &_handles[channel];
- } else {
- warning("Attempted to play a sound on a channel that isn't free");
- return;
- }
- }
-
- int bufferSize = soundStream->size();
- byte *buffer = new byte[bufferSize];
- soundStream->read(buffer, bufferSize);
- _vm->res()->toss(soundName);
-
- handle->type = kEffectHandle;
-
- _vm->res()->toss(soundName);
-
- // Sound format is 8bit mono, unsigned, 11025kHz
- Audio::AudioStream *stream = Audio::makeLoopingAudioStream(
- Audio::makeRawStream(buffer, bufferSize, 11025, Audio::FLAG_UNSIGNED),
- loop ? 0 : 1);
- _mixer->playStream(Audio::Mixer::kSFXSoundType, &handle->handle, stream, -1, volume);
-}
-
-void Sound::playSound(int soundNum) {
- warning("TODO: playSound(%d)", soundNum);
-}
-
-void Sound::pauseSound() {
- for (int i = 0; i < SOUND_HANDLES; i++) {
- if (_handles[i].type == kEffectHandle)
- _mixer->pauseHandle(_handles[i].handle, true);
- }
-}
-
-void Sound::resumeSound() {
- for (int i = 0; i < SOUND_HANDLES; i++) {
- if (_handles[i].type == kEffectHandle)
- _mixer->pauseHandle(_handles[i].handle, false);
- }
-}
-
-void Sound::stopSound(int channel) {
- if (channel >= 0) {
- if (_handles[channel].type == kEffectHandle) {
- _mixer->stopHandle(_handles[channel].handle);
- _handles[channel].type = kFreeHandle;
- return;
- } else {
- warning("Attempted to stop a sound on a channel that is already free");
- return;
- }
- }
-
- for (int i = 0; i < SOUND_HANDLES; i++) {
- if (_handles[i].type == kEffectHandle) {
- _mixer->stopHandle(_handles[i].handle);
- _handles[i].type = kFreeHandle;
- }
- }
-}
-
-void Sound::playVoice(const char *soundName, int volume) {
- Common::SeekableReadStream *soundStream = _vm->res()->get(soundName);
- SndHandle *handle = getHandle();
- byte *buffer;
-
- buffer = (byte *)malloc(soundStream->size());
- soundStream->read(buffer, soundStream->size());
-
- handle->type = kEffectHandle;
-
- _vm->res()->toss(soundName);
-
- // Voice format is 8bit mono, unsigned, 11025kHz
- Audio::AudioStream *stream = Audio::makeRawStream(buffer, soundStream->size(), 11025, Audio::FLAG_UNSIGNED);
- _mixer->playStream(Audio::Mixer::kSFXSoundType, &handle->handle, stream, -1, volume);
-}
-
-void Sound::pauseVoice() {
- for (int i = 0; i < SOUND_HANDLES; i++)
- if (_handles[i].type == kVoiceHandle)
- _mixer->pauseHandle(_handles[i].handle, true);
-}
-
-void Sound::resumeVoice() {
- for (int i = 0; i < SOUND_HANDLES; i++)
- if (_handles[i].type == kVoiceHandle)
- _mixer->pauseHandle(_handles[i].handle, false);
-}
-
-void Sound::stopVoice() {
- for (int i = 0; i < SOUND_HANDLES; i++)
- if (_handles[i].type == kVoiceHandle) {
- _mixer->stopHandle(_handles[i].handle);
- _handles[i].type = kFreeHandle;
- }
-}
-
-void Sound::stopAll() {
- stopVoice();
- stopSound();
-}
-
-void Sound::setVolume(int volume) {
- _mixer->setVolumeForSoundType(Audio::Mixer::kSFXSoundType, volume);
- _mixer->setVolumeForSoundType(Audio::Mixer::kSpeechSoundType, volume);
-}
-
-void Sound::loadDSRFile(const char *fileName) {
- if (_dsrFileLoaded)
- unloadDSRFile();
-
- Common::SeekableReadStream *fileStream = _vm->res()->get(fileName);
-
- sprintf(_dsrFile.fileName, "%s", fileName);
-
- // Read header
- _dsrFile.entryCount = fileStream->readUint16LE();
- //warning(kDebugSound, "DSR has %i entries\n", _dsrFile.entryCount);
-
- for (int i = 0; i < _dsrFile.entryCount; i++) {
- DSREntry newEntry;
- newEntry.frequency = fileStream->readUint16LE();
- newEntry.channels = fileStream->readUint32LE();
- newEntry.compSize = fileStream->readUint32LE();
- newEntry.uncompSize = fileStream->readUint32LE();
- newEntry.offset = fileStream->readUint32LE();
- _dsrFile.dsrEntries.push_back(newEntry);
-
- /*
- warning(kDebugSound, "%i: ", i);
- warning(kDebugSound, "frequency: %i ", newEntry->frequency);
- warning(kDebugSound, "channels: %i ", newEntry->channels);
- warning(kDebugSound, "comp: %i ", newEntry.compSize);
- warning(kDebugSound, "uncomp: %i ", newEntry.uncompSize);
- warning(kDebugSound, "offset: %i ", newEntry->offset);
- warning(kDebugSound, "\n");
- */
- }
-
- _vm->res()->toss(fileName);
-
- _dsrFileLoaded = true;
-}
-
-void Sound::unloadDSRFile() {
- if (!_dsrFileLoaded)
- return;
-
- _dsrFile.dsrEntries.clear();
-
- _dsrFile.entryCount = 0;
- strcpy(_dsrFile.fileName, "");
- _dsrFileLoaded = false;
-}
-
-void Sound::playDSRSound(int soundIndex, int volume, bool loop) {
- if (!_dsrFileLoaded) {
- warning("DSR file not loaded, not playing sound");
- return;
- }
-
- if (soundIndex < 0 || soundIndex > _dsrFile.entryCount - 1) {
- warning("Invalid sound index: %i, not playing sound", soundIndex);
- return;
- }
-
- SndHandle *handle = getHandle();
-
- handle->type = kEffectHandle;
-
- // Get sound data
- FabDecompressor fab;
- byte *compData = new byte[_dsrFile.dsrEntries[soundIndex].compSize];
- byte *buffer = new byte[_dsrFile.dsrEntries[soundIndex].uncompSize];
- Common::SeekableReadStream *fileStream = _vm->res()->get(_dsrFile.fileName);
- fileStream->seek(_dsrFile.dsrEntries[soundIndex].offset, SEEK_SET);
- fileStream->read(compData, _dsrFile.dsrEntries[soundIndex].compSize);
- _vm->res()->toss(_dsrFile.fileName);
-
- fab.decompress(compData, _dsrFile.dsrEntries[soundIndex].compSize,
- buffer, _dsrFile.dsrEntries[soundIndex].uncompSize);
-
- // Play sound
- Audio::AudioStream *stream = Audio::makeLoopingAudioStream(
- Audio::makeRawStream(buffer,
- _dsrFile.dsrEntries[soundIndex].uncompSize,
- _dsrFile.dsrEntries[soundIndex].frequency, Audio::FLAG_UNSIGNED),
- loop ? 0 : 1);
- _mixer->playStream(Audio::Mixer::kSFXSoundType, &handle->handle, stream, -1, volume);
-
- /*
- // Dump the sound file
- FILE *destFile = fopen("sound.raw", "wb");
- fwrite(_dsrFile.dsrEntries[soundIndex]->data, _dsrFile.dsrEntries[soundIndex].uncompSize, 1, destFile);
- fclose(destFile);
- */
-}
-
-} // End of namespace M4
diff --git a/engines/m4/sound.h b/engines/m4/sound.h
deleted file mode 100644
index 99a2292d83..0000000000
--- a/engines/m4/sound.h
+++ /dev/null
@@ -1,110 +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.
- *
- */
-
-// Sound class
-
-#ifndef M4_SOUND_H
-#define M4_SOUND_H
-
-#include "common/file.h"
-#include "common/array.h"
-#include "audio/mixer.h"
-#include "audio/decoders/mp3.h"
-#include "audio/decoders/vorbis.h"
-#include "audio/decoders/flac.h"
-
-namespace M4 {
-
-#define SOUND_HANDLES 10
-
-enum SOUND_FLAGS {
- SOUND_LOOP = 1
-};
-
-enum sndHandleType {
- kFreeHandle,
- kEffectHandle,
- kVoiceHandle
-};
-
-struct SndHandle {
- Audio::SoundHandle handle;
- sndHandleType type;
-};
-
-struct DSREntry {
- int16 frequency;
- int channels;
- int32 compSize;
- int32 uncompSize;
- int32 offset;
-};
-
-struct DSRFile {
- char fileName[20];
- int entryCount;
- Common::Array<DSREntry> dsrEntries;
-};
-
-class MadsM4Engine;
-
-class Sound {
-public:
-
- Sound(MadsM4Engine *vm, Audio::Mixer *mixer, int volume);
- ~Sound();
-
- void playSound(const char *soundName, int volume, bool loop, int channel = -1);
- void playSound(int soundNum);
- void pauseSound();
- void resumeSound();
- void stopSound(int channel = -1);
-
- void playVoice(const char *soundName, int volume);
- void pauseVoice();
- void resumeVoice();
- void stopVoice();
-
- void stopAll();
-
- void setVolume(int volume);
-
- bool isHandleActive(SndHandle *handle);
- SndHandle *getHandle();
-
- void loadDSRFile(const char *fileName);
- void unloadDSRFile();
- void playDSRSound(int soundIndex, int volume, bool loop);
-
- private:
-
- MadsM4Engine *_vm;
- Audio::Mixer *_mixer;
- SndHandle _handles[SOUND_HANDLES];
-
- DSRFile _dsrFile;
- bool _dsrFileLoaded;
-};
-
-} // End of namespace M4
-
-#endif
diff --git a/engines/m4/sprite.cpp b/engines/m4/sprite.cpp
deleted file mode 100644
index d0741732f3..0000000000
--- a/engines/m4/sprite.cpp
+++ /dev/null
@@ -1,207 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#include "common/rect.h"
-#include "common/textconsole.h"
-
-#include "m4/globals.h"
-#include "m4/graphics.h"
-#include "m4/m4.h"
-#include "m4/resource.h"
-#include "m4/sprite.h"
-
-namespace M4 {
-
-enum {
- kEndOfLine = 0,
- kEndOfSprite = 1,
- kMarker = 2
-};
-
-M4Sprite::M4Sprite(Common::SeekableReadStream* source, int xOfs, int yOfs, int widthVal, int heightVal, bool decodeRle, uint8 encodingVal)
- : M4Surface(widthVal, heightVal), encoding(encodingVal) {
-
- if (_vm->isM4()) {
- if (decodeRle) {
- loadRle(source);
- } else {
- // Raw sprite data, load directly
- byte *dst = getBasePtr();
- source->read(dst, widthVal * heightVal);
- }
- } else {
- loadMadsSprite(source);
- }
-
- x = xOffset = xOfs;
- y = yOffset = yOfs;
-
-}
-
-void M4Sprite::loadRle(Common::SeekableReadStream* rleData) {
- byte *dst = getBasePtr();
- while (1) {
- byte len = rleData->readByte();
- if (len == 0) {
- len = rleData->readByte();
- if (len <= kMarker) {
- if (len == kEndOfSprite)
- break;
- } else {
- while (len--) {
- *dst++ = rleData->readByte();
- }
- }
- } else {
- byte value = rleData->readByte();
- while (len--)
- *dst++ = value;
- }
- }
-}
-
-void M4Sprite::loadDeltaRle(Common::SeekableReadStream* rleData, int destX, int destY) {
- int lineNum = 0;
- byte *dst = getBasePtr(destX, destY);
- while (1) {
- byte len = rleData->readByte();
- if (len == 0) {
- len = rleData->readByte();
- if (len <= kMarker) {
- if (len == kEndOfLine) {
- dst = getBasePtr(destX, destY + lineNum);
- lineNum++;
- } else if (len == kEndOfSprite)
- break;
- } else {
- while (len--) {
- byte pixel = rleData->readByte();
- if (pixel == 0)
- dst++;
- else
- *dst++ = pixel;
- /* NOTE: The change below behaved differently than the old code,
- so I put the old code back in again above.
- If the pixel value is 0, nothing should be written to the
- output buffer, since 0 means transparent. */
- //*dst++ = (pixel == 0xFD) ? 0 : pixel;
- }
- }
- } else {
- byte value = rleData->readByte();
- if (value == 0)
- dst += len;
- else
- while (len--)
- *dst++ = value;
- }
- }
-}
-
-// TODO: The sprite outlines (pixel value 0xFD) are not shown
-void M4Sprite::loadMadsSprite(Common::SeekableReadStream* source) {
- bool spriteEnd = false;
-
- // Set entire sprite contents to transparent pixels
- fillRect(bounds(), TRANSPARENT_COLOR_INDEX);
-
- // Major line loop
- for (int yp = 0; yp < h; ++yp) {
- byte *destP = getBasePtr(0, yp);
- bool newLine = false;
- byte cmd = source->readByte();
- int x2 = 0;
-
- if (cmd == 0xfc) {
- // End of entire sprite
- spriteEnd = true;
- break;
- } else if (cmd == 0xff) {
- // The entire line is empty
- newLine = true;
- } else if (cmd == 0xFD) {
- // Lines contains only run lenghs of pixels
- while (x2 < w) {
- cmd = source->readByte();
- if (cmd == 0xff) {
- // End of line reached
- newLine = true;
- break;
- }
-
- byte v = source->readByte();
- while (cmd-- > 0) {
- if (x2 < w)
- *destP++ = (v == 0xFD) ? TRANSPARENT_COLOR_INDEX : v;
- ++x2;
- }
- }
- } else {
- // Line intermixes run lengths with individual pixels
- while (x2 < w) {
- cmd = source->readByte();
- if (cmd == 0xff) {
- // End of line reached
- newLine = true;
- break;
- }
-
- if (cmd == 0xFE) {
- // Handle repeated sequence
- cmd = source->readByte();
- byte v = source->readByte();
- while (cmd-- > 0) {
- if (x2 < w) {
- *destP++ = (v == 0xFD) ? TRANSPARENT_COLOR_INDEX : v;
- }
- ++x2;
- }
- } else {
- // Handle writing out single pixel
- *destP++ = (cmd == 0xFD) ? TRANSPARENT_COLOR_INDEX : cmd;
- ++x2;
- }
- }
- }
-
- // Check if we need to scan forward to find the end of the line
- if (!newLine) {
- do {
- if (source->eos()) {
- warning("M4Sprite::loadMadsSprite: unexpected end of data");
- break;
- }
- } while (source->readByte() != 0xff);
- }
- }
-
- if (!spriteEnd) {
- byte v = source->readByte();
- assert(v == 0xFC);
- }
-}
-
-byte M4Sprite::getTransparencyIndex() const {
- return TRANSPARENT_COLOR_INDEX;
-}
-
-} // End of namespace M4
diff --git a/engines/m4/sprite.h b/engines/m4/sprite.h
deleted file mode 100644
index af49d8cbaf..0000000000
--- a/engines/m4/sprite.h
+++ /dev/null
@@ -1,121 +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 M4_SPRITE_H
-#define M4_SPRITE_H
-
-#include "common/util.h"
-#include "common/endian.h"
-#include "common/stream.h"
-#include "m4/graphics.h"
-
-/*
- TODO:
- - change DrawRequestX and RendCell
-*/
-
-namespace M4 {
-
-typedef struct
-{
- int32 x; // x position relative to GrBuff(0, 0)
- int32 y; // y position relative to GrBuff(0, 0)
- int32 scale_x; // x scale factor (can be negative for reverse draw)
- int32 scale_y; // y scale factor (can't be negative)
- uint8* depth_map; // depth code array for destination (doesn't care if srcDepth is 0)
- BGR8 *Pal; // palette for shadow draw (doesn't care if SHADOW bit is not set in Src.encoding)
- uint8* ICT; // Inverse Color Table (doesn't care if SHADOW bit is not set in Src.encoding)
- uint8 depth; // depth code for source (0 if no depth processing)
-} DrawRequestX;
-
-typedef struct
-{
- uint32 Pack;
- uint32 Stream;
- long hot_x;
- long hot_y;
- uint32 Width;
- uint32 Height;
- uint32 Comp;
- uint32 Reserved[8];
- uint8* data;
-} RendCell;
-
-#define SS_HEADER_NUM_FIELDS 14
-struct SpriteSeriesHeader {
- uint32 header;
- uint32 size;
- uint32 packing;
- uint32 frameRate;
- uint32 pixSpeed;
- uint32 maxWidth;
- uint32 maxHeight;
- uint32 reserved3;
- uint32 reserved4;
- uint32 reserved5;
- uint32 reserved6;
- uint32 reserved7;
- uint32 reserved8;
- uint32 count;
-};
-
-#define SF_HEADER_NUM_FIELDS 15
-struct SpriteFrameHeader {
- uint32 pack;
- uint32 stream;
- uint32 x;
- uint32 y;
- uint32 width;
- uint32 height;
- uint32 comp;
- uint32 reserved1;
- uint32 reserved2;
- uint32 reserved3;
- uint32 reserved4;
- uint32 reserved5;
- uint32 reserved6;
- uint32 reserved7;
- uint32 reserved8;
-};
-
-class M4Sprite : public M4Surface {
-public:
- int x, y;
- int xOffset, yOffset;
- uint8 encoding;
-
- M4Sprite(MadsM4Engine *vm): M4Surface() {}
- M4Sprite(MadsM4Engine *vm, int widthVal, int heightVal): M4Surface(widthVal, heightVal), xOffset(0), yOffset(0) {}
- // Loads a sprite from the given stream, and optionally decompresses the RLE-encoded data
- M4Sprite(Common::SeekableReadStream* source, int xOfs, int yOfs, int widthVal, int heightVal, bool decodeRle = true, uint8 encodingVal = 0);
- // Loads an RLE compressed sprite; the surface must have been created before
- void loadRle(Common::SeekableReadStream* rleData);
- void loadDeltaRle(Common::SeekableReadStream* rleData, int destX, int destY);
- void loadMadsSprite(Common::SeekableReadStream* source);
-
- byte getTransparencyIndex() const;
-protected:
-};
-
-} // End of namespace M4
-
-#endif
diff --git a/engines/m4/viewmgr.cpp b/engines/m4/viewmgr.cpp
deleted file mode 100644
index 8eb40f0f17..0000000000
--- a/engines/m4/viewmgr.cpp
+++ /dev/null
@@ -1,444 +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.
- *
- */
-
-// TODO: Views have a _coords rect, so I'm not sure if x/y is needed in the onRefresh
-
-#include "m4/m4.h"
-#include "m4/viewmgr.h"
-#include "m4/mads_anim.h"
-
-namespace M4 {
-
-void returnToMainMenuFn(MadsM4Engine *vm) {
- vm->_palette->resetColorCounts();
- vm->_palette->setMadsSystemPalette();
-
- vm->loadMenu(MAIN_MENU);
-}
-
-RectList::RectList() {
-}
-
-RectList::~RectList() {
-}
-
-void RectList::addRect(int x1, int y1, int x2, int y2) {
- addRect(Common::Rect(x1, y1, x2, y2));
-}
-
-void RectList::addRect(const Common::Rect &rect) {
- /* TODO:
- Implement the following:
- - Don't add the Rect if it's contained in any Rect in the list
- - Split up the Rect if it intersects any Rect in the list
- and add the resulting partial Rects instead
- */
- push_back(rect);
-}
-
-int RectList::find(const Common::Point &pt) {
- for (uint idx = 0; idx < size(); ++idx) {
- if (this->operator [](idx).contains(pt.x, pt.y))
- return idx;
- }
- return -1;
-}
-
-//--------------------------------------------------------------------------
-
-HotkeyList::HotkeyList(View *owner) : _view(owner) {
-}
-
-HotkeyList::~HotkeyList() {
- for (uint32 i = 0; i < _hotkeys.size(); i++)
- delete _hotkeys[i];
-}
-
-void HotkeyList::add(uint32 key, Hotkey::Callback callback) {
- _hotkeys.push_back(new Hotkey(key, callback));
-}
-
-void HotkeyList::remove(uint32 key) {
- for (uint32 i = 0; i < _hotkeys.size(); i++) {
- if (_hotkeys[i]->key == key) {
- delete _hotkeys[i];
- _hotkeys.remove_at(i);
- break;
- }
- }
-}
-
-bool HotkeyList::call(uint32 key) {
- for (uint32 i = 0; i < _hotkeys.size(); i++) {
- if (_hotkeys[i]->key == key) {
- if (_hotkeys[i]->callback)
- (_hotkeys[i]->callback)(_vm, _view, key);
- return true;
- }
- }
- return false;
-}
-
-//--------------------------------------------------------------------------
-
-// View constructor
-
-View::View(MadsM4Engine *vm, const Common::Rect &viewBounds, bool transparent)
- : M4Surface(viewBounds.width(), viewBounds.height()), _hotkeys(this), _vm(vm) {
- SCREEN_FLAGS_DEFAULT;
- _coords = viewBounds;
- _transparent = transparent;
-}
-
-View::View(MadsM4Engine *vm, int x, int y, bool transparent)
- : M4Surface(), _hotkeys(this), _vm(vm) {
- SCREEN_FLAGS_DEFAULT;
- _coords.left = x;
- _coords.top = y;
- _coords.right = _vm->_screen->width();
- _coords.bottom = _vm->_screen->height();
- _transparent = transparent;
-}
-
-void View::getCoordinates(Common::Rect &rect) {
- rect = _coords;
-}
-
-void View::extract(int *status) {
-}
-
-void View::show() {
- _screenFlags.visible = true;
- _vm->_viewManager->moveToFront(this);
- _vm->_viewManager->restore(_coords);
-}
-
-void View::hide() {
- _screenFlags.visible = false;
- _vm->_viewManager->restore(_coords);
-}
-
-void View::moveToBack() {
- _vm->_viewManager->moveToBack(this);
-}
-
-void View::moveAbsolute(int x, int y) {
- // TODO: Handle clipping and offscreen
- Common::Rect oldCoords = _coords;
- _coords.moveTo(x, y);
- _vm->_viewManager->restore(oldCoords);
- _vm->_viewManager->restore(_coords);
-}
-
-void View::moveRelative(int x, int y) {
- // TODO: Handle clipping and offscreen
- Common::Rect oldCoords = _coords;
- _coords.translate(x, y);
- _vm->_viewManager->restore(oldCoords);
- _vm->_viewManager->restore(_coords);
-}
-
-void View::resize(int newWidth, int newHeight) {
- Common::Rect oldCoords = _coords;
- if (newWidth >= 0)
- _coords.setWidth(newWidth);
- if (newHeight >= 0)
- _coords.setHeight(newHeight);
- _vm->_viewManager->restore(oldCoords);
- _vm->_viewManager->restore(_coords);
-}
-
-void View::restore(int x1, int y1, int x2, int y2) {
- _vm->_viewManager->restore(_coords.left + x1, _coords.top + y1, _coords.left + x2, _coords.top + y2);
-}
-
-void View::onRefresh(RectList *rects, M4Surface *destSurface) {
- assert(destSurface);
-
- if (rects == NULL)
- // No rect list specified, so copy entire surface
- copyTo(destSurface, _coords.left, _coords.top, _transparent ? 0 : -1);
- else {
- // Loop through the set of specified rectangles
- RectList::iterator i;
- for (i = rects->begin(); i != rects->end(); ++i) {
- Common::Rect &destRect = *i;
- Common::Rect srcBounds(destRect.left - _coords.left, destRect.top - _coords.top,
- destRect.right - _coords.left, destRect.bottom - _coords.top);
- copyTo(destSurface, srcBounds, destRect.left, destRect.top, _transparent ? 0 : -1);
- }
- }
-}
-
-//--------------------------------------------------------------------------
-
-ViewManager::ViewManager(MadsM4Engine *vm): _systemHotkeys(HotkeyList(NULL)), _vm(vm) {
- _captureScreen = NULL;
- _captureEvents = false;
-}
-
-ViewManager::~ViewManager() {
- // Delete any remaining active views
- ListIterator i;
- for (i = _views.begin(); i != _views.end(); ++i)
- delete (*i);
-}
-
-void ViewManager::addView(View *view) {
- _views.push_back(view);
- moveToFront(view);
-}
-
-// Warning: After calling this method, the passed view object will no longer be valid
-
-void ViewManager::deleteView(View *view) {
- _views.remove(view);
- delete view;
-}
-
-void ViewManager::handleEvents(const Common::Event &event) {
-}
-
-void ViewManager::handleKeyboardEvents(uint32 keycode) {
- Common::Point mousePos = _vm->_mouse->currentPos();
- View *view;
- bool blockedFlag;
- bool foundFlag;
- bool handledFlag;
-
- // Scan view list for one which accepts or blocks keyboard events. If one is found,
- // then the event is passed to it
-
- view = NULL;
- handledFlag = false;
- foundFlag = false;
- blockedFlag = false;
-
- // Loop from the front to back view
- ListIterator i;
- for (i = _views.reverse_begin(); (i != _views.end()) && !foundFlag; --i) {
- view = *i;
- if (!view->isVisible()) continue;
-
- if (view->screenFlags().blocks & SCREVENT_KEY)
- blockedFlag = true;
- if (view->screenFlags().get & SCREVENT_KEY) {
- foundFlag = true;
- handledFlag = (view->onEvent)(KEVENT_KEY, keycode, mousePos.x, mousePos.y, _captureEvents);
- if (_captureEvents)
- _captureScreen = view;
- }
- }
-
- // Scan view list for one with a hotkey list, aborting if a view is found that either
- // blocks keyboard events, or has a hotkey list that includes the keycode
-
- blockedFlag = false;
- for (i = _views.reverse_begin(); (i != _views.end()) && !foundFlag && !blockedFlag; --i) {
- view = *i;
- if (!view->isVisible()) continue;
-
- if (view->screenFlags().blocks & SCREVENT_KEY)
- blockedFlag = true;
- if (view->screenFlags().get & SCREVENT_KEY) {
- if (view->hotkeys().call(keycode)) {
- handledFlag = true;
- _captureEvents = false;
- //_vm->_dialogs->keyMouseCollision(); // TODO
- }
- }
- }
-
- // Final check: if no view handled or blocked the key, check against the system hotkey list
-
- if (!handledFlag && !blockedFlag) {
- handledFlag = _systemHotkeys.call(keycode);
- if (handledFlag) {
- _captureEvents = false;
- //_vm->_dialogs->keyMouseCollision(); // TODO
- }
- }
-}
-
-void ViewManager::handleMouseEvents(M4EventType event) {
- Common::Point mousePos = _vm->_mouse->currentPos();
- ListIterator i;
- View *view;
- bool blockedFlag;
- bool foundFlag;
-
- // If a window sets the _captureEvents flag to true, it will receive all events until
- // it sets it to false, even if it's not the top window
- if (_captureEvents) {
- assert(_captureScreen);
- if (_captureScreen->screenFlags().get & SCREVENT_MOUSE)
- (_captureScreen->onEvent)(event, 0, mousePos.x, mousePos.y, _captureEvents);
-
- } else {
- blockedFlag = false;
- foundFlag = false;
- view = NULL;
-
- // Loop from the front to back view
- for (i = _views.reverse_begin(); (i != _views.end()) && !foundFlag && !blockedFlag; --i) {
- view = *i;
- if (!view->isVisible()) continue;
-
- if (view->screenFlags().blocks & SCREVENT_MOUSE)
- blockedFlag = true;
- if ((view->screenFlags().get & SCREVENT_MOUSE) && view->isInside(mousePos.x, mousePos.y))
- foundFlag = true;
- }
-
- if (foundFlag)
- view->onEvent(event, 0, mousePos.x, mousePos.y, _captureEvents);
- else
- _captureEvents = false;
- if (_captureEvents)
- _captureScreen = view;
- }
-}
-
-void ViewManager::restore(int x1, int y1, int x2, int y2) {
- RectList *rl = new RectList();
- Common::Rect redrawBounds(x1, y1, x2, y2);
- rl->addRect(x1, y1, x2, y2);
-
- for (ListIterator i = _views.begin(); i != _views.end(); ++i) {
- View *v = *i;
-
- if (v->isVisible() && v->bounds().intersects(redrawBounds))
- v->onRefresh(rl, _vm->_screen);
- }
-
- _vm->_screen->update();
-
-}
-
-void ViewManager::restore(const Common::Rect &rect) {
- restore(rect.left, rect.top, rect.right, rect.bottom);
-}
-
-void ViewManager::moveToFront(View *view) {
- if (_views.size() < 2)
- return;
-
- _views.remove(view);
-
- ListIterator i = _views.begin();
- while ((i != _views.end()) && ((*i)->layer() <= view->layer()))
- ++i;
-
- _views.insert(i, view);
-}
-
-void ViewManager::moveToBack(View *view) {
- if (_views.size() < 2)
- return;
-
- _views.remove(view);
-
- ListIterator i = _views.begin();
- while ((i != _views.end()) && ((*i)->layer() < view->layer()))
- ++i;
-
- _views.insert(i, view);
-}
-
-View *ViewManager::getView(int screenType) {
- ListIterator i = _views.begin();
- while (i != _views.end()) {
- if ((*i)->screenType() == screenType)
- return *i;
- ++i;
- }
-
- return NULL;
-}
-
-void ViewManager::updateState() {
- Common::List<View *> viewList = _views;
-
- for (ListIterator i = viewList.begin(); i != viewList.end(); ++i) {
- if (_vm->_events->quitFlag)
- return;
-
- View *v = *i;
- v->updateState();
- }
-}
-
-void ViewManager::refreshAll() {
- _vm->_screen->clear();
-
- for (ListIterator i = _views.begin(); i != _views.end(); ++i) {
- View *v = *i;
-
- if (v->isVisible())
- v->onRefresh(NULL, _vm->_screen);
- }
-
- _vm->_screen->update();
-}
-
-void ViewManager::showTextView(const char *textViewName, bool returnToMainMenu) {
- // Deactivate the scene if it's currently active
- View *view = _vm->_viewManager->getView(VIEWID_SCENE);
- if (view != NULL)
- _vm->_viewManager->deleteView(view);
-
- // Deactivate the main menu if it's currently active
- view = _vm->_viewManager->getView(VIEWID_MAINMENU);
- if (view != NULL)
- _vm->_viewManager->deleteView(view);
-
- // Activate the textview view
- _vm->_font->setFont(FONT_CONVERSATION_MADS);
- TextviewView *textView = new TextviewView(_vm);
- _vm->_viewManager->addView(textView);
- if (returnToMainMenu)
- textView->setScript(textViewName, returnToMainMenuFn);
- else
- textView->setScript(textViewName, NULL);
-}
-
-void ViewManager::showAnimView(const char *animViewName, bool returnToMainMenu) {
- // Deactivate the scene if it's currently active
- View *view = _vm->_viewManager->getView(VIEWID_SCENE);
- if (view != NULL)
- _vm->_viewManager->deleteView(view);
-
- // Deactivate the main menu if it's currently active
- view = _vm->_viewManager->getView(VIEWID_MAINMENU);
- if (view != NULL)
- _vm->_viewManager->deleteView(view);
-
- // Activate the animview view
- AnimviewView *animView = new AnimviewView(_vm);
- _vm->_viewManager->addView(animView);
- if (returnToMainMenu)
- animView->setScript(animViewName, returnToMainMenuFn);
- else
- animView->setScript(animViewName, NULL);
-}
-
-} // End of namespace M4
diff --git a/engines/m4/viewmgr.h b/engines/m4/viewmgr.h
deleted file mode 100644
index bb4f76cfaa..0000000000
--- a/engines/m4/viewmgr.h
+++ /dev/null
@@ -1,204 +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 M4_VIEWMGR_H
-#define M4_VIEWMGR_H
-
-#include "common/algorithm.h"
-#include "common/array.h"
-#include "common/list.h"
-#include "common/events.h"
-#include "common/rect.h"
-
-#include "m4/font.h"
-#include "m4/globals.h"
-#include "m4/events.h"
-#include "m4/graphics.h"
-
-namespace M4 {
-
-class View;
-class ViewManager;
-
-enum SceneTransition {
- kTransitionNone = 0,
- kTransitionFadeIn = 1,
- kTransitionFadeIn2 = 2,
- kTransitionBoxInBottomLeft = 3,
- kTransitionBoxInBottomRight = 4,
- kTransitionBoxInTopLeft = 5,
- kTransitionBoxInTopRight = 6,
- kTransitionPanLeftToRight = 7,
- kTransitionPanRightToLeft = 8,
- kTransitionCircleIn = 9
-};
-
-enum {SCREEN_DIALOG, SCREEN_BUFFER, SCREEN_TEXT, SCREEN_TRANSPARENT};
-enum ScreenEventType {SCREVENT_NONE = 0, SCREVENT_KEY = 1, SCREVENT_MOUSE = 2, SCREVENT_ALL = 3};
-enum ScreenLayers {
- LAYER_BACKGROUND = 0, LAYER_DRIFTER = 1, LAYER_INTERFACE = 1, LAYER_FLOATER = 2,
- LAYER_SURFACE = 3, LAYER_MENU = 9, LAYER_DIALOG = 10, LAYER_MOUSE = 15
-};
-
-enum ViewIds {
- VIEWID_MAINMENU = 1,
- VIEWID_SCENE = 2,
- VIEWID_TEXTVIEW = 3,
- VIEWID_ANIMVIEW = 4,
- VIEWID_MENU = 69,
- VIEWID_CONVERSATION = 48,
- VIEWID_INTERFACE = 49
-};
-
-struct ScreenFlags {
- bool visible:1;
- bool transparent:1;
- bool immovable:1;
-
- enum ScreenEventType blocks:2;
- enum ScreenEventType get:2;
-
- uint layer:4;
-};
-
-#define SCREEN_FLAGS_DEFAULT _screenFlags.layer = LAYER_DRIFTER; \
- _screenFlags.get = SCREVENT_ALL; _screenFlags.blocks = SCREVENT_NONE; \
- _screenFlags.visible = true;
-#define SCREEN_FLAGS_ALERT _screenFlags.layer = LAYER_FLOATER \
- _screenFlags.get = SCREVENT_ALL; _screenFlags.blocks = SCREVENT_ALL; \
- _screenFlags.visible = true;
-
-class RectList : public Common::Array<Common::Rect> {
-public:
- RectList();
- ~RectList();
- void addRect(int x1, int y1, int x2, int y2);
- void addRect(const Common::Rect &rect);
-
-// Common::Rect& operator [](int idx) { return _rects[idx]; }
- int find(const Common::Point &pt);
-};
-
-struct Hotkey {
-public:
- typedef void (*Callback)(MadsM4Engine *vm, View *view, uint32 key);
- Hotkey(uint32 keyVal, Hotkey::Callback callbackFn) : key(keyVal), callback(callbackFn) {}
- uint32 key;
- Hotkey::Callback callback;
-};
-
-class HotkeyList {
-public:
- HotkeyList(View *owner);
- ~HotkeyList();
- void add(uint32 key, Hotkey::Callback callback);
- void remove(uint32 key);
- bool call(uint32 key);
-private:
- Common::Array<Hotkey*> _hotkeys;
- View *_view;
-};
-
-class View : public M4Surface {
-public:
- View(MadsM4Engine *vm, const Common::Rect &viewBounds, bool transparent = false);
- View(MadsM4Engine *vm, int x = 0, int y = 0, bool transparent = false);
- virtual ~View() {}
-
- void getCoordinates(Common::Rect &rect);
- void extract(int *status);
- virtual void show();
- virtual void hide();
- void moveToFront() {}
- void moveToBack();
- void moveAbsolute(int x, int y);
- void moveRelative(int x, int y);
- void resize(int newWidth, int newHeight);
- void restore(int x1, int y1, int x2, int y2);
-
- Common::Rect bounds() const { return _coords; }
- bool isInside(int x, int y) const { return _coords.contains(x, y); }
- ScreenFlags screenFlags() const { return _screenFlags; }
- int screenType() const { return _screenType; }
- bool isOffscreen() const { return !_screenFlags.visible; }
- bool isTransparent() const { return _screenFlags.transparent; }
- bool isVisible() const { return _screenFlags.visible; }
- uint layer() const { return _screenFlags.layer; }
- HotkeyList &hotkeys() { return _hotkeys; }
-
- virtual void onRefresh(RectList *rects, M4Surface *destSurface);
- virtual bool onEvent(M4EventType eventType, int32 param, int x, int y, bool &captureEvents) { return false; }
- virtual void updateState() {}
-
-protected:
- MadsM4Engine *_vm;
- Common::Rect _coords;
- HotkeyList _hotkeys;
- int _screenType;
- ScreenFlags _screenFlags;
- bool _transparent;
-};
-
-class ViewManager {
-private:
- MadsM4Engine *_vm;
- HotkeyList _systemHotkeys;
- Common::List<View *> _views;
- View *_captureScreen;
- bool _captureEvents;
-public:
- typedef Common::List<View *>::iterator ListIterator;
-
- ViewManager(MadsM4Engine *vm);
- ~ViewManager();
-
- void addView(View *view);
- void deleteView(View *view);
-
- void handleEvents(const Common::Event &event);
- void handleKeyboardEvents(uint32 keycode);
- void handleMouseEvents(M4EventType event);
- void restore(int x1, int y1, int x2, int y2);
- void restore(const Common::Rect &rect);
-
- void moveToFront(View *view);
- void moveToBack(View *view);
-
- Common::List<View *> views() const { return _views; }
- bool contains(View *key) const {
- return Common::find(_views.begin(), _views.end(), key) != _views.end();
- }
- bool contains(int screenType) { return getView(screenType) != NULL; }
- View *getView(int screenType);
- int containsViews() { return !_views.empty(); }
-
- void showTextView(const char *textViewName, bool returnToMainMenu = true);
- void showAnimView(const char *animViewName, bool returnToMainMenu = true);
-
- void updateState();
- void refreshAll();
- HotkeyList &systemHotkeys() { return _systemHotkeys; }
-};
-
-}
-
-#endif
diff --git a/engines/m4/woodscript.cpp b/engines/m4/woodscript.cpp
deleted file mode 100644
index 42f4fbce98..0000000000
--- a/engines/m4/woodscript.cpp
+++ /dev/null
@@ -1,398 +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 "m4/woodscript.h"
-
-#include "common/memstream.h"
-#include "graphics/palette.h"
-
-namespace M4 {
-
-// FIXME: Put in Engine/WoodScript class
-RGB8 _mainPalette[256];
-
-//Woodscript Assembler/Compiler
-
-int32 Bytecode::_dataFormats[] = {0, 5, 8, 12, 16};
-
-Bytecode::Bytecode(WoodScript *ws, byte *code, int32 codeSize, Sequence *seq) {
- _ws = ws;
- _code = new Common::MemoryReadStream(code, codeSize);
- _sequence = seq;
-}
-
-Bytecode::~Bytecode() {
- delete _code;
-}
-
-int Bytecode::loadInstruction(Instruction &instruction) {
-
- //debugCN(kDebugScript, "Bytecode::loadInstruction() ip = %08X\n", _code->pos());
-
- int32 format, data;
- uint32 code, code2;
-
- code = _code->readUint32LE();
-
- instruction.instr = (code >> 25) & 0xFF;
- instruction.argp[0] = NULL;
- instruction.argp[1] = NULL;
- instruction.argp[2] = NULL;
- instruction.argc = 0;
-
- // Maybe make this a for-loop?
-
- format = (code >> 22) & 7;
- if (format) {
- /* Load argument 1 */
- data = code & 0xFFFF;
- decodeArgument(format, data, instruction.argp[0], instruction.argv[0]);
- instruction.argc++;
- /* Load argument 2 */
- format = (code >> 19) & 7;
- if (format) {
- code2 = _code->readUint32LE();
- data = (code2 >> 16) & 0xFFFF;
- decodeArgument(format, data, instruction.argp[1], instruction.argv[1]);
- instruction.argc++;
- /* Load argument 3 */
- format = (code >> 16) & 7;
- if (format) {
- data = code2 & 0xFFFF;
- decodeArgument(format, data, instruction.argp[2], instruction.argv[2]);
- instruction.argc++;
- }
- }
- }
-
- return 0; //FIXME check if instruction size is needed by caller
-
-}
-
-void Bytecode::jumpAbsolute(int32 ofs) {
- _code->seek(ofs * 4);
- //debugCN(kDebugScript, "Bytecode::jumpAbsolute() ofs = %08X\n", _code->pos());
-}
-
-void Bytecode::jumpRelative(int32 ofs) {
- _code->seek(ofs * 4, SEEK_CUR);
-}
-
-void Bytecode::setSequence(Sequence *seq) {
- _sequence = seq;
-}
-
-void Bytecode::setCode(byte *code, int32 codeSize) {
- delete _code;
- _code = new Common::MemoryReadStream(code, codeSize);
-}
-
-Sequence *Bytecode::sequence() const {
- assert(_sequence);
- return _sequence;
-}
-
-bool Bytecode::decodeArgument(int32 format, int32 data, long *&arg, long &value) {
-
- int32 index;
-
- if (format == 1) {
- if (data & 0x8000)
- index = _sequence->indexReg();
- else
- index = data & 0x0FFF;
- switch (data & 0x7000) {
- case 0x0000:
- arg = sequence()->getParentVarPtr(index);
- value = *arg;
- break;
- case 0x1000:
- arg = sequence()->getVarPtr(index);
- value = *arg;
- break;
- case 0x2000:
- arg = sequence()->getDataPtr(index);
- value = *arg;
- break;
- }
- } else if (format == 2) {
- if (data & 0x8000)
- index = _sequence->indexReg();
- else
- index = data & 0x0FFF;
- arg = _ws->getGlobalPtr(index);
- value = *arg;
- } else {
- if (data & 0x8000) {
- value = -(data & 0x7FFF) << (_dataFormats[format - 3]);
- } else {
- value = (data & 0x7FFF) << (_dataFormats[format - 3]);
- }
- arg = &value;
- }
-
- return true;
-}
-
-WoodScript::WoodScript(MadsM4Engine *vm) {
- _vm = vm;
- _machineId = 0;
- _assets = new AssetManager(vm);
- _globals = new long[256]; //FIXME Find out how many globals there should be
- memset(_globals, 0, sizeof(long));
-
- _backgroundSurface = NULL;
-
- //Common::Rect viewBounds = Common::Rect(0, 0, 640, 480);
- //_surfaceView = new View(viewBounds);
-}
-
-WoodScript::~WoodScript() {
- delete _assets;
- delete[] _globals;
-}
-
-Sequence *WoodScript::createSequence(Machine *machine, int32 sequenceHash) {
- Sequence *sequence = new Sequence(this, machine, sequenceHash);
- _sequences.push_back(sequence);
- _layers.push_back(sequence);
- return sequence;
-}
-
-void WoodScript::runSequencePrograms() {
- // A lot TODO
- for (Common::Array<Sequence*>::iterator it = _sequences.begin(); it != _sequences.end(); ++it) {
- Sequence *sequence = *it;
- if (sequence->isActive()) {
- sequence->runProgram();
- if (sequence->isTerminated() && sequence->hasEndOfSequenceRequestPending()) {
- _endOfSequenceRequestList.push_back(sequence);
- }
- }
- }
-}
-
-void WoodScript::runEndOfSequenceRequests() {
-}
-
-void WoodScript::runTimerSequenceRequests() {
-}
-
-Machine *WoodScript::createMachine(int32 machineHash, Sequence *parentSeq,
- int32 dataHash, int32 dataRowIndex, int callbackHandler, const char *machineName) {
-
- //debugCN(kDebugScript, "WoodScript::createMachine(%d)\n", machineHash);
-
- Machine *machine = new Machine(this, machineHash, parentSeq, dataHash, dataRowIndex, callbackHandler, machineName, _machineId);
- _machineId++;
-
- _machines.push_back(machine);
-
- // goto first state for initialization
- machine->enterState();
-
- return machine;
-}
-
-int32 WoodScript::loadSeries(const char* seriesName, int32 hash, RGB8* palette) {
- return _assets->addSpriteAsset(seriesName, hash, palette);
-}
-
-void WoodScript::unloadSeries(int32 hash) {
- _assets->clearAssets(kAssetTypeCELS, hash, hash);
-}
-
-void WoodScript::setSeriesFramerate(Machine *machine, int32 frameRate) {
-}
-
-Machine *WoodScript::playSeries(const char *seriesName, long layer, uint32 flags, int32 triggerNum,
- int32 frameRate, int32 loopCount, int32 s, int32 x, int32 y,
- int32 firstFrame, int32 lastFrame) {
-
- //debugCN(kDebugScript, "WoodScript::playSeries(%s)\n", seriesName);
-
- RGB8 *palette = NULL;
- if (flags & SERIES_LOAD_PALETTE)
- palette = &_mainPalette[0];
-
- int32 spriteHash = _assets->addSpriteAsset(seriesName, -1, palette);
-
- _globals[kGlobTemp1] = (long)spriteHash << 24;
- _globals[kGlobTemp2] = layer << 16;
- _globals[kGlobTemp3] = _vm->_kernel->createTrigger(triggerNum);
- _globals[kGlobTemp4] = frameRate << 16;
- _globals[kGlobTemp5] = loopCount << 16;
- _globals[kGlobTemp6] = (s << 16) / 100;
- _globals[kGlobTemp7] = x << 16;
- _globals[kGlobTemp8] = y << 16;
- _globals[kGlobTemp9] = firstFrame << 16;
- _globals[kGlobTemp10] = lastFrame << 16;
- _globals[kGlobTemp11] = (flags & SERIES_PINGPONG) ? 0x10000 : 0;
- _globals[kGlobTemp12] = (flags & SERIES_BACKWARD) ? 0x10000 : 0;
- _globals[kGlobTemp13] = (flags & SERIES_RANDOM) ? 0x10000 : 0;
- _globals[kGlobTemp14] = (flags & SERIES_STICK) ? 0x10000 : 0;
- _globals[kGlobTemp15] = (flags & SERIES_LOOP_TRIGGER) ? 0x10000 : 0;
- _globals[kGlobTemp16] = (flags & SERIES_HORZ_FLIP) ? 0x10000 : 0;
-
- return createMachine(0, NULL, -1, -1, kCallbackTriggerDispatch, seriesName);
-
-}
-
-Machine *WoodScript::showSeries(const char *seriesName, long layer, uint32 flags, int32 triggerNum,
- int32 duration, int32 index, int32 s, int32 x, int32 y) {
-
- RGB8 *palette = NULL;
- if (flags & SERIES_LOAD_PALETTE)
- palette = &_mainPalette[0];
-
- int32 spriteHash = _assets->addSpriteAsset(seriesName, -1, palette);
-
- _globals[kGlobTemp1] = spriteHash << 24;
- _globals[kGlobTemp2] = layer << 16;
- _globals[kGlobTemp3] = _vm->_kernel->createTrigger(triggerNum);
- _globals[kGlobTemp4] = duration << 16;
- _globals[kGlobTemp5] = index << 16;
- _globals[kGlobTemp6] = (s << 16) / 100;
- _globals[kGlobTemp7] = x << 16;
- _globals[kGlobTemp8] = y << 16;
- _globals[kGlobTemp14] = (flags & SERIES_STICK) ? 0x10000 : 0;
- _globals[kGlobTemp16] = (flags & SERIES_HORZ_FLIP) ? 0x10000 : 0;
-
- return createMachine(1, NULL, -1, -1, kCallbackTriggerDispatch, seriesName);
-
-}
-
-Machine *WoodScript::streamSeries(const char *seriesName, int32 frameRate, long layer, int32 triggerNum) {
- //debugCN(kDebugScript, "WoodScript::streamSeries(%s)\n", seriesName);
- _globals[kGlobTemp1] = frameRate << 16;
- /* FIXME: Single frames from a stream series will be decompressed on-the-fly, contrary to
- "normal" sprite series, to save some memory, and since no random access to single
- frames is needed, this is ok.
- */
- _globals[kGlobTemp4] = 0; // The actual stream is opened in the Sequence
- _globals[kGlobTemp5] = 0;//TODO: kernel_trigger_create(triggerNum); // trigger
- _globals[kGlobTemp6] = layer << 16; // layer
- return createMachine(6, NULL, -1, -1, kCallbackTriggerDispatch, seriesName);
-}
-
-void WoodScript::update() {
- // TODO: Don't show hidden sequences etc.
-
- // TODO: For now, prevent any engine action if a menu is being displayed - eventually this should be
- // changed to a proper check of the engine paused variable, which the menus should set while active
- if (_vm->_viewManager->getView(VIEWID_MENU) != NULL)
- return;
-
- //TODO: Include _pauseTime
- uint32 clockTime = g_system->getMillis() / 60; // FIXME: g_system
- _globals[kGlobTimeDelta] = clockTime - _globals[kGlobTime];
- _globals[kGlobTime] += _globals[kGlobTimeDelta];
-
- runSequencePrograms();
-
- if (_backgroundSurface) {
- // FIXME: For now, copy the whole surface. Later, copy only the rectangles that need updating.
- _backgroundSurface->copyTo(_surfaceView);
- } else {
- // "This should never happen."
- _surfaceView->fillRect(Common::Rect(0, 0, 640, 480), 0);
- }
-
- {
- // FIXME: This should be done when a new palette is set
- byte palette[768];
- g_system->getPaletteManager()->grabPalette(palette, 0, 256);
- for (int i = 0; i < 256; i++) {
- _mainPalette[i].r = palette[i * 3 + 0];
- _mainPalette[i].g = palette[i * 3 + 1];
- _mainPalette[i].b = palette[i * 3 + 2];
- }
- }
-
- for (Common::Array<Sequence*>::iterator it = _layers.begin(); it != _layers.end(); ++it) {
- Sequence *sequence = *it;
-
- // TODO: Use correct clipRect etc.
- Common::Rect clipRect = Common::Rect(0, 0, 640, 480);
- Common::Rect updateRect;
-
- sequence->draw(_surfaceView, clipRect, updateRect);
-
- }
-
- // Handle end-of-sequence requests
- if (_endOfSequenceRequestList.size() > 0) {
- for (Common::Array<Sequence*>::iterator it = _endOfSequenceRequestList.begin(); it != _endOfSequenceRequestList.end(); ++it) {
- Sequence *sequence = *it;
-
- EndOfSequenceRequestItem endOfSequenceRequestItem = sequence->getEndOfSequenceRequestItem();
- sequence->getMachine()->execBlock(endOfSequenceRequestItem.codeOffset, endOfSequenceRequestItem.count);
- }
- _endOfSequenceRequestList.clear();
- }
-
-}
-
-void WoodScript::clear() {
-
- for (Common::Array<Sequence*>::iterator it = _sequences.begin(); it != _sequences.end(); ++it)
- delete *it;
- _sequences.clear();
-
- for (Common::Array<Machine*>::iterator it = _machines.begin(); it != _machines.end(); ++it)
- delete *it;
- _machines.clear();
-
- _layers.clear();
- _endOfSequenceRequestList.clear();
-
-}
-
-void WoodScript::setDepthTable(int16 *depthTable) {
- _depthTable = depthTable;
-}
-
-long *WoodScript::getGlobalPtr(int index) {
- return &_globals[index];
-}
-
-long WoodScript::getGlobal(int index) {
- return _globals[index];
-}
-
-void WoodScript::setGlobal(int index, long value) {
- _globals[index] = value;
-}
-
-void WoodScript::setBackgroundSurface(M4Surface *backgroundSurface) {
- _backgroundSurface = backgroundSurface;
-}
-
-void WoodScript::setSurfaceView(View *view) {
- _surfaceView = view;
-}
-
-RGB8 *WoodScript::getMainPalette() const {
- return _mainPalette;
-}
-
-}
diff --git a/engines/m4/woodscript.h b/engines/m4/woodscript.h
deleted file mode 100644
index 95033b9179..0000000000
--- a/engines/m4/woodscript.h
+++ /dev/null
@@ -1,348 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#ifndef M4_WOODSCRIPT_H
-#define M4_WOODSCRIPT_H
-
-#include "common/scummsys.h"
-#include "common/util.h"
-#include "common/str.h"
-#include "common/array.h"
-#include "common/stream.h"
-#include "graphics/surface.h"
-
-#include "m4/globals.h"
-#include "m4/assets.h"
-#include "m4/resource.h"
-#include "m4/sprite.h"
-#include "m4/m4.h"
-#include "m4/graphics.h"
-#include "m4/viewmgr.h"
-
-namespace M4 {
-
-class MadsM4Engine;
-class WoodScript;
-class Machine;
-class Sequence;
-class AssetManager;
-class View;
-
-struct Instruction {
- int32 instr;
- long *argp[3];
- long argv[3];
- int argc;
- // Helper method; many opcode functions can get either a defined value or a random value
- long getValue() {
- if (argc == 3)
- return _vm->imath_ranged_rand16(argv[1], argv[2]);
- else
- return argv[1];
- }
-};
-
-class Bytecode {
-public:
- Bytecode(WoodScript *ws, byte *code, int32 codeSize, Sequence *seq);
- ~Bytecode();
- int loadInstruction(Instruction &instruction);
- void jumpAbsolute(int32 ofs);
- void jumpRelative(int32 ofs);
- void setSequence(Sequence *sequence);
- void setCode(byte *code, int32 codeSize);
- Sequence *sequence() const;
- uint32 pos() const { return _code->pos() / 4; }
-protected:
- WoodScript *_ws;
- Common::SeekableReadStream *_code;
- Sequence *_sequence;
- static int32 _dataFormats[];
- bool decodeArgument(int32 format, int32 data, long *&arg, long &value);
-};
-
-struct EndOfSequenceRequestItem {
- int32 codeOffset, count;
- EndOfSequenceRequestItem() : codeOffset(-1) {}
- bool isValid() const { return codeOffset >= 0; }
-};
-
-typedef Common::Array<EndOfSequenceRequestItem> EndOfSequenceRequestList;
-
-class Sequence {
-public:
- Sequence(WoodScript *ws, Machine *machine, int32 sequenceHash);
- ~Sequence();
-
- void pause();
- void resume();
- void issueEndOfSequenceRequest(int32 codeOffset, int32 count);
- void cancelEndOfSequenceRequest();
-
- bool runProgram();
-
- bool changeProgram(int32 sequenceHash);
-
- void clearVars();
-
- long *getVarPtr(int index);
- long *getParentVarPtr(int index);
- long *getDataPtr(int index);
-
- void setActive(bool active) { _active = active; }
- bool isActive() const { return _active; }
-
- bool isTerminated() const { return _terminated; }
-
- void draw(M4Surface *surface, const Common::Rect &clipRect, Common::Rect &updateRect);
-
- bool s1_end(Instruction &instruction);
- bool s1_clearVars(Instruction &instruction);
- bool s1_set(Instruction &instruction);
- bool s1_compare(Instruction &instruction);
- bool s1_add(Instruction &instruction);
- bool s1_sub(Instruction &instruction);
- bool s1_mul(Instruction &instruction);
- bool s1_div(Instruction &instruction);
- bool s1_and(Instruction &instruction);
- bool s1_or(Instruction &instruction);
- bool s1_not(Instruction &instruction);
- bool s1_sin(Instruction &instruction);
- bool s1_cos(Instruction &instruction);
- bool s1_abs(Instruction &instruction);
- bool s1_min(Instruction &instruction);
- bool s1_max(Instruction &instruction);
- bool s1_mod(Instruction &instruction);
- bool s1_floor(Instruction &instruction);
- bool s1_round(Instruction &instruction);
- bool s1_ceil(Instruction &instruction);
- bool s1_point(Instruction &instruction);
- bool s1_dist2d(Instruction &instruction);
- bool s1_crunch(Instruction &instruction);
- bool s1_branch(Instruction &instruction);
- bool s1_setFrame(Instruction &instruction);
- bool s1_sendMessage(Instruction &instruction);
- bool s1_push(Instruction &instruction);
- bool s1_pop(Instruction &instruction);
- bool s1_jumpSub(Instruction &instruction);
- bool s1_return(Instruction &instruction);
- bool s1_getFrameCount(Instruction &instruction);
- bool s1_getFrameRate(Instruction &instruction);
- bool s1_getCelsPixSpeed(Instruction &instruction);
- bool s1_setIndex(Instruction &instruction);
- bool s1_setLayer(Instruction &instruction);
- bool s1_setDepth(Instruction &instruction);
- bool s1_setData(Instruction &instruction);
- bool s1_openStream(Instruction &instruction);
- bool s1_streamNextFrame(Instruction &instruction);
- bool s1_closeStream(Instruction &instruction);
-
- int32 indexReg() const { return _indexReg; }
-
- EndOfSequenceRequestItem getEndOfSequenceRequestItem() const { return _endOfSequenceRequest; }
- bool hasEndOfSequenceRequestPending() const { return _endOfSequenceRequest.isValid(); }
- void resetEndOfSequenceRequest() { _endOfSequenceRequest.codeOffset = -1; }
-
- Machine *getMachine() const { return _machine; }
-
-
-protected:
- WoodScript *_ws;
- Bytecode *_code;
-
- long *_vars;
- bool _active, _terminated;
- Machine *_machine;
- Sequence *_parentSequence;
- int32 _layer;
- int32 _startTime, _switchTime;
- long *_dataRow;
- int32 _localVarCount;
- int32 _cmpFlags;
-
- EndOfSequenceRequestItem _endOfSequenceRequest;
-
- int32 _indexReg;
-
- M4Sprite *_curFrame;
-
- int32 _sequenceHash;
-
- int32 _returnHashes[8]; //FIXME: Use constant instead of 8
- uint32 _returnOffsets[8];
- int32 _returnStackIndex;
-
- Common::SeekableReadStream *_stream;
- SpriteAsset *_streamSpriteAsset;
-
- bool streamOpen();
- bool streamNextFrame();
- void streamClose();
-
-};
-
-class Machine {
-public:
- Machine(WoodScript *ws, int32 machineHash, Sequence *parentSeq, int32 dataHash,
- int32 dataRowIndex, int callbackHandler, Common::String machineName, int32 id);
- ~Machine();
-
- void clearMessages();
- void clearPersistentMessages();
- void restorePersistentMessages();
- void sendMessage(uint32 messageHash, long messageValue, Machine *sender);
- void resetSwitchTime();
- bool changeSequenceProgram(int32 sequenceHash);
-
- bool searchMessages(uint32 messageHash, uint32 messageValue, Machine *sender);
- bool searchPersistentMessages(uint32 messageHash, uint32 messageValue, Machine *sender);
-
- void enterState();
- int32 execInstruction();
- void execBlock(int32 offset, int32 count);
- int32 getState() { return _currentState; }
-
- int32 getId() const { return _id; }
-
- bool m1_gotoState(Instruction &instruction);
- bool m1_jump(Instruction &instruction);
- bool m1_terminate(Instruction &instruction);
- bool m1_startSequence(Instruction &instruction);
- bool m1_pauseSequence(Instruction &instruction);
- bool m1_resumeSequence(Instruction &instruction);
- bool m1_storeValue(Instruction &instruction);
- bool m1_sendMessage(Instruction &instruction);
- bool m1_broadcastMessage(Instruction &instruction);
- bool m1_replyMessage(Instruction &instruction);
- bool m1_sendSystemMessage(Instruction &instruction);
- bool m1_createMachine(Instruction &instruction);
- bool m1_createMachineEx(Instruction &instruction);
- bool m1_clearVars(Instruction &instruction);
-
- void m1_onEndSequence(Instruction &instruction);
- void m1_onMessage(Instruction &instruction);
- void m1_switchLt(Instruction &instruction);
- void m1_switchLe(Instruction &instruction);
- void m1_switchEq(Instruction &instruction);
- void m1_switchNe(Instruction &instruction);
- void m1_switchGe(Instruction &instruction);
- void m1_switchGt(Instruction &instruction);
-
- long *dataRow() const { return _dataRow; }
- Sequence *parentSequence() const { return _parentSequence; }
- Common::String name() const { return _name; }
-
-protected:
- WoodScript *_ws;
- Bytecode *_code;
-
- Common::String _name;
- Sequence *_sequence, *_parentSequence;
- byte *_mach;
- int32 _machHash, _machineCodeOffset;
- int32 _stateCount, _stateTableOffset;
- long *_dataRow;
- int32 _id, _recursionLevel, _currentState, _targetCount;
- /* TODO:
- m->msgReplyXM = NULL;
- m->CintrMsg = CintrMsg;
- _walkPath
- _messages
- _persistentMessages
- _usedPersistentMessages
- */
-};
-
-class WoodScript {
-public:
-
- WoodScript(MadsM4Engine *vm);
- ~WoodScript();
-
- Machine *createMachine(int32 machineHash, Sequence *parentSeq, int32 dataHash, int32 dataRowIndex, int callbackHandler, const char *machineName);
- Sequence *createSequence(Machine *machine, int32 sequenceHash);
-
- void runSequencePrograms();
- void runEndOfSequenceRequests();
- void runTimerSequenceRequests();
-
- /* Series */
- // Move to own class, e.g. SeriesPlayer
- int32 loadSeries(const char* seriesName, int32 hash, RGB8* palette);
- void unloadSeries(int32 hash);
- void setSeriesFramerate(Machine *machine, int32 frameRate);
- Machine *playSeries(const char *seriesName, long layer, uint32 flags, int32 triggerNum,
- int32 frameRate, int32 loopCount, int32 s, int32 x, int32 y,
- int32 firstFrame, int32 lastFrame);
- Machine *showSeries(const char *seriesName, long layer, uint32 flags, int32 triggerNum,
- int32 duration, int32 index, int32 s, int32 x, int32 y);
- Machine *streamSeries(const char *seriesName, int32 frameRate, long layer, int32 triggerNum);
-
- void update();
- void clear();
-
- /* Misc */
- void setDepthTable(int16 *depthTable);
-
- long *getGlobalPtr(int index);
- long getGlobal(int index);
- void setGlobal(int index, long value);
-
- AssetManager *assets() const { return _assets; }
-
- // Sets the untouched, clean surface which contains the room background
- void setBackgroundSurface(M4Surface *backgroundSurface);
- // Sets the view which is used for drawing
- void setSurfaceView(View *view);
-
- RGB8 *getMainPalette() const;
-
- void setInverseColorTable(byte *inverseColorTable) { _inverseColorTable = inverseColorTable; }
- byte *getInverseColorTable() const { return _inverseColorTable; }
-
-protected:
- MadsM4Engine *_vm;
- AssetManager *_assets;
-
- Common::Array<Sequence*> _sequences, _layers;
- Common::Array<Machine*> _machines;
- int32 _machineId;
-
- long *_globals;
-
- Common::Array<Sequence*> _endOfSequenceRequestList;
-
- int32 _indexReg;
-
- /* Misc */
- int16 *_depthTable;
- byte *_inverseColorTable;
- M4Surface *_backgroundSurface;
- View *_surfaceView;
-
-};
-
-
-} // End of namespace M4
-
-
-#endif
diff --git a/engines/m4/ws_machine.cpp b/engines/m4/ws_machine.cpp
deleted file mode 100644
index 18a8af76a8..0000000000
--- a/engines/m4/ws_machine.cpp
+++ /dev/null
@@ -1,423 +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 "m4/woodscript.h"
-
-namespace M4 {
-
-bool (Machine::*machineCommandsTable[])(Instruction &instruction) = {
- NULL,
- NULL,//TODO: nop
- &Machine::m1_gotoState,
- &Machine::m1_jump,
- &Machine::m1_terminate,
- &Machine::m1_startSequence,
- &Machine::m1_pauseSequence,
- &Machine::m1_resumeSequence,
- &Machine::m1_storeValue,
- &Machine::m1_sendMessage,
- &Machine::m1_broadcastMessage,
- &Machine::m1_replyMessage,
- &Machine::m1_sendSystemMessage,
- &Machine::m1_createMachine,
- &Machine::m1_createMachineEx,
- &Machine::m1_clearVars
-};
-
-void (Machine::*machineConditionalsTable[])(Instruction &instruction) = {
- NULL,//TODO: after
- &Machine::m1_onEndSequence,
- &Machine::m1_onMessage,
- NULL,//TODO: on_p_msg
- &Machine::m1_switchLt,
- &Machine::m1_switchLe,
- &Machine::m1_switchEq,
- &Machine::m1_switchNe,
- &Machine::m1_switchGe,
- &Machine::m1_switchGt,
-};
-
-Machine::Machine(WoodScript *ws, int32 machineHash, Sequence *parentSeq, int32 dataHash,
- int32 dataRowIndex, int callbackHandler, Common::String machineName, int32 id) {
-
- _ws = ws;
-
- _machHash = machineHash;
- _name = machineName;
- _id = id;
-
- // initialize the machine's bytecode
- MachineAsset *machineAsset = _ws->assets()->getMachine(_machHash);
- byte *code;
- uint32 codeSize;
- machineAsset->getCode(code, codeSize);
- _code = new Bytecode(_ws, code, codeSize, NULL);
-
- // initialize the machine's data
- if (dataHash >= 0) {
- DataAsset *dataAsset = _ws->assets()->getData(dataHash);
- _dataRow = dataAsset->getRow(dataRowIndex);
- } else {
- _dataRow = NULL;
- }
-
- _recursionLevel = 0;
- _currentState = 0;
- _sequence = NULL;
- _parentSequence = parentSeq;
- _targetCount = 0;
-
-}
-
-Machine::~Machine() {
- delete _code;
-}
-
-void Machine::clearMessages() {
-}
-
-void Machine::clearPersistentMessages() {
-}
-
-void Machine::restorePersistentMessages() {
-}
-
-void Machine::sendMessage(uint32 messageHash, long messageValue, Machine *sender) {
-}
-
-void Machine::resetSwitchTime() {
-}
-
-bool Machine::changeSequenceProgram(int32 sequenceHash) {
- return _sequence->changeProgram(sequenceHash);
-}
-
-bool Machine::searchMessages(uint32 messageHash, uint32 messageValue, Machine *sender) {
- return false;
-}
-
-bool Machine::searchPersistentMessages(uint32 messageHash, uint32 messageValue, Machine *sender) {
- return false;
-}
-
-void Machine::enterState() {
-
- MachineAsset *machineAsset = _ws->assets()->getMachine(_machHash);
-
- _code->jumpAbsolute(machineAsset->getStateOffset(_currentState));
-
- int32 instruction = -1;
-
- _recursionLevel++;
-
- int32 oldId = _id;
- int32 oldRecursionLevel = _recursionLevel;
-
- while (instruction && instruction != 4 && _id == oldId && _recursionLevel == oldRecursionLevel) {
- instruction = execInstruction();
- }
-
- if (instruction != 4 && _id == oldId && _recursionLevel == oldRecursionLevel) {
- _recursionLevel--;
- }
-
-}
-
-int32 Machine::execInstruction() {
-
- //debugCN(kDebugScript, "Machine::execInstruction()\n");
-
- bool done = false;
- Instruction instruction;
- //Sequence *sequence;
- int32 machID = _id;
-
- _code->loadInstruction(instruction);
-
- if (instruction.instr >= 64) {
- if (machineConditionalsTable[instruction.instr - 64] != 0)
- (this->*machineConditionalsTable[instruction.instr - 64])(instruction);
- /* The next line is to yield on unimplemented opcodes */
- else {
- g_system->delayMillis(5000);
- }
- } else if (instruction.instr > 0) {
- if (machineCommandsTable[instruction.instr] != 0)
- done = !(this->*machineCommandsTable[instruction.instr])(instruction);
- /* The next line is to yield on unimplemented opcodes */
- else {
- g_system->delayMillis(5000);
- }
- if (done) {
- if (_id == machID) {
- //TODO: Cancel all requests
- if (_currentState == -1) {
- // TODO: Set terminated flag and delete machine in WoodScript update
- }
- else {
- // initialize new state
- enterState();
- }
- }
- }
- }
-
- return instruction.instr;
-
-}
-
-void Machine::execBlock(int32 offset, int32 count) {
-
- // MachineAsset *machineAsset = _ws->assets()->getMachine(_machHash);
-
- int32 startOffset = offset, endOffset = offset + count;
-
- _recursionLevel++;
-
- int32 oldId = _id;
- int32 oldRecursionLevel = _recursionLevel;
-
- _code->jumpAbsolute(offset);
-
- int32 instruction = -1;
-
- //debugCN(kDebugScript, "---------------------------------------\n");
-
- while (instruction && instruction != 4 && _id == oldId && _recursionLevel == oldRecursionLevel &&
- _code->pos() >= (uint32)startOffset && _code->pos() < (uint32)endOffset) {
-
- instruction = execInstruction();
- //g_system->delayMillis(500);
- }
-
- //debugCN(kDebugScript, "---------------------------------------\n");
-
- if (instruction == 3) {
- execInstruction();
- }
-
- if (instruction != 4 && _id == oldId && _recursionLevel == oldRecursionLevel) {
- _recursionLevel--;
- }
-
-}
-
-bool Machine::m1_gotoState(Instruction &instruction) {
- //debugCN(kDebugScript, "Machine::m1_gotoState() state = %d\n", (int32)instruction.argv[0] >> 16);
-
- _currentState = (int32)instruction.argv[0] >> 16;
- _recursionLevel = 0;
- return false;
-}
-
-bool Machine::m1_jump(Instruction &instruction) {
- //debugCN(kDebugScript, "Machine::m1_jump() ofs = %08X\n", (int32)instruction.argv[0] >> 16);
-
- _code->jumpRelative((int32)instruction.argv[0] >> 16);
- return true;
-}
-
-bool Machine::m1_terminate(Instruction &instruction) {
- //debugCN(kDebugScript, "Machine::m1_terminate()\n");
-
- _currentState = -1;
- _recursionLevel = 0;
- return false;
-}
-
-bool Machine::m1_startSequence(Instruction &instruction) {
- //debugCN(kDebugScript, "Machine::m1_startSequence() sequence hash = %d\n", (uint32)instruction.argv[0] >> 16);
-
- int32 sequenceHash = instruction.argv[0] >> 16;
- if (_sequence == NULL) {
- //debugCN(kDebugScript, "Machine::m1_startSequence() creating new sequence\n");
- _sequence = _ws->createSequence(this, sequenceHash);
- _code->setSequence(_sequence);
- } else {
- //debugCN(kDebugScript, "Machine::m1_startSequence() using existing sequence\n");
- _sequence->changeProgram(sequenceHash);
- //_code->setSequence(_sequence);
- }
- return true;
-}
-
-bool Machine::m1_pauseSequence(Instruction &instruction) {
- //debugCN(kDebugScript, "Machine::m1_pauseSequence()\n");
-
- _sequence->pause();
- return true;
-}
-
-bool Machine::m1_resumeSequence(Instruction &instruction) {
- //debugCN(kDebugScript, "Machine::m1_resumeSequence()\n");
-
- _sequence->resume();
- return true;
-}
-
-bool Machine::m1_storeValue(Instruction &instruction) {
- //debugCN(kDebugScript, "Machine::m1_storeValue() %p = %d (%08X)\n", (void*)instruction.argp[0], (uint32)instruction.argv[1], (uint32)instruction.argv[1]);
-
- *instruction.argp[0] = instruction.getValue();
- return true;
-}
-
-bool Machine::m1_sendMessage(Instruction &instruction) {
- //debugCN(kDebugScript, "Machine::m1_sendMessage() %p = %d (%08X)\n", (void*)instruction.argp[0], (uint32)instruction.argv[1], (uint32)instruction.argv[1]);
-
-#if 0
-//TODO
- long messageValue;
-
- if (instruction.argc == 3) {
- messageValue = instruction.argv[2];
- } else {
- messageValue = 0;
- }
- //_ws->sendMessage((uint32)instruction.argv[1], messageValue, (uint32)instruction.argv[0] >> 16);
- //void SendWSMessage(uint32 msgHash, long msgValue, machine *recvM, uint32 machHash, machine *sendM, int32 msgCount) {
-#endif
- return true;
-
-}
-
-bool Machine::m1_broadcastMessage(Instruction &instruction) {
- //debugCN(kDebugScript, "Machine::m1_broadcastMessage() %p = %d (%08X)\n", (void*)instruction.argp[0], (uint32)instruction.argv[1], (uint32)instruction.argv[1]);
-
-#if 0
-//TODO
- long messageValue;
-
- if (instruction.argc == 3) {
- messageValue = instruction.argv[2];
- } else {
- messageValue = 0;
- }
- //_ws->sendMessage((uint32)instruction.argv[1], messageValue, (uint32)instruction.argv[0] >> 16);
-#endif
- return true;
-}
-
-bool Machine::m1_replyMessage(Instruction &instruction) {
- //debugCN(kDebugScript, "Machine::m1_replyMessage() messageHash = %d; messageValue = %d\n", (uint32)instruction.argv[0], (uint32)instruction.argv[1]);
-#if 0
- if (myArg2) {
- msgValue = *myArg2;
- }
- else {
- msgValue = 0;
- }
- SendWSMessage(*myArg1, msgValue, m->msgReplyXM, 0, m, 1);
-#endif
- return true;
-}
-
-bool Machine::m1_sendSystemMessage(Instruction &instruction) {
- //debugCN(kDebugScript, "Machine::m1_sendSystemMessage() messageValue = %d\n", (uint32)instruction.argv[0]);
-#if 0
-#endif
- return true;
-}
-
-bool Machine::m1_createMachine(Instruction &instruction) {
- //debugCN(kDebugScript, "Machine::m1_createMachine()\n");
-#if 0
-#endif
- return true;
-}
-
-bool Machine::m1_createMachineEx(Instruction &instruction) {
- //debugCN(kDebugScript, "Machine::m1_createMachineEx()\n");
-#if 0
-#endif
- return true;
-}
-
-bool Machine::m1_clearVars(Instruction &instruction) {
- //debugCN(kDebugScript, "Machine::m1_clearVars()\n");
-
- _sequence->clearVars();
- return true;
-}
-
-
-void Machine::m1_onEndSequence(Instruction &instruction) {
- //debugCN(kDebugScript, "Machine::m1_onEndSequence() count = %08X\n", (uint32)instruction.argv[0] >> 16);
-
- int32 count = instruction.argv[0] >> 16;
- _sequence->issueEndOfSequenceRequest(_code->pos(), count);
- _code->jumpRelative(count);
-}
-
-void Machine::m1_onMessage(Instruction &instruction) {
- //debugCN(kDebugScript, "Machine::m1_onEndSequence() count = %08X\n", (uint32)instruction.argv[0] >> 16);
-
- // TODO: Add message to list
-
- int32 count = instruction.argv[0] >> 16;
- _code->jumpRelative(count);
-
-}
-
-void Machine::m1_switchLt(Instruction &instruction) {
- //debugCN(kDebugScript, "Machine::m1_switchLt() %d < %d -> %08X\n", (uint32)instruction.argv[1], (uint32)instruction.argv[2], (uint32)instruction.argv[0] >> 16);
-
- if (instruction.argv[1] >= instruction.argv[2])
- _code->jumpRelative(instruction.argv[0] >> 16);
-}
-
-void Machine::m1_switchLe(Instruction &instruction) {
- //debugCN(kDebugScript, "Machine::m1_switchLe() %d <= %d -> %08X\n", (uint32)instruction.argv[1], (uint32)instruction.argv[2], (uint32)instruction.argv[0] >> 16);
-
- if (instruction.argv[1] > instruction.argv[2])
- _code->jumpRelative(instruction.argv[0] >> 16);
-}
-
-void Machine::m1_switchEq(Instruction &instruction) {
- //debugCN(kDebugScript, "Machine::m1_switchEq() %d == %d -> %08X\n", (uint32)instruction.argv[1], (uint32)instruction.argv[2], (uint32)instruction.argv[0] >> 16);
-
- if (instruction.argv[1] != instruction.argv[2])
- _code->jumpRelative(instruction.argv[0] >> 16);
-}
-
-void Machine::m1_switchNe(Instruction &instruction) {
- //debugCN(kDebugScript, "Machine::m1_switchNe() %d != %d -> %08X\n", (uint32)instruction.argv[1], (uint32)instruction.argv[2], (uint32)instruction.argv[0] >> 16);
-
- if (instruction.argv[1] == instruction.argv[2])
- _code->jumpRelative(instruction.argv[0] >> 16);
-}
-
-void Machine::m1_switchGe(Instruction &instruction) {
- //debugCN(kDebugScript, "Machine::m1_switchGe() %d >= %d -> %08X\n", (uint32)instruction.argv[1], (uint32)instruction.argv[2], (uint32)instruction.argv[0] >> 16);
-
- if (instruction.argv[1] < instruction.argv[2])
- _code->jumpRelative(instruction.argv[0] >> 16);
-}
-
-void Machine::m1_switchGt(Instruction &instruction) {
- //debugCN(kDebugScript, "Machine::m1_switchGt() %d > %d -> %08X\n", (uint32)instruction.argv[1], (uint32)instruction.argv[2], (uint32)instruction.argv[0] >> 16);
-
- if (instruction.argv[1] <= instruction.argv[2])
- _code->jumpRelative(instruction.argv[0] >> 16);
-}
-
-}
diff --git a/engines/m4/ws_sequence.cpp b/engines/m4/ws_sequence.cpp
deleted file mode 100644
index 01776ef6ec..0000000000
--- a/engines/m4/ws_sequence.cpp
+++ /dev/null
@@ -1,768 +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 "m4/woodscript.h"
-
-namespace M4 {
-
-static const long sinCosTable[320] = {
- 0, 1608, 3215, 4821, 6423, 8022, 9616, 11204,
- 12785, 14359, 15923, 17479, 19024, 20557, 22078, 23586,
- 25079, 26557, 28020, 29465, 30893, 32302, 33692, 35061,
- 36409, 37736, 39039, 40319, 41575, 42806, 44011, 45189,
- 46340, 47464, 48558, 49624, 50660, 51665, 52639, 53581,
- 54491, 55368, 56212, 57022, 57797, 58538, 59243, 59913,
- 60547, 61144, 61705, 62228, 62714, 63162, 63571, 63943,
- 64276, 64571, 64826, 65043, 65220, 65358, 65457, 65516,
- 65536, 65516, 65457, 65358, 65220, 65043, 64826, 64571,
- 64276, 63943, 63571, 63162, 62714, 62228, 61705, 61144,
- 60547, 59913, 59243, 58538, 57797, 57022, 56212, 55368,
- 54491, 53581, 52639, 51665, 50660, 49624, 48558, 47464,
- 46340, 45189, 44011, 42806, 41575, 40319, 39039, 37736,
- 36409, 35061, 33692, 32302, 30893, 29465, 28020, 26557,
- 25079, 23586, 22078, 20557, 19024, 17479, 15923, 14359,
- 12785, 11204, 9616, 8022, 6423, 4821, 3215, 1608,
- 0, -1608, -3215, -4821, -6423, -8022, -9616, -11204,
- -12785, -14359, -15923, -17479, -19024, -20557, -22078, -23586,
- -25079, -26557, -28020, -29465, -30893, -32302, -33692, -35061,
- -36409, -37736, -39039, -40319, -41575, -42806, -44011, -45189,
- -46340, -47464, -48558, -49624, -50660, -51665, -52639, -53581,
- -54491, -55368, -56212, -57022, -57797, -58538, -59243, -59913,
- -60547, -61144, -61705, -62228, -62714, -63162, -63571, -63943,
- -64276, -64571, -64826, -65043, -65220, -65358, -65457, -65516,
- -65536, -65516, -65457, -65358, -65220, -65043, -64826, -64571,
- -64276, -63943, -63571, -63162, -62714, -62228, -61705, -61144,
- -60547, -59913, -59243, -58538, -57797, -57022, -56212, -55368,
- -54491, -53581, -52639, -51665, -50660, -49624, -48558, -47464,
- -46340, -45189, -44011, -42806, -41575, -40319, -39039, -37736,
- -36409, -35061, -33692, -32302, -30893, -29465, -28020, -26557,
- -25079, -23586, -22078, -20557, -19024, -17479, -15923, -14359,
- -12785, -11204, -9616, -8022, -6423, -4821, -3215, -1608,
- 0, 1608, 3215, 4821, 6423, 8022, 9616, 11204,
- 12785, 14359, 15923, 17479, 19024, 20557, 22078, 23586,
- 25079, 26557, 28020, 29465, 30893, 32302, 33692, 35061,
- 36409, 37736, 39039, 40319, 41575, 42806, 44011, 45189,
- 46340, 47464, 48558, 49624, 50660, 51665, 52639, 53581,
- 54491, 55368, 56212, 57022, 57797, 58538, 59243, 59913,
- 60547, 61144, 61705, 62228, 62714, 63162, 63571, 63943,
- 64276, 64571, 64826, 65043, 65220, 65358, 65457, 65516
-};
-
-const long *sinTable = &(sinCosTable[0]);
-const long *cosTable = &(sinCosTable[64]);
-
-// FIXME: Tables
-
-const int sequenceVariableCount = 33;
-
-enum SequenceVariables {
- kSeqVarTimer = 0,
- kSeqVarTag = 1,
- kSeqVarLayer = 2,
- kSeqVarWidth = 3,
- kSeqVarHeight = 4,
- kSeqVarX = 5,
- kSeqVarY = 6,
- kSeqVarScale = 7,
- kSeqVarR = 8,
- kSeqVarSpriteHash = 9,
- kSeqVarSpriteFrameNumber = 10,
- kSeqVarSpriteFrameCount = 11,
- kSeqVarSpriteFrameRate = 12,
- kSeqVarSpriteFramePixelSpeed = 13,
- kSeqVarTargetS = 14,
- kSeqVarTargetR = 15,
- kSeqVarTargetX = 16,
- kSeqVarTargetY = 17,
- kSeqVarDeltaS = 18,
- kSeqVarDeltaR = 19,
- kSeqVarDeltaX = 20,
- kSeqVarDeltaY = 21,
- kSeqVarVelocity = 22,
- kSeqVarTheta = 23,
- kSeqVarTemp1 = 24,
- kSeqVarTemp2 = 25,
- kSeqVarTemp3 = 26,
- kSeqVarTemp4 = 27,
- kSeqVarTemp5 = 28,
- kSeqVarTemp6 = 29,
- kSeqVarTemp7 = 30,
- kSeqVarTemp8 = 31,
- kSeqVarMachineID = 32
-};
-
-bool (Sequence::*sequenceCommandsTable[])(Instruction &instruction) = {
- &Sequence::s1_end,
- &Sequence::s1_clearVars,
- &Sequence::s1_set,
- &Sequence::s1_compare,
- &Sequence::s1_add,
- &Sequence::s1_sub,
- &Sequence::s1_mul,
- &Sequence::s1_div,
- &Sequence::s1_and,
- &Sequence::s1_or,
- &Sequence::s1_not,
- &Sequence::s1_sin,
- &Sequence::s1_cos,
- &Sequence::s1_abs,
- &Sequence::s1_min,
- &Sequence::s1_max,
- &Sequence::s1_mod,
- &Sequence::s1_floor,
- &Sequence::s1_round,
- &Sequence::s1_ceil,
- &Sequence::s1_point,
- &Sequence::s1_dist2d,
- &Sequence::s1_crunch,
- &Sequence::s1_branch,
- &Sequence::s1_setFrame,
- &Sequence::s1_sendMessage,
- &Sequence::s1_push,
- &Sequence::s1_pop,
- &Sequence::s1_jumpSub,
- &Sequence::s1_return,
- &Sequence::s1_getFrameCount,
- &Sequence::s1_getFrameRate,
- &Sequence::s1_getCelsPixSpeed,
- &Sequence::s1_setIndex,
- &Sequence::s1_setLayer,
- &Sequence::s1_setDepth,
- &Sequence::s1_setData,
- &Sequence::s1_openStream,
- &Sequence::s1_streamNextFrame,
- &Sequence::s1_closeStream
-};
-
-Sequence::Sequence(WoodScript *ws, Machine *machine, int32 sequenceHash) {
-
- _ws = ws;
-
- SequenceAsset *sequenceAsset = _ws->assets()->getSequence(sequenceHash);
-
- // initialize the sequence's bytecode
- byte *code;
- uint32 codeSize;
- sequenceAsset->getCode(code, codeSize);
- _code = new Bytecode(_ws, code, codeSize, this);
-
- _active = true;
- _sequenceHash = sequenceHash;
- _machine = machine;
- _parentSequence = _machine->parentSequence();
- _dataRow = _machine->dataRow();
- _startTime = 0;
- _switchTime = 0;
- //TODO _flags = 0;
- _localVarCount = sequenceAsset->localVarCount();
- _vars = new long[sequenceVariableCount + _localVarCount];
- _returnStackIndex = 0;
- _layer = 0;
- _terminated = false;
-
- clearVars();
- _vars[kSeqVarMachineID] = _machine->getId();
-
-}
-
-Sequence::~Sequence() {
- delete _code;
-}
-
-void Sequence::pause() {
- _active = false;
-}
-
-void Sequence::resume() {
- _active = true;
-}
-
-void Sequence::issueEndOfSequenceRequest(int32 codeOffset, int32 count) {
-
- //debugCN(kDebugScript, "Sequence::issueEndOfSequenceRequest(%04X, %04X)\n", codeOffset, count);
- //g_system->delayMillis(5000);
-
- _endOfSequenceRequest.codeOffset = codeOffset;
- _endOfSequenceRequest.count = count;
-}
-
-void Sequence::cancelEndOfSequenceRequest() {
- _endOfSequenceRequest.codeOffset = -1;
-}
-
-bool Sequence::runProgram() {
-
- bool done = true;
-
- //debugCN(kDebugScript, "_ws->getGlobal(kGlobTime) = %ld, _switchTime = %d\n", _ws->getGlobal(kGlobTime), _switchTime);
-
- if (_switchTime >= 0 && _ws->getGlobal(kGlobTime) >= _switchTime)
- done = false;
-
- _vars[kSeqVarTimer] -= _ws->getGlobal(kGlobTimeDelta) << 16;
-
- while (!done) {
- Instruction instruction;
- _code->loadInstruction(instruction);
- if (sequenceCommandsTable[instruction.instr] != 0)
- done = !(this->*sequenceCommandsTable[instruction.instr])(instruction);
- else {
- //g_system->delayMillis(1000);
- }
- }
-
- return _terminated;
-}
-
-void Sequence::clearVars() {
- for (int i = 0; i < sequenceVariableCount + _localVarCount; i++)
- _vars[i] = 0;
- // set default scaling to 100%
- _vars[kSeqVarScale] = 0x10000;
-}
-
-bool Sequence::changeProgram(int32 sequenceHash) {
-
- SequenceAsset *sequenceAsset = _ws->assets()->getSequence(sequenceHash);
-
- if (sequenceAsset->localVarCount() > _localVarCount) {
- //debugCN(kDebugScript, "Sequence::changeProgram(%d) sequenceAsset->localVarCount() > _localVarCount\n", sequenceHash);
- return false;
- }
-
- // Initialize the sequence's bytecode
- byte *code;
- uint32 codeSize;
- sequenceAsset->getCode(code, codeSize);
- _code->setCode(code, codeSize);
-
- // Reset status variables
- _switchTime = 0;
- _active = true;
- _terminated = false;
- _endOfSequenceRequest.codeOffset = -1;
-
- _sequenceHash = sequenceHash;
- _returnStackIndex = 0;
-
- return true;
-
-}
-
-long *Sequence::getVarPtr(int index) {
- return &_vars[index];
-}
-
-long *Sequence::getParentVarPtr(int index) {
- return _parentSequence->getVarPtr(index);
-}
-
-long *Sequence::getDataPtr(int index) {
- return &_dataRow[index];
-}
-
-void Sequence::draw(M4Surface *surface, const Common::Rect &clipRect, Common::Rect &updateRect) {
-
- SpriteInfo info;
-
- info.sprite = _curFrame;
- info.hotX = _curFrame->xOffset;
- info.hotY = _curFrame->yOffset;
- info.encoding = _curFrame->encoding;
- info.inverseColorTable = _m4Vm->scene()->getInverseColorTable();
- info.palette = _ws->getMainPalette();
- info.width = _curFrame->width();
- info.height = _curFrame->height();
- int32 scaler = FixedMul(_vars[kSeqVarScale], 100 << 16) >> 16;
- info.scaleX = _vars[kSeqVarWidth] < 0 ? -scaler : scaler;
- info.scaleY = scaler;
- surface->drawSprite(_vars[kSeqVarX] >> 16, _vars[kSeqVarY] >> 16, info, clipRect);
-
-}
-
-bool Sequence::s1_end(Instruction &instruction) {
- //debugCN(kDebugScript, "Sequence::s1_end()\n");
-
- _terminated = true;
- return false;
-}
-
-bool Sequence::s1_clearVars(Instruction &instruction) {
- //debugCN(kDebugScript, "Sequence::s1_clearVars()\n");
-
- clearVars();
- _vars[kSeqVarMachineID] = _machine->getId();
- return true;
-}
-
-bool Sequence::s1_set(Instruction &instruction) {
- //debugCN(kDebugScript, "Sequence::s1_set()\n");
-
- *instruction.argp[0] = instruction.getValue();
- return true;
-}
-
-bool Sequence::s1_compare(Instruction &instruction) {
- //debugCN(kDebugScript, "Sequence::s1_compare()\n");
-
- long value = instruction.getValue();
- if (instruction.argv[0] < value)
- _cmpFlags = -1;
- else if (instruction.argv[0] > value)
- _cmpFlags = 1;
- else
- _cmpFlags = 0;
- return true;
-}
-
-bool Sequence::s1_add(Instruction &instruction) {
- //debugCN(kDebugScript, "Sequence::s1_add()\n");
-
- *instruction.argp[0] += instruction.getValue();
- return true;
-}
-
-bool Sequence::s1_sub(Instruction &instruction) {
- //debugCN(kDebugScript, "Sequence::s1_sub()\n");
-
- *instruction.argp[0] -= instruction.getValue();
- return true;
-}
-
-bool Sequence::s1_mul(Instruction &instruction) {
- //debugCN(kDebugScript, "Sequence::s1_mul()\n");
-
- *instruction.argp[0] = FixedMul(instruction.argv[0], instruction.getValue());
- return true;
-}
-
-bool Sequence::s1_div(Instruction &instruction) {
- //debugCN(kDebugScript, "Sequence::s1_div()\n");
-
- // TODO: Catch divisor = 0 in FixedDiv
- *instruction.argp[0] = FixedDiv(instruction.argv[0], instruction.getValue());
- return true;
-}
-
-bool Sequence::s1_and(Instruction &instruction) {
- //debugCN(kDebugScript, "Sequence::s1_and()\n");
-
- *instruction.argp[0] = instruction.argv[0] & instruction.getValue();
- if (*instruction.argp[0])
- _cmpFlags = 0;
- else
- _cmpFlags = 1;
- return true;
-}
-
-bool Sequence::s1_or(Instruction &instruction) {
- //debugCN(kDebugScript, "Sequence::s1_or()\n");
-
- *instruction.argp[0] = instruction.argv[0] | instruction.getValue();
- if (*instruction.argp[0])
- _cmpFlags = 0;
- else
- _cmpFlags = 1;
- return true;
-}
-
-bool Sequence::s1_not(Instruction &instruction) {
- //debugCN(kDebugScript, "Sequence::s1_not()\n");
-
- if (instruction.argv[0] == 0) {
- *instruction.argp[0] = 0x10000;
- _cmpFlags = 1;
- } else {
- *instruction.argp[0] = 0;
- _cmpFlags = 0;
- }
- return true;
-}
-
-bool Sequence::s1_sin(Instruction &instruction) {
- //debugCN(kDebugScript, "Sequence::s1_sin()\n");
-
- int32 tempAngle = *instruction.argp[1] >> 16;
- if (tempAngle < 0)
- tempAngle = 0x0100 - ((-tempAngle) & 0xff);
- else
- tempAngle &= 0xff;
-
- // FIXME: Why use the cosTable in s1_sin() ?
- // Note that sin(0) 0 and sinTable[0] = 0 but cos(0)=1, and indeed
- // cosTable[0] = 65536, which is 1 considered as a fixed point.
- *instruction.argp[0] = -cosTable[tempAngle];
-
- return true;
-}
-
-bool Sequence::s1_cos(Instruction &instruction) {
- //debugCN(kDebugScript, "Sequence::s1_cos()\n");
-
- int32 tempAngle = *instruction.argp[1] >> 16;
- if (tempAngle < 0)
- tempAngle = 0x0100 - ((-tempAngle) & 0xff);
- else
- tempAngle &= 0xff;
-
- // FIXME: Why use the sinTable in s1_cos() ?
- // Note that sin(0) 0 and sinTable[0] = 0 but cos(0)=1, and indeed
- // cosTable[0] = 65536, which is 1 considered as a fixed point.
- *instruction.argp[0] = sinTable[tempAngle];
-
- return true;
-}
-
-bool Sequence::s1_abs(Instruction &instruction) {
- //debugCN(kDebugScript, "Sequence::s1_abs()\n");
-
- *instruction.argp[0] = ABS(instruction.argv[1]);
- return true;
-}
-
-bool Sequence::s1_min(Instruction &instruction) {
- //debugCN(kDebugScript, "Sequence::s1_min()\n");
-
- *instruction.argp[0] = MIN(instruction.argv[1], instruction.argv[2]);
- return true;
-}
-
-bool Sequence::s1_max(Instruction &instruction) {
- //debugCN(kDebugScript, "Sequence::s1_max()\n");
-
- *instruction.argp[0] = MAX(instruction.argv[1], instruction.argv[2]);
- return true;
-}
-
-bool Sequence::s1_mod(Instruction &instruction) {
- //debugCN(kDebugScript, "Sequence::s1_mod()\n");
-
- *instruction.argp[0] = instruction.argv[0] % instruction.getValue();
- return true;
-}
-
-bool Sequence::s1_floor(Instruction &instruction) {
- //debugCN(kDebugScript, "Sequence::s1_floor()\n");
-
- *instruction.argp[0] = instruction.getValue() & 0xffff0000;
- return true;
-}
-
-bool Sequence::s1_round(Instruction &instruction) {
- //debugCN(kDebugScript, "Sequence::s1_round()\n");
-
- if ((*instruction.argp[1] & 0xffff) >= 0x8000)
- *instruction.argp[0] = (*instruction.argp[1] + 0x10000) & 0xffff0000;
- else
- *instruction.argp[0] = *instruction.argp[1] & 0xffff0000;
- return true;
-}
-
-bool Sequence::s1_ceil(Instruction &instruction) {
- //debugCN(kDebugScript, "Sequence::s1_ceil()\n");
-
- if ((*instruction.argp[1] & 0xffff) >= 0)
- *instruction.argp[0] = (*instruction.argp[1] + 0x10000) & 0xffff0000;
- else
- *instruction.argp[0] = *instruction.argp[1] & 0xffff0000;
- return true;
-}
-
-bool Sequence::s1_point(Instruction &instruction) {
- debugCN(kDebugScript, "Sequence::s1_point()\n");
- // TODO
- return true;
-}
-
-bool Sequence::s1_dist2d(Instruction &instruction) {
- debugCN(kDebugScript, "Sequence::s1_dist2d()\n");
- // TODO
- return true;
-}
-
-bool Sequence::s1_crunch(Instruction &instruction) {
- //debugCN(kDebugScript, "Sequence::s1_crunch()\n");
-
- long deltaTime;
-
- if (instruction.argc == 2) {
- deltaTime = _vm->imath_ranged_rand16(instruction.argv[0], instruction.argv[1]);
- } else if (instruction.argc == 1) {
- deltaTime = instruction.argv[0];
- } else {
- deltaTime = 0;
- }
-
- _startTime = _ws->getGlobal(kGlobTime);
-
- //debugCN(kDebugScript, "deltaTime = %ld\n", deltaTime >> 16);
- //g_system->delayMillis(5000);
-
- if (deltaTime >= 0) {
- _switchTime = _ws->getGlobal(kGlobTime) + (deltaTime >> 16);
- //debugCN(kDebugScript, "_ws->getGlobal(kGlobTime) = %ld\n", _ws->getGlobal(kGlobTime));
- //g_system->delayMillis(5000);
- } else {
- _switchTime = -1;
- }
-
- // TODO: Update if walking etc.
-
- return false;
-}
-
-bool Sequence::s1_branch(Instruction &instruction) {
- //debugCN(kDebugScript, "Sequence::s1_branch()\n");
-
- uint32 ofs = instruction.argv[1] >> 16;
- switch (instruction.argv[0] >> 16) {
- case 0: // jmp
- _code->jumpRelative(ofs);
- break;
- case 1: // <
- if (_cmpFlags < 0)
- _code->jumpRelative(ofs);
- break;
- case 2: // <=
- if (_cmpFlags <= 0)
- _code->jumpRelative(ofs);
- break;
- case 3: // ==
- if (_cmpFlags == 0)
- _code->jumpRelative(ofs);
- break;
- case 4: // !=
- if (_cmpFlags != 0)
- _code->jumpRelative(ofs);
- break;
- case 5: // >=
- if (_cmpFlags >= 0)
- _code->jumpRelative(ofs);
- break;
- case 6: // >
- if (_cmpFlags > 0)
- _code->jumpRelative(ofs);
- break;
- }
-
- return true;
-}
-
-bool Sequence::s1_setFrame(Instruction &instruction) {
- //debugCN(kDebugScript, "Sequence::s1_setFrame()\n");
-
- int32 frameIndex;
- if (instruction.argc == 3) {
- frameIndex = _vm->imath_ranged_rand(instruction.argv[1] >> 16, instruction.argv[2] >> 16);
- } else if (instruction.argc == 2) {
- frameIndex = instruction.argv[1] >> 16;
- } else {
- frameIndex = (instruction.argv[0] & 0xFF0000) >> 16;
- }
-
- //debugCN(kDebugScript, "Sequence::s1_setFrame() spriteHash = %d\n", (uint32)instruction.argv[0] >> 24);
- //debugCN(kDebugScript, "Sequence::s1_setFrame() frameIndex = %d\n", frameIndex);
-
- SpriteAsset *spriteAsset = _ws->assets()->getSprite((uint32)instruction.argv[0] >> 24);
- _curFrame = spriteAsset->getFrame(frameIndex);
-
- return true;
-}
-
-bool Sequence::s1_sendMessage(Instruction &instruction) {
- debugCN(kDebugScript, "Sequence::s1_sendMessage()\n");
- // TODO
- return true;
-}
-
-bool Sequence::s1_push(Instruction &instruction) {
- debugCN(kDebugScript, "Sequence::s1_push()\n");
- // TODO
- return true;
-}
-
-bool Sequence::s1_pop(Instruction &instruction) {
- debugCN(kDebugScript, "Sequence::s1_pop()\n");
- // TODO
- return true;
-}
-
-bool Sequence::s1_jumpSub(Instruction &instruction) {
- //debugCN(kDebugScript, "Sequence::s1_jumpSub()\n");
-
- _returnHashes[_returnStackIndex] = _sequenceHash;
- _returnOffsets[_returnStackIndex] = _code->pos();
- _returnStackIndex++;
-
- _sequenceHash = instruction.argv[0] >> 16;
-
- SequenceAsset *sequenceAsset = _ws->assets()->getSequence(_sequenceHash);
-
- // initialize the sequence's bytecode
- byte *code;
- uint32 codeSize;
- sequenceAsset->getCode(code, codeSize);
- _code->setCode(code, codeSize);
-
- return true;
-}
-
-bool Sequence::s1_return(Instruction &instruction) {
- //debugCN(kDebugScript, "Sequence::s1_return()\n");
-
- if (_returnStackIndex <= 0)
- return s1_end(instruction);
-
- _returnStackIndex--;
-
- _sequenceHash = _returnHashes[_returnStackIndex];
- uint32 ofs = _returnOffsets[_returnStackIndex];
-
- SequenceAsset *sequenceAsset = _ws->assets()->getSequence(_sequenceHash);
-
- // initialize the sequence's bytecode
- byte *code;
- uint32 codeSize;
- sequenceAsset->getCode(code, codeSize);
- _code->setCode(code, codeSize);
- _code->jumpAbsolute(ofs);
-
-
- return true;
-}
-
-bool Sequence::s1_getFrameCount(Instruction &instruction) {
- //debugCN(kDebugScript, "Sequence::s1_getFrameCount()\n");
-
- SpriteAsset *spriteAsset = _ws->assets()->getSprite(instruction.argv[1] >> 24);
- *instruction.argp[0] = spriteAsset->getCount() << 16;
- return true;
-}
-
-bool Sequence::s1_getFrameRate(Instruction &instruction) {
- //debugCN(kDebugScript, "Sequence::s1_getFrameRate()\n");
-
- SpriteAsset *spriteAsset = _ws->assets()->getSprite(instruction.argv[1] >> 24);
- *instruction.argp[0] = spriteAsset->getFrameRate();
- return true;
-}
-
-bool Sequence::s1_getCelsPixSpeed(Instruction &instruction) {
- debugCN(kDebugScript, "Sequence::s1_getCelsPixSpeed()\n");
- // TODO
- return true;
-}
-
-bool Sequence::s1_setIndex(Instruction &instruction) {
- debugCN(kDebugScript, "Sequence::s1_setIndex()\n");
- // TODO
- return true;
-}
-
-bool Sequence::s1_setLayer(Instruction &instruction) {
- debugCN(kDebugScript, "Sequence::s1_setLayer()\n");
- //TODO
- return true;
-}
-
-bool Sequence::s1_setDepth(Instruction &instruction) {
- debugCN(kDebugScript, "Sequence::s1_setDepth()\n");
- //TODO
- return true;
-}
-
-bool Sequence::s1_setData(Instruction &instruction) {
- debugCN(kDebugScript, "Sequence::s1_setData()\n");
- //TODO
- return true;
-}
-
-bool Sequence::s1_openStream(Instruction &instruction) {
- //debugCN(kDebugScript, "Sequence::s1_openStream()\n");
-
- _stream = _vm->res()->openFile(_machine->name().c_str());
- streamOpen();
- return true;
-}
-
-bool Sequence::s1_streamNextFrame(Instruction &instruction) {
- //debugCN(kDebugScript, "Sequence::s1_streamNextFrame()\n");
-
- streamNextFrame();
- return true;
-}
-
-bool Sequence::s1_closeStream(Instruction &instruction) {
- debugCN(kDebugScript, "Sequence::s1_closeStream()\n");
- //TODO
- return true;
-}
-
-bool Sequence::streamOpen() {
-
- _streamSpriteAsset = new SpriteAsset(_vm, _stream, _stream->size(), "stream", true);
-
- _vars[kSeqVarSpriteFrameNumber] = -0x10000;
- _vars[kSeqVarSpriteFrameCount] = _streamSpriteAsset->getCount() << 16;
- _vars[kSeqVarSpriteFrameRate] = _streamSpriteAsset->getFrameRate() << 16;
-
- //debugCN(kDebugScript, "Sequence::streamOpen() frames = %d; max = %d x %d\n", _streamSpriteAsset->getCount(), _streamSpriteAsset->getMaxFrameWidth(), _streamSpriteAsset->getMaxFrameHeight());
-
- _curFrame = new M4Sprite(_vm, _streamSpriteAsset->getMaxFrameWidth(), _streamSpriteAsset->getMaxFrameHeight());
- streamNextFrame();
-
- // TODO: Just a hack to see the series with the correct palette.
- _vm->_palette->setPalette(_streamSpriteAsset->getPalette(), 0, 256);
-
- return true;
-}
-
-bool Sequence::streamNextFrame() {
-
- _vars[kSeqVarSpriteFrameNumber] += 0x10000;
-
- int32 frameNum = _vars[kSeqVarSpriteFrameNumber] >> 16;
- if (frameNum >= _streamSpriteAsset->getCount()) {
- // End reached
- return false;
- }
-
- _streamSpriteAsset->loadStreamingFrame(_curFrame, frameNum, _vars[kSeqVarX], _vars[kSeqVarY]);
-
- _vars[kSeqVarWidth] = _curFrame->width() << 16;
- _vars[kSeqVarHeight] = _curFrame->height() << 16;
-
- return true;
-}
-
-void Sequence::streamClose() {
- _stream = NULL;
- _vm->res()->toss(_machine->name().c_str());
- //_vm->res()->purge();
- delete _streamSpriteAsset;
- delete _curFrame;
- _stream = NULL;
- _streamSpriteAsset = NULL;
- _curFrame = NULL;
-}
-
-}
diff --git a/engines/made/database.cpp b/engines/made/database.cpp
index 454fe09a38..2b87f97392 100644
--- a/engines/made/database.cpp
+++ b/engines/made/database.cpp
@@ -56,7 +56,7 @@ const char *Object::getString() {
void Object::setString(const char *str) {
if (getClass() == 0x7FFF) {
- char *objStr = (char*)getData();
+ char *objStr = (char *)getData();
if (str)
strncpy(objStr, str, getSize());
else
@@ -86,10 +86,10 @@ int16 Object::getVectorSize() {
int16 Object::getVectorItem(int16 index) {
if (getClass() == 0x7FFF) {
- byte *vector = (byte*)getData();
+ byte *vector = (byte *)getData();
return vector[index];
} else if (getClass() <= 0x7FFE) {
- int16 *vector = (int16*)getData();
+ int16 *vector = (int16 *)getData();
return READ_LE_UINT16(&vector[index]);
} else {
// should never reach here
@@ -100,10 +100,10 @@ int16 Object::getVectorItem(int16 index) {
void Object::setVectorItem(int16 index, int16 value) {
if (getClass() == 0x7FFF) {
- byte *vector = (byte*)getData();
+ byte *vector = (byte *)getData();
vector[index] = value;
} else if (getClass() <= 0x7FFE) {
- int16 *vector = (int16*)getData();
+ int16 *vector = (int16 *)getData();
WRITE_LE_UINT16(&vector[index], value);
}
}
@@ -526,7 +526,7 @@ int16 *GameDatabaseV2::findObjectProperty(int16 objectIndex, int16 propertyId, i
error("GameDatabaseV2::findObjectProperty(%04X, %04X) Not an object", objectIndex, propertyId);
}
- int16 *prop = (int16*)obj->getData();
+ int16 *prop = (int16 *)obj->getData();
byte count1 = obj->getCount1();
byte count2 = obj->getCount2();
@@ -553,7 +553,7 @@ int16 *GameDatabaseV2::findObjectProperty(int16 objectIndex, int16 propertyId, i
obj = getObject(parentObjectIndex);
- prop = (int16*)obj->getData();
+ prop = (int16 *)obj->getData();
count1 = obj->getCount1();
count2 = obj->getCount2();
@@ -750,7 +750,7 @@ int16 *GameDatabaseV3::findObjectProperty(int16 objectIndex, int16 propertyId, i
error("GameDatabaseV2::findObjectProperty(%04X, %04X) Not an object", objectIndex, propertyId);
}
- int16 *prop = (int16*)obj->getData();
+ int16 *prop = (int16 *)obj->getData();
byte count1 = obj->getCount1();
byte count2 = obj->getCount2();
@@ -762,7 +762,7 @@ int16 *GameDatabaseV3::findObjectProperty(int16 objectIndex, int16 propertyId, i
if ((READ_LE_UINT16(prop) & 0x3FFF) == propertyId) {
if (READ_LE_UINT16(prop) & 0x4000) {
propertyFlag = 1;
- return (int16*)_gameState + READ_LE_UINT16(propPtr1);
+ return (int16 *)_gameState + READ_LE_UINT16(propPtr1);
} else {
propertyFlag = obj->getFlags() & 1;
return propPtr1;
@@ -782,7 +782,7 @@ int16 *GameDatabaseV3::findObjectProperty(int16 objectIndex, int16 propertyId, i
obj = getObject(parentObjectIndex);
- prop = (int16*)obj->getData();
+ prop = (int16 *)obj->getData();
count1 = obj->getCount1();
count2 = obj->getCount2();
@@ -794,7 +794,7 @@ int16 *GameDatabaseV3::findObjectProperty(int16 objectIndex, int16 propertyId, i
if ((READ_LE_UINT16(prop) & 0x3FFF) == propertyId) {
if (READ_LE_UINT16(prop) & 0x4000) {
propertyFlag = 1;
- return (int16*)_gameState + READ_LE_UINT16(propPtr1);
+ return (int16 *)_gameState + READ_LE_UINT16(propPtr1);
} else {
propertyFlag = obj->getFlags() & 1;
return propPtr1;
@@ -806,7 +806,7 @@ int16 *GameDatabaseV3::findObjectProperty(int16 objectIndex, int16 propertyId, i
if ((READ_LE_UINT16(prop) & 0x3FFF) == propertyId) {
if (READ_LE_UINT16(prop) & 0x4000) {
propertyFlag = 1;
- return (int16*)_gameState + READ_LE_UINT16(propertyPtr);
+ return (int16 *)_gameState + READ_LE_UINT16(propertyPtr);
} else {
propertyFlag = obj->getFlags() & 1;
return propertyPtr;
diff --git a/engines/made/database.h b/engines/made/database.h
index 63f0557196..89b4b45357 100644
--- a/engines/made/database.h
+++ b/engines/made/database.h
@@ -151,9 +151,9 @@ public:
void dumpObject(int16 index);
protected:
- typedef Common::HashMap<uint32, int16*> ObjectPropertyCacheMap;
+ typedef Common::HashMap<uint32, int16 *> ObjectPropertyCacheMap;
MadeEngine *_vm;
- Common::Array<Object*> _objects;
+ Common::Array<Object *> _objects;
ObjectPropertyCacheMap _objectPropertyCache;
byte *_gameState;
uint32 _gameStateSize;
diff --git a/engines/made/detection.cpp b/engines/made/detection.cpp
index 2a9beed5c4..2591e92af3 100644
--- a/engines/made/detection.cpp
+++ b/engines/made/detection.cpp
@@ -80,7 +80,7 @@ static const MadeGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformPC,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO0()
},
GID_RTZ,
0,
@@ -98,7 +98,7 @@ static const MadeGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformPC,
ADGF_CD,
- GUIO1(GUIO_NONE)
+ GUIO0()
},
GID_RTZ,
0,
@@ -115,7 +115,7 @@ static const MadeGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformPC,
ADGF_CD,
- GUIO1(GUIO_NONE)
+ GUIO0()
},
GID_RTZ,
0,
@@ -132,7 +132,7 @@ static const MadeGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformPC,
ADGF_CD,
- GUIO1(GUIO_NONE)
+ GUIO0()
},
GID_RTZ,
0,
@@ -150,7 +150,7 @@ static const MadeGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformPC,
ADGF_CD,
- GUIO1(GUIO_NONE)
+ GUIO0()
},
GID_RTZ,
0,
@@ -167,7 +167,7 @@ static const MadeGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformPC,
ADGF_CD,
- GUIO1(GUIO_NONE)
+ GUIO0()
},
GID_RTZ,
0,
@@ -185,7 +185,7 @@ static const MadeGameDescription gameDescriptions[] = {
Common::DE_DEU,
Common::kPlatformPC,
ADGF_CD,
- GUIO1(GUIO_NONE)
+ GUIO0()
},
GID_RTZ,
0,
@@ -203,7 +203,7 @@ static const MadeGameDescription gameDescriptions[] = {
Common::DE_DEU,
Common::kPlatformPC,
ADGF_CD,
- GUIO1(GUIO_NONE)
+ GUIO0()
},
GID_RTZ,
0,
@@ -221,7 +221,7 @@ static const MadeGameDescription gameDescriptions[] = {
Common::IT_ITA,
Common::kPlatformPC,
ADGF_CD,
- GUIO1(GUIO_NONE)
+ GUIO0()
},
GID_RTZ,
0,
@@ -239,7 +239,7 @@ static const MadeGameDescription gameDescriptions[] = {
Common::IT_ITA,
Common::kPlatformPC,
ADGF_CD,
- GUIO1(GUIO_NONE)
+ GUIO0()
},
GID_RTZ,
0,
@@ -257,7 +257,7 @@ static const MadeGameDescription gameDescriptions[] = {
Common::FR_FRA,
Common::kPlatformPC,
ADGF_CD,
- GUIO1(GUIO_NONE)
+ GUIO0()
},
GID_RTZ,
0,
@@ -275,7 +275,7 @@ static const MadeGameDescription gameDescriptions[] = {
Common::FR_FRA,
Common::kPlatformPC,
ADGF_CD,
- GUIO1(GUIO_NONE)
+ GUIO0()
},
GID_RTZ,
0,
@@ -309,7 +309,7 @@ static const MadeGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformPC,
ADGF_DEMO,
- GUIO1(GUIO_NONE)
+ GUIO0()
},
GID_RTZ,
0,
@@ -327,7 +327,7 @@ static const MadeGameDescription gameDescriptions[] = {
Common::JA_JPN,
Common::kPlatformPC,
ADGF_CD,
- GUIO1(GUIO_NONE)
+ GUIO0()
},
GID_RTZ,
0,
@@ -345,7 +345,7 @@ static const MadeGameDescription gameDescriptions[] = {
Common::JA_JPN,
Common::kPlatformFMTowns,
ADGF_CD,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GID_RTZ,
0,
@@ -363,7 +363,7 @@ static const MadeGameDescription gameDescriptions[] = {
Common::JA_JPN,
Common::kPlatformPC98,
ADGF_CD,
- GUIO1(GUIO_NONE)
+ GUIO0()
},
GID_RTZ,
0,
@@ -508,7 +508,7 @@ static MadeGameDescription g_fallbackDesc = {
Common::UNK_LANG,
Common::kPlatformPC,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO0()
},
0,
0,
diff --git a/engines/made/graphics.cpp b/engines/made/graphics.cpp
index 30496d8595..4d3fc7116a 100644
--- a/engines/made/graphics.cpp
+++ b/engines/made/graphics.cpp
@@ -83,7 +83,7 @@ void decompressImage(byte *source, Graphics::Surface &surface, uint16 cmdOffs, u
if ((maskFlags != 0) && (maskFlags != 2) && (pixelFlags != 0) && (pixelFlags != 2) && (cmdFlags != 0))
error("decompressImage() Unsupported flags: cmdFlags = %02X; maskFlags = %02X, pixelFlags = %02X", cmdFlags, maskFlags, pixelFlags);
- byte *destPtr = (byte*)surface.getBasePtr(0, 0);
+ byte *destPtr = (byte *)surface.getBasePtr(0, 0);
byte lineBuf[640 * 4];
byte bitBuf[40];
@@ -196,7 +196,7 @@ void decompressMovieImage(byte *source, Graphics::Surface &surface, uint16 cmdOf
byte *maskBuffer = source + maskOffs;
byte *pixelBuffer = source + pixelOffs;
- byte *destPtr = (byte*)surface.getBasePtr(0, 0);
+ byte *destPtr = (byte *)surface.getBasePtr(0, 0);
byte bitBuf[40];
diff --git a/engines/made/resource.h b/engines/made/resource.h
index 9e0a729c58..a789069272 100644
--- a/engines/made/resource.h
+++ b/engines/made/resource.h
@@ -111,7 +111,7 @@ public:
int16 getWidth() const { return _width; }
int16 getHeight() const { return _height; }
protected:
- Common::Array<Graphics::Surface*> _frames;
+ Common::Array<Graphics::Surface *> _frames;
uint16 _flags;
int16 _width, _height;
};
@@ -210,7 +210,7 @@ protected:
bool _isV1;
typedef Common::Array<ResourceSlot> ResourceSlots;
- typedef Common::HashMap<uint32, ResourceSlots*> ResMap;
+ typedef Common::HashMap<uint32, ResourceSlots *> ResMap;
void openResourceBlock(const char *filename, Common::File *blockFile, uint32 resType);
ResMap _resSlots;
@@ -219,12 +219,12 @@ protected:
void loadIndex(ResourceSlots *slots);
- template <class T>
+ template<class T>
T *createResource(uint32 resType, int index) {
ResourceSlot *slot = getResourceSlot(resType, index);
if (!slot)
return NULL;
- T *res = (T*)getResourceFromCache(slot);
+ T *res = (T *)getResourceFromCache(slot);
if (!res) {
byte *buffer;
uint32 size;
diff --git a/engines/made/screen.cpp b/engines/made/screen.cpp
index dbe2f1c7ba..b49bfff840 100644
--- a/engines/made/screen.cpp
+++ b/engines/made/screen.cpp
@@ -179,10 +179,10 @@ void Screen::drawSurface(Graphics::Surface *sourceSurface, int x, int y, int16 f
clipHeight = clipInfo.clipRect.bottom - y;
}
- source = (byte*)sourceSurface->getBasePtr(0, startY);
- dest = (byte*)clipInfo.destSurface->getBasePtr(x, y);
+ source = (byte *)sourceSurface->getBasePtr(0, startY);
+ dest = (byte *)clipInfo.destSurface->getBasePtr(x, y);
if (_vm->getGameID() != GID_RTZ)
- maskp = (byte*)_maskDrawCtx.destSurface->getBasePtr(x, y);
+ maskp = (byte *)_maskDrawCtx.destSurface->getBasePtr(x, y);
int32 sourcePitch, linePtrAdd, sourceAdd;
byte *linePtr;
@@ -437,15 +437,15 @@ uint16 Screen::placeSprite(uint16 channelIndex, uint16 flexIndex, int16 x, int16
PictureResource *flex = _vm->_res->getPicture(flexIndex);
if (flex) {
- Graphics::Surface *surf = flex->getPicture();
+ //Graphics::Surface *surf = flex->getPicture();
int16 state = 1;
- int16 x1, y1, x2, y2;
+ /*int16 x1, y1, x2, y2;
x1 = x;
y1 = y;
x2 = x + surf->w + 1;
- y2 = y + surf->h + 1;
+ y2 = y + surf->h + 1;*/
if (_ground == 0)
state |= 2;
@@ -485,12 +485,12 @@ uint16 Screen::placeAnim(uint16 channelIndex, uint16 animIndex, int16 x, int16 y
if (anim) {
int16 state = 1;
- int16 x1, y1, x2, y2;
+ /*int16 x1, y1, x2, y2;
x1 = x;
y1 = y;
x2 = x + anim->getWidth();
- y2 = y + anim->getHeight();
+ y2 = y + anim->getHeight();*/
if (anim->getFlags() == 1 || _ground == 0)
state |= 2;
@@ -543,7 +543,7 @@ uint16 Screen::placeText(uint16 channelIndex, uint16 textObjectIndex, int16 x, i
Object *obj = _vm->_dat->getObject(textObjectIndex);
const char *text = obj->getString();
- int16 x1, y1, x2, y2;
+ //int16 x1, y1, x2, y2;
setFont(fontNum);
@@ -557,10 +557,10 @@ uint16 Screen::placeText(uint16 channelIndex, uint16 textObjectIndex, int16 x, i
y--;
}
- x1 = x;
+ /*x1 = x;
y1 = y;
x2 = x + textWidth;
- y2 = y + textHeight;
+ y2 = y + textHeight;*/
if (textWidth > 0 && outlineColor != -1) {
x++;
@@ -633,7 +633,7 @@ void Screen::printChar(uint c, int16 x, int16 y, byte color) {
return;
byte p;
- byte *dest = (byte*)_fontDrawCtx.destSurface->getBasePtr(x, y);
+ byte *dest = (byte *)_fontDrawCtx.destSurface->getBasePtr(x, y);
for (uint yc = 0; yc < height; yc++) {
p = charData[yc];
diff --git a/engines/made/screenfx.cpp b/engines/made/screenfx.cpp
index ff0d393885..4e0d463b53 100644
--- a/engines/made/screenfx.cpp
+++ b/engines/made/screenfx.cpp
@@ -231,10 +231,10 @@ void ScreenEffects::copyFxRect(Graphics::Surface *surface, int16 x1, int16 y1, i
vfxY1 = y1 & 7;
- byte *source = (byte*)surface->getBasePtr(x1, y1);
+ byte *source = (byte *)surface->getBasePtr(x1, y1);
Graphics::Surface *vgaScreen = _screen->lockScreen();
- byte *dest = (byte*)vgaScreen->getBasePtr(x1, y1);
+ byte *dest = (byte *)vgaScreen->getBasePtr(x1, y1);
int16 addX = x2 / 16;
diff --git a/engines/made/scriptfuncs.h b/engines/made/scriptfuncs.h
index 6b3301755d..03d29c4592 100644
--- a/engines/made/scriptfuncs.h
+++ b/engines/made/scriptfuncs.h
@@ -68,7 +68,7 @@ protected:
Audio::SoundHandle _pcSpeakerHandle1, _pcSpeakerHandle2;
Audio::PCSpeaker *_pcSpeaker1, *_pcSpeaker2;
- Common::Array<const ExternalFunc*> _externalFuncs;
+ Common::Array<const ExternalFunc *> _externalFuncs;
Common::Array<const char *> _externalFuncNames;
GenericResource *_musicRes;
diff --git a/engines/metaengine.h b/engines/metaengine.h
index 8eb8044b34..d9c1360042 100644
--- a/engines/metaengine.h
+++ b/engines/metaengine.h
@@ -224,9 +224,6 @@ typedef PluginSubclass<MetaEngine> EnginePlugin;
* Singleton class which manages all Engine plugins.
*/
class EngineManager : public Common::Singleton<EngineManager> {
-private:
- friend class Common::Singleton<SingletonBaseType>;
-
public:
GameDescriptor findGameInLoadedPlugins(const Common::String &gameName, const EnginePlugin **plugin = NULL) const;
GameDescriptor findGame(const Common::String &gameName, const EnginePlugin **plugin = NULL) const;
diff --git a/engines/mohawk/bitmap.cpp b/engines/mohawk/bitmap.cpp
index f61516c91d..4edde31236 100644
--- a/engines/mohawk/bitmap.cpp
+++ b/engines/mohawk/bitmap.cpp
@@ -887,7 +887,7 @@ void DOSBitmap::expandEGAPlanes(Graphics::Surface *surface, Common::SeekableRead
assert(surface->format.bytesPerPixel == 1);
// Note that the image is in EGA planar form and not just standard 4bpp
- // This seems to contradict the PoP specs which seem to do
+ // This seems to contradict the PoP specs which seem to do something else
byte *dst = (byte *)surface->pixels;
diff --git a/engines/mohawk/console.cpp b/engines/mohawk/console.cpp
index 0234c86c7e..a7a650d8ed 100644
--- a/engines/mohawk/console.cpp
+++ b/engines/mohawk/console.cpp
@@ -21,7 +21,6 @@
*/
#include "mohawk/console.h"
-#include "mohawk/graphics.h"
#include "mohawk/livingbooks.h"
#include "mohawk/sound.h"
#include "mohawk/video.h"
@@ -36,6 +35,7 @@
#ifdef ENABLE_MYST
#include "mohawk/myst.h"
#include "mohawk/myst_areas.h"
+#include "mohawk/myst_graphics.h"
#include "mohawk/myst_scripts.h"
#endif
diff --git a/engines/mohawk/cstime.h b/engines/mohawk/cstime.h
index 0bc236f930..db06b9791e 100644
--- a/engines/mohawk/cstime.h
+++ b/engines/mohawk/cstime.h
@@ -25,7 +25,7 @@
#include "mohawk/mohawk.h"
#include "mohawk/console.h"
-#include "mohawk/graphics.h"
+#include "mohawk/cstime_graphics.h"
#include "common/random.h"
#include "common/list.h"
diff --git a/engines/mohawk/cstime_graphics.cpp b/engines/mohawk/cstime_graphics.cpp
new file mode 100644
index 0000000000..3a1452e67c
--- /dev/null
+++ b/engines/mohawk/cstime_graphics.cpp
@@ -0,0 +1,64 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "mohawk/cstime.h"
+#include "mohawk/cstime_graphics.h"
+#include "mohawk/resource.h"
+
+#include "common/system.h"
+#include "engines/util.h"
+
+namespace Mohawk {
+
+CSTimeGraphics::CSTimeGraphics(MohawkEngine_CSTime *vm) : GraphicsManager(), _vm(vm) {
+ _bmpDecoder = new MohawkBitmap();
+
+ initGraphics(640, 480, true);
+}
+
+CSTimeGraphics::~CSTimeGraphics() {
+ delete _bmpDecoder;
+}
+
+void CSTimeGraphics::drawRect(Common::Rect rect, byte color) {
+ rect.clip(Common::Rect(640, 480));
+
+ // Useful with debugging. Shows where hotspots are on the screen and whether or not they're active.
+ if (!rect.isValidRect() || rect.width() == 0 || rect.height() == 0)
+ return;
+
+ Graphics::Surface *screen = _vm->_system->lockScreen();
+
+ screen->frameRect(rect, color);
+
+ _vm->_system->unlockScreen();
+}
+
+MohawkSurface *CSTimeGraphics::decodeImage(uint16 id) {
+ return _bmpDecoder->decodeImage(_vm->getResource(ID_TBMP, id));
+}
+
+Common::Array<MohawkSurface *> CSTimeGraphics::decodeImages(uint16 id) {
+ return _bmpDecoder->decodeImages(_vm->getResource(ID_TBMH, id));
+}
+
+} // End of namespace Mohawk
diff --git a/engines/mohawk/cstime_graphics.h b/engines/mohawk/cstime_graphics.h
new file mode 100644
index 0000000000..5f034f47f4
--- /dev/null
+++ b/engines/mohawk/cstime_graphics.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 MOHAWK_CSTIME_GRAPHICS_H
+#define MOHAWK_CSTIME_GRAPHICS_H
+
+#include "mohawk/graphics.h"
+
+namespace Mohawk {
+
+class MohawkEngine_CSTime;
+
+class CSTimeGraphics : public GraphicsManager {
+public:
+ CSTimeGraphics(MohawkEngine_CSTime *vm);
+ ~CSTimeGraphics();
+
+ void drawRect(Common::Rect rect, byte color);
+
+protected:
+ MohawkSurface *decodeImage(uint16 id);
+ Common::Array<MohawkSurface *> decodeImages(uint16 id);
+ MohawkEngine *getVM() { return (MohawkEngine *)_vm; }
+
+private:
+ MohawkBitmap *_bmpDecoder;
+ MohawkEngine_CSTime *_vm;
+};
+
+} // End of namespace Mohawk
+
+#endif
diff --git a/engines/mohawk/detection_tables.h b/engines/mohawk/detection_tables.h
index 94f18e134b..08df0a2cbe 100644
--- a/engines/mohawk/detection_tables.h
+++ b/engines/mohawk/detection_tables.h
@@ -34,7 +34,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_UNSTABLE,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_MYST,
0,
@@ -52,7 +52,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_DEMO | ADGF_UNSTABLE,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_MYST,
GF_DEMO,
@@ -70,7 +70,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::DE_DEU,
Common::kPlatformWindows,
ADGF_UNSTABLE,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_MYST,
0,
@@ -88,7 +88,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::DE_DEU,
Common::kPlatformWindows,
ADGF_UNSTABLE,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_MYST,
0,
@@ -106,7 +106,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::ES_ESP,
Common::kPlatformWindows,
ADGF_UNSTABLE,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_MYST,
0,
@@ -124,7 +124,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::JA_JPN,
Common::kPlatformWindows,
ADGF_UNSTABLE,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_MYST,
0,
@@ -142,7 +142,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::FR_FRA,
Common::kPlatformWindows,
ADGF_UNSTABLE,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_MYST,
0,
@@ -160,7 +160,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_UNSTABLE,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_MAKINGOF,
0,
@@ -178,7 +178,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::JA_JPN,
Common::kPlatformWindows,
ADGF_UNSTABLE,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_MAKINGOF,
0,
@@ -196,7 +196,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_UNSTABLE,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_MYST,
GF_ME,
@@ -214,7 +214,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformMacintosh,
ADGF_UNSTABLE,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_MYST,
GF_ME,
@@ -232,7 +232,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::DE_DEU,
Common::kPlatformWindows,
ADGF_UNSTABLE,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_MYST,
GF_ME,
@@ -250,7 +250,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::FR_FRA,
Common::kPlatformWindows,
ADGF_UNSTABLE,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_MYST,
GF_ME,
@@ -268,7 +268,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_UNSTABLE,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_RIVEN,
0,
@@ -286,7 +286,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_UNSTABLE,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_RIVEN,
0,
@@ -304,7 +304,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::ES_ESP,
Common::kPlatformWindows,
ADGF_UNSTABLE,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_RIVEN,
0,
@@ -322,7 +322,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_UNSTABLE,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_RIVEN,
GF_DVD,
@@ -340,7 +340,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::DE_DEU,
Common::kPlatformWindows,
ADGF_UNSTABLE,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_RIVEN,
GF_DVD,
@@ -358,7 +358,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::FR_FRA,
Common::kPlatformWindows,
ADGF_UNSTABLE,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_RIVEN,
GF_DVD,
@@ -376,7 +376,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_DEMO | ADGF_UNSTABLE,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_RIVEN,
GF_DEMO,
@@ -391,7 +391,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_UNSTABLE,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_CSTIME,
0,
@@ -406,7 +406,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_DEMO | ADGF_UNSTABLE,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_CSTIME,
GF_DEMO,
@@ -422,7 +422,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_UNSTABLE,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_ZOOMBINI,
GF_HASMIDI,
@@ -437,7 +437,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_UNSTABLE,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_ZOOMBINI,
GF_HASMIDI,
@@ -452,7 +452,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_ZOOMBINI,
GF_HASMIDI,
@@ -467,7 +467,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::DE_DEU,
Common::kPlatformWindows,
ADGF_UNSTABLE,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_ZOOMBINI,
GF_HASMIDI,
@@ -482,7 +482,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::FR_FRA,
Common::kPlatformWindows,
ADGF_UNSTABLE,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_ZOOMBINI,
GF_HASMIDI,
@@ -497,7 +497,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_UNSTABLE,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_CSWORLD,
0,
@@ -512,7 +512,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_UNSTABLE,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_CSWORLD,
0,
@@ -527,7 +527,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_UNSTABLE,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_CSAMTRAK,
0,
@@ -545,7 +545,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_GRB,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV2,
0,
@@ -563,7 +563,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::FR_FRA,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV2,
0,
@@ -581,7 +581,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::DE_DEU,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV2,
0,
@@ -597,7 +597,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_GRB,
Common::kPlatformMacintosh,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV2,
0,
@@ -613,7 +613,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::DE_DEU,
Common::kPlatformMacintosh,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV2,
0,
@@ -629,7 +629,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::FR_FRA,
Common::kPlatformMacintosh,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV2,
0,
@@ -646,7 +646,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV1,
0,
@@ -663,7 +663,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV1,
0,
@@ -678,7 +678,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_UNSTABLE,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV5,
0,
@@ -693,7 +693,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_UNSTABLE,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV5,
0,
@@ -709,7 +709,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_UNSTABLE,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV3,
0,
@@ -724,7 +724,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_UNSTABLE,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV3,
0,
@@ -739,7 +739,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformMacintosh,
ADGF_UNSTABLE,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV3,
0,
@@ -754,7 +754,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_UNSTABLE,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_JAMESMATH,
GF_HASMIDI,
@@ -770,7 +770,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_UNSTABLE,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_JAMESMATH,
GF_HASMIDI,
@@ -785,7 +785,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_UNSTABLE,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_TREEHOUSE,
GF_HASMIDI,
@@ -800,7 +800,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV3,
0,
@@ -816,7 +816,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV3,
0,
@@ -831,7 +831,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformMacintosh,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV3,
0,
@@ -846,7 +846,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV2,
0,
@@ -862,7 +862,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV2,
0,
@@ -877,7 +877,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformMacintosh,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV2,
0,
@@ -892,7 +892,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformMacintosh,
ADGF_DEMO,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV2,
GF_DEMO,
@@ -907,7 +907,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_UNSTABLE,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_1STDEGREE,
GF_HASMIDI,
@@ -925,7 +925,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::FR_FRA,
Common::kPlatformWindows,
ADGF_UNSTABLE,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_1STDEGREE,
GF_HASMIDI,
@@ -940,7 +940,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_UNSTABLE,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_CSUSA,
0,
@@ -955,7 +955,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV1,
0,
@@ -972,7 +972,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV1,
0,
@@ -988,7 +988,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_GRB,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV2,
0,
@@ -1004,7 +1004,23 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_GRB,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
+ },
+ GType_LIVINGBOOKSV2,
+ 0,
+ 0,
+ },
+
+ // Tortoise and the Hare Hebrew variant - From georgeqgreg on bug #3441928
+ {
+ {
+ "tortoise",
+ "",
+ AD_ENTRY1("TORTB.LB", "23135777370cf1ff00aa7247e93642d3"),
+ Common::HE_ISR,
+ Common::kPlatformWindows,
+ ADGF_NO_FLAGS,
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV2,
0,
@@ -1020,7 +1036,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::DE_DEU,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV2,
0,
@@ -1036,7 +1052,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::DE_DEU,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV2,
0,
@@ -1052,7 +1068,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::FR_FRA,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV2,
0,
@@ -1068,7 +1084,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::FR_FRA,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV2,
0,
@@ -1083,7 +1099,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_DEMO,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV1,
GF_DEMO,
@@ -1098,7 +1114,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_DEMO,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV1,
GF_DEMO,
@@ -1114,7 +1130,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_DEMO,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV1,
GF_DEMO,
@@ -1129,7 +1145,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformMacintosh,
ADGF_DEMO,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV1,
GF_DEMO,
@@ -1144,7 +1160,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV1,
GF_LB_10,
@@ -1161,7 +1177,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV1,
GF_LB_10,
@@ -1177,7 +1193,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformMacintosh,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV1,
GF_LB_10,
@@ -1193,7 +1209,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV1,
GF_LB_10,
@@ -1208,7 +1224,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_DEMO,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV1,
GF_DEMO | GF_LB_10,
@@ -1223,7 +1239,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_DEMO,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV1,
GF_DEMO,
@@ -1239,7 +1255,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_DEMO,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV1,
GF_DEMO,
@@ -1254,7 +1270,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformMacintosh,
ADGF_DEMO,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV1,
GF_DEMO | GF_LB_10,
@@ -1269,7 +1285,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformMacintosh,
ADGF_DEMO,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV1,
GF_DEMO,
@@ -1286,7 +1302,24 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_UNSTABLE,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
+ },
+ GType_LIVINGBOOKSV3,
+ 0,
+ 0
+ },
+
+ // Just Grandma and Me 2.0 Macintosh
+ // From aluff in bug #3461368
+ {
+ {
+ "grandma",
+ "v2.0",
+ AD_ENTRY1("BookOutline", "99fe5c8ace79f0542e6390bc3b58f25a"),
+ Common::EN_ANY,
+ Common::kPlatformMacintosh,
+ ADGF_UNSTABLE,
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV3,
0,
@@ -1303,7 +1336,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV1,
GF_LB_10,
@@ -1319,7 +1352,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV1,
GF_LB_10,
@@ -1335,7 +1368,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_GRB,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV2,
0,
@@ -1351,7 +1384,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::DE_DEU,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV2,
0,
@@ -1367,7 +1400,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::FR_FRA,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV2,
0,
@@ -1382,7 +1415,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_DEMO,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV1,
GF_DEMO | GF_LB_10,
@@ -1397,7 +1430,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_DEMO,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV1,
GF_DEMO,
@@ -1413,7 +1446,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_DEMO,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV1,
GF_DEMO,
@@ -1428,7 +1461,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformMacintosh,
ADGF_DEMO,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV1,
GF_DEMO | GF_LB_10,
@@ -1443,7 +1476,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformMacintosh,
ADGF_DEMO,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV1,
GF_DEMO,
@@ -1460,7 +1493,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV1,
0,
@@ -1476,7 +1509,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformMacintosh,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV1,
0,
@@ -1491,7 +1524,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_DEMO,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV1,
GF_DEMO,
@@ -1507,7 +1540,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_DEMO,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV1,
GF_DEMO,
@@ -1522,7 +1555,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformMacintosh,
ADGF_DEMO,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV1,
GF_DEMO,
@@ -1538,7 +1571,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV1,
0,
@@ -1555,7 +1588,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV1,
0,
@@ -1571,7 +1604,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformMacintosh,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV1,
0,
@@ -1586,7 +1619,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_DEMO,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV1,
GF_DEMO,
@@ -1601,7 +1634,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_DEMO,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV1,
GF_DEMO,
@@ -1617,7 +1650,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_DEMO,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV1,
GF_DEMO,
@@ -1632,7 +1665,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformMacintosh,
ADGF_DEMO,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV1,
GF_DEMO,
@@ -1647,7 +1680,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_UNSTABLE,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV3,
0,
@@ -1663,7 +1696,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_UNSTABLE,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV3,
0,
@@ -1678,7 +1711,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformMacintosh,
ADGF_UNSTABLE,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV3,
0,
@@ -1694,7 +1727,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV1,
0,
@@ -1710,7 +1743,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformMacintosh,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV1,
0,
@@ -1726,7 +1759,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_GRB,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV2,
0,
@@ -1742,7 +1775,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::DE_DEU,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV2,
0,
@@ -1758,7 +1791,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::FR_FRA,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV2,
0,
@@ -1775,7 +1808,24 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_UNSTABLE,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
+ },
+ GType_LIVINGBOOKSV3,
+ 0,
+ 0
+ },
+
+ // Arthur Birthday (English) Version 2.0 Macintosh
+ // From aluff in bug #3461368
+ {
+ {
+ "arthurbday",
+ "",
+ AD_ENTRY1("BookOutline", "8e4fddb5b761c8cf2a3b448dd38422be"),
+ Common::EN_ANY,
+ Common::kPlatformMacintosh,
+ ADGF_UNSTABLE,
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV3,
0,
@@ -1790,7 +1840,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_DEMO,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV1,
GF_DEMO,
@@ -1806,7 +1856,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_DEMO,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV1,
GF_DEMO,
@@ -1821,7 +1871,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformMacintosh,
ADGF_DEMO,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV1,
GF_DEMO,
@@ -1836,7 +1886,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV1,
0,
@@ -1851,7 +1901,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformMacintosh,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV1,
0,
@@ -1867,7 +1917,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_GRB,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV2,
0,
@@ -1883,7 +1933,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::DE_DEU,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV2,
0,
@@ -1899,7 +1949,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV2,
0,
@@ -1915,7 +1965,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_GRB,
Common::kPlatformMacintosh,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV2,
0,
@@ -1931,7 +1981,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::DE_DEU,
Common::kPlatformMacintosh,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV2,
0,
@@ -1947,7 +1997,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::FR_FRA,
Common::kPlatformMacintosh,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV2,
0,
@@ -1963,7 +2013,23 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_DEMO,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
+ },
+ GType_LIVINGBOOKSV1,
+ GF_DEMO,
+ "MONSTER.EXE"
+ },
+
+ // From GeorgeQGreg
+ {
+ {
+ "lilmonster",
+ "Demo",
+ AD_ENTRY1("MONSTER.512", "f603f04c1824d1034ec0366416a059c9"),
+ Common::EN_ANY,
+ Common::kPlatformWindows,
+ ADGF_DEMO,
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV1,
GF_DEMO,
@@ -1978,7 +2044,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_UNSTABLE,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV3,
0,
@@ -1993,7 +2059,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformMacintosh,
ADGF_UNSTABLE,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV3,
0,
@@ -2008,7 +2074,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_UNSTABLE,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV4,
0,
@@ -2023,7 +2089,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformMacintosh,
ADGF_UNSTABLE,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV4,
0,
@@ -2041,7 +2107,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::FR_FRA,
Common::kPlatformWindows,
ADGF_UNSTABLE,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV4,
0,
@@ -2056,7 +2122,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV1,
0,
@@ -2071,7 +2137,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformMacintosh,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV1,
0,
@@ -2086,7 +2152,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV2,
0,
@@ -2102,7 +2168,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformMacintosh,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV1,
0,
@@ -2117,7 +2183,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_UNSTABLE,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV3,
0,
@@ -2132,7 +2198,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformMacintosh,
ADGF_UNSTABLE,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV3,
0,
@@ -2147,7 +2213,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV1,
0,
@@ -2164,7 +2230,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV1,
0,
@@ -2179,7 +2245,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformMacintosh,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV1,
0,
@@ -2195,7 +2261,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV3,
0,
@@ -2212,7 +2278,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV3,
0,
@@ -2228,7 +2294,23 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformMacintosh,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
+ },
+ GType_LIVINGBOOKSV3,
+ 0,
+ 0
+ },
+
+ // From aluff in bug #3461368
+ {
+ {
+ "beardark",
+ "",
+ AD_ENTRY1("BookOutline", "b56746b3b2c062c8588bfb6b28e137c1"),
+ Common::EN_ANY,
+ Common::kPlatformMacintosh,
+ ADGF_NO_FLAGS,
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV3,
0,
@@ -2243,7 +2325,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_UNSTABLE,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV4,
0,
@@ -2258,7 +2340,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformMacintosh,
ADGF_UNSTABLE,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV4,
0,
@@ -2275,7 +2357,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV2,
0,
@@ -2291,7 +2373,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV2,
0,
@@ -2307,7 +2389,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformMacintosh,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV2,
0,
@@ -2324,7 +2406,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV2,
0,
@@ -2340,7 +2422,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformMacintosh,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV2,
0,
@@ -2356,7 +2438,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_GRB,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV2,
0,
@@ -2372,7 +2454,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::DE_DEU,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV2,
0,
@@ -2388,7 +2470,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::FR_FRA,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV2,
0,
@@ -2404,7 +2486,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_GRB,
Common::kPlatformMacintosh,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV2,
0,
@@ -2420,7 +2502,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::DE_DEU,
Common::kPlatformMacintosh,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV2,
0,
@@ -2436,7 +2518,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::FR_FRA,
Common::kPlatformMacintosh,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV2,
0,
@@ -2459,7 +2541,7 @@ static const MohawkGameDescription fallbackDescs[] = {
Common::UNK_LANG,
Common::kPlatformWindows,
ADGF_UNSTABLE,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_MYST,
0,
@@ -2474,7 +2556,7 @@ static const MohawkGameDescription fallbackDescs[] = {
Common::UNK_LANG,
Common::kPlatformWindows,
ADGF_UNSTABLE,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_MAKINGOF,
0,
@@ -2489,7 +2571,7 @@ static const MohawkGameDescription fallbackDescs[] = {
Common::UNK_LANG,
Common::kPlatformWindows,
ADGF_UNSTABLE,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_MYST,
GF_ME,
@@ -2504,7 +2586,7 @@ static const MohawkGameDescription fallbackDescs[] = {
Common::UNK_LANG,
Common::kPlatformWindows,
ADGF_UNSTABLE,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_RIVEN,
0,
@@ -2519,7 +2601,7 @@ static const MohawkGameDescription fallbackDescs[] = {
Common::UNK_LANG,
Common::kPlatformWindows,
ADGF_UNSTABLE,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_RIVEN,
GF_DVD,
diff --git a/engines/mohawk/graphics.cpp b/engines/mohawk/graphics.cpp
index c4326d175f..a08d034ef7 100644
--- a/engines/mohawk/graphics.cpp
+++ b/engines/mohawk/graphics.cpp
@@ -20,30 +20,13 @@
*
*/
+#include "mohawk/mohawk.h"
#include "mohawk/resource.h"
#include "mohawk/graphics.h"
-#include "mohawk/livingbooks.h"
-#include "common/substream.h"
#include "common/system.h"
-#include "common/textconsole.h"
#include "engines/util.h"
#include "graphics/palette.h"
-#include "graphics/primitives.h"
-#include "gui/message.h"
-
-#ifdef ENABLE_CSTIME
-#include "mohawk/cstime.h"
-#endif
-
-#ifdef ENABLE_MYST
-#include "mohawk/myst.h"
-#include "graphics/jpeg.h"
-#endif
-
-#ifdef ENABLE_RIVEN
-#include "mohawk/riven.h"
-#endif
namespace Mohawk {
@@ -108,9 +91,9 @@ GraphicsManager::~GraphicsManager() {
}
void GraphicsManager::clearCache() {
- for (Common::HashMap<uint16, MohawkSurface*>::iterator it = _cache.begin(); it != _cache.end(); it++)
+ for (Common::HashMap<uint16, MohawkSurface *>::iterator it = _cache.begin(); it != _cache.end(); it++)
delete it->_value;
- for (Common::HashMap<uint16, Common::Array<MohawkSurface*> >::iterator it = _subImageCache.begin(); it != _subImageCache.end(); it++) {
+ for (Common::HashMap<uint16, Common::Array<MohawkSurface *> >::iterator it = _subImageCache.begin(); it != _subImageCache.end(); it++) {
Common::Array<MohawkSurface *> &array = it->_value;
for (uint i = 0; i < array.size(); i++)
delete array[i];
@@ -262,983 +245,4 @@ void GraphicsManager::addImageToCache(uint16 id, MohawkSurface *surface) {
_cache[id] = surface;
}
-#ifdef ENABLE_MYST
-
-MystGraphics::MystGraphics(MohawkEngine_Myst* vm) : GraphicsManager(), _vm(vm) {
- _bmpDecoder = new MystBitmap();
-
- _viewport = Common::Rect(544, 332);
-
- // The original version of Myst could run in 8bpp color too.
- // However, it dithered videos to 8bpp and they looked considerably
- // worse (than they already did :P). So we're not even going to
- // support 8bpp mode in Myst (Myst ME required >8bpp anyway).
- initGraphics(_viewport.width(), _viewport.height(), true, NULL); // What an odd screen size!
-
- _pixelFormat = _vm->_system->getScreenFormat();
-
- if (_pixelFormat.bytesPerPixel == 1)
- error("Myst requires greater than 256 colors to run");
-
- if (_vm->getFeatures() & GF_ME) {
- _jpegDecoder = new Graphics::JPEG();
- _pictDecoder = new Graphics::PictDecoder(_pixelFormat);
- } else {
- _jpegDecoder = NULL;
- _pictDecoder = NULL;
- }
-
- _pictureFile.entries = NULL;
-
- // Initialize our buffer
- _backBuffer = new Graphics::Surface();
- _backBuffer->create(_vm->_system->getWidth(), _vm->_system->getHeight(), _pixelFormat);
-
- _nextAllowedDrawTime = _vm->_system->getMillis();
- _enableDrawingTimeSimulation = 0;
-}
-
-MystGraphics::~MystGraphics() {
- delete _bmpDecoder;
- delete _jpegDecoder;
- delete _pictDecoder;
- delete[] _pictureFile.entries;
-
- _backBuffer->free();
- delete _backBuffer;
-}
-
-static const char* picFileNames[] = {
- "CHpics",
- "",
- "DUpics",
- "INpics",
- "MEpics",
- "MYpics",
- "SEpics",
- "STpics",
- ""
-};
-
-void MystGraphics::loadExternalPictureFile(uint16 stack) {
- if (_vm->getPlatform() != Common::kPlatformMacintosh)
- return;
-
- if (_pictureFile.picFile.isOpen())
- _pictureFile.picFile.close();
- delete[] _pictureFile.entries;
-
- if (!scumm_stricmp(picFileNames[stack], ""))
- return;
-
- if (!_pictureFile.picFile.open(picFileNames[stack]))
- error ("Could not open external picture file \'%s\'", picFileNames[stack]);
-
- _pictureFile.pictureCount = _pictureFile.picFile.readUint32BE();
- _pictureFile.entries = new PictureFile::PictureEntry[_pictureFile.pictureCount];
-
- for (uint32 i = 0; i < _pictureFile.pictureCount; i++) {
- _pictureFile.entries[i].offset = _pictureFile.picFile.readUint32BE();
- _pictureFile.entries[i].size = _pictureFile.picFile.readUint32BE();
- _pictureFile.entries[i].id = _pictureFile.picFile.readUint16BE();
- _pictureFile.entries[i].type = _pictureFile.picFile.readUint16BE();
- _pictureFile.entries[i].width = _pictureFile.picFile.readUint16BE();
- _pictureFile.entries[i].height = _pictureFile.picFile.readUint16BE();
- }
-}
-
-MohawkSurface *MystGraphics::decodeImage(uint16 id) {
- MohawkSurface *mhkSurface = 0;
-
- // Myst ME uses JPEG/PICT images instead of compressed Windows Bitmaps for room images,
- // though there are a few weird ones that use that format. For further nonsense with images,
- // the Macintosh version stores images in external "picture files." We check them before
- // going to check for a PICT resource.
- if (_vm->getFeatures() & GF_ME && _vm->getPlatform() == Common::kPlatformMacintosh && _pictureFile.picFile.isOpen()) {
- for (uint32 i = 0; i < _pictureFile.pictureCount; i++)
- if (_pictureFile.entries[i].id == id) {
- if (_pictureFile.entries[i].type == 0) {
- Common::SeekableReadStream *stream = new Common::SeekableSubReadStream(&_pictureFile.picFile, _pictureFile.entries[i].offset, _pictureFile.entries[i].offset + _pictureFile.entries[i].size);
-
- if (!_jpegDecoder->read(stream))
- error("Could not decode Myst ME Mac JPEG");
-
- mhkSurface = new MohawkSurface(_jpegDecoder->getSurface(_pixelFormat));
- delete stream;
- } else if (_pictureFile.entries[i].type == 1) {
- mhkSurface = new MohawkSurface(_pictDecoder->decodeImage(new Common::SeekableSubReadStream(&_pictureFile.picFile, _pictureFile.entries[i].offset, _pictureFile.entries[i].offset + _pictureFile.entries[i].size)));
- } else
- error ("Unknown Picture File type %d", _pictureFile.entries[i].type);
- break;
- }
- }
-
- // We're not using the external Mac files, so it's time to delve into the main Mohawk
- // archives. However, we still don't know if it's a PICT or WDIB resource. If it's Myst
- // ME it's most likely a PICT, and if it's original it's definitely a WDIB. However,
- // Myst ME throws us another curve ball in that PICT resources can contain WDIB's instead
- // of PICT's.
- if (!mhkSurface) {
- bool isPict = false;
- Common::SeekableReadStream *dataStream = NULL;
-
- if (_vm->getFeatures() & GF_ME && _vm->hasResource(ID_PICT, id)) {
- // The PICT resource exists. However, it could still contain a MystBitmap
- // instead of a PICT image...
- dataStream = _vm->getResource(ID_PICT, id);
- } else // No PICT, so the WDIB must exist. Let's go grab it.
- dataStream = _vm->getResource(ID_WDIB, id);
-
- if (_vm->getFeatures() & GF_ME) {
- // Here we detect whether it's really a PICT or a WDIB. Since a MystBitmap
- // would be compressed, there's no way to detect for the BM without a hack.
- // So, we search for the PICT version opcode for detection.
- dataStream->seek(512 + 10); // 512 byte pict header
- isPict = (dataStream->readUint32BE() == 0x001102FF);
- dataStream->seek(0);
- }
-
- if (isPict)
- mhkSurface = new MohawkSurface(_pictDecoder->decodeImage(dataStream));
- else {
- mhkSurface = _bmpDecoder->decodeImage(dataStream);
- mhkSurface->convertToTrueColor();
- }
- }
-
- assert(mhkSurface);
- return mhkSurface;
-}
-
-void MystGraphics::copyImageSectionToScreen(uint16 image, Common::Rect src, Common::Rect dest) {
- Graphics::Surface *surface = findImage(image)->getSurface();
-
- // Make sure the image is bottom aligned in the dest rect
- dest.top = dest.bottom - MIN<int>(surface->h, dest.height());
-
- // Convert from bitmap coordinates to surface coordinates
- uint16 top = surface->h - (src.top + MIN<int>(surface->h, dest.height()));
-
- // Do not draw the top pixels if the image is too tall
- if (dest.height() > _viewport.height())
- top += dest.height() - _viewport.height();
-
- // Clip the destination rect to the screen
- if (dest.right > _vm->_system->getWidth() || dest.bottom > _vm->_system->getHeight())
- dest.debugPrint(4, "Clipping destination rect to the screen");
- dest.right = CLIP<int>(dest.right, 0, _vm->_system->getWidth());
- dest.bottom = CLIP<int>(dest.bottom, 0, _vm->_system->getHeight());
-
- uint16 width = MIN<int>(surface->w, dest.width());
- uint16 height = MIN<int>(surface->h, dest.height());
-
- // Clamp Width and Height to within src surface dimensions
- if (src.left + width > surface->w)
- width = surface->w - src.left;
- if (src.top + height > surface->h)
- height = surface->h - src.top;
-
- debug(3, "MystGraphics::copyImageSectionToScreen()");
- debug(3, "\tImage: %d", image);
- debug(3, "\tsrc.left: %d", src.left);
- debug(3, "\tsrc.top: %d", src.top);
- debug(3, "\tdest.left: %d", dest.left);
- debug(3, "\tdest.top: %d", dest.top);
- debug(3, "\twidth: %d", width);
- debug(3, "\theight: %d", height);
-
- simulatePreviousDrawDelay(dest);
-
- _vm->_system->copyRectToScreen((byte *)surface->getBasePtr(src.left, top), surface->pitch, dest.left, dest.top, width, height);
-}
-
-void MystGraphics::copyImageSectionToBackBuffer(uint16 image, Common::Rect src, Common::Rect dest) {
- Graphics::Surface *surface = findImage(image)->getSurface();
-
- // Make sure the image is bottom aligned in the dest rect
- dest.top = dest.bottom - MIN<int>(surface->h, dest.height());
-
- // Convert from bitmap coordinates to surface coordinates
- uint16 top = surface->h - (src.top + MIN<int>(surface->h, dest.height()));
-
- // Do not draw the top pixels if the image is too tall
- if (dest.height() > _viewport.height()) {
- top += dest.height() - _viewport.height();
- }
-
- // Clip the destination rect to the screen
- if (dest.right > _vm->_system->getWidth() || dest.bottom > _vm->_system->getHeight())
- dest.debugPrint(4, "Clipping destination rect to the screen");
- dest.right = CLIP<int>(dest.right, 0, _vm->_system->getWidth());
- dest.bottom = CLIP<int>(dest.bottom, 0, _vm->_system->getHeight());
-
- uint16 width = MIN<int>(surface->w, dest.width());
- uint16 height = MIN<int>(surface->h, dest.height());
-
- // Clamp Width and Height to within src surface dimensions
- if (src.left + width > surface->w)
- width = surface->w - src.left;
- if (src.top + height > surface->h)
- height = surface->h - src.top;
-
- debug(3, "MystGraphics::copyImageSectionToBackBuffer()");
- debug(3, "\tImage: %d", image);
- debug(3, "\tsrc.left: %d", src.left);
- debug(3, "\tsrc.top: %d", src.top);
- debug(3, "\tdest.left: %d", dest.left);
- debug(3, "\tdest.top: %d", dest.top);
- debug(3, "\twidth: %d", width);
- debug(3, "\theight: %d", height);
-
- for (uint16 i = 0; i < height; i++)
- memcpy(_backBuffer->getBasePtr(dest.left, i + dest.top), surface->getBasePtr(src.left, top + i), width * surface->format.bytesPerPixel);
-}
-
-void MystGraphics::copyImageToScreen(uint16 image, Common::Rect dest) {
- copyImageSectionToScreen(image, Common::Rect(544, 333), dest);
-}
-
-void MystGraphics::copyImageToBackBuffer(uint16 image, Common::Rect dest) {
- copyImageSectionToBackBuffer(image, Common::Rect(544, 333), dest);
-}
-
-void MystGraphics::copyBackBufferToScreen(Common::Rect r) {
- r.clip(_viewport);
-
- simulatePreviousDrawDelay(r);
-
- _vm->_system->copyRectToScreen((byte *)_backBuffer->getBasePtr(r.left, r.top), _backBuffer->pitch, r.left, r.top, r.width(), r.height());
-}
-
-void MystGraphics::runTransition(uint16 type, Common::Rect rect, uint16 steps, uint16 delay) {
-
- // Do not artificially delay during transitions
- int oldEnableDrawingTimeSimulation = _enableDrawingTimeSimulation;
- _enableDrawingTimeSimulation = 0;
-
- switch (type) {
- case 0: {
- debugC(kDebugScript, "Left to Right");
-
- uint16 step = (rect.right - rect.left) / steps;
- Common::Rect area = rect;
- for (uint i = 0; i < steps; i++) {
- area.left = rect.left + step * i;
- area.right = area.left + step;
-
- _vm->_system->delayMillis(delay);
-
- copyBackBufferToScreen(area);
- _vm->_system->updateScreen();
- }
- if (area.right < rect.right) {
- area.left = area.right;
- area.right = rect.right;
-
- copyBackBufferToScreen(area);
- _vm->_system->updateScreen();
- }
- }
- break;
- case 1: {
- debugC(kDebugScript, "Right to Left");
-
- uint16 step = (rect.right - rect.left) / steps;
- Common::Rect area = rect;
- for (uint i = 0; i < steps; i++) {
- area.right = rect.right - step * i;
- area.left = area.right - step;
-
- _vm->_system->delayMillis(delay);
-
- copyBackBufferToScreen(area);
- _vm->_system->updateScreen();
- }
- if (area.left > rect.left) {
- area.right = area.left;
- area.left = rect.left;
-
- copyBackBufferToScreen(area);
- _vm->_system->updateScreen();
- }
- }
- break;
- case 5: {
- debugC(kDebugScript, "Top to Bottom");
-
- uint16 step = (rect.bottom - rect.top) / steps;
- Common::Rect area = rect;
- for (uint i = 0; i < steps; i++) {
- area.top = rect.top + step * i;
- area.bottom = area.top + step;
-
- _vm->_system->delayMillis(delay);
-
- copyBackBufferToScreen(area);
- _vm->_system->updateScreen();
- }
- if (area.bottom < rect.bottom) {
- area.top = area.bottom;
- area.bottom = rect.bottom;
-
- copyBackBufferToScreen(area);
- _vm->_system->updateScreen();
- }
- }
- break;
- case 6: {
- debugC(kDebugScript, "Bottom to Top");
-
- uint16 step = (rect.bottom - rect.top) / steps;
- Common::Rect area = rect;
- for (uint i = 0; i < steps; i++) {
- area.bottom = rect.bottom - step * i;
- area.top = area.bottom - step;
-
- _vm->_system->delayMillis(delay);
-
- copyBackBufferToScreen(area);
- _vm->_system->updateScreen();
- }
- if (area.top > rect.top) {
- area.bottom = area.top;
- area.top = rect.top;
-
- copyBackBufferToScreen(area);
- _vm->_system->updateScreen();
- }
- }
- break;
- default:
- warning("Unknown Update Direction");
-
- //TODO: Replace minimal implementation
- copyBackBufferToScreen(rect);
- _vm->_system->updateScreen();
- break;
- }
-
- _enableDrawingTimeSimulation = oldEnableDrawingTimeSimulation;
-}
-
-void MystGraphics::drawRect(Common::Rect rect, RectState state) {
- rect.clip(_viewport);
-
- // Useful with debugging. Shows where hotspots are on the screen and whether or not they're active.
- if (!rect.isValidRect() || rect.width() == 0 || rect.height() == 0)
- return;
-
- Graphics::Surface *screen = _vm->_system->lockScreen();
-
- if (state == kRectEnabled)
- screen->frameRect(rect, _pixelFormat.RGBToColor(0, 255, 0));
- else if (state == kRectUnreachable)
- screen->frameRect(rect, _pixelFormat.RGBToColor(0, 0, 255));
- else
- screen->frameRect(rect, _pixelFormat.RGBToColor(255, 0, 0));
-
- _vm->_system->unlockScreen();
-}
-
-void MystGraphics::drawLine(const Common::Point &p1, const Common::Point &p2, uint32 color) {
- _backBuffer->drawLine(p1.x, p1.y, p2.x, p2.y, color);
-}
-
-void MystGraphics::enableDrawingTimeSimulation(bool enable) {
- if (enable)
- _enableDrawingTimeSimulation++;
- else
- _enableDrawingTimeSimulation--;
-
- if (_enableDrawingTimeSimulation < 0)
- _enableDrawingTimeSimulation = 0;
-}
-
-void MystGraphics::simulatePreviousDrawDelay(const Common::Rect &dest) {
- uint32 time = 0;
-
- if (_enableDrawingTimeSimulation) {
- time = _vm->_system->getMillis();
-
- // Do not draw anything new too quickly after the previous draw call
- // so that images stay at least a little while on screen
- // This is enabled only for scripted draw calls
- if (time < _nextAllowedDrawTime)
- _vm->_system->delayMillis(_nextAllowedDrawTime - time);
- }
-
- // Next draw call allowed at DELAY + AERA * COEFF milliseconds from now
- time = _vm->_system->getMillis();
- _nextAllowedDrawTime = time + _constantDrawDelay + dest.height() * dest.width() / _proportionalDrawDelay;
-}
-
-void MystGraphics::copyBackBufferToScreenWithSaturation(int16 saturation) {
- Graphics::Surface *screen = _vm->_system->lockScreen();
-
- for (uint16 y = 0; y < _viewport.height(); y++)
- for (uint16 x = 0; x < _viewport.width(); x++) {
- uint32 color;
- uint8 r, g, b;
-
- if (_pixelFormat.bytesPerPixel == 2)
- color = *(const uint16 *)_backBuffer->getBasePtr(x, y);
- else
- color = *(const uint32 *)_backBuffer->getBasePtr(x, y);
-
- _pixelFormat.colorToRGB(color, r, g, b);
-
- r = CLIP<int16>((int16)r - saturation, 0, 255);
- g = CLIP<int16>((int16)g - saturation, 0, 255);
- b = CLIP<int16>((int16)b - saturation, 0, 255);
-
- color = _pixelFormat.RGBToColor(r, g, b);
-
- if (_pixelFormat.bytesPerPixel == 2) {
- uint16 *dst = (uint16 *)screen->getBasePtr(x, y);
- *dst = color;
- } else {
- uint32 *dst = (uint32 *)screen->getBasePtr(x, y);
- *dst = color;
- }
- }
-
- _vm->_system->unlockScreen();
- _vm->_system->updateScreen();
-}
-
-void MystGraphics::fadeToBlack() {
- for (int16 i = 0; i < 256; i += 32) {
- copyBackBufferToScreenWithSaturation(i);
- }
-}
-
-void MystGraphics::fadeFromBlack() {
- for (int16 i = 256; i >= 0; i -= 32) {
- copyBackBufferToScreenWithSaturation(i);
- }
-}
-
-#endif // ENABLE_MYST
-
-#ifdef ENABLE_RIVEN
-
-RivenGraphics::RivenGraphics(MohawkEngine_Riven* vm) : GraphicsManager(), _vm(vm) {
- _bitmapDecoder = new MohawkBitmap();
-
- // Give me the best you've got!
- initGraphics(608, 436, true, NULL);
- _pixelFormat = _vm->_system->getScreenFormat();
-
- if (_pixelFormat.bytesPerPixel == 1)
- error("Riven requires greater than 256 colors to run");
-
- // The actual game graphics only take up the first 392 rows. The inventory
- // occupies the rest of the screen and we don't use the buffer to hold that.
- _mainScreen = new Graphics::Surface();
- _mainScreen->create(608, 392, _pixelFormat);
-
- _updatesEnabled = true;
- _scheduledTransition = -1; // no transition
- _dirtyScreen = false;
- _inventoryDrawn = false;
-
- _creditsImage = 302;
- _creditsPos = 0;
-}
-
-RivenGraphics::~RivenGraphics() {
- _mainScreen->free();
- delete _mainScreen;
- delete _bitmapDecoder;
-}
-
-MohawkSurface *RivenGraphics::decodeImage(uint16 id) {
- MohawkSurface *surface = _bitmapDecoder->decodeImage(_vm->getResource(ID_TBMP, id));
- surface->convertToTrueColor();
- return surface;
-}
-
-void RivenGraphics::copyImageToScreen(uint16 image, uint32 left, uint32 top, uint32 right, uint32 bottom) {
- Graphics::Surface *surface = findImage(image)->getSurface();
-
- // Clip the width to fit on the screen. Fixes some images.
- if (left + surface->w > 608)
- surface->w = 608 - left;
-
- for (uint16 i = 0; i < surface->h; i++)
- memcpy(_mainScreen->getBasePtr(left, i + top), surface->getBasePtr(0, i), surface->w * surface->format.bytesPerPixel);
-
- _dirtyScreen = true;
-}
-
-void RivenGraphics::drawPLST(uint16 x) {
- Common::SeekableReadStream* plst = _vm->getResource(ID_PLST, _vm->getCurCard());
- uint16 recordCount = plst->readUint16BE();
-
- for (uint16 i = 0; i < recordCount; i++) {
- uint16 index = plst->readUint16BE();
- uint16 id = plst->readUint16BE();
- uint16 left = plst->readUint16BE();
- uint16 top = plst->readUint16BE();
- uint16 right = plst->readUint16BE();
- uint16 bottom = plst->readUint16BE();
-
- // We are also checking here to make sure we haven't drawn the image yet on screen.
- // This fixes problems with drawing PLST 1 twice and some other images twice. PLST
- // 1 is sometimes not called by the scripts, so some cards don't appear if we don't
- // draw PLST 1 each time. This "hack" is here to catch any PLST attempting to draw
- // twice. There should never be a problem with doing it this way.
- if (index == x && !(Common::find(_activatedPLSTs.begin(), _activatedPLSTs.end(), x) != _activatedPLSTs.end())) {
- debug(0, "Drawing image %d", id);
- copyImageToScreen(id, left, top, right, bottom);
- _activatedPLSTs.push_back(x);
- break;
- }
- }
-
- delete plst;
-}
-
-void RivenGraphics::updateScreen(Common::Rect updateRect) {
- if (_updatesEnabled) {
- _vm->runUpdateScreenScript();
-
- if (_dirtyScreen) {
- _activatedPLSTs.clear();
-
- // Copy to screen if there's no transition. Otherwise transition. ;)
- if (_scheduledTransition < 0)
- _vm->_system->copyRectToScreen((byte *)_mainScreen->getBasePtr(updateRect.left, updateRect.top), _mainScreen->pitch, updateRect.left, updateRect.top, updateRect.width(), updateRect.height());
- else
- runScheduledTransition();
-
- // Finally, update the screen.
- _vm->_system->updateScreen();
- _dirtyScreen = false;
- }
- }
-}
-
-void RivenGraphics::scheduleWaterEffect(uint16 sfxeID) {
- Common::SeekableReadStream *sfxeStream = _vm->getResource(ID_SFXE, sfxeID);
-
- if (sfxeStream->readUint16BE() != 'SL')
- error ("Unknown sfxe tag");
-
- // Read in header info
- SFXERecord sfxeRecord;
- sfxeRecord.frameCount = sfxeStream->readUint16BE();
- uint32 offsetTablePosition = sfxeStream->readUint32BE();
- sfxeRecord.rect.left = sfxeStream->readUint16BE();
- sfxeRecord.rect.top = sfxeStream->readUint16BE();
- sfxeRecord.rect.right = sfxeStream->readUint16BE();
- sfxeRecord.rect.bottom = sfxeStream->readUint16BE();
- sfxeRecord.speed = sfxeStream->readUint16BE();
- // Skip the rest of the fields...
-
- // Read in offsets
- sfxeStream->seek(offsetTablePosition);
- uint32 *frameOffsets = new uint32[sfxeRecord.frameCount];
- for (uint16 i = 0; i < sfxeRecord.frameCount; i++)
- frameOffsets[i] = sfxeStream->readUint32BE();
- sfxeStream->seek(frameOffsets[0]);
-
- // Read in the scripts
- for (uint16 i = 0; i < sfxeRecord.frameCount; i++)
- sfxeRecord.frameScripts.push_back(sfxeStream->readStream((i == sfxeRecord.frameCount - 1) ? sfxeStream->size() - frameOffsets[i] : frameOffsets[i + 1] - frameOffsets[i]));
-
- // Set it to the first frame
- sfxeRecord.curFrame = 0;
- sfxeRecord.lastFrameTime = 0;
-
- delete[] frameOffsets;
- delete sfxeStream;
- _waterEffects.push_back(sfxeRecord);
-}
-
-void RivenGraphics::clearWaterEffects() {
- _waterEffects.clear();
-}
-
-bool RivenGraphics::runScheduledWaterEffects() {
- // Don't run the effect if it's disabled
- if (_vm->_vars["waterenabled"] == 0)
- return false;
-
- Graphics::Surface *screen = NULL;
-
- for (uint16 i = 0; i < _waterEffects.size(); i++) {
- if (_vm->_system->getMillis() > _waterEffects[i].lastFrameTime + 1000 / _waterEffects[i].speed) {
- // Lock the screen!
- if (!screen)
- screen = _vm->_system->lockScreen();
-
- // Make sure the script is at the starting point
- Common::SeekableReadStream *script = _waterEffects[i].frameScripts[_waterEffects[i].curFrame];
- if (script->pos() != 0)
- script->seek(0);
-
- // Run script
- uint16 curRow = 0;
- for (uint16 op = script->readUint16BE(); op != 4; op = script->readUint16BE()) {
- if (op == 1) { // Increment Row
- curRow++;
- } else if (op == 3) { // Copy Pixels
- uint16 dstLeft = script->readUint16BE();
- uint16 srcLeft = script->readUint16BE();
- uint16 srcTop = script->readUint16BE();
- uint16 rowWidth = script->readUint16BE();
- memcpy ((byte *)screen->getBasePtr(dstLeft, curRow + _waterEffects[i].rect.top), (byte *)_mainScreen->getBasePtr(srcLeft, srcTop), rowWidth * _pixelFormat.bytesPerPixel);
- } else if (op != 4) { // End of Script
- error ("Unknown SFXE opcode %d", op);
- }
- }
-
- // Increment frame
- _waterEffects[i].curFrame++;
- if (_waterEffects[i].curFrame == _waterEffects[i].frameCount)
- _waterEffects[i].curFrame = 0;
-
- // Set the new time
- _waterEffects[i].lastFrameTime = _vm->_system->getMillis();
- }
- }
-
- // Unlock the screen if it has been locked and return true to update the screen
- if (screen) {
- _vm->_system->unlockScreen();
- return true;
- }
-
- return false;
-}
-
-void RivenGraphics::scheduleTransition(uint16 id, Common::Rect rect) {
- _scheduledTransition = id;
- _transitionRect = rect;
-}
-
-void RivenGraphics::runScheduledTransition() {
- if (_scheduledTransition < 0) // No transition is scheduled
- return;
-
- // TODO: There's a lot to be done here...
-
- // Note: Transitions 0-11 are actual transitions, but none are used in-game.
- // There's no point in implementing them if they're not used. These extra
- // transitions were found by hacking scripts.
-
- switch (_scheduledTransition) {
- case 0: // Swipe Left
- case 1: // Swipe Right
- case 2: // Swipe Up
- case 3: // Swipe Down
- case 12: // Pan Left
- case 13: // Pan Right
- case 14: // Pan Up
- case 15: // Pan Down
- case 16: // Dissolve
- case 17: // Dissolve (tspit CARD 155)
- break;
- default:
- if (_scheduledTransition >= 4 && _scheduledTransition <= 11)
- error("Found unused transition %d", _scheduledTransition);
- else
- error("Found unknown transition %d", _scheduledTransition);
- }
-
- // For now, just copy the image to screen without doing any transition.
- _vm->_system->copyRectToScreen((byte *)_mainScreen->pixels, _mainScreen->pitch, 0, 0, _mainScreen->w, _mainScreen->h);
- _vm->_system->updateScreen();
-
- _scheduledTransition = -1; // Clear scheduled transition
-}
-
-void RivenGraphics::clearMainScreen() {
- _mainScreen->fillRect(Common::Rect(0, 0, 608, 392), _pixelFormat.RGBToColor(0, 0, 0));
-}
-
-void RivenGraphics::fadeToBlack() {
- // The transition speed is forced to best here
- setTransitionSpeed(kRivenTransitionSpeedBest);
- scheduleTransition(16);
- clearMainScreen();
- runScheduledTransition();
-}
-
-void RivenGraphics::showInventory() {
- // Don't redraw the inventory
- if (_inventoryDrawn)
- return;
-
- // Clear the inventory area
- clearInventoryArea();
-
- // Draw the demo's exit button
- if (_vm->getFeatures() & GF_DEMO) {
- // extras.mhk tBMP 101 contains "EXIT" instead of Atrus' journal in the demo!
- // The demo's extras.mhk contains all the other inventory/marble/credits image
- // but has hacked tBMP 101 with "EXIT". *sigh*
- drawInventoryImage(101, g_demoExitRect);
- } else {
- // We don't want to show the inventory on setup screens or in other journals.
- if (_vm->getCurStack() == aspit)
- return;
-
- // There are three books and three vars. We have three different
- // combinations. At the start you have just Atrus' journal. Later,
- // you get Catherine's journal and the trap book. Near the end,
- // you lose the trap book and have just the two journals.
-
- bool hasCathBook = _vm->_vars["acathbook"] != 0;
- bool hasTrapBook = _vm->_vars["atrapbook"] != 0;
-
- if (!hasCathBook) {
- drawInventoryImage(101, g_atrusJournalRect1);
- } else if (!hasTrapBook) {
- drawInventoryImage(101, g_atrusJournalRect2);
- drawInventoryImage(102, g_cathJournalRect2);
- } else {
- drawInventoryImage(101, g_atrusJournalRect3);
- drawInventoryImage(102, g_cathJournalRect3);
- drawInventoryImage(100, g_trapBookRect3);
- }
- }
-
- _vm->_system->updateScreen();
- _inventoryDrawn = true;
-}
-
-void RivenGraphics::hideInventory() {
- // Don't hide the inventory twice
- if (!_inventoryDrawn)
- return;
-
- // Clear the area
- clearInventoryArea();
-
- _inventoryDrawn = false;
-}
-
-void RivenGraphics::clearInventoryArea() {
- // Clear the inventory area
- static const Common::Rect inventoryRect = Common::Rect(0, 392, 608, 436);
-
- // Lock the screen
- Graphics::Surface *screen = _vm->_system->lockScreen();
-
- // Fill the inventory area with black
- screen->fillRect(inventoryRect, _pixelFormat.RGBToColor(0, 0, 0));
-
- _vm->_system->unlockScreen();
-}
-
-void RivenGraphics::drawInventoryImage(uint16 id, const Common::Rect *rect) {
- MohawkSurface *mhkSurface = _bitmapDecoder->decodeImage(_vm->getExtrasResource(ID_TBMP, id));
- mhkSurface->convertToTrueColor();
- Graphics::Surface *surface = mhkSurface->getSurface();
-
- _vm->_system->copyRectToScreen((byte *)surface->pixels, surface->pitch, rect->left, rect->top, surface->w, surface->h);
-
- delete mhkSurface;
-}
-
-void RivenGraphics::drawRect(Common::Rect rect, bool active) {
- // Useful with debugging. Shows where hotspots are on the screen and whether or not they're active.
- Graphics::Surface *screen = _vm->_system->lockScreen();
-
- if (active)
- screen->frameRect(rect, _pixelFormat.RGBToColor(0, 255, 0));
- else
- screen->frameRect(rect, _pixelFormat.RGBToColor(255, 0, 0));
-
- _vm->_system->unlockScreen();
-}
-
-void RivenGraphics::drawImageRect(uint16 id, Common::Rect srcRect, Common::Rect dstRect) {
- // Draw tBMP id from srcRect to dstRect
- Graphics::Surface *surface = findImage(id)->getSurface();
-
- assert(srcRect.width() == dstRect.width() && srcRect.height() == dstRect.height());
-
- for (uint16 i = 0; i < srcRect.height(); i++)
- memcpy(_mainScreen->getBasePtr(dstRect.left, i + dstRect.top), surface->getBasePtr(srcRect.left, i + srcRect.top), srcRect.width() * surface->format.bytesPerPixel);
-
- _dirtyScreen = true;
-}
-
-void RivenGraphics::drawExtrasImage(uint16 id, Common::Rect dstRect) {
- MohawkSurface *mhkSurface = _bitmapDecoder->decodeImage(_vm->getExtrasResource(ID_TBMP, id));
- mhkSurface->convertToTrueColor();
- Graphics::Surface *surface = mhkSurface->getSurface();
-
- assert(dstRect.width() == surface->w);
-
- for (uint16 i = 0; i < surface->h; i++)
- memcpy(_mainScreen->getBasePtr(dstRect.left, i + dstRect.top), surface->getBasePtr(0, i), surface->pitch);
-
- delete mhkSurface;
- _dirtyScreen = true;
-}
-
-void RivenGraphics::beginCredits() {
- // Clear the old cache
- clearCache();
-
- // Now cache all the credits images
- for (uint16 i = 302; i <= 320; i++) {
- MohawkSurface *surface = _bitmapDecoder->decodeImage(_vm->getExtrasResource(ID_TBMP, i));
- surface->convertToTrueColor();
- addImageToCache(i, surface);
- }
-
- // And clear our screen too
- clearMainScreen();
-}
-
-void RivenGraphics::updateCredits() {
- if ((_creditsImage == 303 || _creditsImage == 304) && _creditsPos == 0)
- fadeToBlack();
-
- if (_creditsImage < 304) {
- // For the first two credit images, they are faded from black to the image and then out again
- scheduleTransition(16);
-
- Graphics::Surface *frame = findImage(_creditsImage++)->getSurface();
-
- for (int y = 0; y < frame->h; y++)
- memcpy(_mainScreen->getBasePtr(124, y), frame->getBasePtr(0, y), frame->pitch);
-
- runScheduledTransition();
- } else {
- // Otheriwse, we're scrolling
- // Move the screen up one row
- memmove(_mainScreen->pixels, _mainScreen->getBasePtr(0, 1), _mainScreen->pitch * (_mainScreen->h - 1));
-
- // Only update as long as we're not before the last frame
- // Otherwise, we're just moving up a row (which we already did)
- if (_creditsImage <= 320) {
- // Copy the next row to the bottom of the screen
- Graphics::Surface *frame = findImage(_creditsImage)->getSurface();
- memcpy(_mainScreen->getBasePtr(124, _mainScreen->h - 1), frame->getBasePtr(0, _creditsPos), frame->pitch);
- _creditsPos++;
-
- if (_creditsPos == _mainScreen->h) {
- _creditsImage++;
- _creditsPos = 0;
- }
- }
-
- // Now flush the new screen
- _vm->_system->copyRectToScreen((byte *)_mainScreen->pixels, _mainScreen->pitch, 0, 0, _mainScreen->w, _mainScreen->h);
- _vm->_system->updateScreen();
- }
-}
-
-#endif // ENABLE_RIVEN
-
-LBGraphics::LBGraphics(MohawkEngine_LivingBooks *vm, uint16 width, uint16 height) : GraphicsManager(), _vm(vm) {
- _bmpDecoder = _vm->isPreMohawk() ? new LivingBooksBitmap_v1() : new MohawkBitmap();
-
- initGraphics(width, height, true);
-}
-
-LBGraphics::~LBGraphics() {
- delete _bmpDecoder;
-}
-
-MohawkSurface *LBGraphics::decodeImage(uint16 id) {
- if (_vm->isPreMohawk())
- return _bmpDecoder->decodeImage(_vm->wrapStreamEndian(ID_BMAP, id));
-
- return _bmpDecoder->decodeImage(_vm->getResource(ID_TBMP, id));
-}
-
-void LBGraphics::copyOffsetAnimImageToScreen(uint16 image, int left, int top) {
- MohawkSurface *mhkSurface = findImage(image);
-
- left -= mhkSurface->getOffsetX();
- top -= mhkSurface->getOffsetY();
-
- GraphicsManager::copyAnimImageToScreen(image, left, top);
-}
-
-bool LBGraphics::imageIsTransparentAt(uint16 image, bool useOffsets, int x, int y) {
- MohawkSurface *mhkSurface = findImage(image);
-
- if (useOffsets) {
- x += mhkSurface->getOffsetX();
- y += mhkSurface->getOffsetY();
- }
-
- if (x < 0 || y < 0)
- return true;
-
- Graphics::Surface *surface = mhkSurface->getSurface();
- if (x >= surface->w || y >= surface->h)
- return true;
-
- return *(byte *)surface->getBasePtr(x, y) == 0;
-}
-
-void LBGraphics::setPalette(uint16 id) {
- // Old Living Books games use the old CTBL-style palette format while newer
- // games use the better tPAL format which can store partial palettes.
- if (_vm->isPreMohawk()) {
- Common::SeekableSubReadStreamEndian *ctblStream = _vm->wrapStreamEndian(ID_CTBL, id);
- uint16 colorCount = ctblStream->readUint16();
- byte *palette = new byte[colorCount * 3];
-
- for (uint16 i = 0; i < colorCount; i++) {
- palette[i * 3 + 0] = ctblStream->readByte();
- palette[i * 3 + 1] = ctblStream->readByte();
- palette[i * 3 + 2] = ctblStream->readByte();
- ctblStream->readByte();
- }
-
- delete ctblStream;
-
- _vm->_system->getPaletteManager()->setPalette(palette, 0, colorCount);
- delete[] palette;
- } else {
- GraphicsManager::setPalette(id);
- }
-}
-
-#ifdef ENABLE_CSTIME
-
-CSTimeGraphics::CSTimeGraphics(MohawkEngine_CSTime *vm) : GraphicsManager(), _vm(vm) {
- _bmpDecoder = new MohawkBitmap();
-
- initGraphics(640, 480, true);
-}
-
-CSTimeGraphics::~CSTimeGraphics() {
- delete _bmpDecoder;
-}
-
-void CSTimeGraphics::drawRect(Common::Rect rect, byte color) {
- rect.clip(Common::Rect(640, 480));
-
- // Useful with debugging. Shows where hotspots are on the screen and whether or not they're active.
- if (!rect.isValidRect() || rect.width() == 0 || rect.height() == 0)
- return;
-
- Graphics::Surface *screen = _vm->_system->lockScreen();
-
- screen->frameRect(rect, color);
-
- _vm->_system->unlockScreen();
-}
-
-MohawkSurface *CSTimeGraphics::decodeImage(uint16 id) {
- return _bmpDecoder->decodeImage(_vm->getResource(ID_TBMP, id));
-}
-
-Common::Array<MohawkSurface *> CSTimeGraphics::decodeImages(uint16 id) {
- return _bmpDecoder->decodeImages(_vm->getResource(ID_TBMH, id));
-}
-
-#endif
-
} // End of namespace Mohawk
diff --git a/engines/mohawk/graphics.h b/engines/mohawk/graphics.h
index 463608a2aa..51d25db5d9 100644
--- a/engines/mohawk/graphics.h
+++ b/engines/mohawk/graphics.h
@@ -25,12 +25,11 @@
#include "mohawk/bitmap.h"
-#include "common/file.h"
#include "common/hashmap.h"
-#include "graphics/pict.h"
+#include "common/rect.h"
namespace Graphics {
-class JPEG;
+struct Surface;
}
namespace Mohawk {
@@ -99,200 +98,10 @@ protected:
private:
// An image cache that stores images until clearCache() is called
- Common::HashMap<uint16, MohawkSurface*> _cache;
- Common::HashMap<uint16, Common::Array<MohawkSurface*> > _subImageCache;
+ Common::HashMap<uint16, MohawkSurface *> _cache;
+ Common::HashMap<uint16, Common::Array<MohawkSurface *> > _subImageCache;
};
-#ifdef ENABLE_MYST
-
-class MystBitmap;
-class MohawkEngine_Myst;
-
-enum RectState {
- kRectEnabled,
- kRectDisabled,
- kRectUnreachable
-};
-
-class MystGraphics : public GraphicsManager {
-public:
- MystGraphics(MohawkEngine_Myst*);
- ~MystGraphics();
-
- void loadExternalPictureFile(uint16 stack);
- void copyImageSectionToScreen(uint16 image, Common::Rect src, Common::Rect dest);
- void copyImageSectionToBackBuffer(uint16 image, Common::Rect src, Common::Rect dest);
- void copyImageToScreen(uint16 image, Common::Rect dest);
- void copyImageToBackBuffer(uint16 image, Common::Rect dest);
- void copyBackBufferToScreen(Common::Rect r);
- void runTransition(uint16 type, Common::Rect rect, uint16 steps, uint16 delay);
- void drawRect(Common::Rect rect, RectState state);
- void drawLine(const Common::Point &p1, const Common::Point &p2, uint32 color);
- void enableDrawingTimeSimulation(bool enable);
- void fadeToBlack();
- void fadeFromBlack();
-
-protected:
- MohawkSurface *decodeImage(uint16 id);
- MohawkEngine *getVM() { return (MohawkEngine *)_vm; }
- void simulatePreviousDrawDelay(const Common::Rect &dest);
- void copyBackBufferToScreenWithSaturation(int16 saturation);
-
-private:
- MohawkEngine_Myst *_vm;
- MystBitmap *_bmpDecoder;
- Graphics::PictDecoder *_pictDecoder;
- Graphics::JPEG *_jpegDecoder;
-
- struct PictureFile {
- uint32 pictureCount;
- struct PictureEntry {
- uint32 offset;
- uint32 size;
- uint16 id;
- uint16 type;
- uint16 width;
- uint16 height;
- } *entries;
-
- Common::File picFile;
- } _pictureFile;
-
- Graphics::Surface *_backBuffer;
- Graphics::PixelFormat _pixelFormat;
- Common::Rect _viewport;
-
- int _enableDrawingTimeSimulation;
- uint32 _nextAllowedDrawTime;
- static const uint _constantDrawDelay = 10; // ms
- static const uint _proportionalDrawDelay = 500; // pixels per ms
-};
-
-#endif // ENABLE_MYST
-
-#ifdef ENABLE_RIVEN
-
-class MohawkEngine_Riven;
-
-class RivenGraphics : public GraphicsManager {
-public:
- RivenGraphics(MohawkEngine_Riven *vm);
- ~RivenGraphics();
-
- void copyImageToScreen(uint16, uint32, uint32, uint32, uint32);
- void updateScreen(Common::Rect updateRect = Common::Rect(0, 0, 608, 392));
- bool _updatesEnabled;
- Common::Array<uint16> _activatedPLSTs;
- void drawPLST(uint16 x);
- void drawRect(Common::Rect rect, bool active);
- void drawImageRect(uint16 id, Common::Rect srcRect, Common::Rect dstRect);
- void drawExtrasImage(uint16 id, Common::Rect dstRect);
-
- // Water Effect
- void scheduleWaterEffect(uint16);
- void clearWaterEffects();
- bool runScheduledWaterEffects();
-
- // Transitions
- void scheduleTransition(uint16 id, Common::Rect rect = Common::Rect(0, 0, 608, 392));
- void runScheduledTransition();
- void fadeToBlack();
- void setTransitionSpeed(uint32 speed) { _transitionSpeed = speed; }
-
- // Inventory
- void showInventory();
- void hideInventory();
-
- // Credits
- void beginCredits();
- void updateCredits();
- uint getCurCreditsImage() { return _creditsImage; }
-
-protected:
- MohawkSurface *decodeImage(uint16 id);
- MohawkEngine *getVM() { return (MohawkEngine *)_vm; }
-
-private:
- MohawkEngine_Riven *_vm;
- MohawkBitmap *_bitmapDecoder;
-
- // Water Effects
- struct SFXERecord {
- // Record values
- uint16 frameCount;
- Common::Rect rect;
- uint16 speed;
- Common::Array<Common::SeekableReadStream*> frameScripts;
-
- // Cur frame
- uint16 curFrame;
- uint32 lastFrameTime;
- };
- Common::Array<SFXERecord> _waterEffects;
-
- // Transitions
- int16 _scheduledTransition;
- Common::Rect _transitionRect;
- uint32 _transitionSpeed;
-
- // Inventory
- void clearInventoryArea();
- void drawInventoryImage(uint16 id, const Common::Rect *rect);
- bool _inventoryDrawn;
-
- // Screen Related
- Graphics::Surface *_mainScreen;
- bool _dirtyScreen;
- Graphics::PixelFormat _pixelFormat;
- void clearMainScreen();
-
- // Credits
- uint _creditsImage, _creditsPos;
-};
-
-#endif // ENABLE_RIVEN
-
-class LBGraphics : public GraphicsManager {
-public:
- LBGraphics(MohawkEngine_LivingBooks *vm, uint16 width, uint16 height);
- ~LBGraphics();
-
- void setPalette(uint16 id);
- void copyOffsetAnimImageToScreen(uint16 image, int left = 0, int top = 0);
- bool imageIsTransparentAt(uint16 image, bool useOffsets, int x, int y);
-
-protected:
- MohawkSurface *decodeImage(uint16 id);
- MohawkEngine *getVM() { return (MohawkEngine *)_vm; }
-
-private:
- MohawkBitmap *_bmpDecoder;
- MohawkEngine_LivingBooks *_vm;
-};
-
-#ifdef ENABLE_CSTIME
-
-class MohawkEngine_CSTime;
-
-class CSTimeGraphics : public GraphicsManager {
-public:
- CSTimeGraphics(MohawkEngine_CSTime *vm);
- ~CSTimeGraphics();
-
- void drawRect(Common::Rect rect, byte color);
-
-protected:
- MohawkSurface *decodeImage(uint16 id);
- Common::Array<MohawkSurface *> decodeImages(uint16 id);
- MohawkEngine *getVM() { return (MohawkEngine *)_vm; }
-
-private:
- MohawkBitmap *_bmpDecoder;
- MohawkEngine_CSTime *_vm;
-};
-
-#endif
-
} // End of namespace Mohawk
#endif
diff --git a/engines/mohawk/installer_archive.cpp b/engines/mohawk/installer_archive.cpp
index 83796158a6..636b7ae476 100644
--- a/engines/mohawk/installer_archive.cpp
+++ b/engines/mohawk/installer_archive.cpp
@@ -107,18 +107,18 @@ void InstallerArchive::close() {
_map.clear();
}
-bool InstallerArchive::hasFile(const Common::String &name) {
+bool InstallerArchive::hasFile(const Common::String &name) const {
return _map.contains(name);
}
-int InstallerArchive::listMembers(Common::ArchiveMemberList &list) {
+int InstallerArchive::listMembers(Common::ArchiveMemberList &list) const {
for (FileMap::const_iterator it = _map.begin(); it != _map.end(); it++)
list.push_back(getMember(it->_key));
return _map.size();
}
-Common::ArchiveMemberPtr InstallerArchive::getMember(const Common::String &name) {
+const Common::ArchiveMemberPtr InstallerArchive::getMember(const Common::String &name) const {
return Common::ArchiveMemberPtr(new Common::GenericArchiveMember(name, this));
}
diff --git a/engines/mohawk/installer_archive.h b/engines/mohawk/installer_archive.h
index 27877d69f9..89d2d85f8d 100644
--- a/engines/mohawk/installer_archive.h
+++ b/engines/mohawk/installer_archive.h
@@ -43,9 +43,9 @@ public:
bool isOpen() const { return _stream != 0; }
// Common::Archive API implementation
- bool hasFile(const Common::String &name);
- int listMembers(Common::ArchiveMemberList &list);
- Common::ArchiveMemberPtr getMember(const Common::String &name);
+ bool hasFile(const Common::String &name) const;
+ int listMembers(Common::ArchiveMemberList &list) const;
+ const Common::ArchiveMemberPtr getMember(const Common::String &name) const;
Common::SeekableReadStream *createReadStreamForMember(const Common::String &name) const;
private:
diff --git a/engines/mohawk/livingbooks.cpp b/engines/mohawk/livingbooks.cpp
index 65073bd970..708478a6d8 100644
--- a/engines/mohawk/livingbooks.cpp
+++ b/engines/mohawk/livingbooks.cpp
@@ -102,6 +102,14 @@ void LBPage::open(Archive *mhk, uint16 baseId) {
for (uint32 i = 0; i < _items.size(); i++)
_items[i]->init();
+
+ for (uint32 i = 0; i < _items.size(); i++)
+ _items[i]->startPhase(kLBPhaseLoad);
+}
+
+void LBPage::addClonedItem(LBItem *item) {
+ _vm->addItem(item);
+ _items.push_back(item);
}
void LBPage::itemDestroyed(LBItem *item) {
@@ -138,8 +146,12 @@ MohawkEngine_LivingBooks::MohawkEngine_LivingBooks(OSystem *syst, const MohawkGa
const Common::FSNode gameDataDir(ConfMan.get("path"));
// Rugrats
- SearchMan.addSubDirectoryMatching(gameDataDir, "program");
- SearchMan.addSubDirectoryMatching(gameDataDir, "Rugrats Adventure Game");
+ const Common::FSNode ProgPath = gameDataDir.getChild("program");
+ if (ProgPath.exists())
+ SearchMan.addDirectory(ProgPath.getPath(), ProgPath, 0, 2);
+ const Common::FSNode RugPath = gameDataDir.getChild("Rugrats Adventure Game");
+ if (RugPath.exists())
+ SearchMan.addDirectory(RugPath.getPath(), RugPath, 0, 2);
// CarmenTQ
const Common::FSNode CTQPath = gameDataDir.getChild("95instal");
if (CTQPath.exists())
@@ -304,8 +316,9 @@ void MohawkEngine_LivingBooks::loadBookInfo(const Common::String &filename) {
const Common::ConfigFile::SectionKeyList globals = _bookInfoFile.getKeys("Globals");
for (Common::ConfigFile::SectionKeyList::const_iterator i = globals.begin(); i != globals.end(); i++) {
Common::String command = Common::String::format("%s = %s", i->key.c_str(), i->value.c_str());
- debug("global: %s", command.c_str());
- // TODO: run command
+ LBCode tempCode(this, 0);
+ uint offset = tempCode.parseCode(command);
+ tempCode.runCode(NULL, offset);
}
}
}
@@ -375,10 +388,13 @@ bool MohawkEngine_LivingBooks::loadPage(LBMode mode, uint page, uint subpage) {
}
// TODO: fading between pages
+#if 0
bool fade = false;
if (leftover.contains("fade")) {
fade = true;
}
+#endif
+
if (leftover.contains("read")) {
_readOnly = true;
}
@@ -436,12 +452,9 @@ bool MohawkEngine_LivingBooks::loadPage(LBMode mode, uint page, uint subpage) {
void MohawkEngine_LivingBooks::updatePage() {
switch (_phase) {
- case 0:
- for (uint32 i = 0; i < _items.size(); i++)
- _items[i]->startPhase(0xFFFE);
-
+ case kLBPhaseInit:
for (uint32 i = 0; i < _items.size(); i++)
- _items[i]->startPhase(0xFFFF);
+ _items[i]->startPhase(kLBPhaseCreate);
for (uint32 i = 0; i < _items.size(); i++)
_items[i]->startPhase(_phase);
@@ -537,7 +550,7 @@ void MohawkEngine_LivingBooks::updatePage() {
_phase++;
break;
- case 1:
+ case kLBPhaseIntro:
for (uint32 i = 0; i < _items.size(); i++)
_items[i]->startPhase(_phase);
@@ -550,7 +563,7 @@ void MohawkEngine_LivingBooks::updatePage() {
_phase++;
break;
- case 2:
+ case kLBPhaseMain:
if (!_introDone)
break;
@@ -593,8 +606,8 @@ void MohawkEngine_LivingBooks::updatePage() {
_items[i]->update();
if (_needsRedraw) {
- for (uint16 i = 0; i < _items.size(); i++)
- _items[i]->draw();
+ for (Common::List<LBItem *>::const_iterator i = _orderedItems.reverse_begin(); i != _orderedItems.end(); --i)
+ (*i)->draw();
_needsRedraw = false;
_needsUpdate = true;
@@ -1854,6 +1867,35 @@ void LBAnimation::seek(uint16 pos) {
}
}
+void LBAnimation::seekToTime(uint32 time) {
+ _lastTime = 0;
+ _currentFrame = 0;
+
+ if (_currentSound != 0xffff) {
+ _vm->_sound->stopSound(_currentSound);
+ _currentSound = 0xffff;
+ }
+
+ for (uint32 i = 0; i < _nodes.size(); i++)
+ _nodes[i]->reset();
+
+ uint32 elapsed = 0;
+ while (elapsed <= time) {
+ bool ranSomething = false;
+ // nodes don't wait while seeking
+ for (uint32 i = 0; i < _nodes.size(); i++)
+ ranSomething |= (_nodes[i]->update(true) != kLBNodeDone);
+
+ elapsed += _tempo;
+ _currentFrame++;
+
+ if (!ranSomething) {
+ _running = false;
+ break;
+ }
+ }
+}
+
void LBAnimation::stop() {
_running = false;
if (_currentSound != 0xffff) {
@@ -1920,7 +1962,10 @@ LBScriptEntry::~LBScriptEntry() {
}
LBItem::LBItem(MohawkEngine_LivingBooks *vm, LBPage *page, Common::Rect rect) : _vm(vm), _page(page), _rect(rect) {
- _phase = 0;
+ if (_vm->getGameType() == GType_LIVINGBOOKSV1 || _vm->getGameType() == GType_LIVINGBOOKSV2)
+ _phase = kLBPhaseInit;
+ else
+ _phase = kLBPhaseLoad;
_loopMode = 0;
_delayMin = 0;
@@ -1931,7 +1976,7 @@ LBItem::LBItem(MohawkEngine_LivingBooks *vm, LBPage *page, Common::Rect rect) :
_controlMode = kLBControlNone;
_soundMode = 0;
- _neverEnabled = true;
+ _loaded = false;
_enabled = false;
_visible = true;
_playing = false;
@@ -2338,6 +2383,22 @@ void LBItem::readData(uint16 type, uint16 size, Common::MemoryReadStreamEndian *
}
break;
+ case kLBSetRolloverData:
+ {
+ assert(size == 2);
+ uint16 flag = stream->readUint16();
+ warning("ignoring kLBSetRolloverData: item %s, flag %d", _desc.c_str(), flag);
+ }
+ break;
+
+ case kLBSetParent:
+ {
+ assert(size == 2);
+ uint16 parent = stream->readUint16();
+ warning("ignoring kLBSetParent: item %s, parent id %d", _desc.c_str(), parent);
+ }
+ break;
+
case kLBUnknown194:
{
assert(size == 4);
@@ -2365,25 +2426,27 @@ void LBItem::destroySelf() {
}
void LBItem::setEnabled(bool enabled) {
- if (enabled && _neverEnabled && !_playing) {
+ if (enabled && !_loaded && !_playing) {
if (_timingMode == kLBAutoUserIdle) {
setNextTime(_periodMin, _periodMax);
debug(2, "Enable time startup");
}
}
- _neverEnabled = false;
_enabled = enabled;
}
void LBItem::setGlobalEnabled(bool enabled) {
- bool wasEnabled = !_neverEnabled && _enabled && _globalEnabled;
+ bool wasEnabled = _loaded && _enabled && _globalEnabled;
_globalEnabled = enabled;
- if (wasEnabled != (!_neverEnabled && _enabled && _globalEnabled))
+ if (wasEnabled != (_loaded && _enabled && _globalEnabled))
setEnabled(enabled);
}
bool LBItem::contains(Common::Point point) {
+ if (!_loaded)
+ return false;
+
if (_playing && _loopMode == 0xFFFF)
stop();
@@ -2394,7 +2457,7 @@ bool LBItem::contains(Common::Point point) {
}
void LBItem::update() {
- if (_phase != 0x7FFF && (_neverEnabled || !_enabled || !_globalEnabled))
+ if (_phase != kLBPhaseNone && (!_loaded || !_enabled || !_globalEnabled))
return;
if (_nextTime == 0 || _nextTime > (uint32)(_vm->_system->getMillis() / 16))
@@ -2409,7 +2472,7 @@ void LBItem::update() {
}
void LBItem::handleMouseDown(Common::Point pos) {
- if (_neverEnabled || !_enabled || !_globalEnabled)
+ if (!_loaded || !_enabled || !_globalEnabled)
return;
_vm->setFocus(this);
@@ -2432,7 +2495,7 @@ bool LBItem::togglePlaying(bool playing, bool restart) {
_vm->queueDelayedEvent(DelayedEvent(this, kLBDelayedEventDone));
return true;
}
- if (((!_neverEnabled && _enabled && _globalEnabled) || _phase == 0x7FFF) && !_playing) {
+ if (((_loaded && _enabled && _globalEnabled) || _phase == kLBPhaseNone) && !_playing) {
_playing = togglePlaying(true, restart);
if (_playing) {
_nextTime = 0;
@@ -2501,6 +2564,10 @@ void LBItem::done(bool onlyNotify) {
notify(0xFFFF, _itemId);
}
+void LBItem::init() {
+ runScript(kLBEventInit);
+}
+
void LBItem::setVisible(bool visible) {
if (visible == _visible)
return;
@@ -2517,38 +2584,40 @@ void LBItem::setGlobalVisible(bool visible) {
}
void LBItem::startPhase(uint phase) {
- if (_phase == phase)
- setEnabled(true);
+ if (_phase == phase) {
+ if (_phase != kLBPhaseNone) {
+ setEnabled(true);
+ }
+
+ load();
+ }
switch (phase) {
- case 0xFFFE:
- if (_timingMode == kLBAutoLoad) {
- debug(2, "Phase load: time startup");
- setNextTime(_periodMin, _periodMax);
- }
+ case kLBPhaseLoad:
+ runScript(kLBEventListLoad);
break;
- case 0xFFFF:
+ case kLBPhaseCreate:
runScript(kLBEventPhaseCreate);
if (_timingMode == kLBAutoCreate) {
debug(2, "Phase create: time startup");
setNextTime(_periodMin, _periodMax);
}
break;
- case 0:
+ case kLBPhaseInit:
runScript(kLBEventPhaseInit);
if (_timingMode == kLBAutoInit) {
debug(2, "Phase init: time startup");
setNextTime(_periodMin, _periodMax);
}
break;
- case 1:
+ case kLBPhaseIntro:
runScript(kLBEventPhaseIntro);
if (_timingMode == kLBAutoIntro || _timingMode == kLBAutoUserIdle) {
debug(2, "Phase intro: time startup");
setNextTime(_periodMin, _periodMax);
}
break;
- case 2:
+ case kLBPhaseMain:
runScript(kLBEventPhaseMain);
if (_timingMode == kLBAutoUserIdle || _timingMode == kLBAutoMain) {
debug(2, "Phase main: time startup");
@@ -2579,6 +2648,54 @@ void LBItem::notify(uint16 data, uint16 from) {
runScript(kLBEventNotified, data, from);
}
+void LBItem::load() {
+ if (_loaded)
+ return;
+
+ _loaded = true;
+
+ // FIXME: events etc
+ if (_timingMode == kLBAutoLoad) {
+ debug(2, "Load: time startup");
+ setNextTime(_periodMin, _periodMax);
+ }
+}
+
+void LBItem::unload() {
+ if (!_loaded)
+ return;
+
+ _loaded = false;
+
+ // FIXME: stuff
+}
+
+void LBItem::moveBy(const Common::Point &pos) {
+ _rect.translate(pos.x, pos.y);
+}
+
+void LBItem::moveTo(const Common::Point &pos) {
+ _rect.moveTo(pos);
+}
+
+LBItem *LBItem::clone(uint16 newId, const Common::String &newName) {
+ LBItem *item = createClone();
+
+ item->_itemId = newId;
+ item->_desc = newName;
+
+ item->_resourceId = _resourceId;
+ // FIXME: the rest
+
+ _page->addClonedItem(item);
+ // FIXME: zorder?
+ return item;
+}
+
+LBItem *LBItem::createClone() {
+ return new LBItem(_vm, _page, _rect);
+}
+
void LBItem::runScript(uint event, uint16 data, uint16 from) {
for (uint i = 0; i < _scriptEntries.size(); i++) {
LBScriptEntry *entry = _scriptEntries[i];
@@ -2819,9 +2936,7 @@ int LBItem::runScriptEntry(LBScriptEntry *entry) {
break;
case kLBOpLoad:
- // FIXME
- warning("ignoring kLBOpLoad (event 0x%04x, param 0x%04x, target '%s')",
- entry->event, entry->param, target->_desc.c_str());
+ target->load();
break;
case kLBOpPreload:
@@ -2831,9 +2946,7 @@ int LBItem::runScriptEntry(LBScriptEntry *entry) {
break;
case kLBOpUnload:
- // FIXME
- warning("ignoring kLBOpUnload (event 0x%04x, param 0x%04x, target '%s')",
- entry->event, entry->param, target->_desc.c_str());
+ target->unload();
break;
case kLBOpSeekToPrev:
@@ -2882,6 +2995,7 @@ int LBItem::runScriptEntry(LBScriptEntry *entry) {
case kLBOpBreakExpression:
debug(2, "BreakExpression");
i = entry->subentries.size();
+ break;
case kLBOpJumpToExpression:
debug(2, "JumpToExpression got %d (on %d, of %d)", e, i, entry->subentries.size());
i = e - 1;
@@ -2969,7 +3083,7 @@ bool LBSoundItem::togglePlaying(bool playing, bool restart) {
_vm->_sound->stopSound(_resourceId);
}
- if (_neverEnabled || !_enabled || !_globalEnabled)
+ if (!_loaded || !_enabled || !_globalEnabled)
return false;
_running = true;
@@ -2987,6 +3101,10 @@ void LBSoundItem::stop() {
LBItem::stop();
}
+LBItem *LBSoundItem::createClone() {
+ return new LBSoundItem(_vm, _page, _rect);
+}
+
LBGroupItem::LBGroupItem(MohawkEngine_LivingBooks *vm, LBPage *page, Common::Rect rect) : LBItem(vm, page, rect) {
debug(3, "new LBGroupItem");
_starting = false;
@@ -3102,6 +3220,44 @@ void LBGroupItem::stop() {
}
}
+void LBGroupItem::load() {
+ for (uint i = 0; i < _groupEntries.size(); i++) {
+ LBItem *item = _vm->getItemById(_groupEntries[i].entryId);
+ if (item)
+ item->load();
+ }
+}
+
+void LBGroupItem::unload() {
+ for (uint i = 0; i < _groupEntries.size(); i++) {
+ LBItem *item = _vm->getItemById(_groupEntries[i].entryId);
+ if (item)
+ item->unload();
+ }
+}
+
+void LBGroupItem::moveBy(const Common::Point &pos) {
+ for (uint i = 0; i < _groupEntries.size(); i++) {
+ LBItem *item = _vm->getItemById(_groupEntries[i].entryId);
+ if (item)
+ item->moveBy(pos);
+ }
+}
+
+void LBGroupItem::moveTo(const Common::Point &pos) {
+ for (uint i = 0; i < _groupEntries.size(); i++) {
+ LBItem *item = _vm->getItemById(_groupEntries[i].entryId);
+ if (item)
+ item->moveTo(pos);
+ }
+}
+
+LBItem *LBGroupItem::createClone() {
+ // TODO: needed?
+ error("LBGroupItem::createClone unimplemented");
+ return new LBGroupItem(_vm, _page, _rect);
+}
+
LBPaletteItem::LBPaletteItem(MohawkEngine_LivingBooks *vm, LBPage *page, Common::Rect rect) : LBItem(vm, page, rect) {
debug(3, "new LBPaletteItem");
@@ -3187,6 +3343,10 @@ void LBPaletteItem::update() {
LBItem::update();
}
+LBItem *LBPaletteItem::createClone() {
+ error("can't clone LBPaletteItem");
+}
+
LBLiveTextItem::LBLiveTextItem(MohawkEngine_LivingBooks *vm, LBPage *page, Common::Rect rect) : LBItem(vm, page, rect) {
_currentPhrase = 0xFFFF;
_currentWord = 0xFFFF;
@@ -3350,7 +3510,7 @@ void LBLiveTextItem::drawWord(uint word, uint yPos) {
}
void LBLiveTextItem::handleMouseDown(Common::Point pos) {
- if (_neverEnabled || !_enabled || !_globalEnabled || _playing)
+ if (!_loaded || !_enabled || !_globalEnabled || _playing)
return LBItem::handleMouseDown(pos);
pos.x -= _rect.left;
@@ -3381,7 +3541,7 @@ void LBLiveTextItem::handleMouseDown(Common::Point pos) {
bool LBLiveTextItem::togglePlaying(bool playing, bool restart) {
if (!playing)
return LBItem::togglePlaying(playing, restart);
- if (_neverEnabled || !_enabled || !_globalEnabled)
+ if (!_loaded || !_enabled || !_globalEnabled)
return _playing;
// TODO: handle this properly
@@ -3400,7 +3560,7 @@ void LBLiveTextItem::stop() {
}
void LBLiveTextItem::notify(uint16 data, uint16 from) {
- if (_neverEnabled || !_enabled || !_globalEnabled || !_playing)
+ if (!_loaded || !_enabled || !_globalEnabled || !_playing)
return LBItem::notify(data, from);
if (_currentWord != 0xFFFF) {
@@ -3434,6 +3594,10 @@ void LBLiveTextItem::notify(uint16 data, uint16 from) {
LBItem::notify(data, from);
}
+LBItem *LBLiveTextItem::createClone() {
+ error("can't clone LBLiveTextItem");
+}
+
LBPictureItem::LBPictureItem(MohawkEngine_LivingBooks *vm, LBPage *page, Common::Rect rect) : LBItem(vm, page, rect) {
debug(3, "new LBPictureItem");
}
@@ -3468,15 +3632,21 @@ bool LBPictureItem::contains(Common::Point point) {
void LBPictureItem::init() {
_vm->_gfx->preloadImage(_resourceId);
+
+ LBItem::init();
}
void LBPictureItem::draw() {
- if (!_visible || !_globalVisible)
+ if (!_loaded || !_visible || !_globalVisible)
return;
_vm->_gfx->copyAnimImageToScreen(_resourceId, _rect.left, _rect.top);
}
+LBItem *LBPictureItem::createClone() {
+ return new LBPictureItem(_vm, _page, _rect);
+}
+
LBAnimationItem::LBAnimationItem(MohawkEngine_LivingBooks *vm, LBPage *page, Common::Rect rect) : LBItem(vm, page, rect) {
_anim = NULL;
_running = false;
@@ -3489,9 +3659,9 @@ LBAnimationItem::~LBAnimationItem() {
void LBAnimationItem::setEnabled(bool enabled) {
if (_running) {
- if (enabled && _globalEnabled && _neverEnabled)
+ if (enabled && _globalEnabled && !_loaded)
_anim->start();
- else if (!_neverEnabled && !enabled && _enabled && _globalEnabled)
+ else if (_loaded && !enabled && _enabled && _globalEnabled)
_anim->stop();
}
@@ -3509,7 +3679,7 @@ bool LBAnimationItem::contains(Common::Point point) {
}
void LBAnimationItem::update() {
- if (!_neverEnabled && _enabled && _globalEnabled && _running) {
+ if (_loaded && _enabled && _globalEnabled && _running) {
bool wasDone = _anim->update();
if (wasDone) {
_running = false;
@@ -3522,7 +3692,7 @@ void LBAnimationItem::update() {
bool LBAnimationItem::togglePlaying(bool playing, bool restart) {
if (playing) {
- if (!_neverEnabled && _enabled && _globalEnabled) {
+ if (_loaded && _enabled && _globalEnabled) {
if (restart)
seek(1);
_running = true;
@@ -3545,6 +3715,8 @@ void LBAnimationItem::done(bool onlyNotify) {
void LBAnimationItem::init() {
_anim = new LBAnimation(_vm, this, _resourceId);
+
+ LBItem::init();
}
void LBAnimationItem::stop() {
@@ -3562,6 +3734,10 @@ void LBAnimationItem::seek(uint16 pos) {
_anim->seek(pos);
}
+void LBAnimationItem::seekToTime(uint32 time) {
+ _anim->seekToTime(time);
+}
+
void LBAnimationItem::startPhase(uint phase) {
if (phase == _phase)
seek(1);
@@ -3576,6 +3752,12 @@ void LBAnimationItem::draw() {
_anim->draw();
}
+LBItem *LBAnimationItem::createClone() {
+ LBAnimationItem *item = new LBAnimationItem(_vm, _page, _rect);
+ item->_anim = new LBAnimation(_vm, item, _resourceId);
+ return item;
+}
+
LBMovieItem::LBMovieItem(MohawkEngine_LivingBooks *vm, LBPage *page, Common::Rect rect) : LBItem(vm, page, rect) {
debug(3, "new LBMovieItem");
}
@@ -3595,7 +3777,7 @@ void LBMovieItem::update() {
bool LBMovieItem::togglePlaying(bool playing, bool restart) {
if (playing) {
- if ((!_neverEnabled && _enabled && _globalEnabled) || _phase == 0x7FFF) {
+ if ((_loaded && _enabled && _globalEnabled) || _phase == kLBPhaseNone) {
_vm->_video->playMovie(_resourceId, _rect.left, _rect.top);
return true;
@@ -3605,6 +3787,10 @@ bool LBMovieItem::togglePlaying(bool playing, bool restart) {
return LBItem::togglePlaying(playing, restart);
}
+LBItem *LBMovieItem::createClone() {
+ return new LBMovieItem(_vm, _page, _rect);
+}
+
LBMiniGameItem::LBMiniGameItem(MohawkEngine_LivingBooks *vm, LBPage *page, Common::Rect rect) : LBItem(vm, page, rect) {
debug(3, "new LBMiniGameItem");
}
@@ -3640,6 +3826,10 @@ bool LBMiniGameItem::togglePlaying(bool playing, bool restart) {
return false;
}
+LBItem *LBMiniGameItem::createClone() {
+ error("can't clone LBMiniGameItem");
+}
+
LBProxyItem::LBProxyItem(MohawkEngine_LivingBooks *vm, LBPage *page, Common::Rect rect) : LBItem(vm, page, rect) {
debug(3, "new LBProxyItem");
@@ -3650,7 +3840,10 @@ LBProxyItem::~LBProxyItem() {
delete _page;
}
-void LBProxyItem::init() {
+void LBProxyItem::load() {
+ if (_loaded)
+ return;
+
Common::String leftover;
Common::String filename = _vm->getFileNameFromConfig("Proxies", _desc.c_str(), leftover);
if (!leftover.empty())
@@ -3669,6 +3862,19 @@ void LBProxyItem::init() {
error("failed to open archive '%s' (for proxy '%s')", filename.c_str(), _desc.c_str());
_page = new LBPage(_vm);
_page->open(pageArchive, baseId);
+
+ LBItem::load();
+}
+
+void LBProxyItem::unload() {
+ delete _page;
+ _page = NULL;
+
+ LBItem::unload();
+}
+
+LBItem *LBProxyItem::createClone() {
+ return new LBProxyItem(_vm, _page, _rect);
}
} // End of namespace Mohawk
diff --git a/engines/mohawk/livingbooks.h b/engines/mohawk/livingbooks.h
index 008a7dbf23..91d6a8cd30 100644
--- a/engines/mohawk/livingbooks.h
+++ b/engines/mohawk/livingbooks.h
@@ -25,7 +25,7 @@
#include "mohawk/mohawk.h"
#include "mohawk/console.h"
-#include "mohawk/graphics.h"
+#include "mohawk/livingbooks_graphics.h"
#include "mohawk/sound.h"
#include "common/config-file.h"
@@ -68,6 +68,15 @@ enum LBMode {
kLBPlayMode = 6
};
+enum {
+ kLBPhaseInit = 0x0,
+ kLBPhaseIntro = 0x1,
+ kLBPhaseMain = 0x2,
+ kLBPhaseNone = 0x7fff,
+ kLBPhaseLoad = 0xfffe,
+ kLBPhaseCreate = 0xffff
+};
+
// automatic modes used in _timingMode
enum {
kLBAutoNone = 0,
@@ -178,10 +187,10 @@ enum {
kLBGlobalSetNotVisible = 0x79,
kLBGlobalSetVisible = 0x7a, // unused?
kLBSetAmbient = 0x7b,
- kLBUnknown7C = 0x7c, // unused?
+ kLBSetDragParams = 0x7c,
kLBSetKeyEvent = 0x7d,
- kLBUnknown7E = 0x7e, // unused? (rect flag)
- kLBSetParent = 0x7f, // unused?
+ kLBSetRolloverData = 0x7e,
+ kLBSetParent = 0x7f,
kLBSetHitTest = 0x80,
// from here, rugrats
kLBUnknown194 = 0x194
@@ -331,6 +340,7 @@ public:
void start();
void seek(uint16 pos);
+ void seekToTime(uint32 time);
void stop();
void playSound(uint16 resourceId);
@@ -391,23 +401,34 @@ public:
virtual void handleMouseUp(Common::Point pos); // 0xD
virtual bool togglePlaying(bool playing, bool restart = false); // 0xF
virtual void done(bool onlyNotify); // 0x10
- virtual void init() { } // 0x11
+ virtual void init(); // 0x11
virtual void seek(uint16 pos) { } // 0x13
+ virtual void seekToTime(uint32 time) { }
virtual void setFocused(bool focused) { } // 0x14
virtual void setVisible(bool visible); // 0x17
virtual void setGlobalVisible(bool enabled);
virtual void startPhase(uint phase); // 0x18
virtual void stop(); // 0x19
virtual void notify(uint16 data, uint16 from); // 0x1A
+ virtual void load();
+ virtual void unload();
+ virtual void moveBy(const Common::Point &pos);
+ virtual void moveTo(const Common::Point &pos);
+
+ LBItem *clone(uint16 newId, const Common::String &newName);
uint16 getId() { return _itemId; }
const Common::String &getName() { return _desc; }
const Common::Rect &getRect() { return _rect; }
uint16 getSoundPriority() { return _soundMode; }
+ bool isLoaded() { return _loaded; }
bool isAmbient() { return _isAmbient; }
Common::List<LBItem *>::iterator _iterator;
+ // TODO: make private
+ Common::HashMap<Common::String, LBValue, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> _variables;
+
protected:
MohawkEngine_LivingBooks *_vm;
LBPage *_page;
@@ -420,7 +441,7 @@ protected:
uint16 _resourceId;
uint16 _itemId;
- bool _visible, _globalVisible, _playing, _enabled, _neverEnabled, _globalEnabled;
+ bool _loaded, _visible, _globalVisible, _playing, _enabled, _globalEnabled;
uint32 _nextTime, _startTime;
uint16 _loops;
@@ -433,6 +454,8 @@ protected:
bool _isAmbient;
bool _doHitTest;
+ virtual LBItem *createClone();
+
Common::Array<LBScriptEntry *> _scriptEntries;
void runScript(uint event, uint16 data = 0, uint16 from = 0);
int runScriptEntry(LBScriptEntry *entry);
@@ -453,6 +476,8 @@ public:
void stop();
protected:
+ LBItem *createClone();
+
bool _running;
};
@@ -478,8 +503,14 @@ public:
void setGlobalVisible(bool visible);
void startPhase(uint phase);
void stop();
+ void load();
+ void unload();
+ void moveBy(const Common::Point &pos);
+ void moveTo(const Common::Point &pos);
protected:
+ LBItem *createClone();
+
bool _starting;
Common::Array<GroupEntry> _groupEntries;
@@ -496,6 +527,8 @@ public:
void update();
protected:
+ LBItem *createClone();
+
uint16 _fadeInPeriod, _fadeInStep, _drawStart, _drawCount;
uint32 _fadeInStart, _fadeInCurrent;
byte *_palette;
@@ -527,6 +560,8 @@ public:
void notify(uint16 data, uint16 from);
protected:
+ LBItem *createClone();
+
void paletteUpdate(uint16 word, bool on);
void drawWord(uint word, uint yPos);
@@ -550,6 +585,9 @@ public:
bool contains(Common::Point point);
void draw();
void init();
+
+protected:
+ LBItem *createClone();
};
class LBAnimationItem : public LBItem {
@@ -565,10 +603,13 @@ public:
void done(bool onlyNotify);
void init();
void seek(uint16 pos);
+ void seekToTime(uint32 time);
void startPhase(uint phase);
void stop();
protected:
+ LBItem *createClone();
+
LBAnimation *_anim;
bool _running;
};
@@ -580,6 +621,9 @@ public:
void update();
bool togglePlaying(bool playing, bool restart);
+
+protected:
+ LBItem *createClone();
};
class LBMiniGameItem : public LBItem {
@@ -588,6 +632,9 @@ public:
~LBMiniGameItem();
bool togglePlaying(bool playing, bool restart);
+
+protected:
+ LBItem *createClone();
};
class LBProxyItem : public LBItem {
@@ -595,9 +642,12 @@ public:
LBProxyItem(MohawkEngine_LivingBooks *_vm, LBPage *page, Common::Rect rect);
~LBProxyItem();
- void init();
+ void load();
+ void unload();
protected:
+ LBItem *createClone();
+
class LBPage *_page;
};
@@ -634,6 +684,7 @@ public:
void open(Archive *mhk, uint16 baseId);
uint16 getResourceVersion();
+ void addClonedItem(LBItem *item);
void itemDestroyed(LBItem *item);
LBCode *_code;
@@ -697,7 +748,7 @@ public:
void nextPage();
// TODO: make private
- Common::HashMap<Common::String, LBValue> _variables;
+ Common::HashMap<Common::String, LBValue, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> _variables;
// helper functions, also used by LBProxyItem
Common::String getFileNameFromConfig(const Common::String &section, const Common::String &key, Common::String &leftover);
diff --git a/engines/mohawk/livingbooks_code.cpp b/engines/mohawk/livingbooks_code.cpp
index 80b5fe9660..bb8f7a0d05 100644
--- a/engines/mohawk/livingbooks_code.cpp
+++ b/engines/mohawk/livingbooks_code.cpp
@@ -21,8 +21,10 @@
*/
#include "mohawk/livingbooks.h"
+#include "mohawk/livingbooks_lbx.h"
#include "mohawk/resource.h"
+#include "common/events.h"
#include "common/system.h"
#include "common/textconsole.h"
@@ -99,12 +101,17 @@ double LBValue::toDouble() const {
Common::Point LBValue::toPoint() const {
switch (type) {
case kLBValueString:
- // FIXME
- return Common::Point();
+ {
+ Common::Point ret;
+ sscanf(string.c_str(), "%hd , %hd", &ret.x, &ret.y);
+ return ret;
+ }
case kLBValueInteger:
return Common::Point(integer, integer);
case kLBValuePoint:
return point;
+ case kLBValueRect:
+ return Common::Point(rect.left, rect.top);
default:
error("failed to convert to point");
}
@@ -113,10 +120,15 @@ Common::Point LBValue::toPoint() const {
Common::Rect LBValue::toRect() const {
switch (type) {
case kLBValueString:
- // FIXME
- return Common::Rect();
+ {
+ Common::Rect ret;
+ sscanf(string.c_str(), "%hd , %hd , %hd , %hd", &ret.left, &ret.top, &ret.right, &ret.bottom);
+ return ret;
+ }
case kLBValueInteger:
return Common::Rect(integer, integer, integer, integer);
+ case kLBValuePoint:
+ return Common::Rect(point.x, point.y, point.x, point.y);
case kLBValueRect:
return rect;
case kLBValueItemPtr:
@@ -476,26 +488,84 @@ void LBCode::parseMain() {
if (_currToken == kTokenAssign)
error("attempted assignment to self");
break;
- } else if (_currToken == kTokenAssign) {
+ }
+ bool indexing = false;
+ Common::Array<LBValue> index;
+ while (_currToken == kTokenListStart) {
+ debugN("[");
+ nextToken();
+ parseStatement();
+ if (_currToken != kTokenListEnd)
+ error("expected list end");
+ debugN("]");
+ nextToken();
+ if (!_stack.size())
+ error("index failed");
+ indexing = true;
+ index.push_back(_stack.pop());
+ }
+ if (_currToken == kTokenAssign) {
debugN(" = ");
nextToken();
parseStatement();
if (!_stack.size())
error("assignment failed");
- LBValue *val = &_vm->_variables[varname];
- *val = _stack.pop();
- _stack.push(*val);
+ LBValue *val;
+ if (indexing)
+ val = getIndexedVar(varname, index);
+ else
+ val = &_vm->_variables[varname];
+ if (val) {
+ *val = _stack.pop();
+ _stack.push(*val);
+ } else
+ _stack.push(LBValue());
+ } else if (_currToken == kTokenAndEquals) {
+ debugN(" &= ");
+ nextToken();
+ parseStatement();
+ if (!_stack.size())
+ error("assignment failed");
+ LBValue *val;
+ if (indexing)
+ val = getIndexedVar(varname, index);
+ else
+ val = &_vm->_variables[varname];
+ if (val) {
+ if (val->type != kLBValueString)
+ error("operator &= used on non-string");
+ val->string = val->string + _stack.pop().toString();
+ _stack.push(*val);
+ } else
+ _stack.push(LBValue());
} else {
- _stack.push(_vm->_variables[varname]);
+ if (indexing) {
+ LBValue *val = getIndexedVar(varname, index);
+ if (val)
+ _stack.push(*val);
+ else
+ _stack.push(LBValue());
+ } else
+ _stack.push(_vm->_variables[varname]);
}
// FIXME: pre/postincrement for non-integers
if (_currToken == kTokenPlusPlus) {
debugN("++");
- _vm->_variables[varname].integer++;
+ if (indexing) {
+ LBValue *val = getIndexedVar(varname, index);
+ if (val)
+ val->integer++;
+ } else
+ _vm->_variables[varname].integer++;
nextToken();
} else if (_currToken == kTokenMinusMinus) {
debugN("--");
- _vm->_variables[varname].integer--;
+ if (indexing) {
+ LBValue *val = getIndexedVar(varname, index);
+ if (val)
+ val->integer--;
+ } else
+ _vm->_variables[varname].integer--;
nextToken();
}
}
@@ -567,6 +637,28 @@ void LBCode::parseMain() {
nextToken();
break;
+ case kTokenListStart:
+ debugN("[");
+ nextToken();
+ {
+ Common::SharedPtr<LBList> list = Common::SharedPtr<LBList>(new LBList);
+ while (_currToken != kTokenListEnd) {
+ parseStatement();
+ if (!_stack.size())
+ error("unexpected empty stack during literal list evaluation");
+ list->array.push_back(_stack.pop());
+ if (_currToken == kTokenComma) {
+ debugN(", ");
+ nextToken();
+ } else if (_currToken != kTokenListEnd)
+ error("encountered unexpected token %02x during literal list", _currToken);
+ }
+ debugN("]");
+ nextToken();
+ _stack.push(list);
+ }
+ break;
+
case kTokenNot:
debugN("!");
nextToken();
@@ -607,6 +699,20 @@ void LBCode::parseMain() {
}
}
+LBValue *LBCode::getIndexedVar(Common::String varname, const Common::Array<LBValue> &index) {
+ LBValue *var = &_vm->_variables[varname];
+ for (uint i = 0; i < index.size(); i++) {
+ if (var->type != kLBValueList)
+ error("variable '%s' was indexed, but isn't a list after %d indexes", varname.c_str(), i);
+ if (index[i].type != kLBValueInteger)
+ error("index %d wasn't an integer", i);
+ if (index[i].integer < 1 || index[i].integer > (int)var->list->array.size())
+ return NULL;
+ var = &var->list->array[index[i].integer - 1];
+ }
+ return var;
+}
+
LBItem *LBCode::resolveItem(const LBValue &value) {
if (value.type == kLBValueItemPtr)
return value.item;
@@ -626,7 +732,7 @@ Common::Array<LBValue> LBCode::readParams() {
byte numParams = _data[_currOffset++];
if (!numParams) {
- debugN("()\n");
+ debugN("()");
nextToken();
return params;
}
@@ -688,14 +794,14 @@ CodeCommandInfo generalCommandInfo[NUM_GENERAL_COMMANDS] = {
{ "random", &LBCode::cmdRandom },
{ "stringLen", &LBCode::cmdStringLen },
{ "substring", &LBCode::cmdSubstring },
- { "max", 0 },
- { "min", 0 },
- { "abs", 0 },
+ { "max", &LBCode::cmdMax },
+ { "min", &LBCode::cmdMin },
+ { "abs", &LBCode::cmdAbs },
{ "getRect", &LBCode::cmdGetRect }, // also "makeRect"
- { "makePt", 0 }, // also "makePair"
+ { "makePt", &LBCode::cmdMakePoint }, // also "makePair"
{ "topLeft", &LBCode::cmdTopLeft },
{ "bottomRight", &LBCode::cmdBottomRight },
- { "mousePos", 0 },
+ { "mousePos", &LBCode::cmdMousePos },
{ "top", &LBCode::cmdTop },
{ "left", &LBCode::cmdLeft },
{ "bottom", &LBCode::cmdBottom },
@@ -704,7 +810,7 @@ CodeCommandInfo generalCommandInfo[NUM_GENERAL_COMMANDS] = {
{ "xpos", 0 },
{ "ypos", 0 },
{ "playFrom", 0 },
- { "move", 0 },
+ { "move", &LBCode::cmdMove },
{ 0, 0 },
{ 0, 0 },
{ "setDragParams", &LBCode::cmdSetDragParams },
@@ -727,26 +833,26 @@ CodeCommandInfo generalCommandInfo[NUM_GENERAL_COMMANDS] = {
{ "getPage", 0 },
{ "getWorldRect", 0 },
{ "isWorldWrap", 0 },
- { "newList", 0 },
+ { "newList", &LBCode::cmdNewList },
{ "deleteList", 0 },
- { "add", 0 },
+ { "add", &LBCode::cmdAdd },
{ 0, 0 },
- { "addAt", 0 },
+ { "addAt", &LBCode::cmdAddAt },
{ "getAt", 0 },
// 0x30
{ 0, 0 },
{ "getIndex", 0 },
- { "setAt", 0 },
- { "listLen", 0 },
- { "deleteAt", 0 },
- { "clearList", 0 },
+ { "setAt", &LBCode::cmdSetAt },
+ { "listLen", &LBCode::cmdListLen },
+ { "deleteAt", &LBCode::cmdDeleteAt },
+ { "clearList", &LBCode::cmdUnimplemented },
{ "setWorld", 0 },
- { "setProperty", 0 },
- { "getProperty", 0 },
+ { "setProperty", &LBCode::cmdSetProperty },
+ { "getProperty", &LBCode::cmdGetProperty },
{ "copyList", 0 },
{ "invoke", 0 },
- { "exec", 0 },
- { "return", 0 },
+ { "exec", &LBCode::cmdExec },
+ { "return", &LBCode::cmdReturn },
{ "sendSync", 0 },
{ "moveViewOrigin", 0 },
{ "addToGroup", 0 },
@@ -775,8 +881,8 @@ CodeCommandInfo generalCommandInfo[NUM_GENERAL_COMMANDS] = {
{ "setDisplay", &LBCode::cmdUnimplemented },
{ "getDisplay", 0 },
{ 0, 0 },
- { "lbxCreate", 0 },
- { "lbxFunc", 0 },
+ { "lbxCreate", &LBCode::cmdLBXCreate },
+ { "lbxFunc", &LBCode::cmdLBXFunc },
{ "waitCursor", 0 },
{ "debugBreak", 0 },
{ "menuItemEnable", 0 },
@@ -886,6 +992,35 @@ void LBCode::cmdSubstring(const Common::Array<LBValue> &params) {
_stack.push(substring);
}
+void LBCode::cmdMax(const Common::Array<LBValue> &params) {
+ if (params.size() != 2)
+ error("incorrect number of parameters (%d) to max", params.size());
+
+ // FIXME: fp
+ int a = params[0].toInt();
+ int b = params[1].toInt();
+ _stack.push(MAX(a, b));
+}
+
+void LBCode::cmdMin(const Common::Array<LBValue> &params) {
+ if (params.size() != 2)
+ error("incorrect number of parameters (%d) to min", params.size());
+
+ // FIXME: fp
+ int a = params[0].toInt();
+ int b = params[1].toInt();
+ _stack.push(MIN(a, b));
+}
+
+void LBCode::cmdAbs(const Common::Array<LBValue> &params) {
+ if (params.size() != 1)
+ error("incorrect number of parameters (%d) to abs", params.size());
+
+ // FIXME: fp
+ int a = params[0].toInt();
+ _stack.push(ABS(a));
+}
+
void LBCode::cmdGetRect(const Common::Array<LBValue> &params) {
if (params.size() < 2) {
_stack.push(getRectFromParams(params));
@@ -899,6 +1034,12 @@ void LBCode::cmdGetRect(const Common::Array<LBValue> &params) {
error("incorrect number of parameters (%d) to getRect", params.size());
}
+void LBCode::cmdMakePoint(const Common::Array<LBValue> &params) {
+ if (params.size() != 2)
+ error("incorrect number of parameters (%d) to makePoint", params.size());
+ _stack.push(Common::Point(params[0].toInt(), params[1].toInt()));
+}
+
void LBCode::cmdTopLeft(const Common::Array<LBValue> &params) {
if (params.size() > 1)
error("too many parameters (%d) to topLeft", params.size());
@@ -915,6 +1056,14 @@ void LBCode::cmdBottomRight(const Common::Array<LBValue> &params) {
_stack.push(Common::Point(rect.bottom, rect.right));
}
+void LBCode::cmdMousePos(const Common::Array<LBValue> &params) {
+ if (params.size() != 0)
+ error("too many parameters (%d) to mousePos", params.size());
+
+ Common::Point pt = _vm->_system->getEventManager()->getMousePos();
+ _stack.push(pt);
+}
+
void LBCode::cmdTop(const Common::Array<LBValue> &params) {
if (params.size() > 1)
error("too many parameters (%d) to top", params.size());
@@ -947,10 +1096,170 @@ void LBCode::cmdRight(const Common::Array<LBValue> &params) {
_stack.push(rect.right);
}
+void LBCode::cmdMove(const Common::Array<LBValue> &params) {
+ if (params.size() != 1 && params.size() != 2)
+ error("incorrect number of parameters (%d) to move", params.size());
+
+ LBItem *target = _currSource;
+ Common::Point pt;
+ if (params.size() == 1) {
+ pt = params[0].toPoint();
+ } else {
+ target = resolveItem(params[0]);
+ if (!target)
+ error("attempted move on invalid item (%s)", params[0].toString().c_str());
+ pt = params[1].toPoint();
+ }
+
+ target->moveBy(pt);
+}
+
void LBCode::cmdSetDragParams(const Common::Array<LBValue> &params) {
warning("ignoring setDragParams");
}
+void LBCode::cmdNewList(const Common::Array<LBValue> &params) {
+ if (params.size() != 0)
+ error("incorrect number of parameters (%d) to newList", params.size());
+
+ _stack.push(Common::SharedPtr<LBList>(new LBList));
+}
+
+void LBCode::cmdAdd(const Common::Array<LBValue> &params) {
+ if (params.size() != 2)
+ error("incorrect number of parameters (%d) to add", params.size());
+
+ if (params[0].type != kLBValueList || !params[0].list)
+ error("invalid lbx object passed to add");
+
+ params[0].list->array.push_back(params[1]);
+}
+
+void LBCode::cmdAddAt(const Common::Array<LBValue> &params) {
+ if (params.size() != 3)
+ error("incorrect number of parameters (%d) to addAt", params.size());
+
+ if (params[0].type != kLBValueList || !params[0].list)
+ error("invalid lbx object passed to addAt");
+
+ if (params[1].type != kLBValueInteger || params[1].integer < 1)
+ error("invalid index passed to addAt");
+
+ if ((uint)params[1].integer > params[0].list->array.size())
+ params[0].list->array.resize(params[1].integer);
+ params[0].list->array.insert_at(params[1].integer - 1, params[2]);
+}
+
+void LBCode::cmdSetAt(const Common::Array<LBValue> &params) {
+ if (params.size() != 3)
+ error("incorrect number of parameters (%d) to setAt", params.size());
+
+ if (params[0].type != kLBValueList || !params[0].list)
+ error("invalid lbx object passed to setAt");
+
+ if (params[1].type != kLBValueInteger || params[1].integer < 1)
+ error("invalid index passed to setAt");
+
+ if ((uint)params[1].integer > params[0].list->array.size())
+ params[0].list->array.resize(params[1].integer);
+ params[0].list->array[params[1].integer - 1] = params[2];
+}
+
+void LBCode::cmdListLen(const Common::Array<LBValue> &params) {
+ if (params.size() != 1)
+ error("incorrect number of parameters (%d) to listLen", params.size());
+
+ if (params[0].type != kLBValueList || !params[0].list)
+ error("invalid lbx object passed to lbxFunc");
+
+ _stack.push(params[0].list->array.size());
+}
+
+void LBCode::cmdDeleteAt(const Common::Array<LBValue> &params) {
+ if (params.size() != 2)
+ error("incorrect number of parameters (%d) to deleteAt", params.size());
+
+ if (params[0].type != kLBValueList || !params[0].list)
+ error("invalid lbx object passed to deleteAt");
+
+ if (params[1].type != kLBValueInteger)
+ error("invalid index passed to deleteAt");
+ if (params[1].integer < 1 || params[1].integer > (int)params[0].list->array.size())
+ return;
+ params[0].list->array.remove_at(params[1].integer - 1);
+}
+
+void LBCode::cmdSetProperty(const Common::Array<LBValue> &params) {
+ if (params.size() < 2 || params.size() > 3)
+ error("incorrect number of parameters (%d) to setProperty", params.size());
+
+ Common::String name;
+ LBValue val;
+ LBItem *target = _currSource;
+ if (params.size() == 3) {
+ target = resolveItem(params[0]);
+ if (!target)
+ error("attempted setProperty on invalid item (%s)", params[0].toString().c_str());
+ name = params[1].toString();
+ val = params[2];
+ } else {
+ name = params[0].toString();
+ val = params[1];
+ }
+
+ target->_variables[name] = val;
+}
+
+void LBCode::cmdGetProperty(const Common::Array<LBValue> &params) {
+ if (params.size() < 1 || params.size() > 2)
+ error("incorrect number of parameters (%d) to getProperty", params.size());
+
+ Common::String name;
+ LBItem *target = _currSource;
+ if (params.size() == 2) {
+ target = resolveItem(params[0]);
+ if (!target)
+ error("attempted getProperty on invalid item (%s)", params[0].toString().c_str());
+ name = params[1].toString();
+ } else {
+ name = params[0].toString();
+ }
+
+ _stack.push(target->_variables[name]);
+}
+
+void LBCode::cmdExec(const Common::Array<LBValue> &params) {
+ if (params.size() != 1)
+ error("incorrect number of parameters (%d) to exec", params.size());
+ if (params[0].type != kLBValueInteger || params[0].integer < 0)
+ error("invalid offset passed to exec");
+ uint offset = (uint)params[0].integer;
+
+ uint32 oldOffset = _currOffset;
+ byte oldToken = _currToken;
+ LBValue val = runCode(_currSource, offset);
+ _currOffset = oldOffset;
+ _currToken = oldToken;
+
+ _stack.push(val);
+ _stack.push(val);
+}
+
+void LBCode::cmdReturn(const Common::Array<LBValue> &params) {
+ if (params.size() != 2)
+ error("incorrect number of parameters (%d) to return", params.size());
+
+ if (!_stack.size())
+ error("empty stack on entry to return");
+
+ if (params[0] == _stack.top()) {
+ _stack.pop();
+ _stack.push(params[1]);
+ _currToken = kTokenEndOfFile;
+ } else
+ _stack.push(_stack.top());
+}
+
void LBCode::cmdSetPlayParams(const Common::Array<LBValue> &params) {
if (params.size() > 8)
error("too many parameters (%d) to setPlayParams", params.size());
@@ -994,6 +1303,32 @@ void LBCode::cmdSetHitTest(const Common::Array<LBValue> &params) {
warning("ignoring setHitTest");
}
+void LBCode::cmdLBXCreate(const Common::Array<LBValue> &params) {
+ if (params.size() != 1)
+ error("incorrect number of parameters (%d) to lbxCreate", params.size());
+
+ _stack.push(createLBXObject(_vm, params[0].toInt()));
+}
+
+void LBCode::cmdLBXFunc(const Common::Array<LBValue> &params) {
+ if (params.size() < 2)
+ error("incorrect number of parameters (%d) to lbxFunc", params.size());
+
+ if (params[0].type != kLBValueLBX || !params[0].lbx)
+ error("invalid lbx object passed to lbxFunc");
+
+ Common::SharedPtr<LBXObject> lbx = params[0].lbx;
+ uint callId = params[1].toInt();
+
+ Common::Array<LBValue> callParams;
+ for (uint i = 0; i < params.size() - 2; i++)
+ callParams.push_back(params[i + 2]);
+
+ LBValue result;
+ if (lbx->call(callId, callParams, result))
+ _stack.push(result);
+}
+
void LBCode::cmdKey(const Common::Array<LBValue> &params) {
_stack.push(0); // FIXME
warning("ignoring Key");
@@ -1001,7 +1336,7 @@ void LBCode::cmdKey(const Common::Array<LBValue> &params) {
#define NUM_ITEM_COMMANDS 34
CodeCommandInfo itemCommandInfo[NUM_ITEM_COMMANDS] = {
- { "clone", 0 },
+ { "clone", &LBCode::itemClone },
{ "destroy", 0 },
{ "dragBeginFrom", 0 },
{ "dragEnd", 0 },
@@ -1022,14 +1357,14 @@ CodeCommandInfo itemCommandInfo[NUM_ITEM_COMMANDS] = {
{ "isMuted", 0 },
{ "isPlaying", &LBCode::itemIsPlaying },
{ "isVisible", 0 },
- { "isLoaded", 0 },
+ { "isLoaded", &LBCode::itemIsLoaded },
{ "isDragging", 0 },
{ "load", 0 },
{ "moveTo", &LBCode::itemMoveTo },
{ "mute", 0 },
{ "play", 0 },
{ "seek", &LBCode::itemSeek },
- { "seekToFrame", 0 },
+ { "seekToFrame", &LBCode::itemSeekToFrame },
{ "setParent", &LBCode::itemSetParent },
{ "setZOrder", 0 },
{ "setText", 0 },
@@ -1054,14 +1389,50 @@ void LBCode::runItemCommand() {
(this->*(info.func))(params);
}
+void LBCode::itemClone(const Common::Array<LBValue> &params) {
+ // TODO: first param can be target?
+ if (params.size() != 2)
+ error("incorrect number of parameters (%d) to setParent", params.size());
+
+ uint id = params[0].toInt();
+ const Common::String &name = params[1].toString();
+
+ _currSource->clone(id, name);
+}
+
void LBCode::itemIsPlaying(const Common::Array<LBValue> &params) {
// TODO
warning("ignoring isPlaying");
_stack.push(0);
}
+void LBCode::itemIsLoaded(const Common::Array<LBValue> &params) {
+ if (params.size() != 1)
+ error("incorrect number of parameters (%d) to isLoaded", params.size());
+
+ LBItem *item = resolveItem(params[0]);
+ if (!item || !item->isLoaded())
+ _stack.push(0);
+ else
+ _stack.push(1);
+}
+
void LBCode::itemMoveTo(const Common::Array<LBValue> &params) {
- warning("ignoring moveTo");
+ if (params.size() != 1 && params.size() != 2)
+ error("incorrect number of parameters (%d) to moveTo", params.size());
+
+ LBItem *target = _currSource;
+ Common::Point pt;
+ if (params.size() == 1) {
+ pt = params[0].toPoint();
+ } else {
+ target = resolveItem(params[0]);
+ if (!target)
+ error("attempted moveTo on invalid item (%s)", params[0].toString().c_str());
+ pt = params[1].toPoint();
+ }
+
+ target->moveTo(pt);
}
void LBCode::itemSeek(const Common::Array<LBValue> &params) {
@@ -1072,6 +1443,17 @@ void LBCode::itemSeek(const Common::Array<LBValue> &params) {
if (!item)
error("attempted seek on invalid item (%s)", params[0].toString().c_str());
uint seekTo = params[1].toInt();
+ item->seekToTime(seekTo);
+}
+
+void LBCode::itemSeekToFrame(const Common::Array<LBValue> &params) {
+ if (params.size() != 2)
+ error("incorrect number of parameters (%d) to seekToFrame", params.size());
+
+ LBItem *item = resolveItem(params[0]);
+ if (!item)
+ error("attempted seekToFrame on invalid item (%s)", params[0].toString().c_str());
+ uint seekTo = params[1].toInt();
item->seek(seekTo);
}
@@ -1091,7 +1473,7 @@ void LBCode::runNotifyCommand() {
debugN("goto");
Common::Array<LBValue> params = readParams();
// TODO: type-checking
- NotifyEvent notifyEvent(kLBNotifyChangePage, 0);
+ NotifyEvent notifyEvent(kLBNotifyChangePage, 1);
switch (params.size()) {
case 4:
notifyEvent.type = kLBNotifyChangeMode; // FIXME: type 8?
@@ -1327,6 +1709,8 @@ uint LBCode::parseCode(const Common::String &source) {
break;
// open bracket
case '(':
+ bool parameterless;
+ parameterless = false;
if (wasFunction) {
// function call parameters
wasFunction = false;
@@ -1342,6 +1726,7 @@ uint LBCode::parseCode(const Common::String &source) {
continue;
if (source[i] != ')')
break;
+ parameterless = true;
code[code.size() - 1] = 0;
break;
}
@@ -1349,14 +1734,20 @@ uint LBCode::parseCode(const Common::String &source) {
// brackets around expression
counterPositions.push_back(0);
}
- code.push_back(kTokenOpenBracket);
+ if (!parameterless)
+ code.push_back(kTokenOpenBracket);
break;
// close bracket
case ')':
if (counterPositions.empty())
error("while parsing script '%s', encountered unmatched )", source.c_str());
+
+ // don't push a kTokenCloseBracket for a parameterless function call
+ uint counterPos2;
+ counterPos2 = counterPositions.back();
+ if (!counterPos2 || code[counterPos2])
+ code.push_back(kTokenCloseBracket);
counterPositions.pop_back();
- code.push_back(kTokenCloseBracket);
break;
// comma (seperating function params)
case ',':
@@ -1375,7 +1766,7 @@ uint LBCode::parseCode(const Common::String &source) {
{
Common::String tempString;
while (pos < source.size()) {
- if (!isalpha(source[pos]) && !isdigit(source[pos]))
+ if (!Common::isAlpha(source[pos]) && !Common::isDigit(source[pos]))
break;
tempString += source[pos++];
}
@@ -1386,7 +1777,7 @@ uint LBCode::parseCode(const Common::String &source) {
}
break;
default:
- if (isdigit(token)) {
+ if (Common::isDigit(token)) {
const char *in = source.c_str() + pos - 1;
// FIXME: handle floats?
char *endptr;
@@ -1401,15 +1792,21 @@ uint LBCode::parseCode(const Common::String &source) {
WRITE_BE_UINT16(tmp, (int16)intValue);
code.push_back(tmp[0]);
code.push_back(tmp[1]);
- } else if (isalpha(token)) {
+ } else if (Common::isAlpha(token)) {
Common::String tempString;
tempString += token;
while (pos < source.size()) {
- if (!isalpha(source[pos]) && !isdigit(source[pos]))
+ if (!Common::isAlpha(source[pos]) && !Common::isDigit(source[pos]))
break;
tempString += source[pos++];
}
- wasFunction = parseCodeSymbol(tempString, pos, code);
+ if (tempString.equalsIgnoreCase("true")) {
+ code.push_back(kTokenTrue);
+ } else if (tempString.equalsIgnoreCase("false")) {
+ code.push_back(kTokenFalse);
+ } else {
+ wasFunction = parseCodeSymbol(tempString, pos, code);
+ }
} else {
error("while parsing script '%s', couldn't parse '%c'", source.c_str(), token);
}
diff --git a/engines/mohawk/livingbooks_code.h b/engines/mohawk/livingbooks_code.h
index 79c9af94f7..47dd90f814 100644
--- a/engines/mohawk/livingbooks_code.h
+++ b/engines/mohawk/livingbooks_code.h
@@ -23,6 +23,7 @@
#ifndef MOHAWK_LIVINGBOOKS_CODE_H
#define MOHAWK_LIVINGBOOKS_CODE_H
+#include "common/ptr.h"
#include "common/rect.h"
#include "common/stack.h"
#include "common/substream.h"
@@ -31,6 +32,8 @@ namespace Mohawk {
class MohawkEngine_LivingBooks;
class LBItem;
+class LBXObject;
+struct LBList;
enum LBValueType {
kLBValueString,
@@ -38,7 +41,9 @@ enum LBValueType {
kLBValueReal,
kLBValuePoint,
kLBValueRect,
- kLBValueItemPtr
+ kLBValueItemPtr,
+ kLBValueLBX,
+ kLBValueList
};
struct LBValue {
@@ -66,6 +71,14 @@ struct LBValue {
type = kLBValueItemPtr;
item = itm;
}
+ LBValue(Common::SharedPtr<LBXObject> l) {
+ type = kLBValueLBX;
+ lbx = l;
+ }
+ LBValue(Common::SharedPtr<LBList> l) {
+ type = kLBValueList;
+ list = l;
+ }
LBValue(const LBValue &val) {
type = val.type;
switch (type) {
@@ -87,6 +100,12 @@ struct LBValue {
case kLBValueItemPtr:
item = val.item;
break;
+ case kLBValueLBX:
+ lbx = val.lbx;
+ break;
+ case kLBValueList:
+ list = val.list;
+ break;
}
}
@@ -97,6 +116,8 @@ struct LBValue {
Common::Point point;
Common::Rect rect;
LBItem *item;
+ Common::SharedPtr<LBXObject> lbx;
+ Common::SharedPtr<LBList> list;
bool operator==(const LBValue &x) const;
bool operator!=(const LBValue &x) const;
@@ -111,6 +132,10 @@ struct LBValue {
Common::Rect toRect() const;
};
+struct LBList {
+ Common::Array<LBValue> array;
+};
+
enum {
kLBCodeLiteralInteger = 0x1
};
@@ -207,6 +232,7 @@ protected:
void parseArithmetic2();
void parseMain();
+ LBValue *getIndexedVar(Common::String varname, const Common::Array<LBValue> &index);
LBItem *resolveItem(const LBValue &value);
Common::Array<LBValue> readParams();
Common::Rect getRectFromParams(const Common::Array<LBValue> &params);
@@ -224,22 +250,43 @@ public:
void cmdRandom(const Common::Array<LBValue> &params);
void cmdStringLen(const Common::Array<LBValue> &params);
void cmdSubstring(const Common::Array<LBValue> &params);
+ void cmdMax(const Common::Array<LBValue> &params);
+ void cmdMin(const Common::Array<LBValue> &params);
+ void cmdAbs(const Common::Array<LBValue> &params);
void cmdGetRect(const Common::Array<LBValue> &params);
+ void cmdMakePoint(const Common::Array<LBValue> &params);
void cmdTopLeft(const Common::Array<LBValue> &params);
void cmdBottomRight(const Common::Array<LBValue> &params);
+ void cmdMousePos(const Common::Array<LBValue> &params);
void cmdTop(const Common::Array<LBValue> &params);
void cmdLeft(const Common::Array<LBValue> &params);
void cmdBottom(const Common::Array<LBValue> &params);
void cmdRight(const Common::Array<LBValue> &params);
+ void cmdMove(const Common::Array<LBValue> &params);
void cmdSetDragParams(const Common::Array<LBValue> &params);
+ void cmdNewList(const Common::Array<LBValue> &params);
+ void cmdAdd(const Common::Array<LBValue> &params);
+ void cmdAddAt(const Common::Array<LBValue> &params);
+ void cmdSetAt(const Common::Array<LBValue> &params);
+ void cmdListLen(const Common::Array<LBValue> &params);
+ void cmdDeleteAt(const Common::Array<LBValue> &params);
+ void cmdSetProperty(const Common::Array<LBValue> &params);
+ void cmdGetProperty(const Common::Array<LBValue> &params);
+ void cmdExec(const Common::Array<LBValue> &params);
+ void cmdReturn(const Common::Array<LBValue> &params);
void cmdSetPlayParams(const Common::Array<LBValue> &params);
void cmdSetKeyEvent(const Common::Array<LBValue> &params);
void cmdSetHitTest(const Common::Array<LBValue> &params);
+ void cmdLBXCreate(const Common::Array<LBValue> &params);
+ void cmdLBXFunc(const Common::Array<LBValue> &params);
void cmdKey(const Common::Array<LBValue> &params);
+ void itemClone(const Common::Array<LBValue> &params);
void itemIsPlaying(const Common::Array<LBValue> &params);
+ void itemIsLoaded(const Common::Array<LBValue> &params);
void itemMoveTo(const Common::Array<LBValue> &params);
void itemSeek(const Common::Array<LBValue> &params);
+ void itemSeekToFrame(const Common::Array<LBValue> &params);
void itemSetParent(const Common::Array<LBValue> &params);
};
diff --git a/engines/mohawk/livingbooks_graphics.cpp b/engines/mohawk/livingbooks_graphics.cpp
new file mode 100644
index 0000000000..fb764fa15b
--- /dev/null
+++ b/engines/mohawk/livingbooks_graphics.cpp
@@ -0,0 +1,102 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "mohawk/resource.h"
+#include "mohawk/livingbooks.h"
+#include "mohawk/livingbooks_graphics.h"
+
+#include "common/substream.h"
+#include "common/system.h"
+#include "engines/util.h"
+#include "graphics/palette.h"
+
+namespace Mohawk {
+
+LBGraphics::LBGraphics(MohawkEngine_LivingBooks *vm, uint16 width, uint16 height) : GraphicsManager(), _vm(vm) {
+ _bmpDecoder = _vm->isPreMohawk() ? new LivingBooksBitmap_v1() : new MohawkBitmap();
+
+ initGraphics(width, height, true);
+}
+
+LBGraphics::~LBGraphics() {
+ delete _bmpDecoder;
+}
+
+MohawkSurface *LBGraphics::decodeImage(uint16 id) {
+ if (_vm->isPreMohawk())
+ return _bmpDecoder->decodeImage(_vm->wrapStreamEndian(ID_BMAP, id));
+
+ return _bmpDecoder->decodeImage(_vm->getResource(ID_TBMP, id));
+}
+
+void LBGraphics::copyOffsetAnimImageToScreen(uint16 image, int left, int top) {
+ MohawkSurface *mhkSurface = findImage(image);
+
+ left -= mhkSurface->getOffsetX();
+ top -= mhkSurface->getOffsetY();
+
+ GraphicsManager::copyAnimImageToScreen(image, left, top);
+}
+
+bool LBGraphics::imageIsTransparentAt(uint16 image, bool useOffsets, int x, int y) {
+ MohawkSurface *mhkSurface = findImage(image);
+
+ if (useOffsets) {
+ x += mhkSurface->getOffsetX();
+ y += mhkSurface->getOffsetY();
+ }
+
+ if (x < 0 || y < 0)
+ return true;
+
+ Graphics::Surface *surface = mhkSurface->getSurface();
+ if (x >= surface->w || y >= surface->h)
+ return true;
+
+ return *(byte *)surface->getBasePtr(x, y) == 0;
+}
+
+void LBGraphics::setPalette(uint16 id) {
+ // Old Living Books games use the old CTBL-style palette format while newer
+ // games use the better tPAL format which can store partial palettes.
+ if (_vm->isPreMohawk()) {
+ Common::SeekableSubReadStreamEndian *ctblStream = _vm->wrapStreamEndian(ID_CTBL, id);
+ uint16 colorCount = ctblStream->readUint16();
+ byte *palette = new byte[colorCount * 3];
+
+ for (uint16 i = 0; i < colorCount; i++) {
+ palette[i * 3 + 0] = ctblStream->readByte();
+ palette[i * 3 + 1] = ctblStream->readByte();
+ palette[i * 3 + 2] = ctblStream->readByte();
+ ctblStream->readByte();
+ }
+
+ delete ctblStream;
+
+ _vm->_system->getPaletteManager()->setPalette(palette, 0, colorCount);
+ delete[] palette;
+ } else {
+ GraphicsManager::setPalette(id);
+ }
+}
+
+} // End of namespace Mohawk
diff --git a/engines/mohawk/livingbooks_graphics.h b/engines/mohawk/livingbooks_graphics.h
new file mode 100644
index 0000000000..3e2609750a
--- /dev/null
+++ b/engines/mohawk/livingbooks_graphics.h
@@ -0,0 +1,52 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef MOHAWK_LIVINGBOOKS_GRAPHICS_H
+#define MOHAWK_LIVINGBOOKS_GRAPHICS_H
+
+#include "mohawk/graphics.h"
+
+namespace Mohawk {
+
+class MohawkEngine_LivingBooks;
+
+class LBGraphics : public GraphicsManager {
+public:
+ LBGraphics(MohawkEngine_LivingBooks *vm, uint16 width, uint16 height);
+ ~LBGraphics();
+
+ void setPalette(uint16 id);
+ void copyOffsetAnimImageToScreen(uint16 image, int left = 0, int top = 0);
+ bool imageIsTransparentAt(uint16 image, bool useOffsets, int x, int y);
+
+protected:
+ MohawkSurface *decodeImage(uint16 id);
+ MohawkEngine *getVM() { return (MohawkEngine *)_vm; }
+
+private:
+ MohawkBitmap *_bmpDecoder;
+ MohawkEngine_LivingBooks *_vm;
+};
+
+} // End of namespace Mohawk
+
+#endif
diff --git a/engines/mohawk/livingbooks_lbx.cpp b/engines/mohawk/livingbooks_lbx.cpp
new file mode 100644
index 0000000000..9628e06294
--- /dev/null
+++ b/engines/mohawk/livingbooks_lbx.cpp
@@ -0,0 +1,141 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "engines/mohawk/livingbooks.h"
+#include "engines/mohawk/livingbooks_lbx.h"
+
+namespace Mohawk {
+
+class LBXDataFile : public LBXObject {
+public:
+ LBXDataFile(MohawkEngine_LivingBooks *vm);
+ ~LBXDataFile();
+
+ bool call(uint callId, const Common::Array<LBValue> &params, LBValue &result);
+
+protected:
+ Common::ConfigFile _dataFile;
+ Common::String _curSection;
+
+ void open(const Common::String &filename);
+ bool sectionExists(const Common::String &section);
+};
+
+LBXDataFile::LBXDataFile(MohawkEngine_LivingBooks *vm) : LBXObject(vm) {
+}
+
+LBXDataFile::~LBXDataFile() {
+}
+
+enum {
+ kLBXDataFileOpen = 1,
+ kLBXDataFileGetSectionList = 4,
+ kLBXDataFileSetCurSection = 5,
+ kLBXDataFileLoadCurSectionVars = 8,
+ kLBXDataFileDeleteCurSection = 10,
+ kLBXDataFileSectionExists = 14
+};
+
+bool LBXDataFile::call(uint callId, const Common::Array<LBValue> &params, LBValue &result) {
+ switch (callId) {
+ case kLBXDataFileOpen:
+ if (params.size() != 1)
+ error("incorrect number of parameters (%d) to LBXDataFile::open", params.size());
+
+ open(params[0].toString());
+ return false;
+
+ case kLBXDataFileGetSectionList:
+ {
+ Common::SharedPtr<LBList> list = Common::SharedPtr<LBList>(new LBList);
+ Common::ConfigFile::SectionList sections = _dataFile.getSections();
+ for (Common::List<Common::ConfigFile::Section>::const_iterator i = sections.begin(); i != sections.end(); ++i)
+ list->array.push_back(LBValue(i->name));
+ result = LBValue(list);
+ }
+ return true;
+
+ case kLBXDataFileSetCurSection:
+ if (params.size() != 1)
+ error("incorrect number of parameters (%d) to LBXDataFile::setCurSection", params.size());
+
+ _curSection = params[0].toString();
+ return false;
+
+ case kLBXDataFileLoadCurSectionVars:
+ if (params.size() != 0)
+ error("incorrect number of parameters (%d) to LBXDataFile::loadCurSectionVars", params.size());
+
+ {
+ const Common::ConfigFile::SectionKeyList globals = _dataFile.getKeys(_curSection);
+ for (Common::ConfigFile::SectionKeyList::const_iterator i = globals.begin(); i != globals.end(); i++) {
+ Common::String command = Common::String::format("%s = %s", i->key.c_str(), i->value.c_str());
+ LBCode tempCode(_vm, 0);
+ uint offset = tempCode.parseCode(command);
+ tempCode.runCode(NULL, offset);
+ }
+ }
+ return false;
+
+ case kLBXDataFileDeleteCurSection:
+ if (params.size() != 0)
+ error("incorrect number of parameters (%d) to LBXDataFile::deleteCurSection", params.size());
+
+ _dataFile.removeSection(_curSection);
+ return false;
+
+ case kLBXDataFileSectionExists:
+ if (params.size() != 1)
+ error("incorrect number of parameters (%d) to LBXDataFile::sectionExists", params.size());
+ if (_dataFile.hasSection(params[0].toString()))
+ result = 1;
+ else
+ result = 0;
+ return true;
+
+ default:
+ error("LBXDataFile call %d is unknown", callId);
+ }
+}
+
+void LBXDataFile::open(const Common::String &filename) {
+ _dataFile.clear();
+
+ if (_dataFile.loadFromFile(filename))
+ return;
+
+ // FIXME: try savegames
+
+ error("LBXDataFile::open: couldn't open '%s'", filename.c_str());
+}
+
+Common::SharedPtr<LBXObject> createLBXObject(MohawkEngine_LivingBooks *vm, uint16 type) {
+ switch (type) {
+ case 1001:
+ return Common::SharedPtr<LBXObject>(new LBXDataFile(vm));
+
+ default:
+ error("unknown LBX object type %d", type);
+ }
+}
+
+} // End of namespace Mohawk
diff --git a/engines/m4/saveload.h b/engines/mohawk/livingbooks_lbx.h
index 9b76054e65..3cca0a8e82 100644
--- a/engines/m4/saveload.h
+++ b/engines/mohawk/livingbooks_lbx.h
@@ -20,35 +20,28 @@
*
*/
-#ifndef M4_SAVELOAD_H
-#define M4_SAVELOAD_H
+#ifndef MOHAWK_LIVINGBOOKS_LBX_H
+#define MOHAWK_LIVINGBOOKS_LBX_H
-#include "m4/graphics.h"
-#include "common/ptr.h"
-
-#define MAX_SAVEGAME_NAME 80
-
-namespace M4 {
+#include "engines/mohawk/livingbooks_code.h"
-typedef Common::List<Common::String> SaveGameList;
-typedef SaveGameList::iterator SaveGameIterator;
+#include "common/ptr.h"
-class SaveLoad {
-private:
- MadsM4Engine *_vm;
- bool _emulateOriginal;
+namespace Mohawk {
- const char *generateSaveName(int slotNumber);
+class LBXObject {
public:
- SaveLoad(MadsM4Engine *vm);
+ LBXObject(MohawkEngine_LivingBooks *vm) : _vm(vm) { }
+ virtual ~LBXObject() { }
+
+ virtual bool call(uint callId, const Common::Array<LBValue> &params, LBValue &result) = 0;
- bool hasSaves();
- SaveGameList *getSaves();
- M4Surface *getThumbnail(int slotNumber);
- bool load(int slotNumber);
- bool save(int slotNumber, Common::String saveName);
+protected:
+ MohawkEngine_LivingBooks *_vm;
};
-}
+Common::SharedPtr<LBXObject> createLBXObject(MohawkEngine_LivingBooks *vm, uint16 type);
+
+} // End of namespace Mohawk
#endif
diff --git a/engines/mohawk/module.mk b/engines/mohawk/module.mk
index 30f1d40fdb..83e541e3e4 100644
--- a/engines/mohawk/module.mk
+++ b/engines/mohawk/module.mk
@@ -10,6 +10,8 @@ MODULE_OBJS = \
installer_archive.o \
livingbooks.o \
livingbooks_code.o \
+ livingbooks_graphics.o \
+ livingbooks_lbx.o \
mohawk.o \
resource.o \
sound.o \
@@ -21,6 +23,7 @@ MODULE_OBJS += \
cstime.o \
cstime_cases.o \
cstime_game.o \
+ cstime_graphics.o \
cstime_ui.o \
cstime_view.o
endif
@@ -29,6 +32,7 @@ ifdef ENABLE_MYST
MODULE_OBJS += \
myst.o \
myst_areas.o \
+ myst_graphics.o \
myst_scripts.o \
myst_state.o \
resource_cache.o \
@@ -50,6 +54,7 @@ ifdef ENABLE_RIVEN
MODULE_OBJS += \
riven.o \
riven_external.o \
+ riven_graphics.o \
riven_saveload.o \
riven_scripts.o \
riven_vars.o
diff --git a/engines/mohawk/myst.cpp b/engines/mohawk/myst.cpp
index eeb4594f3c..c22b30ad4d 100644
--- a/engines/mohawk/myst.cpp
+++ b/engines/mohawk/myst.cpp
@@ -27,9 +27,9 @@
#include "common/textconsole.h"
#include "mohawk/cursors.h"
-#include "mohawk/graphics.h"
#include "mohawk/myst.h"
#include "mohawk/myst_areas.h"
+#include "mohawk/myst_graphics.h"
#include "mohawk/myst_scripts.h"
#include "mohawk/myst_state.h"
#include "mohawk/dialogs.h"
diff --git a/engines/mohawk/myst.h b/engines/mohawk/myst.h
index 02f0a46e3f..30770f7ec9 100644
--- a/engines/mohawk/myst.h
+++ b/engines/mohawk/myst.h
@@ -173,7 +173,7 @@ public:
MystGraphics *_gfx;
MystGameState *_gameState;
MystScriptParser *_scriptParser;
- Common::Array<MystResource*> _resources;
+ Common::Array<MystResource *> _resources;
MystResource *_dragResource;
Common::RandomSource *_rnd;
diff --git a/engines/mohawk/myst_areas.cpp b/engines/mohawk/myst_areas.cpp
index 294fcea2f1..fe33ceaa9b 100644
--- a/engines/mohawk/myst_areas.cpp
+++ b/engines/mohawk/myst_areas.cpp
@@ -20,8 +20,8 @@
*
*/
-#include "mohawk/graphics.h"
#include "mohawk/myst_areas.h"
+#include "mohawk/myst_graphics.h"
#include "mohawk/myst_scripts.h"
#include "mohawk/sound.h"
#include "mohawk/video.h"
diff --git a/engines/mohawk/myst_areas.h b/engines/mohawk/myst_areas.h
index 136356ea4f..62af5ec4cf 100644
--- a/engines/mohawk/myst_areas.h
+++ b/engines/mohawk/myst_areas.h
@@ -20,11 +20,13 @@
*
*/
+#ifndef MYST_AREAS_H
+#define MYST_AREAS_H
+
#include "mohawk/myst.h"
#include "mohawk/video.h"
-#ifndef MYST_AREAS_H
-#define MYST_AREAS_H
+#include "common/rect.h"
namespace Mohawk {
@@ -137,7 +139,7 @@ public:
protected:
uint16 _var7;
uint16 _numSubResources;
- Common::Array<MystResource*> _subResources;
+ Common::Array<MystResource *> _subResources;
};
class MystResourceType8 : public MystResourceType7 {
diff --git a/engines/mohawk/myst_graphics.cpp b/engines/mohawk/myst_graphics.cpp
new file mode 100644
index 0000000000..151390580f
--- /dev/null
+++ b/engines/mohawk/myst_graphics.cpp
@@ -0,0 +1,493 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "mohawk/myst.h"
+#include "mohawk/myst_graphics.h"
+#include "mohawk/resource.h"
+
+#include "common/substream.h"
+#include "common/system.h"
+#include "common/textconsole.h"
+#include "engines/util.h"
+#include "graphics/jpeg.h"
+#include "graphics/pict.h"
+
+namespace Mohawk {
+
+MystGraphics::MystGraphics(MohawkEngine_Myst* vm) : GraphicsManager(), _vm(vm) {
+ _bmpDecoder = new MystBitmap();
+
+ _viewport = Common::Rect(544, 332);
+
+ // The original version of Myst could run in 8bpp color too.
+ // However, it dithered videos to 8bpp and they looked considerably
+ // worse (than they already did :P). So we're not even going to
+ // support 8bpp mode in Myst (Myst ME required >8bpp anyway).
+ initGraphics(_viewport.width(), _viewport.height(), true, NULL); // What an odd screen size!
+
+ _pixelFormat = _vm->_system->getScreenFormat();
+
+ if (_pixelFormat.bytesPerPixel == 1)
+ error("Myst requires greater than 256 colors to run");
+
+ if (_vm->getFeatures() & GF_ME) {
+ _jpegDecoder = new Graphics::JPEG();
+ _pictDecoder = new Graphics::PictDecoder(_pixelFormat);
+ } else {
+ _jpegDecoder = NULL;
+ _pictDecoder = NULL;
+ }
+
+ _pictureFile.entries = NULL;
+
+ // Initialize our buffer
+ _backBuffer = new Graphics::Surface();
+ _backBuffer->create(_vm->_system->getWidth(), _vm->_system->getHeight(), _pixelFormat);
+
+ _nextAllowedDrawTime = _vm->_system->getMillis();
+ _enableDrawingTimeSimulation = 0;
+}
+
+MystGraphics::~MystGraphics() {
+ delete _bmpDecoder;
+ delete _jpegDecoder;
+ delete _pictDecoder;
+ delete[] _pictureFile.entries;
+
+ _backBuffer->free();
+ delete _backBuffer;
+}
+
+static const char *s_picFileNames[] = {
+ "CHpics",
+ "",
+ "",
+ "DUpics",
+ "INpics",
+ "",
+ "MEpics",
+ "MYpics",
+ "SEpics",
+ "",
+ "",
+ "STpics"
+};
+
+void MystGraphics::loadExternalPictureFile(uint16 stack) {
+ if (_vm->getPlatform() != Common::kPlatformMacintosh)
+ return;
+
+ if (_pictureFile.picFile.isOpen())
+ _pictureFile.picFile.close();
+ delete[] _pictureFile.entries;
+
+ if (!scumm_stricmp(s_picFileNames[stack], ""))
+ return;
+
+ if (!_pictureFile.picFile.open(s_picFileNames[stack]))
+ error ("Could not open external picture file \'%s\'", s_picFileNames[stack]);
+
+ _pictureFile.pictureCount = _pictureFile.picFile.readUint32BE();
+ _pictureFile.entries = new PictureFile::PictureEntry[_pictureFile.pictureCount];
+
+ for (uint32 i = 0; i < _pictureFile.pictureCount; i++) {
+ _pictureFile.entries[i].offset = _pictureFile.picFile.readUint32BE();
+ _pictureFile.entries[i].size = _pictureFile.picFile.readUint32BE();
+ _pictureFile.entries[i].id = _pictureFile.picFile.readUint16BE();
+ _pictureFile.entries[i].type = _pictureFile.picFile.readUint16BE();
+ _pictureFile.entries[i].width = _pictureFile.picFile.readUint16BE();
+ _pictureFile.entries[i].height = _pictureFile.picFile.readUint16BE();
+ }
+}
+
+MohawkSurface *MystGraphics::decodeImage(uint16 id) {
+ MohawkSurface *mhkSurface = 0;
+
+ // Myst ME uses JPEG/PICT images instead of compressed Windows Bitmaps for room images,
+ // though there are a few weird ones that use that format. For further nonsense with images,
+ // the Macintosh version stores images in external "picture files." We check them before
+ // going to check for a PICT resource.
+ if (_vm->getFeatures() & GF_ME && _vm->getPlatform() == Common::kPlatformMacintosh && _pictureFile.picFile.isOpen()) {
+ for (uint32 i = 0; i < _pictureFile.pictureCount; i++)
+ if (_pictureFile.entries[i].id == id) {
+ if (_pictureFile.entries[i].type == 0) {
+ Common::SeekableReadStream *stream = new Common::SeekableSubReadStream(&_pictureFile.picFile, _pictureFile.entries[i].offset, _pictureFile.entries[i].offset + _pictureFile.entries[i].size);
+
+ if (!_jpegDecoder->read(stream))
+ error("Could not decode Myst ME Mac JPEG");
+
+ mhkSurface = new MohawkSurface(_jpegDecoder->getSurface(_pixelFormat));
+ delete stream;
+ } else if (_pictureFile.entries[i].type == 1) {
+ mhkSurface = new MohawkSurface(_pictDecoder->decodeImage(new Common::SeekableSubReadStream(&_pictureFile.picFile, _pictureFile.entries[i].offset, _pictureFile.entries[i].offset + _pictureFile.entries[i].size)));
+ } else
+ error ("Unknown Picture File type %d", _pictureFile.entries[i].type);
+ break;
+ }
+ }
+
+ // We're not using the external Mac files, so it's time to delve into the main Mohawk
+ // archives. However, we still don't know if it's a PICT or WDIB resource. If it's Myst
+ // ME it's most likely a PICT, and if it's original it's definitely a WDIB. However,
+ // Myst ME throws us another curve ball in that PICT resources can contain WDIB's instead
+ // of PICT's.
+ if (!mhkSurface) {
+ bool isPict = false;
+ Common::SeekableReadStream *dataStream = NULL;
+
+ if (_vm->getFeatures() & GF_ME && _vm->hasResource(ID_PICT, id)) {
+ // The PICT resource exists. However, it could still contain a MystBitmap
+ // instead of a PICT image...
+ dataStream = _vm->getResource(ID_PICT, id);
+ } else // No PICT, so the WDIB must exist. Let's go grab it.
+ dataStream = _vm->getResource(ID_WDIB, id);
+
+ if (_vm->getFeatures() & GF_ME) {
+ // Here we detect whether it's really a PICT or a WDIB. Since a MystBitmap
+ // would be compressed, there's no way to detect for the BM without a hack.
+ // So, we search for the PICT version opcode for detection.
+ dataStream->seek(512 + 10); // 512 byte pict header
+ isPict = (dataStream->readUint32BE() == 0x001102FF);
+ dataStream->seek(0);
+ }
+
+ if (isPict)
+ mhkSurface = new MohawkSurface(_pictDecoder->decodeImage(dataStream));
+ else {
+ mhkSurface = _bmpDecoder->decodeImage(dataStream);
+ mhkSurface->convertToTrueColor();
+ }
+ }
+
+ assert(mhkSurface);
+ return mhkSurface;
+}
+
+void MystGraphics::copyImageSectionToScreen(uint16 image, Common::Rect src, Common::Rect dest) {
+ Graphics::Surface *surface = findImage(image)->getSurface();
+
+ // Make sure the image is bottom aligned in the dest rect
+ dest.top = dest.bottom - MIN<int>(surface->h, dest.height());
+
+ // Convert from bitmap coordinates to surface coordinates
+ uint16 top = surface->h - (src.top + MIN<int>(surface->h, dest.height()));
+
+ // Do not draw the top pixels if the image is too tall
+ if (dest.height() > _viewport.height())
+ top += dest.height() - _viewport.height();
+
+ // Clip the destination rect to the screen
+ if (dest.right > _vm->_system->getWidth() || dest.bottom > _vm->_system->getHeight())
+ dest.debugPrint(4, "Clipping destination rect to the screen");
+ dest.right = CLIP<int>(dest.right, 0, _vm->_system->getWidth());
+ dest.bottom = CLIP<int>(dest.bottom, 0, _vm->_system->getHeight());
+
+ uint16 width = MIN<int>(surface->w, dest.width());
+ uint16 height = MIN<int>(surface->h, dest.height());
+
+ // Clamp Width and Height to within src surface dimensions
+ if (src.left + width > surface->w)
+ width = surface->w - src.left;
+ if (src.top + height > surface->h)
+ height = surface->h - src.top;
+
+ debug(3, "MystGraphics::copyImageSectionToScreen()");
+ debug(3, "\tImage: %d", image);
+ debug(3, "\tsrc.left: %d", src.left);
+ debug(3, "\tsrc.top: %d", src.top);
+ debug(3, "\tdest.left: %d", dest.left);
+ debug(3, "\tdest.top: %d", dest.top);
+ debug(3, "\twidth: %d", width);
+ debug(3, "\theight: %d", height);
+
+ simulatePreviousDrawDelay(dest);
+
+ _vm->_system->copyRectToScreen((byte *)surface->getBasePtr(src.left, top), surface->pitch, dest.left, dest.top, width, height);
+}
+
+void MystGraphics::copyImageSectionToBackBuffer(uint16 image, Common::Rect src, Common::Rect dest) {
+ Graphics::Surface *surface = findImage(image)->getSurface();
+
+ // Make sure the image is bottom aligned in the dest rect
+ dest.top = dest.bottom - MIN<int>(surface->h, dest.height());
+
+ // Convert from bitmap coordinates to surface coordinates
+ uint16 top = surface->h - (src.top + MIN<int>(surface->h, dest.height()));
+
+ // Do not draw the top pixels if the image is too tall
+ if (dest.height() > _viewport.height()) {
+ top += dest.height() - _viewport.height();
+ }
+
+ // Clip the destination rect to the screen
+ if (dest.right > _vm->_system->getWidth() || dest.bottom > _vm->_system->getHeight())
+ dest.debugPrint(4, "Clipping destination rect to the screen");
+ dest.right = CLIP<int>(dest.right, 0, _vm->_system->getWidth());
+ dest.bottom = CLIP<int>(dest.bottom, 0, _vm->_system->getHeight());
+
+ uint16 width = MIN<int>(surface->w, dest.width());
+ uint16 height = MIN<int>(surface->h, dest.height());
+
+ // Clamp Width and Height to within src surface dimensions
+ if (src.left + width > surface->w)
+ width = surface->w - src.left;
+ if (src.top + height > surface->h)
+ height = surface->h - src.top;
+
+ debug(3, "MystGraphics::copyImageSectionToBackBuffer()");
+ debug(3, "\tImage: %d", image);
+ debug(3, "\tsrc.left: %d", src.left);
+ debug(3, "\tsrc.top: %d", src.top);
+ debug(3, "\tdest.left: %d", dest.left);
+ debug(3, "\tdest.top: %d", dest.top);
+ debug(3, "\twidth: %d", width);
+ debug(3, "\theight: %d", height);
+
+ for (uint16 i = 0; i < height; i++)
+ memcpy(_backBuffer->getBasePtr(dest.left, i + dest.top), surface->getBasePtr(src.left, top + i), width * surface->format.bytesPerPixel);
+}
+
+void MystGraphics::copyImageToScreen(uint16 image, Common::Rect dest) {
+ copyImageSectionToScreen(image, Common::Rect(544, 333), dest);
+}
+
+void MystGraphics::copyImageToBackBuffer(uint16 image, Common::Rect dest) {
+ copyImageSectionToBackBuffer(image, Common::Rect(544, 333), dest);
+}
+
+void MystGraphics::copyBackBufferToScreen(Common::Rect r) {
+ r.clip(_viewport);
+
+ simulatePreviousDrawDelay(r);
+
+ _vm->_system->copyRectToScreen((byte *)_backBuffer->getBasePtr(r.left, r.top), _backBuffer->pitch, r.left, r.top, r.width(), r.height());
+}
+
+void MystGraphics::runTransition(uint16 type, Common::Rect rect, uint16 steps, uint16 delay) {
+
+ // Do not artificially delay during transitions
+ int oldEnableDrawingTimeSimulation = _enableDrawingTimeSimulation;
+ _enableDrawingTimeSimulation = 0;
+
+ switch (type) {
+ case 0: {
+ debugC(kDebugScript, "Left to Right");
+
+ uint16 step = (rect.right - rect.left) / steps;
+ Common::Rect area = rect;
+ for (uint i = 0; i < steps; i++) {
+ area.left = rect.left + step * i;
+ area.right = area.left + step;
+
+ _vm->_system->delayMillis(delay);
+
+ copyBackBufferToScreen(area);
+ _vm->_system->updateScreen();
+ }
+ if (area.right < rect.right) {
+ area.left = area.right;
+ area.right = rect.right;
+
+ copyBackBufferToScreen(area);
+ _vm->_system->updateScreen();
+ }
+ }
+ break;
+ case 1: {
+ debugC(kDebugScript, "Right to Left");
+
+ uint16 step = (rect.right - rect.left) / steps;
+ Common::Rect area = rect;
+ for (uint i = 0; i < steps; i++) {
+ area.right = rect.right - step * i;
+ area.left = area.right - step;
+
+ _vm->_system->delayMillis(delay);
+
+ copyBackBufferToScreen(area);
+ _vm->_system->updateScreen();
+ }
+ if (area.left > rect.left) {
+ area.right = area.left;
+ area.left = rect.left;
+
+ copyBackBufferToScreen(area);
+ _vm->_system->updateScreen();
+ }
+ }
+ break;
+ case 5: {
+ debugC(kDebugScript, "Top to Bottom");
+
+ uint16 step = (rect.bottom - rect.top) / steps;
+ Common::Rect area = rect;
+ for (uint i = 0; i < steps; i++) {
+ area.top = rect.top + step * i;
+ area.bottom = area.top + step;
+
+ _vm->_system->delayMillis(delay);
+
+ copyBackBufferToScreen(area);
+ _vm->_system->updateScreen();
+ }
+ if (area.bottom < rect.bottom) {
+ area.top = area.bottom;
+ area.bottom = rect.bottom;
+
+ copyBackBufferToScreen(area);
+ _vm->_system->updateScreen();
+ }
+ }
+ break;
+ case 6: {
+ debugC(kDebugScript, "Bottom to Top");
+
+ uint16 step = (rect.bottom - rect.top) / steps;
+ Common::Rect area = rect;
+ for (uint i = 0; i < steps; i++) {
+ area.bottom = rect.bottom - step * i;
+ area.top = area.bottom - step;
+
+ _vm->_system->delayMillis(delay);
+
+ copyBackBufferToScreen(area);
+ _vm->_system->updateScreen();
+ }
+ if (area.top > rect.top) {
+ area.bottom = area.top;
+ area.top = rect.top;
+
+ copyBackBufferToScreen(area);
+ _vm->_system->updateScreen();
+ }
+ }
+ break;
+ default:
+ warning("Unknown Update Direction");
+
+ //TODO: Replace minimal implementation
+ copyBackBufferToScreen(rect);
+ _vm->_system->updateScreen();
+ break;
+ }
+
+ _enableDrawingTimeSimulation = oldEnableDrawingTimeSimulation;
+}
+
+void MystGraphics::drawRect(Common::Rect rect, RectState state) {
+ rect.clip(_viewport);
+
+ // Useful with debugging. Shows where hotspots are on the screen and whether or not they're active.
+ if (!rect.isValidRect() || rect.width() == 0 || rect.height() == 0)
+ return;
+
+ Graphics::Surface *screen = _vm->_system->lockScreen();
+
+ if (state == kRectEnabled)
+ screen->frameRect(rect, _pixelFormat.RGBToColor(0, 255, 0));
+ else if (state == kRectUnreachable)
+ screen->frameRect(rect, _pixelFormat.RGBToColor(0, 0, 255));
+ else
+ screen->frameRect(rect, _pixelFormat.RGBToColor(255, 0, 0));
+
+ _vm->_system->unlockScreen();
+}
+
+void MystGraphics::drawLine(const Common::Point &p1, const Common::Point &p2, uint32 color) {
+ _backBuffer->drawLine(p1.x, p1.y, p2.x, p2.y, color);
+}
+
+void MystGraphics::enableDrawingTimeSimulation(bool enable) {
+ if (enable)
+ _enableDrawingTimeSimulation++;
+ else
+ _enableDrawingTimeSimulation--;
+
+ if (_enableDrawingTimeSimulation < 0)
+ _enableDrawingTimeSimulation = 0;
+}
+
+void MystGraphics::simulatePreviousDrawDelay(const Common::Rect &dest) {
+ uint32 time = 0;
+
+ if (_enableDrawingTimeSimulation) {
+ time = _vm->_system->getMillis();
+
+ // Do not draw anything new too quickly after the previous draw call
+ // so that images stay at least a little while on screen
+ // This is enabled only for scripted draw calls
+ if (time < _nextAllowedDrawTime)
+ _vm->_system->delayMillis(_nextAllowedDrawTime - time);
+ }
+
+ // Next draw call allowed at DELAY + AERA * COEFF milliseconds from now
+ time = _vm->_system->getMillis();
+ _nextAllowedDrawTime = time + _constantDrawDelay + dest.height() * dest.width() / _proportionalDrawDelay;
+}
+
+void MystGraphics::copyBackBufferToScreenWithSaturation(int16 saturation) {
+ Graphics::Surface *screen = _vm->_system->lockScreen();
+
+ for (uint16 y = 0; y < _viewport.height(); y++)
+ for (uint16 x = 0; x < _viewport.width(); x++) {
+ uint32 color;
+ uint8 r, g, b;
+
+ if (_pixelFormat.bytesPerPixel == 2)
+ color = *(const uint16 *)_backBuffer->getBasePtr(x, y);
+ else
+ color = *(const uint32 *)_backBuffer->getBasePtr(x, y);
+
+ _pixelFormat.colorToRGB(color, r, g, b);
+
+ r = CLIP<int16>((int16)r - saturation, 0, 255);
+ g = CLIP<int16>((int16)g - saturation, 0, 255);
+ b = CLIP<int16>((int16)b - saturation, 0, 255);
+
+ color = _pixelFormat.RGBToColor(r, g, b);
+
+ if (_pixelFormat.bytesPerPixel == 2) {
+ uint16 *dst = (uint16 *)screen->getBasePtr(x, y);
+ *dst = color;
+ } else {
+ uint32 *dst = (uint32 *)screen->getBasePtr(x, y);
+ *dst = color;
+ }
+ }
+
+ _vm->_system->unlockScreen();
+ _vm->_system->updateScreen();
+}
+
+void MystGraphics::fadeToBlack() {
+ for (int16 i = 0; i < 256; i += 32) {
+ copyBackBufferToScreenWithSaturation(i);
+ }
+}
+
+void MystGraphics::fadeFromBlack() {
+ for (int16 i = 256; i >= 0; i -= 32) {
+ copyBackBufferToScreenWithSaturation(i);
+ }
+}
+
+} // End of namespace Mohawk
diff --git a/engines/mohawk/myst_graphics.h b/engines/mohawk/myst_graphics.h
new file mode 100644
index 0000000000..e2b02db5fc
--- /dev/null
+++ b/engines/mohawk/myst_graphics.h
@@ -0,0 +1,102 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public 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 MOHAWK_MYST_GRAPHICS_H
+#define MOHAWK_MYST_GRAPHICS_H
+
+#include "mohawk/graphics.h"
+
+#include "common/file.h"
+
+namespace Graphics {
+class JPEG;
+class PictDecoder;
+}
+
+namespace Mohawk {
+
+class MystBitmap;
+class MohawkEngine_Myst;
+
+enum RectState {
+ kRectEnabled,
+ kRectDisabled,
+ kRectUnreachable
+};
+
+class MystGraphics : public GraphicsManager {
+public:
+ MystGraphics(MohawkEngine_Myst*);
+ ~MystGraphics();
+
+ void loadExternalPictureFile(uint16 stack);
+ void copyImageSectionToScreen(uint16 image, Common::Rect src, Common::Rect dest);
+ void copyImageSectionToBackBuffer(uint16 image, Common::Rect src, Common::Rect dest);
+ void copyImageToScreen(uint16 image, Common::Rect dest);
+ void copyImageToBackBuffer(uint16 image, Common::Rect dest);
+ void copyBackBufferToScreen(Common::Rect r);
+ void runTransition(uint16 type, Common::Rect rect, uint16 steps, uint16 delay);
+ void drawRect(Common::Rect rect, RectState state);
+ void drawLine(const Common::Point &p1, const Common::Point &p2, uint32 color);
+ void enableDrawingTimeSimulation(bool enable);
+ void fadeToBlack();
+ void fadeFromBlack();
+
+protected:
+ MohawkSurface *decodeImage(uint16 id);
+ MohawkEngine *getVM() { return (MohawkEngine *)_vm; }
+ void simulatePreviousDrawDelay(const Common::Rect &dest);
+ void copyBackBufferToScreenWithSaturation(int16 saturation);
+
+private:
+ MohawkEngine_Myst *_vm;
+ MystBitmap *_bmpDecoder;
+ Graphics::PictDecoder *_pictDecoder;
+ Graphics::JPEG *_jpegDecoder;
+
+ struct PictureFile {
+ uint32 pictureCount;
+ struct PictureEntry {
+ uint32 offset;
+ uint32 size;
+ uint16 id;
+ uint16 type;
+ uint16 width;
+ uint16 height;
+ } *entries;
+
+ Common::File picFile;
+ } _pictureFile;
+
+ Graphics::Surface *_backBuffer;
+ Graphics::PixelFormat _pixelFormat;
+ Common::Rect _viewport;
+
+ int _enableDrawingTimeSimulation;
+ uint32 _nextAllowedDrawTime;
+ static const uint _constantDrawDelay = 10; // ms
+ static const uint _proportionalDrawDelay = 500; // pixels per ms
+};
+
+} // End of namespace Mohawk
+
+#endif
diff --git a/engines/mohawk/myst_scripts.cpp b/engines/mohawk/myst_scripts.cpp
index ca8e985491..b9353312c7 100644
--- a/engines/mohawk/myst_scripts.cpp
+++ b/engines/mohawk/myst_scripts.cpp
@@ -22,8 +22,8 @@
#include "mohawk/cursors.h"
#include "mohawk/myst.h"
-#include "mohawk/graphics.h"
#include "mohawk/myst_areas.h"
+#include "mohawk/myst_graphics.h"
#include "mohawk/myst_scripts.h"
#include "mohawk/sound.h"
#include "mohawk/video.h"
diff --git a/engines/mohawk/myst_scripts.h b/engines/mohawk/myst_scripts.h
index 18f5b27a6d..ccb76e0dc8 100644
--- a/engines/mohawk/myst_scripts.h
+++ b/engines/mohawk/myst_scripts.h
@@ -143,7 +143,7 @@ protected:
const char *desc;
};
- Common::Array<MystOpcode*> _opcodes;
+ Common::Array<MystOpcode *> _opcodes;
MystResource *_invokingResource;
diff --git a/engines/mohawk/myst_stacks/channelwood.cpp b/engines/mohawk/myst_stacks/channelwood.cpp
index 9ca47cc92a..069281f5dc 100644
--- a/engines/mohawk/myst_stacks/channelwood.cpp
+++ b/engines/mohawk/myst_stacks/channelwood.cpp
@@ -22,8 +22,8 @@
#include "mohawk/cursors.h"
#include "mohawk/myst.h"
-#include "mohawk/graphics.h"
#include "mohawk/myst_areas.h"
+#include "mohawk/myst_graphics.h"
#include "mohawk/myst_state.h"
#include "mohawk/sound.h"
#include "mohawk/video.h"
diff --git a/engines/mohawk/myst_stacks/credits.cpp b/engines/mohawk/myst_stacks/credits.cpp
index ad593e3542..192e55d5e3 100644
--- a/engines/mohawk/myst_stacks/credits.cpp
+++ b/engines/mohawk/myst_stacks/credits.cpp
@@ -21,8 +21,8 @@
*/
#include "mohawk/myst.h"
-#include "mohawk/graphics.h"
#include "mohawk/myst_areas.h"
+#include "mohawk/myst_graphics.h"
#include "mohawk/sound.h"
#include "mohawk/video.h"
#include "mohawk/myst_stacks/credits.h"
diff --git a/engines/mohawk/myst_stacks/demo.cpp b/engines/mohawk/myst_stacks/demo.cpp
index fbad7dc384..29a12571fd 100644
--- a/engines/mohawk/myst_stacks/demo.cpp
+++ b/engines/mohawk/myst_stacks/demo.cpp
@@ -21,8 +21,8 @@
*/
#include "mohawk/cursors.h"
-#include "mohawk/graphics.h"
#include "mohawk/myst.h"
+#include "mohawk/myst_graphics.h"
#include "mohawk/myst_stacks/demo.h"
#include "common/system.h"
diff --git a/engines/mohawk/myst_stacks/intro.cpp b/engines/mohawk/myst_stacks/intro.cpp
index 7d3179fa24..0af386f51f 100644
--- a/engines/mohawk/myst_stacks/intro.cpp
+++ b/engines/mohawk/myst_stacks/intro.cpp
@@ -21,8 +21,8 @@
*/
#include "mohawk/myst.h"
-#include "mohawk/graphics.h"
#include "mohawk/myst_areas.h"
+#include "mohawk/myst_graphics.h"
#include "mohawk/myst_state.h"
#include "mohawk/sound.h"
#include "mohawk/video.h"
diff --git a/engines/mohawk/myst_stacks/mechanical.cpp b/engines/mohawk/myst_stacks/mechanical.cpp
index 12d9dc7e2f..79de03308c 100644
--- a/engines/mohawk/myst_stacks/mechanical.cpp
+++ b/engines/mohawk/myst_stacks/mechanical.cpp
@@ -22,8 +22,8 @@
#include "mohawk/cursors.h"
#include "mohawk/myst.h"
-#include "mohawk/graphics.h"
#include "mohawk/myst_areas.h"
+#include "mohawk/myst_graphics.h"
#include "mohawk/myst_state.h"
#include "mohawk/sound.h"
#include "mohawk/video.h"
diff --git a/engines/mohawk/myst_stacks/myst.cpp b/engines/mohawk/myst_stacks/myst.cpp
index b67b333a85..c1ddc74c82 100644
--- a/engines/mohawk/myst_stacks/myst.cpp
+++ b/engines/mohawk/myst_stacks/myst.cpp
@@ -22,8 +22,8 @@
#include "mohawk/cursors.h"
#include "mohawk/myst.h"
-#include "mohawk/graphics.h"
#include "mohawk/myst_areas.h"
+#include "mohawk/myst_graphics.h"
#include "mohawk/myst_state.h"
#include "mohawk/sound.h"
#include "mohawk/video.h"
@@ -2138,7 +2138,7 @@ void Myst::rocketSliderMove() {
}
uint16 Myst::rocketSliderGetSound(uint16 pos) {
- return (uint16)(9530 + (pos - 216) * 35.0 * 0.01639344262295082);
+ return (uint16)(9530 + (pos - 216) * 35.0 / 61.0);
}
void Myst::rocketCheckSolution() {
@@ -2978,15 +2978,17 @@ void Myst::clockReset() {
}
void Myst::clockResetWeight() {
- // Set video bounds, weight going up
+ _clockWeightVideo = _vm->_video->playMovie(_vm->wrapMovieFilename("cl1wlfch", kMystStack) , 124, 0);
+
if (!(_vm->getFeatures() & GF_ME)) {
- _clockWeightVideo = _vm->_video->playMovie(_vm->wrapMovieFilename("cl1wlfch", kMystStack) , 124, 0);
+ // Set video bounds, weight going up
_vm->_video->setVideoBounds(_clockWeightVideo,
Audio::Timestamp(0, 2214 * 2 - _clockWeightPosition, 600),
Audio::Timestamp(0, 2214 * 2, 600));
} else {
- //FIXME: Needs QT backwards playing
+ //FIXME: Needs QT backwards playing, for now just display the weight up
warning("Weight going back up not implemented");
+ _vm->_video->drawVideoFrame(_clockWeightVideo, Audio::Timestamp(0, 0, 600));
}
// Reset position
diff --git a/engines/mohawk/myst_stacks/preview.cpp b/engines/mohawk/myst_stacks/preview.cpp
index 31e22bb8c5..0b8dcf897a 100644
--- a/engines/mohawk/myst_stacks/preview.cpp
+++ b/engines/mohawk/myst_stacks/preview.cpp
@@ -22,8 +22,8 @@
#include "mohawk/cursors.h"
#include "mohawk/myst.h"
-#include "mohawk/graphics.h"
#include "mohawk/myst_areas.h"
+#include "mohawk/myst_graphics.h"
#include "mohawk/sound.h"
#include "mohawk/video.h"
#include "mohawk/myst_stacks/preview.h"
diff --git a/engines/mohawk/myst_stacks/slides.cpp b/engines/mohawk/myst_stacks/slides.cpp
index 794793e49c..c0bb400db1 100644
--- a/engines/mohawk/myst_stacks/slides.cpp
+++ b/engines/mohawk/myst_stacks/slides.cpp
@@ -22,8 +22,8 @@
#include "mohawk/cursors.h"
#include "mohawk/myst.h"
-#include "mohawk/graphics.h"
#include "mohawk/myst_areas.h"
+#include "mohawk/myst_graphics.h"
#include "mohawk/sound.h"
#include "mohawk/video.h"
#include "mohawk/myst_stacks/slides.h"
diff --git a/engines/mohawk/myst_stacks/stoneship.cpp b/engines/mohawk/myst_stacks/stoneship.cpp
index e0c374a926..ef228e62f3 100644
--- a/engines/mohawk/myst_stacks/stoneship.cpp
+++ b/engines/mohawk/myst_stacks/stoneship.cpp
@@ -22,8 +22,8 @@
#include "mohawk/cursors.h"
#include "mohawk/myst.h"
-#include "mohawk/graphics.h"
#include "mohawk/myst_areas.h"
+#include "mohawk/myst_graphics.h"
#include "mohawk/myst_state.h"
#include "mohawk/sound.h"
#include "mohawk/video.h"
@@ -623,7 +623,7 @@ void Stoneship::o_hologramSelectionMove(uint16 op, uint16 var, uint16 argc, uint
uint16 selectionPos = position * 1500 / 243;
VideoHandle handleMovie = _hologramSelection->playMovie();
- _vm->_video->setVideoBounds(handleMovie, Audio::Timestamp(0, selectionPos, 600), Audio::Timestamp(0, selectionPos, 600));
+ _vm->_video->drawVideoFrame(handleMovie, Audio::Timestamp(0, selectionPos, 600));
_hologramDisplayPos = position * 1450 / 243 + 350;
@@ -631,7 +631,7 @@ void Stoneship::o_hologramSelectionMove(uint16 op, uint16 var, uint16 argc, uint
if (_hologramTurnedOn) {
_hologramDisplay->setBlocking(false);
VideoHandle displayMovie = _hologramDisplay->playMovie();
- _vm->_video->setVideoBounds(displayMovie, Audio::Timestamp(0, _hologramDisplayPos, 600), Audio::Timestamp(0, _hologramDisplayPos, 600));
+ _vm->_video->drawVideoFrame(displayMovie, Audio::Timestamp(0, _hologramDisplayPos, 600));
}
}
}
@@ -655,7 +655,7 @@ void Stoneship::o_compassButton(uint16 op, uint16 var, uint16 argc, uint16 *argv
_state.generatorPowerAvailable = 2;
_state.lightState = 0;
_state.generatorDepletionTime = 0;
- _state.generatorDepletionTime = 0;
+ _state.generatorDuration = 0;
_batteryDepleting = false;
}
diff --git a/engines/mohawk/riven.cpp b/engines/mohawk/riven.cpp
index 3e2fa4f979..38b38d2c56 100644
--- a/engines/mohawk/riven.cpp
+++ b/engines/mohawk/riven.cpp
@@ -27,11 +27,11 @@
#include "common/system.h"
#include "mohawk/cursors.h"
-#include "mohawk/graphics.h"
#include "mohawk/installer_archive.h"
#include "mohawk/resource.h"
#include "mohawk/riven.h"
#include "mohawk/riven_external.h"
+#include "mohawk/riven_graphics.h"
#include "mohawk/riven_saveload.h"
#include "mohawk/dialogs.h"
#include "mohawk/sound.h"
diff --git a/engines/mohawk/riven_external.cpp b/engines/mohawk/riven_external.cpp
index 9e1365f8da..8dfc74ebf0 100644
--- a/engines/mohawk/riven_external.cpp
+++ b/engines/mohawk/riven_external.cpp
@@ -21,9 +21,9 @@
*/
#include "mohawk/cursors.h"
-#include "mohawk/graphics.h"
#include "mohawk/riven.h"
#include "mohawk/riven_external.h"
+#include "mohawk/riven_graphics.h"
#include "mohawk/sound.h"
#include "mohawk/video.h"
diff --git a/engines/mohawk/riven_external.h b/engines/mohawk/riven_external.h
index 5f5d0cb0b2..9f076325a2 100644
--- a/engines/mohawk/riven_external.h
+++ b/engines/mohawk/riven_external.h
@@ -53,7 +53,7 @@ private:
ExternalCmd proc;
};
- Common::Array<RivenExternalCmd*> _externalCommands;
+ Common::Array<RivenExternalCmd *> _externalCommands;
void setupCommands();
// Supplementary Functions
diff --git a/engines/mohawk/riven_graphics.cpp b/engines/mohawk/riven_graphics.cpp
new file mode 100644
index 0000000000..9415e51412
--- /dev/null
+++ b/engines/mohawk/riven_graphics.cpp
@@ -0,0 +1,445 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "mohawk/resource.h"
+#include "mohawk/riven.h"
+#include "mohawk/riven_graphics.h"
+
+#include "common/system.h"
+#include "engines/util.h"
+
+namespace Mohawk {
+
+RivenGraphics::RivenGraphics(MohawkEngine_Riven* vm) : GraphicsManager(), _vm(vm) {
+ _bitmapDecoder = new MohawkBitmap();
+
+ // Give me the best you've got!
+ initGraphics(608, 436, true, NULL);
+ _pixelFormat = _vm->_system->getScreenFormat();
+
+ if (_pixelFormat.bytesPerPixel == 1)
+ error("Riven requires greater than 256 colors to run");
+
+ // The actual game graphics only take up the first 392 rows. The inventory
+ // occupies the rest of the screen and we don't use the buffer to hold that.
+ _mainScreen = new Graphics::Surface();
+ _mainScreen->create(608, 392, _pixelFormat);
+
+ _updatesEnabled = true;
+ _scheduledTransition = -1; // no transition
+ _dirtyScreen = false;
+ _inventoryDrawn = false;
+
+ _creditsImage = 302;
+ _creditsPos = 0;
+}
+
+RivenGraphics::~RivenGraphics() {
+ _mainScreen->free();
+ delete _mainScreen;
+ delete _bitmapDecoder;
+}
+
+MohawkSurface *RivenGraphics::decodeImage(uint16 id) {
+ MohawkSurface *surface = _bitmapDecoder->decodeImage(_vm->getResource(ID_TBMP, id));
+ surface->convertToTrueColor();
+ return surface;
+}
+
+void RivenGraphics::copyImageToScreen(uint16 image, uint32 left, uint32 top, uint32 right, uint32 bottom) {
+ Graphics::Surface *surface = findImage(image)->getSurface();
+
+ // Clip the width to fit on the screen. Fixes some images.
+ if (left + surface->w > 608)
+ surface->w = 608 - left;
+
+ for (uint16 i = 0; i < surface->h; i++)
+ memcpy(_mainScreen->getBasePtr(left, i + top), surface->getBasePtr(0, i), surface->w * surface->format.bytesPerPixel);
+
+ _dirtyScreen = true;
+}
+
+void RivenGraphics::drawPLST(uint16 x) {
+ Common::SeekableReadStream* plst = _vm->getResource(ID_PLST, _vm->getCurCard());
+ uint16 recordCount = plst->readUint16BE();
+
+ for (uint16 i = 0; i < recordCount; i++) {
+ uint16 index = plst->readUint16BE();
+ uint16 id = plst->readUint16BE();
+ uint16 left = plst->readUint16BE();
+ uint16 top = plst->readUint16BE();
+ uint16 right = plst->readUint16BE();
+ uint16 bottom = plst->readUint16BE();
+
+ // We are also checking here to make sure we haven't drawn the image yet on screen.
+ // This fixes problems with drawing PLST 1 twice and some other images twice. PLST
+ // 1 is sometimes not called by the scripts, so some cards don't appear if we don't
+ // draw PLST 1 each time. This "hack" is here to catch any PLST attempting to draw
+ // twice. There should never be a problem with doing it this way.
+ if (index == x && !(Common::find(_activatedPLSTs.begin(), _activatedPLSTs.end(), x) != _activatedPLSTs.end())) {
+ debug(0, "Drawing image %d", id);
+ copyImageToScreen(id, left, top, right, bottom);
+ _activatedPLSTs.push_back(x);
+ break;
+ }
+ }
+
+ delete plst;
+}
+
+void RivenGraphics::updateScreen(Common::Rect updateRect) {
+ if (_updatesEnabled) {
+ _vm->runUpdateScreenScript();
+
+ if (_dirtyScreen) {
+ _activatedPLSTs.clear();
+
+ // Copy to screen if there's no transition. Otherwise transition. ;)
+ if (_scheduledTransition < 0)
+ _vm->_system->copyRectToScreen((byte *)_mainScreen->getBasePtr(updateRect.left, updateRect.top), _mainScreen->pitch, updateRect.left, updateRect.top, updateRect.width(), updateRect.height());
+ else
+ runScheduledTransition();
+
+ // Finally, update the screen.
+ _vm->_system->updateScreen();
+ _dirtyScreen = false;
+ }
+ }
+}
+
+void RivenGraphics::scheduleWaterEffect(uint16 sfxeID) {
+ Common::SeekableReadStream *sfxeStream = _vm->getResource(ID_SFXE, sfxeID);
+
+ if (sfxeStream->readUint16BE() != 'SL')
+ error ("Unknown sfxe tag");
+
+ // Read in header info
+ SFXERecord sfxeRecord;
+ sfxeRecord.frameCount = sfxeStream->readUint16BE();
+ uint32 offsetTablePosition = sfxeStream->readUint32BE();
+ sfxeRecord.rect.left = sfxeStream->readUint16BE();
+ sfxeRecord.rect.top = sfxeStream->readUint16BE();
+ sfxeRecord.rect.right = sfxeStream->readUint16BE();
+ sfxeRecord.rect.bottom = sfxeStream->readUint16BE();
+ sfxeRecord.speed = sfxeStream->readUint16BE();
+ // Skip the rest of the fields...
+
+ // Read in offsets
+ sfxeStream->seek(offsetTablePosition);
+ uint32 *frameOffsets = new uint32[sfxeRecord.frameCount];
+ for (uint16 i = 0; i < sfxeRecord.frameCount; i++)
+ frameOffsets[i] = sfxeStream->readUint32BE();
+ sfxeStream->seek(frameOffsets[0]);
+
+ // Read in the scripts
+ for (uint16 i = 0; i < sfxeRecord.frameCount; i++)
+ sfxeRecord.frameScripts.push_back(sfxeStream->readStream((i == sfxeRecord.frameCount - 1) ? sfxeStream->size() - frameOffsets[i] : frameOffsets[i + 1] - frameOffsets[i]));
+
+ // Set it to the first frame
+ sfxeRecord.curFrame = 0;
+ sfxeRecord.lastFrameTime = 0;
+
+ delete[] frameOffsets;
+ delete sfxeStream;
+ _waterEffects.push_back(sfxeRecord);
+}
+
+void RivenGraphics::clearWaterEffects() {
+ _waterEffects.clear();
+}
+
+bool RivenGraphics::runScheduledWaterEffects() {
+ // Don't run the effect if it's disabled
+ if (_vm->_vars["waterenabled"] == 0)
+ return false;
+
+ Graphics::Surface *screen = NULL;
+
+ for (uint16 i = 0; i < _waterEffects.size(); i++) {
+ if (_vm->_system->getMillis() > _waterEffects[i].lastFrameTime + 1000 / _waterEffects[i].speed) {
+ // Lock the screen!
+ if (!screen)
+ screen = _vm->_system->lockScreen();
+
+ // Make sure the script is at the starting point
+ Common::SeekableReadStream *script = _waterEffects[i].frameScripts[_waterEffects[i].curFrame];
+ if (script->pos() != 0)
+ script->seek(0);
+
+ // Run script
+ uint16 curRow = 0;
+ for (uint16 op = script->readUint16BE(); op != 4; op = script->readUint16BE()) {
+ if (op == 1) { // Increment Row
+ curRow++;
+ } else if (op == 3) { // Copy Pixels
+ uint16 dstLeft = script->readUint16BE();
+ uint16 srcLeft = script->readUint16BE();
+ uint16 srcTop = script->readUint16BE();
+ uint16 rowWidth = script->readUint16BE();
+ memcpy ((byte *)screen->getBasePtr(dstLeft, curRow + _waterEffects[i].rect.top), (byte *)_mainScreen->getBasePtr(srcLeft, srcTop), rowWidth * _pixelFormat.bytesPerPixel);
+ } else if (op != 4) { // End of Script
+ error ("Unknown SFXE opcode %d", op);
+ }
+ }
+
+ // Increment frame
+ _waterEffects[i].curFrame++;
+ if (_waterEffects[i].curFrame == _waterEffects[i].frameCount)
+ _waterEffects[i].curFrame = 0;
+
+ // Set the new time
+ _waterEffects[i].lastFrameTime = _vm->_system->getMillis();
+ }
+ }
+
+ // Unlock the screen if it has been locked and return true to update the screen
+ if (screen) {
+ _vm->_system->unlockScreen();
+ return true;
+ }
+
+ return false;
+}
+
+void RivenGraphics::scheduleTransition(uint16 id, Common::Rect rect) {
+ _scheduledTransition = id;
+ _transitionRect = rect;
+}
+
+void RivenGraphics::runScheduledTransition() {
+ if (_scheduledTransition < 0) // No transition is scheduled
+ return;
+
+ // TODO: There's a lot to be done here...
+
+ // Note: Transitions 0-11 are actual transitions, but none are used in-game.
+ // There's no point in implementing them if they're not used. These extra
+ // transitions were found by hacking scripts.
+
+ switch (_scheduledTransition) {
+ case 0: // Swipe Left
+ case 1: // Swipe Right
+ case 2: // Swipe Up
+ case 3: // Swipe Down
+ case 12: // Pan Left
+ case 13: // Pan Right
+ case 14: // Pan Up
+ case 15: // Pan Down
+ case 16: // Dissolve
+ case 17: // Dissolve (tspit CARD 155)
+ break;
+ default:
+ if (_scheduledTransition >= 4 && _scheduledTransition <= 11)
+ error("Found unused transition %d", _scheduledTransition);
+ else
+ error("Found unknown transition %d", _scheduledTransition);
+ }
+
+ // For now, just copy the image to screen without doing any transition.
+ _vm->_system->copyRectToScreen((byte *)_mainScreen->pixels, _mainScreen->pitch, 0, 0, _mainScreen->w, _mainScreen->h);
+ _vm->_system->updateScreen();
+
+ _scheduledTransition = -1; // Clear scheduled transition
+}
+
+void RivenGraphics::clearMainScreen() {
+ _mainScreen->fillRect(Common::Rect(0, 0, 608, 392), _pixelFormat.RGBToColor(0, 0, 0));
+}
+
+void RivenGraphics::fadeToBlack() {
+ // The transition speed is forced to best here
+ setTransitionSpeed(kRivenTransitionSpeedBest);
+ scheduleTransition(16);
+ clearMainScreen();
+ runScheduledTransition();
+}
+
+void RivenGraphics::showInventory() {
+ // Don't redraw the inventory
+ if (_inventoryDrawn)
+ return;
+
+ // Clear the inventory area
+ clearInventoryArea();
+
+ // Draw the demo's exit button
+ if (_vm->getFeatures() & GF_DEMO) {
+ // extras.mhk tBMP 101 contains "EXIT" instead of Atrus' journal in the demo!
+ // The demo's extras.mhk contains all the other inventory/marble/credits image
+ // but has hacked tBMP 101 with "EXIT". *sigh*
+ drawInventoryImage(101, g_demoExitRect);
+ } else {
+ // We don't want to show the inventory on setup screens or in other journals.
+ if (_vm->getCurStack() == aspit)
+ return;
+
+ // There are three books and three vars. We have three different
+ // combinations. At the start you have just Atrus' journal. Later,
+ // you get Catherine's journal and the trap book. Near the end,
+ // you lose the trap book and have just the two journals.
+
+ bool hasCathBook = _vm->_vars["acathbook"] != 0;
+ bool hasTrapBook = _vm->_vars["atrapbook"] != 0;
+
+ if (!hasCathBook) {
+ drawInventoryImage(101, g_atrusJournalRect1);
+ } else if (!hasTrapBook) {
+ drawInventoryImage(101, g_atrusJournalRect2);
+ drawInventoryImage(102, g_cathJournalRect2);
+ } else {
+ drawInventoryImage(101, g_atrusJournalRect3);
+ drawInventoryImage(102, g_cathJournalRect3);
+ drawInventoryImage(100, g_trapBookRect3);
+ }
+ }
+
+ _vm->_system->updateScreen();
+ _inventoryDrawn = true;
+}
+
+void RivenGraphics::hideInventory() {
+ // Don't hide the inventory twice
+ if (!_inventoryDrawn)
+ return;
+
+ // Clear the area
+ clearInventoryArea();
+
+ _inventoryDrawn = false;
+}
+
+void RivenGraphics::clearInventoryArea() {
+ // Clear the inventory area
+ static const Common::Rect inventoryRect = Common::Rect(0, 392, 608, 436);
+
+ // Lock the screen
+ Graphics::Surface *screen = _vm->_system->lockScreen();
+
+ // Fill the inventory area with black
+ screen->fillRect(inventoryRect, _pixelFormat.RGBToColor(0, 0, 0));
+
+ _vm->_system->unlockScreen();
+}
+
+void RivenGraphics::drawInventoryImage(uint16 id, const Common::Rect *rect) {
+ MohawkSurface *mhkSurface = _bitmapDecoder->decodeImage(_vm->getExtrasResource(ID_TBMP, id));
+ mhkSurface->convertToTrueColor();
+ Graphics::Surface *surface = mhkSurface->getSurface();
+
+ _vm->_system->copyRectToScreen((byte *)surface->pixels, surface->pitch, rect->left, rect->top, surface->w, surface->h);
+
+ delete mhkSurface;
+}
+
+void RivenGraphics::drawRect(Common::Rect rect, bool active) {
+ // Useful with debugging. Shows where hotspots are on the screen and whether or not they're active.
+ Graphics::Surface *screen = _vm->_system->lockScreen();
+
+ if (active)
+ screen->frameRect(rect, _pixelFormat.RGBToColor(0, 255, 0));
+ else
+ screen->frameRect(rect, _pixelFormat.RGBToColor(255, 0, 0));
+
+ _vm->_system->unlockScreen();
+}
+
+void RivenGraphics::drawImageRect(uint16 id, Common::Rect srcRect, Common::Rect dstRect) {
+ // Draw tBMP id from srcRect to dstRect
+ Graphics::Surface *surface = findImage(id)->getSurface();
+
+ assert(srcRect.width() == dstRect.width() && srcRect.height() == dstRect.height());
+
+ for (uint16 i = 0; i < srcRect.height(); i++)
+ memcpy(_mainScreen->getBasePtr(dstRect.left, i + dstRect.top), surface->getBasePtr(srcRect.left, i + srcRect.top), srcRect.width() * surface->format.bytesPerPixel);
+
+ _dirtyScreen = true;
+}
+
+void RivenGraphics::drawExtrasImage(uint16 id, Common::Rect dstRect) {
+ MohawkSurface *mhkSurface = _bitmapDecoder->decodeImage(_vm->getExtrasResource(ID_TBMP, id));
+ mhkSurface->convertToTrueColor();
+ Graphics::Surface *surface = mhkSurface->getSurface();
+
+ assert(dstRect.width() == surface->w);
+
+ for (uint16 i = 0; i < surface->h; i++)
+ memcpy(_mainScreen->getBasePtr(dstRect.left, i + dstRect.top), surface->getBasePtr(0, i), surface->pitch);
+
+ delete mhkSurface;
+ _dirtyScreen = true;
+}
+
+void RivenGraphics::beginCredits() {
+ // Clear the old cache
+ clearCache();
+
+ // Now cache all the credits images
+ for (uint16 i = 302; i <= 320; i++) {
+ MohawkSurface *surface = _bitmapDecoder->decodeImage(_vm->getExtrasResource(ID_TBMP, i));
+ surface->convertToTrueColor();
+ addImageToCache(i, surface);
+ }
+
+ // And clear our screen too
+ clearMainScreen();
+}
+
+void RivenGraphics::updateCredits() {
+ if ((_creditsImage == 303 || _creditsImage == 304) && _creditsPos == 0)
+ fadeToBlack();
+
+ if (_creditsImage < 304) {
+ // For the first two credit images, they are faded from black to the image and then out again
+ scheduleTransition(16);
+
+ Graphics::Surface *frame = findImage(_creditsImage++)->getSurface();
+
+ for (int y = 0; y < frame->h; y++)
+ memcpy(_mainScreen->getBasePtr(124, y), frame->getBasePtr(0, y), frame->pitch);
+
+ runScheduledTransition();
+ } else {
+ // Otheriwse, we're scrolling
+ // Move the screen up one row
+ memmove(_mainScreen->pixels, _mainScreen->getBasePtr(0, 1), _mainScreen->pitch * (_mainScreen->h - 1));
+
+ // Only update as long as we're not before the last frame
+ // Otherwise, we're just moving up a row (which we already did)
+ if (_creditsImage <= 320) {
+ // Copy the next row to the bottom of the screen
+ Graphics::Surface *frame = findImage(_creditsImage)->getSurface();
+ memcpy(_mainScreen->getBasePtr(124, _mainScreen->h - 1), frame->getBasePtr(0, _creditsPos), frame->pitch);
+ _creditsPos++;
+
+ if (_creditsPos == _mainScreen->h) {
+ _creditsImage++;
+ _creditsPos = 0;
+ }
+ }
+
+ // Now flush the new screen
+ _vm->_system->copyRectToScreen((byte *)_mainScreen->pixels, _mainScreen->pitch, 0, 0, _mainScreen->w, _mainScreen->h);
+ _vm->_system->updateScreen();
+ }
+}
+
+} // End of namespace Mohawk
diff --git a/engines/mohawk/riven_graphics.h b/engines/mohawk/riven_graphics.h
new file mode 100644
index 0000000000..48dda28afd
--- /dev/null
+++ b/engines/mohawk/riven_graphics.h
@@ -0,0 +1,110 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef MOHAWK_RIVEN_GRAPHICS_H
+#define MOHAWK_RIVEN_GRAPHICS_H
+
+#include "mohawk/graphics.h"
+
+namespace Mohawk {
+
+class MohawkEngine_Riven;
+
+class RivenGraphics : public GraphicsManager {
+public:
+ RivenGraphics(MohawkEngine_Riven *vm);
+ ~RivenGraphics();
+
+ void copyImageToScreen(uint16, uint32, uint32, uint32, uint32);
+ void updateScreen(Common::Rect updateRect = Common::Rect(0, 0, 608, 392));
+ bool _updatesEnabled;
+ Common::Array<uint16> _activatedPLSTs;
+ void drawPLST(uint16 x);
+ void drawRect(Common::Rect rect, bool active);
+ void drawImageRect(uint16 id, Common::Rect srcRect, Common::Rect dstRect);
+ void drawExtrasImage(uint16 id, Common::Rect dstRect);
+
+ // Water Effect
+ void scheduleWaterEffect(uint16);
+ void clearWaterEffects();
+ bool runScheduledWaterEffects();
+
+ // Transitions
+ void scheduleTransition(uint16 id, Common::Rect rect = Common::Rect(0, 0, 608, 392));
+ void runScheduledTransition();
+ void fadeToBlack();
+ void setTransitionSpeed(uint32 speed) { _transitionSpeed = speed; }
+
+ // Inventory
+ void showInventory();
+ void hideInventory();
+
+ // Credits
+ void beginCredits();
+ void updateCredits();
+ uint getCurCreditsImage() { return _creditsImage; }
+
+protected:
+ MohawkSurface *decodeImage(uint16 id);
+ MohawkEngine *getVM() { return (MohawkEngine *)_vm; }
+
+private:
+ MohawkEngine_Riven *_vm;
+ MohawkBitmap *_bitmapDecoder;
+
+ // Water Effects
+ struct SFXERecord {
+ // Record values
+ uint16 frameCount;
+ Common::Rect rect;
+ uint16 speed;
+ Common::Array<Common::SeekableReadStream *> frameScripts;
+
+ // Cur frame
+ uint16 curFrame;
+ uint32 lastFrameTime;
+ };
+ Common::Array<SFXERecord> _waterEffects;
+
+ // Transitions
+ int16 _scheduledTransition;
+ Common::Rect _transitionRect;
+ uint32 _transitionSpeed;
+
+ // Inventory
+ void clearInventoryArea();
+ void drawInventoryImage(uint16 id, const Common::Rect *rect);
+ bool _inventoryDrawn;
+
+ // Screen Related
+ Graphics::Surface *_mainScreen;
+ bool _dirtyScreen;
+ Graphics::PixelFormat _pixelFormat;
+ void clearMainScreen();
+
+ // Credits
+ uint _creditsImage, _creditsPos;
+};
+
+} // End of namespace Mohawk
+
+#endif
diff --git a/engines/mohawk/riven_scripts.cpp b/engines/mohawk/riven_scripts.cpp
index 6e3e9a34dc..352a018990 100644
--- a/engines/mohawk/riven_scripts.cpp
+++ b/engines/mohawk/riven_scripts.cpp
@@ -21,9 +21,9 @@
*/
#include "mohawk/cursors.h"
-#include "mohawk/graphics.h"
#include "mohawk/riven.h"
#include "mohawk/riven_external.h"
+#include "mohawk/riven_graphics.h"
#include "mohawk/riven_scripts.h"
#include "mohawk/sound.h"
#include "mohawk/video.h"
diff --git a/engines/mohawk/riven_scripts.h b/engines/mohawk/riven_scripts.h
index 2932ba5939..6df4a2e523 100644
--- a/engines/mohawk/riven_scripts.h
+++ b/engines/mohawk/riven_scripts.h
@@ -27,8 +27,6 @@
#include "common/ptr.h"
#include "common/textconsole.h"
-class MohawkEngine_Riven;
-
#define DECLARE_OPCODE(x) void x(uint16 op, uint16 argc, uint16 *argv)
namespace Mohawk {
@@ -50,6 +48,7 @@ enum {
kStoredOpcodeScript // This is ScummVM-only to denote the script from a storeMovieOpcode() call
};
+class MohawkEngine_Riven;
class RivenScript;
class RivenScript {
@@ -125,7 +124,7 @@ private:
DECLARE_OPCODE(activateMLST);
};
-typedef Common::Array<RivenScript*> RivenScriptList;
+typedef Common::Array<RivenScript *> RivenScriptList;
class RivenScriptManager {
public:
diff --git a/engines/mohawk/video.cpp b/engines/mohawk/video.cpp
index cd8fc8ef80..8d72fa3f72 100644
--- a/engines/mohawk/video.cpp
+++ b/engines/mohawk/video.cpp
@@ -261,7 +261,7 @@ bool VideoManager::updateMovies() {
// Clip the width/height to make sure we stay on the screen (Myst does this a few times)
uint16 width = MIN<int32>(_videoStreams[i]->getWidth(), _vm->_system->getWidth() - _videoStreams[i].x);
uint16 height = MIN<int32>(_videoStreams[i]->getHeight(), _vm->_system->getHeight() - _videoStreams[i].y);
- _vm->_system->copyRectToScreen((byte*)frame->pixels, frame->pitch, _videoStreams[i].x, _videoStreams[i].y, width, height);
+ _vm->_system->copyRectToScreen((byte *)frame->pixels, frame->pitch, _videoStreams[i].x, _videoStreams[i].y, width, height);
// We've drawn something to the screen, make sure we update it
updateScreen = true;
@@ -529,6 +529,15 @@ void VideoManager::setVideoBounds(VideoHandle handle, Audio::Timestamp start, Au
_videoStreams[handle]->seekToTime(start);
}
+void VideoManager::drawVideoFrame(VideoHandle handle, Audio::Timestamp time) {
+ assert(handle != NULL_VID_HANDLE);
+ _videoStreams[handle].end = Audio::Timestamp(0xffffffff, 1);
+ _videoStreams[handle]->seekToTime(time);
+ updateMovies();
+ delete _videoStreams[handle].video;
+ _videoStreams[handle].clear();
+}
+
void VideoManager::seekToTime(VideoHandle handle, Audio::Timestamp time) {
assert(handle != NULL_VID_HANDLE);
_videoStreams[handle]->seekToTime(time);
diff --git a/engines/mohawk/video.h b/engines/mohawk/video.h
index efa81edfbd..34c287497f 100644
--- a/engines/mohawk/video.h
+++ b/engines/mohawk/video.h
@@ -104,6 +104,7 @@ public:
uint32 getDuration(VideoHandle videoHandle);
bool endOfVideo(VideoHandle handle);
void setVideoBounds(VideoHandle handle, Audio::Timestamp start, Audio::Timestamp end);
+ void drawVideoFrame(VideoHandle handle, Audio::Timestamp time);
void seekToTime(VideoHandle handle, Audio::Timestamp time);
void setVideoLooping(VideoHandle handle, bool loop);
void waitUntilMovieEnds(VideoHandle videoHandle);
diff --git a/engines/neverhood/blbarchive.cpp b/engines/neverhood/blbarchive.cpp
index 6a047cab46..4e138b01a2 100644
--- a/engines/neverhood/blbarchive.cpp
+++ b/engines/neverhood/blbarchive.cpp
@@ -110,7 +110,7 @@ byte *BlbArchive::getEntryExtData(uint index) {
Common::SeekableReadStream *BlbArchive::createStream(uint index) {
const BlbArchiveEntry &entry = _entries[index];
- return new Common::SafeSubReadStream(&_fd, entry.offset, entry.offset + entry.diskSize);
+ return new Common::SafeSeekableSubReadStream(&_fd, entry.offset, entry.offset + entry.diskSize);
}
} // End of namespace Neverhood
diff --git a/engines/parallaction/balloons.cpp b/engines/parallaction/balloons.cpp
index f74eef18e1..1ddd401b20 100644
--- a/engines/parallaction/balloons.cpp
+++ b/engines/parallaction/balloons.cpp
@@ -179,7 +179,7 @@ protected:
uint16 rx = 10;
uint16 ry = 4 + _lines * _font->height(); // y
- byte *dst = (byte*)_surf->getBasePtr(rx, ry);
+ byte *dst = (byte *)_surf->getBasePtr(rx, ry);
_font->setColor(_color);
_font->drawString(dst, _surf->w, _line.c_str());
}
@@ -494,7 +494,7 @@ protected:
uint16 rx = _x + (_surf->w - _lineWidth) / 2;
uint16 ry = _y + _lines * _font->height(); // y
- byte *dst = (byte*)_surf->getBasePtr(rx, ry);
+ byte *dst = (byte *)_surf->getBasePtr(rx, ry);
_font->setColor(_color);
_font->drawString(dst, _surf->w, _line.c_str());
}
diff --git a/engines/parallaction/callables_br.cpp b/engines/parallaction/callables_br.cpp
index ac5ff88560..7d3e63dfba 100644
--- a/engines/parallaction/callables_br.cpp
+++ b/engines/parallaction/callables_br.cpp
@@ -26,31 +26,31 @@
namespace Parallaction {
-void Parallaction_br::_c_null(void*) {
+void Parallaction_br::_c_null(void *) {
// do nothing :)
}
-void Parallaction_br::_c_blufade(void*) {
+void Parallaction_br::_c_blufade(void *) {
warning("Parallaction_br::_c_blufade() not yet implemented");
}
-void Parallaction_br::_c_resetpalette(void*) {
+void Parallaction_br::_c_resetpalette(void *) {
warning("Parallaction_br::_c_resetpalette() not yet implemented");
}
-void Parallaction_br::_c_ferrcycle(void*) {
+void Parallaction_br::_c_ferrcycle(void *) {
warning("Parallaction_br::_c_ferrcycle() not yet implemented");
}
-void Parallaction_br::_c_lipsinc(void*) {
+void Parallaction_br::_c_lipsinc(void *) {
warning("Unexpected lipsinc routine call! Please notify the team");
}
-void Parallaction_br::_c_albcycle(void*) {
+void Parallaction_br::_c_albcycle(void *) {
warning("Parallaction_br::_c_albcycle() not yet implemented");
}
-void Parallaction_br::_c_password(void*) {
+void Parallaction_br::_c_password(void *) {
warning("Parallaction_br::_c_password() not yet implemented");
}
diff --git a/engines/parallaction/callables_ns.cpp b/engines/parallaction/callables_ns.cpp
index 77f54fcc98..64885c7ff3 100644
--- a/engines/parallaction/callables_ns.cpp
+++ b/engines/parallaction/callables_ns.cpp
@@ -260,7 +260,7 @@ void Parallaction_ns::stopMovingSarcophagus() {
void Parallaction_ns::_c_moveSarc(void *parm) {
if (!_movingSarcophagus) {
- startMovingSarcophagus(*(ZonePtr*)parm);
+ startMovingSarcophagus(*(ZonePtr *)parm);
} else {
stopMovingSarcophagus();
}
@@ -417,18 +417,18 @@ void Parallaction_ns::_c_testResult(void *parm) {
return;
}
-void Parallaction_ns::_c_offSound(void*) {
+void Parallaction_ns::_c_offSound(void *) {
_soundManI->stopSfx(0);
_soundManI->stopSfx(1);
_soundManI->stopSfx(2);
_soundManI->stopSfx(3);
}
-void Parallaction_ns::_c_startMusic(void*) {
+void Parallaction_ns::_c_startMusic(void *) {
_soundManI->playMusic();
}
-void Parallaction_ns::_c_closeMusic(void*) {
+void Parallaction_ns::_c_closeMusic(void *) {
_soundManI->stopMusic();
}
@@ -490,7 +490,7 @@ void Parallaction_ns::_c_moveSheet(void *parm) {
}
void zeroMask(int x, int y, int color, void *data) {
- BackgroundInfo *info = (BackgroundInfo*)data;
+ BackgroundInfo *info = (BackgroundInfo *)data;
uint16 _ax = x + y * info->_mask->w;
info->_mask->data[_ax >> 2] &= ~(3 << ((_ax & 3) << 1));
@@ -575,16 +575,16 @@ int16 projectorProgram[] = {
25, 116, 25, 115, 25, 114, 25, 113, 25, 112, 25, 111, 25, 110, 25, -1, -1
};
-void Parallaction_ns::_c_projector(void*) {
+void Parallaction_ns::_c_projector(void *) {
_gfx->setHalfbriteMode(true);
_gfx->setProjectorProgram(projectorProgram);
}
-void Parallaction_ns::_c_HBOff(void*) {
+void Parallaction_ns::_c_HBOff(void *) {
_gfx->setHalfbriteMode(false);
}
-void Parallaction_ns::_c_HBOn(void*) {
+void Parallaction_ns::_c_HBOn(void *) {
_gfx->setHalfbriteMode(true);
}
diff --git a/engines/parallaction/debug.cpp b/engines/parallaction/debug.cpp
index 72f26cb6b9..0cb329e0f0 100644
--- a/engines/parallaction/debug.cpp
+++ b/engines/parallaction/debug.cpp
@@ -69,14 +69,14 @@ bool Debugger::Cmd_Location(int argc, const char **argv) {
switch (argc) {
case 3:
- character = const_cast<char*>(argv[2]);
- location = const_cast<char*>(argv[1]);
+ character = const_cast<char *>(argv[2]);
+ location = const_cast<char *>(argv[1]);
sprintf(tmp, "%s.%s", location, character);
_vm->scheduleLocationSwitch(tmp);
break;
case 2:
- location = const_cast<char*>(argv[1]);
+ location = const_cast<char *>(argv[1]);
_vm->scheduleLocationSwitch(location);
break;
diff --git a/engines/parallaction/dialogue.cpp b/engines/parallaction/dialogue.cpp
index a908152bf8..e0bd6a6677 100644
--- a/engines/parallaction/dialogue.cpp
+++ b/engines/parallaction/dialogue.cpp
@@ -381,7 +381,7 @@ protected:
}
void accumPassword(uint16 ascii) {
- if (!isdigit(ascii)) {
+ if (!Common::isDigit(ascii)) {
return;
}
diff --git a/engines/parallaction/disk.cpp b/engines/parallaction/disk.cpp
index 61172d0896..f20e05771a 100644
--- a/engines/parallaction/disk.cpp
+++ b/engines/parallaction/disk.cpp
@@ -38,7 +38,7 @@ void ILBMLoader::setupBuffer(uint32 w, uint32 h) {
}
_surf->create(w, h, Graphics::PixelFormat::createFormatCLUT8());
_mode = Graphics::ILBMDecoder::ILBM_UNPACK_PLANES;
- _intBuffer = (byte*)_surf->pixels;
+ _intBuffer = (byte *)_surf->pixels;
break;
case BODYMODE_MASKBUFFER:
@@ -82,7 +82,7 @@ bool ILBMLoader::callback(Common::IFFChunk &chunk) {
case ID_CRNG:
if (_crng) {
PaletteFxRange *ptr = &_crng[_numCRNG];
- chunk._stream->read((byte*)ptr, chunk._size);
+ chunk._stream->read((byte *)ptr, chunk._size);
ptr->_timer = FROM_BE_16(ptr->_timer);
ptr->_step = FROM_BE_16(ptr->_step);
ptr->_flags = FROM_BE_16(ptr->_flags);
diff --git a/engines/parallaction/disk_br.cpp b/engines/parallaction/disk_br.cpp
index f9e368ab39..5e39c893db 100644
--- a/engines/parallaction/disk_br.cpp
+++ b/engines/parallaction/disk_br.cpp
@@ -283,7 +283,7 @@ Sprites* DosDisk_br::createSprites(Common::ReadStream *stream) {
spr->w = stream->readUint16LE();
spr->h = stream->readUint16LE();
- spr->packedData = (byte*)malloc(spr->size);
+ spr->packedData = (byte *)malloc(spr->size);
stream->read(spr->packedData, spr->size);
}
delete stream;
@@ -450,7 +450,7 @@ void AmigaDisk_br::init() {
void AmigaDisk_br::adjustForPalette(Graphics::Surface &surf, int transparentColor) {
uint size = surf.w * surf.h;
- byte *data = (byte*)surf.pixels;
+ byte *data = (byte *)surf.pixels;
for (uint i = 0; i < size; i++, data++) {
if (transparentColor == -1 || transparentColor != *data)
*data += 16;
@@ -609,7 +609,7 @@ GfxObj* AmigaDisk_br::loadStatic(const char* name) {
stream->read(shadow, shadowSize);
for (int32 i = 0; i < surf->h; ++i) {
byte *src = shadow + shadowWidth * i;
- byte *dst = (byte*)surf->pixels + surf->pitch * i;
+ byte *dst = (byte *)surf->pixels + surf->pitch * i;
for (int32 j = 0; j < surf->w; ++j, ++dst) {
byte bit = src[j/8] & (1 << (7 - (j & 7)));
@@ -637,7 +637,7 @@ Sprites* AmigaDisk_br::createSprites(Common::ReadStream *stream) {
spr->w = stream->readUint16BE();
spr->h = stream->readUint16BE() - 1;
- spr->packedData = (byte*)malloc(spr->size);
+ spr->packedData = (byte *)malloc(spr->size);
stream->read(spr->packedData, spr->size);
}
@@ -725,7 +725,7 @@ GfxObj* AmigaDisk_br::loadObjects(const char *name, uint8 part) {
max = 72;
byte *data = new byte[max * 2601];
- byte *srcPtr = (byte*)loader._surf->getBasePtr(0,0);
+ byte *srcPtr = (byte *)loader._surf->getBasePtr(0,0);
int w = loader._surf->w;
// Convert to the expected display format
diff --git a/engines/parallaction/disk_ns.cpp b/engines/parallaction/disk_ns.cpp
index 05ea60f510..b2285d0da3 100644
--- a/engines/parallaction/disk_ns.cpp
+++ b/engines/parallaction/disk_ns.cpp
@@ -73,9 +73,9 @@ public:
~NSArchive();
Common::SeekableReadStream *createReadStreamForMember(const Common::String &name) const;
- bool hasFile(const Common::String &name);
- int listMembers(Common::ArchiveMemberList &list);
- Common::ArchiveMemberPtr getMember(const Common::String &name);
+ bool hasFile(const Common::String &name) const;
+ int listMembers(Common::ArchiveMemberList &list) const;
+ const Common::ArchiveMemberPtr getMember(const Common::String &name) const;
};
@@ -137,23 +137,23 @@ Common::SeekableReadStream *NSArchive::createReadStreamForMember(const Common::S
return new Common::SeekableSubReadStream(_stream, offset, endOffset, DisposeAfterUse::NO);
}
-bool NSArchive::hasFile(const Common::String &name) {
+bool NSArchive::hasFile(const Common::String &name) const {
if (name.empty())
return false;
return lookup(name.c_str()) != _numFiles;
}
-int NSArchive::listMembers(Common::ArchiveMemberList &list) {
+int NSArchive::listMembers(Common::ArchiveMemberList &list) const {
for (uint32 i = 0; i < _numFiles; i++) {
list.push_back(Common::SharedPtr<Common::GenericArchiveMember>(new Common::GenericArchiveMember(_archiveDir[i], this)));
}
return _numFiles;
}
-Common::ArchiveMemberPtr NSArchive::getMember(const Common::String &name) {
+const Common::ArchiveMemberPtr NSArchive::getMember(const Common::String &name) const {
uint32 index = lookup(name.c_str());
- char *item = 0;
+ const char *item = 0;
if (index < _numFiles) {
item = _archiveDir[index];
}
@@ -473,7 +473,7 @@ void DosDisk_ns::loadBackground(BackgroundInfo& info, const char *filename) {
// read bitmap, mask and path data and extract them into the 3 buffers
info.bg.create(info.width, info.height, Graphics::PixelFormat::createFormatCLUT8());
createMaskAndPathBuffers(info);
- unpackBackground(stream, (byte*)info.bg.pixels, info._mask->data, info._path->data);
+ unpackBackground(stream, (byte *)info.bg.pixels, info._mask->data, info._path->data);
delete stream;
}
@@ -661,10 +661,10 @@ public:
stream.seek(-4, SEEK_END);
uint32 decrlen = stream.readUint32BE() >> 8;
- byte *dest = (byte*)malloc(decrlen);
+ byte *dest = (byte *)malloc(decrlen);
uint32 crlen = stream.size() - 4;
- byte *src = (byte*)malloc(crlen);
+ byte *src = (byte *)malloc(crlen);
stream.seek(4, SEEK_SET);
stream.read(src, crlen);
@@ -757,14 +757,14 @@ void AmigaDisk_ns::unpackFrame(byte *dst, byte *src, uint16 planeSize) {
*/
void AmigaDisk_ns::patchFrame(byte *dst, byte *dlta, uint16 bytesPerPlane, uint16 height) {
- uint32 *dataIndex = (uint32*)dlta;
- uint32 *ofslenIndex = (uint32*)dlta + 8;
+ uint32 *dataIndex = (uint32 *)dlta;
+ uint32 *ofslenIndex = (uint32 *)dlta + 8;
- uint16 *base = (uint16*)dlta;
+ uint16 *base = (uint16 *)dlta;
uint16 wordsPerLine = bytesPerPlane >> 1;
for (uint j = 0; j < NUM_PLANES; j++) {
- uint16 *dst16 = (uint16*)(dst + j * bytesPerPlane * height);
+ uint16 *dst16 = (uint16 *)(dst + j * bytesPerPlane * height);
uint16 *data = base + READ_BE_UINT32(dataIndex);
dataIndex++;
@@ -804,7 +804,7 @@ void AmigaDisk_ns::unpackBitmap(byte *dst, byte *src, uint16 numFrames, uint16 b
uint size = READ_BE_UINT32(src + 4);
if (tempBuffer == 0)
- tempBuffer = (byte*)malloc(planeSize * NUM_PLANES);
+ tempBuffer = (byte *)malloc(planeSize * NUM_PLANES);
memcpy(tempBuffer, baseFrame, planeSize * NUM_PLANES);
diff --git a/engines/parallaction/exec.h b/engines/parallaction/exec.h
index 4ca3947514..b966d677cd 100644
--- a/engines/parallaction/exec.h
+++ b/engines/parallaction/exec.h
@@ -55,7 +55,7 @@ struct CommandContext {
// in Parallaction_XX
};
typedef Common::Functor1<CommandContext&, void> CommandOpcode;
-typedef Common::Array<const CommandOpcode*> CommandOpcodeSet;
+typedef Common::Array<const CommandOpcode *> CommandOpcodeSet;
#define DECLARE_UNQUALIFIED_COMMAND_OPCODE(op) void cmdOp_##op(CommandContext &)
struct ProgramContext {
@@ -67,11 +67,11 @@ struct ProgramContext {
bool _suspend;
};
typedef Common::Functor1<ProgramContext&, void> ProgramOpcode;
-typedef Common::Array<const ProgramOpcode*> ProgramOpcodeSet;
+typedef Common::Array<const ProgramOpcode *> ProgramOpcodeSet;
#define DECLARE_UNQUALIFIED_INSTRUCTION_OPCODE(op) void instOp_##op(ProgramContext &)
-template <class OpcodeSet>
+template<class OpcodeSet>
class Exec {
protected:
OpcodeSet _opcodes;
diff --git a/engines/parallaction/font.cpp b/engines/parallaction/font.cpp
index cc7f320e1c..d4c9aefd32 100644
--- a/engines/parallaction/font.cpp
+++ b/engines/parallaction/font.cpp
@@ -57,17 +57,17 @@ public:
_numGlyphs = stream.readByte();
_height = stream.readUint32BE();
- _widths = (byte*)malloc(_numGlyphs);
+ _widths = (byte *)malloc(_numGlyphs);
stream.read(_widths, _numGlyphs);
- _offsets = (uint*)malloc(_numGlyphs * sizeof(uint));
+ _offsets = (uint *)malloc(_numGlyphs * sizeof(uint));
_offsets[0] = 0;
for (uint i = 1; i < _numGlyphs; i++)
_offsets[i] = _offsets[i-1] + _widths[i-1] * _height;
uint size = _offsets[_numGlyphs-1] + _widths[_numGlyphs-1] * _height;
- _data = (byte*)malloc(size);
+ _data = (byte *)malloc(size);
stream.read(_data, size);
}
@@ -503,25 +503,25 @@ AmigaFont::AmigaFont(Common::SeekableReadStream &stream) {
stream.seek(32); // skips dummy header
_dataSize = stream.size() - stream.pos();
- _data = (byte*)malloc(_dataSize);
+ _data = (byte *)malloc(_dataSize);
stream.read(_data, _dataSize);
- _font = (AmigaDiskFont*)(_data + 78);
+ _font = (AmigaDiskFont *)(_data + 78);
_font->_ySize = FROM_BE_16(_font->_ySize);
_font->_xSize = FROM_BE_16(_font->_xSize);
_font->_baseline = FROM_BE_16(_font->_baseline);
_font->_modulo = FROM_BE_16(_font->_modulo);
- _charLoc = (CharLoc*)(_data + FROM_BE_32(_font->_charLoc));
+ _charLoc = (CharLoc *)(_data + FROM_BE_32(_font->_charLoc));
_charData = _data + FROM_BE_32(_font->_charData);
_charSpace = 0;
_charKern = 0;
if (_font->_charSpace != 0)
- _charSpace = (uint16*)(_data + FROM_BE_32(_font->_charSpace));
+ _charSpace = (uint16 *)(_data + FROM_BE_32(_font->_charSpace));
if (_font->_charKern != 0)
- _charKern = (uint16*)(_data + FROM_BE_32(_font->_charKern));
+ _charKern = (uint16 *)(_data + FROM_BE_32(_font->_charKern));
}
diff --git a/engines/parallaction/gfxbase.cpp b/engines/parallaction/gfxbase.cpp
index c351551e36..852235ce34 100644
--- a/engines/parallaction/gfxbase.cpp
+++ b/engines/parallaction/gfxbase.cpp
@@ -235,7 +235,7 @@ void Gfx::drawGfxObject(GfxObj *obj, Graphics::Surface &surf) {
}
void Gfx::drawText(Font *font, Graphics::Surface* surf, uint16 x, uint16 y, const char *text, byte color) {
- byte *dst = (byte*)surf->getBasePtr(x, y);
+ byte *dst = (byte *)surf->getBasePtr(x, y);
font->setColor(color);
font->drawString(dst, surf->w, text);
}
@@ -308,7 +308,7 @@ void Gfx::bltMaskScale(const Common::Rect& r, byte *data, Graphics::Surface *sur
dp.y = dstRect.top;
byte *s = data + srcRect.left + srcRect.top * width;
- byte *d = (byte*)surf->getBasePtr(dp.x, dp.y);
+ byte *d = (byte *)surf->getBasePtr(dp.x, dp.y);
uint line = 0, col = 0;
@@ -380,7 +380,7 @@ void Gfx::bltMaskNoScale(const Common::Rect& r, byte *data, Graphics::Surface *s
q.translate(-r.left, -r.top);
byte *s = data + q.left + q.top * r.width();
- byte *d = (byte*)surf->getBasePtr(dp.x, dp.y);
+ byte *d = (byte *)surf->getBasePtr(dp.x, dp.y);
uint sPitch = r.width() - q.width();
uint dPitch = surf->w - q.width();
@@ -422,7 +422,7 @@ void Gfx::bltNoMaskNoScale(const Common::Rect& r, byte *data, Graphics::Surface
q.translate(-r.left, -r.top);
byte *s = data + q.left + q.top * r.width();
- byte *d = (byte*)surf->getBasePtr(dp.x, dp.y);
+ byte *d = (byte *)surf->getBasePtr(dp.x, dp.y);
uint sPitch = r.width() - q.width();
uint dPitch = surf->w - q.width();
diff --git a/engines/parallaction/graphics.cpp b/engines/parallaction/graphics.cpp
index 1da61b68ae..6868505c52 100644
--- a/engines/parallaction/graphics.cpp
+++ b/engines/parallaction/graphics.cpp
@@ -44,7 +44,7 @@ namespace Parallaction {
void halfbritePixel(int x, int y, int color, void *data) {
Graphics::Surface *surf = (Graphics::Surface *)data;
- byte *pixel = (byte*)surf->getBasePtr(x, y);
+ byte *pixel = (byte *)surf->getBasePtr(x, y);
*pixel &= ~0x20;
}
@@ -319,7 +319,7 @@ void Gfx::copyRectToScreen(const byte *buf, int pitch, int x, int y, int w, int
y += _scrollPosY;
}
- byte *dst = (byte*)_backBuffer.getBasePtr(x, y);
+ byte *dst = (byte *)_backBuffer.getBasePtr(x, y);
for (int i = 0; i < h; i++) {
memcpy(dst, buf, w);
buf += pitch;
@@ -357,7 +357,7 @@ void Gfx::unlockScreen() {
void Gfx::updateScreenIntern() {
if (_doubleBuffering) {
- byte *data = (byte*)_backBuffer.getBasePtr(_scrollPosX, _scrollPosY);
+ byte *data = (byte *)_backBuffer.getBasePtr(_scrollPosX, _scrollPosY);
_vm->_system->copyRectToScreen(data, _backBuffer.pitch, 0, 0, _vm->_screenWidth, _vm->_screenHeight);
}
@@ -425,7 +425,7 @@ void Gfx::updateScreen() {
// background may not cover the whole screen, so adjust bulk update size
uint w = _backgroundInfo->width;
uint h = _backgroundInfo->height;
- byte *backgroundData = (byte*)_backgroundInfo->bg.getBasePtr(0, 0);
+ byte *backgroundData = (byte *)_backgroundInfo->bg.getBasePtr(0, 0);
uint16 backgroundPitch = _backgroundInfo->bg.pitch;
copyRectToScreen(backgroundData, backgroundPitch, _backgroundInfo->_x, _backgroundInfo->_y, w, h);
}
@@ -450,7 +450,7 @@ void Gfx::applyHalfbriteEffect_NS(Graphics::Surface &surf) {
return;
}
- byte *buf = (byte*)surf.pixels;
+ byte *buf = (byte *)surf.pixels;
for (int i = 0; i < surf.w*surf.h; i++) {
*buf++ |= 0x20;
}
@@ -493,7 +493,7 @@ void Gfx::patchBackground(Graphics::Surface &surf, int16 x, int16 y, bool mask)
r.moveTo(x, y);
uint16 z = (mask) ? _backgroundInfo->getMaskLayer(y) : LAYER_FOREGROUND;
- blt(r, (byte*)surf.pixels, &_backgroundInfo->bg, z, 100, 0);
+ blt(r, (byte *)surf.pixels, &_backgroundInfo->bg, z, 100, 0);
}
void Gfx::fillBackground(const Common::Rect& r, byte color) {
@@ -502,7 +502,7 @@ void Gfx::fillBackground(const Common::Rect& r, byte color) {
void Gfx::invertBackground(const Common::Rect& r) {
- byte *d = (byte*)_backgroundInfo->bg.getBasePtr(r.left, r.top);
+ byte *d = (byte *)_backgroundInfo->bg.getBasePtr(r.left, r.top);
for (int i = 0; i < r.height(); i++) {
for (int j = 0; j < r.width(); j++) {
@@ -536,12 +536,12 @@ GfxObj *Gfx::renderFloatingLabel(Font *font, char *text) {
setupLabelSurface(*cnv, w, h);
font->setColor((_gameType == GType_BRA) ? 0 : 7);
- font->drawString((byte*)cnv->pixels + 1, cnv->w, text);
- font->drawString((byte*)cnv->pixels + 1 + cnv->w * 2, cnv->w, text);
- font->drawString((byte*)cnv->pixels + cnv->w, cnv->w, text);
- font->drawString((byte*)cnv->pixels + 2 + cnv->w, cnv->w, text);
+ font->drawString((byte *)cnv->pixels + 1, cnv->w, text);
+ font->drawString((byte *)cnv->pixels + 1 + cnv->w * 2, cnv->w, text);
+ font->drawString((byte *)cnv->pixels + cnv->w, cnv->w, text);
+ font->drawString((byte *)cnv->pixels + 2 + cnv->w, cnv->w, text);
font->setColor((_gameType == GType_BRA) ? 11 : 1);
- font->drawString((byte*)cnv->pixels + 1 + cnv->w, cnv->w, text);
+ font->drawString((byte *)cnv->pixels + 1 + cnv->w, cnv->w, text);
} else {
w = font->getStringWidth(text);
h = font->height();
@@ -596,20 +596,22 @@ void Gfx::updateFloatingLabel() {
Common::Rect r;
_floatingLabel->getRect(0, r);
+ FloatingLabelTraits traits_NS = {
+ Common::Point(16 - r.width()/2, 34),
+ Common::Point(8 - r.width()/2, 21),
+ 0, 0, _vm->_screenWidth - r.width(), 190
+ };
+
+ // FIXME: _maxY for BRA is not constant (390), but depends on _vm->_subtitleY
+ FloatingLabelTraits traits_BR = {
+ Common::Point(34 - r.width()/2, 70),
+ Common::Point(16 - r.width()/2, 37),
+ 0, 0, _vm->_screenWidth - r.width(), 390
+ };
+
if (_gameType == GType_Nippon) {
- FloatingLabelTraits traits_NS = {
- Common::Point(16 - r.width()/2, 34),
- Common::Point(8 - r.width()/2, 21),
- 0, 0, _vm->_screenWidth - r.width(), 190
- };
traits = &traits_NS;
} else {
- // FIXME: _maxY for BRA is not constant (390), but depends on _vm->_subtitleY
- FloatingLabelTraits traits_BR = {
- Common::Point(34 - r.width()/2, 70),
- Common::Point(16 - r.width()/2, 37),
- 0, 0, _vm->_screenWidth - r.width(), 390
- };
traits = &traits_BR;
}
@@ -701,8 +703,8 @@ void Gfx::unregisterLabel(GfxObj *label) {
void Gfx::copyRect(const Common::Rect &r, Graphics::Surface &src, Graphics::Surface &dst) {
- byte *s = (byte*)src.getBasePtr(r.left, r.top);
- byte *d = (byte*)dst.getBasePtr(0, 0);
+ byte *s = (byte *)src.getBasePtr(r.left, r.top);
+ byte *d = (byte *)dst.getBasePtr(0, 0);
for (uint16 i = 0; i < r.height(); i++) {
memcpy(d, s, r.width());
@@ -1015,7 +1017,7 @@ void MaskBuffer::create(uint16 width, uint16 height) {
internalWidth = w >> 2;
h = height;
size = (internalWidth * h);
- data = (byte*)calloc(size, 1);
+ data = (byte *)calloc(size, 1);
}
void MaskBuffer::free() {
@@ -1094,7 +1096,7 @@ void PathBuffer::create(uint16 width, uint16 height) {
internalWidth = w >> 3;
h = height;
size = (internalWidth * h);
- data = (byte*)calloc(size, 1);
+ data = (byte *)calloc(size, 1);
}
void PathBuffer::free() {
diff --git a/engines/parallaction/graphics.h b/engines/parallaction/graphics.h
index dacf7715ae..b43dd193b5 100644
--- a/engines/parallaction/graphics.h
+++ b/engines/parallaction/graphics.h
@@ -103,7 +103,7 @@ public:
}
byte* getData(uint16 index) {
assert(index == 0);
- return (byte*)_surf->getBasePtr(0,0);
+ return (byte *)_surf->getBasePtr(0,0);
}
void getRect(uint16 index, Common::Rect &r) {
assert(index == 0);
@@ -341,12 +341,12 @@ public:
*/
struct BackgroundInfo {
protected:
- typedef Common::Array<MaskBuffer*> MaskPatches;
+ typedef Common::Array<MaskBuffer *> MaskPatches;
MaskPatches _maskPatches;
MaskBuffer _maskBackup;
void clearMaskData();
- typedef Common::Array<PathBuffer*> PathPatches;
+ typedef Common::Array<PathBuffer *> PathPatches;
PathPatches _pathPatches;
PathBuffer _pathBackup;
void clearPathData();
@@ -415,7 +415,7 @@ public:
};
-typedef Common::Array<GfxObj*> GfxObjArray;
+typedef Common::Array<GfxObj *> GfxObjArray;
#define SCENE_DRAWLIST_SIZE 100
class Gfx {
diff --git a/engines/parallaction/gui.h b/engines/parallaction/gui.h
index 95c5653220..a6eed240c4 100644
--- a/engines/parallaction/gui.h
+++ b/engines/parallaction/gui.h
@@ -36,7 +36,7 @@ namespace Parallaction {
class MenuInputState;
class MenuInputHelper {
- typedef Common::HashMap<Common::String, MenuInputState*> StateMap;
+ typedef Common::HashMap<Common::String, MenuInputState *> StateMap;
StateMap _map;
MenuInputState *_state;
diff --git a/engines/parallaction/gui_br.cpp b/engines/parallaction/gui_br.cpp
index 56148d78d8..5bc5acf630 100644
--- a/engines/parallaction/gui_br.cpp
+++ b/engines/parallaction/gui_br.cpp
@@ -488,10 +488,10 @@ public:
_font->setColor(0);
int x = (w - questionW)/2;
int y = 13;
- _font->drawString((byte*)surf->getBasePtr(x, y), surf->pitch, question);
+ _font->drawString((byte *)surf->getBasePtr(x, y), surf->pitch, question);
x = (w - optionW)/2;
y = 13 + _font->height()*2;
- _font->drawString((byte*)surf->getBasePtr(x,y), surf->pitch, option);
+ _font->drawString((byte *)surf->getBasePtr(x,y), surf->pitch, option);
_obj = new GfxObj(kGfxObjTypeMenu, new SurfaceToFrames(surf), "quitdialog");
assert(_obj);
diff --git a/engines/parallaction/inventory.cpp b/engines/parallaction/inventory.cpp
index 8fd9f56802..1cae63be42 100644
--- a/engines/parallaction/inventory.cpp
+++ b/engines/parallaction/inventory.cpp
@@ -183,7 +183,7 @@ ItemPosition InventoryRenderer::hitTest(const Common::Point &p) const {
void InventoryRenderer::drawItem(ItemPosition pos, ItemName name) {
Common::Rect r;
getItemRect(pos, r);
- byte* d = (byte*)_surf.getBasePtr(r.left, r.top);
+ byte* d = (byte *)_surf.getBasePtr(r.left, r.top);
drawItem(name, d, _surf.pitch);
}
@@ -238,7 +238,7 @@ void InventoryRenderer::getItemRect(ItemPosition pos, Common::Rect &r) {
}
Inventory::Inventory(int maxItems, InventoryItem *verbs) : _numItems(0), _maxItems(maxItems) {
- _items = (InventoryItem*)calloc(_maxItems, sizeof(InventoryItem));
+ _items = (InventoryItem *)calloc(_maxItems, sizeof(InventoryItem));
int i = 0;
for ( ; verbs[i]._id; i++) {
diff --git a/engines/parallaction/inventory.h b/engines/parallaction/inventory.h
index 91c06d1e93..a3b7bf953f 100644
--- a/engines/parallaction/inventory.h
+++ b/engines/parallaction/inventory.h
@@ -108,7 +108,7 @@ public:
void highlightItem(ItemPosition pos, byte color);
void drawItem(ItemName name, byte *buffer, uint pitch);
- byte* getData() const { return (byte*)_surf.pixels; }
+ byte* getData() const { return (byte *)_surf.pixels; }
void getRect(Common::Rect &r) const;
int16 getNumLines() const;
diff --git a/engines/parallaction/objects.cpp b/engines/parallaction/objects.cpp
index fe21732f03..d3529c5dd9 100644
--- a/engines/parallaction/objects.cpp
+++ b/engines/parallaction/objects.cpp
@@ -386,11 +386,11 @@ ScriptVar::~ScriptVar() {
Table::Table(uint32 size) : _size(size), _used(0), _disposeMemory(true) {
- _data = (char**)calloc(size, sizeof(char*));
+ _data = (char**)calloc(size, sizeof(char *));
}
Table::Table(uint32 size, const char **data) : _size(size), _used(size), _disposeMemory(false) {
- _data = const_cast<char**>(data);
+ _data = const_cast<char **>(data);
}
Table::~Table() {
diff --git a/engines/parallaction/parallaction.cpp b/engines/parallaction/parallaction.cpp
index 2fffc9071c..3b1b7d54a0 100644
--- a/engines/parallaction/parallaction.cpp
+++ b/engines/parallaction/parallaction.cpp
@@ -795,7 +795,7 @@ bool Location::keepAnimation_br(AnimationPtr a) {
return keepZone_br(a);
}
-template <class T>
+template<class T>
void Location::freeList(Common::List<T> &list, bool removeAll, Common::MemFunc1<bool, T, Location> filter) {
typedef typename Common::List<T>::iterator iterator;
iterator it = list.begin();
diff --git a/engines/parallaction/parallaction.h b/engines/parallaction/parallaction.h
index 5554eff3c5..0d56b62e2f 100644
--- a/engines/parallaction/parallaction.h
+++ b/engines/parallaction/parallaction.h
@@ -178,7 +178,7 @@ protected:
bool keepAnimation_ns(AnimationPtr a);
bool keepAnimation_br(AnimationPtr a);
- template <class T>
+ template<class T>
void freeList(Common::List<T> &list, bool removeAll, Common::MemFunc1<bool, T, Location> filter);
public:
@@ -447,7 +447,7 @@ private:
// callables data
- typedef void (Parallaction_ns::*Callable)(void*);
+ typedef void (Parallaction_ns::*Callable)(void *);
const Callable *_callables;
ZonePtr _moveSarcGetZone;
ZonePtr _moveSarcExaZone;
@@ -468,37 +468,37 @@ private:
PathWalker_NS *_walker;
// common callables
- void _c_play_boogie(void*);
- void _c_startIntro(void*);
- void _c_endIntro(void*);
- void _c_moveSheet(void*);
- void _c_sketch(void*);
- void _c_shade(void*);
- void _c_score(void*);
- void _c_fade(void*);
- void _c_moveSarc(void*);
- void _c_contaFoglie(void*);
- void _c_zeroFoglie(void*);
- void _c_trasformata(void*);
- void _c_offMouse(void*);
- void _c_onMouse(void*);
- void _c_setMask(void*);
- void _c_endComment(void*);
- void _c_frankenstein(void*);
- void _c_finito(void*);
- void _c_ridux(void*);
- void _c_testResult(void*);
+ void _c_play_boogie(void *);
+ void _c_startIntro(void *);
+ void _c_endIntro(void *);
+ void _c_moveSheet(void *);
+ void _c_sketch(void *);
+ void _c_shade(void *);
+ void _c_score(void *);
+ void _c_fade(void *);
+ void _c_moveSarc(void *);
+ void _c_contaFoglie(void *);
+ void _c_zeroFoglie(void *);
+ void _c_trasformata(void *);
+ void _c_offMouse(void *);
+ void _c_onMouse(void *);
+ void _c_setMask(void *);
+ void _c_endComment(void *);
+ void _c_frankenstein(void *);
+ void _c_finito(void *);
+ void _c_ridux(void *);
+ void _c_testResult(void *);
// dos specific callables
- void _c_null(void*);
+ void _c_null(void *);
// amiga specific callables
- void _c_projector(void*);
- void _c_HBOff(void*);
- void _c_offSound(void*);
- void _c_startMusic(void*);
- void _c_closeMusic(void*);
- void _c_HBOn(void*);
+ void _c_projector(void *);
+ void _c_HBOff(void *);
+ void _c_offSound(void *);
+ void _c_startMusic(void *);
+ void _c_closeMusic(void *);
+ void _c_HBOn(void *);
};
@@ -582,7 +582,7 @@ private:
void startIngameMenu();
void freeCharacter();
- typedef void (Parallaction_br::*Callable)(void*);
+ typedef void (Parallaction_br::*Callable)(void *);
const Callable *_callables;
static const Callable _dosCallables[6];
static const Callable _amigaCallables[6];
@@ -592,13 +592,13 @@ private:
PathWalker_BR *_walker;
// dos callables
- void _c_null(void*);
- void _c_blufade(void*);
- void _c_resetpalette(void*);
- void _c_ferrcycle(void*);
- void _c_lipsinc(void*);
- void _c_albcycle(void*);
- void _c_password(void*);
+ void _c_null(void *);
+ void _c_blufade(void *);
+ void _c_resetpalette(void *);
+ void _c_ferrcycle(void *);
+ void _c_lipsinc(void *);
+ void _c_albcycle(void *);
+ void _c_password(void *);
};
extern Parallaction *_vm;
diff --git a/engines/parallaction/parallaction_br.cpp b/engines/parallaction/parallaction_br.cpp
index 44a8899304..658a8e8795 100644
--- a/engines/parallaction/parallaction_br.cpp
+++ b/engines/parallaction/parallaction_br.cpp
@@ -289,7 +289,7 @@ void Parallaction_br::changeLocation() {
_disk->selectArchive(_partNames[_part]);
- memset(_counters, 0, ARRAYSIZE(_counters));
+ memset(_counters, 0, sizeof(_counters));
_globalFlagsNames = _disk->loadTable("global");
_objectsNames = _disk->loadTable("objects");
diff --git a/engines/parallaction/parser.h b/engines/parallaction/parser.h
index 1cf8e2f7ff..3e2604eda2 100644
--- a/engines/parallaction/parser.h
+++ b/engines/parallaction/parser.h
@@ -57,7 +57,7 @@ public:
typedef Common::Functor0<void> Opcode;
-typedef Common::Array<const Opcode*> OpcodeSet;
+typedef Common::Array<const Opcode *> OpcodeSet;
@@ -69,8 +69,8 @@ public:
uint _lookup;
- Common::Stack<OpcodeSet*> _opcodes;
- Common::Stack<Table*> _statements;
+ Common::Stack<OpcodeSet *> _opcodes;
+ Common::Stack<Table *> _statements;
OpcodeSet *_currentOpcodes;
Table *_currentStatements;
@@ -199,7 +199,7 @@ protected:
void addCommand();
void clearSet(OpcodeSet &opcodes) {
- for (Common::Array<const Opcode*>::iterator i = opcodes.begin(); i != opcodes.end(); ++i)
+ for (Common::Array<const Opcode *>::iterator i = opcodes.begin(); i != opcodes.end(); ++i)
delete *i;
opcodes.clear();
}
@@ -357,7 +357,7 @@ protected:
virtual void parseRValue(ScriptVar &var, const char *str);
void clearSet(OpcodeSet &opcodes) {
- for (Common::Array<const Opcode*>::iterator i = opcodes.begin(); i != opcodes.end(); ++i)
+ for (Common::Array<const Opcode *>::iterator i = opcodes.begin(); i != opcodes.end(); ++i)
delete *i;
opcodes.clear();
}
diff --git a/engines/parallaction/parser_br.cpp b/engines/parallaction/parser_br.cpp
index df53ecca3f..0904dbf655 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(static_cast<unsigned char>(_tokens[ctxt.nextToken][0])) || _tokens[ctxt.nextToken][0] == '-') {
+ if (Common::isDigit(_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(static_cast<unsigned char>(_tokens[ctxt.nextToken][0])) || _tokens[ctxt.nextToken][0] == '-') {
+ if (Common::isDigit(_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(static_cast<unsigned char>(_tokens[1][1]))) {
+ if (Common::isDigit(_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(static_cast<unsigned char>(_tokens[1][1]))) {
+ if (Common::isAlpha(_tokens[1][1])) {
ctxt.z->_flags |= kFlagsAnimLinked;
ctxt.z->_linkedName = _tokens[1];
} else {
@@ -1003,7 +1003,7 @@ DECLARE_INSTRUCTION_PARSER(text) {
int _si = 1;
- if (isdigit(static_cast<unsigned char>(_tokens[1][1]))) {
+ if (Common::isDigit(_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(static_cast<unsigned char>(str[0])) || str[0] == '-') {
+ if (Common::isDigit(str[0]) || str[0] == '-') {
v.setImmediate(atoi(str));
return;
}
@@ -1131,7 +1131,7 @@ void LocationParser_br::init() {
_locationZoneStmt = new Table(ARRAYSIZE(_locationZoneStmtRes_br), _locationZoneStmtRes_br);
_locationAnimStmt = new Table(ARRAYSIZE(_locationAnimStmtRes_br), _locationAnimStmtRes_br);
- Common::Array<const Opcode*> *table = 0;
+ Common::Array<const Opcode *> *table = 0;
SetOpcodeTable(_commandParsers);
WARNING_PARSER(unexpected);
@@ -1234,7 +1234,7 @@ void ProgramParser_br::init() {
_instructionNames = new Table(ARRAYSIZE(_instructionNamesRes_br), _instructionNamesRes_br);
- Common::Array<const Opcode*> *table = 0;
+ Common::Array<const Opcode *> *table = 0;
SetOpcodeTable(_instructionParsers);
INSTRUCTION_PARSER(defLocal); // invalid opcode -> local definition
diff --git a/engines/parallaction/parser_ns.cpp b/engines/parallaction/parser_ns.cpp
index a73f1558e8..f1d1db53e9 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(static_cast<unsigned char>(str[0])) || str[0] == '-') {
+ if (Common::isDigit(str[0]) || str[0] == '-') {
v.setImmediate(atoi(str));
return;
}
@@ -1107,7 +1107,7 @@ void LocationParser_ns::init() {
_locationZoneStmt = new Table(ARRAYSIZE(_locationZoneStmtRes_ns), _locationZoneStmtRes_ns);
_locationAnimStmt = new Table(ARRAYSIZE(_locationAnimStmtRes_ns), _locationAnimStmtRes_ns);
- Common::Array<const Opcode*> *table = 0;
+ Common::Array<const Opcode *> *table = 0;
SetOpcodeTable(_commandParsers);
WARNING_PARSER(unexpected);
@@ -1177,7 +1177,7 @@ void ProgramParser_ns::init() {
_instructionNames = new Table(ARRAYSIZE(_instructionNamesRes_ns), _instructionNamesRes_ns);
- Common::Array<const Opcode*> *table = 0;
+ Common::Array<const Opcode *> *table = 0;
SetOpcodeTable(_instructionParsers);
INSTRUCTION_PARSER(defLocal); // invalid opcode -> local definition
INSTRUCTION_PARSER(animation); // on
diff --git a/engines/parallaction/saveload.cpp b/engines/parallaction/saveload.cpp
index 5a1daa256b..3ab25f203f 100644
--- a/engines/parallaction/saveload.cpp
+++ b/engines/parallaction/saveload.cpp
@@ -49,7 +49,7 @@ Common::String SaveLoad::genSaveFileName(uint slot) {
assert(slot < NUM_SAVESLOTS || slot == SPECIAL_SAVESLOT);
char s[20];
- sprintf(s, "%s.%.3d", _saveFilePrefix.c_str(), slot);
+ sprintf(s, "%s.%.3u", _saveFilePrefix.c_str(), slot);
return Common::String(s);
}
diff --git a/engines/parallaction/sound_br.cpp b/engines/parallaction/sound_br.cpp
index 16ffd24a82..0925e55309 100644
--- a/engines/parallaction/sound_br.cpp
+++ b/engines/parallaction/sound_br.cpp
@@ -378,7 +378,7 @@ Audio::AudioStream *AmigaSoundMan_br::loadChannelData(const char *filename, Chan
if (_vm->getFeatures() & GF_DEMO) {
uint32 dataSize = stream->size();
- int8 *data = (int8*)malloc(dataSize);
+ int8 *data = (int8 *)malloc(dataSize);
if (stream->read(data, dataSize) != dataSize)
error("DosSoundMan_br::loadChannelData: Read failed");
diff --git a/engines/parallaction/sound_ns.cpp b/engines/parallaction/sound_ns.cpp
index b5d4c72ea4..3cc25b36b0 100644
--- a/engines/parallaction/sound_ns.cpp
+++ b/engines/parallaction/sound_ns.cpp
@@ -165,7 +165,7 @@ void DosSoundMan_ns::playCharacterMusic(const char *character) {
return;
}
- char *name = const_cast<char*>(character);
+ char *name = const_cast<char *>(character);
const char *newMusicFile = 0;
if (!scumm_stricmp(name, _dinoName)) {
diff --git a/engines/queen/input.h b/engines/queen/input.h
index 0aa04dd026..b3bf811cd1 100644
--- a/engines/queen/input.h
+++ b/engines/queen/input.h
@@ -23,7 +23,7 @@
#ifndef QUEEN_INPUT_H
#define QUEEN_INPUT_H
-#include "common/util.h"
+#include "common/language.h"
#include "common/rect.h"
#include "common/events.h"
#include "queen/defs.h"
diff --git a/engines/queen/logic.cpp b/engines/queen/logic.cpp
index f60ac59ff1..6d90254608 100644
--- a/engines/queen/logic.cpp
+++ b/engines/queen/logic.cpp
@@ -1193,14 +1193,11 @@ void Logic::handlePinnacleRoom() {
uint16 prevObj = 0;
CmdText *cmdText = CmdText::makeCmdTextInstance(5, _vm);
cmdText->setVerb(VERB_WALK_TO);
- while (_vm->input()->mouseButton() == 0 || _entryObj == 0) {
+ while (!_vm->shouldQuit() && (_vm->input()->mouseButton() == 0 || _entryObj == 0)) {
_vm->update();
mouse = _vm->input()->getMousePos();
- // update screen scrolling
- _vm->display()->horizontalScroll(mouse.x);
-
// update bobs position / frame
joe->x = piton->x = 3 * mouse.x / 4 + 200;
joe->frameNum = mouse.x / 36 + 45;
@@ -1218,6 +1215,9 @@ void Logic::handlePinnacleRoom() {
}
prevObj = curObj;
}
+
+ // update screen scrolling
+ _vm->display()->horizontalScroll(mouse.x);
}
delete cmdText;
_vm->input()->clearMouseButton();
diff --git a/engines/queen/music.cpp b/engines/queen/music.cpp
index 858692703c..2835954003 100644
--- a/engines/queen/music.cpp
+++ b/engines/queen/music.cpp
@@ -303,7 +303,7 @@ void MidiMusic::playMusic() {
for (uint i = 0; i < packedSize; i++)
#if defined(SCUMM_NEED_ALIGNMENT)
- memcpy(&_buf[i], (byte*)((byte*)data + *(idx + i) * sizeof(uint16)), sizeof(uint16));
+ memcpy(&_buf[i], (byte *)((byte *)data + *(idx + i) * sizeof(uint16)), sizeof(uint16));
#else
_buf[i] = data[*(idx + i)];
#endif
diff --git a/engines/queen/queen.cpp b/engines/queen/queen.cpp
index c610ef9921..d17268e16b 100644
--- a/engines/queen/queen.cpp
+++ b/engines/queen/queen.cpp
@@ -25,6 +25,7 @@
#include "common/config-manager.h"
#include "common/file.h"
#include "common/fs.h"
+#include "common/gui_options.h"
#include "common/savefile.h"
#include "common/system.h"
#include "common/events.h"
diff --git a/engines/queen/resource.h b/engines/queen/resource.h
index ef8e463631..7317ec5134 100644
--- a/engines/queen/resource.h
+++ b/engines/queen/resource.h
@@ -25,7 +25,8 @@
#include "common/file.h"
#include "common/str-array.h"
-#include "common/util.h"
+#include "common/language.h"
+#include "common/platform.h"
#include "queen/defs.h"
namespace Queen {
diff --git a/engines/queen/talk.cpp b/engines/queen/talk.cpp
index 1f8d9b29f9..94bc105bb0 100644
--- a/engines/queen/talk.cpp
+++ b/engines/queen/talk.cpp
@@ -96,7 +96,7 @@ void Talk::talk(const char *filename, int personInRoom, char *cutawayFilename) {
}
int16 oldLevel = 0;
- bool personWalking = false;
+ bool personWalking = false; // FIXME: unused
// Lines 828-846 in talk.c
for (i = 1; i <= 4; i++) {
@@ -373,7 +373,6 @@ byte *Talk::loadDialogFile(const char *filename) {
void Talk::load(const char *filename) {
int i;
byte *ptr = _fileData = loadDialogFile(filename);
- bool canQuit;
// Load talk header
@@ -381,9 +380,9 @@ void Talk::load(const char *filename) {
if (_levelMax < 0) {
_levelMax = -_levelMax;
- canQuit = false;
+ _vm->input()->canQuit(false);
} else {
- canQuit = true;
+ _vm->input()->canQuit(true);
}
_uniqueKey = (int16)READ_BE_INT16(ptr); ptr += 2;
@@ -658,7 +657,7 @@ void Talk::stringAnimation(const SpeechParameters *parameters, int startFrame, i
} else if (parameters->animation[0] == 'E') {
// Talking head animation
return;
- } else if (!isdigit(static_cast<unsigned char>(parameters->animation[0]))) {
+ } else if (!Common::isDigit(parameters->animation[0])) {
debug(6, "Error in speak string animation: '%s'", parameters->animation);
return;
} else
diff --git a/engines/saga/animation.cpp b/engines/saga/animation.cpp
index 8b2d1e9dad..fd602ff4fb 100644
--- a/engines/saga/animation.cpp
+++ b/engines/saga/animation.cpp
@@ -501,7 +501,7 @@ void Anim::play(uint16 animId, int vectorTime, bool playing) {
}
anim = getAnimation(animId);
- displayBuffer = (byte*)_vm->_render->getBackGroundSurface()->pixels;
+ displayBuffer = (byte *)_vm->_render->getBackGroundSurface()->pixels;
if (playing) {
anim->state = ANIM_PLAYING;
diff --git a/engines/saga/detection.cpp b/engines/saga/detection.cpp
index 091ec8d427..d39ec34cc8 100644
--- a/engines/saga/detection.cpp
+++ b/engines/saga/detection.cpp
@@ -209,7 +209,7 @@ int SagaMetaEngine::getMaximumSaveSlot() const { return MAX_SAVES - 1; }
void SagaMetaEngine::removeSaveState(const char *target, int slot) const {
Common::String filename = target;
- filename += Common::String::format(".s%02d", slot);;
+ filename += Common::String::format(".s%02d", slot);
g_system->getSavefileManager()->removeSavefile(filename);
}
diff --git a/engines/saga/detection_tables.h b/engines/saga/detection_tables.h
index 863c2cee64..234a10acfe 100644
--- a/engines/saga/detection_tables.h
+++ b/engines/saga/detection_tables.h
@@ -267,7 +267,7 @@ static const SAGAGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_DEMO,
- GUIO1(GUIO_NONE)
+ GUIO0()
},
GID_ITE,
0,
@@ -293,7 +293,7 @@ static const SAGAGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_DEMO,
- GUIO1(GUIO_NONE)
+ GUIO0()
},
GID_ITE,
GF_8BIT_UNSIGNED_PCM,
@@ -326,7 +326,7 @@ static const SAGAGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformMacintosh,
ADGF_CD,
- GUIO1(GUIO_NONE)
+ GUIO0()
},
GID_ITE,
GF_8BIT_UNSIGNED_PCM,
@@ -350,7 +350,7 @@ static const SAGAGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformMacintosh,
ADGF_CD,
- GUIO1(GUIO_NONE)
+ GUIO0()
},
GID_ITE,
0,
@@ -382,7 +382,7 @@ static const SAGAGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformUnknown,
ADGF_CD,
- GUIO1(GUIO_NONE)
+ GUIO0()
},
GID_ITE,
0,
@@ -412,7 +412,7 @@ static const SAGAGameDescription gameDescriptions[] = {
Common::IT_ITA,
Common::kPlatformUnknown,
ADGF_CD,
- GUIO1(GUIO_NONE)
+ GUIO0()
},
GID_ITE,
0,
@@ -436,7 +436,7 @@ static const SAGAGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformPC,
ADGF_CD,
- GUIO1(GUIO_NONE)
+ GUIO0()
},
GID_ITE,
GF_EXTRA_ITE_CREDITS,
@@ -460,7 +460,7 @@ static const SAGAGameDescription gameDescriptions[] = {
Common::IT_ITA,
Common::kPlatformPC,
ADGF_CD,
- GUIO1(GUIO_NONE)
+ GUIO0()
},
GID_ITE,
0,
@@ -484,7 +484,7 @@ static const SAGAGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformPC,
ADGF_CD,
- GUIO1(GUIO_NONE)
+ GUIO0()
},
GID_ITE,
0,
@@ -509,7 +509,7 @@ static const SAGAGameDescription gameDescriptions[] = {
Common::DE_DEU,
Common::kPlatformPC,
ADGF_CD,
- GUIO1(GUIO_NONE)
+ GUIO0()
},
GID_ITE,
0,
@@ -617,7 +617,7 @@ static const SAGAGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformPC,
ADGF_DEMO,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GID_IHNM,
0,
@@ -649,7 +649,7 @@ static const SAGAGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformPC,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GID_IHNM,
0,
@@ -679,7 +679,7 @@ static const SAGAGameDescription gameDescriptions[] = {
Common::DE_DEU,
Common::kPlatformPC,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GID_IHNM,
0,
@@ -707,7 +707,7 @@ static const SAGAGameDescription gameDescriptions[] = {
Common::ES_ESP,
Common::kPlatformPC,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GID_IHNM,
0,
@@ -736,7 +736,7 @@ static const SAGAGameDescription gameDescriptions[] = {
Common::FR_FRA,
Common::kPlatformPC,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GID_IHNM,
0,
@@ -764,7 +764,7 @@ static const SAGAGameDescription gameDescriptions[] = {
Common::IT_ITA,
Common::kPlatformPC,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GID_IHNM,
0,
@@ -789,7 +789,7 @@ static const SAGAGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformMacintosh,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GID_IHNM,
0,
@@ -819,7 +819,7 @@ static const SAGAGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformPC,
ADGF_UNSTABLE,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GID_DINO,
0,
@@ -849,7 +849,7 @@ static const SAGAGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformPC,
ADGF_UNSTABLE,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GID_FTA2,
0,
diff --git a/engines/saga/gfx.cpp b/engines/saga/gfx.cpp
index ab0c0f3e4c..62250a0820 100644
--- a/engines/saga/gfx.cpp
+++ b/engines/saga/gfx.cpp
@@ -123,7 +123,7 @@ void Surface::drawPolyLine(const Point *points, int count, int color) {
drawLine(points[i].x, points[i].y, points[i - 1].x, points[i - 1].y, color);
}
- drawLine(points[count - 1].x, points[count - 1].y, points->x, points->y, color);
+ drawLine(points[count - 1].x, points[count - 1].y, points[0].x, points[0].y, color);
}
}
@@ -156,7 +156,7 @@ void Surface::transitionDissolve(const byte *sourceBuffer, const Common::Rect &s
if (sourceRect.contains(x1, y1)) {
color = sourceBuffer[(x1-sourceRect.left) + sourceRect.width()*(y1-sourceRect.top)];
if (flags == 0 || color)
- ((byte*)pixels)[seq] = color;
+ ((byte *)pixels)[seq] = color;
}
}
}
diff --git a/engines/saga/interface.cpp b/engines/saga/interface.cpp
index 994b35cbf8..a7bd7edbe5 100644
--- a/engines/saga/interface.cpp
+++ b/engines/saga/interface.cpp
@@ -1151,7 +1151,7 @@ void Interface::processStatusTextInput(Common::KeyState keystate) {
if (_statusTextInputPos >= STATUS_TEXT_INPUT_MAX) {
break;
}
- if (isalnum(keystate.ascii) || (keystate.ascii == ' ')) {
+ if (Common::isAlnum(keystate.ascii) || (keystate.ascii == ' ')) {
_statusTextInputString[_statusTextInputPos++] = keystate.ascii;
_statusTextInputString[_statusTextInputPos] = 0;
}
@@ -1209,7 +1209,7 @@ bool Interface::processTextInput(Common::KeyState keystate) {
_textInputPos = _textInputStringLength + 1;
break;
default:
- if (((keystate.ascii <= 255) && (isalnum(keystate.ascii))) || (keystate.ascii == ' ') ||
+ if (((keystate.ascii <= 255) && (Common::isAlnum(keystate.ascii))) || (keystate.ascii == ' ') ||
(keystate.ascii == '-') || (keystate.ascii == '_')) {
if (_textInputStringLength < save_title_size - 1) {
ch[0] = keystate.ascii;
diff --git a/engines/saga/isomap.cpp b/engines/saga/isomap.cpp
index e886f0df82..945b4ad5a7 100644
--- a/engines/saga/isomap.cpp
+++ b/engines/saga/isomap.cpp
@@ -95,7 +95,7 @@ static const int16 directions[8][2] = {
IsoMap::IsoMap(SagaEngine *vm) : _vm(vm) {
_viewScroll.x = (128 - 8) * 16;
- _viewScroll.x = (128 - 8) * 16 - 64;
+ _viewScroll.y = (128 - 8) * 16 - 64;
_viewDiff = 1;
}
@@ -346,7 +346,7 @@ int16 IsoMap::findMulti(int16 tileIndex, int16 absU, int16 absV, int16 absH) {
if (offset + sizeof(int16) > _multiTableData.size() * sizeof(int16)) {
error("wrong multiTileEntryData->offset");
}
- tiles = (int16*)((byte*)&_multiTableData.front() + offset);
+ tiles = (int16 *)((byte *)&_multiTableData.front() + offset);
tileIndex = *tiles;
if (tileIndex >= 256) {
warning("something terrible happened");
diff --git a/engines/saga/resource.h b/engines/saga/resource.h
index 2124f3e29f..a8e2e92361 100644
--- a/engines/saga/resource.h
+++ b/engines/saga/resource.h
@@ -157,7 +157,7 @@ protected:
virtual void processPatches(Resource *resource, const GamePatchDescription *patchFiles) { }
};
-typedef Common::List<ResourceContext*> ResourceContextList;
+typedef Common::List<ResourceContext *> ResourceContextList;
struct MetaResource {
int16 sceneIndex;
diff --git a/engines/saga/saga.h b/engines/saga/saga.h
index fb01b1ac5d..829425aeaf 100644
--- a/engines/saga/saga.h
+++ b/engines/saga/saga.h
@@ -208,18 +208,6 @@ enum PanelButtonType {
kPanelAllButtons = 0xFFFFF
};
-enum GameSoundTypes {
- kSoundPCM = 0,
- kSoundVOX = 1,
- kSoundVOC = 2,
- kSoundWAV = 3,
- kSoundMP3 = 4,
- kSoundOGG = 5,
- kSoundFLAC = 6,
- kSoundAIFF = 7,
- kSoundShorten = 8
-};
-
enum TextStringIds {
kTextPickUp,
kTextLookAt,
diff --git a/engines/saga/saveload.cpp b/engines/saga/saveload.cpp
index 9e0789fdaf..6a5a7d8e14 100644
--- a/engines/saga/saveload.cpp
+++ b/engines/saga/saveload.cpp
@@ -44,7 +44,7 @@ static SaveFileData emptySlot = {
char* SagaEngine::calcSaveFileName(uint slotNumber) {
static char name[MAX_FILE_NAME];
- sprintf(name, "%s.s%02d", _targetName.c_str(), slotNumber);
+ sprintf(name, "%s.s%02u", _targetName.c_str(), slotNumber);
return name;
}
diff --git a/engines/saga/scene.cpp b/engines/saga/scene.cpp
index 61e62d5626..35d923f821 100644
--- a/engines/saga/scene.cpp
+++ b/engines/saga/scene.cpp
@@ -454,7 +454,6 @@ void Scene::changeScene(int16 sceneNumber, int actorsEntrance, SceneTransitionTy
if (_vm->_hasITESceneSubstitutes) {
for (int i = 0; i < ARRAYSIZE(sceneSubstitutes); i++) {
if (sceneSubstitutes[i].sceneId == sceneNumber) {
- Surface bbmBuffer;
byte *pal, colors[768];
Common::File file;
Rect rect;
@@ -463,6 +462,7 @@ void Scene::changeScene(int16 sceneNumber, int actorsEntrance, SceneTransitionTy
_vm->_interface->setMode(kPanelSceneSubstitute);
if (file.open(sceneSubstitutes[i].image)) {
+ Graphics::Surface bbmBuffer;
Graphics::decodePBM(file, bbmBuffer, colors);
pal = colors;
rect.setWidth(bbmBuffer.w);
diff --git a/engines/saga/script.h b/engines/saga/script.h
index 227b58a298..c4ea2d62b3 100644
--- a/engines/saga/script.h
+++ b/engines/saga/script.h
@@ -196,9 +196,9 @@ public:
case kAddressModule:
return _moduleBase;
case kAddressStack:
- return (byte*)&_stackBuf[_frameIndex];
+ return (byte *)&_stackBuf[_frameIndex];
case kAddressThread:
- return (byte*)_threadVars;
+ return (byte *)_threadVars;
default:
return _commonBase;
}
diff --git a/engines/saga/sndres.cpp b/engines/saga/sndres.cpp
index add34e22a2..5a97eb6019 100644
--- a/engines/saga/sndres.cpp
+++ b/engines/saga/sndres.cpp
@@ -30,12 +30,17 @@
#include "saga/sound.h"
#include "common/file.h"
+#include "common/substream.h"
#include "audio/audiostream.h"
#include "audio/decoders/adpcm.h"
#include "audio/decoders/aiff.h"
+#include "audio/decoders/flac.h"
+#include "audio/decoders/mac_snd.h"
+#include "audio/decoders/mp3.h"
#include "audio/decoders/raw.h"
#include "audio/decoders/voc.h"
+#include "audio/decoders/vorbis.h"
#include "audio/decoders/wave.h"
#ifdef ENABLE_SAGA2
#include "saga/shorten.h"
@@ -167,14 +172,31 @@ void SndRes::playVoice(uint32 resourceId) {
_vm->_sound->playVoice(buffer);
}
+enum GameSoundType {
+ kSoundPCM = 0,
+ kSoundVOX = 1,
+ kSoundVOC = 2,
+ kSoundWAV = 3,
+ kSoundMP3 = 4,
+ kSoundOGG = 5,
+ kSoundFLAC = 6,
+ kSoundAIFF = 7,
+ kSoundShorten = 8,
+ kSoundMacSND = 9
+};
+
+// Use a macro to read in the sound data based on if we actually want to buffer it or not
+#define READ_STREAM(streamSize) \
+ (onlyHeader \
+ ? new Common::SeekableSubReadStream(&readS, readS.pos(), readS.pos() + (streamSize)) \
+ : readS.readStream(streamSize))
+
bool SndRes::load(ResourceContext *context, uint32 resourceId, SoundBuffer &buffer, bool onlyHeader) {
- Audio::AudioStream *voxStream;
size_t soundResourceLength;
bool result = false;
- GameSoundTypes resourceType = kSoundPCM;
- byte *data = 0;
+ GameSoundType resourceType = kSoundPCM;
int rate = 0, size = 0;
- Common::File* file;
+ Common::File *file;
if (resourceId == (uint32)-1) {
return false;
@@ -210,7 +232,7 @@ bool SndRes::load(ResourceContext *context, uint32 resourceId, SoundBuffer &buff
soundResourceLength = resourceData->size;
}
- Common::SeekableReadStream& readS = *file;
+ Common::SeekableReadStream &readS = *file;
bool uncompressedSound = false;
if (soundResourceLength >= 8) {
@@ -250,160 +272,141 @@ bool SndRes::load(ResourceContext *context, uint32 resourceId, SoundBuffer &buff
}
- // Default sound type is 16-bit signed PCM, used in ITE by PCM and VOX files
- buffer.isCompressed = context->isCompressed();
- buffer.soundType = resourceType;
- buffer.originalSize = 0;
- // Set default flags and frequency for PCM, VOC and VOX files, which got no header
- buffer.flags = Audio::FLAG_16BITS;
- buffer.frequency = 22050;
+ // Default sound type is 16-bit signed PCM, used in ITE
+ byte rawFlags = Audio::FLAG_16BITS;
+
if (_vm->getGameId() == GID_ITE) {
- if (_vm->getFeatures() & GF_8BIT_UNSIGNED_PCM) { // older ITE demos
- buffer.flags |= Audio::FLAG_UNSIGNED;
- buffer.flags &= ~Audio::FLAG_16BITS;
- } else {
+ if (context->fileType() & GAME_MACBINARY) {
+ // ITE Mac has sound in the Mac snd format
+ resourceType = kSoundMacSND;
+ } else if (_vm->getFeatures() & GF_8BIT_UNSIGNED_PCM) { // older ITE demos
+ rawFlags |= Audio::FLAG_UNSIGNED;
+ rawFlags &= ~Audio::FLAG_16BITS;
+ } else if (!uncompressedSound && !scumm_stricmp(context->fileName(), "voicesd.rsc")) {
// Voice files in newer ITE demo versions are OKI ADPCM (VOX) encoded.
- // These are LE in all the Windows and Mac demos
- if (!uncompressedSound && !scumm_stricmp(context->fileName(), "voicesd.rsc")) {
- resourceType = kSoundVOX;
- buffer.flags |= Audio::FLAG_LITTLE_ENDIAN;
- }
+ resourceType = kSoundVOX;
}
}
- buffer.buffer = NULL;
+
+ buffer.stream = 0;
// Check for LE sounds
if (!context->isBigEndian())
- buffer.flags |= Audio::FLAG_LITTLE_ENDIAN;
-
- // Older Mac versions of ITE were Macbinary packed
- int soundOffset = (context->fileType() & GAME_MACBINARY) ? 36 : 0;
+ rawFlags |= Audio::FLAG_LITTLE_ENDIAN;
switch (resourceType) {
- case kSoundPCM:
- buffer.size = soundResourceLength - soundOffset;
- if (!onlyHeader) {
- buffer.buffer = (byte *) malloc(buffer.size);
- if (soundOffset > 0)
- readS.skip(soundOffset);
- readS.read(buffer.buffer, buffer.size);
- }
+ case kSoundPCM: {
+ // In ITE CD German, some voices are absent and contain just 5 zero bytes.
+ // Round down to an even number when the audio is 16-bit so makeRawStream
+ // will accept the data (needs to be an even size for 16-bit data).
+ // See bug #1256701
+
+ if ((soundResourceLength & 1) && (rawFlags & Audio::FLAG_16BITS))
+ soundResourceLength &= ~1;
+
+ Audio::SeekableAudioStream *audStream = Audio::makeRawStream(READ_STREAM(soundResourceLength), 22050, rawFlags);
+ buffer.stream = audStream;
+ buffer.streamLength = audStream->getLength();
result = true;
- break;
+ } break;
case kSoundVOX:
- buffer.size = soundResourceLength * 4;
- if (!onlyHeader) {
- voxStream = Audio::makeADPCMStream(&readS, DisposeAfterUse::NO, soundResourceLength, Audio::kADPCMOki);
- buffer.buffer = (byte *)malloc(buffer.size);
- voxStream->readBuffer((int16*)buffer.buffer, soundResourceLength * 2);
- delete voxStream;
- }
+ buffer.stream = Audio::makeADPCMStream(READ_STREAM(soundResourceLength), DisposeAfterUse::YES, soundResourceLength, Audio::kADPCMOki, 22050, 1);
+ buffer.streamLength = Audio::Timestamp(0, soundResourceLength * 2, buffer.stream->getRate());
result = true;
break;
+ case kSoundMacSND: {
+ Audio::SeekableAudioStream *audStream = Audio::makeMacSndStream(READ_STREAM(soundResourceLength), DisposeAfterUse::YES);
+ buffer.stream = audStream;
+ buffer.streamLength = audStream->getLength();
+ result = true;
+ } break;
+ case kSoundAIFF: {
+ Audio::SeekableAudioStream *audStream = Audio::makeAIFFStream(READ_STREAM(soundResourceLength), DisposeAfterUse::YES);
+ buffer.stream = audStream;
+ buffer.streamLength = audStream->getLength();
+ result = true;
+ } break;
+ case kSoundVOC: {
+ Audio::SeekableAudioStream *audStream = Audio::makeVOCStream(READ_STREAM(soundResourceLength), Audio::FLAG_UNSIGNED, DisposeAfterUse::YES);
+ buffer.stream = audStream;
+ buffer.streamLength = audStream->getLength();
+ result = true;
+ } break;
case kSoundWAV:
- case kSoundAIFF:
case kSoundShorten:
- case kSoundVOC:
if (resourceType == kSoundWAV) {
- result = Audio::loadWAVFromStream(readS, size, rate, buffer.flags);
- } else if (resourceType == kSoundAIFF) {
- result = Audio::loadAIFFFromStream(readS, size, rate, buffer.flags);
+ result = Audio::loadWAVFromStream(readS, size, rate, rawFlags);
#ifdef ENABLE_SAGA2
} else if (resourceType == kSoundShorten) {
- result = loadShortenFromStream(readS, size, rate, buffer.flags);
+ result = loadShortenFromStream(readS, size, rate, rawFlags);
#endif
- } else if (resourceType == kSoundVOC) {
- data = Audio::loadVOCFromStream(readS, size, rate);
- result = (data != NULL);
- if (onlyHeader)
- free(data);
- buffer.flags |= Audio::FLAG_UNSIGNED;
- buffer.flags &= ~Audio::FLAG_16BITS;
- buffer.flags &= ~Audio::FLAG_STEREO;
}
if (result) {
- buffer.frequency = rate;
- buffer.size = size;
-
- if (!onlyHeader) {
- if (resourceType == kSoundVOC) {
- buffer.buffer = data;
- } else {
- buffer.buffer = (byte *)malloc(size);
- readS.read(buffer.buffer, size);
- }
- }
+ Audio::SeekableAudioStream *audStream = Audio::makeRawStream(READ_STREAM(size), rate, rawFlags);
+ buffer.stream = audStream;
+ buffer.streamLength = audStream->getLength();
}
break;
case kSoundMP3:
case kSoundOGG:
- case kSoundFLAC:
- ResourceData *resourceData;
- resourceData = context->getResourceData(resourceId);
-
- // Read compressed sfx header
- readS.readByte(); // Skip compression identifier byte
- buffer.frequency = readS.readUint16LE();
- buffer.originalSize = readS.readUint32LE();
- if (readS.readByte() == 8) // read sample bits
- buffer.flags &= ~Audio::FLAG_16BITS;
- if (readS.readByte() != 0) // read stereo flag
- buffer.flags |= Audio::FLAG_STEREO;
-
- buffer.size = soundResourceLength;
- buffer.soundType = resourceType;
- buffer.fileOffset = resourceData->offset + 9; // skip compressed sfx header: byte + uint16 + uint32 + byte + byte
-
- if (!onlyHeader) {
- buffer.buffer = (byte *)malloc(buffer.size);
- readS.read(buffer.buffer, buffer.size);
+ case kSoundFLAC: {
+ readS.skip(9); // skip sfx header
+
+ Audio::SeekableAudioStream *audStream = 0;
+ Common::SeekableReadStream *memStream = READ_STREAM(soundResourceLength - 9);
+
+ if (resourceType == kSoundMP3) {
+#ifdef USE_MAD
+ audStream = Audio::makeMP3Stream(memStream, DisposeAfterUse::YES);
+#endif
+ } else if (resourceType == kSoundOGG) {
+#ifdef USE_VORBIS
+ audStream = Audio::makeVorbisStream(memStream, DisposeAfterUse::YES);
+#endif
+ } else /* if (resourceType == kSoundFLAC) */ {
+#ifdef USE_FLAC
+ audStream = Audio::makeFLACStream(memStream, DisposeAfterUse::YES);
+#endif
}
- result = true;
- break;
+ if (audStream) {
+ buffer.stream = audStream;
+ buffer.streamLength = audStream->getLength();
+ result = true;
+ } else {
+ delete memStream;
+ }
+
+ } break;
default:
error("SndRes::load Unknown sound type");
}
-
if (_vm->getGameId() == GID_IHNM && _vm->isMacResources()) {
delete file;
}
-
- // In ITE CD De some voices are absent and contain just 5 bytes header
- // Round it to even number so soundmanager will not crash.
- // See bug #1256701
- buffer.size &= ~(0x1);
+ if (onlyHeader) {
+ delete buffer.stream;
+ buffer.stream = 0;
+ }
return result;
}
+#undef READ_STREAM
+
int SndRes::getVoiceLength(uint32 resourceId) {
- double msDouble;
SoundBuffer buffer;
if (!(_vm->_voiceFilesExist))
return -1;
- if (!load(_voiceContext, resourceId, buffer, true)) {
+ if (!load(_voiceContext, resourceId, buffer, true))
return -1;
- }
-
- if (!_voiceContext->isCompressed() || buffer.originalSize == 0)
- msDouble = (double)buffer.size;
- else
- msDouble = (double)buffer.originalSize;
-
- if (buffer.flags & Audio::FLAG_16BITS)
- msDouble /= 2.0;
-
- if (buffer.flags & Audio::FLAG_STEREO)
- msDouble /= 2.0;
- msDouble = msDouble / buffer.frequency * 1000.0;
- return (int)msDouble;
+ return buffer.streamLength.msecs();
}
} // End of namespace Saga
diff --git a/engines/saga/sndres.h b/engines/saga/sndres.h
index 9b0eebc834..979c0288f6 100644
--- a/engines/saga/sndres.h
+++ b/engines/saga/sndres.h
@@ -52,8 +52,6 @@ public:
private:
bool load(ResourceContext *context, uint32 resourceId, SoundBuffer &buffer, bool onlyHeader);
- bool loadVocSound(byte *soundResource, size_t soundResourceLength, SoundBuffer &buffer);
- bool loadWavSound(byte *soundResource, size_t soundResourceLength, SoundBuffer &buffer);
ResourceContext *_sfxContext;
ResourceContext *_voiceContext;
diff --git a/engines/saga/sound.cpp b/engines/saga/sound.cpp
index 3408125f73..67be499bc7 100644
--- a/engines/saga/sound.cpp
+++ b/engines/saga/sound.cpp
@@ -63,42 +63,11 @@ SndHandle *Sound::getHandle() {
void Sound::playSoundBuffer(Audio::SoundHandle *handle, const SoundBuffer &buffer, int volume,
sndHandleType handleType, bool loop) {
- Audio::RewindableAudioStream *stream = 0;
-
Audio::Mixer::SoundType soundType = (handleType == kVoiceHandle) ?
Audio::Mixer::kSpeechSoundType : Audio::Mixer::kSFXSoundType;
- if (!buffer.isCompressed) {
- stream = Audio::makeRawStream(buffer.buffer, buffer.size, buffer.frequency, buffer.flags);
- } else {
- Common::SeekableReadStream *memStream = new Common::MemoryReadStream(buffer.buffer, buffer.size, DisposeAfterUse::YES);
-
- switch (buffer.soundType) {
-#ifdef USE_MAD
- case kSoundMP3:
- stream = Audio::makeMP3Stream(memStream, DisposeAfterUse::YES);
- break;
-#endif
-#ifdef USE_VORBIS
- case kSoundOGG:
- stream = Audio::makeVorbisStream(memStream, DisposeAfterUse::YES);
- break;
-#endif
-#ifdef USE_FLAC
- case kSoundFLAC:
- stream = Audio::makeFLACStream(memStream, DisposeAfterUse::YES);
- break;
-#endif
- default:
- // Unknown compression, ignore sample
- delete memStream;
- warning("Unknown compression, ignoring sound");
- break;
- }
- }
-
- if (stream != NULL)
- _mixer->playStream(soundType, handle, Audio::makeLoopingAudioStream(stream, loop ? 0 : 1), -1, volume);
+ if (buffer.stream)
+ _mixer->playStream(soundType, handle, Audio::makeLoopingAudioStream(buffer.stream, loop ? 0 : 1), -1, volume);
}
void Sound::playSound(SoundBuffer &buffer, int volume, bool loop, int resId) {
diff --git a/engines/saga/sound.h b/engines/saga/sound.h
index 15624a9da5..e2163dfb0e 100644
--- a/engines/saga/sound.h
+++ b/engines/saga/sound.h
@@ -27,9 +27,11 @@
#include "common/file.h"
#include "audio/mixer.h"
-#include "audio/decoders/mp3.h"
-#include "audio/decoders/vorbis.h"
-#include "audio/decoders/flac.h"
+#include "audio/timestamp.h"
+
+namespace Audio {
+class RewindableAudioStream;
+}
namespace Saga {
@@ -40,15 +42,8 @@ enum SOUND_FLAGS {
};
struct SoundBuffer {
- uint16 frequency;
- bool isCompressed;
- byte flags;
-
- byte *buffer;
- size_t size;
- size_t originalSize;
- GameSoundTypes soundType;
- size_t fileOffset;
+ Audio::RewindableAudioStream *stream;
+ Audio::Timestamp streamLength;
};
enum sndHandleType {
diff --git a/engines/sci/console.cpp b/engines/sci/console.cpp
index a44c661561..9607a8e66d 100644
--- a/engines/sci/console.cpp
+++ b/engines/sci/console.cpp
@@ -860,14 +860,14 @@ bool Console::cmdVerifyScripts(int argc, const char **argv) {
return true;
}
- Common::List<ResourceId> *resources = _engine->getResMan()->listResources(kResourceTypeScript);
- Common::sort(resources->begin(), resources->end());
- Common::List<ResourceId>::iterator itr = resources->begin();
+ Common::List<ResourceId> resources = _engine->getResMan()->listResources(kResourceTypeScript);
+ Common::sort(resources.begin(), resources.end());
- DebugPrintf("%d SCI1.1-SCI3 scripts found, performing sanity checks...\n", resources->size());
+ DebugPrintf("%d SCI1.1-SCI3 scripts found, performing sanity checks...\n", resources.size());
Resource *script, *heap;
- while (itr != resources->end()) {
+ Common::List<ResourceId>::iterator itr;
+ for (itr = resources.begin(); itr != resources.end(); ++itr) {
script = _engine->getResMan()->findResource(*itr, false);
if (!script)
DebugPrintf("Error: script %d couldn't be loaded\n", itr->getNumber());
@@ -885,12 +885,9 @@ bool Console::cmdVerifyScripts(int argc, const char **argv) {
DebugPrintf("Error: script %d is larger than 64KB (%d bytes)\n",
itr->getNumber(), script->size);
}
-
- ++itr;
}
DebugPrintf("SCI1.1-SCI2.1 script check finished\n");
- delete resources;
return true;
}
@@ -914,9 +911,8 @@ bool Console::cmdShowInstruments(int argc, const char **argv) {
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();
+ Common::List<ResourceId> resources = _engine->getResMan()->listResources(kResourceTypeSound);
+ Common::sort(resources.begin(), resources.end());
int instruments[128];
bool instrumentsSongs[128][1000];
@@ -928,26 +924,21 @@ bool Console::cmdShowInstruments(int argc, const char **argv) {
instrumentsSongs[i][j] = false;
if (songNumber == -1) {
- DebugPrintf("%d sounds found, checking their instrument mappings...\n", resources->size());
+ DebugPrintf("%d sounds found, checking their instrument mappings...\n", resources.size());
DebugPrintf("Instruments:\n");
DebugPrintf("============\n");
}
- SoundResource *sound;
-
- while (itr != resources->end()) {
- if (songNumber >= 0 && itr->getNumber() != songNumber) {
- ++itr;
+ Common::List<ResourceId>::iterator itr;
+ for (itr = resources.begin(); itr != resources.end(); ++itr) {
+ if (songNumber >= 0 && itr->getNumber() != songNumber)
continue;
- }
- sound = new SoundResource(itr->getNumber(), _engine->getResMan(), doSoundVersion);
- int channelFilterMask = sound->getChannelFilterMask(player->getPlayId(), player->hasRhythmChannel());
- SoundResource::Track *track = sound->getTrackByType(player->getPlayId());
+ SoundResource sound(itr->getNumber(), _engine->getResMan(), doSoundVersion);
+ int channelFilterMask = sound.getChannelFilterMask(player->getPlayId(), player->hasRhythmChannel());
+ SoundResource::Track *track = sound.getTrackByType(player->getPlayId());
if (track->digitalChannelNr != -1) {
// Skip digitized sound effects
- delete sound;
- ++itr;
continue;
}
@@ -1027,9 +1018,6 @@ bool Console::cmdShowInstruments(int argc, const char **argv) {
} while (!endOfTrack);
DebugPrintf("\n");
-
- delete sound;
- ++itr;
}
delete parser;
@@ -1069,7 +1057,6 @@ bool Console::cmdShowInstruments(int argc, const char **argv) {
DebugPrintf("\n\n");
}
- delete resources;
return true;
}
@@ -1132,12 +1119,12 @@ bool Console::cmdList(int argc, const char **argv) {
number = atoi(argv[2]);
}
- Common::List<ResourceId> *resources = _engine->getResMan()->listResources(res, number);
- Common::sort(resources->begin(), resources->end());
- Common::List<ResourceId>::iterator itr = resources->begin();
+ Common::List<ResourceId> resources = _engine->getResMan()->listResources(res, number);
+ Common::sort(resources.begin(), resources.end());
int cnt = 0;
- while (itr != resources->end()) {
+ Common::List<ResourceId>::iterator itr;
+ for (itr = resources.begin(); itr != resources.end(); ++itr) {
if (number == -1) {
DebugPrintf("%8i", itr->getNumber());
if (++cnt % 10 == 0)
@@ -1149,10 +1136,8 @@ bool Console::cmdList(int argc, const char **argv) {
if (++cnt % 4 == 0)
DebugPrintf("\n");
}
- ++itr;
}
DebugPrintf("\n");
- delete resources;
}
return true;
@@ -1448,7 +1433,7 @@ bool Console::cmdSaid(int argc, const char **argv) {
_engine->getVocabulary()->dumpParseTree();
_engine->getVocabulary()->parserIsValid = true;
- int ret = said((byte*)spec, true);
+ int ret = said((byte *)spec, true);
DebugPrintf("kSaid: %s\n", (ret == SAID_NO_MATCH ? "No match" : "Match"));
}
@@ -1620,7 +1605,7 @@ bool Console::cmdWindowList(int argc, const char **argv) {
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);
+ HunkTable* hunks = (HunkTable *)segman->getSegmentObj(id);
if (!hunks) {
DebugPrintf("No hunk segment found.\n");
return true;
@@ -1632,7 +1617,7 @@ bool Console::cmdSavedBits(int argc, const char **argv) {
uint16 offset = entries[i].offset;
const Hunk& h = hunks->_table[offset];
if (strcmp(h.type, "SaveBits()") == 0) {
- byte* memoryPtr = (byte*)h.mem;
+ byte* memoryPtr = (byte *)h.mem;
if (memoryPtr) {
DebugPrintf("%04x:%04x:", PRINT_REG(entries[i]));
@@ -1686,7 +1671,7 @@ bool Console::cmdShowSavedBits(int argc, const char **argv) {
SegManager *segman = _engine->_gamestate->_segMan;
SegmentId id = segman->findSegmentByType(SEG_TYPE_HUNK);
- HunkTable* hunks = (HunkTable*)segman->getSegmentObj(id);
+ HunkTable* hunks = (HunkTable *)segman->getSegmentObj(id);
if (!hunks) {
DebugPrintf("No hunk segment found.\n");
return true;
@@ -1876,16 +1861,17 @@ bool Console::segmentInfo(int nr) {
DebugPrintf(" Synonyms: %4d\n", scr->getSynonymsNr());
- if (scr->_localsBlock)
- DebugPrintf(" Locals : %4d in segment 0x%x\n", scr->_localsBlock->_locals.size(), scr->_localsSegment);
+ if (scr->getLocalsCount() > 0)
+ DebugPrintf(" Locals : %4d in segment 0x%x\n", scr->getLocalsCount(), scr->getLocalsSegment());
else
DebugPrintf(" Locals : none\n");
- DebugPrintf(" Objects: %4d\n", scr->_objects.size());
+ ObjMap objects = scr->getObjectMap();
+ DebugPrintf(" Objects: %4d\n", objects.size());
ObjMap::iterator it;
- const ObjMap::iterator end = scr->_objects.end();
- for (it = scr->_objects.begin(); it != end; ++it) {
+ const ObjMap::iterator end = objects.end();
+ for (it = objects.begin(); it != end; ++it) {
DebugPrintf(" ");
// Object header
const Object *obj = _engine->_gamestate->_segMan->getObject(it->_value.getPos());
@@ -2914,12 +2900,11 @@ bool Console::cmdDisassembleAddress(int argc, const char **argv) {
}
void Console::printKernelCallsFound(int kernelFuncNum, bool showFoundScripts) {
- Common::List<ResourceId> *resources = _engine->getResMan()->listResources(kResourceTypeScript);
- Common::sort(resources->begin(), resources->end());
- Common::List<ResourceId>::iterator itr = resources->begin();
+ Common::List<ResourceId> resources = _engine->getResMan()->listResources(kResourceTypeScript);
+ Common::sort(resources.begin(), resources.end());
if (showFoundScripts)
- DebugPrintf("%d scripts found, dissassembling...\n", resources->size());
+ DebugPrintf("%d scripts found, dissassembling...\n", resources.size());
int scriptSegment;
Script *script;
@@ -2927,13 +2912,13 @@ void Console::printKernelCallsFound(int kernelFuncNum, bool showFoundScripts) {
// manager won't be affected by loading and unloading scripts here.
SegManager *customSegMan = new SegManager(_engine->getResMan());
- while (itr != resources->end()) {
+ Common::List<ResourceId>::iterator itr;
+ for (itr = resources.begin(); itr != resources.end(); ++itr) {
// Ignore specific leftover scripts, which require other non-existing scripts
if ((_engine->getGameId() == GID_HOYLE3 && itr->getNumber() == 995) ||
(_engine->getGameId() == GID_KQ5 && itr->getNumber() == 980) ||
(_engine->getGameId() == GID_SLATER && itr->getNumber() == 947) ||
(_engine->getGameId() == GID_MOTHERGOOSE256 && itr->getNumber() == 980)) {
- itr++;
continue;
}
@@ -2942,9 +2927,10 @@ void Console::printKernelCallsFound(int kernelFuncNum, bool showFoundScripts) {
script = customSegMan->getScript(scriptSegment);
// Iterate through all the script's objects
+ ObjMap objects = script->getObjectMap();
ObjMap::iterator it;
- const ObjMap::iterator end = script->_objects.end();
- for (it = script->_objects.begin(); it != end; ++it) {
+ const ObjMap::iterator end = objects.end();
+ for (it = objects.begin(); it != end; ++it) {
const Object *obj = customSegMan->getObject(it->_value.getPos());
const char *objName = customSegMan->getObjectName(it->_value.getPos());
@@ -2976,7 +2962,8 @@ void Console::printKernelCallsFound(int kernelFuncNum, bool showFoundScripts) {
// there is a jump after a ret, we don't stop processing
if (opcode == op_bt || opcode == op_bnt || opcode == op_jmp) {
uint16 curJmpOffset = offset + (uint16)opparams[0];
- if (curJmpOffset > maxJmpOffset)
+ // QFG2 has invalid jumps outside the script buffer in script 260
+ if (curJmpOffset > maxJmpOffset && curJmpOffset < script->getScriptSize())
maxJmpOffset = curJmpOffset;
}
@@ -2990,12 +2977,9 @@ void Console::printKernelCallsFound(int kernelFuncNum, bool showFoundScripts) {
} // for (it = script->_objects.begin(); it != end; ++it)
customSegMan->uninstantiateScript(itr->getNumber());
- ++itr;
}
delete customSegMan;
-
- delete resources;
}
bool Console::cmdFindKernelFunctionCall(int argc, const char **argv) {
diff --git a/engines/sci/detection.cpp b/engines/sci/detection.cpp
index 2d567a7fde..c43849056b 100644
--- a/engines/sci/detection.cpp
+++ b/engines/sci/detection.cpp
@@ -303,29 +303,29 @@ Common::String convertSierraGameId(Common::String sierraId, uint32 *gameFlags, R
if (sierraId == "fp" || sierraId == "gk" || sierraId == "pq4")
demoThreshold = 150;
- Common::ScopedPtr<Common::List<ResourceId> > resources(resMan.listResources(kResourceTypeScript, -1));
- if (resources->size() < demoThreshold) {
+ Common::List<ResourceId> resources = resMan.listResources(kResourceTypeScript, -1);
+ if (resources.size() < demoThreshold) {
*gameFlags |= ADGF_DEMO;
// Crazy Nick's Picks
- if (sierraId == "lsl1" && resources->size() == 34)
+ if (sierraId == "lsl1" && resources.size() == 34)
return "cnick-lsl";
- if (sierraId == "sq4" && resources->size() == 34)
+ if (sierraId == "sq4" && resources.size() == 34)
return "cnick-sq";
- if (sierraId == "hoyle3" && resources->size() == 42)
+ if (sierraId == "hoyle3" && resources.size() == 42)
return "cnick-kq";
- if (sierraId == "rh budget" && resources->size() == 39)
+ if (sierraId == "rh budget" && resources.size() == 39)
return "cnick-longbow";
// TODO: cnick-laurabow (the name of the game object contains junk)
// Handle Astrochicken 1 (SQ3) and 2 (SQ4)
- if (sierraId == "sq3" && resources->size() == 20)
+ if (sierraId == "sq3" && resources.size() == 20)
return "astrochicken";
if (sierraId == "sq4")
return "msastrochicken";
}
- if (sierraId == "torin" && resources->size() == 226) // Torin's Passage demo
+ if (sierraId == "torin" && resources.size() == 226) // Torin's Passage demo
*gameFlags |= ADGF_DEMO;
for (const OldNewIdTableEntry *cur = s_oldNewTable; cur->oldId[0]; ++cur) {
@@ -350,7 +350,7 @@ Common::String convertSierraGameId(Common::String sierraId, uint32 *gameFlags, R
return "qfg4";
// qfg4 demo has less than 50 scripts
- if (resources->size() < 50)
+ if (resources.size() < 50)
return "qfg4";
// Otherwise it's qfg3
@@ -373,7 +373,7 @@ static ADGameDescription s_fallbackDesc = {
Common::UNK_LANG,
Common::kPlatformPC,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO0()
};
static char s_fallbackGameIdBuf[256];
@@ -435,7 +435,7 @@ const ADGameDescription *SciMetaEngine::fallbackDetect(const FileMap &allFiles,
s_fallbackDesc.flags = ADGF_NO_FLAGS;
s_fallbackDesc.platform = Common::kPlatformPC; // default to PC platform
s_fallbackDesc.gameid = "sci";
- s_fallbackDesc.guioptions = GUIO1(GUIO_NONE);
+ s_fallbackDesc.guioptions = GUIO0();
if (allFiles.contains("resource.map") || allFiles.contains("Data1")
|| allFiles.contains("resmap.001") || allFiles.contains("resmap.001")) {
diff --git a/engines/sci/detection_tables.h b/engines/sci/detection_tables.h
index 4b1f36cda0..63eda1c348 100644
--- a/engines/sci/detection_tables.h
+++ b/engines/sci/detection_tables.h
@@ -42,7 +42,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "f3d1be7752d30ba60614533d531e2e98", 474},
{"resource.001", 0, "6fd05926c2199af0af6f72f90d0d7260", 126895},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformPC, 0, GUIO1(GUIO_NOSPEECH) },
+ Common::EN_ANY, Common::kPlatformPC, 0, GUIO2(GUIO_NOSPEECH, GUIO_EGAUNDITHER) },
// Castle of Dr. Brain - English Amiga (from www.back2roots.org)
// Executable scanning reports "1.005.000"
@@ -98,7 +98,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.005", 0, "8a5ed3ba96e2eaf18e36fedfaab89419", 297838},
{"resource.006", 0, "dceed92e709cad1bd9582809a235b0a0", 266682},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformPC, 0, GUIO1(GUIO_NOSPEECH) },
+ Common::EN_ANY, Common::kPlatformPC, 0, GUIO2(GUIO_NOSPEECH, GUIO_EGAUNDITHER) },
// Castle of Dr. Brain - English DOS 3.5" Floppy EGA (from nozomi77, bug report #3405307)
{"castlebrain", "EGA", {
@@ -108,7 +108,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.002", 0, "de2f182529efaad2c4b510b452ab77ac", 633662},
{"resource.003", 0, "38b4b37febc6b4f5061c461a283df148", 430388},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformPC, 0, GUIO1(GUIO_NOSPEECH) },
+ Common::EN_ANY, Common::kPlatformPC, 0, GUIO2(GUIO_NOSPEECH, GUIO_EGAUNDITHER) },
// Castle of Dr. Brain - English DOS Floppy (from jvprat)
// Executable scanning reports "1.000.044", Floppy label reports "1.0, 10.30.91", VERSION file reports "1.000"
@@ -160,7 +160,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "39485580d34a72997f3d5b3aba4d24f1", 426},
{"resource.001", 0, "11391434f41c834090d7a1e9488ce936", 129739},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformPC, 0, GUIO1(GUIO_NOSPEECH) },
+ Common::EN_ANY, Common::kPlatformPC, 0, GUIO2(GUIO_NOSPEECH, GUIO_EGAUNDITHER) },
// Christmas Card 1990: The Seasoned Professional - English DOS (16 Colors)
// SCI interpreter version 1.000.172
@@ -198,7 +198,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.004", 0, "8613c45fc771d658e5a505b9a4a54f31", 713382},
{"resource.005", 0, "605b67a9ef199a9bb015745e7c004cf4", 478384},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO1(GUIO_NOSPEECH) },
+ Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO2(GUIO_NOSPEECH, GUIO_EGAUNDITHER) },
// Codename: Iceman - English DOS Non-Interactive Demo
// Executable scanning reports "0.000.685"
@@ -206,7 +206,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "782974f29d8a824782d2d4aea39964e3", 1056},
{"resource.001", 0, "d4b75e280d1c3a97cfef1b0bebff387c", 573647},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO1(GUIO_NOSPEECH) },
+ Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO2(GUIO_NOSPEECH, GUIO_EGAUNDITHER) },
// Codename: Iceman - English DOS (from jvprat)
// Executable scanning reports "0.000.685", Floppy label reports "1.033, 6.8.90", VERSION file reports "1.033"
@@ -219,7 +219,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.003", 0, "d97a96f1ab91b41cf46a02cc89b0a04e", 624303},
{"resource.004", 0, "8613c45fc771d658e5a505b9a4a54f31", 670883},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformPC, 0, GUIO1(GUIO_NOSPEECH) },
+ Common::EN_ANY, Common::kPlatformPC, 0, GUIO2(GUIO_NOSPEECH, GUIO_EGAUNDITHER) },
// Codename: Iceman - English DOS (from FRG)
// SCI interpreter version 0.000.668
@@ -231,7 +231,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.003", 0, "dc7c5280e7acfaffe6ef2a6c963c5f94", 622118},
{"resource.004", 0, "64f342463f6f35ba71b3509ef696ae3f", 669188},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformPC, 0, GUIO1(GUIO_NOSPEECH) },
+ Common::EN_ANY, Common::kPlatformPC, 0, GUIO2(GUIO_NOSPEECH, GUIO_EGAUNDITHER) },
// Codename: Iceman - English DOS (supplied by ssburnout in bug report #3049193)
// 1.022 9x5.25" (label: Int#0.000.668)
@@ -246,7 +246,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.006", 0, "08050329aa113a9f14ed99cbfe3536ec", 232942},
{"resource.007", 0, "64f342463f6f35ba71b3509ef696ae3f", 267811},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformPC, 0, GUIO1(GUIO_NOSPEECH) },
+ Common::EN_ANY, Common::kPlatformPC, 0, GUIO2(GUIO_NOSPEECH, GUIO_EGAUNDITHER) },
// Codename: Iceman - English DOS 1.023 (from abevi, bug report #2612718)
{"iceman", "", {
@@ -275,7 +275,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.005", 0, "c6e551bdc24f0acc193159038d4ca767", 605882},
{"resource.006", 0, "8f880a536908ab496bbc552f7f5c3738", 585255},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO1(GUIO_NOSPEECH) },
+ Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO2(GUIO_NOSPEECH, GUIO_EGAUNDITHER) },
// Conquests of Camelot - English DOS Non-Interactive Demo
// SCI interpreter version 0.000.668
@@ -283,7 +283,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "f4cd75c15be75e04cdca3acda2c0b0ea", 468},
{"resource.001", 0, "4930708722f34bfbaa4945fb08f55f61", 232523},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO1(GUIO_NOSPEECH) },
+ Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO2(GUIO_NOSPEECH, GUIO_EGAUNDITHER) },
// Conquests of Camelot - English DOS (from jvprat)
// Executable scanning reports "0.000.685", Floppy label reports "1.001, 0.000.685", VERSION file reports "1.001.000"
@@ -295,7 +295,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.003", 0, "8e1a3a8c588007404b532b8dfacc1460", 723712},
{"resource.004", 0, "8e1a3a8c588007404b532b8dfacc1460", 729143},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformPC, 0, GUIO1(GUIO_NOSPEECH) },
+ Common::EN_ANY, Common::kPlatformPC, 0, GUIO2(GUIO_NOSPEECH, GUIO_EGAUNDITHER) },
// Conquests of Camelot - English DOS
// SCI interpreter version 0.000.685
@@ -309,7 +309,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.006", 0, "8e1a3a8c588007404b532b8dfacc1460", 332446},
{"resource.007", 0, "8e1a3a8c588007404b532b8dfacc1460", 358182},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformPC, 0, GUIO1(GUIO_NOSPEECH) },
+ Common::EN_ANY, Common::kPlatformPC, 0, GUIO2(GUIO_NOSPEECH, GUIO_EGAUNDITHER) },
// Conquests of the Longbow - English Amiga (from www.back2roots.org)
// Executable scanning reports "1.005.001"
@@ -378,7 +378,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.004", 0, "b7bb35c027bb424ecefcd122768e5e60", 705631},
{"resource.005", 0, "58942b1aa6d6ffeb66e9f8897fd4435f", 469243},
{"resource.006", 0, "8c767b3939add63d11274065e46aad04", 713158},
- AD_LISTEND}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO1(GUIO_NOSPEECH) },
+ AD_LISTEND}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO2(GUIO_NOSPEECH, GUIO_EGAUNDITHER) },
// Conquests of the Longbow DOS 1.0 EGA (4 x 5.25" disks)
// Provided by ssburnout in bug report #3046802
@@ -388,7 +388,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.001", 0, "76c729e563809170e6cc8b2f3f6cf0a4", 1196133},
{"resource.002", 0, "8c767b3939add63d11274065e46aad04", 1152478},
{"resource.003", 0, "7025b87e735b1df3f0e9488a621f4333", 1171439},
- AD_LISTEND}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO1(GUIO_NOSPEECH) },
+ AD_LISTEND}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO2(GUIO_NOSPEECH, GUIO_EGAUNDITHER) },
// Conquests of the Longbow - English DOS Non-Interactive Demo
// SCI interpreter version 1.000.510
@@ -427,7 +427,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "a4b73d5d2b55bdb6e44345e99c8fbdd0", 4804},
{"resource.000", 0, "d908dbef56816ac6c60dd145fdeafb2b", 3536046},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformPC, ADGF_CD, GUIO1(GUIO_NONE) },
+ Common::EN_ANY, Common::kPlatformPC, ADGF_CD, GUIO0() },
// Eco Quest - English DOS CD 1.1
// SCI interpreter version 1.001.064
@@ -541,7 +541,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "d46b282f228a67ba13bd4b4009e95f8f", 6058},
{"resource.000", 0, "ee3c64ffff0ba9fb08bea2624631c598", 5490246},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformPC, ADGF_CD, GUIO1(GUIO_NONE) },
+ Common::EN_ANY, Common::kPlatformPC, ADGF_CD, GUIO0() },
// Freddy Pharkas - English DOS Floppy (updated information from markcoolio in bug reports #2723773 and #2724720)
// Executable scanning reports "1.cfs.081"
@@ -583,7 +583,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.003", 0, "05acdc256c742e79c50b9fe7ec2cc898", 863310},
{"resource.msg", 0, "45b5bf74933ac3727e4cc844446dc052", 796156},
AD_LISTEND},
- Common::ES_ESP, Common::kPlatformPC, ADGF_CD, GUIO1(GUIO_NONE) },
+ Common::ES_ESP, Common::kPlatformPC, ADGF_CD, GUIO0() },
// Freddy Pharkas - Spanish DOS (from jvprat)
// Executable scanning reports "1.cfs.081", VERSION file reports "1.000, March 30, 1995"
@@ -601,7 +601,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "a62a7eae85dd1e6b07f39662b278437e", 1918},
{"resource.000", 0, "4962a3c4dd44e36e78ea4a7a374c2220", 957382},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO1(GUIO_NONE) },
+ Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO0() },
// Freddy Pharkas - English Macintosh
{"freddypharkas", "", {
@@ -616,7 +616,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "7ee6859ef74314f6d91938c3595348a9", 282},
{"resource.001", 0, "f1e680095424e31f7fae1255d36bacba", 40692},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformPC, 0, GUIO1(GUIO_NOSPEECH) },
+ Common::EN_ANY, Common::kPlatformPC, 0, GUIO2(GUIO_NOSPEECH, GUIO_EGAUNDITHER) },
// Gabriel Knight - English DOS CD Demo
// SCI interpreter version 1.001.092
@@ -624,7 +624,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "39645952ae0ed8072c7e838f31b75464", 2490},
{"resource.000", 0, "eb3ed7477ca4110813fe1fcf35928561", 1718450},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO1(GUIO_NONE) },
+ Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO0() },
#ifdef ENABLE_SCI32
// Gabriel Knight - English DOS Floppy
@@ -665,7 +665,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 | ADGF_UNSTABLE, GUIO1(GUIO_NONE) },
+ Common::EN_ANY, Common::kPlatformPC, ADGF_CD | ADGF_UNSTABLE, GUIO0() },
// Gabriel Knight - English Windows CD (from jvprat)
// Executable scanning reports "2.000.000", VERSION file reports "01.100.000"
@@ -673,7 +673,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "372d059f75856afa6d73dd84cbb8913d", 10996},
{"resource.000", 0, "69b7516962510f780d38519cc15fcc7c", 12581736},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformWindows, ADGF_CD | ADGF_UNSTABLE, GUIO1(GUIO_NONE) },
+ Common::EN_ANY, Common::kPlatformWindows, ADGF_CD | ADGF_UNSTABLE, GUIO1(GUIO_NOASPECT) },
// Gabriel Knight - German DOS CD (from Tobis87)
// SCI interpreter version 2.000.000
@@ -681,7 +681,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 | ADGF_UNSTABLE, GUIO1(GUIO_NONE) },
+ Common::DE_DEU, Common::kPlatformPC, ADGF_CD | ADGF_UNSTABLE, GUIO0() },
// Gabriel Knight - Spanish DOS CD (from jvprat)
// Executable scanning reports "2.000.000", VERSION file reports "1.000.000, April 13, 1995"
@@ -689,7 +689,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 | ADGF_UNSTABLE, GUIO1(GUIO_NONE) },
+ Common::ES_ESP, Common::kPlatformPC, ADGF_CD | ADGF_UNSTABLE, GUIO0() },
// Gabriel Knight - French DOS CD (from Hkz)
// VERSION file reports "1.000.000, May 3, 1994"
@@ -697,7 +697,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 | ADGF_UNSTABLE, GUIO1(GUIO_NONE) },
+ Common::FR_FRA, Common::kPlatformPC, ADGF_CD | ADGF_UNSTABLE, GUIO0() },
// Gabriel Knight - German Windows CD (from Tobis87)
// SCI interpreter version 2.000.000
@@ -705,7 +705,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "a7d3e55114c65647310373cb390815ba", 11392},
{"resource.000", 0, "091cf08910780feabc56f8551b09cb36", 13400497},
AD_LISTEND},
- Common::DE_DEU, Common::kPlatformWindows, ADGF_CD | ADGF_UNSTABLE, GUIO1(GUIO_NONE) },
+ Common::DE_DEU, Common::kPlatformWindows, ADGF_CD | ADGF_UNSTABLE, GUIO1(GUIO_NOASPECT) },
// Gabriel Knight - Spanish Windows CD (from jvprat)
// Executable scanning reports "2.000.000", VERSION file reports "1.000.000, April 13, 1995"
@@ -713,7 +713,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "7cb6e9bba15b544ec7a635c45bde9953", 11404},
{"resource.000", 0, "091cf08910780feabc56f8551b09cb36", 13381599},
AD_LISTEND},
- Common::ES_ESP, Common::kPlatformWindows, ADGF_CD | ADGF_UNSTABLE, GUIO1(GUIO_NONE) },
+ Common::ES_ESP, Common::kPlatformWindows, ADGF_CD | ADGF_UNSTABLE, GUIO1(GUIO_NOASPECT) },
// Gabriel Knight - English Macintosh
{"gk1", "", {
@@ -722,7 +722,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"Data3", 0, "f25068b408b09275d8b698866462f578", 3677599},
{"Data4", 0, "1cceebbe411b26c860a74f91c337fdf3", 3230086},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformMacintosh, ADGF_MACRESFORK | ADGF_UNSTABLE, GUIO1(GUIO_NONE) },
+ Common::EN_ANY, Common::kPlatformMacintosh, ADGF_MACRESFORK | ADGF_UNSTABLE, GUIO1(GUIO_NOASPECT) },
// Gabriel Knight 2 - English Windows Non-Interactive Demo
// Executable scanning reports "2.100.002"
@@ -730,7 +730,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "e0effce11c4908f4b91838741716c83d", 1351},
{"resource.000", 0, "d04cfc7f04b6f74d13025378be49ec2b", 4640330},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformWindows, ADGF_DEMO | ADGF_UNSTABLE, GUIO1(GUIO_NOSPEECH) },
+ Common::EN_ANY, Common::kPlatformWindows, ADGF_DEMO | ADGF_UNSTABLE, GUIO2(GUIO_NOSPEECH, GUIO_NOASPECT) },
// Gabriel Knight 2 - English DOS (GOG version) - ressci.* merged in ressci.000
// using Enrico Rolfi's HD/DVD installer: http://gkpatches.vogons.zetafleet.com/
@@ -738,7 +738,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resmap.000", 0, "b996fa1e57389a1e179a00a0049de1f4", 8110},
{"ressci.000", 0, "a19fc3604c6e5407abcf03d59ee87217", 168522221},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformPC, ADGF_UNSTABLE, GUIO1(GUIO_NONE) },
+ Common::EN_ANY, Common::kPlatformPC, ADGF_UNSTABLE, GUIO1(GUIO_NOASPECT) },
// Gabriel Knight 2 - English DOS (from jvprat)
// Executable scanning reports "2.100.002", VERSION file reports "1.1"
@@ -756,7 +756,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resmap.006", 0, "ce9359037277b7d7976da185c2fa0aad", 2977},
{"ressci.006", 0, "8e44e03890205a7be12f45aaba9644b4", 60659424},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformPC, ADGF_UNSTABLE, GUIO1(GUIO_NONE) },
+ Common::EN_ANY, Common::kPlatformPC, ADGF_UNSTABLE, GUIO1(GUIO_NOASPECT) },
// Gabriel Knight 2 - French DOS (6-CDs Sierra Originals reedition)
// Executable scanning reports "2.100.002", VERSION file reports "1.0"
@@ -774,7 +774,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resmap.006", 0, "11b2e722170b8c93fdaa5428e2c7676f", 3001},
{"ressci.006", 0, "4037d941aec39d2e654e20960429aefc", 60568486},
AD_LISTEND},
- Common::FR_FRA, Common::kPlatformPC, ADGF_UNSTABLE, GUIO1(GUIO_NONE) },
+ Common::FR_FRA, Common::kPlatformPC, ADGF_UNSTABLE, GUIO1(GUIO_NOASPECT) },
// Gabriel Knight 2 - English Macintosh
// NOTE: This only contains disc 1 files (as well as the persistent file:
@@ -786,7 +786,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"Data4", 0, "8b843c62eb53136a855d6e0087e3cb0d", 5889553},
{"Data5", 0, "f9fcf9ab2eb13b2125c33a1cda03a093", 14349984},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformMacintosh, ADGF_MACRESFORK | ADGF_UNSTABLE, GUIO1(GUIO_NONE) },
+ Common::EN_ANY, Common::kPlatformMacintosh, ADGF_MACRESFORK | ADGF_UNSTABLE, GUIO1(GUIO_NOASPECT) },
#endif // ENABLE_SCI32
@@ -808,7 +808,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.002", 0, "e0dd44069a62a463fd124974b915f10d", 342309},
{"resource.003", 0, "e0dd44069a62a463fd124974b915f10d", 328912},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformPC, 0, GUIO1(GUIO_NOSPEECH) },
+ Common::EN_ANY, Common::kPlatformPC, 0, GUIO2(GUIO_NOSPEECH, GUIO_EGAUNDITHER) },
// Hoyle 1 - English DOS (supplied by merkur in bug report #2719227)
// SCI interpreter version 0.000.530
@@ -816,14 +816,14 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "1034a218943d12f1f36e753fa10c95b8", 4386},
{"resource.001", 0, "e0dd44069a62a463fd124974b915f10d", 518308},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformPC, 0, GUIO1(GUIO_NOSPEECH) },
+ Common::EN_ANY, Common::kPlatformPC, 0, GUIO2(GUIO_NOSPEECH, GUIO_EGAUNDITHER) },
// Hoyle 1 3.5' - English DOS (supplied by eddydrama in bug report #3052366 and dinnerx in bug report #3090841)
{"hoyle1", "", {
{"resource.map", 0, "0af9a3dcd72a091960de070432e1f524", 4386},
{"resource.001", 0, "e0dd44069a62a463fd124974b915f10d", 518127},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformPC, 0, GUIO1(GUIO_NOSPEECH) },
+ Common::EN_ANY, Common::kPlatformPC, 0, GUIO2(GUIO_NOSPEECH, GUIO_EGAUNDITHER) },
#if 0 // TODO: unknown if these files are corrupt
// Hoyle 1 - English Amiga (from www.back2roots.org)
@@ -843,7 +843,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.001", 0, "8f2dd70abe01112eca464cda818b5eb6", 98138},
{"resource.002", 0, "8f2dd70abe01112eca464cda818b5eb6", 196631},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformPC, 0, GUIO1(GUIO_NOSPEECH) },
+ Common::EN_ANY, Common::kPlatformPC, 0, GUIO2(GUIO_NOSPEECH, GUIO_EGAUNDITHER) },
// Hoyle 2 - English DOS (supplied by ssburnout in bug report #3049193)
// 1.000.011 1x3.5" (label:Int#6.21.90)
@@ -851,7 +851,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "db0ba08b953e9904a4960ad99cd29c20", 1356},
{"resource.001", 0, "8f2dd70abe01112eca464cda818b5eb6", 216315},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformPC, 0, GUIO1(GUIO_NOSPEECH) },
+ Common::EN_ANY, Common::kPlatformPC, 0, GUIO2(GUIO_NOSPEECH, GUIO_EGAUNDITHER) },
// Hoyle 2 - English Amiga (from www.back2roots.org)
// Executable scanning reports "1.002.032"
@@ -918,7 +918,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.000", 0, "6ef28cac094dcd97fdb461662ead6f92", 319905},
{"resource.001", 0, "0a98a268ee99b92c233a0d7187c1f0fa", 526438},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformPC, 0, GUIO1(GUIO_NOSPEECH) },
+ Common::EN_ANY, Common::kPlatformPC, 0, GUIO2(GUIO_NOSPEECH, GUIO_EGAUNDITHER) },
// Hoyle 4 (Hoyle Classic Card Games) - English DOS Demo
{"hoyle4", "Demo", {
@@ -959,14 +959,14 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.001", 0, "bac3ec6cb3e3920984ab0f32becf5163", 202105},
{"resource.002", 0, "b86daa3ba2784d1502da881eedb80d9b", 341771},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformPC, 0, GUIO1(GUIO_NOSPEECH) },
+ Common::EN_ANY, Common::kPlatformPC, 0, GUIO2(GUIO_NOSPEECH, GUIO_EGAUNDITHER) },
// Jones in the Fast Lane EGA - English DOS (supplied by EddyDrama in bug report #3038761)
{"jones", "EGA", {
{"resource.map", 0, "8e92cf319180cc8b5b87b2ce93a4fe22", 1602},
{"resource.001", 0, "bac3ec6cb3e3920984ab0f32becf5163", 511528},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformPC, 0, GUIO1(GUIO_NOSPEECH) },
+ Common::EN_ANY, Common::kPlatformPC, 0, GUIO2(GUIO_NOSPEECH, GUIO_EGAUNDITHER) },
// Jones in the Fast Lane VGA - English DOS
// SCI interpreter version 1.000.172
@@ -990,7 +990,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "459f5b04467bc2107aec02f5c4b71b37", 4878},
{"resource.001", 0, "3876da2ce16fb7dea2f5d943d946fa84", 1652150},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformPC, ADGF_CD, GUIO1(GUIO_NONE) },
+ Common::EN_ANY, Common::kPlatformPC, ADGF_CD, GUIO0() },
// Jones in the Fast Lane - English DOS CD
// Same entry as the DOS version above. This one is used for the alternate
@@ -1019,7 +1019,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "59b13619078bd47011421468959ee5d4", 954},
{"resource.001", 0, "4cfb9040db152868f7cb6a1e8151c910", 296555},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO1(GUIO_NOSPEECH) },
+ Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO2(GUIO_NOSPEECH, GUIO_EGAUNDITHER) },
// King's Quest 1 SCI Remake - English DOS (from the King's Quest Collection)
// Executable scanning reports "S.old.010", VERSION file reports "1.000.051"
@@ -1030,7 +1030,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.002", 0, "fed9e0072ffd511d248674e60dee2099", 714062},
{"resource.003", 0, "fed9e0072ffd511d248674e60dee2099", 717478},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformPC, 0, GUIO1(GUIO_NOSPEECH) },
+ Common::EN_ANY, Common::kPlatformPC, 0, GUIO2(GUIO_NOSPEECH, GUIO_EGAUNDITHER) },
// King's Quest 1 SCI Remake - English DOS (supplied by ssburnout in bug report #3049193)
// 1.000.051 9x5.25" (label: INT#9.19.90)
@@ -1057,7 +1057,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.003", 0, "fd16c9c223f7dc5b65f06447615224ff", 683016},
{"resource.004", 0, "3fac034c7d130e055d05bc43a1f8d5f8", 549993},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO1(GUIO_NOSPEECH) },
+ Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO2(GUIO_NOSPEECH, GUIO_EGAUNDITHER) },
// King's Quest 4 - English DOS Non-Interactive Demo
// Executable scanning reports "0.000.494"
@@ -1065,7 +1065,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "992ac7cc31d3717fe53818a9bb6d1dae", 594},
{"resource.001", 0, "143e1c14f15ad0fbfc714f648a65f661", 205330},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO1(GUIO_NOSPEECH) },
+ Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO2(GUIO_NOSPEECH, GUIO_EGAUNDITHER) },
// King's Quest 4 - English DOS (original boxed release, 3 1/2" disks)
// SCI interpreter version 0.000.247
@@ -1076,7 +1076,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.003", 0, "851a62d00972dc4002f472cc0d84e71d", 683145},
{"resource.004", 0, "851a62d00972dc4002f472cc0d84e71d", 649441},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformPC, 0, GUIO1(GUIO_NOSPEECH) },
+ Common::EN_ANY, Common::kPlatformPC, 0, GUIO2(GUIO_NOSPEECH, GUIO_EGAUNDITHER) },
// King's Quest 4 - English DOS (from the King's Quest Collection)
// Executable scanning reports "0.000.502"
@@ -1088,7 +1088,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.003", 0, "77615c595388acf3d1df8e107bfb6b52", 707591},
{"resource.004", 0, "77615c595388acf3d1df8e107bfb6b52", 479562},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformPC, 0, GUIO1(GUIO_NOSPEECH) },
+ Common::EN_ANY, Common::kPlatformPC, 0, GUIO2(GUIO_NOSPEECH, GUIO_EGAUNDITHER) },
// King's Quest 4 - English DOS (supplied by ssburnout in bug report #3049193)
// 1.006.003 8x5.25" (label: Int.#0.000.502)
@@ -1102,7 +1102,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.006", 0, "6db7de6f93c6ea62dca78abee677f8c0", 324789},
{"resource.007", 0, "6db7de6f93c6ea62dca78abee677f8c0", 334441},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformPC, 0, GUIO1(GUIO_NOSPEECH) },
+ Common::EN_ANY, Common::kPlatformPC, 0, GUIO2(GUIO_NOSPEECH, GUIO_EGAUNDITHER) },
// King's Quest 4 - English DOS
// SCI interpreter version 0.000.274
@@ -1116,7 +1116,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.006", 0, "851a62d00972dc4002f472cc0d84e71d", 333777},
{"resource.007", 0, "851a62d00972dc4002f472cc0d84e71d", 341038},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformPC, 0, GUIO1(GUIO_NOSPEECH) },
+ Common::EN_ANY, Common::kPlatformPC, 0, GUIO2(GUIO_NOSPEECH, GUIO_EGAUNDITHER) },
// King's Quest 4 - English DOS
// SCI interpreter version 0.000.253
@@ -1130,7 +1130,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.006", 0, "0c8566848a76eea19a6d6220914030a7", 337288},
{"resource.007", 0, "0c8566848a76eea19a6d6220914030a7", 343882},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformPC, 0, GUIO1(GUIO_NOSPEECH) },
+ Common::EN_ANY, Common::kPlatformPC, 0, GUIO2(GUIO_NOSPEECH, GUIO_EGAUNDITHER) },
// King's Quest 4 - English Atari ST (double-sided diskettes)
// Game version 1.003.006 (January 12, 1989)
@@ -1143,7 +1143,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.003", 0, "a3cdb4848fb859fdd302976fff56490f", 705074},
{"resource.004", 0, "a3cdb4848fb859fdd302976fff56490f", 478366},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformAtariST, 0, GUIO1(GUIO_NOSPEECH) },
+ Common::EN_ANY, Common::kPlatformAtariST, 0, GUIO2(GUIO_NOSPEECH, GUIO_EGAUNDITHER) },
// King's Quest 5 - English Amiga (from www.back2roots.org)
// Executable scanning reports "1.004.018"
@@ -1201,7 +1201,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.000", 0, "449471bfd77be52f18a3773c7f7d843d", 571368},
{"resource.001", 0, "b45a581ff8751e052c7e364f58d3617f", 16800210},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformPC, ADGF_CD, GUIO1(GUIO_NONE) },
+ Common::EN_ANY, Common::kPlatformPC, ADGF_CD, GUIO0() },
// King's Quest 5 - English DOS CD (from the King's Quest Collection)
// Executable scanning reports "x.yyy.zzz", VERSION file reports "1.000.052"
@@ -1259,7 +1259,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.006", 0, "698c698570cde9015e4d51eb8d2e9db1", 666527},
{"resource.007", 0, "703d8df30e89541af337d7706540d5c4", 541743},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformPC, 0, GUIO1(GUIO_NOSPEECH) },
+ Common::EN_ANY, Common::kPlatformPC, 0, GUIO2(GUIO_NOSPEECH, GUIO_EGAUNDITHER) },
// King's Quest 5 EGA 1.2M disk version (from LordHoto)
// VERSION file reports "0.000.055"
@@ -1271,7 +1271,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "53206afb4fd73871a484e83acab80f31", 7608},
{"resource.004", 0, "83568edf7fde18b3eed988bc5d22ceb1", 1188053},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformPC, 0, GUIO1(GUIO_NOSPEECH) },
+ Common::EN_ANY, Common::kPlatformPC, 0, GUIO2(GUIO_NOSPEECH, GUIO_EGAUNDITHER) },
// King's Quest 5 EGA (supplied by omer_mor in bug report #3035421)
// VERSION file reports "0.000.062"
@@ -1286,7 +1286,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.006", 0, "698c698570cde9015e4d51eb8d2e9db1", 666541},
{"resource.007", 0, "703d8df30e89541af337d7706540d5c4", 541762},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformPC, 0, GUIO1(GUIO_NOSPEECH) },
+ Common::EN_ANY, Common::kPlatformPC, 0, GUIO2(GUIO_NOSPEECH, GUIO_EGAUNDITHER) },
// King's Quest V DOS 0.000.062 EGA (5 x 5.25" disks)
// Supplied by ssburnout in bug report #3046780
@@ -1298,7 +1298,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.003", 0, "3cca5b2dae8afe94532edfdc98d7edbe", 1092325},
{"resource.004", 0, "8e5c1bc4d738cf7316ff506f59d265e2", 1187803},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformPC, 0, GUIO1(GUIO_NOSPEECH) },
+ Common::EN_ANY, Common::kPlatformPC, 0, GUIO2(GUIO_NOSPEECH, GUIO_EGAUNDITHER) },
// King's Quest 5 - German DOS Floppy (supplied by markcoolio in bug report #2727101, also includes english language)
// SCI interpreter version 1.000.060
@@ -1382,7 +1382,13 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.000", 0, "71afd220d46bde1109c58e6acc0f3a01", 469094},
{"resource.001", 0, "72a569f46f1abf2d9d2b1526ad3799c3", 12808839},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformFMTowns, 0, GUIO1(GUIO_NONE) },
+ Common::EN_ANY, Common::kPlatformFMTowns, 0, GUIO2(GUIO_NOASPECT, GUIO_MIDITOWNS) },
+ {"kq5", "", {
+ {"resource.map", 0, "20c7cd248ff1a349ed354568eebd972b", 12733},
+ {"resource.000", 0, "71afd220d46bde1109c58e6acc0f3a01", 469094},
+ {"resource.001", 0, "72a569f46f1abf2d9d2b1526ad3799c3", 12808839},
+ AD_LISTEND},
+ Common::JA_JPN, Common::kPlatformFMTowns, 0, GUIO2(GUIO_NOASPECT, GUIO_MIDITOWNS) },
// King's Quest 5 - Japanese PC-98 Floppy 0.000.015 (supplied by omer_mor in bug report #3073583)
{"kq5", "", {
@@ -1394,7 +1400,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.004", 0, "e114ce8f884601c43308fb5cbbea4874", 1174129},
{"resource.005", 0, "349ad9438172265d00680075c5a988d0", 1019669},
AD_LISTEND},
- Common::JA_JPN, Common::kPlatformPC98, ADGF_ADDENGLISH, GUIO1(GUIO_NOSPEECH) },
+ Common::JA_JPN, Common::kPlatformPC98, ADGF_ADDENGLISH, GUIO2(GUIO_NOSPEECH, GUIO_NOASPECT) },
// King's Quest 6 - English DOS Non-Interactive Demo
// Executable scanning reports "1.001.055", VERSION file reports "1.000.000"
@@ -1431,7 +1437,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "7a550ebfeae2575ca00d47703a6a774c", 9215},
{"resource.000", 0, "233394a5f33b475ae5975e7e9a420865", 8376352},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformPC, ADGF_CD, GUIO1(GUIO_NONE) },
+ Common::EN_ANY, Common::kPlatformPC, ADGF_CD, GUIO0() },
// King's Quest 6 - English Windows CD (from the King's Quest Collection)
// Executable scanning reports "1.cfs.158", VERSION file reports "1.034 9/11/94 - KQ6 version 1.000.00G"
@@ -1440,7 +1446,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "7a550ebfeae2575ca00d47703a6a774c", 9215},
{"resource.000", 0, "233394a5f33b475ae5975e7e9a420865", 8376352},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformWindows, ADGF_CD, GUIO1(GUIO_NONE) },
+ Common::EN_ANY, Common::kPlatformWindows, ADGF_CD, GUIO1(GUIO_NOASPECT) },
// King's Quest 6 - Spanish DOS CD (from jvprat)
// Executable scanning reports "1.cfs.158", VERSION file reports "1.000.000, July 5, 1994"
@@ -1450,7 +1456,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.000", 0, "4da3ad5868a775549a7cc4f72770a58e", 8537260},
{"resource.msg", 0, "41eed2d3893e1ca6c3695deba4e9d2e8", 267102},
AD_LISTEND},
- Common::ES_ESP, Common::kPlatformPC, ADGF_CD, GUIO1(GUIO_NONE) },
+ Common::ES_ESP, Common::kPlatformPC, ADGF_CD, GUIO0() },
// King's Quest 6 - English Macintosh Floppy
// VERSION file reports "1.0"
@@ -1469,7 +1475,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.000", 0, "4948e4e1506f1e1c4e1d47abfa06b7f8", 204385195},
{"resource.map", 0, "40ccafb2195301504eba2e4f4f2c7f3d", 18925},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO1(GUIO_NOSPEECH) },
+ Common::EN_ANY, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO2(GUIO_NOSPEECH, GUIO_NOASPECT) },
// King's Quest 7 - English Windows (from the King's Quest Collection)
// Executable scanning reports "2.100.002", VERSION file reports "1.4"
@@ -1477,7 +1483,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "2be9ab94429c721af8e05c507e048a15", 18697},
{"resource.000", 0, "eb63ea3a2c2469dc2d777d351c626404", 203882535},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO1(GUIO_NOSPEECH) },
+ Common::EN_ANY, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO2(GUIO_NOSPEECH, GUIO_NOASPECT) },
// King's Quest 7 - English DOS (from FRG)
// SCI interpreter version 2.100.002, VERSION file reports "2.00b"
@@ -1485,7 +1491,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "8676b0fbbd7362989a029fe72fea14c6", 18709},
{"resource.000", 0, "51c1ead1163e19a2de8f121c39df7a76", 200764100},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformPC, ADGF_UNSTABLE, GUIO1(GUIO_NOSPEECH) },
+ Common::EN_ANY, Common::kPlatformPC, ADGF_UNSTABLE, GUIO2(GUIO_NOSPEECH, GUIO_NOASPECT) },
// King's Quest 7 - English Windows (from FRG)
// SCI interpreter version 2.100.002, VERSION file reports "2.00b"
@@ -1493,7 +1499,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "8676b0fbbd7362989a029fe72fea14c6", 18709},
{"resource.000", 0, "51c1ead1163e19a2de8f121c39df7a76", 200764100},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO1(GUIO_NOSPEECH) },
+ Common::EN_ANY, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO2(GUIO_NOSPEECH, GUIO_NOASPECT) },
// King's Quest 7 - German Windows (supplied by markcoolio in bug report #2727402)
// SCI interpreter version 2.100.002
@@ -1501,7 +1507,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "838b9ff132bd6962026fee832e8a7ddb", 18697},
{"resource.000", 0, "eb63ea3a2c2469dc2d777d351c626404", 206626576},
AD_LISTEND},
- Common::DE_DEU, Common::kPlatformPC, ADGF_UNSTABLE, GUIO1(GUIO_NOSPEECH) },
+ Common::DE_DEU, Common::kPlatformPC, ADGF_UNSTABLE, GUIO2(GUIO_NOSPEECH, GUIO_NOASPECT) },
// King's Quest 7 - Spanish DOS (from jvprat)
// Executable scanning reports "2.100.002", VERSION file reports "2.00"
@@ -1509,7 +1515,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "0b62693cbe87e3aaca3e8655a437f27f", 18709},
{"resource.000", 0, "51c1ead1163e19a2de8f121c39df7a76", 200764100},
AD_LISTEND},
- Common::ES_ESP, Common::kPlatformPC, ADGF_UNSTABLE, GUIO1(GUIO_NOSPEECH) },
+ Common::ES_ESP, Common::kPlatformPC, ADGF_UNSTABLE, GUIO2(GUIO_NOSPEECH, GUIO_NOASPECT) },
// King's Quest 7 - English DOS Non-Interactive Demo
// SCI interpreter version 2.100.002
@@ -1517,7 +1523,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 | ADGF_UNSTABLE, GUIO1(GUIO_NOSPEECH) },
+ Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO | ADGF_UNSTABLE, GUIO2(GUIO_NOSPEECH, GUIO_NOASPECT) },
#endif // ENABLE_SCI32
@@ -1533,7 +1539,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.004", 0, "aa553977f7e5804081de293800d3bcce", 695067},
{"resource.005", 0, "bfd870d51dc97729f0914095f58e6957", 676881},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO1(GUIO_NOSPEECH) },
+ Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO2(GUIO_NOSPEECH, GUIO_EGAUNDITHER) },
// Laura Bow - English Atari ST (from jvprat)
// Executable scanning reports "1.002.030", Floppy label reports "1.000.062, 9.23.90"
@@ -1545,7 +1551,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.003", 0, "e45c888d9c7c04aec0a20e9f820b79ff", 667365},
{"resource.004", 0, "e45c888d9c7c04aec0a20e9f820b79ff", 683737},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformAtariST, 0, GUIO1(GUIO_NOSPEECH) },
+ Common::EN_ANY, Common::kPlatformAtariST, 0, GUIO2(GUIO_NOSPEECH, GUIO_EGAUNDITHER) },
// Laura Bow - English DOS Non-Interactive Demo
// Executable scanning reports "x.yyy.zzz"
@@ -1553,7 +1559,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "e625726268ff4e123ada11f31f0249f3", 768},
{"resource.001", 0, "0c8912290af0890f8d95faeb4ddb2d68", 333031},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO1(GUIO_NOSPEECH) },
+ Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO2(GUIO_NOSPEECH, GUIO_EGAUNDITHER) },
// Laura Bow - English DOS 3.5" Floppy (from "The Roberta Williams Anthology"/1996)
// SCI interpreter version 0.000.631
@@ -1564,7 +1570,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.003", 0, "e45c888d9c7c04aec0a20e9f820b79ff", 667468},
{"resource.004", 0, "e45c888d9c7c04aec0a20e9f820b79ff", 683807},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformPC, 0, GUIO1(GUIO_NOSPEECH) },
+ Common::EN_ANY, Common::kPlatformPC, 0, GUIO2(GUIO_NOSPEECH, GUIO_EGAUNDITHER) },
// Laura Bow - English DOS (from FRG)
// SCI interpreter version 0.000.631
@@ -1578,7 +1584,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.006", 0, "e45c888d9c7c04aec0a20e9f820b79ff", 328390},
{"resource.007", 0, "e45c888d9c7c04aec0a20e9f820b79ff", 317687},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformPC, 0, GUIO1(GUIO_NOSPEECH) },
+ Common::EN_ANY, Common::kPlatformPC, 0, GUIO2(GUIO_NOSPEECH, GUIO_EGAUNDITHER) },
// Laura Bow 2 - English DOS Non-Interactive Demo (from FRG)
// Executable scanning reports "x.yyy.zzz"
@@ -1605,7 +1611,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "a70945e61ba7ac7bfea6b7bd72c6aec5", 7274},
{"resource.000", 0, "82578b8d5a7e09c4c58891ca49fae35b", 5598672},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformPC, ADGF_CD, GUIO1(GUIO_NONE) },
+ Common::EN_ANY, Common::kPlatformPC, ADGF_CD, GUIO0() },
// Laura Bow 2 v1.1 - French DOS Floppy (from Hkz)
{"laurabow2", "", {
@@ -1631,7 +1637,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.000", 0, "57084910bc923bff5d6d9bc1b56e9604", 5028766},
{"resource.msg", 0, "71f1f0cd9f082da2e750c793a8ed9d84", 286141},
AD_LISTEND},
- Common::ES_ESP, Common::kPlatformPC, ADGF_CD, GUIO1(GUIO_NONE) },
+ Common::ES_ESP, Common::kPlatformPC, ADGF_CD, GUIO0() },
// Larry 1 EGA Remake - English DOS (from spookypeanut)
// SCI interpreter version 0.000.510 (or 0.000.577?)
@@ -1642,7 +1648,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.002", 0, "24c958bc922b07f91e25e8c93aa01fcf", 491230},
{"resource.003", 0, "685cd6c1e05a695ab1e0db826337ee2a", 553279},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformPC, 0, GUIO1(GUIO_NOSPEECH) },
+ Common::EN_ANY, Common::kPlatformPC, 0, GUIO2(GUIO_NOSPEECH, GUIO_EGAUNDITHER) },
#if 0
// The resource.002 file, contained in disk 3, is broken in this version
@@ -1742,7 +1748,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.003", 0, "a0d4a625311d307257da7fc43d00459d", 570356},
{"resource.004", 0, "a0d4a625311d307257da7fc43d00459d", 717844},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO1(GUIO_NOSPEECH) },
+ Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO2(GUIO_NOSPEECH, GUIO_EGAUNDITHER) },
// Larry 2 - English DOS Non-Interactive Demo
// Executable scanning reports "x.yyy.zzz"
@@ -1751,7 +1757,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "03dba704bb77da55a91ad27b5a3cac09", 528},
{"resource.001", 0, "9f5520f0297206928df0b0b36493cd33", 127532},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO1(GUIO_NOSPEECH) },
+ Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO2(GUIO_NOSPEECH, GUIO_EGAUNDITHER) },
// Larry 2 - English DOS
// SCI interpreter version 0.000.409
@@ -1764,7 +1770,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.005", 0, "4a24443a25e2b1492462a52809605dc2", 277732},
{"resource.006", 0, "4a24443a25e2b1492462a52809605dc2", 345683},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformPC, 0, GUIO1(GUIO_NOSPEECH) },
+ Common::EN_ANY, Common::kPlatformPC, 0, GUIO2(GUIO_NOSPEECH, GUIO_EGAUNDITHER) },
// Larry 2 - English DOS
// SCI interpreter version 0.000.343
@@ -1779,7 +1785,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
//{"resource.006", 0, "96033f57accfca903750413fd09193c8", 345818},
{"resource.006", 0, "96033f57accfca903750413fd09193c8", -1}, // 345818 or 208739
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformPC, 0, GUIO1(GUIO_NOSPEECH) },
+ Common::EN_ANY, Common::kPlatformPC, 0, GUIO2(GUIO_NOSPEECH, GUIO_EGAUNDITHER) },
// Larry 2 - English DOS (supplied by ssburnout in bug report #3049193)
// 1.000.011 3x3.5" (label: Int. #0.000.343)
@@ -1789,7 +1795,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.002", 0, "96033f57accfca903750413fd09193c8", 407014},
{"resource.003", 0, "96033f57accfca903750413fd09193c8", 592834},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformPC, 0, GUIO1(GUIO_NOSPEECH) },
+ Common::EN_ANY, Common::kPlatformPC, 0, GUIO2(GUIO_NOSPEECH, GUIO_EGAUNDITHER) },
// Larry 2 - English DOS (supplied by ssburnout in bug report #3049193)
// 1.002.000 3x3.5" (label: INT#0.000.409)
@@ -1799,7 +1805,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.002", 0, "4a24443a25e2b1492462a52809605dc2", 406935},
{"resource.003", 0, "4a24443a25e2b1492462a52809605dc2", 592533},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformPC, 0, GUIO1(GUIO_NOSPEECH) },
+ Common::EN_ANY, Common::kPlatformPC, 0, GUIO2(GUIO_NOSPEECH, GUIO_EGAUNDITHER) },
// Larry 3 - English Amiga (from www.back2roots.org)
// Executable scanning reports "1.002.032"
@@ -1824,7 +1830,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.003", 0, "f18441027154292836b973c655fa3175", 506807},
{"resource.004", 0, "f18441027154292836b973c655fa3175", 513651},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformPC, 0, GUIO1(GUIO_NOSPEECH) },
+ Common::EN_ANY, Common::kPlatformPC, 0, GUIO2(GUIO_NOSPEECH, GUIO_EGAUNDITHER) },
// Larry 3 - English DOS (supplied by ssburnout in bug report #3049193)
// 1.021 8x5.25" (label: Int#5.15.90)
@@ -1838,7 +1844,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.006", 0, "f18441027154292836b973c655fa3175", 282649},
{"resource.007", 0, "f18441027154292836b973c655fa3175", 257178},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformPC, 0, GUIO1(GUIO_NOSPEECH) },
+ Common::EN_ANY, Common::kPlatformPC, 0, GUIO2(GUIO_NOSPEECH, GUIO_EGAUNDITHER) },
// Larry 3 - English DOS
// SCI interpreter version 0.000.572
@@ -1852,7 +1858,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.006", 0, "f18441027154292836b973c655fa3175", 282465},
{"resource.007", 0, "f18441027154292836b973c655fa3175", 257174},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformPC, 0, GUIO1(GUIO_NOSPEECH) },
+ Common::EN_ANY, Common::kPlatformPC, 0, GUIO2(GUIO_NOSPEECH, GUIO_EGAUNDITHER) },
// Larry 3 - English DOS Non-Interactive Demo
// SCI interpreter version 0.000.530
@@ -1861,7 +1867,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.001", 0, "f773d79b93dfd4052ec8c1cc64c1e6ab", 76525},
{"resource.002", 0, "f773d79b93dfd4052ec8c1cc64c1e6ab", 268299},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO1(GUIO_NOSPEECH) },
+ Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO2(GUIO_NOSPEECH, GUIO_EGAUNDITHER) },
// Larry 3 - German DOS (from Tobis87, updated info from markcoolio in bug report #2723832, also includes english language)
// Executable scanning reports "S.old.123"
@@ -1873,7 +1879,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.003", 0, "3827a9b17b926e12dcc336860f50612a", 587036},
{"resource.004", 0, "3827a9b17b926e12dcc336860f50612a", 691932},
AD_LISTEND},
- Common::DE_DEU, Common::kPlatformPC, ADGF_ADDENGLISH, GUIO1(GUIO_NOSPEECH) },
+ Common::DE_DEU, Common::kPlatformPC, ADGF_ADDENGLISH, GUIO2(GUIO_NOSPEECH, GUIO_EGAUNDITHER) },
// Larry 3 - French DOS (provided by richiefs in bug report #2670691, also includes english language)
// Executable scanning reports "S.old.123"
@@ -1885,7 +1891,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.003", 0, "65f1bdaa20f6d0470e9d969f22473873", 586921},
{"resource.004", 0, "65f1bdaa20f6d0470e9d969f22473873", 690826},
AD_LISTEND},
- Common::FR_FRA, Common::kPlatformPC, ADGF_ADDENGLISH, GUIO1(GUIO_NOSPEECH) },
+ Common::FR_FRA, Common::kPlatformPC, ADGF_ADDENGLISH, GUIO2(GUIO_NOSPEECH, GUIO_EGAUNDITHER) },
// Larry 3 1.050 Fr/En (9 x 5.25" disks)
// Provided by ssburnout in bug report #3046779
@@ -2037,7 +2043,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.006", 0, "f6046a8445422f17d40b1b10ab21ebf3", 568551},
{"resource.007", 0, "640ee65595d40372ef95462f2c1ae28a", 593429},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformPC, 0, GUIO1(GUIO_NOSPEECH) },
+ Common::EN_ANY, Common::kPlatformPC, 0, GUIO2(GUIO_NOSPEECH, GUIO_EGAUNDITHER) },
// Larry 5 EGA
// Supplied by omer_mor in bug report #3049771
@@ -2048,7 +2054,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.002", 0, "5a55af4e40728b1a8103dc47ad2afa8d", 1100539},
{"resource.003", 0, "16f4d8fb1b526125edaca4fc6cbb7530", 1064563},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformPC, 0, GUIO1(GUIO_NOSPEECH) },
+ Common::EN_ANY, Common::kPlatformPC, 0, GUIO2(GUIO_NOSPEECH, GUIO_EGAUNDITHER) },
// Larry 6 - English DOS (from spookypeanut)
// SCI interpreter version 1.001.113
@@ -2064,7 +2070,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "0b91234b7112782962cb480b7791b6e2", 7263},
{"resource.000", 0, "57d5fe8bb9e044158514476ea7678eb0", 5754790},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformPC, ADGF_CD, GUIO1(GUIO_NONE) },
+ Common::EN_ANY, Common::kPlatformPC, ADGF_CD, GUIO0() },
// Larry 6 - German DOS CD - LOWRES (provided by richiefs in bug report #2670691)
// SCI interpreter version 1.001.115
@@ -2072,7 +2078,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "bafe85f32738854135991d4324ad147e", 7268},
{"resource.000", 0, "f6cbc6da7b90ea135883e0759848ca2c", 5773160},
AD_LISTEND},
- Common::DE_DEU, Common::kPlatformPC, ADGF_CD, GUIO1(GUIO_NONE) },
+ Common::DE_DEU, Common::kPlatformPC, ADGF_CD, GUIO0() },
// Larry 6 - French DOS CD - LOWRES (provided by richiefs in bug report #2670691)
// SCI interpreter version 1.001.115
@@ -2080,7 +2086,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "97797ea775baaf18a1907d357d3c0ea6", 7268},
{"resource.000", 0, "f6cbc6da7b90ea135883e0759848ca2c", 5776092},
AD_LISTEND},
- Common::FR_FRA, Common::kPlatformPC, ADGF_CD, GUIO1(GUIO_NONE) },
+ Common::FR_FRA, Common::kPlatformPC, ADGF_CD, GUIO0() },
// Larry 6 - Spanish DOS - LOWRES (from the Leisure Suit Larry Collection)
// Executable scanning reports "1.001.113", VERSION file reports "1.000, 11.06.93, FIVE PATCHES ADDED TO DISK 6 ON 11-18-93"
@@ -2133,7 +2139,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "0c0804434ea62278dd15032b1947426c", 8872},
{"resource.000", 0, "9a9f4870504444cda863dd14d077a680", 18520872},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformPC, ADGF_UNSTABLE, GUIO1(GUIO_NONE) },
+ Common::EN_ANY, Common::kPlatformPC, ADGF_UNSTABLE, GUIO1(GUIO_NOASPECT) },
// Larry 6 - German DOS CD - HIRES (provided by richiefs in bug report #2670691)
// SCI interpreter version 2.100.002
@@ -2141,7 +2147,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "badfdf446ffed569a310d2c63a249421", 8896},
{"resource.000", 0, "bd944d2b06614a5b39f1586906f0ee88", 18534274},
AD_LISTEND},
- Common::DE_DEU, Common::kPlatformPC, ADGF_UNSTABLE, GUIO1(GUIO_NONE) },
+ Common::DE_DEU, Common::kPlatformPC, ADGF_UNSTABLE, GUIO1(GUIO_NOASPECT) },
// Larry 6 - French DOS CD - HIRES (provided by richiefs in bug report #2670691)
// SCI interpreter version 2.100.002
@@ -2149,7 +2155,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "d184e9aa4f2d4b5670ddb3669db82cda", 8896},
{"resource.000", 0, "bd944d2b06614a5b39f1586906f0ee88", 18538987},
AD_LISTEND},
- Common::FR_FRA, Common::kPlatformPC, ADGF_UNSTABLE, GUIO1(GUIO_NONE) },
+ Common::FR_FRA, Common::kPlatformPC, ADGF_UNSTABLE, GUIO1(GUIO_NOASPECT) },
// Larry 7 - English DOS Demo (provided by richiefs in bug report #2670691)
// SCI interpreter version 2.100.002
@@ -2157,7 +2163,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 | ADGF_UNSTABLE, GUIO1(GUIO_NOSPEECH) },
+ Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO | ADGF_UNSTABLE, GUIO2(GUIO_NOSPEECH, GUIO_NOASPECT) },
#ifdef ENABLE_SCI3_GAMES
// Larry 7 - English DOS CD (from spookypeanut)
@@ -2166,7 +2172,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resmap.000", 0, "eae93e1b1d1ccc58b4691c371281c95d", 8188},
{"ressci.000", 0, "89353723488219e25589165d73ed663e", 66965678},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformPC, ADGF_UNSTABLE, GUIO1(GUIO_NONE) },
+ Common::EN_ANY, Common::kPlatformPC, ADGF_UNSTABLE, GUIO1(GUIO_NOASPECT) },
// Larry 7 - German DOS (from Tobis87)
// SCI interpreter version 3.000.000
@@ -2174,7 +2180,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resmap.000", 0, "c11e6bfcfc2f2d05da47e5a7df3e9b1a", 8188},
{"ressci.000", 0, "a8c6817bb94f332ff498a71c8b47f893", 66971724},
AD_LISTEND},
- Common::DE_DEU, Common::kPlatformPC, ADGF_UNSTABLE, GUIO1(GUIO_NOSPEECH) },
+ Common::DE_DEU, Common::kPlatformPC, ADGF_UNSTABLE, GUIO2(GUIO_NOSPEECH, GUIO_NOASPECT) },
// Larry 7 - French DOS (provided by richiefs in bug report #2670691)
// SCI interpreter version 3.000.000
@@ -2182,7 +2188,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resmap.000", 0, "4407849fd52fe3efb0c30fba60cd5cd4", 8206},
{"ressci.000", 0, "dc37c3055fffbefb494ff22b145d377b", 66964472},
AD_LISTEND},
- Common::DE_DEU, Common::kPlatformPC, ADGF_UNSTABLE, GUIO1(GUIO_NOSPEECH) },
+ Common::DE_DEU, Common::kPlatformPC, ADGF_UNSTABLE, GUIO2(GUIO_NOSPEECH, GUIO_NOASPECT) },
// Larry 7 - Italian DOS CD (from glorifindel)
// SCI interpreter version 3.000.000
@@ -2190,7 +2196,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resmap.000", 0, "9852a97141f789413f29bf956052acdb", 8212},
{"ressci.000", 0, "440b9fed89590abb4e4386ed6f948ee2", 67140181},
AD_LISTEND},
- Common::IT_ITA, Common::kPlatformPC, ADGF_UNSTABLE, GUIO1(GUIO_NONE) },
+ Common::IT_ITA, Common::kPlatformPC, ADGF_UNSTABLE, GUIO1(GUIO_NOASPECT) },
// Larry 7 - Spanish DOS (from the Leisure Suit Larry Collection)
// Executable scanning reports "3.000.000", VERSION file reports "1.0s"
@@ -2198,7 +2204,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resmap.000", 0, "8f3d603e1acc834a5d598b30cdfc93f3", 8188},
{"ressci.000", 0, "32792f9bc1bf3633a88b382bb3f6e40d", 67071418},
AD_LISTEND},
- Common::ES_ESP, Common::kPlatformPC, ADGF_UNSTABLE, GUIO1(GUIO_NOSPEECH) },
+ Common::ES_ESP, Common::kPlatformPC, ADGF_UNSTABLE, GUIO2(GUIO_NOSPEECH, GUIO_NOASPECT) },
#endif
// Lighthouse - English Windows Demo (from jvprat)
@@ -2207,7 +2213,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 | ADGF_UNSTABLE, GUIO1(GUIO_NOSPEECH) },
+ Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO | ADGF_UNSTABLE, GUIO2(GUIO_NOSPEECH, GUIO_NOASPECT) },
#ifdef ENABLE_SCI3_GAMES
// Lighthouse - English Windows Demo
@@ -2216,7 +2222,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 | ADGF_UNSTABLE, GUIO1(GUIO_NOSPEECH) },
+ Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO | ADGF_UNSTABLE, GUIO2(GUIO_NOSPEECH, GUIO_NOASPECT) },
// Lighthouse - English DOS (from jvprat)
// Executable scanning reports "3.000.000", VERSION file reports "1.1"
@@ -2226,7 +2232,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resmap.002", 0, "c68db5333f152fea6ca2dfc75cad8b34", 7573},
{"ressci.002", 0, "175468431a979b9f317c294ce3bc1430", 94628315},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformPC, ADGF_UNSTABLE, GUIO1(GUIO_NOSPEECH) },
+ Common::EN_ANY, Common::kPlatformPC, ADGF_UNSTABLE, GUIO2(GUIO_NOSPEECH, GUIO_NOASPECT) },
// Lighthouse - Spanish DOS (from jvprat)
// Executable scanning reports "3.000.000", VERSION file reports "1.1"
@@ -2236,7 +2242,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resmap.002", 0, "e7dc85884a2417e2eff9de0c63dd65fa", 7630},
{"ressci.002", 0, "3c8d627c555b0e3e4f1d9955bc0f0df4", 94631127},
AD_LISTEND},
- Common::ES_ESP, Common::kPlatformPC, ADGF_UNSTABLE, GUIO1(GUIO_NOSPEECH) },
+ Common::ES_ESP, Common::kPlatformPC, ADGF_UNSTABLE, GUIO2(GUIO_NOSPEECH, GUIO_NOASPECT) },
#endif // ENABLE_SCI3_GAMES
#endif // ENABLE_SCI32
@@ -2258,7 +2264,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.003", 0, "509b2467ba779100d5933ed51a9ae32f", 560255},
{"resource.004", 0, "93afc85d5ffa60ea555d6cc336d22c03", 651109},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformPC, 0, GUIO1(GUIO_NOSPEECH) },
+ Common::EN_ANY, Common::kPlatformPC, 0, GUIO2(GUIO_NOSPEECH, GUIO_EGAUNDITHER) },
// Mixed-Up Fairy Tales v1.000 - English DOS (supplied by markcoolio in bug report #2723791)
// Executable scanning reports "1.000.145"
@@ -2299,7 +2305,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.001", 0, "d893892d62b3f061357291d66775e360", 239906},
{"resource.002", 0, "d893892d62b3f061357291d66775e360", 719398},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformPC, 0, GUIO1(GUIO_NOSPEECH) },
+ Common::EN_ANY, Common::kPlatformPC, 0, GUIO2(GUIO_NOSPEECH, GUIO_EGAUNDITHER) },
// Mixed-Up Mother Goose - English DOS Floppy EGA (supplied by ssburnout in bug report #3049193)
// 1.011 5x5.25" (label: Int#8.2.90)
@@ -2312,7 +2318,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.004", 0, "dbbc22f124533ce308bc386b08956326", 146251},
{"resource.005", 0, "2ba5348e7fad641b9c4c7ff7c7cf4e68", 110979},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformPC, 0, GUIO1(GUIO_NOSPEECH) },
+ Common::EN_ANY, Common::kPlatformPC, 0, GUIO2(GUIO_NOSPEECH, GUIO_EGAUNDITHER) },
// Mixed-Up Mother Goose v2.000 - English DOS Floppy (supplied by markcoolio in bug report #2723795)
// Executable scanning reports "1.001.031"
@@ -2329,7 +2335,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "1c7f311b0a2c927b2fbe81ae341fb2f6", 5790},
{"resource.001", 0, "5a0ed1d745855148364de1b3be099bac", 4369438},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformPC, ADGF_CD, GUIO1(GUIO_NONE) },
+ Common::EN_ANY, Common::kPlatformPC, ADGF_CD, GUIO0() },
// Mixed-Up Mother Goose - English Windows Interactive Demo
// Executable scanning reports "x.yyy.zzz"
@@ -2344,7 +2350,12 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "b11e971ccd2040bebba59dfb409a08ef", 5772},
{"resource.001", 0, "d49625d9b8005ec01c852f8322a82867", 4330713},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformFMTowns, 0, GUIO1(GUIO_NONE) },
+ Common::EN_ANY, Common::kPlatformFMTowns, 0, GUIO1(GUIO_NOASPECT) },
+ {"mothergoose256", "", {
+ {"resource.map", 0, "b11e971ccd2040bebba59dfb409a08ef", 5772},
+ {"resource.001", 0, "d49625d9b8005ec01c852f8322a82867", 4330713},
+ AD_LISTEND},
+ Common::JA_JPN, Common::kPlatformFMTowns, 0, GUIO1(GUIO_NOASPECT) },
#ifdef ENABLE_SCI32
// Mixed-Up Mother Goose Deluxe - English Windows/DOS CD (supplied by markcoolio in bug report #2723810)
@@ -2353,7 +2364,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "5159a1578c4306bfe070a3e4d8c2e1d3", 4741},
{"resource.000", 0, "1926925c95d82f0999590e93b02887c5", 15150768},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformPC, ADGF_UNSTABLE, GUIO1(GUIO_NONE) },
+ Common::EN_ANY, Common::kPlatformPC, ADGF_UNSTABLE, GUIO1(GUIO_NOASPECT) },
// Mixed-Up Mother Goose Deluxe - Multilingual Windows CD (English/French/German/Spanish)
// Executable scanning reports "2.100.002"
@@ -2361,7 +2372,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resmap.000", 0, "ef611af561898dcfea87846919ebf3eb", 4969},
{"ressci.000", 0, "227685bc59d90821978d330713e44a7a", 17205800},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformPC, ADGF_UNSTABLE, GUIO1(GUIO_NONE) },
+ Common::EN_ANY, Common::kPlatformPC, ADGF_UNSTABLE, GUIO1(GUIO_NOASPECT) },
#endif // ENABLE_SCI32
// Ms. Astro Chicken - English DOS
@@ -2391,7 +2402,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resmap.007", 0, "afbd16ea77869a720afa1c5371de107d", 7972},
//{"ressci.007", 0, "3aae6559aa1df273bc542d5ac6330d75", 25859038},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformPC, ADGF_UNSTABLE, GUIO1(GUIO_NOSPEECH) },
+ Common::EN_ANY, Common::kPlatformPC, ADGF_UNSTABLE, GUIO2(GUIO_NOSPEECH, GUIO_NOASPECT) },
// Phantasmagoria - English DOS Demo
// Executable scanning reports "2.100.002"
@@ -2399,7 +2410,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resmap.001", 0, "416138651ea828219ca454cae18341a3", 11518},
{"ressci.001", 0, "3aae6559aa1df273bc542d5ac6330d75", 65844612},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO | ADGF_UNSTABLE, GUIO1(GUIO_NOSPEECH) },
+ Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO | ADGF_UNSTABLE, GUIO2(GUIO_NOSPEECH, GUIO_NOASPECT) },
// Phantasmagoria - English DOS/Windows (GOG version) - ressci.* merged in ressci.000
// Windows executable scanning reports "2.100.002" - "Sep 19 1995 15:09:43"
@@ -2410,7 +2421,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"ressci.000", 0, "cd5967f9b9586e3380645961c0765be3", 116822037},
{"resmap.000", 0, "3cafc1c6a53945c1f3babbfd6380c64c", 16468},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformPC, ADGF_UNSTABLE, GUIO1(GUIO_NOSPEECH) },
+ Common::EN_ANY, Common::kPlatformPC, ADGF_UNSTABLE, GUIO2(GUIO_NOSPEECH, GUIO_NOASPECT) },
// Phantasmagoria - English Macintosh
// NOTE: This only contains disc 1 files (as well as the two persistent files:
@@ -2426,7 +2437,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
// Data8-12 are empty
{"Data13", 0, "6d2c450fca19a69b5af74ed5b03c0a17", 14923328},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformMacintosh, ADGF_MACRESFORK | ADGF_UNSTABLE, GUIO1(GUIO_NONE) },
+ Common::EN_ANY, Common::kPlatformMacintosh, ADGF_MACRESFORK | ADGF_UNSTABLE, GUIO1(GUIO_NOASPECT) },
#ifdef ENABLE_SCI3_GAMES
// Phantasmagoria 2 - English Windows (from jvprat)
@@ -2443,7 +2454,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resmap.005", 0, "8bd5ceeedcbe16dfe55d1b90dcd4be84", 1942},
{"ressci.005", 0, "05f9fe2bee749659acb3cd2c90252fc5", 67905112},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO1(GUIO_NOSPEECH) },
+ Common::EN_ANY, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO2(GUIO_NOSPEECH, GUIO_NOASPECT) },
// Phantasmagoria 2 - English DOS (GOG version) - ressci.* merged in ressci.000
// Executable scanning reports "3.000.000" - "Dec 07 1996 09:29:03"
@@ -2453,7 +2464,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"ressci.000", 0, "c54f26d9f43f908151263254b6d97053", 108134481},
{"resmap.000", 0, "de154a223a9ef4ea7358b76adc38ef5b", 2956},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO1(GUIO_NOSPEECH) },
+ Common::EN_ANY, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO2(GUIO_NOSPEECH, GUIO_NOASPECT) },
#endif // ENABLE_SCI3_GAMES
#endif // ENABLE_SCI32
@@ -2507,7 +2518,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.002", 0, "499737c21a28ac026e11ab817100d610", 511099},
{"resource.003", 0, "e008f5d6e2a7c4d4a0da0173e4fa8f8b", 553970},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO1(GUIO_NOSPEECH) },
+ Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO2(GUIO_NOSPEECH, GUIO_EGAUNDITHER) },
// Police Quest 2 - English DOS Non-Interactive Demo
// Executable scanning reports "0.000.413"
@@ -2515,7 +2526,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "8b77d0d4650c2052b356cece28294b58", 576},
{"resource.001", 0, "376ef6d6eaaeed66e1424bd219c4b9ab", 215398},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO1(GUIO_NOSPEECH) },
+ Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO2(GUIO_NOSPEECH, GUIO_EGAUNDITHER) },
// Police Quest 2 - English DOS (provided by richiefs in bug report #2670691)
// SCI interpreter version 0.000.395
@@ -2528,7 +2539,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.005", 0, "77f02def3094af804fd2371db25b7100", 349899},
{"resource.006", 0, "77f02def3094af804fd2371db25b7100", 354991},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformPC, 0, GUIO1(GUIO_NOSPEECH) },
+ Common::EN_ANY, Common::kPlatformPC, 0, GUIO2(GUIO_NOSPEECH, GUIO_EGAUNDITHER) },
// Police Quest 2 - English DOS (from the Police Quest Collection)
// Executable scanning reports "0.000.490"
@@ -2538,7 +2549,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.002", 0, "77f02def3094af804fd2371db25b7100", 546000},
{"resource.003", 0, "77f02def3094af804fd2371db25b7100", 591851},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformPC, 0, GUIO1(GUIO_NOSPEECH) },
+ Common::EN_ANY, Common::kPlatformPC, 0, GUIO2(GUIO_NOSPEECH, GUIO_EGAUNDITHER) },
// Police Quest 2 - English DOS (from FRG)
// SCI interpreter version 0.000.395
@@ -2548,7 +2559,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.002", 0, "77f02def3094af804fd2371db25b7100", 542897},
{"resource.003", 0, "77f02def3094af804fd2371db25b7100", 586857},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformPC, 0, GUIO1(GUIO_NOSPEECH) },
+ Common::EN_ANY, Common::kPlatformPC, 0, GUIO2(GUIO_NOSPEECH, GUIO_EGAUNDITHER) },
// Police Quest 2 English DOS 1.001.006 (supplied by merkur-kun in bug report #3028479)
{"pq2", "", {
@@ -2557,7 +2568,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.002", 0, "77f02def3094af804fd2371db25b7100", 541261},
{"resource.003", 0, "77f02def3094af804fd2371db25b7100", 587511},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformPC, 0, GUIO1(GUIO_NOSPEECH) },
+ Common::EN_ANY, Common::kPlatformPC, 0, GUIO2(GUIO_NOSPEECH, GUIO_EGAUNDITHER) },
// Police Quest 2 - Japanese PC-98 (also includes english language)
// SCI interpreter version unknown
@@ -2567,7 +2578,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.002", 0, "05fdee43a228dd6ea4d1a92ccae3f788", 637662},
{"resource.003", 0, "05fdee43a228dd6ea4d1a92ccae3f788", 684395},
AD_LISTEND},
- Common::JA_JPN, Common::kPlatformPC98, ADGF_ADDENGLISH, GUIO1(GUIO_NOSPEECH) },
+ Common::JA_JPN, Common::kPlatformPC98, ADGF_ADDENGLISH, GUIO2(GUIO_NOSPEECH, GUIO_NOASPECT) },
// Police Quest 3 - English Amiga
// Executable scanning reports "1.004.024"
@@ -2643,7 +2654,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.004", 0, "b96a86ab681769e4cbb439670d967ca6", 449682},
{"resource.005", 0, "9e6c53a0e7eef53694d260fade8b1fc7", 724000},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformPC, 0, GUIO1(GUIO_NOSPEECH) },
+ Common::EN_ANY, Common::kPlatformPC, 0, GUIO2(GUIO_NOSPEECH, GUIO_EGAUNDITHER) },
// Police Quest 4 - English DOS Non-Interactive Demo (from FRG)
// SCI interpreter version 1.001.096
@@ -2660,7 +2671,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 | ADGF_UNSTABLE, GUIO1(GUIO_NONE) },
+ Common::EN_ANY, Common::kPlatformPC, ADGF_CD | ADGF_UNSTABLE, GUIO0() },
// Police Quest 4 - German DOS CD (German text, English speech)
// Supplied by markcoolio in bug report #3392955
@@ -2668,7 +2679,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "a398076371ed0e1e706c8f9fb9fc7ac5", 11386},
{"resource.000", 0, "6ff21954e0a2c5992279e7eb787c8d56", 18918747},
AD_LISTEND},
- Common::DE_DEU, Common::kPlatformPC, ADGF_CD | ADGF_UNSTABLE, GUIO1(GUIO_NONE) },
+ Common::DE_DEU, Common::kPlatformPC, ADGF_CD | ADGF_UNSTABLE, GUIO0() },
// Police Quest 4 - English DOS
// SCI interpreter version 2.000.000 (a guess?)
@@ -2700,7 +2711,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 | ADGF_UNSTABLE, GUIO1(GUIO_NOSPEECH) },
+ Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO | ADGF_UNSTABLE, GUIO2(GUIO_NOSPEECH, GUIO_NOASPECT) },
// Police Quest: SWAT - English DOS (from GOG.com)
// Executable scanning reports "2.100.002", VERSION file reports "1.0c"
@@ -2708,7 +2719,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resmap.000", 0, "1c2563fee189885e29d9348f37306d94", 12175},
{"ressci.000", 0, "b2e1826ca81ce2e7e764587f5a14eee9", 127149181},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformPC, ADGF_UNSTABLE, GUIO1(GUIO_NONE) },
+ Common::EN_ANY, Common::kPlatformPC, ADGF_UNSTABLE, GUIO1(GUIO_NOASPECT) },
// Police Quest: SWAT - English Windows (from the Police Quest Collection)
// Executable scanning reports "2.100.002", VERSION file reports "1.0c"
@@ -2723,7 +2734,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resmap.004", 0, "4228038906f041623e65789500b22285", 6835},
{"ressci.004", 0, "b7e619e6ecf62fe65d5116a3a422e5f0", 46223872},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO1(GUIO_NONE) },
+ Common::EN_ANY, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO1(GUIO_NOASPECT) },
#endif // ENABLE_SCI32
// Quest for Glory 1 / Hero's Quest - English DOS 3.5" Floppy (supplied by merkur in bug report #2718784)
@@ -2736,7 +2747,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.003", 0, "7ab2bf8e224b57f75e0cd6e4ba790761", 642203},
{"resource.004", 0, "7ab2bf8e224b57f75e0cd6e4ba790761", 641688},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformPC, 0, GUIO1(GUIO_NOSPEECH) },
+ Common::EN_ANY, Common::kPlatformPC, 0, GUIO2(GUIO_NOSPEECH, GUIO_EGAUNDITHER) },
// Quest for Glory 1 / Hero's Quest - English DOS 3.5" Floppy (supplied by alonzotg in bug report #3206006)
{"qfg1", "", {
@@ -2747,7 +2758,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.003", 0, "7ab2bf8e224b57f75e0cd6e4ba790761", 642203},
{"resource.004", 0, "7ab2bf8e224b57f75e0cd6e4ba790761", 641688},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformPC, 0, GUIO1(GUIO_NOSPEECH) },
+ Common::EN_ANY, Common::kPlatformPC, 0, GUIO2(GUIO_NOSPEECH, GUIO_EGAUNDITHER) },
// Quest for Glory 1 / Hero's Quest - English DOS 5.25" Floppy (supplied by markcoolio in bug report #2723843)
// Executable scanning reports "0.000.566"
@@ -2762,7 +2773,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.006", 0, "69366c2a2f99917199fe1b60a4fee19d", 267852},
{"resource.007", 0, "7ab2bf8e224b57f75e0cd6e4ba790761", 272747},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformPC, 0, GUIO1(GUIO_NOSPEECH) },
+ Common::EN_ANY, Common::kPlatformPC, 0, GUIO2(GUIO_NOSPEECH, GUIO_EGAUNDITHER) },
// Quest for Glory 1 / Hero's Quest - English DOS 5.25" Floppy (supplied by ssburnout in bug report #3049193)
// 1.001 10x5.25" (label: INT.#0.000.566)
@@ -2777,7 +2788,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.006", 0, "69366c2a2f99917199fe1b60a4fee19d", 267852},
{"resource.007", 0, "7ab2bf8e224b57f75e0cd6e4ba790761", 272747},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformPC, 0, GUIO1(GUIO_NOSPEECH) },
+ Common::EN_ANY, Common::kPlatformPC, 0, GUIO2(GUIO_NOSPEECH, GUIO_EGAUNDITHER) },
// Quest for Glory 1 / Hero's Quest - English DOS 5.25" Floppy (supplied by ssburnout in bug report #3049193)
// 1.200 10x5.25" (label: INT#9.10.90)
@@ -2792,7 +2803,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.006", 0, "f46690dca714abc8c89357d30e363dd3", 278387},
{"resource.007", 0, "951299a82a8134ed12c5c18118d45c2f", 269173},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformPC, 0, GUIO1(GUIO_NOSPEECH) },
+ Common::EN_ANY, Common::kPlatformPC, 0, GUIO2(GUIO_NOSPEECH, GUIO_EGAUNDITHER) },
// Quest for Glory 1 / Hero's Quest - English DOS Demo
// Executable scanning reports "0.000.685"
@@ -2800,7 +2811,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "df34c758cbb9026da175793ff686b0e6", 882},
{"resource.001", 0, "73fbaafdd313b39aeedb80fbf85ecef1", 389884},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO1(GUIO_NOSPEECH) },
+ Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO2(GUIO_NOSPEECH, GUIO_EGAUNDITHER) },
// Quest for Glory 1 - Japanese PC-98 5.25" Floppy (also includes English language)
// Executable scanning reports "S.old.201"
@@ -2810,7 +2821,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.002", 0, "a21451ef6fa8179bd4b22c4950004c44", 1136968},
{"resource.003", 0, "a21451ef6fa8179bd4b22c4950004c44", 769897},
AD_LISTEND},
- Common::JA_JPN, Common::kPlatformPC98, ADGF_ADDENGLISH, GUIO1(GUIO_NOSPEECH) },
+ Common::JA_JPN, Common::kPlatformPC98, ADGF_ADDENGLISH, GUIO3(GUIO_NOSPEECH, GUIO_NOASPECT, GUIO_EGAUNDITHER) },
// Quest for Glory 1 - Japanese PC-98 5.25" Floppy (also includes English language)
// Executable scanning reports "S.old.201"
@@ -2820,7 +2831,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.002", 0, "a21451ef6fa8179bd4b22c4950004c44", 1147121},
{"resource.003", 0, "a21451ef6fa8179bd4b22c4950004c44", 777575},
AD_LISTEND},
- Common::JA_JPN, Common::kPlatformPC98, ADGF_ADDENGLISH, GUIO1(GUIO_NOSPEECH) },
+ Common::JA_JPN, Common::kPlatformPC98, ADGF_ADDENGLISH, GUIO3(GUIO_NOSPEECH, GUIO_NOASPECT, GUIO_EGAUNDITHER) },
// Quest for Glory 1 - English Amiga
// Executable scanning reports "1.002.020"
@@ -2834,7 +2845,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.004", 0, "16cd4414c37ae3bb6d6da33dce8e25e8", 689124},
{"resource.005", 0, "5f3386ef2f2b1254e4a066f5d9027324", 609529},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO1(GUIO_NOSPEECH) },
+ Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO2(GUIO_NOSPEECH, GUIO_EGAUNDITHER) },
// Quest for Glory 1 (from abevi, bug report #2612718)
{"qfg1", "", {
@@ -2845,7 +2856,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.003", 0, "f0af87c60ec869946da442833aa5afa8", 640502},
{"resource.004", 0, "f0af87c60ec869946da442833aa5afa8", 644575},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO1(GUIO_NOSPEECH) },
+ Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO2(GUIO_NOSPEECH, GUIO_EGAUNDITHER) },
// Quest for Glory 1 - English DOS
// SCI interpreter version 0.000.629
@@ -2857,7 +2868,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.003", 0, "951299a82a8134ed12c5c18118d45c2f", 640483},
{"resource.004", 0, "951299a82a8134ed12c5c18118d45c2f", 644443},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformPC, 0, GUIO1(GUIO_NOSPEECH) },
+ Common::EN_ANY, Common::kPlatformPC, 0, GUIO2(GUIO_NOSPEECH, GUIO_EGAUNDITHER) },
// Quest for Glory 1 VGA Remake - English DOS
// Executable scanning reports "2.000.411"
@@ -3008,7 +3019,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.000", 0, "ba7ac86155e4c531e46cd73c86daa80a", 5884098},
{"resource.msg", 0, "a63974730d294dec0bea10057c36e506", 256014},
AD_LISTEND},
- Common::ES_ESP, Common::kPlatformPC, 0, GUIO1(GUIO_NONE) },
+ Common::ES_ESP, Common::kPlatformPC, 0, GUIO0() },
// Quest for Glory 3 - Italian DOS
// Supplied by ghoost in bug report #3053457
@@ -3017,7 +3028,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.000", 0, "6178ad2e83e58e4671ca03315f7a6498", 5868000},
{"resource.msg", 0, "5a0a896ff3e4a628db38a75eb6c84114", 259018},
AD_LISTEND},
- Common::IT_ITA, Common::kPlatformPC, 0, GUIO1(GUIO_NONE) },
+ Common::IT_ITA, Common::kPlatformPC, 0, GUIO0() },
// Quest for Glory 4 - English DOS Non-Interactive Demo (from FRG)
// SCI interpreter version 1.001.069 (just a guess)
@@ -3058,7 +3069,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 | ADGF_UNSTABLE, GUIO1(GUIO_NONE) },
+ Common::EN_ANY, Common::kPlatformPC, ADGF_CD | ADGF_UNSTABLE, GUIO1(GUIO_NOASPECT) },
// RAMA - English DOS/Windows Demo
// Executable scanning reports "2.100.002", VERSION file reports "000.000.008"
@@ -3066,7 +3077,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resmap.001", 0, "775304e9b2a545156be4d94209550094", 1393},
{"ressci.001", 0, "259437fd75fdf51e8207fda8c01fa4fd", 2334384},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformWindows, ADGF_DEMO | ADGF_UNSTABLE, GUIO1(GUIO_NONE) },
+ Common::EN_ANY, Common::kPlatformWindows, ADGF_DEMO | ADGF_UNSTABLE, GUIO1(GUIO_NOASPECT) },
#ifdef ENABLE_SCI3_GAMES
// RAMA - English Windows (from jvprat)
@@ -3079,7 +3090,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resmap.003", 0, "31ef4c0621711585d031f0ae81707251", 1636},
{"ressci.003", 0, "2a68edd064e5e4937b5e9c74b38f2082", 6860492},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO1(GUIO_NONE) },
+ Common::EN_ANY, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO1(GUIO_NOASPECT) },
// RAMA - English Windows (from Quietust, in bug report #2850645)
{"rama", "", {
@@ -3090,7 +3101,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resmap.003", 0, "48841e4b84ef1b98b48d43566fda9e13", 1636},
{"ressci.003", 0, "2a68edd064e5e4937b5e9c74b38f2082", 6870356},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO1(GUIO_NONE) },
+ Common::EN_ANY, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO1(GUIO_NOASPECT) },
// RAMA - Italian Windows CD (from glorifindel)
// SCI interpreter version 3.000.000 (a guess?)
@@ -3098,7 +3109,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"ressci.001", 0, "2a68edd064e5e4937b5e9c74b38f2082", 70611091},
{"resmap.001", 0, "70ba2ff04a2b7fb2c52420ba7fbd47c2", 8338},
AD_LISTEND},
- Common::IT_ITA, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO1(GUIO_NONE) },
+ Common::IT_ITA, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO1(GUIO_NOASPECT) },
#endif // ENABLE_SCI3_GAMES
// Shivers - English Windows (from jvprat)
@@ -3107,14 +3118,14 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resmap.000", 0, "f2ead37749ed8f6535a2445a7d05a0cc", 46525},
{"ressci.000", 0, "4294c6d7510935f2e0a52e302073c951", 262654836},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO1(GUIO_NONE) },
+ Common::EN_ANY, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO1(GUIO_NOASPECT) },
// Shivers - German Windows (from Tobis87)
{"shivers", "", {
{"resmap.000", 0, "f483d0a1f78334c18052e92785c3086e", 46537},
{"ressci.000", 0, "6751b144671e2deed919eb9d284b07eb", 262390692},
AD_LISTEND},
- Common::DE_DEU, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO1(GUIO_NONE) },
+ Common::DE_DEU, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO1(GUIO_NOASPECT) },
// Shivers - English Windows Demo
// Executable scanning reports "2.100.002"
@@ -3122,7 +3133,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resmap.000", 0, "d9e0bc5eddefcbe47f528760085d8927", 1186},
{"ressci.000", 0, "3a93c6340b54e07e65d0e5583354d186", 10505469},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformWindows, ADGF_DEMO | ADGF_UNSTABLE, GUIO1(GUIO_NONE) },
+ Common::EN_ANY, Common::kPlatformWindows, ADGF_DEMO | ADGF_UNSTABLE, GUIO1(GUIO_NOASPECT) },
// Shivers 2 doesn't contain SCI scripts. The whole game logic has
// been reimplemented from SCI in native code placed in DLL files.
@@ -3140,7 +3151,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resmap.000", 0, "d8659188b84beaef076bd869837cd530", 634},
{"ressci.000", 0, "7fbac0807a044c9543e8ac376d200e59", 4925003},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformWindows, ADGF_DEMO | ADGF_UNSTABLE, GUIO1(GUIO_NONE) },
+ Common::EN_ANY, Common::kPlatformWindows, ADGF_DEMO | ADGF_UNSTABLE, GUIO1(GUIO_NOASPECT) },
// Shivers 2 - English Windows (from abevi)
// VERSION.TXT Version 1.0 (3/25/97)
@@ -3148,7 +3159,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"ressci.001", 0, "a79d03d6eb75be0a79324f14e3d2ace4", 95346793},
{"resmap.001", 0, "a4804d436d90c4ec2e46b537f5e954db", 6268},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO1(GUIO_NOSPEECH) },
+ Common::EN_ANY, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO2(GUIO_NOSPEECH, GUIO_NOASPECT) },
#endif
@@ -3180,6 +3191,13 @@ static const struct ADGameDescription SciGameDescriptions[] = {
AD_LISTEND},
Common::EN_ANY, Common::kPlatformPC, 0, GUIO1(GUIO_NOSPEECH) },
+ // Slater & Charlie Go Camping - English Macintosh
+ {"slater", "", {
+ {"Data1", 0, "7243b4390e5f0182d8133fbcae4b50c5", 2298853},
+ {"Data2", 0, "6b6f18f9b502dc0923eeae0ef47f02d5", 2276956},
+ AD_LISTEND},
+ Common::EN_ANY, Common::kPlatformMacintosh, ADGF_MACRESFORK, GUIO1(GUIO_NONE) },
+
// Space Quest 1 VGA Remake - English Amiga (from www.back2roots.org)
// SCI interpreter version 1.000.510 (just a guess)
{"sq1sci", "SCI", {
@@ -3250,7 +3268,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.004", 0, "975c6e81194ae6b65e960a248129ecaa", 684119},
{"resource.005", 0, "13d96f7905637552c0647175ff816145", 695589},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformPC, 0, GUIO1(GUIO_NOSPEECH) },
+ Common::EN_ANY, Common::kPlatformPC, 0, GUIO2(GUIO_NOSPEECH, GUIO_EGAUNDITHER) },
// Space Quest 3 - English Amiga (from www.back2roots.org)
// SCI interpreter version 0.000.453 (just a guess)
@@ -3261,7 +3279,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.003", 0, "ceeda7202b96e5c85ecaa88a40a540fc", 746496},
{"resource.004", 0, "ceeda7202b96e5c85ecaa88a40a540fc", 761984},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO1(GUIO_NOSPEECH) },
+ Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO2(GUIO_NOSPEECH, GUIO_EGAUNDITHER) },
// Space Quest 3 - German Amiga (also includes english language)
// Executable scanning reports "1.004.006"
@@ -3274,7 +3292,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.004", 0, "6d8f34090503ce937e7dbef6cb6cdb6a", 545053},
{"resource.005", 0, "6d8f34090503ce937e7dbef6cb6cdb6a", 687507},
AD_LISTEND},
- Common::DE_DEU, Common::kPlatformAmiga, ADGF_ADDENGLISH, GUIO1(GUIO_NOSPEECH) },
+ Common::DE_DEU, Common::kPlatformAmiga, ADGF_ADDENGLISH, GUIO2(GUIO_NOSPEECH, GUIO_EGAUNDITHER) },
// Space Quest 3 - English DOS Non-Interactive Demo
// SCI interpreter version 0.000.453
@@ -3282,7 +3300,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "ec66ac2b1ce58b2575ba00b65058de1a", 612},
{"resource.001", 0, "ceeda7202b96e5c85ecaa88a40a540fc", 180245},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO1(GUIO_NOSPEECH) },
+ Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO2(GUIO_NOSPEECH, GUIO_EGAUNDITHER) },
// Space Quest 3 - English DOS (provided by richiefs in bug report #2670691)
// SCI interpreter version 0.000.453
@@ -3292,7 +3310,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.002", 0, "ceeda7202b96e5c85ecaa88a40a540fc", 720244},
{"resource.003", 0, "ceeda7202b96e5c85ecaa88a40a540fc", 688367},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformPC, 0, GUIO1(GUIO_NOSPEECH) },
+ Common::EN_ANY, Common::kPlatformPC, 0, GUIO2(GUIO_NOSPEECH, GUIO_EGAUNDITHER) },
// Space Quest 3 - English DOS (from the Space Quest Collection)
// Executable scanning reports "0.000.685", VERSION file reports "1.018"
@@ -3302,7 +3320,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.002", 0, "8b55c4875298f45ea5696a5ee8f6a7fe", 715777},
{"resource.003", 0, "8b55c4875298f45ea5696a5ee8f6a7fe", 703370},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformPC, 0, GUIO1(GUIO_NOSPEECH) },
+ Common::EN_ANY, Common::kPlatformPC, 0, GUIO2(GUIO_NOSPEECH, GUIO_EGAUNDITHER) },
// Space Quest 3 - English DOS (from abevi, bug report #2612718)
{"sq3", "", {
@@ -3314,7 +3332,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.005", 0, "ceeda7202b96e5c85ecaa88a40a540fc", 328278},
{"resource.006", 0, "ceeda7202b96e5c85ecaa88a40a540fc", 356702},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformPC, 0, GUIO1(GUIO_NOSPEECH) },
+ Common::EN_ANY, Common::kPlatformPC, 0, GUIO2(GUIO_NOSPEECH, GUIO_EGAUNDITHER) },
// Space Quest 3 - English Mac (from Fingolfin)
{"sq3", "", {
@@ -3323,7 +3341,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.002", 0, "0d8dfe42683b46f3131823233a91ce6a", 794072},
{"resource.003", 0, "0d8dfe42683b46f3131823233a91ce6a", 776536},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformMacintosh, 0, GUIO1(GUIO_NOSPEECH) },
+ Common::EN_ANY, Common::kPlatformMacintosh, 0, GUIO2(GUIO_NOSPEECH, GUIO_EGAUNDITHER) },
// Space Quest 3 - German DOS (from Tobis87, also includes english language)
// SCI interpreter version 0.000.453 (?)
@@ -3337,7 +3355,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.006", 0, "9107c2aa5398e28b5c5406df13491f85", 320643},
{"resource.007", 0, "9107c2aa5398e28b5c5406df13491f85", 344287},
AD_LISTEND},
- Common::DE_DEU, Common::kPlatformPC, ADGF_ADDENGLISH, GUIO1(GUIO_NOSPEECH) },
+ Common::DE_DEU, Common::kPlatformPC, ADGF_ADDENGLISH, GUIO2(GUIO_NOSPEECH, GUIO_EGAUNDITHER) },
// Space Quest 3 v1.052 - German DOS (supplied by markcoolio in bug report #2723860, also includes english language)
// Executable scanning reports "S.old.114"
@@ -3433,7 +3451,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.004", 0, "9a673e33c3f6dd560b993ffed77eeb49", 534994},
{"resource.005", 0, "3c4841d0a3ebba4404af588c93620c22", 595465},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformPC, 0, GUIO1(GUIO_NOSPEECH) },
+ Common::EN_ANY, Common::kPlatformPC, 0, GUIO2(GUIO_NOSPEECH, GUIO_EGAUNDITHER) },
// Space Quest 4 - German DOS (from Tobis87, also includes english language)
// SCI interpreter version 1.000.200 (just a guess)
@@ -3470,7 +3488,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.001", 0, "454684e3a7a68cbca073945e50778447", 1187088},
{"resource.002", 0, "6dc668326cc22cb9e8bd8ca9e68d2a66", 1181249},
AD_LISTEND},
- Common::JA_JPN, Common::kPlatformPC98, ADGF_ADDENGLISH, GUIO1(GUIO_NOSPEECH) },
+ Common::JA_JPN, Common::kPlatformPC98, ADGF_ADDENGLISH, GUIO2(GUIO_NOSPEECH, GUIO_NOASPECT) },
// Space Quest 4 - Japanese PC-98 5.25" Floppy (also includes english language)
// SCI interpreter version 1.000.1068
@@ -3480,7 +3498,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.001", 0, "454684e3a7a68cbca073945e50778447", 1187088},
{"resource.002", 0, "6dc668326cc22cb9e8bd8ca9e68d2a66", 1181249},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformPC98, ADGF_ADDENGLISH, GUIO1(GUIO_NOSPEECH) },
+ Common::EN_ANY, Common::kPlatformPC98, ADGF_ADDENGLISH, GUIO2(GUIO_NOSPEECH, GUIO_NOASPECT) },
// Space Quest 4 - English DOS CD (from the Space Quest Collection)
// Executable scanning reports "1.001.064", VERSION file reports "1.0"
@@ -3488,7 +3506,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "ed90a8e3ccc53af6633ff6ab58392bae", 7054},
{"resource.000", 0, "63247e3901ab8963d4eece73747832e0", 5157378},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformPC, ADGF_CD, GUIO1(GUIO_NONE) },
+ Common::EN_ANY, Common::kPlatformPC, ADGF_CD, GUIO0() },
// Space Quest 4 - English Windows CD (from the Space Quest Collection)
// Executable scanning reports "1.001.064", VERSION file reports "1.0"
@@ -3512,7 +3530,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.004", 0, "776fba81c110d1908776232cbe190e20", 1253752},
{"resource.005", 0, "55fae26c2a92f16ef72c1e216e827c0f", 1098328},
AD_LISTEND},
- Common::ES_ESP, Common::kPlatformPC, ADGF_ADDENGLISH, GUIO1(GUIO_NONE) },
+ Common::ES_ESP, Common::kPlatformPC, ADGF_ADDENGLISH, GUIO0() },
// Space Quest 4 - Spanish DOS Floppy (from jvprat, also includes english language)
// Executable scanning reports "1.SQ4.056", VERSION file reports "1.000"
@@ -3635,7 +3653,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "6dddfa3a8f3a3a513ec9dfdfae955005", 10528},
{"resource.000", 0, "c4259ab7355aead07773397b1052827d", 41150806},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformPC, ADGF_CD | ADGF_UNSTABLE, GUIO1(GUIO_NONE) },
+ Common::EN_ANY, Common::kPlatformPC, ADGF_CD | ADGF_UNSTABLE, GUIO1(GUIO_NOASPECT) },
// Space Quest 6 - English DOS/Win3.11 CD ver 1.11 (from FRG)
// SCI interpreter version 2.100.002 (just a guess)
@@ -3643,7 +3661,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "e0615d6e4e10e37ae42e6a2a95aaf145", 10528},
{"resource.000", 0, "c4259ab7355aead07773397b1052827d", 41150806},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformPC, ADGF_CD | ADGF_UNSTABLE, GUIO1(GUIO_NONE) },
+ Common::EN_ANY, Common::kPlatformPC, ADGF_CD | ADGF_UNSTABLE, GUIO1(GUIO_NOASPECT) },
// 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"
@@ -3651,7 +3669,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "3c831625931d5079b73ae8c275f52c95", 10534},
{"resource.000", 0, "4195ca940f759424f62b90e262cc1737", 40932397},
AD_LISTEND},
- Common::FR_FRA, Common::kPlatformPC, ADGF_CD | ADGF_UNSTABLE, GUIO1(GUIO_NONE) },
+ Common::FR_FRA, Common::kPlatformPC, ADGF_CD | ADGF_UNSTABLE, GUIO1(GUIO_NOASPECT) },
// Space Quest 6 - German DOS (from Tobis87, updated info from markcoolio in bug report #2723884)
// SCI interpreter version 2.100.002 (just a guess)
@@ -3659,7 +3677,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "664d797415484f85c90b1b45aedc7686", 10534},
{"resource.000", 0, "ba87ba91e5bdabb4169dd0df75777722", 40933685},
AD_LISTEND},
- Common::DE_DEU, Common::kPlatformPC, ADGF_CD | ADGF_UNSTABLE, GUIO1(GUIO_NONE) },
+ Common::DE_DEU, Common::kPlatformPC, ADGF_CD | ADGF_UNSTABLE, GUIO1(GUIO_NOASPECT) },
// Space Quest 6 - English DOS/Win3.11 Interactive Demo (from FRG)
// SCI interpreter version 2.100.002 (just a guess)
@@ -3667,7 +3685,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 | ADGF_UNSTABLE, GUIO1(GUIO_NOSPEECH) },
+ Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO | ADGF_UNSTABLE, GUIO2(GUIO_NOSPEECH, GUIO_NOASPECT) },
#endif // ENABLE_SCI32
// The Island of Dr. Brain - English DOS CD (from jvprat)
@@ -3676,7 +3694,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "2388efef8430b041b0f3b00b9050e4a2", 3281},
{"resource.000", 0, "b3acd9b9dd7fe53c4ee133ac9a1acfab", 2103560},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformPC, 0, GUIO1(GUIO_NONE) },
+ Common::EN_ANY, Common::kPlatformPC, 0, GUIO0() },
// The Island of Dr. Brain - English DOS (from Quietust)
// Executable scanning reports "1.001.053", VERSION file reports "1.1 2.3.93"
@@ -3701,7 +3719,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resmap.000", 0, "9a3e172cde9963d0a969f26469318cec", 3403},
{"ressci.000", 0, "db3e290481c35c3224e9602e71e4a1f1", 5073868},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformWindows, ADGF_DEMO | ADGF_UNSTABLE, GUIO1(GUIO_NOSPEECH) },
+ Common::EN_ANY, Common::kPlatformWindows, ADGF_DEMO | ADGF_UNSTABLE, GUIO2(GUIO_NOSPEECH, GUIO_NOASPECT) },
// Torin's Passage - English Windows
// SCI interpreter version 2.100.002 (just a guess)
@@ -3709,7 +3727,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resmap.000", 0, "bb3b0b22ff08df54fbe2d06263409be6", 9799},
{"ressci.000", 0, "693a259d346c9360f4a0c11fdaae430a", 55973887},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO1(GUIO_NOSPEECH) },
+ Common::EN_ANY, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO2(GUIO_NOSPEECH, GUIO_NOASPECT) },
// Torin's Passage - Spanish Windows (from jvprat)
// Executable scanning reports "2.100.002", VERSION file reports "1.0"
@@ -3718,7 +3736,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"ressci.000", 0, "693a259d346c9360f4a0c11fdaae430a", 55973887},
// TODO: depend on one of the patches?
AD_LISTEND},
- Common::ES_ESP, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO1(GUIO_NOSPEECH) },
+ Common::ES_ESP, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO2(GUIO_NOSPEECH, GUIO_NOASPECT) },
// Torin's Passage - French Windows
// SCI interpreter version 2.100.002 (just a guess)
@@ -3726,7 +3744,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resmap.000", 0, "bb3b0b22ff08df54fbe2d06263409be6", 9799},
{"ressci.000", 0, "693a259d346c9360f4a0c11fdaae430a", 55973887},
AD_LISTEND},
- Common::FR_FRA, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO1(GUIO_NOSPEECH) },
+ Common::FR_FRA, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO2(GUIO_NOSPEECH, GUIO_NOASPECT) },
// Torin's Passage - German Windows
// SCI interpreter version 2.100.002 (just a guess)
@@ -3734,7 +3752,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resmap.000", 0, "bb3b0b22ff08df54fbe2d06263409be6", 9799},
{"ressci.000", 0, "693a259d346c9360f4a0c11fdaae430a", 55973887},
AD_LISTEND},
- Common::DE_DEU, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO1(GUIO_NOSPEECH) },
+ Common::DE_DEU, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO2(GUIO_NOSPEECH, GUIO_NOASPECT) },
// Torin's Passage - Italian Windows CD (from glorifindel)
// SCI interpreter version 2.100.002 (just a guess)
@@ -3742,7 +3760,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resmap.000", 0, "bb3b0b22ff08df54fbe2d06263409be6", 9799},
{"ressci.000", 0, "693a259d346c9360f4a0c11fdaae430a", 55973887},
AD_LISTEND},
- Common::IT_ITA, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO1(GUIO_NONE) },
+ Common::IT_ITA, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO1(GUIO_NOASPECT) },
#endif // ENABLE_SCI32
// SCI Fanmade Games
diff --git a/engines/sci/engine/features.cpp b/engines/sci/engine/features.cpp
index a5c1b970f1..b3cfee873c 100644
--- a/engines/sci/engine/features.cpp
+++ b/engines/sci/engine/features.cpp
@@ -430,19 +430,16 @@ SciVersion GameFeatures::detectMessageFunctionType() {
return _messageFunctionType;
}
- Common::List<ResourceId> *resources = g_sci->getResMan()->listResources(kResourceTypeMessage, -1);
-
- if (resources->empty()) {
- delete resources;
+ Common::List<ResourceId> resources = g_sci->getResMan()->listResources(kResourceTypeMessage, -1);
+ if (resources.empty()) {
// No messages found, so this doesn't really matter anyway...
_messageFunctionType = SCI_VERSION_1_1;
return _messageFunctionType;
}
- Resource *res = g_sci->getResMan()->findResource(*resources->begin(), false);
+ Resource *res = g_sci->getResMan()->findResource(*resources.begin(), false);
assert(res);
- delete resources;
// Only v2 Message resources use the kGetMessage kernel function.
// v3-v5 use the kMessage kernel function.
diff --git a/engines/sci/engine/kernel.cpp b/engines/sci/engine/kernel.cpp
index 6f783d79e8..c99bc4fe47 100644
--- a/engines/sci/engine/kernel.cpp
+++ b/engines/sci/engine/kernel.cpp
@@ -914,28 +914,32 @@ Common::String Kernel::lookupText(reg_t address, int index) {
// TODO: script_adjust_opcode_formats should probably be part of the
// constructor (?) of a VirtualMachine or a ScriptManager class.
void script_adjust_opcode_formats() {
+
+ g_sci->_opcode_formats = new opcode_format[128][4];
+ memcpy(g_sci->_opcode_formats, g_base_opcode_formats, 128*4*sizeof(opcode_format));
+
if (g_sci->_features->detectLofsType() != SCI_VERSION_0_EARLY) {
- g_opcode_formats[op_lofsa][0] = Script_Offset;
- g_opcode_formats[op_lofss][0] = Script_Offset;
+ g_sci->_opcode_formats[op_lofsa][0] = Script_Offset;
+ g_sci->_opcode_formats[op_lofss][0] = Script_Offset;
}
#ifdef ENABLE_SCI32
// In SCI32, some arguments are now words instead of bytes
if (getSciVersion() >= SCI_VERSION_2) {
- g_opcode_formats[op_calle][2] = Script_Word;
- g_opcode_formats[op_callk][1] = Script_Word;
- g_opcode_formats[op_super][1] = Script_Word;
- g_opcode_formats[op_send][0] = Script_Word;
- g_opcode_formats[op_self][0] = Script_Word;
- g_opcode_formats[op_call][1] = Script_Word;
- g_opcode_formats[op_callb][1] = Script_Word;
+ g_sci->_opcode_formats[op_calle][2] = Script_Word;
+ g_sci->_opcode_formats[op_callk][1] = Script_Word;
+ g_sci->_opcode_formats[op_super][1] = Script_Word;
+ g_sci->_opcode_formats[op_send][0] = Script_Word;
+ g_sci->_opcode_formats[op_self][0] = Script_Word;
+ g_sci->_opcode_formats[op_call][1] = Script_Word;
+ g_sci->_opcode_formats[op_callb][1] = Script_Word;
}
if (getSciVersion() >= SCI_VERSION_3) {
// TODO: There are also opcodes in
// here to get the superclass, and possibly the species too.
- g_opcode_formats[0x4d/2][0] = Script_None;
- g_opcode_formats[0x4e/2][0] = Script_None;
+ g_sci->_opcode_formats[0x4d/2][0] = Script_None;
+ g_sci->_opcode_formats[0x4e/2][0] = Script_None;
}
#endif
}
diff --git a/engines/sci/engine/kernel.h b/engines/sci/engine/kernel.h
index 8cb294e166..e549c1f8ae 100644
--- a/engines/sci/engine/kernel.h
+++ b/engines/sci/engine/kernel.h
@@ -457,6 +457,7 @@ reg_t kListFirstTrue(EngineState *s, int argc, reg_t *argv);
reg_t kListAllTrue(EngineState *s, int argc, reg_t *argv);
reg_t kInPolygon(EngineState *s, int argc, reg_t *argv);
reg_t kObjectIntersect(EngineState *s, int argc, reg_t *argv);
+reg_t kEditText(EngineState *s, int argc, reg_t *argv);
// SCI2.1 Kernel Functions
reg_t kText(EngineState *s, int argc, reg_t *argv);
diff --git a/engines/sci/engine/kernel_tables.h b/engines/sci/engine/kernel_tables.h
index afe6b176e5..622511c906 100644
--- a/engines/sci/engine/kernel_tables.h
+++ b/engines/sci/engine/kernel_tables.h
@@ -24,7 +24,7 @@
#define SCI_ENGINE_KERNEL_TABLES_H
#include "sci/engine/workarounds.h"
-#include "sci/engine/vm.h" // for opcode_formats
+#include "sci/engine/vm_types.h" // for opcode_formats
namespace Sci {
@@ -499,6 +499,7 @@ static SciKernelMapEntry s_kernelMap[] = {
{ MAP_CALL(UpdatePlane), SIG_EVERYWHERE, "o", NULL, NULL },
{ MAP_CALL(UpdateScreenItem), SIG_EVERYWHERE, "o", NULL, NULL },
{ MAP_CALL(ObjectIntersect), SIG_EVERYWHERE, "oo", NULL, NULL },
+ { MAP_CALL(EditText), SIG_EVERYWHERE, "o", NULL, NULL },
// SCI2 unmapped functions - TODO!
@@ -523,13 +524,6 @@ static SciKernelMapEntry s_kernelMap[] = {
// TODO: Implement once the original save/load menus are implemented.
{ MAP_DUMMY(MakeSaveFileName), SIG_EVERYWHERE, "(.*)", NULL, NULL },
- // Used for edit boxes in save/load dialogs. It's a rewritten version of kEditControl,
- // but it handles events on its own, using an internal loop, instead of using SCI
- // scripts for event management like kEditControl does. Called by script 64914,
- // DEdit::hilite().
- // TODO: Implement once the original save/load menus are implemented.
- { MAP_DUMMY(EditText), SIG_EVERYWHERE, "o", NULL, NULL },
-
// Unused / debug SCI2 unused functions, always mapped to kDummy
// AddMagnify/DeleteMagnify are both called by script 64979 (the Magnifier
@@ -616,6 +610,12 @@ static SciKernelMapEntry s_kernelMap[] = {
{ MAP_DUMMY(DeletePic), SIG_EVERYWHERE, "(.*)", NULL, NULL },
{ MAP_DUMMY(GetSierraProfileString), SIG_EVERYWHERE, "(.*)", NULL, NULL },
+ // Unused / debug functions in the in-between SCI2.1 interpreters
+ { MAP_DUMMY(PreloadResource), SIG_EVERYWHERE, "(.*)", NULL, NULL },
+ { MAP_DUMMY(CheckCDisc), SIG_EVERYWHERE, "(.*)", NULL, NULL },
+ { MAP_DUMMY(GetSaveCDisc), SIG_EVERYWHERE, "(.*)", NULL, NULL },
+ { MAP_DUMMY(TestPoly), SIG_EVERYWHERE, "(.*)", NULL, NULL },
+
// SCI2.1 unmapped functions - TODO!
// MovePlaneItems - used by SQ6 to scroll through the inventory via the up/down buttons
@@ -1116,7 +1116,9 @@ static const char *const sci21_default_knames[] = {
#endif
-opcode_format g_opcode_formats[128][4] = {
+// Base set of opcode formats. They're copied and adjusted slightly in
+// script_adjust_opcode_format depending on SCI version.
+static const opcode_format g_base_opcode_formats[128][4] = {
/*00*/
{Script_None}, {Script_None}, {Script_None}, {Script_None},
/*04*/
diff --git a/engines/sci/engine/kfile.cpp b/engines/sci/engine/kfile.cpp
index 9e9441847d..312497720a 100644
--- a/engines/sci/engine/kfile.cpp
+++ b/engines/sci/engine/kfile.cpp
@@ -22,7 +22,9 @@
#include "common/archive.h"
#include "common/config-manager.h"
+#include "common/debug-channels.h"
#include "common/file.h"
+#include "common/macresman.h"
#include "common/str.h"
#include "common/savefile.h"
#include "common/system.h"
@@ -52,9 +54,10 @@ struct SavegameDesc {
* arbitrary data files, simply because many of our target platforms do not
* support this. The only files one can create are savestates. But SCI has an
* opcode to create and write to seemingly 'arbitrary' files. This is mainly
- * used in LSL3 for LARRY3.DRV (which is a game data file, not a driver) and
- * in LSL5 for MEMORY.DRV (which is again a game data file and contains the
- * game's password).
+ * used in LSL3 for LARRY3.DRV (which is a game data file, not a driver, used
+ * for persisting the results of the "age quiz" across restarts) and in LSL5
+ * for MEMORY.DRV (which is again a game data file and contains the game's
+ * password, XOR encrypted).
* To implement that opcode, we combine the SaveFileManager with regular file
* code, similarly to how the SCUMM HE engine does it.
*
@@ -115,20 +118,6 @@ reg_t file_open(EngineState *s, const Common::String &filename, int mode, bool u
if (!inFile)
inFile = SearchMan.createReadStreamForMember(englishName);
- // Special case for LSL3: It tries to create a new dummy file,
- // LARRY3.DRV. Apparently, if the file doesn't exist here, it should be
- // created. The game scripts then go ahead and fill its contents with
- // data. It seems to be a similar case as the dummy MEMORY.DRV file in
- // LSL5, but LSL5 creates the file if it can't find it with a separate
- // call to file_open().
- if (!inFile && englishName == "LARRY3.DRV") {
- outFile = saveFileMan->openForSaving(wrappedName);
- outFile->finalize();
- delete outFile;
- outFile = 0;
- inFile = SearchMan.createReadStreamForMember(wrappedName);
- }
-
if (!inFile)
debugC(kDebugLevelFile, " -> file_open(_K_FILE_MODE_OPEN_OR_FAIL): failed to open file '%s'", englishName.c_str());
} else if (mode == _K_FILE_MODE_CREATE) {
@@ -835,7 +824,7 @@ reg_t kFileIOWriteRaw(EngineState *s, int argc, reg_t *argv) {
int size = argv[2].toUint16();
char *buf = new char[size];
bool success = false;
- s->_segMan->memcpy((byte*)buf, argv[1], size);
+ s->_segMan->memcpy((byte *)buf, argv[1], size);
debugC(kDebugLevelFile, "kFileIO(writeRaw): %d, %d", handle, size);
FileHandle *f = getFileFromHandle(s, handle);
@@ -1060,6 +1049,18 @@ reg_t kFileIOExists(EngineState *s, int argc, reg_t *argv) {
exists = !saveFileMan->listSavefiles(wrappedName).empty();
}
+ // SCI2+ debug mode
+ if (DebugMan.isDebugChannelEnabled(kDebugLevelDebugMode)) {
+ if (!exists && name == "1.scr") // PQ4
+ exists = true;
+ if (!exists && name == "18.scr") // QFG4
+ exists = true;
+ if (!exists && name == "99.scr") // GK1, KQ7
+ exists = true;
+ if (!exists && name == "classes") // GK2, SQ6, LSL7
+ exists = true;
+ }
+
// Special case for non-English versions of LSL5: The English version of
// LSL5 calls kFileIO(), case K_FILEIO_OPEN for reading to check if
// memory.drv exists (which is where the game's password is stored). If
@@ -1080,6 +1081,14 @@ reg_t kFileIOExists(EngineState *s, int argc, reg_t *argv) {
delete outFile;
}
+ // Special case for KQ6 Mac: The game checks for two video files to see
+ // if they exist before it plays them. Since we support multiple naming
+ // schemes for resource fork files, we also need to support that here in
+ // case someone has a "HalfDome.bin" file, etc.
+ if (!exists && g_sci->getGameId() == GID_KQ6 && g_sci->getPlatform() == Common::kPlatformMacintosh &&
+ (name == "HalfDome" || name == "Kq6Movie"))
+ exists = Common::MacResManager::exists(name);
+
debugC(kDebugLevelFile, "kFileIO(fileExists) %s -> %d", name.c_str(), exists);
return make_reg(0, exists);
}
diff --git a/engines/sci/engine/kgraphics.cpp b/engines/sci/engine/kgraphics.cpp
index ea2b4816fc..caae562d67 100644
--- a/engines/sci/engine/kgraphics.cpp
+++ b/engines/sci/engine/kgraphics.cpp
@@ -25,6 +25,7 @@
#include "engines/util.h"
#include "graphics/cursorman.h"
#include "graphics/surface.h"
+#include "graphics/palette.h" // temporary, for the fadeIn()/fadeOut() functions below
#include "gui/message.h"
@@ -39,7 +40,7 @@
#include "sci/graphics/animate.h"
#include "sci/graphics/cache.h"
#include "sci/graphics/compare.h"
-#include "sci/graphics/controls.h"
+#include "sci/graphics/controls16.h"
#include "sci/graphics/cursor.h"
#include "sci/graphics/palette.h"
#include "sci/graphics/paint16.h"
@@ -49,6 +50,7 @@
#include "sci/graphics/text16.h"
#include "sci/graphics/view.h"
#ifdef ENABLE_SCI32
+#include "sci/graphics/controls32.h"
#include "sci/graphics/font.h" // TODO: remove once kBitmap is moved in a separate class
#include "sci/graphics/text32.h"
#include "sci/graphics/frameout.h"
@@ -57,11 +59,13 @@
namespace Sci {
static int16 adjustGraphColor(int16 color) {
- // WORKAROUND: SCI1 EGA and Amiga games can set invalid colors (above 0 - 15).
- // Colors above 15 are all white in SCI1 EGA games, which is why this was never
- // observed. We clip them all to (0, 15) instead, as colors above 15 are used
- // for the undithering algorithm in EGA games - bug #3048908.
- if (getSciVersion() >= SCI_VERSION_1_EARLY && g_sci->getResMan()->getViewType() == kViewEga)
+ // WORKAROUND: EGA and Amiga games can set invalid colors (above 0 - 15).
+ // It seems only the lower nibble was used in these games.
+ // bug #3048908, #3486899.
+ // Confirmed in EGA games KQ4(late), QFG1(ega), LB1 that
+ // at least FillBox (only one of the functions using adjustGraphColor)
+ // behaves like this.
+ if (g_sci->getResMan()->getViewType() == kViewEga)
return color & 0x0F; // 0 - 15
else
return color;
@@ -810,13 +814,13 @@ void _k_GenericDrawControl(EngineState *s, reg_t controlObject, bool hilite) {
switch (type) {
case SCI_CONTROLS_TYPE_BUTTON:
debugC(kDebugLevelGraphics, "drawing button %04x:%04x to %d,%d", PRINT_REG(controlObject), x, y);
- g_sci->_gfxControls->kernelDrawButton(rect, controlObject, g_sci->strSplit(text.c_str(), NULL).c_str(), fontId, style, hilite);
+ g_sci->_gfxControls16->kernelDrawButton(rect, controlObject, g_sci->strSplit(text.c_str(), NULL).c_str(), fontId, style, hilite);
return;
case SCI_CONTROLS_TYPE_TEXT:
alignment = readSelectorValue(s->_segMan, controlObject, SELECTOR(mode));
debugC(kDebugLevelGraphics, "drawing text %04x:%04x ('%s') to %d,%d, mode=%d", PRINT_REG(controlObject), text.c_str(), x, y, alignment);
- g_sci->_gfxControls->kernelDrawText(rect, controlObject, g_sci->strSplit(text.c_str()).c_str(), fontId, alignment, style, hilite);
+ g_sci->_gfxControls16->kernelDrawText(rect, controlObject, g_sci->strSplit(text.c_str()).c_str(), fontId, alignment, style, hilite);
s->r_acc = g_sci->_gfxText16->allocAndFillReferenceRectArray();
return;
@@ -830,7 +834,7 @@ void _k_GenericDrawControl(EngineState *s, reg_t controlObject, bool hilite) {
writeSelectorValue(s->_segMan, controlObject, SELECTOR(cursor), cursorPos);
}
debugC(kDebugLevelGraphics, "drawing edit control %04x:%04x (text %04x:%04x, '%s') to %d,%d", PRINT_REG(controlObject), PRINT_REG(textReference), text.c_str(), x, y);
- g_sci->_gfxControls->kernelDrawTextEdit(rect, controlObject, g_sci->strSplit(text.c_str(), NULL).c_str(), fontId, mode, style, cursorPos, maxChars, hilite);
+ g_sci->_gfxControls16->kernelDrawTextEdit(rect, controlObject, g_sci->strSplit(text.c_str(), NULL).c_str(), fontId, mode, style, cursorPos, maxChars, hilite);
return;
case SCI_CONTROLS_TYPE_ICON:
@@ -847,7 +851,7 @@ void _k_GenericDrawControl(EngineState *s, reg_t controlObject, bool hilite) {
priority = -1;
}
debugC(kDebugLevelGraphics, "drawing icon control %04x:%04x to %d,%d", PRINT_REG(controlObject), x, y - 1);
- g_sci->_gfxControls->kernelDrawIcon(rect, controlObject, viewId, loopNo, celNo, priority, style, hilite);
+ g_sci->_gfxControls16->kernelDrawIcon(rect, controlObject, viewId, loopNo, celNo, priority, style, hilite);
return;
case SCI_CONTROLS_TYPE_LIST:
@@ -895,7 +899,7 @@ void _k_GenericDrawControl(EngineState *s, reg_t controlObject, bool hilite) {
}
debugC(kDebugLevelGraphics, "drawing list control %04x:%04x to %d,%d, diff %d", PRINT_REG(controlObject), x, y, SCI_MAX_SAVENAME_LENGTH);
- g_sci->_gfxControls->kernelDrawList(rect, controlObject, maxChars, listCount, listEntries, fontId, style, upperPos, cursorPos, isAlias, hilite);
+ g_sci->_gfxControls16->kernelDrawList(rect, controlObject, maxChars, listCount, listEntries, fontId, style, upperPos, cursorPos, isAlias, hilite);
free(listEntries);
delete[] listStrings;
return;
@@ -975,7 +979,10 @@ reg_t kEditControl(EngineState *s, int argc, reg_t *argv) {
switch (controlType) {
case SCI_CONTROLS_TYPE_TEXTEDIT:
// Only process textedit controls in here
- g_sci->_gfxControls->kernelTexteditChange(controlObject, eventObject);
+ g_sci->_gfxControls16->kernelTexteditChange(controlObject, eventObject);
+ break;
+ default:
+ break;
}
}
return s->r_acc;
@@ -1208,7 +1215,8 @@ reg_t kRemapColors(EngineState *s, int argc, reg_t *argv) {
switch (operation) {
case 0: { // Set remapping to base. 0 turns remapping off.
int16 base = (argc >= 2) ? argv[1].toSint16() : 0;
- warning("kRemapColors: Set remapping to base %d", base);
+ if (base != 0) // 0 is the default behavior when changing rooms in GK1, thus silencing the warning
+ warning("kRemapColors: Set remapping to base %d", base);
}
break;
case 1: { // unknown
@@ -1436,6 +1444,46 @@ reg_t kWinHelp(EngineState *s, int argc, reg_t *argv) {
return s->r_acc;
}
+// Taken from the SCI16 GfxTransitions class
+static void fadeOut() {
+ byte oldPalette[3 * 256], workPalette[3 * 256];
+ int16 stepNr, colorNr;
+ // Sierra did not fade in/out color 255 for sci1.1, but they used it in
+ // several pictures (e.g. qfg3 demo/intro), so the fading looked weird
+ int16 tillColorNr = getSciVersion() >= SCI_VERSION_1_1 ? 255 : 254;
+
+ g_system->getPaletteManager()->grabPalette(oldPalette, 0, 256);
+
+ for (stepNr = 100; stepNr >= 0; stepNr -= 10) {
+ for (colorNr = 1; colorNr <= tillColorNr; colorNr++) {
+ if (g_sci->_gfxPalette->colorIsFromMacClut(colorNr)) {
+ workPalette[colorNr * 3 + 0] = oldPalette[colorNr * 3];
+ workPalette[colorNr * 3 + 1] = oldPalette[colorNr * 3 + 1];
+ workPalette[colorNr * 3 + 2] = oldPalette[colorNr * 3 + 2];
+ } else {
+ workPalette[colorNr * 3 + 0] = oldPalette[colorNr * 3] * stepNr / 100;
+ workPalette[colorNr * 3 + 1] = oldPalette[colorNr * 3 + 1] * stepNr / 100;
+ workPalette[colorNr * 3 + 2] = oldPalette[colorNr * 3 + 2] * stepNr / 100;
+ }
+ }
+ g_system->getPaletteManager()->setPalette(workPalette + 3, 1, tillColorNr);
+ g_sci->getEngineState()->wait(2);
+ }
+}
+
+// Taken from the SCI16 GfxTransitions class
+static void fadeIn() {
+ int16 stepNr;
+ // Sierra did not fade in/out color 255 for sci1.1, but they used it in
+ // several pictures (e.g. qfg3 demo/intro), so the fading looked weird
+ int16 tillColorNr = getSciVersion() >= SCI_VERSION_1_1 ? 255 : 254;
+
+ for (stepNr = 0; stepNr <= 100; stepNr += 10) {
+ g_sci->_gfxPalette->kernelSetIntensity(1, tillColorNr + 1, stepNr, true);
+ g_sci->getEngineState()->wait(2);
+ }
+}
+
/**
* Used for scene transitions, replacing (but reusing parts of) the old
* transition code.
@@ -1446,31 +1494,65 @@ reg_t kSetShowStyle(EngineState *s, int argc, reg_t *argv) {
// tables inside graphics/transitions.cpp
uint16 showStyle = argv[0].toUint16(); // 0 - 15
reg_t planeObj = argv[1]; // the affected plane
- //argv[2] // seconds that the transition lasts
- //argv[3] // back color to be used(?)
- //int16 priority = argv[4].toSint16();
- //argv[5] // boolean, animate or not while the transition lasts
- //argv[6] // refFrame
+ uint16 seconds = argv[2].toUint16(); // seconds that the transition lasts
+ uint16 backColor = argv[3].toUint16(); // target back color(?). When fading out, it's 0x0000. When fading in, it's 0xffff
+ int16 priority = argv[4].toSint16(); // always 0xc8 (200) when fading in/out
+ uint16 animate = argv[5].toUint16(); // boolean, animate or not while the transition lasts
+ uint16 refFrame = argv[6].toUint16(); // refFrame, always 0 when fading in/out
+ int16 divisions;
// If the game has the pFadeArray selector, another parameter is used here,
// before the optional last parameter
- /*bool hasFadeArray = g_sci->getKernel()->findSelector("pFadeArray") > 0;
+ bool hasFadeArray = g_sci->getKernel()->findSelector("pFadeArray") > 0;
if (hasFadeArray) {
// argv[7]
- //int16 unk7 = (argc >= 9) ? argv[8].toSint16() : 0; // divisions (transition steps?)
+ divisions = (argc >= 9) ? argv[8].toSint16() : -1; // divisions (transition steps?)
} else {
- //int16 unk7 = (argc >= 8) ? argv[7].toSint16() : 0; // divisions (transition steps?)
- }*/
+ divisions = (argc >= 8) ? argv[7].toSint16() : -1; // divisions (transition steps?)
+ }
if (showStyle > 15) {
warning("kSetShowStyle: Illegal style %d for plane %04x:%04x", showStyle, PRINT_REG(planeObj));
return s->r_acc;
}
+ // TODO: Proper implementation. This is a very basic version. I'm not even
+ // sure if the rest of the styles will work with this mechanism.
+
+ // Check if the passed parameters are the ones we expect
+ if (showStyle == 13 || showStyle == 14) { // fade out / fade in
+ if (seconds != 1)
+ warning("kSetShowStyle(fade): seconds isn't 1, it's %d", seconds);
+ if (backColor != 0 && backColor != 0xFFFF)
+ warning("kSetShowStyle(fade): backColor isn't 0 or 0xFFFF, it's %d", backColor);
+ if (priority != 200)
+ warning("kSetShowStyle(fade): priority isn't 200, it's %d", priority);
+ if (animate != 0)
+ warning("kSetShowStyle(fade): animate isn't 0, it's %d", animate);
+ if (refFrame != 0)
+ warning("kSetShowStyle(fade): refFrame isn't 0, it's %d", refFrame);
+ if (divisions >= 0 && divisions != 20)
+ warning("kSetShowStyle(fade): divisions isn't 20, it's %d", divisions);
+ }
+
// TODO: Check if the plane is in the list of planes to draw
- // TODO: This is all a stub/skeleton, thus we're invoking kStub() for now
- kStub(s, argc, argv);
+ switch (showStyle) {
+ //case 0: // no transition, perhaps? (like in the previous SCI versions)
+ case 13: // fade out
+ // TODO: Temporary implementation, which ignores all additional parameters
+ fadeOut();
+ break;
+ case 14: // fade in
+ // TODO: Temporary implementation, which ignores all additional parameters
+ g_sci->_gfxFrameout->kernelFrameout(); // draw new scene before fading in
+ fadeIn();
+ break;
+ default:
+ // TODO: This is all a stub/skeleton, thus we're invoking kStub() for now
+ kStub(s, argc, argv);
+ break;
+ }
return s->r_acc;
}
@@ -1662,8 +1744,8 @@ reg_t kBitmap(EngineState *s, int argc, reg_t *argv) {
memset(memoryPtr + BITMAP_HEADER_SIZE, back, width * height);
// Save totalWidth, totalHeight
// TODO: Save the whole bitmap header, like SSCI does
- WRITE_LE_UINT16((void *)memoryPtr, width);
- WRITE_LE_UINT16((void *)(memoryPtr + 2), height);
+ WRITE_LE_UINT16(memoryPtr, width);
+ WRITE_LE_UINT16(memoryPtr + 2, height);
return memoryId;
}
break;
@@ -1689,8 +1771,8 @@ reg_t kBitmap(EngineState *s, int argc, reg_t *argv) {
byte *memoryPtr = s->_segMan->getHunkPointer(hunkId);
// Get totalWidth, totalHeight
- uint16 totalWidth = READ_LE_UINT16((void *)memoryPtr);
- uint16 totalHeight = READ_LE_UINT16((void *)(memoryPtr + 2));
+ uint16 totalWidth = READ_LE_UINT16(memoryPtr);
+ uint16 totalHeight = READ_LE_UINT16(memoryPtr + 2);
byte *bitmap = memoryPtr + BITMAP_HEADER_SIZE;
GfxView *view = g_sci->_gfxCache->getView(viewNum);
@@ -1730,8 +1812,8 @@ reg_t kBitmap(EngineState *s, int argc, reg_t *argv) {
byte *memoryPtr = s->_segMan->getHunkPointer(hunkId);
// Get totalWidth, totalHeight
- uint16 totalWidth = READ_LE_UINT16((void *)memoryPtr);
- uint16 totalHeight = READ_LE_UINT16((void *)(memoryPtr + 2));
+ uint16 totalWidth = READ_LE_UINT16(memoryPtr);
+ uint16 totalHeight = READ_LE_UINT16(memoryPtr + 2);
byte *bitmap = memoryPtr + BITMAP_HEADER_SIZE;
GfxFont *font = g_sci->_gfxCache->getFont(fontId);
@@ -1773,8 +1855,8 @@ reg_t kBitmap(EngineState *s, int argc, reg_t *argv) {
byte *memoryPtr = s->_segMan->getHunkPointer(hunkId);
// Get totalWidth, totalHeight
- uint16 totalWidth = READ_LE_UINT16((void *)memoryPtr);
- uint16 totalHeight = READ_LE_UINT16((void *)(memoryPtr + 2));
+ uint16 totalWidth = READ_LE_UINT16(memoryPtr);
+ uint16 totalHeight = READ_LE_UINT16(memoryPtr + 2);
uint16 width = MIN<uint16>(totalWidth - x, fillWidth);
uint16 height = MIN<uint16>(totalHeight - y, fillHeight);
byte *bitmap = memoryPtr + BITMAP_HEADER_SIZE;
@@ -1795,6 +1877,20 @@ reg_t kBitmap(EngineState *s, int argc, reg_t *argv) {
return s->r_acc;
}
+// Used for edit boxes in save/load dialogs. It's a rewritten version of kEditControl,
+// but it handles events on its own, using an internal loop, instead of using SCI
+// scripts for event management like kEditControl does. Called by script 64914,
+// DEdit::hilite().
+reg_t kEditText(EngineState *s, int argc, reg_t *argv) {
+ reg_t controlObject = argv[0];
+
+ if (!controlObject.isNull()) {
+ g_sci->_gfxControls32->kernelTexteditChange(controlObject);
+ }
+
+ return s->r_acc;
+}
+
#endif
} // End of namespace Sci
diff --git a/engines/sci/engine/klists.cpp b/engines/sci/engine/klists.cpp
index 8500f08211..2a33df26bc 100644
--- a/engines/sci/engine/klists.cpp
+++ b/engines/sci/engine/klists.cpp
@@ -409,7 +409,7 @@ int sort_temp_cmp(const void *p1, const void *p2) {
const sort_temp_t *st1 = (const sort_temp_t *)p1;
const sort_temp_t *st2 = (const sort_temp_t *)p2;
- if (st1->order.segment < st1->order.segment || (st1->order.segment == st1->order.segment && st1->order.offset < st2->order.offset))
+ if (st1->order.segment < st2->order.segment || (st1->order.segment == st2->order.segment && st1->order.offset < st2->order.offset))
return -1;
if (st1->order.segment > st2->order.segment || (st1->order.segment == st2->order.segment && st1->order.offset > st2->order.offset))
@@ -753,7 +753,6 @@ reg_t kArray(EngineState *s, int argc, reg_t *argv) {
reg_t arrayHandle = argv[1];
SciArray<reg_t> *array1 = s->_segMan->lookupArray(argv[1]);
- //SciArray<reg_t> *array1 = !argv[1].isNull() ? s->_segMan->lookupArray(argv[1]) : s->_segMan->allocateArray(&arrayHandle);
SciArray<reg_t> *array2 = s->_segMan->lookupArray(argv[3]);
uint32 index1 = argv[2].toUint16();
uint32 index2 = argv[4].toUint16();
@@ -790,21 +789,8 @@ reg_t kArray(EngineState *s, int argc, reg_t *argv) {
#endif
return NULL_REG;
}
- SegmentType sourceType = s->_segMan->getSegmentObj(argv[1].segment)->getType();
- if (sourceType == SEG_TYPE_SCRIPT) {
- // A technique used in later SCI2.1 and SCI3 games: the contents of a script
- // are loaded in an array (well, actually a string).
- Script *scr = s->_segMan->getScript(argv[1].segment);
- reg_t stringHandle;
-
- SciString *dupString = s->_segMan->allocateString(&stringHandle);
- dupString->setSize(scr->getBufSize());
- dupString->fromString(Common::String((const char *)scr->getBuf()));
-
- return stringHandle;
- } else if (sourceType != SEG_TYPE_ARRAY && sourceType != SEG_TYPE_SCRIPT) {
- error("kArray(Dup): Request to duplicate a segment which isn't an array or a script");
- }
+ if (s->_segMan->getSegmentObj(argv[1].segment)->getType() != SEG_TYPE_ARRAY)
+ error("kArray(Dup): Request to duplicate a segment which isn't an array");
reg_t arrayHandle;
SciArray<reg_t> *dupArray = s->_segMan->allocateArray(&arrayHandle);
diff --git a/engines/sci/engine/kpathing.cpp b/engines/sci/engine/kpathing.cpp
index 375aeaa06b..089b325a7f 100644
--- a/engines/sci/engine/kpathing.cpp
+++ b/engines/sci/engine/kpathing.cpp
@@ -1545,7 +1545,6 @@ reg_t kAvoidPath(EngineState *s, int argc, reg_t *argv) {
default:
warning("Unknown AvoidPath subfunction %d", argc);
return NULL_REG;
- break;
}
}
diff --git a/engines/sci/engine/kscripts.cpp b/engines/sci/engine/kscripts.cpp
index 93c1fffe3c..9b0e490d7e 100644
--- a/engines/sci/engine/kscripts.cpp
+++ b/engines/sci/engine/kscripts.cpp
@@ -74,17 +74,13 @@ reg_t kLock(EngineState *s, int argc, reg_t *argv) {
case 0 :
if (id.getNumber() == 0xFFFF) {
// Unlock all resources of the requested type
- Common::List<ResourceId> *resources = g_sci->getResMan()->listResources(type);
- Common::List<ResourceId>::iterator itr = resources->begin();
-
- while (itr != resources->end()) {
+ Common::List<ResourceId> resources = g_sci->getResMan()->listResources(type);
+ Common::List<ResourceId>::iterator itr;
+ for (itr = resources.begin(); itr != resources.end(); ++itr) {
Resource *res = g_sci->getResMan()->testResource(*itr);
if (res->isLocked())
g_sci->getResMan()->unlockResource(res);
- ++itr;
}
-
- delete resources;
} else {
which = g_sci->getResMan()->findResource(id, 0);
diff --git a/engines/sci/engine/ksound.cpp b/engines/sci/engine/ksound.cpp
index 33bef58e52..c469f775f9 100644
--- a/engines/sci/engine/ksound.cpp
+++ b/engines/sci/engine/ksound.cpp
@@ -195,6 +195,13 @@ reg_t kDoAudio(EngineState *s, int argc, reg_t *argv) {
return make_reg(0, 1);
} else {
int16 language = argv[1].toSint16();
+
+ // athrxx: It seems from disasm that the original KQ5 FM-Towns loads a default language (Japanese) audio map at the beginning
+ // right after loading the video and audio drivers. The -1 language argument in here simply means that the original will stick
+ // with Japanese. Instead of doing that we switch to the language selected in the launcher.
+ if (g_sci->getPlatform() == Common::kPlatformFMTowns && language == -1)
+ language = (g_sci->getLanguage() == Common::JA_JPN) ? K_LANG_JAPANESE : K_LANG_ENGLISH;
+
debugC(kDebugLevelSound, "kDoAudio: set language to %d", language);
if (language != -1)
diff --git a/engines/sci/engine/kstring.cpp b/engines/sci/engine/kstring.cpp
index 1a9359bb26..fe8d631497 100644
--- a/engines/sci/engine/kstring.cpp
+++ b/engines/sci/engine/kstring.cpp
@@ -147,7 +147,7 @@ reg_t kReadNumber(EngineState *s, int argc, reg_t *argv) {
Common::String source_str = s->_segMan->getString(argv[0]);
const char *source = source_str.c_str();
- while (isspace((unsigned char)*source))
+ while (Common::isSpace(*source))
source++; /* Skip whitespace */
int16 result = 0;
@@ -246,14 +246,14 @@ reg_t kFormat(EngineState *s, int argc, reg_t *argv) {
/* int writelength; -- unused atm */
- if (xfer && (isdigit(static_cast<unsigned char>(xfer)) || xfer == '-' || xfer == '=')) {
+ if (xfer && (Common::isDigit(xfer) || xfer == '-' || xfer == '=')) {
char *destp;
if (xfer == '0')
fillchar = '0';
else if (xfer == '=')
align = ALIGN_CENTER;
- else if (isdigit(static_cast<unsigned char>(xfer)) || (xfer == '-'))
+ else if (Common::isDigit(xfer) || (xfer == '-'))
source--; // Go to start of length argument
strLength = strtol(source, &destp, 10);
@@ -697,13 +697,15 @@ reg_t kString(EngineState *s, int argc, reg_t *argv) {
case 6: { // Cpy
const char *string2 = 0;
uint32 string2Size = 0;
+ Common::String string;
if (argv[3].segment == s->_segMan->getStringSegmentId()) {
- SciString *string = s->_segMan->lookupString(argv[3]);
- string2 = string->getRawData();
- string2Size = string->getSize();
+ SciString *sstr;
+ sstr = s->_segMan->lookupString(argv[3]);
+ string2 = sstr->getRawData();
+ string2Size = sstr->getSize();
} else {
- Common::String string = s->_segMan->getString(argv[3]);
+ string = s->_segMan->getString(argv[3]);
string2 = string.c_str();
string2Size = string.size() + 1;
}
@@ -743,28 +745,16 @@ reg_t kString(EngineState *s, int argc, reg_t *argv) {
return make_reg(0, strcmp(string1.c_str(), string2.c_str()));
}
case 8: { // Dup
- const char *rawString = 0;
- uint32 size = 0;
reg_t stringHandle;
- // We allocate the new string first because if the StringTable needs to
- // grow, our rawString pointer will be invalidated
+
SciString *dupString = s->_segMan->allocateString(&stringHandle);
if (argv[1].segment == s->_segMan->getStringSegmentId()) {
- SciString *string = s->_segMan->lookupString(argv[1]);
- rawString = string->getRawData();
- size = string->getSize();
+ *dupString = *s->_segMan->lookupString(argv[1]);
} else {
- Common::String string = s->_segMan->getString(argv[1]);
- rawString = string.c_str();
- size = string.size() + 1;
+ dupString->fromString(s->_segMan->getString(argv[1]));
}
- dupString->setSize(size);
-
- for (uint32 i = 0; i < size; i++)
- dupString->setValue(i, rawString[i]);
-
return stringHandle;
}
case 9: // Getdata
diff --git a/engines/sci/engine/message.cpp b/engines/sci/engine/message.cpp
index f30f4e923e..cddd01e10c 100644
--- a/engines/sci/engine/message.cpp
+++ b/engines/sci/engine/message.cpp
@@ -345,7 +345,7 @@ bool MessageState::stringLit(Common::String &outStr, const Common::String &inStr
}
bool MessageState::stringStage(Common::String &outstr, const Common::String &inStr, uint &index) {
- // Stage directions of the form (n*), where n is anything but a digit or a lowercase character
+ // Stage directions of the form (n *), where n is anything but a digit or a lowercase character
if (inStr[index] != '(')
return false;
diff --git a/engines/sci/engine/savegame.cpp b/engines/sci/engine/savegame.cpp
index 030c0f3f54..404bea799d 100644
--- a/engines/sci/engine/savegame.cpp
+++ b/engines/sci/engine/savegame.cpp
@@ -66,7 +66,7 @@ void syncWithSerializer(Common::Serializer &s, T &obj) {
}
// By default, sync using syncWithSerializer, which in turn can easily be overloaded.
-template <typename T>
+template<typename T>
struct DefaultSyncer : Common::BinaryFunction<Common::Serializer, T, void> {
void operator()(Common::Serializer &s, T &obj) const {
//obj.saveLoadWithSerializer(s);
@@ -87,7 +87,7 @@ struct DefaultSyncer : Common::BinaryFunction<Common::Serializer, T, void> {
*
* TODO: Add something like this for lists, queues....
*/
-template <typename T, class Syncer = DefaultSyncer<T> >
+template<typename T, class Syncer = DefaultSyncer<T> >
struct ArraySyncer : Common::BinaryFunction<Common::Serializer, T, void> {
void operator()(Common::Serializer &s, Common::Array<T> &arr) const {
uint len = arr.size();
@@ -113,13 +113,13 @@ void syncArray(Common::Serializer &s, Common::Array<T> &arr) {
}
-template <>
+template<>
void syncWithSerializer(Common::Serializer &s, reg_t &obj) {
s.syncAsUint16LE(obj.segment);
s.syncAsUint16LE(obj.offset);
}
-template <>
+template<>
void syncWithSerializer(Common::Serializer &s, synonym_t &obj) {
s.syncAsUint16LE(obj.replaceant);
s.syncAsUint16LE(obj.replacement);
@@ -203,7 +203,8 @@ void SegManager::saveLoadWithSerializer(Common::Serializer &s) {
// Now, load the script itself
scr->load(g_sci->getResMan());
- for (ObjMap::iterator it = scr->_objects.begin(); it != scr->_objects.end(); ++it)
+ ObjMap objects = scr->getObjectMap();
+ for (ObjMap::iterator it = objects.begin(); it != objects.end(); ++it)
it->_value.syncBaseObject(scr->getBuf(it->_value.getPos().offset));
}
@@ -226,9 +227,10 @@ void SegManager::saveLoadWithSerializer(Common::Serializer &s) {
continue;
Script *scr = (Script *)_heap[i];
- scr->_localsBlock = (scr->_localsSegment == 0) ? NULL : (LocalVariables *)(_heap[scr->_localsSegment]);
+ scr->syncLocalsBlock(this);
- for (ObjMap::iterator it = scr->_objects.begin(); it != scr->_objects.end(); ++it) {
+ ObjMap objects = scr->getObjectMap();
+ for (ObjMap::iterator it = objects.begin(); it != objects.end(); ++it) {
reg_t addr = it->_value.getPos();
Object *obj = scr->scriptObjInit(addr, false);
@@ -237,7 +239,7 @@ void SegManager::saveLoadWithSerializer(Common::Serializer &s) {
// TODO/FIXME: This should not be happening at all. It might indicate a possible issue
// with the garbage collector. It happens for example in LSL5 (German, perhaps English too).
warning("Failed to locate base object for object at %04X:%04X; skipping", PRINT_REG(addr));
- scr->_objects.erase(addr.toUint16());
+ objects.erase(addr.toUint16());
}
}
}
@@ -245,7 +247,7 @@ void SegManager::saveLoadWithSerializer(Common::Serializer &s) {
}
-template <>
+template<>
void syncWithSerializer(Common::Serializer &s, Class &obj) {
s.syncAsSint32LE(obj.script);
syncWithSerializer(s, obj.reg);
@@ -324,14 +326,14 @@ void Object::saveLoadWithSerializer(Common::Serializer &s) {
syncArray<reg_t>(s, _variables);
}
-template <>
+template<>
void syncWithSerializer(Common::Serializer &s, SegmentObjTable<Clone>::Entry &obj) {
s.syncAsSint32LE(obj.next_free);
syncWithSerializer<Object>(s, obj);
}
-template <>
+template<>
void syncWithSerializer(Common::Serializer &s, SegmentObjTable<List>::Entry &obj) {
s.syncAsSint32LE(obj.next_free);
@@ -339,7 +341,7 @@ void syncWithSerializer(Common::Serializer &s, SegmentObjTable<List>::Entry &obj
syncWithSerializer(s, obj.last);
}
-template <>
+template<>
void syncWithSerializer(Common::Serializer &s, SegmentObjTable<Node>::Entry &obj) {
s.syncAsSint32LE(obj.next_free);
@@ -350,7 +352,7 @@ void syncWithSerializer(Common::Serializer &s, SegmentObjTable<Node>::Entry &obj
}
#ifdef ENABLE_SCI32
-template <>
+template<>
void syncWithSerializer(Common::Serializer &s, SegmentObjTable<SciArray<reg_t> >::Entry &obj) {
s.syncAsSint32LE(obj.next_free);
@@ -386,7 +388,7 @@ void syncWithSerializer(Common::Serializer &s, SegmentObjTable<SciArray<reg_t> >
}
}
-template <>
+template<>
void syncWithSerializer(Common::Serializer &s, SegmentObjTable<SciString>::Entry &obj) {
s.syncAsSint32LE(obj.next_free);
@@ -414,7 +416,7 @@ void syncWithSerializer(Common::Serializer &s, SegmentObjTable<SciString>::Entry
}
#endif
-template <typename T>
+template<typename T>
void sync_Table(Common::Serializer &s, T &obj) {
s.syncAsSint32LE(obj.first_free);
s.syncAsSint32LE(obj.entries_used);
diff --git a/engines/sci/engine/script.cpp b/engines/sci/engine/script.cpp
index 01e1afe5ea..8b26969f4a 100644
--- a/engines/sci/engine/script.cpp
+++ b/engines/sci/engine/script.cpp
@@ -492,8 +492,29 @@ SegmentRef Script::dereference(reg_t pointer) {
return ret;
}
+LocalVariables *Script::allocLocalsSegment(SegManager *segMan) {
+ if (!getLocalsCount()) { // No locals
+ return NULL;
+ } else {
+ LocalVariables *locals;
+
+ if (_localsSegment) {
+ locals = (LocalVariables *)segMan->getSegment(_localsSegment, SEG_TYPE_LOCALS);
+ if (!locals || locals->getType() != SEG_TYPE_LOCALS || locals->script_id != getScriptNumber())
+ error("Invalid script locals segment while allocating locals");
+ } else
+ locals = (LocalVariables *)segMan->allocSegment(new LocalVariables(), &_localsSegment);
+
+ _localsBlock = locals;
+ locals->script_id = getScriptNumber();
+ locals->_locals.resize(getLocalsCount());
+
+ return locals;
+ }
+}
+
void Script::initializeLocals(SegManager *segMan) {
- LocalVariables *locals = segMan->allocLocalsSegment(this);
+ LocalVariables *locals = allocLocalsSegment(segMan);
if (locals) {
if (getSciVersion() > SCI_VERSION_0_EARLY) {
const byte *base = (const byte *)(_buf + getLocalsOffset());
@@ -508,6 +529,10 @@ void Script::initializeLocals(SegManager *segMan) {
}
}
+void Script::syncLocalsBlock(SegManager *segMan) {
+ _localsBlock = (_localsSegment == 0) ? NULL : (LocalVariables *)(segMan->getSegment(_localsSegment, SEG_TYPE_LOCALS));
+}
+
void Script::initializeClasses(SegManager *segMan) {
const byte *seeker = 0;
uint16 mult = 0;
diff --git a/engines/sci/engine/script.h b/engines/sci/engine/script.h
index ff061e0e36..1ebae3b7a8 100644
--- a/engines/sci/engine/script.h
+++ b/engines/sci/engine/script.h
@@ -62,23 +62,18 @@ private:
const uint16 *_exportTable; /**< Abs. offset of the export table or 0 if not present */
uint16 _numExports; /**< Number of entries in the exports table */
- const byte *_synonyms; /**< Synonyms block or 0 if not present*/
+ const byte *_synonyms; /**< Synonyms block or 0 if not present */
uint16 _numSynonyms; /**< Number of entries in the synonyms block */
int _localsOffset;
uint16 _localsCount;
bool _markedAsDeleted;
-
-public:
- /**
- * Table for objects, contains property variables.
- * Indexed by the TODO offset.
- */
- ObjMap _objects;
SegmentId _localsSegment; /**< The local variable segment */
LocalVariables *_localsBlock;
+ ObjMap _objects; /**< Table for objects, contains property variables */
+
public:
int getLocalsOffset() const { return _localsOffset; }
uint16 getLocalsCount() const { return _localsCount; }
@@ -89,6 +84,11 @@ public:
const byte *getBuf(uint offset = 0) const { return _buf + offset; }
int getScriptNumber() const { return _nr; }
+ SegmentId getLocalsSegment() const { return _localsSegment; }
+ reg_t *getLocalsBegin() { return _localsBlock ? _localsBlock->_locals.begin() : NULL; }
+ void syncLocalsBlock(SegManager *segMan);
+ ObjMap &getObjectMap() { return _objects; }
+ const ObjMap &getObjectMap() const { return _objects; }
public:
Script();
@@ -295,6 +295,8 @@ private:
* @param segmentId The script's segment id
*/
void initializeObjectsSci3(SegManager *segMan, SegmentId segmentId);
+
+ LocalVariables *allocLocalsSegment(SegManager *segMan);
};
} // End of namespace Sci
diff --git a/engines/sci/engine/script_patches.cpp b/engines/sci/engine/script_patches.cpp
index 7efcb42f4b..187f1ce021 100644
--- a/engines/sci/engine/script_patches.cpp
+++ b/engines/sci/engine/script_patches.cpp
@@ -366,7 +366,7 @@ const uint16 freddypharkasPatchLadderEvent[] = {
// script, description, magic DWORD, adjust
const SciScriptSignature freddypharkasSignatures[] = {
{ 0, "CD: score early disposal", 1, PATCH_MAGICDWORD(0x39, 0x0d, 0x43, 0x75), -3, freddypharkasSignatureScoreDisposal, freddypharkasPatchScoreDisposal },
- { 235, "CD: canister pickup hang", 3, PATCH_MAGICDWORD(0x39, 0x07, 0x39, 0x08), -4, freddypharkasSignatureCanisterHang, freddypharkasPatchCanisterHang },
+ { 235, "CD: canister pickup hang", 3, PATCH_MAGICDWORD(0x39, 0x07, 0x39, 0x08), -4, freddypharkasSignatureCanisterHang, freddypharkasPatchCanisterHang },
{ 320, "ladder event issue", 2, PATCH_MAGICDWORD(0x6d, 0x76, 0x38, 0xf5), -1, freddypharkasSignatureLadderEvent, freddypharkasPatchLadderEvent },
SCI_SIGNATUREENTRY_TERMINATOR
};
@@ -437,8 +437,68 @@ const uint16 gk1PatchDay5PhoneFreeze[] = {
PATCH_END
};
+// Floppy version: Interrogation::dispose() compares an object reference
+// (stored in the view selector) with a number, leading to a crash (this kind
+// of comparison was not used in SCI32). The view selector is used to store
+// both a view number (in some cases), and a view reference (in other cases).
+// In the floppy version, the checks are in the wrong order, so there is a
+// comparison between a number an an object. In the CD version, the checks are
+// in the correct order, thus the comparison is correct, thus we use the code
+// from the CD version in the floppy one.
+const byte gk1SignatureInterrogationBug[] = {
+ 43,
+ 0x65, 0x4c, // aTop 4c
+ 0x67, 0x50, // pTos 50
+ 0x34, 0x10, 0x27, // ldi 2710
+ 0x1e, // gt?
+ 0x31, 0x08, // bnt 08 [05a0]
+ 0x67, 0x50, // pTos 50
+ 0x34, 0x10, 0x27, // ldi 2710
+ 0x04, // sub
+ 0x65, 0x50, // aTop 50
+ 0x63, 0x50, // pToa 50
+ 0x31, 0x15, // bnt 15 [05b9]
+ 0x39, 0x0e, // pushi 0e
+ 0x76, // push0
+ 0x4a, 0x04, 0x00, // send 0004
+ 0xa5, 0x00, // sat 00
+ 0x38, 0x93, 0x00, // pushi 0093
+ 0x76, // push0
+ 0x63, 0x50, // pToa 50
+ 0x4a, 0x04, 0x00, // send 0004
+ 0x85, 0x00, // lat 00
+ 0x65, 0x50, // aTop 50
+ 0
+};
+
+const uint16 gk1PatchInterrogationBug[] = {
+ 0x65, 0x4c, // aTop 4c
+ 0x63, 0x50, // pToa 50
+ 0x31, 0x15, // bnt 15 [05b9]
+ 0x39, 0x0e, // pushi 0e
+ 0x76, // push0
+ 0x4a, 0x04, 0x00, // send 0004
+ 0xa5, 0x00, // sat 00
+ 0x38, 0x93, 0x00, // pushi 0093
+ 0x76, // push0
+ 0x63, 0x50, // pToa 50
+ 0x4a, 0x04, 0x00, // send 0004
+ 0x85, 0x00, // lat 00
+ 0x65, 0x50, // aTop 50
+ 0x67, 0x50, // pTos 50
+ 0x34, 0x10, 0x27, // ldi 2710
+ 0x1e, // gt?
+ 0x31, 0x08, // bnt 08 [05b9]
+ 0x67, 0x50, // pTos 50
+ 0x34, 0x10, 0x27, // ldi 2710
+ 0x04, // sub
+ 0x65, 0x50, // aTop 50
+ PATCH_END
+};
+
// script, description, magic DWORD, adjust
const SciScriptSignature gk1Signatures[] = {
+ { 51, "interrogation bug", 1, PATCH_MAGICDWORD(0x65, 0x4c, 0x67, 0x50), 0, gk1SignatureInterrogationBug, gk1PatchInterrogationBug },
{ 212, "day 5 phone freeze", 1, PATCH_MAGICDWORD(0x35, 0x03, 0x65, 0x1a), 0, gk1SignatureDay5PhoneFreeze, gk1PatchDay5PhoneFreeze },
{ 230, "day 6 police beignet timer issue", 1, PATCH_MAGICDWORD(0x34, 0xdc, 0x00, 0x65), -16, gk1SignatureDay6PoliceBeignet, gk1PatchDay6PoliceBeignet },
{ 230, "day 6 police sleep timer issue", 1, PATCH_MAGICDWORD(0x34, 0xdc, 0x00, 0x65), -5, gk1SignatureDay6PoliceSleep, gk1PatchDay6PoliceSleep },
diff --git a/engines/sci/engine/scriptdebug.cpp b/engines/sci/engine/scriptdebug.cpp
index ad3f4fb788..ef61b2e28a 100644
--- a/engines/sci/engine/scriptdebug.cpp
+++ b/engines/sci/engine/scriptdebug.cpp
@@ -122,8 +122,8 @@ reg_t disassemble(EngineState *s, reg_t pos, bool printBWTag, bool printBytecode
#endif
i = 0;
- while (g_opcode_formats[opcode][i]) {
- switch (g_opcode_formats[opcode][i++]) {
+ while (g_sci->_opcode_formats[opcode][i]) {
+ switch (g_sci->_opcode_formats[opcode][i++]) {
case Script_Invalid:
warning("-Invalid operation-");
break;
@@ -296,7 +296,7 @@ bool isJumpOpcode(EngineState *s, reg_t pos, reg_t& jumpTarget) {
Script *script_entity = (Script *)mobj;
const byte *scr = script_entity->getBuf();
- int scr_size = script_entity->getBufSize();
+ int scr_size = script_entity->getScriptSize();
if (pos.offset >= scr_size)
return false;
@@ -310,7 +310,13 @@ bool isJumpOpcode(EngineState *s, reg_t pos, reg_t& jumpTarget) {
case op_bt:
case op_bnt:
case op_jmp:
- jumpTarget = pos + bytecount + opparams[0];
+ {
+ reg_t jmpTarget = pos + bytecount + opparams[0];
+ // QFG2 has invalid jumps outside the script buffer in script 260
+ if (jmpTarget.offset >= scr_size)
+ return false;
+ jumpTarget = jmpTarget;
+ }
return true;
default:
return false;
@@ -721,7 +727,7 @@ void logKernelCall(const KernelFunction *kernelCall, const KernelSubFunction *ke
switch (mobj->getType()) {
case SEG_TYPE_HUNK:
{
- HunkTable *ht = (HunkTable*)mobj;
+ HunkTable *ht = (HunkTable *)mobj;
int index = argv[parmNr].offset;
if (ht->isValidEntry(index)) {
// NOTE: This ", deleted" isn't as useful as it could
diff --git a/engines/sci/engine/seg_manager.cpp b/engines/sci/engine/seg_manager.cpp
index 1510af8508..cc127c8dbc 100644
--- a/engines/sci/engine/seg_manager.cpp
+++ b/engines/sci/engine/seg_manager.cpp
@@ -151,8 +151,8 @@ void SegManager::deallocate(SegmentId seg) {
if (mobj->getType() == SEG_TYPE_SCRIPT) {
Script *scr = (Script *)mobj;
_scriptSegMap.erase(scr->getScriptNumber());
- if (scr->_localsSegment)
- deallocate(scr->_localsSegment);
+ if (scr->getLocalsSegment())
+ deallocate(scr->getLocalsSegment());
}
delete mobj;
@@ -270,12 +270,13 @@ reg_t SegManager::findObjectByName(const Common::String &name, int index) {
if (mobj->getType() == SEG_TYPE_SCRIPT) {
// It's a script, scan all objects in it
const Script *scr = (const Script *)mobj;
- for (ObjMap::const_iterator it = scr->_objects.begin(); it != scr->_objects.end(); ++it) {
+ const ObjMap &objects = scr->getObjectMap();
+ for (ObjMap::const_iterator it = objects.begin(); it != objects.end(); ++it) {
objpos.offset = it->_value.getPos().offset;
if (name == getObjectName(objpos))
result.push_back(objpos);
}
- } else if (mobj->getType() == SEG_TYPE_CLONES) {
+ } else if (mobj->getType() == SEG_TYPE_CLONES) {
// It's clone table, scan all objects in it
const CloneTable *ct = (const CloneTable *)mobj;
for (uint idx = 0; idx < ct->_table.size(); ++idx) {
@@ -341,29 +342,6 @@ SegmentId SegManager::getScriptSegment(int script_nr, ScriptLoadType load) {
return segment;
}
-LocalVariables *SegManager::allocLocalsSegment(Script *scr) {
- if (!scr->getLocalsCount()) { // No locals
- scr->_localsSegment = 0;
- scr->_localsBlock = NULL;
- return NULL;
- } else {
- LocalVariables *locals;
-
- if (scr->_localsSegment) {
- locals = (LocalVariables *)_heap[scr->_localsSegment];
- if (!locals || locals->getType() != SEG_TYPE_LOCALS || locals->script_id != scr->getScriptNumber())
- error("Invalid script locals segment while allocating locals");
- } else
- locals = (LocalVariables *)allocSegment(new LocalVariables(), &scr->_localsSegment);
-
- scr->_localsBlock = locals;
- locals->script_id = scr->getScriptNumber();
- locals->_locals.resize(scr->getLocalsCount());
-
- return locals;
- }
-}
-
DataStack *SegManager::allocateStack(int size, SegmentId *segid) {
SegmentObj *mobj = allocSegment(new DataStack(), segid);
DataStack *retval = (DataStack *)mobj;
@@ -713,7 +691,7 @@ void SegManager::memcpy(reg_t dest, const byte* src, size_t n) {
if (dest_r.isRaw) {
// raw -> raw
- ::memcpy((char*)dest_r.raw, src, n);
+ ::memcpy((char *)dest_r.raw, src, n);
} else {
// raw -> non-raw
for (uint i = 0; i < n; i++)
diff --git a/engines/sci/engine/seg_manager.h b/engines/sci/engine/seg_manager.h
index ab5aeacabf..62e711e686 100644
--- a/engines/sci/engine/seg_manager.h
+++ b/engines/sci/engine/seg_manager.h
@@ -463,8 +463,10 @@ private:
SegmentId _stringSegId;
#endif
-private:
+public:
SegmentObj *allocSegment(SegmentObj *mem, SegmentId *segid);
+
+private:
void deallocate(SegmentId seg);
void createClassTable();
@@ -477,9 +479,6 @@ private:
* 'seg' is a valid segment
*/
bool check(SegmentId seg);
-
-public:
- LocalVariables *allocLocalsSegment(Script *scr);
};
} // End of namespace Sci
diff --git a/engines/sci/engine/segment.cpp b/engines/sci/engine/segment.cpp
index 3f11d6ff49..36b7d92c07 100644
--- a/engines/sci/engine/segment.cpp
+++ b/engines/sci/engine/segment.cpp
@@ -143,9 +143,11 @@ SegmentRef LocalVariables::dereference(reg_t pointer) {
if (ret.maxSize > 0) {
ret.reg = &_locals[pointer.offset / 2];
} else {
- if ((g_sci->getEngineState()->currentRoomNumber() == 660 || g_sci->getEngineState()->currentRoomNumber() == 660)
+ if ((g_sci->getEngineState()->currentRoomNumber() == 160 ||
+ g_sci->getEngineState()->currentRoomNumber() == 220)
&& g_sci->getGameId() == GID_LAURABOW2) {
- // Happens in two places during the intro of LB2CD, both from kMemory(peek):
+ // WORKAROUND: Happens in two places during the intro of LB2CD, both
+ // from kMemory(peek):
// - room 160: Heap 160 has 83 local variables (0-82), and the game
// asks for variables at indices 83 - 90 too.
// - room 220: Heap 220 has 114 local variables (0-113), and the
@@ -292,18 +294,19 @@ void SciString::fromString(const Common::String &string) {
if (_type != 3)
error("SciString::fromString(): Array is not a string");
- if (string.size() > _size)
- setSize(string.size());
+ setSize(string.size() + 1);
for (uint32 i = 0; i < string.size(); i++)
_data[i] = string[i];
+
+ _data[string.size()] = 0;
}
SegmentRef StringTable::dereference(reg_t pointer) {
SegmentRef ret;
ret.isRaw = true;
ret.maxSize = _table[pointer.offset].getSize();
- ret.raw = (byte*)_table[pointer.offset].getRawData();
+ ret.raw = (byte *)_table[pointer.offset].getRawData();
return ret;
}
diff --git a/engines/sci/engine/segment.h b/engines/sci/engine/segment.h
index 009a2558ce..54cf7b98af 100644
--- a/engines/sci/engine/segment.h
+++ b/engines/sci/engine/segment.h
@@ -370,7 +370,7 @@ public:
#ifdef ENABLE_SCI32
-template <typename T>
+template<typename T>
class SciArray {
public:
SciArray() : _type(-1), _data(NULL), _size(0), _actualSize(0) { }
diff --git a/engines/sci/engine/selector.cpp b/engines/sci/engine/selector.cpp
index a9aca9e22f..a8b1cf7ec2 100644
--- a/engines/sci/engine/selector.cpp
+++ b/engines/sci/engine/selector.cpp
@@ -178,6 +178,7 @@ void Kernel::mapSelectors() {
FIND_SELECTOR(dimmed);
FIND_SELECTOR(fore);
FIND_SELECTOR(back);
+ FIND_SELECTOR(skip);
FIND_SELECTOR(fixPriority);
FIND_SELECTOR(mirrored);
FIND_SELECTOR(useInsetRect);
diff --git a/engines/sci/engine/selector.h b/engines/sci/engine/selector.h
index bbd86bb03e..4b913a866a 100644
--- a/engines/sci/engine/selector.h
+++ b/engines/sci/engine/selector.h
@@ -144,6 +144,7 @@ struct SelectorCache {
Selector fore;
Selector back;
+ Selector skip;
Selector dimmed;
Selector fixPriority;
diff --git a/engines/sci/engine/state.cpp b/engines/sci/engine/state.cpp
index 4ea9f72054..28818cddef 100644
--- a/engines/sci/engine/state.cpp
+++ b/engines/sci/engine/state.cpp
@@ -145,12 +145,12 @@ void EngineState::wait(int16 ticks) {
void EngineState::initGlobals() {
Script *script_000 = _segMan->getScript(1);
- if (!script_000->_localsBlock)
+ if (script_000->getLocalsCount() == 0)
error("Script 0 has no locals block");
- variablesSegment[VAR_GLOBAL] = script_000->_localsSegment;
- variablesBase[VAR_GLOBAL] = variables[VAR_GLOBAL] = script_000->_localsBlock->_locals.begin();
- variablesMax[VAR_GLOBAL] = script_000->_localsBlock->_locals.size();
+ variablesSegment[VAR_GLOBAL] = script_000->getLocalsSegment();
+ variablesBase[VAR_GLOBAL] = variables[VAR_GLOBAL] = script_000->getLocalsBegin();
+ variablesMax[VAR_GLOBAL] = script_000->getLocalsCount();
}
uint16 EngineState::currentRoomNumber() const {
diff --git a/engines/sci/engine/vm.cpp b/engines/sci/engine/vm.cpp
index c94fdac034..162dce9fcc 100644
--- a/engines/sci/engine/vm.cpp
+++ b/engines/sci/engine/vm.cpp
@@ -235,6 +235,9 @@ ExecStack *execute_method(EngineState *s, uint16 script, uint16 pubfunct, StackP
if (g_sci->getGameId() == GID_TORIN && script == 64036) {
// Script 64036 in Torin's Passage is empty and contains an invalid
// (empty) export
+ } else if (g_sci->getGameId() == GID_RAMA && script == 64908) {
+ // Script 64908 in the demo of RAMA contains an invalid (empty)
+ // export
} else
#endif
error("Request for invalid exported function 0x%x of script %d", pubfunct, script);
@@ -462,10 +465,10 @@ int readPMachineInstruction(const byte *src, byte &extOpcode, int16 opparams[4])
memset(opparams, 0, 4*sizeof(int16));
- for (int i = 0; g_opcode_formats[opcode][i]; ++i) {
+ for (int i = 0; g_sci->_opcode_formats[opcode][i]; ++i) {
//debugN("Opcode: 0x%x, Opnumber: 0x%x, temp: %d\n", opcode, opcode, temp);
assert(i < 3);
- switch (g_opcode_formats[opcode][i]) {
+ switch (g_sci->_opcode_formats[opcode][i]) {
case Script_Byte:
opparams[i] = src[offset++];
@@ -593,15 +596,9 @@ void run_vm(EngineState *s) {
if (!local_script) {
error("Could not find local script from segment %x", s->xs->local_segment);
} else {
- s->variablesSegment[VAR_LOCAL] = local_script->_localsSegment;
- if (local_script->_localsBlock)
- s->variablesBase[VAR_LOCAL] = s->variables[VAR_LOCAL] = local_script->_localsBlock->_locals.begin();
- else
- s->variablesBase[VAR_LOCAL] = s->variables[VAR_LOCAL] = NULL;
- if (local_script->_localsBlock)
- s->variablesMax[VAR_LOCAL] = local_script->_localsBlock->_locals.size();
- else
- s->variablesMax[VAR_LOCAL] = 0;
+ s->variablesSegment[VAR_LOCAL] = local_script->getLocalsSegment();
+ s->variablesBase[VAR_LOCAL] = s->variables[VAR_LOCAL] = local_script->getLocalsBegin();
+ s->variablesMax[VAR_LOCAL] = local_script->getLocalsCount();
s->variablesMax[VAR_TEMP] = s->xs->sp - s->xs->fp;
s->variablesMax[VAR_PARAM] = s->xs->argc + 1;
}
@@ -770,16 +767,28 @@ void run_vm(EngineState *s) {
// Branch relative if true
if (s->r_acc.offset || s->r_acc.segment)
s->xs->addr.pc.offset += opparams[0];
+
+ if (s->xs->addr.pc.offset >= local_script->getScriptSize())
+ error("[VM] op_bt: request to jump past the end of script %d (offset %d, script is %d bytes)",
+ local_script->getScriptNumber(), s->xs->addr.pc.offset, local_script->getScriptSize());
break;
case op_bnt: // 0x18 (24)
// Branch relative if not true
if (!(s->r_acc.offset || s->r_acc.segment))
s->xs->addr.pc.offset += opparams[0];
+
+ if (s->xs->addr.pc.offset >= local_script->getScriptSize())
+ error("[VM] op_bnt: request to jump past the end of script %d (offset %d, script is %d bytes)",
+ local_script->getScriptNumber(), s->xs->addr.pc.offset, local_script->getScriptSize());
break;
case op_jmp: // 0x19 (25)
s->xs->addr.pc.offset += opparams[0];
+
+ if (s->xs->addr.pc.offset >= local_script->getScriptSize())
+ error("[VM] op_jmp: request to jump past the end of script %d (offset %d, script is %d bytes)",
+ local_script->getScriptNumber(), s->xs->addr.pc.offset, local_script->getScriptSize());
break;
case op_ldi: // 0x1a (26)
diff --git a/engines/sci/engine/vm.h b/engines/sci/engine/vm.h
index 36eadfa1c2..334d224baf 100644
--- a/engines/sci/engine/vm.h
+++ b/engines/sci/engine/vm.h
@@ -139,26 +139,6 @@ enum {
GC_INTERVAL = 0x8000
};
-// Opcode formats
-enum opcode_format {
- Script_Invalid = -1,
- Script_None = 0,
- Script_Byte,
- Script_SByte,
- Script_Word,
- Script_SWord,
- Script_Variable,
- Script_SVariable,
- Script_SRelative,
- Script_Property,
- Script_Global,
- Script_Local,
- Script_Temp,
- Script_Param,
- Script_Offset,
- Script_End
-};
-
enum sci_opcodes {
op_bnot = 0x00, // 000
op_add = 0x01, // 001
@@ -290,8 +270,6 @@ enum sci_opcodes {
op_minusspi = 0x7f // 127
};
-extern opcode_format g_opcode_formats[128][4];
-
void script_adjust_opcode_formats();
/**
diff --git a/engines/sci/engine/vm_types.h b/engines/sci/engine/vm_types.h
index dc87cf758a..7b155a4532 100644
--- a/engines/sci/engine/vm_types.h
+++ b/engines/sci/engine/vm_types.h
@@ -172,6 +172,26 @@ enum {
NULL_SELECTOR = -1
};
+// Opcode formats
+enum opcode_format {
+ Script_Invalid = -1,
+ Script_None = 0,
+ Script_Byte,
+ Script_SByte,
+ Script_Word,
+ Script_SWord,
+ Script_Variable,
+ Script_SVariable,
+ Script_SRelative,
+ Script_Property,
+ Script_Global,
+ Script_Local,
+ Script_Temp,
+ Script_Param,
+ Script_Offset,
+ Script_End
+};
+
} // End of namespace Sci
diff --git a/engines/sci/engine/workarounds.cpp b/engines/sci/engine/workarounds.cpp
index f68b74e1e0..a556134e32 100644
--- a/engines/sci/engine/workarounds.cpp
+++ b/engines/sci/engine/workarounds.cpp
@@ -353,7 +353,7 @@ const SciWorkaroundEntry kNewWindow_workarounds[] = {
// gameID, room,script,lvl, object-name, method-name, call,index, workaround
const SciWorkaroundEntry kPaletteUnsetFlag_workarounds[] = {
- { GID_QFG4, 100, 100, 0, "doMovie", "<noname144>", -1, 0, { WORKAROUND_IGNORE, 0 } }, // after the Sierra logo, no flags are passed, thus the call is meaningless - bug #3034506
+ { GID_QFG4, 100, 100, 0, "doMovie", "changeState", -1, 0, { WORKAROUND_IGNORE, 0 } }, // after the Sierra logo, no flags are passed, thus the call is meaningless - bug #3034506
SCI_WORKAROUNDENTRY_TERMINATOR
};
diff --git a/engines/sci/event.cpp b/engines/sci/event.cpp
index c14cfada07..378e88b7df 100644
--- a/engines/sci/event.cpp
+++ b/engines/sci/event.cpp
@@ -253,14 +253,11 @@ SciEvent EventManager::getScummVMEvent() {
if ((modifiers & Common::KBD_ALT) && input.character > 0 && input.character < 27)
input.character += 96; // 0x01 -> 'a'
- if (getSciVersion() <= SCI_VERSION_1_MIDDLE) {
- // TODO: find out if altify is also not needed for sci1late+, couldnt find any game that uses those keys
- // Scancodify if appropriate
- if (modifiers & Common::KBD_ALT)
- input.character = altify(input.character);
- else if ((modifiers & Common::KBD_CTRL) && input.character > 0 && input.character < 27)
- input.character += 96; // 0x01 -> 'a'
- }
+ // Scancodify if appropriate
+ if (modifiers & Common::KBD_ALT)
+ input.character = altify(input.character);
+ else if ((modifiers & Common::KBD_CTRL) && input.character > 0 && input.character < 27)
+ input.character += 96; // 0x01 -> 'a'
// If no actual key was pressed (e.g. if only a modifier key was pressed),
// ignore the event
diff --git a/engines/sci/graphics/controls.cpp b/engines/sci/graphics/controls16.cpp
index a0750c7d3e..ab54e468d1 100644
--- a/engines/sci/graphics/controls.cpp
+++ b/engines/sci/graphics/controls16.cpp
@@ -36,26 +36,26 @@
#include "sci/graphics/font.h"
#include "sci/graphics/screen.h"
#include "sci/graphics/text16.h"
-#include "sci/graphics/controls.h"
+#include "sci/graphics/controls16.h"
namespace Sci {
-GfxControls::GfxControls(SegManager *segMan, GfxPorts *ports, GfxPaint16 *paint16, GfxText16 *text16, GfxScreen *screen)
+GfxControls16::GfxControls16(SegManager *segMan, GfxPorts *ports, GfxPaint16 *paint16, GfxText16 *text16, GfxScreen *screen)
: _segMan(segMan), _ports(ports), _paint16(paint16), _text16(text16), _screen(screen) {
init();
}
-GfxControls::~GfxControls() {
+GfxControls16::~GfxControls16() {
}
-void GfxControls::init() {
+void GfxControls16::init() {
_texteditCursorVisible = false;
}
const char controlListUpArrow[2] = { 0x18, 0 };
const char controlListDownArrow[2] = { 0x19, 0 };
-void GfxControls::drawListControl(Common::Rect rect, reg_t obj, int16 maxChars, int16 count, const char **entries, GuiResourceId fontId, int16 upperPos, int16 cursorPos, bool isAlias) {
+void GfxControls16::drawListControl(Common::Rect rect, reg_t obj, int16 maxChars, int16 count, const char **entries, GuiResourceId fontId, int16 upperPos, int16 cursorPos, bool isAlias) {
Common::Rect workerRect = rect;
GuiResourceId oldFontId = _text16->GetFontId();
int16 oldPenColor = _ports->_curPort->penClr;
@@ -112,7 +112,7 @@ void GfxControls::drawListControl(Common::Rect rect, reg_t obj, int16 maxChars,
_text16->SetFont(oldFontId);
}
-void GfxControls::texteditCursorDraw(Common::Rect rect, const char *text, uint16 curPos) {
+void GfxControls16::texteditCursorDraw(Common::Rect rect, const char *text, uint16 curPos) {
int16 textWidth, i;
if (!_texteditCursorVisible) {
textWidth = 0;
@@ -130,7 +130,7 @@ void GfxControls::texteditCursorDraw(Common::Rect rect, const char *text, uint16
}
}
-void GfxControls::texteditCursorErase() {
+void GfxControls16::texteditCursorErase() {
if (_texteditCursorVisible) {
_paint16->invertRect(_texteditCursorRect);
_paint16->bitsShow(_texteditCursorRect);
@@ -139,11 +139,11 @@ void GfxControls::texteditCursorErase() {
texteditSetBlinkTime();
}
-void GfxControls::texteditSetBlinkTime() {
+void GfxControls16::texteditSetBlinkTime() {
_texteditBlinkTime = g_system->getMillis() + (30 * 1000 / 60);
}
-void GfxControls::kernelTexteditChange(reg_t controlObject, reg_t eventObject) {
+void GfxControls16::kernelTexteditChange(reg_t controlObject, reg_t eventObject) {
uint16 cursorPos = readSelectorValue(_segMan, controlObject, SELECTOR(cursor));
uint16 maxChars = readSelectorValue(_segMan, controlObject, SELECTOR(max));
reg_t textReference = readSelector(_segMan, controlObject, SELECTOR(text));
@@ -277,13 +277,13 @@ void GfxControls::kernelTexteditChange(reg_t controlObject, reg_t eventObject) {
writeSelectorValue(_segMan, controlObject, SELECTOR(cursor), cursorPos);
}
-int GfxControls::getPicNotValid() {
+int GfxControls16::getPicNotValid() {
if (getSciVersion() >= SCI_VERSION_1_1)
return _screen->_picNotValidSci11;
return _screen->_picNotValid;
}
-void GfxControls::kernelDrawButton(Common::Rect rect, reg_t obj, const char *text, int16 fontId, int16 style, bool hilite) {
+void GfxControls16::kernelDrawButton(Common::Rect rect, reg_t obj, const char *text, int16 fontId, int16 style, bool hilite) {
int16 sci0EarlyPen = 0, sci0EarlyBack = 0;
if (!hilite) {
if (getSciVersion() == SCI_VERSION_0_EARLY) {
@@ -321,7 +321,7 @@ void GfxControls::kernelDrawButton(Common::Rect rect, reg_t obj, const char *tex
}
}
-void GfxControls::kernelDrawText(Common::Rect rect, reg_t obj, const char *text, int16 fontId, TextAlignment alignment, int16 style, bool hilite) {
+void GfxControls16::kernelDrawText(Common::Rect rect, reg_t obj, const char *text, int16 fontId, TextAlignment alignment, int16 style, bool hilite) {
if (!hilite) {
rect.grow(1);
_paint16->eraseRect(rect);
@@ -338,7 +338,7 @@ void GfxControls::kernelDrawText(Common::Rect rect, reg_t obj, const char *text,
}
}
-void GfxControls::kernelDrawTextEdit(Common::Rect rect, reg_t obj, const char *text, int16 fontId, int16 mode, int16 style, int16 cursorPos, int16 maxChars, bool hilite) {
+void GfxControls16::kernelDrawTextEdit(Common::Rect rect, reg_t obj, const char *text, int16 fontId, int16 mode, int16 style, int16 cursorPos, int16 maxChars, bool hilite) {
Common::Rect textRect = rect;
uint16 oldFontId = _text16->GetFontId();
@@ -359,7 +359,7 @@ void GfxControls::kernelDrawTextEdit(Common::Rect rect, reg_t obj, const char *t
_paint16->bitsShow(rect);
}
-void GfxControls::kernelDrawIcon(Common::Rect rect, reg_t obj, GuiResourceId viewId, int16 loopNo, int16 celNo, int16 priority, int16 style, bool hilite) {
+void GfxControls16::kernelDrawIcon(Common::Rect rect, reg_t obj, GuiResourceId viewId, int16 loopNo, int16 celNo, int16 priority, int16 style, bool hilite) {
if (!hilite) {
_paint16->drawCelAndShow(viewId, loopNo, celNo, rect.left, rect.top, priority, 0);
if (style & 0x20) {
@@ -373,7 +373,7 @@ void GfxControls::kernelDrawIcon(Common::Rect rect, reg_t obj, GuiResourceId vie
}
}
-void GfxControls::kernelDrawList(Common::Rect rect, reg_t obj, int16 maxChars, int16 count, const char **entries, GuiResourceId fontId, int16 style, int16 upperPos, int16 cursorPos, bool isAlias, bool hilite) {
+void GfxControls16::kernelDrawList(Common::Rect rect, reg_t obj, int16 maxChars, int16 count, const char **entries, GuiResourceId fontId, int16 style, int16 upperPos, int16 cursorPos, bool isAlias, bool hilite) {
if (!hilite) {
drawListControl(rect, obj, maxChars, count, entries, fontId, upperPos, cursorPos, isAlias);
rect.grow(1);
diff --git a/engines/sci/graphics/controls.h b/engines/sci/graphics/controls16.h
index 17e7c39318..90bd7beacb 100644
--- a/engines/sci/graphics/controls.h
+++ b/engines/sci/graphics/controls16.h
@@ -20,8 +20,8 @@
*
*/
-#ifndef SCI_GRAPHICS_CONTROLS_H
-#define SCI_GRAPHICS_CONTROLS_H
+#ifndef SCI_GRAPHICS_CONTROLS16_H
+#define SCI_GRAPHICS_CONTROLS16_H
namespace Sci {
@@ -50,10 +50,10 @@ class GfxScreen;
/**
* Controls class, handles drawing of controls in SCI16 (SCI0-SCI1.1) games
*/
-class GfxControls {
+class GfxControls16 {
public:
- GfxControls(SegManager *segMan, GfxPorts *ports, GfxPaint16 *paint16, GfxText16 *text16, GfxScreen *screen);
- ~GfxControls();
+ GfxControls16(SegManager *segMan, GfxPorts *ports, GfxPaint16 *paint16, GfxText16 *text16, GfxScreen *screen);
+ ~GfxControls16();
void kernelDrawButton(Common::Rect rect, reg_t obj, const char *text, int16 fontId, int16 style, bool hilite);
void kernelDrawText(Common::Rect rect, reg_t obj, const char *text, int16 fontId, int16 alignment, int16 style, bool hilite);
diff --git a/engines/sci/graphics/controls32.cpp b/engines/sci/graphics/controls32.cpp
new file mode 100644
index 0000000000..ad1d9e8623
--- /dev/null
+++ b/engines/sci/graphics/controls32.cpp
@@ -0,0 +1,204 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "common/system.h"
+
+#include "sci/sci.h"
+#include "sci/event.h"
+#include "sci/engine/kernel.h"
+#include "sci/engine/seg_manager.h"
+#include "sci/graphics/cache.h"
+#include "sci/graphics/compare.h"
+#include "sci/graphics/controls32.h"
+#include "sci/graphics/font.h"
+#include "sci/graphics/screen.h"
+#include "sci/graphics/text32.h"
+
+namespace Sci {
+
+GfxControls32::GfxControls32(SegManager *segMan, GfxCache *cache, GfxScreen *screen, GfxText32 *text)
+ : _segMan(segMan), _cache(cache), _screen(screen), _text(text) {
+}
+
+GfxControls32::~GfxControls32() {
+}
+
+void GfxControls32::kernelTexteditChange(reg_t controlObject) {
+ SciEvent curEvent;
+ uint16 maxChars = 40; //readSelectorValue(_segMan, controlObject, SELECTOR(max)); // TODO
+ reg_t textReference = readSelector(_segMan, controlObject, SELECTOR(text));
+ GfxFont *font = _cache->getFont(readSelectorValue(_segMan, controlObject, SELECTOR(font)));
+ Common::String text;
+ uint16 textSize;
+ bool textChanged = false;
+ bool textAddChar = false;
+ Common::Rect rect;
+
+ if (textReference.isNull())
+ error("kEditControl called on object that doesnt have a text reference");
+ text = _segMan->getString(textReference);
+
+ // TODO: Finish this
+ warning("kEditText ('%s')", text.c_str());
+ return;
+
+ uint16 cursorPos = 0;
+ //uint16 oldCursorPos = cursorPos;
+ bool captureEvents = true;
+ EventManager* eventMan = g_sci->getEventManager();
+
+ while (captureEvents) {
+ curEvent = g_sci->getEventManager()->getSciEvent(SCI_EVENT_KEYBOARD | SCI_EVENT_PEEK);
+
+ if (curEvent.type == SCI_EVENT_NONE) {
+ eventMan->getSciEvent(SCI_EVENT_KEYBOARD); // consume the event
+ } else {
+ textSize = text.size();
+
+ switch (curEvent.type) {
+ case SCI_EVENT_MOUSE_PRESS:
+ // TODO: Implement mouse support for cursor change
+ break;
+ case SCI_EVENT_KEYBOARD:
+ switch (curEvent.data) {
+ case SCI_KEY_BACKSPACE:
+ if (cursorPos > 0) {
+ cursorPos--; text.deleteChar(cursorPos);
+ textChanged = true;
+ }
+ eventMan->getSciEvent(SCI_EVENT_KEYBOARD); // consume the event
+ break;
+ case SCI_KEY_DELETE:
+ if (cursorPos < textSize) {
+ text.deleteChar(cursorPos);
+ textChanged = true;
+ }
+ eventMan->getSciEvent(SCI_EVENT_KEYBOARD); // consume the event
+ break;
+ case SCI_KEY_HOME: // HOME
+ cursorPos = 0; textChanged = true;
+ eventMan->getSciEvent(SCI_EVENT_KEYBOARD); // consume the event
+ break;
+ case SCI_KEY_END: // END
+ cursorPos = textSize; textChanged = true;
+ eventMan->getSciEvent(SCI_EVENT_KEYBOARD); // consume the event
+ break;
+ case SCI_KEY_LEFT: // LEFT
+ if (cursorPos > 0) {
+ cursorPos--; textChanged = true;
+ }
+ eventMan->getSciEvent(SCI_EVENT_KEYBOARD); // consume the event
+ break;
+ case SCI_KEY_RIGHT: // RIGHT
+ if (cursorPos + 1 <= textSize) {
+ cursorPos++; textChanged = true;
+ }
+ eventMan->getSciEvent(SCI_EVENT_KEYBOARD); // consume the event
+ break;
+ case 3: // returned in SCI1 late and newer when Control - C is pressed
+ if (curEvent.modifiers & SCI_KEYMOD_CTRL) {
+ // Control-C erases the whole line
+ cursorPos = 0; text.clear();
+ textChanged = true;
+ }
+ eventMan->getSciEvent(SCI_EVENT_KEYBOARD); // consume the event
+ break;
+ case SCI_KEY_UP:
+ case SCI_KEY_DOWN:
+ case SCI_KEY_ENTER:
+ case SCI_KEY_ESC:
+ case SCI_KEY_TAB:
+ case SCI_KEY_SHIFT_TAB:
+ captureEvents = false;
+ break;
+ default:
+ if ((curEvent.modifiers & SCI_KEYMOD_CTRL) && curEvent.data == 99) {
+ // Control-C in earlier SCI games (SCI0 - SCI1 middle)
+ // Control-C erases the whole line
+ cursorPos = 0; text.clear();
+ textChanged = true;
+ } else if (curEvent.data > 31 && curEvent.data < 256 && textSize < maxChars) {
+ // insert pressed character
+ textAddChar = true;
+ textChanged = true;
+ }
+ eventMan->getSciEvent(SCI_EVENT_KEYBOARD); // consume the event
+ break;
+ }
+ break;
+ }
+ }
+
+ if (textChanged) {
+ rect = g_sci->_gfxCompare->getNSRect(controlObject);
+
+ if (textAddChar) {
+ const char *textPtr = text.c_str();
+
+ // We check if we are really able to add the new char
+ uint16 textWidth = 0;
+ while (*textPtr)
+ textWidth += font->getCharWidth((byte)*textPtr++);
+ textWidth += font->getCharWidth(curEvent.data);
+
+ // Does it fit?
+ if (textWidth >= rect.width()) {
+ return;
+ }
+
+ text.insertChar(curEvent.data, cursorPos++);
+
+ // Note: the following checkAltInput call might make the text
+ // too wide to fit, but SSCI fails to check that too.
+ }
+
+ reg_t hunkId = readSelector(_segMan, controlObject, SELECTOR(bitmap));
+ Common::Rect nsRect = g_sci->_gfxCompare->getNSRect(controlObject);
+ //texteditCursorErase(); // TODO: Cursor
+
+ // Write back string
+ _segMan->strcpy(textReference, text.c_str());
+ // Modify the buffer and show it
+ _text->createTextBitmap(controlObject, 0, 0, hunkId);
+
+ _text->drawTextBitmap(0, 0, nsRect, controlObject);
+ //texteditCursorDraw(rect, text.c_str(), cursorPos); // TODO: Cursor
+ g_system->updateScreen();
+ } else {
+ // TODO: Cursor
+ /*
+ if (g_system->getMillis() >= _texteditBlinkTime) {
+ _paint16->invertRect(_texteditCursorRect);
+ _paint16->bitsShow(_texteditCursorRect);
+ _texteditCursorVisible = !_texteditCursorVisible;
+ texteditSetBlinkTime();
+ }
+ */
+ }
+
+ textAddChar = false;
+ textChanged = false;
+ g_sci->sleep(10);
+ } // while
+}
+
+} // End of namespace Sci
diff --git a/engines/sci/graphics/controls32.h b/engines/sci/graphics/controls32.h
new file mode 100644
index 0000000000..68dca59462
--- /dev/null
+++ b/engines/sci/graphics/controls32.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 SCI_GRAPHICS_CONTROLS32_H
+#define SCI_GRAPHICS_CONTROLS32_H
+
+namespace Sci {
+
+class GfxCache;
+class GfxScreen;
+class GfxText32;
+
+/**
+ * Controls class, handles drawing of controls in SCI32 (SCI2, SCI2.1, SCI3) games
+ */
+class GfxControls32 {
+public:
+ GfxControls32(SegManager *segMan, GfxCache *cache, GfxScreen *screen, GfxText32 *text);
+ ~GfxControls32();
+
+ void kernelTexteditChange(reg_t controlObject);
+
+private:
+ SegManager *_segMan;
+ GfxCache *_cache;
+ GfxScreen *_screen;
+ GfxText32 *_text;
+};
+
+} // End of namespace Sci
+
+#endif
diff --git a/engines/sci/graphics/coordadjuster.cpp b/engines/sci/graphics/coordadjuster.cpp
index 2952d4da7b..1446888cf4 100644
--- a/engines/sci/graphics/coordadjuster.cpp
+++ b/engines/sci/graphics/coordadjuster.cpp
@@ -86,8 +86,8 @@ Common::Rect GfxCoordAdjuster16::pictureGetDisplayArea() {
#ifdef ENABLE_SCI32
GfxCoordAdjuster32::GfxCoordAdjuster32(SegManager *segMan)
: _segMan(segMan) {
- scriptsRunningWidth = 0;
- scriptsRunningHeight = 0;
+ _scriptsRunningWidth = 0;
+ _scriptsRunningHeight = 0;
}
GfxCoordAdjuster32::~GfxCoordAdjuster32() {
@@ -109,18 +109,18 @@ void GfxCoordAdjuster32::kernelLocalToGlobal(int16 &x, int16 &y, reg_t planeObje
}
void GfxCoordAdjuster32::setScriptsResolution(uint16 width, uint16 height) {
- scriptsRunningWidth = width;
- scriptsRunningHeight = height;
+ _scriptsRunningWidth = width;
+ _scriptsRunningHeight = height;
}
void GfxCoordAdjuster32::fromDisplayToScript(int16 &y, int16 &x) {
- y = ((y * scriptsRunningHeight) / g_sci->_gfxScreen->getHeight());
- x = ((x * scriptsRunningWidth) / g_sci->_gfxScreen->getWidth());
+ y = ((y * _scriptsRunningHeight) / g_sci->_gfxScreen->getHeight());
+ x = ((x * _scriptsRunningWidth) / g_sci->_gfxScreen->getWidth());
}
void GfxCoordAdjuster32::fromScriptToDisplay(int16 &y, int16 &x) {
- y = ((y * g_sci->_gfxScreen->getHeight()) / scriptsRunningHeight);
- x = ((x * g_sci->_gfxScreen->getWidth()) / scriptsRunningWidth);
+ y = ((y * g_sci->_gfxScreen->getHeight()) / _scriptsRunningHeight);
+ x = ((x * g_sci->_gfxScreen->getWidth()) / _scriptsRunningWidth);
}
void GfxCoordAdjuster32::pictureSetDisplayArea(Common::Rect displayArea) {
diff --git a/engines/sci/graphics/coordadjuster.h b/engines/sci/graphics/coordadjuster.h
index 23cf79d209..63f608be6b 100644
--- a/engines/sci/graphics/coordadjuster.h
+++ b/engines/sci/graphics/coordadjuster.h
@@ -96,8 +96,8 @@ private:
Common::Rect _pictureDisplayArea;
- uint16 scriptsRunningWidth;
- uint16 scriptsRunningHeight;
+ uint16 _scriptsRunningWidth;
+ uint16 _scriptsRunningHeight;
};
#endif
diff --git a/engines/sci/graphics/cursor.cpp b/engines/sci/graphics/cursor.cpp
index 50da48aaf3..52a5961070 100644
--- a/engines/sci/graphics/cursor.cpp
+++ b/engines/sci/graphics/cursor.cpp
@@ -59,10 +59,16 @@ GfxCursor::GfxCursor(ResourceManager *resMan, GfxPalette *palette, GfxScreen *sc
_zoomColor = 0;
_zoomMultiplier = 0;
_cursorSurface = 0;
+
if (g_sci && g_sci->getGameId() == GID_KQ6 && g_sci->getPlatform() == Common::kPlatformWindows)
_useOriginalKQ6WinCursors = ConfMan.getBool("windows_cursors");
else
_useOriginalKQ6WinCursors = false;
+
+ if (g_sci && g_sci->getGameId() == GID_SQ4 && getSciVersion() == SCI_VERSION_1_1)
+ _useSilverSQ4CDCursors = ConfMan.getBool("silver_cursors");
+ else
+ _useSilverSQ4CDCursors = false;
}
GfxCursor::~GfxCursor() {
@@ -125,18 +131,28 @@ void GfxCursor::kernelSetShape(GuiResourceId resourceId) {
error("cursor resource %d has invalid size", resourceId);
resourceData = resource->data;
- // hotspot is specified for SCI1 cursors
- hotspot.x = READ_LE_UINT16(resourceData);
- hotspot.y = READ_LE_UINT16(resourceData + 2);
- // bit 0 of resourceData[3] is set on <SCI1 games, which means center hotspot
- if ((hotspot.x == 0) && (hotspot.y == 256))
- hotspot.x = hotspot.y = SCI_CURSOR_SCI0_HEIGHTWIDTH / 2;
+
+ if (getSciVersion() <= SCI_VERSION_0_LATE) {
+ // SCI0 cursors contain hotspot flags, not actual hotspot coordinates.
+ // If bit 0 of resourceData[3] is set, the hotspot should be centered,
+ // otherwise it's in the top left of the mouse cursor.
+ hotspot.x = hotspot.y = resourceData[3] ? SCI_CURSOR_SCI0_HEIGHTWIDTH / 2 : 0;
+ } else {
+ // Cursors in newer SCI versions contain actual hotspot coordinates.
+ hotspot.x = READ_LE_UINT16(resourceData);
+ hotspot.y = READ_LE_UINT16(resourceData + 2);
+ }
// Now find out what colors we are supposed to use
colorMapping[0] = 0; // Black is hardcoded
colorMapping[1] = _screen->getColorWhite(); // White is also hardcoded
colorMapping[2] = SCI_CURSOR_SCI0_TRANSPARENCYCOLOR;
colorMapping[3] = _palette->matchColor(170, 170, 170); // Grey
+ // Special case for the magnifier cursor in LB1 (bug #3487092).
+ // No other SCI0 game has a cursor resource of 1, so this is handled
+ // specifically for LB1.
+ if (g_sci->getGameId() == GID_LAURABOW && resourceId == 1)
+ colorMapping[3] = _screen->getColorWhite();
// Seek to actual data
resourceData += 4;
@@ -165,6 +181,11 @@ void GfxCursor::kernelSetShape(GuiResourceId resourceId) {
rawBitmap = upscaledBitmap;
}
+ if (hotspot.x >= heightWidth || hotspot.y >= heightWidth) {
+ error("cursor %d's hotspot (%d, %d) is out of range of the cursor's dimensions (%dx%d)",
+ resourceId, hotspot.x, hotspot.y, heightWidth, heightWidth);
+ }
+
CursorMan.replaceCursor(rawBitmap, heightWidth, heightWidth, hotspot.x, hotspot.y, SCI_CURSOR_SCI0_TRANSPARENCYCOLOR);
kernelShow();
@@ -191,6 +212,26 @@ void GfxCursor::kernelSetView(GuiResourceId viewNum, int loopNum, int celNum, Co
return;
}
+ // Use the alternate silver cursors in SQ4 CD, if requested
+ if (_useSilverSQ4CDCursors) {
+ switch(viewNum) {
+ case 850:
+ case 852:
+ case 854:
+ case 856:
+ celNum = 3;
+ break;
+ case 851:
+ case 853:
+ case 855:
+ case 999:
+ celNum = 2;
+ break;
+ default:
+ break;
+ }
+ }
+
if (!_cachedCursors.contains(viewNum))
_cachedCursors[viewNum] = new GfxView(_resMan, _screen, _palette, viewNum);
diff --git a/engines/sci/graphics/cursor.h b/engines/sci/graphics/cursor.h
index 25109b3920..ac928f50bb 100644
--- a/engines/sci/graphics/cursor.h
+++ b/engines/sci/graphics/cursor.h
@@ -113,13 +113,18 @@ private:
bool _isVisible;
- // KQ6 Windows has different black and white cursors. If this is
- // true (set from the sci_originalkq6wincursors ini setting), then
- // we use these, and don't scale them by 2x like the rest of the
- // graphics, like SSCI did. These look very ugly, which is why
- // they aren't enabled by default.
+ // KQ6 Windows has different black and white cursors. If this is true (set
+ // from the windows_cursors ini setting), then we use these and don't scale
+ // them by 2x like the rest of the graphics, like SSCI did. These look very
+ // ugly, which is why they aren't enabled by default.
bool _useOriginalKQ6WinCursors;
+ // The CD version of SQ4 contains a complete set of silver mouse cursors.
+ // If this is true (set from the silver_cursors ini setting), then we use
+ // these instead and replace the game's gold cursors with their silver
+ // equivalents.
+ bool _useSilverSQ4CDCursors;
+
// Mac versions of games use a remap list to remap their cursors
Common::Array<uint16> _macCursorRemap;
};
diff --git a/engines/sci/graphics/frameout.cpp b/engines/sci/graphics/frameout.cpp
index a41efd6a9f..b12413ab69 100644
--- a/engines/sci/graphics/frameout.cpp
+++ b/engines/sci/graphics/frameout.cpp
@@ -56,17 +56,18 @@ GfxFrameout::GfxFrameout(SegManager *segMan, ResourceManager *resMan, GfxCoordAd
: _segMan(segMan), _resMan(resMan), _cache(cache), _screen(screen), _palette(palette), _paint32(paint32) {
_coordAdjuster = (GfxCoordAdjuster32 *)coordAdjuster;
- scriptsRunningWidth = 320;
- scriptsRunningHeight = 200;
+ _scriptsRunningWidth = 320;
+ _scriptsRunningHeight = 200;
}
GfxFrameout::~GfxFrameout() {
+ clear();
}
void GfxFrameout::clear() {
- _screenItems.clear();
+ deletePlaneItems(NULL_REG);
_planes.clear();
- _planePictures.clear();
+ deletePlanePictures(NULL_REG);
}
void GfxFrameout::kernelAddPlane(reg_t object) {
@@ -80,11 +81,11 @@ void GfxFrameout::kernelAddPlane(reg_t object) {
// The above can be 0 in SCI3 (e.g. Phantasmagoria 2)
if (tmpRunningWidth > 0 && tmpRunningHeight > 0) {
- scriptsRunningWidth = tmpRunningWidth;
- scriptsRunningHeight = tmpRunningHeight;
+ _scriptsRunningWidth = tmpRunningWidth;
+ _scriptsRunningHeight = tmpRunningHeight;
}
- _coordAdjuster->setScriptsResolution(scriptsRunningWidth, scriptsRunningHeight);
+ _coordAdjuster->setScriptsResolution(_scriptsRunningWidth, _scriptsRunningHeight);
}
newPlane.object = object;
@@ -101,7 +102,7 @@ void GfxFrameout::kernelAddPlane(reg_t object) {
}
void GfxFrameout::kernelUpdatePlane(reg_t object) {
- for (PlaneList::iterator it = _planes.begin(); it != _planes.end(); it++) {
+ for (PlaneList::iterator it = _planes.begin(); it != _planes.end(); ++it) {
if (it->object == object) {
// Read some information
it->priority = readSelectorValue(_segMan, object, SELECTOR(priority));
@@ -118,14 +119,14 @@ void GfxFrameout::kernelUpdatePlane(reg_t object) {
}
it->planeRect.top = readSelectorValue(_segMan, object, SELECTOR(top));
it->planeRect.left = readSelectorValue(_segMan, object, SELECTOR(left));
- it->planeRect.bottom = readSelectorValue(_segMan, object, SELECTOR(bottom)) + 1;
- it->planeRect.right = readSelectorValue(_segMan, object, SELECTOR(right)) + 1;
+ it->planeRect.bottom = readSelectorValue(_segMan, object, SELECTOR(bottom));
+ it->planeRect.right = readSelectorValue(_segMan, object, SELECTOR(right));
Common::Rect screenRect(_screen->getWidth(), _screen->getHeight());
- it->planeRect.top = (it->planeRect.top * screenRect.height()) / scriptsRunningHeight;
- it->planeRect.left = (it->planeRect.left * screenRect.width()) / scriptsRunningWidth;
- it->planeRect.bottom = (it->planeRect.bottom * screenRect.height()) / scriptsRunningHeight;
- it->planeRect.right = (it->planeRect.right * screenRect.width()) / scriptsRunningWidth;
+ it->planeRect.top = (it->planeRect.top * screenRect.height()) / _scriptsRunningHeight;
+ it->planeRect.left = (it->planeRect.left * screenRect.width()) / _scriptsRunningWidth;
+ it->planeRect.bottom = (it->planeRect.bottom * screenRect.height()) / _scriptsRunningHeight;
+ it->planeRect.right = (it->planeRect.right * screenRect.width()) / _scriptsRunningWidth;
// We get negative left in kq7 in scrolling rooms
if (it->planeRect.left < 0) {
@@ -178,22 +179,23 @@ void GfxFrameout::kernelUpdatePlane(reg_t object) {
}
void GfxFrameout::kernelDeletePlane(reg_t object) {
+ deletePlaneItems(object);
deletePlanePictures(object);
- for (PlaneList::iterator it = _planes.begin(); it != _planes.end(); it++) {
+
+ for (PlaneList::iterator it = _planes.begin(); it != _planes.end(); ++it) {
if (it->object == object) {
_planes.erase(it);
Common::Rect planeRect;
planeRect.top = readSelectorValue(_segMan, object, SELECTOR(top));
planeRect.left = readSelectorValue(_segMan, object, SELECTOR(left));
- planeRect.bottom = readSelectorValue(_segMan, object, SELECTOR(bottom)) + 1;
- planeRect.right = readSelectorValue(_segMan, object, SELECTOR(right)) + 1;
+ planeRect.bottom = readSelectorValue(_segMan, object, SELECTOR(bottom));
+ planeRect.right = readSelectorValue(_segMan, object, SELECTOR(right));
Common::Rect screenRect(_screen->getWidth(), _screen->getHeight());
- planeRect.top = (planeRect.top * screenRect.height()) / scriptsRunningHeight;
- planeRect.left = (planeRect.left * screenRect.width()) / scriptsRunningWidth;
- planeRect.bottom = (planeRect.bottom * screenRect.height()) / scriptsRunningHeight;
- planeRect.right = (planeRect.right * screenRect.width()) / scriptsRunningWidth;
- planeRect.clip(screenRect); // we need to do this, at least in gk1 on cemetary we get bottom right -> 201, 321
+ planeRect.top = (planeRect.top * screenRect.height()) / _scriptsRunningHeight;
+ planeRect.left = (planeRect.left * screenRect.width()) / _scriptsRunningWidth;
+ planeRect.bottom = (planeRect.bottom * screenRect.height()) / _scriptsRunningHeight;
+ planeRect.right = (planeRect.right * screenRect.width()) / _scriptsRunningWidth;
// Blackout removed plane rect
_paint32->fillRect(planeRect, 0);
return;
@@ -213,12 +215,15 @@ void GfxFrameout::addPlanePicture(reg_t object, GuiResourceId pictureId, uint16
}
void GfxFrameout::deletePlanePictures(reg_t object) {
- for (PlanePictureList::iterator it = _planePictures.begin(); it != _planePictures.end(); it++) {
- if (it->object == object) {
+ PlanePictureList::iterator it = _planePictures.begin();
+
+ while (it != _planePictures.end()) {
+ if (it->object == object || object.isNull()) {
+ delete it->pictureCels;
delete it->picture;
- _planePictures.erase(it);
- deletePlanePictures(object);
- return;
+ it = _planePictures.erase(it);
+ } else {
+ ++it;
}
}
}
@@ -271,6 +276,29 @@ void GfxFrameout::kernelDeleteScreenItem(reg_t object) {
}
_screenItems.remove(itemEntry);
+ delete itemEntry;
+}
+
+void GfxFrameout::deletePlaneItems(reg_t planeObject) {
+ FrameoutList::iterator listIterator = _screenItems.begin();
+
+ while (listIterator != _screenItems.end()) {
+ bool objectMatches = false;
+ if (!planeObject.isNull()) {
+ reg_t itemPlane = readSelector(_segMan, (*listIterator)->object, SELECTOR(plane));
+ objectMatches = (planeObject == itemPlane);
+ } else {
+ objectMatches = true;
+ }
+
+ if (objectMatches) {
+ FrameoutEntry *itemEntry = *listIterator;
+ listIterator = _screenItems.erase(listIterator);
+ delete itemEntry;
+ } else {
+ ++listIterator;
+ }
+ }
}
FrameoutEntry *GfxFrameout::findScreenItem(reg_t object) {
@@ -329,37 +357,149 @@ void GfxFrameout::sortPlanes() {
Common::sort(_planes.begin(), _planes.end(), planeSortHelper);
}
-void GfxFrameout::kernelFrameout() {
- if (g_sci->_robotDecoder->isVideoLoaded()) {
- bool skipVideo = false;
- RobotDecoder *videoDecoder = g_sci->_robotDecoder;
- uint16 x = videoDecoder->getPos().x;
- uint16 y = videoDecoder->getPos().y;
+int16 GfxFrameout::upscaleHorizontalCoordinate(int16 coordinate) {
+ return ((coordinate * _screen->getWidth()) / _scriptsRunningWidth);
+}
- if (videoDecoder->hasDirtyPalette())
- videoDecoder->setSystemPalette();
+int16 GfxFrameout::upscaleVerticalCoordinate(int16 coordinate) {
+ return ((coordinate * _screen->getHeight()) / _scriptsRunningHeight);
+}
- while (!g_engine->shouldQuit() && !videoDecoder->endOfVideo() && !skipVideo) {
- if (videoDecoder->needsUpdate()) {
- const Graphics::Surface *frame = videoDecoder->decodeNextFrame();
- if (frame) {
- g_system->copyRectToScreen((byte *)frame->pixels, frame->pitch, x, y, frame->w, frame->h);
+Common::Rect GfxFrameout::upscaleRect(Common::Rect &rect) {
+ rect.top = (rect.top * _scriptsRunningHeight) / _screen->getHeight();
+ rect.left = (rect.left * _scriptsRunningWidth) / _screen->getWidth();
+ rect.bottom = (rect.bottom * _scriptsRunningHeight) / _screen->getHeight();
+ rect.right = (rect.right * _scriptsRunningWidth) / _screen->getWidth();
- if (videoDecoder->hasDirtyPalette())
- videoDecoder->setSystemPalette();
+ return rect;
+}
- g_system->updateScreen();
- }
+void GfxFrameout::showVideo() {
+ bool skipVideo = false;
+ RobotDecoder *videoDecoder = g_sci->_robotDecoder;
+ uint16 x = videoDecoder->getPos().x;
+ uint16 y = videoDecoder->getPos().y;
+
+ if (videoDecoder->hasDirtyPalette())
+ videoDecoder->setSystemPalette();
+
+ while (!g_engine->shouldQuit() && !videoDecoder->endOfVideo() && !skipVideo) {
+ if (videoDecoder->needsUpdate()) {
+ const Graphics::Surface *frame = videoDecoder->decodeNextFrame();
+ if (frame) {
+ g_system->copyRectToScreen((byte *)frame->pixels, frame->pitch, x, y, frame->w, frame->h);
+
+ if (videoDecoder->hasDirtyPalette())
+ videoDecoder->setSystemPalette();
+
+ g_system->updateScreen();
}
+ }
- Common::Event event;
- while (g_system->getEventManager()->pollEvent(event)) {
- if ((event.type == Common::EVENT_KEYDOWN && event.kbd.keycode == Common::KEYCODE_ESCAPE) || event.type == Common::EVENT_LBUTTONUP)
- skipVideo = true;
+ Common::Event event;
+ while (g_system->getEventManager()->pollEvent(event)) {
+ if ((event.type == Common::EVENT_KEYDOWN && event.kbd.keycode == Common::KEYCODE_ESCAPE) || event.type == Common::EVENT_LBUTTONUP)
+ skipVideo = true;
+ }
+
+ g_system->delayMillis(10);
+ }
+}
+
+void GfxFrameout::createPlaneItemList(reg_t planeObject, FrameoutList &itemList) {
+ // Copy screen items of the current frame to the list of items to be drawn
+ for (FrameoutList::iterator listIterator = _screenItems.begin(); listIterator != _screenItems.end(); listIterator++) {
+ reg_t itemPlane = readSelector(_segMan, (*listIterator)->object, SELECTOR(plane));
+ if (planeObject == itemPlane) {
+ kernelUpdateScreenItem((*listIterator)->object); // TODO: Why is this necessary?
+ itemList.push_back(*listIterator);
+ }
+ }
+
+ for (PlanePictureList::iterator pictureIt = _planePictures.begin(); pictureIt != _planePictures.end(); pictureIt++) {
+ if (pictureIt->object == planeObject) {
+ GfxPicture *planePicture = pictureIt->picture;
+ // Allocate memory for picture cels
+ pictureIt->pictureCels = new FrameoutEntry[planePicture->getSci32celCount()];
+
+ // Add following cels to the itemlist
+ FrameoutEntry *picEntry = pictureIt->pictureCels;
+ int planePictureCels = planePicture->getSci32celCount();
+ for (int pictureCelNr = 0; pictureCelNr < planePictureCels; pictureCelNr++) {
+ picEntry->celNo = pictureCelNr;
+ picEntry->object = NULL_REG;
+ picEntry->picture = planePicture;
+ picEntry->y = planePicture->getSci32celY(pictureCelNr);
+ picEntry->x = planePicture->getSci32celX(pictureCelNr);
+ picEntry->picStartX = pictureIt->startX;
+ picEntry->picStartY = pictureIt->startY;
+
+ picEntry->priority = planePicture->getSci32celPriority(pictureCelNr);
+
+ itemList.push_back(picEntry);
+ picEntry++;
}
+ }
+ }
+
+ // Now sort our itemlist
+ Common::sort(itemList.begin(), itemList.end(), sortHelper);
+}
- g_system->delayMillis(10);
+bool GfxFrameout::isPictureOutOfView(FrameoutEntry *itemEntry, Common::Rect planeRect, int16 planeOffsetX, int16 planeOffsetY) {
+ // Out of view horizontally (sanity checks)
+ int16 pictureCelStartX = itemEntry->picStartX + itemEntry->x;
+ int16 pictureCelEndX = pictureCelStartX + itemEntry->picture->getSci32celWidth(itemEntry->celNo);
+ int16 planeStartX = planeOffsetX;
+ int16 planeEndX = planeStartX + planeRect.width();
+ if (pictureCelEndX < planeStartX)
+ return true;
+ if (pictureCelStartX > planeEndX)
+ return true;
+
+ // Out of view vertically (sanity checks)
+ int16 pictureCelStartY = itemEntry->picStartY + itemEntry->y;
+ int16 pictureCelEndY = pictureCelStartY + itemEntry->picture->getSci32celHeight(itemEntry->celNo);
+ int16 planeStartY = planeOffsetY;
+ int16 planeEndY = planeStartY + planeRect.height();
+ if (pictureCelEndY < planeStartY)
+ return true;
+ if (pictureCelStartY > planeEndY)
+ return true;
+
+ return false;
+}
+
+void GfxFrameout::drawPicture(FrameoutEntry *itemEntry, int16 planeOffsetX, int16 planeOffsetY, bool planePictureMirrored) {
+ int16 pictureOffsetX = planeOffsetX;
+ int16 pictureX = itemEntry->x;
+ if ((planeOffsetX) || (itemEntry->picStartX)) {
+ if (planeOffsetX <= itemEntry->picStartX) {
+ pictureX += itemEntry->picStartX - planeOffsetX;
+ pictureOffsetX = 0;
+ } else {
+ pictureOffsetX = planeOffsetX - itemEntry->picStartX;
+ }
+ }
+
+ int16 pictureOffsetY = planeOffsetY;
+ int16 pictureY = itemEntry->y;
+ if ((planeOffsetY) || (itemEntry->picStartY)) {
+ if (planeOffsetY <= itemEntry->picStartY) {
+ pictureY += itemEntry->picStartY - planeOffsetY;
+ pictureOffsetY = 0;
+ } else {
+ pictureOffsetY = planeOffsetY - itemEntry->picStartY;
}
+ }
+
+ itemEntry->picture->drawSci32Vga(itemEntry->celNo, pictureX, itemEntry->y, pictureOffsetX, pictureOffsetY, planePictureMirrored);
+ // warning("picture cel %d %d", itemEntry->celNo, itemEntry->priority);
+}
+
+void GfxFrameout::kernelFrameout() {
+ if (g_sci->_robotDecoder->isVideoLoaded()) {
+ showVideo();
return;
}
@@ -383,7 +523,8 @@ void GfxFrameout::kernelFrameout() {
// There is a race condition lurking in SQ6, which causes the game to hang in the intro, when teleporting to Polysorbate LX.
// Since I first wrote the patch, the race has stopped occurring for me though.
// I'll leave this for investigation later, when someone can reproduce.
- if (it->pictureId == 0xffff)
+ //if (it->pictureId == 0xffff) // FIXME: This is what SSCI does, and fixes the intro of LSL7, but breaks the dialogs in GK1 (adds black boxes)
+ if (it->planeBack)
_paint32->fillRect(it->planeRect, it->planeBack);
GuiResourceId planeMainPictureId = it->pictureId;
@@ -393,43 +534,7 @@ void GfxFrameout::kernelFrameout() {
FrameoutList itemList;
- // Copy screen items of the current frame to the list of items to be drawn
- for (FrameoutList::iterator listIterator = _screenItems.begin(); listIterator != _screenItems.end(); listIterator++) {
- reg_t itemPlane = readSelector(_segMan, (*listIterator)->object, SELECTOR(plane));
- if (planeObject == itemPlane) {
- kernelUpdateScreenItem((*listIterator)->object); // TODO: Why is this necessary?
- itemList.push_back(*listIterator);
- }
- }
-
- for (PlanePictureList::iterator pictureIt = _planePictures.begin(); pictureIt != _planePictures.end(); pictureIt++) {
- if (pictureIt->object == planeObject) {
- GfxPicture *planePicture = pictureIt->picture;
- // Allocate memory for picture cels
- pictureIt->pictureCels = new FrameoutEntry[planePicture->getSci32celCount()];
-
- // Add following cels to the itemlist
- FrameoutEntry *picEntry = pictureIt->pictureCels;
- int planePictureCels = planePicture->getSci32celCount();
- for (int pictureCelNr = 0; pictureCelNr < planePictureCels; pictureCelNr++) {
- picEntry->celNo = pictureCelNr;
- picEntry->object = NULL_REG;
- picEntry->picture = planePicture;
- picEntry->y = planePicture->getSci32celY(pictureCelNr);
- picEntry->x = planePicture->getSci32celX(pictureCelNr);
- picEntry->picStartX = pictureIt->startX;
- picEntry->picStartY = pictureIt->startY;
-
- picEntry->priority = planePicture->getSci32celPriority(pictureCelNr);
-
- itemList.push_back(picEntry);
- picEntry++;
- }
- }
- }
-
- // Now sort our itemlist
- Common::sort(itemList.begin(), itemList.end(), sortHelper);
+ createPlaneItemList(planeObject, itemList);
// warning("Plane %s", _segMan->getObjectName(planeObject));
@@ -438,69 +543,24 @@ void GfxFrameout::kernelFrameout() {
if (itemEntry->object.isNull()) {
// Picture cel data
- itemEntry->y = ((itemEntry->y * _screen->getHeight()) / scriptsRunningHeight);
- itemEntry->x = ((itemEntry->x * _screen->getWidth()) / scriptsRunningWidth);
- itemEntry->picStartX = ((itemEntry->picStartX * _screen->getWidth()) / scriptsRunningWidth);
- itemEntry->picStartY = ((itemEntry->picStartY * _screen->getHeight()) / scriptsRunningHeight);
-
- // Out of view horizontally (sanity checks)
- int16 pictureCelStartX = itemEntry->picStartX + itemEntry->x;
- int16 pictureCelEndX = pictureCelStartX + itemEntry->picture->getSci32celWidth(itemEntry->celNo);
- int16 planeStartX = it->planeOffsetX;
- int16 planeEndX = planeStartX + it->planeRect.width();
- if (pictureCelEndX < planeStartX)
- continue;
- if (pictureCelStartX > planeEndX)
- continue;
-
- // Out of view vertically (sanity checks)
- int16 pictureCelStartY = itemEntry->picStartY + itemEntry->y;
- int16 pictureCelEndY = pictureCelStartY + itemEntry->picture->getSci32celHeight(itemEntry->celNo);
- int16 planeStartY = it->planeOffsetY;
- int16 planeEndY = planeStartY + it->planeRect.height();
- if (pictureCelEndY < planeStartY)
- continue;
- if (pictureCelStartY > planeEndY)
- continue;
+ itemEntry->x = upscaleHorizontalCoordinate(itemEntry->x);
+ itemEntry->y = upscaleVerticalCoordinate(itemEntry->y);
+ itemEntry->picStartX = upscaleHorizontalCoordinate(itemEntry->picStartX);
+ itemEntry->picStartY = upscaleVerticalCoordinate(itemEntry->picStartY);
- int16 pictureOffsetX = it->planeOffsetX;
- int16 pictureX = itemEntry->x;
- if ((it->planeOffsetX) || (itemEntry->picStartX)) {
- if (it->planeOffsetX <= itemEntry->picStartX) {
- pictureX += itemEntry->picStartX - it->planeOffsetX;
- pictureOffsetX = 0;
- } else {
- pictureOffsetX = it->planeOffsetX - itemEntry->picStartX;
- }
- }
-
- int16 pictureOffsetY = it->planeOffsetY;
- int16 pictureY = itemEntry->y;
- if ((it->planeOffsetY) || (itemEntry->picStartY)) {
- if (it->planeOffsetY <= itemEntry->picStartY) {
- pictureY += itemEntry->picStartY - it->planeOffsetY;
- pictureOffsetY = 0;
- } else {
- pictureOffsetY = it->planeOffsetY - itemEntry->picStartY;
- }
- }
-
- itemEntry->picture->drawSci32Vga(itemEntry->celNo, pictureX, itemEntry->y, pictureOffsetX, pictureOffsetY, it->planePictureMirrored);
-// warning("picture cel %d %d", itemEntry->celNo, itemEntry->priority);
-
- } else if (itemEntry->viewId != 0xFFFF) {
- GfxView *view = _cache->getView(itemEntry->viewId);
-
-// warning("view %s %04x:%04x", _segMan->getObjectName(itemEntry->object), PRINT_REG(itemEntry->object));
-
- if (view->isSci2Hires()) {
+ if (!isPictureOutOfView(itemEntry, it->planeRect, it->planeOffsetX, it->planeOffsetY))
+ drawPicture(itemEntry, it->planeOffsetX, it->planeOffsetY, it->planePictureMirrored);
+ } else {
+ GfxView *view = (itemEntry->viewId != 0xFFFF) ? _cache->getView(itemEntry->viewId) : NULL;
+
+ if (view && view->isSci2Hires()) {
int16 dummyX = 0;
view->adjustToUpscaledCoordinates(itemEntry->y, itemEntry->x);
view->adjustToUpscaledCoordinates(itemEntry->z, dummyX);
} else if (getSciVersion() == SCI_VERSION_2_1) {
- itemEntry->y = (itemEntry->y * _screen->getHeight()) / scriptsRunningHeight;
- itemEntry->x = (itemEntry->x * _screen->getWidth()) / scriptsRunningWidth;
- itemEntry->z = (itemEntry->z * _screen->getHeight()) / scriptsRunningHeight;
+ itemEntry->x = upscaleHorizontalCoordinate(itemEntry->x);
+ itemEntry->y = upscaleVerticalCoordinate(itemEntry->y);
+ itemEntry->z = upscaleVerticalCoordinate(itemEntry->z);
}
// Adjust according to current scroll position
@@ -511,33 +571,33 @@ void GfxFrameout::kernelFrameout() {
if (useInsetRect) {
itemEntry->celRect.top = readSelectorValue(_segMan, itemEntry->object, SELECTOR(inTop));
itemEntry->celRect.left = readSelectorValue(_segMan, itemEntry->object, SELECTOR(inLeft));
- itemEntry->celRect.bottom = readSelectorValue(_segMan, itemEntry->object, SELECTOR(inBottom)) + 1;
- itemEntry->celRect.right = readSelectorValue(_segMan, itemEntry->object, SELECTOR(inRight)) + 1;
- if (view->isSci2Hires()) {
+ itemEntry->celRect.bottom = readSelectorValue(_segMan, itemEntry->object, SELECTOR(inBottom));
+ itemEntry->celRect.right = readSelectorValue(_segMan, itemEntry->object, SELECTOR(inRight));
+ if (view && view->isSci2Hires()) {
view->adjustToUpscaledCoordinates(itemEntry->celRect.top, itemEntry->celRect.left);
view->adjustToUpscaledCoordinates(itemEntry->celRect.bottom, itemEntry->celRect.right);
}
itemEntry->celRect.translate(itemEntry->x, itemEntry->y);
// TODO: maybe we should clip the cels rect with this, i'm not sure
// the only currently known usage is game menu of gk1
- } else {
- if ((itemEntry->scaleX == 128) && (itemEntry->scaleY == 128))
- view->getCelRect(itemEntry->loopNo, itemEntry->celNo, itemEntry->x, itemEntry->y, itemEntry->z, itemEntry->celRect);
- else
- view->getCelScaledRect(itemEntry->loopNo, itemEntry->celNo, itemEntry->x, itemEntry->y, itemEntry->z, itemEntry->scaleX, itemEntry->scaleY, itemEntry->celRect);
+ } else if (view) {
+ if ((itemEntry->scaleX == 128) && (itemEntry->scaleY == 128))
+ view->getCelRect(itemEntry->loopNo, itemEntry->celNo,
+ itemEntry->x, itemEntry->y, itemEntry->z, itemEntry->celRect);
+ else
+ view->getCelScaledRect(itemEntry->loopNo, itemEntry->celNo,
+ itemEntry->x, itemEntry->y, itemEntry->z, itemEntry->scaleX,
+ itemEntry->scaleY, itemEntry->celRect);
Common::Rect nsRect = itemEntry->celRect;
// Translate back to actual coordinate within scrollable plane
nsRect.translate(it->planeOffsetX, it->planeOffsetY);
- if (view->isSci2Hires()) {
+ if (view && view->isSci2Hires()) {
view->adjustBackUpscaledCoordinates(nsRect.top, nsRect.left);
view->adjustBackUpscaledCoordinates(nsRect.bottom, nsRect.right);
} else if (getSciVersion() == SCI_VERSION_2_1) {
- nsRect.top = (nsRect.top * scriptsRunningHeight) / _screen->getHeight();
- nsRect.left = (nsRect.left * scriptsRunningWidth) / _screen->getWidth();
- nsRect.bottom = (nsRect.bottom * scriptsRunningHeight) / _screen->getHeight();
- nsRect.right = (nsRect.right * scriptsRunningWidth) / _screen->getWidth();
+ nsRect = upscaleRect(nsRect);
}
if (g_sci->getGameId() == GID_PHANTASMAGORIA2) {
@@ -552,7 +612,7 @@ void GfxFrameout::kernelFrameout() {
int16 screenHeight = _screen->getHeight();
int16 screenWidth = _screen->getWidth();
- if (view->isSci2Hires()) {
+ if (view && view->isSci2Hires()) {
screenHeight = _screen->getDisplayHeight();
screenWidth = _screen->getDisplayWidth();
}
@@ -565,7 +625,8 @@ void GfxFrameout::kernelFrameout() {
Common::Rect clipRect, translatedClipRect;
clipRect = itemEntry->celRect;
- if (view->isSci2Hires()) {
+
+ if (view && view->isSci2Hires()) {
clipRect.clip(it->upscaledPlaneClipRect);
translatedClipRect = clipRect;
translatedClipRect.translate(it->upscaledPlaneRect.left, it->upscaledPlaneRect.top);
@@ -575,16 +636,20 @@ void GfxFrameout::kernelFrameout() {
translatedClipRect.translate(it->planeRect.left, it->planeRect.top);
}
- if (!clipRect.isEmpty()) {
- if ((itemEntry->scaleX == 128) && (itemEntry->scaleY == 128))
- view->draw(itemEntry->celRect, clipRect, translatedClipRect, itemEntry->loopNo, itemEntry->celNo, 255, 0, view->isSci2Hires());
- else
- view->drawScaled(itemEntry->celRect, clipRect, translatedClipRect, itemEntry->loopNo, itemEntry->celNo, 255, itemEntry->scaleX, itemEntry->scaleY);
+ if (view) {
+ if (!clipRect.isEmpty()) {
+ if ((itemEntry->scaleX == 128) && (itemEntry->scaleY == 128))
+ view->draw(itemEntry->celRect, clipRect, translatedClipRect,
+ itemEntry->loopNo, itemEntry->celNo, 255, 0, view->isSci2Hires());
+ else
+ view->drawScaled(itemEntry->celRect, clipRect, translatedClipRect,
+ itemEntry->loopNo, itemEntry->celNo, 255, itemEntry->scaleX, itemEntry->scaleY);
+ }
}
- } else {
- // Most likely a text entry
+
+ // Draw text, if it exists
if (lookupSelector(_segMan, itemEntry->object, SELECTOR(text), NULL, NULL) == kSelectorVariable) {
- g_sci->_gfxText32->drawTextBitmap(itemEntry->object);
+ g_sci->_gfxText32->drawTextBitmap(itemEntry->x, itemEntry->y, it->planeRect, itemEntry->object);
}
}
}
diff --git a/engines/sci/graphics/frameout.h b/engines/sci/graphics/frameout.h
index 160c343b05..8c3cc261d5 100644
--- a/engines/sci/graphics/frameout.h
+++ b/engines/sci/graphics/frameout.h
@@ -94,6 +94,7 @@ public:
void kernelAddScreenItem(reg_t object);
void kernelUpdateScreenItem(reg_t object);
void kernelDeleteScreenItem(reg_t object);
+ void deletePlaneItems(reg_t planeObject);
FrameoutEntry *findScreenItem(reg_t object);
int16 kernelGetHighPlanePri();
void kernelAddPicAt(reg_t planeObj, GuiResourceId pictureId, int16 pictureX, int16 pictureY);
@@ -104,6 +105,14 @@ public:
void clear();
private:
+ void showVideo();
+ void createPlaneItemList(reg_t planeObject, FrameoutList &itemList);
+ bool isPictureOutOfView(FrameoutEntry *itemEntry, Common::Rect planeRect, int16 planeOffsetX, int16 planeOffsetY);
+ void drawPicture(FrameoutEntry *itemEntry, int16 planeOffsetX, int16 planeOffsetY, bool planePictureMirrored);
+ int16 upscaleHorizontalCoordinate(int16 coordinate);
+ int16 upscaleVerticalCoordinate(int16 coordinate);
+ Common::Rect upscaleRect(Common::Rect &rect);
+
SegManager *_segMan;
ResourceManager *_resMan;
GfxCoordAdjuster32 *_coordAdjuster;
@@ -118,8 +127,8 @@ private:
void sortPlanes();
- uint16 scriptsRunningWidth;
- uint16 scriptsRunningHeight;
+ uint16 _scriptsRunningWidth;
+ uint16 _scriptsRunningHeight;
};
} // End of namespace Sci
diff --git a/engines/sci/graphics/palette.cpp b/engines/sci/graphics/palette.cpp
index b52af38675..47d1647c6c 100644
--- a/engines/sci/graphics/palette.cpp
+++ b/engines/sci/graphics/palette.cpp
@@ -709,6 +709,13 @@ bool GfxPalette::palVaryLoadTargetPalette(GuiResourceId resourceId) {
}
void GfxPalette::palVaryInstallTimer() {
+ // Remove any possible leftover palVary timer callbacks.
+ // This happens for example in QFG1VGA, when sleeping at Erana's place
+ // (bug #3439240) - the nighttime to daytime effect clashes with the
+ // scene transition effect, as we load scene images too quickly for
+ // the SCI scripts in that case (also refer to kernelPalVaryInit).
+ palVaryRemoveTimer();
+
int16 ticks = _palVaryTicks > 0 ? _palVaryTicks : 1;
// Call signal increase every [ticks]
g_sci->getTimerManager()->installTimerProc(&palVaryCallback, 1000000 / 60 * ticks, this, "sciPalette");
@@ -966,7 +973,7 @@ void GfxPalette::loadMacIconBarPalette() {
}
bool GfxPalette::colorIsFromMacClut(byte index) {
- return index != 0 && _macClut && (_macClut[index * 3] != 0 || _macClut[index * 3 + 1] != 0 || _macClut[index * 3 + 1] != 0);
+ return index != 0 && _macClut && (_macClut[index * 3] != 0 || _macClut[index * 3 + 1] != 0 || _macClut[index * 3 + 2] != 0);
}
#ifdef ENABLE_SCI32
diff --git a/engines/sci/graphics/screen.cpp b/engines/sci/graphics/screen.cpp
index 6469bc0cb3..4020518b72 100644
--- a/engines/sci/graphics/screen.cpp
+++ b/engines/sci/graphics/screen.cpp
@@ -438,7 +438,7 @@ void GfxScreen::bitsSaveScreen(Common::Rect rect, byte *screen, uint16 screenWid
screen += (rect.top * screenWidth) + rect.left;
for (y = rect.top; y < rect.bottom; y++) {
- memcpy(memoryPtr, (void*)screen, width); memoryPtr += width;
+ memcpy(memoryPtr, (void *)screen, width); memoryPtr += width;
screen += screenWidth;
}
}
@@ -458,7 +458,7 @@ void GfxScreen::bitsSaveDisplayScreen(Common::Rect rect, byte *&memoryPtr) {
}
for (y = rect.top; y < rect.bottom; y++) {
- memcpy(memoryPtr, (void*)screen, width); memoryPtr += width;
+ memcpy(memoryPtr, (void *)screen, width); memoryPtr += width;
screen += _displayWidth;
}
}
@@ -503,7 +503,7 @@ void GfxScreen::bitsRestoreScreen(Common::Rect rect, byte *&memoryPtr, byte *scr
screen += (rect.top * screenWidth) + rect.left;
for (y = rect.top; y < rect.bottom; y++) {
- memcpy((void*) screen, memoryPtr, width); memoryPtr += width;
+ memcpy((void *) screen, memoryPtr, width); memoryPtr += width;
screen += screenWidth;
}
}
@@ -523,7 +523,7 @@ void GfxScreen::bitsRestoreDisplayScreen(Common::Rect rect, byte *&memoryPtr) {
}
for (y = rect.top; y < rect.bottom; y++) {
- memcpy((void*) screen, memoryPtr, width); memoryPtr += width;
+ memcpy((void *) screen, memoryPtr, width); memoryPtr += width;
screen += _displayWidth;
}
}
diff --git a/engines/sci/graphics/text16.cpp b/engines/sci/graphics/text16.cpp
index 84547d9828..7eaa0168b8 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(static_cast<unsigned char>(curCodeParm))) {
+ if (Common::isDigit(curCodeParm)) {
curCodeParm -= '0';
} else {
curCodeParm = -1;
diff --git a/engines/sci/graphics/text32.cpp b/engines/sci/graphics/text32.cpp
index 029030165d..7894c7109c 100644
--- a/engines/sci/graphics/text32.cpp
+++ b/engines/sci/graphics/text32.cpp
@@ -18,9 +18,6 @@
* 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://scummvm.svn.sourceforge.net/svnroot/scummvm/scummvm/trunk/engines/sci/graphics/text16.cpp $
- * $Id: text16.cpp 55178 2011-01-08 23:16:44Z thebluegr $
- *
*/
#include "common/util.h"
@@ -41,6 +38,10 @@ namespace Sci {
#define BITMAP_HEADER_SIZE 46
+#define SCI_TEXT32_ALIGNMENT_RIGHT -1
+#define SCI_TEXT32_ALIGNMENT_CENTER 1
+#define SCI_TEXT32_ALIGNMENT_LEFT 0
+
GfxText32::GfxText32(SegManager *segMan, GfxCache *fonts, GfxScreen *screen)
: _segMan(segMan), _cache(fonts), _screen(screen) {
}
@@ -48,7 +49,7 @@ GfxText32::GfxText32(SegManager *segMan, GfxCache *fonts, GfxScreen *screen)
GfxText32::~GfxText32() {
}
-reg_t GfxText32::createTextBitmap(reg_t textObject, uint16 maxWidth, uint16 maxHeight) {
+reg_t GfxText32::createTextBitmap(reg_t textObject, uint16 maxWidth, uint16 maxHeight, reg_t prevHunk) {
reg_t stringObject = readSelector(_segMan, textObject, SELECTOR(text));
// The object in the text selector of the item can be either a raw string
@@ -58,13 +59,21 @@ reg_t GfxText32::createTextBitmap(reg_t textObject, uint16 maxWidth, uint16 maxH
stringObject = readSelector(_segMan, stringObject, SELECTOR(data));
Common::String text = _segMan->getString(stringObject);
- GfxFont *font = _cache->getFont(readSelectorValue(_segMan, textObject, SELECTOR(font)));
+ // HACK: The character offsets of the up and down arrow buttons are off by one
+ // in GK1, for some unknown reason. Fix them here.
+ if (text.size() == 1 && (text[0] == 29 || text[0] == 30)) {
+ text.setChar(text[0] + 1, 0);
+ }
+ GuiResourceId fontId = readSelectorValue(_segMan, textObject, SELECTOR(font));
+ GfxFont *font = _cache->getFont(fontId);
bool dimmed = readSelectorValue(_segMan, textObject, SELECTOR(dimmed));
+ int16 alignment = readSelectorValue(_segMan, textObject, SELECTOR(mode));
uint16 foreColor = readSelectorValue(_segMan, textObject, SELECTOR(fore));
+ uint16 backColor = readSelectorValue(_segMan, textObject, SELECTOR(back));
- Common::Rect planeRect = getPlaneRect(textObject);
- uint16 width = planeRect.width() + 1;
- uint16 height = planeRect.height() + 1;
+ Common::Rect nsRect = g_sci->_gfxCompare->getNSRect(textObject);
+ uint16 width = nsRect.width() + 1;
+ uint16 height = nsRect.height() + 1;
// Limit rectangle dimensions, if requested
if (maxWidth > 0)
@@ -79,24 +88,74 @@ reg_t GfxText32::createTextBitmap(reg_t textObject, uint16 maxWidth, uint16 maxH
}
int entrySize = width * height + BITMAP_HEADER_SIZE;
- reg_t memoryId = _segMan->allocateHunkEntry("TextBitmap()", entrySize);
- writeSelector(_segMan, textObject, SELECTOR(bitmap), memoryId);
+ reg_t memoryId = NULL_REG;
+ if (prevHunk.isNull()) {
+ memoryId = _segMan->allocateHunkEntry("TextBitmap()", entrySize);
+ writeSelector(_segMan, textObject, SELECTOR(bitmap), memoryId);
+ } else {
+ memoryId = prevHunk;
+ }
byte *memoryPtr = _segMan->getHunkPointer(memoryId);
- memset(memoryPtr, 0, entrySize);
+
+ if (prevHunk.isNull())
+ memset(memoryPtr, 0, BITMAP_HEADER_SIZE);
+
byte *bitmap = memoryPtr + BITMAP_HEADER_SIZE;
+ memset(bitmap, backColor, width * height);
+
+ // Save totalWidth, totalHeight
+ WRITE_LE_UINT16(memoryPtr, width);
+ WRITE_LE_UINT16(memoryPtr + 2, height);
int16 charCount = 0;
uint16 curX = 0, curY = 0;
const char *txt = text.c_str();
+ int16 textWidth, textHeight, totalHeight = 0, offsetX = 0, offsetY = 0;
+ uint16 start = 0;
+
+ // Calculate total text height
+ while (*txt) {
+ charCount = GetLongest(txt, width, font);
+ if (charCount == 0)
+ break;
+
+ Width(txt, 0, (int16)strlen(txt), fontId, textWidth, textHeight, true);
+
+ totalHeight += textHeight;
+ txt += charCount;
+ while (*txt == ' ')
+ txt++; // skip over breaking spaces
+ }
+
+ txt = text.c_str();
+ // Draw text in buffer
while (*txt) {
charCount = GetLongest(txt, width, font);
if (charCount == 0)
break;
+ Width(txt, start, charCount, fontId, textWidth, textHeight, true);
+
+ switch (alignment) {
+ case SCI_TEXT32_ALIGNMENT_RIGHT:
+ offsetX = width - textWidth;
+ break;
+ case SCI_TEXT32_ALIGNMENT_CENTER:
+ // Center text both horizontally and vertically
+ offsetX = (width - textWidth) / 2;
+ offsetY = (height - totalHeight) / 2;
+ break;
+ case SCI_TEXT32_ALIGNMENT_LEFT:
+ offsetX = 0;
+ break;
+
+ default:
+ warning("Invalid alignment %d used in TextBox()", alignment);
+ }
for (int i = 0; i < charCount; i++) {
unsigned char curChar = txt[i];
- font->drawToBuffer(curChar, curY, curX, foreColor, dimmed, bitmap, width, height);
+ font->drawToBuffer(curChar, curY + offsetY, curX + offsetX, foreColor, dimmed, bitmap, width, height);
curX += font->getCharWidth(curChar);
}
@@ -114,13 +173,18 @@ void GfxText32::disposeTextBitmap(reg_t hunkId) {
_segMan->freeHunkEntry(hunkId);
}
-void GfxText32::drawTextBitmap(reg_t textObject) {
+void GfxText32::drawTextBitmap(int16 x, int16 y, Common::Rect planeRect, reg_t textObject) {
reg_t hunkId = readSelector(_segMan, textObject, SELECTOR(bitmap));
+ uint16 backColor = readSelectorValue(_segMan, textObject, SELECTOR(back));
// Sanity check: Check if the hunk is set. If not, either the game scripts
// didn't set it, or an old saved game has been loaded, where it wasn't set.
if (hunkId.isNull())
return;
+ // Negative coordinates indicate that text shouldn't be displayed
+ if (x < 0 || y < 0)
+ return;
+
byte *memoryPtr = _segMan->getHunkPointer(hunkId);
if (!memoryPtr)
@@ -129,46 +193,28 @@ void GfxText32::drawTextBitmap(reg_t textObject) {
byte *surface = memoryPtr + BITMAP_HEADER_SIZE;
int curByte = 0;
- Common::Rect nsRect = g_sci->_gfxCompare->getNSRect(textObject);
- Common::Rect planeRect = getPlaneRect(textObject);
- uint16 x = readSelectorValue(_segMan, textObject, SELECTOR(x));
- uint16 y = readSelectorValue(_segMan, textObject, SELECTOR(y));
+ uint16 skipColor = readSelectorValue(_segMan, textObject, SELECTOR(skip));
uint16 textX = planeRect.left + x;
uint16 textY = planeRect.top + y;
- uint16 width = nsRect.width() + 1;
- uint16 height = nsRect.height() + 1;
+ // Get totalWidth, totalHeight
+ uint16 width = READ_LE_UINT16(memoryPtr);
+ uint16 height = READ_LE_UINT16(memoryPtr + 2);
// Upscale the coordinates/width if the fonts are already upscaled
if (_screen->fontIsUpscaled()) {
textX = textX * _screen->getDisplayWidth() / _screen->getWidth();
textY = textY * _screen->getDisplayHeight() / _screen->getHeight();
- width = width * _screen->getDisplayWidth() / _screen->getWidth();
- height = height * _screen->getDisplayHeight() / _screen->getHeight();
}
for (int curY = 0; curY < height; curY++) {
for (int curX = 0; curX < width; curX++) {
byte pixel = surface[curByte++];
- if (pixel)
+ if (pixel != skipColor && pixel != backColor)
_screen->putFontPixel(textY, curX + textX, curY, pixel);
}
}
}
-Common::Rect GfxText32::getPlaneRect(reg_t textObject) {
- Common::Rect planeRect(0, 0, _screen->getWidth(), _screen->getHeight());
-
- reg_t planeObject = readSelector(_segMan, textObject, SELECTOR(plane));
- if (!planeObject.isNull()) {
- planeRect.top = readSelectorValue(_segMan, planeObject, SELECTOR(top));
- planeRect.left = readSelectorValue(_segMan, planeObject, SELECTOR(left));
- planeRect.bottom = readSelectorValue(_segMan, planeObject, SELECTOR(bottom));
- planeRect.right = readSelectorValue(_segMan, planeObject, SELECTOR(right));
- }
-
- return planeRect;
-}
-
int16 GfxText32::GetLongest(const char *text, int16 maxWidth, GfxFont *font) {
uint16 curChar = 0;
int16 maxChars = 0, curCharCount = 0;
@@ -251,6 +297,10 @@ int16 GfxText32::Size(Common::Rect &rect, const char *text, GuiResourceId fontId
int16 maxTextWidth = 0, textWidth;
int16 totalHeight = 0, textHeight;
+ // Adjust maxWidth if we're using an upscaled font
+ if (_screen->fontIsUpscaled())
+ maxWidth = maxWidth * _screen->getDisplayWidth() / _screen->getWidth();
+
rect.top = rect.left = 0;
GfxFont *font = _cache->getFont(fontId);
@@ -277,6 +327,14 @@ int16 GfxText32::Size(Common::Rect &rect, const char *text, GuiResourceId fontId
rect.bottom = totalHeight;
rect.right = maxWidth ? maxWidth : MIN(rect.right, maxTextWidth);
}
+
+ // Adjust the width/height if we're using an upscaled font
+ // for the scripts
+ if (_screen->fontIsUpscaled()) {
+ rect.right = rect.right * _screen->getWidth() / _screen->getDisplayWidth();
+ rect.bottom = rect.bottom * _screen->getHeight() / _screen->getDisplayHeight();
+ }
+
return rect.right;
}
diff --git a/engines/sci/graphics/text32.h b/engines/sci/graphics/text32.h
index dfcbf63ccf..3505de85eb 100644
--- a/engines/sci/graphics/text32.h
+++ b/engines/sci/graphics/text32.h
@@ -18,9 +18,6 @@
* 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://scummvm.svn.sourceforge.net/svnroot/scummvm/scummvm/trunk/engines/sci/graphics/text16.h $
- * $Id: text16.h 55178 2011-01-08 23:16:44Z thebluegr $
- *
*/
#ifndef SCI_GRAPHICS_TEXT32_H
@@ -35,9 +32,9 @@ class GfxText32 {
public:
GfxText32(SegManager *segMan, GfxCache *fonts, GfxScreen *screen);
~GfxText32();
- reg_t createTextBitmap(reg_t textObject, uint16 maxWidth = 0, uint16 maxHeight = 0);
+ reg_t createTextBitmap(reg_t textObject, uint16 maxWidth = 0, uint16 maxHeight = 0, reg_t prevHunk = NULL_REG);
void disposeTextBitmap(reg_t hunkId);
- void drawTextBitmap(reg_t textObject);
+ void drawTextBitmap(int16 x, int16 y, Common::Rect planeRect, reg_t textObject);
int16 GetLongest(const char *text, int16 maxWidth, GfxFont *font);
void kernelTextSize(const char *text, int16 font, int16 maxWidth, int16 *textWidth, int16 *textHeight);
@@ -46,7 +43,6 @@ private:
int16 Size(Common::Rect &rect, const char *text, GuiResourceId fontId, int16 maxWidth);
void Width(const char *text, int16 from, int16 len, GuiResourceId orgFontId, int16 &textWidth, int16 &textHeight, bool restoreFont);
void StringWidth(const char *str, GuiResourceId orgFontId, int16 &textWidth, int16 &textHeight);
- Common::Rect getPlaneRect(reg_t textObject);
SegManager *_segMan;
GfxCache *_cache;
diff --git a/engines/sci/graphics/transitions.cpp b/engines/sci/graphics/transitions.cpp
index d047eb10a1..b385c2c1db 100644
--- a/engines/sci/graphics/transitions.cpp
+++ b/engines/sci/graphics/transitions.cpp
@@ -52,8 +52,8 @@ static const GfxTransitionTranslateEntry oldTransitionIDs[] = {
{ 3, SCI_TRANSITIONS_STRAIGHT_FROM_LEFT, false },
{ 4, SCI_TRANSITIONS_STRAIGHT_FROM_BOTTOM, false },
{ 5, SCI_TRANSITIONS_STRAIGHT_FROM_TOP, false },
- { 6, SCI_TRANSITIONS_DIAGONALROLL_FROMCENTER, false },
- { 7, SCI_TRANSITIONS_DIAGONALROLL_TOCENTER, false },
+ { 6, SCI_TRANSITIONS_DIAGONALROLL_TOCENTER, false },
+ { 7, SCI_TRANSITIONS_DIAGONALROLL_FROMCENTER, false },
{ 8, SCI_TRANSITIONS_BLOCKS, false },
{ 9, SCI_TRANSITIONS_VERTICALROLL_TOCENTER, false },
{ 10, SCI_TRANSITIONS_HORIZONTALROLL_TOCENTER, false },
@@ -295,12 +295,12 @@ void GfxTransitions::fadeOut() {
int16 stepNr, colorNr;
// Sierra did not fade in/out color 255 for sci1.1, but they used it in
// several pictures (e.g. qfg3 demo/intro), so the fading looked weird
- int16 tillColorNr = getSciVersion() >= SCI_VERSION_1_1 ? 256 : 255;
+ int16 tillColorNr = getSciVersion() >= SCI_VERSION_1_1 ? 255 : 254;
g_system->getPaletteManager()->grabPalette(oldPalette, 0, 256);
for (stepNr = 100; stepNr >= 0; stepNr -= 10) {
- for (colorNr = 1; colorNr < tillColorNr; colorNr++) {
+ for (colorNr = 1; colorNr <= tillColorNr; colorNr++) {
if (_palette->colorIsFromMacClut(colorNr)) {
workPalette[colorNr * 3 + 0] = oldPalette[colorNr * 3];
workPalette[colorNr * 3 + 1] = oldPalette[colorNr * 3 + 1];
@@ -311,7 +311,7 @@ void GfxTransitions::fadeOut() {
workPalette[colorNr * 3 + 2] = oldPalette[colorNr * 3 + 2] * stepNr / 100;
}
}
- g_system->getPaletteManager()->setPalette(workPalette + 3, 1, 254);
+ g_system->getPaletteManager()->setPalette(workPalette + 3, 1, tillColorNr);
g_sci->getEngineState()->wait(2);
}
}
@@ -322,10 +322,10 @@ void GfxTransitions::fadeIn() {
int16 stepNr;
// Sierra did not fade in/out color 255 for sci1.1, but they used it in
// several pictures (e.g. qfg3 demo/intro), so the fading looked weird
- int16 tillColorNr = getSciVersion() >= SCI_VERSION_1_1 ? 256 : 255;
+ int16 tillColorNr = getSciVersion() >= SCI_VERSION_1_1 ? 255 : 254;
for (stepNr = 0; stepNr <= 100; stepNr += 10) {
- _palette->kernelSetIntensity(1, tillColorNr, stepNr, true);
+ _palette->kernelSetIntensity(1, tillColorNr + 1, stepNr, true);
g_sci->getEngineState()->wait(2);
}
}
diff --git a/engines/sci/graphics/view.cpp b/engines/sci/graphics/view.cpp
index e095cde697..a77bcccc52 100644
--- a/engines/sci/graphics/view.cpp
+++ b/engines/sci/graphics/view.cpp
@@ -432,10 +432,11 @@ void unpackCelData(byte *inBuffer, byte *celBitmap, byte clearColor, int pixelCo
// Skip the next YYYYY pixels (i.e. transparency)
if (literalPos && isMacSci11ViewData) {
- // KQ6/Freddy Pharkas use byte lengths, all others use uint16
+ // KQ6/Freddy Pharkas/Slater use byte lengths, all others use uint16
// The SCI devs must have realized that a max of 255 pixels wide
// was not very good for 320 or 640 width games.
- bool hasByteLengths = (g_sci->getGameId() == GID_KQ6 || g_sci->getGameId() == GID_FREDDYPHARKAS);
+ bool hasByteLengths = (g_sci->getGameId() == GID_KQ6 || g_sci->getGameId() == GID_FREDDYPHARKAS
+ || g_sci->getGameId() == GID_SLATER);
// compression for SCI1.1+ Mac
while (pixelNr < pixelCount) {
diff --git a/engines/sci/module.mk b/engines/sci/module.mk
index c129ae5439..90a0f33f06 100644
--- a/engines/sci/module.mk
+++ b/engines/sci/module.mk
@@ -43,7 +43,7 @@ MODULE_OBJS := \
graphics/animate.o \
graphics/cache.o \
graphics/compare.o \
- graphics/controls.o \
+ graphics/controls16.o \
graphics/coordadjuster.o \
graphics/cursor.o \
graphics/font.o \
@@ -71,6 +71,7 @@ MODULE_OBJS := \
sound/drivers/amigamac.o \
sound/drivers/cms.o \
sound/drivers/fb01.o \
+ sound/drivers/fmtowns.o \
sound/drivers/midi.o \
sound/drivers/pcjr.o \
video/seq_decoder.o
@@ -78,6 +79,7 @@ MODULE_OBJS := \
ifdef ENABLE_SCI32
MODULE_OBJS += \
+ graphics/controls32.o \
graphics/frameout.o \
graphics/paint32.o \
graphics/text32.o \
diff --git a/engines/sci/parser/said.cpp b/engines/sci/parser/said.cpp
index d44109faec..eff4a29f49 100644
--- a/engines/sci/parser/said.cpp
+++ b/engines/sci/parser/said.cpp
@@ -743,7 +743,7 @@ static void node_print_desc(ParseTreeNode* node) {
}
}
#else
-static void node_print_desc(ParseTreeNode*) { }
+static void node_print_desc(ParseTreeNode *) { }
#endif
diff --git a/engines/sci/parser/vocabulary.cpp b/engines/sci/parser/vocabulary.cpp
index a5c4686b3b..e56158ecc1 100644
--- a/engines/sci/parser/vocabulary.cpp
+++ b/engines/sci/parser/vocabulary.cpp
@@ -534,7 +534,7 @@ bool Vocabulary::tokenizeString(ResultWordListList &retval, const char *sentence
do {
c = sentence[pos_in_sentence++];
- if (isalnum(c) || (c == '-' && wordLen) || (c >= 0x80)) {
+ if (Common::isAlnum(c) || (c == '-' && wordLen) || (c >= 0x80)) {
currentWord[wordLen] = lowerCaseMap[c];
++wordLen;
}
diff --git a/engines/sci/resource.cpp b/engines/sci/resource.cpp
index c50d1b8d8a..77a6a40a92 100644
--- a/engines/sci/resource.cpp
+++ b/engines/sci/resource.cpp
@@ -169,8 +169,11 @@ ResourceType ResourceManager::convertResType(byte type) {
if (type < ARRAYSIZE(s_resTypeMapSci21)) {
// LSL6 hires doesn't have the chunk resource type, to match
// the resource types of the lowres version, thus we use the
- // older resource types here
- if (g_sci && g_sci->getGameId() == GID_LSL6HIRES)
+ // older resource types here.
+ // PQ4 CD and QFG4 CD are SCI2.1, but use the resource types of the
+ // corresponding SCI2 floppy disk versions.
+ if (g_sci && (g_sci->getGameId() == GID_LSL6HIRES ||
+ g_sci->getGameId() == GID_QFG4 || g_sci->getGameId() == GID_PQ4))
return s_resTypeMapSci0[type];
else
return s_resTypeMapSci21[type];
@@ -606,7 +609,7 @@ int ResourceManager::addAppropriateSources() {
if (Common::File::exists("alt.map") && Common::File::exists("resource.alt"))
addSource(new VolumeResourceSource("resource.alt", addExternalMap("alt.map", 10), 10));
#endif
- } else if (Common::File::exists("Data1")) {
+ } else if (Common::MacResManager::exists("Data1")) {
// Mac SCI1.1+ file naming scheme
SearchMan.listMatchingMembers(files, "Data?*");
@@ -750,12 +753,10 @@ void ResourceManager::addScriptChunkSources() {
// to try to get to any scripts in there. The Lighthouse SCI2.1 demo
// does exactly this.
- Common::List<ResourceId> *resources = listResources(kResourceTypeScript);
+ Common::List<ResourceId> resources = listResources(kResourceTypeScript);
- if (resources->empty() && testResource(ResourceId(kResourceTypeChunk, 0)))
+ if (resources.empty() && testResource(ResourceId(kResourceTypeChunk, 0)))
addResourcesFromChunk(0);
-
- delete resources;
}
#endif
}
@@ -1042,13 +1043,13 @@ void ResourceManager::freeOldResources() {
}
}
-Common::List<ResourceId> *ResourceManager::listResources(ResourceType type, int mapNumber) {
- Common::List<ResourceId> *resources = new Common::List<ResourceId>;
+Common::List<ResourceId> ResourceManager::listResources(ResourceType type, int mapNumber) {
+ Common::List<ResourceId> resources;
ResourceMap::iterator itr = _resMap.begin();
while (itr != _resMap.end()) {
if ((itr->_value->getType() == type) && ((mapNumber == -1) || (itr->_value->getNumber() == mapNumber)))
- resources->push_back(itr->_value->_id);
+ resources.push_back(itr->_value->_id);
++itr;
}
@@ -1557,7 +1558,7 @@ void ResourceManager::readResourcePatches() {
name = (*x)->getName();
// SCI1 scheme
- if (isdigit(static_cast<unsigned char>(name[0]))) {
+ if (Common::isDigit(name[0])) {
char *end = 0;
resourceNr = strtol(name.c_str(), &end, 10);
bAdd = (*end == '.'); // Ensure the next character is the period
@@ -1565,7 +1566,7 @@ void ResourceManager::readResourcePatches() {
// SCI0 scheme
int resname_len = strlen(szResType);
if (scumm_strnicmp(name.c_str(), szResType, resname_len) == 0
- && !isalpha(static_cast<unsigned char>(name[resname_len + 1]))) {
+ && !Common::isAlpha(name[resname_len + 1])) {
resourceNr = atoi(name.c_str() + resname_len + 1);
bAdd = true;
}
@@ -2196,14 +2197,16 @@ void ResourceManager::detectSciVersion() {
// Handle SCI32 versions here
if (_volVersion >= kResVersionSci2) {
- Common::List<ResourceId> *heaps = listResources(kResourceTypeHeap);
+ Common::List<ResourceId> heaps = listResources(kResourceTypeHeap);
+ bool hasHeapResources = !heaps.empty();
+
// SCI2.1/3 and SCI1 Late resource maps are the same, except that
// SCI1 Late resource maps have the resource types or'd with
// 0x80. We differentiate between SCI2 and SCI2.1/3 based on that.
if (_mapVersion == kResVersionSci1Late) {
s_sciVersion = SCI_VERSION_2;
return;
- } else if (!heaps->empty()) {
+ } else if (hasHeapResources) {
s_sciVersion = SCI_VERSION_2_1;
return;
} else {
diff --git a/engines/sci/resource.h b/engines/sci/resource.h
index 47602de017..294a4672e2 100644
--- a/engines/sci/resource.h
+++ b/engines/sci/resource.h
@@ -322,7 +322,7 @@ public:
* @param mapNumber For audio36 and sync36, limit search to this map
* @return The resource list
*/
- Common::List<ResourceId> *listResources(ResourceType type, int mapNumber = -1);
+ Common::List<ResourceId> listResources(ResourceType type, int mapNumber = -1);
void setAudioLanguage(int language);
int getAudioLanguage() const;
diff --git a/engines/sci/resource_audio.cpp b/engines/sci/resource_audio.cpp
index f3a3c8dd5b..684e1a1d0d 100644
--- a/engines/sci/resource_audio.cpp
+++ b/engines/sci/resource_audio.cpp
@@ -185,6 +185,7 @@ void ResourceManager::processWavePatch(ResourceId resourceId, Common::String nam
file.open(name);
updateResource(resourceId, resSrc, file.size());
+ _sources.push_back(resSrc);
debugC(1, kDebugLevelResMan, "Patching %s - OK", name.c_str());
}
@@ -197,7 +198,7 @@ void ResourceManager::readWaveAudioPatches() {
for (Common::ArchiveMemberList::const_iterator x = files.begin(); x != files.end(); ++x) {
Common::String name = (*x)->getName();
- if (isdigit(static_cast<unsigned char>(name[0])))
+ if (Common::isDigit(name[0]))
processWavePatch(ResourceId(kResourceTypeAudio, atoi(name.c_str())), name);
}
}
@@ -538,11 +539,10 @@ bool ResourceManager::isGMTrackIncluded() {
// Read the first song and check if it has a GM track
bool result = false;
- Common::List<ResourceId> *resources = listResources(kResourceTypeSound, -1);
- Common::sort(resources->begin(), resources->end());
- Common::List<ResourceId>::iterator itr = resources->begin();
+ Common::List<ResourceId> resources = listResources(kResourceTypeSound, -1);
+ Common::sort(resources.begin(), resources.end());
+ Common::List<ResourceId>::iterator itr = resources.begin();
int firstSongId = itr->getNumber();
- delete resources;
SoundResource *song1 = new SoundResource(firstSongId, this, soundVersion);
if (!song1) {
@@ -892,10 +892,10 @@ void AudioVolumeResourceSource::loadResource(ResourceManager *resMan, Resource *
}
bool ResourceManager::addAudioSources() {
- Common::List<ResourceId> *resources = listResources(kResourceTypeMap);
- Common::List<ResourceId>::iterator itr = resources->begin();
+ Common::List<ResourceId> resources = listResources(kResourceTypeMap);
+ Common::List<ResourceId>::iterator itr;
- while (itr != resources->end()) {
+ for (itr = resources.begin(); itr != resources.end(); ++itr) {
ResourceSource *src = addSource(new IntMapResourceSource("MAP", itr->getNumber()));
if ((itr->getNumber() == 65535) && Common::File::exists("RESOURCE.SFX"))
@@ -904,29 +904,30 @@ bool ResourceManager::addAudioSources() {
addSource(new AudioVolumeResourceSource(this, "RESOURCE.AUD", src, 0));
else
return false;
-
- ++itr;
}
- delete resources;
-
return true;
}
void ResourceManager::changeAudioDirectory(Common::String path) {
// Remove all of the audio map resource sources, as well as the audio resource sources
- for (Common::List<ResourceSource *>::iterator it = _sources.begin(); it != _sources.end(); ++it) {
+ for (Common::List<ResourceSource *>::iterator it = _sources.begin(); it != _sources.end();) {
ResourceSource *source = *it;
ResSourceType sourceType = source->getSourceType();
// Remove the resource source, if it's an audio map or an audio file
if (sourceType == kSourceIntMap || sourceType == kSourceAudioVolume) {
// Don't remove 65535.map (the SFX map) or resource.sfx
- if (source->_volumeNumber == 65535 || source->getLocationName() == "RESOURCE.SFX")
+ if (source->_volumeNumber == 65535 || source->getLocationName() == "RESOURCE.SFX") {
+ ++it;
continue;
+ }
+ // erase() will move the iterator to the next element
it = _sources.erase(it);
delete source;
+ } else {
+ ++it;
}
}
@@ -938,8 +939,9 @@ void ResourceManager::changeAudioDirectory(Common::String path) {
audioResourceName = Common::String::format("%s/RESOURCE.AUD", path.c_str());
}
- Common::List<ResourceId> *resources = listResources(kResourceTypeMap);
- for (Common::List<ResourceId>::iterator it = resources->begin(); it != resources->end(); ++it) {
+ Common::List<ResourceId> resources = listResources(kResourceTypeMap);
+ Common::List<ResourceId>::iterator it;
+ for (it = resources.begin(); it != resources.end(); ++it) {
// Don't readd 65535.map or resource.sfx
if ((it->getNumber() == 65535))
continue;
@@ -948,8 +950,6 @@ void ResourceManager::changeAudioDirectory(Common::String path) {
addSource(new AudioVolumeResourceSource(this, audioResourceName, src, 0));
}
- delete resources;
-
// Rescan the newly added resources
scanNewSources();
}
diff --git a/engines/sci/sci.cpp b/engines/sci/sci.cpp
index 1d0d63870d..4ae55cbcba 100644
--- a/engines/sci/sci.cpp
+++ b/engines/sci/sci.cpp
@@ -46,7 +46,8 @@
#include "sci/graphics/animate.h"
#include "sci/graphics/cache.h"
#include "sci/graphics/compare.h"
-#include "sci/graphics/controls.h"
+#include "sci/graphics/controls16.h"
+#include "sci/graphics/controls32.h"
#include "sci/graphics/coordadjuster.h"
#include "sci/graphics/cursor.h"
#include "sci/graphics/maciconbar.h"
@@ -90,6 +91,7 @@ SciEngine::SciEngine(OSystem *syst, const ADGameDescription *desc, SciGameId gam
_vocabularyLanguage = 1; // we load english vocabulary on startup
_eventMan = 0;
_console = 0;
+ _opcode_formats = 0;
// Set up the engine specific debug levels
DebugMan.addDebugChannel(kDebugLevelError, "Error", "Script error debugging");
@@ -113,6 +115,7 @@ SciEngine::SciEngine(OSystem *syst, const ADGameDescription *desc, SciGameId gam
DebugMan.addDebugChannel(kDebugLevelGC, "GC", "Garbage Collector debugging");
DebugMan.addDebugChannel(kDebugLevelResMan, "ResMan", "Resource manager debugging");
DebugMan.addDebugChannel(kDebugLevelOnStartup, "OnStartup", "Enter debugger at start of game");
+ DebugMan.addDebugChannel(kDebugLevelDebugMode, "DebugMode", "Enable game debug mode at start of game");
const Common::FSNode gameDataDir(ConfMan.get("path"));
@@ -147,12 +150,13 @@ SciEngine::~SciEngine() {
DebugMan.clearAllDebugChannels();
#ifdef ENABLE_SCI32
+ delete _gfxControls32;
delete _gfxText32;
delete _robotDecoder;
delete _gfxFrameout;
#endif
delete _gfxMenu;
- delete _gfxControls;
+ delete _gfxControls16;
delete _gfxText16;
delete _gfxAnimate;
delete _gfxPaint;
@@ -176,6 +180,9 @@ SciEngine::~SciEngine() {
delete _eventMan;
delete _gamestate->_segMan;
delete _gamestate;
+
+ delete[] _opcode_formats;
+
delete _resMan; // should be deleted last
g_sci = 0;
}
@@ -187,6 +194,7 @@ Common::Error SciEngine::run() {
ConfMan.registerDefault("sci_originalsaveload", "false");
ConfMan.registerDefault("native_fb01", "false");
ConfMan.registerDefault("windows_cursors", "false"); // Windows cursors for KQ6 Windows
+ ConfMan.registerDefault("silver_cursors", "false"); // Silver cursors for SQ4 CD
_resMan = new ResourceManager();
assert(_resMan);
@@ -588,7 +596,7 @@ void SciEngine::initGraphics() {
_gfxAnimate = 0;
_gfxCache = 0;
_gfxCompare = 0;
- _gfxControls = 0;
+ _gfxControls16 = 0;
_gfxCoordAdjuster = 0;
_gfxCursor = 0;
_gfxMacIconBar = 0;
@@ -600,6 +608,7 @@ void SciEngine::initGraphics() {
_gfxText16 = 0;
_gfxTransitions = 0;
#ifdef ENABLE_SCI32
+ _gfxControls32 = 0;
_gfxText32 = 0;
_robotDecoder = 0;
_gfxFrameout = 0;
@@ -622,6 +631,7 @@ void SciEngine::initGraphics() {
_gfxPaint32 = new GfxPaint32(_resMan, _gamestate->_segMan, _kernel, _gfxCoordAdjuster, _gfxCache, _gfxScreen, _gfxPalette);
_gfxPaint = _gfxPaint32;
_gfxText32 = new GfxText32(_gamestate->_segMan, _gfxCache, _gfxScreen);
+ _gfxControls32 = new GfxControls32(_gamestate->_segMan, _gfxCache, _gfxScreen, _gfxText32);
_robotDecoder = new RobotDecoder(g_system->getMixer(), getPlatform() == Common::kPlatformMacintosh);
_gfxFrameout = new GfxFrameout(_gamestate->_segMan, _resMan, _gfxCoordAdjuster, _gfxCache, _gfxScreen, _gfxPalette, _gfxPaint32);
} else {
@@ -636,7 +646,7 @@ void SciEngine::initGraphics() {
_gfxPaint = _gfxPaint16;
_gfxAnimate = new GfxAnimate(_gamestate, _gfxCache, _gfxPorts, _gfxPaint16, _gfxScreen, _gfxPalette, _gfxCursor, _gfxTransitions);
_gfxText16 = new GfxText16(_resMan, _gfxCache, _gfxPorts, _gfxPaint16, _gfxScreen);
- _gfxControls = new GfxControls(_gamestate->_segMan, _gfxPorts, _gfxPaint16, _gfxText16, _gfxScreen);
+ _gfxControls16 = new GfxControls16(_gamestate->_segMan, _gfxPorts, _gfxPaint16, _gfxText16, _gfxScreen);
_gfxMenu = new GfxMenu(_eventMan, _gamestate->_segMan, _gfxPorts, _gfxPaint16, _gfxText16, _gfxScreen, _gfxCursor);
_gfxMenu->reset();
diff --git a/engines/sci/sci.h b/engines/sci/sci.h
index 81bbdc51de..9f18219cb7 100644
--- a/engines/sci/sci.h
+++ b/engines/sci/sci.h
@@ -59,7 +59,8 @@ class SegManager;
class GfxAnimate;
class GfxCache;
class GfxCompare;
-class GfxControls;
+class GfxControls16;
+class GfxControls32;
class GfxCoordAdjuster;
class GfxCursor;
class GfxMacIconBar;
@@ -101,7 +102,8 @@ enum kDebugLevels {
kDebugLevelScripts = 1 << 17,
kDebugLevelGC = 1 << 18,
kDebugLevelResMan = 1 << 19,
- kDebugLevelOnStartup = 1 << 20
+ kDebugLevelOnStartup = 1 << 20,
+ kDebugLevelDebugMode = 1 << 21
};
enum SciGameId {
@@ -303,7 +305,8 @@ public:
GfxAnimate *_gfxAnimate; // Animate for 16-bit gfx
GfxCache *_gfxCache;
GfxCompare *_gfxCompare;
- GfxControls *_gfxControls; // Controls for 16-bit gfx
+ GfxControls16 *_gfxControls16; // Controls for 16-bit gfx
+ GfxControls32 *_gfxControls32; // Controls for 32-bit gfx
GfxCoordAdjuster *_gfxCoordAdjuster;
GfxCursor *_gfxCursor;
GfxMenu *_gfxMenu; // Menu for 16-bit gfx
@@ -327,6 +330,8 @@ public:
SoundCommandParser *_soundCmd;
GameFeatures *_features;
+ opcode_format (*_opcode_formats)[4];
+
DebugState _debugState;
Common::MacResManager *getMacExecutable() { return &_macExecutable; }
diff --git a/engines/sci/sound/drivers/adlib.cpp b/engines/sci/sound/drivers/adlib.cpp
index add3d8851f..db9317e071 100644
--- a/engines/sci/sound/drivers/adlib.cpp
+++ b/engines/sci/sound/drivers/adlib.cpp
@@ -613,8 +613,6 @@ void MidiDriver_AdLib::setNote(int voice, int note, bool key) {
_voices[voice].note = note;
- delta = 0;
-
n = note % 12;
if (bend < 8192)
diff --git a/engines/sci/sound/drivers/amigamac.cpp b/engines/sci/sound/drivers/amigamac.cpp
index 3c750401b9..131a85f371 100644
--- a/engines/sci/sound/drivers/amigamac.cpp
+++ b/engines/sci/sound/drivers/amigamac.cpp
@@ -130,7 +130,7 @@ private:
};
bool _isSci1;
- bool _isSci1Early; // KQ1 Amiga, patch 5
+ bool _isSci1Early; // KQ1/MUMG Amiga, patch 5
bool _playSwitch;
int _masterVolume;
int _frequency;
@@ -524,7 +524,7 @@ MidiDriver_AmigaMac::InstrumentSample *MidiDriver_AmigaMac::readInstrumentSCI0(C
instrument->size = seg_size[0];
instrument->loop_size = seg_size[1];
- instrument->loop = (int8*)malloc(instrument->loop_size + 1);
+ instrument->loop = (int8 *)malloc(instrument->loop_size + 1);
memcpy(instrument->loop, instrument->samples + loop_offset, instrument->loop_size);
instrument->samples[instrument->size] = instrument->loop[0];
@@ -586,12 +586,12 @@ int MidiDriver_AmigaMac::open() {
} else {
ResourceManager *resMan = g_sci->getResMan();
- Resource *resource = resMan->findResource(ResourceId(kResourceTypePatch, 7), false); // Mac
+ Resource *resource = resMan->findResource(ResourceId(kResourceTypePatch, 7), false); // Mac
if (!resource)
- resource = resMan->findResource(ResourceId(kResourceTypePatch, 9), false); // Amiga
+ resource = resMan->findResource(ResourceId(kResourceTypePatch, 9), false); // Amiga
if (!resource) {
- resource = resMan->findResource(ResourceId(kResourceTypePatch, 5), false); // KQ1 Amiga
+ resource = resMan->findResource(ResourceId(kResourceTypePatch, 5), false); // KQ1/MUMG Amiga
if (resource)
_isSci1Early = true;
}
@@ -708,7 +708,7 @@ void MidiDriver_AmigaMac::generateSamples(int16 *data, int len) {
if (len == 0)
return;
- int16 *buffers = (int16*)malloc(len * 2 * kChannels);
+ int16 *buffers = (int16 *)malloc(len * 2 * kChannels);
memset(buffers, 0, len * 2 * kChannels);
@@ -869,7 +869,7 @@ bool MidiDriver_AmigaMac::loadInstrumentsSCI0Mac(Common::SeekableReadStream &fil
instrument->size = seg_size[0];
instrument->loop_size = seg_size[1] - seg_size[0];
- instrument->loop = (int8*)malloc(instrument->loop_size + 1);
+ instrument->loop = (int8 *)malloc(instrument->loop_size + 1);
memcpy(instrument->loop, instrument->samples + loop_offset, instrument->loop_size);
instrument->samples[instrument->size] = instrument->loop[0];
@@ -892,7 +892,7 @@ bool MidiDriver_AmigaMac::loadInstrumentsSCI1(Common::SeekableReadStream &file)
_bank.size = 128;
if (_isSci1Early)
- file.skip(4); // TODO: What is this offset for?
+ file.readUint32BE(); // Skip size of bank
Common::Array<uint32> instrumentOffsets;
instrumentOffsets.resize(_bank.size);
@@ -911,12 +911,6 @@ bool MidiDriver_AmigaMac::loadInstrumentsSCI1(Common::SeekableReadStream &file)
// Read in the instrument name
file.read(_bank.instruments[i].name, 10); // last two bytes are always 0
- // TODO: Finish off support of SCI1 early patches (patch.005 - KQ1 Amiga)
- if (_isSci1Early) {
- warning("Music patch 5 isn't supported yet - ignoring instrument %d", i);
- continue;
- }
-
for (uint32 j = 0; ; j++) {
InstrumentSample *sample = new InstrumentSample;
memset(sample, 0, sizeof(InstrumentSample));
@@ -943,16 +937,30 @@ bool MidiDriver_AmigaMac::loadInstrumentsSCI1(Common::SeekableReadStream &file)
int16 loop = file.readSint16BE();
uint32 nextSamplePos = file.pos();
- file.seek(samplePtr);
+ file.seek(samplePtr + (_isSci1Early ? 4 : 0));
file.read(sample->name, 8);
- sample->isUnsigned = file.readUint16BE() == 0;
- uint16 phase1Offset = file.readUint16BE();
- uint16 phase1End = file.readUint16BE();
- uint16 phase2Offset = file.readUint16BE();
- uint16 phase2End = file.readUint16BE();
- sample->baseNote = file.readUint16BE();
- uint32 periodTableOffset = file.readUint32BE();
+ uint16 phase1Offset, phase1End;
+ uint16 phase2Offset, phase2End;
+
+ if (_isSci1Early) {
+ sample->isUnsigned = false;
+ file.readUint32BE(); // skip total sample size
+ phase2Offset = file.readUint16BE();
+ phase2End = file.readUint16BE();
+ sample->baseNote = file.readUint16BE();
+ phase1Offset = file.readUint16BE();
+ phase1End = file.readUint16BE();
+ } else {
+ sample->isUnsigned = file.readUint16BE() == 0;
+ phase1Offset = file.readUint16BE();
+ phase1End = file.readUint16BE();
+ phase2Offset = file.readUint16BE();
+ phase2End = file.readUint16BE();
+ sample->baseNote = file.readUint16BE();
+ }
+
+ uint32 periodTableOffset = _isSci1Early ? 0 : file.readUint32BE();
uint32 sampleDataPos = file.pos();
sample->size = phase1End - phase1Offset + 1;
@@ -974,8 +982,13 @@ bool MidiDriver_AmigaMac::loadInstrumentsSCI1(Common::SeekableReadStream &file)
_bank.instruments[i].push_back(sample);
- file.seek(periodTableOffset + 0xe0);
- sample->baseFreq = file.readUint16BE();
+ if (_isSci1Early) {
+ // There's no frequency specified by the sample and is hardcoded like in SCI0
+ sample->baseFreq = 11000;
+ } else {
+ file.seek(periodTableOffset + 0xe0);
+ sample->baseFreq = file.readUint16BE();
+ }
file.seek(nextSamplePos);
}
diff --git a/engines/sci/sound/drivers/fmtowns.cpp b/engines/sci/sound/drivers/fmtowns.cpp
new file mode 100644
index 0000000000..6d8bb2e525
--- /dev/null
+++ b/engines/sci/sound/drivers/fmtowns.cpp
@@ -0,0 +1,652 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "sci/sci.h"
+
+#include "common/file.h"
+#include "common/system.h"
+#include "common/textconsole.h"
+
+#include "audio/softsynth/fmtowns_pc98/towns_audio.h"
+
+#include "sci/resource.h"
+#include "sci/sound/drivers/mididriver.h"
+
+namespace Sci {
+
+class MidiDriver_FMTowns;
+
+class TownsChannel {
+public:
+ TownsChannel(MidiDriver_FMTowns *driver, uint8 id);
+ ~TownsChannel() {}
+
+ void noteOff();
+ void noteOn(uint8 note, uint8 velo);
+ void pitchBend(int16 val);
+ void updateVolume();
+ void updateDuration();
+
+ uint8 _assign;
+ uint8 _note;
+ uint8 _sustain;
+ uint16 _duration;
+
+private:
+ uint8 _id;
+ uint8 _velo;
+ uint8 _program;
+
+ MidiDriver_FMTowns *_drv;
+};
+
+class TownsMidiPart {
+friend class MidiDriver_FMTowns;
+public:
+ TownsMidiPart(MidiDriver_FMTowns *driver, uint8 id);
+ ~TownsMidiPart() {}
+
+ void noteOff(uint8 note);
+ void noteOn(uint8 note, uint8 velo);
+ void controlChangeVolume(uint8 vol);
+ void controlChangeSustain(uint8 sus);
+ void controlChangePolyphony(uint8 numChan);
+ void controlChangeAllNotesOff();
+ void programChange(uint8 prg);
+ void pitchBend(int16 val);
+
+ void addChannels(int num);
+ void dropChannels(int num);
+
+ uint8 currentProgram() const;
+
+private:
+ int allocateChannel();
+
+ uint8 _id;
+ uint8 _program;
+ uint8 _volume;
+ uint8 _sustain;
+ uint8 _chanMissing;
+ int16 _pitchBend;
+ uint8 _outChan;
+
+ MidiDriver_FMTowns *_drv;
+};
+
+class MidiDriver_FMTowns : public MidiDriver, public TownsAudioInterfacePluginDriver {
+friend class TownsChannel;
+friend class TownsMidiPart;
+public:
+ MidiDriver_FMTowns(Audio::Mixer *mixer, SciVersion version);
+ ~MidiDriver_FMTowns();
+
+ int open();
+ void loadInstruments(const uint8 *data);
+ bool isOpen() const { return _isOpen; }
+ void close();
+
+ void send(uint32 b);
+
+ uint32 property(int prop, uint32 param);
+ void setTimerCallback(void *timer_param, Common::TimerManager::TimerProc timer_proc);
+
+ void setSoundOn(bool toggle);
+
+ uint32 getBaseTempo();
+ MidiChannel *allocateChannel() { return 0; }
+ MidiChannel *getPercussionChannel() { return 0; }
+
+ uint8 currentProgram();
+
+ void timerCallback(int timerId);
+
+private:
+ int getChannelVolume(uint8 midiPart);
+ void addMissingChannels();
+
+ void updateParser();
+ void updateChannels();
+
+ Common::TimerManager::TimerProc _timerProc;
+ void *_timerProcPara;
+
+ TownsMidiPart **_parts;
+ TownsChannel **_out;
+
+ uint8 _masterVolume;
+
+ bool _soundOn;
+
+ bool _isOpen;
+ bool _ready;
+
+ const uint16 _baseTempo;
+ SciVersion _version;
+
+ TownsAudioInterface *_intf;
+};
+
+class MidiPlayer_FMTowns : public MidiPlayer {
+public:
+ MidiPlayer_FMTowns(SciVersion version);
+ ~MidiPlayer_FMTowns();
+
+ int open(ResourceManager *resMan);
+
+ bool hasRhythmChannel() const;
+ byte getPlayId() const;
+ int getPolyphony() const;
+ void playSwitch(bool play);
+
+private:
+ MidiDriver_FMTowns *_townsDriver;
+};
+
+TownsChannel::TownsChannel(MidiDriver_FMTowns *driver, uint8 id) : _drv(driver), _id(id), _assign(0xff), _note(0xff), _velo(0), _sustain(0), _duration(0), _program(0xff) {
+}
+
+void TownsChannel::noteOn(uint8 note, uint8 velo) {
+ _duration = 0;
+
+ if (_drv->_version != SCI_VERSION_1_EARLY) {
+ if (_program != _drv->_parts[_assign]->currentProgram() && _drv->_soundOn) {
+ _program = _drv->_parts[_assign]->currentProgram();
+ _drv->_intf->callback(4, _id, _program);
+ }
+ }
+
+ _note = note;
+ _velo = velo;
+ _drv->_intf->callback(1, _id, _note, _velo);
+}
+
+void TownsChannel::noteOff() {
+ if (_sustain)
+ return;
+
+ _drv->_intf->callback(2, _id);
+ _note = 0xff;
+ _duration = 0;
+}
+
+void TownsChannel::pitchBend(int16 val) {
+ _drv->_intf->callback(7, _id, val);
+}
+
+void TownsChannel::updateVolume() {
+ if (_assign > 15 && _drv->_version != SCI_VERSION_1_EARLY)
+ return;
+ _drv->_intf->callback(8, _id, _drv->getChannelVolume((_drv->_version == SCI_VERSION_1_EARLY) ? 0 : _assign));
+}
+
+void TownsChannel::updateDuration() {
+ if (_note != 0xff)
+ _duration++;
+}
+
+TownsMidiPart::TownsMidiPart(MidiDriver_FMTowns *driver, uint8 id) : _drv(driver), _id(id), _program(0), _volume(0x3f), _sustain(0), _chanMissing(0), _pitchBend(0x2000), _outChan(0) {
+}
+
+void TownsMidiPart::noteOff(uint8 note) {
+ for (int i = 0; i < 6; i++) {
+ if ((_drv->_out[i]->_assign != _id && _drv->_version != SCI_VERSION_1_EARLY) || _drv->_out[i]->_note != note)
+ continue;
+ if (_sustain)
+ _drv->_out[i]->_sustain = 1;
+ else
+ _drv->_out[i]->noteOff();
+ return;
+ }
+}
+
+void TownsMidiPart::noteOn(uint8 note, uint8 velo) {
+ if (note < 12 || note > 107)
+ return;
+
+ if (velo == 0) {
+ noteOff(note);
+ return;
+ }
+
+ if (_drv->_version != SCI_VERSION_1_EARLY)
+ velo >>= 1;
+
+ for (int i = 0; i < 6; i++) {
+ if ((_drv->_out[i]->_assign != _id && _drv->_version != SCI_VERSION_1_EARLY) || _drv->_out[i]->_note != note)
+ continue;
+ _drv->_out[i]->_sustain = 0;
+ _drv->_out[i]->noteOff();
+ _drv->_out[i]->noteOn(note, velo);
+ return;
+ }
+
+ int chan = allocateChannel();
+ if (chan != -1)
+ _drv->_out[chan]->noteOn(note, velo);
+}
+
+void TownsMidiPart::controlChangeVolume(uint8 vol) {
+ if (_drv->_version == SCI_VERSION_1_EARLY)
+ return;
+
+ _volume = vol >> 1;
+ for (int i = 0; i < 6; i++) {
+ if (_drv->_out[i]->_assign == _id)
+ _drv->_out[i]->updateVolume();
+ }
+}
+
+void TownsMidiPart::controlChangeSustain(uint8 sus) {
+ if (_drv->_version == SCI_VERSION_1_EARLY)
+ return;
+
+ _sustain = sus;
+ if (_sustain)
+ return;
+
+ for (int i = 0; i < 6; i++) {
+ if (_drv->_out[i]->_assign == _id && _drv->_out[i]->_sustain) {
+ _drv->_out[i]->_sustain = 0;
+ _drv->_out[i]->noteOff();
+ }
+ }
+}
+
+void TownsMidiPart::controlChangePolyphony(uint8 numChan) {
+ if (_drv->_version == SCI_VERSION_1_EARLY)
+ return;
+
+ uint8 numAssigned = 0;
+ for (int i = 0; i < 6; i++) {
+ if (_drv->_out[i]->_assign == _id)
+ numAssigned++;
+ }
+
+ numAssigned += _chanMissing;
+ if (numAssigned < numChan) {
+ addChannels(numChan - numAssigned);
+ } else if (numAssigned > numChan) {
+ dropChannels(numAssigned - numChan);
+ _drv->addMissingChannels();
+ }
+}
+
+void TownsMidiPart::controlChangeAllNotesOff() {
+ for (int i = 0; i < 6; i++) {
+ if ((_drv->_out[i]->_assign == _id || _drv->_version == SCI_VERSION_1_EARLY) && _drv->_out[i]->_note != 0xff)
+ _drv->_out[i]->noteOff();
+ }
+}
+
+void TownsMidiPart::programChange(uint8 prg) {
+ _program = prg;
+}
+
+void TownsMidiPart::pitchBend(int16 val) {
+ _pitchBend = val;
+ val -= 0x2000;
+ for (int i = 0; i < 6; i++) {
+ // Strangely, the early version driver applies the setting to channel 0 only.
+ if (_drv->_out[i]->_assign == _id || (_drv->_version == SCI_VERSION_1_EARLY && i == 0))
+ _drv->_out[i]->pitchBend(val);
+ }
+}
+
+void TownsMidiPart::addChannels(int num) {
+ for (int i = 0; i < 6; i++) {
+ if (_drv->_out[i]->_assign != 0xff)
+ continue;
+
+ _drv->_out[i]->_assign = _id;
+ _drv->_out[i]->updateVolume();
+
+ if (_drv->_out[i]->_note != 0xff)
+ _drv->_out[i]->noteOff();
+
+ if (!--num)
+ break;
+ }
+
+ _chanMissing += num;
+ programChange(_program);
+}
+
+void TownsMidiPart::dropChannels(int num) {
+ if (_chanMissing == num) {
+ _chanMissing = 0;
+ return;
+ } else if (_chanMissing > num) {
+ _chanMissing -= num;
+ return;
+ }
+
+ num -= _chanMissing;
+ _chanMissing = 0;
+
+ for (int i = 0; i < 6; i++) {
+ if (_drv->_out[i]->_assign != _id || _drv->_out[i]->_note != 0xff)
+ continue;
+ _drv->_out[i]->_assign = 0xff;
+ if (!--num)
+ return;
+ }
+
+ for (int i = 0; i < 6; i++) {
+ if (_drv->_out[i]->_assign != _id)
+ continue;
+ _drv->_out[i]->_sustain = 0;
+ _drv->_out[i]->noteOff();
+ _drv->_out[i]->_assign = 0xff;
+ if (!--num)
+ return;
+ }
+}
+
+uint8 TownsMidiPart::currentProgram() const {
+ return _program;
+}
+
+int TownsMidiPart::allocateChannel() {
+ int chan = _outChan;
+ int ovrChan = 0;
+ int ld = 0;
+ bool found = false;
+
+ for (bool loop = true; loop; ) {
+ if (++chan == 6)
+ chan = 0;
+
+ if (chan == _outChan)
+ loop = false;
+
+ if (_id == _drv->_out[chan]->_assign || _drv->_version == SCI_VERSION_1_EARLY) {
+ if (_drv->_out[chan]->_note == 0xff) {
+ found = true;
+ break;
+ }
+
+ if (_drv->_out[chan]->_duration >= ld) {
+ ld = _drv->_out[chan]->_duration;
+ ovrChan = chan;
+ }
+ }
+ }
+
+ if (!found) {
+ if (!ld)
+ return -1;
+ chan = ovrChan;
+ _drv->_out[chan]->_sustain = 0;
+ _drv->_out[chan]->noteOff();
+ }
+
+ _outChan = chan;
+ return chan;
+}
+
+MidiDriver_FMTowns::MidiDriver_FMTowns(Audio::Mixer *mixer, SciVersion version) : _version(version), _timerProc(0), _timerProcPara(0), _baseTempo(10080), _ready(false), _isOpen(false), _masterVolume(0x0f), _soundOn(true) {
+ _intf = new TownsAudioInterface(mixer, this, true);
+ _out = new TownsChannel*[6];
+ for (int i = 0; i < 6; i++)
+ _out[i] = new TownsChannel(this, i);
+ _parts = new TownsMidiPart*[16];
+ for (int i = 0; i < 16; i++)
+ _parts[i] = new TownsMidiPart(this, i);
+}
+
+MidiDriver_FMTowns::~MidiDriver_FMTowns() {
+ delete _intf;
+
+ if (_parts) {
+ for (int i = 0; i < 16; i++) {
+ delete _parts[i];
+ _parts[i] = 0;
+ }
+ delete[] _parts;
+ _parts = 0;
+ }
+
+ if (_out) {
+ for (int i = 0; i < 6; i++) {
+ delete _out[i];
+ _out[i] = 0;
+ }
+ delete[] _out;
+ _out = 0;
+ }
+}
+
+int MidiDriver_FMTowns::open() {
+ if (_isOpen)
+ return MERR_ALREADY_OPEN;
+
+ if (!_ready) {
+ if (!_intf->init())
+ return MERR_CANNOT_CONNECT;
+
+ _intf->callback(0);
+
+ _intf->callback(21, 255, 1);
+ _intf->callback(21, 0, 1);
+ _intf->callback(22, 255, 221);
+
+ _intf->callback(33, 8);
+ _intf->setSoundEffectChanMask(~0x3f);
+
+ _ready = true;
+ }
+
+ _isOpen = true;
+
+ return 0;
+}
+
+void MidiDriver_FMTowns::loadInstruments(const uint8 *data) {
+ if (data) {
+ data += 6;
+ for (int i = 0; i < 128; i++) {
+ _intf->callback(5, 0, i, data);
+ data += 48;
+ }
+ }
+ _intf->callback(70, 3);
+ property(MIDI_PROP_MASTER_VOLUME, _masterVolume);
+}
+
+void MidiDriver_FMTowns::close() {
+ _isOpen = false;
+}
+
+void MidiDriver_FMTowns::send(uint32 b) {
+ if (!_isOpen)
+ return;
+
+ byte para2 = (b >> 16) & 0xFF;
+ byte para1 = (b >> 8) & 0xFF;
+ byte cmd = b & 0xF0;
+
+ TownsMidiPart *chan = _parts[b & 0x0F];
+
+ switch (cmd) {
+ case 0x80:
+ chan->noteOff(para1);
+ break;
+ case 0x90:
+ chan->noteOn(para1, para2);
+ break;
+ case 0xb0:
+ switch (para1) {
+ case 7:
+ chan->controlChangeVolume(para2);
+ break;
+ case 64:
+ chan->controlChangeSustain(para2);
+ break;
+ case SCI_MIDI_SET_POLYPHONY:
+ chan->controlChangePolyphony(para2);
+ break;
+ case SCI_MIDI_CHANNEL_NOTES_OFF:
+ chan->controlChangeAllNotesOff();
+ break;
+ default:
+ break;
+ }
+ break;
+ case 0xc0:
+ chan->programChange(para1);
+ break;
+ case 0xe0:
+ chan->pitchBend(para1 | (para2 << 7));
+ break;
+ default:
+ break;
+ }
+}
+
+uint32 MidiDriver_FMTowns::property(int prop, uint32 param) {
+ switch(prop) {
+ case MIDI_PROP_MASTER_VOLUME:
+ if (param != 0xffff) {
+ _masterVolume = param;
+ for (int i = 0; i < 6; i++)
+ _out[i]->updateVolume();
+ }
+ return _masterVolume;
+ default:
+ break;
+ }
+ return 0;
+}
+
+void MidiDriver_FMTowns::setTimerCallback(void *timer_param, Common::TimerManager::TimerProc timer_proc) {
+ _timerProc = timer_proc;
+ _timerProcPara = timer_param;
+}
+
+void MidiDriver_FMTowns::setSoundOn(bool toggle) {
+ _soundOn = toggle;
+}
+
+uint32 MidiDriver_FMTowns::getBaseTempo() {
+ return _baseTempo;
+}
+
+void MidiDriver_FMTowns::timerCallback(int timerId) {
+ if (!_isOpen)
+ return;
+
+ switch (timerId) {
+ case 1:
+ updateParser();
+ updateChannels();
+ break;
+ default:
+ break;
+ }
+}
+
+int MidiDriver_FMTowns::getChannelVolume(uint8 midiPart) {
+ static const uint8 volumeTable[] = { 0x00, 0x0D, 0x1B, 0x28, 0x36, 0x43, 0x51, 0x5F, 0x63, 0x67, 0x6B, 0x6F, 0x73, 0x77, 0x7B, 0x7F };
+ int tableIndex = (_version == SCI_VERSION_1_EARLY) ? _masterVolume : (_parts[midiPart]->_volume * (_masterVolume + 1)) >> 6;
+ assert(tableIndex < 16);
+ return volumeTable[tableIndex];
+}
+
+void MidiDriver_FMTowns::addMissingChannels() {
+ uint8 avlChan = 0;
+ for (int i = 0; i < 6; i++) {
+ if (_out[i]->_assign == 0xff)
+ avlChan++;
+ }
+
+ if (!avlChan)
+ return;
+
+ for (int i = 0; i < 16; i++) {
+ if (!_parts[i]->_chanMissing)
+ continue;
+
+ if (_parts[i]->_chanMissing < avlChan) {
+ avlChan -= _parts[i]->_chanMissing;
+ uint8 m = _parts[i]->_chanMissing;
+ _parts[i]->_chanMissing = 0;
+ _parts[i]->addChannels(m);
+ } else {
+ _parts[i]->_chanMissing -= avlChan;
+ _parts[i]->addChannels(avlChan);
+ return;
+ }
+ }
+}
+
+void MidiDriver_FMTowns::updateParser() {
+ if (_timerProc)
+ _timerProc(_timerProcPara);
+}
+
+void MidiDriver_FMTowns::updateChannels() {
+ for (int i = 0; i < 6; i++)
+ _out[i]->updateDuration();
+}
+
+MidiPlayer_FMTowns::MidiPlayer_FMTowns(SciVersion version) : MidiPlayer(version) {
+ _driver = _townsDriver = new MidiDriver_FMTowns(g_system->getMixer(), version);
+}
+
+MidiPlayer_FMTowns::~MidiPlayer_FMTowns() {
+ delete _driver;
+}
+
+int MidiPlayer_FMTowns::open(ResourceManager *resMan) {
+ int result = MidiDriver::MERR_DEVICE_NOT_AVAILABLE;
+ if (_townsDriver) {
+ result = _townsDriver->open();
+ if (!result && _version == SCI_VERSION_1_LATE)
+ _townsDriver->loadInstruments((resMan->findResource(ResourceId(kResourceTypePatch, 8), true))->data);
+ }
+ return result;
+}
+
+bool MidiPlayer_FMTowns::hasRhythmChannel() const {
+ return false;
+}
+
+byte MidiPlayer_FMTowns::getPlayId() const {
+ return (_version == SCI_VERSION_1_EARLY) ? 0x00 : 0x16;
+}
+
+int MidiPlayer_FMTowns::getPolyphony() const {
+ return (_version == SCI_VERSION_1_EARLY) ? 1 : 6;
+}
+
+void MidiPlayer_FMTowns::playSwitch(bool play) {
+ if (_townsDriver)
+ _townsDriver->setSoundOn(play);
+}
+
+MidiPlayer *MidiPlayer_FMTowns_create(SciVersion _soundVersion) {
+ return new MidiPlayer_FMTowns(_soundVersion);
+}
+
+} // End of namespace Sci
+
diff --git a/engines/sci/sound/drivers/mididriver.h b/engines/sci/sound/drivers/mididriver.h
index ec66984bd4..8938eef62f 100644
--- a/engines/sci/sound/drivers/mididriver.h
+++ b/engines/sci/sound/drivers/mididriver.h
@@ -130,6 +130,7 @@ extern MidiPlayer *MidiPlayer_PCSpeaker_create(SciVersion version);
extern MidiPlayer *MidiPlayer_CMS_create(SciVersion version);
extern MidiPlayer *MidiPlayer_Midi_create(SciVersion version);
extern MidiPlayer *MidiPlayer_Fb01_create(SciVersion version);
+extern MidiPlayer *MidiPlayer_FMTowns_create(SciVersion version);
} // End of namespace Sci
diff --git a/engines/sci/sound/midiparser_sci.cpp b/engines/sci/sound/midiparser_sci.cpp
index ad7ba7ca36..422948f975 100644
--- a/engines/sci/sound/midiparser_sci.cpp
+++ b/engines/sci/sound/midiparser_sci.cpp
@@ -355,17 +355,14 @@ void MidiParser_SCI::sendInitCommands() {
}
}
- // Send a velocity off signal to all channels
- for (int i = 0; i < 15; ++i) {
- if (_channelUsed[i])
- sendToDriver(0xB0 | i, 0x4E, 0); // Reset velocity
- }
-
- // Center the pitch wheels and hold pedal in preparation for the next piece of music
+ // Reset all the parameters of the channels used by this song
for (int i = 0; i < 16; ++i) {
if (_channelUsed[i]) {
- sendToDriver(0xE0 | i, 0, 0x40); // Reset pitch wheel
- sendToDriver(0xB0 | i, 0x40, 0); // Reset hold pedal
+ sendToDriver(0xB0 | i, 0x07, 127); // Reset volume to maximum
+ sendToDriver(0xB0 | i, 0x0A, 64); // Reset panning to center
+ sendToDriver(0xB0 | i, 0x40, 0); // Reset hold pedal to none
+ sendToDriver(0xB0 | i, 0x4E, 0); // Reset velocity to none
+ sendToDriver(0xE0 | i, 0, 64); // Reset pitch wheel to center
}
}
}
diff --git a/engines/sci/sound/music.cpp b/engines/sci/sound/music.cpp
index 9610b6f847..09cab75c39 100644
--- a/engines/sci/sound/music.cpp
+++ b/engines/sci/sound/music.cpp
@@ -37,15 +37,17 @@
namespace Sci {
-SciMusic::SciMusic(SciVersion soundVersion)
- : _soundVersion(soundVersion), _soundOn(true), _masterVolume(0), _globalReverb(0) {
+SciMusic::SciMusic(SciVersion soundVersion, bool useDigitalSFX)
+ : _soundVersion(soundVersion), _soundOn(true), _masterVolume(0), _globalReverb(0), _useDigitalSFX(useDigitalSFX) {
// Reserve some space in the playlist, to avoid expensive insertion
// operations
_playList.reserve(10);
- for (int i = 0; i < 16; i++)
+ for (int i = 0; i < 16; i++) {
_usedChannel[i] = 0;
+ _channelRemap[i] = -1;
+ }
_queuedCommands.reserve(1000);
}
@@ -76,6 +78,13 @@ void SciMusic::init() {
if (getSciVersion() >= SCI_VERSION_1_EGA_ONLY && getSciVersion() <= SCI_VERSION_1_1)
deviceFlags |= MDT_CMS;
+ if (g_sci->getPlatform() == Common::kPlatformFMTowns) {
+ if (getSciVersion() > SCI_VERSION_1_EARLY)
+ deviceFlags = MDT_TOWNS;
+ else
+ deviceFlags |= MDT_TOWNS;
+ }
+
uint32 dev = MidiDriver::detectDevice(deviceFlags);
_musicType = MidiDriver::getMusicType(dev);
@@ -96,6 +105,9 @@ void SciMusic::init() {
case MT_CMS:
_pMidiDrv = MidiPlayer_CMS_create(_soundVersion);
break;
+ case MT_TOWNS:
+ _pMidiDrv = MidiPlayer_FMTowns_create(_soundVersion);
+ break;
default:
if (ConfMan.getBool("native_fb01"))
_pMidiDrv = MidiPlayer_Fb01_create(_soundVersion);
@@ -110,8 +122,6 @@ void SciMusic::init() {
error("Failed to initialize sound driver");
}
- _bMultiMidi = ConfMan.getBool("multi_midi");
-
// Find out what the first possible channel is (used, when doing channel
// remapping).
_driverFirstChannel = _pMidiDrv->getFirstChannel();
@@ -273,10 +283,10 @@ void SciMusic::soundInitSnd(MusicEntry *pSnd) {
SoundResource::Track *track = pSnd->soundRes->getTrackByType(_pMidiDrv->getPlayId());
// If MIDI device is selected but there is no digital track in sound
- // resource try to use adlib's digital sample if possible. Also, if the
+ // resource try to use Adlib's digital sample if possible. Also, if the
// track couldn't be found, load the digital track, as some games depend on
// this (e.g. the Longbow demo).
- if (!track || (_bMultiMidi && track->digitalChannelNr == -1)) {
+ if (!track || (_useDigitalSFX && track->digitalChannelNr == -1)) {
SoundResource::Track *digital = pSnd->soundRes->getDigitalTrack();
if (digital)
track = digital;
@@ -349,6 +359,7 @@ int16 SciMusic::tryToOwnChannel(MusicEntry *caller, int16 bestChannel) {
if (!_usedChannel[bestChannel]) {
// currently unused, so give it to caller directly
_usedChannel[bestChannel] = caller;
+ _channelRemap[bestChannel] = bestChannel;
return bestChannel;
}
// otherwise look for unused channel
@@ -357,6 +368,7 @@ int16 SciMusic::tryToOwnChannel(MusicEntry *caller, int16 bestChannel) {
continue;
if (!_usedChannel[channelNr]) {
_usedChannel[channelNr] = caller;
+ _channelRemap[bestChannel] = channelNr;
return channelNr;
}
}
@@ -369,8 +381,24 @@ int16 SciMusic::tryToOwnChannel(MusicEntry *caller, int16 bestChannel) {
void SciMusic::freeChannels(MusicEntry *caller) {
// Remove used channels
for (int i = 0; i < 15; i++) {
- if (_usedChannel[i] == caller)
+ if (_usedChannel[i] == caller) {
+ if (_channelRemap[i] != -1) {
+ // athrxx: The original handles this differently. It seems to be checking for (and effecting) necessary
+ // remaps / resets etc. more or less all the time. There are several more tables to keep track of everything.
+ // I don't know whether all of that is needed and to which SCI versions it applies, though.
+ // At least it is necessary to release the allocated channels inside the driver. Otherwise these channels
+ // won't be available any more (e.g. after half of the KQ5 FM-Towns intro there will be no more music
+ // since the driver can't pick up any more channels). The channels also have to be reset to
+ // default values, since the original does the same (although in a different manny) and the music will be wrong
+ // otherwise (at least KQ5 FM-Towns).
+
+ sendMidiCommand(0x4000e0 | _channelRemap[i]); // Reset pitch wheel
+ sendMidiCommand(0x0040b0 | _channelRemap[i]); // Release pedal
+ sendMidiCommand(0x004bb0 | _channelRemap[i]); // Release assigned driver channels
+ }
_usedChannel[i] = 0;
+ _channelRemap[i] = -1;
+ }
}
// Also tell midiparser, that he lost ownership
caller->pMidiParser->lostChannels();
@@ -446,9 +474,9 @@ void SciMusic::soundPlay(MusicEntry *pSnd) {
// volume of the sound channels that the faded song occupies..
// Fixes bug #3266480 and partially fixes bug #3041738.
for (uint i = 0; i < playListCount; i++) {
- // Is another MIDI song being faded? If yes, stop it
+ // Is another MIDI song being faded down? If yes, stop it
// immediately instead
- if (_playList[i]->fadeStep && _playList[i]->pMidiParser) {
+ if (_playList[i]->fadeStep < 0 && _playList[i]->pMidiParser) {
_playList[i]->status = kSoundStopped;
if (_soundVersion <= SCI_VERSION_0_LATE)
_playList[i]->isQueued = false;
diff --git a/engines/sci/sound/music.h b/engines/sci/sound/music.h
index 8577ed7313..1f798c90d7 100644
--- a/engines/sci/sound/music.h
+++ b/engines/sci/sound/music.h
@@ -120,7 +120,7 @@ typedef Common::Array<uint32> MidiCommandQueue;
class SciMusic : public Common::Serializable {
public:
- SciMusic(SciVersion soundVersion);
+ SciMusic(SciVersion soundVersion, bool useDigitalSFX);
~SciMusic();
void init();
@@ -210,15 +210,15 @@ protected:
MidiPlayer *_pMidiDrv;
uint32 _dwTempo;
- // Mixed AdLib/MIDI mode: when enabled from the ScummVM sound options screen,
- // and a sound has a digital track, the sound from the AdLib track is played
- bool _bMultiMidi;
+ // If true and a sound has a digital track, the sound from the AdLib track is played
+ bool _useDigitalSFX;
private:
MusicList _playList;
bool _soundOn;
byte _masterVolume;
MusicEntry *_usedChannel[16];
+ int8 _channelRemap[16];
int8 _globalReverb;
MidiCommandQueue _queuedCommands;
diff --git a/engines/sci/sound/soundcmd.cpp b/engines/sci/sound/soundcmd.cpp
index 274c532779..b8be898abc 100644
--- a/engines/sci/sound/soundcmd.cpp
+++ b/engines/sci/sound/soundcmd.cpp
@@ -32,20 +32,30 @@
namespace Sci {
+//#define ENABLE_SFX_TYPE_SELECTION
+
SoundCommandParser::SoundCommandParser(ResourceManager *resMan, SegManager *segMan, Kernel *kernel, AudioPlayer *audio, SciVersion soundVersion) :
_resMan(resMan), _segMan(segMan), _kernel(kernel), _audio(audio), _soundVersion(soundVersion) {
- _music = new SciMusic(_soundVersion);
- _music->init();
+#ifdef ENABLE_SFX_TYPE_SELECTION
// Check if the user wants synthesized or digital sound effects in SCI1.1
- // or later games
- _bMultiMidi = ConfMan.getBool("multi_midi");
+ // games based on the multi_midi config setting
+
// In SCI2 and later games, this check should always be true - there was
// always only one version of each sound effect or digital music track
// (e.g. the menu music in GK1 - there is a sound effect with the same
// resource number, but it's totally unrelated to the menu music).
- if (getSciVersion() >= SCI_VERSION_2)
- _bMultiMidi = true;
+ // The GK1 demo (very late SCI1.1) does the same thing
+ // TODO: Check the QFG4 demo
+
+ _useDigitalSFX = (getSciVersion() >= SCI_VERSION_2 || g_sci->getGameId() == GID_GK1 || ConfMan.getBool("multi_midi"));
+#else
+ // Always prefer digital sound effects
+ _useDigitalSFX = true;
+#endif
+
+ _music = new SciMusic(_soundVersion, _useDigitalSFX);
+ _music->init();
}
SoundCommandParser::~SoundCommandParser() {
@@ -84,16 +94,14 @@ void SoundCommandParser::initSoundResource(MusicEntry *newSound) {
// effects map)
bool checkAudioResource = getSciVersion() >= SCI_VERSION_1_1;
// Hoyle 4 has garbled audio resources in place of the sound resources.
- // The demo of GK1 has no alternate sound effects.
- if ((g_sci->getGameId() == GID_HOYLE4) ||
- (g_sci->getGameId() == GID_GK1 && g_sci->isDemo()))
+ if (g_sci->getGameId() == GID_HOYLE4)
checkAudioResource = false;
if (checkAudioResource && _resMan->testResource(ResourceId(kResourceTypeAudio, newSound->resourceId))) {
// Found a relevant audio resource, create an audio stream if there is
// no associated sound resource, or if both resources exist and the
// user wants the digital version.
- if (_bMultiMidi || !newSound->soundRes) {
+ if (_useDigitalSFX || !newSound->soundRes) {
int sampleLen;
newSound->pStreamAud = _audio->getAudioStream(newSound->resourceId, 65535, &sampleLen);
newSound->soundType = Audio::Mixer::kSpeechSoundType;
@@ -485,7 +493,7 @@ void SoundCommandParser::processUpdateCues(reg_t obj) {
} else {
// Slot actually has no data (which would mean that a sound-resource w/
// unsupported data is used.
- // (example lsl5 - sound resource 744 - it's roland exclusive
+ // (example lsl5 - sound resource 744 - it's Roland exclusive
writeSelectorValue(_segMan, obj, SELECTOR(signal), SIGNAL_OFFSET);
// If we don't set signal here, at least the switch to the mud wrestling
// room in lsl5 will not work.
diff --git a/engines/sci/sound/soundcmd.h b/engines/sci/sound/soundcmd.h
index c1dce014d2..d76f969c7d 100644
--- a/engines/sci/sound/soundcmd.h
+++ b/engines/sci/sound/soundcmd.h
@@ -111,7 +111,9 @@ private:
SciMusic *_music;
AudioPlayer *_audio;
SciVersion _soundVersion;
- bool _bMultiMidi;
+ // If true and an alternative digital sound effect exists, the digital
+ // sound effect is preferred instead
+ bool _useDigitalSFX;
void processInitSound(reg_t obj);
void processDisposeSound(reg_t obj);
diff --git a/engines/scumm/actor.cpp b/engines/scumm/actor.cpp
index eb23c30ebe..b8722b6963 100644
--- a/engines/scumm/actor.cpp
+++ b/engines/scumm/actor.cpp
@@ -42,6 +42,14 @@ namespace Scumm {
byte Actor::kInvalidBox = 0;
+static const byte v0ActorTalkArray[0x19] = {
+ 0x00, 0x06, 0x06, 0x06, 0x06,
+ 0x06, 0x06, 0x00, 0x46, 0x06,
+ 0x06, 0x06, 0x06, 0xFF, 0xFF,
+ 0x06, 0xC0, 0x06, 0x06, 0x00,
+ 0xC0, 0xC0, 0x00, 0x06, 0x06
+};
+
Actor::Actor(ScummEngine *scumm, int id) :
_vm(scumm), _number(id) {
assert(_vm != 0);
@@ -167,6 +175,21 @@ void Actor_v2::initActor(int mode) {
_talkStopFrame = 4;
}
+void Actor_v0::initActor(int mode) {
+ Actor_v2::initActor(mode);
+
+ _costCommandNew = 0xFF;
+ _costCommand = 0xFF;
+ _miscflags = 0;
+ _speaking = 0;
+
+ _animFrameRepeat = 0;
+ for (int i = 0; i < 8; ++i) {
+ _limbFrameRepeatNew[i] = 0;
+ _limbFrameRepeat[i] = 0;
+ _limb_flipped[i] = false;
+ }
+}
void Actor::setBox(int box) {
_walkbox = box;
@@ -226,12 +249,9 @@ void Actor::stopActorMoving() {
if (_walkScript)
_vm->stopScript(_walkScript);
- // V0 Games will walk on the spot if the actor is stopped mid-walk
- // So we must set the stand still frame
- if (_vm->_game.version == 0)
- startWalkAnim(3, -1);
-
_moving = 0;
+ if (_vm->_game.version == 0)
+ setDirection(_facing);
}
void Actor::setActorWalkSpeed(uint newSpeedX, uint newSpeedY) {
@@ -286,7 +306,7 @@ int Actor::calcMovementFactor(const Common::Point& next) {
deltaYFactor = 0;
}
- if ((uint) ABS((int)(deltaXFactor >> 16)) > _speedx) {
+ if ((uint) ABS(deltaXFactor) > (_speedx << 16)) {
deltaXFactor = _speedx << 16;
if (diffX < 0)
deltaXFactor = -deltaXFactor;
@@ -319,6 +339,9 @@ int Actor::actorWalkStep() {
int distX, distY;
int nextFacing;
+ if (_vm->_game.version == 0)
+ ((Actor_v0 *)this)->_animFrameRepeat = -1;
+
_needRedraw = true;
nextFacing = updateActorDirection(true);
@@ -327,6 +350,10 @@ int Actor::actorWalkStep() {
startWalkAnim(1, nextFacing);
}
_moving |= MF_IN_LEG;
+
+ // V0: Don't move during the turn
+ if (_vm->_game.version == 0)
+ return 0;
}
if (_walkbox != _walkdata.curbox && _vm->checkXYInBoxBounds(_walkdata.curbox, _pos.x, _pos.y)) {
@@ -361,6 +388,10 @@ int Actor::actorWalkStep() {
_moving &= ~MF_IN_LEG;
return 0;
}
+
+ if (_vm->_game.version == 0)
+ ((Actor_v0 *)this)->animateActor(newDirToOldDir(_facing));
+
return 1;
}
@@ -536,23 +567,101 @@ void Actor::walkActor() {
calcMovementFactor(_walkdata.dest);
}
+bool Actor_v2::checkWalkboxesHaveDirectPath(Common::Point &foundPath) {
+ // only MM v0 supports walking in direct line between walkboxes.
+ // MM v1 already does not support it anymore.
+ return false;
+}
+
+bool Actor_v0::intersectLineSegments(const Common::Point &line1Start, const Common::Point &line1End,
+ const Common::Point &line2Start, const Common::Point &line2End, Common::Point &result)
+{
+ const Common::Point v1 = line1End - line1Start; // line1(n1) = line1Start + n1 * v1
+ const Common::Point v2 = line2End - line2Start; // line2(n2) = line2Start + n2 * v2
+
+ double det = v2.x * v1.y - v1.x * v2.y;
+ if (det == 0)
+ return false;
+
+ double n1 = ((double)v2.x * (line2Start.y - line1Start.y) -
+ (double)v2.y * (line2Start.x - line1Start.x)) / det;
+ double n2 = ((double)v1.x * (line2Start.y - line1Start.y) -
+ (double)v1.y * (line2Start.x - line1Start.x)) / det;
+
+ // both coefficients have to be in [0, 1], otherwise the intersection is
+ // not inside of at least one of the two line segments
+ if (n1 < 0.0 || n1 > 1.0 || n2 < 0.0 || n2 > 1.0)
+ return false;
+
+ result.x = line1Start.x + (int)(n1 * v1.x);
+ result.y = line1Start.y + (int)(n1 * v1.y);
+ return true;
+}
+
+/*
+ * MM v0 allows the actor to walk in a direct line between boxes to the target
+ * if actor and target share a horizontal or vertical corridor.
+ * If such a corridor is found the actor is not forced to go horizontally or
+ * vertically from one box to the next but can also walk diagonally.
+ *
+ * Note: the original v0 interpreter sets the target destination for diagonal
+ * walking only once and then rechecks whenever the actor reaches a new box if the
+ * walk destination is still suitable for the current box.
+ * ScummVM does not perform such a check, so it is possible to leave the walkboxes
+ * in some cases, for example L-shaped rooms like the swimming pool (actor walks over water)
+ * or the medical room (actor walks over examination table).
+ * To solve this we intersect the new walk destination with the actor's walkbox borders,
+ * so a recheck is done when the actor leaves his box. This is done by the
+ * intersectLineSegments() routine calls.
+ */
+bool Actor_v0::checkWalkboxesHaveDirectPath(Common::Point &foundPath) {
+ BoxCoords boxCoords = _vm->getBoxCoordinates(_walkbox);
+ BoxCoords curBoxCoords = _vm->getBoxCoordinates(_walkdata.curbox);
+
+ // check if next walkbox is left or right to actor's box
+ if (boxCoords.ll.x > curBoxCoords.lr.x || boxCoords.lr.x < curBoxCoords.ll.x) {
+ // determine horizontal corridor gates
+ int gateUpper = MAX(boxCoords.ul.y, curBoxCoords.ul.y);
+ int gateLower = MIN(boxCoords.ll.y, curBoxCoords.ll.y);
+
+ // check if actor and target are in the same horizontal corridor between the boxes
+ if ((_pos.y >= gateUpper && _pos.y <= gateLower) &&
+ (_walkdata.dest.y >= gateUpper && _walkdata.dest.y <= gateLower)) {
+ if (boxCoords.ll.x > curBoxCoords.lr.x) // next box is left
+ return intersectLineSegments(_pos, _walkdata.dest, boxCoords.ll, boxCoords.ul, foundPath);
+ else // next box is right
+ return intersectLineSegments(_pos, _walkdata.dest, boxCoords.lr, boxCoords.ur, foundPath);
+ }
+ // check if next walkbox is above or below actor's box
+ } else if (boxCoords.ul.y > curBoxCoords.ll.y || boxCoords.ll.y < curBoxCoords.ul.y) {
+ // determine vertical corridor gates
+ int gateLeft = MAX(boxCoords.ll.x, curBoxCoords.ll.x);
+ int gateRight = MIN(boxCoords.lr.x, curBoxCoords.lr.x);
+
+ // check if actor and target are in the same vertical corridor between the boxes
+ if ((_pos.x >= gateLeft && _pos.x <= gateRight) &&
+ (_walkdata.dest.x >= gateLeft && _walkdata.dest.x <= gateRight)) {
+ if (boxCoords.ul.y > curBoxCoords.ll.y) // next box is above
+ return intersectLineSegments(_pos, _walkdata.dest, boxCoords.ul, boxCoords.ur, foundPath);
+ else // next box is below
+ return intersectLineSegments(_pos, _walkdata.dest, boxCoords.ll, boxCoords.lr, foundPath);
+ }
+ }
+
+ return false;
+}
+
void Actor_v2::walkActor() {
Common::Point foundPath, tmp;
int new_dir, next_box;
if (_moving & MF_TURN) {
new_dir = updateActorDirection(false);
- // FIXME: is this correct?
if (_facing != new_dir) {
-
- // Actor never stops walking when an object has been selected without this
- if (_vm->_game.version ==0)
- _moving = 0;
-
setDirection(new_dir);
-
- } else
+ } else {
_moving = 0;
+ }
return;
}
@@ -588,14 +697,7 @@ void Actor_v2::walkActor() {
_walkdata.curbox = next_box;
- // WORKAROUND: The route of the meteor landing in the introduction isn't correct.
- // MM V0 in contrast to MM V2 uses two walkboxes instead of just one. Hence a route
- // from walkbox 1 to 0 is calculated first. This causes the meteor to fly on a
- // horizontal line to walkbox 0 then vertically to the ground.
- // To fix this problem, the box-to-box routing has been disabled in room 33.
- if (_vm->_game.version == 0 && _vm->_currentRoom == 33) {
- foundPath = _walkdata.dest;
- } else {
+ if (!checkWalkboxesHaveDirectPath(foundPath)) {
getClosestPtOnBox(_vm->getBoxCoordinates(_walkdata.curbox), _pos.x, _pos.y, tmp.x, tmp.y);
getClosestPtOnBox(_vm->getBoxCoordinates(_walkbox), tmp.x, tmp.y, foundPath.x, foundPath.y);
}
@@ -781,7 +883,7 @@ int Actor::remapDirection(int dir, bool is_walking) {
return 180;
}
- // MM C64 stores flags as a part of the mask
+ // MM v0 stores flags as a part of the mask
if (_vm->_game.version == 0) {
mask = _vm->getMaskFromBox(_walkbox);
// face the wall if climbing/descending a ladder
@@ -857,16 +959,6 @@ void Actor::setDirection(int direction) {
if (_costume == 0)
return;
- // V0 MM
- if (_vm->_game.version == 0) {
- if (_moving)
- _vm->_costumeLoader->costumeDecodeData(this, _walkFrame, 0);
- else
- _vm->_costumeLoader->costumeDecodeData(this, _standFrame, 0);
- _needRedraw = true;
- return;
- }
-
// Update the costume for the new direction (and mark the actor for redraw)
aMask = 0x8000;
for (i = 0; i < 16; i++, aMask >>= 1) {
@@ -879,6 +971,34 @@ void Actor::setDirection(int direction) {
_needRedraw = true;
}
+void Actor_v0::setDirection(int direction) {
+ int dir = newDirToOldDir( direction );
+ int res = 0;
+
+ switch (dir) {
+ case 0:
+ res = 4; // Left
+ break;
+
+ case 1:
+ res = 5; // Right
+ break;
+
+ case 2:
+ res = 6; // Face Away
+ break;
+
+ default:
+ res = 7; // Face Camera
+ break;
+ }
+
+ _animFrameRepeat = -1;
+ animateActor(res);
+ if (_moving)
+ animateCostume();
+}
+
void Actor::faceToObject(int obj) {
int x2, y2, dir;
@@ -963,6 +1083,10 @@ void Actor::putActor(int dstX, int dstY, int newRoom) {
if (isInCurrentRoom())
showActor();
}
+
+ // V0 always sets the actor to face the camera upon entering a room
+ if (_vm->_game.version == 0)
+ setDirection(oldDirToNewDir(2));
}
static bool inBoxQuickReject(const BoxCoords &box, int x, int y, int threshold) {
@@ -1062,16 +1186,11 @@ static int checkXYInBoxBounds(int boxnum, int x, int y, int &destX, int &destY)
// yDist must be divided by 4, as we are using 8x2 pixels
// blocks for actor coordinates).
int xDist = ABS(x - destX);
- int yDist;
+ int yDist = ABS(y - destY) / 4;
int dist;
- // MM C64: This fixes the trunk bug (#3070065), as well
- // 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);
- else
- yDist = ABS(y - destY) / 4;
+ if (g_scumm->_game.version == 0)
+ xDist *= 2;
if (xDist < yDist)
dist = (xDist >> 1) + yDist;
@@ -1090,7 +1209,9 @@ AdjustBoxResult Actor_v2::adjustXYToBeInBox(const int dstX, const int dstY) {
int numBoxes = _vm->getNumBoxes() - 1;
int bestDist = 0xFF;
- for (int box = numBoxes; box >= 0; box--) {
+ for (int i = 0; i <= numBoxes; i++) {
+ // MM v0 prioritizes lower boxes, other engines higher boxes
+ int box = (_vm->_game.version == 0 ? i : numBoxes - i);
int foundX, foundY;
int flags = _vm->getBoxFlags(box);
if ((flags & kBoxInvisible) && !((flags & kBoxPlayerOnly) && !isPlayer()))
@@ -1286,8 +1407,24 @@ void Actor::showActor() {
_vm->ensureResourceLoaded(rtCostume, _costume);
if (_vm->_game.version == 0) {
+ Actor_v0 *a = ((Actor_v0 *)this);
+
+ a->_costCommand = a->_costCommandNew = 0xFF;
+
+ for (int i = 0; i < 8; ++i) {
+ a->_limbFrameRepeat[i] = 0;
+ a->_limbFrameRepeatNew[i] = 0;
+ }
+
_cost.reset();
+
+ a->_animFrameRepeat = 1;
+ a->_speaking = 0;
+
startAnimActor(_standFrame);
+ _visible = true;
+ return;
+
} else if (_vm->_game.version <= 2) {
_cost.reset();
startAnimActor(_standFrame);
@@ -1323,23 +1460,23 @@ static const byte v0ActorSounds[24] = {
0x06, // Bernard
0x06, // Wendy
0x00, // Jeff
- 0x46, // ???
+ 0x46, // Radiation Suit
0x06, // Dr Fred
0x06, // Nurse Edna
0x06, // Weird Ed
0x06, // Dead Cousin Ted
0xFF, // Purple Tentacle
0xFF, // Green Tentacle
- 0x06, // Meteor
- 0xC0, // Plant
- 0x06, // ???
- 0x06, // ???
- 0x00, // ???
- 0xC0, // ???
- 0xC0, // ???
- 0x00, // ???
- 0x06, // Sandy
- 0x06, // ???
+ 0x06, // Meteor police
+ 0xC0, // Meteor
+ 0x06, // Mark Eteer
+ 0x06, // Talkshow Host
+ 0x00, // Plant
+ 0xC0, // Meteor Radiation
+ 0xC0, // Edsel (small, outro)
+ 0x00, // Meteor (small, intro)
+ 0x06, // Sandy (Lab)
+ 0x06, // Sandy (Cut-Scene)
};
/* Used in Scumm v5 only. Play sounds associated with actors */
@@ -1355,7 +1492,10 @@ void ScummEngine::playActorSounds() {
} else {
sound = _actors[i]->_sound[0];
}
- _sound->addSoundToQueue(sound);
+ // fast mode will flood the queue with walk sounds
+ if (!_fastMode) {
+ _sound->addSoundToQueue(sound);
+ }
for (j = 1; j < _numActors; j++) {
_actors[j]->_cost.soundCounter = 0;
}
@@ -1462,6 +1602,18 @@ void ScummEngine::processActors() {
}
}
}
+ } else if (_game.version == 0) {
+ for (int j = 0; j < numactors; ++j) {
+ for (int i = 0; i < numactors; ++i) {
+ // Note: the plant is handled different in v0, the y value is not used.
+ // In v1/2 this is done by the actor's elevation instead.
+ int sc_actor1 = (_sortedActors[j]->_number == 19 ? 0 : _sortedActors[j]->getPos().y);
+ int sc_actor2 = (_sortedActors[i]->_number == 19 ? 0 : _sortedActors[i]->getPos().y);
+ if (sc_actor1 < sc_actor2) {
+ SWAP(_sortedActors[i], _sortedActors[j]);
+ }
+ }
+ }
} else {
for (int j = 0; j < numactors; ++j) {
for (int i = 0; i < numactors; ++i) {
@@ -1479,11 +1631,26 @@ void ScummEngine::processActors() {
for (Actor** ac = _sortedActors; ac != end; ++ac) {
Actor* a = *ac;
- // V0 MM: 0x057B
if (_game.version == 0) {
- ActorC64 *A = (ActorC64*) a;
- if ((A->_speaking & 1))
- A->_speaking ^= 0xFE;
+ // 0x057B
+ Actor_v0 *a0 = (Actor_v0*) a;
+ if (a0->_speaking & 1)
+ a0->_speaking ^= 0xFE;
+
+ // 0x22B5
+ if (a0->_miscflags & kActorMiscFlagHide)
+ continue;
+
+ // Sound
+ if (a0->_moving && _currentRoom != 1 && _currentRoom != 44) {
+ if (a0->_cost.soundPos == 0)
+ a0->_cost.soundCounter++;
+
+ // Is this the correct location?
+ // 0x073C
+ if (v0ActorTalkArray[a0->_number] & 0x3F)
+ a0->_cost.soundPos = (a0->_cost.soundPos + 1) % 3;
+ }
}
// Draw and animate the actors, except those w/o a costume.
// Note: We could 'optimize' this a little bit by only putting
@@ -1779,6 +1946,25 @@ void Actor::startAnimActor(int f) {
}
}
+void Actor_v0::startAnimActor(int f) {
+ if (f == _talkStartFrame) {
+ if (v0ActorTalkArray[_number] & 0x40)
+ return;
+
+ _speaking = 1;
+ return;
+ }
+
+ if (f == _talkStopFrame) {
+
+ _speaking = 0;
+ return;
+ }
+
+ if (f == _standFrame)
+ setDirection(_facing);
+}
+
void Actor::animateActor(int anim) {
int cmd, dir;
@@ -1841,6 +2027,47 @@ void Actor::animateCostume() {
}
}
+void Actor_v0::limbFrameCheck(int limb) {
+ if (_cost.frame[limb] == 0xFFFF)
+ return;
+
+ if (_cost.start[limb] == _cost.frame[limb])
+ return;
+
+ // 0x25A4
+ _cost.start[limb] = _cost.frame[limb];
+
+ _limbFrameRepeat[limb] = _limbFrameRepeatNew[limb];
+
+ // 0x25C3
+ _cost.active[limb] = ((V0CostumeLoader *)_vm->_costumeLoader)->getFrame(this, limb);
+ _cost.curpos[limb] = 0;
+
+ _needRedraw = true;
+}
+
+void Actor_v0::animateCostume() {
+ speakCheck();
+
+ if (_vm->_costumeLoader->increaseAnims(this))
+ _needRedraw = true;
+}
+
+void Actor_v0::speakCheck() {
+ if (v0ActorTalkArray[_number] & 0x80)
+ return;
+
+ int cmd = newDirToOldDir(_facing);
+
+ if (_speaking & 0x80)
+ cmd += 0x0C;
+ else
+ cmd += 0x10;
+
+ _animFrameRepeat = -1;
+ animateActor(cmd);
+}
+
#ifdef ENABLE_SCUMM_7_8
void Actor::animateLimb(int limb, int f) {
// This methods is very similiar to animateCostume().
@@ -1994,7 +2221,7 @@ void ScummEngine::setTalkingActor(int i) {
VAR(VAR_TALK_ACTOR) = i;
}
-static const int c64MMActorTalkColor[25] = {
+static const int v0MMActorTalkColor[25] = {
1, 7, 2, 14, 8, 15, 3, 7, 7, 15, 1, 13, 1, 4, 5, 5, 4, 3, 1, 5, 1, 1, 1, 1, 7
};
static const int v1MMActorTalkColor[25] = {
@@ -2006,7 +2233,7 @@ void ScummEngine::resetV1ActorTalkColor() {
for (i = 1; i < _numActors; i++) {
if (_game.version == 0) {
- _actors[i]->_talkColor = c64MMActorTalkColor[i];
+ _actors[i]->_talkColor = v0MMActorTalkColor[i];
} else {
_actors[i]->_talkColor = v1MMActorTalkColor[i];
}
@@ -2295,22 +2522,23 @@ static const char *const v0ActorNames_English[25] = {
"Bernard",
"Wendy",
"Jeff",
- "",
+ "", // Radiation Suit
"Dr Fred",
"Nurse Edna",
"Weird Ed",
"Dead Cousin Ted",
"Purple Tentacle",
"Green Tentacle",
+ "", // Meteor Police
"Meteor",
- "",
- "",
- "",
+ "", // Mark Eteer
+ "", // Talkshow Host
"Plant",
- "",
- "",
- "",
- "Sandy"
+ "", // Meteor Radiation
+ "", // Edsel (small, outro)
+ "", // Meteor (small, intro)
+ "Sandy", // (Lab)
+ "", // Sandy (Cut-Scene)
};
static const char *const v0ActorNames_German[25] = {
@@ -2328,15 +2556,16 @@ static const char *const v0ActorNames_German[25] = {
"Ted",
"Lila Tentakel",
"Gr<nes Tentakel",
- "Meteor",
"",
+ "Meteor",
"",
"",
"Pflanze",
"",
"",
"",
- "Sandy"
+ "Sandy",
+ "",
};
const byte *Actor::getActorName() {
@@ -2467,6 +2696,8 @@ bool Actor::isPlayer() {
}
bool Actor_v2::isPlayer() {
+ // isPlayer() is not supported by v0
+ assert(_vm->_game.version != 0);
return _vm->VAR(42) <= _number && _number <= _vm->VAR(43);
}
@@ -2621,16 +2852,64 @@ void ScummEngine_v71he::queueAuxEntry(int actorNum, int subIndex) {
}
#endif
+void Actor_v0::animateActor(int anim) {
+ int dir = -1;
+
+ switch (anim) {
+ case 0x00:
+ case 0x04:
+ dir = 0;
+ break;
+
+ case 0x01:
+ case 0x05:
+ dir = 1;
+ break;
+
+ case 0x02:
+ case 0x06:
+ dir = 2;
+ break;
+
+ case 0x03:
+ case 0x07:
+ dir = 3;
+ break;
+
+ default:
+ break;
+ }
+
+ if (isInCurrentRoom()) {
+
+ _costCommandNew = anim;
+ _vm->_costumeLoader->costumeDecodeData(this, 0, 0);
+
+ if (dir == -1)
+ return;
+
+ _facing = normalizeAngle(oldDirToNewDir(dir));
+
+ } else {
+
+ if (anim > 4 && anim <= 7)
+ _facing = normalizeAngle(oldDirToNewDir(dir));
+ }
+}
-void ActorC64::saveLoadWithSerializer(Serializer *ser) {
+void Actor_v0::saveLoadWithSerializer(Serializer *ser) {
Actor::saveLoadWithSerializer(ser);
static const SaveLoadEntry actorEntries[] = {
- MKLINE(ActorC64, _costCommand, sleByte, VER(84)),
- MKLINE(ActorC64, _costFrame, sleByte, VER(84)),
- MKLINE(ActorC64, _miscflags, sleByte, VER(84)),
- MKLINE(ActorC64, _speaking, sleByte, VER(84)),
- MKLINE(ActorC64, _speakingPrev, sleByte, VER(84)),
+ MKLINE(Actor_v0, _costCommand, sleByte, VER(84)),
+ MK_OBSOLETE(Actor_v0, _costFrame, sleByte, VER(84), VER(89)),
+ MKLINE(Actor_v0, _miscflags, sleByte, VER(84)),
+ MKLINE(Actor_v0, _speaking, sleByte, VER(84)),
+ MK_OBSOLETE(Actor_v0, _speakingPrev, sleByte, VER(84), VER(89)),
+ MK_OBSOLETE(Actor_v0, _limbTemp, sleByte, VER(89), VER(89)),
+ MKLINE(Actor_v0, _animFrameRepeat, sleByte, VER(89)),
+ MKARRAY(Actor_v0, _limbFrameRepeatNew[0], sleInt8, 8, VER(89)),
+ MKARRAY(Actor_v0, _limbFrameRepeat[0], sleInt8, 8, VER(90)),
MKEND()
};
diff --git a/engines/scumm/actor.h b/engines/scumm/actor.h
index 1584d0a78b..0ed239d005 100644
--- a/engines/scumm/actor.h
+++ b/engines/scumm/actor.h
@@ -202,13 +202,13 @@ public:
void adjustActorPos();
virtual AdjustBoxResult adjustXYToBeInBox(int dstX, int dstY);
- void setDirection(int direction);
+ virtual void setDirection(int direction);
void faceToObject(int obj);
void turnToDirection(int newdir);
virtual void walkActor();
void drawActorCostume(bool hitTestMode = false);
virtual void prepareDrawActorCostume(BaseCostumeRenderer *bcr);
- void animateCostume();
+ virtual void animateCostume();
virtual void setActorCostume(int c);
void animateLimb(int limb, int f);
@@ -222,7 +222,7 @@ protected:
void startWalkAnim(int cmd, int angle);
public:
void runActorTalkScript(int f);
- void startAnimActor(int frame);
+ virtual void startAnimActor(int frame);
void remapActorPalette(int r_fact, int g_fact, int b_fact, int threshold);
void remapActorPaletteColor(int slot, int color);
@@ -333,33 +333,53 @@ public:
protected:
virtual bool isPlayer();
virtual void prepareDrawActorCostume(BaseCostumeRenderer *bcr);
+ virtual bool checkWalkboxesHaveDirectPath(Common::Point &foundPath);
};
-class ActorC64 : public Actor_v2 {
+enum ActorV0MiscFlags {
+ kActorMiscFlagStrong = 0x01, // Kid is strong (Hunk-O-Matic used)
+ kActorMiscFlagGTFriend = 0x02, // Kid is green tentacle's friend (recording contract)
+ kActorMiscFlagWatchedTV = 0x04, // Kid knows publisher's address (watched TV)
+ kActorMiscFlagEdsEnemy = 0x08, // Kid is not Weird Ed's friend
+ kActorMiscFlag_10 = 0x10, // ???
+ kActorMiscFlag_20 = 0x20, // ???
+ kActorMiscFlagFreeze = 0x40, // Stop moving
+ kActorMiscFlagHide = 0x80 // Kid is invisible (dead or in radiation suit)
+};
+
+class Actor_v0 : public Actor_v2 {
public:
- byte _costCommand, _costFrame;
- byte _miscflags; // 0x1: strong, 0x8: Ed's enemy, 0x40: stop moving, 0x80: hide(dead/radiation suit)
- byte _speaking, _speakingPrev;
+ byte _costCommandNew;
+ byte _costCommand;
+ byte _miscflags;
+ byte _speaking;
+
+ int8 _animFrameRepeat;
+ int8 _limbFrameRepeatNew[8];
+ int8 _limbFrameRepeat[8];
+
+ bool _limb_flipped[8];
public:
- ActorC64(ScummEngine *scumm, int id) : Actor_v2(scumm, id) {
- _costCommand = 0;
- _costFrame = 0;
- _speaking = 0;
- _speakingPrev = 0;
- }
- virtual void initActor(int mode) {
- Actor_v2::initActor(mode);
- if (mode == -1) {
- _miscflags = 0;
- }
- }
+ Actor_v0(ScummEngine *scumm, int id) : Actor_v2(scumm, id) {}
+
+ virtual void initActor(int mode);
+ virtual void animateActor(int anim);
+ virtual void animateCostume();
+
+ void limbFrameCheck(int limb);
+
+ void speakCheck();
+ virtual void setDirection(int direction);
+ void startAnimActor(int f);
// Used by the save/load system:
virtual void saveLoadWithSerializer(Serializer *ser);
protected:
-
+ bool intersectLineSegments(const Common::Point &line1Start, const Common::Point &line1End,
+ const Common::Point &line2Start, const Common::Point &line2End, Common::Point &result);
+ virtual bool checkWalkboxesHaveDirectPath(Common::Point &foundPath);
};
diff --git a/engines/scumm/boxes.cpp b/engines/scumm/boxes.cpp
index 64d4d7422c..f6d2a18f38 100644
--- a/engines/scumm/boxes.cpp
+++ b/engines/scumm/boxes.cpp
@@ -42,7 +42,7 @@ struct Box { /* Internal walkbox file format */
byte y1;
byte y2;
byte mask;
- } c64;
+ } v0;
struct {
byte uy;
@@ -181,7 +181,7 @@ byte ScummEngine::getMaskFromBox(int box) {
if (_game.version == 8)
return (byte) FROM_LE_32(ptr->v8.mask);
else if (_game.version == 0)
- return ptr->c64.mask;
+ return ptr->v0.mask;
else if (_game.version <= 2)
return ptr->v2.mask;
else
@@ -479,7 +479,7 @@ Box *ScummEngine::getBoxBaseAddr(int box) {
assertRange(0, box, ptr[0] - 1, "box");
if (_game.version == 0)
- return (Box *)(ptr + box * SIZEOF_BOX_C64 + 1);
+ return (Box *)(ptr + box * SIZEOF_BOX_V0 + 1);
else if (_game.version <= 2)
return (Box *)(ptr + box * SIZEOF_BOX_V2 + 1);
else if (_game.version == 3)
@@ -602,19 +602,19 @@ BoxCoords ScummEngine::getBoxCoordinates(int boxnum) {
SWAP(box->ll, box->lr);
}
} else if (_game.version == 0) {
- box->ul.x = bp->c64.x1;
- box->ul.y = bp->c64.y1;
- box->ur.x = bp->c64.x2;
- box->ur.y = bp->c64.y1;
+ box->ul.x = bp->v0.x1;
+ box->ul.y = bp->v0.y1;
+ box->ur.x = bp->v0.x2;
+ box->ur.y = bp->v0.y1;
- box->ll.x = bp->c64.x1;
- box->ll.y = bp->c64.y2;
- box->lr.x = bp->c64.x2;
- box->lr.y = bp->c64.y2;
+ box->ll.x = bp->v0.x1;
+ box->ll.y = bp->v0.y2;
+ box->lr.x = bp->v0.x2;
+ box->lr.y = bp->v0.y2;
- if ((bp->c64.mask & 0x88) == 0x88) {
+ if ((bp->v0.mask & 0x88) == 0x88) {
// walkbox for (right/left) corner
- if (bp->c64.mask & 0x04)
+ if (bp->v0.mask & 0x04)
box->ur = box->ul;
else
box->ul = box->ur;
diff --git a/engines/scumm/boxes.h b/engines/scumm/boxes.h
index e554aea1b5..345d6a9d36 100644
--- a/engines/scumm/boxes.h
+++ b/engines/scumm/boxes.h
@@ -27,7 +27,7 @@
namespace Scumm {
-#define SIZEOF_BOX_C64 5
+#define SIZEOF_BOX_V0 5
#define SIZEOF_BOX_V2 8
#define SIZEOF_BOX_V3 18
#define SIZEOF_BOX 20
diff --git a/engines/scumm/charset-fontdata.cpp b/engines/scumm/charset-fontdata.cpp
index 29465584f8..16193f5503 100644
--- a/engines/scumm/charset-fontdata.cpp
+++ b/engines/scumm/charset-fontdata.cpp
@@ -420,7 +420,7 @@ static const byte germanCharsetDataV2[] = {
126, 10,
};
-// German C64 MM.
+// German v0 MM.
static const byte germanCharsetDataV0[] = {
36, 11,
42, 12,
diff --git a/engines/scumm/costume.cpp b/engines/scumm/costume.cpp
index eb3cc3262c..6e7e9ff688 100644
--- a/engines/scumm/costume.cpp
+++ b/engines/scumm/costume.cpp
@@ -72,14 +72,6 @@ static const int v1MMNESLookup[25] = {
0x17, 0x00, 0x01, 0x05, 0x16
};
-static const byte v0ActorTalkArray[0x19] = {
- 0x00, 0x06, 0x06, 0x06, 0x06,
- 0x06, 0x06, 0x00, 0x46, 0x06,
- 0x06, 0x06, 0x06, 0xFF, 0xFF,
- 0x06, 0xC0, 0x06, 0x06, 0x00,
- 0xC0, 0xC0, 0x00, 0x06, 0x06
-};
-
byte ClassicCostumeRenderer::mainRoutine(int xmoveCur, int ymoveCur) {
int i, skip = 0;
byte drawFlag = 1;
@@ -676,7 +668,7 @@ void ClassicCostumeRenderer::procPCEngine(Codec1 &v1) {
(v1.mask_ptr && (mask[0] & maskbit));
if (pcolor && !masked) {
- WRITE_UINT16(dst, ((uint16*)_palette)[pcolor]);
+ WRITE_UINT16(dst, ((uint16 *)_palette)[pcolor]);
}
xPos += xStep;
@@ -1171,7 +1163,7 @@ byte NESCostumeLoader::increaseAnim(Actor *a, int slot) {
return (a->_cost.curpos[slot] != oldframe);
}
-static const byte actorColorsMMC64[25] = {
+static const byte actorV0Colors[25] = {
0, 7, 2, 6, 9, 1, 3, 7, 7, 1, 1, 9, 1, 4, 5, 5, 4, 1, 0, 5, 4, 2, 2, 7, 7
};
@@ -1186,24 +1178,25 @@ static const byte actorColorsMMC64[25] = {
dst[p + 1] = palette[pcolor]; \
}
-byte C64CostumeRenderer::drawLimb(const Actor *a, int limb) {
- if (limb >= 8)
- return 0;
+byte V0CostumeRenderer::drawLimb(const Actor *a, int limb) {
+ const Actor_v0* a0 = (const Actor_v0 *)a;
- if (a->_cost.start[limb] == 0xFFFF)
+ if (limb >= 8)
return 0;
if (limb == 0) {
_draw_top = 200;
_draw_bottom = 0;
}
-
- bool flipped = (a->_cost.start[limb] & 0x80) != 0;
- byte frameStart = _loaded._frameOffsets[a->_cost.frame[limb]];
- byte frame = _loaded._frameOffsets[frameStart + a->_cost.curpos[limb]];
- if (frame == 0xFF)
+
+ // Invalid current position?
+ if (a->_cost.curpos[limb] == 0xFFFF)
return 0;
+ _loaded.loadCostume(a->_costume);
+ byte frame = _loaded._frameOffsets[a->_cost.curpos[limb] + a->_cost.active[limb]];
+
+ // Get the frame ptr
byte ptrLow = _loaded._baseptr[frame];
byte ptrHigh = ptrLow + _loaded._dataOffsets[4];
int frameOffset = (_loaded._baseptr[ptrHigh] << 8) + _loaded._baseptr[ptrLow + 2]; // 0x23EF / 0x2400
@@ -1214,7 +1207,7 @@ byte C64CostumeRenderer::drawLimb(const Actor *a, int limb) {
byte palette[4] = { 0, 0, 0, 0 };
if (_vm->getCurrentLights() & LIGHTMODE_actor_use_colors) {
palette[1] = 10;
- palette[2] = actorColorsMMC64[_actorID];
+ palette[2] = actorV0Colors[_actorID];
} else {
palette[2] = 11;
palette[3] = 11;
@@ -1231,7 +1224,7 @@ byte C64CostumeRenderer::drawLimb(const Actor *a, int limb) {
if (!width || !height)
return 0;
- int xpos = _actorX + (flipped ? -1 : +1) * (offsetX * 8 - a->_width / 2);
+ int xpos = _actorX + (a0->_limb_flipped[limb] ? -1 : +1) * (offsetX * 8 - a->_width / 2);
// +1 as we appear to be 1 pixel away from the original interpreter
int ypos = _actorY - offsetY + 1;
@@ -1241,13 +1234,13 @@ byte C64CostumeRenderer::drawLimb(const Actor *a, int limb) {
byte color = data[y * width + x];
byte pcolor;
- int destX = xpos + (flipped ? -(x + 1) : x) * 8;
+ int destX = xpos + (a0->_limb_flipped[limb] ? -(x + 1) : x) * 8;
int destY = ypos + y;
if (destY >= 0 && destY < _out.h && destX >= 0 && destX < _out.w) {
byte *dst = (byte *)_out.pixels + destY * _out.pitch + destX;
byte *mask = _vm->getMaskBuffer(0, destY, _zbuf);
- if (flipped) {
+ if (a0->_limb_flipped[limb]) {
LINE(0, 0); LINE(2, 2); LINE(4, 4); LINE(6, 6);
} else {
LINE(6, 0); LINE(4, 2); LINE(2, 4); LINE(0, 6);
@@ -1258,7 +1251,7 @@ byte C64CostumeRenderer::drawLimb(const Actor *a, int limb) {
_draw_top = MIN(_draw_top, ypos);
_draw_bottom = MAX(_draw_bottom, ypos + height);
- if (flipped)
+ if (a0->_limb_flipped[limb])
_vm->markRectAsDirty(kMainVirtScreen, xpos - (width * 8), xpos, ypos, ypos + height, _actorID);
else
_vm->markRectAsDirty(kMainVirtScreen, xpos, xpos + (width * 8), ypos, ypos + height, _actorID);
@@ -1268,11 +1261,11 @@ byte C64CostumeRenderer::drawLimb(const Actor *a, int limb) {
#undef LINE
#undef MASK_AT
-void C64CostumeRenderer::setCostume(int costume, int shadow) {
+void V0CostumeRenderer::setCostume(int costume, int shadow) {
_loaded.loadCostume(costume);
}
-void C64CostumeLoader::loadCostume(int id) {
+void V0CostumeLoader::loadCostume(int id) {
const byte *ptr = _vm->getResourceAddress(rtCostume, id);
_id = id;
@@ -1282,166 +1275,128 @@ void C64CostumeLoader::loadCostume(int id) {
_numColors = 0;
_numAnim = 0;
_mirror = 0;
- _palette = &actorColorsMMC64[id];
+ _palette = &actorV0Colors[id];
_frameOffsets = _baseptr + READ_LE_UINT16(ptr + 5);
_dataOffsets = ptr;
_animCmds = _baseptr + READ_LE_UINT16(ptr + 7);
-
- _maxHeight = 0;
}
-void C64CostumeLoader::frameUpdate(ActorC64 *a, int cmd ) {
- byte limbFrames = 0;
+void V0CostumeLoader::costumeDecodeData(Actor *a, int frame, uint usemask) {
+ Actor_v0 *a0 = (Actor_v0 *)a;
+
+ if (!a->_costume)
+ return;
+
+ loadCostume(a->_costume);
+
+ // Invalid costume command?
+ if (a0->_costCommandNew == 0xFF || (a0->_costCommand == a0->_costCommandNew))
+ return;
+
+ a0->_costCommand = a0->_costCommandNew;
+
+ int cmd = a0->_costCommand;
+ byte limbFrameNumber = 0;
// Each costume-command has 8 limbs (0x2622)
cmd <<= 3;
- for (int limb = 0, pos = 0; limb < 8; ++limb, pos = 0) {
- // get a limb frames ptr from the costume command
- limbFrames = ((_animCmds + cmd)[limb]);
-
- // Dont change limb if entry is invalid
- if (limbFrames == 0xFF)
- continue;
+ for (int limb = 0; limb < 8; ++limb) {
- // Has limb frames ptr changed since last update?
- if (a->_cost.start[limb] == limbFrames)
- continue;
+ // get the frame number for the beginning of the costume command
+ limbFrameNumber = ((_animCmds + cmd)[limb]);
- // Set new limb command addresses
- a->_cost.start[limb] = limbFrames;
- a->_cost.frame[limb] = _frameOffsets[limb] + (limbFrames & 0x7f); // limb animation-frames ptr
+ // Is this limb flipped?
+ if (limbFrameNumber & 0x80) {
- // Get first entry of a limbs' frames
- byte frameStart = _frameOffsets[ a->_cost.frame[limb]];
+ // Invalid frame?
+ if (limbFrameNumber == 0xFF)
+ continue;
- // Loop each frame in this limb until we reach the end marker
- while (pos != 0xFF) { // This is just so we dont overflow
- byte frame = _frameOffsets[frameStart + pos];
+ // Store the limb frame number (clear the flipped status)
+ a->_cost.frame[limb] = (limbFrameNumber & 0x7f);
- // Each animation-frame until we find end
- if (frame == 0xFF)
- break;
+ if (a0->_limb_flipped[limb] != true)
+ a->_cost.start[limb] = 0xFFFF;
- byte ptrLow = _baseptr[frame];
- byte ptrHigh = ptrLow + _dataOffsets[4];
- int frameOffset = (_baseptr[ptrHigh] << 8) + _baseptr[ptrLow + 2]; // 0x23EF / 0x2400
+ a0->_limb_flipped[limb] = true;
- const byte *data = _baseptr + frameOffset;
+ } else {
+ //Store the limb frame number
+ a->_cost.frame[limb] = limbFrameNumber;
- if (data[3] > _maxHeight)
- _maxHeight = data[3] + 1;
+ if (a0->_limb_flipped[limb] != false)
+ a->_cost.start[limb] = 0xFFFF;
- ++pos;
+ a0->_limb_flipped[limb] = false;
}
- // Set ending position of limb frames
- a->_cost.end[limb] = pos - 1;
- a->_cost.curpos[limb] = 0;
- }
-}
-
-// based on 0x2BCA, doesn't match disassembly because 'oldDir' variable
-// is not the same value as stored in the original interpreter
-int C64CostumeLoader::dirToDirStop(int oldDir) {
- switch (oldDir) {
- case 0:
- return 4; // Left
- case 1:
- return 5; // Right
- case 2:
- return 6; // Face Camera
- case 3:
- return 7; // Face Away
+ // Set the repeat value
+ a0->_limbFrameRepeatNew[limb] = a0->_animFrameRepeat;
}
- // shouldnt' be reached
- return 4;
}
-void C64CostumeLoader::actorSpeak(ActorC64 *a, int &cmd) {
- if (v0ActorTalkArray[a->_number] & 0x80)
- return;
+byte V0CostumeLoader::getFrame(Actor *a, int limb) {
+ loadCostume(a->_costume);
- if ((a->_speaking & 0x80))
- cmd += 0x0C;
- else
- cmd += 0x10;
+ // Get the frame number for the current limb / Command
+ return _frameOffsets[_frameOffsets[limb] + a->_cost.start[limb]];
}
-void C64CostumeLoader::costumeDecodeData(Actor *a, int frame, uint usemask) {
- ActorC64 *A = (ActorC64 *)a;
- int dir = newDirToOldDir(a->getFacing());
- int command = dir;
-
- loadCostume(a->_costume);
-
- // Enable/Disable speaking flag
- if (frame == a->_talkStartFrame) {
- if (v0ActorTalkArray[a->_number] & 0x40)
- return;
+byte V0CostumeLoader::increaseAnims(Actor *a) {
+ Actor_v0 *a0 = (Actor_v0 *)a;
+ int i;
+ byte r = 0;
- A->_speaking = 1;
- return;
- }
- if (frame == a->_talkStopFrame) {
- A->_speaking = 0;
- return;
+ for (i = 0; i != 8; i++) {
+ a0->limbFrameCheck(i);
+ r += increaseAnim(a, i);
}
+ return r;
+}
- // Different command for stand frame
- if (frame == a->_standFrame)
- command = dirToDirStop(dir);
-
- // Update the limb frames
- frameUpdate(A, command);
-
- // Keep current command/frame mode
- A->_costCommand = dir;
- A->_costFrame = frame;
+byte V0CostumeLoader::increaseAnim(Actor *a, int limb) {
+ Actor_v0 *a0 = (Actor_v0 *)a;
+ const uint16 limbPrevious = a->_cost.curpos[limb]++;
- // Update 'speaking' frames?
- if (A->_speaking) {
- command = dir; // Incase standing frame was set as cmd
- actorSpeak(A, command);
+ loadCostume(a->_costume);
- // Update the limb speak frames
- frameUpdate(A, command);
- }
-}
+ // 0x2543
+ byte frame = _frameOffsets[a->_cost.curpos[limb] + a->_cost.active[limb]];
-byte C64CostumeLoader::increaseAnims(Actor *a) {
- ActorC64 *A = (ActorC64 *)a;
+ // Is this frame invalid?
+ if (frame == 0xFF) {
- // check if the actor speak flag has changed since last frame increase
- if (A->_speaking != A->_speakingPrev) {
- int cmd = A->_costCommand;
- A->_speakingPrev = A->_speaking;
+ // Repeat timer has reached 0?
+ if (a0->_limbFrameRepeat[limb] == 0) {
- actorSpeak(A, cmd);
+ // Use the previous frame
+ --a0->_cost.curpos[limb];
- // Update the limb frames
- frameUpdate(A, cmd);
- }
+ // Reset the comstume command
+ a0->_costCommandNew = 0xFF;
+ a0->_costCommand = 0xFF;
+
+ // Set the frame/start to invalid
+ a0->_cost.frame[limb] = 0xFFFF;
+ a0->_cost.start[limb] = 0xFFFF;
- if (A->_moving && _vm->_currentRoom != 1 && _vm->_currentRoom != 44) {
- if (a->_cost.soundPos == 0)
- a->_cost.soundCounter++;
+ } else {
- // Is this the correct location?
- // 0x073C
- if (v0ActorTalkArray[a->_number] & 0x3F)
- a->_cost.soundPos = (a->_cost.soundPos + 1) % 3;
- }
+ // Repeat timer enabled?
+ if (a0->_limbFrameRepeat[limb] != -1)
+ --a0->_limbFrameRepeat[limb];
- // increase each frame pos
- for (int limb = 0; limb < 8; ++limb) {
- if (a->_cost.curpos[limb] < a->_cost.end[limb])
- a->_cost.curpos[limb]++;
- else
+ // No, restart at frame 0
a->_cost.curpos[limb] = 0;
+ }
}
+ // Limb frame has changed?
+ if (limbPrevious == a->_cost.curpos[limb])
+ return 0;
+
return 1;
}
diff --git a/engines/scumm/costume.h b/engines/scumm/costume.h
index 3acf2a1f6c..4a21692ddb 100644
--- a/engines/scumm/costume.h
+++ b/engines/scumm/costume.h
@@ -67,20 +67,16 @@ protected:
byte increaseAnim(Actor *a, int slot);
};
-class C64CostumeLoader : public ClassicCostumeLoader {
+class V0CostumeLoader : public ClassicCostumeLoader {
public:
- C64CostumeLoader(ScummEngine *vm) : ClassicCostumeLoader(vm) {}
+ V0CostumeLoader(ScummEngine *vm) : ClassicCostumeLoader(vm) {}
void loadCostume(int id);
void costumeDecodeData(Actor *a, int frame, uint usemask);
byte increaseAnims(Actor *a);
-
- int _maxHeight;
+ byte getFrame(Actor *a, int limb);
protected:
- void actorSpeak(ActorC64 *a, int &cmd);
- int dirToDirStop(int oldDir);
- void frameUpdate(ActorC64 *A, int cmd);
-
+ byte increaseAnim(Actor *a, int limb);
};
class ClassicCostumeRenderer : public BaseCostumeRenderer {
@@ -135,12 +131,12 @@ public:
};
#endif
-class C64CostumeRenderer : public BaseCostumeRenderer {
+class V0CostumeRenderer : public BaseCostumeRenderer {
protected:
- C64CostumeLoader _loaded;
+ V0CostumeLoader _loaded;
public:
- C64CostumeRenderer(ScummEngine *vm) : BaseCostumeRenderer(vm), _loaded(vm) {}
+ V0CostumeRenderer(ScummEngine *vm) : BaseCostumeRenderer(vm), _loaded(vm) {}
void setPalette(uint16 *palette) {}
void setFacing(const Actor *a) {}
diff --git a/engines/scumm/cursor.cpp b/engines/scumm/cursor.cpp
index 36f06a4889..42f11498d9 100644
--- a/engines/scumm/cursor.cpp
+++ b/engines/scumm/cursor.cpp
@@ -636,7 +636,7 @@ void ScummEngine_v5::setBuiltinCursor(int idx) {
byte *dst2 = (_textSurfaceMultiplier == 2) ? dst1 + 16 * scl : dst1;
if (_outputPixelFormat.bytesPerPixel == 2) {
for (int b = 0; b < scl; b += 2) {
- *((uint16*)dst1) = *((uint16*)dst2) = color;
+ *((uint16 *)dst1) = *((uint16 *)dst2) = color;
dst1 += 2;
dst2 += 2;
}
diff --git a/engines/scumm/debugger.cpp b/engines/scumm/debugger.cpp
index 9cfdfbccc9..edcf2e6fea 100644
--- a/engines/scumm/debugger.cpp
+++ b/engines/scumm/debugger.cpp
@@ -292,7 +292,7 @@ bool ScummDebugger::Cmd_ImportRes(int argc, const char** argv) {
if (_vm->_game.features & GF_SMALL_HEADER) {
size = file.readUint16LE();
file.seek(-2, SEEK_CUR);
- } else if (_vm->_game.features & GF_SMALL_HEADER) {
+ } else if (_vm->_game.features & GF_SMALL_HEADER) { // FIXME: This never was executed
if (_vm->_game.version == 4)
file.seek(8, SEEK_CUR);
size = file.readUint32LE();
@@ -382,7 +382,8 @@ bool ScummDebugger::Cmd_Actor(int argc, const char **argv) {
DebugPrintf("Actor[%d].costume = %d\n", actnum, a->_costume);
}
} else if (!strcmp(argv[2], "name")) {
- DebugPrintf("Name of actor %d: %s\n", actnum, _vm->getObjOrActorName(actnum));
+ DebugPrintf("Name of actor %d: %s\n", actnum,
+ _vm->getObjOrActorName(_vm->actorToObj(actnum)));
} else if (!strcmp(argv[2], "condmask")) {
if (argc > 3) {
a->_heCondMask = value;
@@ -427,9 +428,10 @@ bool ScummDebugger::Cmd_PrintObjects(int argc, const char **argv) {
o = &(_vm->_objs[i]);
if (o->obj_nr == 0)
continue;
+ int classData = (_vm->_game.version != 0 ? _vm->_classData[o->obj_nr] : 0);
DebugPrintf("|%4d|%4d|%4d|%5d|%6d|%5d|%2d|$%08x|\n",
o->obj_nr, o->x_pos, o->y_pos, o->width, o->height, o->state,
- o->fl_object_index, _vm->_classData[o->obj_nr]);
+ o->fl_object_index, classData);
}
DebugPrintf("\n");
@@ -446,7 +448,7 @@ bool ScummDebugger::Cmd_Object(int argc, const char **argv) {
}
obj = atoi(argv[1]);
- if (obj >= _vm->_numGlobalObjects) {
+ if (_vm->_game.version != 0 && obj >= _vm->_numGlobalObjects) {
DebugPrintf("Object %d is out of range (range: 1 - %d)\n", obj, _vm->_numGlobalObjects);
return true;
}
diff --git a/engines/scumm/detection.cpp b/engines/scumm/detection.cpp
index 6da3578530..b47982af00 100644
--- a/engines/scumm/detection.cpp
+++ b/engines/scumm/detection.cpp
@@ -585,7 +585,6 @@ static void detectGames(const Common::FSList &fslist, Common::List<DetectorResul
// Print some debug info
int filesize = tmp->size();
- if (d.md5Entry->filesize != filesize)
debug(1, "SCUMM detector found matching file '%s' with MD5 %s, size %d\n",
file.c_str(), md5str.c_str(), filesize);
@@ -599,7 +598,7 @@ static void detectGames(const Common::FSList &fslist, Common::List<DetectorResul
}
if (isDiskImg)
- closeDiskImage((ScummDiskImage*)tmp);
+ closeDiskImage((ScummDiskImage *)tmp);
delete tmp;
}
@@ -649,8 +648,15 @@ static void detectGames(const Common::FSList &fslist, Common::List<DetectorResul
dr.language = detectLanguage(fslist, g->id);
// Detect if there are speech files in this unknown game
- //if (detectSpeech(fslist, g))
- // dr.game.guioptions &= ~GUIO_NOSPEECH;
+ if (detectSpeech(fslist, g)) {
+ if (strchr(dr.game.guioptions, GUIO_NOSPEECH[0]) != NULL) {
+ if (g->id == GID_MONKEY || g->id == GID_MONKEY2)
+ // TODO: This may need to be updated if something important gets added in the top detection table for these game ids
+ dr.game.guioptions = GUIO0();
+ else
+ warning("FIXME: fix NOSPEECH fallback");
+ }
+ }
// Add the game/variant to the candidates list if it is consistent
// with the file(s) we are seeing.
@@ -965,9 +971,6 @@ GameList ScummMetaEngine::detectGames(const Common::FSList &fslist) const {
::detectGames(fslist, results, 0);
- // TODO: We still don't handle the FM-TOWNS demos (like zakloom) very well.
- // In particular, they are detected as ZakTowns, which is bad.
-
for (Common::List<DetectorResult>::iterator
x = results.begin(); x != results.end(); ++x) {
const PlainGameDescriptor *g = findPlainGameDescriptor(x->game.gameid, gameDescriptions);
@@ -981,26 +984,6 @@ GameList ScummMetaEngine::detectGames(const Common::FSList &fslist) const {
// Based on generateComplexID() in advancedDetector.cpp.
dg["preferredtarget"] = generatePreferredTarget(*x);
- // HACK: Detect and distinguish the FM-TOWNS demos
- if (x->game.platform == Common::kPlatformFMTowns && (x->game.features & GF_DEMO)) {
- if (x->md5 == "2d388339d6050d8ccaa757b64633954e") {
- // Indy + Loom demo
- dg.description() = "Indiana Jones and the Last Crusade & Loom";
- dg.updateDesc(x->extra);
- dg["preferredtarget"] = "indyloom";
- } else if (x->md5 == "77f5c9cc0986eb729c1a6b4c8823bbae") {
- // Zak + Loom demo
- dg.description() = "Zak McKracken & Loom";
- dg.updateDesc(x->extra);
- dg["preferredtarget"] = "zakloom";
- } else if (x->md5 == "3938ee1aa4433fca9d9308c9891172b1") {
- // Indy + Zak demo
- dg.description() = "Indiana Jones and the Last Crusade & Zak McKracken";
- dg.updateDesc(x->extra);
- dg["preferredtarget"] = "indyzak";
- }
- }
-
dg.setGUIOptions(x->game.guioptions + MidiDriver::musicType2GUIO(x->game.midi));
dg.appendGUIOptions(getGameGUIOptionsDescriptionLanguage(x->language));
diff --git a/engines/scumm/detection.h b/engines/scumm/detection.h
index ad8b3cec12..b6dfa757bb 100644
--- a/engines/scumm/detection.h
+++ b/engines/scumm/detection.h
@@ -23,7 +23,8 @@
#ifndef SCUMM_DETECTION_H
#define SCUMM_DETECTION_H
-#include "common/util.h"
+#include "common/language.h"
+#include "common/platform.h"
namespace Scumm {
diff --git a/engines/scumm/detection_tables.h b/engines/scumm/detection_tables.h
index 31ba44b693..22708de2d3 100644
--- a/engines/scumm/detection_tables.h
+++ b/engines/scumm/detection_tables.h
@@ -24,6 +24,7 @@
#define SCUMM_DETECTION_TABLES_H
#include "engines/obsolete.h"
+#include "common/gui_options.h"
#include "common/rect.h"
#include "common/util.h"
@@ -70,6 +71,9 @@ static const PlainGameDescriptor gameDescriptions[] = {
{ "samnmax", "Sam & Max Hit the Road" },
{ "tentacle", "Day of the Tentacle" },
{ "zak", "Zak McKracken and the Alien Mindbenders" },
+ { "indyloom", "Indiana Jones and the Last Crusade & Loom" },
+ { "indyzak", "Indiana Jones and the Last Crusade & Zak McKracken" },
+ { "zakloom", "Zak McKracken & Loom" },
#ifdef ENABLE_SCUMM_7_8
{ "ft", "Full Throttle" },
@@ -203,25 +207,28 @@ static const GameSettings gameVariantsTable[] = {
{"maniac", "C64", 0, GID_MANIAC, 0, 0, MDT_C64, 0, Common::kPlatformC64, GUIO2(GUIO_NOSPEECH, GUIO_NOMIDI) },
{"maniac", "V1", "v1", GID_MANIAC, 1, 0, MDT_PCSPK | MDT_PCJR, 0, Common::kPlatformPC, GUIO2(GUIO_NOSPEECH, GUIO_NOMIDI)},
{"maniac", "V1 Demo", "v1", GID_MANIAC, 1, 0, MDT_PCSPK | MDT_PCJR, GF_DEMO, Common::kPlatformPC, GUIO2(GUIO_NOSPEECH, GUIO_NOMIDI)},
- {"maniac", "NES", 0, GID_MANIAC, 1, 0, MDT_NONE, 0, Common::kPlatformNES, GUIO2(GUIO_NOSPEECH, GUIO_NOMIDI)},
+ {"maniac", "NES", 0, GID_MANIAC, 1, 0, MDT_NONE, 0, Common::kPlatformNES, GUIO3(GUIO_NOSPEECH, GUIO_NOMIDI, GUIO_NOASPECT)},
{"maniac", "V2", "v2", GID_MANIAC, 2, 0, MDT_PCSPK | MDT_PCJR, 0, UNK, GUIO2(GUIO_NOSPEECH, GUIO_NOMIDI)},
{"maniac", "V2 Demo", "v2", GID_MANIAC, 2, 0, MDT_PCSPK | MDT_PCJR, GF_DEMO, Common::kPlatformPC, GUIO2(GUIO_NOSPEECH, GUIO_NOMIDI)},
{"zak", "V1", "v1", GID_ZAK, 1, 0, MDT_PCSPK | MDT_PCJR, 0, UNK, GUIO2(GUIO_NOSPEECH, GUIO_NOMIDI)},
{"zak", "V2", "v2", GID_ZAK, 2, 0, MDT_PCSPK | MDT_PCJR, 0, UNK, GUIO2(GUIO_NOSPEECH, GUIO_NOMIDI)},
- {"zak", "FM-TOWNS", 0, GID_ZAK, 3, 0, MDT_TOWNS, GF_OLD256 | GF_AUDIOTRACKS, Common::kPlatformFMTowns, GUIO3(GUIO_NOSPEECH, GUIO_NOMIDI, GUIO_MIDITOWNS)},
+ {"zak", "FM-TOWNS", 0, GID_ZAK, 3, 0, MDT_TOWNS, GF_OLD256 | GF_AUDIOTRACKS, Common::kPlatformFMTowns, GUIO4(GUIO_NOSPEECH, GUIO_NOMIDI, GUIO_MIDITOWNS, GUIO_NOASPECT)},
+ {"zakloom", "FM-TOWNS", 0, GID_ZAK, 3, 0, MDT_TOWNS, GF_OLD256 | GF_AUDIOTRACKS, Common::kPlatformFMTowns, GUIO4(GUIO_NOSPEECH, GUIO_NOMIDI, GUIO_MIDITOWNS, GUIO_NOASPECT)},
+ {"indyloom", "FM-TOWNS", 0, GID_ZAK, 3, 0, MDT_TOWNS, GF_OLD256 | GF_AUDIOTRACKS, Common::kPlatformFMTowns, GUIO4(GUIO_NOSPEECH, GUIO_NOMIDI, GUIO_MIDITOWNS, GUIO_NOASPECT)},
+ {"indyzak", "FM-TOWNS", 0, GID_ZAK, 3, 0, MDT_TOWNS, GF_OLD256 | GF_AUDIOTRACKS, Common::kPlatformFMTowns, GUIO4(GUIO_NOSPEECH, GUIO_NOMIDI, GUIO_MIDITOWNS, GUIO_NOASPECT)},
{"indy3", "EGA", "ega", GID_INDY3, 3, 0, MDT_PCSPK | MDT_PCJR | MDT_CMS | MDT_ADLIB, 0, UNK, GUIO2(GUIO_NOSPEECH, GUIO_NOMIDI)},
{"indy3", "No AdLib", "ega", GID_INDY3, 3, 0, MDT_PCSPK | MDT_PCJR, 0, UNK, GUIO2(GUIO_NOSPEECH, GUIO_NOMIDI)},
{"indy3", "VGA", "vga", GID_INDY3, 3, 0, MDT_PCSPK | MDT_PCJR | MDT_CMS | MDT_ADLIB, GF_OLD256 | GF_FEW_LOCALS, Common::kPlatformPC, GUIO2(GUIO_NOSPEECH, GUIO_NOMIDI)},
- {"indy3", "FM-TOWNS", 0, GID_INDY3, 3, 0, MDT_TOWNS, GF_OLD256 | GF_FEW_LOCALS | GF_AUDIOTRACKS, Common::kPlatformFMTowns, GUIO3(GUIO_NOSPEECH, GUIO_NOMIDI, GUIO_MIDITOWNS)},
+ {"indy3", "FM-TOWNS", 0, GID_INDY3, 3, 0, MDT_TOWNS, GF_OLD256 | GF_FEW_LOCALS | GF_AUDIOTRACKS, Common::kPlatformFMTowns, GUIO4(GUIO_NOSPEECH, GUIO_NOMIDI, GUIO_MIDITOWNS, GUIO_NOASPECT)},
{"loom", "EGA", "ega", GID_LOOM, 3, 0, MDT_PCSPK | MDT_PCJR | MDT_CMS | MDT_ADLIB | MDT_MIDI | MDT_PREFER_MT32, 0, UNK, GUIO1(GUIO_NOSPEECH)},
{"loom", "No AdLib", "ega", GID_LOOM, 3, 0, MDT_PCSPK | MDT_PCJR | MDT_CMS, 0, UNK, GUIO2(GUIO_NOSPEECH, GUIO_NOMIDI)},
#ifdef USE_RGB_COLOR
{"loom", "PC-Engine", 0, GID_LOOM, 3, 0, MDT_NONE, GF_AUDIOTRACKS | GF_OLD256 | GF_16BIT_COLOR, Common::kPlatformPCEngine, GUIO2(GUIO_NOSPEECH, GUIO_NOMIDI)},
#endif
- {"loom", "FM-TOWNS", 0, GID_LOOM, 3, 0, MDT_TOWNS, GF_AUDIOTRACKS | GF_OLD256, Common::kPlatformFMTowns, GUIO3(GUIO_NOSPEECH, GUIO_NOMIDI, GUIO_MIDITOWNS)},
+ {"loom", "FM-TOWNS", 0, GID_LOOM, 3, 0, MDT_TOWNS, GF_AUDIOTRACKS | GF_OLD256, Common::kPlatformFMTowns, GUIO4(GUIO_NOSPEECH, GUIO_NOMIDI, GUIO_MIDITOWNS, GUIO_NOASPECT)},
{"loom", "VGA", "vga", GID_LOOM, 4, 0, MDT_NONE, GF_AUDIOTRACKS, Common::kPlatformPC, GUIO2(GUIO_NOSPEECH, GUIO_NOMIDI)},
{"pass", 0, 0, GID_PASS, 4, 0, MDT_PCSPK | MDT_PCJR | MDT_CMS | MDT_ADLIB, GF_16COLOR, Common::kPlatformPC, GUIO2(GUIO_NOSPEECH, GUIO_NOMIDI)},
@@ -231,20 +238,20 @@ static const GameSettings gameVariantsTable[] = {
{"monkey", "No AdLib", "ega", GID_MONKEY_EGA, 4, 0, MDT_PCSPK | MDT_PCJR, GF_16COLOR, Common::kPlatformAtariST, GUIO2(GUIO_NOSPEECH, GUIO_NOMIDI)},
{"monkey", "Demo", "ega", GID_MONKEY_EGA, 4, 0, MDT_PCSPK | MDT_PCJR | MDT_ADLIB, GF_16COLOR, Common::kPlatformPC, GUIO2(GUIO_NOSPEECH, GUIO_NOMIDI)},
{"monkey", "CD", 0, GID_MONKEY, 5, 0, MDT_ADLIB, GF_AUDIOTRACKS, UNK, GUIO2(GUIO_NOSPEECH, GUIO_NOMIDI)},
- {"monkey", "FM-TOWNS", 0, GID_MONKEY, 5, 0, MDT_TOWNS, GF_AUDIOTRACKS, Common::kPlatformFMTowns, GUIO3(GUIO_NOSPEECH, GUIO_NOMIDI, GUIO_MIDITOWNS)},
+ {"monkey", "FM-TOWNS", 0, GID_MONKEY, 5, 0, MDT_TOWNS, GF_AUDIOTRACKS, Common::kPlatformFMTowns, GUIO4(GUIO_NOSPEECH, GUIO_NOMIDI, GUIO_MIDITOWNS, GUIO_NOASPECT)},
{"monkey", "SEGA", 0, GID_MONKEY, 5, 0, MDT_NONE, GF_AUDIOTRACKS, Common::kPlatformSegaCD, GUIO2(GUIO_NOSPEECH, GUIO_NOMIDI)},
{"monkey2", "", 0, GID_MONKEY2, 5, 0, MDT_PCSPK | MDT_ADLIB | MDT_MIDI | MDT_PREFER_MT32, 0, UNK, GUIO1(GUIO_NOSPEECH)},
- {"monkey2", "FM-TOWNS", 0, GID_MONKEY2, 5, 0, MDT_PCSPK | MDT_TOWNS | MDT_ADLIB | MDT_MIDI | MDT_PREFER_MT32, 0, Common::kPlatformFMTowns, GUIO4(GUIO_NOSPEECH, GUIO_MIDITOWNS, GUIO_MIDIADLIB, GUIO_MIDIMT32)},
+ {"monkey2", "FM-TOWNS", 0, GID_MONKEY2, 5, 0, MDT_PCSPK | MDT_TOWNS | MDT_ADLIB | MDT_MIDI | MDT_PREFER_MT32, 0, Common::kPlatformFMTowns, GUIO5(GUIO_NOSPEECH, GUIO_MIDITOWNS, GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_NOASPECT)},
- {"atlantis", "", 0, GID_INDY4, 5, 0, MDT_PCSPK | MDT_ADLIB | MDT_MIDI | MDT_PREFER_MT32, 0, UNK, GUIO1(GUIO_NONE)},
+ {"atlantis", "", 0, GID_INDY4, 5, 0, MDT_PCSPK | MDT_ADLIB | MDT_MIDI | MDT_PREFER_MT32, 0, UNK, GUIO0()},
{"atlantis", "Floppy", 0, GID_INDY4, 5, 0, MDT_PCSPK | MDT_ADLIB | MDT_MIDI | MDT_PREFER_MT32, 0, UNK, GUIO1(GUIO_NOSPEECH)},
- {"atlantis", "FM-TOWNS", 0, GID_INDY4, 5, 0, MDT_TOWNS | MDT_ADLIB | MDT_MIDI | MDT_PREFER_MT32, 0, Common::kPlatformFMTowns, GUIO3(GUIO_MIDITOWNS, GUIO_MIDIADLIB, GUIO_MIDIMT32)},
+ {"atlantis", "FM-TOWNS", 0, GID_INDY4, 5, 0, MDT_TOWNS | MDT_ADLIB | MDT_MIDI | MDT_PREFER_MT32, 0, Common::kPlatformFMTowns, GUIO4(GUIO_MIDITOWNS, GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_NOASPECT)},
- {"tentacle", "", 0, GID_TENTACLE, 6, 0, MDT_ADLIB | MDT_MIDI | MDT_PREFER_GM, GF_USE_KEY, UNK, GUIO1(GUIO_NONE)},
+ {"tentacle", "", 0, GID_TENTACLE, 6, 0, MDT_ADLIB | MDT_MIDI | MDT_PREFER_GM, GF_USE_KEY, UNK, GUIO0()},
{"tentacle", "Floppy", 0, GID_TENTACLE, 6, 0, MDT_ADLIB | MDT_MIDI | MDT_PREFER_GM, GF_USE_KEY, UNK, GUIO1(GUIO_NOSPEECH)},
- {"samnmax", "", 0, GID_SAMNMAX, 6, 0, MDT_ADLIB | MDT_MIDI | MDT_PREFER_GM, GF_USE_KEY, UNK, GUIO1(GUIO_NONE)},
+ {"samnmax", "", 0, GID_SAMNMAX, 6, 0, MDT_ADLIB | MDT_MIDI | MDT_PREFER_GM, GF_USE_KEY, UNK, GUIO0()},
{"samnmax", "Floppy", 0, GID_SAMNMAX, 6, 0, MDT_ADLIB | MDT_MIDI | MDT_PREFER_GM, GF_USE_KEY, UNK, GUIO1(GUIO_NOSPEECH)},
#ifdef ENABLE_SCUMM_7_8
@@ -252,7 +259,7 @@ static const GameSettings gameVariantsTable[] = {
{"dig", 0, 0, GID_DIG, 7, 0, MDT_NONE, 0, UNK, GUIO1(GUIO_NOMIDI)},
- {"comi", 0, 0, GID_CMI, 8, 0, MDT_NONE, 0, Common::kPlatformWindows, GUIO1(GUIO_NOMIDI)},
+ {"comi", 0, 0, GID_CMI, 8, 0, MDT_NONE, 0, Common::kPlatformWindows, GUIO2(GUIO_NOMIDI, GUIO_NOASPECT)},
#endif
// Humongous Entertainment Scumm Version 6
@@ -284,122 +291,122 @@ static const GameSettings gameVariantsTable[] = {
// Humongous Entertainment Scumm Version 7.1
// The first version to use 640x480 resolution and wizImages
// There are also 7.1 versions of freddemo, airdemo and farmdemo
- {"catalog", "", 0, GID_HEGAME, 6, 71, MDT_NONE, GF_USE_KEY, UNK, GUIO2(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI)},
- {"freddi", "", 0, GID_HEGAME, 6, 71, MDT_NONE, GF_USE_KEY, UNK, GUIO2(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI)},
+ {"catalog", "", 0, GID_HEGAME, 6, 71, MDT_NONE, GF_USE_KEY, UNK, GUIO3(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI, GUIO_NOASPECT)},
+ {"freddi", "", 0, GID_HEGAME, 6, 71, MDT_NONE, GF_USE_KEY, UNK, GUIO3(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI, GUIO_NOASPECT)},
// Humongous Entertainment Scumm Version 7.2
- {"airport", "", 0, GID_HEGAME, 6, 72, MDT_NONE, GF_USE_KEY, UNK, GUIO2(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI)},
+ {"airport", "", 0, GID_HEGAME, 6, 72, MDT_NONE, GF_USE_KEY, UNK, GUIO3(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI, GUIO_NOASPECT)},
// Changed o_getResourceSize to cover all resource types
- {"farm", "", 0, GID_HEGAME, 6, 73, MDT_NONE, GF_USE_KEY, UNK, GUIO2(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI)},
- {"puttzoo", "", 0, GID_HEGAME, 6, 73, MDT_NONE, GF_USE_KEY, UNK, GUIO2(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI)},
+ {"farm", "", 0, GID_HEGAME, 6, 73, MDT_NONE, GF_USE_KEY, UNK, GUIO3(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI, GUIO_NOASPECT)},
+ {"puttzoo", "", 0, GID_HEGAME, 6, 73, MDT_NONE, GF_USE_KEY, UNK, GUIO3(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI, GUIO_NOASPECT)},
// Added VAR_PLATFORM variable
- {"jungle", "", 0, GID_HEGAME, 6, 74, MDT_NONE, GF_USE_KEY, UNK, GUIO2(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI)},
+ {"jungle", "", 0, GID_HEGAME, 6, 74, MDT_NONE, GF_USE_KEY, UNK, GUIO3(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI, GUIO_NOASPECT)},
// Humongous Entertainment Scumm Version 8.0 ? Scummsrc.80
- {"freddi2", "", 0, GID_HEGAME, 6, 80, MDT_NONE, GF_USE_KEY, UNK, GUIO2(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI)},
- {"pajama", "", 0, GID_HEGAME, 6, 80, MDT_NONE, GF_USE_KEY, UNK, GUIO2(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI)},
+ {"freddi2", "", 0, GID_HEGAME, 6, 80, MDT_NONE, GF_USE_KEY, UNK, GUIO3(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI, GUIO_NOASPECT)},
+ {"pajama", "", 0, GID_HEGAME, 6, 80, MDT_NONE, GF_USE_KEY, UNK, GUIO3(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI, GUIO_NOASPECT)},
- {"balloon", "", 0, GID_HEGAME, 6, 80, MDT_NONE, GF_USE_KEY, UNK, GUIO2(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI)},
- {"dog", "", 0, GID_HEGAME, 6, 80, MDT_NONE, GF_USE_KEY, UNK, GUIO2(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI)},
- {"maze", "", 0, GID_HEGAME, 6, 80, MDT_NONE, GF_USE_KEY, UNK, GUIO2(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI)},
+ {"balloon", "", 0, GID_HEGAME, 6, 80, MDT_NONE, GF_USE_KEY, UNK, GUIO3(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI, GUIO_NOASPECT)},
+ {"dog", "", 0, GID_HEGAME, 6, 80, MDT_NONE, GF_USE_KEY, UNK, GUIO3(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI, GUIO_NOASPECT)},
+ {"maze", "", 0, GID_HEGAME, 6, 80, MDT_NONE, GF_USE_KEY, UNK, GUIO3(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI, GUIO_NOASPECT)},
- {"water", "", 0, GID_HEGAME, 6, 80, MDT_NONE, GF_USE_KEY, UNK, GUIO2(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI)},
+ {"water", "", 0, GID_HEGAME, 6, 80, MDT_NONE, GF_USE_KEY, UNK, GUIO3(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI, GUIO_NOASPECT)},
// condMaskCode value changed in setUserCondition & setTalkCondition
- {"putttime", "", 0, GID_HEGAME, 6, 85, MDT_NONE, GF_USE_KEY, UNK, GUIO2(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI)},
- {"socks", "", 0, GID_HEGAME, 6, 85, MDT_NONE, GF_USE_KEY, UNK, GUIO2(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI)},
+ {"putttime", "", 0, GID_HEGAME, 6, 85, MDT_NONE, GF_USE_KEY, UNK, GUIO3(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI, GUIO_NOASPECT)},
+ {"socks", "", 0, GID_HEGAME, 6, 85, MDT_NONE, GF_USE_KEY, UNK, GUIO3(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI, GUIO_NOASPECT)},
// Humongous Entertainment Scumm Version 9.0 ? Scummsys.90
- {"baseball", "", 0, GID_HEGAME, 6, 90, MDT_NONE, GF_USE_KEY, UNK, GUIO2(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI)},
- {"thinkerk", "", 0, GID_HEGAME, 6, 90, MDT_NONE, GF_USE_KEY, UNK, GUIO2(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI)},
- {"thinker1", "", 0, GID_HEGAME, 6, 90, MDT_NONE, GF_USE_KEY, UNK, GUIO2(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI)},
- {"spyfox", "", 0, GID_HEGAME, 6, 90, MDT_NONE, GF_USE_KEY, UNK, GUIO2(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI)},
+ {"baseball", "", 0, GID_HEGAME, 6, 90, MDT_NONE, GF_USE_KEY, UNK, GUIO3(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI, GUIO_NOASPECT)},
+ {"thinkerk", "", 0, GID_HEGAME, 6, 90, MDT_NONE, GF_USE_KEY, UNK, GUIO3(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI, GUIO_NOASPECT)},
+ {"thinker1", "", 0, GID_HEGAME, 6, 90, MDT_NONE, GF_USE_KEY, UNK, GUIO3(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI, GUIO_NOASPECT)},
+ {"spyfox", "", 0, GID_HEGAME, 6, 90, MDT_NONE, GF_USE_KEY, UNK, GUIO3(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI, GUIO_NOASPECT)},
- {"freddi3", "", 0, GID_FREDDI3, 6, 90, MDT_NONE, GF_USE_KEY, UNK, GUIO2(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI)},
- {"freddi3", "HE 99", 0, GID_FREDDI3, 6, 99, MDT_NONE, GF_USE_KEY, UNK, GUIO2(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI)},
+ {"freddi3", "", 0, GID_FREDDI3, 6, 90, MDT_NONE, GF_USE_KEY, UNK, GUIO3(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI, GUIO_NOASPECT)},
+ {"freddi3", "HE 99", 0, GID_FREDDI3, 6, 99, MDT_NONE, GF_USE_KEY, UNK, GUIO3(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI, GUIO_NOASPECT)},
// Humongous Entertainment Scumm Version 9.5 ? Scummsys.95
- {"pajama2", "", 0, GID_HEGAME, 6, 95, MDT_NONE, GF_USE_KEY, UNK, GUIO2(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI)},
- {"chase", "", 0, GID_HEGAME, 6, 95, MDT_NONE, GF_USE_KEY, UNK, GUIO2(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI)},
+ {"pajama2", "", 0, GID_HEGAME, 6, 95, MDT_NONE, GF_USE_KEY, UNK, GUIO3(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI, GUIO_NOASPECT)},
+ {"chase", "", 0, GID_HEGAME, 6, 95, MDT_NONE, GF_USE_KEY, UNK, GUIO3(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI, GUIO_NOASPECT)},
// Humongous Entertainment Scumm Version 9.8 ? Scummsys.98
// these and later games can easily be identified by the .(a) file instead of a .he1
// and INIB chunk in the .he0
- {"lost", "", 0, GID_HEGAME, 6, 98, MDT_NONE, GF_USE_KEY, UNK, GUIO2(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI)},
+ {"lost", "", 0, GID_HEGAME, 6, 98, MDT_NONE, GF_USE_KEY, UNK, GUIO3(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI, GUIO_NOASPECT)},
- {"puttrace", "HE 98", 0, GID_PUTTRACE, 6, 98, MDT_NONE, GF_USE_KEY, UNK, GUIO2(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI)},
- {"puttrace", "HE 98.5", 0, GID_PUTTRACE, 6, 98, MDT_NONE, GF_USE_KEY | GF_HE_985, UNK, GUIO2(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI)},
- {"puttrace", "HE 99", 0, GID_PUTTRACE, 6, 99, MDT_NONE, GF_USE_KEY, UNK, GUIO2(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI)},
+ {"puttrace", "HE 98", 0, GID_PUTTRACE, 6, 98, MDT_NONE, GF_USE_KEY, UNK, GUIO3(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI, GUIO_NOASPECT)},
+ {"puttrace", "HE 98.5", 0, GID_PUTTRACE, 6, 98, MDT_NONE, GF_USE_KEY | GF_HE_985, UNK, GUIO3(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI, GUIO_NOASPECT)},
+ {"puttrace", "HE 99", 0, GID_PUTTRACE, 6, 99, MDT_NONE, GF_USE_KEY, UNK, GUIO3(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI, GUIO_NOASPECT)},
- {"bluesabctime", "", 0, GID_HEGAME, 6, 98, MDT_NONE, GF_USE_KEY, UNK, GUIO2(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI)},
- {"BluesBirthday", "", 0, GID_HEGAME, 6, 98, MDT_NONE, GF_USE_KEY, UNK, GUIO2(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI)},
- {"BluesBirthday", "Red", 0, GID_BIRTHDAYRED, 6, 98, MDT_NONE, GF_USE_KEY, UNK, GUIO2(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI)},
- {"BluesBirthday", "Yellow", 0, GID_BIRTHDAYYELLOW, 6, 98, MDT_NONE, GF_USE_KEY, UNK, GUIO2(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI)},
- {"soccer", "", 0, GID_SOCCER, 6, 98, MDT_NONE, GF_USE_KEY, UNK, GUIO2(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI)},
+ {"bluesabctime", "", 0, GID_HEGAME, 6, 98, MDT_NONE, GF_USE_KEY, UNK, GUIO3(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI, GUIO_NOASPECT)},
+ {"BluesBirthday", "", 0, GID_HEGAME, 6, 98, MDT_NONE, GF_USE_KEY, UNK, GUIO3(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI, GUIO_NOASPECT)},
+ {"BluesBirthday", "Red", 0, GID_BIRTHDAYRED, 6, 98, MDT_NONE, GF_USE_KEY, UNK, GUIO3(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI, GUIO_NOASPECT)},
+ {"BluesBirthday", "Yellow", 0, GID_BIRTHDAYYELLOW, 6, 98, MDT_NONE, GF_USE_KEY, UNK, GUIO3(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI, GUIO_NOASPECT)},
+ {"soccer", "", 0, GID_SOCCER, 6, 98, MDT_NONE, GF_USE_KEY, UNK, GUIO3(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI, GUIO_NOASPECT)},
// Global scripts increased to 2048
- {"blues123time", "", 0, GID_HEGAME, 6, 98, MDT_NONE, GF_USE_KEY | GF_HE_985, UNK, GUIO2(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI)},
- {"freddi4", "", 0, GID_HEGAME, 6, 98, MDT_NONE, GF_USE_KEY | GF_HE_985, UNK, GUIO2(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI)},
- {"freddi4", "unenc", 0, GID_HEGAME, 6, 98, MDT_NONE, GF_HE_985, UNK, GUIO2(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI)},
+ {"blues123time", "", 0, GID_HEGAME, 6, 98, MDT_NONE, GF_USE_KEY | GF_HE_985, UNK, GUIO3(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI, GUIO_NOASPECT)},
+ {"freddi4", "", 0, GID_HEGAME, 6, 98, MDT_NONE, GF_USE_KEY | GF_HE_985, UNK, GUIO3(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI, GUIO_NOASPECT)},
+ {"freddi4", "unenc", 0, GID_HEGAME, 6, 98, MDT_NONE, GF_HE_985, UNK, GUIO3(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI, GUIO_NOASPECT)},
// Humongous Entertainment Scumm Version 9.9 ? Scummsys.99
- {"football", 0, 0, GID_FOOTBALL, 6, 99, MDT_NONE, GF_USE_KEY, UNK, GUIO2(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI)},
- {"pajama3", 0, 0, GID_HEGAME, 6, 99, MDT_NONE, GF_USE_KEY | GF_HE_LOCALIZED, UNK, GUIO2(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI)},
- {"puttcircus", 0, 0, GID_HEGAME, 6, 99, MDT_NONE, GF_USE_KEY | GF_HE_LOCALIZED, UNK, GUIO2(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI)},
- {"spyfox2", 0, 0, GID_HEGAME, 6, 99, MDT_NONE, GF_USE_KEY | GF_HE_LOCALIZED, UNK, GUIO2(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI)},
- {"mustard", 0, 0, GID_HEGAME, 6, 99, MDT_NONE, GF_USE_KEY | GF_HE_LOCALIZED, UNK, GUIO2(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI)},
+ {"football", 0, 0, GID_FOOTBALL, 6, 99, MDT_NONE, GF_USE_KEY, UNK, GUIO3(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI, GUIO_NOASPECT)},
+ {"pajama3", 0, 0, GID_HEGAME, 6, 99, MDT_NONE, GF_USE_KEY | GF_HE_LOCALIZED, UNK, GUIO3(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI, GUIO_NOASPECT)},
+ {"puttcircus", 0, 0, GID_HEGAME, 6, 99, MDT_NONE, GF_USE_KEY | GF_HE_LOCALIZED, UNK, GUIO3(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI, GUIO_NOASPECT)},
+ {"spyfox2", 0, 0, GID_HEGAME, 6, 99, MDT_NONE, GF_USE_KEY | GF_HE_LOCALIZED, UNK, GUIO3(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI, GUIO_NOASPECT)},
+ {"mustard", 0, 0, GID_HEGAME, 6, 99, MDT_NONE, GF_USE_KEY | GF_HE_LOCALIZED, UNK, GUIO3(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI, GUIO_NOASPECT)},
// Added the use of fonts
- {"FreddisFunShop", 0, 0, GID_FUNSHOP, 6, 99, MDT_NONE, GF_USE_KEY | GF_HE_LOCALIZED, UNK, GUIO2(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI)},
- {"SamsFunShop", 0, 0, GID_FUNSHOP, 6, 99, MDT_NONE, GF_USE_KEY | GF_HE_LOCALIZED, UNK, GUIO2(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI)},
- {"PuttsFunShop", 0, 0, GID_FUNSHOP, 6, 99, MDT_NONE, GF_USE_KEY | GF_HE_LOCALIZED, UNK, GUIO2(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI)},
+ {"FreddisFunShop", 0, 0, GID_FUNSHOP, 6, 99, MDT_NONE, GF_USE_KEY | GF_HE_LOCALIZED, UNK, GUIO3(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI, GUIO_NOASPECT)},
+ {"SamsFunShop", 0, 0, GID_FUNSHOP, 6, 99, MDT_NONE, GF_USE_KEY | GF_HE_LOCALIZED, UNK, GUIO3(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI, GUIO_NOASPECT)},
+ {"PuttsFunShop", 0, 0, GID_FUNSHOP, 6, 99, MDT_NONE, GF_USE_KEY | GF_HE_LOCALIZED, UNK, GUIO3(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI, GUIO_NOASPECT)},
// Added the use of smacker videos
- {"BluesTreasureHunt", 0, 0, GID_TREASUREHUNT, 6, 99, MDT_NONE, GF_HE_LOCALIZED | GF_USE_KEY, UNK, GUIO2(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI)},
+ {"BluesTreasureHunt", 0, 0, GID_TREASUREHUNT, 6, 99, MDT_NONE, GF_HE_LOCALIZED | GF_USE_KEY, UNK, GUIO3(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI, GUIO_NOASPECT)},
#ifdef USE_RGB_COLOR
// Added 16bit color
- {"arttime", 0, 0, GID_HEGAME, 6, 99, MDT_NONE, GF_USE_KEY | GF_HE_LOCALIZED | GF_16BIT_COLOR, UNK, GUIO2(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI)},
- {"baseball2001", 0, 0, GID_BASEBALL2001, 6, 99, MDT_NONE, GF_USE_KEY | GF_16BIT_COLOR, UNK, GUIO2(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI)},
- {"readtime", 0, 0, GID_HEGAME, 6, 99, MDT_NONE, GF_USE_KEY | GF_HE_LOCALIZED | GF_16BIT_COLOR, UNK, GUIO2(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI)},
- {"SoccerMLS", 0, 0, GID_SOCCERMLS, 6, 99, MDT_NONE, GF_USE_KEY | GF_HE_LOCALIZED | GF_16BIT_COLOR, UNK, GUIO2(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI)},
- {"spyozon", 0, 0, GID_HEGAME, 6, 99, MDT_NONE, GF_USE_KEY | GF_HE_LOCALIZED | GF_16BIT_COLOR, UNK, GUIO2(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI)},
+ {"arttime", 0, 0, GID_HEGAME, 6, 99, MDT_NONE, GF_USE_KEY | GF_HE_LOCALIZED | GF_16BIT_COLOR, UNK, GUIO3(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI, GUIO_NOASPECT)},
+ {"baseball2001", 0, 0, GID_BASEBALL2001, 6, 99, MDT_NONE, GF_USE_KEY | GF_16BIT_COLOR, UNK, GUIO3(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI, GUIO_NOASPECT)},
+ {"readtime", 0, 0, GID_HEGAME, 6, 99, MDT_NONE, GF_USE_KEY | GF_HE_LOCALIZED | GF_16BIT_COLOR, UNK, GUIO3(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI, GUIO_NOASPECT)},
+ {"SoccerMLS", 0, 0, GID_SOCCERMLS, 6, 99, MDT_NONE, GF_USE_KEY | GF_HE_LOCALIZED | GF_16BIT_COLOR, UNK, GUIO3(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI, GUIO_NOASPECT)},
+ {"spyozon", 0, 0, GID_HEGAME, 6, 99, MDT_NONE, GF_USE_KEY | GF_HE_LOCALIZED | GF_16BIT_COLOR, UNK, GUIO3(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI, GUIO_NOASPECT)},
- {"freddicove", "", 0, GID_HEGAME, 6, 99, MDT_NONE, GF_USE_KEY | GF_HE_LOCALIZED | GF_16BIT_COLOR, UNK, GUIO2(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI)},
- {"freddicove", "unenc", 0, GID_HEGAME, 6, 99, MDT_NONE, GF_HE_LOCALIZED | GF_16BIT_COLOR, UNK, GUIO2(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI)},
- {"freddicove", "HE 100", 0, GID_HEGAME, 6, 100, MDT_NONE, GF_USE_KEY | GF_HE_LOCALIZED | GF_16BIT_COLOR, UNK, GUIO2(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI)},
+ {"freddicove", "", 0, GID_HEGAME, 6, 99, MDT_NONE, GF_USE_KEY | GF_HE_LOCALIZED | GF_16BIT_COLOR, UNK, GUIO3(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI, GUIO_NOASPECT)},
+ {"freddicove", "unenc", 0, GID_HEGAME, 6, 99, MDT_NONE, GF_HE_LOCALIZED | GF_16BIT_COLOR, UNK, GUIO3(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI, GUIO_NOASPECT)},
+ {"freddicove", "HE 100", 0, GID_HEGAME, 6, 100, MDT_NONE, GF_USE_KEY | GF_HE_LOCALIZED | GF_16BIT_COLOR, UNK, GUIO3(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI, GUIO_NOASPECT)},
// Restructured the Scumm engine
- {"pjgames", 0, 0, GID_HEGAME, 6, 100, MDT_NONE, GF_USE_KEY | GF_HE_LOCALIZED | GF_16BIT_COLOR, UNK, GUIO2(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI)},
+ {"pjgames", 0, 0, GID_HEGAME, 6, 100, MDT_NONE, GF_USE_KEY | GF_HE_LOCALIZED | GF_16BIT_COLOR, UNK, GUIO3(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI, GUIO_NOASPECT)},
// Added the use of bink videos
- {"Baseball2003", 0, 0, GID_HEGAME, 6, 100, MDT_NONE, GF_USE_KEY | GF_16BIT_COLOR, UNK, GUIO2(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI)},
- {"basketball", 0, 0, GID_BASKETBALL, 6, 100, MDT_NONE, GF_USE_KEY| GF_16BIT_COLOR, UNK, GUIO2(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI)},
- {"football2002", 0, 0, GID_FOOTBALL, 6, 100, MDT_NONE, GF_USE_KEY | GF_16BIT_COLOR, UNK, GUIO2(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI)},
- {"Soccer2004", 0, 0, GID_SOCCER2004, 6, 100, MDT_NONE, GF_USE_KEY | GF_16BIT_COLOR, UNK, GUIO2(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI)},
+ {"Baseball2003", 0, 0, GID_HEGAME, 6, 100, MDT_NONE, GF_USE_KEY | GF_16BIT_COLOR, UNK, GUIO3(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI, GUIO_NOASPECT)},
+ {"basketball", 0, 0, GID_BASKETBALL, 6, 100, MDT_NONE, GF_USE_KEY| GF_16BIT_COLOR, UNK, GUIO3(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI, GUIO_NOASPECT)},
+ {"football2002", 0, 0, GID_FOOTBALL, 6, 100, MDT_NONE, GF_USE_KEY | GF_16BIT_COLOR, UNK, GUIO3(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI, GUIO_NOASPECT)},
+ {"Soccer2004", 0, 0, GID_SOCCER2004, 6, 100, MDT_NONE, GF_USE_KEY | GF_16BIT_COLOR, UNK, GUIO3(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI, GUIO_NOASPECT)},
// U32 code required, for testing only
- {"moonbase", 0, 0, GID_MOONBASE, 6, 100, MDT_NONE, GF_USE_KEY | GF_16BIT_COLOR, UNK, GUIO2(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI)},
- {"moonbase", "Demo", 0, GID_MOONBASE, 6, 100, MDT_NONE, GF_USE_KEY | GF_16BIT_COLOR | GF_DEMO, UNK, GUIO2(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI)},
+ {"moonbase", 0, 0, GID_MOONBASE, 6, 100, MDT_NONE, GF_USE_KEY | GF_16BIT_COLOR, UNK, GUIO3(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI, GUIO_NOASPECT)},
+ {"moonbase", "Demo", 0, GID_MOONBASE, 6, 100, MDT_NONE, GF_USE_KEY | GF_16BIT_COLOR | GF_DEMO, UNK, GUIO3(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI, GUIO_NOASPECT)},
#endif
// The following are meant to be generic HE game variants and as such do
// not specify a game ID. Make sure that these are last in the table, else
// they'll override more specific entries that follow later on.
- {"", "HE 71", 0, GID_HEGAME, 6, 71, MDT_NONE, GF_USE_KEY, UNK, GUIO2(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI)},
- {"", "HE 72", 0, GID_HEGAME, 6, 72, MDT_NONE, GF_USE_KEY, UNK, GUIO2(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI)},
- {"", "HE 73", 0, GID_HEGAME, 6, 73, MDT_NONE, GF_USE_KEY, UNK, GUIO2(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI)},
- {"", "HE 74", 0, GID_HEGAME, 6, 74, MDT_NONE, GF_USE_KEY, UNK, GUIO2(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI)},
- {"", "HE 80", 0, GID_HEGAME, 6, 80, MDT_NONE, GF_USE_KEY, UNK, GUIO2(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI)},
- {"", "HE 85", 0, GID_HEGAME, 6, 85, MDT_NONE, GF_USE_KEY, UNK, GUIO2(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI)},
- {"", "HE 90", 0, GID_HEGAME, 6, 90, MDT_NONE, GF_USE_KEY, UNK, GUIO2(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI)},
- {"", "HE 95", 0, GID_HEGAME, 6, 95, MDT_NONE, GF_USE_KEY, UNK, GUIO2(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI)},
- {"", "HE 98", 0, GID_HEGAME, 6, 98, MDT_NONE, GF_USE_KEY, UNK, GUIO2(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI)},
- {"", "HE 98.5", 0, GID_HEGAME, 6, 98, MDT_NONE, GF_USE_KEY | GF_HE_985, UNK, GUIO2(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI)},
- {"", "HE 99", 0, GID_HEGAME, 6, 99, MDT_NONE, GF_USE_KEY, UNK, GUIO2(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI)},
- {"", "HE 100", 0, GID_HEGAME, 6, 100, MDT_NONE, GF_USE_KEY, UNK, GUIO2(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI)},
+ {"", "HE 71", 0, GID_HEGAME, 6, 71, MDT_NONE, GF_USE_KEY, UNK, GUIO3(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI, GUIO_NOASPECT)},
+ {"", "HE 72", 0, GID_HEGAME, 6, 72, MDT_NONE, GF_USE_KEY, UNK, GUIO3(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI, GUIO_NOASPECT)},
+ {"", "HE 73", 0, GID_HEGAME, 6, 73, MDT_NONE, GF_USE_KEY, UNK, GUIO3(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI, GUIO_NOASPECT)},
+ {"", "HE 74", 0, GID_HEGAME, 6, 74, MDT_NONE, GF_USE_KEY, UNK, GUIO3(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI, GUIO_NOASPECT)},
+ {"", "HE 80", 0, GID_HEGAME, 6, 80, MDT_NONE, GF_USE_KEY, UNK, GUIO3(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI, GUIO_NOASPECT)},
+ {"", "HE 85", 0, GID_HEGAME, 6, 85, MDT_NONE, GF_USE_KEY, UNK, GUIO3(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI, GUIO_NOASPECT)},
+ {"", "HE 90", 0, GID_HEGAME, 6, 90, MDT_NONE, GF_USE_KEY, UNK, GUIO3(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI, GUIO_NOASPECT)},
+ {"", "HE 95", 0, GID_HEGAME, 6, 95, MDT_NONE, GF_USE_KEY, UNK, GUIO3(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI, GUIO_NOASPECT)},
+ {"", "HE 98", 0, GID_HEGAME, 6, 98, MDT_NONE, GF_USE_KEY, UNK, GUIO3(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI, GUIO_NOASPECT)},
+ {"", "HE 98.5", 0, GID_HEGAME, 6, 98, MDT_NONE, GF_USE_KEY | GF_HE_985, UNK, GUIO3(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI, GUIO_NOASPECT)},
+ {"", "HE 99", 0, GID_HEGAME, 6, 99, MDT_NONE, GF_USE_KEY, UNK, GUIO3(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI, GUIO_NOASPECT)},
+ {"", "HE 100", 0, GID_HEGAME, 6, 100, MDT_NONE, GF_USE_KEY, UNK, GUIO3(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI, GUIO_NOASPECT)},
#endif
{NULL, NULL, 0, 0, 0, MDT_NONE, 0, 0, UNK, 0}
};
@@ -437,6 +444,10 @@ static const GameFilenamePattern gameFilenamesTable[] = {
{ "indy3", "%02d.LFL", kGenRoomNum, UNK_LANG, UNK, 0 },
+ { "indyloom", "%02d.LFL", kGenRoomNum, UNK_LANG, UNK, 0 },
+ { "indyzak", "%02d.LFL", kGenRoomNum, UNK_LANG, UNK, 0 },
+ { "zakloom", "%02d.LFL", kGenRoomNum, UNK_LANG, UNK, 0 },
+
{ "loom", "%02d.LFL", kGenRoomNum, UNK_LANG, UNK, 0 },
{ "loom", "%03d.LFL", kGenRoomNum, UNK_LANG, UNK, "VGA" }, // Loom CD
@@ -622,8 +633,9 @@ static const GameFilenamePattern gameFilenamesTable[] = {
{ "chase", "chase", kGenHEPC, UNK_LANG, UNK, 0 },
{ "chase", "Cheese Chase", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 },
- { "dog", "dog", kGenHEPC, UNK_LANG, UNK, 0 },
+ { "dog", "dog", kGenHEPC, UNK_LANG, Common::kPlatformWindows, 0 },
{ "dog", "Dog on a Stick", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 },
+ { "dog", "Springparadijs", kGenHEMac, Common::NL_NLD, Common::kPlatformMacintosh, 0 },
{ "farm", "farm", kGenHEPC, UNK_LANG, UNK, 0 },
{ "farm", "farmdemo", kGenHEPC, UNK_LANG, UNK, 0 },
@@ -647,7 +659,7 @@ static const GameFilenamePattern gameFilenamesTable[] = {
{ "freddi", "MM-DEMO", kGenHEPC, UNK_LANG, UNK, 0 },
{ "freddi2", "freddi2", kGenHEPC, UNK_LANG, UNK, 0 },
- { "freddi2", "ff2-demo", kGenHEPC, UNK_LANG, UNK, 0 },
+ { "freddi2", "ff2-demo", kGenHEPC, UNK_LANG, Common::kPlatformWindows, 0 },
{ "freddi2", "FFHSDemo", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 },
{ "freddi2", "FFHSDemo", kGenHEPC, UNK_LANG, UNK, 0 },
{ "freddi2", "Freddi Fish 2 Demo", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 },
@@ -657,10 +669,12 @@ static const GameFilenamePattern gameFilenamesTable[] = {
{ "freddi2", "Fritzi Fisch 2", kGenHEMac, Common::DE_DEU, Common::kPlatformMacintosh, 0 },
{ "freddi2", "MALICE2", kGenHEMac, Common::FR_FRA, Common::kPlatformMacintosh, 0 },
- { "freddi3", "freddi3", kGenHEPC, UNK_LANG, UNK, 0 },
+ { "freddi3", "freddi3", kGenHEPC, UNK_LANG, Common::kPlatformWindows, 0 },
{ "freddi3", "F3-Mdemo", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 },
{ "freddi3", "f3-mdemo", kGenHEPC, UNK_LANG, UNK, 0 },
- { "freddi3", "FF3-DEMO", kGenHEPC, UNK_LANG, UNK, 0 },
+ { "freddi3", "FF3 Demo", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 },
+ { "freddi3", "FF3-demo", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 },
+ { "freddi3", "FF3-DEMO", kGenHEPC, UNK_LANG, Common::kPlatformWindows, 0 },
{ "freddi3", "FF3DEMO", kGenHEPC, Common::HE_ISR, UNK, 0 },
{ "freddi3", "Freddi 3", kGenHEMac, Common::NL_NLD, Common::kPlatformMacintosh, 0 },
{ "freddi3", "Freddi Fish 3", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 },
@@ -677,10 +691,10 @@ static const GameFilenamePattern gameFilenamesTable[] = {
{ "freddi3", "MM3-DEMO", kGenHEPC, Common::FR_FRA, UNK, 0 },
{ "freddi3", "MM3-Demo", kGenHEMac, Common::FR_FRA, Common::kPlatformMacintosh, 0 },
- { "freddi4", "freddi4", kGenHEPC, UNK_LANG, UNK, 0 },
+ { "freddi4", "freddi4", kGenHEPC, UNK_LANG, Common::kPlatformWindows, 0 },
{ "freddi4", "Freddi4", kGenHEMac, Common::NL_NLD, Common::kPlatformMacintosh, 0 },
{ "freddi4", "f4-demo", kGenHEPC, UNK_LANG, UNK, 0 },
- { "freddi4", "ff4demo", kGenHEPC, UNK_LANG, UNK, 0 },
+ { "freddi4", "ff4demo", kGenHEPC, UNK_LANG, Common::kPlatformWindows, 0 },
{ "freddi4", "Ff4demo", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 },
{ "freddi4", "Freddi 4", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 },
{ "freddi4", "Freddi 4 Demo", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 },
@@ -692,7 +706,8 @@ static const GameFilenamePattern gameFilenamesTable[] = {
{ "freddi4", "MaliceMRC", kGenHEPC, Common::FR_FRA, UNK, 0 },
{ "freddi4", "Mm4demo", kGenHEPC, Common::FR_FRA, UNK, 0 },
- { "FreddisFunShop", "FreddisFunShop", kGenHEPC, UNK_LANG, UNK, 0 },
+ { "FreddisFunShop", "FreddisFunShop", kGenHEPC, UNK_LANG, Common::kPlatformWindows, 0 },
+ { "FreddisFunShop", "FreddisFunShop", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 },
{ "FreddisFunShop", "Freddi's FunShop", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 },
{ "jungle", "jungle", kGenHEPC, UNK_LANG, UNK, 0 },
@@ -705,7 +720,7 @@ static const GameFilenamePattern gameFilenamesTable[] = {
{ "lost", "Verloren", kGenHEMac, Common::NL_NLD, Common::kPlatformMacintosh, 0 },
{ "maze", "maze", kGenHEPC, UNK_LANG, UNK, 0 },
- { "maze", "Doolhof", kGenHEPC, Common::NL_NLD, UNK, 0 },
+ { "maze", "Doolhof", kGenHEPC, Common::NL_NLD, Common::kPlatformWindows, 0 },
{ "maze", "Doolhof", kGenHEMac, Common::NL_NLD, Common::kPlatformMacintosh, 0 },
{ "maze", "Maze Madness", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 },
@@ -717,6 +732,7 @@ static const GameFilenamePattern gameFilenamesTable[] = {
{ "pajama", "Pajama Sam", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 },
{ "pajama", "PajamaNHD", kGenHEPC, UNK_LANG, UNK, 0 },
{ "pajama", "PJS-DEMO", kGenHEPC, UNK_LANG, UNK, 0 },
+ { "pajama", "PJS-DEMO", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 },
{ "pajama", "pjsam", kGenHEPC, UNK_LANG, UNK, 0 },
{ "pajama", "PjSamDemo", kGenHEPC, UNK_LANG, UNK, 0 },
{ "pajama", "PYJAMA", kGenHEPC, Common::DE_DEU, UNK, 0 },
@@ -740,7 +756,7 @@ static const GameFilenamePattern gameFilenamesTable[] = {
{ "pajama2", "PJP2DEMO", kGenHEPC, Common::DE_DEU, UNK, 0 },
{ "pajama2", "PJ2Demo", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 },
{ "pajama2", "pj2demo", kGenHEPC, UNK_LANG, UNK, 0 },
- { "pajama2", "Pjs2demo", kGenHEPC, UNK_LANG, UNK, 0 },
+ { "pajama2", "Pjs2demo", kGenHEPC, UNK_LANG, Common::kPlatformWindows, 0 },
{ "pajama2", "PJ2 Demo", kGenHEMac, Common::NL_NLD, Common::kPlatformMacintosh, 0 },
{ "pajama2", "PS2DEMO", kGenHEPC, Common::HE_ISR, UNK, 0 },
@@ -751,7 +767,7 @@ static const GameFilenamePattern gameFilenamesTable[] = {
{ "pajama3", "Pajama Sam 3", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 },
{ "pajama3", "Pajama Sam 3-Demo", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 },
{ "pajama3", "pj3-demo", kGenHEPC, UNK_LANG, UNK, 0 },
- { "pajama3", "pj3demo", kGenHEPC, UNK_LANG, UNK, 0 },
+ { "pajama3", "pj3demo", kGenHEPC, UNK_LANG, Common::kPlatformWindows, 0 },
{ "pajama3", "PJ3Demo", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 },
{ "pajama3", "Pajama Sam Demo", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 },
{ "pajama3", "PJMini", kGenHEPC, UNK_LANG, UNK, 0 },
@@ -775,14 +791,14 @@ static const GameFilenamePattern gameFilenamesTable[] = {
{ "puttcircus", "ToffToffGZZ", kGenHEPC, Common::DE_DEU, UNK, 0 },
{ "puttrace", "puttrace", kGenHEPC, UNK_LANG, UNK, 0 },
- { "puttrace", "500demo", kGenHEPC, Common::NL_NLD, UNK, 0 },
+ { "puttrace", "500demo", kGenHEPC, Common::NL_NLD, Common::kPlatformWindows, 0 },
{ "puttrace", "course", kGenHEPC, Common::FR_FRA, UNK, 0 },
{ "puttrace", "CourseDemo", kGenHEPC, Common::FR_FRA, UNK, 0 },
- { "puttrace", "racedemo", kGenHEPC, UNK_LANG, UNK, 0 },
+ { "puttrace", "racedemo", kGenHEPC, UNK_LANG, Common::kPlatformWindows, 0 },
{ "puttrace", "RaceDemo", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 },
{ "puttrace", "Rennen", kGenHEPC, Common::DE_DEU, UNK, 0 },
{ "puttrace", "PouceCourse", kGenHEPC, Common::FR_FRA, UNK, 0 },
- { "puttrace", "Putt500", kGenHEPC, Common::NL_NLD, UNK, 0 },
+ { "puttrace", "Putt500", kGenHEPC, Common::NL_NLD, Common::kPlatformWindows, 0 },
{ "puttrace", "Putt500", kGenHEMac, Common::NL_NLD, Common::kPlatformMacintosh, 0 },
{ "puttrace", "Putt500 demo", kGenHEMac, Common::NL_NLD, Common::kPlatformMacintosh, 0 },
{ "puttrace", "Putt Race", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 },
@@ -807,7 +823,8 @@ static const GameFilenamePattern gameFilenamesTable[] = {
{ "putttime", "Putt Time", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 },
{ "putttime", "PuttTTT", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 },
{ "putttime", "PuttTTT", kGenHEPC, UNK_LANG, UNK, 0 },
- { "putttime", "TIJDDEMO", kGenHEPC, UNK_LANG, UNK, 0 },
+ { "putttime", "TIJDDEMO", kGenHEPC, Common::NL_NLD, Common::kPlatformWindows, 0 },
+ { "putttime", "TijdDemo", kGenHEMac, Common::NL_NLD, Common::kPlatformMacintosh, 0 },
{ "putttime", "timedemo", kGenHEPC, UNK_LANG, UNK, 0 },
{ "putttime", "TimeDemo", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 },
{ "putttime", "TEMPDEMO", kGenHEPC, Common::FR_FRA, UNK, 0 },
@@ -830,6 +847,7 @@ static const GameFilenamePattern gameFilenamesTable[] = {
{ "puttzoo", "zoodemo", kGenHEPC, UNK_LANG, UNK, 0 },
{ "puttzoo", "Zoo Demo", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 },
{ "puttzoo", "Putt-Putt Saves the Zoo", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 },
+ { "puttzoo", "game", kGenHEPC, Common::EN_ANY, Common::kPlatformIOS, 0 },
{ "SamsFunShop", "SamsFunShop", kGenHEPC, UNK_LANG, UNK, 0 },
{ "SamsFunShop", "Sam's FunShop", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 },
@@ -850,7 +868,7 @@ static const GameFilenamePattern gameFilenamesTable[] = {
{ "spyfox", "JAMESDEM", kGenHEPC, Common::FR_FRA, UNK, 0 },
{ "spyfox", "renard", kGenHEPC, Common::FR_FRA, UNK, 0 },
{ "spyfox", "Spydemo", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 },
- { "spyfox", "Spydemo", kGenHEPC, UNK_LANG, UNK, 0 },
+ { "spyfox", "Spydemo", kGenHEPC, UNK_LANG, Common::kPlatformWindows, 0 },
{ "spyfox", "SPYFox", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 },
{ "spyfox", "SPYFoxDC", kGenHEPC, UNK_LANG, UNK, 0 },
{ "spyfox", "SPYFoxDC", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 },
@@ -865,7 +883,7 @@ static const GameFilenamePattern gameFilenamesTable[] = {
{ "spyfox2", "spyfox2", kGenHEPC, UNK_LANG, UNK, 0 },
{ "spyfox2", "sf2-demo", kGenHEPC, UNK_LANG, UNK, 0 },
- { "spyfox2", "sf2demo", kGenHEPC, UNK_LANG, UNK, 0 },
+ { "spyfox2", "sf2demo", kGenHEPC, UNK_LANG, Common::kPlatformWindows, 0 },
{ "spyfox2", "Sf2demo", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 },
{ "spyfox2", "Spy Fox 2", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 },
{ "spyfox2", "Spy Fox 2 - Demo", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 },
@@ -887,7 +905,7 @@ static const GameFilenamePattern gameFilenamesTable[] = {
{ "thinkerk", "thinkerk", kGenHEPC, UNK_LANG, UNK, 0 },
{ "thinkerk", "ThinkerK", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 },
- { "water", "water", kGenHEPC, UNK_LANG, UNK, 0 },
+ { "water", "water", kGenHEPC, UNK_LANG, Common::kPlatformWindows, 0 },
{ "water", "Water", kGenHEMac, Common::NL_NLD, Common::kPlatformMacintosh, 0 },
{ "water", "Water Worries", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 },
#endif
diff --git a/engines/scumm/dialogs.cpp b/engines/scumm/dialogs.cpp
index 20aedae089..0e531daf73 100644
--- a/engines/scumm/dialogs.cpp
+++ b/engines/scumm/dialogs.cpp
@@ -648,4 +648,38 @@ void DebugInputDialog::handleKeyDown(Common::KeyState state) {
}
}
+LoomTownsDifficultyDialog::LoomTownsDifficultyDialog()
+ : Dialog("LoomTownsDifficultyDialog"), _difficulty(-1) {
+ GUI::StaticTextWidget *text1 = new GUI::StaticTextWidget(this, "LoomTownsDifficultyDialog.Description1", _("Select a Proficiency Level."));
+ text1->setAlign(Graphics::kTextAlignCenter);
+ GUI::StaticTextWidget *text2 = new GUI::StaticTextWidget(this, "LoomTownsDifficultyDialog.Description2", _("Refer to your Loom(TM) manual for help."));
+ text2->setAlign(Graphics::kTextAlignCenter);
+
+ new GUI::ButtonWidget(this, "LoomTownsDifficultyDialog.Standard", _("Standard"), 0, kStandardCmd);
+ new GUI::ButtonWidget(this, "LoomTownsDifficultyDialog.Practice", _("Practice"), 0, kPracticeCmd);
+ new GUI::ButtonWidget(this, "LoomTownsDifficultyDialog.Expert", _("Expert"), 0, kExpertCmd);
+}
+
+void LoomTownsDifficultyDialog::handleCommand(GUI::CommandSender *sender, uint32 cmd, uint32 data) {
+ switch (cmd) {
+ case kStandardCmd:
+ _difficulty = 1;
+ close();
+ break;
+
+ case kPracticeCmd:
+ _difficulty = 0;
+ close();
+ break;
+
+ case kExpertCmd:
+ _difficulty = 2;
+ close();
+ break;
+
+ default:
+ GUI::Dialog::handleCommand(sender, cmd, data);
+ }
+}
+
} // End of namespace Scumm
diff --git a/engines/scumm/dialogs.h b/engines/scumm/dialogs.h
index c26aa9f414..7977f123ed 100644
--- a/engines/scumm/dialogs.h
+++ b/engines/scumm/dialogs.h
@@ -187,6 +187,27 @@ public:
Common::String mainText;
};
+/**
+ * Difficulty selection dialog for Loom FM-Towns.
+ */
+class LoomTownsDifficultyDialog : public GUI::Dialog {
+public:
+ LoomTownsDifficultyDialog();
+
+ int getSelectedDifficulty() const { return _difficulty; }
+protected:
+ virtual void handleCommand(GUI::CommandSender *sender, uint32 cmd, uint32 data);
+
+private:
+ enum {
+ kStandardCmd = 'STDD',
+ kPracticeCmd = 'PRAD',
+ kExpertCmd = 'EXPD'
+ };
+
+ int _difficulty;
+};
+
} // End of namespace Scumm
#endif
diff --git a/engines/scumm/gfx.cpp b/engines/scumm/gfx.cpp
index a22aa1802f..2cf4a429db 100644
--- a/engines/scumm/gfx.cpp
+++ b/engines/scumm/gfx.cpp
@@ -26,6 +26,7 @@
#include "scumm/he/intern_he.h"
#endif
#include "scumm/resource.h"
+#include "scumm/scumm_v0.h"
#include "scumm/scumm_v5.h"
#include "scumm/scumm_v6.h"
#include "scumm/usage_bits.h"
@@ -239,7 +240,7 @@ GdiPCEngine::~GdiPCEngine() {
#endif
GdiV1::GdiV1(ScummEngine *vm) : Gdi(vm) {
- memset(&_C64, 0, sizeof(_C64));
+ memset(&_V1, 0, sizeof(_V1));
}
GdiV2::GdiV2(ScummEngine *vm) : Gdi(vm) {
@@ -296,17 +297,17 @@ void GdiPCEngine::loadTiles(byte *roomptr) {
void GdiV1::roomChanged(byte *roomptr) {
for (int i = 0; i < 4; i++){
- _C64.colors[i] = roomptr[6 + i];
+ _V1.colors[i] = roomptr[6 + i];
}
- decodeC64Gfx(roomptr + READ_LE_UINT16(roomptr + 10), _C64.charMap, 2048);
- decodeC64Gfx(roomptr + READ_LE_UINT16(roomptr + 12), _C64.picMap, roomptr[4] * roomptr[5]);
- decodeC64Gfx(roomptr + READ_LE_UINT16(roomptr + 14), _C64.colorMap, roomptr[4] * roomptr[5]);
- decodeC64Gfx(roomptr + READ_LE_UINT16(roomptr + 16), _C64.maskMap, roomptr[4] * roomptr[5]);
+ decodeV1Gfx(roomptr + READ_LE_UINT16(roomptr + 10), _V1.charMap, 2048);
+ decodeV1Gfx(roomptr + READ_LE_UINT16(roomptr + 12), _V1.picMap, roomptr[4] * roomptr[5]);
+ decodeV1Gfx(roomptr + READ_LE_UINT16(roomptr + 14), _V1.colorMap, roomptr[4] * roomptr[5]);
+ decodeV1Gfx(roomptr + READ_LE_UINT16(roomptr + 16), _V1.maskMap, roomptr[4] * roomptr[5]);
// Read the mask data. The 16bit length value seems to always be 8 too big.
// See bug #1837375 for details on this.
const byte *maskPtr = roomptr + READ_LE_UINT16(roomptr + 18);
- decodeC64Gfx(maskPtr + 2, _C64.maskChar, READ_LE_UINT16(maskPtr) - 8);
+ decodeV1Gfx(maskPtr + 2, _V1.maskChar, READ_LE_UINT16(maskPtr) - 8);
_objectMode = true;
}
@@ -679,11 +680,10 @@ 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);
+ 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;
@@ -714,8 +714,8 @@ void ScummEngine::drawStripToScreen(VirtScreen *vs, int x, int width, int top, i
src32 += vsPitch;
text32 += textPitch;
}
- }
#endif
+ }
src = _compositeBuf;
pitch = width * vs->format.bytesPerPixel;
@@ -1135,7 +1135,7 @@ void ScummEngine::clearTextSurface() {
_townsScreen->fillLayerRect(1, 0, 0, _textSurface.w, _textSurface.h, 0);
#endif
- fill((byte*)_textSurface.pixels, _textSurface.pitch,
+ fill((byte *)_textSurface.pixels, _textSurface.pitch,
#ifndef DISABLE_TOWNS_DUAL_LAYER_MODE
_game.platform == Common::kPlatformFMTowns ? 0 :
#endif
@@ -1487,15 +1487,17 @@ void ScummEngine_v5::drawFlashlight() {
_flashlight.isDrawn = true;
}
-// V0 Maniac doesn't have a ScummVar for VAR_CURRENT_LIGHTS, and just uses
-// an internal variable. Emulate this to prevent overwriting script vars...
-// And V6 games do not use the "lights" at all. There, the whole screen is
-// always visible, and actors are always colored, so we fake the correct
-// light value for it.
+int ScummEngine_v0::getCurrentLights() const {
+ // V0 Maniac doesn't have a ScummVar for VAR_CURRENT_LIGHTS, and just uses
+ // an internal variable. Emulate this to prevent overwriting script vars...
+ // And V6 games do not use the "lights" at all. There, the whole screen is
+ // always visible, and actors are always colored, so we fake the correct
+ // light value for it.
+ return _currentLights;
+}
+
int ScummEngine::getCurrentLights() const {
- if (_game.id == GID_MANIAC && _game.version == 0)
- return _currentLights;
- else if (_game.version >= 6)
+ if (_game.version >= 6)
return LIGHTMODE_room_lights_on | LIGHTMODE_actor_use_colors;
else
return VAR(VAR_CURRENT_LIGHTS);
@@ -1538,7 +1540,7 @@ void GdiV1::prepareDrawBitmap(const byte *ptr, VirtScreen *vs,
const int x, const int y, const int width, const int height,
int stripnr, int numstrip) {
if (_objectMode) {
- decodeC64Gfx(ptr, _C64.objectMap, (width / 8) * (height / 8) * 3);
+ decodeV1Gfx(ptr, _V1.objectMap, (width / 8) * (height / 8) * 3);
}
}
@@ -1925,9 +1927,9 @@ bool GdiPCEngine::drawStrip(byte *dstPtr, VirtScreen *vs, int x, int y, const in
bool GdiV1::drawStrip(byte *dstPtr, VirtScreen *vs, int x, int y, const int width, const int height,
int stripnr, const byte *smap_ptr) {
if (_objectMode)
- drawStripC64Object(dstPtr, vs->pitch, stripnr, width, height);
+ drawStripV1Object(dstPtr, vs->pitch, stripnr, width, height);
else
- drawStripC64Background(dstPtr, vs->pitch, stripnr, height);
+ drawStripV1Background(dstPtr, vs->pitch, stripnr, height);
return false;
}
@@ -2068,7 +2070,7 @@ void GdiV1::decodeMask(int x, int y, const int width, const int height,
int stripnr, int numzbuf, const byte *zplane_list[9],
bool transpStrip, byte flag) {
byte *mask_ptr = getMaskBuffer(x, y, 1);
- drawStripC64Mask(mask_ptr, stripnr, width, height);
+ drawStripV1Mask(mask_ptr, stripnr, width, height);
}
void GdiV2::decodeMask(int x, int y, const int width, const int height,
@@ -2770,7 +2772,7 @@ void GdiNES::drawStripNESMask(byte *dst, int stripnr, int top, int height) const
void readOffsetTable(const byte *ptr, uint16 **table, int *count) {
int pos = 0;
*count = READ_LE_UINT16(ptr) / 2 + 1;
- *table = (uint16*)malloc(*count * sizeof(uint16));
+ *table = (uint16 *)malloc(*count * sizeof(uint16));
for (int i = 0; i < *count; i++) {
(*table)[i] = READ_LE_UINT16(ptr + pos) + pos + 2;
pos += 2;
@@ -2974,10 +2976,10 @@ void GdiPCEngine::decodePCEngineTileData(const byte *ptr) {
if (_distaff) {
free(_PCE.staffTiles);
- _PCE.staffTiles = (byte*)calloc(_PCE.numTiles * 8 * 8, sizeof(byte));
+ _PCE.staffTiles = (byte *)calloc(_PCE.numTiles * 8 * 8, sizeof(byte));
} else {
free(_PCE.roomTiles);
- _PCE.roomTiles = (byte*)calloc(_PCE.numTiles * 8 * 8, sizeof(byte));
+ _PCE.roomTiles = (byte *)calloc(_PCE.numTiles * 8 * 8, sizeof(byte));
}
for (int i = 0; i < _PCE.numTiles; ++i) {
@@ -3020,7 +3022,7 @@ void GdiPCEngine::decodePCEngineMaskData(const byte *ptr) {
readOffsetTable(ptr, &maskOffsets, &_PCE.numMasks);
free(_PCE.masks);
- _PCE.masks = (byte*)malloc(_PCE.numMasks * 8 * sizeof(byte));
+ _PCE.masks = (byte *)malloc(_PCE.numMasks * 8 * sizeof(byte));
for (int i = 0; i < _PCE.numMasks; ++i) {
mask = &_PCE.masks[i * 8];
@@ -3086,67 +3088,67 @@ void GdiPCEngine::drawStripPCEngineMask(byte *dst, int stripnr, int top, int hei
}
#endif
-void GdiV1::drawStripC64Background(byte *dst, int dstPitch, int stripnr, int height) {
+void GdiV1::drawStripV1Background(byte *dst, int dstPitch, int stripnr, int height) {
int charIdx;
height /= 8;
for (int y = 0; y < height; y++) {
- _C64.colors[3] = (_C64.colorMap[y + stripnr * height] & 7);
+ _V1.colors[3] = (_V1.colorMap[y + stripnr * height] & 7);
// Check for room color change in V1 zak
if (_roomPalette[0] == 255) {
- _C64.colors[2] = _roomPalette[2];
- _C64.colors[1] = _roomPalette[1];
+ _V1.colors[2] = _roomPalette[2];
+ _V1.colors[1] = _roomPalette[1];
}
- charIdx = _C64.picMap[y + stripnr * height] * 8;
+ charIdx = _V1.picMap[y + stripnr * height] * 8;
for (int i = 0; i < 8; i++) {
- byte c = _C64.charMap[charIdx + i];
- dst[0] = dst[1] = _C64.colors[(c >> 6) & 3];
- dst[2] = dst[3] = _C64.colors[(c >> 4) & 3];
- dst[4] = dst[5] = _C64.colors[(c >> 2) & 3];
- dst[6] = dst[7] = _C64.colors[(c >> 0) & 3];
+ byte c = _V1.charMap[charIdx + i];
+ dst[0] = dst[1] = _V1.colors[(c >> 6) & 3];
+ dst[2] = dst[3] = _V1.colors[(c >> 4) & 3];
+ dst[4] = dst[5] = _V1.colors[(c >> 2) & 3];
+ dst[6] = dst[7] = _V1.colors[(c >> 0) & 3];
dst += dstPitch;
}
}
}
-void GdiV1::drawStripC64Object(byte *dst, int dstPitch, int stripnr, int width, int height) {
+void GdiV1::drawStripV1Object(byte *dst, int dstPitch, int stripnr, int width, int height) {
int charIdx;
height /= 8;
width /= 8;
for (int y = 0; y < height; y++) {
- _C64.colors[3] = (_C64.objectMap[(y + height) * width + stripnr] & 7);
- charIdx = _C64.objectMap[y * width + stripnr] * 8;
+ _V1.colors[3] = (_V1.objectMap[(y + height) * width + stripnr] & 7);
+ charIdx = _V1.objectMap[y * width + stripnr] * 8;
for (int i = 0; i < 8; i++) {
- byte c = _C64.charMap[charIdx + i];
- dst[0] = dst[1] = _C64.colors[(c >> 6) & 3];
- dst[2] = dst[3] = _C64.colors[(c >> 4) & 3];
- dst[4] = dst[5] = _C64.colors[(c >> 2) & 3];
- dst[6] = dst[7] = _C64.colors[(c >> 0) & 3];
+ byte c = _V1.charMap[charIdx + i];
+ dst[0] = dst[1] = _V1.colors[(c >> 6) & 3];
+ dst[2] = dst[3] = _V1.colors[(c >> 4) & 3];
+ dst[4] = dst[5] = _V1.colors[(c >> 2) & 3];
+ dst[6] = dst[7] = _V1.colors[(c >> 0) & 3];
dst += dstPitch;
}
}
}
-void GdiV1::drawStripC64Mask(byte *dst, int stripnr, int width, int height) const {
+void GdiV1::drawStripV1Mask(byte *dst, int stripnr, int width, int height) const {
int maskIdx;
height /= 8;
width /= 8;
for (int y = 0; y < height; y++) {
if (_objectMode)
- maskIdx = _C64.objectMap[(y + 2 * height) * width + stripnr] * 8;
+ maskIdx = _V1.objectMap[(y + 2 * height) * width + stripnr] * 8;
else
- maskIdx = _C64.maskMap[y + stripnr * height] * 8;
+ maskIdx = _V1.maskMap[y + stripnr * height] * 8;
for (int i = 0; i < 8; i++) {
- byte c = _C64.maskChar[maskIdx + i];
+ byte c = _V1.maskChar[maskIdx + i];
- // V1/C64 masks are inverted compared to what ScummVM expects
+ // V1/V0 masks are inverted compared to what ScummVM expects
*dst = c ^ 0xFF;
dst += _numStrips;
}
}
}
-void GdiV1::decodeC64Gfx(const byte *src, byte *dst, int size) const {
+void GdiV1::decodeV1Gfx(const byte *src, byte *dst, int size) const {
int x, z;
byte color, run, common[4];
diff --git a/engines/scumm/gfx.h b/engines/scumm/gfx.h
index 4b44ddc376..0d81698c50 100644
--- a/engines/scumm/gfx.h
+++ b/engines/scumm/gfx.h
@@ -375,19 +375,19 @@ public:
class GdiV1 : public Gdi {
protected:
- /** Render settings which are specific to the C64 graphic decoders. */
+ /** Render settings which are specific to the v0/v1 graphic decoders. */
struct {
byte colors[4];
byte charMap[2048], objectMap[2048], picMap[4096], colorMap[4096];
byte maskMap[4096], maskChar[4096];
- } _C64;
+ } _V1;
protected:
- void decodeC64Gfx(const byte *src, byte *dst, int size) const;
+ void decodeV1Gfx(const byte *src, byte *dst, int size) const;
- void drawStripC64Object(byte *dst, int dstPitch, int stripnr, int width, int height);
- void drawStripC64Background(byte *dst, int dstPitch, int stripnr, int height);
- void drawStripC64Mask(byte *dst, int stripnr, int width, int height) const;
+ void drawStripV1Object(byte *dst, int dstPitch, int stripnr, int width, int height);
+ void drawStripV1Background(byte *dst, int dstPitch, int stripnr, int height);
+ void drawStripV1Mask(byte *dst, int stripnr, int width, int height) const;
virtual bool drawStrip(byte *dstPtr, VirtScreen *vs,
int x, int y, const int width, const int height,
diff --git a/engines/scumm/gfxARM.s b/engines/scumm/gfxARM.s
index 92f8951466..9238888831 100644
--- a/engines/scumm/gfxARM.s
+++ b/engines/scumm/gfxARM.s
@@ -59,10 +59,6 @@ _asmDrawStripToScreen:
CMP r1,#4 @ If width<4
BLT end @ return
- @ Width &= ~4 ? What''s that about then? Width &= ~3 I could have
- @ understood...
- BIC r1,r1,#4
-
SUB r5,r5,r1 @ vsPitch -= width
SUB r6,r6,r1 @ vmScreenWidth -= width
SUB r7,r7,r1 @ textSurfacePitch -= width
diff --git a/engines/scumm/gfx_towns.cpp b/engines/scumm/gfx_towns.cpp
index 6a3f50a1af..8bffcab4a0 100644
--- a/engines/scumm/gfx_towns.cpp
+++ b/engines/scumm/gfx_towns.cpp
@@ -39,7 +39,7 @@ void ScummEngine::towns_drawStripToScreen(VirtScreen *vs, int dstX, int dstY, in
int m = _textSurfaceMultiplier;
uint8 *src1 = vs->getPixels(srcX, srcY);
- uint8 *src2 = (uint8*)_textSurface.getBasePtr(srcX * m, (srcY + vs->topline - _screenTop) * m);
+ uint8 *src2 = (uint8 *)_textSurface.getBasePtr(srcX * m, (srcY + vs->topline - _screenTop) * m);
uint8 *dst1 = _townsScreen->getLayerPixels(0, dstX, dstY);
uint8 *dst2 = _townsScreen->getLayerPixels(1, dstX * m, dstY * m);
@@ -52,7 +52,7 @@ void ScummEngine::towns_drawStripToScreen(VirtScreen *vs, int dstX, int dstY, in
for (int h = 0; h < height; ++h) {
if (_outputPixelFormat.bytesPerPixel == 2) {
for (int w = 0; w < width; ++w) {
- *(uint16*)dst1 = _16BitPalette[*src1++];
+ *(uint16 *)dst1 = _16BitPalette[*src1++];
dst1 += _outputPixelFormat.bytesPerPixel;
}
@@ -245,7 +245,7 @@ void TownsScreen::setupLayer(int layer, int width, int height, int numCol, void
l->numCol = numCol;
l->bpp = ((numCol - 1) & 0xff00) ? 2 : 1;
l->pitch = width * l->bpp;
- l->palette = (uint8*)pal;
+ l->palette = (uint8 *)pal;
if (l->palette && _pixelFormat.bytesPerPixel == 1)
warning("TownsScreen::setupLayer(): Layer palette usage requires 16 bit graphics setting.\nLayer palette will be ignored.");
@@ -304,7 +304,7 @@ void TownsScreen::fillLayerRect(int layer, int x, int y, int w, int h, int col)
for (int i = 0; i < h; ++i) {
if (l->bpp == 2) {
for (int ii = 0; ii < w; ++ii) {
- *(uint16*)pos = col;
+ *(uint16 *)pos = col;
pos += 2;
}
pos += (l->pitch - w * 2);
@@ -472,10 +472,10 @@ void TownsScreen::updateOutputBuffer() {
if (col || l->onBottom) {
if (l->numCol == 16)
col = (col >> 4) & (col & 0x0f);
- *(uint16*)dst = l->bltTmpPal[col];
+ *(uint16 *)dst = l->bltTmpPal[col];
}
} else {
- *(uint16*)dst = *(uint16*)src;
+ *(uint16 *)dst = *(uint16 *)src;
}
dst += 2;
}
diff --git a/engines/scumm/he/script_v80he.cpp b/engines/scumm/he/script_v80he.cpp
index 9711f6415b..eb62b650a4 100644
--- a/engines/scumm/he/script_v80he.cpp
+++ b/engines/scumm/he/script_v80he.cpp
@@ -25,6 +25,7 @@
#include "common/archive.h"
#include "common/config-file.h"
#include "common/config-manager.h"
+#include "common/macresman.h"
#include "common/savefile.h"
#include "common/str.h"
@@ -158,19 +159,41 @@ void ScummEngine_v80he::o80_readConfigFile() {
memcpy(section, "BluesTreasureHunt-Disc2\0", 24);
}
- Common::ConfigFile ConfFile;
- if (!strcmp((char *)filename + r, "map.ini"))
- ConfFile.loadFromFile((const char *)filename + r);
- else
- ConfFile.loadFromSaveFile((const char *)filename + r);
+ if (!strcmp((const char *)filename, "map (i)")) {
+ // Mac resource fork config file
+ // (as used by only mustard mac for map data?)
+ Common::MacResManager resFork;
+
+ if (!resFork.open((const char *)filename) || !resFork.hasResFork())
+ error("Could not open '%s'", filename);
+
+ Common::String prefResName = Common::String::format("Pref:%s.%s", (const char *)section, (const char *)option);
+ Common::SeekableReadStream *res = resFork.getResource(prefResName);
+
+ if (res) {
+ // The string is inside the resource as a pascal string
+ byte length = res->readByte();
+ for (byte i = 0; i < length; i++)
+ entry += (char)res->readByte();
+
+ delete res;
+ }
+ } else {
+ // Normal Windows INI files
+ Common::ConfigFile confFile;
+ if (!strcmp((char *)filename + r, "map.ini"))
+ confFile.loadFromFile((const char *)filename + r);
+ else
+ confFile.loadFromSaveFile((const char *)filename + r);
+
+ confFile.getKey((const char *)option, (const char *)section, entry);
+ }
byte subOp = fetchScriptByte();
switch (subOp) {
case 43: // HE 100
case 6: // number
- ConfFile.getKey((const char *)option, (const char *)section, entry);
-
if (!strcmp((char *)option, "Benchmark"))
push(2);
else
@@ -178,8 +201,6 @@ void ScummEngine_v80he::o80_readConfigFile() {
break;
case 77: // HE 100
case 7: // string
- ConfFile.getKey((const char *)option, (const char *)section, entry);
-
writeVar(0, 0);
len = resStrLen((const byte *)entry.c_str());
data = defineArray(0, kStringArray, 0, 0, 0, len);
diff --git a/engines/scumm/he/script_v90he.cpp b/engines/scumm/he/script_v90he.cpp
index 877f8b239d..0beebdb7a1 100644
--- a/engines/scumm/he/script_v90he.cpp
+++ b/engines/scumm/he/script_v90he.cpp
@@ -2373,6 +2373,9 @@ void ScummEngine_v90he::o90_kernelSetFunctions() {
case 2001:
_logicHE->dispatch(args[1], num - 2, (int32 *)&args[2]);
break;
+ case 201102:
+ // Used in puttzoo iOS
+ break;
default:
error("o90_kernelSetFunctions: default case %d (param count %d)", args[0], num);
}
diff --git a/engines/scumm/he/sound_he.cpp b/engines/scumm/he/sound_he.cpp
index 5c15a85929..1007d2a7b0 100644
--- a/engines/scumm/he/sound_he.cpp
+++ b/engines/scumm/he/sound_he.cpp
@@ -652,7 +652,7 @@ void SoundHE::playHESound(int soundID, int heOffset, int heChannel, int heFlags)
* even addresses, so the use of (void *) in the
* following cast shuts the compiler from warning
* unnecessarily. */
- size = voxStream->readBuffer((int16*)(void *)sound, size * 2);
+ size = voxStream->readBuffer((int16 *)(void *)sound, size * 2);
size *= 2; // 16bits.
delete voxStream;
@@ -770,24 +770,30 @@ void SoundHE::startHETalkSound(uint32 offset) {
if (ConfMan.getBool("speech_mute"))
return;
- assert(_sfxFile);
- if (!_sfxFile->isOpen()) {
+ if (_sfxFilename.empty()) {
// This happens in the Pajama Sam's Lost & Found demo, on the
// main menu screen, so don't make it a fatal error.
- warning("startHETalkSound: Speech file is not open");
+ warning("startHETalkSound: Speech file is not found");
return;
}
+ ScummFile file;
+ if (!_vm->openFile(file, _sfxFilename)) {
+ warning("startHETalkSound: Could not open speech file %s", _sfxFilename.c_str());
+ return;
+ }
+ file.setEnc(_sfxFileEncByte);
+
_sfxMode |= 2;
_vm->_res->nukeResource(rtSound, 1);
- _sfxFile->seek(offset + 4, SEEK_SET);
- size = _sfxFile->readUint32BE();
- _sfxFile->seek(offset, SEEK_SET);
+ file.seek(offset + 4, SEEK_SET);
+ size = file.readUint32BE();
+ file.seek(offset, SEEK_SET);
_vm->_res->createResource(rtSound, 1, size);
ptr = _vm->getResourceAddress(rtSound, 1);
- _sfxFile->read(ptr, size);
+ file.read(ptr, size);
int channel = (_vm->VAR_TALK_CHANNEL != 0xFF) ? _vm->VAR(_vm->VAR_TALK_CHANNEL) : 0;
addSoundToQueue2(1, 0, channel, 0);
diff --git a/engines/scumm/he/sprite_he.cpp b/engines/scumm/he/sprite_he.cpp
index 081110c7cd..ec69ae11b4 100644
--- a/engines/scumm/he/sprite_he.cpp
+++ b/engines/scumm/he/sprite_he.cpp
@@ -33,7 +33,12 @@
namespace Scumm {
-Sprite::Sprite(ScummEngine_v90he *vm) : _vm(vm) {
+Sprite::Sprite(ScummEngine_v90he *vm)
+ :
+ _vm(vm),
+ _spriteGroups(0),
+ _spriteTable(0),
+ _activeSpritesTable(0) {
}
Sprite::~Sprite() {
diff --git a/engines/scumm/he/wiz_he.cpp b/engines/scumm/he/wiz_he.cpp
index f67922c81c..47b4b8ad33 100644
--- a/engines/scumm/he/wiz_he.cpp
+++ b/engines/scumm/he/wiz_he.cpp
@@ -687,7 +687,7 @@ void Wiz::copyRawWizImage(uint8 *dst, const uint8 *src, int dstPitch, int dstTyp
}
#ifdef USE_RGB_COLOR
-template <int type>
+template<int type>
void Wiz::write16BitColor(uint8 *dstPtr, const uint8 *dataPtr, int dstType, const uint8 *xmapPtr) {
uint16 col = READ_LE_UINT16(dataPtr);
if (type == kWizXMap) {
@@ -701,7 +701,7 @@ void Wiz::write16BitColor(uint8 *dstPtr, const uint8 *dataPtr, int dstType, cons
}
}
-template <int type>
+template<int type>
void Wiz::decompress16BitWizImage(uint8 *dst, int dstPitch, int dstType, const uint8 *src, const Common::Rect &srcRect, int flags, const uint8 *xmapPtr) {
const uint8 *dataPtr, *dataPtrNext;
uint8 code;
@@ -804,7 +804,7 @@ void Wiz::decompress16BitWizImage(uint8 *dst, int dstPitch, int dstType, const u
}
#endif
-template <int type>
+template<int type>
void Wiz::write8BitColor(uint8 *dstPtr, const uint8 *dataPtr, int dstType, const uint8 *palPtr, const uint8 *xmapPtr, uint8 bitDepth) {
if (bitDepth == 2) {
if (type == kWizXMap) {
@@ -833,7 +833,7 @@ void Wiz::write8BitColor(uint8 *dstPtr, const uint8 *dataPtr, int dstType, const
}
}
-template <int type>
+template<int type>
void Wiz::decompressWizImage(uint8 *dst, int dstPitch, int dstType, const uint8 *src, const Common::Rect &srcRect, int flags, const uint8 *palPtr, const uint8 *xmapPtr, uint8 bitDepth) {
const uint8 *dataPtr, *dataPtrNext;
uint8 code, *dstPtr, *dstPtrNext;
@@ -942,7 +942,7 @@ template void Wiz::decompressWizImage<kWizXMap>(uint8 *dst, int dstPitch, int ds
template void Wiz::decompressWizImage<kWizRMap>(uint8 *dst, int dstPitch, int dstType, const uint8 *src, const Common::Rect &srcRect, int flags, const uint8 *palPtr, const uint8 *xmapPtr, uint8 bitDepth);
template void Wiz::decompressWizImage<kWizCopy>(uint8 *dst, int dstPitch, int dstType, const uint8 *src, const Common::Rect &srcRect, int flags, const uint8 *palPtr, const uint8 *xmapPtr, uint8 bitDepth);
-template <int type>
+template<int type>
void Wiz::decompressRawWizImage(uint8 *dst, int dstPitch, int dstType, const uint8 *src, int srcPitch, int w, int h, int transColor, const uint8 *palPtr, uint8 bitDepth) {
if (type == kWizRMap) {
assert(palPtr != 0);
diff --git a/engines/scumm/help.h b/engines/scumm/help.h
index 5ba6bdc65c..a3948566c4 100644
--- a/engines/scumm/help.h
+++ b/engines/scumm/help.h
@@ -24,6 +24,7 @@
#define SCUMM_HELP_H
#include "common/str.h"
+#include "common/platform.h"
namespace Scumm {
diff --git a/engines/scumm/imuse/imuse_player.cpp b/engines/scumm/imuse/imuse_player.cpp
index 73be2174cd..53ccfb3734 100644
--- a/engines/scumm/imuse/imuse_player.cpp
+++ b/engines/scumm/imuse/imuse_player.cpp
@@ -592,6 +592,7 @@ bool Player::setLoop(uint count, uint tobeat, uint totick, uint frombeat, uint f
if (tobeat == 0)
tobeat = 1;
+ // FIXME: Thread safety?
_loop_counter = 0; // Because of possible interrupts
_loop_to_beat = tobeat;
_loop_to_tick = totick;
diff --git a/engines/scumm/input.cpp b/engines/scumm/input.cpp
index 6d9e1f3f72..ee2de49475 100644
--- a/engines/scumm/input.cpp
+++ b/engines/scumm/input.cpp
@@ -446,6 +446,23 @@ void ScummEngine_v6::processKeyboard(Common::KeyState lastKeyHit) {
}
void ScummEngine_v2::processKeyboard(Common::KeyState lastKeyHit) {
+ // RETURN is used to skip cutscenes in the Commodote 64 version of Zak McKracken
+ if (_game.id == GID_ZAK &&_game.platform == Common::kPlatformC64 && lastKeyHit.keycode == Common::KEYCODE_RETURN && lastKeyHit.hasFlags(0)) {
+ lastKeyHit = Common::KeyState(Common::KEYCODE_ESCAPE);
+ // F7 is used to skip cutscenes in the Commodote 64 version of Maniac Mansion
+ } else if (_game.id == GID_MANIAC &&_game.platform == Common::kPlatformC64) {
+ if (lastKeyHit.keycode == Common::KEYCODE_F7 && lastKeyHit.hasFlags(0))
+ lastKeyHit = Common::KeyState(Common::KEYCODE_ESCAPE);
+ // 'B' is used to skip cutscenes in the NES version of Maniac Mansion
+ } else if (_game.id == GID_MANIAC &&_game.platform == Common::kPlatformNES) {
+ if (lastKeyHit.keycode == Common::KEYCODE_b && lastKeyHit.hasFlags(Common::KBD_SHIFT))
+ lastKeyHit = Common::KeyState(Common::KEYCODE_ESCAPE);
+ // 'F4' is used to skip cutscenes in the other versions of Maniac Mansion
+ } else if (_game.id == GID_MANIAC) {
+ if (lastKeyHit.keycode == Common::KEYCODE_F4 && lastKeyHit.hasFlags(0))
+ lastKeyHit = Common::KeyState(Common::KEYCODE_ESCAPE);
+ }
+
// Fall back to default behavior
ScummEngine::processKeyboard(lastKeyHit);
diff --git a/engines/scumm/module.mk b/engines/scumm/module.mk
index 781ca30459..1f219f5187 100644
--- a/engines/scumm/module.mk
+++ b/engines/scumm/module.mk
@@ -34,6 +34,7 @@ MODULE_OBJS := \
midiparser_ro.o \
object.o \
palette.o \
+ player_apple2.o \
player_mod.o \
player_nes.o \
player_pce.o \
diff --git a/engines/scumm/object.cpp b/engines/scumm/object.cpp
index ae4bbc45a6..399cd91324 100644
--- a/engines/scumm/object.cpp
+++ b/engines/scumm/object.cpp
@@ -178,10 +178,7 @@ void ScummEngine::clearOwnerOf(int obj) {
// Alternatively, scan the inventory to see if the object is in there...
for (i = 0; i < _numInventory; i++) {
if (_inventory[i] == obj) {
- if (_game.version == 0)
- assert(WIO_INVENTORY == whereIsObjectInventory(obj));
- else
- assert(WIO_INVENTORY == whereIsObject(obj));
+ assert(WIO_INVENTORY == whereIsObject(obj));
// Found the object! Nuke it from the inventory.
_res->nukeResource(rtInventory, i);
@@ -206,6 +203,9 @@ void ScummEngine::clearOwnerOf(int obj) {
}
bool ScummEngine::getClass(int obj, int cls) const {
+ if (_game.version == 0)
+ return false;
+
assertRange(0, obj, _numGlobalObjects - 1, "object");
cls &= 0x7F;
assertRange(1, cls, 32, "class");
@@ -233,6 +233,9 @@ bool ScummEngine::getClass(int obj, int cls) const {
}
void ScummEngine::putClass(int obj, int cls, bool set) {
+ if (_game.version == 0)
+ return;
+
assertRange(0, obj, _numGlobalObjects - 1, "object");
cls &= 0x7F;
assertRange(1, cls, 32, "class");
@@ -315,47 +318,38 @@ int ScummEngine::getObjectIndex(int object) const {
return -1;
for (i = (_numLocalObjects-1); i > 0; i--) {
- if (_game.version == 0 )
- if( _objs[i].flags != _v0ObjectFlag )
- continue;
-
if (_objs[i].obj_nr == object)
return i;
}
return -1;
}
-int ScummEngine::whereIsObjectInventory(int object) {
- int res = 0;
- _v0ObjectInInventory = true;
- res = whereIsObject(object);
- _v0ObjectInInventory = false;
-
- return res;
-}
-
int ScummEngine::whereIsObject(int object) const {
int i;
- if (object >= _numGlobalObjects)
+ // Note: in MM v0 bg objects are greater _numGlobalObjects
+ if (_game.version != 0 && object >= _numGlobalObjects)
return WIO_NOT_FOUND;
if (object < 1)
return WIO_NOT_FOUND;
- if ((_objectOwnerTable[object] != OF_OWNER_ROOM && _game.version != 0) || _v0ObjectInInventory) {
+ if ((_game.version != 0 || OBJECT_V0_TYPE(object) == 0) &&
+ _objectOwnerTable[object] != OF_OWNER_ROOM)
+ {
for (i = 0; i < _numInventory; i++)
if (_inventory[i] == object)
return WIO_INVENTORY;
return WIO_NOT_FOUND;
}
- for (i = (_numLocalObjects-1); i > 0; i--)
- if ((_objs[i].obj_nr == object && !_v0ObjectIndex) || (_v0ObjectIndex && i == object)) {
+ for (i = (_numLocalObjects-1); i > 0; i--) {
+ if (_objs[i].obj_nr == object) {
if (_objs[i].fl_object_index)
return WIO_FLOBJECT;
return WIO_ROOM;
}
+ }
return WIO_NOT_FOUND;
}
@@ -363,8 +357,8 @@ int ScummEngine::whereIsObject(int object) const {
int ScummEngine::getObjectOrActorXY(int object, int &x, int &y) {
Actor *act;
- if (object < _numActors) {
- act = derefActorSafe(object, "getObjectOrActorXY");
+ if (objIsActor(object)) {
+ act = derefActorSafe(objToActor(object), "getObjectOrActorXY");
if (act && act->isInCurrentRoom()) {
x = act->getRealPos().x;
y = act->getRealPos().y;
@@ -377,7 +371,7 @@ int ScummEngine::getObjectOrActorXY(int object, int &x, int &y) {
case WIO_NOT_FOUND:
return -1;
case WIO_INVENTORY:
- if (_objectOwnerTable[object] < _numActors) {
+ if (objIsActor(_objectOwnerTable[object])) {
act = derefActor(_objectOwnerTable[object], "getObjectOrActorXY(2)");
if (act && act->isInCurrentRoom()) {
x = act->getRealPos().x;
@@ -396,7 +390,7 @@ int ScummEngine::getObjectOrActorXY(int object, int &x, int &y) {
* Returns X, Y and direction in angles
*/
void ScummEngine::getObjectXYPos(int object, int &x, int &y, int &dir) {
- int idx = (_v0ObjectIndex) ? object : getObjectIndex(object);
+ int idx = getObjectIndex(object);
assert(idx >= 0);
ObjectData &od = _objs[idx];
int state;
@@ -439,8 +433,15 @@ void ScummEngine::getObjectXYPos(int object, int &x, int &y, int &dir) {
y = od.y_pos + (int16)READ_LE_UINT16(&imhd->old.hotspot[state].y);
}
} else if (_game.version <= 2) {
- x = od.walk_x >> V12_X_SHIFT;
- y = od.walk_y >> V12_Y_SHIFT;
+ if (od.actordir) {
+ x = od.walk_x;
+ y = od.walk_y;
+ } else {
+ x = od.x_pos + od.width / 2;
+ y = od.y_pos + od.height / 2;
+ }
+ x = x >> V12_X_SHIFT;
+ y = y >> V12_Y_SHIFT;
} else {
x = od.walk_x;
y = od.walk_y;
@@ -462,11 +463,11 @@ int ScummEngine::getObjActToObjActDist(int a, int b) {
Actor *acta = NULL;
Actor *actb = NULL;
- if (a < _numActors)
- acta = derefActorSafe(a, "getObjActToObjActDist");
+ if (objIsActor(a))
+ acta = derefActorSafe(objToActor(a), "getObjActToObjActDist");
- if (b < _numActors)
- actb = derefActorSafe(b, "getObjActToObjActDist(2)");
+ if (objIsActor(b))
+ actb = derefActorSafe(objToActor(b), "getObjActToObjActDist(2)");
if (acta && actb && acta->getRoom() == actb->getRoom() && acta->getRoom() && !acta->isInCurrentRoom())
return 0;
@@ -492,14 +493,6 @@ int ScummEngine::getObjActToObjActDist(int a, int b) {
return getDist(x, y, x2, y2);
}
-int ScummEngine_v0::findObjectIndex(int x, int y) {
- int objIdx;
- _v0ObjectIndex = true;
- objIdx = findObject(x, y);
- _v0ObjectIndex = false;
- return objIdx;
-}
-
int ScummEngine::findObject(int x, int y) {
int i, b;
byte a;
@@ -509,11 +502,9 @@ int ScummEngine::findObject(int x, int y) {
if ((_objs[i].obj_nr < 1) || getClass(_objs[i].obj_nr, kObjectClassUntouchable))
continue;
- if (_game.version == 0) {
- if (_objs[i].flags == 0 && _objs[i].state & kObjectStateUntouchable)
- continue;
- } else {
- if (_game.version <= 2 && _objs[i].state & kObjectStateUntouchable)
+ if ((_game.version == 0 && OBJECT_V0_TYPE(_objs[i].obj_nr) == kObjectV0TypeFG) ||
+ (_game.version > 0 && _game.version <= 2)) {
+ if (_objs[i].state & kObjectStateUntouchable)
continue;
}
@@ -529,15 +520,8 @@ int ScummEngine::findObject(int x, int y) {
}
#endif
if (_objs[i].x_pos <= x && _objs[i].width + _objs[i].x_pos > x &&
- _objs[i].y_pos <= y && _objs[i].height + _objs[i].y_pos > y) {
- // MMC64: Set the object search flag
- if (_game.version == 0)
- _v0ObjectFlag = _objs[i].flags;
- if (_game.version == 0 && _v0ObjectIndex)
- return i;
- else
- return _objs[i].obj_nr;
- }
+ _objs[i].y_pos <= y && _objs[i].height + _objs[i].y_pos > y)
+ return _objs[i].obj_nr;
break;
}
} while ((_objs[b].state & mask) == a);
@@ -824,7 +808,7 @@ void ScummEngine_v3old::resetRoomObjects() {
else
ptr = room + 29;
- // Default pointer of objects without image, in C64 verison of Maniac Mansion
+ // Default pointer of objects without image, in v0 version of Maniac Mansion
int defaultPtr = READ_LE_UINT16(ptr + 2 * _numObjectsInRoom);
for (i = 0; i < _numObjectsInRoom; i++) {
@@ -843,9 +827,6 @@ void ScummEngine_v3old::resetRoomObjects() {
if (_dumpScripts) {
char buf[32];
sprintf(buf, "roomobj-%d-", _roomResource);
- if (_game.version == 0)
- sprintf(buf + 11, "%d-", od->flags);
-
dumpResource(buf, od->obj_nr, room + od->OBCDoffset);
}
}
@@ -911,8 +892,7 @@ void ScummEngine_v0::resetRoomObject(ObjectData *od, const byte *room, const byt
const byte *ptr = room + od->OBCDoffset;
ptr -= 2;
- od->obj_nr = *(ptr + 6);
- od->flags = *(ptr + 7);
+ od->obj_nr = OBJECT_V0(*(ptr + 6), *(ptr + 7));
od->x_pos = *(ptr + 8) * 8;
od->y_pos = ((*(ptr + 9)) & 0x7F) * 8;
@@ -1072,8 +1052,8 @@ void ScummEngine::updateObjectStates() {
int i;
ObjectData *od = &_objs[1];
for (i = 1; i < _numLocalObjects; i++, od++) {
- // V0 MM, Room objects with Flag == 1 are objects with 'no-state' (room specific objects, non-pickup)
- if (_game.version == 0 && od->flags == 1)
+ // V0 MM, objects with type == 1 are room objects (room specific objects, non-pickup)
+ if (_game.version == 0 && OBJECT_V0_TYPE(od->obj_nr) == kObjectV0TypeBG)
continue;
if (od->obj_nr > 0)
@@ -1163,8 +1143,8 @@ const byte *ScummEngine::getObjOrActorName(int obj) {
byte *objptr;
int i;
- if (obj < _numActors && _game.version >= 1)
- return derefActor(obj, "getObjOrActorName")->getActorName();
+ if (objIsActor(obj))
+ return derefActor(objToActor(obj), "getObjOrActorName")->getActorName();
for (i = 0; i < _numNewNames; i++) {
if (_newNames[i] == obj) {
@@ -1173,7 +1153,7 @@ const byte *ScummEngine::getObjOrActorName(int obj) {
}
}
- objptr = getOBCDFromObject(obj);
+ objptr = getOBCDFromObject(obj, true);
if (objptr == NULL)
return NULL;
@@ -1200,7 +1180,7 @@ const byte *ScummEngine::getObjOrActorName(int obj) {
void ScummEngine::setObjectName(int obj) {
int i;
- if (obj < _numActors && _game.version != 0)
+ if (objIsActor(obj))
error("Can't set actor %d name with new-name-of", obj);
for (i = 0; i < _numNewNames; i++) {
@@ -1226,13 +1206,10 @@ void ScummEngine::setObjectName(int obj) {
uint32 ScummEngine::getOBCDOffs(int object) const {
int i;
- if ((_objectOwnerTable[object] != OF_OWNER_ROOM && (_game.version != 0)) || _v0ObjectInInventory)
+ if ((_game.version != 0 || OBJECT_V0_TYPE(object) == 0) &&
+ _objectOwnerTable[object] != OF_OWNER_ROOM)
return 0;
- // V0 MM Return by Index
- if (_v0ObjectIndex)
- return _objs[object].OBCDoffset;
-
for (i = (_numLocalObjects-1); i > 0; i--) {
if (_objs[i].obj_nr == object) {
if (_objs[i].fl_object_index != 0)
@@ -1243,21 +1220,22 @@ uint32 ScummEngine::getOBCDOffs(int object) const {
return 0;
}
-byte *ScummEngine::getOBCDFromObject(int obj) {
- bool useInventory = _v0ObjectInInventory;
+byte *ScummEngine::getOBCDFromObject(int obj, bool v0CheckInventory) {
int i;
byte *ptr;
- _v0ObjectInInventory = false;
-
- if ((_objectOwnerTable[obj] != OF_OWNER_ROOM && (_game.version != 0)) || useInventory) {
+ if ((_game.version != 0 || OBJECT_V0_TYPE(obj) == 0) &&
+ _objectOwnerTable[obj] != OF_OWNER_ROOM)
+ {
+ if (_game.version == 0 && !v0CheckInventory)
+ return 0;
for (i = 0; i < _numInventory; i++) {
if (_inventory[i] == obj)
return getResourceAddress(rtInventory, i);
}
} else {
for (i = (_numLocalObjects-1); i > 0; --i) {
- if ((_objs[i].obj_nr == obj && !_v0ObjectIndex) || (_v0ObjectIndex && i == obj)) {
+ if (_objs[i].obj_nr == obj) {
if (_objs[i].fl_object_index) {
assert(_objs[i].OBCDoffset == 8);
ptr = getResourceAddress(rtFlObject, _objs[i].fl_object_index);
@@ -1510,11 +1488,37 @@ void ScummEngine::findObjectInRoom(FindObjectInRoom *fo, byte findWhat, uint id,
}
}
+bool ScummEngine_v0::objIsActor(int obj) {
+ // object IDs < _numActors are used in v0 for objects too (e.g. hamster)
+ return OBJECT_V0_TYPE(obj) == kObjectV0TypeActor;
+}
+
+int ScummEngine_v0::objToActor(int obj) {
+ return OBJECT_V0_ID(obj);
+}
+
+int ScummEngine_v0::actorToObj(int actor) {
+ return OBJECT_V0(actor, kObjectV0TypeActor);
+}
+
+bool ScummEngine::objIsActor(int obj) {
+ return obj < _numActors;
+}
+
+int ScummEngine::objToActor(int obj) {
+ return obj;
+}
+
+int ScummEngine::actorToObj(int actor) {
+ return actor;
+}
+
int ScummEngine::getObjX(int obj) {
- if (obj < _numActors) {
- if (obj < 1)
- return 0; /* fix for indy4's map */
- return derefActor(obj, "getObjX")->getRealPos().x;
+ if (obj < 1)
+ return 0; /* fix for indy4's map */
+
+ if (objIsActor(obj)) {
+ return derefActor(objToActor(obj), "getObjX")->getRealPos().x;
} else {
if (whereIsObject(obj) == WIO_NOT_FOUND)
return -1;
@@ -1525,10 +1529,11 @@ int ScummEngine::getObjX(int obj) {
}
int ScummEngine::getObjY(int obj) {
- if (obj < _numActors) {
- if (obj < 1)
- return 0; /* fix for indy4's map */
- return derefActor(obj, "getObjY")->getRealPos().y;
+ if (obj < 1)
+ return 0; /* fix for indy4's map */
+
+ if (objIsActor(obj)) {
+ return derefActor(objToActor(obj), "getObjY")->getRealPos().y;
} else {
if (whereIsObject(obj) == WIO_NOT_FOUND)
return -1;
@@ -1544,8 +1549,8 @@ int ScummEngine::getObjOldDir(int obj) {
int ScummEngine::getObjNewDir(int obj) {
int dir;
- if (obj < _numActors) {
- dir = derefActor(obj, "getObjNewDir")->getFacing();
+ if (objIsActor(obj)) {
+ dir = derefActor(objToActor(obj), "getObjNewDir")->getFacing();
} else {
int x, y;
getObjectXYPos(obj, x, y, dir);
@@ -1842,7 +1847,7 @@ void ScummEngine::loadFlObject(uint object, uint room) {
if (_dumpScripts) {
char buf[32];
const byte *ptr = foir.obcd;
- sprintf(buf, "roomobj-%d-", room);
+ sprintf(buf, "roomobj-%u-", room);
ptr = findResource(MKTAG('V','E','R','B'), ptr);
dumpResource(buf, object, ptr);
}
diff --git a/engines/scumm/object.h b/engines/scumm/object.h
index cdf8b09e6f..8212075e43 100644
--- a/engines/scumm/object.h
+++ b/engines/scumm/object.h
@@ -24,6 +24,26 @@
namespace Scumm {
+static inline int OBJECT_V0(int id, byte type) {
+ assert(id < 256);
+ return (type << 8 | id);
+}
+#define OBJECT_V0_ID(obj) (obj & 0xFF)
+#define OBJECT_V0_TYPE(obj) ((obj >> 8) & 0xFF)
+
+enum ObjectV0Type {
+ kObjectV0TypeFG = 0, // foreground object
+ // - with owner/state, might (but has not to) be pickupable
+ // -> with entry in _objectOwner/StateTable
+ // -> all objects in _inventory have this type
+ // - image can be exchanged (background overlay)
+ kObjectV0TypeBG = 1, // background object
+ // - without owner/state, not pickupable (room only)
+ // -> without entry in _objectOwner/StateTable
+ // - image cannot be exchanged (part of background image)
+ kObjectV0TypeActor = 2 // object is an actor
+};
+
enum ObjectClass {
kObjectClassNeverClip = 20,
kObjectClassAlwaysClip = 21,
diff --git a/engines/scumm/palette.cpp b/engines/scumm/palette.cpp
index 2c10758730..bd085dd4d5 100644
--- a/engines/scumm/palette.cpp
+++ b/engines/scumm/palette.cpp
@@ -823,7 +823,7 @@ void ScummEngine::setShadowPalette(int slot, int redScale, int greenScale, int b
if (slot < 0 || slot >= NUM_SHADOW_PALETTE)
error("setShadowPalette: invalid slot %d", slot);
- if (startColor < 0 || startColor > 255 || endColor < 0 || startColor > 255 || endColor < startColor)
+ if (startColor < 0 || startColor > 255 || endColor < 0 || endColor > 255 || endColor < startColor)
error("setShadowPalette: invalid range from %d to %d", startColor, endColor);
table = _shadowPalette + slot * 256;
diff --git a/engines/scumm/player_apple2.cpp b/engines/scumm/player_apple2.cpp
new file mode 100644
index 0000000000..a8e150caa9
--- /dev/null
+++ b/engines/scumm/player_apple2.cpp
@@ -0,0 +1,500 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * 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/engine.h"
+#include "scumm/player_apple2.h"
+#include "scumm/scumm.h"
+
+namespace Scumm {
+
+/************************************
+ * Apple-II sound-resource parsers
+ ************************************/
+
+/*
+ * SoundFunction1: frequency up/down
+ */
+class AppleII_SoundFunction1_FreqUpDown : public AppleII_SoundFunction {
+public:
+ virtual void init(Player_AppleII *player, const byte *params) {
+ _player = player;
+ _delta = params[0];
+ _count = params[1];
+ _interval = params[2];
+ _limit = params[3];
+ _decInterval = (params[4] >= 0x40);
+ }
+
+ virtual bool update() { // D085
+ if (_decInterval) {
+ do {
+ _update(_interval, _count);
+ _interval -= _delta;
+ } while (_interval >= _limit);
+ } else {
+ do {
+ _update(_interval, _count);
+ _interval += _delta;
+ } while (_interval < _limit);
+ }
+ return true;
+ }
+
+private:
+ void _update(int interval /*a*/, int count /*y*/) { // D076
+ assert(interval > 0); // 0 == 256?
+ assert(count > 0); // 0 == 256?
+
+ for (; count >= 0; --count) {
+ _player->speakerToggle();
+ _player->generateSamples(17 + 5 * interval);
+ }
+ }
+
+protected:
+ int _delta;
+ int _count;
+ byte _interval; // must be unsigned byte ("interval < delta" possible)
+ int _limit;
+ bool _decInterval;
+};
+
+/*
+ * SoundFunction2: symmetric wave (~)
+ */
+class AppleII_SoundFunction2_SymmetricWave : public AppleII_SoundFunction {
+public:
+ virtual void init(Player_AppleII *player, const byte *params) {
+ _player = player;
+ _params = params;
+ _pos = 1;
+ }
+
+ virtual bool update() { // D0D6
+ // while (pos = 1; pos < 256; ++pos)
+ if (_pos < 256) {
+ byte interval = _params[_pos];
+ if (interval == 0xFF)
+ return true;
+ _update(interval, _params[0] /*, LD12F=interval*/);
+
+ ++_pos;
+ return false;
+ }
+ return true;
+ }
+
+private:
+ void _update(int interval /*a*/, int count) { // D0EF
+ if (interval == 0xFE) {
+ _player->wait(interval, 10);
+ } else {
+ assert(count > 0); // 0 == 256?
+ assert(interval > 0); // 0 == 256?
+
+ int a = (interval >> 3) + count;
+ for (int y = a; y > 0; --y) {
+ _player->generateSamples(1292 - 5*interval);
+ _player->speakerToggle();
+
+ _player->generateSamples(1287 - 5*interval);
+ _player->speakerToggle();
+ }
+ }
+ }
+
+protected:
+ const byte *_params;
+ int _pos;
+};
+
+/*
+ * SoundFunction3: asymmetric wave (__-)
+ */
+class AppleII_SoundFunction3_AsymmetricWave : public AppleII_SoundFunction {
+public:
+ virtual void init(Player_AppleII *player, const byte *params) {
+ _player = player;
+ _params = params;
+ _pos = 1;
+ }
+
+ virtual bool update() { // D132
+ // while (pos = 1; pos < 256; ++pos)
+ if (_pos < 256) {
+ byte interval = _params[_pos];
+ if (interval == 0xFF)
+ return true;
+ _update(interval, _params[0]);
+
+ ++_pos;
+ return false;
+ }
+ return true;
+ }
+
+private:
+ void _update(int interval /*a*/, int count /*LD12D*/) { // D14B
+ if (interval == 0xFE) {
+ _player->wait(interval, 70);
+ } else {
+ assert(interval > 0); // 0 == 256?
+ assert(count > 0); // 0 == 256?
+
+ for (int y = count; y > 0; --y) {
+ _player->generateSamples(1289 - 5*interval);
+ _player->speakerToggle();
+ }
+ }
+ }
+
+protected:
+ const byte *_params;
+ int _pos;
+};
+
+/*
+ * SoundFunction4: polyphone (2 voices)
+ */
+class AppleII_SoundFunction4_Polyphone : public AppleII_SoundFunction {
+public:
+ virtual void init(Player_AppleII *player, const byte *params) {
+ _player = player;
+ _params = params;
+ _updateRemain1 = 80;
+ _updateRemain2 = 10;
+ _count = 0;
+ }
+
+ virtual bool update() { // D170
+ // while (_params[0] != 0x01)
+ if (_params[0] != 0x01) {
+ if (_count == 0) // prepare next loop
+ nextLoop(_params[0], _params[1], _params[2]);
+ if (loopIteration()) // loop finished -> fetch next parameter set
+ _params += 3;
+ return false;
+ }
+ return true;
+ }
+
+private:
+ /*
+ * prepare for next parameter set loop
+ */
+ void nextLoop(byte param0, byte param1, byte param2) { // LD182
+ _count = (-param2 << 8) | 0x3;
+
+ _bitmask1 = 0x3;
+ _bitmask2 = 0x3;
+
+ _updateInterval2 = param0;
+ if (_updateInterval2 == 0)
+ _bitmask2 = 0x0;
+
+ _updateInterval1 = param1;
+ if (_updateInterval1 == 0) {
+ _bitmask1 = 0x0;
+ if (_bitmask2 != 0) {
+ _bitmask1 = _bitmask2;
+ _bitmask2 = 0;
+ _updateInterval1 = _updateInterval2;
+ }
+ }
+
+ _speakerShiftReg = 0;
+ }
+
+ /*
+ * perform one loop iteration
+ * Returns true if loop finished
+ */
+ bool loopIteration() { // D1A2
+ --_updateRemain1;
+ --_updateRemain2;
+
+ if (_updateRemain2 == 0) {
+ _updateRemain2 = _updateInterval2;
+ // use only first voice's data (bitmask1) if both voices are triggered
+ if (_updateRemain1 != 0) {
+ _speakerShiftReg ^= _bitmask2;
+ }
+ }
+
+ if (_updateRemain1 == 0) {
+ _updateRemain1 = _updateInterval1;
+ _speakerShiftReg ^= _bitmask1;
+ }
+
+ if (_speakerShiftReg & 0x1)
+ _player->speakerToggle();
+ _speakerShiftReg >>= 1;
+ _player->generateSamples(42); /* actually 42.5 */
+
+ ++_count;
+ return (_count == 0);
+ }
+
+protected:
+ const byte *_params;
+
+ byte _updateRemain1;
+ byte _updateRemain2;
+
+ uint16 _count;
+ byte _bitmask1;
+ byte _bitmask2;
+ byte _updateInterval1;
+ byte _updateInterval2;
+ byte _speakerShiftReg;
+};
+
+/*
+ * SoundFunction5: periodic noise
+ */
+class AppleII_SoundFunction5_Noise : public AppleII_SoundFunction {
+public:
+ virtual void init(Player_AppleII *player, const byte *params) {
+ _player = player;
+ _index = 0;
+ _param0 = params[0];
+ assert(_param0 > 0);
+ }
+
+ virtual bool update() { // D222
+ const byte noiseMask[] = {
+ 0x3F, 0x3F, 0x7F, 0x7F, 0x7F, 0x7F, 0xFF, 0xFF, 0xFF, 0x0F, 0x0F
+ };
+
+ // while (i = 0; i < 10; ++i)
+ if (_index < 10) {
+ int count = _param0;
+ do {
+ _update(noise() & noiseMask[_index], 1);
+ --count;
+ } while (count > 0);
+
+ ++_index;
+ return false;
+ }
+
+ return true;
+ }
+
+private:
+ void _update(int interval /*a*/, int count) { // D270
+ assert(count > 0); // 0 == 256?
+ if (interval == 0)
+ interval = 256;
+
+ for (int i = count; i > 0; --i) {
+ _player->generateSamples(10 + 5*interval);
+ _player->speakerToggle();
+
+ _player->generateSamples(5 + 5*interval);
+ _player->speakerToggle();
+ }
+ }
+
+ byte /*a*/ noise() { // D261
+ static int pos = 0; // initial value?
+ byte result = _noiseTable[pos];
+ pos = (pos + 1) % 256;
+ return result;
+ }
+
+protected:
+ int _index;
+ int _param0;
+
+private:
+ static const byte _noiseTable[256];
+};
+
+// LD000[loc] ^ LD00A[loc]
+const byte AppleII_SoundFunction5_Noise::_noiseTable[256] = {
+ 0x65, 0x1b, 0xda, 0x11, 0x61, 0xe5, 0x77, 0x57, 0x92, 0xc8, 0x51, 0x1c, 0xd4, 0x91, 0x62, 0x63,
+ 0x00, 0x38, 0x57, 0xd5, 0x18, 0xd8, 0xdc, 0x40, 0x03, 0x86, 0xd3, 0x2f, 0x10, 0x11, 0xd8, 0x3c,
+ 0xbe, 0x00, 0x19, 0xc5, 0xd2, 0xc3, 0xca, 0x34, 0x00, 0x28, 0xbf, 0xb9, 0x18, 0x20, 0x01, 0xcc,
+ 0xda, 0x08, 0xbc, 0x75, 0x7c, 0xb0, 0x8d, 0xe0, 0x09, 0x18, 0xbf, 0x5d, 0xe9, 0x8c, 0x75, 0x64,
+ 0xe5, 0xb5, 0x5d, 0xe0, 0xb7, 0x7d, 0xe9, 0x8c, 0x55, 0x65, 0xc5, 0xb5, 0x5d, 0xd8, 0x09, 0x0d,
+ 0x64, 0xf0, 0xf0, 0x08, 0x63, 0x03, 0x00, 0x55, 0x35, 0xc0, 0x00, 0x20, 0x74, 0xa5, 0x1e, 0xe3,
+ 0x00, 0x06, 0x3c, 0x52, 0xd1, 0x70, 0xd0, 0x57, 0x02, 0xf0, 0x00, 0xb6, 0xfc, 0x02, 0x11, 0x9a,
+ 0x3b, 0xc8, 0x38, 0xdf, 0x1a, 0xb0, 0xd1, 0xb8, 0xd0, 0x18, 0x8a, 0x4a, 0xea, 0x1b, 0x12, 0x5d,
+ 0x29, 0x58, 0xd8, 0x43, 0xb8, 0x2d, 0xd2, 0x61, 0x10, 0x3c, 0x0c, 0x5d, 0x1b, 0x61, 0x10, 0x3c,
+ 0x0a, 0x5d, 0x1d, 0x61, 0x10, 0x3c, 0x0b, 0x19, 0x88, 0x21, 0xc0, 0x21, 0x07, 0x00, 0x65, 0x62,
+ 0x08, 0xe9, 0x36, 0x40, 0x20, 0x41, 0x06, 0x00, 0x20, 0x00, 0x00, 0xed, 0xa3, 0x00, 0x88, 0x06,
+ 0x98, 0x01, 0x5d, 0x7f, 0x02, 0x1d, 0x78, 0x03, 0x60, 0xcb, 0x3a, 0x01, 0xbd, 0x78, 0x02, 0x5d,
+ 0x7e, 0x03, 0x1d, 0xf5, 0xa6, 0x40, 0x81, 0xb4, 0xd0, 0x8d, 0xd3, 0xd0, 0x6d, 0xd5, 0x61, 0x48,
+ 0x61, 0x4d, 0xd1, 0xc8, 0xb1, 0xd8, 0x69, 0xff, 0x61, 0xd9, 0xed, 0xa0, 0xfe, 0x19, 0x91, 0x37,
+ 0x19, 0x37, 0x00, 0xf1, 0x00, 0x01, 0x1f, 0x00, 0xad, 0xc1, 0x01, 0x01, 0x2e, 0x00, 0x40, 0xc6,
+ 0x7a, 0x9b, 0x95, 0x43, 0xfc, 0x18, 0xd2, 0x9e, 0x2a, 0x5a, 0x4b, 0x2a, 0xb6, 0x87, 0x30, 0x6c
+};
+
+/************************************
+ * Apple-II player
+ ************************************/
+
+Player_AppleII::Player_AppleII(ScummEngine *scumm, Audio::Mixer *mixer)
+ : _mixer(mixer), _vm(scumm), _soundFunc(0) {
+ resetState();
+ setSampleRate(_mixer->getOutputRate());
+ _mixer->playStream(Audio::Mixer::kPlainSoundType, &_soundHandle, this, -1, Audio::Mixer::kMaxChannelVolume, 0, DisposeAfterUse::NO, true);
+}
+
+Player_AppleII::~Player_AppleII() {
+ _mixer->stopHandle(_soundHandle);
+ delete _soundFunc;
+}
+
+void Player_AppleII::resetState() {
+ _soundNr = 0;
+ _type = 0;
+ _loop = 0;
+ _params = NULL;
+ _speakerState = 0;
+ delete _soundFunc;
+ _soundFunc = 0;
+ _sampleConverter.reset();
+}
+
+void Player_AppleII::startSound(int nr) {
+ Common::StackLock lock(_mutex);
+
+ byte *data = _vm->getResourceAddress(rtSound, nr);
+ assert(data);
+ byte *ptr1 = data + 4;
+
+ resetState();
+ _soundNr = nr;
+ _type = ptr1[0];
+ _loop = ptr1[1];
+ _params = &ptr1[2];
+
+ switch (_type) {
+ case 0: // empty (nothing to play)
+ resetState();
+ return;
+ case 1:
+ _soundFunc = new AppleII_SoundFunction1_FreqUpDown();
+ break;
+ case 2:
+ _soundFunc = new AppleII_SoundFunction2_SymmetricWave();
+ break;
+ case 3:
+ _soundFunc = new AppleII_SoundFunction3_AsymmetricWave();
+ break;
+ case 4:
+ _soundFunc = new AppleII_SoundFunction4_Polyphone();
+ break;
+ case 5:
+ _soundFunc = new AppleII_SoundFunction5_Noise();
+ break;
+ }
+ _soundFunc->init(this, _params);
+
+ assert(_loop > 0);
+
+ debug(4, "startSound %d: type %d, loop %d",
+ nr, _type, _loop);
+}
+
+bool Player_AppleII::updateSound() {
+ if (!_soundFunc)
+ return false;
+
+ if (_soundFunc->update()) {
+ --_loop;
+ if (_loop <= 0) {
+ delete _soundFunc;
+ _soundFunc = 0;
+ } else {
+ // reset function state on each loop
+ _soundFunc->init(this, _params);
+ }
+ }
+
+ return true;
+}
+
+void Player_AppleII::stopAllSounds() {
+ Common::StackLock lock(_mutex);
+ resetState();
+}
+
+void Player_AppleII::stopSound(int nr) {
+ Common::StackLock lock(_mutex);
+ if (_soundNr == nr) {
+ resetState();
+ }
+}
+
+int Player_AppleII::getSoundStatus(int nr) const {
+ Common::StackLock lock(_mutex);
+ return (_soundNr == nr);
+}
+
+int Player_AppleII::getMusicTimer() {
+ /* Apple-II sounds are synchronous -> no music timer */
+ return 0;
+}
+
+int Player_AppleII::readBuffer(int16 *buffer, const int numSamples) {
+ Common::StackLock lock(_mutex);
+
+ if (!_soundNr)
+ return 0;
+
+ int samplesLeft = numSamples;
+ do {
+ int nSamplesRead = _sampleConverter.readSamples(buffer, samplesLeft);
+ samplesLeft -= nSamplesRead;
+ buffer += nSamplesRead;
+ } while ((samplesLeft > 0) && updateSound());
+
+ // reset state if sound is played completely
+ if (!_soundFunc && (_sampleConverter.availableSize() == 0))
+ resetState();
+
+ return numSamples - samplesLeft;
+}
+
+/************************************
+ * Apple-II sound-resource helpers
+ ************************************/
+
+// toggle speaker on/off
+void Player_AppleII::speakerToggle() {
+ _speakerState ^= 0x1;
+}
+
+void Player_AppleII::generateSamples(int cycles) {
+ _sampleConverter.addCycles(_speakerState, cycles);
+}
+
+void Player_AppleII::wait(int interval, int count /*y*/) {
+ assert(count > 0); // 0 == 256?
+ assert(interval > 0); // 0 == 256?
+ generateSamples(11 + count*(8 + 5 * interval));
+}
+
+} // End of namespace Scumm
diff --git a/engines/scumm/player_apple2.h b/engines/scumm/player_apple2.h
new file mode 100644
index 0000000000..b4a7d409fb
--- /dev/null
+++ b/engines/scumm/player_apple2.h
@@ -0,0 +1,297 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef SCUMM_PLAYER_APPLEII_H
+#define SCUMM_PLAYER_APPLEII_H
+
+#include "common/mutex.h"
+#include "common/scummsys.h"
+#include "common/memstream.h"
+#include "scumm/music.h"
+#include "audio/audiostream.h"
+#include "audio/mixer.h"
+#include "audio/softsynth/sid.h"
+
+namespace Scumm {
+
+class ScummEngine;
+
+/*
+ * Optimized for use with periodical read/write phases when the buffer
+ * is filled in a write phase and completely read in a read phase.
+ * The growing strategy is optimized for repeated small (e.g. 2 bytes)
+ * single writes resulting in large buffers
+ * (avg.: 4KB, max: 18KB @ 16bit/22.050kHz (MM sound21)).
+ */
+class SampleBuffer {
+public:
+ SampleBuffer() : _data(0) {
+ clear();
+ }
+
+ ~SampleBuffer() {
+ free(_data);
+ }
+
+ void clear() {
+ free(_data);
+ _data = 0;
+ _capacity = 0;
+ _writePos = 0;
+ _readPos = 0;
+ }
+
+ void ensureFree(uint32 needed) {
+ // if data was read completely, reset read/write pos to front
+ if ((_writePos != 0) && (_writePos == _readPos)) {
+ _writePos = 0;
+ _readPos = 0;
+ }
+
+ // check for enough space at end of buffer
+ uint32 freeEndCnt = _capacity - _writePos;
+ if (needed <= freeEndCnt)
+ return;
+
+ uint32 avail = availableSize();
+
+ // check for enough space at beginning and end of buffer
+ if (needed <= _readPos + freeEndCnt) {
+ // move unread data to front of buffer
+ memmove(_data, _data + _readPos, avail);
+ _writePos = avail;
+ _readPos = 0;
+ } else { // needs a grow
+ byte *old_data = _data;
+ uint32 new_len = avail + needed;
+
+ _capacity = new_len + 2048;
+ _data = (byte *)malloc(_capacity);
+
+ if (old_data) {
+ // copy old unread data to front of new buffer
+ memcpy(_data, old_data + _readPos, avail);
+ free(old_data);
+ _writePos = avail;
+ _readPos = 0;
+ }
+ }
+ }
+
+ uint32 availableSize() const {
+ if (_readPos >= _writePos)
+ return 0;
+ return _writePos - _readPos;
+ }
+
+ uint32 write(const void *dataPtr, uint32 dataSize) {
+ ensureFree(dataSize);
+ memcpy(_data + _writePos, dataPtr, dataSize);
+ _writePos += dataSize;
+ return dataSize;
+ }
+
+ uint32 read(byte *dataPtr, uint32 dataSize) {
+ uint32 avail = availableSize();
+ if (avail == 0)
+ return 0;
+ if (dataSize > avail)
+ dataSize = avail;
+ memcpy(dataPtr, _data + _readPos, dataSize);
+ _readPos += dataSize;
+ return dataSize;
+ }
+
+private:
+ uint32 _writePos;
+ uint32 _readPos;
+ uint32 _capacity;
+ byte *_data;
+};
+
+// CPU_CLOCK according to AppleWin
+static const double APPLEII_CPU_CLOCK = 1020484.5; // ~ 1.02 MHz
+
+/*
+ * Converts the 1-bit speaker state values into audio samples.
+ * This is done by aggregation of the speaker states at each
+ * CPU cycle in a sampling period into an audio sample.
+ */
+class SampleConverter {
+private:
+ void addSampleToBuffer(int sample) {
+ int16 value = sample * _volume / _maxVolume;
+ _buffer.write(&value, sizeof(value));
+ }
+
+public:
+ SampleConverter() :
+ _cyclesPerSampleFP(0),
+ _missingCyclesFP(0),
+ _sampleCyclesSumFP(0),
+ _volume(_maxVolume)
+ {}
+
+ ~SampleConverter() {}
+
+ void reset() {
+ _missingCyclesFP = 0;
+ _sampleCyclesSumFP = 0;
+ _buffer.clear();
+ }
+
+ uint32 availableSize() const {
+ return _buffer.availableSize();
+ }
+
+ void setMusicVolume(int vol) {
+ assert(vol >= 0 && vol <= _maxVolume);
+ _volume = vol;
+ }
+
+ void setSampleRate(int rate) {
+ /* ~46 CPU cycles per sample @ 22.05kHz */
+ _cyclesPerSampleFP = int(APPLEII_CPU_CLOCK * (1 << PREC_SHIFT) / rate);
+ reset();
+ }
+
+ void addCycles(byte level, const int cycles) {
+ /* convert to fixed precision floats */
+ int cyclesFP = cycles << PREC_SHIFT;
+
+ // step 1: if cycles are left from the last call, process them first
+ if (_missingCyclesFP > 0) {
+ int n = (_missingCyclesFP < cyclesFP) ? _missingCyclesFP : cyclesFP;
+ if (level)
+ _sampleCyclesSumFP += n;
+ cyclesFP -= n;
+ _missingCyclesFP -= n;
+ if (_missingCyclesFP == 0) {
+ addSampleToBuffer(2*32767 * _sampleCyclesSumFP / _cyclesPerSampleFP - 32767);
+ } else {
+ return;
+ }
+ }
+
+ _sampleCyclesSumFP = 0;
+
+ // step 2: process blocks of cycles fitting into a whole sample
+ while (cyclesFP >= _cyclesPerSampleFP) {
+ addSampleToBuffer(level ? 32767 : -32767);
+ cyclesFP -= _cyclesPerSampleFP;
+ }
+
+ // step 3: remember cycles left for next call
+ if (cyclesFP > 0) {
+ _missingCyclesFP = _cyclesPerSampleFP - cyclesFP;
+ if (level)
+ _sampleCyclesSumFP = cyclesFP;
+ }
+ }
+
+ uint32 readSamples(void *buffer, int numSamples) {
+ return _buffer.read((byte *)buffer, numSamples * 2) / 2;
+ }
+
+private:
+ static const int PREC_SHIFT = 7;
+
+private:
+ int _cyclesPerSampleFP; /* (fixed precision) */
+ int _missingCyclesFP; /* (fixed precision) */
+ int _sampleCyclesSumFP; /* (fixed precision) */
+ int _volume; /* 0 - 256 */
+ static const int _maxVolume = 256;
+ SampleBuffer _buffer;
+};
+
+class Player_AppleII;
+
+class AppleII_SoundFunction {
+public:
+ AppleII_SoundFunction() {}
+ virtual ~AppleII_SoundFunction() {}
+ virtual void init(Player_AppleII *player, const byte *params) = 0;
+ /* returns true if finished */
+ virtual bool update() = 0;
+protected:
+ Player_AppleII *_player;
+};
+
+class Player_AppleII : public Audio::AudioStream, public MusicEngine {
+public:
+ Player_AppleII(ScummEngine *scumm, Audio::Mixer *mixer);
+ virtual ~Player_AppleII();
+
+ virtual void setMusicVolume(int vol) { _sampleConverter.setMusicVolume(vol); }
+ void setSampleRate(int rate) {
+ _sampleRate = rate;
+ _sampleConverter.setSampleRate(rate);
+ }
+ virtual void startSound(int sound);
+ virtual void stopSound(int sound);
+ virtual void stopAllSounds();
+ virtual int getSoundStatus(int sound) const;
+ virtual int getMusicTimer();
+
+ // AudioStream API
+ int readBuffer(int16 *buffer, const int numSamples);
+ bool isStereo() const { return false; }
+ bool endOfData() const { return false; }
+ int getRate() const { return _sampleRate; }
+
+public:
+ void speakerToggle();
+ void generateSamples(int cycles);
+ void wait(int interval, int count);
+
+private:
+ // sound number
+ int _soundNr;
+ // type of sound
+ int _type;
+ // number of loops left
+ int _loop;
+ // global sound param list
+ const byte *_params;
+ // speaker toggle state (0 / 1)
+ byte _speakerState;
+ // sound function
+ AppleII_SoundFunction *_soundFunc;
+ // cycle to sample converter
+ SampleConverter _sampleConverter;
+
+private:
+ ScummEngine *_vm;
+ Audio::Mixer *_mixer;
+ Audio::SoundHandle _soundHandle;
+ int _sampleRate;
+ Common::Mutex _mutex;
+
+private:
+ void resetState();
+ bool updateSound();
+};
+
+} // End of namespace Scumm
+
+#endif
diff --git a/engines/scumm/player_nes.cpp b/engines/scumm/player_nes.cpp
index 3f8bcef8b7..a6ffc9ed86 100644
--- a/engines/scumm/player_nes.cpp
+++ b/engines/scumm/player_nes.cpp
@@ -507,7 +507,7 @@ void APU::Reset () {
Frame.Cycles = 1;
}
-template <class T>
+template<class T>
int step(T &obj, int sampcycles, uint frame_Cycles, int frame_Num) {
int samppos = 0;
while (sampcycles) {
diff --git a/engines/scumm/player_pce.cpp b/engines/scumm/player_pce.cpp
index 786971c683..8d886ee008 100644
--- a/engines/scumm/player_pce.cpp
+++ b/engines/scumm/player_pce.cpp
@@ -269,13 +269,13 @@ void PSG_HuC6280::init() {
reset();
// Make waveform frequency table
- for(i = 0; i < 4096; i++) {
+ for (i = 0; i < 4096; i++) {
step = ((_clock / _rate) * 4096) / (i+1);
_waveFreqTable[(1 + i) & 0xFFF] = (uint32)step;
}
// Make noise frequency table
- for(i = 0; i < 32; i++) {
+ for (i = 0; i < 32; i++) {
step = ((_clock / _rate) * 32) / (i+1);
_noiseFreqTable[i] = (uint32)step;
}
@@ -283,7 +283,7 @@ void PSG_HuC6280::init() {
// Make volume table
// PSG_HuC6280 has 48dB volume range spread over 32 steps
step = 48.0 / 32.0;
- for(i = 0; i < 31; i++) {
+ for (i = 0; i < 31; i++) {
_volumeTable[i] = (uint16)level;
level /= pow(10.0, step / 20.0);
}
@@ -323,7 +323,7 @@ void PSG_HuC6280::write(int offset, byte data) {
case 0x04: // Channel control (key-on, DDA mode, volume)
// 1-to-0 transition of DDA bit resets waveform index
- if((chan->control & 0x40) && ((data & 0x40) == 0)) {
+ if ((chan->control & 0x40) && ((data & 0x40) == 0)) {
chan->index = 0;
}
chan->control = data;
@@ -383,9 +383,9 @@ void PSG_HuC6280::update(int16* samples, int sampleCnt) {
// Clear buffer
memset(samples, 0, 2 * sampleCnt * sizeof(int16));
- for(ch = 0; ch < 6; ch++) {
+ for (ch = 0; ch < 6; ch++) {
// Only look at enabled channels
- if(_channel[ch].control & 0x80) {
+ if (_channel[ch].control & 0x80) {
int lal = (_channel[ch].balance >> 4) & 0x0F;
int ral = (_channel[ch].balance >> 0) & 0x0F;
int al = _channel[ch].control & 0x1F;
@@ -395,25 +395,25 @@ void PSG_HuC6280::update(int16* samples, int sampleCnt) {
// Calculate volume just as the patent says
vll = (0x1F - lal) + (0x1F - al) + (0x1F - lmal);
- if(vll > 0x1F) vll = 0x1F;
+ if (vll > 0x1F) vll = 0x1F;
vlr = (0x1F - ral) + (0x1F - al) + (0x1F - rmal);
- if(vlr > 0x1F) vlr = 0x1F;
+ if (vlr > 0x1F) vlr = 0x1F;
vll = _volumeTable[vll];
vlr = _volumeTable[vlr];
// Check channel mode
- if(_channel[ch].control & 0x40) {
+ if (_channel[ch].control & 0x40) {
/* DDA mode */
- for(i = 0; i < sampleCnt; i++) {
+ for (i = 0; i < sampleCnt; i++) {
samples[2*i] += (int16)(vll * (_channel[ch].dda - 16));
samples[2*i + 1] += (int16)(vlr * (_channel[ch].dda - 16));
}
} else {
/* Waveform mode */
uint32 step = _waveFreqTable[_channel[ch].frequency];
- for(i = 0; i < sampleCnt; i += 1) {
+ for (i = 0; i < sampleCnt; i += 1) {
int offset;
int16 data;
offset = (_channel[ch].counter >> 12) & 0x1F;
diff --git a/engines/scumm/player_pce.h b/engines/scumm/player_pce.h
index eb6afd892a..427fb1ace6 100644
--- a/engines/scumm/player_pce.h
+++ b/engines/scumm/player_pce.h
@@ -76,7 +76,6 @@ public:
virtual ~Player_PCE();
virtual void setMusicVolume(int vol) { _maxvol = vol; }
- void startMusic(int songResIndex);
virtual void startSound(int sound);
virtual void stopSound(int sound);
virtual void stopAllSounds();
diff --git a/engines/scumm/player_sid.cpp b/engines/scumm/player_sid.cpp
index f0f60a3924..7a609364e5 100644
--- a/engines/scumm/player_sid.cpp
+++ b/engines/scumm/player_sid.cpp
@@ -683,7 +683,7 @@ void Player_SID::stopSound_intern(int soundResID) { // $5093
releaseResource(soundResID);
}
-void Player_SID::stopAllSounds_intern() { // $4CAA
+void Player_SID::stopMusic_intern() { // $4CAA
statusBits1B = 0;
isMusicPlaying = false;
@@ -1293,7 +1293,7 @@ int Player_SID::readBuffer(int16 *buffer, const int numSamples) {
_cpuCyclesLeft = timingProps[_videoSystem].cyclesPerFrame;
}
// fetch samples
- int sampleCount = _sid->updateClock(_cpuCyclesLeft, (short*)buffer, samplesLeft);
+ int sampleCount = _sid->updateClock(_cpuCyclesLeft, (short *)buffer, samplesLeft);
samplesLeft -= sampleCount;
buffer += sampleCount;
}
@@ -1352,7 +1352,7 @@ void Player_SID::stopSound(int nr) {
void Player_SID::stopAllSounds() {
Common::StackLock lock(_mutex);
- stopAllSounds_intern();
+ resetPlayerState();
}
int Player_SID::getSoundStatus(int nr) const {
diff --git a/engines/scumm/player_sid.h b/engines/scumm/player_sid.h
index baeb7bbef0..12e3573575 100644
--- a/engines/scumm/player_sid.h
+++ b/engines/scumm/player_sid.h
@@ -57,7 +57,6 @@ public:
virtual ~Player_SID();
virtual void setMusicVolume(int vol) { _maxvol = vol; }
- void startMusic(int songResIndex);
virtual void startSound(int sound);
virtual void stopSound(int sound);
virtual void stopAllSounds();
@@ -95,7 +94,7 @@ private:
void initMusic(int songResIndex); // $7de6
int initSound(int soundResID); // $4D0A
void stopSound_intern(int soundResID); // $5093
- void stopAllSounds_intern(); // $4CAA
+ void stopMusic_intern(); // $4CAA
void resetSID(); // $48D8
void update(); // $481B
diff --git a/engines/scumm/player_towns.cpp b/engines/scumm/player_towns.cpp
index f6f493a1e1..2588026e59 100644
--- a/engines/scumm/player_towns.cpp
+++ b/engines/scumm/player_towns.cpp
@@ -75,10 +75,19 @@ void Player_Towns::saveLoadWithSerializer(Serializer *ser) {
}
void Player_Towns::restoreAfterLoad() {
+ Common::Array<uint16> restoredSounds;
+
for (int i = 1; i < 9; i++) {
if (!_pcmCurrentSound[i].index || _pcmCurrentSound[i].index == 0xffff)
continue;
+ // Don't restart multichannel sounds more than once
+ if (Common::find(restoredSounds.begin(), restoredSounds.end(), _pcmCurrentSound[i].index) != restoredSounds.end())
+ continue;
+
+ if (!_v2)
+ restoredSounds.push_back(_pcmCurrentSound[i].index);
+
uint8 *ptr = _vm->getResourceAddress(rtSound, _pcmCurrentSound[i].index);
if (!ptr)
continue;
diff --git a/engines/scumm/player_v1.cpp b/engines/scumm/player_v1.cpp
index 8afede8c5a..8e784e9866 100644
--- a/engines/scumm/player_v1.cpp
+++ b/engines/scumm/player_v1.cpp
@@ -351,8 +351,8 @@ parse_again:
*_value_ptr_2 = _start_2;
}
debug(6, "chunk 1: %lu: %d step %d for %d, %lu: %d step %d for %d",
- (long)(_value_ptr - (uint*)_channels), _start, _delta, _time_left,
- (long)(_value_ptr_2 - (uint*)_channels), _start_2, _delta_2, _time_left_2);
+ (long)(_value_ptr - (uint *)_channels), _start, _delta, _time_left,
+ (long)(_value_ptr_2 - (uint *)_channels), _start_2, _delta_2, _time_left_2);
break;
case 2:
diff --git a/engines/scumm/player_v2a.cpp b/engines/scumm/player_v2a.cpp
index ed97c4098f..07fc77b301 100644
--- a/engines/scumm/player_v2a.cpp
+++ b/engines/scumm/player_v2a.cpp
@@ -31,7 +31,7 @@ namespace Scumm {
static uint32 CRCtable[256];
-static void InitCRC () {
+static void InitCRC() {
const uint32 poly = 0xEDB88320;
int i, j;
uint32 n;
@@ -44,7 +44,7 @@ static void InitCRC () {
}
}
-static uint32 GetCRC (byte *data, int len) {
+static uint32 GetCRC(byte *data, int len) {
uint32 CRC = 0xFFFFFFFF;
int i;
for (i = 0; i < len; i++)
@@ -131,7 +131,7 @@ public:
_mod->stopChannel(_id | (_chan[i].chan << 8));
} else {
_mod->setChannelVol(_id | (_chan[i].chan << 8),
- READ_BE_UINT16(_data + _chan[i].volbase + (_chan[i].volptr++ << 1)));
+ READ_BE_UINT16(_data + _chan[i].volbase + (_chan[i].volptr++ << 1)));
if (_chan[i].volptr == 0) {
_mod->stopChannel(_id | (_chan[i].chan << 8));
_chan[i].dur = 0;
@@ -163,7 +163,7 @@ public:
_chan[i].volptr = 0;
_chan[i].chan = READ_BE_UINT16(_data + _chan[i].dataptr + 6) & 0x3;
- if (_chan[i].dur) // if there's something playing, stop it
+ if (_chan[i].dur) // if there's something playing, stop it
_mod->stopChannel(_id | (_chan[i].chan << 8));
_chan[i].dur = READ_BE_UINT16(_data + _chan[i].dataptr + 4);
@@ -173,7 +173,8 @@ public:
int pan;
if ((_chan[i].chan == 0) || (_chan[i].chan == 3))
pan = -127;
- else pan = 127;
+ else
+ pan = 127;
int offset = READ_BE_UINT16(_data + _instoff + (inst << 5) + 0x14);
int len = READ_BE_UINT16(_data + _instoff + (inst << 5) + 0x18);
int loopoffset = READ_BE_UINT16(_data + _instoff + (inst << 5) + 0x16);
@@ -873,7 +874,7 @@ private:
uint16 _freq4;
int16 _step4;
- void updatefreq (uint16 &freq, int16 &step, uint16 min, uint16 max) {
+ void updatefreq(uint16 &freq, int16 &step, uint16 min, uint16 max) {
freq += step;
if (freq <= min) {
freq = min;
@@ -1004,8 +1005,7 @@ public:
if (_curvol == 0)
return false;
_mod->setChannelVol(_id, (_curvol << 2) | (_curvol >> 4));
- }
- else {
+ } else {
if (_freq1 < _freq2)
_curfreq++;
else
@@ -1691,7 +1691,7 @@ public:
assert(_id);
const uint16 _minvol[2] = {0x2E, 0x32};
int i;
- for (i = 0; i < 4; i++) {
+ for (i = 0; i < 4; i++) {
_mod->setChannelFreq(_id | (i << 8), BASE_FREQUENCY / _freq[i]);
_mod->setChannelVol(_id | (i << 8), _vol[i]);
}
@@ -1704,7 +1704,7 @@ public:
_vol[i] = _minvol[i];
_volmod[i] = -_volmod[i];
}
- _vol[i+2] = _vol[i];
+ _vol[i + 2] = _vol[i];
}
_freq[0] += _freqmod;
if (_freq[0] > 0x2BC) {
@@ -1731,113 +1731,113 @@ private:
if (crc == CRC) \
return new SOUND
-static V2A_Sound *findSound (unsigned long crc) {
- CRCToSound(0x8FAB08C4, V2A_Sound_SingleLooped(0x006C,0x2B58,0x016E,0x3F)); // Maniac 17
- CRCToSound(0xB673160A, V2A_Sound_SingleLooped(0x006C,0x1E78,0x01C2,0x1E)); // Maniac 38
- CRCToSound(0x4DB1D0B2, V2A_Sound_MultiLooped(0x0072,0x1BC8,0x023D,0x3F,0x0224,0x3F)); // Maniac 20
- CRCToSound(0x754D75EF, V2A_Sound_Single(0x0076,0x0738,0x01FC,0x3F)); // Maniac 10
- CRCToSound(0x6E3454AF, V2A_Sound_Single(0x0076,0x050A,0x017C,0x3F)); // Maniac 12
- CRCToSound(0x92F0BBB6, V2A_Sound_Single(0x0076,0x3288,0x012E,0x3F)); // Maniac 41
- CRCToSound(0xE1B13982, V2A_Sound_MultiLoopedDuration(0x0078,0x0040,0x007C,0x3F,0x007B,0x3F,0x001E)); // Maniac 21
- CRCToSound(0x288B16CF, V2A_Sound_MultiLoopedDuration(0x007A,0x0040,0x007C,0x3F,0x007B,0x3F,0x000A)); // Maniac 11
- CRCToSound(0xA7565268, V2A_Sound_MultiLoopedDuration(0x007A,0x0040,0x00F8,0x3F,0x00F7,0x3F,0x000A)); // Maniac 19
- CRCToSound(0x7D419BFC, V2A_Sound_MultiLoopedDuration(0x007E,0x0040,0x012C,0x3F,0x0149,0x3F,0x001E)); // Maniac 22
- CRCToSound(0x1B52280C, V2A_Sound_Single(0x0098,0x0A58,0x007F,0x32)); // Maniac 6
- CRCToSound(0x38D4A810, V2A_Sound_Single(0x0098,0x2F3C,0x0258,0x32)); // Maniac 7
- CRCToSound(0x09F98FC2, V2A_Sound_Single(0x0098,0x0A56,0x012C,0x32)); // Maniac 16
- CRCToSound(0x90440A65, V2A_Sound_Single(0x0098,0x0208,0x0078,0x28)); // Maniac 28
- CRCToSound(0x985C76EF, V2A_Sound_Single(0x0098,0x0D6E,0x00C8,0x32)); // Maniac 30
- CRCToSound(0x76156137, V2A_Sound_Single(0x0098,0x2610,0x017C,0x39)); // Maniac 39
- CRCToSound(0x5D95F88C, V2A_Sound_Single(0x0098,0x0A58,0x007F,0x1E)); // Maniac 65
- CRCToSound(0x92D704EA, V2A_Sound_SingleLooped(0x009C,0x29BC,0x012C,0x3F,0x1BD4,0x0DE8)); // Maniac 15
- CRCToSound(0x92F5513C, V2A_Sound_Single(0x009E,0x0DD4,0x01F4,0x3F)); // Maniac 13
- CRCToSound(0xCC2F3B5A, V2A_Sound_Single(0x009E,0x00DE,0x01AC,0x3F)); // Maniac 43
- CRCToSound(0x153207D3, V2A_Sound_Single(0x009E,0x0E06,0x02A8,0x3F)); // Maniac 67
- CRCToSound(0xC4F370CE, V2A_Sound_Single(0x00AE,0x0330,0x01AC,0x3F)); // Maniac 8
- CRCToSound(0x928C4BAC, V2A_Sound_Single(0x00AE,0x08D6,0x01AC,0x3F)); // Maniac 9
- CRCToSound(0x62D5B11F, V2A_Sound_Single(0x00AE,0x165C,0x01CB,0x3F)); // Maniac 27
- CRCToSound(0x3AB22CB5, V2A_Sound_Single(0x00AE,0x294E,0x012A,0x3F)); // Maniac 62
- CRCToSound(0x2D70BBE9, V2A_Sound_SingleLoopedPitchbend(0x00B4,0x1702,0x03E8,0x0190,0x3F,5)); // Maniac 64
- CRCToSound(0xFA4C1B1C, V2A_Sound_Special_Maniac69(0x00B2,0x1702,0x0190,0x3F)); // Maniac 69
- CRCToSound(0x19D50D67, V2A_Sound_Special_ManiacDing(0x00B6,0x0020,0x00C8,16,2)); // Maniac 14
- CRCToSound(0x3E6FBE15, V2A_Sound_Special_ManiacTentacle(0x00B2,0x0010,0x007C,0x016D,1)); // Maniac 25
- CRCToSound(0x5305753C, V2A_Sound_Special_ManiacTentacle(0x00B2,0x0010,0x007C,0x016D,7)); // Maniac 36
- CRCToSound(0x28895106, V2A_Sound_Special_Maniac59(0x00C0,0x00FE,0x00E9,0x0111,4,0x0A)); // Maniac 59
- CRCToSound(0xB641ACF6, V2A_Sound_Special_Maniac61(0x00C8,0x0100,0x00C8,0x01C2)); // Maniac 61
- CRCToSound(0xE1A91583, V2A_Sound_Special_ManiacPhone(0x00D0,0x0040,0x007C,0x3F,0x007B,0x3F,0x3C,5,6)); // Maniac 23
- CRCToSound(0x64816ED5, V2A_Sound_Special_ManiacPhone(0x00D0,0x0040,0x00BE,0x37,0x00BD,0x37,0x3C,5,6)); // Maniac 24
- CRCToSound(0x639D72C2, V2A_Sound_Special_Maniac46(0x00D0,0x10A4,0x0080,0x3F,0x28,3)); // Maniac 46
- CRCToSound(0xE8826D92, V2A_Sound_Special_ManiacTypewriter(0x00EC,0x025A,0x023C,0x3F,8,(const uint8 *)"\x20\x41\x04\x21\x08\x10\x13\x07", true)); // Maniac 45
- CRCToSound(0xEDFF3D41, V2A_Sound_Single(0x00F8,0x2ADE,0x01F8,0x3F)); // Maniac 42 (this should echo, but it's barely noticeable and I don't feel like doing it)
- CRCToSound(0x15606D06, V2A_Sound_Special_Maniac32(0x0148,0x0020,0x0168,0x0020,0x3F)); // Maniac 32
- CRCToSound(0x753EAFE3, V2A_Sound_Special_Maniac44(0x017C,0x0010,0x018C,0x0020,0x00C8,0x0080,0x3F)); // Maniac 44
- CRCToSound(0xB1AB065C, V2A_Sound_Music(0x0032,0x00B2,0x08B2,0x1222,0x1A52,0x23C2,0x3074,false)); // Maniac 50
- CRCToSound(0x091F5D9C, V2A_Sound_Music(0x0032,0x0132,0x0932,0x1802,0x23D2,0x3EA2,0x4F04,false)); // Maniac 58
-
- CRCToSound(0x8E2C8AB3, V2A_Sound_SingleLooped(0x005C,0x0F26,0x0168,0x3C)); // Zak 41
- CRCToSound(0x3792071F, V2A_Sound_SingleLooped(0x0060,0x1A18,0x06A4,0x3F)); // Zak 88
- CRCToSound(0xF192EDE9, V2A_Sound_SingleLooped(0x0062,0x0054,0x01FC,0x1E)); // Zak 68
- CRCToSound(0xC43B0245, V2A_Sound_Special_Zak70(0x006C,0x166E,0x00C8,0x0190,0x0320,0x0640,0x32)); // Zak 70
- CRCToSound(0xCEB51670, V2A_Sound_SingleLooped(0x00AC,0x26DC,0x012C,0x3F)); // Zak 42
- CRCToSound(0x10347B51, V2A_Sound_SingleLooped(0x006C,0x00E0,0x0594,0x3F)); // Zak 18
- CRCToSound(0x9D2FADC0, V2A_Sound_MultiLooped(0x0072,0x1FC8,0x016A,0x3F,0x01CE,0x3F)); // Zak 80
- CRCToSound(0xFAD2C676, V2A_Sound_MultiLooped(0x0076,0x0010,0x0080,0x3F,0x0090,0x3B)); // Zak 40
- CRCToSound(0x01508B48, V2A_Sound_Single(0x0076,0x0D8C,0x017C,0x3F)); // Zak 90
- CRCToSound(0x9C18DC46, V2A_Sound_Single(0x0076,0x0D8C,0x015E,0x3F)); // Zak 91
- CRCToSound(0xF98F7EAC, V2A_Sound_Single(0x0076,0x0D8C,0x0140,0x3F)); // Zak 92
- CRCToSound(0xC925FBEF, V2A_Sound_MultiLoopedDuration(0x0080,0x0010,0x0080,0x3F,0x0090,0x3B,0x0168)); // Zak 53
- CRCToSound(0xCAB35257, V2A_Sound_Special_Zak101(0x00DA,0x425C,0x023C,0x08F0,0x0640,0x0478,0x3F,0x012C)); // Zak 101
- CRCToSound(0xA31FE4FD, V2A_Sound_Single(0x0094,0x036A,0x00E1,0x3F)); // Zak 97
- CRCToSound(0x0A1AE0F5, V2A_Sound_Single(0x009E,0x0876,0x0168,0x3F)); // Zak 5
- CRCToSound(0xD01A66CB, V2A_Sound_Single(0x009E,0x04A8,0x0168,0x3F)); // Zak 47
- CRCToSound(0x5497B912, V2A_Sound_Single(0x009E,0x0198,0x01F4,0x3F)); // Zak 39
- CRCToSound(0x2B50362F, V2A_Sound_Single(0x009E,0x09B6,0x023D,0x3F)); // Zak 67
- CRCToSound(0x7BFB6E72, V2A_Sound_Single(0x009E,0x0D14,0x0078,0x3F)); // Zak 69
- CRCToSound(0xB803A792, V2A_Sound_Single(0x009E,0x2302,0x02BC,0x3F)); // Zak 78
- CRCToSound(0x7AB82E39, V2A_Sound_SingleLooped(0x00A0,0x2A3C,0x016E,0x3F,0x1018,0x1A24)); // Zak 100
- CRCToSound(0x28057CEC, V2A_Sound_Single(0x0098,0x0FEC,0x0140,0x32)); // Zak 63
- CRCToSound(0x1180A2FC, V2A_Sound_Single(0x0098,0x0F06,0x0190,0x32)); // Zak 64
- CRCToSound(0x12616755, V2A_Sound_Single(0x0098,0x14C8,0x023C,0x14)); // Zak 9
- CRCToSound(0x642723AA, V2A_Sound_Special_Zak37(0x00A2,0x1702,0x01F4,0x3F)); // Zak 37
- CRCToSound(0xDEE56848, V2A_Sound_Single(0x009A,0x0F86,0x0100,0x3F)); // Zak 93
- CRCToSound(0xF9BE27B8, V2A_Sound_Special_Zak37(0x011C,0x1704,0x0228,0x3F)); // Zak 113
- CRCToSound(0xC73487B2, V2A_Sound_Single(0x00B0,0x18BA,0x0478,0x3F)); // Zak 81
- CRCToSound(0x32D8F925, V2A_Sound_Single(0x00B0,0x2E46,0x00F0,0x3F)); // Zak 94
- CRCToSound(0x988C83A5, V2A_Sound_Single(0x00B0,0x0DE0,0x025B,0x3F)); // Zak 106
- CRCToSound(0x8F1E3B3D, V2A_Sound_Single(0x00B0,0x05FE,0x04E2,0x3F)); // Zak 107
- CRCToSound(0x0A2A7646, V2A_Sound_Single(0x00B0,0x36FE,0x016E,0x3F)); // Zak 43
- CRCToSound(0x6F1FC435, V2A_Sound_Single(0x00B0,0x2808,0x044C,0x3F)); // Zak 108
- CRCToSound(0x870EFC29, V2A_Sound_SingleLoopedPitchbend(0x00BA,0x0100,0x03E8,0x00C8,0x3F,3)); // Zak 55
- CRCToSound(0xED773699, V2A_Sound_Special_ManiacDing(0x00B4,0x0020,0x012C,8,4)); // Zak 3
- CRCToSound(0x0BF59774, V2A_Sound_Special_ZakStereoDing(0x00BE,0x0020,0x00F8,0x00F7,8,1)); // Zak 72
- CRCToSound(0x656FFEDE, V2A_Sound_Special_ZakStereoDing(0x00BE,0x0020,0x00C4,0x00C3,8,1)); // Zak 73
- CRCToSound(0xFC4D41E5, V2A_Sound_Special_ZakStereoDing(0x00BE,0x0020,0x00A5,0x00A4,8,1)); // Zak 74
- CRCToSound(0xC0DD2089, V2A_Sound_Special_ZakStereoDing(0x00BE,0x0020,0x009C,0x009B,8,1)); // Zak 75
- CRCToSound(0x627DFD92, V2A_Sound_Special_ZakStereoDing(0x00BE,0x0020,0x008B,0x008A,8,1)); // Zak 76
- CRCToSound(0x703E05C1, V2A_Sound_Special_ZakStereoDing(0x00BE,0x0020,0x007C,0x007B,8,1)); // Zak 77
- CRCToSound(0xB0F77006, V2A_Sound_Special_Zak52(0x00B0,0x01BC)); // Zak 52
- CRCToSound(0x5AE9D6A7, V2A_Sound_Special_ZakAirplane(0x00CA,0x22A4,0x0113,0x0227)); // Zak 109
- CRCToSound(0xABE0D3B0, V2A_Sound_Special_ZakAirplane(0x00CE,0x22A4,0x0227,0x0113)); // Zak 105
- CRCToSound(0x788CC749, V2A_Sound_Special_Zak71(0x00C8,0x0B37)); // Zak 71
- CRCToSound(0x2E2AB1FA, V2A_Sound_Special_Zak99(0x00D4,0x04F0,0x0FE3,0x0080,0x3F)); // Zak 99
- CRCToSound(0x1304CF20, V2A_Sound_Special_ManiacTypewriter(0x00DC,0x0624,0x023C,0x3C,2,(const uint8 *)"\x14\x11",false)); // Zak 79
- CRCToSound(0xAE68ED91, V2A_Sound_Special_Zak54(0x00D4,0x1A25,0x1E1E,0x0B80,0x01F4)); // Zak 54
- CRCToSound(0xA4F40F97, V2A_Sound_Special_Zak61(0x00E4,0x0020)); // Zak 61
- CRCToSound(0x348F85CE, V2A_Sound_Special_Zak62(0x00E4,0x0020)); // Zak 62
- CRCToSound(0xD473AB86, V2A_Sound_Special_ManiacTypewriter(0x0122,0x03E8,0x00BE,0x3F,7,(const uint8 *)"\x0F\x0B\x04\x0F\x1E\x0F\x66",false)); // Zak 46
- CRCToSound(0x84A0BA90, V2A_Sound_Special_Zak110(0x0126,0x0040,0x0136,0x0080,0x007C,0x0087)); // Zak 110
- CRCToSound(0x92680D9F, V2A_Sound_Special_Zak32(0x0140,0x0150,0x0010,0x0010)); // Zak 32
- CRCToSound(0xABFFDB02, V2A_Sound_Special_Zak86(0x01A2,0x2BAE)); // Zak 86
- CRCToSound(0x41045447, V2A_Sound_Special_Zak98(0x017A,0x0020)); // Zak 98
- CRCToSound(0xC8EEBD34, V2A_Sound_Special_Zak82(0x01A6,0x3900)); // Zak 82
- CRCToSound(0x42F9469F, V2A_Sound_Music(0x05F6,0x0636,0x0456,0x0516,0x05D6,0x05E6,0x0A36,true)); // Zak 96
- CRCToSound(0x038BBD78, V2A_Sound_Music(0x054E,0x05CE,0x044E,0x04BE,0x052E,0x053E,0x0BCE,true)); // Zak 85
- CRCToSound(0x06FFADC5, V2A_Sound_Music(0x0626,0x0686,0x0446,0x04F6,0x0606,0x0616,0x0C86,true)); // Zak 87
- CRCToSound(0xCE20ECF0, V2A_Sound_Music(0x0636,0x0696,0x0446,0x0576,0x0616,0x0626,0x0E96,true)); // Zak 114
- CRCToSound(0xBDA01BB6, V2A_Sound_Music(0x0678,0x06B8,0x0458,0x0648,0x0658,0x0668,0x0EB8,false)); // Zak 33
- CRCToSound(0x59976529, V2A_Sound_Music(0x088E,0x092E,0x048E,0x05EE,0x074E,0x07EE,0x112E,true)); // Zak 49
- CRCToSound(0xED1EED02, V2A_Sound_Music(0x08D0,0x0950,0x0440,0x07E0,0x08B0,0x08C0,0x1350,false)); // Zak 112
- CRCToSound(0x5A16C037, V2A_Sound_Music(0x634A,0x64CA,0x049A,0x18FA,0x398A,0x511A,0x6CCA,false)); // Zak 95
+static V2A_Sound *findSound(unsigned long crc) {
+ CRCToSound(0x8FAB08C4, V2A_Sound_SingleLooped(0x006C, 0x2B58, 0x016E, 0x3F)); // Maniac 17
+ CRCToSound(0xB673160A, V2A_Sound_SingleLooped(0x006C, 0x1E78, 0x01C2, 0x1E)); // Maniac 38
+ CRCToSound(0x4DB1D0B2, V2A_Sound_MultiLooped(0x0072, 0x1BC8, 0x023D, 0x3F, 0x0224, 0x3F)); // Maniac 20
+ CRCToSound(0x754D75EF, V2A_Sound_Single(0x0076, 0x0738, 0x01FC, 0x3F)); // Maniac 10
+ CRCToSound(0x6E3454AF, V2A_Sound_Single(0x0076, 0x050A, 0x017C, 0x3F)); // Maniac 12
+ CRCToSound(0x92F0BBB6, V2A_Sound_Single(0x0076, 0x3288, 0x012E, 0x3F)); // Maniac 41
+ CRCToSound(0xE1B13982, V2A_Sound_MultiLoopedDuration(0x0078, 0x0040, 0x007C, 0x3F, 0x007B, 0x3F, 0x001E)); // Maniac 21
+ CRCToSound(0x288B16CF, V2A_Sound_MultiLoopedDuration(0x007A, 0x0040, 0x007C, 0x3F, 0x007B, 0x3F, 0x000A)); // Maniac 11
+ CRCToSound(0xA7565268, V2A_Sound_MultiLoopedDuration(0x007A, 0x0040, 0x00F8, 0x3F, 0x00F7, 0x3F, 0x000A)); // Maniac 19
+ CRCToSound(0x7D419BFC, V2A_Sound_MultiLoopedDuration(0x007E, 0x0040, 0x012C, 0x3F, 0x0149, 0x3F, 0x001E)); // Maniac 22
+ CRCToSound(0x1B52280C, V2A_Sound_Single(0x0098, 0x0A58, 0x007F, 0x32)); // Maniac 6
+ CRCToSound(0x38D4A810, V2A_Sound_Single(0x0098, 0x2F3C, 0x0258, 0x32)); // Maniac 7
+ CRCToSound(0x09F98FC2, V2A_Sound_Single(0x0098, 0x0A56, 0x012C, 0x32)); // Maniac 16
+ CRCToSound(0x90440A65, V2A_Sound_Single(0x0098, 0x0208, 0x0078, 0x28)); // Maniac 28
+ CRCToSound(0x985C76EF, V2A_Sound_Single(0x0098, 0x0D6E, 0x00C8, 0x32)); // Maniac 30
+ CRCToSound(0x76156137, V2A_Sound_Single(0x0098, 0x2610, 0x017C, 0x39)); // Maniac 39
+ CRCToSound(0x5D95F88C, V2A_Sound_Single(0x0098, 0x0A58, 0x007F, 0x1E)); // Maniac 65
+ CRCToSound(0x92D704EA, V2A_Sound_SingleLooped(0x009C, 0x29BC, 0x012C, 0x3F, 0x1BD4, 0x0DE8)); // Maniac 15
+ CRCToSound(0x92F5513C, V2A_Sound_Single(0x009E, 0x0DD4, 0x01F4, 0x3F)); // Maniac 13
+ CRCToSound(0xCC2F3B5A, V2A_Sound_Single(0x009E, 0x00DE, 0x01AC, 0x3F)); // Maniac 43
+ CRCToSound(0x153207D3, V2A_Sound_Single(0x009E, 0x0E06, 0x02A8, 0x3F)); // Maniac 67
+ CRCToSound(0xC4F370CE, V2A_Sound_Single(0x00AE, 0x0330, 0x01AC, 0x3F)); // Maniac 8
+ CRCToSound(0x928C4BAC, V2A_Sound_Single(0x00AE, 0x08D6, 0x01AC, 0x3F)); // Maniac 9
+ CRCToSound(0x62D5B11F, V2A_Sound_Single(0x00AE, 0x165C, 0x01CB, 0x3F)); // Maniac 27
+ CRCToSound(0x3AB22CB5, V2A_Sound_Single(0x00AE, 0x294E, 0x012A, 0x3F)); // Maniac 62
+ CRCToSound(0x2D70BBE9, V2A_Sound_SingleLoopedPitchbend(0x00B4, 0x1702, 0x03E8, 0x0190, 0x3F, 5)); // Maniac 64
+ CRCToSound(0xFA4C1B1C, V2A_Sound_Special_Maniac69(0x00B2, 0x1702, 0x0190, 0x3F)); // Maniac 69
+ CRCToSound(0x19D50D67, V2A_Sound_Special_ManiacDing(0x00B6, 0x0020, 0x00C8, 16, 2)); // Maniac 14
+ CRCToSound(0x3E6FBE15, V2A_Sound_Special_ManiacTentacle(0x00B2, 0x0010, 0x007C, 0x016D, 1)); // Maniac 25
+ CRCToSound(0x5305753C, V2A_Sound_Special_ManiacTentacle(0x00B2, 0x0010, 0x007C, 0x016D, 7)); // Maniac 36
+ CRCToSound(0x28895106, V2A_Sound_Special_Maniac59(0x00C0, 0x00FE, 0x00E9, 0x0111, 4, 0x0A)); // Maniac 59
+ CRCToSound(0xB641ACF6, V2A_Sound_Special_Maniac61(0x00C8, 0x0100, 0x00C8, 0x01C2)); // Maniac 61
+ CRCToSound(0xE1A91583, V2A_Sound_Special_ManiacPhone(0x00D0, 0x0040, 0x007C, 0x3F, 0x007B, 0x3F, 0x3C, 5, 6)); // Maniac 23
+ CRCToSound(0x64816ED5, V2A_Sound_Special_ManiacPhone(0x00D0, 0x0040, 0x00BE, 0x37, 0x00BD, 0x37, 0x3C, 5, 6)); // Maniac 24
+ CRCToSound(0x639D72C2, V2A_Sound_Special_Maniac46(0x00D0, 0x10A4, 0x0080, 0x3F, 0x28, 3)); // Maniac 46
+ CRCToSound(0xE8826D92, V2A_Sound_Special_ManiacTypewriter(0x00EC, 0x025A, 0x023C, 0x3F, 8, (const uint8 *)"\x20\x41\x04\x21\x08\x10\x13\x07", true)); // Maniac 45
+ CRCToSound(0xEDFF3D41, V2A_Sound_Single(0x00F8, 0x2ADE, 0x01F8, 0x3F)); // Maniac 42 (this should echo, but it's barely noticeable and I don't feel like doing it)
+ CRCToSound(0x15606D06, V2A_Sound_Special_Maniac32(0x0148, 0x0020, 0x0168, 0x0020, 0x3F)); // Maniac 32
+ CRCToSound(0x753EAFE3, V2A_Sound_Special_Maniac44(0x017C, 0x0010, 0x018C, 0x0020, 0x00C8, 0x0080, 0x3F)); // Maniac 44
+ CRCToSound(0xB1AB065C, V2A_Sound_Music(0x0032, 0x00B2, 0x08B2, 0x1222, 0x1A52, 0x23C2, 0x3074, false)); // Maniac 50
+ CRCToSound(0x091F5D9C, V2A_Sound_Music(0x0032, 0x0132, 0x0932, 0x1802, 0x23D2, 0x3EA2, 0x4F04, false)); // Maniac 58
+
+ CRCToSound(0x8E2C8AB3, V2A_Sound_SingleLooped(0x005C, 0x0F26, 0x0168, 0x3C)); // Zak 41
+ CRCToSound(0x3792071F, V2A_Sound_SingleLooped(0x0060, 0x1A18, 0x06A4, 0x3F)); // Zak 88
+ CRCToSound(0xF192EDE9, V2A_Sound_SingleLooped(0x0062, 0x0054, 0x01FC, 0x1E)); // Zak 68
+ CRCToSound(0xC43B0245, V2A_Sound_Special_Zak70(0x006C, 0x166E, 0x00C8, 0x0190, 0x0320, 0x0640, 0x32)); // Zak 70
+ CRCToSound(0xCEB51670, V2A_Sound_SingleLooped(0x00AC, 0x26DC, 0x012C, 0x3F)); // Zak 42
+ CRCToSound(0x10347B51, V2A_Sound_SingleLooped(0x006C, 0x00E0, 0x0594, 0x3F)); // Zak 18
+ CRCToSound(0x9D2FADC0, V2A_Sound_MultiLooped(0x0072, 0x1FC8, 0x016A, 0x3F, 0x01CE, 0x3F)); // Zak 80
+ CRCToSound(0xFAD2C676, V2A_Sound_MultiLooped(0x0076, 0x0010, 0x0080, 0x3F, 0x0090, 0x3B)); // Zak 40
+ CRCToSound(0x01508B48, V2A_Sound_Single(0x0076, 0x0D8C, 0x017C, 0x3F)); // Zak 90
+ CRCToSound(0x9C18DC46, V2A_Sound_Single(0x0076, 0x0D8C, 0x015E, 0x3F)); // Zak 91
+ CRCToSound(0xF98F7EAC, V2A_Sound_Single(0x0076, 0x0D8C, 0x0140, 0x3F)); // Zak 92
+ CRCToSound(0xC925FBEF, V2A_Sound_MultiLoopedDuration(0x0080, 0x0010, 0x0080, 0x3F, 0x0090, 0x3B, 0x0168)); // Zak 53
+ CRCToSound(0xCAB35257, V2A_Sound_Special_Zak101(0x00DA, 0x425C, 0x023C, 0x08F0, 0x0640, 0x0478, 0x3F, 0x012C)); // Zak 101
+ CRCToSound(0xA31FE4FD, V2A_Sound_Single(0x0094, 0x036A, 0x00E1, 0x3F)); // Zak 97
+ CRCToSound(0x0A1AE0F5, V2A_Sound_Single(0x009E, 0x0876, 0x0168, 0x3F)); // Zak 5
+ CRCToSound(0xD01A66CB, V2A_Sound_Single(0x009E, 0x04A8, 0x0168, 0x3F)); // Zak 47
+ CRCToSound(0x5497B912, V2A_Sound_Single(0x009E, 0x0198, 0x01F4, 0x3F)); // Zak 39
+ CRCToSound(0x2B50362F, V2A_Sound_Single(0x009E, 0x09B6, 0x023D, 0x3F)); // Zak 67
+ CRCToSound(0x7BFB6E72, V2A_Sound_Single(0x009E, 0x0D14, 0x0078, 0x3F)); // Zak 69
+ CRCToSound(0xB803A792, V2A_Sound_Single(0x009E, 0x2302, 0x02BC, 0x3F)); // Zak 78
+ CRCToSound(0x7AB82E39, V2A_Sound_SingleLooped(0x00A0, 0x2A3C, 0x016E, 0x3F, 0x1018, 0x1A24)); // Zak 100
+ CRCToSound(0x28057CEC, V2A_Sound_Single(0x0098, 0x0FEC, 0x0140, 0x32)); // Zak 63
+ CRCToSound(0x1180A2FC, V2A_Sound_Single(0x0098, 0x0F06, 0x0190, 0x32)); // Zak 64
+ CRCToSound(0x12616755, V2A_Sound_Single(0x0098, 0x14C8, 0x023C, 0x14)); // Zak 9
+ CRCToSound(0x642723AA, V2A_Sound_Special_Zak37(0x00A2, 0x1702, 0x01F4, 0x3F)); // Zak 37
+ CRCToSound(0xDEE56848, V2A_Sound_Single(0x009A, 0x0F86, 0x0100, 0x3F)); // Zak 93
+ CRCToSound(0xF9BE27B8, V2A_Sound_Special_Zak37(0x011C, 0x1704, 0x0228, 0x3F)); // Zak 113
+ CRCToSound(0xC73487B2, V2A_Sound_Single(0x00B0, 0x18BA, 0x0478, 0x3F)); // Zak 81
+ CRCToSound(0x32D8F925, V2A_Sound_Single(0x00B0, 0x2E46, 0x00F0, 0x3F)); // Zak 94
+ CRCToSound(0x988C83A5, V2A_Sound_Single(0x00B0, 0x0DE0, 0x025B, 0x3F)); // Zak 106
+ CRCToSound(0x8F1E3B3D, V2A_Sound_Single(0x00B0, 0x05FE, 0x04E2, 0x3F)); // Zak 107
+ CRCToSound(0x0A2A7646, V2A_Sound_Single(0x00B0, 0x36FE, 0x016E, 0x3F)); // Zak 43
+ CRCToSound(0x6F1FC435, V2A_Sound_Single(0x00B0, 0x2808, 0x044C, 0x3F)); // Zak 108
+ CRCToSound(0x870EFC29, V2A_Sound_SingleLoopedPitchbend(0x00BA, 0x0100, 0x03E8, 0x00C8, 0x3F, 3)); // Zak 55
+ CRCToSound(0xED773699, V2A_Sound_Special_ManiacDing(0x00B4, 0x0020, 0x012C, 8, 4)); // Zak 3
+ CRCToSound(0x0BF59774, V2A_Sound_Special_ZakStereoDing(0x00BE, 0x0020, 0x00F8, 0x00F7, 8, 1)); // Zak 72
+ CRCToSound(0x656FFEDE, V2A_Sound_Special_ZakStereoDing(0x00BE, 0x0020, 0x00C4, 0x00C3, 8, 1)); // Zak 73
+ CRCToSound(0xFC4D41E5, V2A_Sound_Special_ZakStereoDing(0x00BE, 0x0020, 0x00A5, 0x00A4, 8, 1)); // Zak 74
+ CRCToSound(0xC0DD2089, V2A_Sound_Special_ZakStereoDing(0x00BE, 0x0020, 0x009C, 0x009B, 8, 1)); // Zak 75
+ CRCToSound(0x627DFD92, V2A_Sound_Special_ZakStereoDing(0x00BE, 0x0020, 0x008B, 0x008A, 8, 1)); // Zak 76
+ CRCToSound(0x703E05C1, V2A_Sound_Special_ZakStereoDing(0x00BE, 0x0020, 0x007C, 0x007B, 8, 1)); // Zak 77
+ CRCToSound(0xB0F77006, V2A_Sound_Special_Zak52(0x00B0, 0x01BC)); // Zak 52
+ CRCToSound(0x5AE9D6A7, V2A_Sound_Special_ZakAirplane(0x00CA, 0x22A4, 0x0113, 0x0227)); // Zak 109
+ CRCToSound(0xABE0D3B0, V2A_Sound_Special_ZakAirplane(0x00CE, 0x22A4, 0x0227, 0x0113)); // Zak 105
+ CRCToSound(0x788CC749, V2A_Sound_Special_Zak71(0x00C8, 0x0B37)); // Zak 71
+ CRCToSound(0x2E2AB1FA, V2A_Sound_Special_Zak99(0x00D4, 0x04F0, 0x0FE3, 0x0080, 0x3F)); // Zak 99
+ CRCToSound(0x1304CF20, V2A_Sound_Special_ManiacTypewriter(0x00DC, 0x0624, 0x023C, 0x3C, 2, (const uint8 *)"\x14\x11", false)); // Zak 79
+ CRCToSound(0xAE68ED91, V2A_Sound_Special_Zak54(0x00D4, 0x1A25, 0x1E1E, 0x0B80, 0x01F4)); // Zak 54
+ CRCToSound(0xA4F40F97, V2A_Sound_Special_Zak61(0x00E4, 0x0020)); // Zak 61
+ CRCToSound(0x348F85CE, V2A_Sound_Special_Zak62(0x00E4, 0x0020)); // Zak 62
+ CRCToSound(0xD473AB86, V2A_Sound_Special_ManiacTypewriter(0x0122, 0x03E8, 0x00BE, 0x3F, 7, (const uint8 *)"\x0F\x0B\x04\x0F\x1E\x0F\x66", false)); // Zak 46
+ CRCToSound(0x84A0BA90, V2A_Sound_Special_Zak110(0x0126, 0x0040, 0x0136, 0x0080, 0x007C, 0x0087)); // Zak 110
+ CRCToSound(0x92680D9F, V2A_Sound_Special_Zak32(0x0140, 0x0150, 0x0010, 0x0010)); // Zak 32
+ CRCToSound(0xABFFDB02, V2A_Sound_Special_Zak86(0x01A2, 0x2BAE)); // Zak 86
+ CRCToSound(0x41045447, V2A_Sound_Special_Zak98(0x017A, 0x0020)); // Zak 98
+ CRCToSound(0xC8EEBD34, V2A_Sound_Special_Zak82(0x01A6, 0x3900)); // Zak 82
+ CRCToSound(0x42F9469F, V2A_Sound_Music(0x05F6, 0x0636, 0x0456, 0x0516, 0x05D6, 0x05E6, 0x0A36, true)); // Zak 96
+ CRCToSound(0x038BBD78, V2A_Sound_Music(0x054E, 0x05CE, 0x044E, 0x04BE, 0x052E, 0x053E, 0x0BCE, true)); // Zak 85
+ CRCToSound(0x06FFADC5, V2A_Sound_Music(0x0626, 0x0686, 0x0446, 0x04F6, 0x0606, 0x0616, 0x0C86, true)); // Zak 87
+ CRCToSound(0xCE20ECF0, V2A_Sound_Music(0x0636, 0x0696, 0x0446, 0x0576, 0x0616, 0x0626, 0x0E96, true)); // Zak 114
+ CRCToSound(0xBDA01BB6, V2A_Sound_Music(0x0678, 0x06B8, 0x0458, 0x0648, 0x0658, 0x0668, 0x0EB8, false)); // Zak 33
+ CRCToSound(0x59976529, V2A_Sound_Music(0x088E, 0x092E, 0x048E, 0x05EE, 0x074E, 0x07EE, 0x112E, true)); // Zak 49
+ CRCToSound(0xED1EED02, V2A_Sound_Music(0x08D0, 0x0950, 0x0440, 0x07E0, 0x08B0, 0x08C0, 0x1350, false)); // Zak 112
+ CRCToSound(0x5A16C037, V2A_Sound_Music(0x634A, 0x64CA, 0x049A, 0x18FA, 0x398A, 0x511A, 0x6CCA, false)); // Zak 95
return NULL;
}
@@ -1860,11 +1860,11 @@ Player_V2A::~Player_V2A() {
delete _mod;
}
-void Player_V2A::setMusicVolume (int vol) {
+void Player_V2A::setMusicVolume(int vol) {
_mod->setMusicVolume(vol);
}
-int Player_V2A::getSoundSlot (int id) const {
+int Player_V2A::getSoundSlot(int id) const {
int i;
for (i = 0; i < V2A_MAXSLOTS; i++) {
if (_slot[i].id == id)
@@ -1914,8 +1914,10 @@ void Player_V2A::startSound(int nr) {
}
stopSound(nr);
int i = getSoundSlot();
- if (i == -1)
+ if (i == -1) {
+ delete snd;
return;
+ }
_slot[i].id = nr;
_slot[i].sound = snd;
_slot[i].sound->start(_mod, nr, data);
@@ -1938,7 +1940,7 @@ void Player_V2A::updateSound() {
}
int Player_V2A::getMusicTimer() {
- return 0; // FIXME - need to keep track of playing music resources
+ return 0; // FIXME - need to keep track of playing music resources
}
int Player_V2A::getSoundStatus(int nr) const {
diff --git a/engines/scumm/player_v2a.h b/engines/scumm/player_v2a.h
index 719d5491ea..fe20b43846 100644
--- a/engines/scumm/player_v2a.h
+++ b/engines/scumm/player_v2a.h
@@ -63,7 +63,7 @@ private:
Player_MOD *_mod;
soundSlot _slot[V2A_MAXSLOTS];
- int getSoundSlot (int id = 0) const;
+ int getSoundSlot(int id = 0) const;
static void update_proc(void *param);
void updateSound();
};
diff --git a/engines/scumm/resource.cpp b/engines/scumm/resource.cpp
index f445a44ded..b2093e9c1a 100644
--- a/engines/scumm/resource.cpp
+++ b/engines/scumm/resource.cpp
@@ -232,7 +232,7 @@ void ScummEngine::askForDisk(const char *filename, int disknum) {
#endif
} else {
sprintf(buf, "Cannot find file: '%s'", filename);
- InfoDialog dialog(this, (char*)buf);
+ InfoDialog dialog(this, (char *)buf);
runDialog(dialog);
error("Cannot find file: '%s'", filename);
}
@@ -350,7 +350,7 @@ void ScummEngine_v7::readIndexBlock(uint32 blocktype, uint32 itemsize) {
switch (blocktype) {
case MKTAG('A','N','A','M'): // Used by: The Dig, FT
num = _fileHandle->readUint16LE();
- ptr = (char*)malloc(num * 9);
+ ptr = (char *)malloc(num * 9);
_fileHandle->read(ptr, num * 9);
_imuseDigital->setAudioNames(num, ptr);
break;
diff --git a/engines/scumm/room.cpp b/engines/scumm/room.cpp
index 63cbef8944..9ee8fb93a9 100644
--- a/engines/scumm/room.cpp
+++ b/engines/scumm/room.cpp
@@ -747,7 +747,7 @@ void ScummEngine_v3old::resetRoomSubBlocks() {
}
ptr = roomptr + *(roomptr + 0x15);
- size = numOfBoxes * SIZEOF_BOX_C64 + 1;
+ size = numOfBoxes * SIZEOF_BOX_V0 + 1;
_res->createResource(rtMatrix, 2, size + 1);
getResourceAddress(rtMatrix, 2)[0] = numOfBoxes;
diff --git a/engines/scumm/saveload.cpp b/engines/scumm/saveload.cpp
index 3ab13df032..beac077fd1 100644
--- a/engines/scumm/saveload.cpp
+++ b/engines/scumm/saveload.cpp
@@ -875,21 +875,21 @@ void ScummEngine::saveOrLoad(Serializer *s) {
// vm.localvar grew from 25 to 40 script entries and then from
// 16 to 32 bit variables (but that wasn't reflect here)... and
// THEN from 16 to 25 variables.
- MKARRAY2_OLD(ScummEngine, vm.localvar[0][0], sleUint16, 17, 25, (byte*)vm.localvar[1] - (byte*)vm.localvar[0], VER(8), VER(8)),
- MKARRAY2_OLD(ScummEngine, vm.localvar[0][0], sleUint16, 17, 40, (byte*)vm.localvar[1] - (byte*)vm.localvar[0], VER(9), VER(14)),
+ MKARRAY2_OLD(ScummEngine, vm.localvar[0][0], sleUint16, 17, 25, (byte *)vm.localvar[1] - (byte *)vm.localvar[0], VER(8), VER(8)),
+ MKARRAY2_OLD(ScummEngine, vm.localvar[0][0], sleUint16, 17, 40, (byte *)vm.localvar[1] - (byte *)vm.localvar[0], VER(9), VER(14)),
// We used to save 25 * 40 = 1000 blocks; but actually, each 'row consisted of 26 entry,
// i.e. 26 * 40 = 1040. Thus the last 40 blocks of localvar where not saved at all. To be
// able to load this screwed format, we use a trick: We load 26 * 38 = 988 blocks.
// Then, we mark the followin 12 blocks (24 bytes) as obsolete.
- MKARRAY2_OLD(ScummEngine, vm.localvar[0][0], sleUint16, 26, 38, (byte*)vm.localvar[1] - (byte*)vm.localvar[0], VER(15), VER(17)),
+ MKARRAY2_OLD(ScummEngine, vm.localvar[0][0], sleUint16, 26, 38, (byte *)vm.localvar[1] - (byte *)vm.localvar[0], VER(15), VER(17)),
MK_OBSOLETE_ARRAY(ScummEngine, vm.localvar[39][0], sleUint16, 12, VER(15), VER(17)),
// This was the first proper multi dimensional version of the localvars, with 32 bit values
- MKARRAY2_OLD(ScummEngine, vm.localvar[0][0], sleUint32, 26, 40, (byte*)vm.localvar[1] - (byte*)vm.localvar[0], VER(18), VER(19)),
+ MKARRAY2_OLD(ScummEngine, vm.localvar[0][0], sleUint32, 26, 40, (byte *)vm.localvar[1] - (byte *)vm.localvar[0], VER(18), VER(19)),
// Then we doubled the script slots again, from 40 to 80
- MKARRAY2(ScummEngine, vm.localvar[0][0], sleUint32, 26, NUM_SCRIPT_SLOT, (byte*)vm.localvar[1] - (byte*)vm.localvar[0], VER(20)),
+ MKARRAY2(ScummEngine, vm.localvar[0][0], sleUint32, 26, NUM_SCRIPT_SLOT, (byte *)vm.localvar[1] - (byte *)vm.localvar[0], VER(20)),
MKARRAY(ScummEngine, _resourceMapper[0], sleByte, 128, VER(8)),
@@ -1205,12 +1205,19 @@ void ScummEngine::saveOrLoad(Serializer *s) {
// Save/load local objects
//
s->saveLoadArrayOf(_objs, _numLocalObjects, sizeof(_objs[0]), objectEntries);
- if (s->isLoading() && s->getVersion() < VER(13)) {
- // Since roughly v13 of the save games, the objs storage has changed a bit
- for (i = _numObjectsInRoom; i < _numLocalObjects; i++) {
- _objs[i].obj_nr = 0;
+ if (s->isLoading()) {
+ if (s->getVersion() < VER(13)) {
+ // Since roughly v13 of the save games, the objs storage has changed a bit
+ for (i = _numObjectsInRoom; i < _numLocalObjects; i++)
+ _objs[i].obj_nr = 0;
+ } else if (_game.version == 0 && s->getVersion() < VER(91)) {
+ for (i = 0; i < _numLocalObjects; i++) {
+ // Merge object id and type (previously stored in flags)
+ if (_objs[i].obj_nr != 0 && OBJECT_V0_TYPE(_objs[i].obj_nr) == 0 && _objs[i].flags != 0)
+ _objs[i].obj_nr = OBJECT_V0(_objs[i].obj_nr, _objs[i].flags);
+ _objs[i].flags = 0;
+ }
}
-
}
@@ -1286,14 +1293,35 @@ void ScummEngine::saveOrLoad(Serializer *s) {
//
// Save/load palette data
- //
- if (_16BitPalette && !(_game.platform == Common::kPlatformFMTowns && s->isLoading() && s->getVersion() < VER(82))) {
+ // Don't save 16 bit palette in FM-Towns and PCE games, since it gets regenerated afterwards anyway.
+ if (_16BitPalette && !(_game.platform == Common::kPlatformFMTowns && s->getVersion() < VER(82)) && !((_game.platform == Common::kPlatformFMTowns || _game.platform == Common::kPlatformPCEngine) && s->getVersion() > VER(87))) {
s->saveLoadArrayOf(_16BitPalette, 512, sizeof(_16BitPalette[0]), sleUint16);
}
-#ifndef DISABLE_TOWNS_DUAL_LAYER_MODE
+
// FM-Towns specific (extra palette data, color cycle data, etc.)
- if (s->getVersion() >= VER(82)) {
+ // In earlier save game versions (below 87) the FM-Towns specific data would get saved (and loaded) even in non FM-Towns games.
+ // This would cause an unnecessary save file incompatibility between DS (which uses the DISABLE_TOWNS_DUAL_LAYER_MODE setting)
+ // and other ports.
+ // In version 88 and later the save files from FM-Towns targets are compatible between DS and other platforms, too.
+
+#ifdef DISABLE_TOWNS_DUAL_LAYER_MODE
+ byte hasTownsData = 0;
+ if (_game.platform == Common::kPlatformFMTowns && s->getVersion() > VER(87))
+ s->saveLoadArrayOf(&hasTownsData, 1, sizeof(byte), sleByte);
+
+ if (hasTownsData) {
+ // Skip FM-Towns specific data
+ for (int i = 69 * sizeof(uint8) + 44 * sizeof(int16); i; i--)
+ s->loadByte();
+ }
+
+#else
+ byte hasTownsData = ((_game.platform == Common::kPlatformFMTowns && s->getVersion() >= VER(87)) || (s->getVersion() >= VER(82) && s->getVersion() < VER(87))) ? 1 : 0;
+ if (_game.platform == Common::kPlatformFMTowns && s->getVersion() > VER(87))
+ s->saveLoadArrayOf(&hasTownsData, 1, sizeof(byte), sleByte);
+
+ if (hasTownsData) {
const SaveLoadEntry townsFields[] = {
MKLINE(Common::Rect, left, sleInt16, VER(82)),
MKLINE(Common::Rect, top, sleInt16, VER(82)),
@@ -1316,6 +1344,8 @@ void ScummEngine::saveOrLoad(Serializer *s) {
s->saveLoadArrayOf(&_curStringRect, 1, sizeof(_curStringRect), townsFields);
s->saveLoadArrayOf(_townsCharsetColorMap, 16, sizeof(_townsCharsetColorMap[0]), sleUint8);
s->saveLoadEntries(this, townsExtraEntries);
+ } else if (_game.platform == Common::kPlatformFMTowns && s->getVersion() >= VER(82)) {
+ warning("Save file is missing FM-Towns specific graphic data (game was apparently saved on another platform)");
}
#endif
@@ -1474,6 +1504,14 @@ void ScummEngine_v0::saveOrLoad(Serializer *s) {
const SaveLoadEntry v0Entrys[] = {
MKLINE(ScummEngine_v0, _currentMode, sleByte, VER(78)),
MKLINE(ScummEngine_v0, _currentLights, sleByte, VER(78)),
+ MKLINE(ScummEngine_v0, _activeVerb, sleByte, VER(92)),
+ MKLINE(ScummEngine_v0, _activeObject, sleUint16, VER(92)),
+ MKLINE(ScummEngine_v0, _activeObject2, sleUint16, VER(92)),
+ MKLINE(ScummEngine_v0, _cmdVerb, sleByte, VER(92)),
+ MKLINE(ScummEngine_v0, _cmdObject, sleUint16, VER(92)),
+ MKLINE(ScummEngine_v0, _cmdObject2, sleUint16, VER(92)),
+ MKLINE(ScummEngine_v0, _walkToObject, sleUint16, VER(92)),
+ MKLINE(ScummEngine_v0, _walkToObjectState, sleByte, VER(92)),
MKEND()
};
s->saveLoadEntries(this, v0Entrys);
@@ -1500,7 +1538,7 @@ void ScummEngine_v5::saveOrLoad(Serializer *s) {
ScummEngine::saveOrLoad(s);
const SaveLoadEntry cursorEntries[] = {
- MKARRAY2(ScummEngine_v5, _cursorImages[0][0], sleUint16, 16, 4, (byte*)_cursorImages[1] - (byte*)_cursorImages[0], VER(44)),
+ MKARRAY2(ScummEngine_v5, _cursorImages[0][0], sleUint16, 16, 4, (byte *)_cursorImages[1] - (byte *)_cursorImages[0], VER(44)),
MKARRAY(ScummEngine_v5, _cursorHotspots[0], sleByte, 8, VER(44)),
MKEND()
};
diff --git a/engines/scumm/saveload.h b/engines/scumm/saveload.h
index 16c225d20e..d5f7ea526e 100644
--- a/engines/scumm/saveload.h
+++ b/engines/scumm/saveload.h
@@ -47,7 +47,7 @@ namespace Scumm {
* only saves/loads those which are valid for the version of the savegame
* which is being loaded/saved currently.
*/
-#define CURRENT_VER 86
+#define CURRENT_VER 92
/**
* An auxillary macro, used to specify savegame versions. We use this instead
@@ -74,13 +74,13 @@ namespace Scumm {
* what POD means refer to <http://en.wikipedia.org/wiki/Plain_Old_Data_Structures> or
* to <http://www.informit.com/guides/content.asp?g=cplusplus&seqNum=32&rl=1>)
*/
-#define OFFS(type,item) (((ptrdiff_t)(&((type*)42)->type::item))-42)
+#define OFFS(type,item) (((ptrdiff_t)(&((type *)42)->type::item))-42)
/**
* Similar to the OFFS macro, this macro computes the size (in bytes) of a
* member of a given struct/class type.
*/
-#define SIZE(type,item) sizeof(((type*)42)->type::item)
+#define SIZE(type,item) sizeof(((type *)42)->type::item)
// Any item that is still in use automatically gets a maxVersion equal to CURRENT_VER
#define MKLINE(type,item,saveas,minVer) {OFFS(type,item),saveas,SIZE(type,item),minVer,CURRENT_VER}
diff --git a/engines/scumm/script.cpp b/engines/scumm/script.cpp
index cfc4b3c419..39420ee974 100644
--- a/engines/scumm/script.cpp
+++ b/engines/scumm/script.cpp
@@ -28,7 +28,9 @@
#include "scumm/object.h"
#include "scumm/resource.h"
#include "scumm/util.h"
+#include "scumm/scumm_v0.h"
#include "scumm/scumm_v2.h"
+#include "scumm/sound.h"
#include "scumm/verbs.h"
namespace Scumm {
@@ -130,8 +132,6 @@ void ScummEngine::runObjectScript(int object, int entry, bool freezeResistant, b
initializeLocals(slot, vars);
- // V0 Ensure we don't try and access objects via index inside the script
- _v0ObjectIndex = false;
runScriptNested(slot);
}
@@ -195,9 +195,10 @@ int ScummEngine::getVerbEntrypoint(int obj, int entry) {
return verboffs + 8 + READ_LE_UINT32(ptr + 1);
} else if (_game.version <= 2) {
do {
+ const int kFallbackEntry = (_game.version == 0 ? 0x0F : 0xFF);
if (!*verbptr)
return 0;
- if (*verbptr == entry || *verbptr == 0xFF)
+ if (*verbptr == entry || *verbptr == kFallbackEntry)
break;
verbptr += 2;
} while (1);
@@ -935,6 +936,17 @@ void ScummEngine::runExitScript() {
}
if (VAR_EXIT_SCRIPT2 != 0xFF && VAR(VAR_EXIT_SCRIPT2))
runScript(VAR(VAR_EXIT_SCRIPT2), 0, 0, 0);
+
+#ifdef ENABLE_SCUMM_7_8
+ // WORKAROUND: The spider lair (room 44) will optionally play the sound
+ // of trickling water (sound 215), but it never stops it. The same sound
+ // effect is also used in room 33, so let's do the same fade out that it
+ // does in that room's exit script.
+ if (_game.id == GID_DIG && _currentRoom == 44) {
+ int scriptCmds[] = { 14, 215, 0x600, 0, 30, 0, 0, 0 };
+ _sound->soundKludge(scriptCmds, ARRAYSIZE(scriptCmds));
+ }
+#endif
}
void ScummEngine::runEntryScript() {
@@ -988,7 +1000,7 @@ void ScummEngine::killScriptsAndResources() {
for (i = 0; i < _numNewNames; i++) {
const int obj = _newNames[i];
if (obj) {
- const int owner = getOwner(obj);
+ const int owner = getOwner((_game.version != 0 ? obj : OBJECT_V0_ID(obj)));
// We can delete custom name resources if either the object is
// no longer in use (i.e. not owned by anyone anymore); or if
// it is an object which is owned by a room.
@@ -1118,6 +1130,183 @@ void ScummEngine::checkAndRunSentenceScript() {
runScript(sentenceScript, 0, 0, localParamList);
}
+void ScummEngine_v0::walkToActorOrObject(int object) {
+ int x, y, dir;
+ Actor_v0 *a = (Actor_v0 *)derefActor(VAR(VAR_EGO), "walkToObject");
+
+ _walkToObject = object;
+ _walkToObjectState = kWalkToObjectStateWalk;
+
+ if (OBJECT_V0_TYPE(object) == kObjectV0TypeActor) {
+ walkActorToActor(VAR(VAR_EGO), OBJECT_V0_ID(object), 4);
+ x = a->getRealPos().x;
+ y = a->getRealPos().y;
+ } else {
+ walkActorToObject(VAR(VAR_EGO), object);
+ getObjectXYPos(object, x, y, dir);
+ }
+
+ VAR(6) = x;
+ VAR(7) = y;
+
+ // actor must not move if frozen
+ if (a->_miscflags & kActorMiscFlagFreeze)
+ a->stopActorMoving();
+}
+
+bool ScummEngine_v0::checkPendingWalkAction() {
+ // before a sentence script is executed, it might be necessary to walk to
+ // and pickup objects before. Check if such an action is pending and handle
+ // it if available.
+ if (_walkToObjectState == kWalkToObjectStateDone)
+ return false;
+
+ int actor = VAR(VAR_EGO);
+ Actor_v0 *a = (Actor_v0 *)derefActor(actor, "checkPendingWalkAction");
+
+ // wait until walking or turning action is finished
+ if (a->_moving)
+ return true;
+
+ // after walking and turning finally execute the script
+ if (_walkToObjectState == kWalkToObjectStateTurn) {
+ runSentenceScript();
+ // change actor facing
+ } else {
+ int x, y, distX, distY;
+ if (objIsActor(_walkToObject)) {
+ Actor *b = derefActor(objToActor(_walkToObject), "checkPendingWalkAction(2)");
+ x = b->getRealPos().x;
+ y = b->getRealPos().y;
+ if (x < a->getRealPos().x)
+ x += 4;
+ else
+ x -= 4;
+ } else {
+ getObjectXYPos(_walkToObject, x, y);
+ }
+ AdjustBoxResult abr = a->adjustXYToBeInBox(x, y);
+ distX = ABS(a->getRealPos().x - abr.x);
+ distY = ABS(a->getRealPos().y - abr.y);
+
+ if (distX <= 4 && distY <= 8) {
+ if (objIsActor(_walkToObject)) { // walk to actor finished
+ // make actors turn to each other
+ a->faceToObject(_walkToObject);
+ int otherActor = objToActor(_walkToObject);
+ // ignore the plant
+ if (otherActor != 19) {
+ Actor *b = derefActor(otherActor, "checkPendingWalkAction(3)");
+ b->faceToObject(actorToObj(actor));
+ }
+ } else { // walk to object finished
+ int tmpX, tmpY, dir;
+ getObjectXYPos(_walkToObject, tmpX, tmpY, dir);
+ a->turnToDirection(dir);
+ }
+ _walkToObjectState = kWalkToObjectStateTurn;
+ return true;
+ }
+ }
+
+ _walkToObjectState = kWalkToObjectStateDone;
+ return false;
+}
+
+void ScummEngine_v0::checkAndRunSentenceScript() {
+ if (checkPendingWalkAction())
+ return;
+
+ if (!_sentenceNum || _sentence[_sentenceNum - 1].freezeCount)
+ return;
+
+ SentenceTab &st = _sentence[_sentenceNum - 1];
+
+ if (st.preposition && st.objectB == st.objectA) {
+ _sentenceNum--;
+ return;
+ }
+
+ _currentScript = 0xFF;
+
+ assert(st.objectA);
+
+ // If two objects are involved, at least one must be in the actors inventory
+ if (st.objectB &&
+ (OBJECT_V0_TYPE(st.objectA) != kObjectV0TypeFG || _objectOwnerTable[st.objectA] != VAR(VAR_EGO)) &&
+ (OBJECT_V0_TYPE(st.objectB) != kObjectV0TypeFG || _objectOwnerTable[st.objectB] != VAR(VAR_EGO)))
+ {
+ if (getVerbEntrypoint(st.objectA, kVerbPickUp))
+ doSentence(kVerbPickUp, st.objectA, 0);
+ else if (getVerbEntrypoint(st.objectB, kVerbPickUp))
+ doSentence(kVerbPickUp, st.objectB, 0);
+ else
+ _sentenceNum--;
+ return;
+ }
+
+ _cmdVerb = st.verb;
+ _cmdObject = st.objectA;
+ _cmdObject2 = st.objectB;
+ _sentenceNum--;
+
+ // abort sentence execution if the number of nested scripts is too high.
+ // This might happen for instance if the sentence command depends on an
+ // object that the actor has to pick-up in a nested doSentence() call.
+ // If the actor is not able to pick-up the object (e.g. because it is not
+ // reachable or pickupable) a nested pick-up command is triggered again
+ // and again, so the actual sentence command will never be executed.
+ // In this case the sentence command has to be aborted.
+ _sentenceNestedCount++;
+ if (_sentenceNestedCount > 6) {
+ _sentenceNestedCount = 0;
+ _sentenceNum = 0;
+ return;
+ }
+
+ if (whereIsObject(st.objectA) != WIO_INVENTORY) {
+ if (_currentMode != kModeKeypad) {
+ walkToActorOrObject(st.objectA);
+ return;
+ }
+ } else if (st.objectB && whereIsObject(st.objectB) != WIO_INVENTORY) {
+ walkToActorOrObject(st.objectB);
+ return;
+ }
+
+ runSentenceScript();
+ if (_currentMode == kModeKeypad) {
+ _walkToObjectState = kWalkToObjectStateDone;
+ }
+}
+
+void ScummEngine_v0::runSentenceScript() {
+ _redrawSentenceLine = true;
+
+ if (getVerbEntrypoint(_cmdObject, _cmdVerb) != 0) {
+ // do not read in the dark
+ if (!(_cmdVerb == kVerbRead && _currentLights == 0)) {
+ VAR(VAR_ACTIVE_OBJECT2) = OBJECT_V0_ID(_cmdObject2);
+ runObjectScript(_cmdObject, _cmdVerb, false, false, NULL);
+ return;
+ }
+ } else {
+ if (_cmdVerb == kVerbGive) {
+ // no "give to"-script: give to other kid or ignore
+ int actor = OBJECT_V0_ID(_cmdObject2);
+ if (actor < 8)
+ setOwnerOf(_cmdObject, actor);
+ return;
+ }
+ }
+
+ if (_cmdVerb != kVerbWalkTo) {
+ // perform verb's fallback action
+ VAR(VAR_ACTIVE_VERB) = _cmdVerb;
+ runScript(3, 0, 0, 0);
+ }
+}
+
void ScummEngine_v2::runInputScript(int clickArea, int val, int mode) {
int args[24];
int verbScript;
diff --git a/engines/scumm/script_v0.cpp b/engines/scumm/script_v0.cpp
index e2d3f40e8e..45901186cd 100644
--- a/engines/scumm/script_v0.cpp
+++ b/engines/scumm/script_v0.cpp
@@ -27,6 +27,7 @@
#include "scumm/resource.h"
#include "scumm/scumm_v0.h"
#include "scumm/verbs.h"
+#include "scumm/util.h"
namespace Scumm {
@@ -50,7 +51,7 @@ void ScummEngine_v0::setupOpcodes() {
OPCODE(0x0b, o_setActorBitVar);
/* 0C */
OPCODE(0x0c, o_loadSound);
- OPCODE(0x0d, o_printEgo_c64);
+ OPCODE(0x0d, o_printEgo);
OPCODE(0x0e, o_putActorAtObject);
OPCODE(0x0f, o2_clearState02);
/* 10 */
@@ -59,7 +60,7 @@ void ScummEngine_v0::setupOpcodes() {
OPCODE(0x12, o2_panCameraTo);
OPCODE(0x13, o_lockCostume);
/* 14 */
- OPCODE(0x14, o_print_c64);
+ OPCODE(0x14, o_print);
OPCODE(0x15, o5_walkActorToActor);
OPCODE(0x16, o5_getRandomNr);
OPCODE(0x17, o2_clearState08);
@@ -79,9 +80,9 @@ void ScummEngine_v0::setupOpcodes() {
OPCODE(0x22, o4_saveLoadGame);
OPCODE(0x23, o_stopCurrentScript);
/* 24 */
- OPCODE(0x24, o_unknown2);
+ OPCODE(0x24, o_ifNotEqualActiveObject2);
OPCODE(0x25, o5_loadRoom);
- OPCODE(0x26, o_getClosestObjActor);
+ OPCODE(0x26, o_getClosestActor);
OPCODE(0x27, o2_getActorY);
/* 28 */
OPCODE(0x28, o5_equalZero);
@@ -91,7 +92,7 @@ void ScummEngine_v0::setupOpcodes() {
/* 2C */
OPCODE(0x2c, o_stopCurrentScript);
OPCODE(0x2d, o2_putActorInRoom);
- OPCODE(0x2e, o_print_c64);
+ OPCODE(0x2e, o_print);
OPCODE(0x2f, o2_ifState08);
/* 30 */
OPCODE(0x30, o_loadCostume);
@@ -101,7 +102,7 @@ void ScummEngine_v0::setupOpcodes() {
/* 34 */
OPCODE(0x34, o5_getDist);
OPCODE(0x35, o_stopCurrentScript);
- OPCODE(0x36, o2_walkActorToObject);
+ OPCODE(0x36, o_walkActorToObject);
OPCODE(0x37, o2_clearState04);
/* 38 */
OPCODE(0x38, o2_isLessEqual);
@@ -144,7 +145,7 @@ void ScummEngine_v0::setupOpcodes() {
OPCODE(0x56, o_getActorMoving);
OPCODE(0x57, o2_clearState08);
/* 58 */
- OPCODE(0x58, o_beginOverride);
+ OPCODE(0x58, o2_beginOverride);
OPCODE(0x59, o_stopCurrentScript);
OPCODE(0x5a, o2_add);
OPCODE(0x5b, o_getActorBitVar);
@@ -154,14 +155,14 @@ void ScummEngine_v0::setupOpcodes() {
OPCODE(0x5e, o2_walkActorTo);
OPCODE(0x5f, o2_ifState04);
/* 60 */
- OPCODE(0x60, o_cursorCommand);
+ OPCODE(0x60, o_setMode);
OPCODE(0x61, o2_putActor);
OPCODE(0x62, o2_stopScript);
OPCODE(0x63, o_stopCurrentScript);
/* 64 */
- OPCODE(0x64, o_ifActiveObject);
+ OPCODE(0x64, o_ifEqualActiveObject2);
OPCODE(0x65, o_stopCurrentScript);
- OPCODE(0x66, o_getClosestObjActor);
+ OPCODE(0x66, o_getClosestActor);
OPCODE(0x67, o5_getActorFacing);
/* 68 */
OPCODE(0x68, o5_isScriptRunning);
@@ -177,11 +178,11 @@ void ScummEngine_v0::setupOpcodes() {
OPCODE(0x70, o_lights);
OPCODE(0x71, o_getBitVar);
OPCODE(0x72, o_nop);
- OPCODE(0x73, o5_getObjectOwner);
+ OPCODE(0x73, o_getObjectOwner);
/* 74 */
OPCODE(0x74, o5_getDist);
- OPCODE(0x75, o_printEgo_c64);
- OPCODE(0x76, o2_walkActorToObject);
+ OPCODE(0x75, o_printEgo);
+ OPCODE(0x76, o_walkActorToObject);
OPCODE(0x77, o2_clearState04);
/* 78 */
OPCODE(0x78, o2_isGreater);
@@ -239,7 +240,7 @@ void ScummEngine_v0::setupOpcodes() {
OPCODE(0xa2, o4_saveLoadGame);
OPCODE(0xa3, o_stopCurrentScript);
/* A4 */
- OPCODE(0xa4, o_unknown2);
+ OPCODE(0xa4, o_ifNotEqualActiveObject2);
OPCODE(0xa5, o5_loadRoom);
OPCODE(0xa6, o_stopCurrentScript);
OPCODE(0xa7, o2_getActorY);
@@ -251,7 +252,7 @@ void ScummEngine_v0::setupOpcodes() {
/* AC */
OPCODE(0xac, o_stopCurrentScript);
OPCODE(0xad, o2_putActorInRoom);
- OPCODE(0xae, o_print_c64);
+ OPCODE(0xae, o_print);
OPCODE(0xaf, o2_ifNotState08);
/* B0 */
OPCODE(0xb0, o_loadCostume);
@@ -261,7 +262,7 @@ void ScummEngine_v0::setupOpcodes() {
/* B4 */
OPCODE(0xb4, o5_getDist);
OPCODE(0xb5, o_stopCurrentScript);
- OPCODE(0xb6, o2_walkActorToObject);
+ OPCODE(0xb6, o_walkActorToObject);
OPCODE(0xb7, o2_setState04);
/* B8 */
OPCODE(0xb8, o2_isLessEqual);
@@ -314,12 +315,12 @@ void ScummEngine_v0::setupOpcodes() {
OPCODE(0xde, o2_walkActorTo);
OPCODE(0xdf, o2_ifNotState04);
/* E0 */
- OPCODE(0xe0, o_cursorCommand);
+ OPCODE(0xe0, o_setMode);
OPCODE(0xe1, o2_putActor);
OPCODE(0xe2, o2_stopScript);
OPCODE(0xe3, o_stopCurrentScript);
/* E4 */
- OPCODE(0xe4, o_ifActiveObject);
+ OPCODE(0xe4, o_ifEqualActiveObject2);
OPCODE(0xe5, o_loadRoomWithEgo);
OPCODE(0xe6, o_stopCurrentScript);
OPCODE(0xe7, o5_getActorFacing);
@@ -337,11 +338,11 @@ void ScummEngine_v0::setupOpcodes() {
OPCODE(0xf0, o_lights);
OPCODE(0xf1, o_getBitVar);
OPCODE(0xf2, o_nop);
- OPCODE(0xf3, o5_getObjectOwner);
+ OPCODE(0xf3, o_getObjectOwner);
/* F4 */
OPCODE(0xf4, o5_getDist);
OPCODE(0xf5, o_stopCurrentScript);
- OPCODE(0xf6, o2_walkActorToObject);
+ OPCODE(0xf6, o_walkActorToObject);
OPCODE(0xf7, o2_setState04);
/* F8 */
OPCODE(0xf8, o2_isGreater);
@@ -365,7 +366,7 @@ uint ScummEngine_v0::fetchScriptWord() {
int ScummEngine_v0::getActiveObject() {
if (_opcode & PARAM_2)
- return _activeObject;
+ return OBJECT_V0_ID(_cmdObject);
return fetchScriptByte();
}
@@ -406,172 +407,121 @@ void ScummEngine_v0::decodeParseString() {
actorTalk(buffer);
}
-void ScummEngine_v0::drawSentenceWord(int object, bool usePrep, bool objInInventory) {
- const byte *temp;
- int sentencePrep = 0;
-
- // If object not in inventory, we except an index
- if (!objInInventory)
- _v0ObjectIndex = true;
- else
- _v0ObjectInInventory = true;
-
- temp = getObjOrActorName(object);
+void ScummEngine_v0::clearSentenceLine() {
+ Common::Rect sentenceline;
+ sentenceline.top = _virtscr[kVerbVirtScreen].topline;
+ sentenceline.bottom = _virtscr[kVerbVirtScreen].topline + 8;
+ sentenceline.left = 0;
+ sentenceline.right = _virtscr[kVerbVirtScreen].w - 1;
+ restoreBackground(sentenceline);
+}
- _v0ObjectInInventory = false;
- _v0ObjectIndex = false;
+void ScummEngine_v0::flushSentenceLine() {
+ byte string[80];
+ const char *ptr = _sentenceBuf.c_str();
+ int i = 0, len = 0;
- // Append the 'object-name'
- if (temp) {
- _sentenceBuf += " ";
- _sentenceBuf += (const char *)temp;
- }
+ // Maximum length of printable characters
+ int maxChars = 40;
+ while (*ptr) {
+ if (*ptr != '@')
+ len++;
+ if (len > maxChars) {
+ break;
+ }
- // Append the modifier? (With / On / To / In)
- if (!usePrep)
- return;
+ string[i++] = *ptr++;
- if (_verbs[_activeVerb].prep == 0xFF) {
- _v0ObjectInInventory = objInInventory;
- sentencePrep = verbPrep(object);
- } else {
- sentencePrep = _verbs[_activeVerb].prep;
}
+ string[i] = 0;
- if (sentencePrep > 0 && sentencePrep <= 4) {
- // The prepositions, like the fonts, were hard code in the engine. Thus
- // we have to do that, too, and provde localized versions for all the
- // languages MM/Zak are available in.
- static const char *const prepositions[][5] = {
- { " ", " in", " with", " on", " to" }, // English
- { " ", " mit", " mit", " mit", " zu" }, // German
- { " ", " dans", " avec", " sur", " <" }, // French
- { " ", " in", " con", " su", " a" }, // Italian
- { " ", " en", " con", " en", " a" }, // Spanish
- };
- int lang;
- switch (_language) {
- case Common::DE_DEU:
- lang = 1;
- break;
- case Common::FR_FRA:
- lang = 2;
- break;
- case Common::IT_ITA:
- lang = 3;
- break;
- case Common::ES_ESP:
- lang = 4;
- break;
- default:
- lang = 0; // Default to english
- }
+ _string[2].charset = 1;
+ _string[2].ypos = _virtscr[kVerbVirtScreen].topline;
+ _string[2].xpos = 0;
+ _string[2].right = _virtscr[kVerbVirtScreen].w - 1;
+ _string[2].color = 16;
+ drawString(2, (byte *)string);
+}
- _sentenceBuf += prepositions[lang][sentencePrep];
+void ScummEngine_v0::drawSentenceObject(int object) {
+ const byte *temp;
+ temp = getObjOrActorName(object);
+ if (temp) {
+ _sentenceBuf += " ";
+ _sentenceBuf += (const char *)temp;
}
}
-void ScummEngine_v0::drawSentence() {
- Common::Rect sentenceline;
- bool inventoryFirst = false;
- if (!(_userState & 32))
- return;
+void ScummEngine_v0::drawSentenceLine() {
+ _redrawSentenceLine = false;
- // Current Verb, Walk/Use
- if (getResourceAddress(rtVerb, _activeVerb)) {
- _sentenceBuf = (char *)getResourceAddress(rtVerb, _activeVerb);
- } else {
+ if (!(_userState & USERSTATE_IFACE_SENTENCE))
return;
- }
-
- // If using inventory first, draw it first
- if (_activeInvExecute && _activeInventory) {
- drawSentenceWord(_activeInventory, true, true);
- } else {
- // Not using inventory, use selected object
- if (_activeObject)
- drawSentenceWord(_activeObjectIndex, true, false);
- else
- inventoryFirst = true;
- }
-
- // Draw the inventory?
- if (_activeInventory > 0 && _activeObject2 == 0) {
- // Only if inventory isnt first (it will already be drawn by now)
- if (!_activeInvExecute) {
- drawSentenceWord(_activeInventory, inventoryFirst, true);
- } else {
- // Draw the active object, which could be inventory based, or room based
- if (_activeObject && !_activeObjectIndex) {
- drawSentenceWord(_activeObject, inventoryFirst, true);
- } else // Room based
- drawSentenceWord(_activeObjectIndex, inventoryFirst, false);
- }
-
- // Draw the 2nd active object
- } else if (_activeObject2) {
-
- // 2nd Object is in inventory
- if (_activeObject2Inv) {
- _v0ObjectInInventory = true;
- drawSentenceWord(_activeObject2, inventoryFirst, true);
- } else {
- drawSentenceWord(_activeObject2Index, inventoryFirst, false);
+ clearSentenceLine();
+
+ if (_activeVerb == kVerbNewKid) {
+ _sentenceBuf = "";
+ for (int i = 0; i < 3; ++i) {
+ const char *actorName;
+ int actorId = VAR(97 + i);
+ if (actorId == 0) {
+ // after usage of the radiation suit, kid vars are set to 0
+ actorName = " ";
+ } else {
+ Actor *a = derefActor(actorId, "drawSentenceLine");
+ actorName = (char *)a->getActorName();
+ }
+ _sentenceBuf += Common::String::format("%-13s", actorName);
}
+ flushSentenceLine();
+ return;
}
- // Draw the active actor
- if (_activeActor) {
- Actor *a = derefActor(_activeActor, "");
+ // Current Verb
+ if (_activeVerb == kVerbNone)
+ _activeVerb = kVerbWalkTo;
- _sentenceBuf += " ";
- _sentenceBuf += (const char *)a->getActorName();
- }
+ char *verbName = (char *)getResourceAddress(rtVerb, _activeVerb);
+ assert(verbName);
+ _sentenceBuf = verbName;
- _string[2].charset = 1;
- _string[2].ypos = _virtscr[kVerbVirtScreen].topline;
- _string[2].xpos = 0;
- _string[2].right = _virtscr[kVerbVirtScreen].w - 1;
- _string[2].color = 16;
+ if (_activeObject) {
+ // Draw the 1st active object
+ drawSentenceObject(_activeObject);
- byte string[80];
- const char *ptr = _sentenceBuf.c_str();
- int i = 0, len = 0;
+ // Append verb preposition
+ int sentencePrep = activeVerbPrep();
+ if (sentencePrep) {
+ drawPreposition(sentencePrep);
- // Maximum length of printable characters
- int maxChars = 40;
- while (*ptr) {
- if (*ptr != '@')
- len++;
- if (len > maxChars) {
- break;
+ // Draw the 2nd active object
+ if (_activeObject2)
+ drawSentenceObject(_activeObject2);
}
-
- string[i++] = *ptr++;
-
}
- string[i] = 0;
- sentenceline.top = _virtscr[kVerbVirtScreen].topline;
- sentenceline.bottom = _virtscr[kVerbVirtScreen].topline + 8;
- sentenceline.left = 0;
- sentenceline.right = _virtscr[kVerbVirtScreen].w - 1;
- restoreBackground(sentenceline);
-
- drawString(2, (byte *)string);
+ flushSentenceLine();
}
void ScummEngine_v0::o_stopCurrentScript() {
- int script;
+ stopScriptCommon(0);
+}
- script = vm.slot[_currentScript].number;
+void ScummEngine_v0::o_walkActorToObject() {
+ int actor = getVarOrDirectByte(PARAM_1);
+ int objId = fetchScriptByte();
+ int obj;
- if (_currentScript != 0 && vm.slot[_currentScript].number == script)
- stopObjectCode();
+ if (_opcode & 0x40)
+ obj = OBJECT_V0(objId, kObjectV0TypeBG);
else
- stopScript(script);
+ obj = OBJECT_V0(objId, kObjectV0TypeFG);
+
+ if (whereIsObject(obj) != WIO_NOT_FOUND) {
+ walkActorToObject(actor, obj);
+ }
}
void ScummEngine_v0::o_loadSound() {
@@ -625,18 +575,16 @@ void ScummEngine_v0::o_loadRoom() {
}
void ScummEngine_v0::o_loadRoomWithEgo() {
- Actor *a;
+ Actor_v0 *a;
int obj, room, x, y, dir;
obj = fetchScriptByte();
room = fetchScriptByte();
- a = derefActor(VAR(VAR_EGO), "o_loadRoomWithEgo");
+ a = (Actor_v0 *)derefActor(VAR(VAR_EGO), "o_loadRoomWithEgo");
//0x634F
- if (((ActorC64 *)a)->_miscflags & 0x40) {
- // TODO: Check if this is the correct function
- // to be calling here
+ if (a->_miscflags & kActorMiscFlagFreeze) {
stopObjectCode();
return;
}
@@ -654,15 +602,14 @@ void ScummEngine_v0::o_loadRoomWithEgo() {
x = r.x;
y = r.y;
a->putActor(x, y, _currentRoom);
- a->setDirection(dir + 180);
-
+
camera._dest.x = camera._cur.x = a->getPos().x;
setCameraAt(a->getPos().x, a->getPos().y);
setCameraFollows(a);
_fullRedraw = true;
- resetSentence(false);
+ resetSentence();
if (x >= 0 && y >= 0) {
a->startWalkActor(x, y, -1);
@@ -679,27 +626,39 @@ void ScummEngine_v0::o_unlockRoom() {
_res->unlock(rtRoom, resid);
}
-void ScummEngine_v0::o_cursorCommand() {
- // TODO
- int state = 0;
+void ScummEngine_v0::setMode(byte mode) {
+ int state;
+
+ _currentMode = mode;
- _currentMode = fetchScriptByte();
switch (_currentMode) {
- case 0:
- state = 15;
+ case kModeCutscene:
+ _redrawSentenceLine = false;
+ // Note: do not change freeze state here
+ state = USERSTATE_SET_IFACE |
+ USERSTATE_SET_CURSOR;
break;
- case 1:
- state = 31;
+ case kModeKeypad:
+ _redrawSentenceLine = false;
+ state = USERSTATE_SET_IFACE |
+ USERSTATE_SET_CURSOR | USERSTATE_CURSOR_ON |
+ USERSTATE_SET_FREEZE | USERSTATE_FREEZE_ON;
break;
- case 2:
- break;
- case 3:
- state = 247;
+ case kModeNormal:
+ case kModeNoNewKid:
+ state = USERSTATE_SET_IFACE | USERSTATE_IFACE_ALL |
+ USERSTATE_SET_CURSOR | USERSTATE_CURSOR_ON |
+ USERSTATE_SET_FREEZE;
break;
+ default:
+ error("Invalid mode: %d", mode);
}
setUserState(state);
- debug(0, "o_cursorCommand(%d)", _currentMode);
+}
+
+void ScummEngine_v0::o_setMode() {
+ setMode(fetchScriptByte());
}
void ScummEngine_v0::o_lights() {
@@ -724,24 +683,31 @@ void ScummEngine_v0::o_lights() {
void ScummEngine_v0::o_animateActor() {
int act = getVarOrDirectByte(PARAM_1);
int anim = getVarOrDirectByte(PARAM_2);
- int unk = fetchScriptByte();
-
- debug(0,"o_animateActor: unk %d", unk);
-
- ActorC64 *a = (ActorC64*) derefActor(act, "o_animateActor");
-
- // 0x6993
- if (anim == 0xFE) {
- a->_speaking = 0x80; // Enabled, but not switching
- return;
- }
- // 0x69A3
- if (anim == 0xFD) {
- a->_speaking = 0x00;
- return;
+ int8 repeat = (int8) fetchScriptByte();
+
+ Actor_v0 *a = (Actor_v0*) derefActor(act, "o_animateActor");
+
+ a->_animFrameRepeat = repeat;
+
+ switch (anim) {
+
+ case 0xFE:
+ // 0x6993
+ a->_speaking = 0x80; // Enabled, but not switching
+ return;
+
+ case 0xFD:
+ // 0x69A3
+ a->_speaking = 0x00;
+ return;
+
+ case 0xFF:
+ a->stopActorMoving();
+ return;
}
a->animateActor(anim);
+ a->animateCostume();
}
void ScummEngine_v0::o_getActorMoving() {
@@ -760,7 +726,12 @@ void ScummEngine_v0::o_putActorAtObject() {
a = derefActor(getVarOrDirectByte(PARAM_1), "o_putActorAtObject");
- obj = fetchScriptByte();
+ int objId = fetchScriptByte();
+ if (_opcode & 0x40)
+ obj = OBJECT_V0(objId, kObjectV0TypeBG);
+ else
+ obj = OBJECT_V0(objId, kObjectV0TypeFG);
+
if (whereIsObject(obj) != WIO_NOT_FOUND) {
getObjectXYPos(obj, x, y);
AdjustBoxResult r = a->adjustXYToBeInBox(x, y);
@@ -776,20 +747,13 @@ void ScummEngine_v0::o_putActorAtObject() {
void ScummEngine_v0::o_pickupObject() {
int obj = fetchScriptByte();
- if (obj == 0) {
- obj = _activeObject;
- }
+ if (!obj)
+ obj = _cmdObject;
- if (obj < 1) {
- error("pickupObject received invalid index %d (script %d)", obj, vm.slot[_currentScript].number);
- }
-
- if (getObjectIndex(obj) == -1)
+ /* Don't take an object twice */
+ if (whereIsObject(obj) == WIO_INVENTORY)
return;
- if (whereIsObjectInventory(_activeObject2) == WIO_INVENTORY) /* Don't take an */
- return; /* object twice */
-
addObjectToInventory(obj, _roomResource);
markObjectRectAsDirty(obj);
putOwner(obj, VAR(VAR_EGO));
@@ -800,14 +764,22 @@ void ScummEngine_v0::o_pickupObject() {
}
void ScummEngine_v0::o_setObjectName() {
- int obj = fetchScriptByte();
+ int obj;
+ int objId = fetchScriptByte();
+ if (!objId) {
+ obj = _cmdObject;
+ } else {
+ if (_opcode & 0x80)
+ obj = OBJECT_V0(objId, kObjectV0TypeBG);
+ else
+ obj = OBJECT_V0(objId, kObjectV0TypeFG);
+ }
setObjectName(obj);
}
void ScummEngine_v0::o_nop() {
}
-// TODO: Maybe translate actor flags in future.
void ScummEngine_v0::o_setActorBitVar() {
byte act = getVarOrDirectByte(PARAM_1);
byte mask = getVarOrDirectByte(PARAM_2);
@@ -817,7 +789,7 @@ void ScummEngine_v0::o_setActorBitVar() {
if (act >= _numActors)
return;
- ActorC64 *a = (ActorC64 *)derefActor(act, "o_setActorBitVar");
+ Actor_v0 *a = (Actor_v0 *)derefActor(act, "o_setActorBitVar");
if (mod)
a->_miscflags |= mask;
@@ -825,20 +797,24 @@ void ScummEngine_v0::o_setActorBitVar() {
a->_miscflags &= ~mask;
// This flag causes the actor to stop moving (used by script #158, Green Tentacle 'Oomph!')
- if (a->_miscflags & 0x40)
+ if (a->_miscflags & kActorMiscFlagFreeze)
a->stopActorMoving();
- if (a->_miscflags & 0x80)
- a->setActorCostume(0);
debug(0, "o_setActorBitVar(%d, %d, %d)", act, mask, mod);
}
+void ScummEngine_v0::o_getObjectOwner() {
+ getResultPos();
+ int obj = getVarOrDirectWord(PARAM_1);
+ setResult(getOwner(obj ? obj : _cmdObject));
+}
+
void ScummEngine_v0::o_getActorBitVar() {
getResultPos();
byte act = getVarOrDirectByte(PARAM_1);
byte mask = getVarOrDirectByte(PARAM_2);
- ActorC64 *a = (ActorC64 *)derefActor(act, "o_getActorBitVar");
+ Actor_v0 *a = (Actor_v0 *)derefActor(act, "o_getActorBitVar");
setResult((a->_miscflags & mask) ? 1 : 0);
debug(0, "o_getActorBitVar(%d, %d, %d)", act, mask, (a->_miscflags & mask));
@@ -867,74 +843,97 @@ void ScummEngine_v0::o_getBitVar() {
debug(0, "o_getBitVar (%d, %d %d)", flag, mask, _bitVars[flag] & (1 << mask));
}
-void ScummEngine_v0::o_print_c64() {
+void ScummEngine_v0::o_print() {
_actorToPrintStrFor = fetchScriptByte();
decodeParseString();
}
-void ScummEngine_v0::o_printEgo_c64() {
+void ScummEngine_v0::o_printEgo() {
_actorToPrintStrFor = (byte)VAR(VAR_EGO);
decodeParseString();
}
void ScummEngine_v0::o_doSentence() {
- byte entry = fetchScriptByte();
- byte obj = fetchScriptByte();
- fetchScriptByte();
+ byte verb = fetchScriptByte();
+ int obj, obj2;
+ byte b;
+
+ b = fetchScriptByte();
+ if (b == 0xFF) {
+ obj = _cmdObject2;
+ } else if (b == 0xFE) {
+ obj = _cmdObject;
+ } else {
+ obj = OBJECT_V0(b, (_opcode & 0x80) ? kObjectV0TypeBG : kObjectV0TypeFG);
+ }
- runObjectScript(obj, entry, false, false, NULL);
-}
+ b = fetchScriptByte();
+ if (b == 0xFF) {
+ obj2 = _cmdObject2;
+ } else if (b == 0xFE) {
+ obj2 = _cmdObject;
+ } else {
+ obj2 = OBJECT_V0(b, (_opcode & 0x40) ? kObjectV0TypeBG : kObjectV0TypeFG);
+ }
-void ScummEngine_v0::o_unknown2() {
- byte var1 = fetchScriptByte();
- error("STUB: o_unknown2(%d)", var1);
+ doSentence(verb, obj, obj2);
}
-void ScummEngine_v0::o_ifActiveObject() {
+bool ScummEngine_v0::ifEqualActiveObject2Common(bool checkType) {
byte obj = fetchScriptByte();
+ if (!checkType || (OBJECT_V0_TYPE(_cmdObject2) == kObjectV0TypeFG))
+ return (obj == OBJECT_V0_ID(_cmdObject2));
+ return false;
+}
- jumpRelative(obj == _activeInventory);
+void ScummEngine_v0::o_ifEqualActiveObject2() {
+ bool equal = ifEqualActiveObject2Common((_opcode & 0x80) == 0);
+ jumpRelative(equal);
}
-void ScummEngine_v0::o_getClosestObjActor() {
- int obj;
- int act;
+void ScummEngine_v0::o_ifNotEqualActiveObject2() {
+ bool equal = ifEqualActiveObject2Common((_opcode & 0x80) == 0);
+ jumpRelative(!equal);
+}
+
+void ScummEngine_v0::o_getClosestActor() {
+ int act, check_act;
int dist;
// This code can't detect any actors farther away than 255 units
// (pixels in newer games, characters in older ones.) But this is
// perfectly OK, as it is exactly how the original behaved.
- int closest_obj = 0xFF, closest_dist = 0xFF;
+ int closest_act = 0xFF, closest_dist = 0xFF;
getResultPos();
act = getVarOrDirectByte(PARAM_1);
- obj = (_opcode & PARAM_2) ? 25 : 7;
+ check_act = (_opcode & PARAM_2) ? 25 : 7;
do {
- dist = getObjActToObjActDist(act, obj);
+ dist = getObjActToObjActDist(actorToObj(act), actorToObj(check_act));
if (dist < closest_dist) {
closest_dist = dist;
- closest_obj = obj;
+ closest_act = check_act;
}
- } while (--obj);
+ } while (--check_act);
- setResult(closest_obj);
+ setResult(closest_act);
}
void ScummEngine_v0::o_cutscene() {
- vm.cutSceneData[0] = _userState | (_userPut ? 16 : 0);
+ vm.cutSceneData[0] = _currentMode;
vm.cutSceneData[2] = _currentRoom;
- vm.cutSceneData[3] = camera._mode;
- // Hide inventory, freeze scripts, hide cursor
- setUserState(15);
+ freezeScripts(0);
+ setMode(kModeCutscene);
_sentenceNum = 0;
- resetSentence(false);
+ resetSentence();
vm.cutScenePtr[0] = 0;
+ vm.cutSceneScript[0] = 0;
}
void ScummEngine_v0::o_endCutscene() {
@@ -944,68 +943,43 @@ void ScummEngine_v0::o_endCutscene() {
vm.cutSceneScript[0] = 0;
vm.cutScenePtr[0] = 0;
- // Reset user state to values before cutscene
- setUserState(vm.cutSceneData[0] | 7);
+ setMode(vm.cutSceneData[0]);
- camera._mode = (byte) vm.cutSceneData[3];
- if (camera._mode == kFollowActorCameraMode) {
- actorFollowCamera(VAR(VAR_EGO));
- } else if (vm.cutSceneData[2] != _currentRoom) {
+ if (_currentMode == kModeKeypad) {
startScene(vm.cutSceneData[2], 0, 0);
+ // in contrast to the normal keypad behavior we unfreeze scripts here
+ unfreezeScripts();
+ } else {
+ unfreezeScripts();
+ actorFollowCamera(VAR(VAR_EGO));
+ // set mode again to have the freeze mode right
+ setMode(vm.cutSceneData[0]);
+ _redrawSentenceLine = true;
}
}
-void ScummEngine_v0::o_beginOverride() {
- const int idx = vm.cutSceneStackPointer;
- assert(0 <= idx && idx < 5);
-
- vm.cutScenePtr[idx] = _scriptPointer - _scriptOrgPointer;
- vm.cutSceneScript[idx] = _currentScript;
-
- // Skip the jump instruction following the override instruction
- // (the jump is responsible for "skipping" cutscenes, and the reason
- // why we record the current script position in vm.cutScenePtr).
- fetchScriptByte();
- ScummEngine::fetchScriptWord();
-
- // This is based on disassembly
- VAR(VAR_OVERRIDE) = 0;
-}
-
void ScummEngine_v0::o_setOwnerOf() {
int obj, owner;
obj = getVarOrDirectWord(PARAM_1);
owner = getVarOrDirectByte(PARAM_2);
- if (obj == 0)
- obj = _activeInventory;
+ if (!obj)
+ obj = _cmdObject;
setOwnerOf(obj, owner);
}
-void ScummEngine_v0::resetSentence(bool walking) {
- _activeVerb = 13;
-
- // If the actor is walking, or the screen is a keypad (no sentence verbs/objects are drawn)
- // Then reset all active objects (stops the radio crash, bug #3077966)
- if (!walking || !(_userState & 32)) {
- _v0ObjectFlag = 0;
- _activeInventory = 0;
- _activeObject = 0;
- _activeObject2 = 0;
- _activeObjectIndex = 0;
- _activeObject2Index = 0;
- }
+void ScummEngine_v0::resetSentence() {
+ _activeVerb = kVerbWalkTo;
+ _activeObject = 0;
+ _activeObject2 = 0;
- _verbExecuting = false;
- _verbPickup = false;
+ _walkToObjectState = kWalkToObjectStateDone;
+ _redrawSentenceLine = true;
- _activeActor = 0;
- _activeInvExecute = false;
- _activeObject2Inv = false;
- _activeObjectObtained = false;
- _activeObject2Obtained = false;
+ _sentenceNum = 0;
+ _sentenceNestedCount = 0;
}
} // End of namespace Scumm
diff --git a/engines/scumm/script_v2.cpp b/engines/scumm/script_v2.cpp
index 7f02e899b4..ce162b4a6a 100644
--- a/engines/scumm/script_v2.cpp
+++ b/engines/scumm/script_v2.cpp
@@ -401,7 +401,7 @@ void ScummEngine_v2::decodeParseString() {
_string[textSlot].overhead = false;
if (_game.id == GID_MANIAC && _actorToPrintStrFor == 0xFF) {
- if (_game.platform == Common::kPlatformC64) {
+ if (_game.version == 0) {
_string[textSlot].color = 14;
} else if (_game.features & GF_DEMO) {
_string[textSlot].color = (_game.version == 2) ? 15 : 1;
@@ -412,7 +412,7 @@ void ScummEngine_v2::decodeParseString() {
}
int ScummEngine_v2::readVar(uint var) {
- if (var >= 14 && var <= 16)
+ if (_game.version >= 1 && var >= 14 && var <= 16)
var = _scummVars[var];
assertRange(0, var, _numVariables - 1, "variable (reading)");
@@ -873,7 +873,7 @@ void ScummEngine_v2::o2_doSentence() {
return;
}
if (a == 0xFB) {
- resetSentence(false);
+ resetSentence();
return;
}
@@ -953,12 +953,48 @@ void ScummEngine_v2::o2_doSentence() {
}
}
+void ScummEngine_v2::drawPreposition(int index) {
+ // The prepositions, like the fonts, were hard code in the engine. Thus
+ // we have to do that, too, and provde localized versions for all the
+ // languages MM/Zak are available in.
+ const char *prepositions[][5] = {
+ { " ", " in", " with", " on", " to" }, // English
+ { " ", " mit", " mit", " mit", " zu" }, // German
+ { " ", " dans", " avec", " sur", " <" }, // French
+ { " ", " in", " con", " su", " a" }, // Italian
+ { " ", " en", " con", " en", " a" }, // Spanish
+ };
+ int lang;
+ switch (_language) {
+ case Common::DE_DEU:
+ lang = 1;
+ break;
+ case Common::FR_FRA:
+ lang = 2;
+ break;
+ case Common::IT_ITA:
+ lang = 3;
+ break;
+ case Common::ES_ESP:
+ lang = 4;
+ break;
+ default:
+ lang = 0; // Default to english
+ }
+
+ if (_game.platform == Common::kPlatformNES) {
+ _sentenceBuf += (const char *)(getResourceAddress(rtCostume, 78) + VAR(VAR_SENTENCE_PREPOSITION) * 8 + 2);
+ } else
+ _sentenceBuf += prepositions[lang][index];
+}
+
void ScummEngine_v2::o2_drawSentence() {
Common::Rect sentenceline;
const byte *temp;
int slot = getVerbSlot(VAR(VAR_SENTENCE_VERB), 0);
- if (!((_userState & 32) || (_game.platform == Common::kPlatformNES && _userState & 0xe0)))
+ if (!((_userState & USERSTATE_IFACE_SENTENCE) ||
+ (_game.platform == Common::kPlatformNES && (_userState & USERSTATE_IFACE_ALL))))
return;
if (getResourceAddress(rtVerb, slot))
@@ -986,38 +1022,7 @@ void ScummEngine_v2::o2_drawSentence() {
}
if (0 < VAR(VAR_SENTENCE_PREPOSITION) && VAR(VAR_SENTENCE_PREPOSITION) <= 4) {
- // The prepositions, like the fonts, were hard code in the engine. Thus
- // we have to do that, too, and provde localized versions for all the
- // languages MM/Zak are available in.
- const char *prepositions[][5] = {
- { " ", " in", " with", " on", " to" }, // English
- { " ", " mit", " mit", " mit", " zu" }, // German
- { " ", " dans", " avec", " sur", " <" }, // French
- { " ", " in", " con", " su", " a" }, // Italian
- { " ", " en", " con", " en", " a" }, // Spanish
- };
- int lang;
- switch (_language) {
- case Common::DE_DEU:
- lang = 1;
- break;
- case Common::FR_FRA:
- lang = 2;
- break;
- case Common::IT_ITA:
- lang = 3;
- break;
- case Common::ES_ESP:
- lang = 4;
- break;
- default:
- lang = 0; // Default to english
- }
-
- if (_game.platform == Common::kPlatformNES) {
- _sentenceBuf += (const char *)(getResourceAddress(rtCostume, 78) + VAR(VAR_SENTENCE_PREPOSITION) * 8 + 2);
- } else
- _sentenceBuf += prepositions[lang][VAR(VAR_SENTENCE_PREPOSITION)];
+ drawPreposition(VAR(VAR_SENTENCE_PREPOSITION));
}
if (VAR(VAR_SENTENCE_OBJECT2) > 0) {
@@ -1171,25 +1176,30 @@ void ScummEngine_v2::o2_startScript() {
// imprisonment of the player), then any attempt to start script 87
// (which makes Ted go answer the door bell) is simply ignored. This
// way, the door bell still chimes, but Ted ignores it.
- if (_game.id == GID_MANIAC && script == 87) {
- if (isScriptRunning(88) || isScriptRunning(89)) {
- return;
+ if (_game.id == GID_MANIAC) {
+ if (_game.version >= 1 && script == 87) {
+ if (isScriptRunning(88) || isScriptRunning(89))
+ return;
+ }
+ // Script numbers are different in V0
+ if (_game.version == 0 && script == 82) {
+ if (isScriptRunning(83) || isScriptRunning(84))
+ return;
}
}
runScript(script, 0, 0, 0);
}
-void ScummEngine_v2::o2_stopScript() {
- int script;
-
- script = getVarOrDirectByte(PARAM_1);
-
+void ScummEngine_v2::stopScriptCommon(int script) {
if (_game.id == GID_MANIAC && _roomResource == 26 && vm.slot[_currentScript].number == 10001) {
// FIXME: Nasty hack for bug #915575
// Don't let the exit script for room 26 stop the script (116), when
// switching to the dungeon (script 89)
- if ((script == 116) && isScriptRunning(89))
+ if (_game.version >= 1 && script == 116 && isScriptRunning(89))
+ return;
+ // Script numbers are different in V0
+ if (_game.version == 0 && script == 111 && isScriptRunning(84))
return;
}
@@ -1202,26 +1212,31 @@ void ScummEngine_v2::o2_stopScript() {
stopScript(script);
}
+void ScummEngine_v2::o2_stopScript() {
+ stopScriptCommon(getVarOrDirectByte(PARAM_1));
+}
+
void ScummEngine_v2::o2_panCameraTo() {
panCameraTo(getVarOrDirectByte(PARAM_1) * V12_X_MULTIPLIER, 0);
}
-void ScummEngine_v2::o2_walkActorToObject() {
- int obj;
- Actor *a;
+void ScummEngine_v2::walkActorToObject(int actor, int obj) {
+ int x, y, dir;
+ getObjectXYPos(obj, x, y, dir);
- _v0ObjectFlag = 0;
+ Actor *a = derefActor(actor, "walkActorToObject");
+ AdjustBoxResult r = a->adjustXYToBeInBox(x, y);
+ x = r.x;
+ y = r.y;
- a = derefActor(getVarOrDirectByte(PARAM_1), "o2_walkActorToObject");
- obj = getVarOrDirectWord(PARAM_2);
- if (whereIsObject(obj) != WIO_NOT_FOUND) {
- int x, y, dir;
- getObjectXYPos(obj, x, y, dir);
- AdjustBoxResult r = a->adjustXYToBeInBox(x, y);
- x = r.x;
- y = r.y;
+ a->startWalkActor(x, y, dir);
+}
- a->startWalkActor(x, y, dir);
+void ScummEngine_v2::o2_walkActorToObject() {
+ int actor = getVarOrDirectByte(PARAM_1);
+ int obj = getVarOrDirectWord(PARAM_2);
+ if (whereIsObject(obj) != WIO_NOT_FOUND) {
+ walkActorToObject(actor, obj);
}
}
@@ -1289,7 +1304,7 @@ void ScummEngine_v2::o2_findObject() {
int x = getVarOrDirectByte(PARAM_1) * V12_X_MULTIPLIER;
int y = getVarOrDirectByte(PARAM_2) * V12_Y_MULTIPLIER;
obj = findObject(x, y);
- if (obj == 0 && (_game.platform == Common::kPlatformNES) && (_userState & 0x40)) {
+ if (obj == 0 && (_game.platform == Common::kPlatformNES) && (_userState & USERSTATE_IFACE_INVENTORY)) {
if (_mouseOverBoxV2 >= 0 && _mouseOverBoxV2 < 4)
obj = findInventory(VAR(VAR_EGO), _mouseOverBoxV2 + _inventoryOffset + 1);
}
@@ -1301,7 +1316,7 @@ void ScummEngine_v2::o2_getActorX() {
getResultPos();
a = getVarOrDirectByte(PARAM_1);
- setResult(getObjX(a));
+ setResult(getObjX(actorToObj(a)));
}
void ScummEngine_v2::o2_getActorY() {
@@ -1309,7 +1324,7 @@ void ScummEngine_v2::o2_getActorY() {
getResultPos();
a = getVarOrDirectByte(PARAM_1);
- setResult(getObjY(a));
+ setResult(getObjY(actorToObj(a)));
}
void ScummEngine_v2::o2_isGreater() {
@@ -1396,7 +1411,7 @@ void ScummEngine_v2::o2_loadRoomWithEgo() {
_fullRedraw = true;
- resetSentence(false);
+ resetSentence();
if (x >= 0 && y >= 0) {
a->startWalkActor(x, y, -1);
@@ -1471,11 +1486,13 @@ void ScummEngine_v2::o2_cutscene() {
VAR(VAR_CURSORSTATE) = 200;
// Hide inventory, freeze scripts, hide cursor
- setUserState(15);
+ setUserState(USERSTATE_SET_IFACE |
+ USERSTATE_SET_CURSOR |
+ USERSTATE_SET_FREEZE | USERSTATE_FREEZE_ON);
_sentenceNum = 0;
stopScript(SENTENCE_SCRIPT);
- resetSentence(false);
+ resetSentence();
vm.cutScenePtr[0] = 0;
}
@@ -1490,7 +1507,7 @@ void ScummEngine_v2::o2_endCutscene() {
VAR(VAR_CURSORSTATE) = vm.cutSceneData[1];
// Reset user state to values before cutscene
- setUserState(vm.cutSceneData[0] | 7);
+ setUserState(vm.cutSceneData[0] | USERSTATE_SET_IFACE | USERSTATE_SET_CURSOR | USERSTATE_SET_FREEZE);
if ((_game.id == GID_MANIAC) && !(_game.platform == Common::kPlatformNES)) {
camera._mode = (byte) vm.cutSceneData[3];
@@ -1510,7 +1527,7 @@ void ScummEngine_v2::o2_beginOverride() {
// Skip the jump instruction following the override instruction
fetchScriptByte();
- fetchScriptWord();
+ ScummEngine::fetchScriptWord();
}
void ScummEngine_v2::o2_chainScript() {
@@ -1556,24 +1573,24 @@ void ScummEngine_v2::o2_cursorCommand() { // TODO: Define the magic numbers
}
void ScummEngine_v2::setUserState(byte state) {
- if (state & 4) { // Userface
+ if (state & USERSTATE_SET_IFACE) { // Userface
if (_game.platform == Common::kPlatformNES)
- _userState = (_userState & ~0xE0) | (state & 0xE0);
+ _userState = (_userState & ~USERSTATE_IFACE_ALL) | (state & USERSTATE_IFACE_ALL);
else
- _userState = state & (32 | 64 | 128);
+ _userState = state & USERSTATE_IFACE_ALL;
}
- if (state & 1) { // Freeze
- if (state & 8)
+ if (state & USERSTATE_SET_FREEZE) { // Freeze
+ if (state & USERSTATE_FREEZE_ON)
freezeScripts(0);
else
unfreezeScripts();
}
- if (state & 2) { // Cursor Show/Hide
+ if (state & USERSTATE_SET_CURSOR) { // Cursor Show/Hide
if (_game.platform == Common::kPlatformNES)
- _userState = (_userState & ~0x10) | (state & 0x10);
- if (state & 16) {
+ _userState = (_userState & ~USERSTATE_CURSOR_ON) | (state & USERSTATE_CURSOR_ON);
+ if (state & USERSTATE_CURSOR_ON) {
_userPut = 1;
_cursor.state = 1;
} else {
@@ -1623,7 +1640,7 @@ void ScummEngine_v2::o2_switchCostumeSet() {
o2_dummy();
}
-void ScummEngine_v2::resetSentence(bool walking) {
+void ScummEngine_v2::resetSentence() {
VAR(VAR_SENTENCE_VERB) = VAR(VAR_BACKUP_VERB);
VAR(VAR_SENTENCE_OBJECT1) = 0;
VAR(VAR_SENTENCE_OBJECT2) = 0;
diff --git a/engines/scumm/script_v4.cpp b/engines/scumm/script_v4.cpp
index 8340f62dbc..1de9f08168 100644
--- a/engines/scumm/script_v4.cpp
+++ b/engines/scumm/script_v4.cpp
@@ -350,7 +350,7 @@ void ScummEngine_v4::loadIQPoints(byte *ptr, int size) {
file = _saveFileMan->openForLoading(filename);
if (file != NULL) {
- byte *tmp = (byte*)malloc(size);
+ byte *tmp = (byte *)malloc(size);
int nread = file->read(tmp, size);
if (nread == size) {
memcpy(ptr, tmp, size);
@@ -414,7 +414,7 @@ void ScummEngine_v4::o4_saveLoadGame() {
// use name entered by the user
char* ptr;
int firstSlot = (_game.id == GID_LOOM) ? STRINGID_SAVENAME1_LOOM : STRINGID_SAVENAME1;
- ptr = (char*)getStringAddress(slot + firstSlot - 1);
+ ptr = (char *)getStringAddress(slot + firstSlot - 1);
strncpy(name, ptr, sizeof(name));
}
diff --git a/engines/scumm/script_v5.cpp b/engines/scumm/script_v5.cpp
index 6426b75e1e..a5591b701f 100644
--- a/engines/scumm/script_v5.cpp
+++ b/engines/scumm/script_v5.cpp
@@ -1095,10 +1095,16 @@ void ScummEngine_v5::o5_getClosestObjActor() {
void ScummEngine_v5::o5_getDist() {
int o1, o2;
int r;
+
getResultPos();
+
o1 = getVarOrDirectWord(PARAM_1);
o2 = getVarOrDirectWord(PARAM_2);
- r = getObjActToObjActDist(o1, o2);
+
+ if (_game.version == 0) // in v0 both parameters are always actor IDs, never objects
+ r = getObjActToObjActDist(actorToObj(o1), actorToObj(o2));
+ else
+ r = getObjActToObjActDist(o1, o2);
// FIXME: MI2 race workaround, see bug #597022. We never quite figured out
// what the real cause of this, or if it maybe occurs in the original, too...
@@ -2464,8 +2470,40 @@ void ScummEngine_v5::o5_walkActorTo() {
a->startWalkActor(x, y, -1);
}
+void ScummEngine_v5::walkActorToActor(int actor, int toActor, int dist) {
+ Actor *a = derefActor(actor, "walkActorToActor");
+ Actor *to = derefActor(toActor, "walkActorToActor(2)");
+
+ if (_game.version <= 2) {
+ dist *= V12_X_MULTIPLIER;
+ } else if (dist == 0xFF) {
+ dist = a->_scalex * a->_width / 0xFF;
+ dist += (to->_scalex * to->_width / 0xFF) / 2;
+ }
+ int x = to->getPos().x;
+ int y = to->getPos().y;
+ if (x < a->getPos().x)
+ x += dist;
+ else
+ x -= dist;
+
+ if (_game.version <= 2) {
+ x /= V12_X_MULTIPLIER;
+ y /= V12_Y_MULTIPLIER;
+ }
+ if (_game.version <= 3) {
+ AdjustBoxResult abr = a->adjustXYToBeInBox(x, y);
+ x = abr.x;
+ y = abr.y;
+ }
+ a->startWalkActor(x, y, -1);
+
+ // WORKAROUND: See bug #2971126 for details on why this is here.
+ if (_game.version == 0)
+ o5_breakHere();
+}
+
void ScummEngine_v5::o5_walkActorToActor() {
- int x, y;
Actor *a, *a2;
int nr = getVarOrDirectByte(PARAM_1);
int nr2 = getVarOrDirectByte(PARAM_2);
@@ -2499,33 +2537,7 @@ void ScummEngine_v5::o5_walkActorToActor() {
if (!a2->isInCurrentRoom())
return;
- if (_game.version <= 2) {
- dist *= V12_X_MULTIPLIER;
- } else if (dist == 0xFF) {
- dist = a->_scalex * a->_width / 0xFF;
- dist += (a2->_scalex * a2->_width / 0xFF) / 2;
- }
- x = a2->getPos().x;
- y = a2->getPos().y;
- if (x < a->getPos().x)
- x += dist;
- else
- x -= dist;
-
- if (_game.version <= 2) {
- x /= V12_X_MULTIPLIER;
- y /= V12_Y_MULTIPLIER;
- }
- if (_game.version <= 3) {
- AdjustBoxResult abr = a->adjustXYToBeInBox(x, y);
- x = abr.x;
- y = abr.y;
- }
- a->startWalkActor(x, y, -1);
-
- // WORKAROUND: See bug #2971126 for details on why this is here.
- if (_game.version == 0)
- o5_breakHere();
+ walkActorToActor(nr, nr2, dist);
}
void ScummEngine_v5::o5_walkActorToObject() {
diff --git a/engines/scumm/script_v8.cpp b/engines/scumm/script_v8.cpp
index c8b92be3c8..f6f376f3c9 100644
--- a/engines/scumm/script_v8.cpp
+++ b/engines/scumm/script_v8.cpp
@@ -1122,7 +1122,7 @@ void ScummEngine_v8::o8_kernelSetFunctions() {
}
case 26: { // saveGameWrite
// FIXME: This doesn't work
- char *address = (char*)getStringAddress(args[2]);
+ char *address = (char *)getStringAddress(args[2]);
debug(0, "o8_kernelSetFunctions: saveGame(%d, %s)", args[1], address);
break;
}
diff --git a/engines/scumm/scumm-md5.h b/engines/scumm/scumm-md5.h
index 45c6e90a08..f7f7678a9f 100644
--- a/engines/scumm/scumm-md5.h
+++ b/engines/scumm/scumm-md5.h
@@ -1,5 +1,5 @@
/*
- This file was generated by the md5table tool on Sun Oct 02 03:05:23 2011
+ This file was generated by the md5table tool on Wed Feb 22 19:57:16 2012
DO NOT EDIT MANUALLY!
*/
@@ -16,7 +16,7 @@ struct MD5Table {
static const MD5Table md5table[] = {
{ "008e76ec3ae58d0add637ea7aa299a2c", "freddi3", "", "", -1, Common::FR_FRA, Common::kPlatformMacintosh },
{ "02cae0e7ff8504f73618391873d5781a", "freddi3", "HE 98.5", "", -1, Common::DE_DEU, Common::kPlatformWindows },
- { "0305e850382b812fec6e5998ef88a966", "pajama", "", "Demo", -1, Common::NL_NLD, Common::kPlatformWindows },
+ { "0305e850382b812fec6e5998ef88a966", "pajama", "", "Demo", -1, Common::NL_NLD, Common::kPlatformUnknown },
{ "035deab53b47bc43abc763560d0f8d4b", "atlantis", "Floppy", "Demo", -1, Common::EN_ANY, Common::kPlatformPC },
{ "037385a953789190298494d92b89b3d0", "catalog", "HE 72", "Demo", -1, Common::EN_ANY, Common::kPlatformWindows },
{ "03d3b18ee3fd68114e2a687c871e38d5", "freddi4", "HE 99", "Mini Game", -1, Common::EN_USA, Common::kPlatformWindows },
@@ -50,6 +50,7 @@ static const MD5Table md5table[] = {
{ "0c45eb4baff0c12c3d9dfa889c8070ab", "pajama3", "", "Demo", 13884, Common::DE_DEU, Common::kPlatformUnknown },
{ "0cccfa5223099a60e76cfcca57a1a141", "freddi3", "", "", -1, Common::NL_NLD, Common::kPlatformUnknown },
{ "0d1b69471605201ef2fa9cec1f5f02d2", "maniac", "V2", "V2", -1, Common::ES_ESP, Common::kPlatformPC },
+ { "0ddf1174d0d097956ba10dd452ea65e6", "freddi3", "HE 99", "", -1, Common::HE_ISR, Common::kPlatformWindows },
{ "0e4c5d54a0ad4b26132e78b5ea76642a", "samnmax", "Floppy", "Demo", 6485, Common::EN_ANY, Common::kPlatformPC },
{ "0e96ab45a4eb72acc1b46813976589fd", "activity", "", "", -1, Common::EN_ANY, Common::kPlatformMacintosh },
{ "0e9b01430e31d9fcd94071d433bbc6bf", "loom", "No AdLib", "EGA", -1, Common::FR_FRA, Common::kPlatformAtariST },
@@ -76,7 +77,7 @@ static const MD5Table md5table[] = {
{ "15f588e887e857e8c56fe6ade4956168", "atlantis", "Floppy", "Floppy", -1, Common::ES_ESP, Common::kPlatformAmiga },
{ "16542a7342a918bfe4ba512007d36c47", "FreddisFunShop", "HE 99L", "", -1, Common::EN_USA, Common::kPlatformUnknown },
{ "166553538ff320c69edafeee29525419", "samnmax", "", "CD", 199195304, Common::EN_ANY, Common::kPlatformMacintosh },
- { "16effd200aa6b8abe9c569c3e578814d", "freddi4", "HE 99", "Demo", -1, Common::NL_NLD, Common::kPlatformWindows },
+ { "16effd200aa6b8abe9c569c3e578814d", "freddi4", "HE 99", "Demo", -1, Common::NL_NLD, Common::kPlatformUnknown },
{ "179879b6e35c1ead0d93aab26db0951b", "fbear", "HE 70", "", 13381, Common::EN_ANY, Common::kPlatformWindows },
{ "17b5d5e6af4ae89d62631641d66d5a05", "indy3", "VGA", "VGA", -1, Common::IT_ITA, Common::kPlatformPC },
{ "17f7296f63c78642724f057fd8e736a7", "maniac", "NES", "", 2082, Common::EN_GRB, Common::kPlatformNES },
@@ -89,6 +90,8 @@ static const MD5Table md5table[] = {
{ "19263586f749a560c1adf8b3393a9593", "socks", "HE 85", "", -1, Common::RU_RUS, Common::kPlatformWindows },
{ "19bf6938a94698296bcb0c99c31c91a7", "spyfox2", "", "Demo", -1, Common::EN_GRB, Common::kPlatformWindows },
{ "1a6e5ae2777a6a33f06ffc0226210934", "atlantis", "", "CD", -1, Common::EN_ANY, Common::kPlatformMacintosh },
+ { "1af4eb581a33d808707d66d50e084dca", "pajama2", "HE 99", "", -1, Common::HE_ISR, Common::kPlatformWindows },
+ { "1b720def35ecfa07032ddf1efb34c368", "dog", "", "", 19681, Common::NL_NLD, Common::kPlatformUnknown },
{ "1c792d28376d45e145cb916bca0400a2", "spyfox2", "", "Demo", -1, Common::NL_NLD, Common::kPlatformUnknown },
{ "1c7e7db2cfab1ad62746ab680a634204", "maniac", "NES", "", -1, Common::FR_FRA, Common::kPlatformNES },
{ "1ca86e2cf9aaa2068738a1e5ba477e60", "zak", "FM-TOWNS", "", -1, Common::JA_JPN, Common::kPlatformFMTowns },
@@ -127,7 +130,7 @@ static const MD5Table md5table[] = {
{ "2c04aacffb8428f30ccf4f734fbe3adc", "activity", "", "", -1, Common::EN_ANY, Common::kPlatformPC },
{ "2ccd8891ce4d3f1a334d21bff6a88ca2", "monkey", "CD", "", 9455, Common::EN_ANY, Common::kPlatformMacintosh },
{ "2d1e891fe52df707c30185e52c50cd92", "monkey", "CD", "CD", 8955, Common::EN_ANY, Common::kPlatformPC },
- { "2d388339d6050d8ccaa757b64633954e", "zak", "FM-TOWNS", "Demo", 7520, Common::EN_ANY, Common::kPlatformFMTowns },
+ { "2d388339d6050d8ccaa757b64633954e", "indyloom", "FM-TOWNS", "Demo", 7520, Common::EN_ANY, Common::kPlatformFMTowns },
{ "2d4536a56e01da4b02eb021e7770afa2", "zak", "FM-TOWNS", "", 7520, Common::EN_ANY, Common::kPlatformFMTowns },
{ "2d4acbdcfd8e374c9da8c2e7303a5cd0", "BluesBirthday", "", "Demo", -1, Common::EN_ANY, Common::kPlatformUnknown },
{ "2d624d1b214f7faf0094daea65c6d1a6", "maniac", "Apple II", "", -1, Common::EN_ANY, Common::kPlatformApple2GS },
@@ -158,7 +161,7 @@ static const MD5Table md5table[] = {
{ "37ff1b308999c4cca7319edfcc1280a0", "puttputt", "HE 70", "Demo", 8269, Common::EN_ANY, Common::kPlatformWindows },
{ "3824e60cdf639d22f6df92a03dc4b131", "fbear", "HE 62", "", 7732, Common::EN_ANY, Common::kPlatformPC },
{ "387a544b8b10b26912d8413bab63a853", "monkey2", "", "Demo", -1, Common::EN_ANY, Common::kPlatformPC },
- { "3938ee1aa4433fca9d9308c9891172b1", "zak", "FM-TOWNS", "Demo", 7520, Common::EN_ANY, Common::kPlatformFMTowns },
+ { "3938ee1aa4433fca9d9308c9891172b1", "indyzak", "FM-TOWNS", "Demo", 7520, Common::EN_ANY, Common::kPlatformFMTowns },
{ "399b217b0c8d65d0398076da486363a9", "indy3", "VGA", "VGA", 6295, Common::DE_DEU, Common::kPlatformPC },
{ "39cb9dec16fa16f38d79acd80effb059", "loom", "EGA", "EGA", -1, Common::FR_FRA, Common::kPlatformAmiga },
{ "39cb9dec16fa16f38d79acd80effb059", "loom", "EGA", "EGA", -1, Common::IT_ITA, Common::kPlatformAmiga },
@@ -208,10 +211,11 @@ static const MD5Table md5table[] = {
{ "4ce2d5b355964bbcb5e5ce73236ef868", "freddicove", "HE 100", "", -1, Common::RU_RUS, Common::kPlatformWindows },
{ "4cfd3fda4a4e6e64a1fc488eba973b7a", "fbpack", "", "", -1, Common::EN_ANY, Common::kPlatformPC },
{ "4d34042713958b971cb139fba4658586", "atlantis", "FM-TOWNS", "", -1, Common::JA_JPN, Common::kPlatformFMTowns },
+ { "4d3fbc888de4e6565013f61dc83da6b6", "FreddisFunShop", "HE 99", "", 36245, Common::NL_NLD, Common::kPlatformUnknown },
{ "4dbff3787aedcd96b0b325f2d92d7ad9", "maze", "HE 100", "Updated", -1, Common::EN_USA, Common::kPlatformUnknown },
{ "4dc780f1bc587a193ce8a97652791438", "loom", "EGA", "EGA", -1, Common::EN_ANY, Common::kPlatformAmiga },
{ "4e5867848ee61bc30d157e2c94eee9b4", "PuttTime", "HE 90", "Demo", 18394, Common::EN_USA, Common::kPlatformUnknown },
- { "4edbf9d03550f7ba01e7f34d69b678dd", "spyfox", "HE 98.5", "Demo", -1, Common::NL_NLD, Common::kPlatformWindows },
+ { "4edbf9d03550f7ba01e7f34d69b678dd", "spyfox", "HE 98.5", "Demo", -1, Common::NL_NLD, Common::kPlatformUnknown },
{ "4f04b321a95d4315ce6d65f8e1dd0368", "maze", "HE 80", "", -1, Common::EN_USA, Common::kPlatformUnknown },
{ "4f138ac6f9b2ac5a41bc68b2c3296064", "freddi4", "HE 99", "", -1, Common::FR_FRA, Common::kPlatformWindows },
{ "4f1d6f8b38343dba405472538b5037ed", "fbear", "HE 62", "", 7717, Common::EN_ANY, Common::kPlatformPC },
@@ -249,6 +253,7 @@ static const MD5Table md5table[] = {
{ "5b08000a9c47b2887df6506ac767ca68", "fbear", "HE 62", "", -1, Common::EN_ANY, Common::kPlatform3DO },
{ "5bd335265a61caa3d78956ad9f88ba23", "football", "", "Demo", 23135, Common::EN_ANY, Common::kPlatformUnknown },
{ "5c21fc49aee8f46e58fef21579e614a1", "thinker1", "", "", -1, Common::EN_USA, Common::kPlatformUnknown },
+ { "5c9cecbd2952ccec14c9ecebf5822a34", "puttzoo", "HE 100", "", -1, Common::EN_ANY, Common::kPlatformIOS },
{ "5d88b9d6a88e6f8e90cded9d01b7f082", "loom", "VGA", "VGA", 8307, Common::EN_ANY, Common::kPlatformPC },
{ "5dda73606533d66a4c3f4f9ea6e842af", "farm", "", "", 87061, Common::RU_RUS, Common::kPlatformWindows },
{ "5e8fb66971a60e523e5afbc4c129c0e8", "socks", "HE 85", "", -1, Common::EN_USA, Common::kPlatformUnknown },
@@ -289,7 +294,7 @@ static const MD5Table md5table[] = {
{ "6a30a07f353a75cdc602db27d73e1b42", "puttputt", "HE 70", "", -1, Common::EN_ANY, Common::kPlatformWindows },
{ "6a60d395b78b205c93a956100b1bf5ae", "pajama2", "HE 98.5", "", -1, Common::DE_DEU, Common::kPlatformUnknown },
{ "6af2419fe3db5c2fdb091ae4e5833770", "puttrace", "HE 98.5", "Demo", -1, Common::NL_NLD, Common::kPlatformUnknown },
- { "6b19d0e25cbf720d05822379b8b90ed9", "PuttTime", "HE 90", "Demo", -1, Common::NL_NLD, Common::kPlatformWindows },
+ { "6b19d0e25cbf720d05822379b8b90ed9", "PuttTime", "HE 90", "Demo", -1, Common::NL_NLD, Common::kPlatformUnknown },
{ "6b257bb2827dd894b8109a50a1a18b5a", "freddicove", "HE 100", "Demo", -1, Common::NL_NLD, Common::kPlatformUnknown },
{ "6b27dbcd8d5697d5c918eeca0f68ef6a", "puttrace", "HE CUP", "Preview", 3901484, Common::UNK_LANG, Common::kPlatformUnknown },
{ "6b3ec67da214f558dc5ceaa2acd47453", "indy3", "EGA", "EGA", -1, Common::EN_ANY, Common::kPlatformPC },
@@ -320,13 +325,13 @@ static const MD5Table md5table[] = {
{ "7410a8ba9795020cd42f171c4320659e", "pajama3", "", "", -1, Common::FR_FRA, Common::kPlatformWindows },
{ "746e88c172a5b7a1ae89ac0ee3ee681a", "freddi", "HE 90", "Updated", -1, Common::RU_RUS, Common::kPlatformWindows },
{ "74da3494fbe1a7d20213b0afe0954755", "catalog", "HE CUP", "Preview", 10841544, Common::FR_FRA, Common::kPlatformUnknown },
- { "754feb59d3bf86b8a00840df74fd7b26", "freddi3", "", "Demo", -1, Common::NL_NLD, Common::kPlatformWindows },
+ { "754feb59d3bf86b8a00840df74fd7b26", "freddi3", "", "Demo", -1, Common::NL_NLD, Common::kPlatformUnknown },
{ "75ba23fff4fd63fa446c02864f2a5a4b", "zak", "V2", "V2", -1, Common::IT_ITA, Common::kPlatformPC },
{ "75bff95816b84672b877d22a911ab811", "freddi3", "HE 99", "Updated", -1, Common::RU_RUS, Common::kPlatformWindows },
{ "76b66b43e593ad4d2f1dfb5cc8f19700", "spyfox", "HE 99", "", -1, Common::NL_NLD, Common::kPlatformWindows },
{ "771bc18ec6f93837b839c992b211904b", "monkey", "Demo", "EGA Demo", -1, Common::DE_DEU, Common::kPlatformPC },
{ "7766c9487f9d53a8cb0edabda5119c3d", "puttputt", "HE 60", "", 8022, Common::EN_ANY, Common::kPlatformPC },
- { "77f5c9cc0986eb729c1a6b4c8823bbae", "zak", "FM-TOWNS", "Demo", 7520, Common::EN_ANY, Common::kPlatformFMTowns },
+ { "77f5c9cc0986eb729c1a6b4c8823bbae", "zakloom", "FM-TOWNS", "Demo", 7520, Common::EN_ANY, Common::kPlatformFMTowns },
{ "780e4a0ae2ff17dc296f4a79543b44f8", "puttmoon", "", "", -1, Common::UNK_LANG, Common::kPlatformPC },
{ "782393c5934ecd0b536eaf5fd541bd26", "pajama", "HE 100", "Updated", -1, Common::EN_ANY, Common::kPlatformWindows },
{ "784b499c98d07260a30952685758636b", "pajama3", "", "Demo", 13911, Common::DE_DEU, Common::kPlatformWindows },
@@ -485,7 +490,7 @@ static const MD5Table md5table[] = {
{ "bfdf584b01503f0762baded581f6a0a2", "SoccerMLS", "", "", -1, Common::EN_ANY, Common::kPlatformWindows },
{ "c0039ad982999c92d0de81910d640fa0", "freddi", "HE 71", "", -1, Common::NL_NLD, Common::kPlatformWindows },
{ "c13225cb1bbd3bc9fe578301696d8021", "monkey", "SEGA", "", -1, Common::EN_ANY, Common::kPlatformSegaCD },
- { "c20848f53c2d48bfacdc840993843765", "freddi2", "HE 80", "Demo", -1, Common::NL_NLD, Common::kPlatformWindows },
+ { "c20848f53c2d48bfacdc840993843765", "freddi2", "HE 80", "Demo", -1, Common::NL_NLD, Common::kPlatformUnknown },
{ "c225bec1b6c0798a2b8c89ac226dc793", "pajama", "HE 100", "", -1, Common::EN_ANY, Common::kPlatformWii },
{ "c24c490373aeb48fbd54caa8e7ae376d", "loom", "No AdLib", "EGA", -1, Common::DE_DEU, Common::kPlatformAtariST },
{ "c25755b08a8d0d47695e05f1e2111bfc", "freddi4", "", "Demo", -1, Common::EN_USA, Common::kPlatformUnknown },
@@ -504,6 +509,7 @@ static const MD5Table md5table[] = {
{ "c7890e038806df2bb5c0c8c6f1986ea2", "monkey", "VGA", "VGA", -1, Common::EN_ANY, Common::kPlatformPC },
{ "c7be10f775404fd9785a8b92a06d240c", "atlantis", "FM-TOWNS", "", 12030, Common::EN_ANY, Common::kPlatformFMTowns },
{ "c7c492a107ec520d7a7943037d0ca54a", "freddi", "HE 71", "Demo", -1, Common::NL_NLD, Common::kPlatformWindows },
+ { "c8253da0f4626d2236b5291b99e33408", "puttcircus", "HE 99", "", -1, Common::HE_ISR, Common::kPlatformWindows },
{ "c83079157ec765a28de445aec9768d60", "tentacle", "", "Demo", 7477, Common::EN_ANY, Common::kPlatformUnknown },
{ "c8575e0b973ff1723aba6cd92c642db2", "puttrace", "HE 99", "Demo", -1, Common::FR_FRA, Common::kPlatformWindows },
{ "c8aac5e3e701874e2fa4117896f9e1b1", "freddi", "HE 73", "Demo", -1, Common::EN_ANY, Common::kPlatformMacintosh },
@@ -609,6 +615,7 @@ static const MD5Table md5table[] = {
{ "f1b0e0d587b85052de5534a3847e68fe", "water", "HE 99", "Updated", -1, Common::EN_ANY, Common::kPlatformUnknown },
{ "f237bf8a5ef9af78b2a6a4f3901da341", "pajama", "", "Demo", 18354, Common::EN_ANY, Common::kPlatformUnknown },
{ "f27b1ba0eadaf2a6617b2b58192d1dbf", "samnmax", "Floppy", "Floppy", -1, Common::DE_DEU, Common::kPlatformPC },
+ { "f2ec78e50bdc63b70044e9758be10914", "spyfox", "HE 98.5", "Demo", -1, Common::NL_NLD, Common::kPlatformMacintosh },
{ "f3d55aea441e260e9e9c7d2a187097e0", "puttzoo", "", "Demo", 14337, Common::EN_ANY, Common::kPlatformWindows },
{ "f40a7f495f59188ca57a9d1d50301bb6", "puttputt", "HE 60", "Demo", -1, Common::EN_ANY, Common::kPlatformMacintosh },
{ "f5228b0cc1c19e6ea8268ba2eeb61f60", "freddi", "HE 73", "Demo", -1, Common::FR_FRA, Common::kPlatformWindows },
diff --git a/engines/scumm/scumm.cpp b/engines/scumm/scumm.cpp
index 81f6af453c..fc46f88df4 100644
--- a/engines/scumm/scumm.cpp
+++ b/engines/scumm/scumm.cpp
@@ -55,6 +55,7 @@
#include "scumm/player_nes.h"
#include "scumm/player_sid.h"
#include "scumm/player_pce.h"
+#include "scumm/player_apple2.h"
#include "scumm/player_v1.h"
#include "scumm/player_v2.h"
#include "scumm/player_v2cms.h"
@@ -150,9 +151,6 @@ ScummEngine::ScummEngine(OSystem *syst, const DetectorResult &dr)
_fileHandle = 0;
// Init all vars
- _v0ObjectIndex = false;
- _v0ObjectInInventory = false;
- _v0ObjectFlag = 0;
_imuse = NULL;
_imuseDigital = NULL;
_musicEngine = NULL;
@@ -265,7 +263,6 @@ ScummEngine::ScummEngine(OSystem *syst, const DetectorResult &dr)
_bytesPerPixel = 1;
_doEffect = false;
_snapScroll = false;
- _currentLights = 0;
_shakeEnabled = false;
_shakeFrame = 0;
_screenStartStrip = 0;
@@ -700,10 +697,6 @@ ScummEngine_v2::ScummEngine_v2(OSystem *syst, const DetectorResult &dr)
_inventoryOffset = 0;
- _activeInventory = 0;
- _activeObject = 0;
- _activeVerb = 0;
-
VAR_SENTENCE_VERB = 0xFF;
VAR_SENTENCE_OBJECT1 = 0xFF;
VAR_SENTENCE_OBJECT2 = 0xFF;
@@ -718,19 +711,18 @@ ScummEngine_v2::ScummEngine_v2(OSystem *syst, const DetectorResult &dr)
ScummEngine_v0::ScummEngine_v0(OSystem *syst, const DetectorResult &dr)
: ScummEngine_v2(syst, dr) {
- _verbExecuting = false;
- _verbPickup = false;
_currentMode = 0;
+ _currentLights = 0;
+ _activeVerb = kVerbNone;
+ _activeObject = 0;
_activeObject2 = 0;
- _activeObjectIndex = 0;
- _activeObject2Index = 0;
- _activeInvExecute = false;
- _activeObject2Inv = false;
- _activeObjectObtained = false;
- _activeObject2Obtained = false;
-
- VAR_ACTIVE_ACTOR = 0xFF;
+
+ _cmdVerb = kVerbNone;
+ _cmdObject = 0;
+ _cmdObject2 = 0;
+
+ VAR_ACTIVE_OBJECT2 = 0xFF;
VAR_IS_SOUND_RUNNING = 0xFF;
VAR_ACTIVE_VERB = 0xFF;
}
@@ -1033,7 +1025,7 @@ Common::Error ScummEngine::init() {
// The kGenUnchanged method is only used for 'container files', i.e. files
// that contain the real game files bundled together in an archive format.
- // This is the case of the NES, C64 and Mac versions of certain games.
+ // This is the case of the NES, v0 and Mac versions of certain games.
// Note: All of these can also occur in 'extracted' form, in which case they
// are treated like any other SCUMM game.
if (_filenamePattern.genMethod == kGenUnchanged) {
@@ -1171,11 +1163,8 @@ Common::Error ScummEngine::init() {
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) {
+ g = tryModes.reverse_erase(g);
+ } else if (*g == _outputPixelFormat) {
tryModes.clear();
tryModes.push_back(_outputPixelFormat);
break;
@@ -1258,6 +1247,16 @@ void ScummEngine::setupScumm() {
// Load game from specified slot, if any
if (ConfMan.hasKey("save_slot")) {
requestLoad(ConfMan.getInt("save_slot"));
+ } else if (!ConfMan.hasKey("boot_param") && _game.id == GID_LOOM && _game.platform == Common::kPlatformFMTowns) {
+ // In case we run the Loom FM-Towns version and have no boot parameter
+ // nor start save game supplied we will show our own custom difficulty
+ // selection dialog, since the original does not have any.
+ LoomTownsDifficultyDialog difficultyDialog;
+ runDialog(difficultyDialog);
+
+ int difficulty = difficultyDialog.getSelectedDifficulty();
+ if (difficulty != -1)
+ _bootParam = difficulty;
}
_res->allocResTypeData(rtBuffer, 0, 10, kDynamicResTypeMode);
@@ -1380,8 +1379,8 @@ void ScummEngine::setupCostumeRenderer() {
_costumeRenderer = new AkosRenderer(this);
_costumeLoader = new AkosCostumeLoader(this);
} else if (_game.version == 0) {
- _costumeRenderer = new C64CostumeRenderer(this);
- _costumeLoader = new C64CostumeLoader(this);
+ _costumeRenderer = new V0CostumeRenderer(this);
+ _costumeLoader = new V0CostumeLoader(this);
} else if (_game.platform == Common::kPlatformNES) {
_costumeRenderer = new NESCostumeRenderer(this);
_costumeLoader = new NESCostumeLoader(this);
@@ -1460,7 +1459,7 @@ void ScummEngine::resetScumm() {
_sortedActors = new Actor * [_numActors];
for (i = 0; i < _numActors; ++i) {
if (_game.version == 0)
- _actors[i] = new ActorC64(this, i);
+ _actors[i] = new Actor_v0(this, i);
else if (_game.version <= 2)
_actors[i] = new Actor_v2(this, i);
else if (_game.version == 3)
@@ -1800,7 +1799,7 @@ void ScummEngine::setupMusic(int midi) {
if (_game.version >= 7) {
// Setup for digital iMuse is performed in another place
} else if (_game.platform == Common::kPlatformApple2GS && _game.version == 0){
- // TODO: Add support for music format
+ _musicEngine = new Player_AppleII(this, _mixer);
} else if (_game.platform == Common::kPlatformC64 && _game.version <= 1) {
#ifndef DISABLE_SID
_musicEngine = new Player_SID(this, _mixer);
@@ -1965,6 +1964,14 @@ Common::Error ScummEngine::go() {
if (delta < 1) // Ensure we don't get into an endless loop
delta = 1; // by not decreasing sleepers.
+ // WORKAROUND: walking speed in the original v0/v1 interpreter
+ // is sometimes slower (e.g. during scrolling) than in ScummVM.
+ // This is important for the door-closing action in the dungeon,
+ // otherwise (delta < 6) a single kid is able to escape.
+ if ((_game.version == 0 && isScriptRunning(132)) ||
+ (_game.version == 1 && isScriptRunning(137)))
+ delta = 6;
+
// Wait...
waitForTimer(delta * 1000 / 60 - diff);
diff --git a/engines/scumm/scumm.h b/engines/scumm/scumm.h
index d9237b2b30..cacf8c214e 100644
--- a/engines/scumm/scumm.h
+++ b/engines/scumm/scumm.h
@@ -24,6 +24,7 @@
#define SCUMM_H
#include "engines/engine.h"
+
#include "common/endian.h"
#include "common/events.h"
#include "common/file.h"
@@ -31,6 +32,7 @@
#include "common/keyboard.h"
#include "common/random.h"
#include "common/rect.h"
+#include "common/rendermode.h"
#include "common/str.h"
#include "common/textconsole.h"
#include "graphics/surface.h"
@@ -303,6 +305,19 @@ struct SaveStateMetaInfos {
uint32 playtime;
};
+enum UserStates {
+ USERSTATE_SET_FREEZE = 0x01, // freeze scripts if USERSTATE_FREEZE_ON is set, unfreeze otherwise
+ USERSTATE_SET_CURSOR = 0x02, // shows cursor if USERSTATE_CURSOR_ON is set, hides it otherwise
+ USERSTATE_SET_IFACE = 0x04, // change user-interface (sentence-line, inventory, verb-area)
+ USERSTATE_FREEZE_ON = 0x08, // only interpreted if USERSTATE_SET_FREEZE is set
+ USERSTATE_CURSOR_ON = 0x10, // only interpreted if USERSTATE_SET_CURSOR is set
+ USERSTATE_IFACE_SENTENCE = 0x20, // only interpreted if USERSTATE_SET_IFACE is set
+ USERSTATE_IFACE_INVENTORY = 0x40, // only interpreted if USERSTATE_SET_IFACE is set
+ USERSTATE_IFACE_VERBS = 0x80 // only interpreted if USERSTATE_SET_IFACE is set
+};
+
+#define USERSTATE_IFACE_ALL (USERSTATE_IFACE_SENTENCE | USERSTATE_IFACE_INVENTORY | USERSTATE_IFACE_VERBS)
+
/**
* A list of resource types.
* WARNING: Do not change the order of these, as the savegame format relies
@@ -502,10 +517,6 @@ protected:
int32 *_scummVars;
byte *_bitVars;
- bool _v0ObjectIndex; // V0 Use object index, instead of object number
- bool _v0ObjectInInventory; // V0 Use object number from inventory
- byte _v0ObjectFlag;
-
/* Global resource tables */
int _numVariables, _numBitVariables, _numLocalObjects;
int _numGlobalObjects, _numArray, _numVerbs, _numFlObject;
@@ -646,7 +657,7 @@ protected:
void updateScriptPtr();
virtual void runInventoryScript(int i);
void inventoryScriptIndy3Mac();
- void checkAndRunSentenceScript();
+ virtual void checkAndRunSentenceScript();
void runExitScript();
void runEntryScript();
void runAllScripts();
@@ -791,6 +802,9 @@ protected:
void setOwnerOf(int obj, int owner);
void clearOwnerOf(int obj);
int getObjectRoom(int obj) const;
+ virtual bool objIsActor(int obj);
+ virtual int objToActor(int obj);
+ virtual int actorToObj(int actor);
int getObjX(int obj);
int getObjY(int obj);
void getObjectXYPos(int object, int &x, int &y) { int dir; getObjectXYPos(object, x, y, dir); }
@@ -799,7 +813,6 @@ protected:
int getObjNewDir(int obj);
int getObjectIndex(int object) const;
int getObjectImageCount(int object);
- int whereIsObjectInventory(int object);
int whereIsObject(int object) const;
int findObject(int x, int y);
void findObjectInRoom(FindObjectInRoom *fo, byte findWhat, uint object, uint room);
@@ -820,7 +833,7 @@ protected:
virtual void clearDrawQueues();
uint32 getOBCDOffs(int object) const;
- byte *getOBCDFromObject(int obj);
+ byte *getOBCDFromObject(int obj, bool v0CheckInventory = true);
const byte *getOBIMFromObjectData(const ObjectData &od);
const byte *getObjectImage(const byte *ptr, int state);
virtual int getObjectIdFromOBIM(const byte *obim);
@@ -931,8 +944,7 @@ protected:
public:
bool isLightOn() const;
- byte _currentLights;
- int getCurrentLights() const;
+ virtual int getCurrentLights() const;
protected:
void initScreens(int b, int h);
diff --git a/engines/scumm/scumm_v0.h b/engines/scumm/scumm_v0.h
index af481df0e0..7f532c04d7 100644
--- a/engines/scumm/scumm_v0.h
+++ b/engines/scumm/scumm_v0.h
@@ -32,20 +32,35 @@ namespace Scumm {
*/
class ScummEngine_v0 : public ScummEngine_v2 {
protected:
+ enum CurrentMode {
+ kModeCutscene = 0, // cutscene active
+ kModeKeypad = 1, // kid selection / dial pad / save-load dialog
+ kModeNoNewKid = 2, // verb "new kid" disabled (e.g. when entering lab)
+ kModeNormal = 3 // normal playing mode
+ };
+
+ enum WalkToObjectState {
+ kWalkToObjectStateDone = 0,
+ kWalkToObjectStateWalk = 1,
+ kWalkToObjectStateTurn = 2
+ };
+
+protected:
byte _currentMode;
- bool _verbExecuting; // is a verb executing
- bool _verbPickup; // are we picking up an object during a verb execute
+ byte _currentLights;
- int _activeActor; // Actor Number
- int _activeObject2; // 2nd Object Number
+ int _activeVerb; // selected verb
+ int _activeObject; // 1st selected object (see OBJECT_V0())
+ int _activeObject2; // 2nd selected object or actor (see OBJECT_V0())
- bool _activeInvExecute; // is activeInventory first to be executed
- bool _activeObject2Inv; // is activeobject2 in the inventory
- bool _activeObjectObtained; // collected _activeobject?
- bool _activeObject2Obtained; // collected _activeObject2?
+ int _cmdVerb; // script verb
+ int _cmdObject; // 1st script object (see OBJECT_V0())
+ int _cmdObject2; // 2nd script object or actor (see OBJECT_V0())
+ int _sentenceNestedCount;
- int _activeObjectIndex;
- int _activeObject2Index;
+ int _walkToObject;
+ int _walkToObjectState;
+ bool _redrawSentenceLine;
public:
ScummEngine_v0(OSystem *syst, const DetectorResult &dr);
@@ -64,26 +79,33 @@ protected:
virtual void processInput();
- virtual void runObject(int obj, int entry);
virtual void saveOrLoad(Serializer *s);
- // V0 MM Verb commands
- int verbPrep(int object);
- bool verbMove(int object, int objectIndex, bool invObject);
- bool verbMoveToActor(int actor);
- bool verbObtain(int object, int objIndex);
- bool verbExecutes(int object, bool inventory = false);
- bool verbExec();
-
- int findObjectIndex(int x, int y);
+ virtual bool objIsActor(int obj);
+ virtual int objToActor(int obj);
+ virtual int actorToObj(int actor);
+ // V0 MM Verb commands
+ int getVerbPrepId();
+ int activeVerbPrep();
+ void walkToActorOrObject(int object);
+ void verbExec();
+
+ virtual void runSentenceScript();
+ virtual void checkAndRunSentenceScript();
+ bool checkPendingWalkAction();
+ bool checkSentenceComplete();
virtual void checkExecVerbs();
virtual void handleMouseOver(bool updateInventory);
+ int verbPrepIdType(int verbid);
void resetVerbs();
- void setNewKidVerbs();
- void drawSentenceWord(int object, bool usePrep, bool objInInventory);
- void drawSentence();
+ void clearSentenceLine();
+ void flushSentenceLine();
+ void drawSentenceObject(int object);
+ void drawSentenceLine();
+
+ void setMode(byte mode);
void switchActor(int slot);
@@ -92,12 +114,17 @@ protected:
virtual int getActiveObject();
- virtual void resetSentence(bool walking);
+ void resetSentence();
virtual bool areBoxesNeighbors(int box1nr, int box2nr);
- /* Version C64 script opcodes */
+ bool ifEqualActiveObject2Common(bool checkType);
+
+ virtual int getCurrentLights() const;
+
+ /* Version 0 script opcodes */
void o_stopCurrentScript();
+ void o_walkActorToObject();
void o_loadSound();
void o_getActorMoving();
void o_animateActor();
@@ -112,30 +139,30 @@ protected:
void o_lockScript();
void o_loadScript();
void o_lockRoom();
- void o_cursorCommand();
+ void o_setMode();
void o_lights();
void o_unlockCostume();
void o_unlockScript();
void o_decrement();
void o_nop();
+ void o_getObjectOwner();
void o_getActorBitVar();
void o_setActorBitVar();
void o_getBitVar();
void o_setBitVar();
void o_doSentence();
- void o_unknown2();
- void o_ifActiveObject();
- void o_getClosestObjActor();
- void o_printEgo_c64();
- void o_print_c64();
+ void o_ifEqualActiveObject2();
+ void o_ifNotEqualActiveObject2();
+ void o_getClosestActor();
+ void o_printEgo();
+ void o_print();
void o_unlockRoom();
void o_unlockSound();
void o_cutscene();
void o_endCutscene();
- void o_beginOverride();
void o_setOwnerOf();
- byte VAR_ACTIVE_ACTOR;
+ byte VAR_ACTIVE_OBJECT2;
byte VAR_IS_SOUND_RUNNING;
byte VAR_ACTIVE_VERB;
};
diff --git a/engines/scumm/scumm_v2.h b/engines/scumm/scumm_v2.h
index 47c5fa2626..316a08d325 100644
--- a/engines/scumm/scumm_v2.h
+++ b/engines/scumm/scumm_v2.h
@@ -44,17 +44,13 @@ protected:
Common::String _sentenceBuf;
uint16 _inventoryOffset;
- int _activeInventory;
- int _activeObject;
- int _activeVerb;
-
public:
ScummEngine_v2(OSystem *syst, const DetectorResult &dr);
virtual void resetScumm();
void checkV2MouseOver(Common::Point pos);
- void checkV2Inventory(int x, int y);
+ int checkV2Inventory(int x, int y);
void redrawV2Inventory();
protected:
@@ -89,8 +85,9 @@ protected:
void ifNotStateCommon(byte type);
void setStateCommon(byte type);
void clearStateCommon(byte type);
+ void stopScriptCommon(int script);
- virtual void resetSentence(bool walking);
+ void resetSentence();
void setUserState(byte state);
virtual void handleMouseOver(bool updateInventory);
@@ -100,6 +97,10 @@ protected:
virtual void setBuiltinCursor(int index);
+ void drawPreposition(int index);
+
+ void walkActorToObject(int actor, int obj);
+
/* Version 2 script opcodes */
void o2_actorFromPos();
void o2_actorOps();
diff --git a/engines/scumm/scumm_v5.h b/engines/scumm/scumm_v5.h
index b8a61c1677..0eef04b8de 100644
--- a/engines/scumm/scumm_v5.h
+++ b/engines/scumm/scumm_v5.h
@@ -87,6 +87,8 @@ protected:
void drawFlashlight();
+ void walkActorToActor(int actor, int toActor, int dist);
+
/**
* Fetch the next script word, then if cond is *false*, perform a relative jump.
* So this corresponds to a "jne" jump instruction.
diff --git a/engines/scumm/smush/smush_player.cpp b/engines/scumm/smush/smush_player.cpp
index 2f4e86bf61..a53b808ba1 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(static_cast<unsigned char>(*(id_end-1)))) {
+ while (id_end >= def_start && !Common::isDigit(*(id_end-1))) {
id_end--;
}
assert(id_end > def_start);
char *id_start = id_end;
- while (isdigit(static_cast<unsigned char>(*(id_start - 1)))) {
+ while (Common::isDigit(*(id_start - 1))) {
id_start--;
}
diff --git a/engines/scumm/sound.cpp b/engines/scumm/sound.cpp
index ba8c6e2277..1dc026ad52 100644
--- a/engines/scumm/sound.cpp
+++ b/engines/scumm/sound.cpp
@@ -23,6 +23,8 @@
#include "common/config-manager.h"
#include "common/timer.h"
#include "common/util.h"
+#include "common/ptr.h"
+#include "common/substream.h"
#include "scumm/actor.h"
#include "scumm/file.h"
@@ -62,7 +64,8 @@ Sound::Sound(ScummEngine *parent, Audio::Mixer *mixer)
_mixer(mixer),
_soundQuePos(0),
_soundQue2Pos(0),
- _sfxFile(0),
+ _sfxFilename(),
+ _sfxFileEncByte(0),
_offsetTable(0),
_numSoundEffects(0),
_soundMode(kVOCMode),
@@ -91,7 +94,7 @@ Sound::Sound(ScummEngine *parent, Audio::Mixer *mixer)
Sound::~Sound() {
stopCDTimer();
g_system->getAudioCDManager()->stop();
- delete _sfxFile;
+ free(_offsetTable);
}
void Sound::addSoundToQueue(int sound, int heOffset, int heChannel, int heFlags) {
@@ -490,6 +493,7 @@ void Sound::startTalkSound(uint32 offset, uint32 b, int mode, Audio::SoundHandle
int num = 0, i;
int size = 0;
int id = -1;
+ Common::ScopedPtr<ScummFile> file;
if (_vm->_game.id == GID_CMI) {
_sfxMode |= mode;
@@ -523,25 +527,29 @@ void Sound::startTalkSound(uint32 offset, uint32 b, int mode, Audio::SoundHandle
return;
}
- _sfxFile->close();
- sprintf(filename, "audio/%s.%d/%d.voc", roomname, offset, b);
- _vm->openFile(*_sfxFile, filename);
- if (!_sfxFile->isOpen()) {
- sprintf(filename, "audio/%s_%d/%d.voc", roomname, offset, b);
- _vm->openFile(*_sfxFile, filename);
+ file.reset(new ScummFile());
+ if (!file)
+ error("startTalkSound: Out of memory");
+
+ sprintf(filename, "audio/%s.%u/%u.voc", roomname, offset, b);
+ if (!_vm->openFile(*file, filename)) {
+ sprintf(filename, "audio/%s_%u/%u.voc", roomname, offset, b);
+ _vm->openFile(*file, filename);
}
- if (!_sfxFile->isOpen()) {
- sprintf(filename, "%d.%d.voc", offset, b);
- _vm->openFile(*_sfxFile, filename);
+
+ if (!file->isOpen()) {
+ sprintf(filename, "%u.%u.voc", offset, b);
+ _vm->openFile(*file, filename);
}
- if (!_sfxFile->isOpen()) {
+
+ if (!file->isOpen()) {
warning("startTalkSound: dig demo: voc file not found");
return;
}
} else {
- if (!_sfxFile->isOpen()) {
- warning("startTalkSound: SFX file is not open");
+ if (_sfxFilename.empty()) {
+ warning("startTalkSound: SFX file not found");
return;
}
@@ -581,11 +589,30 @@ void Sound::startTalkSound(uint32 offset, uint32 b, int mode, Audio::SoundHandle
size = -1;
}
- _sfxFile->seek(offset, SEEK_SET);
+ file.reset(new ScummFile());
+ if (!file)
+ error("startTalkSound: Out of memory");
+
+ if (!_vm->openFile(*file, _sfxFilename)) {
+ warning("startTalkSound: could not open sfx file %s", _sfxFilename.c_str());
+ return;
+ }
+
+ file->setEnc(_sfxFileEncByte);
+ file->seek(offset, SEEK_SET);
assert(num + 1 < (int)ARRAYSIZE(_mouthSyncTimes));
for (i = 0; i < num; i++)
- _mouthSyncTimes[i] = _sfxFile->readUint16BE();
+ _mouthSyncTimes[i] = file->readUint16BE();
+
+ // Adjust offset to account for the mouth sync times. It is noteworthy
+ // that we do not adjust the size here for compressed streams, since
+ // they only set size to the size of the compressed sound data.
+ offset += num * 2;
+ // TODO: In case we ever set up the size for VOC streams, we should
+ // really check whether the size contains the _mouthSyncTimes.
+ //if (_soundMode == kVOCMode)
+ // size -= num * 2;
_mouthSyncTimes[i] = 0xFFFF;
_sfxMode |= mode;
@@ -601,9 +628,7 @@ void Sound::startTalkSound(uint32 offset, uint32 b, int mode, Audio::SoundHandle
#ifdef USE_MAD
{
assert(size > 0);
- Common::SeekableReadStream *tmp = _sfxFile->readStream(size);
- assert(tmp);
- input = Audio::makeMP3Stream(tmp, DisposeAfterUse::YES);
+ input = Audio::makeMP3Stream(new Common::SeekableSubReadStream(file.release(), offset, offset + size, DisposeAfterUse::YES), DisposeAfterUse::YES);
}
#endif
break;
@@ -611,9 +636,7 @@ void Sound::startTalkSound(uint32 offset, uint32 b, int mode, Audio::SoundHandle
#ifdef USE_VORBIS
{
assert(size > 0);
- Common::SeekableReadStream *tmp = _sfxFile->readStream(size);
- assert(tmp);
- input = Audio::makeVorbisStream(tmp, DisposeAfterUse::YES);
+ input = Audio::makeVorbisStream(new Common::SeekableSubReadStream(file.release(), offset, offset + size, DisposeAfterUse::YES), DisposeAfterUse::YES);
}
#endif
break;
@@ -621,14 +644,12 @@ void Sound::startTalkSound(uint32 offset, uint32 b, int mode, Audio::SoundHandle
#ifdef USE_FLAC
{
assert(size > 0);
- Common::SeekableReadStream *tmp = _sfxFile->readStream(size);
- assert(tmp);
- input = Audio::makeFLACStream(tmp, DisposeAfterUse::YES);
+ input = Audio::makeFLACStream(new Common::SeekableSubReadStream(file.release(), offset, offset + size, DisposeAfterUse::YES), DisposeAfterUse::YES);
}
#endif
break;
default:
- input = Audio::makeVOCStream(_sfxFile, Audio::FLAG_UNSIGNED);
+ input = Audio::makeVOCStream(file.release(), Audio::FLAG_UNSIGNED, DisposeAfterUse::YES);
break;
}
@@ -847,20 +868,11 @@ void Sound::talkSound(uint32 a, uint32 b, int mode, int channel) {
_talk_sound_mode |= mode;
}
-/* The sound code currently only supports General Midi.
- * General Midi is used in Day Of The Tentacle.
- * Roland music is also playable, but doesn't sound well.
- * A mapping between roland instruments and GM instruments
- * is needed.
- */
-
void Sound::setupSound() {
- delete _sfxFile;
-
- _sfxFile = openSfxFile();
+ setupSfxFile();
if (_vm->_game.id == GID_FT) {
- _vm->VAR(_vm->VAR_VOICE_BUNDLE_LOADED) = _sfxFile->isOpen();
+ _vm->VAR(_vm->VAR_VOICE_BUNDLE_LOADED) = _sfxFilename.empty() ? 0 : 1;
}
}
@@ -892,7 +904,7 @@ void Sound::pauseSounds(bool pause) {
}
}
-BaseScummFile *Sound::openSfxFile() {
+void Sound::setupSfxFile() {
struct SoundFileExtensions {
const char *ext;
SoundMode mode;
@@ -912,8 +924,10 @@ BaseScummFile *Sound::openSfxFile() {
{ 0, kVOCMode }
};
- ScummFile *file = new ScummFile();
+ ScummFile file;
_offsetTable = NULL;
+ _sfxFileEncByte = 0;
+ _sfxFilename.clear();
/* Try opening the file <baseName>.sou first, e.g. tentacle.sou.
* That way, you can keep .sou files for multiple games in the
@@ -938,15 +952,20 @@ BaseScummFile *Sound::openSfxFile() {
tmp = basename[0] + "tlk";
}
- if (file->open(tmp) && _vm->_game.heversion <= 74)
- file->setEnc(0x69);
+ if (file.open(tmp))
+ _sfxFilename = tmp;
+
+ if (_vm->_game.heversion <= 74)
+ _sfxFileEncByte = 0x69;
+
_soundMode = kVOCMode;
} else {
- for (uint j = 0; j < 2 && !file->isOpen(); ++j) {
+ for (uint j = 0; j < 2 && !file.isOpen(); ++j) {
for (int i = 0; extensions[i].ext; ++i) {
tmp = basename[j] + extensions[i].ext;
- if (_vm->openFile(*file, tmp)) {
+ if (_vm->openFile(file, tmp)) {
_soundMode = extensions[i].mode;
+ _sfxFilename = tmp;
break;
}
}
@@ -970,23 +989,21 @@ BaseScummFile *Sound::openSfxFile() {
*/
int size, compressed_offset;
MP3OffsetTable *cur;
- compressed_offset = file->readUint32BE();
+ compressed_offset = file.readUint32BE();
_offsetTable = (MP3OffsetTable *) malloc(compressed_offset);
_numSoundEffects = compressed_offset / 16;
size = compressed_offset;
cur = _offsetTable;
while (size > 0) {
- cur->org_offset = file->readUint32BE();
- cur->new_offset = file->readUint32BE() + compressed_offset + 4; /* The + 4 is to take into accound the 'size' field */
- cur->num_tags = file->readUint32BE();
- cur->compressed_size = file->readUint32BE();
+ cur->org_offset = file.readUint32BE();
+ cur->new_offset = file.readUint32BE() + compressed_offset + 4; /* The + 4 is to take into accound the 'size' field */
+ cur->num_tags = file.readUint32BE();
+ cur->compressed_size = file.readUint32BE();
size -= 4 * 4;
cur++;
}
}
-
- return file;
}
bool Sound::isSfxFinished() const {
diff --git a/engines/scumm/sound.h b/engines/scumm/sound.h
index e9a37ac9fa..48f28d51ff 100644
--- a/engines/scumm/sound.h
+++ b/engines/scumm/sound.h
@@ -69,7 +69,8 @@ protected:
int16 flags;
} _soundQue2[10];
- BaseScummFile *_sfxFile;
+ Common::String _sfxFilename;
+ byte _sfxFileEncByte;
SoundMode _soundMode;
MP3OffsetTable *_offsetTable; // For compressed audio
int _numSoundEffects; // For compressed audio
@@ -126,7 +127,7 @@ public:
void saveLoadWithSerializer(Serializer *ser);
protected:
- BaseScummFile *openSfxFile();
+ void setupSfxFile();
bool isSfxFinished() const;
void processSfxQueues();
diff --git a/engines/scumm/string.cpp b/engines/scumm/string.cpp
index 61bb89328d..975307d0d0 100644
--- a/engines/scumm/string.cpp
+++ b/engines/scumm/string.cpp
@@ -112,7 +112,7 @@ void ScummEngine::showMessageDialog(const byte *msg) {
if (_string[3].color == 0)
_string[3].color = 4;
- InfoDialog dialog(this, (char*)buf);
+ InfoDialog dialog(this, (char *)buf);
VAR(VAR_KEYPRESS) = runDialog(dialog);
}
@@ -1389,10 +1389,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(static_cast<unsigned char>(*ptr))) {
+ } else if (Common::isDigit(*ptr)) {
int idx = 0;
// A number (up to three digits)...
- while (isdigit(static_cast<unsigned char>(*ptr))) {
+ while (Common::isDigit(*ptr)) {
idx = idx * 10 + (*ptr - '0');
ptr++;
}
@@ -1430,12 +1430,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(static_cast<unsigned char>(*ptr)); j++, ptr++)
+ for (j = 0; j < 8 && !Common::isSpace(*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(static_cast<unsigned char>(*ptr)));
+ assert(Common::isSpace(*ptr));
ptr++;
// Then comes the translated string: we record an offset to that.
diff --git a/engines/scumm/vars.cpp b/engines/scumm/vars.cpp
index 26a6a2f3b1..6d132c601f 100644
--- a/engines/scumm/vars.cpp
+++ b/engines/scumm/vars.cpp
@@ -115,7 +115,7 @@ void ScummEngine_v0::setupScummVars() {
VAR_CAMERA_POS_X = 2;
VAR_HAVE_MSG = 3;
VAR_ROOM = 4;
- VAR_ACTIVE_ACTOR = 5;
+ VAR_ACTIVE_OBJECT2 = 5;
VAR_OVERRIDE = 6;
VAR_IS_SOUND_RUNNING = 8;
VAR_ACTIVE_VERB = 9;
@@ -546,7 +546,7 @@ void ScummEngine_v8::setupScummVars() {
#endif
void ScummEngine_v0::resetScummVars() {
- resetSentence(false);
+ resetSentence();
VAR(VAR_EGO) = 3;
diff --git a/engines/scumm/verbs.cpp b/engines/scumm/verbs.cpp
index 67ed17c024..567ca31485 100644
--- a/engines/scumm/verbs.cpp
+++ b/engines/scumm/verbs.cpp
@@ -41,47 +41,58 @@ struct VerbSettings {
int id;
int x_pos;
int y_pos;
- int prep;
const char *name;
};
static const VerbSettings v0VerbTable_English[] = {
- { 1, 8, 0, 0, "Open"},
- { 2, 8, 1, 0, "Close"},
- { 3, 0, 2, 4, "Give"},
- { 4, 32, 0, 0, "Turn on"},
- { 5, 32, 1, 0, "Turn off"},
- { 6, 32, 2, 2, "Fix"},
- { 7, 24, 0, 0, "New Kid"},
- { 8, 24, 1, 2, "Unlock"},
- { 9, 0, 0, 0, "Push"},
- {10, 0, 1, 0, "Pull"},
- {11, 24, 2, 255, "Use"},
- {12, 8, 2, 0, "Read"},
- {13, 15, 0, 0, "Walk to"},
- {14, 15, 1, 0, "Pick up"},
- {15, 15, 2, 0, "What is"}
+ {kVerbOpen, 8, 0, "Open"},
+ {kVerbClose, 8, 1, "Close"},
+ {kVerbGive, 0, 2, "Give"},
+ {kVerbTurnOn, 32, 0, "Turn on"},
+ {kVerbTurnOff, 32, 1, "Turn off"},
+ {kVerbFix, 32, 2, "Fix"},
+ {kVerbNewKid, 24, 0, "New Kid"},
+ {kVerbUnlock, 24, 1, "Unlock"},
+ {kVerbPush, 0, 0, "Push"},
+ {kVerbPull, 0, 1, "Pull"},
+ {kVerbUse, 24, 2, "Use"},
+ {kVerbRead, 8, 2, "Read"},
+ {kVerbWalkTo, 15, 0, "Walk to"},
+ {kVerbPickUp, 15, 1, "Pick up"},
+ {kVerbWhatIs, 15, 2, "What is"}
};
-// FIXME: Replace * with the correct character
static const VerbSettings v0VerbTable_German[] = {
- { 1, 7, 0, 0, "$ffne"},
- { 2, 13, 1, 0, "Schlie*e"},
- { 3, 0, 2, 4, "Gebe"},
- { 4, 37, 1, 0, "Ein"},
- { 5, 37, 0, 0, "Aus"},
- { 6, 23, 1, 2, "Repariere"},
- { 7, 34, 2, 0, "Person"},
- { 8, 23, 0, 2, "Schlie*e auf"},
- { 9, 0, 0, 0, "Dr<cke"},
- {10, 0, 1, 0, "Ziehe"},
- {11, 23, 2, 255, "Benutz"},
- {12, 7, 2, 0, "Lese"},
- {13, 13, 0, 0, "Gehe zu"},
- {14, 7, 1, 0, "Nimm"},
- {15, 13, 2, 0, "Was ist"}
+ {kVerbOpen, 7, 0, "$ffne"},
+ {kVerbClose, 13, 1, "Schlie*e"},
+ {kVerbGive, 0, 2, "Gebe"},
+ {kVerbTurnOn, 37, 1, "Ein"},
+ {kVerbTurnOff, 37, 0, "Aus"},
+ {kVerbFix, 23, 1, "Repariere"},
+ {kVerbNewKid, 34, 2, "Person"},
+ {kVerbUnlock, 23, 0, "Schlie*e auf"},
+ {kVerbPush, 0, 0, "Dr<cke"},
+ {kVerbPull, 0, 1, "Ziehe"},
+ {kVerbUse, 23, 2, "Benutz"},
+ {kVerbRead, 7, 2, "Lese"},
+ {kVerbWalkTo, 13, 0, "Gehe zu"},
+ {kVerbPickUp, 7, 1, "Nimm"},
+ {kVerbWhatIs, 13, 2, "Was ist"}
};
+int ScummEngine_v0::verbPrepIdType(int verbid) {
+ switch (verbid) {
+ case kVerbUse: // depends on object1
+ return kVerbPrepObject;
+ case kVerbGive:
+ return kVerbPrepTo;
+ case kVerbUnlock: case kVerbFix:
+ return kVerbPrepWith;
+ default:
+ return kVerbPrepNone;
+ }
+}
+
void ScummEngine_v0::resetVerbs() {
VirtScreen *virt = &_virtscr[kVerbVirtScreen];
VerbSlot *vs;
@@ -112,62 +123,22 @@ void ScummEngine_v0::resetVerbs() {
vs->key = 0;
vs->center = 0;
vs->imgindex = 0;
- vs->prep = vtable[i - 1].prep;
+ vs->prep = verbPrepIdType(vtable[i - 1].id);
vs->curRect.left = vtable[i - 1].x_pos * 8;
vs->curRect.top = vtable[i - 1].y_pos * 8 + virt->topline + 8;
loadPtrToResource(rtVerb, i, (const byte*)vtable[i - 1].name);
}
}
-void ScummEngine_v0::setNewKidVerbs() {
- VirtScreen *virt = &_virtscr[kVerbVirtScreen];
- VerbSlot *vs;
- int i;
-
- for (i = 1; i < 16; i++)
- killVerb(i);
-
- for (i = 1; i < 4; i++) {
- vs = &_verbs[i];
- vs->verbid = i;
- vs->color = 5;
- vs->hicolor = 7;
- vs->dimcolor = 11;
- vs->type = kTextVerbType;
- vs->charset_nr = _string[0]._default.charset;
- vs->curmode = 1;
- vs->saveid = 0;
- vs->key = 0;
- vs->center = 0;
- vs->imgindex = 0;
- vs->prep = 0;
- vs->curRect.left = (i * 8) * 8;
- vs->curRect.top = virt->topline + 8;
-
- Actor *a = derefActor(VAR(96 + i), "setNewKidVerbs");
- loadPtrToResource(rtVerb, i, (const byte*)a->getActorName());
- }
- setUserState(191);
-}
-
void ScummEngine_v0::switchActor(int slot) {
- resetSentence(false);
-
- if (_currentRoom == 45)
- return;
-
- // radiation suit? don't let the player switch
- if (VAR(VAR_EGO) == 8)
- return;
+ resetSentence();
- // verbs disabled? or just new kid button?
- if (_currentMode == 0 || _currentMode == 1 || _currentMode == 2)
+ // actor switching only allowed during normal gamplay (not cutscene, ...)
+ if (_currentMode != kModeNormal)
return;
VAR(VAR_EGO) = VAR(97 + slot);
- resetVerbs();
actorFollowCamera(VAR(VAR_EGO));
- setUserState(247);
}
void ScummEngine_v2::initV2MouseOver() {
@@ -301,7 +272,7 @@ void ScummEngine_v2::checkV2MouseOver(Common::Point pos) {
int i, x, y, new_box = -1;
// Don't do anything unless the inventory is active
- if (!(_userState & 64)) {
+ if (!(_userState & USERSTATE_IFACE_INVENTORY)) {
_mouseOverBoxV2 = -1;
return;
}
@@ -354,14 +325,14 @@ void ScummEngine_v2::checkV2MouseOver(Common::Point pos) {
}
}
-void ScummEngine_v2::checkV2Inventory(int x, int y) {
+int ScummEngine_v2::checkV2Inventory(int x, int y) {
int inventoryArea = (_game.platform == Common::kPlatformNES) ? 48: 32;
int object = 0;
y -= _virtscr[kVerbVirtScreen].topline;
if ((y < inventoryArea) || !(_mouseAndKeyboardStat & MBS_LEFT_CLICK))
- return;
+ return 0;
if (_mouseOverBoxesV2[kInventoryUpArrow].rect.contains(x, y)) {
if (_inventoryOffset >= 2) {
@@ -382,18 +353,9 @@ void ScummEngine_v2::checkV2Inventory(int x, int y) {
}
if (object >= 4)
- return;
-
- object = findInventory(_scummVars[VAR_EGO], object + 1 + _inventoryOffset);
-
- if (object > 0) {
- if (_game.version == 0) {
- _activeInventory = object;
+ return 0;
- } else {
- runInputScript(kInventoryClickArea, object, 0);
- }
- }
+ return findInventory(_scummVars[VAR_EGO], object + 1 + _inventoryOffset);
}
void ScummEngine_v2::redrawV2Inventory() {
@@ -406,7 +368,7 @@ void ScummEngine_v2::redrawV2Inventory() {
_mouseOverBoxV2 = -1;
- if (!(_userState & 64)) // Don't draw inventory unless active
+ if (!(_userState & USERSTATE_IFACE_INVENTORY)) // Don't draw inventory unless active
return;
// Clear on all invocations
@@ -431,9 +393,7 @@ void ScummEngine_v2::redrawV2Inventory() {
_string[1].right = _mouseOverBoxesV2[i].rect.right - 1;
_string[1].color = _mouseOverBoxesV2[i].color;
- _v0ObjectInInventory = true;
const byte *tmp = getObjOrActorName(obj);
- _v0ObjectInInventory = false;
assert(tmp);
// Prevent inventory entries from overflowing by truncating the text
@@ -472,7 +432,7 @@ void ScummEngine_v2::redrawV2Inventory() {
}
void ScummEngine::redrawVerbs() {
- if (_game.version <= 2 && !(_userState & 128)) // Don't draw verbs unless active
+ if (_game.version <= 2 && !(_userState & USERSTATE_IFACE_VERBS)) // Don't draw verbs unless active
return;
int i, verb = 0;
@@ -516,7 +476,6 @@ void ScummEngine_v2::handleMouseOver(bool updateInventory) {
}
void ScummEngine_v0::handleMouseOver(bool updateInventory) {
- drawSentence();
ScummEngine_v2::handleMouseOver(updateInventory);
}
@@ -674,15 +633,8 @@ void ScummEngine_v2::checkExecVerbs() {
if (object != -1) {
object = findInventory(_scummVars[VAR_EGO], object + 1 + _inventoryOffset);
-
- if (object > 0) {
- if (_game.version == 0) {
- _activeInventory = object;
-
- } else {
- runInputScript(kInventoryClickArea, object, 0);
- }
- }
+ if (object > 0)
+ runInputScript(kInventoryClickArea, object, 0);
return;
}
@@ -703,7 +655,9 @@ void ScummEngine_v2::checkExecVerbs() {
runInputScript(kSentenceClickArea, 0, 0);
} else if (zone->number == kVerbVirtScreen && _mouse.y > zone->topline + inventoryArea) {
// Click into V2 inventory
- checkV2Inventory(_mouse.x, _mouse.y);
+ int object = checkV2Inventory(_mouse.x, _mouse.y);
+ if (object > 0)
+ runInputScript(kInventoryClickArea, object, 0);
} else {
over = findVerbAtPos(_mouse.x, _mouse.y);
if (over != 0) {
@@ -717,550 +671,210 @@ void ScummEngine_v2::checkExecVerbs() {
}
}
-void ScummEngine_v0::runObject(int obj, int entry) {
- bool prev = _v0ObjectInInventory;
-
- if (getVerbEntrypoint(obj, entry) == 0) {
- // If nothing was found, attempt to find the 'WHAT-IS' verb script
- // (which is not really the what-is script, as this verb never actually executes
- // it merely seems to be some type of fallback)
- if (getVerbEntrypoint(obj, 0x0F) != 0) {
- entry = 0x0F;
- }
- }
-
- _v0ObjectInInventory = prev;
-
- if (getVerbEntrypoint(obj, entry) != 0) {
- _v0ObjectInInventory = prev;
- runObjectScript(obj, entry, false, false, NULL);
- } else if (entry != 13 && entry != 15) {
- if (_activeVerb != 3) {
- VAR(VAR_ACTIVE_VERB) = entry;
- runScript(3, 0, 0, 0);
-
- // For some reasons, certain objects don't have a "give" script
- } else if (VAR(VAR_ACTIVE_ACTOR) > 0 && VAR(VAR_ACTIVE_ACTOR) < 8) {
- if (_activeInventory)
- setOwnerOf(_activeInventory, VAR(VAR_ACTIVE_ACTOR));
- }
- }
-}
-
-bool ScummEngine_v0::verbMoveToActor(int actor) {
- Actor *a = derefActor(VAR(VAR_EGO), "verbMoveToActor");
- Actor *a2 = derefActor(actor, "verbMoveToActor");
- int dist = getDist(a->getRealPos().x, a->getRealPos().y, a2->getRealPos().x, a2->getRealPos().y);
-
- if (!a->_moving && dist > 4) {
- a->startWalkActor(a2->getRealPos().x, a2->getRealPos().y, -1);
+int ScummEngine_v0::getVerbPrepId() {
+ if (_verbs[_activeVerb].prep != 0xFF) {
+ return _verbs[_activeVerb].prep;
} else {
- if (dist <= 4) {
- a->stopActorMoving();
- return false;
- }
+ byte *ptr = getOBCDFromObject(_activeObject, true);
+ assert(ptr);
+ return (*(ptr + 11) >> 5);
}
-
- return true;
}
-bool ScummEngine_v0::verbMove(int object, int objectIndex, bool invObject) {
- int x, y, dir;
- Actor *a = derefActor(VAR(VAR_EGO), "verbMove");
-
- if (_currentMode != 3 && _currentMode != 2)
- return false;
-
- _v0ObjectIndex = true;
- getObjectXYPos(objectIndex, x, y, dir);
- _v0ObjectIndex = false;
-
- // Detect distance from target object
- int dist = getDist(a->getRealPos().x, a->getRealPos().y, x, y);
-
- if (a->_moving)
- return true;
-
- if (dist > 5) {
- a->startWalkActor(x, y, dir);
- VAR(6) = x;
- VAR(7) = y;
- return true;
- } else {
- // Finished walk, are we picking up the item?
- if (_verbPickup) {
- int oldActive = _activeObject, oldIndex = _activeObjectIndex;
- _activeObject = object;
- _activeObjectIndex = objectIndex;
-
- _v0ObjectIndex = true;
- // Execute pickup
- runObject(objectIndex, 14);
- _v0ObjectIndex = false;
-
- _activeObject = oldActive;
- _activeObjectIndex = oldIndex;
-
- // Finished picking up
- _verbPickup = false;
- }
- }
-
- return false;
+int ScummEngine_v0::activeVerbPrep() {
+ if (!_activeVerb || !_activeObject)
+ return 0;
+ return getVerbPrepId();
}
-bool ScummEngine_v0::verbObtain(int obj, int objIndex) {
- bool didPickup = false;
+void ScummEngine_v0::verbExec() {
+ _sentenceNum = 0;
+ _sentenceNestedCount = 0;
- int prep, where = whereIsObjectInventory(obj);
-
- if (objIndex == 0)
- return false;
-
- // Object in inventory ?
- if (where != WIO_INVENTORY) {
- _v0ObjectIndex = true;
- prep = verbPrep(objIndex);
-
- if (prep == 1 || prep == 4) {
- if (_activeVerb != 13 && _activeVerb != 14) {
- _verbPickup = true;
- didPickup = true;
- }
- } else {
- _verbPickup = false;
- }
-
- // Ignore verbs?
- Actor *a = derefActor(VAR(VAR_EGO), "verbObtain");
- if (((ActorC64 *)a)->_miscflags & 0x40) {
- resetSentence(false);
- return false;
+ if (_activeVerb == kVerbWhatIs)
+ return;
+
+ if (!(_activeVerb == kVerbWalkTo && _activeObject == 0)) {
+ doSentence(_activeVerb, _activeObject, _activeObject2);
+ if (_activeVerb != kVerbWalkTo) {
+ _activeVerb = kVerbWalkTo;
+ _activeObject = 0;
+ _activeObject2 = 0;
}
-
- //attempt move to object
- if (verbMove(obj, objIndex, false))
- return true;
-
- if (didPickup && (prep == 1 || prep == 4))
- if (_activeVerb != 13 && _activeVerb != 14) {
- _v0ObjectInInventory = true;
-
- if (whereIsObject(obj) == WIO_INVENTORY)
- _activeInventory = obj;
- else
- resetSentence(false);
-
- _v0ObjectInInventory = false;
- }
+ _walkToObjectState = kWalkToObjectStateDone;
+ return;
}
- return false;
-}
-
-int ScummEngine_v0::verbPrep(int object) {
- if (!_v0ObjectInInventory)
- _v0ObjectIndex = true;
- else
- _v0ObjectIndex = false;
+ Actor_v0 *a = (Actor_v0 *)derefActor(VAR(VAR_EGO), "verbExec");
+ int x = _virtualMouse.x / V12_X_MULTIPLIER;
+ int y = _virtualMouse.y / V12_Y_MULTIPLIER;
+ //actorSetPosInBox();
- byte *ptr = getOBCDFromObject(object);
- _v0ObjectIndex = false;
- assert(ptr);
- return (*(ptr + 11) >> 5);
-}
+ // 0xB31
+ VAR(6) = x;
+ VAR(7) = y;
-bool ScummEngine_v0::verbExecutes(int object, bool inventory) {
- _v0ObjectInInventory = inventory;
- int prep = verbPrep(object);
-
- if (prep == 2 || prep == 0) {
- return true;
- }
+ if (a->_miscflags & kActorMiscFlagFreeze)
+ return;
- return false;
+ a->stopActorMoving();
+ a->startWalkActor(VAR(6), VAR(7), -1);
}
-bool ScummEngine_v0::verbExec() {
- int prep = 0;
- int entry = (_currentMode != 0 && _currentMode != 1) ? _activeVerb : 15;
-
- if ((!_activeInvExecute && _activeObject && getObjectIndex(_activeObject) == -1)) {
- resetSentence(false);
- return false;
- }
-
- // Lets try walk to the object
- if (_activeObject && _activeObjectIndex && !_activeObjectObtained && _currentMode != 0) {
- prep = verbPrep(_activeObjectIndex);
-
- if (verbObtain(_activeObject, _activeObjectIndex))
+bool ScummEngine_v0::checkSentenceComplete() {
+ if (_activeVerb && _activeVerb != kVerbWalkTo && _activeVerb != kVerbWhatIs) {
+ if (_activeObject && (!activeVerbPrep() || _activeObject2))
return true;
-
- _activeObjectObtained = true;
}
-
- // Attempt to obtain/reach object2
- if (_activeObject2 && _activeObject2Index && !_activeObject2Obtained && _currentMode != 0) {
- prep = verbPrep(_activeObject2Index);
-
- _v0ObjectInInventory = false;
- if (verbObtain(_activeObject2, _activeObject2Index))
- return true;
-
- if (prep != 1 && prep != 4) {
- _activeInventory = _activeObject;
- _activeObject = _activeObject2;
- _activeObjectIndex = _activeObject2Index;
- _activeObject2 = 0;
- _activeObject2Index = 0;
- }
-
- _activeObject2Obtained = true;
- }
-
- // Give-To
- if (_activeVerb == 3 && _activeInventory && _activeActor) {
- // FIXME: Actors need to turn and face each other
- if (verbMoveToActor(_activeActor)) {
- // Ignore verbs?
- Actor *a = derefActor(VAR(VAR_EGO), "verbExec");
- if (((ActorC64 *)a)->_miscflags & 0x40) {
- resetSentence(false);
- return false;
- }
-
- return true;
- }
- _v0ObjectInInventory = true;
- VAR(VAR_ACTIVE_ACTOR) = _activeActor;
- runObject(_activeInventory , 3);
- _v0ObjectInInventory = false;
-
- resetSentence(false);
- return false;
- }
-
- // Where we performing an action on an actor?
- if (_activeActor) {
- _v0ObjectIndex = true;
- runObject(_activeActor, entry);
- _v0ObjectIndex = false;
- _verbExecuting = false;
-
- resetSentence(false);
- return false;
- }
-
- // If we've finished walking (now near target), execute the action
- if (_activeObject && _activeObjectIndex && verbPrep(_activeObjectIndex) == 2) {
- _v0ObjectIndex = true;
- runObject(_activeObjectIndex, entry);
- _v0ObjectIndex = false;
- _verbExecuting = false;
-
- if ((_currentMode == 3 || _currentMode == 2) && _activeVerb == 13)
- return false;
-
- resetSentence(false);
- return false;
- }
-
- // We acted on an inventory item
- if (_activeInventory && verbExecutes(_activeInventory, true) && _activeVerb != 3) {
- _v0ObjectInInventory = true;
- _activeObject = _activeInventory;
- runObject(_activeInventory, _activeVerb);
-
- _verbExecuting = false;
-
- if (_currentMode == 3 && _activeVerb == 13) {
- resetSentence(true);
- return false;
- }
-
- resetSentence(false);
- return false;
- }
-
- // Item not in inventory is executed
- if (_activeObject) {
- _v0ObjectIndex = true;
- runObject(_activeObjectIndex, entry);
- _v0ObjectIndex = false;
- } else if (_activeInventory) {
- // 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)) {
- _v0ObjectInInventory = true;
-
- _activeObject = _activeInventory;
- _activeInventory = _activeObject2;
-
- runObject(_activeObject, _activeVerb);
- } else {
- _v0ObjectInInventory = true;
-
- if (_activeObject2) {
- _activeObject = _activeObject2;
-
- runObject(_activeObject, _activeVerb);
- } else
- runObject(_activeInventory, _activeVerb);
- }
- } else {
- _v0ObjectInInventory = true;
- runObject(_activeInventory, _activeVerb);
- }
- }
-
- _verbExecuting = false;
-
- if (_activeVerb == 13) {
- resetSentence(true);
- return false;
- }
-
- resetSentence(false);
-
return false;
}
void ScummEngine_v0::checkExecVerbs() {
- ActorC64 *a = (ActorC64 *)derefActor(VAR(VAR_EGO), "checkExecVerbs");
+ Actor_v0 *a = (Actor_v0 *)derefActor(VAR(VAR_EGO), "checkExecVerbs");
VirtScreen *zone = findVirtScreen(_mouse.y);
- // Is a verb currently executing
- if (_verbExecuting) {
- // Check if mouse click
- if (_mouseAndKeyboardStat & MBS_MOUSE_MASK) {
- int over = findVerbAtPos(_mouse.x, _mouse.y);
- int act = getActorFromPos(_virtualMouse.x, _virtualMouse.y);
- int obj = findObject(_virtualMouse.x, _virtualMouse.y);
-
- if (over && over != _activeVerb) {
+ bool execute = false;
+
+ if (_mouseAndKeyboardStat & MBS_MOUSE_MASK) {
+ int over = findVerbAtPos(_mouse.x, _mouse.y);
+ // click region: verbs
+ if (over) {
+ if (_activeVerb != over) { // new verb
+ // keep first object if no preposition is used yet
+ if (activeVerbPrep())
+ _activeObject = 0;
+ _activeObject2 = 0;
_activeVerb = over;
- _verbExecuting = false;
- return;
- }
-
- if (!obj && !act && !over) {
- resetSentence(false);
+ _redrawSentenceLine = true;
} else {
- a->stopActorMoving();
+ // execute sentence if complete
+ if (checkSentenceComplete())
+ execute = true;
}
- } else {
-
- if (_verbExecuting && !verbExec())
- return;
}
}
- // What-Is selected, any object we hover over is selected, on mouse press we set to WalkTo
- if (_activeVerb == 15) {
- int obj = findObject(_virtualMouse.x, _virtualMouse.y);
- int objIdx = findObjectIndex(_virtualMouse.x, _virtualMouse.y);
- _activeObject = obj;
- _activeObjectIndex = objIdx;
-
- if ((_mouseAndKeyboardStat & MBS_MOUSE_MASK))
- _activeVerb = 13; // Walk-To
-
- return;
+ if (a->_miscflags & kActorMiscFlagHide) {
+ if (_activeVerb != kVerbNewKid) {
+ _activeVerb = kVerbNone;
+ }
}
- if (_userPut <= 0 || _mouseAndKeyboardStat == 0)
- return;
-
- if (_mouseAndKeyboardStat < MBS_MAX_KEY) {
- /* Check keypresses */
- // TODO
- } else if (_mouseAndKeyboardStat & MBS_MOUSE_MASK) {
- if (zone->number == kVerbVirtScreen && _mouse.y <= zone->topline + 8) {
- // TODO
- } else if (zone->number == kVerbVirtScreen && _mouse.y > zone->topline + 32) {
- int prevInventory = _activeInventory;
- int invOff = _inventoryOffset;
-
- // Click into V2 inventory
- checkV2Inventory(_mouse.x, _mouse.y);
-
- // Did the Inventory position changed (arrows pressed, do nothing)
- if (invOff != _inventoryOffset)
- return;
-
- // No inventory selected?
- if (!_activeInventory)
- return;
+ if (_currentMode != kModeCutscene) {
+ if (_currentMode == kModeKeypad) {
+ _activeVerb = kVerbPush;
+ }
- // Did we just change the selected inventory item?
- if (prevInventory && prevInventory != _activeInventory && _activeInventory != _activeObject2) {
- _v0ObjectInInventory = true;
- int prep = verbPrep(_activeInventory);
- _v0ObjectInInventory = true;
- int prep2 = verbPrep(prevInventory);
-
- // Should the new inventory object remain as the secondary selected object
- // Or should the new inventory object become primary?
- if (prep != prep2 || prep != 1) {
- if (prep == 1 || prep == 3) {
- int tmp = _activeInventory;
- _activeInventory = prevInventory;
- prevInventory = tmp;
+ if (_mouseAndKeyboardStat > 0 && _mouseAndKeyboardStat < MBS_MAX_KEY) {
+ // keys already checked by input handler
+ } else if ((_mouseAndKeyboardStat & MBS_MOUSE_MASK) || _activeVerb == kVerbWhatIs) {
+ // click region: sentence line
+ if (zone->number == kVerbVirtScreen && _mouse.y <= zone->topline + 8) {
+ if (_activeVerb == kVerbNewKid) {
+ if (_currentMode == kModeNormal) {
+ int kid;
+ int lineX = _mouse.x >> V12_X_SHIFT;
+ if (lineX < 11)
+ kid = 0;
+ else if (lineX < 25)
+ kid = 1;
+ else
+ kid = 2;
+ _activeVerb = kVerbWalkTo;
+ _redrawSentenceLine = true;
+ drawSentenceLine();
+ switchActor(kid);
}
- }
-
- // Setup object2
- _activeObject = 0;
- _activeInvExecute = true;
- _activeObject2Inv = true;
- _activeObject2 = _activeInventory;
- _activeInventory = prevInventory;
- return;
- }
-
- // is the new selected inventory the same as the last selected?, reset to previous if it is
- if (_activeInventory == _activeObject2)
- _activeInventory = prevInventory;
-
- // Inventory Selected changed
- if (prevInventory != _activeInventory)
- if (!_activeObject2 || prevInventory != _activeObject2)
- return;
-
- if (_activeVerb == 11 && !(((_activeObject || _activeInventory)) || !_activeObject2))
- return;
- } else {
- int over = findVerbAtPos(_mouse.x, _mouse.y);
- int act = getActorFromPos(_virtualMouse.x, _virtualMouse.y);
- int obj = findObject(_virtualMouse.x, _virtualMouse.y);
- int objIdx = findObjectIndex(_virtualMouse.x, _virtualMouse.y);
-
- // If we already have an object selected, and we just clicked an actor
- // Clear any object we may of also clicked on
- if ((_activeObject || _activeInventory) && act) {
- obj = 0;
- objIdx = 0;
- }
-
- if (a->_miscflags & 0x80) {
- if (_activeVerb != 7 && over != 7) {
- _activeVerb = 0;
- over = 0;
- }
- }
-
- // Handle New Kid verb options
- if (_activeVerb == 7 || over == 7) {
- // Disable New-Kid (in the secret lab)
- if (_currentMode == 2 || _currentMode == 0)
- return;
-
- if (_activeVerb == 7 && over) {
- _activeVerb = 13;
- switchActor(_verbs[over].verbid - 1);
+ _activeVerb = kVerbWalkTo;
+ _redrawSentenceLine = true;
return;
+ } else {
+ // execute sentence if complete
+ if (checkSentenceComplete())
+ execute = true;
}
-
- setNewKidVerbs();
- _activeVerb = 7;
-
- return;
- }
-
- // Clicked on nothing, walk here?
- if (!over && !act && _activeVerb == 13 && !obj && _currentMode != 0) {
- // Clear all selected
- resetSentence(false);
-
- // 0xB31
- VAR(6) = _virtualMouse.x / V12_X_MULTIPLIER;
- VAR(7) = _virtualMouse.y / V12_Y_MULTIPLIER;
-
- if (zone->number == kMainVirtScreen) {
- // Ignore verbs?
- if (a->_miscflags & 0x40) {
- resetSentence(false);
+ // click region: inventory or main screen
+ } else if ((zone->number == kVerbVirtScreen && _mouse.y > zone->topline + 32) ||
+ (zone->number == kMainVirtScreen))
+ {
+ int obj = 0;
+
+ // click region: inventory
+ if (zone->number == kVerbVirtScreen && _mouse.y > zone->topline + 32) {
+ // click into inventory
+ int invOff = _inventoryOffset;
+ obj = checkV2Inventory(_mouse.x, _mouse.y);
+ if (invOff != _inventoryOffset) {
+ // inventory position changed (arrows pressed, do nothing)
return;
}
- a->stopActorMoving();
- a->startWalkActor(VAR(6), VAR(7), -1);
- _verbExecuting = true;
- }
- return;
- }
-
- // No new verb, use previous
- if (over == 0)
- over = _activeVerb;
-
- // No verb selected, use walk-to
- if (!_activeVerb)
- _activeVerb = over = 13; // Walk-To
-
- // New verb selected
- if (_activeVerb != over) {
- _activeVerb = over;
- if (_activeVerb == 13) {
- resetSentence(false);
- }
- return;
- }
-
- // Only allowing targetting actors if its the GIVE/USE verb
- if (_activeVerb == 3 || _activeVerb == 11) {
- // Different actor selected?
- if (act) {
- if (_activeActor != act) {
- _activeActor = act;
- return;
+ // the second object of a give-to command has to be an actor
+ if (_activeVerb == kVerbGive && _activeObject)
+ obj = 0;
+ // click region: main screen
+ } else if (zone->number == kMainVirtScreen) {
+ // click into main screen
+ if (_activeVerb == kVerbGive && _activeObject) {
+ int actor = getActorFromPos(_virtualMouse.x, _virtualMouse.y);
+ if (actor != 0)
+ obj = OBJECT_V0(actor, kObjectV0TypeActor);
+ } else {
+ obj = findObject(_virtualMouse.x, _virtualMouse.y);
}
}
- }
-
- if (obj && obj != _activeObject) {
- if (!_activeObject)
- if (_activeInventory)
- _activeInvExecute = true;
- // USE
- if (_activeVerb == 11 || _activeVerb == 8) {
- if (obj != _activeObject || obj != _activeObject2) {
- if (!_activeObject || _activeInventory) {
+ if (!obj) {
+ if (_activeVerb == kVerbWalkTo) {
+ _activeObject = 0;
+ _activeObject2 = 0;
+ }
+ } else {
+ if (activeVerbPrep() == kVerbPrepNone) {
+ if (obj == _activeObject)
+ execute = true;
+ else
_activeObject = obj;
- _activeObjectIndex = objIdx;
- return;
- } else {
- if (_activeObject2 != obj) {
- _activeObject2 = obj;
- _activeObject2Index = objIdx;
- return;
- }
+ // immediately execute action in keypad/selection mode
+ if (_currentMode == kModeKeypad)
+ execute = true;
+ } else {
+ if (obj == _activeObject2)
+ execute = true;
+ if (obj != _activeObject) {
+ _activeObject2 = obj;
+ if (_currentMode == kModeKeypad)
+ execute = true;
}
}
- } else {
- a->stopActorMoving();
-
- _activeObject = obj;
- _activeObjectIndex = objIdx;
-
- if (_activeVerb != 13)
- return;
+ }
- //return;
+ _redrawSentenceLine = true;
+ if (_activeVerb == kVerbWalkTo && zone->number == kMainVirtScreen) {
+ _walkToObjectState = kWalkToObjectStateDone;
+ execute = true;
}
}
}
+ }
- _verbExecuting = true;
+ if (_redrawSentenceLine)
+ drawSentenceLine();
- } // mouse k/b action
+ if (!execute || !_activeVerb)
+ return;
+
+ if (_activeVerb == kVerbWalkTo)
+ verbExec();
+ else if (_activeObject) {
+ // execute if we have a 1st object and either have or do not need a 2nd
+ if (activeVerbPrep() == kVerbPrepNone || _activeObject2)
+ verbExec();
+ }
}
void ScummEngine::verbMouseOver(int verb) {
// Don't do anything unless verbs are active
- if (_game.version <= 2 && !(_userState & 128))
+ if (_game.version <= 2 && !(_userState & USERSTATE_IFACE_VERBS))
return;
if (_game.id == GID_FT)
diff --git a/engines/scumm/verbs.h b/engines/scumm/verbs.h
index fb4dc969e2..0aa008b4de 100644
--- a/engines/scumm/verbs.h
+++ b/engines/scumm/verbs.h
@@ -57,6 +57,34 @@ struct VerbSlot {
uint16 imgindex;
};
+enum VerbsV0 {
+ kVerbNone = 0,
+ kVerbOpen = 1,
+ kVerbClose = 2,
+ kVerbGive = 3,
+ kVerbTurnOn = 4,
+ kVerbTurnOff = 5,
+ kVerbFix = 6,
+ kVerbNewKid = 7,
+ kVerbUnlock = 8,
+ kVerbPush = 9,
+ kVerbPull = 10,
+ kVerbUse = 11,
+ kVerbRead = 12,
+ kVerbWalkTo = 13,
+ kVerbPickUp = 14,
+ kVerbWhatIs = 15
+};
+
+enum VerbPrepsV0 {
+ kVerbPrepNone = 0,
+ kVerbPrepIn = 1,
+ kVerbPrepWith = 2,
+ kVerbPrepOn = 3,
+ kVerbPrepTo = 4,
+ kVerbPrepObject = 0xFF // prep depends on object (USE)
+};
+
} // End of namespace Scumm
#endif
diff --git a/engines/sky/autoroute.cpp b/engines/sky/autoroute.cpp
index 5273b21807..ab791cb066 100644
--- a/engines/sky/autoroute.cpp
+++ b/engines/sky/autoroute.cpp
@@ -242,7 +242,7 @@ uint16 AutoRoute::autoRoute(Compact *cpt) {
clipCoordX(cpt->arTargetX, destX, initDestX);
clipCoordY(cpt->arTargetY, destY, initDestY);
- uint16 *routeDest = (uint16*)_skyCompact->fetchCpt(cpt->animScratchId);
+ uint16 *routeDest = (uint16 *)_skyCompact->fetchCpt(cpt->animScratchId);
memset(routeDest, 0, 64);
if ((startX == destX) && (startY == destY))
return 2;
diff --git a/engines/sky/compact.cpp b/engines/sky/compact.cpp
index fd81cb9bea..cf9bd55b1a 100644
--- a/engines/sky/compact.cpp
+++ b/engines/sky/compact.cpp
@@ -34,7 +34,7 @@ namespace Sky {
#define SKY_CPT_SIZE 419427
-#define OFFS(type,item) (((ptrdiff_t)(&((type*)42)->item))-42)
+#define OFFS(type,item) (((ptrdiff_t)(&((type *)42)->item))-42)
#define MK32(type,item) OFFS(type, item),0,0,0
#define MK16(type,item) OFFS(type, item),0
#define MK32_A5(type, item) MK32(type, item[0]), MK32(type, item[1]), \
@@ -147,28 +147,28 @@ SkyCompact::SkyCompact() {
_numDataLists = _cptFile->readUint16LE();
_cptNames = (char***)malloc(_numDataLists * sizeof(char**));
_dataListLen = (uint16 *)malloc(_numDataLists * sizeof(uint16));
- _cptSizes = (uint16 **)malloc(_numDataLists * sizeof(uint16*));
- _cptTypes = (uint16 **)malloc(_numDataLists * sizeof(uint16*));
+ _cptSizes = (uint16 **)malloc(_numDataLists * sizeof(uint16 *));
+ _cptTypes = (uint16 **)malloc(_numDataLists * sizeof(uint16 *));
_compacts = (Compact***)malloc(_numDataLists * sizeof(Compact**));
for (int i = 0; i < _numDataLists; i++) {
_dataListLen[i] = _cptFile->readUint16LE();
- _cptNames[i] = (char**)malloc(_dataListLen[i] * sizeof(char*));
+ _cptNames[i] = (char**)malloc(_dataListLen[i] * sizeof(char *));
_cptSizes[i] = (uint16 *)malloc(_dataListLen[i] * sizeof(uint16));
_cptTypes[i] = (uint16 *)malloc(_dataListLen[i] * sizeof(uint16));
- _compacts[i] = (Compact**)malloc(_dataListLen[i] * sizeof(Compact*));
+ _compacts[i] = (Compact**)malloc(_dataListLen[i] * sizeof(Compact *));
}
uint32 rawSize = _cptFile->readUint32LE() * sizeof(uint16);
- uint16 *rawPos = _rawBuf = (uint16*)malloc(rawSize);
+ uint16 *rawPos = _rawBuf = (uint16 *)malloc(rawSize);
uint32 srcSize = _cptFile->readUint32LE() * sizeof(uint16);
- uint16 *srcBuf = (uint16*)malloc(srcSize);
+ uint16 *srcBuf = (uint16 *)malloc(srcSize);
uint16 *srcPos = srcBuf;
_cptFile->read(srcBuf, srcSize);
uint32 asciiSize = _cptFile->readUint32LE();
- char *asciiPos = _asciiBuf = (char*)malloc(asciiSize);
+ char *asciiPos = _asciiBuf = (char *)malloc(asciiSize);
_cptFile->read(_asciiBuf, asciiSize);
// and fill them with the compact data
@@ -177,7 +177,7 @@ SkyCompact::SkyCompact() {
_cptSizes[lcnt][ecnt] = READ_LE_UINT16(srcPos++);
if (_cptSizes[lcnt][ecnt]) {
_cptTypes[lcnt][ecnt] = READ_LE_UINT16(srcPos++);
- _compacts[lcnt][ecnt] = (Compact*)rawPos;
+ _compacts[lcnt][ecnt] = (Compact *)rawPos;
_cptNames[lcnt][ecnt] = asciiPos;
asciiPos += strlen(asciiPos) + 1;
@@ -193,7 +193,7 @@ SkyCompact::SkyCompact() {
free(srcBuf);
uint16 numDlincs = _cptFile->readUint16LE();
- uint16 *dlincBuf = (uint16*)malloc(numDlincs * 2 * sizeof(uint16));
+ uint16 *dlincBuf = (uint16 *)malloc(numDlincs * 2 * sizeof(uint16));
uint16 *dlincPos = dlincBuf;
_cptFile->read(dlincBuf, numDlincs * 2 * sizeof(uint16));
// these compacts don't actually exist but only point to other ones...
@@ -213,13 +213,13 @@ SkyCompact::SkyCompact() {
// if this is v0.0288, parse this diff data
uint16 numDiffs = _cptFile->readUint16LE();
uint16 diffSize = _cptFile->readUint16LE();
- uint16 *diffBuf = (uint16*)malloc(diffSize * sizeof(uint16));
+ uint16 *diffBuf = (uint16 *)malloc(diffSize * sizeof(uint16));
_cptFile->read(diffBuf, diffSize * sizeof(uint16));
if (SkyEngine::_systemVars.gameVersion == 288) {
uint16 *diffPos = diffBuf;
for (cnt = 0; cnt < numDiffs; cnt++) {
uint16 cptId = READ_LE_UINT16(diffPos++);
- uint16 *rawCpt = (uint16*)fetchCpt(cptId);
+ uint16 *rawCpt = (uint16 *)fetchCpt(cptId);
rawCpt += READ_LE_UINT16(diffPos++);
uint16 len = READ_LE_UINT16(diffPos++);
for (uint16 elemCnt = 0; elemCnt < len; elemCnt++)
@@ -231,7 +231,7 @@ SkyCompact::SkyCompact() {
// these are the IDs that have to be saved into savegame files.
_numSaveIds = _cptFile->readUint16LE();
- _saveIds = (uint16*)malloc(_numSaveIds * sizeof(uint16));
+ _saveIds = (uint16 *)malloc(_numSaveIds * sizeof(uint16));
_cptFile->read(_saveIds, _numSaveIds * sizeof(uint16));
for (cnt = 0; cnt < _numSaveIds; cnt++)
_saveIds[cnt] = FROM_LE_16(_saveIds[cnt]);
@@ -318,7 +318,7 @@ uint16 *SkyCompact::getSub(Compact *cpt, uint16 mode) {
}
uint16 *SkyCompact::getGrafixPtr(Compact *cpt) {
- uint16 *gfxBase = (uint16*)fetchCpt(cpt->grafixProgId);
+ uint16 *gfxBase = (uint16 *)fetchCpt(cpt->grafixProgId);
if (gfxBase == NULL)
return NULL;
@@ -358,7 +358,7 @@ MegaSet *SkyCompact::getMegaSet(Compact *cpt) {
*/
uint16 *SkyCompact::getTurnTable(Compact *cpt, uint16 dir) {
MegaSet *m = getMegaSet(cpt);
- TurnTable *turnTable = (TurnTable*)fetchCpt(m->turnTableId);
+ TurnTable *turnTable = (TurnTable *)fetchCpt(m->turnTableId);
switch (dir) {
case 0:
return turnTable->turnTableUp;
@@ -418,7 +418,7 @@ void *SkyCompact::getCompactElem(Compact *cpt, uint16 off) {
uint8 *SkyCompact::createResetData(uint16 gameVersion) {
_cptFile->seek(_resetDataPos);
uint32 dataSize = _cptFile->readUint16LE() * sizeof(uint16);
- uint16 *resetBuf = (uint16*)malloc(dataSize);
+ uint16 *resetBuf = (uint16 *)malloc(dataSize);
_cptFile->read(resetBuf, dataSize);
uint16 numDiffs = _cptFile->readUint16LE();
for (uint16 cnt = 0; cnt < numDiffs; cnt++) {
@@ -429,7 +429,7 @@ uint8 *SkyCompact::createResetData(uint16 gameVersion) {
uint16 pos = _cptFile->readUint16LE();
resetBuf[pos] = TO_LE_16(_cptFile->readUint16LE());
}
- return (uint8*)resetBuf;
+ return (uint8 *)resetBuf;
} else
_cptFile->seek(diffFields * 2 * sizeof(uint16), SEEK_CUR);
}
diff --git a/engines/sky/control.cpp b/engines/sky/control.cpp
index 9efa6ce769..c1ed763281 100644
--- a/engines/sky/control.cpp
+++ b/engines/sky/control.cpp
@@ -535,7 +535,7 @@ uint16 Control::handleClick(ConResource *pButton) {
return saveRestorePanel(true); // texts can be edited
case SAVE_A_GAME:
animClick(pButton);
- return saveGameToFile();
+ return saveGameToFile(true);
case RESTORE_A_GAME:
animClick(pButton);
return restoreGameFromFile(false);
@@ -878,6 +878,8 @@ uint16 Control::saveRestorePanel(bool allowSave) {
clickRes = handleClick(lookList[0]);
if (clickRes == GAME_SAVED)
saveDescriptions(saveGameTexts);
+ else if (clickRes == NO_DISK_SPACE)
+ displayMessage(0, "Could not save the game. (%s)", _saveFileMan->popErrorDesc().c_str());
quitPanel = true;
_mouseClicked = false;
_keyPressed.reset();
@@ -972,7 +974,7 @@ void Control::handleKeyPress(Common::KeyState kbd, Common::String &textBuf) {
// Allow the key only if is a letter, a digit, or one of a selected
// list of extra characters
- if (isalnum(kbd.ascii) || strchr(" ,().='-&+!?\"", kbd.ascii) != 0) {
+ if (Common::isAlnum(kbd.ascii) || strchr(" ,().='-&+!?\"", kbd.ascii) != 0) {
textBuf += kbd.ascii;
}
}
@@ -1092,35 +1094,33 @@ void Control::doAutoSave() {
strcpy(fName, "SKY-VM-CD.ASD");
else
sprintf(fName, "SKY-VM%03d.ASD", SkyEngine::_systemVars.gameVersion);
- Common::OutSaveFile *outf;
- outf = _saveFileMan->openForSaving(fName);
- if (outf == NULL) {
- displayMessage(0, "Unable to create autosave file '%s'. (%s)", fName, _saveFileMan->popErrorDesc().c_str());
- return;
- }
- uint8 *saveData = (uint8 *)malloc(0x20000);
- uint32 fSize = prepareSaveData(saveData);
-
- outf->write(saveData, fSize);
- outf->finalize();
+ uint16 res = saveGameToFile(false, fName);
- if (outf->err())
- displayMessage(0, "Unable to write autosave file '%s'. Disk full? (%s)", fName, _saveFileMan->popErrorDesc().c_str());
+ if (res != GAME_SAVED)
+ displayMessage(0, "Unable to perform autosave to '%s'. (%s)", fName, _saveFileMan->popErrorDesc().c_str());
- delete outf;
- free(saveData);
}
-uint16 Control::saveGameToFile() {
+uint16 Control::saveGameToFile(bool fromControlPanel, const char *filename) {
char fName[20];
- sprintf(fName,"SKY-VM.%03d", _selectedGame);
+ if (!filename) {
+ sprintf(fName,"SKY-VM.%03d", _selectedGame);
+ filename = fName;
+ }
Common::OutSaveFile *outf;
- outf = _saveFileMan->openForSaving(fName);
+ outf = _saveFileMan->openForSaving(filename);
if (outf == NULL)
return NO_DISK_SPACE;
+ if (!fromControlPanel) {
+ // These variables are usually set when entering the control panel,
+ // but not when using the GMM.
+ _savedCharSet = _skyText->giveCurrentCharSet();
+ _savedMouse = _skyMouse->giveCurrentMouseType();
+ }
+
uint8 *saveData = (uint8 *)malloc(0x20000);
uint32 fSize = prepareSaveData(saveData);
@@ -1160,7 +1160,7 @@ uint32 Control::prepareSaveData(uint8 *destBuf) {
for (cnt = 0; cnt < _skyCompact->_numSaveIds; cnt++) {
uint16 numElems;
- uint16 *rawCpt = (uint16*)_skyCompact->fetchCptInfo(_skyCompact->_saveIds[cnt], &numElems, NULL, NULL);
+ uint16 *rawCpt = (uint16 *)_skyCompact->fetchCptInfo(_skyCompact->_saveIds[cnt], &numElems, NULL, NULL);
for (uint16 elemCnt = 0; elemCnt < numElems; elemCnt++)
STOSW(destPos, rawCpt[elemCnt]);
}
@@ -1209,9 +1209,9 @@ void Control::importOldCompact(Compact* destCpt, uint8 **srcPos, uint16 numElems
else if (graphType == OG_COMPACT)
destCpt->grafixProgId = target;
else if (graphType == OG_TALKTABLE)
- destCpt->grafixProgId = ((uint16*)_skyCompact->fetchCpt(CPT_TALK_TABLE_LIST))[target];
+ destCpt->grafixProgId = ((uint16 *)_skyCompact->fetchCpt(CPT_TALK_TABLE_LIST))[target];
else if (graphType == OG_COMPACTELEM)
- destCpt->grafixProgId = *(uint16*)_skyCompact->getCompactElem(destCpt, target);
+ destCpt->grafixProgId = *(uint16 *)_skyCompact->getCompactElem(destCpt, target);
else
error("Illegal GrafixProg type encountered for compact %s", name);
}
@@ -1330,7 +1330,7 @@ uint16 Control::parseSaveData(uint8 *srcBuf) {
LODSD(srcPos, mouseType);
LODSD(srcPos, palette);
- _skyLogic->parseSaveData((uint32*)srcPos);
+ _skyLogic->parseSaveData((uint32 *)srcPos);
srcPos += NUM_SKY_SCRIPTVARS * sizeof(uint32);
for (cnt = 0; cnt < 60; cnt++)
@@ -1339,7 +1339,7 @@ uint16 Control::parseSaveData(uint8 *srcBuf) {
if (saveRev == SAVE_FILE_REVISION) {
for (cnt = 0; cnt < _skyCompact->_numSaveIds; cnt++) {
uint16 numElems;
- uint16 *rawCpt = (uint16*)_skyCompact->fetchCptInfo(_skyCompact->_saveIds[cnt], &numElems, NULL, NULL);
+ uint16 *rawCpt = (uint16 *)_skyCompact->fetchCptInfo(_skyCompact->_saveIds[cnt], &numElems, NULL, NULL);
for (uint16 elemCnt = 0; elemCnt < numElems; elemCnt++)
LODSW(srcPos, rawCpt[elemCnt]);
}
@@ -1348,19 +1348,19 @@ uint16 Control::parseSaveData(uint8 *srcBuf) {
uint16 numElems;
uint16 type;
char name[128];
- uint16 *rawCpt = (uint16*)_skyCompact->fetchCptInfo(_skyCompact->_saveIds[cnt], &numElems, &type, name);
+ uint16 *rawCpt = (uint16 *)_skyCompact->fetchCptInfo(_skyCompact->_saveIds[cnt], &numElems, &type, name);
if (type == COMPACT) {
- importOldCompact((Compact*)rawCpt, &srcPos, numElems, type, name);
+ importOldCompact((Compact *)rawCpt, &srcPos, numElems, type, name);
} else if (type == ROUTEBUF) {
assert(numElems == 32);
for (uint32 elemCnt = 0; elemCnt < numElems; elemCnt++)
LODSW(srcPos, rawCpt[elemCnt]);
}
}
- uint16 *rawCpt = (uint16*)_skyCompact->fetchCpt(0xBF);
+ uint16 *rawCpt = (uint16 *)_skyCompact->fetchCpt(0xBF);
for (cnt = 0; cnt < 3; cnt++)
LODSW(srcPos, rawCpt[cnt]);
- rawCpt = (uint16*)_skyCompact->fetchCpt(0xC2);
+ rawCpt = (uint16 *)_skyCompact->fetchCpt(0xC2);
for (cnt = 0; cnt < 13; cnt++)
LODSW(srcPos, rawCpt[cnt]);
}
@@ -1467,7 +1467,7 @@ void Control::restartGame() {
return; // no restart for floppy demo
uint8 *resetData = _skyCompact->createResetData((uint16)SkyEngine::_systemVars.gameVersion);
- parseSaveData((uint8*)resetData);
+ parseSaveData((uint8 *)resetData);
free(resetData);
_skyScreen->forceRefresh();
diff --git a/engines/sky/control.h b/engines/sky/control.h
index 6aa7a41c62..280f7e19cd 100644
--- a/engines/sky/control.h
+++ b/engines/sky/control.h
@@ -136,7 +136,7 @@ class ConResource {
public:
ConResource(void *pSpData, uint32 pNSprites, uint32 pCurSprite, uint16 pX, uint16 pY, uint32 pText, uint8 pOnClick, OSystem *system, uint8 *screen);
virtual ~ConResource() {}
- void setSprite(void *pSpData) { _spriteData = (DataFileHeader*)pSpData; }
+ void setSprite(void *pSpData) { _spriteData = (DataFileHeader *)pSpData; }
void setText(uint32 pText) { if (pText) _text = pText + 0x7000; else _text = 0; }
void setXY(uint16 x, uint16 y) { _x = x; _y = y; }
bool isMouseOver(uint32 mouseX, uint32 mouseY);
@@ -190,7 +190,7 @@ public:
bool loadSaveAllowed();
uint16 _selectedGame;
- uint16 saveGameToFile();
+ uint16 saveGameToFile(bool fromControlPanel, const char *filename = 0);
void loadDescriptions(Common::StringArray &list);
void saveDescriptions(const Common::StringArray &list);
diff --git a/engines/sky/detection.cpp b/engines/sky/detection.cpp
index 2699500527..2b702e99ea 100644
--- a/engines/sky/detection.cpp
+++ b/engines/sky/detection.cpp
@@ -55,9 +55,9 @@ static const SkyVersion skyVersions[] = {
{ 1413, -1, "floppy", 303, GUIO1(GUIO_NOSPEECH) },
{ 1445, 8830435, "floppy", 348, GUIO1(GUIO_NOSPEECH) },
{ 1445, -1, "floppy", 331, GUIO1(GUIO_NOSPEECH) },
- { 1711, -1, "cd demo", 365, GUIO1(GUIO_NONE) },
- { 5099, -1, "cd", 368, GUIO1(GUIO_NONE) },
- { 5097, -1, "cd", 372, GUIO1(GUIO_NONE) },
+ { 1711, -1, "cd demo", 365, GUIO0() },
+ { 5099, -1, "cd", 368, GUIO0() },
+ { 5097, -1, "cd", 372, GUIO0() },
{ 0, 0, 0, 0, 0 }
};
@@ -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(static_cast<unsigned char>(ext[0])) && isdigit(static_cast<unsigned char>(ext[1])) && isdigit(static_cast<unsigned char>(ext[2]))){
+ if (Common::isDigit(ext[0]) && Common::isDigit(ext[1]) && Common::isDigit(ext[2])) {
int slotNum = atoi(ext.c_str());
Common::InSaveFile *in = saveFileMan->openForLoading(*file);
if (in) {
@@ -286,7 +286,7 @@ Common::Error SkyEngine::saveGameState(int slot, const Common::String &desc) {
// Set the save slot and save the game
_skyControl->_selectedGame = slot - 1;
- if (_skyControl->saveGameToFile() != GAME_SAVED)
+ if (_skyControl->saveGameToFile(false) != GAME_SAVED)
return Common::kWritePermissionDenied;
// Load current save game descriptions
diff --git a/engines/sky/disk.cpp b/engines/sky/disk.cpp
index 99b707dcf1..e97aeb01a2 100644
--- a/engines/sky/disk.cpp
+++ b/engines/sky/disk.cpp
@@ -117,7 +117,7 @@ uint8 *Disk::loadFile(uint16 fileNr) {
cflag = (uint8)((fileFlags >> 23) & 0x1);
//if cflag == 0 then file is compressed, 1 == uncompressed
- DataFileHeader *fileHeader = (DataFileHeader*)fileDest;
+ DataFileHeader *fileHeader = (DataFileHeader *)fileDest;
if ((!cflag) && ((FROM_LE_16(fileHeader->flag) >> 7) & 1)) {
debug(4, "File is RNC compressed.");
@@ -175,7 +175,7 @@ uint8 *Disk::loadFile(uint16 fileNr) {
}
uint16 *Disk::loadScriptFile(uint16 fileNr) {
- uint16 *buf = (uint16*)loadFile(fileNr);
+ uint16 *buf = (uint16 *)loadFile(fileNr);
#ifdef SCUMM_BIG_ENDIAN
for (uint i = 0; i < _lastLoadedFileSize / 2; i++)
buf[i] = FROM_LE_16(buf[i]);
diff --git a/engines/sky/intro.cpp b/engines/sky/intro.cpp
index f1ea4d2df2..2f75a19b69 100644
--- a/engines/sky/intro.cpp
+++ b/engines/sky/intro.cpp
@@ -633,8 +633,8 @@ Intro::Intro(Disk *disk, Screen *screen, MusicBase *music, Sound *sound, Text *t
_skyText = text;
_mixer = mixer;
_system = system;
- _textBuf = (uint8*)malloc(10000);
- _saveBuf = (uint8*)malloc(10000);
+ _textBuf = (uint8 *)malloc(10000);
+ _saveBuf = (uint8 *)malloc(10000);
_bgBuf = NULL;
_relDelay = 0;
}
@@ -774,7 +774,7 @@ bool Intro::nextPart(uint16 *&data) {
}
bool Intro::floppyScrollFlirt() {
- uint8 *scrollScreen = (uint8*)malloc(FRAME_SIZE * 2);
+ uint8 *scrollScreen = (uint8 *)malloc(FRAME_SIZE * 2);
memset(scrollScreen, 0, FRAME_SIZE);
memcpy(scrollScreen + FRAME_SIZE, _skyScreen->giveCurrent(), FRAME_SIZE);
uint8 *scrollPos = scrollScreen + FRAME_SIZE;
@@ -828,8 +828,8 @@ bool Intro::commandFlirt(uint16 *&data) {
_skyText->displayText(*data++, _textBuf, true, INTRO_TEXT_WIDTH, 255);
break;
case IC_SHOW_TEXT:
- ((DataFileHeader*)_textBuf)->s_x = *data++;
- ((DataFileHeader*)_textBuf)->s_y = *data++;
+ ((DataFileHeader *)_textBuf)->s_x = *data++;
+ ((DataFileHeader *)_textBuf)->s_y = *data++;
showTextBuf();
break;
case IC_REMOVE_TEXT:
@@ -858,10 +858,10 @@ bool Intro::commandFlirt(uint16 *&data) {
}
void Intro::showTextBuf() {
- uint16 x = ((DataFileHeader*)_textBuf)->s_x;
- uint16 y = ((DataFileHeader*)_textBuf)->s_y;
- uint16 width = ((DataFileHeader*)_textBuf)->s_width;
- uint16 height = ((DataFileHeader*)_textBuf)->s_height;
+ uint16 x = ((DataFileHeader *)_textBuf)->s_x;
+ uint16 y = ((DataFileHeader *)_textBuf)->s_y;
+ uint16 width = ((DataFileHeader *)_textBuf)->s_width;
+ uint16 height = ((DataFileHeader *)_textBuf)->s_height;
uint8 *screenBuf = _skyScreen->giveCurrent() + y * GAME_SCREEN_WIDTH + x;
memcpy(_saveBuf, _textBuf, sizeof(DataFileHeader));
uint8 *saveBuf = _saveBuf + sizeof(DataFileHeader);
@@ -880,10 +880,10 @@ void Intro::showTextBuf() {
}
void Intro::restoreScreen() {
- uint16 x = ((DataFileHeader*)_saveBuf)->s_x;
- uint16 y = ((DataFileHeader*)_saveBuf)->s_y;
- uint16 width = ((DataFileHeader*)_saveBuf)->s_width;
- uint16 height = ((DataFileHeader*)_saveBuf)->s_height;
+ uint16 x = ((DataFileHeader *)_saveBuf)->s_x;
+ uint16 y = ((DataFileHeader *)_saveBuf)->s_y;
+ uint16 width = ((DataFileHeader *)_saveBuf)->s_width;
+ uint16 height = ((DataFileHeader *)_saveBuf)->s_height;
uint8 *screenBuf = _skyScreen->giveCurrent() + y * GAME_SCREEN_WIDTH + x;
uint8 *saveBuf = _saveBuf + sizeof(DataFileHeader);
for (uint16 cnt = 0; cnt < height; cnt++) {
diff --git a/engines/sky/logic.cpp b/engines/sky/logic.cpp
index a69ba793f2..e92e768272 100644
--- a/engines/sky/logic.cpp
+++ b/engines/sky/logic.cpp
@@ -382,8 +382,8 @@ void Logic::mainAnim() {
}
};
- uint16 animId = *(uint16*)_skyCompact->getCompactElem(_compact, C_ANIM_UP + _compact->megaSet + dir * 4);
- uint16 *animList = (uint16*)_skyCompact->fetchCpt(animId);
+ uint16 animId = *(uint16 *)_skyCompact->getCompactElem(_compact, C_ANIM_UP + _compact->megaSet + dir * 4);
+ uint16 *animList = (uint16 *)_skyCompact->fetchCpt(animId);
uint16 arAnimIndex = _compact->arAnimIndex;
if (!animList[arAnimIndex / 2]) {
@@ -400,7 +400,7 @@ void Logic::mainAnim() {
}
void Logic::arTurn() {
- uint16 *turnData = (uint16*)_skyCompact->fetchCpt(_compact->turnProgId) + _compact->turnProgPos;
+ uint16 *turnData = (uint16 *)_skyCompact->fetchCpt(_compact->turnProgId) + _compact->turnProgPos;
_compact->frame = *turnData++;
_compact->turnProgPos++;
@@ -453,7 +453,7 @@ void Logic::anim() {
}
void Logic::turn() {
- uint16 *turnData = (uint16*)_skyCompact->fetchCpt(_compact->turnProgId) + _compact->turnProgPos;
+ uint16 *turnData = (uint16 *)_skyCompact->fetchCpt(_compact->turnProgId) + _compact->turnProgPos;
if (*turnData) {
_compact->frame = *turnData;
_compact->turnProgPos++;
@@ -1232,201 +1232,205 @@ uint16 Logic::mouseScript(uint32 scrNum, Compact *scriptComp) {
* @return 0 if script finished. Else offset where to continue.
*/
uint16 Logic::script(uint16 scriptNo, uint16 offset) {
-script:
- /// process a script
- /// low level interface to interpreter
+ do {
+ bool restartScript = false;
- uint16 moduleNo = scriptNo >> 12;
- uint16 *scriptData = _moduleList[moduleNo]; // get module address
+ /// process a script
+ /// low level interface to interpreter
- if (!scriptData) { // We need to load the script module
- _moduleList[moduleNo] = _skyDisk->loadScriptFile(moduleNo + F_MODULE_0);
- scriptData = _moduleList[moduleNo]; // module has been loaded
- }
+ uint16 moduleNo = scriptNo >> 12;
+ uint16 *scriptData = _moduleList[moduleNo]; // get module address
- uint16 *moduleStart = scriptData;
+ if (!scriptData) { // We need to load the script module
+ _moduleList[moduleNo] = _skyDisk->loadScriptFile(moduleNo + F_MODULE_0);
+ scriptData = _moduleList[moduleNo]; // module has been loaded
+ }
- debug(3, "Doing Script: %d:%d:%x", moduleNo, scriptNo & 0xFFF, offset ? (offset - moduleStart[scriptNo & 0xFFF]) : 0);
+ uint16 *moduleStart = scriptData;
- // WORKAROUND for bug #3149412: "Invalid Mode when giving shades to travel agent"
- // Using the dark glasses on Trevor (travel agent) multiple times in succession would
- // wreck the trevor compact's mode, as the script in question doesn't account for using
- // this item at this point in the game (you will only have it here if you play the game
- // in an unusual way) and thus would loop indefinitely / never drop out.
- // To prevent this, we trigger the generic response by pretending we're using an item
- // which the script /does/ handle.
- if (scriptNo == TREVOR_SPEECH && _scriptVariables[OBJECT_HELD] == IDO_SHADES)
- _scriptVariables[OBJECT_HELD] = IDO_GLASS;
+ debug(3, "Doing Script: %d:%d:%x", moduleNo, scriptNo & 0xFFF, offset ? (offset - moduleStart[scriptNo & 0xFFF]) : 0);
+ // WORKAROUND for bug #3149412: "Invalid Mode when giving shades to travel agent"
+ // Using the dark glasses on Trevor (travel agent) multiple times in succession would
+ // wreck the trevor compact's mode, as the script in question doesn't account for using
+ // this item at this point in the game (you will only have it here if you play the game
+ // in an unusual way) and thus would loop indefinitely / never drop out.
+ // To prevent this, we trigger the generic response by pretending we're using an item
+ // which the script /does/ handle.
+ if (scriptNo == TREVOR_SPEECH && _scriptVariables[OBJECT_HELD] == IDO_SHADES)
+ _scriptVariables[OBJECT_HELD] = IDO_GLASS;
- // Check whether we have an offset or what
- if (offset)
- scriptData = moduleStart + offset;
- else
- scriptData += scriptData[scriptNo & 0x0FFF];
- uint32 a = 0, b = 0, c = 0;
- uint16 command, s;
-
- for (;;) {
- command = *scriptData++; // get a command
- Debug::script(command, scriptData);
-
- switch (command) {
- case 0: // push_variable
- push( _scriptVariables[*scriptData++ / 4] );
- break;
- case 1: // less_than
- a = pop();
- b = pop();
- if (a > b)
- push(1);
- else
- push(0);
- break;
- case 2: // push_number
- push(*scriptData++);
- break;
- case 3: // not_equal
- a = pop();
- b = pop();
- if (a != b)
- push(1);
- else
- push(0);
- break;
- case 4: // if_and
- a = pop();
- b = pop();
- if (a && b)
- push(1);
- else
- push(0);
- break;
- case 5: // skip_zero
- s = *scriptData++;
-
- a = pop();
- if (!a)
- scriptData += s / 2;
- break;
- case 6: // pop_var
- b = _scriptVariables[*scriptData++ / 4] = pop();
- break;
- case 7: // minus
- a = pop();
- b = pop();
- push(b-a);
- break;
- case 8: // plus
- a = pop();
- b = pop();
- push(b+a);
- break;
- case 9: // skip_always
- s = *scriptData++;
- scriptData += s / 2;
- break;
- case 10: // if_or
- a = pop();
- b = pop();
- if (a || b)
- push(1);
- else
- push(0);
- break;
- case 11: // call_mcode
- {
- a = *scriptData++;
- assert(a <= 3);
- // No, I did not forget the "break"s
- switch (a) {
- case 3:
- c = pop();
- case 2:
- b = pop();
- case 1:
- a = pop();
- }
-
- uint16 mcode = *scriptData++ / 4; // get mcode number
- Debug::mcode(mcode, a, b, c);
+ // Check whether we have an offset or what
+ if (offset)
+ scriptData = moduleStart + offset;
+ else
+ scriptData += scriptData[scriptNo & 0x0FFF];
- Compact *saveCpt = _compact;
- bool ret = (this->*_mcodeTable[mcode]) (a, b, c);
- _compact = saveCpt;
+ uint32 a = 0, b = 0, c = 0;
+ uint16 command, s;
- if (!ret)
- return (scriptData - moduleStart);
- }
- break;
- case 12: // more_than
- a = pop();
- b = pop();
- if (a < b)
- push(1);
- else
- push(0);
- break;
- case 14: // switch
- c = s = *scriptData++; // get number of cases
+ while(!restartScript) {
+ command = *scriptData++; // get a command
+ Debug::script(command, scriptData);
- a = pop(); // and value to switch on
+ switch (command) {
+ case 0: // push_variable
+ push( _scriptVariables[*scriptData++ / 4] );
+ break;
+ case 1: // less_than
+ a = pop();
+ b = pop();
+ if (a > b)
+ push(1);
+ else
+ push(0);
+ break;
+ case 2: // push_number
+ push(*scriptData++);
+ break;
+ case 3: // not_equal
+ a = pop();
+ b = pop();
+ if (a != b)
+ push(1);
+ else
+ push(0);
+ break;
+ case 4: // if_and
+ a = pop();
+ b = pop();
+ if (a && b)
+ push(1);
+ else
+ push(0);
+ break;
+ case 5: // skip_zero
+ s = *scriptData++;
- do {
- if (a == *scriptData) {
- scriptData += scriptData[1] / 2;
- scriptData++;
- break;
+ a = pop();
+ if (!a)
+ scriptData += s / 2;
+ break;
+ case 6: // pop_var
+ b = _scriptVariables[*scriptData++ / 4] = pop();
+ break;
+ case 7: // minus
+ a = pop();
+ b = pop();
+ push(b-a);
+ break;
+ case 8: // plus
+ a = pop();
+ b = pop();
+ push(b+a);
+ break;
+ case 9: // skip_always
+ s = *scriptData++;
+ scriptData += s / 2;
+ break;
+ case 10: // if_or
+ a = pop();
+ b = pop();
+ if (a || b)
+ push(1);
+ else
+ push(0);
+ break;
+ case 11: // call_mcode
+ {
+ a = *scriptData++;
+ assert(a <= 3);
+ // No, I did not forget the "break"s
+ switch (a) {
+ case 3:
+ c = pop();
+ case 2:
+ b = pop();
+ case 1:
+ a = pop();
+ }
+
+ uint16 mcode = *scriptData++ / 4; // get mcode number
+ Debug::mcode(mcode, a, b, c);
+
+ Compact *saveCpt = _compact;
+ bool ret = (this->*_mcodeTable[mcode]) (a, b, c);
+ _compact = saveCpt;
+
+ if (!ret)
+ return (scriptData - moduleStart);
}
- scriptData += 2;
- } while (--s);
-
- if (s == 0)
- scriptData += *scriptData / 2; // use the default
- break;
- case 15: // push_offset
- push( *(uint16 *)_skyCompact->getCompactElem(_compact, *scriptData++) );
- break;
- case 16: // pop_offset
- // pop a value into a compact
- *(uint16 *)_skyCompact->getCompactElem(_compact, *scriptData++) = (uint16)pop();
- break;
- case 17: // is_equal
- a = pop();
- b = pop();
- if (a == b)
- push(1);
- else
- push(0);
- break;
- case 18: { // skip_nz
- int16 t = *scriptData++;
+ break;
+ case 12: // more_than
+ a = pop();
+ b = pop();
+ if (a < b)
+ push(1);
+ else
+ push(0);
+ break;
+ case 14: // switch
+ c = s = *scriptData++; // get number of cases
+
+ a = pop(); // and value to switch on
+
+ do {
+ if (a == *scriptData) {
+ scriptData += scriptData[1] / 2;
+ scriptData++;
+ break;
+ }
+ scriptData += 2;
+ } while (--s);
+
+ if (s == 0)
+ scriptData += *scriptData / 2; // use the default
+ break;
+ case 15: // push_offset
+ push( *(uint16 *)_skyCompact->getCompactElem(_compact, *scriptData++) );
+ break;
+ case 16: // pop_offset
+ // pop a value into a compact
+ *(uint16 *)_skyCompact->getCompactElem(_compact, *scriptData++) = (uint16)pop();
+ break;
+ case 17: // is_equal
a = pop();
- if (a)
- scriptData += t / 2;
+ b = pop();
+ if (a == b)
+ push(1);
+ else
+ push(0);
+ break;
+ case 18: { // skip_nz
+ int16 t = *scriptData++;
+ a = pop();
+ if (a)
+ scriptData += t / 2;
+ break;
+ }
+ case 13:
+ case 19: // script_exit
+ return 0;
+ case 20: // restart_script
+ offset = 0;
+ restartScript = true;
break;
+ default:
+ error("Unknown script command: %d", command);
}
- case 13:
- case 19: // script_exit
- return 0;
- case 20: // restart_script
- offset = 0;
- goto script;
- default:
- error("Unknown script command: %d", command);
}
- }
+ } while (true);
}
bool Logic::fnCacheChip(uint32 a, uint32 b, uint32 c) {
_skySound->fnStopFx();
- _skyDisk->fnCacheChip((uint16*)_skyCompact->fetchCpt((uint16)a));
+ _skyDisk->fnCacheChip((uint16 *)_skyCompact->fetchCpt((uint16)a));
return true;
}
bool Logic::fnCacheFast(uint32 a, uint32 b, uint32 c) {
- _skyDisk->fnCacheFast((uint16*)_skyCompact->fetchCpt((uint16)a));
+ _skyDisk->fnCacheFast((uint16 *)_skyCompact->fetchCpt((uint16)a));
return true;
}
@@ -1573,7 +1577,7 @@ bool Logic::fnGetTo(uint32 targetPlaceId, uint32 mode, uint32 c) {
warning("can't find _compact's getToTable. Place compact is NULL");
return false;
}
- uint16 *getToTable = (uint16*)_skyCompact->fetchCpt(cpt->getToTableId);
+ uint16 *getToTable = (uint16 *)_skyCompact->fetchCpt(cpt->getToTableId);
if (!getToTable) {
warning("Place compact's getToTable is NULL");
return false;
@@ -1592,7 +1596,7 @@ bool Logic::fnGetTo(uint32 targetPlaceId, uint32 mode, uint32 c) {
bool Logic::fnSetToStand(uint32 a, uint32 b, uint32 c) {
_compact->mood = 1; // high level stood still
- _compact->grafixProgId = *(uint16*)_skyCompact->getCompactElem(_compact, C_STAND_UP + _compact->megaSet + _compact->dir * 4);
+ _compact->grafixProgId = *(uint16 *)_skyCompact->getCompactElem(_compact, C_STAND_UP + _compact->megaSet + _compact->dir * 4);
_compact->grafixProgPos = 0;
uint16 *standList = _skyCompact->getGrafixPtr(_compact);
@@ -2154,8 +2158,8 @@ bool Logic::fnSetMegaSet(uint32 mega, uint32 setNo, uint32 c) {
bool Logic::fnMoveItems(uint32 listNo, uint32 screenNo, uint32 c) {
// Move a list of id's to another screen
- uint16 *p = (uint16*)_skyCompact->fetchCpt(CPT_MOVE_LIST);
- p = (uint16*)_skyCompact->fetchCpt(p[listNo]);
+ uint16 *p = (uint16 *)_skyCompact->fetchCpt(CPT_MOVE_LIST);
+ p = (uint16 *)_skyCompact->fetchCpt(p[listNo]);
for (int i = 0; i < 2; i++) {
if (!*p)
return true;
@@ -2524,7 +2528,7 @@ void Logic::stdSpeak(Compact *target, uint32 textNum, uint32 animNum, uint32 bas
animNum += target->megaSet / NEXT_MEGA_SET;
animNum &= 0xFF;
- uint16 *talkTable = (uint16*)_skyCompact->fetchCpt(CPT_TALK_TABLE_LIST);
+ uint16 *talkTable = (uint16 *)_skyCompact->fetchCpt(CPT_TALK_TABLE_LIST);
target->grafixProgId = talkTable[animNum];
target->grafixProgPos = 0;
uint16 *animPtr = _skyCompact->getGrafixPtr(target);
diff --git a/engines/sky/mouse.cpp b/engines/sky/mouse.cpp
index 98f942889e..74a92c8f00 100644
--- a/engines/sky/mouse.cpp
+++ b/engines/sky/mouse.cpp
@@ -319,7 +319,7 @@ void Mouse::fnOpenCloseHand(bool open) {
if (open)
cursor++;
- uint32 size = ((DataFileHeader*)_objectMouseData)->s_sp_size;
+ uint32 size = ((DataFileHeader *)_objectMouseData)->s_sp_size;
uint8 *srcData;
uint8 *destData;
diff --git a/engines/sky/music/adlibchannel.cpp b/engines/sky/music/adlibchannel.cpp
index 896b58aa22..99509554c7 100644
--- a/engines/sky/music/adlibchannel.cpp
+++ b/engines/sky/music/adlibchannel.cpp
@@ -49,32 +49,32 @@ AdLibChannel::AdLibChannel(FM_OPL *opl, uint8 *pMusicData, uint16 startOfData) {
if (SkyEngine::_systemVars.gameVersion == 109) {
//instrumentDataLoc = (_musicData[0x11D0] << 8) | _musicData[0x11CF];
- //_frequenceTable = (uint16*)(_musicData + 0x835);
+ //_frequenceTable = (uint16 *)(_musicData + 0x835);
//_registerTable = _musicData + 0xE35;
//_opOutputTable = _musicData + 0xE47;
//_adlibRegMirror = _musicData + 0xF4A;
instrumentDataLoc = READ_LE_UINT16(_musicData + 0x1204);
- _frequenceTable = (uint16*)(_musicData + 0x868);
+ _frequenceTable = (uint16 *)(_musicData + 0x868);
_registerTable = _musicData + 0xE68;
_opOutputTable = _musicData + 0xE7A;
_adlibRegMirror = _musicData + 0xF7D;
} else if (SkyEngine::_systemVars.gameVersion == 267) {
instrumentDataLoc = READ_LE_UINT16(_musicData + 0x11FB);
- _frequenceTable = (uint16*)(_musicData + 0x7F4);
+ _frequenceTable = (uint16 *)(_musicData + 0x7F4);
_registerTable = _musicData + 0xDF4;
_opOutputTable = _musicData + 0xE06;
_adlibRegMirror = _musicData + 0xF55;
} else {
instrumentDataLoc = READ_LE_UINT16(_musicData + 0x1205);
- _frequenceTable = (uint16*)(_musicData + 0x7FE);
+ _frequenceTable = (uint16 *)(_musicData + 0x7FE);
_registerTable = _musicData + 0xDFE;
_opOutputTable = _musicData + 0xE10;
_adlibRegMirror = _musicData + 0xF5F;
}
_instrumentMap = _musicData+instrumentDataLoc;
- _instruments = (InstrumentStruct*)(_instrumentMap+0x80);
+ _instruments = (InstrumentStruct *)(_instrumentMap+0x80);
}
AdLibChannel::~AdLibChannel() {
diff --git a/engines/sky/music/adlibmusic.cpp b/engines/sky/music/adlibmusic.cpp
index 1b5518fcb1..a41cd6a81d 100644
--- a/engines/sky/music/adlibmusic.cpp
+++ b/engines/sky/music/adlibmusic.cpp
@@ -30,9 +30,8 @@
namespace Sky {
-AdLibMusic::AdLibMusic(Audio::Mixer *pMixer, Disk *pDisk) : MusicBase(pDisk) {
+AdLibMusic::AdLibMusic(Audio::Mixer *pMixer, Disk *pDisk) : MusicBase(pMixer, pDisk) {
_driverFileBase = 60202;
- _mixer = pMixer;
_sampleRate = pMixer->getOutputRate();
_opl = makeAdLibOPL(_sampleRate);
diff --git a/engines/sky/music/adlibmusic.h b/engines/sky/music/adlibmusic.h
index 2782a07be6..2161795b4c 100644
--- a/engines/sky/music/adlibmusic.h
+++ b/engines/sky/music/adlibmusic.h
@@ -26,7 +26,6 @@
#include "sky/music/musicbase.h"
#include "audio/audiostream.h"
#include "audio/fmopl.h"
-#include "audio/mixer.h"
namespace Sky {
@@ -44,7 +43,6 @@ public:
private:
FM_OPL *_opl;
- Audio::Mixer *_mixer;
Audio::SoundHandle _soundHandle;
uint8 *_initSequence;
uint32 _sampleRate, _nextMusicPoll;
diff --git a/engines/sky/music/gmmusic.cpp b/engines/sky/music/gmmusic.cpp
index d0ba1505cb..84f6a654d0 100644
--- a/engines/sky/music/gmmusic.cpp
+++ b/engines/sky/music/gmmusic.cpp
@@ -31,10 +31,10 @@
namespace Sky {
void GmMusic::passTimerFunc(void *param) {
- ((GmMusic*)param)->timerCall();
+ ((GmMusic *)param)->timerCall();
}
-GmMusic::GmMusic(MidiDriver *pMidiDrv, Disk *pDisk) : MusicBase(pDisk) {
+GmMusic::GmMusic(MidiDriver *pMidiDrv, Audio::Mixer *pMixer, Disk *pDisk) : MusicBase(pMixer, pDisk) {
_driverFileBase = 60200;
_midiDrv = pMidiDrv;
int midiRes = _midiDrv->open();
diff --git a/engines/sky/music/gmmusic.h b/engines/sky/music/gmmusic.h
index 0f54a930e4..068601ba1f 100644
--- a/engines/sky/music/gmmusic.h
+++ b/engines/sky/music/gmmusic.h
@@ -31,7 +31,7 @@ namespace Sky {
class GmMusic : public MusicBase {
public:
- GmMusic(MidiDriver *pMidiDrv, Disk *pDisk);
+ GmMusic(MidiDriver *pMidiDrv, Audio::Mixer *pMixer, Disk *pDisk);
~GmMusic();
virtual void setVolume(uint16 param);
private:
diff --git a/engines/sky/music/mt32music.cpp b/engines/sky/music/mt32music.cpp
index d068a221b2..a3fdd42713 100644
--- a/engines/sky/music/mt32music.cpp
+++ b/engines/sky/music/mt32music.cpp
@@ -31,10 +31,10 @@
namespace Sky {
void MT32Music::passTimerFunc(void *param) {
- ((MT32Music*)param)->timerCall();
+ ((MT32Music *)param)->timerCall();
}
-MT32Music::MT32Music(MidiDriver *pMidiDrv, Disk *pDisk) : MusicBase(pDisk) {
+MT32Music::MT32Music(MidiDriver *pMidiDrv, Audio::Mixer *pMixer, Disk *pDisk) : MusicBase(pMixer, pDisk) {
_driverFileBase = 60200;
_midiDrv = pMidiDrv;
int midiRes = _midiDrv->open();
diff --git a/engines/sky/music/mt32music.h b/engines/sky/music/mt32music.h
index 74962daac3..8f8e70f51b 100644
--- a/engines/sky/music/mt32music.h
+++ b/engines/sky/music/mt32music.h
@@ -31,7 +31,7 @@ namespace Sky {
class MT32Music : public MusicBase {
public:
- MT32Music(MidiDriver *pMidiDrv, Disk *pDisk);
+ MT32Music(MidiDriver *pMidiDrv, Audio::Mixer *pMixer, Disk *pDisk);
~MT32Music();
private:
static void passTimerFunc(void *param);
diff --git a/engines/sky/music/musicbase.cpp b/engines/sky/music/musicbase.cpp
index 60d0f352e7..b388afdb13 100644
--- a/engines/sky/music/musicbase.cpp
+++ b/engines/sky/music/musicbase.cpp
@@ -25,11 +25,13 @@
#include "common/util.h"
#include "common/endian.h"
#include "common/textconsole.h"
+#include "audio/audiostream.h"
namespace Sky {
-MusicBase::MusicBase(Disk *pDisk) {
+MusicBase::MusicBase(Audio::Mixer *pMixer, Disk *pDisk) {
_musicData = NULL;
+ _mixer = pMixer;
_skyDisk = pDisk;
_currentMusic = 0;
_musicVolume = 127;
@@ -59,6 +61,8 @@ void MusicBase::loadSection(uint8 pSection) {
}
bool MusicBase::musicIsPlaying() {
+ if (_mixer->isSoundHandleActive(_musicHandle))
+ return true;
for (uint8 cnt = 0; cnt < _numberOfChannels; cnt++)
if (_channels[cnt]->isActive())
return true;
@@ -71,6 +75,8 @@ void MusicBase::stopMusic() {
}
void MusicBase::stopMusicInternal() {
+ _mixer->stopHandle(_musicHandle);
+
for (uint8 cnt = 0; cnt < _numberOfChannels; cnt++)
delete _channels[cnt];
_numberOfChannels = 0;
@@ -94,18 +100,52 @@ void MusicBase::loadNewMusic() {
_currentMusic = _onNextPoll.musicToProcess;
- if (_currentMusic != 0) {
- musicPos = READ_LE_UINT16(_musicData + _musicDataLoc + 1);
- musicPos += _musicDataLoc + ((_currentMusic - 1) << 1);
- musicPos = READ_LE_UINT16(_musicData + musicPos) + _musicDataLoc;
+ if (_currentMusic == 0)
+ return;
+
+ // Try playing digital audio first (from the Music Enhancement Project).
+ // TODO: This always prefers digital music over the MIDI music types!
+ uint8 section = _currentSection;
+ uint8 song = _currentMusic;
+ // handle duplicates
+ if ((section == 2 && song == 1) || (section == 5 && song == 1)) {
+ section = 1;
+ song = 1;
+ } else if ((section == 2 && song == 4) || (section == 5 && song == 4)) {
+ section = 1;
+ song = 4;
+ } else if (section == 5 && song == 6) {
+ section = 4;
+ song = 4;
+ }
+ Common::String trackName = Common::String::format("music_%d%02d", section, song);
+ Audio::SeekableAudioStream *stream = Audio::SeekableAudioStream::openStreamFile(trackName);
+ if (stream) {
+ // not all tracks should loop
+ bool loops = true;
+ if ((section == 0 && song == 1)
+ || (section == 1 && song == 1) || (section == 1 && song == 4)
+ || (section == 2 && song == 1) || (section == 2 && song == 4)
+ || (section == 4 && song == 2) || (section == 4 && song == 3)
+ || (section == 4 && song == 5) || (section == 4 && song == 6)
+ || (section == 4 && song == 11) || (section == 5 && song == 1)
+ || (section == 5 && song == 3) || (section == 5 && song == 4))
+ loops = false;
+ _mixer->playStream(Audio::Mixer::kMusicSoundType, &_musicHandle, Audio::makeLoopingAudioStream(stream, loops ? 0 : 1));
+ return;
+ }
+
+ // no digital audio, resort to MIDI playback
+ musicPos = READ_LE_UINT16(_musicData + _musicDataLoc + 1);
+ musicPos += _musicDataLoc + ((_currentMusic - 1) << 1);
+ musicPos = READ_LE_UINT16(_musicData + musicPos) + _musicDataLoc;
- _musicTempo0 = _musicData[musicPos];
- _musicTempo1 = _musicData[musicPos+1];
+ _musicTempo0 = _musicData[musicPos];
+ _musicTempo1 = _musicData[musicPos+1];
- setupChannels(_musicData + musicPos + 2);
+ setupChannels(_musicData + musicPos + 2);
- updateTempo();
- }
+ updateTempo();
}
void MusicBase::pollMusic() {
diff --git a/engines/sky/music/musicbase.h b/engines/sky/music/musicbase.h
index c175876380..066ebe593c 100644
--- a/engines/sky/music/musicbase.h
+++ b/engines/sky/music/musicbase.h
@@ -27,6 +27,8 @@
#include "common/scummsys.h"
#include "common/mutex.h"
+#include "audio/mixer.h"
+
namespace Sky {
class Disk;
@@ -48,7 +50,7 @@ private:
class MusicBase {
public:
- MusicBase(Disk *pDisk);
+ MusicBase(Audio::Mixer *pMixer, Disk *pDisk);
virtual ~MusicBase();
void loadSection(uint8 pSection);
void startMusic(uint16 param);
@@ -60,6 +62,7 @@ public:
protected:
+ Audio::Mixer *_mixer;
Disk *_skyDisk;
uint8 *_musicData;
@@ -75,6 +78,7 @@ protected:
Actions _onNextPoll;
ChannelBase *_channels[10];
Common::Mutex _mutex;
+ Audio::SoundHandle _musicHandle;
virtual void setupPointers() = 0;
virtual void setupChannels(uint8 *channelData) = 0;
diff --git a/engines/sky/sky.cpp b/engines/sky/sky.cpp
index 72abc26f32..fd90015aa3 100644
--- a/engines/sky/sky.cpp
+++ b/engines/sky/sky.cpp
@@ -58,8 +58,8 @@ extern bool draw_keyboard;
At the beginning the reverse engineers were happy, and did rejoice at
their task, for the engine before them did shineth and was full of
promise. But then they did look closer and see'th the aweful truth;
- it's code was assembly and messy (rareth was its comments). And so large
- were it's includes that did at first seem small; queereth also was its
+ its code was assembly and messy (rareth was its comments). And so large
+ were its includes that did at first seem small; queereth also was its
compact(s). Then they did findeth another version, and this was slightly
different from the first. Then a third, and this was different again.
All different, but not really better, for all were not really compatible.
@@ -268,9 +268,9 @@ Common::Error SkyEngine::init() {
} else {
_systemVars.systemFlags |= SF_ROLAND;
if ((MidiDriver::getMusicType(dev) == MT_MT32) || ConfMan.getBool("native_mt32"))
- _skyMusic = new MT32Music(MidiDriver::createMidi(dev), _skyDisk);
+ _skyMusic = new MT32Music(MidiDriver::createMidi(dev), _mixer, _skyDisk);
else
- _skyMusic = new GmMusic(MidiDriver::createMidi(dev), _skyDisk);
+ _skyMusic = new GmMusic(MidiDriver::createMidi(dev), _mixer, _skyDisk);
}
if (isCDVersion()) {
diff --git a/engines/sky/text.cpp b/engines/sky/text.cpp
index 3e119b3b20..38a01116fe 100644
--- a/engines/sky/text.cpp
+++ b/engines/sky/text.cpp
@@ -136,7 +136,7 @@ void Text::getText(uint32 textNr) { //load text #"textNr" into textBuffer
textNr &= 0x1F;
if (blockNr) {
- uint16 *blockPtr = (uint16*)(textDataPtr + 4);
+ uint16 *blockPtr = (uint16 *)(textDataPtr + 4);
uint32 nr32MsgBlocks = blockNr >> 5;
do {
@@ -298,7 +298,7 @@ DisplayedText Text::displayText(char *textPtr, uint8 *dest, bool center, uint16
uint32 numBytes = (dtLineSize * numLines) + sizeof(DataFileHeader) + 4;
if (!dest)
- dest = (uint8*)malloc(numBytes);
+ dest = (uint8 *)malloc(numBytes);
// clear text sprite buffer
memset(dest + sizeof(DataFileHeader), 0, numBytes - sizeof(DataFileHeader));
diff --git a/engines/sword1/animation.cpp b/engines/sword1/animation.cpp
index 324154f709..1e2964054a 100644
--- a/engines/sword1/animation.cpp
+++ b/engines/sword1/animation.cpp
@@ -28,6 +28,7 @@
#include "sword1/sword1.h"
#include "sword1/animation.h"
#include "sword1/text.h"
+#include "sword1/resman.h"
#include "common/str.h"
#include "common/system.h"
@@ -36,6 +37,11 @@
#include "gui/message.h"
+#include "video/psx_decoder.h"
+#include "video/smk_decoder.h"
+
+#include "engines/util.h"
+
namespace Sword1 {
static const char *const sequenceList[20] = {
@@ -61,17 +67,42 @@ static const char *const sequenceList[20] = {
"credits", // 19 CD2 credits, to follow "finale" sequence
};
+// This is the list of the names of the PlayStation videos
+// TODO: fight.str, flashy.str,
+static const char *const sequenceListPSX[20] = {
+ "e_ferr1",
+ "ladder1",
+ "steps1",
+ "sewer1",
+ "e_intro1",
+ "river1",
+ "truck1",
+ "grave1",
+ "montfcn1",
+ "tapesty1",
+ "ireland1",
+ "e_fin1",
+ "e_hist1",
+ "spanish1",
+ "well1",
+ "candle1",
+ "geodrop1",
+ "vulture1",
+ "", // demo video not present
+ "" // credits are not a video
+};
+
///////////////////////////////////////////////////////////////////////////////
// Basic movie player
///////////////////////////////////////////////////////////////////////////////
-MoviePlayer::MoviePlayer(SwordEngine *vm, Text *textMan, Audio::Mixer *snd, OSystem *system, Audio::SoundHandle *bgSoundHandle, Video::VideoDecoder *decoder, DecoderType decoderType)
- : _vm(vm), _textMan(textMan), _snd(snd), _bgSoundHandle(bgSoundHandle), _system(system) {
+MoviePlayer::MoviePlayer(SwordEngine *vm, Text *textMan, ResMan *resMan, Audio::Mixer *snd, OSystem *system, Audio::SoundHandle *bgSoundHandle, Video::VideoDecoder *decoder, DecoderType decoderType)
+ : _vm(vm), _textMan(textMan), _resMan(resMan), _snd(snd), _bgSoundHandle(bgSoundHandle), _system(system) {
_bgSoundStream = NULL;
_decoderType = decoderType;
_decoder = decoder;
- _white = 255;
+ _c1Color = _c2Color = _c3Color = _c4Color = 255;
_black = 0;
}
@@ -114,7 +145,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(static_cast<unsigned char>(*ptr)))
+ while (*ptr && Common::isSpace(*ptr))
ptr++;
if (startFrame > endFrame) {
@@ -126,8 +157,16 @@ bool MoviePlayer::load(uint32 id) {
warning("%s:%d startFrame (%d) <= lastEnd (%d)", filename.c_str(), lineNo, startFrame, lastEnd);
continue;
}
-
- _movieTexts.push_back(MovieText(startFrame, endFrame, ptr));
+
+ int color = 0;
+ if (*ptr == '@') {
+ ++ptr;
+ color = strtoul(ptr, const_cast<char **>(&ptr), 10);
+ while (*ptr && Common::isSpace(*ptr))
+ ptr++;
+ }
+
+ _movieTexts.push_back(MovieText(startFrame, endFrame, ptr, color));
lastEnd = endFrame;
}
f.close();
@@ -141,6 +180,21 @@ bool MoviePlayer::load(uint32 id) {
case kVideoDecoderSMK:
filename = Common::String::format("%s.smk", sequenceList[id]);
break;
+ case kVideoDecoderPSX:
+ filename = Common::String::format("%s.str", (_vm->_systemVars.isDemo) ? sequenceList[id] : sequenceListPSX[id]);
+
+ // Need to switch to true color
+ initGraphics(g_system->getWidth(), g_system->getHeight(), true, 0);
+
+ // Need to load here in case it fails in which case we'd need
+ // to go back to paletted mode
+ if (_decoder->loadFile(filename)) {
+ return true;
+ } else {
+ initGraphics(g_system->getWidth(), g_system->getHeight(), true);
+ return false;
+ }
+ break;
}
return _decoder->loadFile(filename.c_str());
@@ -178,15 +232,21 @@ void MoviePlayer::play() {
}
void MoviePlayer::performPostProcessing(byte *screen) {
+ // TODO: We don't support the PSX stream videos yet
+ // nor using the PSX fonts to display subtitles.
+ if (_vm->isPsx())
+ return;
+
if (!_movieTexts.empty()) {
if (_decoder->getCurFrame() == _movieTexts.front()._startFrame) {
_textMan->makeTextSprite(2, (const uint8 *)_movieTexts.front()._text.c_str(), 600, LETTER_COL);
FrameHeader *frame = _textMan->giveSpriteData(2);
- _textWidth = frame->width;
- _textHeight = frame->height;
+ _textWidth = _resMan->toUint16(frame->width);
+ _textHeight = _resMan->toUint16(frame->height);
_textX = 320 - _textWidth / 2;
_textY = 420 - _textHeight;
+ _textColor = _movieTexts.front()._color;
}
if (_decoder->getCurFrame() == _movieTexts.front()._endFrame) {
_textMan->releaseText(2, false);
@@ -205,10 +265,10 @@ void MoviePlayer::performPostProcessing(byte *screen) {
for (x = 0; x < _textWidth; x++) {
switch (src[x]) {
case BORDER_COL:
- dst[x] = findBlackPalIndex();
+ dst[x] = getBlackColor();
break;
case LETTER_COL:
- dst[x] = findWhitePalIndex();
+ dst[x] = findTextColor();
break;
}
}
@@ -228,12 +288,12 @@ void MoviePlayer::performPostProcessing(byte *screen) {
for (y = 0; y < _textHeight; y++) {
if (_textY + y < frameY || _textY + y >= frameY + frameHeight) {
- memset(dst + _textX, findBlackPalIndex(), _textWidth);
+ memset(dst + _textX, getBlackColor(), _textWidth);
} else {
if (frameX > _textX)
- memset(dst + _textX, findBlackPalIndex(), frameX - _textX);
+ memset(dst + _textX, getBlackColor(), frameX - _textX);
if (frameX + frameWidth < _textX + _textWidth)
- memset(dst + frameX + frameWidth, findBlackPalIndex(), _textX + _textWidth - (frameX + frameWidth));
+ memset(dst + frameX + frameWidth, getBlackColor(), _textX + _textWidth - (frameX + frameWidth));
}
dst += _system->getWidth();
@@ -245,40 +305,105 @@ void MoviePlayer::performPostProcessing(byte *screen) {
}
bool MoviePlayer::playVideo() {
+ bool skipped = false;
uint16 x = (g_system->getWidth() - _decoder->getWidth()) / 2;
uint16 y = (g_system->getHeight() - _decoder->getHeight()) / 2;
- while (!_vm->shouldQuit() && !_decoder->endOfVideo()) {
+ while (!_vm->shouldQuit() && !_decoder->endOfVideo() && !skipped) {
if (_decoder->needsUpdate()) {
const Graphics::Surface *frame = _decoder->decodeNextFrame();
- if (frame)
- _vm->_system->copyRectToScreen((byte *)frame->pixels, frame->pitch, x, y, frame->w, frame->h);
+ if (frame) {
+ if (_decoderType == kVideoDecoderPSX)
+ drawFramePSX(frame);
+ else
+ _vm->_system->copyRectToScreen((byte *)frame->pixels, frame->pitch, x, y, frame->w, frame->h);
+ }
if (_decoder->hasDirtyPalette()) {
_decoder->setSystemPalette();
- uint32 maxWeight = 0;
- uint32 minWeight = 0xFFFFFFFF;
- uint32 weight;
- byte r, g, b;
-
- const byte *palette = _decoder->getPalette();
-
- for (int i = 0; i < 256; i++) {
- r = *palette++;
- g = *palette++;
- b = *palette++;
-
- weight = 3 * r * r + 6 * g * g + 2 * b * b;
-
- if (weight >= maxWeight) {
- maxWeight = weight;
- _white = i;
- }
-
- if (weight <= minWeight) {
- minWeight = weight;
- _black = i;
+ if (!_movieTexts.empty()) {
+ // Look for the best color indexes to use to display the subtitles
+ uint32 minWeight = 0xFFFFFFFF;
+ uint32 weight;
+ float c1Weight = 1e+30f;
+ float c2Weight = 1e+30f;
+ float c3Weight = 1e+30f;
+ float c4Weight = 1e+30f;
+ byte r, g, b;
+ float h, s, v, hd, hsvWeight;
+
+ const byte *palette = _decoder->getPalette();
+
+ // Color comparaison for the subtitles colors is done in HSL
+ // C1 color is used for George and is almost white (R = 248, G = 252, B = 248)
+ const float h1 = 0.333333f, s1 = 0.02f, v1 = 0.99f;
+
+ // C2 color is used for George as a narrator and is grey (R = 184, G = 188, B = 184)
+ const float h2 = 0.333333f, s2 = 0.02f, v2 = 0.74f;
+
+ // C3 color is used for Nicole and is rose (R = 200, G = 120, B = 184)
+ const float h3 = 0.866667f, s3 = 0.4f, v3 = 0.78f;
+
+ // C4 color is used for Maguire and is blue (R = 80, G = 152, B = 184)
+ const float h4 = 0.55f, s4 = 0.57f, v4 = 0.72f;
+
+ for (int i = 0; i < 256; i++) {
+ r = *palette++;
+ g = *palette++;
+ b = *palette++;
+
+ weight = 3 * r * r + 6 * g * g + 2 * b * b;
+
+ if (weight <= minWeight) {
+ minWeight = weight;
+ _black = i;
+ }
+
+ convertColor(r, g, b, h, s, v);
+
+ // C1 color
+ // It is almost achromatic (very low saturation) so the hue as litle impact on the color.
+ // Therefore use a low weight on hue and high weight on saturation.
+ hd = h - h1;
+ hd += hd < -0.5f ? 1.0f : hd > 0.5f ? -1.0f : 0.0f;
+ hsvWeight = 1.0f * hd * hd + 4.0f * (s - s1) * (s - s1) + 3.0f * (v - v1) * (v - v1);
+ if (hsvWeight <= c1Weight) {
+ c1Weight = hsvWeight;
+ _c1Color = i;
+ }
+
+ // C2 color
+ // Also an almost achromatic color so use the same weights as for C1 color.
+ hd = h - h2;
+ hd += hd < -0.5f ? 1.0f : hd > 0.5f ? -1.0f : 0.0f;
+ hsvWeight = 1.0f * hd * hd + 4.0f * (s - s2) * (s - s2) + 3.0f * (v - v2) * (v - v2);
+ if (hsvWeight <= c2Weight) {
+ c2Weight = hsvWeight;
+ _c2Color = i;
+ }
+
+ // C3 color
+ // A light rose. Use a high weight on the hue to get a rose.
+ // The color is a bit gray and the saturation has not much impact so use a low weight.
+ hd = h - h3;
+ hd += hd < -0.5f ? 1.0f : hd > 0.5f ? -1.0f : 0.0f;
+ hsvWeight = 4.0f * hd * hd + 1.0f * (s - s3) * (s - s3) + 2.0f * (v - v3) * (v - v3);
+ if (hsvWeight <= c3Weight) {
+ c3Weight = hsvWeight;
+ _c3Color = i;
+ }
+
+ // C4 color
+ // Blue. Use a hight weight on the hue to get a blue.
+ // The color is darker and more saturated than C3 and the saturation has more impact.
+ hd = h - h4;
+ hd += hd < -0.5f ? 1.0f : hd > 0.5f ? -1.0f : 0.0f;
+ hsvWeight = 5.0f * hd * hd + 3.0f * (s - s4) * (s - s4) + 2.0f * (v - v4) * (v - v4);
+ if (hsvWeight <= c4Weight) {
+ c4Weight = hsvWeight;
+ _c4Color = i;
+ }
}
}
}
@@ -292,20 +417,93 @@ bool MoviePlayer::playVideo() {
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)
- return false;
+ skipped = true;
_vm->_system->delayMillis(10);
}
- return !_vm->shouldQuit();
+ if (_decoderType == kVideoDecoderPSX) {
+ // Need to jump back to paletted color
+ initGraphics(g_system->getWidth(), g_system->getHeight(), true);
+ }
+
+ return !_vm->shouldQuit() && !skipped;
+}
+
+uint32 MoviePlayer::getBlackColor() {
+ return (_decoderType == kVideoDecoderPSX) ? g_system->getScreenFormat().RGBToColor(0x00, 0x00, 0x00) : _black;
+}
+
+uint32 MoviePlayer::findTextColor() {
+ if (_decoderType == kVideoDecoderPSX) {
+ // We're in true color mode, so return the actual colors
+ switch (_textColor) {
+ case 1:
+ return g_system->getScreenFormat().RGBToColor(248, 252, 248);
+ case 2:
+ return g_system->getScreenFormat().RGBToColor(184, 188, 184);
+ case 3:
+ return g_system->getScreenFormat().RGBToColor(200, 120, 184);
+ case 4:
+ return g_system->getScreenFormat().RGBToColor(80, 152, 184);
+ }
+
+ return g_system->getScreenFormat().RGBToColor(0xFF, 0xFF, 0xFF);
+ }
+
+ switch (_textColor) {
+ case 1:
+ return _c1Color;
+ case 2:
+ return _c2Color;
+ case 3:
+ return _c3Color;
+ case 4:
+ return _c4Color;
+ }
+ return _c1Color;
}
-byte MoviePlayer::findBlackPalIndex() {
- return _black;
+void MoviePlayer::convertColor(byte r, byte g, byte b, float &h, float &s, float &v) {
+ float varR = r / 255.0f;
+ float varG = g / 255.0f;
+ float varB = b / 255.0f;
+
+ float min = MIN(varR, MIN(varG, varB));
+ float max = MAX(varR, MAX(varG, varB));
+
+ v = max;
+ float d = max - min;
+ s = max == 0.0f ? 0.0f : d / max;
+
+ if (min == max) {
+ h = 0.0f; // achromatic
+ } else {
+ if (max == varR)
+ h = (varG - varB) / d + (varG < varB ? 6.0f : 0.0f);
+ else if (max == varG)
+ h = (varB - varR) / d + 2.0f;
+ else
+ h = (varR - varG) / d + 4.0f;
+ h /= 6.0f;
+ }
}
-byte MoviePlayer::findWhitePalIndex() {
- return _white;
+void MoviePlayer::drawFramePSX(const Graphics::Surface *frame) {
+ // The PSX videos have half resolution
+
+ Graphics::Surface scaledFrame;
+ scaledFrame.create(frame->w, frame->h * 2, frame->format);
+
+ for (int y = 0; y < scaledFrame.h; y++)
+ memcpy(scaledFrame.getBasePtr(0, y), frame->getBasePtr(0, y / 2), scaledFrame.w * scaledFrame.format.bytesPerPixel);
+
+ uint16 x = (g_system->getWidth() - scaledFrame.w) / 2;
+ uint16 y = (g_system->getHeight() - scaledFrame.h) / 2;
+
+ _vm->_system->copyRectToScreen((byte *)scaledFrame.pixels, scaledFrame.pitch, x, y, scaledFrame.w, scaledFrame.h);
+
+ scaledFrame.free();
}
DXADecoderWithSound::DXADecoderWithSound(Audio::Mixer *mixer, Audio::SoundHandle *bgSoundHandle)
@@ -323,15 +521,33 @@ uint32 DXADecoderWithSound::getElapsedTime() const {
// Factory function for creating the appropriate cutscene player
///////////////////////////////////////////////////////////////////////////////
-MoviePlayer *makeMoviePlayer(uint32 id, SwordEngine *vm, Text *textMan, Audio::Mixer *snd, OSystem *system) {
+MoviePlayer *makeMoviePlayer(uint32 id, SwordEngine *vm, Text *textMan, ResMan *resMan, Audio::Mixer *snd, OSystem *system) {
Common::String filename;
Audio::SoundHandle *bgSoundHandle = new Audio::SoundHandle;
+ // For the PSX version, we'll try the PlayStation stream files
+ if (vm->isPsx()) {
+ // The demo uses the normal file names
+ filename = ((vm->_systemVars.isDemo) ? Common::String(sequenceList[id]) : Common::String(sequenceListPSX[id])) + ".str";
+
+ if (Common::File::exists(filename)) {
+#ifdef USE_RGB_COLOR
+ // All BS1 PSX videos run the videos at 2x speed
+ Video::VideoDecoder *psxDecoder = new Video::PSXStreamDecoder(Video::PSXStreamDecoder::kCD2x);
+ return new MoviePlayer(vm, textMan, resMan, snd, system, bgSoundHandle, psxDecoder, kVideoDecoderPSX);
+#else
+ GUI::MessageDialog dialog(Common::String::format(_("PSX stream cutscene '%s' cannot be played in paletted mode"), filename.c_str()), _("OK"));
+ dialog.runModal();
+ return 0;
+#endif
+ }
+ }
+
filename = Common::String::format("%s.smk", sequenceList[id]);
if (Common::File::exists(filename)) {
Video::SmackerDecoder *smkDecoder = new Video::SmackerDecoder(snd);
- return new MoviePlayer(vm, textMan, snd, system, bgSoundHandle, smkDecoder, kVideoDecoderSMK);
+ return new MoviePlayer(vm, textMan, resMan, snd, system, bgSoundHandle, smkDecoder, kVideoDecoderSMK);
}
filename = Common::String::format("%s.dxa", sequenceList[id]);
@@ -339,7 +555,7 @@ MoviePlayer *makeMoviePlayer(uint32 id, SwordEngine *vm, Text *textMan, Audio::M
if (Common::File::exists(filename)) {
#ifdef USE_ZLIB
DXADecoderWithSound *dxaDecoder = new DXADecoderWithSound(snd, bgSoundHandle);
- return new MoviePlayer(vm, textMan, snd, system, bgSoundHandle, dxaDecoder, kVideoDecoderDXA);
+ return new MoviePlayer(vm, textMan, resMan, snd, system, bgSoundHandle, dxaDecoder, kVideoDecoderDXA);
#else
GUI::MessageDialog dialog(_("DXA cutscenes found but ScummVM has been built without zlib support"), _("OK"));
dialog.runModal();
@@ -356,9 +572,11 @@ MoviePlayer *makeMoviePlayer(uint32 id, SwordEngine *vm, Text *textMan, Audio::M
return NULL;
}
- Common::String buf = Common::String::format(_("Cutscene '%s' not found"), sequenceList[id]);
- GUI::MessageDialog dialog(buf, _("OK"));
- dialog.runModal();
+ if (!vm->isPsx() || scumm_stricmp(sequenceList[id], "enddemo") != 0) {
+ 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/animation.h b/engines/sword1/animation.h
index fc3061bbf9..f64b03dd1b 100644
--- a/engines/sword1/animation.h
+++ b/engines/sword1/animation.h
@@ -24,7 +24,6 @@
#define SWORD1_ANIMATION_H
#include "video/dxa_decoder.h"
-#include "video/smk_decoder.h"
#include "video/video_decoder.h"
#include "common/list.h"
@@ -38,18 +37,21 @@ namespace Sword1 {
enum DecoderType {
kVideoDecoderDXA = 0,
- kVideoDecoderSMK = 1
+ kVideoDecoderSMK = 1,
+ kVideoDecoderPSX = 2
};
class MovieText {
public:
uint16 _startFrame;
uint16 _endFrame;
+ uint16 _color;
Common::String _text;
- MovieText(int startFrame, int endFrame, const Common::String &text) {
+ MovieText(int startFrame, int endFrame, const Common::String &text, int color) {
_startFrame = startFrame;
_endFrame = endFrame;
_text = text;
+ _color = color;
}
};
@@ -67,7 +69,7 @@ private:
class MoviePlayer {
public:
- MoviePlayer(SwordEngine *vm, Text *textMan, Audio::Mixer *snd, OSystem *system, Audio::SoundHandle *bgSoundHandle, Video::VideoDecoder *decoder, DecoderType decoderType);
+ MoviePlayer(SwordEngine *vm, Text *textMan, ResMan *resMan, Audio::Mixer *snd, OSystem *system, Audio::SoundHandle *bgSoundHandle, Video::VideoDecoder *decoder, DecoderType decoderType);
virtual ~MoviePlayer();
bool load(uint32 id);
void play();
@@ -75,11 +77,14 @@ public:
protected:
SwordEngine *_vm;
Text *_textMan;
+ ResMan *_resMan;
Audio::Mixer *_snd;
OSystem *_system;
Common::List<MovieText> _movieTexts;
int _textX, _textY, _textWidth, _textHeight;
- byte _white, _black;
+ int _textColor;
+ uint32 _black;
+ uint32 _c1Color, _c2Color, _c3Color, _c4Color;
DecoderType _decoderType;
Video::VideoDecoder *_decoder;
@@ -88,12 +93,14 @@ protected:
bool playVideo();
void performPostProcessing(byte *screen);
+ void drawFramePSX(const Graphics::Surface *frame);
- byte findBlackPalIndex();
- byte findWhitePalIndex();
+ uint32 getBlackColor();
+ uint32 findTextColor();
+ void convertColor(byte r, byte g, byte b, float &h, float &s, float &v);
};
-MoviePlayer *makeMoviePlayer(uint32 id, SwordEngine *vm, Text *textMan, Audio::Mixer *snd, OSystem *system);
+MoviePlayer *makeMoviePlayer(uint32 id, SwordEngine *vm, Text *textMan, ResMan *resMan, Audio::Mixer *snd, OSystem *system);
} // End of namespace Sword1
diff --git a/engines/sword1/detection.cpp b/engines/sword1/detection.cpp
index 9d9f198f8b..087dcd09d8 100644
--- a/engines/sword1/detection.cpp
+++ b/engines/sword1/detection.cpp
@@ -25,6 +25,7 @@
#include "base/plugins.h"
#include "common/fs.h"
+#include "common/gui_options.h"
#include "common/savefile.h"
#include "common/system.h"
#include "graphics/thumbnail.h"
@@ -198,17 +199,17 @@ GameList SwordMetaEngine::detectGames(const Common::FSList &fslist) const {
psxDemoFilesFound = false;
if (mainFilesFound && pcFilesFound && demoFilesFound)
- detectedGames.push_back(GameDescriptor(sword1DemoSettings, GUIO1(GUIO_NOMIDI)));
+ detectedGames.push_back(GameDescriptor(sword1DemoSettings, GUIO2(GUIO_NOMIDI, GUIO_NOASPECT)));
else if (mainFilesFound && pcFilesFound && psxFilesFound)
- detectedGames.push_back(GameDescriptor(sword1PSXSettings, GUIO1(GUIO_NOMIDI)));
+ detectedGames.push_back(GameDescriptor(sword1PSXSettings, GUIO2(GUIO_NOMIDI, GUIO_NOASPECT)));
else if (mainFilesFound && pcFilesFound && psxDemoFilesFound)
- detectedGames.push_back(GameDescriptor(sword1PSXDemoSettings, GUIO1(GUIO_NOMIDI)));
+ detectedGames.push_back(GameDescriptor(sword1PSXDemoSettings, GUIO2(GUIO_NOMIDI, GUIO_NOASPECT)));
else if (mainFilesFound && pcFilesFound && !psxFilesFound)
- detectedGames.push_back(GameDescriptor(sword1FullSettings, GUIO1(GUIO_NOMIDI)));
+ detectedGames.push_back(GameDescriptor(sword1FullSettings, GUIO2(GUIO_NOMIDI, GUIO_NOASPECT)));
else if (mainFilesFound && macFilesFound)
- detectedGames.push_back(GameDescriptor(sword1MacFullSettings, GUIO1(GUIO_NOMIDI)));
+ detectedGames.push_back(GameDescriptor(sword1MacFullSettings, GUIO2(GUIO_NOMIDI, GUIO_NOASPECT)));
else if (mainFilesFound && macDemoFilesFound)
- detectedGames.push_back(GameDescriptor(sword1MacDemoSettings, GUIO1(GUIO_NOMIDI)));
+ detectedGames.push_back(GameDescriptor(sword1MacDemoSettings, GUIO2(GUIO_NOMIDI, GUIO_NOASPECT)));
return detectedGames;
}
diff --git a/engines/sword1/logic.cpp b/engines/sword1/logic.cpp
index d1c69c80ff..8e04861edf 100644
--- a/engines/sword1/logic.cpp
+++ b/engines/sword1/logic.cpp
@@ -520,7 +520,7 @@ int Logic::interpretScript(Object *compact, int id, Header *scriptModule, int sc
case IT_PUSHVARIABLE:
debug(9, "IT_PUSHVARIABLE: ScriptVar[%d] => %d", scriptCode[pc], _scriptVars[scriptCode[pc]]);
varNum = scriptCode[pc++];
- if (SwordEngine::_systemVars.isDemo && SwordEngine::isPc()) {
+ if (SwordEngine::_systemVars.isDemo && SwordEngine::isWindows()) {
if (varNum >= 397) // BS1 Demo has different number of script variables
varNum++;
if (varNum >= 699)
@@ -611,7 +611,7 @@ int Logic::interpretScript(Object *compact, int id, Header *scriptModule, int sc
case IT_POPVAR: // pop a variable
debug(9, "IT_POPVAR: ScriptVars[%d] = %d", scriptCode[pc], stack[stackIdx - 1]);
varNum = scriptCode[pc++];
- if (SwordEngine::_systemVars.isDemo && SwordEngine::isPc()) {
+ if (SwordEngine::_systemVars.isDemo && SwordEngine::isWindows()) {
if (varNum >= 397) // BS1 Demo has different number of script variables
varNum++;
if (varNum >= 699)
@@ -959,7 +959,7 @@ int Logic::fnPlaySequence(Object *cpt, int32 id, int32 sequenceId, int32 d, int3
// meantime, we don't want any looping sound effects still playing.
_sound->quitScreen();
- MoviePlayer *player = makeMoviePlayer(sequenceId, _vm, _textMan, _mixer, _system);
+ MoviePlayer *player = makeMoviePlayer(sequenceId, _vm, _textMan, _resMan, _mixer, _system);
if (player) {
_screen->clearScreen();
if (player->load(sequenceId))
diff --git a/engines/sword1/sound.cpp b/engines/sword1/sound.cpp
index b74cd8c393..3574074b00 100644
--- a/engines/sword1/sound.cpp
+++ b/engines/sword1/sound.cpp
@@ -62,11 +62,22 @@ Sound::~Sound() {
_mixer->stopAll();
for (uint8 cnt = 0; cnt < _endOfQueue; cnt++)
if (_fxQueue[cnt].delay == 0)
- _resMan->resClose(_fxList[_fxQueue[cnt].id].sampleId);
+ _resMan->resClose(getSampleId(_fxQueue[cnt].id));
_endOfQueue = 0;
closeCowSystem();
}
+uint32 Sound::getSampleId(int32 fxNo) {
+ byte cluster = _fxList[fxNo].sampleId.cluster;
+ byte id;
+ if (SwordEngine::_systemVars.isDemo && SwordEngine::_systemVars.platform == Common::kPlatformWindows) {
+ id = _fxList[fxNo].sampleId.idWinDemo;
+ } else {
+ id = _fxList[fxNo].sampleId.idStd;
+ }
+ return (cluster << 24) | id;
+}
+
void Sound::checkSpeechFileEndianness() {
// Some mac versions (not all of them) use big endian wav, although
// the wav header doesn't indicate it.
@@ -154,14 +165,18 @@ int Sound::addToQueue(int32 fxNo) {
warning("Sound queue overflow");
return 0;
}
- _resMan->resOpen(_fxList[fxNo].sampleId);
- _fxQueue[_endOfQueue].id = fxNo;
- if (_fxList[fxNo].type == FX_SPOT)
- _fxQueue[_endOfQueue].delay = _fxList[fxNo].delay + 1;
- else
- _fxQueue[_endOfQueue].delay = 1;
- _endOfQueue++;
- return 1;
+ uint32 sampleId = getSampleId(fxNo);
+ if ((sampleId & 0xFF) != 0xFF) {
+ _resMan->resOpen(sampleId);
+ _fxQueue[_endOfQueue].id = fxNo;
+ if (_fxList[fxNo].type == FX_SPOT)
+ _fxQueue[_endOfQueue].delay = _fxList[fxNo].delay + 1;
+ else
+ _fxQueue[_endOfQueue].delay = 1;
+ _endOfQueue++;
+ return 1;
+ }
+ return 0;
}
return 0;
}
@@ -186,7 +201,7 @@ void Sound::engine() {
playSample(&_fxQueue[cnt2]);
} else {
if (!_mixer->isSoundHandleActive(_fxQueue[cnt2].handle)) { // sound finished
- _resMan->resClose(_fxList[_fxQueue[cnt2].id].sampleId);
+ _resMan->resClose(getSampleId(_fxQueue[cnt2].id));
if (cnt2 != _endOfQueue - 1)
_fxQueue[cnt2] = _fxQueue[_endOfQueue - 1];
_endOfQueue--;
@@ -200,7 +215,7 @@ void Sound::fnStopFx(int32 fxNo) {
for (uint8 cnt = 0; cnt < _endOfQueue; cnt++)
if (_fxQueue[cnt].id == (uint32)fxNo) {
if (!_fxQueue[cnt].delay) // sound was started
- _resMan->resClose(_fxList[_fxQueue[cnt].id].sampleId);
+ _resMan->resClose(getSampleId(_fxQueue[cnt].id));
if (cnt != _endOfQueue - 1)
_fxQueue[cnt] = _fxQueue[_endOfQueue - 1];
_endOfQueue--;
@@ -243,7 +258,7 @@ void Sound::quitScreen() {
}
void Sound::playSample(QueueElement *elem) {
- uint8 *sampleData = (uint8 *)_resMan->fetchRes(_fxList[elem->id].sampleId);
+ uint8 *sampleData = (uint8 *)_resMan->fetchRes(getSampleId(elem->id));
for (uint16 cnt = 0; cnt < MAX_ROOMS_PER_FX; cnt++) {
if (_fxList[elem->id].roomVolList[cnt].roomNo) {
if ((_fxList[elem->id].roomVolList[cnt].roomNo == (int)Logic::_scriptVars[SCREEN]) ||
diff --git a/engines/sword1/sound.h b/engines/sword1/sound.h
index 112ae5b6aa..4e1ac7ba34 100644
--- a/engines/sword1/sound.h
+++ b/engines/sword1/sound.h
@@ -53,8 +53,15 @@ struct RoomVol {
int32 roomNo, leftVol, rightVol;
};
+struct SampleId {
+ byte cluster;
+ byte idStd;
+ byte idWinDemo;
+};
+
struct FxDef {
- uint32 sampleId, type, delay;
+ SampleId sampleId;
+ uint32 type, delay;
RoomVol roomVolList[MAX_ROOMS_PER_FX];
};
@@ -100,6 +107,7 @@ private:
void playSample(QueueElement *elem);
void initCowSystem();
+ uint32 getSampleId(int32 fxNo);
int16 *uncompressSpeech(uint32 index, uint32 cSize, uint32 *size);
void calcWaveVolume(int16 *data, uint32 length);
bool _waveVolume[WAVE_VOL_TAB_LENGTH];
diff --git a/engines/sword1/staticres.cpp b/engines/sword1/staticres.cpp
index 60c6877232..5dabce1301 100644
--- a/engines/sword1/staticres.cpp
+++ b/engines/sword1/staticres.cpp
@@ -2894,7 +2894,7 @@ const char Music::_tuneList[TOTAL_TUNES][8] = {
const FxDef Sound::_fxList[312] = {
// 0
{
- 0, // sampleId
+ {0,0,0}, // sampleId
0, // type (FX_LOOP, FX_RANDOM or FX_SPOT)
0, // delay (random chance for FX_RANDOM sound fx)
{ // roomVolList
diff --git a/engines/sword1/sword1.cpp b/engines/sword1/sword1.cpp
index 865e025786..75e8f72d9d 100644
--- a/engines/sword1/sword1.cpp
+++ b/engines/sword1/sword1.cpp
@@ -62,8 +62,9 @@ SwordEngine::SwordEngine(OSystem *syst)
SearchMan.addSubDirectoryMatching(gameDataDir, "speech");
SearchMan.addSubDirectoryMatching(gameDataDir, "video");
SearchMan.addSubDirectoryMatching(gameDataDir, "smackshi");
- SearchMan.addSubDirectoryMatching(gameDataDir, "english");//PSX Demo
- SearchMan.addSubDirectoryMatching(gameDataDir, "italian");//PSX Demo
+ SearchMan.addSubDirectoryMatching(gameDataDir, "streams"); // PSX videos
+ SearchMan.addSubDirectoryMatching(gameDataDir, "english"); // PSX Demo
+ SearchMan.addSubDirectoryMatching(gameDataDir, "italian"); // PSX Demo
_console = new SwordConsole(this);
}
diff --git a/engines/sword1/sword1.h b/engines/sword1/sword1.h
index e973c12754..ccdc2d3a59 100644
--- a/engines/sword1/sword1.h
+++ b/engines/sword1/sword1.h
@@ -90,7 +90,7 @@ public:
static bool isMac() { return _systemVars.platform == Common::kPlatformMacintosh; }
static bool isPsx() { return _systemVars.platform == Common::kPlatformPSX; }
- static bool isPc() { return _systemVars.platform == Common::kPlatformPC; }
+ static bool isWindows() { return _systemVars.platform == Common::kPlatformWindows ; }
protected:
// Engine APIs
diff --git a/engines/sword1/swordres.h b/engines/sword1/swordres.h
index 384c240283..b1fc206b80 100644
--- a/engines/sword1/swordres.h
+++ b/engines/sword1/swordres.h
@@ -1298,66 +1298,66 @@ namespace Sword1 {
// 2 entities in TXTs, 2 in datafiles.
// paris_1
// sound_fx
-#define FX_CAMERA1 0x06000000
-#define FX_CAMERA2 0x06000001
-#define FX_CAMERA3 0x06000002
-#define FX_CANDO 0x06000003
-#define FX_CANUP 0x06000004
-#define FX_CAW1 0x06000005
-#define FX_DUST 0x06000006
-#define FX_HORN1 0x06000007
-#define FX_HORN2 0x06000008
-#define FX_HORN3 0x06000009
-#define FX_LVSFLY 0x0600000A
-#define FX_PAP1 0x0600000B
-#define FX_PAP2 0x0600000C
-#define FX_PICK1 0x0600000D
-#define FX_PICK2 0x0600000E
-#define FX_PICK3 0x0600000F
-#define FX_PICK4 0x06000010
-#define FX_PICK5 0x06000011
-#define FX_TRAFFIC2 0x06000012
-#define FX_TWEET1 0x06000013
-#define FX_TWEET2 0x06000014
-#define FX_TWEET3 0x06000015
-#define FX_TWEET4 0x06000016
-#define FX_TWEET5 0x06000017
-#define FX_BIN1 0x06000018
-#define FX_BIN2 0x06000019
-#define FX_BIN3 0x0600001A
-#define FX_CAT 0x0600001B
-#define FX_COVERON2 0x0600001C
-#define FX_CRATE 0x0600001D
-#define FX_DRAIN 0x0600001E
-#define FX_HOLE 0x0600001F
-#define FX_BODY 0x06000020
-#define FX_BOTDN 0x06000021
-#define FX_BOTUP 0x06000022
-#define FX_GULP 0x06000023
-#define FX_LIGHT 0x06000024
-#define FX_PIKUP 0x06000025
-#define FX_PAP3 0x06000026
-#define FX_PAP4 0x06000027
-#define FX_PAP5 0x06000028
-#define FX_PISTOL 0x06000029
-#define FX_TBOX 0x0600002A
-#define FX_KNOKKNOK 0x0600002B
-#define FX_ALBCLO 0x0600002C
-#define FX_ALBOP 0x0600002D
-#define FX_LADD1 0x0600002E
-#define FX_LADD2 0x0600002F
-#define FX_LADD3 0x06000030
-#define FX_RAT1 0x06000031
-#define FX_RAT2 0x06000032
-#define FX_SEWSTEP1 0x06000033
-#define FX_SEWSTEP2 0x06000034
-#define FX_SWATER3 0x06000035
-#define FX_DRIP1 0x06000036
-#define FX_DRIP2 0x06000037
-#define FX_DRIP3 0x06000038
-#define FX_SWATER1 0x06000039
-#define FX_SEWLADD7 0x0600003A
-#define FX_SEWLADU7 0x0600003B
+#define FX_CAMERA1 {0x06,0x00,0x00}
+#define FX_CAMERA2 {0x06,0x01,0x01}
+#define FX_CAMERA3 {0x06,0x02,0x02}
+#define FX_CANDO {0x06,0x03,0x03}
+#define FX_CANUP {0x06,0x04,0x04}
+#define FX_CAW1 {0x06,0x05,0x05}
+#define FX_DUST {0x06,0x06,0x06}
+#define FX_HORN1 {0x06,0x07,0x07}
+#define FX_HORN2 {0x06,0x08,0x08}
+#define FX_HORN3 {0x06,0x09,0x09}
+#define FX_LVSFLY {0x06,0x0A,0xFF}
+#define FX_PAP1 {0x06,0x0B,0x0A}
+#define FX_PAP2 {0x06,0x0C,0x0B}
+#define FX_PICK1 {0x06,0x0D,0x0C}
+#define FX_PICK2 {0x06,0x0E,0x0D}
+#define FX_PICK3 {0x06,0x0F,0x0E}
+#define FX_PICK4 {0x06,0x10,0x0F}
+#define FX_PICK5 {0x06,0x11,0x10}
+#define FX_TRAFFIC2 {0x06,0x12,0x11}
+#define FX_TWEET1 {0x06,0x13,0x12}
+#define FX_TWEET2 {0x06,0x14,0x13}
+#define FX_TWEET3 {0x06,0x15,0x14}
+#define FX_TWEET4 {0x06,0x16,0x15}
+#define FX_TWEET5 {0x06,0x17,0x16}
+#define FX_BIN1 {0x06,0x18,0x17}
+#define FX_BIN2 {0x06,0x19,0x18}
+#define FX_BIN3 {0x06,0x1A,0x19}
+#define FX_CAT {0x06,0x1B,0x1A}
+#define FX_COVERON2 {0x06,0x1C,0x1B}
+#define FX_CRATE {0x06,0x1D,0x1C}
+#define FX_DRAIN {0x06,0x1E,0x1D}
+#define FX_HOLE {0x06,0x1F,0x1E}
+#define FX_BODY {0x06,0x20,0x1F}
+#define FX_BOTDN {0x06,0x21,0x20}
+#define FX_BOTUP {0x06,0x22,0x21}
+#define FX_GULP {0x06,0x23,0x22}
+#define FX_LIGHT {0x06,0x24,0x23}
+#define FX_PIKUP {0x06,0x25,0x24}
+#define FX_PAP3 {0x06,0x26,0x25}
+#define FX_PAP4 {0x06,0x27,0x26}
+#define FX_PAP5 {0x06,0x28,0x27}
+#define FX_PISTOL {0x06,0x29,0x28}
+#define FX_TBOX {0x06,0x2A,0x29}
+#define FX_KNOKKNOK {0x06,0x2B,0x2A}
+#define FX_ALBCLO {0x06,0x2C,0x2B}
+#define FX_ALBOP {0x06,0x2D,0x2C}
+#define FX_LADD1 {0x06,0x2E,0x2D}
+#define FX_LADD2 {0x06,0x2F,0x2E}
+#define FX_LADD3 {0x06,0x30,0x2F}
+#define FX_RAT1 {0x06,0x31,0x30}
+#define FX_RAT2 {0x06,0x32,0x31}
+#define FX_SEWSTEP1 {0x06,0x33,0x32}
+#define FX_SEWSTEP2 {0x06,0x34,0x33}
+#define FX_SWATER3 {0x06,0x35,0x34}
+#define FX_DRIP1 {0x06,0x36,0x35}
+#define FX_DRIP2 {0x06,0x37,0x36}
+#define FX_DRIP3 {0x06,0x38,0x37}
+#define FX_SWATER1 {0x06,0x39,0x38}
+#define FX_SEWLADD7 {0x06,0x3A,0xFF}
+#define FX_SEWLADU7 {0x06,0x3B,0x39}
// 60 entities in TXTs, 60 in datafiles.
// room1
#define PARIS1_PAL 0x06010000
@@ -1767,52 +1767,52 @@ namespace Sword1 {
// 8 entities in TXTs, 8 in datafiles.
// paris_2
// sound_fx
-#define FX_BIRD 0x07000000
-#define FX_BIRD2 0x07000001
-#define FX_CARLTON 0x07000002
-#define FX_CARS 0x07000003
-#define FX_DOORTRY 0x07000004
-#define FX_FIESTA 0x07000005
-#define FX_FLATDOOR 0x07000006
-#define FX_HVYVEHR 0x07000007
-#define FX_HVYVEHL 0x07000008
-#define FX_LITEVEHR 0x07000009
-#define FX_LITEVEHL 0x0700000A
-#define FX_FONEUP 0x0700000B
-#define FX_FONEDN 0x0700000C
-#define FX_GEOCCH 0x0700000D
-#define FX_GEOCHAIR 0x0700000E
-#define FX_GEOCHR9 0x0700000F
-#define FX_NICOPEN 0x07000010
-#define FX_NICLOSE 0x07000011
-#define FX_PHONICO1 0x07000012
-#define FX_GRAMOFON 0x07000013
-#define FX_SHOCK1 0x07000014
-#define FX_WINDUP11 0x07000015
-#define FX_FRISK 0x07000016
-#define FX_TRAFFIC3 0x07000017
-#define FX_DESKBELL 0x07000018
-#define FX_KEY13 0x07000019
-#define FX_PAPER6 0x0700001A
-#define FX_PHONEDN2 0x0700001B
-#define FX_PHONEUP2 0x0700001C
-#define FX_PIANO14 0x0700001D
-#define FX_TRYDOR14 0x0700001E
-#define FX_CABCLOSE 0x0700001F
-#define FX_CABOPEN 0x07000020
-#define FX_DORCLOSE 0x07000021
-#define FX_WINDOPEN 0x07000022
-#define FX_COO 0x07000023
-#define FX_COO2 0x07000024
-#define FX_LEDGE1 0x07000025
-#define FX_LEDGE2 0x07000026
-#define FX_BRIEFOFF 0x07000027
-#define FX_BRIEFON 0x07000028
-#define FX_JUMPIN 0x07000029
-#define FX_WARDIN 0x0700002A
-#define FX_WARDOUT 0x0700002B
-#define FX_CLIMBIN 0x0700002C
-#define FX_CLIMBOUT 0x0700002D
+#define FX_BIRD {0x07,0x00,0x00}
+#define FX_BIRD2 {0x07,0x01,0x01}
+#define FX_CARLTON {0x07,0x02,0x02}
+#define FX_CARS {0x07,0x03,0x03}
+#define FX_DOORTRY {0x07,0x04,0x04}
+#define FX_FIESTA {0x07,0x05,0x05}
+#define FX_FLATDOOR {0x07,0x06,0x06}
+#define FX_HVYVEHR {0x07,0x07,0xFF}
+#define FX_HVYVEHL {0x07,0x08,0xFF}
+#define FX_LITEVEHR {0x07,0x09,0xFF}
+#define FX_LITEVEHL {0x07,0x0A,0xFF}
+#define FX_FONEUP {0x07,0x0B,0x07}
+#define FX_FONEDN {0x07,0x0C,0x08}
+#define FX_GEOCCH {0x07,0x0D,0x09}
+#define FX_GEOCHAIR {0x07,0x0E,0x0A}
+#define FX_GEOCHR9 {0x07,0x0F,0x0B}
+#define FX_NICOPEN {0x07,0x10,0x0D}
+#define FX_NICLOSE {0x07,0x11,0x0E}
+#define FX_PHONICO1 {0x07,0x12,0x0F}
+#define FX_GRAMOFON {0x07,0x13,0x10}
+#define FX_SHOCK1 {0x07,0x14,0x11}
+#define FX_WINDUP11 {0x07,0x15,0x12}
+#define FX_FRISK {0x07,0x16,0x13}
+#define FX_TRAFFIC3 {0x07,0x17,0x14}
+#define FX_DESKBELL {0x07,0x18,0x15}
+#define FX_KEY13 {0x07,0x19,0xFF}
+#define FX_PAPER6 {0x07,0x1A,0x16}
+#define FX_PHONEDN2 {0x07,0x1B,0x17}
+#define FX_PHONEUP2 {0x07,0x1C,0x18}
+#define FX_PIANO14 {0x07,0x1D,0x19}
+#define FX_TRYDOR14 {0x07,0x1E,0x1A}
+#define FX_CABCLOSE {0x07,0x1F,0x1B}
+#define FX_CABOPEN {0x07,0x20,0x1C}
+#define FX_DORCLOSE {0x07,0x21,0x1D}
+#define FX_WINDOPEN {0x07,0x22,0x1E}
+#define FX_COO {0x07,0x23,0x1F}
+#define FX_COO2 {0x07,0x24,0x20}
+#define FX_LEDGE1 {0x07,0x25,0x21}
+#define FX_LEDGE2 {0x07,0x26,0x22}
+#define FX_BRIEFOFF {0x07,0x27,0x23}
+#define FX_BRIEFON {0x07,0x28,0x24}
+#define FX_JUMPIN {0x07,0x29,0x25}
+#define FX_WARDIN {0x07,0x2A,0x26}
+#define FX_WARDOUT {0x07,0x2B,0x27}
+#define FX_CLIMBIN {0x07,0x2C,0x28}
+#define FX_CLIMBOUT {0x07,0x2D,0x29}
// 46 entities in TXTs, 46 in datafiles.
// room9
#define PARIS2_PAL 0x07010000
@@ -2349,38 +2349,38 @@ namespace Sword1 {
// 9 entities in TXTs, 9 in datafiles.
// paris_3
// sound_fx
-#define FX_MUESEXT 0x08000000
-#define FX_AIRCON28 0x08000001
-#define FX_SARCO28A 0x08000002
-#define FX_SARCO28B 0x08000003
-#define FX_SARCO28C 0x08000004
-#define FX_TOTEM28A 0x08000005
-#define FX_ALARM 0x08000006
-#define FX_CARABINE 0x08000007
-#define FX_DOOR29 0x08000008
-#define FX_FISHFALL 0x08000009
-#define FX_GDROP29 0x0800000A
-#define FX_GUI_HIT 0x0800000B
-#define FX_GUN1 0x0800000C
-#define FX_ROPEDOWN 0x0800000D
-#define FX_SARCO29 0x0800000E
-#define FX_SMASHGLA 0x0800000F
-#define FX_TOTEM29A 0x08000010
-#define FX_TOTEM29B 0x08000011
-#define FX_HOSPEXT 0x08000012
-#define FX_GRAVEL1 0x08000013
-#define FX_GRAVEL2 0x08000014
-#define FX_HOSPNOIS 0x08000015
-#define FX_CUPBOPEN 0x08000016
-#define FX_CUPBCLOS 0x08000017
-#define FX_KIKSHINY 0x08000018
-#define FX_SHINY 0x08000019
-#define FX_SHINYOFF 0x0800001A
-#define FX_SHINYON 0x0800001B
-#define FX_BLOODPRE 0x0800001C
-#define FX_GUN34 0x0800001D
-#define FX_PULSE2 0x0800001E
-#define FX_PULSE3 0x0800001F
+#define FX_MUESEXT {0x08,0x00,0x00}
+#define FX_AIRCON28 {0x08,0x01,0x01}
+#define FX_SARCO28A {0x08,0x02,0x02}
+#define FX_SARCO28B {0x08,0x03,0x03}
+#define FX_SARCO28C {0x08,0x04,0x04}
+#define FX_TOTEM28A {0x08,0x05,0x05}
+#define FX_ALARM {0x08,0x06,0x06}
+#define FX_CARABINE {0x08,0x07,0x07}
+#define FX_DOOR29 {0x08,0x08,0x08}
+#define FX_FISHFALL {0x08,0x09,0x09}
+#define FX_GDROP29 {0x08,0x0A,0x0A}
+#define FX_GUI_HIT {0x08,0x0B,0x0B}
+#define FX_GUN1 {0x08,0x0C,0x0C}
+#define FX_ROPEDOWN {0x08,0x0D,0x0D}
+#define FX_SARCO29 {0x08,0x0E,0x0E}
+#define FX_SMASHGLA {0x08,0x0F,0x0F}
+#define FX_TOTEM29A {0x08,0x10,0x10}
+#define FX_TOTEM29B {0x08,0x11,0x11}
+#define FX_HOSPEXT {0x08,0x12,0x12}
+#define FX_GRAVEL1 {0x08,0x13,0x13}
+#define FX_GRAVEL2 {0x08,0x14,0x14}
+#define FX_HOSPNOIS {0x08,0x15,0x15}
+#define FX_CUPBOPEN {0x08,0x16,0x16}
+#define FX_CUPBCLOS {0x08,0x17,0x17}
+#define FX_KIKSHINY {0x08,0x18,0xFF}
+#define FX_SHINY {0x08,0x19,0x18}
+#define FX_SHINYOFF {0x08,0x1A,0x19}
+#define FX_SHINYON {0x08,0x1B,0x1A}
+#define FX_BLOODPRE {0x08,0x1C,0x1B}
+#define FX_GUN34 {0x08,0x1D,0x1C}
+#define FX_PULSE2 {0x08,0x1E,0x1D}
+#define FX_PULSE3 {0x08,0x1F,0x1E}
// 32 entities in TXTs, 32 in datafiles.
// benoir
#define MEGABEN 0x08010000
@@ -2794,29 +2794,29 @@ namespace Sword1 {
// 30 entities in TXTs, 30 in datafiles.
// paris_4
// sound_fx
-#define FX_COVDWN 0x09000000
-#define FX_KEYIN 0x09000001
-#define FX_MANOP36 0x09000002
-#define FX_MONTAMB 0x09000003
-#define FX_OOH 0x09000004
-#define FX_PULLUP36 0x09000005
-#define FX_REPLCE36 0x09000006
-#define FX_AMBIEN37 0x09000007
-#define FX_CHAIN37 0x09000008
-#define FX_CHAIN37B 0x09000009
-#define FX_DOOR37 0x0900000A
-#define FX_HOLE37 0x0900000B
-#define FX_KNOCK37 0x0900000C
-#define FX_KNOCK37B 0x0900000D
-#define FX_WINCH37 0x0900000E
-#define FX_AIRCON41 0x0900000F
-#define FX_FONEDN41 0x09000010
-#define FX_FONEUP41 0x09000011
-#define FX_PHONCALL 0x09000012
-#define FX_THERMO1 0x09000013
-#define FX_TAPDRIP 0x09000014
-#define FX_DRIER1 0x09000015
-#define FX_CHURCHFX 0x09000016
+#define FX_COVDWN {0x09,0x00,0xFF}
+#define FX_KEYIN {0x09,0x01,0xFF}
+#define FX_MANOP36 {0x09,0x02,0x00}
+#define FX_MONTAMB {0x09,0x03,0x01}
+#define FX_OOH {0x09,0x04,0x02}
+#define FX_PULLUP36 {0x09,0x05,0x03}
+#define FX_REPLCE36 {0x09,0x06,0x04}
+#define FX_AMBIEN37 {0x09,0x07,0x05}
+#define FX_CHAIN37 {0x09,0x08,0x06}
+#define FX_CHAIN37B {0x09,0x09,0x06}
+#define FX_DOOR37 {0x09,0x0A,0x07}
+#define FX_HOLE37 {0x09,0x0B,0x08}
+#define FX_KNOCK37 {0x09,0x0C,0x09}
+#define FX_KNOCK37B {0x09,0x0D,0x0A}
+#define FX_WINCH37 {0x09,0x0E,0x0B}
+#define FX_AIRCON41 {0x09,0x0F,0x0C}
+#define FX_FONEDN41 {0x09,0x10,0x0D}
+#define FX_FONEUP41 {0x09,0x11,0x0E}
+#define FX_PHONCALL {0x09,0x12,0x0F}
+#define FX_THERMO1 {0x09,0x13,0x10}
+#define FX_TAPDRIP {0x09,0x14,0xFF}
+#define FX_DRIER1 {0x09,0x15,0x11}
+#define FX_CHURCHFX {0x09,0x16,0x12}
// 23 entities in TXTs, 23 in datafiles.
// room36
#define R36SPRPAL 0x09010000
@@ -3302,56 +3302,56 @@ namespace Sword1 {
// 39 entities in TXTs, 39 in datafiles.
// ireland
// sound_fx
-#define FX_EIRBIRD3 0x0A000000
-#define FX_SHOCK2 0x0A000001
-#define FX_EIRBIRD1 0x0A000002
-#define FX_EIRBIRD2 0x0A000003
-#define FX_SWITCH19 0x0A000004
-#define FX_TRAPOPEN 0x0A000005
-#define FX_VIOLIN19 0x0A000006
-#define FX_WHISTLE 0x0A000007
-#define FX_BARFLAP 0x0A000008
-#define FX_DORCLOSE20 0x0A000009
-#define FX_DRINK 0x0A00000A
-#define FX_FITZHIT 0x0A00000B
-#define FX_FITZRUN 0x0A00000C
-#define FX_FITZUP 0x0A00000D
-#define FX_FUSE20 0x0A00000E
-#define FX_PULLPINT 0x0A00000F
-#define FX_SNEEZE1 0x0A000010
-#define FX_SNEEZE2 0x0A000011
-#define FX_WASHER 0x0A000012
-#define FX_CELTAP 0x0A000013
-#define FX_DRIPIRE 0x0A000014
-#define FX_DRIPIRE2 0x0A000015
-#define FX_TAP 0x0A000016
-#define FX_TAP2 0x0A000017
-#define FX_CLIMBHAY 0x0A000018
-#define FX_FARMERGO 0x0A000019
-#define FX_CASTLWAL 0x0A00001A
-#define FX_CLIMBFAL 0x0A00001B
-#define FX_KEYSTEP 0x0A00001C
-#define FX_WIND 0x0A00001D
-#define FX_GEOGOAT 0x0A00001E
-#define FX_GOATBAA 0x0A00001F
-#define FX_GOATCHEW 0x0A000020
-#define FX_GOATDOH 0x0A000021
-#define FX_PLOUGH 0x0A000022
-#define FX_EIRDRIP1 0x0A000023
-#define FX_EIRDRIP2 0x0A000024
-#define FX_LADDWN25 0x0A000025
-#define FX_LADDUP25 0x0A000026
-#define FX_SECDOR25 0x0A000027
-#define FX_SLABFALL 0x0A000028
-#define FX_SLABUP 0x0A000029
-#define FX_TRIGER25 0x0A00002A
-#define FX_WRING 0x0A00002B
-#define FX_LEVER 0x0A00002C
-#define FX_LEVER2 0x0A00002D
-#define FX_RAT3A 0x0A00002E
-#define FX_RAT3B 0x0A00002F
-#define FX_RAT3C 0x0A000030
-#define FX_RAT3D 0x0A000031
+#define FX_EIRBIRD3 {0x0A,0x00,0x00}
+#define FX_SHOCK2 {0x0A,0x01,0x01}
+#define FX_EIRBIRD1 {0x0A,0x02,0x02}
+#define FX_EIRBIRD2 {0x0A,0x03,0x03}
+#define FX_SWITCH19 {0x0A,0x04,0x04}
+#define FX_TRAPOPEN {0x0A,0x05,0x05}
+#define FX_VIOLIN19 {0x0A,0x06,0x06}
+#define FX_WHISTLE {0x0A,0x07,0x07}
+#define FX_BARFLAP {0x0A,0x08,0x08}
+#define FX_DORCLOSE20 {0x0A,0x09,0x09}
+#define FX_DRINK {0x0A,0x0A,0x0A}
+#define FX_FITZHIT {0x0A,0x0B,0x0B}
+#define FX_FITZRUN {0x0A,0x0C,0x0C}
+#define FX_FITZUP {0x0A,0x0D,0x0D}
+#define FX_FUSE20 {0x0A,0x0E,0x0E}
+#define FX_PULLPINT {0x0A,0x0F,0x0F}
+#define FX_SNEEZE1 {0x0A,0x10,0xFF}
+#define FX_SNEEZE2 {0x0A,0x11,0xFF}
+#define FX_WASHER {0x0A,0x12,0x10}
+#define FX_CELTAP {0x0A,0x13,0x11}
+#define FX_DRIPIRE {0x0A,0x14,0xFF}
+#define FX_DRIPIRE2 {0x0A,0x15,0xFF}
+#define FX_TAP {0x0A,0x16,0x12}
+#define FX_TAP2 {0x0A,0x17,0x13}
+#define FX_CLIMBHAY {0x0A,0x18,0x14}
+#define FX_FARMERGO {0x0A,0x19,0x15}
+#define FX_CASTLWAL {0x0A,0x1A,0x16}
+#define FX_CLIMBFAL {0x0A,0x1B,0x17}
+#define FX_KEYSTEP {0x0A,0x1C,0x18}
+#define FX_WIND {0x0A,0x1D,0x19}
+#define FX_GEOGOAT {0x0A,0x1E,0x1A}
+#define FX_GOATBAA {0x0A,0x1F,0x1B}
+#define FX_GOATCHEW {0x0A,0x20,0x1C}
+#define FX_GOATDOH {0x0A,0x21,0x1D}
+#define FX_PLOUGH {0x0A,0x22,0x1E}
+#define FX_EIRDRIP1 {0x0A,0x23,0xFF}
+#define FX_EIRDRIP2 {0x0A,0x24,0xFF}
+#define FX_LADDWN25 {0x0A,0x25,0xFF}
+#define FX_LADDUP25 {0x0A,0x26,0xFF}
+#define FX_SECDOR25 {0x0A,0x27,0x21}
+#define FX_SLABFALL {0x0A,0x28,0x22}
+#define FX_SLABUP {0x0A,0x29,0x23}
+#define FX_TRIGER25 {0x0A,0x2A,0x24}
+#define FX_WRING {0x0A,0x2B,0x25}
+#define FX_LEVER {0x0A,0x2C,0x26}
+#define FX_LEVER2 {0x0A,0x2D,0x27}
+#define FX_RAT3A {0x0A,0x2E,0x28}
+#define FX_RAT3B {0x0A,0x2F,0x28}
+#define FX_RAT3C {0x0A,0x30,0x28}
+#define FX_RAT3D {0x0A,0x31,0x28}
// 50 entities in TXTs, 50 in datafiles.
// room19
#define R19SPRPAL 0x0A010000
@@ -3811,23 +3811,23 @@ namespace Sword1 {
// 16 entities in TXTs, 16 in datafiles.
// spain
// sound_fx
-#define FX_SPNBIRD1 0x0B000000
-#define FX_SPNBIRD2 0x0B000001
-#define FX_AMBIEN56 0x0B000002
-#define FX_DOGS56 0x0B000003
-#define FX_PENDULUM 0x0B000004
-#define FX_CANFALL 0x0B000005
-#define FX_HOSE57 0x0B000006
-#define FX_HOSE57B 0x0B000007
-#define FX_SPAIN 0x0B000008
-#define FX_CHESS 0x0B000009
-#define FX_SECDOR59 0x0B00000A
-#define FX_WINDOW59 0x0B00000B
-#define FX_LIONFALL 0x0B00000C
-#define FX_LIONFAL2 0x0B00000D
-#define FX_TOOTHPUL 0x0B00000E
-#define FX_SECDOR61 0x0B00000F
-#define FX_WELLDRIP 0x0B000010
+#define FX_SPNBIRD1 {0x0B,0x00,0x00}
+#define FX_SPNBIRD2 {0x0B,0x01,0x01}
+#define FX_AMBIEN56 {0x0B,0x02,0x02}
+#define FX_DOGS56 {0x0B,0x03,0x03}
+#define FX_PENDULUM {0x0B,0x04,0x04}
+#define FX_CANFALL {0x0B,0x05,0x05}
+#define FX_HOSE57 {0x0B,0x06,0x06}
+#define FX_HOSE57B {0x0B,0x07,0x07}
+#define FX_SPAIN {0x0B,0x08,0x08}
+#define FX_CHESS {0x0B,0x09,0x09}
+#define FX_SECDOR59 {0x0B,0x0A,0xFF}
+#define FX_WINDOW59 {0x0B,0x0B,0xFF}
+#define FX_LIONFALL {0x0B,0x0C,0x0B}
+#define FX_LIONFAL2 {0x0B,0x0D,0x0C}
+#define FX_TOOTHPUL {0x0B,0x0E,0x0D}
+#define FX_SECDOR61 {0x0B,0x0F,0x0E}
+#define FX_WELLDRIP {0x0B,0x10,0x0F}
// 17 entities in TXTs, 17 in datafiles.
// room56
#define SPAIN_PAL 0x0B010000
@@ -4186,34 +4186,34 @@ namespace Sword1 {
// 8 entities in TXTs, 8 in datafiles.
// syria
// sound_fx
-#define FX_CAMERA45 0x0C000000
-#define FX_SHOCK3 0x0C000001
-#define FX_STALLBEL 0x0C000002
-#define FX_AYUBDOOR 0x0C000003
-#define FX_BALLPLAY 0x0C000004
-#define FX_CATHIT 0x0C000005
-#define FX_MARIB 0x0C000006
-#define FX_NEWTON 0x0C000007
-#define FX_STALLCAT 0x0C000008
-#define FX_STATBREK 0x0C000009
-#define FX_KEYS49 0x0C00000A
-#define FX_MANG1 0x0C00000B
-#define FX_MANG2 0x0C00000C
-#define FX_MANG3 0x0C00000D
-#define FX_UNLOCK49 0x0C00000E
-#define FX_WCCHAIN 0x0C00000F
-#define FX_CUBDOR 0x0C000010
-#define FX_BREKSTIK 0x0C000011
-#define FX_CLIMBDWN 0x0C000012
-#define FX_CRICKET 0x0C000013
-#define FX_GEOFAL54 0x0C000014
-#define FX_KHANDOWN 0x0C000015
-#define FX_RINGPULL 0x0C000016
-#define FX_SECDOR54 0x0C000017
-#define FX_SHOTKHAN 0x0C000018
-#define FX_SYRIWIND 0x0C000019
-#define FX_THUMP1 0x0C00001A
-#define FX_SECDOR55 0x0C00001B
+#define FX_CAMERA45 {0x0C,0x00,0xFF}
+#define FX_SHOCK3 {0x0C,0x01,0x00}
+#define FX_STALLBEL {0x0C,0x02,0x01}
+#define FX_AYUBDOOR {0x0C,0x03,0x02}
+#define FX_BALLPLAY {0x0C,0x04,0x03}
+#define FX_CATHIT {0x0C,0x05,0x04}
+#define FX_MARIB {0x0C,0x06,0x05}
+#define FX_NEWTON {0x0C,0x07,0x06}
+#define FX_STALLCAT {0x0C,0x08,0x07}
+#define FX_STATBREK {0x0C,0x09,0x08}
+#define FX_KEYS49 {0x0C,0x0A,0x09}
+#define FX_MANG1 {0x0C,0x0B,0x0A}
+#define FX_MANG2 {0x0C,0x0C,0x0B}
+#define FX_MANG3 {0x0C,0x0D,0x0C}
+#define FX_UNLOCK49 {0x0C,0x0E,0x0D}
+#define FX_WCCHAIN {0x0C,0x0F,0x0E}
+#define FX_CUBDOR {0x0C,0x10,0x0F}
+#define FX_BREKSTIK {0x0C,0x11,0x10}
+#define FX_CLIMBDWN {0x0C,0x12,0x11}
+#define FX_CRICKET {0x0C,0x13,0x12}
+#define FX_GEOFAL54 {0x0C,0x14,0x13}
+#define FX_KHANDOWN {0x0C,0x15,0x14}
+#define FX_RINGPULL {0x0C,0x16,0x15}
+#define FX_SECDOR54 {0x0C,0x17,0x16}
+#define FX_SHOTKHAN {0x0C,0x18,0x17}
+#define FX_SYRIWIND {0x0C,0x19,0x18}
+#define FX_THUMP1 {0x0C,0x1A,0x19}
+#define FX_SECDOR55 {0x0C,0x1B,0x1A}
// 28 entities in TXTs, 28 in datafiles.
// duane
#define DUANE_MEGA 0x0C010000
@@ -4578,19 +4578,19 @@ namespace Sword1 {
// 37 entities in TXTs, 37 in datafiles.
// train
// sound_fx
-#define FX_SHOCK63 0x0D000000
-#define FX_TRAINEXT 0x0D000001
-#define FX_TRAININT 0x0D000002
-#define FX_DOOR65 0x0D000003
-#define FX_WIND66 0x0D000004
-#define FX_WINDOW66 0x0D000005
-#define FX_BRAKES 0x0D000006
-#define FX_DOOR69 0x0D000007
-#define FX_EKSHOOT 0x0D000008
-#define FX_FIGHT69 0x0D000009
-#define FX_PNEUMO69 0x0D00000A
-#define FX_TICK69 0x0D00000B
-#define FX_TRNPASS 0x0D00000C
+#define FX_SHOCK63 {0x0D,0x00,0x00}
+#define FX_TRAINEXT {0x0D,0x01,0x01}
+#define FX_TRAININT {0x0D,0x02,0x02}
+#define FX_DOOR65 {0x0D,0x03,0x03}
+#define FX_WIND66 {0x0D,0x04,0x04}
+#define FX_WINDOW66 {0x0D,0x05,0x05}
+#define FX_BRAKES {0x0D,0x06,0x06}
+#define FX_DOOR69 {0x0D,0x07,0x07}
+#define FX_EKSHOOT {0x0D,0x08,0x08}
+#define FX_FIGHT69 {0x0D,0x09,0xFF}
+#define FX_PNEUMO69 {0x0D,0x0A,0x09}
+#define FX_TICK69 {0x0D,0x0B,0x0A}
+#define FX_TRNPASS {0x0D,0x0C,0x0B}
// 13 entities in TXTs, 13 in datafiles.
// room63
#define TRAIN_PAL 0x0D010000
@@ -4828,33 +4828,33 @@ namespace Sword1 {
// 57 entities in TXTs, 57 in datafiles.
// scotland
// sound_fx
-#define FX_WIND71 0x0E000000
-#define FX_GUST71 0x0E000001
-#define FX_OWL71A 0x0E000002
-#define FX_OWL71B 0x0E000003
-#define FX_COG72A 0x0E000004
-#define FX_PING 0x0E000005
-#define FX_RUMMAGE1 0x0E000006
-#define FX_RUMMAGE2 0x0E000007
-#define FX_SECDOR72 0x0E000008
-#define FX_CHANT 0x0E000009
-#define FX_DAGGER1 0x0E00000A
-#define FX_GDROP73 0x0E00000B
-#define FX_GUNPOWDR 0x0E00000C
-#define FX_STAFF 0x0E00000D
-#define FX_TORCH73 0x0E00000E
-#define FX_BAPHAMB 0x0E00000F
-#define FX_FIGHT1 0x0E000010
-#define FX_REFORGE2 0x0E000011
-#define FX_ROSSODIE 0x0E000012
-#define FX_GKSWORD 0x0E000013
-#define FX_REFORGE1 0x0E000014
-#define FX_REFORGE4 0x0E000015
-#define FX_CHOKE1 0x0E000016
-#define FX_CHOKE2 0x0E000017
-#define FX_EKDIES 0x0E000018
-#define FX_FIGHT2 0x0E000019
-#define FX_GUN79 0x0E00001A
+#define FX_WIND71 {0x0E,0x00,0x00}
+#define FX_GUST71 {0x0E,0x01,0x01}
+#define FX_OWL71A {0x0E,0x02,0x02}
+#define FX_OWL71B {0x0E,0x03,0x03}
+#define FX_COG72A {0x0E,0x04,0x04}
+#define FX_PING {0x0E,0x05,0x05}
+#define FX_RUMMAGE1 {0x0E,0x06,0x06}
+#define FX_RUMMAGE2 {0x0E,0x07,0x07}
+#define FX_SECDOR72 {0x0E,0x08,0x08}
+#define FX_CHANT {0x0E,0x09,0xFF}
+#define FX_DAGGER1 {0x0E,0x0A,0x09}
+#define FX_GDROP73 {0x0E,0x0B,0xFF}
+#define FX_GUNPOWDR {0x0E,0x0C,0x0A}
+#define FX_STAFF {0x0E,0x0D,0xFF}
+#define FX_TORCH73 {0x0E,0x0E,0x0B}
+#define FX_BAPHAMB {0x0E,0x0F,0xFF}
+#define FX_FIGHT1 {0x0E,0x10,0xFF}
+#define FX_REFORGE2 {0x0E,0x11,0xFF}
+#define FX_ROSSODIE {0x0E,0x12,0x0C}
+#define FX_GKSWORD {0x0E,0x13,0xFF}
+#define FX_REFORGE1 {0x0E,0x14,0xFF}
+#define FX_REFORGE4 {0x0E,0x15,0xFF}
+#define FX_CHOKE1 {0x0E,0x16,0x0D}
+#define FX_CHOKE2 {0x0E,0x17,0x0E}
+#define FX_EKDIES {0x0E,0x18,0xFF}
+#define FX_FIGHT2 {0x0E,0x19,0x0F}
+#define FX_GUN79 {0x0E,0x1A,0x10}
// 27 entities in TXTs, 27 in datafiles.
// room71
#define R71L0 0x0E010000
diff --git a/engines/sword2/animation.cpp b/engines/sword2/animation.cpp
index 80b4809722..e77ae98163 100644
--- a/engines/sword2/animation.cpp
+++ b/engines/sword2/animation.cpp
@@ -40,6 +40,11 @@
#include "gui/message.h"
+#include "video/smk_decoder.h"
+#include "video/psx_decoder.h"
+
+#include "engines/util.h"
+
namespace Sword2 {
///////////////////////////////////////////////////////////////////////////////
@@ -66,6 +71,10 @@ MoviePlayer::~MoviePlayer() {
* @param id the id of the file
*/
bool MoviePlayer::load(const char *name) {
+ // This happens when quitting during the "eye" cutscene.
+ if (_vm->shouldQuit())
+ return false;
+
if (_decoderType == kVideoDecoderDXA)
_bgSoundStream = Audio::SeekableAudioStream::openStreamFile(name);
else
@@ -81,16 +90,26 @@ bool MoviePlayer::load(const char *name) {
case kVideoDecoderSMK:
filename = Common::String::format("%s.smk", name);
break;
+ case kVideoDecoderPSX:
+ filename = Common::String::format("%s.str", name);
+
+ // Need to switch to true color
+ initGraphics(640, 480, true, 0);
+
+ // Need to load here in case it fails in which case we'd need
+ // to go back to paletted mode
+ if (_decoder->loadFile(filename)) {
+ return true;
+ } else {
+ initGraphics(640, 480, true);
+ return false;
+ }
}
return _decoder->loadFile(filename.c_str());
}
void MoviePlayer::play(MovieText *movieTexts, uint32 numMovieTexts, uint32 leadIn, uint32 leadOut) {
- // This happens when quitting during the "eye" cutscene.
- if (_vm->shouldQuit())
- return;
-
_leadOutFrame = _decoder->getFrameCount();
if (_leadOutFrame > 60)
_leadOutFrame -= 60;
@@ -120,6 +139,11 @@ void MoviePlayer::play(MovieText *movieTexts, uint32 numMovieTexts, uint32 leadI
while (_snd->isSoundHandleActive(*_bgSoundHandle))
_system->delayMillis(100);
+
+ if (_decoderType == kVideoDecoderPSX) {
+ // Need to jump back to paletted color
+ initGraphics(640, 480, true);
+ }
}
void MoviePlayer::openTextObject(uint32 index) {
@@ -165,7 +189,7 @@ void MoviePlayer::openTextObject(uint32 index) {
}
}
-void MoviePlayer::closeTextObject(uint32 index, byte *screen, uint16 pitch) {
+void MoviePlayer::closeTextObject(uint32 index, Graphics::Surface *screen, uint16 pitch) {
if (index < _numMovieTexts) {
MovieText *text = &_movieTexts[index];
@@ -180,23 +204,23 @@ void MoviePlayer::closeTextObject(uint32 index, byte *screen, uint16 pitch) {
int frameWidth = _decoder->getWidth();
int frameHeight = _decoder->getHeight();
+
+ if (_decoderType == kVideoDecoderPSX)
+ frameHeight *= 2;
+
int frameX = (_system->getWidth() - frameWidth) / 2;
int frameY = (_system->getHeight() - frameHeight) / 2;
- byte black = findBlackPalIndex();
-
- byte *dst = screen + _textY * pitch;
+ uint32 black = getBlackColor();
for (int y = 0; y < text->_textSprite.h; y++) {
if (_textY + y < frameY || _textY + y >= frameY + frameHeight) {
- memset(dst + _textX, black, text->_textSprite.w);
+ screen->hLine(_textX, _textY + y, _textX + text->_textSprite.w, black);
} else {
if (frameX > _textX)
- memset(dst + _textX, black, frameX - _textX);
+ screen->hLine(_textX, _textY + y, frameX, black);
if (frameX + frameWidth < _textX + text->_textSprite.w)
- memset(dst + frameX + frameWidth, black, _textX + text->_textSprite.w - (frameX + frameWidth));
+ screen->hLine(frameX + frameWidth, _textY + y, text->_textSprite.w, black);
}
-
- dst += pitch;
}
}
@@ -206,11 +230,24 @@ void MoviePlayer::closeTextObject(uint32 index, byte *screen, uint16 pitch) {
}
}
-void MoviePlayer::drawTextObject(uint32 index, byte *screen, uint16 pitch) {
+#define PUT_PIXEL(c) \
+ switch (screen->format.bytesPerPixel) { \
+ case 1: \
+ *dst = (c); \
+ break; \
+ case 2: \
+ WRITE_UINT16(dst, (c)); \
+ break; \
+ case 4: \
+ WRITE_UINT32(dst, (c)); \
+ break; \
+ }
+
+void MoviePlayer::drawTextObject(uint32 index, Graphics::Surface *screen, uint16 pitch) {
MovieText *text = &_movieTexts[index];
- byte white = findWhitePalIndex();
- byte black = findBlackPalIndex();
+ uint32 white = getWhiteColor();
+ uint32 black = getBlackColor();
if (text->_textMem && _textSurface) {
byte *src = text->_textSprite.data;
@@ -226,17 +263,20 @@ void MoviePlayer::drawTextObject(uint32 index, byte *screen, uint16 pitch) {
src = psxSpriteBuffer;
}
- byte *dst = screen + _textY * pitch + _textX;
-
for (int y = 0; y < height; y++) {
+ byte *dst = (byte *)screen->getBasePtr(_textX, _textY + y);
+
for (int x = 0; x < width; x++) {
- if (src[x] == 1)
- dst[x] = black;
- else if (src[x] == 255)
- dst[x] = white;
+ if (src[x] == 1) {
+ PUT_PIXEL(black);
+ } else if (src[x] == 255) {
+ PUT_PIXEL(white);
+ }
+
+ dst += screen->format.bytesPerPixel;
}
+
src += width;
- dst += pitch;
}
// Free buffer used to resize psx sprite
@@ -245,7 +285,9 @@ void MoviePlayer::drawTextObject(uint32 index, byte *screen, uint16 pitch) {
}
}
-void MoviePlayer::performPostProcessing(byte *screen, uint16 pitch) {
+#undef PUT_PIXEL
+
+void MoviePlayer::performPostProcessing(Graphics::Surface *screen, uint16 pitch) {
MovieText *text;
int frame = _decoder->getCurFrame();
@@ -286,8 +328,12 @@ bool MoviePlayer::playVideo() {
while (!_vm->shouldQuit() && !_decoder->endOfVideo()) {
if (_decoder->needsUpdate()) {
const Graphics::Surface *frame = _decoder->decodeNextFrame();
- if (frame)
- _vm->_system->copyRectToScreen((byte *)frame->pixels, frame->pitch, x, y, frame->w, frame->h);
+ if (frame) {
+ if (_decoderType == kVideoDecoderPSX)
+ drawFramePSX(frame);
+ else
+ _vm->_system->copyRectToScreen((byte *)frame->pixels, frame->pitch, x, y, frame->w, frame->h);
+ }
if (_decoder->hasDirtyPalette()) {
_decoder->setSystemPalette();
@@ -319,7 +365,7 @@ bool MoviePlayer::playVideo() {
}
Graphics::Surface *screen = _vm->_system->lockScreen();
- performPostProcessing((byte *)screen->pixels, screen->pitch);
+ performPostProcessing(screen, screen->pitch);
_vm->_system->unlockScreen();
_vm->_system->updateScreen();
}
@@ -335,12 +381,29 @@ bool MoviePlayer::playVideo() {
return !_vm->shouldQuit();
}
-byte MoviePlayer::findBlackPalIndex() {
- return _black;
+uint32 MoviePlayer::getBlackColor() {
+ return (_decoderType == kVideoDecoderPSX) ? g_system->getScreenFormat().RGBToColor(0x00, 0x00, 0x00) : _black;
}
-byte MoviePlayer::findWhitePalIndex() {
- return _white;
+uint32 MoviePlayer::getWhiteColor() {
+ return (_decoderType == kVideoDecoderPSX) ? g_system->getScreenFormat().RGBToColor(0xFF, 0xFF, 0xFF) : _white;
+}
+
+void MoviePlayer::drawFramePSX(const Graphics::Surface *frame) {
+ // The PSX videos have half resolution
+
+ Graphics::Surface scaledFrame;
+ scaledFrame.create(frame->w, frame->h * 2, frame->format);
+
+ for (int y = 0; y < scaledFrame.h; y++)
+ memcpy(scaledFrame.getBasePtr(0, y), frame->getBasePtr(0, y / 2), scaledFrame.w * scaledFrame.format.bytesPerPixel);
+
+ uint16 x = (g_system->getWidth() - scaledFrame.w) / 2;
+ uint16 y = (g_system->getHeight() - scaledFrame.h) / 2;
+
+ _vm->_system->copyRectToScreen((byte *)scaledFrame.pixels, scaledFrame.pitch, x, y, scaledFrame.w, scaledFrame.h);
+
+ scaledFrame.free();
}
DXADecoderWithSound::DXADecoderWithSound(Audio::Mixer *mixer, Audio::SoundHandle *bgSoundHandle)
@@ -358,10 +421,23 @@ uint32 DXADecoderWithSound::getElapsedTime() const {
// Factory function for creating the appropriate cutscene player
///////////////////////////////////////////////////////////////////////////////
-MoviePlayer *makeMoviePlayer(const char *name, Sword2Engine *vm, Audio::Mixer *snd, OSystem *system) {
+MoviePlayer *makeMoviePlayer(const char *name, Sword2Engine *vm, Audio::Mixer *snd, OSystem *system, uint32 frameCount) {
Common::String filename;
Audio::SoundHandle *bgSoundHandle = new Audio::SoundHandle;
+ filename = Common::String::format("%s.str", name);
+
+ if (Common::File::exists(filename)) {
+#ifdef USE_RGB_COLOR
+ Video::VideoDecoder *psxDecoder = new Video::PSXStreamDecoder(Video::PSXStreamDecoder::kCD2x, frameCount);
+ return new MoviePlayer(vm, snd, system, bgSoundHandle, psxDecoder, kVideoDecoderPSX);
+#else
+ GUI::MessageDialog dialog(_("PSX cutscenes found but ScummVM has been built without RGB color support"), _("OK"));
+ dialog.runModal();
+ return NULL;
+#endif
+ }
+
filename = Common::String::format("%s.smk", name);
if (Common::File::exists(filename)) {
diff --git a/engines/sword2/animation.h b/engines/sword2/animation.h
index 1f5fced03b..3ef8dac754 100644
--- a/engines/sword2/animation.h
+++ b/engines/sword2/animation.h
@@ -26,7 +26,6 @@
#define SWORD2_ANIMATION_H
#include "video/dxa_decoder.h"
-#include "video/smk_decoder.h"
#include "video/video_decoder.h"
#include "audio/mixer.h"
@@ -36,7 +35,8 @@ namespace Sword2 {
enum DecoderType {
kVideoDecoderDXA = 0,
- kVideoDecoderSMK = 1
+ kVideoDecoderSMK = 1,
+ kVideoDecoderPSX = 2
};
struct MovieText {
@@ -93,18 +93,19 @@ protected:
uint32 _leadOut;
int _leadOutFrame;
- void performPostProcessing(byte *screen, uint16 pitch);
+ void performPostProcessing(Graphics::Surface *screen, uint16 pitch);
bool playVideo();
+ void drawFramePSX(const Graphics::Surface *frame);
void openTextObject(uint32 index);
- void closeTextObject(uint32 index, byte *screen, uint16 pitch);
- void drawTextObject(uint32 index, byte *screen, uint16 pitch);
+ void closeTextObject(uint32 index, Graphics::Surface *screen, uint16 pitch);
+ void drawTextObject(uint32 index, Graphics::Surface *screen, uint16 pitch);
- byte findBlackPalIndex();
- byte findWhitePalIndex();
+ uint32 getBlackColor();
+ uint32 getWhiteColor();
};
-MoviePlayer *makeMoviePlayer(const char *name, Sword2Engine *vm, Audio::Mixer *snd, OSystem *system);
+MoviePlayer *makeMoviePlayer(const char *name, Sword2Engine *vm, Audio::Mixer *snd, OSystem *system, uint32 frameCount);
} // End of namespace Sword2
diff --git a/engines/sword2/console.cpp b/engines/sword2/console.cpp
index 957b2431e0..28e2e8ce7b 100644
--- a/engines/sword2/console.cpp
+++ b/engines/sword2/console.cpp
@@ -446,7 +446,7 @@ bool Debugger::Cmd_ResLook(int argc, const char **argv) {
DebugPrintf("<menu icon> %s\n", _vm->_resman->fetchName(res));
break;
default:
- DebugPrintf("unrecognised fileType %d\n", type);
+ DebugPrintf("unrecognized fileType %d\n", type);
break;
}
diff --git a/engines/sword2/function.cpp b/engines/sword2/function.cpp
index 60ee6176a4..836b252d6c 100644
--- a/engines/sword2/function.cpp
+++ b/engines/sword2/function.cpp
@@ -2137,7 +2137,9 @@ int32 Logic::fnPlaySequence(int32 *params) {
// pause sfx during sequence
_vm->_sound->pauseFx();
- _moviePlayer = makeMoviePlayer(filename, _vm, _vm->_mixer, _vm->_system);
+ uint32 frameCount = Sword2Engine::isPsx() ? params[1] : 0;
+
+ _moviePlayer = makeMoviePlayer(filename, _vm, _vm->_mixer, _vm->_system, frameCount);
if (_moviePlayer && _moviePlayer->load(filename)) {
_moviePlayer->play(_sequenceTextList, _sequenceTextLines, _smackerLeadIn, _smackerLeadOut);
diff --git a/engines/sword2/music.cpp b/engines/sword2/music.cpp
index 1bb08fd36f..62fb3d244d 100644
--- a/engines/sword2/music.cpp
+++ b/engines/sword2/music.cpp
@@ -115,7 +115,7 @@ static Audio::AudioStream *getAudioStream(SoundFileHandle *fh, const char *base,
fh->idxLen = fh->file.readUint32LE();
fh->file.seek(entrySize * 4);
- fh->idxTab = (uint32*)malloc(fh->idxLen * 3 * sizeof(uint32));
+ fh->idxTab = (uint32 *)malloc(fh->idxLen * 3 * sizeof(uint32));
for (uint32 cnt = 0; cnt < fh->idxLen; cnt++) {
fh->idxTab[cnt * 3 + 0] = fh->file.readUint32LE();
fh->idxTab[cnt * 3 + 1] = fh->file.readUint32LE();
@@ -160,19 +160,19 @@ static Audio::AudioStream *getAudioStream(SoundFileHandle *fh, const char *base,
return makeCLUStream(&fh->file, enc_len);
#ifdef USE_MAD
case kMP3Mode: {
- Common::SafeSubReadStream *tmp = new Common::SafeSubReadStream(&fh->file, pos, pos + enc_len);
+ Common::SafeSeekableSubReadStream *tmp = new Common::SafeSeekableSubReadStream(&fh->file, pos, pos + enc_len);
return Audio::makeMP3Stream(tmp, DisposeAfterUse::YES);
}
#endif
#ifdef USE_VORBIS
case kVorbisMode: {
- Common::SafeSubReadStream *tmp = new Common::SafeSubReadStream(&fh->file, pos, pos + enc_len);
+ Common::SafeSeekableSubReadStream *tmp = new Common::SafeSeekableSubReadStream(&fh->file, pos, pos + enc_len);
return Audio::makeVorbisStream(tmp, DisposeAfterUse::YES);
}
#endif
#ifdef USE_FLAC
case kFLACMode: {
- Common::SafeSubReadStream *tmp = new Common::SafeSubReadStream(&fh->file, pos, pos + enc_len);
+ Common::SafeSeekableSubReadStream *tmp = new Common::SafeSeekableSubReadStream(&fh->file, pos, pos + enc_len);
return Audio::makeFLACStream(tmp, DisposeAfterUse::YES);
}
#endif
diff --git a/engines/sword2/sprite.cpp b/engines/sword2/sprite.cpp
index 8d260947f1..cb0923cc2f 100644
--- a/engines/sword2/sprite.cpp
+++ b/engines/sword2/sprite.cpp
@@ -500,6 +500,16 @@ int32 Screen::drawSprite(SpriteInfo *s) {
recomposePsxSprite(s);
}
+ // If the height is not an even value, fix it.
+ // Apparently it's a problem in the data of a few sprites
+ // of the PSX version. This should fix an evident problem
+ // in the foyer at the beginning of the game, where a line
+ // of pixels is missing near the stairs. But it should also
+ // fix a more subtle one in the glease gallery and in quaramonte
+ // police office.
+ if (s->h % 2)
+ s->h++;
+
freeSprite = true;
byte *tempBuf = (byte *)malloc(s->w * s->h * 2);
memset(tempBuf, 0, s->w * s->h * 2);
@@ -762,14 +772,18 @@ int32 Screen::drawSprite(SpriteInfo *s) {
src = sprite + rs.top * srcPitch + rs.left;
dst = _buffer + _screenWide * rd.top + rd.left;
- if (s->type & RDSPR_BLEND && !Sword2Engine::isPsx()) { // Blending is unavailable in PSX version
+ if (s->type & RDSPR_BLEND) {
// The original code had two different blending cases. One for
// s->blend & 0x01 and one for s->blend & 0x02. However, the
// only values that actually appear in the cluster files are
// 0, 513 and 1025 so the s->blend & 0x02 case was never used.
// Which is just as well since that code made no sense to me.
- if (!(_renderCaps & RDBLTFX_SPRITEBLEND)) {
+ // TODO: In PSX version, blending is done through hardware transparency.
+ // The only correct way to simulate this would be using 16-bit mode.
+ // As this is not yet available for this engine, fake transparency is used
+ // as placeholder.
+ if (!(_renderCaps & RDBLTFX_SPRITEBLEND) || Sword2Engine::isPsx()) {
for (i = 0; i < rs.height(); i++) {
for (j = 0; j < rs.width(); j++) {
if (src[j] && ((i & 1) == (j & 1)))
diff --git a/engines/sword2/sword2.cpp b/engines/sword2/sword2.cpp
index b4d4f52a12..c395186570 100644
--- a/engines/sword2/sword2.cpp
+++ b/engines/sword2/sword2.cpp
@@ -25,9 +25,10 @@
#include "base/plugins.h"
#include "common/config-manager.h"
+#include "common/events.h"
#include "common/file.h"
#include "common/fs.h"
-#include "common/events.h"
+#include "common/gui_options.h"
#include "common/savefile.h"
#include "common/system.h"
#include "common/textconsole.h"
@@ -145,7 +146,7 @@ GameList Sword2MetaEngine::detectGames(const Common::FSList &fslist) const {
if (0 == scumm_stricmp(g->detectname, fileName)) {
// Match found, add to list of candidates, then abort inner loop.
- detectedGames.push_back(GameDescriptor(g->gameid, g->description, Common::UNK_LANG, Common::kPlatformUnknown, GUIO1(GUIO_NOMIDI)));
+ detectedGames.push_back(GameDescriptor(g->gameid, g->description, Common::UNK_LANG, Common::kPlatformUnknown, GUIO2(GUIO_NOMIDI, GUIO_NOASPECT)));
break;
}
}
@@ -255,6 +256,7 @@ Sword2Engine::Sword2Engine(OSystem *syst) : Engine(syst), _rnd("sword2") {
SearchMan.addSubDirectoryMatching(gameDataDir, "sword2");
SearchMan.addSubDirectoryMatching(gameDataDir, "video");
SearchMan.addSubDirectoryMatching(gameDataDir, "smacks");
+ SearchMan.addSubDirectoryMatching(gameDataDir, "streams"); // PSX video
if (!scumm_stricmp(ConfMan.get("gameid").c_str(), "sword2demo") || !scumm_stricmp(ConfMan.get("gameid").c_str(), "sword2psxdemo"))
_features = GF_DEMO;
diff --git a/engines/sword25/detection_tables.h b/engines/sword25/detection_tables.h
index 5e0473dee5..94a5b55fed 100644
--- a/engines/sword25/detection_tables.h
+++ b/engines/sword25/detection_tables.h
@@ -30,7 +30,7 @@ static const ADGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformUnknown,
ADGF_UNSTABLE,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
{
"sword25",
@@ -39,7 +39,7 @@ static const ADGameDescription gameDescriptions[] = {
Common::FR_FRA,
Common::kPlatformUnknown,
ADGF_UNSTABLE,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
{
"sword25",
@@ -48,16 +48,16 @@ static const ADGameDescription gameDescriptions[] = {
Common::DE_DEU,
Common::kPlatformUnknown,
ADGF_UNSTABLE,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
{
"sword25",
"",
AD_ENTRY1s("lang_hr.b25c", "e881054d1f8ec1e527422fc521c25405", 1273217),
- Common::HU_HUN,
+ Common::HR_HRV,
Common::kPlatformUnknown,
ADGF_UNSTABLE,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
{
"sword25",
@@ -66,7 +66,7 @@ static const ADGameDescription gameDescriptions[] = {
Common::IT_ITA,
Common::kPlatformUnknown,
ADGF_UNSTABLE,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
{
"sword25",
@@ -75,7 +75,7 @@ static const ADGameDescription gameDescriptions[] = {
Common::PL_POL,
Common::kPlatformUnknown,
ADGF_UNSTABLE,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
{
"sword25",
@@ -84,7 +84,7 @@ static const ADGameDescription gameDescriptions[] = {
Common::PT_BRA,
Common::kPlatformUnknown,
ADGF_UNSTABLE,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
{
"sword25",
@@ -93,7 +93,7 @@ static const ADGameDescription gameDescriptions[] = {
Common::RU_RUS,
Common::kPlatformUnknown,
ADGF_UNSTABLE,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
{
"sword25",
@@ -102,7 +102,18 @@ static const ADGameDescription gameDescriptions[] = {
Common::ES_ESP,
Common::kPlatformUnknown,
ADGF_UNSTABLE,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
+ },
+ // Hungarian "psylog" version.
+ // Submitted by goodoldgeorg in bug report #3428644.
+ {
+ "sword25",
+ "psylog version",
+ AD_ENTRY1s("lang_hu.b25c", "7de51a3b4926a192549e75b1a7d81667", 1864915),
+ Common::HU_HUN,
+ Common::kPlatformUnknown,
+ ADGF_UNSTABLE,
+ GUIO1(GUIO_NOASPECT)
},
// Extracted version
@@ -116,7 +127,7 @@ static const ADGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformUnknown,
GF_EXTRACTED | ADGF_UNSTABLE,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
AD_TABLE_END_MARKER
};
diff --git a/engines/sword25/gfx/image/art.cpp b/engines/sword25/gfx/image/art.cpp
index 2ba102e779..3944a207c8 100644
--- a/engines/sword25/gfx/image/art.cpp
+++ b/engines/sword25/gfx/image/art.cpp
@@ -328,18 +328,6 @@ static void art_vpath_render_bez(ArtVpath **p_vpath, int *pn, int *pn_max,
double x2, double y2,
double x3, double y3,
double flatness) {
- double x3_0, y3_0;
- double z3_0_dot;
- double z1_dot, z2_dot;
- double z1_perp, z2_perp;
- double max_perp_sq;
-
- double x_m, y_m;
- double xa1, ya1;
- double xa2, ya2;
- double xb1, yb1;
- double xb2, yb2;
-
/* It's possible to optimize this routine a fair amount.
First, once the _dot conditions are met, they will also be met in
@@ -363,11 +351,13 @@ static void art_vpath_render_bez(ArtVpath **p_vpath, int *pn, int *pn_max,
*/
- x3_0 = x3 - x0;
- y3_0 = y3 - y0;
+ bool subDivide = false;
+
+ double x3_0 = x3 - x0;
+ double y3_0 = y3 - y0;
- /* z3_0_dot is dist z0-z3 squared */
- z3_0_dot = x3_0 * x3_0 + y3_0 * y3_0;
+ // z3_0_dot is dist z0-z3 squared
+ double z3_0_dot = x3_0 * x3_0 + y3_0 * y3_0;
if (z3_0_dot < 0.001) {
/* if start and end point are almost identical, the flatness tests
@@ -375,72 +365,68 @@ static void art_vpath_render_bez(ArtVpath **p_vpath, int *pn, int *pn_max,
* the other two control points are the same as the start point,
* too.
*/
- if (hypot(x1 - x0, y1 - y0) < 0.001
- && hypot(x2 - x0, y2 - y0) < 0.001)
- goto nosubdivide;
- else
- goto subdivide;
- }
-
- /* we can avoid subdivision if:
-
- z1 has distance no more than flatness from the z0-z3 line
-
- z1 is no more z0'ward than flatness past z0-z3
-
- z1 is more z0'ward than z3'ward on the line traversing z0-z3
-
- and correspondingly for z2 */
-
- /* perp is distance from line, multiplied by dist z0-z3 */
- max_perp_sq = flatness * flatness * z3_0_dot;
-
- z1_perp = (y1 - y0) * x3_0 - (x1 - x0) * y3_0;
- if (z1_perp * z1_perp > max_perp_sq)
- goto subdivide;
+ if (!(hypot(x1 - x0, y1 - y0) < 0.001
+ && hypot(x2 - x0, y2 - y0) < 0.001))
+ subDivide = true;
+ } else {
+ /* we can avoid subdivision if:
- z2_perp = (y3 - y2) * x3_0 - (x3 - x2) * y3_0;
- if (z2_perp * z2_perp > max_perp_sq)
- goto subdivide;
+ z1 has distance no more than flatness from the z0-z3 line
- z1_dot = (x1 - x0) * x3_0 + (y1 - y0) * y3_0;
- if (z1_dot < 0 && z1_dot * z1_dot > max_perp_sq)
- goto subdivide;
+ z1 is no more z0'ward than flatness past z0-z3
- z2_dot = (x3 - x2) * x3_0 + (y3 - y2) * y3_0;
- if (z2_dot < 0 && z2_dot * z2_dot > max_perp_sq)
- goto subdivide;
+ z1 is more z0'ward than z3'ward on the line traversing z0-z3
- if (z1_dot + z1_dot > z3_0_dot)
- goto subdivide;
+ and correspondingly for z2 */
- if (z2_dot + z2_dot > z3_0_dot)
- goto subdivide;
+ // perp is distance from line, multiplied by dist z0-z3
+ double max_perp_sq = flatness * flatness * z3_0_dot;
+ double z1_perp = (y1 - y0) * x3_0 - (x1 - x0) * y3_0;
+ if (z1_perp * z1_perp > max_perp_sq) {
+ subDivide = true;
+ } else {
+ double z2_perp = (y3 - y2) * x3_0 - (x3 - x2) * y3_0;
+ if (z2_perp * z2_perp > max_perp_sq) {
+ subDivide = true;
+ } else {
+ double z1_dot = (x1 - x0) * x3_0 + (y1 - y0) * y3_0;
+ if (z1_dot < 0 && z1_dot * z1_dot > max_perp_sq) {
+ subDivide = true;
+ } else {
+ double z2_dot = (x3 - x2) * x3_0 + (y3 - y2) * y3_0;
+ if (z2_dot < 0 && z2_dot * z2_dot > max_perp_sq)
+ subDivide = true;
+ else if (z1_dot + z1_dot > z3_0_dot)
+ subDivide = true;
+ else if (z2_dot + z2_dot > z3_0_dot)
+ subDivide = true;
+ }
+ }
+ }
+ }
-nosubdivide:
- /* don't subdivide */
- art_vpath_add_point(p_vpath, pn, pn_max,
- ART_LINETO, x3, y3);
- return;
-
-subdivide:
-
- xa1 = (x0 + x1) * 0.5;
- ya1 = (y0 + y1) * 0.5;
- xa2 = (x0 + 2 * x1 + x2) * 0.25;
- ya2 = (y0 + 2 * y1 + y2) * 0.25;
- xb1 = (x1 + 2 * x2 + x3) * 0.25;
- yb1 = (y1 + 2 * y2 + y3) * 0.25;
- xb2 = (x2 + x3) * 0.5;
- yb2 = (y2 + y3) * 0.5;
- x_m = (xa2 + xb1) * 0.5;
- y_m = (ya2 + yb1) * 0.5;
-
- art_vpath_render_bez(p_vpath, pn, pn_max,
- x0, y0, xa1, ya1, xa2, ya2, x_m, y_m, flatness);
- art_vpath_render_bez(p_vpath, pn, pn_max,
- x_m, y_m, xb1, yb1, xb2, yb2, x3, y3, flatness);
+ if (subDivide) {
+ double xa1 = (x0 + x1) * 0.5;
+ double ya1 = (y0 + y1) * 0.5;
+ double xa2 = (x0 + 2 * x1 + x2) * 0.25;
+ double ya2 = (y0 + 2 * y1 + y2) * 0.25;
+ double xb1 = (x1 + 2 * x2 + x3) * 0.25;
+ double yb1 = (y1 + 2 * y2 + y3) * 0.25;
+ double xb2 = (x2 + x3) * 0.5;
+ double yb2 = (y2 + y3) * 0.5;
+ double x_m = (xa2 + xb1) * 0.5;
+ double y_m = (ya2 + yb1) * 0.5;
+
+ art_vpath_render_bez(p_vpath, pn, pn_max,
+ x0, y0, xa1, ya1, xa2, ya2, x_m, y_m, flatness);
+ art_vpath_render_bez(p_vpath, pn, pn_max,
+ x_m, y_m, xb1, yb1, xb2, yb2, x3, y3, flatness);
+ } else {
+ // don't subdivide
+ art_vpath_add_point(p_vpath, pn, pn_max,
+ ART_LINETO, x3, y3);
+ }
}
/**
diff --git a/engines/sword25/gfx/image/renderedimage.cpp b/engines/sword25/gfx/image/renderedimage.cpp
index 3b29b0333f..b0d4853e5e 100644
--- a/engines/sword25/gfx/image/renderedimage.cpp
+++ b/engines/sword25/gfx/image/renderedimage.cpp
@@ -152,7 +152,7 @@ RenderedImage::RenderedImage(uint width, uint height, bool &result) :
_height(height) {
_data = new byte[width * height * 4];
- Common::set_to(_data, &_data[width * height * 4], 0);
+ Common::fill(_data, &_data[width * height * 4], 0);
_backSurface = Kernel::getInstance()->getGfx()->getSurface();
@@ -507,7 +507,7 @@ int *RenderedImage::scaleLine(int size, int srcSize) {
int scale = 100 * size / srcSize;
assert(scale > 0);
int *v = new int[size];
- Common::set_to(v, &v[size], 0);
+ Common::fill(v, &v[size], 0);
int distCtr = 0;
int *destP = v;
diff --git a/engines/sword25/gfx/renderobject.h b/engines/sword25/gfx/renderobject.h
index 0b54ccc24b..f963ccaeb3 100644
--- a/engines/sword25/gfx/renderobject.h
+++ b/engines/sword25/gfx/renderobject.h
@@ -402,7 +402,7 @@ protected:
@return Gibt false zurück, falls das Rendern fehlgeschlagen ist.
@remark
*/
- virtual bool doRender() = 0; // { return true; };
+ virtual bool doRender() = 0; // { return true; }
// RenderObject-Baum Variablen
// ---------------------------
diff --git a/engines/sword25/gfx/screenshot.cpp b/engines/sword25/gfx/screenshot.cpp
index de7b62fba9..0ea4bff906 100644
--- a/engines/sword25/gfx/screenshot.cpp
+++ b/engines/sword25/gfx/screenshot.cpp
@@ -74,7 +74,7 @@ Common::SeekableReadStream *Screenshot::createThumbnail(Graphics::Surface *data)
// The source image must be 800x600.
if (data->w != 800 || data->h != 600 || data->format.bytesPerPixel != 4) {
error("The sreenshot dimensions have to be 800x600 in order to be saved as a thumbnail.");
- return false;
+ return 0;
}
// Buffer for the output thumbnail
diff --git a/engines/sword25/util/lua/lbaselib.cpp b/engines/sword25/util/lua/lbaselib.cpp
index 3f0b645164..659c61d956 100644
--- a/engines/sword25/util/lua/lbaselib.cpp
+++ b/engines/sword25/util/lua/lbaselib.cpp
@@ -6,10 +6,7 @@
-#include <ctype.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
+#include "common/util.h"
#define lbaselib_c
#define LUA_LIB
@@ -62,7 +59,7 @@ static int luaB_tonumber (lua_State *L) {
luaL_argcheck(L, 2 <= base && base <= 36, 2, "base out of range");
n = strtoul(s1, &s2, base);
if (s1 != s2) { /* at least one valid digit? */
- while (isspace((unsigned char)(*s2))) s2++; /* skip trailing spaces */
+ while (Common::isSpace(*s2)) s2++; /* skip trailing spaces */
if (*s2 == '\0') { /* no invalid trailing characters? */
lua_pushnumber(L, (lua_Number)n);
return 1;
diff --git a/engines/sword25/util/lua/llex.cpp b/engines/sword25/util/lua/llex.cpp
index 464ab3ec15..f8433d3afa 100644
--- a/engines/sword25/util/lua/llex.cpp
+++ b/engines/sword25/util/lua/llex.cpp
@@ -5,9 +5,7 @@
*/
-#include <ctype.h>
-#include <stdio.h>
-#include <string.h>
+#include "common/util.h"
#define llex_c
#define LUA_CORE
@@ -188,7 +186,7 @@ static void trydecpoint (LexState *ls, SemInfo *seminfo) {
sprintf(buf, "%.1f", 1.0);
ls->decpoint = '.';
for (i = 0; buf[i]; i++) {
- if (!isspace(static_cast<unsigned char>(buf[i])) && !isdigit(static_cast<unsigned char>(buf[i]))) {
+ if (!Common::isSpace(buf[i]) && !Common::isDigit(buf[i])) {
ls->decpoint = buf[i];
break;
}
@@ -204,13 +202,13 @@ static void trydecpoint (LexState *ls, SemInfo *seminfo) {
/* LUA_NUMBER */
static void read_numeral (LexState *ls, SemInfo *seminfo) {
- lua_assert(isdigit(ls->current));
+ lua_assert(Common::isDigit(ls->current));
do {
save_and_next(ls);
- } while (isdigit(ls->current) || ls->current == '.');
+ } while (Common::isDigit(ls->current) || ls->current == '.');
if (check_next(ls, "Ee")) /* `E'? */
check_next(ls, "+-"); /* optional exponent sign */
- while (isalnum(ls->current) || ls->current == '_')
+ while (Common::isAlnum(ls->current) || ls->current == '_')
save_and_next(ls);
save(ls, '\0');
buffreplace(ls, '.', ls->decpoint); /* follow locale for decimal point */
@@ -313,7 +311,7 @@ static void read_string (LexState *ls, int del, SemInfo *seminfo) {
case '\r': save(ls, '\n'); inclinenumber(ls); continue;
case EOZ: continue; /* will raise an error next loop */
default: {
- if (!isdigit(ls->current))
+ if (!Common::isDigit(ls->current))
save_and_next(ls); /* handles \\, \", \', and \? */
else { /* \xxx */
int i = 0;
@@ -321,7 +319,7 @@ static void read_string (LexState *ls, int del, SemInfo *seminfo) {
do {
c = 10*c + (ls->current-'0');
next(ls);
- } while (++i<3 && isdigit(ls->current));
+ } while (++i<3 && Common::isDigit(ls->current));
if (c > UCHAR_MAX)
luaX_lexerror(ls, "escape sequence too large", TK_STRING);
save(ls, c);
@@ -412,7 +410,7 @@ static int llex (LexState *ls, SemInfo *seminfo) {
return TK_DOTS; /* ... */
else return TK_CONCAT; /* .. */
}
- else if (!isdigit(ls->current)) return '.';
+ else if (!Common::isDigit(ls->current)) return '.';
else {
read_numeral(ls, seminfo);
return TK_NUMBER;
@@ -422,21 +420,21 @@ static int llex (LexState *ls, SemInfo *seminfo) {
return TK_EOS;
}
default: {
- if (isspace(ls->current)) {
+ if (Common::isSpace(ls->current)) {
lua_assert(!currIsNewline(ls));
next(ls);
continue;
}
- else if (isdigit(ls->current)) {
+ else if (Common::isDigit(ls->current)) {
read_numeral(ls, seminfo);
return TK_NUMBER;
}
- else if (isalpha(ls->current) || ls->current == '_') {
+ else if (Common::isAlpha(ls->current) || ls->current == '_') {
/* identifier or reserved word */
TString *ts;
do {
save_and_next(ls);
- } while (isalnum(ls->current) || ls->current == '_');
+ } while (Common::isAlnum(ls->current) || ls->current == '_');
ts = luaX_newstring(ls, luaZ_buffer(ls->buff),
luaZ_bufflen(ls->buff));
if (ts->tsv.reserved > 0) /* reserved word? */
diff --git a/engines/sword25/util/lua/lobject.cpp b/engines/sword25/util/lua/lobject.cpp
index 24718931ed..1ffee52556 100644
--- a/engines/sword25/util/lua/lobject.cpp
+++ b/engines/sword25/util/lua/lobject.cpp
@@ -4,11 +4,7 @@
** See Copyright Notice in lua.h
*/
-#include <ctype.h>
-#include <stdarg.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
+#include "common/util.h"
#define lobject_c
#define LUA_CORE
@@ -94,7 +90,7 @@ int luaO_str2d (const char *s, lua_Number *result) {
if (*endptr == 'x' || *endptr == 'X') /* maybe an hexadecimal constant? */
*result = cast_num(strtoul(s, &endptr, 16));
if (*endptr == '\0') return 1; /* most common case */
- while (isspace(cast(unsigned char, *endptr))) endptr++;
+ while (Common::isSpace(*endptr)) endptr++;
if (*endptr != '\0') return 0; /* invalid trailing characters? */
return 1;
}
diff --git a/engines/sword25/util/lua/lstrlib.cpp b/engines/sword25/util/lua/lstrlib.cpp
index bcc869cb98..ed68a2fa00 100644
--- a/engines/sword25/util/lua/lstrlib.cpp
+++ b/engines/sword25/util/lua/lstrlib.cpp
@@ -5,6 +5,8 @@
*/
+#define FORBIDDEN_SYMBOL_EXCEPTION_ctype_h
+
#include <ctype.h>
#include <stddef.h>
#include <stdio.h>
diff --git a/engines/sword25/util/lua/luaconf.h b/engines/sword25/util/lua/luaconf.h
index f5affe9fd7..38ff9e1320 100644
--- a/engines/sword25/util/lua/luaconf.h
+++ b/engines/sword25/util/lua/luaconf.h
@@ -643,7 +643,7 @@ union luai_Cast { double l_d; long l_l; };
** CHANGE it if you have a way to implement it in your system.
*/
#define lua_popen(L,c,m) ((void)((void)c, m), \
- luaL_error(L, LUA_QL("popen") " not supported"), (FILE*)0)
+ luaL_error(L, LUA_QL("popen") " not supported"), (FILE *)0)
#define lua_pclose(L,file) ((void)((void)L, file), 0)
/*
diff --git a/engines/sword25/util/lua/scummvm_file.cpp b/engines/sword25/util/lua/scummvm_file.cpp
index 33053a71cb..b5f1388129 100644
--- a/engines/sword25/util/lua/scummvm_file.cpp
+++ b/engines/sword25/util/lua/scummvm_file.cpp
@@ -22,7 +22,7 @@
#include "sword25/util/lua/scummvm_file.h"
#include "common/config-manager.h"
-#include "common/util.h"
+#include "common/language.h"
namespace Sword25 {
diff --git a/engines/sword25/util/pluto/pluto.cpp b/engines/sword25/util/pluto/pluto.cpp
index 957f5af795..d645e5ed2a 100644
--- a/engines/sword25/util/pluto/pluto.cpp
+++ b/engines/sword25/util/pluto/pluto.cpp
@@ -159,7 +159,7 @@ static int persistspecialobject(PersistInfo *pi, int defaction)
lua_pushvalue(pi->L, -3);
/* perms reftbl ... obj mt __persist obj */
#ifdef PLUTO_PASS_USERDATA_TO_PERSIST
- lua_pushlightuserdata(pi->L, (void*)pi->writer);
+ lua_pushlightuserdata(pi->L, (void *)pi->writer);
lua_pushlightuserdata(pi->L, pi->ud);
/* perms reftbl ... obj mt __persist obj ud */
lua_call(pi->L, 3, 1);
@@ -663,7 +663,7 @@ static void persist(PersistInfo *pi)
}
lua_pushvalue(pi->L, -1);
/* perms reftbl ... obj obj */
- lua_pushlightuserdata(pi->L, (void*)(++(pi->counter)));
+ lua_pushlightuserdata(pi->L, (void *)(++(pi->counter)));
/* perms reftbl ... obj obj ref */
lua_rawset(pi->L, 2);
/* perms reftbl ... obj */
@@ -854,7 +854,7 @@ static void registerobject(int ref, UnpersistInfo *upi)
{
/* perms reftbl ... obj */
lua_checkstack(upi->L, 2);
- lua_pushlightuserdata(upi->L, (void*)ref);
+ lua_pushlightuserdata(upi->L, (void *)ref);
/* perms reftbl ... obj ref */
lua_pushvalue(upi->L, -2);
/* perms reftbl ... obj ref obj */
@@ -989,7 +989,7 @@ static void unpersisttable(int ref, UnpersistInfo *upi)
static UpVal *makeupval(lua_State *L, int stackpos)
{
UpVal *uv = pdep_new(L, UpVal);
- pdep_link(L, (GCObject*)uv, LUA_TUPVAL);
+ pdep_link(L, (GCObject *)uv, LUA_TUPVAL);
uv->tt = LUA_TUPVAL;
uv->v = &uv->u.value;
uv->u.l.prev = NULL;
@@ -1025,8 +1025,8 @@ static Proto *makefakeproto(lua_State *L, lu_byte nups)
static void boxupval_start(lua_State *L)
{
LClosure *lcl;
- lcl = (LClosure*)pdep_newLclosure(L, 1, hvalue(&L->l_gt));
- pushclosure(L, (Closure*)lcl);
+ lcl = (LClosure *)pdep_newLclosure(L, 1, hvalue(&L->l_gt));
+ pushclosure(L, (Closure *)lcl);
/* ... func */
lcl->p = makefakeproto(L, 1);
@@ -1053,7 +1053,7 @@ static void unboxupval(lua_State *L)
LClosure *lcl;
UpVal *uv;
- lcl = (LClosure*)clvalue(getobject(L, -1));
+ lcl = (LClosure *)clvalue(getobject(L, -1));
uv = lcl->upvals[0];
lua_pop(L, 1);
/* ... */
@@ -1071,8 +1071,8 @@ static void unpersistfunction(int ref, UnpersistInfo *upi)
verify(LIF(Z,read)(&upi->zio, &nupvalues, sizeof(lu_byte)) == 0);
- lcl = (LClosure*)pdep_newLclosure(upi->L, nupvalues, hvalue(&upi->L->l_gt));
- pushclosure(upi->L, (Closure*)lcl);
+ lcl = (LClosure *)pdep_newLclosure(upi->L, nupvalues, hvalue(&upi->L->l_gt));
+ pushclosure(upi->L, (Closure *)lcl);
/* perms reftbl ... func */
/* Put *some* proto in the closure, before the GC can find it */
@@ -1393,9 +1393,9 @@ static void unpersistthread(int ref, UnpersistInfo *upi)
verify(LIF(Z,read)(&upi->zio, &stackpos, sizeof(size_t)) == 0);
uv->v = L2->stack + stackpos;
- gcunlink(upi->L, (GCObject*)uv);
+ gcunlink(upi->L, (GCObject *)uv);
uv->marked = luaC_white(g);
- *nextslot = (GCObject*)uv;
+ *nextslot = (GCObject *)uv;
nextslot = &uv->next;
uv->u.l.prev = &G(L2)->uvhead;
uv->u.l.next = G(L2)->uvhead.u.l.next;
@@ -1482,7 +1482,7 @@ static int inreftable(lua_State *L, int ref)
int res;
lua_checkstack(L, 1);
/* perms reftbl ... */
- lua_pushlightuserdata(L, (void*)ref);
+ lua_pushlightuserdata(L, (void *)ref);
/* perms reftbl ... ref */
lua_gettable(L, 2);
/* perms reftbl ... obj? */
@@ -1571,7 +1571,7 @@ static void unpersist(UnpersistInfo *upi)
lua_pushnil(upi->L);
/* perms reftbl ... nil */
} else {
- lua_pushlightuserdata(upi->L, (void*)ref);
+ lua_pushlightuserdata(upi->L, (void *)ref);
/* perms reftbl ... ref */
lua_gettable(upi->L, 2);
/* perms reftbl ... obj? */
diff --git a/engines/teenagent/callbacks.cpp b/engines/teenagent/callbacks.cpp
index f8bb142bd8..8882531d27 100644
--- a/engines/teenagent/callbacks.cpp
+++ b/engines/teenagent/callbacks.cpp
@@ -3110,7 +3110,7 @@ bool TeenAgentEngine::processCallback(uint16 addr) {
playSound(67, 4);
playActorAnimation(680);
SET_FLAG(0xDBB8, 0);
- } else if (CHECK_FLAG(0xDBB8, 1)) {
+ } else if (CHECK_FLAG(0xDBB7, 1)) {
processCallback(0x6b86);
} else if (CHECK_FLAG(0xDBB9, 1)) {
processCallback(0x6b86);
@@ -3177,7 +3177,7 @@ bool TeenAgentEngine::processCallback(uint16 addr) {
playSound(67, 5);
playActorAnimation(688);
SET_FLAG(0xdbbc, 0);
- } else if (CHECK_FLAG(0xdbbc, 1)) {
+ } else if (CHECK_FLAG(0xdbbb, 1)) {
processCallback(0x6b86);
} else {
playSound(66, 6);
@@ -3221,7 +3221,8 @@ bool TeenAgentEngine::processCallback(uint16 addr) {
return true;
case 0x6c83:
- Dialog::pop(scene, 0xdb2e, 0, 0, 0xd1, 0xef, 0, 1);
+ waitLanAnimationFrame(1, 1);
+ Dialog::pop(scene, 0xdb2e, 0, 727, 0xd1, 0xef, 0, 1);
scene->getObject(1)->setName((const char *)res->dseg.ptr(0xaa94));
SET_FLAG(0xDBD1, 1);
return true;
@@ -3557,8 +3558,9 @@ bool TeenAgentEngine::processCallback(uint16 addr) {
playSound(5, 39);
displayAsyncMessage(0x5124, 40388, 9, 35, 0xd0);
playActorAnimation(728);
- //fixme: add 727 animation
- Dialog::show(scene, 0x3d17, 0, 0, 0xd1, 0xef, 0, 1);
+
+ waitLanAnimationFrame(1, 1);
+ Dialog::show(scene, 0x3d17, 0, 727, 0xd1, 0xef, 0, 1);
SET_FLAG(0xDBD2, 1);
processCallback(0x9175);
return true;
@@ -3572,13 +3574,14 @@ bool TeenAgentEngine::processCallback(uint16 addr) {
return true;
}
displayMessage(0x5138);
- waitLanAnimationFrame(1, 1);
+ waitLanAnimationFrame(1, 1);
playSound(5, 3);
playSound(5, 23);
playActorAnimation(729);
- //fixme: add 727 animation
- Dialog::show(scene, 0x3d70, 0, 0, 0xd1, 0xef, 0, 1);
+
+ waitLanAnimationFrame(1, 1);
+ Dialog::show(scene, 0x3d70, 0, 727, 0xd1, 0xef, 0, 1);
SET_FLAG(0xDBD3, 1);
processCallback(0x9175);
return true;
@@ -3597,8 +3600,9 @@ bool TeenAgentEngine::processCallback(uint16 addr) {
playSound(5, 3);
playSound(5, 25);
playActorAnimation(730);
- //fixme: add 727 animation
- Dialog::show(scene, 0x3dd6, 0, 0, 0xd1, 0xef, 0, 1);
+
+ waitLanAnimationFrame(1, 1);
+ Dialog::show(scene, 0x3dd6, 0, 727, 0xd1, 0xef, 0, 1);
SET_FLAG(0xDBD4, 1);
processCallback(0x9175);
return true;
diff --git a/engines/teenagent/console.cpp b/engines/teenagent/console.cpp
index 5164b44729..9ab6001d54 100644
--- a/engines/teenagent/console.cpp
+++ b/engines/teenagent/console.cpp
@@ -25,10 +25,13 @@
namespace TeenAgent {
Console::Console(TeenAgentEngine *engine) : _engine(engine) {
- DCmd_Register("enable_object", WRAP_METHOD(Console, enableObject));
- DCmd_Register("disable_object", WRAP_METHOD(Console, enableObject));
- DCmd_Register("set_ons", WRAP_METHOD(Console, setOns));
- DCmd_Register("set_music", WRAP_METHOD(Console, setMusic));
+ DCmd_Register("enable_object", WRAP_METHOD(Console, enableObject));
+ DCmd_Register("disable_object", WRAP_METHOD(Console, enableObject));
+ DCmd_Register("set_ons", WRAP_METHOD(Console, setOns));
+ DCmd_Register("set_music", WRAP_METHOD(Console, setMusic));
+ DCmd_Register("animation", WRAP_METHOD(Console, playAnimation));
+ DCmd_Register("actor_animation", WRAP_METHOD(Console, playActorAnimation));
+ DCmd_Register("call", WRAP_METHOD(Console, call));
}
bool Console::enableObject(int argc, const char **argv) {
@@ -97,13 +100,66 @@ bool Console::setMusic(int argc, const char **argv) {
DebugPrintf("usage: %s index(1-11)\n", argv[0]);
return true;
}
+
int index = atoi(argv[1]);
if (index <= 0 || index > 11) {
DebugPrintf("invalid value\n");
return true;
}
+
_engine->setMusic(index);
return true;
}
+bool Console::playAnimation(int argc, const char **argv) {
+ if (argc < 3) {
+ DebugPrintf("usage: %s id slot(0-3)\n", argv[0]);
+ return true;
+ }
+
+ int id = atoi(argv[1]);
+ int slot = atoi(argv[2]);
+ if (id < 0 || slot < 0 || slot > 3) {
+ DebugPrintf("invalid slot or animation id\n");
+ return true;
+ }
+
+ _engine->playAnimation(id, slot);
+ return true;
+}
+
+bool Console::playActorAnimation(int argc, const char **argv) {
+ if (argc < 2) {
+ DebugPrintf("usage: %s id\n", argv[0]);
+ return true;
+ }
+
+ int id = atoi(argv[1]);
+ if (id < 0) {
+ DebugPrintf("invalid animation id\n");
+ return true;
+ }
+
+ _engine->playActorAnimation(id);
+ return true;
+}
+
+bool Console::call(int argc, const char **argv) {
+ if (argc < 2) {
+ DebugPrintf("usage: %s 0xHEXADDR\n", argv[0]);
+ return true;
+ }
+
+ uint addr;
+ if (sscanf(argv[1], "0x%x", &addr) != 1) {
+ DebugPrintf("invalid address\n");
+ return true;
+ }
+
+ if (!_engine->processCallback(addr))
+ DebugPrintf("calling callback %04x failed\n", addr);
+
+ return true;
+}
+
}
diff --git a/engines/teenagent/console.h b/engines/teenagent/console.h
index ab2f068520..4dbdd3fc07 100644
--- a/engines/teenagent/console.h
+++ b/engines/teenagent/console.h
@@ -36,6 +36,9 @@ private:
bool enableObject(int argc, const char **argv);
bool setOns(int argc, const char **argv);
bool setMusic(int argc, const char **argv);
+ bool playAnimation(int argc, const char **argv);
+ bool playActorAnimation(int argc, const char **argv);
+ bool call(int argc, const char **argv);
TeenAgentEngine *_engine;
};
diff --git a/engines/teenagent/detection.cpp b/engines/teenagent/detection.cpp
index cf58df1344..dad876dd97 100644
--- a/engines/teenagent/detection.cpp
+++ b/engines/teenagent/detection.cpp
@@ -74,7 +74,7 @@ static const ADGameDescription teenAgentGameDescriptions[] = {
Common::CZ_CZE,
Common::kPlatformPC,
ADGF_CD,
- GUIO1(GUIO_NONE)
+ GUIO0()
},
AD_TABLE_END_MARKER,
};
diff --git a/engines/teenagent/music.cpp b/engines/teenagent/music.cpp
index 6cc2fd8d6b..1f44e9cfcb 100644
--- a/engines/teenagent/music.cpp
+++ b/engines/teenagent/music.cpp
@@ -51,6 +51,7 @@ bool MusicPlayer::load(int id) {
stream->read(header, 4);
//check header?
+ Common::StackLock lock(_mutex);
// Load the samples
sampleCount = stream->readByte();
diff --git a/engines/teenagent/music.h b/engines/teenagent/music.h
index bf36ac7057..22b4fa5e8e 100644
--- a/engines/teenagent/music.h
+++ b/engines/teenagent/music.h
@@ -40,7 +40,7 @@ public:
void start();
void stop();
-protected:
+private:
int _id;
struct Row {
diff --git a/engines/teenagent/surface.h b/engines/teenagent/surface.h
index 1771b2d683..51368c6bee 100644
--- a/engines/teenagent/surface.h
+++ b/engines/teenagent/surface.h
@@ -31,7 +31,6 @@ class SeekableReadStream;
namespace TeenAgent {
-class Pack;
class Surface : public Graphics::Surface {
public:
enum Type {kTypeOns, kTypeLan};
diff --git a/engines/testbed/detection.cpp b/engines/testbed/detection.cpp
index 356d75f7ea..02a9dfcb87 100644
--- a/engines/testbed/detection.cpp
+++ b/engines/testbed/detection.cpp
@@ -40,7 +40,7 @@ static const ADGameDescription testbedDescriptions[] = {
Common::EN_ANY,
Common::kPlatformPC,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO0()
},
AD_TABLE_END_MARKER
};
diff --git a/engines/tinsel/background.cpp b/engines/tinsel/background.cpp
index 72397db97f..8e3fc50f12 100644
--- a/engines/tinsel/background.cpp
+++ b/engines/tinsel/background.cpp
@@ -34,7 +34,7 @@ namespace Tinsel {
// FIXME: Avoid non-const global vars
// current background
-const BACKGND *pCurBgnd = NULL;
+const BACKGND *g_pCurBgnd = NULL;
/**
* Called to initialize a background.
@@ -46,7 +46,7 @@ void InitBackground(const BACKGND *pBgnd) {
PLAYFIELD *pPlayfield; // pointer to current playfield
// set current background
- pCurBgnd = pBgnd;
+ g_pCurBgnd = pBgnd;
// init background sky color
SetBgndColor(pBgnd->rgbSkyColor);
@@ -83,13 +83,13 @@ void PlayfieldSetPos(int which, int newXpos, int newYpos) {
PLAYFIELD *pPlayfield; // pointer to relavent playfield
// make sure there is a background
- assert(pCurBgnd != NULL);
+ assert(g_pCurBgnd != NULL);
// make sure the playfield number is in range
- assert(which >= 0 && which < pCurBgnd->numPlayfields);
+ assert(which >= 0 && which < g_pCurBgnd->numPlayfields);
// get playfield pointer
- pPlayfield = pCurBgnd->fieldArray + which;
+ pPlayfield = g_pCurBgnd->fieldArray + which;
// set new integer position
pPlayfield->fieldX = intToFrac(newXpos);
@@ -110,13 +110,13 @@ void PlayfieldGetPos(int which, int *pXpos, int *pYpos) {
PLAYFIELD *pPlayfield; // pointer to relavent playfield
// make sure there is a background
- assert(pCurBgnd != NULL);
+ assert(g_pCurBgnd != NULL);
// make sure the playfield number is in range
- assert(which >= 0 && which < pCurBgnd->numPlayfields);
+ assert(which >= 0 && which < g_pCurBgnd->numPlayfields);
// get playfield pointer
- pPlayfield = pCurBgnd->fieldArray + which;
+ pPlayfield = g_pCurBgnd->fieldArray + which;
// get current integer position
*pXpos = fracToInt(pPlayfield->fieldX);
@@ -132,13 +132,13 @@ int PlayfieldGetCenterX(int which) {
PLAYFIELD *pPlayfield; // pointer to relavent playfield
// make sure there is a background
- assert(pCurBgnd != NULL);
+ assert(g_pCurBgnd != NULL);
// make sure the playfield number is in range
- assert(which >= 0 && which < pCurBgnd->numPlayfields);
+ assert(which >= 0 && which < g_pCurBgnd->numPlayfields);
// get playfield pointer
- pPlayfield = pCurBgnd->fieldArray + which;
+ pPlayfield = g_pCurBgnd->fieldArray + which;
// get current integer position
return fracToInt(pPlayfield->fieldX) + SCREEN_WIDTH/2;
@@ -153,13 +153,13 @@ OBJECT **GetPlayfieldList(int which) {
PLAYFIELD *pPlayfield; // pointer to relavent playfield
// make sure there is a background
- assert(pCurBgnd != NULL);
+ assert(g_pCurBgnd != NULL);
// make sure the playfield number is in range
- assert(which >= 0 && which < pCurBgnd->numPlayfields);
+ assert(which >= 0 && which < g_pCurBgnd->numPlayfields);
// get playfield pointer
- pPlayfield = pCurBgnd->fieldArray + which;
+ pPlayfield = g_pCurBgnd->fieldArray + which;
// return the display list pointer for this playfield
return &pPlayfield->pDispList;
@@ -177,13 +177,13 @@ void DrawBackgnd() {
int prevX, prevY; // save interger part of position
Common::Point ptWin; // window top left
- if (pCurBgnd == NULL)
+ if (g_pCurBgnd == NULL)
return; // no current background
// scroll each background playfield
- for (i = 0; i < pCurBgnd->numPlayfields; i++) {
+ for (i = 0; i < g_pCurBgnd->numPlayfields; i++) {
// get pointer to correct playfield
- pPlay = pCurBgnd->fieldArray + i;
+ pPlay = g_pCurBgnd->fieldArray + i;
// save integer part of position
prevX = fracToInt(pPlay->fieldX);
@@ -220,11 +220,11 @@ void DrawBackgnd() {
for (RectList::const_iterator r = clipRects.begin(); r != clipRects.end(); ++r) {
// clear the clip rectangle on the virtual screen
// for each background playfield
- for (i = 0; i < pCurBgnd->numPlayfields; i++) {
+ for (i = 0; i < g_pCurBgnd->numPlayfields; i++) {
Common::Rect rcPlayClip; // clip rect for this playfield
// get pointer to correct playfield
- pPlay = pCurBgnd->fieldArray + i;
+ pPlay = g_pCurBgnd->fieldArray + i;
// convert fixed point window pos to a int
ptWin.x = fracToInt(pPlay->fieldX);
diff --git a/engines/tinsel/bg.cpp b/engines/tinsel/bg.cpp
index cf692e16ea..72ba05f0b9 100644
--- a/engines/tinsel/bg.cpp
+++ b/engines/tinsel/bg.cpp
@@ -47,59 +47,59 @@ namespace Tinsel {
#define MAX_BG 10
// FIXME: Avoid non-const global vars
-static SCNHANDLE hBgPal = 0; // Background's palette
-static POBJECT pBG[MAX_BG];
-static ANIM thisAnim[MAX_BG]; // used by BGmainProcess()
-static int BGspeed = 0;
-static SCNHANDLE hBackground = 0; // Current scene handle - stored in case of Save_Scene()
-static bool bDoFadeIn = false;
-static int bgReels;
+static SCNHANDLE g_hBgPal = 0; // Background's palette
+static POBJECT g_pBG[MAX_BG];
+static ANIM g_thisAnim[MAX_BG]; // used by BGmainProcess()
+static int g_BGspeed = 0;
+static SCNHANDLE g_hBackground = 0; // Current scene handle - stored in case of Save_Scene()
+static bool g_bDoFadeIn = false;
+static int g_bgReels;
/**
* GetBgObject
*/
OBJECT *GetBgObject() {
- return pBG[0];
+ return g_pBG[0];
}
/**
* BackPal
*/
SCNHANDLE BgPal() {
- return hBgPal;
+ return g_hBgPal;
}
/**
* SetDoFadeIn
*/
void SetDoFadeIn(bool tf) {
- bDoFadeIn = tf;
+ g_bDoFadeIn = tf;
}
/**
* Called before scene change.
*/
void DropBackground() {
- pBG[0] = NULL; // No background
+ g_pBG[0] = NULL; // No background
if (!TinselV2)
- hBgPal = 0; // No background palette
+ g_hBgPal = 0; // No background palette
}
/**
* Return the width of the current background.
*/
int BgWidth() {
- assert(pBG[0]);
- return MultiRightmost(pBG[0]) + 1;
+ assert(g_pBG[0]);
+ return MultiRightmost(g_pBG[0]) + 1;
}
/**
* Return the height of the current background.
*/
int BgHeight() {
- assert(pBG[0]);
- return MultiLowest(pBG[0]) + 1;
+ assert(g_pBG[0]);
+ return MultiLowest(g_pBG[0]) + 1;
}
/**
@@ -117,7 +117,7 @@ static void BGmainProcess(CORO_PARAM, const void *param) {
const MULTI_INIT *pmi;
// get the stuff copied to process when it was created
- if (pBG[0] == NULL) {
+ if (g_pBG[0] == NULL) {
/*** At start of scene ***/
if (!TinselV2) {
@@ -127,40 +127,40 @@ static void BGmainProcess(CORO_PARAM, const void *param) {
pmi = (const MULTI_INIT *)LockMem(FROM_LE_32(pReel->mobj));
// Initialize and insert the object, and initialize its script.
- pBG[0] = MultiInitObject(pmi);
- MultiInsertObject(GetPlayfieldList(FIELD_WORLD), pBG[0]);
- InitStepAnimScript(&thisAnim[0], pBG[0], FROM_LE_32(pReel->script), BGspeed);
- bgReels = 1;
+ g_pBG[0] = MultiInitObject(pmi);
+ MultiInsertObject(GetPlayfieldList(FIELD_WORLD), g_pBG[0]);
+ InitStepAnimScript(&g_thisAnim[0], g_pBG[0], FROM_LE_32(pReel->script), g_BGspeed);
+ g_bgReels = 1;
} else {
/*** At start of scene ***/
- pFilm = (const FILM *)LockMem(hBackground);
- bgReels = FROM_LE_32(pFilm->numreels);
+ pFilm = (const FILM *)LockMem(g_hBackground);
+ g_bgReels = FROM_LE_32(pFilm->numreels);
int i;
- for (i = 0; i < bgReels; i++) {
+ for (i = 0; i < g_bgReels; i++) {
// Get the MULTI_INIT structure
pmi = (PMULTI_INIT) LockMem(FROM_LE_32(pFilm->reels[i].mobj));
// Initialize and insert the object, and initialize its script.
- pBG[i] = MultiInitObject(pmi);
- MultiInsertObject(GetPlayfieldList(FIELD_WORLD), pBG[i]);
- MultiSetZPosition(pBG[i], 0);
- InitStepAnimScript(&thisAnim[i], pBG[i], FROM_LE_32(pFilm->reels[i].script), BGspeed);
+ g_pBG[i] = MultiInitObject(pmi);
+ MultiInsertObject(GetPlayfieldList(FIELD_WORLD), g_pBG[i]);
+ MultiSetZPosition(g_pBG[i], 0);
+ InitStepAnimScript(&g_thisAnim[i], g_pBG[i], FROM_LE_32(pFilm->reels[i].script), g_BGspeed);
if (i > 0)
- pBG[i-1]->pSlave = pBG[i];
+ g_pBG[i-1]->pSlave = g_pBG[i];
}
}
- if (bDoFadeIn) {
+ if (g_bDoFadeIn) {
FadeInFast(NULL);
- bDoFadeIn = false;
+ g_bDoFadeIn = false;
} else if (TinselV2)
PokeInTagColor();
for (;;) {
- for (int i = 0; i < bgReels; i++) {
- if (StepAnimScript(&thisAnim[i]) == ScriptFinished)
+ for (int i = 0; i < g_bgReels; i++) {
+ if (StepAnimScript(&g_thisAnim[i]) == ScriptFinished)
error("Background animation has finished");
}
@@ -170,16 +170,16 @@ static void BGmainProcess(CORO_PARAM, const void *param) {
// New background during scene
if (!TinselV2) {
pReel = (const FREEL *)param;
- InitStepAnimScript(&thisAnim[0], pBG[0], FROM_LE_32(pReel->script), BGspeed);
- StepAnimScript(&thisAnim[0]);
+ InitStepAnimScript(&g_thisAnim[0], g_pBG[0], FROM_LE_32(pReel->script), g_BGspeed);
+ StepAnimScript(&g_thisAnim[0]);
} else {
- pFilm = (const FILM *)LockMem(hBackground);
- assert(bgReels == (int32)FROM_LE_32(pFilm->numreels));
+ pFilm = (const FILM *)LockMem(g_hBackground);
+ assert(g_bgReels == (int32)FROM_LE_32(pFilm->numreels));
// Just re-initialize the scripts.
- for (int i = 0; i < bgReels; i++) {
- InitStepAnimScript(&thisAnim[i], pBG[i], pFilm->reels[i].script, BGspeed);
- StepAnimScript(&thisAnim[i]);
+ for (int i = 0; i < g_bgReels; i++) {
+ InitStepAnimScript(&g_thisAnim[i], g_pBG[i], pFilm->reels[i].script, g_BGspeed);
+ StepAnimScript(&g_thisAnim[i]);
}
}
}
@@ -206,7 +206,7 @@ static void BGotherProcess(CORO_PARAM, const void *param) {
_ctx->pObj = MultiInitObject(pmi);
MultiInsertObject(GetPlayfieldList(FIELD_WORLD), _ctx->pObj);
- InitStepAnimScript(&_ctx->anim, pBG[0], FROM_LE_32(pReel->script), BGspeed);
+ InitStepAnimScript(&_ctx->anim, g_pBG[0], FROM_LE_32(pReel->script), g_BGspeed);
while (StepAnimScript(&_ctx->anim) != ScriptFinished)
CORO_SLEEP(1);
@@ -218,14 +218,14 @@ static void BGotherProcess(CORO_PARAM, const void *param) {
* AetBgPal()
*/
void SetBackPal(SCNHANDLE hPal) {
- hBgPal = hPal;
+ g_hBgPal = hPal;
- FettleFontPal(hBgPal);
- CreateTranslucentPalette(hBgPal);
+ FettleFontPal(g_hBgPal);
+ CreateTranslucentPalette(g_hBgPal);
}
void ChangePalette(SCNHANDLE hPal) {
- SwapPalette(FindPalette(hBgPal), hPal);
+ SwapPalette(FindPalette(g_hBgPal), hPal);
SetBackPal(hPal);
}
@@ -245,14 +245,14 @@ void StartupBackground(CORO_PARAM, SCNHANDLE hFilm) {
const FILM *pfilm;
IMAGE *pim;
- hBackground = hFilm; // Save handle in case of Save_Scene()
+ g_hBackground = hFilm; // Save handle in case of Save_Scene()
pim = GetImageFromFilm(hFilm, 0, NULL, NULL, &pfilm);
SetBackPal(FROM_LE_32(pim->hImgPal));
// Extract the film speed
- BGspeed = ONE_SECOND / FROM_LE_32(pfilm->frate);
+ g_BGspeed = ONE_SECOND / FROM_LE_32(pfilm->frate);
// Start display process for each reel in the film
g_scheduler->createProcess(PID_REEL, BGmainProcess, &pfilm->reels[0], sizeof(FREEL));
@@ -262,7 +262,7 @@ void StartupBackground(CORO_PARAM, SCNHANDLE hFilm) {
g_scheduler->createProcess(PID_REEL, BGotherProcess, &pfilm->reels[i], sizeof(FREEL));
}
- if (pBG[0] == NULL)
+ if (g_pBG[0] == NULL)
ControlStartOff();
if (TinselV2 && (coroParam != nullContext))
@@ -275,7 +275,7 @@ void StartupBackground(CORO_PARAM, SCNHANDLE hFilm) {
* Return the current scene handle.
*/
SCNHANDLE GetBgroundHandle() {
- return hBackground;
+ return g_hBackground;
}
} // End of namespace Tinsel
diff --git a/engines/tinsel/cursor.cpp b/engines/tinsel/cursor.cpp
index 8248609a81..bf901c03b6 100644
--- a/engines/tinsel/cursor.cpp
+++ b/engines/tinsel/cursor.cpp
@@ -56,36 +56,36 @@ namespace Tinsel {
// FIXME: Avoid non-const global vars
-static OBJECT *McurObj = NULL; // Main cursor object
-static OBJECT *AcurObj = NULL; // Auxiliary cursor object
+static OBJECT *g_McurObj = NULL; // Main cursor object
+static OBJECT *g_AcurObj = NULL; // Auxiliary cursor object
-static ANIM McurAnim = {0,0,0,0,0}; // Main cursor animation structure
-static ANIM AcurAnim = {0,0,0,0,0}; // Auxiliary cursor animation structure
+static ANIM g_McurAnim = {0,0,0,0,0}; // Main cursor animation structure
+static ANIM g_AcurAnim = {0,0,0,0,0}; // Auxiliary cursor animation structure
-static bool bHiddenCursor = false; // Set when cursor is hidden
-static bool bTempNoTrailers = false; // Set when cursor trails are hidden
-static bool bTempHide = false; // Set when cursor is hidden
+static bool g_bHiddenCursor = false; // Set when cursor is hidden
+static bool g_bTempNoTrailers = false; // Set when cursor trails are hidden
+static bool g_bTempHide = false; // Set when cursor is hidden
-static bool bFrozenCursor = false; // Set when cursor position is frozen
+static bool g_bFrozenCursor = false; // Set when cursor position is frozen
-static frac_t IterationSize = 0;
+static frac_t g_IterationSize = 0;
-static SCNHANDLE hCursorFilm = 0; // Handle to cursor reel data
+static SCNHANDLE g_hCursorFilm = 0; // Handle to cursor reel data
-static int numTrails = 0;
-static int nextTrail = 0;
+static int g_numTrails = 0;
+static int g_nextTrail = 0;
-static bool bWhoa = false; // Set by DropCursor() at the end of a scene
+static bool g_bWhoa = false; // Set by DropCursor() at the end of a scene
// - causes cursor processes to do nothing
// Reset when main cursor has re-initialized
-static uint16 restart = 0; // When main cursor has been bWhoa-ed, it waits
+static uint16 g_restart = 0; // When main cursor has been bWhoa-ed, it waits
// for this to be set to 0x8000.
// Main cursor sets all the bits after a re-start
// - each cursor trail examines it's own bit
// to trigger a trail restart.
-static short ACoX = 0, ACoY = 0; // Auxillary cursor image's animation offsets
+static short g_ACoX = 0, g_ACoY = 0; // Auxillary cursor image's animation offsets
@@ -96,9 +96,9 @@ static struct {
ANIM trailAnim; // Animation structure
OBJECT *trailObj; // This trailer's object
-} ntrailData [MAX_TRAILERS];
+} g_ntrailData [MAX_TRAILERS];
-static int lastCursorX = 0, lastCursorY = 0;
+static int g_lastCursorX = 0, g_lastCursorY = 0;
//----------------- FORWARD REFERENCES --------------------
@@ -116,26 +116,26 @@ static void InitCurTrailObj(int i, int x, int y) {
const FILM *pfilm;
- if (!numTrails)
+ if (!g_numTrails)
return;
// Get rid of old object
- if (ntrailData[i].trailObj != NULL)
- MultiDeleteObject(GetPlayfieldList(FIELD_STATUS), ntrailData[i].trailObj);
+ if (g_ntrailData[i].trailObj != NULL)
+ MultiDeleteObject(GetPlayfieldList(FIELD_STATUS), g_ntrailData[i].trailObj);
- pim = GetImageFromFilm(hCursorFilm, i+1, &pfr, &pmi, &pfilm);// Get pointer to image
+ pim = GetImageFromFilm(g_hCursorFilm, i+1, &pfr, &pmi, &pfilm);// Get pointer to image
assert(BgPal()); // No background palette
pim->hImgPal = TO_LE_32(BgPal());
// Initialize and insert the object, set its Z-pos, and hide it
- ntrailData[i].trailObj = MultiInitObject(pmi);
- MultiInsertObject(GetPlayfieldList(FIELD_STATUS), ntrailData[i].trailObj);
- MultiSetZPosition(ntrailData[i].trailObj, Z_CURSORTRAIL);
- MultiSetAniXY(ntrailData[i].trailObj, x, y);
+ g_ntrailData[i].trailObj = MultiInitObject(pmi);
+ MultiInsertObject(GetPlayfieldList(FIELD_STATUS), g_ntrailData[i].trailObj);
+ MultiSetZPosition(g_ntrailData[i].trailObj, Z_CURSORTRAIL);
+ MultiSetAniXY(g_ntrailData[i].trailObj, x, y);
// Initialize the animation script
- InitStepAnimScript(&ntrailData[i].trailAnim, ntrailData[i].trailObj, FROM_LE_32(pfr->script), ONE_SECOND / FROM_LE_32(pfilm->frate));
- StepAnimScript(&ntrailData[i].trailAnim);
+ InitStepAnimScript(&g_ntrailData[i].trailAnim, g_ntrailData[i].trailObj, FROM_LE_32(pfr->script), ONE_SECOND / FROM_LE_32(pfilm->frate));
+ StepAnimScript(&g_ntrailData[i].trailAnim);
}
/**
@@ -196,12 +196,12 @@ void SetCursorScreenXY(int newx, int newy) {
* Returns false if there is no cursor object.
*/
bool GetCursorXYNoWait(int *x, int *y, bool absolute) {
- if (McurObj == NULL) {
+ if (g_McurObj == NULL) {
*x = *y = 0;
return false;
}
- GetAniPosition(McurObj, x, y);
+ GetAniPosition(g_McurObj, x, y);
if (absolute) {
int Loffset, Toffset; // Screen offset
@@ -222,7 +222,7 @@ bool GetCursorXYNoWait(int *x, int *y, bool absolute) {
void GetCursorXY(int *x, int *y, bool absolute) {
//while (McurObj == NULL)
// ProcessSleepSelf();
- assert(McurObj);
+ assert(g_McurObj);
GetCursorXYNoWait(x, y, absolute);
}
@@ -234,22 +234,22 @@ void GetCursorXY(int *x, int *y, bool absolute) {
void RestoreMainCursor() {
const FILM *pfilm;
- if (McurObj != NULL) {
- pfilm = (const FILM *)LockMem(hCursorFilm);
+ if (g_McurObj != NULL) {
+ pfilm = (const FILM *)LockMem(g_hCursorFilm);
- InitStepAnimScript(&McurAnim, McurObj, FROM_LE_32(pfilm->reels->script), ONE_SECOND / FROM_LE_32(pfilm->frate));
- StepAnimScript(&McurAnim);
+ InitStepAnimScript(&g_McurAnim, g_McurObj, FROM_LE_32(pfilm->reels->script), ONE_SECOND / FROM_LE_32(pfilm->frate));
+ StepAnimScript(&g_McurAnim);
}
- bHiddenCursor = false;
- bFrozenCursor = false;
+ g_bHiddenCursor = false;
+ g_bFrozenCursor = false;
}
/**
* Called from INVENTRY.C to customise the main cursor.
*/
void SetTempCursor(SCNHANDLE pScript) {
- if (McurObj != NULL)
- InitStepAnimScript(&McurAnim, McurObj, pScript, 2);
+ if (g_McurObj != NULL)
+ InitStepAnimScript(&g_McurAnim, g_McurObj, pScript, 2);
}
/**
@@ -258,17 +258,17 @@ void SetTempCursor(SCNHANDLE pScript) {
void DwHideCursor() {
int i;
- bHiddenCursor = true;
+ g_bHiddenCursor = true;
- if (McurObj)
- MultiHideObject(McurObj);
- if (AcurObj)
- MultiHideObject(AcurObj);
+ if (g_McurObj)
+ MultiHideObject(g_McurObj);
+ if (g_AcurObj)
+ MultiHideObject(g_AcurObj);
- for (i = 0; i < numTrails; i++) {
- if (ntrailData[i].trailObj != NULL) {
- MultiDeleteObject(GetPlayfieldList(FIELD_STATUS), ntrailData[i].trailObj);
- ntrailData[i].trailObj = NULL;
+ for (i = 0; i < g_numTrails; i++) {
+ if (g_ntrailData[i].trailObj != NULL) {
+ MultiDeleteObject(GetPlayfieldList(FIELD_STATUS), g_ntrailData[i].trailObj);
+ g_ntrailData[i].trailObj = NULL;
}
}
}
@@ -277,21 +277,21 @@ void DwHideCursor() {
* Unhide the cursor.
*/
void UnHideCursor() {
- bHiddenCursor = false;
+ g_bHiddenCursor = false;
}
/**
* Freeze the cursor.
*/
void FreezeCursor() {
- bFrozenCursor = true;
+ g_bFrozenCursor = true;
}
/**
* Freeze the cursor, or not.
*/
void DoFreezeCursor(bool bFreeze) {
- bFrozenCursor = bFreeze;
+ g_bFrozenCursor = bFreeze;
}
/**
@@ -300,12 +300,12 @@ void DoFreezeCursor(bool bFreeze) {
void HideCursorTrails() {
int i;
- bTempNoTrailers = true;
+ g_bTempNoTrailers = true;
- for (i = 0; i < numTrails; i++) {
- if (ntrailData[i].trailObj != NULL) {
- MultiDeleteObject(GetPlayfieldList(FIELD_STATUS), ntrailData[i].trailObj);
- ntrailData[i].trailObj = NULL;
+ for (i = 0; i < g_numTrails; i++) {
+ if (g_ntrailData[i].trailObj != NULL) {
+ MultiDeleteObject(GetPlayfieldList(FIELD_STATUS), g_ntrailData[i].trailObj);
+ g_ntrailData[i].trailObj = NULL;
}
}
}
@@ -314,7 +314,7 @@ void HideCursorTrails() {
* UnHideCursorTrails
*/
void UnHideCursorTrails() {
- bTempNoTrailers = false;
+ g_bTempNoTrailers = false;
}
/**
@@ -356,9 +356,9 @@ IMAGE *GetImageFromFilm(SCNHANDLE hFilm, int reel, const FREEL **ppfr, const MUL
* Delete auxillary cursor. Restore animation offsets in the image.
*/
void DelAuxCursor() {
- if (AcurObj != NULL) {
- MultiDeleteObject(GetPlayfieldList(FIELD_STATUS), AcurObj);
- AcurObj = NULL;
+ if (g_AcurObj != NULL) {
+ MultiDeleteObject(GetPlayfieldList(FIELD_STATUS), g_AcurObj);
+ g_AcurObj = NULL;
}
}
@@ -381,21 +381,21 @@ void SetAuxCursor(SCNHANDLE hFilm) {
assert(BgPal()); // no background palette
pim->hImgPal = TO_LE_32(BgPal()); // Poke in the background palette
- ACoX = (short)(FROM_LE_16(pim->imgWidth)/2 - ((int16) FROM_LE_16(pim->anioffX)));
- ACoY = (short)((FROM_LE_16(pim->imgHeight) & ~C16_FLAG_MASK)/2 -
+ g_ACoX = (short)(FROM_LE_16(pim->imgWidth)/2 - ((int16) FROM_LE_16(pim->anioffX)));
+ g_ACoY = (short)((FROM_LE_16(pim->imgHeight) & ~C16_FLAG_MASK)/2 -
((int16) FROM_LE_16(pim->anioffY)));
// Initialize and insert the auxillary cursor object
- AcurObj = MultiInitObject(pmi);
- MultiInsertObject(GetPlayfieldList(FIELD_STATUS), AcurObj);
+ g_AcurObj = MultiInitObject(pmi);
+ MultiInsertObject(GetPlayfieldList(FIELD_STATUS), g_AcurObj);
// Initialize the animation and set its position
- InitStepAnimScript(&AcurAnim, AcurObj, FROM_LE_32(pfr->script), ONE_SECOND / FROM_LE_32(pfilm->frate));
- MultiSetAniXY(AcurObj, x - ACoX, y - ACoY);
- MultiSetZPosition(AcurObj, Z_ACURSOR);
+ InitStepAnimScript(&g_AcurAnim, g_AcurObj, FROM_LE_32(pfr->script), ONE_SECOND / FROM_LE_32(pfilm->frate));
+ MultiSetAniXY(g_AcurObj, x - g_ACoX, y - g_ACoY);
+ MultiSetZPosition(g_AcurObj, Z_ACURSOR);
- if (bHiddenCursor)
- MultiHideObject(AcurObj);
+ if (g_bHiddenCursor)
+ MultiHideObject(g_AcurObj);
}
/**
@@ -421,52 +421,52 @@ static void DoCursorMove() {
dir = _vm->getKeyDirection();
if (dir != 0) {
if (dir & MSK_LEFT)
- newX -= IterationSize;
+ newX -= g_IterationSize;
if (dir & MSK_RIGHT)
- newX += IterationSize;
+ newX += g_IterationSize;
if (dir & MSK_UP)
- newY -= IterationSize;
+ newY -= g_IterationSize;
if (dir & MSK_DOWN)
- newY += IterationSize;
+ newY += g_IterationSize;
- IterationSize += ITER_ACCELERATION;
+ g_IterationSize += ITER_ACCELERATION;
// set new mouse driver position
_vm->setMousePosition(Common::Point(fracToInt(newX), fracToInt(newY)));
} else
- IterationSize = ITERATION_BASE;
+ g_IterationSize = ITERATION_BASE;
// get new mouse driver position - could have been modified
ptMouse = _vm->getMousePosition();
- if (lastCursorX != ptMouse.x || lastCursorY != ptMouse.y) {
+ if (g_lastCursorX != ptMouse.x || g_lastCursorY != ptMouse.y) {
resetUserEventTime();
- if (!bTempNoTrailers && !bHiddenCursor) {
- InitCurTrailObj(nextTrail++, lastCursorX, lastCursorY);
- if (nextTrail == numTrails)
- nextTrail = 0;
+ if (!g_bTempNoTrailers && !g_bHiddenCursor) {
+ InitCurTrailObj(g_nextTrail++, g_lastCursorX, g_lastCursorY);
+ if (g_nextTrail == g_numTrails)
+ g_nextTrail = 0;
}
}
// adjust cursor to new mouse position
- if (McurObj)
- MultiSetAniXY(McurObj, ptMouse.x, ptMouse.y);
- if (AcurObj != NULL)
- MultiSetAniXY(AcurObj, ptMouse.x - ACoX, ptMouse.y - ACoY);
+ if (g_McurObj)
+ MultiSetAniXY(g_McurObj, ptMouse.x, ptMouse.y);
+ if (g_AcurObj != NULL)
+ MultiSetAniXY(g_AcurObj, ptMouse.x - g_ACoX, ptMouse.y - g_ACoY);
- if (InventoryActive() && McurObj) {
+ if (InventoryActive() && g_McurObj) {
// Notify the inventory
Xmovement(ptMouse.x - startX);
Ymovement(ptMouse.y - startY);
}
- lastCursorX = ptMouse.x;
- lastCursorY = ptMouse.y;
+ g_lastCursorX = ptMouse.x;
+ g_lastCursorY = ptMouse.y;
}
/**
@@ -479,7 +479,7 @@ static void InitCurObj() {
IMAGE *pim;
if (TinselV2) {
- pFilm = (const FILM *)LockMem(hCursorFilm);
+ pFilm = (const FILM *)LockMem(g_hCursorFilm);
pfr = (const FREEL *)&pFilm->reels[0];
pmi = (MULTI_INIT *)LockMem(FROM_LE_32(pfr->mobj));
@@ -487,16 +487,16 @@ static void InitCurObj() {
} else {
assert(BgPal()); // no background palette
- pim = GetImageFromFilm(hCursorFilm, 0, &pfr, &pmi, &pFilm);// Get pointer to image
+ pim = GetImageFromFilm(g_hCursorFilm, 0, &pfr, &pmi, &pFilm);// Get pointer to image
pim->hImgPal = TO_LE_32(BgPal());
- AcurObj = NULL; // No auxillary cursor
+ g_AcurObj = NULL; // No auxillary cursor
}
- McurObj = MultiInitObject(pmi);
- MultiInsertObject(GetPlayfieldList(FIELD_STATUS), McurObj);
+ g_McurObj = MultiInitObject(pmi);
+ MultiInsertObject(GetPlayfieldList(FIELD_STATUS), g_McurObj);
- InitStepAnimScript(&McurAnim, McurObj, FROM_LE_32(pfr->script), ONE_SECOND / FROM_LE_32(pFilm->frate));
+ InitStepAnimScript(&g_McurAnim, g_McurObj, FROM_LE_32(pfr->script), ONE_SECOND / FROM_LE_32(pFilm->frate));
}
/**
@@ -504,14 +504,14 @@ static void InitCurObj() {
*/
static void InitCurPos() {
Common::Point ptMouse = _vm->getMousePosition();
- lastCursorX = ptMouse.x;
- lastCursorY = ptMouse.y;
+ g_lastCursorX = ptMouse.x;
+ g_lastCursorY = ptMouse.y;
- MultiSetZPosition(McurObj, Z_CURSOR);
+ MultiSetZPosition(g_McurObj, Z_CURSOR);
DoCursorMove();
- MultiHideObject(McurObj);
+ MultiHideObject(g_McurObj);
- IterationSize = ITERATION_BASE;
+ g_IterationSize = ITERATION_BASE;
}
/**
@@ -525,9 +525,9 @@ static void CursorStoppedCheck(CORO_PARAM) {
CORO_BEGIN_CODE(_ctx);
// If scene is closing down
- if (bWhoa) {
+ if (g_bWhoa) {
// ...wait for next scene start-up
- while (restart != 0x8000)
+ while (g_restart != 0x8000)
CORO_SLEEP(1);
// Re-initialize
@@ -536,8 +536,8 @@ static void CursorStoppedCheck(CORO_PARAM) {
InventoryIconCursor(false); // May be holding something
// Re-start the cursor trails
- restart = (uint16)-1; // set all bits
- bWhoa = false;
+ g_restart = (uint16)-1; // set all bits
+ g_bWhoa = false;
}
CORO_END_CODE;
}
@@ -552,15 +552,15 @@ void CursorProcess(CORO_PARAM, const void *) {
CORO_BEGIN_CODE(_ctx);
- while (!hCursorFilm || !BgPal())
+ while (!g_hCursorFilm || !BgPal())
CORO_SLEEP(1);
InitCurObj();
InitCurPos();
InventoryIconCursor(false); // May be holding something
- bWhoa = false;
- restart = 0;
+ g_bWhoa = false;
+ g_restart = 0;
while (1) {
// allow rescheduling
@@ -570,36 +570,36 @@ void CursorProcess(CORO_PARAM, const void *) {
CORO_INVOKE_0(CursorStoppedCheck);
// Step the animation script(s)
- StepAnimScript(&McurAnim);
- if (AcurObj != NULL)
- StepAnimScript(&AcurAnim);
- for (int i = 0; i < numTrails; i++) {
- if (ntrailData[i].trailObj != NULL) {
- if (StepAnimScript(&ntrailData[i].trailAnim) == ScriptFinished) {
- MultiDeleteObject(GetPlayfieldList(FIELD_STATUS), ntrailData[i].trailObj);
- ntrailData[i].trailObj = NULL;
+ StepAnimScript(&g_McurAnim);
+ if (g_AcurObj != NULL)
+ StepAnimScript(&g_AcurAnim);
+ for (int i = 0; i < g_numTrails; i++) {
+ if (g_ntrailData[i].trailObj != NULL) {
+ if (StepAnimScript(&g_ntrailData[i].trailAnim) == ScriptFinished) {
+ MultiDeleteObject(GetPlayfieldList(FIELD_STATUS), g_ntrailData[i].trailObj);
+ g_ntrailData[i].trailObj = NULL;
}
}
}
// Move the cursor as appropriate
- if (!bFrozenCursor)
+ if (!g_bFrozenCursor)
DoCursorMove();
// If the cursor should be hidden...
- if (bHiddenCursor || bTempHide) {
+ if (g_bHiddenCursor || g_bTempHide) {
// ...hide the cursor object(s)
- MultiHideObject(McurObj);
- if (AcurObj)
- MultiHideObject(AcurObj);
+ MultiHideObject(g_McurObj);
+ if (g_AcurObj)
+ MultiHideObject(g_AcurObj);
- for (int i = 0; i < numTrails; i++) {
- if (ntrailData[i].trailObj != NULL)
- MultiHideObject(ntrailData[i].trailObj);
+ for (int i = 0; i < g_numTrails; i++) {
+ if (g_ntrailData[i].trailObj != NULL)
+ MultiHideObject(g_ntrailData[i].trailObj);
}
// Wait 'til cursor is again required.
- while (bHiddenCursor) {
+ while (g_bHiddenCursor) {
CORO_SLEEP(1);
// Stop/start between scenes
@@ -617,12 +617,12 @@ void CursorProcess(CORO_PARAM, const void *) {
void DwInitCursor(SCNHANDLE bfilm) {
const FILM *pfilm;
- hCursorFilm = bfilm;
+ g_hCursorFilm = bfilm;
- pfilm = (const FILM *)LockMem(hCursorFilm);
- numTrails = FROM_LE_32(pfilm->numreels) - 1;
+ pfilm = (const FILM *)LockMem(g_hCursorFilm);
+ g_numTrails = FROM_LE_32(pfilm->numreels) - 1;
- assert(numTrails <= MAX_TRAILERS);
+ assert(g_numTrails <= MAX_TRAILERS);
}
/**
@@ -630,24 +630,24 @@ void DwInitCursor(SCNHANDLE bfilm) {
*/
void DropCursor() {
if (TinselV2) {
- if (AcurObj)
- MultiDeleteObject(GetPlayfieldList(FIELD_STATUS), AcurObj);
- if (McurObj)
- MultiDeleteObject(GetPlayfieldList(FIELD_STATUS), McurObj);
+ if (g_AcurObj)
+ MultiDeleteObject(GetPlayfieldList(FIELD_STATUS), g_AcurObj);
+ if (g_McurObj)
+ MultiDeleteObject(GetPlayfieldList(FIELD_STATUS), g_McurObj);
- restart = 0;
+ g_restart = 0;
}
- AcurObj = NULL; // No auxillary cursor
- McurObj = NULL; // No cursor object (imminently deleted elsewhere)
- bHiddenCursor = false; // Not hidden in next scene
- bTempNoTrailers = false; // Trailers not hidden in next scene
- bWhoa = true; // Suspend cursor processes
+ g_AcurObj = NULL; // No auxillary cursor
+ g_McurObj = NULL; // No cursor object (imminently deleted elsewhere)
+ g_bHiddenCursor = false; // Not hidden in next scene
+ g_bTempNoTrailers = false; // Trailers not hidden in next scene
+ g_bWhoa = true; // Suspend cursor processes
- for (int i = 0; i < numTrails; i++) {
- if (ntrailData[i].trailObj != NULL) {
- MultiDeleteObject(GetPlayfieldList(FIELD_STATUS), ntrailData[i].trailObj);
- ntrailData[i].trailObj = NULL;
+ for (int i = 0; i < g_numTrails; i++) {
+ if (g_ntrailData[i].trailObj != NULL) {
+ MultiDeleteObject(GetPlayfieldList(FIELD_STATUS), g_ntrailData[i].trailObj);
+ g_ntrailData[i].trailObj = NULL;
}
}
}
@@ -656,7 +656,7 @@ void DropCursor() {
* RestartCursor is called when a new scene is starting up.
*/
void RestartCursor() {
- restart = 0x8000; // Get the main cursor to re-initialize
+ g_restart = 0x8000; // Get the main cursor to re-initialize
}
/**
@@ -664,32 +664,32 @@ void RestartCursor() {
* pointers etc.
*/
void RebootCursor() {
- McurObj = AcurObj = NULL;
+ g_McurObj = g_AcurObj = NULL;
for (int i = 0; i < MAX_TRAILERS; i++)
- ntrailData[i].trailObj = NULL;
+ g_ntrailData[i].trailObj = NULL;
- bHiddenCursor = bTempNoTrailers = bFrozenCursor = false;
+ g_bHiddenCursor = g_bTempNoTrailers = g_bFrozenCursor = false;
- hCursorFilm = 0;
+ g_hCursorFilm = 0;
- bWhoa = false;
- restart = 0;
+ g_bWhoa = false;
+ g_restart = 0;
}
void StartCursorFollowed() {
DelAuxCursor();
if (!SysVar(SV_ENABLEPRINTCURSOR))
- bTempHide = true;
+ g_bTempHide = true;
}
void EndCursorFollowed() {
InventoryIconCursor(false); // May be holding something
- bTempHide = false;
+ g_bTempHide = false;
}
bool isCursorShown() {
- return !(bTempHide || bHiddenCursor);
+ return !(g_bTempHide || g_bHiddenCursor);
}
} // End of namespace Tinsel
diff --git a/engines/tinsel/detection.cpp b/engines/tinsel/detection.cpp
index 1fce032633..0f662e22bd 100644
--- a/engines/tinsel/detection.cpp
+++ b/engines/tinsel/detection.cpp
@@ -169,7 +169,7 @@ 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;
-typedef Common::Array<const ADGameDescription*> ADGameDescList;
+typedef Common::Array<const ADGameDescription *> ADGameDescList;
/**
* Fallback detection scans the list of Discworld 2 targets to see if it can detect an installation
diff --git a/engines/tinsel/detection_tables.h b/engines/tinsel/detection_tables.h
index 64a0af8404..be44b1c462 100644
--- a/engines/tinsel/detection_tables.h
+++ b/engines/tinsel/detection_tables.h
@@ -62,7 +62,7 @@ static const TinselGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformPC,
ADGF_DEMO,
- GUIO1(GUIO_NONE)
+ GUIO0()
},
GID_DW1,
0,
@@ -82,7 +82,7 @@ static const TinselGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformMacintosh,
ADGF_DEMO,
- GUIO1(GUIO_NONE)
+ GUIO0()
},
GID_DW1,
0,
@@ -210,7 +210,7 @@ static const TinselGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformPC,
ADGF_CD,
- GUIO1(GUIO_NONE)
+ GUIO0()
},
GID_DW1,
0,
@@ -232,7 +232,7 @@ static const TinselGameDescription gameDescriptions[] = {
Common::IT_ITA,
Common::kPlatformPC,
ADGF_DROPLANGUAGE | ADGF_CD,
- GUIO1(GUIO_NONE)
+ GUIO0()
},
GID_DW1,
0,
@@ -257,7 +257,7 @@ static const TinselGameDescription gameDescriptions[] = {
Common::FR_FRA,
Common::kPlatformPC,
ADGF_DROPLANGUAGE | ADGF_CD,
- GUIO1(GUIO_NONE)
+ GUIO0()
},
GID_DW1,
0,
@@ -281,7 +281,7 @@ static const TinselGameDescription gameDescriptions[] = {
Common::DE_DEU,
Common::kPlatformPC,
ADGF_DROPLANGUAGE | ADGF_CD,
- GUIO1(GUIO_NONE)
+ GUIO0()
},
GID_DW1,
0,
@@ -304,7 +304,7 @@ static const TinselGameDescription gameDescriptions[] = {
Common::IT_ITA,
Common::kPlatformPC,
ADGF_DROPLANGUAGE | ADGF_CD,
- GUIO1(GUIO_NONE)
+ GUIO0()
},
GID_DW1,
0,
@@ -327,7 +327,7 @@ static const TinselGameDescription gameDescriptions[] = {
Common::ES_ESP,
Common::kPlatformPC,
ADGF_DROPLANGUAGE | ADGF_CD,
- GUIO1(GUIO_NONE)
+ GUIO0()
},
GID_DW1,
0,
@@ -347,7 +347,7 @@ static const TinselGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformPC,
ADGF_CD,
- GUIO1(GUIO_NONE)
+ GUIO0()
},
GID_DW1,
0,
@@ -367,7 +367,7 @@ static const TinselGameDescription gameDescriptions[] = {
Common::HE_ISR,
Common::kPlatformPC,
ADGF_CD,
- GUIO1(GUIO_NONE)
+ GUIO0()
},
GID_DW1,
0,
@@ -386,7 +386,7 @@ static const TinselGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformPSX,
ADGF_CD,
- GUIO1(GUIO_NONE)
+ GUIO0()
},
GID_DW1,
0,
@@ -409,7 +409,7 @@ static const TinselGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformPSX,
ADGF_DEMO,
- GUIO1(GUIO_NONE)
+ GUIO0()
},
GID_DW1,
0,
@@ -430,7 +430,7 @@ static const TinselGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformPC,
ADGF_CD,
- GUIO1(GUIO_NONE)
+ GUIO0()
},
GID_DW1,
0,
@@ -452,7 +452,7 @@ static const TinselGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformMacintosh,
ADGF_CD,
- GUIO1(GUIO_NONE)
+ GUIO0()
},
GID_DW1,
0,
@@ -471,7 +471,7 @@ static const TinselGameDescription gameDescriptions[] = {
Common::DE_DEU,
Common::kPlatformPC,
ADGF_CD,
- GUIO1(GUIO_NONE)
+ GUIO0()
},
GID_DW1,
0,
@@ -492,7 +492,7 @@ static const TinselGameDescription gameDescriptions[] = {
Common::RU_RUS,
Common::kPlatformPC,
ADGF_CD,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GID_DW1,
0,
@@ -512,7 +512,7 @@ static const TinselGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformPC,
ADGF_DEMO,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GID_DW2,
0,
@@ -532,7 +532,7 @@ static const TinselGameDescription gameDescriptions[] = {
Common::EN_GRB,
Common::kPlatformPC,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GID_DW2,
0,
@@ -552,7 +552,7 @@ static const TinselGameDescription gameDescriptions[] = {
Common::EN_USA,
Common::kPlatformPC,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GID_DW2,
0,
@@ -572,7 +572,7 @@ static const TinselGameDescription gameDescriptions[] = {
Common::FR_FRA,
Common::kPlatformPC,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GID_DW2,
0,
@@ -592,7 +592,7 @@ static const TinselGameDescription gameDescriptions[] = {
Common::DE_DEU,
Common::kPlatformPC,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GID_DW2,
0,
@@ -613,7 +613,7 @@ static const TinselGameDescription gameDescriptions[] = {
Common::IT_ITA,
Common::kPlatformPC,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GID_DW2,
0,
@@ -633,7 +633,7 @@ static const TinselGameDescription gameDescriptions[] = {
Common::ES_ESP,
Common::kPlatformPC,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GID_DW2,
0,
@@ -654,7 +654,7 @@ static const TinselGameDescription gameDescriptions[] = {
Common::RU_RUS,
Common::kPlatformPC,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GID_DW2,
0,
diff --git a/engines/tinsel/dialogs.cpp b/engines/tinsel/dialogs.cpp
index 6ca070b67a..5396e47566 100644
--- a/engines/tinsel/dialogs.cpp
+++ b/engines/tinsel/dialogs.cpp
@@ -63,17 +63,6 @@
namespace Tinsel {
-//----------------- EXTERNAL GLOBAL DATA --------------------
-
-// In DOS_DW.C
-extern bool bRestart; // restart flag - set to restart the game
-
-#ifdef MAC_OPTIONS
-// In MAC_SOUND.C
-extern int volMaster;
-#endif
-
-
//----------------- LOCAL DEFINES --------------------
#define HOPPER_FILENAME "hopper"
@@ -312,23 +301,23 @@ static const int vFillers[MAXVICONS] = {
//----- Permanent data (set once) -----
-static SCNHANDLE hWinParts = 0; // Window members and cursors' graphic data
-static SCNHANDLE flagFilm = 0; // Window members and cursors' graphic data
-static SCNHANDLE configStrings[20];
+static SCNHANDLE g_hWinParts = 0; // Window members and cursors' graphic data
+static SCNHANDLE g_flagFilm = 0; // Window members and cursors' graphic data
+static SCNHANDLE g_configStrings[20];
-static INV_OBJECT *invObjects = NULL; // Inventory objects' data
-static int numObjects = 0; // Number of inventory objects
-static SCNHANDLE *invFilms = NULL;
-static bool bNoLanguage = false;
-static DIRECTION initialDirection;
+static INV_OBJECT *g_invObjects = NULL; // Inventory objects' data
+static int g_numObjects = 0; // Number of inventory objects
+static SCNHANDLE *g_invFilms = NULL;
+static bool g_bNoLanguage = false;
+static DIRECTION g_initialDirection;
//----- Permanent data (updated, valid while inventory closed) -----
-static enum {NO_INV, IDLE_INV, ACTIVE_INV, BOGUS_INV} InventoryState;
+static enum {NO_INV, IDLE_INV, ACTIVE_INV, BOGUS_INV} g_InventoryState;
-static int HeldItem = INV_NOICON; // Current held item
+static int g_heldItem = INV_NOICON; // Current held item
-static SCNHANDLE heldFilm;
+static SCNHANDLE g_heldFilm;
struct INV_DEF {
@@ -364,60 +353,60 @@ struct INV_DEF {
};
-static INV_DEF InvD[NUM_INV]; // Conversation + 2 inventories + ...
+static INV_DEF g_InvD[NUM_INV]; // Conversation + 2 inventories + ...
// Permanent contents of conversation inventory
-static int permIcons[MAX_PERMICONS]; // Basic items i.e. permanent contents
-static int numPermIcons = 0; // - copy to conv. inventory at pop-up time
-static int numEndIcons = 0;
+static int g_permIcons[MAX_PERMICONS]; // Basic items i.e. permanent contents
+static int g_numPermIcons = 0; // - copy to conv. inventory at pop-up time
+static int g_numEndIcons = 0;
//----- Data pertinant to current active inventory -----
-static int ino = 0; // Which inventory is currently active
+static int g_ino = 0; // Which inventory is currently active
-static bool InventoryHidden = false;
-static bool InventoryMaximised = false;
+static bool g_InventoryHidden = false;
+static bool g_InventoryMaximised = false;
static enum { ID_NONE, ID_MOVE, ID_SLIDE,
ID_BOTTOM, ID_TOP, ID_LEFT, ID_RIGHT,
ID_TLEFT, ID_TRIGHT, ID_BLEFT, ID_BRIGHT,
- ID_CSLIDE, ID_MDCONT } InvDragging;
+ ID_CSLIDE, ID_MDCONT } g_InvDragging;
-static int SuppH = 0; // 'Linear' element of
-static int SuppV = 0; // dimensions during re-sizing
+static int g_SuppH = 0; // 'Linear' element of
+static int g_SuppV = 0; // dimensions during re-sizing
-static int Ychange = 0; //
-static int Ycompensate = 0; // All to do with re-sizing.
-static int Xchange = 0; //
-static int Xcompensate = 0; //
+static int g_Ychange = 0; //
+static int g_Ycompensate = 0; // All to do with re-sizing.
+static int g_Xchange = 0; //
+static int g_Xcompensate = 0; //
-static bool ItemsChanged = 0; // When set, causes items to be re-drawn
+static bool g_ItemsChanged = 0; // When set, causes items to be re-drawn
-static bool bReOpenMenu = 0;
+static bool g_bReOpenMenu = 0;
-static int TL = 0, TR = 0, BL = 0, BR = 0; // Used during window construction
-static int TLwidth = 0, TLheight = 0; //
-static int TRwidth = 0; //
-static int BLheight = 0; //
+static int g_TL = 0, g_TR = 0, g_BL = 0, g_BR = 0; // Used during window construction
+static int g_TLwidth = 0, g_TLheight = 0; //
+static int g_TRwidth = 0; //
+static int g_BLheight = 0; //
-static LANGUAGE displayedLanguage;
+static LANGUAGE g_displayedLanguage;
-static OBJECT *objArray[MAX_WCOMP]; // Current display objects (window)
-static OBJECT *iconArray[MAX_ICONS]; // Current display objects (icons)
-static ANIM iconAnims[MAX_ICONS];
-static OBJECT *DobjArray[MAX_WCOMP]; // Current display objects (re-sizing window)
+static OBJECT *g_objArray[MAX_WCOMP]; // Current display objects (window)
+static OBJECT *g_iconArray[MAX_ICONS]; // Current display objects (icons)
+static ANIM g_iconAnims[MAX_ICONS];
+static OBJECT *g_DobjArray[MAX_WCOMP]; // Current display objects (re-sizing window)
-static OBJECT *RectObject = 0, *SlideObject = 0; // Current display objects, for reference
+static OBJECT *g_RectObject = 0, *g_SlideObject = 0; // Current display objects, for reference
// objects are in objArray.
-static int sliderYpos = 0; // For positioning the slider
-static int sliderYmax = 0, sliderYmin = 0; //
+static int g_sliderYpos = 0; // For positioning the slider
+static int g_sliderYmax = 0, g_sliderYmin = 0; //
-#define sliderRange (sliderYmax - sliderYmin)
+#define sliderRange (g_sliderYmax - g_sliderYmin)
// Also to do with the slider
-static struct { int n; int y; } slideStuff[MAX_ININV_TOT+1];
+static struct { int n; int y; } g_slideStuff[MAX_ININV_TOT+1];
#define MAXSLIDES 4
struct MDSLIDES {
@@ -425,25 +414,25 @@ struct MDSLIDES {
OBJECT *obj;
int min, max;
};
-static MDSLIDES mdSlides[MAXSLIDES];
-static int numMdSlides = 0;
+static MDSLIDES g_mdSlides[MAXSLIDES];
+static int g_numMdSlides = 0;
-static int GlitterIndex = 0;
+static int g_GlitterIndex = 0;
// Icon clicked on to cause an event
// - Passed to conversation polygon or actor code via Topic()
// - (sometimes) Passed to inventory icon code via OtherObject()
-static int thisIcon = 0;
+static int g_thisIcon = 0;
-static CONV_PARAM thisConvFn; // Top, 'Middle' or Bottom
-static HPOLYGON thisConvPoly = 0; // Conversation code is in a polygon code block
-static int thisConvActor; // ...or an actor's code block.
-static int pointedIcon = INV_NOICON; // used by InvLabels - icon pointed to on last call
-static volatile int PointedWaitCount = 0; // used by ObjectProcess - fix the 'repeated pressing bug'
-static int sX = 0; // used by SlideMSlider() - current x-coordinate
-static int lX = 0; // used by SlideMSlider() - last x-coordinate
+static CONV_PARAM g_thisConvFn; // Top, 'Middle' or Bottom
+static HPOLYGON g_thisConvPoly = 0; // Conversation code is in a polygon code block
+static int g_thisConvActor; // ...or an actor's code block.
+static int g_pointedIcon = INV_NOICON; // used by InvLabels - icon pointed to on last call
+static volatile int g_PointedWaitCount = 0; // used by ObjectProcess - fix the 'repeated pressing bug'
+static int g_sX = 0; // used by SlideMSlider() - current x-coordinate
+static int g_lX = 0; // used by SlideMSlider() - last x-coordinate
-static bool bMoveOnUnHide; // Set before start of conversation
+static bool g_bMoveOnUnHide; // Set before start of conversation
// - causes conversation to be started in a sensible place
//----- Data pertinant to configure (incl. load/save game) -----
@@ -486,16 +475,16 @@ typedef HOPENTRY *PHOPENTRY;
#include "common/pack-end.h" // END STRUCT PACKING
-static PHOPPER pHopper;
-static PHOPENTRY pEntries;
-static int numScenes;
+static PHOPPER g_pHopper;
+static PHOPENTRY g_pEntries;
+static int g_numScenes;
-static int numEntries;
+static int g_numEntries;
-static PHOPPER pChosenScene = NULL;
+static PHOPPER g_pChosenScene = NULL;
-static int lastChosenScene;
-static bool bRemember;
+static int g_lastChosenScene;
+static bool g_bRemember;
//--------------------------------------------------------------
@@ -970,7 +959,7 @@ static struct {
};
// For editing save game names
-static char sedit[SG_DESC_LEN+2];
+static char g_sedit[SG_DESC_LEN+2];
#define HL1 0 // Hilight that moves with the cursor
#define HL2 1 // Hilight on selected RGROUP box
@@ -1096,7 +1085,7 @@ static void PrimeSceneHopper() {
vSize = f.readUint32LE();
// allocate a buffer for it all
- assert(pHopper == NULL);
+ assert(g_pHopper == NULL);
uint32 size = f.size() - 8;
// make sure memory allocated
@@ -1111,9 +1100,9 @@ static void PrimeSceneHopper() {
error(FILE_IS_CORRUPT, HOPPER_FILENAME);
// Set data pointers
- pHopper = (PHOPPER)pBuffer;
- pEntries = (PHOPENTRY)(pBuffer + vSize);
- numScenes = vSize / sizeof(HOPPER);
+ g_pHopper = (PHOPPER)pBuffer;
+ g_pEntries = (PHOPENTRY)(pBuffer + vSize);
+ g_numScenes = vSize / sizeof(HOPPER);
// close the file
f.close();
@@ -1123,31 +1112,31 @@ static void PrimeSceneHopper() {
* Free the scene hopper data file
*/
static void FreeSceneHopper() {
- free(pHopper);
- pHopper = NULL;
+ free(g_pHopper);
+ g_pHopper = NULL;
}
static void FirstScene(int first) {
int i;
- assert(numScenes && pHopper);
+ assert(g_numScenes && g_pHopper);
- if (bRemember) {
+ if (g_bRemember) {
assert(first == 0);
- first = lastChosenScene;
- bRemember = false;
+ first = g_lastChosenScene;
+ g_bRemember = false;
}
// Force it to a sensible value
- if (first > numScenes - NUM_RGROUP_BOXES)
- first = numScenes - NUM_RGROUP_BOXES;
+ if (first > g_numScenes - NUM_RGROUP_BOXES)
+ first = g_numScenes - NUM_RGROUP_BOXES;
if (first < 0)
first = 0;
// Fill in the rest
- for (i = 0; i < NUM_RGROUP_BOXES && i + first < numScenes; i++) {
+ for (i = 0; i < NUM_RGROUP_BOXES && i + first < g_numScenes; i++) {
cd.box[i].textMethod = TM_STRINGNUM;
- cd.box[i].ixText = FROM_LE_32(pHopper[i + first].hSceneDesc);
+ cd.box[i].ixText = FROM_LE_32(g_pHopper[i + first].hSceneDesc);
}
// Blank out the spare ones (if any)
while (i < NUM_RGROUP_BOXES) {
@@ -1159,31 +1148,31 @@ static void FirstScene(int first) {
}
static void RememberChosenScene() {
- bRemember = true;
+ g_bRemember = true;
}
static void SetChosenScene() {
- lastChosenScene = cd.selBox + cd.extraBase;
- pChosenScene = &pHopper[cd.selBox + cd.extraBase];
+ g_lastChosenScene = cd.selBox + cd.extraBase;
+ g_pChosenScene = &g_pHopper[cd.selBox + cd.extraBase];
}
static void FirstEntry(int first) {
int i;
- InvD[INV_MENU].hInvTitle = FROM_LE_32(pChosenScene->hSceneDesc);
+ g_InvD[INV_MENU].hInvTitle = FROM_LE_32(g_pChosenScene->hSceneDesc);
// get number of entrances
- numEntries = FROM_LE_32(pChosenScene->numEntries);
+ g_numEntries = FROM_LE_32(g_pChosenScene->numEntries);
// Force first to a sensible value
- if (first > numEntries-NUM_RGROUP_BOXES)
- first = numEntries-NUM_RGROUP_BOXES;
+ if (first > g_numEntries-NUM_RGROUP_BOXES)
+ first = g_numEntries-NUM_RGROUP_BOXES;
if (first < 0)
first = 0;
- for (i = 0; i < NUM_RGROUP_BOXES && i < numEntries; i++) {
+ for (i = 0; i < NUM_RGROUP_BOXES && i < g_numEntries; i++) {
cd.box[i].textMethod = TM_STRINGNUM;
- cd.box[i].ixText = FROM_LE_32(pEntries[FROM_LE_32(pChosenScene->entryIndex) + i + first].hDesc);
+ cd.box[i].ixText = FROM_LE_32(g_pEntries[FROM_LE_32(g_pChosenScene->entryIndex) + i + first].hDesc);
}
// Blank out the spare ones (if any)
while (i < NUM_RGROUP_BOXES) {
@@ -1195,15 +1184,15 @@ static void FirstEntry(int first) {
}
static void HopAction() {
- PHOPENTRY pEntry = pEntries + FROM_LE_32(pChosenScene->entryIndex) + cd.selBox + cd.extraBase;
+ PHOPENTRY pEntry = g_pEntries + FROM_LE_32(g_pChosenScene->entryIndex) + cd.selBox + cd.extraBase;
- uint32 hScene = FROM_LE_32(pChosenScene->hScene);
+ uint32 hScene = FROM_LE_32(g_pChosenScene->hScene);
uint32 eNumber = FROM_LE_32(pEntry->eNumber);
debugC(DEBUG_BASIC, kTinselDebugAnimations, "Scene hopper chose scene %xh,%d\n", hScene, eNumber);
if (FROM_LE_32(pEntry->flags) & fCall) {
SaveScene(nullContext);
- NewScene(nullContext, pChosenScene->hScene, pEntry->eNumber, TRANS_FADE);
+ NewScene(nullContext, g_pChosenScene->hScene, pEntry->eNumber, TRANS_FADE);
}
else if (FROM_LE_32(pEntry->flags) & fHook)
HookScene(hScene, eNumber, TRANS_FADE);
@@ -1220,9 +1209,9 @@ static void HopAction() {
*/
static void DumpIconArray() {
for (int i = 0; i < MAX_ICONS; i++) {
- if (iconArray[i] != NULL) {
- MultiDeleteObject(GetPlayfieldList(FIELD_STATUS), iconArray[i]);
- iconArray[i] = NULL;
+ if (g_iconArray[i] != NULL) {
+ MultiDeleteObject(GetPlayfieldList(FIELD_STATUS), g_iconArray[i]);
+ g_iconArray[i] = NULL;
}
}
}
@@ -1232,9 +1221,9 @@ static void DumpIconArray() {
*/
static void DumpDobjArray() {
for (int i = 0; i < MAX_WCOMP; i++) {
- if (DobjArray[i] != NULL) {
- MultiDeleteObject(GetPlayfieldList(FIELD_STATUS), DobjArray[i]);
- DobjArray[i] = NULL;
+ if (g_DobjArray[i] != NULL) {
+ MultiDeleteObject(GetPlayfieldList(FIELD_STATUS), g_DobjArray[i]);
+ g_DobjArray[i] = NULL;
}
}
}
@@ -1244,9 +1233,9 @@ static void DumpDobjArray() {
*/
static void DumpObjArray() {
for (int i = 0; i < MAX_WCOMP; i++) {
- if (objArray[i] != NULL) {
- MultiDeleteObject(GetPlayfieldList(FIELD_STATUS), objArray[i]);
- objArray[i] = NULL;
+ if (g_objArray[i] != NULL) {
+ MultiDeleteObject(GetPlayfieldList(FIELD_STATUS), g_objArray[i]);
+ g_objArray[i] = NULL;
}
}
}
@@ -1256,9 +1245,9 @@ static void DumpObjArray() {
* i.e. Image data and Glitter code.
*/
static INV_OBJECT *GetInvObject(int id) {
- INV_OBJECT *pObject = invObjects;
+ INV_OBJECT *pObject = g_invObjects;
- for (int i = 0; i < numObjects; i++, pObject++) {
+ for (int i = 0; i < g_numObjects; i++, pObject++) {
if (pObject->id == id)
return pObject;
}
@@ -1270,9 +1259,9 @@ static INV_OBJECT *GetInvObject(int id) {
* Convert item ID number to index.
*/
static int GetObjectIndex(int id) {
- INV_OBJECT *pObject = invObjects;
+ INV_OBJECT *pObject = g_invObjects;
- for (int i = 0; i < numObjects; i++, pObject++) {
+ for (int i = 0; i < g_numObjects; i++, pObject++) {
if (pObject->id == id)
return i;
}
@@ -1287,15 +1276,15 @@ static int GetObjectIndex(int id) {
extern int InventoryPos(int num) {
int i;
- for (i = 0; i < InvD[INV_1].NoofItems; i++) // First inventory
- if (InvD[INV_1].contents[i] == num)
+ for (i = 0; i < g_InvD[INV_1].NoofItems; i++) // First inventory
+ if (g_InvD[INV_1].contents[i] == num)
return i;
- for (i = 0; i < InvD[INV_2].NoofItems; i++) // Second inventory
- if (InvD[INV_2].contents[i] == num)
+ for (i = 0; i < g_InvD[INV_2].NoofItems; i++) // Second inventory
+ if (g_InvD[INV_2].contents[i] == num)
return i;
- if (HeldItem == num)
+ if (g_heldItem == num)
return INV_HELDNOTIN; // Held, but not in either inventory
return INV_NOICON; // Not held, not in either inventory
@@ -1304,8 +1293,8 @@ extern int InventoryPos(int num) {
extern bool IsInInventory(int object, int invnum) {
assert(invnum == INV_1 || invnum == INV_2);
- for (int i = 0; i < InvD[invnum].NoofItems; i++) // First inventory
- if (InvD[invnum].contents[i] == object)
+ for (int i = 0; i < g_InvD[invnum].NoofItems; i++) // First inventory
+ if (g_InvD[invnum].contents[i] == object)
return true;
return false;
@@ -1315,7 +1304,7 @@ extern bool IsInInventory(int object, int invnum) {
* Returns which item is held (INV_NOICON (-1) if none)
*/
extern int WhichItemHeld() {
- return HeldItem;
+ return g_heldItem;
}
/**
@@ -1324,15 +1313,15 @@ extern int WhichItemHeld() {
*/
extern void InventoryIconCursor(bool bNewItem) {
- if (HeldItem != INV_NOICON) {
+ if (g_heldItem != INV_NOICON) {
if (TinselV2) {
if (bNewItem) {
- int objIndex = GetObjectIndex(HeldItem);
- heldFilm = invFilms[objIndex];
+ int objIndex = GetObjectIndex(g_heldItem);
+ g_heldFilm = g_invFilms[objIndex];
}
- SetAuxCursor(heldFilm);
+ SetAuxCursor(g_heldFilm);
} else {
- INV_OBJECT *invObj = GetInvObject(HeldItem);
+ INV_OBJECT *invObj = GetInvObject(g_heldItem);
SetAuxCursor(invObj->hIconFilm);
}
}
@@ -1342,14 +1331,14 @@ extern void InventoryIconCursor(bool bNewItem) {
* Returns true if the inventory is active.
*/
extern bool InventoryActive() {
- return (InventoryState == ACTIVE_INV);
+ return (g_InventoryState == ACTIVE_INV);
}
extern int WhichInventoryOpen() {
- if (InventoryState != ACTIVE_INV)
+ if (g_InventoryState != ACTIVE_INV)
return 0;
else
- return ino;
+ return g_ino;
}
@@ -1387,7 +1376,7 @@ static void ObjectProcess(CORO_PARAM, const void *param) {
CORO_INVOKE_1(Interpret, _ctx->pic);
if (to->event == POINTED) {
- _ctx->ThisPointedWait = ++PointedWaitCount;
+ _ctx->ThisPointedWait = ++g_PointedWaitCount;
while (1) {
CORO_SLEEP(1);
int x, y;
@@ -1396,7 +1385,7 @@ static void ObjectProcess(CORO_PARAM, const void *param) {
break;
// Fix the 'repeated pressing bug'
- if (_ctx->ThisPointedWait != PointedWaitCount)
+ if (_ctx->ThisPointedWait != g_PointedWaitCount)
CORO_KILL_SELF();
}
@@ -1413,10 +1402,10 @@ static void ObjectProcess(CORO_PARAM, const void *param) {
static void InvTinselEvent(INV_OBJECT *pinvo, TINSEL_EVENT event, PLR_EVENT be, int index) {
OP_INIT to = { pinvo, event, be, 0 };
- if (InventoryHidden || (TinselV2 && !pinvo->hScript))
+ if (g_InventoryHidden || (TinselV2 && !pinvo->hScript))
return;
- GlitterIndex = index;
+ g_GlitterIndex = index;
g_scheduler->createProcess(PID_TCODE, ObjectProcess, &to, sizeof(to));
}
@@ -1491,9 +1480,9 @@ static void FirstFile(int first) {
static void InvSaveGame() {
if (cd.selBox != NOBOX) {
#ifndef JAPAN
- sedit[strlen(sedit)-1] = 0; // Don't include the cursor!
+ g_sedit[strlen(g_sedit)-1] = 0; // Don't include the cursor!
#endif
- SaveGame(ListEntry(cd.selBox-cd.modifier+cd.extraBase, LE_NAME), sedit);
+ SaveGame(ListEntry(cd.selBox-cd.modifier+cd.extraBase, LE_NAME), g_sedit);
}
}
@@ -1506,17 +1495,17 @@ static void InvLoadGame() {
if (cd.selBox != NOBOX && (cd.selBox+cd.extraBase < cd.numSaved)) {
rGame = cd.selBox;
cd.selBox = NOBOX;
- if (iconArray[HL3] != NULL) {
- MultiDeleteObject(GetPlayfieldList(FIELD_STATUS), iconArray[HL3]);
- iconArray[HL3] = NULL;
+ if (g_iconArray[HL3] != NULL) {
+ MultiDeleteObject(GetPlayfieldList(FIELD_STATUS), g_iconArray[HL3]);
+ g_iconArray[HL3] = NULL;
}
- if (iconArray[HL2] != NULL) {
- MultiDeleteObject(GetPlayfieldList(FIELD_STATUS), iconArray[HL2]);
- iconArray[HL2] = NULL;
+ if (g_iconArray[HL2] != NULL) {
+ MultiDeleteObject(GetPlayfieldList(FIELD_STATUS), g_iconArray[HL2]);
+ g_iconArray[HL2] = NULL;
}
- if (iconArray[HL1] != NULL) {
- MultiDeleteObject(GetPlayfieldList(FIELD_STATUS), iconArray[HL1]);
- iconArray[HL1] = NULL;
+ if (g_iconArray[HL1] != NULL) {
+ MultiDeleteObject(GetPlayfieldList(FIELD_STATUS), g_iconArray[HL1]);
+ g_iconArray[HL1] = NULL;
}
RestoreGame(rGame+cd.extraBase);
}
@@ -1533,7 +1522,7 @@ static bool UpdateString(const Common::KeyState &kbd) {
if (!cd.editableRgroup)
return false;
- cpos = strlen(sedit)-1;
+ cpos = strlen(g_sedit)-1;
if (kbd.ascii == 0)
return false;
@@ -1541,18 +1530,18 @@ static bool UpdateString(const Common::KeyState &kbd) {
if (kbd.keycode == Common::KEYCODE_BACKSPACE) {
if (!cpos)
return false;
- sedit[cpos] = 0;
+ g_sedit[cpos] = 0;
cpos--;
- sedit[cpos] = CURSOR_CHAR;
+ g_sedit[cpos] = CURSOR_CHAR;
return true;
// } else if (isalnum(c) || c == ',' || c == '.' || c == '\'' || (c == ' ' && cpos != 0)) {
} else if (IsCharImage(GetTagFontHandle(), kbd.ascii) || (kbd.ascii == ' ' && cpos != 0)) {
if (cpos == SG_DESC_LEN)
return false;
- sedit[cpos] = kbd.ascii;
+ g_sedit[cpos] = kbd.ascii;
cpos++;
- sedit[cpos] = CURSOR_CHAR;
- sedit[cpos+1] = 0;
+ g_sedit[cpos] = CURSOR_CHAR;
+ g_sedit[cpos+1] = 0;
return true;
}
return false;
@@ -1582,25 +1571,25 @@ static bool InvKeyIn(const Common::KeyState &kbd) {
* Delete display of text currently being edited,
* and replace it with freshly edited text.
*/
- if (iconArray[HL3] != NULL) {
- MultiDeleteObject(GetPlayfieldList(FIELD_STATUS), iconArray[HL3]);
- iconArray[HL3] = NULL;
+ if (g_iconArray[HL3] != NULL) {
+ MultiDeleteObject(GetPlayfieldList(FIELD_STATUS), g_iconArray[HL3]);
+ g_iconArray[HL3] = NULL;
}
- iconArray[HL3] = ObjectTextOut(
- GetPlayfieldList(FIELD_STATUS), sedit, 0,
- InvD[ino].inventoryX + cd.box[cd.selBox].xpos + 2,
- InvD[ino].inventoryY + cd.box[cd.selBox].ypos + TYOFF,
+ g_iconArray[HL3] = ObjectTextOut(
+ GetPlayfieldList(FIELD_STATUS), g_sedit, 0,
+ g_InvD[g_ino].inventoryX + cd.box[cd.selBox].xpos + 2,
+ g_InvD[g_ino].inventoryY + cd.box[cd.selBox].ypos + TYOFF,
GetTagFontHandle(), 0);
- if (MultiRightmost(iconArray[HL3]) > MAX_NAME_RIGHT) {
- MultiDeleteObject(GetPlayfieldList(FIELD_STATUS), iconArray[HL3]);
+ if (MultiRightmost(g_iconArray[HL3]) > MAX_NAME_RIGHT) {
+ MultiDeleteObject(GetPlayfieldList(FIELD_STATUS), g_iconArray[HL3]);
UpdateString(Common::KeyState(Common::KEYCODE_BACKSPACE));
- iconArray[HL3] = ObjectTextOut(
- GetPlayfieldList(FIELD_STATUS), sedit, 0,
- InvD[ino].inventoryX + cd.box[cd.selBox].xpos + 2,
- InvD[ino].inventoryY + cd.box[cd.selBox].ypos + TYOFF,
+ g_iconArray[HL3] = ObjectTextOut(
+ GetPlayfieldList(FIELD_STATUS), g_sedit, 0,
+ g_InvD[g_ino].inventoryX + cd.box[cd.selBox].xpos + 2,
+ g_InvD[g_ino].inventoryY + cd.box[cd.selBox].ypos + TYOFF,
GetTagFontHandle(), 0);
}
- MultiSetZPosition(iconArray[HL3], Z_INV_ITEXT + 2);
+ MultiSetZPosition(g_iconArray[HL3], Z_INV_ITEXT + 2);
}
#endif
}
@@ -1625,28 +1614,28 @@ static void Select(int i, bool force) {
cd.selBox = i;
// Clear previous selected highlight and text
- if (iconArray[HL2] != NULL) {
- MultiDeleteObject(GetPlayfieldList(FIELD_STATUS), iconArray[HL2]);
- iconArray[HL2] = NULL;
+ if (g_iconArray[HL2] != NULL) {
+ MultiDeleteObject(GetPlayfieldList(FIELD_STATUS), g_iconArray[HL2]);
+ g_iconArray[HL2] = NULL;
}
- if (iconArray[HL3] != NULL) {
- MultiDeleteObject(GetPlayfieldList(FIELD_STATUS), iconArray[HL3]);
- iconArray[HL3] = NULL;
+ if (g_iconArray[HL3] != NULL) {
+ MultiDeleteObject(GetPlayfieldList(FIELD_STATUS), g_iconArray[HL3]);
+ g_iconArray[HL3] = NULL;
}
// New highlight box
switch (cd.box[i].boxType) {
case RGROUP:
- iconArray[HL2] = RectangleObject(BgPal(),
+ g_iconArray[HL2] = RectangleObject(BgPal(),
(TinselV2 ? HighlightColor() : COL_HILIGHT), cd.box[i].w, cd.box[i].h);
- MultiInsertObject(GetPlayfieldList(FIELD_STATUS), iconArray[HL2]);
- MultiSetAniXY(iconArray[HL2],
- InvD[ino].inventoryX + cd.box[i].xpos,
- InvD[ino].inventoryY + cd.box[i].ypos);
+ MultiInsertObject(GetPlayfieldList(FIELD_STATUS), g_iconArray[HL2]);
+ MultiSetAniXY(g_iconArray[HL2],
+ g_InvD[g_ino].inventoryX + cd.box[i].xpos,
+ g_InvD[g_ino].inventoryY + cd.box[i].ypos);
// Z-position of box, and add edit text if appropriate
if (cd.editableRgroup) {
- MultiSetZPosition(iconArray[HL2], Z_INV_ITEXT+1);
+ MultiSetZPosition(g_iconArray[HL2], Z_INV_ITEXT+1);
if (TinselV2) {
assert(cd.box[i].textMethod == TM_POINTER);
@@ -1657,29 +1646,29 @@ static void Select(int i, bool force) {
// Current date and time
time(&secs_now);
time_now = localtime(&secs_now);
- strftime(sedit, SG_DESC_LEN, "%D %H:%M", time_now);
+ strftime(g_sedit, SG_DESC_LEN, "%D %H:%M", time_now);
#else
// Current description with cursor appended
if (cd.box[i].boxText != NULL) {
- strcpy(sedit, cd.box[i].boxText);
- strcat(sedit, sCursor);
+ strcpy(g_sedit, cd.box[i].boxText);
+ strcat(g_sedit, sCursor);
} else {
- strcpy(sedit, sCursor);
+ strcpy(g_sedit, sCursor);
}
#endif
- iconArray[HL3] = ObjectTextOut(
- GetPlayfieldList(FIELD_STATUS), sedit, 0,
- InvD[ino].inventoryX + cd.box[i].xpos + 2,
+ g_iconArray[HL3] = ObjectTextOut(
+ GetPlayfieldList(FIELD_STATUS), g_sedit, 0,
+ g_InvD[g_ino].inventoryX + cd.box[i].xpos + 2,
#ifdef JAPAN
- InvD[ino].inventoryY + cd.box[i].ypos + 2,
+ g_InvD[g_ino].inventoryY + cd.box[i].ypos + 2,
#else
- InvD[ino].inventoryY + cd.box[i].ypos + TYOFF,
+ g_InvD[g_ino].inventoryY + cd.box[i].ypos + TYOFF,
#endif
GetTagFontHandle(), 0);
- MultiSetZPosition(iconArray[HL3], Z_INV_ITEXT + 2);
+ MultiSetZPosition(g_iconArray[HL3], Z_INV_ITEXT + 2);
} else {
- MultiSetZPosition(iconArray[HL2], Z_INV_ICONS + 1);
+ MultiSetZPosition(g_iconArray[HL2], Z_INV_ICONS + 1);
}
_vm->divertKeyInput(InvKeyIn);
@@ -1687,12 +1676,12 @@ static void Select(int i, bool force) {
break;
case FRGROUP:
- iconArray[HL2] = RectangleObject(BgPal(), COL_HILIGHT, cd.box[i].w+6, cd.box[i].h+6);
- MultiInsertObject(GetPlayfieldList(FIELD_STATUS), iconArray[HL2]);
- MultiSetAniXY(iconArray[HL2],
- InvD[ino].inventoryX + cd.box[i].xpos - 2,
- InvD[ino].inventoryY + cd.box[i].ypos - 2);
- MultiSetZPosition(iconArray[HL2], Z_INV_BRECT+1);
+ g_iconArray[HL2] = RectangleObject(BgPal(), COL_HILIGHT, cd.box[i].w+6, cd.box[i].h+6);
+ MultiInsertObject(GetPlayfieldList(FIELD_STATUS), g_iconArray[HL2]);
+ MultiSetAniXY(g_iconArray[HL2],
+ g_InvD[g_ino].inventoryX + cd.box[i].xpos - 2,
+ g_InvD[g_ino].inventoryY + cd.box[i].ypos - 2);
+ MultiSetZPosition(g_iconArray[HL2], Z_INV_BRECT+1);
break;
@@ -1710,13 +1699,13 @@ static void Select(int i, bool force) {
* Stop holding an item.
*/
extern void DropItem(int item) {
- if (HeldItem == item) {
- HeldItem = INV_NOICON; // Item not held
+ if (g_heldItem == item) {
+ g_heldItem = INV_NOICON; // Item not held
DelAuxCursor(); // no longer aux cursor
}
// Redraw contents - held item was not displayed as a content.
- ItemsChanged = true;
+ g_ItemsChanged = true;
}
/**
@@ -1725,8 +1714,8 @@ extern void DropItem(int item) {
extern void ClearInventory(int invno) {
assert(invno == INV_1 || invno == INV_2);
- InvD[invno].NoofItems = 0;
- memset(InvD[invno].contents, 0, sizeof(InvD[invno].contents));
+ g_InvD[invno].NoofItems = 0;
+ memset(g_InvD[invno].contents, 0, sizeof(g_InvD[invno].contents));
}
/**
@@ -1743,12 +1732,12 @@ extern void AddToInventory(int invno, int icon, bool hold) {
|| invno == INV_OPEN || (invno == INV_DEFAULT && TinselV2));
if (invno == INV_OPEN) {
- assert(InventoryState == ACTIVE_INV && (ino == INV_1 || ino == INV_2)); // addopeninv() with inventry not open
- invno = ino;
+ assert(g_InventoryState == ACTIVE_INV && (g_ino == INV_1 || g_ino == INV_2)); // addopeninv() with inventry not open
+ invno = g_ino;
bOpen = true;
// Make sure it doesn't get in both!
- RemFromInventory(ino == INV_1 ? INV_2 : INV_1, icon);
+ RemFromInventory(g_ino == INV_1 ? INV_2 : INV_1, icon);
} else {
bOpen = false;
@@ -1769,61 +1758,61 @@ extern void AddToInventory(int invno, int icon, bool hold) {
RemFromInventory(INV_1, icon);
// See if it's already there
- for (i = 0; i < InvD[invno].NoofItems; i++) {
- if (InvD[invno].contents[i] == icon)
+ for (i = 0; i < g_InvD[invno].NoofItems; i++) {
+ if (g_InvD[invno].contents[i] == icon)
break;
}
// Add it if it isn't already there
- if (i == InvD[invno].NoofItems) {
+ if (i == g_InvD[invno].NoofItems) {
if (!bOpen) {
if (invno == INV_CONV) {
if (TinselV2) {
int nei;
// Count how many current contents have end attribute
- for (i = 0, nei = 0; i < InvD[INV_CONV].NoofItems; i++) {
- invObj = GetInvObject(InvD[INV_CONV].contents[i]);
+ for (i = 0, nei = 0; i < g_InvD[INV_CONV].NoofItems; i++) {
+ invObj = GetInvObject(g_InvD[INV_CONV].contents[i]);
if (invObj->attribute & CONVENDITEM)
nei++;
}
// For conversation, insert before end icons
- memmove(&InvD[INV_CONV].contents[i-nei+1],
- &InvD[INV_CONV].contents[i-nei], nei * sizeof(int));
- InvD[INV_CONV].contents[i - nei] = icon;
- InvD[INV_CONV].NoofItems++;
- InvD[INV_CONV].NoofHicons = InvD[INV_CONV].NoofItems;
+ memmove(&g_InvD[INV_CONV].contents[i-nei+1],
+ &g_InvD[INV_CONV].contents[i-nei], nei * sizeof(int));
+ g_InvD[INV_CONV].contents[i - nei] = icon;
+ g_InvD[INV_CONV].NoofItems++;
+ g_InvD[INV_CONV].NoofHicons = g_InvD[INV_CONV].NoofItems;
// Get the window to re-position
- bMoveOnUnHide = true;
+ g_bMoveOnUnHide = true;
} else {
// For conversation, insert before last icon
// which will always be the goodbye icon
- InvD[invno].contents[InvD[invno].NoofItems] = InvD[invno].contents[InvD[invno].NoofItems-1];
- InvD[invno].contents[InvD[invno].NoofItems-1] = icon;
- InvD[invno].NoofItems++;
+ g_InvD[invno].contents[g_InvD[invno].NoofItems] = g_InvD[invno].contents[g_InvD[invno].NoofItems-1];
+ g_InvD[invno].contents[g_InvD[invno].NoofItems-1] = icon;
+ g_InvD[invno].NoofItems++;
}
} else {
- InvD[invno].contents[InvD[invno].NoofItems++] = icon;
+ g_InvD[invno].contents[g_InvD[invno].NoofItems++] = icon;
}
- ItemsChanged = true;
+ g_ItemsChanged = true;
} else {
// It could be that the index is beyond what you'd expect
// as delinv may well have been called
- if (GlitterIndex < InvD[invno].NoofItems) {
- memmove(&InvD[invno].contents[GlitterIndex + 1],
- &InvD[invno].contents[GlitterIndex],
- (InvD[invno].NoofItems - GlitterIndex) * sizeof(int));
- InvD[invno].contents[GlitterIndex] = icon;
+ if (g_GlitterIndex < g_InvD[invno].NoofItems) {
+ memmove(&g_InvD[invno].contents[g_GlitterIndex + 1],
+ &g_InvD[invno].contents[g_GlitterIndex],
+ (g_InvD[invno].NoofItems - g_GlitterIndex) * sizeof(int));
+ g_InvD[invno].contents[g_GlitterIndex] = icon;
} else {
- InvD[invno].contents[InvD[invno].NoofItems] = icon;
+ g_InvD[invno].contents[g_InvD[invno].NoofItems] = icon;
}
- InvD[invno].NoofItems++;
+ g_InvD[invno].NoofItems++;
}
// Move here after bug on Japenese DW1
- ItemsChanged = true;
+ g_ItemsChanged = true;
}
// Hold it if requested
@@ -1841,25 +1830,25 @@ extern bool RemFromInventory(int invno, int icon) {
assert(invno == INV_1 || invno == INV_2 || invno == INV_CONV); // Trying to delete from illegal inventory
// See if it's there
- for (i = 0; i < InvD[invno].NoofItems; i++) {
- if (InvD[invno].contents[i] == icon)
+ for (i = 0; i < g_InvD[invno].NoofItems; i++) {
+ if (g_InvD[invno].contents[i] == icon)
break;
}
- if (i == InvD[invno].NoofItems)
+ if (i == g_InvD[invno].NoofItems)
return false; // Item wasn't there
else {
- memmove(&InvD[invno].contents[i], &InvD[invno].contents[i+1], (InvD[invno].NoofItems-i)*sizeof(int));
- InvD[invno].NoofItems--;
+ memmove(&g_InvD[invno].contents[i], &g_InvD[invno].contents[i+1], (g_InvD[invno].NoofItems-i)*sizeof(int));
+ g_InvD[invno].NoofItems--;
if (TinselV2 && invno == INV_CONV) {
- InvD[INV_CONV].NoofHicons = InvD[invno].NoofItems;
+ g_InvD[INV_CONV].NoofHicons = g_InvD[invno].NoofItems;
// Get the window to re-position
- bMoveOnUnHide = true;
+ g_bMoveOnUnHide = true;
}
- ItemsChanged = true;
+ g_ItemsChanged = true;
return true; // Item removed
}
}
@@ -1870,27 +1859,27 @@ extern bool RemFromInventory(int invno, int icon) {
extern void HoldItem(int item, bool bKeepFilm) {
INV_OBJECT *invObj;
- if (HeldItem != item) {
- if (TinselV2 && (HeldItem != NOOBJECT)) {
+ if (g_heldItem != item) {
+ if (TinselV2 && (g_heldItem != NOOBJECT)) {
// No longer holding previous item
DelAuxCursor(); // no longer aux cursor
// If old held object is not in an inventory, and
// has a default, stick it in its default inventory.
- if (!IsInInventory(HeldItem, INV_1) && !IsInInventory(HeldItem, INV_2)) {
- invObj = GetInvObject(HeldItem);
+ if (!IsInInventory(g_heldItem, INV_1) && !IsInInventory(g_heldItem, INV_2)) {
+ invObj = GetInvObject(g_heldItem);
if (invObj->attribute & DEFINV1)
- AddToInventory(INV_1, HeldItem);
+ AddToInventory(INV_1, g_heldItem);
else if (invObj->attribute & DEFINV2)
- AddToInventory(INV_2, HeldItem);
+ AddToInventory(INV_2, g_heldItem);
else
// Hook for definable default inventory
- AddToInventory(INV_1, HeldItem);
+ AddToInventory(INV_1, g_heldItem);
}
} else if (!TinselV2) {
- if (item == INV_NOICON && HeldItem != INV_NOICON)
+ if (item == INV_NOICON && g_heldItem != INV_NOICON)
DelAuxCursor(); // no longer aux cursor
if (item != INV_NOICON) {
@@ -1899,19 +1888,19 @@ extern void HoldItem(int item, bool bKeepFilm) {
}
}
- HeldItem = item; // Item held
+ g_heldItem = item; // Item held
if (TinselV2) {
InventoryIconCursor(!bKeepFilm);
// Redraw contents - held item not displayed as a content.
- ItemsChanged = true;
+ g_ItemsChanged = true;
}
}
if (!TinselV2)
// Redraw contents - held item not displayed as a content.
- ItemsChanged = true;
+ g_ItemsChanged = true;
}
/**************************************************************************/
@@ -1929,8 +1918,8 @@ enum { I_NOTIN, I_HEADER, I_BODY,
// the active area of the borders for re-sizing.
/*---------------------------------*/
-#define LeftX InvD[ino].inventoryX
-#define TopY InvD[ino].inventoryY
+#define LeftX g_InvD[g_ino].inventoryX
+#define TopY g_InvD[g_ino].inventoryY
/*---------------------------------*/
/**
@@ -1943,8 +1932,8 @@ enum { I_NOTIN, I_HEADER, I_BODY,
*/
static int InvArea(int x, int y) {
if (TinselV2) {
- int RightX = MultiRightmost(RectObject) - NM_BG_SIZ_X - NM_BG_POS_X - NM_RS_R_INSET;
- int BottomY = MultiLowest(RectObject) - NM_BG_SIZ_Y - NM_BG_POS_Y - NM_RS_B_INSET;
+ int RightX = MultiRightmost(g_RectObject) - NM_BG_SIZ_X - NM_BG_POS_X - NM_RS_R_INSET;
+ int BottomY = MultiLowest(g_RectObject) - NM_BG_SIZ_Y - NM_BG_POS_Y - NM_RS_B_INSET;
// Outside the whole rectangle?
if (x <= LeftX || x > RightX || y <= TopY || y > BottomY)
@@ -1983,7 +1972,7 @@ static int InvArea(int x, int y) {
return I_HEADER;
// Scroll bits
- if (!(ino == INV_MENU && cd.bExtraWin)) {
+ if (!(g_ino == INV_MENU && cd.bExtraWin)) {
if (x > RightX - NM_SLIDE_INSET && x <= RightX - NM_SLIDE_INSET + NM_SLIDE_THICKNESS) {
if (y > TopY + NM_UP_ARROW_TOP && y < TopY + NM_UP_ARROW_BOTTOM)
return I_UP;
@@ -1992,10 +1981,10 @@ static int InvArea(int x, int y) {
/* '3' is a magic adjustment with no apparent sense */
- if (y >= TopY + sliderYmin - 3 && y < TopY + sliderYmax + NM_SLH) {
- if (y < TopY + sliderYpos - 3)
+ if (y >= TopY + g_sliderYmin - 3 && y < TopY + g_sliderYmax + NM_SLH) {
+ if (y < TopY + g_sliderYpos - 3)
return I_SLIDE_UP;
- if (y < TopY + sliderYpos + NM_SLH - 3)
+ if (y < TopY + g_sliderYpos + NM_SLH - 3)
return I_SLIDE;
else
return I_SLIDE_DOWN;
@@ -2003,8 +1992,8 @@ static int InvArea(int x, int y) {
}
}
} else {
- int RightX = MultiRightmost(RectObject) + 1;
- int BottomY = MultiLowest(RectObject) + 1;
+ int RightX = MultiRightmost(g_RectObject) + 1;
+ int BottomY = MultiLowest(g_RectObject) + 1;
// Outside the whole rectangle?
if (x <= LeftX - EXTRA || x > RightX + EXTRA
@@ -2041,7 +2030,7 @@ static int InvArea(int x, int y) {
/*
* In the move area?
*/
- if (ino != INV_CONF
+ if (g_ino != INV_CONF
&& x >= LeftX + M_SW - 2 && x <= RightX - M_SW + 3 &&
y >= TopY + M_TH - 2 && y < TopY + M_TBB + 2)
return I_HEADER;
@@ -2049,17 +2038,17 @@ static int InvArea(int x, int y) {
/*
* Scroll bits
*/
- if (!(ino == INV_CONF && cd.bExtraWin)) {
+ if (!(g_ino == INV_CONF && cd.bExtraWin)) {
if (x > RightX - NM_SLIDE_INSET && x <= RightX - NM_SLIDE_INSET + NM_SLIDE_THICKNESS) {
if (y > TopY + M_IUT + 1 && y < TopY + M_IUB - 1)
return I_UP;
if (y > BottomY - M_IDT + 4 && y <= BottomY - M_IDB + 1)
return I_DOWN;
- if (y >= TopY + sliderYmin && y < TopY + sliderYmax + M_SH) {
- if (y < TopY + sliderYpos)
+ if (y >= TopY + g_sliderYmin && y < TopY + g_sliderYmax + M_SH) {
+ if (y < TopY + g_sliderYpos)
return I_SLIDE_UP;
- if (y < TopY + sliderYpos + M_SH)
+ if (y < TopY + g_sliderYpos + M_SH)
return I_SLIDE;
else
return I_SLIDE_DOWN;
@@ -2081,14 +2070,14 @@ extern int InvItem(int *x, int *y, bool update) {
int item;
int IconsX;
- itop = InvD[ino].inventoryY + START_ICONY;
+ itop = g_InvD[g_ino].inventoryY + START_ICONY;
- IconsX = InvD[ino].inventoryX + START_ICONX;
+ IconsX = g_InvD[g_ino].inventoryX + START_ICONX;
- for (item = InvD[ino].FirstDisp, row = 0; row < InvD[ino].NoofVicons; row++) {
+ for (item = g_InvD[g_ino].FirstDisp, row = 0; row < g_InvD[g_ino].NoofVicons; row++) {
ileft = IconsX;
- for (col = 0; col < InvD[ino].NoofHicons; col++, item++) {
+ for (col = 0; col < g_InvD[g_ino].NoofHicons; col++, item++) {
if (*x >= ileft && *x < ileft + ITEM_WIDTH &&
*y >= itop && *y < itop + ITEM_HEIGHT) {
if (update) {
@@ -2121,20 +2110,20 @@ int InvItemId(int x, int y) {
int row, col;
int item;
- if (InventoryHidden || InventoryState == IDLE_INV)
+ if (g_InventoryHidden || g_InventoryState == IDLE_INV)
return INV_NOICON;
- itop = InvD[ino].inventoryY + START_ICONY;
+ itop = g_InvD[g_ino].inventoryY + START_ICONY;
- int IconsX = InvD[ino].inventoryX + START_ICONX;
+ int IconsX = g_InvD[g_ino].inventoryX + START_ICONX;
- for (item = InvD[ino].FirstDisp, row = 0; row < InvD[ino].NoofVicons; row++) {
+ for (item = g_InvD[g_ino].FirstDisp, row = 0; row < g_InvD[g_ino].NoofVicons; row++) {
ileft = IconsX;
- for (col = 0; col < InvD[ino].NoofHicons; col++, item++) {
+ for (col = 0; col < g_InvD[g_ino].NoofHicons; col++, item++) {
if (x >= ileft && x < ileft + ITEM_WIDTH &&
y >= itop && y < itop + ITEM_HEIGHT) {
- return InvD[ino].contents[item];
+ return g_InvD[g_ino].contents[item];
}
ileft += ITEM_WIDTH + 1;
@@ -2149,15 +2138,15 @@ int InvItemId(int x, int y) {
*/
static int WhichMenuBox(int curX, int curY, bool bSlides) {
if (bSlides) {
- for (int i = 0; i < numMdSlides; i++) {
- if (curY > MultiHighest(mdSlides[i].obj) && curY < MultiLowest(mdSlides[i].obj)
- && curX > MultiLeftmost(mdSlides[i].obj) && curX < MultiRightmost(mdSlides[i].obj))
- return mdSlides[i].num | IS_SLIDER;
+ for (int i = 0; i < g_numMdSlides; i++) {
+ if (curY > MultiHighest(g_mdSlides[i].obj) && curY < MultiLowest(g_mdSlides[i].obj)
+ && curX > MultiLeftmost(g_mdSlides[i].obj) && curX < MultiRightmost(g_mdSlides[i].obj))
+ return g_mdSlides[i].num | IS_SLIDER;
}
}
- curX -= InvD[ino].inventoryX;
- curY -= InvD[ino].inventoryY;
+ curX -= g_InvD[g_ino].inventoryX;
+ curY -= g_InvD[g_ino].inventoryY;
for (int i = 0; i < cd.NumBoxes; i++) {
switch (cd.box[i].boxType) {
@@ -2184,7 +2173,7 @@ static int WhichMenuBox(int curX, int curY, bool bSlides) {
break;
case ROTATE:
- if (bNoLanguage)
+ if (g_bNoLanguage)
break;
if (curY > cd.box[i].ypos && curY < cd.box[i].ypos + cd.box[i].h) {
@@ -2222,9 +2211,9 @@ static int WhichMenuBox(int curX, int curY, bool bSlides) {
return IB_UP;
else if (curY > (r.bottom - (TinselV2 ? 18 : 5)))
return IB_DOWN;
- else if (curY + InvD[ino].inventoryY < sliderYpos)
+ else if (curY + g_InvD[g_ino].inventoryY < g_sliderYpos)
return IB_SLIDE_UP;
- else if (curY + InvD[ino].inventoryY >= sliderYpos + NM_SLH)
+ else if (curY + g_InvD[g_ino].inventoryY >= g_sliderYpos + NM_SLH)
return IB_SLIDE_DOWN;
else
return IB_SLIDE;
@@ -2260,60 +2249,60 @@ static void InvBoxes(bool InBody, int curX, int curY) {
if (index < 0) {
// unhigh-light box (if one was)
cd.pointBox = NOBOX;
- if (iconArray[HL1] != NULL) {
- MultiDeleteObject(GetPlayfieldList(FIELD_STATUS), iconArray[HL1]);
- iconArray[HL1] = NULL;
+ if (g_iconArray[HL1] != NULL) {
+ MultiDeleteObject(GetPlayfieldList(FIELD_STATUS), g_iconArray[HL1]);
+ g_iconArray[HL1] = NULL;
}
} else if (index != cd.pointBox) {
cd.pointBox = index;
// A new box is pointed to - high-light it
- if (iconArray[HL1] != NULL) {
- MultiDeleteObject(GetPlayfieldList(FIELD_STATUS), iconArray[HL1]);
- iconArray[HL1] = NULL;
+ if (g_iconArray[HL1] != NULL) {
+ MultiDeleteObject(GetPlayfieldList(FIELD_STATUS), g_iconArray[HL1]);
+ g_iconArray[HL1] = NULL;
}
if ((cd.box[cd.pointBox].boxType == ARSBUT && cd.selBox != NOBOX) ||
///* I don't agree */ cd.box[cd.pointBox].boxType == RGROUP ||
cd.box[cd.pointBox].boxType == AATBUT ||
cd.box[cd.pointBox].boxType == AABUT) {
- iconArray[HL1] = RectangleObject(BgPal(),
+ g_iconArray[HL1] = RectangleObject(BgPal(),
(TinselV2 ? HighlightColor() : COL_HILIGHT),
cd.box[cd.pointBox].w, cd.box[cd.pointBox].h);
- MultiInsertObject(GetPlayfieldList(FIELD_STATUS), iconArray[HL1]);
- MultiSetAniXY(iconArray[HL1],
- InvD[ino].inventoryX + cd.box[cd.pointBox].xpos,
- InvD[ino].inventoryY + cd.box[cd.pointBox].ypos);
- MultiSetZPosition(iconArray[HL1], Z_INV_ICONS+1);
+ MultiInsertObject(GetPlayfieldList(FIELD_STATUS), g_iconArray[HL1]);
+ MultiSetAniXY(g_iconArray[HL1],
+ g_InvD[g_ino].inventoryX + cd.box[cd.pointBox].xpos,
+ g_InvD[g_ino].inventoryY + cd.box[cd.pointBox].ypos);
+ MultiSetZPosition(g_iconArray[HL1], Z_INV_ICONS+1);
} else if (cd.box[cd.pointBox].boxType == AAGBUT ||
cd.box[cd.pointBox].boxType == ARSGBUT ||
cd.box[cd.pointBox].boxType == TOGGLE ||
cd.box[cd.pointBox].boxType == TOGGLE1 ||
cd.box[cd.pointBox].boxType == TOGGLE2) {
- pfilm = (const FILM *)LockMem(hWinParts);
+ pfilm = (const FILM *)LockMem(g_hWinParts);
- iconArray[HL1] = AddObject(&pfilm->reels[cd.box[cd.pointBox].bi+HIGRAPH], -1);
- MultiSetAniXY(iconArray[HL1],
- InvD[ino].inventoryX + cd.box[cd.pointBox].xpos,
- InvD[ino].inventoryY + cd.box[cd.pointBox].ypos);
- MultiSetZPosition(iconArray[HL1], Z_INV_ICONS+1);
+ g_iconArray[HL1] = AddObject(&pfilm->reels[cd.box[cd.pointBox].bi+HIGRAPH], -1);
+ MultiSetAniXY(g_iconArray[HL1],
+ g_InvD[g_ino].inventoryX + cd.box[cd.pointBox].xpos,
+ g_InvD[g_ino].inventoryY + cd.box[cd.pointBox].ypos);
+ MultiSetZPosition(g_iconArray[HL1], Z_INV_ICONS+1);
} else if (cd.box[cd.pointBox].boxType == ROTATE) {
- if (bNoLanguage)
+ if (g_bNoLanguage)
return;
- pfilm = (const FILM *)LockMem(hWinParts);
+ pfilm = (const FILM *)LockMem(g_hWinParts);
rotateIndex = cd.box[cd.pointBox].bi;
if (rotateIndex == IX2_LEFT1) {
- iconArray[HL1] = AddObject(&pfilm->reels[IX2_LEFT2], -1 );
- MultiSetAniXY(iconArray[HL1],
- InvD[ino].inventoryX + cd.box[cd.pointBox].xpos - ROTX1,
- InvD[ino].inventoryY + cd.box[cd.pointBox].ypos);
- MultiSetZPosition(iconArray[HL1], Z_INV_ICONS+1);
+ g_iconArray[HL1] = AddObject(&pfilm->reels[IX2_LEFT2], -1 );
+ MultiSetAniXY(g_iconArray[HL1],
+ g_InvD[g_ino].inventoryX + cd.box[cd.pointBox].xpos - ROTX1,
+ g_InvD[g_ino].inventoryY + cd.box[cd.pointBox].ypos);
+ MultiSetZPosition(g_iconArray[HL1], Z_INV_ICONS+1);
} else if (rotateIndex == IX2_RIGHT1) {
- iconArray[HL1] = AddObject(&pfilm->reels[IX2_RIGHT2], -1);
- MultiSetAniXY(iconArray[HL1],
- InvD[ino].inventoryX + cd.box[cd.pointBox].xpos + ROTX1,
- InvD[ino].inventoryY + cd.box[cd.pointBox].ypos);
- MultiSetZPosition(iconArray[HL1], Z_INV_ICONS + 1);
+ g_iconArray[HL1] = AddObject(&pfilm->reels[IX2_RIGHT2], -1);
+ MultiSetAniXY(g_iconArray[HL1],
+ g_InvD[g_ino].inventoryX + cd.box[cd.pointBox].xpos + ROTX1,
+ g_InvD[g_ino].inventoryY + cd.box[cd.pointBox].ypos);
+ MultiSetZPosition(g_iconArray[HL1], Z_INV_ICONS + 1);
}
}
}
@@ -2330,37 +2319,37 @@ static void ButtonPress(CORO_PARAM, CONFBOX *box) {
assert(box->boxType == AAGBUT || box->boxType == ARSGBUT);
// Replace highlight image with normal image
- pfilm = (const FILM *)LockMem(hWinParts);
- if (iconArray[HL1] != NULL)
- MultiDeleteObject(GetPlayfieldList(FIELD_STATUS), iconArray[HL1]);
- pfilm = (const FILM *)LockMem(hWinParts);
- iconArray[HL1] = AddObject(&pfilm->reels[box->bi+NORMGRAPH], -1);
- MultiSetAniXY(iconArray[HL1], InvD[ino].inventoryX + box->xpos, InvD[ino].inventoryY + box->ypos);
- MultiSetZPosition(iconArray[HL1], Z_INV_ICONS+1);
+ pfilm = (const FILM *)LockMem(g_hWinParts);
+ if (g_iconArray[HL1] != NULL)
+ MultiDeleteObject(GetPlayfieldList(FIELD_STATUS), g_iconArray[HL1]);
+ pfilm = (const FILM *)LockMem(g_hWinParts);
+ g_iconArray[HL1] = AddObject(&pfilm->reels[box->bi+NORMGRAPH], -1);
+ MultiSetAniXY(g_iconArray[HL1], g_InvD[g_ino].inventoryX + box->xpos, g_InvD[g_ino].inventoryY + box->ypos);
+ MultiSetZPosition(g_iconArray[HL1], Z_INV_ICONS+1);
// Hold normal image for 1 frame
CORO_SLEEP(1);
- if (iconArray[HL1] == NULL)
+ if (g_iconArray[HL1] == NULL)
return;
// Replace normal image with depresses image
- pfilm = (const FILM *)LockMem(hWinParts);
- MultiDeleteObject(GetPlayfieldList(FIELD_STATUS), iconArray[HL1]);
- iconArray[HL1] = AddObject(&pfilm->reels[box->bi+DOWNGRAPH], -1);
- MultiSetAniXY(iconArray[HL1], InvD[ino].inventoryX + box->xpos, InvD[ino].inventoryY + box->ypos);
- MultiSetZPosition(iconArray[HL1], Z_INV_ICONS+1);
+ pfilm = (const FILM *)LockMem(g_hWinParts);
+ MultiDeleteObject(GetPlayfieldList(FIELD_STATUS), g_iconArray[HL1]);
+ g_iconArray[HL1] = AddObject(&pfilm->reels[box->bi+DOWNGRAPH], -1);
+ MultiSetAniXY(g_iconArray[HL1], g_InvD[g_ino].inventoryX + box->xpos, g_InvD[g_ino].inventoryY + box->ypos);
+ MultiSetZPosition(g_iconArray[HL1], Z_INV_ICONS+1);
// Hold depressed image for 2 frames
CORO_SLEEP(2);
- if (iconArray[HL1] == NULL)
+ if (g_iconArray[HL1] == NULL)
return;
// Replace depressed image with normal image
- pfilm = (const FILM *)LockMem(hWinParts);
- MultiDeleteObject(GetPlayfieldList(FIELD_STATUS), iconArray[HL1]);
- iconArray[HL1] = AddObject(&pfilm->reels[box->bi+NORMGRAPH], -1);
- MultiSetAniXY(iconArray[HL1], InvD[ino].inventoryX + box->xpos, InvD[ino].inventoryY + box->ypos);
- MultiSetZPosition(iconArray[HL1], Z_INV_ICONS+1);
+ pfilm = (const FILM *)LockMem(g_hWinParts);
+ MultiDeleteObject(GetPlayfieldList(FIELD_STATUS), g_iconArray[HL1]);
+ g_iconArray[HL1] = AddObject(&pfilm->reels[box->bi+NORMGRAPH], -1);
+ MultiSetAniXY(g_iconArray[HL1], g_InvD[g_ino].inventoryX + box->xpos, g_InvD[g_ino].inventoryY + box->ypos);
+ MultiSetZPosition(g_iconArray[HL1], Z_INV_ICONS+1);
CORO_SLEEP(1);
@@ -2379,25 +2368,25 @@ static void ButtonToggle(CORO_PARAM, CONFBOX *box) {
|| (box->boxType == TOGGLE2));
// Remove hilight image
- if (iconArray[HL1] != NULL) {
- MultiDeleteObject(GetPlayfieldList(FIELD_STATUS), iconArray[HL1]);
- iconArray[HL1] = NULL;
+ if (g_iconArray[HL1] != NULL) {
+ MultiDeleteObject(GetPlayfieldList(FIELD_STATUS), g_iconArray[HL1]);
+ g_iconArray[HL1] = NULL;
}
// Hold normal image for 1 frame
CORO_SLEEP(1);
- if (InventoryState != ACTIVE_INV)
+ if (g_InventoryState != ACTIVE_INV)
return;
// Add depressed image
- pfilm = (const FILM *)LockMem(hWinParts);
- iconArray[HL1] = AddObject(&pfilm->reels[box->bi+DOWNGRAPH], -1);
- MultiSetAniXY(iconArray[HL1], InvD[ino].inventoryX + box->xpos, InvD[ino].inventoryY + box->ypos);
- MultiSetZPosition(iconArray[HL1], Z_INV_ICONS+1);
+ pfilm = (const FILM *)LockMem(g_hWinParts);
+ g_iconArray[HL1] = AddObject(&pfilm->reels[box->bi+DOWNGRAPH], -1);
+ MultiSetAniXY(g_iconArray[HL1], g_InvD[g_ino].inventoryX + box->xpos, g_InvD[g_ino].inventoryY + box->ypos);
+ MultiSetZPosition(g_iconArray[HL1], Z_INV_ICONS+1);
// Hold depressed image for 1 frame
CORO_SLEEP(1);
- if (iconArray[HL1] == NULL)
+ if (g_iconArray[HL1] == NULL)
return;
// Toggle state
@@ -2409,34 +2398,34 @@ static void ButtonToggle(CORO_PARAM, CONFBOX *box) {
Select(cd.selBox, true);
// New state, depressed image
- pfilm = (const FILM *)LockMem(hWinParts);
- if (iconArray[HL1] != NULL)
- MultiDeleteObject(GetPlayfieldList(FIELD_STATUS), iconArray[HL1]);
- iconArray[HL1] = AddObject(&pfilm->reels[box->bi+DOWNGRAPH], -1);
- MultiSetAniXY(iconArray[HL1], InvD[ino].inventoryX + box->xpos, InvD[ino].inventoryY + box->ypos);
- MultiSetZPosition(iconArray[HL1], Z_INV_ICONS+1);
+ pfilm = (const FILM *)LockMem(g_hWinParts);
+ if (g_iconArray[HL1] != NULL)
+ MultiDeleteObject(GetPlayfieldList(FIELD_STATUS), g_iconArray[HL1]);
+ g_iconArray[HL1] = AddObject(&pfilm->reels[box->bi+DOWNGRAPH], -1);
+ MultiSetAniXY(g_iconArray[HL1], g_InvD[g_ino].inventoryX + box->xpos, g_InvD[g_ino].inventoryY + box->ypos);
+ MultiSetZPosition(g_iconArray[HL1], Z_INV_ICONS+1);
// Hold new depressed image for 1 frame
CORO_SLEEP(1);
- if (iconArray[HL1] == NULL)
+ if (g_iconArray[HL1] == NULL)
return;
// New state, normal
- MultiDeleteObject(GetPlayfieldList(FIELD_STATUS), iconArray[HL1]);
- iconArray[HL1] = NULL;
+ MultiDeleteObject(GetPlayfieldList(FIELD_STATUS), g_iconArray[HL1]);
+ g_iconArray[HL1] = NULL;
// Hold normal image for 1 frame
CORO_SLEEP(1);
- if (InventoryState != ACTIVE_INV)
+ if (g_InventoryState != ACTIVE_INV)
return;
// New state, highlighted
- pfilm = (const FILM *)LockMem(hWinParts);
- if (iconArray[HL1] != NULL)
- MultiDeleteObject(GetPlayfieldList(FIELD_STATUS), iconArray[HL1]);
- iconArray[HL1] = AddObject(&pfilm->reels[box->bi+HIGRAPH], -1);
- MultiSetAniXY(iconArray[HL1], InvD[ino].inventoryX + box->xpos, InvD[ino].inventoryY + box->ypos);
- MultiSetZPosition(iconArray[HL1], Z_INV_ICONS+1);
+ pfilm = (const FILM *)LockMem(g_hWinParts);
+ if (g_iconArray[HL1] != NULL)
+ MultiDeleteObject(GetPlayfieldList(FIELD_STATUS), g_iconArray[HL1]);
+ g_iconArray[HL1] = AddObject(&pfilm->reels[box->bi+HIGRAPH], -1);
+ MultiSetAniXY(g_iconArray[HL1], g_InvD[g_ino].inventoryX + box->xpos, g_InvD[g_ino].inventoryY + box->ypos);
+ MultiSetZPosition(g_iconArray[HL1], Z_INV_ICONS+1);
CORO_END_CODE;
}
@@ -2454,23 +2443,23 @@ static void InvLabels(bool InBody, int aniX, int aniY) {
else {
index = InvItem(&aniX, &aniY, false);
if (index != INV_NOICON) {
- if (index >= InvD[ino].NoofItems)
+ if (index >= g_InvD[g_ino].NoofItems)
index = INV_NOICON;
else
- index = InvD[ino].contents[index];
+ index = g_InvD[g_ino].contents[index];
}
}
// If no icon pointed to, or points to (logical position of)
// currently held icon, then no icon is pointed to!
- if (index == INV_NOICON || index == HeldItem) {
- pointedIcon = INV_NOICON;
- } else if (index != pointedIcon) {
+ if (index == INV_NOICON || index == g_heldItem) {
+ g_pointedIcon = INV_NOICON;
+ } else if (index != g_pointedIcon) {
// A new icon is pointed to - run its script with POINTED event
invObj = GetInvObject(index);
if (invObj->hScript)
InvTinselEvent(invObj, POINTED, PLR_NOEVENT, index);
- pointedIcon = index;
+ g_pointedIcon = index;
}
}
@@ -2492,54 +2481,54 @@ static void AdjustTop() {
int n, i;
// Only do this if there's a slider
- if (!SlideObject)
+ if (!g_SlideObject)
return;
- rowsWanted = (InvD[ino].NoofItems - InvD[ino].FirstDisp + InvD[ino].NoofHicons-1) / InvD[ino].NoofHicons;
+ rowsWanted = (g_InvD[g_ino].NoofItems - g_InvD[g_ino].FirstDisp + g_InvD[g_ino].NoofHicons-1) / g_InvD[g_ino].NoofHicons;
- while (rowsWanted < InvD[ino].NoofVicons) {
- if (InvD[ino].FirstDisp) {
- InvD[ino].FirstDisp -= InvD[ino].NoofHicons;
- if (InvD[ino].FirstDisp < 0)
- InvD[ino].FirstDisp = 0;
+ while (rowsWanted < g_InvD[g_ino].NoofVicons) {
+ if (g_InvD[g_ino].FirstDisp) {
+ g_InvD[g_ino].FirstDisp -= g_InvD[g_ino].NoofHicons;
+ if (g_InvD[g_ino].FirstDisp < 0)
+ g_InvD[g_ino].FirstDisp = 0;
rowsWanted++;
} else
break;
}
- tMissing = InvD[ino].FirstDisp ? (InvD[ino].FirstDisp + InvD[ino].NoofHicons-1)/InvD[ino].NoofHicons : 0;
- bMissing = (rowsWanted > InvD[ino].NoofVicons) ? rowsWanted - InvD[ino].NoofVicons : 0;
+ tMissing = g_InvD[g_ino].FirstDisp ? (g_InvD[g_ino].FirstDisp + g_InvD[g_ino].NoofHicons-1)/g_InvD[g_ino].NoofHicons : 0;
+ bMissing = (rowsWanted > g_InvD[g_ino].NoofVicons) ? rowsWanted - g_InvD[g_ino].NoofVicons : 0;
nMissing = tMissing + bMissing;
- slideRange = sliderYmax - sliderYmin;
+ slideRange = g_sliderYmax - g_sliderYmin;
if (!tMissing)
- nsliderYpos = sliderYmin;
+ nsliderYpos = g_sliderYmin;
else if (!bMissing)
- nsliderYpos = sliderYmax;
+ nsliderYpos = g_sliderYmax;
else {
nsliderYpos = tMissing*slideRange/nMissing;
- nsliderYpos += sliderYmin;
+ nsliderYpos += g_sliderYmin;
}
if (nMissing) {
- n = InvD[ino].FirstDisp - tMissing*InvD[ino].NoofHicons;
- for (i = 0; i <= nMissing; i++, n += InvD[ino].NoofHicons) {
- slideStuff[i].n = n;
- slideStuff[i].y = (i*slideRange/nMissing) + sliderYmin;
+ n = g_InvD[g_ino].FirstDisp - tMissing*g_InvD[g_ino].NoofHicons;
+ for (i = 0; i <= nMissing; i++, n += g_InvD[g_ino].NoofHicons) {
+ g_slideStuff[i].n = n;
+ g_slideStuff[i].y = (i*slideRange/nMissing) + g_sliderYmin;
}
- if (slideStuff[0].n < 0)
- slideStuff[0].n = 0;
+ if (g_slideStuff[0].n < 0)
+ g_slideStuff[0].n = 0;
assert(i < MAX_ININV + 1);
- slideStuff[i].n = -1;
+ g_slideStuff[i].n = -1;
} else {
- slideStuff[0].n = 0;
- slideStuff[0].y = sliderYmin;
- slideStuff[1].n = -1;
+ g_slideStuff[0].n = 0;
+ g_slideStuff[0].y = g_sliderYmin;
+ g_slideStuff[1].n = -1;
}
- if (nsliderYpos != sliderYpos) {
- MultiMoveRelXY(SlideObject, 0, nsliderYpos - sliderYpos);
- sliderYpos = nsliderYpos;
+ if (nsliderYpos != g_sliderYpos) {
+ MultiMoveRelXY(g_SlideObject, 0, nsliderYpos - g_sliderYpos);
+ g_sliderYpos = nsliderYpos;
}
}
@@ -2580,26 +2569,26 @@ static void FillInInventory() {
DumpIconArray();
- if (InvDragging != ID_SLIDE)
+ if (g_InvDragging != ID_SLIDE)
AdjustTop(); // Set up slideStuff[]
- Index = InvD[ino].FirstDisp; // Start from first displayed object
+ Index = g_InvD[g_ino].FirstDisp; // Start from first displayed object
n = 0;
ypos = START_ICONY; // Y-offset of first display row
- for (row = 0; row < InvD[ino].NoofVicons; row++, ypos += ITEM_HEIGHT + 1) {
+ for (row = 0; row < g_InvD[g_ino].NoofVicons; row++, ypos += ITEM_HEIGHT + 1) {
xpos = START_ICONX; // X-offset of first display column
- for (col = 0; col < InvD[ino].NoofHicons; col++) {
- if (Index >= InvD[ino].NoofItems)
+ for (col = 0; col < g_InvD[g_ino].NoofHicons; col++) {
+ if (Index >= g_InvD[g_ino].NoofItems)
break;
- else if (InvD[ino].contents[Index] != HeldItem) {
+ else if (g_InvD[g_ino].contents[Index] != g_heldItem) {
// Create a display object and position it
- iconArray[n] = AddInvObject(InvD[ino].contents[Index], &pfr, &pfilm);
- MultiSetAniXY(iconArray[n], InvD[ino].inventoryX + xpos , InvD[ino].inventoryY + ypos);
- MultiSetZPosition(iconArray[n], Z_INV_ICONS);
+ g_iconArray[n] = AddInvObject(g_InvD[g_ino].contents[Index], &pfr, &pfilm);
+ MultiSetAniXY(g_iconArray[n], g_InvD[g_ino].inventoryX + xpos , g_InvD[g_ino].inventoryY + ypos);
+ MultiSetZPosition(g_iconArray[n], Z_INV_ICONS);
- InitStepAnimScript(&iconAnims[n], iconArray[n], FROM_LE_32(pfr->script), ONE_SECOND / FROM_LE_32(pfilm->frate));
+ InitStepAnimScript(&g_iconAnims[n], g_iconArray[n], FROM_LE_32(pfr->script), ONE_SECOND / FROM_LE_32(pfilm->frate));
n++;
}
@@ -2617,16 +2606,16 @@ enum {FROM_HANDLE, FROM_STRING};
*/
static void AddBackground(OBJECT **rect, OBJECT **title, int extraH, int extraV, int textFrom) {
// Why not 2 ????
- int width = TLwidth + extraH + TRwidth + NM_BG_SIZ_X;
- int height = TLheight + extraV + BLheight + NM_BG_SIZ_Y;
+ int width = g_TLwidth + extraH + g_TRwidth + NM_BG_SIZ_X;
+ int height = g_TLheight + extraV + g_BLheight + NM_BG_SIZ_Y;
// Create a rectangle object
- RectObject = *rect = TranslucentObject(width, height);
+ g_RectObject = *rect = TranslucentObject(width, height);
// add it to display list and position it
MultiInsertObject(GetPlayfieldList(FIELD_STATUS), *rect);
- MultiSetAniXY(*rect, InvD[ino].inventoryX + NM_BG_POS_X,
- InvD[ino].inventoryY + NM_BG_POS_Y);
+ MultiSetAniXY(*rect, g_InvD[g_ino].inventoryX + NM_BG_POS_X,
+ g_InvD[g_ino].inventoryY + NM_BG_POS_Y);
MultiSetZPosition(*rect, Z_INV_BRECT);
if (title == NULL)
@@ -2634,16 +2623,16 @@ static void AddBackground(OBJECT **rect, OBJECT **title, int extraH, int extraV,
// Create text object using title string
if (textFrom == FROM_HANDLE) {
- LoadStringRes(InvD[ino].hInvTitle, TextBufferAddr(), TBUFSZ);
+ LoadStringRes(g_InvD[g_ino].hInvTitle, TextBufferAddr(), TBUFSZ);
*title = ObjectTextOut(GetPlayfieldList(FIELD_STATUS), TextBufferAddr(), 0,
- InvD[ino].inventoryX + width/2, InvD[ino].inventoryY + M_TOFF,
+ g_InvD[g_ino].inventoryX + width/2, g_InvD[g_ino].inventoryY + M_TOFF,
GetTagFontHandle(), TXT_CENTER);
assert(*title); // Inventory title string produced NULL text
MultiSetZPosition(*title, Z_INV_HTEXT);
} else if (textFrom == FROM_STRING && cd.ixHeading != NO_HEADING) {
- LoadStringRes(configStrings[cd.ixHeading], TextBufferAddr(), TBUFSZ);
+ LoadStringRes(g_configStrings[cd.ixHeading], TextBufferAddr(), TBUFSZ);
*title = ObjectTextOut(GetPlayfieldList(FIELD_STATUS), TextBufferAddr(), 0,
- InvD[ino].inventoryX + width/2, InvD[ino].inventoryY + M_TOFF,
+ g_InvD[g_ino].inventoryX + width/2, g_InvD[g_ino].inventoryY + M_TOFF,
GetTagFontHandle(), TXT_CENTER);
assert(*title); // Inventory title string produced NULL text
MultiSetZPosition(*title, Z_INV_HTEXT);
@@ -2661,13 +2650,13 @@ static void AddBackground(OBJECT **rect, int extraH, int extraV) {
* Adds a title for a dialog
*/
static void AddTitle(POBJECT *title, int extraH) {
- int width = TLwidth + extraH + TRwidth + NM_BG_SIZ_X;
+ int width = g_TLwidth + extraH + g_TRwidth + NM_BG_SIZ_X;
// Create text object using title string
- if (InvD[ino].hInvTitle != (SCNHANDLE)NO_HEADING) {
- LoadStringRes(InvD[ino].hInvTitle, TextBufferAddr(), TBUFSZ);
+ if (g_InvD[g_ino].hInvTitle != (SCNHANDLE)NO_HEADING) {
+ LoadStringRes(g_InvD[g_ino].hInvTitle, TextBufferAddr(), TBUFSZ);
*title = ObjectTextOut(GetPlayfieldList(FIELD_STATUS), TextBufferAddr(), 0,
- InvD[ino].inventoryX + (width/2)+NM_BG_POS_X, InvD[ino].inventoryY + NM_TOFF,
+ g_InvD[g_ino].inventoryX + (width/2)+NM_BG_POS_X, g_InvD[g_ino].inventoryY + NM_TOFF,
GetTagFontHandle(), TXT_CENTER, 0);
assert(*title);
MultiSetZPosition(*title, Z_INV_HTEXT);
@@ -2691,13 +2680,13 @@ static OBJECT *AddObject(const FREEL *pfreel, int num) {
// Horrible bodge involving global variables to save
// width and/or height of some window frame components
- if (num == TL) {
- TLwidth = FROM_LE_16(pim->imgWidth);
- TLheight = FROM_LE_16(pim->imgHeight) & ~C16_FLAG_MASK;
- } else if (num == TR) {
- TRwidth = FROM_LE_16(pim->imgWidth);
- } else if (num == BL) {
- BLheight = FROM_LE_16(pim->imgHeight) & ~C16_FLAG_MASK;
+ if (num == g_TL) {
+ g_TLwidth = FROM_LE_16(pim->imgWidth);
+ g_TLheight = FROM_LE_16(pim->imgHeight) & ~C16_FLAG_MASK;
+ } else if (num == g_TR) {
+ g_TRwidth = FROM_LE_16(pim->imgWidth);
+ } else if (num == g_BL) {
+ g_BLheight = FROM_LE_16(pim->imgHeight) & ~C16_FLAG_MASK;
}
// Set up and insert the multi-object
@@ -2712,9 +2701,9 @@ static OBJECT *AddObject(const FREEL *pfreel, int num) {
*/
static void AddSlider(OBJECT **slide, const FILM *pfilm) {
- SlideObject = *slide = AddObject(&pfilm->reels[IX_SLIDE], -1);
- MultiSetAniXY(*slide, MultiRightmost(RectObject) + (TinselV2 ? NM_SLX : -M_SXOFF + 2) - 1,
- InvD[ino].inventoryY + sliderYpos);
+ g_SlideObject = *slide = AddObject(&pfilm->reels[IX_SLIDE], -1);
+ MultiSetAniXY(*slide, MultiRightmost(g_RectObject) + (TinselV2 ? NM_SLX : -M_SXOFF + 2) - 1,
+ g_InvD[g_ino].inventoryY + g_sliderYpos);
MultiSetZPosition(*slide, Z_INV_MFRAME);
}
@@ -2722,8 +2711,8 @@ static void AddSlider(OBJECT **slide, const FILM *pfilm) {
* Display a box with some text in it.
*/
static void AddBox(int *pi, const int i) {
- int x = InvD[ino].inventoryX + cd.box[i].xpos;
- int y = InvD[ino].inventoryY + cd.box[i].ypos;
+ int x = g_InvD[g_ino].inventoryX + cd.box[i].xpos;
+ int y = g_InvD[g_ino].inventoryY + cd.box[i].ypos;
int *pival = cd.box[i].ival;
int xdisp;
const FILM *pFilm;
@@ -2735,11 +2724,11 @@ static void AddBox(int *pi, const int i) {
break;
// Give us a box
- iconArray[*pi] = RectangleObject(BgPal(), TinselV2 ? BoxColor() : COL_BOX,
+ g_iconArray[*pi] = RectangleObject(BgPal(), TinselV2 ? BoxColor() : COL_BOX,
cd.box[i].w, cd.box[i].h);
- MultiInsertObject(GetPlayfieldList(FIELD_STATUS), iconArray[*pi]);
- MultiSetAniXY(iconArray[*pi], x, y);
- MultiSetZPosition(iconArray[*pi], Z_INV_BRECT + 1);
+ MultiInsertObject(GetPlayfieldList(FIELD_STATUS), g_iconArray[*pi]);
+ MultiSetAniXY(g_iconArray[*pi], x, y);
+ MultiSetZPosition(g_iconArray[*pi], Z_INV_BRECT + 1);
*pi += 1;
// Stick in the text
@@ -2747,14 +2736,14 @@ static void AddBox(int *pi, const int i) {
(!TinselV2 && (cd.box[i].ixText == USE_POINTER))) {
if (cd.box[i].boxText != NULL) {
if (cd.box[i].boxType == RGROUP) {
- iconArray[*pi] = ObjectTextOut(GetPlayfieldList(FIELD_STATUS), cd.box[i].boxText, 0,
+ g_iconArray[*pi] = ObjectTextOut(GetPlayfieldList(FIELD_STATUS), cd.box[i].boxText, 0,
#ifdef JAPAN
x + 2, y+2, GetTagFontHandle(), 0);
#else
x + 2, y + TYOFF, GetTagFontHandle(), 0);
#endif
} else {
- iconArray[*pi] = ObjectTextOut(GetPlayfieldList(FIELD_STATUS), cd.box[i].boxText, 0,
+ g_iconArray[*pi] = ObjectTextOut(GetPlayfieldList(FIELD_STATUS), cd.box[i].boxText, 0,
#ifdef JAPAN
// Note: it never seems to go here!
x + cd.box[i].w/2, y+2, GetTagFontHandle(), TXT_CENTER);
@@ -2763,7 +2752,7 @@ static void AddBox(int *pi, const int i) {
#endif
}
- MultiSetZPosition(iconArray[*pi], Z_INV_ITEXT);
+ MultiSetZPosition(g_iconArray[*pi], Z_INV_ITEXT);
*pi += 1;
}
} else {
@@ -2775,61 +2764,61 @@ static void AddBox(int *pi, const int i) {
LoadStringRes(cd.box[i].ixText, TextBufferAddr(), TBUFSZ);
}
} else {
- LoadStringRes(configStrings[cd.box[i].ixText], TextBufferAddr(), TBUFSZ);
+ LoadStringRes(g_configStrings[cd.box[i].ixText], TextBufferAddr(), TBUFSZ);
assert(cd.box[i].boxType != RGROUP); // You'll need to add some code!
}
if (TinselV2 && (cd.box[i].boxType == RGROUP))
- iconArray[*pi] = ObjectTextOut(GetPlayfieldList(FIELD_STATUS), TextBufferAddr(),
+ g_iconArray[*pi] = ObjectTextOut(GetPlayfieldList(FIELD_STATUS), TextBufferAddr(),
0, x + 2, y + TYOFF, GetTagFontHandle(), 0, 0);
else
- iconArray[*pi] = ObjectTextOut(GetPlayfieldList(FIELD_STATUS),
+ g_iconArray[*pi] = ObjectTextOut(GetPlayfieldList(FIELD_STATUS),
TextBufferAddr(), 0,
#ifdef JAPAN
x + cd.box[i].w/2, y+2, GetTagFontHandle(), TXT_CENTER);
#else
x + cd.box[i].w / 2, y + TYOFF, GetTagFontHandle(), TXT_CENTER);
#endif
- MultiSetZPosition(iconArray[*pi], Z_INV_ITEXT);
+ MultiSetZPosition(g_iconArray[*pi], Z_INV_ITEXT);
*pi += 1;
}
break;
case AAGBUT:
case ARSGBUT:
- pFilm = (const FILM *)LockMem(hWinParts);
+ pFilm = (const FILM *)LockMem(g_hWinParts);
- iconArray[*pi] = AddObject(&pFilm->reels[cd.box[i].bi + NORMGRAPH], -1);
- MultiSetAniXY(iconArray[*pi], x, y);
- MultiSetZPosition(iconArray[*pi], Z_INV_BRECT + 1);
+ g_iconArray[*pi] = AddObject(&pFilm->reels[cd.box[i].bi + NORMGRAPH], -1);
+ MultiSetAniXY(g_iconArray[*pi], x, y);
+ MultiSetZPosition(g_iconArray[*pi], Z_INV_BRECT + 1);
*pi += 1;
break;
case FRGROUP:
- assert(flagFilm != 0); // Language flags not declared!
+ assert(g_flagFilm != 0); // Language flags not declared!
- pFilm = (const FILM *)LockMem(flagFilm);
+ pFilm = (const FILM *)LockMem(g_flagFilm);
if (_vm->_config->_isAmericanEnglishVersion && cd.box[i].bi == FIX_UK)
cd.box[i].bi = FIX_USA;
- iconArray[*pi] = AddObject(&pFilm->reels[cd.box[i].bi], -1);
- MultiSetAniXY(iconArray[*pi], x, y);
- MultiSetZPosition(iconArray[*pi], Z_INV_BRECT+2);
+ g_iconArray[*pi] = AddObject(&pFilm->reels[cd.box[i].bi], -1);
+ MultiSetAniXY(g_iconArray[*pi], x, y);
+ MultiSetZPosition(g_iconArray[*pi], Z_INV_BRECT+2);
*pi += 1;
break;
case FLIP:
- pFilm = (const FILM *)LockMem(hWinParts);
+ pFilm = (const FILM *)LockMem(g_hWinParts);
if (*pival)
- iconArray[*pi] = AddObject(&pFilm->reels[cd.box[i].bi], -1);
+ g_iconArray[*pi] = AddObject(&pFilm->reels[cd.box[i].bi], -1);
else
- iconArray[*pi] = AddObject(&pFilm->reels[cd.box[i].bi+1], -1);
- MultiSetAniXY(iconArray[*pi], x, y);
- MultiSetZPosition(iconArray[*pi], Z_INV_BRECT+1);
+ g_iconArray[*pi] = AddObject(&pFilm->reels[cd.box[i].bi+1], -1);
+ MultiSetAniXY(g_iconArray[*pi], x, y);
+ MultiSetZPosition(g_iconArray[*pi], Z_INV_BRECT+1);
*pi += 1;
// Stick in the text
@@ -2838,23 +2827,23 @@ static void AddBox(int *pi, const int i) {
LoadStringRes(SysString(cd.box[i].ixText), TextBufferAddr(), TBUFSZ);
} else {
assert(cd.box[i].ixText != USE_POINTER);
- LoadStringRes(configStrings[cd.box[i].ixText], TextBufferAddr(), TBUFSZ);
+ LoadStringRes(g_configStrings[cd.box[i].ixText], TextBufferAddr(), TBUFSZ);
}
- iconArray[*pi] = ObjectTextOut(GetPlayfieldList(FIELD_STATUS),
+ g_iconArray[*pi] = ObjectTextOut(GetPlayfieldList(FIELD_STATUS),
TextBufferAddr(), 0, x + MDTEXT_XOFF, y + MDTEXT_YOFF, GetTagFontHandle(), TXT_RIGHT);
- MultiSetZPosition(iconArray[*pi], Z_INV_ITEXT);
+ MultiSetZPosition(g_iconArray[*pi], Z_INV_ITEXT);
*pi += 1;
break;
case TOGGLE:
case TOGGLE1:
case TOGGLE2:
- pFilm = (const FILM *)LockMem(hWinParts);
+ pFilm = (const FILM *)LockMem(g_hWinParts);
cd.box[i].bi = *pival ? IX_TICK1 : IX_CROSS1;
- iconArray[*pi] = AddObject(&pFilm->reels[cd.box[i].bi + NORMGRAPH], -1);
- MultiSetAniXY(iconArray[*pi], x, y);
- MultiSetZPosition(iconArray[*pi], Z_INV_BRECT+1);
+ g_iconArray[*pi] = AddObject(&pFilm->reels[cd.box[i].bi + NORMGRAPH], -1);
+ MultiSetAniXY(g_iconArray[*pi], x, y);
+ MultiSetZPosition(g_iconArray[*pi], Z_INV_BRECT+1);
*pi += 1;
// Stick in the text
@@ -2863,39 +2852,39 @@ static void AddBox(int *pi, const int i) {
LoadStringRes(SysString(cd.box[i].ixText), TextBufferAddr(), TBUFSZ);
} else {
assert(cd.box[i].ixText != USE_POINTER);
- LoadStringRes(configStrings[cd.box[i].ixText], TextBufferAddr(), TBUFSZ);
+ LoadStringRes(g_configStrings[cd.box[i].ixText], TextBufferAddr(), TBUFSZ);
}
if (cd.box[i].boxType == TOGGLE2) {
- iconArray[*pi] = ObjectTextOut(GetPlayfieldList(FIELD_STATUS),
+ g_iconArray[*pi] = ObjectTextOut(GetPlayfieldList(FIELD_STATUS),
TextBufferAddr(), 0, x + cd.box[i].w / 2, y + TOG2_YOFF,
GetTagFontHandle(), TXT_CENTER, 0);
} else {
- iconArray[*pi] = ObjectTextOut(GetPlayfieldList(FIELD_STATUS),
+ g_iconArray[*pi] = ObjectTextOut(GetPlayfieldList(FIELD_STATUS),
TextBufferAddr(), 0, x + MDTEXT_XOFF, y + MDTEXT_YOFF,
GetTagFontHandle(), TXT_RIGHT, 0);
}
- MultiSetZPosition(iconArray[*pi], Z_INV_ITEXT);
+ MultiSetZPosition(g_iconArray[*pi], Z_INV_ITEXT);
*pi += 1;
break;
case SLIDER:
- pFilm = (const FILM *)LockMem(hWinParts);
+ pFilm = (const FILM *)LockMem(g_hWinParts);
xdisp = SLIDE_RANGE*(*pival)/cd.box[i].w;
- iconArray[*pi] = AddObject(&pFilm->reels[IX_MDGROOVE], -1);
- MultiSetAniXY(iconArray[*pi], x, y);
- MultiSetZPosition(iconArray[*pi], Z_MDGROOVE);
+ g_iconArray[*pi] = AddObject(&pFilm->reels[IX_MDGROOVE], -1);
+ MultiSetAniXY(g_iconArray[*pi], x, y);
+ MultiSetZPosition(g_iconArray[*pi], Z_MDGROOVE);
*pi += 1;
- iconArray[*pi] = AddObject(&pFilm->reels[IX_MDSLIDER], -1);
- MultiSetAniXY(iconArray[*pi], x+SLIDE_MINX+xdisp, y);
- MultiSetZPosition(iconArray[*pi], Z_MDSLIDER);
- assert(numMdSlides < MAXSLIDES);
- mdSlides[numMdSlides].num = i;
- mdSlides[numMdSlides].min = x + SLIDE_MINX;
- mdSlides[numMdSlides].max = x + SLIDE_MAXX;
- mdSlides[numMdSlides++].obj = iconArray[*pi];
+ g_iconArray[*pi] = AddObject(&pFilm->reels[IX_MDSLIDER], -1);
+ MultiSetAniXY(g_iconArray[*pi], x+SLIDE_MINX+xdisp, y);
+ MultiSetZPosition(g_iconArray[*pi], Z_MDSLIDER);
+ assert(g_numMdSlides < MAXSLIDES);
+ g_mdSlides[g_numMdSlides].num = i;
+ g_mdSlides[g_numMdSlides].min = x + SLIDE_MINX;
+ g_mdSlides[g_numMdSlides].max = x + SLIDE_MAXX;
+ g_mdSlides[g_numMdSlides++].obj = g_iconArray[*pi];
*pi += 1;
// Stick in the text
@@ -2904,55 +2893,55 @@ static void AddBox(int *pi, const int i) {
LoadStringRes(SysString(cd.box[i].ixText), TextBufferAddr(), TBUFSZ);
} else {
assert(cd.box[i].ixText != USE_POINTER);
- LoadStringRes(configStrings[cd.box[i].ixText], TextBufferAddr(), TBUFSZ);
+ LoadStringRes(g_configStrings[cd.box[i].ixText], TextBufferAddr(), TBUFSZ);
}
- iconArray[*pi] = ObjectTextOut(GetPlayfieldList(FIELD_STATUS),
+ g_iconArray[*pi] = ObjectTextOut(GetPlayfieldList(FIELD_STATUS),
TextBufferAddr(), 0, x+MDTEXT_XOFF, y+MDTEXT_YOFF, GetTagFontHandle(), TXT_RIGHT);
- MultiSetZPosition(iconArray[*pi], Z_INV_ITEXT);
+ MultiSetZPosition(g_iconArray[*pi], Z_INV_ITEXT);
*pi += 1;
break;
case ROTATE:
- pFilm = (const FILM *)LockMem(hWinParts);
+ pFilm = (const FILM *)LockMem(g_hWinParts);
// Left one
- if (!bNoLanguage) {
- iconArray[*pi] = AddObject(&pFilm->reels[IX2_LEFT1], -1);
- MultiSetAniXY(iconArray[*pi], x-ROTX1, y);
- MultiSetZPosition(iconArray[*pi], Z_INV_BRECT + 1);
+ if (!g_bNoLanguage) {
+ g_iconArray[*pi] = AddObject(&pFilm->reels[IX2_LEFT1], -1);
+ MultiSetAniXY(g_iconArray[*pi], x-ROTX1, y);
+ MultiSetZPosition(g_iconArray[*pi], Z_INV_BRECT + 1);
*pi += 1;
// Right one
- iconArray[*pi] = AddObject( &pFilm->reels[IX2_RIGHT1], -1);
- MultiSetAniXY(iconArray[*pi], x + ROTX1, y);
- MultiSetZPosition(iconArray[*pi], Z_INV_BRECT + 1);
+ g_iconArray[*pi] = AddObject( &pFilm->reels[IX2_RIGHT1], -1);
+ MultiSetAniXY(g_iconArray[*pi], x + ROTX1, y);
+ MultiSetZPosition(g_iconArray[*pi], Z_INV_BRECT + 1);
*pi += 1;
// Stick in the text
assert(cd.box[i].textMethod == TM_INDEX);
LoadStringRes(SysString(cd.box[i].ixText), TextBufferAddr(), TBUFSZ);
- iconArray[*pi] = ObjectTextOut(GetPlayfieldList(FIELD_STATUS),
+ g_iconArray[*pi] = ObjectTextOut(GetPlayfieldList(FIELD_STATUS),
TextBufferAddr(), 0, x + cd.box[i].w / 2, y + TOG2_YOFF,
GetTagFontHandle(), TXT_CENTER, 0);
- MultiSetZPosition(iconArray[*pi], Z_INV_ITEXT);
+ MultiSetZPosition(g_iconArray[*pi], Z_INV_ITEXT);
*pi += 1;
}
// Current language's text
- if (LanguageDesc(displayedLanguage) == 0)
+ if (LanguageDesc(g_displayedLanguage) == 0)
break;
- LoadStringRes(LanguageDesc(displayedLanguage), TextBufferAddr(), TBUFSZ);
- iconArray[*pi] = ObjectTextOut(GetPlayfieldList(FIELD_STATUS), TextBufferAddr(), 0,
+ LoadStringRes(LanguageDesc(g_displayedLanguage), TextBufferAddr(), TBUFSZ);
+ g_iconArray[*pi] = ObjectTextOut(GetPlayfieldList(FIELD_STATUS), TextBufferAddr(), 0,
x + cd.box[i].w / 2, y + ROT_YOFF, GetTagFontHandle(), TXT_CENTER, 0);
- MultiSetZPosition(iconArray[*pi], Z_INV_ITEXT);
+ MultiSetZPosition(g_iconArray[*pi], Z_INV_ITEXT);
*pi += 1;
// Current language's flag
- pFilm = (const FILM *)LockMem(LanguageFlag(displayedLanguage));
- iconArray[*pi] = AddObject(&pFilm->reels[0], -1);
- MultiSetAniXY(iconArray[*pi], x + FLAGX, y + FLAGY);
- MultiSetZPosition(iconArray[*pi], Z_INV_BRECT + 1);
+ pFilm = (const FILM *)LockMem(LanguageFlag(g_displayedLanguage));
+ g_iconArray[*pi] = AddObject(&pFilm->reels[0], -1);
+ MultiSetAniXY(g_iconArray[*pi], x + FLAGX, y + FLAGY);
+ MultiSetZPosition(g_iconArray[*pi], Z_INV_BRECT + 1);
*pi += 1;
break;
}
@@ -2965,7 +2954,7 @@ static void AddBoxes(bool bPosnSlide) {
int objCount = NUMHL; // Object count - allow for HL1, HL2 etc.
DumpIconArray();
- numMdSlides = 0;
+ g_numMdSlides = 0;
for (int i = 0; i < cd.NumBoxes; i++) {
AddBox(&objCount, i);
@@ -2973,32 +2962,32 @@ static void AddBoxes(bool bPosnSlide) {
if (cd.bExtraWin) {
if (bPosnSlide && !TinselV2)
- sliderYpos = sliderYmin + (cd.extraBase*(sliderYmax-sliderYmin))/(MAX_SAVED_FILES-NUM_RGROUP_BOXES);
+ g_sliderYpos = g_sliderYmin + (cd.extraBase*(g_sliderYmax-g_sliderYmin))/(MAX_SAVED_FILES-NUM_RGROUP_BOXES);
else if (bPosnSlide) {
// Tinsel 2 bPosnSlide code
- int lastY = sliderYpos;
+ int lastY = g_sliderYpos;
if (cd.box == loadBox || cd.box == saveBox)
- sliderYpos = sliderYmin + (cd.extraBase * (sliderRange)) /
+ g_sliderYpos = g_sliderYmin + (cd.extraBase * (sliderRange)) /
(MAX_SAVED_FILES - NUM_RGROUP_BOXES);
else if (cd.box == hopperBox1) {
- if (numScenes <= NUM_RGROUP_BOXES)
- sliderYpos = sliderYmin;
+ if (g_numScenes <= NUM_RGROUP_BOXES)
+ g_sliderYpos = g_sliderYmin;
else
- sliderYpos = sliderYmin + (cd.extraBase*(sliderRange))/(numScenes-NUM_RGROUP_BOXES);
+ g_sliderYpos = g_sliderYmin + (cd.extraBase*(sliderRange))/(g_numScenes-NUM_RGROUP_BOXES);
} else if (cd.box == hopperBox2) {
- if (numEntries <= NUM_RGROUP_BOXES)
- sliderYpos = sliderYmin;
+ if (g_numEntries <= NUM_RGROUP_BOXES)
+ g_sliderYpos = g_sliderYmin;
else
- sliderYpos = sliderYmin + (cd.extraBase * (sliderRange)) /
- (numEntries-NUM_RGROUP_BOXES);
+ g_sliderYpos = g_sliderYmin + (cd.extraBase * (sliderRange)) /
+ (g_numEntries-NUM_RGROUP_BOXES);
}
- MultiMoveRelXY(SlideObject, 0, sliderYpos - lastY);
+ MultiMoveRelXY(g_SlideObject, 0, g_sliderYpos - lastY);
}
if (!TinselV2)
- MultiSetAniXY(SlideObject, InvD[ino].inventoryX + 24 + 179, sliderYpos);
+ MultiSetAniXY(g_SlideObject, g_InvD[g_ino].inventoryX + 24 + 179, g_sliderYpos);
}
assert(objCount < MAX_ICONS); // added too many icons
@@ -3008,8 +2997,8 @@ static void AddBoxes(bool bPosnSlide) {
* Display the scroll bar slider.
*/
static void AddEWSlider(OBJECT **slide, const FILM *pfilm) {
- SlideObject = *slide = AddObject(&pfilm->reels[IX_SLIDE], -1);
- MultiSetAniXY(*slide, InvD[ino].inventoryX + 24 + 127, sliderYpos);
+ g_SlideObject = *slide = AddObject(&pfilm->reels[IX_SLIDE], -1);
+ MultiSetAniXY(*slide, g_InvD[g_ino].inventoryX + 24 + 127, g_sliderYpos);
MultiSetZPosition(*slide, Z_INV_MFRAME);
}
@@ -3021,7 +3010,7 @@ static int AddExtraWindow(int x, int y, OBJECT **retObj) {
const FILM *pfilm;
// Get the frame's data
- pfilm = (const FILM *)LockMem(hWinParts);
+ pfilm = (const FILM *)LockMem(g_hWinParts);
x += TinselV2 ? 30 : 20;
y += TinselV2 ? 38 : 24;
@@ -3032,56 +3021,56 @@ static int AddExtraWindow(int x, int y, OBJECT **retObj) {
MultiSetZPosition(retObj[n], Z_INV_MFRAME);
n++;
retObj[n] = AddObject(&pfilm->reels[IX_NTR], -1); // Top right
- MultiSetAniXY(retObj[n], x + (TinselV2 ? TLwidth + 312 : 152), y);
+ MultiSetAniXY(retObj[n], x + (TinselV2 ? g_TLwidth + 312 : 152), y);
MultiSetZPosition(retObj[n], Z_INV_MFRAME);
n++;
retObj[n] = AddObject(&pfilm->reels[IX_BL], -1); // Bottom left
- MultiSetAniXY(retObj[n], x, y + (TinselV2 ? TLheight + 208 : 124));
+ MultiSetAniXY(retObj[n], x, y + (TinselV2 ? g_TLheight + 208 : 124));
MultiSetZPosition(retObj[n], Z_INV_MFRAME);
n++;
retObj[n] = AddObject(&pfilm->reels[IX_BR], -1); // Bottom right
- MultiSetAniXY(retObj[n], x + (TinselV2 ? TLwidth + 312 : 152),
- y + (TinselV2 ? TLheight + 208 : 124));
+ MultiSetAniXY(retObj[n], x + (TinselV2 ? g_TLwidth + 312 : 152),
+ y + (TinselV2 ? g_TLheight + 208 : 124));
MultiSetZPosition(retObj[n], Z_INV_MFRAME);
n++;
// Draw the edges
retObj[n] = AddObject(&pfilm->reels[IX_H156], -1); // Top
- MultiSetAniXY(retObj[n], x + (TinselV2 ? TLwidth : 6), y + NM_TBT);
+ MultiSetAniXY(retObj[n], x + (TinselV2 ? g_TLwidth : 6), y + NM_TBT);
MultiSetZPosition(retObj[n], Z_INV_MFRAME);
n++;
retObj[n] = AddObject(&pfilm->reels[IX_H156], -1); // Bottom
- MultiSetAniXY(retObj[n], x + (TinselV2 ? TLwidth : 6), y +
- (TinselV2 ? TLheight + 208 + BLheight + NM_BSY : 143));
+ MultiSetAniXY(retObj[n], x + (TinselV2 ? g_TLwidth : 6), y +
+ (TinselV2 ? g_TLheight + 208 + g_BLheight + NM_BSY : 143));
MultiSetZPosition(retObj[n], Z_INV_MFRAME);
n++;
retObj[n] = AddObject(&pfilm->reels[IX_V104], -1); // Left
- MultiSetAniXY(retObj[n], x + NM_LSX, y + (TinselV2 ? TLheight : 20));
+ MultiSetAniXY(retObj[n], x + NM_LSX, y + (TinselV2 ? g_TLheight : 20));
MultiSetZPosition(retObj[n], Z_INV_MFRAME);
n++;
retObj[n] = AddObject(&pfilm->reels[IX_V104], -1); // Right 1
- MultiSetAniXY(retObj[n], x + (TinselV2 ? TLwidth + 312 + TRwidth + NM_RSX : 179),
- y + (TinselV2 ? TLheight : 20));
+ MultiSetAniXY(retObj[n], x + (TinselV2 ? g_TLwidth + 312 + g_TRwidth + NM_RSX : 179),
+ y + (TinselV2 ? g_TLheight : 20));
MultiSetZPosition(retObj[n], Z_INV_MFRAME);
n++;
retObj[n] = AddObject(&pfilm->reels[IX_V104], -1); // Right 2
- MultiSetAniXY(retObj[n], x + (TinselV2 ? TLwidth + 312 + TRwidth + NM_SBL : 188),
- y + (TinselV2 ? TLheight : 20));
+ MultiSetAniXY(retObj[n], x + (TinselV2 ? g_TLwidth + 312 + g_TRwidth + NM_SBL : 188),
+ y + (TinselV2 ? g_TLheight : 20));
MultiSetZPosition(retObj[n], Z_INV_MFRAME);
n++;
if (TinselV2) {
- sliderYpos = sliderYmin = y + 27;
- sliderYmax = y + 273;
-
- retObj[n++] = SlideObject = AddObject( &pfilm->reels[IX_SLIDE], -1);
- MultiSetAniXY(SlideObject,
- x + TLwidth + 320 + TRwidth - NM_BG_POS_X + NM_BG_SIZ_X - 2,
- sliderYpos);
- MultiSetZPosition(SlideObject, Z_INV_MFRAME);
+ g_sliderYpos = g_sliderYmin = y + 27;
+ g_sliderYmax = y + 273;
+
+ retObj[n++] = g_SlideObject = AddObject( &pfilm->reels[IX_SLIDE], -1);
+ MultiSetAniXY(g_SlideObject,
+ x + g_TLwidth + 320 + g_TRwidth - NM_BG_POS_X + NM_BG_SIZ_X - 2,
+ g_sliderYpos);
+ MultiSetZPosition(g_SlideObject, Z_INV_MFRAME);
} else {
- sliderYpos = sliderYmin = y + 9;
- sliderYmax = y + 134;
+ g_sliderYpos = g_sliderYmin = y + 9;
+ g_sliderYmax = y + 134;
AddEWSlider(&retObj[n++], pfilm);
}
@@ -3099,17 +3088,17 @@ static void ConstructInventory(InventoryType filling) {
int eH, eV; // Extra width and height
int n = 0; // Index into object array
int zpos; // Z-position of frame
- int invX = InvD[ino].inventoryX;
- int invY = InvD[ino].inventoryY;
+ int invX = g_InvD[g_ino].inventoryX;
+ int invY = g_InvD[g_ino].inventoryY;
OBJECT **retObj;
const FILM *pfilm;
// Select the object array to use
if (filling == FULL || filling == CONF) {
- retObj = objArray; // Standard window
+ retObj = g_objArray; // Standard window
zpos = Z_INV_MFRAME;
} else {
- retObj = DobjArray; // Re-sizing window
+ retObj = g_DobjArray; // Re-sizing window
zpos = Z_INV_RFRAME;
}
@@ -3122,83 +3111,83 @@ static void ConstructInventory(InventoryType filling) {
}
// Get the frame's data
- pfilm = (const FILM *)LockMem(hWinParts);
+ pfilm = (const FILM *)LockMem(g_hWinParts);
// Standard window is of granular dimensions
if (filling == FULL) {
// Round-up/down to nearest number of icons
- if (SuppH > ITEM_WIDTH / 2)
- InvD[ino].NoofHicons++;
- if (SuppV > ITEM_HEIGHT / 2)
- InvD[ino].NoofVicons++;
- SuppH = SuppV = 0;
+ if (g_SuppH > ITEM_WIDTH / 2)
+ g_InvD[g_ino].NoofHicons++;
+ if (g_SuppV > ITEM_HEIGHT / 2)
+ g_InvD[g_ino].NoofVicons++;
+ g_SuppH = g_SuppV = 0;
}
// Extra width and height
- eH = (InvD[ino].NoofHicons - 1) * (ITEM_WIDTH+I_SEPARATION) + SuppH;
- eV = (InvD[ino].NoofVicons - 1) * (ITEM_HEIGHT+I_SEPARATION) + SuppV;
+ eH = (g_InvD[g_ino].NoofHicons - 1) * (ITEM_WIDTH+I_SEPARATION) + g_SuppH;
+ eV = (g_InvD[g_ino].NoofVicons - 1) * (ITEM_HEIGHT+I_SEPARATION) + g_SuppV;
// Which window frame corners to use
- if (TinselV2 && (ino == INV_CONV)) {
- TL = IX_TL;
- TR = IX2_TR4;
- BL = IX_BL;
- BR = IX_RBR;
- } else if ((filling == FULL) && (ino != INV_CONV)) {
- TL = IX_TL;
- TR = IX_TR;
- BL = IX_BL;
- BR = IX_BR;
+ if (TinselV2 && (g_ino == INV_CONV)) {
+ g_TL = IX_TL;
+ g_TR = IX2_TR4;
+ g_BL = IX_BL;
+ g_BR = IX_RBR;
+ } else if ((filling == FULL) && (g_ino != INV_CONV)) {
+ g_TL = IX_TL;
+ g_TR = IX_TR;
+ g_BL = IX_BL;
+ g_BR = IX_BR;
} else {
- TL = IX_RTL;
- TR = IX_RTR;
- BL = IX_BL;
- BR = IX_RBR;
+ g_TL = IX_RTL;
+ g_TR = IX_RTR;
+ g_BL = IX_BL;
+ g_BR = IX_RBR;
}
// Draw the four corners
- retObj[n] = AddObject(&pfilm->reels[TL], TL);
+ retObj[n] = AddObject(&pfilm->reels[g_TL], g_TL);
MultiSetAniXY(retObj[n], invX, invY);
MultiSetZPosition(retObj[n], zpos);
n++;
- retObj[n] = AddObject(&pfilm->reels[TR], TR);
- MultiSetAniXY(retObj[n], invX + TLwidth + eH, invY);
+ retObj[n] = AddObject(&pfilm->reels[g_TR], g_TR);
+ MultiSetAniXY(retObj[n], invX + g_TLwidth + eH, invY);
MultiSetZPosition(retObj[n], zpos);
n++;
- retObj[n] = AddObject(&pfilm->reels[BL], BL);
- MultiSetAniXY(retObj[n], invX, invY + TLheight + eV);
+ retObj[n] = AddObject(&pfilm->reels[g_BL], g_BL);
+ MultiSetAniXY(retObj[n], invX, invY + g_TLheight + eV);
MultiSetZPosition(retObj[n], zpos);
n++;
- retObj[n] = AddObject(&pfilm->reels[BR], BR);
- MultiSetAniXY(retObj[n], invX + TLwidth + eH, invY + TLheight + eV);
+ retObj[n] = AddObject(&pfilm->reels[g_BR], g_BR);
+ MultiSetAniXY(retObj[n], invX + g_TLwidth + eH, invY + g_TLheight + eV);
MultiSetZPosition(retObj[n], zpos);
n++;
// Draw extra Top and bottom parts
- if (InvD[ino].NoofHicons > 1) {
+ if (g_InvD[g_ino].NoofHicons > 1) {
// Top side
- retObj[n] = AddObject(&pfilm->reels[hFillers[InvD[ino].NoofHicons-2]], -1);
- MultiSetAniXY(retObj[n], invX + TLwidth, invY + NM_TBT);
+ retObj[n] = AddObject(&pfilm->reels[hFillers[g_InvD[g_ino].NoofHicons-2]], -1);
+ MultiSetAniXY(retObj[n], invX + g_TLwidth, invY + NM_TBT);
MultiSetZPosition(retObj[n], zpos);
n++;
// Bottom of header box
if (filling == FULL) {
if (TinselV2) {
- retObj[n] = AddObject(&pfilm->reels[hFillers[InvD[ino].NoofHicons-2]], -1);
- MultiSetAniXY(retObj[n], invX + TLwidth, invY + NM_TBB);
+ retObj[n] = AddObject(&pfilm->reels[hFillers[g_InvD[g_ino].NoofHicons-2]], -1);
+ MultiSetAniXY(retObj[n], invX + g_TLwidth, invY + NM_TBB);
MultiSetZPosition(retObj[n], zpos);
n++;
} else {
- retObj[n] = AddObject(&pfilm->reels[hFillers[InvD[ino].NoofHicons-2]], -1);
- MultiSetAniXY(retObj[n], invX + TLwidth, invY + M_TBB + 1);
+ retObj[n] = AddObject(&pfilm->reels[hFillers[g_InvD[g_ino].NoofHicons-2]], -1);
+ MultiSetAniXY(retObj[n], invX + g_TLwidth, invY + M_TBB + 1);
MultiSetZPosition(retObj[n], zpos);
n++;
// Extra bits for conversation - hopefully temporary
- if (ino == INV_CONV) {
+ if (g_ino == INV_CONV) {
retObj[n] = AddObject(&pfilm->reels[IX_H26], -1);
- MultiSetAniXY(retObj[n], invX + TLwidth - 2, invY + M_TBB + 1);
+ MultiSetAniXY(retObj[n], invX + g_TLwidth - 2, invY + M_TBB + 1);
MultiSetZPosition(retObj[n], zpos);
n++;
@@ -3211,16 +3200,16 @@ static void ConstructInventory(InventoryType filling) {
}
// Bottom side
- retObj[n] = AddObject(&pfilm->reels[hFillers[InvD[ino].NoofHicons-2]], -1);
- MultiSetAniXY(retObj[n], invX + TLwidth, invY + TLheight + eV + BLheight + NM_BSY);
+ retObj[n] = AddObject(&pfilm->reels[hFillers[g_InvD[g_ino].NoofHicons-2]], -1);
+ MultiSetAniXY(retObj[n], invX + g_TLwidth, invY + g_TLheight + eV + g_BLheight + NM_BSY);
MultiSetZPosition(retObj[n], zpos);
n++;
}
- if (SuppH) {
- int offx = TLwidth + eH - (TinselV2 ? ITEM_WIDTH + I_SEPARATION : 26);
- if (offx < TLwidth) // Not too far!
- offx = TLwidth;
+ if (g_SuppH) {
+ int offx = g_TLwidth + eH - (TinselV2 ? ITEM_WIDTH + I_SEPARATION : 26);
+ if (offx < g_TLwidth) // Not too far!
+ offx = g_TLwidth;
// Top side extra
retObj[n] = AddObject(&pfilm->reels[IX_H26], -1);
@@ -3230,39 +3219,39 @@ static void ConstructInventory(InventoryType filling) {
// Bottom side extra
retObj[n] = AddObject(&pfilm->reels[IX_H26], -1);
- MultiSetAniXY(retObj[n], invX + offx, invY + TLheight + eV + BLheight + NM_BSY);
+ MultiSetAniXY(retObj[n], invX + offx, invY + g_TLheight + eV + g_BLheight + NM_BSY);
MultiSetZPosition(retObj[n], zpos);
n++;
}
// Draw extra side parts
- if (InvD[ino].NoofVicons > 1) {
+ if (g_InvD[g_ino].NoofVicons > 1) {
// Left side
- retObj[n] = AddObject(&pfilm->reels[vFillers[InvD[ino].NoofVicons-2]], -1);
- MultiSetAniXY(retObj[n], invX + NM_LSX, invY + TLheight);
+ retObj[n] = AddObject(&pfilm->reels[vFillers[g_InvD[g_ino].NoofVicons-2]], -1);
+ MultiSetAniXY(retObj[n], invX + NM_LSX, invY + g_TLheight);
MultiSetZPosition(retObj[n], zpos);
n++;
// Left side of scroll bar
- if (filling == FULL && ino != INV_CONV) {
- retObj[n] = AddObject(&pfilm->reels[vFillers[InvD[ino].NoofVicons-2]], -1);
+ if (filling == FULL && g_ino != INV_CONV) {
+ retObj[n] = AddObject(&pfilm->reels[vFillers[g_InvD[g_ino].NoofVicons-2]], -1);
if (TinselV2)
- MultiSetAniXY(retObj[n], invX + TLwidth + eH + TRwidth + NM_SBL, invY + TLheight);
+ MultiSetAniXY(retObj[n], invX + g_TLwidth + eH + g_TRwidth + NM_SBL, invY + g_TLheight);
else
- MultiSetAniXY(retObj[n], invX + TLwidth + eH + M_SBL + 1, invY + TLheight);
+ MultiSetAniXY(retObj[n], invX + g_TLwidth + eH + M_SBL + 1, invY + g_TLheight);
MultiSetZPosition(retObj[n], zpos);
n++;
}
// Right side
- retObj[n] = AddObject(&pfilm->reels[vFillers[InvD[ino].NoofVicons-2]], -1);
- MultiSetAniXY(retObj[n], invX + TLwidth + eH + TRwidth + NM_RSX, invY + TLheight);
+ retObj[n] = AddObject(&pfilm->reels[vFillers[g_InvD[g_ino].NoofVicons-2]], -1);
+ MultiSetAniXY(retObj[n], invX + g_TLwidth + eH + g_TRwidth + NM_RSX, invY + g_TLheight);
MultiSetZPosition(retObj[n], zpos);
n++;
}
- if (SuppV) {
- int offy = TLheight + eV - (TinselV2 ? ITEM_HEIGHT + I_SEPARATION : 26);
+ if (g_SuppV) {
+ int offy = g_TLheight + eV - (TinselV2 ? ITEM_HEIGHT + I_SEPARATION : 26);
int minAmount = TinselV2 ? 20 : 5;
if (offy < minAmount)
offy = minAmount;
@@ -3275,7 +3264,7 @@ static void ConstructInventory(InventoryType filling) {
// Right side extra
retObj[n] = AddObject(&pfilm->reels[IX_V26], -1);
- MultiSetAniXY(retObj[n], invX + TLwidth + eH + TRwidth + NM_RSX, invY + offy);
+ MultiSetAniXY(retObj[n], invX + g_TLwidth + eH + g_TRwidth + NM_RSX, invY + offy);
MultiSetZPosition(retObj[n], zpos);
n++;
}
@@ -3296,20 +3285,20 @@ static void ConstructInventory(InventoryType filling) {
AddBackground(rect, title, eH, eV, FROM_HANDLE);
}
- if (ino == INV_CONV) {
- SlideObject = NULL;
+ if (g_ino == INV_CONV) {
+ g_SlideObject = NULL;
if (TinselV2) {
// !!!!! MAGIC NUMBER ALERT !!!!!
// Make sure it's big enough for the heading
- if (MultiLeftmost(retObj[n-1]) < InvD[INV_CONV].inventoryX + 10) {
- InvD[INV_CONV].NoofHicons++;
+ if (MultiLeftmost(retObj[n-1]) < g_InvD[INV_CONV].inventoryX + 10) {
+ g_InvD[INV_CONV].NoofHicons++;
ConstructInventory(FULL);
}
}
- } else if (InvD[ino].NoofItems > InvD[ino].NoofHicons*InvD[ino].NoofVicons) {
- sliderYmin = TLheight - (TinselV2 ? 2 : 1);
- sliderYmax = TLheight + eV + (TinselV2 ? 12 : 10);
+ } else if (g_InvD[g_ino].NoofItems > g_InvD[g_ino].NoofHicons*g_InvD[g_ino].NoofVicons) {
+ g_sliderYmin = g_TLheight - (TinselV2 ? 2 : 1);
+ g_sliderYmax = g_TLheight + eV + (TinselV2 ? 12 : 10);
AddSlider(&retObj[n++], pfilm);
}
@@ -3333,7 +3322,7 @@ static void ConstructInventory(InventoryType filling) {
assert(n < MAX_WCOMP); // added more parts than we can handle!
// Reposition returns true if needs to move
- if (InvD[ino].bMoveable && filling == FULL && RePosition()) {
+ if (g_InvD[g_ino].bMoveable && filling == FULL && RePosition()) {
ConstructInventory(FULL);
}
}
@@ -3348,32 +3337,32 @@ static bool RePosition() {
int p;
bool bMoveitMoveit = false;
- assert(RectObject); // no recangle object!
+ assert(g_RectObject); // no recangle object!
// Test for off-screen horizontally
- p = MultiLeftmost(RectObject);
+ p = MultiLeftmost(g_RectObject);
if (p > MAXLEFT) {
// Too far to the right
- InvD[ino].inventoryX += MAXLEFT - p;
+ g_InvD[g_ino].inventoryX += MAXLEFT - p;
bMoveitMoveit = true; // I like to....
} else {
// Too far to the left?
- p = MultiRightmost(RectObject);
+ p = MultiRightmost(g_RectObject);
if (p < MINRIGHT) {
- InvD[ino].inventoryX += MINRIGHT - p;
+ g_InvD[g_ino].inventoryX += MINRIGHT - p;
bMoveitMoveit = true; // I like to....
}
}
// Test for off-screen vertically
- p = MultiHighest(RectObject);
+ p = MultiHighest(g_RectObject);
if (p < MINTOP) {
// Too high
- InvD[ino].inventoryY += MINTOP - p;
+ g_InvD[g_ino].inventoryY += MINTOP - p;
bMoveitMoveit = true; // I like to....
} else if (p > MAXTOP) {
// Too low
- InvD[ino].inventoryY += MAXTOP - p;
+ g_InvD[g_ino].inventoryY += MAXTOP - p;
bMoveitMoveit = true; // I like to....
}
@@ -3393,7 +3382,7 @@ static void AlterCursor(int num) {
IMAGE *pim;
// Get pointer to image
- pim = GetImageFromFilm(hWinParts, num, &pfreel);
+ pim = GetImageFromFilm(g_hWinParts, num, &pfreel);
// Poke in the background palette
pim->hImgPal = TO_LE_32(BgPal());
@@ -3414,7 +3403,7 @@ static void InvCursor(InvCursorFN fn, int CurX, int CurY) {
bool restoreMain = false;
// If currently dragging, don't be messing about with the cursor shape
- if (InvDragging != ID_NONE)
+ if (g_InvDragging != ID_NONE)
return;
switch (fn) {
@@ -3427,7 +3416,7 @@ static void InvCursor(InvCursorFN fn, int CurX, int CurY) {
area = InvArea(CurX, CurY);
// Check for POINTED events
- if (ino == INV_CONF)
+ if (g_ino == INV_CONF)
InvBoxes(area == I_BODY, CurX, CurY);
else
InvLabels(area == I_BODY, CurX, CurY);
@@ -3445,7 +3434,7 @@ static void InvCursor(InvCursorFN fn, int CurX, int CurY) {
case I_TLEFT:
case I_BRIGHT:
- if (!InvD[ino].resizable)
+ if (!g_InvD[g_ino].resizable)
restoreMain = true;
else if (ICursor != IC_DR) {
AlterCursor(IX_CURDD);
@@ -3455,7 +3444,7 @@ static void InvCursor(InvCursorFN fn, int CurX, int CurY) {
case I_TRIGHT:
case I_BLEFT:
- if (!InvD[ino].resizable)
+ if (!g_InvD[g_ino].resizable)
restoreMain = true;
else if (ICursor != IC_UR) {
AlterCursor(IX_CURDU);
@@ -3465,7 +3454,7 @@ static void InvCursor(InvCursorFN fn, int CurX, int CurY) {
case I_TOP:
case I_BOTTOM:
- if (!InvD[ino].resizable) {
+ if (!g_InvD[g_ino].resizable) {
restoreMain = true;
break;
}
@@ -3477,7 +3466,7 @@ static void InvCursor(InvCursorFN fn, int CurX, int CurY) {
case I_LEFT:
case I_RIGHT:
- if (!InvD[ino].resizable)
+ if (!g_InvD[g_ino].resizable)
restoreMain = true;
else if (ICursor != IC_LR) {
AlterCursor(IX_CURLR);
@@ -3516,7 +3505,7 @@ static void InvCursor(InvCursorFN fn, int CurX, int CurY) {
extern void ConvAction(int index) {
- assert(ino == INV_CONV); // not conv. window!
+ assert(g_ino == INV_CONV); // not conv. window!
PMOVER pMover = TinselV2 ? GetMover(GetLeadId()) : NULL;
switch (index) {
@@ -3524,36 +3513,36 @@ extern void ConvAction(int index) {
return;
case INV_CLOSEICON:
- thisIcon = -1; // Postamble
+ g_thisIcon = -1; // Postamble
break;
case INV_OPENICON:
// Store the direction the lead character is facing in when the conversation starts
if (TinselV2)
- initialDirection = GetMoverDirection(pMover);
- thisIcon = -2; // Preamble
+ g_initialDirection = GetMoverDirection(pMover);
+ g_thisIcon = -2; // Preamble
break;
default:
- thisIcon = InvD[ino].contents[index];
+ g_thisIcon = g_InvD[g_ino].contents[index];
break;
}
if (!TinselV2)
- RunPolyTinselCode(thisConvPoly, CONVERSE, PLR_NOEVENT, true);
+ RunPolyTinselCode(g_thisConvPoly, CONVERSE, PLR_NOEVENT, true);
else {
// If the lead's direction has changed for any reason (such as having broken the
// fourth wall and talked to the screen), reset back to the original direction
DIRECTION currDirection = GetMoverDirection(pMover);
- if (currDirection != initialDirection) {
- SetMoverDirection(pMover, initialDirection);
+ if (currDirection != g_initialDirection) {
+ SetMoverDirection(pMover, g_initialDirection);
SetMoverStanding(pMover);
}
- if (thisConvPoly != NOPOLY)
- PolygonEvent(nullContext, thisConvPoly, CONVERSE, 0, false, 0);
+ if (g_thisConvPoly != NOPOLY)
+ PolygonEvent(nullContext, g_thisConvPoly, CONVERSE, 0, false, 0);
else
- ActorEvent(nullContext, thisConvActor, CONVERSE, false, 0);
+ ActorEvent(nullContext, g_thisConvActor, CONVERSE, false, 0);
}
}
@@ -3566,18 +3555,18 @@ extern void ConvAction(int index) {
* Note: ano may (will probably) be set when it's a polygon.
*/
extern void SetConvDetails(CONV_PARAM fn, HPOLYGON hPoly, int ano) {
- thisConvFn = fn;
- thisConvPoly = hPoly;
- thisConvActor = ano;
+ g_thisConvFn = fn;
+ g_thisConvPoly = hPoly;
+ g_thisConvActor = ano;
- bMoveOnUnHide = true;
+ g_bMoveOnUnHide = true;
// Get the Actor Tag's or Tagged Actor's label for the conversation window title
if (hPoly != NOPOLY) {
int x, y;
- GetTagTag(hPoly, &InvD[INV_CONV].hInvTitle, &x, &y);
+ GetTagTag(hPoly, &g_InvD[INV_CONV].hInvTitle, &x, &y);
} else {
- InvD[INV_CONV].hInvTitle = GetActorTagHandle(ano);
+ g_InvD[INV_CONV].hInvTitle = GetActorTagHandle(ano);
}
}
@@ -3590,27 +3579,27 @@ extern void PermaConvIcon(int icon, bool bEnd) {
int i;
// See if it's already there
- for (i = 0; i < numPermIcons; i++) {
- if (permIcons[i] == icon)
+ for (i = 0; i < g_numPermIcons; i++) {
+ if (g_permIcons[i] == icon)
break;
}
// Add it if it isn't already there
- if (i == numPermIcons) {
- assert(numPermIcons < MAX_PERMICONS);
+ if (i == g_numPermIcons) {
+ assert(g_numPermIcons < MAX_PERMICONS);
- if (bEnd || !numEndIcons) {
+ if (bEnd || !g_numEndIcons) {
// Add it at the end
- permIcons[numPermIcons++] = icon;
+ g_permIcons[g_numPermIcons++] = icon;
if (bEnd)
- numEndIcons++;
+ g_numEndIcons++;
} else {
// Insert before end icons
- memmove(&permIcons[numPermIcons-numEndIcons+1],
- &permIcons[numPermIcons-numEndIcons],
- numEndIcons * sizeof(int));
- permIcons[numPermIcons-numEndIcons] = icon;
- numPermIcons++;
+ memmove(&g_permIcons[g_numPermIcons-g_numEndIcons+1],
+ &g_permIcons[g_numPermIcons-g_numEndIcons],
+ g_numEndIcons * sizeof(int));
+ g_permIcons[g_numPermIcons-g_numEndIcons] = icon;
+ g_numPermIcons++;
}
}
}
@@ -3619,21 +3608,21 @@ extern void PermaConvIcon(int icon, bool bEnd) {
extern void convPos(int fn) {
if (fn == CONV_DEF)
- InvD[INV_CONV].inventoryY = 8;
+ g_InvD[INV_CONV].inventoryY = 8;
else if (fn == CONV_BOTTOM)
- InvD[INV_CONV].inventoryY = 150;
+ g_InvD[INV_CONV].inventoryY = 150;
}
extern void ConvPoly(HPOLYGON hPoly) {
- thisConvPoly = hPoly;
+ g_thisConvPoly = hPoly;
}
extern int GetIcon() {
- return thisIcon;
+ return g_thisIcon;
}
extern void CloseDownConv() {
- if (InventoryState == ACTIVE_INV && ino == INV_CONV) {
+ if (g_InventoryState == ACTIVE_INV && g_ino == INV_CONV) {
KillInventory();
}
}
@@ -3642,43 +3631,43 @@ extern void HideConversation(bool bHide) {
int aniX, aniY;
int i;
- if (InventoryState == ACTIVE_INV && ino == INV_CONV) {
+ if (g_InventoryState == ACTIVE_INV && g_ino == INV_CONV) {
if (bHide) {
// Move all the window and icons off-screen
- for (i = 0; objArray[i] && i < MAX_WCOMP; i++) {
- MultiAdjustXY(objArray[i], 2 * SCREEN_WIDTH, 0);
+ for (i = 0; g_objArray[i] && i < MAX_WCOMP; i++) {
+ MultiAdjustXY(g_objArray[i], 2 * SCREEN_WIDTH, 0);
}
- for (i = 0; iconArray[i] && i < MAX_ICONS; i++) {
- MultiAdjustXY(iconArray[i], 2 * SCREEN_WIDTH, 0);
+ for (i = 0; g_iconArray[i] && i < MAX_ICONS; i++) {
+ MultiAdjustXY(g_iconArray[i], 2 * SCREEN_WIDTH, 0);
}
// Window is hidden
- InventoryHidden = true;
+ g_InventoryHidden = true;
// Remove any labels
InvLabels(false, 0, 0);
} else {
// Window is not hidden
- InventoryHidden = false;
+ g_InventoryHidden = false;
- if (TinselV2 && ItemsChanged)
+ if (TinselV2 && g_ItemsChanged)
// Just rebuild the whole thing
ConstructInventory(FULL);
else {
// Move it all back on-screen
- for (i = 0; objArray[i] && i < MAX_WCOMP; i++) {
- MultiAdjustXY(objArray[i], -2 * SCREEN_WIDTH, 0);
+ for (i = 0; g_objArray[i] && i < MAX_WCOMP; i++) {
+ MultiAdjustXY(g_objArray[i], -2 * SCREEN_WIDTH, 0);
}
// Don't flash if items changed. If they have, will be redrawn anyway.
- if (TinselV2 || !ItemsChanged) {
- for (i = 0; iconArray[i] && i < MAX_ICONS; i++) {
- MultiAdjustXY(iconArray[i], -2*SCREEN_WIDTH, 0);
+ if (TinselV2 || !g_ItemsChanged) {
+ for (i = 0; g_iconArray[i] && i < MAX_ICONS; i++) {
+ MultiAdjustXY(g_iconArray[i], -2*SCREEN_WIDTH, 0);
}
}
}
- if (TinselV2 && bMoveOnUnHide) {
+ if (TinselV2 && g_bMoveOnUnHide) {
/*
* First time, position it appropriately
*/
@@ -3686,17 +3675,17 @@ extern void HideConversation(bool bHide) {
int x, y, deltay;
// Only do it once per conversation
- bMoveOnUnHide = false;
+ g_bMoveOnUnHide = false;
// Current center of the window
- left = MultiLeftmost(RectObject);
- center = (MultiRightmost(RectObject) + left) / 2;
+ left = MultiLeftmost(g_RectObject);
+ center = (MultiRightmost(g_RectObject) + left) / 2;
// Get the x-offset for the conversation window
- if (thisConvActor) {
+ if (g_thisConvActor) {
int Loffset, Toffset;
- GetActorMidTop(thisConvActor, &x, &y);
+ GetActorMidTop(g_thisConvActor, &x, &y);
PlayfieldGetPos(FIELD_WORLD, &Loffset, &Toffset);
x -= Loffset;
y -= Toffset;
@@ -3706,19 +3695,19 @@ extern void HideConversation(bool bHide) {
}
// Save old y-position
- deltay = InvD[INV_CONV].inventoryY;
+ deltay = g_InvD[INV_CONV].inventoryY;
- switch (thisConvFn) {
+ switch (g_thisConvFn) {
case CONV_TOP:
- InvD[INV_CONV].inventoryY = SysVar(SV_CONV_TOPY);
+ g_InvD[INV_CONV].inventoryY = SysVar(SV_CONV_TOPY);
break;
case CONV_BOTTOM:
- InvD[INV_CONV].inventoryY = SysVar(SV_CONV_BOTY);
+ g_InvD[INV_CONV].inventoryY = SysVar(SV_CONV_BOTY);
break;
case CONV_DEF:
- InvD[INV_CONV].inventoryY = y - SysVar(SV_CONV_ABOVE_Y);
+ g_InvD[INV_CONV].inventoryY = y - SysVar(SV_CONV_ABOVE_Y);
break;
default:
@@ -3726,34 +3715,34 @@ extern void HideConversation(bool bHide) {
}
// Calculate y change
- deltay = InvD[INV_CONV].inventoryY - deltay;
+ deltay = g_InvD[INV_CONV].inventoryY - deltay;
// Move it all
- for (i = 0; objArray[i] && i < MAX_WCOMP; i++) {
- MultiMoveRelXY(objArray[i], x - center, deltay);
+ for (i = 0; g_objArray[i] && i < MAX_WCOMP; i++) {
+ MultiMoveRelXY(g_objArray[i], x - center, deltay);
}
- for (i = 0; iconArray[i] && i < MAX_ICONS; i++) {
- MultiMoveRelXY(iconArray[i], x - center, deltay);
+ for (i = 0; g_iconArray[i] && i < MAX_ICONS; i++) {
+ MultiMoveRelXY(g_iconArray[i], x - center, deltay);
}
- InvD[INV_CONV].inventoryX += x - center;
+ g_InvD[INV_CONV].inventoryX += x - center;
/*
* Now positioned as worked out
* - but it must be in a sensible place
*/
- if (MultiLeftmost(RectObject) < SysVar(SV_CONV_MINX))
- x = SysVar(SV_CONV_MINX) - MultiLeftmost(RectObject);
- else if (MultiRightmost(RectObject) > SCREEN_WIDTH - SysVar(SV_CONV_MINX))
- x = SCREEN_WIDTH - SysVar(SV_CONV_MINX) - MultiRightmost(RectObject);
+ if (MultiLeftmost(g_RectObject) < SysVar(SV_CONV_MINX))
+ x = SysVar(SV_CONV_MINX) - MultiLeftmost(g_RectObject);
+ else if (MultiRightmost(g_RectObject) > SCREEN_WIDTH - SysVar(SV_CONV_MINX))
+ x = SCREEN_WIDTH - SysVar(SV_CONV_MINX) - MultiRightmost(g_RectObject);
else
x = 0;
- if (thisConvFn == CONV_DEF && MultiHighest(RectObject) < SysVar(SV_CONV_MINY)
- && thisConvActor) {
+ if (g_thisConvFn == CONV_DEF && MultiHighest(g_RectObject) < SysVar(SV_CONV_MINY)
+ && g_thisConvActor) {
int Loffset, Toffset;
PlayfieldGetPos(FIELD_WORLD, &Loffset, &Toffset);
- y = GetActorBottom(thisConvActor) - MultiHighest(RectObject) +
+ y = GetActorBottom(g_thisConvActor) - MultiHighest(g_RectObject) +
SysVar(SV_CONV_BELOW_Y);
y -= Toffset;
}
@@ -3761,28 +3750,28 @@ extern void HideConversation(bool bHide) {
y = 0;
if (x || y) {
- for (i = 0; objArray[i] && i < MAX_WCOMP; i++) {
- MultiMoveRelXY(objArray[i], x, y);
+ for (i = 0; g_objArray[i] && i < MAX_WCOMP; i++) {
+ MultiMoveRelXY(g_objArray[i], x, y);
}
- for (i = 0; iconArray[i] && i < MAX_ICONS; i++) {
- MultiMoveRelXY(iconArray[i], x, y);
+ for (i = 0; g_iconArray[i] && i < MAX_ICONS; i++) {
+ MultiMoveRelXY(g_iconArray[i], x, y);
}
- InvD[INV_CONV].inventoryX += x;
- InvD[INV_CONV].inventoryY += y;
+ g_InvD[INV_CONV].inventoryX += x;
+ g_InvD[INV_CONV].inventoryY += y;
}
/*
* Oh shit! We might have gone off the bottom
*/
- if (MultiLowest(RectObject) > SCREEN_BOX_HEIGHT2 - SysVar(SV_CONV_MINY)) {
- y = (SCREEN_BOX_HEIGHT2 - SysVar(SV_CONV_MINY)) - MultiLowest(RectObject);
- for (i = 0; objArray[i] && i < MAX_WCOMP; i++) {
- MultiMoveRelXY(objArray[i], 0, y);
+ if (MultiLowest(g_RectObject) > SCREEN_BOX_HEIGHT2 - SysVar(SV_CONV_MINY)) {
+ y = (SCREEN_BOX_HEIGHT2 - SysVar(SV_CONV_MINY)) - MultiLowest(g_RectObject);
+ for (i = 0; g_objArray[i] && i < MAX_WCOMP; i++) {
+ MultiMoveRelXY(g_objArray[i], 0, y);
}
- for (i = 0; iconArray[i] && i < MAX_ICONS; i++) {
- MultiMoveRelXY(iconArray[i], 0, y);
+ for (i = 0; g_iconArray[i] && i < MAX_ICONS; i++) {
+ MultiMoveRelXY(g_iconArray[i], 0, y);
}
- InvD[INV_CONV].inventoryY += y;
+ g_InvD[INV_CONV].inventoryY += y;
}
}
@@ -3793,7 +3782,7 @@ extern void HideConversation(bool bHide) {
}
extern bool ConvIsHidden() {
- return InventoryHidden;
+ return g_InventoryHidden;
}
@@ -3808,8 +3797,8 @@ extern void PopUpInventory(int invno) {
assert(invno == INV_1 || invno == INV_2 || invno == INV_CONV
|| invno == INV_CONF || invno == INV_MENU); // Trying to open illegal inventory
- if (InventoryState == IDLE_INV) {
- bReOpenMenu = false; // Better safe than sorry...
+ if (g_InventoryState == IDLE_INV) {
+ g_bReOpenMenu = false; // Better safe than sorry...
DisableTags(); // Tags disabled during inventory
if (TinselV2)
@@ -3821,25 +3810,25 @@ extern void PopUpInventory(int invno) {
_vm->_pcmMusic->dim(false);
// Start conversation with permanent contents
- memset(InvD[INV_CONV].contents, 0, MAX_ININV*sizeof(int));
- memcpy(InvD[INV_CONV].contents, permIcons, numPermIcons*sizeof(int));
- InvD[INV_CONV].NoofItems = numPermIcons;
+ memset(g_InvD[INV_CONV].contents, 0, MAX_ININV*sizeof(int));
+ memcpy(g_InvD[INV_CONV].contents, g_permIcons, g_numPermIcons*sizeof(int));
+ g_InvD[INV_CONV].NoofItems = g_numPermIcons;
if (TinselV2)
- InvD[INV_CONV].NoofHicons = numPermIcons;
+ g_InvD[INV_CONV].NoofHicons = g_numPermIcons;
else
- thisIcon = 0;
+ g_thisIcon = 0;
} else if (invno == INV_CONF) { // Configuration window?
cd.selBox = NOBOX;
cd.pointBox = NOBOX;
}
- ino = invno; // The open inventory
+ g_ino = invno; // The open inventory
- ItemsChanged = false; // Nothing changed
- InvDragging = ID_NONE; // Not dragging
- InventoryState = ACTIVE_INV; // Inventory actiive
- InventoryHidden = false; // Not hidden
- InventoryMaximised = InvD[ino].bMax;
+ g_ItemsChanged = false; // Nothing changed
+ g_InvDragging = ID_NONE; // Not dragging
+ g_InventoryState = ACTIVE_INV; // Inventory actiive
+ g_InventoryHidden = false; // Not hidden
+ g_InventoryMaximised = g_InvD[g_ino].bMax;
if (invno != INV_CONF) // Configuration window?
ConstructInventory(FULL); // Draw it up
else {
@@ -3849,10 +3838,10 @@ extern void PopUpInventory(int invno) {
}
static void SetMenuGlobals(CONFINIT *ci) {
- InvD[INV_CONF].MinHicons = InvD[INV_CONF].MaxHicons = InvD[INV_CONF].NoofHicons = ci->h;
- InvD[INV_CONF].MaxVicons = InvD[INV_CONF].MinVicons = InvD[INV_CONF].NoofVicons = ci->v;
- InvD[INV_CONF].inventoryX = ci->x;
- InvD[INV_CONF].inventoryY = ci->y;
+ g_InvD[INV_CONF].MinHicons = g_InvD[INV_CONF].MaxHicons = g_InvD[INV_CONF].NoofHicons = ci->h;
+ g_InvD[INV_CONF].MaxVicons = g_InvD[INV_CONF].MinVicons = g_InvD[INV_CONF].NoofVicons = ci->v;
+ g_InvD[INV_CONF].inventoryX = ci->x;
+ g_InvD[INV_CONF].inventoryY = ci->y;
cd.bExtraWin = ci->bExtraWin;
cd.box = ci->Box;
cd.NumBoxes = ci->NumBoxes;
@@ -3860,9 +3849,9 @@ static void SetMenuGlobals(CONFINIT *ci) {
if (TinselV2) {
if ((ci->ixHeading != NO_HEADING) && SysString(ci->ixHeading))
- InvD[INV_MENU].hInvTitle = SysString(ci->ixHeading);
+ g_InvD[INV_MENU].hInvTitle = SysString(ci->ixHeading);
else
- InvD[INV_MENU].hInvTitle = NO_HEADING;
+ g_InvD[INV_MENU].hInvTitle = NO_HEADING;
}
}
@@ -3876,11 +3865,11 @@ extern void OpenMenu(CONFTYPE menuType) {
if (TinselV0)
return;
- if (InventoryState != IDLE_INV)
+ if (g_InventoryState != IDLE_INV)
return;
- InvD[INV_CONF].resizable = false;
- InvD[INV_CONF].bMoveable = false;
+ g_InvD[INV_CONF].resizable = false;
+ g_InvD[INV_CONF].bMoveable = false;
switch (menuType) {
case MAIN_MENU:
@@ -3915,7 +3904,7 @@ extern void OpenMenu(CONFTYPE menuType) {
case SOUND_MENU:
if (TinselV2)
- displayedLanguage = TextLanguage();
+ g_displayedLanguage = TextLanguage();
#if 1
// FIXME: Hack to setup CONFBOX pointer to data in the global Config object
if (TinselV2) {
@@ -4003,16 +3992,16 @@ extern void OpenMenu(CONFTYPE menuType) {
case TOP_WINDOW:
SetMenuGlobals(&ciTopWin);
- ino = INV_CONF;
+ g_ino = INV_CONF;
ConstructInventory(CONF); // Draw it up
- InventoryState = BOGUS_INV;
+ g_InventoryState = BOGUS_INV;
return;
default:
return;
}
- if (HeldItem != INV_NOICON)
+ if (g_heldItem != INV_NOICON)
DelAuxCursor(); // no longer aux cursor
PopUpInventory(INV_CONF);
@@ -4045,38 +4034,38 @@ extern void OpenMenu(CONFTYPE menuType) {
* Close down an inventory window.
*/
extern void KillInventory() {
- if (objArray[0] != NULL) {
+ if (g_objArray[0] != NULL) {
DumpObjArray();
DumpDobjArray();
DumpIconArray();
}
- if (InventoryState == ACTIVE_INV) {
+ if (g_InventoryState == ACTIVE_INV) {
EnableTags();
if (TinselV2)
EnablePointing();
- InvD[ino].bMax = InventoryMaximised;
+ g_InvD[g_ino].bMax = g_InventoryMaximised;
UnHideCursorTrails();
_vm->divertKeyInput(NULL);
}
- InventoryState = IDLE_INV;
+ g_InventoryState = IDLE_INV;
- if (bReOpenMenu) {
- bReOpenMenu = false;
+ if (g_bReOpenMenu) {
+ g_bReOpenMenu = false;
OpenMenu(MAIN_MENU);
// Write config changes
_vm->_config->writeToDisk();
- } else if (ino == INV_CONF)
+ } else if (g_ino == INV_CONF)
InventoryIconCursor(false);
if (TinselV2)
// Pump up the volume
- if (ino == INV_CONV)
+ if (g_ino == INV_CONV)
_vm->_pcmMusic->unDim(false);
g_system->setFeatureState(OSystem::kFeatureVirtualKeyboard, false); // Hide VK after save dialog closes
@@ -4084,15 +4073,15 @@ extern void KillInventory() {
extern void CloseInventory() {
// If not active, ignore this
- if (InventoryState != ACTIVE_INV)
+ if (g_InventoryState != ACTIVE_INV)
return;
// If hidden, a conversation action is still underway - ignore this
- if (InventoryHidden)
+ if (g_InventoryHidden)
return;
// If conversation, this is a closeing event
- if (ino == INV_CONV)
+ if (g_ino == INV_CONV)
ConvAction(INV_CLOSEICON);
KillInventory();
@@ -4117,13 +4106,13 @@ extern void InventoryProcess(CORO_PARAM, const void *) {
CORO_BEGIN_CODE(_ctx);
if (NumberOfLanguages() <= 1)
- bNoLanguage = true;
+ g_bNoLanguage = true;
while (1) {
CORO_SLEEP(1); // allow scheduling
- if (objArray[0] != NULL) {
- if (ItemsChanged && ino != INV_CONF && !InventoryHidden) {
+ if (g_objArray[0] != NULL) {
+ if (g_ItemsChanged && g_ino != INV_CONF && !g_InventoryHidden) {
FillInInventory();
// Needed when clicking on scroll bar.
@@ -4131,15 +4120,15 @@ extern void InventoryProcess(CORO_PARAM, const void *) {
GetCursorXY(&curX, &curY, false);
InvCursor(IC_AREA, curX, curY);
- ItemsChanged = false;
+ g_ItemsChanged = false;
}
- if (ino != INV_CONF) {
+ if (g_ino != INV_CONF) {
for (int i = 0; i < MAX_ICONS; i++) {
- if (iconArray[i] != NULL)
- StepAnimScript(&iconAnims[i]);
+ if (g_iconArray[i] != NULL)
+ StepAnimScript(&g_iconAnims[i]);
}
}
- if (InvDragging == ID_MDCONT) {
+ if (g_InvDragging == ID_MDCONT) {
// Mixing desk control
int sval, index, *pival;
@@ -4263,12 +4252,12 @@ static int NearestSlideY(int fity) {
int i = 0;
do {
- thisDist = ABS(slideStuff[i].y - fity);
+ thisDist = ABS(g_slideStuff[i].y - fity);
if (thisDist < nearDist) {
nearDist = thisDist;
nearI = i;
}
- } while (slideStuff[++i].n != -1);
+ } while (g_slideStuff[++i].n != -1);
return nearI;
}
@@ -4281,44 +4270,44 @@ static void SlideSlider(int y, SSFN fn) {
int gotoY, ati;
// Only do this if there's a slider
- if (!SlideObject)
+ if (!g_SlideObject)
return;
switch (fn) {
case S_START: // Start of a drag on the slider
- newY = sliderYpos;
- lasti = NearestSlideY(sliderYpos);
+ newY = g_sliderYpos;
+ lasti = NearestSlideY(g_sliderYpos);
break;
case S_SLIDE: // Y-movement during drag
newY = newY + y; // New y-position
- if (newY < sliderYmin)
- gotoY = sliderYmin; // Above top limit
- else if (newY > sliderYmax)
- gotoY = sliderYmax; // Below bottom limit
+ if (newY < g_sliderYmin)
+ gotoY = g_sliderYmin; // Above top limit
+ else if (newY > g_sliderYmax)
+ gotoY = g_sliderYmax; // Below bottom limit
else
gotoY = newY; // Hunky-Dory
// Move slider to new position
- MultiMoveRelXY(SlideObject, 0, gotoY - sliderYpos);
- sliderYpos = gotoY;
+ MultiMoveRelXY(g_SlideObject, 0, gotoY - g_sliderYpos);
+ g_sliderYpos = gotoY;
// Re-draw icons if necessary
- ati = NearestSlideY(sliderYpos);
+ ati = NearestSlideY(g_sliderYpos);
if (ati != lasti) {
- InvD[ino].FirstDisp = slideStuff[ati].n;
- assert(InvD[ino].FirstDisp >= 0); // negative first displayed
- ItemsChanged = true;
+ g_InvD[g_ino].FirstDisp = g_slideStuff[ati].n;
+ assert(g_InvD[g_ino].FirstDisp >= 0); // negative first displayed
+ g_ItemsChanged = true;
lasti = ati;
}
break;
case S_END: // End of a drag on the slider
// Draw icons from new start icon
- ati = NearestSlideY(sliderYpos);
- InvD[ino].FirstDisp = slideStuff[ati].n;
- ItemsChanged = true;
+ ati = NearestSlideY(g_sliderYpos);
+ g_InvD[g_ino].FirstDisp = g_slideStuff[ati].n;
+ g_ItemsChanged = true;
break;
default:
@@ -4336,38 +4325,38 @@ static void SlideCSlider(int y, SSFN fn) {
int fc;
// Only do this if there's a slider
- if (!SlideObject)
+ if (!g_SlideObject)
return;
switch (fn) {
case S_START: // Start of a drag on the slider
- newY = sliderYpos;
+ newY = g_sliderYpos;
break;
case S_SLIDE: // Y-movement during drag
newY = newY + y; // New y-position
- if (newY < sliderYmin)
- gotoY = sliderYmin; // Above top limit
- else if (newY > sliderYmax)
- gotoY = sliderYmax; // Below bottom limit
+ if (newY < g_sliderYmin)
+ gotoY = g_sliderYmin; // Above top limit
+ else if (newY > g_sliderYmax)
+ gotoY = g_sliderYmax; // Below bottom limit
else
gotoY = newY; // Hunky-Dory
// Move slider to new position
if (TinselV2)
- MultiMoveRelXY(SlideObject, 0, gotoY - sliderYpos);
- sliderYpos = gotoY;
+ MultiMoveRelXY(g_SlideObject, 0, gotoY - g_sliderYpos);
+ g_sliderYpos = gotoY;
fc = cd.extraBase;
if ((cd.box == saveBox || cd.box == loadBox))
- FirstFile((sliderYpos - sliderYmin) * (MAX_SAVED_FILES - NUM_RGROUP_BOXES) /
- (sliderYmax - sliderYmin));
+ FirstFile((g_sliderYpos - g_sliderYmin) * (MAX_SAVED_FILES - NUM_RGROUP_BOXES) /
+ (g_sliderYmax - g_sliderYmin));
else if (cd.box == hopperBox1)
- FirstScene((sliderYpos - sliderYmin) * (numScenes - NUM_RGROUP_BOXES) / sliderRange);
+ FirstScene((g_sliderYpos - g_sliderYmin) * (g_numScenes - NUM_RGROUP_BOXES) / sliderRange);
else if (cd.box == hopperBox2)
- FirstEntry((sliderYpos - sliderYmin) * (numEntries - NUM_RGROUP_BOXES) / sliderRange);
+ FirstEntry((g_sliderYpos - g_sliderYmin) * (g_numEntries - NUM_RGROUP_BOXES) / sliderRange);
// If extraBase has changed...
if (fc != cd.extraBase) {
@@ -4409,16 +4398,16 @@ static void SlideMSlider(int x, SSFN fn) {
// Work out the indices
index = cd.selBox & ~IS_MASK;
- for (i = 0; i < numMdSlides; i++)
- if (mdSlides[i].num == index)
+ for (i = 0; i < g_numMdSlides; i++)
+ if (g_mdSlides[i].num == index)
break;
- assert(i < numMdSlides);
+ assert(i < g_numMdSlides);
switch (fn) {
case S_START: // Start of a drag on the slider
// can use index as a throw-away value
- GetAniPosition(mdSlides[i].obj, &newX, &index);
- lX = sX = newX;
+ GetAniPosition(g_mdSlides[i].obj, &newX, &index);
+ g_lX = g_sX = newX;
break;
case S_SLIDE: // X-movement during drag
@@ -4427,19 +4416,19 @@ static void SlideMSlider(int x, SSFN fn) {
newX = newX + x; // New x-position
- if (newX < mdSlides[i].min)
- gotoX = mdSlides[i].min; // Below bottom limit
- else if (newX > mdSlides[i].max)
- gotoX = mdSlides[i].max; // Above top limit
+ if (newX < g_mdSlides[i].min)
+ gotoX = g_mdSlides[i].min; // Below bottom limit
+ else if (newX > g_mdSlides[i].max)
+ gotoX = g_mdSlides[i].max; // Above top limit
else
gotoX = newX; // Hunky-Dory
// Move slider to new position
- MultiMoveRelXY(mdSlides[i].obj, gotoX - sX, 0);
- sX = gotoX;
+ MultiMoveRelXY(g_mdSlides[i].obj, gotoX - g_sX, 0);
+ g_sX = gotoX;
- if (lX != sX) {
- *cd.box[index].ival = (sX - mdSlides[i].min)*cd.box[index].w/SLIDE_RANGE;
+ if (g_lX != g_sX) {
+ *cd.box[index].ival = (g_sX - g_mdSlides[i].min)*cd.box[index].w/SLIDE_RANGE;
if (cd.box[index].boxFunc == MUSICVOL)
SetMidiVolume(*cd.box[index].ival);
#ifdef MAC_OPTIONS
@@ -4449,14 +4438,14 @@ static void SlideMSlider(int x, SSFN fn) {
if (cd.box[index].boxFunc == SAMPVOL)
SetSampleVolume(*cd.box[index].ival);
#endif
- lX = sX;
+ g_lX = g_sX;
}
break;
case S_TIMEUP:
case S_TIMEDN:
gotoX = SLIDE_RANGE*(*cd.box[index].ival)/cd.box[index].w;
- MultiSetAniX(mdSlides[i].obj, mdSlides[i].min+gotoX);
+ MultiSetAniX(g_mdSlides[i].obj, g_mdSlides[i].min+gotoX);
if (cd.box[index].boxFunc == MUSICVOL)
SetMidiVolume(*cd.box[index].ival);
@@ -4471,7 +4460,7 @@ static void SlideMSlider(int x, SSFN fn) {
case S_END: // End of a drag on the slider
AddBoxes(false); // Might change position slightly
- if (ino == INV_CONF && cd.box == subtitlesBox)
+ if (g_ino == INV_CONF && cd.box == subtitlesBox)
Select(_vm->_config->_language, false);
break;
}
@@ -4481,23 +4470,23 @@ static void SlideMSlider(int x, SSFN fn) {
* Called from ChangeingSize() during re-sizing.
*/
static void GettingTaller() {
- if (SuppV) {
- Ychange += SuppV;
- if (Ycompensate == 'T')
- InvD[ino].inventoryY += SuppV;
- SuppV = 0;
+ if (g_SuppV) {
+ g_Ychange += g_SuppV;
+ if (g_Ycompensate == 'T')
+ g_InvD[g_ino].inventoryY += g_SuppV;
+ g_SuppV = 0;
}
- while (Ychange > (ITEM_HEIGHT+1) && InvD[ino].NoofVicons < InvD[ino].MaxVicons) {
- Ychange -= (ITEM_HEIGHT+1);
- InvD[ino].NoofVicons++;
- if (Ycompensate == 'T')
- InvD[ino].inventoryY -= (ITEM_HEIGHT+1);
+ while (g_Ychange > (ITEM_HEIGHT+1) && g_InvD[g_ino].NoofVicons < g_InvD[g_ino].MaxVicons) {
+ g_Ychange -= (ITEM_HEIGHT+1);
+ g_InvD[g_ino].NoofVicons++;
+ if (g_Ycompensate == 'T')
+ g_InvD[g_ino].inventoryY -= (ITEM_HEIGHT+1);
}
- if (InvD[ino].NoofVicons < InvD[ino].MaxVicons) {
- SuppV = Ychange;
- Ychange = 0;
- if (Ycompensate == 'T')
- InvD[ino].inventoryY -= SuppV;
+ if (g_InvD[g_ino].NoofVicons < g_InvD[g_ino].MaxVicons) {
+ g_SuppV = g_Ychange;
+ g_Ychange = 0;
+ if (g_Ycompensate == 'T')
+ g_InvD[g_ino].inventoryY -= g_SuppV;
}
}
@@ -4505,73 +4494,73 @@ static void GettingTaller() {
* Called from ChangeingSize() during re-sizing.
*/
static void GettingShorter() {
- int StartNvi = InvD[ino].NoofVicons;
- int StartUv = SuppV;
+ int StartNvi = g_InvD[g_ino].NoofVicons;
+ int StartUv = g_SuppV;
- if (SuppV) {
- Ychange += (SuppV - (ITEM_HEIGHT+1));
- InvD[ino].NoofVicons++;
- SuppV = 0;
+ if (g_SuppV) {
+ g_Ychange += (g_SuppV - (ITEM_HEIGHT+1));
+ g_InvD[g_ino].NoofVicons++;
+ g_SuppV = 0;
}
- while (Ychange < -(ITEM_HEIGHT+1) && InvD[ino].NoofVicons > InvD[ino].MinVicons) {
- Ychange += (ITEM_HEIGHT+1);
- InvD[ino].NoofVicons--;
+ while (g_Ychange < -(ITEM_HEIGHT+1) && g_InvD[g_ino].NoofVicons > g_InvD[g_ino].MinVicons) {
+ g_Ychange += (ITEM_HEIGHT+1);
+ g_InvD[g_ino].NoofVicons--;
}
- if (InvD[ino].NoofVicons > InvD[ino].MinVicons && Ychange) {
- SuppV = (ITEM_HEIGHT+1) + Ychange;
- InvD[ino].NoofVicons--;
- Ychange = 0;
+ if (g_InvD[g_ino].NoofVicons > g_InvD[g_ino].MinVicons && g_Ychange) {
+ g_SuppV = (ITEM_HEIGHT+1) + g_Ychange;
+ g_InvD[g_ino].NoofVicons--;
+ g_Ychange = 0;
}
- if (Ycompensate == 'T')
- InvD[ino].inventoryY += (ITEM_HEIGHT+1)*(StartNvi - InvD[ino].NoofVicons) - (SuppV - StartUv);
+ if (g_Ycompensate == 'T')
+ g_InvD[g_ino].inventoryY += (ITEM_HEIGHT+1)*(StartNvi - g_InvD[g_ino].NoofVicons) - (g_SuppV - StartUv);
}
/**
* Called from ChangeingSize() during re-sizing.
*/
static void GettingWider() {
- int StartNhi = InvD[ino].NoofHicons;
- int StartUh = SuppH;
+ int StartNhi = g_InvD[g_ino].NoofHicons;
+ int StartUh = g_SuppH;
- if (SuppH) {
- Xchange += SuppH;
- SuppH = 0;
+ if (g_SuppH) {
+ g_Xchange += g_SuppH;
+ g_SuppH = 0;
}
- while (Xchange > (ITEM_WIDTH+1) && InvD[ino].NoofHicons < InvD[ino].MaxHicons) {
- Xchange -= (ITEM_WIDTH+1);
- InvD[ino].NoofHicons++;
+ while (g_Xchange > (ITEM_WIDTH+1) && g_InvD[g_ino].NoofHicons < g_InvD[g_ino].MaxHicons) {
+ g_Xchange -= (ITEM_WIDTH+1);
+ g_InvD[g_ino].NoofHicons++;
}
- if (InvD[ino].NoofHicons < InvD[ino].MaxHicons) {
- SuppH = Xchange;
- Xchange = 0;
+ if (g_InvD[g_ino].NoofHicons < g_InvD[g_ino].MaxHicons) {
+ g_SuppH = g_Xchange;
+ g_Xchange = 0;
}
- if (Xcompensate == 'L')
- InvD[ino].inventoryX += (ITEM_WIDTH+1)*(StartNhi - InvD[ino].NoofHicons) - (SuppH - StartUh);
+ if (g_Xcompensate == 'L')
+ g_InvD[g_ino].inventoryX += (ITEM_WIDTH+1)*(StartNhi - g_InvD[g_ino].NoofHicons) - (g_SuppH - StartUh);
}
/**
* Called from ChangeingSize() during re-sizing.
*/
static void GettingNarrower() {
- int StartNhi = InvD[ino].NoofHicons;
- int StartUh = SuppH;
+ int StartNhi = g_InvD[g_ino].NoofHicons;
+ int StartUh = g_SuppH;
- if (SuppH) {
- Xchange += (SuppH - (ITEM_WIDTH+1));
- InvD[ino].NoofHicons++;
- SuppH = 0;
+ if (g_SuppH) {
+ g_Xchange += (g_SuppH - (ITEM_WIDTH+1));
+ g_InvD[g_ino].NoofHicons++;
+ g_SuppH = 0;
}
- while (Xchange < -(ITEM_WIDTH+1) && InvD[ino].NoofHicons > InvD[ino].MinHicons) {
- Xchange += (ITEM_WIDTH+1);
- InvD[ino].NoofHicons--;
+ while (g_Xchange < -(ITEM_WIDTH+1) && g_InvD[g_ino].NoofHicons > g_InvD[g_ino].MinHicons) {
+ g_Xchange += (ITEM_WIDTH+1);
+ g_InvD[g_ino].NoofHicons--;
}
- if (InvD[ino].NoofHicons > InvD[ino].MinHicons && Xchange) {
- SuppH = (ITEM_WIDTH+1) + Xchange;
- InvD[ino].NoofHicons--;
- Xchange = 0;
+ if (g_InvD[g_ino].NoofHicons > g_InvD[g_ino].MinHicons && g_Xchange) {
+ g_SuppH = (ITEM_WIDTH+1) + g_Xchange;
+ g_InvD[g_ino].NoofHicons--;
+ g_Xchange = 0;
}
- if (Xcompensate == 'L')
- InvD[ino].inventoryX += (ITEM_WIDTH+1)*(StartNhi - InvD[ino].NoofHicons) - (SuppH - StartUh);
+ if (g_Xcompensate == 'L')
+ g_InvD[g_ino].inventoryX += (ITEM_WIDTH+1)*(StartNhi - g_InvD[g_ino].NoofHicons) - (g_SuppH - StartUh);
}
@@ -4580,15 +4569,15 @@ static void GettingNarrower() {
*/
static void ChangeingSize() {
/* Make it taller or shorter if necessary. */
- if (Ychange > 0)
+ if (g_Ychange > 0)
GettingTaller();
- else if (Ychange < 0)
+ else if (g_Ychange < 0)
GettingShorter();
/* Make it wider or narrower if necessary. */
- if (Xchange > 0)
+ if (g_Xchange > 0)
GettingWider();
- else if (Xchange < 0)
+ else if (g_Xchange < 0)
GettingNarrower();
ConstructInventory(EMPTY);
@@ -4601,29 +4590,29 @@ extern void Xmovement(int x) {
int aniX, aniY;
int i;
- if (x && objArray[0] != NULL) {
- switch (InvDragging) {
+ if (x && g_objArray[0] != NULL) {
+ switch (g_InvDragging) {
case ID_MOVE:
- GetAniPosition(objArray[0], &InvD[ino].inventoryX, &aniY);
- InvD[ino].inventoryX +=x;
- MultiSetAniX(objArray[0], InvD[ino].inventoryX);
- for (i = 1; objArray[i] && i < MAX_WCOMP; i++)
- MultiMoveRelXY(objArray[i], x, 0);
- for (i = 0; iconArray[i] && i < MAX_ICONS; i++)
- MultiMoveRelXY(iconArray[i], x, 0);
+ GetAniPosition(g_objArray[0], &g_InvD[g_ino].inventoryX, &aniY);
+ g_InvD[g_ino].inventoryX +=x;
+ MultiSetAniX(g_objArray[0], g_InvD[g_ino].inventoryX);
+ for (i = 1; g_objArray[i] && i < MAX_WCOMP; i++)
+ MultiMoveRelXY(g_objArray[i], x, 0);
+ for (i = 0; g_iconArray[i] && i < MAX_ICONS; i++)
+ MultiMoveRelXY(g_iconArray[i], x, 0);
break;
case ID_LEFT:
case ID_TLEFT:
case ID_BLEFT:
- Xchange -= x;
+ g_Xchange -= x;
ChangeingSize();
break;
case ID_RIGHT:
case ID_TRIGHT:
case ID_BRIGHT:
- Xchange += x;
+ g_Xchange += x;
ChangeingSize();
break;
@@ -4649,16 +4638,16 @@ extern void Ymovement(int y) {
int aniX, aniY;
int i;
- if (y && objArray[0] != NULL) {
- switch (InvDragging) {
+ if (y && g_objArray[0] != NULL) {
+ switch (g_InvDragging) {
case ID_MOVE:
- GetAniPosition(objArray[0], &aniX, &InvD[ino].inventoryY);
- InvD[ino].inventoryY +=y;
- MultiSetAniY(objArray[0], InvD[ino].inventoryY);
- for (i = 1; objArray[i] && i < MAX_WCOMP; i++)
- MultiMoveRelXY(objArray[i], 0, y);
- for (i = 0; iconArray[i] && i < MAX_ICONS; i++)
- MultiMoveRelXY(iconArray[i], 0, y);
+ GetAniPosition(g_objArray[0], &aniX, &g_InvD[g_ino].inventoryY);
+ g_InvD[g_ino].inventoryY +=y;
+ MultiSetAniY(g_objArray[0], g_InvD[g_ino].inventoryY);
+ for (i = 1; g_objArray[i] && i < MAX_WCOMP; i++)
+ MultiMoveRelXY(g_objArray[i], 0, y);
+ for (i = 0; g_iconArray[i] && i < MAX_ICONS; i++)
+ MultiMoveRelXY(g_iconArray[i], 0, y);
break;
case ID_SLIDE:
@@ -4672,14 +4661,14 @@ extern void Ymovement(int y) {
case ID_BOTTOM:
case ID_BLEFT:
case ID_BRIGHT:
- Ychange += y;
+ g_Ychange += y;
ChangeingSize();
break;
case ID_TOP:
case ID_TLEFT:
case ID_TRIGHT:
- Ychange -= y;
+ g_Ychange -= y;
ChangeingSize();
break;
@@ -4705,16 +4694,16 @@ static void InvDragStart() {
/*
* Do something different for Save/Restore screens
*/
- if (ino == INV_CONF) {
+ if (g_ino == INV_CONF) {
int whichbox;
whichbox = WhichMenuBox(curX, curY, true);
if (whichbox == IB_SLIDE) {
- InvDragging = ID_CSLIDE;
+ g_InvDragging = ID_CSLIDE;
SlideCSlider(0, S_START);
} else if (whichbox > 0 && (whichbox & IS_MASK)) {
- InvDragging = ID_MDCONT; // Mixing desk control
+ g_InvDragging = ID_MDCONT; // Mixing desk control
cd.selBox = whichbox;
SlideMSlider(0, S_START);
}
@@ -4726,85 +4715,85 @@ static void InvDragStart() {
*/
switch (InvArea(curX, curY)) {
case I_HEADER:
- if (InvD[ino].bMoveable) {
- InvDragging = ID_MOVE;
+ if (g_InvD[g_ino].bMoveable) {
+ g_InvDragging = ID_MOVE;
}
break;
case I_SLIDE:
- InvDragging = ID_SLIDE;
+ g_InvDragging = ID_SLIDE;
SlideSlider(0, S_START);
break;
case I_BOTTOM:
- if (InvD[ino].resizable) {
- Ychange = 0;
- InvDragging = ID_BOTTOM;
- Ycompensate = 'B';
+ if (g_InvD[g_ino].resizable) {
+ g_Ychange = 0;
+ g_InvDragging = ID_BOTTOM;
+ g_Ycompensate = 'B';
}
break;
case I_TOP:
- if (InvD[ino].resizable) {
- Ychange = 0;
- InvDragging = ID_TOP;
- Ycompensate = 'T';
+ if (g_InvD[g_ino].resizable) {
+ g_Ychange = 0;
+ g_InvDragging = ID_TOP;
+ g_Ycompensate = 'T';
}
break;
case I_LEFT:
- if (InvD[ino].resizable) {
- Xchange = 0;
- InvDragging = ID_LEFT;
- Xcompensate = 'L';
+ if (g_InvD[g_ino].resizable) {
+ g_Xchange = 0;
+ g_InvDragging = ID_LEFT;
+ g_Xcompensate = 'L';
}
break;
case I_RIGHT:
- if (InvD[ino].resizable) {
- Xchange = 0;
- InvDragging = ID_RIGHT;
- Xcompensate = 'R';
+ if (g_InvD[g_ino].resizable) {
+ g_Xchange = 0;
+ g_InvDragging = ID_RIGHT;
+ g_Xcompensate = 'R';
}
break;
case I_TLEFT:
- if (InvD[ino].resizable) {
- Ychange = 0;
- Ycompensate = 'T';
- Xchange = 0;
- Xcompensate = 'L';
- InvDragging = ID_TLEFT;
+ if (g_InvD[g_ino].resizable) {
+ g_Ychange = 0;
+ g_Ycompensate = 'T';
+ g_Xchange = 0;
+ g_Xcompensate = 'L';
+ g_InvDragging = ID_TLEFT;
}
break;
case I_TRIGHT:
- if (InvD[ino].resizable) {
- Ychange = 0;
- Ycompensate = 'T';
- Xchange = 0;
- Xcompensate = 'R';
- InvDragging = ID_TRIGHT;
+ if (g_InvD[g_ino].resizable) {
+ g_Ychange = 0;
+ g_Ycompensate = 'T';
+ g_Xchange = 0;
+ g_Xcompensate = 'R';
+ g_InvDragging = ID_TRIGHT;
}
break;
case I_BLEFT:
- if (InvD[ino].resizable) {
- Ychange = 0;
- Ycompensate = 'B';
- Xchange = 0;
- Xcompensate = 'L';
- InvDragging = ID_BLEFT;
+ if (g_InvD[g_ino].resizable) {
+ g_Ychange = 0;
+ g_Ycompensate = 'B';
+ g_Xchange = 0;
+ g_Xcompensate = 'L';
+ g_InvDragging = ID_BLEFT;
}
break;
case I_BRIGHT:
- if (InvD[ino].resizable) {
- Ychange = 0;
- Ycompensate = 'B';
- Xchange = 0;
- Xcompensate = 'R';
- InvDragging = ID_BRIGHT;
+ if (g_InvD[g_ino].resizable) {
+ g_Ychange = 0;
+ g_Ycompensate = 'B';
+ g_Xchange = 0;
+ g_Xcompensate = 'R';
+ g_InvDragging = ID_BRIGHT;
}
break;
}
@@ -4818,14 +4807,14 @@ static void InvDragEnd() {
GetCursorXY(&curX, &curY, false);
- if (InvDragging != ID_NONE) {
- if (InvDragging == ID_SLIDE) {
+ if (g_InvDragging != ID_NONE) {
+ if (g_InvDragging == ID_SLIDE) {
SlideSlider(0, S_END);
- } else if (InvDragging == ID_CSLIDE) {
+ } else if (g_InvDragging == ID_CSLIDE) {
; // No action
- } else if (InvDragging == ID_MDCONT) {
+ } else if (g_InvDragging == ID_MDCONT) {
SlideMSlider(0, S_END);
- } else if (InvDragging == ID_MOVE) {
+ } else if (g_InvDragging == ID_MOVE) {
; // No action
} else {
// Were re-sizing. Redraw the whole thing.
@@ -4834,21 +4823,21 @@ static void InvDragEnd() {
ConstructInventory(FULL);
// If this was the maximised, it no longer is!
- if (InventoryMaximised) {
- InventoryMaximised = false;
- InvD[ino].otherX = InvD[ino].inventoryX;
- InvD[ino].otherY = InvD[ino].inventoryY;
+ if (g_InventoryMaximised) {
+ g_InventoryMaximised = false;
+ g_InvD[g_ino].otherX = g_InvD[g_ino].inventoryX;
+ g_InvD[g_ino].otherY = g_InvD[g_ino].inventoryY;
}
}
- InvDragging = ID_NONE;
+ g_InvDragging = ID_NONE;
ProcessedProvisional();
}
// Cursor could well now be inappropriate
InvCursor(IC_AREA, curX, curY);
- Xchange = Ychange = 0; // Probably no need, but does no harm!
+ g_Xchange = g_Ychange = 0; // Probably no need, but does no harm!
}
static void MenuPageDown() {
@@ -4860,7 +4849,7 @@ static void MenuPageDown() {
Select(cd.selBox, true);
}
} else if (cd.box == hopperBox1) {
- if (cd.extraBase < numScenes - NUM_RGROUP_BOXES) {
+ if (cd.extraBase < g_numScenes - NUM_RGROUP_BOXES) {
FirstScene(cd.extraBase + (NUM_RGROUP_BOXES - 1));
AddBoxes(true);
if (cd.selBox)
@@ -4868,7 +4857,7 @@ static void MenuPageDown() {
Select(cd.selBox, true);
}
} else if (cd.box == hopperBox2) {
- if (cd.extraBase < numEntries - NUM_RGROUP_BOXES) {
+ if (cd.extraBase < g_numEntries - NUM_RGROUP_BOXES) {
FirstEntry(cd.extraBase+(NUM_RGROUP_BOXES - 1));
AddBoxes(true);
if (cd.selBox)
@@ -5010,7 +4999,7 @@ static void ConfActionSpecial(int i) {
Select(cd.selBox, true);
}
} else if (cd.box == hopperBox1) {
- if (cd.extraBase < numScenes - NUM_RGROUP_BOXES) {
+ if (cd.extraBase < g_numScenes - NUM_RGROUP_BOXES) {
FirstScene(cd.extraBase + 1);
AddBoxes(true);
if (cd.selBox)
@@ -5018,7 +5007,7 @@ static void ConfActionSpecial(int i) {
Select(cd.selBox, true);
}
} else if (cd.box == hopperBox2) {
- if (cd.extraBase < numEntries - NUM_RGROUP_BOXES) {
+ if (cd.extraBase < g_numEntries - NUM_RGROUP_BOXES) {
FirstEntry(cd.extraBase + 1);
AddBoxes(true);
if (cd.selBox)
@@ -5045,25 +5034,25 @@ static void InvPutDown(int index) {
int hiIndex; // Current position of held item (if in)
// Find where the held item is positioned in this inventory (if it is)
- for (hiIndex = 0; hiIndex < InvD[ino].NoofItems; hiIndex++)
- if (InvD[ino].contents[hiIndex] == HeldItem)
+ for (hiIndex = 0; hiIndex < g_InvD[g_ino].NoofItems; hiIndex++)
+ if (g_InvD[g_ino].contents[hiIndex] == g_heldItem)
break;
// If drop position would leave a gap, move it up
- if (index >= InvD[ino].NoofItems) {
- if (hiIndex == InvD[ino].NoofItems) // Not in, add it
- index = InvD[ino].NoofItems;
+ if (index >= g_InvD[g_ino].NoofItems) {
+ if (hiIndex == g_InvD[g_ino].NoofItems) // Not in, add it
+ index = g_InvD[g_ino].NoofItems;
else
- index = InvD[ino].NoofItems - 1;
+ index = g_InvD[g_ino].NoofItems - 1;
}
- if (hiIndex == InvD[ino].NoofItems) { // Not in, add it
- if (InvD[ino].NoofItems < InvD[ino].MaxInvObj) {
- InvD[ino].NoofItems++;
+ if (hiIndex == g_InvD[g_ino].NoofItems) { // Not in, add it
+ if (g_InvD[g_ino].NoofItems < g_InvD[g_ino].MaxInvObj) {
+ g_InvD[g_ino].NoofItems++;
// Don't leave it in the other inventory!
- if (InventoryPos(HeldItem) != INV_HELDNOTIN)
- RemFromInventory(ino == INV_1 ? INV_2 : INV_1, HeldItem);
+ if (InventoryPos(g_heldItem) != INV_HELDNOTIN)
+ RemFromInventory(g_ino == INV_1 ? INV_2 : INV_1, g_heldItem);
} else {
// No room at the inn!
return;
@@ -5072,17 +5061,17 @@ static void InvPutDown(int index) {
// Position it in the inventory
if (index < hiIndex) {
- memmove(&InvD[ino].contents[index + 1], &InvD[ino].contents[index], (hiIndex-index)*sizeof(int));
- InvD[ino].contents[index] = HeldItem;
+ memmove(&g_InvD[g_ino].contents[index + 1], &g_InvD[g_ino].contents[index], (hiIndex-index)*sizeof(int));
+ g_InvD[g_ino].contents[index] = g_heldItem;
} else if (index > hiIndex) {
- memmove(&InvD[ino].contents[hiIndex], &InvD[ino].contents[hiIndex+1], (index-hiIndex)*sizeof(int));
- InvD[ino].contents[index] = HeldItem;
+ memmove(&g_InvD[g_ino].contents[hiIndex], &g_InvD[g_ino].contents[hiIndex+1], (index-hiIndex)*sizeof(int));
+ g_InvD[g_ino].contents[index] = g_heldItem;
} else {
- InvD[ino].contents[index] = HeldItem;
+ g_InvD[g_ino].contents[index] = g_heldItem;
}
- HeldItem = INV_NOICON;
- ItemsChanged = true;
+ g_heldItem = INV_NOICON;
+ g_ItemsChanged = true;
DelAuxCursor();
RestoreMainCursor();
GetCursorXY(&aniX, &aniY, false);
@@ -5116,26 +5105,26 @@ static void InvPickup(int index) {
return;
// If not holding anything
- if (HeldItem == INV_NOICON && InvD[ino].contents[index] &&
- (!TinselV2 || InvD[ino].contents[index] != HeldItem)) {
+ if (g_heldItem == INV_NOICON && g_InvD[g_ino].contents[index] &&
+ (!TinselV2 || g_InvD[g_ino].contents[index] != g_heldItem)) {
// Pick-up
- invObj = GetInvObject(InvD[ino].contents[index]);
- thisIcon = InvD[ino].contents[index];
+ invObj = GetInvObject(g_InvD[g_ino].contents[index]);
+ g_thisIcon = g_InvD[g_ino].contents[index];
if (TinselV2)
InvTinselEvent(invObj, PICKUP, INV_PICKUP, index);
else if (invObj->hScript)
InvTinselEvent(invObj, WALKTO, INV_PICKUP, index);
- } else if (HeldItem != INV_NOICON) {
+ } else if (g_heldItem != INV_NOICON) {
// Put-down
- invObj = GetInvObject(HeldItem);
+ invObj = GetInvObject(g_heldItem);
// If DROPCODE set, send event, otherwise it's a putdown
if (invObj->attribute & IO_DROPCODE && invObj->hScript)
InvTinselEvent(invObj, PUTDOWN, INV_PICKUP, index);
- else if (!(invObj->attribute & IO_ONLYINV1 && ino != INV_1)
- && !(invObj->attribute & IO_ONLYINV2 && ino != INV_2)) {
+ else if (!(invObj->attribute & IO_ONLYINV1 && g_ino != INV_1)
+ && !(invObj->attribute & IO_ONLYINV2 && g_ino != INV_2)) {
if (TinselV2)
InvPutDown(index);
else
@@ -5152,7 +5141,7 @@ static void InvWalkTo(const Common::Point &coOrds) {
switch (InvArea(coOrds.x, coOrds.y)) {
case I_NOTIN:
- if (ino == INV_CONV)
+ if (g_ino == INV_CONV)
ConvAction(INV_CLOSEICON);
if ((cd.box == hopperBox1) || (cd.box == hopperBox2))
FreeSceneHopper();
@@ -5160,43 +5149,43 @@ static void InvWalkTo(const Common::Point &coOrds) {
break;
case I_SLIDE_UP:
- if (InvD[ino].NoofVicons == 1)
- InvD[ino].FirstDisp -= InvD[ino].NoofHicons;
- for (i = 1; i < InvD[ino].NoofVicons; i++)
- InvD[ino].FirstDisp -= InvD[ino].NoofHicons;
- if (InvD[ino].FirstDisp < 0)
- InvD[ino].FirstDisp = 0;
- ItemsChanged = true;
+ if (g_InvD[g_ino].NoofVicons == 1)
+ g_InvD[g_ino].FirstDisp -= g_InvD[g_ino].NoofHicons;
+ for (i = 1; i < g_InvD[g_ino].NoofVicons; i++)
+ g_InvD[g_ino].FirstDisp -= g_InvD[g_ino].NoofHicons;
+ if (g_InvD[g_ino].FirstDisp < 0)
+ g_InvD[g_ino].FirstDisp = 0;
+ g_ItemsChanged = true;
break;
case I_UP:
- InvD[ino].FirstDisp -= InvD[ino].NoofHicons;
- if (InvD[ino].FirstDisp < 0)
- InvD[ino].FirstDisp = 0;
- ItemsChanged = true;
+ g_InvD[g_ino].FirstDisp -= g_InvD[g_ino].NoofHicons;
+ if (g_InvD[g_ino].FirstDisp < 0)
+ g_InvD[g_ino].FirstDisp = 0;
+ g_ItemsChanged = true;
break;
case I_SLIDE_DOWN:
- if (InvD[ino].NoofVicons == 1)
- if (InvD[ino].FirstDisp + InvD[ino].NoofHicons*InvD[ino].NoofVicons < InvD[ino].NoofItems)
- InvD[ino].FirstDisp += InvD[ino].NoofHicons;
- for (i = 1; i < InvD[ino].NoofVicons; i++) {
- if (InvD[ino].FirstDisp + InvD[ino].NoofHicons*InvD[ino].NoofVicons < InvD[ino].NoofItems)
- InvD[ino].FirstDisp += InvD[ino].NoofHicons;
+ if (g_InvD[g_ino].NoofVicons == 1)
+ if (g_InvD[g_ino].FirstDisp + g_InvD[g_ino].NoofHicons*g_InvD[g_ino].NoofVicons < g_InvD[g_ino].NoofItems)
+ g_InvD[g_ino].FirstDisp += g_InvD[g_ino].NoofHicons;
+ for (i = 1; i < g_InvD[g_ino].NoofVicons; i++) {
+ if (g_InvD[g_ino].FirstDisp + g_InvD[g_ino].NoofHicons*g_InvD[g_ino].NoofVicons < g_InvD[g_ino].NoofItems)
+ g_InvD[g_ino].FirstDisp += g_InvD[g_ino].NoofHicons;
}
- ItemsChanged = true;
+ g_ItemsChanged = true;
break;
case I_DOWN:
- if (InvD[ino].FirstDisp + InvD[ino].NoofHicons*InvD[ino].NoofVicons < InvD[ino].NoofItems) {
- InvD[ino].FirstDisp += InvD[ino].NoofHicons;
- ItemsChanged = true;
+ if (g_InvD[g_ino].FirstDisp + g_InvD[g_ino].NoofHicons*g_InvD[g_ino].NoofVicons < g_InvD[g_ino].NoofItems) {
+ g_InvD[g_ino].FirstDisp += g_InvD[g_ino].NoofHicons;
+ g_ItemsChanged = true;
}
break;
case I_BODY:
- if (ino == INV_CONF) {
- if (!InventoryHidden)
+ if (g_ino == INV_CONF) {
+ if (!g_InventoryHidden)
MenuAction(WhichMenuBox(coOrds.x, coOrds.y, false), false);
} else {
Common::Point pt = coOrds;
@@ -5204,8 +5193,8 @@ static void InvWalkTo(const Common::Point &coOrds) {
// To cater for drop in dead space between icons,
// look 1 pixel right, then 1 down, then 1 right and down.
- if (i == INV_NOICON && HeldItem != INV_NOICON &&
- (ino == INV_1 || ino == INV_2)) {
+ if (i == INV_NOICON && g_heldItem != INV_NOICON &&
+ (g_ino == INV_1 || g_ino == INV_2)) {
pt.x += 1; // 1 to the right
i = InvItem(pt, false);
if (i == INV_NOICON) {
@@ -5219,7 +5208,7 @@ static void InvWalkTo(const Common::Point &coOrds) {
}
}
- if (ino == INV_CONV) {
+ if (g_ino == INV_CONV) {
ConvAction(i);
} else
InvPickup(i);
@@ -5238,19 +5227,19 @@ static void InvAction() {
switch (InvArea(aniX, aniY)) {
case I_BODY:
- if (ino == INV_CONF) {
- if (!InventoryHidden)
+ if (g_ino == INV_CONF) {
+ if (!g_InventoryHidden)
MenuAction(WhichMenuBox(aniX, aniY, false), true);
- } else if (ino == INV_CONV) {
+ } else if (g_ino == INV_CONV) {
index = InvItem(&aniX, &aniY, false);
ConvAction(index);
} else {
index = InvItem(&aniX, &aniY, false);
if (index != INV_NOICON) {
- if (InvD[ino].contents[index] && InvD[ino].contents[index] != HeldItem) {
- invObj = GetInvObject(InvD[ino].contents[index]);
+ if (g_InvD[g_ino].contents[index] && g_InvD[g_ino].contents[index] != g_heldItem) {
+ invObj = GetInvObject(g_InvD[g_ino].contents[index]);
if (TinselV2)
- thisIcon = InvD[ino].contents[index];
+ g_thisIcon = g_InvD[g_ino].contents[index];
if (TinselV2 || (invObj->hScript))
InvTinselEvent(invObj, ACTION, INV_ACTION, index);
}
@@ -5259,33 +5248,33 @@ static void InvAction() {
break;
case I_HEADER: // Maximise/unmaximise inventory
- if (!InvD[ino].resizable)
+ if (!g_InvD[g_ino].resizable)
break;
- if (!InventoryMaximised) {
- InvD[ino].sNoofHicons = InvD[ino].NoofHicons;
- InvD[ino].sNoofVicons = InvD[ino].NoofVicons;
- InvD[ino].NoofHicons = InvD[ino].MaxHicons;
- InvD[ino].NoofVicons = InvD[ino].MaxVicons;
- InventoryMaximised = true;
-
- i = InvD[ino].inventoryX;
- InvD[ino].inventoryX = InvD[ino].otherX;
- InvD[ino].otherX = i;
- i = InvD[ino].inventoryY;
- InvD[ino].inventoryY = InvD[ino].otherY;
- InvD[ino].otherY = i;
+ if (!g_InventoryMaximised) {
+ g_InvD[g_ino].sNoofHicons = g_InvD[g_ino].NoofHicons;
+ g_InvD[g_ino].sNoofVicons = g_InvD[g_ino].NoofVicons;
+ g_InvD[g_ino].NoofHicons = g_InvD[g_ino].MaxHicons;
+ g_InvD[g_ino].NoofVicons = g_InvD[g_ino].MaxVicons;
+ g_InventoryMaximised = true;
+
+ i = g_InvD[g_ino].inventoryX;
+ g_InvD[g_ino].inventoryX = g_InvD[g_ino].otherX;
+ g_InvD[g_ino].otherX = i;
+ i = g_InvD[g_ino].inventoryY;
+ g_InvD[g_ino].inventoryY = g_InvD[g_ino].otherY;
+ g_InvD[g_ino].otherY = i;
} else {
- InvD[ino].NoofHicons = InvD[ino].sNoofHicons;
- InvD[ino].NoofVicons = InvD[ino].sNoofVicons;
- InventoryMaximised = false;
-
- i = InvD[ino].inventoryX;
- InvD[ino].inventoryX = InvD[ino].otherX;
- InvD[ino].otherX = i;
- i = InvD[ino].inventoryY;
- InvD[ino].inventoryY = InvD[ino].otherY;
- InvD[ino].otherY = i;
+ g_InvD[g_ino].NoofHicons = g_InvD[g_ino].sNoofHicons;
+ g_InvD[g_ino].NoofVicons = g_InvD[g_ino].sNoofVicons;
+ g_InventoryMaximised = false;
+
+ i = g_InvD[g_ino].inventoryX;
+ g_InvD[g_ino].inventoryX = g_InvD[g_ino].otherX;
+ g_InvD[g_ino].otherX = i;
+ i = g_InvD[g_ino].inventoryY;
+ g_InvD[g_ino].inventoryY = g_InvD[g_ino].otherY;
+ g_InvD[g_ino].otherY = i;
}
// Delete current, and re-draw
@@ -5295,15 +5284,15 @@ static void InvAction() {
break;
case I_UP:
- InvD[ino].FirstDisp -= InvD[ino].NoofHicons;
- if (InvD[ino].FirstDisp < 0)
- InvD[ino].FirstDisp = 0;
- ItemsChanged = true;
+ g_InvD[g_ino].FirstDisp -= g_InvD[g_ino].NoofHicons;
+ if (g_InvD[g_ino].FirstDisp < 0)
+ g_InvD[g_ino].FirstDisp = 0;
+ g_ItemsChanged = true;
break;
case I_DOWN:
- if (InvD[ino].FirstDisp + InvD[ino].NoofHicons*InvD[ino].NoofVicons < InvD[ino].NoofItems) {
- InvD[ino].FirstDisp += InvD[ino].NoofHicons;
- ItemsChanged = true;
+ if (g_InvD[g_ino].FirstDisp + g_InvD[g_ino].NoofHicons*g_InvD[g_ino].NoofVicons < g_InvD[g_ino].NoofItems) {
+ g_InvD[g_ino].FirstDisp += g_InvD[g_ino].NoofHicons;
+ g_ItemsChanged = true;
}
break;
}
@@ -5319,8 +5308,8 @@ static void InvLook(const Common::Point &coOrds) {
case I_BODY:
index = InvItem(pt, false);
if (index != INV_NOICON) {
- if (InvD[ino].contents[index] && InvD[ino].contents[index] != HeldItem) {
- invObj = GetInvObject(InvD[ino].contents[index]);
+ if (g_InvD[g_ino].contents[index] && g_InvD[g_ino].contents[index] != g_heldItem) {
+ invObj = GetInvObject(g_InvD[g_ino].contents[index]);
if (invObj->hScript)
InvTinselEvent(invObj, LOOK, INV_LOOK, index);
}
@@ -5328,7 +5317,7 @@ static void InvLook(const Common::Point &coOrds) {
break;
case I_NOTIN:
- if (ino == INV_CONV)
+ if (g_ino == INV_CONV)
ConvAction(INV_CLOSEICON);
KillInventory();
break;
@@ -5341,7 +5330,7 @@ static void InvLook(const Common::Point &coOrds) {
/**************************************************************************/
extern void EventToInventory(PLR_EVENT pEvent, const Common::Point &coOrds) {
- if (InventoryHidden)
+ if (g_InventoryHidden)
return;
switch (pEvent) {
@@ -5364,7 +5353,7 @@ extern void EventToInventory(PLR_EVENT pEvent, const Common::Point &coOrds) {
break;
case PLR_ACTION: // PLR_DLEFT
- if (InvDragging != ID_MDCONT)
+ if (g_InvDragging != ID_MDCONT)
InvDragEnd();
InvAction();
break;
@@ -5380,7 +5369,7 @@ extern void EventToInventory(PLR_EVENT pEvent, const Common::Point &coOrds) {
case PLR_ESCAPE:
if (MenuActive()) {
if (cd.box != optionBox && cd.box != hopperBox1 && cd.box != hopperBox2)
- bReOpenMenu = true;
+ g_bReOpenMenu = true;
if ((cd.box == hopperBox1) || (cd.box == hopperBox2))
FreeSceneHopper();
}
@@ -5388,42 +5377,42 @@ extern void EventToInventory(PLR_EVENT pEvent, const Common::Point &coOrds) {
break;
case PLR_PGDN:
- if (ino == INV_MENU) {
+ if (g_ino == INV_MENU) {
// Only act if load or save screen
MenuPageDown();
} else {
// This code is a copy of the IB_SLIDE_DOWN case in InvWalkTo
// TODO: So share this duplicate code
- if (InvD[ino].NoofVicons == 1)
- if (InvD[ino].FirstDisp + InvD[ino].NoofHicons*InvD[ino].NoofVicons < InvD[ino].NoofItems)
- InvD[ino].FirstDisp += InvD[ino].NoofHicons;
- for (int i = 1; i < InvD[ino].NoofVicons; i++) {
- if (InvD[ino].FirstDisp + InvD[ino].NoofHicons*InvD[ino].NoofVicons < InvD[ino].NoofItems)
- InvD[ino].FirstDisp += InvD[ino].NoofHicons;
+ if (g_InvD[g_ino].NoofVicons == 1)
+ if (g_InvD[g_ino].FirstDisp + g_InvD[g_ino].NoofHicons*g_InvD[g_ino].NoofVicons < g_InvD[g_ino].NoofItems)
+ g_InvD[g_ino].FirstDisp += g_InvD[g_ino].NoofHicons;
+ for (int i = 1; i < g_InvD[g_ino].NoofVicons; i++) {
+ if (g_InvD[g_ino].FirstDisp + g_InvD[g_ino].NoofHicons*g_InvD[g_ino].NoofVicons < g_InvD[g_ino].NoofItems)
+ g_InvD[g_ino].FirstDisp += g_InvD[g_ino].NoofHicons;
}
- ItemsChanged = true;
+ g_ItemsChanged = true;
}
break;
case PLR_PGUP:
- if (ino == INV_MENU) {
+ if (g_ino == INV_MENU) {
// Only act if load or save screen
MenuPageUp();
} else {
// This code is a copy of the I_SLIDE_UP case in InvWalkTo
// TODO: So share this duplicate code
- if (InvD[ino].NoofVicons == 1)
- InvD[ino].FirstDisp -= InvD[ino].NoofHicons;
- for (int i = 1; i < InvD[ino].NoofVicons; i++)
- InvD[ino].FirstDisp -= InvD[ino].NoofHicons;
- if (InvD[ino].FirstDisp < 0)
- InvD[ino].FirstDisp = 0;
- ItemsChanged = true;
+ if (g_InvD[g_ino].NoofVicons == 1)
+ g_InvD[g_ino].FirstDisp -= g_InvD[g_ino].NoofHicons;
+ for (int i = 1; i < g_InvD[g_ino].NoofVicons; i++)
+ g_InvD[g_ino].FirstDisp -= g_InvD[g_ino].NoofHicons;
+ if (g_InvD[g_ino].FirstDisp < 0)
+ g_InvD[g_ino].FirstDisp = 0;
+ g_ItemsChanged = true;
}
break;
case PLR_HOME:
- if (ino == INV_MENU) {
+ if (g_ino == INV_MENU) {
// Only act if load or save screen
if (cd.box == loadBox || cd.box == saveBox)
FirstFile(0);
@@ -5438,19 +5427,19 @@ extern void EventToInventory(PLR_EVENT pEvent, const Common::Point &coOrds) {
cd.selBox = 0;
Select(cd.selBox, true);
} else {
- InvD[ino].FirstDisp = 0;
- ItemsChanged = true;
+ g_InvD[g_ino].FirstDisp = 0;
+ g_ItemsChanged = true;
}
break;
case PLR_END:
- if (ino == INV_MENU) {
+ if (g_ino == INV_MENU) {
if (cd.box == loadBox || cd.box == saveBox)
FirstFile(MAX_SAVED_FILES); // Will get reduced to appropriate value
else if (cd.box == hopperBox1)
- FirstScene(numScenes); // Will get reduced to appropriate value
+ FirstScene(g_numScenes); // Will get reduced to appropriate value
else if (cd.box == hopperBox2)
- FirstEntry(numEntries); // Will get reduced to appropriate value
+ FirstEntry(g_numEntries); // Will get reduced to appropriate value
else
break;
@@ -5458,10 +5447,10 @@ extern void EventToInventory(PLR_EVENT pEvent, const Common::Point &coOrds) {
cd.selBox = 0;
Select(cd.selBox, true);
} else {
- InvD[ino].FirstDisp = InvD[ino].NoofItems - InvD[ino].NoofHicons*InvD[ino].NoofVicons;
- if (InvD[ino].FirstDisp < 0)
- InvD[ino].FirstDisp = 0;
- ItemsChanged = true;
+ g_InvD[g_ino].FirstDisp = g_InvD[g_ino].NoofItems - g_InvD[g_ino].NoofHicons*g_InvD[g_ino].NoofVicons;
+ if (g_InvD[g_ino].FirstDisp < 0)
+ g_InvD[g_ino].FirstDisp = 0;
+ g_ItemsChanged = true;
}
break;
default:
@@ -5483,8 +5472,8 @@ extern void SetObjectFilm(int object, SCNHANDLE hFilm) {
invObj = GetInvObject(object);
invObj->hIconFilm = hFilm;
- if (HeldItem != object)
- ItemsChanged = true;
+ if (g_heldItem != object)
+ g_ItemsChanged = true;
}
/**
@@ -5492,34 +5481,34 @@ extern void SetObjectFilm(int object, SCNHANDLE hFilm) {
*/
extern void syncInvInfo(Common::Serializer &s) {
for (int i = 0; i < NUM_INV; i++) {
- s.syncAsSint32LE(InvD[i].MinHicons);
- s.syncAsSint32LE(InvD[i].MinVicons);
- s.syncAsSint32LE(InvD[i].MaxHicons);
- s.syncAsSint32LE(InvD[i].MaxVicons);
- s.syncAsSint32LE(InvD[i].NoofHicons);
- s.syncAsSint32LE(InvD[i].NoofVicons);
+ s.syncAsSint32LE(g_InvD[i].MinHicons);
+ s.syncAsSint32LE(g_InvD[i].MinVicons);
+ s.syncAsSint32LE(g_InvD[i].MaxHicons);
+ s.syncAsSint32LE(g_InvD[i].MaxVicons);
+ s.syncAsSint32LE(g_InvD[i].NoofHicons);
+ s.syncAsSint32LE(g_InvD[i].NoofVicons);
for (int j = 0; j < MAX_ININV; j++) {
- s.syncAsSint32LE(InvD[i].contents[j]);
+ s.syncAsSint32LE(g_InvD[i].contents[j]);
}
- s.syncAsSint32LE(InvD[i].NoofItems);
- s.syncAsSint32LE(InvD[i].FirstDisp);
- s.syncAsSint32LE(InvD[i].inventoryX);
- s.syncAsSint32LE(InvD[i].inventoryY);
- s.syncAsSint32LE(InvD[i].otherX);
- s.syncAsSint32LE(InvD[i].otherY);
- s.syncAsSint32LE(InvD[i].MaxInvObj);
- s.syncAsSint32LE(InvD[i].hInvTitle);
- s.syncAsSint32LE(InvD[i].resizable);
- s.syncAsSint32LE(InvD[i].bMoveable);
- s.syncAsSint32LE(InvD[i].sNoofHicons);
- s.syncAsSint32LE(InvD[i].sNoofVicons);
- s.syncAsSint32LE(InvD[i].bMax);
+ s.syncAsSint32LE(g_InvD[i].NoofItems);
+ s.syncAsSint32LE(g_InvD[i].FirstDisp);
+ s.syncAsSint32LE(g_InvD[i].inventoryX);
+ s.syncAsSint32LE(g_InvD[i].inventoryY);
+ s.syncAsSint32LE(g_InvD[i].otherX);
+ s.syncAsSint32LE(g_InvD[i].otherY);
+ s.syncAsSint32LE(g_InvD[i].MaxInvObj);
+ s.syncAsSint32LE(g_InvD[i].hInvTitle);
+ s.syncAsSint32LE(g_InvD[i].resizable);
+ s.syncAsSint32LE(g_InvD[i].bMoveable);
+ s.syncAsSint32LE(g_InvD[i].sNoofHicons);
+ s.syncAsSint32LE(g_InvD[i].sNoofVicons);
+ s.syncAsSint32LE(g_InvD[i].bMax);
}
if (TinselV2) {
- for (int i = 0; i < numObjects; ++i)
- s.syncAsUint32LE(invFilms[i]);
- s.syncAsUint32LE(heldFilm);
+ for (int i = 0; i < g_numObjects; ++i)
+ s.syncAsUint32LE(g_invFilms[i]);
+ s.syncAsUint32LE(g_heldFilm);
}
}
@@ -5533,18 +5522,18 @@ extern void syncInvInfo(Common::Serializer &s) {
*/
// Note: the SCHANDLE type here has been changed to a void*
extern void RegisterIcons(void *cptr, int num) {
- numObjects = num;
- invObjects = (INV_OBJECT *) cptr;
+ g_numObjects = num;
+ g_invObjects = (INV_OBJECT *) cptr;
if (TinselV0) {
// In Tinsel 0, the INV_OBJECT structure doesn't have an attributes field, so we
// need to 'unpack' the source structures into the standard Tinsel v1/v2 format
- MEM_NODE *node = MemoryAllocFixed(numObjects * sizeof(INV_OBJECT));
+ MEM_NODE *node = MemoryAllocFixed(g_numObjects * sizeof(INV_OBJECT));
assert(node);
- invObjects = (INV_OBJECT *)MemoryDeref(node);
- assert(invObjects);
+ g_invObjects = (INV_OBJECT *)MemoryDeref(node);
+ assert(g_invObjects);
byte *srcP = (byte *)cptr;
- INV_OBJECT *destP = (INV_OBJECT *)invObjects;
+ INV_OBJECT *destP = (INV_OBJECT *)g_invObjects;
for (int i = 0; i < num; ++i, ++destP, srcP += 12) {
memmove(destP, srcP, 12);
@@ -5552,12 +5541,12 @@ extern void RegisterIcons(void *cptr, int num) {
}
} else if (TinselV1Mac) {
// Macintosh version has BE encoded resources, so the values need to be byte swapped
- MEM_NODE *node = MemoryAllocFixed(numObjects * sizeof(INV_OBJECT));
+ MEM_NODE *node = MemoryAllocFixed(g_numObjects * sizeof(INV_OBJECT));
assert(node);
- invObjects = (INV_OBJECT *)MemoryDeref(node);
- assert(invObjects);
+ g_invObjects = (INV_OBJECT *)MemoryDeref(node);
+ assert(g_invObjects);
INV_OBJECT *srcP = (INV_OBJECT *)cptr;
- INV_OBJECT *destP = (INV_OBJECT *)invObjects;
+ INV_OBJECT *destP = (INV_OBJECT *)g_invObjects;
for (int i = 0; i < num; ++i, ++destP, ++srcP) {
destP->id = FROM_BE_32(srcP->id);
@@ -5566,14 +5555,14 @@ extern void RegisterIcons(void *cptr, int num) {
destP->attribute = FROM_BE_32(srcP->attribute);
}
} else if (TinselV2) {
- if (invFilms == NULL) {
+ if (g_invFilms == NULL) {
// First time - allocate memory
- MEM_NODE *node = MemoryAllocFixed(numObjects * sizeof(SCNHANDLE));
+ MEM_NODE *node = MemoryAllocFixed(g_numObjects * sizeof(SCNHANDLE));
assert(node);
- invFilms = (SCNHANDLE *)MemoryDeref(node);
- if (invFilms == NULL)
+ g_invFilms = (SCNHANDLE *)MemoryDeref(node);
+ if (g_invFilms == NULL)
error(NO_MEM, "inventory scripts");
- memset(invFilms, 0, numObjects * sizeof(SCNHANDLE));
+ memset(g_invFilms, 0, g_numObjects * sizeof(SCNHANDLE));
}
@@ -5581,11 +5570,11 @@ extern void RegisterIcons(void *cptr, int num) {
// and store all the films separately
int i;
INV_OBJECT *pio;
- for (i = 0, pio = invObjects; i < numObjects; i++, pio++) {
+ for (i = 0, pio = g_invObjects; i < g_numObjects; i++, pio++) {
if (pio->attribute & PERMACONV)
PermaConvIcon(pio->id, pio->attribute & CONVENDITEM);
- invFilms[i] = pio->hIconFilm;
+ g_invFilms[i] = pio->hIconFilm;
}
}
}
@@ -5599,7 +5588,7 @@ extern void setInvWinParts(SCNHANDLE hf) {
const FILM *pfilm;
#endif
- hWinParts = hf;
+ g_hWinParts = hf;
#ifdef DEBUG
pfilm = (const FILM *)LockMem(hf);
@@ -5616,7 +5605,7 @@ extern void setFlagFilms(SCNHANDLE hf) {
const FILM *pfilm;
#endif
- flagFilm = hf;
+ g_flagFilm = hf;
#ifdef DEBUG
pfilm = (const FILM *)LockMem(hf);
@@ -5628,7 +5617,7 @@ extern void setFlagFilms(SCNHANDLE hf) {
* Called from Glitter function 'DecCStrings()'
*/
extern void setConfigStrings(SCNHANDLE *tp) {
- memcpy(configStrings, tp, sizeof(configStrings));
+ memcpy(g_configStrings, tp, sizeof(g_configStrings));
}
/**
@@ -5652,36 +5641,36 @@ extern void idec_inv(int num, SCNHANDLE text, int MaxContents,
if (StartHeight > MaxHeight)
StartHeight = MaxHeight;
- InventoryState = IDLE_INV;
+ g_InventoryState = IDLE_INV;
- InvD[num].MaxHicons = MaxWidth;
- InvD[num].MinHicons = MinWidth;
- InvD[num].MaxVicons = MaxHeight;
- InvD[num].MinVicons = MinHeight;
+ g_InvD[num].MaxHicons = MaxWidth;
+ g_InvD[num].MinHicons = MinWidth;
+ g_InvD[num].MaxVicons = MaxHeight;
+ g_InvD[num].MinVicons = MinHeight;
- InvD[num].NoofHicons = StartWidth;
- InvD[num].NoofVicons = StartHeight;
+ g_InvD[num].NoofHicons = StartWidth;
+ g_InvD[num].NoofVicons = StartHeight;
- memset(InvD[num].contents, 0, sizeof(InvD[num].contents));
- InvD[num].NoofItems = 0;
+ memset(g_InvD[num].contents, 0, sizeof(g_InvD[num].contents));
+ g_InvD[num].NoofItems = 0;
- InvD[num].FirstDisp = 0;
+ g_InvD[num].FirstDisp = 0;
- InvD[num].inventoryX = startx;
- InvD[num].inventoryY = starty;
- InvD[num].otherX = 21;
- InvD[num].otherY = 15;
+ g_InvD[num].inventoryX = startx;
+ g_InvD[num].inventoryY = starty;
+ g_InvD[num].otherX = 21;
+ g_InvD[num].otherY = 15;
- InvD[num].MaxInvObj = MaxContents;
+ g_InvD[num].MaxInvObj = MaxContents;
- InvD[num].hInvTitle = text;
+ g_InvD[num].hInvTitle = text;
if (MaxWidth != MinWidth && MaxHeight != MinHeight)
- InvD[num].resizable = true;
+ g_InvD[num].resizable = true;
- InvD[num].bMoveable = moveable;
+ g_InvD[num].bMoveable = moveable;
- InvD[num].bMax = false;
+ g_InvD[num].bMax = false;
}
/**
@@ -5729,7 +5718,7 @@ extern void idec_inv2(SCNHANDLE text, int MaxContents,
extern int InvGetLimit(int invno) {
assert(invno == INV_1 || invno == INV_2); // only INV_1 and INV_2 supported
- return InvD[invno].MaxInvObj;
+ return g_InvD[invno].MaxInvObj;
}
/**
@@ -5737,12 +5726,12 @@ extern int InvGetLimit(int invno) {
*/
extern void InvSetLimit(int invno, int MaxContents) {
assert(invno == INV_1 || invno == INV_2); // only INV_1 and INV_2 supported
- assert(MaxContents >= InvD[invno].NoofItems); // can't reduce maximum contents below current contents
+ assert(MaxContents >= g_InvD[invno].NoofItems); // can't reduce maximum contents below current contents
if (MaxContents > MAX_ININV)
MaxContents = MAX_ININV; // Max contents
- InvD[invno].MaxInvObj = MaxContents;
+ g_InvD[invno].MaxInvObj = MaxContents;
}
/**
@@ -5757,34 +5746,34 @@ extern void InvSetSize(int invno, int MinWidth, int MinHeight,
if (StartHeight > MaxHeight)
StartHeight = MaxHeight;
- InvD[invno].MaxHicons = MaxWidth;
- InvD[invno].MinHicons = MinWidth;
- InvD[invno].MaxVicons = MaxHeight;
- InvD[invno].MinVicons = MinHeight;
+ g_InvD[invno].MaxHicons = MaxWidth;
+ g_InvD[invno].MinHicons = MinWidth;
+ g_InvD[invno].MaxVicons = MaxHeight;
+ g_InvD[invno].MinVicons = MinHeight;
- InvD[invno].NoofHicons = StartWidth;
- InvD[invno].NoofVicons = StartHeight;
+ g_InvD[invno].NoofHicons = StartWidth;
+ g_InvD[invno].NoofVicons = StartHeight;
if (MaxWidth != MinWidth && MaxHeight != MinHeight)
- InvD[invno].resizable = true;
+ g_InvD[invno].resizable = true;
else
- InvD[invno].resizable = false;
+ g_InvD[invno].resizable = false;
- InvD[invno].bMax = false;
+ g_InvD[invno].bMax = false;
}
/**************************************************************************/
extern bool IsTopWindow() {
- return (InventoryState == BOGUS_INV);
+ return (g_InventoryState == BOGUS_INV);
}
extern bool MenuActive() {
- return (InventoryState == ACTIVE_INV && ino == INV_CONF);
+ return (g_InventoryState == ACTIVE_INV && g_ino == INV_CONF);
}
extern bool IsConvWindow() {
- return (InventoryState == ACTIVE_INV && ino == INV_CONV);
+ return (g_InventoryState == ACTIVE_INV && g_ino == INV_CONV);
}
} // End of namespace Tinsel
diff --git a/engines/tinsel/drives.cpp b/engines/tinsel/drives.cpp
index 5977d3b718..d815fd165d 100644
--- a/engines/tinsel/drives.cpp
+++ b/engines/tinsel/drives.cpp
@@ -32,13 +32,13 @@ namespace Tinsel {
// FIXME: Avoid non-const global vars
-char currentCD = '1';
+char g_currentCD = '1';
-static bool bChangingCD = false;
-static char nextCD = '\0';
+static bool g_bChangingCD = false;
+static char g_nextCD = '\0';
-static uint32 lastTime = 0;
-extern LANGUAGE sampleLanguage;
+static uint32 g_lastTime = 0;
+extern LANGUAGE g_sampleLanguage;
void CdCD(CORO_PARAM) {
@@ -47,7 +47,7 @@ void CdCD(CORO_PARAM) {
CORO_BEGIN_CODE(_ctx);
- while (bChangingCD) {
+ while (g_bChangingCD) {
if (g_scheduler->getCurrentProcess()) {
// FIXME: CdCD gets passed a nullContext in RegisterGlobals() and
// PrimeSceneHopper(), because I didn't know how to get a proper
@@ -66,13 +66,13 @@ void CdCD(CORO_PARAM) {
int GetCurrentCD() {
// count from 1
- return (currentCD - '1' + 1);
+ return (g_currentCD - '1' + 1);
}
static const uint32 cdFlags[] = { fCd1, fCd2, fCd3, fCd4, fCd5, fCd6, fCd7, fCd8 };
void SetCD(int flags) {
- if (flags & cdFlags[currentCD - '1'])
+ if (flags & cdFlags[g_currentCD - '1'])
return;
error("SetCD() problem");
@@ -82,7 +82,7 @@ int GetCD(int flags) {
int i;
char cd = '\0';
- if (flags & cdFlags[currentCD - '1'])
+ if (flags & cdFlags[g_currentCD - '1'])
return GetCurrentCD();
for (i = 0; i < 8; i++) {
@@ -93,19 +93,19 @@ int GetCD(int flags) {
}
assert(i != 8);
- nextCD = cd;
+ g_nextCD = cd;
return cd;
}
void DoCdChange() {
- if (bChangingCD && (g_system->getMillis() > (lastTime + 1000))) {
- lastTime = g_system->getMillis();
+ if (g_bChangingCD && (g_system->getMillis() > (g_lastTime + 1000))) {
+ g_lastTime = g_system->getMillis();
_vm->_sound->closeSampleStream();
// Use the filesize of the sample file to determine, for Discworld 2, which CD it is
if (TinselV2) {
TinselFile f;
- if (!f.open(_vm->getSampleFile(sampleLanguage)))
+ if (!f.open(_vm->getSampleFile(g_sampleLanguage)))
// No CD present
return;
@@ -113,28 +113,28 @@ void DoCdChange() {
f.close();
- if (currentCD != sampleCdNumber)
+ if (g_currentCD != sampleCdNumber)
return;
}
_vm->_sound->openSampleFiles();
ChangeLanguage(TextLanguage());
- bChangingCD = false;
+ g_bChangingCD = false;
}
}
void SetNextCD(int cdNumber) {
assert(cdNumber == 1 || cdNumber == 2);
- nextCD = (char)(cdNumber + '1' - 1);
+ g_nextCD = (char)(cdNumber + '1' - 1);
}
bool GotoCD() {
// WORKAROUND: Somehow, CdDoChange() is called twice... Hopefully, this guard helps
- if (currentCD == nextCD)
+ if (g_currentCD == g_nextCD)
return false;
- currentCD = nextCD;
+ g_currentCD = g_nextCD;
/* if (bNoCD) {
strcpy(cdDirectory, hdDirectory);
@@ -142,7 +142,7 @@ bool GotoCD() {
strcat(cdDirectory, cdLastBit);
}
*/
- bChangingCD = true;
+ g_bChangingCD = true;
return true;
}
diff --git a/engines/tinsel/events.cpp b/engines/tinsel/events.cpp
index e701ddca99..74454c5f2a 100644
--- a/engines/tinsel/events.cpp
+++ b/engines/tinsel/events.cpp
@@ -54,37 +54,37 @@ extern HPOLYGON GetTaggedPoly();
//----------------- EXTERNAL GLOBAL DATA ---------------------
-extern bool bEnableMenu;
+extern bool g_bEnableMenu;
//----------------- LOCAL GLOBAL DATA --------------------
// FIXME: Avoid non-const global vars
-static uint32 lastUserEvent = 0; // Time it hapenned
-static int leftEvents = 0; // Single or double, left or right. Or escape key.
-static int escEvents = 1; // Escape key
-static int userEvents = 0; // Whenever a button or a key comes in
+static uint32 g_lastUserEvent = 0; // Time it hapenned
+static int g_leftEvents = 0; // Single or double, left or right. Or escape key.
+static int g_escEvents = 1; // Escape key
+static int g_userEvents = 0; // Whenever a button or a key comes in
-static int eCount = 0;
+static int g_eCount = 0;
-static int controlState;
-static bool bStartOff;
+static int g_controlState;
+static bool g_bStartOff;
-static int controlX, controlY;
-static bool bProvNotProcessed = false;
+static int g_controlX, g_controlY;
+static bool g_bProvNotProcessed = false;
/**
* Gets called before each schedule, only 1 user action per schedule
* is allowed.
*/
void ResetEcount() {
- eCount = 0;
+ g_eCount = 0;
}
void IncUserEvents() {
- userEvents++;
- lastUserEvent = DwGetCurrentTime();
+ g_userEvents++;
+ g_lastUserEvent = DwGetCurrentTime();
}
/**
@@ -104,7 +104,7 @@ void AllowDclick(CORO_PARAM, PLR_EVENT be) {
FreeToken(TOKEN_LEFT_BUT);
// Prevent activation of 2 events on the same tick
- if (++eCount != 1)
+ if (++g_eCount != 1)
CORO_KILL_SELF();
break;
@@ -125,17 +125,17 @@ void ControlOn() {
return;
}
- bEnableMenu = false;
+ g_bEnableMenu = false;
- if (controlState == CONTROL_OFF) {
+ if (g_controlState == CONTROL_OFF) {
// Control is on
- controlState = CONTROL_ON;
+ g_controlState = CONTROL_ON;
// Restore cursor to where it was
- if (bStartOff == true)
- bStartOff = false;
+ if (g_bStartOff == true)
+ g_bStartOff = false;
else
- SetCursorXY(controlX, controlY);
+ SetCursorXY(g_controlX, g_controlY);
// Re-instate cursor
UnHideCursor();
@@ -155,14 +155,14 @@ void ControlOff() {
return;
}
- bEnableMenu = false;
+ g_bEnableMenu = false;
- if (controlState == CONTROL_ON) {
+ if (g_controlState == CONTROL_ON) {
// Control is off
- controlState = CONTROL_OFF;
+ g_controlState = CONTROL_OFF;
// Store cursor position
- GetCursorXY(&controlX, &controlY, true);
+ GetCursorXY(&g_controlX, &g_controlY, true);
// Blank out cursor
DwHideCursor();
@@ -181,10 +181,10 @@ void ControlStartOff() {
return;
}
- bEnableMenu = false;
+ g_bEnableMenu = false;
// Control is off
- controlState = CONTROL_OFF;
+ g_controlState = CONTROL_OFF;
// Blank out cursor
DwHideCursor();
@@ -192,7 +192,7 @@ void ControlStartOff() {
// Switch off tags
DisableTags();
- bStartOff = true;
+ g_bStartOff = true;
}
/**
@@ -211,7 +211,7 @@ bool GetControl(int param) {
}
bool GetControl() {
- if (controlState == CONTROL_ON) {
+ if (g_controlState == CONTROL_ON) {
ControlOff();
return true;
} else
@@ -220,7 +220,7 @@ bool GetControl() {
bool ControlIsOn() {
if (TinselV2)
- return (controlState == CONTROL_ON);
+ return (g_controlState == CONTROL_ON);
return TestToken(TOKEN_CONTROL);
}
@@ -289,7 +289,7 @@ static void ProcessUserEvent(TINSEL_EVENT uEvent, const Common::Point &coOrds, P
HPOLYGON hPoly;
// Prevent activation of 2 events on the same tick
- if (++eCount != 1)
+ if (++g_eCount != 1)
return;
if ((actor = GetTaggedActor()) != 0) {
@@ -395,19 +395,19 @@ void PlayerEvent(PLR_EVENT pEvent, const Common::Point &coOrds) {
static uint32 lastRealAction = 0; // FIXME: Avoid non-const global vars
// This stuff to allow F1 key during startup.
- if (bEnableMenu && pEvent == PLR_MENU)
+ if (g_bEnableMenu && pEvent == PLR_MENU)
Control(CONTROL_ON);
else
IncUserEvents();
if (pEvent == PLR_ESCAPE) {
- ++escEvents;
- ++leftEvents; // Yes, I do mean this
+ ++g_escEvents;
+ ++g_leftEvents; // Yes, I do mean this
} else if ((pEvent == PLR_PROV_WALKTO)
|| (pEvent == PLR_WALKTO)
|| (pEvent == PLR_LOOK)
|| (pEvent == PLR_ACTION)) {
- ++leftEvents;
+ ++g_leftEvents;
}
// Only allow events if player control is on
@@ -484,18 +484,18 @@ void PlayerEvent(PLR_EVENT pEvent, const Common::Point &coOrds) {
* For ESCapable Glitter sequences
*/
int GetEscEvents() {
- return escEvents;
+ return g_escEvents;
}
/**
* For cutting short talk()s etc.
*/
int GetLeftEvents() {
- return leftEvents;
+ return g_leftEvents;
}
bool LeftEventChange(int myleftEvent) {
- if (leftEvents != myleftEvent) {
+ if (g_leftEvents != myleftEvent) {
ProcessedProvisional();
return true;
} else
@@ -506,15 +506,15 @@ bool LeftEventChange(int myleftEvent) {
* For waitkey() Glitter function
*/
int getUserEvents() {
- return userEvents;
+ return g_userEvents;
}
uint32 getUserEventTime() {
- return DwGetCurrentTime() - lastUserEvent;
+ return DwGetCurrentTime() - g_lastUserEvent;
}
void resetUserEventTime() {
- lastUserEvent = DwGetCurrentTime();
+ g_lastUserEvent = DwGetCurrentTime();
}
struct PTP_INIT {
@@ -655,18 +655,18 @@ void effRunPolyTinselCode(HPOLYGON hPoly, TINSEL_EVENT event, int actor) {
* subsequent 'real' event.
*/
void ProcessedProvisional() {
- bProvNotProcessed = false;
+ g_bProvNotProcessed = false;
}
/**
* Resets the bProvNotProcessed flag
*/
void ProvNotProcessed() {
- bProvNotProcessed = true;
+ g_bProvNotProcessed = true;
}
bool GetProvNotProcessed() {
- return bProvNotProcessed;
+ return g_bProvNotProcessed;
}
} // End of namespace Tinsel
diff --git a/engines/tinsel/font.cpp b/engines/tinsel/font.cpp
index e857dca509..54aa7cc15f 100644
--- a/engines/tinsel/font.cpp
+++ b/engines/tinsel/font.cpp
@@ -34,38 +34,38 @@ namespace Tinsel {
// FIXME: Avoid non-const global vars
-static char tBuffer[TBUFSZ];
+static char g_tBuffer[TBUFSZ];
-static SCNHANDLE hTagFont = 0, hTalkFont = 0;
-static SCNHANDLE hRegularTalkFont = 0, hRegularTagFont = 0;
+static SCNHANDLE g_hTagFont = 0, g_hTalkFont = 0;
+static SCNHANDLE g_hRegularTalkFont = 0, g_hRegularTagFont = 0;
/**
* Return address of tBuffer
*/
char *TextBufferAddr() {
- return tBuffer;
+ return g_tBuffer;
}
/**
* Return hTagFont handle.
*/
SCNHANDLE GetTagFontHandle() {
- return hTagFont;
+ return g_hTagFont;
}
/**
* Return hTalkFont handle.
*/
SCNHANDLE GetTalkFontHandle() {
- return hTalkFont;
+ return g_hTalkFont;
}
/**
* Called from dec_tagfont() Glitter function. Store the tag font handle.
*/
void SetTagFontHandle(SCNHANDLE hFont) {
- hTagFont = hRegularTagFont = hFont; // Store the font handle
+ g_hTagFont = g_hRegularTagFont = hFont; // Store the font handle
}
/**
@@ -73,20 +73,20 @@ void SetTagFontHandle(SCNHANDLE hFont) {
* Store the talk font handle.
*/
void SetTalkFontHandle(SCNHANDLE hFont) {
- hTalkFont = hRegularTalkFont = hFont; // Store the font handle
+ g_hTalkFont = g_hRegularTalkFont = hFont; // Store the font handle
}
void SetTempTagFontHandle(SCNHANDLE hFont) {
- hTagFont = hFont;
+ g_hTagFont = hFont;
}
void SetTempTalkFontHandle(SCNHANDLE hFont) {
- hTalkFont = hFont;
+ g_hTalkFont = hFont;
}
void ResetFontHandles() {
- hTagFont = hRegularTagFont;
- hTalkFont = hRegularTalkFont;
+ g_hTagFont = g_hRegularTagFont;
+ g_hTalkFont = g_hRegularTalkFont;
}
@@ -98,17 +98,17 @@ void FettleFontPal(SCNHANDLE fontPal) {
IMAGE *pImg;
assert(fontPal);
- assert(hTagFont); // Tag font not declared
- assert(hTalkFont); // Talk font not declared
+ assert(g_hTagFont); // Tag font not declared
+ assert(g_hTalkFont); // Talk font not declared
- pFont = (const FONT *)LockMem(hTagFont);
+ pFont = (const FONT *)LockMem(g_hTagFont);
pImg = (IMAGE *)LockMem(FROM_LE_32(pFont->fontInit.hObjImg)); // get image for char 0
if (!TinselV2)
pImg->hImgPal = TO_LE_32(fontPal);
else
pImg->hImgPal = 0;
- pFont = (const FONT *)LockMem(hTalkFont);
+ pFont = (const FONT *)LockMem(g_hTalkFont);
pImg = (IMAGE *)LockMem(FROM_LE_32(pFont->fontInit.hObjImg)); // get image for char 0
if (!TinselV2)
pImg->hImgPal = TO_LE_32(fontPal);
diff --git a/engines/tinsel/graphics.cpp b/engines/tinsel/graphics.cpp
index 6a5d626de8..9b06b1a501 100644
--- a/engines/tinsel/graphics.cpp
+++ b/engines/tinsel/graphics.cpp
@@ -40,7 +40,7 @@ namespace Tinsel {
#define CHAR_WIDTH 4
#define CHAR_HEIGHT 4
-extern uint8 transPalette[MAX_COLORS];
+extern uint8 g_transPalette[MAX_COLORS];
//----------------- SUPPORT FUNCTIONS ---------------------
@@ -67,7 +67,7 @@ uint8* psxPJCRLEUnwinder(uint16 imageWidth, uint16 imageHeight, uint8 *srcIdx) {
// Calculate needed index numbers, align width and height not next multiple of four
imageWidth = (imageWidth % 4) ? ((imageWidth / 4) + 1) * 4 : imageWidth;
imageHeight = (imageHeight % 4) ? ((imageHeight / 4) + 1) * 4 : imageHeight;
- destinationBuffer = (uint8*)malloc((imageWidth * imageHeight) / 8);
+ destinationBuffer = (uint8 *)malloc((imageWidth * imageHeight) / 8);
dstIdx = destinationBuffer;
remainingBlocks = (imageWidth * imageHeight) / 16;
@@ -478,9 +478,9 @@ static void t2WrtNonZero(DRAWOBJECT *pObj, uint8 *srcP, uint8 *destP, bool apply
// Non-transparent run length
color += pObj->constant;
if (horizFlipped)
- Common::set_to(tempP - runLength + 1, tempP + 1, color);
+ Common::fill(tempP - runLength + 1, tempP + 1, color);
else
- Common::set_to(tempP, tempP + runLength, color);
+ Common::fill(tempP, tempP + runLength, color);
}
}
@@ -533,7 +533,7 @@ static void WrtConst(DRAWOBJECT *pObj, uint8 *destP, bool applyClipping) {
// Loop through any remaining lines
while (pObj->height > 0) {
- Common::set_to(destP, destP + pObj->width, pObj->constant);
+ Common::fill(destP, destP + pObj->width, pObj->constant);
--pObj->height;
destP += SCREEN_WIDTH;
@@ -559,7 +559,7 @@ static void WrtTrans(DRAWOBJECT *pObj, uint8 *destP, bool applyClipping) {
// Loop through any remaining lines
while (pObj->height > 0) {
for (int i = 0; i < pObj->width; ++i, ++destP)
- *destP = transPalette[*destP];
+ *destP = g_transPalette[*destP];
--pObj->height;
destP += lineOffset;
diff --git a/engines/tinsel/handle.cpp b/engines/tinsel/handle.cpp
index eeb83b1f98..e31b2141f5 100644
--- a/engines/tinsel/handle.cpp
+++ b/engines/tinsel/handle.cpp
@@ -69,17 +69,17 @@ enum {
// FIXME: Avoid non-const global vars
// handle table gets loaded from index file at runtime
-static MEMHANDLE *handleTable = 0;
+static MEMHANDLE *g_handleTable = 0;
// number of handles in the handle table
-static uint numHandles = 0;
+static uint g_numHandles = 0;
-static uint32 cdPlayHandle = (uint32)-1;
+static uint32 g_cdPlayHandle = (uint32)-1;
-static SCNHANDLE cdBaseHandle = 0, cdTopHandle = 0;
-static Common::File *cdGraphStream = 0;
+static SCNHANDLE g_cdBaseHandle = 0, g_cdTopHandle = 0;
+static Common::File *g_cdGraphStream = 0;
-static char szCdPlayFile[100];
+static char g_szCdPlayFile[100];
//----------------- FORWARD REFERENCES --------------------
@@ -110,24 +110,24 @@ void SetupHandleTable() {
}
// calc number of handles
- numHandles = len / RECORD_SIZE;
+ g_numHandles = len / RECORD_SIZE;
// allocate memory for the index file
- handleTable = (MEMHANDLE *)calloc(numHandles, sizeof(struct MEMHANDLE));
+ g_handleTable = (MEMHANDLE *)calloc(g_numHandles, sizeof(struct MEMHANDLE));
// make sure memory allocated
- assert(handleTable);
+ assert(g_handleTable);
// load data
- for (i = 0; i < numHandles; i++) {
- f.read(handleTable[i].szName, 12);
- handleTable[i].filesize = f.readUint32();
+ for (i = 0; i < g_numHandles; i++) {
+ f.read(g_handleTable[i].szName, 12);
+ g_handleTable[i].filesize = f.readUint32();
// The pointer should always be NULL. We don't
// need to read that from the file.
- handleTable[i]._node = NULL;
+ g_handleTable[i]._node = NULL;
f.seek(4, SEEK_CUR);
// For Discworld 2, read in the flags2 field
- handleTable[i].flags2 = t2Flag ? f.readUint32() : 0;
+ g_handleTable[i].flags2 = t2Flag ? f.readUint32() : 0;
}
if (f.eos() || f.err()) {
@@ -145,7 +145,7 @@ void SetupHandleTable() {
}
// allocate memory nodes and load all permanent graphics
- for (i = 0, pH = handleTable; i < numHandles; i++, pH++) {
+ for (i = 0, pH = g_handleTable; i < g_numHandles; i++, pH++) {
if (pH->filesize & fPreload) {
// allocate a fixed memory node for permanent files
pH->_node = MemoryAllocFixed((pH->filesize & FSIZE_MASK));
@@ -172,24 +172,24 @@ void SetupHandleTable() {
}
void FreeHandleTable() {
- free(handleTable);
- handleTable = NULL;
+ free(g_handleTable);
+ g_handleTable = NULL;
- delete cdGraphStream;
- cdGraphStream = NULL;
+ delete g_cdGraphStream;
+ g_cdGraphStream = NULL;
}
/**
* Loads a memory block as a file.
*/
void OpenCDGraphFile() {
- delete cdGraphStream;
+ delete g_cdGraphStream;
// As the theory goes, the right CD will be in there!
- cdGraphStream = new Common::File;
- if (!cdGraphStream->open(szCdPlayFile))
- error(CANNOT_FIND_FILE, szCdPlayFile);
+ g_cdGraphStream = new Common::File;
+ if (!g_cdGraphStream->open(g_szCdPlayFile))
+ error(CANNOT_FIND_FILE, g_szCdPlayFile);
}
void LoadCDGraphData(MEMHANDLE *pH) {
@@ -210,15 +210,15 @@ void LoadCDGraphData(MEMHANDLE *pH) {
assert(addr);
// Move to correct place in file and load the required data
- assert(cdGraphStream);
- cdGraphStream->seek(cdBaseHandle & OFFSETMASK, SEEK_SET);
- bytes = cdGraphStream->read(addr, (cdTopHandle - cdBaseHandle) & OFFSETMASK);
+ assert(g_cdGraphStream);
+ g_cdGraphStream->seek(g_cdBaseHandle & OFFSETMASK, SEEK_SET);
+ bytes = g_cdGraphStream->read(addr, (g_cdTopHandle - g_cdBaseHandle) & OFFSETMASK);
// New code to try and handle CD read failures 24/2/97
- while (bytes != ((cdTopHandle - cdBaseHandle) & OFFSETMASK) && retries++ < MAX_READ_RETRIES) {
+ while (bytes != ((g_cdTopHandle - g_cdBaseHandle) & OFFSETMASK) && retries++ < MAX_READ_RETRIES) {
// Try again
- cdGraphStream->seek(cdBaseHandle & OFFSETMASK, SEEK_SET);
- bytes = cdGraphStream->read(addr, (cdTopHandle - cdBaseHandle) & OFFSETMASK);
+ g_cdGraphStream->seek(g_cdBaseHandle & OFFSETMASK, SEEK_SET);
+ bytes = g_cdGraphStream->read(addr, (g_cdTopHandle - g_cdBaseHandle) & OFFSETMASK);
}
// discardable - unlock the memory
@@ -230,7 +230,7 @@ void LoadCDGraphData(MEMHANDLE *pH) {
// clear the loading flag
// pH->filesize &= ~fLoading;
- if (bytes != ((cdTopHandle - cdBaseHandle) & OFFSETMASK))
+ if (bytes != ((g_cdTopHandle - g_cdBaseHandle) & OFFSETMASK))
// file is corrupt
error(FILE_READ_ERROR, "CD play file");
}
@@ -245,22 +245,22 @@ void LoadCDGraphData(MEMHANDLE *pH) {
void LoadExtraGraphData(SCNHANDLE start, SCNHANDLE next) {
OpenCDGraphFile();
- MemoryDiscard((handleTable + cdPlayHandle)->_node); // Free it
+ MemoryDiscard((g_handleTable + g_cdPlayHandle)->_node); // Free it
// It must always be the same
- assert(cdPlayHandle == (start >> SCNHANDLE_SHIFT));
- assert(cdPlayHandle == (next >> SCNHANDLE_SHIFT));
+ assert(g_cdPlayHandle == (start >> SCNHANDLE_SHIFT));
+ assert(g_cdPlayHandle == (next >> SCNHANDLE_SHIFT));
- cdBaseHandle = start;
- cdTopHandle = next;
+ g_cdBaseHandle = start;
+ g_cdTopHandle = next;
}
void SetCdPlaySceneDetails(int fileNum, const char *fileName) {
- strcpy(szCdPlayFile, fileName);
+ strcpy(g_szCdPlayFile, fileName);
}
void SetCdPlayHandle(int fileNum) {
- cdPlayHandle = fileNum;
+ g_cdPlayHandle = fileNum;
}
@@ -323,26 +323,26 @@ byte *LockMem(SCNHANDLE offset) {
MEMHANDLE *pH; // points to table entry
// range check the memory handle
- assert(handle < numHandles);
+ assert(handle < g_numHandles);
#ifdef DEBUG
if (handle != s_lockedScene)
warning(" Calling LockMem(0x%x), handle %d differs from active scene %d", offset, handle, s_lockedScene);
#endif
- pH = handleTable + handle;
+ pH = g_handleTable + handle;
if (pH->filesize & fPreload) {
// permanent files are already loaded, nothing to be done
- } else if (handle == cdPlayHandle) {
+ } else if (handle == g_cdPlayHandle) {
// Must be in currently loaded/loadable range
- if (offset < cdBaseHandle || offset >= cdTopHandle)
+ if (offset < g_cdBaseHandle || offset >= g_cdTopHandle)
error("Overlapping (in time) CD-plays");
// May have been discarded, if so, we have to reload
if (!MemoryDeref(pH->_node)) {
// Data was discarded, we have to reload
- MemoryReAlloc(pH->_node, cdTopHandle - cdBaseHandle);
+ MemoryReAlloc(pH->_node, g_cdTopHandle - g_cdBaseHandle);
LoadCDGraphData(pH);
@@ -353,7 +353,7 @@ byte *LockMem(SCNHANDLE offset) {
// make sure address is valid
assert(pH->filesize & fLoaded);
- offset -= cdBaseHandle;
+ offset -= g_cdBaseHandle;
} else {
if (!MemoryDeref(pH->_node)) {
// Data was discarded, we have to reload
@@ -387,9 +387,9 @@ void LockScene(SCNHANDLE offset) {
#endif
// range check the memory handle
- assert(handle < numHandles);
+ assert(handle < g_numHandles);
- pH = handleTable + handle;
+ pH = g_handleTable + handle;
if ((pH->filesize & fPreload) == 0) {
// Ensure the scene handle is allocated.
@@ -414,9 +414,9 @@ void UnlockScene(SCNHANDLE offset) {
MEMHANDLE *pH; // points to table entry
// range check the memory handle
- assert(handle < numHandles);
+ assert(handle < g_numHandles);
- pH = handleTable + handle;
+ pH = g_handleTable + handle;
if ((pH->filesize & fPreload) == 0) {
// unlock the scene data
@@ -441,9 +441,9 @@ bool ValidHandle(SCNHANDLE offset) {
MEMHANDLE *pH; // points to table entry
// range check the memory handle
- assert(handle < numHandles);
+ assert(handle < g_numHandles);
- pH = handleTable + handle;
+ pH = g_handleTable + handle;
return (pH->filesize & FSIZE_MASK) != 8;
}
@@ -458,7 +458,7 @@ void TouchMem(SCNHANDLE offset) {
uint32 handle = offset >> SCNHANDLE_SHIFT; // calc memory handle to use
if (offset != 0) {
- pH = handleTable + handle;
+ pH = g_handleTable + handle;
// update the LRU time whether its loaded or not!
if (pH->_node)
@@ -474,9 +474,9 @@ bool IsCdPlayHandle(SCNHANDLE offset) {
uint32 handle = offset >> SCNHANDLE_SHIFT; // calc memory handle to use
// range check the memory handle
- assert(handle < numHandles);
+ assert(handle < g_numHandles);
- return (handle == cdPlayHandle);
+ return (handle == g_cdPlayHandle);
}
/**
@@ -486,9 +486,9 @@ int CdNumber(SCNHANDLE offset) {
uint handle = offset >> SCNHANDLE_SHIFT; // calc memory handle to use
// range check the memory handle
- assert(handle < numHandles);
+ assert(handle < g_numHandles);
- MEMHANDLE *pH = handleTable + handle;
+ MEMHANDLE *pH = g_handleTable + handle;
if (!TinselV2)
return 1;
diff --git a/engines/tinsel/heapmem.cpp b/engines/tinsel/heapmem.cpp
index 026dc9457e..597cc69e66 100644
--- a/engines/tinsel/heapmem.cpp
+++ b/engines/tinsel/heapmem.cpp
@@ -58,16 +58,16 @@ static const uint32 MemoryPoolSize[3] = {5 * 1024 * 1024, 5 * 1024 * 1024, 10 *
// list of all memory nodes
-MEM_NODE mnodeList[NUM_MNODES];
+MEM_NODE g_mnodeList[NUM_MNODES];
// pointer to the linked list of free mnodes
-static MEM_NODE *pFreeMemNodes;
+static MEM_NODE *g_pFreeMemNodes;
// list of all fixed memory nodes
-MEM_NODE s_fixedMnodesList[5];
+MEM_NODE g_s_fixedMnodesList[5];
// the mnode heap sentinel
-static MEM_NODE heapSentinel;
+static MEM_NODE g_heapSentinel;
//
static MEM_NODE *AllocMemNode();
@@ -80,7 +80,7 @@ static void MemoryStats() {
int lockedSize = 0;
int totalSize = 0;
- const MEM_NODE *pHeap = &heapSentinel;
+ const MEM_NODE *pHeap = &g_heapSentinel;
MEM_NODE *pCur;
for (pCur = pHeap->pNext; pCur != pHeap; pCur = pCur->pNext) {
@@ -104,43 +104,43 @@ static void MemoryStats() {
*/
void MemoryInit() {
// place first node on free list
- pFreeMemNodes = mnodeList;
+ g_pFreeMemNodes = g_mnodeList;
// link all other objects after first
- memset(mnodeList, 0, sizeof(mnodeList));
+ memset(g_mnodeList, 0, sizeof(g_mnodeList));
for (int i = 1; i < NUM_MNODES; i++) {
- mnodeList[i - 1].pNext = mnodeList + i;
+ g_mnodeList[i - 1].pNext = g_mnodeList + i;
}
// null the last mnode
- mnodeList[NUM_MNODES - 1].pNext = NULL;
+ g_mnodeList[NUM_MNODES - 1].pNext = NULL;
// clear list of fixed memory nodes
- memset(s_fixedMnodesList, 0, sizeof(s_fixedMnodesList));
+ memset(g_s_fixedMnodesList, 0, sizeof(g_s_fixedMnodesList));
// set cyclic links to the sentinel
- heapSentinel.pPrev = &heapSentinel;
- heapSentinel.pNext = &heapSentinel;
+ g_heapSentinel.pPrev = &g_heapSentinel;
+ g_heapSentinel.pNext = &g_heapSentinel;
// flag sentinel as locked
- heapSentinel.flags = DWM_LOCKED | DWM_SENTINEL;
+ g_heapSentinel.flags = DWM_LOCKED | DWM_SENTINEL;
// store the current heap size in the sentinel
uint32 size = MemoryPoolSize[0];
if (TinselVersion == TINSEL_V1) size = MemoryPoolSize[1];
else if (TinselVersion == TINSEL_V2) size = MemoryPoolSize[2];
- heapSentinel.size = size;
+ g_heapSentinel.size = size;
}
/**
* Deinitializes the memory manager.
*/
void MemoryDeinit() {
- const MEM_NODE *pHeap = &heapSentinel;
+ const MEM_NODE *pHeap = &g_heapSentinel;
MEM_NODE *pCur;
- pCur = s_fixedMnodesList;
- for (int i = 0; i < ARRAYSIZE(s_fixedMnodesList); ++i, ++pCur) {
+ pCur = g_s_fixedMnodesList;
+ for (int i = 0; i < ARRAYSIZE(g_s_fixedMnodesList); ++i, ++pCur) {
free(pCur->pBaseAddr);
pCur->pBaseAddr = 0;
}
@@ -157,13 +157,13 @@ void MemoryDeinit() {
*/
static MEM_NODE *AllocMemNode() {
// get the first free mnode
- MEM_NODE *pMemNode = pFreeMemNodes;
+ MEM_NODE *pMemNode = g_pFreeMemNodes;
// make sure a mnode is available
assert(pMemNode); // Out of memory nodes
// the next free mnode
- pFreeMemNodes = pMemNode->pNext;
+ g_pFreeMemNodes = pMemNode->pNext;
// wipe out the mnode
memset(pMemNode, 0, sizeof(MEM_NODE));
@@ -178,13 +178,13 @@ static MEM_NODE *AllocMemNode() {
*/
void FreeMemNode(MEM_NODE *pMemNode) {
// validate mnode pointer
- assert(pMemNode >= mnodeList && pMemNode <= mnodeList + NUM_MNODES - 1);
+ assert(pMemNode >= g_mnodeList && pMemNode <= g_mnodeList + NUM_MNODES - 1);
// place free list in mnode next
- pMemNode->pNext = pFreeMemNodes;
+ pMemNode->pNext = g_pFreeMemNodes;
// add mnode to top of free list
- pFreeMemNodes = pMemNode;
+ g_pFreeMemNodes = pMemNode;
}
@@ -194,11 +194,11 @@ void FreeMemNode(MEM_NODE *pMemNode) {
* @return true if any blocks were discarded, false otherwise
*/
static bool HeapCompact(long size) {
- const MEM_NODE *pHeap = &heapSentinel;
+ const MEM_NODE *pHeap = &g_heapSentinel;
MEM_NODE *pCur, *pOldest;
uint32 oldest; // time of the oldest discardable block
- while (heapSentinel.size < size) {
+ while (g_heapSentinel.size < size) {
// find the oldest discardable block
oldest = DwGetCurrentTime();
@@ -231,11 +231,11 @@ static bool HeapCompact(long size) {
* @param size Number of bytes to allocate
*/
static MEM_NODE *MemoryAlloc(long size) {
- MEM_NODE *pHeap = &heapSentinel;
+ MEM_NODE *pHeap = &g_heapSentinel;
#ifdef SCUMM_NEED_ALIGNMENT
- const int alignPadding = sizeof(void*) - 1;
- size = (size + alignPadding) & ~alignPadding; //round up to nearest multiple of sizeof(void*), this ensures the addresses that are returned are alignment-safe.
+ const int alignPadding = sizeof(void *) - 1;
+ size = (size + alignPadding) & ~alignPadding; //round up to nearest multiple of sizeof(void *), this ensures the addresses that are returned are alignment-safe.
#endif
// compact the heap to make up room for 'size' bytes, if necessary
@@ -255,7 +255,7 @@ static MEM_NODE *MemoryAlloc(long size) {
assert(pNode->pBaseAddr);
// Subtract size of new block from total
- heapSentinel.size -= size;
+ g_heapSentinel.size -= size;
#ifdef DEBUG
MemoryStats();
@@ -282,7 +282,7 @@ static MEM_NODE *MemoryAlloc(long size) {
* by using MemoryReAlloc().
*/
MEM_NODE *MemoryNoAlloc() {
- MEM_NODE *pHeap = &heapSentinel;
+ MEM_NODE *pHeap = &g_heapSentinel;
// chain a discarded node onto the end of the heap
MEM_NODE *pNode = AllocMemNode();
@@ -310,13 +310,13 @@ MEM_NODE *MemoryNoAlloc() {
MEM_NODE *MemoryAllocFixed(long size) {
#ifdef SCUMM_NEED_ALIGNMENT
- const int alignPadding = sizeof(void*) - 1;
- size = (size + alignPadding) & ~alignPadding; //round up to nearest multiple of sizeof(void*), this ensures the addresses that are returned are alignment-safe.
+ const int alignPadding = sizeof(void *) - 1;
+ size = (size + alignPadding) & ~alignPadding; //round up to nearest multiple of sizeof(void *), this ensures the addresses that are returned are alignment-safe.
#endif
// Search for a free entry in s_fixedMnodesList
- MEM_NODE *pNode = s_fixedMnodesList;
- for (int i = 0; i < ARRAYSIZE(s_fixedMnodesList); ++i, ++pNode) {
+ MEM_NODE *pNode = g_s_fixedMnodesList;
+ for (int i = 0; i < ARRAYSIZE(g_s_fixedMnodesList); ++i, ++pNode) {
if (!pNode->pBaseAddr) {
pNode->pNext = 0;
pNode->pPrev = 0;
@@ -326,7 +326,7 @@ MEM_NODE *MemoryAllocFixed(long size) {
pNode->flags = DWM_USED;
// Subtract size of new block from total
- heapSentinel.size -= size;
+ g_heapSentinel.size -= size;
return pNode;
}
@@ -342,7 +342,7 @@ MEM_NODE *MemoryAllocFixed(long size) {
*/
void MemoryDiscard(MEM_NODE *pMemNode) {
// validate mnode pointer
- assert(pMemNode >= mnodeList && pMemNode <= mnodeList + NUM_MNODES - 1);
+ assert(pMemNode >= g_mnodeList && pMemNode <= g_mnodeList + NUM_MNODES - 1);
// object must be in use and locked
assert((pMemNode->flags & (DWM_USED | DWM_LOCKED)) == DWM_USED);
@@ -351,7 +351,7 @@ void MemoryDiscard(MEM_NODE *pMemNode) {
if ((pMemNode->flags & DWM_DISCARDED) == 0) {
// free memory
free(pMemNode->pBaseAddr);
- heapSentinel.size += pMemNode->size;
+ g_heapSentinel.size += pMemNode->size;
#ifdef DEBUG
MemoryStats();
@@ -416,7 +416,7 @@ void MemoryReAlloc(MEM_NODE *pMemNode, long size) {
MEM_NODE *pNew;
// validate mnode pointer
- assert(pMemNode >= mnodeList && pMemNode <= mnodeList + NUM_MNODES - 1);
+ assert(pMemNode >= g_mnodeList && pMemNode <= g_mnodeList + NUM_MNODES - 1);
// align the size to machine boundary requirements
size = (size + sizeof(void *) - 1) & ~(sizeof(void *) - 1);
diff --git a/engines/tinsel/mareels.cpp b/engines/tinsel/mareels.cpp
index bd267a2c65..7dd905d0f2 100644
--- a/engines/tinsel/mareels.cpp
+++ b/engines/tinsel/mareels.cpp
@@ -48,9 +48,9 @@ struct SCIdataStruct {
// FIXME: Avoid non-const global vars
-static SCIdataStruct SCIdata[MAX_SCRENTRIES];
+static SCIdataStruct g_SCIdata[MAX_SCRENTRIES];
-static int scrEntries = 0;
+static int g_scrEntries = 0;
/**
* Sets an actor's walk reels
@@ -131,16 +131,16 @@ void SetScalingReels(int actor, int scale, int direction,
assert(!(scale == 1 && direction == D_UP) &&
!(scale == NUM_MAINSCALES && direction == D_DOWN)); // illegal direction from scale
- assert(scrEntries < MAX_SCRENTRIES); // Scaling reels limit reached!
+ assert(g_scrEntries < MAX_SCRENTRIES); // Scaling reels limit reached!
- SCIdata[scrEntries].actor = actor;
- SCIdata[scrEntries].scale = scale;
- SCIdata[scrEntries].direction = direction;
- SCIdata[scrEntries].reels[LEFTREEL] = left;
- SCIdata[scrEntries].reels[RIGHTREEL] = right;
- SCIdata[scrEntries].reels[FORWARD] = forward;
- SCIdata[scrEntries].reels[AWAY] = away;
- scrEntries++;
+ g_SCIdata[g_scrEntries].actor = actor;
+ g_SCIdata[g_scrEntries].scale = scale;
+ g_SCIdata[g_scrEntries].direction = direction;
+ g_SCIdata[g_scrEntries].reels[LEFTREEL] = left;
+ g_SCIdata[g_scrEntries].reels[RIGHTREEL] = right;
+ g_SCIdata[g_scrEntries].reels[FORWARD] = forward;
+ g_SCIdata[g_scrEntries].reels[AWAY] = away;
+ g_scrEntries++;
}
/**
@@ -155,12 +155,12 @@ SCNHANDLE ScalingReel(int ano, int scale1, int scale2, DIRECTION reel) {
else
d = D_UP;
- for (int i = 0; i < scrEntries; i++) {
- if (SCIdata[i].actor == ano && SCIdata[i].scale == scale1 && SCIdata[i].direction == d) {
- if (SCIdata[i].reels[reel] == TF_NONE)
+ for (int i = 0; i < g_scrEntries; i++) {
+ if (g_SCIdata[i].actor == ano && g_SCIdata[i].scale == scale1 && g_SCIdata[i].direction == d) {
+ if (g_SCIdata[i].reels[reel] == TF_NONE)
return 0;
else
- return SCIdata[i].reels[reel];
+ return g_SCIdata[i].reels[reel];
}
}
return 0;
@@ -170,8 +170,8 @@ SCNHANDLE ScalingReel(int ano, int scale1, int scale2, DIRECTION reel) {
* RebootScalingReels
*/
void RebootScalingReels() {
- scrEntries = 0;
- memset(SCIdata, 0, sizeof(SCIdata));
+ g_scrEntries = 0;
+ memset(g_SCIdata, 0, sizeof(g_SCIdata));
}
/**
diff --git a/engines/tinsel/move.cpp b/engines/tinsel/move.cpp
index e20f28d528..bb49e59fe7 100644
--- a/engines/tinsel/move.cpp
+++ b/engines/tinsel/move.cpp
@@ -77,14 +77,14 @@ HPOLYGON InitExtraBlock(PMOVER ca, PMOVER ta);
// FIXME: Avoid non-const global vars
#if SLOW_RINCE_DOWN
-static int Interlude = 0; // For slowing down walking, for testing
-static int BogusVar = 0; // For slowing down walking, for testing
+static int g_Interlude = 0; // For slowing down walking, for testing
+static int g_BogusVar = 0; // For slowing down walking, for testing
#endif
-static int32 DefaultRefer = 0;
-static int lastLeadXdest = 0, lastLeadYdest = 0;
+static int32 g_DefaultRefer = 0;
+static int g_lastLeadXdest = 0, g_lastLeadYdest = 0;
-static int hSlowVar = 0; // used by MoveActor()
+static int g_hSlowVar = 0; // used by MoveActor()
//----------------- FORWARD REFERENCES --------------------
@@ -101,9 +101,9 @@ static void NewCoOrdinates(int fromx, int fromy, int *targetX, int *targetY,
*/
void AddInterlude(int n) {
- Interlude += n;
- if (Interlude < 0)
- Interlude = 0;
+ g_Interlude += n;
+ if (g_Interlude < 0)
+ g_Interlude = 0;
}
#endif
@@ -251,7 +251,7 @@ static int ClickedOnNothing(int clickX, int clickY, int *ptgtX, int *ptgtY) {
PlayfieldGetPos(FIELD_WORLD, &Loffset, &Toffset);
- switch (DefaultRefer) {
+ switch (g_DefaultRefer) {
case REF_DEFAULT:
// Try searching down and up (onscreen).
for (i = clickY+1; i < SCREEN_HEIGHT+Toffset; i++)
@@ -1353,15 +1353,15 @@ int SetActorDest(PMOVER pMover, int clickX, int clickY, bool igPath, SCNHANDLE h
targetY = clickY;
if (pMover->actorID == GetLeadId()) {
- lastLeadXdest = targetX;
- lastLeadYdest = targetY;
+ g_lastLeadXdest = targetX;
+ g_lastLeadYdest = targetY;
}
} else {
int wodResult = WorkOutDestination(clickX, clickY, &targetX, &targetY);
if (pMover->actorID == GetLeadId()) {
- lastLeadXdest = targetX;
- lastLeadYdest = targetY;
+ g_lastLeadXdest = targetX;
+ g_lastLeadYdest = targetY;
}
if (wodResult == ALL_SORTED) {
@@ -1613,17 +1613,17 @@ void MoveActor(PMOVER pMover) {
}
#if SLOW_RINCE_DOWN
-/**/ if (BogusVar++ < Interlude) // Temporary slow-down-the-action code
+/**/ if (g_BogusVar++ < g_Interlude) // Temporary slow-down-the-action code
/**/ return; //
-/**/ BogusVar = 0; //
+/**/ g_BogusVar = 0; //
#endif
if (!TinselV2) {
// During swalk()s, movement while hidden may be slowed down.
if (pMover->bHidden) {
- if (++hSlowVar < pMover->SlowFactor)
+ if (++g_hSlowVar < pMover->SlowFactor)
return;
- hSlowVar = 0;
+ g_hSlowVar = 0;
}
}
@@ -1705,15 +1705,15 @@ void MoveActor(PMOVER pMover) {
* Store the default refer type for the current scene.
*/
void SetDefaultRefer(int32 defRefer) {
- DefaultRefer = defRefer;
+ g_DefaultRefer = defRefer;
}
int GetLastLeadXdest() {
- return lastLeadXdest;
+ return g_lastLeadXdest;
}
int GetLastLeadYdest() {
- return lastLeadYdest;
+ return g_lastLeadYdest;
}
diff --git a/engines/tinsel/music.cpp b/engines/tinsel/music.cpp
index d6478f5cae..781a378f13 100644
--- a/engines/tinsel/music.cpp
+++ b/engines/tinsel/music.cpp
@@ -64,13 +64,13 @@ struct SOUND_BUFFER {
// FIXME: Avoid non-const global vars
// MIDI buffer
-static SOUND_BUFFER midiBuffer = { 0, 0 };
+static SOUND_BUFFER g_midiBuffer = { 0, 0 };
-static SCNHANDLE currentMidi = 0;
-static bool currentLoop = false;
+static SCNHANDLE g_currentMidi = 0;
+static bool g_currentLoop = false;
// We allocate 155 entries because that's the maximum, used in the SCN version
-static SCNHANDLE midiOffsets[155];
+static SCNHANDLE g_midiOffsets[155];
static const int enhancedAudioGRAVersion[] = {
1, 2, 1, 1, 3, 3, 4, 4, 5, 6, // 1-10
@@ -110,16 +110,16 @@ static const int enhancedAudioSCNVersion[] = {
};
int GetTrackNumber(SCNHANDLE hMidi) {
- for (int i = 0; i < ARRAYSIZE(midiOffsets); i++)
- if (midiOffsets[i] == hMidi)
+ for (int i = 0; i < ARRAYSIZE(g_midiOffsets); i++)
+ if (g_midiOffsets[i] == hMidi)
return i;
return -1;
}
SCNHANDLE GetTrackOffset(int trackNumber) {
- assert(trackNumber < ARRAYSIZE(midiOffsets));
- return midiOffsets[trackNumber];
+ assert(trackNumber < ARRAYSIZE(g_midiOffsets));
+ return g_midiOffsets[trackNumber];
}
/**
@@ -128,8 +128,8 @@ SCNHANDLE GetTrackOffset(int trackNumber) {
* @param bLoop Whether to loop the sequence
*/
bool PlayMidiSequence(uint32 dwFileOffset, bool bLoop) {
- currentMidi = dwFileOffset;
- currentLoop = bLoop;
+ g_currentMidi = dwFileOffset;
+ g_currentLoop = bLoop;
// Tinsel V1 PSX uses a different music format, so i
// disable it here.
@@ -166,8 +166,8 @@ bool PlayMidiSequence(uint32 dwFileOffset, bool bLoop) {
StopMidi();
// StopMidi resets these fields, so set them again
- currentMidi = dwFileOffset;
- currentLoop = bLoop;
+ g_currentMidi = dwFileOffset;
+ g_currentLoop = bLoop;
// try to play track, but don't fall back to a true CD
g_system->getAudioCDManager()->play(track, bLoop ? -1 : 1, 0, 0, true);
@@ -203,13 +203,13 @@ bool PlayMidiSequence(uint32 dwFileOffset, bool bLoop) {
dwSeqLen = midiStream.readUint32LE();
// make sure buffer is large enough for this sequence
- assert(dwSeqLen > 0 && dwSeqLen <= midiBuffer.size);
+ assert(dwSeqLen > 0 && dwSeqLen <= g_midiBuffer.size);
// stop any currently playing tune
_vm->_midiMusic->stop();
// read the sequence
- if (midiStream.read(midiBuffer.pDat, dwSeqLen) != dwSeqLen)
+ if (midiStream.read(g_midiBuffer.pDat, dwSeqLen) != dwSeqLen)
error(FILE_IS_CORRUPT, MIDI_FILE);
midiStream.close();
@@ -231,14 +231,14 @@ bool PlayMidiSequence(uint32 dwFileOffset, bool bLoop) {
_vm->_midiMusic->send(0x7F07B0 | 13);
}
- _vm->_midiMusic->playXMIDI(midiBuffer.pDat, dwSeqLen, bLoop);
+ _vm->_midiMusic->playXMIDI(g_midiBuffer.pDat, dwSeqLen, bLoop);
// Store the length
//dwLastSeqLen = dwSeqLen;
} else {
// dwFileOffset == dwLastMidiIndex
_vm->_midiMusic->stop();
- _vm->_midiMusic->playXMIDI(midiBuffer.pDat, dwSeqLen, bLoop);
+ _vm->_midiMusic->playXMIDI(g_midiBuffer.pDat, dwSeqLen, bLoop);
}
return true;
@@ -259,8 +259,8 @@ bool MidiPlaying() {
* Stops any currently playing midi.
*/
bool StopMidi() {
- currentMidi = 0;
- currentLoop = false;
+ g_currentMidi = 0;
+ g_currentLoop = false;
if (_vm->getFeatures() & GF_ENHANCED_AUDIO_SUPPORT) {
g_system->getAudioCDManager()->stop();
@@ -295,8 +295,8 @@ void SetMidiVolume(int vol) {
_vm->_midiMusic->setVolume(vol);
} else if (vol != 0 && priorVolMusic == 0) {
// Perhaps restart last midi sequence
- if (currentLoop)
- PlayMidiSequence(currentMidi, true);
+ if (g_currentLoop)
+ PlayMidiSequence(g_currentMidi, true);
_vm->_midiMusic->setVolume(vol);
} else if (vol != 0 && priorVolMusic != 0) {
@@ -318,7 +318,7 @@ void OpenMidiFiles() {
if ((_vm->getFeatures() & GF_DEMO) || (TinselVersion == TINSEL_V2) || TinselV1PSX)
return;
- if (midiBuffer.pDat)
+ if (g_midiBuffer.pDat)
// already allocated
return;
@@ -327,15 +327,15 @@ void OpenMidiFiles() {
error(CANNOT_FIND_FILE, MIDI_FILE);
// gen length of the largest sequence
- midiBuffer.size = midiStream.readUint32LE();
+ g_midiBuffer.size = midiStream.readUint32LE();
if (midiStream.eos() || midiStream.err())
error(FILE_IS_CORRUPT, MIDI_FILE);
- if (midiBuffer.size) {
+ if (g_midiBuffer.size) {
// allocate a buffer big enough for the largest MIDI sequence
- if ((midiBuffer.pDat = (uint8 *)malloc(midiBuffer.size)) != NULL) {
+ if ((g_midiBuffer.pDat = (uint8 *)malloc(g_midiBuffer.size)) != NULL) {
// clear out the buffer
- memset(midiBuffer.pDat, 0, midiBuffer.size);
+ memset(g_midiBuffer.pDat, 0, g_midiBuffer.size);
// VMM_lock(midiBuffer.pDat, midiBuffer.size);
} else {
//mSeqHandle = NULL;
@@ -352,15 +352,15 @@ void OpenMidiFiles() {
uint32 songLength = 0;
// Init
- for (int i = 0; i < ARRAYSIZE(midiOffsets); i++)
- midiOffsets[i] = 0;
+ for (int i = 0; i < ARRAYSIZE(g_midiOffsets); i++)
+ g_midiOffsets[i] = 0;
while (!midiStream.eos() && !midiStream.err()) {
if (curOffset + (4 * curTrack) >= (uint32)midiStream.size())
break;
- assert(curTrack < ARRAYSIZE(midiOffsets));
- midiOffsets[curTrack] = curOffset + (4 * curTrack);
+ assert(curTrack < ARRAYSIZE(g_midiOffsets));
+ g_midiOffsets[curTrack] = curOffset + (4 * curTrack);
//debug("%d: %d", curTrack, midiOffsets[curTrack]);
songLength = midiStream.readUint32LE();
@@ -374,8 +374,8 @@ void OpenMidiFiles() {
}
void DeleteMidiBuffer() {
- free(midiBuffer.pDat);
- midiBuffer.pDat = NULL;
+ free(g_midiBuffer.pDat);
+ g_midiBuffer.pDat = NULL;
}
MidiMusicPlayer::MidiMusicPlayer() {
@@ -485,6 +485,7 @@ PCMMusicPlayer::PCMMusicPlayer() {
PCMMusicPlayer::~PCMMusicPlayer() {
_vm->_mixer->stopHandle(_handle);
+ delete _curChunk;
}
void PCMMusicPlayer::startPlay(int id) {
@@ -859,22 +860,22 @@ void PCMMusicPlayer::stop() {
}
void CurrentMidiFacts(SCNHANDLE *pMidi, bool *pLoop) {
- *pMidi = currentMidi;
- *pLoop = currentLoop;
+ *pMidi = g_currentMidi;
+ *pLoop = g_currentLoop;
}
void RestoreMidiFacts(SCNHANDLE Midi, bool Loop) {
StopMidi();
- currentMidi = Midi;
- currentLoop = Loop;
+ g_currentMidi = Midi;
+ g_currentLoop = Loop;
if (_vm->_config->_musicVolume != 0 && Loop) {
bool mute = false;
if (ConfMan.hasKey("mute"))
mute = ConfMan.getBool("mute");
- PlayMidiSequence(currentMidi, true);
+ PlayMidiSequence(g_currentMidi, true);
SetMidiVolume(mute ? 0 : _vm->_config->_musicVolume);
}
}
diff --git a/engines/tinsel/palette.cpp b/engines/tinsel/palette.cpp
index f2437bd17e..e6c9467fab 100644
--- a/engines/tinsel/palette.cpp
+++ b/engines/tinsel/palette.cpp
@@ -54,33 +54,33 @@ struct VIDEO_DAC_Q {
// FIXME: Avoid non-const global vars
/** palette allocator data */
-static PALQ palAllocData[NUM_PALETTES];
+static PALQ g_palAllocData[NUM_PALETTES];
/** video DAC transfer Q length */
#define VDACQLENGTH (NUM_PALETTES+2)
/** video DAC transfer Q */
-static VIDEO_DAC_Q vidDACdata[VDACQLENGTH];
+static VIDEO_DAC_Q g_vidDACdata[VDACQLENGTH];
/** video DAC transfer Q head pointer */
-static VIDEO_DAC_Q *pDAChead;
+static VIDEO_DAC_Q *g_pDAChead;
/** color index of the 4 colors used for the translucent palette */
#define COL_HILIGHT TBLUE1
/** the translucent palette lookup table */
-uint8 transPalette[MAX_COLORS]; // used in graphics.cpp
+uint8 g_transPalette[MAX_COLORS]; // used in graphics.cpp
-uint8 ghostPalette[MAX_COLORS];
+uint8 g_ghostPalette[MAX_COLORS];
-static int translucentIndex = 228;
+static int g_translucentIndex = 228;
-static int talkIndex = 233;
+static int g_talkIndex = 233;
-static COLORREF talkColRef;
+static COLORREF g_talkColRef;
-static COLORREF tagColRef;
+static COLORREF g_tagColRef;
#ifdef DEBUG
@@ -131,11 +131,11 @@ void psxPaletteMapper(PALQ *originalPal, uint8 *psxClut, byte *mapperTable) {
*/
void PalettesToVideoDAC() {
PALQ *pPalQ; // palette Q iterator
- VIDEO_DAC_Q *pDACtail = vidDACdata; // set tail pointer
+ VIDEO_DAC_Q *pDACtail = g_vidDACdata; // set tail pointer
byte pal[768];
// while Q is not empty
- while (pDAChead != pDACtail) {
+ while (g_pDAChead != pDACtail) {
const PALETTE *pPalette; // pointer to hardware palette
const COLORREF *pColors; // pointer to list of RGB triples
@@ -179,10 +179,10 @@ void PalettesToVideoDAC() {
}
// reset video DAC transfer Q head pointer
- pDAChead = vidDACdata;
+ g_pDAChead = g_vidDACdata;
// clear all palette moved bits
- for (pPalQ = palAllocData; pPalQ < palAllocData + NUM_PALETTES; pPalQ++)
+ for (pPalQ = g_palAllocData; pPalQ < g_palAllocData + NUM_PALETTES; pPalQ++)
pPalQ->posInDAC &= ~PALETTE_MOVED;
}
@@ -196,10 +196,10 @@ void ResetPalAllocator() {
#endif
// wipe out the palette allocator data
- memset(palAllocData, 0, sizeof(palAllocData));
+ memset(g_palAllocData, 0, sizeof(g_palAllocData));
// reset video DAC transfer Q head pointer
- pDAChead = vidDACdata;
+ g_pDAChead = g_vidDACdata;
}
#ifdef DEBUG
@@ -220,19 +220,19 @@ void PaletteStats() {
*/
void UpdateDACqueueHandle(int posInDAC, int numColors, SCNHANDLE hPalette) {
// check Q overflow
- assert(pDAChead < vidDACdata + VDACQLENGTH);
+ assert(g_pDAChead < g_vidDACdata + VDACQLENGTH);
- pDAChead->destDACindex = posInDAC & ~PALETTE_MOVED; // set index in video DAC
- pDAChead->numColors = numColors; // set number of colors
- pDAChead->pal.hRGBarray = hPalette; // set handle of palette
- pDAChead->bHandle = true; // we are using a palette handle
+ g_pDAChead->destDACindex = posInDAC & ~PALETTE_MOVED; // set index in video DAC
+ g_pDAChead->numColors = numColors; // set number of colors
+ g_pDAChead->pal.hRGBarray = hPalette; // set handle of palette
+ g_pDAChead->bHandle = true; // we are using a palette handle
// update head pointer
- ++pDAChead;
+ ++g_pDAChead;
#ifdef DEBUG
- if ((pDAChead-vidDACdata) > maxDACQ)
- maxDACQ = pDAChead-vidDACdata;
+ if ((g_pDAChead-g_vidDACdata) > maxDACQ)
+ maxDACQ = g_pDAChead-g_vidDACdata;
#endif
}
@@ -244,22 +244,22 @@ void UpdateDACqueueHandle(int posInDAC, int numColors, SCNHANDLE hPalette) {
*/
void UpdateDACqueue(int posInDAC, int numColors, COLORREF *pColors) {
// check Q overflow
- assert(pDAChead < vidDACdata + NUM_PALETTES);
+ assert(g_pDAChead < g_vidDACdata + NUM_PALETTES);
- pDAChead->destDACindex = posInDAC & ~PALETTE_MOVED; // set index in video DAC
- pDAChead->numColors = numColors; // set number of colors
+ g_pDAChead->destDACindex = posInDAC & ~PALETTE_MOVED; // set index in video DAC
+ g_pDAChead->numColors = numColors; // set number of colors
if (numColors == 1)
- pDAChead->pal.singleRGB = *pColors; // set single color of which the "palette" consists
+ g_pDAChead->pal.singleRGB = *pColors; // set single color of which the "palette" consists
else
- pDAChead->pal.pRGBarray = pColors; // set addr of palette
- pDAChead->bHandle = false; // we are not using a palette handle
+ g_pDAChead->pal.pRGBarray = pColors; // set addr of palette
+ g_pDAChead->bHandle = false; // we are not using a palette handle
// update head pointer
- ++pDAChead;
+ ++g_pDAChead;
#ifdef DEBUG
- if ((pDAChead-vidDACdata) > maxDACQ)
- maxDACQ = pDAChead-vidDACdata;
+ if ((g_pDAChead-g_vidDACdata) > maxDACQ)
+ maxDACQ = g_pDAChead-g_vidDACdata;
#endif
}
@@ -271,19 +271,19 @@ void UpdateDACqueue(int posInDAC, int numColors, COLORREF *pColors) {
*/
void UpdateDACqueue(int posInDAC, COLORREF color) {
// check Q overflow
- assert(pDAChead < vidDACdata + NUM_PALETTES);
+ assert(g_pDAChead < g_vidDACdata + NUM_PALETTES);
- pDAChead->destDACindex = posInDAC & ~PALETTE_MOVED; // set index in video DAC
- pDAChead->numColors = 1; // set number of colors
- pDAChead->pal.singleRGB = color; // set single color of which the "palette" consists
- pDAChead->bHandle = false; // we are not using a palette handle
+ g_pDAChead->destDACindex = posInDAC & ~PALETTE_MOVED; // set index in video DAC
+ g_pDAChead->numColors = 1; // set number of colors
+ g_pDAChead->pal.singleRGB = color; // set single color of which the "palette" consists
+ g_pDAChead->bHandle = false; // we are not using a palette handle
// update head pointer
- ++pDAChead;
+ ++g_pDAChead;
#ifdef DEBUG
- if ((pDAChead-vidDACdata) > maxDACQ)
- maxDACQ = pDAChead-vidDACdata;
+ if ((g_pDAChead-g_vidDACdata) > maxDACQ)
+ maxDACQ = g_pDAChead-g_vidDACdata;
#endif
}
@@ -301,7 +301,7 @@ PALQ *AllocPalette(SCNHANDLE hNewPal) {
pNewPal = (PALETTE *)LockMem(hNewPal);
// search all structs in palette allocator - see if palette already allocated
- for (p = palAllocData; p < palAllocData + NUM_PALETTES; p++) {
+ for (p = g_palAllocData; p < g_palAllocData + NUM_PALETTES; p++) {
if (p->hPal == hNewPal) {
// found the desired palette in palette allocator
p->objCount++; // update number of objects using palette
@@ -312,7 +312,7 @@ PALQ *AllocPalette(SCNHANDLE hNewPal) {
// search all structs in palette allocator - find a free slot
iDAC = FGND_DAC_INDEX; // init DAC index to first available foreground color
- for (p = palAllocData; p < palAllocData + NUM_PALETTES; p++) {
+ for (p = g_palAllocData; p < g_palAllocData + NUM_PALETTES; p++) {
if (p->hPal == 0) {
// found a free slot in palette allocator
p->objCount = 1; // init number of objects using palette
@@ -337,7 +337,7 @@ PALQ *AllocPalette(SCNHANDLE hNewPal) {
UpdateDACqueueHandle(p->posInDAC, p->numColors, p->hPal);
// move all palettes after this one down (if necessary)
- for (pPrev = p, pNxtPal = pPrev + 1; pNxtPal < palAllocData + NUM_PALETTES; pNxtPal++) {
+ for (pPrev = p, pNxtPal = pPrev + 1; pNxtPal < g_palAllocData + NUM_PALETTES; pNxtPal++) {
if (pNxtPal->hPal != 0) {
// palette slot is in use
if (pNxtPal->posInDAC >= pPrev->posInDAC + pPrev->numColors)
@@ -381,7 +381,7 @@ PALQ *AllocPalette(SCNHANDLE hNewPal) {
*/
void FreePalette(PALQ *pFreePal) {
// validate palette Q pointer
- assert(pFreePal >= palAllocData && pFreePal <= palAllocData + NUM_PALETTES - 1);
+ assert(pFreePal >= g_palAllocData && pFreePal <= g_palAllocData + NUM_PALETTES - 1);
// reduce the palettes object reference count
pFreePal->objCount--;
@@ -408,7 +408,7 @@ PALQ *FindPalette(SCNHANDLE hSrchPal) {
PALQ *pPal; // palette allocator iterator
// search all structs in palette allocator
- for (pPal = palAllocData; pPal < palAllocData + NUM_PALETTES; pPal++) {
+ for (pPal = g_palAllocData; pPal < g_palAllocData + NUM_PALETTES; pPal++) {
if (pPal->hPal == hSrchPal)
// found palette in palette allocator
return pPal;
@@ -428,7 +428,7 @@ void SwapPalette(PALQ *pPalQ, SCNHANDLE hNewPal) {
PALETTE *pNewPal = (PALETTE *)LockMem(hNewPal);
// validate palette Q pointer
- assert(pPalQ >= palAllocData && pPalQ <= palAllocData + NUM_PALETTES - 1);
+ assert(pPalQ >= g_palAllocData && pPalQ <= g_palAllocData + NUM_PALETTES - 1);
if (pPalQ->numColors >= (int)FROM_LE_32(pNewPal->numColors)) {
// new palette will fit the slot
@@ -455,7 +455,7 @@ void SwapPalette(PALQ *pPalQ, SCNHANDLE hNewPal) {
PALQ *pNxtPalQ; // next palette queue position
- for (pNxtPalQ = pPalQ + 1; pNxtPalQ < palAllocData + NUM_PALETTES; pNxtPalQ++) {
+ for (pNxtPalQ = pPalQ + 1; pNxtPalQ < g_palAllocData + NUM_PALETTES; pNxtPalQ++) {
if (pNxtPalQ->posInDAC >= pPalQ->posInDAC + pPalQ->numColors)
// no need to move palettes down
break;
@@ -482,14 +482,14 @@ void SwapPalette(PALQ *pPalQ, SCNHANDLE hNewPal) {
PALQ *GetNextPalette(PALQ *pStrtPal) {
if (pStrtPal == NULL) {
// start of palette iteration - return 1st palette
- return (palAllocData[0].objCount) ? palAllocData : NULL;
+ return (g_palAllocData[0].objCount) ? g_palAllocData : NULL;
}
// validate palette Q pointer
- assert(pStrtPal >= palAllocData && pStrtPal <= palAllocData + NUM_PALETTES - 1);
+ assert(pStrtPal >= g_palAllocData && pStrtPal <= g_palAllocData + NUM_PALETTES - 1);
// return next active palette in list
- while (++pStrtPal < palAllocData + NUM_PALETTES) {
+ while (++pStrtPal < g_palAllocData + NUM_PALETTES) {
if (pStrtPal->objCount)
// active palette found
return pStrtPal;
@@ -515,7 +515,7 @@ void SetBgndColor(COLORREF color) {
*/
void FadingPalette(PALQ *pPalQ, bool bFading) {
// validate palette Q pointer
- assert(pPalQ >= palAllocData && pPalQ <= palAllocData + NUM_PALETTES - 1);
+ assert(pPalQ >= g_palAllocData && pPalQ <= g_palAllocData + NUM_PALETTES - 1);
// validate that this is a change
assert(pPalQ->bFading != bFading);
@@ -530,7 +530,7 @@ void FadingPalette(PALQ *pPalQ, bool bFading) {
void NoFadingPalettes() {
PALQ *pPalQ;
- for (pPalQ = palAllocData; pPalQ <= palAllocData + NUM_PALETTES - 1; pPalQ++) {
+ for (pPalQ = g_palAllocData; pPalQ <= g_palAllocData + NUM_PALETTES - 1; pPalQ++) {
pPalQ->bFading = false;
}
}
@@ -544,7 +544,7 @@ void CreateTranslucentPalette(SCNHANDLE hPalette) {
PALETTE *pPal = (PALETTE *)LockMem(hPalette);
// leave background color alone
- transPalette[0] = 0;
+ g_transPalette[0] = 0;
for (uint i = 0; i < FROM_LE_32(pPal->numColors); i++) {
// get the RGB color model values
@@ -558,7 +558,7 @@ void CreateTranslucentPalette(SCNHANDLE hPalette) {
// map the Value field to one of the 4 colors reserved for the translucent palette
val /= 63;
- transPalette[i + 1] = (uint8)((val == 0) ? 0 : val +
+ g_transPalette[i + 1] = (uint8)((val == 0) ? 0 : val +
(TinselV2 ? TranslucentColor() : COL_HILIGHT) - 1);
}
}
@@ -572,7 +572,7 @@ void CreateGhostPalette(SCNHANDLE hPalette) {
int i;
// leave background color alone
- ghostPalette[0] = 0;
+ g_ghostPalette[0] = 0;
for (i = 0; i < (int)FROM_LE_32(pPal->numColors); i++) {
// get the RGB color model values
@@ -587,7 +587,7 @@ void CreateGhostPalette(SCNHANDLE hPalette) {
// map the Value field to one of the 4 colors reserved for the translucent palette
val /= 64;
assert(/*val >= 0 &&*/ val <= 3);
- ghostPalette[i + 1] = (uint8)(val + SysVar(ISV_GHOST_BASE));
+ g_ghostPalette[i + 1] = (uint8)(val + SysVar(ISV_GHOST_BASE));
}
}
@@ -648,41 +648,41 @@ void DimPartPalette(SCNHANDLE hDimPal, int startColor, int length, int brightnes
}
int TranslucentColor() {
- return translucentIndex;
+ return g_translucentIndex;
}
int HighlightColor() {
- UpdateDACqueue(talkIndex, (COLORREF)SysVar(SYS_HighlightRGB));
+ UpdateDACqueue(g_talkIndex, (COLORREF)SysVar(SYS_HighlightRGB));
- return talkIndex;
+ return g_talkIndex;
}
int TalkColor() {
- return TinselV2 ? talkIndex : TALKFONT_COL;
+ return TinselV2 ? g_talkIndex : TALKFONT_COL;
}
void SetTalkColorRef(COLORREF colRef) {
- talkColRef = colRef;
+ g_talkColRef = colRef;
}
COLORREF GetTalkColorRef() {
- return talkColRef;
+ return g_talkColRef;
}
void SetTagColorRef(COLORREF colRef) {
- tagColRef = colRef;
+ g_tagColRef = colRef;
}
COLORREF GetTagColorRef() {
- return tagColRef;
+ return g_tagColRef;
}
void SetTranslucencyOffset(int offset) {
- translucentIndex = offset;
+ g_translucentIndex = offset;
}
void SetTalkTextOffset(int offset) {
- talkIndex = offset;
+ g_talkIndex = offset;
}
} // End of namespace Tinsel
diff --git a/engines/tinsel/pcode.cpp b/engines/tinsel/pcode.cpp
index 2ab1e653d4..145a6a8e5d 100644
--- a/engines/tinsel/pcode.cpp
+++ b/engines/tinsel/pcode.cpp
@@ -100,19 +100,19 @@ enum OPCODE {
#define OPMASK 0x3F ///< mask to isolate the opcode
-bool bNoPause = false;
+bool g_bNoPause = false;
//----------------- LOCAL GLOBAL DATA --------------------
// FIXME: Avoid non-const global vars
-static int32 *pGlobals = 0; // global vars
+static int32 *g_pGlobals = 0; // global vars
-static int numGlobals = 0; // How many global variables to save/restore
+static int g_numGlobals = 0; // How many global variables to save/restore
-static INT_CONTEXT *icList = 0;
+static INT_CONTEXT *g_icList = 0;
-static uint32 hMasterScript;
+static uint32 g_hMasterScript;
//----------------- SCRIPT BUGS WORKAROUNDS --------------
@@ -227,7 +227,7 @@ void LockCode(INT_CONTEXT *ic) {
if (ic->GSort == GS_MASTER) {
if (TinselV2)
// Get the srcipt handle from a specific global chunk
- ic->code = (byte *)LockMem(hMasterScript);
+ ic->code = (byte *)LockMem(g_hMasterScript);
else
ic->code = (byte *)FindChunk(MASTER_SCNHANDLE, CHUNK_PCODE);
} else
@@ -241,7 +241,7 @@ static INT_CONTEXT *AllocateInterpretContext(GSORT gsort) {
INT_CONTEXT *pic;
int i;
- for (i = 0, pic = icList; i < NUM_INTERPRET; i++, pic++) {
+ for (i = 0, pic = g_icList; i < NUM_INTERPRET; i++, pic++) {
if (pic->GSort == GS_NONE) {
pic->pProc = g_scheduler->getCurrentProcess();
pic->GSort = gsort;
@@ -264,8 +264,8 @@ static void FreeWaitCheck(PINT_CONTEXT pic, bool bVoluntary) {
// Is this waiting for something?
if (pic->waitNumber1) {
for (i = 0; i < NUM_INTERPRET; i++) {
- if ((icList + i)->waitNumber2 == pic->waitNumber1) {
- (icList + i)->waitNumber2 = 0;
+ if ((g_icList + i)->waitNumber2 == pic->waitNumber1) {
+ (g_icList + i)->waitNumber2 = 0;
break;
}
}
@@ -274,10 +274,10 @@ static void FreeWaitCheck(PINT_CONTEXT pic, bool bVoluntary) {
// Is someone waiting for this?
if (pic->waitNumber2) {
for (i = 0; i < NUM_INTERPRET; i++) {
- if ((icList + i)->waitNumber1 == pic->waitNumber2) {
- (icList + i)->waitNumber1 = 0;
- (icList + i)->resumeCode = bVoluntary ? RES_FINISHED : RES_CUTSHORT;
- g_scheduler->reschedule((icList + i)->pProc);
+ if ((g_icList + i)->waitNumber1 == pic->waitNumber2) {
+ (g_icList + i)->waitNumber1 = 0;
+ (g_icList + i)->resumeCode = bVoluntary ? RES_FINISHED : RES_CUTSHORT;
+ g_scheduler->reschedule((g_icList + i)->pProc);
break;
}
}
@@ -305,7 +305,7 @@ void FreeInterpretContextPr(PROCESS *pProc) {
INT_CONTEXT *pic;
int i;
- for (i = 0, pic = icList; i < NUM_INTERPRET; i++, pic++) {
+ for (i = 0, pic = g_icList; i < NUM_INTERPRET; i++, pic++) {
if (pic->GSort != GS_NONE && pic->pProc == pProc) {
FreeWaitCheck(pic, false);
if (TinselV2)
@@ -323,7 +323,7 @@ void FreeMostInterpretContexts() {
INT_CONTEXT *pic;
int i;
- for (i = 0, pic = icList; i < NUM_INTERPRET; i++, pic++) {
+ for (i = 0, pic = g_icList; i < NUM_INTERPRET; i++, pic++) {
if ((pic->GSort != GS_MASTER) && (pic->GSort != GS_GPROCESS)) {
memset(pic, 0, sizeof(INT_CONTEXT));
pic->GSort = GS_NONE;
@@ -338,7 +338,7 @@ void FreeMasterInterpretContext() {
INT_CONTEXT *pic;
int i;
- for (i = 0, pic = icList; i < NUM_INTERPRET; i++, pic++) {
+ for (i = 0, pic = g_icList; i < NUM_INTERPRET; i++, pic++) {
if ((pic->GSort == GS_MASTER) || (pic->GSort == GS_GPROCESS)) {
memset(pic, 0, sizeof(INT_CONTEXT));
pic->GSort = GS_NONE;
@@ -405,30 +405,30 @@ INT_CONTEXT *RestoreInterpretContext(INT_CONTEXT *ric) {
* Allocates enough RAM to hold the global Glitter variables.
*/
void RegisterGlobals(int num) {
- if (pGlobals == NULL) {
- numGlobals = num;
+ if (g_pGlobals == NULL) {
+ g_numGlobals = num;
- hMasterScript = !TinselV2 ? 0 :
+ g_hMasterScript = !TinselV2 ? 0 :
READ_LE_UINT32(FindChunk(MASTER_SCNHANDLE, CHUNK_MASTER_SCRIPT));
// Allocate RAM for pGlobals and make sure it's allocated
- pGlobals = (int32 *)calloc(numGlobals, sizeof(int32));
- if (pGlobals == NULL) {
+ g_pGlobals = (int32 *)calloc(g_numGlobals, sizeof(int32));
+ if (g_pGlobals == NULL) {
error("Cannot allocate memory for global data");
}
// Allocate RAM for interpret contexts and make sure it's allocated
- icList = (INT_CONTEXT *)calloc(NUM_INTERPRET, sizeof(INT_CONTEXT));
- if (icList == NULL) {
+ g_icList = (INT_CONTEXT *)calloc(NUM_INTERPRET, sizeof(INT_CONTEXT));
+ if (g_icList == NULL) {
error("Cannot allocate memory for interpret contexts");
}
g_scheduler->setResourceCallback(FreeInterpretContextPr);
} else {
// Check size is still the same
- assert(numGlobals == num);
+ assert(g_numGlobals == num);
- memset(pGlobals, 0, numGlobals * sizeof(int32));
- memset(icList, 0, NUM_INTERPRET * sizeof(INT_CONTEXT));
+ memset(g_pGlobals, 0, g_numGlobals * sizeof(int32));
+ memset(g_icList, 0, NUM_INTERPRET * sizeof(INT_CONTEXT));
}
if (TinselV2) {
@@ -444,7 +444,7 @@ void RegisterGlobals(int num) {
error(FILE_IS_CORRUPT, GLOBALS_FILENAME);
for (int i = 0; i < length; ++i)
- pGlobals[i] = f.readSint32LE();
+ g_pGlobals[i] = f.readSint32LE();
if (f.eos() || f.err())
error(FILE_IS_CORRUPT, GLOBALS_FILENAME);
@@ -454,19 +454,19 @@ void RegisterGlobals(int num) {
}
void FreeGlobals() {
- free(pGlobals);
- pGlobals = NULL;
+ free(g_pGlobals);
+ g_pGlobals = NULL;
- free(icList);
- icList = NULL;
+ free(g_icList);
+ g_icList = NULL;
}
/**
* (Un)serialize the global data for save/restore game.
*/
void syncGlobInfo(Common::Serializer &s) {
- for (int i = 0; i < numGlobals; i++) {
- s.syncAsSint32LE(pGlobals[i]);
+ for (int i = 0; i < g_numGlobals; i++) {
+ s.syncAsSint32LE(g_pGlobals[i]);
}
}
@@ -502,7 +502,7 @@ void INT_CONTEXT::syncWithSerializer(Common::Serializer &s) {
* Return pointer to and size of global data for save/restore game.
*/
void SaveInterpretContexts(INT_CONTEXT *sICInfo) {
- memcpy(sICInfo, icList, NUM_INTERPRET * sizeof(INT_CONTEXT));
+ memcpy(sICInfo, g_icList, NUM_INTERPRET * sizeof(INT_CONTEXT));
}
/**
@@ -633,8 +633,8 @@ void Interpret(CORO_PARAM, INT_CONTEXT *ic) {
case OP_GLOAD: // loads global variable onto stack
tmp = Fetch(opcode, ic->code, wkEntry, ip);
- assert(0 <= tmp && tmp < numGlobals);
- ic->stack[++ic->sp] = pGlobals[tmp];
+ assert(0 <= tmp && tmp < g_numGlobals);
+ ic->stack[++ic->sp] = g_pGlobals[tmp];
break;
case OP_STORE: // pops stack and stores in local variable
@@ -645,8 +645,8 @@ void Interpret(CORO_PARAM, INT_CONTEXT *ic) {
case OP_GSTORE: // pops stack and stores in global variable
tmp = Fetch(opcode, ic->code, wkEntry, ip);
- assert(0 <= tmp && tmp < numGlobals);
- pGlobals[tmp] = ic->stack[ic->sp--];
+ assert(0 <= tmp && tmp < g_numGlobals);
+ g_pGlobals[tmp] = ic->stack[ic->sp--];
break;
case OP_CALL: // procedure call
@@ -809,7 +809,7 @@ void Interpret(CORO_PARAM, INT_CONTEXT *ic) {
break;
case OP_ESCON:
- bNoPause = true;
+ g_bNoPause = true;
ic->escOn = true;
ic->myEscape = GetEscEvents();
break;
@@ -856,8 +856,8 @@ static uint32 UniqueWaitNumber() {
retval = (uint32)-1;
for (i = 0; i < NUM_INTERPRET; i++) {
- if ((icList+i)->waitNumber1 == retval
- || (icList+i)->waitNumber2 == retval)
+ if ((g_icList+i)->waitNumber1 == retval
+ || (g_icList+i)->waitNumber2 == retval)
break;
}
@@ -887,7 +887,7 @@ void WaitInterpret(CORO_PARAM, PPROCESS pWaitProc, bool *result) {
CORO_BEGIN_CODE(_ctx);
- for (i = 0, _ctx->picWaiter = icList; i < NUM_INTERPRET; i++, _ctx->picWaiter++) {
+ for (i = 0, _ctx->picWaiter = g_icList; i < NUM_INTERPRET; i++, _ctx->picWaiter++) {
if (_ctx->picWaiter->GSort != GS_NONE && _ctx->picWaiter->pProc == currentProcess) {
break;
}
@@ -896,7 +896,7 @@ void WaitInterpret(CORO_PARAM, PPROCESS pWaitProc, bool *result) {
/*
* Find the interpret context of the process we're waiting for
*/
- for (i = 0, _ctx->picWaitee = icList; i < NUM_INTERPRET; i++, _ctx->picWaitee++) {
+ for (i = 0, _ctx->picWaitee = g_icList; i < NUM_INTERPRET; i++, _ctx->picWaitee++) {
if (_ctx->picWaitee->GSort != GS_NONE && _ctx->picWaitee->pProc == pWaitProc) {
break;
}
@@ -931,11 +931,11 @@ void CheckOutWaiters() {
// Check all waited for have someone waiting
for (i = 0; i < NUM_INTERPRET; i++) {
// If someone is supposedly waiting for this one
- if ((icList + i)->GSort != GS_NONE && (icList + i)->waitNumber2) {
+ if ((g_icList + i)->GSort != GS_NONE && (g_icList + i)->waitNumber2) {
// Someone really must be waiting for this one
for (j = 0; j < NUM_INTERPRET; j++) {
- if ((icList + j)->GSort != GS_NONE
- && (icList + j)->waitNumber1 == (icList + i)->waitNumber2) {
+ if ((g_icList + j)->GSort != GS_NONE
+ && (g_icList + j)->waitNumber1 == (g_icList + i)->waitNumber2) {
break;
}
}
@@ -946,11 +946,11 @@ void CheckOutWaiters() {
// Check waiting for someone to wait for
for (i = 0; i < NUM_INTERPRET; i++) {
// If someone is supposedly waiting for this one
- if ((icList + i)->GSort != GS_NONE && (icList + i)->waitNumber1) {
+ if ((g_icList + i)->GSort != GS_NONE && (g_icList + i)->waitNumber1) {
// Someone really must be waiting for this one
for (j = 0; j < NUM_INTERPRET; j++) {
- if ((icList + j)->GSort != GS_NONE
- && (icList + j)->waitNumber2 == (icList + i)->waitNumber1) {
+ if ((g_icList + j)->GSort != GS_NONE
+ && (g_icList + j)->waitNumber2 == (g_icList + i)->waitNumber1) {
break;
}
}
diff --git a/engines/tinsel/pdisplay.cpp b/engines/tinsel/pdisplay.cpp
index 7439c6f77d..9a9e6ab00f 100644
--- a/engines/tinsel/pdisplay.cpp
+++ b/engines/tinsel/pdisplay.cpp
@@ -50,7 +50,7 @@ namespace Tinsel {
#ifdef DEBUG
//extern int Overrun; // The overrun counter, in DOS_DW.C
-extern int newestString; // The overrun counter, in STRRES.C
+extern int g_newestString; // The overrun counter, in STRRES.C
#endif
@@ -73,17 +73,17 @@ enum HotSpotTag {
// FIXME: Avoid non-const global vars
-static bool DispPath = false;
-static bool bShowString = false;
+static bool g_DispPath = false;
+static bool g_bShowString = false;
-static int TaggedActor = 0;
-static HPOLYGON hTaggedPolygon = NOPOLY;
+static int g_TaggedActor = 0;
+static HPOLYGON g_hTaggedPolygon = NOPOLY;
-static bool bTagsActive = true;
+static bool g_bTagsActive = true;
-static bool bPointingActive = true;
+static bool g_bPointingActive = true;
-static char tagBuffer[64];
+static char g_tagBuffer[64];
#ifdef DEBUG
/**
@@ -158,7 +158,7 @@ void CursorPositionProcess(CORO_PARAM, const void *) {
sprintf(PositionString, "%d %d", aniX + Loffset, aniY + Toffset);
_ctx->cpText = ObjectTextOut(GetPlayfieldList(FIELD_STATUS), PositionString,
0, CPOSX, POSY, GetTagFontHandle(), TXT_CENTER);
- if (DispPath) {
+ if (g_DispPath) {
HPOLYGON hp = InPolygon(aniX + Loffset, aniY + Toffset, PATH);
if (hp == NOPOLY)
sprintf(PositionString, "No path");
@@ -226,18 +226,18 @@ void CursorPositionProcess(CORO_PARAM, const void *) {
/*-------------*\
| String number |
\*-------------*/
- if (bShowString && newestString != _ctx->prevString) {
+ if (g_bShowString && g_newestString != _ctx->prevString) {
// kill current text objects
if (_ctx->spText) {
MultiDeleteObject(GetPlayfieldList(FIELD_STATUS), _ctx->spText);
}
- sprintf(PositionString, "String: %d", newestString);
+ sprintf(PositionString, "String: %d", g_newestString);
_ctx->spText = ObjectTextOut(GetPlayfieldList(FIELD_STATUS), PositionString,
0, SPOSX, POSY+10, GetTalkFontHandle(), TXT_CENTER);
// update previous value
- _ctx->prevString = newestString;
+ _ctx->prevString = g_newestString;
}
// update previous playfield position
@@ -257,7 +257,7 @@ void DisablePointing() {
int i;
HPOLYGON hPoly; // Polygon handle
- bPointingActive = false;
+ g_bPointingActive = false;
for (i = 0; i < MAX_POLY; i++) {
hPoly = GetPolyHandle(i);
@@ -284,7 +284,7 @@ void DisablePointing() {
* EnablePointing()
*/
void EnablePointing() {
- bPointingActive = true;
+ g_bPointingActive = true;
}
/**
@@ -292,7 +292,7 @@ void EnablePointing() {
* (if one is). Tag process asks us for this information, as does ProcessUserEvent().
*/
static void SaveTaggedActor(int ano) {
- TaggedActor = ano;
+ g_TaggedActor = ano;
}
/**
@@ -300,7 +300,7 @@ static void SaveTaggedActor(int ano) {
* (if one is). Tag process asks us for this information, as does ProcessUserEvent().
*/
int GetTaggedActor() {
- return TaggedActor;
+ return g_TaggedActor;
}
/**
@@ -308,11 +308,11 @@ int GetTaggedActor() {
* (if one is). Tag process asks us for this information, as does ProcessUserEvent().
*/
static void SaveTaggedPoly(HPOLYGON hp) {
- hTaggedPolygon = hp;
+ g_hTaggedPolygon = hp;
}
HPOLYGON GetTaggedPoly() {
- return hTaggedPolygon;
+ return g_hTaggedPolygon;
}
/**
@@ -405,11 +405,11 @@ static bool ActorTag(int curX, int curY, HotSpotTag *pTag, OBJECT **ppText) {
if (ActorTagIsWanted(actor)) {
GetActorTagPos(actor, &tagX, &tagY, false);
- LoadStringRes(GetActorTagHandle(actor), tagBuffer, sizeof(tagBuffer));
+ LoadStringRes(GetActorTagHandle(actor), g_tagBuffer, sizeof(g_tagBuffer));
// May have buggered cursor
EndCursorFollowed();
- *ppText = ObjectTextOut(GetPlayfieldList(FIELD_STATUS), tagBuffer,
+ *ppText = ObjectTextOut(GetPlayfieldList(FIELD_STATUS), g_tagBuffer,
0, tagX, tagY, GetTagFontHandle(), TXT_CENTER, 0);
assert(*ppText);
MultiSetZPosition(*ppText, Z_TAG_TEXT);
@@ -653,7 +653,7 @@ void TagProcess(CORO_PARAM, const void *) {
SaveTaggedPoly(NOPOLY); // No tagged polygon yet
while (1) {
- if (bTagsActive) {
+ if (g_bTagsActive) {
int curX, curY; // cursor position
while (!GetCursorXYNoWait(&curX, &curY, true))
CORO_SLEEP(1);
@@ -804,7 +804,7 @@ void PointProcess(CORO_PARAM, const void *) {
// allow re-scheduling
do {
CORO_SLEEP(1);
- } while (!bPointingActive);
+ } while (!g_bPointingActive);
} else {
// allow re-scheduling
CORO_SLEEP(1);
@@ -815,15 +815,15 @@ void PointProcess(CORO_PARAM, const void *) {
}
void DisableTags() {
- bTagsActive = false;
+ g_bTagsActive = false;
}
void EnableTags() {
- bTagsActive = true;
+ g_bTagsActive = true;
}
bool DisableTagsIfEnabled() {
- if (bTagsActive) {
+ if (g_bTagsActive) {
DisableTags();
return true;
} else
@@ -836,12 +836,12 @@ bool DisableTagsIfEnabled() {
* cursor is in.
*/
void TogglePathDisplay() {
- DispPath ^= 1; // Toggle path display (XOR with true)
+ g_DispPath ^= 1; // Toggle path display (XOR with true)
}
void setshowstring() {
- bShowString = true;
+ g_bShowString = true;
}
} // End of namespace Tinsel
diff --git a/engines/tinsel/play.cpp b/engines/tinsel/play.cpp
index 71e07721a6..40729d9f3a 100644
--- a/engines/tinsel/play.cpp
+++ b/engines/tinsel/play.cpp
@@ -62,10 +62,10 @@ struct PPINIT {
// FIXME: Avoid non-const global vars
-static SOUNDREELS soundReels[MAX_SOUNDREELS];
-static int soundReelNumbers[MAX_SOUNDREELS];
+static SOUNDREELS g_soundReels[MAX_SOUNDREELS];
+static int g_soundReelNumbers[MAX_SOUNDREELS];
-static int soundReelWait;
+static int g_soundReelWait;
//-------------------- METHODS ----------------------
@@ -148,31 +148,31 @@ static int RegisterSoundReel(SCNHANDLE hFilm, int column, int actorCol) {
for (i = 0; i < MAX_SOUNDREELS; i++) {
// Should assert this doesn't happen, but let's be tolerant
- if (soundReels[i].hFilm == hFilm && soundReels[i].column == column)
+ if (g_soundReels[i].hFilm == hFilm && g_soundReels[i].column == column)
break;
- if (!soundReels[i].hFilm) {
- soundReels[i].hFilm = hFilm;
- soundReels[i].column = column;
- soundReels[i].actorCol = actorCol;
+ if (!g_soundReels[i].hFilm) {
+ g_soundReels[i].hFilm = hFilm;
+ g_soundReels[i].column = column;
+ g_soundReels[i].actorCol = actorCol;
break;
}
}
- soundReelNumbers[i]++;
+ g_soundReelNumbers[i]++;
return i;
}
void NoSoundReels() {
- memset(soundReels, 0, sizeof(soundReels));
- soundReelWait = 0;
+ memset(g_soundReels, 0, sizeof(g_soundReels));
+ g_soundReelWait = 0;
}
static void DeRegisterSoundReel(SCNHANDLE hFilm, int column) {
for (int i = 0; i < MAX_SOUNDREELS; i++) {
// Should assert this doesn't happen, but let's be tolerant
- if (soundReels[i].hFilm == hFilm && soundReels[i].column == column) {
- soundReels[i].hFilm = 0;
+ if (g_soundReels[i].hFilm == hFilm && g_soundReels[i].column == column) {
+ g_soundReels[i].hFilm = 0;
break;
}
}
@@ -180,15 +180,15 @@ static void DeRegisterSoundReel(SCNHANDLE hFilm, int column) {
void SaveSoundReels(PSOUNDREELS psr) {
for (int i = 0; i < MAX_SOUNDREELS; i++) {
- if (IsCdPlayHandle(soundReels[i].hFilm))
- soundReels[i].hFilm = 0;
+ if (IsCdPlayHandle(g_soundReels[i].hFilm))
+ g_soundReels[i].hFilm = 0;
}
- memcpy(psr, soundReels, sizeof(soundReels));
+ memcpy(psr, g_soundReels, sizeof(g_soundReels));
}
void RestoreSoundReels(PSOUNDREELS psr) {
- memcpy(soundReels, psr, sizeof(soundReels));
+ memcpy(g_soundReels, psr, sizeof(g_soundReels));
}
static uint32 GetZfactor(int actorID, PMOVER pMover, bool bNewMover) {
@@ -245,7 +245,7 @@ static void SoundReel(CORO_PARAM, SCNHANDLE hFilm, int column, int speed,
_ctx->bFinished = false;
_ctx->bLooped = false;
_ctx->myId = RegisterSoundReel(hFilm, column, actorCol);
- _ctx->myNum = soundReelNumbers[_ctx->myId];
+ _ctx->myNum = g_soundReelNumbers[_ctx->myId];
do {
pFilm = (FILM *)LockMem(hFilm);
@@ -366,10 +366,10 @@ static void SoundReel(CORO_PARAM, SCNHANDLE hFilm, int column, int speed,
_ctx->bFinished = true;
}
- } while (!_ctx->bFinished && _ctx->myNum == soundReelNumbers[_ctx->myId]);
+ } while (!_ctx->bFinished && _ctx->myNum == g_soundReelNumbers[_ctx->myId]);
// De-register - if not been replaced
- if (_ctx->myNum == soundReelNumbers[_ctx->myId])
+ if (_ctx->myNum == g_soundReelNumbers[_ctx->myId])
DeRegisterSoundReel(hFilm, column);
CORO_END_CODE;
@@ -384,17 +384,17 @@ static void ResSoundReel(CORO_PARAM, const void *param) {
CORO_BEGIN_CODE(_ctx);
- CORO_INVOKE_ARGS(SoundReel, (CORO_SUBCTX, soundReels[i].hFilm, soundReels[i].column,
- -1, 0, soundReels[i].actorCol));
+ CORO_INVOKE_ARGS(SoundReel, (CORO_SUBCTX, g_soundReels[i].hFilm, g_soundReels[i].column,
+ -1, 0, g_soundReels[i].actorCol));
CORO_KILL_SELF();
CORO_END_CODE;
}
static void SoundReelWaitCheck() {
- if (--soundReelWait == 0) {
+ if (--g_soundReelWait == 0) {
for (int i = 0; i < MAX_SOUNDREELS; i++) {
- if (soundReels[i].hFilm) {
+ if (g_soundReels[i].hFilm) {
g_scheduler->createProcess(PID_REEL, ResSoundReel, &i, sizeof(i));
}
}
@@ -1162,7 +1162,7 @@ void RestoreActorReels(SCNHANDLE hFilm, int actor, int x, int y) {
// Start display process for the reel
g_scheduler->createProcess(PID_REEL, PlayProcess, &ppi, sizeof(ppi));
- soundReelWait++;
+ g_soundReelWait++;
}
}
}
diff --git a/engines/tinsel/rince.cpp b/engines/tinsel/rince.cpp
index ca196aac92..bb0aeabd2f 100644
--- a/engines/tinsel/rince.cpp
+++ b/engines/tinsel/rince.cpp
@@ -51,7 +51,7 @@ namespace Tinsel {
//----------------- LOCAL GLOBAL DATA --------------------
-static MOVER Movers[MAX_MOVERS]; // FIXME: Avoid non-const global vars
+static MOVER g_Movers[MAX_MOVERS]; // FIXME: Avoid non-const global vars
//----------------- FUNCTIONS ----------------------------
@@ -115,7 +115,7 @@ void MoverBrightness(PMOVER pMover, int brightness) {
* RebootMovers
*/
void RebootMovers() {
- memset(Movers, 0, sizeof(Movers));
+ memset(g_Movers, 0, sizeof(g_Movers));
}
/**
@@ -127,11 +127,11 @@ PMOVER GetMover(int ano) {
// Slot 0 is reserved for lead actor
if (ano == GetLeadId() || ano == LEAD_ACTOR)
- return &Movers[0];
+ return &g_Movers[0];
for (i = 1; i < MAX_MOVERS; i++)
- if (Movers[i].actorID == ano)
- return &Movers[i];
+ if (g_Movers[i].actorID == ano)
+ return &g_Movers[i];
return NULL;
}
@@ -144,25 +144,25 @@ PMOVER RegisterMover(int ano) {
// Slot 0 is reserved for lead actor
if (ano == GetLeadId() || ano == LEAD_ACTOR) {
- Movers[0].actorToken = TOKEN_LEAD;
- Movers[0].actorID = GetLeadId();
- return &Movers[0];
+ g_Movers[0].actorToken = TOKEN_LEAD;
+ g_Movers[0].actorID = GetLeadId();
+ return &g_Movers[0];
}
// Check it hasn't already been declared
for (i = 1; i < MAX_MOVERS; i++) {
- if (Movers[i].actorID == ano) {
+ if (g_Movers[i].actorID == ano) {
// Actor is already a moving actor
- return &Movers[i];
+ return &g_Movers[i];
}
}
// Find an empty slot
for (i = 1; i < MAX_MOVERS; i++)
- if (!Movers[i].actorID) {
- Movers[i].actorToken = TOKEN_LEAD + i;
- Movers[i].actorID = ano;
- return &Movers[i];
+ if (!g_Movers[i].actorID) {
+ g_Movers[i].actorToken = TOKEN_LEAD + i;
+ g_Movers[i].actorID = ano;
+ return &g_Movers[i];
}
error("Too many moving actors");
@@ -176,8 +176,8 @@ PMOVER RegisterMover(int ano) {
PMOVER GetLiveMover(int index) {
assert(index >= 0 && index < MAX_MOVERS); // out of range
- if (Movers[index].bActive)
- return &Movers[index];
+ if (g_Movers[index].bActive)
+ return &g_Movers[index];
else
return NULL;
}
@@ -185,13 +185,13 @@ PMOVER GetLiveMover(int index) {
bool IsMAinEffectPoly(int index) {
assert(index >= 0 && index < MAX_MOVERS); // out of range
- return Movers[index].bInEffect;
+ return g_Movers[index].bInEffect;
}
void SetMoverInEffect(int index, bool tf) {
assert(index >= 0 && index < MAX_MOVERS); // out of range
- Movers[index].bInEffect = tf;
+ g_Movers[index].bInEffect = tf;
}
/**
@@ -392,7 +392,7 @@ static void InitMover(PMOVER pMover) {
*/
void DropMovers() {
for (int i = 0; i < MAX_MOVERS; i++)
- InitMover(&Movers[i]);
+ InitMover(&g_Movers[i]);
}
@@ -880,30 +880,30 @@ PMOVER InMoverBlock(PMOVER pMover, int x, int y) {
caR = GetMoverRight(pMover) + x - caX;
for (int i = 0; i < MAX_MOVERS; i++) {
- if (pMover == &Movers[i] ||
- (TinselV2 && (Movers[i].actorObj == NULL)) ||
- (!TinselV2 && !Movers[i].bActive))
+ if (pMover == &g_Movers[i] ||
+ (TinselV2 && (g_Movers[i].actorObj == NULL)) ||
+ (!TinselV2 && !g_Movers[i].bActive))
continue;
// At around the same height?
- GetMoverPosition(&Movers[i], &taX, &taY);
- if (Movers[i].hFnpath != NOPOLY)
+ GetMoverPosition(&g_Movers[i], &taX, &taY);
+ if (g_Movers[i].hFnpath != NOPOLY)
continue;
if (ABS(y - taY) > 2) // 2 was 8
continue;
// To the left?
- taL = GetMoverLeft(&Movers[i]);
+ taL = GetMoverLeft(&g_Movers[i]);
if (caR <= taL)
continue;
// To the right?
- taR = GetMoverRight(&Movers[i]);
+ taR = GetMoverRight(&g_Movers[i]);
if (caL >= taR)
continue;
- return &Movers[i];
+ return &g_Movers[i];
}
return NULL;
}
@@ -913,33 +913,33 @@ PMOVER InMoverBlock(PMOVER pMover, int x, int y) {
*/
void SaveMovers(SAVED_MOVER *sMoverInfo) {
for (int i = 0; i < MAX_MOVERS; i++) {
- sMoverInfo[i].bActive = !TinselV2 ? Movers[i].bActive : Movers[i].actorObj != NULL;
- sMoverInfo[i].actorID = Movers[i].actorID;
- sMoverInfo[i].objX = Movers[i].objX;
- sMoverInfo[i].objY = Movers[i].objY;
- sMoverInfo[i].hLastfilm = Movers[i].hLastFilm;
+ sMoverInfo[i].bActive = !TinselV2 ? g_Movers[i].bActive : g_Movers[i].actorObj != NULL;
+ sMoverInfo[i].actorID = g_Movers[i].actorID;
+ sMoverInfo[i].objX = g_Movers[i].objX;
+ sMoverInfo[i].objY = g_Movers[i].objY;
+ sMoverInfo[i].hLastfilm = g_Movers[i].hLastFilm;
if (TinselV2) {
- sMoverInfo[i].bHidden = Movers[i].bHidden;
- sMoverInfo[i].brightness = Movers[i].brightness;
- sMoverInfo[i].startColor = Movers[i].startColor;
- sMoverInfo[i].paletteLength = Movers[i].paletteLength;
+ sMoverInfo[i].bHidden = g_Movers[i].bHidden;
+ sMoverInfo[i].brightness = g_Movers[i].brightness;
+ sMoverInfo[i].startColor = g_Movers[i].startColor;
+ sMoverInfo[i].paletteLength = g_Movers[i].paletteLength;
}
- memcpy(sMoverInfo[i].walkReels, Movers[i].walkReels, TOTAL_SCALES * 4 * sizeof(SCNHANDLE));
- memcpy(sMoverInfo[i].standReels, Movers[i].standReels, TOTAL_SCALES * 4 * sizeof(SCNHANDLE));
- memcpy(sMoverInfo[i].talkReels, Movers[i].talkReels, TOTAL_SCALES * 4 * sizeof(SCNHANDLE));
+ memcpy(sMoverInfo[i].walkReels, g_Movers[i].walkReels, TOTAL_SCALES * 4 * sizeof(SCNHANDLE));
+ memcpy(sMoverInfo[i].standReels, g_Movers[i].standReels, TOTAL_SCALES * 4 * sizeof(SCNHANDLE));
+ memcpy(sMoverInfo[i].talkReels, g_Movers[i].talkReels, TOTAL_SCALES * 4 * sizeof(SCNHANDLE));
}
}
void RestoreAuxScales(SAVED_MOVER *sMoverInfo) {
for (int i = 0; i < MAX_MOVERS; i++) {
if (TinselV2)
- Movers[i].actorID = sMoverInfo[i].actorID;
+ g_Movers[i].actorID = sMoverInfo[i].actorID;
- memcpy(Movers[i].walkReels, sMoverInfo[i].walkReels, TOTAL_SCALES * 4 * sizeof(SCNHANDLE));
- memcpy(Movers[i].standReels, sMoverInfo[i].standReels, TOTAL_SCALES * 4 * sizeof(SCNHANDLE));
- memcpy(Movers[i].talkReels, sMoverInfo[i].talkReels, TOTAL_SCALES * 4 * sizeof(SCNHANDLE));
+ memcpy(g_Movers[i].walkReels, sMoverInfo[i].walkReels, TOTAL_SCALES * 4 * sizeof(SCNHANDLE));
+ memcpy(g_Movers[i].standReels, sMoverInfo[i].standReels, TOTAL_SCALES * 4 * sizeof(SCNHANDLE));
+ memcpy(g_Movers[i].talkReels, sMoverInfo[i].talkReels, TOTAL_SCALES * 4 * sizeof(SCNHANDLE));
}
}
@@ -950,10 +950,10 @@ PMOVER NextMover(PMOVER pMover) {
if (pMover == NULL)
next = 0;
else
- next = pMover - Movers + 1;
+ next = pMover - g_Movers + 1;
- if (Movers[next].actorID)
- return &Movers[next];
+ if (g_Movers[next].actorID)
+ return &g_Movers[next];
else
return NULL;
}
diff --git a/engines/tinsel/saveload.cpp b/engines/tinsel/saveload.cpp
index a0801d8247..0a552c8c2b 100644
--- a/engines/tinsel/saveload.cpp
+++ b/engines/tinsel/saveload.cpp
@@ -22,6 +22,7 @@
*/
#include "tinsel/actors.h"
+#include "tinsel/config.h"
#include "tinsel/dialogs.h"
#include "tinsel/drives.h"
#include "tinsel/dw.h"
@@ -67,9 +68,9 @@ namespace Tinsel {
//----------------- GLOBAL GLOBAL DATA --------------------
-int thingHeld = 0;
-int restoreCD = 0;
-SRSTATE SRstate = SR_IDLE;
+int g_thingHeld = 0;
+int g_restoreCD = 0;
+SRSTATE g_SRstate = SR_IDLE;
//----------------- EXTERN FUNCTIONS --------------------
@@ -82,9 +83,9 @@ extern void syncGlobInfo(Common::Serializer &s);
// in POLYGONS.C
extern void syncPolyInfo(Common::Serializer &s);
-extern int sceneCtr;
+extern int g_sceneCtr;
-extern bool ASceneIsSaved;
+extern bool g_ASceneIsSaved;
//----------------- LOCAL DEFINES --------------------
@@ -94,12 +95,14 @@ struct SaveGameHeader {
uint32 ver;
char desc[SG_DESC_LEN];
TimeDate dateTime;
+ bool scnFlag;
+ byte language;
};
enum {
DW1_SAVEGAME_ID = 0x44575399, // = 'DWSc' = "DiscWorld 1 ScummVM"
DW2_SAVEGAME_ID = 0x44573253, // = 'DW2S' = "DiscWorld 2 ScummVM"
- SAVEGAME_HEADER_SIZE = 4 + 4 + 4 + SG_DESC_LEN + 7
+ SAVEGAME_HEADER_SIZE = 4 + 4 + 4 + SG_DESC_LEN + 7 + 1 + 1
};
#define SAVEGAME_ID (TinselV2 ? (uint32)DW2_SAVEGAME_ID : (uint32)DW1_SAVEGAME_ID)
@@ -120,21 +123,23 @@ struct SFILES {
// FIXME: Avoid non-const global vars
-static int numSfiles = 0;
-static SFILES savedFiles[MAX_SAVED_FILES];
+static int g_numSfiles = 0;
+static SFILES g_savedFiles[MAX_SAVED_FILES];
-static bool NeedLoad = true;
+static bool g_NeedLoad = true;
-static SAVED_DATA *srsd = 0;
-static int RestoreGameNumber = 0;
-static char *SaveSceneName = 0;
-static const char *SaveSceneDesc = 0;
-static int *SaveSceneSsCount = 0;
-static SAVED_DATA *SaveSceneSsData = 0; // points to 'SAVED_DATA ssdata[MAX_NEST]'
+static SAVED_DATA *g_srsd = 0;
+static int g_RestoreGameNumber = 0;
+static char *g_SaveSceneName = 0;
+static const char *g_SaveSceneDesc = 0;
+static int *g_SaveSceneSsCount = 0;
+static SAVED_DATA *g_SaveSceneSsData = 0; // points to 'SAVED_DATA ssdata[MAX_NEST]'
//------------- SAVE/LOAD SUPPORT METHODS ----------------
-void setNeedLoad() { NeedLoad = true; }
+void setNeedLoad() {
+ g_NeedLoad = true;
+}
static void syncTime(Common::Serializer &s, TimeDate &t) {
s.syncAsUint16LE(t.tm_year);
@@ -166,6 +171,21 @@ static bool syncSaveGameHeader(Common::Serializer &s, SaveGameHeader &hdr) {
// Perform sanity check
if (tmp < 0 || !correctID || hdr.ver > CURRENT_VER || hdr.size > 1024)
return false;
+
+ if (tmp > 0) {
+ // If there's header space left, handling syncing the Scn flag and game language
+ s.syncAsByte(hdr.scnFlag);
+ s.syncAsByte(hdr.language);
+ tmp -= 2;
+
+ if (_vm && s.isLoading()) {
+ // If the engine is loaded, ensure the Scn/Gra usage is correct, and it's the correct language
+ if ((hdr.scnFlag != ((_vm->getFeatures() & GF_SCNFILES) != 0)) ||
+ (hdr.language != _vm->_config->_language))
+ return false;
+ }
+ }
+
// Skip over any extra bytes
s.skip(tmp);
return true;
@@ -327,18 +347,18 @@ static int cmpTimeDate(const TimeDate &a, const TimeDate &b) {
int getList(Common::SaveFileManager *saveFileMan, const Common::String &target) {
// No change since last call?
// TODO/FIXME: Just always reload this data? Be careful about slow downs!!!
- if (!NeedLoad)
- return numSfiles;
+ if (!g_NeedLoad)
+ return g_numSfiles;
int i;
const Common::String pattern = target + ".???";
Common::StringArray files = saveFileMan->listSavefiles(pattern);
- numSfiles = 0;
+ g_numSfiles = 0;
for (Common::StringArray::const_iterator file = files.begin(); file != files.end(); ++file) {
- if (numSfiles >= MAX_SAVED_FILES)
+ if (g_numSfiles >= MAX_SAVED_FILES)
break;
const Common::String &fname = *file;
@@ -358,46 +378,46 @@ int getList(Common::SaveFileManager *saveFileMan, const Common::String &target)
// "incompatible version".
}
- i = numSfiles;
+ i = g_numSfiles;
#ifndef DISABLE_SAVEGAME_SORTING
- for (i = 0; i < numSfiles; i++) {
- if (cmpTimeDate(hdr.dateTime, savedFiles[i].dateTime) > 0) {
- Common::copy_backward(&savedFiles[i], &savedFiles[numSfiles], &savedFiles[numSfiles + 1]);
+ for (i = 0; i < g_numSfiles; i++) {
+ if (cmpTimeDate(hdr.dateTime, g_savedFiles[i].dateTime) > 0) {
+ Common::copy_backward(&g_savedFiles[i], &g_savedFiles[g_numSfiles], &g_savedFiles[g_numSfiles + 1]);
break;
}
}
#endif
- Common::strlcpy(savedFiles[i].name, fname.c_str(), FNAMELEN);
- Common::strlcpy(savedFiles[i].desc, hdr.desc, SG_DESC_LEN);
- savedFiles[i].dateTime = hdr.dateTime;
+ Common::strlcpy(g_savedFiles[i].name, fname.c_str(), FNAMELEN);
+ Common::strlcpy(g_savedFiles[i].desc, hdr.desc, SG_DESC_LEN);
+ g_savedFiles[i].dateTime = hdr.dateTime;
- ++numSfiles;
+ ++g_numSfiles;
}
// Next getList() needn't do its stuff again
- NeedLoad = false;
+ g_NeedLoad = false;
- return numSfiles;
+ return g_numSfiles;
}
int getList() {
// No change since last call?
// TODO/FIXME: Just always reload this data? Be careful about slow downs!!!
- if (!NeedLoad)
- return numSfiles;
+ if (!g_NeedLoad)
+ return g_numSfiles;
return getList(_vm->getSaveFileMan(), _vm->getTargetName());
}
char *ListEntry(int i, letype which) {
if (i == -1)
- i = numSfiles;
+ i = g_numSfiles;
assert(i >= 0);
- if (i < numSfiles)
- return which == LE_NAME ? savedFiles[i].name : savedFiles[i].desc;
+ if (i < g_numSfiles)
+ return which == LE_NAME ? g_savedFiles[i].name : g_savedFiles[i].desc;
else
return NULL;
}
@@ -407,14 +427,14 @@ static void DoSync(Common::Serializer &s) {
if (TinselV2) {
if (s.isSaving())
- restoreCD = GetCurrentCD();
- s.syncAsSint16LE(restoreCD);
+ g_restoreCD = GetCurrentCD();
+ s.syncAsSint16LE(g_restoreCD);
}
if (TinselV2 && s.isLoading())
HoldItem(INV_NOICON);
- syncSavedData(s, *srsd);
+ syncSavedData(s, *g_srsd);
syncGlobInfo(s); // Glitter globals
syncInvInfo(s); // Inventory data
@@ -424,7 +444,7 @@ static void DoSync(Common::Serializer &s) {
s.syncAsSint32LE(sg);
if (s.isLoading()) {
if (TinselV2)
- thingHeld = sg;
+ g_thingHeld = sg;
else
HoldItem(sg);
}
@@ -434,17 +454,17 @@ static void DoSync(Common::Serializer &s) {
syncPolyInfo(s); // Dead polygon data
syncSCdata(s); // Hook Scene and delayed scene
- s.syncAsSint32LE(*SaveSceneSsCount);
+ s.syncAsSint32LE(*g_SaveSceneSsCount);
- if (*SaveSceneSsCount != 0) {
- SAVED_DATA *sdPtr = SaveSceneSsData;
- for (int i = 0; i < *SaveSceneSsCount; ++i, ++sdPtr)
+ if (*g_SaveSceneSsCount != 0) {
+ SAVED_DATA *sdPtr = g_SaveSceneSsData;
+ for (int i = 0; i < *g_SaveSceneSsCount; ++i, ++sdPtr)
syncSavedData(s, *sdPtr);
// Flag that there is a saved scene to return to. Note that in this context 'saved scene'
// is a stored scene to return to from another scene, such as from the Summoning Book close-up
// in Discworld 1 to whatever scene Rincewind was in prior to that
- ASceneIsSaved = true;
+ g_ASceneIsSaved = true;
}
if (!TinselV2)
@@ -455,7 +475,7 @@ static void DoSync(Common::Serializer &s) {
* DoRestore
*/
static bool DoRestore() {
- Common::InSaveFile *f = _vm->getSaveFileMan()->openForLoading(savedFiles[RestoreGameNumber].name);
+ Common::InSaveFile *f = _vm->getSaveFileMan()->openForLoading(g_savedFiles[g_RestoreGameNumber].name);
if (f == NULL) {
return false;
@@ -486,6 +506,16 @@ static bool DoRestore() {
return !failed;
}
+static void SaveFailure(Common::OutSaveFile *f) {
+ if (f) {
+ delete f;
+ _vm->getSaveFileMan()->removeSavefile(g_SaveSceneName);
+ g_SaveSceneName = NULL; // Invalidate save name
+ }
+ GUI::MessageDialog dialog(_("Failed to save game state to file."));
+ dialog.runModal();
+}
+
/**
* DoSave
*/
@@ -494,9 +524,9 @@ static void DoSave() {
char tmpName[FNAMELEN];
// Next getList() must do its stuff again
- NeedLoad = true;
+ g_NeedLoad = true;
- if (SaveSceneName == NULL) {
+ if (g_SaveSceneName == NULL) {
// Generate a new unique save name
int i;
int ano = 1; // Allocated number
@@ -505,81 +535,80 @@ static void DoSave() {
Common::String fname = _vm->getSavegameFilename(ano);
strcpy(tmpName, fname.c_str());
- for (i = 0; i < numSfiles; i++)
- if (!strcmp(savedFiles[i].name, tmpName))
+ for (i = 0; i < g_numSfiles; i++)
+ if (!strcmp(g_savedFiles[i].name, tmpName))
break;
- if (i == numSfiles)
+ if (i == g_numSfiles)
break;
ano++;
}
- SaveSceneName = tmpName;
+ g_SaveSceneName = tmpName;
}
- if (SaveSceneDesc[0] == 0)
- SaveSceneDesc = "unnamed";
+ if (g_SaveSceneDesc[0] == 0)
+ g_SaveSceneDesc = "unnamed";
- f = _vm->getSaveFileMan()->openForSaving(SaveSceneName);
+ f = _vm->getSaveFileMan()->openForSaving(g_SaveSceneName);
Common::Serializer s(0, f);
- if (f == NULL)
- goto save_failure;
+ if (f == NULL) {
+ SaveFailure(f);
+ return;
+ }
// Write out a savegame header
SaveGameHeader hdr;
hdr.id = SAVEGAME_ID;
hdr.size = SAVEGAME_HEADER_SIZE;
hdr.ver = CURRENT_VER;
- memcpy(hdr.desc, SaveSceneDesc, SG_DESC_LEN);
+ memcpy(hdr.desc, g_SaveSceneDesc, SG_DESC_LEN);
hdr.desc[SG_DESC_LEN - 1] = 0;
g_system->getTimeAndDate(hdr.dateTime);
+ hdr.scnFlag = _vm->getFeatures() & GF_SCNFILES;
+ hdr.language = _vm->_config->_language;
+
if (!syncSaveGameHeader(s, hdr) || f->err()) {
- goto save_failure;
+ SaveFailure(f);
+ return;
}
DoSync(s);
// Write out the special Id for Discworld savegames
f->writeUint32LE(0xFEEDFACE);
- if (f->err())
- goto save_failure;
+ if (f->err()) {
+ SaveFailure(f);
+ return;
+ }
f->finalize();
delete f;
- SaveSceneName = NULL; // Invalidate save name
- return;
-
-save_failure:
- if (f) {
- delete f;
- _vm->getSaveFileMan()->removeSavefile(SaveSceneName);
- SaveSceneName = NULL; // Invalidate save name
- }
- GUI::MessageDialog dialog(_("Failed to save game state to file."));
- dialog.runModal();
+ g_SaveSceneName = NULL; // Invalidate save name
}
/**
* ProcessSRQueue
*/
void ProcessSRQueue() {
- switch (SRstate) {
+ switch (g_SRstate) {
case SR_DORESTORE:
// If a load has been done directly from title screens, set a larger value for scene ctr so the
// code used to skip the title screens in Discworld 1 gets properly disabled
- if (sceneCtr < 10) sceneCtr = 10;
+ if (g_sceneCtr < 10)
+ g_sceneCtr = 10;
if (DoRestore()) {
- DoRestoreScene(srsd, false);
+ DoRestoreScene(g_srsd, false);
}
- SRstate = SR_IDLE;
+ g_SRstate = SR_IDLE;
break;
case SR_DOSAVE:
DoSave();
- SRstate = SR_IDLE;
+ g_SRstate = SR_IDLE;
break;
default:
break;
@@ -588,14 +617,14 @@ void ProcessSRQueue() {
void RequestSaveGame(char *name, char *desc, SAVED_DATA *sd, int *pSsCount, SAVED_DATA *pSsData) {
- assert(SRstate == SR_IDLE);
-
- SaveSceneName = name;
- SaveSceneDesc = desc;
- SaveSceneSsCount = pSsCount;
- SaveSceneSsData = pSsData;
- srsd = sd;
- SRstate = SR_DOSAVE;
+ assert(g_SRstate == SR_IDLE);
+
+ g_SaveSceneName = name;
+ g_SaveSceneDesc = desc;
+ g_SaveSceneSsCount = pSsCount;
+ g_SaveSceneSsData = pSsData;
+ g_srsd = sd;
+ g_SRstate = SR_DOSAVE;
}
void RequestRestoreGame(int num, SAVED_DATA *sd, int *pSsCount, SAVED_DATA *pSsData) {
@@ -604,17 +633,17 @@ void RequestRestoreGame(int num, SAVED_DATA *sd, int *pSsCount, SAVED_DATA *pSsD
return;
else if (num == -2) {
// From CD change for restore
- num = RestoreGameNumber;
+ num = g_RestoreGameNumber;
}
}
assert(num >= 0);
- RestoreGameNumber = num;
- SaveSceneSsCount = pSsCount;
- SaveSceneSsData = pSsData;
- srsd = sd;
- SRstate = SR_DORESTORE;
+ g_RestoreGameNumber = num;
+ g_SaveSceneSsCount = pSsCount;
+ g_SaveSceneSsData = pSsData;
+ g_srsd = sd;
+ g_SRstate = SR_DORESTORE;
}
/**
diff --git a/engines/tinsel/savescn.cpp b/engines/tinsel/savescn.cpp
index 39a8033d45..1b06e3929c 100644
--- a/engines/tinsel/savescn.cpp
+++ b/engines/tinsel/savescn.cpp
@@ -75,29 +75,29 @@ enum {
//----------------- EXTERNAL GLOBAL DATA --------------------
-extern int thingHeld;
-extern int restoreCD;
-extern SRSTATE SRstate;
+extern int g_thingHeld;
+extern int g_restoreCD;
+extern SRSTATE g_SRstate;
//----------------- LOCAL GLOBAL DATA --------------------
// FIXME: Avoid non-const global vars
-bool ASceneIsSaved = false;
+bool g_ASceneIsSaved = false;
-static int savedSceneCount = 0;
+static int g_savedSceneCount = 0;
-static bool bNotDoneYet = false;
+static bool g_bNotDoneYet = false;
//static SAVED_DATA ssData[MAX_NEST];
-static SAVED_DATA *ssData = NULL;
-static SAVED_DATA sgData;
+static SAVED_DATA *g_ssData = NULL;
+static SAVED_DATA g_sgData;
-static SAVED_DATA *rsd = 0;
+static SAVED_DATA *g_rsd = 0;
-static int RestoreSceneCount = 0;
+static int g_RestoreSceneCount = 0;
-static bool bNoFade = false;
+static bool g_bNoFade = false;
//----------------- FORWARD REFERENCES --------------------
@@ -133,7 +133,7 @@ void DoSaveScene(SAVED_DATA *sd) {
CurrentMidiFacts(&sd->SavedMidi, &sd->SavedLoop);
}
- ASceneIsSaved = true;
+ g_ASceneIsSaved = true;
}
/**
@@ -142,29 +142,29 @@ void DoSaveScene(SAVED_DATA *sd) {
* @param bFadeOut Flag to perform a fade out
*/
void DoRestoreScene(SAVED_DATA *sd, bool bFadeOut) {
- rsd = sd;
+ g_rsd = sd;
if (bFadeOut)
- RestoreSceneCount = RS_COUNT + COUNTOUT_COUNT; // Set restore scene count
+ g_RestoreSceneCount = RS_COUNT + COUNTOUT_COUNT; // Set restore scene count
else
- RestoreSceneCount = RS_COUNT; // Set restore scene count
+ g_RestoreSceneCount = RS_COUNT; // Set restore scene count
}
void InitializeSaveScenes() {
- if (ssData == NULL) {
- ssData = (SAVED_DATA *)calloc(MAX_NEST, sizeof(SAVED_DATA));
- if (ssData == NULL) {
+ if (g_ssData == NULL) {
+ g_ssData = (SAVED_DATA *)calloc(MAX_NEST, sizeof(SAVED_DATA));
+ if (g_ssData == NULL) {
error("Cannot allocate memory for scene changes");
}
} else {
// Re-initialize - no scenes saved
- savedSceneCount = 0;
+ g_savedSceneCount = 0;
}
}
void FreeSaveScenes() {
- free(ssData);
- ssData = NULL;
+ free(g_ssData);
+ g_ssData = NULL;
}
/**
@@ -212,29 +212,29 @@ static void SortMAProcess(CORO_PARAM, const void *) {
_ctx->viaActor = SysVar(ISV_DIVERT_ACTOR);
SetSysVar(ISV_DIVERT_ACTOR, 0);
- RestoreAuxScales(rsd->SavedMoverInfo);
+ RestoreAuxScales(g_rsd->SavedMoverInfo);
for (_ctx->i = 0; _ctx->i < MAX_MOVERS; _ctx->i++) {
- if (rsd->SavedMoverInfo[_ctx->i].bActive) {
- CORO_INVOKE_ARGS(Stand, (CORO_SUBCTX, rsd->SavedMoverInfo[_ctx->i].actorID,
- rsd->SavedMoverInfo[_ctx->i].objX, rsd->SavedMoverInfo[_ctx->i].objY,
- rsd->SavedMoverInfo[_ctx->i].hLastfilm));
+ if (g_rsd->SavedMoverInfo[_ctx->i].bActive) {
+ CORO_INVOKE_ARGS(Stand, (CORO_SUBCTX, g_rsd->SavedMoverInfo[_ctx->i].actorID,
+ g_rsd->SavedMoverInfo[_ctx->i].objX, g_rsd->SavedMoverInfo[_ctx->i].objY,
+ g_rsd->SavedMoverInfo[_ctx->i].hLastfilm));
- if (rsd->SavedMoverInfo[_ctx->i].bHidden)
- HideMover(GetMover(rsd->SavedMoverInfo[_ctx->i].actorID));
+ if (g_rsd->SavedMoverInfo[_ctx->i].bHidden)
+ HideMover(GetMover(g_rsd->SavedMoverInfo[_ctx->i].actorID));
}
- ActorPalette(rsd->SavedMoverInfo[_ctx->i].actorID,
- rsd->SavedMoverInfo[_ctx->i].startColor, rsd->SavedMoverInfo[_ctx->i].paletteLength);
+ ActorPalette(g_rsd->SavedMoverInfo[_ctx->i].actorID,
+ g_rsd->SavedMoverInfo[_ctx->i].startColor, g_rsd->SavedMoverInfo[_ctx->i].paletteLength);
- if (rsd->SavedMoverInfo[_ctx->i].brightness != BOGUS_BRIGHTNESS)
- ActorBrightness(rsd->SavedMoverInfo[_ctx->i].actorID, rsd->SavedMoverInfo[_ctx->i].brightness);
+ if (g_rsd->SavedMoverInfo[_ctx->i].brightness != BOGUS_BRIGHTNESS)
+ ActorBrightness(g_rsd->SavedMoverInfo[_ctx->i].actorID, g_rsd->SavedMoverInfo[_ctx->i].brightness);
}
// Restore via actor
SetSysVar(ISV_DIVERT_ACTOR, _ctx->viaActor);
- bNotDoneYet = false;
+ g_bNotDoneYet = false;
CORO_END_CODE;
}
@@ -244,49 +244,49 @@ static void SortMAProcess(CORO_PARAM, const void *) {
void ResumeInterprets() {
// Master script only affected on restore game, not restore scene
- if (!TinselV2 && (rsd == &sgData)) {
+ if (!TinselV2 && (g_rsd == &g_sgData)) {
g_scheduler->killMatchingProcess(PID_MASTER_SCR, -1);
FreeMasterInterpretContext();
}
for (int i = 0; i < NUM_INTERPRET; i++) {
- switch (rsd->SavedICInfo[i].GSort) {
+ switch (g_rsd->SavedICInfo[i].GSort) {
case GS_NONE:
break;
case GS_INVENTORY:
- if (rsd->SavedICInfo[i].event != POINTED) {
- RestoreProcess(&rsd->SavedICInfo[i]);
+ if (g_rsd->SavedICInfo[i].event != POINTED) {
+ RestoreProcess(&g_rsd->SavedICInfo[i]);
}
break;
case GS_MASTER:
// Master script only affected on restore game, not restore scene
- if (rsd == &sgData)
- RestoreMasterProcess(&rsd->SavedICInfo[i]);
+ if (g_rsd == &g_sgData)
+ RestoreMasterProcess(&g_rsd->SavedICInfo[i]);
break;
case GS_PROCESS:
// Tinsel 2 process
- RestoreSceneProcess(&rsd->SavedICInfo[i]);
+ RestoreSceneProcess(&g_rsd->SavedICInfo[i]);
break;
case GS_GPROCESS:
// Tinsel 2 Global processes only affected on restore game, not restore scene
- if (rsd == &sgData)
- RestoreGlobalProcess(&rsd->SavedICInfo[i]);
+ if (g_rsd == &g_sgData)
+ RestoreGlobalProcess(&g_rsd->SavedICInfo[i]);
break;
case GS_ACTOR:
if (TinselV2)
- RestoreProcess(&rsd->SavedICInfo[i]);
+ RestoreProcess(&g_rsd->SavedICInfo[i]);
else
- RestoreActorProcess(rsd->SavedICInfo[i].idActor, &rsd->SavedICInfo[i], rsd == &sgData);
+ RestoreActorProcess(g_rsd->SavedICInfo[i].idActor, &g_rsd->SavedICInfo[i], g_rsd == &g_sgData);
break;
case GS_POLYGON:
case GS_SCENE:
- RestoreProcess(&rsd->SavedICInfo[i]);
+ RestoreProcess(&g_rsd->SavedICInfo[i]);
break;
default:
@@ -313,7 +313,7 @@ static int DoRestoreSceneFrame(SAVED_DATA *sd, int n) {
if (TinselV2) {
// Master script only affected on restore game, not restore scene
- if (sd == &sgData) {
+ if (sd == &g_sgData) {
g_scheduler->killMatchingProcess(PID_MASTER_SCR);
KillGlobalProcesses();
FreeMasterInterpretContext();
@@ -322,12 +322,12 @@ static int DoRestoreSceneFrame(SAVED_DATA *sd, int n) {
RestorePolygonStuff(sd->SavedPolygonStuff);
// Abandon temporarily if different CD
- if (sd == &sgData && restoreCD != GetCurrentCD()) {
- SRstate = SR_IDLE;
+ if (sd == &g_sgData && g_restoreCD != GetCurrentCD()) {
+ g_SRstate = SR_IDLE;
EndScene();
- SetNextCD(restoreCD);
- CDChangeForRestore(restoreCD);
+ SetNextCD(g_restoreCD);
+ CDChangeForRestore(g_restoreCD);
return 0;
}
@@ -338,8 +338,8 @@ static int DoRestoreSceneFrame(SAVED_DATA *sd, int n) {
// Start up the scene
StartNewScene(sd->SavedSceneHandle, NO_ENTRY_NUM);
- SetDoFadeIn(!bNoFade);
- bNoFade = false;
+ SetDoFadeIn(!g_bNoFade);
+ g_bNoFade = false;
StartupBackground(nullContext, sd->SavedBgroundHandle);
if (TinselV2) {
@@ -355,7 +355,7 @@ static int DoRestoreSceneFrame(SAVED_DATA *sd, int n) {
if (TinselV2) {
// create process to sort out the moving actors
g_scheduler->createProcess(PID_MOVER, SortMAProcess, NULL, 0);
- bNotDoneYet = true;
+ g_bNotDoneYet = true;
RestoreActorZ(sd->savedActorZ);
RestoreZpositions(sd->zPositions);
@@ -374,11 +374,11 @@ static int DoRestoreSceneFrame(SAVED_DATA *sd, int n) {
case 1:
if (TinselV2) {
- if (bNotDoneYet)
+ if (g_bNotDoneYet)
return n;
- if (sd == &sgData)
- HoldItem(thingHeld, true);
+ if (sd == &g_sgData)
+ HoldItem(g_thingHeld, true);
if (sd->bTinselDim)
_vm->_pcmMusic->dim(true);
_vm->_pcmMusic->restoreThatTune(sd->SavedTune);
@@ -406,7 +406,7 @@ static int DoRestoreSceneFrame(SAVED_DATA *sd, int n) {
void RestoreGame(int num) {
KillInventory();
- RequestRestoreGame(num, &sgData, &savedSceneCount, ssData);
+ RequestRestoreGame(num, &g_sgData, &g_savedSceneCount, g_ssData);
// Actual restoring is performed by ProcessSRQueue
}
@@ -418,9 +418,9 @@ void RestoreGame(int num) {
*/
void SaveGame(char *name, char *desc) {
// Get current scene data
- DoSaveScene(&sgData);
+ DoSaveScene(&g_sgData);
- RequestSaveGame(name, desc, &sgData, &savedSceneCount, ssData);
+ RequestSaveGame(name, desc, &g_sgData, &g_savedSceneCount, g_ssData);
// Actual saving is performed by ProcessSRQueue
}
@@ -429,11 +429,11 @@ void SaveGame(char *name, char *desc) {
//---------------------------------------------------------------------------------
bool IsRestoringScene() {
- if (RestoreSceneCount) {
- RestoreSceneCount = DoRestoreSceneFrame(rsd, RestoreSceneCount);
+ if (g_RestoreSceneCount) {
+ g_RestoreSceneCount = DoRestoreSceneFrame(g_rsd, g_RestoreSceneCount);
}
- return RestoreSceneCount ? true : false;
+ return g_RestoreSceneCount ? true : false;
}
/**
@@ -441,13 +441,13 @@ bool IsRestoringScene() {
*/
void TinselRestoreScene(bool bFade) {
// only called by restore_scene PCODE
- if (RestoreSceneCount == 0) {
- assert(savedSceneCount >= 1); // No saved scene to restore
+ if (g_RestoreSceneCount == 0) {
+ assert(g_savedSceneCount >= 1); // No saved scene to restore
- if (ASceneIsSaved)
- DoRestoreScene(&ssData[--savedSceneCount], bFade);
+ if (g_ASceneIsSaved)
+ DoRestoreScene(&g_ssData[--g_savedSceneCount], bFade);
if (!bFade)
- bNoFade = true;
+ g_bNoFade = true;
}
}
@@ -461,14 +461,14 @@ void TinselSaveScene(CORO_PARAM) {
CORO_BEGIN_CODE(_ctx);
- assert(savedSceneCount < MAX_NEST); // nesting limit reached
+ assert(g_savedSceneCount < MAX_NEST); // nesting limit reached
// Don't save the same thing multiple times!
// FIXME/TODO: Maybe this can be changed to an assert?
- if (savedSceneCount && ssData[savedSceneCount-1].SavedSceneHandle == GetSceneHandle())
+ if (g_savedSceneCount && g_ssData[g_savedSceneCount-1].SavedSceneHandle == GetSceneHandle())
CORO_KILL_SELF();
- DoSaveScene(&ssData[savedSceneCount++]);
+ DoSaveScene(&g_ssData[g_savedSceneCount++]);
CORO_END_CODE;
}
diff --git a/engines/tinsel/scene.cpp b/engines/tinsel/scene.cpp
index 89b0da7d65..f635ce13a3 100644
--- a/engines/tinsel/scene.cpp
+++ b/engines/tinsel/scene.cpp
@@ -107,15 +107,15 @@ struct ENTRANCE_STRUC {
// FIXME: Avoid non-const global vars
#ifdef DEBUG
-static bool ShowPosition = false; // Set when showpos() has been called
+static bool g_ShowPosition = false; // Set when showpos() has been called
#endif
-int sceneCtr = 0;
-static int initialMyEscape;
+int g_sceneCtr = 0;
+static int g_initialMyEscape;
-static SCNHANDLE SceneHandle = 0; // Current scene handle - stored in case of Save_Scene()
+static SCNHANDLE g_SceneHandle = 0; // Current scene handle - stored in case of Save_Scene()
-SCENE_STRUC tempStruc;
+SCENE_STRUC g_tempStruc;
struct TP_INIT {
SCNHANDLE hTinselCode; // Code
@@ -128,18 +128,18 @@ const SCENE_STRUC *GetSceneStruc(const byte *pStruc) {
// Copy appropriate fields into tempStruc, and return a pointer to it
const byte *p = pStruc;
- memset(&tempStruc, 0, sizeof(SCENE_STRUC));
-
- tempStruc.numEntrance = READ_UINT32(p); p += sizeof(uint32);
- tempStruc.numPoly = READ_UINT32(p); p += sizeof(uint32);
- tempStruc.numTaggedActor = READ_UINT32(p); p += sizeof(uint32);
- tempStruc.defRefer = READ_UINT32(p); p += sizeof(uint32);
- tempStruc.hSceneScript = READ_UINT32(p); p += sizeof(uint32);
- tempStruc.hEntrance = READ_UINT32(p); p += sizeof(uint32);
- tempStruc.hPoly = READ_UINT32(p); p += sizeof(uint32);
- tempStruc.hTaggedActor = READ_UINT32(p); p += sizeof(uint32);
-
- return &tempStruc;
+ memset(&g_tempStruc, 0, sizeof(SCENE_STRUC));
+
+ g_tempStruc.numEntrance = READ_UINT32(p); p += sizeof(uint32);
+ g_tempStruc.numPoly = READ_UINT32(p); p += sizeof(uint32);
+ g_tempStruc.numTaggedActor = READ_UINT32(p); p += sizeof(uint32);
+ g_tempStruc.defRefer = READ_UINT32(p); p += sizeof(uint32);
+ g_tempStruc.hSceneScript = READ_UINT32(p); p += sizeof(uint32);
+ g_tempStruc.hEntrance = READ_UINT32(p); p += sizeof(uint32);
+ g_tempStruc.hPoly = READ_UINT32(p); p += sizeof(uint32);
+ g_tempStruc.hTaggedActor = READ_UINT32(p); p += sizeof(uint32);
+
+ return &g_tempStruc;
}
@@ -157,8 +157,8 @@ static void SceneTinselProcess(CORO_PARAM, const void *param) {
CORO_BEGIN_CODE(_ctx);
// The following myEscape value setting is used for enabling title screen skipping in DW1
- if (TinselV1 && (sceneCtr == 1)) initialMyEscape = GetEscEvents();
- _ctx->myEscape = (TinselV1 && (sceneCtr < 4)) ? initialMyEscape : 0;
+ if (TinselV1 && (g_sceneCtr == 1)) g_initialMyEscape = GetEscEvents();
+ _ctx->myEscape = (TinselV1 && (g_sceneCtr < 4)) ? g_initialMyEscape : 0;
// get the stuff copied to process when it was created
_ctx->pInit = (const TP_INIT *)param;
@@ -184,8 +184,8 @@ static void SceneTinselProcess(CORO_PARAM, const void *param) {
void SendSceneTinselProcess(TINSEL_EVENT event) {
SCENE_STRUC *ss;
- if (SceneHandle != (SCNHANDLE)NULL) {
- ss = (SCENE_STRUC *) FindChunk(SceneHandle, CHUNK_SCENE);
+ if (g_SceneHandle != (SCNHANDLE)NULL) {
+ ss = (SCENE_STRUC *) FindChunk(g_SceneHandle, CHUNK_SCENE);
if (ss->hSceneScript) {
TP_INIT init;
@@ -214,9 +214,9 @@ static void LoadScene(SCNHANDLE scene, int entry) {
const ENTRANCE_STRUC *es;
// Scene handle
- SceneHandle = scene; // Save scene handle in case of Save_Scene()
- LockMem(SceneHandle); // Make sure scene is loaded
- LockScene(SceneHandle); // Prevent current scene from being discarded
+ g_SceneHandle = scene; // Save scene handle in case of Save_Scene()
+ LockMem(g_SceneHandle); // Make sure scene is loaded
+ LockScene(g_SceneHandle); // Prevent current scene from being discarded
if (TinselV2) {
// CdPlay() stuff
@@ -307,9 +307,9 @@ static void LoadScene(SCNHANDLE scene, int entry) {
* Wrap up the last scene.
*/
void EndScene() {
- if (SceneHandle != 0) {
- UnlockScene(SceneHandle);
- SceneHandle = 0;
+ if (g_SceneHandle != 0) {
+ UnlockScene(g_SceneHandle);
+ g_SceneHandle = 0;
}
KillInventory(); // Close down any open inventory
@@ -409,7 +409,7 @@ void PrimeScene() {
g_scheduler->createProcess(PID_SCROLL, EffectPolyProcess, NULL, 0);
#ifdef DEBUG
- if (ShowPosition)
+ if (g_ShowPosition)
g_scheduler->createProcess(PID_POSITION, CursorPositionProcess, NULL, 0);
#endif
@@ -445,7 +445,7 @@ void StartNewScene(SCNHANDLE scene, int entry) {
*/
void setshowpos() {
- ShowPosition = true;
+ g_ShowPosition = true;
}
#endif
@@ -454,7 +454,7 @@ void setshowpos() {
*/
SCNHANDLE GetSceneHandle() {
- return SceneHandle;
+ return g_SceneHandle;
}
/**
diff --git a/engines/tinsel/sched.cpp b/engines/tinsel/sched.cpp
index d6cd806eb2..343758d924 100644
--- a/engines/tinsel/sched.cpp
+++ b/engines/tinsel/sched.cpp
@@ -47,11 +47,11 @@ struct PROCESS_STRUC {
// FIXME: Avoid non-const global vars
-static uint32 numSceneProcess;
-static SCNHANDLE hSceneProcess;
+static uint32 g_numSceneProcess;
+static SCNHANDLE g_hSceneProcess;
-static uint32 numGlobalProcess;
-static PROCESS_STRUC *pGlobalProcess;
+static uint32 g_numGlobalProcess;
+static PROCESS_STRUC *g_pGlobalProcess;
//--------------------- FUNCTIONS ------------------------
@@ -574,8 +574,8 @@ void RestoreSceneProcess(INT_CONTEXT *pic) {
uint32 i;
PROCESS_STRUC *pStruc;
- pStruc = (PROCESS_STRUC *)LockMem(hSceneProcess);
- for (i = 0; i < numSceneProcess; i++) {
+ pStruc = (PROCESS_STRUC *)LockMem(g_hSceneProcess);
+ for (i = 0; i < g_numSceneProcess; i++) {
if (FROM_LE_32(pStruc[i].hProcessCode) == pic->hCode) {
g_scheduler->createProcess(PID_PROCESS + i, RestoredProcessProcess,
&pic, sizeof(pic));
@@ -583,7 +583,7 @@ void RestoreSceneProcess(INT_CONTEXT *pic) {
}
}
- assert(i < numSceneProcess);
+ assert(i < g_numSceneProcess);
}
/**
@@ -602,8 +602,8 @@ void SceneProcessEvent(CORO_PARAM, uint32 procID, TINSEL_EVENT event, bool bWait
CORO_BEGIN_CODE(_ctx);
- _ctx->pStruc = (PROCESS_STRUC *)LockMem(hSceneProcess);
- for (i = 0; i < numSceneProcess; i++) {
+ _ctx->pStruc = (PROCESS_STRUC *)LockMem(g_hSceneProcess);
+ for (i = 0; i < g_numSceneProcess; i++) {
if (FROM_LE_32(_ctx->pStruc[i].processId) == procID) {
assert(_ctx->pStruc[i].hProcessCode); // Must have some code to run
@@ -624,7 +624,7 @@ void SceneProcessEvent(CORO_PARAM, uint32 procID, TINSEL_EVENT event, bool bWait
}
}
- if (i == numSceneProcess)
+ if (i == g_numSceneProcess)
return;
if (bWait) {
@@ -641,8 +641,8 @@ void KillSceneProcess(uint32 procID) {
uint32 i; // Loop counter
PROCESS_STRUC *pStruc;
- pStruc = (PROCESS_STRUC *) LockMem(hSceneProcess);
- for (i = 0; i < numSceneProcess; i++) {
+ pStruc = (PROCESS_STRUC *) LockMem(g_hSceneProcess);
+ for (i = 0; i < g_numSceneProcess; i++) {
if (FROM_LE_32(pStruc[i].processId) == procID) {
g_scheduler->killMatchingProcess(PID_PROCESS + i, -1);
break;
@@ -654,8 +654,8 @@ void KillSceneProcess(uint32 procID) {
* Register the scene processes in a scene.
*/
void SceneProcesses(uint32 numProcess, SCNHANDLE hProcess) {
- numSceneProcess = numProcess;
- hSceneProcess = hProcess;
+ g_numSceneProcess = numProcess;
+ g_hSceneProcess = hProcess;
}
@@ -669,15 +669,15 @@ void SceneProcesses(uint32 numProcess, SCNHANDLE hProcess) {
void RestoreGlobalProcess(INT_CONTEXT *pic) {
uint32 i; // Loop counter
- for (i = 0; i < numGlobalProcess; i++) {
- if (pGlobalProcess[i].hProcessCode == pic->hCode) {
+ for (i = 0; i < g_numGlobalProcess; i++) {
+ if (g_pGlobalProcess[i].hProcessCode == pic->hCode) {
g_scheduler->createProcess(PID_GPROCESS + i, RestoredProcessProcess,
&pic, sizeof(pic));
break;
}
}
- assert(i < numGlobalProcess);
+ assert(i < g_numGlobalProcess);
}
/**
@@ -685,7 +685,7 @@ void RestoreGlobalProcess(INT_CONTEXT *pic) {
*/
void KillGlobalProcesses() {
- for (uint32 i = 0; i < numGlobalProcess; ++i) {
+ for (uint32 i = 0; i < g_numGlobalProcess; ++i) {
g_scheduler->killMatchingProcess(PID_GPROCESS + i, -1);
}
}
@@ -706,12 +706,12 @@ bool GlobalProcessEvent(CORO_PARAM, uint32 procID, TINSEL_EVENT event, bool bWai
uint32 i; // Loop counter
_ctx->pProc = NULL;
- for (i = 0; i < numGlobalProcess; ++i) {
- if (pGlobalProcess[i].processId == procID) {
- assert(pGlobalProcess[i].hProcessCode); // Must have some code to run
+ for (i = 0; i < g_numGlobalProcess; ++i) {
+ if (g_pGlobalProcess[i].processId == procID) {
+ assert(g_pGlobalProcess[i].hProcessCode); // Must have some code to run
_ctx->pic = InitInterpretContext(GS_GPROCESS,
- pGlobalProcess[i].hProcessCode,
+ g_pGlobalProcess[i].hProcessCode,
event,
NOPOLY, // No polygon
0, // No actor
@@ -728,7 +728,7 @@ bool GlobalProcessEvent(CORO_PARAM, uint32 procID, TINSEL_EVENT event, bool bWai
}
}
- if ((i == numGlobalProcess) || (_ctx->pic == NULL))
+ if ((i == g_numGlobalProcess) || (_ctx->pic == NULL))
result = false;
else if (bWait)
CORO_INVOKE_ARGS_V(WaitInterpret, false, (CORO_SUBCTX, _ctx->pProc, &result));
@@ -743,8 +743,8 @@ bool GlobalProcessEvent(CORO_PARAM, uint32 procID, TINSEL_EVENT event, bool bWai
void xKillGlobalProcess(uint32 procID) {
uint32 i; // Loop counter
- for (i = 0; i < numGlobalProcess; ++i) {
- if (pGlobalProcess[i].processId == procID) {
+ for (i = 0; i < g_numGlobalProcess; ++i) {
+ if (g_pGlobalProcess[i].processId == procID) {
g_scheduler->killMatchingProcess(PID_GPROCESS + i, -1);
break;
}
@@ -755,13 +755,13 @@ void xKillGlobalProcess(uint32 procID) {
* Register the global processes list
*/
void GlobalProcesses(uint32 numProcess, byte *pProcess) {
- pGlobalProcess = new PROCESS_STRUC[numProcess];
- numGlobalProcess = numProcess;
+ g_pGlobalProcess = new PROCESS_STRUC[numProcess];
+ g_numGlobalProcess = numProcess;
byte *p = pProcess;
for (uint i = 0; i < numProcess; ++i, p += 8) {
- pGlobalProcess[i].processId = READ_LE_UINT32(p);
- pGlobalProcess[i].hProcessCode = READ_LE_UINT32(p + 4);
+ g_pGlobalProcess[i].processId = READ_LE_UINT32(p);
+ g_pGlobalProcess[i].hProcessCode = READ_LE_UINT32(p + 4);
}
}
@@ -769,9 +769,9 @@ void GlobalProcesses(uint32 numProcess, byte *pProcess) {
* Frees the global processes list
*/
void FreeGlobalProcesses() {
- delete[] pGlobalProcess;
- pGlobalProcess = 0;
- numGlobalProcess = 0;
+ delete[] g_pGlobalProcess;
+ g_pGlobalProcess = 0;
+ g_numGlobalProcess = 0;
}
} // End of namespace Tinsel
diff --git a/engines/tinsel/scroll.cpp b/engines/tinsel/scroll.cpp
index d75e649be3..0a6a281d35 100644
--- a/engines/tinsel/scroll.cpp
+++ b/engines/tinsel/scroll.cpp
@@ -49,14 +49,14 @@ namespace Tinsel {
// FIXME: Avoid non-const global vars
-static int LeftScroll = 0, DownScroll = 0; // Number of iterations outstanding
+static int g_LeftScroll = 0, g_DownScroll = 0; // Number of iterations outstanding
-static int scrollActor = 0;
-static PMOVER pScrollMover = 0;
-static int oldx = 0, oldy = 0;
+static int g_scrollActor = 0;
+static PMOVER g_pScrollMover = 0;
+static int g_oldx = 0, g_oldy = 0;
/** Boundaries and numbers of boundaries */
-static SCROLLDATA sd = {
+static SCROLLDATA g_sd = {
{
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0},
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}
@@ -77,28 +77,28 @@ static SCROLLDATA sd = {
0
};
-static int ImageH = 0, ImageW = 0;
+static int g_ImageH = 0, g_ImageW = 0;
-static bool ScrollCursor = 0; // If a TAG or EXIT polygon is clicked on,
+static bool g_ScrollCursor = 0; // If a TAG or EXIT polygon is clicked on,
// the cursor is kept over that polygon
// whilst scrolling
-static int scrollPixelsX = SCROLLPIXELS;
-static int scrollPixelsY = SCROLLPIXELS;
+static int g_scrollPixelsX = SCROLLPIXELS;
+static int g_scrollPixelsY = SCROLLPIXELS;
/**
* Reset the ScrollCursor flag
*/
void DontScrollCursor() {
- ScrollCursor = false;
+ g_ScrollCursor = false;
}
/**
* Set the ScrollCursor flag
*/
void DoScrollCursor() {
- ScrollCursor = true;
+ g_ScrollCursor = true;
}
/**
@@ -107,20 +107,20 @@ void DoScrollCursor() {
void SetNoScroll(int x1, int y1, int x2, int y2) {
if (x1 == x2) {
/* Vertical line */
- assert(sd.NumNoH < MAX_HNOSCROLL);
+ assert(g_sd.NumNoH < MAX_HNOSCROLL);
- sd.NoHScroll[sd.NumNoH].ln = x1; // X pos of vertical line
- sd.NoHScroll[sd.NumNoH].c1 = y1;
- sd.NoHScroll[sd.NumNoH].c2 = y2;
- sd.NumNoH++;
+ g_sd.NoHScroll[g_sd.NumNoH].ln = x1; // X pos of vertical line
+ g_sd.NoHScroll[g_sd.NumNoH].c1 = y1;
+ g_sd.NoHScroll[g_sd.NumNoH].c2 = y2;
+ g_sd.NumNoH++;
} else if (y1 == y2) {
/* Horizontal line */
- assert(sd.NumNoV < MAX_VNOSCROLL);
+ assert(g_sd.NumNoV < MAX_VNOSCROLL);
- sd.NoVScroll[sd.NumNoV].ln = y1; // Y pos of horizontal line
- sd.NoVScroll[sd.NumNoV].c1 = x1;
- sd.NoVScroll[sd.NumNoV].c2 = x2;
- sd.NumNoV++;
+ g_sd.NoVScroll[g_sd.NumNoV].ln = y1; // Y pos of horizontal line
+ g_sd.NoVScroll[g_sd.NumNoV].c1 = x1;
+ g_sd.NoVScroll[g_sd.NumNoV].c2 = x2;
+ g_sd.NumNoV++;
} else {
/* No-scroll lines must be horizontal or vertical */
}
@@ -144,21 +144,21 @@ static void NeedScroll(int direction) {
BottomLine = Toffset + (SCREEN_HEIGHT - 1);
RightCol = Loffset + (SCREEN_WIDTH - 1);
- for (i = 0; i < sd.NumNoH; i++) {
- if (RightCol >= sd.NoHScroll[i].ln - 1 && RightCol <= sd.NoHScroll[i].ln + 1 &&
- ((sd.NoHScroll[i].c1 >= Toffset && sd.NoHScroll[i].c1 <= BottomLine) ||
- (sd.NoHScroll[i].c2 >= Toffset && sd.NoHScroll[i].c2 <= BottomLine) ||
- (sd.NoHScroll[i].c1 < Toffset && sd.NoHScroll[i].c2 > BottomLine)))
+ for (i = 0; i < g_sd.NumNoH; i++) {
+ if (RightCol >= g_sd.NoHScroll[i].ln - 1 && RightCol <= g_sd.NoHScroll[i].ln + 1 &&
+ ((g_sd.NoHScroll[i].c1 >= Toffset && g_sd.NoHScroll[i].c1 <= BottomLine) ||
+ (g_sd.NoHScroll[i].c2 >= Toffset && g_sd.NoHScroll[i].c2 <= BottomLine) ||
+ (g_sd.NoHScroll[i].c1 < Toffset && g_sd.NoHScroll[i].c2 > BottomLine)))
return;
}
- if (LeftScroll <= 0) {
+ if (g_LeftScroll <= 0) {
if (TinselV2) {
- scrollPixelsX = sd.xSpeed;
- LeftScroll += sd.xDistance;
+ g_scrollPixelsX = g_sd.xSpeed;
+ g_LeftScroll += g_sd.xDistance;
} else {
- scrollPixelsX = SCROLLPIXELS;
- LeftScroll = RLSCROLL;
+ g_scrollPixelsX = SCROLLPIXELS;
+ g_LeftScroll = RLSCROLL;
}
}
break;
@@ -167,21 +167,21 @@ static void NeedScroll(int direction) {
BottomLine = Toffset + (SCREEN_HEIGHT - 1);
- for (i = 0; i < sd.NumNoH; i++) {
- if (Loffset >= sd.NoHScroll[i].ln - 1 && Loffset <= sd.NoHScroll[i].ln + 1 &&
- ((sd.NoHScroll[i].c1 >= Toffset && sd.NoHScroll[i].c1 <= BottomLine) ||
- (sd.NoHScroll[i].c2 >= Toffset && sd.NoHScroll[i].c2 <= BottomLine) ||
- (sd.NoHScroll[i].c1 < Toffset && sd.NoHScroll[i].c2 > BottomLine)))
+ for (i = 0; i < g_sd.NumNoH; i++) {
+ if (Loffset >= g_sd.NoHScroll[i].ln - 1 && Loffset <= g_sd.NoHScroll[i].ln + 1 &&
+ ((g_sd.NoHScroll[i].c1 >= Toffset && g_sd.NoHScroll[i].c1 <= BottomLine) ||
+ (g_sd.NoHScroll[i].c2 >= Toffset && g_sd.NoHScroll[i].c2 <= BottomLine) ||
+ (g_sd.NoHScroll[i].c1 < Toffset && g_sd.NoHScroll[i].c2 > BottomLine)))
return;
}
- if (LeftScroll >= 0) {
+ if (g_LeftScroll >= 0) {
if (TinselV2) {
- scrollPixelsX = sd.xSpeed;
- LeftScroll -= sd.xDistance;
+ g_scrollPixelsX = g_sd.xSpeed;
+ g_LeftScroll -= g_sd.xDistance;
} else {
- scrollPixelsX = SCROLLPIXELS;
- LeftScroll = -RLSCROLL;
+ g_scrollPixelsX = SCROLLPIXELS;
+ g_LeftScroll = -RLSCROLL;
}
}
break;
@@ -191,21 +191,21 @@ static void NeedScroll(int direction) {
BottomLine = Toffset + (SCREEN_HEIGHT - 1);
RightCol = Loffset + (SCREEN_WIDTH - 1);
- for (i = 0; i < sd.NumNoV; i++) {
- if ((BottomLine >= sd.NoVScroll[i].ln - 1 && BottomLine <= sd.NoVScroll[i].ln + 1) &&
- ((sd.NoVScroll[i].c1 >= Loffset && sd.NoVScroll[i].c1 <= RightCol) ||
- (sd.NoVScroll[i].c2 >= Loffset && sd.NoVScroll[i].c2 <= RightCol) ||
- (sd.NoVScroll[i].c1 < Loffset && sd.NoVScroll[i].c2 > RightCol)))
+ for (i = 0; i < g_sd.NumNoV; i++) {
+ if ((BottomLine >= g_sd.NoVScroll[i].ln - 1 && BottomLine <= g_sd.NoVScroll[i].ln + 1) &&
+ ((g_sd.NoVScroll[i].c1 >= Loffset && g_sd.NoVScroll[i].c1 <= RightCol) ||
+ (g_sd.NoVScroll[i].c2 >= Loffset && g_sd.NoVScroll[i].c2 <= RightCol) ||
+ (g_sd.NoVScroll[i].c1 < Loffset && g_sd.NoVScroll[i].c2 > RightCol)))
return;
}
- if (DownScroll <= 0) {
+ if (g_DownScroll <= 0) {
if (TinselV2) {
- scrollPixelsY = sd.ySpeed;
- DownScroll += sd.yDistance;
+ g_scrollPixelsY = g_sd.ySpeed;
+ g_DownScroll += g_sd.yDistance;
} else {
- scrollPixelsY = SCROLLPIXELS;
- DownScroll = UDSCROLL;
+ g_scrollPixelsY = SCROLLPIXELS;
+ g_DownScroll = UDSCROLL;
}
}
break;
@@ -214,21 +214,21 @@ static void NeedScroll(int direction) {
RightCol = Loffset + (SCREEN_WIDTH - 1);
- for (i = 0; i < sd.NumNoV; i++) {
- if (Toffset >= sd.NoVScroll[i].ln - 1 && Toffset <= sd.NoVScroll[i].ln + 1 &&
- ((sd.NoVScroll[i].c1 >= Loffset && sd.NoVScroll[i].c1 <= RightCol) ||
- (sd.NoVScroll[i].c2 >= Loffset && sd.NoVScroll[i].c2 <= RightCol) ||
- (sd.NoVScroll[i].c1 < Loffset && sd.NoVScroll[i].c2 > RightCol)))
+ for (i = 0; i < g_sd.NumNoV; i++) {
+ if (Toffset >= g_sd.NoVScroll[i].ln - 1 && Toffset <= g_sd.NoVScroll[i].ln + 1 &&
+ ((g_sd.NoVScroll[i].c1 >= Loffset && g_sd.NoVScroll[i].c1 <= RightCol) ||
+ (g_sd.NoVScroll[i].c2 >= Loffset && g_sd.NoVScroll[i].c2 <= RightCol) ||
+ (g_sd.NoVScroll[i].c1 < Loffset && g_sd.NoVScroll[i].c2 > RightCol)))
return;
}
- if (DownScroll >= 0) {
+ if (g_DownScroll >= 0) {
if (TinselV2) {
- scrollPixelsY = sd.ySpeed;
- DownScroll -= sd.yDistance;
+ g_scrollPixelsY = g_sd.ySpeed;
+ g_DownScroll -= g_sd.yDistance;
} else {
- scrollPixelsY = SCROLLPIXELS;
- DownScroll = -UDSCROLL;
+ g_scrollPixelsY = SCROLLPIXELS;
+ g_DownScroll = -UDSCROLL;
}
}
break;
@@ -249,39 +249,39 @@ static void ScrollImage() {
/*
* Keeping cursor on a tag?
*/
- if (ScrollCursor) {
+ if (g_ScrollCursor) {
GetCursorXYNoWait(&curX, &curY, true);
if (InPolygon(curX, curY, TAG) != NOPOLY || InPolygon(curX, curY, EXIT) != NOPOLY) {
OldLoffset = Loffset;
OldToffset = Toffset;
} else
- ScrollCursor = false;
+ g_ScrollCursor = false;
}
/*
* Horizontal scrolling
*/
- if (LeftScroll > 0) {
- LeftScroll -= scrollPixelsX;
- if (LeftScroll < 0) {
- Loffset += LeftScroll;
- LeftScroll = 0;
+ if (g_LeftScroll > 0) {
+ g_LeftScroll -= g_scrollPixelsX;
+ if (g_LeftScroll < 0) {
+ Loffset += g_LeftScroll;
+ g_LeftScroll = 0;
}
- Loffset += scrollPixelsX; // Move right
- if (Loffset > ImageW - SCREEN_WIDTH)
- Loffset = ImageW - SCREEN_WIDTH;// Now at extreme right
+ Loffset += g_scrollPixelsX; // Move right
+ if (Loffset > g_ImageW - SCREEN_WIDTH)
+ Loffset = g_ImageW - SCREEN_WIDTH;// Now at extreme right
/*** New feature to prop up rickety scroll boundaries ***/
if (TinselV2 && SysVar(SV_MaximumXoffset) && (Loffset > SysVar(SV_MaximumXoffset)))
Loffset = SysVar(SV_MaximumXoffset);
- } else if (LeftScroll < 0) {
- LeftScroll += scrollPixelsX;
- if (LeftScroll > 0) {
- Loffset += LeftScroll;
- LeftScroll = 0;
+ } else if (g_LeftScroll < 0) {
+ g_LeftScroll += g_scrollPixelsX;
+ if (g_LeftScroll > 0) {
+ Loffset += g_LeftScroll;
+ g_LeftScroll = 0;
}
- Loffset -= scrollPixelsX; // Move left
+ Loffset -= g_scrollPixelsX; // Move left
if (Loffset < 0)
Loffset = 0; // Now at extreme left
@@ -293,28 +293,28 @@ static void ScrollImage() {
/*
* Vertical scrolling
*/
- if (DownScroll > 0) {
- DownScroll -= scrollPixelsY;
- if (DownScroll < 0) {
- Toffset += DownScroll;
- DownScroll = 0;
+ if (g_DownScroll > 0) {
+ g_DownScroll -= g_scrollPixelsY;
+ if (g_DownScroll < 0) {
+ Toffset += g_DownScroll;
+ g_DownScroll = 0;
}
- Toffset += scrollPixelsY; // Move down
+ Toffset += g_scrollPixelsY; // Move down
- if (Toffset > ImageH - SCREEN_HEIGHT)
- Toffset = ImageH - SCREEN_HEIGHT;// Now at extreme bottom
+ if (Toffset > g_ImageH - SCREEN_HEIGHT)
+ Toffset = g_ImageH - SCREEN_HEIGHT;// Now at extreme bottom
/*** New feature to prop up rickety scroll boundaries ***/
if (TinselV2 && SysVar(SV_MaximumYoffset) && Toffset > SysVar(SV_MaximumYoffset))
Toffset = SysVar(SV_MaximumYoffset);
- } else if (DownScroll < 0) {
- DownScroll += scrollPixelsY;
- if (DownScroll > 0) {
- Toffset += DownScroll;
- DownScroll = 0;
+ } else if (g_DownScroll < 0) {
+ g_DownScroll += g_scrollPixelsY;
+ if (g_DownScroll > 0) {
+ Toffset += g_DownScroll;
+ g_DownScroll = 0;
}
- Toffset -= scrollPixelsY; // Move up
+ Toffset -= g_scrollPixelsY; // Move up
if (Toffset < 0)
Toffset = 0; // Now at extreme top
@@ -327,7 +327,7 @@ static void ScrollImage() {
/*
* Move cursor if keeping cursor on a tag.
*/
- if (ScrollCursor)
+ if (g_ScrollCursor)
AdjustCursorXY(OldLoffset - Loffset, OldToffset - Toffset);
PlayfieldSetPos(FIELD_WORLD, Loffset, Toffset);
@@ -345,12 +345,12 @@ static void MonitorScroll() {
/*
* Only do it if the actor is there and is visible
*/
- if (!pScrollMover || MoverHidden(pScrollMover) || !MoverIs(pScrollMover))
+ if (!g_pScrollMover || MoverHidden(g_pScrollMover) || !MoverIs(g_pScrollMover))
return;
- GetActorPos(scrollActor, &newx, &newy);
+ GetActorPos(g_scrollActor, &newx, &newy);
- if (oldx == newx && oldy == newy)
+ if (g_oldx == newx && g_oldy == newy)
return;
PlayfieldGetPos(FIELD_WORLD, &Loffset, &Toffset);
@@ -358,49 +358,49 @@ static void MonitorScroll() {
/*
* Approaching right side or left side of the screen?
*/
- if (newx > Loffset+SCREEN_WIDTH - RLDISTANCE && Loffset < ImageW - SCREEN_WIDTH) {
- if (newx > oldx)
+ if (newx > Loffset+SCREEN_WIDTH - RLDISTANCE && Loffset < g_ImageW - SCREEN_WIDTH) {
+ if (newx > g_oldx)
NeedScroll(LEFT);
} else if (newx < Loffset + RLDISTANCE && Loffset) {
- if (newx < oldx)
+ if (newx < g_oldx)
NeedScroll(RIGHT);
}
/*
* Approaching bottom or top of the screen?
*/
- if (newy > Toffset+SCREEN_HEIGHT-DDISTANCE && Toffset < ImageH-SCREEN_HEIGHT) {
- if (newy > oldy)
+ if (newy > Toffset+SCREEN_HEIGHT-DDISTANCE && Toffset < g_ImageH-SCREEN_HEIGHT) {
+ if (newy > g_oldy)
NeedScroll(UP);
- } else if (Toffset && newy < Toffset + UDISTANCE + GetActorBottom(scrollActor) - GetActorTop(scrollActor)) {
- if (newy < oldy)
+ } else if (Toffset && newy < Toffset + UDISTANCE + GetActorBottom(g_scrollActor) - GetActorTop(g_scrollActor)) {
+ if (newy < g_oldy)
NeedScroll(DOWN);
}
- oldx = newx;
- oldy = newy;
+ g_oldx = newx;
+ g_oldy = newy;
}
static void RestoreScrollDefaults() {
- sd.xTrigger = SysVar(SV_SCROLL_XTRIGGER);
- sd.xDistance = SysVar(SV_SCROLL_XDISTANCE);
- sd.xSpeed = SysVar(SV_SCROLL_XSPEED);
- sd.yTriggerTop = SysVar(SV_SCROLL_YTRIGGERTOP);
- sd.yTriggerBottom= SysVar(SV_SCROLL_YTRIGGERBOT);
- sd.yDistance = SysVar(SV_SCROLL_YDISTANCE);
- sd.ySpeed = SysVar(SV_SCROLL_YSPEED);
+ g_sd.xTrigger = SysVar(SV_SCROLL_XTRIGGER);
+ g_sd.xDistance = SysVar(SV_SCROLL_XDISTANCE);
+ g_sd.xSpeed = SysVar(SV_SCROLL_XSPEED);
+ g_sd.yTriggerTop = SysVar(SV_SCROLL_YTRIGGERTOP);
+ g_sd.yTriggerBottom= SysVar(SV_SCROLL_YTRIGGERBOT);
+ g_sd.yDistance = SysVar(SV_SCROLL_YDISTANCE);
+ g_sd.ySpeed = SysVar(SV_SCROLL_YSPEED);
}
/**
* Does the obvious - called at the end of a scene.
*/
void DropScroll() {
- sd.NumNoH = sd.NumNoV = 0;
+ g_sd.NumNoH = g_sd.NumNoV = 0;
if (TinselV2) {
- LeftScroll = DownScroll = 0; // No iterations outstanding
- oldx = oldy = 0;
- scrollPixelsX = sd.xSpeed;
- scrollPixelsY = sd.ySpeed;
+ g_LeftScroll = g_DownScroll = 0; // No iterations outstanding
+ g_oldx = g_oldy = 0;
+ g_scrollPixelsX = g_sd.xSpeed;
+ g_scrollPixelsY = g_sd.ySpeed;
RestoreScrollDefaults();
}
}
@@ -420,28 +420,28 @@ void ScrollProcess(CORO_PARAM, const void *) {
while (!GetBgObject())
CORO_SLEEP(1);
- ImageH = BgHeight(); // Dimensions
- ImageW = BgWidth(); // of this scene.
+ g_ImageH = BgHeight(); // Dimensions
+ g_ImageW = BgWidth(); // of this scene.
// Give up if there'll be no purpose in this process
- if (ImageW == SCREEN_WIDTH && ImageH == SCREEN_HEIGHT)
+ if (g_ImageW == SCREEN_WIDTH && g_ImageH == SCREEN_HEIGHT)
CORO_KILL_SELF();
if (!TinselV2) {
- LeftScroll = DownScroll = 0; // No iterations outstanding
- oldx = oldy = 0;
- scrollPixelsX = scrollPixelsY = SCROLLPIXELS;
+ g_LeftScroll = g_DownScroll = 0; // No iterations outstanding
+ g_oldx = g_oldy = 0;
+ g_scrollPixelsX = g_scrollPixelsY = SCROLLPIXELS;
}
- if (!scrollActor)
- scrollActor = GetLeadId();
+ if (!g_scrollActor)
+ g_scrollActor = GetLeadId();
- pScrollMover = GetMover(scrollActor);
+ g_pScrollMover = GetMover(g_scrollActor);
while (1) {
MonitorScroll(); // Set scroll requirement
- if (LeftScroll || DownScroll) // Scroll if required
+ if (g_LeftScroll || g_DownScroll) // Scroll if required
ScrollImage();
CORO_SLEEP(1); // allow re-scheduling
@@ -454,11 +454,11 @@ void ScrollProcess(CORO_PARAM, const void *) {
* Change which actor the camera is following.
*/
void ScrollFocus(int ano) {
- if (scrollActor != ano) {
- oldx = oldy = 0;
- scrollActor = ano;
+ if (g_scrollActor != ano) {
+ g_oldx = g_oldy = 0;
+ g_scrollActor = ano;
- pScrollMover = ano ? GetMover(scrollActor) : NULL;
+ g_pScrollMover = ano ? GetMover(g_scrollActor) : NULL;
}
}
@@ -466,7 +466,7 @@ void ScrollFocus(int ano) {
* Returns the actor which the camera is following
*/
int GetScrollFocus() {
- return scrollActor;
+ return g_scrollActor;
}
@@ -476,29 +476,29 @@ int GetScrollFocus() {
void ScrollTo(int x, int y, int xIter, int yIter) {
int Loffset, Toffset; // for background offsets
- scrollPixelsX = xIter != 0 ? xIter : (TinselV2 ? sd.xSpeed : SCROLLPIXELS);
- scrollPixelsY = yIter != 0 ? yIter : (TinselV2 ? sd.ySpeed : SCROLLPIXELS);
+ g_scrollPixelsX = xIter != 0 ? xIter : (TinselV2 ? g_sd.xSpeed : SCROLLPIXELS);
+ g_scrollPixelsY = yIter != 0 ? yIter : (TinselV2 ? g_sd.ySpeed : SCROLLPIXELS);
PlayfieldGetPos(FIELD_WORLD, &Loffset, &Toffset); // get background offsets
- LeftScroll = x - Loffset;
- DownScroll = y - Toffset;
+ g_LeftScroll = x - Loffset;
+ g_DownScroll = y - Toffset;
}
/**
* Kill of any current scroll.
*/
void KillScroll() {
- LeftScroll = DownScroll = 0;
+ g_LeftScroll = g_DownScroll = 0;
}
void GetNoScrollData(SCROLLDATA *ssd) {
- memcpy(ssd, &sd, sizeof(SCROLLDATA));
+ memcpy(ssd, &g_sd, sizeof(SCROLLDATA));
}
void RestoreNoScrollData(SCROLLDATA *ssd) {
- memcpy(&sd, ssd, sizeof(SCROLLDATA));
+ memcpy(&g_sd, ssd, sizeof(SCROLLDATA));
}
/**
@@ -512,24 +512,24 @@ void SetScrollParameters(int xTrigger, int xDistance, int xSpeed, int yTriggerTo
RestoreScrollDefaults();
} else {
if (xTrigger)
- sd.xTrigger = xTrigger;
+ g_sd.xTrigger = xTrigger;
if (xDistance)
- sd.xDistance = xDistance;
+ g_sd.xDistance = xDistance;
if (xSpeed)
- sd.xSpeed = xSpeed;
+ g_sd.xSpeed = xSpeed;
if (yTriggerTop)
- sd.yTriggerTop = yTriggerTop;
+ g_sd.yTriggerTop = yTriggerTop;
if (yTriggerBottom)
- sd.yTriggerBottom = yTriggerBottom;
+ g_sd.yTriggerBottom = yTriggerBottom;
if (yDistance)
- sd.yDistance = yDistance;
+ g_sd.yDistance = yDistance;
if (ySpeed)
- sd.ySpeed = ySpeed;
+ g_sd.ySpeed = ySpeed;
}
}
bool IsScrolling() {
- return (LeftScroll || DownScroll);
+ return (g_LeftScroll || g_DownScroll);
}
} // End of namespace Tinsel
diff --git a/engines/tinsel/scroll.h b/engines/tinsel/scroll.h
index 62562b20b2..bcdc15cda6 100644
--- a/engines/tinsel/scroll.h
+++ b/engines/tinsel/scroll.h
@@ -28,9 +28,9 @@ namespace Tinsel {
#define SCROLLPIXELS 8 // Number of pixels to scroll per iteration
// Distance from edge that triggers a scroll
-#define RLDISTANCE (TinselV2 ? sd.xTrigger : 50)
-#define UDISTANCE (TinselV2 ? sd.yTriggerTop : 20)
-#define DDISTANCE (TinselV2 ? sd.yTriggerBottom : 20)
+#define RLDISTANCE (TinselV2 ? g_sd.xTrigger : 50)
+#define UDISTANCE (TinselV2 ? g_sd.yTriggerTop : 20)
+#define DDISTANCE (TinselV2 ? g_sd.yTriggerBottom : 20)
// Number of iterations to make
#define RLSCROLL 160 // 20*8 = 160 = half a screen
diff --git a/engines/tinsel/sound.cpp b/engines/tinsel/sound.cpp
index 130928d885..f575b03270 100644
--- a/engines/tinsel/sound.cpp
+++ b/engines/tinsel/sound.cpp
@@ -49,7 +49,7 @@
namespace Tinsel {
-extern LANGUAGE sampleLanguage;
+extern LANGUAGE g_sampleLanguage;
//--------------------------- General data ----------------------------------
@@ -99,12 +99,12 @@ bool SoundManager::playSample(int id, Audio::Mixer::SoundType type, Audio::Sound
// move to correct position in the sample file
_sampleStream.seek(dwSampleIndex);
if (_sampleStream.eos() || _sampleStream.err() || (uint32)_sampleStream.pos() != dwSampleIndex)
- error(FILE_IS_CORRUPT, _vm->getSampleFile(sampleLanguage));
+ error(FILE_IS_CORRUPT, _vm->getSampleFile(g_sampleLanguage));
// read the length of the sample
uint32 sampleLen = _sampleStream.readUint32();
if (_sampleStream.eos() || _sampleStream.err())
- error(FILE_IS_CORRUPT, _vm->getSampleFile(sampleLanguage));
+ error(FILE_IS_CORRUPT, _vm->getSampleFile(g_sampleLanguage));
if (TinselV1PSX) {
// Read the stream and create a XA ADPCM audio stream
@@ -124,7 +124,7 @@ bool SoundManager::playSample(int id, Audio::Mixer::SoundType type, Audio::Sound
// read all of the sample
if (_sampleStream.read(sampleBuf, sampleLen) != sampleLen)
- error(FILE_IS_CORRUPT, _vm->getSampleFile(sampleLanguage));
+ error(FILE_IS_CORRUPT, _vm->getSampleFile(g_sampleLanguage));
// FIXME: Should set this in a different place ;)
_vm->_mixer->setVolumeForSoundType(Audio::Mixer::kSFXSoundType, _vm->_config->_soundVolume);
@@ -254,12 +254,12 @@ bool SoundManager::playSample(int id, int sub, bool bLooped, int x, int y, int p
// move to correct position in the sample file
_sampleStream.seek(dwSampleIndex);
if (_sampleStream.eos() || _sampleStream.err() || (uint32)_sampleStream.pos() != dwSampleIndex)
- error(FILE_IS_CORRUPT, _vm->getSampleFile(sampleLanguage));
+ error(FILE_IS_CORRUPT, _vm->getSampleFile(g_sampleLanguage));
// read the length of the sample
uint32 sampleLen = _sampleStream.readUint32();
if (_sampleStream.eos() || _sampleStream.err())
- error(FILE_IS_CORRUPT, _vm->getSampleFile(sampleLanguage));
+ error(FILE_IS_CORRUPT, _vm->getSampleFile(g_sampleLanguage));
if (sampleLen & 0x80000000) {
// Has sub samples
@@ -273,11 +273,11 @@ bool SoundManager::playSample(int id, int sub, bool bLooped, int x, int y, int p
sampleLen = _sampleStream.readUint32();
_sampleStream.skip(sampleLen);
if (_sampleStream.eos() || _sampleStream.err())
- error(FILE_IS_CORRUPT, _vm->getSampleFile(sampleLanguage));
+ error(FILE_IS_CORRUPT, _vm->getSampleFile(g_sampleLanguage));
}
sampleLen = _sampleStream.readUint32();
if (_sampleStream.eos() || _sampleStream.err())
- error(FILE_IS_CORRUPT, _vm->getSampleFile(sampleLanguage));
+ error(FILE_IS_CORRUPT, _vm->getSampleFile(g_sampleLanguage));
}
debugC(DEBUG_DETAILED, kTinselDebugSound, "Playing sound %d.%d, %d bytes at %d (pan %d)", id, sub, sampleLen,
@@ -289,7 +289,7 @@ bool SoundManager::playSample(int id, int sub, bool bLooped, int x, int y, int p
// read all of the sample
if (_sampleStream.read(sampleBuf, sampleLen) != sampleLen)
- error(FILE_IS_CORRUPT, _vm->getSampleFile(sampleLanguage));
+ error(FILE_IS_CORRUPT, _vm->getSampleFile(g_sampleLanguage));
Common::MemoryReadStream *compressedStream =
new Common::MemoryReadStream(sampleBuf, sampleLen, DisposeAfterUse::YES);
@@ -481,7 +481,7 @@ void SoundManager::openSampleFiles() {
return;
// open sample index file in binary mode
- if (f.open(_vm->getSampleIndex(sampleLanguage))) {
+ if (f.open(_vm->getSampleIndex(g_sampleLanguage))) {
// get length of index file
f.seek(0, SEEK_END); // move to end of file
_sampleIndexLen = f.pos(); // get file pointer
@@ -502,7 +502,7 @@ void SoundManager::openSampleFiles() {
// load data
if (f.read(_sampleIndex, _sampleIndexLen) != (uint32)_sampleIndexLen)
// file must be corrupt if we get to here
- error(FILE_IS_CORRUPT, _vm->getSampleFile(sampleLanguage));
+ error(FILE_IS_CORRUPT, _vm->getSampleFile(g_sampleLanguage));
// close the file
f.close();
@@ -542,28 +542,28 @@ void SoundManager::openSampleFiles() {
_sampleIndex[0] = 0;
} else {
char buf[50];
- sprintf(buf, CANNOT_FIND_FILE, _vm->getSampleIndex(sampleLanguage));
+ sprintf(buf, CANNOT_FIND_FILE, _vm->getSampleIndex(g_sampleLanguage));
GUI::MessageDialog dialog(buf, "OK");
dialog.runModal();
- error(CANNOT_FIND_FILE, _vm->getSampleIndex(sampleLanguage));
+ error(CANNOT_FIND_FILE, _vm->getSampleIndex(g_sampleLanguage));
}
// open sample file in binary mode
- if (!_sampleStream.open(_vm->getSampleFile(sampleLanguage))) {
+ if (!_sampleStream.open(_vm->getSampleFile(g_sampleLanguage))) {
char buf[50];
- sprintf(buf, CANNOT_FIND_FILE, _vm->getSampleFile(sampleLanguage));
+ sprintf(buf, CANNOT_FIND_FILE, _vm->getSampleFile(g_sampleLanguage));
GUI::MessageDialog dialog(buf, "OK");
dialog.runModal();
- error(CANNOT_FIND_FILE, _vm->getSampleFile(sampleLanguage));
+ error(CANNOT_FIND_FILE, _vm->getSampleFile(g_sampleLanguage));
}
/*
// gen length of the largest sample
sampleBuffer.size = _sampleStream.readUint32LE();
if (_sampleStream.eos() || _sampleStream.err())
- error(FILE_IS_CORRUPT, _vm->getSampleFile(sampleLanguage));
+ error(FILE_IS_CORRUPT, _vm->getSampleFile(g_sampleLanguage));
*/
}
diff --git a/engines/tinsel/strres.cpp b/engines/tinsel/strres.cpp
index f3a7278993..5a29a4d2cd 100644
--- a/engines/tinsel/strres.cpp
+++ b/engines/tinsel/strres.cpp
@@ -38,11 +38,11 @@ namespace Tinsel {
#ifdef DEBUG
// Diagnostic number
-int newestString;
+int g_newestString;
#endif
// buffer for resource strings
-static uint8 *textBuffer = 0;
+static uint8 *g_textBuffer = 0;
static struct {
bool bPresent;
@@ -50,7 +50,7 @@ static struct {
SCNHANDLE hDescription;
SCNHANDLE hFlagFilm;
-} languages[NUM_LANGUAGES] = {
+} g_languages[NUM_LANGUAGES] = {
{ false, "English", 0, 0 },
{ false, "French", 0, 0 },
@@ -65,9 +65,9 @@ static struct {
// Set if we're handling 2-byte characters.
-bool bMultiByte = false;
+bool g_bMultiByte = false;
-LANGUAGE textLanguage, sampleLanguage = TXT_ENGLISH;
+LANGUAGE g_textLanguage, g_sampleLanguage = TXT_ENGLISH;
//----------------- LOCAL DEFINES ----------------------------
@@ -85,12 +85,12 @@ void ChangeLanguage(LANGUAGE newLang) {
TinselFile f;
uint32 textLen = 0; // length of buffer
- textLanguage = newLang;
- sampleLanguage = newLang;
+ g_textLanguage = newLang;
+ g_sampleLanguage = newLang;
// free the previous buffer
- free(textBuffer);
- textBuffer = NULL;
+ free(g_textBuffer);
+ g_textBuffer = NULL;
// Try and open the specified language file. If it fails, and the language
// isn't English, try falling back on opening 'english.txt' - some foreign
@@ -116,22 +116,22 @@ void ChangeLanguage(LANGUAGE newLang) {
if (textLen == CHUNK_STRING || textLen == CHUNK_MBSTRING) {
// the file is uncompressed
- bMultiByte = (textLen == CHUNK_MBSTRING);
+ g_bMultiByte = (textLen == CHUNK_MBSTRING);
// get length of uncompressed file
textLen = f.size();
f.seek(0, SEEK_SET); // Set to beginning of file
- if (textBuffer == NULL) {
+ if (g_textBuffer == NULL) {
// allocate a text buffer for the strings
- textBuffer = (uint8 *)malloc(textLen);
+ g_textBuffer = (uint8 *)malloc(textLen);
// make sure memory allocated
- assert(textBuffer);
+ assert(g_textBuffer);
}
// load data
- if (f.read(textBuffer, textLen) != textLen)
+ if (f.read(g_textBuffer, textLen) != textLen)
// file must be corrupt if we get to here
error(FILE_IS_CORRUPT, _vm->getTextFile(newLang));
@@ -147,7 +147,7 @@ void ChangeLanguage(LANGUAGE newLang) {
*/
static byte *FindStringBase(int id) {
// base of string resource table
- byte *pText = textBuffer;
+ byte *pText = g_textBuffer;
// For Tinsel 0, Ids are decremented by 1
if (TinselV0)
@@ -353,8 +353,8 @@ int SubStringCount(int id) {
void FreeTextBuffer() {
- free(textBuffer);
- textBuffer = NULL;
+ free(g_textBuffer);
+ g_textBuffer = NULL;
}
/**
@@ -364,29 +364,29 @@ void FreeTextBuffer() {
void LanguageFacts(int language, SCNHANDLE hDescription, SCNHANDLE hFlagFilm) {
assert(language >= 0 && language < NUM_LANGUAGES);
- languages[language].hDescription = hDescription;
- languages[language].hFlagFilm = hFlagFilm;
+ g_languages[language].hDescription = hDescription;
+ g_languages[language].hFlagFilm = hFlagFilm;
}
/**
* Gets the current subtitles language
*/
LANGUAGE TextLanguage() {
- return textLanguage;
+ return g_textLanguage;
}
/**
* Gets the current voice language
*/
LANGUAGE SampleLanguage() {
- return sampleLanguage;
+ return g_sampleLanguage;
}
int NumberOfLanguages() {
int i, count;
for (i = 0, count = 0; i < NUM_LANGUAGES; i++) {
- if (languages[i].bPresent)
+ if (g_languages[i].bPresent)
count++;
}
return count;
@@ -396,12 +396,12 @@ LANGUAGE NextLanguage(LANGUAGE thisOne) {
int i;
for (i = thisOne+1; i < NUM_LANGUAGES; i++) {
- if (languages[i].bPresent)
+ if (g_languages[i].bPresent)
return (LANGUAGE)i;
}
for (i = 0; i < thisOne; i++) {
- if (languages[i].bPresent)
+ if (g_languages[i].bPresent)
return (LANGUAGE)i;
}
@@ -413,12 +413,12 @@ LANGUAGE PrevLanguage(LANGUAGE thisOne) {
int i;
for (i = thisOne-1; i >= 0; i--) {
- if (languages[i].bPresent)
+ if (g_languages[i].bPresent)
return (LANGUAGE)i;
}
for (i = NUM_LANGUAGES-1; i > thisOne; i--) {
- if (languages[i].bPresent)
+ if (g_languages[i].bPresent)
return (LANGUAGE)i;
}
@@ -427,11 +427,11 @@ LANGUAGE PrevLanguage(LANGUAGE thisOne) {
}
SCNHANDLE LanguageDesc(LANGUAGE thisOne) {
- return languages[thisOne].hDescription;
+ return g_languages[thisOne].hDescription;
}
SCNHANDLE LanguageFlag(LANGUAGE thisOne) {
- return languages[thisOne].hFlagFilm;
+ return g_languages[thisOne].hFlagFilm;
}
} // End of namespace Tinsel
diff --git a/engines/tinsel/strres.h b/engines/tinsel/strres.h
index f6e86951b6..772896c81f 100644
--- a/engines/tinsel/strres.h
+++ b/engines/tinsel/strres.h
@@ -35,7 +35,7 @@ namespace Tinsel {
#define MAX_STRRES_SIZE 300000 // maximum size of string resource file
// Set if we're handling 2-byte characters.
-extern bool bMultiByte;
+extern bool g_bMultiByte;
/*----------------------------------------------------------------------*\
|* Function Prototypes *|
diff --git a/engines/tinsel/sysvar.cpp b/engines/tinsel/sysvar.cpp
index 88053f15c6..6ef4f165ab 100644
--- a/engines/tinsel/sysvar.cpp
+++ b/engines/tinsel/sysvar.cpp
@@ -43,7 +43,7 @@ extern int NewestSavedGame();
// FIXME: Avoid non-const global vars
-static int systemVars[SV_TOPVALID] = {
+static int g_systemVars[SV_TOPVALID] = {
INV_1, // Default inventory
@@ -105,7 +105,7 @@ static int systemVars[SV_TOPVALID] = {
0 // ISV_GHOST_COLOR
};
-static SCNHANDLE systemStrings[SS_MAX_VALID]; // FIXME: Avoid non-const global vars
+static SCNHANDLE g_systemStrings[SS_MAX_VALID]; // FIXME: Avoid non-const global vars
//static bool bFlagNoBlocking = false;
@@ -116,8 +116,8 @@ static SCNHANDLE systemStrings[SS_MAX_VALID]; // FIXME: Avoid non-const global v
*/
void InitSysVars() {
- systemVars[SV_SCROLL_XDISTANCE] = SCREEN_WIDTH / 2;
- systemVars[SV_SCROLL_YDISTANCE] = SCREEN_BOX_HEIGHT1 / 2;
+ g_systemVars[SV_SCROLL_XDISTANCE] = SCREEN_WIDTH / 2;
+ g_systemVars[SV_SCROLL_YDISTANCE] = SCREEN_BOX_HEIGHT1 / 2;
}
/**
@@ -138,7 +138,7 @@ void SetSysVar(int varId, int newValue) {
error("SetSystemVar(): read only identifier");
default:
- systemVars[varId] = newValue;
+ g_systemVars[varId] = newValue;
}
}
@@ -167,28 +167,28 @@ int SysVar(int varId) {
//return bDebuggingAllowed;
default:
- return systemVars[varId];
+ return g_systemVars[varId];
}
}
void SaveSysVars(int *pSv) {
- memcpy(pSv, systemVars, sizeof(systemVars));
+ memcpy(pSv, g_systemVars, sizeof(g_systemVars));
}
void RestoreSysVars(int *pSv) {
- memcpy(systemVars, pSv, sizeof(systemVars));
+ memcpy(g_systemVars, pSv, sizeof(g_systemVars));
}
void SetSysString(int number, SCNHANDLE hString) {
assert(number >= 0 && number < SS_MAX_VALID);
- systemStrings[number] = hString;
+ g_systemStrings[number] = hString;
}
SCNHANDLE SysString(int number) {
assert(number >= 0 && number < SS_MAX_VALID);
- return systemStrings[number];
+ return g_systemStrings[number];
}
/**
diff --git a/engines/tinsel/text.cpp b/engines/tinsel/text.cpp
index ecb1e153f3..5eb092d00d 100644
--- a/engines/tinsel/text.cpp
+++ b/engines/tinsel/text.cpp
@@ -25,7 +25,7 @@
#include "tinsel/graphics.h" // object plotting
#include "tinsel/handle.h"
#include "tinsel/sched.h" // process scheduler defines
-#include "tinsel/strres.h" // bMultiByte
+#include "tinsel/strres.h" // g_bMultiByte
#include "tinsel/text.h" // text defines
namespace Tinsel {
@@ -42,7 +42,7 @@ int StringLengthPix(char *szStr, const FONT *pFont) {
// while not end of string or end of line
for (strLen = 0; (c = *szStr) != EOS_CHAR && c != LF_CHAR; szStr++) {
- if (bMultiByte) {
+ if (g_bMultiByte) {
if (c & 0x80)
c = ((c & ~0x80) << 8) + *++szStr;
}
@@ -136,7 +136,7 @@ OBJECT *ObjectTextOut(OBJECT **pList, char *szStr, int color,
// repeat until end of string or end of line
while ((c = *szStr) != EOS_CHAR && c != LF_CHAR) {
- if (bMultiByte) {
+ if (g_bMultiByte) {
if (c & 0x80)
c = ((c & ~0x80) << 8) + *++szStr;
}
@@ -265,7 +265,7 @@ bool IsCharImage(SCNHANDLE hFont, char c) {
// Inventory save game name editor needs to be more clever for
// multi-byte characters. This bodge will stop it erring.
- if (bMultiByte && (c2 & 0x80))
+ if (g_bMultiByte && (c2 & 0x80))
return false;
// get font pointer
diff --git a/engines/tinsel/timers.cpp b/engines/tinsel/timers.cpp
index 1c3ff9b260..d3a7446565 100644
--- a/engines/tinsel/timers.cpp
+++ b/engines/tinsel/timers.cpp
@@ -49,7 +49,7 @@ struct TIMER {
//----------------- LOCAL GLOBAL DATA --------------------
-static TIMER timers[MAX_TIMERS]; // FIXME: Avoid non-const global vars
+static TIMER g_timers[MAX_TIMERS]; // FIXME: Avoid non-const global vars
//--------------------------------------------------------
@@ -72,7 +72,7 @@ uint32 DwGetCurrentTime() {
*/
void RebootTimers() {
- memset(timers, 0, sizeof(timers));
+ memset(g_timers, 0, sizeof(g_timers));
}
/**
@@ -80,11 +80,11 @@ void RebootTimers() {
*/
void syncTimerInfo(Common::Serializer &s) {
for (int i = 0; i < MAX_TIMERS; i++) {
- s.syncAsSint32LE(timers[i].tno);
- s.syncAsSint32LE(timers[i].ticks);
- s.syncAsSint32LE(timers[i].secs);
- s.syncAsSint32LE(timers[i].delta);
- s.syncAsSint32LE(timers[i].frame);
+ s.syncAsSint32LE(g_timers[i].tno);
+ s.syncAsSint32LE(g_timers[i].ticks);
+ s.syncAsSint32LE(g_timers[i].secs);
+ s.syncAsSint32LE(g_timers[i].delta);
+ s.syncAsSint32LE(g_timers[i].frame);
}
}
@@ -95,8 +95,8 @@ void syncTimerInfo(Common::Serializer &s) {
*/
static TIMER *findTimer(int num) {
for (int i = 0; i < MAX_TIMERS; i++) {
- if (timers[i].tno == num)
- return &timers[i];
+ if (g_timers[i].tno == num)
+ return &g_timers[i];
}
return NULL;
}
@@ -109,9 +109,9 @@ static TIMER *allocateTimer(int num) {
assert(!findTimer(num)); // Allocating already existant timer
for (int i = 0; i < MAX_TIMERS; i++) {
- if (!timers[i].tno) {
- timers[i].tno = num;
- return &timers[i];
+ if (!g_timers[i].tno) {
+ g_timers[i].tno = num;
+ return &g_timers[i];
}
}
@@ -123,23 +123,23 @@ static TIMER *allocateTimer(int num) {
*/
void FettleTimers() {
for (int i = 0; i < MAX_TIMERS; i++) {
- if (!timers[i].tno)
+ if (!g_timers[i].tno)
continue;
- timers[i].ticks += timers[i].delta; // Update tick value
+ g_timers[i].ticks += g_timers[i].delta; // Update tick value
- if (timers[i].frame) {
- if (timers[i].ticks < 0)
- timers[i].ticks = 0; // Have reached zero
+ if (g_timers[i].frame) {
+ if (g_timers[i].ticks < 0)
+ g_timers[i].ticks = 0; // Have reached zero
} else {
- if (timers[i].ticks < 0) {
- timers[i].ticks = ONE_SECOND;
- timers[i].secs--;
- if (timers[i].secs < 0)
- timers[i].secs = 0; // Have reached zero
- } else if (timers[i].ticks == ONE_SECOND) {
- timers[i].ticks = 0;
- timers[i].secs++; // Another second has passed
+ if (g_timers[i].ticks < 0) {
+ g_timers[i].ticks = ONE_SECOND;
+ g_timers[i].secs--;
+ if (g_timers[i].secs < 0)
+ g_timers[i].secs = 0; // Have reached zero
+ } else if (g_timers[i].ticks == ONE_SECOND) {
+ g_timers[i].ticks = 0;
+ g_timers[i].secs++; // Another second has passed
}
}
}
diff --git a/engines/tinsel/tinlib.cpp b/engines/tinsel/tinlib.cpp
index 7fbec69cbf..c652abca25 100644
--- a/engines/tinsel/tinlib.cpp
+++ b/engines/tinsel/tinlib.cpp
@@ -74,11 +74,11 @@ namespace Tinsel {
//----------------- EXTERNAL GLOBAL DATA --------------------
// In DOS_DW.C
-extern bool bRestart; // restart flag - set to restart the game
-extern bool bHasRestarted; // Set after a restart
+extern bool g_bRestart; // restart flag - set to restart the game
+extern bool g_bHasRestarted; // Set after a restart
// In PCODE.CPP
-extern bool bNoPause;
+extern bool g_bNoPause;
// In DOS_MAIN.C
// TODO/FIXME: From dos_main.c: "Only used on PSX so far"
@@ -100,7 +100,7 @@ extern int NewestSavedGame();
// in SCENE.CPP
extern void setshowpos();
-extern int sceneCtr;
+extern int g_sceneCtr;
// in TINSEL.CPP
extern void SetCdChangeScene(SCNHANDLE hScene);
@@ -122,10 +122,10 @@ SCNHANDLE GetSceneHandle();
// FIXME: Avoid non-const global vars
-bool bEnableMenu;
+bool g_bEnableMenu;
-static bool bInstantScroll = false;
-static bool bEscapedCdPlay = false;
+static bool g_bInstantScroll = false;
+static bool g_bEscapedCdPlay = false;
//----------------- LOCAL DEFINES --------------------
@@ -298,13 +298,13 @@ static const MASTER_LIB_CODES DW2_CODES[] = {
// as it was at control(off).
// They are global so that MoveCursor(..) has a net effect if it
// precedes control(on).
-static int controlX = 0, controlY = 0;
+static int g_controlX = 0, g_controlY = 0;
-static int offtype = 0; // used by Control()
-static uint32 lastValue = 0; // used by RandomFn()
-static int scrollNumber = 0; // used by scroll()
+static int g_offtype = 0; // used by Control()
+static uint32 g_lastValue = 0; // used by RandomFn()
+static int g_scrollNumber = 0; // used by scroll()
-static bool bNotPointedRunning = false; // Used in Printobj and PrintObjPointed
+static bool g_bNotPointedRunning = false; // Used in Printobj and PrintObjPointed
//----------------- FORWARD REFERENCES --------------------
@@ -404,7 +404,7 @@ static void ScrollMonitorProcess(CORO_PARAM, const void *param) {
CORO_SLEEP(1);
// give up if have been superseded
- if (psm->thisScroll != scrollNumber)
+ if (psm->thisScroll != g_scrollNumber)
break;
// If ESCAPE is pressed...
@@ -706,7 +706,7 @@ static void CDload(SCNHANDLE start, SCNHANDLE next, int myEscape) {
if (TinselV2) {
if (myEscape && myEscape != GetEscEvents()) {
- bEscapedCdPlay = true;
+ g_bEscapedCdPlay = true;
return;
}
@@ -754,14 +754,14 @@ void Control(int param) {
}
// Tinsel 1 handling code
- bEnableMenu = false;
+ g_bEnableMenu = false;
switch (param) {
case CONTROL_STARTOFF:
GetControlToken(); // Take control
DisableTags(); // Switch off tags
DwHideCursor(); // Blank out cursor
- offtype = param;
+ g_offtype = param;
break;
case CONTROL_OFF:
@@ -771,17 +771,17 @@ void Control(int param) {
GetControlToken(); // Take control
DisableTags(); // Switch off tags
- GetCursorXYNoWait(&controlX, &controlY, true); // Store cursor position
+ GetCursorXYNoWait(&g_controlX, &g_controlY, true); // Store cursor position
// There may be a button timing out
GetToken(TOKEN_LEFT_BUT);
FreeToken(TOKEN_LEFT_BUT);
}
- if (offtype == CONTROL_STARTOFF)
- GetCursorXYNoWait(&controlX, &controlY, true); // Store cursor position
+ if (g_offtype == CONTROL_STARTOFF)
+ GetCursorXYNoWait(&g_controlX, &g_controlY, true); // Store cursor position
- offtype = param;
+ g_offtype = param;
if (param == CONTROL_OFF)
DwHideCursor(); // Blank out cursor
@@ -794,8 +794,8 @@ void Control(int param) {
break;
case CONTROL_ON:
- if (offtype != CONTROL_OFFV2 && offtype != CONTROL_STARTOFF)
- SetCursorXY(controlX, controlY);// ... where it was
+ if (g_offtype != CONTROL_OFFV2 && g_offtype != CONTROL_STARTOFF)
+ SetCursorXY(g_controlX, g_controlY);// ... where it was
FreeControlToken(); // Release control
@@ -1092,7 +1092,7 @@ static void DropEverything() {
* EnableMenu
*/
static void EnableMenu() {
- bEnableMenu = true;
+ g_bEnableMenu = true;
}
/**
@@ -1212,7 +1212,7 @@ static void HailScene(SCNHANDLE scene) {
* Returns TRUE if the game has been restarted, FALSE if not.
*/
static bool HasRestarted() {
- return bHasRestarted;
+ return g_bHasRestarted;
}
/**
@@ -1308,7 +1308,7 @@ static int IdleTime() {
* Set flag if InstantScroll(on), reset if InstantScroll(off)
*/
void InstantScroll(int onoff) {
- bInstantScroll = (onoff != 0);
+ g_bInstantScroll = (onoff != 0);
}
/**
@@ -1419,8 +1419,8 @@ static int LToffset(int lort) {
static void MoveCursor(int x, int y) {
SetCursorXY(x, y);
- controlX = x; // Save these values so that
- controlY = y; // control(on) doesn't undo this
+ g_controlX = x; // Save these values so that
+ g_controlY = y; // control(on) doesn't undo this
}
/**
@@ -1465,7 +1465,7 @@ void NewScene(CORO_PARAM, SCNHANDLE scene, int entrance, int transition) {
GetControl(CONTROL_STARTOFF);
if (TinselV1)
- ++sceneCtr;
+ ++g_sceneCtr;
// Prevent code subsequent to this call running before scene changes
if (g_scheduler->getCurrentPID() != PID_MASTER_SCR)
@@ -1541,8 +1541,8 @@ static void Play(CORO_PARAM, SCNHANDLE hFilm, int x, int y, int compit, int acto
// Don't do CDPlay() for now if already escaped
- if (bEscapedCdPlay) {
- bEscapedCdPlay = false;
+ if (g_bEscapedCdPlay) {
+ g_bEscapedCdPlay = false;
return;
}
@@ -1583,8 +1583,8 @@ static void Play(CORO_PARAM, SCNHANDLE hFilm, int x, int y, bool bComplete, int
assert(hFilm != 0);
// Don't do CdPlay() for now if already escaped
- if (bEscapedCdPlay) {
- bEscapedCdPlay = false;
+ if (g_bEscapedCdPlay) {
+ g_bEscapedCdPlay = false;
return;
}
@@ -2068,11 +2068,11 @@ static void PrintObj(CORO_PARAM, const SCNHANDLE hText, const INV_OBJECT *pinvo,
_ctx->myEscape = myEscape;
if (hText == (SCNHANDLE)-1) { // 'OFF'
- bNotPointedRunning = true;
+ g_bNotPointedRunning = true;
return;
}
if (hText == (SCNHANDLE)-2) { // 'ON'
- bNotPointedRunning = false;
+ g_bNotPointedRunning = false;
return;
}
@@ -2092,10 +2092,10 @@ static void PrintObj(CORO_PARAM, const SCNHANDLE hText, const INV_OBJECT *pinvo,
* POINT/other event PrintObj() arbitration...
*/
if (event != POINTED) {
- bNotPointedRunning = true; // Get POINTED text to die
+ g_bNotPointedRunning = true; // Get POINTED text to die
CORO_SLEEP(1); // Give it chance to
} else if (!TinselV2)
- bNotPointedRunning = false; // There may have been an OFF without an ON
+ g_bNotPointedRunning = false; // There may have been an OFF without an ON
// Make multi-ones escape
if (TinselV2 && (SubStringCount(hText) > 1) && !_ctx->myEscape)
@@ -2163,12 +2163,12 @@ static void PrintObj(CORO_PARAM, const SCNHANDLE hText, const INV_OBJECT *pinvo,
break;
// Give way to non-POINTED-generated text
- if (bNotPointedRunning) {
+ if (g_bNotPointedRunning) {
// Delete the text, and wait for the all-clear
MultiDeleteObject(GetPlayfieldList(FIELD_STATUS), _ctx->pText);
_ctx->pText = NULL;
- while (bNotPointedRunning)
+ while (g_bNotPointedRunning)
CORO_SLEEP(1);
GetCursorXY(&x, &y, false);
@@ -2262,7 +2262,7 @@ static void PrintObj(CORO_PARAM, const SCNHANDLE hText, const INV_OBJECT *pinvo,
// Let POINTED text back in if this is the last
if (event != POINTED)
- bNotPointedRunning = false;
+ g_bNotPointedRunning = false;
CORO_END_CODE;
}
@@ -2281,11 +2281,11 @@ static void PrintObjPointed(CORO_PARAM, const SCNHANDLE text, const INV_OBJECT *
break;
// Give way to non-POINTED-generated text
- if (bNotPointedRunning) {
+ if (g_bNotPointedRunning) {
// Delete the text, and wait for the all-clear
MultiDeleteObject(GetPlayfieldList(FIELD_STATUS), pText);
pText = NULL;
- while (bNotPointedRunning)
+ while (g_bNotPointedRunning)
CORO_SLEEP(1);
GetCursorXY(&x, &y, false);
@@ -2372,7 +2372,7 @@ static void PrintObjNonPointed(CORO_PARAM, const SCNHANDLE text, const OBJECT *p
}
} while (1);
- bNotPointedRunning = false; // Let POINTED text back in
+ g_bNotPointedRunning = false; // Let POINTED text back in
if (_ctx->took_control)
Control(CONTROL_ON); // Free control if we took it
@@ -2425,9 +2425,9 @@ static int RandomFn(int n1, int n2, int norpt) {
do {
value = n1 + _vm->getRandomNumber(n2 - n1);
- } while ((lastValue == value) && (norpt == RAND_NORPT) && (++i <= 10));
+ } while ((g_lastValue == value) && (norpt == RAND_NORPT) && (++i <= 10));
- lastValue = value;
+ g_lastValue = value;
return value;
}
@@ -2446,8 +2446,8 @@ void FnRestartGame() {
StopMidi();
StopSample();
- bRestart = true;
- sceneCtr = 0;
+ g_bRestart = true;
+ g_sceneCtr = 0;
}
/**
@@ -2554,15 +2554,15 @@ static void Scroll(CORO_PARAM, EXTREME extreme, int xp, int yp, int xIter, int y
CORO_BEGIN_CODE(_ctx);
- ++scrollNumber;
+ ++g_scrollNumber;
_ctx->x = xp;
_ctx->y = yp;
- if ((TinselV2 && bInstantScroll) || (escOn && myEscape != GetEscEvents())) {
+ if ((TinselV2 && g_bInstantScroll) || (escOn && myEscape != GetEscEvents())) {
// Instant completion!
Offset(extreme, _ctx->x, _ctx->y);
} else {
- _ctx->thisScroll = scrollNumber;
+ _ctx->thisScroll = g_scrollNumber;
if (TinselV2)
DecodeExtreme(extreme, &_ctx->x, &_ctx->y);
@@ -2581,7 +2581,7 @@ static void Scroll(CORO_PARAM, EXTREME extreme, int xp, int yp, int xIter, int y
}
// give up if have been superseded
- if (_ctx->thisScroll != scrollNumber)
+ if (_ctx->thisScroll != g_scrollNumber)
CORO_KILL_SELF();
PlayfieldGetPos(FIELD_WORLD, &Loffset, &Toffset);
@@ -2592,7 +2592,7 @@ static void Scroll(CORO_PARAM, EXTREME extreme, int xp, int yp, int xIter, int y
// Scroll is escapable even though we're not waiting for it
sm.x = _ctx->x;
sm.y = _ctx->y;
- sm.thisScroll = scrollNumber;
+ sm.thisScroll = g_scrollNumber;
sm.myEscape = myEscape;
g_scheduler->createProcess(PID_TCODE, ScrollMonitorProcess, &sm, sizeof(sm));
}
@@ -3410,8 +3410,8 @@ static void TalkOrSay(CORO_PARAM, SPEECH_TYPE speechType, SCNHANDLE hText, int x
if (TinselV2 && _ctx->bSample) {
// Kick off the sample now (perhaps with a delay)
- if (bNoPause)
- bNoPause = false;
+ if (g_bNoPause)
+ g_bNoPause = false;
else if (!IsDemo)
CORO_SLEEP(SysVar(SV_SPEECHDELAY));
@@ -4899,7 +4899,7 @@ int CallLibraryRoutine(CORO_PARAM, int operand, int32 *pp, const INT_CONTEXT *pi
case NOPAUSE:
// DW2 only
- bNoPause = true;
+ g_bNoPause = true;
return 0;
case NOSCROLL:
diff --git a/engines/tinsel/tinsel.cpp b/engines/tinsel/tinsel.cpp
index 635845ab26..65900cc7f3 100644
--- a/engines/tinsel/tinsel.cpp
+++ b/engines/tinsel/tinsel.cpp
@@ -66,7 +66,7 @@ namespace Tinsel {
// In BG.CPP
extern void SetDoFadeIn(bool tf);
extern void DropBackground();
-extern const BACKGND *pCurBgnd;
+extern const BACKGND *g_pCurBgnd;
// In CURSOR.CPP
extern void CursorProcess(CORO_PARAM, const void *);
@@ -85,16 +85,16 @@ void SetNewScene(SCNHANDLE scene, int entrance, int transition);
// FIXME: Avoid non-const global vars
-bool bRestart = false;
-bool bHasRestarted = false;
-bool loadingFromGMM = false;
+bool g_bRestart = false;
+bool g_bHasRestarted = false;
+bool g_loadingFromGMM = false;
-static bool bCuttingScene = false;
+static bool g_bCuttingScene = false;
-static bool bChangingForRestore = false;
+static bool g_bChangingForRestore = false;
#ifdef DEBUG
-bool bFast; // set to make it go ludicrously fast
+bool g_bFast; // set to make it go ludicrously fast
#endif
//----------------- LOCAL GLOBAL DATA --------------------
@@ -105,14 +105,14 @@ struct Scene {
int trans; // Transition - not yet used
};
-static Scene NextScene = { 0, 0, 0 };
-static Scene HookScene = { 0, 0, 0 };
-static Scene DelayedScene = { 0, 0, 0 };
+static Scene g_NextScene = { 0, 0, 0 };
+static Scene g_HookScene = { 0, 0, 0 };
+static Scene g_DelayedScene = { 0, 0, 0 };
-static PROCESS *pMouseProcess = 0;
-static PROCESS *pKeyboardProcess = 0;
+static PROCESS *g_pMouseProcess = 0;
+static PROCESS *g_pKeyboardProcess = 0;
-static SCNHANDLE hCdChangeScene;
+static SCNHANDLE g_hCdChangeScene;
//----------------- LOCAL PROCEDURES --------------------
@@ -457,49 +457,49 @@ static void MasterScriptProcess(CORO_PARAM, const void *) {
* Store the facts pertaining to a scene change.
*/
void SetNewScene(SCNHANDLE scene, int entrance, int transition) {
- if (!bCuttingScene && TinselV2)
+ if (!g_bCuttingScene && TinselV2)
WrapScene();
// If we're loading from the GMM, load the scene as a delayed one
- if (loadingFromGMM) {
- DelayedScene.scene = scene;
- DelayedScene.entry = entrance;
- DelayedScene.trans = transition;
- loadingFromGMM = false;
+ if (g_loadingFromGMM) {
+ g_DelayedScene.scene = scene;
+ g_DelayedScene.entry = entrance;
+ g_DelayedScene.trans = transition;
+ g_loadingFromGMM = false;
return;
}
// If CD change will be required, stick in the scene change scene
if (CdNumber(scene) != GetCurrentCD()) {
// This scene gets delayed
- DelayedScene.scene = scene;
- DelayedScene.entry = entrance;
- DelayedScene.trans = transition;
+ g_DelayedScene.scene = scene;
+ g_DelayedScene.entry = entrance;
+ g_DelayedScene.trans = transition;
- NextScene.scene = hCdChangeScene;
- NextScene.entry = CdNumber(scene) - '0';
- NextScene.trans = TRANS_FADE;
+ g_NextScene.scene = g_hCdChangeScene;
+ g_NextScene.entry = CdNumber(scene) - '0';
+ g_NextScene.trans = TRANS_FADE;
return;
}
- if (HookScene.scene == 0 || bCuttingScene) {
+ if (g_HookScene.scene == 0 || g_bCuttingScene) {
// This scene comes next
- NextScene.scene = scene;
- NextScene.entry = entrance;
- NextScene.trans = transition;
+ g_NextScene.scene = scene;
+ g_NextScene.entry = entrance;
+ g_NextScene.trans = transition;
} else {
// This scene gets delayed
- DelayedScene.scene = scene;
- DelayedScene.entry = entrance;
- DelayedScene.trans = transition;
+ g_DelayedScene.scene = scene;
+ g_DelayedScene.entry = entrance;
+ g_DelayedScene.trans = transition;
// The hooked scene comes next
- NextScene.scene = HookScene.scene;
- NextScene.entry = HookScene.entry;
- NextScene.trans = HookScene.trans;
+ g_NextScene.scene = g_HookScene.scene;
+ g_NextScene.entry = g_HookScene.entry;
+ g_NextScene.trans = g_HookScene.trans;
- HookScene.scene = 0;
+ g_HookScene.scene = 0;
}
// Workaround for "Missing Red Dragon in square" bug in Discworld 1 PSX, act IV.
@@ -509,10 +509,10 @@ void SetNewScene(SCNHANDLE scene, int entrance, int transition) {
// I'm forcing the load of the right scene by checking that the player has (or has not) the
// right items: player must have Mambo the swamp dragon, and mustn't have fireworks (used on
// the swamp dragon previously to "load it up").
- if (TinselV1PSX && NextScene.scene == 0x1800000 && NextScene.entry == 2) {
+ if (TinselV1PSX && g_NextScene.scene == 0x1800000 && g_NextScene.entry == 2) {
if ((IsInInventory(261, INV_1) || IsInInventory(261, INV_2)) &&
(!IsInInventory(232, INV_1) && !IsInInventory(232, INV_2)))
- NextScene.entry = 1;
+ g_NextScene.entry = 1;
}
}
@@ -520,72 +520,72 @@ void SetNewScene(SCNHANDLE scene, int entrance, int transition) {
* Store a scene as hooked
*/
void SetHookScene(SCNHANDLE scene, int entrance, int transition) {
- assert(HookScene.scene == 0); // scene already hooked
+ assert(g_HookScene.scene == 0); // scene already hooked
- HookScene.scene = scene;
- HookScene.entry = entrance;
- HookScene.trans = transition;
+ g_HookScene.scene = scene;
+ g_HookScene.entry = entrance;
+ g_HookScene.trans = transition;
}
/**
* Hooked scene is over, trigger a change to the delayed scene
*/
void UnHookScene() {
- assert(DelayedScene.scene != 0); // no scene delayed
+ assert(g_DelayedScene.scene != 0); // no scene delayed
// The delayed scene can go now
- NextScene.scene = DelayedScene.scene;
- NextScene.entry = DelayedScene.entry;
- NextScene.trans = DelayedScene.trans;
+ g_NextScene.scene = g_DelayedScene.scene;
+ g_NextScene.entry = g_DelayedScene.entry;
+ g_NextScene.trans = g_DelayedScene.trans;
- DelayedScene.scene = 0;
+ g_DelayedScene.scene = 0;
}
void SuspendHook() {
- bCuttingScene = true;
+ g_bCuttingScene = true;
}
void CdHasChanged() {
- if (bChangingForRestore) {
- bChangingForRestore = false;
+ if (g_bChangingForRestore) {
+ g_bChangingForRestore = false;
RestoreGame(-2);
} else {
- assert(DelayedScene.scene != 0);
+ assert(g_DelayedScene.scene != 0);
WrapScene();
// The delayed scene can go now
- NextScene.scene = DelayedScene.scene;
- NextScene.entry = DelayedScene.entry;
- NextScene.trans = DelayedScene.trans;
+ g_NextScene.scene = g_DelayedScene.scene;
+ g_NextScene.entry = g_DelayedScene.entry;
+ g_NextScene.trans = g_DelayedScene.trans;
- DelayedScene.scene = 0;
+ g_DelayedScene.scene = 0;
}
}
void SetCdChangeScene(SCNHANDLE hScene) {
- hCdChangeScene = hScene;
+ g_hCdChangeScene = hScene;
}
void CDChangeForRestore(int cdNumber) {
- NextScene.scene = hCdChangeScene;
- NextScene.entry = cdNumber;
- NextScene.trans = TRANS_FADE;
- bChangingForRestore = true;
+ g_NextScene.scene = g_hCdChangeScene;
+ g_NextScene.entry = cdNumber;
+ g_NextScene.trans = TRANS_FADE;
+ g_bChangingForRestore = true;
}
void UnSuspendHook() {
- bCuttingScene = false;
+ g_bCuttingScene = false;
}
void syncSCdata(Common::Serializer &s) {
- s.syncAsUint32LE(HookScene.scene);
- s.syncAsSint32LE(HookScene.entry);
- s.syncAsSint32LE(HookScene.trans);
+ s.syncAsUint32LE(g_HookScene.scene);
+ s.syncAsSint32LE(g_HookScene.entry);
+ s.syncAsSint32LE(g_HookScene.trans);
- s.syncAsUint32LE(DelayedScene.scene);
- s.syncAsSint32LE(DelayedScene.entry);
- s.syncAsSint32LE(DelayedScene.trans);
+ s.syncAsUint32LE(g_DelayedScene.scene);
+ s.syncAsSint32LE(g_DelayedScene.entry);
+ s.syncAsSint32LE(g_DelayedScene.trans);
}
@@ -640,16 +640,16 @@ bool ChangeScene(bool bReset) {
// Prevent attempt to fade-out when restarting game
if (bReset) {
CountOut = 1; // immediate start of first scene again
- DelayedScene.scene = HookScene.scene = 0;
+ g_DelayedScene.scene = g_HookScene.scene = 0;
return false;
}
if (IsRestoringScene())
return true;
- if (NextScene.scene != 0) {
+ if (g_NextScene.scene != 0) {
if (!CountOut) {
- switch (NextScene.trans) {
+ switch (g_NextScene.trans) {
case TRANS_CUT:
CountOut = 1;
break;
@@ -667,10 +667,10 @@ bool ChangeScene(bool bReset) {
if (!TinselV2)
ClearScreen();
- StartNewScene(NextScene.scene, NextScene.entry);
- NextScene.scene = 0;
+ StartNewScene(g_NextScene.scene, g_NextScene.entry);
+ g_NextScene.scene = 0;
- switch (NextScene.trans) {
+ switch (g_NextScene.trans) {
case TRANS_CUT:
SetDoFadeIn(false);
break;
@@ -691,7 +691,7 @@ bool ChangeScene(bool bReset) {
* CuttingScene
*/
void CuttingScene(bool bCutting) {
- bCuttingScene = bCutting;
+ g_bCuttingScene = bCutting;
if (!bCutting)
WrapScene();
@@ -927,7 +927,7 @@ Common::Error TinselEngine::run() {
RebootTimers();
RebootScalingReels();
- DelayedScene.scene = HookScene.scene = 0;
+ g_DelayedScene.scene = g_HookScene.scene = 0;
#endif
// Load in text strings
@@ -957,7 +957,7 @@ Common::Error TinselEngine::run() {
if (ConfMan.hasKey("save_slot")) {
if (loadGameState(ConfMan.getInt("save_slot")).getCode() == Common::kNoError)
- loadingFromGMM = true;
+ g_loadingFromGMM = true;
}
// Foreground loop
@@ -973,10 +973,10 @@ Common::Error TinselEngine::run() {
NextGameCycle();
}
- if (bRestart) {
+ if (g_bRestart) {
RestartGame();
- bRestart = false;
- bHasRestarted = true; // Set restarted flag
+ g_bRestart = false;
+ g_bHasRestarted = true; // Set restarted flag
}
// Save/Restore scene file transfers
@@ -986,7 +986,7 @@ Common::Error TinselEngine::run() {
_bmv->FettleBMV();
#ifdef DEBUG
- if (bFast)
+ if (g_bFast)
continue; // run flat-out
#endif
// Loop processing events while there are any pending
@@ -1005,7 +1005,7 @@ Common::Error TinselEngine::run() {
_vm->_config->writeToDisk();
EndScene();
- pCurBgnd = NULL;
+ g_pCurBgnd = NULL;
return Common::kNoError;
}
@@ -1106,7 +1106,7 @@ void TinselEngine::RestartGame() {
RebootTimers();
RebootScalingReels();
- DelayedScene.scene = HookScene.scene = 0;
+ g_DelayedScene.scene = g_HookScene.scene = 0;
// remove keyboard, mouse and joystick drivers
ChopDrivers();
@@ -1135,8 +1135,8 @@ void TinselEngine::RestartDrivers() {
_scheduler->reset();
// init the event handlers
- pMouseProcess = _scheduler->createProcess(PID_MOUSE, MouseProcess, NULL, 0);
- pKeyboardProcess = _scheduler->createProcess(PID_KEYBOARD, KeyboardProcess, NULL, 0);
+ g_pMouseProcess = _scheduler->createProcess(PID_MOUSE, MouseProcess, NULL, 0);
+ g_pKeyboardProcess = _scheduler->createProcess(PID_KEYBOARD, KeyboardProcess, NULL, 0);
// open MIDI files
OpenMidiFiles();
@@ -1164,8 +1164,8 @@ void TinselEngine::ChopDrivers() {
DeleteMidiBuffer();
// remove event drivers
- _scheduler->killProcess(pMouseProcess);
- _scheduler->killProcess(pKeyboardProcess);
+ _scheduler->killProcess(g_pMouseProcess);
+ _scheduler->killProcess(g_pKeyboardProcess);
}
/**
@@ -1177,7 +1177,7 @@ void TinselEngine::ProcessKeyEvent(const Common::Event &event) {
switch (event.kbd.keycode) {
case Common::KEYCODE_d:
// Checks for CTRL flag, ignoring all the sticky flags
- if ((Common::KBD_CTRL == (event.kbd.flags & ~(Common::KBD_NUM|Common::KBD_CAPS|Common::KBD_SCRL))) && (event.type == Common::EVENT_KEYDOWN)) {
+ if (event.kbd.hasFlags(Common::KBD_CTRL) && event.type == Common::EVENT_KEYDOWN) {
// Activate the debugger
assert(_console);
_console->attach();
diff --git a/engines/tinsel/token.cpp b/engines/tinsel/token.cpp
index c7490a100b..c26fa40466 100644
--- a/engines/tinsel/token.cpp
+++ b/engines/tinsel/token.cpp
@@ -34,7 +34,7 @@ struct Token {
PROCESS *proc;
};
-static Token tokens[NUMTOKENS]; // FIXME: Avoid non-const global vars
+static Token g_tokens[NUMTOKENS]; // FIXME: Avoid non-const global vars
/**
@@ -44,8 +44,8 @@ static void TerminateProcess(PROCESS *tProc) {
// Release tokens held by the process
for (int i = 0; i < NUMTOKENS; i++) {
- if (tokens[i].proc == tProc) {
- tokens[i].proc = NULL;
+ if (g_tokens[i].proc == tProc) {
+ g_tokens[i].proc = NULL;
}
}
@@ -59,8 +59,8 @@ static void TerminateProcess(PROCESS *tProc) {
void GetControlToken() {
const int which = TOKEN_CONTROL;
- if (tokens[which].proc == NULL) {
- tokens[which].proc = g_scheduler->getCurrentProcess();
+ if (g_tokens[which].proc == NULL) {
+ g_tokens[which].proc = g_scheduler->getCurrentProcess();
}
}
@@ -69,7 +69,7 @@ void GetControlToken() {
*/
void FreeControlToken() {
// Allow anyone to free TOKEN_CONTROL
- tokens[TOKEN_CONTROL].proc = NULL;
+ g_tokens[TOKEN_CONTROL].proc = NULL;
}
@@ -84,12 +84,12 @@ void FreeControlToken() {
void GetToken(int which) {
assert(TOKEN_LEAD <= which && which < NUMTOKENS);
- if (tokens[which].proc != NULL) {
- assert(tokens[which].proc != g_scheduler->getCurrentProcess());
- TerminateProcess(tokens[which].proc);
+ if (g_tokens[which].proc != NULL) {
+ assert(g_tokens[which].proc != g_scheduler->getCurrentProcess());
+ TerminateProcess(g_tokens[which].proc);
}
- tokens[which].proc = g_scheduler->getCurrentProcess();
+ g_tokens[which].proc = g_scheduler->getCurrentProcess();
}
/**
@@ -99,9 +99,9 @@ void GetToken(int which) {
void FreeToken(int which) {
assert(TOKEN_LEAD <= which && which < NUMTOKENS);
- assert(tokens[which].proc == g_scheduler->getCurrentProcess()); // we'd have been killed if some other proc had taken this token
+ assert(g_tokens[which].proc == g_scheduler->getCurrentProcess()); // we'd have been killed if some other proc had taken this token
- tokens[which].proc = NULL;
+ g_tokens[which].proc = NULL;
}
/**
@@ -111,7 +111,7 @@ bool TestToken(int which) {
if (which < 0 || which >= NUMTOKENS)
return false;
- return (tokens[which].proc == NULL);
+ return (g_tokens[which].proc == NULL);
}
/**
@@ -119,7 +119,7 @@ bool TestToken(int which) {
*/
void FreeAllTokens() {
for (int i = 0; i < NUMTOKENS; i++) {
- tokens[i].proc = NULL;
+ g_tokens[i].proc = NULL;
}
}
diff --git a/engines/toltecs/animation.cpp b/engines/toltecs/animation.cpp
new file mode 100644
index 0000000000..eef9cef9ed
--- /dev/null
+++ b/engines/toltecs/animation.cpp
@@ -0,0 +1,164 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ *
+ */
+
+#include "toltecs/toltecs.h"
+#include "toltecs/animation.h"
+#include "toltecs/palette.h"
+#include "toltecs/screen.h"
+
+namespace Toltecs {
+
+AnimationPlayer::AnimationPlayer(ToltecsEngine *vm) : _vm(vm) {
+ _animBuffer = new byte[262144];
+}
+
+AnimationPlayer::~AnimationPlayer() {
+ delete[] _animBuffer;
+}
+
+void AnimationPlayer::start(uint resIndex) {
+ debug(1, "AnimationPlayer::start(%d)", resIndex);
+
+ _resIndex = resIndex;
+
+ _vm->_arc->openResource(_resIndex);
+ _height = _vm->_arc->readUint16LE();
+ _width = _vm->_arc->readUint16LE();
+ _frameCount = _vm->_arc->readUint16LE();
+ _vm->_arc->read(_vm->_palette->getAnimPalette(), 768);
+ _curFrameSize = _vm->_arc->readUint32LE();
+ _nextFrameOffset = _curFrameSize + 782;
+ _vm->_arc->read(_animBuffer, _curFrameSize);
+ _nextFrameSize = _vm->_arc->readUint32LE();
+ _vm->_arc->closeResource();
+
+ debug(1, "AnimationPlayer::start() width = %d; height = %d; frameCount = %d", _width, _height, _frameCount);
+
+ _vm->_sceneWidth = _width;
+ _vm->_sceneHeight = _height;
+
+ unpackFrame();
+
+ _keepFrameCounter = 0;
+ _frameNumber = 0;
+ // TODO mov screenFlag01, 0FFFFh
+ // TODO mov animDrawFrameFlag, 0FFFFh
+
+ _firstNextFrameOffset = _nextFrameOffset;
+ _firstCurFrameSize = _curFrameSize;
+ _firstNextFrameSize = _nextFrameSize;
+
+}
+
+void AnimationPlayer::nextFrame() {
+ debug(1, "AnimationPlayer::nextFrame()");
+
+ if (_frameNumber == _frameCount) {
+ _nextFrameOffset = _firstNextFrameOffset;
+ _curFrameSize = _firstCurFrameSize;
+ _nextFrameSize = _firstNextFrameSize;
+ _frameNumber = 1;
+ } else {
+ _frameNumber++;
+ }
+
+ debug(1, "AnimationPlayer::nextFrame() frameNumber = %d", _frameNumber);
+
+ if (_keepFrameCounter > 0) {
+ _keepFrameCounter--;
+ return;
+ }
+
+ _vm->_arc->openResource(_resIndex);
+ _vm->_arc->seek(_nextFrameOffset, SEEK_CUR);
+ _curFrameSize = _nextFrameSize;
+
+ if (_curFrameSize == 0)
+ _curFrameSize = 1;
+
+ _vm->_arc->read(_animBuffer, _curFrameSize);
+ _nextFrameSize = _vm->_arc->readUint32LE();
+ _nextFrameOffset += _curFrameSize + 4;
+
+ if (_curFrameSize > 1) {
+ unpackFrame();
+ // TODO mov animDrawFrameFlag, 0FFFFh
+ } else {
+ _keepFrameCounter = _animBuffer[0] - 1;
+ // TODO mov animDrawFrameFlag, 0
+ }
+
+ _vm->_arc->closeResource();
+
+
+}
+
+int16 AnimationPlayer::getStatus() {
+ debug(1, "AnimationPlayer::getStatus()");
+ int16 status = -1;
+ if (_frameNumber == _frameCount)
+ status = 0;
+ else if (_frameNumber == _frameCount - 1)
+ status = 1;
+ debug(1, "AnimationPlayer::getStatus() status = %d", status);
+ return status;
+}
+
+void AnimationPlayer::unpackFrame() {
+ _vm->_screen->unpackRle(_animBuffer, _vm->_screen->_frontScreen, _width, _height);
+ _vm->_screen->unpackRle(_animBuffer, _vm->_screen->_backScreen, _width, _height);
+ _vm->_screen->_fullRefresh = true;
+}
+
+void AnimationPlayer::saveState(Common::WriteStream *out) {
+ out->writeUint16LE(_resIndex);
+ // NOTE: The original engine doesn't save width/height, but we do
+ out->writeUint16LE(_width);
+ out->writeUint16LE(_height);
+ out->writeUint16LE(_frameCount);
+ out->writeUint16LE(_frameNumber);
+ out->writeUint32LE(_keepFrameCounter);
+ out->writeUint32LE(_curFrameSize);
+ out->writeUint32LE(_nextFrameSize);
+ out->writeUint32LE(_nextFrameOffset);
+ out->writeUint32LE(_firstCurFrameSize);
+ out->writeUint32LE(_firstNextFrameSize);
+ out->writeUint32LE(_firstNextFrameOffset);
+}
+
+void AnimationPlayer::loadState(Common::ReadStream *in) {
+ _resIndex = in->readUint16LE();
+ _width = in->readUint16LE();
+ _height = in->readUint16LE();
+ _frameCount = in->readUint16LE();
+ _frameNumber = in->readUint16LE();
+ _keepFrameCounter = in->readUint32LE();
+ _curFrameSize = in->readUint32LE();
+ _nextFrameSize = in->readUint32LE();
+ _nextFrameOffset = in->readUint32LE();
+ _firstCurFrameSize = in->readUint32LE();
+ _firstNextFrameSize = in->readUint32LE();
+ _firstNextFrameOffset = in->readUint32LE();
+}
+
+} // End of namespace Toltecs
diff --git a/engines/m4/staticres.cpp b/engines/toltecs/animation.h
index 520c0ad58e..22576d7535 100644
--- a/engines/m4/staticres.cpp
+++ b/engines/toltecs/animation.h
@@ -18,44 +18,52 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
+ *
*/
-#include "m4/staticres.h"
+#ifndef TOLTECS_ANIMATION_H
+#define TOLTECS_ANIMATION_H
-namespace M4 {
+#include "toltecs/toltecs.h"
+#include "toltecs/resource.h"
-const char *englishMADSArticleList[9] = {
- NULL, "with", "to", "at", "from", "on", "in", "under", "behind"
-};
+namespace Toltecs {
-const char *cheatingEnabledDesc[3] = {
- "CHEATING ENABLED",
- "(For your convenience).",
- NULL
-};
+class AnimationPlayer {
+public:
+ AnimationPlayer(ToltecsEngine *vm);
+ ~AnimationPlayer();
+
+ void start(uint resIndex);
+ void nextFrame();
+ int16 getStatus();
+ uint16 getFrameNumber() const { return _frameNumber; }
+
+ void saveState(Common::WriteStream *out);
+ void loadState(Common::ReadStream *in);
+
+//protected:
+public:
+ ToltecsEngine *_vm;
+
+ // 262144
+ byte *_animBuffer;
+
+ uint16 _resIndex;
+
+ uint16 _width, _height;
+ uint16 _frameNumber, _frameCount;
+ uint32 _keepFrameCounter;
+
+ uint32 _curFrameSize;
+ uint32 _nextFrameSize, _nextFrameOffset;
+
+ uint32 _firstNextFrameOffset, _firstCurFrameSize, _firstNextFrameSize;
+
+ void unpackFrame();
-const char *atStr = "at";
-const char *lookAroundStr = "Look around";
-const char *toStr = "to ";
-const char *useStr = "Use ";
-const char *walkToStr = "Walk to ";
-const char *fenceStr = "fence";
-const char *overStr = "over";
-
-const char *GameReleaseInfoStr = "ScummVM rev: 8.43 14-Sept-92";
-const char *GameReleaseTitleStr = "GAME RELASE VERSION INFO";
-
-VerbInit verbList[10] = {
- {kVerbLook, 2, 0},
- {kVerbTake, 2, 0},
- {kVerbPush, 2, 0},
- {kVerbOpen, 2, 0},
- {kVerbPut, 1, -1},
- {kVerbTalkTo, 2, 0},
- {kVerbGive, 1, 2},
- {kVerbPull, 2, 0},
- {kVerbClose, 2, 0},
- {kVerbThrow, 1, 3}
};
-} // End of namespace M4
+} // End of namespace Toltecs
+
+#endif /* TOLTECS_ANIMATION_H */
diff --git a/engines/toltecs/detection.cpp b/engines/toltecs/detection.cpp
new file mode 100644
index 0000000000..c532bbbf09
--- /dev/null
+++ b/engines/toltecs/detection.cpp
@@ -0,0 +1,306 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ *
+ */
+
+#include "base/plugins.h"
+
+#include "engines/advancedDetector.h"
+#include "common/savefile.h"
+#include "common/str-array.h"
+#include "common/system.h"
+
+#include "toltecs/toltecs.h"
+
+
+namespace Toltecs {
+
+struct ToltecsGameDescription {
+ ADGameDescription desc;
+};
+
+uint32 ToltecsEngine::getFeatures() const {
+ return _gameDescription->desc.flags;
+}
+
+Common::Language ToltecsEngine::getLanguage() const {
+ return _gameDescription->desc.language;
+}
+
+}
+
+static const PlainGameDescriptor toltecsGames[] = {
+ {"toltecs", "3 Skulls of the Toltecs"},
+ {0, 0}
+};
+
+
+namespace Toltecs {
+
+static const ToltecsGameDescription gameDescriptions[] = {
+
+ {
+ // 3 Skulls of the Toltecs English version
+ {
+ "toltecs",
+ 0,
+ AD_ENTRY1s("WESTERN", "05472037e9cfde146e953c434e74f0f4", 337643527),
+ Common::EN_ANY,
+ Common::kPlatformPC,
+ ADGF_NO_FLAGS,
+ GUIO1(GUIO_NONE)
+ },
+ },
+
+ {
+ // 3 Skulls of the Toltecs Russian version
+ {
+ "toltecs",
+ 0,
+ AD_ENTRY1s("WESTERN", "ba1742d3193b68ceb9434e2ab7a09a9b", 391462783),
+ Common::RU_RUS,
+ Common::kPlatformPC,
+ ADGF_NO_FLAGS,
+ GUIO1(GUIO_NONE)
+ },
+ },
+
+ {
+ // 3 Skulls of the Toltecs German version
+ {
+ "toltecs",
+ 0,
+ AD_ENTRY1s("WESTERN", "1a3292bad8e0bb5701800c73531dd75e", 345176617),
+ Common::DE_DEU,
+ Common::kPlatformPC,
+ ADGF_NO_FLAGS,
+ GUIO1(GUIO_NONE)
+ },
+ },
+
+ {
+ // 3 Skulls of the Toltecs German Demo version
+ {
+ "toltecs",
+ 0,
+ AD_ENTRY1s("WESTERN", "1c85e82712d24f1d5c1ea2a66ddd75c2", 47730038),
+ Common::DE_DEU,
+ Common::kPlatformPC,
+ ADGF_NO_FLAGS,
+ GUIO1(GUIO_NONE)
+ },
+ },
+
+ {
+ // 3 Skulls of the Toltecs French version
+ {
+ "toltecs",
+ 0,
+ AD_ENTRY1s("WESTERN", "4fb845635cbdac732453fe23be350df9", 327269545),
+ Common::FR_FRA,
+ Common::kPlatformPC,
+ ADGF_NO_FLAGS,
+ GUIO1(GUIO_NONE)
+ },
+ },
+
+ {
+ // 3 Skulls of the Toltecs Spanish version
+ {
+ "toltecs",
+ 0,
+ AD_ENTRY1s("WESTERN", "479f468beccc1b0ce5873ec523d1380e", 308391018),
+ Common::ES_ESP,
+ Common::kPlatformPC,
+ ADGF_NO_FLAGS,
+ GUIO1(GUIO_NONE)
+ },
+ },
+
+ {
+ // 3 Skulls of the Toltecs Hungarian version
+ // From bug #3440641
+ {
+ "toltecs",
+ 0,
+ AD_ENTRY1s("WESTERN", "69a5572e75409d8c6230b787faa353af", 337647960),
+ Common::HU_HUN,
+ Common::kPlatformPC,
+ ADGF_NO_FLAGS,
+ GUIO1(GUIO_NONE)
+ },
+ },
+
+ { AD_TABLE_END_MARKER }
+};
+
+} // End of namespace Toltecs
+
+class ToltecsMetaEngine : public AdvancedMetaEngine {
+public:
+ ToltecsMetaEngine() : AdvancedMetaEngine(Toltecs::gameDescriptions, sizeof(Toltecs::ToltecsGameDescription), toltecsGames) {
+ _singleid = "toltecs";
+ }
+
+ virtual const char *getName() const {
+ return "Toltecs Engine";
+ }
+
+ virtual const char *getOriginalCopyright() const {
+ return "Toltecs Engine Revistronic (C) 1996";
+ }
+
+ virtual bool hasFeature(MetaEngineFeature f) const;
+ virtual bool createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const;
+ SaveStateList listSaves(const char *target) const;
+ virtual int getMaximumSaveSlot() const;
+ void removeSaveState(const char *target, int slot) const;
+ SaveStateDescriptor querySaveMetaInfos(const char *target, int slot) const;
+};
+
+bool ToltecsMetaEngine::hasFeature(MetaEngineFeature f) const {
+ return
+ (f == kSupportsListSaves) ||
+ (f == kSupportsLoadingDuringStartup) ||
+ (f == kSupportsDeleteSave) ||
+ (f == kSavesSupportMetaInfo) ||
+ (f == kSavesSupportThumbnail) ||
+ (f == kSavesSupportCreationDate) ||
+ (f == kSavesSupportPlayTime);
+}
+
+bool Toltecs::ToltecsEngine::hasFeature(EngineFeature f) const {
+ return
+ (f == kSupportsRTL) ||
+ (f == kSupportsLoadingDuringRuntime) ||
+ (f == kSupportsSavingDuringRuntime);
+}
+
+bool ToltecsMetaEngine::createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const {
+ const Toltecs::ToltecsGameDescription *gd = (const Toltecs::ToltecsGameDescription *)desc;
+ if (gd) {
+ *engine = new Toltecs::ToltecsEngine(syst, gd);
+ }
+ return gd != 0;
+}
+
+SaveStateList ToltecsMetaEngine::listSaves(const char *target) const {
+ Common::SaveFileManager *saveFileMan = g_system->getSavefileManager();
+ Toltecs::ToltecsEngine::SaveHeader header;
+ Common::String pattern = target;
+ pattern += ".???";
+
+ Common::StringArray filenames;
+ filenames = saveFileMan->listSavefiles(pattern.c_str());
+ Common::sort(filenames.begin(), filenames.end()); // Sort (hopefully ensuring we are sorted numerically..)
+
+ SaveStateList saveList;
+ for (Common::StringArray::const_iterator file = filenames.begin(); file != filenames.end(); file++) {
+ // Obtain the last 3 digits of the filename, since they correspond to the save slot
+ int slotNum = atoi(file->c_str() + file->size() - 3);
+
+ if (slotNum >= 0 && slotNum <= 999) {
+ Common::InSaveFile *in = saveFileMan->openForLoading(file->c_str());
+ if (in) {
+ if (Toltecs::ToltecsEngine::readSaveHeader(in, false, header) == Toltecs::ToltecsEngine::kRSHENoError) {
+ saveList.push_back(SaveStateDescriptor(slotNum, header.description));
+ }
+ delete in;
+ }
+ }
+ }
+
+ return saveList;
+}
+
+int ToltecsMetaEngine::getMaximumSaveSlot() const {
+ return 999;
+}
+
+void ToltecsMetaEngine::removeSaveState(const char *target, int slot) const {
+ Common::SaveFileManager *saveFileMan = g_system->getSavefileManager();
+ Common::String filename = Toltecs::ToltecsEngine::getSavegameFilename(target, slot);
+
+ saveFileMan->removeSavefile(filename.c_str());
+
+ Common::StringArray filenames;
+ Common::String pattern = target;
+ pattern += ".???";
+ filenames = saveFileMan->listSavefiles(pattern.c_str());
+ Common::sort(filenames.begin(), filenames.end()); // Sort (hopefully ensuring we are sorted numerically..)
+
+ for (Common::StringArray::const_iterator file = filenames.begin(); file != filenames.end(); ++file) {
+ // Obtain the last 3 digits of the filename, since they correspond to the save slot
+ int slotNum = atoi(file->c_str() + file->size() - 3);
+
+ // Rename every slot greater than the deleted slot,
+ if (slotNum > slot) {
+ saveFileMan->renameSavefile(file->c_str(), filename.c_str());
+ filename = Toltecs::ToltecsEngine::getSavegameFilename(target, ++slot);
+ }
+ }
+}
+
+SaveStateDescriptor ToltecsMetaEngine::querySaveMetaInfos(const char *target, int slot) const {
+ Common::String filename = Toltecs::ToltecsEngine::getSavegameFilename(target, slot);
+ Common::InSaveFile *in = g_system->getSavefileManager()->openForLoading(filename.c_str());
+
+ if (in) {
+ Toltecs::ToltecsEngine::SaveHeader header;
+ Toltecs::ToltecsEngine::kReadSaveHeaderError error;
+
+ error = Toltecs::ToltecsEngine::readSaveHeader(in, true, header);
+ delete in;
+
+ if (error == Toltecs::ToltecsEngine::kRSHENoError) {
+ SaveStateDescriptor desc(slot, header.description);
+
+ desc.setDeletableFlag(true);
+ desc.setWriteProtectedFlag(false);
+ desc.setThumbnail(header.thumbnail);
+
+ if (header.version > 0) {
+ int day = (header.saveDate >> 24) & 0xFF;
+ int month = (header.saveDate >> 16) & 0xFF;
+ int year = header.saveDate & 0xFFFF;
+
+ desc.setSaveDate(year, month, day);
+
+ int hour = (header.saveTime >> 16) & 0xFF;
+ int minutes = (header.saveTime >> 8) & 0xFF;
+
+ desc.setSaveTime(hour, minutes);
+
+ desc.setPlayTime(header.playTime * 1000);
+ }
+
+ return desc;
+ }
+ }
+
+ return SaveStateDescriptor();
+} // End of namespace Toltecs
+
+#if PLUGIN_ENABLED_DYNAMIC(TOLTECS)
+ REGISTER_PLUGIN_DYNAMIC(TOLTECS, PLUGIN_TYPE_ENGINE, ToltecsMetaEngine);
+#else
+ REGISTER_PLUGIN_STATIC(TOLTECS, PLUGIN_TYPE_ENGINE, ToltecsMetaEngine);
+#endif
diff --git a/engines/toltecs/menu.cpp b/engines/toltecs/menu.cpp
new file mode 100644
index 0000000000..172ec0a565
--- /dev/null
+++ b/engines/toltecs/menu.cpp
@@ -0,0 +1,613 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ *
+ */
+
+#include "common/savefile.h"
+
+#include "toltecs/toltecs.h"
+#include "toltecs/menu.h"
+#include "toltecs/palette.h"
+#include "toltecs/render.h"
+#include "toltecs/resource.h"
+
+namespace Toltecs {
+
+MenuSystem::MenuSystem(ToltecsEngine *vm) : _vm(vm) {
+}
+
+MenuSystem::~MenuSystem() {
+}
+
+int MenuSystem::run() {
+
+ //debug("MenuSystem::run()");
+
+ _background = new Graphics::Surface();
+ _background->create(640, 400, Graphics::PixelFormat::createFormatCLUT8());
+
+ // Save original background
+ Graphics::Surface backgroundOrig;
+ backgroundOrig.create(640, 400, Graphics::PixelFormat::createFormatCLUT8());
+ memcpy(backgroundOrig.getBasePtr(0,0), _vm->_screen->_frontScreen, 640 * 400);
+
+ _currMenuID = kMenuIdNone;
+ _newMenuID = kMenuIdMain;
+ _currItemID = kItemIdNone;
+ _editingDescription = false;
+ _cfgText = true;
+ _cfgVoices = true;
+ _cfgMasterVolume = 10;
+ _cfgVoicesVolume = 10;
+ _cfgMusicVolume = 10;
+ _cfgSoundFXVolume = 10;
+ _cfgBackgroundVolume = 10;
+ _running = true;
+ _top = 30 - _vm->_guiHeight / 2;
+ _needRedraw = false;
+
+ // TODO: buildColorTransTable2
+ _vm->_palette->buildColorTransTable(0, 16, 7);
+
+ _vm->_screen->_renderQueue->clear();
+ // Draw the menu background and frame
+ _vm->_screen->blastSprite(0x140 + _vm->_cameraX, 0x175 + _vm->_cameraY, 0, 1, 0x4000);
+ shadeRect(60, 39, 520, 246, 30, 94);
+
+ memcpy(_background->pixels, _vm->_screen->_frontScreen, 640 * 400);
+
+ while (_running) {
+ update();
+ _vm->_system->updateScreen();
+ }
+
+ // Restore original background
+ memcpy(_vm->_screen->_frontScreen, backgroundOrig.getBasePtr(0,0), 640 * 400);
+ _vm->_system->copyRectToScreen((const byte *)_vm->_screen->_frontScreen, 640, 0, 0, 640, 400);
+ _vm->_system->updateScreen();
+
+ // Cleanup
+ backgroundOrig.free();
+ _background->free();
+ delete _background;
+
+ return 0;
+}
+
+void MenuSystem::update() {
+
+ if (_currMenuID != _newMenuID) {
+ _currMenuID = _newMenuID;
+ //debug("_currMenuID = %d", _currMenuID);
+ initMenu(_currMenuID);
+ }
+
+ handleEvents();
+
+ if (_needRedraw) {
+ //_vm->_system->copyRectToScreen((const byte *)_vm->_screen->_frontScreen + 39 * 640 + 60, 640, 60, 39, 520, 247);
+ _vm->_system->copyRectToScreen((const byte *)_vm->_screen->_frontScreen, 640, 0, 0, 640, 400);
+ //debug("redraw");
+ _needRedraw = false;
+ }
+
+ _vm->_system->delayMillis(5);
+
+}
+
+void MenuSystem::handleEvents() {
+
+ Common::Event event;
+ Common::EventManager *eventMan = _vm->_system->getEventManager();
+ while (eventMan->pollEvent(event)) {
+ switch (event.type) {
+ case Common::EVENT_KEYDOWN:
+ handleKeyDown(event.kbd);
+ break;
+ case Common::EVENT_QUIT:
+ _running = false;
+ break;
+ case Common::EVENT_MOUSEMOVE:
+ handleMouseMove(event.mouse.x, event.mouse.y);
+ break;
+ case Common::EVENT_LBUTTONDOWN:
+ handleMouseClick(event.mouse.x, event.mouse.y);
+ break;
+ default:
+ break;
+ }
+ }
+
+}
+
+void MenuSystem::addClickTextItem(ItemID id, int x, int y, int w, uint fontNum, const char *caption, byte defaultColor, byte activeColor) {
+ Item item;
+ item.id = id;
+ item.defaultColor = defaultColor;
+ item.activeColor = activeColor;
+ item.x = x;
+ item.y = y;
+ item.w = w;
+ item.fontNum = fontNum;
+ setItemCaption(&item, caption);
+ _items.push_back(item);
+}
+
+void MenuSystem::drawItem(ItemID itemID, bool active) {
+ Item *item = getItem(itemID);
+ if (item) {
+ byte color = active ? item->activeColor : item->defaultColor;
+ drawString(item->rect.left, item->y, 0, item->fontNum, color, item->caption.c_str());
+ }
+}
+
+void MenuSystem::handleMouseMove(int x, int y) {
+ if (!_editingDescription) {
+ ItemID newItemID = findItemAt(x, y);
+ if (_currItemID != newItemID) {
+ leaveItem(_currItemID);
+ _currItemID = newItemID;
+ enterItem(newItemID);
+ }
+ }
+}
+
+void MenuSystem::handleMouseClick(int x, int y) {
+ if (!_editingDescription) {
+ ItemID id = findItemAt(x, y);
+ clickItem(id);
+ }
+}
+
+void MenuSystem::handleKeyDown(const Common::KeyState& kbd) {
+ if (_editingDescription) {
+ if (kbd.keycode >= Common::KEYCODE_SPACE && kbd.keycode <= Common::KEYCODE_z) {
+ _editingDescriptionItem->caption += kbd.ascii;
+ restoreRect(_editingDescriptionItem->rect.left, _editingDescriptionItem->rect.top,
+ _editingDescriptionItem->rect.width() + 1, _editingDescriptionItem->rect.height() - 2);
+ setItemCaption(_editingDescriptionItem, _editingDescriptionItem->caption.c_str());
+ drawItem(_editingDescriptionID, true);
+ } else if (kbd.keycode == Common::KEYCODE_BACKSPACE) {
+ _editingDescriptionItem->caption.deleteLastChar();
+ restoreRect(_editingDescriptionItem->rect.left, _editingDescriptionItem->rect.top,
+ _editingDescriptionItem->rect.width() + 1, _editingDescriptionItem->rect.height() - 2);
+ setItemCaption(_editingDescriptionItem, _editingDescriptionItem->caption.c_str());
+ drawItem(_editingDescriptionID, true);
+ } else if (kbd.keycode == Common::KEYCODE_RETURN) {
+ SavegameItem *savegameItem = getSavegameItemByID(_editingDescriptionID);
+ _editingDescription = false;
+ _vm->requestSavegame(savegameItem->_slotNum, _editingDescriptionItem->caption);
+ _running = false;
+ } else if (kbd.keycode == Common::KEYCODE_ESCAPE) {
+ _editingDescription = false;
+ }
+ }
+}
+
+ItemID MenuSystem::findItemAt(int x, int y) {
+ for (Common::Array<Item>::iterator iter = _items.begin(); iter != _items.end(); iter++) {
+ if ((*iter).rect.contains(x, y))
+ return (*iter).id;
+ }
+ return kItemIdNone;
+}
+
+MenuSystem::Item *MenuSystem::getItem(ItemID id) {
+ for (Common::Array<Item>::iterator iter = _items.begin(); iter != _items.end(); iter++) {
+ if ((*iter).id == id)
+ return &(*iter);
+ }
+ return NULL;
+}
+
+void MenuSystem::setItemCaption(Item *item, const char *caption) {
+ Font font(_vm->_res->load(_vm->_screen->getFontResIndex(item->fontNum))->data);
+ int width = font.getTextWidth((const byte*)caption);
+ int height = font.getHeight();
+ item->rect = Common::Rect(item->x, item->y - height, item->x + width, item->y);
+ if (item->w) {
+ item->rect.translate(item->w - width / 2, 0);
+ }
+ item->caption = caption;
+}
+
+void MenuSystem::initMenu(MenuID menuID) {
+ int newSlotNum;
+
+ _items.clear();
+
+ memcpy(_vm->_screen->_frontScreen, _background->pixels, 640 * 400);
+
+ switch (menuID) {
+ case kMenuIdMain:
+ drawString(0, 74, 320, 1, 229, _vm->getSysString(kStrWhatCanIDoForYou));
+ addClickTextItem(kItemIdLoad, 0, 115, 320, 0, _vm->getSysString(kStrLoad), 229, 255);
+ addClickTextItem(kItemIdSave, 0, 135, 320, 0, _vm->getSysString(kStrSave), 229, 255);
+ addClickTextItem(kItemIdToggleText, 0, 165, 320, 0, _vm->getSysString(kStrTextOn), 229, 255);
+ addClickTextItem(kItemIdToggleVoices, 0, 185, 320, 0, _vm->getSysString(kStrVoicesOn), 229, 255);
+ addClickTextItem(kItemIdVolumesMenu, 0, 215, 320, 0, _vm->getSysString(kStrVolume), 229, 255);
+ addClickTextItem(kItemIdPlay, 0, 245, 320, 0, _vm->getSysString(kStrPlay), 229, 255);
+ addClickTextItem(kItemIdQuit, 0, 275, 320, 0, _vm->getSysString(kStrQuit), 229, 255);
+ break;
+ case kMenuIdLoad:
+ drawString(0, 74, 320, 1, 229, _vm->getSysString(kStrLoadGame));
+ addClickTextItem(kItemIdSavegameUp, 0, 155, 545, 1, "^", 255, 253);
+ addClickTextItem(kItemIdSavegameDown, 0, 195, 545, 1, "\\", 255, 253);
+ addClickTextItem(kItemIdCancel, 0, 275, 320, 0, _vm->getSysString(kStrCancel), 255, 253);
+ for (int i = 1; i <= 7; i++) {
+ Common::String saveDesc = Common::String::format("SAVEGAME %d", i);
+ addClickTextItem((ItemID)(kItemIdSavegame1 + i - 1), 0, 115 + 20 * (i - 1), 300, 0, saveDesc.c_str(), 231, 234);
+ }
+ loadSavegamesList();
+ setSavegameCaptions();
+ break;
+ case kMenuIdSave:
+ drawString(0, 74, 320, 1, 229, _vm->getSysString(kStrSaveGame));
+ addClickTextItem(kItemIdSavegameUp, 0, 155, 545, 1, "^", 255, 253);
+ addClickTextItem(kItemIdSavegameDown, 0, 195, 545, 1, "\\", 255, 253);
+ addClickTextItem(kItemIdCancel, 0, 275, 320, 0, _vm->getSysString(kStrCancel), 255, 253);
+ for (int i = 1; i <= 7; i++) {
+ Common::String saveDesc = Common::String::format("SAVEGAME %d", i);
+ addClickTextItem((ItemID)(kItemIdSavegame1 + i - 1), 0, 115 + 20 * (i - 1), 300, 0, saveDesc.c_str(), 231, 234);
+ }
+ newSlotNum = loadSavegamesList() + 1;
+ _savegames.push_back(SavegameItem(newSlotNum, Common::String::format("GAME %03d", _savegames.size() + 1)));
+ setSavegameCaptions();
+ break;
+ case kMenuIdVolumes:
+ drawString(0, 74, 320, 1, 229, _vm->getSysString(kStrAdjustVolume));
+ drawString(0, 130, 200, 0, 246, _vm->getSysString(kStrMaster));
+ drawString(0, 155, 200, 0, 244, _vm->getSysString(kStrVoices));
+ drawString(0, 180, 200, 0, 244, _vm->getSysString(kStrMusic));
+ drawString(0, 205, 200, 0, 244, _vm->getSysString(kStrSoundFx));
+ drawString(0, 230, 200, 0, 244, _vm->getSysString(kStrBackground));
+ addClickTextItem(kItemIdDone, 0, 275, 200, 0, _vm->getSysString(kStrDone), 229, 253);
+ addClickTextItem(kItemIdCancel, 0, 275, 440, 0, _vm->getSysString(kStrCancel), 229, 253);
+ addClickTextItem(kItemIdMasterDown, 0, 130 + 25 * 0, 348, 1, "[", 229, 253);
+ addClickTextItem(kItemIdVoicesDown, 0, 130 + 25 * 1, 348, 1, "[", 229, 253);
+ addClickTextItem(kItemIdMusicDown, 0, 130 + 25 * 2, 348, 1, "[", 229, 253);
+ addClickTextItem(kItemIdSoundFXDown, 0, 130 + 25 * 3, 348, 1, "[", 229, 253);
+ addClickTextItem(kItemIdBackgroundDown, 0, 130 + 25 * 4, 348, 1, "[", 229, 253);
+ addClickTextItem(kItemIdMasterUp, 0, 130 + 25 * 0, 372, 1, "]", 229, 253);
+ addClickTextItem(kItemIdVoicesUp, 0, 130 + 25 * 1, 372, 1, "]", 229, 253);
+ addClickTextItem(kItemIdMusicUp, 0, 130 + 25 * 2, 372, 1, "]", 229, 253);
+ addClickTextItem(kItemIdSoundFXUp, 0, 130 + 25 * 3, 372, 1, "]", 229, 253);
+ addClickTextItem(kItemIdBackgroundUp, 0, 130 + 25 * 4, 372, 1, "]", 229, 253);
+ drawVolumeBar(kItemIdMaster);
+ drawVolumeBar(kItemIdVoices);
+ drawVolumeBar(kItemIdMusic);
+ drawVolumeBar(kItemIdSoundFX);
+ drawVolumeBar(kItemIdBackground);
+ break;
+ default:
+ break;
+ }
+
+ for (Common::Array<Item>::iterator iter = _items.begin(); iter != _items.end(); iter++) {
+ drawItem((*iter).id, false);
+ }
+
+}
+
+void MenuSystem::enterItem(ItemID id) {
+ drawItem(id, true);
+}
+
+void MenuSystem::leaveItem(ItemID id) {
+ drawItem(id, false);
+}
+
+void MenuSystem::clickItem(ItemID id) {
+ //Item *item = getItem(id);
+ switch (id) {
+ // Main menu
+ case kItemIdSave:
+ _newMenuID = kMenuIdSave;
+ break;
+ case kItemIdLoad:
+ _newMenuID = kMenuIdLoad;
+ break;
+ case kItemIdToggleText:
+ setCfgText(!_cfgText, true);
+ if (!_cfgVoices && !_cfgText)
+ setCfgVoices(true, false);
+ break;
+ case kItemIdToggleVoices:
+ setCfgVoices(!_cfgVoices, true);
+ if (!_cfgVoices && !_cfgText)
+ setCfgText(true, false);
+ break;
+ case kItemIdVolumesMenu:
+ //debug("kItemIdVolumesMenu");
+ _newMenuID = kMenuIdVolumes;
+ break;
+ case kItemIdPlay:
+ //debug("kItemIdPlay");
+ _running = false;
+ break;
+ case kItemIdQuit:
+ _running = false;
+ _vm->quitGame();
+ break;
+ // Volumes menu
+ case kItemIdMasterUp:
+ changeVolumeBar(kItemIdMaster, +1);
+ break;
+ case kItemIdVoicesUp:
+ changeVolumeBar(kItemIdVoices, +1);
+ break;
+ case kItemIdMusicUp:
+ changeVolumeBar(kItemIdMusic, +1);
+ break;
+ case kItemIdSoundFXUp:
+ changeVolumeBar(kItemIdSoundFX, +1);
+ break;
+ case kItemIdBackgroundUp:
+ changeVolumeBar(kItemIdBackground, +1);
+ break;
+ case kItemIdMasterDown:
+ changeVolumeBar(kItemIdMaster, -1);
+ break;
+ case kItemIdVoicesDown:
+ changeVolumeBar(kItemIdVoices, -1);
+ break;
+ case kItemIdMusicDown:
+ changeVolumeBar(kItemIdMusic, -1);
+ break;
+ case kItemIdSoundFXDown:
+ changeVolumeBar(kItemIdSoundFX, -1);
+ break;
+ case kItemIdBackgroundDown:
+ changeVolumeBar(kItemIdBackground, -1);
+ break;
+ case kItemIdCancel:
+ _newMenuID = kMenuIdMain;
+ break;
+ // Save/Load menu
+ case kItemIdSavegame1:
+ case kItemIdSavegame2:
+ case kItemIdSavegame3:
+ case kItemIdSavegame4:
+ case kItemIdSavegame5:
+ case kItemIdSavegame6:
+ case kItemIdSavegame7:
+ clickSavegameItem(id);
+ break;
+ case kItemIdDone:
+ _newMenuID = kMenuIdMain;
+ break;
+ case kItemIdSavegameUp:
+ scrollSavegames(-6);
+ break;
+ case kItemIdSavegameDown:
+ scrollSavegames(+6);
+ break;
+ default:
+ break;
+ }
+}
+
+void MenuSystem::restoreRect(int x, int y, int w, int h) {
+ byte *src = (byte *)_background->getBasePtr(x, y);
+ byte *dst = _vm->_screen->_frontScreen + x + y * 640;
+ while (h--) {
+ memcpy(dst, src, w);
+ src += 640;
+ dst += 640;
+ }
+}
+
+void MenuSystem::shadeRect(int x, int y, int w, int h, byte color1, byte color2) {
+ byte *src = (byte *)_background->getBasePtr(x, y);
+ for (int xc = 0; xc < w; xc++) {
+ src[xc] = color2;
+ src[xc + h * 640] = color1;
+ }
+ src += 640;
+ w -= 1;
+ h -= 1;
+ while (h--) {
+ src[0] = color2;
+ src[w] = color1;
+ src += 640;
+ }
+}
+
+void MenuSystem::drawString(int16 x, int16 y, int w, uint fontNum, byte color, const char *text) {
+ fontNum = _vm->_screen->getFontResIndex(fontNum);
+ Font font(_vm->_res->load(fontNum)->data);
+ if (w) {
+ x = x + w - font.getTextWidth((const byte*)text) / 2;
+ }
+ _vm->_screen->drawString(x, y - font.getHeight(), color, fontNum, (const byte*)text, -1, NULL, true);
+ _needRedraw = true;
+}
+
+int MenuSystem::loadSavegamesList() {
+
+ int maxSlotNum = -1;
+
+ _savegameListTopIndex = 0;
+ _savegames.clear();
+
+ Common::SaveFileManager *saveFileMan = g_system->getSavefileManager();
+ Toltecs::ToltecsEngine::SaveHeader header;
+ Common::String pattern = _vm->getTargetName();
+ pattern += ".???";
+
+ Common::StringArray filenames;
+ filenames = saveFileMan->listSavefiles(pattern.c_str());
+ Common::sort(filenames.begin(), filenames.end()); // Sort (hopefully ensuring we are sorted numerically..)
+
+ for (Common::StringArray::const_iterator file = filenames.begin(); file != filenames.end(); file++) {
+ // Obtain the last 3 digits of the filename, since they correspond to the save slot
+ int slotNum = atoi(file->c_str() + file->size() - 3);
+ if (slotNum > maxSlotNum)
+ maxSlotNum = slotNum;
+
+ if (slotNum >= 0 && slotNum <= 999) {
+ Common::InSaveFile *in = saveFileMan->openForLoading(file->c_str());
+ if (in) {
+ if (Toltecs::ToltecsEngine::readSaveHeader(in, false, header) == Toltecs::ToltecsEngine::kRSHENoError) {
+ _savegames.push_back(SavegameItem(slotNum, header.description));
+ //debug("%s -> %s", file->c_str(), header.description.c_str());
+ }
+ delete in;
+ }
+ }
+ }
+
+ return maxSlotNum;
+}
+
+MenuSystem::SavegameItem *MenuSystem::getSavegameItemByID(ItemID id) {
+ if (id >= kItemIdSavegame1 && id <= kItemIdSavegame7)
+ return &_savegames[_savegameListTopIndex + id - kItemIdSavegame1];
+ else
+ return NULL;
+}
+
+void MenuSystem::setSavegameCaptions() {
+ uint index = _savegameListTopIndex;
+ for (int i = 1; i <= 7; i++)
+ setItemCaption(getItem((ItemID)(kItemIdSavegame1 + i - 1)), index < _savegames.size() ? _savegames[index++]._description.c_str() : "");
+}
+
+void MenuSystem::scrollSavegames(int delta) {
+ int newPos = CLIP<int>(_savegameListTopIndex + delta, 0, _savegames.size() - 1);
+ _savegameListTopIndex = newPos;
+ restoreRect(80, 92, 440, 140);
+ setSavegameCaptions();
+ for (int i = 1; i <= 7; i++)
+ drawItem((ItemID)(kItemIdSavegame1 + i - 1), false);
+}
+
+void MenuSystem::clickSavegameItem(ItemID id) {
+ if (_currMenuID == kMenuIdLoad) {
+ SavegameItem *savegameItem = getSavegameItemByID(id);
+ //debug("slotNum = [%d]; description = [%s]", savegameItem->_slotNum, savegameItem->_description.c_str());
+ //_vm->loadgame(savegameItem->_filename.c_str());
+ _vm->requestLoadgame(savegameItem->_slotNum);
+ _running = false;
+ } else {
+ _editingDescription = true;
+ _editingDescriptionItem = getItem(id);
+ _editingDescriptionID = id;
+ _editingDescriptionItem->activeColor = 249;
+ _editingDescriptionItem->defaultColor = 249;
+ drawItem(_editingDescriptionID, true);
+ }
+}
+
+void MenuSystem::setCfgText(bool value, bool active) {
+ if (_cfgText != value) {
+ Item *item = getItem(kItemIdToggleText);
+ _cfgText = value;
+ restoreRect(item->rect.left, item->rect.top, item->rect.width() + 1, item->rect.height() - 2);
+ setItemCaption(item, _vm->getSysString(_cfgText ? kStrTextOn : kStrTextOff));
+ drawItem(kItemIdToggleText, true);
+ }
+}
+
+void MenuSystem::setCfgVoices(bool value, bool active) {
+ if (_cfgVoices != value) {
+ Item *item = getItem(kItemIdToggleVoices);
+ _cfgVoices = value;
+ restoreRect(item->rect.left, item->rect.top, item->rect.width() + 1, item->rect.height() - 2);
+ setItemCaption(item, _vm->getSysString(_cfgVoices ? kStrVoicesOn : kStrVoicesOff));
+ drawItem(kItemIdToggleVoices, true);
+ }
+}
+
+void MenuSystem::drawVolumeBar(ItemID itemID) {
+ int w = 440, y, volume;
+ char text[21];
+
+ switch (itemID) {
+ case kItemIdMaster:
+ y = 130 + 25 * 0;
+ volume = _cfgMasterVolume;
+ break;
+ case kItemIdVoices:
+ y = 130 + 25 * 1;
+ volume = _cfgVoicesVolume;
+ break;
+ case kItemIdMusic:
+ y = 130 + 25 * 2;
+ volume = _cfgMusicVolume;
+ break;
+ case kItemIdSoundFX:
+ y = 130 + 25 * 3;
+ volume = _cfgSoundFXVolume;
+ break;
+ case kItemIdBackground:
+ y = 130 + 25 * 4;
+ volume = _cfgBackgroundVolume;
+ break;
+ default:
+ return;
+ }
+
+ Font font(_vm->_res->load(_vm->_screen->getFontResIndex(1))->data);
+ restoreRect(390, y - font.getHeight(), 100, 25);
+
+ for (int i = 0; i < volume; i++)
+ text[i] = '|';
+ text[volume] = 0;
+
+ drawString(0, y, w, 0, 246, text);
+
+}
+
+void MenuSystem::changeVolumeBar(ItemID itemID, int delta) {
+
+ int *volume, newVolume;
+
+ switch (itemID) {
+ case kItemIdMaster:
+ volume = &_cfgMasterVolume;
+ break;
+ case kItemIdVoices:
+ volume = &_cfgVoicesVolume;
+ break;
+ case kItemIdMusic:
+ volume = &_cfgMusicVolume;
+ break;
+ case kItemIdSoundFX:
+ volume = &_cfgSoundFXVolume;
+ break;
+ case kItemIdBackground:
+ volume = &_cfgBackgroundVolume;
+ break;
+ default:
+ return;
+ }
+
+ newVolume = CLIP(*volume + delta, 0, 20);
+
+ if (newVolume != *volume) {
+ *volume = newVolume;
+ drawVolumeBar(itemID);
+ }
+
+}
+
+} // End of namespace Toltecs
diff --git a/engines/toltecs/menu.h b/engines/toltecs/menu.h
new file mode 100644
index 0000000000..3e2c2da8d9
--- /dev/null
+++ b/engines/toltecs/menu.h
@@ -0,0 +1,167 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public 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 TOLTECS_MENU_H
+#define TOLTECS_MENU_H
+
+#include "common/array.h"
+#include "common/str-array.h"
+
+namespace Toltecs {
+
+enum MenuID {
+ kMenuIdNone,
+ kMenuIdMain,
+ kMenuIdSave,
+ kMenuIdLoad,
+ kMenuIdVolumes
+};
+
+enum ItemID {
+ kItemIdNone,
+ // Main menu
+ kItemIdSave,
+ kItemIdLoad,
+ kItemIdToggleText,
+ kItemIdToggleVoices,
+ kItemIdVolumesMenu,
+ kItemIdPlay,
+ kItemIdQuit,
+ // Volumes menu
+ kItemIdMasterUp,
+ kItemIdVoicesUp,
+ kItemIdMusicUp,
+ kItemIdSoundFXUp,
+ kItemIdBackgroundUp,
+ kItemIdMasterDown,
+ kItemIdVoicesDown,
+ kItemIdMusicDown,
+ kItemIdSoundFXDown,
+ kItemIdBackgroundDown,
+ kItemIdMaster,
+ kItemIdVoices,
+ kItemIdMusic,
+ kItemIdSoundFX,
+ kItemIdBackground,
+ kItemIdDone,
+ kItemIdCancel,
+ // Save/load menu
+ kItemIdSavegameUp,
+ kItemIdSavegameDown,
+ kItemIdSavegame1,
+ kItemIdSavegame2,
+ kItemIdSavegame3,
+ kItemIdSavegame4,
+ kItemIdSavegame5,
+ kItemIdSavegame6,
+ kItemIdSavegame7,
+ // TODO
+ kMenuIdDummy
+};
+
+class MenuSystem {
+
+public:
+ MenuSystem(ToltecsEngine *vm);
+ ~MenuSystem();
+
+ int run();
+ void update();
+ void handleEvents();
+
+protected:
+
+ struct Item {
+ Common::Rect rect;
+ ItemID id;
+ Common::String caption;
+ byte defaultColor, activeColor;
+ int x, y, w;
+ uint fontNum;
+ };
+
+ struct SavegameItem {
+ int _slotNum;
+ Common::String _description;
+ SavegameItem()
+ : _slotNum(-1), _description("") {}
+ SavegameItem(int slotNum, Common::String description)
+ : _slotNum(slotNum), _description(description) {}
+ };
+
+ ToltecsEngine *_vm;
+ Graphics::Surface *_background;
+
+ bool _running;
+ MenuID _currMenuID, _newMenuID;
+ ItemID _currItemID;
+ int _top;
+ int _savegameListTopIndex;
+ bool _editingDescription;
+ ItemID _editingDescriptionID;
+ Item *_editingDescriptionItem;
+ bool _needRedraw;
+
+ Common::Array<Item> _items;
+ Common::Array<SavegameItem> _savegames;
+
+ bool _cfgText, _cfgVoices;
+ int _cfgMasterVolume, _cfgVoicesVolume, _cfgMusicVolume, _cfgSoundFXVolume, _cfgBackgroundVolume;
+
+ void addClickTextItem(ItemID id, int x, int y, int w, uint fontNum, const char *caption, byte defaultColor, byte activeColor);
+
+ void drawItem(ItemID itemID, bool active);
+ void handleMouseMove(int x, int y);
+ void handleMouseClick(int x, int y);
+ void handleKeyDown(const Common::KeyState& kbd);
+
+ ItemID findItemAt(int x, int y);
+ Item *getItem(ItemID id);
+ void setItemCaption(Item *item, const char *caption);
+
+ void initMenu(MenuID menuID);
+
+ void enterItem(ItemID id);
+ void leaveItem(ItemID id);
+ void clickItem(ItemID id);
+
+ void restoreRect(int x, int y, int w, int h);
+ void shadeRect(int x, int y, int w, int h, byte color1, byte color2);
+ void drawString(int16 x, int16 y, int w, uint fontNum, byte color, const char *text);
+
+ SavegameItem *getSavegameItemByID(ItemID id);
+
+ int loadSavegamesList();
+ void setSavegameCaptions();
+ void scrollSavegames(int delta);
+ void clickSavegameItem(ItemID id);
+ void setCfgText(bool value, bool active);
+ void setCfgVoices(bool value, bool active);
+ void drawVolumeBar(ItemID itemID);
+ void changeVolumeBar(ItemID itemID, int delta);
+
+};
+
+} // End of namespace Toltecs
+
+#endif /* TOLTECS_MENU_H */
diff --git a/engines/toltecs/microtiles.cpp b/engines/toltecs/microtiles.cpp
new file mode 100644
index 0000000000..0b61ac38a5
--- /dev/null
+++ b/engines/toltecs/microtiles.cpp
@@ -0,0 +1,215 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ *
+ */
+
+#include "toltecs/microtiles.h"
+
+namespace Toltecs {
+
+MicroTileArray::MicroTileArray(int16 width, int16 height) {
+ _tilesW = (width / TileSize) + ((width % TileSize) > 0 ? 1 : 0);
+ _tilesH = (height / TileSize) + ((height % TileSize) > 0 ? 1 : 0);
+ _tiles = new BoundingBox[_tilesW * _tilesH];
+ clear();
+}
+
+MicroTileArray::~MicroTileArray() {
+ delete[] _tiles;
+}
+
+void MicroTileArray::addRect(Common::Rect r) {
+
+ int ux0, uy0, ux1, uy1;
+ int tx0, ty0, tx1, ty1;
+ int ix0, iy0, ix1, iy1;
+
+ r.clip(Common::Rect(0, 0, 639, 399));
+
+ ux0 = r.left / TileSize;
+ uy0 = r.top / TileSize;
+ ux1 = r.right / TileSize;
+ uy1 = r.bottom / TileSize;
+
+ tx0 = r.left % TileSize;
+ ty0 = r.top % TileSize;
+ tx1 = r.right % TileSize;
+ ty1 = r.bottom % TileSize;
+
+ for (int yc = uy0; yc <= uy1; yc++) {
+ for (int xc = ux0; xc <= ux1; xc++) {
+ ix0 = (xc == ux0) ? tx0 : 0;
+ ix1 = (xc == ux1) ? tx1 : TileSize - 1;
+ iy0 = (yc == uy0) ? ty0 : 0;
+ iy1 = (yc == uy1) ? ty1 : TileSize - 1;
+ updateBoundingBox(_tiles[xc + yc * _tilesW], ix0, iy0, ix1, iy1);
+ }
+ }
+
+}
+
+void MicroTileArray::clear() {
+ memset(_tiles, 0, _tilesW * _tilesH * sizeof(BoundingBox));
+}
+
+byte MicroTileArray::TileX0(const BoundingBox &boundingBox) {
+ return (boundingBox >> 24) & 0xFF;
+}
+
+byte MicroTileArray::TileY0(const BoundingBox &boundingBox) {
+ return (boundingBox >> 16) & 0xFF;
+}
+
+byte MicroTileArray::TileX1(const BoundingBox &boundingBox) {
+ return (boundingBox >> 8) & 0xFF;
+}
+
+byte MicroTileArray::TileY1(const BoundingBox &boundingBox) {
+ return boundingBox & 0xFF;
+}
+
+bool MicroTileArray::isBoundingBoxEmpty(const BoundingBox &boundingBox) {
+ return boundingBox == EmptyBoundingBox;
+}
+
+bool MicroTileArray::isBoundingBoxFull(const BoundingBox &boundingBox) {
+ return boundingBox == FullBoundingBox;
+}
+
+void MicroTileArray::setBoundingBox(BoundingBox &boundingBox, byte x0, byte y0, byte x1, byte y1) {
+ boundingBox = (x0 << 24) | (y0 << 16) | (x1 << 8) | y1;
+}
+
+void MicroTileArray::updateBoundingBox(BoundingBox &boundingBox, byte x0, byte y0, byte x1, byte y1) {
+ if (!isBoundingBoxEmpty(boundingBox)) {
+ x0 = MIN(TileX0(boundingBox), x0);
+ y0 = MIN(TileY0(boundingBox), y0);
+ x1 = MAX(TileX1(boundingBox), x1);
+ y1 = MAX(TileY1(boundingBox), y1);
+ }
+ setBoundingBox(boundingBox, x0, y0, x1, y1);
+}
+
+Common::Rect * MicroTileArray::getRectangles(int *num_rects, int min_x, int min_y, int max_x, int max_y) {
+
+ Common::Rect *rects = new Common::Rect[_tilesW * _tilesH];
+
+ int n_rects = 0;
+ int x, y;
+ int x0, y0, x1, y1;
+ int i = 0;
+
+ for (y = 0; y < _tilesH; ++y) {
+ for (x = 0; x < _tilesW; ++x) {
+
+ int start;
+ int finish = 0;
+ BoundingBox boundingBox;
+
+ boundingBox = _tiles[i];
+
+ if (isBoundingBoxEmpty(boundingBox)) {
+ ++i;
+ continue;
+ }
+
+ x0 = (x * TileSize) + TileX0(boundingBox);
+ y0 = (y * TileSize) + TileY0(boundingBox);
+ y1 = (y * TileSize) + TileY1(boundingBox);
+
+ x0 = CLIP (x0, min_x, max_x);
+ y0 = CLIP (y0, min_y, max_y);
+ y1 = CLIP (y1, min_y, max_y);
+
+ // FIXME: Why is the following code in an #if block?
+#if 1
+ start = i;
+
+ if (TileX1(boundingBox) == TileSize - 1 && x != _tilesW - 1) { // check if the tile continues
+ while (!finish) {
+ ++x;
+ ++i;
+
+ if (x == _tilesW || i >= _tilesW * _tilesH ||
+ TileY0(_tiles[i]) != TileY0(boundingBox) ||
+ TileY1(_tiles[i]) != TileY1(boundingBox) ||
+ TileX0(_tiles[i]) != 0)
+ {
+ --x;
+ --i;
+ finish = 1;
+ }
+ }
+ }
+#endif
+ x1 = (x * TileSize) + TileX1(_tiles[i]);
+
+ x1 = CLIP (x1, min_x, max_x);
+
+ // FIXME: Why is the following code in an #if block?
+
+ #if 1
+
+ rects[n_rects].left = x0;
+ rects[n_rects].top = y0;
+ rects[n_rects].right = x1 + 1;
+ rects[n_rects].bottom = y1 + 1;
+ n_rects++;
+
+ #else
+
+ // FIXME: Why is this code disabled?
+
+ if (glom [start] != -1 && /* try to glom */
+ rects [glom [start]].left == x0 &&
+ rects [glom [start]].right == x1 &&
+ rects [glom [start]].bottom == y0 - 1)
+ {
+ rects [glom [start]].bottom = y1;
+ if (y != tilesH - 1) {
+ glom [start + tilesW] = glom [start];
+ }
+ } else {
+ rects[n_rects].left = x0;
+ rects[n_rects].top = y0;
+ rects[n_rects].right = x1;
+ rects[n_rects].bottom = y1;
+ if (y != tilesH - 1) {
+ glom [start + tilesW] = n_rects;
+ }
+ n_rects ++;
+ }
+
+ #endif
+
+ ++i;
+ } // for (x = 0; x < _tilesW; ++x)
+ } // for (y = 0; y < _tilesH; ++y)
+
+ *num_rects = n_rects;
+
+ //delete glom;
+
+ return rects;
+
+}
+
+} // End of namespace Toltecs
diff --git a/engines/toltecs/microtiles.h b/engines/toltecs/microtiles.h
new file mode 100644
index 0000000000..53933621a9
--- /dev/null
+++ b/engines/toltecs/microtiles.h
@@ -0,0 +1,61 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ *
+ */
+
+#ifndef TOLTECS_MICROTILES_H
+#define TOLTECS_MICROTILES_H
+
+#include "common/scummsys.h"
+#include "common/util.h"
+#include "common/rect.h"
+
+namespace Toltecs {
+
+typedef uint32 BoundingBox;
+
+const BoundingBox FullBoundingBox = 0x00001F1F;
+const BoundingBox EmptyBoundingBox = 0x00000000;
+const int TileSize = 32;
+
+class MicroTileArray {
+public:
+ MicroTileArray(int16 width, int16 height);
+ ~MicroTileArray();
+ void addRect(Common::Rect r);
+ void clear();
+ Common::Rect *getRectangles(int *num_rects, int min_x, int min_y, int max_x, int max_y);
+protected:
+ BoundingBox *_tiles;
+ int16 _tilesW, _tilesH;
+ byte TileX0(const BoundingBox &boundingBox);
+ byte TileY0(const BoundingBox &boundingBox);
+ byte TileX1(const BoundingBox &boundingBox);
+ byte TileY1(const BoundingBox &boundingBox);
+ bool isBoundingBoxEmpty(const BoundingBox &boundingBox);
+ bool isBoundingBoxFull(const BoundingBox &boundingBox);
+ void setBoundingBox(BoundingBox &boundingBox, byte x0, byte y0, byte x1, byte y1);
+ void updateBoundingBox(BoundingBox &boundingBox, byte x0, byte y0, byte x1, byte y1);
+};
+
+} // namespace Toltecs
+
+#endif // TOLTECS_MICROTILES_H
diff --git a/engines/toltecs/module.mk b/engines/toltecs/module.mk
new file mode 100644
index 0000000000..aa4a6f376b
--- /dev/null
+++ b/engines/toltecs/module.mk
@@ -0,0 +1,28 @@
+MODULE := engines/toltecs
+
+MODULE_OBJS = \
+ animation.o \
+ detection.o \
+ menu.o \
+ microtiles.o \
+ movie.o \
+ music.o \
+ palette.o \
+ toltecs.o \
+ render.o \
+ resource.o \
+ saveload.o \
+ screen.o \
+ script.o \
+ segmap.o \
+ sound.o \
+ sprite.o
+
+
+# This module can be built as a plugin
+ifeq ($(ENABLE_TOLTECS), DYNAMIC_PLUGIN)
+PLUGIN := 1
+endif
+
+# Include common rules
+include $(srcdir)/rules.mk
diff --git a/engines/toltecs/movie.cpp b/engines/toltecs/movie.cpp
new file mode 100644
index 0000000000..76d42ebf0a
--- /dev/null
+++ b/engines/toltecs/movie.cpp
@@ -0,0 +1,289 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ *
+ */
+
+#include "audio/mixer.h"
+#include "audio/decoders/raw.h"
+
+#include "toltecs/toltecs.h"
+#include "toltecs/movie.h"
+#include "toltecs/palette.h"
+#include "toltecs/resource.h"
+#include "toltecs/screen.h"
+#include "toltecs/script.h"
+
+namespace Toltecs {
+
+enum ChunkTypes {
+ kChunkFirstImage = 0,
+ kChunkSubsequentImages = 1,
+ kChunkPalette = 2,
+ kChunkUnused = 3,
+ kChunkAudio = 4,
+ kChunkShowSubtitle = 5,
+ kChunkShakeScreen = 6,
+ kChunkSetupSubtitles = 7,
+ kChunkStopSubtitles = 8
+};
+
+MoviePlayer::MoviePlayer(ToltecsEngine *vm) : _vm(vm) {
+}
+
+MoviePlayer::~MoviePlayer() {
+}
+
+void MoviePlayer::playMovie(uint resIndex) {
+
+ const uint32 subtitleSlot = kMaxScriptSlots - 1;
+ int16 savedSceneWidth = _vm->_sceneWidth;
+ int16 savedSceneHeight = _vm->_sceneHeight;
+ int16 savedCameraHeight = _vm->_cameraHeight;
+ int16 savedCameraX = _vm->_cameraX;
+ int16 savedCameraY = _vm->_cameraY;
+ int16 savedGuiHeight = _vm->_guiHeight;
+ byte moviePalette[768];
+
+ _vm->_isSaveAllowed = false;
+
+ memset(moviePalette, 0, sizeof(moviePalette));
+
+ _vm->_screen->finishTalkTextItems();
+ _vm->_screen->clearSprites();
+
+ _vm->_arc->openResource(resIndex);
+
+ _frameCount = _vm->_arc->readUint32LE();
+ _chunkCount = _vm->_arc->readUint32LE();
+
+ // TODO: Figure out rest of the header
+ _vm->_arc->readUint32LE();
+ _vm->_arc->readUint32LE();
+ _framesPerSoundChunk = _vm->_arc->readUint32LE();
+ _vm->_arc->readUint32LE();
+
+ _vm->_sceneWidth = 640;
+ _vm->_sceneHeight = 400;
+ _vm->_cameraHeight = 400;
+ _vm->_cameraX = 0;
+ _vm->_cameraY = 0;
+ _vm->_guiHeight = 0;
+
+ _audioStream = Audio::makeQueuingAudioStream(22050, false);
+
+ _vm->_mixer->playStream(Audio::Mixer::kPlainSoundType, &_audioStreamHandle, _audioStream);
+
+ _soundChunkFramesLeft = 0;
+ _lastPrefetchOfs = 0;
+
+ fetchAudioChunks();
+
+ uint32 lastTime = _vm->_mixer->getSoundElapsedTime(_audioStreamHandle);
+
+ while (_chunkCount--) {
+
+ byte chunkType = _vm->_arc->readByte();
+ uint32 chunkSize = _vm->_arc->readUint32LE();
+ byte *chunkBuffer = NULL;
+ uint32 movieOffset;
+
+ debug(0, "chunkType = %d; chunkSize = %d", chunkType, chunkSize);
+
+ // Skip audio chunks - we've already queued them in
+ // fetchAudioChunks() above
+ if (chunkType == kChunkAudio) {
+ _vm->_arc->skip(chunkSize);
+ } else {
+ chunkBuffer = new byte[chunkSize];
+ _vm->_arc->read(chunkBuffer, chunkSize);
+ }
+
+ movieOffset = _vm->_arc->pos();
+
+ switch (chunkType) {
+ case kChunkFirstImage:
+ case kChunkSubsequentImages:
+ unpackRle(chunkBuffer, _vm->_screen->_backScreen);
+ // TODO: Rework this
+ _vm->_screen->updateShakeScreen();
+ _vm->_screen->_fullRefresh = true;
+ _vm->updateInput();
+ _vm->drawScreen();
+
+ _soundChunkFramesLeft--;
+ if (_soundChunkFramesLeft <= _framesPerSoundChunk) {
+ fetchAudioChunks();
+ }
+
+ while (_vm->_mixer->getSoundElapsedTime(_audioStreamHandle) < lastTime + 111) {
+ g_system->delayMillis(10);
+ }
+
+ lastTime = _vm->_mixer->getSoundElapsedTime(_audioStreamHandle);
+
+ break;
+ case kChunkPalette:
+ unpackPalette(chunkBuffer, moviePalette, 256, 3);
+ _vm->_palette->setFullPalette(moviePalette);
+ break;
+ case kChunkUnused:
+ error("Chunk considered to be unused has been encountered");
+ case kChunkAudio:
+ // Already processed
+ break;
+ case kChunkShowSubtitle:
+ // TODO: Check if the text is a subtitle (last character == 0xFE).
+ // If so, don't show it if text display is disabled.
+ memcpy(_vm->_script->getSlotData(subtitleSlot), chunkBuffer, chunkSize);
+ _vm->_screen->updateTalkText(subtitleSlot, 0);
+ break;
+ case kChunkShakeScreen: // start/stop shakescreen effect
+ if (chunkBuffer[0] == 0xFF)
+ _vm->_screen->stopShakeScreen();
+ else
+ _vm->_screen->startShakeScreen(chunkBuffer[0]);
+ break;
+ case kChunkSetupSubtitles: // setup subtitle parameters
+ _vm->_screen->_talkTextY = READ_LE_UINT16(chunkBuffer + 0);
+ _vm->_screen->_talkTextX = READ_LE_UINT16(chunkBuffer + 2);
+ _vm->_screen->_talkTextFontColor = ((chunkBuffer[4] << 4) & 0xF0) | ((chunkBuffer[4] >> 4) & 0x0F);
+ debug(0, "_talkTextX = %d; _talkTextY = %d; _talkTextFontColor = %d",
+ _vm->_screen->_talkTextX, _vm->_screen->_talkTextY, _vm->_screen->_talkTextFontColor);
+ break;
+ case kChunkStopSubtitles:
+ _vm->_script->getSlotData(subtitleSlot)[0] = 0xFF;
+ _vm->_screen->finishTalkTextItems();
+ break;
+ default:
+ error("MoviePlayer::playMovie(%04X) Unknown chunk type %d at %08X", resIndex, chunkType, _vm->_arc->pos() - 5 - chunkSize);
+ }
+
+ delete[] chunkBuffer;
+
+ _vm->_arc->seek(movieOffset, SEEK_SET);
+
+ if (!handleInput())
+ break;
+
+ }
+
+ _audioStream->finish();
+ _vm->_mixer->stopHandle(_audioStreamHandle);
+
+ _vm->_arc->closeResource();
+
+ debug(0, "playMovie() done");
+
+ _vm->_sceneWidth = savedSceneWidth;
+ _vm->_sceneHeight = savedSceneHeight;
+ _vm->_cameraHeight = savedCameraHeight;
+ _vm->_cameraX = savedCameraX;
+ _vm->_cameraY = savedCameraY;
+ _vm->_guiHeight = savedGuiHeight;
+
+ _vm->_isSaveAllowed = true;
+}
+
+void MoviePlayer::fetchAudioChunks() {
+
+ uint32 startOfs = _vm->_arc->pos();
+ uint32 chunkCount = _chunkCount;
+ uint prefetchChunkCount = 0;
+
+ if (_lastPrefetchOfs != 0)
+ _vm->_arc->seek(_lastPrefetchOfs, SEEK_SET);
+
+ while (chunkCount-- && prefetchChunkCount < _framesPerSoundChunk / 2) {
+ byte chunkType = _vm->_arc->readByte();
+ uint32 chunkSize = _vm->_arc->readUint32LE();
+ if (chunkType == 4) {
+ byte *chunkBuffer = (byte *)malloc(chunkSize);
+ _vm->_arc->read(chunkBuffer, chunkSize);
+ _audioStream->queueBuffer(chunkBuffer, chunkSize, DisposeAfterUse::YES, Audio::FLAG_UNSIGNED);
+ chunkBuffer = NULL;
+ prefetchChunkCount++;
+ _soundChunkFramesLeft += _framesPerSoundChunk;
+ } else {
+ _vm->_arc->seek(chunkSize, SEEK_CUR);
+ }
+ }
+
+ _lastPrefetchOfs = _vm->_arc->pos();
+
+ _vm->_arc->seek(startOfs, SEEK_SET);
+
+}
+
+void MoviePlayer::unpackPalette(byte *source, byte *dest, int elemCount, int elemSize) {
+ int ofs = 0, size = elemCount * elemSize;
+ while (ofs < size) {
+ byte len;
+ len = *source++;
+ if (len == 0) {
+ len = *source++;
+ } else {
+ byte value = *source++;
+ memset(dest, value, len);
+ }
+ ofs += len;
+ dest += len;
+ }
+}
+
+void MoviePlayer::unpackRle(byte *source, byte *dest) {
+ int size = 256000;
+ while (size > 0) {
+ byte a = *source++;
+ byte b = *source++;
+ if (a == 0) {
+ dest += b;
+ size -= b;
+ } else {
+ memset(dest, b, a);
+ dest += a;
+ size -= a;
+ }
+ }
+}
+
+bool MoviePlayer::handleInput() {
+ Common::Event event;
+ Common::EventManager *eventMan = g_system->getEventManager();
+ while (eventMan->pollEvent(event)) {
+ switch (event.type) {
+ case Common::EVENT_KEYDOWN:
+ if (event.kbd.keycode == Common::KEYCODE_ESCAPE)
+ return false;
+ break;
+ case Common::EVENT_LBUTTONDOWN:
+ case Common::EVENT_RBUTTONDOWN:
+ return false;
+ case Common::EVENT_QUIT:
+ _vm->quitGame();
+ return false;
+ default:
+ break;
+ }
+ }
+ return !_vm->shouldQuit();
+}
+
+} // End of namespace Toltecs
diff --git a/engines/toltecs/movie.h b/engines/toltecs/movie.h
new file mode 100644
index 0000000000..aecfac240f
--- /dev/null
+++ b/engines/toltecs/movie.h
@@ -0,0 +1,59 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ *
+ */
+
+#ifndef TOLTECS_MOVIE_H
+#define TOLTECS_MOVIE_H
+
+#include "audio/audiostream.h"
+#include "audio/mixer.h" // for Audio::SoundHandle
+
+namespace Toltecs {
+
+class MoviePlayer {
+
+public:
+ MoviePlayer(ToltecsEngine *vm);
+ ~MoviePlayer();
+
+ void playMovie(uint resIndex);
+
+protected:
+ ToltecsEngine *_vm;
+ Audio::QueuingAudioStream *_audioStream;
+ Audio::SoundHandle _audioStreamHandle;
+
+ uint32 _chunkCount, _frameCount, _lastPrefetchOfs;
+ uint32 _soundChunkFramesLeft, _framesPerSoundChunk;
+
+ void unpackPalette(byte *source, byte *dest, int elemCount, int elemSize);
+ void unpackRle(byte *source, byte *dest);
+
+ void fetchAudioChunks();
+
+ bool handleInput();
+
+};
+
+} // End of namespace Toltecs
+
+#endif /* TOLTECS_MOVIE_H */
diff --git a/engines/toltecs/music.cpp b/engines/toltecs/music.cpp
new file mode 100644
index 0000000000..c322961077
--- /dev/null
+++ b/engines/toltecs/music.cpp
@@ -0,0 +1,145 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+// FIXME: This code is taken from SAGA and needs more work (e.g. setVolume).
+
+#include "toltecs/toltecs.h"
+#include "toltecs/music.h"
+#include "toltecs/resource.h"
+
+#include "audio/midiparser.h"
+#include "common/textconsole.h"
+
+namespace Toltecs {
+
+MusicPlayer::MusicPlayer(bool isGM) : _isGM(isGM), _buffer(NULL) {
+ MidiPlayer::createDriver();
+
+ int ret = _driver->open();
+ if (ret == 0) {
+ if (_nativeMT32)
+ _driver->sendMT32Reset();
+ else
+ _driver->sendGMReset();
+
+ _driver->setTimerCallback(this, &timerCallback);
+ }
+}
+
+void MusicPlayer::send(uint32 b) {
+ if ((b & 0xF0) == 0xC0 && !_isGM && !_nativeMT32) {
+ b = (b & 0xFFFF00FF) | MidiDriver::_mt32ToGm[(b >> 8) & 0xFF] << 8;
+ }
+
+ Audio::MidiPlayer::send(b);
+}
+
+void MusicPlayer::playMIDI(const byte *data, uint32 size, bool loop) {
+ Common::StackLock lock(_mutex);
+
+ stopAndClear();
+
+ _buffer = new byte[size];
+ memcpy(_buffer, data, size);
+
+ MidiParser *parser;
+
+ if (!memcmp(data, "FORM", 4))
+ parser = MidiParser::createParser_XMIDI(NULL);
+ else
+ parser = MidiParser::createParser_SMF();
+
+ if (parser->loadMusic(_buffer, size)) {
+ parser->setTrack(0);
+ parser->setMidiDriver(this);
+ parser->setTimerRate(_driver->getBaseTempo());
+ parser->property(MidiParser::mpCenterPitchWheelOnUnload, 1);
+ parser->property(MidiParser::mpSendSustainOffOnNotesOff, 1);
+
+ _parser = parser;
+
+ setVolume(127);
+
+ _isLooping = loop;
+ _isPlaying = true;
+ } else {
+ delete parser;
+ }
+}
+
+void MusicPlayer::pause() {
+ setVolume(-1);
+ _isPlaying = false;
+}
+
+void MusicPlayer::resume() {
+ setVolume(127);
+ _isPlaying = true;
+}
+
+void MusicPlayer::stopAndClear() {
+ Common::StackLock lock(_mutex);
+ stop();
+
+ delete[] _buffer;
+ _buffer = NULL;
+}
+
+Music::Music(ArchiveReader *arc) : MusicPlayer(true), _arc(arc) {
+ _sequenceResIndex = -1;
+}
+
+void Music::playSequence(int16 sequenceResIndex) {
+ _sequenceResIndex = sequenceResIndex;
+
+ int32 resourceSize = _arc->getResourceSize(sequenceResIndex);
+ byte *data = new byte[resourceSize];
+ _arc->openResource(sequenceResIndex);
+ _arc->read(data, resourceSize);
+ _arc->closeResource();
+
+ if (!memcmp(data, "FORM", 4))
+ playMIDI(data, resourceSize, true); // music tracks are always looping
+ else
+ // Sanity check: this should never occur
+ error("playSequence: resource %d isn't XMIDI", sequenceResIndex);
+
+ delete[] data;
+}
+
+void Music::stopSequence() {
+ _sequenceResIndex = -1;
+ stopAndClear();
+}
+
+void Music::saveState(Common::WriteStream *out) {
+ out->writeSint16LE(_sequenceResIndex);
+}
+
+void Music::loadState(Common::ReadStream *in) {
+ _sequenceResIndex = in->readSint16LE();
+
+ if (_sequenceResIndex >= 0)
+ playSequence(_sequenceResIndex);
+}
+
+} // End of namespace Made
diff --git a/engines/m4/midi.h b/engines/toltecs/music.h
index 817150fd81..79df1ea2f5 100644
--- a/engines/m4/midi.h
+++ b/engines/toltecs/music.h
@@ -22,38 +22,52 @@
// Music class
-#ifndef M4_MIDI_H
-#define M4_MIDI_H
+#ifndef MADE_MUSIC_H
+#define MADE_MUSIC_H
#include "audio/midiplayer.h"
+#include "common/stream.h"
-namespace M4 {
+namespace Toltecs {
-class MidiPlayer : public Audio::MidiPlayer {
-public:
- MidiPlayer(MadsM4Engine *vm);
+class ArchiveReader;
- void playMusic(const char *name, int32 vol, bool loop, int32 trigger, int32 scene);
+class MusicPlayer : public Audio::MidiPlayer {
+public:
+ MusicPlayer(bool isGM = true);
- void setGM(bool isGM) { _isGM = isGM; }
+ void playMIDI(const byte *data, uint32 size, bool loop = false);
+ void pause();
+ void resume();
+ void stopAndClear();
// MidiDriver_BASE interface implementation
virtual void send(uint32 b);
protected:
- MadsM4Engine *_vm;
-
bool _isGM;
- bool _randomLoop;
+private:
+ byte *_buffer;
+};
+
+class Music : public MusicPlayer {
+public:
+
+ Music(ArchiveReader *arc);
+ ~Music() {}
+
+ void playSequence(int16 sequenceResIndex);
+ void stopSequence();
- byte *_musicData;
- uint16 *_buf;
- size_t _musicDataSize;
+ void saveState(Common::WriteStream *out);
+ void loadState(Common::ReadStream *in);
- byte *convertHMPtoSMF(byte *data, uint32 inSize, uint32 &outSize);
+private:
+ int16 _sequenceResIndex;
+ ArchiveReader *_arc;
};
-} // End of namespace M4
+} // End of namespace Toltecs
#endif
diff --git a/engines/toltecs/palette.cpp b/engines/toltecs/palette.cpp
new file mode 100644
index 0000000000..706218e0ba
--- /dev/null
+++ b/engines/toltecs/palette.cpp
@@ -0,0 +1,231 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ *
+ */
+
+#include "graphics/palette.h"
+
+#include "toltecs/toltecs.h"
+#include "toltecs/palette.h"
+#include "toltecs/resource.h"
+
+namespace Toltecs {
+
+Palette::Palette(ToltecsEngine *vm) : _vm(vm) {
+ clearFragments();
+
+ memset(_colorTransTable, 0, sizeof(_colorTransTable));
+}
+
+Palette::~Palette() {
+}
+
+void Palette::setFullPalette(byte *palette) {
+ byte colors[768];
+ for (int i = 0; i < 256; i++) {
+ colors[i * 3 + 0] = palette[i * 3 + 0] << 2;
+ colors[i * 3 + 1] = palette[i * 3 + 1] << 2;
+ colors[i * 3 + 2] = palette[i * 3 + 2] << 2;
+ }
+ _vm->_system->getPaletteManager()->setPalette((const byte *)colors, 0, 256);
+ _vm->_system->updateScreen();
+}
+
+void Palette::getFullPalette(byte *palette) {
+ byte colors[768];
+ _vm->_system->getPaletteManager()->grabPalette(colors, 0, 256);
+ for (int i = 0; i < 256; i++) {
+ palette[i * 3 + 0] = colors[i * 3 + 0] >> 2;
+ palette[i * 3 + 1] = colors[i * 3 + 1] >> 2;
+ palette[i * 3 + 2] = colors[i * 3 + 2] >> 2;
+ }
+}
+
+void Palette::setDeltaPalette(byte *palette, byte mask, int8 deltaValue, int16 count, int16 startIndex) {
+ byte colors[768];
+
+ byte *palPtr = palette + startIndex * 3;
+ int16 index = startIndex, colorCount = count;
+ byte rgb;
+
+ count++;
+
+ _vm->_system->getPaletteManager()->grabPalette(colors, 0, 256);
+
+ deltaValue *= -1;
+
+ while (count--) {
+ rgb = *palPtr++;
+ if (mask & 1) colors[index * 3 + 0] = CLIP<int>(rgb + deltaValue, 0, 63) << 2;
+ rgb = *palPtr++;
+ if (mask & 2) colors[index * 3 + 1] = CLIP<int>(rgb + deltaValue, 0, 63) << 2;
+ rgb = *palPtr++;
+ if (mask & 4) colors[index * 3 + 2] = CLIP<int>(rgb + deltaValue, 0, 63) << 2;
+ index++;
+ }
+
+ debug(0, "startIndex = %d; colorCount = %d", startIndex, colorCount);
+
+ _vm->_system->getPaletteManager()->setPalette((const byte *)colors, 0, 256);
+}
+
+void Palette::loadAddPalette(uint resIndex, byte startIndex) {
+ Resource *paletteResource = _vm->_res->load(resIndex);
+ memcpy(&_mainPalette[startIndex * 3], paletteResource->data, paletteResource->size);
+}
+
+void Palette::loadAddPaletteFrom(byte *source, byte startIndex, byte count) {
+ memcpy(&_mainPalette[startIndex * 3], source, count * 3);
+}
+
+void Palette::addFragment(uint resIndex, int16 id) {
+ debug(0, "Palette::addFragment(%d, %d)", resIndex, id);
+
+ Resource *fragmentResource = _vm->_res->load(resIndex);
+ byte count = fragmentResource->size / 3;
+
+ memcpy(&_mainPalette[_fragmentIndex * 3], fragmentResource->data, count * 3);
+
+ PaletteFragment fragment;
+ fragment.id = id;
+ fragment.index = _fragmentIndex;
+ fragment.count = count;
+ _fragments.push_back(fragment);
+
+ debug(0, "Palette::addFragment() index = %02X; count = %02X", fragment.index, fragment.count);
+
+ _fragmentIndex += count;
+}
+
+uint16 Palette::findFragment(int16 id) {
+ debug(0, "Palette::findFragment(%d)", id);
+
+ uint16 result = 0;
+ for (PaletteFragmentArray::iterator iter = _fragments.begin(); iter != _fragments.end(); iter++) {
+ PaletteFragment fragment = *iter;
+ if (fragment.id == id) {
+ result = (fragment.count << 8) | fragment.index;
+ break;
+ }
+ }
+
+ debug(0, "Palette::findFragment() result = %04X", result);
+
+ return result;
+}
+
+void Palette::clearFragments() {
+ debug(0, "Palette::clearFragments()");
+ _fragmentIndex = 128;
+ _fragments.clear();
+}
+
+void Palette::buildColorTransTable(byte limit, int8 deltaValue, byte mask) {
+ byte r = 0, g = 0, b = 0;
+
+ mask &= 7;
+
+ for (int i = 0; i < 256; i++) {
+
+ if (deltaValue < 0) {
+ // TODO (probably unused)
+ warning("Palette::buildColorTransTable(%d, %d, %02X) not yet implemented!", limit, deltaValue, mask);
+ } else {
+ r = _mainPalette[i * 3 + 0];
+ g = _mainPalette[i * 3 + 1];
+ b = _mainPalette[i * 3 + 2];
+ if (MAX(r, MAX(b, g)) >= limit) {
+ if ((mask & 1) && r >= deltaValue)
+ r -= deltaValue;
+ if ((mask & 2) && g >= deltaValue)
+ g -= deltaValue;
+ if ((mask & 4) && b >= deltaValue)
+ b -= deltaValue;
+ }
+ }
+
+ int bestIndex = 0;
+ uint16 bestMatch = 0xFFFF;
+
+ for (int j = 0; j < 256; j++) {
+ byte distance = ABS(_mainPalette[j * 3 + 0] - r) + ABS(_mainPalette[j * 3 + 1] - g) + ABS(_mainPalette[j * 3 + 2] - b);
+ byte maxColor = MAX(_mainPalette[j * 3 + 0], MAX(_mainPalette[j * 3 + 1], _mainPalette[j * 3 + 2]));
+ uint16 match = (distance << 8) | maxColor;
+ if (match < bestMatch) {
+ bestMatch = match;
+ bestIndex = j;
+ }
+ }
+
+ _colorTransTable[i] = bestIndex;
+
+ }
+}
+
+void Palette::buildColorTransTable2(byte limit, int8 deltaValue, byte mask) {
+ // TODO
+}
+
+void Palette::saveState(Common::WriteStream *out) {
+ // Save currently active palette
+ byte palette[768];
+ getFullPalette(palette);
+ out->write(palette, 768);
+
+ out->write(_mainPalette, 768);
+ out->write(_animPalette, 768);
+ out->write(_colorTransTable, 256);
+
+ uint16 fragmentCount = _fragments.size();
+ out->writeUint16LE(fragmentCount);
+ for (PaletteFragmentArray::iterator iter = _fragments.begin(); iter != _fragments.end(); iter++) {
+ PaletteFragment fragment = *iter;
+ out->writeUint16LE(fragment.id);
+ out->writeByte(fragment.index);
+ out->writeByte(fragment.count);
+ }
+ out->writeByte(_fragmentIndex);
+}
+
+void Palette::loadState(Common::ReadStream *in) {
+ // Save currently active palette
+ byte palette[768];
+ in->read(palette, 768);
+ setFullPalette(palette);
+
+ in->read(_mainPalette, 768);
+ in->read(_animPalette, 768);
+ in->read(_colorTransTable, 256);
+
+ uint16 fragmentCount = in->readUint16LE();
+ _fragments.clear();
+ for (uint16 i = 0; i < fragmentCount; i++) {
+ PaletteFragment fragment;
+ fragment.id = in->readUint16LE();
+ fragment.index = in->readByte();
+ fragment.count = in->readByte();
+ _fragments.push_back(fragment);
+ }
+ _fragmentIndex = in->readByte();
+}
+
+
+} // End of namespace Toltecs
diff --git a/engines/toltecs/palette.h b/engines/toltecs/palette.h
new file mode 100644
index 0000000000..7bcf06e027
--- /dev/null
+++ b/engines/toltecs/palette.h
@@ -0,0 +1,85 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ *
+ */
+
+#ifndef TOLTECS_PALETTE_H
+#define TOLTECS_PALETTE_H
+
+#include "common/array.h"
+#include "common/system.h"
+
+#include "toltecs/toltecs.h"
+
+namespace Toltecs {
+
+//#define ROT(index) (((index << 4) & 0xF0) | ((index >> 4) & 0x0F))
+//#define ROT(index) (index)
+
+class Palette {
+public:
+ Palette(ToltecsEngine *vm);
+ ~Palette();
+
+ void setFullPalette(byte *palette);
+ void getFullPalette(byte *palette);
+ void setDeltaPalette(byte *palette, byte mask, int8 deltaValue, int16 count, int16 startIndex);
+
+ void loadAddPalette(uint resIndex, byte startIndex);
+ void loadAddPaletteFrom(byte *source, byte startIndex, byte count);
+
+ void addFragment(uint resIndex, int16 id);
+ uint16 findFragment(int16 id);
+ void clearFragments();
+
+ void buildColorTransTable(byte limit, int8 deltaValue, byte mask);
+ void buildColorTransTable2(byte limit, int8 deltaValue, byte mask);
+ byte getColorTransPixel(byte pixel) const { return _colorTransTable[pixel]; }
+
+ byte *getMainPalette() { return _mainPalette; }
+ byte *getAnimPalette() { return _animPalette; }
+
+ void saveState(Common::WriteStream *out);
+ void loadState(Common::ReadStream *in);
+
+protected:
+
+ struct PaletteFragment {
+ int16 id;
+ byte index, count;
+ };
+
+ typedef Common::Array<PaletteFragment> PaletteFragmentArray;
+
+ ToltecsEngine *_vm;
+
+ byte _mainPalette[768];
+ byte _animPalette[768];
+ byte _colorTransTable[256];
+
+ PaletteFragmentArray _fragments;
+ byte _fragmentIndex;
+
+};
+
+} // End of namespace Toltecs
+
+#endif /* TOLTECS_PALETTE_H */
diff --git a/engines/toltecs/render.cpp b/engines/toltecs/render.cpp
new file mode 100644
index 0000000000..de5e77fb50
--- /dev/null
+++ b/engines/toltecs/render.cpp
@@ -0,0 +1,311 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ *
+ */
+
+#include "common/system.h"
+
+#include "toltecs/toltecs.h"
+#include "toltecs/render.h"
+#include "toltecs/resource.h"
+
+namespace Toltecs {
+
+Common::Rect makeRect(int16 x, int16 y, int16 width, int16 height) {
+ Common::Rect rect;
+ rect.left = x;
+ rect.top = y;
+ rect.setWidth(width);
+ rect.setHeight(height);
+ return rect;
+}
+
+RenderQueue::RenderQueue(ToltecsEngine *vm) : _vm(vm) {
+ _currQueue = new RenderQueueArray();
+ _prevQueue = new RenderQueueArray();
+ _updateUta = new MicroTileArray(640, 400);
+}
+
+RenderQueue::~RenderQueue() {
+ delete _currQueue;
+ delete _prevQueue;
+ delete _updateUta;
+}
+
+void RenderQueue::addSprite(SpriteDrawItem &sprite) {
+
+ RenderQueueItem item;
+ item.type = kSprite;
+ item.flags = kRefresh;
+ item.rect = makeRect(sprite.x - _vm->_cameraX, sprite.y - _vm->_cameraY, sprite.width, sprite.height);
+ item.priority = sprite.priority;
+
+ item.sprite = sprite;
+ item.sprite.x -= _vm->_cameraX;
+ item.sprite.y -= _vm->_cameraY;
+
+ // Add sprite sorted by priority
+ RenderQueueArray::iterator iter = _currQueue->begin();
+ while (iter != _currQueue->end() && (*iter).priority <= item.priority) {
+ iter++;
+ }
+ _currQueue->insert(iter, item);
+
+}
+
+void RenderQueue::addText(int16 x, int16 y, byte color, uint fontResIndex, byte *text, int len) {
+
+ Font font(_vm->_res->load(fontResIndex)->data);
+
+ RenderQueueItem item;
+ item.type = kText;
+ item.flags = kRefresh;
+ item.rect = makeRect(x, y, font.getTextWidth(text), font.getHeight());
+ item.priority = 1000;
+
+ item.text.color = color;
+ item.text.fontResIndex = fontResIndex;
+ item.text.text = text;
+ item.text.len = len;
+
+ _currQueue->push_back(item);
+
+}
+
+void RenderQueue::addMask(SegmapMaskRect &mask) {
+
+ RenderQueueItem item;
+ item.type = kMask;
+ item.flags = kRefresh;
+ item.rect = makeRect(mask.x - _vm->_cameraX, mask.y - _vm->_cameraY, mask.width, mask.height);
+ item.priority = mask.priority;
+
+ item.mask = mask;
+
+ // Only add the mask if a sprite intersects its rect
+ if (rectIntersectsItem(item.rect)) {
+ RenderQueueArray::iterator iter = _currQueue->begin();
+ while (iter != _currQueue->end() && (*iter).priority <= item.priority) {
+ iter++;
+ }
+ _currQueue->insert(iter, item);
+ }
+
+}
+
+void RenderQueue::update() {
+
+ bool doFullRefresh = _vm->_screen->_fullRefresh;
+
+ _updateUta->clear();
+
+ if (!doFullRefresh) {
+
+ for (RenderQueueArray::iterator iter = _currQueue->begin(); iter != _currQueue->end(); iter++) {
+ RenderQueueItem *item = &(*iter);
+ RenderQueueItem *prevItem = findItemInQueue(_prevQueue, *item);
+ if (prevItem) {
+ if (hasItemChanged(*prevItem, *item)) {
+ item->flags = kRefresh;
+ addDirtyRect(prevItem->rect);
+ } else {
+ item->flags = kUnchanged;
+ }
+ } else {
+ item->flags = kRefresh;
+ }
+ }
+
+ for (RenderQueueArray::iterator iter = _prevQueue->begin(); iter != _prevQueue->end(); iter++) {
+ RenderQueueItem *prevItem = &(*iter);
+ RenderQueueItem *item = findItemInQueue(_currQueue, *prevItem);
+ if (!item) {
+ prevItem->flags = kRemoved;
+ addDirtyRect(prevItem->rect);
+ }
+ }
+
+ restoreDirtyBackground();
+
+ for (RenderQueueArray::iterator iter = _currQueue->begin(); iter != _currQueue->end(); iter++) {
+ RenderQueueItem *item = &(*iter);
+ if (item->flags != kUnchanged)
+ invalidateItemsByRect(item->rect, item);
+ }
+
+ } else {
+ byte *destp = _vm->_screen->_frontScreen;
+ byte *srcp = _vm->_screen->_backScreen + _vm->_cameraX + _vm->_cameraY * _vm->_sceneWidth;
+ int16 w = MIN<int16>(640, _vm->_sceneWidth);
+ int16 h = MIN<int16>(400, _vm->_cameraHeight);
+ while (h--) {
+ memcpy(destp, srcp, w);
+ destp += 640;
+ srcp += _vm->_sceneWidth;
+ }
+ _vm->_screen->_fullRefresh = false;
+ }
+
+ for (RenderQueueArray::iterator iter = _currQueue->begin(); iter != _currQueue->end(); iter++) {
+ const RenderQueueItem *item = &(*iter);
+
+ if (item->flags == kRefresh || doFullRefresh) {
+
+ switch (item->type) {
+ case kSprite:
+ _vm->_screen->drawSprite(item->sprite);
+ break;
+ case kText:
+ _vm->_screen->drawString(item->rect.left, item->rect.top, item->text.color, item->text.fontResIndex,
+ item->text.text, item->text.len, NULL, true);
+ break;
+ case kMask:
+ _vm->_screen->drawSurface(item->rect.left, item->rect.top, item->mask.surface);
+ break;
+ default:
+ break;
+ }
+
+ if (!doFullRefresh)
+ addDirtyRect(item->rect);
+
+ }
+
+ }
+
+ if (doFullRefresh) {
+ clear();
+ _vm->_system->copyRectToScreen((const byte *)_vm->_screen->_frontScreen, 640, 0, 0, 640, _vm->_cameraHeight);
+ } else {
+ updateDirtyRects();
+ }
+
+ SWAP(_currQueue, _prevQueue);
+ _currQueue->clear();
+
+}
+
+void RenderQueue::clear() {
+ _prevQueue->clear();
+ _currQueue->clear();
+}
+
+bool RenderQueue::rectIntersectsItem(const Common::Rect &rect) {
+ for (RenderQueueArray::iterator iter = _currQueue->begin(); iter != _currQueue->end(); iter++) {
+ const RenderQueueItem *item = &(*iter);
+ if (rect.intersects(item->rect))
+ return true;
+ }
+ return false;
+}
+
+RenderQueueItem *RenderQueue::findItemInQueue(RenderQueueArray *queue, const RenderQueueItem &item) {
+ /* This checks if the given item also exists in the previously drawn frame.
+ The state of the item (position, color etc) is handled elsewhere.
+ */
+ for (RenderQueueArray::iterator iter = queue->begin(); iter != queue->end(); iter++) {
+ RenderQueueItem *prevItem = &(*iter);
+ if (prevItem->type == item.type) {
+ switch (item.type) {
+ case kSprite:
+ if (prevItem->sprite.resIndex == item.sprite.resIndex &&
+ prevItem->sprite.frameNum == item.sprite.frameNum)
+ return prevItem;
+ break;
+ case kText:
+ if (prevItem->text.text == item.text.text &&
+ prevItem->text.len == item.text.len)
+ return prevItem;
+ break;
+ case kMask:
+ if (prevItem->mask.surface == item.mask.surface)
+ return prevItem;
+ break;
+ }
+ }
+ }
+ return NULL; // Not found
+}
+
+bool RenderQueue::hasItemChanged(const RenderQueueItem &item1, const RenderQueueItem &item2) {
+
+ if (item1.type != item2.type)
+ return true;
+
+ if (item1.rect.left != item2.rect.left ||
+ item1.rect.top != item2.rect.top ||
+ item1.rect.right != item2.rect.right ||
+ item1.rect.bottom != item2.rect.bottom)
+ return true;
+
+ if (item1.type == kText && item1.text.color != item2.text.color)
+ return true;
+
+ return false;
+}
+
+void RenderQueue::invalidateItemsByRect(const Common::Rect &rect, const RenderQueueItem *item) {
+ for (RenderQueueArray::iterator iter = _currQueue->begin(); iter != _currQueue->end(); iter++) {
+ RenderQueueItem *subItem = &(*iter);
+ if (item != subItem &&
+ subItem->flags == kUnchanged &&
+ rect.intersects(subItem->rect)) {
+
+ subItem->flags = kRefresh;
+ invalidateItemsByRect(subItem->rect, subItem);
+ }
+ }
+}
+
+void RenderQueue::addDirtyRect(const Common::Rect &rect) {
+ _updateUta->addRect(rect);
+}
+
+void RenderQueue::restoreDirtyBackground() {
+ int n_rects = 0;
+ Common::Rect *rects = _updateUta->getRectangles(&n_rects, 0, 0, 639, _vm->_cameraHeight - 1);
+ for (int i = 0; i < n_rects; i++) {
+ byte *destp = _vm->_screen->_frontScreen + rects[i].left + rects[i].top * 640;
+ byte *srcp = _vm->_screen->_backScreen + (_vm->_cameraX + rects[i].left) + (_vm->_cameraY + rects[i].top) * _vm->_sceneWidth;
+ int16 w = rects[i].width();
+ int16 h = rects[i].height();
+ while (h--) {
+ memcpy(destp, srcp, w);
+ destp += 640;
+ srcp += _vm->_sceneWidth;
+ }
+ invalidateItemsByRect(rects[i], NULL);
+ }
+ delete[] rects;
+}
+
+void RenderQueue::updateDirtyRects() {
+ int n_rects = 0;
+ Common::Rect *rects = _updateUta->getRectangles(&n_rects, 0, 0, 639, _vm->_cameraHeight - 1);
+ for (int i = 0; i < n_rects; i++) {
+ _vm->_system->copyRectToScreen((const byte *)_vm->_screen->_frontScreen + rects[i].left + rects[i].top * 640,
+ 640, rects[i].left, rects[i].top, rects[i].width(), rects[i].height());
+ }
+ delete[] rects;
+}
+
+
+} // End of namespace Toltecs
diff --git a/engines/toltecs/render.h b/engines/toltecs/render.h
new file mode 100644
index 0000000000..bb9ec29959
--- /dev/null
+++ b/engines/toltecs/render.h
@@ -0,0 +1,99 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public 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 TOLTECS_RENDER_H
+#define TOLTECS_RENDER_H
+
+#include "graphics/surface.h"
+
+#include "toltecs/segmap.h"
+#include "toltecs/screen.h"
+#include "toltecs/microtiles.h"
+
+namespace Toltecs {
+
+enum RenderType {
+ kSprite,
+ kText,
+ kMask
+};
+
+enum RenderFlags {
+ kNone = 1 << 0,
+ kRefresh = 1 << 1,
+ kRemoved = 1 << 2,
+ kMoved = 1 << 3,
+ kUnchanged = 1 << 4
+};
+
+struct RenderTextItem {
+ byte color;
+ uint fontResIndex;
+ byte *text;
+ int len;
+};
+
+struct RenderQueueItem {
+ RenderType type;
+ uint flags;
+ Common::Rect rect;
+ int16 priority;
+ union {
+ SpriteDrawItem sprite;
+ RenderTextItem text;
+ SegmapMaskRect mask;
+ };
+};
+
+class RenderQueue {
+public:
+ RenderQueue(ToltecsEngine *vm);
+ ~RenderQueue();
+
+ void addSprite(SpriteDrawItem &sprite);
+ void addText(int16 x, int16 y, byte color, uint fontResIndex, byte *text, int len);
+ void addMask(SegmapMaskRect &mask);
+ void update();
+ void clear();
+
+protected:
+ typedef Common::List<RenderQueueItem> RenderQueueArray;
+
+ ToltecsEngine *_vm;
+ RenderQueueArray *_currQueue, *_prevQueue;
+ MicroTileArray *_updateUta;
+
+ bool rectIntersectsItem(const Common::Rect &rect);
+ RenderQueueItem *findItemInQueue(RenderQueueArray *queue, const RenderQueueItem &item);
+ bool hasItemChanged(const RenderQueueItem &item1, const RenderQueueItem &item2);
+ void invalidateItemsByRect(const Common::Rect &rect, const RenderQueueItem *item);
+
+ void addDirtyRect(const Common::Rect &rect);
+ void restoreDirtyBackground();
+ void updateDirtyRects();
+
+};
+
+} // End of namespace Toltecs
+
+#endif /* TOLTECS_RENDER_H */
diff --git a/engines/toltecs/resource.cpp b/engines/toltecs/resource.cpp
new file mode 100644
index 0000000000..b95e0444b1
--- /dev/null
+++ b/engines/toltecs/resource.cpp
@@ -0,0 +1,128 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ *
+ */
+
+#include "common/file.h"
+
+#include "toltecs/toltecs.h"
+#include "toltecs/resource.h"
+
+namespace Toltecs {
+
+
+/* ArchiveReader */
+
+ArchiveReader::ArchiveReader() {
+}
+
+ArchiveReader::~ArchiveReader() {
+ delete[] _offsets;
+}
+
+void ArchiveReader::openArchive(const char *filename) {
+ open(filename);
+ uint32 firstOffs = readUint32LE();
+ uint count = firstOffs / 4;
+ _offsets = new uint32[count];
+ _offsets[0] = firstOffs;
+ for (uint i = 1; i < count; i++)
+ _offsets[i] = readUint32LE();
+}
+
+uint32 ArchiveReader::openResource(uint resIndex) {
+ uint32 resourceSize = getResourceSize(resIndex);
+ seek(_offsets[resIndex]);
+ return resourceSize;
+}
+
+void ArchiveReader::closeResource() {
+}
+
+uint32 ArchiveReader::getResourceSize(uint resIndex) {
+ return _offsets[resIndex + 1] - _offsets[resIndex];
+}
+
+void ArchiveReader::dump(uint resIndex, const char *prefix) {
+ int32 resourceSize = getResourceSize(resIndex);
+ byte *data = new byte[resourceSize];
+
+ Common::String fn;
+
+ if (prefix)
+ fn = Common::String::format("%s_%04X.0", prefix, resIndex);
+ else
+ fn = Common::String::format("%04X.0", resIndex);
+
+ openResource(resIndex);
+ read(data, resourceSize);
+ closeResource();
+
+ Common::DumpFile o;
+ o.open(fn);
+ o.write(data, resourceSize);
+ o.finalize();
+ o.close();
+
+ delete[] data;
+}
+
+/* ResourceCache */
+
+ResourceCache::ResourceCache(ToltecsEngine *vm) : _vm(vm) {
+}
+
+ResourceCache::~ResourceCache() {
+ purgeCache();
+}
+
+void ResourceCache::purgeCache() {
+ for (ResourceMap::iterator iter = _cache.begin(); iter != _cache.end(); ++iter) {
+ delete[] iter->_value->data;
+ delete iter->_value;
+ iter->_value = 0;
+ }
+
+ _cache.clear();
+}
+
+Resource *ResourceCache::load(uint resIndex) {
+ ResourceMap::iterator item = _cache.find(resIndex);
+ if (item != _cache.end()) {
+ debug(1, "ResourceCache::load(%d) From cache", resIndex);
+ return (*item)._value;
+ } else {
+ debug(1, "ResourceCache::load(%d) From disk", resIndex);
+
+ Resource *resItem = new Resource();
+ resItem->size = _vm->_arc->openResource(resIndex);
+ resItem->data = new byte[resItem->size];
+ _vm->_arc->read(resItem->data, resItem->size);
+ _vm->_arc->closeResource();
+
+ _cache[resIndex] = resItem;
+
+ return resItem;
+
+ }
+}
+
+} // End of namespace Toltecs
diff --git a/engines/toltecs/resource.h b/engines/toltecs/resource.h
new file mode 100644
index 0000000000..3fed2e11ca
--- /dev/null
+++ b/engines/toltecs/resource.h
@@ -0,0 +1,85 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ *
+ */
+
+#ifndef TOLTECS_RESOURCE_H
+#define TOLTECS_RESOURCE_H
+
+#include "common/file.h"
+#include "common/hashmap.h"
+#include "common/hash-str.h"
+
+#include "engines/engine.h"
+
+namespace Toltecs {
+
+const uint kMaxCacheItems = 1024;
+const uint kMaxCacheSize = 8 * 1024 * 1024; // 8 MB
+
+
+class ArchiveReader : public Common::File {
+public:
+ ArchiveReader();
+ ~ArchiveReader();
+
+ void openArchive(const char *filename);
+
+ // Returns the size of the opened resource
+ uint32 openResource(uint resIndex);
+ // Closes the resource
+ void closeResource();
+ // Returns the size of the resource
+ uint32 getResourceSize(uint resIndex);
+
+ void dump(uint resIndex, const char *prefix = NULL);
+
+protected:
+ uint32 *_offsets;
+
+};
+
+struct Resource {
+ uint32 size;
+ byte *data;
+};
+
+class ResourceCache {
+public:
+ ResourceCache(ToltecsEngine *vm);
+ ~ResourceCache();
+
+ Resource *load(uint resIndex);
+ void purgeCache();
+
+protected:
+ typedef Common::HashMap<uint, Resource *> ResourceMap;
+
+ ToltecsEngine *_vm;
+
+ ResourceMap _cache;
+
+};
+
+
+} // End of namespace Toltecs
+
+#endif /* TOLTECS_H */
diff --git a/engines/toltecs/saveload.cpp b/engines/toltecs/saveload.cpp
new file mode 100644
index 0000000000..c24d2149b0
--- /dev/null
+++ b/engines/toltecs/saveload.cpp
@@ -0,0 +1,233 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ *
+ */
+
+#include "common/savefile.h"
+
+#include "graphics/thumbnail.h"
+
+#include "toltecs/toltecs.h"
+#include "toltecs/animation.h"
+#include "toltecs/music.h"
+#include "toltecs/palette.h"
+#include "toltecs/script.h"
+#include "toltecs/screen.h"
+#include "toltecs/sound.h"
+
+namespace Toltecs {
+
+/* TODO:
+ - Save with F7; Load with F9
+ - Saving during an animation (AnimationPlayer) is not working correctly yet
+ - Maybe switch to SCUMM/Tinsel serialization approach?
+*/
+
+#define TOLTECS_SAVEGAME_VERSION 3
+
+ToltecsEngine::kReadSaveHeaderError ToltecsEngine::readSaveHeader(Common::SeekableReadStream *in, bool loadThumbnail, SaveHeader &header) {
+
+ header.version = in->readUint32LE();
+ if (header.version > TOLTECS_SAVEGAME_VERSION)
+ return kRSHEInvalidVersion;
+
+ byte descriptionLen = in->readByte();
+ header.description = "";
+ while (descriptionLen--)
+ header.description += (char)in->readByte();
+
+ if (loadThumbnail) {
+ header.thumbnail = Graphics::loadThumbnail(*in);
+ } else {
+ Graphics::skipThumbnail(*in);
+ }
+
+ // Not used yet, reserved for future usage
+ header.gameID = in->readByte();
+ header.flags = in->readUint32LE();
+
+ if (header.version >= 1) {
+ header.saveDate = in->readUint32LE();
+ header.saveTime = in->readUint32LE();
+ header.playTime = in->readUint32LE();
+ } else {
+ header.saveDate = 0;
+ header.saveTime = 0;
+ header.playTime = 0;
+ }
+
+ return ((in->eos() || in->err()) ? kRSHEIoError : kRSHENoError);
+}
+
+void ToltecsEngine::savegame(const char *filename, const char *description) {
+ Common::OutSaveFile *out;
+ if (!(out = g_system->getSavefileManager()->openForSaving(filename))) {
+ warning("Can't create file '%s', game not saved", filename);
+ return;
+ }
+
+ TimeDate curTime;
+ g_system->getTimeAndDate(curTime);
+
+ // Header start
+ out->writeUint32LE(TOLTECS_SAVEGAME_VERSION);
+
+ byte descriptionLen = strlen(description);
+ out->writeByte(descriptionLen);
+ out->write(description, descriptionLen);
+
+ Graphics::saveThumbnail(*out);
+
+ // Not used yet, reserved for future usage
+ out->writeByte(0);
+ out->writeUint32LE(0);
+ uint32 saveDate = ((curTime.tm_mday & 0xFF) << 24) | (((curTime.tm_mon + 1) & 0xFF) << 16) | ((curTime.tm_year + 1900) & 0xFFFF);
+ uint32 saveTime = ((curTime.tm_hour & 0xFF) << 16) | (((curTime.tm_min) & 0xFF) << 8) | ((curTime.tm_sec) & 0xFF);
+ uint32 playTime = g_engine->getTotalPlayTime() / 1000;
+ out->writeUint32LE(saveDate);
+ out->writeUint32LE(saveTime);
+ out->writeUint32LE(playTime);
+ // Header end
+
+ out->writeUint16LE(_cameraX);
+ out->writeUint16LE(_cameraY);
+ out->writeUint16LE(_cameraHeight);
+
+ out->writeUint16LE(_guiHeight);
+
+ out->writeUint16LE(_sceneWidth);
+ out->writeUint16LE(_sceneHeight);
+ out->writeUint32LE(_sceneResIndex);
+
+ out->writeUint16LE(_walkSpeedX);
+ out->writeUint16LE(_walkSpeedY);
+
+ out->writeUint32LE(_counter01);
+ out->writeUint32LE(_counter02);
+ out->writeByte(_movieSceneFlag ? 1 : 0);
+ out->writeByte(_flag01);
+
+ out->writeUint16LE(_mouseX);
+ out->writeUint16LE(_mouseY);
+ out->writeUint16LE(_mouseDisabled);
+
+ _palette->saveState(out);
+ _script->saveState(out);
+ _anim->saveState(out);
+ _screen->saveState(out);
+ _sound->saveState(out);
+ _music->saveState(out);
+
+ out->finalize();
+ delete out;
+}
+
+void ToltecsEngine::loadgame(const char *filename) {
+ Common::InSaveFile *in;
+ if (!(in = g_system->getSavefileManager()->openForLoading(filename))) {
+ warning("Can't open file '%s', game not loaded", filename);
+ return;
+ }
+
+ SaveHeader header;
+
+ kReadSaveHeaderError errorCode = readSaveHeader(in, false, header);
+
+ if (errorCode != kRSHENoError) {
+ warning("Error loading savegame '%s'", filename);
+ delete in;
+ return;
+ }
+
+ _sound->stopAll();
+ _music->stopSequence();
+ g_engine->setTotalPlayTime(header.playTime * 1000);
+
+ _cameraX = in->readUint16LE();
+ _cameraY = in->readUint16LE();
+ _cameraHeight = in->readUint16LE();
+
+ _guiHeight = in->readUint16LE();
+
+ _sceneWidth = in->readUint16LE();
+ _sceneHeight = in->readUint16LE();
+ _sceneResIndex = in->readUint32LE();
+
+ _walkSpeedX = in->readUint16LE();
+ _walkSpeedY = in->readUint16LE();
+
+ _counter01 = in->readUint32LE();
+ _counter02 = in->readUint32LE();
+ _movieSceneFlag = in->readByte() != 0;
+ _flag01 = in->readByte();
+
+ _mouseX = in->readUint16LE();
+ _mouseY = in->readUint16LE();
+ _mouseDisabled = in->readUint16LE();
+
+ _system->warpMouse(_mouseX, _mouseY);
+ _system->showMouse(_mouseDisabled == 0);
+
+ _palette->loadState(in);
+ _script->loadState(in);
+ _anim->loadState(in);
+ _screen->loadState(in);
+ if (header.version >= 2)
+ _sound->loadState(in);
+ if (header.version >= 3)
+ _music->loadState(in);
+
+ delete in;
+
+ loadScene(_sceneResIndex);
+
+ _newCameraX = _cameraX;
+ _newCameraY = _cameraY;
+}
+
+Common::Error ToltecsEngine::loadGameState(int slot) {
+ const char *fileName = getSavegameFilename(slot);
+ loadgame(fileName);
+ return Common::kNoError;
+}
+
+Common::Error ToltecsEngine::saveGameState(int slot, const Common::String &description) {
+ const char *fileName = getSavegameFilename(slot);
+ savegame(fileName, description.c_str());
+ return Common::kNoError;
+}
+
+const char *ToltecsEngine::getSavegameFilename(int num) {
+ static Common::String filename;
+ filename = getSavegameFilename(_targetName, num);
+ return filename.c_str();
+}
+
+Common::String ToltecsEngine::getSavegameFilename(const Common::String &target, int num) {
+ assert(num >= 0 && num <= 999);
+
+ char extension[5];
+ sprintf(extension, "%03d", num);
+
+ return target + "." + extension;
+}
+
+} // End of namespace Toltecs
diff --git a/engines/toltecs/screen.cpp b/engines/toltecs/screen.cpp
new file mode 100644
index 0000000000..b781490b69
--- /dev/null
+++ b/engines/toltecs/screen.cpp
@@ -0,0 +1,808 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ *
+ */
+
+#include "graphics/cursorman.h"
+
+#include "toltecs/toltecs.h"
+#include "toltecs/palette.h"
+#include "toltecs/render.h"
+#include "toltecs/resource.h"
+#include "toltecs/screen.h"
+#include "toltecs/script.h"
+
+namespace Toltecs {
+
+Screen::Screen(ToltecsEngine *vm) : _vm(vm) {
+
+ _frontScreen = new byte[268800];
+ _backScreen = new byte[870400];
+
+ memset(_fontResIndexArray, 0, sizeof(_fontResIndexArray));
+ _fontColor1 = 0;
+ _fontColor2 = 0;
+
+ // Screen shaking
+ _shakeActive = false;
+ _shakeCounterInit = 0;
+ _shakeCounter = 0;
+ _shakePos = 0;
+
+ // Verb line
+ _verbLineNum = 0;
+ memset(_verbLineItems, 0, sizeof(_verbLineItems));
+ _verbLineX = 160;
+ _verbLineY = 2;
+ _verbLineWidth = 20;
+ _verbLineCount = 0;
+
+ // Talk text
+ _talkTextItemNum = 0;
+ memset(_talkTextItems, 0, sizeof(_talkTextItems));
+ _talkTextX = 0;
+ _talkTextY = 0;
+ _talkTextFontColor = 0;
+ _talkTextMaxWidth = 520;
+
+ _renderQueue = new RenderQueue(_vm);
+ _fullRefresh = false;
+ _guiRefresh = false;
+
+}
+
+Screen::~Screen() {
+
+ delete[] _frontScreen;
+ delete[] _backScreen;
+
+ delete _renderQueue;
+
+}
+
+void Screen::unpackRle(byte *source, byte *dest, uint16 width, uint16 height) {
+ int32 size = width * height;
+ while (size > 0) {
+ byte a = *source++;
+ byte b = *source++;
+ if (a == 0) {
+ dest += b;
+ size -= b;
+ } else {
+ b = ((b << 4) & 0xF0) | ((b >> 4) & 0x0F);
+ memset(dest, b, a);
+ dest += a;
+ size -= a;
+ }
+ }
+}
+
+void Screen::loadMouseCursor(uint resIndex) {
+ byte mouseCursor[16 * 16], *mouseCursorP = mouseCursor;
+ byte *cursorData = _vm->_res->load(resIndex)->data;
+ for (int i = 0; i < 32; i++) {
+ byte pixel;
+ byte mask1 = *cursorData++;
+ byte mask2 = *cursorData++;
+ for (int j = 0; j < 8; j++) {
+ pixel = 0xE5;
+ if ((mask2 & 0x80) == 0)
+ pixel = 0xE0;
+ mask2 <<= 1;
+ if ((mask1 & 0x80) == 0)
+ pixel = 0;
+ mask1 <<= 1;
+ *mouseCursorP++ = pixel;
+ }
+ }
+ // FIXME: Where's the cursor hotspot? Using 8, 8 seems good enough for now.
+ CursorMan.replaceCursor((const byte*)mouseCursor, 16, 16, 8, 8, 0);
+}
+
+void Screen::drawGuiImage(int16 x, int16 y, uint resIndex) {
+
+ byte *imageData = _vm->_res->load(resIndex)->data;
+ int16 headerSize = READ_LE_UINT16(imageData);
+ int16 width = imageData[2];
+ int16 height = imageData[3];
+ int16 workWidth = width, workHeight = height;
+ imageData += headerSize;
+
+ byte *dest = _frontScreen + x + (y + _vm->_cameraHeight) * 640;
+
+ //debug(0, "Screen::drawGuiImage() x = %d; y = %d; w = %d; h = %d; resIndex = %d", x, y, width, height, resIndex);
+
+ while (workHeight > 0) {
+ int count = 1;
+ byte pixel = *imageData++;
+ if (pixel & 0x80) {
+ pixel &= 0x7F;
+ count = *imageData++;
+ count += 2;
+ }
+ pixel = pixel + 0xE0;
+ while (count-- && workHeight > 0) {
+ *dest++ = pixel;
+ workWidth--;
+ if (workWidth == 0) {
+ workHeight--;
+ dest += 640 - width;
+ workWidth = width;
+ }
+ }
+ }
+
+ _guiRefresh = true;
+
+}
+
+void Screen::startShakeScreen(int16 shakeCounter) {
+ _shakeActive = true;
+ _shakeCounterInit = shakeCounter;
+ _shakeCounter = shakeCounter;
+ _shakePos = 0;
+}
+
+void Screen::stopShakeScreen() {
+ _shakeActive = false;
+ _vm->_system->setShakePos(0);
+}
+
+void Screen::updateShakeScreen() {
+ if (_shakeActive) {
+ _shakeCounter--;
+ if (_shakeCounter == 0) {
+ _shakeCounter = _shakeCounterInit;
+ _shakePos ^= 8;
+ _vm->_system->setShakePos(_shakePos);
+ }
+ }
+}
+
+void Screen::addStaticSprite(byte *spriteItem) {
+
+ DrawRequest drawRequest;
+ memset(&drawRequest, 0, sizeof(drawRequest));
+
+ drawRequest.y = READ_LE_UINT16(spriteItem + 0);
+ drawRequest.x = READ_LE_UINT16(spriteItem + 2);
+ int16 fragmentId = READ_LE_UINT16(spriteItem + 4);
+ drawRequest.baseColor = _vm->_palette->findFragment(fragmentId) & 0xFF;
+ drawRequest.resIndex = READ_LE_UINT16(spriteItem + 6);
+ drawRequest.flags = READ_LE_UINT16(spriteItem + 8);
+ drawRequest.scaling = 0;
+
+ debug(0, "Screen::addStaticSprite() x = %d; y = %d; baseColor = %d; resIndex = %d; flags = %04X", drawRequest.x, drawRequest.y, drawRequest.baseColor, drawRequest.resIndex, drawRequest.flags);
+
+ addDrawRequest(drawRequest);
+
+}
+
+void Screen::addAnimatedSprite(int16 x, int16 y, int16 fragmentId, byte *data, int16 *spriteArray, bool loop, int mode) {
+
+ //debug(0, "Screen::addAnimatedSprite(%d, %d, %d)", x, y, fragmentId);
+
+ DrawRequest drawRequest;
+ memset(&drawRequest, 0, sizeof(drawRequest));
+
+ drawRequest.x = x;
+ drawRequest.y = y;
+ drawRequest.baseColor = _vm->_palette->findFragment(fragmentId) & 0xFF;
+
+ if (mode == 1) {
+ drawRequest.scaling = _vm->_segmap->getScalingAtPoint(drawRequest.x, drawRequest.y);
+ } else if (mode == 2) {
+ drawRequest.scaling = 0;
+ }
+
+ int16 count = FROM_LE_16(spriteArray[0]);
+
+ //debug(0, "count = %d", count);
+
+ for (int16 index = 1; index <= count; index++) {
+
+ byte *spriteItem = data + FROM_LE_16(spriteArray[index]);
+
+ uint16 loopNum = READ_LE_UINT16(spriteItem + 0) & 0x7FFF;
+ uint16 loopCount = READ_LE_UINT16(spriteItem + 2);
+ uint16 frameNum = READ_LE_UINT16(spriteItem + 4);
+ uint16 frameCount = READ_LE_UINT16(spriteItem + 6);
+ drawRequest.resIndex = READ_LE_UINT16(spriteItem + 8);
+ drawRequest.flags = READ_LE_UINT16(spriteItem + 10 + loopNum * 2);
+
+ debug(0, "Screen::addAnimatedSprite(%d of %d) loopNum = %d; loopCount = %d; frameNum = %d; frameCount = %d; resIndex = %d; flags = %04X, mode = %d",
+ index, count, loopNum, loopCount, frameNum, frameCount, drawRequest.resIndex, drawRequest.flags, mode);
+
+ addDrawRequest(drawRequest);
+
+ frameNum++;
+ if (frameNum == frameCount) {
+ frameNum = 0;
+ loopNum++;
+ if (loopNum == loopCount) {
+ if (loop) {
+ loopNum = 0;
+ } else {
+ loopNum--;
+ }
+ }
+ } else {
+ loopNum |= 0x8000;
+ }
+
+ WRITE_LE_UINT16(spriteItem + 0, loopNum);
+ WRITE_LE_UINT16(spriteItem + 4, frameNum);
+
+ }
+
+}
+
+void Screen::clearSprites() {
+
+}
+
+void Screen::blastSprite(int16 x, int16 y, int16 fragmentId, int16 resIndex, uint16 flags) {
+
+ DrawRequest drawRequest;
+ SpriteDrawItem sprite;
+
+ drawRequest.x = x;
+ drawRequest.y = y;
+ drawRequest.baseColor = _vm->_palette->findFragment(fragmentId) & 0xFF;
+ drawRequest.resIndex = resIndex;
+ drawRequest.flags = flags;
+ drawRequest.scaling = 0;
+
+ if (createSpriteDrawItem(drawRequest, sprite)) {
+ sprite.x -= _vm->_cameraX;
+ sprite.y -= _vm->_cameraY;
+ drawSprite(sprite);
+ }
+
+}
+
+void Screen::updateVerbLine(int16 slotIndex, int16 slotOffset) {
+
+ debug(0, "Screen::updateVerbLine() _verbLineNum = %d; _verbLineX = %d; _verbLineY = %d; _verbLineWidth = %d; _verbLineCount = %d",
+ _verbLineNum, _verbLineX, _verbLineY, _verbLineWidth, _verbLineCount);
+
+ Font font(_vm->_res->load(_fontResIndexArray[0])->data);
+
+ _verbLineItems[_verbLineNum].slotIndex = slotIndex;
+ _verbLineItems[_verbLineNum].slotOffset = slotOffset;
+
+ // First clear the line
+ int16 y = _verbLineY;
+ for (int16 i = 0; i < _verbLineCount; i++) {
+ byte *dest = _frontScreen + _verbLineX - _verbLineWidth / 2 + (y - 1 + _vm->_cameraHeight) * 640;
+ for (int16 j = 0; j < 20; j++) {
+ memset(dest, 0xE0, _verbLineWidth);
+ dest += 640;
+ }
+ y += 18;
+ }
+
+ GuiTextWrapState wrapState;
+ int16 len = 0;
+ wrapState.width = 0;
+ wrapState.destString = wrapState.textBuffer;
+ wrapState.len1 = 0;
+ wrapState.len2 = 0;
+
+ y = _verbLineY;
+
+ memset(wrapState.textBuffer, 0, sizeof(wrapState.textBuffer));
+
+ for (int16 i = 0; i <= _verbLineNum; i++) {
+ wrapState.sourceString = _vm->_script->getSlotData(_verbLineItems[i].slotIndex) + _verbLineItems[i].slotOffset;
+ len = wrapGuiText(_fontResIndexArray[0], _verbLineWidth, wrapState);
+ wrapState.len1 += len;
+ }
+
+ if (_verbLineCount != 1) {
+ int16 charWidth = 0;
+ if (*wrapState.sourceString < 0xF0) {
+ while (*wrapState.sourceString > 0x20 && *wrapState.sourceString < 0xF0 && len > 0) {
+ byte ch = *wrapState.sourceString--;
+ wrapState.len1--;
+ len--;
+ charWidth = font.getCharWidth(ch) + font.getSpacing() - 1;
+ wrapState.width -= charWidth;
+ }
+ wrapState.width += charWidth;
+ wrapState.sourceString++;
+ wrapState.len1 -= len;
+ wrapState.len2 = len + 1;
+
+ drawGuiText(_verbLineX - 1 - (wrapState.width / 2), y, 0xF9, 0xFF, _fontResIndexArray[0], wrapState);
+
+ wrapState.destString = wrapState.textBuffer;
+ wrapState.width = 0;
+ len = wrapGuiText(_fontResIndexArray[0], _verbLineWidth, wrapState);
+ wrapState.len1 += len;
+
+ y += 9;
+ }
+ y += 9;
+ }
+
+ wrapState.len1 -= len;
+ wrapState.len2 = len;
+
+ drawGuiText(_verbLineX - 1 - (wrapState.width / 2), y, 0xF9, 0xFF, _fontResIndexArray[0], wrapState);
+
+ _guiRefresh = true;
+
+}
+
+void Screen::updateTalkText(int16 slotIndex, int16 slotOffset) {
+
+ int16 x, y, maxWidth, width, length;
+ byte durationModifier = 1;
+ byte *textData = _vm->_script->getSlotData(slotIndex) + slotOffset;
+
+ TalkTextItem *item = &_talkTextItems[_talkTextItemNum];
+
+ item->fontNum = 0;
+ item->color = _talkTextFontColor;
+
+ x = CLIP<int16>(_talkTextX - _vm->_cameraX, 120, _talkTextMaxWidth);
+ y = CLIP<int16>(_talkTextY - _vm->_cameraY, 4, _vm->_cameraHeight - 16);
+
+ maxWidth = 624 - ABS(x - 320) * 2;
+
+ while (1) {
+ if (*textData == 0x0A) {
+ x = CLIP<int16>(READ_LE_UINT16(&textData[3]), 120, _talkTextMaxWidth);
+ y = CLIP<int16>(READ_LE_UINT16(&textData[1]), 4, _vm->_cameraHeight - 16);
+ maxWidth = 624 - ABS(x - 320) * 2;
+ textData += 4;
+ } else if (*textData == 0x14) {
+ item->color = ((textData[1] << 4) & 0xF0) | ((textData[1] >> 4) & 0x0F);
+ textData += 2;
+ } else if (*textData == 0x19) {
+ durationModifier = textData[1];
+ textData += 2;
+ } else if (*textData < 0x0A) {
+ item->fontNum = textData[0];
+ // FIXME: Some texts request a font which isn't registered so we change it to a font that is
+ if (_fontResIndexArray[item->fontNum] == 0)
+ item->fontNum = 0;
+ textData += 1;
+ } else
+ break;
+ }
+
+ item->slotIndex = slotIndex;
+ item->slotOffset = textData - _vm->_script->getSlotData(slotIndex);
+
+ width = 0;
+ length = 0;
+
+ item->duration = 0;
+ item->lineCount = 0;
+
+ Font font(_vm->_res->load(_fontResIndexArray[item->fontNum])->data);
+ int16 wordLength, wordWidth;
+
+ while (*textData < 0xF0) {
+ if (*textData == 0x1E) {
+ textData++;
+ addTalkTextRect(font, x, y, length, width, item);
+ width = 0;
+ length = 0;
+ } else {
+ wordLength = 0;
+ wordWidth = 0;
+ while (*textData >= 0x20 && *textData < 0xF0) {
+ byte ch = *textData++;
+ wordLength++;
+ if (ch == 0x20) {
+ wordWidth += font.getWidth();
+ break;
+ } else {
+ wordWidth += font.getCharWidth(ch) + font.getSpacing() - 1;
+ }
+ }
+ if (width + wordWidth > maxWidth + font.getWidth()) {
+ addTalkTextRect(font, x, y, length, width, item);
+ width = wordWidth;
+ length = wordLength;
+ } else {
+ width += wordWidth;
+ length += wordLength;
+ }
+ }
+ }
+
+ addTalkTextRect(font, x, y, length, width, item);
+
+ if (item->lineCount > 0) {
+ int16 ysub = (font.getHeight() - 1) * item->lineCount;
+ if (item->lines[0].y - 4 < ysub)
+ ysub = item->lines[0].y - 4;
+ for (int16 l = 0; l < item->lineCount; l++)
+ item->lines[l].y -= ysub;
+ }
+
+ int16 textDurationMultiplier = item->duration + 8;
+ if (_vm->_doSpeech && *textData == 0xFE) {
+ textDurationMultiplier += 100;
+ }
+ item->duration = 4 * textDurationMultiplier * durationModifier;
+
+}
+
+void Screen::addTalkTextRect(Font &font, int16 x, int16 &y, int16 length, int16 width, TalkTextItem *item) {
+
+ if (width > 0) {
+ TextRect *textRect = &item->lines[item->lineCount];
+ width = width + 1 - font.getSpacing();
+ textRect->width = width;
+ item->duration += length;
+ textRect->length = length;
+ textRect->y = y;
+ textRect->x = CLIP<int16>(x - width / 2, 0, 640);
+ item->lineCount++;
+ }
+
+ y += font.getHeight() - 1;
+
+}
+
+void Screen::addTalkTextItemsToRenderQueue() {
+
+ for (int16 i = 0; i <= _talkTextItemNum; i++) {
+ TalkTextItem *item = &_talkTextItems[i];
+ byte *text = _vm->_script->getSlotData(item->slotIndex) + item->slotOffset;
+
+ if (item->fontNum == -1 || item->duration == 0)
+ continue;
+
+ //item->duration -= _vm->_counter01;
+ item->duration--;
+ if (item->duration < 0)
+ item->duration = 0;
+
+ for (byte j = 0; j < item->lineCount; j++) {
+ _renderQueue->addText(item->lines[j].x, item->lines[j].y, item->color, _fontResIndexArray[item->fontNum],
+ text, item->lines[j].length);
+ text += item->lines[j].length;
+ }
+
+ }
+
+}
+
+int16 Screen::getTalkTextDuration() {
+ return _talkTextItems[_talkTextItemNum].duration;
+}
+
+void Screen::finishTalkTextItems() {
+ for (int16 i = 0; i <= _talkTextItemNum; i++) {
+ _talkTextItems[i].duration = 0;
+ }
+}
+
+void Screen::keepTalkTextItemsAlive() {
+ for (int16 i = 0; i <= _talkTextItemNum; i++) {
+ TalkTextItem *item = &_talkTextItems[i];
+ if (item->fontNum == -1)
+ item->duration = 0;
+ else if (item->duration > 0)
+ item->duration = 2;
+ }
+}
+
+void Screen::registerFont(uint fontIndex, uint resIndex) {
+ _fontResIndexArray[fontIndex] = resIndex;
+}
+
+void Screen::drawGuiTextMulti(byte *textData) {
+
+ int16 x = 0, y = 0;
+
+ // Really strange stuff.
+ for (int i = 30; i >= 0; i--) {
+ if (textData[i] >= 0xF0)
+ break;
+ if (i == 0)
+ return;
+ }
+
+ GuiTextWrapState wrapState;
+ wrapState.sourceString = textData;
+
+ do {
+ if (*wrapState.sourceString == 0x0A) {
+ // Set text position
+ y = wrapState.sourceString[1];
+ x = READ_LE_UINT32(wrapState.sourceString + 2);
+ wrapState.sourceString += 4;
+ } else if (*wrapState.sourceString == 0x0B) {
+ // Inc text position
+ y += wrapState.sourceString[1];
+ x += wrapState.sourceString[2];
+ wrapState.sourceString += 3;
+ } else {
+ wrapState.destString = wrapState.textBuffer;
+ wrapState.width = 0;
+ wrapState.len1 = 0;
+ wrapState.len2 = wrapGuiText(_fontResIndexArray[1], 640, wrapState);
+ drawGuiText(x - wrapState.width / 2, y, _fontColor1, _fontColor2, _fontResIndexArray[1], wrapState);
+ }
+ } while (*wrapState.sourceString != 0xFF);
+
+ _guiRefresh = true;
+
+}
+
+int16 Screen::wrapGuiText(uint fontResIndex, int maxWidth, GuiTextWrapState &wrapState) {
+
+ Font font(_vm->_res->load(fontResIndex)->data);
+ int16 len = 0;
+
+ while (*wrapState.sourceString >= 0x20 && *wrapState.sourceString < 0xF0) {
+ byte ch = *wrapState.sourceString;
+ byte charWidth;
+ if (ch <= 0x20)
+ charWidth = font.getWidth();
+ else
+ charWidth = font.getCharWidth(ch) + font.getSpacing() - 1;
+ if (wrapState.width + charWidth >= maxWidth)
+ break;
+ len++;
+ wrapState.width += charWidth;
+ *wrapState.destString++ = *wrapState.sourceString++;
+ }
+
+ return len;
+
+}
+
+void Screen::drawGuiText(int16 x, int16 y, byte fontColor1, byte fontColor2, uint fontResIndex, GuiTextWrapState &wrapState) {
+
+ debug(0, "Screen::drawGuiText(%d, %d, %d, %d, %d) wrapState.len1 = %d; wrapState.len2 = %d", x, y, fontColor1, fontColor2, fontResIndex, wrapState.len1, wrapState.len2);
+
+ int16 ywobble = 1;
+
+ x = drawString(x + 1, y + _vm->_cameraHeight, fontColor1, fontResIndex, wrapState.textBuffer, wrapState.len1, &ywobble, false);
+ x = drawString(x, y + _vm->_cameraHeight, fontColor2, fontResIndex, wrapState.textBuffer + wrapState.len1, wrapState.len2, &ywobble, false);
+
+}
+
+int16 Screen::drawString(int16 x, int16 y, byte color, uint fontResIndex, const byte *text, int len, int16 *ywobble, bool outline) {
+
+ //debug(0, "Screen::drawString(%d, %d, %d, %d)", x, y, color, fontResIndex);
+
+ Font font(_vm->_res->load(fontResIndex)->data);
+
+ if (len == -1)
+ len = strlen((const char*)text);
+
+ int16 yadd = 0;
+ if (ywobble)
+ yadd = *ywobble;
+
+ while (len--) {
+ byte ch = *text++;
+ if (ch <= 0x20) {
+ x += font.getWidth();
+ } else {
+ drawChar(font, _frontScreen, x, y - yadd, ch, color, outline);
+ x += font.getCharWidth(ch) + font.getSpacing() - 1;
+ yadd = -yadd;
+ }
+ }
+
+ if (ywobble)
+ *ywobble = yadd;
+
+ return x;
+
+}
+
+void Screen::drawChar(const Font &font, byte *dest, int16 x, int16 y, byte ch, byte color, bool outline) {
+
+ int16 charWidth, charHeight;
+ byte *charData;
+
+ dest += x + y * 640;
+
+ charWidth = font.getCharWidth(ch);
+ //charHeight = font.getHeight() - 2;//Why was this here?!
+ charHeight = font.getHeight();
+ charData = font.getCharData(ch);
+
+ while (charHeight--) {
+ byte lineWidth = charWidth;
+ while (lineWidth > 0) {
+ byte count = charData[0] & 0x0F;
+ byte flags = charData[0] & 0xF0;
+ charData++;
+ if ((flags & 0x80) == 0) {
+ if (flags & 0x10) {
+ memset(dest, color, count);
+ } else if (outline) {
+ memset(dest, 0, count);
+ }
+ }
+ dest += count;
+ lineWidth -= count;
+ }
+ dest += 640 - charWidth;
+ }
+
+}
+
+void Screen::drawSurface(int16 x, int16 y, Graphics::Surface *surface) {
+
+ int16 skipX = 0;
+ int16 width = surface->w;
+ int16 height = surface->h;
+ byte *surfacePixels = (byte *)surface->getBasePtr(0, 0);
+ byte *frontScreen;
+
+ // Not on screen, skip
+ if (x + width < 0 || y + height < 0 || x >= 640 || y >= _vm->_cameraHeight)
+ return;
+
+ if (x < 0) {
+ skipX = -x;
+ x = 0;
+ width -= skipX;
+ }
+
+ if (y < 0) {
+ int16 skipY = -y;
+ surfacePixels += surface->w * skipY;
+ y = 0;
+ height -= skipY;
+ }
+
+ if (x + width >= 640) {
+ width -= x + width - 640;
+ }
+
+ if (y + height >= _vm->_cameraHeight) {
+ height -= y + height - _vm->_cameraHeight;
+ }
+
+ frontScreen = _vm->_screen->_frontScreen + x + (y * 640);
+
+ for (int16 h = 0; h < height; h++) {
+ surfacePixels += skipX;
+ for (int16 w = 0; w < width; w++) {
+ if (*surfacePixels != 0xFF)
+ *frontScreen = *surfacePixels;
+ frontScreen++;
+ surfacePixels++;
+ }
+ frontScreen += 640 - width;
+ surfacePixels += surface->w - width - skipX;
+ }
+
+}
+
+void Screen::saveState(Common::WriteStream *out) {
+
+ // Save verb line
+ out->writeUint16LE(_verbLineNum);
+ out->writeUint16LE(_verbLineX);
+ out->writeUint16LE(_verbLineY);
+ out->writeUint16LE(_verbLineWidth);
+ out->writeUint16LE(_verbLineCount);
+ for (int i = 0; i < 8; i++) {
+ out->writeUint16LE(_verbLineItems[i].slotIndex);
+ out->writeUint16LE(_verbLineItems[i].slotOffset);
+ }
+
+ // Save talk text items
+ out->writeUint16LE(_talkTextX);
+ out->writeUint16LE(_talkTextY);
+ out->writeUint16LE(_talkTextMaxWidth);
+ out->writeByte(_talkTextFontColor);
+ out->writeUint16LE(_talkTextItemNum);
+ for (int i = 0; i < 5; i++) {
+ out->writeUint16LE(_talkTextItems[i].duration);
+ out->writeUint16LE(_talkTextItems[i].slotIndex);
+ out->writeUint16LE(_talkTextItems[i].slotOffset);
+ out->writeUint16LE(_talkTextItems[i].fontNum);
+ out->writeByte(_talkTextItems[i].color);
+ out->writeByte(_talkTextItems[i].lineCount);
+ for (int j = 0; j < _talkTextItems[i].lineCount; j++) {
+ out->writeUint16LE(_talkTextItems[i].lines[j].x);
+ out->writeUint16LE(_talkTextItems[i].lines[j].y);
+ out->writeUint16LE(_talkTextItems[i].lines[j].width);
+ out->writeUint16LE(_talkTextItems[i].lines[j].length);
+ }
+ }
+
+ // Save GUI bitmap
+ {
+ byte *gui = _frontScreen + _vm->_cameraHeight * 640;
+ for (int i = 0; i < _vm->_guiHeight; i++) {
+ out->write(gui, 640);
+ gui += 640;
+ }
+ }
+
+ // Save fonts
+ for (int i = 0; i < 10; i++)
+ out->writeUint32LE(_fontResIndexArray[i]);
+ out->writeByte(_fontColor1);
+ out->writeByte(_fontColor2);
+
+}
+
+void Screen::loadState(Common::ReadStream *in) {
+
+ // Load verb line
+ _verbLineNum = in->readUint16LE();
+ _verbLineX = in->readUint16LE();
+ _verbLineY = in->readUint16LE();
+ _verbLineWidth = in->readUint16LE();
+ _verbLineCount = in->readUint16LE();
+ for (int i = 0; i < 8; i++) {
+ _verbLineItems[i].slotIndex = in->readUint16LE();
+ _verbLineItems[i].slotOffset = in->readUint16LE();
+ }
+
+ // Load talk text items
+ _talkTextX = in->readUint16LE();
+ _talkTextY = in->readUint16LE();
+ _talkTextMaxWidth = in->readUint16LE();
+ _talkTextFontColor = in->readByte();
+ _talkTextItemNum = in->readUint16LE();
+ for (int i = 0; i < 5; i++) {
+ _talkTextItems[i].duration = in->readUint16LE();
+ _talkTextItems[i].slotIndex = in->readUint16LE();
+ _talkTextItems[i].slotOffset = in->readUint16LE();
+ _talkTextItems[i].fontNum = in->readUint16LE();
+ _talkTextItems[i].color = in->readByte();
+ _talkTextItems[i].lineCount = in->readByte();
+ for (int j = 0; j < _talkTextItems[i].lineCount; j++) {
+ _talkTextItems[i].lines[j].x = in->readUint16LE();
+ _talkTextItems[i].lines[j].y = in->readUint16LE();
+ _talkTextItems[i].lines[j].width = in->readUint16LE();
+ _talkTextItems[i].lines[j].length = in->readUint16LE();
+ }
+ }
+
+ // Load GUI bitmap
+ {
+ byte *gui = _frontScreen + _vm->_cameraHeight * 640;
+ for (int i = 0; i < _vm->_guiHeight; i++) {
+ in->read(gui, 640);
+ gui += 640;
+ }
+ _guiRefresh = true;
+ }
+
+ // Load fonts
+ for (int i = 0; i < 10; i++)
+ _fontResIndexArray[i] = in->readUint32LE();
+ _fontColor1 = in->readByte();
+ _fontColor2 = in->readByte();
+
+}
+
+} // End of namespace Toltecs
diff --git a/engines/toltecs/screen.h b/engines/toltecs/screen.h
new file mode 100644
index 0000000000..988f59c840
--- /dev/null
+++ b/engines/toltecs/screen.h
@@ -0,0 +1,251 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public 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 TOLTECS_SCREEN_H
+#define TOLTECS_SCREEN_H
+
+#include "graphics/surface.h"
+#include "toltecs/toltecs.h"
+
+namespace Toltecs {
+
+struct DrawRequest {
+ int16 x, y;
+ int16 resIndex;
+ uint16 flags;
+ int16 baseColor;
+ int8 scaling;
+};
+
+struct SpriteDrawItem {
+ int16 x, y;
+ int16 width, height;
+ int16 origWidth, origHeight;
+ int16 resIndex, frameNum;
+ uint32 offset;
+ int16 xdelta, ydelta;
+ uint16 flags;
+ int16 skipX, yerror;
+ int16 priority;
+ int16 baseColor;
+};
+
+struct SpriteFrameEntry {
+ int16 y, x, h, w;
+ uint32 offset;
+ SpriteFrameEntry() {
+ }
+ SpriteFrameEntry(byte *data) {
+ y = READ_LE_UINT16(data + 0);
+ x = READ_LE_UINT16(data + 2);
+ h = READ_LE_UINT16(data + 4);
+ w = READ_LE_UINT16(data + 6);
+ offset = READ_LE_UINT32(data + 8);
+ }
+};
+
+class Font {
+public:
+ Font(byte *fontData) : _fontData(fontData) {
+ }
+ ~Font() {
+ }
+ int16 getSpacing() const {
+ return _fontData[1];
+ }
+ int16 getHeight() const {
+ return _fontData[2];
+ }
+ int16 getWidth() const {
+ return _fontData[3];
+ }
+ int16 getCharWidth(byte ch) const {
+ return _fontData[4 + (ch - 0x21)];
+ }
+ byte *getCharData(byte ch) const {
+ return _fontData + 0x298 + READ_LE_UINT16(&_fontData[0xE0 + (ch - 0x21) * 2]);
+ }
+ int16 getTextWidth(const byte *text) {
+ int16 width = 0;
+ while (*text && *text < 0xF0) {
+ byte ch = *text++;
+ if (ch <= 0x20) {
+ width += getWidth();
+ } else {
+ width += getCharWidth(ch) + getSpacing() - 1;
+ }
+ }
+ return width;
+ }
+
+protected:
+ byte *_fontData;
+};
+
+struct PixelPacket {
+ byte count;
+ byte pixel;
+};
+
+enum SpriteReaderStatus {
+ kSrsPixelsLeft,
+ kSrsEndOfLine,
+ kSrsEndOfSprite
+};
+
+class SpriteFilter {
+public:
+ SpriteFilter(const SpriteDrawItem &sprite) : _sprite(&sprite) {
+ }
+ virtual ~SpriteFilter() {}
+ virtual SpriteReaderStatus readPacket(PixelPacket &packet) = 0;
+protected:
+ const SpriteDrawItem *_sprite;
+};
+
+struct TextRect {
+ int16 x, y;
+ int16 width, length;
+};
+
+struct TalkTextItem {
+ int16 duration;
+ int16 slotIndex;
+ int16 slotOffset;
+ int16 fontNum;
+ byte color;
+ byte lineCount;
+ TextRect lines[15];
+};
+
+struct GuiTextWrapState {
+ int16 len1, len2;
+ byte *sourceString;
+ byte *destString;
+ int16 width;
+ byte textBuffer[100];
+};
+
+class RenderQueue;
+
+class Screen {
+public:
+ Screen(ToltecsEngine *vm);
+ ~Screen();
+
+ void unpackRle(byte *source, byte *dest, uint16 width, uint16 height);
+
+ void loadMouseCursor(uint resIndex);
+
+ void drawGuiImage(int16 x, int16 y, uint resIndex);
+
+ void startShakeScreen(int16 shakeCounter);
+ void stopShakeScreen();
+ void updateShakeScreen();
+
+ // Sprite list
+ void addStaticSprite(byte *spriteItem);
+ void addAnimatedSprite(int16 x, int16 y, int16 fragmentId, byte *data, int16 *spriteArray, bool loop, int mode);
+ void clearSprites();
+
+ // Sprite drawing
+ void drawSprite(const SpriteDrawItem &sprite);
+ void drawSpriteCore(byte *dest, SpriteFilter &reader, const SpriteDrawItem &sprite);
+ void blastSprite(int16 x, int16 y, int16 fragmentId, int16 resIndex, uint16 flags);
+
+ // Verb line
+ void updateVerbLine(int16 slotIndex, int16 slotOffset);
+
+ // Talk text
+ void updateTalkText(int16 slotIndex, int16 slotOffset);
+ void addTalkTextRect(Font &font, int16 x, int16 &y, int16 length, int16 width, TalkTextItem *item);
+ void addTalkTextItemsToRenderQueue();
+ int16 getTalkTextDuration();
+ void finishTalkTextItems();
+ void keepTalkTextItemsAlive();
+
+ // Font/text
+ void registerFont(uint fontIndex, uint resIndex);
+ void drawGuiTextMulti(byte *textData);
+ int16 wrapGuiText(uint fontResIndex, int maxWidth, GuiTextWrapState &wrapState);
+ void drawGuiText(int16 x, int16 y, byte fontColor1, byte fontColor2, uint fontResIndex, GuiTextWrapState &wrapState);
+
+ int16 drawString(int16 x, int16 y, byte color, uint fontResIndex, const byte *text, int len = -1, int16 *ywobble = NULL, bool outline = false);
+ void drawChar(const Font &font, byte *dest, int16 x, int16 y, byte ch, byte color, bool outline);
+
+ void drawSurface(int16 x, int16 y, Graphics::Surface *surface);
+
+ void saveState(Common::WriteStream *out);
+ void loadState(Common::ReadStream *in);
+
+ uint getFontResIndex(int fontNum) const { return _fontResIndexArray[fontNum]; }
+
+//protected:
+public:
+
+ struct VerbLineItem {
+ int16 slotIndex;
+ int16 slotOffset;
+ };
+
+ struct Rect {
+ int16 x, y, width, height;
+ };
+
+ ToltecsEngine *_vm;
+
+ byte *_frontScreen, *_backScreen;
+
+ uint _fontResIndexArray[10];
+ byte _fontColor1, _fontColor2;
+
+ // Screen shaking
+ bool _shakeActive;
+ int16 _shakeCounterInit, _shakeCounter;
+ int _shakePos;
+
+ // Verb line
+ int16 _verbLineNum;
+ VerbLineItem _verbLineItems[8];
+ int16 _verbLineX, _verbLineY, _verbLineWidth;
+ int16 _verbLineCount;
+
+ // Talk text
+ int16 _talkTextX, _talkTextY;
+ int16 _talkTextMaxWidth;
+ byte _talkTextFontColor;
+ int16 _talkTextItemNum;
+ TalkTextItem _talkTextItems[5];
+
+ RenderQueue *_renderQueue;
+ bool _fullRefresh;
+ bool _guiRefresh;
+
+ bool createSpriteDrawItem(const DrawRequest &drawRequest, SpriteDrawItem &sprite);
+ void addDrawRequest(const DrawRequest &drawRequest);
+
+};
+
+} // End of namespace Toltecs
+
+#endif /* TOLTECS_SCREEN_H */
diff --git a/engines/toltecs/script.cpp b/engines/toltecs/script.cpp
new file mode 100644
index 0000000000..9683831980
--- /dev/null
+++ b/engines/toltecs/script.cpp
@@ -0,0 +1,1108 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ *
+ */
+
+// TODO: Clean up game variable handling and move it to ToltecsEngine
+
+#include "common/error.h"
+
+#include "graphics/cursorman.h"
+
+#include "toltecs/toltecs.h"
+#include "toltecs/animation.h"
+#include "toltecs/menu.h"
+#include "toltecs/movie.h"
+#include "toltecs/music.h"
+#include "toltecs/palette.h"
+#include "toltecs/resource.h"
+#include "toltecs/script.h"
+#include "toltecs/segmap.h"
+#include "toltecs/sound.h"
+
+namespace Toltecs {
+
+ScriptInterpreter::ScriptInterpreter(ToltecsEngine *vm) : _vm(vm) {
+
+ _stack = new byte[kScriptStackSize];
+
+ memset(_slots, 0, sizeof(_slots));
+
+ _savedSp = 0;
+
+ _slots[kMaxScriptSlots - 1].size = 1024;
+ _slots[kMaxScriptSlots - 1].data = new byte[_slots[kMaxScriptSlots - 1].size];
+
+ setupScriptFunctions();
+
+}
+
+ScriptInterpreter::~ScriptInterpreter() {
+ delete[] _stack;
+ for (int i = 0; i < kMaxScriptSlots; i++)
+ delete[] _slots[i].data;
+ for (uint i = 0; i < _scriptFuncs.size(); ++i)
+ delete _scriptFuncs[i];
+}
+
+typedef Common::Functor0Mem<void, ScriptInterpreter> ScriptFunctionF;
+#define RegisterScriptFunction(x) \
+ _scriptFuncs.push_back(new ScriptFunctionF(this, &ScriptInterpreter::x)); \
+ _scriptFuncNames.push_back(#x);
+void ScriptInterpreter::setupScriptFunctions() {
+
+ // 0
+ RegisterScriptFunction(sfNop);
+ RegisterScriptFunction(sfNop);
+ RegisterScriptFunction(sfGetGameVar);
+ RegisterScriptFunction(sfSetGameVar);
+ RegisterScriptFunction(sfUpdateScreen);
+ // 5
+ RegisterScriptFunction(sfGetRandomNumber);
+ RegisterScriptFunction(sfDrawGuiTextMulti);
+ RegisterScriptFunction(sfUpdateVerbLine);
+ RegisterScriptFunction(sfSetFontColor);
+ RegisterScriptFunction(sfGetTalkTextDuration);
+ // 10
+ RegisterScriptFunction(sfTalk);
+ RegisterScriptFunction(sfFindPaletteFragment);
+ RegisterScriptFunction(sfClearPaletteFragments);
+ RegisterScriptFunction(sfAddPaletteFragment);
+ RegisterScriptFunction(sfSetDeltaAnimPalette);
+ // 15
+ RegisterScriptFunction(sfSetUnkPaletteEffect);
+ RegisterScriptFunction(sfBuildColorTransTable);
+ RegisterScriptFunction(sfSetDeltaMainPalette);
+ RegisterScriptFunction(sfLoadScript);
+ RegisterScriptFunction(sfRegisterFont);
+ // 20
+ RegisterScriptFunction(sfLoadAddPalette);
+ RegisterScriptFunction(sfLoadScene);
+ RegisterScriptFunction(sfSetGuiHeight);
+ RegisterScriptFunction(sfFindMouseInRectIndex1);
+ RegisterScriptFunction(sfFindMouseInRectIndex2);
+ // 25
+ RegisterScriptFunction(sfDrawGuiImage);
+ RegisterScriptFunction(sfAddAnimatedSpriteNoLoop);
+ RegisterScriptFunction(sfAddAnimatedSprite);
+ RegisterScriptFunction(sfAddStaticSprite);
+ RegisterScriptFunction(sfAddAnimatedSpriteScaled);
+ // 30
+ RegisterScriptFunction(sfFindPath);
+ RegisterScriptFunction(sfWalk);
+ RegisterScriptFunction(sfScrollCameraUp);
+ RegisterScriptFunction(sfScrollCameraDown);
+ RegisterScriptFunction(sfScrollCameraLeft);
+ // 35
+ RegisterScriptFunction(sfScrollCameraRight);
+ RegisterScriptFunction(sfScrollCameraUpEx);
+ RegisterScriptFunction(sfScrollCameraDownEx);
+ RegisterScriptFunction(sfScrollCameraLeftEx);
+ RegisterScriptFunction(sfScrollCameraRightEx);
+ // 40
+ RegisterScriptFunction(sfSetCamera);
+ RegisterScriptFunction(sfGetCameraChanged);
+ RegisterScriptFunction(sfGetRgbModifiertAtPoint);
+ RegisterScriptFunction(sfStartAnim);
+ RegisterScriptFunction(sfAnimNextFrame);
+ // 45
+ RegisterScriptFunction(sfNop);
+ RegisterScriptFunction(sfGetAnimFrameNumber);
+ RegisterScriptFunction(sfGetAnimStatus);
+ RegisterScriptFunction(sfStartShakeScreen);
+ RegisterScriptFunction(sfStopShakeScreen);
+ // 50
+ RegisterScriptFunction(sfStartSequence);
+ RegisterScriptFunction(sfEndSequence);
+ RegisterScriptFunction(sfSetSequenceVolume);
+ RegisterScriptFunction(sfPlayPositionalSound);
+ RegisterScriptFunction(sfPlaySound2);
+ // 55
+ RegisterScriptFunction(sfClearScreen);
+ RegisterScriptFunction(sfNop);
+ RegisterScriptFunction(sfHandleInput);
+ RegisterScriptFunction(sfRunOptionsScreen);
+ RegisterScriptFunction(sfPrecacheSprites);
+ // 60
+ RegisterScriptFunction(sfPrecacheSounds1);
+ RegisterScriptFunction(sfDeletePrecachedFiles);
+ RegisterScriptFunction(sfPrecacheSounds2);
+ RegisterScriptFunction(sfRestoreStackPtr);
+ RegisterScriptFunction(sfSaveStackPtr);
+ // 65
+ RegisterScriptFunction(sfPlayMovie);
+ RegisterScriptFunction(sfNop);
+
+}
+
+void ScriptInterpreter::loadScript(uint resIndex, uint slotIndex) {
+
+ delete[] _slots[slotIndex].data;
+
+ _slots[slotIndex].resIndex = resIndex;
+ Resource *scriptResource = _vm->_res->load(resIndex);
+ _slots[slotIndex].size = scriptResource->size;
+ _slots[slotIndex].data = new byte[_slots[slotIndex].size];
+ memcpy(_slots[slotIndex].data, scriptResource->data, _slots[slotIndex].size);
+
+}
+
+void ScriptInterpreter::setMainScript(uint slotIndex) {
+ _switchLocalDataNear = true;
+ _switchLocalDataFar = false;
+ _switchLocalDataToStack = false;
+ _cmpBitTest = false;
+ _regs.reg0 = 0;
+ _regs.reg1 = 0;
+ _regs.reg2 = 0;
+ _regs.reg3 = 0;
+ _regs.reg4 = slotIndex;
+ _regs.reg5 = 0;
+ _regs.reg6 = 0;
+ _regs.sp = 4096;
+ _regs.reg8 = 0;
+ _code = getSlotData(_regs.reg4);
+}
+
+void ScriptInterpreter::runScript() {
+ uint32 lastScreenUpdate = 0;
+
+ while (!_vm->shouldQuit()) {
+
+ if (_vm->_movieSceneFlag)
+ _vm->_mouseButton = 0;
+
+ if (_vm->_saveLoadRequested != 0) {
+ if (_vm->_saveLoadRequested == 1)
+ _vm->loadGameState(_vm->_saveLoadSlot);
+ else if (_vm->_saveLoadRequested == 2)
+ _vm->saveGameState(_vm->_saveLoadSlot, _vm->_saveLoadDescription);
+ _vm->_saveLoadRequested = 0;
+ }
+
+ if (_switchLocalDataNear) {
+ _switchLocalDataNear = false;
+ _localData = getSlotData(_regs.reg4);
+ }
+
+ if (_switchLocalDataFar) {
+ _switchLocalDataFar = false;
+ _localData = getSlotData(_regs.reg5);
+ _switchLocalDataNear = true;
+ }
+
+ if (_switchLocalDataToStack) {
+ _switchLocalDataToStack = false;
+ _localData = _stack + 2;
+ _switchLocalDataNear = true;
+ }
+
+ byte opcode = readByte();
+ execOpcode(opcode);
+
+ // Update the screen at semi-regular intervals, else the mouse
+ // cursor will be jerky.
+ uint32 now = _vm->_system->getMillis();
+ if (now < lastScreenUpdate || now - lastScreenUpdate > 10) {
+ _vm->_system->updateScreen();
+ lastScreenUpdate = _vm->_system->getMillis();
+ }
+
+ }
+
+}
+
+byte ScriptInterpreter::readByte() {
+ return *_code++;
+}
+
+int16 ScriptInterpreter::readInt16() {
+ int16 value = READ_LE_UINT16(_code);
+ _code += 2;
+ return value;
+}
+
+void ScriptInterpreter::execOpcode(byte opcode) {
+
+ int16 ofs;
+
+ debug(1, "opcode = %d", opcode);
+
+ switch (opcode) {
+ case 0:
+ {
+ // ok
+ _subCode = _code;
+ byte length = readByte();
+ debug(1, "length = %d", length);
+ uint16 index = readInt16();
+ debug(1, "callScriptFunction %d", index);
+ execScriptFunction(index);
+ _code += length - 2;
+ break;
+ }
+ case 1:
+ // ok
+ _regs.reg0 = readInt16();
+ break;
+ case 2:
+ // ok
+ _regs.reg1 = readInt16();
+ break;
+ case 3:
+ // ok
+ _regs.reg3 = readInt16();
+ break;
+ case 4:
+ // ok
+ _regs.reg5 = _regs.reg0;
+ break;
+ case 5:
+ // ok
+ _regs.reg3 = _regs.reg0;
+ break;
+ case 6:
+ // ok
+ _regs.reg1 = _regs.reg0;
+ break;
+ case 7:
+ _regs.reg1 = localRead16(_regs.reg3);
+ break;
+ case 8:
+ localWrite16(_regs.reg3, _regs.reg0);
+ break;
+ case 9:
+ localWrite16(readInt16(), _regs.reg0);
+ break;
+ case 10:
+ localWrite8(readInt16(), _regs.reg0);
+ break;
+ case 11:
+ localWrite16(readInt16(), _regs.reg5);
+ break;
+ case 12:
+ localWrite16(readInt16(), _regs.reg4);
+ break;
+ case 13:
+ localWrite16(readInt16(), _regs.reg3);
+ break;
+ case 14:
+ _regs.reg3 = localRead16(readInt16());
+ break;
+ case 15:
+ _regs.reg2 = localRead16(_regs.reg1);
+ break;
+ case 16:
+ _regs.reg2 = localRead16(_regs.reg1 + readInt16());
+ break;
+ case 17:
+ _regs.reg2 = _regs.reg0;
+ break;
+ case 18:
+ _regs.reg0 += readInt16();
+ break;
+ case 19:
+ localWrite16(_regs.reg3, localRead16(_regs.reg3) + _regs.reg0);
+ break;
+ case 20:
+ _regs.reg0 += _regs.reg2;
+ break;
+ case 21:
+ _regs.reg3 += _regs.sp;
+ break;
+ case 22:
+ _regs.reg1 += _regs.sp;
+ break;
+ case 23:
+ localWrite16(_regs.reg3, localRead16(_regs.reg3) - _regs.reg0);
+ break;
+ case 24:
+ _regs.reg0 /= readInt16();
+ break;
+ case 25:
+ localWrite16(_regs.reg3, localRead16(_regs.reg3) / _regs.reg0);
+ break;
+ case 26:
+ // NOP
+ break;
+ case 27:
+ _regs.reg0 *= readInt16();
+ break;
+ case 28:
+ localWrite16(_regs.reg3, localRead16(_regs.reg3) * _regs.reg0);
+ break;
+ case 29:
+ _regs.reg0 *= _regs.reg2;
+ break;
+ case 30:
+ localWrite16(_regs.reg3, localRead16(_regs.reg3) + 1);
+ break;
+ case 31:
+ localWrite16(_regs.reg3, localRead16(_regs.reg3) - 1);
+ break;
+ case 32:
+ _switchLocalDataFar = true;
+ break;
+ case 33:
+ _switchLocalDataToStack = true;
+ break;
+ case 34:
+ pushInt16(_regs.reg0);
+ break;
+ case 35:
+ pushInt16(_regs.reg1);
+ break;
+ case 36:
+ _regs.reg1 = popInt16();
+ break;
+ case 37:
+ _regs.reg0 = popInt16();
+ break;
+ case 38:
+ _regs.reg2 = -_regs.reg2;
+ break;
+ case 39:
+ _regs.reg8 = readInt16();
+ _cmpBitTest = false;
+ break;
+ case 40:
+ _regs.reg8 = _regs.reg0;
+ _cmpBitTest = false;
+ break;
+ case 41:
+ _regs.reg8 = readInt16();
+ _cmpBitTest = true;
+ break;
+ case 42:
+ _regs.reg8 = _regs.reg0;
+ _cmpBitTest = true;
+ break;
+ case 43:
+ _code = getSlotData(_regs.reg4) + _regs.reg0;
+ break;
+ case 44:
+ _code = getSlotData(_regs.reg5) + _regs.reg0;
+ _regs.reg4 = _regs.reg5;
+ _switchLocalDataNear = true;
+ break;
+ case 45:
+ pushInt16(_code - getSlotData(_regs.reg4));
+ pushInt16(_regs.reg4);
+ _code = getSlotData(_regs.reg4) + _regs.reg0;
+ break;
+ case 46:
+ pushInt16(_code - getSlotData(_regs.reg4));
+ pushInt16(_regs.reg4);
+ _code = getSlotData(_regs.reg5) + _regs.reg0;
+ _regs.reg4 = _regs.reg5;
+ _switchLocalDataNear = true;
+ break;
+ case 47:
+ _regs.reg4 = popInt16();
+ ofs = popInt16();
+ _code = getSlotData(_regs.reg4) + ofs;
+ _switchLocalDataNear = true;
+ break;
+ case 48:
+ _regs.reg4 = popInt16();
+ ofs = popInt16();
+ _code = getSlotData(_regs.reg4) + ofs;
+ _regs.sp += _regs.reg0;
+ _switchLocalDataNear = true;
+ break;
+ case 49:
+ ofs = readByte();
+ _code += ofs;
+ break;
+ case 50:
+ if (_cmpBitTest) {
+ _regs.reg1 &= _regs.reg8;
+ if (_regs.reg1 == 0)
+ _code += 4;
+ } else {
+ if (_regs.reg1 == _regs.reg8)
+ _code += 4;
+ }
+ _code++;
+ break;
+ case 51:
+ if (_cmpBitTest) {
+ _regs.reg1 &= _regs.reg8;
+ if (_regs.reg1 != 0)
+ _code += 4;
+ } else {
+ if (_regs.reg1 != _regs.reg8)
+ _code += 4;
+ }
+ _code++;
+ break;
+ case 52:
+ if ((uint16)_regs.reg1 >= (uint16)_regs.reg8)
+ _code += 4;
+ _code++;
+ break;
+ case 53:
+ if ((uint16)_regs.reg1 <= (uint16)_regs.reg8)
+ _code += 4;
+ _code++;
+ break;
+ case 54:
+ if ((uint16)_regs.reg1 < (uint16)_regs.reg8)
+ _code += 4;
+ _code++;
+ break;
+ case 55:
+ if ((uint16)_regs.reg1 > (uint16)_regs.reg8)
+ _code += 4;
+ _code++;
+ break;
+ default:
+ error("Invalid opcode %d", opcode);
+ }
+
+}
+
+void ScriptInterpreter::execScriptFunction(uint16 index) {
+ debug(4, "execScriptFunction(%d)", index);
+ if (index >= _scriptFuncs.size())
+ error("ScriptInterpreter::execScriptFunction() Invalid script function index %d", index);
+ debug(4, "%s", _scriptFuncNames[index]);
+ (*_scriptFuncs[index])();
+}
+
+VarType ScriptInterpreter::getGameVarType(uint variable) {
+ switch (variable) {
+ case 0: return vtByte;
+ case 1: return vtWord;
+ case 2: return vtWord;
+ case 3: return vtByte;
+ case 4: return vtWord;
+ case 5: return vtWord;
+ case 6: return vtWord;
+ case 7: return vtWord;
+ case 8: return vtWord;
+ case 9: return vtWord;
+ case 10: return vtWord;
+ case 11: return vtWord;
+ case 12: return vtByte;
+ case 13: return vtWord;
+ case 14: return vtWord;
+ case 15: return vtWord;
+ case 16: return vtWord;
+ case 17: return vtWord;
+ case 18: return vtWord;
+ case 19: return vtWord;
+ case 20: return vtWord;
+ case 21: return vtWord;
+ default:
+ error("Invalid game variable");
+ }
+}
+
+const char *getVarName(uint variable) {
+ switch (variable) {
+ case 0: return "mouseDisabled";
+ case 1: return "mouseY";
+ case 2: return "mouseX";
+ case 3: return "mouseButton";
+ case 4: return "verbLineY";
+ case 5: return "verbLineX";
+ case 6: return "verbLineWidth";
+ case 7: return "verbLineCount";
+ case 8: return "verbLineNum";
+ case 9: return "talkTextItemNum";
+ case 10: return "talkTextY";
+ case 11: return "talkTextX";
+ case 12: return "talkTextFontColor";
+ case 13: return "cameraY";
+ case 14: return "cameraX";
+ case 15: return "walkSpeedY";
+ case 16: return "walkSpeedX";
+ case 17: return "flag01";
+ case 18: return "sceneResIndex";
+ case 19: return "guiHeight";
+ case 20: return "sceneHeight";
+ case 21: return "sceneWidth";
+ }
+ return "(invalid)";
+}
+
+int16 ScriptInterpreter::getGameVar(uint variable) {
+ debug(0, "ScriptInterpreter::getGameVar(%d{%s})", variable, getVarName(variable));
+
+ switch (variable) {
+ case 0: return _vm->_mouseDisabled;
+ case 1: return _vm->_mouseY;
+ case 2: return _vm->_mouseX;
+ case 3: return _vm->_mouseButton;
+ case 4: return _vm->_screen->_verbLineY;
+ case 5: return _vm->_screen->_verbLineX;
+ case 6: return _vm->_screen->_verbLineWidth;
+ case 7: return _vm->_screen->_verbLineCount;
+ case 8: return _vm->_screen->_verbLineNum;
+ case 9: return _vm->_screen->_talkTextItemNum;
+ case 10: return _vm->_screen->_talkTextY;
+ case 11: return _vm->_screen->_talkTextX;
+ case 12: return _vm->_screen->_talkTextFontColor;
+ case 13: return _vm->_cameraY;
+ case 14: return _vm->_cameraX;
+ case 15: return _vm->_walkSpeedY;
+ case 16: return _vm->_walkSpeedX;
+ case 17: return _vm->_flag01;
+ case 18: return _vm->_sceneResIndex;
+ case 19: return _vm->_guiHeight;
+ case 20: return _vm->_sceneHeight;
+ case 21: return _vm->_sceneWidth;
+ default:
+ warning("Getting unimplemented game variable %s (%d)", getVarName(variable), variable);
+ return 0;
+ }
+}
+
+void ScriptInterpreter::setGameVar(uint variable, int16 value) {
+ debug(0, "ScriptInterpreter::setGameVar(%d{%s}, %d)", variable, getVarName(variable), value);
+
+ switch (variable) {
+ case 0:
+ _vm->_mouseDisabled = value;
+ CursorMan.showMouse(value == 0);
+ break;
+ case 3:
+ _vm->_mouseButton = value;
+ break;
+ case 4:
+ _vm->_screen->_verbLineY = value;
+ break;
+ case 5:
+ _vm->_screen->_verbLineX = value;
+ break;
+ case 6:
+ _vm->_screen->_verbLineWidth = value;
+ break;
+ case 7:
+ _vm->_screen->_verbLineCount = value;
+ break;
+ case 8:
+ _vm->_screen->_verbLineNum = value;
+ break;
+ case 9:
+ _vm->_screen->_talkTextItemNum = value;
+ break;
+ case 10:
+ _vm->_screen->_talkTextY = value;
+ break;
+ case 11:
+ _vm->_screen->_talkTextX = value;
+ break;
+ case 12:
+ _vm->_screen->_talkTextFontColor = value;
+ break;
+ case 13:
+ _vm->_cameraY = value;
+ break;
+ case 14:
+ _vm->_cameraX = value;
+ break;
+ case 15:
+ _vm->_walkSpeedY = value;
+ break;
+ case 16:
+ _vm->_walkSpeedX = value;
+ break;
+ case 17:
+ _vm->_flag01 = value != 0;
+ break;
+ case 18:
+ _vm->_sceneResIndex = value;
+ break;
+ case 19:
+ _vm->_guiHeight = value;
+ break;
+ case 20:
+ _vm->_sceneHeight = value;
+ break;
+ case 21:
+ _vm->_sceneWidth = value;
+ break;
+ case 1:
+ case 2:
+ default:
+ warning("Setting unimplemented game variable %s (%d) to %d", getVarName(variable), variable, value);
+ break;
+ }
+
+}
+
+byte ScriptInterpreter::arg8(int16 offset) {
+ return _subCode[offset];
+}
+
+int16 ScriptInterpreter::arg16(int16 offset) {
+ return READ_LE_UINT16(&_subCode[offset]);
+}
+
+void ScriptInterpreter::pushInt16(int16 value) {
+ WRITE_LE_UINT16(_stack + _regs.sp, value);
+ _regs.sp -= 2;
+}
+
+int16 ScriptInterpreter::popInt16() {
+ _regs.sp += 2;
+ return READ_LE_UINT16(_stack + _regs.sp);
+}
+
+void ScriptInterpreter::localWrite8(int16 offset, byte value) {
+ //debug(1, "localWrite8(%d, %d)", offset, value);
+ _localData[offset] = value;
+}
+
+byte ScriptInterpreter::localRead8(int16 offset) {
+ //debug(1, "localRead8(%d) -> %d", offset, _localData[offset]);
+ return _localData[offset];
+}
+
+void ScriptInterpreter::localWrite16(int16 offset, int16 value) {
+ //debug(1, "localWrite16(%d, %d)", offset, value);
+ WRITE_LE_UINT16(&_localData[offset], value);
+}
+
+int16 ScriptInterpreter::localRead16(int16 offset) {
+ //debug(1, "localRead16(%d) -> %d", offset, (int16)READ_LE_UINT16(&_localData[offset]));
+ return (int16)READ_LE_UINT16(&_localData[offset]);
+}
+
+byte *ScriptInterpreter::localPtr(int16 offset) {
+ //debug(1, "localPtr(%d)", offset);
+ return &_localData[offset];
+}
+
+void ScriptInterpreter::saveState(Common::WriteStream *out) {
+
+ // Save registers
+ out->writeUint16LE(_regs.reg0);
+ out->writeUint16LE(_regs.reg1);
+ out->writeUint16LE(_regs.reg2);
+ out->writeUint16LE(_regs.reg3);
+ out->writeUint16LE(_regs.reg4);
+ out->writeUint16LE(_regs.reg5);
+ out->writeUint16LE(_regs.reg6);
+ out->writeUint16LE(_regs.sp);
+ out->writeUint16LE(_regs.reg8);
+
+ // Save slots
+ for (int slot = 0; slot < kMaxScriptSlots; slot++) {
+ out->writeUint32LE(_slots[slot].size);
+ out->writeUint16LE(_slots[slot].resIndex);
+ if (_slots[slot].size > 0)
+ out->write(_slots[slot].data, _slots[slot].size);
+ }
+
+ // Save stack
+ out->write(_stack, kScriptStackSize);
+ out->writeUint16LE(_savedSp);
+
+ // Save IP
+ out->writeUint16LE((int16)(_code - getSlotData(_regs.reg4)));
+
+}
+
+void ScriptInterpreter::loadState(Common::ReadStream *in) {
+
+ // Load registers
+ _regs.reg0 = in->readUint16LE();
+ _regs.reg1 = in->readUint16LE();
+ _regs.reg2 = in->readUint16LE();
+ _regs.reg3 = in->readUint16LE();
+ _regs.reg4 = in->readUint16LE();
+ _regs.reg5 = in->readUint16LE();
+ _regs.reg6 = in->readUint16LE();
+ _regs.sp = in->readUint16LE();
+ _regs.reg8 = in->readUint16LE();
+
+ // Load slots
+ for (int slot = 0; slot < kMaxScriptSlots; slot++) {
+ _slots[slot].size = in->readUint32LE();
+ _slots[slot].resIndex = in->readUint16LE();
+ _slots[slot].data = NULL;
+ if (_slots[slot].size > 0) {
+ _slots[slot].data = new byte[_slots[slot].size];
+ in->read(_slots[slot].data, _slots[slot].size);
+ }
+ }
+
+ // Load stack
+ in->read(_stack, kScriptStackSize);
+ _savedSp = in->readUint16LE();
+
+ // Load IP
+ _code = getSlotData(_regs.reg4) + in->readUint16LE();
+
+}
+
+void ScriptInterpreter::sfNop() {
+ // NOP
+}
+
+void ScriptInterpreter::sfGetGameVar() {
+ int16 value = getGameVar(arg16(3));
+ localWrite16(arg16(5), value);
+}
+
+void ScriptInterpreter::sfSetGameVar() {
+ int16 varIndex = arg16(3);
+ VarType varType = getGameVarType(varIndex);
+ int16 value = 0;
+ if (varType == vtByte)
+ value = arg8(5);
+ else if (varType == vtWord)
+ value = arg16(5);
+ setGameVar(varIndex, value);
+}
+
+void ScriptInterpreter::sfUpdateScreen() {
+ _vm->updateScreen();
+}
+
+void ScriptInterpreter::sfGetRandomNumber() {
+ localWrite16(arg16(5), _vm->_rnd->getRandomNumber(arg16(3) - 1));
+}
+
+void ScriptInterpreter::sfDrawGuiTextMulti() {
+ _vm->_screen->drawGuiTextMulti((byte *)localPtr(arg16(3)));
+}
+
+void ScriptInterpreter::sfUpdateVerbLine() {
+ _vm->_screen->updateVerbLine(arg16(5), arg16(3));
+}
+
+void ScriptInterpreter::sfSetFontColor() {
+ _vm->_screen->_fontColor1 = 0;
+ _vm->_screen->_fontColor2 = arg8(3);
+}
+
+void ScriptInterpreter::sfGetTalkTextDuration() {
+ localWrite16(arg16(3), _vm->_screen->getTalkTextDuration());
+}
+
+void ScriptInterpreter::sfTalk() {
+ _vm->talk(arg16(5), arg16(3));
+}
+
+void ScriptInterpreter::sfFindPaletteFragment() {
+ localWrite16(arg16(5), _vm->_palette->findFragment(arg16(3)));
+}
+
+void ScriptInterpreter::sfClearPaletteFragments() {
+ _vm->_palette->clearFragments();
+}
+
+void ScriptInterpreter::sfAddPaletteFragment() {
+ _vm->_palette->addFragment(arg16(3), arg16(5));
+}
+
+void ScriptInterpreter::sfSetDeltaAnimPalette() {
+ _vm->_palette->setDeltaPalette(_vm->_palette->getAnimPalette(), arg8(6), (char)arg8(5), arg8(4), arg8(3));
+}
+
+void ScriptInterpreter::sfSetUnkPaletteEffect() {
+ // TODO
+ debug("ScriptInterpreter::sfSetUnkPaletteEffect");
+}
+
+void ScriptInterpreter::sfBuildColorTransTable() {
+ _vm->_palette->buildColorTransTable(arg8(4), (char)arg8(3), arg8(5));
+}
+
+void ScriptInterpreter::sfSetDeltaMainPalette() {
+ _vm->_palette->setDeltaPalette(_vm->_palette->getMainPalette(), arg8(6), (char)arg8(5), arg8(4), arg8(3));
+}
+
+void ScriptInterpreter::sfLoadScript() {
+ int16 codeOfs = _code - getSlotData(_regs.reg4);
+ loadScript(arg16(4), arg8(3));
+ _code = getSlotData(_regs.reg4) + codeOfs;
+ _switchLocalDataNear = true;
+}
+
+void ScriptInterpreter::sfRegisterFont() {
+ _vm->_screen->registerFont(arg8(3), arg16(4));
+}
+
+void ScriptInterpreter::sfLoadAddPalette() {
+ _vm->_palette->loadAddPalette(arg16(4), arg8(3));
+}
+
+void ScriptInterpreter::sfLoadScene() {
+ if (arg8(3) == 0) {
+ // FIXME: Originally, this was stopSpeech(). However, we need to stop
+ // ALL sounds here (including sound effects and background sounds)
+ // before purgeCache() is called, otherwise the sound buffers will be
+ // invalidated. This is apparent when moving from a scene that has
+ // background sounds (such as the canyon at the beginning), to another
+ // one that doesn't (such as the map), and does not stop the sounds
+ // already playing. In this case, the engine will either crash or
+ // garbage will be heard through the speakers.
+ // TODO: We should either move purgeCache() elsewhere, or monitor
+ // which resources are still used before purging the cache.
+ _vm->_sound->stopAll();
+ _vm->_res->purgeCache();
+ _vm->loadScene(arg16(4));
+ } else {
+ _vm->_screen->loadMouseCursor(arg16(4));
+ }
+}
+
+void ScriptInterpreter::sfSetGuiHeight() {
+ _vm->setGuiHeight(arg8(3));
+}
+
+void ScriptInterpreter::sfFindMouseInRectIndex1() {
+ int16 index = -1;
+ if (_vm->_mouseY < _vm->_cameraHeight) {
+ int16 slotIndex = arg16(5);
+ index = _vm->findRectAtPoint(getSlotData(slotIndex) + arg16(3),
+ _vm->_mouseX + _vm->_cameraX,
+ _vm->_mouseY + _vm->_cameraY,
+ arg16(11) + 1, arg16(7),
+ getSlotData(slotIndex) + _slots[slotIndex].size);
+ }
+ localWrite16(arg16(9), index);
+}
+
+void ScriptInterpreter::sfFindMouseInRectIndex2() {
+ int16 index = -1;
+ if (_vm->_sceneResIndex != 0) {
+ if (_vm->_mouseY < _vm->_cameraHeight) {
+ int16 slotIndex = arg16(5);
+ index = _vm->findRectAtPoint(getSlotData(slotIndex) + arg16(3),
+ _vm->_mouseX + _vm->_cameraX,
+ _vm->_mouseY + _vm->_cameraY,
+ 0, arg16(7),
+ getSlotData(slotIndex) + _slots[slotIndex].size);
+ }
+ }
+ localWrite16(arg16(9), index);
+}
+
+void ScriptInterpreter::sfDrawGuiImage() {
+ _vm->_screen->drawGuiImage(arg16(5), arg16(3), arg16(7));
+}
+
+void ScriptInterpreter::sfAddAnimatedSpriteNoLoop() {
+ _vm->_screen->addAnimatedSprite(arg16(5), arg16(3), arg16(7), (byte *)localPtr(0), (int16 *)localPtr(arg16(9)), false, 2);
+}
+
+void ScriptInterpreter::sfAddAnimatedSprite() {
+ _vm->_screen->addAnimatedSprite(arg16(5), arg16(3), arg16(7), (byte *)localPtr(0), (int16 *)localPtr(arg16(9)), true, 2);
+}
+
+void ScriptInterpreter::sfAddStaticSprite() {
+ _vm->_screen->addStaticSprite(_subCode + 3);
+}
+
+void ScriptInterpreter::sfAddAnimatedSpriteScaled() {
+ _vm->_screen->addAnimatedSprite(arg16(5), arg16(3), arg16(7), (byte *)localPtr(0), (int16 *)localPtr(arg16(9)), true, 1);
+}
+
+void ScriptInterpreter::sfFindPath() {
+ _vm->_segmap->findPath((int16 *)(getSlotData(arg16(13)) + arg16(11)), arg16(9), arg16(7), arg16(5), arg16(3));
+}
+
+void ScriptInterpreter::sfWalk() {
+ _vm->walk(getSlotData(arg16(5)) + arg16(3));
+}
+
+void ScriptInterpreter::sfScrollCameraUp() {
+ _vm->scrollCameraUp(4);
+}
+
+void ScriptInterpreter::sfScrollCameraDown() {
+ _vm->scrollCameraDown(4);
+}
+
+void ScriptInterpreter::sfScrollCameraLeft() {
+ _vm->scrollCameraLeft(4);
+}
+
+void ScriptInterpreter::sfScrollCameraRight() {
+ _vm->scrollCameraRight(4);
+}
+
+void ScriptInterpreter::sfScrollCameraUpEx() {
+ _vm->scrollCameraUp(arg16(3));
+}
+
+void ScriptInterpreter::sfScrollCameraDownEx() {
+ _vm->scrollCameraDown(arg16(3));
+}
+
+void ScriptInterpreter::sfScrollCameraLeftEx() {
+ _vm->scrollCameraLeft(arg16(3));
+}
+
+void ScriptInterpreter::sfScrollCameraRightEx() {
+ _vm->scrollCameraRight(arg16(3));
+}
+
+void ScriptInterpreter::sfSetCamera() {
+ _vm->setCamera(arg16(5), arg16(3));
+}
+
+void ScriptInterpreter::sfGetCameraChanged() {
+ localWrite16(arg16(3), _vm->getCameraChanged() ? 1 : 0);
+}
+
+void ScriptInterpreter::sfGetRgbModifiertAtPoint() {
+ byte *rgb = getSlotData(arg16(11)) + arg16(9);
+ _vm->_segmap->getRgbModifiertAtPoint(arg16(5), arg16(3), arg16(7), rgb[0], rgb[1], rgb[2]);
+}
+
+void ScriptInterpreter::sfStartAnim() {
+ _vm->_anim->start(arg16(3));
+}
+
+void ScriptInterpreter::sfAnimNextFrame() {
+ _vm->_anim->nextFrame();
+}
+
+void ScriptInterpreter::sfGetAnimFrameNumber() {
+ localWrite16(arg16(3), _vm->_anim->getFrameNumber());
+}
+
+void ScriptInterpreter::sfGetAnimStatus() {
+ int16 status = _vm->_anim->getStatus();
+ if (status == 0 || status == 1) {
+ // TODO mov screenFlag01, 0
+ }
+ localWrite16(arg16(3), status);
+}
+
+void ScriptInterpreter::sfStartShakeScreen() {
+ _vm->_screen->startShakeScreen(arg16(3));
+}
+
+void ScriptInterpreter::sfStopShakeScreen() {
+ _vm->_screen->stopShakeScreen();
+}
+
+void ScriptInterpreter::sfStartSequence() {
+ int16 sequenceResIndex = arg16(3);
+ //debug("ScriptInterpreter::sfStartSequence(%d)", sequenceResIndex);
+ if (sequenceResIndex >= 0) {
+ //_vm->_arc->dump(sequenceResIndex, "music"); // DEBUG: Dump music so we know what's in there
+
+ _vm->_music->playSequence(sequenceResIndex);
+ }
+}
+
+void ScriptInterpreter::sfEndSequence() {
+ //debug("ScriptInterpreter::sfEndSequence");
+ _vm->_music->stopSequence();
+}
+
+void ScriptInterpreter::sfSetSequenceVolume() {
+ // TODO
+ //debug("ScriptInterpreter::sfSetSequenceVolume");
+}
+
+void ScriptInterpreter::sfPlayPositionalSound() {
+ _vm->_sound->playSoundAtPos(arg16(3), arg16(9), arg16(7));
+}
+
+void ScriptInterpreter::sfPlaySound2() {
+ _vm->_sound->playSound(arg16(3), arg16(5), arg16(7));
+}
+
+void ScriptInterpreter::sfClearScreen() {
+ // TODO: Occurs on every scene change, but seems unneeded
+ //debug("ScriptInterpreter::sfClearScreen");
+}
+
+void ScriptInterpreter::sfHandleInput() {
+ int16 varOfs = arg16(3);
+ int16 keyCode = 0;
+ if (_vm->_rightButtonDown) {
+ keyCode = 1;
+ } else {
+ /* Convert keyboard scancode to IBM PC scancode
+ Only scancodes known to be used (so far) are converted
+ */
+ switch (_vm->_keyState.keycode) {
+ case Common::KEYCODE_ESCAPE:
+ keyCode = 1;
+ break;
+ case Common::KEYCODE_F10:
+ keyCode = 68;
+ break;
+ default:
+ break;
+ }
+ }
+ localWrite16(varOfs, keyCode);
+}
+
+void ScriptInterpreter::sfRunOptionsScreen() {
+ _vm->_screen->loadMouseCursor(12);
+ _vm->_palette->loadAddPalette(9, 224);
+ _vm->_palette->setDeltaPalette(_vm->_palette->getMainPalette(), 7, 0, 31, 224);
+ _vm->_screen->finishTalkTextItems();
+ _vm->_screen->clearSprites();
+ CursorMan.showMouse(true);
+ _vm->_menuSystem->run();
+ _vm->_keyState.reset();
+ _switchLocalDataNear = true;
+}
+
+/* NOTE: The opcodes sfPrecacheSprites, sfPrecacheSounds1, sfPrecacheSounds2 and
+ sfDeletePrecachedFiles were used by the original engine to handle precaching
+ of data so the game doesn't stall while playing (due to the slow speed of
+ CD-Drives back then). This is not needed in ScummVM since all supported
+ systems are fast enough to load data in-game. */
+
+void ScriptInterpreter::sfPrecacheSprites() {
+ // See note above
+}
+
+void ScriptInterpreter::sfPrecacheSounds1() {
+ // See note above
+}
+
+void ScriptInterpreter::sfDeletePrecachedFiles() {
+ // See note above
+}
+
+void ScriptInterpreter::sfPrecacheSounds2() {
+ // See note above
+}
+
+void ScriptInterpreter::sfRestoreStackPtr() {
+ _regs.sp = _savedSp;
+}
+
+void ScriptInterpreter::sfSaveStackPtr() {
+ _savedSp = _regs.sp;
+}
+
+void ScriptInterpreter::sfPlayMovie() {
+ _vm->_moviePlayer->playMovie(arg16(3));
+}
+
+} // End of namespace Toltecs
diff --git a/engines/toltecs/script.h b/engines/toltecs/script.h
new file mode 100644
index 0000000000..0c1898c525
--- /dev/null
+++ b/engines/toltecs/script.h
@@ -0,0 +1,184 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ *
+ */
+
+#ifndef TOLTECS_SCRIPT_H
+#define TOLTECS_SCRIPT_H
+
+#include "common/func.h"
+
+namespace Toltecs {
+
+const int kMaxScriptSlots = 50;
+const int kScriptStackSize = 4096 + 4;
+
+enum VarType {
+ vtByte,
+ vtWord
+};
+
+typedef Common::Functor0<void> ScriptFunction;
+
+class ScriptInterpreter {
+public:
+ ScriptInterpreter(ToltecsEngine *vm);
+ ~ScriptInterpreter();
+
+ void loadScript(uint resIndex, uint slotIndex);
+ void setMainScript(uint slotIndex);
+ void runScript();
+
+ byte *getSlotData(int slotIndex) const { return _slots[slotIndex].data; }
+
+ VarType getGameVarType(uint variable);
+ int16 getGameVar(uint variable);
+ void setGameVar(uint variable, int16 value);
+
+ void saveState(Common::WriteStream *out);
+ void loadState(Common::ReadStream *in);
+
+protected:
+
+ struct ScriptRegs {
+ int16 reg0;
+ int16 reg1;
+ int16 reg2;
+ int16 reg3;
+ int16 reg4;
+ int16 reg5;
+ int16 reg6;
+ int16 sp;
+ int16 reg8;
+ };
+
+ struct ScriptSlot {
+ byte *data;
+ int32 size;
+ uint resIndex;
+ };
+
+ ToltecsEngine *_vm;
+ Common::Array<const ScriptFunction *> _scriptFuncs;
+ Common::Array<const char *> _scriptFuncNames;
+
+ byte *_stack;
+
+ byte *_code, *_subCode;
+ byte *_localData;
+ bool _switchLocalDataNear, _switchLocalDataFar, _switchLocalDataToStack;
+ bool _cmpBitTest;
+
+ ScriptSlot _slots[kMaxScriptSlots];
+
+ ScriptRegs _regs;
+ int16 _savedSp;
+
+ byte readByte();
+ int16 readInt16();
+
+ void execOpcode(byte opcode);
+
+ void setupScriptFunctions();
+ void execScriptFunction(uint16 index);
+
+ byte arg8(int16 offset);
+ int16 arg16(int16 offset);
+
+ void pushInt16(int16 value);
+ int16 popInt16();
+
+ void localWrite8(int16 offset, byte value);
+ byte localRead8(int16 offset);
+ void localWrite16(int16 offset, int16 value);
+ int16 localRead16(int16 offset);
+ byte *localPtr(int16 offset);
+
+ void sfNop();
+ void sfGetGameVar();
+ void sfSetGameVar();
+ void sfUpdateScreen();
+ void sfGetRandomNumber();
+ void sfDrawGuiTextMulti();
+ void sfUpdateVerbLine();
+ void sfSetFontColor();
+ void sfGetTalkTextDuration();
+ void sfTalk();
+ void sfFindPaletteFragment();
+ void sfClearPaletteFragments();
+ void sfAddPaletteFragment();
+ void sfSetDeltaAnimPalette();
+ void sfSetUnkPaletteEffect();
+ void sfBuildColorTransTable();
+ void sfSetDeltaMainPalette();
+ void sfLoadScript();
+ void sfRegisterFont();
+ void sfLoadAddPalette();
+ void sfLoadScene();
+ void sfSetGuiHeight();
+ void sfFindMouseInRectIndex1();
+ void sfFindMouseInRectIndex2();
+ void sfDrawGuiImage();
+ void sfAddAnimatedSpriteNoLoop();
+ void sfAddAnimatedSprite();
+ void sfAddStaticSprite();
+ void sfAddAnimatedSpriteScaled();
+ void sfFindPath();
+ void sfWalk();
+ void sfScrollCameraUp();
+ void sfScrollCameraDown();
+ void sfScrollCameraLeft();
+ void sfScrollCameraRight();
+ void sfScrollCameraUpEx();
+ void sfScrollCameraDownEx();
+ void sfScrollCameraLeftEx();
+ void sfScrollCameraRightEx();
+ void sfSetCamera();
+ void sfGetCameraChanged();
+ void sfGetRgbModifiertAtPoint();
+ void sfStartAnim();
+ void sfAnimNextFrame();
+ void sfGetAnimFrameNumber();
+ void sfGetAnimStatus();
+ void sfStartShakeScreen();
+ void sfStopShakeScreen();
+ void sfStartSequence();
+ void sfEndSequence();
+ void sfSetSequenceVolume();
+ void sfPlayPositionalSound();
+ void sfPlaySound2();
+ void sfClearScreen();
+ void sfHandleInput();
+ void sfRunOptionsScreen();
+ void sfPrecacheSprites();
+ void sfPrecacheSounds1();
+ void sfDeletePrecachedFiles();
+ void sfPrecacheSounds2();
+ void sfRestoreStackPtr();
+ void sfSaveStackPtr();
+ void sfPlayMovie();
+
+};
+
+
+} // End of namespace Toltecs
+
+#endif /* TOLTECS_H */
diff --git a/engines/toltecs/segmap.cpp b/engines/toltecs/segmap.cpp
new file mode 100644
index 0000000000..f7d806c67b
--- /dev/null
+++ b/engines/toltecs/segmap.cpp
@@ -0,0 +1,408 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ *
+ */
+
+#include "toltecs/toltecs.h"
+#include "toltecs/render.h"
+#include "toltecs/segmap.h"
+
+namespace Toltecs {
+
+SegmentMap::SegmentMap(ToltecsEngine *vm) : _vm(vm) {
+}
+
+SegmentMap::~SegmentMap() {
+ freeSegmapMaskRectSurfaces();
+}
+
+void SegmentMap::load(byte *source) {
+
+ freeSegmapMaskRectSurfaces();
+ _maskRects.clear();
+ _pathRects.clear();
+ _infoRects.clear();
+
+ // Load mask rects
+ byte *maskData = source + 2;
+ uint16 maskSize = READ_LE_UINT16(source);
+ source += 2;
+ uint16 maskRectCount = READ_LE_UINT16(source);
+ source += 2;
+ uint16 maskRectDataSize = maskRectCount * 12 + 2;
+
+ debug(0, "SegmentMap::load() maskRectCount = %d", maskRectCount);
+
+ for (uint16 i = 0; i < maskRectCount; i++) {
+ SegmapMaskRect maskRect;
+ int16 maskOffset;
+ maskRect.y = READ_LE_UINT16(source);
+ maskRect.x = READ_LE_UINT16(source + 2);
+ maskRect.height = READ_LE_UINT16(source + 4);
+ maskRect.width = READ_LE_UINT16(source + 6);
+ maskOffset = READ_LE_UINT16(source + 8);
+ maskRect.priority = READ_LE_UINT16(source + 10);
+ loadSegmapMaskRectSurface(maskData + maskOffset, maskRect);
+
+ debug(0, "SegmentMap::load() (%d, %d, %d, %d, %04X, %d)",
+ maskRect.x, maskRect.y, maskRect.width, maskRect.height, maskOffset, maskRect.priority);
+
+ source += 12;
+ _maskRects.push_back(maskRect);
+ }
+
+ source += maskSize - maskRectDataSize;
+
+ // Load path rects
+
+ source += 2; // skip rects array size
+
+ uint16 pathRectCount = READ_LE_UINT16(source);
+ source += 2;
+
+ debug(0, "SegmentMap::load() pathRectCount = %d", pathRectCount);
+
+ for (uint16 i = 0; i < pathRectCount; i++) {
+ SegmapPathRect pathRect;
+ pathRect.y1 = READ_LE_UINT16(source);
+ pathRect.x1 = READ_LE_UINT16(source + 2);
+ pathRect.y2 = pathRect.y1 + READ_LE_UINT16(source + 4);
+ pathRect.x2 = pathRect.x1 + READ_LE_UINT16(source + 6);
+
+ debug(0, "SegmentMap::load() (%d, %d, %d, %d)", pathRect.x1, pathRect.y1, pathRect.x2, pathRect.y2);
+
+ source += 8;
+ _pathRects.push_back(pathRect);
+ }
+
+ // Load info rects
+
+ source += 2; // skip rects array size
+
+ uint16 infoRectCount = READ_LE_UINT16(source);
+ source += 2;
+ debug(0, "SegmentMap::load() infoRectCount = %d", infoRectCount);
+ for (uint16 i = 0; i < infoRectCount; i++) {
+ SegmapInfoRect infoRect;
+ infoRect.y = READ_LE_UINT16(source);
+ infoRect.x = READ_LE_UINT16(source + 2);
+ infoRect.height = READ_LE_UINT16(source + 4);
+ infoRect.width = READ_LE_UINT16(source + 6);
+ infoRect.id = source[8];
+ infoRect.a = source[9];
+ infoRect.b = source[10];
+ infoRect.c = source[11];
+
+ debug(0, "SegmentMap::load() (%d, %d, %d, %d) (%d, %d, %d, %d)",
+ infoRect.x, infoRect.y, infoRect.width, infoRect.height,
+ infoRect.id, (int8)infoRect.a, (int8)infoRect.b, (int8)infoRect.c);
+
+ source += 12;
+ _infoRects.push_back(infoRect);
+ }
+
+ // TODO Other stuff
+
+
+}
+
+int16 SegmentMap::findPathRectAtPoint(int16 x, int16 y) {
+ for (int16 rectIndex = 0; rectIndex < (int16)_pathRects.size(); rectIndex++) {
+ if (y >= _pathRects[rectIndex].y1 && y <= _pathRects[rectIndex].y2 &&
+ x >= _pathRects[rectIndex].x1 && x <= _pathRects[rectIndex].x2) {
+ return rectIndex;
+ }
+ }
+ return -1;
+}
+
+void SegmentMap::adjustPathPoint(int16 &x, int16 &y) {
+
+ if (findPathRectAtPoint(x, y) != -1)
+ return;
+
+ uint32 minDistance = 0xFFFFFFFF, distance;
+ int16 adjustedX = 0, adjustedY = 0, x2, y2;
+
+ for (int16 rectIndex = 0; rectIndex < (int16)_pathRects.size(); rectIndex++) {
+
+ if (x >= _pathRects[rectIndex].x1 && x < _pathRects[rectIndex].x2) {
+ x2 = x;
+ } else if (ABS(x - _pathRects[rectIndex].x1) >= ABS(x - _pathRects[rectIndex].x2)) {
+ x2 = _pathRects[rectIndex].x2;
+ } else {
+ x2 = _pathRects[rectIndex].x1;
+ }
+
+ if (ABS(y - _pathRects[rectIndex].y1) >= ABS(y - _pathRects[rectIndex].y2)) {
+ y2 = _pathRects[rectIndex].y2;
+ } else {
+ y2 = _pathRects[rectIndex].y1;
+ }
+
+ distance = ABS(y - y2) + ABS(x - x2);
+ if (distance < minDistance) {
+ if (x >= _pathRects[rectIndex].x1 && x <= _pathRects[rectIndex].x2) {
+ adjustedX = x;
+ } else {
+ adjustedX = x2;
+ }
+ if (y >= _pathRects[rectIndex].y1 && y <= _pathRects[rectIndex].y2) {
+ adjustedY = y;
+ } else {
+ adjustedY = y2;
+ }
+ minDistance = distance;
+ }
+
+ }
+
+ x = adjustedX;
+ y = adjustedY;
+
+}
+
+int16 SegmentMap::findNextPathRect(int16 srcRectIndex, int16 destX, int16 destY) {
+
+ int16 result;
+ uint16 minDistance, distance;
+ int16 x1, y1, x2, y2;
+ int16 xmin, xmax, ymax, ymin;
+
+ result = -1;
+ minDistance = 0xFFFF;
+
+ x1 = _pathRects[srcRectIndex].x1;
+ y1 = _pathRects[srcRectIndex].y1;
+ x2 = _pathRects[srcRectIndex].x2;
+ y2 = _pathRects[srcRectIndex].y2;
+
+ for (int16 rectIndex = 0; rectIndex < (int16)_pathRects.size(); rectIndex++) {
+
+ int16 nodeX = -1, nodeY = -1;
+
+ // Check if the current rectangle is connected to the source rectangle
+ if (x1 == _pathRects[rectIndex].x2 && y1 < _pathRects[rectIndex].y2 && y2 > _pathRects[rectIndex].y1) {
+ nodeX = x1;
+ } else if (x2 == _pathRects[rectIndex].x1 && y1 < _pathRects[rectIndex].y2 && y2 > _pathRects[rectIndex].y1) {
+ nodeX = x2 - 1;
+ } else if (y1 == _pathRects[rectIndex].y2 && x1 < _pathRects[rectIndex].x2 && x2 > _pathRects[rectIndex].x1) {
+ nodeY = y1;
+ } else if (y2 == _pathRects[rectIndex].y1 && x1 < _pathRects[rectIndex].x2 && x2 > _pathRects[rectIndex].x1) {
+ nodeY = y2 - 1;
+ } else
+ continue;
+
+ if (nodeX == -1) {
+ xmin = MAX<int16>(x1, _pathRects[rectIndex].x1);
+ xmax = MIN<int16>(x2, _pathRects[rectIndex].x2) - 1;
+ if (destX > xmin && destX < xmax) {
+ nodeX = destX;
+ } else if (ABS(destX - xmin) >= ABS(destX - xmax)) {
+ nodeX = xmax - 1;
+ } else {
+ nodeX = xmin;
+ }
+ }
+
+ if (nodeY == -1) {
+ ymin = MAX<int16>(y1, _pathRects[rectIndex].y1);
+ ymax = MIN<int16>(y2, _pathRects[rectIndex].y2) - 1;
+ if (destY > ymin && destY < ymax) {
+ nodeY = destY;
+ } else if (ABS(destY - ymin) >= ABS(destY - ymax)) {
+ nodeY = ymax - 1;
+ } else {
+ nodeY = ymin;
+ }
+ }
+
+ distance = ABS(destX - nodeX) + ABS(destY - nodeY);
+
+ for (uint i = 0; i < _closedPathRectsCount; i++) {
+ if (rectIndex == _closedPathRects[i]) {
+ distance = minDistance;
+ break;
+ }
+ }
+
+ for (uint i = 0; i < _deadEndPathRectsCount; i++) {
+ if (rectIndex == _deadEndPathRects[i]) {
+ distance = minDistance;
+ break;
+ }
+ }
+
+ if (distance < minDistance) {
+ result = rectIndex;
+ minDistance = distance;
+ _pathNodes[_pathNodesCount].x = nodeX;
+ _pathNodes[_pathNodesCount].y = nodeY;
+ }
+
+ }
+
+ return result;
+}
+
+struct LineData {
+ int pitch;
+ byte *surf;
+};
+
+void plotProc(int x, int y, int color, void *data) {
+ LineData *ld = (LineData *)data;
+ ld->surf[x + y * ld->pitch] = color;
+}
+
+void SegmentMap::findPath(int16 *pointsArray, int16 destX, int16 destY, int16 sourceX, int16 sourceY) {
+
+ int16 currentRectIndex, destRectIndex;
+ int16 pointsCount;
+
+ debug(0, "SegmentMap::findPath(fromX: %d; fromY: %d; toX: %d; toY: %d)", sourceX, sourceY, destX, destY);
+
+ _deadEndPathRectsCount = 0;
+ _closedPathRectsCount = 0;
+ _pathNodesCount = 0;
+
+ pointsCount = 2;
+
+ adjustPathPoint(sourceX, sourceY);
+ currentRectIndex = findPathRectAtPoint(sourceX, sourceY);
+
+ adjustPathPoint(destX, destY);
+ destRectIndex = findPathRectAtPoint(destX, destY);
+
+ if (currentRectIndex != -1) {
+ if (destRectIndex != currentRectIndex) {
+ while (1) {
+ do {
+ _closedPathRects[_closedPathRectsCount++] = currentRectIndex;
+ currentRectIndex = findNextPathRect(currentRectIndex, destX, destY);
+ _pathNodesCount++;
+ } while (currentRectIndex != -1 && currentRectIndex != destRectIndex);
+ if (currentRectIndex != -1 && currentRectIndex == destRectIndex)
+ break;
+ _deadEndPathRects[_deadEndPathRectsCount++] = _closedPathRects[--_closedPathRectsCount];
+ _pathNodesCount -= 2;
+ currentRectIndex = _closedPathRects[--_closedPathRectsCount];
+ }
+ for (int16 i = 0; i < _pathNodesCount; i++) {
+ pointsArray[pointsCount++] = TO_LE_16(_pathNodes[i].y);
+ pointsArray[pointsCount++] = TO_LE_16(_pathNodes[i].x);
+ }
+ }
+
+ pointsArray[pointsCount++] = TO_LE_16(destY);
+ pointsArray[pointsCount++] = TO_LE_16(destX);
+
+ pointsArray[0] = 0;
+ pointsArray[1] = TO_LE_16(_pathNodesCount + 1);
+ }
+
+ debug(0, "SegmentMap::findPath() count = %d", FROM_LE_16(pointsArray[1]));
+
+#if 0 // DEBUG: Draw the path we found
+ int sx = sourceX, sy = sourceY;
+ LineData ld;
+ ld.pitch = _vm->_sceneWidth;
+ ld.surf = _vm->_screen->_backScreen;
+ for (int16 i = 0; i < FROM_LE_16(pointsArray[1]) * 2; i+=2) {
+ const int x = FROM_LE_16(pointsArray[3+i]);
+ const int y = FROM_LE_16(pointsArray[2+1]);
+ debug(0, "x = %d; y = %d", x, y);
+ Graphics::drawLine(sx, sy, x, y, 0xFF, plotProc, &ld);
+ sx = x;
+ sy = y;
+ }
+#endif
+
+}
+
+int8 SegmentMap::getScalingAtPoint(int16 x, int16 y) {
+ int8 scaling = 0;
+ for (uint i = 0; i < _infoRects.size(); i++) {
+ if (_infoRects[i].id == 0 && _infoRects[i].isPointInside(x, y)) {
+ int8 topScaling = (int8)_infoRects[i].b;
+ int8 bottomScaling = (int8)_infoRects[i].c;
+ if (y - _infoRects[i].y != 0) {
+ scaling = (ABS(y - _infoRects[i].y) * (bottomScaling - topScaling) / _infoRects[i].height) + topScaling;
+ }
+ }
+ }
+ debug(0, "SegmentMap::getScalingAtPoint(%d, %d) %d", x, y, scaling);
+ return scaling;
+}
+
+void SegmentMap::getRgbModifiertAtPoint(int16 x, int16 y, int16 id, byte &r, byte &g, byte &b) {
+ r = 0;
+ g = 0;
+ b = 0;
+ for (uint i = 0; i < _infoRects.size(); i++) {
+ if (_infoRects[i].id == id && _infoRects[i].isPointInside(x, y)) {
+ r = _infoRects[i].a;
+ g = _infoRects[i].b;
+ b = _infoRects[i].c;
+ }
+ }
+ debug(0, "SegmentMap::getRgbModifiertAtPoint() r: %d; g: %d; b: %d", r, g, b);
+}
+
+void SegmentMap::loadSegmapMaskRectSurface(byte *maskData, SegmapMaskRect &maskRect) {
+
+ maskRect.surface = new Graphics::Surface();
+ maskRect.surface->create(maskRect.width, maskRect.height, Graphics::PixelFormat::createFormatCLUT8());
+
+ byte *backScreen = _vm->_screen->_backScreen + maskRect.x + (maskRect.y * _vm->_sceneWidth);
+ byte *dest = (byte *)maskRect.surface->getBasePtr(0, 0);
+
+ for (int16 h = 0; h < maskRect.height; h++) {
+ int16 w = maskRect.width;
+ while (w > 0) {
+ byte mask = *maskData++;
+ byte count = mask & 0x7F;
+ if (mask & 0x80)
+ memcpy(dest, backScreen, count);
+ else
+ memset(dest, 0xFF, count);
+ w -= count;
+ dest += count;
+ backScreen += count;
+ }
+ backScreen += _vm->_sceneWidth - maskRect.width;
+ }
+
+}
+
+void SegmentMap::freeSegmapMaskRectSurfaces() {
+ for (uint i = 0; i < _maskRects.size(); i++) {
+ delete _maskRects[i].surface;
+ }
+}
+
+void SegmentMap::addMasksToRenderQueue() {
+ for (uint i = 0; i < _maskRects.size(); i++) {
+ _vm->_screen->_renderQueue->addMask(_maskRects[i]);
+ }
+}
+
+} // End of namespace Toltecs
diff --git a/engines/toltecs/segmap.h b/engines/toltecs/segmap.h
new file mode 100644
index 0000000000..30182a6b71
--- /dev/null
+++ b/engines/toltecs/segmap.h
@@ -0,0 +1,116 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ *
+ */
+
+#ifndef TOLTECS_SEGMAP_H
+#define TOLTECS_SEGMAP_H
+
+#include "common/array.h"
+
+#include "toltecs/screen.h"
+
+namespace Toltecs {
+
+struct ScriptWalk {
+ int16 y, x;
+ int16 y1, x1, y2, x2;
+ int16 yerror, xerror;
+ int16 mulValue;
+ int16 scaling;
+};
+
+struct SegmapMaskRect {
+ int16 x, y;
+ int16 width, height;
+ int16 priority;
+ Graphics::Surface *surface;
+};
+
+class SegmentMap {
+public:
+ SegmentMap(ToltecsEngine *vm);
+ ~SegmentMap();
+
+ void load(byte *source);
+
+ int16 findPathRectAtPoint(int16 x, int16 y);
+ void adjustPathPoint(int16 &x, int16 &y);
+
+ void findPath(int16 *pointsArray, int16 destX, int16 destY, int16 sourceX, int16 sourceY);
+
+ int8 getScalingAtPoint(int16 x, int16 y);
+ void getRgbModifiertAtPoint(int16 x, int16 y, int16 id, byte &r, byte &g, byte &b);
+
+ void addMasksToRenderQueue();
+
+//protected:
+public: // for debugging purposes
+
+ struct SegmapPathRect {
+ int16 x1, y1, x2, y2;
+ };
+
+ struct SegmapInfoRect {
+ int16 y, x;
+ int16 height, width;
+ byte id;
+ byte a, b, c;
+ inline bool isPointInside(int16 px, int16 py) {
+ return py >= y && py <= y + height && px >= x && px <= x + width;
+ }
+ };
+
+ struct PathPoint {
+ int16 y, x;
+ };
+
+ typedef Common::Array<SegmapMaskRect> SegmapMaskRectArray;
+ typedef Common::Array<SegmapPathRect> SegmapPathRectArray;
+ typedef Common::Array<SegmapInfoRect> SegmapInfoRectArray;
+
+ ToltecsEngine *_vm;
+
+ SegmapMaskRectArray _maskRects;
+ byte *_maskRectData;
+
+ SegmapPathRectArray _pathRects;
+ SegmapInfoRectArray _infoRects;
+
+ int16 _deadEndPathRects[1000];
+ uint _deadEndPathRectsCount;
+
+ int16 _closedPathRects[1000];
+ uint _closedPathRectsCount;
+
+ PathPoint _pathNodes[1000];
+ int16 _pathNodesCount;
+
+ int16 findNextPathRect(int16 srcRectIndex, int16 destX, int16 destY);
+
+ void loadSegmapMaskRectSurface(byte *maskData, SegmapMaskRect &maskRect);
+ void freeSegmapMaskRectSurfaces();
+
+};
+
+} // End of namespace Toltecs
+
+#endif /* TOLTECS_SEGMAP_H */
diff --git a/engines/toltecs/sound.cpp b/engines/toltecs/sound.cpp
new file mode 100644
index 0000000000..c9ef00e31b
--- /dev/null
+++ b/engines/toltecs/sound.cpp
@@ -0,0 +1,224 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ *
+ */
+
+#include "audio/audiostream.h"
+#include "audio/mixer.h"
+#include "audio/decoders/raw.h"
+
+#include "toltecs/toltecs.h"
+#include "toltecs/resource.h"
+#include "toltecs/segmap.h"
+#include "toltecs/sound.h"
+
+namespace Toltecs {
+
+Sound::Sound(ToltecsEngine *vm) : _vm(vm) {
+ for (int i = 0; i < kMaxChannels; i++) {
+ channels[i].type = kChannelTypeEmpty;
+ channels[i].resIndex = -1;
+ }
+}
+
+Sound::~Sound() {
+}
+
+void Sound::playSpeech(int16 resIndex) {
+ debug(0, "playSpeech(%d)", resIndex);
+ internalPlaySound(resIndex, kChannelTypeSpeech, 50 /*TODO*/, 0);
+}
+
+void Sound::playSound(int16 resIndex, int16 type, int16 volume) {
+
+ // TODO: Use the right volumes
+
+ debug(0, "playSound(%d, %d, %d)", resIndex, type, volume);
+
+ if (volume == -1 || type == -2) {
+ if (type == kChannelTypeBackground) {
+ internalPlaySound(resIndex, type, 50 /*TODO*/, 0);
+ } else {
+ internalPlaySound(resIndex, type, 100 /*TODO*/, 0);
+ }
+ } else {
+ internalPlaySound(resIndex, type, 100 /*TODO*/, 0);
+ }
+
+}
+
+void Sound::playSoundAtPos(int16 resIndex, int16 x, int16 y) {
+
+ debug(0, "playSoundAtPos(%d, %d, %d)", resIndex, x, y);
+
+ int16 volume, panning = 0, deltaX = 0;
+ int8 scaling = _vm->_segmap->getScalingAtPoint(x, y);
+
+ if (scaling >= 0)
+ volume = 50 + ABS(scaling) / 2;
+ else
+ volume = 50 - ABS(scaling) / 2;
+
+ if (_vm->_cameraX > x)
+ deltaX = _vm->_cameraX - x;
+ else if (_vm->_cameraX + 640 < x)
+ deltaX = x - (_vm->_cameraX + 640);
+ if (deltaX > 600)
+ deltaX = 600;
+
+ volume = ((100 - deltaX / 6) * volume) / 100;
+
+ if (_vm->_cameraX + 320 != x) {
+ panning = CLIP(x - (_vm->_cameraX + 320), -381, 381) / 3;
+ }
+
+ internalPlaySound(resIndex, 1, volume, panning);
+
+}
+
+void Sound::internalPlaySound(int16 resIndex, int16 type, int16 volume, int16 panning) {
+
+ if (resIndex == -1) {
+ // Stop all sounds
+ _vm->_mixer->stopAll();
+ _vm->_screen->keepTalkTextItemsAlive();
+ for (int i = 0; i < kMaxChannels; i++) {
+ channels[i].type = kChannelTypeEmpty;
+ channels[i].resIndex = -1;
+ }
+ } else if (type == -2) {
+ // Stop sounds with specified resIndex
+ for (int i = 0; i < kMaxChannels; i++) {
+ if (channels[i].resIndex == resIndex) {
+ _vm->_mixer->stopHandle(channels[i].handle);
+ channels[i].type = kChannelTypeEmpty;
+ channels[i].resIndex = -1;
+ }
+ }
+ } else {
+
+ if (type == -3) {
+ // Stop speech and play new sound
+ stopSpeech();
+ }
+
+ // Play new sound in empty channel
+ int freeChannel = -1;
+ for (int i = 0; i < kMaxChannels; i++) {
+ if (channels[i].type == kChannelTypeEmpty || !_vm->_mixer->isSoundHandleActive(channels[i].handle)) {
+ freeChannel = i;
+ break;
+ }
+ }
+
+ // If all channels are in use no new sound will be played
+ if (freeChannel >= 0) {
+ Resource *soundResource = _vm->_res->load(resIndex);
+
+ Audio::AudioStream *stream = Audio::makeLoopingAudioStream(
+ Audio::makeRawStream(soundResource->data,
+ soundResource->size, 22050, Audio::FLAG_UNSIGNED,
+ DisposeAfterUse::NO),
+ type == kChannelTypeBackground ? 0 : 1);
+
+ channels[freeChannel].type = type;
+ channels[freeChannel].resIndex = resIndex;
+
+ Audio::Mixer::SoundType soundType = Audio::Mixer::kPlainSoundType;
+ /*
+ switch (type) {
+ }
+ */
+
+ _vm->_mixer->playStream(soundType, &channels[freeChannel].handle,
+ stream, -1, volume, panning);
+ }
+
+ }
+
+}
+
+void Sound::updateSpeech() {
+ for (int i = 0; i < kMaxChannels; i++) {
+ if (channels[i].type == kChannelTypeSpeech && _vm->_mixer->isSoundHandleActive(channels[i].handle)) {
+ _vm->_screen->keepTalkTextItemsAlive();
+ break;
+ }
+ }
+}
+
+void Sound::stopSpeech() {
+ for (int i = 0; i < kMaxChannels; i++) {
+ if (channels[i].type == kChannelTypeSpeech) {
+ _vm->_mixer->stopHandle(channels[i].handle);
+ _vm->_screen->keepTalkTextItemsAlive();
+ channels[i].type = kChannelTypeEmpty;
+ channels[i].resIndex = -1;
+ }
+ }
+}
+
+void Sound::stopAll() {
+ for (int i = 0; i < kMaxChannels; i++) {
+ _vm->_mixer->stopHandle(channels[i].handle);
+ _vm->_screen->keepTalkTextItemsAlive();
+ channels[i].type = kChannelTypeEmpty;
+ channels[i].resIndex = -1;
+ }
+}
+
+void Sound::saveState(Common::WriteStream *out) {
+ for (int i = 0; i < kMaxChannels; i++) {
+ out->writeSint16LE(channels[i].type);
+ out->writeSint16LE(channels[i].resIndex);
+ }
+}
+
+void Sound::loadState(Common::ReadStream *in) {
+ for (int i = 0; i < kMaxChannels; i++) {
+ channels[i].type = in->readSint16LE();
+ channels[i].resIndex = in->readSint16LE();
+
+ if (channels[i].type != kChannelTypeEmpty) {
+ Resource *soundResource = _vm->_res->load(channels[i].resIndex);
+
+ Audio::AudioStream *stream = Audio::makeLoopingAudioStream(
+ Audio::makeRawStream(soundResource->data,
+ soundResource->size, 22050, Audio::FLAG_UNSIGNED,
+ DisposeAfterUse::NO),
+ channels[i].type == kChannelTypeBackground ? 0 : 1);
+
+ Audio::Mixer::SoundType soundType = Audio::Mixer::kPlainSoundType;
+ /*
+ switch (type) {
+ }
+ */
+
+ // TODO: Volume and panning
+ int16 volume = (channels[i].type == kChannelTypeBackground) ? 50 : 100;
+
+ _vm->_mixer->playStream(soundType, &channels[i].handle,
+ stream, -1, volume, /*panning*/0);
+ }
+ }
+}
+
+} // End of namespace Toltecs
diff --git a/engines/toltecs/sound.h b/engines/toltecs/sound.h
new file mode 100644
index 0000000000..e292d22c0f
--- /dev/null
+++ b/engines/toltecs/sound.h
@@ -0,0 +1,77 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ *
+ */
+
+#ifndef TOLTECS_SOUND_H
+#define TOLTECS_SOUND_H
+
+#include "audio/mixer.h" // for Audio::SoundHandle
+
+#include "toltecs/toltecs.h"
+
+namespace Toltecs {
+
+// 0x1219
+
+enum SoundChannelType {
+ kChannelTypeEmpty = 0,
+ kChannelTypeBackground = -1,
+ kChannelTypeSfx = -2,
+ kChannelTypeSpeech = -3
+};
+
+struct SoundChannel {
+ int16 resIndex;
+ int16 type;
+ Audio::SoundHandle handle;
+};
+
+const int kMaxChannels = 4;
+
+class Sound {
+public:
+ Sound(ToltecsEngine *vm);
+ ~Sound();
+
+ void playSpeech(int16 resIndex);
+ void playSound(int16 resIndex, int16 type, int16 volume);
+ void playSoundAtPos(int16 resIndex, int16 x, int16 y);
+ void updateSpeech();
+ void stopSpeech();
+ void stopAll();
+
+ void saveState(Common::WriteStream *out);
+ void loadState(Common::ReadStream *in);
+
+protected:
+ ToltecsEngine *_vm;
+
+ SoundChannel channels[kMaxChannels];
+
+ void internalPlaySound(int16 resIndex, int16 type, int16 volume, int16 panning);
+
+};
+
+
+} // End of namespace Toltecs
+
+#endif /* TOLTECS_SOUND_H */
diff --git a/engines/toltecs/sprite.cpp b/engines/toltecs/sprite.cpp
new file mode 100644
index 0000000000..7a02663793
--- /dev/null
+++ b/engines/toltecs/sprite.cpp
@@ -0,0 +1,509 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ *
+ */
+
+#include "toltecs/toltecs.h"
+#include "toltecs/palette.h"
+#include "toltecs/render.h"
+#include "toltecs/resource.h"
+
+namespace Toltecs {
+
+class SpriteReader : public SpriteFilter {
+public:
+ SpriteReader(byte *source, const SpriteDrawItem &sprite) : SpriteFilter(sprite), _source(source) {
+ _curWidth = _sprite->origWidth;
+ _curHeight = _sprite->origHeight;
+ }
+ SpriteReaderStatus readPacket(PixelPacket &packet) {
+ if (_sprite->flags & 0x40) {
+ // shadow sprite
+ packet.count = _source[0] & 0x7F;
+ if (_source[0] & 0x80)
+ packet.pixel = 1;
+ else
+ packet.pixel = 0;
+ _source++;
+ } else if (_sprite->flags & 0x10) {
+ // 256-color sprite
+ packet.pixel = *_source++;
+ packet.count = *_source++;
+ } else {
+ // 16-color sprite
+ packet.count = _source[0] & 0x0F;
+ packet.pixel = (_source[0] & 0xF0) >> 4;
+ _source++;
+ }
+ _curWidth -= packet.count;
+ if (_curWidth <= 0) {
+ _curHeight--;
+ if (_curHeight == 0) {
+ return kSrsEndOfSprite;
+ } else {
+ _curWidth = _sprite->origWidth;
+ return kSrsEndOfLine;
+ }
+ } else {
+ return kSrsPixelsLeft;
+ }
+ }
+ byte *getSource() {
+ return _source;
+ }
+ void setSource(byte *source) {
+ _source = source;
+ _curHeight++;
+ }
+protected:
+ byte *_source;
+ int16 _curWidth, _curHeight;
+};
+
+class SpriteFilterScaleDown : public SpriteFilter {
+public:
+ SpriteFilterScaleDown(const SpriteDrawItem &sprite, SpriteReader *reader) : SpriteFilter(sprite), _reader(reader) {
+ _height = _sprite->height;
+ _yerror = _sprite->yerror;
+ _origHeight = _sprite->origHeight;
+ _scalerStatus = 0;
+ }
+ SpriteReaderStatus readPacket(PixelPacket &packet) {
+ SpriteReaderStatus status = kSrsPixelsLeft;
+ if (_scalerStatus == 0) {
+ _xerror = _sprite->xdelta;
+ _yerror -= 100;
+ while (_yerror <= 0) {
+ do {
+ status = _reader->readPacket(packet);
+ } while (status == kSrsPixelsLeft);
+ _yerror += _sprite->ydelta - 100;
+ }
+ if (status == kSrsEndOfSprite)
+ return kSrsEndOfSprite;
+ _scalerStatus = 1;
+ }
+ if (_scalerStatus == 1) {
+ status = _reader->readPacket(packet);
+ byte updcount = packet.count;
+ while (updcount--) {
+ _xerror -= 100;
+ if (_xerror <= 0) {
+ if (packet.count > 0)
+ packet.count--;
+ _xerror += _sprite->xdelta;
+ }
+ }
+ if (status == kSrsEndOfLine) {
+ if (--_height == 0)
+ return kSrsEndOfSprite;
+ _scalerStatus = 0;
+ return kSrsEndOfLine;
+ }
+ }
+ return kSrsPixelsLeft;
+ }
+protected:
+ SpriteReader *_reader;
+ int16 _xerror, _yerror;
+ int16 _height;
+ int16 _origHeight;
+ int _scalerStatus;
+};
+
+class SpriteFilterScaleUp : public SpriteFilter {
+public:
+ SpriteFilterScaleUp(const SpriteDrawItem &sprite, SpriteReader *reader) : SpriteFilter(sprite), _reader(reader) {
+ _height = _sprite->height;
+ _yerror = _sprite->yerror;
+ _origHeight = _sprite->origHeight;
+ _scalerStatus = 0;
+ }
+ SpriteReaderStatus readPacket(PixelPacket &packet) {
+ SpriteReaderStatus status;
+ if (_scalerStatus == 0) {
+ _xerror = _sprite->xdelta;
+ _sourcep = _reader->getSource();
+ _scalerStatus = 1;
+ }
+ if (_scalerStatus == 1) {
+ status = _reader->readPacket(packet);
+ byte updcount = packet.count;
+ while (updcount--) {
+ _xerror -= 100;
+ if (_xerror <= 0) {
+ packet.count++;
+ _xerror += _sprite->xdelta;
+ }
+ }
+ if (status == kSrsEndOfLine) {
+ if (--_height == 0)
+ return kSrsEndOfSprite;
+ _yerror -= 100;
+ if (_yerror <= 0) {
+ _reader->setSource(_sourcep);
+ _yerror += _sprite->ydelta + 100;
+ }
+ _scalerStatus = 0;
+ return kSrsEndOfLine;
+ }
+ }
+ return kSrsPixelsLeft;
+ }
+protected:
+ SpriteReader *_reader;
+ byte *_sourcep;
+ int16 _xerror, _yerror;
+ int16 _height;
+ int16 _origHeight;
+ int _scalerStatus;
+};
+
+bool Screen::createSpriteDrawItem(const DrawRequest &drawRequest, SpriteDrawItem &sprite) {
+ int16 scaleValueX, scaleValueY;
+ int16 xoffs, yoffs;
+ byte *spriteData;
+ int16 frameNum;
+
+ memset(&sprite, 0, sizeof(SpriteDrawItem));
+
+ if (drawRequest.flags == 0xFFFF)
+ return false;
+
+ frameNum = drawRequest.flags & 0x0FFF;
+
+ sprite.flags = 0;
+ sprite.baseColor = drawRequest.baseColor;
+ sprite.x = drawRequest.x;
+ sprite.y = drawRequest.y;
+ sprite.priority = drawRequest.y;
+ sprite.resIndex = drawRequest.resIndex;
+ sprite.frameNum = frameNum;
+
+ spriteData = _vm->_res->load(drawRequest.resIndex)->data;
+
+ if (drawRequest.flags & 0x1000) {
+ sprite.flags |= 4;
+ }
+
+ if (drawRequest.flags & 0x2000) {
+ sprite.flags |= 0x10;
+ }
+
+ if (drawRequest.flags & 0x4000) {
+ sprite.flags |= 0x40;
+ }
+
+ // First initialize the sprite item with the values from the sprite resource
+
+ SpriteFrameEntry spriteFrameEntry(spriteData + frameNum * 12);
+
+ if (spriteFrameEntry.w == 0 || spriteFrameEntry.h == 0)
+ return false;
+
+ sprite.offset = spriteFrameEntry.offset;
+
+ sprite.width = spriteFrameEntry.w;
+ sprite.height = spriteFrameEntry.h;
+ sprite.origWidth = spriteFrameEntry.w;
+ sprite.origHeight = spriteFrameEntry.h;
+
+ if (drawRequest.flags & 0x1000) {
+ xoffs = spriteFrameEntry.w - spriteFrameEntry.x;
+ } else {
+ xoffs = spriteFrameEntry.x;
+ }
+
+ yoffs = spriteFrameEntry.y;
+
+ // If the sprite should be scaled we need to initialize some values now
+
+ if (drawRequest.scaling != 0) {
+
+ byte scaleValue = ABS(drawRequest.scaling);
+
+ scaleValueX = scaleValue * sprite.origWidth;
+ sprite.xdelta = (10000 * sprite.origWidth) / scaleValueX;
+ scaleValueX /= 100;
+
+ scaleValueY = scaleValue * sprite.origHeight;
+ sprite.ydelta = (10000 * sprite.origHeight) / scaleValueY;
+ scaleValueY /= 100;
+
+ if (drawRequest.scaling > 0) {
+ sprite.flags |= 2;
+ sprite.width = sprite.origWidth + scaleValueX;
+ sprite.height = sprite.origHeight + scaleValueY;
+ xoffs += (xoffs * scaleValue) / 100;
+ yoffs += (yoffs * scaleValue) / 100;
+ } else {
+ sprite.flags |= 1;
+ sprite.width = sprite.origWidth - scaleValueX;
+ sprite.height = sprite.origHeight - 1 - scaleValueY;
+ if (sprite.width <= 0 || sprite.height <= 0)
+ return false;
+ xoffs -= (xoffs * scaleValue) / 100;
+ yoffs -= (yoffs * scaleValue) / 100;
+ }
+
+ }
+
+ sprite.x -= xoffs;
+ sprite.y -= yoffs;
+
+ sprite.yerror = sprite.ydelta;
+
+ // Now we check if the sprite needs to be clipped
+
+ // Clip Y
+ if (sprite.y - _vm->_cameraY < 0) {
+
+ int16 clipHeight = ABS(sprite.y - _vm->_cameraY);
+ int16 skipHeight = clipHeight;
+ byte *spriteFrameData;
+
+ sprite.height -= clipHeight;
+ if (sprite.height <= 0)
+ return false;
+
+ sprite.y = _vm->_cameraY;
+
+ // If the sprite is scaled
+ if (sprite.flags & 3) {
+ int16 chopHeight = sprite.ydelta;
+ if ((sprite.flags & 2) == 0) {
+ do {
+ chopHeight -= 100;
+ if (chopHeight <= 0) {
+ skipHeight++;
+ chopHeight += sprite.ydelta;
+ } else {
+ clipHeight--;
+ }
+ } while (clipHeight > 0);
+ } else {
+ do {
+ chopHeight -= 100;
+ if (chopHeight < 0) {
+ skipHeight--;
+ chopHeight += sprite.ydelta + 100;
+ }
+ clipHeight--;
+ } while (clipHeight > 0);
+ }
+ sprite.yerror = chopHeight;
+ }
+
+ spriteFrameData = spriteData + sprite.offset;
+ // Now the sprite's offset is adjusted to point to the starting line
+ if ((sprite.flags & 0x10) == 0) {
+ while (skipHeight--) {
+ int16 lineWidth = 0;
+ while (lineWidth < sprite.origWidth) {
+ sprite.offset++;
+ lineWidth += spriteFrameData[0] & 0x0F;
+ spriteFrameData++;
+ }
+ }
+ } else {
+ while (skipHeight--) {
+ int16 lineWidth = 0;
+ while (lineWidth < sprite.origWidth) {
+ sprite.offset += 2;
+ lineWidth += spriteFrameData[1];
+ spriteFrameData += 2;
+ }
+ }
+ }
+
+ }
+
+ if (sprite.y + sprite.height - _vm->_cameraY - _vm->_cameraHeight > 0)
+ sprite.height -= sprite.y + sprite.height - _vm->_cameraY - _vm->_cameraHeight;
+ if (sprite.height <= 0)
+ return false;
+
+ sprite.skipX = 0;
+
+ if (drawRequest.flags & 0x1000) {
+ // Left border
+ if (sprite.x - _vm->_cameraX < 0) {
+ sprite.width -= ABS(sprite.x - _vm->_cameraX);
+ sprite.x = _vm->_cameraX;
+ }
+ // Right border
+ if (sprite.x + sprite.width - _vm->_cameraX - 640 > 0) {
+ sprite.flags |= 8;
+ sprite.skipX = sprite.x + sprite.width - _vm->_cameraX - 640;
+ sprite.width -= sprite.skipX;
+ }
+ } else {
+ // Left border
+ if (sprite.x - _vm->_cameraX < 0) {
+ sprite.flags |= 8;
+ sprite.skipX = ABS(sprite.x - _vm->_cameraX);
+ sprite.width -= sprite.skipX;
+ sprite.x = _vm->_cameraX;
+ }
+ // Right border
+ if (sprite.x + sprite.width - _vm->_cameraX - 640 > 0) {
+ sprite.flags |= 8;
+ sprite.width -= sprite.x + sprite.width - _vm->_cameraX - 640;
+ }
+ }
+
+ if (sprite.width <= 0)
+ return false;
+
+ return true;
+}
+
+void Screen::addDrawRequest(const DrawRequest &drawRequest) {
+ SpriteDrawItem sprite;
+ if (createSpriteDrawItem(drawRequest, sprite))
+ _renderQueue->addSprite(sprite);
+}
+
+void Screen::drawSprite(const SpriteDrawItem &sprite) {
+
+ debug(0, "Screen::drawSprite() x = %d; y = %d; flags = %04X; resIndex = %d; offset = %08X; drawX = %d; drawY = %d",
+ sprite.x, sprite.y, sprite.flags, sprite.resIndex, sprite.offset,
+ sprite.x - _vm->_cameraX, sprite.y - _vm->_cameraY);
+ debug(0, "Screen::drawSprite() width = %d; height = %d; origWidth = %d; origHeight = %d",
+ sprite.width, sprite.height, sprite.origWidth, sprite.origHeight);
+
+ byte *source = _vm->_res->load(sprite.resIndex)->data + sprite.offset;
+ byte *dest = _frontScreen + sprite.x + sprite.y * 640;
+
+ SpriteReader spriteReader(source, sprite);
+
+ if (sprite.flags & 0x40) {
+ // Shadow sprites
+ if (sprite.flags & 1) {
+ SpriteFilterScaleDown spriteScaler(sprite, &spriteReader);
+ drawSpriteCore(dest, spriteScaler, sprite);
+ } else if (sprite.flags & 2) {
+ SpriteFilterScaleUp spriteScaler(sprite, &spriteReader);
+ drawSpriteCore(dest, spriteScaler, sprite);
+ } else {
+ drawSpriteCore(dest, spriteReader, sprite);
+ }
+ } else if (sprite.flags & 0x10) {
+ // 256 color sprite
+ drawSpriteCore(dest, spriteReader, sprite);
+ } else {
+ // 16 color sprite
+ if (sprite.flags & 1) {
+ SpriteFilterScaleDown spriteScaler(sprite, &spriteReader);
+ drawSpriteCore(dest, spriteScaler, sprite);
+ } else if (sprite.flags & 2) {
+ SpriteFilterScaleUp spriteScaler(sprite, &spriteReader);
+ drawSpriteCore(dest, spriteScaler, sprite);
+ } else {
+ drawSpriteCore(dest, spriteReader, sprite);
+ }
+ }
+
+ debug(0, "Screen::drawSprite() ok");
+
+}
+
+void Screen::drawSpriteCore(byte *dest, SpriteFilter &reader, const SpriteDrawItem &sprite) {
+
+ int16 destInc;
+
+ if (sprite.flags & 4) {
+ destInc = -1;
+ dest += sprite.width;
+ } else {
+ destInc = 1;
+ }
+
+ SpriteReaderStatus status;
+ PixelPacket packet;
+
+ byte *destp = dest;
+ int16 skipX = sprite.skipX;
+
+ int16 w = sprite.width;
+ int16 h = sprite.height;
+
+ do {
+ status = reader.readPacket(packet);
+
+ if (skipX > 0) {
+ while (skipX > 0) {
+ skipX -= packet.count;
+ if (skipX < 0) {
+ packet.count = ABS(skipX);
+ break;
+ }
+ status = reader.readPacket(packet);
+ }
+ }
+
+ if (w - packet.count < 0)
+ packet.count = w;
+
+ w -= packet.count;
+
+ if (((sprite.flags & 0x40) && (packet.pixel != 0)) ||
+ ((sprite.flags & 0x10) && (packet.pixel != 0xFF)) ||
+ (!(sprite.flags & 0x10) && (packet.pixel != 0)))
+ {
+ if (sprite.flags & 0x40) {
+ while (packet.count--) {
+ *dest = _vm->_palette->getColorTransPixel(*dest);
+ dest += destInc;
+ }
+ } else {
+ if (sprite.flags & 0x10) {
+ packet.pixel = ((packet.pixel << 4) & 0xF0) | ((packet.pixel >> 4) & 0x0F);
+ } else {
+ packet.pixel += sprite.baseColor - 1;
+ }
+ while (packet.count--) {
+ *dest = packet.pixel;
+ dest += destInc;
+ }
+ }
+ } else {
+ dest += packet.count * destInc;
+ }
+
+ if (status == kSrsEndOfLine || w <= 0) {
+ if (w <= 0) {
+ while (status == kSrsPixelsLeft) {
+ status = reader.readPacket(packet);
+ }
+ }
+ dest = destp + 640;
+ destp = dest;
+ skipX = sprite.skipX;
+ w = sprite.width;
+ h--;
+ }
+
+ } while (status != kSrsEndOfSprite && h > 0);
+
+}
+
+} // End of namespace Toltecs
diff --git a/engines/toltecs/toltecs.cpp b/engines/toltecs/toltecs.cpp
new file mode 100644
index 0000000000..d403e0499b
--- /dev/null
+++ b/engines/toltecs/toltecs.cpp
@@ -0,0 +1,641 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ *
+ */
+
+#include "common/config-manager.h"
+#include "common/events.h"
+#include "common/random.h"
+#include "common/str.h"
+#include "common/error.h"
+#include "common/textconsole.h"
+
+#include "base/plugins.h"
+#include "base/version.h"
+
+#include "graphics/cursorman.h"
+
+#include "engines/util.h"
+
+#include "audio/mixer.h"
+
+#include "toltecs/toltecs.h"
+#include "toltecs/animation.h"
+#include "toltecs/menu.h"
+#include "toltecs/movie.h"
+#include "toltecs/music.h"
+#include "toltecs/palette.h"
+#include "toltecs/render.h"
+#include "toltecs/resource.h"
+#include "toltecs/script.h"
+#include "toltecs/screen.h"
+#include "toltecs/segmap.h"
+#include "toltecs/sound.h"
+#include "toltecs/microtiles.h"
+
+namespace Toltecs {
+
+struct GameSettings {
+ const char *gameid;
+ const char *description;
+ byte id;
+ uint32 features;
+ const char *detectname;
+};
+
+ToltecsEngine::ToltecsEngine(OSystem *syst, const ToltecsGameDescription *gameDesc) : Engine(syst), _gameDescription(gameDesc) {
+
+ // Setup mixer
+ _mixer->setVolumeForSoundType(Audio::Mixer::kSFXSoundType, ConfMan.getInt("sfx_volume"));
+ _mixer->setVolumeForSoundType(Audio::Mixer::kMusicSoundType, ConfMan.getInt("music_volume"));
+
+ _rnd = new Common::RandomSource("toltecs");
+}
+
+ToltecsEngine::~ToltecsEngine() {
+ delete _rnd;
+}
+
+Common::Error ToltecsEngine::run() {
+ initGraphics(640, 400, true);
+
+ _isSaveAllowed = true;
+
+ _counter01 = 0;
+ _counter02 = 0;
+ _movieSceneFlag = false;
+ _flag01 = 0;
+
+ _saveLoadRequested = 0;
+
+ _cameraX = 0;
+ _cameraY = 0;
+ _newCameraX = 0;
+ _newCameraY = 0;
+ _cameraHeight = 0;
+
+ _guiHeight = 26;
+
+ _sceneWidth = 0;
+ _sceneHeight = 0;
+
+ _doSpeech = true;
+ _doText = true;
+
+ _walkSpeedY = 5;
+ _walkSpeedX = 1;
+
+ _mouseX = 0;
+ _mouseY = 0;
+ _mouseDblClickTicks = 60;
+ _mouseWaitForRelease = false;
+ _mouseButton = 0;
+ _mouseDisabled = 0;
+ _leftButtonDown = false;
+ _rightButtonDown = false;
+
+ _arc = new ArchiveReader();
+ _arc->openArchive("WESTERN");
+
+ _res = new ResourceCache(this);
+
+ _screen = new Screen(this);
+
+ _script = new ScriptInterpreter(this);
+ _anim = new AnimationPlayer(this);
+ _palette = new Palette(this);
+ _segmap = new SegmentMap(this);
+ _moviePlayer = new MoviePlayer(this);
+ _music = new Music(_arc);
+ _menuSystem = new MenuSystem(this);
+
+ _sound = new Sound(this);
+
+ syncSoundSettings();
+
+ CursorMan.showMouse(true);
+
+ setupSysStrings();
+
+//#define TEST_MENU
+#ifdef TEST_MENU
+ _screen->registerFont(0, 0x0D);
+ _screen->registerFont(1, 0x0E);
+ _screen->loadMouseCursor(12);
+ _palette->loadAddPalette(9, 224);
+ _palette->setDeltaPalette(_palette->getMainPalette(), 7, 0, 31, 224);
+ _screen->finishTalkTextItems();
+ _screen->clearSprites();
+ _menuSystem->run();
+ /*
+ while (1) {
+ //updateInput();
+ _menuSystem->update();
+ updateScreen();
+ }
+ */
+ return Common::kNoError;
+#endif
+
+ // Start main game loop
+ setTotalPlayTime(0);
+ _script->loadScript(0, 0);
+ _script->setMainScript(0);
+ if (ConfMan.hasKey("save_slot")) {
+ int saveSlot = ConfMan.getInt("save_slot");
+ if (saveSlot >= 0 && saveSlot <= 99) {
+ _screen->loadMouseCursor(12);
+ loadGameState(saveSlot);
+ }
+ }
+ _script->runScript();
+
+ _music->stopSequence();
+ _sound->stopAll();
+
+ delete _arc;
+ delete _res;
+ delete _screen;
+ delete _script;
+ delete _anim;
+ delete _palette;
+ delete _segmap;
+ delete _music;
+ delete _moviePlayer;
+ delete _menuSystem;
+
+ delete _sound;
+
+ return Common::kNoError;
+}
+
+void ToltecsEngine::setupSysStrings() {
+ Resource *sysStringsResource = _res->load(15);
+ const char *sysStrings = (const char*)sysStringsResource->data;
+ for (int i = 0; i < kSysStrCount; i++) {
+ debug(1, "sysStrings[%d] = [%s]", i, sysStrings);
+ _sysStrings[i] = sysStrings;
+ sysStrings += strlen(sysStrings) + 1;
+ }
+ // TODO: Set yes/no chars
+}
+
+void ToltecsEngine::requestSavegame(int slotNum, Common::String &description) {
+ _saveLoadRequested = 2;
+ _saveLoadSlot = slotNum;
+ _saveLoadDescription = description;
+}
+
+void ToltecsEngine::requestLoadgame(int slotNum) {
+ _saveLoadRequested = 1;
+ _saveLoadSlot = slotNum;
+}
+
+void ToltecsEngine::loadScene(uint resIndex) {
+
+ Resource *sceneResource = _res->load(resIndex);
+ byte *scene = sceneResource->data;
+
+ uint32 imageSize = READ_LE_UINT32(scene);
+ _sceneResIndex = resIndex;
+ _sceneHeight = READ_LE_UINT16(scene + 4);
+ _sceneWidth = READ_LE_UINT16(scene + 6);
+
+ // Load scene palette
+ _palette->loadAddPaletteFrom(scene + 8, 0, 128);
+
+ // Load scene background
+ byte *source = scene + 392;
+ byte *destp = _screen->_backScreen;
+ byte *destEnd = destp + _sceneWidth * _sceneHeight;
+ while (destp < destEnd) {
+ int count = 1;
+ byte pixel = *source++;
+ if (pixel & 0x80) {
+ pixel &= 0x7F;
+ count = *source++;
+ count += 2;
+ }
+ memset(destp, pixel, count);
+ destp += count;
+ }
+
+ debug(0, "_sceneWidth = %d; _sceneHeight = %d", _sceneWidth, _sceneHeight);
+
+ // Load scene segmap
+ _segmap->load(scene + imageSize + 4);
+
+ _screen->_fullRefresh = true;
+ _screen->_renderQueue->clear();
+
+}
+
+void ToltecsEngine::updateScreen() {
+
+ _sound->updateSpeech();
+
+ _screen->updateShakeScreen();
+
+ // TODO: Set quit flag
+ if (shouldQuit())
+ return;
+
+ if (!_movieSceneFlag)
+ updateInput();
+ else
+ _mouseButton = 0;
+
+ // TODO? Check keyb
+
+ _counter01--;
+ if (_counter01 <= 0) {
+ _counter01 = MIN(_counter02, 30);
+ _counter02 = 0;
+ drawScreen();
+ _flag01 = 1;
+ _counter02 = 1;
+ } else {
+ _screen->clearSprites();
+ _flag01 = 0;
+ }
+
+ static uint32 prevUpdateTime = 0;
+ uint32 currUpdateTime;
+ do {
+ currUpdateTime = _system->getMillis();
+ _counter02 = (currUpdateTime - prevUpdateTime) / 13;
+ } while (_counter02 == 0);
+ prevUpdateTime = currUpdateTime;
+
+}
+
+void ToltecsEngine::drawScreen() {
+ // FIXME: Quick hack, sometimes cameraY was negative (the code in updateCamera was at fault)
+ if (_cameraY < 0) _cameraY = 0;
+
+ _segmap->addMasksToRenderQueue();
+ _screen->addTalkTextItemsToRenderQueue();
+
+ _screen->_renderQueue->update();
+
+ //debug("_guiHeight = %d\n", _guiHeight);
+
+ if (_screen->_guiRefresh && _guiHeight > 0 && _cameraHeight > 0) {
+ // Update the GUI when needed and it's visible
+ _system->copyRectToScreen((const byte *)_screen->_frontScreen + _cameraHeight * 640,
+ 640, 0, _cameraHeight, 640, _guiHeight);
+ _screen->_guiRefresh = false;
+ }
+
+ _system->updateScreen();
+
+ updateCamera();
+}
+
+void ToltecsEngine::updateInput() {
+
+ Common::Event event;
+ Common::EventManager *eventMan = _system->getEventManager();
+ while (eventMan->pollEvent(event)) {
+ switch (event.type) {
+ case Common::EVENT_KEYDOWN:
+ _keyState = event.kbd;
+
+ //debug("key: flags = %02X; keycode = %d", _keyState.flags, _keyState.keycode);
+
+ // FIXME: This is just for debugging
+ switch (event.kbd.keycode) {
+ case Common::KEYCODE_F7:
+ savegame("toltecs.001", "Quicksave");
+ break;
+ case Common::KEYCODE_F9:
+ loadgame("toltecs.001");
+ break;
+ case Common::KEYCODE_ESCAPE:
+ // Skip current dialog line, if a dialog is active
+ if (_screen->getTalkTextDuration() > 0) {
+ _sound->stopSpeech();
+ _screen->finishTalkTextItems();
+ _keyState.reset(); // event consumed
+ }
+ break;
+ default:
+ break;
+ }
+
+ break;
+ case Common::EVENT_KEYUP:
+ _keyState.reset();
+ break;
+ case Common::EVENT_QUIT:
+ quitGame();
+ break;
+ case Common::EVENT_MOUSEMOVE:
+ _mouseX = event.mouse.x;
+ _mouseY = event.mouse.y;
+ break;
+ case Common::EVENT_LBUTTONDOWN:
+ _mouseX = event.mouse.x;
+ _mouseY = event.mouse.y;
+ _leftButtonDown = true;
+ break;
+ case Common::EVENT_LBUTTONUP:
+ _mouseX = event.mouse.x;
+ _mouseY = event.mouse.y;
+ _leftButtonDown = false;
+ break;
+ case Common::EVENT_RBUTTONDOWN:
+ _mouseX = event.mouse.x;
+ _mouseY = event.mouse.y;
+ _rightButtonDown = true;
+ break;
+ case Common::EVENT_RBUTTONUP:
+ _mouseX = event.mouse.x;
+ _mouseY = event.mouse.y;
+ _rightButtonDown = false;
+ break;
+ default:
+ break;
+ }
+ }
+
+ if (!_mouseDisabled) {
+
+ if (_mouseDblClickTicks > 0)
+ _mouseDblClickTicks--;
+
+ byte mouseButtons = 0;
+ if (_leftButtonDown)
+ mouseButtons |= 1;
+ if (_rightButtonDown)
+ mouseButtons |= 2;
+
+ if (mouseButtons != 0) {
+ if (!_mouseWaitForRelease) {
+ _mouseButton = mouseButtons;
+ if (_mouseDblClickTicks > 0)
+ _mouseButton = 0x80;
+ //if (_mouseButton == 0x80) debug("DBL!");
+ _mouseDblClickTicks = 30; // maybe TODO
+ _mouseWaitForRelease = true;
+ } else {
+ _mouseButton = 0;
+ }
+ } else {
+ _mouseWaitForRelease = false;
+ _mouseButton = 0;
+ }
+
+ }
+
+}
+
+void ToltecsEngine::setGuiHeight(int16 guiHeight) {
+ if (guiHeight != _guiHeight) {
+ _guiHeight = guiHeight;
+ _cameraHeight = 400 - _guiHeight;
+ _screen->_guiRefresh = true;
+ debug(0, "ToltecsEngine::setGuiHeight() _guiHeight = %d; _cameraHeight = %d", _guiHeight, _cameraHeight);
+ // TODO: clearScreen();
+ }
+}
+
+void ToltecsEngine::setCamera(int16 x, int16 y) {
+ _screen->finishTalkTextItems();
+
+ _screen->clearSprites();
+
+ _cameraX = x;
+ _newCameraX = x;
+
+ _cameraY = y;
+ _newCameraY = y;
+}
+
+bool ToltecsEngine::getCameraChanged() {
+ return _cameraX != _newCameraX || _cameraY != _newCameraY;
+}
+
+void ToltecsEngine::scrollCameraUp(int16 delta) {
+ if (_newCameraY > 0) {
+ if (_newCameraY < delta)
+ _newCameraY = 0;
+ else
+ _newCameraY -= delta;
+ }
+}
+
+void ToltecsEngine::scrollCameraDown(int16 delta) {
+ debug(0, "ToltecsEngine::scrollCameraDown(%d)", delta);
+ if (_newCameraY != _sceneHeight - _cameraHeight) {
+ if (_sceneHeight - _cameraHeight < _newCameraY + delta)
+ delta += (_sceneHeight - _cameraHeight) - (delta + _newCameraY);
+ _newCameraY += delta;
+ debug(0, "ToltecsEngine::scrollCameraDown() _newCameraY = %d; delta = %d", _newCameraY, delta);
+ }
+}
+
+void ToltecsEngine::scrollCameraLeft(int16 delta) {
+ if (_newCameraX > 0) {
+ if (_newCameraX < delta)
+ _newCameraX = 0;
+ else
+ _newCameraX -= delta;
+ }
+}
+
+void ToltecsEngine::scrollCameraRight(int16 delta) {
+ debug(0, "ToltecsEngine::scrollCameraRight(%d)", delta);
+ if (_newCameraX != _sceneWidth - 640) {
+ if (_sceneWidth - 640 < delta + _newCameraX)
+ delta += (_sceneWidth - 640) - (delta + _newCameraX);
+ _newCameraX += delta;
+ debug(0, "ToltecsEngine::scrollCameraRight() _newCameraX = %d; delta = %d", _newCameraY, delta);
+ }
+}
+
+void ToltecsEngine::updateCamera() {
+
+ if (_cameraX != _newCameraX) {
+ _cameraX = _newCameraX;
+ _screen->_fullRefresh = true;
+ _screen->finishTalkTextItems();
+ }
+
+ if (_cameraY != _newCameraY) {
+ _cameraY = _newCameraY;
+ _screen->_fullRefresh = true;
+ _screen->finishTalkTextItems();
+ }
+
+ //debug(0, "ToltecsEngine::updateCamera() _cameraX = %d; _cameraY = %d", _cameraX, _cameraY);
+
+}
+
+void ToltecsEngine::talk(int16 slotIndex, int16 slotOffset) {
+
+ byte *scanData = _script->getSlotData(slotIndex) + slotOffset;
+
+ while (*scanData < 0xF0) {
+ if (*scanData == 0x19) {
+ scanData++;
+ } else if (*scanData == 0x14) {
+ scanData++;
+ } else if (*scanData == 0x0A) {
+ scanData += 4;
+ } else if (*scanData < 0x0A) {
+ scanData++;
+ }
+ scanData++;
+ }
+
+ if (*scanData == 0xFE) {
+ if (_doSpeech) {
+ int16 resIndex = READ_LE_UINT16(scanData + 1);
+ debug(0, "ToltecsEngine::talk() playSound(resIndex: %d)", resIndex);
+ _sound->playSpeech(resIndex);
+ }
+ if (_doText) {
+ _screen->updateTalkText(slotIndex, slotOffset);
+ } else {
+ _screen->keepTalkTextItemsAlive();
+ }
+ } else {
+ _screen->updateTalkText(slotIndex, slotOffset);
+ }
+
+}
+
+void ToltecsEngine::walk(byte *walkData) {
+
+ int16 xdelta, ydelta, v8, v10, v11;
+ int16 xstep, ystep;
+ ScriptWalk walkInfo;
+
+ walkInfo.y = READ_LE_UINT16(walkData + 0);
+ walkInfo.x = READ_LE_UINT16(walkData + 2);
+ walkInfo.y1 = READ_LE_UINT16(walkData + 4);
+ walkInfo.x1 = READ_LE_UINT16(walkData + 6);
+ walkInfo.y2 = READ_LE_UINT16(walkData + 8);
+ walkInfo.x2 = READ_LE_UINT16(walkData + 10);
+ walkInfo.yerror = READ_LE_UINT16(walkData + 12);
+ walkInfo.xerror = READ_LE_UINT16(walkData + 14);
+ walkInfo.mulValue = READ_LE_UINT16(walkData + 16);
+ walkInfo.scaling = READ_LE_UINT16(walkData + 18);
+
+ walkInfo.scaling = -_segmap->getScalingAtPoint(walkInfo.x, walkInfo.y);
+
+ if (walkInfo.y1 < walkInfo.y2)
+ ystep = -1;
+ else
+ ystep = 1;
+ ydelta = ABS(walkInfo.y1 - walkInfo.y2) * _walkSpeedY;
+
+ if (walkInfo.x1 < walkInfo.x2)
+ xstep = -1;
+ else
+ xstep = 1;
+ xdelta = ABS(walkInfo.x1 - walkInfo.x2) * _walkSpeedX;
+
+ debug(0, "ToltecsEngine::walk() xdelta = %d; ydelta = %d", xdelta, ydelta);
+
+ if (xdelta > ydelta)
+ SWAP(xdelta, ydelta);
+
+ v8 = 100 * xdelta;
+ if (v8 != 0) {
+ if (walkInfo.scaling > 0)
+ v8 -= v8 * ABS(walkInfo.scaling) / 100;
+ else
+ v8 += v8 * ABS(walkInfo.scaling) / 100;
+ if (ydelta != 0)
+ v8 /= ydelta;
+ }
+
+ if (ydelta > ABS(walkInfo.x1 - walkInfo.x2) * _walkSpeedX) {
+ v10 = 100 - walkInfo.scaling;
+ v11 = v8;
+ } else {
+ v10 = v8;
+ v11 = 100 - walkInfo.scaling;
+ }
+
+ walkInfo.yerror += walkInfo.mulValue * v10;
+ while (walkInfo.yerror >= 100 * _walkSpeedY) {
+ walkInfo.yerror -= 100 * _walkSpeedY;
+ if (walkInfo.y == walkInfo.y1) {
+ walkInfo.x = walkInfo.x1;
+ break;
+ }
+ walkInfo.y += ystep;
+ }
+
+ walkInfo.xerror += walkInfo.mulValue * v11;
+ while (walkInfo.xerror >= 100 * _walkSpeedX) {
+ walkInfo.xerror -= 100 * _walkSpeedX;
+ if (walkInfo.x == walkInfo.x1) {
+ walkInfo.y = walkInfo.y1;
+ break;
+ }
+ walkInfo.x += xstep;
+ }
+
+ WRITE_LE_UINT16(walkData + 0, walkInfo.y);
+ WRITE_LE_UINT16(walkData + 2, walkInfo.x);
+ WRITE_LE_UINT16(walkData + 4, walkInfo.y1);
+ WRITE_LE_UINT16(walkData + 6, walkInfo.x1);
+ WRITE_LE_UINT16(walkData + 8, walkInfo.y2);
+ WRITE_LE_UINT16(walkData + 10, walkInfo.x2);
+ WRITE_LE_UINT16(walkData + 12, walkInfo.yerror);
+ WRITE_LE_UINT16(walkData + 14, walkInfo.xerror);
+ WRITE_LE_UINT16(walkData + 16, walkInfo.mulValue);
+ WRITE_LE_UINT16(walkData + 18, walkInfo.scaling);
+
+}
+
+int16 ToltecsEngine::findRectAtPoint(byte *rectData, int16 x, int16 y, int16 index, int16 itemSize,
+ byte *rectDataEnd) {
+
+ rectData += index * itemSize;
+
+ while (rectData < rectDataEnd) {
+ int16 rectY = READ_LE_UINT16(rectData);
+ if (rectY == -10)
+ break;
+ int16 rectX = READ_LE_UINT16(rectData + 2);
+ int16 rectH = READ_LE_UINT16(rectData + 4);
+ int16 rectW = READ_LE_UINT16(rectData + 6);
+
+ debug(0, "x = %d; y = %d; x1 = %d; y2 = %d; w = %d; h = %d",
+ x, y, rectX, rectY, rectW, rectH);
+
+ if (x >= rectX && x <= rectX + rectW && y >= rectY && y <= rectY + rectH) {
+ return index;
+ }
+ index++;
+ rectData += itemSize;
+ }
+
+ return -1;
+
+}
+
+} // End of namespace Toltecs
diff --git a/engines/toltecs/toltecs.h b/engines/toltecs/toltecs.h
new file mode 100644
index 0000000000..efa1f9d13a
--- /dev/null
+++ b/engines/toltecs/toltecs.h
@@ -0,0 +1,215 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public 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 TOLTECS_H
+#define TOLTECS_H
+
+#include "common/scummsys.h"
+#include "common/endian.h"
+#include "common/events.h"
+#include "common/file.h"
+#include "common/keyboard.h"
+#include "common/random.h"
+#include "common/textconsole.h"
+
+#include "engines/engine.h"
+
+#include "graphics/surface.h"
+
+namespace Toltecs {
+
+struct ToltecsGameDescription;
+
+class AnimationPlayer;
+class ArchiveReader;
+class Input;
+class MenuSystem;
+class MoviePlayer;
+class Music;
+class Palette;
+class ResourceCache;
+class ScriptInterpreter;
+class Screen;
+class SegmentMap;
+class Sound;
+
+enum SysString {
+ kStrLoadingPleaseWait,
+ kStrWhatCanIDoForYou,
+ kStrLoad,
+ kStrSave,
+ kStrTextOn,
+ kStrTextOff,
+ kStrVoicesOn,
+ kStrVoicesOff,
+ kStrVolume,
+ kStrPlay,
+ kStrQuit,
+ kStrLoadGame,
+ kStrSaveGame,
+ kStrAdjustVolume,
+ kStrMaster,
+ kStrVoices,
+ kStrMusic,
+ kStrSoundFx,
+ kStrBackground,
+ kStrCancel,
+ kStrDone,
+ kStrAreYouSure,
+ kStrYes,
+ kStrNo,
+ kSysStrCount
+};
+
+class ToltecsEngine : public ::Engine {
+ Common::KeyState _keyPressed;
+
+protected:
+ Common::Error run();
+// void shutdown();
+
+public:
+ ToltecsEngine(OSystem *syst, const ToltecsGameDescription *gameDesc);
+ virtual ~ToltecsEngine();
+
+ virtual bool hasFeature(EngineFeature f) const;
+
+ Common::RandomSource *_rnd;
+ const ToltecsGameDescription *_gameDescription;
+ uint32 getFeatures() const;
+ Common::Language getLanguage() const;
+ const Common::String& getTargetName() const { return _targetName; }
+
+ void setupSysStrings();
+ void requestSavegame(int slotNum, Common::String &description);
+ void requestLoadgame(int slotNum);
+
+ void loadScene(uint resIndex);
+
+ void updateScreen();
+ void drawScreen();
+ void updateInput();
+
+ void setGuiHeight(int16 guiHeight);
+
+ void setCamera(int16 x, int16 y);
+ bool getCameraChanged();
+ void scrollCameraUp(int16 delta);
+ void scrollCameraDown(int16 delta);
+ void scrollCameraLeft(int16 delta);
+ void scrollCameraRight(int16 delta);
+ void updateCamera();
+
+ void talk(int16 slotIndex, int16 slotOffset);
+
+ void walk(byte *walkData);
+
+ int16 findRectAtPoint(byte *rectData, int16 x, int16 y, int16 index, int16 itemSize,
+ byte *rectDataEnd);
+
+public:
+
+ AnimationPlayer *_anim;
+ ArchiveReader *_arc;
+ Input *_input;
+ MenuSystem *_menuSystem;
+ MoviePlayer *_moviePlayer;
+ Music *_music;
+ Palette *_palette;
+ ResourceCache *_res;
+ ScriptInterpreter *_script;
+ Screen *_screen;
+ SegmentMap *_segmap;
+ Sound *_sound;
+
+ Common::String _sysStrings[kSysStrCount];
+
+ int _saveLoadRequested;
+ int _saveLoadSlot;
+ Common::String _saveLoadDescription;
+
+ uint _sceneResIndex;
+ int16 _sceneWidth, _sceneHeight;
+
+ int _counter01, _counter02;
+ bool _movieSceneFlag;
+ byte _flag01;
+
+ int16 _cameraX, _cameraY;
+ int16 _newCameraX, _newCameraY;
+ int16 _cameraHeight;
+ int16 _guiHeight;
+
+ bool _doSpeech, _doText;
+
+ int16 _walkSpeedY, _walkSpeedX;
+
+ Common::KeyState _keyState;
+ int16 _mouseX, _mouseY;
+ int16 _mouseDblClickTicks;
+ bool _mouseWaitForRelease;
+ byte _mouseButton;
+ int16 _mouseDisabled;
+ bool _leftButtonDown, _rightButtonDown;
+
+ const char *getSysString(int index) const { return _sysStrings[index].c_str(); }
+
+ /* Save/load */
+
+ enum kReadSaveHeaderError {
+ kRSHENoError = 0,
+ kRSHEInvalidType = 1,
+ kRSHEInvalidVersion = 2,
+ kRSHEIoError = 3
+ };
+
+ struct SaveHeader {
+ Common::String description;
+ uint32 version;
+ byte gameID;
+ uint32 flags;
+ uint32 saveDate;
+ uint32 saveTime;
+ uint32 playTime;
+ Graphics::Surface *thumbnail;
+ };
+
+ bool _isSaveAllowed;
+
+ bool canLoadGameStateCurrently() { return _isSaveAllowed; }
+ bool canSaveGameStateCurrently() { return _isSaveAllowed; }
+ Common::Error loadGameState(int slot);
+ Common::Error saveGameState(int slot, const Common::String &description);
+ void savegame(const char *filename, const char *description);
+ void loadgame(const char *filename);
+
+ const char *getSavegameFilename(int num);
+ static Common::String getSavegameFilename(const Common::String &target, int num);
+
+ static kReadSaveHeaderError readSaveHeader(Common::SeekableReadStream *in, bool loadThumbnail, SaveHeader &header);
+
+};
+
+} // End of namespace Toltecs
+
+#endif /* TOLTECS_H */
diff --git a/engines/toon/anim.cpp b/engines/toon/anim.cpp
index a529001af5..98c667c303 100644
--- a/engines/toon/anim.cpp
+++ b/engines/toon/anim.cpp
@@ -29,7 +29,7 @@
namespace Toon {
-bool Animation::loadAnimation(Common::String file) {
+bool Animation::loadAnimation(const Common::String &file) {
debugC(1, kDebugAnim, "loadAnimation(%s)", file.c_str());
uint32 fileSize = 0;
diff --git a/engines/toon/anim.h b/engines/toon/anim.h
index 4b95b6cf40..eb8dcbd600 100644
--- a/engines/toon/anim.h
+++ b/engines/toon/anim.h
@@ -60,7 +60,7 @@ public:
int32 _paletteEntries;
char _name[32];
- bool loadAnimation(Common::String file);
+ bool loadAnimation(const Common::String &file);
void drawFrame(Graphics::Surface &surface, int32 frame, int32 x, int32 y);
void drawFontFrame(Graphics::Surface &surface, int32 frame, int32 x, int32 y, byte *colorMap);
void drawFrameOnPicture(int32 frame, int32 x, int32 y);
diff --git a/engines/toon/audio.cpp b/engines/toon/audio.cpp
index 5b2d06b74d..77822ab078 100644
--- a/engines/toon/audio.cpp
+++ b/engines/toon/audio.cpp
@@ -84,7 +84,7 @@ void AudioManager::removeInstance(AudioStreamInstance *inst) {
}
}
-void AudioManager::playMusic(Common::String dir, Common::String music) {
+void AudioManager::playMusic(const Common::String &dir, const Common::String &music) {
debugC(1, kDebugAudio, "playMusic(%s, %s)", dir.c_str(), music.c_str());
// two musics can be played at same time
@@ -199,7 +199,7 @@ void AudioManager::closeAudioPack(int32 id) {
_audioPacks[id] = NULL;
}
-bool AudioManager::loadAudioPack(int32 id, Common::String indexFile, Common::String packFile) {
+bool AudioManager::loadAudioPack(int32 id, const Common::String &indexFile, const Common::String &packFile) {
debugC(4, kDebugAudio, "loadAudioPack(%d, %s, %s)", id, indexFile.c_str(), packFile.c_str());
closeAudioPack(id);
@@ -481,7 +481,7 @@ AudioStreamPackage::~AudioStreamPackage() {
delete _file;
}
-bool AudioStreamPackage::loadAudioPackage(Common::String indexFile, Common::String streamFile) {
+bool AudioStreamPackage::loadAudioPackage(const Common::String &indexFile, const Common::String &streamFile) {
debugC(4, kDebugAudio, "loadAudioPackage(%s, %s)", indexFile.c_str(), streamFile.c_str());
uint32 size = 0;
@@ -514,7 +514,7 @@ Common::SeekableReadStream *AudioStreamPackage::getStream(int32 id, bool ownMemo
int32 size = 0;
getInfo(id, &offset, &size);
if (ownMemory) {
- byte *memory = (byte*)malloc(size);
+ byte *memory = (byte *)malloc(size);
_file->seek(offset);
_file->read(memory, size);
return new Common::MemoryReadStream(memory, size, DisposeAfterUse::YES);
diff --git a/engines/toon/audio.h b/engines/toon/audio.h
index 61a534265e..25063603eb 100644
--- a/engines/toon/audio.h
+++ b/engines/toon/audio.h
@@ -103,7 +103,7 @@ public:
AudioStreamPackage(ToonEngine *vm);
~AudioStreamPackage();
- bool loadAudioPackage(Common::String indexFile, Common::String streamFile);
+ bool loadAudioPackage(const Common::String &indexFile, const Common::String &streamFile);
void getInfo(int32 id, int32 *offset, int32 *size);
Common::SeekableReadStream *getStream(int32 id, bool ownMemory = false);
protected:
@@ -131,7 +131,7 @@ public:
bool voiceStillPlaying();
- void playMusic(Common::String dir, Common::String music);
+ void playMusic(const Common::String &dir, const Common::String &music);
void playVoice(int32 id, bool genericVoice);
int32 playSFX(int32 id, int volume, bool genericSFX);
void stopCurrentVoice();
@@ -152,7 +152,7 @@ public:
void setAmbientSFXVolume(int32 id, int volume);
void closeAudioPack(int32 id);
- bool loadAudioPack(int32 id, Common::String indexFile, Common::String packFile);
+ bool loadAudioPack(int32 id, const Common::String &indexFile, const Common::String &packFile);
AudioStreamInstance *_channels[16]; // 0-1 : music
// 2 : voice
diff --git a/engines/toon/character.cpp b/engines/toon/character.cpp
index 7d9a31c170..0e5189957b 100644
--- a/engines/toon/character.cpp
+++ b/engines/toon/character.cpp
@@ -292,21 +292,21 @@ int32 Character::getFacing() {
return _facing;
}
-bool Character::loadWalkAnimation(Common::String animName) {
+bool Character::loadWalkAnimation(const Common::String &animName) {
debugC(1, kDebugCharacter, "loadWalkAnimation(%s)", animName.c_str());
delete _walkAnim;
_walkAnim = new Animation(_vm);
return _walkAnim->loadAnimation(animName);
}
-bool Character::loadIdleAnimation(Common::String animName) {
+bool Character::loadIdleAnimation(const Common::String &animName) {
debugC(1, kDebugCharacter, "loadIdleAnimation(%s)", animName.c_str());
delete _idleAnim;
_idleAnim = new Animation(_vm);
return _idleAnim->loadAnimation(animName);
}
-bool Character::loadTalkAnimation(Common::String animName) {
+bool Character::loadTalkAnimation(const Common::String &animName) {
debugC(1, kDebugCharacter, "loadTalkAnimation(%s)", animName.c_str());
delete _talkAnim;
_talkAnim = new Animation(_vm);
@@ -977,7 +977,7 @@ const SpecialCharacterAnimation *Character::getSpecialAnimation(int32 characterI
return &anims[characterAnims[characterId] + animationId];
}
-bool Character::loadShadowAnimation(Common::String animName) {
+bool Character::loadShadowAnimation(const Common::String &animName) {
debugC(1, kDebugCharacter, "loadShadowAnimation(%s)", animName.c_str());
delete _shadowAnim;
@@ -997,7 +997,7 @@ bool Character::loadShadowAnimation(Common::String animName) {
void Character::plotPath(Graphics::Surface& surface) {
for (int i = 0; i < _currentPathNodeCount; i++) {
- *(byte*)surface.getBasePtr(_currentPathX[i], _currentPathY[i]) = ( i < _currentPathNode);
+ *(byte *)surface.getBasePtr(_currentPathX[i], _currentPathY[i]) = ( i < _currentPathNode);
}
}
diff --git a/engines/toon/character.h b/engines/toon/character.h
index b48991732c..d06a6c060c 100644
--- a/engines/toon/character.h
+++ b/engines/toon/character.h
@@ -74,10 +74,10 @@ public:
virtual bool walkTo(int32 newPosX, int32 newPosY);
virtual bool getVisible();
virtual void setVisible(bool visible);
- virtual bool loadWalkAnimation(Common::String animName);
- virtual bool loadIdleAnimation(Common::String animName);
- virtual bool loadTalkAnimation(Common::String animName);
- virtual bool loadShadowAnimation(Common::String animName);
+ virtual bool loadWalkAnimation(const Common::String &animName);
+ virtual bool loadIdleAnimation(const Common::String &animName);
+ virtual bool loadTalkAnimation(const Common::String &animName);
+ virtual bool loadShadowAnimation(const Common::String &animName);
virtual bool setupPalette();
virtual void playStandingAnim();
virtual void playWalkAnim(int32 start, int32 end);
@@ -96,7 +96,7 @@ public:
virtual void updateTimers(int32 relativeAdd);
virtual void setTalking(bool talking) { _isTalking = talking; }
virtual bool isTalking() { return _isTalking; }
- virtual void resetScale() { };
+ virtual void resetScale() {}
virtual void plotPath(Graphics::Surface& surface);
int32 getFacingFromDirection(int32 dx, int32 dy);
diff --git a/engines/toon/detection.cpp b/engines/toon/detection.cpp
index 2afcb589b7..8234934972 100644
--- a/engines/toon/detection.cpp
+++ b/engines/toon/detection.cpp
@@ -44,7 +44,7 @@ static const ADGameDescription gameDescriptions[] = {
{"study.svl", 0, "281efa3f33f6712c0f641a605f4d40fd", 2511090},
AD_LISTEND
},
- Common::EN_ANY, Common::kPlatformPC, ADGF_NO_FLAGS, GUIO1(GUIO_NONE)
+ Common::EN_ANY, Common::kPlatformPC, ADGF_NO_FLAGS, GUIO0()
},
{
"toon", "",
@@ -54,7 +54,7 @@ static const ADGameDescription gameDescriptions[] = {
{"study.svl", 0, "df056b94ea83f1ed92a539cf636053ab", 2542668},
AD_LISTEND
},
- Common::FR_FRA, Common::kPlatformPC, ADGF_NO_FLAGS, GUIO1(GUIO_NONE)
+ Common::FR_FRA, Common::kPlatformPC, ADGF_NO_FLAGS, GUIO0()
},
{
"toon", "",
@@ -64,7 +64,7 @@ static const ADGameDescription gameDescriptions[] = {
{"study.svl", 0, "72fe96a9e10967d3138e918295babc42", 2910283},
AD_LISTEND
},
- Common::DE_DEU, Common::kPlatformPC, ADGF_NO_FLAGS, GUIO1(GUIO_NONE)
+ Common::DE_DEU, Common::kPlatformPC, ADGF_NO_FLAGS, GUIO0()
},
{
"toon", "",
@@ -74,17 +74,26 @@ static const ADGameDescription gameDescriptions[] = {
{"study.svl", 0, "b6b1ee2d9d94d53d305856039ab7bde7", 2634620},
AD_LISTEND
},
- Common::ES_ESP, Common::kPlatformPC, ADGF_NO_FLAGS, GUIO1(GUIO_NONE)
+ Common::ES_ESP, Common::kPlatformPC, ADGF_NO_FLAGS, GUIO0()
},
{
"toon", "",
{
+ {"local.pak", 0, "48ec60709bebbdeff791d55ee18ec910", 3417846},
+ {"arcaddbl.svl", 0, "1d1b96e317e03ffd3874a8ebe59556f3", 6246232},
+ {"study.svl", 0, "d4aff126ee27be3c3d25e2996369d7cb", 2324368},
+ },
+ Common::RU_RUS, Common::kPlatformPC, ADGF_NO_FLAGS, GUIO0()
+ },
+ {
+ "toon", "",
+ {
{"local.pak", 0, "bf5da4c03f78ffbd643f12122319366e", 3250841},
{"wacexdbl.emc", 0, "cfbc2156a31b294b038204888407ebc8", 6974},
{"generic.svl", 0, "5eb99850ada22f0b8cf6392262d4dd07", 9404599},
AD_LISTEND
},
- Common::DE_DEU, Common::kPlatformPC, ADGF_DEMO, GUIO1(GUIO_NONE)
+ Common::DE_DEU, Common::kPlatformPC, ADGF_DEMO, GUIO0()
},
{
"toon", "",
@@ -93,7 +102,7 @@ static const ADGameDescription gameDescriptions[] = {
{"generic.svl", 0, "5c42724bb93b360dca7044d6b7ef26e5", 7739319},
AD_LISTEND
},
- Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO1(GUIO_NONE)
+ Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO0()
},
AD_TABLE_END_MARKER
diff --git a/engines/toon/font.cpp b/engines/toon/font.cpp
index 63304c905f..d58663a00c 100644
--- a/engines/toon/font.cpp
+++ b/engines/toon/font.cpp
@@ -65,7 +65,7 @@ byte FontRenderer::textToFont(byte c) {
return map_textToFont[c - 0x80];
}
-void FontRenderer::renderText(int32 x, int32 y, Common::String origText, int32 mode) {
+void FontRenderer::renderText(int32 x, int32 y, const Common::String &origText, int32 mode) {
debugC(5, kDebugFont, "renderText(%d, %d, %s, %d)", x, y, origText.c_str(), mode);
int32 xx, yy;
@@ -104,7 +104,7 @@ void FontRenderer::renderText(int32 x, int32 y, Common::String origText, int32 m
}
}
-void FontRenderer::computeSize(Common::String origText, int32 *retX, int32 *retY) {
+void FontRenderer::computeSize(const Common::String &origText, int32 *retX, int32 *retY) {
debugC(4, kDebugFont, "computeSize(%s, retX, retY)", origText.c_str());
int32 lineWidth = 0;
@@ -189,7 +189,7 @@ void FontRenderer::setFontColor(int32 fontColor1, int32 fontColor2, int32 fontCo
_currentFontColor[3] = fontColor3;
}
-void FontRenderer::renderMultiLineText(int32 x, int32 y, Common::String origText, int32 mode) {
+void FontRenderer::renderMultiLineText(int32 x, int32 y, const Common::String &origText, int32 mode) {
debugC(5, kDebugFont, "renderMultiLineText(%d, %d, %s, %d)", x, y, origText.c_str(), mode);
// divide the text in several lines
diff --git a/engines/toon/font.h b/engines/toon/font.h
index 168c61f27e..349d9d1ee7 100644
--- a/engines/toon/font.h
+++ b/engines/toon/font.h
@@ -33,9 +33,9 @@ public:
~FontRenderer();
void setFont(Animation *font);
- void computeSize(Common::String origText, int32 *retX, int32 *retY);
- void renderText(int32 x, int32 y, Common::String origText, int32 mode);
- void renderMultiLineText(int32 x, int32 y, Common::String origText, int32 mode);
+ void computeSize(const Common::String &origText, int32 *retX, int32 *retY);
+ void renderText(int32 x, int32 y, const Common::String &origText, int32 mode);
+ void renderMultiLineText(int32 x, int32 y, const Common::String &origText, int32 mode);
void setFontColorByCharacter(int32 characterId);
void setFontColor(int32 fontColor1, int32 fontColor2, int32 fontColor3);
protected:
diff --git a/engines/toon/hotspot.cpp b/engines/toon/hotspot.cpp
index ee81b87417..ce2cdf1bb9 100644
--- a/engines/toon/hotspot.cpp
+++ b/engines/toon/hotspot.cpp
@@ -96,7 +96,7 @@ int32 Hotspots::Find(int32 x, int32 y) {
return foundId;
}
-bool Hotspots::LoadRif(Common::String rifName, Common::String additionalRifName) {
+bool Hotspots::LoadRif(const Common::String &rifName, const Common::String &additionalRifName) {
debugC(1, kDebugHotspot, "LoadRif(%s, %s)", rifName.c_str(), additionalRifName.c_str());
uint32 size = 0;
diff --git a/engines/toon/hotspot.h b/engines/toon/hotspot.h
index 49ac1a4af8..70e80046e1 100644
--- a/engines/toon/hotspot.h
+++ b/engines/toon/hotspot.h
@@ -50,7 +50,7 @@ public:
Hotspots(ToonEngine *vm);
~Hotspots();
- bool LoadRif(Common::String rifName, Common::String additionalRifName);
+ bool LoadRif(const Common::String &rifName, const Common::String &additionalRifName);
int32 Find(int32 x, int32 y);
int32 FindBasedOnCorner(int32 x, int32 y);
HotspotData *Get(int32 id);
diff --git a/engines/toon/movie.cpp b/engines/toon/movie.cpp
index 7637f4e62f..59ad8484d5 100644
--- a/engines/toon/movie.cpp
+++ b/engines/toon/movie.cpp
@@ -83,7 +83,7 @@ Movie::~Movie() {
void Movie::init() const {
}
-void Movie::play(Common::String video, int32 flags) {
+void Movie::play(const Common::String &video, int32 flags) {
debugC(1, kDebugMovie, "play(%s, %d)", video.c_str(), flags);
bool isFirstIntroVideo = false;
if (video == "209_1M.SMK")
diff --git a/engines/toon/movie.h b/engines/toon/movie.h
index 7e443fd8ab..2cd33302f2 100644
--- a/engines/toon/movie.h
+++ b/engines/toon/movie.h
@@ -45,7 +45,7 @@ public:
virtual ~Movie(void);
void init() const;
- void play(Common::String video, int32 flags = 0);
+ void play(const Common::String &video, int32 flags = 0);
bool isPlaying() { return _playing; }
protected:
diff --git a/engines/toon/path.cpp b/engines/toon/path.cpp
index 60ca007930..2dd5fc45e2 100644
--- a/engines/toon/path.cpp
+++ b/engines/toon/path.cpp
@@ -322,9 +322,10 @@ int32 PathFinding::findPath(int32 x, int32 y, int32 destx, int32 desty) {
int32 endY = MIN<int32>(curY + 1, _height - 1);
int32 startX = MAX<int32>(curX - 1, 0);
int32 startY = MAX<int32>(curY - 1, 0);
+ bool next = false;
- for (int32 px = startX; px <= endX; px++) {
- for (int py = startY; py <= endY; py++) {
+ for (int32 px = startX; px <= endX && !next; px++) {
+ for (int py = startY; py <= endY && !next; py++) {
if (px != curX || py != curY) {
wei = ((abs(px - curX) + abs(py - curY)));
@@ -336,7 +337,7 @@ int32 PathFinding::findPath(int32 x, int32 y, int32 destx, int32 desty) {
sq[curPNode] = sum;
_heap->push(px, py, sq[curPNode] + newWeight);
if (!newWeight)
- goto next; // we found it !
+ next = true; // we found it !
}
}
}
@@ -344,8 +345,6 @@ int32 PathFinding::findPath(int32 x, int32 y, int32 destx, int32 desty) {
}
}
-next:
-
// let's see if we found a result !
if (!_gridTemp[destx + desty * _width]) {
// didn't find anything
diff --git a/engines/toon/picture.cpp b/engines/toon/picture.cpp
index 6367165d6f..ff136e5acb 100644
--- a/engines/toon/picture.cpp
+++ b/engines/toon/picture.cpp
@@ -29,7 +29,7 @@
namespace Toon {
-bool Picture::loadPicture(Common::String file) {
+bool Picture::loadPicture(const Common::String &file) {
debugC(1, kDebugPicture, "loadPicture(%s)", file.c_str());
uint32 size = 0;
diff --git a/engines/toon/picture.h b/engines/toon/picture.h
index ee0e006702..460c5b58a2 100644
--- a/engines/toon/picture.h
+++ b/engines/toon/picture.h
@@ -38,7 +38,7 @@ class Picture {
public:
Picture(ToonEngine *vm);
~Picture();
- bool loadPicture(Common::String file);
+ bool loadPicture(const Common::String &file);
void setupPalette();
void draw(Graphics::Surface &surface, int32 x, int32 y, int32 dx, int32 dy);
void drawWithRectList(Graphics::Surface& surface, int32 x, int32 y, int32 dx, int32 dy, Common::Array<Common::Rect>& rectArray);
diff --git a/engines/toon/resource.cpp b/engines/toon/resource.cpp
index 384a363d7d..2d419ec027 100644
--- a/engines/toon/resource.cpp
+++ b/engines/toon/resource.cpp
@@ -50,13 +50,13 @@ Resources::~Resources() {
purgeFileData();
}
-void Resources::removePackageFromCache(Common::String packName) {
+void Resources::removePackageFromCache(const Common::String &packName) {
// I'm not sure what's a good strategy here. It seems unnecessary to
// actually remove the cached resources, because the player may be
// wandering back and forth between rooms. So for now, do nothing.
}
-bool Resources::getFromCache(Common::String fileName, uint32 *fileSize, uint8 **fileData) {
+bool Resources::getFromCache(const Common::String &fileName, uint32 *fileSize, uint8 **fileData) {
for (Common::Array<CacheEntry *>::iterator entry = _resourceCache.begin(); entry != _resourceCache.end(); ++entry) {
if ((*entry)->_data && (*entry)->_fileName.compareToIgnoreCase(fileName) == 0) {
debugC(5, kDebugResource, "getFromCache(%s) - Got %d bytes from %s", fileName.c_str(), (*entry)->_size, (*entry)->_packName.c_str());
@@ -69,7 +69,7 @@ bool Resources::getFromCache(Common::String fileName, uint32 *fileSize, uint8 **
return false;
}
-void Resources::addToCache(Common::String packName, Common::String fileName, uint32 fileSize, uint8 *fileData) {
+void Resources::addToCache(const Common::String &packName, const Common::String &fileName, uint32 fileSize, uint8 *fileData) {
debugC(5, kDebugResource, "addToCache(%s, %s, %d) - Total Size: %d", packName.c_str(), fileName.c_str(), fileSize, _cacheSize + fileSize);
for (Common::Array<CacheEntry *>::iterator entry = _resourceCache.begin(); entry != _resourceCache.end(); ++entry) {
if ((*entry)->_data) {
@@ -115,7 +115,7 @@ void Resources::addToCache(Common::String packName, Common::String fileName, uin
_resourceCache.push_back(entry);
}
-void Resources::openPackage(Common::String fileName) {
+void Resources::openPackage(const Common::String &fileName) {
debugC(1, kDebugResource, "openPackage(%s)", fileName.c_str());
Common::File file;
@@ -132,7 +132,7 @@ void Resources::openPackage(Common::String fileName) {
_pakFiles.push_back(pakFile);
}
-void Resources::closePackage(Common::String fileName) {
+void Resources::closePackage(const Common::String &fileName) {
removePackageFromCache(fileName);
for (uint32 i = 0; i < _pakFiles.size(); i++) {
@@ -144,7 +144,7 @@ void Resources::closePackage(Common::String fileName) {
}
}
-uint8 *Resources::getFileData(Common::String fileName, uint32 *fileSize) {
+uint8 *Resources::getFileData(const Common::String &fileName, uint32 *fileSize) {
debugC(4, kDebugResource, "getFileData(%s, fileSize)", fileName.c_str());
// first try to find files outside of .pak
@@ -184,7 +184,7 @@ uint8 *Resources::getFileData(Common::String fileName, uint32 *fileSize) {
}
}
-Common::SeekableReadStream *Resources::openFile(Common::String fileName) {
+Common::SeekableReadStream *Resources::openFile(const Common::String &fileName) {
debugC(1, kDebugResource, "openFile(%s)", fileName.c_str());
// first try to find files outside of .pak
@@ -216,7 +216,7 @@ void Resources::purgeFileData() {
_allocatedFileData.clear();
}
-Common::SeekableReadStream *PakFile::createReadStream(Common::String fileName) {
+Common::SeekableReadStream *PakFile::createReadStream(const Common::String &fileName) {
debugC(1, kDebugResource, "createReadStream(%s)", fileName.c_str());
uint32 fileSize = 0;
@@ -227,7 +227,7 @@ Common::SeekableReadStream *PakFile::createReadStream(Common::String fileName) {
return 0;
}
-uint8 *PakFile::getFileData(Common::String fileName, uint32 *fileSize) {
+uint8 *PakFile::getFileData(const Common::String &fileName, uint32 *fileSize) {
debugC(4, kDebugResource, "getFileData(%s, fileSize)", fileName.c_str());
for (uint32 i = 0; i < _numFiles; i++) {
@@ -250,7 +250,7 @@ uint8 *PakFile::getFileData(Common::String fileName, uint32 *fileSize) {
return 0;
}
-void PakFile::open(Common::SeekableReadStream *rs, Common::String packName) {
+void PakFile::open(Common::SeekableReadStream *rs, const Common::String &packName) {
debugC(1, kDebugResource, "open(rs)");
char buffer[64];
diff --git a/engines/toon/resource.h b/engines/toon/resource.h
index 0cecad8187..c80ac2216e 100644
--- a/engines/toon/resource.h
+++ b/engines/toon/resource.h
@@ -37,10 +37,10 @@ public:
PakFile();
~PakFile();
- void open(Common::SeekableReadStream *rs, Common::String packName);
- uint8 *getFileData(Common::String fileName, uint32 *fileSize);
+ void open(Common::SeekableReadStream *rs, const Common::String &packName);
+ uint8 *getFileData(const Common::String &fileName, uint32 *fileSize);
Common::String getPackName() { return _packName; }
- Common::SeekableReadStream *createReadStream(Common::String fileName);
+ Common::SeekableReadStream *createReadStream(const Common::String &fileName);
void close();
protected:
@@ -76,10 +76,10 @@ class Resources {
public:
Resources(ToonEngine *vm);
~Resources();
- void openPackage(Common::String file);
- void closePackage(Common::String fileName);
- Common::SeekableReadStream *openFile(Common::String file);
- uint8 *getFileData(Common::String fileName, uint32 *fileSize); // this memory must be copied to your own structures!
+ void openPackage(const Common::String &file);
+ void closePackage(const Common::String &fileName);
+ Common::SeekableReadStream *openFile(const Common::String &file);
+ uint8 *getFileData(const Common::String &fileName, uint32 *fileSize); // this memory must be copied to your own structures!
void purgeFileData();
protected:
@@ -89,9 +89,9 @@ protected:
uint32 _cacheSize;
Common::Array<CacheEntry *> _resourceCache;
- void removePackageFromCache(Common::String packName);
- bool getFromCache(Common::String fileName, uint32 *fileSize, uint8 **fileData);
- void addToCache(Common::String packName, Common::String fileName, uint32 fileSize, uint8 *fileData);
+ void removePackageFromCache(const Common::String &packName);
+ bool getFromCache(const Common::String &fileName, uint32 *fileSize, uint8 **fileData);
+ void addToCache(const Common::String &packName, const Common::String &fileName, uint32 fileSize, uint8 *fileData);
};
} // End of namespace Toon
diff --git a/engines/toon/script_func.h b/engines/toon/script_func.h
index ef1cb59f47..e22c4b34fa 100644
--- a/engines/toon/script_func.h
+++ b/engines/toon/script_func.h
@@ -39,7 +39,7 @@ public:
Common::Array<const OpcodeV2 *> _opcodes;
ToonEngine *_vm;
-#define SYSFUNC(x) int32 x(EMCState*)
+#define SYSFUNC(x) int32 x(EMCState *)
SYSFUNC(sys_Cmd_Dummy);
SYSFUNC(sys_Cmd_Change_Actor_X_And_Y);
SYSFUNC(sys_Cmd_Init_Talking_Character);
diff --git a/engines/toon/text.cpp b/engines/toon/text.cpp
index 0f72d58b3b..bd4583d799 100644
--- a/engines/toon/text.cpp
+++ b/engines/toon/text.cpp
@@ -35,7 +35,7 @@ TextResource::~TextResource(void) {
delete[] _textData;
}
-bool TextResource::loadTextResource(Common::String fileName) {
+bool TextResource::loadTextResource(const Common::String &fileName) {
debugC(1, kDebugText, "loadTextResource(%s)", fileName.c_str());
uint32 fileSize = 0;
diff --git a/engines/toon/text.h b/engines/toon/text.h
index b8f4a96a6a..cd575736b7 100644
--- a/engines/toon/text.h
+++ b/engines/toon/text.h
@@ -32,7 +32,7 @@ public:
TextResource(ToonEngine *vm);
~TextResource(void);
- bool loadTextResource(Common::String fileName);
+ bool loadTextResource(const Common::String &fileName);
char *getText(int32 id);
int32 getId(int32 offset);
int32 getNext(int32 offset);
diff --git a/engines/toon/toon.cpp b/engines/toon/toon.cpp
index b3ab591ba7..657e18635f 100644
--- a/engines/toon/toon.cpp
+++ b/engines/toon/toon.cpp
@@ -192,7 +192,7 @@ void ToonEngine::parseInput() {
}
if (event.kbd.keycode == Common::KEYCODE_F5 && !hasModifier) {
if (canSaveGameStateCurrently())
- saveGame(-1, Common::String());
+ saveGame(-1, "");
}
if (event.kbd.keycode == Common::KEYCODE_F6 && !hasModifier) {
if (canLoadGameStateCurrently())
@@ -214,7 +214,7 @@ void ToonEngine::parseInput() {
if (event.kbd.flags & Common::KBD_ALT) {
int slotNum = event.kbd.ascii - '0';
if (slotNum >= 0 && slotNum <= 9 && canSaveGameStateCurrently()) {
- if (saveGame(slotNum, Common::String())) {
+ if (saveGame(slotNum, "")) {
// ok
Common::String buf = Common::String::format("Saved game in slot #%d ", slotNum);
GUI::TimedMessageDialog dialog(buf, 1000);
@@ -1084,9 +1084,6 @@ void ToonEngine::updateAnimationSceneScripts(int32 timeElapsed) {
}
void ToonEngine::loadScene(int32 SceneId, bool forGameLoad) {
- char temp[256];
- char temp2[256];
-
_firstFrame = true;
_gameState->_lastVisitedScene = _gameState->_currentScene;
@@ -1148,79 +1145,54 @@ void ToonEngine::loadScene(int32 SceneId, bool forGameLoad) {
_mouseButton = 0;
_lastMouseButton = 0x3;
+ Common::String locationName = state()->_locations[SceneId]._name;
+
// load package
- strcpy(temp, createRoomFilename(Common::String::format("%s.PAK", _gameState->_locations[_gameState->_currentScene]._name).c_str()).c_str());
- resources()->openPackage(temp);
+ resources()->openPackage(createRoomFilename(locationName + ".PAK"));
- strcpy(temp, state()->_locations[SceneId]._name);
- strcat(temp, ".NPP");
- loadAdditionalPalette(temp, 0);
+ loadAdditionalPalette(locationName + ".NPP", 0);
_additionalPalette2Present = false;
- strcpy(temp, state()->_locations[SceneId]._name);
- strcat(temp, ".NP2");
- loadAdditionalPalette(temp, 1);
+ loadAdditionalPalette(locationName + ".NP2", 1);
- strcpy(temp, state()->_locations[SceneId]._name);
- strcat(temp, ".CUP");
- loadAdditionalPalette(temp, 2);
+ loadAdditionalPalette(locationName + ".CUP", 2);
// load artwork
- strcpy(temp, state()->_locations[SceneId]._name);
- strcat(temp, ".CPS");
delete _currentPicture;
_currentPicture = new Picture(this);
- _currentPicture->loadPicture(temp);
+ _currentPicture->loadPicture(locationName + ".CPS");
_currentPicture->setupPalette();
- strcpy(temp, state()->_locations[SceneId]._name);
- strcat(temp, ".MSC");
delete _currentMask;
_currentMask = new Picture(this);
- if (_currentMask->loadPicture(temp))
+ if (_currentMask->loadPicture(locationName + ".MSC"))
_pathFinding->init(_currentMask);
- strcpy(temp, state()->_locations[SceneId]._name);
- strcat(temp, ".TRE");
delete _roomTexts;
_roomTexts = new TextResource(this);
- _roomTexts->loadTextResource(temp);
+ _roomTexts->loadTextResource(locationName + ".TRE");
- strcpy(temp, state()->_locations[SceneId]._name);
- strcat(temp, ".DAT");
uint32 fileSize;
- uint8 *sceneData = resources()->getFileData(temp, &fileSize);
+ uint8 *sceneData = resources()->getFileData(locationName + ".DAT", &fileSize);
if (sceneData) {
delete[] _roomScaleData;
_roomScaleData = new uint8[fileSize];
memcpy(_roomScaleData, sceneData, fileSize);
}
- strcpy(temp, state()->_locations[SceneId]._name);
- strcat(temp, ".SVI");
- strcpy(temp2, createRoomFilename(Common::String::format("%s.SVL", _gameState->_locations[_gameState->_currentScene]._name).c_str()).c_str());
- _audioManager->loadAudioPack(1, temp, temp2);
- strcpy(temp, state()->_locations[SceneId]._name);
- strcpy(temp2, state()->_locations[SceneId]._name);
- strcat(temp, ".SEI");
- strcat(temp2, ".SEL");
- _audioManager->loadAudioPack(3, temp, temp2);
+ _audioManager->loadAudioPack(1, locationName + ".SVI", createRoomFilename(locationName + ".SVL"));
+ _audioManager->loadAudioPack(3, locationName + ".SEI", locationName + ".SEL");
- strcpy(temp, state()->_locations[SceneId]._name);
- strcat(temp, ".RIC");
if (state()->_locations[SceneId]._flags & 0x40) {
- strcpy(temp2, state()->_locations[SceneId]._cutaway);
- strcat(temp2, ".RIC");
+ Common::String cutaway = state()->_locations[SceneId]._cutaway;
+ _hotspots->LoadRif(locationName + ".RIC", cutaway + ".RIC");
} else {
- strcpy(temp2, "");
+ _hotspots->LoadRif(locationName + ".RIC", "");
}
- _hotspots->LoadRif(temp, temp2);
restoreRifFlags(_gameState->_currentScene);
- strcpy(temp, state()->_locations[SceneId]._name);
- strcat(temp, ".CNV");
uint32 convfileSize;
- uint8 *convData = resources()->getFileData(temp, &convfileSize);
+ uint8 *convData = resources()->getFileData(locationName + ".CNV", &convfileSize);
if (convData) {
assert(convfileSize < 4096 * sizeof(int16));
memcpy(_conversationData , convData, convfileSize);
@@ -1228,8 +1200,6 @@ void ToonEngine::loadScene(int32 SceneId, bool forGameLoad) {
}
// load script
- strcpy(temp, state()->_locations[SceneId]._name);
- strcat(temp, ".EMC");
_oldTimer = _system->getMillis();
_oldTimer2 = _oldTimer;
@@ -1239,7 +1209,8 @@ void ToonEngine::loadScene(int32 SceneId, bool forGameLoad) {
_flux->update(0);
_script->unload(&_scriptData);
- _script->load(temp, &_scriptData, &_script_func->_opcodes);
+ Common::String emcfile = locationName + ".EMC";
+ _script->load(emcfile.c_str(), &_scriptData, &_script_func->_opcodes);
_script->init(&_scriptState[0], &_scriptData);
_script->init(&_scriptState[1], &_scriptData);
_script->init(&_scriptState[2], &_scriptData);
@@ -1312,7 +1283,7 @@ void ToonEngine::setupGeneralPalette() {
_drew->setupPalette();
}
-void ToonEngine::loadAdditionalPalette(Common::String fileName, int32 mode) {
+void ToonEngine::loadAdditionalPalette(const Common::String &fileName, int32 mode) {
uint32 size = 0;
uint8 *palette = resources()->getFileData(fileName, &size);
@@ -1779,9 +1750,8 @@ void ToonEngine::exitScene() {
_currentTextLineId = -1;
_currentTextLineCharacterId = 0;
- char temp[256];
- strcpy(temp, createRoomFilename(Common::String::format("%s.PAK", _gameState->_locations[_gameState->_currentScene]._name).c_str()).c_str());
- resources()->closePackage(temp);
+ Common::String locationName = _gameState->_locations[_gameState->_currentScene]._name;
+ resources()->closePackage(createRoomFilename(locationName + ".PAK"));
_drew->stopWalk();
_flux->stopWalk();
@@ -2327,8 +2297,7 @@ void ToonEngine::processConversationClick(Conversation *conv, int32 status) {
if (v8 == -1) {
_gameState->_mouseHidden = false;
} else {
-retry:
- while (1) {
+ while (v8 != -1) {
v7 += 1;
int16 *v14 = (int16 *)((char *)_conversationData + v8);
@@ -2345,15 +2314,10 @@ retry:
v8 = READ_LE_INT16(v7);
if (v8 == -1)
return;
-
- goto retry;
+ else
+ break; // restarts while loop;
}
}
-
- if (v8 != -1)
- continue;
-
- break;
}
}
}
@@ -2785,13 +2749,15 @@ void ToonEngine::deleteMouseItem() {
setCursor(0);
}
-void ToonEngine::showCutaway(Common::String cutawayPicture) {
+void ToonEngine::showCutaway(const Common::String &cutawayPicture) {
_gameState->_inCutaway = true;
_currentCutaway = new Picture(this);
- if (cutawayPicture == "") {
- cutawayPicture = Common::String(_gameState->_locations[_gameState->_currentScene]._cutaway) + ".CPS";
+ if (cutawayPicture.empty()) {
+ Common::String name = _gameState->_locations[_gameState->_currentScene]._cutaway;
+ _currentCutaway->loadPicture(name + ".CPS");
+ } else {
+ _currentCutaway->loadPicture(cutawayPicture);
}
- _currentCutaway->loadPicture(cutawayPicture);
_currentCutaway->setupPalette();
_oldScrollValue = _gameState->_currentScrollValue;
_gameState->_currentScrollValue = 0;
@@ -2942,7 +2908,7 @@ void ToonEngine::drawConversationLine() {
if (_currentTextLine && _showConversationText) {
_fontRenderer->setFontColorByCharacter(_currentTextLineCharacterId);
_fontRenderer->setFont(_fontToon);
- _fontRenderer->renderMultiLineText(_currentTextLineX, _currentTextLineY, Common::String(_currentTextLine), 0);
+ _fontRenderer->renderMultiLineText(_currentTextLineX, _currentTextLineY, _currentTextLine, 0);
}
}
@@ -2988,7 +2954,7 @@ Common::String ToonEngine::getSavegameName(int nr) {
return _targetName + Common::String::format(".%03d", nr);
}
-bool ToonEngine::saveGame(int32 slot, Common::String saveGameDesc) {
+bool ToonEngine::saveGame(int32 slot, const Common::String &saveGameDesc) {
const EnginePlugin *plugin = NULL;
int16 savegameId;
Common::String savegameDescription;
@@ -3418,7 +3384,7 @@ const char *ToonEngine::getSpecialConversationMusic(int32 conversationId) {
return specialMusic[randRange(0, 1) + conversationId * 2];
}
-void ToonEngine::viewInventoryItem(Common::String str, int32 lineId, int32 itemDest) {
+void ToonEngine::viewInventoryItem(const Common::String &str, int32 lineId, int32 itemDest) {
storePalette();
fadeOut(5);
@@ -4511,7 +4477,7 @@ int32 ToonEngine::pauseSceneAnimationScript(int32 animScriptId, int32 tickToWait
return nextTicks;
}
-Common::String ToonEngine::createRoomFilename(Common::String name) {
+Common::String ToonEngine::createRoomFilename(const Common::String& name) {
Common::String file = Common::String::format("ACT%d/%s/%s", _gameState->_currentChapter, _gameState->_locations[_gameState->_currentScene]._name, name.c_str());
return file;
}
@@ -4700,11 +4666,11 @@ void ToonEngine::addDirtyRect( int32 left, int32 top, int32 right, int32 bottom
top = MIN<int32>(MAX<int32>(top, 0), TOON_BACKBUFFER_HEIGHT);
bottom = MIN<int32>(MAX<int32>(bottom, 0), TOON_BACKBUFFER_HEIGHT);
- Common::Rect rect(left, top, right, bottom);
-
if (bottom - top <= 0 || right - left <= 0)
return;
+ Common::Rect rect(left, top, right, bottom);
+
for (uint32 i = 0; i < _dirtyRects.size(); i++) {
if (_dirtyRects[i].contains(rect))
return;
diff --git a/engines/toon/toon.h b/engines/toon/toon.h
index cad684d590..540f3e403b 100644
--- a/engines/toon/toon.h
+++ b/engines/toon/toon.h
@@ -126,7 +126,7 @@ public:
void exitScene();
void loadCursor();
void setCursor(int32 type, bool inventory = false, int32 offsetX = 0, int offsetY = 0);
- void loadAdditionalPalette(Common::String fileName, int32 mode);
+ void loadAdditionalPalette(const Common::String &fileName, int32 mode);
void setupGeneralPalette();
void render();
void update(int32 timeIncrement);
@@ -167,7 +167,7 @@ public:
void rearrangeInventory();
void createMouseItem(int32 item);
void deleteMouseItem();
- void showCutaway(Common::String cutawayPicture);
+ void showCutaway(const Common::String &cutawayPicture);
void hideCutaway();
void drawPalette();
void newGame();
@@ -181,7 +181,7 @@ public:
Character *getCharacterById(int32 charId);
Common::String getSavegameName(int nr);
bool loadGame(int32 slot);
- bool saveGame(int32 slot, Common::String saveGameDesc);
+ bool saveGame(int32 slot, const Common::String &saveGameDesc);
void fadeIn(int32 numFrames);
void fadeOut(int32 numFrames);
void initCharacter(int32 characterId, int32 animScriptId, int32 animToPlayId, int32 sceneAnimationId);
@@ -190,7 +190,7 @@ public:
int32 handleInventoryOnDrew(int32 itemId);
int32 pauseSceneAnimationScript(int32 animScriptId, int32 tickToWait);
void updateTimer(int32 timeIncrement);
- Common::String createRoomFilename(Common::String name);
+ Common::String createRoomFilename(const Common::String &name);
void createShadowLUT();
void playTalkAnimOnCharacter(int32 animID, int32 characterId, bool talker);
void updateScrolling(bool force, int32 timeIncrement);
@@ -201,7 +201,7 @@ public:
void makeLineNonWalkable(int32 x, int32 y, int32 x2, int32 y2);
void makeLineWalkable(int32 x, int32 y, int32 x2, int32 y2);
void renderInventory();
- void viewInventoryItem(Common::String str, int32 lineId, int32 itemDest);
+ void viewInventoryItem(const Common::String &str, int32 lineId, int32 itemDest);
void storePalette();
void restorePalette();
const char *getSpecialConversationMusic(int32 locationId);
diff --git a/engines/touche/detection.cpp b/engines/touche/detection.cpp
index a42d765056..35dd54776f 100644
--- a/engines/touche/detection.cpp
+++ b/engines/touche/detection.cpp
@@ -45,7 +45,7 @@ static const ADGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformPC,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO0()
},
{ // retail version - tracker item #1601818
"touche",
@@ -54,7 +54,7 @@ static const ADGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformPC,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO0()
},
{ // retail version
"touche",
@@ -63,7 +63,7 @@ static const ADGameDescription gameDescriptions[] = {
Common::FR_FRA,
Common::kPlatformPC,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO0()
},
{ // retail version - tracker item #1598643
"touche",
@@ -72,7 +72,7 @@ static const ADGameDescription gameDescriptions[] = {
Common::DE_DEU,
Common::kPlatformPC,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO0()
},
{ // retail version - tracker item #1681643
"touche",
@@ -81,7 +81,7 @@ static const ADGameDescription gameDescriptions[] = {
Common::ES_ESP,
Common::kPlatformPC,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO0()
},
{ // fan-made translation (http://www.iagtg.net/) - tracker item #1602360
"touche",
@@ -90,7 +90,7 @@ static const ADGameDescription gameDescriptions[] = {
Common::IT_ITA,
Common::kPlatformPC,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO0()
},
{ // retail version - tracker item #1800500
"touche",
@@ -99,7 +99,7 @@ static const ADGameDescription gameDescriptions[] = {
Common::PL_POL,
Common::kPlatformPC,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO0()
},
{ // demo version
"touche",
@@ -108,7 +108,7 @@ static const ADGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformPC,
ADGF_DEMO,
- GUIO1(GUIO_NONE)
+ GUIO0()
},
AD_TABLE_END_MARKER
};
diff --git a/engines/touche/graphics.h b/engines/touche/graphics.h
index 4b769b0a66..5b2ea39a24 100644
--- a/engines/touche/graphics.h
+++ b/engines/touche/graphics.h
@@ -23,7 +23,7 @@
#ifndef TOUCHE_GRAPHICS_H
#define TOUCHE_GRAPHICS_H
-#include "common/util.h"
+#include "common/language.h"
namespace Touche {
diff --git a/engines/touche/resource.cpp b/engines/touche/resource.cpp
index 6df6fc0e5f..0790d726b7 100644
--- a/engines/touche/resource.cpp
+++ b/engines/touche/resource.cpp
@@ -590,8 +590,14 @@ void ToucheEngine::res_loadSound(int priority, int num) {
if (priority >= 0) {
uint32 size;
const uint32 offs = res_getDataOffset(kResourceTypeSound, num, &size);
- _fData.seek(offs);
- Audio::AudioStream *stream = Audio::makeVOCStream(&_fData, Audio::FLAG_UNSIGNED);
+ Common::SeekableReadStream *datastream = SearchMan.createReadStreamForMember("TOUCHE.DAT");
+ if (!datastream) {
+ warning("res_loadSound: Could not open TOUCHE.DAT");
+ return;
+ }
+
+ datastream->seek(offs);
+ Audio::AudioStream *stream = Audio::makeVOCStream(datastream, Audio::FLAG_UNSIGNED, DisposeAfterUse::YES);
if (stream) {
_mixer->playStream(Audio::Mixer::kSFXSoundType, &_sfxHandle, stream);
}
diff --git a/engines/touche/saveload.cpp b/engines/touche/saveload.cpp
index 7732c6deb9..a054299ecd 100644
--- a/engines/touche/saveload.cpp
+++ b/engines/touche/saveload.cpp
@@ -60,7 +60,7 @@ static void saveOrLoadPtr(Common::ReadStream &stream, int16 *&p, int16 *base) {
p = base + offset;
}
-template <class S>
+template<class S>
static void saveOrLoad(S &s, Common::Rect &r) {
saveOrLoad(s, r.left);
saveOrLoad(s, r.top);
@@ -68,13 +68,13 @@ static void saveOrLoad(S &s, Common::Rect &r) {
saveOrLoad(s, r.bottom);
}
-template <class S>
+template<class S>
static void saveOrLoad(S &s, SequenceEntry &seq) {
saveOrLoad(s, seq.sprNum);
saveOrLoad(s, seq.seqNum);
}
-template <class S>
+template<class S>
static void saveOrLoad(S &s, KeyChar &key) {
saveOrLoad(s, key.num);
saveOrLoad(s, key.flags);
@@ -134,14 +134,14 @@ static void saveOrLoad(S &s, KeyChar &key) {
}
}
-template <class S>
+template<class S>
static void saveOrLoad(S &s, TalkEntry &entry) {
saveOrLoad(s, entry.otherKeyChar);
saveOrLoad(s, entry.talkingKeyChar);
saveOrLoad(s, entry.num);
}
-template <class S>
+template<class S>
static void saveOrLoad(S &s, ProgramHitBoxData &data) {
saveOrLoad(s, data.item);
saveOrLoad(s, data.talk);
@@ -156,14 +156,14 @@ static void saveOrLoad(S &s, ProgramHitBoxData &data) {
}
}
-template <class S>
+template<class S>
static void saveOrLoad(S &s, Area &area) {
saveOrLoad(s, area.r);
saveOrLoad(s, area.srcX);
saveOrLoad(s, area.srcY);
}
-template <class S>
+template<class S>
static void saveOrLoad(S &s, ProgramBackgroundData &data) {
saveOrLoad(s, data.area);
saveOrLoad(s, data.type);
@@ -172,7 +172,7 @@ static void saveOrLoad(S &s, ProgramBackgroundData &data) {
saveOrLoad(s, data.scaleDiv);
}
-template <class S>
+template<class S>
static void saveOrLoad(S &s, ProgramAreaData &data) {
saveOrLoad(s, data.area);
saveOrLoad(s, data.id);
@@ -181,7 +181,7 @@ static void saveOrLoad(S &s, ProgramAreaData &data) {
saveOrLoad(s, data.animNext);
}
-template <class S>
+template<class S>
static void saveOrLoad(S &s, ProgramWalkData &data) {
saveOrLoad(s, data.point1);
saveOrLoad(s, data.point2);
@@ -190,7 +190,7 @@ static void saveOrLoad(S &s, ProgramWalkData &data) {
saveOrLoad(s, data.area2);
}
-template <class S>
+template<class S>
static void saveOrLoad(S &s, ProgramPointData &data) {
saveOrLoad(s, data.x);
saveOrLoad(s, data.y);
@@ -198,7 +198,7 @@ static void saveOrLoad(S &s, ProgramPointData &data) {
saveOrLoad(s, data.order);
}
-template <class A>
+template<class A>
static void saveOrLoadCommonArray(Common::WriteStream &stream, A &array) {
uint count = array.size();
assert(count < 0xFFFF);
@@ -208,7 +208,7 @@ static void saveOrLoadCommonArray(Common::WriteStream &stream, A &array) {
}
}
-template <class A>
+template<class A>
static void saveOrLoadCommonArray(Common::ReadStream &stream, A &array) {
uint count = stream.readUint16LE();
if (count == array.size()) {
@@ -218,7 +218,7 @@ static void saveOrLoadCommonArray(Common::ReadStream &stream, A &array) {
}
}
-template <class S, class A>
+template<class S, class A>
static void saveOrLoadStaticArray(S &s, A &array, uint count) {
for (uint i = 0; i < count; ++i) {
saveOrLoad(s, array[i]);
diff --git a/engines/touche/staticres.cpp b/engines/touche/staticres.cpp
index f7b1482f80..c18a947358 100644
--- a/engines/touche/staticres.cpp
+++ b/engines/touche/staticres.cpp
@@ -887,6 +887,10 @@ const uint8 Graphics::_freGerFontData[] = {
};
// spanish charset differs from original executable, see tracker item #2040311.
+// We remap missing accented upper case letters from CP850 to their unaccented
+// ASCII variants. Specifically, 0xB5 -> A, 0xD6 -> I, 0xE0 -> O, 0xE9 -> U,
+// 0xEF -> '
+// FIXME: Shouldn't we just add these to the font data?
const uint16 Graphics::_spaFontOffs[] = {
0x0000, 0x0007, 0x0024, 0x0043, 0x0072, 0x00AD, 0x00E0, 0x0113, 0x0124, 0x0141,
0x015E, 0x0191, 0x01C4, 0x01E3, 0x01F8, 0x0215, 0x0232, 0x0269, 0x0286, 0x02BD,
@@ -907,7 +911,8 @@ const uint16 Graphics::_spaFontOffs[] = {
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0703, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
- 0x0000, 0x0000, 0x0000, 0x1954
+ 0x0000, 0x0000, 0x0627, 0x1954, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x097D, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0113
};
const int Graphics::_spaFontSize = ARRAYSIZE(Graphics::_spaFontOffs);
diff --git a/engines/touche/touche.cpp b/engines/touche/touche.cpp
index 81d6adf581..4b989963f6 100644
--- a/engines/touche/touche.cpp
+++ b/engines/touche/touche.cpp
@@ -81,6 +81,7 @@ ToucheEngine::ToucheEngine(OSystem *system, Common::Language language)
DebugMan.addDebugChannel(kDebugResource, "Resource", "Resource debug level");
DebugMan.addDebugChannel(kDebugOpcodes, "Opcodes", "Opcodes debug level");
DebugMan.addDebugChannel(kDebugMenu, "Menu", "Menu debug level");
+ DebugMan.addDebugChannel(kDebugCharset, "Charset", "Charset debug level");
_console = new ToucheConsole(this);
}
@@ -1260,6 +1261,13 @@ const char *ToucheEngine::getString(int num) const {
int ToucheEngine::getStringWidth(int num) const {
const char *str = getString(num);
+ if (DebugMan.isDebugChannelEnabled(kDebugCharset)) {
+ debug("stringwidth: %s", str);
+ debugN("raw:");
+ const char *p = str;
+ while (*p) debugN(" %02X", (unsigned char)*p++);
+ debugN("\n");
+ }
return Graphics::getStringWidth16(str);
}
diff --git a/engines/touche/touche.h b/engines/touche/touche.h
index cbb3fec7aa..949727b665 100644
--- a/engines/touche/touche.h
+++ b/engines/touche/touche.h
@@ -277,7 +277,8 @@ enum {
kDebugGraphics = 1 << 1,
kDebugResource = 1 << 2,
kDebugOpcodes = 1 << 3,
- kDebugMenu = 1 << 4
+ kDebugMenu = 1 << 4,
+ kDebugCharset = 1 << 5
};
enum ResourceType {
diff --git a/engines/tsage/blue_force/blueforce_dialogs.cpp b/engines/tsage/blue_force/blueforce_dialogs.cpp
index 86feceb015..a76d5839a9 100644
--- a/engines/tsage/blue_force/blueforce_dialogs.cpp
+++ b/engines/tsage/blue_force/blueforce_dialogs.cpp
@@ -163,9 +163,12 @@ void RightClickDialog::execute() {
}
g_system->delayMillis(10);
- g_system->updateScreen();
+ GLOBALS._screenSurface.updateScreen();
}
+ // Deactivate the graphics manager used for the dialog
+ _gfxManager.deactivate();
+
// Execute the specified action
CursorType cursorNum = CURSOR_NONE;
switch (_selectedAction) {
@@ -187,13 +190,12 @@ void RightClickDialog::execute() {
break;
case 4:
// Options dialog
+ BlueForce::OptionsDialog::show();
break;
}
if (cursorNum != CURSOR_NONE)
BF_GLOBALS._events.setCursor(cursorNum);
-
- _gfxManager.deactivate();
}
/*--------------------------------------------------------------------------*/
@@ -242,7 +244,7 @@ void AmmoBeltDialog::execute() {
}
g_system->delayMillis(10);
- g_system->updateScreen();
+ GLOBALS._screenSurface.updateScreen();
}
_gfxManager.deactivate();
@@ -342,7 +344,7 @@ void AmmoBeltDialog::draw() {
// Draw the first clip if necessary
if (clip1) {
- GfxSurface clipSurface = surfaceFromRes(9, 6, BF_GLOBALS._clip1Bullets);
+ GfxSurface clipSurface = surfaceFromRes(9, 6, BF_GLOBALS._clip1Bullets + 1);
_clip1Rect.resize(clipSurface, _clip1Rect.left, _clip1Rect.top, 100);
g_globals->gfxManager().copyFrom(clipSurface, bounds.left + _clip1Rect.left,
bounds.top + _clip1Rect.top);
@@ -350,7 +352,7 @@ void AmmoBeltDialog::draw() {
// Draw the second clip if necessary
if (clip2) {
- GfxSurface clipSurface = surfaceFromRes(9, 6, BF_GLOBALS._clip2Bullets);
+ GfxSurface clipSurface = surfaceFromRes(9, 6, BF_GLOBALS._clip2Bullets + 1);
_clip2Rect.resize(clipSurface, _clip2Rect.left, _clip2Rect.top, 100);
g_globals->gfxManager().copyFrom(clipSurface, bounds.left + _clip2Rect.left,
bounds.top + _clip2Rect.top);
@@ -428,6 +430,88 @@ int RadioConvDialog::show() {
return btnIndex;
}
+/*--------------------------------------------------------------------------*/
+
+void OptionsDialog::show() {
+ OptionsDialog *dlg = new OptionsDialog();
+ dlg->draw();
+
+ // Show the dialog
+ GfxButton *btn = dlg->execute();
+
+ // Get which button was pressed
+ int btnIndex = -1;
+ if (btn == &dlg->_btnRestore)
+ btnIndex = 0;
+ else if (btn == &dlg->_btnSave)
+ btnIndex = 1;
+ else if (btn == &dlg->_btnRestart)
+ btnIndex = 2;
+ else if (btn == &dlg->_btnQuit)
+ btnIndex = 3;
+ else if (btn == &dlg->_btnSound)
+ btnIndex = 4;
+
+ // Close the dialog
+ dlg->remove();
+ delete dlg;
+
+ // Execute the given selection
+ if (btnIndex == 0) {
+ // Restore button
+ g_globals->_game->restoreGame();
+ } else if (btnIndex == 1) {
+ // Save button
+ g_globals->_game->saveGame();
+ } else if (btnIndex == 2) {
+ // Restart game
+ g_globals->_game->restartGame();
+ } else if (btnIndex == 3) {
+ // Quit game
+ if (MessageDialog::show(QUIT_CONFIRM_MSG, CANCEL_BTN_STRING, QUIT_BTN_STRING) == 1) {
+ g_vm->quitGame();
+ }
+ } else if (btnIndex == 4) {
+ // Sound dialog
+ SoundDialog::execute();
+ }
+}
+
+OptionsDialog::OptionsDialog() {
+ // Set the element text
+ _gfxMessage.set(OPTIONS_MSG, 140, ALIGN_LEFT);
+ _btnRestore.setText(RESTORE_BTN_STRING);
+ _btnSave.setText(SAVE_BTN_STRING);
+ _btnRestart.setText(RESTART_BTN_STRING);
+ _btnQuit.setText(QUIT_BTN_STRING);
+ _btnSound.setText(SOUND_BTN_STRING);
+ _btnResume.setText(RESUME_BTN_STRING);
+
+ // Set position of the elements
+ _gfxMessage._bounds.moveTo(0, 1);
+ _btnRestore._bounds.moveTo(0, _gfxMessage._bounds.bottom + 1);
+ _btnSave._bounds.moveTo(0, _btnRestore._bounds.bottom + 1);
+ _btnRestart._bounds.moveTo(0, _btnSave._bounds.bottom + 1);
+ _btnQuit._bounds.moveTo(0, _btnRestart._bounds.bottom + 1);
+ _btnSound._bounds.moveTo(0, _btnQuit._bounds.bottom + 1);
+ _btnResume._bounds.moveTo(0, _btnSound._bounds.bottom + 1);
+
+ // Set all the buttons to the widest button
+ GfxButton *btnList[6] = {&_btnRestore, &_btnSave, &_btnRestart, &_btnQuit, &_btnSound, &_btnResume};
+ int16 btnWidth = 0;
+ for (int idx = 0; idx < 6; ++idx)
+ btnWidth = MAX(btnWidth, btnList[idx]->_bounds.width());
+ for (int idx = 0; idx < 6; ++idx)
+ btnList[idx]->_bounds.setWidth(btnWidth);
+
+ // Add the items to the dialog
+ addElements(&_gfxMessage, &_btnRestore, &_btnSave, &_btnRestart, &_btnQuit, &_btnSound, &_btnResume, NULL);
+
+ // Set the dialog size and position
+ frame();
+ _bounds.collapse(-6, -6);
+ setCenter(160, 90);
+}
} // End of namespace BlueForce
diff --git a/engines/tsage/blue_force/blueforce_dialogs.h b/engines/tsage/blue_force/blueforce_dialogs.h
index ca51c97aa2..76de7d19d9 100644
--- a/engines/tsage/blue_force/blueforce_dialogs.h
+++ b/engines/tsage/blue_force/blueforce_dialogs.h
@@ -85,6 +85,20 @@ public:
static int show();
};
+class OptionsDialog: public GfxDialog {
+private:
+ GfxButton _btnSave, _btnRestore, _btnRestart;
+ GfxButton _btnQuit, _btnResume;
+ GfxButton _btnSound;
+ GfxMessage _gfxMessage;
+public:
+ OptionsDialog();
+ virtual ~OptionsDialog() {}
+
+ static void show();
+};
+
+
} // End of namespace BlueForce
} // End of namespace TsAGE
diff --git a/engines/tsage/blue_force/blueforce_logic.cpp b/engines/tsage/blue_force/blueforce_logic.cpp
index 130cf557b2..3aef18f4f0 100644
--- a/engines/tsage/blue_force/blueforce_logic.cpp
+++ b/engines/tsage/blue_force/blueforce_logic.cpp
@@ -20,6 +20,7 @@
*
*/
+#include "common/config-manager.h"
#include "tsage/blue_force/blueforce_logic.h"
#include "tsage/blue_force/blueforce_dialogs.h"
#include "tsage/blue_force/blueforce_scenes0.h"
@@ -42,8 +43,25 @@ namespace TsAGE {
namespace BlueForce {
void BlueForceGame::start() {
- // Start the game
- g_globals->_sceneManager.changeScene(20);
+ int slot = -1;
+
+ // Check for a savegame to load straight from the launcher
+ if (ConfMan.hasKey("save_slot")) {
+ slot = ConfMan.getInt("save_slot");
+ Common::String file = g_vm->generateSaveName(slot);
+ Common::InSaveFile *in = g_vm->_system->getSavefileManager()->openForLoading(file);
+ if (in)
+ delete in;
+ else
+ slot = -1;
+ }
+
+ if (slot >= 0)
+ // Set the savegame slot to load in the main loop
+ g_globals->_sceneHandler->_loadGameSlot = slot;
+ else
+ // Switch to the title screen
+ g_globals->_sceneManager.setNewScene(20);
}
Scene *BlueForceGame::createScene(int sceneNumber) {
@@ -255,14 +273,16 @@ Scene *BlueForceGame::createScene(int sceneNumber) {
* Returns true if it is currently okay to restore a game
*/
bool BlueForceGame::canLoadGameStateCurrently() {
- return true;
+ // Don't allow a game to be loaded if a dialog is active
+ return g_globals->_gfxManagers.size() == 1;
}
/**
* Returns true if it is currently okay to save the game
*/
bool BlueForceGame::canSaveGameStateCurrently() {
- return true;
+ // Don't allow a game to be saved if a dialog is active
+ return g_globals->_gfxManagers.size() == 1;
}
void BlueForceGame::rightClick() {
@@ -315,6 +335,24 @@ void BlueForceGame::processEvent(Event &event) {
}
}
+void BlueForceGame::restart() {
+ g_globals->_scenePalette.clearListeners();
+ g_globals->_soundHandler.stop();
+
+ // Reset the globals
+ g_globals->reset();
+
+ // Clear save/load slots
+ g_globals->_sceneHandler->_saveGameSlot = -1;
+ g_globals->_sceneHandler->_loadGameSlot = -1;
+
+ g_globals->_stripNum = 0;
+ g_globals->_events.setCursor(CURSOR_WALK);
+
+ // Change to the first game scene
+ g_globals->_sceneManager.changeScene(190);
+}
+
/*--------------------------------------------------------------------------*/
AObjectArray::AObjectArray(): EventHandler() {
@@ -515,35 +553,6 @@ bool NamedObject::startAction(CursorType action, Event &event) {
return handled;
}
-void NamedObject::setDetails(int resNum, int lookLineNum, int talkLineNum, int useLineNum, int mode, SceneItem *item) {
- _resNum = resNum;
- _lookLineNum = lookLineNum;
- _talkLineNum = talkLineNum;
- _useLineNum = useLineNum;
-
- switch (mode) {
- case 2:
- g_globals->_sceneItems.push_front(this);
- break;
- case 4:
- g_globals->_sceneItems.addBefore(item, this);
- break;
- case 5:
- g_globals->_sceneItems.addAfter(item, this);
- break;
- default:
- g_globals->_sceneItems.push_back(this);
- break;
- }
-}
-
-void NamedObject::setDetails(int resNum, int lookLineNum, int talkLineNum, int useLineNum) {
- _resNum = resNum;
- _lookLineNum = lookLineNum;
- _talkLineNum = talkLineNum;
- _useLineNum = useLineNum;
-}
-
/*--------------------------------------------------------------------------*/
CountdownObject::CountdownObject(): NamedObject() {
@@ -604,14 +613,14 @@ void FollowerObject::dispatch() {
} else if ((_object->_visage != 308) || (_object->_strip != 1)) {
show();
setStrip(_object->_strip);
- setPosition(_object->_position, _object->_yDiff);
+ setPosition(Common::Point(_object->_position.x + 1, _object->_position.y), _yDiff);
}
}
void FollowerObject::reposition() {
assert(_object);
setStrip(_object->_strip);
- setPosition(_object->_position, _object->_yDiff);
+ setPosition(_object->_position, _yDiff);
NamedObject::reposition();
}
@@ -724,7 +733,7 @@ void SceneExt::remove() {
_action->_endHandler = NULL;
_action->remove();
}
-
+
_focusObject = NULL;
}
@@ -755,6 +764,7 @@ void SceneExt::loadScene(int sceneNum) {
_v51C34.top = 0;
_v51C34.bottom = 300;
+ BF_GLOBALS._sceneHandler->_delayTicks = 1;
}
void SceneExt::checkGun() {
@@ -955,7 +965,7 @@ void SceneHandlerExt::process(Event &event) {
return;
}
- // If the user clicks the button whislt the introduction is active, prompt for playing the game
+ // If the user clicks the button whilst the introduction is active, prompt for playing the game
if ((BF_GLOBALS._dayNumber == 0) && (event.eventType == EVENT_BUTTON_DOWN)) {
// Prompt user for whether to start play or watch introduction
BF_GLOBALS._player.enableControl();
@@ -1316,7 +1326,7 @@ bool BlueForceInvObjectList::SelectItem(int objectNumber) {
AmmoBeltDialog *dlg = new AmmoBeltDialog();
dlg->execute();
delete dlg;
-
+
return true;
}
@@ -1358,58 +1368,6 @@ bool NamedHotspot::startAction(CursorType action, Event &event) {
}
}
-void NamedHotspot::setDetails(int ys, int xs, int ye, int xe, const int resnum, const int lookLineNum, const int useLineNum) {
- setBounds(ys, xe, ye, xs);
- _resNum = resnum;
- _lookLineNum = lookLineNum;
- _useLineNum = useLineNum;
- _talkLineNum = -1;
- g_globals->_sceneItems.addItems(this, NULL);
-}
-
-void NamedHotspot::setDetails(const Rect &bounds, int resNum, int lookLineNum, int talkLineNum, int useLineNum, int mode, SceneItem *item) {
- setBounds(bounds);
- _resNum = resNum;
- _lookLineNum = lookLineNum;
- _talkLineNum = talkLineNum;
- _useLineNum = useLineNum;
-
- switch (mode) {
- case 2:
- g_globals->_sceneItems.push_front(this);
- break;
- case 4:
- g_globals->_sceneItems.addBefore(item, this);
- break;
- case 5:
- g_globals->_sceneItems.addAfter(item, this);
- break;
- default:
- g_globals->_sceneItems.push_back(this);
- break;
- }
-}
-
-void NamedHotspot::setDetails(int sceneRegionId, int resNum, int lookLineNum, int talkLineNum, int useLineNum, int mode) {
- _sceneRegionId = sceneRegionId;
- _resNum = resNum;
- _lookLineNum = lookLineNum;
- _talkLineNum = talkLineNum;
- _useLineNum = useLineNum;
-
- // Handle adding hotspot to scene items list as necessary
- switch (mode) {
- case 2:
- GLOBALS._sceneItems.push_front(this);
- break;
- case 3:
- break;
- default:
- GLOBALS._sceneItems.push_back(this);
- break;
- }
-}
-
void NamedHotspot::synchronize(Serializer &s) {
SceneHotspot::synchronize(s);
s.syncAsSint16LE(_resNum);
@@ -1450,7 +1408,7 @@ void SceneMessage::signal() {
}
void SceneMessage::process(Event &event) {
- if ((event.eventType == EVENT_BUTTON_DOWN) ||
+ if ((event.eventType == EVENT_BUTTON_DOWN) ||
((event.eventType == EVENT_KEYPRESS) && (event.kbd.keycode == Common::KEYCODE_RETURN))) {
signal();
}
@@ -1481,7 +1439,7 @@ void SceneMessage::draw() {
void SceneMessage::clear() {
// Fade out the text display
- static const uint32 black = 0;
+ static const uint32 black = 0;
BF_GLOBALS._scenePalette.fade((const byte *)&black, false, 100);
// Refresh the background
diff --git a/engines/tsage/blue_force/blueforce_logic.h b/engines/tsage/blue_force/blueforce_logic.h
index 1b161bce06..59bc2b7a51 100644
--- a/engines/tsage/blue_force/blueforce_logic.h
+++ b/engines/tsage/blue_force/blueforce_logic.h
@@ -45,6 +45,7 @@ public:
virtual void processEvent(Event &event);
virtual bool canSaveGameStateCurrently();
virtual bool canLoadGameStateCurrently();
+ virtual void restart();
};
#define OBJ_ARRAY_SIZE 10
@@ -64,6 +65,9 @@ public:
void add(EventHandler *obj);
void remove(EventHandler *obj);
+ // The following line prevents compiler warnings about hiding the remove()
+ // method from the parent class.
+ virtual void remove() { EventHandler::remove(); }
};
class Timer: public EventHandler {
@@ -115,16 +119,10 @@ public:
class NamedObject: public SceneObject {
public:
- int _resNum;
- int _lookLineNum, _talkLineNum, _useLineNum;
-
virtual Common::String getClassName() { return "NamedObject"; }
virtual void synchronize(Serializer &s);
virtual void postInit(SceneObjectList *OwnerList = NULL);
virtual bool startAction(CursorType action, Event &event);
-
- void setDetails(int resNum, int lookLineNum, int talkLineNum, int useLineNum, int mode, SceneItem *item);
- void setDetails(int resNum, int lookLineNum, int talkLineNum, int useLineNum);
};
class NamedObjectExt: public NamedObject {
@@ -334,16 +332,11 @@ public:
class NamedHotspot : public SceneHotspot {
public:
- int _resNum, _lookLineNum, _useLineNum, _talkLineNum;
NamedHotspot();
-
virtual bool startAction(CursorType action, Event &event);
virtual Common::String getClassName() { return "NamedHotspot"; }
virtual void synchronize(Serializer &s);
- virtual void setDetails(int ys, int xs, int ye, int xe, const int resnum, const int lookLineNum, const int useLineNum);
- virtual void setDetails(const Rect &bounds, int resNum, int lookLineNum, int talkLineNum, int useLineNum, int mode, SceneItem *item);
- virtual void setDetails(int sceneRegionId, int resNum, int lookLineNum, int talkLineNum, int useLineNum, int mode);
};
class NamedHotspotExt : public NamedHotspot {
diff --git a/engines/tsage/blue_force/blueforce_scenes0.cpp b/engines/tsage/blue_force/blueforce_scenes0.cpp
index bb283d051e..95598babc6 100644
--- a/engines/tsage/blue_force/blueforce_scenes0.cpp
+++ b/engines/tsage/blue_force/blueforce_scenes0.cpp
@@ -48,45 +48,45 @@ void Scene20::Action1::signal() {
BF_GLOBALS._scenePalette.addRotation(64, 127, -1, 1, this);
break;
case 2:
- scene->_object1.setVisage(22);
- scene->_object1._strip = 1;
- scene->_object1._frame = 1;
- scene->_object1.changeZoom(100);
-
- scene->_object2.setVisage(22);
- scene->_object2._strip = 2;
- scene->_object2._frame = 1;
- scene->_object2.changeZoom(100);
-
- scene->_object3.setVisage(22);
- scene->_object3._strip = 3;
- scene->_object3._frame = 1;
- scene->_object3.changeZoom(100);
-
- scene->_object4.setVisage(22);
- scene->_object4._strip = 4;
- scene->_object4._frame = 1;
- scene->_object4.changeZoom(100);
-
- scene->_object5.setVisage(22);
- scene->_object5._strip = 5;
- scene->_object5._frame = 1;
- scene->_object5.changeZoom(100);
-
- scene->_object6.setVisage(22);
- scene->_object6._strip = 6;
- scene->_object6._frame = 1;
- scene->_object6.changeZoom(100);
-
- scene->_object7.setVisage(22);
- scene->_object7._strip = 7;
- scene->_object7._frame = 1;
- scene->_object7.changeZoom(100);
-
- scene->_object8.setVisage(22);
- scene->_object8._strip = 8;
- scene->_object8._frame = 1;
- scene->_object8.changeZoom(100);
+ scene->_tsunamiWave.setVisage(22);
+ scene->_tsunamiWave._strip = 1;
+ scene->_tsunamiWave._frame = 1;
+ scene->_tsunamiWave.changeZoom(100);
+
+ scene->_letterT.setVisage(22);
+ scene->_letterT._strip = 2;
+ scene->_letterT._frame = 1;
+ scene->_letterT.changeZoom(100);
+
+ scene->_letterS.setVisage(22);
+ scene->_letterS._strip = 3;
+ scene->_letterS._frame = 1;
+ scene->_letterS.changeZoom(100);
+
+ scene->_letterU.setVisage(22);
+ scene->_letterU._strip = 4;
+ scene->_letterU._frame = 1;
+ scene->_letterU.changeZoom(100);
+
+ scene->_letterN.setVisage(22);
+ scene->_letterN._strip = 5;
+ scene->_letterN._frame = 1;
+ scene->_letterN.changeZoom(100);
+
+ scene->_letterA.setVisage(22);
+ scene->_letterA._strip = 6;
+ scene->_letterA._frame = 1;
+ scene->_letterA.changeZoom(100);
+
+ scene->_letterM.setVisage(22);
+ scene->_letterM._strip = 7;
+ scene->_letterM._frame = 1;
+ scene->_letterM.changeZoom(100);
+
+ scene->_letterI.setVisage(22);
+ scene->_letterI._strip = 8;
+ scene->_letterI._frame = 1;
+ scene->_letterI.changeZoom(100);
setDelay(1);
break;
@@ -97,12 +97,12 @@ void Scene20::Action1::signal() {
setDelay(60);
break;
case 5:
- scene->_object2.animate(ANIM_MODE_5, NULL);
- scene->_object3.animate(ANIM_MODE_5, NULL);
- scene->_object4.animate(ANIM_MODE_5, NULL);
- scene->_object5.animate(ANIM_MODE_5, NULL);
- scene->_object6.animate(ANIM_MODE_5, NULL);
- scene->_object7.animate(ANIM_MODE_5, this);
+ scene->_letterT.animate(ANIM_MODE_5, NULL);
+ scene->_letterS.animate(ANIM_MODE_5, NULL);
+ scene->_letterU.animate(ANIM_MODE_5, NULL);
+ scene->_letterN.animate(ANIM_MODE_5, NULL);
+ scene->_letterA.animate(ANIM_MODE_5, NULL);
+ scene->_letterM.animate(ANIM_MODE_5, this);
break;
case 6:
setDelay(120);
@@ -121,76 +121,76 @@ void Scene20::Action1::signal() {
void Scene20::postInit(SceneObjectList *OwnerList) {
loadScene(20);
- Scene::postInit();
+ SceneExt::postInit();
setZoomPercents(60, 85, 200, 100);
BF_GLOBALS._interfaceY = SCREEN_HEIGHT;
_scenePalette.loadPalette(1);
_scenePalette.loadPalette(22);
- _object1.postInit();
- _object1.setVisage(21);
- _object1._strip = 1;
- _object1._frame = 1;
- _object1.animate(ANIM_MODE_NONE, NULL);
- _object1.setPosition(Common::Point(62, 85));
- _object1.changeZoom(100);
-
- _object2.postInit();
- _object2.setVisage(21);
- _object2._strip = 2;
- _object2._frame = 1;
- _object2.animate(ANIM_MODE_NONE, NULL);
- _object2.setPosition(Common::Point(27, 94));
- _object2.changeZoom(100);
-
- _object3.postInit();
- _object3.setVisage(21);
- _object3._strip = 2;
- _object3._frame = 2;
- _object3.animate(ANIM_MODE_NONE, NULL);
- _object3.setPosition(Common::Point(68, 94));
- _object3.changeZoom(100);
-
- _object4.postInit();
- _object4.setVisage(21);
- _object4._strip = 2;
- _object4._frame = 3;
- _object4.animate(ANIM_MODE_NONE, NULL);
- _object4.setPosition(Common::Point(110, 94));
- _object4.changeZoom(100);
-
- _object5.postInit();
- _object5.setVisage(21);
- _object5._strip = 2;
- _object5._frame = 4;
- _object5.animate(ANIM_MODE_NONE, NULL);
- _object5.setPosition(Common::Point(154, 94));
- _object5.changeZoom(100);
-
- _object6.postInit();
- _object6.setVisage(21);
- _object6._strip = 2;
- _object6._frame = 5;
- _object6.animate(ANIM_MODE_NONE, NULL);
- _object6.setPosition(Common::Point(199, 94));
- _object6.changeZoom(100);
-
- _object7.postInit();
- _object7.setVisage(21);
- _object7._strip = 2;
- _object7._frame = 6;
- _object7.animate(ANIM_MODE_NONE, NULL);
- _object7.setPosition(Common::Point(244, 94));
- _object7.changeZoom(100);
-
- _object8.postInit();
- _object8.setVisage(21);
- _object8._strip = 2;
- _object8._frame = 7;
- _object8.animate(ANIM_MODE_NONE, NULL);
- _object8.setPosition(Common::Point(286, 94));
- _object8.changeZoom(100);
+ _tsunamiWave.postInit();
+ _tsunamiWave.setVisage(21);
+ _tsunamiWave._strip = 1;
+ _tsunamiWave._frame = 1;
+ _tsunamiWave.animate(ANIM_MODE_NONE, NULL);
+ _tsunamiWave.setPosition(Common::Point(62, 85));
+ _tsunamiWave.changeZoom(100);
+
+ _letterT.postInit();
+ _letterT.setVisage(21);
+ _letterT._strip = 2;
+ _letterT._frame = 1;
+ _letterT.animate(ANIM_MODE_NONE, NULL);
+ _letterT.setPosition(Common::Point(27, 94));
+ _letterT.changeZoom(100);
+
+ _letterS.postInit();
+ _letterS.setVisage(21);
+ _letterS._strip = 2;
+ _letterS._frame = 2;
+ _letterS.animate(ANIM_MODE_NONE, NULL);
+ _letterS.setPosition(Common::Point(68, 94));
+ _letterS.changeZoom(100);
+
+ _letterU.postInit();
+ _letterU.setVisage(21);
+ _letterU._strip = 2;
+ _letterU._frame = 3;
+ _letterU.animate(ANIM_MODE_NONE, NULL);
+ _letterU.setPosition(Common::Point(110, 94));
+ _letterU.changeZoom(100);
+
+ _letterN.postInit();
+ _letterN.setVisage(21);
+ _letterN._strip = 2;
+ _letterN._frame = 4;
+ _letterN.animate(ANIM_MODE_NONE, NULL);
+ _letterN.setPosition(Common::Point(154, 94));
+ _letterN.changeZoom(100);
+
+ _letterA.postInit();
+ _letterA.setVisage(21);
+ _letterA._strip = 2;
+ _letterA._frame = 5;
+ _letterA.animate(ANIM_MODE_NONE, NULL);
+ _letterA.setPosition(Common::Point(199, 94));
+ _letterA.changeZoom(100);
+
+ _letterM.postInit();
+ _letterM.setVisage(21);
+ _letterM._strip = 2;
+ _letterM._frame = 6;
+ _letterM.animate(ANIM_MODE_NONE, NULL);
+ _letterM.setPosition(Common::Point(244, 94));
+ _letterM.changeZoom(100);
+
+ _letterI.postInit();
+ _letterI.setVisage(21);
+ _letterI._strip = 2;
+ _letterI._frame = 7;
+ _letterI.animate(ANIM_MODE_NONE, NULL);
+ _letterI.setPosition(Common::Point(286, 94));
+ _letterI.changeZoom(100);
setAction(&_action1);
BF_GLOBALS._dialogCenter.y = 165;
@@ -209,6 +209,11 @@ void Scene50::Tooltip::synchronize(Serializer &s) {
SavedObject::synchronize(s);
_bounds.synchronize(s);
s.syncString(_msg);
+
+ if (s.getVersion() >= 10) {
+ s.syncAsSint16LE(_newSceneNumber);
+ s.syncAsSint16LE(_locationId);
+ }
}
void Scene50::Tooltip2::signal() {
@@ -239,11 +244,11 @@ void Scene50::Tooltip2::dispatch() {
}
}
-void Scene50::Tooltip::set(const Rect &bounds, int v60, const Common::String &msg, int v62) {
+void Scene50::Tooltip::set(const Rect &bounds, int sceneNum, const Common::String &msg, int locationId) {
_bounds = bounds;
- _newSceneNumber = v60;
+ _newSceneNumber = sceneNum;
_msg = msg;
- _locationId = v62;
+ _locationId = locationId;
}
void Scene50::Tooltip::update() {
@@ -261,8 +266,8 @@ void Scene50::Tooltip::update() {
void Scene50::Tooltip::highlight(bool btnDown) {
Scene50 *scene = (Scene50 *)BF_GLOBALS._sceneManager._scene;
- scene->_field382 = _newSceneNumber;
- if ((scene->_field380 != 0) || (scene->_field380 != _newSceneNumber))
+ // In the original, a variable was used, always set to 0. The check is simplified
+ if (_newSceneNumber != 0)
update();
if (btnDown) {
@@ -323,9 +328,16 @@ void Scene50::Tooltip::highlight(bool btnDown) {
/*--------------------------------------------------------------------------*/
-Scene50::Scene50(): SceneExt() {
- _field382 = 0;
- _field380 = 0;
+Scene50::Scene50() {
+ _sceneNumber = 0;
+}
+
+
+void Scene50::synchronize(Serializer &s) {
+ if (s.getVersion() >= 10) {
+ SceneExt::synchronize(s);
+ s.syncAsSint16LE(_sceneNumber);
+ }
}
void Scene50::postInit(SceneObjectList *OwnerList) {
@@ -439,11 +451,11 @@ void Scene50::signal() {
}
if ((BF_GLOBALS._driveFromScene == 410) && (_sceneNumber != BF_GLOBALS._driveFromScene)) {
- BF_GLOBALS.setFlag(125);
+ BF_GLOBALS.setFlag(f1097Frankie);
}
if ((BF_GLOBALS._driveFromScene == 340) && (_sceneNumber != BF_GLOBALS._driveFromScene)) {
- BF_GLOBALS.setFlag(123);
+ BF_GLOBALS.setFlag(f1097Marina);
}
if ((BF_GLOBALS._driveFromScene == 380) && (_sceneNumber != BF_GLOBALS._driveFromScene)) {
@@ -469,7 +481,6 @@ void Scene50::signal() {
BF_GLOBALS._player.enableControl();
BF_GLOBALS._events.setCursor(CURSOR_WALK);
_sceneMode = 0;
- _field380 = 0;
}
}
@@ -477,7 +488,6 @@ void Scene50::process(Event &event) {
SceneExt::process(event);
Common::Point pt(event.mousePos.x + _sceneBounds.left, event.mousePos.y + _sceneBounds.top);
bool mouseDown = false;
- _field382 = 0;
if ((event.mousePos.x > 270 && (_sceneBounds.right < (SCREEN_WIDTH * 2))))
loadBackground(4, 0);
@@ -537,7 +547,7 @@ bool Scene60::Ignition::startAction(CursorType action, Event &event) {
bool Scene60::Ignition::check1() {
if (BF_GLOBALS._bookmark >= bStoppedFrankie) {
- BF_GLOBALS._v5098C |= 1;
+ BF_GLOBALS._subFlagBitArr1 |= 1;
return false;
} else {
if ((BF_GLOBALS._bookmark == bBookedGreen) && BF_GLOBALS.getFlag(fArrivedAtGangStop)) {
@@ -564,13 +574,13 @@ bool Scene60::Ignition::check1() {
} else if (BF_GLOBALS._bookmark < bStartOfGame) {
// Should never reach here
} else if (BF_GLOBALS._bookmark < bCalledToDomesticViolence) {
- if ((BF_GLOBALS._v5098C >> 1) & 1)
+ if ((BF_GLOBALS._subFlagBitArr1 >> 1) & 1)
BF_GLOBALS.setFlag(fLateToMarina);
else
- BF_GLOBALS._v5098C |= 2;
+ BF_GLOBALS._subFlagBitArr1 |= 2;
} else {
- int v = (((BF_GLOBALS._v5098C >> 2) & 15) + 1) & 15;
- BF_GLOBALS._v5098C = (BF_GLOBALS._v5098C & 0xC3) | (v << 2);
+ int v = (((BF_GLOBALS._subFlagBitArr1 >> 2) & 15) + 1) & 15;
+ BF_GLOBALS._subFlagBitArr1 = (BF_GLOBALS._subFlagBitArr1 & 0xC3) | (v << 2);
if ((v != 1) && (v != 2)) {
BF_GLOBALS._deathReason = 19;
@@ -580,17 +590,17 @@ bool Scene60::Ignition::check1() {
}
}
- BF_GLOBALS._v5098C |= 1;
+ BF_GLOBALS._subFlagBitArr1 |= 1;
return false;
}
bool Scene60::Ignition::check2() {
switch (BF_GLOBALS._bookmark) {
case bInspectionDone:
- if (BF_GLOBALS._v5098D & 1) {
+ if (BF_GLOBALS._subFlagBitArr2 & 1) {
BF_GLOBALS.setFlag(fLateToDrunkStop);
} else {
- BF_GLOBALS._v5098D |= 1;
+ BF_GLOBALS._subFlagBitArr2 |= 1;
}
break;
case bCalledToDrunkStop:
@@ -600,7 +610,7 @@ bool Scene60::Ignition::check2() {
break;
}
- BF_GLOBALS._v5098C |= 0x80;
+ BF_GLOBALS._subFlagBitArr1 |= 0x80;
return false;
}
@@ -1083,7 +1093,7 @@ void Scene60::postInit(SceneObjectList *OwnerList) {
switch (BF_GLOBALS._dayNumber) {
case 1:
- if (BF_GLOBALS.getFlag(onDuty) && (BF_GLOBALS._v5098C & 1) &&
+ if (BF_GLOBALS.getFlag(onDuty) && (BF_GLOBALS._subFlagBitArr1 & 1) &&
(BF_GLOBALS._bookmark < bStartOfGame) && (BF_GLOBALS._sceneManager._previousScene != 342)) {
setAction(&_action2);
if (BF_GLOBALS._sceneManager._previousScene == 342)
@@ -1091,7 +1101,7 @@ void Scene60::postInit(SceneObjectList *OwnerList) {
}
break;
case 2:
- if (BF_GLOBALS.getFlag(onDuty) && ((BF_GLOBALS._v5098C >> 7) & 1) &&
+ if (BF_GLOBALS.getFlag(onDuty) && ((BF_GLOBALS._subFlagBitArr1 >> 7) & 1) &&
(BF_GLOBALS._sceneManager._previousScene != 550) &&
(BF_GLOBALS._bookmark < bInspectionDone)) {
setAction(&_action3);
diff --git a/engines/tsage/blue_force/blueforce_scenes0.h b/engines/tsage/blue_force/blueforce_scenes0.h
index 103e5f0a4c..dd502c5f30 100644
--- a/engines/tsage/blue_force/blueforce_scenes0.h
+++ b/engines/tsage/blue_force/blueforce_scenes0.h
@@ -50,8 +50,8 @@ class Scene20 : public SceneExt {
public:
Action1 _action1;
ScenePalette _scenePalette;
- SceneObject _object1, _object2, _object3, _object4;
- SceneObject _object5, _object6, _object7, _object8;
+ SceneObject _tsunamiWave, _letterT, _letterS, _letterU;
+ SceneObject _letterN, _letterA, _letterM, _letterI;
virtual void postInit(SceneObjectList *OwnerList = NULL);
};
@@ -65,7 +65,7 @@ class Scene50: public SceneExt {
int _locationId;
public:
Tooltip();
- void set(const Rect &bounds, int v60, const Common::String &msg, int v62);
+ void set(const Rect &bounds, int sceneNum, const Common::String &msg, int locationId);
void update();
void highlight(bool btnDown);
@@ -81,7 +81,6 @@ class Scene50: public SceneExt {
virtual void dispatch();
};
public:
- int _field380, _field382;
int _sceneNumber;
SceneText _text;
SceneItemType2 _item;
@@ -90,7 +89,10 @@ public:
Timer _timer;
public:
Scene50();
+
virtual Common::String getClassName() { return "Scene50"; }
+ virtual void synchronize(Serializer &s);
+
virtual void postInit(SceneObjectList *OwnerList = NULL);
virtual void remove();
virtual void signal();
@@ -172,6 +174,7 @@ public:
int _sceneNumber;
int _visage;
CursorType _cursorId;
+ // TODO: Check if really useless in original
bool _field1222;
Scene60();
diff --git a/engines/tsage/blue_force/blueforce_scenes1.cpp b/engines/tsage/blue_force/blueforce_scenes1.cpp
index e977d5fbca..9f1e9ce36e 100644
--- a/engines/tsage/blue_force/blueforce_scenes1.cpp
+++ b/engines/tsage/blue_force/blueforce_scenes1.cpp
@@ -243,8 +243,8 @@ void Scene109::Action1::signal() {
scene->_drunk.show();
scene->_drunk.setAction(&scene->_action3);
scene->_object2.show();
- scene->_object9.show();
- scene->_object9.setAction(&scene->_action2);
+ scene->_beerSign.show();
+ scene->_beerSign.setAction(&scene->_action2);
BF_GLOBALS._v501FC = 170;
setDelay(60);
@@ -257,27 +257,27 @@ void Scene109::Action1::signal() {
break;
case 5:
// Open briefcase and pass over disk
- setAction(&scene->_sequenceManager6, this, 105, &scene->_object10, NULL);
+ setAction(&scene->_sequenceManager6, this, 105, &scene->_animationInset, NULL);
break;
case 6:
// Protaginist 2 walk to the bar
- scene->_object10.remove();
+ scene->_animationInset.remove();
setAction(&scene->_sequenceManager6, this, 100, &scene->_protaginist2, NULL);
break;
case 7:
// Two thugs enter and walk to table
- scene->_object7.setAction(&scene->_sequenceManager7, NULL, 103, &scene->_object7, NULL);
- scene->_object5.setAction(&scene->_sequenceManager8, this, 102, &scene->_object5, NULL);
+ scene->_cop2.setAction(&scene->_sequenceManager7, NULL, 103, &scene->_cop2, NULL);
+ scene->_cop1.setAction(&scene->_sequenceManager8, this, 102, &scene->_cop1, NULL);
scene->_protaginist2.setAction(&scene->_sequenceManager6, NULL, 104, &scene->_protaginist2, &scene->_bartender, NULL);
break;
case 8:
// Protaginist 1 leaves, protaginist 2 stands up
- setAction(&scene->_sequenceManager8, this, 101, &scene->_object5, &scene->_protaginist1, NULL);
+ setAction(&scene->_sequenceManager8, this, 101, &scene->_cop1, &scene->_protaginist1, NULL);
break;
case 9:
// Shots fired!
scene->_protaginist1.setAction(&scene->_sequenceManager5, this, 98, &scene->_protaginist1, NULL);
- scene->_object7.setAction(&scene->_sequenceManager7, NULL, 99, &scene->_object7, NULL);
+ scene->_cop2.setAction(&scene->_sequenceManager7, NULL, 99, &scene->_cop2, NULL);
break;
case 10:
// End scene
@@ -289,12 +289,12 @@ void Scene109::Action1::signal() {
void Scene109::Action2::signal() {
Scene109 *scene = (Scene109 *)BF_GLOBALS._sceneManager._scene;
- scene->setAction(&scene->_sequenceManager2, this, 3117, &scene->_object9, NULL);
+ setAction(&scene->_sequenceManager2, this, 3117, &scene->_beerSign, NULL);
}
void Scene109::Action3::signal() {
Scene109 *scene = (Scene109 *)BF_GLOBALS._sceneManager._scene;
- scene->setAction(&scene->_sequenceManager3, this, 108, &scene->_drunk, NULL);
+ setAction(&scene->_sequenceManager3, this, 108, &scene->_drunk, NULL);
}
/*--------------------------------------------------------------------------*/
@@ -353,21 +353,21 @@ void Scene109::postInit(SceneObjectList *OwnerList) {
_object2.setPosition(Common::Point(104, 64));
_object2.hide();
- _object9.postInit();
- _object9.setVisage(115);
- _object9.setStrip(4);
- _object9.setFrame(1);
- _object9.setPosition(Common::Point(262, 29));
- _object9.hide();
+ _beerSign.postInit();
+ _beerSign.setVisage(115);
+ _beerSign.setStrip(4);
+ _beerSign.setFrame(1);
+ _beerSign.setPosition(Common::Point(262, 29));
+ _beerSign.hide();
- _object5.postInit();
- _object5.hide();
+ _cop1.postInit();
+ _cop1.hide();
- _object7.postInit();
- _object7.hide();
+ _cop2.postInit();
+ _cop2.hide();
- _object10.postInit();
- _object10.hide();
+ _animationInset.postInit();
+ _animationInset.hide();
BF_GLOBALS._player.disableControl();
setAction(&_action1, this);
@@ -430,7 +430,7 @@ void Scene110::Action1::signal() {
case 6:
// Play "Vroum"
scene->_sound.play(31);
- // The guy starts the engine
+ // The guy starts the engine
scene->_object4.setStrip(3);
scene->_object4._frame = 1;
scene->_object4.animate(ANIM_MODE_5, NULL);
@@ -837,7 +837,7 @@ void Scene110::postInit(SceneObjectList *OwnerList) {
_object10._moveDiff.y = 10;
_object10.setPosition(_object9._position);
_object10.hide();
-
+
setAction(&_action1);
}
/*--------------------------------------------------------------------------
@@ -877,7 +877,7 @@ bool Scene114::Door::startAction(CursorType action, Event &event) {
SceneItem::display2(114, 1);
return true;
case CURSOR_USE:
- BF_GLOBALS._walkRegions.proc2(2);
+ BF_GLOBALS._walkRegions.enableRegion(2);
BF_GLOBALS._player.disableControl();
scene->_lyle.fixPriority(-1);
scene->_sceneMode = 1140;
@@ -895,8 +895,8 @@ void Scene114::postInit(SceneObjectList *OwnerList) {
loadScene(110);
setZoomPercents(85, 80, 105, 100);
- BF_GLOBALS._walkRegions.proc1(9);
- BF_GLOBALS._walkRegions.proc1(22);
+ BF_GLOBALS._walkRegions.disableRegion(9);
+ BF_GLOBALS._walkRegions.disableRegion(22);
_door.postInit();
_door.setVisage(110);
@@ -921,7 +921,7 @@ void Scene114::postInit(SceneObjectList *OwnerList) {
_lyle._moveDiff.x = 2;
_lyle._moveDiff.y = 1;
_lyle.hide();
- _lyle.setDetails(114, 2, -1, -1, 1, NULL);
+ _lyle.setDetails(114, 2, -1, -1, 1, (SceneItem *)NULL);
_vechile.postInit();
if (BF_GLOBALS.getFlag(fWithLyle)) {
@@ -943,10 +943,10 @@ void Scene114::postInit(SceneObjectList *OwnerList) {
_vechile.setStrip(1);
_vechile.changeZoom(77);
}
- BF_GLOBALS._walkRegions.proc1(17);
+ BF_GLOBALS._walkRegions.disableRegion(17);
}
BF_GLOBALS._sceneItems.push_front(&_vechile);
- BF_GLOBALS._walkRegions.proc1(2);
+ BF_GLOBALS._walkRegions.disableRegion(2);
if (BF_GLOBALS._sceneManager._previousScene == 115) {
BF_GLOBALS._player.setPosition(Common::Point(219, 100));
@@ -962,7 +962,7 @@ void Scene114::postInit(SceneObjectList *OwnerList) {
BF_GLOBALS._player.enableControl();
}
- _item1.setDetails(Rect(0, 0, 320, 200), 114, 3, -1, -1, 1, NULL);
+ _item1.setDetails(Rect(0, 0, 320, 200), 114, 3, -1, -1, 1, (SceneItem *)NULL);
}
void Scene114::signal() {
@@ -985,9 +985,9 @@ void Scene114::signal() {
* Scene 115 - Inside Tony's bar
*
*--------------------------------------------------------------------------*/
-bool Scene115::Object1::startAction(CursorType action, Event &event) {
+bool Scene115::Kate::startAction(CursorType action, Event &event) {
Scene115 *scene = (Scene115 *)BF_GLOBALS._sceneManager._scene;
-
+
switch (action) {
case CURSOR_LOOK:
SceneItem::display(115, 8, SET_WIDTH, 312,
@@ -1001,7 +1001,7 @@ bool Scene115::Object1::startAction(CursorType action, Event &event) {
BF_GLOBALS._player.disableControl();
scene->_sceneMode = 0;
scene->_stripManager.start(1174, scene);
- } else if (scene->_field31E8 == 0) {
+ } else if (scene->_jukeboxPlaying == 0) {
if (BF_GLOBALS.getFlag(fShowedIdToKate)) {
BF_GLOBALS._player.disableControl();
scene->_sceneMode = 0;
@@ -1014,10 +1014,10 @@ bool Scene115::Object1::startAction(CursorType action, Event &event) {
scene->setAction(&scene->_action7);
return true;
case INV_MUG_SHOT:
- if (scene->_field31E8 == 0) {
+ if (scene->_jukeboxPlaying == 0) {
BF_GLOBALS._player.disableControl();
scene->_sceneMode = 0;
- if (BF_GLOBALS._v4CEAA == 0)
+ if (BF_GLOBALS._tonyDialogCtr == 0)
scene->_stripManager.start(1167, scene);
else if (BF_GLOBALS.getFlag(fShowedIdToKate))
scene->_stripManager.start(1159, scene);
@@ -1035,8 +1035,8 @@ bool Scene115::Object1::startAction(CursorType action, Event &event) {
SET_EXT_FGCOLOR, 13, LIST_END);
return true;
case INV_ID:
- if (scene->_field31E8 == 0) {
- if (BF_GLOBALS._v4CEAA == 0) {
+ if (scene->_jukeboxPlaying == 0) {
+ if (BF_GLOBALS._tonyDialogCtr == 0) {
scene->_sceneMode = 1167;
scene->setAction(&scene->_action6);
} else if (BF_GLOBALS.getFlag(fShowedIdToKate)) {
@@ -1059,9 +1059,9 @@ bool Scene115::Object1::startAction(CursorType action, Event &event) {
}
}
-bool Scene115::Object2::startAction(CursorType action, Event &event) {
+bool Scene115::Tony::startAction(CursorType action, Event &event) {
Scene115 *scene = (Scene115 *)BF_GLOBALS._sceneManager._scene;
-
+
switch (action) {
case CURSOR_LOOK:
SceneItem::display(115, 7, SET_WIDTH, 312,
@@ -1077,25 +1077,25 @@ bool Scene115::Object2::startAction(CursorType action, Event &event) {
else if (BF_INVENTORY.getObjectScene(INV_COBB_RAP) == 1) {
if (BF_GLOBALS.getFlag(fTalkedToTony))
scene->_sceneMode = 1151;
- else if (BF_GLOBALS._v4CEAA == 0) {
+ else if (BF_GLOBALS._tonyDialogCtr == 0) {
scene->_sceneMode = 1150;
BF_GLOBALS.setFlag(fTalkedToTony);
} else
scene->_sceneMode = 1151;
- } else if (_field15F8 == 0) {
- _field15F8++;
+ } else if (_talkToTonyCtr2 == 0) {
+ _talkToTonyCtr2++;
scene->_sceneMode = 1171;
} else
scene->_sceneMode = 1172;
} else if (BF_GLOBALS.getFlag(onDuty)) {
- if (scene->_field31EA == 0) {
- scene->_field31EA = 1;
+ if (scene->_talkToTonyCtr == 0) {
+ scene->_talkToTonyCtr = 1;
scene->_sceneMode = 1169;
} else
scene->_sceneMode = 1170;
- } else if (scene->_field31EA == 0) {
+ } else if (scene->_talkToTonyCtr == 0) {
scene->_sceneMode = 1171;
- scene->_field31EA = 1;
+ scene->_talkToTonyCtr = 1;
} else
scene->_sceneMode = 1172;
@@ -1111,7 +1111,7 @@ bool Scene115::Object2::startAction(CursorType action, Event &event) {
case INV_COBB_RAP:
if (BF_GLOBALS.getFlag(onDuty))
scene->_sceneMode = 1177;
- else if (BF_GLOBALS._v4CEAA == 0)
+ else if (BF_GLOBALS._tonyDialogCtr == 0)
scene->_sceneMode = 1179;
else
scene->_sceneMode = 1154;
@@ -1132,16 +1132,16 @@ bool Scene115::Object2::startAction(CursorType action, Event &event) {
} else {
T2_GLOBALS._uiElements.addScore(30);
BF_GLOBALS.setFlag(fTalkedToTony);
- if (BF_GLOBALS._v4CEAA == 0) {
+ if (BF_GLOBALS._tonyDialogCtr == 0) {
scene->_sceneMode = 1150;
scene->setAction(&scene->_action9);
} else {
- BF_GLOBALS._v4CEAA = 1;
+ BF_GLOBALS._tonyDialogCtr = 1;
scene->setAction(&scene->_action2);
}
}
- } else if (_field15F8 == 0) {
- _field15F8++;
+ } else if (_talkToTonyCtr2 == 0) {
+ _talkToTonyCtr2++;
if (BF_GLOBALS.getFlag(onDuty)) {
scene->_sceneMode = 1182;
scene->setAction(&scene->_action9);
@@ -1164,7 +1164,7 @@ bool Scene115::Object2::startAction(CursorType action, Event &event) {
bool Scene115::Object3::startAction(CursorType action, Event &event) {
Scene115 *scene = (Scene115 *)BF_GLOBALS._sceneManager._scene;
-
+
switch (action) {
case CURSOR_LOOK:
SceneItem::display(115, 9, SET_WIDTH, 312,
@@ -1195,7 +1195,7 @@ bool Scene115::Object3::startAction(CursorType action, Event &event) {
bool Scene115::Object4::startAction(CursorType action, Event &event) {
Scene115 *scene = (Scene115 *)BF_GLOBALS._sceneManager._scene;
-
+
switch (action) {
case CURSOR_LOOK:
SceneItem::display(115, 42, SET_WIDTH, 312,
@@ -1215,24 +1215,23 @@ bool Scene115::Object4::startAction(CursorType action, Event &event) {
}
}
-void Scene115::Item1::signal() {
+void Scene115::Jukebox::signal() {
Scene115 *scene = (Scene115 *)BF_GLOBALS._sceneManager._scene;
-
- if (_field1F8A == 2)
- _field1F8A = 0;
- if (_field1F8A == 1) {
- _field1F8A = 2;
+ if (_jokeboxPlayingCtr == 2)
+ _jokeboxPlayingCtr = 0;
+ else if (_jokeboxPlayingCtr == 1) {
+ _jokeboxPlayingCtr = 2;
setAction(&_sequenceManager6, this, 118, &scene->_object12, &scene->_object11, NULL);
}
}
-bool Scene115::Item1::startAction(CursorType action, Event &event) {
+bool Scene115::Jukebox::startAction(CursorType action, Event &event) {
Scene115 *scene = (Scene115 *)BF_GLOBALS._sceneManager._scene;
-
+
if (action == CURSOR_USE) {
- if (_field1F8A == 0) {
- _field1F8A = 1;
+ if (_jokeboxPlayingCtr == 0) {
+ _jokeboxPlayingCtr = 1;
BF_GLOBALS._player.disableControl();
scene->setAction(&scene->_action4);
} else
@@ -1242,31 +1241,31 @@ bool Scene115::Item1::startAction(CursorType action, Event &event) {
SET_FONT, 4, SET_BG_COLOR, 1, SET_FG_COLOR, 19, SET_EXT_BGCOLOR, 9,
SET_EXT_FGCOLOR, 13, LIST_END);
return true;
- } else
+ } else
return NamedHotspot::startAction(action, event);
}
-void Scene115::Item1::synchronize(Serializer &s) {
+void Scene115::Jukebox::synchronize(Serializer &s) {
NamedHotspot::synchronize(s);
- s.syncAsSint16LE(_field1F8A);
+ s.syncAsSint16LE(_jokeboxPlayingCtr);
}
-Scene115::Item1::Item1() {
- _field1F8A = 0;
+Scene115::Jukebox::Jukebox() {
+ _jokeboxPlayingCtr = 0;
}
void Scene115::EventHandler1::dispatch() {
Scene115 *scene = (Scene115 *)BF_GLOBALS._sceneManager._scene;
if (BF_GLOBALS._player.getRegionIndex() == 27) {
- scene->_object1.setAction(&scene->_action5);
+ scene->_kate.setAction(&scene->_action5);
scene->removeTimer(this);
}
}
bool Scene115::Item10::startAction(CursorType action, Event &event) {
Scene115 *scene = (Scene115 *)BF_GLOBALS._sceneManager._scene;
-
+
if (BF_GLOBALS.getFlag(fWithLyle)) {
scene->_object4.setStrip2(6);
Common::Point pt(-20, 122);
@@ -1339,20 +1338,20 @@ void Scene115::Action2::signal() {
switch (_actionIndex++) {
case 0:
BF_GLOBALS._player.disableControl();
- if (BF_GLOBALS._v4CEAA < 3) {
- if (scene->_object2._position.x > 67) {
- scene->_object2.setAction(&scene->_sequenceManager3, NULL, 1118, &scene->_object2, NULL);
- } else if (scene->_object2._position.x != 67) {
- scene->_object2.setAction(&scene->_sequenceManager3, NULL, 1119, &scene->_object2, NULL);
+ if (BF_GLOBALS._tonyDialogCtr < 3) {
+ if (scene->_tony._position.x > 67) {
+ scene->_tony.setAction(&scene->_sequenceManager3, NULL, 1118, &scene->_tony, NULL);
+ } else if (scene->_tony._position.x != 67) {
+ scene->_tony.setAction(&scene->_sequenceManager3, NULL, 1119, &scene->_tony, NULL);
}
}
BF_GLOBALS._player.setAction(&scene->_sequenceManager1, this, 1117, &BF_GLOBALS._player);
break;
case 1:
- BF_GLOBALS._v4CEAA++;
+ ++BF_GLOBALS._tonyDialogCtr;
if (BF_GLOBALS.getFlag(onDuty)) {
if (BF_GLOBALS.getFlag(fTalkedToTony)) {
- switch (BF_GLOBALS._v4CEAA) {
+ switch (BF_GLOBALS._tonyDialogCtr) {
case 1:
T2_GLOBALS._uiElements.addScore(30);
scene->_stripManager.start(1181, this);
@@ -1369,7 +1368,7 @@ void Scene115::Action2::signal() {
}
} else {
if (BF_GLOBALS.getFlag(fTalkedToTony)) {
- switch (BF_GLOBALS._v4CEAA) {
+ switch (BF_GLOBALS._tonyDialogCtr) {
case 1:
T2_GLOBALS._uiElements.addScore(30);
scene->_stripManager.start(1153, this);
@@ -1387,8 +1386,8 @@ void Scene115::Action2::signal() {
}
break;
case 2:
- if (BF_GLOBALS._v4CEAA == 3)
- scene->_object2.setAction(&scene->_sequenceManager3, NULL, 3119, &scene->_object2, NULL);
+ if (BF_GLOBALS._tonyDialogCtr == 3)
+ scene->_tony.setAction(&scene->_sequenceManager3, NULL, 3119, &scene->_tony, NULL);
BF_GLOBALS._player.enableControl();
remove();
default:
@@ -1399,7 +1398,7 @@ void Scene115::Action2::signal() {
void Scene115::Action3::signal() {
Scene115 *scene = (Scene115 *)BF_GLOBALS._sceneManager._scene;
- setAction(&scene->_sequenceManager4, this, 3117, &scene->_object7, NULL);
+ setAction(&scene->_sequenceManager4, this, 3117, &scene->_neonSign, NULL);
}
void Scene115::Action4::signal() {
@@ -1426,7 +1425,7 @@ void Scene115::Action4::signal() {
setAction(&scene->_sequenceManager1, this, 117, &scene->_object12, &scene->_object11, NULL);
break;
case 3:
- scene->_sound1.play(81, &scene->_item1, 127);
+ scene->_sound1.play(81, &scene->_itemJukebox, 127);
BF_GLOBALS._player.enableControl();
remove();
default:
@@ -1439,10 +1438,11 @@ void Scene115::Action5::signal() {
switch (_actionIndex++) {
case 0:
- if (scene->_item1._field1F8A == 0) {
- setAction(&scene->_sequenceManager5, this, 1115, &scene->_object1, NULL);
+ if (scene->_itemJukebox._jokeboxPlayingCtr == 0) {
+ setAction(&scene->_sequenceManager5, this, 1115, &scene->_kate, NULL);
+ scene->_jukeboxPlaying = 1;
} else {
- _actionIndex--;
+ --_actionIndex;
setDelay(120);
}
break;
@@ -1450,15 +1450,15 @@ void Scene115::Action5::signal() {
setAction(&scene->_sequenceManager5, this, 117, &scene->_object12, &scene->_object11, NULL);
break;
case 2:
- scene->_sound1.play(81, &scene->_item1, 127);
- scene->_item1._field1F8A = 1;
+ scene->_sound1.play(81, &scene->_itemJukebox, 127);
+ scene->_itemJukebox._jokeboxPlayingCtr = 1;
setDelay(3);
break;
case 3:
- setAction(&scene->_sequenceManager5, this, 1116, &scene->_object1, NULL);
+ setAction(&scene->_sequenceManager5, this, 1116, &scene->_kate, NULL);
break;
case 4:
- scene->_field31E8 = 0;
+ scene->_jukeboxPlaying = 0;
remove();
default:
break;
@@ -1471,22 +1471,22 @@ void Scene115::Action6::signal() {
switch (_actionIndex++) {
case 0:
BF_GLOBALS._player.disableControl();
- BF_GLOBALS._player.setAction(&scene->_sequenceManager1, this, 2115, &scene->_object1, &BF_GLOBALS._player, NULL);
+ BF_GLOBALS._player.setAction(&scene->_sequenceManager1, this, 2115, &scene->_kate, &BF_GLOBALS._player, NULL);
break;
case 1:
if (scene->_sceneMode == 9999) {
- setAction(&scene->_sequenceManager1, this, 4115, &scene->_object1, &BF_GLOBALS._player, NULL);
- _actionIndex--;
+ setAction(&scene->_sequenceManager1, this, 4115, &scene->_kate, &BF_GLOBALS._player, NULL);
+ --_actionIndex;
scene->_sceneMode = 1166;
} else {
scene->_stripManager.start(scene->_sceneMode, this);
}
break;
case 2:
- scene->_object1.setVisage(131);
- scene->_object1.setStrip(1);
- scene->_object1.setFrame(1);
- scene->_object1.setPosition(Common::Point(122, 97));
+ scene->_kate.setVisage(131);
+ scene->_kate.setStrip(1);
+ scene->_kate.setFrame(1);
+ scene->_kate.setPosition(Common::Point(122, 97));
BF_GLOBALS._player.enableControl();
remove();
default:
@@ -1507,11 +1507,11 @@ void Scene115::Action7::signal() {
break;
case 1:
BF_GLOBALS._player.setStrip(4);
- if (BF_GLOBALS._v4CEB0 == 0)
+ if (BF_GLOBALS._kateDialogCtr == 0)
scene->_stripManager.start(1156, this);
else
scene->_stripManager.start(1157, this);
- BF_GLOBALS._v4CEB0++;
+ ++BF_GLOBALS._kateDialogCtr;
break;
case 2:
BF_GLOBALS._player.enableControl();
@@ -1528,11 +1528,11 @@ void Scene115::Action8::signal() {
switch (_actionIndex++) {
case 0:
BF_GLOBALS._player.disableControl();
- setAction(&scene->_sequenceManager1, this, 2115, &scene->_object1, &BF_GLOBALS._player, NULL);
+ setAction(&scene->_sequenceManager1, this, 2115, &scene->_kate, &BF_GLOBALS._player, NULL);
break;
case 1:
T2_GLOBALS._uiElements.addScore(30);
- setAction(&scene->_sequenceManager1, this, 4115, &scene->_object1, &BF_GLOBALS._player, NULL);
+ setAction(&scene->_sequenceManager1, this, 4115, &scene->_kate, &BF_GLOBALS._player, NULL);
break;
case 2:
scene->_stripManager.start(1160, this);
@@ -1542,15 +1542,15 @@ void Scene115::Action8::signal() {
break;
case 4:
BF_GLOBALS.setFlag(fGivenNapkin);
- setAction(&scene->_sequenceManager1, this, 2117, &scene->_object1, &BF_GLOBALS._player, &scene->_object13, NULL);
+ setAction(&scene->_sequenceManager1, this, 2117, &scene->_kate, &BF_GLOBALS._player, &scene->_object13, NULL);
break;
case 5:
BF_INVENTORY.setObjectScene(INV_NAPKIN, 1);
T2_GLOBALS._uiElements.addScore(10);
- scene->_object1.setVisage(131);
- scene->_object1.setStrip(1);
- scene->_object1.setFrame(1);
- scene->_object1.setPosition(Common::Point(122, 97));
+ scene->_kate.setVisage(131);
+ scene->_kate.setStrip(1);
+ scene->_kate.setFrame(1);
+ scene->_kate.setPosition(Common::Point(122, 97));
BF_GLOBALS._player.enableControl();
remove();
break;
@@ -1565,17 +1565,17 @@ void Scene115::Action9::signal() {
switch (_actionIndex++) {
case 0:
BF_GLOBALS._player.disableControl();
- if (scene->_object2._position.x > 67)
- scene->_object2.setAction(&scene->_sequenceManager3, NULL, 1118, &scene->_object2, NULL);
- else if (scene->_object2._position.x != 67)
- scene->_object2.setAction(&scene->_sequenceManager3, NULL, 1119, &scene->_object2, NULL);
+ if (scene->_tony._position.x > 67)
+ scene->_tony.setAction(&scene->_sequenceManager3, NULL, 1118, &scene->_tony, NULL);
+ else if (scene->_tony._position.x != 67)
+ scene->_tony.setAction(&scene->_sequenceManager3, NULL, 1119, &scene->_tony, NULL);
BF_GLOBALS._player.setAction(&scene->_sequenceManager1, this, 1117, &BF_GLOBALS._player, NULL);
break;
case 1:
scene->_stripManager.start(scene->_sceneMode, this);
break;
case 2:
- scene->_object2.setAction(&scene->_sequenceManager3, this, 3119, &scene->_object2, NULL);
+ scene->_tony.setAction(&scene->_sequenceManager3, this, 3119, &scene->_tony, NULL);
break;
case 3:
BF_GLOBALS._player.enableControl();
@@ -1586,16 +1586,16 @@ void Scene115::Action9::signal() {
}
Scene115::Scene115() : SceneExt () {
- _field168A = _field31E8 = _field31EA = 0;
+ _lineNumModifier = _jukeboxPlaying = _talkToTonyCtr = 0;
}
void Scene115::postInit(SceneObjectList *OwnerList) {
SceneExt::postInit();
-
+
BF_GLOBALS._sound1.fadeSound(15);
loadScene(115);
setZoomPercents(98, 85, 115, 100);
- _field31E8 = 0;
+ _jukeboxPlaying = 0;
_stripManager.addSpeaker(&_gameTextSpeaker);
_stripManager.addSpeaker(&_kateSpeaker);
_stripManager.addSpeaker(&_tonySpeaker);
@@ -1620,28 +1620,28 @@ void Scene115::postInit(SceneObjectList *OwnerList) {
_object5.fixPriority(95);
// Bartender
- _object2.postInit();
- _object2.setVisage(132);
- _object2.setPosition(Common::Point(74, 66));
- _object2.setStrip(3);
- _object2.setFrame(1);
- _object2.fixPriority(95);
- _object2.animate(ANIM_MODE_2, NULL);
- _object2._numFrames = 5;
- _object2._field15F8 = 0;
- _field31EA = 0;
+ _tony.postInit();
+ _tony.setVisage(132);
+ _tony.setPosition(Common::Point(74, 66));
+ _tony.setStrip(3);
+ _tony.setFrame(1);
+ _tony.fixPriority(95);
+ _tony.animate(ANIM_MODE_2, NULL);
+ _tony._numFrames = 5;
+ _tony._talkToTonyCtr2 = 0;
+ _talkToTonyCtr = 0;
//Neon sign
- _object7.postInit();
- _object7.setVisage(115);
- _object7.setStrip(4);
- _object7.setFrame(1);
- _object7.setPosition(Common::Point(262, 29));
- _object7.setAction(&_action3);
+ _neonSign.postInit();
+ _neonSign.setVisage(115);
+ _neonSign.setStrip(4);
+ _neonSign.setFrame(1);
+ _neonSign.setPosition(Common::Point(262, 29));
+ _neonSign.setAction(&_action3);
_object11.postInit();
_object11.hide();
-
+
_object12.postInit();
_object12.hide();
@@ -1665,7 +1665,7 @@ void Scene115::postInit(SceneObjectList *OwnerList) {
NpcMover *mover = new NpcMover();
_object4.addMover(mover, &destPos, NULL);
BF_GLOBALS._sceneItems.push_front(&_object4);
- BF_GLOBALS._walkRegions.proc1(1);
+ BF_GLOBALS._walkRegions.disableRegion(1);
} else if (BF_GLOBALS.getFlag(onDuty))
BF_GLOBALS._player.setVisage(1341);
@@ -1674,7 +1674,7 @@ void Scene115::postInit(SceneObjectList *OwnerList) {
_object3.setVisage(123);
_object3.setPosition(Common::Point(212, 108));
_object3.setAction(&_action1);
- _field168A = 0;
+ _lineNumModifier = 0;
BF_GLOBALS._sceneItems.push_front(&_object3);
_object8.postInit();
@@ -1696,18 +1696,18 @@ void Scene115::postInit(SceneObjectList *OwnerList) {
_object10.fixPriority(112);
if (BF_INVENTORY.getObjectScene(INV_COBB_RAP) == 1) {
- _object1.postInit();
- _object1.setVisage(131);
- _object1.setPosition(Common::Point(122, 97));
- _object1.setStrip(1);
- _object1.setFrame(1);
- _object1.changeZoom(100);
- _object1.fixPriority(95);
- BF_GLOBALS._sceneItems.push_front(&_object1);
+ _kate.postInit();
+ _kate.setVisage(131);
+ _kate.setPosition(Common::Point(122, 97));
+ _kate.setStrip(1);
+ _kate.setFrame(1);
+ _kate.changeZoom(100);
+ _kate.fixPriority(95);
+ BF_GLOBALS._sceneItems.push_front(&_kate);
}
addTimer(&_eventHandler1);
}
- BF_GLOBALS._sceneItems.push_front(&_object2);
+ BF_GLOBALS._sceneItems.push_front(&_tony);
_item11.setDetails(16, 115, 4, 15, 21, 1);
_item12.setDetails(20, 115, 5, 15, 21, 1);
@@ -1716,8 +1716,8 @@ void Scene115::postInit(SceneObjectList *OwnerList) {
BF_GLOBALS._sceneItems.push_front(&_item14);
_item10.setDetails(Rect(0, 147, 30, 167), 115, -1, -1, -1, 1, NULL);
// SUB_177B8
- addTimer(&_item1);
- _item1.setDetails(Rect(147, 45, 179, 91), 115, 25, 26, 27, 1, NULL);
+ addTimer(&_itemJukebox);
+ _itemJukebox.setDetails(Rect(147, 45, 179, 91), 115, 25, 26, 27, 1, NULL);
//
_item6.setDetails(Rect(107, 43, 122, 61), 115, 28, 29, 30, 1, NULL);
_item7.setDetails(Rect(180, 33, 230, 63), 115, 31, 32, 33, 1, NULL);
@@ -1741,14 +1741,14 @@ void Scene115::signal() {
break;
case 1:
BF_GLOBALS._player.updateAngle(_object3._position);
- SceneItem::display(115, 38 + _field168A, SET_WIDTH, 312,
+ SceneItem::display(115, 38 + _lineNumModifier, SET_WIDTH, 312,
SET_X, GLOBALS._sceneManager._scene->_sceneBounds.left + 4,
SET_Y, GLOBALS._sceneManager._scene->_sceneBounds.top + UI_INTERFACE_Y + 2,
SET_FONT, 4, SET_BG_COLOR, 1, SET_FG_COLOR, 19, SET_EXT_BGCOLOR, 9,
SET_EXT_FGCOLOR, 13, LIST_END);
- _field168A++;
- if (_field168A >= 4)
- _field168A = 0;
+ ++_lineNumModifier;
+ if (_lineNumModifier >= 4)
+ _lineNumModifier = 0;
// No break on purpose
case 0:
// No break on purpose
@@ -1777,9 +1777,9 @@ void Scene115::process(Event &event) {
void Scene115::synchronize(Serializer &s) {
SceneExt::synchronize(s);
- s.syncAsSint16LE(_field168A);
- s.syncAsSint16LE(_field31E8);
- s.syncAsSint16LE(_field31EA);
+ s.syncAsSint16LE(_lineNumModifier);
+ s.syncAsSint16LE(_jukeboxPlaying);
+ s.syncAsSint16LE(_talkToTonyCtr);
}
/*--------------------------------------------------------------------------
@@ -1817,7 +1817,7 @@ void Scene125::Action1::signal() {
case 0:
// No break on purpose
default:
- break;
+ break;
}
}
@@ -2054,7 +2054,7 @@ void Scene125::Action3::dispatch() {
SceneObject *owner = static_cast<SceneObject *>(this->_owner);
Action::dispatch();
-
+
if ((_actionIndex == 9) && (owner->_percent > 70))
owner->changeZoom(owner->_percent - 1);
}
@@ -2095,7 +2095,7 @@ void Scene125::Action4::dispatch() {
SceneObject *owner = static_cast<SceneObject *>(this->_owner);
Action::dispatch();
-
+
if ((_actionIndex == 4) && (owner->_percent > 80))
owner->changeZoom(owner->_percent - 1);
}
@@ -2134,7 +2134,7 @@ void Scene125::Action6::dispatch() {
SceneObject *owner = static_cast<SceneObject *>(this->_owner);
Action::dispatch();
-
+
if ((_actionIndex == 2) && (owner->_percent < 100))
owner->changeZoom(owner->_percent + 1);
}
@@ -2169,7 +2169,7 @@ void Scene125::postInit(SceneObjectList *OwnerList) {
BF_GLOBALS._player._moveDiff.x = 6;
BF_GLOBALS._player._moveDiff.y = 6;
BF_GLOBALS._player.disableControl();
-
+
_object5.postInit();
_object5.setVisage(128);
_object5.setPosition(Common::Point(150, 117));
@@ -2457,7 +2457,7 @@ void Scene160::Action1::signal() {
scene->_kid.setStrip(2);
scene->_kid.animate(ANIM_MODE_5, this);
- scene->_kidBody.setPosition(scene->_kid._position);
+ scene->_kidBody.setPosition(scene->_kid._position);
scene->_kidBody.setFrame(1);
scene->_kidBody.setStrip(3);
break;
@@ -2630,7 +2630,7 @@ void Scene160::Action2::signal() {
break;
case 25:
BF_GLOBALS._sound1.fade(0, 10, 10, true, this);
-// FIXME: Currently, fade() doesn't end properly with this song,
+// FIXME: Currently, fade() doesn't end properly with this song,
// thus never returns here. This hack skips the wait and changes
// directly to the next scene
// Start of hack
@@ -2764,12 +2764,12 @@ bool Scene180::GarageExit::startAction(CursorType action, Event &event) {
/*--------------------------------------------------------------------------*/
Scene180::Scene180(): SceneExt() {
- _fieldC56 = 0;
+ _dispatchMode = 0;
}
void Scene180::synchronize(Serializer &s) {
SceneExt::synchronize(s);
- s.syncAsSint16LE(_fieldC56);
+ s.syncAsSint16LE(_dispatchMode);
}
void Scene180::postInit(SceneObjectList *OwnerList) {
@@ -2784,7 +2784,7 @@ void Scene180::postInit(SceneObjectList *OwnerList) {
_garageExit.setDetails(Rect(243, 93, 275, 122), 180, -1, -1, -1, 1, NULL);
_gameTextSpeaker._textPos.y = 180;
_stripManager.addSpeaker(&_gameTextSpeaker);
- _fieldC56 = 0;
+ _dispatchMode = 0;
setZoomPercents(121, 60, 125, 70);
if ((BF_GLOBALS._bookmark == bLyleStoppedBy) && (BF_GLOBALS._dayNumber == 1)) {
@@ -2830,7 +2830,7 @@ void Scene180::postInit(SceneObjectList *OwnerList) {
_vechile.setStrip(2);
_vechile.setPosition(Common::Point(262, 131));
_vechile.setZoom(65);
- _vechile.setDetails(180, 33, 34, 35, 1, NULL);
+ _vechile.setDetails(180, 33, 34, 35, 1, (SceneItem *)NULL);
_object1.postInit();
_object1.setVisage(182);
@@ -2845,7 +2845,7 @@ void Scene180::postInit(SceneObjectList *OwnerList) {
BF_GLOBALS._player.disableControl();
_vechile.postInit();
- _vechile.setDetails(180, 33, 34, 35, 1, NULL);
+ _vechile.setDetails(180, 33, 34, 35, 1, (SceneItem *)NULL);
_object1.postInit();
@@ -2874,7 +2874,7 @@ void Scene180::postInit(SceneObjectList *OwnerList) {
_vechile._moveDiff = Common::Point(40, 5);
_vechile.setPosition(Common::Point(-25, 171));
- _fieldC56 = 1;
+ _dispatchMode = 1;
BF_GLOBALS._sound1.play(29);
_sceneMode = 1;
@@ -2895,15 +2895,15 @@ void Scene180::postInit(SceneObjectList *OwnerList) {
_vechile.setStrip(3);
_vechile._frame = 5;
_vechile.changeZoom(75);
-
- _fieldC56 = 1;
+
+ _dispatchMode = 1;
_vechile._moveDiff.x = 45;
} else {
_vechile.setVisage(444);
_vechile.setStrip(2);
_vechile.changeZoom(85);
- _fieldC56 = 3;
+ _dispatchMode = 3;
_vechile._moveDiff.x = 30;
}
@@ -2935,7 +2935,7 @@ void Scene180::postInit(SceneObjectList *OwnerList) {
void Scene180::signal() {
switch (_sceneMode) {
case 1:
- _fieldC56 = 0;
+ _dispatchMode = 0;
switch (BF_GLOBALS._bookmark) {
case bFlashBackThree:
BF_GLOBALS._bookmark = bDroppedOffLyle;
@@ -2953,12 +2953,12 @@ void Scene180::signal() {
setAction(&_sequenceManager, this, 1802, &_vechile, &_object1, NULL);
break;
case 2:
- _fieldC56 = 0;
+ _dispatchMode = 0;
BF_GLOBALS._sound1.fadeOut2(NULL);
BF_GLOBALS._sceneManager.changeScene(BF_GLOBALS._driveToScene);
break;
case 3:
- _fieldC56 = 0;
+ _dispatchMode = 0;
BF_GLOBALS._sound1.stop();
_stripManager.start(1800, this);
_sceneMode = 4;
@@ -2997,7 +2997,7 @@ void Scene180::signal() {
BF_GLOBALS._player.disableControl();
_vechile.postInit();
- _vechile.setDetails(180, 33, 34, 35, 1, NULL);
+ _vechile.setDetails(180, 33, 34, 35, 1, (SceneItem *)NULL);
_object1.postInit();
_sceneMode = 1801;
@@ -3040,7 +3040,7 @@ void Scene180::signal() {
}
break;
case 1800:
- _fieldC56 = 2;
+ _dispatchMode = 2;
_vechile._moveDiff.x = 10;
_sceneMode = 2;
ADD_MOVER(_vechile, -25, 171);
@@ -3079,7 +3079,7 @@ void Scene180::process(Event &event) {
}
void Scene180::dispatch() {
- switch (_fieldC56) {
+ switch (_dispatchMode) {
case 1:
if (_vechile._mover && (_vechile._percent > 50))
_vechile.changeZoom(_vechile._percent - 1);
@@ -3123,7 +3123,7 @@ void Scene180::dispatch() {
*
*--------------------------------------------------------------------------*/
-bool Scene190::Object4::startAction(CursorType action, Event &event) {
+bool Scene190::LyleCar::startAction(CursorType action, Event &event) {
Scene190 *scene = (Scene190 *)BF_GLOBALS._sceneManager._scene;
switch (action) {
@@ -3191,14 +3191,14 @@ void Scene190::Action1::signal() {
}
case 2:
scene->_sound.play(82);
- scene->_object2.animate(ANIM_MODE_5, this);
+ scene->_door.animate(ANIM_MODE_5, this);
break;
case 3:
ADD_MOVER(BF_GLOBALS._player, 180, 86);
break;
case 4:
scene->_sound.play(82);
- scene->_object2.animate(ANIM_MODE_6, this);
+ scene->_door.animate(ANIM_MODE_6, this);
break;
case 5:
BF_GLOBALS._sound1.fadeOut2(NULL);
@@ -3220,12 +3220,17 @@ void Scene190::postInit(SceneObjectList *OwnerList) {
(BF_GLOBALS._sceneManager._previousScene == 20)) {
// clearScreen();
}
- if (BF_GLOBALS._dayNumber == 0)
+ if (BF_GLOBALS._dayNumber == 0) {
// If at start of game, change to first day
BF_GLOBALS._dayNumber = 1;
+ // To be checked: Not present in the original
+ g_globals->_sceneManager._previousScene = 100;
+ }
+ SceneExt::postInit();
// Load the scene data
loadScene(190);
+
BF_GLOBALS._scenePalette.loadPalette(2);
_stripManager.addSpeaker(&_speaker);
@@ -3233,18 +3238,20 @@ void Scene190::postInit(SceneObjectList *OwnerList) {
BF_GLOBALS._player.disableControl();
// Initialise objects
- _object2.postInit();
- _object2.setVisage(190);
- _object2.setStrip(1);
- _object2.setPosition(Common::Point(179, 88));
+ _door.postInit();
+ _door.setVisage(190);
+ _door.setStrip(1);
+ _door.setPosition(Common::Point(179, 88));
- _object3.postInit();
- _object3.setVisage(190);
- _object3.setStrip(2);
- _object3.fixPriority(200);
- _object3.setPosition(Common::Point(170, 31));
- _object3.animate(ANIM_MODE_7, 0, NULL);
- _object3.setDetails(190, 8, 26, 19, 1, NULL);
+ _flag.postInit();
+ _flag.setVisage(190);
+ _flag.setStrip(2);
+ _flag.fixPriority(200);
+ _flag.setPosition(Common::Point(170, 31));
+ _flag.animate(ANIM_MODE_7, 0, NULL);
+ _flag.setDetails(190, 8, 26, 19, 1, (SceneItem *)NULL);
+
+ _fieldB52 = true;
if (BF_GLOBALS.getFlag(fWithLyle)) {
BF_GLOBALS._player.setVisage(303);
@@ -3252,11 +3259,11 @@ void Scene190::postInit(SceneObjectList *OwnerList) {
BF_GLOBALS._player.animate(ANIM_MODE_1, NULL);
BF_GLOBALS._player._moveDiff = Common::Point(3, 1);
- _object4.postInit();
- _object4.setVisage(444);
- _object4.setFrame(2);
- _object4.setPosition(Common::Point(54, 114));
- _object4.setDetails(190, -1, -1, -1, 1, NULL);
+ _lyleCar.postInit();
+ _lyleCar.setVisage(444);
+ _lyleCar.setFrame(2);
+ _lyleCar.setPosition(Common::Point(54, 114));
+ _lyleCar.setDetails(190, -1, -1, -1, 1, (SceneItem *)NULL);
switch (BF_GLOBALS._sceneManager._previousScene) {
case 300: {
@@ -3267,7 +3274,7 @@ void Scene190::postInit(SceneObjectList *OwnerList) {
}
case 315:
_sceneMode = 1901;
- setAction(&_sequenceManager, this, 1901, &BF_GLOBALS._player, &_object2, NULL);
+ setAction(&_sequenceManager, this, 1901, &BF_GLOBALS._player, &_door, NULL);
break;
case 50:
case 60:
@@ -3301,13 +3308,14 @@ void Scene190::postInit(SceneObjectList *OwnerList) {
case 315:
BF_GLOBALS._player._moveDiff = Common::Point(3, 1);
_sceneMode = BF_GLOBALS.getFlag(onDuty) ? 1900 : 1901;
- setAction(&_sequenceManager, this, _sceneMode, &BF_GLOBALS._player, &_object2, NULL);
+ setAction(&_sequenceManager, this, _sceneMode, &BF_GLOBALS._player, &_door, NULL);
break;
case 50:
case 60:
default:
BF_GLOBALS.setFlag(onBike);
BF_GLOBALS._player.disableControl();
+ // To be checked: Not present in the original
T2_GLOBALS._uiElements._active = true;
_sceneMode = BF_GLOBALS.getFlag(onDuty) ? 192 : 190;
setAction(&_sequenceManager, this, _sceneMode, &BF_GLOBALS._player, NULL);
@@ -3394,6 +3402,11 @@ void Scene190::dispatch() {
}
}
+void Scene190::synchronize(Serializer &s) {
+ SceneExt::synchronize(s);
+ s.syncAsSint16LE(_fieldB52);
+}
+
} // End of namespace BlueForce
} // End of namespace TsAGE
diff --git a/engines/tsage/blue_force/blueforce_scenes1.h b/engines/tsage/blue_force/blueforce_scenes1.h
index bdf414ec9b..ddde200370 100644
--- a/engines/tsage/blue_force/blueforce_scenes1.h
+++ b/engines/tsage/blue_force/blueforce_scenes1.h
@@ -99,11 +99,12 @@ public:
SequenceManager _sequenceManager1, _sequenceManager2, _sequenceManager3;
SequenceManager _sequenceManager4, _sequenceManager5, _sequenceManager6;
SequenceManager _sequenceManager7, _sequenceManager8;
- SceneObject _object1, _object2, _protaginist2, _protaginist1, _object5;
- SceneObject _drunk, _object7, _bartender, _object9, _object10;
+ SceneObject _object1, _object2, _protaginist2, _protaginist1, _cop1;
+ SceneObject _drunk, _cop2, _bartender, _beerSign, _animationInset;
IntroSceneText _text;
Action1 _action1;
- Action _action2, _action3;
+ Action2 _action2;
+ Action3 _action3;
public:
Scene109();
@@ -136,7 +137,7 @@ class Scene110: public SceneExt {
virtual void signal();
};
public:
- NamedObject _object1, _object2, _object3, _object4, _object5, _object6, _object7, _object8, _object9, _object10;
+ NamedObject _object1, _object2, _object3, _object4, _object5, _object6, _object7, _object8, _object9, _object10;
ASound _sound;
Action1 _action1;
Action2 _action2;
@@ -170,13 +171,13 @@ public:
class Scene115: public SceneExt {
/* Objects */
- class Object1: public NamedObject {
+ class Kate: public NamedObject {
public:
virtual bool startAction(CursorType action, Event &event);
};
- class Object2: public NamedObject {
+ class Tony: public NamedObject {
public:
- int _field15F8;
+ int _talkToTonyCtr2;
virtual bool startAction(CursorType action, Event &event);
};
class Object3: public NamedObject {
@@ -196,12 +197,12 @@ class Scene115: public SceneExt {
};
/* Items */
- class Item1: public NamedHotspot {
+ class Jukebox: public NamedHotspot {
SequenceManager _sequenceManager6;
public:
- int _field1F8A;
+ int _jokeboxPlayingCtr;
- Item1();
+ Jukebox();
virtual bool startAction(CursorType action, Event &event);
virtual void signal();
virtual void synchronize(Serializer &s);
@@ -258,13 +259,13 @@ class Scene115: public SceneExt {
SequenceManager _sequenceManager3;
SequenceManager _sequenceManager4;
SequenceManager _sequenceManager5;
- Object1 _object1;
- Object2 _object2;
+ Kate _kate;
+ Tony _tony;
Object3 _object3;
Object4 _object4;
- SceneObject _object5, _object6, _object7, _object8, _object9;
+ SceneObject _object5, _object6, _neonSign, _object8, _object9;
SceneObject _object10, _object11, _object12, _object13;
- Item1 _item1;
+ Jukebox _itemJukebox;
EventHandler1 _eventHandler1;
NamedHotspot _item2, _item3, _item4, _item5, _item6, _item7, _item8, _item9;
Item10 _item10;
@@ -286,9 +287,9 @@ class Scene115: public SceneExt {
SpeakerJakeUniform _jakeUniformSpeaker;
SpeakerLyleHat _lyleHatSpeaker;
ASound _sound1;
- int _field168A;
- int _field31E8;
- int _field31EA;
+ int _lineNumModifier;
+ int _jukeboxPlaying;
+ int _talkToTonyCtr;
public:
Scene115();
virtual void synchronize(Serializer &s);
@@ -353,7 +354,7 @@ public:
NamedObject _object1;
NamedObject _object2;
IntroSceneText _text;
-
+
void postInit(SceneObjectList *OwnerList);
};
@@ -419,7 +420,7 @@ public:
GarageExit _garageExit;
ASoundExt _sound1;
SceneMessage _sceneMessage;
- int _fieldC56;
+ int _dispatchMode;
Scene180();
virtual void synchronize(Serializer &s);
@@ -431,7 +432,7 @@ public:
class Scene190: public SceneExt {
/* Objects */
- class Object4: public NamedObject {
+ class LyleCar: public NamedObject {
public:
virtual bool startAction(CursorType action, Event &event);
};
@@ -458,8 +459,8 @@ class Scene190: public SceneExt {
public:
SequenceManager _sequenceManager;
FollowerObject _object1;
- NamedObject _object2, _object3;
- Object4 _object4;
+ NamedObject _door, _flag;
+ LyleCar _lyleCar;
Item1 _item1;
Item2 _item2;
NamedHotspot _item3, _item4, _item5, _item6;
@@ -475,10 +476,7 @@ public:
virtual void signal();
virtual void process(Event &event);
virtual void dispatch();
- virtual void synchronize(Serializer &s) {
- SceneExt::synchronize(s);
- s.syncAsSint16LE(_fieldB52);
- }
+ virtual void synchronize(Serializer &s);
};
} // End of namespace BlueForce
diff --git a/engines/tsage/blue_force/blueforce_scenes2.cpp b/engines/tsage/blue_force/blueforce_scenes2.cpp
index 3af02bd463..c992afe620 100644
--- a/engines/tsage/blue_force/blueforce_scenes2.cpp
+++ b/engines/tsage/blue_force/blueforce_scenes2.cpp
@@ -67,7 +67,7 @@ void Scene200::Action1::signal() {
rot->setDelay(10);
rot = BF_GLOBALS._scenePalette.addRotation(96, 111, 1);
rot->setDelay(10);
-
+
scene->setAction(&scene->_sequenceManager, this, 201, &scene->_object1, &scene->_object2,
&scene->_object3, &scene->_object4, &scene->_object5, &scene->_object6, NULL);
break;
@@ -99,7 +99,7 @@ void Scene200::Action2::signal() {
break;
}
}
-
+
/*--------------------------------------------------------------------------*/
@@ -133,7 +133,7 @@ void Scene200::postInit(SceneObjectList *OwnerList) {
_object11.setVisage(200);
_object11.setPosition(Common::Point(96, 112), 1000);
_object11.setStrip(3);
- _object11.setFrame(1);
+ _object11.setFrame(1);
_object11.changeZoom(100);
_object10.setAction(&_action1);
@@ -168,7 +168,7 @@ void Scene210::Action1::signal() {
rot->setDelay(10);
rot = BF_GLOBALS._scenePalette.addRotation(96, 111, 1);
rot->setDelay(10);
-
+
scene->setAction(&scene->_sequenceManager, this, 210, &scene->_object10, &scene->_object11,
&scene->_object12, &scene->_object13, &scene->_object14, &scene->_object15, NULL);
break;
@@ -301,7 +301,7 @@ void Scene220::Action1::signal() {
rot->setDelay(10);
rot = BF_GLOBALS._scenePalette.addRotation(96, 111, 1);
rot->setDelay(10);
-
+
scene->setAction(&scene->_sequenceManager, this, 220, &scene->_object4, &scene->_object5,
&scene->_object6, &scene->_object7, &scene->_object8, &scene->_object9, NULL);
break;
@@ -508,7 +508,7 @@ void Scene225::Action1::signal() {
rot->setDelay(10);
rot = BF_GLOBALS._scenePalette.addRotation(96, 111, 1);
rot->setDelay(10);
-
+
scene->setAction(&scene->_sequenceManager, this, 225, &scene->_object15, &scene->_object16,
&scene->_object17, &scene->_object18, &scene->_object19, &scene->_object20, NULL);
break;
@@ -661,7 +661,7 @@ void Scene225::postInit(SceneObjectList *OwnerList) {
_object11._frame = 1;
_object11.changeZoom(100);
_object11._numFrames = 2;
-
+
_object12.postInit();
_object12.setVisage(1225);
_object12.setPosition(Common::Point(368, 35));
@@ -937,9 +937,9 @@ void Scene270::postInit(SceneObjectList *OwnerList) {
(BF_INVENTORY.getObjectScene(INV_BASEBALL_CARD) != 2) &&
(BF_INVENTORY.getObjectScene(INV_BASEBALL_CARD) != 1)) ||
((BF_GLOBALS._dayNumber == 3) && BF_GLOBALS.getFlag(fGotGreen355fTalkedToGrannyDay3))) {
- BF_GLOBALS._walkRegions.proc1(6);
- BF_GLOBALS._walkRegions.proc1(14);
- BF_GLOBALS._walkRegions.proc1(19);
+ BF_GLOBALS._walkRegions.disableRegion(6);
+ BF_GLOBALS._walkRegions.disableRegion(14);
+ BF_GLOBALS._walkRegions.disableRegion(19);
_grandma.postInit();
_grandma.setVisage(274);
@@ -983,17 +983,17 @@ void Scene270::postInit(SceneObjectList *OwnerList) {
_fireplace.animate(ANIM_MODE_2, NULL);
_fridge.setDetails(Rect(0, 56, 56, 130), 270, 9, 10, 11, 1, NULL);
- _object3.setDetails(270, 12, 13, 14, 1, NULL);
- _laura.setDetails(270, 15, -1, -1, 1, NULL);
- _skip.setDetails(270, 14, -1, -1, 1, NULL);
- _lyle.setDetails(270, 34, 35, 36, 1, NULL);
- _tv.setDetails(270, 3, 4, 5, 1, NULL);
- _fireplace.setDetails(270, 6, 7, 8, 1, NULL);
+ _object3.setDetails(270, 12, 13, 14, 1, (SceneItem *)NULL);
+ _laura.setDetails(270, 15, -1, -1, 1, (SceneItem *)NULL);
+ _skip.setDetails(270, 14, -1, -1, 1, (SceneItem *)NULL);
+ _lyle.setDetails(270, 34, 35, 36, 1, (SceneItem *)NULL);
+ _tv.setDetails(270, 3, 4, 5, 1, (SceneItem *)NULL);
+ _fireplace.setDetails(270, 6, 7, 8, 1, (SceneItem *)NULL);
if ((BF_GLOBALS._sceneManager._previousScene == 710) && (BF_GLOBALS._bookmark == bTalkedToGrannyAboutSkipsCard)) {
- _grandma.setDetails(270, 15, 16, 17, 1, NULL);
+ _grandma.setDetails(270, 15, 16, 17, 1, (SceneItem *)NULL);
} else {
- _grandma.setDetails(270, 40, 16, 17, 1, NULL);
+ _grandma.setDetails(270, 40, 16, 17, 1, (SceneItem *)NULL);
}
_afgan.setDetails(4, 270, 27, 28, 29, 1);
@@ -1007,14 +1007,14 @@ void Scene270::postInit(SceneObjectList *OwnerList) {
BF_GLOBALS._player._moveDiff.x = 8;
BF_GLOBALS._player.changeZoom(-1);
BF_GLOBALS._player.disableControl();
-
+
switch (BF_GLOBALS._sceneManager._previousScene) {
case 560:
if (BF_GLOBALS._bookmark == bTalkedToGrannyAboutSkipsCard) {
_field219A = 1;
BF_GLOBALS._player._moveDiff.x = 5;
_field386 = 0;
-
+
_grandma.animate(ANIM_MODE_1, NULL);
setAction(&_sequenceManager1, NULL, 2720, &BF_GLOBALS._player, &_grandma, NULL);
BF_GLOBALS._bookmark = bLyleStoppedBy;
@@ -1138,13 +1138,13 @@ void Scene270::signal() {
case 2717:
_sceneMode = 2718;
_lyle.setFrame2(-1);
- setAction(&_sequenceManager1, this, 2718, &BF_GLOBALS._player, &_laura, &_skip,
+ setAction(&_sequenceManager1, this, 2718, &BF_GLOBALS._player, &_laura, &_skip,
&_lyle, &_grandma, NULL);
break;
case 2718:
- BF_GLOBALS._walkRegions.proc1(6);
- BF_GLOBALS._walkRegions.proc1(14);
- BF_GLOBALS._walkRegions.proc1(19);
+ BF_GLOBALS._walkRegions.disableRegion(6);
+ BF_GLOBALS._walkRegions.disableRegion(14);
+ BF_GLOBALS._walkRegions.disableRegion(19);
_field219A = 1;
BF_GLOBALS._bookmark = bTalkedToGrannyAboutSkipsCard;
@@ -1152,7 +1152,7 @@ void Scene270::signal() {
_grandma.setStrip(8);
_grandma._frame = 5;
_field384 = 1;
- _field384 = 1;
+ _field386 = 1;
BF_GLOBALS._player._moveDiff.x = 8;
BF_GLOBALS._player.enableControl();
@@ -1167,7 +1167,7 @@ void Scene270::signal() {
break;
default:
break;
- }
+ }
}
void Scene270::process(Event &event) {
@@ -1290,7 +1290,7 @@ void Scene270::dispatch() {
void Scene271::Action1::signal() {
Scene271 *scene = (Scene271 *)BF_GLOBALS._sceneManager._scene;
- scene->setAction(&scene->_sequenceManager2, this, 2703, &scene->_tv, NULL);
+ setAction(&scene->_sequenceManager2, this, 2703, &scene->_tv, NULL);
}
/*--------------------------------------------------------------------------*/
@@ -1374,7 +1374,7 @@ Scene271::Scene271() {
void Scene271::synchronize(Serializer &s) {
PalettedScene::synchronize(s);
-
+
s.syncAsSint16LE(_field796);
s.syncAsSint16LE(_field2E16);
s.syncAsSint16LE(_tempPos.x);
@@ -1396,7 +1396,7 @@ void Scene271::postInit(SceneObjectList *OwnerList) {
_stripManager.addSpeaker(&_gameTextSpeaker);
_stripManager.addSpeaker(&_granTextSpeaker);
_stripManager.addSpeaker(&_lyleTextSpeaker);
-
+
_exit.setDetails(Rect(310, 115, 320, 167), 270, -1, -1, -1, 1, NULL);
_tv.postInit();
@@ -1420,20 +1420,20 @@ void Scene271::postInit(SceneObjectList *OwnerList) {
_object5.hide();
_item5.setDetails(Rect(0, 56, 56, 130), 270, 9, 10, 11, 1, NULL);
- _object6.setDetails(270, 12, 13, 14, 1, NULL);
- _object7.setDetails(270, 15, -1, -1, 1, NULL);
- _object8.setDetails(270, 14, -1, -1, 1, NULL);
- _object11.setDetails(270, -1, -1, -1, 1, NULL);
- _tv.setDetails(270, 3, 4, 5, 1, NULL);
- _object10.setDetails(270, 6, 7, 8, 1, NULL);
- _object12.setDetails(270, 15, 16, 17, 1, NULL);
+ _object6.setDetails(270, 12, 13, 14, 1, (SceneItem *)NULL);
+ _object7.setDetails(270, 15, -1, -1, 1, (SceneItem *)NULL);
+ _object8.setDetails(270, 14, -1, -1, 1, (SceneItem *)NULL);
+ _object11.setDetails(270, -1, -1, -1, 1, (SceneItem *)NULL);
+ _tv.setDetails(270, 3, 4, 5, 1, (SceneItem *)NULL);
+ _object10.setDetails(270, 6, 7, 8, 1, (SceneItem *)NULL);
+ _object12.setDetails(270, 15, 16, 17, 1, (SceneItem *)NULL);
_item3.setDetails(4, 270, 27, 28, 29, 1);
_item1.setDetails(1, 270, 18, 19, 20, 1);
_item6.setDetails(Rect(278, 50, 318, 72), 270, 21, 22, 23, 1, NULL);
_item2.setDetails(3, 270, 24, 25, 26, 1);
_item4.setDetails(2, 270, 30, 31, 32, 1);
_item11.setDetails(Rect(0, 0, SCREEN_WIDTH, UI_INTERFACE_Y), 270, 0, 1, 2, 1, NULL);
-
+
BF_GLOBALS._player.postInit();
BF_GLOBALS._player._moveDiff.x = 8;
BF_GLOBALS._player.changeZoom(-1);
@@ -1450,11 +1450,11 @@ void Scene271::postInit(SceneObjectList *OwnerList) {
switch (BF_GLOBALS._sceneManager._previousScene) {
case 180:
- BF_GLOBALS._walkRegions.proc1(6);
- BF_GLOBALS._walkRegions.proc1(14);
- BF_GLOBALS._walkRegions.proc1(19);
+ BF_GLOBALS._walkRegions.disableRegion(6);
+ BF_GLOBALS._walkRegions.disableRegion(14);
+ BF_GLOBALS._walkRegions.disableRegion(19);
- BF_GLOBALS._player.setVisage(151);
+ BF_GLOBALS._player.setVisage(275);
BF_GLOBALS._player.setPosition(Common::Point(348, 151));
_object12.postInit();
@@ -1477,13 +1477,13 @@ void Scene271::postInit(SceneObjectList *OwnerList) {
_object11.setStrip(1);
_object11._frame = 2;
_object11.setPosition(Common::Point(35, 136));
-
+
_object6.postInit();
_object6.hide();
- BF_GLOBALS._walkRegions.proc1(6);
- BF_GLOBALS._walkRegions.proc1(14);
- BF_GLOBALS._walkRegions.proc1(19);
+ BF_GLOBALS._walkRegions.disableRegion(6);
+ BF_GLOBALS._walkRegions.disableRegion(14);
+ BF_GLOBALS._walkRegions.disableRegion(19);
_object12.postInit();
_object12.setVisage(274);
@@ -1508,15 +1508,15 @@ void Scene271::postInit(SceneObjectList *OwnerList) {
_object7.setVisage(277);
_object7.setStrip(7);
_object7.setPosition(Common::Point(48, 149));
-
- BF_GLOBALS._walkRegions.proc1(6);
- BF_GLOBALS._walkRegions.proc1(14);
- BF_GLOBALS._walkRegions.proc1(19);
-
+
+ BF_GLOBALS._walkRegions.disableRegion(6);
+ BF_GLOBALS._walkRegions.disableRegion(14);
+ BF_GLOBALS._walkRegions.disableRegion(19);
+
_object12.postInit();
_object12.setVisage(276);
_object12.setPosition(Common::Point(129, 130));
-
+
_object2.postInit();
_object2.setVisage(270);
_object2.setStrip(3);
@@ -1543,9 +1543,9 @@ void Scene271::postInit(SceneObjectList *OwnerList) {
BF_GLOBALS._player.setFrame(1);
BF_GLOBALS._player.setPosition(Common::Point(239, 145));
- BF_GLOBALS._walkRegions.proc1(6);
- BF_GLOBALS._walkRegions.proc1(14);
- BF_GLOBALS._walkRegions.proc1(19);
+ BF_GLOBALS._walkRegions.disableRegion(6);
+ BF_GLOBALS._walkRegions.disableRegion(14);
+ BF_GLOBALS._walkRegions.disableRegion(19);
_object12.postInit();
_object12.setVisage(274);
@@ -1637,10 +1637,10 @@ void Scene271::signal() {
BF_GLOBALS._player.enableControl();
_field796 = 1;
_field2E16 = 1;
-
+
_object1.remove();
_object11.remove();
-
+
BF_INVENTORY.setObjectScene(INV_LYLE_CARD, 1);
break;
case 2709:
@@ -1754,7 +1754,7 @@ void Scene280::Action1::signal() {
scene->_jake.setFrame(1);
scene->_jake.animate(ANIM_MODE_8, NULL);
scene->_jake._numFrames = 5;
-
+
scene->_stripManager.start(2800, this);
break;
case 2:
diff --git a/engines/tsage/blue_force/blueforce_scenes3.cpp b/engines/tsage/blue_force/blueforce_scenes3.cpp
index 1fa27ccb27..22c831f531 100644
--- a/engines/tsage/blue_force/blueforce_scenes3.cpp
+++ b/engines/tsage/blue_force/blueforce_scenes3.cpp
@@ -58,7 +58,7 @@ bool Scene300::Object19::startAction(CursorType action, Event &event) {
return true;
}
-
+// entrance door
bool Scene300::Item1::startAction(CursorType action, Event &event) {
if (action == CURSOR_USE) {
Scene300 *scene = (Scene300 *)BF_GLOBALS._sceneManager._scene;
@@ -75,6 +75,8 @@ bool Scene300::Item1::startAction(CursorType action, Event &event) {
bool Scene300::Item2::startAction(CursorType action, Event &event) {
if ((action == CURSOR_LOOK) || (action == CURSOR_USE)) {
Scene300 *scene = (Scene300 *)BF_GLOBALS._sceneManager._scene;
+ BF_GLOBALS._player.disableControl();
+ scene->_sceneMode = 0;
scene->setAction(&scene->_sequenceManager1, scene, 304, &scene->_object11, NULL);
return true;
} else {
@@ -108,7 +110,7 @@ void Scene300::Action1::signal() {
setDelay(1);
break;
case 2: {
- ADD_PLAYER_MOVER_THIS(BF_GLOBALS._player, BF_GLOBALS._player._position.x - 8,
+ ADD_MOVER(BF_GLOBALS._player, BF_GLOBALS._player._position.x - 8,
BF_GLOBALS._player._position.y);
break;
}
@@ -183,12 +185,13 @@ void Scene300::Action4::signal() {
break;
case 2:
BF_GLOBALS._sceneManager.changeScene(60);
+ setDelay(15);
break;
case 3:
setAction(&scene->_sequenceManager1, this, 319, &scene->_object19, NULL);
break;
case 4:
- BF_GLOBALS.setFlag(2);
+ BF_GLOBALS.setFlag(onBike);
BF_GLOBALS._sceneManager.changeScene(190);
break;
default:
@@ -213,6 +216,7 @@ void Scene300::Action5::signal() {
break;
case 3: {
ADD_PLAYER_MOVER_NULL(BF_GLOBALS._player, 186, 140);
+ setDelay(3);
break;
}
case 4:
@@ -265,20 +269,20 @@ void Scene300::postInit(SceneObjectList *OwnerList) {
_object17.setVisage(301);
_object17.setStrip(1);
_object17.setPosition(Common::Point(87, 88));
- _object17.setDetails(300, 11, 13, 2, 1, NULL);
+ _object17.setDetails(300, 11, 13, 2, 1, (SceneItem *)NULL);
_object18.postInit();
_object18.setVisage(301);
_object18.setStrip(1);
_object18.setPosition(Common::Point(137, 92));
- _object18.setDetails(300, 11, 13, 3, 1, NULL);
+ _object18.setDetails(300, 11, 13, 3, 1, (SceneItem *)NULL);
}
_object19.postInit();
_object19.setVisage(301);
_object19.setStrip(1);
_object19.setPosition(Common::Point(175, 99));
- _object19.setDetails(300, 11, 13, 34, 1, NULL);
+ _object19.setDetails(300, 11, 13, 34, 1, (SceneItem *)NULL);
_object11.postInit();
_object11.setVisage(301);
@@ -302,14 +306,14 @@ void Scene300::postInit(SceneObjectList *OwnerList) {
break;
case 190:
_sceneMode = 0;
- if (!BF_GLOBALS.getFlag(2)) {
+ if (!BF_GLOBALS.getFlag(onBike)) {
_sceneMode = 7308;
BF_GLOBALS._player.setPosition(Common::Point(175, 50));
ADD_PLAYER_MOVER_THIS(BF_GLOBALS._player, 123, 71);
if ((BF_GLOBALS._dayNumber == 2) && (BF_GLOBALS._bookmark < bEndDayOne))
- setup();
- } else if (!BF_GLOBALS.getFlag(3)) {
+ setupInspection();
+ } else if (!BF_GLOBALS.getFlag(onDuty)) {
BF_GLOBALS._player.disableControl();
_sceneMode = 300;
setAction(&_sequenceManager1, this, 300, &BF_GLOBALS._player, NULL);
@@ -328,7 +332,7 @@ void Scene300::postInit(SceneObjectList *OwnerList) {
setAction(&_sequenceManager1, this, 306, &BF_GLOBALS._player, &_object8, NULL);
} else {
BF_GLOBALS._player.setVisage(1304);
- setup();
+ setupInspection();
BF_GLOBALS._player.disableControl();
_sceneMode = 0;
setAction(&_sequenceManager1, this, 306, &BF_GLOBALS._player, &_object8, NULL);
@@ -420,7 +424,7 @@ void Scene300::signal() {
setAction(&_sequenceManager1, this, 312, &_object1, &_object16, NULL);
break;
case 317:
- BF_GLOBALS.setFlag(2);
+ BF_GLOBALS.setFlag(onBike);
BF_GLOBALS._sceneManager.changeScene(60);
break;
case 318:
@@ -474,10 +478,10 @@ void Scene300::signal() {
_object10.postInit();
_object10.hide();
- if (BF_GLOBALS.getFlag(1)) {
+ if (BF_GLOBALS.getFlag(gunClean)) {
BF_GLOBALS._player.disableControl();
_sceneMode = 4308;
- setAction(&_sequenceManager1, this, 6307, &_object2, &_object1, &_object9, &_object10, NULL);
+ setAction(&_sequenceManager1, this, 6307, &_object12, &_object1, &_object9, &_object10, NULL);
} else {
BF_GLOBALS._player.disableControl();
_sceneMode = 4308;
@@ -552,7 +556,7 @@ void Scene300::dispatch() {
if ((BF_GLOBALS._player._position.y < 59) && (BF_GLOBALS._player._position.x > 137) &&
(_sceneMode != 6308) && (_sceneMode != 7308)) {
- BF_GLOBALS._v4CEA4 = 3;
+ // The original was setting a useless global variable (removed)
_sceneMode = 6308;
BF_GLOBALS._player.disableControl();
ADD_MOVER(BF_GLOBALS._player, BF_GLOBALS._player._position.x + 20,
@@ -574,7 +578,7 @@ void Scene300::dispatch() {
}
}
-void Scene300::setup() {
+void Scene300::setupInspection() {
_object13.postInit();
_object13.setVisage(307);
_object13.setStrip(6);
@@ -618,7 +622,7 @@ void Scene300::setup() {
_object1._moveDiff = Common::Point(3, 1);
_object1.setObjectWrapper(new SceneObjectWrapper());
_object1.animate(ANIM_MODE_1, NULL);
- _object2.setup(&_object1, 306, 4, 9);
+ _object2.setup(&_object1, 306, 4, 29);
BF_GLOBALS._sceneItems.addItems(&_object13, &_object14, &_object15, &_object16, NULL);
_timer.set(3600, this, &_action5);
@@ -638,7 +642,7 @@ bool Scene315::Barry::startAction(CursorType action, Event &event) {
switch (action) {
case CURSOR_USE:
- if (scene->_field1B60 || scene->_field1B64)
+ if (scene->_invGreenCount || scene->_invGangCount)
SceneItem::display2(320, 51);
else
NamedHotspot::startAction(action, event);
@@ -667,7 +671,7 @@ bool Scene315::Barry::startAction(CursorType action, Event &event) {
scene->_stripNumber = 3174;
scene->setAction(&scene->_action1);
} else {
- ++scene->_field1B62;
+ ++scene->_bookGreenCount;
scene->_stripNumber = (action == INV_GREENS_GUN) ? 3168 : 0;
scene->_sceneMode = 3153;
scene->setAction(&scene->_sequenceManager, scene, 3153, &BF_GLOBALS._player, NULL);
@@ -675,7 +679,7 @@ bool Scene315::Barry::startAction(CursorType action, Event &event) {
break;
case INV_FOREST_RAP:
BF_GLOBALS._player.disableControl();
- scene->_stripNumber = BF_GLOBALS.getFlag(onDuty) ? 3178 : 3173;
+ scene->_stripNumber = BF_GLOBALS.getFlag(onDuty) ? 3173 : 3178;
scene->setAction(&scene->_action1);
break;
case INV_GREEN_ID:
@@ -693,7 +697,7 @@ bool Scene315::Barry::startAction(CursorType action, Event &event) {
scene->setAction(&scene->_action1);
break;
case INV_COBB_RAP:
- if (BF_INVENTORY._mugshot._sceneNumber == 1)
+ if (BF_INVENTORY.getObjectScene(INV_MUG_SHOT) == 1)
NamedHotspot::startAction(action, event);
else {
BF_GLOBALS._player.disableControl();
@@ -717,8 +721,8 @@ bool Scene315::Barry::startAction(CursorType action, Event &event) {
scene->_stripNumber = 3174;
scene->setAction(&scene->_action1);
} else {
- ++scene->_field1B66;
- if (!scene->_field1B6C && (scene->_field1B66 == 1)) {
+ ++scene->_bookGangCount;
+ if (!scene->_field1B6C && (scene->_bookGangCount == 1)) {
scene->_field1B6C = 1;
scene->_stripNumber = 3169;
} else {
@@ -759,9 +763,9 @@ bool Scene315::SutterSlot::startAction(CursorType action, Event &event) {
case INV_BOOKING_FRANKIE:
case INV_BOOKING_GANG:
if (action == INV_BOOKING_GREEN)
- ++scene->_field1B62;
+ ++scene->_bookGreenCount;
else
- ++scene->_field1B66;
+ ++scene->_bookGangCount;
BF_GLOBALS._player.disableControl();
scene->_sceneMode = 12;
@@ -874,6 +878,7 @@ bool Scene315::BulletinMemo::startAction(CursorType action, Event &event) {
}
}
+// Own Mail Slot
bool Scene315::Object2::startAction(CursorType action, Event &event) {
Scene315 *scene = (Scene315 *)BF_GLOBALS._sceneManager._scene;
@@ -939,6 +944,10 @@ void Scene315::Action1::signal() {
if (scene->_sceneMode == 3169) {
T2_GLOBALS._uiElements.addScore(30);
BF_INVENTORY.setObjectScene(INV_MUG_SHOT, 1);
+ //HACK: This has to be checked wether or not it occurs in the original.
+ //When the _sceneMode is set to 3169, the value desn't change.
+ //If you show the forest rapsheet, it gives points (and again... and again...)
+ scene->_sceneMode = 3154;
}
remove();
@@ -957,9 +966,9 @@ Scene315::Scene315() {
BF_GLOBALS.clearFlag(fCanDrawGun);
_field1B68 = true;
- _field1B6A = false;
- _field1B60 = _field1B62 = 0;
- _field1B64 = _field1B66 = 0;
+ _doorOpened = false;
+ _invGreenCount = _bookGreenCount = 0;
+ _invGangCount = _bookGangCount = 0;
}
void Scene315::synchronize(Serializer &s) {
@@ -968,18 +977,19 @@ void Scene315::synchronize(Serializer &s) {
s.syncAsSint16LE(_field1390);
s.syncAsSint16LE(_stripNumber);
s.syncAsSint16LE(_field1398);
- s.syncAsSint16LE(_field1B60);
- s.syncAsSint16LE(_field1B62);
- s.syncAsSint16LE(_field1B64);
- s.syncAsSint16LE(_field1B66);
+ s.syncAsSint16LE(_invGreenCount);
+ s.syncAsSint16LE(_bookGreenCount);
+ s.syncAsSint16LE(_invGangCount);
+ s.syncAsSint16LE(_bookGangCount);
s.syncAsSint16LE(_field1B6C);
s.syncAsSint16LE(_field139C);
s.syncAsByte(_field1B68);
- s.syncAsByte(_field1B6A);
+ s.syncAsByte(_doorOpened);
s.syncAsSint16LE(_currentCursor);
}
void Scene315::postInit(SceneObjectList *OwnerList) {
+ SceneExt::postInit(OwnerList);
loadScene(315);
if (BF_GLOBALS._sceneManager._previousScene != 325)
@@ -1005,7 +1015,7 @@ void Scene315::postInit(SceneObjectList *OwnerList) {
_atfMemo.setStrip(4);
_atfMemo.setFrame(4);
_atfMemo.fixPriority(82);
- _atfMemo.setDetails(315, -1, -1, -1, 1, NULL);
+ _atfMemo.setDetails(315, -1, -1, -1, 1, (SceneItem *)NULL);
}
if (BF_GLOBALS._dayNumber == 1) {
@@ -1016,7 +1026,7 @@ void Scene315::postInit(SceneObjectList *OwnerList) {
_bulletinMemo.setStrip(4);
_bulletinMemo.setFrame(2);
_bulletinMemo.fixPriority(82);
- _bulletinMemo.setDetails(315, -1, -1, -1, 1, NULL);
+ _bulletinMemo.setDetails(315, -1, -1, -1, 1, (SceneItem *)NULL);
}
} else if ((BF_INVENTORY._daNote._sceneNumber != 1) && (BF_GLOBALS._dayNumber < 3)) {
_object2.postInit();
@@ -1025,7 +1035,7 @@ void Scene315::postInit(SceneObjectList *OwnerList) {
_object2.setFrame(2);
_object2.setPosition(Common::Point(304, 31));
_object2.fixPriority(70);
- _object2.setDetails(315, 3, 4, -1, 1, NULL);
+ _object2.setDetails(315, 3, 4, -1, 1, (SceneItem *)NULL);
}
_sutterSlot.setDetails(12, 315, 35, -1, 36, 1);
@@ -1061,29 +1071,29 @@ void Scene315::postInit(SceneObjectList *OwnerList) {
// Set up evidence objects in inventory
if (BF_INVENTORY._bookingGreen.inInventory())
- ++_field1B60;
+ ++_invGreenCount;
if (BF_INVENTORY._greensGun.inInventory())
- ++_field1B60;
+ ++_invGreenCount;
if (BF_INVENTORY._greensKnife.inInventory())
- ++_field1B60;
+ ++_invGreenCount;
if (BF_INVENTORY._bullet22.inInventory())
- ++_field1B64;
+ ++_invGangCount;
if (BF_INVENTORY._autoRifle.inInventory())
- ++_field1B64;
+ ++_invGangCount;
if (BF_INVENTORY._wig.inInventory())
- ++_field1B64;
+ ++_invGangCount;
if (BF_INVENTORY._bookingFrankie.inInventory())
- ++_field1B64;
+ ++_invGangCount;
if (BF_INVENTORY._bookingGang.inInventory())
- ++_field1B64;
+ ++_invGangCount;
if (BF_INVENTORY._snub22.inInventory())
- ++_field1B64;
+ ++_invGangCount;
switch (BF_GLOBALS._sceneManager._previousScene) {
case 190:
if (_field1398)
- _field1B6A = true;
+ _doorOpened = true;
_sceneMode = BF_GLOBALS.getFlag(onDuty) ? 3150 : 3165;
setAction(&_sequenceManager, this, _sceneMode, &BF_GLOBALS._player, NULL);
break;
@@ -1099,7 +1109,7 @@ void Scene315::postInit(SceneObjectList *OwnerList) {
case 300:
default:
if (_field1398)
- _field1B6A = true;
+ _doorOpened = true;
if (!BF_GLOBALS.getFlag(onDuty))
_sceneMode = 3166;
else if (!_field1398)
@@ -1111,10 +1121,10 @@ void Scene315::postInit(SceneObjectList *OwnerList) {
break;
}
- if (_field1B6A) {
+ if (_doorOpened) {
_object8.setFrame(8);
} else {
- BF_GLOBALS._walkRegions.proc1(4);
+ BF_GLOBALS._walkRegions.disableRegion(4);
}
_briefingMaterial.setDetails(24, 315, 38, 39, 40, 1);
@@ -1135,15 +1145,15 @@ void Scene315::signal() {
BF_GLOBALS._player.enableControl();
break;
case 10:
- if (_field1B62) {
- if (_field1B62 >= _field1B60)
+ if (_bookGreenCount) {
+ if (_bookGreenCount >= _invGreenCount)
BF_GLOBALS.setFlag(fLeftTraceIn910);
else
++ctr;
}
- if (_field1B66) {
- if (_field1B66 < _field1B64)
+ if (_bookGangCount) {
+ if (_bookGangCount < _invGangCount)
++ctr;
else if (BF_GLOBALS._bookmark < bBookedFrankieEvidence)
BF_GLOBALS._bookmark = bBookedFrankieEvidence;
@@ -1158,15 +1168,15 @@ void Scene315::signal() {
BF_GLOBALS._sound1.fadeOut2(NULL);
break;
case 11:
- if (_field1B62) {
- if (_field1B62 >= _field1B60)
+ if (_bookGreenCount) {
+ if (_bookGreenCount >= _invGreenCount)
BF_GLOBALS.setFlag(fLeftTraceIn910);
else
++ctr;
}
- if (_field1B66) {
- if (_field1B66 < _field1B64)
+ if (_bookGangCount) {
+ if (_bookGangCount < _invGangCount)
++ctr;
else if (BF_GLOBALS._bookmark < bBookedFrankie)
BF_GLOBALS._bookmark = bBookedFrankie;
@@ -1195,7 +1205,7 @@ void Scene315::signal() {
T2_GLOBALS._uiElements.addScore(30);
BF_INVENTORY.setObjectScene((int)_currentCursor, 315);
- if (!_field1B64 || (_field1B66 != _field1B64))
+ if (!_invGangCount || (_bookGangCount != _invGangCount))
BF_GLOBALS._player.enableControl();
else {
_field139C = 1;
@@ -1214,13 +1224,14 @@ void Scene315::signal() {
BF_GLOBALS._sceneManager.changeScene(325);
break;
case 3152:
- BF_GLOBALS._walkRegions.proc1(4);
+ BF_GLOBALS._walkRegions.disableRegion(4);
_object7.remove();
_object6.remove();
-
+ // No break on purpose
+ case 3155:
BF_GLOBALS._player.enableControl();
_field1B68 = false;
- BF_GLOBALS._walkRegions.proc1(4);
+ BF_GLOBALS._walkRegions.disableRegion(4);
T2_GLOBALS._uiElements._active = true;
T2_GLOBALS._uiElements.show();
break;
@@ -1230,7 +1241,7 @@ void Scene315::signal() {
if (_stripNumber != 0)
setAction(&_action1);
- else if (!_field1B64 || (_field1B66 != _field1B64))
+ else if (!_invGangCount || (_bookGangCount != _invGangCount))
BF_GLOBALS._player.enableControl();
else {
_stripNumber = 3171;
@@ -1238,13 +1249,6 @@ void Scene315::signal() {
_field139C = 1;
}
break;
- case 3155:
- BF_GLOBALS._player.enableControl();
- _field1B68 = false;
- BF_GLOBALS._walkRegions.proc1(4);
- T2_GLOBALS._uiElements._active = true;
- T2_GLOBALS._uiElements.show();
- break;
case 3156:
T2_GLOBALS._uiElements.addScore(10);
BF_INVENTORY.setObjectScene(INV_DA_NOTE, 1);
@@ -1287,6 +1291,11 @@ void Scene315::signal() {
BF_GLOBALS._player.enableControl();
_object9.remove();
break;
+ case 3169:
+ T2_GLOBALS._uiElements.addScore(30);
+ BF_INVENTORY.setObjectScene(INV_MUG_SHOT, 1);
+ BF_GLOBALS._player.enableControl();
+ break;
case 3154:
default:
break;
@@ -1318,7 +1327,7 @@ void Scene315::dispatch() {
if (_field1B68)
return;
- if (_field1B6A) {
+ if (_doorOpened) {
if (BF_GLOBALS._player._position.y < 69) {
BF_GLOBALS._player.disableControl();
_field1B68 = true;
@@ -1721,9 +1730,9 @@ void Scene340::Action1::signal() {
++BF_GLOBALS._marinaWomanCtr;
if (BF_GLOBALS.getFlag(fBackupArrived340)) {
- scene->_field2654 = 1;
+ scene->_backupPresent = 1;
scene->_harrison.setPosition(Common::Point(46, 154));
- BF_GLOBALS._walkRegions.proc1(19);
+ BF_GLOBALS._walkRegions.disableRegion(19);
} else if (BF_GLOBALS.getFlag(fCalledBackup)) {
scene->_timer1.set(40, &scene->_harrison, &scene->_action4);
}
@@ -1732,6 +1741,8 @@ void Scene340::Action1::signal() {
BF_GLOBALS._player.enableControl();
remove();
break;
+ default:
+ break;
}
}
@@ -1740,6 +1751,7 @@ void Scene340::Action2::signal() {
switch (_actionIndex++) {
case 0: {
+ BF_GLOBALS._player.disableControl();
ADD_PLAYER_MOVER(64, 155);
break;
}
@@ -1757,6 +1769,8 @@ void Scene340::Action2::signal() {
BF_GLOBALS._player.enableControl();
remove();
break;
+ default:
+ break;
}
}
@@ -1765,6 +1779,7 @@ void Scene340::Action3::signal() {
switch (_actionIndex++) {
case 0: {
+ BF_GLOBALS._player.disableControl();
ADD_PLAYER_MOVER(64, 155);
break;
}
@@ -1773,18 +1788,20 @@ void Scene340::Action3::signal() {
setDelay(3);
break;
case 2:
- scene->_stripManager.start(scene->_field2652 + 3404, this);
+ scene->_stripManager.start(scene->_womanDialogCount + 3404, this);
break;
case 3:
- if (++scene->_field2652 > 2) {
+ if (++scene->_womanDialogCount > 2) {
if (!BF_GLOBALS.getFlag(fGotAllSkip340))
BF_GLOBALS.setFlag(fGotAllSkip340);
- scene->_field2652 = 0;
+ scene->_womanDialogCount = 0;
}
BF_GLOBALS._player.enableControl();
remove();
break;
+ default:
+ break;
}
}
@@ -1803,17 +1820,19 @@ void Scene340::Action4::signal() {
break;
case 1:
BF_GLOBALS.setFlag(fBackupArrived340);
- scene->_field2654 = 1;
+ scene->_backupPresent = 1;
setDelay(3);
break;
case 2:
BF_GLOBALS._player.setAction(&scene->_sequenceManager3, this, 1347, &scene->_harrison, NULL);
break;
case 3:
- BF_GLOBALS._walkRegions.proc1(19);
+ BF_GLOBALS._walkRegions.disableRegion(19);
BF_GLOBALS._player.enableControl();
remove();
break;
+ default:
+ break;
}
}
@@ -1823,7 +1842,7 @@ void Scene340::Action5::signal() {
switch (_actionIndex++) {
case 0:
BF_GLOBALS._player.disableControl();
- if (scene->_field2654) {
+ if (scene->_backupPresent) {
ADD_PLAYER_MOVER(64, 155);
} else {
BF_GLOBALS._player.changeAngle(45);
@@ -1849,6 +1868,8 @@ void Scene340::Action5::signal() {
BF_GLOBALS._player.enableControl();
remove();
break;
+ default:
+ break;
}
}
@@ -1893,6 +1914,8 @@ void Scene340::Action7::signal() {
BF_GLOBALS.setFlag(fBackupIn350);
BF_GLOBALS._sceneManager.changeScene(350);
break;
+ default:
+ break;
}
}
@@ -1945,6 +1968,11 @@ void Scene340::Action8::signal() {
case 4:
remove();
break;
+ default:
+ // This is present in the original game
+ warning("Bugs");
+ remove();
+ break;
}
}
@@ -1977,15 +2005,15 @@ void Scene340::Timer2::signal() {
/*--------------------------------------------------------------------------*/
Scene340::Scene340(): PalettedScene() {
- _seqNumber1 = _field2652 = _field2654 = 0;
+ _seqNumber1 = _womanDialogCount = _backupPresent = 0;
}
void Scene340::synchronize(Serializer &s) {
PalettedScene::synchronize(s);
s.syncAsSint16LE(_seqNumber1);
- s.syncAsSint16LE(_field2652);
- s.syncAsSint16LE(_field2654);
+ s.syncAsSint16LE(_womanDialogCount);
+ s.syncAsSint16LE(_backupPresent);
}
void Scene340::postInit(SceneObjectList *OwnerList) {
@@ -1993,14 +2021,14 @@ void Scene340::postInit(SceneObjectList *OwnerList) {
loadScene(340);
setZoomPercents(126, 70, 162, 100);
- BF_GLOBALS._walkRegions.proc1(13);
- BF_GLOBALS._walkRegions.proc1(15);
+ BF_GLOBALS._walkRegions.disableRegion(13);
+ BF_GLOBALS._walkRegions.disableRegion(15);
_timer2.set(2, NULL);
_stripManager.addSpeaker(&_gameTextSpeaker);
_stripManager.addSpeaker(&_jakeUniformSpeaker);
- _field2652 = 0;
+ _womanDialogCount = 0;
BF_GLOBALS._player.postInit();
BF_GLOBALS._player.setObjectWrapper(new SceneObjectWrapper());
BF_GLOBALS._player.animate(ANIM_MODE_1, NULL);
@@ -2009,7 +2037,7 @@ void Scene340::postInit(SceneObjectList *OwnerList) {
_swExit.setDetails(15, 340, -1, -1, -1, 1);
_northExit.setDetails(16, 340, -1, -1, -1, 1);
- BF_GLOBALS._player._regionBitList = 0x10000;
+ BF_GLOBALS._player._regionBitList |= 0x10000;
BF_GLOBALS._player.setVisage(BF_GLOBALS.getFlag(onDuty) ? 1341 : 129);
BF_GLOBALS._player._moveDiff = Common::Point(5, 2);
@@ -2057,18 +2085,18 @@ void Scene340::postInit(SceneObjectList *OwnerList) {
_stripManager.addSpeaker(&_harrisonSpeaker);
if (BF_GLOBALS.getFlag(fBackupIn350)) {
- _field2654 = 0;
+ _backupPresent = 0;
_harrison.setVisage(1355);
_harrison.setPosition(Common::Point(289, 112));
_harrison.changeAngle(225);
_harrison.setFrame(1);
_harrison.fixPriority(75);
- BF_GLOBALS._walkRegions.proc1(23);
+ BF_GLOBALS._walkRegions.disableRegion(23);
} else if (BF_GLOBALS.getFlag(fBackupArrived340)) {
- _field2654 = 1;
+ _backupPresent = 1;
_harrison.setPosition(Common::Point(46, 154));
- BF_GLOBALS._walkRegions.proc1(19);
+ BF_GLOBALS._walkRegions.disableRegion(19);
} else if (BF_GLOBALS.getFlag(fCalledBackup) && (BF_GLOBALS._marinaWomanCtr > 0)) {
_timer1.set(900, &_harrison, &_action4);
}
@@ -2291,8 +2319,8 @@ void Scene342::postInit(SceneObjectList *OwnerList) {
loadScene(340);
setZoomPercents(126, 70, 162, 100);
- BF_GLOBALS._walkRegions.proc1(13);
- BF_GLOBALS._walkRegions.proc1(15);
+ BF_GLOBALS._walkRegions.disableRegion(13);
+ BF_GLOBALS._walkRegions.disableRegion(15);
_field1A1A = 0;
_timer1.set(2, NULL);
@@ -2360,7 +2388,7 @@ void Scene342::postInit(SceneObjectList *OwnerList) {
}
if (BF_GLOBALS.getFlag(fWithLyle)) {
- BF_GLOBALS._walkRegions.proc1(19);
+ BF_GLOBALS._walkRegions.disableRegion(19);
BF_GLOBALS._player.disableControl();
_sceneMode = 0;
@@ -2658,7 +2686,7 @@ void Scene350::postInit(SceneObjectList *OwnerList) {
_harrison.setObjectWrapper(new SceneObjectWrapper());
_harrison.animate(ANIM_MODE_1, NULL);
_harrison.changeZoom(-1);
- _harrison.setDetails(350, 12, 13, 14, 1, NULL);
+ _harrison.setDetails(350, 12, 13, 14, 1, (SceneItem *)NULL);
_harrison._moveDiff = Common::Point(2, 1);
_stripManager.addSpeaker(&_harrisonSpeaker);
@@ -2751,7 +2779,7 @@ void Scene350::signal() {
default:
if (BF_GLOBALS.getFlag(fBackupIn350)) {
_harrison.updateAngle(BF_GLOBALS._player._position);
- BF_GLOBALS._walkRegions.proc1(19);
+ BF_GLOBALS._walkRegions.disableRegion(19);
}
BF_GLOBALS._player.enableControl();
@@ -2952,8 +2980,8 @@ bool Scene355::LockerInset::startAction(CursorType action, Event &event) {
if (_frame == 1) {
SceneItem::display2(355, 23);
return true;
- }
- return true;
+ } else
+ return NamedObject::startAction(action, event);
case INV_SCREWDRIVER:
scene->_sound2.play(104);
BF_INVENTORY.setObjectScene(INV_SCREWDRIVER, 999);
@@ -3558,7 +3586,7 @@ void Scene355::postInit(SceneObjectList *OwnerList) {
_lyle.setStrip(1);
_lyle.setAction(&_action1);
_lyle._flag = BF_GLOBALS.getFlag(fTookTrailerAmmo) ? 1 : 0;
- _lyle.setDetails(355, 40, 42, 41, 1, NULL);
+ _lyle.setDetails(355, 40, 42, 41, 1, (SceneItem *)NULL);
}
if ((BF_INVENTORY.getObjectScene(INV_RAGS) == 0) && (BF_INVENTORY.getObjectScene(INV_JAR) == 0) &&
@@ -3643,7 +3671,7 @@ void Scene355::postInit(SceneObjectList *OwnerList) {
}
_item3._sceneRegionId = 18;
- _harrison.setDetails(355, 18, 20, 19, 1, NULL);
+ _harrison.setDetails(355, 18, 20, 19, 1, (SceneItem *)NULL);
_item6.setDetails(10, 355, 2, -1, 14, 1);
_item7.setDetails(11, 355, 3, -1, 15, 1);
_item8.setDetails(12, 355, 4, -1, 8, 1);
@@ -4137,7 +4165,7 @@ bool Scene360::Item1::startAction(CursorType action, Event &event) {
case CURSOR_TALK:
scene->_sceneMode = 3607;
BF_GLOBALS._player.disableControl();
- scene->_stripManager.start(3550, this);
+ scene->_stripManager.start(3550, scene);
return true;
case INV_COLT45:
SceneItem::display2(1, 4);
@@ -4246,7 +4274,7 @@ bool Scene360::Object4::startAction(CursorType action, Event &event) {
}
}
-bool Scene360::BsseballCards::startAction(CursorType action, Event &event) {
+bool Scene360::BaseballCards::startAction(CursorType action, Event &event) {
switch (action) {
case CURSOR_LOOK:
if (event.mousePos.x >= (_bounds.left + _bounds.width() / 2))
@@ -4262,7 +4290,7 @@ bool Scene360::BsseballCards::startAction(CursorType action, Event &event) {
}
}
-bool Scene360::Object6::startAction(CursorType action, Event &event) {
+bool Scene360::Harrison::startAction(CursorType action, Event &event) {
switch (action) {
case CURSOR_LOOK:
SceneItem::display2(360, 6);
@@ -4319,13 +4347,12 @@ void Scene360::Action1::signal() {
/*--------------------------------------------------------------------------*/
-Scene360::Scene360() {
- _field380 = 0;
-}
-
void Scene360::synchronize(Serializer &s) {
SceneExt::synchronize(s);
- s.syncAsSint16LE(_field380);
+ if (s.getVersion() < 9) {
+ int tmpVar = 0;
+ s.syncAsSint16LE(tmpVar);
+ }
}
void Scene360::postInit(SceneObjectList *OwnerList) {
@@ -4403,20 +4430,19 @@ void Scene360::postInit(SceneObjectList *OwnerList) {
BF_GLOBALS._player._moveDiff.y = 4;
BF_GLOBALS._player.enableControl();
- if (BF_GLOBALS._sceneManager._previousScene == 370) {
- BF_GLOBALS._player.setPosition(Common::Point(62, 122));
- } else {
+ if ((BF_GLOBALS._sceneManager._previousScene == 355) || (BF_GLOBALS._sceneManager._previousScene != 370)) {
+ // The original was using there a useless variable (now removed)
BF_GLOBALS._player.setPosition(Common::Point(253, 135));
BF_GLOBALS._player.setStrip(2);
if (BF_GLOBALS.getFlag(fBackupIn350)) {
- _object6.postInit();
- _object6.setVisage(BF_GLOBALS.getFlag(gunDrawn) ? 363 : 1363);
- _object6.animate(ANIM_MODE_1, NULL);
- _object6.setObjectWrapper(new SceneObjectWrapper());
- _object6.setPosition(Common::Point(235, 150));
- _object6.setStrip(2);
- BF_GLOBALS._sceneItems.push_back(&_object6);
+ _harrison.postInit();
+ _harrison.setVisage(BF_GLOBALS.getFlag(gunDrawn) ? 363 : 1363);
+ _harrison.animate(ANIM_MODE_1, NULL);
+ _harrison.setObjectWrapper(new SceneObjectWrapper());
+ _harrison.setPosition(Common::Point(235, 150));
+ _harrison.setStrip(2);
+ BF_GLOBALS._sceneItems.push_back(&_harrison);
}
_sceneMode = 3607;
@@ -4431,6 +4457,9 @@ void Scene360::postInit(SceneObjectList *OwnerList) {
_slidingDoor.setPosition(Common::Point(6, 130));
_slidingDoor.setAction(&_sequenceManager1, this, 3606, &_slidingDoor, &_object7, NULL);
}
+ } else {
+ BF_GLOBALS._player.setPosition(Common::Point(62, 122));
+ BF_GLOBALS._player.enableControl();
}
_barometer._sceneRegionId = 9;
@@ -4451,7 +4480,7 @@ void Scene360::signal() {
BF_GLOBALS.setFlag(gunDrawn);
BF_GLOBALS._deathReason = BF_GLOBALS.getFlag(fBackupIn350) ? 2 : 1;
BF_GLOBALS._player.setPosition(Common::Point(BF_GLOBALS._player._position.x - 20,
- BF_GLOBALS._player._position.y));
+ BF_GLOBALS._player._position.y + 1));
_sceneMode = 3610;
setAction(&_sequenceManager1, this, 3610, &_slidingDoor, &_object2, &BF_GLOBALS._player, NULL);
break;
@@ -4460,8 +4489,13 @@ void Scene360::signal() {
setAction(&_sequenceManager1, this, 3605, &BF_GLOBALS._player, &_slidingDoor, NULL);
break;
case 3604:
- _sceneMode = BF_GLOBALS.getFlag(fBackupIn350) ? 3603 : 3605;
- setAction(&_sequenceManager1, this, _sceneMode, &_object6, NULL);
+ if (BF_GLOBALS.getFlag(fBackupIn350)) {
+ _sceneMode = 3603;
+ setAction(&_sequenceManager1, this, _sceneMode, &_harrison, NULL);
+ } else {
+ _sceneMode = 3605;
+ setAction(&_sequenceManager1, this, _sceneMode, &BF_GLOBALS._player, &_slidingDoor, NULL);
+ }
break;
case 3605:
if (BF_GLOBALS.getFlag(fBackupIn350)) {
@@ -4475,11 +4509,17 @@ void Scene360::signal() {
break;
case 3607:
case 3609:
- _object6.setVisage(1363);
+ // Original game was only using at this place visage 1363.
+ // This workaround allow Harrison to keep his gun handy
+ // when entering the romm (if required)
+ if (! BF_GLOBALS.getFlag(gunDrawn))
+ _harrison.setVisage(1363);
+ else
+ _harrison.setVisage(363);
BF_GLOBALS._player.enableControl();
break;
case 3608:
- BF_GLOBALS._sceneManager.changeScene(355);
+ BF_GLOBALS._sceneManager.changeScene(355);
break;
case 3610:
BF_GLOBALS._sceneManager.changeScene(666);
@@ -4523,7 +4563,7 @@ void Scene360::process(Event &event) {
BF_GLOBALS._player.setFrame(BF_GLOBALS._player.getFrameCount());
BF_GLOBALS._player.animate(ANIM_MODE_6, this);
- _object6.setVisage(1363);
+ _harrison.setVisage(1363);
}
} else {
// Handle drawing gun
@@ -4538,7 +4578,7 @@ void Scene360::process(Event &event) {
BF_GLOBALS.setFlag(gunDrawn);
_sceneMode = 9998;
- _object6.setVisage(363);
+ _harrison.setVisage(363);
}
event.handled = true;
@@ -4587,7 +4627,7 @@ bool Scene370::GreensGun::startAction(CursorType action, Event &event) {
case CURSOR_USE:
if ((BF_INVENTORY.getObjectScene(INV_HANDCUFFS) != 1) || BF_GLOBALS.getFlag(greenTaken)) {
BF_GLOBALS._player.disableControl();
- BF_GLOBALS._walkRegions.proc2(3);
+ BF_GLOBALS._walkRegions.enableRegion(3);
scene->_sceneMode = 3711;
scene->setAction(&scene->_sequenceManager, scene, 3711, &BF_GLOBALS._player, this, NULL);
} else {
@@ -4616,7 +4656,7 @@ bool Scene370::Green::startAction(CursorType action, Event &event) {
scene->_stripManager.start(3717, scene);
} else {
BF_GLOBALS._player.disableControl();
- BF_GLOBALS._walkRegions.proc2(3);
+ BF_GLOBALS._walkRegions.enableRegion(3);
scene->_sceneMode = 3715;
scene->setAction(&scene->_sequenceManager, scene, 3715, &BF_GLOBALS._player, this, NULL);
}
@@ -4751,37 +4791,36 @@ bool Scene370::Laura::startAction(CursorType action, Event &event) {
bool Scene370::Item1::startAction(CursorType action, Event &event) {
Scene370 *scene = (Scene370 *)BF_GLOBALS._sceneManager._scene;
- switch (action) {
- case CURSOR_LOOK:
+ if (action == CURSOR_LOOK) {
SceneItem::display2(370, 15);
return true;
- case CURSOR_USE:
+ } else if (action == CURSOR_USE) {
SceneItem::display2(370, 16);
return true;
- case INV_COLT45:
+ } else if (action == INV_COLT45) {
if (BF_GLOBALS._sceneObjects->contains(&scene->_green) && (BF_INVENTORY.getObjectScene(INV_GREENS_GUN) != 370)) {
scene->_green.setAction(NULL);
scene->_sceneMode = 3703;
scene->setAction(&scene->_sequenceManager, scene, 3703, &BF_GLOBALS._player, &scene->_green, &scene->_harrison, NULL);
return true;
}
- // Deliberate fall-through
- default:
+ return false;
+ } else if (action < CURSOR_WALK) // If any other inventory item used
+ return false;
+ else // If any other action is used
return NamedHotspot::startAction(action, event);
- }
}
bool Scene370::Item6::startAction(CursorType action, Event &event) {
Scene370 *scene = (Scene370 *)BF_GLOBALS._sceneManager._scene;
- switch (action) {
- case CURSOR_LOOK:
+ if (action == CURSOR_LOOK) {
SceneItem::display2(370, 14);
return true;
- case CURSOR_USE:
+ } else if (action == CURSOR_USE) {
SceneItem::display2(370, 29);
return true;
- case INV_COLT45:
+ } else if (action == INV_COLT45) {
if (BF_GLOBALS._sceneObjects->contains(&scene->_green) && (BF_INVENTORY.getObjectScene(INV_GREENS_GUN) != 370) &&
(BF_INVENTORY.getObjectScene(INV_HANDCUFFS) == 1)) {
BF_GLOBALS._player.disableControl();
@@ -4790,10 +4829,11 @@ bool Scene370::Item6::startAction(CursorType action, Event &event) {
scene->setAction(&scene->_sequenceManager, scene, 3703, &BF_GLOBALS._player, &scene->_green, &scene->_harrison, NULL);
return true;
}
- // Deliberate fall-through
- default:
return SceneHotspot::startAction(action, event);
- }
+ } else if (action < CURSOR_WALK) // If any other inventory item used
+ return false;
+ else // If any other action
+ return SceneHotspot::startAction(action, event);
}
@@ -4904,7 +4944,7 @@ void Scene370::signal() {
case 3:
break;
case 3707:
- _object5.setDetails(370, 6, -1, 7, 1, NULL);
+ _object5.setDetails(370, 6, -1, 7, 1, (SceneItem *)NULL);
BF_GLOBALS._sceneItems.push_back(&_object5);
// Deliberate fall-through
case 3700:
@@ -4936,7 +4976,7 @@ void Scene370::signal() {
BF_GLOBALS._player.setStrip(3);
BF_GLOBALS._sceneItems.push_front(&_laura);
- BF_GLOBALS._walkRegions.proc1(3);
+ BF_GLOBALS._walkRegions.disableRegion(3);
_harrison.setAction(NULL);
BF_GLOBALS._player.enableControl();
@@ -4946,8 +4986,8 @@ void Scene370::signal() {
break;
case 3705:
_laura.remove();
- BF_GLOBALS._walkRegions.proc2(6);
- BF_GLOBALS._walkRegions.proc2(1);
+ BF_GLOBALS._walkRegions.enableRegion(6);
+ BF_GLOBALS._walkRegions.enableRegion(1);
BF_GLOBALS._player.enableControl();
break;
case 3708:
@@ -4963,8 +5003,8 @@ void Scene370::signal() {
_sceneMode = 0;
_object5.remove();
_green.setAction(NULL);
- BF_GLOBALS._walkRegions.proc1(6);
- BF_GLOBALS._walkRegions.proc1(1);
+ BF_GLOBALS._walkRegions.disableRegion(6);
+ BF_GLOBALS._walkRegions.disableRegion(1);
break;
case 3709:
BF_GLOBALS._player.disableControl();
@@ -4978,7 +5018,7 @@ void Scene370::signal() {
_green.setAction(&_sequenceManager, this, 3701, NULL);
break;
case 3711:
- BF_GLOBALS._walkRegions.proc1(3);
+ BF_GLOBALS._walkRegions.disableRegion(3);
BF_INVENTORY.setObjectScene(INV_GREENS_GUN, 1);
T2_GLOBALS._uiElements.addScore(30);
_greensGun.remove();
@@ -5001,7 +5041,7 @@ void Scene370::signal() {
T2_GLOBALS._uiElements.addScore(50);
BF_INVENTORY.setObjectScene(INV_GREEN_ID, 1);
BF_INVENTORY.setObjectScene(INV_GREENS_KNIFE, 1);
- BF_GLOBALS._walkRegions.proc1(3);
+ BF_GLOBALS._walkRegions.disableRegion(3);
BF_GLOBALS._player.enableControl();
break;
case 3716:
@@ -5092,13 +5132,13 @@ void Scene380::postInit(SceneObjectList *OwnerList) {
setZoomPercents(68, 80, 131, 100);
BF_GLOBALS._sound1.fadeSound(33);
- BF_GLOBALS._walkRegions.proc1(9);
+ BF_GLOBALS._walkRegions.disableRegion(9);
_door.postInit();
_door.setVisage(380);
_door.setStrip(4);
_door.setPosition(Common::Point(132, 66));
- _door.setDetails(380, 12, 13, -1, 1, NULL);
+ _door.setDetails(380, 12, 13, -1, 1, (SceneItem *)NULL);
BF_GLOBALS._player.postInit();
BF_GLOBALS._player.setObjectWrapper(new SceneObjectWrapper());
@@ -5113,27 +5153,27 @@ void Scene380::postInit(SceneObjectList *OwnerList) {
// Show vechile as car
_vechile.setStrip(3);
_vechile.setPosition(Common::Point(273, 125));
- _vechile.setDetails(580, 2, 3, -1, 1, NULL);
+ _vechile.setDetails(580, 2, 3, -1, 1, (SceneItem *)NULL);
BF_GLOBALS._player.setVisage(129);
- BF_GLOBALS._walkRegions.proc1(12);
- BF_GLOBALS._walkRegions.proc1(18);
- BF_GLOBALS._walkRegions.proc1(19);
- BF_GLOBALS._walkRegions.proc1(20);
- BF_GLOBALS._walkRegions.proc1(25);
- BF_GLOBALS._walkRegions.proc1(26);
- BF_GLOBALS._walkRegions.proc1(27);
+ BF_GLOBALS._walkRegions.disableRegion(12);
+ BF_GLOBALS._walkRegions.disableRegion(18);
+ BF_GLOBALS._walkRegions.disableRegion(19);
+ BF_GLOBALS._walkRegions.disableRegion(20);
+ BF_GLOBALS._walkRegions.disableRegion(25);
+ BF_GLOBALS._walkRegions.disableRegion(26);
+ BF_GLOBALS._walkRegions.disableRegion(27);
} else if (BF_GLOBALS.getFlag(onDuty)) {
// Show on duty motorcycle
_vechile.setStrip(2);
- _vechile.setDetails(300, 11, 13, -1, 1, NULL);
+ _vechile.setDetails(300, 11, 13, -1, 1, (SceneItem *)NULL);
_vechile.setPosition(Common::Point(252, 115));
BF_GLOBALS._player.setVisage(1341);
} else {
// Show off duty motorcycle
_vechile.setStrip(1);
- _vechile.setDetails(580, 0, 1, -1, 1, NULL);
+ _vechile.setDetails(580, 0, 1, -1, 1, (SceneItem *)NULL);
_vechile.setPosition(Common::Point(249, 110));
BF_GLOBALS._player.setVisage(129);
@@ -5272,7 +5312,7 @@ bool Scene385::Door::startAction(CursorType action, Event &event) {
switch (action) {
case CURSOR_USE:
- BF_GLOBALS._walkRegions.proc2(6);
+ BF_GLOBALS._walkRegions.enableRegion(6);
BF_GLOBALS._player.disableControl();
scene->_sceneMode = 3850;
scene->setAction(&scene->_sequenceManager, scene, 3850, &BF_GLOBALS._player, this, NULL);
@@ -5285,8 +5325,7 @@ bool Scene385::Door::startAction(CursorType action, Event &event) {
bool Scene385::Jim::startAction(CursorType action, Event &event) {
Scene385 *scene = (Scene385 *)BF_GLOBALS._sceneManager._scene;
- switch (action) {
- case CURSOR_TALK:
+ if (action == CURSOR_TALK) {
if (scene->_jimFlag) {
scene->_talkAction = 3867;
scene->setAction(&scene->_action1);
@@ -5310,24 +5349,24 @@ bool Scene385::Jim::startAction(CursorType action, Event &event) {
break;
}
- scene->_jimFlag = 1;
+ scene->_jimFlag = true;
scene->setAction(&scene->_action1);
}
return true;
- case INV_PRINT_OUT:
+ } else if (action == INV_PRINT_OUT) {
if (!BF_GLOBALS.getFlag(fGotPointsForMCard)) {
T2_GLOBALS._uiElements.addScore(30);
- BF_GLOBALS.getFlag(fGotPointsForMCard);
+ BF_GLOBALS.setFlag(fGotPointsForMCard);
scene->setAction(&scene->_action2);
return true;
- }
- break;
- default:
- break;
- }
-
- return NamedObject::startAction(action, event);
+ } else
+ return false;
+ } else if (action < CURSOR_WALK)
+ // Any other inventory item
+ return false;
+ else
+ return NamedObject::startAction(action, event);
}
bool Scene385::Dezi::startAction(CursorType action, Event &event) {
@@ -5398,7 +5437,8 @@ bool Scene385::Exit::startAction(CursorType action, Event &event) {
Scene385::Scene385(): SceneExt() {
- _talkAction = _jimFlag = 0;
+ _talkAction = 0;
+ _jimFlag = false;
}
void Scene385::synchronize(Serializer &s) {
@@ -5439,21 +5479,21 @@ void Scene385::postInit(SceneObjectList *OwnerList) {
_jim.setVisage(385);
_jim.setStrip(3);
_jim.setPosition(Common::Point(304, 113));
- _jim.setDetails(385, 1, -1, 2, 1, NULL);
+ _jim.setDetails(385, 1, -1, 2, 1, (SceneItem *)NULL);
_dezi.postInit();
_dezi.setVisage(385);
_dezi.setStrip(2);
_dezi.setPosition(Common::Point(235, 93));
_dezi.fixPriority(120);
- _dezi.setDetails(385, 3, -1, 2, 1, NULL);
+ _dezi.setDetails(385, 3, -1, 2, 1, (SceneItem *)NULL);
_door.postInit();
_door.setVisage(385);
_door.setPosition(Common::Point(107, 27));
- _door.setDetails(385, 0, -1, -1, 1, NULL);
+ _door.setDetails(385, 0, -1, -1, 1, (SceneItem *)NULL);
- BF_GLOBALS._walkRegions.proc1(6);
+ BF_GLOBALS._walkRegions.disableRegion(6);
if (BF_GLOBALS._sceneManager._previousScene == 390) {
BF_GLOBALS._player.setPosition(Common::Point(109, 119));
@@ -5835,13 +5875,13 @@ void Scene390::postInit(TsAGE::SceneObjectList *OwnerList) {
_object2.setPosition(Common::Point(38, 84));
_object2.fixPriority(50);
_object2._flag = 0;
- _object2.setDetails(390, 10, 17, 10, 1, NULL);
+ _object2.setDetails(390, 10, 17, 10, 1, (SceneItem *)NULL);
_door.postInit();
_door.setVisage(390);
_door.setStrip(2);
_door.setPosition(Common::Point(151, 18));
- _door.setDetails(390, 5, -1, -1, 1, NULL);
+ _door.setDetails(390, 5, -1, -1, 1, (SceneItem *)NULL);
BF_GLOBALS._player.disableControl();
_sceneMode = 3901;
@@ -5852,7 +5892,7 @@ void Scene390::postInit(TsAGE::SceneObjectList *OwnerList) {
_green.setVisage(392);
_green.setPosition(Common::Point(241, 164));
_green.fixPriority(153);
- _green.setDetails(390, 12, -1, 13, 1, NULL);
+ _green.setDetails(390, 12, -1, 13, 1, (SceneItem *)NULL);
_green._flag = 0;
}
@@ -5862,7 +5902,7 @@ void Scene390::postInit(TsAGE::SceneObjectList *OwnerList) {
_gangMember1.setPosition(Common::Point(273, 169));
_gangMember1.fixPriority(152);
_gangMember1._flag = 0;
- _gangMember1.setDetails(390, 19, -1, 20, 1, NULL);
+ _gangMember1.setDetails(390, 19, -1, 20, 1, (SceneItem *)NULL);
_gangMember2.postInit();
_gangMember2.setVisage(396);
@@ -5870,7 +5910,7 @@ void Scene390::postInit(TsAGE::SceneObjectList *OwnerList) {
_gangMember2.setPosition(Common::Point(241, 153));
_gangMember2.fixPriority(152);
_gangMember2._flag = 0;
- _gangMember2.setDetails(390, 19, -1, 20, 1, NULL);
+ _gangMember2.setDetails(390, 19, -1, 20, 1, (SceneItem *)NULL);
}
_item1.setDetails(Rect(22, 40, 77, 67), 390, 0, -1, 1, 1, NULL);
@@ -5904,7 +5944,7 @@ void Scene390::signal() {
_object3.setVisage(390);
_object3.setPosition(Common::Point(250, 60));
_object3.fixPriority(255);
- _object3.setDetails(390, 8, -1, 9, 2, NULL);
+ _object3.setDetails(390, 8, -1, 9, 2, (SceneItem *)NULL);
BF_GLOBALS._player.enableControl();
break;
diff --git a/engines/tsage/blue_force/blueforce_scenes3.h b/engines/tsage/blue_force/blueforce_scenes3.h
index 2982fd3306..ea9d5f7311 100644
--- a/engines/tsage/blue_force/blueforce_scenes3.h
+++ b/engines/tsage/blue_force/blueforce_scenes3.h
@@ -94,7 +94,7 @@ class Scene300: public SceneExt {
virtual void signal();
};
private:
- void setup();
+ void setupInspection();
public:
SequenceManager _sequenceManager1, _sequenceManager2;
SequenceManager _sequenceManager3, _sequenceManager4;
@@ -213,9 +213,9 @@ public:
int _field1390;
int _stripNumber;
int _field1398;
- int _field1B60, _field1B62, _field1B64;
- int _field1B66, _field1B6C, _field139C;
- bool _field1B68, _field1B6A;
+ int _invGreenCount, _bookGreenCount, _invGangCount;
+ int _bookGangCount, _field1B6C, _field139C;
+ bool _field1B68, _doorOpened;
CursorType _currentCursor;
Scene315();
@@ -363,7 +363,7 @@ public:
ASoundExt _sound1, _sound2;
TimerExt _timer1;
Timer2 _timer2;
- int _seqNumber1, _field2652, _field2654;
+ int _seqNumber1, _womanDialogCount, _backupPresent;
Scene340();
virtual void synchronize(Serializer &s);
@@ -621,11 +621,11 @@ class Scene360: public SceneExt {
public:
virtual bool startAction(CursorType action, Event &event);
};
- class BsseballCards: public NamedObject {
+ class BaseballCards: public NamedObject {
public:
virtual bool startAction(CursorType action, Event &event);
};
- class Object6: public NamedObject {
+ class Harrison: public NamedObject {
public:
virtual bool startAction(CursorType action, Event &event);
};
@@ -667,8 +667,8 @@ public:
SceneObject _object2;
Window _window;
Object4 _object4;
- BsseballCards _baseballCards;
- Object6 _object6;
+ BaseballCards _baseballCards;
+ Harrison _harrison;
Object7 _object7;
Item1 _item1;
Item2 _item2;
@@ -676,9 +676,7 @@ public:
Barometer _barometer;
Action1 _action1;
ASound _sound1;
- int _field380;
- Scene360();
virtual void synchronize(Serializer &s);
virtual void postInit(SceneObjectList *OwnerList = NULL);
virtual void signal();
@@ -815,7 +813,8 @@ public:
SpeakerJake385 _jake385Speaker;
NamedHotspot _item1, _item2, _item3, _item4, _item5;
Exit _exit;
- int _talkAction, _jimFlag;
+ int _talkAction;
+ bool _jimFlag;
Scene385();
virtual void synchronize(Serializer &s);
diff --git a/engines/tsage/blue_force/blueforce_scenes4.cpp b/engines/tsage/blue_force/blueforce_scenes4.cpp
index 814a2fff7f..a10f311791 100644
--- a/engines/tsage/blue_force/blueforce_scenes4.cpp
+++ b/engines/tsage/blue_force/blueforce_scenes4.cpp
@@ -35,6 +35,7 @@ namespace BlueForce {
*
*--------------------------------------------------------------------------*/
+// Talk to driver with backup
void Scene410::Action1::signal() {
Scene410 *scene = (Scene410 *)BF_GLOBALS._sceneManager._scene;
@@ -62,6 +63,7 @@ void Scene410::Action1::signal() {
}
}
+// Talk to passenger with backup
void Scene410::Action2::signal() {
Scene410 *scene = (Scene410 *)BF_GLOBALS._sceneManager._scene;
BF_GLOBALS._player.disableControl();
@@ -98,6 +100,7 @@ void Scene410::Action2::signal() {
}
}
+// Talk to passenger without backup
void Scene410::Action3::signal() {
Scene410 *scene = (Scene410 *)BF_GLOBALS._sceneManager._scene;
if (BF_GLOBALS.getFlag(fTalkedShooterNoBkup)) {
@@ -111,36 +114,23 @@ void Scene410::Action3::signal() {
}
}
+// Talk to driver without backup
void Scene410::Action4::signal() {
Scene410 *scene = (Scene410 *)BF_GLOBALS._sceneManager._scene;
- switch (_actionIndex++) {
- case 0:
- if (scene->_field1FC4 == 0) {
- ADD_PLAYER_MOVER(114, 133);
- } else {
- ADD_PLAYER_MOVER(195, 139);
- }
- break;
- case 1:
- BF_GLOBALS._player.updateAngle(scene->_passenger._position);
- setDelay(3);
- break;
- case 2:
- setDelay(3);
- break;
- case 3:
- if (BF_GLOBALS.getFlag(fCalledBackup))
- scene->setAction(&scene->_action2);
- else
- scene->setAction(&scene->_action3);
- remove();
- break;
- default:
- break;
+ if (BF_GLOBALS.getFlag(fTalkedDriverNoBkup)) {
+ BF_GLOBALS._player.disableControl();
+ scene->_sceneMode = 2;
+ scene->setAction(&scene->_sequenceManager1, scene, 4120, &scene->_passenger, &BF_GLOBALS._player, NULL);
+ } else {
+ BF_GLOBALS._player.disableControl();
+ BF_GLOBALS.setFlag(fTalkedDriverNoBkup);
+ scene->_sceneMode = 4101;
+ scene->_stripManager.start(4103, scene);
}
}
+// Talk to passenger
void Scene410::Action5::signal() {
Scene410 *scene = (Scene410 *)BF_GLOBALS._sceneManager._scene;
@@ -171,6 +161,7 @@ void Scene410::Action5::signal() {
}
}
+// Talk to driver
void Scene410::Action6::signal() {
Scene410 *scene = (Scene410 *)BF_GLOBALS._sceneManager._scene;
@@ -222,7 +213,7 @@ void Scene410::Action7::signal() {
case 3:
BF_GLOBALS._player.setObjectWrapper(new SceneObjectWrapper());
BF_GLOBALS._player.updateAngle(Common::Point(100, 170));
- scene->setAction(&scene->_sequenceManager1, this, 4112, &scene->_driver, &scene->_passenger,
+ setAction(&scene->_sequenceManager1, this, 4112, &scene->_driver, &scene->_passenger,
&scene->_harrison, NULL);
break;
case 5:
@@ -380,21 +371,27 @@ bool Scene410::Passenger::startAction(CursorType action, Event &event) {
switch (action) {
case CURSOR_USE:
if (!BF_GLOBALS.getFlag(fCalledBackup)) {
- if (BF_GLOBALS.getFlag(fTalkedShooterNoBkup)) {
+ if (BF_GLOBALS.getFlag(fTalkedShooterNoBkup))
scene->setAction(&scene->_action3);
- } else {
- SceneItem::display2(410, 5);
- }
+ else
+ SceneItem::display(410, 5, SET_WIDTH, 300,
+ SET_X, 10 + GLOBALS._sceneManager._scene->_sceneBounds.left,
+ SET_Y, GLOBALS._sceneManager._scene->_sceneBounds.top + UI_INTERFACE_Y + 2,
+ SET_FONT, 4, SET_BG_COLOR, 1, SET_FG_COLOR, 96, SET_EXT_BGCOLOR, 99,
+ SET_EXT_FGCOLOR, 13, LIST_END);
} else if (!scene->_field1FBA) {
- SceneItem::display2(410, 5);
+ SceneItem::display(410, 5, SET_WIDTH, 300,
+ SET_X, 10 + GLOBALS._sceneManager._scene->_sceneBounds.left,
+ SET_Y, GLOBALS._sceneManager._scene->_sceneBounds.top + UI_INTERFACE_Y + 2,
+ SET_FONT, 4, SET_BG_COLOR, 1, SET_FG_COLOR, 96, SET_EXT_BGCOLOR, 99,
+ SET_EXT_FGCOLOR, 13, LIST_END);
} else if (!scene->_field1FBE) {
scene->_sceneMode = 4121;
scene->_field1FBE = 1;
T2_GLOBALS._uiElements.addScore(50);
scene->signal();
- } else {
+ } else
break;
- }
return true;
case CURSOR_TALK:
scene->setAction(&scene->_action5);
@@ -452,7 +449,11 @@ bool Scene410::Harrison::startAction(CursorType action, Event &event) {
PlayerMover *mover = new PlayerMover();
BF_GLOBALS._player.addMover(mover, &destPos, scene);
} else {
- SceneItem::display2(350, 13);
+ SceneItem::display(350, 13, SET_WIDTH, 300,
+ SET_X, 10 + GLOBALS._sceneManager._scene->_sceneBounds.left,
+ SET_Y, GLOBALS._sceneManager._scene->_sceneBounds.top + UI_INTERFACE_Y + 2,
+ SET_FONT, 4, SET_BG_COLOR, 1, SET_FG_COLOR, 32, SET_EXT_BGCOLOR, 49,
+ SET_EXT_FGCOLOR, 13, LIST_END);
}
} else if ((scene->_field1FBA != 0) && (scene->_field1FBC != 0)) {
BF_GLOBALS._player.disableControl();
@@ -463,15 +464,16 @@ bool Scene410::Harrison::startAction(CursorType action, Event &event) {
BF_GLOBALS.clearFlag(f1098Marina);
} else if ((BF_INVENTORY.getObjectScene(INV_HANDCUFFS) == 1) ||
(!scene->_field1FBA && (scene->_talkCount < 5))) {
- SceneItem::display2(350, 13);
+ SceneItem::display(350, 13, SET_WIDTH, 300,
+ SET_X, 10 + GLOBALS._sceneManager._scene->_sceneBounds.left,
+ SET_Y, GLOBALS._sceneManager._scene->_sceneBounds.top + UI_INTERFACE_Y + 2,
+ SET_FONT, 4, SET_BG_COLOR, 1, SET_FG_COLOR, 32, SET_EXT_BGCOLOR, 49,
+ SET_EXT_FGCOLOR, 13, LIST_END);
} else if (!scene->_field1FBA) {
- if (scene->_field1FBA)
- error("Error - want to cuff shooter, but he's cuffed already");
-
BF_GLOBALS._player.disableControl();
scene->_field1FBA = 1;
scene->_field1FBE = 1;
- BF_GLOBALS._walkRegions.proc2(22);
+ BF_GLOBALS._walkRegions.enableRegion(22);
scene->_sceneMode = 4122;
scene->_stripManager.start(4112, scene);
} else if (scene->_field1FB6 < 1) {
@@ -482,7 +484,7 @@ bool Scene410::Harrison::startAction(CursorType action, Event &event) {
BF_GLOBALS._player.disableControl();
scene->_field1FBC = 1;
scene->_field1FC0 = 1;
- BF_GLOBALS._walkRegions.proc2(22);
+ BF_GLOBALS._walkRegions.enableRegion(22);
scene->_sceneMode = 4109;
scene->_stripManager.start(4112, scene);
}
@@ -545,13 +547,13 @@ void Scene410::postInit(SceneObjectList *OwnerList) {
_passenger.setVisage(415);
_passenger.setStrip(1);
_passenger.setPosition(Common::Point(278, 92));
- _passenger.setDetails(410, 4, -1, 5, 1, NULL);
+ _passenger.setDetails(410, 4, -1, 5, 1, (SceneItem *)NULL);
_driver.postInit();
_driver.setVisage(416);
_driver.setStrip(2);
_driver.setPosition(Common::Point(244, 85));
- _driver.setDetails(410, 6, -1, 7, 1, NULL);
+ _driver.setDetails(410, 6, -1, 7, 1, (SceneItem *)NULL);
_driver.changeZoom(-1);
_object5.postInit();
@@ -574,20 +576,20 @@ void Scene410::postInit(SceneObjectList *OwnerList) {
_passenger.remove();
_driver.remove();
- BF_GLOBALS._walkRegions.proc1(21);
- BF_GLOBALS._walkRegions.proc1(22);
+ BF_GLOBALS._walkRegions.disableRegion(21);
+ BF_GLOBALS._walkRegions.disableRegion(22);
_harrison.postInit();
_harrison.setVisage(343);
_harrison.setObjectWrapper(new SceneObjectWrapper());
_harrison.animate(ANIM_MODE_1, NULL);
- _harrison.setDetails(350, 12, 13, 14, 1, NULL);
+ _harrison.setDetails(350, 12, 13, 14, 1, (SceneItem *)NULL);
_harrison.setPosition(Common::Point(97, 185));
_harrison.changeZoom(-1);
_patrolCar.postInit();
_patrolCar.setVisage(410);
- _patrolCar.setDetails(410, 8, 9, 10, 1, NULL);
+ _patrolCar.setDetails(410, 8, 9, 10, 1, (SceneItem *)NULL);
_patrolCar.fixPriority(148);
_patrolCar.setPosition(Common::Point(39, 168));
@@ -621,24 +623,24 @@ void Scene410::postInit(SceneObjectList *OwnerList) {
_passenger.setFrame(8);
}
- BF_GLOBALS._walkRegions.proc1(16);
+ BF_GLOBALS._walkRegions.disableRegion(16);
if (BF_GLOBALS.getFlag(fDriverOutOfTruck)) {
_driver.setVisage(417);
_driver.setStrip(1);
_driver.setPosition(Common::Point(152, 97));
- BF_GLOBALS._walkRegions.proc1(7);
+ BF_GLOBALS._walkRegions.disableRegion(7);
}
if (BF_GLOBALS.getFlag(fCalledBackup)) {
- BF_GLOBALS._walkRegions.proc1(21);
- BF_GLOBALS._walkRegions.proc1(22);
+ BF_GLOBALS._walkRegions.disableRegion(21);
+ BF_GLOBALS._walkRegions.disableRegion(22);
_harrison.postInit();
_harrison.setVisage(343);
_harrison.setObjectWrapper(new SceneObjectWrapper());
_harrison.animate(ANIM_MODE_1, NULL);
- _harrison.setDetails(350, 12, 13, 14, 1, NULL);
+ _harrison.setDetails(350, 12, 13, 14, 1, (SceneItem *)NULL);
BF_GLOBALS._sceneItems.addBefore(&_driver, &_harrison);
_harrison.setPosition(Common::Point(-10, 124));
@@ -646,7 +648,7 @@ void Scene410::postInit(SceneObjectList *OwnerList) {
_patrolCar.postInit();
_patrolCar.setVisage(410);
- _patrolCar.setDetails(410, 8, 9, 10, 1, NULL);
+ _patrolCar.setDetails(410, 8, 9, 10, 1, (SceneItem *)NULL);
_patrolCar.fixPriority(148);
if (_field1FC4) {
@@ -715,10 +717,11 @@ void Scene410::signal() {
break;
case 7:
BF_INVENTORY.setObjectScene(INV_TYRONE_ID, 1);
+ _sceneMode = 0;
signal();
break;
case 8:
- BF_GLOBALS._walkRegions.proc2(22);
+ BF_GLOBALS._walkRegions.enableRegion(22);
BF_GLOBALS._player.changeAngle(225);
_harrison.changeAngle(45);
_sceneMode = 4114;
@@ -739,7 +742,7 @@ void Scene410::signal() {
BF_GLOBALS._player.disableControl();
_sceneMode = 0;
setAction(&_sequenceManager1, this, 4100, &_passenger, &_object5, NULL);
- BF_GLOBALS._walkRegions.proc1(16);
+ BF_GLOBALS._walkRegions.disableRegion(16);
break;
case 4101:
// Driver gets out of the car
@@ -747,7 +750,7 @@ void Scene410::signal() {
_sceneMode = 0;
setAction(&_sequenceManager1, this, 4101, &_driver, &_object6, NULL);
BF_GLOBALS.setFlag(fDriverOutOfTruck);
- BF_GLOBALS._walkRegions.proc1(7);
+ BF_GLOBALS._walkRegions.disableRegion(7);
break;
case 4103:
// Click on moto to ask for backup
@@ -781,19 +784,21 @@ void Scene410::signal() {
case 4108:
BF_GLOBALS._player.setObjectWrapper(new SceneObjectWrapper());
BF_GLOBALS._player.updateAngle(Common::Point(100, 170));
- BF_GLOBALS._walkRegions.proc2(22);
- BF_GLOBALS._walkRegions.proc2(16);
+ BF_GLOBALS._walkRegions.enableRegion(22);
+ BF_GLOBALS._walkRegions.enableRegion(7);
+ BF_GLOBALS._walkRegions.enableRegion(16);
BF_GLOBALS._player.disableControl();
_sceneMode = 0;
setAction(&_sequenceManager1, this, 4108, &_harrison, NULL);
break;
case 4109:
+ // Harrison puts handcuffs to driver
if ((BF_GLOBALS._player._position.x > 116) && (BF_GLOBALS._player._position.x != 195) &&
(BF_GLOBALS._player._position.y != 139)) {
- ADD_PLAYER_MOVER(195, 139);
+ ADD_PLAYER_MOVER_NULL(BF_GLOBALS._player, 195, 139);
}
- BF_GLOBALS._walkRegions.proc2(22);
+ BF_GLOBALS._walkRegions.enableRegion(22);
BF_GLOBALS._player.disableControl();
_sceneMode = 0;
setAction(&_sequenceManager1, this, 4109, &_driver, &_harrison, NULL);
@@ -813,14 +818,14 @@ void Scene410::signal() {
setAction(&_sequenceManager1, this, 4112, &_driver, &_passenger, &_harrison, NULL);
break;
case 4114:
- BF_GLOBALS._walkRegions.proc2(22);
+ BF_GLOBALS._walkRegions.enableRegion(22);
BF_GLOBALS._player.disableControl();
_sceneMode = 4116;
setAction(&_sequenceManager1, this, 4114, &_harrison, &_patrolCar, NULL);
break;
case 4116:
- BF_GLOBALS._walkRegions.proc2(21);
- BF_GLOBALS._walkRegions.proc2(22);
+ BF_GLOBALS._walkRegions.enableRegion(21);
+ BF_GLOBALS._walkRegions.enableRegion(22);
_harrison.remove();
BF_GLOBALS._player.disableControl();
_sceneMode = 0;
@@ -842,7 +847,7 @@ void Scene410::signal() {
setAction(&_sequenceManager1, this, 4121, &BF_GLOBALS._player, &_passenger, NULL);
break;
case 4122:
- BF_GLOBALS._walkRegions.proc2(22);
+ BF_GLOBALS._walkRegions.enableRegion(22);
BF_INVENTORY.setObjectScene(INV_22_SNUB, 0);
BF_GLOBALS._player.disableControl();
_sceneMode = 0;
@@ -923,6 +928,17 @@ bool Scene415::GunInset::startAction(CursorType action, Event &event) {
}
}
+void Scene415::GunInset::remove() {
+ Scene415 *scene = (Scene415 *)BF_GLOBALS._sceneManager._scene;
+
+ BF_GLOBALS._player.disableControl();
+ scene->_gunAndWig.remove();
+ FocusObject::remove();
+
+ scene->_sceneMode = 0;
+ scene->_animatedSeat.animate(ANIM_MODE_6, scene);
+}
+
bool Scene415::GunAndWig::startAction(CursorType action, Event &event) {
Scene415 *scene = (Scene415 *)BF_GLOBALS._sceneManager._scene;
@@ -937,14 +953,14 @@ bool Scene415::GunAndWig::startAction(CursorType action, Event &event) {
remove();
return true;
case INV_FOREST_RAP:
- if (scene->_fieldE14)
+ if (scene->_scoreWigRapFlag)
break;
BF_GLOBALS._player.disableControl();
scene->_sceneMode = 0;
scene->_stripManager.start(4126, scene);
T2_GLOBALS._uiElements.addScore(50);
- scene->_fieldE14 = true;
+ scene->_scoreWigRapFlag = true;
return true;
default:
break;
@@ -957,7 +973,7 @@ bool Scene415::BulletsInset::startAction(CursorType action, Event &event) {
Scene415 *scene = (Scene415 *)BF_GLOBALS._sceneManager._scene;
if (action == CURSOR_USE) {
- if (BF_GLOBALS.getFlag(fGotAutoWeapon)) {
+ if (BF_GLOBALS.getFlag(fGotBulletsFromDash)) {
FocusObject::startAction(action, event);
} else {
remove();
@@ -969,6 +985,13 @@ bool Scene415::BulletsInset::startAction(CursorType action, Event &event) {
}
}
+void Scene415::BulletsInset::remove() {
+ Scene415 *scene = (Scene415 *)BF_GLOBALS._sceneManager._scene;
+
+ scene->_theBullets.remove();
+ FocusObject::remove();
+}
+
bool Scene415::DashDrawer::startAction(CursorType action, Event &event) {
Scene415 *scene = (Scene415 *)BF_GLOBALS._sceneManager._scene;
@@ -994,17 +1017,16 @@ bool Scene415::TheBullets::startAction(CursorType action, Event &event) {
scene->_dashDrawer.remove();
return true;
case INV_FOREST_RAP:
- if (scene->_fieldE16) {
+ if (scene->_scoreBulletRapFlag) {
SceneItem::display2(415, 35);
- return true;
} else {
BF_GLOBALS._player.disableControl();
scene->_sceneMode = 0;
scene->_stripManager.start(4122, scene);
T2_GLOBALS._uiElements.addScore(50);
- scene->_fieldE16 = true;
+ scene->_scoreBulletRapFlag = true;
}
- break;
+ return true;
default:
break;
}
@@ -1024,7 +1046,7 @@ bool Scene415::Lever::startAction(CursorType action, Event &event) {
} else {
BF_GLOBALS._player.disableControl();
scene->_sceneMode = 2;
- scene->setAction(&scene->_sequenceManager, scene, 4150, &scene->_object6, NULL);
+ scene->setAction(&scene->_sequenceManager, scene, 4150, &scene->_animatedSeat, NULL);
}
return true;
default:
@@ -1035,13 +1057,13 @@ bool Scene415::Lever::startAction(CursorType action, Event &event) {
/*--------------------------------------------------------------------------*/
Scene415::Scene415(): SceneExt() {
- _fieldE14 = _fieldE16 = false;
+ _scoreWigRapFlag = _scoreBulletRapFlag = false;
}
void Scene415::synchronize(Serializer &s) {
SceneExt::synchronize(s);
- s.syncAsSint16LE(_fieldE14);
- s.syncAsSint16LE(_fieldE16);
+ s.syncAsSint16LE(_scoreWigRapFlag);
+ s.syncAsSint16LE(_scoreBulletRapFlag);
}
void Scene415::postInit(SceneObjectList *OwnerList) {
@@ -1054,14 +1076,14 @@ void Scene415::postInit(SceneObjectList *OwnerList) {
_dashDrawer.setVisage(411);
_dashDrawer.setStrip(3);
_dashDrawer.setPosition(Common::Point(151, 97));
- _dashDrawer.setDetails(415, 22, -1, -1, 1, NULL);
+ _dashDrawer.setDetails(415, 22, -1, -1, 1, (SceneItem *)NULL);
+
+ _animatedSeat.postInit();
+ _animatedSeat.setVisage(419);
+ _animatedSeat.setStrip(1);
+ _animatedSeat.setPosition(Common::Point(306, 116));
+ _animatedSeat.fixPriority(80);
- _object6.postInit();
- _object6.setVisage(419);
- _object6.setStrip(1);
- _object6.setPosition(Common::Point(306, 116));
- _object6.fixPriority(80);
-
_windowLever.setDetails(16, 415, 25, -1, 26, 1);
_item7.setDetails(17, 415, 32, -1, 33, 1);
_seatBelt.setDetails(14, 415, 29, -1, 30, 1);
@@ -1118,7 +1140,7 @@ void Scene415::showBullets() {
_theBullets.setFrame(2);
_theBullets.setPosition(Common::Point(184, 86));
_theBullets.fixPriority(105);
- _theBullets.setDetails(415, 16, 17, 18, 1, NULL);
+ _theBullets.setDetails(415, 16, 17, 18, 1, (SceneItem *)NULL);
BF_GLOBALS._sceneItems.remove(&_theBullets);
BF_GLOBALS._sceneItems.push_front(&_theBullets);
}
@@ -1136,7 +1158,7 @@ void Scene415::showGunAndWig() {
_gunAndWig.setFrame(2);
_gunAndWig.setPosition(Common::Point(159, 88));
_gunAndWig.fixPriority(105);
- _gunAndWig.setDetails(415, 13, 14, 15, 1, NULL);
+ _gunAndWig.setDetails(415, 13, 14, 15, 1, (SceneItem *)NULL);
BF_GLOBALS._sceneItems.remove(&_gunAndWig);
BF_GLOBALS._sceneItems.push_front(&_gunAndWig);
@@ -1249,12 +1271,12 @@ void Scene440::postInit(SceneObjectList *OwnerList) {
BF_GLOBALS._player.setVisage(303);
BF_GLOBALS._player.setPosition(Common::Point(187, 104));
-
+
_lyle.setPosition(Common::Point(135, 128));
_lyle.show();
- BF_GLOBALS._walkRegions.proc1(12);
- BF_GLOBALS._walkRegions.proc1(13);
+ BF_GLOBALS._walkRegions.disableRegion(12);
+ BF_GLOBALS._walkRegions.disableRegion(13);
} else {
_vechile.setPosition(Common::Point(169, 121));
_vechile.fixPriority(117);
@@ -1269,13 +1291,13 @@ void Scene440::postInit(SceneObjectList *OwnerList) {
_vechile.setVisage(580);
_vechile.setStrip(2);
_vechile.setFrame(3);
-
+
BF_GLOBALS._player.setVisage(303);
}
}
BF_GLOBALS._sceneItems.push_back(&_vechile);
- BF_GLOBALS._walkRegions.proc1(11);
+ BF_GLOBALS._walkRegions.disableRegion(11);
_doorway.postInit();
_doorway.setVisage(440);
@@ -1288,7 +1310,7 @@ void Scene440::postInit(SceneObjectList *OwnerList) {
_lyle.setPosition(Common::Point(143, 93));
_lyle.setStrip(5);
_lyle.fixPriority(90);
-
+
_doorway.setFrame(_doorway.getFrameCount());
_sceneMode = 4401;
setAction(&_sequenceManager, this, 4401, &BF_GLOBALS._player, &_doorway, NULL);
@@ -1353,7 +1375,7 @@ bool Scene450::Weasel::startAction(CursorType action, Event &event) {
T2_GLOBALS._uiElements.addScore(30);
scene->_sceneMode = 4505;
- scene->setAction(&scene->_sequenceManager, scene, 4505, &BF_GLOBALS._player, this,
+ scene->setAction(&scene->_sequenceManager, scene, 4505, &BF_GLOBALS._player, this,
&scene->_counterDoor, &scene->_object2, NULL);
return true;
default:
@@ -1405,7 +1427,7 @@ bool Scene450::Manager::startAction(CursorType action, Event &event) {
if (BF_GLOBALS.getFlag(takenWeasel) && !BF_GLOBALS.getFlag(gotTrailer450)) {
BF_GLOBALS.setFlag(gotTrailer450);
scene->_sceneMode = 4517;
- scene->setAction(&scene->_sequenceManager, scene, 4517, &BF_GLOBALS._player, this,
+ scene->setAction(&scene->_sequenceManager, scene, 4517, &BF_GLOBALS._player, this,
&scene->_door, NULL);
} else {
animate(ANIM_MODE_8, 1, NULL);
@@ -1463,11 +1485,11 @@ bool Scene450::Manager::startAction(CursorType action, Event &event) {
} else {
animate(ANIM_MODE_8, 1, NULL);
BF_GLOBALS._player.disableControl();
-
+
if (!BF_GLOBALS.getFlag(showEugeneID))
T2_GLOBALS._uiElements.addScore(30);
BF_GLOBALS.setFlag(showEugeneID);
-
+
if ((BF_GLOBALS.getFlag(showRapEugene) || BF_GLOBALS.getFlag(showEugeneNapkin)) &&
!BF_GLOBALS.getFlag(fMgrCallsWeasel)) {
T2_GLOBALS._uiElements.addScore(30);
@@ -1537,13 +1559,13 @@ void Scene450::postInit(SceneObjectList *OwnerList) {
_door.setVisage(450);
_door.setStrip(2);
_door.setPosition(Common::Point(72, 80));
- _door.setDetails(450, 15, -1, 13, 1, NULL);
+ _door.setDetails(450, 15, -1, 13, 1, (SceneItem *)NULL);
_counterDoor.postInit();
_counterDoor.setVisage(450);
_counterDoor.setPosition(Common::Point(39, 104));
_counterDoor.fixPriority(100);
- _counterDoor.setDetails(450, 12, -1, 13, 1, NULL);
+ _counterDoor.setDetails(450, 12, -1, 13, 1, (SceneItem *)NULL);
if (BF_GLOBALS._dayNumber != 3) {
_pinBoy.postInit();
@@ -1576,9 +1598,9 @@ void Scene450::postInit(SceneObjectList *OwnerList) {
_object2.setPosition(Common::Point(-30, 126));
ADD_MOVER_NULL(_object2, 27, 126);
_object2.changeZoom(-1);
- _object2.setDetails(450, 2, 18, 3, 1, NULL);
+ _object2.setDetails(450, 2, 18, 3, 1, (SceneItem *)NULL);
- BF_GLOBALS._walkRegions.proc1(4);
+ BF_GLOBALS._walkRegions.disableRegion(4);
_weasel.postInit();
_weasel.setVisage(466);
@@ -1625,7 +1647,7 @@ void Scene450::signal() {
BF_GLOBALS.setFlag(takenWeasel);
_weasel.remove();
_object2.remove();
- BF_GLOBALS._walkRegions.proc2(4);
+ BF_GLOBALS._walkRegions.enableRegion(4);
BF_GLOBALS._player.enableControl();
break;
case 4507:
diff --git a/engines/tsage/blue_force/blueforce_scenes4.h b/engines/tsage/blue_force/blueforce_scenes4.h
index 6c40211f28..937c015a4c 100644
--- a/engines/tsage/blue_force/blueforce_scenes4.h
+++ b/engines/tsage/blue_force/blueforce_scenes4.h
@@ -133,6 +133,7 @@ class Scene415: public SceneExt {
class GunInset: public FocusObject {
public:
virtual bool startAction(CursorType action, Event &event);
+ virtual void remove();
};
class GunAndWig: public NamedObject {
public:
@@ -141,6 +142,7 @@ class Scene415: public SceneExt {
class BulletsInset: public FocusObject {
public:
virtual bool startAction(CursorType action, Event &event);
+ virtual void remove();
};
class DashDrawer: public NamedObject {
public:
@@ -166,12 +168,12 @@ public:
BulletsInset _bulletsInset;
DashDrawer _dashDrawer;
TheBullets _theBullets;
- NamedObject _object6;
+ NamedObject _animatedSeat;
NamedHotspot _item1, _steeringWheel, _horn, _dashboard;
NamedHotspot _seat, _windowLever, _item7, _seatBelt;
Lever _lever;
SpeakerJakeRadio _jakeRadioSpeaker;
- bool _fieldE14, _fieldE16;
+ bool _scoreWigRapFlag, _scoreBulletRapFlag;
Scene415();
virtual void postInit(SceneObjectList *OwnerList = NULL);
diff --git a/engines/tsage/blue_force/blueforce_scenes5.cpp b/engines/tsage/blue_force/blueforce_scenes5.cpp
index 500cad60b1..abadc4300a 100644
--- a/engines/tsage/blue_force/blueforce_scenes5.cpp
+++ b/engines/tsage/blue_force/blueforce_scenes5.cpp
@@ -60,7 +60,7 @@ bool Scene550::Lyle::startAction(CursorType action, Event &event) {
switch (action) {
case CURSOR_TALK:
- if ((BF_INVENTORY.getObjectScene(INV_SCHEDULE) == 1) ||
+ if ((BF_INVENTORY.getObjectScene(INV_SCHEDULE) == 1) ||
(BF_INVENTORY.getObjectScene(INV_9MM_BULLETS) == 1)) {
if ((BF_INVENTORY.getObjectScene(INV_SCHEDULE) == 1) &&
(BF_INVENTORY.getObjectScene(INV_9MM_BULLETS) == 1)) {
@@ -132,7 +132,7 @@ bool Scene550::Vechile::startAction(CursorType action, Event &event) {
BF_GLOBALS._player.disableControl();
scene->_sceneMode = 2;
scene->setAction(&scene->_sequenceManager, scene, 5501, &BF_GLOBALS._player, NULL);
- } else if ((BF_INVENTORY.getObjectScene(INV_SCHEDULE) == 1) ||
+ } else if ((BF_INVENTORY.getObjectScene(INV_SCHEDULE) == 1) ||
(BF_INVENTORY.getObjectScene(INV_9MM_BULLETS) == 1)) {
if (BF_INVENTORY.getObjectScene(INV_9MM_BULLETS) == 1) {
scene->_sceneMode = 5501;
@@ -164,11 +164,11 @@ void Scene550::postInit(SceneObjectList *OwnerList) {
_sceneMode = 1;
signal();
return;
- }
+ }
SceneExt::postInit();
loadScene(550);
-
+
_stripManager.addSpeaker(&_gameTextSpeaker);
_stripManager.addSpeaker(&_lyleHatSpeaker);
_stripManager.addSpeaker(&_jakeJacketSpeaker);
@@ -189,8 +189,8 @@ void Scene550::postInit(SceneObjectList *OwnerList) {
_vechile.fixPriority(70);
if (BF_GLOBALS.getFlag(fWithLyle)) {
- BF_GLOBALS._walkRegions.proc1(10);
- BF_GLOBALS._walkRegions.proc1(11);
+ BF_GLOBALS._walkRegions.disableRegion(10);
+ BF_GLOBALS._walkRegions.disableRegion(11);
_vechile.setVisage(444);
_vechile.setStrip(4);
@@ -201,14 +201,14 @@ void Scene550::postInit(SceneObjectList *OwnerList) {
_lyle.postInit();
_lyle.setVisage(835);
_lyle.setPosition(Common::Point(139, 83));
- _lyle.setDetails(550, 29, 30, 31, 1, NULL);
+ _lyle.setDetails(550, 29, 30, 31, 1, (SceneItem *)NULL);
_lyle.setStrip(8);
BF_GLOBALS._player.setVisage(303);
BF_GLOBALS._player.setPosition(Common::Point(89, 76));
BF_GLOBALS._player.updateAngle(_lyle._position);
} else {
- BF_GLOBALS._walkRegions.proc1(12);
+ BF_GLOBALS._walkRegions.disableRegion(12);
_vechile.setPosition(Common::Point(205, 77));
_vechile.changeZoom(80);
@@ -216,7 +216,7 @@ void Scene550::postInit(SceneObjectList *OwnerList) {
if (BF_GLOBALS.getFlag(onDuty)) {
_vechile.setVisage(301);
_vechile.setStrip(1);
-
+
BF_GLOBALS._player.setVisage(304);
} else {
_vechile.setVisage(580);
@@ -224,7 +224,7 @@ void Scene550::postInit(SceneObjectList *OwnerList) {
_vechile.setFrame(2);
BF_GLOBALS._player.setVisage(303);
- }
+ }
}
BF_GLOBALS._sceneItems.push_back(&_vechile);
@@ -296,10 +296,10 @@ void Scene551::Action2::signal() {
switch (_actionIndex++) {
case 0:
- BF_GLOBALS._walkRegions.proc2(18);
- BF_GLOBALS._walkRegions.proc2(4);
+ BF_GLOBALS._walkRegions.enableRegion(18);
+ BF_GLOBALS._walkRegions.enableRegion(4);
scene->_field1CD2 = 1;
-
+
scene->_harrison.setObjectWrapper(new SceneObjectWrapper());
scene->_harrison.animate(ANIM_MODE_1, NULL);
@@ -316,7 +316,7 @@ void Scene551::Action2::signal() {
scene->_harrison.updateAngle(BF_GLOBALS._player._position);
if (scene->_drunkStanding._flag == 1) {
- BF_GLOBALS._walkRegions.proc1(4);
+ BF_GLOBALS._walkRegions.disableRegion(4);
ADD_PLAYER_MOVER(71, 97);
} else {
ADD_PLAYER_MOVER(141, 87);
@@ -486,7 +486,7 @@ bool Scene551::PatrolCarTrunk::startAction(CursorType action, Event &event) {
switch (action) {
case CURSOR_USE:
if (BF_INVENTORY.getObjectScene(INV_CENTER_PUNCH) != 1) {
- BF_GLOBALS._walkRegions.proc2(18);
+ BF_GLOBALS._walkRegions.enableRegion(18);
BF_GLOBALS._player.disableControl();
scene->_sceneMode = 2;
scene->setAction(&scene->_sequenceManager, scene, 5503, &BF_GLOBALS._player, &scene->_harrison, this, NULL);
@@ -506,7 +506,7 @@ void Scene551::TrunkInset::remove() {
BF_GLOBALS._player.disableControl();
scene->_sceneMode = 0;
- scene->setAction(&scene->_sequenceManager, scene, 5516, &scene->_harrison,
+ scene->setAction(&scene->_sequenceManager, scene, 5516, &scene->_harrison,
&scene->_patrolCarTrunk, NULL);
FocusObject::remove();
@@ -681,7 +681,7 @@ void Scene551::postInit(SceneObjectList *OwnerList) {
_vechile2.changeZoom(80);
BF_GLOBALS._sceneItems.push_back(&_vechile2);
- BF_GLOBALS._walkRegions.proc1(14);
+ BF_GLOBALS._walkRegions.disableRegion(14);
_drunk.postInit();
_drunk.setVisage(550);
@@ -702,16 +702,16 @@ void Scene551::postInit(SceneObjectList *OwnerList) {
_object13.setStrip(2);
_object13.setPosition(Common::Point(29, 92));
_object13.fixPriority(82);
- _object13.setDetails(550, 8, -1, 9, 1, NULL);
+ _object13.setDetails(550, 8, -1, 9, 1, (SceneItem *)NULL);
if (BF_GLOBALS.getFlag(didDrunk)) {
_drunk._flag = 3;
_drunk.setStrip(3);
_object12.show();
- _object12.setDetails(550, 25, -1, 26, 1, NULL);
+ _object12.setDetails(550, 25, -1, 26, 1, (SceneItem *)NULL);
BF_GLOBALS._sceneItems.push_front(&_object12);
-
+
_harrison.postInit();
_harrison.setVisage(304);
_harrison.setPosition(Common::Point(67, 102));
@@ -733,7 +733,7 @@ void Scene551::postInit(SceneObjectList *OwnerList) {
_object11.setFrame(2);
_object11.setPosition(Common::Point(116, 84));
_object11.fixPriority(77);
- _object11.setDetails(550, 32, -1, 10, 1, NULL);
+ _object11.setDetails(550, 32, -1, 10, 1, (SceneItem *)NULL);
_drunkStanding.postInit();
_drunkStanding._flag = 0;
@@ -764,7 +764,7 @@ void Scene551::postInit(SceneObjectList *OwnerList) {
_patrolCarTrunk.setFrame(1);
_patrolCarTrunk.setPosition(Common::Point(149, 69));
_patrolCarTrunk.fixPriority(79);
- _patrolCarTrunk.setDetails(550, 18, -1, 9, 1, NULL);
+ _patrolCarTrunk.setDetails(550, 18, -1, 9, 1, (SceneItem *)NULL);
_object11.postInit();
_object11.setVisage(550);
@@ -772,7 +772,7 @@ void Scene551::postInit(SceneObjectList *OwnerList) {
_object11.setFrame(2);
_object11.setPosition(Common::Point(116, 84));
_object11.fixPriority(77);
- _object11.setDetails(550, 32, -1, 10, 1, NULL);
+ _object11.setDetails(550, 32, -1, 10, 1, (SceneItem *)NULL);
_drunkStanding.postInit();
_drunkStanding._flag = 0;
@@ -812,7 +812,7 @@ void Scene551::signal() {
BF_GLOBALS._sceneManager.changeScene(60);
break;
case 2:
- BF_GLOBALS._walkRegions.proc1(18);
+ BF_GLOBALS._walkRegions.disableRegion(18);
_trunkInset.postInit();
_trunkInset.setVisage(553);
@@ -842,7 +842,7 @@ void Scene551::signal() {
ADD_PLAYER_MOVER_NULL(_harrison, 88, 91);
_object12.show();
- _object12.setDetails(550, 25, -1, 26, 1, NULL);
+ _object12.setDetails(550, 25, -1, 26, 1, (SceneItem *)NULL);
BF_GLOBALS._sceneItems.push_front(&_object12);
BF_GLOBALS._player.enableControl();
@@ -850,8 +850,8 @@ void Scene551::signal() {
setAction(&_sequenceManager, this, 5507, &BF_GLOBALS._player, &_drunk, &_drunkStanding, NULL);
break;
case 5507:
- BF_GLOBALS._walkRegions.proc1(2);
- BF_GLOBALS._walkRegions.proc1(4);
+ BF_GLOBALS._walkRegions.disableRegion(2);
+ BF_GLOBALS._walkRegions.disableRegion(4);
_drunkStanding._flag = 1;
BF_GLOBALS._sceneItems.push_front(&_drunkStanding);
@@ -924,7 +924,7 @@ void Scene560::Action1::signal() {
scene->_deskChair.setStrip(BF_GLOBALS._player._strip);
scene->_deskChair.setPosition(BF_GLOBALS._player._position);
- scene->_field380 = 1;
+ scene->_field380 = true;
BF_GLOBALS._player.enableControl();
remove();
break;
@@ -950,7 +950,7 @@ void Scene560::Action2::signal() {
BF_GLOBALS._player.animate(ANIM_MODE_6, this);
break;
case 2:
- scene->_field380 = 0;
+ scene->_field380 = false;
scene->_deskChair.setPosition(Common::Point(81, 149));
scene->_deskChair.setVisage(561);
scene->_deskChair.setStrip(3);
@@ -1064,7 +1064,7 @@ void Scene560::SafeInset::postInit(SceneObjectList *OwnerList) {
scene->_nickel.setFrame(3);
scene->_nickel.fixPriority(252);
scene->_nickel.setPosition(Common::Point(181, 140));
- scene->_nickel.setDetails(560, 47, 48, -1, 1, NULL);
+ scene->_nickel.setDetails(560, 47, 48, -1, 1, (SceneItem *)NULL);
BF_GLOBALS._sceneItems.remove(&scene->_nickel);
BF_GLOBALS._sceneItems.push_front(&scene->_nickel);
}
@@ -1076,7 +1076,7 @@ void Scene560::SafeInset::postInit(SceneObjectList *OwnerList) {
_item4.setDetails(Rect(143, 86, 159, 102), 560, 49, 50, -1, 1, NULL);
_item5.setDetails(Rect(159, 86, 175, 102), 560, 49, 50, -1, 1, NULL);
_item6.setDetails(Rect(175, 86, 191, 102), 560, 49, 50, -1, 1, NULL);
-
+
BF_GLOBALS._sceneItems.remove(&_item1);
BF_GLOBALS._sceneItems.remove(&_item2);
BF_GLOBALS._sceneItems.remove(&_item3);
@@ -1114,9 +1114,9 @@ void Scene560::SafeInset::postInit(SceneObjectList *OwnerList) {
_digit0.setStrip(3);
_digit0.setPosition(Common::Point(183, 94));
_digit0.fixPriority(252);
-
+
int amount = (BF_GLOBALS._safeCombination != 0) ? BF_GLOBALS._safeCombination : 1000;
-
+
// Get digit 0 portion
int remainder = amount % 10;
amount /= 10;
@@ -1135,7 +1135,7 @@ void Scene560::SafeInset::postInit(SceneObjectList *OwnerList) {
void Scene560::SafeInset::remove() {
Scene560 *scene = (Scene560 *)BF_GLOBALS._sceneManager._scene;
-
+
_item1.remove();
_item2.remove();
_item3.remove();
@@ -1145,7 +1145,7 @@ void Scene560::SafeInset::remove() {
_digit2.remove();
_digit1.remove();
_digit0.remove();
-
+
scene->_nickel.remove();
if (BF_GLOBALS._events.getCursor() == CURSOR_USE) {
@@ -1201,7 +1201,7 @@ void Scene560::SafeInset::signal() {
scene->_nickel.setFrame(3);
scene->_nickel.fixPriority(252);
scene->_nickel.setPosition(Common::Point(181, 140));
- scene->_nickel.setDetails(560, 47, 48, -1, 1, NULL);
+ scene->_nickel.setDetails(560, 47, 48, -1, 1, (SceneItem *)NULL);
BF_GLOBALS._sceneItems.remove(&scene->_nickel);
BF_GLOBALS._sceneItems.push_front(&scene->_nickel);
}
@@ -1293,7 +1293,7 @@ bool Scene560::SafeInset::Item::startAction(CursorType action, Event &event) {
default:
break;
}
-
+
scene->_safeInset.signal();
scene->_sound1.play(75);
return true;
@@ -1345,7 +1345,7 @@ bool Scene560::BoxInset::Item1::startAction(CursorType action, Event &event) {
scene->_safeInset.setPosition(Common::Point(160, 141));
scene->_safeInset.fixPriority(251);
scene->_safeInset.setDetails(560, 45, 46, -1);
-
+
scene->_sceneMode = 3;
scene->_boxInset.remove();
@@ -1378,7 +1378,7 @@ bool Scene560::Computer::startAction(CursorType action, Event &event) {
/*--------------------------------------------------------------------------*/
Scene560::Scene560(): SceneExt() {
- _field380 = _field11EA = 0;
+ _field380 = _field11EA = false;
}
void Scene560::postInit(SceneObjectList *OwnerList) {
@@ -1405,7 +1405,7 @@ void Scene560::postInit(SceneObjectList *OwnerList) {
_box.setStrip(4);
_box.setFrame(1);
_box.setPosition(Common::Point(295, 37));
- _box.setDetails(560, 41, 42, -1, 1, NULL);
+ _box.setDetails(560, 41, 42, -1, 1, (SceneItem *)NULL);
}
_deskChair.postInit();
@@ -1414,7 +1414,7 @@ void Scene560::postInit(SceneObjectList *OwnerList) {
_deskChair.setPosition(Common::Point(81, 149));
_deskChair.fixPriority(151);
_deskChair.changeZoom(81);
-
+
if (BF_GLOBALS._sceneManager._previousScene == 570) {
// Returning from using computer
BF_GLOBALS._events.setCursor(CURSOR_USE);
@@ -1433,12 +1433,12 @@ void Scene560::postInit(SceneObjectList *OwnerList) {
_deskChair.setStrip(BF_GLOBALS._player._strip);
_deskChair.setPosition(BF_GLOBALS._player._position);
- _field11EA = 0;
- _field380 = 1;
+ _field11EA = false;
+ _field380 = true;
} else {
// Entering study through doorway
- _field11EA = 0;
- _field380 = 0;
+ _field11EA = false;
+ _field380 = false;
BF_GLOBALS._player.postInit();
BF_GLOBALS._player.setVisage(563);
@@ -1448,13 +1448,13 @@ void Scene560::postInit(SceneObjectList *OwnerList) {
BF_GLOBALS._player._moveDiff.x = 11;
BF_GLOBALS._player.changeZoom(-1);
BF_GLOBALS._player.disableControl();
-
+
_sceneMode = 10;
ADD_MOVER(BF_GLOBALS._player, 85, 115);
}
_computer.setDetails(Rect(16, 77, 58, 107), 560, 2, -1, -1, 1, NULL);
- _deskChair.setDetails(560, 3, -1, -1, 1, NULL);
+ _deskChair.setDetails(560, 3, -1, -1, 1, (SceneItem *)NULL);
_chair.setDetails(Rect(163, 64, 196, 102), 560, 13, 25, 36, 1, NULL);
_lamp.setDetails(Rect(197, 43, 214, 56), 560, 7, 19, 30, 1, NULL);
_item4.setDetails(Rect(121, 18, 156, 54), 560, 8, 20, 31, 1, NULL);
@@ -1516,7 +1516,7 @@ void Scene560::signal() {
T2_GLOBALS._uiElements.addScore(10);
BF_GLOBALS.setFlag(fGotPointsForPunch);
}
-
+
_boxInset.postInit();
_boxInset.setVisage(560);
_boxInset.setStrip(2);
@@ -1529,7 +1529,7 @@ void Scene560::signal() {
}
break;
case 10:
- _field11EA = 0;
+ _field11EA = false;
BF_GLOBALS._player.enableControl();
break;
case 11:
@@ -1540,7 +1540,7 @@ void Scene560::signal() {
void Scene560::process(Event &event) {
if ((event.eventType == EVENT_BUTTON_DOWN) && (BF_GLOBALS._events.getCursor() == CURSOR_WALK) &&
- (_field380 == 1) && !_action) {
+ (_field380) && !_action) {
_destPosition = event.mousePos;
BF_GLOBALS._player.disableControl();
setAction(&_action2);
@@ -1553,7 +1553,7 @@ void Scene560::process(Event &event) {
void Scene560::dispatch() {
if (!_field11EA && (BF_GLOBALS._player._position.y < 105)) {
- _field11EA = 1;
+ _field11EA = true;
BF_GLOBALS._player.disableControl();
BF_GLOBALS._sceneManager.changeScene(270);
}
@@ -1605,7 +1605,7 @@ void Scene570::PasswordEntry::postInit(SceneObjectList *OwnerList) {
void Scene570::PasswordEntry::process(Event &event) {
Scene570 *scene = (Scene570 *)BF_GLOBALS._sceneManager._scene;
bool entryChanged = false;
-
+
switch (event.eventType) {
case EVENT_KEYPRESS: {
int key = toupper(event.kbd.ascii);
@@ -1648,7 +1648,7 @@ void Scene570::PasswordEntry::process(Event &event) {
_entryText.setPosition(Common::Point(213, 40));
_entryText.fixPriority(255);
_entryText.setup(_entryBuffer);
-
+
// Pad entered text with spaces to make up the allowed width and then display
Common::String msg = _entryBuffer;
while (msg.size() < 10)
@@ -1658,7 +1658,7 @@ void Scene570::PasswordEntry::process(Event &event) {
}
void Scene570::PasswordEntry::checkPassword() {
- // Check if the password is correctly entered as 'JACKIE' or, as a nod to the
+ // Check if the password is correctly entered as 'JACKIE' or, as a nod to the
// reimplementation in ScummVM, as the project name.
Scene570 *scene = (Scene570 *)BF_GLOBALS._sceneManager._scene;
@@ -1794,7 +1794,7 @@ void Scene570::Icon::remove() {
}
bool Scene570::Icon::startAction(CursorType action, Event &event) {
- Scene570 *scene = (Scene570 *)BF_GLOBALS._sceneManager._scene;
+ Scene570 *scene = (Scene570 *)BF_GLOBALS._sceneManager._scene;
switch (action) {
case CURSOR_LOOK:
@@ -1907,7 +1907,7 @@ bool Scene570::Icon::startAction(CursorType action, Event &event) {
}
void Scene570::Icon::setDetails(int iconId, int folderId, int parentFolderId, int unused, const Common::String &msg) {
- Scene570 *scene = (Scene570 *)BF_GLOBALS._sceneManager._scene;
+ Scene570 *scene = (Scene570 *)BF_GLOBALS._sceneManager._scene;
NamedObject::postInit();
_iconId = iconId;
@@ -1929,7 +1929,7 @@ void Scene570::Icon::setDetails(int iconId, int folderId, int parentFolderId, in
/*--------------------------------------------------------------------------*/
bool Scene570::PowerSwitch::startAction(CursorType action, Event &event) {
- Scene570 *scene = (Scene570 *)BF_GLOBALS._sceneManager._scene;
+ Scene570 *scene = (Scene570 *)BF_GLOBALS._sceneManager._scene;
switch (action) {
case CURSOR_USE:
@@ -1972,7 +1972,7 @@ bool Scene570::PrinterIcon::startAction(CursorType action, Event &event) {
}
void Scene570::Object3::remove() {
- Scene570 *scene = (Scene570 *)BF_GLOBALS._sceneManager._scene;
+ Scene570 *scene = (Scene570 *)BF_GLOBALS._sceneManager._scene;
scene->_object4._flag = 0;
scene->_printerIcon.remove();
@@ -1998,7 +1998,7 @@ void Scene570::Object3::remove() {
/*--------------------------------------------------------------------------*/
bool Scene570::FloppyDrive::startAction(CursorType action, Event &event) {
- Scene570 *scene = (Scene570 *)BF_GLOBALS._sceneManager._scene;
+ Scene570 *scene = (Scene570 *)BF_GLOBALS._sceneManager._scene;
switch (action) {
case CURSOR_USE:
@@ -2039,7 +2039,7 @@ void Scene570::postInit(SceneObjectList *OwnerList) {
_powerSwitch.setStrip(4);
_powerSwitch.setFrame(1);
_powerSwitch.setPosition(Common::Point(163, 131));
- _powerSwitch.setDetails(570, 1, 15, -1, 1, NULL);
+ _powerSwitch.setDetails(570, 1, 15, -1, 1, (SceneItem *)NULL);
_floppyDrive.setDetails(Rect(258, 111, 303, 120), 570, 0, 15, -1, 1, NULL);
_item11.setDetails(0, 570, 15, 15, 15, 1);
@@ -2070,7 +2070,7 @@ void Scene570::signal() {
_printerIcon.setFrame(3);
_printerIcon.setPosition(Common::Point(172, 71));
_printerIcon.fixPriority(2);
- _printerIcon.setDetails(570, 14, 15, -1, 2, NULL);
+ _printerIcon.setDetails(570, 14, 15, -1, 2, (SceneItem *)NULL);
_iconManager.setup(2);
_folder1.setDetails(1, 1, 0, 2, SCENE570_C_DRIVE);
@@ -2201,7 +2201,7 @@ void Scene580::postInit(SceneObjectList *OwnerList) {
_door.setStrip(4);
_door.setPosition(Common::Point(168, 41));
_door.hide();
- _door.setDetails(580, 5, -1, -1, 1, NULL);
+ _door.setDetails(580, 5, -1, -1, 1, (SceneItem *)NULL);
_vechile.postInit();
_vechile.setVisage(580);
@@ -2219,28 +2219,27 @@ void Scene580::postInit(SceneObjectList *OwnerList) {
_vechile.changeZoom(90);
_vechile.setStrip(3);
_vechile.setPosition(Common::Point(165, 76));
- _vechile.setDetails(580, 2, 3, -1, 1, NULL);
- _vechile.setVisage(303);
+ _vechile.setDetails(580, 2, 3, -1, 1, (SceneItem *)NULL);
BF_GLOBALS._player.setVisage(303);
- BF_GLOBALS._walkRegions.proc1(8);
- BF_GLOBALS._walkRegions.proc1(9);
- BF_GLOBALS._walkRegions.proc1(10);
- BF_GLOBALS._walkRegions.proc1(11);
+ BF_GLOBALS._walkRegions.disableRegion(8);
+ BF_GLOBALS._walkRegions.disableRegion(9);
+ BF_GLOBALS._walkRegions.disableRegion(10);
+ BF_GLOBALS._walkRegions.disableRegion(11);
} else {
_vechile.setPosition(Common::Point(159, 72));
if (BF_GLOBALS.getFlag(onDuty)) {
_vechile.setStrip(1);
_vechile.setFrame(2);
- _vechile.setDetails(300, 11, 13, -1, 1, NULL);
+ _vechile.setDetails(300, 11, 13, -1, 1, (SceneItem *)NULL);
BF_GLOBALS._player.setVisage(304);
} else {
_vechile.setStrip(2);
_vechile.setFrame(3);
- _vechile.setDetails(580, 0, 1, -1, 1, NULL);
+ _vechile.setDetails(580, 0, 1, -1, 1, (SceneItem *)NULL);
BF_GLOBALS._player.setVisage(303);
}
@@ -2327,7 +2326,7 @@ bool Scene590::Skip::startAction(CursorType action, Event &event) {
} else {
scene->_stripNumber = !scene->_field17DC ? 5901 : 5902;
}
-
+
scene->setAction(&scene->_action1);
scene->_field17DC = 1;
return true;
@@ -2405,7 +2404,7 @@ void Scene590::Action2::signal() {
case 4:
scene->_skip.setStrip(1);
scene->_skip.animate(ANIM_MODE_1, NULL);
-
+
BF_GLOBALS._player.setVisage(368);
BF_GLOBALS._player.setStrip(7);
BF_GLOBALS._player.setPosition(Common::Point(238, 131));
@@ -2457,7 +2456,7 @@ void Scene590::postInit(SceneObjectList *OwnerList) {
_stripManager.addSpeaker(&_skipSpeaker);
_stripManager.addSpeaker(&_lauraSpeaker);
_stripManager.addSpeaker(&_jakeJacketSpeaker);
-
+
if (BF_GLOBALS.getFlag(onDuty)) {
BF_GLOBALS._player.setVisage(361);
BF_GLOBALS._player._moveDiff = Common::Point(6, 2);
@@ -2469,12 +2468,12 @@ void Scene590::postInit(SceneObjectList *OwnerList) {
_skip.postInit();
_skip.setVisage(693);
_skip.setPosition(Common::Point(271, 117));
- _skip.setDetails(590, 26, -1, 27, 1, NULL);
+ _skip.setDetails(590, 26, -1, 27, 1, (SceneItem *)NULL);
_laura.postInit();
_laura.setVisage(692);
_laura.setPosition(Common::Point(248, 115));
- _laura.setDetails(590, 24, -1, 25, 1, NULL);
+ _laura.setDetails(590, 24, -1, 25, 1, (SceneItem *)NULL);
}
}
@@ -2489,7 +2488,7 @@ void Scene590::postInit(SceneObjectList *OwnerList) {
_item10.setDetails(13, 590, 9, -1, 21, 1);
_item11.setDetails(15, 590, 10, -1, 22, 1);
_item12.setDetails(17, 590, 11, -1, 23, 1);
-
+
BF_GLOBALS._player.disableControl();
_sceneMode = 0;
setAction(&_sequenceManager, this, 5900, &BF_GLOBALS._player, NULL);
diff --git a/engines/tsage/blue_force/blueforce_scenes5.h b/engines/tsage/blue_force/blueforce_scenes5.h
index 34328ab9e8..73d323fc54 100644
--- a/engines/tsage/blue_force/blueforce_scenes5.h
+++ b/engines/tsage/blue_force/blueforce_scenes5.h
@@ -228,7 +228,8 @@ public:
NamedHotspot _chair, _lamp, _item4, _trophy, _watercolours, _fileCabinets;
NamedHotspot _certificate, _bookcase, _desk, _carpet, _item12, _office;
ASound _sound1;
- int _field380, _field11EA;
+ bool _field380;
+ bool _field11EA;
Common::Point _destPosition;
Scene560();
diff --git a/engines/tsage/blue_force/blueforce_scenes6.cpp b/engines/tsage/blue_force/blueforce_scenes6.cpp
index 56fdec47cd..9467df7917 100644
--- a/engines/tsage/blue_force/blueforce_scenes6.cpp
+++ b/engines/tsage/blue_force/blueforce_scenes6.cpp
@@ -37,7 +37,7 @@ namespace BlueForce {
void Scene600::Action1::signal() {
Scene600 *scene = (Scene600 *)BF_GLOBALS._sceneManager._scene;
- static const uint32 black = 0;
+ static byte red[3] = {220, 0, 0};
switch (_actionIndex++) {
case 0:
@@ -49,8 +49,8 @@ void Scene600::Action1::signal() {
break;
case 2:
scene->_sound1.play(59);
- setAction(&scene->_sequenceManager, this, 600, &scene->_object2, &scene->_object1,
- &BF_GLOBALS._player, &scene->_object3, NULL);
+ setAction(&scene->_sequenceManager, this, 600, &scene->_object2, &scene->_ryan,
+ &BF_GLOBALS._player, &scene->_skidMarks, NULL);
break;
case 3:
BF_GLOBALS._sound1.play(61);
@@ -61,13 +61,13 @@ void Scene600::Action1::signal() {
break;
case 5: {
BF_GLOBALS._player.remove();
- scene->_object1.remove();
+ scene->_ryan.remove();
scene->_object2.remove();
- scene->_object3.remove();
+ scene->_skidMarks.remove();
- for (int percent = 100; percent >= 0; percent -= 5) {
- BF_GLOBALS._scenePalette.fade((const byte *)&black, false, percent);
- g_system->delayMillis(10);
+ for (int percent = 100; percent >= 0; percent -= 2) {
+ BF_GLOBALS._scenePalette.fade((const byte *)&red, false, percent);
+ g_system->delayMillis(5);
}
SynchronizedList<SceneObject *>::iterator i;
@@ -91,6 +91,8 @@ void Scene600::Action1::signal() {
BF_GLOBALS._v51C44 = 0;
remove();
break;
+ default:
+ break;
}
}
@@ -110,14 +112,14 @@ void Scene600::postInit(SceneObjectList *OwnerList) {
BF_GLOBALS._player.setPosition(Common::Point(639, 0));
BF_GLOBALS._player.disableControl();
- _object3.postInit();
- _object3.hide();
+ _skidMarks.postInit();
+ _skidMarks.hide();
_object2.postInit();
-
- _object1.postInit();
- _object1.setVisage(600);
- _object1.setStrip(7);
- _object1.setPosition(Common::Point(417, 82));
+
+ _ryan.postInit();
+ _ryan.setVisage(600);
+ _ryan.setStrip(7);
+ _ryan.setPosition(Common::Point(417, 82));
BF_GLOBALS.clearFlag(onDuty);
BF_INVENTORY.setObjectScene(INV_TICKET_BOOK, 60);
@@ -147,7 +149,7 @@ void Scene600::remove() {
void Scene620::postInit(SceneObjectList *OwnerList) {
SceneExt::postInit();
loadScene(999);
-
+
BF_GLOBALS._player.postInit();
BF_GLOBALS._player.disableControl();
BF_GLOBALS._player.setVisage(621);
@@ -174,14 +176,14 @@ void Scene620::signal() {
case 13:
case 16:
case 19:
- addFader((const byte *)&black, 2, this);
+ addFader((const byte *)&black, 2, this);
break;
case 2:
BF_GLOBALS._player.remove();
_object1.postInit();
_object1.setVisage(622);
_object1.setPosition(Common::Point(101, 41));
- addFader((const byte *)&black, 2, this);
+ add2Faders((const byte *)&black, 2, 622, this);
break;
case 5:
_object1.remove();
@@ -240,6 +242,8 @@ void Scene620::signal() {
BF_GLOBALS._dayNumber = 3;
BF_GLOBALS._sceneManager.changeScene(271);
break;
+ default:
+ break;
}
}
@@ -386,8 +390,8 @@ bool Scene690::Object1::startAction(CursorType action, Event &event) {
if ((action == CURSOR_USE) && (scene->_object2._strip == 1)) {
BF_GLOBALS._player.disableControl();
- BF_GLOBALS._walkRegions.proc2(1);
- BF_GLOBALS._walkRegions.proc2(6);
+ BF_GLOBALS._walkRegions.enableRegion(1);
+ BF_GLOBALS._walkRegions.enableRegion(6);
scene->_sceneMode = 6901;
scene->setAction(&scene->_sequenceManager, scene, 6901, &BF_GLOBALS._player,
&scene->_object2, &scene->_object1, &scene->_object4, &scene->_object5, NULL);
@@ -406,7 +410,7 @@ bool Scene690::Object2::startAction(CursorType action, Event &event) {
scene->_object6.postInit();
scene->_object6.hide();
scene->_object6.fixPriority(1);
- scene->_object6.setDetails(690, 21, 17, 23, 1, NULL);
+ scene->_object6.setDetails(690, 21, 17, 23, 1, (SceneItem *)NULL);
BF_GLOBALS._player.disableControl();
scene->_sceneMode = 6902;
@@ -437,36 +441,36 @@ void Scene690::postInit(SceneObjectList *OwnerList) {
BF_GLOBALS._dayNumber = 1;
_stripManager.addSpeaker(&_jakeSpeaker);
-
+
_object1.postInit();
_object1.setVisage(690);
_object1.setStrip2(2);
_object1.fixPriority(188);
_object1.setPosition(Common::Point(50, 166));
- _object1.setDetails(690, 4, 17, 26, 1, NULL);
+ _object1.setDetails(690, 4, 17, 26, 1, (SceneItem *)NULL);
_object3.postInit();
_object3.setVisage(690);
_object3.fixPriority(100);
_object3.setPosition(Common::Point(238, 125));
- _object3.setDetails(690, 7, 17, 28, 1, NULL);
+ _object3.setDetails(690, 7, 17, 28, 1, (SceneItem *)NULL);
_object2.postInit();
_object2.setVisage(694);
_object2.setStrip2(3);
_object2.fixPriority(125);
_object2.setPosition(Common::Point(100, 134));
- _object2.setDetails(690, 12, -1, 11, 1, NULL);
+ _object2.setDetails(690, 12, -1, 11, 1, (SceneItem *)NULL);
BF_GLOBALS._player.postInit();
BF_GLOBALS._player.disableControl();
BF_GLOBALS._player._moveDiff.x = 8;
_object4.postInit();
- _object4.setDetails(690, 13, -1, -1, 1, NULL);
+ _object4.setDetails(690, 13, -1, -1, 1, (SceneItem *)NULL);
_object5.postInit();
- _object5.setDetails(690, 14, -1, -1, 1, NULL);
+ _object5.setDetails(690, 14, -1, -1, 1, (SceneItem *)NULL);
_sceneMode = 6903;
setAction(&_sequenceManager, this, 6903, &BF_GLOBALS._player, &_object3, &_object4, &_object5, NULL);
@@ -500,8 +504,8 @@ void Scene690::signal() {
BF_GLOBALS._player.enableControl();
break;
case 6903:
- BF_GLOBALS._walkRegions.proc1(1);
- BF_GLOBALS._walkRegions.proc1(6);
+ BF_GLOBALS._walkRegions.disableRegion(1);
+ BF_GLOBALS._walkRegions.disableRegion(6);
BF_GLOBALS._player.enableControl();
break;
default:
diff --git a/engines/tsage/blue_force/blueforce_scenes6.h b/engines/tsage/blue_force/blueforce_scenes6.h
index e354e9e069..3f9c14aa11 100644
--- a/engines/tsage/blue_force/blueforce_scenes6.h
+++ b/engines/tsage/blue_force/blueforce_scenes6.h
@@ -49,7 +49,7 @@ public:
SequenceManager _sequenceManager;
Action1 _action1;
ASoundExt _sound1;
- NamedObject _object1, _object2, _object3;
+ NamedObject _ryan, _object2, _skidMarks;
BackgroundSceneObject _object4, _object5;
BackgroundSceneObject _object6, _object7, _object8;
diff --git a/engines/tsage/blue_force/blueforce_scenes7.cpp b/engines/tsage/blue_force/blueforce_scenes7.cpp
index 2ced7ce08c..bb29ad1f34 100644
--- a/engines/tsage/blue_force/blueforce_scenes7.cpp
+++ b/engines/tsage/blue_force/blueforce_scenes7.cpp
@@ -37,7 +37,7 @@ namespace BlueForce {
void Scene710::Timer1::signal() {
PaletteRotation *rotation = BF_GLOBALS._scenePalette.addRotation(136, 138, -1);
- rotation->setDelay(25);
+ rotation->setDelay(20);
rotation = BF_GLOBALS._scenePalette.addRotation(146, 148, -1);
rotation->setDelay(30);
rotation = BF_GLOBALS._scenePalette.addRotation(187, 191, -1);
@@ -113,19 +113,19 @@ bool Scene710::Object5::startAction(CursorType action, Event &event) {
switch (action) {
case CURSOR_LOOK:
- if (scene->_v1D64 <= 2)
+ if (scene->_stickThrowCount <= 2)
return NamedObject::startAction(action, event);
else {
SceneItem::display2(710, 3);
- scene->_v1D66 = 1;
+ scene->_watchCrate = true;
return true;
}
case CURSOR_USE:
- if ((scene->_kid._position.x < 0) && (scene->_v1D62 == 1)) {
- scene->_v1D64++;
- if (scene->_v1D66 == 0) {
+ if ((scene->_kid._position.x < 0) && (scene->_dogLying)) {
+ scene->_stickThrowCount++;
+ if (!scene->_watchCrate) {
BF_GLOBALS._player.disableControl();
- scene->_v1D62 = 0;
+ scene->_dogLying = false;
scene->_sceneMode = 7105;
scene->setAction(&scene->_sequenceManager1, scene, 7105, &BF_GLOBALS._player, &scene->_stick, &scene->_dog, NULL);
} else {
@@ -172,10 +172,10 @@ void Scene710::postInit(SceneObjectList *OwnerList) {
_stick.animate(ANIM_MODE_2, NULL);
_stick.setPosition(Common::Point(650, 160));
_stick._moveDiff.x = 16;
- _stick.setDetails(710, 4, -1, -1, 1, NULL);
- _laura.setDetails(710, 2, -1, -1, 1, NULL);
- _kid.setDetails(710, 6, -1, -1, 1, NULL);
- _dog.setDetails(710, 0, -1, -1, 1, NULL);
+ _stick.setDetails(710, 4, -1, -1, 1, (SceneItem *)NULL);
+ _laura.setDetails(710, 2, -1, -1, 1, (SceneItem *)NULL);
+ _kid.setDetails(710, 6, -1, -1, 1, (SceneItem *)NULL);
+ _dog.setDetails(710, 0, -1, -1, 1, (SceneItem *)NULL);
_item1.setDetails(Rect(555, 68, 583, 101), 710, 7, 23, -1, 1, NULL);
_item2.setDetails(Rect(583, 46, 611, 78), 710, 7, 23, -1, 1, NULL);
@@ -187,7 +187,8 @@ void Scene710::postInit(SceneObjectList *OwnerList) {
_item7.setDetails(Rect(0, 0, 640, 52), 710, 11, 17, -1, 1, NULL);
_item9.setDetails(Rect(0, 0, 640, 128), 710, 5, 15, -1, 1, NULL);
- _v1D62 = _v1D64 = _v1D66 = _v1D68 = 0;
+ _stickThrowCount = 0;
+ _dogLying = _watchCrate = _throwStick = false;
_action1._state = 7100;
_timer1.set(2, NULL);
_sceneMode = 7100;
@@ -205,28 +206,29 @@ void Scene710::signal() {
setAction(&_sequenceManager1, this, 7102, &_dog, NULL);
break;
case 7101:
+ // Pick up crate part
BF_GLOBALS._player.enableControl();
BF_INVENTORY.setObjectScene(INV_CRATE1, 1);
_stick.remove();
- BF_GLOBALS._walkRegions.proc2(2);
+ BF_GLOBALS._walkRegions.enableRegion(2);
break;
case 7102:
_stick.setPosition(Common::Point(100, 122));
_stick.animate(ANIM_MODE_NONE, NULL);
_stick._strip = 2;
- if (_v1D64 <= 2)
+ if (_stickThrowCount <= 2)
_stick._frame = 2;
else {
- if (_v1D64 == 3) {
+ if (_stickThrowCount == 3) {
BF_GLOBALS._player.disableControl();
_sceneMode = 0;
_stripManager.start(7108, this);
}
_stick._frame = 1;
}
- _v1D62 = 1;
- BF_GLOBALS._walkRegions.proc1(2);
- if ((_v1D68 != 0) && (_sceneMode != 0))
+ _dogLying = true;
+ BF_GLOBALS._walkRegions.disableRegion(2);
+ if ((_throwStick) && (_sceneMode != 0))
BF_GLOBALS._player.enableControl();
break;
case 7103:
@@ -239,12 +241,12 @@ void Scene710::signal() {
}
break;
case 7105:
- _v1D68 = 1;
+ _throwStick = true;
// No break on purpose
case 7104:
_sceneMode = 7102;
setAction(&_sequenceManager1, this, 7102, &_dog, NULL);
- BF_GLOBALS._walkRegions.proc2(2);
+ BF_GLOBALS._walkRegions.enableRegion(2);
break;
case 7106:
BF_GLOBALS._sound1.fadeOut2(NULL);
@@ -256,8 +258,8 @@ void Scene710::signal() {
}
void Scene710::dispatch() {
- if ((_kid._position.x > 0) && (_v1D62 == 1) && (_sceneMode != 7106)) {
- _v1D62 = 0;
+ if ((_kid._position.x > 0) && (_dogLying) && (_sceneMode != 7106)) {
+ _dogLying = false;
_sceneMode = 7103;
setAction(&_sequenceManager1, this, 7103, &_kid, &_stick, &_dog, NULL);
}
@@ -266,10 +268,10 @@ void Scene710::dispatch() {
void Scene710::synchronize(Serializer &s) {
SceneExt::synchronize(s);
- s.syncAsSint16LE(_v1D62);
- s.syncAsSint16LE(_v1D64);
- s.syncAsSint16LE(_v1D66);
- s.syncAsSint16LE(_v1D68);
+ s.syncAsSint16LE(_dogLying);
+ s.syncAsSint16LE(_stickThrowCount);
+ s.syncAsSint16LE(_watchCrate);
+ s.syncAsSint16LE(_throwStick);
}
diff --git a/engines/tsage/blue_force/blueforce_scenes7.h b/engines/tsage/blue_force/blueforce_scenes7.h
index 91bd1e537f..161d94cc2c 100644
--- a/engines/tsage/blue_force/blueforce_scenes7.h
+++ b/engines/tsage/blue_force/blueforce_scenes7.h
@@ -89,7 +89,10 @@ public:
NamedHotspot _item7;
NamedHotspot _item8;
NamedHotspot _item9;
- int _v1D62, _v1D64, _v1D66, _v1D68;
+ int _stickThrowCount;
+ bool _dogLying;
+ bool _watchCrate;
+ bool _throwStick;
virtual void postInit(SceneObjectList *OwnerList = NULL);
virtual void signal();
diff --git a/engines/tsage/blue_force/blueforce_scenes8.cpp b/engines/tsage/blue_force/blueforce_scenes8.cpp
index c81f3b8d65..5a60cd7c5e 100644
--- a/engines/tsage/blue_force/blueforce_scenes8.cpp
+++ b/engines/tsage/blue_force/blueforce_scenes8.cpp
@@ -252,12 +252,12 @@ void Scene800::postInit(SceneObjectList *OwnerList) {
_car2.fixPriority(158);
BF_GLOBALS._sceneItems.push_back(&_car2);
- BF_GLOBALS._walkRegions.proc1(8);
+ BF_GLOBALS._walkRegions.disableRegion(8);
}
if ((BF_GLOBALS._dayNumber == 4) && (BF_GLOBALS._bookmark < bEndDayThree)) {
_car2.remove();
- BF_GLOBALS._walkRegions.proc2(8);
+ BF_GLOBALS._walkRegions.enableRegion(8);
}
if (BF_GLOBALS.getFlag(fWithLyle)) {
@@ -427,14 +427,14 @@ void Scene810::Action2::signal() {
setAction(&scene->_sequenceManager1, this, 8117, &scene->_lyle, &scene->_chair, NULL);
break;
case 3:
- BF_GLOBALS._walkRegions.proc2(4);
+ BF_GLOBALS._walkRegions.enableRegion(4);
ADD_PLAYER_MOVER_THIS(scene->_lyle, 27, 124);
break;
case 4:
scene->_lyle.setVisage(813);
scene->_lyle.setStrip(2);
scene->_lyle.setFrame(1);
-
+
ADD_PLAYER_MOVER(84, 113);
break;
case 5:
@@ -454,7 +454,7 @@ void Scene810::Action2::signal() {
scene->_stripManager.start(BF_GLOBALS.getFlag(onDuty) ? 8137 : 8112, this);
break;
case 8:
- BF_GLOBALS._walkRegions.proc1(13);
+ BF_GLOBALS._walkRegions.disableRegion(13);
BF_GLOBALS._player.enableControl();
remove();
break;
@@ -562,24 +562,36 @@ bool Scene810::Lyle::startAction(CursorType action, Event &event) {
case INV_PRINT_OUT:
if (BF_GLOBALS.getFlag(shownLylePO)) {
scene->_sceneMode = 8149;
- } else if (!BF_GLOBALS.getFlag(shownLylePO)) {
- if (!BF_GLOBALS.getFlag(shownFax)) {
- // WORKAROUND: Original did not do a 'not', but I think this is correct
- BF_GLOBALS.setFlag(shownFax);
- scene->_sceneMode = 8125;
- } else if (BF_GLOBALS.getFlag(shownLyleRapsheet)) {
- scene->_sceneMode = 8104;
+ } else {
+ BF_GLOBALS.setFlag(shownLylePO);
+ if (BF_GLOBALS._dayNumber == 3) {
+ if (BF_GLOBALS.getFlag(shownFax)) {
+ BF_GLOBALS.setFlag(shownFax);
+ scene->_sceneMode = 8125;
+ } else if (BF_GLOBALS.getFlag(shownLyleRapsheet)) {
+ scene->_sceneMode = 8104;
+ } else {
+ scene->_sceneMode = 8121;
+ }
+ } else if (BF_GLOBALS.getFlag(onDuty)) {
+ if ((BF_GLOBALS.getFlag(shownLyleRapsheet)) || (BF_GLOBALS.getFlag(shownLyleCrate1))){
+ scene->_sceneMode = 8141;
+ } else {
+ // Doublecheck on shownLyleCrate1 removed: useless
+ scene->_sceneMode = 8144;
+ }
} else {
- scene->_sceneMode = 8121;
+ if ((BF_GLOBALS.getFlag(shownLyleRapsheet)) || (BF_GLOBALS.getFlag(shownLyleCrate1))) {
+ scene->_sceneMode = 8129;
+ } else { // if (BF_GLOBALS.getFlag(shownLyleCrate1)) {
+ scene->_sceneMode = 8132;
+ // doublecheck Present in the original, may hide a bug in the original
+ //} else
+ // scene->_sceneMode = 8121;
+ }
}
- } else if (BF_GLOBALS.getFlag(onDuty)) {
- scene->_sceneMode = 8141;
- } else {
- if (BF_GLOBALS.getFlag(shownLyleRapsheet) || BF_GLOBALS.getFlag(shownLyleCrate1))
- scene->_sceneMode = 8129;
- else
- scene->_sceneMode = 8121;
}
+
BF_GLOBALS._player.disableControl();
scene->setAction(&scene->_action1);
return true;
@@ -599,7 +611,7 @@ bool Scene810::Lyle::startAction(CursorType action, Event &event) {
default:
return NamedObjectExt::startAction(action, event);
}
-}
+}
bool Scene810::Chair::startAction(CursorType action, Event &event) {
switch (action) {
@@ -654,12 +666,12 @@ bool Scene810::FaxMachineInset::startAction(CursorType action, Event &event) {
if (BF_INVENTORY.getObjectScene(INV_PRINT_OUT) == 811) {
T2_GLOBALS._uiElements.addScore(50);
scene->_sound1.play(77);
+ scene->_fieldA70 = 1;
BF_GLOBALS._player.disableControl();
scene->_sceneMode = 8109;
scene->setAction(&scene->_sequenceManager1, scene, 8109, &BF_GLOBALS._player,
&scene->_object6, &scene->_object5, NULL);
- scene->_fieldA70 = 1;
scene->_fieldA74 = 1;
remove();
} else {
@@ -697,7 +709,7 @@ bool Scene810::Object5::startAction(CursorType action, Event &event) {
case CURSOR_USE: {
scene->_sceneMode = 8195;
BF_GLOBALS._player.disableControl();
-
+
PlayerMover *mover = new PlayerMover();
Common::Point destPos(67, 111);
BF_GLOBALS._player.addMover(mover, &destPos, scene);
@@ -792,7 +804,7 @@ bool Scene810::FaxMachine::startAction(CursorType action, Event &event) {
scene->_sceneMode = 811;
if (BF_GLOBALS._sceneObjects->contains(&scene->_lyle)) {
- scene->setAction(&scene->_sequenceManager1, scene, BF_GLOBALS.getFlag(onDuty) ? 8108 : 8105,
+ scene->setAction(&scene->_sequenceManager1, scene, BF_GLOBALS.getFlag(onDuty) ? 8108 : 8105,
&BF_GLOBALS._player, &scene->_object6, NULL);
} else {
scene->setAction(&scene->_sequenceManager1, scene, 8111, &BF_GLOBALS._player,
@@ -1046,12 +1058,12 @@ void Scene810::postInit(SceneObjectList *OwnerList) {
case 820:
BF_GLOBALS._player.setStrip(7);
BF_GLOBALS._player.setPosition(Common::Point(278, 116));
-
+
_lyle.setVisage(845);
_lyle.setPosition(Common::Point(340, 175));
_lyle.setObjectWrapper(new SceneObjectWrapper());
_lyle.animate(ANIM_MODE_1, NULL);
-
+
_chair.show();
BF_GLOBALS._player.disableControl();
@@ -1109,7 +1121,7 @@ void Scene810::postInit(SceneObjectList *OwnerList) {
_item12._sceneRegionId = 8;
BF_GLOBALS._sceneItems.push_back(&_item12);
- BF_GLOBALS._sceneItems.addItems(&_microficheReader, &_map, &_window, &_bookcase, &_garbageCan,
+ BF_GLOBALS._sceneItems.addItems(&_microficheReader, &_map, &_window, &_bookcase, &_garbageCan,
&_fileCabinets, &_coffeeMaker, &_shelves, &_background, NULL);
_background.setBounds(Rect(0, 0, SCREEN_WIDTH, UI_INTERFACE_Y));
}
@@ -1172,7 +1184,7 @@ void Scene810::signal() {
if (BF_GLOBALS.getFlag(shownFax)) {
BF_GLOBALS.setFlag(showMugAround);
} else {
- BF_GLOBALS._walkRegions.proc1(4);
+ BF_GLOBALS._walkRegions.disableRegion(4);
BF_GLOBALS._player.enableControl();
}
break;
@@ -1225,7 +1237,7 @@ void Scene810::signal() {
_object5.setFrame(1);
break;
case 8196:
- BF_GLOBALS._walkRegions.proc1(4);
+ BF_GLOBALS._walkRegions.disableRegion(4);
BF_GLOBALS._player.enableControl();
break;
case 8198:
@@ -1264,7 +1276,7 @@ void Scene810::dispatch() {
_lyle.updateAngle(BF_GLOBALS._player._position);
}
- if (BF_GLOBALS._sceneObjects->contains(&_faxMachineInset) && (BF_GLOBALS._player._position.x != 67) &&
+ if (BF_GLOBALS._sceneObjects->contains(&_faxMachineInset) && (BF_GLOBALS._player._position.x != 67) &&
(BF_GLOBALS._player._position.y != 111)) {
_faxMachineInset.remove();
}
@@ -1279,8 +1291,8 @@ void Scene810::dispatch() {
} else {
BF_GLOBALS.clearFlag(showMugAround);
BF_GLOBALS._player.disableControl();
- BF_GLOBALS._walkRegions.proc2(4);
- BF_GLOBALS._walkRegions.proc2(13);
+ BF_GLOBALS._walkRegions.enableRegion(4);
+ BF_GLOBALS._walkRegions.enableRegion(13);
_sceneMode = 8112;
setAction(&_sequenceManager1, this, 8112, &BF_GLOBALS._player, &_lyle, NULL);
@@ -1296,8 +1308,8 @@ void Scene810::dispatch() {
setAction(&_sequenceManager1, this, 8100, &BF_GLOBALS._player, NULL);
} else {
if (BF_GLOBALS.getFlag(fWithLyle)) {
- BF_GLOBALS._walkRegions.proc2(4);
- BF_GLOBALS._walkRegions.proc2(13);
+ BF_GLOBALS._walkRegions.enableRegion(4);
+ BF_GLOBALS._walkRegions.enableRegion(13);
ADD_MOVER_NULL(_lyle, 320, 155);
}
@@ -1329,7 +1341,7 @@ bool Scene820::PowerButton::startAction(CursorType action, Event &event) {
BF_GLOBALS._scenePalette.loadPalette(821);
BF_GLOBALS._scenePalette.refresh();
- SceneItem::display(820, scene->_pageNumber, SET_WIDTH, 240, SET_X, 41, SET_Y, 0,
+ SceneItem::display(820, scene->_pageNumber, SET_WIDTH, 240, SET_X, 41, SET_Y, 0,
SET_FONT, 50, SET_FG_COLOR, 18, SET_EXT_BGCOLOR, 12, SET_KEEP_ONSCREEN, true, LIST_END);
} else {
BF_GLOBALS._scenePalette.loadPalette(820);
@@ -1376,7 +1388,7 @@ bool Scene820::BackButton::startAction(CursorType action, Event &event) {
scene->_object5.hide();
}
- SceneItem::display(820, scene->_pageNumber, SET_WIDTH, 240, SET_X, 41, SET_Y, 0,
+ SceneItem::display(820, scene->_pageNumber, SET_WIDTH, 240, SET_X, 41, SET_Y, 0,
SET_FONT, 50, SET_FG_COLOR, 18, SET_EXT_BGCOLOR, 12, SET_KEEP_ONSCREEN, true, LIST_END);
return true;
default:
@@ -1407,7 +1419,7 @@ bool Scene820::ForwardButton::startAction(CursorType action, Event &event) {
if (scene->_pageNumber < 4)
++scene->_pageNumber;
- SceneItem::display(820, scene->_pageNumber, SET_WIDTH, 240, SET_X, 41, SET_Y, 0,
+ SceneItem::display(820, scene->_pageNumber, SET_WIDTH, 240, SET_X, 41, SET_Y, 0,
SET_FONT, 50, SET_FG_COLOR, 18, SET_EXT_BGCOLOR, 12, SET_KEEP_ONSCREEN, true, LIST_END);
if (scene->_pageNumber == 4) {
@@ -1435,7 +1447,7 @@ void Scene820::synchronize(Serializer &s) {
void Scene820::postInit(SceneObjectList *OwnerList) {
SceneExt::postInit();
loadScene(820);
-
+
_stripManager.addSpeaker(&_gameTextSpeaker);
_powerButton.postInit();
@@ -1660,12 +1672,12 @@ void Scene830::postInit(SceneObjectList *OwnerList) {
_rentalBoat.setStrip(1);
_rentalBoat.setPosition(Common::Point(271, 146));
_rentalBoat.fixPriority(90);
- _rentalBoat.setDetails(830, 0, 1, 2, 1, NULL);
+ _rentalBoat.setDetails(830, 0, 1, 2, 1, (SceneItem *)NULL);
}
_door.postInit();
_door.setVisage(830);
- _door.setDetails(830, 3, 4, -1, 1, NULL);
+ _door.setDetails(830, 3, 4, -1, 1, (SceneItem *)NULL);
_door.setStrip((BF_GLOBALS._dayNumber == 2) ? 4 : 3);
_door.setPosition(Common::Point(182, 97));
@@ -1690,7 +1702,7 @@ void Scene830::postInit(SceneObjectList *OwnerList) {
_object5.setStrip(2);
_object5.setFrame(2);
_object5.setPosition(Common::Point(126, 133));
- _object5.setDetails(830, 7, 8, -1, 1, NULL);
+ _object5.setDetails(830, 7, 8, -1, 1, (SceneItem *)NULL);
}
break;
case 5:
@@ -1706,7 +1718,7 @@ void Scene830::postInit(SceneObjectList *OwnerList) {
_lyle.setStrip(4);
_lyle.setPosition(Common::Point(180, 154));
_lyle._moveDiff = Common::Point(2, 0);
- _lyle.setDetails(830, 28, -1, 29, 1, NULL);
+ _lyle.setDetails(830, 28, -1, 29, 1, (SceneItem *)NULL);
_field18AC = 1;
}
@@ -1938,7 +1950,7 @@ void Scene840::BoatKeysInset::postInit(SceneObjectList *OwnerList) {
_rentalKeys.setFrame(3);
_rentalKeys.setPosition(Common::Point(120, 132));
_rentalKeys.fixPriority(255);
- _rentalKeys.setDetails(840, 52, 8, -1, 2, NULL);
+ _rentalKeys.setDetails(840, 52, 8, -1, 2, (SceneItem *)NULL);
}
if (BF_INVENTORY.getObjectScene(INV_WAVE_KEYS) != 1) {
@@ -1948,7 +1960,7 @@ void Scene840::BoatKeysInset::postInit(SceneObjectList *OwnerList) {
_waveKeys.setFrame(2);
_waveKeys.setPosition(Common::Point(201, 91));
_waveKeys.fixPriority(255);
- _waveKeys.setDetails(840, 53, 8, -1, 2, NULL);
+ _waveKeys.setDetails(840, 53, 8, -1, 2, (SceneItem *)NULL);
}
_v1B4 = _v1B6 = 0;
@@ -2023,7 +2035,7 @@ bool Scene840::BoatKeysInset::startAction(CursorType action, Event &event) {
_rentalKeys.setFrame(3);
_rentalKeys.setPosition(Common::Point(120, 132));
_rentalKeys.fixPriority(255);
- _rentalKeys.setDetails(840, 52, 8, -1, 2, NULL);
+ _rentalKeys.setDetails(840, 52, 8, -1, 2, (SceneItem *)NULL);
}
if (BF_INVENTORY.getObjectScene(INV_WAVE_KEYS) == 1) {
@@ -2034,7 +2046,7 @@ bool Scene840::BoatKeysInset::startAction(CursorType action, Event &event) {
_waveKeys.setFrame(2);
_waveKeys.setPosition(Common::Point(201, 91));
_waveKeys.fixPriority(255);
- _waveKeys.setDetails(840, 53, 8, -1, 2, NULL);
+ _waveKeys.setDetails(840, 53, 8, -1, 2, (SceneItem *)NULL);
}
BF_INVENTORY.setObjectScene(INV_WAVE_KEYS, 0);
@@ -2247,7 +2259,7 @@ void Scene840::postInit(SceneObjectList *OwnerList) {
_doors.setVisage(840);
_doors.setStrip(3);
_doors.setPosition(Common::Point(157, 81));
- _doors.setDetails(840, 0, 1, 2, 1, NULL);
+ _doors.setDetails(840, 0, 1, 2, 1, (SceneItem *)NULL);
_carter.postInit();
_carter.setVisage(843);
@@ -2267,7 +2279,7 @@ void Scene840::postInit(SceneObjectList *OwnerList) {
_item10.setDetails(Rect(199, 56, 236, 80), 840, 24, 14, 12, 1, NULL);
_item11.setDetails(Rect(256, 94, 319, 118), 840, 25, 15, 13, 1, NULL);
_item18.setDetails(6, 840, 38, 39, 40, 1);
- _carter.setDetails(840, 3, 4, 5, 1, NULL);
+ _carter.setDetails(840, 3, 4, 5, 1, (SceneItem *)NULL);
_item8.setDetails(Rect(259, 4, 319, 87), 840, 22, 15, 13, 1, NULL);
_item15.setDetails(2, 840, 32, 33, 34, 1);
_coins.setDetails(3, 840, -1, 6, 7, 1);
@@ -2283,7 +2295,7 @@ void Scene840::postInit(SceneObjectList *OwnerList) {
_boatKeys.setFrame(1);
_boatKeys.setPosition(Common::Point(250, 83));
_boatKeys.fixPriority(120);
- _boatKeys.setDetails(840, -1, 8, 9, 2, NULL);
+ _boatKeys.setDetails(840, -1, 8, 9, 2, (SceneItem *)NULL);
_field1AC0 = 1;
}
@@ -2375,7 +2387,7 @@ void Scene840::signal() {
case 4:
_sceneMode = 8403;
_boatKeys.postInit();
- _boatKeys.setDetails(840, -1, 8, 9, 2, NULL);
+ _boatKeys.setDetails(840, -1, 8, 9, 2, (SceneItem *)NULL);
setAction(&_sequenceManager1, this, 8403, &_carter, &_boatKeys, NULL);
break;
case 5:
@@ -2667,7 +2679,7 @@ void Scene860::postInit(SceneObjectList *OwnerList) {
_object2.setVisage(880);
_object2.setPosition(Common::Point(196, 81));
BF_GLOBALS._sceneItems.push_back(&_object2);
- _object2.setDetails(860, 0, 1, -1, 1, NULL);
+ _object2.setDetails(860, 0, 1, -1, 1, (SceneItem *)NULL);
_object2.fixPriority(20);
_neRect = Rect(0, 0, 0, 0);
@@ -2864,7 +2876,7 @@ void Scene870::CrateInset::initContents() {
_jar.setPosition(Common::Point(scene->_crateInset._position.x + 5,
scene->_crateInset._position.y - 26));
_jar.fixPriority(251);
- _jar.setDetails(870, 39, 40, 41, 1, NULL);
+ _jar.setDetails(870, 39, 40, 41, 1, (SceneItem *)NULL);
BF_GLOBALS._sceneItems.remove(&_jar);
BF_GLOBALS._sceneItems.push_front(&_jar);
}
@@ -2878,7 +2890,7 @@ void Scene870::CrateInset::initContents() {
_rags.setPosition(Common::Point(scene->_crateInset._position.x - 18,
scene->_crateInset._position.y - 18));
_rags.fixPriority(251);
- _rags.setDetails(870, 42, 43, 44, 1, NULL);
+ _rags.setDetails(870, 42, 43, 44, 1, (SceneItem *)NULL);
BF_GLOBALS._sceneItems.remove(&_rags);
BF_GLOBALS._sceneItems.push_front(&_rags);
}
@@ -3051,7 +3063,7 @@ void Scene870::postInit(SceneObjectList *OwnerList) {
_lyle.setObjectWrapper(new SceneObjectWrapper());
_lyle.animate(ANIM_MODE_1, NULL);
_lyle._moveDiff = Common::Point(2, 1);
- _lyle.setDetails(870, 27, 28, 29, 1, NULL);
+ _lyle.setDetails(870, 27, 28, 29, 1, (SceneItem *)NULL);
}
_yacht.postInit();
@@ -3059,7 +3071,7 @@ void Scene870::postInit(SceneObjectList *OwnerList) {
_yacht.setStrip(4);
_yacht.setFrame(4);
_yacht.setPosition(Common::Point(232, 19));
- _yacht.setDetails(870, 30, 31, 32, 1, NULL);
+ _yacht.setDetails(870, 30, 31, 32, 1, (SceneItem *)NULL);
if ((BF_INVENTORY.getObjectScene(INV_RAGS) == 0) && (BF_INVENTORY.getObjectScene(INV_FLARE) == 0) &&
(BF_INVENTORY.getObjectScene(INV_HANDCUFFS) == 355)) {
@@ -3069,9 +3081,9 @@ void Scene870::postInit(SceneObjectList *OwnerList) {
_green.setPosition(Common::Point(127, 109));
if (BF_GLOBALS._bookmark == bFinishedWGreen) {
- _green.setDetails(870, 51, 54, 53, 1, NULL);
+ _green.setDetails(870, 51, 54, 53, 1, (SceneItem *)NULL);
} else {
- _green.setDetails(870, 51, 52, 53, 1, NULL);
+ _green.setDetails(870, 51, 52, 53, 1, (SceneItem *)NULL);
}
}
}
@@ -3103,7 +3115,7 @@ void Scene870::postInit(SceneObjectList *OwnerList) {
_lyle.setPosition(Common::Point(156, 148));
_lyle.fixPriority(149);
}
-
+
if ((BF_INVENTORY.getObjectScene(INV_HANDCUFFS) != 1) &&
(BF_INVENTORY.getObjectScene(INV_GRENADES) == 355)) {
_object4.postInit();
@@ -3123,7 +3135,7 @@ void Scene870::postInit(SceneObjectList *OwnerList) {
}
break;
}
-
+
_boat.setDetails(7, 870, 3, 4, 5, 1);
_crate.setDetails(14, 870, 12, 13, 14, 1);
_water.setDetails(5, 870, 24, 25, 26, 1);
@@ -3346,11 +3358,11 @@ void Scene880::postInit(SceneObjectList *OwnerList) {
_object2.postInit();
_object2.setVisage(880);
_object2.setPosition(Common::Point(209, 76));
- _object2.setDetails(880, 4, 5, 6, 1, NULL);
+ _object2.setDetails(880, 4, 5, 6, 1, (SceneItem *)NULL);
_object4.postInit();
_object4.setVisage(875);
- _object4.setDetails(880, 7, -1, 9, 1, NULL);
+ _object4.setDetails(880, 7, -1, 9, 1, (SceneItem *)NULL);
_object5.postInit();
_object5.setVisage(874);
@@ -3381,7 +3393,7 @@ void Scene880::postInit(SceneObjectList *OwnerList) {
_object4.setFrame2(_object4.getFrameCount());
_object4.fixPriority(160);
_object4.setPosition(Common::Point(255, 148));
-
+
_seqNumber = 8816;
} else if (BF_GLOBALS.getFlag(fBlowUpGoon)) {
_object4.setStrip(7);
@@ -3393,7 +3405,7 @@ void Scene880::postInit(SceneObjectList *OwnerList) {
} else {
_object4.setStrip(2);
_object4.setPosition(Common::Point(258, 147));
-
+
_object3.postInit();
_object3.setVisage(871);
_object3.setStrip(4);
@@ -3588,7 +3600,7 @@ void Scene880::handleAction(Action *action) {
action->_owner = NULL;
}
}
-
+
void Scene880::dispatch() {
SceneExt::dispatch();
diff --git a/engines/tsage/blue_force/blueforce_scenes9.cpp b/engines/tsage/blue_force/blueforce_scenes9.cpp
index 545edb91d6..2178f31b30 100644
--- a/engines/tsage/blue_force/blueforce_scenes9.cpp
+++ b/engines/tsage/blue_force/blueforce_scenes9.cpp
@@ -35,7 +35,7 @@ namespace BlueForce {
*
*--------------------------------------------------------------------------*/
-bool Scene900::Item1::startAction(CursorType action, Event &event) {
+bool Scene900::Exterior::startAction(CursorType action, Event &event) {
if (action == CURSOR_LOOK) {
SceneItem::display2(900, 6);
return true;
@@ -44,7 +44,7 @@ bool Scene900::Item1::startAction(CursorType action, Event &event) {
}
}
-bool Scene900::Item4::startAction(CursorType action, Event &event) {
+bool Scene900::WestExit::startAction(CursorType action, Event &event) {
Scene900 *scene = (Scene900 *)BF_GLOBALS._sceneManager._scene;
BF_GLOBALS._player.disableControl();
@@ -62,37 +62,37 @@ bool Scene900::Gate::startAction(CursorType action, Event &event) {
switch (action) {
case CURSOR_USE:
- if (BF_GLOBALS._v4CEC0 == 0) {
+ if (BF_GLOBALS._gateStatus == 0) {
return NamedObject::startAction(action, event);
} else {
BF_GLOBALS._player.disableControl();
- if (BF_GLOBALS._v4CEC0 == 2) {
+ if (BF_GLOBALS._gateStatus == 2) {
scene->_sceneMode = 9006;
- BF_GLOBALS._v4CEC0 = 1;
+ BF_GLOBALS._gateStatus = 1;
scene->setAction(&scene->_sequenceManager1, scene, 9006, &BF_GLOBALS._player, this, NULL);
} else {
- BF_GLOBALS._v4CEC0 = 2;
+ BF_GLOBALS._gateStatus = 2;
if (scene->_dog._flag == false) {
BF_GLOBALS._player.setAction(&scene->_action4);
} else {
scene->_sceneMode = 9005;
scene->setAction(&scene->_sequenceManager1, scene, 9005, &BF_GLOBALS._player, this, NULL);
- BF_GLOBALS._walkRegions.proc2(24);
+ BF_GLOBALS._walkRegions.enableRegion(24);
}
}
return true;
}
break;
case INV_WAREHOUSE_KEYS:
- if (BF_GLOBALS._v4CEC0 == 2) {
+ if (BF_GLOBALS._gateStatus == 2) {
SceneItem::display2(900, 14);
} else {
- if (BF_GLOBALS._v4CEC0 == 0) {
+ if (BF_GLOBALS._gateStatus == 0) {
if (!BF_GLOBALS.getFlag(fGotPointsForUnlockGate)) {
BF_GLOBALS.setFlag(fGotPointsForUnlockGate);
T2_GLOBALS._uiElements.addScore(30);
}
- BF_GLOBALS._v4CEC0 = 1;
+ BF_GLOBALS._gateStatus = 1;
} else {
if (!BF_GLOBALS.getFlag(fGotPointsForLockGate)) {
if (BF_GLOBALS._bookmark == bEndDayThree) {
@@ -100,7 +100,7 @@ bool Scene900::Gate::startAction(CursorType action, Event &event) {
T2_GLOBALS._uiElements.addScore(30);
}
}
- BF_GLOBALS._v4CEC0 = 0;
+ BF_GLOBALS._gateStatus = 0;
}
scene->_sceneMode = 9004;
BF_GLOBALS._player.disableControl();
@@ -117,12 +117,12 @@ bool Scene900::Door::startAction(CursorType action, Event &event) {
switch (action) {
case CURSOR_USE:
- if (BF_GLOBALS._v4CEC0 == 2) {
+ if (BF_GLOBALS._gateStatus == 2) {
if (_flag) {
SceneItem::display2(900, 1);
} else {
BF_GLOBALS._player.disableControl();
- BF_GLOBALS._walkRegions.proc2(26);
+ BF_GLOBALS._walkRegions.enableRegion(26);
scene->_sceneMode = 9007;
scene->setAction(&scene->_sequenceManager1, scene, 9007, &BF_GLOBALS._player, &scene->_door, this, NULL);
}
@@ -131,7 +131,7 @@ bool Scene900::Door::startAction(CursorType action, Event &event) {
return NamedObject::startAction(action, event);
break;
case INV_WAREHOUSE_KEYS:
- if (BF_GLOBALS._v4CEC0 == 2) {
+ if (BF_GLOBALS._gateStatus == 2) {
BF_GLOBALS._player.disableControl();
scene->_sceneMode = 9012;
scene->setAction(&scene->_sequenceManager1, scene, 9012, &BF_GLOBALS._player, &scene->_door, NULL);
@@ -180,11 +180,12 @@ bool Scene900::Lyle::startAction(CursorType action, Event &event) {
if (action == CURSOR_TALK) {
if (!_action) {
if (scene->_dog._flag) {
- if (BF_GLOBALS._v4CEC0 == 0)
+ // Dog is no longer there
+ if (BF_GLOBALS._gateStatus == 0)
scene->_stripManager.start(9004, &BF_GLOBALS._stripProxy);
else {
if (scene->_door._flag == 1) {
- if (BF_GLOBALS._v4CEC0 == 2)
+ if (BF_GLOBALS._gateStatus == 2)
scene->_stripManager.start(9005, &BF_GLOBALS._stripProxy);
else
scene->_stripManager.start(9001, &BF_GLOBALS._stripProxy);
@@ -192,10 +193,11 @@ bool Scene900::Lyle::startAction(CursorType action, Event &event) {
scene->_stripManager.start(9001, &BF_GLOBALS._stripProxy);
}
} else {
- if (scene->_field1974)
+ // Dog is there
+ if (scene->_lyleDialogCtr)
scene->_stripManager.start(9003, &BF_GLOBALS._stripProxy);
else {
- ++scene->_field1974;
+ ++scene->_lyleDialogCtr;
scene->_stripManager.start(9002, &BF_GLOBALS._stripProxy);
}
}
@@ -384,7 +386,7 @@ void Scene900::Action3::signal() {
break;
default:
break;
- }
+ }
}
void Scene900::Action4::signal() {
@@ -416,7 +418,7 @@ void Scene900::Action4::signal() {
/*--------------------------------------------------------------------------*/
Scene900::Scene900(): PalettedScene() {
- _field1974 = _field1976 = 0;
+ _lyleDialogCtr = _field1976 = 0;
}
void Scene900::postInit(SceneObjectList *OwnerList) {
@@ -425,7 +427,7 @@ void Scene900::postInit(SceneObjectList *OwnerList) {
if (BF_GLOBALS._sceneManager._previousScene == 910)
BF_GLOBALS._sound1.changeSound(91);
- _field1974 = 0;
+ _lyleDialogCtr = 0;
_field1976 = 0;
T2_GLOBALS._uiElements._active = true;
BF_GLOBALS.clearFlag(fCanDrawGun);
@@ -440,12 +442,12 @@ void Scene900::postInit(SceneObjectList *OwnerList) {
_body.fixPriority(120);
_body.setVisage(901);
_body.setPosition(Common::Point(159,128));
- _body.setDetails(900, 15, 16, 17, ANIM_MODE_1, NULL);
+ _body.setDetails(900, 15, 16, 17, ANIM_MODE_1, (SceneItem *)NULL);
}
if (BF_GLOBALS._sceneManager._previousScene == 910) {
_sceneBounds.moveTo(639, 0);
- BF_GLOBALS._v4CEC0 = 2;
+ BF_GLOBALS._gateStatus = 2;
BF_INVENTORY.setObjectScene(INV_FISHING_NET, 900);
_dog._flag = 1;
}
@@ -456,14 +458,14 @@ void Scene900::postInit(SceneObjectList *OwnerList) {
_stripManager.addSpeaker(&_jakeJacketSpeaker);
_stripManager.addSpeaker(&_lyleHatSpeaker);
- _item4.setDetails(Rect(0, 85, 20, 130), 900, -1, -1, -1, 1, 0);
+ _westExit.setDetails(Rect(0, 85, 20, 130), 900, -1, -1, -1, 1, 0);
BF_GLOBALS._player.postInit();
_dog.postInit();
_dog.setVisage(902);
_dog.setPosition(Common::Point(845, 135));
_dog.fixPriority(122);
- _dog.setDetails(900, 8, -1, 9, 1, NULL);
+ _dog.setDetails(900, 8, -1, 9, 1, (SceneItem *)NULL);
if (_dog._flag == 0) {
_dog.animate(ANIM_MODE_1, NULL);
@@ -485,10 +487,10 @@ void Scene900::postInit(SceneObjectList *OwnerList) {
_gate.setVisage(900);
_gate.setStrip(2);
- if (BF_GLOBALS._v4CEC0 == 2)
+ if (BF_GLOBALS._gateStatus == 2)
_gate.setPosition(Common::Point(758, 127));
else {
- BF_GLOBALS._walkRegions.proc1(24);
+ BF_GLOBALS._walkRegions.disableRegion(24);
_gate.setPosition(Common::Point(804, 132));
}
@@ -515,14 +517,14 @@ void Scene900::postInit(SceneObjectList *OwnerList) {
_door._flag = 1;
if ((BF_GLOBALS._sceneManager._previousScene == 880) || (BF_GLOBALS._sceneManager._previousScene != 910)) {
- BF_GLOBALS._walkRegions.proc1(26);
+ BF_GLOBALS._walkRegions.disableRegion(26);
BF_GLOBALS._player.disableControl();
if (BF_GLOBALS._bookmark == bFinishedWGreen) {
_sceneMode = 9013;
_lyle.postInit();
_lyle._moveDiff.y = 7;
_lyle._flags |= OBJFLAG_CHECK_REGION;
- _lyle.setDetails(900, 19, 20, 21, ANIM_MODE_1, NULL);
+ _lyle.setDetails(900, 19, 20, 21, ANIM_MODE_1, (SceneItem *)NULL);
_lyleHatSpeaker._xp = 210;
_jakeJacketSpeaker._xp = 75;
setAction(&_sequenceManager1, this, 9013, &BF_GLOBALS._player, &_lyle, NULL);
@@ -535,10 +537,10 @@ void Scene900::postInit(SceneObjectList *OwnerList) {
_lyle.setPosition(Common::Point(780, 153));
_lyle._moveDiff.y = 7;
_lyle._flags |= 0x1000;
- _lyle.setDetails(900, 19, 20, 21, ANIM_MODE_1, NULL);
+ _lyle.setDetails(900, 19, 20, 21, ANIM_MODE_1, (SceneItem *)NULL);
_lyle.animate(ANIM_MODE_1, NULL);
_lyle.setObjectWrapper(new SceneObjectWrapper());
- }
+ }
_sceneMode = 9000;
setAction(&_sequenceManager1, this, 9000, &BF_GLOBALS._player, NULL);
@@ -551,17 +553,17 @@ void Scene900::postInit(SceneObjectList *OwnerList) {
if (BF_GLOBALS.getFlag(fWithLyle)) {
_lyle.postInit();
_lyle._flags |= 0x1000;
- _lyle.setDetails(900, 19, 20, 21, ANIM_MODE_1, NULL);
+ _lyle.setDetails(900, 19, 20, 21, ANIM_MODE_1, (SceneItem *)NULL);
setAction(&_sequenceManager1, this, 9014, &BF_GLOBALS._player, &_door, &_lyle, NULL);
} else
setAction(&_sequenceManager1, this, 9002, &BF_GLOBALS._player, &_door, NULL);
}
- _gate.setDetails(900, 0, -1, 1, 1, 0);
- _door.setDetails(900, 2, -1, 5, 1, 0);
+ _gate.setDetails(900, 0, -1, 1, 1, (SceneItem *)NULL);
+ _door.setDetails(900, 2, -1, 5, 1, (SceneItem *)NULL);
_item2.setDetails(Rect(0, 0, 225, 21), 666, 25, -1, -1, 1, NULL);
_item3.setDetails(Rect(37, 21, 324, 50), 666, 26, -1, -1, 1, NULL);
- _item1.setDetails(Rect(0, 0, 960, 200), 900, 7, -1, -1, 1, NULL);
+ _exterior.setDetails(Rect(0, 0, 960, 200), 900, 7, -1, -1, 1, NULL);
}
void Scene900::signal() {
@@ -572,7 +574,7 @@ void Scene900::signal() {
BF_GLOBALS._sceneManager.changeScene(910);
break;
case 3:
- BF_GLOBALS._walkRegions.proc1(24);
+ BF_GLOBALS._walkRegions.disableRegion(24);
_sceneMode = 9004;
setAction(&_sequenceManager1, this, 9006, &BF_GLOBALS._player, &_gate, NULL);
break;
@@ -580,7 +582,7 @@ void Scene900::signal() {
BF_GLOBALS._player.enableControl();
break;
case 9001:
- if ((BF_INVENTORY.getObjectScene(INV_FISHING_NET) == 900) || (BF_GLOBALS._v4CEC0 != 0) ||
+ if ((BF_INVENTORY.getObjectScene(INV_FISHING_NET) == 900) || (BF_GLOBALS._gateStatus != 0) ||
(_door._flag == 0))
BF_GLOBALS.setFlag(fLeftTraceIn900);
else
@@ -589,11 +591,11 @@ void Scene900::signal() {
BF_GLOBALS._sceneManager.changeScene(880);
break;
case 9002:
- BF_GLOBALS._walkRegions.proc1(26);
+ BF_GLOBALS._walkRegions.disableRegion(26);
BF_GLOBALS._player.enableControl();
break;
case 9004:
- if (BF_GLOBALS._v4CEC0 == 0)
+ if (BF_GLOBALS._gateStatus == 0)
SceneItem::display2(900, 3);
else
SceneItem::display2(900, 4);
@@ -606,7 +608,7 @@ void Scene900::signal() {
BF_GLOBALS._player.enableControl();
break;
case 9006:
- BF_GLOBALS._walkRegions.proc1(24);
+ BF_GLOBALS._walkRegions.disableRegion(24);
BF_GLOBALS._player.enableControl();
break;
case 9007:
@@ -625,7 +627,7 @@ void Scene900::signal() {
break;
case 9010:
_sound1.play(92);
- if (BF_GLOBALS._v4CEC0 == 2) {
+ if (BF_GLOBALS._gateStatus == 2) {
_sceneMode = 9008;
setAction(&_sequenceManager1, this, 9008, &BF_GLOBALS._player, &_dog, NULL);
} else {
@@ -666,9 +668,9 @@ void Scene900::signal() {
BF_GLOBALS._player.enableControl();
break;
case 9016:
- if ((BF_GLOBALS._clip1Bullets == 0) && (BF_GLOBALS._clip2Bullets == 0)){
- BF_GLOBALS._clip1Bullets = 8;
+ if ((BF_GLOBALS._clip1Bullets == 0) && (BF_GLOBALS._clip2Bullets == 0)) {
BF_GLOBALS._clip1Bullets = 8;
+ BF_GLOBALS._clip2Bullets = 8;
SceneItem::display2(900, 25);
} else if (BF_GLOBALS._clip1Bullets == 0) {
BF_GLOBALS._clip1Bullets = 8;
@@ -690,7 +692,7 @@ void Scene900::process(Event &event) {
SceneExt::process(event);
if (BF_GLOBALS._player._enabled && !_focusObject && (event.mousePos.y < (UI_INTERFACE_Y - 1))) {
- if (_item4.contains(event.mousePos)) {
+ if (_westExit.contains(event.mousePos)) {
GfxSurface surface = _cursorVisage.getFrame(EXITFRAME_W);
BF_GLOBALS._events.setCursor(surface);
} else {
@@ -718,7 +720,7 @@ void Scene900::dispatch() {
void Scene900::synchronize(Serializer &s) {
SceneExt::synchronize(s);
- s.syncAsSint16LE(_field1974);
+ s.syncAsSint16LE(_lyleDialogCtr);
s.syncAsSint16LE(_field1976);
}
@@ -755,26 +757,26 @@ void Scene910::Action2::signal() {
switch (_actionIndex++) {
case 0:
- scene->_object7.postInit();
- scene->_object7.setVisage(919);
- scene->_object7.setPosition(Common::Point(267, 51));
- scene->_object7.fixPriority(40);
+ scene->_shadow.postInit();
+ scene->_shadow.setVisage(919);
+ scene->_shadow.setPosition(Common::Point(267, 51));
+ scene->_shadow.fixPriority(40);
signal();
break;
case 1:
- scene->_object7.hide();
+ scene->_shadow.hide();
setDelay(600);
break;
case 2:
- scene->_object7.setStrip(BF_GLOBALS._randomSource.getRandomNumber(3) + 2);
- scene->_object7.setFrame(1);
- scene->_object7.show();
+ scene->_shadow.setStrip(BF_GLOBALS._randomSource.getRandomNumber(2) + 2);
+ scene->_shadow.setFrame(1);
+ scene->_shadow.show();
setDelay(6);
break;
case 3:
_actionIndex = 1;
- scene->_object7.setStrip(BF_GLOBALS._randomSource.getRandomNumber(3) + 2);
- scene->_object7.animate(ANIM_MODE_5, this);
+ scene->_shadow.setStrip(BF_GLOBALS._randomSource.getRandomNumber(2) + 2);
+ scene->_shadow.animate(ANIM_MODE_5, this);
break;
default:
break;
@@ -797,7 +799,7 @@ bool Scene910::Lyle::startAction(CursorType action, Event &event) {
else
return false;
} else if (action == CURSOR_TALK) {
- if ((BF_GLOBALS._v4CEE0 != 0) || (BF_GLOBALS._v4CEE2 != 0)) {
+ if ((BF_GLOBALS._hiddenDoorStatus != 0) || (BF_GLOBALS._v4CEE2 != 0)) {
scene->_stripManager.start(9100 + _field90, &BF_GLOBALS._stripProxy);
if (_field90 < 1)
_field90++;
@@ -822,7 +824,7 @@ bool Scene910::Nico::startAction(CursorType action, Event &event) {
switch (action) {
case CURSOR_USE:
BF_GLOBALS._player.disableControl();
- scene->_field2DDA = 6;
+ scene->_sceneSubMode = 6;
scene->_sceneMode = 9123;
if (BF_GLOBALS._player._visage == 1911)
scene->setAction(&scene->_sequenceManager1, scene, 9123, &BF_GLOBALS._player, NULL);
@@ -844,10 +846,10 @@ bool Scene910::Nico::startAction(CursorType action, Event &event) {
scene->_stripManager.start(9103 + BF_GLOBALS._v4CEE6, &BF_GLOBALS._stripProxy);
return true;
break;
- case 1:
+ case INV_COLT45:
if (BF_GLOBALS._v4CEE2 > 1) {
if (BF_GLOBALS._v4CEE2 != 4) {
- if ((BF_GLOBALS.getFlag(gunDrawn)) && (BF_GLOBALS.getFlag(25)) && (BF_GLOBALS.getHasBullets())) {
+ if ((BF_GLOBALS.getFlag(gunDrawn)) && (BF_GLOBALS.getFlag(fGunLoaded)) && (BF_GLOBALS.getHasBullets())) {
if (scene->_field2DE0 == 0) {
BF_GLOBALS._player.disableControl();
scene->_sceneMode = 9126;
@@ -868,7 +870,7 @@ bool Scene910::Nico::startAction(CursorType action, Event &event) {
return true;
}
} else {
- if ((BF_GLOBALS.getFlag(gunDrawn)) && (BF_GLOBALS.getFlag(25)) && (BF_GLOBALS.getHasBullets())) {
+ if ((BF_GLOBALS.getFlag(gunDrawn)) && (BF_GLOBALS.getFlag(fGunLoaded)) && (BF_GLOBALS.getHasBullets())) {
BF_GLOBALS._player.disableControl();
scene->_sceneMode = 9125;
scene->setAction(&scene->_sequenceManager1, scene, 9125, &scene->_nico, NULL);
@@ -876,8 +878,8 @@ bool Scene910::Nico::startAction(CursorType action, Event &event) {
return NamedObject::startAction(action, event);
}
break;
- case 39:
- case 53:
+ case INV_BADGE:
+ case INV_ID:
if (BF_GLOBALS._v4CEE2 >= 4)
return NamedObject::startAction(action, event);
@@ -892,11 +894,11 @@ bool Scene910::Nico::startAction(CursorType action, Event &event) {
return true;
break;
- case 57:
+ case INV_YELLOW_CORD:
if (BF_GLOBALS._v4CEE2 < 4) {
BF_GLOBALS._player.disableControl();
scene->_yellowCord.fixPriority(121);
- scene->_field2DDA = 10;
+ scene->_sceneSubMode = 10;
scene->_sceneMode = 9123;
if (BF_GLOBALS._player._visage == 1911)
scene->setAction(&scene->_sequenceManager1, scene, 9123, &BF_GLOBALS._player, NULL);
@@ -914,7 +916,7 @@ bool Scene910::Nico::startAction(CursorType action, Event &event) {
return true;
}
break;
- case 58:
+ case INV_HALF_YELLOW_CORD:
if (BF_GLOBALS._v4CECC == 1)
SceneItem::display(910, 84, SET_WIDTH, 312,
SET_X, GLOBALS._sceneManager._scene->_sceneBounds.left + 4,
@@ -929,8 +931,8 @@ bool Scene910::Nico::startAction(CursorType action, Event &event) {
SET_EXT_FGCOLOR, 13, LIST_END);
return true;
break;
- case 59:
- case 61:
+ case INV_BLACK_CORD:
+ case INV_HALF_BLACK_CORD:
SceneItem::display(910, 83, SET_WIDTH, 312,
SET_X, GLOBALS._sceneManager._scene->_sceneBounds.left + 4,
SET_Y, GLOBALS._sceneManager._scene->_sceneBounds.top + UI_INTERFACE_Y + 2,
@@ -950,7 +952,7 @@ bool Scene910::Stuart::startAction(CursorType action, Event &event) {
switch (action) {
case CURSOR_USE:
BF_GLOBALS._player.disableControl();
- scene->_field2DDA = 7;
+ scene->_sceneSubMode = 7;
scene->_sceneMode = 9123;
if (BF_GLOBALS._player._visage == 1911)
scene->setAction(&scene->_sequenceManager1, scene, 9123, &BF_GLOBALS._player, NULL);
@@ -965,8 +967,8 @@ bool Scene910::Stuart::startAction(CursorType action, Event &event) {
scene->_stripManager.start(9107 + BF_GLOBALS._v4CEE8, &BF_GLOBALS._stripProxy);
return true;
break;
- case 1:
- if ((BF_GLOBALS.getFlag(gunDrawn)) && (BF_GLOBALS.getFlag(25)) && (BF_GLOBALS.getHasBullets())){
+ case INV_COLT45:
+ if ((BF_GLOBALS.getFlag(gunDrawn)) && (BF_GLOBALS.getFlag(fGunLoaded)) && (BF_GLOBALS.getHasBullets())){
BF_GLOBALS._player.disableControl();
if (BF_GLOBALS._v4CEE4 == 2) {
scene->_sceneMode = 9132;
@@ -983,7 +985,7 @@ bool Scene910::Stuart::startAction(CursorType action, Event &event) {
} else
return NamedObject::startAction(action, event);
break;
- case 57:
+ case INV_YELLOW_CORD:
if (BF_GLOBALS._v4CECC == 1) {
SceneItem::display(910, 84, SET_WIDTH, 312,
SET_X, GLOBALS._sceneManager._scene->_sceneBounds.left + 4,
@@ -994,7 +996,7 @@ bool Scene910::Stuart::startAction(CursorType action, Event &event) {
} else {
BF_GLOBALS._player.disableControl();
if (BF_GLOBALS._v4CEE2 == 4) {
- scene->_field2DDA = 11;
+ scene->_sceneSubMode = 11;
scene->_sceneMode = 9123;
if (BF_GLOBALS._player._visage == 1911)
scene->setAction(&scene->_sequenceManager1, scene, 9123, &BF_GLOBALS._player, NULL);
@@ -1002,7 +1004,7 @@ bool Scene910::Stuart::startAction(CursorType action, Event &event) {
scene->signal();
return true;
} else {
- scene->_field2DDA = 12;
+ scene->_sceneSubMode = 12;
scene->_sceneMode = 9123;
if (BF_GLOBALS._player._visage == 1911)
scene->setAction(&scene->_sequenceManager1, scene, 9123, &BF_GLOBALS._player, NULL);
@@ -1012,7 +1014,7 @@ bool Scene910::Stuart::startAction(CursorType action, Event &event) {
}
}
break;
- case 58:
+ case INV_HALF_YELLOW_CORD:
if (BF_GLOBALS._v4CECC == 1) {
SceneItem::display(910, 84, SET_WIDTH, 312,
SET_X, GLOBALS._sceneManager._scene->_sceneBounds.left + 4,
@@ -1022,7 +1024,7 @@ bool Scene910::Stuart::startAction(CursorType action, Event &event) {
return true;
} else {
BF_GLOBALS._player.disableControl();
- scene->_field2DDA = 11;
+ scene->_sceneSubMode = 11;
scene->_sceneMode = 9123;
if (BF_GLOBALS._player._visage == 1911)
scene->setAction(&scene->_sequenceManager1, scene, 9123, &BF_GLOBALS._player, NULL);
@@ -1031,8 +1033,8 @@ bool Scene910::Stuart::startAction(CursorType action, Event &event) {
return true;
}
break;
- case 59:
- case 61:
+ case INV_BLACK_CORD:
+ case INV_HALF_BLACK_CORD:
SceneItem::display(910, 83, SET_WIDTH, 312,
SET_X, GLOBALS._sceneManager._scene->_sceneBounds.left + 4,
SET_Y, GLOBALS._sceneManager._scene->_sceneBounds.top + UI_INTERFACE_Y + 2,
@@ -1051,8 +1053,8 @@ bool Scene910::Forbes::startAction(CursorType action, Event &event) {
if (action == CURSOR_TALK) {
BF_GLOBALS._player.disableControl();
- BF_GLOBALS._walkRegions.proc2(1);
- BF_GLOBALS._walkRegions.proc2(16);
+ BF_GLOBALS._walkRegions.enableRegion(1);
+ BF_GLOBALS._walkRegions.enableRegion(16);
scene->_sceneMode = 9140;
scene->setAction(&scene->_sequenceManager1, scene, 9140, &scene->_forbes, &BF_GLOBALS._player, &scene->_lyle, NULL);
return true;
@@ -1074,15 +1076,15 @@ bool Scene910::PowerCord::startAction(CursorType action, Event &event) {
if ((action == CURSOR_LOOK) || (action == CURSOR_TALK) || (action < CURSOR_WALK)) {
if (_field90 == 1)
return false;
- if ((_field92 != 1) || (BF_GLOBALS._v4CEE0 == 0 ))
+ if ((_field92 != 1) || (BF_GLOBALS._hiddenDoorStatus == 0 ))
return NamedObject::startAction(action, event);
return false;
} else if (action == CURSOR_USE) {
if (_field90 == 0) {
- if ((BF_GLOBALS._v4CEE0 == 0) || (_field92 != 1)) {
+ if ((BF_GLOBALS._hiddenDoorStatus == 0) || (_field92 != 1)) {
BF_GLOBALS._player.disableControl();
if (_field92 == 1) {
- scene->_field2DDA = 8;
+ scene->_sceneSubMode = 8;
scene->_sceneMode = 9123;
if (BF_GLOBALS._player._visage == 1911)
scene->setAction(&scene->_sequenceManager1, scene, 9123, &BF_GLOBALS._player, NULL);
@@ -1092,7 +1094,7 @@ bool Scene910::PowerCord::startAction(CursorType action, Event &event) {
return true;
} else {
scene->_destPos = Common::Point(151, 186);
- scene->_field2DDA = 4;
+ scene->_sceneSubMode = 4;
scene->_sceneMode = 9123;
if (BF_GLOBALS._player._visage == 1911)
scene->setAction(&scene->_sequenceManager1, scene, 9123, &BF_GLOBALS._player, NULL);
@@ -1143,7 +1145,7 @@ bool Scene910::BreakerBox::startAction(CursorType action, Event &event) {
BF_GLOBALS._player.disableControl();
scene->_sceneMode = 9102;
if (BF_GLOBALS.getFlag(gunDrawn)) {
- scene->_field2DDA = 1;
+ scene->_sceneSubMode = 1;
scene->_sceneMode = 9123;
scene->setAction(&scene->_sequenceManager1, scene, 9123, &BF_GLOBALS._player, NULL);
return true;
@@ -1173,7 +1175,7 @@ bool Scene910::FakeWall::startAction(CursorType action, Event &event) {
if (action == INV_YELLOW_CORD) {
BF_GLOBALS._player.disableControl();
scene->_destPos = Common::Point(285, 114);
- scene->_field2DDA = 9;
+ scene->_sceneSubMode = 9;
scene->_sceneMode = 9123;
if (BF_GLOBALS._player._visage == 1911)
scene->setAction(&scene->_sequenceManager1, scene, 9123, &BF_GLOBALS._player, NULL);
@@ -1192,23 +1194,23 @@ void Scene910::BreakerBoxInset::postInit(SceneObjectList *OwnerList) {
_lookLineNum = 7;
_useLineNum = 8;
BF_GLOBALS._sceneItems.push_back(this);
- scene->_field2DD8 = 0;
+ scene->_breakerButtonCtr = 0;
- _object13.setupBreaker(115, 44, 1, BF_GLOBALS._v4CECE[0]);
- _object14.setupBreaker(116, 63, 2, BF_GLOBALS._v4CECE[1]);
- _object15.setupBreaker(116, 69, 2, BF_GLOBALS._v4CECE[2]);
- _object16.setupBreaker(115, 76, 1, BF_GLOBALS._v4CECE[3]);
- _object17.setupBreaker(115, 95, 1, BF_GLOBALS._v4CECE[4]);
- _object18.setupBreaker(116, 114, 2, BF_GLOBALS._v4CECE[5]);
- _object19.setupBreaker(116, 120, 2, BF_GLOBALS._v4CECE[6]);
- _object20.setupBreaker(188, 45, 2, BF_GLOBALS._v4CECE[7]);
- _object21.setupBreaker(188, 51, 2, BF_GLOBALS._v4CECE[8]);
- _object22.setupBreaker(179, 59, 1, BF_GLOBALS._v4CECE[9]);
- _object23.setupBreaker(187, 78, 2, BF_GLOBALS._v4CECE[10]);
- _object24.setupBreaker(187, 84, 2, BF_GLOBALS._v4CECE[11]);
+ _object13.setupBreaker(115, 44, 1, BF_GLOBALS._breakerBoxStatusArr[0]);
+ _object14.setupBreaker(116, 63, 2, BF_GLOBALS._breakerBoxStatusArr[1]);
+ _object15.setupBreaker(116, 69, 2, BF_GLOBALS._breakerBoxStatusArr[2]);
+ _object16.setupBreaker(115, 76, 1, BF_GLOBALS._breakerBoxStatusArr[3]);
+ _object17.setupBreaker(115, 95, 1, BF_GLOBALS._breakerBoxStatusArr[4]);
+ _object18.setupBreaker(116, 114, 2, BF_GLOBALS._breakerBoxStatusArr[5]);
+ _object19.setupBreaker(116, 120, 2, BF_GLOBALS._breakerBoxStatusArr[6]);
+ _object20.setupBreaker(188, 45, 2, BF_GLOBALS._breakerBoxStatusArr[7]);
+ _object21.setupBreaker(188, 51, 2, BF_GLOBALS._breakerBoxStatusArr[8]);
+ _object22.setupBreaker(179, 59, 1, BF_GLOBALS._breakerBoxStatusArr[9]);
+ _object23.setupBreaker(187, 78, 2, BF_GLOBALS._breakerBoxStatusArr[10]);
+ _object24.setupBreaker(187, 84, 2, BF_GLOBALS._breakerBoxStatusArr[11]);
- _object25.subEBBDC(178, 90, 1, BF_GLOBALS._v4CECE[12]);
- _object26.subEBBDC(178, 108, 2, BF_GLOBALS._v4CECE[13]);
+ _object25.setupHiddenSwitch(178, 90, 1, BF_GLOBALS._breakerBoxStatusArr[12]);
+ _object26.setupHiddenSwitch(178, 108, 2, BF_GLOBALS._breakerBoxStatusArr[13]);
}
void Scene910::BreakerBoxInset::remove() {
@@ -1231,7 +1233,7 @@ void Scene910::BreakerBoxInset::remove() {
_object27.remove();
_object28.remove();
- if ((BF_GLOBALS._v4CECE[13] < 4) && (scene->_breakerBox._frame > 1))
+ if ((BF_GLOBALS._breakerBoxStatusArr[13] < 4) && (scene->_breakerBox._frame > 1))
scene->_breakerBox.animate(ANIM_MODE_6, NULL);
FocusObject::remove();
@@ -1239,20 +1241,20 @@ void Scene910::BreakerBoxInset::remove() {
void Scene910::Object13::synchronize(Serializer &s) {
NamedObject::synchronize(s);
- s.syncAsSint16LE(_field90);
- s.syncAsSint16LE(_field92);
+ s.syncAsSint16LE(_state);
+ s.syncAsSint16LE(_mode);
}
bool Scene910::Object13::startAction(CursorType action, Event &event) {
static uint32 black = 0;
Scene910 *scene = (Scene910 *)BF_GLOBALS._sceneManager._scene;
- int8 var2;
+ int8 xDiff;
- if (_field92 == 1)
- var2 = 12;
+ if (_mode == 1)
+ xDiff = 12;
else
- var2 = 7;
+ xDiff = 7;
switch (action) {
case CURSOR_LOOK:
@@ -1264,8 +1266,8 @@ bool Scene910::Object13::startAction(CursorType action, Event &event) {
return true;
case CURSOR_USE:
scene->_sound2.play(101);
- if (event.mousePos.x <= _position.x + var2) {
- if (_field92 != 1) {
+ if (event.mousePos.x <= _position.x + xDiff) {
+ if (_mode != 1) {
if (_frame > 6)
setFrame(_frame - 1);
} else {
@@ -1273,7 +1275,7 @@ bool Scene910::Object13::startAction(CursorType action, Event &event) {
setFrame(_frame - 1);
}
} else {
- if (_field92 == 1) {
+ if (_mode == 1) {
if (_frame < 3)
setFrame(_frame + 1);
} else {
@@ -1282,18 +1284,18 @@ bool Scene910::Object13::startAction(CursorType action, Event &event) {
}
}
- if (_field92 != 1)
- BF_GLOBALS._v4CECE[_field90 - 1] = (_field90 + 251) % 256;
+ if (_mode != 1)
+ BF_GLOBALS._breakerBoxStatusArr[_state - 1] = (_frame + 251) % 256;
else
- BF_GLOBALS._v4CECE[_field90 - 1] = _field90;
+ BF_GLOBALS._breakerBoxStatusArr[_state - 1] = _frame;
- switch (_field90) {
+ switch (_state) {
case 1:
if (BF_GLOBALS._v4CEE2 < 1) {
if (_frame == 2) {
- if (!BF_GLOBALS.getFlag(81)) {
+ if (!BF_GLOBALS.getFlag(fGotPointsForClosingDoor)) {
T2_GLOBALS._uiElements.addScore(30);
- BF_GLOBALS.setFlag(81);
+ BF_GLOBALS.setFlag(fGotPointsForClosingDoor);
}
scene->_sceneMode = 0;
if (BF_GLOBALS._dayNumber == 5) {
@@ -1302,7 +1304,7 @@ bool Scene910::Object13::startAction(CursorType action, Event &event) {
// _objectList.draw();
BF_GLOBALS._player.disableControl();
scene->_lyle.setVisage(912);
- scene->_object7.remove();
+ scene->_shadow.remove();
scene->_action2.remove();
scene->_nico.postInit();
scene->_sceneMode = 9129;
@@ -1332,9 +1334,9 @@ bool Scene910::Object13::startAction(CursorType action, Event &event) {
// _objectList.draw();
} else {
if (BF_GLOBALS._v4CEC8 == 1) {
- if (!BF_GLOBALS.getFlag(78)) {
+ if (!BF_GLOBALS.getFlag(fGotPointsForStartGenerator)) {
T2_GLOBALS._uiElements.addScore(30);
- BF_GLOBALS.setFlag(78);
+ BF_GLOBALS.setFlag(fGotPointsForStartGenerator);
}
BF_GLOBALS._player.disableControl();
BF_GLOBALS._v4CEC8 = 0;
@@ -1351,7 +1353,7 @@ bool Scene910::Object13::startAction(CursorType action, Event &event) {
return true;
case 4:
if (_frame == 2) {
- if (BF_GLOBALS._v4CECE[4] == 2) {
+ if (BF_GLOBALS._breakerBoxStatusArr[4] == 2) {
scene->_action1.setActionIndex(2);
scene->_action1.signal();
}
@@ -1362,7 +1364,7 @@ bool Scene910::Object13::startAction(CursorType action, Event &event) {
return true;
case 5:
if (_frame == 2) {
- if (BF_GLOBALS._v4CECE[3] == 2) {
+ if (BF_GLOBALS._breakerBoxStatusArr[3] == 2) {
scene->_action1.setActionIndex(2);
scene->_action1.signal();
}
@@ -1372,11 +1374,11 @@ bool Scene910::Object13::startAction(CursorType action, Event &event) {
}
return true;
case 15:
- if ((BF_GLOBALS._v4CECA == 2) && (BF_GLOBALS._v4CECE[17] == 1)) {
+ if ((BF_GLOBALS._v4CECA == 2) && (BF_GLOBALS._breakerBoxStatusArr[17] == 1)) {
if (_frame == 7)
- scene->subE83E1();
+ scene->closeHiddenDoor();
else
- scene->subE82BD();
+ scene->openHiddenDoor();
}
return true;
default:
@@ -1397,9 +1399,9 @@ void Scene910::Object13::setupBreaker(int x, int y, int mode, int8 frameNumber)
Scene910 *scene = (Scene910 *)BF_GLOBALS._sceneManager._scene;
NamedObject::postInit();
- _field92 = mode;
- scene->_field2DD8++;
- _field90 = scene->_field2DD8;
+ _mode = mode;
+ scene->_breakerButtonCtr++;
+ _state = scene->_breakerButtonCtr;
setVisage(910);
if (mode == 1) {
@@ -1432,18 +1434,18 @@ bool Scene910::Object25::startAction(CursorType action, Event &event) {
SceneItem::display2(910, 11);
return true;
case CURSOR_USE:
- _field92 = BF_GLOBALS._v4CECE[_field90 + 11];
+ _field92 = BF_GLOBALS._breakerBoxStatusArr[_field90 + 11];
switch (_field92 - 1) {
case 0:
_field92 = 2;
setStrip(7);
setFrame(1);
if (_field90 == 1) {
- scene->_field2DD8 = 14;
- scene->_breakerBoxInset._object27.setupBreaker(182, 92, 2, BF_GLOBALS._v4CECE[14]);
+ scene->_breakerButtonCtr = 14;
+ scene->_breakerBoxInset._object27.setupBreaker(182, 92, 2, BF_GLOBALS._breakerBoxStatusArr[14]);
} else {
- scene->_field2DD8 = 15;
- scene->_breakerBoxInset._object28.init(178, 108, 0, BF_GLOBALS._v4CECE[15]);
+ scene->_breakerButtonCtr = 15;
+ scene->_breakerBoxInset._object28.init(178, 108, 0, BF_GLOBALS._breakerBoxStatusArr[15]);
}
SceneItem::display2(910, 12);
break;
@@ -1461,11 +1463,11 @@ bool Scene910::Object25::startAction(CursorType action, Event &event) {
setStrip(7);
setFrame(1);
if (_field90 == 1) {
- scene->_field2DD8 = 14;
- scene->_breakerBoxInset._object27.setupBreaker(182, 96, 2, BF_GLOBALS._v4CECE[14]);
+ scene->_breakerButtonCtr = 14;
+ scene->_breakerBoxInset._object27.setupBreaker(182, 96, 2, BF_GLOBALS._breakerBoxStatusArr[14]);
} else {
- scene->_field2DD8 = 15;
- scene->_breakerBoxInset._object28.init(178, 108, 0, BF_GLOBALS._v4CECE[15]);
+ scene->_breakerButtonCtr = 15;
+ scene->_breakerBoxInset._object28.init(178, 108, 0, BF_GLOBALS._breakerBoxStatusArr[15]);
}
break;
case 3:
@@ -1475,7 +1477,7 @@ bool Scene910::Object25::startAction(CursorType action, Event &event) {
break;
}
- BF_GLOBALS._v4CECE[_field90 + 11] = _field92;
+ BF_GLOBALS._breakerBoxStatusArr[_field90 + 11] = _field92;
return true;
default:
return NamedObject::startAction(action, event);
@@ -1488,11 +1490,11 @@ void Scene910::Object25::remove() {
SceneObject::remove();
}
-void Scene910::Object25::subEBBDC(int x, int y, int arg8, int argA) {
+void Scene910::Object25::setupHiddenSwitch(int x, int y, int arg8, int argA) {
Scene910 *scene = (Scene910 *)BF_GLOBALS._sceneManager._scene;
NamedObject::postInit();
- scene->_field2DD8++;
+ scene->_breakerButtonCtr++;
_field90 = arg8;
_field92 = argA;
setVisage(910);
@@ -1504,11 +1506,11 @@ void Scene910::Object25::subEBBDC(int x, int y, int arg8, int argA) {
setStrip(7);
setFrame(1);
if (_field90 == 1) {
- scene->_field2DD8 = 14;
- scene->_breakerBoxInset._object27.setupBreaker(182, 96, 2, BF_GLOBALS._v4CECE[14]);
+ scene->_breakerButtonCtr = 14;
+ scene->_breakerBoxInset._object27.setupBreaker(182, 96, 2, BF_GLOBALS._breakerBoxStatusArr[14]);
} else {
- scene->_field2DD8 = 15;
- scene->_breakerBoxInset._object28.init(178, 108, 0, BF_GLOBALS._v4CECE[15]);
+ scene->_breakerButtonCtr = 15;
+ scene->_breakerBoxInset._object28.init(178, 108, 0, BF_GLOBALS._breakerBoxStatusArr[15]);
}
}
@@ -1529,7 +1531,7 @@ bool Scene910::BlackPlug::startAction(CursorType action, Event &event) {
SET_EXT_FGCOLOR, 13, LIST_END);
return true;
case CURSOR_USE:
- switch (_frame - _field90 - 2) {
+ switch (_frame - _state - 2) {
case 0:
SceneItem::display(910, 15, SET_WIDTH, 312,
SET_X, GLOBALS._sceneManager._scene->_sceneBounds.left + 4,
@@ -1544,11 +1546,11 @@ bool Scene910::BlackPlug::startAction(CursorType action, Event &event) {
BF_INVENTORY.setObjectScene(INV_HALF_BLACK_CORD, 910);
} else if (BF_GLOBALS._v4CECA == 2) {
BF_GLOBALS._v4CECA = 1;
- BF_INVENTORY.setObjectScene(INV_BLACK_CORD, 3 - _field90);
+ BF_INVENTORY.setObjectScene(INV_BLACK_CORD, 3 - _state);
BF_INVENTORY.setObjectScene(INV_HALF_BLACK_CORD, 1);
scene->_blackCord.setPosition(Common::Point(540, 100));
}
- setFrame(_field90 + 2);
+ setFrame(_state + 2);
break;
case 2:
if (BF_GLOBALS._v4CECC == 1) {
@@ -1557,14 +1559,14 @@ bool Scene910::BlackPlug::startAction(CursorType action, Event &event) {
BF_INVENTORY.setObjectScene(INV_HALF_YELLOW_CORD, 910);
} else if (BF_GLOBALS._v4CECC == 2) {
BF_GLOBALS._v4CECC = 1;
- BF_INVENTORY.setObjectScene(INV_YELLOW_CORD, 3 - _field90);
+ BF_INVENTORY.setObjectScene(INV_YELLOW_CORD, 3 - _state);
BF_INVENTORY.setObjectScene(INV_HALF_YELLOW_CORD, 1);
scene->_yellowCord.setPosition(Common::Point(540, 100));
}
- setFrame(_field90 + 2);
+ setFrame(_state + 2);
break;
case 3:
- if ((_position.x - 12) - (5 * _field90) < event.mousePos.x) {
+ if ((_position.x - 12) - (5 * _state) < event.mousePos.x) {
if (BF_GLOBALS._v4CECA == 1) {
BF_GLOBALS._v4CECA = 0;
BF_INVENTORY.setObjectScene(INV_BLACK_CORD, 1);
@@ -1572,11 +1574,11 @@ bool Scene910::BlackPlug::startAction(CursorType action, Event &event) {
scene->_blackCord.setPosition(Common::Point(540, 100));
} else if (BF_GLOBALS._v4CECA == 2) {
BF_GLOBALS._v4CECA = 1;
- BF_INVENTORY.setObjectScene(INV_BLACK_CORD, 3 - _field90);
+ BF_INVENTORY.setObjectScene(INV_BLACK_CORD, 3 - _state);
BF_INVENTORY.setObjectScene(INV_HALF_BLACK_CORD, 1);
scene->_blackCord.setPosition(Common::Point(540, 100));
}
- setFrame(_field90 + 4);
+ setFrame(_state + 4);
} else {
if (BF_GLOBALS._v4CECC == 1) {
BF_GLOBALS._v4CECC = 0;
@@ -1584,25 +1586,25 @@ bool Scene910::BlackPlug::startAction(CursorType action, Event &event) {
BF_INVENTORY.setObjectScene(INV_HALF_YELLOW_CORD, 910);
} else if (BF_GLOBALS._v4CECC == 2) {
BF_GLOBALS._v4CECC = 1;
- BF_INVENTORY.setObjectScene(INV_YELLOW_CORD, 3 - _field90);
+ BF_INVENTORY.setObjectScene(INV_YELLOW_CORD, 3 - _state);
BF_INVENTORY.setObjectScene(INV_HALF_YELLOW_CORD, 1);
scene->_yellowCord.setPosition(Common::Point(540, 100));
}
- setFrame(_field90 + 3);
+ setFrame(_state + 3);
}
default:
break;
}
- BF_GLOBALS._v4CECE[_field90 + 15] = _frame;
- if (_field90 == 0) {
+ BF_GLOBALS._breakerBoxStatusArr[_state + 15] = _frame;
+ if (_state == 0) {
if (_frame == 2)
- BF_GLOBALS._v4CECE[13] = 2;
+ BF_GLOBALS._breakerBoxStatusArr[13] = 2;
else
- BF_GLOBALS._v4CECE[13] = 4;
+ BF_GLOBALS._breakerBoxStatusArr[13] = 4;
}
return true;
case INV_HALF_YELLOW_CORD:
- if (BF_INVENTORY.getObjectScene(INV_YELLOW_CORD) == _field90 + 2) {
+ if (BF_INVENTORY.getObjectScene(INV_YELLOW_CORD) == _state + 2) {
SceneItem::display(910, 85, SET_WIDTH, 312,
SET_X, GLOBALS._sceneManager._scene->_sceneBounds.left + 4,
SET_Y, GLOBALS._sceneManager._scene->_sceneBounds.top + UI_INTERFACE_Y + 2,
@@ -1622,31 +1624,30 @@ bool Scene910::BlackPlug::startAction(CursorType action, Event &event) {
case INV_YELLOW_CORD:
if (BF_GLOBALS._v4CECC == 0) {
BF_GLOBALS._v4CECC = 1;
- BF_INVENTORY.setObjectScene(INV_YELLOW_CORD, _field90 + 2);
+ BF_INVENTORY.setObjectScene(INV_YELLOW_CORD, _state + 2);
BF_INVENTORY.setObjectScene(INV_HALF_YELLOW_CORD, 1);
} else if (BF_GLOBALS._v4CECC == 1) {
BF_GLOBALS._v4CECC = 2;
- BF_INVENTORY.setObjectScene(INV_HALF_YELLOW_CORD, _field90 + 2);
+ BF_INVENTORY.setObjectScene(INV_HALF_YELLOW_CORD, _state + 2);
scene->_yellowCord.setStrip(4);
scene->_yellowCord.setFrame(2);
scene->_yellowCord.setPosition(Common::Point(135, 93));
scene->_yellowCord.fixPriority(50);
}
- if (_frame - _field90 == 2)
- setFrame(_field90 + 4);
- else if (_frame - _field90 == 3)
- setFrame(_field90 + 5);
- BF_GLOBALS._v4CECE[15 + _field90] = _frame;
- BF_GLOBALS._v4CECE[_field90 + 15] = _frame;
- if (_field90 == 0) {
+ if (_frame - _state == 2)
+ setFrame(_state + 4);
+ else if (_frame - _state == 3)
+ setFrame(_state + 5);
+ BF_GLOBALS._breakerBoxStatusArr[_state + 15] = _frame;
+ if (_state == 0) {
if (_frame == 2)
- BF_GLOBALS._v4CECE[13] = 2;
+ BF_GLOBALS._breakerBoxStatusArr[13] = 2;
else
- BF_GLOBALS._v4CECE[13] = 4;
+ BF_GLOBALS._breakerBoxStatusArr[13] = 4;
}
return true;
case INV_HALF_BLACK_CORD:
- if (BF_INVENTORY.getObjectScene(INV_BLACK_CORD) == _field90 + 2) {
+ if (BF_INVENTORY.getObjectScene(INV_BLACK_CORD) == _state + 2) {
SceneItem::display(910, 85, SET_WIDTH, 312,
SET_X, GLOBALS._sceneManager._scene->_sceneBounds.left + 4,
SET_Y, GLOBALS._sceneManager._scene->_sceneBounds.top + UI_INTERFACE_Y + 2,
@@ -1657,7 +1658,7 @@ bool Scene910::BlackPlug::startAction(CursorType action, Event &event) {
//No break on purpose
case INV_BLACK_CORD:
if (BF_GLOBALS._v4CECA == 0) {
- if (_field90 == 1) {
+ if (_state == 1) {
if (!BF_GLOBALS.getFlag(fGotPointsForBlackCord)) {
T2_GLOBALS._uiElements.addScore(30);
BF_GLOBALS.setFlag(fGotPointsForBlackCord);
@@ -1669,10 +1670,10 @@ bool Scene910::BlackPlug::startAction(CursorType action, Event &event) {
}
}
BF_GLOBALS._v4CECA = 1;
- BF_INVENTORY.setObjectScene(INV_BLACK_CORD, _field90 + 2);
+ BF_INVENTORY.setObjectScene(INV_BLACK_CORD, _state + 2);
BF_INVENTORY.setObjectScene(INV_HALF_BLACK_CORD, 1);
} else if (BF_GLOBALS._v4CECA == 1) {
- if (_field90 == 1) {
+ if (_state == 1) {
if (!BF_GLOBALS.getFlag(fGotPointsForBlackCord)) {
T2_GLOBALS._uiElements.addScore(30);
BF_GLOBALS.setFlag(fGotPointsForBlackCord);
@@ -1684,31 +1685,30 @@ bool Scene910::BlackPlug::startAction(CursorType action, Event &event) {
}
}
BF_GLOBALS._v4CECA = 2;
- BF_INVENTORY.setObjectScene(INV_HALF_BLACK_CORD, _field90 + 2);
+ BF_INVENTORY.setObjectScene(INV_HALF_BLACK_CORD, _state + 2);
scene->_blackCord.setStrip(4);
scene->_blackCord.setFrame(1);
scene->_blackCord.setPosition(Common::Point(135, 93));
scene->_blackCord.fixPriority(50);
scene->_blackCord.show();
scene->_blackCord._field90 = 1;
- if (BF_GLOBALS._v4CECE[17] == 1) {
- if (BF_GLOBALS._v4CECE[14] == 2)
- scene->subE83E1();
+ if (BF_GLOBALS._breakerBoxStatusArr[17] == 1) {
+ if (BF_GLOBALS._breakerBoxStatusArr[14] == 2)
+ scene->closeHiddenDoor();
else
- scene->subE82BD();
+ scene->openHiddenDoor();
}
}
- if (_frame - _field90 == 2)
- setFrame(_field90 + 3);
- else if (_frame - _field90 == 4)
- setFrame(_field90 + 5);
- BF_GLOBALS._v4CECE[15 + _field90] = _frame;
- BF_GLOBALS._v4CECE[_field90 + 15] = _frame;
- if (_field90 == 0) {
+ if (_frame - _state == 2)
+ setFrame(_state + 3);
+ else if (_frame - _state == 4)
+ setFrame(_state + 5);
+ BF_GLOBALS._breakerBoxStatusArr[_state + 15] = _frame;
+ if (_state == 0) {
if (_frame == 2)
- BF_GLOBALS._v4CECE[13] = 2;
+ BF_GLOBALS._breakerBoxStatusArr[13] = 2;
else
- BF_GLOBALS._v4CECE[13] = 4;
+ BF_GLOBALS._breakerBoxStatusArr[13] = 4;
}
return true;
default:
@@ -1718,10 +1718,10 @@ bool Scene910::BlackPlug::startAction(CursorType action, Event &event) {
void Scene910::BlackPlug::init(int x, int y, int arg8, int8 argA) {
NamedObject::postInit();
- _field90 = arg8;
- _field92 = argA;
+ _state = arg8;
+ _mode = argA;
setVisage(910);
- if (_field90 == 0)
+ if (_state == 0)
setStrip(7);
else
setStrip(3);
@@ -1745,11 +1745,11 @@ void Scene910::GeneratorInset::postInit(SceneObjectList *OwnerList) {
_useLineNum = 87;
BF_GLOBALS._sceneItems.push_front(this);
- scene->_field2DD8 = 16;
- _blackPlug.init(142, 86, 1, BF_GLOBALS._v4CECE[16]);
+ scene->_breakerButtonCtr = 16;
+ _blackPlug.init(142, 86, 1, BF_GLOBALS._breakerBoxStatusArr[16]);
- scene->_field2DD8 = 17;
- _powerButton.init(BF_GLOBALS._v4CECE[17]);
+ scene->_breakerButtonCtr = 17;
+ _powerButton.init(BF_GLOBALS._breakerBoxStatusArr[17]);
}
void Scene910::GeneratorInset::remove() {
@@ -1770,30 +1770,30 @@ bool Scene910::PowerButton::startAction(CursorType action, Event &event) {
if (_frame == 4) {
scene->_sound1.play(100);
scene->_sound1.holdAt(1);
- if (!BF_GLOBALS.getFlag(77)) {
+ if (!BF_GLOBALS.getFlag(fGotPointsForFuseBoxPlug)) {
T2_GLOBALS._uiElements.addScore(30);
- BF_GLOBALS.setFlag(77);
+ BF_GLOBALS.setFlag(fGotPointsForFuseBoxPlug);
}
setFrame(5);
_object32.setFrame(7);
if (BF_GLOBALS._v4CECA == 2) {
- if (BF_GLOBALS._v4CECE[14] == 2)
- scene->subE83E1();
+ if (BF_GLOBALS._breakerBoxStatusArr[14] == 2)
+ scene->closeHiddenDoor();
else
- scene->subE82BD();
+ scene->openHiddenDoor();
}
} else {
scene->_sound1.release();
- if (BF_GLOBALS._bookmark == 21) {
- if (!BF_GLOBALS.getFlag(82)) {
+ if (BF_GLOBALS._bookmark == bEndDayThree) {
+ if (!BF_GLOBALS.getFlag(fGotPointsForLightsOff)) {
T2_GLOBALS._uiElements.addScore(30);
- BF_GLOBALS.setFlag(82);
+ BF_GLOBALS.setFlag(fGotPointsForLightsOff);
}
}
setFrame(4);
_object32.setFrame(6);
}
- BF_GLOBALS._v4CECE[17] = (_frame + 252) % 256;
+ BF_GLOBALS._breakerBoxStatusArr[17] = (_frame + 252) % 256;
return true;
} else
return NamedObject::startAction(action, event);
@@ -1855,7 +1855,7 @@ bool Scene910::Item2::startAction(CursorType action, Event &event) {
if (action == 59) {
BF_GLOBALS._player.disableControl();
scene->_destPos = Common::Point(151, 186);
- scene->_field2DDA = 5;
+ scene->_sceneSubMode = 5;
scene->_sceneMode = 9123;
if (BF_GLOBALS._player._visage == 1911)
scene->setAction(&scene->_sequenceManager1, scene, 9123, &BF_GLOBALS._player, NULL);
@@ -1880,7 +1880,7 @@ bool Scene910::Item3::startAction(CursorType action, Event &event) {
}
bool Scene910::Item9::startAction(CursorType action, Event &event) {
- if (BF_GLOBALS._v4CEE0 == 0)
+ if (BF_GLOBALS._hiddenDoorStatus == 0)
return NamedHotspot::startAction(action, event);
else
return false;
@@ -1907,13 +1907,13 @@ bool Scene910::Item15::startAction(CursorType action, Event &event) {
bool Scene910::Item16::startAction(CursorType action, Event &event) {
Scene910 *scene = (Scene910 *)BF_GLOBALS._sceneManager._scene;
- if ((BF_GLOBALS._v4CEE0 == 0) || (BF_GLOBALS._v4CEE2 != 0))
+ if ((BF_GLOBALS._hiddenDoorStatus == 0) || (BF_GLOBALS._v4CEE2 != 0))
return false;
if (BF_GLOBALS._player._visage == 1911) {
BF_GLOBALS._player.disableControl();
scene->_destPos = Common::Point(292, 100);
- scene->_field2DDA = 0;
+ scene->_sceneSubMode = 0;
scene->_sceneMode = 9123;
scene->setAction(&scene->_sequenceManager1, scene, 9123, &BF_GLOBALS._player, NULL);
} else {
@@ -1940,8 +1940,8 @@ void Scene910::remove() {
void Scene910::synchronize(Serializer &s) {
PalettedScene::synchronize(s);
- s.syncAsSint16LE(_field2DDA);
- s.syncAsSint16LE(_field2DD8);
+ s.syncAsSint16LE(_sceneSubMode);
+ s.syncAsSint16LE(_breakerButtonCtr);
s.syncAsSint16LE(_field2DE0);
s.syncAsSint16LE(_field2DE2);
s.syncAsSint16LE(_field2DE4);
@@ -1979,7 +1979,7 @@ void Scene910::postInit(SceneObjectList *OwnerList) {
_vent.postInit();
_vent.setVisage(910);
- if ((BF_GLOBALS._v4CECE[3] == 2) && (BF_GLOBALS._v4CECE[4] == 2)) {
+ if ((BF_GLOBALS._breakerBoxStatusArr[3] == 2) && (BF_GLOBALS._breakerBoxStatusArr[4] == 2)) {
_action1.setActionIndex(4);
} else {
_vent.animate(ANIM_MODE_2, NULL);
@@ -2019,10 +2019,10 @@ void Scene910::postInit(SceneObjectList *OwnerList) {
if (BF_GLOBALS._v4CEE2 == 0)
_item16.setDetails(Rect(265, 18, 319, 102), 910, -1, -1, -1, 1, NULL);
- _breakerBox.setDetails(910, 6, -1, -1, 1, NULL);
+ _breakerBox.setDetails(910, 6, -1, -1, 1, (SceneItem *)NULL);
_item15.setDetails(Rect(0, 0, 320, 170), 910, 0, 1, 2, 1, NULL);
- _yellowCord.setDetails(910, 52, 53, -1, 1, NULL);
- _blackCord.setDetails(910, 54, 55, -1, 1, NULL);
+ _yellowCord.setDetails(910, 52, 53, -1, 1, (SceneItem *)NULL);
+ _blackCord.setDetails(910, 54, 55, -1, 1, (SceneItem *)NULL);
_item2.setDetails(3, 910, 22, -1, 24, 1);
_item4.setDetails(1, 910, 16, 17, 18, 1);
_item8.setDetails(4, 910, 25, 26, 27, 1);
@@ -2032,7 +2032,7 @@ void Scene910::postInit(SceneObjectList *OwnerList) {
_item9.setDetails(Rect(266, 39, 274, 70), 910, 43, 44, 45, 1, NULL);
_item10.setDetails(Rect(276, 27, 288, 83), 910, 46, 47, 48, 1, NULL);
_item11.setDetails(Rect(295, 42, 312, 87), 910, 49, 50, 51, 1, NULL);
- _fakeWall.setDetails(910, 28, -1, 30, 1, NULL);
+ _fakeWall.setDetails(910, 28, -1, 30, 1, (SceneItem *)NULL);
_item3.setDetails(7, 910, 59, 60, 61, 1);
_item5.setDetails(2, 910, 19, 20, 21, 1);
_backWall.setDetails(6, 910, 28, 29, 30, 1);
@@ -2041,7 +2041,7 @@ void Scene910::postInit(SceneObjectList *OwnerList) {
if (BF_GLOBALS._dayNumber == 0) {
BF_GLOBALS._dayNumber = 5;
BF_GLOBALS._sceneManager._previousScene = 900;
- BF_GLOBALS.setFlag(7);
+ BF_GLOBALS.setFlag(fWithLyle);
}
if ( (BF_GLOBALS._sceneManager._previousScene == 910)
@@ -2055,11 +2055,11 @@ void Scene910::postInit(SceneObjectList *OwnerList) {
_field2DE0 = 0;
_field2DE2 = 0;
_field2DE4 = 0;
- BF_GLOBALS.clearFlag(34);
+ BF_GLOBALS.clearFlag(fCanDrawGun);
_lyle._position.x = 0;
if ((BF_GLOBALS._dayNumber == 5) && (BF_GLOBALS._sceneManager._previousScene == 900)){
- BF_GLOBALS.setFlag(34);
+ BF_GLOBALS.setFlag(fCanDrawGun);
BF_GLOBALS._v4CEC8 = 0;
BF_GLOBALS._player.setVisage(129);
@@ -2071,21 +2071,21 @@ void Scene910::postInit(SceneObjectList *OwnerList) {
_lyle._field90 = 0;
_lyle.setDetails(910, 69, 70, 71, 5, &_item4);
- BF_GLOBALS._v4CECE[0] = 3;
- BF_GLOBALS._v4CECE[12] = 2;
- BF_GLOBALS._v4CECE[13] = 4;
- BF_GLOBALS._v4CECE[14] = 3;
- BF_GLOBALS._v4CECE[15] = 3;
- BF_GLOBALS._v4CECE[16] = 4;
- BF_GLOBALS._v4CECE[17] = 1;
+ BF_GLOBALS._breakerBoxStatusArr[0] = 3;
+ BF_GLOBALS._breakerBoxStatusArr[12] = 2;
+ BF_GLOBALS._breakerBoxStatusArr[13] = 4;
+ BF_GLOBALS._breakerBoxStatusArr[14] = 3;
+ BF_GLOBALS._breakerBoxStatusArr[15] = 3;
+ BF_GLOBALS._breakerBoxStatusArr[16] = 4;
+ BF_GLOBALS._breakerBoxStatusArr[17] = 1;
BF_GLOBALS._v4CECA = 2;
- BF_GLOBALS._v4CEE0 = 1;
+ BF_GLOBALS._hiddenDoorStatus = 1;
_yellowCord.setPosition(Common::Point(291, -30));
BF_GLOBALS._v4CECC = 0;
}
if (BF_GLOBALS._sceneManager._previousScene == 920) {
- BF_GLOBALS.setFlag(34);
+ BF_GLOBALS.setFlag(fCanDrawGun);
BF_GLOBALS._player.setPosition(Common::Point(276, 119));
BF_GLOBALS._player.setStrip(6);
if (BF_GLOBALS._v4CECC == 0)
@@ -2116,7 +2116,7 @@ void Scene910::postInit(SceneObjectList *OwnerList) {
}
BF_GLOBALS._player.enableControl();
} else if (BF_GLOBALS._sceneManager._previousScene == 935) {
- BF_GLOBALS.setFlag(34);
+ BF_GLOBALS.setFlag(fCanDrawGun);
BF_GLOBALS._v4CEC8 = 0;
_lyle.postInit();
_lyle.setVisage(916);
@@ -2125,11 +2125,11 @@ void Scene910::postInit(SceneObjectList *OwnerList) {
_lyle.setFrame(3);
_lyle._field90 = 1;
_lyle.setDetails(910, 69, 70 ,71 , 5, &_item4);
-
- BF_GLOBALS._walkRegions.proc1(15);
- BF_GLOBALS._walkRegions.proc1(16);
- BF_GLOBALS._walkRegions.proc1(14);
- BF_GLOBALS._walkRegions.proc1(10);
+
+ BF_GLOBALS._walkRegions.disableRegion(15);
+ BF_GLOBALS._walkRegions.disableRegion(16);
+ BF_GLOBALS._walkRegions.disableRegion(14);
+ BF_GLOBALS._walkRegions.disableRegion(10);
if (BF_GLOBALS.getFlag(gunDrawn)) {
BF_GLOBALS._player.setVisage(1911);
BF_GLOBALS._player.animate(ANIM_MODE_NONE, 0, NULL);
@@ -2153,13 +2153,13 @@ void Scene910::postInit(SceneObjectList *OwnerList) {
else
add2Faders((const byte *)&unk_50E90, 2, 911, this);
} else {
- BF_GLOBALS.clearFlag(8);
+ BF_GLOBALS.clearFlag(gunDrawn);
BF_GLOBALS._player.disableControl();
}
if ((BF_GLOBALS._dayNumber == 5) && (BF_GLOBALS._v4CEE2 == 0)){
- _object7.postInit();
- _object7.setAction(&_action2);
+ _shadow.postInit();
+ _shadow.setAction(&_action2);
}
if (BF_INVENTORY.getObjectScene(INV_YELLOW_CORD) == 1)
@@ -2197,22 +2197,22 @@ void Scene910::postInit(SceneObjectList *OwnerList) {
if (BF_GLOBALS._v4CEC8 == 0)
_object5.hide();
- if (BF_GLOBALS._v4CEE0 == 0) {
+ if (BF_GLOBALS._hiddenDoorStatus == 0) {
_object5.setFrame(1);
_fakeWall.setPosition(Common::Point(292, 107));
if (BF_GLOBALS._v4CECC != 2)
_yellowCord.setPosition(Common::Point(288, 57));
- BF_GLOBALS._walkRegions.proc1(10);
+ BF_GLOBALS._walkRegions.disableRegion(10);
} else {
_object5.setFrame(6);
_fakeWall.setPosition(Common::Point(295, 20));
_fakeWall.hide();
if (BF_GLOBALS._v4CECC != 2)
_yellowCord.setPosition(Common::Point(291, -30));
- BF_GLOBALS._walkRegions.proc1(10);
+ BF_GLOBALS._walkRegions.enableRegion(10);
}
- if (BF_GLOBALS._v4CECE[17] != 0) {
+ if (BF_GLOBALS._breakerBoxStatusArr[17] != 0) {
_sound1.play(100);
_sound1.holdAt(1);
}
@@ -2315,8 +2315,8 @@ void Scene910::signal() {
_sceneMode = 10;
addFader((const byte *)&black, 2, this);
BF_GLOBALS._v4CEE2 = 1;
- BF_GLOBALS._walkRegions.proc1(16);
- BF_GLOBALS._walkRegions.proc1(14);
+ BF_GLOBALS._walkRegions.disableRegion(16);
+ BF_GLOBALS._walkRegions.disableRegion(14);
BF_GLOBALS._sceneItems.remove(&_item16);
break;
case 17:
@@ -2375,11 +2375,11 @@ void Scene910::signal() {
break;
case 9100:
if (BF_GLOBALS._dayNumber == 5)
- BF_GLOBALS._walkRegions.proc1(1);
+ BF_GLOBALS._walkRegions.disableRegion(1);
BF_GLOBALS._player.enableControl();
break;
case 9101:
- if ((BF_GLOBALS._v4CEE0 == 0) && (BF_GLOBALS._v4CEC8 != 0) && (BF_GLOBALS._v4CECE[17] == 0) && (BF_INVENTORY.getObjectScene(INV_YELLOW_CORD) == 910) && (BF_INVENTORY.getObjectScene(INV_BLACK_CORD) == 910))
+ if ((BF_GLOBALS._hiddenDoorStatus == 0) && (BF_GLOBALS._v4CEC8 != 0) && (BF_GLOBALS._breakerBoxStatusArr[17] == 0) && (BF_INVENTORY.getObjectScene(INV_YELLOW_CORD) == 910) && (BF_INVENTORY.getObjectScene(INV_BLACK_CORD) == 910))
BF_GLOBALS.clearFlag(fGotPointsForSearchingDA);
else
BF_GLOBALS.setFlag(fGotPointsForSearchingDA);
@@ -2387,7 +2387,7 @@ void Scene910::signal() {
BF_GLOBALS._sceneManager.changeScene(900);
break;
case 9102:
- if ((BF_GLOBALS._v4CECE[13] < 4) && (_breakerBox._frame == 1))
+ if ((BF_GLOBALS._breakerBoxStatusArr[13] < 4) && (_breakerBox._frame == 1))
_breakerBox.animate(ANIM_MODE_5, NULL);
BF_GLOBALS._player.enableControl();
@@ -2457,7 +2457,7 @@ void Scene910::signal() {
_nico.postInit();
_nico.setDetails(910, 63, 64, 65, 5, &_item4);
BF_GLOBALS._v4CEE6 = 0;
- _object7.postInit();
+ _shadow.postInit();
_action2.remove();
_sceneMode = 9116;
setAction(&_sequenceManager1, this, 9116, &_nico, NULL);
@@ -2490,7 +2490,7 @@ void Scene910::signal() {
BF_GLOBALS._player.enableControl();
break;
case 9120:
- BF_GLOBALS._walkRegions.proc1(7);
+ BF_GLOBALS._walkRegions.disableRegion(7);
BF_GLOBALS._player.enableControl();
break;
case 9121:
@@ -2505,7 +2505,7 @@ void Scene910::signal() {
break;
case 9123:
BF_GLOBALS.clearFlag(gunDrawn);
- switch (_field2DDA - 1) {
+ switch (_sceneSubMode - 1) {
case 0:
_sceneMode = 9102;
setAction(&_sequenceManager1, this, 9102, &BF_GLOBALS._player, NULL);
@@ -2600,7 +2600,7 @@ void Scene910::signal() {
BF_GLOBALS.setFlag(fBackupAt340);
BF_GLOBALS._v4CEE2 = 4;
_stuart.postInit();
- _nico.setDetails(910, 72, 73, 74, 3, NULL);
+ _nico.setDetails(910, 72, 73, 74, 3, (SceneItem *)NULL);
_stuart.setDetails(910, 66, 67, 68, 5, &_nico);
BF_GLOBALS._v4CEE8 = 0;
_sceneMode = 9121;
@@ -2622,9 +2622,9 @@ void Scene910::signal() {
break;
case 9130:
_lyle.setAction(&_sequenceManager2, NULL, 9133, &_lyle, NULL);
- BF_GLOBALS._v4CECE[14] = 3;
- subE82BD();
- BF_GLOBALS._walkRegions.proc1(15);
+ BF_GLOBALS._breakerBoxStatusArr[14] = 3;
+ openHiddenDoor();
+ BF_GLOBALS._walkRegions.disableRegion(15);
break;
case 9132:
BF_GLOBALS._player.enableControl();
@@ -2644,7 +2644,7 @@ void Scene910::signal() {
BF_GLOBALS.setFlag(fGotPointsForCuffingNico);
}
_lyle.setAction(&_sequenceManager2, NULL, 9131, &_lyle, NULL);
- BF_GLOBALS._walkRegions.proc2(16);
+ BF_GLOBALS._walkRegions.enableRegion(16);
if (BF_GLOBALS._v4CEE2 == 4)
BF_INVENTORY.setObjectScene(INV_YELLOW_CORD, 0);
else
@@ -2655,7 +2655,7 @@ void Scene910::signal() {
setAction(&_sequenceManager1, this, 9139, &_forbes, &BF_GLOBALS._player, NULL);
break;
case 9139:
- BF_GLOBALS._walkRegions.proc1(4);
+ BF_GLOBALS._walkRegions.disableRegion(4);
_field2DE0 = 1;
BF_GLOBALS._player.enableControl();
break;
@@ -2730,7 +2730,7 @@ void Scene910::process(Event &event) {
if (_item17._bounds.contains(event.mousePos)) {
GfxSurface surface = _cursorVisage.getFrame(EXITFRAME_SW);
BF_GLOBALS._events.setCursor(surface);
- } else if ((BF_GLOBALS._v4CEE0 == 0) || (BF_GLOBALS._v4CEE2 != 0)) {
+ } else if ((BF_GLOBALS._hiddenDoorStatus == 0) || (BF_GLOBALS._v4CEE2 != 0)) {
CursorType cursorId = BF_GLOBALS._events.getCursor();
BF_GLOBALS._events.setCursor(cursorId);
} else if (!_item16._bounds.contains(event.mousePos)) {
@@ -2781,7 +2781,7 @@ void Scene910::process(Event &event) {
if (BF_GLOBALS._player._visage == 1911) {
BF_GLOBALS._player.disableControl();
_destPos = event.mousePos;
- _field2DDA = 0;
+ _sceneSubMode = 0;
_sceneMode = 9123;
setAction(&_sequenceManager1, this, 9123, &BF_GLOBALS._player, NULL);
} else {
@@ -2792,7 +2792,7 @@ void Scene910::process(Event &event) {
} else if (BF_GLOBALS._player._visage == 1911) {
BF_GLOBALS._player.disableControl();
_destPos = event.mousePos;
- _field2DDA = 0;
+ _sceneSubMode = 0;
_sceneMode = 9123;
setAction(&_sequenceManager1, this, 9123, &BF_GLOBALS._player, NULL);
}
@@ -2813,17 +2813,17 @@ void Scene910::dispatch() {
setAction(&_sequenceManager1, this, 9101, &BF_GLOBALS._player, NULL);
} else {
_sceneMode = 9146;
- if (BF_GLOBALS._v4CEE0 == 0)
+ if (BF_GLOBALS._hiddenDoorStatus == 0)
setAction(&_sequenceManager1, this, 9146, &BF_GLOBALS._player, NULL);
else
setAction(&_sequenceManager1, this, 9145, &BF_GLOBALS._player, NULL);
}
}
- if ((BF_GLOBALS._player._position.x > 265) && (BF_GLOBALS._player._position.y < 102) && (BF_GLOBALS._v4CEE0 != 0) && (_sceneMode != 9143)) {
+ if ((BF_GLOBALS._player._position.x > 265) && (BF_GLOBALS._player._position.y < 102) && (BF_GLOBALS._hiddenDoorStatus != 0) && (_sceneMode != 9143)) {
BF_GLOBALS._player.disableControl();
if (BF_GLOBALS.getFlag(gunDrawn)) {
- _field2DDA = 3;
+ _sceneSubMode = 3;
_sceneMode = 9123;
setAction(&_sequenceManager1, this, 9123, &BF_GLOBALS._player, NULL);
} else if (BF_GLOBALS._v4CEE2 == 0) {
@@ -2840,9 +2840,9 @@ void Scene910::dispatch() {
}
}
- if ((BF_GLOBALS._dayNumber == 5) && (BF_GLOBALS._player._position.x > 250) && (_sceneMode != 9135) && (_sceneMode != 11) && (BF_GLOBALS._v4CEE0 != 0) && (BF_GLOBALS._v4CEE2 == 0)) {
+ if ((BF_GLOBALS._dayNumber == 5) && (BF_GLOBALS._player._position.x > 250) && (_sceneMode != 9135) && (_sceneMode != 11) && (BF_GLOBALS._hiddenDoorStatus != 0) && (BF_GLOBALS._v4CEE2 == 0)) {
BF_GLOBALS._player.disableControl();
- _object7.remove();
+ _shadow.remove();
_nico.remove();
_nico.postInit();
_nico.setDetails(910, 63, 64, 65, 5, &_item4);
@@ -2853,7 +2853,7 @@ void Scene910::dispatch() {
}
void Scene910::checkGun() {
- if ((BF_GLOBALS._dayNumber == 5) && (BF_GLOBALS._v4CEE2 == 0) && (BF_GLOBALS._v4CEE0 != 0))
+ if ((BF_GLOBALS._dayNumber == 5) && (BF_GLOBALS._v4CEE2 == 0) && (BF_GLOBALS._hiddenDoorStatus != 0))
SceneItem::display(910, 70, SET_WIDTH, 312,
SET_X, GLOBALS._sceneManager._scene->_sceneBounds.left + 4,
SET_Y, GLOBALS._sceneManager._scene->_sceneBounds.top + UI_INTERFACE_Y + 2,
@@ -2863,17 +2863,17 @@ void Scene910::checkGun() {
SceneExt::checkGun();
}
-void Scene910::subE82BD() {
- if (BF_GLOBALS._v4CEE0 != 0)
+void Scene910::openHiddenDoor() {
+ if (BF_GLOBALS._hiddenDoorStatus != 0)
return;
if (! BF_GLOBALS.getFlag(fGotPointsForLightsOn)) {
T2_GLOBALS._uiElements.addScore(50);
BF_GLOBALS.setFlag(fGotPointsForLightsOn);
}
- BF_GLOBALS._v4CEE0 = 1;
+ BF_GLOBALS._hiddenDoorStatus = 1;
BF_GLOBALS._player.disableControl();
- BF_GLOBALS._walkRegions.proc2(10);
+ BF_GLOBALS._walkRegions.enableRegion(10);
_sceneMode = 9114;
_sound2.play(42);
if ((BF_GLOBALS._v4CECC == 0) && (BF_INVENTORY.getObjectScene(INV_YELLOW_CORD) == 910))
@@ -2882,19 +2882,19 @@ void Scene910::subE82BD() {
setAction(&_sequenceManager1, this, 9114, &_fakeWall, &_object5, NULL);
}
-void Scene910::subE83E1() {
- if (BF_GLOBALS._v4CEE0 != 0) {
+void Scene910::closeHiddenDoor() {
+ if (BF_GLOBALS._hiddenDoorStatus != 0) {
_fakeWall.show();
- if ((BF_GLOBALS._bookmark == 21) && (!BF_GLOBALS.getFlag(80))) {
+ if ((BF_GLOBALS._bookmark == bEndDayThree) && (!BF_GLOBALS.getFlag(fGotPointsForOpeningDoor))) {
T2_GLOBALS._uiElements.addScore(30);
- BF_GLOBALS.setFlag(80);
+ BF_GLOBALS.setFlag(fGotPointsForOpeningDoor);
}
- BF_GLOBALS._v4CEE0 = 0;
- BF_GLOBALS._walkRegions.proc1(10);
+ BF_GLOBALS._hiddenDoorStatus = 0;
+ BF_GLOBALS._walkRegions.disableRegion(10);
BF_GLOBALS._player.disableControl();
_sceneMode = 9115;
_sound2.play(42);
- if ((BF_GLOBALS._v4CECC == 0) && (BF_INVENTORY.getObjectScene(57) == 910))
+ if ((BF_GLOBALS._v4CECC == 0) && (BF_INVENTORY.getObjectScene(INV_YELLOW_CORD) == 910))
setAction(&_sequenceManager1, this, 9128, &_fakeWall, &_yellowCord, &_object5, NULL);
else
setAction(&_sequenceManager1, this, 9115, &_fakeWall, &_object5, NULL);
@@ -2910,7 +2910,7 @@ void Scene910::subE83E1() {
BF_GLOBALS._player.disableControl();
_sceneMode = 9120;
BF_GLOBALS._player.setAction(&_sequenceManager2, NULL, 9120, &BF_GLOBALS._player, &_lyle, NULL);
- BF_GLOBALS._walkRegions.proc2(1);
+ BF_GLOBALS._walkRegions.enableRegion(1);
}
}
@@ -2941,7 +2941,7 @@ bool Scene920::Item1::startAction(CursorType action, Event &event) {
BF_GLOBALS._player.disableControl();
if (BF_GLOBALS.getFlag(fCrateOpen)) {
if (BF_GLOBALS._player._visage == 921) {
- if ((BF_INVENTORY.getObjectScene(15) != 1) && (BF_GLOBALS.getFlag(fSawGuns))) {
+ if ((BF_INVENTORY.getObjectScene(INV_AUTO_RIFLE) != 1) && (BF_GLOBALS.getFlag(fSawGuns))) {
scene->_sceneMode = 9207;
scene->setAction(&scene->_sequenceManager1, scene, 9207, &BF_GLOBALS._player, NULL);
} else {
@@ -3055,7 +3055,7 @@ void Scene920::signal() {
case 9207:
BF_GLOBALS._player.enableControl();
T2_GLOBALS._uiElements.addScore(30);
- BF_INVENTORY.setObjectScene(15, 1);
+ BF_INVENTORY.setObjectScene(INV_AUTO_RIFLE, 1);
BF_GLOBALS._bookmark = bEndDayThree;
break;
default:
@@ -3107,7 +3107,7 @@ bool Scene930::Object1::startAction(CursorType action, Event &event) {
Scene930 *scene = (Scene930 *)BF_GLOBALS._sceneManager._scene;
bool result;
- if ((action == CURSOR_USE) && (!BF_GLOBALS.getFlag(93))) {
+ if ((action == CURSOR_USE) && (!BF_GLOBALS.getFlag(fGotPointsForFBI))) {
scene->setAction(&scene->_action2);
result = true;
} else
@@ -3117,6 +3117,7 @@ bool Scene930::Object1::startAction(CursorType action, Event &event) {
}
bool Scene930::Object2::startAction(CursorType action, Event &event) {
+// Small box Inset
Scene930 *scene = (Scene930 *)BF_GLOBALS._sceneManager._scene;
if (action != CURSOR_USE)
@@ -3124,8 +3125,8 @@ bool Scene930::Object2::startAction(CursorType action, Event &event) {
NamedObject::startAction(action, event);
T2_GLOBALS._uiElements.addScore(30);
- BF_INVENTORY.setObjectScene(54, 1);
- BF_GLOBALS.setFlag(93);
+ BF_INVENTORY.setObjectScene(INV_9MM_BULLETS, 1);
+ BF_GLOBALS.setFlag(fGotPointsForFBI);
remove();
scene->_box.remove();
return true;
@@ -3138,13 +3139,13 @@ bool Scene930::Object3::startAction(CursorType action, Event &event) {
if (action != CURSOR_USE)
return NamedObject::startAction(action, event);
- if (scene->_v141C == 0)
+ if (!scene->_bootInsetDisplayed)
scene->setAction(&scene->_action1);
return true;
}
bool Scene930::Object4::startAction(CursorType action, Event &event) {
-// Boot window
+// Boot inset
Scene930 *scene = (Scene930 *)BF_GLOBALS._sceneManager._scene;
switch (action) {
@@ -3167,7 +3168,7 @@ bool Scene930::Object4::startAction(CursorType action, Event &event) {
if (BF_GLOBALS._bookmark >= bFlashBackTwo) {
_lookLineNum = 71;
NamedObject::startAction(action, event);
- scene->subF3D6F();
+ scene->ShowSoleInset();
remove();
} else
NamedObject::startAction(action, event);
@@ -3179,9 +3180,10 @@ bool Scene930::Object4::startAction(CursorType action, Event &event) {
}
void Scene930::Object4::remove() {
+// Boots inset
Scene930 *scene = (Scene930 *)BF_GLOBALS._sceneManager._scene;
- if (scene->_v141C && !BF_GLOBALS._sceneObjects->contains(&scene->_object5)) {
+ if (scene->_bootInsetDisplayed && !BF_GLOBALS._sceneObjects->contains(&scene->_soleInset)) {
scene->_boots.setAction(&scene->_action3);
}
@@ -3189,22 +3191,23 @@ void Scene930::Object4::remove() {
}
bool Scene930::Object5::startAction(CursorType action, Event &event) {
+// Boots sole inset
Scene930 *scene = (Scene930 *)BF_GLOBALS._sceneManager._scene;
switch (action) {
case CURSOR_WALK:
return true;
case CURSOR_USE:
- if (BF_INVENTORY.getObjectScene(55) == 1)
+ if (BF_INVENTORY.getObjectScene(INV_SCHEDULE) == 1)
return NamedObject::startAction(action, event);
- if (scene->_v141A == 0) {
+ if (!scene->_soleOpened) {
animate(ANIM_MODE_4, getFrameCount() - 1, 1, NULL);
- scene->_v141A = 1;
+ scene->_soleOpened = 1;
_lookLineNum = 76;
_useLineNum = 78;
} else {
T2_GLOBALS._uiElements.addScore(50);
- BF_INVENTORY.setObjectScene(55, 1);
+ BF_INVENTORY.setObjectScene(INV_SCHEDULE, 1);
setFrame2(getFrameCount());
_lookLineNum = 92;
_useLineNum = -1;
@@ -3244,7 +3247,7 @@ void Scene930::Action1::signal() {
case 0:
setDelay(10);
BF_GLOBALS._player.disableControl();
- scene->_v141C = 1;
+ scene->_bootInsetDisplayed = 1;
break;
case 1: {
Common::Point pt(50, 142);
@@ -3268,10 +3271,10 @@ void Scene930::Action1::signal() {
BF_GLOBALS._player.animate(ANIM_MODE_5, this);
break;
case 5:
- scene->showBootWindow();
- if (!BF_GLOBALS.getFlag(72)) {
+ scene->showBootInset();
+ if (!BF_GLOBALS.getFlag(fGotPointsForCPU)) {
T2_GLOBALS._uiElements.addScore(30);
- BF_GLOBALS.setFlag(72);
+ BF_GLOBALS.setFlag(fGotPointsForCPU);
}
SceneItem::display(0, 312);
BF_GLOBALS._player.enableControl();
@@ -3304,7 +3307,7 @@ void Scene930::Action2::signal() {
SET_Y, GLOBALS._sceneManager._scene->_sceneBounds.top + UI_INTERFACE_Y + 2,
SET_FONT, 4, SET_BG_COLOR, 1, SET_FG_COLOR, 19, SET_EXT_BGCOLOR, 9,
SET_EXT_FGCOLOR, 13, LIST_END);
- scene->subF3C07();
+ scene->ShowBoxInset();
BF_GLOBALS._player.enableControl();
remove();
break;
@@ -3330,7 +3333,7 @@ void Scene930::Action3::signal() {
BF_GLOBALS._player.setVisage(368);
BF_GLOBALS._player.setStrip(6);
BF_GLOBALS._player.setFrame(1);
- scene->_v141C = 0;
+ scene->_bootInsetDisplayed = 0;
remove();
BF_GLOBALS._player.animate(ANIM_MODE_1, NULL);
BF_GLOBALS._player.enableControl();
@@ -3348,21 +3351,21 @@ void Scene930::postInit(SceneObjectList *OwnerList) {
if (BF_GLOBALS._dayNumber == 0)
BF_GLOBALS._dayNumber = 1;
setZoomPercents(83, 75, 140, 100);
- _v141A = 0;
- _v141C = 0;
- if (BF_INVENTORY.getObjectScene(54) != 1) {
+ _soleOpened = 0;
+ _bootInsetDisplayed = 0;
+ if (BF_INVENTORY.getObjectScene(INV_9MM_BULLETS) != 1) {
_box.postInit();
_box.setVisage(930);
_box.setStrip(1);
_box.setPosition(Common::Point(223, 21));
- _box.setDetails(930, 66, 67, 68, 1, NULL);
+ _box.setDetails(930, 66, 67, 68, 1, (SceneItem *)NULL);
}
_boots.postInit();
_boots.setVisage(930);
_boots.setStrip(2);
_boots.setPosition(Common::Point(9, 161));
_boots.fixPriority(120);
- _boots.setDetails(930, 62, 63, 64, 1, NULL);
+ _boots.setDetails(930, 62, 63, 64, 1, (SceneItem *)NULL);
BF_GLOBALS._player.postInit();
BF_GLOBALS._player.setVisage(368);
@@ -3372,6 +3375,7 @@ void Scene930::postInit(SceneObjectList *OwnerList) {
BF_GLOBALS._player.fixPriority(80);
BF_GLOBALS._player.changeZoom(-1);
BF_GLOBALS._player.enableControl();
+ BF_GLOBALS._events.setCursor(CURSOR_WALK);
_item1.setDetails( 1, 930, 0, 1, 2, 1);
_item2.setDetails( 2, 930, 4, 5, 6, 1);
@@ -3400,7 +3404,8 @@ void Scene930::postInit(SceneObjectList *OwnerList) {
_sceneMode = 0;
setAction(&_sequenceManager1, this, 9300, &BF_GLOBALS._player, NULL);
} else {
- _v141C = 1;
+ // After flashback
+ _bootInsetDisplayed = 1;
BF_GLOBALS._player.animate(ANIM_MODE_NONE);
BF_GLOBALS._player.setPosition(Common::Point(50, 142));
BF_GLOBALS._player.setVisage(931);
@@ -3410,7 +3415,7 @@ void Scene930::postInit(SceneObjectList *OwnerList) {
BF_GLOBALS._player.enableControl();
BF_GLOBALS._player.changeZoom(110);
_boots.setFrame(2);
- showBootWindow();
+ showBootInset();
}
}
@@ -3448,49 +3453,49 @@ void Scene930::dispatch() {
SceneExt::dispatch();
}
-void Scene930::showBootWindow() {
- _bootsWindow.postInit();
- _bootsWindow.setVisage(930);
- _bootsWindow.setStrip(3);
- _bootsWindow.setFrame2(1);
- _bootsWindow.fixPriority(260);
- _bootsWindow.setPosition(Common::Point(147, 128));
- _bootsWindow.setDetails(930, 69, 70, 93);
+void Scene930::showBootInset() {
+ _bootsInset.postInit();
+ _bootsInset.setVisage(930);
+ _bootsInset.setStrip(3);
+ _bootsInset.setFrame2(1);
+ _bootsInset.fixPriority(260);
+ _bootsInset.setPosition(Common::Point(147, 128));
+ _bootsInset.setDetails(930, 69, 70, 93);
}
-void Scene930::subF3C07() {
- _object2.postInit();
- _object2.setVisage(930);
- _object2.setStrip(1);
- _object2.setFrame2(2);
- _object2.fixPriority(260);
- _object2.setPosition(Common::Point(147, 128));
- _object2.setDetails(930, 73, 74, 75);
+void Scene930::ShowBoxInset() {
+ _boxInset.postInit();
+ _boxInset.setVisage(930);
+ _boxInset.setStrip(1);
+ _boxInset.setFrame2(2);
+ _boxInset.fixPriority(260);
+ _boxInset.setPosition(Common::Point(147, 128));
+ _boxInset.setDetails(930, 73, 74, 75);
}
-void Scene930::subF3D6F() {
- _object5.postInit();
- _object5.setVisage(930);
- _object5.setStrip(3);
+void Scene930::ShowSoleInset() {
+ _soleInset.postInit();
+ _soleInset.setVisage(930);
+ _soleInset.setStrip(3);
if (BF_INVENTORY.getObjectScene(INV_SCHEDULE) == 1) {
- _object5.setFrame(_object5.getFrameCount());
- _object5.setDetails(930, 92, 77, -1);
- } else if (_v141A == 0) {
- _object5.setFrame(2);
- _object5.setDetails(930, 93, 77, -1);
+ _soleInset.setFrame(_soleInset.getFrameCount());
+ _soleInset.setDetails(930, 92, 77, -1);
+ } else if (!_soleOpened) {
+ _soleInset.setFrame(2);
+ _soleInset.setDetails(930, 93, 77, -1);
} else {
- _object5.setFrame(_object5.getFrameCount());
- _object5.setDetails(930, 76, 77, 78);
+ _soleInset.setFrame(_soleInset.getFrameCount());
+ _soleInset.setDetails(930, 76, 77, 78);
}
- _object5.fixPriority(260);
- _object5.setPosition(Common::Point(147, 128));
+ _soleInset.fixPriority(260);
+ _soleInset.setPosition(Common::Point(147, 128));
}
void Scene930::synchronize(Serializer &s) {
SceneExt::synchronize(s);
- s.syncAsSint16LE(_v141A);
- s.syncAsSint16LE(_v141C);
+ s.syncAsSint16LE(_soleOpened);
+ s.syncAsSint16LE(_bootInsetDisplayed);
}
/*--------------------------------------------------------------------------
diff --git a/engines/tsage/blue_force/blueforce_scenes9.h b/engines/tsage/blue_force/blueforce_scenes9.h
index b0761713b1..74708b94de 100644
--- a/engines/tsage/blue_force/blueforce_scenes9.h
+++ b/engines/tsage/blue_force/blueforce_scenes9.h
@@ -41,11 +41,11 @@ using namespace TsAGE;
class Scene900: public PalettedScene {
/* Items */
- class Item1: public NamedHotspot {
+ class Exterior: public NamedHotspot {
public:
virtual bool startAction(CursorType action, Event &event);
};
- class Item4: public NamedHotspot {
+ class WestExit: public NamedHotspot {
public:
virtual bool startAction(CursorType action, Event &event);
};
@@ -94,7 +94,7 @@ public:
SpeakerGameText _gameTextSpeaker;
SpeakerJakeJacket _jakeJacketSpeaker;
SpeakerLyleHat _lyleHatSpeaker;
- Item1 _item1;
+ Exterior _exterior;
Gate _gate;
Door _door;
Dog _dog;
@@ -104,13 +104,13 @@ public:
NamedObject _object5;
Lyle _lyle;
Body _body;
- Item4 _item4;
+ WestExit _westExit;
ASoundExt _sound1;
Action1 _action1;
Action2 _action2;
Action3 _action3;
Action4 _action4;
- int _field1974;
+ int _lyleDialogCtr;
int _field1976;
Scene900();
@@ -170,7 +170,7 @@ class Scene910: public PalettedScene {
class Object13: public NamedObject {
protected:
- int _field90, _field92;
+ int _state, _mode;
public:
void setupBreaker(int x, int y, int mode, int8 frameNumber);
virtual void synchronize(Serializer &s);
@@ -180,7 +180,7 @@ class Scene910: public PalettedScene {
class BlackPlug: public Object13 {
public:
- void init(int x, int y, int arg8, int8 argA);
+ void init(int x, int y, int arg8, int8 mode);
virtual bool startAction(CursorType action, Event &event);
virtual void remove();
};
@@ -188,7 +188,7 @@ class Scene910: public PalettedScene {
class Object25: public NamedObject {
int _field90, _field92;
public:
- void subEBBDC(int x, int y, int arg8, int argA);
+ void setupHiddenSwitch(int x, int y, int arg8, int argA);
virtual void synchronize(Serializer &s);
virtual bool startAction(CursorType action, Event &event);
virtual void remove();
@@ -253,7 +253,7 @@ class Scene910: public PalettedScene {
virtual bool startAction(CursorType action, Event &event);
};
- int _field2DDA, _field2DD8, _field2DE0, _field2DE2, _field2DE4;
+ int _sceneSubMode, _breakerButtonCtr, _field2DE0, _field2DE2, _field2DE4;
Common::Point _destPos;
public:
SequenceManager _sequenceManager1, _sequenceManager2;
@@ -270,7 +270,7 @@ public:
Nico _nico;
Stuart _stuart;
Forbes _forbes;
- NamedObject _object5, _vent, _object7;
+ NamedObject _object5, _vent, _shadow;
PowerCord _blackCord, _yellowCord;
BreakerBox _breakerBox;
FakeWall _fakeWall;
@@ -295,8 +295,8 @@ public:
virtual void process(Event &event);
virtual void dispatch();
virtual void checkGun();
- void subE82BD();
- void subE83E1();
+ void openHiddenDoor();
+ void closeHiddenDoor();
};
class Scene920: public SceneExt {
@@ -378,16 +378,16 @@ class Scene930: public PalettedScene {
virtual void signal();
};
- void showBootWindow();
- void subF3C07();
- void subF3D6F();
+ void showBootInset();
+ void ShowBoxInset();
+ void ShowSoleInset();
public:
SequenceManager _sequenceManager1;
Object1 _box;
- Object2 _object2;
+ Object2 _boxInset;
Object3 _boots;
- Object4 _bootsWindow;
- Object5 _object5;
+ Object4 _bootsInset;
+ Object5 _soleInset;
Item1 _item1;
NamedHotspot _item2;
@@ -417,8 +417,8 @@ public:
SpeakerGameText gameTextSpeaker;
- int _v141A;
- int _v141C;
+ bool _soleOpened;
+ int _bootInsetDisplayed;
virtual void postInit(SceneObjectList *OwnerList = NULL);
virtual void signal();
diff --git a/engines/tsage/converse.cpp b/engines/tsage/converse.cpp
index d86548bd4b..06fbffb751 100644
--- a/engines/tsage/converse.cpp
+++ b/engines/tsage/converse.cpp
@@ -25,6 +25,7 @@
#include "tsage/tsage.h"
#include "tsage/globals.h"
#include "tsage/staticres.h"
+#include "ringworld2/ringworld2_speakers.h"
namespace TsAGE {
@@ -32,7 +33,7 @@ namespace TsAGE {
SequenceManager::SequenceManager() : Action() {
- Common::set_to(&_objectList[0], &_objectList[6], (SceneObject *)NULL);
+ Common::fill(&_objectList[0], &_objectList[6], (SceneObject *)NULL);
_sequenceData.clear();
_fontNum = 0;
_sequenceOffset = 0;
@@ -81,7 +82,7 @@ void SequenceManager::remove() {
if (g_globals->_sceneObjects->contains(&_sceneText))
_sceneText.remove();
- Common::set_to(&_objectList[0], &_objectList[6], (SceneObject *)NULL);
+ Common::fill(&_objectList[0], &_objectList[6], (SceneObject *)NULL);
Action::remove();
}
@@ -342,7 +343,7 @@ void SequenceManager::attached(EventHandler *newOwner, EventHandler *endHandler,
DEALLOCATE(seqData);
- Common::set_to(&_objectList[0], &_objectList[6], (SceneObject *)NULL);
+ Common::fill(&_objectList[0], &_objectList[6], (SceneObject *)NULL);
for (int idx = 0; idx < 6; ++idx) {
_objectList[idx] = va_arg(va, SceneObject *);
if (!_objectList[idx])
@@ -451,7 +452,7 @@ int ConversationChoiceDialog::execute(const Common::StringArray &choiceList) {
while (!g_globals->_events.getEvent(event, EVENT_KEYPRESS | EVENT_BUTTON_DOWN | EVENT_MOUSE_MOVE) &&
!g_vm->shouldQuit()) {
g_system->delayMillis(10);
- g_system->updateScreen();
+ GLOBALS._screenSurface.updateScreen();
}
if (g_vm->shouldQuit())
break;
@@ -531,26 +532,52 @@ void ConversationChoiceDialog::draw() {
/*--------------------------------------------------------------------------*/
void Obj44::load(const byte *dataP) {
- _id = READ_LE_UINT16(dataP);
+ Common::MemoryReadStream s(dataP, (g_vm->getGameID() == GType_Ringworld2) ? 126 : 68);
+
+ if (g_vm->getGameID() == GType_Ringworld2) {
+ _mode = s.readSint16LE();
+ _lookupValue = s.readSint16LE();
+ _lookupIndex = s.readSint16LE();
+ _field6 = s.readSint16LE();
+ _field8 = s.readSint16LE();
+ }
+
+ _id = s.readSint16LE();
for (int idx = 0; idx < OBJ44_LIST_SIZE; ++idx)
- _field2[idx] = READ_LE_UINT16(dataP + 2 + idx * 2);
+ _callbackId[idx] = s.readSint16LE();
+
+ if (g_vm->getGameID() == GType_Ringworld2) {
+ _field16 = s.readSint16LE();
+ s.skip(20);
+ } else {
+ s.skip(4);
+ }
- const byte *listP = dataP + 0x10;
- for (int idx = 0; idx < OBJ44_LIST_SIZE; ++idx, listP += 10) {
- _list[idx]._id = READ_LE_UINT16(listP);
- _list[idx]._scriptOffset = READ_LE_UINT16(listP + 2);
+ for (int idx = 0; idx < OBJ0A_LIST_SIZE; ++idx) {
+ _list[idx]._id = s.readSint16LE();
+ _list[idx]._scriptOffset = s.readSint16LE();
+ s.skip(6);
}
- _speakerOffset = READ_LE_UINT16(dataP + 0x42);
+ _speakerOffset = s.readSint16LE();
}
void Obj44::synchronize(Serializer &s) {
s.syncAsSint32LE(_id);
for (int idx = 0; idx < OBJ44_LIST_SIZE; ++idx)
- s.syncAsSint32LE(_field2[idx]);
- for (int idx = 0; idx < OBJ44_LIST_SIZE; ++idx)
+ s.syncAsSint32LE(_callbackId[idx]);
+ for (int idx = 0; idx < OBJ0A_LIST_SIZE; ++idx)
_list[idx].synchronize(s);
s.syncAsUint32LE(_speakerOffset);
+
+ if (g_vm->getGameID() == GType_Ringworld2) {
+ s.syncAsSint16LE(_mode);
+ s.syncAsSint16LE(_lookupValue);
+ s.syncAsSint16LE(_lookupIndex);
+ s.syncAsSint16LE(_field6);
+ s.syncAsSint16LE(_field8);
+ s.syncAsSint16LE(_field16);
+ }
}
/*--------------------------------------------------------------------------*/
@@ -581,6 +608,11 @@ void StripManager::start(int stripNum, EventHandler *owner, StripCallback *callb
owner->setAction(this, owner);
}
+void StripManager::start3(int stripNum, EventHandler *owner, byte *lookupList) {
+ _lookupList = lookupList;
+ start(stripNum, owner, NULL);
+}
+
void StripManager::reset() {
_actionIndex = 0;
_delayFrames = 0;
@@ -614,10 +646,12 @@ void StripManager::load() {
// Get the object list
byte *obj44List = g_resourceManager->getResource(RES_STRIP, _stripNum, 1);
int dataSize = g_vm->_memoryManager.getSize(obj44List);
- assert((dataSize % 0x44) == 0);
+
+ int obj44Size = (g_vm->getGameID() == GType_Ringworld2) ? 126 : 68;
+ assert((dataSize % obj44Size) == 0);
byte *dataP = obj44List;
- for (int idx = 0; idx < (dataSize / 0x44); ++idx, dataP += 0x44) {
+ for (int idx = 0; idx < (dataSize / obj44Size); ++idx, dataP += obj44Size) {
Obj44 obj;
obj.load(dataP);
_obj44List.push_back(obj);
@@ -703,7 +737,12 @@ void StripManager::signal() {
return;
} else if (_obj44Index == 10000) {
// Reached end of strip
+ EventHandler *endHandler = _endHandler;
remove();
+
+ if ((g_vm->getGameID() == GType_Ringworld2) && endHandler)
+ endHandler->signal();
+
return;
}
@@ -714,17 +753,54 @@ void StripManager::signal() {
load();
Obj44 &obj44 = _obj44List[_obj44Index];
- _field2E8 = obj44._id;
+
+ if (g_vm->getGameID() != GType_Ringworld2) {
+ _field2E8 = obj44._id;
+ } else {
+ // Return to Ringworld specific handling
+ if (obj44._field6)
+ _field2E8 = obj44._field6;
+
+ switch (obj44._mode) {
+ case 1:
+ ++_lookupList[obj44._lookupIndex - 1];
+ break;
+ case 2:
+ --_lookupList[obj44._lookupIndex - 1];
+ break;
+ case 3:
+ _lookupList[obj44._lookupIndex - 1] = obj44._lookupValue;
+ break;
+ default:
+ break;
+ }
+ }
+
Common::StringArray choiceList;
// Build up a list of script entries
int idx;
- for (idx = 0; idx < OBJ44_LIST_SIZE; ++idx) {
- if (!obj44._list[idx]._id)
- break;
- // Get the next one
- choiceList.push_back((const char *)&_script[0] + obj44._list[idx]._scriptOffset);
+ if (g_vm->getGameID() == GType_Ringworld2 && obj44._field16) {
+ // Special loading mode used in Return to Ringworld
+ for (idx = 0; idx < OBJ44_LIST_SIZE; ++idx) {
+ int objIndex = _lookupList[obj44._field16 - 1];
+
+ if (!obj44._list[objIndex]._id)
+ break;
+
+ // Get the next one
+ choiceList.push_back((const char *)&_script[0] + obj44._list[objIndex]._scriptOffset);
+ }
+ } else {
+ // Standard choices loading
+ for (idx = 0; idx < OBJ44_LIST_SIZE; ++idx) {
+ if (!obj44._list[idx]._id)
+ break;
+
+ // Get the next one
+ choiceList.push_back((const char *)&_script[0] + obj44._list[idx]._scriptOffset);
+ }
}
int strIndex = 0;
@@ -754,13 +830,16 @@ void StripManager::signal() {
if (_callbackObject) {
for (idx = 0; idx < OBJ44_LIST_SIZE; ++idx) {
- if (!obj44._field2[idx])
+ if (!obj44._callbackId[idx])
break;
- _callbackObject->stripCallback(obj44._field2[idx]);
+ _callbackObject->stripCallback(obj44._callbackId[idx]);
}
}
+ if ((g_vm->getGameID() == GType_Ringworld2) && (_obj44List.size() > 0))
+ static_cast<Ringworld2::VisualSpeaker *>(_activeSpeaker)->proc15();
+
_textShown = true;
_activeSpeaker->setText(choiceList[strIndex]);
}
@@ -813,6 +892,17 @@ Speaker *StripManager::getSpeaker(const char *speakerName) {
return _speakerList[idx];
}
+ // TODO: Check if it necessary to make a strcmp first.
+ //
+ // If nothing is found, recheck and ignore the case as
+ // in R2R, some character names aren't in uppercase.
+ if (g_vm->getGameID() == GType_Ringworld2) {
+ for (uint idx = 0; idx < _speakerList.size(); ++idx) {
+ if (!scumm_stricmp(_speakerList[idx]->_speakerName.c_str(), speakerName))
+ return _speakerList[idx];
+ }
+ }
+
return NULL;
}
diff --git a/engines/tsage/converse.h b/engines/tsage/converse.h
index f82c07a7dd..0c4eb9539d 100644
--- a/engines/tsage/converse.h
+++ b/engines/tsage/converse.h
@@ -178,13 +178,19 @@ public:
};
#define OBJ44_LIST_SIZE 5
+#define OBJ0A_LIST_SIZE ((g_vm->getGameID() == GType_Ringworld2) ? 8 : 5)
class Obj44 : public Serialisable {
public:
int _id;
- int _field2[OBJ44_LIST_SIZE];
- Obj0A _list[OBJ44_LIST_SIZE];
+ int _callbackId[OBJ44_LIST_SIZE];
+ Obj0A _list[8];
uint _speakerOffset;
+
+ // Return to Ringworld specific field
+ int _mode;
+ int _lookupValue, _lookupIndex, _field6;
+ int _field8, _field16;
public:
void load(const byte *dataP);
virtual void synchronize(Serializer &s);
@@ -215,6 +221,9 @@ public:
Common::Array<byte> _script;
StripProc _onBegin;
StripProc _onEnd;
+
+ // Ringworld 2 specific fields
+ byte *_lookupList;
public:
StripManager();
virtual ~StripManager();
@@ -225,6 +234,7 @@ public:
virtual void process(Event &event);
void start(int stripNum, EventHandler *owner, StripCallback *callback = NULL);
+ void start3(int stripNum, EventHandler *owner, byte *lookupList);
void setCallback(StripCallback *callback) { _callbackObject = callback; }
void setColors(int stdColor, int highlightColor) { _choiceDialog.setColors(stdColor, highlightColor); }
void setFontNumber(int fontNum) { _choiceDialog.setFontNumber(fontNum); }
diff --git a/engines/tsage/core.cpp b/engines/tsage/core.cpp
index a56b30ad4d..292e74c09b 100644
--- a/engines/tsage/core.cpp
+++ b/engines/tsage/core.cpp
@@ -34,6 +34,7 @@
#include "tsage/globals.h"
#include "tsage/sound.h"
#include "tsage/blue_force/blueforce_logic.h"
+#include "tsage/ringworld2/ringworld2_logic.h"
namespace TsAGE {
@@ -71,14 +72,14 @@ InvObject::InvObject(int strip, int frame) {
_strip = strip;
_frame = frame;
- _visage = 0;
+ _visage = 7;
_sceneNumber = 0;
_iconResNum = 10;
}
void InvObject::setCursor() {
- if (g_vm->getGameID() == GType_BlueForce) {
- // Blue Force cursor handling
+ if (g_vm->getGameID() != GType_Ringworld) {
+ // All other games
_cursorId = (CursorType)BF_GLOBALS._inventory->indexOf(this);
g_globals->_events.setCursor(_cursorId);
} else {
@@ -94,6 +95,10 @@ void InvObject::setCursor() {
}
}
+bool InvObject::inInventory() const {
+ return _sceneNumber == ((g_vm->getGameID() != GType_Ringworld2) ? 1 : g_globals->_player._characterIndex);
+}
+
/*--------------------------------------------------------------------------*/
InvObjectList::InvObjectList() {
@@ -896,24 +901,28 @@ int PlayerMover::calculateRestOfRoute(int *routeList, int srcRegion, int destReg
// Check every connected region until we find a route to the destination (or we have no more to check).
int bestDistance = 31990;
while (((currDest = g_globals->_walkRegions._idxList[srcWalkRegion._idxListIndex + foundIndex]) != 0) && (!foundRoute)) {
- int newDistance = calculateRestOfRoute(tempList, currDest, destRegion, foundRoute);
+ // Only check the region if it isn't in the list of explicitly disabled regions
+ if (!contains(g_globals->_walkRegions._disabledRegions, (int)currDest)) {
+ 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 <= bestDistance) || foundRoute) {
+ // We found a shorter possible route, or one leading to the destination.
- // Overwrite the route with this new one.
- routeList[0] = ourListSize - 1;
+ // Overwrite the route with this new one.
+ routeList[0] = ourListSize - 1;
- for (int i = ourListSize; i <= tempList[0]; ++i) {
- routeList[i] = tempList[i];
- ++routeList[0];
+ for (int i = ourListSize; i <= tempList[0]; ++i) {
+ routeList[i] = tempList[i];
+ ++routeList[0];
+ }
+
+ bestDistance = newDistance;
}
- bestDistance = newDistance;
+ // Truncate our local list to the size it was before the call.
+ tempList[0] = ourListSize;
}
- // Truncate our local list to the size it was before the call.
- tempList[0] = ourListSize;
++foundIndex;
}
@@ -932,6 +941,8 @@ int PlayerMover::findDistance(const Common::Point &pt1, const Common::Point &pt2
return (int)sqrt(xx + yy);
}
+// Calculate intersection of the line segments pt1-pt2 and pt3-pt4.
+// Return true if they intersect, and return the intersection in ptOut.
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 diffX1 = pt2.x - pt1.x;
@@ -1057,6 +1068,8 @@ PaletteRotation::PaletteRotation() : PaletteModifierCached() {
_percent = 0;
_delayCtr = 0;
_frameNumber = g_globals->_events.getFrameNumber();
+ _idxChange = 1;
+ _countdown = 0;
}
void PaletteRotation::synchronize(Serializer &s) {
@@ -1070,14 +1083,24 @@ void PaletteRotation::synchronize(Serializer &s) {
s.syncAsSint32LE(_rotationMode);
s.syncAsSint32LE(_duration);
s.syncBytes(&_palette[0], 256 * 3);
+
+ if (g_vm->getGameID() == GType_Ringworld2) {
+ s.syncAsSint16LE(_idxChange);
+ s.syncAsSint16LE(_countdown);
+ }
}
void PaletteRotation::signal() {
+ if (_countdown > 0) {
+ --_countdown;
+ return;
+ }
+
if (_delayCtr) {
uint32 frameNumber = g_globals->_events.getFrameNumber();
if (frameNumber >= _frameNumber) {
- _delayCtr = frameNumber - _frameNumber;
+ _delayCtr -= frameNumber - _frameNumber;
_frameNumber = frameNumber;
if (_delayCtr < 0)
@@ -1094,21 +1117,24 @@ void PaletteRotation::signal() {
bool flag = true;
switch (_rotationMode) {
case -1:
- if (--_currIndex < _start) {
+ _currIndex -= _idxChange;
+ if (_currIndex < _start) {
flag = decDuration();
if (flag)
_currIndex = _end - 1;
}
break;
case 1:
- if (++_currIndex >= _end) {
+ _currIndex += _idxChange;
+ if (_currIndex >= _end) {
flag = decDuration();
if (flag)
_currIndex = _start;
}
break;
case 2:
- if (++_currIndex >= _end) {
+ _currIndex += _idxChange;
+ if (_currIndex >= _end) {
flag = decDuration();
if (flag) {
_currIndex = _end - 2;
@@ -1117,7 +1143,8 @@ void PaletteRotation::signal() {
}
break;
case 3:
- if (--_currIndex < _start) {
+ _currIndex -= _idxChange;
+ if (_currIndex < _start) {
flag = decDuration();
if (flag) {
_currIndex = _start + 1;
@@ -1140,7 +1167,9 @@ void PaletteRotation::signal() {
void PaletteRotation::remove() {
Action *action = _action;
- g_system->getPaletteManager()->setPalette((const byte *)&_palette[_start * 3], _start, _end - _start);
+
+ if (_idxChange)
+ g_system->getPaletteManager()->setPalette((const byte *)&_palette[_start * 3], _start, _end - _start);
_scenePalette->_listeners.remove(this);
@@ -1272,6 +1301,13 @@ bool ScenePalette::loadPalette(int paletteNum) {
return true;
}
+/**
+ * Loads a palette from the passed raw data block
+ */
+void ScenePalette::loadPalette(const byte *pSrc, int start, int count) {
+ Common::copy(pSrc, pSrc + count * 3, &_palette[start * 3]);
+}
+
void ScenePalette::refresh() {
// Set indexes for standard colors to closest color in the palette
_colors.background = indexOf(255, 255, 255); // White background
@@ -1295,6 +1331,15 @@ void ScenePalette::setPalette(int index, int count) {
}
/**
+ * Get a palette entry
+ */
+void ScenePalette::getEntry(int index, uint *r, uint *g, uint *b) {
+ *r = _palette[index * 3];
+ *g = _palette[index * 3 + 1];
+ *b = _palette[index * 3 + 2];
+}
+
+/**
* Set a palette entry
*/
void ScenePalette::setEntry(int index, uint r, uint g, uint b) {
@@ -1309,13 +1354,15 @@ void ScenePalette::setEntry(int index, uint r, uint g, uint b) {
* @param g G component
* @param b B component
* @param threshold Closeness threshold.
+ * @param start Starting index
+ * @param count Number of indexes to scan
* @remarks A threshold may be provided to specify how close the matching color must be
*/
-uint8 ScenePalette::indexOf(uint r, uint g, uint b, int threshold) {
+uint8 ScenePalette::indexOf(uint r, uint g, uint b, int threshold, int start, int count) {
int palIndex = -1;
byte *palData = &_palette[0];
- for (int i = 0; i < 256; ++i) {
+ for (int i = start; i < (start + count); ++i) {
byte ir = *palData++;
byte ig = *palData++;
byte ib = *palData++;
@@ -1380,7 +1427,7 @@ void ScenePalette::fade(const byte *adjustData, bool fullAdjust, int percent) {
// Set the altered pale4tte
g_system->getPaletteManager()->setPalette((const byte *)&tempPalette[0], 0, 256);
- g_system->updateScreen();
+ GLOBALS._screenSurface.updateScreen();
}
PaletteRotation *ScenePalette::addRotation(int start, int end, int rotationMode, int duration, Action *action) {
@@ -1435,7 +1482,7 @@ void ScenePalette::changeBackground(const Rect &bounds, FadeMode fadeMode) {
Rect tempRect = bounds;
if (g_vm->getGameID() != GType_Ringworld)
- tempRect.setHeight(BF_GLOBALS._interfaceY);
+ tempRect.setHeight(T2_GLOBALS._interfaceY);
g_globals->_screenSurface.copyFrom(g_globals->_sceneManager._scene->_backSurface,
tempRect, Rect(0, 0, tempRect.width(), tempRect.height()), NULL);
@@ -1498,25 +1545,30 @@ bool SceneItem::startAction(CursorType action, Event &event) {
void SceneItem::doAction(int action) {
const char *msg = NULL;
- switch ((int)action) {
- case CURSOR_LOOK:
- msg = LOOK_SCENE_HOTSPOT;
- break;
- case CURSOR_USE:
- msg = USE_SCENE_HOTSPOT;
- break;
- case CURSOR_TALK:
- msg = TALK_SCENE_HOTSPOT;
- break;
- case 0x1000:
- msg = SPECIAL_SCENE_HOTSPOT;
- break;
- default:
- msg = DEFAULT_SCENE_HOTSPOT;
- break;
- }
+ if (g_vm->getGameID() == GType_Ringworld2) {
+ Event dummyEvent;
+ ((Ringworld2::SceneExt *)GLOBALS._sceneManager._scene)->display((CursorType)action, dummyEvent);
+ } else {
+ switch ((int)action) {
+ case CURSOR_LOOK:
+ msg = LOOK_SCENE_HOTSPOT;
+ break;
+ case CURSOR_USE:
+ msg = USE_SCENE_HOTSPOT;
+ break;
+ case CURSOR_TALK:
+ msg = TALK_SCENE_HOTSPOT;
+ break;
+ case 0x1000:
+ msg = SPECIAL_SCENE_HOTSPOT;
+ break;
+ default:
+ msg = DEFAULT_SCENE_HOTSPOT;
+ break;
+ }
- GUIErrorMessage(msg);
+ GUIErrorMessage(msg);
+ }
}
bool SceneItem::contains(const Common::Point &pt) {
@@ -1541,12 +1593,12 @@ void SceneItem::display(int resNum, int lineNum, ...) {
g_globals->_sceneObjects->draw();
}
- GfxFontBackup font;
Common::Point pos(160, 100);
Rect textRect;
int maxWidth = 120;
bool keepOnscreen = false;
- bool centerText = g_vm->getGameID() == GType_Ringworld;
+ bool centerText = g_vm->getGameID() != GType_BlueForce;
+ Common::List<int> playList;
if (resNum != 0) {
va_list va;
@@ -1555,6 +1607,17 @@ void SceneItem::display(int resNum, int lineNum, ...) {
if (resNum == -1)
msg = Common::String(va_arg(va, const char *));
+ if (g_vm->getGameID() == GType_Ringworld2) {
+ // Pre-process the string for any sound information
+ while (msg.hasPrefix("!")) {
+ msg.deleteChar(0);
+ playList.push_back(atoi(msg.c_str()));
+
+ while (!msg.empty() && (*msg.c_str() >= '0' && *msg.c_str() <= '9'))
+ msg.deleteChar(0);
+ }
+ }
+
int mode;
do {
// Get next instruction
@@ -1628,10 +1691,14 @@ void SceneItem::display(int resNum, int lineNum, ...) {
if (resNum) {
// Get required bounding size
- g_globals->gfxManager().getStringBounds(msg.c_str(), textRect, maxWidth);
- textRect.center(pos.x, pos.y);
+ GfxFont font;
+ font.setFontNumber(g_globals->_sceneText._fontNumber);
+ font.getStringBounds(msg.c_str(), textRect, maxWidth);
+ // Center the text at the specified position, and then constrain it to be-
+ textRect.center(pos.x, pos.y);
textRect.contain(g_globals->gfxManager()._bounds);
+
if (centerText) {
g_globals->_sceneText._color1 = g_globals->_sceneText._color2;
g_globals->_sceneText._color2 = 0;
@@ -1658,10 +1725,16 @@ void SceneItem::display(int resNum, int lineNum, ...) {
// Keep event on-screen until a mouse or keypress
while (!g_vm->shouldQuit() && !g_globals->_events.getEvent(event,
EVENT_BUTTON_DOWN | EVENT_KEYPRESS)) {
- g_system->updateScreen();
+ GLOBALS._screenSurface.updateScreen();
g_system->delayMillis(10);
}
+ // For Return to Ringworld, play the voice overs in sequence
+ if ((g_vm->getGameID() == GType_Ringworld2) && !playList.empty() && !R2_GLOBALS._playStream.isPlaying()) {
+ R2_GLOBALS._playStream.play(*playList.begin(), NULL);
+ playList.pop_front();
+ }
+
g_globals->_sceneText.remove();
}
@@ -1684,7 +1757,8 @@ void SceneItem::display2(int resNum, int lineNum) {
SET_EXT_FGCOLOR, 13, LIST_END);
break;
case GType_Ringworld2:
- display(resNum, lineNum, SET_WIDTH, 280, SET_X, 20, SET_Y, 20, SET_EXT_BGCOLOR, 60, LIST_END);
+ display(resNum, lineNum, SET_WIDTH, 280, SET_X, 160, SET_Y, 20, SET_POS_MODE, ALIGN_CENTER,
+ SET_EXT_BGCOLOR, 60, LIST_END);
break;
default:
display(resNum, lineNum, SET_WIDTH, 200, SET_EXT_BGCOLOR, 7, LIST_END);
@@ -1705,13 +1779,55 @@ void SceneItem::display(const Common::String &msg) {
/*--------------------------------------------------------------------------*/
+SceneHotspot::SceneHotspot(): SceneItem() {
+ _lookLineNum = _useLineNum = _talkLineNum = 0;
+}
+
+void SceneHotspot::synchronize(Serializer &s) {
+ SceneItem::synchronize(s);
+
+ if (g_vm->getGameID() == GType_Ringworld2) {
+ // In R2R, the following fields were moved into the SceneItem class
+ s.syncAsSint16LE(_resNum);
+ s.syncAsSint16LE(_lookLineNum);
+ s.syncAsSint16LE(_useLineNum);
+ s.syncAsSint16LE(_talkLineNum);
+ }
+}
+
bool SceneHotspot::startAction(CursorType action, Event &event) {
- switch (action) {
+ switch (g_vm->getGameID()) {
case GType_BlueForce: {
BlueForce::SceneExt *scene = (BlueForce::SceneExt *)BF_GLOBALS._sceneManager._scene;
assert(scene);
return scene->display(action);
}
+ case GType_Ringworld2: {
+ switch (action) {
+ case CURSOR_LOOK:
+ if (_lookLineNum != -1) {
+ SceneItem::display2(_resNum, _lookLineNum);
+ return true;
+ }
+ break;
+ case CURSOR_USE:
+ if (_useLineNum != -1) {
+ SceneItem::display2(_resNum, _useLineNum);
+ return true;
+ }
+ break;
+ case CURSOR_TALK:
+ if (_talkLineNum != -1) {
+ SceneItem::display2(_resNum, _talkLineNum);
+ return true;
+ }
+ break;
+ default:
+ break;
+ }
+
+ return ((Ringworld2::SceneExt *)GLOBALS._sceneManager._scene)->display(action, event);
+ }
default:
return SceneItem::startAction(action, event);
}
@@ -1748,6 +1864,87 @@ void SceneHotspot::doAction(int action) {
}
}
+void SceneHotspot::setDetails(int ys, int xs, int ye, int xe, const int resnum, const int lookLineNum, const int useLineNum) {
+ setBounds(ys, xe, ye, xs);
+ _resNum = resnum;
+ _lookLineNum = lookLineNum;
+ _useLineNum = useLineNum;
+ _talkLineNum = -1;
+ g_globals->_sceneItems.addItems(this, NULL);
+}
+
+void SceneHotspot::setDetails(const Rect &bounds, int resNum, int lookLineNum, int talkLineNum, int useLineNum, int mode, SceneItem *item) {
+ setBounds(bounds);
+ _resNum = resNum;
+ _lookLineNum = lookLineNum;
+ _talkLineNum = talkLineNum;
+ _useLineNum = useLineNum;
+
+ switch (mode) {
+ case 2:
+ g_globals->_sceneItems.push_front(this);
+ break;
+ case 4:
+ g_globals->_sceneItems.addBefore(item, this);
+ break;
+ case 5:
+ g_globals->_sceneItems.addAfter(item, this);
+ break;
+ default:
+ g_globals->_sceneItems.push_back(this);
+ break;
+ }
+}
+
+void SceneHotspot::setDetails(int sceneRegionId, int resNum, int lookLineNum, int talkLineNum, int useLineNum, int mode) {
+ _sceneRegionId = sceneRegionId;
+ _resNum = resNum;
+ _lookLineNum = lookLineNum;
+ _talkLineNum = talkLineNum;
+ _useLineNum = useLineNum;
+
+ // Handle adding hotspot to scene items list as necessary
+ switch (mode) {
+ case 2:
+ GLOBALS._sceneItems.push_front(this);
+ break;
+ case 3:
+ break;
+ default:
+ GLOBALS._sceneItems.push_back(this);
+ break;
+ }
+}
+
+void SceneHotspot::setDetails(int resNum, int lookLineNum, int talkLineNum, int useLineNum, int mode, SceneItem *item) {
+ _resNum = resNum;
+ _lookLineNum = lookLineNum;
+ _talkLineNum = talkLineNum;
+ _useLineNum = useLineNum;
+
+ switch (mode) {
+ case 2:
+ g_globals->_sceneItems.push_front(this);
+ break;
+ case 4:
+ g_globals->_sceneItems.addBefore(item, this);
+ break;
+ case 5:
+ g_globals->_sceneItems.addAfter(item, this);
+ break;
+ default:
+ g_globals->_sceneItems.push_back(this);
+ break;
+ }
+}
+
+void SceneHotspot::setDetails(int resNum, int lookLineNum, int talkLineNum, int useLineNum) {
+ _resNum = resNum;
+ _lookLineNum = lookLineNum;
+ _talkLineNum = talkLineNum;
+ _useLineNum = useLineNum;
+}
+
/*--------------------------------------------------------------------------*/
void SceneObjectWrapper::setSceneObject(SceneObject *so) {
@@ -1823,7 +2020,6 @@ SceneObject::SceneObject() : SceneHotspot() {
_moveDiff.x = 5;
_moveDiff.y = 3;
_numFrames = 10;
- _numFrames = 10;
_moveRate = 10;
_regionBitList = 0;
_sceneRegionId = 0;
@@ -1835,6 +2031,11 @@ SceneObject::SceneObject() : SceneHotspot() {
_visage = 0;
_strip = 0;
_frame = 0;
+ _effect = 0;
+ _shade = _shade2 = 0;
+ _linkedActor = NULL;
+
+ _field8A = Common::Point(0, 0);
}
SceneObject::SceneObject(const SceneObject &so) : SceneHotspot() {
@@ -2137,6 +2338,14 @@ SceneObject *SceneObject::clone() const {
return obj;
}
+void SceneObject::copy(SceneObject *src) {
+ *this = *src;
+
+ _objectWrapper = NULL;
+ _mover = NULL;
+ _endAction = NULL;
+}
+
void SceneObject::checkAngle(const SceneObject *obj) {
checkAngle(obj->_position);
}
@@ -2201,8 +2410,19 @@ void SceneObject::synchronize(Serializer &s) {
SYNC_POINTER(_mover);
s.syncAsSint16LE(_moveDiff.x); s.syncAsSint16LE(_moveDiff.y);
s.syncAsSint32LE(_moveRate);
+ if (g_vm->getGameID() == GType_Ringworld2) {
+ s.syncAsSint16LE(_field8A.x);
+ s.syncAsSint16LE(_field8A.y);
+ }
SYNC_POINTER(_endAction);
s.syncAsUint32LE(_regionBitList);
+
+ if (g_vm->getGameID() == GType_Ringworld2) {
+ s.syncAsSint16LE(_effect);
+ s.syncAsSint16LE(_shade);
+ s.syncAsSint16LE(_shade2);
+ SYNC_POINTER(_linkedActor);
+ }
}
void SceneObject::postInit(SceneObjectList *OwnerList) {
@@ -2245,6 +2465,12 @@ void SceneObject::remove() {
}
void SceneObject::dispatch() {
+ if (g_vm->getGameID() == GType_Ringworld2) {
+ if (_shade != _shade2)
+ _flags |= OBJFLAG_PANES;
+ _shade2 = _shade;
+ }
+
uint32 currTime = g_globals->_events.getFrameNumber();
if (_action)
_action->dispatch();
@@ -2352,6 +2578,17 @@ void SceneObject::dispatch() {
if (!(_flags & OBJFLAG_FIXED_PRIORITY)) {
setPriority(_position.y);
}
+
+ if (g_vm->getGameID() == GType_Ringworld2) {
+ if (_linkedActor) {
+ _linkedActor->setPosition(_position);
+ _linkedActor->setStrip(_strip);
+ _linkedActor->setFrame(_frame);
+ }
+
+ if ((_effect == 1) && (getRegionIndex() < 11))
+ _shade = 0;
+ }
}
void SceneObject::calcAngle(const Common::Point &pt) {
@@ -2412,6 +2649,11 @@ void SceneObject::updateScreen() {
srcRect.right = ((srcRect.right + 3) / 4) * 4;
srcRect.clip(g_globals->_sceneManager._scene->_sceneBounds);
+ if (g_vm->getGameID() != GType_Ringworld) {
+ if (T2_GLOBALS._uiElements._visible)
+ srcRect.bottom = MIN<int16>(srcRect.bottom, T2_GLOBALS._interfaceY);
+ }
+
if (srcRect.isValidRect()) {
Rect destRect = srcRect;
destRect.translate(-sceneBounds.left, -sceneBounds.top);
@@ -2469,6 +2711,20 @@ void BackgroundSceneObject::draw() {
g_globals->_sceneManager._scene->_backSurface.copyFrom(frame, destRect, priorityRegion);
}
+void BackgroundSceneObject::setup2(int visage, int stripFrameNum, int frameNum, int posX, int posY, int priority, int32 arg10) {
+ warning("TODO: Implement properly BackgroundSceneObject::setup2()");
+ postInit();
+ setVisage(visage);
+ setStrip(stripFrameNum);
+ setFrame(frameNum);
+ setPosition(Common::Point(posX, posY), 0);
+ fixPriority(priority);
+}
+
+void BackgroundSceneObject::proc27() {
+ warning("STUB: BackgroundSceneObject::proc27()");
+}
+
/*--------------------------------------------------------------------------*/
void SceneObjectList::draw() {
@@ -2585,43 +2841,48 @@ void SceneObjectList::draw() {
}
g_globals->_paneRegions[paneNum].setRect(0, 0, 0, 0);
-redraw:
- // Main draw loop
- for (uint objIndex = 0; objIndex < objList.size(); ++objIndex) {
- SceneObject *obj = objList[objIndex];
-
- if ((obj->_flags & flagMask) && !(obj->_flags & OBJFLAG_HIDE)) {
- obj->_paneRects[paneNum] = obj->_bounds;
- obj->draw();
+
+ // FIXME: Currently, removing objects causes screen flickers when the removed object intersects
+ // another drawn object, since the background is briefly redrawn over the object. For now, I'm
+ // using a forced jump back to redraw objects. In the long term, I should figure out how the
+ // original game does this properly
+ bool redrawFlag = true;
+ while (redrawFlag) {
+ redrawFlag = false;
+
+ // Main draw loop
+ for (uint objIndex = 0; objIndex < objList.size(); ++objIndex) {
+ SceneObject *obj = objList[objIndex];
+
+ if ((obj->_flags & flagMask) && !(obj->_flags & OBJFLAG_HIDE)) {
+ obj->_paneRects[paneNum] = obj->_bounds;
+ obj->draw();
+ }
}
- }
- // Update the palette
- g_globals->_sceneManager.fadeInIfNecessary();
- g_globals->_sceneManager._loadMode = 0;
- g_globals->_paneRefreshFlag[paneNum] = 0;
-
- // Loop through the object list, removing any objects and refreshing the screen as necessary
- for (uint objIndex = 0; objIndex < objList.size(); ++objIndex) {
- SceneObject *obj = objList[objIndex];
-
- if (obj->_flags & OBJFLAG_HIDE)
- obj->_flags |= OBJFLAG_HIDING;
- obj->_flags &= ~flagMask;
- if (obj->_flags & OBJFLAG_REMOVE) {
- obj->_flags |= OBJFLAG_PANES;
-
- checkIntersection(objList, objIndex, CURRENT_PANENUM);
-
- obj->updateScreen();
- obj->removeObject();
-
- // FIXME: Currently, removing objects causes screen flickers when the removed object intersects
- // another drawn object, since the background is briefly redrawn over the object. For now, I'm
- // using a forced jump back to redraw objects. In the long term, I should figure out how the
- // original game does this properly
- objList.remove_at(objIndex);
- goto redraw;
+ // Update the palette
+ g_globals->_sceneManager.fadeInIfNecessary();
+ g_globals->_sceneManager._loadMode = 0;
+ g_globals->_paneRefreshFlag[paneNum] = 0;
+
+ // Loop through the object list, removing any objects and refreshing the screen as necessary
+ for (uint objIndex = 0; objIndex < objList.size() && !redrawFlag; ++objIndex) {
+ SceneObject *obj = objList[objIndex];
+
+ if (obj->_flags & OBJFLAG_HIDE)
+ obj->_flags |= OBJFLAG_HIDING;
+ obj->_flags &= ~flagMask;
+ if (obj->_flags & OBJFLAG_REMOVE) {
+ obj->_flags |= OBJFLAG_PANES;
+
+ checkIntersection(objList, objIndex, CURRENT_PANENUM);
+
+ obj->updateScreen();
+ obj->removeObject();
+
+ objList.remove_at(objIndex);
+ redrawFlag = true;
+ }
}
}
}
@@ -2730,6 +2991,7 @@ SceneText::SceneText() : SceneObject() {
_fontNumber = 2;
_width = 160;
_textMode = ALIGN_LEFT;
+ _color1 = 0;
_color2 = 0;
_color3 = 0;
}
@@ -2790,7 +3052,7 @@ void SceneText::synchronize(Serializer &s) {
void SceneText::updateScreen() {
// FIXME: Hack for Blue Force to handle not refreshing the screen if the user interface
// has been re-activated after showing some scene text
- if ((g_vm->getGameID() != GType_BlueForce) || (_bounds.top < UI_INTERFACE_Y) ||
+ if ((g_vm->getGameID() == GType_Ringworld) || (_bounds.top < UI_INTERFACE_Y) ||
!T2_GLOBALS._uiElements._visible)
SceneObject::updateScreen();
}
@@ -2905,6 +3167,16 @@ Player::Player(): SceneObject() {
_enabled = false;
_uiEnabled = false;
_field8C = 0;
+
+ // Return to Ringworld specific fields
+ _characterIndex = R2_NONE;
+
+ for (int i = 0; i < MAX_CHARACTERS; ++i) {
+ _characterScene[i] = 0;
+ _characterStrip[i] = 0;
+ _characterFrame[i] = 0;
+ _oldCharacterScene[i] = 0;
+ }
}
void Player::postInit(SceneObjectList *OwnerList) {
@@ -2914,8 +3186,25 @@ void Player::postInit(SceneObjectList *OwnerList) {
_uiEnabled = true;
_percent = 100;
_field8C = 10;
- _moveDiff.x = 4;
- _moveDiff.y = 2;
+
+ if (g_vm->getGameID() != GType_Ringworld2)
+ {
+ _moveDiff.x = 4;
+ _moveDiff.y = 2;
+ }
+ else
+ {
+ _moveDiff.x = 3;
+ _moveDiff.y = 2;
+ _effect = 1;
+ _shade = 0;
+
+ setObjectWrapper(new SceneObjectWrapper());
+ setPosition(_characterPos[_characterIndex]);
+ setStrip(_characterStrip[_characterIndex]);
+ setFrame(_characterFrame[_characterIndex]);
+ _characterScene[_characterIndex] = GLOBALS._sceneManager._sceneNumber;
+ }
}
void Player::disableControl() {
@@ -2924,7 +3213,7 @@ void Player::disableControl() {
g_globals->_events.setCursor(CURSOR_NONE);
_enabled = false;
- if ((g_vm->getGameID() == GType_BlueForce) && T2_GLOBALS._uiElements._active)
+ if ((g_vm->getGameID() != GType_Ringworld) && T2_GLOBALS._uiElements._active)
T2_GLOBALS._uiElements.hide();
}
@@ -2964,6 +3253,24 @@ void Player::enableControl() {
}
}
+void Player::disableControl(CursorType cursorId, CursorType objectId) {
+ if (cursorId != -1)
+ R2_GLOBALS._events.setCursor(cursorId);
+ else if (objectId != CURSOR_NONE)
+ R2_GLOBALS._events.setCursor(objectId);
+
+ disableControl();
+}
+
+void Player::enableControl(CursorType cursorId, CursorType objectId) {
+ enableControl();
+
+ if (cursorId != -1)
+ R2_GLOBALS._events.setCursor(cursorId);
+ else if (objectId != CURSOR_NONE)
+ R2_GLOBALS._events.setCursor(objectId);
+}
+
void Player::process(Event &event) {
if ((g_vm->getGameID() != GType_Ringworld) && _action)
_action->process(event);
@@ -2972,7 +3279,7 @@ void Player::process(Event &event) {
(g_globals->_events.getCursor() == CURSOR_WALK) && g_globals->_player._canWalk &&
(_position != event.mousePos) && g_globals->_sceneObjects->contains(this)) {
- if ((g_vm->getGameID() == GType_BlueForce) && !BF_GLOBALS._player._enabled)
+ if ((g_vm->getGameID() != GType_Ringworld) && !BF_GLOBALS._player._enabled)
return;
PlayerMover *newMover = new PlayerMover();
@@ -2991,8 +3298,20 @@ void Player::synchronize(Serializer &s) {
s.syncAsByte(_uiEnabled);
s.syncAsSint16LE(_field8C);
- if (g_vm->getGameID() == GType_BlueForce)
+ if (g_vm->getGameID() != GType_Ringworld)
s.syncAsByte(_enabled);
+
+ if (g_vm->getGameID() == GType_Ringworld2) {
+ s.syncAsSint16LE(_characterIndex);
+ for (int i = 0; i < MAX_CHARACTERS; ++i) {
+ s.syncAsSint16LE(_characterScene[i]);
+ s.syncAsSint16LE(_oldCharacterScene[i]);
+ s.syncAsSint16LE(_characterPos[i].x);
+ s.syncAsSint16LE(_characterPos[i].y);
+ s.syncAsSint16LE(_characterStrip[i]);
+ s.syncAsSint16LE(_characterFrame[i]);
+ }
+ }
}
/*--------------------------------------------------------------------------*/
@@ -3434,6 +3753,7 @@ void WalkRegions::clear() {
_field18.clear();
_idxList.clear();
_idxList2.clear();
+ _disabledRegions.clear();
}
void WalkRegions::load(int sceneNum) {
@@ -3606,6 +3926,39 @@ int WalkRegions::indexOf(const Common::Point &pt, const Common::List<int> *index
return -1;
}
+void WalkRegions::synchronize(Serializer &s) {
+ // Synchronise the list of disabled regions as a list of values terminated with a '-1'
+ int regionId = 0;
+ if (s.isLoading()) {
+ _disabledRegions.clear();
+
+ s.syncAsSint16LE(regionId);
+ while (regionId != -1) {
+ _disabledRegions.push_back(regionId);
+ s.syncAsSint16LE(regionId);
+ }
+ } else {
+ Common::List<int>::iterator i;
+ for (i = _disabledRegions.begin(); i != _disabledRegions.end(); ++i) {
+ regionId = *i;
+ s.syncAsSint16LE(regionId);
+ }
+
+ regionId = -1;
+ s.syncAsSint16LE(regionId);
+ }
+}
+
+void WalkRegions::disableRegion(int regionId) {
+ if (!contains(_disabledRegions, regionId))
+ _disabledRegions.push_back(regionId);
+}
+
+void WalkRegions::enableRegion(int regionId) {
+ _disabledRegions.remove(regionId);
+}
+
+
/*--------------------------------------------------------------------------*/
void ScenePriorities::load(int resNum) {
@@ -3756,7 +4109,8 @@ void SceneHandler::process(Event &event) {
// Check for displaying right-click dialog
if ((event.eventType == EVENT_BUTTON_DOWN) && (event.btnState == BTNSHIFT_RIGHT) &&
- g_globals->_player._uiEnabled) {
+ g_globals->_player._uiEnabled &&
+ ((g_vm->getGameID() != GType_Ringworld2) || (R2_GLOBALS._sceneManager._sceneNumber != 1330))) {
g_globals->_game->rightClick();
event.handled = true;
@@ -3809,7 +4163,7 @@ void SceneHandler::process(Event &event) {
}
// Mouse press handling
- bool enabled = (g_vm->getGameID() == GType_BlueForce) ? g_globals->_player._enabled :
+ bool enabled = (g_vm->getGameID() != GType_Ringworld) ? g_globals->_player._enabled :
g_globals->_player._uiEnabled;
if (enabled && (event.eventType == EVENT_BUTTON_DOWN) && !g_globals->_sceneItems.empty()) {
// Check if the mouse is on the player
@@ -3841,7 +4195,7 @@ void SceneHandler::process(Event &event) {
g_globals->_events.setCursor(CURSOR_USE);
}
- if (g_vm->getGameID() == GType_BlueForce)
+ if (g_vm->getGameID() != GType_Ringworld)
event.handled = true;
} else if (g_vm->getGameID() != GType_Ringworld) {
event.handled = true;
@@ -3897,7 +4251,7 @@ void SceneHandler::dispatch() {
do {
process(event);
} while (g_globals->_events.getEvent(event));
- } else if (g_vm->getGameID() == GType_BlueForce) {
+ } else if (g_vm->getGameID() != GType_Ringworld) {
// For Blue Force, 'none' events need to be generated in the absence of any
event.eventType = EVENT_NONE;
event.mousePos = g_globals->_events._mousePos;
@@ -3905,8 +4259,10 @@ void SceneHandler::dispatch() {
}
// Handle drawing the contents of the scene
- if (g_globals->_sceneManager._scene)
- g_globals->_sceneObjects->draw();
+ if ((g_vm->getGameID() != GType_Ringworld2) || (R2_GLOBALS._animationCtr == 0)) {
+ if (g_globals->_sceneManager._scene)
+ g_globals->_sceneObjects->draw();
+ }
// Check to see if any scene change is required
g_globals->_sceneManager.checkScene();
diff --git a/engines/tsage/core.h b/engines/tsage/core.h
index 0137134583..60a7930eab 100644
--- a/engines/tsage/core.h
+++ b/engines/tsage/core.h
@@ -64,7 +64,7 @@ public:
InvObject(int visage, int strip, int frame);
InvObject(int visage, int strip);
- bool inInventory() const { return _sceneNumber == 1; }
+ bool inInventory() const;
void setCursor();
virtual Common::String getClassName() { return "InvObject"; }
@@ -129,7 +129,7 @@ public:
virtual void dispatch();
virtual void setAction(Action *action) { setAction(action, NULL); }
virtual void setAction(Action *action, EventHandler *endHandler, ...);
- virtual void destroy() {};
+ virtual void destroy() {}
};
class Action : public EventHandler {
@@ -322,6 +322,8 @@ public:
int _end;
int _rotationMode;
int _duration;
+ int _idxChange;
+ int _countdown;
public:
PaletteRotation();
@@ -370,10 +372,13 @@ public:
~ScenePalette();
bool loadPalette(int paletteNum);
+ void loadPalette(const byte *pSrc, int start, int count);
+ void replace(const ScenePalette *src) { loadPalette(src->_palette, 0, 256); }
void refresh();
void setPalette(int index, int count);
+ void getEntry(int index, uint *r, uint *g, uint *b);
void setEntry(int index, uint r, uint g, uint b);
- uint8 indexOf(uint r, uint g, uint b, int threshold = 0xffff);
+ uint8 indexOf(uint r, uint g, uint b, int threshold = 0xffff, int start = 0, int count = 256);
void getPalette(int start = 0, int count = 256);
void signalListeners();
void clearListeners();
@@ -440,10 +445,19 @@ public:
class SceneHotspot : public SceneItem {
public:
- SceneHotspot() : SceneItem() {}
+ int _resNum, _lookLineNum, _useLineNum, _talkLineNum;
+public:
+ SceneHotspot();
+ virtual void synchronize(Serializer &s);
virtual bool startAction(CursorType action, Event &event);
virtual Common::String getClassName() { return "SceneHotspot"; }
virtual void doAction(int action);
+
+ void setDetails(int ys, int xs, int ye, int xe, const int resnum, const int lookLineNum, const int useLineNum);
+ void setDetails(const Rect &bounds, int resNum, int lookLineNum, int talkLineNum, int useLineNum, int mode, SceneItem *item);
+ void setDetails(int sceneRegionId, int resNum, int lookLineNum, int talkLineNum, int useLineNum, int mode = 0);
+ void setDetails(int resNum, int lookLineNum, int talkLineNum, int useLineNum, int mode, SceneItem *item);
+ void setDetails(int resNum, int lookLineNum, int talkLineNum, int useLineNum);
};
enum AnimateMode {ANIM_MODE_NONE = 0, ANIM_MODE_1 = 1, ANIM_MODE_2 = 2, ANIM_MODE_3 = 3,
@@ -504,8 +518,8 @@ private:
int getNewFrame();
void animEnded();
- int changeFrame();
public:
+ int changeFrame();
uint32 _updateStartFrame;
uint32 _walkStartFrame;
Common::Point _field2E;
@@ -528,8 +542,15 @@ public:
EventHandler *_mover;
Common::Point _moveDiff;
int _moveRate;
+ Common::Point _field8A;
Action *_endAction;
uint32 _regionBitList;
+
+ // Ringworld 2 specific fields
+ byte *_field9C;
+ int _shade, _shade2;
+ int _effect;
+ SceneObject *_linkedActor;
public:
SceneObject();
SceneObject(const SceneObject &so);
@@ -577,6 +598,8 @@ public:
// New methods introduced by Blue Force
virtual void updateAngle(const Common::Point &pt);
virtual void changeAngle(int angle);
+ // New methods introduced by Ringworld 2
+ virtual void copy(SceneObject *src);
void setup(int visage, int stripFrameNum, int frameNum, int posX, int posY, int priority);
void setup(int visage, int stripFrameNum, int frameNum);
@@ -587,6 +610,8 @@ public:
virtual Common::String getClassName() { return "BackgroundSceneObject"; }
virtual void postInit(SceneObjectList *OwnerList = NULL);
virtual void draw();
+ void setup2(int visage, int stripFrameNum, int frameNum, int posX, int posY, int priority, int32 arg10);
+ void proc27();
};
class SceneText : public SceneObject {
@@ -610,12 +635,23 @@ public:
virtual void updateScreen();
};
+#define MAX_CHARACTERS 4
+enum R2RCharacter { R2_NONE = 0, R2_QUINN = 1, R2_SEEKER = 2, R2_MIRANDA = 3 };
+
class Player : public SceneObject {
public:
bool _canWalk;
bool _uiEnabled;
int _field8C;
bool _enabled;
+
+ // Return to Ringworld specific fields
+ R2RCharacter _characterIndex;
+ int _characterScene[MAX_CHARACTERS];
+ int _oldCharacterScene[MAX_CHARACTERS];
+ Common::Point _characterPos[MAX_CHARACTERS];
+ int _characterStrip[MAX_CHARACTERS];
+ int _characterFrame[MAX_CHARACTERS];
public:
Player();
@@ -626,6 +662,8 @@ public:
void disableControl();
void enableControl();
+ void disableControl(CursorType cursorId, CursorType objectId = CURSOR_NONE);
+ void enableControl(CursorType cursorId, CursorType objectId = CURSOR_NONE);
};
/*--------------------------------------------------------------------------*/
@@ -801,8 +839,11 @@ public:
Common::Array<WRField18> _field18;
Common::Array<int> _idxList;
Common::Array<int> _idxList2;
+ Common::List<int> _disabledRegions;
public:
WalkRegions() { _resNum = -1; }
+ virtual ~WalkRegions() {}
+ virtual void synchronize(Serializer &s);
void clear();
void load(int sceneNum);
@@ -811,8 +852,8 @@ public:
assert((idx >= 1) && (idx <= (int)_regionList.size()));
return _regionList[idx - 1];
}
- void proc1(int v) { warning("TODO: WalkRegions::proc1"); }
- void proc2(int v) { warning("TODO: WalkRegions::proc2"); }
+ void disableRegion(int regionId);
+ void enableRegion(int regionId);
};
/*--------------------------------------------------------------------------*/
diff --git a/engines/tsage/debugger.cpp b/engines/tsage/debugger.cpp
index a0e8b9edba..82645f2d62 100644
--- a/engines/tsage/debugger.cpp
+++ b/engines/tsage/debugger.cpp
@@ -24,6 +24,8 @@
#include "tsage/globals.h"
#include "tsage/graphics.h"
#include "tsage/ringworld/ringworld_logic.h"
+#include "tsage/blue_force/blueforce_logic.h"
+#include "tsage/ringworld2/ringworld2_logic.h"
namespace TsAGE {
@@ -95,6 +97,10 @@ bool Debugger::Cmd_WalkRegions(int argc, const char **argv) {
for (uint regionIndex = 0; regionIndex < g_globals->_walkRegions._regionList.size(); ++regionIndex, ++color) {
WalkRegion &wr = g_globals->_walkRegions._regionList[regionIndex];
+ // Skip the region if it's in the list of explicitly disabled regions
+ if (contains(g_globals->_walkRegions._disabledRegions, (int)regionIndex + 1))
+ continue;
+
for (int yp = wr._bounds.top; yp < wr._bounds.bottom; ++yp) {
LineSliceSet sliceSet = wr.getLineSlices(yp);
@@ -269,10 +275,88 @@ bool Debugger::Cmd_ClearFlag(int argc, const char **argv) {
return true;
}
+/**
+ * Show any active hotspot areas in the scene
+ */
+bool Debugger::Cmd_Hotspots(int argc, const char **argv) {
+ int colIndex = 16;
+ const Rect &sceneBounds = g_globals->_sceneManager._scene->_sceneBounds;
+
+ // Lock the background surface for access
+ Graphics::Surface destSurface = g_globals->_sceneManager._scene->_backSurface.lockSurface();
+
+ // Iterate through the scene items
+ SynchronizedList<SceneItem *>::iterator i;
+ for (i = g_globals->_sceneItems.reverse_begin(); i != g_globals->_sceneItems.end(); --i, ++colIndex) {
+ SceneItem *o = *i;
+
+ // Draw the contents of the hotspot area
+ if (o->_sceneRegionId == 0) {
+ // Scene item doesn't use a region, so fill in the entire area
+ if ((o->_bounds.right > o->_bounds.left) && (o->_bounds.bottom > o->_bounds.top))
+ destSurface.fillRect(Rect(o->_bounds.left - sceneBounds.left, o->_bounds.top - sceneBounds.top,
+ o->_bounds.right - sceneBounds.left - 1, o->_bounds.bottom - sceneBounds.top - 1), colIndex);
+ } else {
+ // Scene uses a region, so get it and use it to fill out only the correct parts
+ SceneRegions::iterator ri = g_globals->_sceneRegions.begin();
+ while ((ri != g_globals->_sceneRegions.end()) && ((*ri)._regionId != o->_sceneRegionId))
+ ++ri;
+
+ if (ri != g_globals->_sceneRegions.end()) {
+ // Fill out the areas defined by the region
+ Region &r = *ri;
+
+ for (int y = r._bounds.top; y < r._bounds.bottom; ++y) {
+ 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,
+ set.items[p].xe - sceneBounds.left - 1, colIndex);
+ }
+ }
+ }
+ }
+
+ // Release the surface
+ g_globals->_sceneManager._scene->_backSurface.unlockSurface();
+
+ // Mark the scene as requiring a full redraw
+ g_globals->_paneRefreshFlag[0] = 2;
+
+ return false;
+}
+
+/**
+ * Play the specified sound
+ */
+bool Debugger::Cmd_Sound(int argc, const char **argv) {
+ if (argc != 2) {
+ DebugPrintf("Usage: %s <sound number>\n", argv[0]);
+ return true;
+ }
+
+ int soundNum = strToInt(argv[1]);
+ g_globals->_soundHandler.play(soundNum);
+ return false;
+}
+
+/*
+ * This command lists the objects available, and their ID
+ */
+bool DemoDebugger::Cmd_ListObjects(int argc, const char **argv) {
+ DebugPrintf("Not available in Demo\n");
+ return true;
+}
+
+bool DemoDebugger::Cmd_MoveObject(int argc, const char **argv) {
+ DebugPrintf("Not available in Demo\n");
+ return true;
+}
+
/*
* This command lists the objects available, and their ID
*/
-bool Debugger::Cmd_ListObjects(int argc, const char **argv) {
+bool RingworldDebugger::Cmd_ListObjects(int argc, const char **argv) {
if (argc != 1) {
DebugPrintf("Usage: %s\n", argv[0]);
return true;
@@ -318,7 +402,7 @@ bool Debugger::Cmd_ListObjects(int argc, const char **argv) {
/*
* This command gets an item, or move it to a room
*/
-bool Debugger::Cmd_MoveObject(int argc, const char **argv) {
+bool RingworldDebugger::Cmd_MoveObject(int argc, const char **argv) {
// Check for a flag to clear
if ((argc < 2) || (argc > 3)){
DebugPrintf("Usage: %s <object number> [<scene number>]\n", argv[0]);
@@ -439,69 +523,188 @@ bool Debugger::Cmd_MoveObject(int argc, const char **argv) {
return true;
}
-/**
- * Show any active hotspot areas in the scene
+/*
+ * This command lists the objects available, and their ID
*/
-bool Debugger::Cmd_Hotspots(int argc, const char **argv) {
- int colIndex = 16;
- const Rect &sceneBounds = g_globals->_sceneManager._scene->_sceneBounds;
-
- // Lock the background surface for access
- Graphics::Surface destSurface = g_globals->_sceneManager._scene->_backSurface.lockSurface();
-
- // Iterate through the scene items
- SynchronizedList<SceneItem *>::iterator i;
- for (i = g_globals->_sceneItems.reverse_begin(); i != g_globals->_sceneItems.end(); --i, ++colIndex) {
- SceneItem *o = *i;
-
- // Draw the contents of the hotspot area
- if (o->_sceneRegionId == 0) {
- // Scene item doesn't use a region, so fill in the entire area
- if ((o->_bounds.right > o->_bounds.left) && (o->_bounds.bottom > o->_bounds.top))
- destSurface.fillRect(Rect(o->_bounds.left - sceneBounds.left, o->_bounds.top - sceneBounds.top,
- o->_bounds.right - sceneBounds.left - 1, o->_bounds.bottom - sceneBounds.top - 1), colIndex);
- } else {
- // Scene uses a region, so get it and use it to fill out only the correct parts
- SceneRegions::iterator ri = g_globals->_sceneRegions.begin();
- while ((ri != g_globals->_sceneRegions.end()) && ((*ri)._regionId != o->_sceneRegionId))
- ++ri;
+bool BlueForceDebugger::Cmd_ListObjects(int argc, const char **argv) {
+ if (argc != 1) {
+ DebugPrintf("Usage: %s\n", argv[0]);
+ return true;
+ }
- if (ri != g_globals->_sceneRegions.end()) {
- // Fill out the areas defined by the region
- Region &r = *ri;
-
- for (int y = r._bounds.top; y < r._bounds.bottom; ++y) {
- LineSliceSet set = r.getLineSlices(y);
+ DebugPrintf("Available objects for this game are:\n");
+ DebugPrintf("1 - INV_COLT45\n");
+ DebugPrintf("2 - INV_AMMO_CLIP\n");
+ DebugPrintf("3 - INV_SPARE_CLIP\n");
+ DebugPrintf("4 - INV_HANDCUFFS\n");
+ DebugPrintf("5 - INV_GREENS_GUN\n");
+ DebugPrintf("6 - INV_TICKET_BOOK\n");
+ DebugPrintf("7 - INV_MIRANDA_CARD\n");
+ DebugPrintf("8 - INV_FOREST_RAP\n");
+ DebugPrintf("9 - INV_GREEN_ID\n");
+ DebugPrintf("10 - INV_BASEBALL_CARD\n");
+ DebugPrintf("11 - INV_BOOKING_GREEN\n");
+ DebugPrintf("12 - INV_FLARE\n");
+ DebugPrintf("13 - INV_COBB_RAP\n");
+ DebugPrintf("14 - INV_22_BULLET\n");
+ DebugPrintf("15 - INV_AUTO_RIFLE\n");
+ DebugPrintf("16 - INV_WIG\n");
+ DebugPrintf("17 - INV_FRANKIE_ID\n");
+ DebugPrintf("18 - INV_TYRONE_ID\n");
+ DebugPrintf("19 - INV_22_SNUB\n");
+ DebugPrintf("20 - INV_BOOKING_FRANKIE\n");
+ DebugPrintf("21 - INV_BOOKING_GANG\n");
+ DebugPrintf("22 - INV_FBI_TELETYPE\n");
+ DebugPrintf("23 - INV_DA_NOTE\n");
+ DebugPrintf("24 - INV_PRINT_OUT\n");
+ DebugPrintf("25 - INV_WAREHOUSE_KEYS\n");
+ DebugPrintf("26 - INV_CENTER_PUNCH\n");
+ DebugPrintf("27 - INV_TRANQ_GUN\n");
+ DebugPrintf("28 - INV_HOOK\n");
+ DebugPrintf("29 - INV_RAGS\n");
+ DebugPrintf("30 - INV_JAR\n");
+ DebugPrintf("31 - INV_SCREWDRIVER\n");
+ DebugPrintf("32 - INV_D_FLOPPY\n");
+ DebugPrintf("33 - INV_BLANK_DISK\n");
+ DebugPrintf("34 - INV_STICK\n");
+ DebugPrintf("35 - INV_CRATE1\n");
+ DebugPrintf("36 - INV_CRATE2\n");
+ DebugPrintf("37 - INV_SHOEBOX\n");
+ DebugPrintf("38 - INV_BADGE\n");
+ DebugPrintf("39 - INV_RENTAL_COUPON\n");
+ DebugPrintf("40 - INV_NICKEL\n");
+ DebugPrintf("41 - INV_LYLE_CARD\n");
+ DebugPrintf("42 - INV_CARTER_NOTE\n");
+ DebugPrintf("43 - INV_MUG_SHOT\n");
+ DebugPrintf("44 - INV_CLIPPING\n");
+ DebugPrintf("45 - INV_MICROFILM \n");
+ DebugPrintf("46 - INV_WAVE_KEYS\n");
+ DebugPrintf("47 - INV_RENTAL_KEYS\n");
+ DebugPrintf("48 - INV_NAPKIN\n");
+ DebugPrintf("49 - INV_DMV_PRINTOUT\n");
+ DebugPrintf("50 - INV_FISHING_NET\n");
+ DebugPrintf("51 - INV_ID\n");
+ DebugPrintf("52 - INV_9MM_BULLETS\n");
+ DebugPrintf("53 - INV_SCHEDULE\n");
+ DebugPrintf("54 - INV_GRENADES\n");
+ DebugPrintf("55 - INV_YELLOW_CORD\n");
+ DebugPrintf("56 - INV_HALF_YELLOW_CORD\n");
+ DebugPrintf("57 - INV_BLACK_CORD\n");
+ DebugPrintf("58 - INV_HALF_BLACK_CORD\n");
+ DebugPrintf("59 - INV_WARRANT\n");
+ DebugPrintf("60 - INV_JACKET\n");
+ DebugPrintf("61 - INV_GREENS_KNIFE\n");
+ DebugPrintf("62 - INV_DOG_WHISTLE\n");
+ DebugPrintf("63 - INV_AMMO_BELT\n");
+ DebugPrintf("64 - INV_CARAVAN_KEY\n");
+ return true;
+}
- for (uint p = 0; p < set.items.size(); ++p)
- destSurface.hLine(set.items[p].xs - sceneBounds.left, y - sceneBounds.top,
- set.items[p].xe - sceneBounds.left - 1, colIndex);
- }
- }
- }
+bool BlueForceDebugger::Cmd_MoveObject(int argc, const char **argv) {
+ // Check for a flag to clear
+ if ((argc < 2) || (argc > 3)){
+ DebugPrintf("Usage: %s <object number> [<scene number>]\n", argv[0]);
+ DebugPrintf("If no scene is specified, the object will be added to inventory\n");
+ return true;
}
- // Release the surface
- g_globals->_sceneManager._scene->_backSurface.unlockSurface();
+ int objNum = strToInt(argv[1]);
+ int sceneNum = 1;
+ if (argc == 3)
+ sceneNum = strToInt(argv[2]);
- // Mark the scene as requiring a full redraw
- g_globals->_paneRefreshFlag[0] = 2;
+ if ((objNum > 0) && (objNum < 65))
+ BF_INVENTORY.setObjectScene(objNum, sceneNum);
+ else
+ DebugPrintf("Invalid object Id %s\n", argv[1]);
- return false;
+ return true;
}
-/**
- * Play the specified sound
+/*
+ * This command lists the objects available, and their ID
*/
-bool Debugger::Cmd_Sound(int argc, const char **argv) {
- if (argc != 2) {
- DebugPrintf("Usage: %s <sound number>\n", argv[0]);
+bool Ringworld2Debugger::Cmd_ListObjects(int argc, const char **argv) {
+ if (argc != 1) {
+ DebugPrintf("Usage: %s\n", argv[0]);
return true;
}
- int soundNum = strToInt(argv[1]);
- g_globals->_soundHandler.play(soundNum);
- return false;
+ DebugPrintf("Available objects for this game are:\n");
+ DebugPrintf("1 - R2_OPTO_DISK\n");
+ DebugPrintf("2 - R2_2\n");
+ DebugPrintf("3 - R2_NEGATOR_GUN\n");
+ DebugPrintf("4 - R2_STEPPING_DISKS\n");
+ DebugPrintf("5 - R2_5\n");
+ DebugPrintf("6 - R2_6\n");
+ DebugPrintf("7 - R2_7\n");
+ DebugPrintf("8 - R2_8\n");
+ DebugPrintf("9 - R2_9\n");
+ DebugPrintf("10 - R2_10\n");
+ DebugPrintf("11 - R2_11\n");
+ DebugPrintf("12 - R2_12\n");
+ DebugPrintf("13 - R2_13\n");
+ DebugPrintf("14 - R2_14\n");
+ DebugPrintf("15 - R2_15\n");
+ DebugPrintf("16 - R2_16\n");
+ DebugPrintf("17 - R2_17\n");
+ DebugPrintf("18 - R2_18\n");
+ DebugPrintf("19 - R2_19\n");
+ DebugPrintf("20 - R2_20\n");
+ DebugPrintf("21 - R2_21\n");
+ DebugPrintf("22 - R2_22\n");
+ DebugPrintf("23 - R2_23\n");
+ DebugPrintf("24 - R2_24\n");
+ DebugPrintf("25 - R2_25\n");
+ DebugPrintf("26 - R2_26\n");
+ DebugPrintf("27 - R2_27\n");
+ DebugPrintf("28 - R2_28\n");
+ DebugPrintf("29 - R2_29\n");
+ DebugPrintf("30 - R2_30\n");
+ DebugPrintf("31 - R2_31\n");
+ DebugPrintf("32 - R2_32\n");
+ DebugPrintf("33 - R2_33\n");
+ DebugPrintf("34 - R2_34\n");
+ DebugPrintf("35 - R2_35\n");
+ DebugPrintf("36 - R2_36\n");
+ DebugPrintf("37 - R2_37\n");
+ DebugPrintf("38 - R2_38\n");
+ DebugPrintf("39 - R2_39\n");
+ DebugPrintf("40 - R2_40\n");
+ DebugPrintf("41 - R2_41\n");
+ DebugPrintf("42 - R2_42\n");
+ DebugPrintf("43 - R2_43\n");
+ DebugPrintf("44 - R2_44\n");
+ DebugPrintf("45 - R2_45\n");
+ DebugPrintf("46 - R2_46\n");
+ DebugPrintf("47 - R2_47\n");
+ DebugPrintf("48 - R2_48\n");
+ DebugPrintf("49 - R2_49\n");
+ DebugPrintf("50 - R2_50\n");
+ DebugPrintf("51 - R2_51\n");
+ DebugPrintf("52 - R2_52\n");
+
+ return true;
}
+bool Ringworld2Debugger::Cmd_MoveObject(int argc, const char **argv) {
+ // Check for a flag to clear
+ if ((argc < 2) || (argc > 3)){
+ DebugPrintf("Usage: %s <object number> [<scene number>]\n", argv[0]);
+ DebugPrintf("If no scene is specified, the object will be added to inventory\n");
+ return true;
+ }
+
+ int objNum = strToInt(argv[1]);
+ int sceneNum = 1;
+ if (argc == 3)
+ sceneNum = strToInt(argv[2]);
+
+ if ((objNum > 0) && (objNum < 53))
+ R2_INVENTORY.setObjectScene(objNum, sceneNum);
+ else
+ DebugPrintf("Invalid object Id %s\n", argv[1]);
+
+ return true;
+}
} // End of namespace TsAGE
diff --git a/engines/tsage/debugger.h b/engines/tsage/debugger.h
index fcdbc2d243..bf826a3f77 100644
--- a/engines/tsage/debugger.h
+++ b/engines/tsage/debugger.h
@@ -41,10 +41,34 @@ protected:
bool Cmd_SetFlag(int argc, const char **argv);
bool Cmd_GetFlag(int argc, const char **argv);
bool Cmd_ClearFlag(int argc, const char **argv);
- bool Cmd_ListObjects(int argc, const char **argv);
- bool Cmd_MoveObject(int argc, const char **argv);
bool Cmd_Hotspots(int argc, const char **argv);
bool Cmd_Sound(int argc, const char **argv);
+ virtual bool Cmd_ListObjects(int argc, const char **argv) = 0;
+ virtual bool Cmd_MoveObject(int argc, const char **argv) = 0;
+};
+
+class DemoDebugger : public Debugger {
+protected:
+ virtual bool Cmd_ListObjects(int argc, const char **argv);
+ virtual bool Cmd_MoveObject(int argc, const char **argv);
+};
+
+class RingworldDebugger : public Debugger {
+protected:
+ virtual bool Cmd_ListObjects(int argc, const char **argv);
+ virtual bool Cmd_MoveObject(int argc, const char **argv);
+};
+
+class BlueForceDebugger : public Debugger {
+protected:
+ virtual bool Cmd_ListObjects(int argc, const char **argv);
+ virtual bool Cmd_MoveObject(int argc, const char **argv);
+};
+
+class Ringworld2Debugger : public Debugger {
+protected:
+ virtual bool Cmd_ListObjects(int argc, const char **argv);
+ virtual bool Cmd_MoveObject(int argc, const char **argv);
};
} // End of namespace TsAGE
diff --git a/engines/tsage/detection.cpp b/engines/tsage/detection.cpp
index 12add10c58..0c458f5c35 100644
--- a/engines/tsage/detection.cpp
+++ b/engines/tsage/detection.cpp
@@ -74,7 +74,6 @@ enum {
class TSageMetaEngine : public AdvancedMetaEngine {
public:
TSageMetaEngine() : AdvancedMetaEngine(TsAGE::gameDescriptions, sizeof(TsAGE::tSageGameDescription), tSageGameTitles) {
- _md5Bytes = 5000;
_singleid = "tsage";
_guioptions = GUIO1(GUIO_NOSPEECH);
}
diff --git a/engines/tsage/detection_tables.h b/engines/tsage/detection_tables.h
index 360dbac0ae..d538cbacbf 100644
--- a/engines/tsage/detection_tables.h
+++ b/engines/tsage/detection_tables.h
@@ -105,7 +105,7 @@ static const tSageGameDescription gameDescriptions[] = {
AD_ENTRY1s("blue.rlb", "17c3993415e8a2cf93040eef7e88ec93", 1156508),
Common::EN_ANY,
Common::kPlatformPC,
- ADGF_UNSTABLE,
+ ADGF_TESTING,
GUIO2(GUIO_NOSPEECH, GUIO_NOSFX)
},
GType_BlueForce,
@@ -120,7 +120,7 @@ static const tSageGameDescription gameDescriptions[] = {
AD_ENTRY1s("blue.rlb", "17eabb456cb1546c66baf1aff387ba6a", 10032614),
Common::EN_ANY,
Common::kPlatformPC,
- ADGF_UNSTABLE,
+ ADGF_TESTING,
GUIO2(GUIO_NOSPEECH, GUIO_NOSFX)
},
GType_BlueForce,
@@ -134,13 +134,29 @@ static const tSageGameDescription gameDescriptions[] = {
AD_ENTRY1s("blue.rlb", "99983f48cb218f1f3760cf2f9a7ef11d", 63863322),
Common::EN_ANY,
Common::kPlatformPC,
- ADGF_CD | ADGF_UNSTABLE,
+ ADGF_CD | ADGF_TESTING,
GUIO2(GUIO_NOSPEECH, GUIO_NOSFX)
},
GType_BlueForce,
GF_CD | GF_ALT_REGIONS
},
-
+#if 0
+ // Blue Force Spanish doesn't yet work
+ // Blue Force Spanish CD
+ {
+ {
+ "blueforce",
+ "CD",
+ AD_ENTRY1s("blue.rlb", "5b2b35c51b62e82d82b0791540bfae2d", 10082565),
+ Common::ES_ESP,
+ Common::kPlatformPC,
+ ADGF_CD | ADGF_TESTING,
+ GUIO2(GUIO_NOSPEECH, GUIO_NOSFX)
+ },
+ GType_BlueForce,
+ GF_CD | GF_ALT_REGIONS
+ },
+#endif
// Return to Ringworld
{
{
@@ -150,7 +166,7 @@ static const tSageGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformPC,
ADGF_CD | ADGF_UNSTABLE,
- GUIO2(GUIO_NOSPEECH, GUIO_NOSFX)
+ GUIO0()
},
GType_Ringworld2,
GF_CD | GF_ALT_REGIONS
diff --git a/engines/tsage/dialogs.cpp b/engines/tsage/dialogs.cpp
index 002835e76b..972d591c34 100644
--- a/engines/tsage/dialogs.cpp
+++ b/engines/tsage/dialogs.cpp
@@ -181,242 +181,6 @@ void ModalDialog::drawFrame() {
/*--------------------------------------------------------------------------*/
-bool GfxInvImage::process(Event &event) {
- if (!event.handled && (event.eventType == EVENT_BUTTON_DOWN)) {
- event.handled = _bounds.contains(event.mousePos);
- return event.handled;
- }
-
- return false;
-}
-
-/*--------------------------------------------------------------------------*/
-
-void InventoryDialog::show() {
- // Determine how many items are in the player's inventory
- int itemCount = 0;
- SynchronizedList<InvObject *>::iterator i;
- for (i = RING_INVENTORY._itemList.begin(); i != RING_INVENTORY._itemList.end(); ++i) {
- if ((*i)->inInventory())
- ++itemCount;
- }
-
- if (itemCount == 0) {
- MessageDialog::show(INV_EMPTY_MSG, OK_BTN_STRING);
- return;
- }
-
- InventoryDialog *dlg = new InventoryDialog();
- dlg->draw();
- dlg->execute();
- delete dlg;
-}
-
-InventoryDialog::InventoryDialog() {
- // Determine the maximum size of the image of any item in the player's inventory
- int imgWidth = 0, imgHeight = 0;
-
- SynchronizedList<InvObject *>::iterator i;
- for (i = RING_INVENTORY._itemList.begin(); i != RING_INVENTORY._itemList.end(); ++i) {
- InvObject *invObject = *i;
- if (invObject->inInventory()) {
- // Get the image for the item
- GfxSurface itemSurface = surfaceFromRes(invObject->_displayResNum, invObject->_rlbNum, invObject->_cursorNum);
-
- // Maintain the dimensions of the largest item image
- imgWidth = MAX(imgWidth, (int)itemSurface.getBounds().width());
- imgHeight = MAX(imgHeight, (int)itemSurface.getBounds().height());
-
- // Add the item to the display list
- GfxInvImage *img = new GfxInvImage();
- _images.push_back(img);
- img->setDetails(invObject->_displayResNum, invObject->_rlbNum, invObject->_cursorNum);
- img->_invObject = invObject;
- add(img);
- }
- }
- assert(_images.size() > 0);
-
- // Figure out the number of columns/rows to show all the items
- int cellsSize = 3;
- while ((cellsSize * cellsSize) < (int)_images.size())
- ++cellsSize;
-
- // Set the position of each inventory item to be displayed
- int cellX = 0;
- Common::Point pt(0, 0);
-
- for (uint idx = 0; idx < _images.size(); ++idx) {
- if (cellX == cellsSize) {
- // Move to the start of the next line
- pt.x = 0;
- pt.y += imgHeight + 2;
- cellX = 0;
- }
-
- _images[idx]->_bounds.moveTo(pt.x, pt.y);
-
- pt.x += imgWidth + 2;
- ++cellX;
- }
-
- // Set up the buttons
- pt.y += imgHeight + 2;
- _btnOk.setText(OK_BTN_STRING);
- _btnOk._bounds.moveTo((imgWidth + 2) * cellsSize - _btnOk._bounds.width(), pt.y);
- _btnLook.setText(LOOK_BTN_STRING);
- _btnLook._bounds.moveTo(_btnOk._bounds.left - _btnLook._bounds.width() - 2, _btnOk._bounds.top);
- addElements(&_btnLook, &_btnOk, NULL);
-
- frame();
- setCenter(SCREEN_CENTER_X, SCREEN_CENTER_Y);
-}
-
-InventoryDialog::~InventoryDialog() {
- for (uint idx = 0; idx < _images.size(); ++idx)
- delete _images[idx];
-}
-
-void InventoryDialog::execute() {
- if ((RING_INVENTORY._selectedItem) && RING_INVENTORY._selectedItem->inInventory())
- RING_INVENTORY._selectedItem->setCursor();
-
- GfxElement *hiliteObj;
- bool lookFlag = false;
- _gfxManager.activate();
-
- while (!g_vm->shouldQuit()) {
- // Get events
- Event event;
- while (!g_globals->_events.getEvent(event) && !g_vm->shouldQuit()) {
- g_system->delayMillis(10);
- g_system->updateScreen();
- }
- if (g_vm->shouldQuit())
- break;
-
- hiliteObj = NULL;
- if ((event.eventType == EVENT_BUTTON_DOWN) && !_bounds.contains(event.mousePos))
- break;
-
- // Pass event to elements
- event.mousePos.x -= _gfxManager._bounds.left;
- event.mousePos.y -= _gfxManager._bounds.top;
-
- for (GfxElementList::iterator i = _elements.begin(); i != _elements.end(); ++i) {
- if ((*i)->process(event))
- hiliteObj = *i;
- }
-
- if (!event.handled && event.eventType == EVENT_KEYPRESS) {
- if ((event.kbd.keycode == Common::KEYCODE_RETURN) || (event.kbd.keycode == Common::KEYCODE_ESCAPE)) {
- // Exit the dialog
- //hiliteObj = &_btnOk;
- break;
- }
- }
-
- if (hiliteObj == &_btnOk) {
- // Ok button clicked
- if (lookFlag)
- g_globals->_events.setCursor(CURSOR_WALK);
- break;
- } else if (hiliteObj == &_btnLook) {
- // Look button clicked
- if (_btnLook._message == LOOK_BTN_STRING) {
- _btnLook._message = PICK_BTN_STRING;
- lookFlag = 1;
- g_globals->_events.setCursor(CURSOR_LOOK);
- } else {
- _btnLook._message = LOOK_BTN_STRING;
- lookFlag = 0;
- g_globals->_events.setCursor(CURSOR_WALK);
- }
-
- hiliteObj->draw();
- } else if (hiliteObj) {
- // Inventory item selected
- InvObject *invObject = static_cast<GfxInvImage *>(hiliteObj)->_invObject;
- if (lookFlag) {
- g_globals->_screenSurface.displayText(invObject->_description);
- } else {
- RING_INVENTORY._selectedItem = invObject;
- invObject->setCursor();
- }
- }
- }
-
- _gfxManager.deactivate();
-}
-
-/*--------------------------------------------------------------------------*/
-
-void OptionsDialog::show() {
- OptionsDialog *dlg = new OptionsDialog();
- dlg->draw();
-
- GfxButton *btn = dlg->execute();
-
- if (btn == &dlg->_btnQuit) {
- // Quit game
- if (MessageDialog::show(QUIT_CONFIRM_MSG, CANCEL_BTN_STRING, QUIT_BTN_STRING) == 1) {
- g_vm->quitGame();
- }
- } else if (btn == &dlg->_btnRestart) {
- // Restart game
- g_globals->_game->restartGame();
- } else if (btn == &dlg->_btnSound) {
- // Sound dialog
- SoundDialog::execute();
- } else if (btn == &dlg->_btnSave) {
- // Save button
- g_globals->_game->saveGame();
- } else if (btn == &dlg->_btnRestore) {
- // Restore button
- g_globals->_game->restoreGame();
- }
-
- dlg->remove();
- delete dlg;
-}
-
-OptionsDialog::OptionsDialog() {
- // Set the element text
- _gfxMessage.set(OPTIONS_MSG, 140, ALIGN_LEFT);
- _btnRestore.setText(RESTORE_BTN_STRING);
- _btnSave.setText(SAVE_BTN_STRING);
- _btnRestart.setText(RESTART_BTN_STRING);
- _btnQuit.setText(QUIT_BTN_STRING);
- _btnSound.setText(SOUND_BTN_STRING);
- _btnResume.setText(RESUME_BTN_STRING);
-
- // Set position of the elements
- _gfxMessage._bounds.moveTo(0, 1);
- _btnRestore._bounds.moveTo(0, _gfxMessage._bounds.bottom + 1);
- _btnSave._bounds.moveTo(0, _btnRestore._bounds.bottom + 1);
- _btnRestart._bounds.moveTo(0, _btnSave._bounds.bottom + 1);
- _btnQuit._bounds.moveTo(0, _btnRestart._bounds.bottom + 1);
- _btnSound._bounds.moveTo(0, _btnQuit._bounds.bottom + 1);
- _btnResume._bounds.moveTo(0, _btnSound._bounds.bottom + 1);
-
- // Set all the buttons to the widest button
- GfxButton *btnList[6] = {&_btnRestore, &_btnSave, &_btnRestart, &_btnQuit, &_btnSound, &_btnResume};
- int16 btnWidth = 0;
- for (int idx = 0; idx < 6; ++idx)
- btnWidth = MAX(btnWidth, btnList[idx]->_bounds.width());
- for (int idx = 0; idx < 6; ++idx)
- btnList[idx]->_bounds.setWidth(btnWidth);
-
- // Add the items to the dialog
- addElements(&_gfxMessage, &_btnRestore, &_btnSave, &_btnRestart, &_btnQuit, &_btnSound, &_btnResume, NULL);
-
- // Set the dialog size and position
- frame();
- setCenter(160, 100);
-}
-
-/*--------------------------------------------------------------------------*/
-
void SoundDialog::execute() {
ConfigDialog *dlg = new ConfigDialog();
dlg->runModal();
diff --git a/engines/tsage/dialogs.h b/engines/tsage/dialogs.h
index 35ed60ba1a..33b55093d0 100644
--- a/engines/tsage/dialogs.h
+++ b/engines/tsage/dialogs.h
@@ -60,47 +60,6 @@ public:
/*--------------------------------------------------------------------------*/
-class GfxInvImage : public GfxImage {
-public:
- InvObject *_invObject;
-public:
- GfxInvImage() : GfxImage(), _invObject(NULL) {}
-
- virtual bool process(Event &event);
-};
-
-#define MAX_INVOBJECT_DISPLAY 20
-
-class InventoryDialog : public ModalDialog {
-private:
- Common::Array<GfxInvImage *> _images;
- GfxButton _btnOk, _btnLook;
-public:
- InventoryDialog();
- virtual ~InventoryDialog();
- void execute();
-
- static void show();
-};
-
-/*--------------------------------------------------------------------------*/
-
-class OptionsDialog : public ModalDialog {
-private:
- GfxButton _btnSave, _btnRestore, _btnRestart;
- GfxButton _btnQuit, _btnResume;
- GfxButton _btnSound;
- GfxMessage _gfxMessage;
-public:
- OptionsDialog();
- virtual ~OptionsDialog() {}
- GfxButton *execute() { return GfxDialog::execute(&_btnResume); }
-
- static void show();
-};
-
-/*--------------------------------------------------------------------------*/
-
class SoundDialog {
public:
static void execute();
diff --git a/engines/tsage/events.cpp b/engines/tsage/events.cpp
index 073cbc35b9..8f07a8243b 100644
--- a/engines/tsage/events.cpp
+++ b/engines/tsage/events.cpp
@@ -50,7 +50,7 @@ bool EventsClass::pollEvent() {
++_frameNumber;
// Update screen
- g_system->updateScreen();
+ GLOBALS._screenSurface.updateScreen();
}
if (!g_system->getEventManager()->pollEvent(_event)) return false;
@@ -221,7 +221,8 @@ void EventsClass::setCursor(CursorType cursorType) {
case CURSOR_WALK:
default:
- if (g_vm->getGameID() == GType_BlueForce) {
+ switch (g_vm->getGameID()) {
+ case GType_BlueForce:
if (cursorType == CURSOR_WALK) {
cursor = g_resourceManager->getSubResource(1, 5, 1, &size);
} else {
@@ -231,13 +232,45 @@ void EventsClass::setCursor(CursorType cursorType) {
questionEnabled = true;
}
_currentCursor = cursorType;
- } else {
+ break;
+ case GType_Ringworld2:
+ if (cursorType == CURSOR_WALK) {
+ cursor = CURSOR_WALK_DATA;
+ delFlag = false;
+ } else {
+ // Inventory icon
+ InvObject *invObject = g_globals->_inventory->getItem((int)cursorType);
+ cursor = g_resourceManager->getSubResource(6, invObject->_strip, invObject->_frame, &size);
+ questionEnabled = true;
+ }
+ _currentCursor = cursorType;
+ break;
+ default:
// For Ringworld, always treat as the walk cursor
cursor = CURSOR_WALK_DATA;
_currentCursor = CURSOR_WALK;
delFlag = false;
+ break;
}
break;
+
+ // Ringworld 2 specific cursors
+ case EXITCURSOR_N:
+ case EXITCURSOR_S:
+ case EXITCURSOR_W:
+ case EXITCURSOR_E:
+ case EXITCURSOR_LEFT_HAND:
+ case CURSOR_INVALID:
+ case EXITCURSOR_NE:
+ case EXITCURSOR_SE:
+ case EXITCURSOR_SW:
+ case EXITCURSOR_NW:
+ case SHADECURSOR_UP:
+ case SHADECURSOR_DOWN:
+ case SHADECURSOR_HAND:
+ _currentCursor = cursorType;
+ cursor = g_resourceManager->getSubResource(5, 1, cursorType - R2CURSORS_START, &size);
+ break;
}
// Decode the cursor
@@ -251,8 +284,8 @@ void EventsClass::setCursor(CursorType cursorType) {
if (delFlag)
DEALLOCATE(cursor);
- // For Blue Force, enable the question button when an inventory icon is selected
- if (g_vm->getGameID() == GType_BlueForce)
+ // For Blue Force and Return to Ringworld, enable the question button when an inventory icon is selected
+ if (g_vm->getGameID() != GType_Ringworld)
T2_GLOBALS._uiElements._question.setEnabled(questionEnabled);
}
@@ -320,7 +353,6 @@ void EventsClass::setCursor(Graphics::Surface &cursor, int transColor, const Com
}
void EventsClass::setCursor(GfxSurface &cursor) {
- // TODO: Find proper parameters for this form in Blue Force
Graphics::Surface s = cursor.lockSurface();
const byte *cursorData = (const byte *)s.getBasePtr(0, 0);
@@ -354,7 +386,7 @@ bool EventsClass::isCursorVisible() const {
*/
void EventsClass::delay(int numFrames) {
while (_frameNumber < (_prevDelayFrame + numFrames)) {
- uint32 delayAmount = CLIP(_priorFrameTime + GAME_FRAME_TIME - g_system->getMillis(),
+ uint32 delayAmount = CLIP(_priorFrameTime + GAME_SCRIPT_TIME - g_system->getMillis(),
(uint32)0, (uint32)GAME_FRAME_TIME);
if (delayAmount > 0)
g_system->delayMillis(delayAmount);
@@ -363,7 +395,7 @@ void EventsClass::delay(int numFrames) {
_priorFrameTime = g_system->getMillis();
}
- g_system->updateScreen();
+ GLOBALS._screenSurface.updateScreen();
_prevDelayFrame = _frameNumber;
_priorFrameTime = g_system->getMillis();
}
diff --git a/engines/tsage/events.h b/engines/tsage/events.h
index 874020f140..475db47315 100644
--- a/engines/tsage/events.h
+++ b/engines/tsage/events.h
@@ -36,9 +36,12 @@ 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)
+// Intrinisc game delay between execution frames
+#define GAME_FRAME_RATE 50
+#define GAME_FRAME_TIME (1000 / GAME_FRAME_RATE)
+
+#define GAME_SCRIPT_RATE 80
+#define GAME_SCRIPT_TIME (1000 / GAME_SCRIPT_RATE)
class GfxManager;
@@ -83,14 +86,28 @@ enum CursorType {
INV_CARAVAN_KEY = 67, BF_LAST_INVENT = 68,
// Ringworld 2 objects
- R2_1 = 1, R2_2 = 2, R2_3 = 3, R2_STEPPING_DISKS = 4, R2_5 = 5, R2_6 = 6, R2_7 = 7,
- R2_8 = 8, R2_9 = 9, R2_10 = 10, R2_11 = 11, R2_12 = 12, R2_13 = 13, R2_14 = 14,
- R2_15 = 15, R2_16 = 16, R2_17 = 17, R2_18 = 18, R2_19 = 19, R2_20 = 20, R2_21 = 21,
- R2_22 = 22, R2_23 = 23, R2_24 = 24, R2_25 = 25, R2_26 = 26, R2_27 = 27, R2_28 = 28,
- R2_29 = 29, R2_30 = 30, R2_31 = 31, R2_32 = 32, R2_33 = 33, R2_34 = 34, R2_35 = 35,
- R2_36 = 36, R2_37 = 37, R2_38 = 38, R2_39 = 39, R2_40 = 40, R2_41 = 41, R2_42 = 42,
- R2_43 = 43, R2_44 = 44, R2_45 = 45, R2_46 = 46, R2_47 = 47, R2_48 = 48, R2_49 = 49,
- R2_50 = 50, R2_51 = 51, R2_52 = 52,
+ R2_OPTO_DISK = 1, R2_READER = 2, R2_NEGATOR_GUN = 3, R2_STEPPING_DISKS = 4,
+ R2_ATTRACTOR_UNIT = 5, R2_SENSOR_PROBE = 6, R2_SONIC_STUNNER = 7,
+ R2_CABLE_HARNESS = 8, R2_COM_SCANNER = 9, R2_SPENT_POWER_CAPSULE = 10,
+ R2_CHARGED_POWER_CAPSULE = 11, R2_AEROSOL = 12, R2_REMOTE_CONTROL = 13,
+ R2_OPTICAL_FIBRE = 14, R2_CLAMP = 15, R2_ATTRACTOR_CABLE_HARNESS = 16,
+ R2_FUEL_CELL = 17, R2_GYROSCOPE = 18, R2_AIRBAG = 19, R2_REBREATHER_TANK = 20,
+ R2_RESERVE_REBREATHER_TANK = 21, R2_GUIDANCE_MODULE = 22, R2_THRUSTER_VALVE = 23,
+ R2_BALLOON_BACKPACK = 24, R2_RADAR_MECHANISM = 25, R2_JOYSTICK = 26,
+ R2_IGNITOR = 27, R2_DIAGNOSTICS_DISPLAY = 28, R2_GLASS_DOME = 29, R2_WICK_LAMP = 30,
+ R2_SCRITH_KEY = 31, R2_TANNER_MASK = 32, R2_PURE_GRAIN_ALCOHOL = 33, R2_SAPPHIRE_BLUE = 34,
+ R2_ANCIENT_SCROLLS = 35, R2_FLUTE = 36, R2_GUNPOWDER = 37, R2_NONAME = 38,
+ R2_COM_SCANNER_2 = 39, R2_SUPERCONDUCTOR_WIRE = 40, R2_PILLOW = 41, R2_FOOD_TRAY = 42,
+ R2_LASER_HACKSAW = 43, R2_PHOTON_STUNNER = 44, R2_BATTERY = 45, R2_SOAKED_FACEMASK = 46,
+ R2_LIGHT_BULB = 47, R2_ALCOHOL_LAMP = 48, R2_ALCOHOL_LAMP_2 = 49, R2_ALCOHOL_LAMP_3 = 50,
+ R2_BROKEN_DISPLAY = 51, R2_TOOLBOX = 52, R2_LAST_INVENT = 53,
+
+ // Ringworld 2 cursors
+ R2CURSORS_START = 0x8000, EXITCURSOR_N = 0x8007, EXITCURSOR_S = 0x8008, EXITCURSOR_W = 0x8009,
+ EXITCURSOR_E = 0x800A, EXITCURSOR_LEFT_HAND = 0x800B, CURSOR_INVALID = 0x800C,
+ EXITCURSOR_NE = 0x800D, EXITCURSOR_SE = 0x800E, EXITCURSOR_SW = 0x800F, EXITCURSOR_NW = 0x8010,
+ SHADECURSOR_UP = 0x8011, SHADECURSOR_DOWN = 0x8012, SHADECURSOR_HAND = 0x8013,
+ R2_CURSOR_20 = 0x8014, R2_CURSOR_21 = 0x8015, R2_CURSOR_22 = 0x8016, R2_CURSOR_23 = 0x8017,
// Cursors
CURSOR_WALK = 0x100, CURSOR_LOOK = 0x200, CURSOR_700 = 700, CURSOR_USE = 0x400, CURSOR_TALK = 0x800,
@@ -132,7 +149,7 @@ public:
Common::EventType type() { return _event.type; }
uint32 getFrameNumber() const { return _frameNumber; }
void delay(int numFrames);
- bool isInventoryIcon() const { return _currentCursor < 256; }
+ bool isInventoryIcon() const { return (_currentCursor >= 0) && (_currentCursor < 256); }
void proc1() { warning("TODO: EventsClass::proc1"); }
virtual void listenerSynchronize(Serializer &s);
diff --git a/engines/tsage/globals.cpp b/engines/tsage/globals.cpp
index 7711e7fba7..59eb59b194 100644
--- a/engines/tsage/globals.cpp
+++ b/engines/tsage/globals.cpp
@@ -78,12 +78,15 @@ Globals::Globals() : _dialogCenter(160, 140), _gfxManagerInstance(_screenSurface
_dialogCenter.y = 140;
} else if (g_vm->getGameID() == GType_Ringworld2) {
// Return to Ringworld
- _gfxFontNumber = 2;
- _gfxColors.background = 89;
- _gfxColors.foreground = 83;
- _fontColors.background = 88;
- _fontColors.foreground = 92;
- _dialogCenter.y = 140;
+ _gfxFontNumber = 50;
+ _gfxColors.background = 0;
+ _gfxColors.foreground = 59;
+ _fontColors.background = 4;
+ _fontColors.foreground = 15;
+ _color1 = 59;
+ _color2 = 15;
+ _color3 = 4;
+ _dialogCenter.y = 100;
} else if ((g_vm->getGameID() == GType_Ringworld) && (g_vm->getFeatures() & GF_CD)) {
_gfxFontNumber = 50;
_gfxColors.background = 53;
@@ -94,6 +97,7 @@ Globals::Globals() : _dialogCenter(160, 140), _gfxManagerInstance(_screenSurface
_color2 = 18;
_color3 = 18;
} else {
+ // Ringworld
_gfxFontNumber = 50;
_gfxColors.background = 53;
_gfxColors.foreground = 18;
@@ -137,7 +141,7 @@ Globals::Globals() : _dialogCenter(160, 140), _gfxManagerInstance(_screenSurface
case GType_Ringworld2:
_inventory = new Ringworld2::Ringworld2InvObjectList();
_game = new Ringworld2::Ringworld2Game();
- _sceneHandler = new SceneHandler();
+ _sceneHandler = new Ringworld2::SceneHandlerExt();
break;
}
}
@@ -151,7 +155,7 @@ Globals::~Globals() {
}
void Globals::reset() {
- Common::set_to(&_flags[0], &_flags[MAX_FLAGS], false);
+ Common::fill(&_flags[0], &_flags[MAX_FLAGS], false);
g_saver->addFactory(classFactoryProc);
}
@@ -184,6 +188,9 @@ void Globals::synchronize(Serializer &s) {
s.syncAsSint16LE(_prevSceneOffset.x); s.syncAsSint16LE(_prevSceneOffset.y);
SYNC_POINTER(_scrollFollower);
s.syncAsSint32LE(_stripNum);
+
+ if (s.getVersion() >= 8)
+ _walkRegions.synchronize(s);
}
void Globals::dispatchSound(ASound *obj) {
@@ -205,6 +212,12 @@ void TsAGE2Globals::reset() {
T2_GLOBALS._uiElements._active = false;
}
+void TsAGE2Globals::synchronize(Serializer &s) {
+ Globals::synchronize(s);
+
+ s.syncAsSint16LE(_interfaceY);
+}
+
/*--------------------------------------------------------------------------*/
namespace BlueForce {
@@ -213,24 +226,27 @@ BlueForceGlobals::BlueForceGlobals(): TsAGE2Globals() {
}
void BlueForceGlobals::synchronize(Serializer &s) {
- Globals::synchronize(s);
+ TsAGE2Globals::synchronize(s);
s.syncAsSint16LE(_dayNumber);
- s.syncAsSint16LE(_v4CEA4);
- s.syncAsSint16LE(_v4CEAA);
+ if (s.getVersion() < 9) {
+ int tmpVar = 0;
+ s.syncAsSint16LE(tmpVar);
+ }
+ s.syncAsSint16LE(_tonyDialogCtr);
s.syncAsSint16LE(_marinaWomanCtr);
- s.syncAsSint16LE(_v4CEB0);
+ s.syncAsSint16LE(_kateDialogCtr);
s.syncAsSint16LE(_v4CEB6);
s.syncAsSint16LE(_safeCombination);
- s.syncAsSint16LE(_v4CEC0);
+ s.syncAsSint16LE(_gateStatus);
s.syncAsSint16LE(_greenDay5TalkCtr);
s.syncAsSint16LE(_v4CEC4);
s.syncAsSint16LE(_v4CEC8);
s.syncAsSint16LE(_v4CECA);
s.syncAsSint16LE(_v4CECC);
for (int i = 0; i < 18; i++)
- s.syncAsByte(_v4CECE[i]);
- s.syncAsSint16LE(_v4CEE0);
+ s.syncAsByte(_breakerBoxStatusArr[i]);
+ s.syncAsSint16LE(_hiddenDoorStatus);
s.syncAsSint16LE(_v4CEE2);
s.syncAsSint16LE(_v4CEE4);
s.syncAsSint16LE(_v4CEE6);
@@ -244,15 +260,14 @@ void BlueForceGlobals::synchronize(Serializer &s) {
s.syncAsSint16LE(_v501FC);
s.syncAsSint16LE(_v5020C);
s.syncAsSint16LE(_v50696);
- s.syncAsSint16LE(_v5098C);
- s.syncAsSint16LE(_v5098D);
+ s.syncAsSint16LE(_subFlagBitArr1);
+ s.syncAsSint16LE(_subFlagBitArr2);
s.syncAsSint16LE(_v50CC2);
s.syncAsSint16LE(_v50CC4);
s.syncAsSint16LE(_v50CC6);
s.syncAsSint16LE(_v50CC8);
s.syncAsSint16LE(_v51C42);
s.syncAsSint16LE(_v51C44);
- s.syncAsSint16LE(_interfaceY);
s.syncAsSint16LE(_bookmark);
s.syncAsSint16LE(_mapLocationId);
s.syncAsSint16LE(_clip1Bullets);
@@ -275,37 +290,36 @@ void BlueForceGlobals::reset() {
_interfaceY = UI_INTERFACE_Y;
_dayNumber = 0;
- _v4CEA4 = 0;
- _v4CEAA = 0;
+ _tonyDialogCtr = 0;
_marinaWomanCtr = 0;
- _v4CEB0 = 0;
+ _kateDialogCtr = 0;
_v4CEB6 = 0;
_safeCombination = 0;
- _v4CEC0 = 0;
+ _gateStatus = 0;
_greenDay5TalkCtr = 0;
_v4CEC4 = 0;
_v4CEC8 = 1;
_v4CECA = 0;
_v4CECC = 0;
- _v4CECE[0] = 2;
- _v4CECE[1] = 2;
- _v4CECE[2] = 2;
- _v4CECE[3] = 1;
- _v4CECE[4] = 2;
- _v4CECE[5] = 2;
- _v4CECE[6] = 2;
- _v4CECE[7] = 2;
- _v4CECE[8] = 2;
- _v4CECE[9] = 2;
- _v4CECE[10] = 2;
- _v4CECE[11] = 2;
- _v4CECE[12] = 1;
- _v4CECE[13] = 1;
- _v4CECE[14] = 2;
- _v4CECE[15] = 2;
- _v4CECE[16] = 3;
- _v4CECE[17] = 0;
- _v4CEE0 = 0;
+ _breakerBoxStatusArr[0] = 2;
+ _breakerBoxStatusArr[1] = 2;
+ _breakerBoxStatusArr[2] = 2;
+ _breakerBoxStatusArr[3] = 1;
+ _breakerBoxStatusArr[4] = 2;
+ _breakerBoxStatusArr[5] = 2;
+ _breakerBoxStatusArr[6] = 2;
+ _breakerBoxStatusArr[7] = 2;
+ _breakerBoxStatusArr[8] = 2;
+ _breakerBoxStatusArr[9] = 2;
+ _breakerBoxStatusArr[10] = 2;
+ _breakerBoxStatusArr[11] = 2;
+ _breakerBoxStatusArr[12] = 1;
+ _breakerBoxStatusArr[13] = 1;
+ _breakerBoxStatusArr[14] = 2;
+ _breakerBoxStatusArr[15] = 2;
+ _breakerBoxStatusArr[16] = 3;
+ _breakerBoxStatusArr[17] = 0;
+ _hiddenDoorStatus = 0;
_v4CEE2 = 0;
_v4CEE4 = 0;
_v4CEE6 = 0;
@@ -317,8 +331,8 @@ void BlueForceGlobals::reset() {
_v501FC = 0;
_v5020C = 0;
_v50696 = 0;
- _v5098C = 0;
- _v5098D = 0;
+ _subFlagBitArr1 = 0;
+ _subFlagBitArr2 = 0;
_v50CC2 = 0;
_v50CC4 = 0;
_v50CC6 = 0;
@@ -359,9 +373,183 @@ void Ringworld2Globals::reset() {
R2_INVENTORY.reset();
T2_GLOBALS._uiElements.updateInventory();
T2_GLOBALS._uiElements._active = false;
-}
+ // Reset fields
+ Common::fill(&_v1000[0], &_v1000[0x1000], 0);
+ _v1000Flag = false;
+ _v5589E.set(0, 0, 0, 0);
+ _v558B6.set(0, 0, 0, 0);
+ _v558C2 = 0;
+ _animationCtr = 0;
+ _v5657C = 0;
+ _v565E1 = 0;
+ _v565E3 = 0;
+ _v565E5 = 0;
+ _v565E7 = 0;
+ _v565E9 = -5;
+ _v565EB = 26;
+ _v565F5 = 0;
+ _v565F6 = 0;
+ _v565FA = 0;
+ _v565AE = 0;
+ _v56605[0] = 0;
+ _v56605[1] = 3;
+ _v56605[2] = 5;
+ _v56605[3] = 1;
+ _v56605[4] = 2;
+ _v56605[5] = 5;
+ _v56605[6] = 9;
+ _v56605[7] = 14;
+ _v56605[8] = 15;
+ _v56605[9] = 18;
+ _v56605[10] = 20;
+ _v56605[11] = 25;
+ _v56605[12] = 27;
+ _v56605[13] = 31;
+
+ for (int i = 0; i < 18; i++) {
+ _v56613[(i * 4) ] = 1;
+ _v56613[(i * 4) + 2] = 0;
+ _v56613[(i * 4) + 3] = 0;
+ }
+ _v56613[( 0 * 4) + 1] = 1;
+ _v56613[( 1 * 4) + 1] = 2;
+ _v56613[( 2 * 4) + 1] = 2;
+ _v56613[( 3 * 4) + 1] = 3;
+ _v56613[( 4 * 4) + 1] = 2;
+ _v56613[( 5 * 4) + 1] = 2;
+ _v56613[( 6 * 4) + 1] = 3;
+ _v56613[( 7 * 4) + 1] = 1;
+ _v56613[( 8 * 4) + 1] = 1;
+ _v56613[( 9 * 4) + 1] = 3;
+ _v56613[(10 * 4) + 1] = 3;
+ _v56613[(11 * 4) + 1] = 1;
+ _v56613[(12 * 4) + 1] = 2;
+ _v56613[(13 * 4) + 1] = 3;
+ _v56613[(14 * 4) + 1] = 2;
+ _v56613[(15 * 4) + 1] = 3;
+ _v56613[(16 * 4) + 1] = 1;
+ _v56613[(17 * 4) + 1] = 1;
+
+ _v566A6 = 3800;
+ _v566A3 = 2;
+ _v566A4 = 1;
+ _v566A5 = 0;
+ _v566A8 = 5;
+ _v566A9 = 0;
+ _v566AA = 0;
+ for (int i = 0; i < 1000; i++)
+ _v566AB[i] = 0;
+ _v56A93 = -1;
+ _v56A99 = 5;
+ _scene1925CurrLevel = 0; //_v56A9C
+ _v56A9E = 0;
+ _v56AA0 = 0;
+ _v56AA1 = 0;
+ _v56AA2 = 60;
+ _v56AA4 = 660;
+ _v56AA6 = 1;
+ _v56AA7 = 1;
+ _v56AA8 = 1;
+ _v56AAB = 0;
+ _scene180Mode = -1;
+ _v57709 = 0;
+ _v5780C = 0;
+ _v5780E = 0;
+ _v57810 = 0;
+ _v57C2C = 0;
+ _v565EC[0] = 0;
+ _v565EC[1] = 27;
+ _v565EC[2] = 27;
+ _v565EC[3] = 4;
+ _v565EC[4] = 4;
+ Common::fill(&_v565F1[0], &_v565F1[MAX_CHARACTERS], 1);
+ _speechSubtitles = SPEECH_VOICE | SPEECH_TEXT;
+ _insetUp = 0;
+ _frameEdgeColour = 2;
+ Common::fill(&_stripManager_lookupList[0], &_stripManager_lookupList[12], 0);
+ _stripManager_lookupList[0] = 1;
+ _stripManager_lookupList[1] = 1;
+ _stripManager_lookupList[2] = 1;
+ _stripManager_lookupList[3] = 1;
+ _stripManager_lookupList[4] = 1;
+ _stripManager_lookupList[5] = 1;
+ _stripManager_lookupList[8] = 1;
+ _stripManager_lookupList[9] = 1;
+ _stripManager_lookupList[10] = 1;
+ _stripManager_lookupList[11] = 1;
+
+ // Reset fields stored in the player class
+ _player._characterIndex = R2_QUINN;
+ _player._characterScene[1] = 100;
+ _player._characterScene[2] = 300;
+ _player._characterScene[3] = 300;
+}
+void Ringworld2Globals::synchronize(Serializer &s) {
+ TsAGE2Globals::synchronize(s);
+ int i;
+
+ _v5589E.synchronize(s);
+ _v558B6.synchronize(s);
+
+ s.syncAsSint16LE(_v558C2);
+ s.syncAsSint16LE(_animationCtr);
+ s.syncAsSint16LE(_v5657C);
+ s.syncAsSint16LE(_v565E1);
+ s.syncAsSint16LE(_v565E3);
+ s.syncAsSint16LE(_v565E5);
+ s.syncAsSint16LE(_v565E7);
+ s.syncAsSint16LE(_v565E9);
+ s.syncAsSint16LE(_v565EB);
+ s.syncAsSint16LE(_v565F5);
+ s.syncAsSint16LE(_v565F6);
+ s.syncAsSint16LE(_v565FA);
+ s.syncAsSint16LE(_v566A3);
+ s.syncAsSint16LE(_v566A6);
+ s.syncAsSint16LE(_v56A93);
+ s.syncAsSint16LE(_scene1925CurrLevel); // _v56A9C
+ s.syncAsSint16LE(_v56A9E);
+ s.syncAsSint16LE(_v56AA2);
+ s.syncAsSint16LE(_v56AA4);
+ s.syncAsSint16LE(_v56AAB);
+ s.syncAsSint16LE(_scene180Mode);
+ s.syncAsSint16LE(_v57709);
+ s.syncAsSint16LE(_v5780C);
+ s.syncAsSint16LE(_v5780E);
+ s.syncAsSint16LE(_v57810);
+ s.syncAsSint16LE(_v57C2C);
+ s.syncAsSint16LE(_speechSubtitles);
+
+ for (i = 0; i < 5; i++)
+ s.syncAsByte(_v565EC[i]);
+
+ for (i = 0; i < MAX_CHARACTERS; ++i)
+ s.syncAsByte(_v565F1[i]);
+
+ s.syncAsByte(_v565AE);
+ s.syncAsByte(_v566A4);
+ s.syncAsByte(_v566A5);
+ s.syncAsByte(_v566A8);
+ s.syncAsByte(_v566A9);
+ s.syncAsByte(_v566AA);
+ s.syncAsByte(_v56AA0);
+ s.syncAsByte(_v56AA1);
+ s.syncAsByte(_v56AA6);
+ s.syncAsByte(_v56AA7);
+ s.syncAsByte(_v56AA8);
+
+ for (i = 0; i < 14; ++i)
+ s.syncAsByte(_v56605[i]);
+ for (i = 0; i < 1000; ++i)
+ s.syncAsByte(_v566AB[i]);
+ s.syncAsByte(_v56A99);
+ for (i = 0; i < 12; ++i)
+ s.syncAsByte(_stripManager_lookupList[i]);
+
+ s.syncAsSint16LE(_insetUp);
+ s.syncAsByte(_frameEdgeColour);
+}
} // end of namespace Ringworld2
diff --git a/engines/tsage/globals.h b/engines/tsage/globals.h
index a5293a5ad1..45226c921b 100644
--- a/engines/tsage/globals.h
+++ b/engines/tsage/globals.h
@@ -108,9 +108,11 @@ public:
UIElements _uiElements;
SelectItemProc _onSelectItem;
int _interfaceY;
+ ASoundExt _inventorySound;
TsAGE2Globals() { _onSelectItem = NULL; }
virtual void reset();
+ virtual void synchronize(Serializer &s);
};
extern Globals *g_globals;
@@ -182,23 +184,22 @@ enum Flag {
class BlueForceGlobals: public TsAGE2Globals {
public:
- ASoundExt _sound1, _sound2, _sound3;
+ ASoundExt _sound1, _sound3;
StripProxy _stripProxy;
int _dayNumber;
- int _v4CEA4;
- int _v4CEAA;
+ int _tonyDialogCtr;
int _marinaWomanCtr;
- int _v4CEB0;
+ int _kateDialogCtr;
int _v4CEB6;
int _safeCombination;
- int _v4CEC0;
+ int _gateStatus;
int _greenDay5TalkCtr;
int _v4CEC4;
int _v4CEC8;
int _v4CECA;
int _v4CECC;
- int8 _v4CECE[18];
- int _v4CEE0;
+ int8 _breakerBoxStatusArr[18];
+ int _hiddenDoorStatus;
int _v4CEE2;
int _v4CEE4;
int _v4CEE6;
@@ -212,8 +213,8 @@ public:
int _v501FC;
int _v5020C;
int _v50696;
- uint8 _v5098C;
- uint8 _v5098D;
+ uint8 _subFlagBitArr1;
+ uint8 _subFlagBitArr2;
int _v50CC2;
int _v50CC4;
int _v50CC6;
@@ -228,8 +229,8 @@ public:
bool getHasBullets();
virtual Common::String getClassName() { return "BFGlobals"; }
- virtual void synchronize(Serializer &s);
virtual void reset();
+ virtual void synchronize(Serializer &s);
void set2Flags(int flagNum);
bool removeFlag(int flagNum);
};
@@ -238,11 +239,74 @@ public:
namespace Ringworld2 {
+#define SPEECH_TEXT 1
+#define SPEECH_VOICE 2
+
+#define k5A78C 15
+#define k5A78D 16
+#define k5A790 18
+#define k5A791 17
+
class Ringworld2Globals: public TsAGE2Globals {
public:
ASoundExt _sound1, _sound2, _sound3, _sound4;
+ PlayStream _playStream;
+ StripProxy _stripProxy;
+ bool _v1000Flag;
+ byte _v1000[0x1000];
+ byte _palIndexList[10][256];
+ int _insetUp;
+ int _frameEdgeColour; // _v421e
+ Rect _v5589E;
+ Rect _v558B6;
+ int _v558C2;
+ int _animationCtr;
+ int _v565E1;
+ int _v565E3;
+ int _v565E5;
+ int _v565E7;
+ int _v565E9;
+ int _v565EB;
+ int _v565F5;
+ int _v565F6;
+ int _v565FA;
+ int _v5657C;
+ byte _v565AE;
+ byte _v56605[14];
+ int _v56613[76];
+ byte _v566A4;
+ byte _v566A5;
+ int _v566A6;
+ byte _v566A3;
+ byte _v566A8;
+ byte _v566A9;
+ byte _v566AA;
+ byte _v566AB[1000];
+ int _v56A93;
+ byte _v56A99;
+ int _scene1925CurrLevel; //_v56A9C
+ int _v56A9E;
+ byte _v56AA0;
+ byte _v56AA1;
+ int _v56AA2;
+ int _v56AA4;
+ byte _v56AA6;
+ byte _v56AA7;
+ byte _v56AA8;
+ int _v56AAB;
+ int _scene180Mode; // _v575f7
+ int _v57709;
+ int _v5780C;
+ int _v5780E;
+ int _v57810;
+ int _v57C2C;
+ int _speechSubtitles;
+ byte _v565EC[5];
+ byte _v565F1[4];
+ byte _stripManager_lookupList[12];
virtual void reset();
+ virtual void synchronize(Serializer &s);
};
} // End of namespace Ringworld2
diff --git a/engines/tsage/graphics.cpp b/engines/tsage/graphics.cpp
index 4b2da0b456..b3dceba292 100644
--- a/engines/tsage/graphics.cpp
+++ b/engines/tsage/graphics.cpp
@@ -81,7 +81,7 @@ GfxSurface surfaceFromRes(const byte *imgData) {
if (!rleEncoded) {
Common::copy(srcP, srcP + (r.width() * r.height()), destP);
} else {
- Common::set_to(destP, destP + (r.width() * r.height()), s._transColor);
+ Common::fill(destP, destP + (r.width() * r.height()), s._transColor);
for (int yp = 0; yp < r.height(); ++yp) {
int width = r.width();
@@ -105,7 +105,7 @@ GfxSurface surfaceFromRes(const byte *imgData) {
controlVal &= 0x3f;
int pixel = *srcP++;
- Common::set_to(destP, destP + controlVal, pixel);
+ Common::fill(destP, destP + controlVal, pixel);
destP += controlVal;
width -= controlVal;
}
@@ -220,16 +220,16 @@ void Rect::synchronize(Serializer &s) {
GfxSurface::GfxSurface() : _bounds(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT) {
_disableUpdates = false;
- _screenSurface = false;
_lockSurfaceCtr = 0;
_customSurface = NULL;
- _screenSurfaceP = NULL;
_transColor = -1;
+ _trackDirtyRects = false;
}
GfxSurface::GfxSurface(const GfxSurface &s) {
_lockSurfaceCtr = 0;
_customSurface = NULL;
+ _trackDirtyRects = false;
this->operator =(s);
}
@@ -244,24 +244,71 @@ GfxSurface::~GfxSurface() {
* Specifies that the surface will encapsulate the ScummVM screen surface
*/
void GfxSurface::setScreenSurface() {
- _screenSurface = true;
- _customSurface = NULL;
- _lockSurfaceCtr = 0;
+ _trackDirtyRects = true;
+ create(SCREEN_WIDTH, SCREEN_HEIGHT);
+}
+
+/**
+ * Updates the physical screen with the screen surface buffer
+ */
+void GfxSurface::updateScreen() {
+ assert(_trackDirtyRects);
+
+ // Merge any overlapping dirty rects
+ mergeDirtyRects();
+
+ // Loop through the dirty rect list to copy the affected areas to the sc
+ for (Common::List<Rect>::iterator i = _dirtyRects.begin(); i != _dirtyRects.end(); ++i) {
+ Rect r = *i;
+
+ // Make sure that there is something to update. If not, skip this
+ // rectangle. An example case is the speedbike closeup at the beginning
+ // of Ringworld (third screen).
+ if (r.isEmpty())
+ continue;
+
+ const byte *srcP = (const byte *)_customSurface->getBasePtr(r.left, r.top);
+ g_system->copyRectToScreen(srcP, _customSurface->pitch, r.left, r.top,
+ r.width(), r.height());
+ }
+
+ // Update the physical screen
+ g_system->updateScreen();
+
+ // Now that the dirty rects have been copied, clear the dirty rect list
+ _dirtyRects.clear();
+}
+
+/**
+ * Adds a rect to the dirty rect list
+ */
+void GfxSurface::addDirtyRect(const Rect &r) {
+ if (_trackDirtyRects) {
+ // Get the bounds and adjust to allow for sub-screen areas
+ Rect r2 = r;
+ r2.translate(_bounds.left, _bounds.top);
+
+ // Add to the dirty rect list
+ _dirtyRects.push_back(Rect(r2.left, r2.top,
+ MIN(r2.right + 1, SCREEN_WIDTH), MIN(r2.bottom + 1, SCREEN_HEIGHT)));
+ }
}
+
+
/**
* Specifies that the surface should maintain it's own internal surface
*/
void GfxSurface::create(int width, int height) {
assert((width >= 0) && (height >= 0));
- _screenSurface = false;
+
if (_customSurface) {
_customSurface->free();
delete _customSurface;
}
_customSurface = new Graphics::Surface();
_customSurface->create(width, height, Graphics::PixelFormat::createFormatCLUT8());
- Common::set_to((byte *)_customSurface->pixels, (byte *)_customSurface->pixels + (width * height), 0);
+ Common::fill((byte *)_customSurface->pixels, (byte *)_customSurface->pixels + (width * height), 0);
_bounds = Rect(0, 0, width, height);
}
@@ -271,13 +318,7 @@ void GfxSurface::create(int width, int height) {
Graphics::Surface GfxSurface::lockSurface() {
++_lockSurfaceCtr;
- Graphics::Surface *src;
- if (_screenSurface) {
- if (_lockSurfaceCtr == 1)
- _screenSurfaceP = g_system->lockScreen();
- src = _screenSurfaceP;
- } else
- src = _customSurface;
+ Graphics::Surface *src = _customSurface;
assert(src);
// Setup the returned surface either as one pointing to the same pixels as the source, or
@@ -298,15 +339,10 @@ Graphics::Surface GfxSurface::lockSurface() {
void GfxSurface::unlockSurface() {
assert(_lockSurfaceCtr > 0);
--_lockSurfaceCtr;
-
- if ((_lockSurfaceCtr == 0) && _screenSurface) {
- g_system->unlockScreen();
- }
}
void GfxSurface::synchronize(Serializer &s) {
assert(!_lockSurfaceCtr);
- assert(!_screenSurface);
s.syncAsByte(_disableUpdates);
_bounds.synchronize(s);
@@ -351,6 +387,7 @@ void GfxSurface::fillRect(const Rect &bounds, int color) {
Graphics::Surface surface = lockSurface();
surface.fillRect(bounds, color);
unlockSurface();
+ addDirtyRect(bounds);
}
GfxSurface &GfxSurface::operator=(const GfxSurface &s) {
@@ -363,7 +400,6 @@ GfxSurface &GfxSurface::operator=(const GfxSurface &s) {
}
_customSurface = s._customSurface;
- _screenSurface = s._screenSurface;
_disableUpdates = s._disableUpdates;
_bounds = s._bounds;
_centroid = s._centroid;
@@ -406,7 +442,7 @@ bool GfxSurface::displayText(const Common::String &msg, const Common::Point &pt)
// Display the text
gfxManager._font.writeLines(msg.c_str(), textRect, ALIGN_LEFT);
- // Write for a mouse or keypress
+ // Wait for a mouse or keypress
Event event;
while (!g_globals->_events.getEvent(event, EVENT_BUTTON_DOWN | EVENT_KEYPRESS) && !g_vm->shouldQuit())
;
@@ -455,7 +491,7 @@ static int *scaleLine(int size, int srcSize) {
int scale = PRECISION_FACTOR * size / srcSize;
assert(scale >= 0);
int *v = new int[size];
- Common::set_to(v, &v[size], -1);
+ Common::fill(v, &v[size], -1);
int distCtr = PRECISION_FACTOR / 2;
int *destP = v;
@@ -493,7 +529,7 @@ static GfxSurface ResizeSurface(GfxSurface &src, int xSize, int ySize, int trans
byte *destP = (byte *)destImage.getBasePtr(0, yp);
if (vertUsage[yp] == -1) {
- Common::set_to(destP, destP + xSize, transIndex);
+ Common::fill(destP, destP + xSize, transIndex);
} else {
const byte *srcP = (const byte *)srcImage.getBasePtr(0, vertUsage[yp]);
@@ -567,7 +603,11 @@ void GfxSurface::copyFrom(GfxSurface &src, Rect srcBounds, Rect destBounds, Regi
if (destBounds.bottom > destSurface.h)
destBounds.bottom = destSurface.h;
- if (destBounds.isValidRect()) {
+ if (destBounds.isValidRect() && !((destBounds.right < 0) || (destBounds.bottom < 0)
+ || (destBounds.left >= destSurface.w) || (destBounds.top >= destSurface.h))) {
+ // Register the affected area as dirty
+ addDirtyRect(destBounds);
+
const byte *pSrc = (const byte *)srcSurface.getBasePtr(srcX, srcY);
byte *pDest = (byte *)destSurface.getBasePtr(destBounds.left, destBounds.top);
@@ -613,6 +653,50 @@ void GfxSurface::draw(const Common::Point &pt, Rect *rect) {
}
}
+/**
+ * Merges any clipping rectangles that overlap to try and reduce
+ * the total number of clip rectangles.
+ */
+void GfxSurface::mergeDirtyRects() {
+ if (_dirtyRects.size() <= 1)
+ return;
+
+ Common::List<Rect>::iterator rOuter, rInner;
+
+ for (rOuter = _dirtyRects.begin(); rOuter != _dirtyRects.end(); ++rOuter) {
+ rInner = rOuter;
+ while (++rInner != _dirtyRects.end()) {
+
+ if ((*rOuter).intersects(*rInner)) {
+ // these two rectangles overlap or
+ // are next to each other - merge them
+
+ unionRectangle(*rOuter, *rOuter, *rInner);
+
+ // remove the inner rect from the list
+ _dirtyRects.erase(rInner);
+
+ // move back to beginning of list
+ rInner = rOuter;
+ }
+ }
+ }
+}
+
+/**
+ * Creates the union of two rectangles.
+ * Returns True if there is a union.
+ * @param pDest destination rectangle that is to receive the new union
+ * @param pSrc1 a source rectangle
+ * @param pSrc2 a source rectangle
+ */
+bool GfxSurface::unionRectangle(Common::Rect &destRect, const Rect &src1, const Rect &src2) {
+ destRect = src1;
+ destRect.extend(src2);
+
+ return !destRect.isEmpty();
+}
+
/*--------------------------------------------------------------------------*/
GfxElement::GfxElement() {
@@ -652,6 +736,9 @@ void GfxElement::highlight() {
}
}
+ // Mark the affected area as dirty
+ gfxManager.getSurface().addDirtyRect(tempRect);
+
// Release the surface
gfxManager.unlockSurface();
}
@@ -676,7 +763,39 @@ void GfxElement::drawFrame() {
Rect tempRect = _bounds;
tempRect.collapse(g_globals->_gfxEdgeAdjust, g_globals->_gfxEdgeAdjust);
tempRect.collapse(-1, -1);
- gfxManager.fillRect(tempRect, _colors.background);
+
+ if (g_vm->getGameID() == GType_Ringworld2) {
+ // For Return to Ringworld, use palette shading
+
+ // Get the current palette and determining a shading translation list
+ ScenePalette tempPalette;
+ tempPalette.getPalette(0, 256);
+ int transList[256];
+
+ for (int i = 0; i < 256; ++i) {
+ uint r, g, b, v;
+ tempPalette.getEntry(i, &r, &g, &b);
+ v = ((r >> 1) + (g >> 1) + (b >> 1)) / 4;
+
+ transList[i] = tempPalette.indexOf(v, v, v);
+ }
+
+ // Loop through the surface area to replace each pixel
+ // with its proper shaded replacement
+ Graphics::Surface surface = gfxManager.lockSurface();
+ for (int y = tempRect.top; y < tempRect.bottom; ++y) {
+ byte *lineP = (byte *)surface.getBasePtr(tempRect.left, y);
+ for (int x = 0; x < tempRect.width(); ++x) {
+ *lineP = transList[*lineP];
+ lineP++;
+ }
+ }
+ gfxManager.unlockSurface();
+
+ } else {
+ // Fill dialog content with specified background colour
+ gfxManager.fillRect(tempRect, _colors.background);
+ }
--tempRect.bottom; --tempRect.right;
gfxManager.fillArea(tempRect.left, tempRect.top, bgColor);
@@ -1058,7 +1177,7 @@ GfxButton *GfxDialog::execute(GfxButton *defaultButton) {
}
g_system->delayMillis(10);
- g_system->updateScreen();
+ GLOBALS._screenSurface.updateScreen();
}
_gfxManager.deactivate();
@@ -1077,7 +1196,7 @@ void GfxDialog::setPalette() {
g_globals->_scenePalette.setPalette(g_globals->_fontColors.background, 1);
g_globals->_scenePalette.setPalette(g_globals->_fontColors.foreground, 1);
g_globals->_scenePalette.setEntry(255, 0xff, 0xff, 0xff);
- g_globals->_scenePalette.setPalette(255, 1);
+ g_globals->_scenePalette.setPalette(255, 1);
} else {
g_globals->_scenePalette.loadPalette(0);
g_globals->_scenePalette.setPalette(0, 1);
@@ -1190,6 +1309,19 @@ int GfxManager::getAngle(const Common::Point &p1, const Common::Point &p2) {
return result;
}
}
+
+void GfxManager::copyFrom(GfxSurface &src, Rect destBounds, Region *priorityRegion) {
+ _surface.setBounds(_bounds);
+
+ _surface.copyFrom(src, destBounds, priorityRegion);
+}
+
+void GfxManager::copyFrom(GfxSurface &src, int destX, int destY) {
+ _surface.setBounds(_bounds);
+
+ _surface.copyFrom(src, destX, destY);
+}
+
/*--------------------------------------------------------------------------*/
@@ -1222,7 +1354,11 @@ void GfxFont::setFontNumber(uint32 fontNumber) {
if (!_fontData)
_fontData = g_resourceManager->getResource(RES_FONT, _fontNumber, 0);
- _numChars = READ_LE_UINT16(_fontData + 4);
+ // Since some TsAGE game versions don't have a valid character count at offset 4, use the offset of the
+ // first charactre data to calculate the number of characters in the offset table preceeding it
+ _numChars = (READ_LE_UINT32(_fontData + 12) - 12) / 4;
+ assert(_numChars <= 256);
+
_fontSize.y = READ_LE_UINT16(_fontData + 6);
_fontSize.x = READ_LE_UINT16(_fontData + 8);
_bpp = READ_LE_UINT16(_fontData + 10);
@@ -1392,7 +1528,12 @@ int GfxFont::writeChar(const char ch) {
}
}
+ // Mark the affected area as dirty
+ _gfxManager->getSurface().addDirtyRect(charRect);
+
+ // Move the text writing position
_position.x += charWidth;
+
_gfxManager->unlockSurface();
return charWidth;
}
diff --git a/engines/tsage/graphics.h b/engines/tsage/graphics.h
index 06b482d7b5..9c6f13e407 100644
--- a/engines/tsage/graphics.h
+++ b/engines/tsage/graphics.h
@@ -74,12 +74,17 @@ public:
class GfxSurface {
private:
Graphics::Surface *_customSurface;
- Graphics::Surface *_screenSurfaceP;
int _lockSurfaceCtr;
- bool _screenSurface;
bool _disableUpdates;
Rect _bounds;
+
+ bool _trackDirtyRects;
+ Common::List<Rect> _dirtyRects;
+
+ void mergeDirtyRects();
+ bool unionRectangle(Common::Rect &destRect, const Rect &src1, const Rect &src2);
+
public:
Common::Point _centroid;
int _transColor;
@@ -89,6 +94,8 @@ public:
~GfxSurface();
void setScreenSurface();
+ void updateScreen();
+ void addDirtyRect(const Rect &r);
Graphics::Surface lockSurface();
void unlockSurface();
void synchronize(Serializer &s);
@@ -292,17 +299,11 @@ public:
Common::copy(src, src + size, dest);
}
virtual void set(byte *dest, int size, byte val) {
- Common::set_to(dest, dest + size, val);
- }
- void copyFrom(GfxSurface &src, Rect destBounds, Region *priorityRegion = NULL) {
- _surface.setBounds(_bounds);
- _surface.copyFrom(src, destBounds, priorityRegion);
- }
- void copyFrom(GfxSurface &src, int destX, int destY) {
- _surface.setBounds(_bounds);
- _surface.copyFrom(src, destX, destY);
- g_system->updateScreen();
+ Common::fill(dest, dest + size, val);
}
+ void copyFrom(GfxSurface &src, Rect destBounds, Region *priorityRegion = NULL);
+ void copyFrom(GfxSurface &src, int destX, int destY);
+
GfxSurface &getSurface() {
_surface.setBounds(_bounds);
return _surface;
diff --git a/engines/tsage/module.mk b/engines/tsage/module.mk
index 0ea8916647..53c03e2e57 100644
--- a/engines/tsage/module.mk
+++ b/engines/tsage/module.mk
@@ -38,6 +38,10 @@ MODULE_OBJS := \
ringworld2/ringworld2_dialogs.o \
ringworld2/ringworld2_logic.o \
ringworld2/ringworld2_scenes0.o \
+ ringworld2/ringworld2_scenes1.o \
+ ringworld2/ringworld2_scenes2.o \
+ ringworld2/ringworld2_scenes3.o \
+ ringworld2/ringworld2_speakers.o \
saveload.o \
scenes.o \
sound.o \
diff --git a/engines/tsage/resources.cpp b/engines/tsage/resources.cpp
index 652ab32350..5987d78067 100644
--- a/engines/tsage/resources.cpp
+++ b/engines/tsage/resources.cpp
@@ -33,7 +33,7 @@ namespace TsAGE {
MemoryManager::MemoryManager() {
_memoryPool = new MemoryHeader*[MEMORY_POOL_SIZE];
- Common::set_to(&_memoryPool[0], &_memoryPool[MEMORY_POOL_SIZE], (MemoryHeader *)NULL);
+ Common::fill(&_memoryPool[0], &_memoryPool[MEMORY_POOL_SIZE], (MemoryHeader *)NULL);
}
MemoryManager::~MemoryManager() {
@@ -67,7 +67,7 @@ uint16 MemoryManager::allocate(uint32 size) {
byte *MemoryManager::allocate2(uint32 size) {
uint32 idx = allocate(size);
byte *result = lock(idx);
- Common::set_to(result, result + size, 0);
+ Common::fill(result, result + size, 0);
return result;
}
@@ -135,7 +135,7 @@ uint16 BitReader::readToken() {
/*-------------------------------------------------------------------------*/
TLib::TLib(MemoryManager &memManager, const Common::String &filename) :
- _memoryManager(memManager) {
+ _filename(filename), _memoryManager(memManager) {
// If the resource strings list isn't yet loaded, load them
if (_resStrings.size() == 0) {
@@ -158,35 +158,15 @@ TLib::~TLib() {
_resStrings.clear();
}
+/**
+ * Load a section index from the given position in the file
+ */
void TLib::loadSection(uint32 fileOffset) {
_resources.clear();
_file.seek(fileOffset);
_sections.fileOffset = fileOffset;
- if (_file.readUint32BE() != 0x544D492D)
- error("Data block is not valid Rlb data");
-
- /*uint8 unknown1 = */_file.readByte();
- uint16 numEntries = _file.readByte();
-
- for (uint i = 0; i < numEntries; ++i) {
- uint16 id = _file.readUint16LE();
- uint16 size = _file.readUint16LE();
- uint16 uncSize = _file.readUint16LE();
- uint8 sizeHi = _file.readByte();
- uint8 type = _file.readByte() >> 5;
- assert(type <= 1);
- uint32 offset = _file.readUint32LE();
-
- ResourceEntry re;
- re.id = id;
- re.fileOffset = offset;
- re.isCompressed = type != 0;
- re.size = ((sizeHi & 0xF) << 16) | size;
- re.uncompressedSize = ((sizeHi & 0xF0) << 12) | uncSize;
-
- _resources.push_back(re);
- }
+ ResourceManager::loadSection(_file, _resources);
}
struct DecodeReference {
@@ -332,6 +312,40 @@ byte *TLib::getResource(ResourceType resType, uint16 resNum, uint16 rlbNum, bool
return getResource(rlbNum, suppressErrors);
}
+/**
+ * Gets the offset of the start of a resource in the resource file
+ */
+uint32 TLib::getResourceStart(ResourceType resType, uint16 resNum, uint16 rlbNum, ResourceEntry &entry) {
+ // Find the correct section
+ SectionList::iterator i = _sections.begin();
+ while ((i != _sections.end()) && ((*i).resType != resType || (*i).resNum != resNum))
+ ++i;
+ if (i == _sections.end()) {
+ error("Unknown resource type %d num %d", resType, resNum);
+ }
+
+ // Load in the section index
+ loadSection((*i).fileOffset);
+
+ // Scan for an entry for the given Id
+ ResourceEntry *re = NULL;
+ ResourceList::iterator iter;
+ for (iter = _resources.begin(); iter != _resources.end(); ++iter) {
+ if ((*iter).id == rlbNum) {
+ re = &(*iter);
+ break;
+ }
+ }
+
+ // Throw an error if no resource was found, or the resource is compressed
+ if (!re || re->isCompressed)
+ error("Invalid resource Id #%d", rlbNum);
+
+ // Return the resource entry as well as the file offset
+ entry = *re;
+ return _sections.fileOffset + entry.fileOffset;
+}
+
void TLib::loadIndex() {
uint16 resNum, configId, fileOffset;
@@ -414,17 +428,28 @@ byte *TLib::getSubResource(int resNum, int rlbNum, int index, uint *size, bool s
*/
bool TLib::getMessage(int resNum, int lineNum, Common::String &result, bool suppressErrors) {
byte *msgData = getResource(RES_MESSAGE, resNum, 0, true);
- if (!msgData) {
+ if (!msgData || (lineNum < 0)) {
if (suppressErrors)
return false;
error("Unknown message %d line %d", resNum, lineNum);
}
+ int msgSize = _memoryManager.getSize(msgData);
const char *srcP = (const char *)msgData;
- while (lineNum-- > 0)
+ const char *endP = srcP + msgSize;
+
+ while (lineNum-- > 0) {
srcP += strlen(srcP) + 1;
+ if (srcP >= endP) {
+ if (suppressErrors)
+ return false;
+
+ error("Unknown message %d line %d", resNum, lineNum);
+ }
+ }
+
result = Common::String(srcP);
_memoryManager.deallocate(msgData);
return true;
@@ -503,7 +528,65 @@ Common::String ResourceManager::getMessage(int resNum, int lineNum, bool suppres
if (!suppressErrors)
error("Unknown message %d line %d", resNum, lineNum);
- return result;
+ return Common::String();
+}
+
+/*--------------------------------------------------------------------------*/
+
+/**
+ * Open up the given resource file using a passed file object. If the desired entry is found
+ * in the index, return the index entry for it, and move the file to the start of the resource
+ */
+bool ResourceManager::scanIndex(Common::File &f, ResourceType resType, int rlbNum, int resNum,
+ ResourceEntry &resEntry) {
+ // Load the root section index
+ ResourceList resList;
+ loadSection(f, resList);
+
+ // Loop through the index for the desired entry
+ ResourceList::iterator iter;
+ for (iter = resList.begin(); iter != resList.end(); ++iter) {
+ ResourceEntry &re = *iter;
+ if (re.id == resNum) {
+ // Found it, so exit
+ resEntry = re;
+ f.seek(re.fileOffset);
+ return true;
+ }
+ }
+
+ // No matching entry found
+ return false;
+}
+
+/**
+ * Inner logic for decoding a section index into a passed resource list object
+ */
+void ResourceManager::loadSection(Common::File &f, ResourceList &resources) {
+ if (f.readUint32BE() != 0x544D492D)
+ error("Data block is not valid Rlb data");
+
+ /*uint8 unknown1 = */f.readByte();
+ uint16 numEntries = f.readByte();
+
+ for (uint i = 0; i < numEntries; ++i) {
+ uint16 id = f.readUint16LE();
+ uint16 size = f.readUint16LE();
+ uint16 uncSize = f.readUint16LE();
+ uint8 sizeHi = f.readByte();
+ uint8 type = f.readByte() >> 5;
+ assert(type <= 1);
+ uint32 offset = f.readUint32LE();
+
+ ResourceEntry re;
+ re.id = id;
+ re.fileOffset = offset;
+ re.isCompressed = type != 0;
+ re.size = ((sizeHi & 0xF) << 16) | size;
+ re.uncompressedSize = ((sizeHi & 0xF0) << 12) | uncSize;
+
+ resources.push_back(re);
+ }
}
} // end of namespace TsAGE
diff --git a/engines/tsage/resources.h b/engines/tsage/resources.h
index 8f90b21908..45cecf8521 100644
--- a/engines/tsage/resources.h
+++ b/engines/tsage/resources.h
@@ -29,7 +29,6 @@
#include "common/list.h"
#include "common/str.h"
#include "common/str-array.h"
-#include "common/textconsole.h"
#include "common/util.h"
#include "graphics/surface.h"
@@ -146,6 +145,7 @@ private:
MemoryManager &_memoryManager;
private:
Common::File _file;
+ Common::String _filename;
ResourceList _resources;
SectionList _sections;
@@ -155,8 +155,11 @@ public:
TLib(MemoryManager &memManager, const Common::String &filename);
~TLib();
+ const Common::String &getFilename() { return _filename; }
+ const SectionList &getSections() { return _sections; }
byte *getResource(uint16 id, bool suppressErrors = false);
byte *getResource(ResourceType resType, uint16 resNum, uint16 rlbNum, bool suppressErrors = false);
+ uint32 getResourceStart(ResourceType resType, uint16 resNum, uint16 rlbNum, ResourceEntry &entry);
bool getPalette(int paletteNum, byte *palData, uint *startNum, uint *numEntries);
byte *getSubResource(int resNum, int rlbNum, int index, uint *size, bool suppressErrors = false);
bool getMessage(int resNum, int lineNum, Common::String &result, bool suppressErrors = false);
@@ -175,6 +178,10 @@ public:
void getPalette(int paletteNum, byte *palData, uint *startNum, uint *numEntries, bool suppressErrors = false);
byte *getSubResource(int resNum, int rlbNum, int index, uint *size, bool suppressErrors = false);
Common::String getMessage(int resNum, int lineNum, bool suppressErrors = false);
+ TLib &first() { return **_libList.begin(); }
+
+ static bool scanIndex(Common::File &f, ResourceType resType, int rlbNum, int resNum, ResourceEntry &resEntry);
+ static void loadSection(Common::File &f, ResourceList &resources);
};
diff --git a/engines/tsage/ringworld/ringworld_dialogs.cpp b/engines/tsage/ringworld/ringworld_dialogs.cpp
index 9d1a7effc2..0e451b8429 100644
--- a/engines/tsage/ringworld/ringworld_dialogs.cpp
+++ b/engines/tsage/ringworld/ringworld_dialogs.cpp
@@ -183,9 +183,11 @@ void RightClickDialog::execute() {
}
g_system->delayMillis(10);
- g_system->updateScreen();
+ GLOBALS._screenSurface.updateScreen();
}
+ _gfxManager.deactivate();
+
// Execute the specified action
switch (_selectedAction) {
case 1:
@@ -210,9 +212,243 @@ void RightClickDialog::execute() {
break;
case 6:
// Dialog options
- OptionsDialog::show();
+ Ringworld::OptionsDialog::show();
break;
}
+}
+
+/*--------------------------------------------------------------------------*/
+
+void OptionsDialog::show() {
+ OptionsDialog *dlg = new OptionsDialog();
+ dlg->draw();
+
+ GfxButton *btn = dlg->execute();
+
+ if (btn == &dlg->_btnQuit) {
+ // Quit game
+ if (MessageDialog::show(QUIT_CONFIRM_MSG, CANCEL_BTN_STRING, QUIT_BTN_STRING) == 1) {
+ g_vm->quitGame();
+ }
+ } else if (btn == &dlg->_btnRestart) {
+ // Restart game
+ g_globals->_game->restartGame();
+ } else if (btn == &dlg->_btnSound) {
+ // Sound dialog
+ SoundDialog::execute();
+ } else if (btn == &dlg->_btnSave) {
+ // Save button
+ g_globals->_game->saveGame();
+ } else if (btn == &dlg->_btnRestore) {
+ // Restore button
+ g_globals->_game->restoreGame();
+ }
+
+ dlg->remove();
+ delete dlg;
+}
+
+OptionsDialog::OptionsDialog() {
+ // Set the element text
+ _gfxMessage.set(OPTIONS_MSG, 140, ALIGN_LEFT);
+ _btnRestore.setText(RESTORE_BTN_STRING);
+ _btnSave.setText(SAVE_BTN_STRING);
+ _btnRestart.setText(RESTART_BTN_STRING);
+ _btnQuit.setText(QUIT_BTN_STRING);
+ _btnSound.setText(SOUND_BTN_STRING);
+ _btnResume.setText(RESUME_BTN_STRING);
+
+ // Set position of the elements
+ _gfxMessage._bounds.moveTo(0, 1);
+ _btnRestore._bounds.moveTo(0, _gfxMessage._bounds.bottom + 1);
+ _btnSave._bounds.moveTo(0, _btnRestore._bounds.bottom + 1);
+ _btnRestart._bounds.moveTo(0, _btnSave._bounds.bottom + 1);
+ _btnQuit._bounds.moveTo(0, _btnRestart._bounds.bottom + 1);
+ _btnSound._bounds.moveTo(0, _btnQuit._bounds.bottom + 1);
+ _btnResume._bounds.moveTo(0, _btnSound._bounds.bottom + 1);
+
+ // Set all the buttons to the widest button
+ GfxButton *btnList[6] = {&_btnRestore, &_btnSave, &_btnRestart, &_btnQuit, &_btnSound, &_btnResume};
+ int16 btnWidth = 0;
+ for (int idx = 0; idx < 6; ++idx)
+ btnWidth = MAX(btnWidth, btnList[idx]->_bounds.width());
+ for (int idx = 0; idx < 6; ++idx)
+ btnList[idx]->_bounds.setWidth(btnWidth);
+
+ // Add the items to the dialog
+ addElements(&_gfxMessage, &_btnRestore, &_btnSave, &_btnRestart, &_btnQuit, &_btnSound, &_btnResume, NULL);
+
+ // Set the dialog size and position
+ frame();
+ setCenter(160, 100);
+}
+
+/*--------------------------------------------------------------------------*/
+
+bool GfxInvImage::process(Event &event) {
+ if (!event.handled && (event.eventType == EVENT_BUTTON_DOWN)) {
+ event.handled = _bounds.contains(event.mousePos);
+ return event.handled;
+ }
+
+ return false;
+}
+
+/*--------------------------------------------------------------------------*/
+
+void InventoryDialog::show() {
+ // Determine how many items are in the player's inventory
+ int itemCount = 0;
+ SynchronizedList<InvObject *>::iterator i;
+ for (i = RING_INVENTORY._itemList.begin(); i != RING_INVENTORY._itemList.end(); ++i) {
+ if ((*i)->inInventory())
+ ++itemCount;
+ }
+
+ if (itemCount == 0) {
+ MessageDialog::show(INV_EMPTY_MSG, OK_BTN_STRING);
+ return;
+ }
+
+ InventoryDialog *dlg = new InventoryDialog();
+ dlg->draw();
+ dlg->execute();
+ delete dlg;
+}
+
+InventoryDialog::InventoryDialog() {
+ // Determine the maximum size of the image of any item in the player's inventory
+ int imgWidth = 0, imgHeight = 0;
+
+ SynchronizedList<InvObject *>::iterator i;
+ for (i = RING_INVENTORY._itemList.begin(); i != RING_INVENTORY._itemList.end(); ++i) {
+ InvObject *invObject = *i;
+ if (invObject->inInventory()) {
+ // Get the image for the item
+ GfxSurface itemSurface = surfaceFromRes(invObject->_displayResNum, invObject->_rlbNum, invObject->_cursorNum);
+
+ // Maintain the dimensions of the largest item image
+ imgWidth = MAX(imgWidth, (int)itemSurface.getBounds().width());
+ imgHeight = MAX(imgHeight, (int)itemSurface.getBounds().height());
+
+ // Add the item to the display list
+ GfxInvImage *img = new GfxInvImage();
+ _images.push_back(img);
+ img->setDetails(invObject->_displayResNum, invObject->_rlbNum, invObject->_cursorNum);
+ img->_invObject = invObject;
+ add(img);
+ }
+ }
+ assert(_images.size() > 0);
+
+ // Figure out the number of columns/rows to show all the items
+ int cellsSize = 3;
+ while ((cellsSize * cellsSize) < (int)_images.size())
+ ++cellsSize;
+
+ // Set the position of each inventory item to be displayed
+ int cellX = 0;
+ Common::Point pt(0, 0);
+
+ for (uint idx = 0; idx < _images.size(); ++idx) {
+ if (cellX == cellsSize) {
+ // Move to the start of the next line
+ pt.x = 0;
+ pt.y += imgHeight + 2;
+ cellX = 0;
+ }
+
+ _images[idx]->_bounds.moveTo(pt.x, pt.y);
+
+ pt.x += imgWidth + 2;
+ ++cellX;
+ }
+
+ // Set up the buttons
+ pt.y += imgHeight + 2;
+ _btnOk.setText(OK_BTN_STRING);
+ _btnOk._bounds.moveTo((imgWidth + 2) * cellsSize - _btnOk._bounds.width(), pt.y);
+ _btnLook.setText(LOOK_BTN_STRING);
+ _btnLook._bounds.moveTo(_btnOk._bounds.left - _btnLook._bounds.width() - 2, _btnOk._bounds.top);
+ addElements(&_btnLook, &_btnOk, NULL);
+
+ frame();
+ setCenter(SCREEN_CENTER_X, SCREEN_CENTER_Y);
+}
+
+InventoryDialog::~InventoryDialog() {
+ for (uint idx = 0; idx < _images.size(); ++idx)
+ delete _images[idx];
+}
+
+void InventoryDialog::execute() {
+ if ((RING_INVENTORY._selectedItem) && RING_INVENTORY._selectedItem->inInventory())
+ RING_INVENTORY._selectedItem->setCursor();
+
+ GfxElement *hiliteObj;
+ bool lookFlag = false;
+ _gfxManager.activate();
+
+ while (!g_vm->shouldQuit()) {
+ // Get events
+ Event event;
+ while (!g_globals->_events.getEvent(event) && !g_vm->shouldQuit()) {
+ g_system->delayMillis(10);
+ GLOBALS._screenSurface.updateScreen();
+ }
+ if (g_vm->shouldQuit())
+ break;
+
+ hiliteObj = NULL;
+ if ((event.eventType == EVENT_BUTTON_DOWN) && !_bounds.contains(event.mousePos))
+ break;
+
+ // Pass event to elements
+ event.mousePos.x -= _gfxManager._bounds.left;
+ event.mousePos.y -= _gfxManager._bounds.top;
+
+ for (GfxElementList::iterator i = _elements.begin(); i != _elements.end(); ++i) {
+ if ((*i)->process(event))
+ hiliteObj = *i;
+ }
+
+ if (!event.handled && event.eventType == EVENT_KEYPRESS) {
+ if ((event.kbd.keycode == Common::KEYCODE_RETURN) || (event.kbd.keycode == Common::KEYCODE_ESCAPE)) {
+ // Exit the dialog
+ //hiliteObj = &_btnOk;
+ break;
+ }
+ }
+
+ if (hiliteObj == &_btnOk) {
+ // Ok button clicked
+ if (lookFlag)
+ g_globals->_events.setCursor(CURSOR_WALK);
+ break;
+ } else if (hiliteObj == &_btnLook) {
+ // Look button clicked
+ if (_btnLook._message == LOOK_BTN_STRING) {
+ _btnLook._message = PICK_BTN_STRING;
+ lookFlag = 1;
+ g_globals->_events.setCursor(CURSOR_LOOK);
+ } else {
+ _btnLook._message = LOOK_BTN_STRING;
+ lookFlag = 0;
+ g_globals->_events.setCursor(CURSOR_WALK);
+ }
+
+ hiliteObj->draw();
+ } else if (hiliteObj) {
+ // Inventory item selected
+ InvObject *invObject = static_cast<GfxInvImage *>(hiliteObj)->_invObject;
+ if (lookFlag) {
+ g_globals->_screenSurface.displayText(invObject->_description);
+ } else {
+ RING_INVENTORY._selectedItem = invObject;
+ invObject->setCursor();
+ }
+ }
+ }
_gfxManager.deactivate();
}
diff --git a/engines/tsage/ringworld/ringworld_dialogs.h b/engines/tsage/ringworld/ringworld_dialogs.h
index 11a8f10e70..b14b3f6d78 100644
--- a/engines/tsage/ringworld/ringworld_dialogs.h
+++ b/engines/tsage/ringworld/ringworld_dialogs.h
@@ -63,6 +63,45 @@ public:
void execute();
};
+class OptionsDialog : public ModalDialog {
+private:
+ GfxButton _btnSave, _btnRestore, _btnRestart;
+ GfxButton _btnQuit, _btnResume;
+ GfxButton _btnSound;
+ GfxMessage _gfxMessage;
+public:
+ OptionsDialog();
+ virtual ~OptionsDialog() {}
+ GfxButton *execute() { return GfxDialog::execute(&_btnResume); }
+
+ static void show();
+};
+
+/*--------------------------------------------------------------------------*/
+
+class GfxInvImage : public GfxImage {
+public:
+ InvObject *_invObject;
+public:
+ GfxInvImage() : GfxImage(), _invObject(NULL) {}
+
+ virtual bool process(Event &event);
+};
+
+#define MAX_INVOBJECT_DISPLAY 20
+
+class InventoryDialog : public ModalDialog {
+private:
+ Common::Array<GfxInvImage *> _images;
+ GfxButton _btnOk, _btnLook;
+public:
+ InventoryDialog();
+ virtual ~InventoryDialog();
+ void execute();
+
+ static void show();
+};
+
} // End of namespace Ringworld
} // End of namespace TsAGE
diff --git a/engines/tsage/ringworld/ringworld_logic.cpp b/engines/tsage/ringworld/ringworld_logic.cpp
index ad67b66f69..00c219f2ee 100644
--- a/engines/tsage/ringworld/ringworld_logic.cpp
+++ b/engines/tsage/ringworld/ringworld_logic.cpp
@@ -196,14 +196,17 @@ Scene *RingworldGame::createScene(int sceneNumber) {
* Returns true if it is currently okay to restore a game
*/
bool RingworldGame::canLoadGameStateCurrently() {
- return !g_globals->getFlag(50);
+ // Don't allow a game to be loaded if a dialog is active
+ return !g_globals->getFlag(50) && (g_globals->_gfxManagers.size() == 1);
+
}
/**
* Returns true if it is currently okay to save the game
*/
bool RingworldGame::canSaveGameStateCurrently() {
- return !g_globals->getFlag(50);
+ // Don't allow a game to be saved if a dialog is active
+ return !g_globals->getFlag(50) && (g_globals->_gfxManagers.size() == 1);
}
/*--------------------------------------------------------------------------*/
@@ -312,7 +315,7 @@ void SceneArea::wait() {
// Wait until a mouse or keypress
Event event;
while (!g_vm->shouldQuit() && !g_globals->_events.getEvent(event)) {
- g_system->updateScreen();
+ GLOBALS._screenSurface.updateScreen();
g_system->delayMillis(10);
}
@@ -623,58 +626,6 @@ void NamedHotspot::doAction(int action) {
SceneHotspot::doAction(action);
}
-void NamedHotspot::setDetails(int ys, int xs, int ye, int xe, const int resnum, const int lookLineNum, const int useLineNum) {
- setBounds(ys, xe, ye, xs);
- _resNum = resnum;
- _lookLineNum = lookLineNum;
- _useLineNum = useLineNum;
- _talkLineNum = -1;
- g_globals->_sceneItems.addItems(this, NULL);
-}
-
-void NamedHotspot::setDetails(const Rect &bounds, int resNum, int lookLineNum, int talkLineNum, int useLineNum, int mode, SceneItem *item) {
- setBounds(bounds);
- _resNum = resNum;
- _lookLineNum = lookLineNum;
- _talkLineNum = talkLineNum;
- _useLineNum = useLineNum;
-
- switch (mode) {
- case 2:
- g_globals->_sceneItems.push_front(this);
- break;
- case 4:
- g_globals->_sceneItems.addBefore(item, this);
- break;
- case 5:
- g_globals->_sceneItems.addAfter(item, this);
- break;
- default:
- g_globals->_sceneItems.push_back(this);
- break;
- }
-}
-
-void NamedHotspot::setDetails(int sceneRegionId, int resNum, int lookLineNum, int talkLineNum, int useLineNum, int mode) {
- _sceneRegionId = sceneRegionId;
- _resNum = resNum;
- _lookLineNum = lookLineNum;
- _talkLineNum = talkLineNum;
- _useLineNum = useLineNum;
-
- // Handle adding hotspot to scene items list as necessary
- switch (mode) {
- case 2:
- GLOBALS._sceneItems.push_front(this);
- break;
- case 3:
- break;
- default:
- GLOBALS._sceneItems.push_back(this);
- break;
- }
-}
-
void NamedHotspot::synchronize(Serializer &s) {
SceneHotspot::synchronize(s);
s.syncAsSint16LE(_resNum);
diff --git a/engines/tsage/ringworld/ringworld_logic.h b/engines/tsage/ringworld/ringworld_logic.h
index 6f6a66cc26..e902ac127f 100644
--- a/engines/tsage/ringworld/ringworld_logic.h
+++ b/engines/tsage/ringworld/ringworld_logic.h
@@ -161,15 +161,11 @@ public:
class NamedHotspot : public SceneHotspot {
public:
- int _resNum, _lookLineNum, _useLineNum, _talkLineNum;
NamedHotspot();
virtual void doAction(int action);
virtual Common::String getClassName() { return "NamedHotspot"; }
virtual void synchronize(Serializer &s);
- virtual void setDetails(int ys, int xs, int ye, int xe, const int resnum, const int lookLineNum, const int useLineNum);
- virtual void setDetails(const Rect &bounds, int resNum, int lookLineNum, int talkLineNum, int useLineNum, int mode, SceneItem *item);
- virtual void setDetails(int sceneRegionId, int resNum, int lookLineNum, int talkLineNum, int useLineNum, int mode);
};
class NamedHotspotExt : public NamedHotspot {
diff --git a/engines/tsage/ringworld/ringworld_scenes10.cpp b/engines/tsage/ringworld/ringworld_scenes10.cpp
index 5aeb127915..f9a8e7996a 100644
--- a/engines/tsage/ringworld/ringworld_scenes10.cpp
+++ b/engines/tsage/ringworld/ringworld_scenes10.cpp
@@ -20,7 +20,6 @@
*
*/
-#include "graphics/cursorman.h"
#include "tsage/ringworld/ringworld_scenes10.h"
#include "tsage/scenes.h"
#include "tsage/tsage.h"
@@ -709,7 +708,7 @@ void Scene9360::postInit(SceneObjectList *OwnerList) {
*
*--------------------------------------------------------------------------*/
Scene9400::Scene9400() {
- _field1032 = 0;
+ _hittingAnvil = false;
}
void Scene9400::SceneHotspot7::doAction(int action) {
@@ -767,12 +766,12 @@ void Scene9400::signal() {
void Scene9400::dispatch() {
if ((_object1._animateMode == 2) && (_object1._strip == 1) && (_object1._frame == 4)){
- if (_field1032 == 0) {
+ if (_hittingAnvil == false) {
_soundHandler.play(296);
- _field1032 = 1;
+ _hittingAnvil = true;
}
} else {
- _field1032 = 0;
+ _hittingAnvil = false;
}
if (_action == 0) {
if (g_globals->_player._position.y < 120) {
@@ -826,7 +825,7 @@ void Scene9400::postInit(SceneObjectList *OwnerList) {
void Scene9400::synchronize(Serializer &s) {
Scene::synchronize(s);
if (s.getVersion() >= 3)
- s.syncAsSint16LE(_field1032);
+ s.syncAsSint16LE(_hittingAnvil);
}
/*--------------------------------------------------------------------------
diff --git a/engines/tsage/ringworld/ringworld_scenes10.h b/engines/tsage/ringworld/ringworld_scenes10.h
index 0193d5af63..48859ab454 100644
--- a/engines/tsage/ringworld/ringworld_scenes10.h
+++ b/engines/tsage/ringworld/ringworld_scenes10.h
@@ -236,7 +236,7 @@ public:
NamedHotspot _hotspot5;
NamedHotspot _hotspot6;
ASound _soundHandler;
- int _field1032;
+ bool _hittingAnvil;
SceneHotspot7 _hotspot7;
SceneHotspot8 _hotspot8;
diff --git a/engines/tsage/ringworld/ringworld_scenes3.cpp b/engines/tsage/ringworld/ringworld_scenes3.cpp
index 81190aea7b..0e4ccd1269 100644
--- a/engines/tsage/ringworld/ringworld_scenes3.cpp
+++ b/engines/tsage/ringworld/ringworld_scenes3.cpp
@@ -532,7 +532,7 @@ void Scene2100::Action1::signal() {
// Wait for an event
Event event;
if (!g_globals->_events.getEvent(event)) {
- g_system->updateScreen();
+ GLOBALS._screenSurface.updateScreen();
g_system->delayMillis(10);
continue;
}
@@ -2263,7 +2263,7 @@ void Scene2150::Action1::signal() {
// Wait for an event
Event event;
if (!g_globals->_events.getEvent(event)) {
- g_system->updateScreen();
+ GLOBALS._screenSurface.updateScreen();
g_system->delayMillis(10);
continue;
}
@@ -5118,7 +5118,7 @@ void Scene2320::Action3::signal() {
// Wait for an event
Event event;
if (!g_globals->_events.getEvent(event)) {
- g_system->updateScreen();
+ GLOBALS._screenSurface.updateScreen();
g_system->delayMillis(10);
continue;
}
diff --git a/engines/tsage/ringworld/ringworld_scenes5.cpp b/engines/tsage/ringworld/ringworld_scenes5.cpp
index 3cf1207e9e..3b415bdb6a 100644
--- a/engines/tsage/ringworld/ringworld_scenes5.cpp
+++ b/engines/tsage/ringworld/ringworld_scenes5.cpp
@@ -1478,7 +1478,7 @@ void Scene4025::Hole::doAction(int action) {
void Scene4025::Peg::synchronize(Serializer &s) {
SceneObject::synchronize(s);
- s.syncAsSint16LE(_field88);
+ s.syncAsSint16LE(_pegId);
s.syncAsSint16LE(_armStrip);
}
@@ -1513,35 +1513,35 @@ void Scene4025::postInit(SceneObjectList *OwnerList) {
_pegPtr = _pegPtr2 = NULL;
_peg1.postInit();
- _peg1._field88 = 1;
+ _peg1._pegId = 1;
_peg1.setVisage(4025);
_peg1.setStrip(2);
_peg1.setFrame(1);
_peg1.setPosition(Common::Point(203, 61));
_peg2.postInit();
- _peg2._field88 = 4;
+ _peg2._pegId = 4;
_peg2.setVisage(4025);
_peg2.setStrip(2);
_peg2.setFrame(2);
_peg2.setPosition(Common::Point(195, 57));
_peg3.postInit();
- _peg3._field88 = 0;
+ _peg3._pegId = 0;
_peg3.setVisage(4025);
_peg3.setStrip(2);
_peg3.setFrame(3);
_peg3.setPosition(Common::Point(202, 66));
_peg4.postInit();
- _peg4._field88 = 3;
+ _peg4._pegId = 3;
_peg4.setVisage(4025);
_peg4.setStrip(2);
_peg4.setFrame(4);
_peg4.setPosition(Common::Point(194, 68));
_peg5.postInit();
- _peg5._field88 = 2;
+ _peg5._pegId = 2;
_peg5.setVisage(4025);
_peg5.setStrip(1);
_peg5.setFrame(5);
@@ -2173,7 +2173,7 @@ void Scene4050::Action4::signal() {
case 5:
scene->_hotspot16.setStrip2(4);
scene->_hotspot16.setFrame(1);
- scene->_hotspot16.animate(ANIM_MODE_4, 4, 1, this);;
+ scene->_hotspot16.animate(ANIM_MODE_4, 4, 1, this);
break;
case 6:
scene->_hotspot16.animate(ANIM_MODE_5, NULL);
@@ -2810,7 +2810,7 @@ void Scene4150::Action1::signal() {
case 4: {
for (int idx = 100; idx >= 0; idx -= 5) {
g_globals->_scenePalette.fade(adjustData, false, idx);
- g_system->updateScreen();
+ GLOBALS._screenSurface.updateScreen();
g_system->delayMillis(10);
}
@@ -2838,7 +2838,7 @@ void Scene4150::Action1::signal() {
case 7:
for (int idx = 100; idx >= 0; idx -= 5) {
g_globals->_scenePalette.fade(adjustData, false, idx);
- g_system->updateScreen();
+ GLOBALS._screenSurface.updateScreen();
g_system->delayMillis(10);
}
@@ -4311,7 +4311,7 @@ void Scene4301::Action1::signal() {
setDelay(20);
break;
case 21:
- scene->_field68E = true;
+ scene->_puzzleDone = true;
remove();
break;
}
@@ -4412,7 +4412,7 @@ void Scene4301::postInit(SceneObjectList *OwnerList) {
Scene::postInit();
setZoomPercents(0, 100, 200, 100);
- _field68E = false;
+ _puzzleDone = false;
RING_INVENTORY._stasisBox2._sceneNumber = 1;
_hotspot4.setDetails(97, 76, 127, 102, 4300, 5, 6);
@@ -4432,8 +4432,8 @@ void Scene4301::postInit(SceneObjectList *OwnerList) {
void Scene4301::dispatch() {
if (_action) {
_action->dispatch();
- } else if (_field68E) {
- _field68E = 0;
+ } else if (_puzzleDone) {
+ _puzzleDone = false;
g_globals->clearFlag(50);
g_globals->_sceneManager._fadeMode = FADEMODE_NONE;
g_globals->_sceneManager.setNewScene(4300);
diff --git a/engines/tsage/ringworld/ringworld_scenes5.h b/engines/tsage/ringworld/ringworld_scenes5.h
index 80e67755bd..c93df2a1d8 100644
--- a/engines/tsage/ringworld/ringworld_scenes5.h
+++ b/engines/tsage/ringworld/ringworld_scenes5.h
@@ -215,10 +215,10 @@ class Scene4025 : public Scene {
};
class Peg : public SceneObject {
public:
- int _field88;
+ int _pegId;
int _armStrip;
- Peg() : SceneObject() { _field88 = 0; _armStrip = 3; }
+ Peg() : SceneObject() { _pegId = 0; _armStrip = 3; }
virtual void synchronize(Serializer &s);
virtual void doAction(int action);
};
@@ -682,13 +682,13 @@ public:
SceneObject _hotspot1, _hotspot2, _hotspot3;
Hotspot4 _hotspot4;
Hotspot5 _hotspot5;
- bool _field68E;
+ bool _puzzleDone;
virtual void postInit(SceneObjectList *OwnerList = NULL);
virtual void dispatch();
virtual void synchronize(Serializer &s) {
Scene::synchronize(s);
- s.syncAsSint16LE(_field68E);
+ s.syncAsSint16LE(_puzzleDone);
}
};
diff --git a/engines/tsage/ringworld/ringworld_scenes6.cpp b/engines/tsage/ringworld/ringworld_scenes6.cpp
index 57a073caee..30a91b57aa 100644
--- a/engines/tsage/ringworld/ringworld_scenes6.cpp
+++ b/engines/tsage/ringworld/ringworld_scenes6.cpp
@@ -1124,7 +1124,7 @@ void Scene5100::postInit(SceneObjectList *OwnerList) {
_hotspot4.setVisage(5363);
_hotspot4.setPosition(Common::Point(1025, 65));
_hotspot4.setStrip(4);
- _hotspot4.animate(ANIM_MODE_7, 0, NULL);;
+ _hotspot4.animate(ANIM_MODE_7, 0, NULL);
g_globals->_sceneItems.push_back(&_hotspot4);
_hotspot9.postInit();
diff --git a/engines/tsage/ringworld/ringworld_scenes8.cpp b/engines/tsage/ringworld/ringworld_scenes8.cpp
index f8fb8b01e7..9cb85a6930 100644
--- a/engines/tsage/ringworld/ringworld_scenes8.cpp
+++ b/engines/tsage/ringworld/ringworld_scenes8.cpp
@@ -1879,12 +1879,12 @@ void Scene7700::SceneHotspot8::doAction(int action) {
scene->_soundHandler.play(259);
scene->_object15.setFrame(scene->_object15.getFrameCount());
scene->_object15.animate(ANIM_MODE_6, scene);
- if ((scene->_field977 == 2) && (scene->_field97B == 0)) {
- scene->_field979++;
+ if ((scene->_seatCountLeft1 == 2) && (scene->_seatCountLeft2 == 0)) {
+ scene->_seatCountRight++;
} else {
- scene->_field97B = 0;
- scene->_field979 = 0;
- scene->_field977 = 0;
+ scene->_seatCountLeft2 = 0;
+ scene->_seatCountRight = 0;
+ scene->_seatCountLeft1 = 0;
}
break;
default:
@@ -1905,26 +1905,26 @@ void Scene7700::SceneHotspot9::doAction(int action) {
scene->_soundHandler.play(259);
scene->_object15.setFrame(1);
scene->_object15.animate(ANIM_MODE_5, scene);
- if (scene->_field977 > 2) {
- scene->_field97B = 0;
- scene->_field979 = 0;
- scene->_field977 = 0;
+ if (scene->_seatCountLeft1 > 2) {
+ scene->_seatCountLeft2 = 0;
+ scene->_seatCountRight = 0;
+ scene->_seatCountLeft1 = 0;
}
- if (scene->_field979 != 0) {
- if (scene->_field979 != 4) {
- scene->_field97B = 0;
- scene->_field979 = 0;
- scene->_field977 = 0;
+ if (scene->_seatCountRight != 0) {
+ if (scene->_seatCountRight != 4) {
+ scene->_seatCountLeft2 = 0;
+ scene->_seatCountRight = 0;
+ scene->_seatCountLeft1 = 0;
} else {
- scene->_field97B++;
- if (scene->_field97B == 3) {
+ scene->_seatCountLeft2++;
+ if (scene->_seatCountLeft2 == 3) {
g_globals->_player.disableControl();
scene->setAction(&scene->_action3);
}
}
} else {
- scene->_field977++;
+ scene->_seatCountLeft1++;
}
break;
default:
@@ -2315,9 +2315,9 @@ void Scene7700::postInit(SceneObjectList *OwnerList) {
Scene::postInit();
setZoomPercents(100, 80, 200, 100);
g_globals->setFlag(53);
- _field97B = 0;
- _field979 = 0;
- _field977 = 0;
+ _seatCountLeft2 = 0;
+ _seatCountRight = 0;
+ _seatCountLeft1 = 0;
_stripManager.addSpeaker(&_speakerEText);
_stripManager.addSpeaker(&_speakerQText);
@@ -2538,9 +2538,9 @@ Scene7700::Scene7700() {
void Scene7700::synchronize(Serializer &s) {
Scene::synchronize(s);
if (s.getVersion() >= 3) {
- s.syncAsSint16LE(_field977);
- s.syncAsSint16LE(_field979);
- s.syncAsSint16LE(_field97B);
+ s.syncAsSint16LE(_seatCountLeft1);
+ s.syncAsSint16LE(_seatCountRight);
+ s.syncAsSint16LE(_seatCountLeft2);
}
}
diff --git a/engines/tsage/ringworld/ringworld_scenes8.h b/engines/tsage/ringworld/ringworld_scenes8.h
index 84178c36f9..b24f220f8c 100644
--- a/engines/tsage/ringworld/ringworld_scenes8.h
+++ b/engines/tsage/ringworld/ringworld_scenes8.h
@@ -480,7 +480,7 @@ public:
SceneHotspot11 _sceneHotspot34;
SceneHotspot11 _sceneHotspot35;
SceneHotspot11 _sceneHotspot36;
- int _field977, _field979, _field97B;
+ int _seatCountLeft1, _seatCountRight, _seatCountLeft2;
Scene7700();
virtual void postInit(SceneObjectList *OwnerList = NULL);
diff --git a/engines/tsage/ringworld2/ringworld2_dialogs.cpp b/engines/tsage/ringworld2/ringworld2_dialogs.cpp
index 8d4863f332..30ae6be7b1 100644
--- a/engines/tsage/ringworld2/ringworld2_dialogs.cpp
+++ b/engines/tsage/ringworld2/ringworld2_dialogs.cpp
@@ -31,6 +31,7 @@
#include "tsage/staticres.h"
#include "tsage/globals.h"
#include "tsage/ringworld2/ringworld2_dialogs.h"
+#include "tsage/ringworld2/ringworld2_logic.h"
namespace TsAGE {
@@ -49,7 +50,7 @@ RightClickDialog::RightClickDialog() : GfxDialog() {
_btnList[5] = Common::Point(83, 47);
// Set the palette and change the cursor
- BF_GLOBALS._events.setCursor(CURSOR_ARROW);
+ R2_GLOBALS._events.setCursor(CURSOR_ARROW);
setPalette();
@@ -95,7 +96,7 @@ bool RightClickDialog::process(Event &event) {
case EVENT_MOUSE_MOVE: {
// Check whether a button is highlighted
int buttonIndex;
- for (buttonIndex = 6; buttonIndex >= 0; --buttonIndex) {
+ for (buttonIndex = 5; buttonIndex >= 0; --buttonIndex) {
Rect tempRect(0, 0, 28, 29);
tempRect.moveTo(_btnList[buttonIndex].x, _btnList[buttonIndex].y);
@@ -152,7 +153,7 @@ void RightClickDialog::execute() {
}
g_system->delayMillis(10);
- g_system->updateScreen();
+ GLOBALS._screenSurface.updateScreen();
}
// Execute the specified action
@@ -176,6 +177,7 @@ void RightClickDialog::execute() {
break;
case 4:
// Change player
+ CharacterDialog::show();
break;
case 5:
// Options dialog
@@ -183,11 +185,263 @@ void RightClickDialog::execute() {
}
if (cursorNum != CURSOR_NONE)
- BF_GLOBALS._events.setCursor(cursorNum);
+ R2_GLOBALS._events.setCursor(cursorNum);
_gfxManager.deactivate();
}
+/*--------------------------------------------------------------------------*/
+
+void CharacterDialog::show() {
+ CharacterDialog *dlg = new CharacterDialog();
+ dlg->draw();
+
+ // Make the default button the currently active character
+ GfxButton *btn = NULL;
+ int oldCharacter = R2_GLOBALS._player._characterIndex;
+ switch (oldCharacter) {
+ case 1:
+ btn = &dlg->_btnQuinn;
+ break;
+ case 2:
+ btn = &dlg->_btnSeeker;
+ break;
+ case 3:
+ btn = &dlg->_btnMiranda;
+ break;
+ default:
+ break;
+ }
+
+ // Show the character selection dialog
+ btn = dlg->execute(btn);
+
+ // Figure out the new selected character
+ if (btn == &dlg->_btnQuinn)
+ R2_GLOBALS._player._characterIndex = R2_QUINN;
+ else if (btn == &dlg->_btnSeeker)
+ R2_GLOBALS._player._characterIndex = R2_SEEKER;
+ else if (btn == &dlg->_btnMiranda)
+ R2_GLOBALS._player._characterIndex = R2_MIRANDA;
+
+ // Remove the dialog
+ dlg->remove();
+ delete dlg;
+
+ // Only do transfer if a different character was selected
+ if (R2_GLOBALS._player._characterIndex != oldCharacter) {
+ // Save the details of the previously active character
+ SceneExt *scene = (SceneExt *)R2_GLOBALS._sceneManager._scene;
+ scene->saveCharacter(oldCharacter);
+
+ // Play a transition sound as the character is changed
+ if (R2_GLOBALS._player._characterScene[0] != 300) {
+ switch (R2_GLOBALS._v565F1[R2_GLOBALS._player._characterIndex]) {
+ case 0:
+ R2_GLOBALS._sound4.stop();
+ break;
+ case 1:
+ R2_GLOBALS._sound4.play(45);
+ break;
+ case 2:
+ R2_GLOBALS._sound4.play(4);
+ break;
+ case 3:
+ R2_GLOBALS._sound4.play(5);
+ break;
+ case 4:
+ R2_GLOBALS._sound4.play(6);
+ break;
+ default:
+ break;
+ }
+ } else if (R2_GLOBALS._v565F1[R2_GLOBALS._player._characterIndex] > 1) {
+ switch (R2_GLOBALS._v565F1[R2_GLOBALS._player._characterIndex]) {
+ case 2:
+ R2_GLOBALS._sound4.play(45);
+ break;
+ case 3:
+ R2_GLOBALS._sound4.play(4);
+ break;
+ case 4:
+ R2_GLOBALS._sound4.play(5);
+ break;
+ case 5:
+ R2_GLOBALS._sound4.play(6);
+ break;
+ default:
+ break;
+ }
+ } else if ((R2_GLOBALS._player._characterScene[1] == 300) && (R2_GLOBALS._v565F1[1] != 1)) {
+ switch (R2_GLOBALS._v565F1[1]) {
+ case 2:
+ R2_GLOBALS._sound4.play(45);
+ break;
+ case 3:
+ R2_GLOBALS._sound4.play(4);
+ break;
+ case 4:
+ R2_GLOBALS._sound4.play(5);
+ break;
+ case 5:
+ R2_GLOBALS._sound4.play(6);
+ break;
+ default:
+ break;
+ }
+ } else if (R2_GLOBALS._player._characterScene[2] != 300) {
+ R2_GLOBALS._sound4.stop();
+ } else if (R2_GLOBALS._v565F1[2] == 1) {
+ R2_GLOBALS._sound4.stop();
+ } else {
+ switch (R2_GLOBALS._v565F1[1]) {
+ case 2:
+ R2_GLOBALS._sound4.play(45);
+ break;
+ case 3:
+ R2_GLOBALS._sound4.play(4);
+ break;
+ case 4:
+ R2_GLOBALS._sound4.play(5);
+ break;
+ case 5:
+ R2_GLOBALS._sound4.play(6);
+ break;
+ default:
+ break;
+ }
+ }
+
+ // Change to whichever scene the newly selected character is in
+ R2_GLOBALS._sceneManager.changeScene(R2_GLOBALS._player._characterScene[R2_GLOBALS._player._characterIndex]);
+ }
+}
+
+CharacterDialog::CharacterDialog() {
+ // Set the element text
+ _msgTitle.set(CHAR_TITLE, 140, ALIGN_LEFT);
+ _btnQuinn.setText(CHAR_QUINN_MSG);
+ _btnSeeker.setText(CHAR_SEEKER_MSG);
+ _btnMiranda.setText(CHAR_MIRANDA_MSG);
+ _btnCancel.setText(CHAR_CANCEL_MSG);
+
+ // Set position of the elements
+ _msgTitle._bounds.moveTo(5, 5);
+ _btnQuinn._bounds.moveTo(25, _msgTitle._bounds.bottom + 1);
+ _btnSeeker._bounds.moveTo(25, _btnQuinn._bounds.bottom + 1);
+ _btnMiranda._bounds.moveTo(25, _btnSeeker._bounds.bottom + 1);
+ _btnCancel._bounds.moveTo(25, _btnMiranda._bounds.bottom + 1);
+
+ // Add the items to the dialog
+ addElements(&_msgTitle, &_btnQuinn, &_btnSeeker, &_btnMiranda, &_btnCancel, NULL);
+
+ // Set the dialog size and position
+ frame();
+ _bounds.collapse(-6, -6);
+ setCenter(160, 100);
+}
+
+/*--------------------------------------------------------------------------*/
+
+void HelpDialog::show() {
+ // Set the palette and change the cursor
+ R2_GLOBALS._events.setCursor(CURSOR_ARROW);
+
+ // Create the dialog and draw it
+ HelpDialog *dlg = new HelpDialog();
+ dlg->draw();
+
+ // Show the character selection dialog
+ GfxButton *btn = dlg->execute(&dlg->_btnResume);
+
+ // If a function button was selected, take care of it
+ Event evt;
+ evt.eventType = EVENT_KEYPRESS;
+ evt.kbd.keycode = Common::KEYCODE_INVALID;
+ if (btn == &dlg->_btnList[0]) {
+ evt.kbd.keycode = Common::KEYCODE_F2;
+ } else if (btn == &dlg->_btnList[1]) {
+ evt.kbd.keycode = Common::KEYCODE_F3;
+ } else if (btn == &dlg->_btnList[2]) {
+ evt.kbd.keycode = Common::KEYCODE_F4;
+ } else if (btn == &dlg->_btnList[3]) {
+ evt.kbd.keycode = Common::KEYCODE_F5;
+ } else if (btn == &dlg->_btnList[4]) {
+ evt.kbd.keycode = Common::KEYCODE_F7;
+ } else if (btn == &dlg->_btnList[5]) {
+ evt.kbd.keycode = Common::KEYCODE_F8;
+ } else if (btn == &dlg->_btnList[6]) {
+ evt.kbd.keycode = Common::KEYCODE_F10;
+ }
+
+ // Remove the dialog
+ dlg->remove();
+ delete dlg;
+
+ // If a action button was selected, dispatch to handle it
+ if (evt.kbd.keycode != Common::KEYCODE_INVALID)
+ R2_GLOBALS._game->processEvent(evt);
+}
+
+HelpDialog::HelpDialog() {
+ // Set the title and game version
+ _msgTitle.set(HELP_MSG, 172, ALIGN_CENTER);
+ _msgTitle._bounds.moveTo(5, 0);
+ _msgVersion.set(GAME_VERSION, 172, ALIGN_CENTER);
+ _msgVersion._bounds.moveTo(5, _msgTitle._bounds.bottom + 3);
+ addElements(&_msgTitle, &_msgVersion, NULL);
+
+ // Set buttons
+ _btnList[0].setText(F2);
+ _btnList[0]._bounds.moveTo(5, _msgVersion._bounds.bottom + 2);
+ _btnDescription[0].set(SOUND_OPTIONS, 140, ALIGN_LEFT);
+ _btnDescription[0]._bounds.moveTo(_btnList[0]._bounds.right + 2, _btnList[0]._bounds.top + 4);
+
+ _btnList[1].setText(F3);
+ _btnList[1]._bounds.moveTo(5, _btnList[0]._bounds.bottom);
+ _btnDescription[1].set(QUIT_GAME, 140, ALIGN_LEFT);
+ _btnDescription[1]._bounds.moveTo(_btnList[1]._bounds.right + 2, _btnList[1]._bounds.top + 4);
+
+ _btnList[2].setText(F4);
+ _btnList[2]._bounds.moveTo(5, _btnList[1]._bounds.bottom);
+ _btnDescription[2].set(RESTART_GAME, 140, ALIGN_LEFT);
+ _btnDescription[2]._bounds.moveTo(_btnList[2]._bounds.right + 2, _btnList[2]._bounds.top + 4);
+
+ _btnList[3].setText(F5);
+ _btnList[3]._bounds.moveTo(5, _btnList[2]._bounds.bottom);
+ _btnDescription[3].set(SAVE_GAME, 140, ALIGN_LEFT);
+ _btnDescription[3]._bounds.moveTo(_btnList[3]._bounds.right + 2, _btnList[3]._bounds.top + 4);
+
+ _btnList[4].setText(F7);
+ _btnList[4]._bounds.moveTo(5, _btnList[3]._bounds.bottom);
+ _btnDescription[4].set(RESTORE_GAME, 140, ALIGN_LEFT);
+ _btnDescription[4]._bounds.moveTo(_btnList[4]._bounds.right + 2, _btnList[4]._bounds.top + 4);
+
+ _btnList[5].setText(F8);
+ _btnList[5]._bounds.moveTo(5, _btnList[4]._bounds.bottom);
+ _btnDescription[5].set(SHOW_CREDITS, 140, ALIGN_LEFT);
+ _btnDescription[5]._bounds.moveTo(_btnList[5]._bounds.right + 2, _btnList[5]._bounds.top + 4);
+
+ _btnList[6].setText(F10);
+ _btnList[6]._bounds.moveTo(5, _btnList[5]._bounds.bottom);
+ _btnDescription[6].set(PAUSE_GAME, 140, ALIGN_LEFT);
+ _btnDescription[6]._bounds.moveTo(_btnList[6]._bounds.right + 2, _btnList[6]._bounds.top + 4);
+
+ for (int i = 0; i < 7; ++i) {
+ addElements(&_btnList[i], &_btnDescription[i], NULL);
+ }
+
+ // Add 'Resume' button
+ _btnResume.setText(RESUME_PLAY);
+ _btnResume._bounds.moveTo(5, _btnList[6]._bounds.bottom + 2);
+ addElements(&_btnResume, NULL);
+
+ // Set the dialog size and position
+ frame();
+ _bounds.collapse(-6, -6);
+ setCenter(160, 100);
+}
+
} // End of namespace Ringworld2
} // End of namespace TsAGE
diff --git a/engines/tsage/ringworld2/ringworld2_dialogs.h b/engines/tsage/ringworld2/ringworld2_dialogs.h
index bbc35da3ea..02a1aed81c 100644
--- a/engines/tsage/ringworld2/ringworld2_dialogs.h
+++ b/engines/tsage/ringworld2/ringworld2_dialogs.h
@@ -59,6 +59,31 @@ public:
void execute();
};
+class CharacterDialog: public GfxDialog {
+private:
+ GfxMessage _msgTitle;
+ GfxButton _btnQuinn, _btnMiranda, _btnSeeker;
+ GfxButton _btnCancel;
+public:
+ CharacterDialog();
+ virtual ~CharacterDialog() {}
+
+ static void show();
+};
+
+class HelpDialog: public GfxDialog {
+private:
+ GfxMessage _msgTitle, _msgVersion;
+ GfxButton _btnList[7];
+ GfxMessage _btnDescription[7];
+ GfxButton _btnResume;
+public:
+ HelpDialog();
+ virtual ~HelpDialog() {}
+
+ static void show();
+};
+
} // End of namespace Ringworld2
} // End of namespace TsAGE
diff --git a/engines/tsage/ringworld2/ringworld2_logic.cpp b/engines/tsage/ringworld2/ringworld2_logic.cpp
index 0bdcf36d0c..a06899fe5a 100644
--- a/engines/tsage/ringworld2/ringworld2_logic.cpp
+++ b/engines/tsage/ringworld2/ringworld2_logic.cpp
@@ -27,17 +27,255 @@
#include "tsage/ringworld2/ringworld2_logic.h"
#include "tsage/ringworld2/ringworld2_dialogs.h"
#include "tsage/ringworld2/ringworld2_scenes0.h"
+#include "tsage/ringworld2/ringworld2_scenes1.h"
+#include "tsage/ringworld2/ringworld2_scenes2.h"
+#include "tsage/ringworld2/ringworld2_scenes3.h"
namespace TsAGE {
namespace Ringworld2 {
Scene *Ringworld2Game::createScene(int sceneNumber) {
+ warning("Switching to scene %d", sceneNumber);
+
switch (sceneNumber) {
/* Scene group #0 */
- // Quinn's room
- case 100: return new Scene100();
-
+ case 50:
+ // Waking up cutscene
+ return new Scene50();
+ case 100:
+ // Quinn's room
+ return new Scene100();
+ case 125:
+ // Computer console
+ return new Scene125();
+ case 150:
+ // Empty Bedroom #1
+ return new Scene150();
+ case 160:
+ // Credits
+ return new Scene160();
+ case 175:
+ // Empty Bedroom #2
+ return new Scene175();
+ case 180:
+ // Title Screen
+ return new Scene180();
+ case 200:
+ // Deck #2 - By Lift
+ return new Scene200();
+ case 205:
+ // Star-field Credits
+ return new Scene205();
+ case 250:
+ // Lift
+ return new Scene250();
+ case 300:
+ // Bridge
+ return new Scene300();
+ case 325:
+ // Bridge Console
+ return new Scene325();
+ case 400:
+ // Science Lab
+ return new Scene400();
+ case 500:
+ // Lander Bay 2 Storage
+ return new Scene500();
+ case 525:
+ // Cutscene - Walking in hall
+ return new Scene525();
+ case 600:
+ return new Scene600();
+ case 700:
+ return new Scene700();
+ case 800:
+ // Sick bay
+ return new Scene800();
+ case 825:
+ // Autodoc
+ return new Scene825();
+ case 850:
+ // Deck #5 - By Lift
+ return new Scene850();
+ case 900:
+ return new Scene900();
+ /* Scene group #1 */
+ //
+ case 1000:
+ error("Missing scene %d from group 1", sceneNumber);
+ case 1010:
+ // Cutscene - trip in space
+ return new Scene1010();
+ case 1020:
+ return new Scene1020();
+ case 1100:
+ return new Scene1100();
+ case 1200:
+ return new Scene1200();
+ case 1337:
+ case 1330:
+ // Card Game
+ return new Scene1337();
+ case 1500:
+ // Cutscene: Ship landing
+ return new Scene1500();
+ case 1525:
+ // Cutscene - Ship
+ return new Scene1525();
+ case 1530:
+ // Cutscene - Elevator
+ return new Scene1530();
+ case 1550:
+ return new Scene1550();
+ case 1575:
+ return new Scene1575();
+ case 1580:
+ // Inside wreck
+ return new Scene1580();
+ case 1625:
+ // Miranda being questioned
+ return new Scene1625();
+ case 1700:
+ return new Scene1700();
+ case 1750:
+ return new Scene1750();
+ case 1800:
+ return new Scene1800();
+ case 1850:
+ return new Scene1850();
+ case 1875:
+ return new Scene1875();
+ case 1900:
+ return new Scene1900();
+ case 1925:
+ return new Scene1925();
+ case 1945:
+ return new Scene1945();
+ case 1950:
+ return new Scene1950();
+ /* Scene group #2 */
+ //
+ case 2000:
+ // Ice Maze
+ return new Scene2000();
+ case 2350:
+ // Ice Maze: Balloon Launch Platform
+ return new Scene2350();
+ case 2400:
+ // Ice Maze: Large empty room
+ return new Scene2400();
+ case 2425:
+ // Ice Maze:
+ return new Scene2425();
+ case 2430:
+ // Ice Maze: Bedroom
+ return new Scene2430();
+ case 2435:
+ // Ice Maze: Throne room
+ return new Scene2435();
+ case 2440:
+ // Ice Maze: Another bedroom
+ return new Scene2440();
+ case 2445:
+ // Ice Maze:
+ return new Scene2445();
+ case 2450:
+ // Ice Maze: Another bedroom
+ return new Scene2450();
+ case 2455:
+ // Ice Maze: Inside crevasse
+ return new Scene2455();
+ case 2500:
+ // Ice Maze: Large Cave
+ return new Scene2500();
+ case 2525:
+ // Ice Maze: Furnace room
+ return new Scene2525();
+ case 2530:
+ // Ice Maze: Well
+ return new Scene2530();
+ case 2535:
+ // Ice Maze: Tannery
+ return new Scene2535();
+ case 2600:
+ // Ice Maze: Exit
+ return new Scene2600();
+ case 2700:
+ // Forest Maze
+ return new Scene2700();
+ case 2750:
+ // Forest Maze
+ return new Scene2750();
+ case 2800:
+ // Exiting Forest
+ return new Scene2800();
+ case 2900:
+ error("Missing scene %d from group 2", sceneNumber);
+ /* Scene group #3 */
+ //
+ case 3100:
+ return new Scene3100();
+ case 3125:
+ // Ghouls dormitory
+ return new Scene3125();
+ case 3150:
+ // Jail
+ return new Scene3150();
+ case 3175:
+ // Autopsy room
+ return new Scene3175();
+ case 3200:
+ // Cutscene : Guards - Discussion
+ return new Scene3200();
+ case 3210:
+ // Cutscene : Captain and Private - Discussion
+ return new Scene3210();
+ case 3220:
+ // Cutscene : Guards in cargo zone
+ return new Scene3220();
+ case 3230:
+ // Cutscene : Guards on duty
+ return new Scene3230();
+ case 3240:
+ // Cutscene : Teal monolog
+ return new Scene3240();
+ case 3245:
+ // Cutscene : Discussions with Dr. Tomko
+ return new Scene3245();
+ case 3250:
+ // Room with large stasis field negator
+ return new Scene3250();
+ case 3255:
+ return new Scene3255();
+ case 3260:
+ // Computer room
+ return new Scene3260();
+ case 3275:
+ // Hall
+ return new Scene3275();
+ case 3350:
+ // Cutscene - Ship landing
+ return new Scene3350();
+ case 3375:
+ return new Scene3375();
+ case 3385:
+ return new Scene3385();
+ case 3395:
+ return new Scene3395();
+ case 3400:
+ return new Scene3400();
+ case 3500:
+ return new Scene3500();
+ case 3600:
+ return new Scene3600();
+ case 3700:
+ // Cutscene - Teleport outside
+ return new Scene3700();
+ case 3800:
+ return new Scene3800();
+ case 3900:
+ return new Scene3900();
default:
error("Unknown scene number - %d", sceneNumber);
break;
@@ -48,14 +286,16 @@ Scene *Ringworld2Game::createScene(int sceneNumber) {
* Returns true if it is currently okay to restore a game
*/
bool Ringworld2Game::canLoadGameStateCurrently() {
- return true;
+ // Don't allow a game to be loaded if a dialog is active
+ return g_globals->_gfxManagers.size() == 1;
}
/**
* Returns true if it is currently okay to save the game
*/
bool Ringworld2Game::canSaveGameStateCurrently() {
- return true;
+ // Don't allow a game to be saved if a dialog is active
+ return g_globals->_gfxManagers.size() == 1;
}
/*--------------------------------------------------------------------------*/
@@ -64,6 +304,8 @@ SceneExt::SceneExt(): Scene() {
_stripManager._onBegin = SceneExt::startStrip;
_stripManager._onEnd = SceneExt::endStrip;
+ for (int i = 0; i < 256; i++)
+ _field312[i] = 0;
_field372 = _field37A = 0;
_savedPlayerEnabled = false;
_savedUiEnabled = false;
@@ -76,21 +318,29 @@ void SceneExt::postInit(SceneObjectList *OwnerList) {
// Exclude the bottom area of the screen to allow room for the UI
T2_GLOBALS._interfaceY = UI_INTERFACE_Y;
+
+ // Initialise fields
+ _action = NULL;
+ _field12 = 0;
+ _sceneMode = 0;
+
+ int prevScene = R2_GLOBALS._sceneManager._previousScene;
+ int sceneNumber = R2_GLOBALS._sceneManager._sceneNumber;
+ if (((prevScene == -1) && (sceneNumber != 180) && (sceneNumber != 205) && (sceneNumber != 50))
+ || (sceneNumber == 50)
+ || ((prevScene == 205) && (sceneNumber == 100))
+ || ((prevScene == 180) && (sceneNumber == 100))) {
+ static_cast<SceneHandlerExt *>(R2_GLOBALS._sceneHandler)->setupPaletteMaps();
+ R2_GLOBALS._uiElements._active = true;
+ R2_GLOBALS._uiElements.show();
+ } else {
+ R2_GLOBALS._uiElements.updateInventory();
+ }
}
void SceneExt::remove() {
-/*
- R2_GLOBALS._uiElements.hide();
- R2_GLOBALS._uiElements.resetClear();
-
- if (_action) {
- if (_action->_endHandler)
- _action->_endHandler = NULL;
- _action->remove();
- }
-
- _focusObject = NULL;
-*/
+ _sceneAreas.clear();
+ Scene::remove();
}
void SceneExt::process(Event &event) {
@@ -120,23 +370,71 @@ void SceneExt::loadScene(int sceneNum) {
_v51C34.top = 0;
_v51C34.bottom = 300;
+
+ int prevScene = R2_GLOBALS._sceneManager._previousScene;
+ int sceneNumber = R2_GLOBALS._sceneManager._sceneNumber;
+
+ if (((prevScene == -1) && (sceneNumber != 180) && (sceneNumber != 205) && (sceneNumber != 50)) ||
+ (sceneNumber == 50) || ((prevScene == 205) && (sceneNumber == 100)) ||
+ ((prevScene == 180) && (sceneNumber == 100))) {
+ // TODO: sub_17875
+ R2_GLOBALS._uiElements._active = true;
+ R2_GLOBALS._uiElements.show();
+ } else {
+ // Update the user interface
+ R2_GLOBALS._uiElements.updateInventory();
+ }
}
-bool SceneExt::display(CursorType action) {
+bool SceneExt::display(CursorType action, Event &event) {
switch (action) {
+ case CURSOR_CROSSHAIRS:
+ case CURSOR_WALK:
+ return false;
case CURSOR_LOOK:
- SceneItem::display2(9000, R2_GLOBALS._randomSource.getRandomNumber(2));
+ SceneItem::display2(1, R2_GLOBALS._randomSource.getRandomNumber(4));
break;
case CURSOR_USE:
- SceneItem::display2(9000, R2_GLOBALS._randomSource.getRandomNumber(2) + 6);
+ SceneItem::display2(1, R2_GLOBALS._randomSource.getRandomNumber(4) + 5);
break;
case CURSOR_TALK:
- SceneItem::display2(9000, R2_GLOBALS._randomSource.getRandomNumber(2) + 3);
+ SceneItem::display2(1, R2_GLOBALS._randomSource.getRandomNumber(4) + 10);
+ break;
+ case R2_NEGATOR_GUN:
+ if (R2_GLOBALS.getFlag(1))
+ SceneItem::display2(2, action);
+ else
+ SceneItem::display2(5, 0);
+ break;
+ case R2_SONIC_STUNNER:
+ if ((R2_GLOBALS._v565F1[1] == 2) || ((R2_GLOBALS._v565F1[1] == 1) &&
+ (R2_GLOBALS._v565F1[2] == 2) && (R2_GLOBALS._sceneManager._previousScene == 300))) {
+ R2_GLOBALS._sound4.stop();
+ R2_GLOBALS._sound3.play(46);
+ SceneItem::display2(5, 15);
+ } else {
+ R2_GLOBALS._sound3.play(43, 0);
+ SceneItem::display2(2, 0);
+ }
+
+ R2_GLOBALS._sound4.play(45);
+ break;
+ case R2_COM_SCANNER:
+ case R2_COM_SCANNER_2:
+ R2_GLOBALS._sound3.play(44);
+ SceneItem::display2(2, action);
+ R2_GLOBALS._sound3.stop();
+ break;
+ case R2_PHOTON_STUNNER:
+ R2_GLOBALS._sound3.play(99);
+ SceneItem::display2(2, action);
break;
default:
- return false;
+ SceneItem::display2(2, action);
+ break;
}
+ event.handled = true;
return true;
}
@@ -219,6 +517,162 @@ void SceneExt::refreshBackground(int xAmount, int yAmount) {
DEALLOCATE(dataP);
}
+/**
+ * Saves the current player position and view in the details for the specified character index
+ */
+void SceneExt::saveCharacter(int characterIndex) {
+ R2_GLOBALS._player._characterPos[characterIndex] = R2_GLOBALS._player._position;
+ R2_GLOBALS._player._characterStrip[characterIndex] = R2_GLOBALS._player._strip;
+ R2_GLOBALS._player._characterFrame[characterIndex] = R2_GLOBALS._player._frame;
+}
+
+void SceneExt::scalePalette(int RFactor, int GFactor, int BFactor) {
+ byte *tmpPal = R2_GLOBALS._scenePalette._palette;
+ byte newR, newG, newB;
+ int tmp, varC, varD = 0;
+
+ for (int i = 0; i < 256; i++) {
+ newR = (RFactor * tmpPal[(3 * i)]) / 100;
+ newG = (GFactor * tmpPal[(3 * i) + 1]) / 100;
+ newB = (BFactor * tmpPal[(3 * i) + 2]) / 100;
+
+ varC = 769;
+ for (int j = 255; j >= 0; j--) {
+ tmp = abs(tmpPal[(3 * j)] - newR);
+ if (tmp >= varC)
+ continue;
+
+ tmp += abs(tmpPal[(3 * j) + 1] - newG);
+ if (tmp >= varC)
+ continue;
+
+ tmp += abs(tmpPal[(3 * j) + 2] - newB);
+ if (tmp >= varC)
+ continue;
+
+ varC = tmp;
+ varD = j;
+ }
+ this->_field312[i] = varD;
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+
+void SceneHandlerExt::postInit(SceneObjectList *OwnerList) {
+ SceneHandler::postInit(OwnerList);
+}
+
+void SceneHandlerExt::process(Event &event) {
+ if (T2_GLOBALS._uiElements._active && R2_GLOBALS._player._uiEnabled) {
+ T2_GLOBALS._uiElements.process(event);
+ if (event.handled)
+ return;
+ }
+
+ SceneExt *scene = static_cast<SceneExt *>(R2_GLOBALS._sceneManager._scene);
+ if (scene && R2_GLOBALS._player._uiEnabled) {
+ // Handle any scene areas that have been registered
+ SynchronizedList<SceneArea *>::iterator saIter;
+ for (saIter = scene->_sceneAreas.begin(); saIter != scene->_sceneAreas.end() && !event.handled; ++saIter) {
+ (*saIter)->process(event);
+ }
+ }
+
+ if (!event.handled)
+ SceneHandler::process(event);
+}
+
+void SceneHandlerExt::setupPaletteMaps() {
+ byte *palP = &R2_GLOBALS._scenePalette._palette[0];
+
+ if (!R2_GLOBALS._v1000Flag) {
+ R2_GLOBALS._v1000Flag = true;
+
+ for (int idx = 0; idx < 10; ++idx) {
+ for (int palIndex = 0; palIndex < 224; ++palIndex) {
+ int r, g, b;
+
+ // Get adjusted RGB values
+ switch (idx) {
+ case 7:
+ r = palP[palIndex * 3] * 85 / 100;
+ g = palP[palIndex * 3 + 1] * 7 / 10;
+ b = palP[palIndex * 3 + 2] * 7 / 10;
+ break;
+ case 8:
+ r = palP[palIndex * 3] * 7 / 10;
+ g = palP[palIndex * 3 + 1] * 85 / 100;
+ b = palP[palIndex * 3 + 2] * 7 / 10;
+ break;
+ case 9:
+ r = palP[palIndex * 3] * 8 / 10;
+ g = palP[palIndex * 3 + 1] * 5 / 10;
+ b = palP[palIndex * 3 + 2] * 9 / 10;
+ break;
+ default:
+ r = palP[palIndex * 3] * (10 - idx) / 10;
+ g = palP[palIndex * 3 + 1] * (10 - idx) / 12;
+ b = palP[palIndex * 3 + 2] * (10 - idx) / 10;
+ break;
+ }
+
+ // Scan for the palette index with the closest matching colour
+ int threshold = 769;
+ int foundIndex = -1;
+ for (int pIndex2 = 223; pIndex2 >= 0; --pIndex2) {
+ int diffSum = ABS(palP[pIndex2 * 3] - r);
+ if (diffSum >= threshold)
+ continue;
+
+ diffSum += ABS(palP[pIndex2 * 3 + 1] - g);
+ if (diffSum >= threshold)
+ continue;
+
+ diffSum += ABS(palP[pIndex2 * 3 + 2] - b);
+ if (diffSum >= threshold)
+ continue;
+
+ threshold = diffSum;
+ foundIndex = pIndex2;
+ }
+
+ R2_GLOBALS._palIndexList[idx][palIndex] = foundIndex;
+ }
+ }
+ }
+
+ for (int palIndex = 0; palIndex < 224; ++palIndex) {
+ int r = palP[palIndex * 3] >> 2;
+ int g = palP[palIndex * 3 + 1] >> 2;
+ int b = palP[palIndex * 3 + 2] >> 2;
+
+ int idx = (((r << 4) | g) << 4) | b;
+ R2_GLOBALS._v1000[idx] = palIndex;
+ }
+
+ int vdx = 0;
+ int idx = 0;
+ int palIndex = 224;
+
+ for (int vIndex = 0; vIndex < 4096; ++vIndex) {
+ int v = R2_GLOBALS._v1000[vIndex];
+ if (!v) {
+ R2_GLOBALS._v1000[vIndex] = idx;
+ } else {
+ idx = v;
+ }
+
+ if (!palIndex) {
+ vdx = palIndex;
+ } else {
+ int idxTemp = palIndex;
+ palIndex = (palIndex + vdx) / 2;
+ vdx = idxTemp;
+ }
+ }
+}
+
/*--------------------------------------------------------------------------*/
DisplayHotspot::DisplayHotspot(int regionId, ...) {
@@ -281,7 +735,7 @@ Ringworld2InvObjectList::Ringworld2InvObjectList():
_none(1, 1),
_inv1(1, 2),
_inv2(1, 3),
- _inv3(1, 4),
+ _negatorGun(1, 4),
_steppingDisks(1, 5),
_inv5(1, 6),
_inv6(1, 7),
@@ -336,7 +790,7 @@ Ringworld2InvObjectList::Ringworld2InvObjectList():
_itemList.push_back(&_none);
_itemList.push_back(&_inv1);
_itemList.push_back(&_inv2);
- _itemList.push_back(&_inv3);
+ _itemList.push_back(&_negatorGun);
_itemList.push_back(&_steppingDisks);
_itemList.push_back(&_inv5);
_itemList.push_back(&_inv6);
@@ -398,58 +852,58 @@ void Ringworld2InvObjectList::reset() {
}
// Set up default inventory
- setObjectScene(R2_1, 800);
- setObjectScene(R2_2, 400);
- setObjectScene(R2_3, 100);
+ setObjectScene(R2_OPTO_DISK, 800);
+ setObjectScene(R2_READER, 400);
+ setObjectScene(R2_NEGATOR_GUN, 100);
setObjectScene(R2_STEPPING_DISKS, 100);
- setObjectScene(R2_5, 400);
- setObjectScene(R2_6, 400);
- setObjectScene(R2_7, 500);
- setObjectScene(R2_8, 700);
- setObjectScene(R2_9, 800);
- setObjectScene(R2_10, 100);
- setObjectScene(R2_11, 400);
- setObjectScene(R2_12, 500);
- setObjectScene(R2_13, 1550);
- setObjectScene(R2_14, 850);
- setObjectScene(R2_15, 850);
- setObjectScene(R2_16, 0);
- setObjectScene(R2_17, 1550);
- setObjectScene(R2_18, 1550);
- setObjectScene(R2_19, 1550);
- setObjectScene(R2_20, 500);
- setObjectScene(R2_21, 500);
- setObjectScene(R2_22, 1550);
- setObjectScene(R2_23, 1580);
- setObjectScene(R2_24, 9999);
- setObjectScene(R2_25, 1550);
- setObjectScene(R2_26, 1550);
- setObjectScene(R2_27, 1580);
- setObjectScene(R2_28, 1550);
- setObjectScene(R2_29, 2525);
- setObjectScene(R2_30, 2440);
- setObjectScene(R2_31, 2455);
- setObjectScene(R2_32, 2535);
- setObjectScene(R2_33, 2530);
- setObjectScene(R2_34, 1950);
- setObjectScene(R2_35, 1950);
- setObjectScene(R2_36, 9999);
- setObjectScene(R2_37, 2430);
- setObjectScene(R2_38, 9999);
- setObjectScene(R2_39, 2);
- setObjectScene(R2_40, 9999);
- setObjectScene(R2_41, 3150);
- setObjectScene(R2_42, 0);
- setObjectScene(R2_43, 3260);
- setObjectScene(R2_44, 2);
- setObjectScene(R2_45, 1550);
- setObjectScene(R2_46, 0);
- setObjectScene(R2_47, 3150);
- setObjectScene(R2_48, 2435);
- setObjectScene(R2_49, 2440);
- setObjectScene(R2_50, 2435);
- setObjectScene(R2_51, 1580);
- setObjectScene(R2_52, 3260);
+ setObjectScene(R2_ATTRACTOR_UNIT, 400);
+ setObjectScene(R2_SENSOR_PROBE, 400);
+ setObjectScene(R2_SONIC_STUNNER, 500);
+ setObjectScene(R2_CABLE_HARNESS, 700);
+ setObjectScene(R2_COM_SCANNER, 800);
+ setObjectScene(R2_SPENT_POWER_CAPSULE, 100);
+ setObjectScene(R2_CHARGED_POWER_CAPSULE, 400);
+ setObjectScene(R2_AEROSOL, 500);
+ setObjectScene(R2_REMOTE_CONTROL, 1550);
+ setObjectScene(R2_OPTICAL_FIBRE, 850);
+ setObjectScene(R2_CLAMP, 850);
+ setObjectScene(R2_ATTRACTOR_CABLE_HARNESS, 0);
+ setObjectScene(R2_FUEL_CELL, 1550);
+ setObjectScene(R2_GYROSCOPE, 1550);
+ setObjectScene(R2_AIRBAG, 1550);
+ setObjectScene(R2_REBREATHER_TANK, 500);
+ setObjectScene(R2_RESERVE_REBREATHER_TANK, 500);
+ setObjectScene(R2_GUIDANCE_MODULE, 1550);
+ setObjectScene(R2_THRUSTER_VALVE, 1580);
+ setObjectScene(R2_BALLOON_BACKPACK, 9999);
+ setObjectScene(R2_RADAR_MECHANISM, 1550);
+ setObjectScene(R2_JOYSTICK, 1550);
+ setObjectScene(R2_IGNITOR, 1580);
+ setObjectScene(R2_DIAGNOSTICS_DISPLAY, 1550);
+ setObjectScene(R2_GLASS_DOME, 2525);
+ setObjectScene(R2_WICK_LAMP, 2440);
+ setObjectScene(R2_SCRITH_KEY, 2455);
+ setObjectScene(R2_TANNER_MASK, 2535);
+ setObjectScene(R2_PURE_GRAIN_ALCOHOL, 2530);
+ setObjectScene(R2_SAPPHIRE_BLUE, 1950);
+ setObjectScene(R2_ANCIENT_SCROLLS, 1950);
+ setObjectScene(R2_FLUTE, 9999);
+ setObjectScene(R2_GUNPOWDER, 2430);
+ setObjectScene(R2_NONAME, 9999);
+ setObjectScene(R2_COM_SCANNER_2, 2);
+ setObjectScene(R2_SUPERCONDUCTOR_WIRE, 9999);
+ setObjectScene(R2_PILLOW, 3150);
+ setObjectScene(R2_FOOD_TRAY, 0);
+ setObjectScene(R2_LASER_HACKSAW, 3260);
+ setObjectScene(R2_PHOTON_STUNNER, 2);
+ setObjectScene(R2_BATTERY, 1550);
+ setObjectScene(R2_SOAKED_FACEMASK, 0);
+ setObjectScene(R2_LIGHT_BULB, 3150);
+ setObjectScene(R2_ALCOHOL_LAMP, 2435);
+ setObjectScene(R2_ALCOHOL_LAMP_2, 2440);
+ setObjectScene(R2_ALCOHOL_LAMP_3, 2435);
+ setObjectScene(R2_BROKEN_DISPLAY, 1580);
+ setObjectScene(R2_TOOLBOX, 3260);
}
void Ringworld2InvObjectList::setObjectScene(int objectNum, int sceneNumber) {
@@ -483,11 +937,12 @@ void Ringworld2Game::start() {
}
if (slot >= 0)
- g_globals->_sceneHandler->_loadGameSlot = slot;
+ R2_GLOBALS._sceneHandler->_loadGameSlot = slot;
else {
// Switch to the first game scene
- g_globals->_events.setCursor(CURSOR_WALK);
- g_globals->_sceneManager.setNewScene(100);
+ R2_GLOBALS._events.setCursor(CURSOR_WALK);
+ R2_GLOBALS._uiElements._active = true;
+ R2_GLOBALS._sceneManager.setNewScene(100);
}
g_globals->_events.showCursor();
@@ -536,7 +991,7 @@ void Ringworld2Game::processEvent(Event &event) {
switch (event.kbd.keycode) {
case Common::KEYCODE_F1:
// F1 - Help
-// MessageDialog::show(HELP_MSG, OK_BTN_STRING);
+ HelpDialog::show();
break;
case Common::KEYCODE_F2:
@@ -562,6 +1017,11 @@ void Ringworld2Game::processEvent(Event &event) {
g_globals->_events.setCursorFromFlag();
break;
+ case Common::KEYCODE_F8:
+ // F8 - Credits
+ warning("TODO: Show Credits");
+ break;
+
case Common::KEYCODE_F10:
// F10 - Pause
GfxDialog::setPalette();
@@ -616,84 +1076,13 @@ bool NamedHotspot::startAction(CursorType action, Event &event) {
}
}
-void NamedHotspot::setDetails(int ys, int xs, int ye, int xe, const int resnum, const int lookLineNum, const int useLineNum) {
- setBounds(ys, xe, ye, xs);
- _resNum = resnum;
- _lookLineNum = lookLineNum;
- _useLineNum = useLineNum;
- _talkLineNum = -1;
- g_globals->_sceneItems.addItems(this, NULL);
-}
-
-void NamedHotspot::setDetails(const Rect &bounds, int resNum, int lookLineNum, int talkLineNum, int useLineNum, int mode, SceneItem *item) {
- setBounds(bounds);
- _resNum = resNum;
- _lookLineNum = lookLineNum;
- _talkLineNum = talkLineNum;
- _useLineNum = useLineNum;
-
- switch (mode) {
- case 2:
- g_globals->_sceneItems.push_front(this);
- break;
- case 4:
- g_globals->_sceneItems.addBefore(item, this);
- break;
- case 5:
- g_globals->_sceneItems.addAfter(item, this);
- break;
- default:
- g_globals->_sceneItems.push_back(this);
- break;
- }
-}
-
-void NamedHotspot::setDetails(int sceneRegionId, int resNum, int lookLineNum, int talkLineNum, int useLineNum, int mode) {
- _sceneRegionId = sceneRegionId;
- _resNum = resNum;
- _lookLineNum = lookLineNum;
- _talkLineNum = talkLineNum;
- _useLineNum = useLineNum;
-
- // Handle adding hotspot to scene items list as necessary
- switch (mode) {
- case 2:
- GLOBALS._sceneItems.push_front(this);
- break;
- case 3:
- break;
- default:
- GLOBALS._sceneItems.push_back(this);
- break;
- }
-}
-
-void NamedHotspot::synchronize(Serializer &s) {
- SceneHotspot::synchronize(s);
- s.syncAsSint16LE(_resNum);
- s.syncAsSint16LE(_lookLineNum);
- s.syncAsSint16LE(_useLineNum);
-
- if (g_vm->getGameID() == GType_BlueForce)
- s.syncAsSint16LE(_talkLineNum);
-}
+/*--------------------------------------------------------------------------*/
void SceneActor::postInit(SceneObjectList *OwnerList) {
_lookLineNum = _talkLineNum = _useLineNum = -1;
SceneObject::postInit();
}
-void SceneActor::synchronize(Serializer &s) {
- SceneObject::synchronize(s);
- s.syncAsSint16LE(_resNum);
- s.syncAsSint16LE(_lookLineNum);
- s.syncAsSint16LE(_talkLineNum);
- s.syncAsSint16LE(_useLineNum);
-
- s.syncAsSint16LE(_effect);
- s.syncAsSint16LE(_shade);
-}
-
bool SceneActor::startAction(CursorType action, Event &event) {
bool handled = true;
@@ -722,39 +1111,895 @@ bool SceneActor::startAction(CursorType action, Event &event) {
}
if (!handled)
- handled = ((SceneExt *)R2_GLOBALS._sceneManager._scene)->display(action);
+ handled = ((SceneExt *)R2_GLOBALS._sceneManager._scene)->display(action, event);
return handled;
}
-void SceneActor::setDetails(int resNum, int lookLineNum, int talkLineNum, int useLineNum, int mode, SceneItem *item) {
- _resNum = resNum;
- _lookLineNum = lookLineNum;
- _talkLineNum = talkLineNum;
- _useLineNum = useLineNum;
+/*--------------------------------------------------------------------------*/
+
+SceneArea::SceneArea(): EventHandler() {
+ _enabled = true;
+ _insideArea = false;
+ _savedCursorNum = CURSOR_NONE;
+ _cursorState = 0;
+}
+
+void SceneArea::synchronize(Serializer &s) {
+ EventHandler::synchronize(s);
+
+ _bounds.synchronize(s);
+ s.syncAsSint16LE(_enabled);
+ s.syncAsSint16LE(_insideArea);
+ s.syncAsSint16LE(_cursorNum);
+ s.syncAsSint16LE(_savedCursorNum);
+ s.syncAsSint16LE(_cursorState);
+}
+
+void SceneArea::remove() {
+ static_cast<SceneExt *>(R2_GLOBALS._sceneManager._scene)->_sceneAreas.remove(this);
+}
+
+void SceneArea::process(Event &event) {
+ if (!R2_GLOBALS._insetUp && _enabled && R2_GLOBALS._events.isCursorVisible()) {
+ CursorType cursor = R2_GLOBALS._events.getCursor();
+
+ if (_bounds.contains(event.mousePos)) {
+ // Cursor moving in bounded area
+ if (cursor != _cursorNum) {
+ _savedCursorNum = cursor;
+ _cursorState = 0;
+ R2_GLOBALS._events.setCursor(_cursorNum);
+ }
+ _insideArea = true;
+ } else if ((event.mousePos.y < 171) && _insideArea && (_cursorNum == cursor) &&
+ (_savedCursorNum != CURSOR_NONE)) {
+ // Cursor moved outside bounded area
+ R2_GLOBALS._events.setCursor(_savedCursorNum);
+ }
+ }
+}
+
+void SceneArea::setDetails(const Rect &bounds, CursorType cursor) {
+ _bounds = bounds;
+ _cursorNum = cursor;
+
+ static_cast<SceneExt *>(R2_GLOBALS._sceneManager._scene)->_sceneAreas.push_front(this);
+}
+
+/*--------------------------------------------------------------------------*/
+
+SceneExit::SceneExit(): SceneArea() {
+ _moving = false;
+ _destPos = Common::Point(-1, -1);
+}
+
+void SceneExit::synchronize(Serializer &s) {
+ SceneArea::synchronize(s);
+
+ s.syncAsSint16LE(_moving);
+ s.syncAsSint16LE(_destPos.x);
+ s.syncAsSint16LE(_destPos.y);
+}
+
+void SceneExit::setDetails(const Rect &bounds, CursorType cursor, int sceneNumber) {
+ _sceneNumber = sceneNumber;
+ SceneArea::setDetails(bounds, cursor);
+}
+
+void SceneExit::changeScene() {
+ R2_GLOBALS._sceneManager.setNewScene(_sceneNumber);
+}
+
+void SceneExit::process(Event &event) {
+ if (!R2_GLOBALS._insetUp) {
+ SceneArea::process(event);
+
+ if (_enabled) {
+ if (event.eventType == EVENT_BUTTON_DOWN) {
+ if (!_bounds.contains(event.mousePos))
+ _moving = false;
+ else if (!R2_GLOBALS._player._canWalk) {
+ _moving = false;
+ changeScene();
+ event.handled = true;
+ } else {
+ Common::Point dest((_destPos.x == -1) ? event.mousePos.x : _destPos.x,
+ (_destPos.y == -1) ? event.mousePos.y : _destPos.y);
+ ADD_PLAYER_MOVER(dest.x, dest.y);
+
+ _moving = true;
+ event.handled = true;
+ }
+ }
+
+ if (_moving && (_bounds.contains(R2_GLOBALS._player._position) || (R2_GLOBALS._player._position == _destPos)))
+ changeScene();
+ }
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+
+void SceneAreaObject::remove() {
+ _object1.remove();
+ SceneArea::remove();
+ --R2_GLOBALS._insetUp;
+}
+
+void SceneAreaObject::process(Event &event) {
+ if (_insetCount == R2_GLOBALS._insetUp) {
+ CursorType cursor = R2_GLOBALS._events.getCursor();
+
+ if (_bounds.contains(event.mousePos)) {
+ // Cursor moving in bounded area
+ if (cursor == _cursorNum) {
+ R2_GLOBALS._events.setCursor(_savedCursorNum);
+ }
+ } else if (event.mousePos.y < 168) {
+ if (_cursorNum != cursor)
+ // Cursor moved outside bounded area
+ R2_GLOBALS._events.setCursor(_savedCursorNum);
+
+ if (event.eventType == EVENT_BUTTON_DOWN) {
+ R2_GLOBALS._events.setCursor(_savedCursorNum);
+ event.handled = true;
+ }
+ }
+ }
+}
+
+void SceneAreaObject::setDetails(int visage, int strip, int frameNumber, const Common::Point &pt) {
+ _object1.postInit();
+ _object1.setup(visage, strip, frameNumber);
+ _object1.setPosition(pt);
+ _object1.fixPriority(250);
+
+ _cursorNum = CURSOR_INVALID;
+ Scene500 *scene = (Scene500 *)R2_GLOBALS._sceneManager._scene;
+ scene->_sceneAreas.push_front(this);
+
+ _insetCount = ++R2_GLOBALS._insetUp;
+}
+
+void SceneAreaObject::setDetails(int resNum, int lookLineNum, int talkLineNum, int useLineNum) {
+ ((SceneHotspot *)(this))->setDetails(resNum, lookLineNum, talkLineNum, useLineNum,
+ 2, (SceneItem *)NULL);
+}
+
+/*****************************************************************************/
+
+UnkObject1200::UnkObject1200() {
+ _field16 = _field3A = NULL;
+ _field12 = _field14 = 0;
+ _field26 = _field28 = _field2A = _field2C = _field2E = _field30 = 0;
+ _field32 = _field34 = _field36 = _field38 = _field3E = _field40 = 0;
+}
+
+void UnkObject1200::synchronize(Serializer &s) {
+ SavedObject::synchronize(s);
+
+ _rect1.synchronize(s);
+ _rect2.synchronize(s);
+
+ // FIXME: syncrhonize _field16 and _field3A
+
+ s.syncAsSint16LE(_field12);
+ s.syncAsSint16LE(_field14);
+ s.syncAsSint16LE(_field26);
+ s.syncAsSint16LE(_field28);
+ s.syncAsSint16LE(_field2A);
+ s.syncAsSint16LE(_field2C);
+ s.syncAsSint16LE(_field2E);
+ s.syncAsSint16LE(_field30);
+ s.syncAsSint16LE(_field32);
+ s.syncAsSint16LE(_field34);
+ s.syncAsSint16LE(_field36);
+ s.syncAsSint16LE(_field38);
+ s.syncAsSint16LE(_field3E);
+ s.syncAsSint16LE(_field40);
+}
+
+void UnkObject1200::sub51AE9(int arg1) {
+ warning("STUB: UnkObject1200::sub51AE9()");
+}
+
+int UnkObject1200::sub51AF8(Common::Point pt) {
+ if (!_rect1.contains(pt))
+ return -1;
+
+ int tmp1 = (pt.x - _rect1.left + _field2E) / _field2A;
+ int tmp2 = (pt.y - _rect1.top + _field30) / _field2C;
+
+ if ((tmp1 >= 0) && (tmp2 >= 0) && (_field26 > tmp1) && (_field28 > tmp2))
+ return _field16[(((_field26 * tmp2) + tmp1)* 2)];
+
+ return -1;
+}
+
+bool UnkObject1200::sub51AFD(Common::Point pt) {
+ int retval = false;
+
+ _field2E = pt.x;
+ _field30 = pt.y;
+
+ if (_field2E < _rect2.top) {
+ _field2E = _rect2.top;
+ retval = true;
+ }
+
+ if (_field30 < _rect2.left) {
+ _field30 = _rect2.left;
+ retval = true;
+ }
+
+ if (_field2E + _rect1.width() > _rect2.right) {
+ _field2E = _rect2.right - _rect1.width();
+ retval = true;
+ }
+
+ if (_field30 + _rect1.height() > _rect2.bottom) {
+ _field30 = _rect2.bottom - _rect1.height();
+ retval = true;
+ }
+
+ return retval;
+}
+
+void UnkObject1200::sub51B02() {
+ warning("STUB: UnkObject1200::sub51B02()");
+}
+
+void UnkObject1200::sub9EDE8(Rect rect) {
+ _rect1 = rect;
+ warning("FIXME: UnkObject1200::sub9EDE8()");
+// _rect1.clip(g_globals->gfxManager()._bounds);
+}
+
+int UnkObject1200::sub9EE22(int &arg1, int &arg2) {
+ arg1 /= _field2A;
+ arg2 /= _field2C;
+
+ if ((arg1 >= 0) && (arg2 >= 0) && (_field26 > arg1) && (_field28 > arg2)) {
+ return _field16[(((_field26 * arg2) + arg1) * 2)];
+ }
+
+ return -1;
+}
- switch (mode) {
+void Scene1200::sub9DAD6(int indx) {
+ _object1.sub9EE22(R2_GLOBALS._v56AA2, R2_GLOBALS._v56AA4);
+
+ switch (indx) {
+ case 0:
+ if ( ((_object1.sub51AF8(Common::Point(200, 50)) > 36) || (_object1.sub51AF8(Common::Point(200, 88)) > 36))
+ && ( ((R2_GLOBALS._v56AA2 == 3) && (R2_GLOBALS._v56AA4 == 33) && (_field418 != 4))
+ || ((R2_GLOBALS._v56AA2 == 13) && (R2_GLOBALS._v56AA4 == 21) && (_field418 != 2))
+ || ((R2_GLOBALS._v56AA2 == 29) && (R2_GLOBALS._v56AA4 == 17) && (_field418 != 1))
+ || ((R2_GLOBALS._v56AA2 == 33) && (R2_GLOBALS._v56AA4 == 41)) )
+ ) {
+ R2_GLOBALS._player.disableControl();
+ _sceneMode = 1200;
+ setAction(&_sequenceManager, this, 1200, &_actor1, NULL);
+ } else if (_object1.sub51AF8(Common::Point(200, 69)) == 36) {
+ switch (_field412 - 1) {
+ case 0:
+ if (R2_GLOBALS._player._visage == 3155)
+ _sceneMode = 15;
+ else
+ _sceneMode = 10;
+ break;
+ case 1:
+ if (R2_GLOBALS._player._visage == 3156)
+ _sceneMode = 76;
+ else
+ _sceneMode = 75;
+ break;
+ case 2:
+ if (R2_GLOBALS._player._visage == 3156)
+ _sceneMode = 101;
+ else
+ _sceneMode = 100;
+ break;
+ case 3:
+ if (R2_GLOBALS._player._visage == 3156)
+ _sceneMode = 111;
+ else
+ _sceneMode = 110;
+ break;
+ default:
+ break;
+ }
+ R2_GLOBALS._player.disableControl();
+ _field412 = 1;
+ signal();
+ }
+ break;
+ case 1:
+ if ( ((_object1.sub51AF8(Common::Point(120, 50)) > 36) || (_object1.sub51AF8(Common::Point(120, 88)) > 36))
+ && ( ((R2_GLOBALS._v56AA2 == 7) && (R2_GLOBALS._v56AA4 == 33) && (_field418 != 4))
+ || ((R2_GLOBALS._v56AA2 == 17) && (R2_GLOBALS._v56AA4 == 21) && (_field418 != 2))
+ || ((R2_GLOBALS._v56AA2 == 33) && (R2_GLOBALS._v56AA4 == 17) && (_field418 != 1))
+ || ((R2_GLOBALS._v56AA2 == 5) && (R2_GLOBALS._v56AA4 == 5)) )
+ ) {
+ R2_GLOBALS._player.disableControl();
+ _sceneMode = 1201;
+ setAction(&_sequenceManager, this, 1201, &_actor1, NULL);
+ } else if (_object1.sub51AF8(Common::Point(120, 69)) == 36) {
+ switch (_field412 - 1) {
+ case 0:
+ if (R2_GLOBALS._player._visage == 3156)
+ _sceneMode = 56;
+ else
+ _sceneMode = 55;
+ break;
+ case 1:
+ if (R2_GLOBALS._player._visage == 3155)
+ _sceneMode = 25;
+ else
+ _sceneMode = 20;
+ break;
+ case 2:
+ if (R2_GLOBALS._player._visage == 3156)
+ _sceneMode = 91;
+ else
+ _sceneMode = 90;
+ break;
+ case 3:
+ if (R2_GLOBALS._player._visage == 3156)
+ _sceneMode = 121;
+ else
+ _sceneMode = 120;
+ break;
+ default:
+ break;
+ }
+ R2_GLOBALS._player.disableControl();
+ _field412 = 2;
+ signal();
+ }
+ break;
case 2:
- g_globals->_sceneItems.push_front(this);
+ if ( ((_object1.sub51AF8(Common::Point(140, 110)) > 36) || (_object1.sub51AF8(Common::Point(178, 110)) > 36))
+ && ( ((R2_GLOBALS._v56AA2 == 17) && (R2_GLOBALS._v56AA4 == 5) && (_field418 != 3))
+ || ((R2_GLOBALS._v56AA2 == 41) && (R2_GLOBALS._v56AA4 == 21)) )
+ ) {
+ R2_GLOBALS._player.disableControl();
+ _sceneMode = 1203;
+ setAction(&_sequenceManager, this, 1203, &_actor1, NULL);
+ } else if (_object1.sub51AF8(Common::Point(160, 110)) == 36) {
+ switch (_field412 - 1) {
+ case 0:
+ if (R2_GLOBALS._player._visage == 3156)
+ _sceneMode = 51;
+ else
+ _sceneMode = 50;
+ break;
+ case 1:
+ if (R2_GLOBALS._player._visage == 3156)
+ _sceneMode = 81;
+ else
+ _sceneMode = 80;
+ break;
+ case 2:
+ if (R2_GLOBALS._player._visage == 3155)
+ _sceneMode = 35;
+ else
+ _sceneMode = 30;
+ break;
+ case 3:
+ if (R2_GLOBALS._player._visage == 3156)
+ _sceneMode = 116;
+ else
+ _sceneMode = 115;
+ break;
+ default:
+ break;
+ }
+ R2_GLOBALS._player.disableControl();
+ _field412 = 3;
+ signal();
+ }
+ break;
+ case 3:
+ if ( ((_object1.sub51AF8(Common::Point(140, 30)) > 36) || (_object1.sub51AF8(Common::Point(178, 30)) > 36))
+ && ( ((R2_GLOBALS._v56AA2 == 17) && (R2_GLOBALS._v56AA4 == 9) && (_field418 != 3))
+ || ((R2_GLOBALS._v56AA2 == 35) && (R2_GLOBALS._v56AA4 == 17)) )
+ ) {
+ R2_GLOBALS._player.disableControl();
+ _sceneMode = 1202;
+ setAction(&_sequenceManager, this, 1202, &_actor1, NULL);
+ } else if (_object1.sub51AF8(Common::Point(160, 30)) == 36) {
+ switch (_field412 - 1) {
+ case 0:
+ if (R2_GLOBALS._player._visage == 3156)
+ _sceneMode = 61;
+ else
+ _sceneMode = 60;
+ break;
+ case 1:
+ if (R2_GLOBALS._player._visage == 3156)
+ _sceneMode = 71;
+ else
+ _sceneMode = 70;
+ break;
+ case 2:
+ if (R2_GLOBALS._player._visage == 3156)
+ _sceneMode = 96;
+ else
+ _sceneMode = 95;
+ break;
+ case 3:
+ if (R2_GLOBALS._player._visage == 3155)
+ _sceneMode = 45;
+ else
+ _sceneMode = 40;
+ break;
+ default:
+ _sceneMode = 1;
+ R2_GLOBALS._player.setup(3156, 4, 6);
+ break;
+ }
+ R2_GLOBALS._player.disableControl();
+ _field412 = 4;
+ signal();
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+
+void AnimationSlice::load(Common::File &f) {
+ f.skip(2);
+ _sliceOffset = f.readUint16LE();
+ f.skip(6);
+ _drawMode = f.readByte();
+ _secondaryIndex = f.readByte();
+}
+
+/*--------------------------------------------------------------------------*/
+
+AnimationSlices::AnimationSlices() {
+ _pixelData = NULL;
+}
+
+AnimationSlices::~AnimationSlices() {
+ delete[] _pixelData;
+}
+
+void AnimationSlices::load(Common::File &f) {
+ f.skip(4);
+ _dataSize = f.readUint32LE();
+ f.skip(8);
+ _dataSize2 = f.readUint32LE();
+ f.skip(28);
+
+ // Load the four slice indexes
+ for (int idx = 0; idx < 4; ++idx)
+ _slices[idx].load(f);
+}
+
+int AnimationSlices::loadPixels(Common::File &f, int slicesSize) {
+ delete[] _pixelData;
+ _pixelData = new byte[slicesSize];
+ return f.read(_pixelData, slicesSize);
+}
+
+/*--------------------------------------------------------------------------*/
+
+void AnimationPlayerSubData::load(Common::File &f) {
+ uint32 posStart = f.pos();
+
+ f.skip(6);
+ _duration = f.readUint32LE();
+ _frameRate = f.readUint16LE();
+ _framesPerSlices = f.readUint16LE();
+ _drawType = f.readUint16LE();
+ f.skip(2);
+ _sliceSize = f.readUint16LE();
+ _ySlices = f.readUint16LE();
+ _field16 = f.readUint32LE();
+ f.skip(2);
+ _palStart = f.readUint16LE();
+ _palSize = f.readUint16LE();
+ f.read(_palData, 768);
+ _totalSize = f.readSint32LE();
+ f.skip(12);
+ _slices.load(f);
+
+ uint32 posEnd = f.pos();
+ assert((posEnd - posStart) == 0x390);
+}
+
+/*--------------------------------------------------------------------------*/
+
+AnimationPlayer::AnimationPlayer(): EventHandler() {
+ _endAction = NULL;
+
+ _animData1 = NULL;
+ _animData2 = NULL;
+
+ _screenBounds = R2_GLOBALS._gfxManagerInstance._bounds;
+ _rect1 = R2_GLOBALS._gfxManagerInstance._bounds;
+ _paletteMode = ANIMPALMODE_REPLACE_PALETTE;
+ _field3A = 1;
+ _sliceHeight = 1;
+ _field58 = 1;
+ _endAction = NULL;
+}
+
+AnimationPlayer::~AnimationPlayer() {
+ if (!isCompleted())
+ close();
+}
+
+void AnimationPlayer::synchronize(Serializer &s) {
+ EventHandler::synchronize(s);
+ warning("TODO AnimationPlayer::load");
+}
+
+void AnimationPlayer::remove() {
+ if (_endAction)
+ _endAction->signal();
+
+ _endAction = NULL;
+}
+
+void AnimationPlayer::process(Event &event) {
+ if ((event.eventType == EVENT_KEYPRESS) && (event.kbd.keycode == Common::KEYCODE_ESCAPE) &&
+ (_field3A)) {
+ // Move the current position to the end
+ _position = _subData._duration;
+ }
+}
+
+void AnimationPlayer::dispatch() {
+ uint32 gameFrame = R2_GLOBALS._events.getFrameNumber();
+ uint32 gameDiff = gameFrame - _gameFrame;
+
+ if (gameDiff >= _frameDelay) {
+ drawFrame(_playbackTick % _subData._framesPerSlices);
+ ++_playbackTick;
+ _position = _playbackTick / _subData._framesPerSlices;
+
+ if (_position == _nextSlicesPosition)
+ nextSlices();
+
+ _playbackTickPrior = _playbackTick;
+ _gameFrame = gameFrame;
+ }
+}
+
+bool AnimationPlayer::load(int animId, Action *endAction) {
+ // Open up the main resource file for access
+ TLib &libFile = g_resourceManager->first();
+ if (!_resourceFile.open(libFile.getFilename()))
+ error("Could not open resource");
+
+ // Get the offset of the given resource and seek to it in the player's file reference
+ ResourceEntry entry;
+ uint32 fileOffset = libFile.getResourceStart(RES_IMAGE, animId, 0, entry);
+ _resourceFile.seek(fileOffset);
+
+ // At this point, the file is pointing to the start of the resource data
+
+ // Set the end action
+ _endAction = endAction;
+
+ // Load the sub data block
+ _subData.load(_resourceFile);
+
+ // Set other properties
+ _playbackTickPrior = -1;
+ _playbackTick = 0;
+
+ // The final multiplication is used to deliberately slow down playback, since the original
+ // was slowed down by the amount of time spent to decode and display the frames
+ _frameDelay = (60 / _subData._frameRate) * 8;
+ _gameFrame = R2_GLOBALS._events.getFrameNumber();
+
+ if (_subData._totalSize) {
+ _dataNeeded = _subData._totalSize;
+ } else {
+ int v = (_subData._sliceSize + 2) * _subData._ySlices * _subData._framesPerSlices;
+ _dataNeeded = (_subData._field16 / _subData._framesPerSlices) + v + 96;
+ }
+
+ debugC(1, ktSageDebugGraphics, "Data needed %d", _dataNeeded);
+
+ // Set up animation data objects
+ _animData1 = new AnimationData();
+ _sliceCurrent = _animData1;
+
+ if (_subData._framesPerSlices <= 1) {
+ _animData2 = NULL;
+ _sliceNext = _sliceCurrent;
+ } else {
+ _animData2 = new AnimationData();
+ _sliceNext = _animData2;
+ }
+
+ _position = 0;
+ _nextSlicesPosition = 1;
+
+ // Load up the first slices set
+ _sliceCurrent->_dataSize = _subData._slices._dataSize;
+ _sliceCurrent->_slices = _subData._slices;
+ int slicesSize = _sliceCurrent->_dataSize - 96;
+ int readSize = _sliceCurrent->_slices.loadPixels(_resourceFile, slicesSize);
+ _sliceCurrent->_animSlicesSize = readSize + 96;
+
+ if (_sliceNext != _sliceCurrent) {
+ getSlices();
+ }
+
+ // Handle starting palette
+ switch (_paletteMode) {
+ case ANIMPALMODE_REPLACE_PALETTE:
+ // Use the palette provided with the animation directly
+ _palette.getPalette();
+ for (int idx = _subData._palStart; idx < (_subData._palStart + _subData._palSize); ++idx) {
+ byte r = _subData._palData[idx * 3];
+ byte g = _subData._palData[idx * 3 + 1];
+ byte b = _subData._palData[idx * 3 + 2];
+
+ R2_GLOBALS._scenePalette.setEntry(idx, r, g, b);
+ }
+
+ R2_GLOBALS._sceneManager._hasPalette = true;
+ break;
+ case ANIMPALMODE_NONE:
break;
- case 4:
- g_globals->_sceneItems.addBefore(item, this);
+
+ default:
+ // ANIMPALMODE_CURR_PALETTE
+ // Use the closest matching colours in the currently active palette to those specified in the animation
+ for (int idx = _subData._palStart; idx < (_subData._palStart + _subData._palSize); ++idx) {
+ byte r = _subData._palData[idx * 3];
+ byte g = _subData._palData[idx * 3 + 1];
+ byte b = _subData._palData[idx * 3 + 2];
+
+ int palIndex = R2_GLOBALS._scenePalette.indexOf(r, g, b);
+ _palIndexes[idx] = palIndex;
+ }
break;
- case 5:
- g_globals->_sceneItems.addAfter(item, this);
+ }
+
+ ++R2_GLOBALS._animationCtr;
+ _field38 = 1;
+ return true;
+}
+
+void AnimationPlayer::drawFrame(int sliceIndex) {
+ assert(sliceIndex < 4);
+ AnimationSlices &slices = _sliceCurrent->_slices;
+ AnimationSlice &slice = _sliceCurrent->_slices._slices[sliceIndex];
+
+ byte *sliceDataStart = &slices._pixelData[slice._sliceOffset - 96];
+ byte *sliceData1 = sliceDataStart;
+
+ Rect playerBounds = _screenBounds;
+ int y = _screenBounds.top;
+ R2_GLOBALS._screenSurface.addDirtyRect(playerBounds);
+
+ Graphics::Surface surface = R2_GLOBALS._screenSurface.lockSurface();
+
+ // Handle different drawing modes
+ switch (slice._drawMode) {
+ case 0:
+ // Draw from uncompressed source
+ for (int sliceNum = 0; sliceNum < _subData._ySlices; ++sliceNum) {
+ for (int yIndex = 0; yIndex < _sliceHeight; ++yIndex) {
+ // TODO: Check of _subData._drawType was done for two different kinds of
+ // line slice drawing in original
+ const byte *pSrc = (const byte *)sliceDataStart + READ_LE_UINT16(sliceData1 + sliceNum * 2);
+ byte *pDest = (byte *)surface.getBasePtr(playerBounds.left, y++);
+
+ Common::copy(pSrc, pSrc + _subData._sliceSize, pDest);
+ }
+ }
break;
+
+ case 1:
+ switch (slice._secondaryIndex) {
+ case 0xfe:
+ // Draw from uncompressed source with optional skipped rows
+ for (int sliceNum = 0; sliceNum < _subData._ySlices; ++sliceNum) {
+ for (int yIndex = 0; yIndex < _sliceHeight; ++yIndex, playerBounds.top++) {
+ int offset = READ_LE_UINT16(sliceData1 + sliceNum * 2);
+
+ if (offset) {
+ const byte *pSrc = (const byte *)sliceDataStart + offset;
+ byte *pDest = (byte *)surface.getBasePtr(playerBounds.left, playerBounds.top);
+
+ //Common::copy(pSrc, pSrc + playerBounds.width(), pDest);
+ rleDecode(pSrc, pDest, playerBounds.width());
+ }
+ }
+ }
+ break;
+ case 0xff:
+ // Draw from RLE compressed source
+ for (int sliceNum = 0; sliceNum < _subData._ySlices; ++sliceNum) {
+ for (int yIndex = 0; yIndex < _sliceHeight; ++yIndex, playerBounds.top++) {
+ // TODO: Check of _subData._drawType was done for two different kinds of
+ // line slice drawing in original
+ const byte *pSrc = (const byte *)sliceDataStart + READ_LE_UINT16(sliceData1 + sliceNum * 2);
+ byte *pDest = (byte *)surface.getBasePtr(playerBounds.left, playerBounds.top);
+
+ rleDecode(pSrc, pDest, _subData._sliceSize);
+ }
+ }
+ break;
+ default: {
+ // Draw from two slice sets simultaneously
+ AnimationSlice &slice2 = _sliceCurrent->_slices._slices[slice._secondaryIndex];
+ byte *sliceData2 = &slices._pixelData[slice2._sliceOffset - 96];
+
+ for (int sliceNum = 0; sliceNum < _subData._ySlices; ++sliceNum) {
+ for (int yIndex = 0; yIndex < _sliceHeight; ++yIndex) {
+ const byte *pSrc1 = (const byte *)sliceDataStart + READ_LE_UINT16(sliceData2 + sliceNum * 2);
+ const byte *pSrc2 = (const byte *)sliceDataStart + READ_LE_UINT16(sliceData1 + sliceNum * 2);
+ byte *pDest = (byte *)surface.getBasePtr(playerBounds.left, y++);
+
+ if (slice2._drawMode == 0) {
+ // Uncompressed background, foreground compressed
+ Common::copy(pSrc1, pSrc1 + _subData._sliceSize, pDest);
+ rleDecode(pSrc2, pDest, _subData._sliceSize);
+ } else {
+ // Both background and foreground is compressed
+ rleDecode(pSrc1, pDest, _subData._sliceSize);
+ rleDecode(pSrc2, pDest, _subData._sliceSize);
+ }
+ }
+ }
+ break;
+ }
+ }
default:
- g_globals->_sceneItems.push_back(this);
break;
}
+
+ // Unlock the screen surface
+ R2_GLOBALS._screenSurface.unlockSurface();
+
+ if (_objectMode == 42) {
+ _screenBounds.expandPanes();
+
+ // Copy the drawn frame to the back surface
+ Rect srcRect = R2_GLOBALS._screenSurface.getBounds();
+ Rect destRect = srcRect;
+ destRect.translate(-g_globals->_sceneOffset.x, -g_globals->_sceneOffset.y);
+ R2_GLOBALS._sceneManager._scene->_backSurface.copyFrom(R2_GLOBALS._screenSurface,
+ srcRect, destRect);
+
+ // Draw any objects into the scene
+ R2_GLOBALS._sceneObjects->draw();
+ } else {
+ if (R2_GLOBALS._sceneManager._hasPalette) {
+ R2_GLOBALS._sceneManager._hasPalette = false;
+ R2_GLOBALS._scenePalette.refresh();
+ }
+ }
+}
+
+/**
+ * Read the next frame's slice set
+ */
+void AnimationPlayer::nextSlices() {
+ _position = _nextSlicesPosition++;
+ _playbackTick = _position * _subData._framesPerSlices;
+ _playbackTickPrior = _playbackTick - 1;
+
+ if (_sliceNext == _sliceCurrent) {
+ int dataSize = _sliceCurrent->_slices._dataSize2;
+ _sliceCurrent->_dataSize = dataSize;
+ debugC(1, ktSageDebugGraphics, "Next frame size = %xh", dataSize);
+ if (dataSize == 0)
+ return;
+
+ dataSize -= 96;
+ assert(dataSize >= 0);
+ _sliceCurrent->_slices.load(_resourceFile);
+ _sliceCurrent->_animSlicesSize = _sliceCurrent->_slices.loadPixels(_resourceFile, dataSize);
+ } else {
+ SWAP(_sliceCurrent, _sliceNext);
+ getSlices();
+ }
+}
+
+bool AnimationPlayer::isCompleted() {
+ return (_position >= _subData._duration);
+}
+
+void AnimationPlayer::close() {
+ if (_field38) {
+ switch (_paletteMode) {
+ case 0:
+ R2_GLOBALS._scenePalette.replace(&_palette);
+ changePane();
+ R2_GLOBALS._sceneManager._hasPalette = true;
+ break;
+ case 2:
+ closing();
+ break;
+ default:
+ changePane();
+ break;
+ }
+ }
+
+ // Close the resource file
+ _resourceFile.close();
+
+ if (_objectMode != 42) {
+ // flip screen in original
+ }
+
+ // Free animation objects
+ delete _animData1;
+ delete _animData2;
+ _animData1 = NULL;
+ _animData2 = NULL;
+
+ _field38 = 0;
+ if (g_globals != NULL)
+ R2_GLOBALS._animationCtr = MAX(R2_GLOBALS._animationCtr, 0);
}
-void SceneActor::setDetails(int resNum, int lookLineNum, int talkLineNum, int useLineNum) {
- _resNum = resNum;
- _lookLineNum = lookLineNum;
- _talkLineNum = talkLineNum;
- _useLineNum = useLineNum;
+void AnimationPlayer::rleDecode(const byte *pSrc, byte *pDest, int size) {
+ while (size > 0) {
+ byte v = *pSrc++;
+ if (!(v & 0x80)) {
+ // Following uncompressed set of bytes
+ Common::copy(pSrc, pSrc + v, pDest);
+ pSrc += v;
+ pDest += v;
+ size -= v;
+ } else {
+ int count = v & 0x3F;
+ size -= count;
+
+ if (!(v & 0x40)) {
+ // Skip over a number of bytes
+ pDest += count;
+ } else {
+ // Replicate a number of bytes
+ Common::fill(pDest, pDest + count, *pSrc++);
+ pDest += count;
+ }
+ }
+ }
}
+void AnimationPlayer::getSlices() {
+ assert((_sliceNext == _animData1) || (_sliceNext == _animData2));
+ assert((_sliceCurrent == _animData1) || (_sliceCurrent == _animData2));
+
+ _sliceNext->_dataSize = _sliceCurrent->_slices._dataSize2;
+ if (_sliceNext->_dataSize) {
+ if (_sliceNext->_dataSize >= _dataNeeded)
+ error("Bogus dataNeeded == %d / %d", _sliceNext->_dataSize, _dataNeeded);
+ }
+
+ int dataSize = _sliceNext->_dataSize - 96;
+ _sliceNext->_slices.load(_resourceFile);
+ _sliceNext->_animSlicesSize = _sliceNext->_slices.loadPixels(_resourceFile, dataSize);
+}
+
+/*--------------------------------------------------------------------------*/
+
+AnimationPlayerExt::AnimationPlayerExt(): AnimationPlayer() {
+ _v = 0;
+ _field3A = 0;
+}
+
+void AnimationPlayerExt::synchronize(Serializer &s) {
+ AnimationPlayer::synchronize(s);
+ s.syncAsSint16LE(_v);
+}
} // End of namespace Ringworld2
diff --git a/engines/tsage/ringworld2/ringworld2_logic.h b/engines/tsage/ringworld2/ringworld2_logic.h
index bfb3281d5d..0b573bf7f0 100644
--- a/engines/tsage/ringworld2/ringworld2_logic.h
+++ b/engines/tsage/ringworld2/ringworld2_logic.h
@@ -42,11 +42,44 @@ public:
static Scene *createScene(int sceneNumber);
};
+class SceneArea: public EventHandler {
+public:
+ Rect _bounds;
+ bool _enabled;
+ bool _insideArea;
+ CursorType _cursorNum;
+ CursorType _savedCursorNum;
+ int _cursorState;
+public:
+ SceneArea();
+ void setDetails(const Rect &bounds, CursorType cursor);
+
+ virtual void synchronize(Serializer &s);
+ virtual void remove();
+ virtual void process(Event &event);
+};
+
+class SceneExit: public SceneArea {
+public:
+ bool _moving;
+ int _sceneNumber;
+ Common::Point _destPos;
+public:
+ SceneExit();
+ virtual void setDetails(const Rect &bounds, CursorType cursor, int sceneNumber);
+ virtual void setDest(const Common::Point &p) { _destPos = p; }
+ virtual void changeScene();
+
+ virtual void synchronize(Serializer &s);
+ virtual void process(Event &event);
+};
+
class SceneExt: public Scene {
private:
static void startStrip();
static void endStrip();
public:
+ byte _field312[256];
int _field372;
bool _savedPlayerEnabled;
bool _savedUiEnabled;
@@ -55,6 +88,7 @@ public:
SceneObject *_focusObject;
Visage _cursorVisage;
+ SynchronizedList<SceneArea *> _sceneAreas;
Rect _v51C34;
public:
@@ -67,12 +101,24 @@ public:
virtual void dispatch();
virtual void loadScene(int sceneNum);
virtual void refreshBackground(int xAmount, int yAmount);
+ virtual void saveCharacter(int characterIndex);
+ virtual void restore() {}
- bool display(CursorType action);
+ bool display(CursorType action, Event &event);
void fadeOut();
void clearScreen();
+ void scalePalette(int RFactor, int GFactor, int BFactor);
};
+class SceneHandlerExt: public SceneHandler {
+public:
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+ virtual void process(Event &event);
+
+ void setupPaletteMaps();
+};
+
+
class DisplayHotspot : public SceneObject {
private:
Common::Array<int> _actions;
@@ -117,7 +163,7 @@ public:
InvObject _none;
InvObject _inv1;
InvObject _inv2;
- InvObject _inv3;
+ InvObject _negatorGun;
InvObject _steppingDisks;
InvObject _inv5;
InvObject _inv6;
@@ -192,15 +238,10 @@ public:
class NamedHotspot : public SceneHotspot {
public:
- int _resNum, _lookLineNum, _useLineNum, _talkLineNum;
NamedHotspot();
virtual bool startAction(CursorType action, Event &event);
virtual Common::String getClassName() { return "NamedHotspot"; }
- virtual void synchronize(Serializer &s);
- virtual void setDetails(int ys, int xs, int ye, int xe, const int resnum, const int lookLineNum, const int useLineNum);
- virtual void setDetails(const Rect &bounds, int resNum, int lookLineNum, int talkLineNum, int useLineNum, int mode, SceneItem *item);
- virtual void setDetails(int sceneRegionId, int resNum, int lookLineNum, int talkLineNum, int useLineNum, int mode = 0);
};
class NamedHotspotExt : public NamedHotspot {
@@ -217,17 +258,9 @@ public:
class SceneActor: public SceneObject {
public:
- int _resNum;
- int _lookLineNum, _talkLineNum, _useLineNum;
- int _effect, _shade;
-
virtual Common::String getClassName() { return "SceneActor"; }
- virtual void synchronize(Serializer &s);
virtual void postInit(SceneObjectList *OwnerList = NULL);
virtual bool startAction(CursorType action, Event &event);
-
- void setDetails(int resNum, int lookLineNum, int talkLineNum, int useLineNum, int mode, SceneItem *item);
- void setDetails(int resNum, int lookLineNum, int talkLineNum, int useLineNum);
};
class SceneActorExt: public SceneActor {
@@ -235,6 +268,7 @@ public:
int _state;
SceneActorExt() { _state = 0; }
+
virtual Common::String getClassName() { return "SceneActorExt"; }
virtual void synchronize(Serializer &s) {
SceneActor::synchronize(s);
@@ -242,6 +276,161 @@ public:
}
};
+class SceneAreaObject: public SceneArea {
+ class Object1: public SceneActor {
+ public:
+ };
+public:
+ Object1 _object1;
+ int _insetCount;
+
+ virtual void remove();
+ virtual void process(Event &event);
+ void setDetails(int visage, int strip, int frameNumber, const Common::Point &pt);
+ void setDetails(int resNum, int lookLineNum, int talkLineNum, int useLineNum);
+};
+
+class UnkObject1200 : public SavedObject {
+public:
+ Rect _rect1;
+ Rect _rect2;
+
+ int *_field16;
+ int *_field3A;
+
+ int _field12;
+ int _field14;
+ int _field26;
+ int _field28;
+ int _field2A;
+ int _field2C;
+ int _field2E;
+ int _field30;
+ int _field32;
+ int _field34;
+ int _field36;
+ int _field38;
+ int _field3E;
+ int _field40;
+
+ UnkObject1200();
+ void synchronize(Serializer &s);
+
+ void sub51AE9(int arg1);
+ int sub51AF8(Common::Point pt);
+ bool sub51AFD(Common::Point pt);
+ void sub51B02();
+ void sub9EDE8(Rect rect);
+ int sub9EE22(int &arg1, int &arg2);
+ virtual Common::String getClassName() { return "UnkObject1200"; }
+};
+
+/*--------------------------------------------------------------------------*/
+
+class AnimationSlice {
+public:
+ int _sliceOffset;
+ int _drawMode;
+ int _secondaryIndex;
+public:
+ void load(Common::File &f);
+};
+
+class AnimationSlices {
+public:
+ int _dataSize;
+ int _dataSize2;
+ AnimationSlice _slices[4];
+ byte *_pixelData;
+public:
+ AnimationSlices();
+ ~AnimationSlices();
+
+ void load(Common::File &f);
+ int loadPixels(Common::File &f, int slicesSize);
+};
+
+class AnimationPlayerSubData {
+public:
+ int _duration;
+ int _frameRate;
+ int _framesPerSlices;
+ int _drawType;
+ int _sliceSize;
+ int _ySlices;
+ int _field16;
+ int _palStart;
+ int _palSize;
+ byte _palData[256 * 3];
+ int32 _totalSize;
+ AnimationSlices _slices;
+public:
+ void load(Common::File &f);
+};
+
+class AnimationData {
+public:
+ AnimationSlices _slices;
+ int _dataSize;
+ int _animSlicesSize;
+};
+
+enum AnimationPaletteMode { ANIMPALMODE_REPLACE_PALETTE = 0, ANIMPALMODE_CURR_PALETTE = 1,
+ ANIMPALMODE_NONE = 2 };
+
+class AnimationPlayer: public EventHandler {
+private:
+ void rleDecode(const byte *pSrc, byte *pDest, int size);
+
+ void drawFrame(int sliceIndex);
+ void nextSlices();
+ void getSlices();
+public:
+ AnimationData *_animData1, *_animData2;
+ AnimationData *_sliceCurrent;
+ AnimationData *_sliceNext;
+ Common::File _resourceFile;
+ Rect _rect1, _screenBounds;
+ int _field38;
+ int _field3A, _paletteMode;
+ int _objectMode;
+ int _field58, _sliceHeight;
+ byte _palIndexes[256];
+ ScenePalette _palette;
+ AnimationPlayerSubData _subData;
+ Action *_endAction;
+ int _dataNeeded;
+ int _playbackTick;
+ int _playbackTickPrior;
+ int _position;
+ int _nextSlicesPosition;
+ uint _frameDelay;
+ uint32 _gameFrame;
+public:
+ AnimationPlayer();
+ ~AnimationPlayer();
+
+ virtual void synchronize(Serializer &s);
+ virtual void remove();
+ virtual void process(Event &event);
+ virtual void dispatch();
+ virtual void flipPane() {}
+ virtual void changePane() {}
+ virtual void closing() {}
+
+ bool load(int animId, Action *endAction = NULL);
+ bool isCompleted();
+ void close();
+};
+
+class AnimationPlayerExt: public AnimationPlayer {
+public:
+ int _v;
+public:
+ AnimationPlayerExt();
+
+ virtual void synchronize(Serializer &s);
+};
} // End of namespace Ringworld2
diff --git a/engines/tsage/ringworld2/ringworld2_scenes0.cpp b/engines/tsage/ringworld2/ringworld2_scenes0.cpp
index 526bf6e3c9..4c98fcf00a 100644
--- a/engines/tsage/ringworld2/ringworld2_scenes0.cpp
+++ b/engines/tsage/ringworld2/ringworld2_scenes0.cpp
@@ -23,18 +23,62 @@
#include "tsage/scenes.h"
#include "tsage/tsage.h"
#include "tsage/staticres.h"
+#include "tsage/ringworld2/ringworld2_dialogs.h"
#include "tsage/ringworld2/ringworld2_scenes0.h"
+#include "tsage/ringworld2/ringworld2_speakers.h"
namespace TsAGE {
namespace Ringworld2 {
+void Scene50::Action1::signal() {
+ switch (_actionIndex++) {
+ case 0:
+ setDelay(2);
+ break;
+ case 1:
+ setDelay(180);
+ break;
+ case 2:
+ R2_GLOBALS._sceneManager.changeScene(100);
+ break;
+ default:
+ break;
+ }
+}
+
+void Scene50::postInit(SceneObjectList *OwnerList) {
+ SceneExt::postInit(OwnerList);
+ loadScene(110);
+
+ R2_GLOBALS._uiElements._active = false;
+ R2_GLOBALS._scenePalette.loadPalette(0);
+
+ R2_GLOBALS._sound2.play(10);
+ R2_GLOBALS._player.disableControl();
+
+ setAction(&_action1);
+}
+
+void Scene50::process(Event &event) {
+ if ((event.eventType != EVENT_BUTTON_DOWN) && (event.eventType != EVENT_KEYPRESS) && (event.eventType == 27)) {
+ event.handled = true;
+ warning("TODO: incomplete Scene50::process()");
+ // CursorType _oldCursorId = _cursorId;
+ g_globals->_events.setCursor(CURSOR_ARROW);
+ // _cursorManager.sub_1D474(2, 0);
+ // sub_5566A(1);
+ // _cursorManager._fieldE = _oldCursorId;
+ R2_GLOBALS._sceneManager.changeScene(100);
+ }
+}
+
/*--------------------------------------------------------------------------
* Scene 100 - Quinn's Room
*
*--------------------------------------------------------------------------*/
-bool Scene100::Object7::startAction(CursorType action, Event &event) {
+bool Scene100::Door::startAction(CursorType action, Event &event) {
Scene100 *scene = (Scene100 *)R2_GLOBALS._sceneManager._scene;
switch (action) {
@@ -51,11 +95,11 @@ bool Scene100::Object7::startAction(CursorType action, Event &event) {
if (_state) {
SceneItem::display2(100, 26);
_state = 0;
- scene->_object10.setFrame(1);
+ scene->_doorDisplay.setFrame(1);
} else {
SceneItem::display2(100, 27);
_state = 1;
- scene->_object10.setFrame(2);
+ scene->_doorDisplay.setFrame(2);
}
return true;
default:
@@ -63,7 +107,7 @@ bool Scene100::Object7::startAction(CursorType action, Event &event) {
}
}
-bool Scene100::Object8::startAction(CursorType action, Event &event) {
+bool Scene100::Table::startAction(CursorType action, Event &event) {
Scene100 *scene = (Scene100 *)R2_GLOBALS._sceneManager._scene;
switch (action) {
@@ -72,46 +116,46 @@ bool Scene100::Object8::startAction(CursorType action, Event &event) {
if (_strip == 2) {
scene->_sceneMode = 108;
scene->_object3.postInit();
- scene->_object9.postInit();
+ scene->_stasisNegator.postInit();
- if (R2_INVENTORY.getObjectScene(R2_3) == 1) {
- scene->_object9.setup(100, 7, 2);
+ if (R2_INVENTORY.getObjectScene(R2_NEGATOR_GUN) == 1) {
+ scene->_stasisNegator.setup(100, 7, 2);
} else {
- scene->_object9.setup(100, 7, 1);
- scene->_object9.setDetails(100, 21, 22, 23, 2, NULL);
+ scene->_stasisNegator.setup(100, 7, 1);
+ scene->_stasisNegator.setDetails(100, 21, 22, 23, 2, (SceneItem *)NULL);
}
- scene->setAction(&scene->_sequenceManager2, scene, 108, this, &scene->_object3,
- &scene->_object9, &R2_GLOBALS._player, NULL);
+ scene->setAction(&scene->_sequenceManager2, scene, 108, this, &scene->_object3,
+ &scene->_stasisNegator, &R2_GLOBALS._player, NULL);
} else {
scene->_sceneMode = 109;
- scene->setAction(&scene->_sequenceManager2, scene, 109, this, &scene->_object3,
- &scene->_object9, &R2_GLOBALS._player, NULL);
+ scene->setAction(&scene->_sequenceManager2, scene, 109, this, &scene->_object3,
+ &scene->_stasisNegator, &R2_GLOBALS._player, NULL);
}
return true;
case CURSOR_TALK:
R2_GLOBALS._player.disableControl();
-
+
if (_strip == 2) {
SceneItem::display2(100, 18);
scene->_sceneMode = 102;
scene->_object3.postInit();
- scene->_object9.postInit();
+ scene->_stasisNegator.postInit();
- if (R2_INVENTORY.getObjectScene(R2_3) == 1) {
- scene->_object9.setup(100, 7, 2);
+ if (R2_INVENTORY.getObjectScene(R2_NEGATOR_GUN) == 1) {
+ scene->_stasisNegator.setup(100, 7, 2);
} else {
- scene->_object9.setup(100, 7, 1);
- scene->_object9.setDetails(100, 21, 22, 23, 2, NULL);
+ scene->_stasisNegator.setup(100, 7, 1);
+ scene->_stasisNegator.setDetails(100, 21, 22, 23, 2, (SceneItem *)NULL);
}
- scene->setAction(&scene->_sequenceManager2, scene, 102, this, &scene->_object3,
- &scene->_object9, NULL);
+ scene->setAction(&scene->_sequenceManager2, scene, 102, this, &scene->_object3,
+ &scene->_stasisNegator, NULL);
} else {
SceneItem::display2(100, 19);
scene->_sceneMode = 103;
- scene->setAction(&scene->_sequenceManager2, scene, 103, this, &scene->_object3,
- &scene->_object9, NULL);
+ scene->setAction(&scene->_sequenceManager2, scene, 103, this, &scene->_object3,
+ &scene->_stasisNegator, NULL);
}
return true;
default:
@@ -119,21 +163,21 @@ bool Scene100::Object8::startAction(CursorType action, Event &event) {
}
}
-bool Scene100::Object9::startAction(CursorType action, Event &event) {
+bool Scene100::StasisNegator::startAction(CursorType action, Event &event) {
Scene100 *scene = (Scene100 *)R2_GLOBALS._sceneManager._scene;
switch (action) {
case CURSOR_USE:
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 107;
- scene->setAction(&scene->_sequenceManager1, scene, 107, &R2_GLOBALS._player, &scene->_object9, NULL);
+ scene->setAction(&scene->_sequenceManager1, scene, 107, &R2_GLOBALS._player, &scene->_stasisNegator, NULL);
return true;
default:
return SceneActor::startAction(action, event);
}
}
-bool Scene100::Object10::startAction(CursorType action, Event &event) {
+bool Scene100::DoorDisplay::startAction(CursorType action, Event &event) {
Scene100 *scene = (Scene100 *)R2_GLOBALS._sceneManager._scene;
switch (action) {
@@ -169,6 +213,22 @@ bool Scene100::SteppingDisks::startAction(CursorType action, Event &event) {
/*--------------------------------------------------------------------------*/
+bool Scene100::Terminal::startAction(CursorType action, Event &event) {
+ Scene100 *scene = (Scene100 *)R2_GLOBALS._sceneManager._scene;
+
+ switch (action) {
+ case CURSOR_USE:
+ R2_GLOBALS._player.disableControl();
+ scene->_sceneMode = 105;
+ scene->setAction(&scene->_sequenceManager1, scene, 105, &R2_GLOBALS._player, this, NULL);
+ return true;
+ default:
+ return NamedHotspot::startAction(action, event);
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+
void Scene100::postInit(SceneObjectList *OwnerList) {
SceneExt::postInit();
loadScene(100);
@@ -177,59 +237,60 @@ void Scene100::postInit(SceneObjectList *OwnerList) {
if (R2_GLOBALS._sceneManager._previousScene != 125)
R2_GLOBALS._sound1.play(10);
- _object7.postInit();
- _object7._state = 0;
- _object7.setVisage(100);
- _object7.setPosition(Common::Point(160, 84));
- _object7.setDetails(100, 3, 4, 5, 1, NULL);
+ _door.postInit();
+ _door._state = 0;
+ _door.setVisage(100);
+ _door.setPosition(Common::Point(160, 84));
+ _door.setDetails(100, 3, 4, 5, 1, (SceneItem *)NULL);
- _object10.postInit();
- _object10.setup(100, 2, 1);
- _object10.setDetails(100, -1, -1, -1, 1, NULL);
+ _doorDisplay.postInit();
+ _doorDisplay.setup(100, 2, 1);
+ _doorDisplay.setPosition(Common::Point(202, 53));
+ _doorDisplay.setDetails(100, -1, -1, -1, 1, (SceneItem *)NULL);
- _object8.postInit();
- _object8.setup(100, 2, 3);
- _object8.setPosition(Common::Point(175, 157));
- _object8.setDetails(100, 17, 18, 20, 1, NULL);
+ _table.postInit();
+ _table.setup(100, 2, 3);
+ _table.setPosition(Common::Point(175, 157));
+ _table.setDetails(100, 17, 18, 20, 1, (SceneItem *)NULL);
- _object1.postInit();
- _object1.setup(100, 3, 1);
- _object1.setPosition(Common::Point(89, 79));
- _object1.fixPriority(250);
- _object1.animate(ANIM_MODE_2, NULL);
- _object1._numFrames = 3;
-
- _object2.postInit();
- _object2.setup(100, 3, 1);
- _object2.setPosition(Common::Point(89, 147));
- _object2.fixPriority(250);
- _object2.animate(ANIM_MODE_7, 0, NULL);
- _object2._numFrames = 3;
+ _bedLights1.postInit();
+ _bedLights1.setup(100, 3, 1);
+ _bedLights1.setPosition(Common::Point(89, 79));
+ _bedLights1.fixPriority(250);
+ _bedLights1.animate(ANIM_MODE_2, NULL);
+ _bedLights1._numFrames = 3;
- _object6.postInit();
- _object6.setVisage(101);
- _object6.setPosition(Common::Point(231, 126));
- _object6.fixPriority(10);
- _object6.setDetails(100, 37, -1, 39, 1, NULL);
+ _bedLights2.postInit();
+ _bedLights2.setup(100, 3, 1);
+ _bedLights2.setPosition(Common::Point(89, 147));
+ _bedLights2.fixPriority(250);
+ _bedLights2.animate(ANIM_MODE_7, 0, NULL);
+ _bedLights2._numFrames = 3;
+
+ _wardrobe.postInit();
+ _wardrobe.setVisage(101);
+ _wardrobe.setPosition(Common::Point(231, 126));
+ _wardrobe.fixPriority(10);
+ _wardrobe.setDetails(100, 37, -1, 39, 1, (SceneItem *)NULL);
if (R2_INVENTORY.getObjectScene(R2_STEPPING_DISKS) == 100) {
_steppingDisks.postInit();
_steppingDisks.setup(100, 8, 1);
_steppingDisks.setPosition(Common::Point(274, 130));
- _steppingDisks.setDetails(100, 40, -1, 42, 1, NULL);
+ _steppingDisks.setDetails(100, 40, -1, 42, 1, (SceneItem *)NULL);
}
- _item5.setDetails(11, 100, 14, 15, 16);
- _item4.setDetails(12, 100, 11, -1, 13);
- _item3.setDetails(13, 100, 8, 9, 10);
- _item2.setDetails(14, 100, 34, -1, 36);
+ _terminal.setDetails(11, 100, 14, 15, 16);
+ _desk.setDetails(12, 100, 11, -1, 13);
+ _bed.setDetails(13, 100, 8, 9, 10);
+ _duct.setDetails(14, 100, 34, -1, 36);
R2_GLOBALS._player.postInit();
R2_GLOBALS._player.setVisage(10);
R2_GLOBALS._player.animate(ANIM_MODE_1, NULL);
R2_GLOBALS._player.disableControl();
-
- _item1.setDetails(Rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT), 100, 0, 1, -1, 1, NULL);
+
+ _background.setDetails(Rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT), 100, 0, 1, -1, 1, NULL);
switch (R2_GLOBALS._sceneManager._previousScene) {
case 50:
@@ -237,7 +298,7 @@ void Scene100::postInit(SceneObjectList *OwnerList) {
_object5.postInit();
_object4.postInit();
_sceneMode = 104;
- setAction(&_sequenceManager1, this, 104, &R2_GLOBALS._player, &_object6, &_object4, &_object5, NULL);
+ setAction(&_sequenceManager1, this, 104, &R2_GLOBALS._player, &_wardrobe, &_object4, &_object5, NULL);
break;
case 125:
_sceneMode = 100;
@@ -245,7 +306,7 @@ void Scene100::postInit(SceneObjectList *OwnerList) {
break;
case 200:
_sceneMode = 100;
- setAction(&_sequenceManager1, this, 100, &R2_GLOBALS._player, &_object7, NULL);
+ setAction(&_sequenceManager1, this, 100, &R2_GLOBALS._player, &_door, NULL);
break;
default:
R2_GLOBALS._player.setStrip(3);
@@ -267,11 +328,11 @@ void Scene100::signal() {
break;
case 103:
case 109:
- _object8.setStrip(2);
- _object8.setFrame(3);
-
+ _table.setStrip(2);
+ _table.setFrame(3);
+
_object3.remove();
- _object9.remove();
+ _stasisNegator.remove();
R2_GLOBALS._player.enableControl();
break;
case 104:
@@ -288,22 +349,27 @@ void Scene100::signal() {
R2_GLOBALS._sceneManager.changeScene(125);
break;
case 107:
- R2_GLOBALS._sceneItems.remove(&_object9);
+ R2_GLOBALS._sceneItems.remove(&_stasisNegator);
- _object9.setFrame(2);
- R2_INVENTORY.setObjectScene(3, 1);
+ _stasisNegator.setFrame(2);
+ R2_INVENTORY.setObjectScene(R2_NEGATOR_GUN, 1);
R2_GLOBALS._player.enableControl();
break;
case 110:
- if (_object7._state) {
- _object7._state = 0;
- _object10.setFrame(1);
+ if (_door._state) {
+ _door._state = 0;
+ _doorDisplay.setFrame(1);
} else {
- _object7._state = 1;
- _object10.setFrame(2);
+ _door._state = 1;
+ _doorDisplay.setFrame(2);
}
R2_GLOBALS._player.enableControl();
break;
+ case 111:
+ R2_INVENTORY.setObjectScene(R2_STEPPING_DISKS, 1);
+ _steppingDisks.remove();
+ R2_GLOBALS._player.enableControl();
+ break;
default:
R2_GLOBALS._player.enableControl();
break;
@@ -311,19 +377,7100 @@ void Scene100::signal() {
}
void Scene100::dispatch() {
-/*
int regionIndex = R2_GLOBALS._player.getRegionIndex();
if (regionIndex == 13)
R2_GLOBALS._player._shade = 4;
if ((R2_GLOBALS._player._visage == 13) || (R2_GLOBALS._player._visage == 101))
- (R2_GLOBALS._player._shade = 0;
-*/
+ R2_GLOBALS._player._shade = 0;
+
SceneExt::dispatch();
- if ((_sceneMode == 101) && (_object7._frame == 2) && (_object8._strip == 5)) {
- _object8.setAction(&_sequenceManager2, NULL, 103, &_object8, &_object3, &_object9, NULL);
+ if ((_sceneMode == 101) && (_door._frame == 2) && (_table._strip == 5)) {
+ _table.setAction(&_sequenceManager2, NULL, 103, &_table, &_object3, &_stasisNegator, NULL);
+ }
+}
+
+/*--------------------------------------------------------------------------
+ * Scene 125 - Computer Terminal
+ *
+ *--------------------------------------------------------------------------*/
+
+bool Scene125::Object5::startAction(CursorType action, Event &event) {
+ if (action == CURSOR_USE)
+ return true;
+ else
+ return SceneActor::startAction(action, event);
+}
+
+/*--------------------------------------------------------------------------*/
+
+Scene125::Icon::Icon(): SceneActor() {
+ _lookLineNum = 0;
+ _field98 = 0;
+ _pressed = false;
+}
+
+void Scene125::Icon::postInit(SceneObjectList *OwnerList) {
+ SceneObject::postInit();
+
+ _object1.postInit();
+ _object1.fixPriority(255);
+ _object1.hide();
+
+ _sceneText1._color1 = 92;
+ _sceneText1._color2 = 0;
+ _sceneText1._width = 200;
+ _sceneText2._color1 = 0;
+ _sceneText2._color2 = 0;
+ _sceneText2._width = 200;
+ setDetails(125, -1, -1, -1, 2, (SceneItem *)NULL);
+}
+
+void Scene125::Icon::synchronize(Serializer &s) {
+ SceneActor::synchronize(s);
+ s.syncAsSint16LE(_lookLineNum);
+ s.syncAsSint16LE(_field98);
+ s.syncAsSint16LE(_pressed);
+}
+
+void Scene125::Icon::process(Event &event) {
+ Scene125 *scene = (Scene125 *)R2_GLOBALS._sceneManager._scene;
+
+ if (!event.handled && !(_flags & OBJFLAG_HIDING) && R2_GLOBALS._player._uiEnabled) {
+
+ if (event.eventType == EVENT_BUTTON_DOWN) {
+ int regionIndex = R2_GLOBALS._sceneRegions.indexOf(event.mousePos);
+
+ switch (R2_GLOBALS._events.getCursor()) {
+ case CURSOR_LOOK:
+ if (regionIndex == _sceneRegionId) {
+ event.handled = true;
+ if (_lookLineNum == 26) {
+ SceneItem::display2(130, 7);
+ } else {
+ SceneItem::display2(130, _lookLineNum);
+ }
+ }
+ break;
+
+ case CURSOR_USE:
+ if ((regionIndex == _sceneRegionId) && !_pressed) {
+ scene->_sound1.play(14);
+ setFrame(2);
+
+ switch (_object1._strip) {
+ case 1:
+ _object1.setStrip(2);
+ break;
+ case 3:
+ _object1.setStrip(4);
+ break;
+ case 5:
+ _object1.setStrip(6);
+ break;
+ default:
+ break;
+ }
+
+ _pressed = true;
+ event.handled = true;
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ if ((event.eventType == EVENT_BUTTON_UP) && _pressed) {
+ setFrame(1);
+
+ switch (_object1._strip) {
+ case 2:
+ _object1.setStrip(1);
+ break;
+ case 4:
+ _object1.setStrip(3);
+ break;
+ case 6:
+ _object1.setStrip(5);
+ break;
+ default:
+ break;
+ }
+
+ _pressed = false;
+ event.handled = true;
+ scene->consoleAction(_lookLineNum);
+ }
+ }
+}
+
+void Scene125::Icon::setIcon(int id) {
+ Scene125 *scene = (Scene125 *)R2_GLOBALS._sceneManager._scene;
+
+ _lookLineNum = _field98 = id;
+ SceneActor::_lookLineNum = id;
+
+ _sceneText1.remove();
+ _sceneText2.remove();
+
+ if (_lookLineNum) {
+ showIcon();
+ _object1.setup(161, ((id - 1) / 10) * 2 + 1, ((id - 1) % 10) + 1);
+ _object1.setPosition(_position);
+
+ _sceneText1._fontNumber = scene->_iconFontNumber;
+ _sceneText1.setup(CONSOLE125_MESSAGES[id]);
+ _sceneText1.fixPriority(20);
+
+ _sceneText2._fontNumber = scene->_iconFontNumber;
+ _sceneText2.setup(CONSOLE125_MESSAGES[id]);
+ _sceneText2.fixPriority(20);
+
+ _sceneText2._fontNumber = scene->_iconFontNumber;
+ _sceneText2.setup(CONSOLE125_MESSAGES[id]);
+ _sceneText2.fixPriority(10);
+
+ switch (_lookLineNum) {
+ case 5:
+ _sceneText1.setPosition(Common::Point(62, _position.y + 8));
+ _sceneText2.setPosition(Common::Point(64, _position.y + 10));
+ break;
+ case 6:
+ case 7:
+ case 24:
+ case 25:
+ _sceneText1.setPosition(Common::Point(65, _position.y + 8));
+ _sceneText2.setPosition(Common::Point(67, _position.y + 10));
+ break;
+ case 26:
+ _sceneText1.setPosition(Common::Point(83, _position.y + 8));
+ _sceneText2.setPosition(Common::Point(85, _position.y + 10));
+ break;
+ default:
+ _sceneText1.setPosition(Common::Point(121, _position.y + 8));
+ _sceneText2.setPosition(Common::Point(123, _position.y + 10));
+ break;
+ }
+ } else {
+ hideIcon();
+ }
+}
+
+void Scene125::Icon::showIcon() {
+ _sceneText1.show();
+ _sceneText2.show();
+ _object1.show();
+ _object2.show();
+ show();
+}
+
+void Scene125::Icon::hideIcon() {
+ _sceneText1.hide();
+ _sceneText2.hide();
+ _object1.hide();
+ _object2.hide();
+ hide();
+}
+
+/*--------------------------------------------------------------------------*/
+
+bool Scene125::Item4::startAction(CursorType action, Event &event) {
+ Scene125 *scene = (Scene125 *)R2_GLOBALS._sceneManager._scene;
+ switch (action) {
+ case CURSOR_USE:
+ if (R2_INVENTORY.getObjectScene(R2_OPTO_DISK) == R2_GLOBALS._player._oldCharacterScene[1]) {
+ R2_GLOBALS._player.disableControl();
+ scene->_sceneMode = 126;
+ scene->setAction(&scene->_sequenceManager, scene, 126, &scene->_object7, NULL);
+ return true;
+ }
+ break;
+ case R2_OPTO_DISK:
+ if (R2_INVENTORY.getObjectScene(R2_OPTO_DISK) == 1) {
+ R2_GLOBALS._player.disableControl();
+ scene->_object7.postInit();
+ scene->_sceneMode = 125;
+ scene->setAction(&scene->_sequenceManager, scene, 125, &scene->_object7, NULL);
+ return true;
+ }
+ break;
+ default:
+ break;
+ }
+
+ return SceneHotspot::startAction(action, event);
+}
+
+/*--------------------------------------------------------------------------*/
+
+Scene125::Scene125(): SceneExt() {
+ _iconFontNumber = 50;
+ _consoleMode = 5;
+ _logIndex = _databaseIndex = _infodiskIndex = 0;
+
+ _soundCount = _soundIndex = 0;
+ for (int i = 0; i < 10; ++i)
+ _soundIndexes[i] = 0;
+}
+
+void Scene125::postInit(SceneObjectList *OwnerList) {
+ SceneExt::postInit();
+ loadScene(160);
+ _palette.loadPalette(0);
+
+ if (R2_GLOBALS._sceneManager._previousScene != 125)
+ // Save the prior scene to return to when the console is turned off
+ R2_GLOBALS._player._oldCharacterScene[1] = R2_GLOBALS._sceneManager._previousScene;
+
+ R2_GLOBALS._player.postInit();
+ R2_GLOBALS._player.hide();
+ R2_GLOBALS._player.disableControl();
+
+ if (R2_INVENTORY.getObjectScene(R2_OPTO_DISK) == R2_GLOBALS._player._oldCharacterScene[1]) {
+ _object7.postInit();
+ _object7.setup(160, 3, 5);
+ _object7.setPosition(Common::Point(47, 167));
+ }
+
+ _object6.postInit();
+ _object6.setup(162, 1, 1);
+ _object6.setPosition(Common::Point(214, 168));
+
+ _item4.setDetails(Rect(27, 145, 81, 159), 126, 9, -1, -1, 1, NULL);
+ _item3.setDetails(Rect(144, 119, 286, 167), 126, 6, 7, 8, 1, NULL);
+ _item2.setDetails(1, 126, 3, 4, 5);
+ _background.setDetails(Rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT), 126, 0, 1, -1, 1, NULL);
+
+ _sceneMode = 1;
+ signal();
+}
+
+void Scene125::signal() {
+ switch (_sceneMode) {
+ case 1:
+ _icon1.postInit();
+ _icon1._sceneRegionId = 2;
+ _icon2.postInit();
+ _icon2._sceneRegionId = 3;
+ _icon3.postInit();
+ _icon3._sceneRegionId = 4;
+ _icon4.postInit();
+ _icon4._sceneRegionId = 5;
+
+ _sceneMode = 2;
+ setAction(&_sequenceManager, this, 127, &_icon1, &_icon2, &_icon3, &_icon4, &R2_GLOBALS._player, NULL);
+ break;
+ case 2:
+ _icon1.setup(160, 1, 1);
+ _icon1.setPosition(Common::Point(65, 17));
+ _icon1._object2.postInit();
+ _icon1._object2.setup(160, 7, 1);
+ _icon1._object2.setPosition(Common::Point(106, 41));
+
+ _icon2.setup(160, 1, 1);
+ _icon2.setPosition(Common::Point(80, 32));
+ _icon2._object2.postInit();
+ _icon2._object2.setup(160, 7, 2);
+ _icon2._object2.setPosition(Common::Point(106, 56));
+
+ _icon3.setup(160, 1, 1);
+ _icon3.setPosition(Common::Point(65, 47));
+ _icon3._object2.postInit();
+ _icon3._object2.setup(160, 7, 1);
+ _icon3._object2.setPosition(Common::Point(106, 71));
+
+ _icon4.setup(160, 1, 1);
+ _icon4.setPosition(Common::Point(80, 62));
+ _icon4._sceneRegionId = 5;
+ _icon4._object2.postInit();
+ _icon4._object2.setup(160, 7, 2);
+ _icon4._object2.setPosition(Common::Point(106, 86));
+
+ _icon5.postInit();
+ _icon5.setup(160, 1, 1);
+ _icon5.setPosition(Common::Point(37, 92));
+ _icon5.setIcon(6);
+ _icon5._sceneRegionId = 7;
+
+ _icon6.postInit();
+ _icon6.setup(160, 1, 1);
+ _icon6.setPosition(Common::Point(106, 110));
+ _icon6.setIcon(5);
+ _icon6._sceneRegionId = 8;
+
+ consoleAction(5);
+ R2_GLOBALS._player.enableControl();
+ R2_GLOBALS._player._canWalk = false;
+ break;
+ case 10:
+ switch (_consoleMode) {
+ case 12:
+ _sceneMode = 129;
+
+ _object1.postInit();
+ _object2.postInit();
+ _object3.postInit();
+
+ if (R2_GLOBALS.getFlag(13)) {
+ _object4.postInit();
+ setAction(&_sequenceManager, this, 130, &R2_GLOBALS._player, &_object1, &_object2,
+ &_object3, &_object4, NULL);
+ } else {
+ setAction(&_sequenceManager, this, 129, &R2_GLOBALS._player, &_object1, &_object2, &_object3, NULL);
+ }
+ break;
+ case 13:
+ R2_GLOBALS._player.enableControl();
+ R2_GLOBALS._player._canWalk = false;
+ _infodiskIndex = 0;
+ setDetails(129, 0);
+ break;
+ case 23:
+ R2_GLOBALS._sceneManager.changeScene(1330);
+ break;
+ case 27:
+ R2_GLOBALS._player.enableControl();
+ R2_GLOBALS._player._canWalk = false;
+ _databaseIndex = 0;
+ setDetails(128, 0);
+ break;
+ case 28:
+ R2_GLOBALS._player.enableControl();
+ R2_GLOBALS._player._canWalk = false;
+ _databaseIndex = 37;
+ setDetails(128, 37);
+ break;
+ case 29:
+ R2_GLOBALS._player.enableControl();
+ R2_GLOBALS._player._canWalk = false;
+ _databaseIndex = 68;
+ setDetails(128, 68);
+ break;
+ case 30:
+ R2_GLOBALS._player.enableControl();
+ R2_GLOBALS._player._canWalk = false;
+ _databaseIndex = 105;
+ setDetails(128, 105);
+ break;
+ default:
+ R2_GLOBALS._player.enableControl();
+ R2_GLOBALS._player._canWalk = false;
+ _logIndex = 0;
+ setDetails(127, 0);
+ break;
+ }
+ break;
+ case 11:
+ R2_GLOBALS._player.enableControl();
+ R2_GLOBALS._player._canWalk = false;
+
+ if ((_consoleMode >= 27) && (_consoleMode <= 30)) {
+ consoleAction(11);
+ }
+ consoleAction(2);
+ _icon6.setIcon(5);
+ break;
+ case 12:
+ if (_soundCount > 0)
+ --_soundCount;
+ if (!_soundCount || (R2_GLOBALS._speechSubtitles & SPEECH_VOICE)) {
+ _soundIndex = 0;
+ R2_GLOBALS._playStream.stop();
+ } else {
+ _sceneMode = 12;
+ R2_GLOBALS._playStream.play(_soundIndexes[_soundIndex++], this);
+ }
+ break;
+ case 125:
+ R2_INVENTORY.setObjectScene(R2_OPTO_DISK, R2_GLOBALS._player._oldCharacterScene[1]);
+ break;
+ case 126:
+ R2_INVENTORY.setObjectScene(R2_OPTO_DISK, 1);
+ _object7.remove();
+ R2_GLOBALS._player.enableControl();
+ R2_GLOBALS._player._canWalk = false;
+ break;
+ case 128:
+ R2_GLOBALS._player.enableControl();
+ R2_GLOBALS._player._canWalk = false;
+ SceneItem::display2(126, 12);
+ break;
+ default:
+ R2_GLOBALS._player.enableControl();
+ R2_GLOBALS._player._canWalk = false;
+ break;
+ }
+}
+
+void Scene125::synchronize(Serializer &s) {
+ SceneExt::synchronize(s);
+
+ s.syncAsSint16LE(_consoleMode);
+ s.syncAsSint16LE(_iconFontNumber);
+ s.syncAsSint16LE(_logIndex);
+ s.syncAsSint16LE(_databaseIndex);
+ s.syncAsSint16LE(_infodiskIndex);
+ s.syncAsSint16LE(_soundCount);
+ s.syncAsSint16LE(_soundIndex);
+
+ for (int i = 0; i < 10; ++i)
+ s.syncAsSint16LE(_soundIndexes[i]);
+}
+
+void Scene125::process(Event &event) {
+ SceneExt::process(event);
+
+ if (R2_GLOBALS._player._uiEnabled) {
+ _icon1.process(event);
+ _icon2.process(event);
+ _icon3.process(event);
+ _icon4.process(event);
+ _icon5.process(event);
+ _icon6.process(event);
+ }
+}
+
+void Scene125::dispatch() {
+ if (_soundCount)
+ R2_GLOBALS._playStream.proc1();
+
+ Scene::dispatch();
+}
+
+/**
+ * Handles actions on the console screen.
+ */
+void Scene125::consoleAction(int id) {
+ _icon3.setIcon(0);
+ _icon4.setIcon(0);
+
+ if (id == 5)
+ _icon5.setIcon(6);
+ else {
+ switch (_consoleMode) {
+ case 10:
+ case 12:
+ case 13:
+ case 27:
+ case 28:
+ case 29:
+ case 30:
+ break;
+ default:
+ _icon5.setIcon(7);
+ break;
+ }
+ }
+
+ switch (id) {
+ case 1:
+ _icon1.setIcon(8);
+ _icon2.setIcon(9);
+ break;
+ case 2:
+ _icon1.setIcon(10);
+ _icon2.setIcon(11);
+ _icon3.setIcon(12);
+ _icon4.setIcon(13);
+ break;
+ case 3:
+ _icon1.setIcon(15);
+ _icon2.setIcon(16);
+ _icon3.setIcon(17);
+ break;
+ case 4:
+ _icon1.setIcon(22);
+ _icon2.setIcon(23);
+ break;
+ case 6:
+ R2_GLOBALS._sceneManager.changeScene(R2_GLOBALS._player._oldCharacterScene[1]);
+ break;
+ case 7:
+ if (_consoleMode == 11)
+ consoleAction(2);
+ else if (_consoleMode == 22)
+ consoleAction(4);
+ else
+ consoleAction(5);
+ break;
+ case 8:
+ _iconFontNumber = 50;
+ stop();
+ _icon6.setIcon(5);
+ consoleAction(1);
+ break;
+ case 9:
+ _iconFontNumber = 52;
+ stop();
+ _icon6.setIcon(5);
+ consoleAction(1);
+ break;
+ case 10:
+ R2_GLOBALS._player.disableControl();
+ consoleAction(2);
+ _icon1.hideIcon();
+ _icon2.hideIcon();
+ _icon3.hideIcon();
+ _icon5.setIcon(24);
+
+ _icon4.setPosition(Common::Point(52, 107));
+ _icon4._sceneRegionId = 9;
+ _icon4.setIcon(25);
+ _icon4._object2.hide();
+
+ _icon6.setIcon(26);
+ _sceneMode = 10;
+
+ _palette.loadPalette(161);
+ R2_GLOBALS._scenePalette.addFader(_palette._palette, 256, 5, this);
+ break;
+ case 11:
+ _icon1.setIcon(27);
+ _icon2.setIcon(28);
+ _icon3.setIcon(29);
+ _icon4.setIcon(30);
+ break;
+ case 12:
+ R2_GLOBALS._player.disableControl();
+ consoleAction(2);
+ _icon1.hideIcon();
+ _icon2.hideIcon();
+ _icon3.hideIcon();
+ _icon4.hideIcon();
+ _icon5.hideIcon();
+
+ _icon6.setIcon(26);
+ _sceneMode = 10;
+ _palette.loadPalette(161);
+ R2_GLOBALS._scenePalette.addFader(_palette._palette, 256, 5, this);
+ break;
+ case 13:
+ consoleAction(2);
+ if (R2_INVENTORY.getObjectScene(R2_OPTO_DISK) != R2_GLOBALS._player._oldCharacterScene[1]) {
+ SceneItem::display2(126, 17);
+ } else {
+ R2_GLOBALS._player.disableControl();
+
+ _icon1.hideIcon();
+ _icon2.hideIcon();
+ _icon3.hideIcon();
+ _icon5.setIcon(24);
+
+ _icon4.setPosition(Common::Point(52, 107));
+ _icon4._sceneRegionId = 9;
+ _icon4.setIcon(25);
+ _icon4._object2.hide();
+
+ _icon6.setIcon(26);
+ _sceneMode = 10;
+
+ _palette.loadPalette(161);
+ R2_GLOBALS._scenePalette.addFader(_palette._palette, 256, 5, this);
+ }
+ break;
+ case 15:
+ consoleAction(3);
+
+ if (R2_GLOBALS._v565F5 < 3) {
+ R2_GLOBALS._player.disableControl();
+ _object5.postInit();
+ _object5.setup(162, 2, 2);
+ _object5.setPosition(Common::Point(216, UI_INTERFACE_Y));
+
+ R2_GLOBALS._v565F5 += 2;
+ } else if (R2_GLOBALS._v565F5 == 3) {
+ SceneItem::display2(126, 13);
+ } else {
+ SceneItem::display2(126, 14);
+ }
+ break;
+ case 16:
+ consoleAction(3);
+
+ if (R2_GLOBALS._v565F5 < 4) {
+ R2_GLOBALS._player.disableControl();
+ _object5.postInit();
+ _object5.setup(162, 2, 3);
+ _object5.setPosition(Common::Point(218, UI_INTERFACE_Y));
+
+ ++R2_GLOBALS._v565F5;
+ } else {
+ SceneItem::display2(126, 15);
+ }
+ break;
+ case 17:
+ consoleAction(3);
+
+ if (R2_GLOBALS._v565F5 < 4) {
+ R2_GLOBALS._player.disableControl();
+ _object5.postInit();
+ _object5.setup(162, 2, 1);
+ _object5.setPosition(Common::Point(215, UI_INTERFACE_Y));
+
+ ++R2_GLOBALS._v565F5;
+ } else {
+ SceneItem::display2(126, 16);
+ }
+ break;
+ case 22:
+ _icon1.setIcon(31);
+ _icon2.setIcon(32);
+ _icon3.setIcon(33);
+ _icon4.setIcon(34);
+ break;
+ case 23:
+ R2_GLOBALS._player.disableControl();
+ consoleAction(4);
+ _icon1.hideIcon();
+ _icon2.hideIcon();
+ _icon3.hideIcon();
+ _icon4.hideIcon();
+ _icon5.hideIcon();
+ _icon6.hideIcon();
+
+ _sceneMode = 10;
+ _palette.loadPalette(161);
+ R2_GLOBALS._scenePalette.addFader(_palette._palette, 256, 5, this);
+ break;
+ case 24:
+ _icon4.setIcon(25);
+ _icon4._object2.hide();
+
+ if (_consoleMode == 10) {
+ setDetails(127, --_logIndex);
+ } else if (_consoleMode == 13) {
+ setDetails(129, --_infodiskIndex);
+ } else {
+ setDetails(128, --_databaseIndex);
+ }
+ break;
+ case 25:
+ _icon4.setIcon(25);
+ _icon4._object2.hide();
+
+ if (_consoleMode == 10) {
+ setDetails(127, ++_logIndex);
+ } else if (_consoleMode == 13) {
+ setDetails(129, ++_infodiskIndex);
+ } else {
+ setDetails(128, ++_databaseIndex);
+ }
+ break;
+ case 26:
+ R2_GLOBALS._player.disableControl();
+ stop();
+ _icon4.setPosition(Common::Point(80, 62));
+ _icon4._sceneRegionId = 5;
+ _icon4.hideIcon();
+
+ R2_GLOBALS._player.hide();
+ _object1.hide();
+ _object2.hide();
+ _object3.hide();
+ _object4.hide();
+
+ _sceneMode = 11;
+ _palette.loadPalette(160);
+ R2_GLOBALS._scenePalette.addFader(_palette._palette, 256, 5, this);
+ break;
+ case 27:
+ case 28:
+ case 29:
+ case 30:
+ R2_GLOBALS._player.disableControl();
+ consoleAction(11);
+ _consoleMode = id;
+
+ _icon1.hideIcon();
+ _icon2.hideIcon();
+ _icon3.hideIcon();
+ _icon4.hideIcon();
+ _icon5.setIcon(24);
+
+ _icon4.setPosition(Common::Point(52, 107));
+ _icon4._sceneRegionId = 9;
+ _icon4.setIcon(25);
+ _icon4._object2.hide();
+
+ _icon6.setIcon(26);
+ _sceneMode = 10;
+
+ _palette.loadPalette(161);
+ R2_GLOBALS._scenePalette.addFader(_palette._palette, 256, 5, this);
+ break;
+ case 31:
+ consoleAction(22);
+ R2_GLOBALS._sound1.play((R2_GLOBALS._sound1.getSoundNum() == 10) ? 63 : 10);
+ break;
+ case 32:
+ consoleAction(22);
+ R2_GLOBALS._sound1.play((R2_GLOBALS._sound1.getSoundNum() == 10) ? 64 : 10);
+ break;
+ case 33:
+ consoleAction(22);
+ R2_GLOBALS._sound1.play((R2_GLOBALS._sound1.getSoundNum() == 10) ? 65 : 10);
+ break;
+ case 34:
+ consoleAction(22);
+ R2_GLOBALS._sound1.play((R2_GLOBALS._sound1.getSoundNum() == 10) ? 66 : 10);
+ break;
+ default:
+ _icon1.setIcon(1);
+ _icon2.setIcon(2);
+ _icon3.setIcon(3);
+ _icon4.setIcon(4);
+ break;
+ }
+
+ if ((id != 6) && (id != 7) && (id != 24) && (id != 25))
+ _consoleMode = id;
+}
+
+/**
+ * Sets the message to be displayed on the console screen.
+ */
+void Scene125::setDetails(int resNum, int lineNum) {
+ stop();
+
+ Common::String msg = g_resourceManager->getMessage(resNum, lineNum, true);
+
+ if (!msg.empty()) {
+ // Check for any specified sound numbers embedded in the message
+ msg = parseMessage(msg);
+
+ _sceneText._fontNumber = _iconFontNumber;
+ _sceneText._color1 = 92;
+ _sceneText._color2 = 0;
+ _sceneText._width = 221;
+ _sceneText.fixPriority(20);
+ _sceneText.setup(msg);
+ _sceneText.setPosition(Common::Point(49, 19));
+
+ R2_GLOBALS._sceneObjects->draw();
+
+ if ((_soundCount > 0) && (R2_GLOBALS._speechSubtitles & SPEECH_VOICE)) {
+ _sceneMode = 12;
+ R2_GLOBALS._playStream.play(_soundIndexes[_soundIndex], this);
+ }
+ } else {
+ // Passed the start or end of the message set, so return to the menu
+ R2_GLOBALS._player.disableControl();
+ R2_GLOBALS._player.hide();
+
+ _icon4.setPosition(Common::Point(80, 62));
+ _icon4._sceneRegionId = 5;
+ _icon4.hideIcon();
+
+ _consoleMode = 0;
+ _palette.loadPalette(160);
+ _sceneMode = 11;
+ R2_GLOBALS._scenePalette.addFader(_palette._palette, 256, 5, this);
+ }
+}
+
+/**
+ * Stops any playing console sounds and hides any current console message.
+ */
+void Scene125::stop() {
+ _sceneText.remove();
+ _soundIndex = 0;
+ _soundCount = 0;
+
+ R2_GLOBALS._playStream.stop();
+}
+
+/**
+ * Parses a message to be displayed on the console to see whether there are any sounds to be played.
+ */
+Common::String Scene125::parseMessage(const Common::String &msg) {
+ _soundIndex = 0;
+ _soundCount = 0;
+
+ const char *msgP = msg.c_str();
+ while (*msgP == '!') {
+ // Get the sound number
+ _soundIndexes[_soundCount++] = atoi(++msgP);
+
+ while (!((*msgP == '\0') || (*msgP < '0') || (*msgP > '9')))
+ ++msgP;
+ }
+
+ return Common::String(msgP);
+}
+
+/*--------------------------------------------------------------------------
+ * Scene 150 - Empty Bedroom
+ *
+ *--------------------------------------------------------------------------*/
+
+void Scene150::postInit(SceneObjectList *OwnerList) {
+ SceneExt::postInit();
+ loadScene(100);
+
+ _door.postInit();
+ _door._state = 0;
+ _door.setVisage(100);
+ _door.setPosition(Common::Point(160, 84));
+ _door.setDetails(100, 3, -1, -1, 1, (SceneItem *)NULL);
+
+ _doorDisplay.postInit();
+ _doorDisplay.setup(100, 2, 1);
+ _doorDisplay.setPosition(Common::Point(202, 53));
+ _doorDisplay.setDetails(100, -1, -1, -1, 1, (SceneItem *)NULL);
+
+ _emptyRoomTable.postInit();
+ _emptyRoomTable.setVisage(100);
+ _emptyRoomTable.setStrip(4);
+ _emptyRoomTable.setFrame(1);
+ _emptyRoomTable.setPosition(Common::Point(175, 157));
+ _emptyRoomTable.setDetails(150, 3, 4, 5, 1, (SceneItem *)NULL);
+
+ _wardrobe.postInit();
+ _wardrobe.setVisage(101);
+ _wardrobe.setPosition(Common::Point(231, 126));
+ _wardrobe.fixPriority(10);
+ _wardrobe.setDetails(100, 37, -1, 39, 1, (SceneItem *)NULL);
+
+ _terminal.setDetails(11, 100, 14, 15, 16);
+ _desk.setDetails(12, 100, 11, -1, 13);
+ _bed.setDetails(13, 100, 8, 9, 10);
+ _duct.setDetails(14, 100, 34, -1, 36);
+
+ R2_GLOBALS._player.postInit();
+ R2_GLOBALS._player.setVisage(10);
+ R2_GLOBALS._player.animate(ANIM_MODE_1, NULL);
+ R2_GLOBALS._player.disableControl();
+
+ _background.setDetails(Rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT), 150, 0, 1, -1, 1, NULL);
+ _sceneMode = 100;
+
+ switch (R2_GLOBALS._sceneManager._previousScene) {
+ case 100:
+ setAction(&_sequenceManager1, this, 106, &R2_GLOBALS._player, NULL);
+ break;
+ case 200:
+ setAction(&_sequenceManager1, this, 100, &R2_GLOBALS._player, &_door, NULL);
+ break;
+ default:
+ R2_GLOBALS._player.setStrip(3);
+ R2_GLOBALS._player.setPosition(Common::Point(180, 100));
+ R2_GLOBALS._player.enableControl();
+ break;
+ }
+}
+
+void Scene150::remove() {
+ R2_GLOBALS._sound1.fadeOut2(NULL);
+ SceneExt::remove();
+}
+
+void Scene150::signal() {
+ switch (_sceneMode) {
+ case 101:
+ R2_GLOBALS._sceneManager.changeScene(200);
+ break;
+ case 105:
+ R2_GLOBALS._sceneManager.changeScene(125);
+ break;
+ case 110:
+ if (_door._state) {
+ _door._state = 0;
+ _doorDisplay.setFrame(1);
+ } else {
+ _door._state = 1;
+ _doorDisplay.setFrame(2);
+ }
+ R2_GLOBALS._player.enableControl();
+ break;
+ default:
+ R2_GLOBALS._player.enableControl();
+ break;
+ }
+}
+
+/*--------------------------------------------------------------------------
+ * Scene 160 - Credits
+ *
+ *--------------------------------------------------------------------------*/
+
+void Scene160::Action1::signal() {
+ Scene160 *scene = (Scene160 *)R2_GLOBALS._sceneManager._scene;
+ bool breakFlag;
+ SynchronizedList<SceneText *>::iterator i;
+ SceneText *topItem;
+
+ switch (_actionIndex) {
+ case 0:
+ scene->_yChange = 1;
+ scene->_lineNum = 0;
+ ++_actionIndex;
+ // Deliberate fall-through
+
+ case 1:
+ setDelay(5);
+ breakFlag = true;
+ do {
+ if (!scene->_lineNum || ((scene->_lineNum != -1) &&
+ (((*scene->_creditsList.reverse_begin())->_position.y < 164) || !breakFlag))) {
+ breakFlag = true;
+ Common::String msg = g_resourceManager->getMessage(160, scene->_lineNum++);
+
+ if (*msg.c_str() == '^') {
+ scene->_lineNum = -1;
+ } else {
+ if (msg.size() == 0)
+ msg = " ";
+
+ SceneText *sceneText = new SceneText();
+ sceneText->_fontNumber = 50;
+
+ switch (*msg.c_str()) {
+ case '$': {
+ // Centered text
+ msg.deleteChar(0);
+ int width = R2_GLOBALS.gfxManager()._font.getStringWidth(msg.c_str());
+
+ sceneText->_textMode = ALIGN_CENTER;
+ sceneText->setPosition(Common::Point(160 - (width / 2), 175));
+ sceneText->_width = 320;
+ break;
+ }
+
+ case '%': {
+ // Text for position name
+ msg.deleteChar(0);
+ int width = R2_GLOBALS.gfxManager()._font.getStringWidth(msg.c_str());
+
+ sceneText->_textMode = ALIGN_RIGHT;
+ sceneText->setPosition(Common::Point(151 - width, 175));
+ sceneText->_width = 320;
+ breakFlag = false;
+ break;
+ }
+
+ case '@':
+ // Text for who was in the position
+ msg.deleteChar(0);
+ sceneText->_textMode = ALIGN_LEFT;
+ sceneText->_position = Common::Point(167, 175);
+ sceneText->_width = 153;
+ break;
+
+ default:
+ sceneText->_width = 151;
+ sceneText->setPosition(Common::Point(151, 175));
+ sceneText->_textMode = ALIGN_RIGHT;
+ break;
+ }
+
+ sceneText->_color1 = 191;
+ sceneText->_color2 = 191;
+ sceneText->_color3 = 191;
+ sceneText->setup(msg);
+ sceneText->_flags |= OBJFLAG_CLONED;
+ sceneText->fixPriority(5);
+
+ scene->_creditsList.push_back(sceneText);
+ }
+ }
+
+ } while (!breakFlag);
+
+ // Move all the active credits
+ for (i = scene->_creditsList.begin(); i != scene->_creditsList.end(); ++i) {
+ SceneObject *item = *i;
+ item->setPosition(Common::Point(item->_position.x, item->_position.y - scene->_yChange));
+ }
+
+ topItem = *scene->_creditsList.begin();
+ if (topItem->_position.y < 25) {
+ // Credit has reached the top, so remove it
+ topItem->remove();
+ scene->_creditsList.remove(topItem);
+
+ if (scene->_creditsList.size() == 0) {
+ // No more items left
+ setDelay(10);
+ ++_actionIndex;
+ }
+ }
+ break;
+
+ case 2:
+ HelpDialog::show();
+ setDelay(4);
+ break;
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+
+Scene160::Scene160(): SceneExt() {
+ _frameNumber = _yChange = 0;
+ _lineNum = 0;
+}
+
+void Scene160::postInit(SceneObjectList *OwnerList) {
+ SceneExt::postInit();
+ loadScene(4001);
+
+ R2_GLOBALS._player._uiEnabled = false;
+ R2_GLOBALS._player.enableControl();
+ R2_GLOBALS._player._canWalk = false;
+
+ R2_GLOBALS._uiElements.hide();
+ R2_GLOBALS._interfaceY = SCREEN_HEIGHT;
+
+ _lineNum = 0;
+ _frameNumber = R2_GLOBALS._events.getFrameNumber();
+
+ _sound1.play(337);
+ setAction(&_action1);
+}
+
+void Scene160::synchronize(Serializer &s) {
+ SceneExt::synchronize(s);
+ s.syncAsSint16LE(_frameNumber);
+ s.syncAsSint16LE(_yChange);
+ s.syncAsSint16LE(_lineNum);
+}
+
+void Scene160::remove() {
+ // Clear the credit list
+ SynchronizedList<SceneText *>::iterator i;
+ for (i = _creditsList.begin(); i != _creditsList.end(); ++i) {
+ SceneText *item = *i;
+
+ item->remove();
+ }
+ _creditsList.clear();
+
+ _sound1.fadeOut(NULL);
+ SceneExt::remove();
+}
+
+void Scene160::process(Event &event) {
+ if ((event.eventType == EVENT_KEYPRESS) && (event.kbd.keycode == Common::KEYCODE_ESCAPE)) {
+ event.handled = true;
+ HelpDialog::show();
+ }
+
+ if (!event.handled)
+ SceneExt::process(event);
+}
+
+/*--------------------------------------------------------------------------
+ * Scene 180 - Title Screen
+ *
+ *--------------------------------------------------------------------------*/
+
+void Scene180::Action1::signal() {
+ Scene180 *scene = (Scene180 *)R2_GLOBALS._sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0:
+ case 1:
+ case 2:
+ scene->_object5.setStrip((_actionIndex == 1) ? 1 : 2);
+ scene->_object5.setFrame(1);
+ scene->_object5.animate(ANIM_MODE_5, this);
+ break;
+ case 4:
+ scene->_object5.setStrip(3);
+ scene->_object5.setFrame(1);
+ scene->_object5.animate(ANIM_MODE_5, this);
+ _actionIndex = 0;
+ break;
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+
+Scene180::Scene180(): SceneExt(), _webbsterSpeaker(27) {
+ _field412 = 0;
+ _frameInc = 0;
+ _frameNumber = R2_GLOBALS._events.getFrameNumber();
+ _field480 = 1;
+ _field482 = -1;
+ _fontNumber = R2_GLOBALS.gfxManager()._font._fontNumber;
+
+ GfxFont font;
+ font.setFontNumber(7);
+ _fontHeight = font.getHeight() + 1;
+
+ _sceneMode = (R2_GLOBALS._sceneManager._previousScene == 205) ? 10 : 0;
+ _gameTextSpeaker._displayMode = 9;
+}
+
+void Scene180::postInit(SceneObjectList *OwnerList) {
+ loadScene(9999);
+ SceneExt::postInit();
+
+ R2_GLOBALS._uiElements._active = true;
+ R2_GLOBALS._player.disableControl();
+
+ _stripManager.addSpeaker(&_gameTextSpeaker);
+ _stripManager.addSpeaker(&_webbsterSpeaker);
+ _stripManager.addSpeaker(&_tealSpeaker);
+ _stripManager.addSpeaker(&_dutyOfficerSpeaker);
+
+ signal();
+}
+
+void Scene180::remove() {
+ _stripManager._field2E8 = -1;
+// _stripManager._field2EA = -1;
+ SceneExt::remove();
+
+ R2_GLOBALS._events.setCursor(CURSOR_WALK);
+ // word_575F7 = 0;
+ R2_GLOBALS._playStream.stop();
+ R2_GLOBALS._sound2.fadeOut2(NULL);
+ R2_GLOBALS._sound1.fadeOut2(NULL);
+}
+
+void Scene180::synchronize(Serializer &s) {
+ SceneExt::synchronize(s);
+
+ s.syncAsSint16LE(_frameNumber);
+ s.syncAsSint16LE(_field412);
+ s.syncAsSint16LE(_field480);
+ s.syncAsSint16LE(_field482);
+ s.syncAsSint16LE(_frameInc);
+ s.syncAsSint16LE(_fontNumber);
+ s.syncAsSint16LE(_fontHeight);
+}
+
+void Scene180::signal() {
+ R2_GLOBALS._playStream.stop();
+
+ switch (_sceneMode++) {
+ case 0:
+ setSceneDelay(6);
+ break;
+
+ case 1:
+ _field412 = 1;
+ R2_GLOBALS._sceneManager._hasPalette = true;
+ _animationPlayer._paletteMode = ANIMPALMODE_NONE;
+ _animationPlayer._v = 1;
+ _animationPlayer._objectMode = 1;
+ R2_GLOBALS._scene180Mode = 1;
+
+ _animationPlayer.load(1);
+ R2_GLOBALS._scenePalette.loadPalette(_animationPlayer._subData._palData, 0, 256);
+
+ R2_GLOBALS._sound1.play(1);
+ break;
+
+ case 2:
+ R2_GLOBALS._scene180Mode = 1;
+ R2_GLOBALS._paneRefreshFlag[0] = 3;
+
+ if (R2_GLOBALS._sound1.isPlaying()) {
+ setSceneDelay(1);
+ } else {
+ setSceneDelay(180);
+ }
+ break;
+
+ case 3:
+ R2_GLOBALS._scene180Mode = 1;
+
+ if (R2_GLOBALS._sound1.isPlaying())
+ _sceneMode = 3;
+
+ setSceneDelay(1);
+ break;
+
+ case 4:
+ case 8:
+ case 30:
+ case 43:
+ case 47:
+ _field412 = 0;
+ _palette.loadPalette(0);
+ _palette.loadPalette(9998);
+ R2_GLOBALS._scenePalette.addFader(_palette._palette, 256, 8, this);
+ break;
+
+ case 5:
+ _animationPlayer._paletteMode = ANIMPALMODE_NONE;
+ _animationPlayer._v = 1;
+ _animationPlayer._objectMode = 1;
+ R2_GLOBALS._scene180Mode = 2;
+ _animationPlayer.load(2);
+
+ _field412 = 1;
+ R2_GLOBALS._scenePalette.addFader(_animationPlayer._subData._palData, 256, 6, NULL);
+ R2_GLOBALS._sound1.play(2);
+ break;
+
+ case 6:
+ R2_GLOBALS._scene180Mode = 2;
+ R2_GLOBALS._paneRefreshFlag[0] = 3;
+
+ if (R2_GLOBALS._sound1.isPlaying()) {
+ setSceneDelay(1);
+ } else {
+ setSceneDelay(180);
+ }
+ break;
+
+ case 7:
+ // Title screen. Wait until title music finishes playing
+ R2_GLOBALS._scene180Mode = 2;
+ if (R2_GLOBALS._sound1.isPlaying())
+ _sceneMode = 7;
+ setSceneDelay(1);
+ break;
+
+ case 9:
+ R2_GLOBALS._sound1.play(3);
+ clearScreen();
+ setSceneDelay(2);
+ break;
+
+ case 10:
+ loadScene(4002);
+ R2_GLOBALS._scenePalette.loadPalette(0);
+ setSceneDelay(6);
+ break;
+
+ case 11:
+ _field412 = 1;
+ _object4.postInit();
+ _object5.postInit();
+ setAction(&_sequenceManager, this, 4000, &_object4, &_object5, NULL);
+ break;
+
+ case 12:
+ case 14:
+ case 16:
+ case 18:
+ case 20:
+ case 22:
+ case 24:
+ case 26:
+ case 46:
+ setSceneDelay((R2_GLOBALS._speechSubtitles & 1) ? 1 : 18);
+ break;
+
+ case 13:
+ setAction(&_sequenceManager, this, 4001, &_object4, &_object5, NULL);
+ break;
+
+ case 15:
+ setAction(&_sequenceManager, this, 4002, &_object4, &_object5, NULL);
+ break;
+
+ case 17:
+ setAction(&_sequenceManager, this, 4003, &_object4, &_object5, NULL);
+ break;
+
+ case 19:
+ setAction(&_sequenceManager, this, 4004, &_object4, &_object5, NULL);
+ break;
+
+ case 21:
+ setAction(&_sequenceManager, this, 4005, &_object4, &_object5, NULL);
+ break;
+
+ case 23:
+ setAction(&_sequenceManager, this, 4006, &_object4, &_object5, NULL);
+ break;
+
+ case 25:
+ setAction(&_sequenceManager, this, 4007, &_object4, &_object5, NULL);
+ break;
+
+ case 27:
+ _field412 = 0;
+ _object4.remove();
+ _object5.remove();
+ setSceneDelay(2);
+ break;
+
+ case 28:
+ _field412 = 0;
+ _palette.loadPalette(0);
+ _palette.loadPalette(9998);
+ R2_GLOBALS._scenePalette.addFader(_palette._palette, 256, 100, this);
+ break;
+
+ case 29:
+ _field412 = 1;
+ _animationPlayer._paletteMode = ANIMPALMODE_REPLACE_PALETTE;
+ _animationPlayer._v = 1;
+ _animationPlayer._objectMode = 42;
+ R2_GLOBALS._scene180Mode = 3;
+ _animationPlayer.load(3);
+ break;
+
+ case 31:
+ R2_GLOBALS._sound2.play(7);
+
+ _object4.postInit();
+ _object4.setVisage(76);
+ _object4.setStrip(1);
+ _object4.setFrame(1);
+ _object4.setPosition(Common::Point(288, 143));
+ _object4.fixPriority(210);
+
+ loadScene(75);
+
+ R2_GLOBALS._scenePalette.loadPalette(0);
+ R2_GLOBALS._scenePalette.loadPalette(75);
+
+ if (R2_GLOBALS._sceneManager._hasPalette)
+ R2_GLOBALS._scenePalette.refresh();
+ setSceneDelay(6);
+ break;
+
+ case 32:
+ _field412 = 1;
+
+ _object2.postInit();
+ _object2.setPosition(Common::Point(161, 97));
+ _object2.hide();
+
+ _object3.postInit();
+ _object3.setPosition(Common::Point(60, 96));
+ _object3.hide();
+ R2_GLOBALS._scenePalette.addFader(_palette._palette, 256, 11, this);
+ break;
+
+ case 33:
+ _object2.hide();
+
+ _object3.setup(76, 4, 1);
+ _object3.setFrame(_object3.getFrameCount());
+
+ _object5.postInit();
+ _object5.setup(75, 1, 1);
+ _object5.setPosition(Common::Point(221, 125));
+ _object5.fixPriority(210);
+ _object5.setAction(&_action1);
+ R2_GLOBALS._scenePalette.addFader(_palette._palette, 256, 12, this);
+ break;
+
+ case 34:
+ _object2.hide();
+ _object3.hide();
+
+ _object1.postInit();
+ _object1.setup(76, 2, 1);
+ _object1.setPosition(Common::Point(287, 135));
+ _object1.fixPriority(200);
+
+ _sound1.play(19);
+ R2_GLOBALS._scenePalette.addFader(_palette._palette, 256, 5, this);
+ break;
+
+ case 35:
+ R2_GLOBALS._scenePalette.addFader(_palette._palette, 256, 13, this);
+ break;
+
+ case 36:
+ _object2.remove();
+ _sound1.play(19);
+
+ R2_GLOBALS._scenePalette.addFader(_palette._palette, 256, 6, this);
+ break;
+
+ case 37:
+ _field412 = 0;
+ _object1.remove();
+ _palette.loadPalette(9998);
+ R2_GLOBALS._scenePalette.addFader(_palette._palette, 256, 8, this);
+ break;
+
+ case 38:
+ _object4.remove();
+ _object5.setAction(NULL);
+ _object5.remove();
+
+ R2_GLOBALS._sound2.fadeOut2(NULL);
+ R2_GLOBALS._sound1.fadeOut2(NULL);
+ break;
+
+ case 39:
+ R2_GLOBALS._sound1.changeSound(8);
+ setSceneDelay(1);
+ break;
+
+ case 40:
+ _animationPlayer._paletteMode = ANIMPALMODE_NONE;
+ _animationPlayer._objectMode = 1;
+ R2_GLOBALS._scene180Mode = 4;
+ if (_animationPlayer.load(4)) {
+ _animationPlayer.dispatch();
+ R2_GLOBALS._scenePalette.addFader(_animationPlayer._subData._palData, 256, 8, this);
+ } else {
+ _sceneMode = 43;
+ setSceneDelay(1);
+ }
+ break;
+
+ case 41:
+ _field412 = 1;
+ _animationPlayer._v = 1;
+ break;
+
+ case 42:
+ R2_GLOBALS._scene180Mode = 4;
+ R2_GLOBALS._paneRefreshFlag[0] = 3;
+ setSceneDelay(1);
+ break;
+
+ case 44:
+ loadScene(9997);
+ R2_GLOBALS._scenePalette.loadPalette(9997);
+ if (R2_GLOBALS._sceneManager._hasPalette)
+ R2_GLOBALS._scenePalette.refresh();
+
+ setSceneDelay(6);
+ break;
+
+ case 45:
+ R2_GLOBALS._scenePalette.addFader(_animationPlayer._subData._palData, 256, 28, this);
+ break;
+
+ case 48:
+ _field412 = 1;
+ _animationPlayer._paletteMode = ANIMPALMODE_NONE;
+ _animationPlayer._v = 1;
+ _animationPlayer._objectMode = 1;
+ R2_GLOBALS._scene180Mode = 15;
+ _animationPlayer.load(15, NULL);
+
+ R2_GLOBALS._sound1.play(9);
+ R2_GLOBALS._scenePalette.addFader(_animationPlayer._subData._palData, 256, 6, NULL);
+ break;
+
+ case 49:
+ R2_GLOBALS._scene180Mode = 15;
+ R2_GLOBALS._paneRefreshFlag[0] = 3;
+ setSceneDelay(1);
+ break;
+
+ case 50:
+ R2_GLOBALS._scene180Mode = 0;
+ _field412 = 0;
+ R2_GLOBALS._sceneManager.changeScene(100);
+ break;
+ }
+}
+
+void Scene180::setSceneDelay(int v) {
+ _frameInc = v;
+ _frameNumber = R2_GLOBALS._events.getFrameNumber();
+}
+
+void Scene180::process(Event &event) {
+ if ((event.eventType == EVENT_KEYPRESS) && (event.kbd.keycode == Common::KEYCODE_ESCAPE)) {
+ event.handled = 1;
+ if (!_field412) {
+ if (R2_GLOBALS._scenePalette._listeners.size() == 0) {
+ HelpDialog::show();
+ }
+ }
+ }
+
+ if (!event.handled)
+ SceneExt::process(event);
+}
+
+void Scene180::dispatch() {
+ if (_frameInc) {
+ uint32 gameFrame = R2_GLOBALS._events.getFrameNumber();
+
+ if (gameFrame >= (uint32)_frameNumber) {
+ _frameInc -= gameFrame - _frameNumber;
+ _frameNumber = gameFrame;
+
+ if (_frameInc <= 0) {
+ _frameInc = 0;
+ signal();
+ }
+ }
+ }
+
+ if (_animationPlayer._v) {
+ if (_animationPlayer.isCompleted()) {
+ _animationPlayer._v = 0;
+ _animationPlayer.close();
+ _animationPlayer.remove();
+
+ signal();
+ } else {
+ _animationPlayer.dispatch();
+ }
+ }
+
+ Scene::dispatch();
+}
+
+void Scene180::restore() {
+ R2_GLOBALS._gfxColors.background = 0;
+ R2_GLOBALS._gfxColors.foreground = 0xff;
+ R2_GLOBALS._fontColors.background = 0;
+ R2_GLOBALS._fontColors.foreground = 0xff;
+
+ switch (R2_GLOBALS._scene180Mode) {
+ case 0:
+ R2_GLOBALS._events.setCursor(SHADECURSOR_HAND);
+
+ R2_GLOBALS._gfxColors.foreground = 4;
+ R2_GLOBALS._gfxColors.background = 3;
+ R2_GLOBALS._fontColors.background = 3;
+ R2_GLOBALS._frameEdgeColour = 3;
+ break;
+
+ case 1:
+ R2_GLOBALS._events.setCursor(R2_CURSOR_20);
+
+ R2_GLOBALS._gfxColors.foreground = 25;
+ R2_GLOBALS._gfxColors.background = 43;
+ R2_GLOBALS._fontColors.background = 48;
+ R2_GLOBALS._frameEdgeColour = 48;
+ break;
+
+ case 2:
+ R2_GLOBALS._events.setCursor(R2_CURSOR_21);
+
+ R2_GLOBALS._gfxColors.foreground = 106;
+ R2_GLOBALS._gfxColors.background = 136;
+ R2_GLOBALS._fontColors.background = 48;
+ R2_GLOBALS._fontColors.foreground = 253;
+ R2_GLOBALS._frameEdgeColour = 48;
+ break;
+
+ case 3:
+ R2_GLOBALS._events.setCursor(R2_CURSOR_22);
+
+ R2_GLOBALS._gfxColors.foreground = 84;
+ R2_GLOBALS._gfxColors.background = 118;
+ R2_GLOBALS._fontColors.background = 47;
+ R2_GLOBALS._frameEdgeColour = 48;
+ break;
+
+ case 14:
+ R2_GLOBALS._events.setCursor(R2_CURSOR_23);
+
+ R2_GLOBALS._fontColors.background = 38;
+ R2_GLOBALS._fontColors.foreground = 38;
+ R2_GLOBALS._gfxColors.foreground = 192;
+ R2_GLOBALS._gfxColors.background = 30;
+ R2_GLOBALS._frameEdgeColour = 48;
+ break;
+
+ default:
+ R2_GLOBALS._gfxColors.background = 0;
+ R2_GLOBALS._gfxColors.foreground = 59;
+ R2_GLOBALS._fontColors.background = 4;
+ R2_GLOBALS._fontColors.foreground = 15;
+
+ R2_GLOBALS._events.setCursor(CURSOR_ARROW);
+ break;
+ }
+}
+
+/*--------------------------------------------------------------------------
+ * Scene 200 - Ship Corridor
+ *
+ *--------------------------------------------------------------------------*/
+
+bool Scene200::NorthDoor::startAction(CursorType action, Event &event) {
+ Scene200 *scene = (Scene200 *)R2_GLOBALS._sceneManager._scene;
+
+ if (action == CURSOR_USE) {
+ R2_GLOBALS._player.disableControl();
+ scene->_sceneMode = 202;
+ scene->setAction(&scene->_sequenceManager, scene, 202, &R2_GLOBALS._player, this, NULL);
+ return true;
+ } else {
+ return SceneActor::startAction(action, event);
+ }
+}
+
+bool Scene200::EastDoor::startAction(CursorType action, Event &event) {
+ Scene200 *scene = (Scene200 *)R2_GLOBALS._sceneManager._scene;
+
+ if (action == CURSOR_USE) {
+ R2_GLOBALS._player.disableControl();
+ scene->_sceneMode = 200;
+ scene->setAction(&scene->_sequenceManager, scene, 200, &R2_GLOBALS._player, this, NULL);
+ return true;
+ } else {
+ return SceneActor::startAction(action, event);
+ }
+}
+
+bool Scene200::WestDoor::startAction(CursorType action, Event &event) {
+ Scene200 *scene = (Scene200 *)R2_GLOBALS._sceneManager._scene;
+
+ if (action == CURSOR_USE) {
+ R2_GLOBALS._player.disableControl();
+ scene->_sceneMode = 204;
+ scene->setAction(&scene->_sequenceManager, scene, 204, &R2_GLOBALS._player, this, NULL);
+ return true;
+ } else {
+ return SceneActor::startAction(action, event);
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+
+void Scene200::EastExit::changeScene() {
+ Scene200 *scene = (Scene200 *)R2_GLOBALS._sceneManager._scene;
+
+ _enabled = false;
+ R2_GLOBALS._player.disableControl();
+ scene->_sceneMode = 206;
+ scene->setAction(&scene->_sequenceManager, scene, 206, &R2_GLOBALS._player, NULL);
+}
+
+void Scene200::WestExit::changeScene() {
+ Scene200 *scene = (Scene200 *)R2_GLOBALS._sceneManager._scene;
+
+ _enabled = false;
+ R2_GLOBALS._player.disableControl();
+ scene->_sceneMode = 208;
+ scene->setAction(&scene->_sequenceManager, scene, 208, &R2_GLOBALS._player, NULL);
+}
+
+/*--------------------------------------------------------------------------*/
+
+void Scene200::postInit(SceneObjectList *OwnerList) {
+ SceneExt::postInit();
+ loadScene(200);
+
+ _westExit.setDetails(Rect(94, 0, 123, 58), EXITCURSOR_W, 175);
+ _westExit.setDest(Common::Point(125, 52));
+ _eastExit.setDetails(Rect(133, 0, 167, 58), EXITCURSOR_E, 150);
+ _eastExit.setDest(Common::Point(135, 52));
+
+ _northDoor.postInit();
+ _northDoor.setVisage(200);
+ _northDoor.setPosition(Common::Point(188, 79));
+ _northDoor.setDetails(200, 3, -1, -1, 1, (SceneItem *)NULL);
+
+ _eastDoor.postInit();
+ _eastDoor.setVisage(200);
+ _eastDoor.setStrip(2);
+ _eastDoor.setPosition(Common::Point(305, 124));
+ _eastDoor.setDetails(200, 6, -1, -1, 1, (SceneItem *)NULL);
+
+ _westDoor.postInit();
+ _westDoor.setVisage(200);
+ _westDoor.setStrip(3);
+ _westDoor.setPosition(Common::Point(62, 84));
+ _westDoor.setDetails(200, 9, -1, -1, 1, (SceneItem *)NULL);
+
+ R2_GLOBALS._player.postInit();
+ R2_GLOBALS._player.setVisage(10);
+ R2_GLOBALS._player.animate(ANIM_MODE_1, NULL);
+ R2_GLOBALS._player.disableControl();
+
+ _compartment.setDetails(Rect(4, 88, 153, 167), 200, 12, -1, -1, 1, NULL);
+ _westDoorDisplay.setDetails(Rect(41, 51, 48, 61), 200, 15, -1, -1, 1, NULL);
+ _eastDoorDisplay.setDetails(Rect(279, 67, 286, 78), 200, 18, -1, -1, 1, NULL);
+ _background.setDetails(Rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT), 200, 0, -1, -1, 1, NULL);
+
+ switch (R2_GLOBALS._sceneManager._previousScene) {
+ case 100:
+ _sceneMode = 201;
+ setAction(&_sequenceManager, this, 201, &R2_GLOBALS._player, &_eastDoor, NULL);
+ break;
+ case 150:
+ _sceneMode = 207;
+ setAction(&_sequenceManager, this, 207, &R2_GLOBALS._player, NULL);
+ break;
+ case 175:
+ _sceneMode = 209;
+ setAction(&_sequenceManager, this, 209, &R2_GLOBALS._player, NULL);
+ break;
+ case 250:
+ _sceneMode = 203;
+ setAction(&_sequenceManager, this, 203, &R2_GLOBALS._player, &_northDoor, NULL);
+ break;
+ case 400:
+ _sceneMode = 205;
+ setAction(&_sequenceManager, this, 205, &R2_GLOBALS._player, &_westDoor, NULL);
+ break;
+ default:
+ R2_GLOBALS._player.setStrip(3);
+ R2_GLOBALS._player.setPosition(Common::Point(215, 115));
+ R2_GLOBALS._player.enableControl();
+ break;
+ }
+}
+
+void Scene200::signal() {
+ switch (_sceneMode) {
+ case 200:
+ R2_GLOBALS._sceneManager.changeScene(100);
+ break;
+ case 202:
+ R2_GLOBALS._sceneManager.changeScene(250);
+ break;
+ case 204:
+ R2_GLOBALS._sceneManager.changeScene(400);
+ break;
+ case 206:
+ R2_GLOBALS._sceneManager.changeScene(150);
+ break;
+ case 208:
+ R2_GLOBALS._sceneManager.changeScene(175);
+ break;
+ default:
+ R2_GLOBALS._player.enableControl();
+ break;
+ }
+}
+
+/*--------------------------------------------------------------------------
+ * Scene 205 - Star-field Credits
+ *
+ *--------------------------------------------------------------------------*/
+
+void Scene205::Action1::signal() {
+ Scene205 *scene = (Scene205 *)R2_GLOBALS._sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0:
+ setDelay(2);
+ break;
+
+ case 1:
+ scene->_yp = 100 - (scene->_fontHeight * 3 / 2);
+ scene->handleText();
+
+ for (int idx = 1; idx <= 2; ++idx) {
+ ++scene->_textIndex;
+ scene->_yp += scene->_fontHeight;
+ scene->handleText();
+ }
+ setDelay(240);
+ break;
+
+ case 2:
+ case 4:
+ case 6:
+ case 8:
+ case 10:
+ case 12:
+ case 14:
+ case 16:
+ case 18:
+ case 20:
+ textLoop();
+ setDelay(120);
+ break;
+
+ case 3:
+ scene->_textIndex = 1;
+ scene->_yp = 100 - ((scene->_fontHeight * 2) / 2);
+ scene->handleText();
+
+ ++scene->_textIndex;
+ scene->_yp += scene->_fontHeight;
+ scene->handleText();
+ setDelay(240);
+ break;
+
+ case 5:
+ scene->_textIndex = 1;
+ scene->_yp = 100 - ((scene->_fontHeight * 7) / 2);
+ scene->handleText();
+
+ for (int idx = 1; idx <= 6; ++idx) {
+ ++scene->_textIndex;
+ scene->_yp += scene->_fontHeight;
+ scene->handleText();
+ }
+
+ setDelay(480);
+ break;
+
+ case 7:
+ scene->_textIndex = 1;
+ scene->_yp = 100 - ((scene->_fontHeight * 6) / 2);
+ scene->handleText();
+
+ for (int idx = 1; idx <= 5; ++idx) {
+ ++scene->_textIndex;
+ scene->_yp += scene->_fontHeight;
+ scene->handleText();
+ }
+
+ setDelay(300);
+ break;
+
+ case 9:
+ scene->_textIndex = 1;
+ scene->_yp = 100 - ((scene->_fontHeight * 8) / 2);
+ scene->handleText();
+
+ for (int idx = 1; idx <= 7; ++idx) {
+ ++scene->_textIndex;
+ scene->_yp += scene->_fontHeight;
+ scene->handleText();
+ }
+
+ setDelay(480);
+ break;
+
+ case 11:
+ scene->_textIndex = 1;
+ scene->_yp = 100 - ((scene->_fontHeight * 3) / 2);
+ scene->handleText();
+
+ for (int idx = 1; idx <= 2; ++idx) {
+ ++scene->_textIndex;
+ scene->_yp += scene->_fontHeight;
+ scene->handleText();
+ }
+
+ setDelay(240);
+ break;
+
+ case 13:
+ scene->_textIndex = 1;
+ scene->_yp = 100 - ((scene->_fontHeight * 3) / 2);
+ scene->handleText();
+
+ for (int idx = 1; idx <= 2; ++idx) {
+ ++scene->_textIndex;
+ scene->_yp += scene->_fontHeight;
+ scene->handleText();
+ }
+
+ setDelay(240);
+ break;
+
+ case 15:
+ scene->_textIndex = 1;
+ scene->_yp = 100 - ((scene->_fontHeight * 5) / 2);
+ scene->handleText();
+
+ for (int idx = 1; idx <= 4; ++idx) {
+ ++scene->_textIndex;
+ scene->_yp += scene->_fontHeight;
+ scene->handleText();
+ }
+
+ setDelay(240);
+ break;
+
+ case 17:
+ scene->_textIndex = 1;
+ scene->_yp = 100 - ((scene->_fontHeight * 5) / 2);
+ scene->handleText();
+
+ for (int idx = 1; idx <= 4; ++idx) {
+ ++scene->_textIndex;
+ scene->_yp += scene->_fontHeight;
+ scene->handleText();
+ }
+
+ setDelay(360);
+ break;
+
+ case 19:
+ scene->_textIndex = 1;
+ scene->_yp = 100 - ((scene->_fontHeight * 3) / 2);
+ scene->handleText();
+
+ for (int idx = 1; idx <= 2; ++idx) {
+ ++scene->_textIndex;
+ scene->_yp += scene->_fontHeight;
+ scene->handleText();
+ }
+
+ setDelay(480);
+ break;
+
+ case 21:
+ R2_GLOBALS._sceneManager.changeScene(R2_GLOBALS._sceneManager._previousScene);
+
+ default:
+ break;
+ }
+}
+
+void Scene205::Action1::textLoop() {
+ Scene205 *scene = (Scene205 *)R2_GLOBALS._sceneManager._scene;
+
+ for (int idx = 1; idx <= 14; ++idx) {
+ if (R2_GLOBALS._sceneObjects->contains(&scene->_textList[idx])) {
+ scene->_textList[idx].remove();
+ }
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+
+Scene205::Object::Object(): SceneObject() {
+ _x100 = _y100 = 0;
+}
+
+void Scene205::Object::synchronize(Serializer &s) {
+ EventHandler::synchronize(s);
+
+ s.syncAsSint32LE(_x100);
+ s.syncAsSint32LE(_y100);
+}
+
+/*--------------------------------------------------------------------------*/
+
+Scene205::Scene205(): SceneExt() {
+ _yp = 0;
+ _textIndex = 1;
+ _lineNum = -1;
+
+ GfxFont font;
+ font.setFontNumber(4);
+ _fontHeight = font.getHeight();
+}
+
+void Scene205::postInit(SceneObjectList *OwnerList) {
+ SceneExt::postInit();
+ loadScene(4000);
+ R2_GLOBALS._player._uiEnabled = false;
+
+ R2_GLOBALS._sound1.play(337);
+ R2_GLOBALS._scenePalette.loadPalette(0);
+ R2_GLOBALS._player.disableControl();
+
+ setup();
+ setAction(&_action1);
+}
+
+void Scene205::synchronize(Serializer &s) {
+ SceneExt::synchronize(s);
+
+ for (int idx = 0; idx < 3; ++idx)
+ SYNC_POINTER(_objList1[idx]);
+ for (int idx = 0; idx < 3; ++idx)
+ SYNC_POINTER(_objList2[idx]);
+ for (int idx = 0; idx < 4; ++idx)
+ SYNC_POINTER(_objList3[idx]);
+
+ s.syncAsSint16LE(_textIndex);
+ s.syncAsSint16LE(_lineNum);
+ s.syncAsSint16BE(_yp);
+}
+
+void Scene205::remove() {
+ R2_GLOBALS._sound1.fadeOut2(NULL);
+ SceneExt::remove();
+}
+
+void Scene205::process(Event &event) {
+ if ((event.eventType == EVENT_KEYPRESS) && (event.kbd.keycode == Common::KEYCODE_ESCAPE)) {
+ event.handled = true;
+ R2_GLOBALS._sceneManager.changeScene(R2_GLOBALS._sceneManager._previousScene);
+ } else {
+ Scene::process(event);
+ }
+}
+
+void Scene205::dispatch() {
+ processList(_objList3, 4, Common::Rect(0, 0, 319, 200), 1, 1, 160, 100);
+ processList(_objList2, 3, Common::Rect(0, 0, 319, 200), 2, 2, 160, 100);
+ processList(_objList1, 3, Common::Rect(0, 0, 319, 200), 4, 3, 160, 100);
+
+ Scene::dispatch();
+}
+
+void Scene205::setup() {
+ const Common::Point pointList1[3] = { Common::Point(2, 50), Common::Point(100, 28), Common::Point(53, 15) };
+ const Common::Point pointList2[3] = { Common::Point(289, 192), Common::Point(125, 60), Common::Point(130, 40) };
+ const Common::Point pointList3[4] = {
+ Common::Point(140, 149), Common::Point(91, 166), Common::Point(299, 46), Common::Point(314, 10)
+ };
+
+ // Set up the first object list
+ for (int idx = 0; idx < 3; ++idx) {
+ Object *obj = new Object();
+ _objList1[idx] = obj;
+
+ obj->postInit();
+ obj->_flags |= OBJFLAG_CLONED;
+ obj->setVisage(205);
+ obj->_strip = 1;
+ obj->_frame = 1;
+ obj->setPosition(pointList1[idx]);
+ obj->_x100 = obj->_position.x * 100;
+ obj->_y100 = obj->_position.y * 100;
+ obj->fixPriority(12);
+ }
+
+ // Setup the second object list
+ for (int idx = 0; idx < 3; ++idx) {
+ Object *obj = new Object();
+ _objList2[idx] = obj;
+
+ obj->postInit();
+ obj->_flags |= OBJFLAG_CLONED;
+ obj->setVisage(205);
+ obj->_strip = 1;
+ obj->_frame = 2;
+ obj->setPosition(pointList2[idx]);
+ obj->_x100 = obj->_position.x * 100;
+ obj->_y100 = obj->_position.y * 100;
+ obj->fixPriority(11);
+ }
+
+ // Setup the third object list
+ for (int idx = 0; idx < 4; ++idx) {
+ Object *obj = new Object();
+ _objList3[idx] = obj;
+
+ obj->postInit();
+ obj->_flags |= OBJFLAG_CLONED;
+ obj->setVisage(205);
+ obj->_strip = 1;
+ obj->_frame = 3;
+ obj->setPosition(pointList3[idx]);
+ obj->_x100 = obj->_position.x * 100;
+ obj->_y100 = obj->_position.y * 100;
+ obj->fixPriority(10);
+ }
+}
+
+/**
+ * Handles moving a group of stars in the scene background
+ */
+void Scene205::processList(Object **ObjList, int count, const Common::Rect &bounds,
+ int xMultiply, int yMultiply, int xCenter, int yCenter) {
+ for (int idx = 0; idx < count; ++idx) {
+ Object *obj = ObjList[idx];
+ Common::Point pt(obj->_position.x - xCenter, obj->_position.y - yCenter);
+
+ if ((obj->_position.x <= 319) && (obj->_position.x >= 0) &&
+ (obj->_position.y <= 199) && (obj->_position.y >= 0)) {
+ if (!pt.x && !pt.y) {
+ pt.x = pt.y = 1;
+ }
+
+ pt.x *= xMultiply;
+ pt.y *= yMultiply;
+ obj->_x100 += pt.x;
+ obj->_y100 += pt.y;
+ } else {
+ obj->_x100 = (bounds.left + R2_GLOBALS._randomSource.getRandomNumber(bounds.right)) * 100;
+ obj->_y100 = (bounds.top + R2_GLOBALS._randomSource.getRandomNumber(bounds.bottom)) * 100;
+ }
+
+ obj->setPosition(Common::Point(obj->_x100 / 100, obj->_y100 / 100));
+ }
+}
+
+void Scene205::handleText() {
+ _message = g_resourceManager->getMessage(205, ++_lineNum);
+
+ _textList[_textIndex]._fontNumber = 4;
+ _textList[_textIndex]._color1 = 0;
+ _textList[_textIndex]._color2 = 10;
+ _textList[_textIndex]._color3 = 7;
+ _textList[_textIndex]._width = 400;
+ _textList[_textIndex].setup(_message);
+ _textList[_textIndex].fixPriority(199);
+
+ GfxFont font;
+ font.setFontNumber(4);
+ int width = font.getStringWidth(_message.c_str());
+
+ _textList[_textIndex].setPosition(Common::Point(160 - (width / 2), _yp));
+}
+
+/*--------------------------------------------------------------------------
+ * Scene 250 - Lift
+ *
+ *--------------------------------------------------------------------------*/
+
+Scene250::Button::Button(): SceneActor() {
+ _floorNumber = _v2 = 0;
+}
+
+void Scene250::Button::synchronize(Serializer &s) {
+ SceneActor::synchronize(s);
+
+ s.syncAsSint16LE(_floorNumber);
+ s.syncAsSint16LE(_v2);
+}
+
+bool Scene250::Button::startAction(CursorType action, Event &event) {
+ Scene250 *scene = (Scene250 *)R2_GLOBALS._sceneManager._scene;
+
+ switch (action) {
+ case CURSOR_USE:
+ if (scene->_field414) {
+ SceneItem::display2(250, 15);
+ } else {
+ switch (_floorNumber) {
+ case 1:
+ case 2:
+ case 5:
+ case 9:
+ scene->_sound1.play(14);
+ scene->changeFloor(_floorNumber);
+ break;
+ case 10:
+ // Current Floor
+ scene->_sound1.play(14);
+ R2_GLOBALS._sceneManager.changeScene(R2_GLOBALS._sceneManager._previousScene);
+ break;
+ default:
+ SceneItem::display2(250, 16);
+ break;
+ }
+ }
+ return true;
+
+ case CURSOR_LOOK:
+ switch (_floorNumber) {
+ case 1:
+ case 2:
+ case 5:
+ case 9:
+ SceneItem::display2(250, 12);
+ break;
+ case 10:
+ SceneItem::display2(250, 13);
+ break;
+ case 11:
+ SceneItem::display2(250, 14);
+ break;
+ default:
+ SceneItem::display2(250, 16);
+ break;
+ }
+ return true;
+
+ default:
+ return SceneActor::startAction(action, event);
+ }
+}
+
+void Scene250::Button::setFloor(int floorNumber) {
+ SceneActor::postInit();
+ _floorNumber = floorNumber;
+ _v2 = 0;
+
+ if (_floorNumber <= 9) {
+ SceneObject::setup(250, 1, 4);
+
+ switch (_floorNumber) {
+ case 1:
+ case 2:
+ case 5:
+ case 9:
+ setFrame(6);
+ break;
+ default:
+ break;
+ }
+
+ setPosition(Common::Point(111, (_floorNumber - 1) * 12 + 43));
+ fixPriority(10);
+ setDetails(250, -1, -1, -1, 1, (SceneItem *)NULL);
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+
+Scene250::Scene250(): SceneExt() {
+ _field412 = _field414 = _field416 = _field418 = _field41A = 0;
+}
+
+void Scene250::synchronize(Serializer &s) {
+ SceneExt::synchronize(s);
+
+ s.syncAsSint16LE(_field412);
+ s.syncAsSint16LE(_field414);
+ s.syncAsSint16LE(_field416);
+ s.syncAsSint16LE(_field418);
+ s.syncAsSint16LE(_field41A);
+}
+
+void Scene250::postInit(SceneObjectList *OwnerList) {
+ SceneExt::postInit();
+ loadScene(250);
+
+ R2_GLOBALS._player.postInit();
+ R2_GLOBALS._player.setVisage(10);
+ R2_GLOBALS._player.hide();
+ R2_GLOBALS._player.enableControl();
+ R2_GLOBALS._player._canWalk = false;
+
+ _currentFloor.setFloor(10);
+ _currentFloor.setup(250, 1, 5);
+ _currentFloor.setDetails(250, 13, -1, -1, 1, (SceneItem *)NULL);
+
+ _button1.setFloor(11);
+ _button1.setup(250, 1, 3);
+ _button1.setPosition(Common::Point(400, 100));
+ _button1.setDetails(250, 14, -1, -1, 1, (SceneItem *)NULL);
+ _button1.fixPriority(190);
+ _button1.hide();
+
+ _floor1.setFloor(1);
+ _floor2.setFloor(2);
+ _floor3.setFloor(3);
+ _floor4.setFloor(4);
+ _floor5.setFloor(5);
+ _floor6.setFloor(6);
+ _floor7.setFloor(7);
+ _floor8.setFloor(8);
+ _floor9.setFloor(9);
+
+ _item2.setDetails(Rect(0, 0, 73, SCREEN_HEIGHT), 250, 9, -1, 9, 1, NULL);
+ _item4.setDetails(Rect(239, 16, 283, 164), 250, 6, -1, -1, 1, NULL);
+ _background.setDetails(Rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT), 250, 0, 1, -1, 1, NULL);
+
+ R2_GLOBALS._events.setCursor(CURSOR_USE);
+
+ switch (R2_GLOBALS._sceneManager._previousScene) {
+ case 200:
+ _field412 = 55;
+ break;
+ case 300:
+ _field412 = 43;
+ break;
+ case 700:
+ _field412 = 139;
+ break;
+ case 850:
+ _field412 = 91;
+ break;
+ default:
+ R2_GLOBALS._sceneManager._previousScene = 200;
+ _field412 = 55;
+ break;
+ }
+
+ _currentFloor.setPosition(Common::Point(111, _field412));
+}
+
+void Scene250::signal() {
+ if (_field41A)
+ _sceneMode = 20;
+
+ switch (_sceneMode) {
+ case 1:
+ _sound1.play(22);
+ R2_GLOBALS._player.show();
+ R2_GLOBALS._player.setup(250, 1, 2);
+ R2_GLOBALS._player.setPosition(Common::Point(261, 185));
+ ADD_MOVER(R2_GLOBALS._player, 261, 15);
+
+ _field416 = 0;
+ _sceneMode = 2;
+ break;
+ case 2:
+ _sceneMode = ((_field414 - 12) == _field412) ? 4 : 3;
+ signal();
+ break;
+ case 3:
+ _currentFloor.setPosition(Common::Point(111, _currentFloor._position.y + 12));
+ _field412 += 12;
+ R2_GLOBALS._player.setPosition(Common::Point(261, 185));
+ ADD_MOVER(R2_GLOBALS._player, 261, 15);
+
+ if ((_field414 - 12) == _field412)
+ _sceneMode = 4;
+ break;
+ case 4:
+ _sound1.play(21);
+
+ _currentFloor.setPosition(Common::Point(111, _currentFloor._position.y + 12));
+ R2_GLOBALS._player.setPosition(Common::Point(261, 185));
+ ADD_MOVER(R2_GLOBALS._player, 261, 15);
+ _sceneMode = 5;
+ break;
+ case 5:
+ R2_GLOBALS._player.disableControl();
+ _sceneMode = 20;
+ signal();
+ break;
+ case 6:
+ _sound1.play(22);
+ R2_GLOBALS._player.show();
+ R2_GLOBALS._player.setup(250, 1, 2);
+ R2_GLOBALS._player.setPosition(Common::Point(261, 15));
+ ADD_MOVER(R2_GLOBALS._player, 261, 185);
+ _field416 = 0;
+ _sceneMode = 7;
+ break;
+ case 7:
+ _field418 = 1;
+ if ((_field414 + 12) == _field412)
+ _sceneMode = 8;
+ signal();
+ break;
+ case 8:
+ _currentFloor.setPosition(Common::Point(111, _currentFloor._position.y - 12));
+ _field412 -= 12;
+ R2_GLOBALS._player.setPosition(Common::Point(261, 15));
+ ADD_MOVER(R2_GLOBALS._player, 261, 185);
+
+ if ((_field414 + 12) == _field412)
+ _sceneMode = 9;
+ break;
+ case 9:
+ _sound1.play(21);
+ _currentFloor.setPosition(Common::Point(111, _currentFloor._position.y - 12));
+ R2_GLOBALS._player.setPosition(Common::Point(261, 15));
+ ADD_MOVER(R2_GLOBALS._player, 261, 185);
+ _sceneMode = 10;
+ break;
+ case 10:
+ _sceneMode = 20;
+ signal();
+ break;
+ case 20:
+ // Handle changing scene
+ switch (_field414) {
+ case 55:
+ R2_GLOBALS._sceneManager.changeScene(200);
+ break;
+ case 43:
+ R2_GLOBALS._sceneManager.changeScene(300);
+ break;
+ case 139:
+ R2_GLOBALS._sceneManager.changeScene(139);
+ break;
+ case 91:
+ R2_GLOBALS._sceneManager.changeScene(850);
+ break;
+ default:
+ break;
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+void Scene250::changeFloor(int floorNumber) {
+ _field414 = (floorNumber - 1) * 12 + 43;
+ _button1.setPosition(Common::Point(111, _field414));
+ _button1.show();
+
+ _sceneMode = (_field412 >= _field414) ? 6 : 1;
+ if (_field414 == _field412)
+ _sceneMode = 20;
+
+ signal();
+}
+
+void Scene250::process(Event &event) {
+ if (!event.handled) {
+ if (((event.eventType == EVENT_KEYPRESS) || (event.btnState != 0)) && _field418) {
+ _field41A = 1;
+ event.handled = true;
+ }
+
+ SceneExt::process(event);
+ }
+}
+
+void Scene250::dispatch() {
+ SceneExt::dispatch();
+
+ if (((_sceneMode == 2) || (_sceneMode == 7)) && (_field416 < 100)) {
+ ++_field416;
+ R2_GLOBALS._player._moveDiff.y = _field416 / 5;
+ }
+
+ if (((_sceneMode == 5) || (_sceneMode == 10)) && (R2_GLOBALS._player._moveDiff.y > 4)) {
+ --_field416;
+ R2_GLOBALS._player._moveDiff.y = _field416 / 7 + 3;
+ }
+}
+
+/*--------------------------------------------------------------------------
+ * Scene 300 - Bridge
+ *
+ *--------------------------------------------------------------------------*/
+
+void Scene300::Action1::signal() {
+ Scene300 *scene = (Scene300 *)R2_GLOBALS._sceneManager._scene;
+
+ switch (_actionIndex) {
+ case 0:
+ setAction(&scene->_sequenceManager2, this, 311, (R2_GLOBALS._player._characterIndex == 1) ?
+ (SceneObject *)&R2_GLOBALS._player : (SceneObject *)&scene->_quinn);
+ _actionIndex = 2;
+ break;
+ case 1:
+ setAction(&scene->_sequenceManager2, this, 312, (R2_GLOBALS._player._characterIndex == 1) ?
+ (SceneObject *)&R2_GLOBALS._player : (SceneObject *)&scene->_quinn);
+ _actionIndex = 0;
+ break;
+ case 2:
+ if (!R2_GLOBALS._playStream.isPlaying())
+ _actionIndex = R2_GLOBALS._randomSource.getRandomNumber(1);
+ break;
+ default:
+ break;
+ }
+}
+
+void Scene300::Action2::signal() {
+ Scene300 *scene = (Scene300 *)R2_GLOBALS._sceneManager._scene;
+
+ switch (_actionIndex) {
+ case 0:
+ setAction(&scene->_sequenceManager3, this, 302, &scene->_seeker, NULL);
+ _actionIndex = 2;
+ break;
+ case 1:
+ setAction(&scene->_sequenceManager3, this, 303, &scene->_seeker, NULL);
+ _actionIndex = 2;
+ break;
+ case 2:
+ if (!R2_GLOBALS._playStream.isPlaying())
+ _actionIndex = R2_GLOBALS._randomSource.getRandomNumber(1);
+
+ setDelay(60 + R2_GLOBALS._randomSource.getRandomNumber(119));
+ break;
+ default:
+ break;
+ }
+}
+
+void Scene300::Action3::signal() {
+ Scene300 *scene = (Scene300 *)R2_GLOBALS._sceneManager._scene;
+
+ switch (_actionIndex) {
+ case 0:
+ setAction(&scene->_sequenceManager3, this, 304, &scene->_miranda, NULL);
+ _actionIndex = 2;
+ break;
+ case 1:
+ setAction(&scene->_sequenceManager3, this, 305, &scene->_miranda, NULL);
+ _actionIndex = 2;
+ break;
+ case 2:
+ if (!R2_GLOBALS._playStream.isPlaying())
+ _actionIndex = R2_GLOBALS._randomSource.getRandomNumber(1);
+
+ setDelay(60 + R2_GLOBALS._randomSource.getRandomNumber(119));
+ break;
+ default:
+ break;
+ }
+}
+
+
+void Scene300::Action4::signal() {
+ Scene300 *scene = (Scene300 *)R2_GLOBALS._sceneManager._scene;
+
+ if (!R2_GLOBALS._playStream.isPlaying()) {
+ scene->_object7.setStrip2(R2_GLOBALS._randomSource.getRandomNumber(2));
+ scene->_object7.setFrame(1);
+
+ scene->_object9.setStrip2(3);
+ scene->_object9.setFrame(1);
+ }
+
+ setDelay(60 + R2_GLOBALS._randomSource.getRandomNumber(479));
+}
+
+/*--------------------------------------------------------------------------*/
+
+bool Scene300::QuinnWorkstation::startAction(CursorType action, Event &event) {
+ Scene300 *scene = (Scene300 *)R2_GLOBALS._sceneManager._scene;
+
+ switch (action) {
+ case CURSOR_USE:
+ if (R2_GLOBALS._player._characterIndex != 1)
+ SceneItem::display2(300, 46);
+ else if (R2_GLOBALS.getFlag(44)) {
+ R2_GLOBALS._player.setAction(NULL);
+ R2_GLOBALS._sceneManager.changeScene(325);
+ } else {
+ R2_GLOBALS._player.disableControl();
+ scene->_sceneMode = 306;
+ scene->setAction(&scene->_sequenceManager1, scene, 306, &R2_GLOBALS._player, NULL);
+ }
+ return true;
+
+ case CURSOR_LOOK:
+ if (R2_GLOBALS._player._characterIndex == 1) {
+ SceneItem::display2(300, 47);
+ return true;
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ return NamedHotspot::startAction(action, event);
+}
+
+bool Scene300::MirandaWorkstation::startAction(CursorType action, Event &event) {
+ switch (action) {
+ case CURSOR_USE:
+ if (R2_GLOBALS._player._characterIndex != 3)
+ SceneItem::display2(300, 49);
+ else
+ R2_GLOBALS._sceneManager.changeScene(325);
+ return true;
+
+ case CURSOR_LOOK:
+ if (R2_GLOBALS._player._characterIndex == 3) {
+ SceneItem::display2(300, 47);
+ return true;
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ return NamedHotspot::startAction(action, event);
+}
+
+bool Scene300::SeekerWorkstation::startAction(CursorType action, Event &event) {
+ switch (action) {
+ case CURSOR_LOOK:
+ if (R2_GLOBALS._player._characterIndex == 2) {
+ SceneItem::display2(300, 47);
+ return true;
+ }
+ break;
+
+ case CURSOR_USE:
+ if (R2_GLOBALS._player._characterIndex != 2)
+ SceneItem::display2(300, 48);
+ else
+ R2_GLOBALS._sceneManager.changeScene(325);
+ return true;
+
+ default:
+ break;
+ }
+
+ return NamedHotspot::startAction(action, event);
+}
+
+/*--------------------------------------------------------------------------*/
+
+bool Scene300::Miranda::startAction(CursorType action, Event &event) {
+ Scene300 *scene = (Scene300 *)R2_GLOBALS._sceneManager._scene;
+
+ switch (action) {
+ case CURSOR_TALK:
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
+ // Quinn talking to Miranda
+ R2_GLOBALS._player.disableControl();
+
+ if (!R2_GLOBALS.getFlag(44)) {
+ if (R2_GLOBALS.getFlag(40))
+ scene->_stripId = 119;
+ else if (R2_GLOBALS.getFlag(38))
+ scene->_stripId = 101;
+ else {
+ R2_GLOBALS._sound1.play(69);
+ scene->_stripId = 100;
+ }
+
+ scene->_sceneMode = 309;
+ scene->setAction(&scene->_sequenceManager1, scene, 309, &R2_GLOBALS._player, NULL);
+ } else if (!R2_GLOBALS.getFlag(55)) {
+ R2_GLOBALS._events.setCursor(CURSOR_ARROW);
+ scene->_sceneMode = 10;
+ scene->_stripManager.start3(scene->_stripId, scene, R2_GLOBALS._stripManager_lookupList);
+ } else {
+ scene->_sceneMode = 16;
+
+ if (!R2_GLOBALS.getFlag(57)) {
+ R2_GLOBALS._events.setCursor(CURSOR_ARROW);
+ scene->_stripManager.start3(434, scene, R2_GLOBALS._stripManager_lookupList);
+ } else if (R2_GLOBALS._player._characterScene[R2_MIRANDA] != 500) {
+ R2_GLOBALS._events.setCursor(CURSOR_ARROW);
+ scene->_stripManager.start3(407, scene, R2_GLOBALS._stripManager_lookupList);
+ } else {
+ scene->_stripId = 433;
+ scene->_sceneMode = 309;
+ scene->setAction(&scene->_sequenceManager1, scene, 309, &R2_GLOBALS._player, NULL);
+ }
+ }
+ } else {
+ // Seeker talking to Miranda
+ scene->_sceneMode = 10;
+ R2_GLOBALS._events.setCursor(CURSOR_ARROW);
+
+ if (!R2_GLOBALS.getFlag(44))
+ scene->_stripId = 174 + R2_GLOBALS._randomSource.getRandomNumber(2);
+ else if (!R2_GLOBALS.getFlag(55))
+ scene->_stripId = 211;
+ else
+ scene->_stripId = 438;
+
+ scene->_stripManager.start3(scene->_stripId, scene, R2_GLOBALS._stripManager_lookupList);
+ }
+ return true;
+
+ case R2_OPTO_DISK:
+ SceneItem::display2(300, 54);
+ return true;
+
+ case R2_READER:
+ if (!R2_GLOBALS.getFlag(2) || !R2_GLOBALS.getFlag(3) || (R2_INVENTORY.getObjectScene(R2_OPTO_DISK) == 1))
+ SceneItem::display2(300, 55);
+ else {
+ R2_GLOBALS._player.disableControl();
+ scene->_stripId = R2_GLOBALS.getFlag(4) ? 121 : 120;
+ scene->_sceneMode = 309;
+ scene->setAction(&scene->_sequenceManager1, scene, 309, &R2_GLOBALS._player, NULL);
+ }
+ return true;
+
+ default:
+ break;
+ }
+
+ return SceneActor::startAction(action, event);
+}
+
+bool Scene300::Seeker::startAction(CursorType action, Event &event) {
+ Scene300 *scene = (Scene300 *)R2_GLOBALS._sceneManager._scene;
+
+ switch (action) {
+ case CURSOR_TALK:
+ R2_GLOBALS._player.disableControl();
+
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
+ if (R2_GLOBALS.getFlag(44)) {
+ if (!R2_GLOBALS.getFlag(38)) {
+ R2_GLOBALS._sound1.play(69);
+ scene->_stripId = 181;
+ scene->_sceneMode = 310;
+ scene->setAction(&scene->_sequenceManager1, scene, 309, &R2_GLOBALS._player, NULL);
+ } else {
+ scene->_stripId = R2_GLOBALS.getFlag(40) ? 170 : 150;
+ scene->_sceneMode = 310;
+ scene->setAction(&scene->_sequenceManager1, scene, 309, &R2_GLOBALS._player, NULL);
+ }
+ } else {
+ R2_GLOBALS._events.setCursor(CURSOR_ARROW);
+ if (!R2_GLOBALS.getFlag(55)) {
+ scene->_sceneMode = 10;
+ scene->_stripManager.start3(205, scene, R2_GLOBALS._stripManager_lookupList);
+ } else {
+ scene->_sceneMode = 16;
+ scene->_stripManager.start3(R2_GLOBALS.getFlag(57) ? 407 : 401, scene, R2_GLOBALS._stripManager_lookupList);
+ }
+ }
+ } else {
+ scene->_sceneMode = 10;
+ R2_GLOBALS._events.setCursor(CURSOR_ARROW);
+
+ if (!R2_GLOBALS.getFlag(44))
+ scene->_stripId = 122 + R2_GLOBALS._randomSource.getRandomNumber(2);
+ else if (!R2_GLOBALS.getFlag(55))
+ scene->_stripId = 209;
+ else
+ scene->_stripId = 440;
+
+ scene->_stripManager.start3(scene->_stripId, scene, R2_GLOBALS._stripManager_lookupList);
+ }
+ return true;
+
+ case R2_OPTO_DISK:
+ if (R2_GLOBALS.getFlag(13)) {
+ SceneItem::display2(300, 53);
+ } else {
+ R2_GLOBALS._player.disableControl();
+ scene->_stripId = 171;
+ }
+
+ scene->_sceneMode = 310;
+ scene->setAction(&scene->_sequenceManager1, scene, 310, &R2_GLOBALS._player, NULL);
+ return true;
+
+ case R2_READER:
+ if (!R2_GLOBALS.getFlag(2) || !R2_GLOBALS.getFlag(3) || (R2_INVENTORY.getObjectScene(R2_OPTO_DISK) == 1))
+ break;
+
+ R2_GLOBALS._player.disableControl();
+ scene->_stripId = R2_GLOBALS.getFlag(4) ? 173 : 172;
+ scene->_sceneMode = 310;
+ scene->setAction(&scene->_sequenceManager1, scene, 310, &R2_GLOBALS._player, NULL);
+ return true;
+
+ default:
+ break;
+ }
+
+ return SceneActor::startAction(action, event);
+}
+
+bool Scene300::Quinn::startAction(CursorType action, Event &event) {
+ Scene300 *scene = (Scene300 *)R2_GLOBALS._sceneManager._scene;
+
+ switch (action) {
+ case CURSOR_TALK:
+ R2_GLOBALS._player.disableControl();
+ R2_GLOBALS._events.setCursor(CURSOR_ARROW);
+ scene->_sceneMode = 10;
+
+ if (R2_GLOBALS._player._characterIndex == R2_MIRANDA) {
+ if (R2_GLOBALS._player._characterScene[R2_MIRANDA] == 500)
+ scene->_stripId = 442;
+ else if (!R2_GLOBALS.getFlag(44))
+ scene->_stripId = 177 + R2_GLOBALS._randomSource.getRandomNumber(2);
+ else if (!R2_GLOBALS.getFlag(55))
+ scene->_stripId = 208;
+ else
+ scene->_stripId = 441;
+ } else if (R2_GLOBALS._player._characterScene[R2_MIRANDA] == 500) {
+ scene->_stripId = 442;
+ } else if (R2_GLOBALS.getFlag(44)) {
+ scene->_stripId = R2_GLOBALS.getFlag(55) ? 441 : 208;
+ } else {
+ scene->_stripId = 125 + R2_GLOBALS._randomSource.getRandomNumber(2);
+ }
+
+ scene->_stripManager.start3(scene->_stripId, scene, R2_GLOBALS._stripManager_lookupList);
+ return true;
+
+ default:
+ return SceneActor::startAction(action, event);
+ }
+}
+
+bool Scene300::Doorway::startAction(CursorType action, Event &event) {
+ Scene300 *scene = (Scene300 *)R2_GLOBALS._sceneManager._scene;
+
+ if (action == CURSOR_USE) {
+ if ((R2_GLOBALS._player._characterIndex == R2_QUINN) &&
+ (!R2_GLOBALS.getFlag(44) || R2_GLOBALS._player._characterScene[R2_MIRANDA] == 500)) {
+ R2_GLOBALS._player.disableControl();
+ scene->_sceneMode = 301;
+ scene->setAction(&scene->_sequenceManager1, scene, 301, &R2_GLOBALS._player, this, NULL);
+ } else {
+ SceneItem::display2(300, 45);
+ }
+
+ return true;
+ } else {
+ return SceneActor::startAction(action, event);
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+
+Scene300::Scene300(): SceneExt() {
+ _stripId = 0;
+ _rotation = NULL;
+}
+
+void Scene300::synchronize(Serializer &s) {
+ SceneExt::synchronize(s);
+
+ s.syncAsSint16LE(_stripId);
+ SYNC_POINTER(_rotation);
+}
+
+void Scene300::postInit(SceneObjectList *OwnerList) {
+ SceneExt::postInit();
+ loadScene(300);
+ _sound1.play(23);
+ setZoomPercents(75, 93, 120, 100);
+
+ if (R2_GLOBALS._sceneManager._previousScene == -1) {
+ R2_GLOBALS._sceneManager._previousScene = 1000;
+ R2_GLOBALS._player._characterIndex = R2_QUINN;
+ }
+
+ _stripManager.setColors(60, 255);
+ _stripManager.setFontNumber(3);
+ _stripManager.addSpeaker(&_mirandaSpeaker);
+ _stripManager.addSpeaker(&_seekerSpeaker);
+ _stripManager.addSpeaker(&_quinnSpeaker);
+ _stripManager.addSpeaker(&_quinnLSpeaker);
+ _stripManager.addSpeaker(&_seekerLSpeaker);
+ _stripManager.addSpeaker(&_tealSpeaker);
+ _stripManager.addSpeaker(&_soldierSpeaker);
+
+ _rotation = R2_GLOBALS._scenePalette.addRotation(237, 254, -1);
+ _rotation->setDelay(3);
+ _rotation->_countdown = 1;
+
+ if (R2_GLOBALS.getFlag(51) && !R2_GLOBALS.getFlag(25)) {
+ _object1.postInit();
+ _object1.setup(301, 7, 2);
+ _object1.setPosition(Common::Point(65, 24));
+
+ _object2.postInit();
+ _object2.setup(301, 8, 2);
+ _object2.setPosition(Common::Point(254, 24));
+ }
+
+ _doorway.postInit();
+ _doorway.setVisage(300);
+ _doorway.setPosition(Common::Point(159, 79));
+
+ _object3.postInit();
+ _object3.setup(300, 4, 1);
+ _object3.setPosition(Common::Point(84, 48));
+ _object3.animate(ANIM_MODE_2, NULL);
+ _object3._numFrames = 5;
+
+ _object4.postInit();
+ _object4.setup(300, 5, 1);
+ _object4.setPosition(Common::Point(236, 48));
+ _object4.animate(ANIM_MODE_2, NULL);
+
+ _protocolDisplay.postInit();
+ _protocolDisplay.setup(300, 6, 1);
+ _protocolDisplay.setPosition(Common::Point(287, 71));
+ _protocolDisplay.animate(ANIM_MODE_7, NULL);
+ _protocolDisplay._numFrames = 5;
+
+ _object6.postInit();
+ _object6.setup(300, 7, 1);
+ _object6.setPosition(Common::Point(214, 37));
+ _object6.animate(ANIM_MODE_2, NULL);
+ _object6._numFrames = 3;
+
+ _object7.postInit();
+ _object7.setup(301, 1, 1);
+ _object7.setPosition(Common::Point(39, 97));
+ _object7.fixPriority(124);
+ _object7.animate(ANIM_MODE_2, NULL);
+ _object7._numFrames = 5;
+ _object7.setAction(&_action4);
+
+ _object8.postInit();
+ _object8.setup(300, 8, 1);
+ _object8.setPosition(Common::Point(105, 37));
+ _object8.animate(ANIM_MODE_2, NULL);
+ _object8._numFrames = 5;
+
+ _object9.postInit();
+ _object9.setup(301, 6, 1);
+ _object9.setPosition(Common::Point(274, 116));
+ _object9.fixPriority(143);
+ _object9.animate(ANIM_MODE_2, NULL);
+ _object9._numFrames = 5;
+
+ _quinnWorkstation1.setDetails(Rect(243, 148, 315, 167), 300, 30, 31, 32, 1, NULL);
+ _mirandaWorkstation1.setDetails(Rect(4, 128, 69, 167), 300, 33, 31, 35, 1, NULL);
+
+ switch (R2_GLOBALS._player._characterIndex) {
+ case 1:
+ _miranda.postInit();
+ _miranda.setup(302, 2, 1);
+ _miranda.setPosition(Common::Point(47, 128));
+ _miranda.setAction(&_action3);
+ _miranda.setDetails(300, 39, 40, 41, 1, (SceneItem *)NULL);
+
+ if ((R2_GLOBALS._player._characterScene[2] == 300) || (R2_GLOBALS._player._characterScene[2] == 325)) {
+ _seeker.postInit();
+ _seeker.setVisage(302);
+ _seeker.setPosition(Common::Point(158, 108));
+ _seeker.fixPriority(130);
+ _seeker.setAction(&_action2);
+ _seeker.setDetails(300, 42, 43, 44, 1, (SceneItem *)NULL);
+ }
+
+ R2_GLOBALS._player.postInit();
+ R2_GLOBALS._player.setVisage(10);
+ R2_GLOBALS._player.animate(ANIM_MODE_1, NULL);
+ R2_GLOBALS._player.disableControl();
+ break;
+
+ case 2:
+ _miranda.postInit();
+ _miranda.setup(302, 2, 1);
+ _miranda.setPosition(Common::Point(47, 128));
+ _miranda.setAction(&_action3);
+ _miranda.setDetails(300, 39, 40, 41, 1, (SceneItem *)NULL);
+
+ if ((R2_GLOBALS._player._characterScene[1] == 300) || (R2_GLOBALS._player._characterScene[1] == 325)) {
+ _quinn.postInit();
+ _quinn.setup(302, 3, 1);
+ _quinn.setPosition(Common::Point(271, 150));
+ _quinn.setAction(&_action1);
+ _quinn.setDetails(300, 50, 51, 52, 1, (SceneItem *)NULL);
+ }
+
+ R2_GLOBALS._player.postInit();
+ R2_GLOBALS._player.setup(302, 1, 3);
+ R2_GLOBALS._player.setPosition(Common::Point(158, 108));
+ R2_GLOBALS._player.fixPriority(130);
+ R2_GLOBALS._player.enableControl(CURSOR_USE);
+ break;
+
+ case 3:
+ if ((R2_GLOBALS._player._characterScene[2] == 300) || (R2_GLOBALS._player._characterScene[2] == 325)) {
+ _seeker.postInit();
+ _seeker.setVisage(302);
+ _seeker.setPosition(Common::Point(158, 108));
+ _seeker.fixPriority(130);
+ _seeker.setAction(&_action2);
+ _seeker.setDetails(300, 42, 43, 44, 1, (SceneItem *)NULL);
+ }
+
+ if ((R2_GLOBALS._player._characterScene[1] == 300) || (R2_GLOBALS._player._characterScene[1] == 325)) {
+ _quinn.postInit();
+ _quinn.setup(302, 3, 1);
+ _quinn.setPosition(Common::Point(271, 150));
+ _quinn.setAction(&_action1);
+ _quinn.setDetails(300, 50, 51, 52, 1, (SceneItem *)NULL);
+ }
+
+ R2_GLOBALS._player.postInit();
+ R2_GLOBALS._player.setup(302, 2, 1);
+ R2_GLOBALS._player.setPosition(Common::Point(47, 128));
+ R2_GLOBALS._player.enableControl(CURSOR_USE);
+ break;
+
+ default:
+ break;
+ }
+
+ _seekerWorkstation.setDetails(Rect(101, 95, 217, 143), 300, 36, 31, 35, 1, NULL);
+ _quinnWorkstation2.setDetails(Rect(224, 102, 315, 143), 300, 30, 31, 32, 1, NULL);
+ _mirandaWorkstation2.setDetails(Rect(4, 83, 84, 124), 300, 33, 31, 35, 1, NULL);
+ _hull.setDetails(11, 300, 6, -1, -1);
+ _statusDisplays.setDetails(12, 300, 9, 10, -1);
+ _damageControl.setDetails(13, 300, 12, -1, -1);
+ _manualOverrides.setDetails(14, 300, 15, -1, 17);
+ _scanners1.setDetails(Rect(126, 15, 183, 25), 300, 18, -1, 20, 1, NULL);
+ _scanners2.setDetails(Rect(126, 80, 183, 90), 300, 18, -1, 20, 1, NULL);
+ _protocolDisplay.setDetails(300, 27, -1, 29, 1, (SceneItem *)NULL);
+ _indirectLighting1.setDetails(Rect(74, 71, 122, 89), 300, 21, -1, -1, 1, NULL);
+ _indirectLighting2.setDetails(Rect(197, 71, 245, 89), 300, 21, -1, -1, 1, NULL);
+ _lighting.setDetails(Rect(129, 3, 190, 14), 300, 24, -1, -1, 1, NULL);
+ _doorway.setDetails(300, 3, -1, 5, 1, (SceneItem *)NULL);
+ _background.setDetails(Rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT), 300, 0, -1, -1, 1, NULL);
+
+ switch (R2_GLOBALS._player._characterIndex) {
+ case 1:
+ _sceneMode = 300;
+
+ switch (R2_GLOBALS._sceneManager._previousScene) {
+ case 250:
+ setAction(&_sequenceManager1, this, 300, &R2_GLOBALS._player, &_doorway, NULL);
+ break;
+ case 325:
+ if (!R2_GLOBALS.getFlag(44) || R2_GLOBALS.getFlag(25))
+ setAction(&_sequenceManager1, this, 309, &R2_GLOBALS._player, NULL);
+ else {
+ R2_GLOBALS.setFlag(60);
+ R2_GLOBALS._player.setup(302, 3, 1);
+ R2_GLOBALS._player.setPosition(Common::Point(271, 150));
+ R2_GLOBALS._player.setAction(&_action1);
+
+ if (R2_GLOBALS.getFlag(55)) {
+ if (R2_GLOBALS.getFlag(57)) {
+ R2_GLOBALS.clearFlag(60);
+ R2_GLOBALS._events.setCursor(CURSOR_ARROW);
+ _sceneMode = 16;
+ _stripManager.start(404, this);
+ } else {
+ R2_GLOBALS._player.enableControl();
+ R2_GLOBALS._player._canWalk = false;
+ }
+ } else {
+ if (R2_GLOBALS.getFlag(45)) {
+ R2_GLOBALS.clearFlag(60);
+ R2_GLOBALS._events.setCursor(CURSOR_ARROW);
+ _sceneMode = 12;
+ _stripManager.start3(204, this, R2_GLOBALS._stripManager_lookupList);
+ } else {
+ R2_GLOBALS._player.enableControl();
+ R2_GLOBALS._player._canWalk = false;
+ }
+ }
+ }
+ break;
+ case 1000:
+ R2_GLOBALS.setFlag(60);
+ R2_GLOBALS._player.setup(302, 3, 1);
+ R2_GLOBALS._player.setPosition(Common::Point(271, 150));
+ R2_GLOBALS._events.setCursor(CURSOR_ARROW);
+
+ if (R2_GLOBALS.getFlag(51)) {
+ _sceneMode = 13;
+ _stripManager.start3(300, this, R2_GLOBALS._stripManager_lookupList);
+ } else {
+ _sceneMode = 11;
+ _stripManager.start3(200, this, R2_GLOBALS._stripManager_lookupList);
+ }
+ break;
+
+ case 1100:
+ R2_GLOBALS._player.setVisage(10);
+ R2_GLOBALS._player.setPosition(Common::Point(160, 95));
+ _stripId = 400;
+ _sceneMode = 309;
+ setAction(&_sequenceManager1, this, 309, &R2_GLOBALS._player, NULL);
+ break;
+
+ case 1500:
+ R2_GLOBALS.clearFlag(60);
+ R2_GLOBALS._player.setup(302, 3, 1);
+ R2_GLOBALS._player.setPosition(Common::Point(271, 150));
+ _sceneMode = 17;
+ R2_GLOBALS._events.setCursor(CURSOR_ARROW);
+ _stripManager.start(413, this);
+ break;
+
+ default:
+ if (R2_GLOBALS.getFlag(60)) {
+ R2_GLOBALS._player.setup(302, 3, 1);
+ R2_GLOBALS._player.setPosition(Common::Point(271, 150));
+ R2_GLOBALS._player.setAction(&_action1);
+ R2_GLOBALS._player.enableControl(CURSOR_USE);
+ R2_GLOBALS._player._canWalk = false;
+ } else {
+ R2_GLOBALS._player.setStrip(3);
+ R2_GLOBALS._player.setPosition(Common::Point(200, 150));
+ R2_GLOBALS._player.enableControl();
+ }
+ break;
+ }
+ break;
+
+ case 3:
+ if (R2_GLOBALS._sceneManager._previousScene == 1500) {
+ R2_GLOBALS._player._oldCharacterScene[3] = 3150;
+ R2_GLOBALS._player._characterScene[3] = 3150;
+ R2_GLOBALS._player._effect = 0;
+ R2_GLOBALS._player.setAction(NULL);
+ R2_GLOBALS._player.disableControl();
+
+ _quinn.postInit();
+ _quinn.setVisage(10);
+ _quinn.setPosition(Common::Point(10, 10));
+ _quinn.hide();
+
+ _seeker.postInit();
+ _seeker.setVisage(20);
+ _seeker.setPosition(Common::Point(20, 20));
+ _seeker.hide();
+
+ _teal.postInit();
+ _soldier.postInit();
+ _object12.postInit();
+
+ R2_GLOBALS._sound1.play(107);
+ _sceneMode = 308;
+
+ setAction(&_sequenceManager1, this, 308, &R2_GLOBALS._player, &_teal, &_soldier, &_object12, &_doorway, NULL);
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+void Scene300::remove() {
+ R2_GLOBALS._player.setAction(NULL);
+ SceneExt::remove();
+}
+
+void Scene300::signal() {
+ switch (_sceneMode) {
+ case 10:
+ switch (_stripManager._field2E8) {
+ case 0:
+ R2_GLOBALS._sound1.changeSound(10);
+ R2_GLOBALS.setFlag(38);
+ break;
+ case 1:
+ R2_GLOBALS.setFlag(3);
+ break;
+ case 2:
+ R2_GLOBALS.setFlag(4);
+ break;
+ case 3:
+ R2_GLOBALS.setFlag(13);
+ if (R2_GLOBALS._stripManager_lookupList[1] == 6)
+ R2_GLOBALS.setFlag(40);
+ break;
+ case 4:
+ if (R2_GLOBALS._stripManager_lookupList[1] == 6)
+ R2_GLOBALS.setFlag(40);
+ break;
+ case 5:
+ R2_GLOBALS._sceneManager.changeScene(1000);
+ break;
+ default:
+ break;
+ }
+
+ _stripManager._field2E8 = 0;
+ switch (_stripId) {
+ case 400:
+ R2_GLOBALS._player.disableControl();
+ _sceneMode = 15;
+ setAction(&_sequenceManager1, this, 306, &R2_GLOBALS._player, NULL);
+ break;
+ case 181:
+ R2_GLOBALS._player.setStrip(6);
+ // Deliberate fall-through
+ default:
+ R2_GLOBALS._player.enableControl(CURSOR_TALK);
+
+ if ((R2_GLOBALS._player._characterIndex != 1) || R2_GLOBALS.getFlag(44))
+ R2_GLOBALS._player._canWalk = false;
+ break;
+ }
+ break;
+
+ case 11:
+ R2_GLOBALS.setFlag(44);
+ R2_GLOBALS._player.enableControl(CURSOR_USE);
+ break;
+
+ case 12:
+ R2_GLOBALS._player.setAction(NULL);
+ R2_GLOBALS._sceneManager.changeScene(1010);
+ break;
+
+ case 13:
+ R2_GLOBALS._player.disableControl();
+ _seeker.changeZoom(-1);
+ _sceneMode = 313;
+ _seeker.setAction(NULL);
+ setAction(&_sequenceManager1, this, 313, &R2_GLOBALS._player, &_seeker, NULL);
+ break;
+
+ case 14:
+ if (_seeker._action)
+ R2_GLOBALS._player.disableControl();
+ _sceneMode = 314;
+ break;
+
+ case 15:
+ R2_GLOBALS.setFlag(55);
+ R2_GLOBALS.setFlag(38);
+ R2_GLOBALS.setFlag(44);
+ R2_GLOBALS.setFlag(51);
+ R2_GLOBALS._events.setCursor(CURSOR_ARROW);
+ _sceneMode = 16;
+ _stripManager.start3(401, this, R2_GLOBALS._stripManager_lookupList);
+ break;
+
+ case 16:
+ if (_stripManager._field2E8 == 1) {
+ R2_GLOBALS._player.setAction(NULL);
+ R2_GLOBALS._sceneManager.changeScene(1000);
+ } else {
+ R2_GLOBALS._player.setAction(&_action1);
+ R2_GLOBALS._player.enableControl(CURSOR_TALK);
+ }
+ break;
+
+ case 17:
+ R2_GLOBALS._player.disableControl();
+ _sceneMode = 316;
+ _seeker.changeZoom(-1);
+ _seeker.setAction(&_sequenceManager3, this, 316, &_seeker, &_doorway, NULL);
+ R2_GLOBALS._player.setAction(&_sequenceManager1, NULL, 307, &R2_GLOBALS._player, NULL);
+ break;
+
+ case 18:
+ R2_GLOBALS._player.disableControl();
+ _sceneMode = 317;
+ setAction(&_sequenceManager1, this, 317, &_teal, &_doorway, NULL);
+ break;
+
+ case 19:
+ R2_GLOBALS._player.disableControl();
+ _sceneMode = 318;
+ setAction(&_sequenceManager1, this, 318, &R2_GLOBALS._player, &_teal, &_soldier, &_object12, NULL);
+ break;
+
+ case 20:
+ R2_GLOBALS._player._characterIndex = R2_QUINN;
+ R2_GLOBALS._sceneManager.changeScene(1500);
+ break;
+
+ case 300:
+ case 307:
+ R2_GLOBALS._player.enableControl();
+ break;
+
+ case 301:
+ R2_GLOBALS._sceneManager.changeScene(250);
+ break;
+
+ case 306:
+ R2_GLOBALS._sceneManager.changeScene(325);
+ break;
+
+ case 308:
+ _sceneMode = 18;
+ R2_GLOBALS._events.setCursor(CURSOR_ARROW);
+ _stripManager.start(418, this);
+ break;
+
+ case 310:
+ R2_GLOBALS._player.setStrip(5);
+ // Deliberate fall-through
+ case 309:
+ signal309();
+ R2_GLOBALS._events.setCursor(CURSOR_ARROW);
+ _sceneMode = 10;
+ _stripManager.start3(_stripId, this, R2_GLOBALS._stripManager_lookupList);
+ break;
+
+ case 313:
+ _sceneMode = 14;
+ R2_GLOBALS._player._effect = 0;
+ _seeker.setAction(&_sequenceManager3, this, 314, &_seeker, &_doorway, NULL);
+ R2_GLOBALS._events.setCursor(CURSOR_ARROW);
+ _stripManager.start(301, this);
+ break;
+
+ case 314:
+ R2_GLOBALS._player.disableControl();
+ _sceneMode = 315;
+ R2_GLOBALS._player._effect = 1;
+ setAction(&_sequenceManager1, this, 315, &R2_GLOBALS._player, &_doorway, NULL);
+ break;
+
+ case 315:
+ R2_GLOBALS._sceneManager.changeScene(1100);
+ break;
+
+ case 316:
+ R2_GLOBALS._player._characterScene[2] = 500;
+ _seeker.remove();
+ R2_GLOBALS._player.enableControl(CURSOR_CROSSHAIRS);
+ break;
+
+ case 317:
+ _sceneMode = 19;
+ R2_GLOBALS._events.setCursor(CURSOR_ARROW);
+ _stripManager.start(419, this);
+ break;
+
+ case 318:
+ _sceneMode = 20;
+ R2_GLOBALS._events.setCursor(CURSOR_ARROW);
+ _stripManager.start(420, this);
+ break;
+
+ default:
+ break;
+ }
+}
+
+void Scene300::signal309() {
+ if (R2_GLOBALS.getFlag(2))
+ R2_GLOBALS._stripManager_lookupList[0] = (R2_INVENTORY.getObjectScene(R2_READER) == 1) ? 3 : 2;
+
+ if (R2_GLOBALS.getFlag(4))
+ R2_GLOBALS._stripManager_lookupList[0] = 4;
+
+ if (R2_INVENTORY.getObjectScene(R2_OPTO_DISK) == 1)
+ R2_GLOBALS._stripManager_lookupList[0] = 5;
+
+ if (R2_GLOBALS.getFlag(13)) {
+ R2_GLOBALS._stripManager_lookupList[0] = 6;
+ R2_GLOBALS._stripManager_lookupList[2] = 2;
+ }
+
+ if (R2_GLOBALS.getFlag(39))
+ R2_GLOBALS._stripManager_lookupList[1] = 2;
+
+ if (R2_GLOBALS.getFlag(5))
+ R2_GLOBALS._stripManager_lookupList[1] = 3;
+
+ if (R2_GLOBALS.getFlag(6))
+ R2_GLOBALS._stripManager_lookupList[1] = 4;
+
+ if (R2_GLOBALS.getFlag(8))
+ R2_GLOBALS._stripManager_lookupList[1] = 5;
+
+ if (R2_GLOBALS.getFlag(9)) {
+ R2_GLOBALS._stripManager_lookupList[1] = 6;
+ R2_GLOBALS._stripManager_lookupList[3] = 2;
+ }
+
+ if (R2_GLOBALS.getFlag(48))
+ R2_GLOBALS._stripManager_lookupList[4] = 2;
+
+ if (R2_GLOBALS.getFlag(49))
+ R2_GLOBALS._stripManager_lookupList[4] = 3;
+}
+
+/*--------------------------------------------------------------------------
+ * Scene 325 - Bridge Console
+ *
+ *--------------------------------------------------------------------------*/
+
+const double ADJUST_FACTOR = 0.06419999999999999;
+
+/*--------------------------------------------------------------------------*/
+
+Scene325::Icon::Icon(): SceneActor() {
+ _lookLineNum = 0;
+ _field98 = 0;
+ _pressed = false;
+}
+
+void Scene325::Icon::postInit(SceneObjectList *OwnerList) {
+ SceneObject::postInit();
+
+ _object1.postInit();
+ _object1.fixPriority(21);
+ _object1.hide();
+
+ _sceneText1._color1 = 92;
+ _sceneText1._color2 = 0;
+ _sceneText1._width = 200;
+ _sceneText2._color1 = 0;
+ _sceneText2._color2 = 0;
+ _sceneText2._width = 200;
+ fixPriority(20);
+}
+
+void Scene325::Icon::synchronize(Serializer &s) {
+ SceneActor::synchronize(s);
+ s.syncAsSint16LE(_lookLineNum);
+ s.syncAsSint16LE(_field98);
+ s.syncAsSint16LE(_pressed);
+}
+
+void Scene325::Icon::process(Event &event) {
+ Scene325 *scene = (Scene325 *)R2_GLOBALS._sceneManager._scene;
+
+ if (!event.handled && !(_flags & OBJFLAG_HIDING) && R2_GLOBALS._player._uiEnabled) {
+
+ if (event.eventType == EVENT_BUTTON_DOWN) {
+ int regionIndex = R2_GLOBALS._sceneRegions.indexOf(event.mousePos);
+
+ switch (R2_GLOBALS._events.getCursor()) {
+ case CURSOR_LOOK:
+ if (regionIndex == _sceneRegionId) {
+ event.handled = true;
+ SceneItem::display2(326, _lookLineNum);
+ }
+ break;
+
+ case CURSOR_USE:
+ if ((regionIndex == _sceneRegionId) && !_pressed) {
+ scene->_sound1.play(14);
+ setFrame(2);
+
+ switch (_object1._strip) {
+ case 1:
+ _object1.setStrip(2);
+ break;
+ case 3:
+ _object1.setStrip(4);
+ break;
+ case 5:
+ _object1.setStrip(6);
+ break;
+ case 7:
+ _object1.setStrip(8);
+ break;
+ default:
+ break;
+ }
+
+ _pressed = true;
+ event.handled = true;
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ if ((event.eventType == EVENT_BUTTON_UP) && _pressed) {
+ setFrame(1);
+
+ switch (_object1._strip) {
+ case 2:
+ _object1.setStrip(1);
+ break;
+ case 4:
+ _object1.setStrip(3);
+ break;
+ case 6:
+ _object1.setStrip(5);
+ break;
+ default:
+ break;
+ }
+
+ _pressed = false;
+ event.handled = true;
+ scene->consoleAction(_lookLineNum);
+ }
+ }
+}
+
+void Scene325::Icon::setIcon(int id) {
+ Scene325 *scene = (Scene325 *)R2_GLOBALS._sceneManager._scene;
+
+ _lookLineNum = _field98 = id;
+ SceneActor::_lookLineNum = id;
+
+ _sceneText1.remove();
+ _sceneText2.remove();
+
+ if (_lookLineNum) {
+ showIcon();
+ _object1.setup(325, ((id - 1) / 10) * 2 + 1, ((id - 1) % 10) + 1);
+ _object1.setPosition(_position);
+
+ _sceneText1._fontNumber = scene->_iconFontNumber;
+ _sceneText1.setup(CONSOLE325_MESSAGES[id]);
+ _sceneText1.fixPriority(20);
+
+ _sceneText2._fontNumber = scene->_iconFontNumber;
+ _sceneText2.setup(CONSOLE325_MESSAGES[id]);
+ _sceneText2.fixPriority(20);
+
+ _sceneText2._fontNumber = scene->_iconFontNumber;
+ _sceneText2.setup(CONSOLE325_MESSAGES[id]);
+ _sceneText2.fixPriority(10);
+
+ switch (_lookLineNum) {
+ case 7:
+ _sceneText1.setPosition(Common::Point(62, _position.y + 8));
+ _sceneText2.setPosition(Common::Point(64, _position.y + 10));
+ break;
+ case 8:
+ case 9:
+ _sceneText1.setPosition(Common::Point(65, _position.y + 8));
+ _sceneText2.setPosition(Common::Point(67, _position.y + 10));
+ break;
+ case 12:
+ _sceneText1.setPosition(Common::Point(83, _position.y + 8));
+ _sceneText2.setPosition(Common::Point(85, _position.y + 10));
+ break;
+ default:
+ _sceneText1.setPosition(Common::Point(121, _position.y + 8));
+ _sceneText2.setPosition(Common::Point(123, _position.y + 10));
+ break;
+ }
+ } else {
+ hideIcon();
+ }
+}
+
+void Scene325::Icon::showIcon() {
+ _sceneText1.show();
+ _sceneText2.show();
+ _object1.show();
+ _object2.show();
+ show();
+}
+
+void Scene325::Icon::hideIcon() {
+ _sceneText1.hide();
+ _sceneText2.hide();
+ _object1.hide();
+ _object2.hide();
+ hide();
+}
+
+/*--------------------------------------------------------------------------*/
+
+Scene325::Scene325(): SceneExt() {
+ _field412 = 7;
+ _iconFontNumber = 50;
+ _field416 = _field418 = 0;
+ _field41A = _field41C = _field41E = _field420 = 0;
+ _soundCount = _soundIndex = 0;
+
+ for (int idx = 0; idx < 10; ++idx)
+ _soundQueue[idx] = 0;
+}
+
+void Scene325::postInit(SceneObjectList *OwnerList) {
+ SceneExt::postInit();
+ loadScene(325);
+
+ R2_GLOBALS.clearFlag(50);
+ _stripManager.addSpeaker(&_quinnSpeaker);
+ _palette.loadPalette(0);
+
+ R2_GLOBALS._player.postInit();
+ R2_GLOBALS._player.hide();
+ R2_GLOBALS._player.disableControl();
+
+ _item2.setDetails(1, 325, 3, 4, 5);
+ _background.setDetails(Rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT), 325, 0, 1, 2, 1, (SceneItem *)NULL);
+ _sceneMode = 1;
+ signal();
+}
+
+void Scene325::synchronize(Serializer &s) {
+ SceneExt::synchronize(s);
+
+ s.syncAsSint16LE(_field412);
+ s.syncAsSint16LE(_iconFontNumber);
+ s.syncAsSint16LE(_field416);
+ s.syncAsSint16LE(_field418);
+ s.syncAsSint16LE(_field41A);
+ s.syncAsSint16LE(_field41C);
+ s.syncAsSint16LE(_field41E);
+ s.syncAsSint16LE(_field420);
+ s.syncAsSint16LE(_soundCount);
+ s.syncAsSint16LE(_soundIndex);
+
+ for (int idx = 0; idx < 10; ++idx)
+ s.syncAsSint16LE(_soundQueue[idx]);
+}
+
+void Scene325::remove() {
+ removeText();
+ SceneExt::remove();
+}
+
+void Scene325::signal() {
+ switch (_sceneMode - 1) {
+ case 0:
+ _icon1.postInit();
+ _icon1._sceneRegionId = 2;
+ _icon2.postInit();
+ _icon2._sceneRegionId = 3;
+ _icon3.postInit();
+ _icon3._sceneRegionId = 4;
+ _icon4.postInit();
+ _icon4._sceneRegionId = 5;
+
+ setAction(&_sequenceManager1, this, 127, &_icon1, &_icon2, &_icon3, &_icon4,
+ &R2_GLOBALS._player, NULL);
+ _sceneMode = 2;
+ break;
+ case 1:
+ _icon1.setup(160, 1, 1);
+ _icon1.setPosition(Common::Point(65, 17));
+ _icon1._object2.postInit();
+ _icon1._object2.setup(160, 7, 1);
+ _icon1._object2.setPosition(Common::Point(106, 41));
+
+ _icon2.setup(160, 1, 1);
+ _icon2.setPosition(Common::Point(80, 32));
+ _icon2._object2.postInit();
+ _icon2._object2.setup(160, 7, 2);
+ _icon2._object2.setPosition(Common::Point(106, 56));
+
+ _icon3.setup(160, 1, 1);
+ _icon3.setPosition(Common::Point(65, 47));
+ _icon3._object2.postInit();
+ _icon3._object2.setup(160, 7, 1);
+ _icon3._object2.setPosition(Common::Point(106, 71));
+
+ _icon4.setup(160, 1, 1);
+ _icon4.setPosition(Common::Point(80, 62));
+ _icon4._sceneRegionId = 5;
+ _icon4._object2.postInit();
+ _icon4._object2.setup(160, 7, 2);
+ _icon4._object2.setPosition(Common::Point(106, 86));
+
+ _icon5.postInit();
+ _icon5.setup(160, 1, 1);
+ _icon5._sceneRegionId = 7;
+ _icon5.setPosition(Common::Point(37, 92));
+ _icon5.setIcon(8);
+
+ _icon6.postInit();
+ _icon6.setup(160, 1, 1);
+ _icon6.setPosition(Common::Point(106, 110));
+ _icon6.setIcon(7);
+ _icon6._sceneRegionId = 8;
+
+ consoleAction(7);
+ R2_GLOBALS._player.enableControl(CURSOR_USE);
+ R2_GLOBALS._player._canWalk = false;
+ break;
+ case 9:
+ switch (_field412) {
+ case 3:
+ _sceneMode = 129;
+ _object1.postInit();
+ _object2.postInit();
+ _object3.postInit();
+ if (R2_GLOBALS.getFlag(13)) {
+ _object4.postInit();
+ setAction(&_sequenceManager1, this, 130, &R2_GLOBALS._player, &_object1,
+ &_object2, &_object3, &_object4, NULL);
+ } else {
+ setAction(&_sequenceManager1, this, 129, &R2_GLOBALS._player, &_object1,
+ &_object2, &_object3, NULL);
+ }
+ break;
+ case 17:
+ case 18:
+ case 19:
+ case 20: {
+ int v = 10 - ((21 - _field412) * 2);
+ if (R2_GLOBALS.getFlag(50))
+ --v;
+ if (_field418 == 5)
+ v += 8;
+ if (R2_GLOBALS.getFlag(51) && (v == 2))
+ R2_GLOBALS.setFlag(57);
+
+ if (R2_GLOBALS.getFlag(44) && !R2_GLOBALS.getFlag(51)) {
+ if (v != 13) {
+ setMessage(328, 0);
+ } else {
+ _field420 = 864;
+
+ _object12.postInit();
+ _object2.setup(326, 4, 1);
+ _object12.setPosition(Common::Point(149, 128));
+ _object12.fixPriority(20);
+
+ _object13.postInit();
+ _object13.setup(326, 4, 2);
+ _object13.setPosition(Common::Point(149, (int)(_field420 * ADJUST_FACTOR)));
+ _object13.fixPriority(21);
+
+ _object10.postInit();
+ _object10.setup(326, 1, 1);
+ _object10.setPosition(Common::Point(210, 20));
+ _object10.fixPriority(10);
+
+ _object1.postInit();
+ _object1.setup(326, 1, 1);
+ _object1.setPosition(Common::Point(210, 32));
+ _object10.fixPriority(10);
+
+ _object2.postInit();
+ _object2.setup(326, 1, 1);
+ _object2.setPosition(Common::Point(210, 44));
+ _object2.fixPriority(10);
+
+ _object3.postInit();
+ _object3.setup(326, 1, 1);
+ _object3.setPosition(Common::Point(210, 56));
+ _object3.fixPriority(10);
+
+ _object4.postInit();
+ _object4.setup(326, 1, 1);
+ _object4.setPosition(Common::Point(210, 68));
+ _object4.fixPriority(10);
+
+ _object5.postInit();
+ _object5.setup(326, 1, 1);
+ _object5.setPosition(Common::Point(210, 80));
+ _object5.fixPriority(10);
+
+ _object6.postInit();
+ _object6.setup(326, 1, 1);
+ _object6.setPosition(Common::Point(210, 92));
+ _object6.fixPriority(10);
+
+ _object7.postInit();
+ _object7.setup(326, 1, 1);
+ _object7.setPosition(Common::Point(210, 104));
+ _object7.fixPriority(10);
+
+ _object8.postInit();
+ _object8.setup(326, 1, 1);
+ _object8.setPosition(Common::Point(210, 116));
+ _object8.fixPriority(10);
+
+ _object9.postInit();
+ _object9.setup(326, 1, 1);
+ _object9.setPosition(Common::Point(210, 128));
+ _object9.fixPriority(10);
+
+ _object11.postInit();
+ _object11.setup(326, 1, 1);
+ _object11.setPosition(Common::Point(210, 150));
+ _object11.fixPriority(10);
+ }
+ } else if (R2_GLOBALS.getFlag(51)) {
+ setMessage(329, (v == 12) ? 10 : v);
+ } else {
+ setMessage(327, (v < 15) ? 1 : v);
+ }
+ break;
+ }
+ case 21:
+ _sceneMode = 129;
+
+ _object1.postInit();
+ _object1.setup(327, 1, 1);
+ _object1.setPosition(Common::Point(170, 80));
+ _object1.fixPriority(10);
+ _object1.animate(ANIM_MODE_5, NULL);
+ break;
+ case 22:
+ _sceneMode = 129;
+
+ _object1.postInit();
+ _object1.setup(327, 2, 1);
+ _object1.setPosition(Common::Point(160, 80));
+ _object1.fixPriority(10);
+ _object1.animate(ANIM_MODE_5, NULL);
+ break;
+ case 24:
+ R2_GLOBALS._player.enableControl();
+ R2_GLOBALS._player._canWalk = false;
+ _field416 = 37;
+ setMessage(128, _field416);
+ break;
+ case 25:
+ R2_GLOBALS._player.enableControl();
+ R2_GLOBALS._player._canWalk = false;
+ _field416 = 68;
+ setMessage(128, _field416);
+ break;
+ case 26:
+ R2_GLOBALS._player.enableControl();
+ R2_GLOBALS._player._canWalk = false;
+ _field416 = 105;
+ setMessage(128, _field416);
+ break;
+ default:
+ R2_GLOBALS._player.enableControl();
+ R2_GLOBALS._player._canWalk = false;
+ _field416 = 105;
+ setMessage(128, _field416);
+ break;
+ }
+ break;
+ case 10:
+ R2_GLOBALS._player.enableControl();
+ R2_GLOBALS._player._canWalk = false;
+
+ if ((_field412 >= 17) && (_field412 <= 20)) {
+ _icon5.setIcon(8);
+ consoleAction(4);
+ } else {
+ consoleAction(7);
+ }
+
+ _icon6.setIcon(7);
+ break;
+ case 11:
+ R2_GLOBALS.setFlag(45);
+ R2_GLOBALS._sceneManager.changeScene(300);
+ break;
+ case 12:
+ R2_GLOBALS.setFlag(57);
+ R2_GLOBALS._sceneManager.changeScene(300);
+ break;
+ case 14:
+ if (_soundCount)
+ --_soundCount;
+
+ if (!_soundCount || (R2_GLOBALS._speechSubtitles == 2)) {
+ _soundIndex = 0;
+ R2_GLOBALS._playStream.stop();
+ } else {
+ _sceneMode = 15;
+ R2_GLOBALS._playStream.play(_soundQueue[_soundIndex], this);
+ }
+ break;
+ default:
+ R2_GLOBALS._player.enableControl();
+ R2_GLOBALS._player._canWalk = false;
+ break;
+ }
+}
+
+void Scene325::removeText() {
+ _text1.remove();
+ _soundCount = 0;
+ _soundIndex = 0;
+ R2_GLOBALS._playStream.stop();
+}
+
+void Scene325::consoleAction(int id) {
+ _icon1.setIcon(0);
+ _icon2.setIcon(0);
+ _icon3.setIcon(0);
+ _icon4.setIcon(0);
+
+ if (id == 7)
+ _icon5.setIcon(9);
+ else if ((_field412 != 3) && ((_field412 < 17) || (_field412 > 26)))
+ _icon5.setIcon(8);
+
+ switch (id - 1) {
+ case 0:
+ _icon1.setIcon(10);
+ _icon2.setIcon(11);
+ break;
+ case 1:
+ _icon1.setIcon(23);
+ _icon2.setIcon(24);
+ _icon3.setIcon(25);
+ _icon4.setIcon(26);
+ case 2:
+ case 16:
+ case 17:
+ case 18:
+ case 19:
+ case 20:
+ case 21:
+ R2_GLOBALS._player.disableControl();
+ consoleAction(7);
+ _icon1.hideIcon();
+ _icon2.hideIcon();
+ _icon3.hideIcon();
+ // TODO: Finish
+ break;
+ case 3:
+ _icon1.setIcon(5);
+ _icon2.setIcon(6);
+ _icon3.setIcon(R2_GLOBALS.getFlag(50) ? 16 : 15);
+ break;
+ case 4:
+ case 5:
+ _field418 = id;
+ _icon1.setIcon(17);
+ _icon2.setIcon(18);
+ _icon3.setIcon(19);
+ break;
+ case 7:
+ consoleAction(((_field412 == 5) || (_field412 == 6) || (_field412 == 15)) ? 4 : 7);
+ break;
+ case 8:
+ R2_GLOBALS._sceneManager.changeScene(300);
+ case 9:
+ case 10:
+ _iconFontNumber = (id - 1) == 9 ? 50 : 52;
+ _text1.remove();
+ _icon6.setIcon(7);
+ break;
+ case 11:
+ if (R2_GLOBALS.getFlag(57) && (R2_GLOBALS._player._characterIndex == 1) && !R2_GLOBALS.getFlag(25)) {
+ R2_GLOBALS._player.disableControl();
+ R2_GLOBALS._events.setCursor(CURSOR_ARROW);
+ _sceneMode = 13;
+ _stripManager.start(403, this);
+ } else {
+ R2_GLOBALS._player.disableControl();
+ _text1.remove();
+
+ _icon4.setPosition(Common::Point(80, 62));
+ _icon4._sceneRegionId = 5;
+ _icon4.hideIcon();
+
+ _object12.remove();
+ _object13.remove();
+ _object10.remove();
+ _object1.remove();
+ _object2.remove();
+ _object3.remove();
+ _object4.remove();
+ _object5.remove();
+ _object6.remove();
+ _object7.remove();
+ _object8.remove();
+ _object9.remove();
+ _object11.remove();
+
+ _palette.loadPalette(160);
+ _sceneMode = 11;
+
+ BF_GLOBALS._scenePalette.addFader(&_palette._palette[0], 256, 5, this);
+ }
+ break;
+ case 12:
+ _icon4.setIcon(14);
+ _icon4._object2.hide();
+
+ switch (_field412) {
+ case 17:
+ case 18:
+ case 19:
+ case 20:
+ if (_field420) {
+ R2_GLOBALS._player.disableControl();
+ _field41A = 1296;
+ _field41E = 1;
+ }
+ break;
+ default:
+ setMessage(128, --_field416);
+ break;
+ }
+ return;
+ case 13:
+ _icon4.setIcon(14);
+ _icon4._object2.hide();
+
+ switch (_field412) {
+ case 17:
+ case 18:
+ case 19:
+ case 20:
+ if (_field420 < 1620) {
+ R2_GLOBALS._player.disableControl();
+ _field41A = 1296;
+ _field41E = -1;
+ }
+ break;
+ }
+ return;
+ case 14:
+ if (R2_GLOBALS.getFlag(55)) {
+ SceneItem::display2(329, 17);
+ } else {
+ R2_GLOBALS.setFlag(50);
+ consoleAction(4);
+ }
+ id = 4;
+ break;
+ case 15:
+ R2_GLOBALS.clearFlag(50);
+ consoleAction(4);
+ id = 4;
+ break;
+ case 22:
+ case 23:
+ case 24:
+ case 25:
+ R2_GLOBALS._player.disableControl();
+ consoleAction(2);
+ _field412 = id;
+
+ _icon1.hideIcon();
+ _icon2.hideIcon();
+ _icon3.hideIcon();
+ _icon4.hideIcon();
+
+ _icon5.setIcon(13);
+ _icon4.setPosition(Common::Point(52, 107));
+ _icon4._sceneRegionId = 9;
+ _icon4.setIcon(14);
+ _icon4._object2.hide();
+
+ _icon6.setIcon(12);
+ _sceneMode = 10;
+ _palette.loadPalette(161);
+
+ BF_GLOBALS._scenePalette.addFader(&_palette._palette[0], 256, 5, this);
+ break;
+ case 6:
+ default:
+ _icon1.setIcon(1);
+ _icon2.setIcon(2);
+ _icon3.setIcon(3);
+ int idList[3] = { 4, 22, 21 };
+ _icon4.setIcon(idList[R2_GLOBALS._player._characterIndex - 1]);
+ break;
+ }
+
+ if (id != 8)
+ _field412 = id;
+}
+
+void Scene325::process(Event &event) {
+ SceneExt::process(event);
+
+ if (R2_GLOBALS._player._uiEnabled) {
+ _icon1.process(event);
+ _icon2.process(event);
+ _icon3.process(event);
+ _icon4.process(event);
+ _icon5.process(event);
+ _icon6.process(event);
+ }
+}
+
+void Scene325::dispatch() {
+ if (_field41A) {
+ switch (_field41A) {
+ case 13:
+ _field41C = 1;
+ break;
+ case 1296:
+ R2_GLOBALS._sound3.play(87);
+ _field41C = 1;
+ break;
+ case 33:
+ case 1283:
+ _field41C = 2;
+ break;
+ case 63:
+ case 1263:
+ _field41C = 3;
+ break;
+ case 103:
+ case 1233:
+ _field41C = 4;
+ break;
+ case 153:
+ case 1193:
+ _field41C = 5;
+ break;
+ case 213:
+ case 1143:
+ _field41C = 6;
+ break;
+ case 283:
+ case 1083:
+ _field41C = 7;
+ break;
+ case 1013:
+ _field41C = 8;
+ break;
+ default:
+ break;
+ }
+
+ _field41A -= _field41C;
+ int yp = _field41E * _field41C + _object10._position.y;
+ bool flag = false;
+
+ if (yp >= 30) {
+ yp -= 12;
+ --_field420;
+ flag = true;
+ }
+ if (yp <= 10) {
+ yp += 12;
+ ++_field420;
+ flag = true;
+ }
+ _object3.setPosition(Common::Point(149, (int)(_field420 * ADJUST_FACTOR) + 22));
+
+ for (int idx = 0; idx < 4; ++idx)
+ _objList[idx].remove();
+
+ if (flag) {
+ int v = _field420 - 758;
+ _object10.setFrame((v++ <= 0) ? 1 : v);
+ _object1.setFrame((v++ <= 0) ? 1 : v);
+ _object2.setFrame((v++ <= 0) ? 1 : v);
+ _object3.setFrame((v++ <= 0) ? 1 : v);
+ _object4.setFrame((v++ <= 0) ? 1 : v);
+ _object5.setFrame((v++ <= 0) ? 1 : v);
+ _object6.setFrame((v++ <= 0) ? 1 : v);
+ _object7.setFrame((v++ <= 0) ? 1 : v);
+ _object8.setFrame((v++ <= 0) ? 1 : v);
+ _object9.setFrame((v++ <= 0) ? 1 : v);
+ _object11.setFrame((v++ <= 0) ? 1 : v);
+ }
+
+ _object10.setPosition(Common::Point(210, yp));
+ yp += 12;
+ _object1.setPosition(Common::Point(210, yp));
+ yp += 12;
+ _object2.setPosition(Common::Point(210, yp));
+ yp += 12;
+ _object3.setPosition(Common::Point(210, yp));
+ yp += 12;
+ _object4.setPosition(Common::Point(210, yp));
+ yp += 12;
+ _object5.setPosition(Common::Point(210, yp));
+ yp += 12;
+ _object6.setPosition(Common::Point(210, yp));
+ yp += 12;
+ _object7.setPosition(Common::Point(210, yp));
+ yp += 12;
+ _object8.setPosition(Common::Point(210, yp));
+ yp += 12;
+ _object9.setPosition(Common::Point(210, yp));
+ yp += 12;
+ _object11.setPosition(Common::Point(210, yp));
+
+ if (!_field41A) {
+ R2_GLOBALS._sound3.stop();
+ _field41C = 0;
+
+ if (_field420 == 756) {
+ R2_GLOBALS._player.disableControl();
+ R2_GLOBALS._events.setCursor(CURSOR_USE);
+ _sceneMode = 12;
+ _stripManager.start(212, this);
+ } else {
+ R2_GLOBALS._player.enableControl();
+ R2_GLOBALS._player._canWalk = false;
+ }
+ }
+ }
+
+ SceneExt::dispatch();
+}
+
+void Scene325::setMessage(int resNum, int lineNum) {
+ Common::String msg = g_resourceManager->getMessage(resNum, lineNum);
+
+ if (!msg.empty()) {
+ Common::String msgText = parseMessage(msg);
+
+ _text1._fontNumber = _iconFontNumber;
+ _text1._color1 = 92;
+ _text1._color2 = 0;
+ _text1._width = 221;
+ _text1.fixPriority(20);
+ _text1.setup(msgText);
+ _text1.setPosition(Common::Point(49, 19));
+
+ R2_GLOBALS._sceneObjects->draw();
+
+ if ((_soundCount != 0) && (R2_GLOBALS._speechSubtitles != 2)) {
+ _sceneMode = 15;
+ R2_GLOBALS._playStream.play(_soundQueue[_soundIndex++], this);
+ }
+ } else {
+ _field412 = 13;
+ R2_GLOBALS._player.disableControl();
+ R2_GLOBALS._player.hide();
+
+ _icon4.setPosition(Common::Point(80, 62));
+ _icon4._sceneRegionId = 5;
+ _icon4.hideIcon();
+
+ _palette.loadPalette(160);
+ _sceneMode = 11;
+ BF_GLOBALS._scenePalette.addFader(&_palette._palette[0], 256, 5, this);
+ }
+}
+
+/**
+ * Parses a message to be displayed on the console to see whether there are any sounds to be played.
+ */
+Common::String Scene325::parseMessage(const Common::String &msg) {
+ _soundIndex = 0;
+ _soundCount = 0;
+
+ const char *msgP = msg.c_str();
+ while (*msgP == '!') {
+ // Get the sound number
+ _soundQueue[_soundCount++] = atoi(++msgP);
+
+ while (!((*msgP == '\0') || (*msgP < '0') || (*msgP > '9')))
+ ++msgP;
+ }
+
+ return Common::String(msgP);
+}
+/*--------------------------------------------------------------------------
+ * Scene 400 - Science Lab
+ *
+ *--------------------------------------------------------------------------*/
+
+bool Scene400::Terminal::startAction(CursorType action, Event &event) {
+ Scene400 *scene = (Scene400 *)R2_GLOBALS._sceneManager._scene;
+
+ if (action == CURSOR_USE) {
+ R2_GLOBALS._player.disableControl();
+ scene->_sceneMode = 402;
+ scene->setAction(&scene->_sequenceManager1, scene, 402, &R2_GLOBALS._player, this, NULL);
+
+ return true;
+ } else {
+ return NamedHotspot::startAction(action, event);
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+
+bool Scene400::Door::startAction(CursorType action, Event &event) {
+ Scene400 *scene = (Scene400 *)R2_GLOBALS._sceneManager._scene;
+
+ if (action == CURSOR_USE) {
+ R2_GLOBALS._player.disableControl();
+ scene->_sceneMode = 401;
+ scene->setAction(&scene->_sequenceManager1, scene, 401, &R2_GLOBALS._player, this, NULL);
+
+ return true;
+ } else {
+ return SceneActor::startAction(action, event);
+ }
+}
+
+bool Scene400::Reader::startAction(CursorType action, Event &event) {
+ Scene400 *scene = (Scene400 *)R2_GLOBALS._sceneManager._scene;
+
+ if (action == CURSOR_USE) {
+ R2_GLOBALS._player.disableControl();
+ scene->_sceneMode = 405;
+ scene->setAction(&scene->_sequenceManager1, scene, 405, &R2_GLOBALS._player, this, NULL);
+
+ return true;
+ } else {
+ return SceneActor::startAction(action, event);
+ }
+}
+
+bool Scene400::SensorProbe::startAction(CursorType action, Event &event) {
+ Scene400 *scene = (Scene400 *)R2_GLOBALS._sceneManager._scene;
+
+ if (action == CURSOR_USE) {
+ R2_GLOBALS._player.disableControl();
+ scene->_sceneMode = 404;
+ scene->setAction(&scene->_sequenceManager1, scene, 404, &R2_GLOBALS._player, this, NULL);
+
+ return true;
+ } else {
+ return SceneActor::startAction(action, event);
+ }
+}
+
+bool Scene400::AttractorUnit::startAction(CursorType action, Event &event) {
+ Scene400 *scene = (Scene400 *)R2_GLOBALS._sceneManager._scene;
+
+ if (action == CURSOR_USE) {
+ R2_GLOBALS._player.disableControl();
+ scene->_sceneMode = 406;
+ scene->setAction(&scene->_sequenceManager1, scene, 406, &R2_GLOBALS._player, this, NULL);
+
+ return true;
+ } else {
+ return SceneActor::startAction(action, event);
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+
+void Scene400::postInit(SceneObjectList *OwnerList) {
+ SceneExt::postInit();
+ loadScene(400);
+ _sound1.play(20);
+
+ _door.postInit();
+ _door.setVisage(100);
+ _door.setPosition(Common::Point(123, 84));
+ _door.setDetails(400, 24, -1, 26, 1, (SceneItem *)NULL);
+
+ _consoleDisplay.postInit();
+ _consoleDisplay.setup(400, 4, 1);
+ _consoleDisplay.setPosition(Common::Point(236, 92));
+ _consoleDisplay.fixPriority(120);
+ _consoleDisplay.animate(ANIM_MODE_2, NULL);
+ _consoleDisplay._numFrames = 5;
+
+ _testerDisplay.postInit();
+ _testerDisplay.setup(400, 2, 1);
+ _testerDisplay.setPosition(Common::Point(198, 83));
+ _testerDisplay.animate(ANIM_MODE_2, NULL);
+ _testerDisplay._numFrames = 20;
+
+ if (R2_INVENTORY.getObjectScene(R2_READER) == 400) {
+ _reader.postInit();
+ _reader.setup(400, 5, 2);
+ _reader.setPosition(Common::Point(301, 95));
+ _reader.setDetails(400, 54, -1, 56, 1, (SceneItem *)NULL);
+ }
+
+ if (R2_INVENTORY.getObjectScene(R2_SENSOR_PROBE) == 400) {
+ _sensorProbe.postInit();
+ _sensorProbe.setup(400, 5, 1);
+ _sensorProbe.setPosition(Common::Point(251, 104));
+ _sensorProbe.fixPriority(121);
+ _sensorProbe.setDetails(400, 57, -1, 59, 1, (SceneItem *)NULL);
+ }
+
+ if (R2_INVENTORY.getObjectScene(R2_ATTRACTOR_UNIT) == 400) {
+ _attractorUnit.postInit();
+ _attractorUnit.setup(400, 5, 3);
+ _attractorUnit.setPosition(Common::Point(265, 129));
+ _attractorUnit.setDetails(400, 60, -1, 62, 1, (SceneItem *)NULL);
+ }
+
+ R2_GLOBALS._player.postInit();
+ R2_GLOBALS._player.setVisage(10);
+ R2_GLOBALS._player.animate(ANIM_MODE_1, NULL);
+ R2_GLOBALS._player.disableControl();
+
+ _equipment1.setDetails(11, 400, 3, -1, -1);
+ _equipment2.setDetails(24, 400, 3, -1, -1);
+ _equipment3.setDetails(25, 400, 3, -1, -1);
+ _equipment4.setDetails(26, 400, 3, -1, -1);
+ _equipment5.setDetails(28, 400, 3, -1, -1);
+ _equipment6.setDetails(29, 400, 3, -1, -1);
+ _desk.setDetails(12, 400, 6, -1, -1);
+ _desk2.setDetails(27, 400, 6, -1, -1);
+ _terminal.setDetails(13, 400, 6, -1, 11);
+ _duct.setDetails(14, 400, 12, -1, -1);
+ _console.setDetails(15, 400, 15, -1, 17);
+ _equalizer.setDetails(Rect(284, 99, 308, 108), 400, 36, -1, 38, 1, NULL);
+ _transducer.setDetails(Rect(295, 67, 314, 79), 400, 39, -1, 41, 1, NULL);
+ _optimizer.setDetails(Rect(308, 106, 315, 113), 400, 42, -1, 44, 1, NULL);
+ _soundModule.setDetails(Rect(291, 118, 315, 131), 400, 45, -1, 47, 1, NULL);
+ _tester.setDetails(Rect(179, 62, 217, 92), 400, 30, -1, 32, 1, NULL);
+ _helmet.setDetails(Rect(181, 53, 197, 65), 400, 48, -1, 50, 1, NULL);
+ _nullifier.setDetails(Rect(201, 56, 212, 65), 400, 51, -1, 50, 1, NULL);
+ _shelves.setDetails(16, 400, 18, -1, 20);
+ _cabinet.setDetails(17, 400, 21, -1, -1);
+ _doorDisplay.setDetails(Rect(161, 43, 166, 52), 400, 27, -1, -1, 1, NULL);
+ _lights.setDetails(Rect(113, 3, 168, 14), 400, 33, -1, -1, 1, NULL);
+ _background.setDetails(Rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT), 400, 0, 1, -1, 1, NULL);
+
+ _sceneMode = 400;
+ switch (R2_GLOBALS._sceneManager._previousScene) {
+ case 125:
+ setAction(&_sequenceManager1, this, 403, &R2_GLOBALS._player, NULL);
+ break;
+ case 200:
+ setAction(&_sequenceManager1, this, 400, &R2_GLOBALS._player, &_door, NULL);
+ break;
+ default:
+ R2_GLOBALS._player.setStrip(3);
+ R2_GLOBALS._player.setPosition(Common::Point(180, 100));
+ R2_GLOBALS._player.enableControl();
+ break;
+ }
+}
+
+void Scene400::remove() {
+ R2_GLOBALS._sound1.fadeOut2(NULL);
+ SceneExt::remove();
+}
+
+void Scene400::signal() {
+ switch (_sceneMode) {
+ case 400:
+ case 403:
+ R2_GLOBALS._player.enableControl();
+ break;
+ case 401:
+ R2_GLOBALS._sceneManager.changeScene(200);
+ break;
+ case 402:
+ R2_GLOBALS._sceneManager.changeScene(125);
+ break;
+ case 404:
+ // Getting the sensor probe
+ R2_INVENTORY.setObjectScene(R2_SENSOR_PROBE, 1);
+ _sensorProbe.remove();
+ R2_GLOBALS._player.enableControl();
+ break;
+ case 405:
+ // Getting the reader
+ R2_INVENTORY.setObjectScene(R2_READER, 1);
+ _reader.remove();
+ R2_GLOBALS._player.enableControl();
+ break;
+ case 406:
+ R2_INVENTORY.setObjectScene(R2_ATTRACTOR_UNIT, 1);
+ _attractorUnit.remove();
+ R2_GLOBALS._player.enableControl();
+ break;
+ default:
+ break;
+ }
+}
+
+void Scene400::dispatch() {
+ SceneExt::dispatch();
+
+ switch (R2_GLOBALS._player.getRegionIndex() - 15) {
+ case 0:
+ case 11:
+ case 12:
+ R2_GLOBALS._player._shade = 2;
+ break;
+ case 9:
+ R2_GLOBALS._player._shade = 0;
+ break;
+ case 10:
+ R2_GLOBALS._player._shade = 1;
+ break;
+ case 13:
+ R2_GLOBALS._player._shade = 3;
+ break;
+ case 14:
+ R2_GLOBALS._player._shade = 4;
+ break;
+ default:
+ break;
+ }
+}
+
+/*--------------------------------------------------------------------------
+ * Scene 500 - Lander Bay 2 Storage
+ *
+ *--------------------------------------------------------------------------*/
+
+bool Scene500::ControlPanel::startAction(CursorType action, Event &event) {
+ Scene500 *scene = (Scene500 *)R2_GLOBALS._sceneManager._scene;
+
+ if ((action == CURSOR_USE) && (R2_GLOBALS._player._characterIndex == R2_QUINN)) {
+ R2_GLOBALS._player.disableControl();
+
+ if (R2_GLOBALS.getFlag(26)) {
+ scene->_stripNumber = 1104;
+ scene->_sceneMode = 524;
+ scene->setAction(&scene->_sequenceManager1, scene, 524, &R2_GLOBALS._player, NULL);
+ } else {
+ scene->_sceneMode = 510;
+ scene->setAction(&scene->_sequenceManager1, scene, 510, &R2_GLOBALS._player, NULL);
+ }
+ return true;
+ } else {
+ return SceneHotspot::startAction(action, event);
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+
+bool Scene500::Object2::startAction(CursorType action, Event &event) {
+ Scene500 *scene = (Scene500 *)R2_GLOBALS._sceneManager._scene;
+
+ if (action == CURSOR_TALK) {
+ R2_GLOBALS._player.disableControl();
+ if (R2_GLOBALS._player._characterIndex == 1) {
+ scene->_stripNumber = R2_GLOBALS.getFlag(26) ? 1101 : 1103;
+ } else {
+ scene->_stripNumber = R2_GLOBALS.getFlag(26) ? 1102 : 1105;
+ }
+
+ scene->setAction(&scene->_sequenceManager1, scene, 524, &R2_GLOBALS._player, NULL);
+ return true;
+ } else {
+ return SceneActor::startAction(action, event);
+ }
+}
+
+bool Scene500::Object3::startAction(CursorType action, Event &event) {
+ Scene500 *scene = (Scene500 *)R2_GLOBALS._sceneManager._scene;
+
+ switch (action) {
+ case CURSOR_LOOK:
+ SceneItem::display2(500, R2_GLOBALS.getFlag(28) ? 28 : _strip + 25);
+ return true;
+
+ case CURSOR_USE:
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
+ if ((_strip != 3) && (_strip != 7))
+ SceneItem::display2(500, _strip);
+ else if (R2_GLOBALS.getFlag(26)) {
+ R2_GLOBALS._player.disableControl();
+ scene->_stripNumber = 1103;
+ scene->_sceneMode = 524;
+ scene->setAction(&scene->_sequenceManager1, scene, 524, &R2_GLOBALS._player, NULL);
+ } else if (!R2_GLOBALS.getFlag(28))
+ SceneItem::display2(500, 41);
+ else if (!R2_GLOBALS.getFlag(40))
+ SceneItem::display2(500, 40);
+ else {
+ R2_GLOBALS._player.disableControl();
+ scene->_sceneMode = 512;
+ scene->setAction(&scene->_sequenceManager1, scene, 524, &R2_GLOBALS._player, &scene->_object3, NULL);
+ R2_GLOBALS.setFlag(26);
+ }
+ } else {
+ SceneItem::display2(500, 42);
+ }
+ return true;
+
+ case R2_REBREATHER_TANK:
+ if (!R2_GLOBALS.getFlag(25))
+ SceneItem::display2(500, 10);
+ else if (_strip != 3)
+ SceneItem::display2(500, _strip + 25);
+ else {
+ R2_GLOBALS._player.disableControl();
+ scene->_sceneMode = 515;
+ scene->setAction(&scene->_sequenceManager1, scene, 515, &R2_GLOBALS._player, &scene->_object3, NULL);
+ R2_GLOBALS.setFlag(28);
+ }
+ return true;
+
+ case R2_RESERVE_REBREATHER_TANK:
+ SceneItem::display2(500, 53);
+ return true;
+
+ default:
+ if (action < R2_LAST_INVENT) {
+ SceneItem::display2(500, action);
+ return true;
+ } else {
+ return SceneActor::startAction(action, event);
+ }
+ }
+}
+
+bool Scene500::Doorway::startAction(CursorType action, Event &event) {
+ Scene500 *scene = (Scene500 *)R2_GLOBALS._sceneManager._scene;
+
+ if ((action == CURSOR_USE) && (R2_GLOBALS._player._characterIndex == R2_QUINN)) {
+ R2_GLOBALS._player.disableControl();
+
+ if (R2_GLOBALS.getFlag(26)) {
+ scene->_stripNumber = 1104;
+ scene->_sceneMode = 524;
+ scene->setAction(&scene->_sequenceManager1, scene, 524, &R2_GLOBALS._player, NULL);
+ } else {
+ scene->_sceneMode = 500;
+ scene->setAction(&scene->_sequenceManager1, scene, 500, &R2_GLOBALS._player, NULL);
+ }
+
+ return true;
+ } else {
+ return SceneActor::startAction(action, event);
+ }
+}
+
+bool Scene500::OxygenTanks::startAction(CursorType action, Event &event) {
+ Scene500 *scene = (Scene500 *)R2_GLOBALS._sceneManager._scene;
+
+ switch (action) {
+ case CURSOR_LOOK:
+ SceneItem::display2(500, R2_INVENTORY.getObjectScene(R2_REBREATHER_TANK) ? 50 : 49);
+ return true;
+
+ case CURSOR_USE:
+ if (R2_GLOBALS._player._characterIndex != R2_QUINN) {
+ SceneItem::display2(500, 52);
+ return true;
+ } else if ((R2_INVENTORY.getObjectScene(R2_REBREATHER_TANK) != 1) &&
+ (R2_GLOBALS._player._characterIndex != R2_SEEKER) && !R2_GLOBALS.getFlag(28)) {
+ R2_GLOBALS._player.disableControl();
+
+ if (_position.y == 120) {
+ scene->_sceneMode = 513;
+ scene->setAction(&scene->_sequenceManager1, scene, scene->_sceneMode, &R2_GLOBALS._player,
+ &scene->_tanks1, NULL);
+ } else {
+ scene->_sceneMode = 514;
+ scene->setAction(&scene->_sequenceManager1, scene, scene->_sceneMode, &R2_GLOBALS._player,
+ &scene->_tanks2, NULL);
+ }
+ return true;
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ return SceneActor::startAction(action, event);
+}
+
+bool Scene500::AirLock::startAction(CursorType action, Event &event) {
+ Scene500 *scene = (Scene500 *)R2_GLOBALS._sceneManager._scene;
+
+ if ((action == CURSOR_USE) && R2_GLOBALS.getFlag(26)) {
+ R2_GLOBALS._player.disableControl();
+ scene->_sceneMode = (R2_GLOBALS._player._characterIndex == R2_QUINN) ? 521 : 522;
+ scene->setAction(&scene->_sequenceManager1, scene, scene->_sceneMode, &R2_GLOBALS._player,
+ &scene->_object2, &scene->_airLock, NULL);
+ return true;
+ } else {
+ return SceneActor::startAction(action, event);
+ }
+}
+
+bool Scene500::Aerosol::startAction(CursorType action, Event &event) {
+ Scene500 *scene = (Scene500 *)R2_GLOBALS._sceneManager._scene;
+
+ if (action == CURSOR_USE) {
+ R2_GLOBALS._player.disableControl();
+ scene->_sceneMode = 503;
+ scene->setAction(&scene->_sequenceManager1, scene, 503, &R2_GLOBALS._player, this, NULL);
+ return true;
+ } else {
+ return SceneActor::startAction(action, event);
+ }
+}
+
+bool Scene500::SonicStunner::startAction(CursorType action, Event &event) {
+ Scene500 *scene = (Scene500 *)R2_GLOBALS._sceneManager._scene;
+
+ if ((action == CURSOR_USE) && (R2_GLOBALS._player._characterIndex == R2_QUINN)) {
+ R2_GLOBALS._player.disableControl();
+ scene->_sceneMode = R2_GLOBALS.getFlag(26) ? 520 : 502;
+ scene->setAction(&scene->_sequenceManager1, scene, scene->_sceneMode, &R2_GLOBALS._player, NULL);
+ return true;
+ } else {
+ return SceneActor::startAction(action, event);
+ }
+}
+
+bool Scene500::Locker1::startAction(CursorType action, Event &event) {
+ Scene500 *scene = (Scene500 *)R2_GLOBALS._sceneManager._scene;
+
+ if ((action == CURSOR_USE) && (R2_GLOBALS._player._characterIndex == R2_QUINN)) {
+ R2_GLOBALS._player.disableControl();
+
+ if (R2_GLOBALS.getFlag(11))
+ scene->_sceneMode = R2_GLOBALS.getFlag(26) ? 517 : 505;
+ else
+ scene->_sceneMode = R2_GLOBALS.getFlag(26) ? 516 : 504;
+
+ scene->setAction(&scene->_sequenceManager1, scene, scene->_sceneMode, &R2_GLOBALS._player, this, NULL);
+ return true;
+ } else {
+ return SceneActor::startAction(action, event);
+ }
+}
+
+bool Scene500::Locker2::startAction(CursorType action, Event &event) {
+ Scene500 *scene = (Scene500 *)R2_GLOBALS._sceneManager._scene;
+
+ if ((action == CURSOR_USE) && (R2_GLOBALS._player._characterIndex == R2_QUINN)) {
+ R2_GLOBALS._player.disableControl();
+
+ if (R2_GLOBALS.getFlag(12))
+ scene->_sceneMode = R2_GLOBALS.getFlag(26) ? 519 : 507;
+ else
+ scene->_sceneMode = R2_GLOBALS.getFlag(26) ? 518 : 506;
+
+ scene->setAction(&scene->_sequenceManager1, scene, scene->_sceneMode, &R2_GLOBALS._player, this, NULL);
+ return true;
+ } else {
+ return SceneActor::startAction(action, event);
+ }
+}
+
+bool Scene500::Object::startAction(CursorType action, Event &event) {
+ if (action == CURSOR_USE) {
+ return false;
+ } else {
+ return SceneActor::startAction(action, event);
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+
+void Scene500::postInit(SceneObjectList *OwnerList) {
+ SceneExt::postInit();
+ loadScene(500);
+
+ Common::fill(&_buffer[0], &_buffer[2710], 0);
+ _stripManager.setColors(60, 255);
+ _stripManager.setFontNumber(50);
+ _stripManager.addSpeaker(&_seekerSpeaker);
+ _stripManager.addSpeaker(&_quinnSpeaker);
+
+ if (R2_GLOBALS.getFlag(25)) {
+ R2_GLOBALS._player._characterScene[R2_SEEKER] = 500;
+
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
+ R2_GLOBALS._walkRegions.disableRegion(1);
+
+ _object2.postInit();
+ _object2._effect = 1;
+ _object2.setup(1505, 1, 1);
+ _object2._moveDiff.x = 5;
+ _object2.setPosition(Common::Point(42, 151));
+ _object2.setDetails(500, 34, 35, 36, 1, (SceneItem *)NULL);
+ } else if (R2_GLOBALS._player._characterScene[R2_QUINN] == 500) {
+ _object2.postInit();
+ _object2._effect = 1;
+ _object2.setup(R2_GLOBALS.getFlag(26) ? 1500 : 10, 1, 1);
+ _object2.setPosition(Common::Point(42, 151));
+
+ R2_GLOBALS._walkRegions.disableRegion(1);
+ R2_GLOBALS._walkRegions.disableRegion(2);
+ R2_GLOBALS._walkRegions.disableRegion(3);
+
+ _object2.setDetails(500, 37, 38, -1, 1, (SceneItem *)NULL);
+ }
+ }
+
+ if ((R2_INVENTORY.getObjectScene(R2_REBREATHER_TANK) != 500) && R2_GLOBALS.getFlag(27)) {
+ _tanks1.postInit();
+ _tanks1.setup(502, 7, 1);
+ _tanks1.setPosition(Common::Point(281, 120));
+ _tanks1.setDetails(500, -1, -1, -1, 1, (SceneItem *)NULL);
+ } else {
+ if (R2_INVENTORY.getObjectScene(R2_REBREATHER_TANK) == 500) {
+ _tanks1.postInit();
+ _tanks1.setup(502, 7, 1);
+ _tanks1.setPosition(Common::Point(281, 120));
+ _tanks1.setDetails(500, -1, -1, -1, 1, (SceneItem *)NULL);
+ }
+
+ _tanks2.postInit();
+ _tanks2.setup(502, 7, 1);
+ _tanks2.setPosition(Common::Point(286, 121));
+ _tanks2.setDetails(500, -1, -1, -1, 1, (SceneItem *)NULL);
+ }
+
+ _doorway.postInit();
+ _doorway.setup(501, 1, 1);
+ _doorway.setPosition(Common::Point(132, 85));
+ _doorway.setDetails(500, 15, -1, 17, 1, (SceneItem *)NULL);
+
+ _airLock.postInit();
+ _airLock.setup(501, 2, 1);
+ _airLock.setPosition(Common::Point(41, 121));
+
+ if (!R2_GLOBALS.getFlag(25))
+ _airLock.setDetails(500, 6, -1, 10, 1, (SceneItem *)NULL);
+ else if ((R2_GLOBALS._player._characterScene[R2_QUINN] != 500) ||
+ (R2_GLOBALS._player._characterScene[R2_SEEKER] != 500))
+ _airLock.setDetails(500, 6, -1, 40, 1, (SceneItem *)NULL);
+ else
+ _airLock.setDetails(500, 6, -1, 9, 1, (SceneItem *)NULL);
+
+ _locker1.postInit();
+ _locker1.setup(500, 3, R2_GLOBALS.getFlag(11) ? 6 : 1);
+ _locker1.setPosition(Common::Point(220, 82));
+ _locker1.setDetails(500, 27, -1, -1, 1, (SceneItem *)NULL);
+
+ _locker2.postInit();
+ _locker2.setup(500, 4, R2_GLOBALS.getFlag(12) ? 6 : 1);
+ _locker2.setPosition(Common::Point(291, 98));
+ _locker2.fixPriority(121);
+ _locker2.setDetails(500, 27, -1, -1, 1, (SceneItem *)NULL);
+
+ if (R2_INVENTORY.getObjectScene(R2_AEROSOL) == 500) {
+ _aerosol.postInit();
+ _aerosol.setup(500, 5, 2);
+ _aerosol.setPosition(Common::Point(286, 91));
+ _aerosol.fixPriority(120);
+ _aerosol.setDetails(500, 24, 25, 26, 1, (SceneItem *)NULL);
+ }
+
+ if (R2_INVENTORY.getObjectScene(R2_SONIC_STUNNER) == 500) {
+ _sonicStunner.postInit();
+ _sonicStunner.setup(500, 5, 1);
+ _sonicStunner.setPosition(Common::Point(214, 76));
+ _sonicStunner.setDetails(500, 21, 22, 23, 1, (SceneItem *)NULL);
+ }
+
+ _object1.postInit();
+ _object1._effect = 1;
+ _object1.setup(502, 1, 1);
+ _object1.setPosition(Common::Point(258, 99));
+ _object1.fixPriority(50);
+
+ _object8.postInit();
+ _object8.setPosition(Common::Point(250, 111));
+
+ if (!R2_GLOBALS.getFlag(35)) {
+ _object8.setup(501, 3, 1);
+ } else {
+ _object8.setup(500, 8, 7);
+
+ _object3.postInit();
+ _object3._effect = 1;
+ _object3.setPosition(Common::Point(247, 52));
+ _object3.setDetails(500, -1, -1, -1, 2, (SceneItem *)NULL);
+
+ if (!R2_GLOBALS.getFlag(26)) {
+ if (R2_GLOBALS.getFlag(28))
+ _object3.setup(502, 7, 2);
+ else
+ _object3.setup(502, R2_GLOBALS._v566A3 + 2, 7);
+ }
+ }
+
+ R2_GLOBALS._player.postInit();
+ R2_GLOBALS._player.setVisage(10);
+ R2_GLOBALS._player.animate(ANIM_MODE_1, NULL);
+ if (R2_GLOBALS._player._characterIndex == R2_SEEKER)
+ R2_GLOBALS._player._moveDiff.x = 5;
+
+ _controlPanel.setDetails(Rect(175, 62, 191, 80), 500, 31, 32, 33, 1, (SceneItem *)NULL);
+ _item2.setDetails(Rect(13, 58, 70, 118), 500, 12, -1, -1, 1, (SceneItem *)NULL);
+ _background.setDetails(Rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT), 500, 0, -1, -1, 1, (SceneItem *)NULL);
+
+ if ((R2_GLOBALS._player._characterIndex == R2_QUINN) && (R2_GLOBALS._sceneManager._previousScene == 700)) {
+ R2_GLOBALS._player.disableControl();
+ _sceneMode = 501;
+ setAction(&_sequenceManager1, this, 501, &R2_GLOBALS._player, &_doorway, NULL);
+ } else {
+ if (R2_GLOBALS._player._characterIndex != R2_QUINN) {
+ R2_GLOBALS._player.setup(1505, 6, 1);
+ } else {
+ R2_GLOBALS._player.setup(R2_GLOBALS.getFlag(26) ? 1500 : 10, 6, 1);
+ }
+
+ R2_GLOBALS._player.setPosition(Common::Point(123, 135));
+ R2_GLOBALS._player.enableControl();
+ }
+}
+
+void Scene500::synchronize(Serializer &s) {
+ SceneExt::synchronize(s);
+ s.syncAsSint16LE(_stripNumber);
+}
+
+void Scene500::signal() {
+ switch (_sceneMode) {
+ case 3:
+ R2_GLOBALS._player.enableControl();
+ break;
+ case 5:
+ _sceneMode = 12;
+ _sound1.play(127);
+ _object1.animate(ANIM_MODE_6, this);
+
+ R2_GLOBALS.clearFlag(35);
+ _object3.remove();
+ R2_GLOBALS._player.enableControl();
+ break;
+ case 6:
+ _sceneMode = 11;
+ _sound1.play(127);
+ _object1.animate(ANIM_MODE_5, this);
+
+ R2_GLOBALS.clearFlag(35);
+ _object3.remove();
+ R2_GLOBALS._player.enableControl();
+ break;
+ case 7:
+ _sound1.play(126);
+ _object8.animate(ANIM_MODE_6, this);
+
+ R2_GLOBALS.clearFlag(35);
+ _object3.remove();
+ R2_GLOBALS._player.enableControl();
+ break;
+ case 500:
+ R2_GLOBALS._sceneManager.changeScene(700);
+ break;
+ case 501:
+ if (R2_GLOBALS._player._characterScene[R2_QUINN] == 500) {
+ _stripNumber = 1100;
+ _sceneMode = 523;
+ setAction(&_sequenceManager1, this, 523, &R2_GLOBALS._player, NULL);
+ } else {
+ R2_GLOBALS._player.enableControl();
+ }
+ break;
+ case 502:
+ case 520:
+ R2_INVENTORY.setObjectScene(R2_SONIC_STUNNER, 1);
+ _sonicStunner.remove();
+ R2_GLOBALS._player.enableControl();
+ break;
+ case 503:
+ R2_INVENTORY.setObjectScene(R2_AEROSOL, 1);
+ _aerosol.remove();
+ R2_GLOBALS._player.enableControl();
+ break;
+ case 504:
+ case 516:
+ R2_GLOBALS.setFlag(11);
+ R2_GLOBALS._player.enableControl();
+ break;
+ case 505:
+ case 517:
+ R2_GLOBALS.clearFlag(11);
+ R2_GLOBALS._player.enableControl();
+ break;
+ case 506:
+ case 518:
+ R2_GLOBALS.setFlag(11);
+ R2_GLOBALS._player.enableControl();
+ break;
+ case 507:
+ case 519:
+ R2_GLOBALS.clearFlag(12);
+ R2_GLOBALS._player.enableControl();
+ break;
+ case 509:
+ R2_GLOBALS.clearFlag(35);
+ _object3.remove();
+ R2_GLOBALS._player.enableControl();
+ break;
+ case 510:
+ R2_GLOBALS._player.enableControl();
+ _area1.setDetails(500, 6, 1, Common::Point(160, 120));
+ R2_GLOBALS._player.enableControl();
+ break;
+ case 513:
+ R2_INVENTORY.setObjectScene(R2_REBREATHER_TANK, 1);
+ _tanks1.remove();
+ R2_GLOBALS._player.enableControl();
+ break;
+ case 514:
+ R2_INVENTORY.setObjectScene(R2_REBREATHER_TANK, 1);
+ R2_GLOBALS.setFlag(27);
+ _tanks2.remove();
+ R2_GLOBALS._player.enableControl();
+ break;
+ case 515:
+ R2_INVENTORY.setObjectScene(R2_REBREATHER_TANK, 0);
+ R2_GLOBALS.setFlag(28);
+ R2_GLOBALS._player.enableControl();
+ break;
+ case 521:
+ case 522:
+ R2_GLOBALS._sceneManager.changeScene(525);
+ break;
+ case 523:
+ case 524:
+ R2_GLOBALS._events.setCursor(CURSOR_ARROW);
+ _sceneMode = 8;
+ _stripManager.start(_stripNumber, this);
+ break;
+ default:
+ R2_GLOBALS._player.enableControl();
+ break;
+ }
+}
+
+
+/*--------------------------------------------------------------------------
+ * Scene 525 - Cutscene - Walking in hall
+ *
+ *--------------------------------------------------------------------------*/
+void Scene525::postInit(SceneObjectList *OwnerList) {
+ loadScene(525);
+ R2_GLOBALS._uiElements._active = false;
+ SceneExt::postInit();
+
+ R2_GLOBALS._sound1.play(105);
+
+ _actor1.postInit();
+ _actor1._effect = 1;
+
+ R2_GLOBALS._player.postInit();
+ R2_GLOBALS._player.animate(ANIM_MODE_1, NULL);
+ R2_GLOBALS._player.disableControl();
+
+ setAction(&_sequenceManager, this, 525, &R2_GLOBALS._player, &_actor1, NULL);
+}
+
+void Scene525::signal() {
+ R2_GLOBALS._sceneManager.changeScene(1525);
+}
+
+/*--------------------------------------------------------------------------
+ * Scene 600 -
+ *
+ *--------------------------------------------------------------------------*/
+Scene600::Scene600() {
+ _field412 = 0;
+ for (int i = 0; i < 256; i++)
+ _fieldAD2[i] = 0;
+}
+
+void Scene600::synchronize(Serializer &s) {
+ SceneExt::synchronize(s);
+
+ s.syncAsSint16LE(_field412);
+ for (int i = 0; i < 256; i++)
+ s.syncAsByte(_fieldAD2[i]);
+}
+
+bool Scene600::Item1::startAction(CursorType action, Event &event) {
+ if ((action != R2_NEGATOR_GUN) || (!R2_GLOBALS.getFlag(5)) || (R2_GLOBALS.getFlag(8)))
+ return SceneHotspot::startAction(action, event);
+
+ SceneItem::display(600, 32, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
+ return true;
+}
+
+bool Scene600::Item4::startAction(CursorType action, Event &event) {
+ if ((action != R2_NEGATOR_GUN) || (!R2_GLOBALS.getFlag(1)))
+ return SceneHotspot::startAction(action, event);
+
+ if ((R2_GLOBALS.getFlag(5)) && (!R2_GLOBALS.getFlag(8))) {
+ SceneItem::display(600, 32, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
+ return true;
+ }
+
+ if (R2_GLOBALS.getFlag(5)) {
+ SceneItem::display(600, 30, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
+ return true;
+ }
+
+ if ((!R2_GLOBALS.getFlag(8)) || (R2_GLOBALS.getFlag(9)))
+ return SceneHotspot::startAction(action, event);
+
+ R2_GLOBALS._player.disableControl();
+
+ Scene600 *scene = (Scene600 *)R2_GLOBALS._sceneManager._scene;
+
+ scene->_object1.setup2(603, 3, 1, 239, 54, 10, 0);
+ scene->_actor3.postInit();
+ scene->_actor2.postInit();
+
+ scene->_sceneMode = 612;
+ setAction(&scene->_sequenceManager1, this, 612, &scene->_actor3, &scene->_actor2, &R2_GLOBALS._player, NULL);
+ return true;
+}
+
+void Scene600::Actor4::signal() {
+ Common::Point pt(36, 177 + R2_GLOBALS._randomSource.getRandomNumber(5));
+ NpcMover *mover = new NpcMover();
+ addMover(mover, &pt, this);
+}
+
+bool Scene600::Actor4::startAction(CursorType action, Event &event) {
+ if ((action >= CURSOR_WALK) && (action < R2CURSORS_START))
+ // Only action cursors
+ return SceneActor::startAction(action, event);
+
+ return false;
+}
+
+void Scene600::Actor4::draw() {
+ warning("TODO: Actor4::draw()");
+ SceneActor::draw();
+}
+
+bool Scene600::Actor5::startAction(CursorType action, Event &event) {
+ if ((action < CURSOR_WALK) && (action >= R2CURSORS_START))
+ return false;
+
+ if (action != CURSOR_USE)
+ return SceneActor::startAction(action, event);
+
+ Scene600 *scene = (Scene600 *)R2_GLOBALS._sceneManager._scene;
+
+ if ((R2_INVENTORY.getObjectScene(R2_CLAMP) == 600) && (!R2_GLOBALS.getFlag(6))) {
+ R2_GLOBALS._player.disableControl();
+ scene->_actor6.setDetails(600, 11, -1, -1, 3, (SceneItem *) NULL);
+ R2_GLOBALS.setFlag(6);
+ scene->_sceneMode = 609;
+ scene->setAction(&scene->_sequenceManager1, scene, 609, &R2_GLOBALS._player, &scene->_actor5, &scene->_actor6, &scene->_actor1, NULL);
+ return true;
+ }
+
+ if (_frame != 1)
+ return false;
+
+ if (!R2_GLOBALS.getFlag(6)) {
+ R2_GLOBALS._player.disableControl();
+ scene->_sceneMode = 616;
+ scene->setAction(&scene->_sequenceManager1, scene, 616, &R2_GLOBALS._player, &scene->_actor5, &scene->_actor6, NULL);
+ return true;
+ }
+
+ if ((R2_GLOBALS.getFlag(9)) && (R2_INVENTORY.getObjectScene(R2_COM_SCANNER) == 600))
+ SceneItem::display(600, 31, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
+ else {
+ R2_GLOBALS._player.disableControl();
+ scene->_sceneMode = 601;
+ scene->setAction(&scene->_sequenceManager1, scene, 601, &R2_GLOBALS._player, &scene->_actor5, NULL);
+ }
+ return true;
+}
+
+bool Scene600::Actor6::startAction(CursorType action, Event &event) {
+ Scene600 *scene = (Scene600 *)R2_GLOBALS._sceneManager._scene;
+
+ if ((action < CURSOR_WALK) && (action >= R2CURSORS_START)) {
+ switch (action) {
+ case R2_COM_SCANNER:
+ if (R2_GLOBALS.getFlag(6)) {
+ if (R2_GLOBALS.getFlag(8)) {
+ SceneItem::display(600, 29, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
+ return true;
+ } else {
+ R2_GLOBALS._player.disableControl();
+ scene->_actor8.postInit();
+ scene->_actor8.setDetails(600, 20, -1, -1, 4, &scene->_actor6);
+ scene->_sceneMode = 607;
+ scene->setAction(&scene->_sequenceManager1, scene, 607, &R2_GLOBALS._player, &scene->_actor8, NULL);
+ return true;
+ }
+ } else {
+ return SceneActor::startAction(action, event);
+ }
+ break;
+ case R2_AEROSOL:
+ if (R2_GLOBALS.getFlag(5)) {
+ SceneItem::display(600, 28, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
+ return true;
+ } else {
+ R2_GLOBALS._player.disableControl();
+ scene->_actor7.postInit();
+ scene->_actor7.setDetails(600, 27, -1, -1, 5, &scene->_actor6);
+
+ scene->_actor4.postInit();
+ scene->_actor4.setup(601, 3, 1);
+ scene->_actor4._effect = 3;
+ scene->_actor4._moveDiff = Common::Point(1, 1);
+ scene->_actor4._moveRate = 2;
+ scene->_actor4._numFrames = 3;
+ scene->_actor4.setDetails(600, 24, 25, 26, 5, &scene->_actor7);
+
+ scene->_sceneMode = 605;
+
+ scene->setAction(&scene->_sequenceManager1, scene, 605, &R2_GLOBALS._player, &scene->_actor7, &scene->_actor4, &scene->_actor5, NULL);
+ return true;
+ }
+ break;
+ case R2_CLAMP:
+ if (R2_GLOBALS.getFlag(5)) {
+ R2_GLOBALS._player.disableControl();
+ scene->_sceneMode = 606;
+ scene->setAction(&scene->_sequenceManager1, scene, 606, &R2_GLOBALS._player, &scene->_actor6, NULL);
+ return true;
+ } else {
+ return SceneActor::startAction(action, event);
+ }
+ break;
+ default:
+ return false;
+ break;
+ }
+ } else if (action != CURSOR_USE) {
+ if (R2_GLOBALS.getFlag(5)) {
+ return SceneActor::startAction(action, event);
+ } else {
+ R2_GLOBALS._player.disableControl();
+ scene->_sceneMode = 610;
+ scene->setAction(&scene->_sequenceManager1, scene, 610, &scene->_actor1, &R2_GLOBALS._player, NULL);
+ return true;
+ }
+ } else
+ return SceneActor::startAction(action, event);
+}
+
+bool Scene600::Actor7::startAction(CursorType action, Event &event) {
+ Scene600 *scene = (Scene600 *)R2_GLOBALS._sceneManager._scene;
+
+ if ((action < CURSOR_WALK) && (action >= R2CURSORS_START)) {
+ return false;
+ } else if (action == CURSOR_USE) {
+ R2_GLOBALS._player.disableControl();
+ scene->_sceneMode = 614;
+ scene->setAction(&scene->_sequenceManager1, scene, 614, &R2_GLOBALS._player, &scene->_actor7, NULL);
+ return true;
+ } else {
+ return SceneActor::startAction(action, event);
+ }
+}
+
+bool Scene600::Actor8::startAction(CursorType action, Event &event) {
+ Scene600 *scene = (Scene600 *)R2_GLOBALS._sceneManager._scene;
+
+ if ((action == CURSOR_USE) && (R2_INVENTORY.getObjectScene(9) == 600)) {
+ R2_GLOBALS._player.disableControl();
+ scene->_sceneMode = 615;
+ scene->setAction(&scene->_sequenceManager1, scene, 615, &R2_GLOBALS._player, &scene->_actor8, NULL);
+ } else if ((action == R2_SONIC_STUNNER) && (R2_INVENTORY.getObjectScene(9) == 600) && (R2_GLOBALS._v565F1[1] == 2) && (!R2_GLOBALS.getFlag(8))){
+ R2_GLOBALS._player.disableControl();
+ scene->_sceneMode = 608;
+ scene->setAction(&scene->_sequenceManager1, scene, 608, &R2_GLOBALS._player, &scene->_actor4, NULL);
+ } else {
+ return SceneActor::startAction(action, event);
+ }
+
+ return true;
+}
+
+void Scene600::postInit(SceneObjectList *OwnerList) {
+ loadScene(600);
+ SceneExt::postInit();
+ R2_GLOBALS.setFlag(39);
+ R2_GLOBALS._walkRegions.enableRegion(3);
+ _field412 = 0;
+
+ warning("FIXME: loop to initialize _fieldAD2[]");
+
+ _actor5.postInit();
+ _actor5.setVisage(600);
+ _actor5.setPosition(Common::Point(29, 147));
+ _actor5.fixPriority(10);
+ _actor5.setDetails(300, 3, -1, -1, 1, (SceneItem *) NULL);
+
+ _actor6.postInit();
+ _actor6.setPosition(Common::Point(246, 41));
+
+ if (R2_INVENTORY.getObjectScene(9) == 600) {
+ _actor8.postInit();
+ _actor8.setup(602, 5, 1);
+ _actor8.setPosition(Common::Point(246, 41));
+ _actor8.setDetails(600, 20, -1, -1, 1, (SceneItem *) NULL);
+ switch (R2_GLOBALS._v565F1[1] - 2) {
+ case 0:
+ R2_GLOBALS._sound4.play(45);
+ break;
+ case 1:
+ R2_GLOBALS._sound4.play(4);
+ break;
+ case 2:
+ R2_GLOBALS._sound4.play(5);
+ break;
+ case 3:
+ R2_GLOBALS._sound4.play(6);
+ break;
+ default:
+ break;
+ }
+ }
+
+ if (R2_GLOBALS.getFlag(6)) {
+ _actor6.setup(602, 7, 1);
+ _actor6.setDetails(600, 11, -1, -1, 1, (SceneItem *) NULL);
+ } else {
+ _actor6.setup(600, 2, 1);
+ _actor6.setDetails(600, 10, -1, -1, 1, (SceneItem *) NULL);
+
+ _actor1.postInit();
+ _actor1.setup(600, 3, 5);
+ _actor1.setPosition(Common::Point(223, 51));
+ _actor1.fixPriority(200);
+ }
+
+ if (! R2_GLOBALS.getFlag(9))
+ _object1.setup2(603, 1, 1, 244, 50, 10, 0);
+
+ if (R2_GLOBALS.getFlag(5)) {
+ if (R2_INVENTORY.getObjectScene(12) == 600) {
+ _actor7.postInit();
+ _actor7.setup(602, 2, 2);
+ _actor7.setPosition(Common::Point(189, 95));
+ _actor7.setDetails(600, 27, -1, -1, 1, (SceneItem *) NULL);
+ }
+
+ if (R2_GLOBALS.getFlag(8)) {
+ if (R2_GLOBALS.getFlag(9)) {
+ _actor2.postInit();
+ _actor2.setup(603, 2, 1);
+ _actor2.setPosition(Common::Point(233, 45));
+ _actor2.animate(ANIM_MODE_2, NULL);_actor2.fixPriority(11);
+ }
+ } else {
+ _actor4.postInit();
+ _actor4.setup(601, 1, 1);
+ _actor4.setPosition(Common::Point(180, 110));
+ _actor4._moveDiff = Common::Point(1, 1);
+ _actor4._moveRate = 2;
+ _actor4._numFrames = 3;
+ _actor4.animate(ANIM_MODE_2, NULL);
+ _actor4.fixPriority(130);
+ _actor4._effect = 3;
+ _actor4.setDetails(600, 24, 25, 26, 1, (SceneItem *) NULL);
+ _actor4.signal();
+ }
+ }
+
+ R2_GLOBALS._player.postInit();
+ R2_GLOBALS._player.setVisage(10);
+ R2_GLOBALS._player.animate(ANIM_MODE_1, NULL);
+ R2_GLOBALS._player.disableControl();
+
+ _item2.setDetails(12, 600, 17, -1, 19);
+ _item3.setDetails(11, 600, 14, -1, -1);
+
+ if (R2_GLOBALS.getFlag(9)) {
+ _item1.setDetails(Rect(159, 3, 315, 95), 600, 7, -1, -1, 1, NULL);
+ } else {
+ _item4.setDetails(Rect(173, 15, 315, 45), 600, 21, -1, 23, 1, NULL);
+ _item1.setDetails(Rect(159, 3, 315, 95), 600, 6, -1, -1, 1, NULL);
+ }
+ _item5.setDetails(Rect(0, 0, 320, 200), 600, 0, -1, -1, 1, NULL);
+
+ _sceneMode = 600;
+ if (R2_GLOBALS._sceneManager._previousScene == 700) {
+ if (R2_GLOBALS.getFlag(6)) {
+ setAction(&_sequenceManager1, this, 600, &R2_GLOBALS._player, &_actor5, NULL);
+ } else if (R2_GLOBALS.getFlag(5)) {
+ setAction(&_sequenceManager1, this, 603, &R2_GLOBALS._player, &_actor5, &_actor6, &_actor1, NULL);
+ } else {
+ setAction(&_sequenceManager1, this, 602, &R2_GLOBALS._player, &_actor5, &_actor6, &_actor1, NULL);
+ }
+ } else if (R2_GLOBALS.getFlag(5)) {
+ R2_GLOBALS._player.setPosition(Common::Point(50, 140));
+ R2_GLOBALS._player.setStrip(3);
+ _actor6.setFrame(_actor6.getFrameCount());
+ signal();
+ } else {
+ _actor5.setFrame(7);
+ _actor6.setFrame(7);
+ R2_GLOBALS._player.setPosition(Common::Point(28, 140));
+ R2_GLOBALS._player.setStrip(5);
+ signal();
+ }
+}
+
+void Scene600::remove() {
+ if (R2_INVENTORY.getObjectScene(9) == 600)
+ R2_GLOBALS._sound4.fadeOut2(NULL);
+ SceneExt::remove();
+}
+
+void Scene600::signal() {
+ switch (_sceneMode) {
+ case 601:
+ // No break on purpose
+ case 613:
+ // No break on purpose
+ case 616:
+ R2_GLOBALS._sceneManager.changeScene(700);
+ break;
+ case 605:
+ R2_GLOBALS._player.enableControl();
+ R2_GLOBALS._walkRegions.enableRegion(6);
+ R2_GLOBALS._walkRegions.enableRegion(7);
+ R2_GLOBALS._walkRegions.enableRegion(9);
+ R2_GLOBALS._walkRegions.enableRegion(10);
+
+ R2_INVENTORY.setObjectScene(12, 600);
+ R2_GLOBALS.setFlag(5);
+
+ _actor4._effect = 3;
+ _actor4.signal();
+ break;
+ case 606:
+ R2_INVENTORY.setObjectScene(15, 600);
+ R2_GLOBALS._player.enableControl();
+ break;
+ case 607:
+ R2_INVENTORY.setObjectScene(9, 600);
+ R2_GLOBALS._player.enableControl();
+ break;
+ case 608:
+ R2_GLOBALS.setFlag(8);
+ _actor4.remove();
+ R2_GLOBALS._walkRegions.disableRegion(6);
+ R2_GLOBALS._walkRegions.disableRegion(9);
+ R2_GLOBALS._walkRegions.disableRegion(10);
+ R2_GLOBALS._player.enableControl();
+ break;
+ case 612:
+ R2_GLOBALS.setFlag(9);
+ _actor3.remove();
+ R2_GLOBALS._sceneItems.remove(&_item4);
+ _actor2.setDetails(600, 21, -1, 23, 4, &_item4);
+ _item1.setDetails(600, 7, -1, -1, 3, (SceneItem *) NULL);
+ R2_GLOBALS._player.enableControl(CURSOR_USE);
+ break;
+ case 614:
+ R2_GLOBALS._player.enableControl();
+ _actor7.remove();
+ R2_INVENTORY.setObjectScene(12, 1);
+ R2_GLOBALS._walkRegions.disableRegion(7);
+ break;
+ case 615:
+ _actor8.remove();
+ R2_INVENTORY.setObjectScene(9, 1);
+ R2_GLOBALS._player.enableControl();
+ break;
+ default:
+ _field412 = 0;
+ _sceneMode = 0;
+ R2_GLOBALS._player.enableControl();
+ break;
+ }
+}
+
+void Scene600::process(Event &event) {
+ if ((!R2_GLOBALS._player._canWalk) && (!R2_GLOBALS.getFlag(6)) && (event.eventType == EVENT_BUTTON_DOWN) && (R2_GLOBALS._events.getCursor() == R2_NEGATOR_GUN)) {
+ if (!_actor5.contains(event.mousePos) || (_actor5._frame <= 1)) {
+ if (R2_GLOBALS.getFlag(5)) {
+ _field412 += 10;
+ } else {
+ R2_GLOBALS._player.disableControl();
+ _sceneMode = 604;
+ setAction(&_sequenceManager1, this, 604, &_actor1, &R2_GLOBALS._player, NULL);
+ event.handled = true;
+ }
+ } else {
+ R2_GLOBALS._player.disableControl();
+ _sceneMode = 613;
+ setAction(&_sequenceManager1, this, 613, &R2_GLOBALS._player, &_actor6, NULL);
+ event.handled = true;
+ }
+ } else if ((!R2_GLOBALS.getFlag(6)) && (R2_GLOBALS._player._mover) && (_field412 < 10)){
+ _field412 += 10;
+ }
+
+ Scene::process(event);
+}
+
+void Scene600::dispatch() {
+ if ((_field412 != 0) && (_sceneMode != 600) && (_sceneMode != 603) && (_sceneMode != 602)) {
+ if ( ((_actor6._strip == 4) && (_actor6._frame > 1))
+ || (_sceneMode == 601)
+ || ((_sceneMode == 616) && (_actor5._frame > 1)) )
+ _field412 = 0;
+ else {
+ _field412--;
+ if (_field412 % 10 == 0) {
+ _actor1.setAction(&_sequenceManager2, NULL, 611, &_actor1, NULL);
+ }
+ if ((_field412 == 0) && (R2_GLOBALS._player._mover))
+ _field412 = 10;
+ }
+ }
+
+ if (_actor1._frame == 2)
+ _aSound1.play(40);
+
+ Scene::dispatch();
+ if ((_actor4._strip == 3) && (_actor4._frame == 3)) {
+ _actor1.setStrip(4);
+ _actor1.setFrame(1);
+ }
+}
+
+/*--------------------------------------------------------------------------
+ * Scene 700 -
+ *
+ *--------------------------------------------------------------------------*/
+Scene700::Scene700() {
+ _rotation = NULL;
+}
+
+void Scene700::synchronize(Serializer &s) {
+ SceneExt::synchronize(s);
+ SYNC_POINTER(_rotation);
+}
+
+bool Scene700::Item11::startAction(CursorType action, Event &event) {
+ if ((action == CURSOR_USE) && (R2_GLOBALS._player._position.x < 100))
+ return false;
+
+ return NamedHotspot::startAction(action, event);
+}
+
+bool Scene700::Item12::startAction(CursorType action, Event &event) {
+ Scene700 *scene = (Scene700 *)R2_GLOBALS._sceneManager._scene;
+
+ switch (action) {
+ case R2_CABLE_HARNESS:
+ R2_GLOBALS._player.disableControl();
+ scene->_actor5.postInit();
+ scene->_actor5.setup(701, 3, 2);
+ scene->_actor5.setPosition(Common::Point(243, 98));
+ scene->_actor5.setDetails(700, 37, -1, -1, 2, (SceneItem *) NULL);
+ scene->_actor5.hide();
+ scene->_sceneMode = 20;
+ break;
+ case R2_ATTRACTOR_CABLE_HARNESS:
+ R2_GLOBALS._player.disableControl();
+ scene->_actor5.postInit();
+ scene->_actor5.setup(701, 2, 8);
+ scene->_actor5.setPosition(Common::Point(243, 98));
+ scene->_actor5.setDetails(700, 38, -1, -1, 2, (SceneItem *) NULL);
+ scene->_actor5.hide();
+ scene->_sceneMode = 21;
+ break;
+ default:
+ return NamedHotspot::startAction(action, event);
+ break;
+ }
+
+ scene->setAction(&scene->_sequenceManager, this, 707, &R2_GLOBALS._player, &scene->_actor5, NULL);
+ return true;
+}
+
+bool Scene700::Actor2::startAction(CursorType action, Event &event) {
+ Scene700 *scene = (Scene700 *)R2_GLOBALS._sceneManager._scene;
+
+ if (action != CURSOR_USE)
+ return SceneActor::startAction(action, event);
+
+ if (R2_GLOBALS._player._position.y <= 100)
+ return false;
+
+ R2_GLOBALS._player.disableControl();
+ scene->_sceneMode = 701;
+ scene->setAction(&scene->_sequenceManager, scene, 701, &R2_GLOBALS._player, this, NULL);
+
+ return true;
+}
+
+bool Scene700::Actor3::startAction(CursorType action, Event &event) {
+ Scene700 *scene = (Scene700 *)R2_GLOBALS._sceneManager._scene;
+
+ if (action != CURSOR_USE)
+ return SceneActor::startAction(action, event);
+
+ if (R2_GLOBALS._player._position.y <= 100)
+ return false;
+
+ R2_GLOBALS._player.disableControl();
+ scene->_sceneMode = 702;
+ scene->setAction(&scene->_sequenceManager, scene, 702, &R2_GLOBALS._player, this, NULL);
+
+ return true;
+}
+
+bool Scene700::Actor4::startAction(CursorType action, Event &event) {
+ Scene700 *scene = (Scene700 *)R2_GLOBALS._sceneManager._scene;
+
+ if (action != CURSOR_USE)
+ return SceneActor::startAction(action, event);
+
+ if (R2_GLOBALS._player._position.y <= 100)
+ return false;
+
+ R2_GLOBALS._player.disableControl();
+ scene->_sceneMode = 704;
+ scene->setAction(&scene->_sequenceManager, scene, 704, &R2_GLOBALS._player, this, NULL);
+
+ return true;
+}
+
+bool Scene700::Actor5::startAction(CursorType action, Event &event) {
+ Scene700 *scene = (Scene700 *)R2_GLOBALS._sceneManager._scene;
+
+ switch (action) {
+ case CURSOR_USE:
+ switch (R2_INVENTORY.getObjectScene(R2_CABLE_HARNESS)) {
+ case 0:
+ if ((_strip == 2) && (_frame == 1)) {
+ R2_GLOBALS._player.disableControl();
+ if (R2_GLOBALS._player._position.x <= 100) {
+ scene->_sceneMode = 710;
+ scene->setAction(&scene->_sequenceManager, scene, 710, &R2_GLOBALS._player, this, NULL);
+ } else {
+ scene->_sceneMode = 709;
+ scene->setAction(&scene->_sequenceManager, scene, 709, &R2_GLOBALS._player, this, NULL);
+ }
+ } else {
+ return SceneActor::startAction(action, event);
+ }
+ break;
+ case 700: {
+ R2_GLOBALS._player.disableControl();
+ scene->_sceneMode = 10;
+ Common::Point pt(_position.x - 12, _position.y + 1);
+ PlayerMover *mover = new PlayerMover();
+ R2_GLOBALS._player.addMover(mover, &pt, scene);
+ }
+ break;
+ default:
+ break;
+ }
+ break;
+ case R2_ATTRACTOR_UNIT:
+ R2_GLOBALS._player.disableControl();
+ if (R2_INVENTORY.getObjectScene(R2_CABLE_HARNESS) == 700) {
+ scene->_sceneMode = 706;
+ scene->setAction(&scene->_sequenceManager, scene, 706, &R2_GLOBALS._player, &scene->_actor5, NULL);
+ } else {
+ scene->_sceneMode = 15;
+ Common::Point pt(_position.x - 12, _position.y + 1);
+ PlayerMover *mover = new PlayerMover();
+ R2_GLOBALS._player.addMover(mover, &pt, scene);
+ }
+ break;
+ default:
+ return SceneActor::startAction(action, event);
+ break;
+ }
+
+ return true;
+}
+
+bool Scene700::Actor6::startAction(CursorType action, Event &event) {
+ Scene700 *scene = (Scene700 *)R2_GLOBALS._sceneManager._scene;
+
+ if ((action != CURSOR_USE) || (R2_GLOBALS._player._position.y >= 100))
+ return SceneActor::startAction(action, event);
+
+ R2_GLOBALS._player.disableControl();
+ scene->_sceneMode = 1;
+ Common::Point pt(_position.x, 69);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, scene);
+
+ return true;
+}
+
+void Scene700::postInit(SceneObjectList *OwnerList) {
+ if (R2_GLOBALS._sceneManager._previousScene == 900)
+ g_globals->gfxManager()._bounds.moveTo(Common::Point(160, 0));
+
+ loadScene(700);
+ R2_GLOBALS._v558B6.set(60, 0, 260, 200);
+ SceneExt::postInit();
+
+ _rotation = R2_GLOBALS._scenePalette.addRotation(237, 246, -1);
+ _rotation->setDelay(5);
+ _rotation->_countdown = 1;
+
+ _actor2.postInit();
+ _actor2.setVisage(700);
+ _actor2.setPosition(Common::Point(21, 128));
+ _actor2.fixPriority(10);
+ _actor2.setDetails(700, 3, -1, -1, 1, (SceneItem *) NULL);
+
+ _actor3.postInit();
+ _actor3.setup(700, 2, 1);
+ _actor3.setPosition(Common::Point(217, 120));
+ _actor3.fixPriority(10);
+ _actor3.setDetails(700, 15, -1, -1, 1, (SceneItem *) NULL);
+
+ _actor1.postInit();
+ _actor1.setup(700, 4, 1);
+ _actor1.setPosition(Common::Point(355 - ((R2_GLOBALS._v565E3 * 8) / 5), ((R2_GLOBALS._v565E1 + 20 ) / 5) - 12));
+ _actor1.fixPriority(10);
+ _actor1.setDetails(700, 12, -1, 14, 1, (SceneItem *) NULL);
+
+ _actor6.postInit();
+ _actor6.setup(700, 8, 1);
+ _actor6.setPosition(Common::Point(85, 53));
+ _actor6.setDetails(700, 33, -1, 35, 1, (SceneItem *) NULL);
+
+ _actor7.postInit();
+ _actor7.setup(700, 8, 1);
+ _actor7.setPosition(Common::Point(164, 53));
+ _actor7.setDetails(700, 33, -1, 35, 1, (SceneItem *) NULL);
+
+ _actor8.postInit();
+ _actor8.setup(700, 8, 1);
+ _actor8.setPosition(Common::Point(243, 53));
+ _actor8.setDetails(700, 33, -1, 35, 1, (SceneItem *) NULL);
+
+ _actor9.postInit();
+ _actor9.setup(700, 8, 1);
+ _actor9.setPosition(Common::Point(324, 53));
+ _actor9.setDetails(700, 33, -1, 35, 1, (SceneItem *) NULL);
+
+ if ((R2_INVENTORY.getObjectScene(R2_CABLE_HARNESS) != 1) && (R2_INVENTORY.getObjectScene(R2_ATTRACTOR_CABLE_HARNESS) != 1)) {
+ _actor5.postInit();
+ _actor5.fixPriority(10);
+ switch (R2_INVENTORY.getObjectScene(R2_ATTRACTOR_CABLE_HARNESS)) {
+ case 0:
+ switch (R2_INVENTORY.getObjectScene(R2_CABLE_HARNESS)) {
+ case 0:
+ _actor5.setup(701, 3, 2);
+ _actor5.setPosition(Common::Point(243, 98));
+ _actor5.setDetails(700, 37, -1, -1, 1, (SceneItem *) NULL);
+ break;
+ case 700:
+ _actor5.setup(701, 3, 1);
+ _actor5.setPosition(Common::Point(356 - (R2_GLOBALS._v565EB * 8), 148 - (((R2_GLOBALS._v565E9 + 10) / 5) * 4)));
+ _actor5.setDetails(700, 37, -1, -1, 1, (SceneItem *) NULL);
+ break;
+ default:
+ break;
+ }
+ break;
+ case 700:
+ switch (R2_INVENTORY.getObjectScene(R2_CABLE_HARNESS)) {
+ case 0:
+ if ((R2_GLOBALS._v565E5 != 0) && (R2_GLOBALS._v565E1 == 20) && (R2_GLOBALS._v565E3 == 70))
+ _actor5.setup(701, 2, 1);
+ else
+ _actor5.setup(701, 2, 8);
+ _actor5.setPosition(Common::Point(243, 98));
+ _actor5.fixPriority(77);
+ _actor5.setDetails(700, 38, -1, -1, 1, (SceneItem *) NULL);
+ break;
+ case 700:
+ _actor5.setup(701, 1, 8);
+ if (R2_GLOBALS._v565E7 == 0) {
+ _actor5.setPosition(Common::Point(356 - (R2_GLOBALS._v565EB * 8), 148 - (((R2_GLOBALS._v565E9 + 10) / 5) * 4)));
+ } else {
+ _actor5.setup(701, 1, 1);
+ _actor5.setPosition(Common::Point(_actor1._position.x + 1, _actor1._position.y + 120));
+ }
+ _actor5.setDetails(700, 38, -1, -1, 1, (SceneItem *) NULL);
+ break;
+ default:
+ break;
+ }
+ default:
+ break;
+ }
+ }
+
+ _actor4.postInit();
+ _actor4.setup(700, 3, 1);
+ _actor4.setPosition(Common::Point(454, 117));
+ _actor4.setDetails(700, 27, -1, -1, 1, (SceneItem *) NULL);
+
+ _item12.setDetails(Rect(234, 90, 252, 110), 700, 39, -1, -1, 1, NULL);
+ _item6.setDetails(Rect(91, 158, 385, 167), 700, 6, -1, 8, 1, NULL);
+ _item2.setDetails(Rect(47, 115, 149, 124), 700, 40, -1, 41, 1, NULL);
+ _item3.setDetails(Rect(151, 108, 187, 124), 700, 40, -1, 41, 1, NULL);
+ _item4.setDetails(Rect(247, 108, 275, 124), 700, 40, -1, 41, 1, NULL);
+ _item5.setDetails(Rect(300, 105, 321, 124), 700, 40, -1, 41, 1, NULL);
+ _item7.setDetails(Rect(255, 74, 368, 115), 700, 9, -1, 11, 1, NULL);
+ _item8.setDetails(Rect(69, 74, 182, 115), 700, 9, -1, 11, 1, NULL);
+ _item9.setDetails(Rect(370, 58, 475, 103), 700, 18, -1, -1, 1, NULL);
+ _item10.setDetails(Rect(17, 11, 393, 31), 700, 24, -1, -1, 1, NULL);
+ _item11.setDetails(Rect(42, 32, 368, 66), 700, 30, -1, 32, 1, NULL);
+ _item1.setDetails(Rect(0, 0, 480, 200), 700, 0, -1, -1, 1, NULL);
+
+ R2_GLOBALS._player.postInit();
+ R2_GLOBALS._player.setVisage(11);
+ R2_GLOBALS._player.animate(ANIM_MODE_1, NULL);
+ R2_GLOBALS._player._moveDiff.x = 2;
+ R2_GLOBALS._player.disableControl();
+
+ R2_GLOBALS._sound1.play(34);
+
+ _sceneMode = 700;
+
+ switch (R2_GLOBALS._sceneManager._previousScene) {
+ case 250:
+ setAction(&_sequenceManager, this, 700, &R2_GLOBALS._player, &_actor2, NULL);
+ break;
+ case 500:
+ setAction(&_sequenceManager, this, 703, &R2_GLOBALS._player, &_actor3, NULL);
+ break;
+ case 600: {
+ _sceneMode = 4;
+ _actor7.setFrame(5);
+ R2_GLOBALS._player.setPosition(Common::Point(164, 74));
+ R2_GLOBALS._player.setStrip2(3);
+ Common::Point pt(164, 69);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, this);
+ }
+ break;
+ case 900:
+ setAction(&_sequenceManager, this, 705, &R2_GLOBALS._player, &_actor4, NULL);
+ break;
+ default:
+ if (R2_GLOBALS.getFlag(41))
+ R2_GLOBALS._player.setPosition(Common::Point(107, 67));
+ else
+ R2_GLOBALS._player.setPosition(Common::Point(60, 140));
+ R2_GLOBALS._player.setStrip(3);
+ R2_GLOBALS._player.enableControl(CURSOR_ARROW);
+ break;
+ }
+}
+
+void Scene700::remove() {
+ R2_GLOBALS._sound1.play(10);
+// CHECKME: Present in the original... But it crashes badly.
+// The instruction was removed as it's not used in other scene coded the same way
+// and reversed by dreammaster. A double check is required in order to verify it doesn't hide
+// a memory leak
+// _rotation->remove();
+ SceneExt::remove();
+}
+
+void Scene700::signal() {
+ switch (_sceneMode) {
+ case 1:
+ _sceneMode = 2;
+ R2_GLOBALS._player.setStrip(4);
+ if (R2_GLOBALS._player._position.x != 164) {
+ SceneItem::display(700, 36, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
+ R2_GLOBALS._player.enableControl();
+ } else {
+ R2_GLOBALS._sound2.play(19);
+ _actor7.animate(ANIM_MODE_5, this);
+ }
+ break;
+ case 2: {
+ _sceneMode = 3;
+ R2_GLOBALS._player.setStrip2(4);
+ Common::Point pt(R2_GLOBALS._player._position.x, R2_GLOBALS._player._position.y + 5);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, this);
+ }
+ break;
+ case 3:
+ R2_INVENTORY.setObjectScene(5, 600);
+ R2_INVENTORY.setObjectScene(16, 700);
+ R2_GLOBALS._player.enableControl();
+ break;
+ case 4:
+ _sceneMode = 5;
+ R2_GLOBALS._player.setStrip2(-1);
+ R2_GLOBALS._player.setObjectWrapper(new SceneObjectWrapper());
+ R2_GLOBALS._sound2.play(19);
+ _actor7.animate(ANIM_MODE_6, this);
+ R2_GLOBALS._player.setStrip(3);
+ R2_GLOBALS.setFlag(41);
+ break;
+ case 10:
+ _sceneMode = 11;
+ R2_GLOBALS._player.setup(16, 7, 1);
+ R2_GLOBALS._player.changeZoom(50);
+ R2_GLOBALS._player.animate(ANIM_MODE_5, this);
+ break;
+ case 11:
+ _sceneMode = 12;
+ _actor5.remove();
+ R2_GLOBALS._player.animate(ANIM_MODE_6, this);
+ break;
+ case 12:
+ R2_GLOBALS._player.setVisage(11);
+ R2_GLOBALS._player.changeZoom(100);
+ R2_GLOBALS._player.animate(ANIM_MODE_1, NULL);
+ R2_GLOBALS._player.setObjectWrapper(new SceneObjectWrapper());
+ R2_GLOBALS._player._strip = 7;
+ if (R2_INVENTORY.getObjectScene(R2_ATTRACTOR_UNIT) == 0) {
+ R2_INVENTORY.setObjectScene(R2_ATTRACTOR_CABLE_HARNESS, 1);
+ R2_INVENTORY.setObjectScene(R2_CABLE_HARNESS, 0);
+ } else {
+ R2_INVENTORY.setObjectScene(R2_CABLE_HARNESS, 1);
+ }
+ R2_GLOBALS._player.enableControl();
+ break;
+ case 15:
+ _sceneMode = 16;
+ R2_GLOBALS._player.setup(16, 7, 1);
+ R2_GLOBALS._player.changeZoom(50);
+ R2_GLOBALS._player.animate(ANIM_MODE_5, this);
+ break;
+ case 16:
+ _sceneMode = 17;
+ _actor5.setup(701, 1, 8);
+ _actor5.setDetails(700, 38, -1, -1, 3, (SceneItem *) NULL);
+ if ((R2_GLOBALS._v565E5 != 0) && (_actor5._position.x == _actor1._position.x + 1) && (_actor5._position.x == 148 - (((R2_GLOBALS._v565E1 + 10) / 5) * 4))) {
+ _actor5.animate(ANIM_MODE_6, NULL);
+ Common::Point pt(_actor5._position.x, _actor1._position.y + 120);
+ NpcMover *mover = new NpcMover();
+ _actor5.addMover(mover, &pt, NULL);
+ R2_GLOBALS._v565E7 = 1;
+ }
+ R2_GLOBALS._player.animate(ANIM_MODE_6, this);
+ break;
+ case 17:
+ R2_INVENTORY.setObjectScene(R2_ATTRACTOR_UNIT, 0);
+ R2_INVENTORY.setObjectScene(R2_ATTRACTOR_CABLE_HARNESS, 700);
+ R2_GLOBALS._player.setVisage(11);
+ R2_GLOBALS._player.changeZoom(100);
+ R2_GLOBALS._player.animate(ANIM_MODE_1, NULL);
+ R2_GLOBALS._player.setObjectWrapper(new SceneObjectWrapper());
+ R2_GLOBALS._player._strip = 7;
+ R2_GLOBALS._player.enableControl();
+ break;
+ case 20:
+ R2_INVENTORY.setObjectScene(R2_CABLE_HARNESS, 0);
+ R2_GLOBALS._player.enableControl();
+ break;
+ case 21:
+ _actor5.fixPriority(77);
+ if ((R2_GLOBALS._v565E5 != 0) && (R2_GLOBALS._v565E1 == 20) && (R2_GLOBALS._v565E3 == 70))
+ _actor5.animate(ANIM_MODE_6, NULL);
+
+ R2_INVENTORY.setObjectScene(R2_ATTRACTOR_CABLE_HARNESS, 700);
+ R2_GLOBALS._player.enableControl();
+ break;
+ case 701:
+ R2_GLOBALS._sceneManager.changeScene(250);
+ break;
+ case 702:
+ R2_GLOBALS._sceneManager.changeScene(500);
+ break;
+ case 704:
+ R2_GLOBALS._sceneManager.changeScene(900);
+ break;
+ case 706:
+ _actor5.setDetails(700, 38, -1, -1, 3, (SceneItem *) NULL);
+ _actor5.fixPriority(77);
+ if ((R2_GLOBALS._v565E5 != 0) && (R2_GLOBALS._v565E1 == 20) && (R2_GLOBALS._v565E3 == 70))
+ _actor5.animate(ANIM_MODE_6, NULL);
+ R2_INVENTORY.setObjectScene(R2_ATTRACTOR_UNIT, 0);
+ R2_INVENTORY.setObjectScene(R2_ATTRACTOR_CABLE_HARNESS, 700);
+ R2_GLOBALS._player.enableControl();
+ break;
+ case 709:
+ R2_GLOBALS.setFlag(41);
+ R2_GLOBALS._player.enableControl();
+ break;
+ case 710:
+ R2_GLOBALS.clearFlag(41);
+ R2_GLOBALS._player.enableControl();
+ break;
+ case 5:
+ // No break on purpose
+ default:
+ R2_GLOBALS._player.enableControl();
+ break;
+ }
+}
+
+/*--------------------------------------------------------------------------
+ * Scene 800 - Sick Bay
+ *
+ *--------------------------------------------------------------------------*/
+
+bool Scene800::Button::startAction(CursorType action, Event &event) {
+ Scene800 *scene = (Scene800 *)R2_GLOBALS._sceneManager._scene;
+
+ if (action != CURSOR_USE) {
+ return NamedHotspot::startAction(action, event);
+ } else {
+ R2_GLOBALS._player.disableControl();
+ scene->_sceneMode = 802;
+ scene->setAction(&scene->_sequenceManager1, scene, 802, &R2_GLOBALS._player, &scene->_autodocCover, NULL);
+ return true;
+ }
+}
+
+bool Scene800::CableJunction::startAction(CursorType action, Event &event) {
+ Scene800 *scene = (Scene800 *)R2_GLOBALS._sceneManager._scene;
+
+ if (action != R2_OPTICAL_FIBRE) {
+ return NamedHotspot::startAction(action, event);
+ } else {
+ R2_GLOBALS._player.disableControl();
+ scene->_opticalFibre.postInit();
+ scene->_sceneMode = 803;
+
+ if (R2_INVENTORY.getObjectScene(R2_READER) == 800)
+ scene->setAction(&scene->_sequenceManager1, scene, 813, &R2_GLOBALS._player, &scene->_opticalFibre, &scene->_reader, NULL);
+ else
+ scene->setAction(&scene->_sequenceManager1, scene, 803, &R2_GLOBALS._player, &scene->_opticalFibre, NULL);
+
+ return true;
+ }
+}
+
+bool Scene800::DeviceSlot::startAction(CursorType action, Event &event) {
+ Scene800 *scene = (Scene800 *)R2_GLOBALS._sceneManager._scene;
+
+ switch (action) {
+ case CURSOR_USE:
+ if (R2_INVENTORY.getObjectScene(R2_READER) != 800)
+ break;
+
+ R2_GLOBALS._player.disableControl();
+ scene->_reader.postInit();
+
+ if (R2_INVENTORY.getObjectScene(R2_OPTICAL_FIBRE) == 800)
+ scene->setAction(&scene->_sequenceManager1, scene, 814, &R2_GLOBALS._player, &scene->_reader, &scene->_opticalFibre, NULL);
+ else
+ scene->setAction(&scene->_sequenceManager1, scene, 804, &R2_GLOBALS._player, &scene->_reader, NULL);
+ return true;
+ default:
+ break;
+ }
+
+ return NamedHotspot::startAction(action, event);
+}
+
+/*--------------------------------------------------------------------------*/
+
+bool Scene800::Door::startAction(CursorType action, Event &event) {
+ Scene800 *scene = (Scene800 *)R2_GLOBALS._sceneManager._scene;
+
+ switch (action) {
+ case CURSOR_USE:
+ R2_GLOBALS._player.disableControl();
+ scene->_sceneMode = 801;
+ scene->setAction(&scene->_sequenceManager1, scene, 801, &R2_GLOBALS._player, &scene->_door, NULL);
+ return true;
+ default:
+ return SceneActor::startAction(action, event);
+ }
+}
+
+bool Scene800::Tray::startAction(CursorType action, Event &event) {
+ Scene800 *scene = (Scene800 *)R2_GLOBALS._sceneManager._scene;
+
+ switch (action) {
+ case CURSOR_USE:
+ if (!R2_GLOBALS.getFlag(10)) {
+ R2_GLOBALS._player.disableControl();
+ scene->_sceneMode = 806;
+ scene->setAction(&scene->_sequenceManager1, scene, 806, &R2_GLOBALS._player, &scene->_tray, NULL);
+ } else if (R2_INVENTORY.getObjectScene(R2_OPTO_DISK) == 825) {
+ R2_GLOBALS._player.disableControl();
+ scene->_sceneMode = 808;
+ scene->setAction(&scene->_sequenceManager1, scene, 808, &R2_GLOBALS._player, &scene->_tray, NULL);
+ } else {
+ R2_GLOBALS._player.disableControl();
+ scene->_sceneMode = 807;
+ scene->setAction(&scene->_sequenceManager1, scene, 807, &R2_GLOBALS._player, &scene->_tray, NULL);
+ }
+ return true;
+ default:
+ return SceneActor::startAction(action, event);
+ }
+}
+
+bool Scene800::ComScanner::startAction(CursorType action, Event &event) {
+ Scene800 *scene = (Scene800 *)R2_GLOBALS._sceneManager._scene;
+
+ switch (action) {
+ case CURSOR_USE:
+ if (scene->_cabinet._frame == 1)
+ return false;
+
+ R2_GLOBALS._player.disableControl();
+ scene->_sceneMode = 811;
+ scene->setAction(&scene->_sequenceManager1, scene, 811, &R2_GLOBALS._player, &scene->_comScanner, NULL);
+ return true;
+ case CURSOR_TALK:
+ SceneItem::display2(800, 35);
+ return true;
+ default:
+ return SceneActor::startAction(action, event);
+ }
+}
+
+bool Scene800::Cabinet::startAction(CursorType action, Event &event) {
+ Scene800 *scene = (Scene800 *)R2_GLOBALS._sceneManager._scene;
+
+ switch (action) {
+ case CURSOR_USE:
+ R2_GLOBALS._player.disableControl();
+
+ if (scene->_cabinet._frame == 1) {
+ scene->_sceneMode = 810;
+ scene->setAction(&scene->_sequenceManager1, scene, 810, &R2_GLOBALS._player, &scene->_cabinet, NULL);
+ R2_GLOBALS.setFlag(56);
+ } else {
+ scene->_sceneMode = 812;
+ scene->setAction(&scene->_sequenceManager1, scene, 812, &R2_GLOBALS._player, &scene->_cabinet, NULL);
+ R2_GLOBALS.clearFlag(56);
+ }
+ return true;
+ default:
+ return SceneActor::startAction(action, event);
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+
+void Scene800::postInit(SceneObjectList *OwnerList) {
+ SceneExt::postInit();
+ loadScene(800);
+
+ _door.postInit();
+ _door.setVisage(800);
+ _door.setPosition(Common::Point(286, 108));
+ _door.fixPriority(50);
+ _door.setDetails(800, 3, -1, -1, 1, (SceneItem *)NULL);
+
+ _autodocCover.postInit();
+ _autodocCover.setup(800, 2, 1);
+ _autodocCover.setPosition(Common::Point(119, 161));
+ _autodocCover.setDetails(800, 6, 7, -1, 1, (SceneItem *)NULL);
+
+ if (R2_INVENTORY.getObjectScene(R2_OPTICAL_FIBRE) == 800) {
+ _opticalFibre.postInit();
+ if (R2_INVENTORY.getObjectScene(R2_READER) == 800)
+ _opticalFibre.setup(800, 4, 1);
+ else
+ _opticalFibre.setup(800, 7, 2);
+
+ _opticalFibre.setPosition(Common::Point(220, 124));
+ _opticalFibre.fixPriority(140);
+ }
+
+ if (R2_INVENTORY.getObjectScene(R2_READER) == 800) {
+ _reader.postInit();
+
+ if (R2_INVENTORY.getObjectScene(R2_OPTICAL_FIBRE) == 800) {
+ _opticalFibre.setup(800, 4, 1);
+ _reader.hide();
+ } else {
+ _reader.setup(800, 7, 1);
+ }
+
+ _reader.setPosition(Common::Point(230, 120));
+ _reader.fixPriority(140);
+ }
+
+ _cabinet.postInit();
+ _cabinet.setup(801, 1, R2_GLOBALS.getFlag(56) ? 6 : 1);
+ _cabinet.setPosition(Common::Point(169, 79));
+ _cabinet.setDetails(800, 41, -1, -1, 1, (SceneItem *)NULL);
+
+ if (R2_INVENTORY.getObjectScene(R2_COM_SCANNER) == 800) {
+ _comScanner.postInit();
+ _comScanner.setup(801, 2, 1);
+ _comScanner.setPosition(Common::Point(174, 73));
+ _comScanner.setDetails(800, 34, 35, -1, 1, (SceneItem *)NULL);
+ }
+
+ _tray.postInit();
+ _tray.setup(800, R2_INVENTORY.getObjectScene(R2_OPTO_DISK) == 825 ? 6 : 5, 1);
+ if (R2_GLOBALS.getFlag(10))
+ _tray.setFrame(5);
+ _tray.setPosition(Common::Point(203, 144));
+ _tray.setDetails(800, 12, -1, 14, 1, (SceneItem *)NULL);
+
+ R2_GLOBALS._player.postInit();
+ R2_GLOBALS._player.setVisage(10);
+ R2_GLOBALS._player.animate(ANIM_MODE_1, NULL);
+ R2_GLOBALS._player.disableControl();
+
+ _dataConduits.setDetails(13, 800, 21, -1, -1);
+ _cableJunction.setDetails(Rect(206, 111, 223, 125), 800, 24, -1, -1, 1, NULL);
+ _deviceSlot.setDetails(Rect(220, 108, 239, 122), 800, 27, -1, -1, 1, NULL);
+ _diskSlot.setDetails(Rect(209, 124, 226, 133), 800, 9, -1, 11, 1, NULL);
+
+ if (R2_INVENTORY.getObjectScene(R2_READER) == 800)
+ _deviceSlot._lookLineNum = 33;
+
+ _button.setDetails(Rect(189, 112, 204, 124), 800, 30, -1, -1, 1, NULL);
+ _couch.setDetails(11, 800, 15, -1, 17);
+ _autoDoc.setDetails(Rect(152, 92, 247, 151), 800, 6, 7, -1, 1, NULL);
+ _medicalDatabase.setDetails(12, 800, 18, -1, -1);
+ _background.setDetails(Rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT), 800, 0, -1, -1, 1, NULL);
+
+ switch (R2_GLOBALS._sceneManager._previousScene) {
+ case 825:
+ _sceneMode = 800;
+ setAction(&_sequenceManager1, this, 805, &R2_GLOBALS._player, &_autodocCover, NULL);
+ break;
+ case 850:
+ _sceneMode = 800;
+ setAction(&_sequenceManager1, this, 800, &R2_GLOBALS._player, &_door, NULL);
+ break;
+ default:
+ R2_GLOBALS._player.setStrip(3);
+ R2_GLOBALS._player.setPosition(Common::Point(277, 132));
+ R2_GLOBALS._player.enableControl();
+ break;
+ }
+}
+
+void Scene800::signal() {
+ switch (_sceneMode) {
+ case 801:
+ R2_GLOBALS._sceneManager.changeScene(850);
+ break;
+ case 802:
+ R2_GLOBALS._sceneManager.changeScene(825);
+ break;
+ case 803:
+ R2_GLOBALS._player.enableControl();
+ R2_INVENTORY.setObjectScene(R2_OPTICAL_FIBRE, 800);
+ break;
+ case 804:
+ R2_GLOBALS._player.enableControl();
+ _deviceSlot._lookLineNum = 33;
+ R2_INVENTORY.setObjectScene(R2_READER, 800);
+ break;
+ case 806:
+ R2_GLOBALS._player.enableControl();
+ R2_GLOBALS.setFlag(10);
+ break;
+ case 807:
+ R2_GLOBALS._player.enableControl();
+ R2_GLOBALS.clearFlag(10);
+ break;
+ case 808:
+ R2_GLOBALS._player.enableControl();
+ R2_INVENTORY.setObjectScene(R2_OPTO_DISK, 1);
+ break;
+ case 809:
+ R2_GLOBALS._player.enableControl();
+ R2_INVENTORY.setObjectScene(R2_READER, 1);
+ break;
+ case 811:
+ R2_GLOBALS._player.enableControl();
+ _comScanner.remove();
+ R2_INVENTORY.setObjectScene(R2_COM_SCANNER, 1);
+ break;
+ default:
+ R2_GLOBALS._player.enableControl();
+ break;
+ }
+}
+
+/*--------------------------------------------------------------------------
+ * Scene 825 - Autodoc
+ *
+ *--------------------------------------------------------------------------*/
+
+Scene825::Button::Button(): SceneObject() {
+ _buttonId = 0;
+ _v2 = 0;
+ _buttonDown = false;
+}
+
+void Scene825::Button::synchronize(Serializer &s) {
+ SceneObject::synchronize(s);
+ s.syncAsSint16LE(_buttonId);
+ s.syncAsSint16LE(_v2);
+ s.syncAsSint16LE(_buttonDown);
+}
+
+void Scene825::Button::process(Event &event) {
+ Scene825 *scene = (Scene825 *)R2_GLOBALS._sceneManager._scene;
+
+ if (!event.handled) {
+ if ((event.eventType == EVENT_BUTTON_DOWN) && _bounds.contains(event.mousePos) && !_buttonDown) {
+ scene->_sound1.play(14);
+ setFrame(2);
+ _buttonDown = true;
+ event.handled = true;
+ }
+
+ if ((event.eventType == EVENT_BUTTON_UP) && _buttonDown) {
+ setFrame(1);
+ _buttonDown = false;
+ event.handled = true;
+
+ scene->doButtonPress(_buttonId);
+ }
+ }
+}
+
+bool Scene825::Button::startAction(CursorType action, Event &event) {
+ if (action == CURSOR_USE)
+ return false;
+ else
+ return SceneObject::startAction(action, event);
+}
+
+void Scene825::Button::setButton(int buttonId) {
+ SceneObject::postInit();
+ _v2 = buttonId;
+ _buttonDown = 0;
+ _sceneText._color1 = 92;
+ _sceneText._color2 = 0;
+ _sceneText._width = 200;
+ _sceneText.fixPriority(20);
+ _sceneText._fontNumber = 50;
+
+ switch (buttonId) {
+ case 1:
+ _sceneText.setPosition(Common::Point(95, 58));
+ break;
+ case 2:
+ _sceneText.setPosition(Common::Point(98, 75));
+ break;
+ case 3:
+ _sceneText.setPosition(Common::Point(102, 95));
+ break;
+ case 4:
+ _sceneText.setPosition(Common::Point(180, 58));
+ _sceneText._textMode = ALIGN_RIGHT;
+ break;
+ case 5:
+ _sceneText.setPosition(Common::Point(177, 75));
+ _sceneText._textMode = ALIGN_RIGHT;
+ break;
+ case 6:
+ _sceneText.setPosition(Common::Point(175, 95));
+ _sceneText._textMode = ALIGN_RIGHT;
+ break;
+ default:
+ break;
+ }
+
+ setDetails(825, 6, 7, -1, 2, (SceneItem *)NULL);
+}
+
+void Scene825::Button::setText(int textId) {
+ Scene825 *scene = (Scene825 *)R2_GLOBALS._sceneManager._scene;
+
+ _buttonId = textId;
+ _lookLineNum = textId;
+
+ _sceneText.remove();
+ if (_buttonId != 0)
+ _sceneText.setup(scene->_autodocItems[textId - 1]);
+}
+
+/*--------------------------------------------------------------------------*/
+
+Scene825::Scene825(): SceneExt() {
+ _menuId = _frame1 = _frame2 = 0;
+
+ // Setup Autodoc items list
+ _autodocItems[0] = MAIN_MENU;
+ _autodocItems[1] = DIAGNOSIS;
+ _autodocItems[2] = ADVANCED_PROCEDURES;
+ _autodocItems[3] = VITAL_SIGNS;
+ _autodocItems[4] = OPEN_DOOR;
+ _autodocItems[5] = TREATMENTS;
+ _autodocItems[6] = NO_MALADY_DETECTED;
+ _autodocItems[7] = NO_TREATMENT_REQUIRED;
+ _autodocItems[8] = ACCESS_CODE_REQUIRED;
+ _autodocItems[9] = INVALID_ACCESS_CODE;
+ _autodocItems[10] = FOREIGN_OBJECT_EXTRACTED;
+}
+
+void Scene825::postInit(SceneObjectList *OwnerList) {
+ SceneExt::postInit();
+ loadScene(825);
+ R2_GLOBALS._player._uiEnabled = false;
+ BF_GLOBALS._interfaceY = 200;
+
+ R2_GLOBALS._player.postInit();
+ R2_GLOBALS._player._effect = 0;
+ R2_GLOBALS._player.setVisage(10);
+ R2_GLOBALS._player.hide();
+ R2_GLOBALS._player.disableControl();
+
+ _item2.setDetails(1, 825, 3, 4, 5);
+ _background.setDetails(Rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT), 825, 0, -1, -1, 1, NULL);
+
+ _sceneMode = 10;
+ signal();
+}
+
+void Scene825::synchronize(Serializer &s) {
+ SceneExt::synchronize(s);
+
+ s.syncAsSint16LE(_menuId);
+ s.syncAsSint16LE(_frame1);
+ s.syncAsSint16LE(_frame2);
+}
+
+void Scene825::remove() {
+ SceneExt::remove();
+ R2_GLOBALS._player._uiEnabled = true;
+}
+
+void Scene825::signal() {
+ switch (_sceneMode) {
+ case 10:
+ _button1.setButton(1);
+ _button1.setup(825, 1, 1);
+ _button1.setPosition(Common::Point(71, 71));
+ _button2.setButton(2);
+ _button2.setup(825, 3, 1);
+ _button2.setPosition(Common::Point(74, 90));
+ _button3.setButton(3);
+ _button3.setup(825, 5, 1);
+ _button3.setPosition(Common::Point(78, 109));
+ _button4.setButton(4);
+ _button4.setup(825, 2, 1);
+ _button4.setPosition(Common::Point(248, 71));
+ _button5.setButton(5);
+ _button5.setup(825, 4, 1);
+ _button5.setPosition(Common::Point(245, 90));
+ _button6.setButton(6);
+ _button6.setup(825, 6, 1);
+ _button6.setPosition(Common::Point(241, 109));
+
+ doButtonPress(1);
+ R2_GLOBALS._player.enableControl();
+ R2_GLOBALS._player._canWalk = false;
+ break;
+ case 825:
+ _object5.remove();
+ _sceneText._color1 = 92;
+ _sceneText._color2 = 0;
+ _sceneText._width = 200;
+ _sceneText.fixPriority(20);
+ _sceneText._fontNumber = 50;
+ _sceneText.setPosition(Common::Point(120, 75));
+ _sceneText.setup(NO_MALADY_DETECTED);
+ _sceneMode = 826;
+ setAction(&_sequenceManager1, this, 826, &R2_GLOBALS._player, NULL);
+ break;
+ case 826:
+ _sceneText.remove();
+ doButtonPress(1);
+ R2_GLOBALS._player.enableControl();
+ R2_GLOBALS._player._canWalk = false;
+ break;
+ case 827:
+ _object5.remove();
+ R2_INVENTORY.setObjectScene(R2_OPTO_DISK, 825);
+ _sceneText.setPosition(Common::Point(108, 75));
+ _sceneText.setup(FOREIGN_OBJECT_EXTRACTED);
+ _sceneMode = 826;
+ setAction(&_sequenceManager1, this, 826, &R2_GLOBALS._player, NULL);
+ break;
+ default:
+ R2_GLOBALS._player.enableControl();
+ R2_GLOBALS._player._canWalk = false;
+ break;
+ }
+}
+
+void Scene825::process(Event &event) {
+ SceneExt::process(event);
+
+ if (R2_GLOBALS._player._uiEnabled) {
+ _button1.process(event);
+ _button2.process(event);
+ _button3.process(event);
+ _button4.process(event);
+ _button5.process(event);
+ _button6.process(event);
+ }
+}
+
+void Scene825::dispatch() {
+ if (R2_GLOBALS._sceneObjects->contains(&_object4) &&
+ ((_object4._frame == 1) || (_object4._frame == 3)) &&
+ (_object4._frame != _frame1)) {
+ _sound2.play(25);
+ }
+
+ if (R2_GLOBALS._sceneObjects->contains(&_object1) &&
+ (_object1._frame == 3) && (_object1._frame != _frame2)) {
+ _sound3.play(26);
+ }
+
+ _frame1 = _object4._frame;
+ _frame2 = _object1._frame;
+
+ Scene::dispatch();
+}
+
+void Scene825::doButtonPress(int buttonId) {
+ if ((_menuId != 4) || (buttonId == 5)) {
+ _button1.setText(0);
+ _button2.setText(0);
+ _button3.setText(0);
+ _button4.setText(0);
+ _button5.setText(0);
+ _button6.setText(0);
+
+ switch (buttonId) {
+ case 2:
+ R2_GLOBALS._player.disableControl();
+ _object5.postInit();
+ _sceneMode = 825;
+ setAction(&_sequenceManager1, this, 825, &R2_GLOBALS._player, &_object5, NULL);
+ break;
+ case 3:
+ R2_GLOBALS._player.disableControl();
+ _sceneText._color1 = 92;
+ _sceneText._color2 = 0;
+ _sceneText._width = 200;
+ _sceneText.fixPriority(20);
+ _sceneText._fontNumber = 50;
+ _sceneText.setPosition(Common::Point(115, 75));
+
+ if (R2_GLOBALS.getFlag(4)) {
+ if ((R2_INVENTORY.getObjectScene(R2_READER) != 800) ||
+ (R2_INVENTORY.getObjectScene(R2_OPTICAL_FIBRE) != 800)) {
+ _sceneText.setPosition(Common::Point(116, 75));
+ _sceneText.setup(ACCESS_CODE_REQUIRED);
+ } else if (R2_INVENTORY.getObjectScene(R2_OPTO_DISK) != 800) {
+ _sceneText.setPosition(Common::Point(115, 75));
+ _sceneText.setup(NO_TREATMENT_REQUIRED);
+ } else {
+ _button6._buttonId = 5;
+
+ _object5.postInit();
+ setAction(&_sequenceManager1, this, 827, &_object5, NULL);
+ }
+ } else {
+ R2_GLOBALS.setFlag(2);
+
+ if ((R2_INVENTORY.getObjectScene(R2_READER) != 800) ||
+ (R2_INVENTORY.getObjectScene(R2_OPTICAL_FIBRE) != 800)) {
+ _sceneText.setPosition(Common::Point(116, 75));
+ _sceneText.setup(ACCESS_CODE_REQUIRED);
+ } else {
+ _sceneText.setPosition(Common::Point(119, 75));
+ _sceneText.setup(INVALID_ACCESS_CODE);
+ }
+ }
+
+ if (_sceneMode != 827) {
+ _sceneMode = 826;
+ setAction(&_sequenceManager1, this, 826, &R2_GLOBALS._player, NULL);
+ }
+ break;
+ case 4:
+ _sound4.play(27);
+ _button6._buttonId = 5;
+
+ _object1.postInit();
+ _object1.setup(826, 7, 1);
+ _object1.setPosition(Common::Point(112, 67));
+ _object1._numFrames = 1;
+ _object1.animate(ANIM_MODE_2);
+
+ _object2.postInit();
+ _object2.setup(826, 5, 1);
+ _object2.setPosition(Common::Point(158, 67));
+ _object2._numFrames = 5;
+ _object2.animate(ANIM_MODE_2);
+
+ _object3.postInit();
+ _object3.setup(826, 6, 1);
+ _object3.setPosition(Common::Point(206, 67));
+ _object3._numFrames = 1;
+ _object3.animate(ANIM_MODE_2);
+
+ _object4.postInit();
+ _object4.setup(826, 8, 1);
+ _object4.setPosition(Common::Point(158, 84));
+ _object4._numFrames = 1;
+ _object4.animate(ANIM_MODE_2);
+
+ _object5.postInit();
+ _object5.setup(826, 4, 1);
+ _object5.setPosition(Common::Point(161, 110));
+ break;
+ case 5:
+ R2_GLOBALS._player.disableControl();
+ if (_menuId == 4) {
+ _menuId = 0;
+
+ _object1.remove();
+ _object2.remove();
+ _object3.remove();
+ _object4.remove();
+ _object5.remove();
+
+ _sound2.stop();
+ _sound3.stop();
+ _sound4.stop();
+
+ doButtonPress(1);
+ R2_GLOBALS._player.enableControl();
+ R2_GLOBALS._player._canWalk = false;
+ } else {
+ R2_GLOBALS._sceneManager.changeScene(800);
+ }
+ break;
+ case 6:
+ R2_GLOBALS._player.disableControl();
+ _sceneText._color1 = 92;
+ _sceneText._color2 = 0;
+ _sceneText._width = 200;
+ _sceneText.fixPriority(20);
+ _sceneText._fontNumber = 50;
+ _sceneText.setPosition(Common::Point(115, 75));
+ _sceneText.setup(NO_TREATMENT_REQUIRED);
+
+ _sceneMode = 826;
+ setAction(&_sequenceManager1, this, 826, &R2_GLOBALS._player, NULL);
+ break;
+ default:
+ _button1.setText(2);
+ _button2.setText(3);
+ _button3.setText(4);
+ _button4.setText(6);
+ _button6.setText(5);
+ break;
+ }
+
+ _menuId = buttonId;
+ }
+}
+
+/*--------------------------------------------------------------------------
+ * Scene 850 - Deck #5 - By Lift
+ *
+ *--------------------------------------------------------------------------*/
+
+bool Scene850::Indicator::startAction(CursorType action, Event &event) {
+ Scene850 *scene = (Scene850 *)R2_GLOBALS._sceneManager._scene;
+
+ if ((action != CURSOR_USE) || (R2_INVENTORY.getObjectScene(R2_OPTICAL_FIBRE) != 850))
+ return NamedHotspot::startAction(action, event);
+ else {
+ R2_GLOBALS._player.disableControl();
+ scene->_sceneMode = 851;
+ scene->setAction(&scene->_sequenceManager1, scene, 851, &R2_GLOBALS._player, &scene->_fibre, NULL);
+ return true;
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+
+bool Scene850::LiftDoor::startAction(CursorType action, Event &event) {
+ Scene850 *scene = (Scene850 *)R2_GLOBALS._sceneManager._scene;
+
+ if (action != CURSOR_USE)
+ return SceneActor::startAction(action, event);
+ else {
+ R2_GLOBALS._player.disableControl();
+ scene->_sceneMode = 202;
+ scene->setAction(&scene->_sequenceManager1, scene, 202, &R2_GLOBALS._player, this, NULL);
+ return true;
+ }
+}
+
+bool Scene850::SickBayDoor::startAction(CursorType action, Event &event) {
+ Scene850 *scene = (Scene850 *)R2_GLOBALS._sceneManager._scene;
+
+ if (action != CURSOR_USE)
+ return SceneActor::startAction(action, event);
+ else {
+ R2_GLOBALS._player.disableControl();
+ scene->_sceneMode = 204;
+ scene->setAction(&scene->_sequenceManager1, scene, 204, &R2_GLOBALS._player, this, NULL);
+ return true;
+ }
+}
+
+bool Scene850::Clamp::startAction(CursorType action, Event &event) {
+ Scene850 *scene = (Scene850 *)R2_GLOBALS._sceneManager._scene;
+
+ if (!R2_GLOBALS.getFlag(7))
+ return false;
+ else if (action != CURSOR_USE)
+ return SceneActor::startAction(action, event);
+ else {
+ R2_GLOBALS._player.disableControl();
+ scene->_object1.postInit();
+ scene->_sceneMode = 850;
+ scene->setAction(&scene->_sequenceManager1, scene, 850, &R2_GLOBALS._player, this, &scene->_object1, NULL);
+ return true;
+ }
+}
+
+bool Scene850::Panel::startAction(CursorType action, Event &event) {
+ Scene850 *scene = (Scene850 *)R2_GLOBALS._sceneManager._scene;
+
+ if ((action != CURSOR_USE) || R2_GLOBALS.getFlag(7))
+ return SceneActor::startAction(action, event);
+ else {
+ R2_GLOBALS._player.disableControl();
+ scene->_sceneMode = 852;
+ scene->setAction(&scene->_sequenceManager1, scene, 852, &R2_GLOBALS._player, this, &scene->_object1, NULL);
+ return true;
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+
+void Scene850::postInit(SceneObjectList *OwnerList) {
+ SceneExt::postInit();
+ loadScene(850);
+
+ _liftDoor.postInit();
+ _liftDoor.setup(850, 2, 1);
+ _liftDoor.setPosition(Common::Point(188, 79));
+ _liftDoor.setDetails(850, 3, -1, -1, 1, (SceneItem *)NULL);
+
+ _sickBayDoor.postInit();
+ _sickBayDoor.setup(850, 3, 1);
+ _sickBayDoor.setPosition(Common::Point(62, 84));
+ _sickBayDoor.setDetails(850, 9, -1, -1, 1, (SceneItem *)NULL);
+
+ if (R2_INVENTORY.getObjectScene(R2_CLAMP) == 850) {
+ _clamp.postInit();
+ _clamp.setup(850, 5, 1);
+ _clamp.setPosition(Common::Point(242, 93));
+ _clamp.fixPriority(81);
+ _clamp.animate(ANIM_MODE_2, NULL);
+ _clamp.setDetails(850, 27, -1, -1, 1, (SceneItem *)NULL);
+ }
+
+ _panel.postInit();
+ _panel.setVisage(850);
+
+ if (R2_GLOBALS.getFlag(7))
+ _panel.setFrame(7);
+
+ _panel.setPosition(Common::Point(232, 119));
+ _panel.fixPriority(82);
+ _panel.setDetails(850, 24, -1, -1, 1, (SceneItem *)NULL);
+
+ if (R2_INVENTORY.getObjectScene(R2_OPTICAL_FIBRE) == 850) {
+ _fibre.postInit();
+ _fibre.setup(850, 6, 1);
+ _fibre.setPosition(Common::Point(280, 87));
+ }
+
+ R2_GLOBALS._player.postInit();
+ R2_GLOBALS._player.setVisage(10);
+ R2_GLOBALS._player.animate(ANIM_MODE_1, NULL);
+ R2_GLOBALS._player.disableControl();
+
+ _eastDoor.setDetails(Rect(289, 53, 315, 125), 850, 6, -1, 8, 1, NULL);
+ _indicator.setDetails(Rect(275, 67, 286, 79), 850, 18, -1, 20, 1, NULL);
+ _sickBayIndicator.setDetails(Rect(41, 51, 48, 61), 850, 15, -1, -1, 1, NULL);
+ _liftControls.setDetails(Rect(156, 32, 166, 44), 850, 21, -1, -1, 1, NULL);
+ _compartment.setDetails(Rect(4, 88, 153, 167), 850, 12, -1, -1, 1, NULL);
+ _background.setDetails(Rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT), 850, 0, -1, -1, 1, NULL);
+
+ switch (R2_GLOBALS._sceneManager._previousScene) {
+ case 250:
+ _sceneMode = 203;
+ setAction(&_sequenceManager1, this, 203, &R2_GLOBALS._player, &_liftDoor, NULL);
+ break;
+ case 800:
+ _sceneMode = 205;
+ setAction(&_sequenceManager1, this, 205, &R2_GLOBALS._player, &_sickBayDoor, NULL);
+ break;
+ default:
+ R2_GLOBALS._player.setStrip(3);
+ R2_GLOBALS._player.setPosition(Common::Point(215, 115));
+ R2_GLOBALS._player.enableControl();
+ break;
+ }
+}
+
+void Scene850::signal() {
+ switch (_sceneMode) {
+ case 202:
+ R2_GLOBALS._sceneManager.changeScene(250);
+ break;
+ case 204:
+ R2_GLOBALS._sceneManager.changeScene(800);
+ break;
+ case 850:
+ R2_INVENTORY.setObjectScene(R2_CLAMP, 1);
+ _clamp.remove();
+ _object1.remove();
+ R2_GLOBALS._player.enableControl();
+ break;
+ case 851:
+ R2_INVENTORY.setObjectScene(R2_OPTICAL_FIBRE, 1);
+ _fibre.remove();
+ R2_GLOBALS._player.enableControl();
+ break;
+ case 852:
+ R2_GLOBALS.setFlag(7);
+ R2_GLOBALS._player.enableControl();
+ break;
+ default:
+ R2_GLOBALS._player.enableControl();
+ break;
+ }
+}
+
+/*--------------------------------------------------------------------------
+ * Scene 900 -
+ *
+ *--------------------------------------------------------------------------*/
+Scene900::Actor4::Actor4() {
+ _fieldA4 = 0;
+}
+
+void Scene900::Actor4::synchronize(Serializer &s) {
+ SceneActor::synchronize(s);
+
+ s.syncAsSint16LE(_fieldA4);
+}
+
+void Scene900::Actor4::sub96135(int arg1) {
+ _fieldA4 = arg1;
+ setDetails(900, -1, -1, -1, 2, (SceneItem *) NULL);
+}
+
+Scene900::Scene900() {
+ _field412 = 0;
+ _field414 = 0;
+ _field416 = 0;
+}
+
+void Scene900::synchronize(Serializer &s) {
+ SceneExt::synchronize(s);
+
+ s.syncAsSint16LE(_field412);
+ s.syncAsSint16LE(_field414);
+ s.syncAsSint16LE(_field416);
+}
+
+bool Scene900::Actor4::startAction(CursorType action, Event &event) {
+ Scene900 *scene = (Scene900 *)R2_GLOBALS._sceneManager._scene;
+
+ if (action == CURSOR_USE) {
+ R2_GLOBALS._sound2.play(14);
+ switch (_fieldA4) {
+ case 2:
+ if (scene->_field412 == 1) {
+ scene->_sceneMode = 2;
+ scene->signal();
+ } else if (scene->_field412 == 2) {
+ if (R2_GLOBALS._v565E5 == 0) {
+ scene->_aSound1.play(30);
+ setup(900, 3, 11);
+ R2_GLOBALS._v565E5 = 1;
+ if ((R2_INVENTORY.getObjectScene(R2_CABLE_HARNESS) == 0) && (R2_INVENTORY.getObjectScene(R2_ATTRACTOR_CABLE_HARNESS == 700)) && (R2_GLOBALS._v565E1 == 20) && (R2_GLOBALS._v565E3 == 70) && (scene->_actor2._animateMode != ANIM_MODE_6)) {
+ scene->_actor2.animate(ANIM_MODE_6, NULL);
+ } else {
+ if (((scene->_actor3._percent * 49) / 100) + scene->_actor3._position.x == scene->_actor2._position.x) {
+ if (scene->_actor2._position.x == 166 - (R2_GLOBALS._v565E3 / 15)) {
+ R2_GLOBALS._player.disableControl();
+ scene->_sceneMode = 4;
+ scene->_actor2._moveDiff.y = (scene->_actor2._position.y - (scene->_actor3._position.y + ((scene->_actor3._percent * 3) / 10) - 2)) / 9;
+ Common::Point pt(scene->_actor3._position.x + ((scene->_actor3._percent * 49) / 100), scene->_actor3._position.y + ((scene->_actor3._percent * 3) / 10) - 2);
+ NpcMover *mover = new NpcMover();
+ scene->_actor2.addMover(mover, &pt, this);
+ scene->_actor2.animate(ANIM_MODE_6, NULL);
+ }
+ }
+ }
+ } else {
+ scene->_aSound1.play(53);
+ setup(900, 3, 9);
+ R2_GLOBALS._v565E5 = 0;
+
+ if ((R2_INVENTORY.getObjectScene(R2_CABLE_HARNESS) == 0) && (R2_INVENTORY.getObjectScene(R2_ATTRACTOR_CABLE_HARNESS) == 700) && (scene->_actor2._frame < 8) && (scene->_actor2._animateMode != ANIM_MODE_5)) {
+ scene->_actor2.animate(ANIM_MODE_5, NULL);
+ } else if ((R2_INVENTORY.getObjectScene(R2_CABLE_HARNESS) == 700) && (R2_INVENTORY.getObjectScene(R2_ATTRACTOR_CABLE_HARNESS) == 700) && (scene->_actor2._frame < 8)) {
+ R2_GLOBALS._v565E7 = 0;
+ if (scene->_actor2._animateMode != 5) {
+ R2_GLOBALS._player.disableControl();
+ scene->_sceneMode = 5;
+ scene->_actor2.animate(ANIM_MODE_5, NULL);
+ scene->_actor2._moveDiff.y = (166 - scene->_actor2._position.y) / 9;
+ Common::Point pt(scene->_actor2._position.x, 166 - (R2_GLOBALS._v565E3 / 15));
+ NpcMover *mover = new NpcMover();
+ scene->_actor2.addMover(mover, &pt, this);
+ }
+ }
+ }
+ }
+ return true;
+ break;
+ case 3:
+ if (scene->_field412 == 1) {
+ scene->_sceneMode = 3;
+ scene->signal();
+ }
+ return true;
+ break;
+ case 4:
+ if ((scene->_field416 == 0) && (scene->_field414 == 0) && (R2_GLOBALS._v565E3 != 0)) {
+ scene->_aSound1.play(38);
+ scene->_field416 = -5;
+ }
+ return true;
+ break;
+ case 5:
+ if ((scene->_field416 == 0) && (scene->_field414 == 0) && (R2_GLOBALS._v565E3 < 135)) {
+ scene->_aSound1.play(38);
+ scene->_field416 = 5;
+ }
+ return true;
+ break;
+ case 6:
+ if ((scene->_field416 == 0) && (scene->_field414 == 0) && (R2_GLOBALS._v565E1 > -10)) {
+ scene->_aSound1.play(38);
+ scene->_field414 = -5;
+ }
+ return true;
+ break;
+ case 7:
+ if ((scene->_field416 == 0) && (scene->_field414 == 0) && (R2_GLOBALS._v565E1 < 20)) {
+ scene->_aSound1.play(38);
+ scene->_field414 = 5;
+ }
+ return true;
+ break;
+ case 8:
+ SceneItem::display(5, 11, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
+ return true;
+ break;
+ case 9:
+ SceneItem::display(5, 12, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
+ return true;
+ break;
+ default:
+ if (scene->_field412 == 1) {
+ R2_GLOBALS._player.disableControl();
+ scene->_actor5.remove();
+ scene->_actor6.remove();
+ scene->_actor7.remove();
+ scene->_actor8.remove();
+ scene->_actor9.remove();
+ scene->_actor10.remove();
+ R2_GLOBALS._sound2.play(37);
+ scene->_sceneMode = 901;
+ scene->setAction(&scene->_sequenceManager1, scene, 901, &scene->_actor1, this ,NULL);
+ } else if ((scene->_field412 == 2) || (scene->_field412 == 3)) {
+ scene->_sceneMode = 1;
+ scene->signal();
+ }
+
+ return true;
+ break;
+ }
+ } else if (action == CURSOR_LOOK) {
+ if ((_fieldA4 == 2) && (scene->_field412 == 2))
+ SceneItem::display(900, 21, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
+ else
+ SceneItem::display(900, _fieldA4, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
+ return true;
+ } else {
+ return SceneActor::startAction(action, event);
+ }
+}
+
+void Scene900::postInit(SceneObjectList *OwnerList) {
+ g_globals->gfxManager()._bounds.moveTo(Common::Point(0, 0));
+ loadScene(900);
+ SceneExt::postInit();
+ R2_GLOBALS._sound1.play(34);
+
+ R2_GLOBALS._player.postInit();
+ R2_GLOBALS._player.hide();
+ R2_GLOBALS._player.disableControl();
+
+ _actor1.postInit();
+ _actor1.setDetails(900, 3, -1, -1, 1, (SceneItem *) NULL);
+
+ _field414 = 0;
+ _field416 = 0;
+
+ _actor3.postInit();
+ _actor3.fixPriority(1);
+ // useless, the original use it for debugging purposes: strcpy(_actor3._actorName, "Crane");
+ _actor3.setup(900, 1, 2);
+ _actor3.setPosition(Common::Point(89, 0));
+ _actor3._effect = 1;
+ _actor3.setDetails(900, 6, -1, 8, 1, (SceneItem *) NULL);
+
+ if ((R2_INVENTORY.getObjectScene(R2_CABLE_HARNESS) != 1) && (R2_INVENTORY.getObjectScene(R2_ATTRACTOR_CABLE_HARNESS) != 1)) {
+ _actor2.postInit();
+ _actor2.setPosition(Common::Point(0, 0));
+ _actor2.fixPriority(1);
+
+ if (R2_INVENTORY.getObjectScene(R2_CABLE_HARNESS) == 0) {
+ if (R2_INVENTORY.getObjectScene(R2_ATTRACTOR_CABLE_HARNESS) != 700) {
+ _actor2.setup(901, 3, 2);
+ } else if ((R2_GLOBALS._v565E5 != 0) && (R2_GLOBALS._v565E1 == 20) && (R2_GLOBALS._v565E3 == 70)) {
+ _actor2.setup(901, 2, 1);
+ } else {
+ _actor2.setup(901, 2, 8);
+ }
+ _actor2.setPosition(Common::Point(171, 145));
+ _actor2.setDetails(700, -1, -1, -1, 1, (SceneItem *) NULL);
+ } else {
+ _actor2.setDetails(700, -1, -1, -1, 1, (SceneItem *) NULL);
+ if (R2_GLOBALS._v565E7 == 0) {
+ _actor2.setup(901, 1, 8);
+ // Original set two times the same values: skipped
+ _actor2.setPosition(Common::Point((((100 - ((R2_GLOBALS._v565EB * 350) / 100)) * 49) / 100) + ((R2_GLOBALS._v565E9 * _actor3._percent * 6) / 100) + 89, 166 - (R2_GLOBALS._v565EB / 3)));
+ _actor2.changeZoom(((100 - ((R2_GLOBALS._v565EB * 350) / 100) + 52) / 10) * 10);
+ }
+ }
+ }
+ _item1.setDetails(Rect(0, 0, 320, 200), 900, 0, -1, -1, 1, NULL);
+ _sceneMode = 900;
+ setAction(&_sequenceManager1, this, 900, &_actor1, NULL);
+}
+
+void Scene900::remove() {
+ if (_sceneMode != 901)
+ R2_GLOBALS._sound1.play(10);
+
+ SceneExt::remove();
+}
+
+void Scene900::signal() {
+ switch (_sceneMode) {
+ case 1:
+ _field412 = 1;
+ R2_GLOBALS._sound2.play(37);
+
+ _actor5.remove();
+ _actor6.remove();
+ _actor7.remove();
+ _actor8.remove();
+ _actor9.remove();
+ _actor10.remove();
+
+ _actor5.sub96135(2);
+ _actor5.setup(900, 2, 1);
+ _actor5.setPosition(Common::Point(36, 166));
+
+ _actor6.sub96135(3);
+ _actor6.setup(900, 2, 5);
+ _actor6.setPosition(Common::Point(117, 166));
+ break;
+ case 2:
+ _field412 = 2;
+
+ _actor5.remove();
+ _actor6.remove();
+
+ _actor5.sub96135(2);
+ if (R2_GLOBALS._v565E5 == 0)
+ _actor5.setup(900, 3, 9);
+ else
+ _actor5.setup(900, 3, 11);
+ _actor5.setPosition(Common::Point(36, 166));
+
+ _actor7.sub96135(5);
+ _actor7.setup(900, 3, 3);
+ _actor7.setPosition(Common::Point(76, 134));
+
+ _actor8.sub96135(4);
+ _actor8.setup(900, 3, 7);
+ _actor8.setPosition(Common::Point(76, 156));
+
+ _actor9.sub96135(6);
+ _actor9.setup(900, 3, 1);
+ _actor9.setPosition(Common::Point(55, 144));
+
+ _actor10.sub96135(7);
+ _actor10.setup(900, 3, 5);
+ _actor10.setPosition(Common::Point(99, 144));
+
+ break;
+ case 3:
+ _field412 = 3;
+
+ _actor5.remove();
+ _actor6.remove();
+ _actor7.remove();
+ _actor8.remove();
+ _actor9.remove();
+ _actor10.remove();
+
+ _actor5.sub96135(8);
+ _actor5.setup(900, 4, 1);
+ _actor5.setPosition(Common::Point(36, 166));
+
+ _actor6.sub96135(9);
+ _actor6.setup(900, 4, 5);
+ _actor6.setPosition(Common::Point(117, 166));
+ break;
+ case 4:
+ _sceneMode = 0;
+ R2_GLOBALS._player.enableControl();
+ R2_GLOBALS._player._canWalk = false;
+ R2_GLOBALS._v565E7 = 1;
+ break;
+ case 900:
+ R2_GLOBALS._player.enableControl(CURSOR_USE);
+ R2_GLOBALS._player._canWalk = false;
+
+ _actor1.setup(900, 1, 1);
+
+ _actor4.sub96135(1);
+ _actor4.setup(900, 1, 3);
+ _actor4.setPosition(Common::Point(77, 168));
+
+ _sceneMode = 1;
+ signal();
+ break;
+ case 901:
+ R2_GLOBALS._sceneManager.changeScene(700);
+ break;
+ case 5:
+ _sceneMode = 0;
+ // No break on purpose
+ default:
+ R2_GLOBALS._player.enableControl();
+ R2_GLOBALS._player._canWalk = false;
+ break;
+ }
+}
+
+void Scene900::dispatch() {
+ if (_field416 != 0) {
+ if (_field416 < 0) {
+ R2_GLOBALS._v565E3--;
+ ++_field416;
+ } else {
+ ++R2_GLOBALS._v565E3;
+ _field416--;
+ }
+ }
+
+ if (_field414 != 0) {
+ R2_GLOBALS._v565E1--;
+ ++_field414;
+ } else {
+ ++R2_GLOBALS._v565E1;
+ _field414++;
+ }
+
+ if (R2_GLOBALS._sceneObjects->contains(&_actor2)) {
+ if ((R2_GLOBALS._v565E5 != 0) && (R2_INVENTORY.getObjectScene(R2_CABLE_HARNESS) == 0) && (R2_INVENTORY.getObjectScene(R2_ATTRACTOR_CABLE_HARNESS) == 700) && (R2_GLOBALS._v565E1 == 20) && (R2_GLOBALS._v565E3 == 70)) {
+ if ((_actor2._frame > 1) && (_actor2._animateMode != ANIM_MODE_6))
+ _actor2.animate(ANIM_MODE_6, NULL);
+ } else {
+ if ((_actor2._frame < 8) && (_actor2._animateMode != ANIM_MODE_5) && (R2_GLOBALS._v565E7 == 0) && (R2_INVENTORY.getObjectScene(R2_CABLE_HARNESS) == 0) && (R2_INVENTORY.getObjectScene(R2_ATTRACTOR_CABLE_HARNESS) == 700) && (_sceneMode != 4))
+ _actor2.animate(ANIM_MODE_5, NULL);
+ }
+ }
+
+ _actor3.changeZoom(100 - ((R2_GLOBALS._v565E3 * 70) / 100));
+ _actor3.setPosition(Common::Point(((_actor3._percent * R2_GLOBALS._v565E1 * 6) / 100) + 89, R2_GLOBALS._v565E3));
+
+ if ((R2_GLOBALS._sceneObjects->contains(&_actor2)) && (R2_GLOBALS._v565E7 != 0) && (!_actor2._mover) && (_actor2._animateMode == ANIM_MODE_NONE)) {
+ _actor2.setPosition(Common::Point(_actor3._position.x + ((_actor3._percent * 49) / 100), _actor3._position.y + ((_actor3._percent * 3) / 10)));
+ if (R2_GLOBALS._v565E3 >= 75) {
+ _actor2.setup(901, 1, 1);
+ _actor2.changeZoom(((_actor3._percent + 52) / 10) * 10);
+ } else {
+ _actor2.setup(901, 5, 1);
+ _actor2.changeZoom(((_actor3._percent / 10) * 10) + 30);
+ }
}
+ Scene::dispatch();
}
} // End of namespace Ringworld2
diff --git a/engines/tsage/ringworld2/ringworld2_scenes0.h b/engines/tsage/ringworld2/ringworld2_scenes0.h
index c51b044137..2f52f9578f 100644
--- a/engines/tsage/ringworld2/ringworld2_scenes0.h
+++ b/engines/tsage/ringworld2/ringworld2_scenes0.h
@@ -31,6 +31,7 @@
#include "tsage/globals.h"
#include "tsage/sound.h"
#include "tsage/ringworld2/ringworld2_logic.h"
+#include "tsage/ringworld2/ringworld2_speakers.h"
namespace TsAGE {
@@ -38,21 +39,35 @@ namespace Ringworld2 {
using namespace TsAGE;
+class Scene50: public SceneExt {
+
+ class Action1: public Action {
+ public:
+ void signal();
+ };
+
+public:
+ Action1 _action1;
+
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+ virtual void process(Event &event);
+};
+
class Scene100: public SceneExt {
/* Objects */
- class Object7: public SceneActorExt {
+ class Door: public SceneActorExt {
public:
bool startAction(CursorType action, Event &event);
};
- class Object8: public SceneActor {
+ class Table: public SceneActor {
public:
bool startAction(CursorType action, Event &event);
};
- class Object9: public SceneActor {
+ class StasisNegator: public SceneActor {
public:
bool startAction(CursorType action, Event &event);
};
- class Object10: public SceneActorExt {
+ class DoorDisplay: public SceneActorExt {
public:
bool startAction(CursorType action, Event &event);
};
@@ -60,21 +75,829 @@ class Scene100: public SceneExt {
public:
bool startAction(CursorType action, Event &event);
};
+
+ /* Items */
+ class Terminal: public NamedHotspot{
+ public:
+ bool startAction(CursorType action, Event &event);
+ };
+
+public:
+ NamedHotspot _background, _duct, _bed, _desk;
+ Terminal _terminal;
+ SceneActor _bedLights1, _bedLights2, _object3, _object4, _object5;
+ SceneActor _wardrobe;
+ Door _door;
+ Table _table;
+ StasisNegator _stasisNegator;
+ DoorDisplay _doorDisplay;
+ SteppingDisks _steppingDisks;
+ SequenceManager _sequenceManager1, _sequenceManager2;
+
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+ virtual void remove();
+ virtual void signal();
+ virtual void dispatch();
+};
+
+class Scene125: public SceneExt {
+ /* Objects */
+ class Object5: public SceneActor {
+ public:
+ virtual bool startAction(CursorType action, Event &event);
+ };
+
+ class Icon: public SceneActor {
+ public:
+ int _lookLineNum, _field98;
+ bool _pressed;
+ SceneObject _object1, _object2;
+ SceneText _sceneText1, _sceneText2;
+
+ Icon();
+ virtual Common::String getClassName() { return "Scene125_Icon"; }
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+ virtual void synchronize(Serializer &s);
+ virtual void process(Event &event);
+
+ void setIcon(int id);
+ void showIcon();
+ void hideIcon();
+ };
+
+ /* Items */
+ class Item4: public NamedHotspot {
+ public:
+ virtual bool startAction(CursorType action, Event &event);
+ };
+
public:
- NamedHotspot _item1, _item2, _item3, _item4, _item5;
+ ScenePalette _palette;
+ ASoundExt _sound1;
+ NamedHotspot _background, _item2, _item3;
+ Item4 _item4;
+ SceneActor _object1, _object2, _object3, _object4, _object5, _object6, _object7;
+ Icon _icon1, _icon2, _icon3, _icon4, _icon5, _icon6;
+ SequenceManager _sequenceManager;
+ SceneText _sceneText;
+ int _consoleMode, _iconFontNumber, _logIndex, _databaseIndex, _infodiskIndex;
+ int _soundCount, _soundIndex;
+ int _soundIndexes[10];
+
+ Scene125();
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+ virtual void synchronize(Serializer &s);
+ virtual void signal();
+ virtual void process(Event &event);
+ virtual void dispatch();
+
+ void consoleAction(int id);
+ void setDetails(int resNum, int lineNum);
+ void stop();
+ Common::String parseMessage(const Common::String &msg);
+};
+
+class Scene150: public Scene100 {
+public:
+ SceneActor _emptyRoomTable;
+public:
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+ virtual void remove();
+ virtual void signal();
+};
+
+class Scene160: public SceneExt {
+ class Action1: public Action {
+ public:
+ void signal();
+ };
+public:
+ ASound _sound1;
+ Action1 _action1;
+ int _frameNumber, _yChange;
+ SceneObject _object1, _object2, _object3;
+ int _lineNum;
+ SynchronizedList<SceneText *> _creditsList;
+public:
+ Scene160();
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+ virtual void synchronize(Serializer &s);
+ virtual void remove();
+ virtual void process(Event &event);
+};
+
+class Scene175: public Scene150 {
+};
+
+class Scene180: public SceneExt {
+ class Action1: public Action {
+ public:
+ void signal();
+ };
+private:
+ void setSceneDelay(int v);
+public:
+ SpeakerWebbster _webbsterSpeaker;
+ SpeakerDutyOfficer _dutyOfficerSpeaker;
+ SpeakerTeal _tealSpeaker;
+ SpeakerGameText _gameTextSpeaker;
SceneActor _object1, _object2, _object3, _object4, _object5;
- SceneActor _object6;
- Object7 _object7;
+ ScenePalette _palette;
+ SceneText _textList[20];
+ AnimationPlayerExt _animationPlayer;
+ SequenceManager _sequenceManager;
+ Action1 _action1;
+ ASoundExt _sound1;
+
+ int _frameNumber;
+ int _field412, _field480;
+ int _field482, _frameInc;
+ int _fontNumber, _fontHeight;
+ int _scene180Mode;
+public:
+ Scene180();
+
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+ virtual void synchronize(Serializer &s);
+ virtual void remove();
+ virtual void signal();
+ virtual void process(Event &event);
+ virtual void dispatch();
+ virtual void restore();
+};
+
+class Scene200: public SceneExt {
+ /* Objects */
+ class NorthDoor: public SceneActor {
+ public:
+ virtual bool startAction(CursorType action, Event &event);
+ };
+ class EastDoor: public SceneActor {
+ public:
+ virtual bool startAction(CursorType action, Event &event);
+ };
+ class WestDoor: public SceneActor {
+ public:
+ virtual bool startAction(CursorType action, Event &event);
+ };
+
+ /* Scene Exits */
+ class EastExit: public SceneExit {
+ public:
+ virtual void changeScene();
+ };
+ class WestExit: public SceneExit {
+ public:
+ virtual void changeScene();
+ };
+public:
+ NamedHotspot _background, _compartment, _westDoorDisplay, _eastDoorDisplay;
+ NorthDoor _northDoor;
+ EastDoor _eastDoor;
+ WestDoor _westDoor;
+ EastExit _eastExit;
+ WestExit _westExit;
+ SequenceManager _sequenceManager;
+
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+ virtual void signal();
+};
+
+class Scene205: public SceneExt {
+ /* Actions */
+ class Action1: public Action {
+ private:
+ void textLoop();
+ public:
+ virtual void signal();
+ };
+
+ /* Objects */
+ class Object: public SceneObject {
+ public:
+ int _x100, _y100;
+ public:
+ Object();
+
+ virtual void synchronize(Serializer &s);
+ };
+private:
+ void setup();
+ void processList(Object **ObjList, int count, const Common::Rect &bounds,
+ int xMultiply, int yMultiply, int xCenter, int yCenter);
+ void handleText();
+public:
+ AnimationPlayer _animationPlayer;
+ int _fontHeight;
+ SceneText _textList[15];
+ Object *_objList1[3];
+ Object *_objList2[3];
+ Object *_objList3[4];
+ ASound _sound1;
+ Action1 _action1;
+ int _yp;
+ int _textIndex, _lineNum;
+ Common::String _message;
+public:
+ Scene205();
+
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+ virtual void synchronize(Serializer &s);
+ virtual void remove();
+ virtual void process(Event &event);
+ virtual void dispatch();
+};
+
+
+class Scene250: public SceneExt {
+ class Button: public SceneActor {
+ public:
+ int _floorNumber, _v2;
+ Button();
+ void setFloor(int floorNumber);
+
+ virtual void synchronize(Serializer &s);
+ virtual bool startAction(CursorType action, Event &event);
+ };
+public:
+ int _field412, _field414, _field416, _field418, _field41A;
+ NamedHotspot _background, _item2, _item3, _item4;
+ Button _button1, _currentFloor;
+ Button _floor1, _floor2, _floor3, _floor4, _floor5;
+ Button _floor6, _floor7, _floor8, _floor9;
+ ASoundExt _sound1;
+ SequenceManager _sequenceManager1;
+public:
+ Scene250();
+ void changeFloor(int floorNumber);
+
+ virtual void synchronize(Serializer &s);
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+ virtual void signal();
+ virtual void process(Event &event);
+ virtual void dispatch();
+};
+
+class Scene300: public SceneExt {
+ /* Actions */
+ class Action1: public Action {
+ public:
+ virtual void signal();
+ };
+ class Action2: public Action {
+ public:
+ virtual void signal();
+ };
+ class Action3: public Action {
+ public:
+ virtual void signal();
+ };
+ class Action4: public Action {
+ public:
+ virtual void signal();
+ };
+
+ /* Items */
+ class QuinnWorkstation: public NamedHotspot {
+ public:
+ virtual bool startAction(CursorType action, Event &event);
+ };
+ class MirandaWorkstation: public NamedHotspot {
+ public:
+ virtual bool startAction(CursorType action, Event &event);
+ };
+ class SeekerWorkstation: public NamedHotspot {
+ public:
+ virtual bool startAction(CursorType action, Event &event);
+ };
+
+ /* Objects */
+ class Miranda: public SceneActor {
+ public:
+ virtual bool startAction(CursorType action, Event &event);
+ };
+ class Seeker: public SceneActor {
+ public:
+ virtual bool startAction(CursorType action, Event &event);
+ };
+ class Quinn: public SceneActor {
+ public:
+ virtual bool startAction(CursorType action, Event &event);
+ };
+ class Doorway: public SceneActor {
+ public:
+ virtual bool startAction(CursorType action, Event &event);
+ };
+public:
+ SequenceManager _sequenceManager1, _sequenceManager2, _sequenceManager3, _sequenceManager4;
+ ASoundExt _sound1;
+ SpeakerMiranda300 _mirandaSpeaker;
+ SpeakerSeeker300 _seekerSpeaker;
+ SpeakerSeekerL _seekerLSpeaker;
+ SpeakerQuinn300 _quinnSpeaker;
+ SpeakerQuinnL _quinnLSpeaker;
+ SpeakerTeal300 _tealSpeaker;
+ SpeakerSoldier300 _soldierSpeaker;
+
+ NamedHotspot _background, _hull, _statusDisplays, _damageControl, _manualOverrides;
+ NamedHotspot _scanners1, _scanners2, _indirectLighting1, _indirectLighting2, _lighting;
+ QuinnWorkstation _quinnWorkstation1, _quinnWorkstation2;
+ SeekerWorkstation _seekerWorkstation;
+ MirandaWorkstation _mirandaWorkstation1, _mirandaWorkstation2;
+ SceneActor _object1, _object2, _object3, _object4, _protocolDisplay;
+ SceneActor _object6, _object7, _object8, _object9;
+ SceneActor _teal, _soldier, _object12;
+ Doorway _doorway;
+ Miranda _miranda;
+ Seeker _seeker;
+ Quinn _quinn;
+ Action1 _action1;
+ Action2 _action2;
+ Action3 _action3;
+ Action4 _action4;
+ PaletteRotation *_rotation;
+ int _stripId;
+
+ Scene300();
+ void signal309();
+
+ virtual void synchronize(Serializer &s);
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+ virtual void remove();
+ virtual void signal();
+};
+
+class Scene325: public SceneExt {
+ class Icon: public SceneActor {
+ public:
+ int _lookLineNum, _field98;
+ bool _pressed;
+ SceneObject _object1, _object2;
+ SceneText _sceneText1, _sceneText2;
+
+ Icon();
+ virtual Common::String getClassName() { return "Scene325_Icon"; }
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+ virtual void synchronize(Serializer &s);
+ virtual void process(Event &event);
+
+ void setIcon(int id);
+ void showIcon();
+ void hideIcon();
+ };
+
+private:
+ void removeText();
+ void consoleAction(int id);
+ void setMessage(int resNum, int lineNum);
+ Common::String parseMessage(const Common::String &msg);
+public:
+ int _field412, _iconFontNumber, _field416, _field418;
+ int _field41A, _field41C, _field41E, _field420;
+ int _soundCount, _soundIndex;
+ int _soundQueue[10];
+ SpeakerQuinn _quinnSpeaker;
+ ScenePalette _palette;
+ SceneHotspot _background, _item2;
+ SceneObject _object1, _object2, _object3, _object4, _object5;
+ SceneObject _object6, _object7, _object8, _object9, _object10;
+ SceneObject _object11, _object12, _object13;
+ SceneObject _objList[4];
+ Icon _icon1, _icon2, _icon3, _icon4, _icon5, _icon6;
+ ASoundExt _sound1;
+ SequenceManager _sequenceManager1;
+ SceneText _text1;
+public:
+ Scene325();
+
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+ virtual void synchronize(Serializer &s);
+ virtual void remove();
+ virtual void signal();
+ virtual void process(Event &event);
+ virtual void dispatch();
+};
+
+
+class Scene400: public SceneExt {
+ /* Items */
+ class Terminal: public NamedHotspot {
+ public:
+ virtual bool startAction(CursorType action, Event &event);
+ };
+
+ /* Objects */
+ class Door: public SceneActor {
+ public:
+ virtual bool startAction(CursorType action, Event &event);
+ };
+ class Reader: public SceneActor {
+ public:
+ virtual bool startAction(CursorType action, Event &event);
+ };
+ class SensorProbe: public SceneActor {
+ public:
+ virtual bool startAction(CursorType action, Event &event);
+ };
+ class AttractorUnit: public SceneActor {
+ public:
+ virtual bool startAction(CursorType action, Event &event);
+ };
+public:
+ NamedHotspot _background, _equipment1, _equipment2, _equipment3;
+ NamedHotspot _equipment4, _equipment5, _equipment6;
+ NamedHotspot _desk, _desk2, _console;
+ NamedHotspot _duct, _shelves, _cabinet, _doorDisplay, _lights;
+ NamedHotspot _equalizer, _transducer, _optimizer, _soundModule, _tester;
+ NamedHotspot _helmet, _nullifier;
+ Terminal _terminal;
+ SceneActor _consoleDisplay, _testerDisplay;
+ Door _door;
+ Reader _reader;
+ SensorProbe _sensorProbe;
+ AttractorUnit _attractorUnit;
+ SequenceManager _sequenceManager1;
+ ASoundExt _sound1;
+
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+ virtual void remove();
+ virtual void signal();
+ virtual void dispatch();
+};
+
+class Scene500: public SceneExt {
+ /* Items */
+ class ControlPanel: public SceneHotspot {
+ public:
+ virtual bool startAction(CursorType action, Event &event);
+ };
+
+ /* Objects */
+ class Object2: public SceneActor {
+ public:
+ virtual bool startAction(CursorType action, Event &event);
+ };
+ class Object3: public SceneActor {
+ public:
+ virtual bool startAction(CursorType action, Event &event);
+ };
+ class Doorway: public SceneActor {
+ public:
+ virtual bool startAction(CursorType action, Event &event);
+ };
+ class OxygenTanks: public SceneActor {
+ public:
+ virtual bool startAction(CursorType action, Event &event);
+ };
+ class AirLock: public SceneActor {
+ public:
+ virtual bool startAction(CursorType action, Event &event);
+ };
+ class Object8: public SceneActor {
+ // This classes uses a custom draw method
+ };
+ class Aerosol: public SceneActor {
+ public:
+ virtual bool startAction(CursorType action, Event &event);
+ };
+ class SonicStunner: public SceneActor {
+ public:
+ virtual bool startAction(CursorType action, Event &event);
+ };
+ class Locker1: public SceneActor {
+ public:
+ virtual bool startAction(CursorType action, Event &event);
+ };
+ class Locker2: public SceneActor {
+ public:
+ virtual bool startAction(CursorType action, Event &event);
+ };
+ class Object: public SceneActor {
+ public:
+ virtual bool startAction(CursorType action, Event &event);
+ };
+public:
+ int _stripNumber;
+ byte _buffer[2710];
+ SpeakerSeeker _seekerSpeaker;
+ SpeakerQuinn _quinnSpeaker;
+ SceneHotspot _background, _item2;
+ ControlPanel _controlPanel;
+ SceneActor _object1;
+ Object2 _object2;
+ Object3 _object3;
+ Doorway _doorway;
+ OxygenTanks _tanks1, _tanks2;
+ AirLock _airLock;
Object8 _object8;
- Object9 _object9;
- Object10 _object10;
- SteppingDisks _steppingDisks;
+ Aerosol _aerosol;
+ SonicStunner _sonicStunner;
+ Locker1 _locker1;
+ Locker2 _locker2;
+ SceneAreaObject _area1;
+ Object _obj1, _obj2, _obj3;
+ ASoundExt _sound1;
SequenceManager _sequenceManager1, _sequenceManager2;
+public:
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+ virtual void synchronize(Serializer &s);
+ virtual void signal();
+};
+
+class Scene525: public SceneExt {
+public:
+ SceneActor _actor1;
+ SequenceManager _sequenceManager;
+
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+ virtual void signal();
+
+};
+
+class Scene600 : public SceneExt {
+ class Item1 : public NamedHotspot {
+ public:
+ virtual bool startAction(CursorType action, Event &event);
+ };
+ class Item4 : public NamedHotspot {
+ public:
+ virtual bool startAction(CursorType action, Event &event);
+ };
+
+ class Actor4 : public SceneActor {
+ public:
+ virtual void signal();
+ virtual bool startAction(CursorType action, Event &event);
+ virtual void draw();
+ };
+ class Actor5 : public SceneActor {
+ public:
+ virtual bool startAction(CursorType action, Event &event);
+ };
+ class Actor6 : public SceneActor {
+ public:
+ virtual bool startAction(CursorType action, Event &event);
+ };
+ class Actor7 : public SceneActor {
+ public:
+ virtual bool startAction(CursorType action, Event &event);
+ };
+ class Actor8 : public SceneActor {
+ public:
+ virtual bool startAction(CursorType action, Event &event);
+ };
+public:
+ int _field412;
+ Item1 _item1;
+ Item1 _item2;
+ Item1 _item3;
+ Item4 _item4;
+ Item1 _item5;
+ BackgroundSceneObject _object1;
+ SceneActor _actor1;
+ SceneActor _actor2;
+ SceneActor _actor3;
+ Actor4 _actor4;
+ Actor5 _actor5;
+ Actor6 _actor6;
+ Actor7 _actor7;
+ Actor8 _actor8;
+ ASoundExt _aSound1;
+ SequenceManager _sequenceManager1;
+ SequenceManager _sequenceManager2;
+ byte _fieldAD2[256];
+
+ Scene600();
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+ virtual void remove();
+ virtual void signal();
+ virtual void process(Event &event);
+ virtual void dispatch();
+ virtual void synchronize(Serializer &s);
+};
+
+class Scene700: public SceneExt {
+ class Item11 : public NamedHotspot {
+ public:
+ virtual bool startAction(CursorType action, Event &event);
+ };
+ class Item12 : public NamedHotspot {
+ public:
+ virtual bool startAction(CursorType action, Event &event);
+ };
+
+ class Actor2 : public SceneActor {
+ public:
+ virtual bool startAction(CursorType action, Event &event);
+ };
+ class Actor3 : public SceneActor {
+ public:
+ virtual bool startAction(CursorType action, Event &event);
+ };
+ class Actor4 : public SceneActor {
+ public:
+ virtual bool startAction(CursorType action, Event &event);
+ };
+ class Actor5 : public SceneActor {
+ public:
+ virtual bool startAction(CursorType action, Event &event);
+ };
+ class Actor6 : public SceneActor {
+ public:
+ virtual bool startAction(CursorType action, Event &event);
+ };
+public:
+ NamedHotspot _item1;
+ NamedHotspot _item2;
+ NamedHotspot _item3;
+ NamedHotspot _item4;
+ NamedHotspot _item5;
+ NamedHotspot _item6;
+ NamedHotspot _item7;
+ NamedHotspot _item8;
+ NamedHotspot _item9;
+ NamedHotspot _item10;
+ Item11 _item11;
+ Item12 _item12;
+ SceneActor _actor1;
+ Actor2 _actor2;
+ Actor3 _actor3;
+ Actor4 _actor4;
+ Actor5 _actor5;
+ Actor6 _actor6;
+ Actor6 _actor7;
+ Actor6 _actor8;
+ Actor6 _actor9;
+ SequenceManager _sequenceManager;
+ PaletteRotation *_rotation;
+ int _field100E;
+
+ Scene700();
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+ virtual void remove();
+ virtual void signal();
+ virtual void synchronize(Serializer &s);
+};
+
+class Scene800: public SceneExt {
+ /* Items */
+ class Button: public NamedHotspot {
+ public:
+ virtual bool startAction(CursorType action, Event &event);
+ };
+ class CableJunction: public NamedHotspot {
+ public:
+ virtual bool startAction(CursorType action, Event &event);
+ };
+ class DeviceSlot: public NamedHotspot {
+ public:
+ virtual bool startAction(CursorType action, Event &event);
+ };
+
+ /* Objects */
+ class Door: public SceneActor {
+ public:
+ virtual bool startAction(CursorType action, Event &event);
+ };
+ class Tray: public SceneActor {
+ public:
+ virtual bool startAction(CursorType action, Event &event);
+ };
+ class ComScanner: public SceneActor {
+ public:
+ virtual bool startAction(CursorType action, Event &event);
+ };
+ class Cabinet: public SceneActor {
+ public:
+ virtual bool startAction(CursorType action, Event &event);
+ };
+public:
+ NamedHotspot _background, _autoDoc, _diskSlot, _couch;
+ NamedHotspot _medicalDatabase, _dataConduits;
+ Button _button;
+ CableJunction _cableJunction;
+ DeviceSlot _deviceSlot;
+ SceneActor _autodocCover, _opticalFibre, _reader;
+ Door _door;
+ Tray _tray;
+ ComScanner _comScanner;
+ Cabinet _cabinet;
+ SequenceManager _sequenceManager1;
+
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+ virtual void signal();
+};
+
+class Scene825: public SceneExt {
+ /* Objects */
+ class Button: public SceneObject {
+ public:
+ int _buttonId, _v2;
+ bool _buttonDown;
+ SceneText _sceneText;
+ public:
+ Button();
+ void setButton(int buttonId);
+ void setText(int textId);
+
+ virtual void synchronize(Serializer &s);
+ virtual void process(Event &event);
+ virtual bool startAction(CursorType action, Event &event);
+ };
+public:
+ NamedHotspot _background, _item2;
+ SceneActor _object1, _object2, _object3, _object4, _object5;
+ Button _button1, _button2, _button3, _button4, _button5, _button6;
+ ASoundExt _sound1, _sound2, _sound3, _sound4;
+ SequenceManager _sequenceManager1;
+ SceneText _sceneText;
+ int _menuId, _frame1, _frame2;
+ const char *_autodocItems[11];
+public:
+ Scene825();
+ virtual void synchronize(Serializer &s);
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+ virtual void remove();
+ virtual void signal();
+ virtual void process(Event &event);
+ virtual void dispatch();
+
+ void doButtonPress(int buttonId);
+};
+
+class Scene850: public SceneExt {
+ /* Items */
+ class Indicator: public NamedHotspot {
+ public:
+ virtual bool startAction(CursorType action, Event &event);
+ };
+
+ /* Objects */
+ class LiftDoor: public SceneActor {
+ public:
+ virtual bool startAction(CursorType action, Event &event);
+ };
+ class SickBayDoor: public SceneActor {
+ public:
+ virtual bool startAction(CursorType action, Event &event);
+ };
+ class Clamp: public SceneActor {
+ public:
+ virtual bool startAction(CursorType action, Event &event);
+ };
+ class Panel: public SceneActor {
+ public:
+ virtual bool startAction(CursorType action, Event &event);
+ };
+public:
+ NamedHotspot _background, _eastDoor, _compartment, _sickBayIndicator;
+ NamedHotspot _liftControls;
+ Indicator _indicator;
+ SceneActor _object1, _fibre;
+ LiftDoor _liftDoor;
+ SickBayDoor _sickBayDoor;
+ Clamp _clamp;
+ Panel _panel;
+ SequenceManager _sequenceManager1;
+
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+ virtual void signal();
+};
+
+class Scene900 : public SceneExt {
+ class Actor4 : public SceneActor {
+ public:
+ int _fieldA4;
+
+ Actor4();
+ void sub96135(int arg1);
+ virtual void synchronize(Serializer &s);
+ virtual bool startAction(CursorType action, Event &event);
+ };
+public:
+ int _field412;
+ int _field414;
+ int _field416;
+ NamedHotspot _item1;
+ SceneActor _actor1;
+ SceneActor _actor2;
+ SceneActor _actor3;
+ Actor4 _actor4;
+ Actor4 _actor5;
+ Actor4 _actor6;
+ Actor4 _actor7;
+ Actor4 _actor8;
+ Actor4 _actor9;
+ Actor4 _actor10;
+ ASoundExt _aSound1;
+ SequenceManager _sequenceManager1;
+ Scene900();
virtual void postInit(SceneObjectList *OwnerList = NULL);
virtual void remove();
virtual void signal();
virtual void dispatch();
+ virtual void synchronize(Serializer &s);
};
} // End of namespace Ringworld2
diff --git a/engines/tsage/ringworld2/ringworld2_scenes1.cpp b/engines/tsage/ringworld2/ringworld2_scenes1.cpp
new file mode 100644
index 0000000000..304d3a4298
--- /dev/null
+++ b/engines/tsage/ringworld2/ringworld2_scenes1.cpp
@@ -0,0 +1,14622 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "tsage/scenes.h"
+#include "tsage/tsage.h"
+#include "tsage/staticres.h"
+#include "tsage/ringworld2/ringworld2_scenes1.h"
+
+namespace TsAGE {
+
+namespace Ringworld2 {
+
+/*--------------------------------------------------------------------------
+ * Scene 1010 - Cutscene: A pixel lost in space!
+ *
+ *--------------------------------------------------------------------------*/
+void Scene1010::postInit(SceneObjectList *OwnerList) {
+ SceneExt::postInit();
+ loadScene(1010);
+
+ R2_GLOBALS._uiElements._active = false;
+ setZoomPercents(100, 1, 160, 100);
+ R2_GLOBALS._player.postInit();
+ R2_GLOBALS._player.setObjectWrapper(NULL);
+ R2_GLOBALS._player.setPosition(Common::Point(30, 264));
+ R2_GLOBALS._player.changeZoom(-1);
+ R2_GLOBALS._player.disableControl();
+
+ setAction(&_sequenceManager, this, 1, &R2_GLOBALS._player, NULL);
+
+ if (R2_GLOBALS.getFlag(57))
+ _sceneMode = 1;
+ else {
+ R2_GLOBALS._sound1.play(89);
+ _sceneMode = 0;
+ }
+}
+
+void Scene1010::signal() {
+ switch (_sceneMode) {
+ case 1: {
+ _sceneMode = 2;
+ R2_GLOBALS._player.setup(1010, 2, 1);
+ R2_GLOBALS._player.setPosition(Common::Point(297, 101));
+ Common::Point pt(30, 264);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, this);
+ }
+ break;
+ case 2:
+ _sceneMode = 3;
+ setAction(&_sequenceManager, this, 1, &R2_GLOBALS._player, NULL);
+ R2_GLOBALS._player.hide();
+ break;
+ case 3:
+ if (R2_GLOBALS.getFlag(57))
+ R2_GLOBALS._sceneManager.changeScene(1500);
+ else
+ R2_GLOBALS._sceneManager.changeScene(1000);
+ break;
+ default: {
+ _sceneMode = 2;
+ R2_GLOBALS._player.setup(1010, 1, 1);
+ Common::Point pt(297, 101);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, this);
+ }
+ break;
+ }
+}
+
+/*--------------------------------------------------------------------------
+ * Scene 1020 -
+ *
+ *--------------------------------------------------------------------------*/
+void Scene1020::postInit(SceneObjectList *OwnerList) {
+ SceneExt::postInit();
+ loadScene(1020);
+
+ if (R2_GLOBALS._sceneManager._previousScene == 1010)
+ g_globals->gfxManager()._bounds.moveTo(Common::Point(160, 0));
+
+ R2_GLOBALS._v558B6.set(160, 0, 160, 161);
+ R2_GLOBALS._uiElements._active = false;
+ R2_GLOBALS._player.postInit();
+
+ if (R2_GLOBALS._sceneManager._previousScene == 1010) {
+ R2_GLOBALS._player.setPosition(Common::Point(500, 100));
+ R2_GLOBALS._player.setup(1020, 1, 1);
+ } else {
+ R2_GLOBALS._player.setPosition(Common::Point(0, 100));
+ R2_GLOBALS._player.setup(1020, 2, 1);
+ }
+
+ R2_GLOBALS._player.setObjectWrapper(NULL);
+ R2_GLOBALS._player.hide();
+ R2_GLOBALS._player.disableControl();
+ setAction(&_sequenceManager, this, 1, &R2_GLOBALS._player, NULL);
+
+ if (R2_GLOBALS._sceneManager._previousScene == 1010)
+ _sceneMode = 0;
+ else
+ _sceneMode = 10;
+}
+
+void Scene1020::signal() {
+ switch (_sceneMode) {
+ case 0: {
+ _sceneMode = 1;
+ R2_GLOBALS._player.show();
+ R2_GLOBALS._player.setPosition(Common::Point(347, 48));
+ R2_GLOBALS._player._moveDiff = Common::Point(2, 1);
+ R2_GLOBALS._player.setZoom(0);
+ Common::Point pt(392, 41);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, this);
+ }
+ break;
+ case 1:
+ _sceneMode = 2;
+ R2_GLOBALS._player.setZoom(100);
+ R2_GLOBALS._player.animate(ANIM_MODE_5, this);
+ break;
+ case 2: {
+ _sceneMode = 3;
+ R2_GLOBALS._player._moveDiff = Common::Point(30, 15);
+ Common::Point pt(-15, 149);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, this);
+ }
+ break;
+ case 3:
+ _sceneMode = 4;
+ setAction(&_sequenceManager, this, 1, &R2_GLOBALS._player, NULL);
+ break;
+ case 4:
+ R2_GLOBALS.setFlag(51);
+ R2_GLOBALS._sceneManager.changeScene(300);
+ break;
+ case 10: {
+ _sceneMode = 11;
+ R2_GLOBALS._player.setPosition(Common::Point(25, 133));
+ R2_GLOBALS._player._moveDiff = Common::Point(30, 15);
+ R2_GLOBALS._player.setZoom(100);
+ Common::Point pt(355, 60);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, this);
+ }
+ break;
+ case 11:
+ R2_GLOBALS._player.setPosition(Common::Point(355, 57));
+ _sceneMode = 12;
+ R2_GLOBALS._player.animate(ANIM_MODE_5, this);
+ break;
+ case 12: {
+ R2_GLOBALS._player.setPosition(Common::Point(355, 60));
+ _sceneMode = 13;
+ R2_GLOBALS._player._moveDiff = Common::Point(3, 1);
+ Common::Point pt(347, 48);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, this);
+ }
+ break;
+ case 13:
+ setAction(&_sequenceManager, this, 1, &R2_GLOBALS._player, NULL);
+ if (R2_GLOBALS._player._percent < 1)
+ _sceneMode = 14;
+ break;
+ case 14:
+ R2_GLOBALS._sceneManager.changeScene(1010);
+ break;
+ default:
+ break;
+ }
+}
+
+void Scene1020::dispatch() {
+ if (_sceneMode == 1) {
+ R2_GLOBALS._player.setZoom(R2_GLOBALS._player._percent + 1);
+ if (R2_GLOBALS._player._percent > 10)
+ R2_GLOBALS._player._moveDiff.x = 3;
+ if (R2_GLOBALS._player._percent > 20)
+ R2_GLOBALS._player._moveDiff.x = 4;
+ }
+
+ if ((_sceneMode == 13) && (R2_GLOBALS._player._percent != 0)) {
+ R2_GLOBALS._player.setZoom(R2_GLOBALS._player._percent - 2);
+ if (R2_GLOBALS._player._percent < 80)
+ R2_GLOBALS._player._moveDiff.x = 2;
+ if (R2_GLOBALS._player._percent < 70)
+ R2_GLOBALS._player._moveDiff.x = 1;
+ }
+
+ Scene::dispatch();
+}
+
+/*--------------------------------------------------------------------------
+ * Scene 1100 -
+ *
+ *--------------------------------------------------------------------------*/
+Scene1100::Scene1100() {
+ _field412 = 0;
+ _field414 = 0;
+}
+
+void Scene1100::synchronize(Serializer &s) {
+ SceneExt::synchronize(s);
+
+ s.syncAsSint16LE(_field412);
+ s.syncAsSint16LE(_field414);
+}
+
+bool Scene1100::Actor16::startAction(CursorType action, Event &event) {
+ Scene1100 *scene = (Scene1100 *)R2_GLOBALS._sceneManager._scene;
+
+ if (action != CURSOR_TALK)
+ return SceneActor::startAction(action, event);
+
+ if (R2_GLOBALS.getFlag(52)) {
+ R2_GLOBALS._player.disableControl();
+ if (R2_GLOBALS._player._characterIndex == 1)
+ scene->_field412 = 327;
+ else
+ scene->_field412 = 328;
+ scene->_sceneMode = 53;
+ scene->setAction(&scene->_sequenceManager1, scene, 1122, &R2_GLOBALS._player, NULL);
+ } else {
+ R2_GLOBALS._player.disableControl();
+ scene->_sceneMode = 55;
+ if (R2_GLOBALS._v565AE >= 3) {
+ if (R2_GLOBALS._player._characterIndex == 1)
+ scene->_stripManager.start3(329, scene, R2_GLOBALS._stripManager_lookupList);
+ else
+ scene->_stripManager.start3(330, scene, R2_GLOBALS._stripManager_lookupList);
+ } else {
+ ++R2_GLOBALS._v565AE;
+ R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
+ if (R2_GLOBALS._player._characterIndex == 1)
+ scene->_stripManager.start3(304, scene, R2_GLOBALS._stripManager_lookupList);
+ else
+ scene->_stripManager.start3(308, scene, R2_GLOBALS._stripManager_lookupList);
+ }
+ }
+ return true;
+}
+
+bool Scene1100::Actor17::startAction(CursorType action, Event &event) {
+ Scene1100 *scene = (Scene1100 *)R2_GLOBALS._sceneManager._scene;
+
+ switch (action) {
+ case R2_NEGATOR_GUN:
+ if (_visage == 1105) {
+ R2_GLOBALS._player.disableControl();
+ scene->_sceneMode = 1114;
+ scene->setAction(&scene->_sequenceManager1, scene, 1114, &R2_GLOBALS._player, &scene->_actor17, NULL);
+ return true;
+ } else {
+ return SceneActor::startAction(action, event);
+ }
+ break;
+ case R2_SONIC_STUNNER:
+ // No break on purpose
+ case R2_PHOTON_STUNNER:
+ if (_visage == 1105) {
+ R2_GLOBALS._player.disableControl();
+ if (R2_GLOBALS._player._characterIndex == 1) {
+ scene->_sceneMode = 1112;
+ scene->setAction(&scene->_sequenceManager1, scene, 1112, &R2_GLOBALS._player, &scene->_actor17, NULL);
+ } else {
+ scene->_sceneMode = 1115;
+ scene->setAction(&scene->_sequenceManager1, scene, 1115, &R2_GLOBALS._player, &scene->_actor17, NULL);
+ }
+ return true;
+ } else if (_strip == 2) {
+ R2_GLOBALS._player.disableControl();
+ scene->_sceneMode = 1113;
+ if (R2_GLOBALS._player._characterIndex == 1) {
+ scene->setAction(&scene->_sequenceManager1, scene, 1113, &R2_GLOBALS._player, &scene->_actor17, NULL);
+ } else {
+ scene->setAction(&scene->_sequenceManager1, scene, 1118, &R2_GLOBALS._player, &scene->_actor17, NULL);
+ }
+ return true;
+ } else {
+ return SceneActor::startAction(action, event);
+ }
+ break;
+ default:
+ return SceneActor::startAction(action, event);
+ break;
+ }
+}
+
+bool Scene1100::Actor18::startAction(CursorType action, Event &event) {
+ Scene1100 *scene = (Scene1100 *)R2_GLOBALS._sceneManager._scene;
+
+ if ((action == CURSOR_TALK) && (!R2_GLOBALS.getFlag(54)) && (R2_GLOBALS.getFlag(52))) {
+ scene->_field412 = 0;
+ R2_GLOBALS._player.disableControl();
+ scene->_sceneMode = 53;
+ scene->setAction(&scene->_sequenceManager1, scene, 1122, &R2_GLOBALS._player, NULL);
+ return true;
+ }
+
+ return SceneActor::startAction(action, event);
+}
+
+void Scene1100::postInit(SceneObjectList *OwnerList) {
+ if ((R2_GLOBALS._sceneManager._previousScene == 300) || (R2_GLOBALS._sceneManager._previousScene == 1100))
+ loadScene(1150);
+ else
+ loadScene(1100);
+
+ if ((R2_GLOBALS._sceneManager._previousScene == 1000) && (!R2_GLOBALS.getFlag(44))) {
+ R2_GLOBALS._uiElements._active = false;
+ R2_GLOBALS._v5589E.left = 0;
+ R2_GLOBALS._v5589E.right = 200;
+ }
+
+ if (R2_GLOBALS._player._characterScene[1] == 1100)
+ R2_GLOBALS._sceneManager._previousScene = 1100;
+
+ if (R2_GLOBALS._sceneManager._previousScene == -1) {
+ R2_GLOBALS._uiElements._active = false;
+ R2_GLOBALS._v5589E.left = 0;
+ R2_GLOBALS._v5589E.right = 200;
+ }
+
+ SceneExt::postInit();
+
+ if (R2_GLOBALS._sceneManager._previousScene == -1)
+ R2_GLOBALS._sceneManager._previousScene = 1000;
+
+ _stripManager.setColors(60, 255);
+ _stripManager.setFontNumber(3);
+ _stripManager.addSpeaker(&_seekerSpeaker);
+ _stripManager.addSpeaker(&_quinnSpeaker);
+ _stripManager.addSpeaker(&_chiefSpeaker);
+
+ scalePalette(65, 65, 65);
+
+ _actor2.postInit();
+ _actor2.setup(1100, 1, 1);
+ _actor2.fixPriority(10);
+
+ R2_GLOBALS._scrollFollower = NULL;
+
+ _item3.setDetails(Rect(56, 47, 68, 83), 1100, 7, -1, -1, 1, NULL);
+ _item4.setDetails(Rect(167, 132, 183, 167), 1100, 7, -1, -1, 1, NULL);
+ _item5.setDetails(Rect(26, 112, 87, 145), 1100, 13, -1, -1, 1, NULL);
+ _item7.setDetails(Rect(4, 70, 79, 167), 1100, 16, -1, -1, 1, NULL);
+
+ R2_GLOBALS._sound1.stop();
+
+ if (R2_GLOBALS._sceneManager._previousScene == 300) {
+ if (R2_GLOBALS._player._characterIndex == 3)
+ R2_GLOBALS._player._characterIndex = R2_QUINN;
+ R2_GLOBALS._player._characterScene[1] = 1100;
+ R2_GLOBALS._player._characterScene[2] = 1100;
+ _actor2.setPosition(Common::Point(150, 30));
+ R2_GLOBALS._sound1.play(93);
+ R2_GLOBALS._player.postInit();
+ R2_GLOBALS._player.hide();
+ R2_GLOBALS._player.disableControl();
+
+ _actor16.postInit();
+ _actor16.hide();
+ if (R2_GLOBALS._player._characterIndex == 1)
+ _actor16.setDetails(9002, 0, 4, 3, 1, (SceneItem *) NULL);
+ else
+ _actor16.setDetails(9001, 0, 5, 3, 1, (SceneItem *) NULL);
+
+ _actor18.postInit();
+ _actor18.setup(1113, 3, 1);
+ _actor18.setPosition(Common::Point(181, 125));
+ _actor18.fixPriority(110);
+
+ if (R2_GLOBALS.getFlag(54))
+ _actor18.setDetails(1100, 4, -1, -1, 1, (SceneItem *) NULL);
+ else
+ _actor18.setDetails(1100, 3, -1, -1, 1, (SceneItem *) NULL);
+
+ _actor17.postInit();
+ _actor17.setup(1105, 3, 1);
+ _actor17.setPosition(Common::Point(312, 165));
+ _actor17._numFrames = 5;
+ _actor17.setDetails(1100, 22, 23, 24, 1, (SceneItem *) NULL);
+
+ _actor1.postInit();
+ _actor1.setup(1512, 1, 1);
+ _actor1.setPosition(Common::Point(187, -25));
+ _actor1.fixPriority(48);
+ _actor1._moveDiff.y = 1;
+ _actor1.setDetails(1100, 37, -1, -1, 1, (SceneItem *) NULL);
+
+ _sceneMode = 20;
+
+ setAction(&_sequenceManager1, this, 1, &R2_GLOBALS._player, NULL);
+ } else if (R2_GLOBALS._sceneManager._previousScene == 1000) {
+ _actor2.setPosition(Common::Point(50, 30));
+ _field414 = 0;
+ _palette1.loadPalette(1101);
+ R2_GLOBALS._player.postInit();
+ R2_GLOBALS._player.disableControl();
+ R2_GLOBALS._player._effect = 5;
+ R2_GLOBALS._player._field9C = _field312;
+ R2_GLOBALS._player.setup(1102, 3, 2);
+ R2_GLOBALS._player.setObjectWrapper(NULL);
+ R2_GLOBALS._player.setPosition(Common::Point(111,-20));
+ R2_GLOBALS._player.fixPriority(150);
+ R2_GLOBALS._player._moveRate = 30;
+ R2_GLOBALS._player._moveDiff = Common::Point(16, 2);
+
+ _object1.setup2(1104, 2, 1, 175, 125, 102, 1);
+ _object2.setup2(1102, 5, 1, 216, 167, 1, 0);
+
+ _actor12.postInit();
+ _actor12.setup(1113, 2, 1);
+ _actor12.setPosition(Common::Point(67, 151));
+ _actor12.fixPriority(255);
+
+ _actor3.postInit();
+ _actor3.setup(1102, 6, 1);
+ _actor3._moveRate = 30;
+ _actor3._moveDiff.x = 2;
+
+ _actor4.postInit();
+ _actor4.setup(1102, 6, 2);
+ _actor4._moveRate = 30;
+ _actor4._moveDiff.x = 2;
+ _actor4._effect = 5;
+ _actor4._field9C = _field312;
+
+ R2_GLOBALS._sound1.play(86);
+
+ _sceneMode = 0;
+
+ setAction(&_sequenceManager1, this, 1, &R2_GLOBALS._player, NULL);
+ } else {
+ _actor2.setPosition(Common::Point(180, 30));
+ if (R2_GLOBALS.getFlag(52))
+ R2_GLOBALS._sound1.play(98);
+ else
+ R2_GLOBALS._sound1.play(95);
+
+ R2_GLOBALS._player.postInit();
+ R2_GLOBALS._player.animate(ANIM_MODE_1, NULL);
+
+ _actor16.postInit();
+
+ if (R2_GLOBALS.getFlag(52)) {
+ if (R2_GLOBALS._player._characterIndex == 1) {
+ R2_GLOBALS._player.setup(19, 7, 1);
+ _actor16.setup(29, 6, 1);
+ } else {
+ R2_GLOBALS._player.setup(29, 7, 1);
+ _actor16.setup(19, 6, 1);
+ }
+ R2_GLOBALS._player.setPosition(Common::Point(140, 124));
+ _actor16.setPosition(Common::Point(237, 134));
+ R2_GLOBALS._player.enableControl();
+ } else {
+ if (R2_GLOBALS._player._characterIndex == 1) {
+ R2_GLOBALS._player.setup(1107, 2, 1);
+ _actor16.setup(1107, 4, 1);
+ R2_GLOBALS._player.setPosition(Common::Point(247, 169));
+ _actor16.setPosition(Common::Point(213, 169));
+ } else {
+ R2_GLOBALS._player.setup(1107, 4, 1);
+ _actor16.setup(1107, 2, 1);
+ R2_GLOBALS._player.setPosition(Common::Point(213, 169));
+ _actor16.setPosition(Common::Point(247, 169));
+ }
+ R2_GLOBALS._player.enableControl();
+ R2_GLOBALS._player._canWalk = false;
+ }
+
+ if (R2_GLOBALS._player._characterIndex == 1)
+ _actor16.setDetails(9002, 0, 4, 3, 1, (SceneItem *) NULL);
+ else
+ _actor16.setDetails(9001, 0, 5, 3, 1, (SceneItem *) NULL);
+
+ _actor18.postInit();
+ _actor18.setup(1113, 3, 1);
+ _actor18.setPosition(Common::Point(181, 125));
+ _actor18.fixPriority(110);
+
+ if (R2_GLOBALS.getFlag(54))
+ _actor18.setDetails(1100, 4, -1, -1, 1, (SceneItem *) NULL);
+ else
+ _actor18.setDetails(1100, 3, -1, -1, 1, (SceneItem *) NULL);
+
+ if (!R2_GLOBALS.getFlag(52)) {
+ _actor17.postInit();
+ if (R2_GLOBALS.getFlag(53))
+ _actor17.setup(1106, 2, 4);
+ else
+ _actor17.setup(1105, 4, 4);
+
+ _actor17.setPosition(Common::Point(17, 54));
+ _actor17._numFrames = 5;
+
+ if (R2_GLOBALS.getFlag(53))
+ _actor17.setDetails(1100, 28, -1, -1, 1, (SceneItem *) NULL);
+ else
+ _actor17.setDetails(1100, 22, 23, 24, 1, (SceneItem *) NULL);
+
+ _actor17.fixPriority(200);
+ }
+ _actor1.postInit();
+ _actor1.setup(1512, 1, 1);
+ _actor1.setPosition(Common::Point(187, 45));
+ _actor1.fixPriority(48);
+ _actor1._moveDiff.y = 1;
+ _actor1.setDetails(1100, 37, -1, -1, 1, (SceneItem *) NULL);
+ }
+ _item6.setDetails(Rect(123, 69, 222, 105), 1100, 13, -1, -1, 1, NULL);
+ _item2.setDetails(Rect(0, 0, 480, 46), 1100, 0, -1, -1, 1, NULL);
+ _item1.setDetails(Rect(0, 0, 480, 200), 1100, 40, 41, 42, 1, NULL);
+}
+
+void Scene1100::remove() {
+ R2_GLOBALS._scrollFollower = &R2_GLOBALS._player;
+ if (_sceneMode > 20)
+ R2_GLOBALS._sound1.fadeOut2(NULL);
+ g_globals->gfxManager()._bounds.moveTo(Common::Point(0, 0));
+ R2_GLOBALS._uiElements._active = true;
+ SceneExt::remove();
+}
+
+void Scene1100::signal() {
+ switch (_sceneMode++) {
+ case 0:
+ _actor3.setPosition(Common::Point(350, 20));
+ setAction(&_sequenceManager1, this, 1, &R2_GLOBALS._player, NULL);
+ break;
+ case 1:{
+ Common::Point pt(-150, 20);
+ NpcMover *mover = new NpcMover();
+ _actor3.addMover(mover, &pt, this);
+ _actor4.setPosition(Common::Point(350, 55));
+
+ Common::Point pt2(-150, 55);
+ NpcMover *mover2 = new NpcMover();
+ _actor4.addMover(mover2, &pt2, NULL);
+ }
+ break;
+ case 2:
+ _actor3.remove();
+ _actor4.remove();
+ _actor5.postInit();
+ _actor6.postInit();
+ _actor7.postInit();
+ _actor8.postInit();
+ _actor9.postInit();
+ _actor10.postInit();
+ setAction(&_sequenceManager1, this, 1102, &_actor5, &_actor6, &_actor7, &_actor8, &_actor9, &_actor10, NULL);
+ break;
+ case 3: {
+ R2_GLOBALS._sound2.play(84);
+ R2_GLOBALS._player.setPosition(Common::Point(-50, 126));
+ Common::Point pt(350, 226);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, this);
+ }
+ break;
+ case 4:
+ _actor18.postInit();
+ _actor18.show();
+ setAction(&_sequenceManager1, this, 1101, &_actor18, &_actor10, NULL);
+ break;
+ case 5:
+ _actor13.postInit();
+ _actor13._effect = 6;
+ _actor13.setup(1103, 3, 1);
+ _actor13._moveRate = 30;
+
+ _actor14.postInit();
+ _actor14._effect = 6;
+ _actor14.setup(1103, 4, 1);
+ _actor4._moveRate = 25;
+
+ _actor13.setAction(&_sequenceManager2, this, 1109, &_actor13, &_actor14, NULL);
+ break;
+ case 6: {
+ _actor13.remove();
+ _actor14.remove();
+ R2_GLOBALS._player.setPosition(Common::Point(-50, 136));
+ R2_GLOBALS._sound2.play(84);
+ Common::Point pt(350, 236);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, this);
+ }
+ break;
+ case 7:
+ setAction(&_sequenceManager1, this, 1103, &_actor18, &_actor10);
+ break;
+ case 8:
+ R2_GLOBALS._player._effect = 0;
+ _actor11.postInit();
+ setAction(&_sequenceManager1, this, 1105, &R2_GLOBALS._player, &_actor10, &_actor11, &_actor18, NULL);
+ break;
+ case 9:
+ _object1.proc27();
+
+ _actor15.postInit();
+ _actor15.setup(1103, 2, 1);
+ _actor15._moveRate = 30;
+ _actor15.setAction(&_sequenceManager3, this, 1107, &_actor15, NULL);
+ break;
+ case 10:
+ _actor13.postInit();
+ _actor13.setup(1103, 1, 1);
+ _actor13._moveRate = 15;
+ _actor13.setAction(&_sequenceManager2, this, 1108, &_actor13, NULL);
+ break;
+ case 11: {
+ setAction(&_sequenceManager1, this, 1116, &_actor11, &_actor10, &_actor12, NULL);
+ R2_GLOBALS._player._effect = 5;
+ R2_GLOBALS._player.setup(1102, 3, 2);
+ R2_GLOBALS._player.setPosition(Common::Point(-50, 131));
+ R2_GLOBALS._sound2.play(84);
+ Common::Point pt(350, 231);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, this);
+ }
+ break;
+ case 12:
+ // Really nothing
+ break;
+ case 13:
+ _actor17.postInit();
+ R2_GLOBALS._scrollFollower = &_actor17;
+
+ _actor11.setup(1100, 2, 1);
+ _actor11.setPosition(Common::Point(408, 121));
+
+ _actor10.setup(1100, 3, 5);
+ _actor10.setPosition(Common::Point(409, 121));
+
+ setAction(&_sequenceManager1, this, 1104, &_actor17, NULL);
+ break;
+ case 14:
+ setAction(&_sequenceManager1, this, 1100, &_actor11, &_actor10, NULL);
+ break;
+ case 15:
+ R2_GLOBALS._sceneManager.changeScene(1000);
+ break;
+ case 20: {
+ Common::Point pt(187, -13);
+ NpcMover *mover = new NpcMover();
+ _actor1.addMover(mover, &pt, this);
+ }
+ break;
+ case 21: {
+ R2_GLOBALS._sound2.play(92);
+ _actor17.animate(ANIM_MODE_5, NULL);
+ Common::Point pt(187, 45);
+ NpcMover *mover = new NpcMover();
+ _actor1.addMover(mover, &pt, this);
+ }
+ break;
+ case 22:
+ setAction(&_sequenceManager1, this, 1110, &_actor16, &R2_GLOBALS._player, NULL);
+ break;
+ case 23:
+ R2_GLOBALS._player.disableControl();
+ R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
+ _stripManager.start(312, this);
+ R2_GLOBALS._player.setAction(&_sequenceManager1, this, 1119, &R2_GLOBALS._player, NULL);
+ break;
+ case 24:
+ if (!_stripManager._endHandler)
+ R2_GLOBALS._player.disableControl();
+ break;
+ case 25:
+ R2_GLOBALS._player.disableControl();
+ _stripManager._lookupList[9] = 1;
+ _stripManager._lookupList[10] = 1;
+ _stripManager._lookupList[11] = 1;
+ R2_GLOBALS._sound1.play(95);
+ setAction(&_sequenceManager1, this, 1111, &_actor17, &R2_GLOBALS._player, &_actor16, NULL);
+ break;
+ case 26:
+ R2_GLOBALS._player.disableControl();
+ R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
+ _stripManager.start(302, this);
+ break;
+ case 27:
+ R2_GLOBALS._player.disableControl();
+ setAction(&_sequenceManager1, this, 1120, &_actor16, &R2_GLOBALS._player, NULL);
+ break;
+ case 28:
+ R2_GLOBALS._player.disableControl();
+ R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
+ _stripManager.start(303, this);
+ break;
+ case 51:
+ R2_GLOBALS.setFlag(53);
+ _actor17.setDetails(1100, 28, -1, -1, 3, (SceneItem *) NULL);
+ // No break on purpose
+ case 50:
+ // No break on purpose
+ case 29:
+ R2_GLOBALS._player.enableControl(CURSOR_USE);
+ break;
+ case 52:
+ R2_GLOBALS._sound1.play(98);
+ R2_GLOBALS.setFlag(52);
+ R2_GLOBALS._player.disableControl();
+ _sceneMode = 1116;
+ if (R2_GLOBALS._player._characterIndex == 1) {
+ setAction(&_sequenceManager1, this, 1116, &R2_GLOBALS._player, NULL);
+ _actor16.setAction(&_sequenceManager2, NULL, 1123, &_actor16, NULL);
+ } else {
+ setAction(&_sequenceManager1, this, 1124, &R2_GLOBALS._player, NULL);
+ _actor16.setAction(&_sequenceManager2, NULL, 1117, &_actor16, NULL);
+ }
+ break;
+ case 53:
+ _sceneMode = 54;
+ R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
+ if (_field412 == 0) {
+ R2_GLOBALS.setFlag(55);
+ if (R2_GLOBALS.getFlag(55)) {
+ if (R2_GLOBALS._player._characterIndex == 1)
+ _stripManager.start(318, this);
+ else
+ _stripManager.start(323, this);
+ } else {
+ // This part is totally useless as flag 55 has been set right before the check
+ if (R2_GLOBALS._player._characterIndex == 1)
+ _stripManager.start(317, this);
+ else
+ _stripManager.start(322, this);
+ }
+ } else {
+ _stripManager.start3(_field412, this, _stripManager._lookupList);
+ }
+ break;
+ case 54:
+ if (_stripManager._field2E8 == 1) {
+ R2_GLOBALS._player.disableControl();
+ _sceneMode = 1125;
+ setAction(&_sequenceManager1, this, 1125, &R2_GLOBALS._player, &_actor16, NULL);
+ } else
+ R2_GLOBALS._player.enableControl(CURSOR_TALK);
+ break;
+ case 55:
+ R2_GLOBALS._player.enableControl(CURSOR_TALK);
+ R2_GLOBALS._player._canWalk = false;
+ break;
+ case 99:
+ R2_GLOBALS._player._characterScene[1] = 300;
+ R2_GLOBALS._player._characterScene[2] = 300;
+ R2_GLOBALS._player._characterIndex = R2_QUINN;
+ R2_GLOBALS._sceneManager.changeScene(300);
+ break;
+ case 1112:
+ _sceneMode = 50;
+ R2_GLOBALS._player.disableControl();
+ R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
+ _stripManager.start3(313, this, _stripManager._lookupList);
+ break;
+ case 1113:
+ _sceneMode = 52;
+ R2_GLOBALS._player.disableControl();
+ R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
+ R2_GLOBALS._sound1.play(96);
+ _stripManager.start3(316, this, _stripManager._lookupList);
+ break;
+ case 1114:
+ _sceneMode = 51;
+ R2_GLOBALS._player.disableControl();
+ R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
+ _stripManager.start3(315, this, _stripManager._lookupList);
+ break;
+ case 1115:
+ _sceneMode = 50;
+ R2_GLOBALS._player.disableControl();
+ R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
+ _stripManager.start3(314, this, _stripManager._lookupList);
+ break;
+ case 1116:
+ R2_GLOBALS._player.enableControl(CURSOR_ARROW);
+ _stripManager._lookupList[9] = 1;
+ _stripManager._lookupList[10] = 1;
+ _stripManager._lookupList[11] = 1;
+ break;
+ case 1125: {
+ _sceneMode = 99;
+ R2_GLOBALS._sound2.play(100);
+ R2_GLOBALS._sound1.play(101);
+ Common::Point pt(187, -13);
+ NpcMover *mover = new NpcMover();
+ _actor1.addMover(mover, &pt, this);
+ }
+ break;
+ default:
+ R2_GLOBALS._player.enableControl();
+ R2_GLOBALS._player._canWalk = false;
+ break;
+ }
+}
+
+void Scene1100::dispatch() {
+ if ((g_globals->_sceneObjects->contains(&_actor10)) && (_actor10._visage == 1102) && (_actor10._strip == 4) && (_actor10._frame == 1) && (_actor10._flags & OBJFLAG_HIDING)) {
+ if (_field414 == 1) {
+ _field414 = 2;
+ R2_GLOBALS._scenePalette.refresh();
+ }
+ } else {
+ if (_field414 == 2)
+ R2_GLOBALS._scenePalette.refresh();
+ _field414 = 1;
+ }
+
+ Scene::dispatch();
+
+ if (R2_GLOBALS._player._bounds.contains(_actor13._position))
+ _actor13._shade = 3;
+ else
+ _actor13._shade = 0;
+
+ if (R2_GLOBALS._player._bounds.contains(_actor14._position))
+ _actor14._shade = 3;
+ else
+ _actor14._shade = 0;
+
+ if (R2_GLOBALS._player._bounds.contains(_actor15._position))
+ _actor15._shade = 3;
+ else
+ _actor15._shade = 0;
+}
+
+void Scene1100::saveCharacter(int characterIndex) {
+ if (R2_GLOBALS._player._characterIndex == 3)
+ R2_GLOBALS._sound1.fadeOut2(NULL);
+ SceneExt::saveCharacter(characterIndex);
+}
+
+/*--------------------------------------------------------------------------
+ * Scene 1200 -
+ *
+ *--------------------------------------------------------------------------*/
+Scene1200::Scene1200() {
+ _field412 = 0;
+ _field414 = 0;
+ _field416 = 0;
+ _field418 = 0;
+ _field41A = 0;
+ _field41C = 1; //CHECKME: Only if fixup_flag == 6??
+}
+
+void Scene1200::synchronize(Serializer &s) {
+ SceneExt::synchronize(s);
+
+ s.syncAsSint16LE(_field412);
+ s.syncAsSint16LE(_field414);
+ s.syncAsSint16LE(_field416);
+ s.syncAsSint16LE(_field418);
+ s.syncAsSint16LE(_field41A);
+ s.syncAsSint16LE(_field41C);
+}
+
+Scene1200::Area1::Area1() {
+ _field20 = 0;
+}
+
+void Scene1200::Area1::synchronize(Serializer &s) {
+ SceneArea::synchronize(s);
+
+ s.syncAsByte(_field20);
+}
+
+void Scene1200::Area1::Actor3::init(int state) {
+ _state = state;
+
+ SceneActor::postInit();
+ setup(1003, 1, 1);
+ fixPriority(255);
+
+ switch (_state) {
+ case 1:
+ switch (R2_GLOBALS._v56AA6) {
+ case 1:
+ setFrame2(2);
+ setPosition(Common::Point(129, 101));
+ break;
+ case 2:
+ setFrame2(3);
+ setPosition(Common::Point(135, 95));
+ break;
+ default:
+ break;
+ }
+ case 2:
+ switch (R2_GLOBALS._v56AA7) {
+ case 1:
+ setFrame2(2);
+ setPosition(Common::Point(152, 101));
+ break;
+ case 2:
+ setFrame2(3);
+ setPosition(Common::Point(158, 122));
+ break;
+ case 3:
+ setFrame2(3);
+ setPosition(Common::Point(135, 122));
+ break;
+ default:
+ break;
+ }
+ case 3:
+ switch (R2_GLOBALS._v56AA8) {
+ case 1:
+ setFrame2(3);
+ setPosition(Common::Point(158, 95));
+ break;
+ case 2:
+ setFrame2(2);
+ setPosition(Common::Point(175, 101));
+ break;
+ default:
+ break;
+ }
+ default:
+ break;
+ }
+
+ setDetails(1200, 12, -1, -1, 2, (SceneItem *) NULL);
+}
+
+bool Scene1200::Area1::Actor3::startAction(CursorType action, Event &event) {
+ if (action != CURSOR_USE)
+ return SceneActor::startAction(action, event);
+
+ R2_GLOBALS._sound2.play(260);
+ switch (_state) {
+ case 1:
+ if (R2_GLOBALS._v56AA6 == 1) {
+ R2_GLOBALS._v56AA6 = 2;
+ setFrame2(3);
+ setPosition(Common::Point(135, 95));
+ } else {
+ R2_GLOBALS._v56AA6 = 1;
+ setFrame2(2);
+ setPosition(Common::Point(129, 101));
+ }
+ break;
+ case 2:
+ ++R2_GLOBALS._v56AA7;
+ if (R2_GLOBALS._v56AA7 == 4)
+ R2_GLOBALS._v56AA7 = 1;
+
+ switch (R2_GLOBALS._v56AA7) {
+ case 1:
+ setFrame2(1);
+ setPosition(Common::Point(152, 101));
+ break;
+ case 2:
+ setFrame2(3);
+ setPosition(Common::Point(158, 122));
+ break;
+ case 3:
+ setFrame2(3);
+ setPosition(Common::Point(135, 122));
+ break;
+ default:
+ break;
+ }
+ break;
+ case 3:
+ if (R2_GLOBALS._v56AA8 == 1) {
+ R2_GLOBALS._v56AA8 = 2;
+ setFrame2(2);
+ setPosition(Common::Point(175, 101));
+ } else {
+ R2_GLOBALS._v56AA8 = 1;
+ setFrame2(3);
+ setPosition(Common::Point(158, 95));
+ }
+ break;
+ default:
+ break;
+ }
+
+ Scene1200 *scene = (Scene1200 *)R2_GLOBALS._sceneManager._scene;
+ scene->_field418 = 0;
+
+ if ((R2_GLOBALS._v56AA6 == 1) && (R2_GLOBALS._v56AA7 == 1) && (R2_GLOBALS._v56AA8 == 1))
+ scene->_field418 = 1;
+ else if ((R2_GLOBALS._v56AA6 == 2) && (R2_GLOBALS._v56AA7 == 1) && (R2_GLOBALS._v56AA8 == 1))
+ scene->_field418 = 2;
+ else if ((R2_GLOBALS._v56AA6 == 2) && (R2_GLOBALS._v56AA7 == 1) && (R2_GLOBALS._v56AA8 == 2))
+ scene->_field418 = 3;
+ else if ((R2_GLOBALS._v56AA6 == 2) && (R2_GLOBALS._v56AA7 == 3) && (R2_GLOBALS._v56AA8 == 1))
+ scene->_field418 = 4;
+
+ return true;
+}
+
+void Scene1200::Area1::postInit(SceneObjectList *OwnerList) {
+ Scene1200 *scene = (Scene1200 *)R2_GLOBALS._sceneManager._scene;
+
+ scene->_field41A = 1;
+ R2_GLOBALS._events.setCursor(CURSOR_USE);
+ proc12(1003, 1, 1, 100, 40);
+ proc13(1200, 11, -1, -1);
+ R2_GLOBALS._sound2.play(259);
+ _actor3.init(1);
+ _actor4.init(2);
+ _actor5.init(3);
+
+ R2_GLOBALS._player._canWalk = false;
+}
+
+void Scene1200::Area1::remove() {
+ Scene1200 *scene = (Scene1200 *)R2_GLOBALS._sceneManager._scene;
+
+ scene->_field41A = 0;
+ warning("Unexpected _sceneAreas.remove() call");
+// scene->_sceneAreas.remove(&_actor3);
+// scene->_sceneAreas.remove(&_actor4);
+// scene->_sceneAreas.remove(&_actor5);
+ _actor3.remove();
+ _actor4.remove();
+ _actor5.remove();
+
+ // sub201EA
+ R2_GLOBALS._sceneItems.remove((SceneItem *)this);
+ _actor2.remove();
+ SceneArea::remove();
+ R2_GLOBALS._insetUp--;
+ //
+
+ R2_GLOBALS._player._canWalk = true;
+}
+
+void Scene1200::Area1::process(Event &event) {
+ if (_field20 != R2_GLOBALS._insetUp)
+ return;
+
+ CursorType cursor = R2_GLOBALS._events.getCursor();
+
+ if (_actor2._bounds.contains(event.mousePos.x + g_globals->gfxManager()._bounds.left , event.mousePos.y)) {
+ if (cursor == _cursorNum)
+ warning("TODO: _cursorState = ???");
+ R2_GLOBALS._events.setCursor(_savedCursorNum); //, _cursorState);
+ } else if (event.mousePos.y < 168) {
+ if (cursor != _cursorNum) {
+ _savedCursorNum = cursor;
+ warning("TODO: _cursorState = ???");
+ R2_GLOBALS._events.setCursor(CURSOR_INVALID);
+ }
+ if (event.eventType == EVENT_BUTTON_DOWN) {
+ event.handled = true;
+ warning("TODO: _cursorState = ???");
+ R2_GLOBALS._events.setCursor(_savedCursorNum); //, _cursorState);
+ remove();
+ }
+ }
+}
+
+void Scene1200::Area1::proc12(int visage, int stripFrameNum, int frameNum, int posX, int posY) {
+ Scene1200 *scene = (Scene1200 *)R2_GLOBALS._sceneManager._scene;
+
+ _actor2.postInit();
+ _actor2.setup(visage, stripFrameNum, frameNum);
+ _actor2.setPosition(Common::Point(posX, posY));
+ _actor2.fixPriority(250);
+ _cursorNum = CURSOR_INVALID;
+ scene->_sceneAreas.push_front(this);
+ ++R2_GLOBALS._insetUp;
+ _field20 = R2_GLOBALS._insetUp;
+}
+
+void Scene1200::Area1::proc13(int resNum, int lookLineNum, int talkLineNum, int useLineNum) {
+ _actor2.setDetails(resNum, lookLineNum, talkLineNum, useLineNum, 2, (SceneItem *) NULL);
+}
+
+void Scene1200::postInit(SceneObjectList *OwnerList) {
+ Rect tmpRect;
+
+ loadScene(1200);
+ SceneExt::postInit();
+
+ if (R2_GLOBALS._sceneManager._previousScene < 3200)
+ R2_GLOBALS._sound1.play(257);
+
+ _field412 = 1;
+ _field414 = 0;
+ _field416 = 0;
+ _field418 = 0;
+ _field41A = 0;
+ _field41C = 0;
+
+ if ((R2_GLOBALS._v56AA6 == 1) && (R2_GLOBALS._v56AA7 == 1) && (R2_GLOBALS._v56AA8 == 1))
+ _field418 = 1;
+ else if ((R2_GLOBALS._v56AA6 == 2) && (R2_GLOBALS._v56AA7 == 1) && (R2_GLOBALS._v56AA8 == 1))
+ _field418 = 2;
+ else if ((R2_GLOBALS._v56AA6 == 2) && (R2_GLOBALS._v56AA7 == 1) && (R2_GLOBALS._v56AA8 == 2))
+ _field418 = 3;
+ else if ((R2_GLOBALS._v56AA6 == 2) && (R2_GLOBALS._v56AA7 == 3) && (R2_GLOBALS._v56AA8 == 1))
+ _field418 = 4;
+
+ R2_GLOBALS._player.postInit();
+ R2_GLOBALS._player.disableControl();
+ R2_GLOBALS._player.setup(3156, 1, 6);
+ R2_GLOBALS._player.setPosition(Common::Point(160, 70));
+ R2_GLOBALS._player._numFrames = 10;
+ R2_GLOBALS._player._oldCharacterScene[3] = 1200;
+
+ _actor1.postInit();
+ _actor1.hide();
+
+ tmpRect.set(110, 20, 210, 120);
+ _object1.sub9EDE8(tmpRect);
+
+ _object1.sub51AE9(1);
+ _object1.sub51AFD(Common::Point(R2_GLOBALS._v56AA2, R2_GLOBALS._v56AA4));
+ warning("int unk = set_pane_p(_paneNumber);");
+ _object1.sub51B02();
+ warning("set_pane_p(unk);");
+
+ R2_GLOBALS._player.enableControl();
+ _item1.setDetails(Rect(0, 0, 320, 200), 1200, 0, 1, 2, 1, NULL);
+}
+
+void Scene1200::signal() {
+ switch (_sceneMode++) {
+ case 1:
+ // No break on purpose
+ case 1200:
+ // No break on purpose
+ case 1201:
+ // No break on purpose
+ case 1202:
+ // No break on purpose
+ case 1203:
+ R2_GLOBALS._player.enableControl();
+ warning("_eventManager.waitEvent()");
+ _sceneMode = 2;
+ break;
+ case 10:
+ _field416 = 1;
+ _field414 = 6;
+ R2_GLOBALS._player._numFrames = 5;
+ R2_GLOBALS._player.setStrip(1);
+ R2_GLOBALS._player.setFrame(5);
+ R2_GLOBALS._player.animate(ANIM_MODE_6, this);
+ break;
+ case 11:
+ // No break on purpose
+ case 21:
+ // No break on purpose
+ case 31:
+ // No break on purpose
+ case 41:
+ _field416 = 0;
+ break;
+ case 12:
+ _field414 = 14;
+ R2_GLOBALS._player._numFrames = 10;
+ R2_GLOBALS._player.setup(3155, 1, 4);
+ R2_GLOBALS._player.setPosition(Common::Point(160, 70));
+ R2_GLOBALS._player.animate(ANIM_MODE_2, NULL);
+ break;
+ case 13:
+ // No break on purpose
+ case 16:
+ // No break on purpose
+ case 23:
+ // No break on purpose
+ case 26:
+ // No break on purpose
+ case 33:
+ // No break on purpose
+ case 36:
+ // No break on purpose
+ case 43:
+ // No break on purpose
+ case 46:
+ R2_GLOBALS._player.setFrame(4);
+ _sceneMode = 1;
+ setAction(&_sequenceManager, this, 1, &R2_GLOBALS._player, NULL);
+ break;
+ case 15:
+ // No break on purpose
+ case 25:
+ // No break on purpose
+ case 35:
+ // No break on purpose
+ case 45:
+ _field414 = 20;
+ R2_GLOBALS._player.animate(ANIM_MODE_2, NULL);
+ break;
+ case 20:
+ _field416 = 1;
+ _field414 = 6;
+ R2_GLOBALS._player._numFrames = 5;
+ R2_GLOBALS._player.setStrip(2);
+ R2_GLOBALS._player.setFrame(5);
+ R2_GLOBALS._player.animate(ANIM_MODE_6, this);
+ break;
+ case 22:
+ _field414 = 14;
+ R2_GLOBALS._player._numFrames = 10;
+ R2_GLOBALS._player.setup(3155, 2, 4);
+ R2_GLOBALS._player.setPosition(Common::Point(160, 70));
+ R2_GLOBALS._player.animate(ANIM_MODE_2, NULL);
+ break;
+ case 30:
+ _field416 = 1;
+ _field414 = 6;
+ R2_GLOBALS._player._numFrames = 5;
+ R2_GLOBALS._player.setStrip(3);
+ R2_GLOBALS._player.setFrame(5);
+ R2_GLOBALS._player.animate(ANIM_MODE_6, this);
+ break;
+ case 32:
+ _field414 = 14;
+ R2_GLOBALS._player._numFrames = 10;
+ R2_GLOBALS._player.setup(3155, 3, 4);
+ R2_GLOBALS._player.setPosition(Common::Point(160, 70));
+ R2_GLOBALS._player.animate(ANIM_MODE_2, NULL);
+ break;
+ case 40:
+ _field416 = 1;
+ _field414 = 6;
+ R2_GLOBALS._player._numFrames = 5;
+ R2_GLOBALS._player.setStrip(4);
+ R2_GLOBALS._player.setFrame(5);
+ R2_GLOBALS._player.animate(ANIM_MODE_6, this);
+ break;
+ case 42:
+ _field414 = 14;
+ R2_GLOBALS._player._numFrames = 10;
+ R2_GLOBALS._player.setup(3155, 4, 4);
+ R2_GLOBALS._player.setPosition(Common::Point(160, 70));
+ R2_GLOBALS._player.animate(ANIM_MODE_2, NULL);
+ break;
+ case 50:
+ // No break on purpose
+ case 55:
+ // No break on purpose
+ case 60:
+ R2_GLOBALS._player.setup(3156, 5, 1);
+ R2_GLOBALS._player._numFrames = 5;
+ R2_GLOBALS._player.animate(ANIM_MODE_5, this);
+ break;
+ case 51:
+ // No break on purpose
+ case 56:
+ // No break on purpose
+ case 117:
+ R2_GLOBALS._player.setup(3157, 1, 1);
+ R2_GLOBALS._player.animate(ANIM_MODE_5, this);
+ break;
+ case 52:
+ // No break on purpose
+ case 82:
+ // No break on purpose
+ case 118:
+ R2_GLOBALS._player.setup(3156, 3, 6);
+ _sceneMode = 1;
+ setAction(&_sequenceManager, this, 1, &R2_GLOBALS._player, NULL);
+ break;
+ case 57:
+ // No break on purpose
+ case 91:
+ // No break on purpose
+ case 96:
+ R2_GLOBALS._player.setup(3157, 2, 1);
+ R2_GLOBALS._player.animate(ANIM_MODE_5, this);
+ break;
+ case 58:
+ // No break on purpose
+ case 92:
+ // No break on purpose
+ case 122:
+ R2_GLOBALS._player.setup(3156, 2, 6);
+ _sceneMode = 1;
+ setAction(&_sequenceManager, this, 1, &R2_GLOBALS._player, NULL);
+ break;
+ case 61:
+ R2_GLOBALS._player.setup(3157, 4, 5);
+ R2_GLOBALS._player.animate(ANIM_MODE_6, this);
+ break;
+ case 62:
+ // No break on purpose
+ case 72:
+ // No break on purpose
+ case 98:
+ R2_GLOBALS._player.setup(3156, 4, 6);
+ _sceneMode = 1;
+ setAction(&_sequenceManager, this, 1, &R2_GLOBALS._player, NULL);
+ break;
+ case 70:
+ // No break on purpose
+ case 75:
+ // No break on purpose
+ case 80:
+ R2_GLOBALS._player.setup(3156, 6, 1);
+ R2_GLOBALS._player._numFrames = 5;
+ R2_GLOBALS._player.animate(ANIM_MODE_5, this);
+ break;
+ case 71:
+ // No break on purpose
+ case 76:
+ // No break on purpose
+ case 97:
+ R2_GLOBALS._player.setup(3157, 3, 1);
+ R2_GLOBALS._player.animate(ANIM_MODE_5, this);
+ break;
+ case 77:
+ // No break on purpose
+ case 111:
+ // No break on purpose
+ case 116:
+ R2_GLOBALS._player.setup(3157, 3, 1);
+ R2_GLOBALS._player.animate(ANIM_MODE_5, this);
+ break;
+ case 78:
+ // No break on purpose
+ case 102:
+ // No break on purpose
+ case 112:
+ R2_GLOBALS._player.setup(3156, 1, 6);
+ _sceneMode = 1;
+ setAction(&_sequenceManager, this, 1, &R2_GLOBALS._player, NULL);
+ break;
+ case 81:
+ R2_GLOBALS._player.setup(3157, 2, 5);
+ R2_GLOBALS._player.animate(ANIM_MODE_6, this);
+ break;
+ case 90:
+ // No break on purpose
+ case 95:
+ // No break on purpose
+ case 100:
+ R2_GLOBALS._player.setup(3156, 7, 1);
+ R2_GLOBALS._player._numFrames = 5;
+ R2_GLOBALS._player.animate(ANIM_MODE_5, this);
+ break;
+ case 101:
+ R2_GLOBALS._player.setup(3157, 1, 5);
+ R2_GLOBALS._player.animate(ANIM_MODE_6, this);
+ break;
+ case 110:
+ // No break on purpose
+ case 115:
+ // No break on purpose
+ case 120:
+ R2_GLOBALS._player.setup(3156, 8, 1);
+ R2_GLOBALS._player._numFrames = 5;
+ R2_GLOBALS._player.animate(ANIM_MODE_5, this);
+ break;
+ case 121:
+ R2_GLOBALS._player.setup(3157, 3, 5);
+ R2_GLOBALS._player.animate(ANIM_MODE_6, this);
+ break;
+ default:
+ warning("_eventManager.waitEvent()");
+ _sceneMode = 2;
+ break;
+ }
+}
+
+void Scene1200::process(Event &event) {
+ if (_field414 != 0)
+ return;
+
+ Scene::process(event);
+
+ if (!R2_GLOBALS._player._canWalk)
+ return;
+
+ if (event.eventType == EVENT_BUTTON_DOWN) {
+ _object1.sub9EE22(R2_GLOBALS._v56AA2, R2_GLOBALS._v56AA4);
+ int unk = _object1.sub51AF8(event.mousePos);
+ switch (R2_GLOBALS._events.getCursor()) {
+ case CURSOR_ARROW:
+ event.handled = true;
+ if ((event.mousePos.x > 179) && (event.mousePos.x < 210) && (event.mousePos.y > 50) && (event.mousePos.y < 89))
+ sub9DAD6(1);
+
+ if ((event.mousePos.x > 109) && (event.mousePos.x < 140) && (event.mousePos.y > 50) && (event.mousePos.y < 89))
+ sub9DAD6(2);
+
+ if ((event.mousePos.x > 140) && (event.mousePos.x < 179) && (event.mousePos.y > 89) && (event.mousePos.y < 120))
+ sub9DAD6(3);
+
+ if ((event.mousePos.x > 140) && (event.mousePos.x < 179) && (event.mousePos.y > 19) && (event.mousePos.y < 50))
+ sub9DAD6(4);
+ break;
+ case CURSOR_USE:
+ if (unk > 36) {
+ if ( ((R2_GLOBALS._v56AA2 == 3) && (R2_GLOBALS._v56AA4 == 33))
+ || ((R2_GLOBALS._v56AA2 == 7) && (R2_GLOBALS._v56AA4 == 33))
+ || ((R2_GLOBALS._v56AA2 == 33) && (R2_GLOBALS._v56AA4 == 41))
+ || ((R2_GLOBALS._v56AA2 == 5) && (R2_GLOBALS._v56AA4 == 5))
+ || ((R2_GLOBALS._v56AA2 == 13) && (R2_GLOBALS._v56AA4 == 21))
+ || ((R2_GLOBALS._v56AA2 == 17) && (R2_GLOBALS._v56AA4 == 21))
+ || ((R2_GLOBALS._v56AA2 == 17) && (R2_GLOBALS._v56AA4 == 5))
+ || ((R2_GLOBALS._v56AA2 == 17) && (R2_GLOBALS._v56AA4 == 9))
+ || ((R2_GLOBALS._v56AA2 == 29) && (R2_GLOBALS._v56AA4 == 17))
+ || ((R2_GLOBALS._v56AA2 == 33) && (R2_GLOBALS._v56AA4 == 17))
+ || ((R2_GLOBALS._v56AA2 == 35) && (R2_GLOBALS._v56AA4 == 17))
+ || ((R2_GLOBALS._v56AA2 == 41) && (R2_GLOBALS._v56AA4 == 21)) ) {
+ _area1.postInit();
+ event.handled = true;
+ }
+ }
+
+ if ((unk == 1) || (unk == 4) || (unk == 11) || (unk == 14)) {
+ if ( ((R2_GLOBALS._v56AA2 == 3) && (R2_GLOBALS._v56AA4 == 9))
+ || ((R2_GLOBALS._v56AA2 == 11) && (R2_GLOBALS._v56AA4 == 27))
+ || ((R2_GLOBALS._v56AA2 == 17) && (R2_GLOBALS._v56AA4 == 7))
+ || ((R2_GLOBALS._v56AA2 == 17) && (R2_GLOBALS._v56AA4 == 27))
+ || ((R2_GLOBALS._v56AA2 == 17) && (R2_GLOBALS._v56AA4 == 33))
+ || (R2_GLOBALS._v56AA2 == 33) ) {
+ switch (R2_GLOBALS._v56AA2) {
+ case 3:
+ R2_GLOBALS._sceneManager.changeScene(3150);
+ break;
+ case 33:
+ if (R2_GLOBALS._v56AA1 >= 4)
+ R2_GLOBALS._sceneManager.changeScene(3250);
+ else
+ SceneItem::display(1200, 6, 0, 280, 1, 160, 9, 1, 2, 20, 7, 154, -999);
+ break;
+ default:
+ SceneItem::display(1200, 5, 0, 280, 1, 160, 9, 1, 2, 20, 7, 154, -999);
+ break;
+ }
+ event.handled = true;
+ }
+ }
+ break;
+ case CURSOR_LOOK:
+ if ((unk == 1) || (unk == 4) || (unk == 11) || (unk == 14)) {
+ event.handled = true;
+ switch (R2_GLOBALS._v56AA2) {
+ case 3:
+ SceneItem::display(1200, 8, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
+ break;
+ case 9:
+ R2_GLOBALS._sceneManager.changeScene(3240);
+ break;
+ case 11:
+ if (R2_GLOBALS._v56AA4 == 27)
+ R2_GLOBALS._sceneManager.changeScene(3210);
+ else
+ SceneItem::display(1200, 10, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
+ break;
+ case 17:
+ switch (R2_GLOBALS._v56AA4) {
+ case 5:
+ R2_GLOBALS._sceneManager.changeScene(3230);
+ break;
+ case 21:
+ R2_GLOBALS._sceneManager.changeScene(3220);
+ break;
+ case 33:
+ R2_GLOBALS._sceneManager.changeScene(3200);
+ break;
+ default:
+ SceneItem::display(1200, 10, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
+ break;
+ }
+ case 33:
+ R2_GLOBALS._sceneManager.changeScene(3245);
+ break;
+ default:
+ SceneItem::display(1200, 10, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
+ break;
+ }
+ }
+ if (unk > 36) {
+ event.handled = true;
+ SceneItem::display(1200, 9, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
+ }
+ break;
+ case CURSOR_TALK:
+ event.handled = true;
+ break;
+ default:
+ return;
+ }
+ } else if (event.eventType == EVENT_KEYPRESS) {
+ if (_field414 == 0) {
+ event.handled = false;
+ return;
+ }
+
+ switch (event.kbd.keycode) {
+ case Common::KEYCODE_1:
+ warning("FIXME: keycode = 0x4800");
+ sub9DAD6(4);
+ break;
+ case Common::KEYCODE_2:
+ warning("FIXME: keycode = 0x4B00");
+ sub9DAD6(2);
+ break;
+ case Common::KEYCODE_3:
+ warning("FIXME: keycode = 0x4D00");
+ sub9DAD6(1);
+ break;
+ case Common::KEYCODE_4:
+ warning("FIXME: keycode = 0x5000");
+ sub9DAD6(3);
+ break;
+ default:
+ event.handled = false;
+ return;
+ break;
+ }
+ } else {
+ return;
+ }
+}
+
+void Scene1200::dispatch() {
+ Rect tmpRect;
+ Scene::dispatch();
+ if (_field41C != 0) {
+ _object1.sub51AFD(Common::Point(R2_GLOBALS._v56AA2, R2_GLOBALS._v56AA4));
+ warning("int unk = set_pane_p(_paneNumber);");
+ _object1.sub51B02();
+ warning("_gfxManager.sub294AC(unk);");
+ warning("tmpRect.sub14DF3();");
+ _field41C = 0;
+ }
+
+ if (_field414 != 0) {
+ tmpRect.set(110, 20, 210, 120);
+ _field414--;
+ switch (_field412 - 1) {
+ case 0:
+ R2_GLOBALS._v56AA2 += 2;
+ break;
+ case 1:
+ R2_GLOBALS._v56AA2 -= 2;
+ break;
+ case 2:
+ R2_GLOBALS._v56AA4 += 2;
+ break;
+ case 3:
+ R2_GLOBALS._v56AA4 -= 2;
+ break;
+ default:
+ break;
+ }
+ _object1.sub51AFD(Common::Point(R2_GLOBALS._v56AA2, R2_GLOBALS._v56AA4));
+ warning("int unk = set_pane_p(_paneNumber);");
+ _object1.sub51B02();
+ warning("_gfxManager.sub294AC(unk);");
+ warning("tmpRect.sub14DF3();");
+
+ if (_field416 != 0) {
+ switch(_field412 - 1) {
+ case 0:
+ R2_GLOBALS._player.setPosition(Common::Point(R2_GLOBALS._player._position.x - 2, R2_GLOBALS._player._position.y));
+ break;
+ case 1:
+ R2_GLOBALS._player.setPosition(Common::Point(R2_GLOBALS._player._position.x + 2, R2_GLOBALS._player._position.y));
+ break;
+ case 2:
+ R2_GLOBALS._player.setPosition(Common::Point(R2_GLOBALS._player._position.x, R2_GLOBALS._player._position.y - 2));
+ break;
+ case 3:
+ R2_GLOBALS._player.setPosition(Common::Point(R2_GLOBALS._player._position.x, R2_GLOBALS._player._position.y + 2));
+ break;
+ default:
+ break;
+ }
+ }
+ if (_field414 == 0) {
+ if (_field416 == 0)
+ R2_GLOBALS._player.animate(ANIM_MODE_NONE, NULL);
+ signal();
+ }
+ }
+}
+
+void Scene1200::saveCharacter(int characterIndex) {
+ R2_GLOBALS._sound1.fadeOut2(NULL);
+ SceneExt::saveCharacter(characterIndex);
+}
+
+/*--------------------------------------------------------------------------
+ * Scene 1337 - Card game
+ *
+ *--------------------------------------------------------------------------*/
+
+Scene1337::unkObj1337sub1::unkObj1337sub1() {
+ _field34 = 0;
+ _field36 = Common::Point(0, 0);
+}
+
+void Scene1337::unkObj1337sub1::synchronize(Serializer &s) {
+ warning("STUBBED: unkObj1337sub1::synchronize()");
+}
+
+Scene1337::unkObj1337_1::unkObj1337_1() {
+ _fieldB94 = Common::Point(0, 0);
+ _fieldB98 = Common::Point(0, 0);
+ _fieldB9C = Common::Point(0, 0);
+ _fieldBA0 = Common::Point(0, 0);
+ _fieldBA4 = 0;
+}
+
+void Scene1337::unkObj1337_1::synchronize(Serializer &s) {
+ warning("STUBBED: unkObj1337_1::synchronize()");
+}
+
+Scene1337::Scene1337() {
+ _autoplay = false;
+ _field3E24 = 0;
+ _field3E26 = 0;
+
+ for (int i = 0; i < 100; i++)
+ _field3E28[i] = 0;
+
+ _field423C = 0;
+ _field423E = 0;
+ _field4240 = 0;
+ _field4242 = 0;
+ _field4244 = 0;
+ _field4246 = 0;
+ _field4248 = 0;
+ _field424A = 0;
+ _field424C = 0;
+ _field424E = 0;
+}
+
+void Scene1337::synchronize(Serializer &s) {
+ warning("STUBBED: Scene1337::synchronize()");
+}
+
+void Scene1337::Action1337::subD18B5(int resNum, int stripNum, int frameNum) {
+ warning("STUBBED: Action1337::subD18B5()");
+}
+
+void Scene1337::Action1337::skipFrames(int32 skipCount) {
+ uint32 firstFrameNumber = g_globals->_events.getFrameNumber();
+ uint32 tmpFrameNumber = firstFrameNumber;
+
+ while (tmpFrameNumber < firstFrameNumber + skipCount)
+ tmpFrameNumber = g_globals->_events.getFrameNumber();
+
+ warning("_eventManager.waitEvent(-1)");
+}
+
+void Scene1337::Action1::signal() {
+ Scene1337 *scene = (Scene1337 *)R2_GLOBALS._sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 1: {
+ scene->actionDisplay(1331, 6, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ R2_GLOBALS._sceneObjects->draw();
+ scene->actionDisplay(1331, 7, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ scene->actionDisplay(1331, 8, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+
+ scene->_arrunkObj1337[1]._arr2[0]._field34 = 2;
+ scene->_arrunkObj1337[1]._arr2[0]._object1.postInit();
+ scene->_arrunkObj1337[1]._arr2[0]._object1.setVisage(1332);
+ scene->_arrunkObj1337[1]._arr2[0]._object1.setPosition(scene->_arrunkObj1337[1]._arr2[0]._field36, 0);
+ scene->_arrunkObj1337[1]._arr2[0]._object1.setStrip(2);
+ scene->_arrunkObj1337[1]._arr2[0]._object1.setFrame(scene->_arrunkObj1337[1]._arr2[0]._field34);
+ scene->_arrunkObj1337[1]._arr2[0]._object1.fixPriority(170);
+ scene->setAnimationInfo(&scene->_arrunkObj1337[1]._arr2[0]);
+
+ scene->_arrunkObj1337[1]._arr2[1]._field34 = 3;
+ scene->_arrunkObj1337[1]._arr2[1]._object1.postInit();
+ scene->_arrunkObj1337[1]._arr2[1]._object1.setVisage(1332);
+ scene->_arrunkObj1337[1]._arr2[1]._object1.setPosition(scene->_arrunkObj1337[1]._arr2[1]._field36, 0);
+ scene->_arrunkObj1337[1]._arr2[1]._object1.setStrip(2);
+ scene->_arrunkObj1337[1]._arr2[1]._object1.setFrame(scene->_arrunkObj1337[1]._arr2[1]._field34);
+ scene->_arrunkObj1337[1]._arr2[1]._object1.fixPriority(170);
+ scene->setAnimationInfo(&scene->_arrunkObj1337[1]._arr2[1]);
+
+ scene->_arrunkObj1337[2]._arr2[0]._field34 = 4;
+ scene->_arrunkObj1337[2]._arr2[0]._object1.postInit();
+ scene->_arrunkObj1337[2]._arr2[0]._object1.setVisage(1332);
+ scene->_arrunkObj1337[2]._arr2[0]._object1.setPosition(scene->_arrunkObj1337[2]._arr2[0]._field36, 0);
+ scene->_arrunkObj1337[2]._arr2[0]._object1.setStrip(2);
+ scene->_arrunkObj1337[2]._arr2[0]._object1.setFrame(scene->_arrunkObj1337[2]._arr2[0]._field34);
+ scene->_arrunkObj1337[2]._arr2[0]._object1.fixPriority(170);
+ scene->setAnimationInfo(&scene->_arrunkObj1337[2]._arr2[0]);
+
+ scene->_arrunkObj1337[3]._arr2[0]._field34 = 5;
+ scene->_arrunkObj1337[3]._arr2[0]._object1.postInit();
+ scene->_arrunkObj1337[3]._arr2[0]._object1.setVisage(1332);
+ scene->_arrunkObj1337[3]._arr2[0]._object1.setPosition(scene->_arrunkObj1337[3]._arr2[0]._field36, 0);
+ scene->_arrunkObj1337[3]._arr2[0]._object1.setStrip(2);
+ scene->_arrunkObj1337[3]._arr2[0]._object1.setFrame(scene->_arrunkObj1337[3]._arr2[0]._field34);
+ scene->_arrunkObj1337[3]._arr2[0]._object1.fixPriority(170);
+ scene->setAnimationInfo(&scene->_arrunkObj1337[3]._arr2[0]);
+
+ scene->_arrunkObj1337[3]._arr2[1]._field34 = 6;
+ scene->_arrunkObj1337[3]._arr2[1]._object1.postInit();
+ scene->_arrunkObj1337[3]._arr2[1]._object1.setVisage(1332);
+ scene->_arrunkObj1337[3]._arr2[1]._object1.setPosition(scene->_arrunkObj1337[3]._arr2[1]._field36, 0);
+ scene->_arrunkObj1337[3]._arr2[1]._object1.setStrip(2);
+ scene->_arrunkObj1337[3]._arr2[1]._object1.setFrame(scene->_arrunkObj1337[3]._arr2[1]._field34);
+ scene->_arrunkObj1337[3]._arr2[1]._object1.fixPriority(170);
+ scene->setAnimationInfo(&scene->_arrunkObj1337[3]._arr2[1]);
+
+ scene->_arrunkObj1337[3]._arr2[2]._field34 = 7;
+ scene->_arrunkObj1337[3]._arr2[2]._object1.postInit();
+ scene->_arrunkObj1337[3]._arr2[2]._object1.setVisage(1332);
+ scene->_arrunkObj1337[3]._arr2[2]._object1.setPosition(scene->_arrunkObj1337[3]._arr2[2]._field36, 0);
+ scene->_arrunkObj1337[3]._arr2[2]._object1.setStrip(2);
+ scene->_arrunkObj1337[3]._arr2[2]._object1.setFrame(scene->_arrunkObj1337[3]._arr2[2]._field34);
+ scene->_arrunkObj1337[3]._arr2[2]._object1.fixPriority(170);
+ scene->setAnimationInfo(&scene->_arrunkObj1337[3]._arr2[2]);
+
+ scene->_arrunkObj1337[0]._arr2[0]._field34 = 8;
+ scene->_arrunkObj1337[0]._arr2[0]._object1.postInit();
+ scene->_arrunkObj1337[0]._arr2[0]._object1.setVisage(1332);
+ scene->_arrunkObj1337[0]._arr2[0]._object1.setPosition(scene->_arrunkObj1337[0]._arr2[0]._field36, 0);
+ scene->_arrunkObj1337[0]._arr2[0]._object1.setStrip(2);
+ scene->_arrunkObj1337[0]._arr2[0]._object1.setFrame(scene->_arrunkObj1337[0]._arr2[0]._field34);
+ scene->_arrunkObj1337[0]._arr2[0]._object1.fixPriority(170);
+ scene->setAnimationInfo(&scene->_arrunkObj1337[0]._arr2[0]);
+
+ scene->_arrunkObj1337[0]._arr2[1]._field34 = 9;
+ scene->_arrunkObj1337[0]._arr2[1]._object1.postInit();
+ scene->_arrunkObj1337[0]._arr2[1]._object1.setVisage(1332);
+ scene->_arrunkObj1337[0]._arr2[1]._object1.setPosition(scene->_arrunkObj1337[0]._arr2[1]._field36, 0);
+ scene->_arrunkObj1337[0]._arr2[1]._object1.setStrip(2);
+ scene->_arrunkObj1337[0]._arr2[1]._object1.setFrame(scene->_arrunkObj1337[0]._arr2[1]._field34);
+ scene->_arrunkObj1337[0]._arr2[1]._object1.fixPriority(170);
+ scene->setAnimationInfo(&scene->_arrunkObj1337[0]._arr2[1]);
+
+ R2_GLOBALS._sceneObjects->draw();
+
+ skipFrames(60);
+ scene->actionDisplay(1331, 9, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+
+ scene->_arrunkObj1337[2]._arr2[1]._field34 = 2;
+ scene->_arrunkObj1337[2]._arr2[1]._object1.postInit();
+ scene->_arrunkObj1337[2]._arr2[1]._object1.setVisage(1332);
+ scene->_arrunkObj1337[2]._arr2[1]._object1.setPosition(scene->_arrunkObj1337[2]._arr2[1]._field36, 0);
+ scene->_arrunkObj1337[2]._arr2[1]._object1.setStrip(2);
+ scene->_arrunkObj1337[2]._arr2[1]._object1.setFrame(scene->_arrunkObj1337[2]._arr2[1]._field34);
+ scene->_arrunkObj1337[2]._arr2[1]._object1.fixPriority(170);
+ scene->setAnimationInfo(&scene->_arrunkObj1337[2]._arr2[1]);
+
+ scene->_arrunkObj1337[2]._arr2[2]._field34 = 3;
+ scene->_arrunkObj1337[2]._arr2[2]._object1.postInit();
+ scene->_arrunkObj1337[2]._arr2[2]._object1.setVisage(1332);
+ scene->_arrunkObj1337[2]._arr2[2]._object1.setPosition(scene->_arrunkObj1337[2]._arr2[2]._field36, 0);
+ scene->_arrunkObj1337[2]._arr2[2]._object1.setStrip(2);
+ scene->_arrunkObj1337[2]._arr2[2]._object1.setFrame(scene->_arrunkObj1337[2]._arr2[2]._field34);
+ scene->_arrunkObj1337[2]._arr2[2]._object1.fixPriority(170);
+ scene->setAnimationInfo(&scene->_arrunkObj1337[2]._arr2[2]);
+
+ scene->_arrunkObj1337[2]._arr2[3]._field34 = 5;
+ scene->_arrunkObj1337[2]._arr2[3]._object1.postInit();
+ scene->_arrunkObj1337[2]._arr2[3]._object1.setVisage(1332);
+ scene->_arrunkObj1337[2]._arr2[3]._object1.setPosition(scene->_arrunkObj1337[2]._arr2[3]._field36, 0);
+ scene->_arrunkObj1337[2]._arr2[3]._object1.setStrip(2);
+ scene->_arrunkObj1337[2]._arr2[3]._object1.setFrame(scene->_arrunkObj1337[2]._arr2[3]._field34);
+ scene->_arrunkObj1337[2]._arr2[3]._object1.fixPriority(170);
+ scene->setAnimationInfo(&scene->_arrunkObj1337[2]._arr2[3]);
+
+ scene->_arrunkObj1337[2]._arr2[4]._field34 = 6;
+ scene->_arrunkObj1337[2]._arr2[4]._object1.postInit();
+ scene->_arrunkObj1337[2]._arr2[4]._object1.setVisage(1332);
+ scene->_arrunkObj1337[2]._arr2[4]._object1.setPosition(scene->_arrunkObj1337[2]._arr2[4]._field36, 0);
+ scene->_arrunkObj1337[2]._arr2[4]._object1.setStrip(2);
+ scene->_arrunkObj1337[2]._arr2[4]._object1.setFrame(scene->_arrunkObj1337[2]._arr2[4]._field34);
+ scene->_arrunkObj1337[2]._arr2[4]._object1.fixPriority(170);
+ scene->setAnimationInfo(&scene->_arrunkObj1337[2]._arr2[4]);
+
+ scene->_arrunkObj1337[2]._arr2[5]._field34 = 7;
+ scene->_arrunkObj1337[2]._arr2[5]._object1.postInit();
+ scene->_arrunkObj1337[2]._arr2[5]._object1.setVisage(1332);
+ scene->_arrunkObj1337[2]._arr2[5]._object1.setPosition(scene->_arrunkObj1337[2]._arr2[5]._field36, 0);
+ scene->_arrunkObj1337[2]._arr2[5]._object1.setStrip(2);
+ scene->_arrunkObj1337[2]._arr2[5]._object1.setFrame(scene->_arrunkObj1337[2]._arr2[5]._field34);
+ scene->_arrunkObj1337[2]._arr2[5]._object1.fixPriority(170);
+ scene->setAnimationInfo(&scene->_arrunkObj1337[2]._arr2[5]);
+
+ scene->_arrunkObj1337[2]._arr2[6]._field34 = 8;
+ scene->_arrunkObj1337[2]._arr2[6]._object1.postInit();
+ scene->_arrunkObj1337[2]._arr2[6]._object1.setVisage(1332);
+ scene->_arrunkObj1337[2]._arr2[6]._object1.setPosition(scene->_arrunkObj1337[2]._arr2[6]._field36, 0);
+ scene->_arrunkObj1337[2]._arr2[6]._object1.setStrip(2);
+ scene->_arrunkObj1337[2]._arr2[6]._object1.setFrame(scene->_arrunkObj1337[2]._arr2[6]._field34);
+ scene->_arrunkObj1337[2]._arr2[6]._object1.fixPriority(170);
+ scene->setAnimationInfo(&scene->_arrunkObj1337[2]._arr2[6]);
+
+ scene->_arrunkObj1337[2]._arr2[7]._field34 = 9;
+ scene->_arrunkObj1337[2]._arr2[7]._object1.postInit();
+ scene->_arrunkObj1337[2]._arr2[7]._object1.setVisage(1332);
+ scene->_arrunkObj1337[2]._arr2[7]._object1.setPosition(scene->_arrunkObj1337[2]._arr2[7]._field36, 0);
+ scene->_arrunkObj1337[2]._arr2[7]._object1.setStrip(2);
+ scene->_arrunkObj1337[2]._arr2[7]._object1.setFrame(scene->_arrunkObj1337[2]._arr2[7]._field34);
+ scene->_arrunkObj1337[2]._arr2[7]._object1.fixPriority(170);
+ scene->setAnimationInfo(&scene->_arrunkObj1337[2]._arr2[7]);
+
+ scene->_aSound1.play(62);
+
+ R2_GLOBALS._sceneObjects->draw();
+
+ skipFrames(120);
+ scene->_arrunkObj1337[2]._arr2[0]._object1.remove();
+ scene->_arrunkObj1337[2]._arr2[1]._object1.remove();
+ scene->_arrunkObj1337[2]._arr2[2]._object1.remove();
+ scene->_arrunkObj1337[2]._arr2[3]._object1.remove();
+ scene->_arrunkObj1337[2]._arr2[4]._object1.remove();
+ scene->_arrunkObj1337[2]._arr2[5]._object1.remove();
+ scene->_arrunkObj1337[2]._arr2[6]._object1.remove();
+ scene->_arrunkObj1337[2]._arr2[7]._object1.remove();
+
+ scene->_arrunkObj1337[1]._arr2[0]._object1.remove();
+ scene->_arrunkObj1337[1]._arr2[1]._object1.remove();
+
+ scene->_arrunkObj1337[3]._arr2[0]._object1.remove();
+ scene->_arrunkObj1337[3]._arr2[1]._object1.remove();
+ scene->_arrunkObj1337[3]._arr2[2]._object1.remove();
+
+ scene->_arrunkObj1337[0]._arr2[0]._object1.remove();
+ scene->_arrunkObj1337[0]._arr2[1]._object1.remove();
+
+ scene->_background2.setup2(1332, 5, 1, 165, 95, 110, 1);
+
+ scene->_arrunkObj1337[1]._arr1[0]._object1.postInit();
+ scene->_arrunkObj1337[1]._arr1[0]._object1.setVisage(1332);
+ scene->_arrunkObj1337[1]._arr1[0]._object1.setPosition(scene->_arrunkObj1337[1]._arr1[0]._field36, 0);
+ scene->_arrunkObj1337[1]._arr1[0]._object1.setStrip(1);
+ scene->_arrunkObj1337[1]._arr1[0]._object1.setFrame(4);
+ scene->_arrunkObj1337[1]._arr1[0]._object1.fixPriority(170);
+
+ scene->_arrunkObj1337[1]._arr1[1]._object1.postInit();
+ scene->_arrunkObj1337[1]._arr1[1]._object1.setVisage(1332);
+ scene->_arrunkObj1337[1]._arr1[1]._object1.setPosition(scene->_arrunkObj1337[1]._arr1[1]._field36, 0);
+ scene->_arrunkObj1337[1]._arr1[1]._object1.setStrip(1);
+ scene->_arrunkObj1337[1]._arr1[1]._object1.setFrame(4);
+ scene->_arrunkObj1337[1]._arr1[1]._object1.fixPriority(170);
+
+ scene->_arrunkObj1337[1]._arr1[2]._object1.postInit();
+ scene->_arrunkObj1337[1]._arr1[2]._object1.setVisage(1332);
+ scene->_arrunkObj1337[1]._arr1[2]._object1.setPosition(scene->_arrunkObj1337[1]._arr1[2]._field36, 0);
+ scene->_arrunkObj1337[1]._arr1[2]._object1.setStrip(1);
+ scene->_arrunkObj1337[1]._arr1[2]._object1.setFrame(4);
+ scene->_arrunkObj1337[1]._arr1[2]._object1.fixPriority(170);
+
+ scene->_arrunkObj1337[2]._arr1[0]._field34 = 30;
+ scene->_arrunkObj1337[2]._arr1[0]._object1.postInit();
+ scene->_arrunkObj1337[2]._arr1[0]._object1.setVisage(1332);
+ scene->_arrunkObj1337[2]._arr1[0]._object1.setPosition(scene->_arrunkObj1337[2]._arr1[0]._field36, 0);
+ scene->_arrunkObj1337[2]._arr1[0]._object1.setStrip(1);
+ scene->_arrunkObj1337[2]._arr1[0]._object1.setFrame(2);
+ scene->_arrunkObj1337[2]._arr1[0]._object1.fixPriority(170);
+ scene->setAnimationInfo(&scene->_arrunkObj1337[2]._arr1[0]);
+
+ scene->_arrunkObj1337[2]._arr1[1]._field34 = 16;
+ scene->_arrunkObj1337[2]._arr1[1]._object1.postInit();
+ scene->_arrunkObj1337[2]._arr1[1]._object1.setVisage(1332);
+ scene->_arrunkObj1337[2]._arr1[1]._object1.setPosition(scene->_arrunkObj1337[2]._arr1[1]._field36, 0);
+ scene->_arrunkObj1337[2]._arr1[1]._object1.setStrip(1);
+ scene->_arrunkObj1337[2]._arr1[1]._object1.setFrame(2);
+ scene->_arrunkObj1337[2]._arr1[1]._object1.fixPriority(170);
+ scene->setAnimationInfo(&scene->_arrunkObj1337[2]._arr1[1]);
+
+ scene->_arrunkObj1337[2]._arr1[2]._field34 = 1;
+ scene->_arrunkObj1337[2]._arr1[2]._object1.postInit();
+ scene->_arrunkObj1337[2]._arr1[2]._object1.setVisage(1332);
+ scene->_arrunkObj1337[2]._arr1[2]._object1.setPosition(scene->_arrunkObj1337[2]._arr1[2]._field36, 0);
+ scene->_arrunkObj1337[2]._arr1[2]._object1.setStrip(1);
+ scene->_arrunkObj1337[2]._arr1[2]._object1.setFrame(2);
+ scene->_arrunkObj1337[2]._arr1[2]._object1.fixPriority(170);
+ scene->setAnimationInfo(&scene->_arrunkObj1337[2]._arr1[2]);
+
+ scene->_arrunkObj1337[3]._arr1[0]._object1.postInit();
+ scene->_arrunkObj1337[3]._arr1[0]._object1.setVisage(1332);
+ scene->_arrunkObj1337[3]._arr1[0]._object1.setPosition(scene->_arrunkObj1337[3]._arr1[0]._field36, 0);
+ scene->_arrunkObj1337[3]._arr1[0]._object1.setStrip(1);
+ scene->_arrunkObj1337[3]._arr1[0]._object1.setFrame(3);
+ scene->_arrunkObj1337[3]._arr1[0]._object1.fixPriority(170);
+
+ scene->_arrunkObj1337[3]._arr1[1]._object1.postInit();
+ scene->_arrunkObj1337[3]._arr1[1]._object1.setVisage(1332);
+ scene->_arrunkObj1337[3]._arr1[1]._object1.setPosition(scene->_arrunkObj1337[3]._arr1[1]._field36, 0);
+ scene->_arrunkObj1337[3]._arr1[1]._object1.setStrip(1);
+ scene->_arrunkObj1337[3]._arr1[1]._object1.setFrame(3);
+ scene->_arrunkObj1337[3]._arr1[1]._object1.fixPriority(170);
+
+ scene->_arrunkObj1337[3]._arr1[2]._object1.postInit();
+ scene->_arrunkObj1337[3]._arr1[2]._object1.setVisage(1332);
+ scene->_arrunkObj1337[3]._arr1[2]._object1.setPosition(scene->_arrunkObj1337[3]._arr1[2]._field36, 0);
+ scene->_arrunkObj1337[3]._arr1[2]._object1.setStrip(1);
+ scene->_arrunkObj1337[3]._arr1[2]._object1.setFrame(3);
+ scene->_arrunkObj1337[3]._arr1[2]._object1.fixPriority(170);
+
+ scene->_arrunkObj1337[0]._arr1[0]._object1.postInit();
+ scene->_arrunkObj1337[0]._arr1[0]._object1.setVisage(1332);
+ scene->_arrunkObj1337[0]._arr1[0]._object1.setPosition(scene->_arrunkObj1337[0]._arr1[0]._field36, 0);
+ scene->_arrunkObj1337[0]._arr1[0]._object1.setStrip(1);
+ scene->_arrunkObj1337[0]._arr1[0]._object1.setFrame(2);
+ scene->_arrunkObj1337[0]._arr1[0]._object1.fixPriority(170);
+
+ scene->_arrunkObj1337[0]._arr1[1]._object1.postInit();
+ scene->_arrunkObj1337[0]._arr1[1]._object1.setVisage(1332);
+ scene->_arrunkObj1337[0]._arr1[1]._object1.setPosition(scene->_arrunkObj1337[0]._arr1[1]._field36, 0);
+ scene->_arrunkObj1337[0]._arr1[1]._object1.setStrip(1);
+ scene->_arrunkObj1337[0]._arr1[1]._object1.setFrame(2);
+ scene->_arrunkObj1337[0]._arr1[1]._object1.fixPriority(170);
+
+ scene->_arrunkObj1337[0]._arr1[2]._object1.postInit();
+ scene->_arrunkObj1337[0]._arr1[2]._object1.setVisage(1332);
+ scene->_arrunkObj1337[0]._arr1[2]._object1.setPosition(scene->_arrunkObj1337[0]._arr1[2]._field36, 0);
+ scene->_arrunkObj1337[0]._arr1[2]._object1.setStrip(1);
+ scene->_arrunkObj1337[0]._arr1[2]._object1.setFrame(2);
+ scene->_arrunkObj1337[0]._arr1[2]._object1.fixPriority(170);
+
+ R2_GLOBALS._sceneObjects->draw();
+
+ scene->actionDisplay(1331, 10, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ scene->_item2._object1.setPosition(Common::Point(162, 95), 0);
+ scene->_item2._object1.show();
+ scene->_aSound2.play(61);
+
+ Common::Point pt(91, 174);
+ NpcMover *mover = new NpcMover();
+ scene->_item2._object1.addMover(mover, &pt, this);
+ }
+ break;
+ case 2: {
+ scene->_arrunkObj1337[2]._arr1[3]._field34 = 2;
+ scene->_arrunkObj1337[2]._arr1[3]._object1.postInit();
+ scene->_arrunkObj1337[2]._arr1[3]._object1.setVisage(1332);
+ scene->_arrunkObj1337[2]._arr1[3]._object1.setPosition(scene->_arrunkObj1337[2]._arr1[3]._field36, 0);
+ scene->_arrunkObj1337[2]._arr1[3]._object1.setStrip(1);
+ scene->_arrunkObj1337[2]._arr1[3]._object1.setFrame(2);
+ scene->_arrunkObj1337[2]._arr1[3]._object1.fixPriority(170);
+
+ scene->_item2._object1.hide();
+ scene->setAnimationInfo(&scene->_arrunkObj1337[2]._arr1[3]);
+
+ R2_GLOBALS._sceneObjects->draw();
+
+ skipFrames(60);
+ scene->actionDisplay(1331, 11, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ scene->actionDisplay(1331, 12, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+
+ scene->_arrunkObj1337[2]._arr2[1]._field34 = 1;
+ scene->_arrunkObj1337[2]._arr2[1]._object1.postInit();
+ scene->_arrunkObj1337[2]._arr2[1]._object1.setVisage(1332);
+ scene->_arrunkObj1337[2]._arr2[1]._object1.setPosition(scene->_arrunkObj1337[2]._arr2[1]._field36, 0);
+ scene->_arrunkObj1337[2]._arr2[1]._object1.hide();
+
+ scene->_item2._object1.setStrip(scene->_arrunkObj1337[2]._arr1[2]._object1._strip);
+ scene->_item2._object1.setFrame(scene->_arrunkObj1337[2]._arr1[2]._object1._frame);
+ scene->_item2._object1.animate(ANIM_MODE_NONE, NULL);
+
+ scene->_arrunkObj1337[2]._arr1[2]._field34 = 0;
+ scene->_arrunkObj1337[2]._arr1[2]._object1.remove();
+
+ scene->_item2._object1.setPosition(scene->_arrunkObj1337[2]._arr1[2]._field36, 0);
+ scene->_item2._object1.show();
+
+ NpcMover *mover = new NpcMover();
+ scene->_item2._object1.addMover(mover, &scene->_arrunkObj1337[2]._arr2[1]._field36, this);
+ }
+ break;
+ case 3: {
+ scene->_item2._object1.hide();
+ scene->setAnimationInfo(&scene->_arrunkObj1337[2]._arr2[1]);
+ scene->_aSound1.play(59);
+
+ R2_GLOBALS._sceneObjects->draw();
+
+ skipFrames(60);
+ scene->actionDisplay(1331, 13, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+
+ scene->_arrunkObj1337[2]._arr2[1]._field34 = scene->_arrunkObj1337[2]._arr1[3]._field34;
+
+ scene->_item2._object1.setStrip(scene->_arrunkObj1337[2]._arr1[3]._object1._strip);
+ scene->_item2._object1.setFrame(scene->_arrunkObj1337[2]._arr1[3]._object1._frame);
+
+ scene->_arrunkObj1337[2]._arr1[3]._field34 = 0;
+ scene->_arrunkObj1337[2]._arr1[3]._object1.remove();
+
+ scene->_item2._object1.setPosition(scene->_arrunkObj1337[2]._arr1[3]._field36, 0);
+ scene->_item2._object1.show();
+
+ NpcMover *mover = new NpcMover();
+ scene->_item2._object1.addMover(mover, &scene->_arrunkObj1337[2]._arr2[1]._field36, this);
+ }
+ break;
+ case 4: {
+ scene->_item2._object1.hide();
+ scene->setAnimationInfo(&scene->_arrunkObj1337[2]._arr2[1]);
+ scene->_aSound1.play(59);
+
+ scene->_item7._field34 = 1;
+ scene->_item7._object1.hide();
+
+ scene->_item2._object1.setStrip(5);
+ scene->_item2._object1.setFrame(1);
+ scene->_item2._object1.animate(ANIM_MODE_2, NULL);
+ scene->_item2._object1.setPosition(scene->_arrunkObj1337[2]._arr2[1]._field36, 0);
+ scene->_item2._object1.show();
+
+ NpcMover *mover = new NpcMover();
+ scene->_item2._object1.addMover(mover, &scene->_item7._field36, this);
+ }
+ break;
+ case 5: {
+ scene->_item2._object1.hide();
+
+ scene->_item7._object1.postInit();
+ scene->_item7._object1.setVisage(1332);
+ scene->_item7._object1.setPosition(scene->_item7._field36, 0);
+ scene->setAnimationInfo(&scene->_item7);
+ scene->_aSound2.play(61);
+
+ R2_GLOBALS._sceneObjects->draw();
+
+ skipFrames(60);
+ scene->actionDisplay(1331, 14, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+
+ scene->_arrunkObj1337[2]._arr3[0]._object1.postInit();
+ scene->_arrunkObj1337[2]._arr3[0]._object1.setVisage(1332);
+ scene->_arrunkObj1337[2]._arr3[0]._object1.setPosition(scene->_arrunkObj1337[2]._arr3[0]._field36, 0);
+ scene->_arrunkObj1337[2]._arr3[0]._object1.hide();
+
+ scene->_arrunkObj1337[3]._arr1[2]._field34 = 0;
+ scene->_arrunkObj1337[3]._arr1[2].remove();
+
+ scene->_item2._object1.setPosition(scene->_arrunkObj1337[3]._arr1[2]._field36, 0);
+ scene->_item2._object1.show();
+
+ NpcMover *mover = new NpcMover();
+ scene->_item2._object1.addMover(mover, &scene->_arrunkObj1337[2]._arr3[0]._field36, this);
+ }
+ break;
+ case 6: {
+ scene->_item2._object1.hide();
+ scene->_arrunkObj1337[2]._arr3[0]._field34 = 21;
+ scene->setAnimationInfo(&scene->_arrunkObj1337[2]._arr3[0]);
+ scene->_aSound1.play(57);
+
+ R2_GLOBALS._sceneObjects->draw();
+
+ skipFrames(60);
+ scene->actionDisplay(1331, 15, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+
+ int tmpVal = 15;
+ int i = -1;
+
+ for (i = 0; i <= 7; i++) {
+ tmpVal += 29;
+
+ scene->_arrObject1[i].postInit();
+ scene->_arrObject1[i].setVisage(1332);
+ scene->_arrObject1[i].setPosition(Common::Point(tmpVal, 90), 0);
+ scene->_arrObject1[i].setStrip(3);
+ scene->_arrObject1[i].fixPriority(190);
+
+ scene->_arrObject2[i].postInit();
+ scene->_arrObject2[i].setVisage(1332);
+ scene->_arrObject2[i].setPosition(Common::Point(tmpVal, 90), 0);
+ scene->_arrObject2[i].setStrip(7);
+ scene->_arrObject2[i].setFrame(1);
+ scene->_arrObject2[i].fixPriority(180);
+ }
+
+ scene->_arrObject1[0].setFrame(1);
+ scene->_arrObject1[1].setFrame(3);
+ scene->_arrObject1[2].setFrame(6);
+ scene->_arrObject1[3].setFrame(8);
+ scene->_arrObject1[4].setFrame(9);
+ scene->_arrObject1[5].setFrame(10);
+ scene->_arrObject1[6].setFrame(11);
+ scene->_arrObject1[7].setFrame(12);
+
+ R2_GLOBALS._sceneObjects->draw();
+
+ skipFrames(240);
+
+ scene->_arrObject1[0].remove();
+ scene->_arrObject1[1].remove();
+ scene->_arrObject1[2].remove();
+ scene->_arrObject1[3].remove();
+ scene->_arrObject1[4].remove();
+ scene->_arrObject1[5].remove();
+ scene->_arrObject1[6].remove();
+ scene->_arrObject1[7].remove();
+
+ scene->_arrObject2[0].remove();
+ scene->_arrObject2[1].remove();
+ scene->_arrObject2[2].remove();
+ scene->_arrObject2[3].remove();
+ scene->_arrObject2[4].remove();
+ scene->_arrObject2[5].remove();
+ scene->_arrObject2[6].remove();
+ scene->_arrObject2[7].remove();
+
+ scene->_item7._field34 = scene->_arrunkObj1337[2]._arr3[0]._field34;
+
+ scene->_arrunkObj1337[2]._arr3[0]._field34 = 0;
+ scene->_arrunkObj1337[2]._arr3[0]._object1.remove();
+
+ scene->_item2._object1.setPosition(scene->_arrunkObj1337[2]._arr3[0]._field36, 0);
+ scene->_item2._object1.show();
+
+ NpcMover *mover = new NpcMover();
+ scene->_item2._object1.addMover(mover, &scene->_item7._field36, this);
+ }
+ break;
+ case 7: {
+ scene->_item2._object1.hide();
+ scene->setAnimationInfo(&scene->_item7);
+ scene->_aSound2.play(61);
+
+ R2_GLOBALS._sceneObjects->draw();
+
+ scene->_arrunkObj1337[2]._arr3[0]._object1.postInit();
+ scene->_arrunkObj1337[2]._arr3[0]._object1.setVisage(1332);
+ scene->_arrunkObj1337[2]._arr3[0]._object1.setPosition(scene->_arrunkObj1337[2]._arr3[0]._field36, 0);
+ scene->_arrunkObj1337[2]._arr3[0]._object1.hide();
+
+ scene->_arrunkObj1337[3]._arr1[1]._field34 = 0;
+ scene->_arrunkObj1337[3]._arr1[1].remove();
+
+ scene->_item2._object1.setPosition(scene->_arrunkObj1337[3]._arr1[1]._field36, 0);
+ scene->_item2._object1.show();
+
+ NpcMover *mover = new NpcMover();
+ scene->_item2._object1.addMover(mover, &scene->_arrunkObj1337[2]._arr3[0]._field36, this);
+ }
+ break;
+ case 8: {
+ scene->_item2._object1.hide();
+ scene->_arrunkObj1337[2]._arr3[0]._field34 = 14;
+ scene->setAnimationInfo(&scene->_arrunkObj1337[2]._arr3[0]);
+ scene->_aSound1.play(57);
+
+ R2_GLOBALS._sceneObjects->draw();
+
+ scene->actionDisplay(1331, 16, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ int tmpVal = 72;
+ int i = -1;
+
+ for (i = 0; i <= 3; i++) {
+ tmpVal += 29;
+ scene->_arrObject1[i].postInit();
+ scene->_arrObject1[i].setVisage(1332);
+ scene->_arrObject1[i].setPosition(Common::Point(tmpVal, 71), 0);
+ scene->_arrObject1[i].setStrip(3);
+ scene->_arrObject1[i].fixPriority(190);
+
+ scene->_arrObject2[i].postInit();
+ scene->_arrObject2[i].setVisage(1332);
+ scene->_arrObject2[i].setPosition(Common::Point(tmpVal, 71), 0);
+ scene->_arrObject2[i].setStrip(7);
+ scene->_arrObject2[i].setFrame(1);
+ scene->_arrObject2[i].fixPriority(180);
+ }
+
+ scene->_arrObject1[0].setFrame(2);
+ scene->_arrObject1[1].setFrame(5);
+ scene->_arrObject1[2].setFrame(7);
+ scene->_arrObject1[3].setFrame(15);
+
+ R2_GLOBALS._sceneObjects->draw();
+
+ skipFrames(240);
+ scene->actionDisplay(1331, 17, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+
+ tmpVal = 72;
+ for (i = 4; i <= 7; i++) {
+ tmpVal += 29;
+
+ scene->_arrObject1[i].postInit();
+ scene->_arrObject1[i].setVisage(1332);
+ scene->_arrObject1[i].setPosition(Common::Point(tmpVal, 100), 0);
+ scene->_arrObject1[i].setStrip(4);
+ scene->_arrObject1[i].fixPriority(190);
+
+ scene->_arrObject2[i].postInit();
+ scene->_arrObject2[i].setVisage(1332);
+ scene->_arrObject2[i].setPosition(Common::Point(tmpVal, 100), 0);
+ scene->_arrObject2[i].setStrip(7);
+ scene->_arrObject2[i].setFrame(1);
+ scene->_arrObject2[i].fixPriority(180);
+ }
+
+ scene->_arrObject1[4].setFrame(1);
+ scene->_arrObject1[5].setFrame(5);
+ scene->_arrObject1[6].setFrame(7);
+ scene->_arrObject1[7].setFrame(3);
+
+ R2_GLOBALS._sceneObjects->draw();
+
+ skipFrames(240);
+
+ scene->_arrObject1[0].remove();
+ scene->_arrObject1[1].remove();
+ scene->_arrObject1[2].remove();
+ scene->_arrObject1[3].remove();
+ scene->_arrObject1[4].remove();
+ scene->_arrObject1[5].remove();
+ scene->_arrObject1[6].remove();
+ scene->_arrObject1[7].remove();
+
+ scene->_arrObject2[0].remove();
+ scene->_arrObject2[1].remove();
+ scene->_arrObject2[2].remove();
+ scene->_arrObject2[3].remove();
+ scene->_arrObject2[4].remove();
+ scene->_arrObject2[5].remove();
+ scene->_arrObject2[6].remove();
+ scene->_arrObject2[7].remove();
+
+ scene->_item7._field34 = scene->_arrunkObj1337[2]._arr1[0]._field34;
+
+ scene->_item2._object1.setStrip(scene->_arrunkObj1337[2]._arr1[0]._object1._strip);
+ scene->_item2._object1.setFrame(scene->_arrunkObj1337[2]._arr1[0]._object1._frame);
+ scene->_item2._object1.animate(ANIM_MODE_NONE, NULL);
+
+ scene->_arrunkObj1337[2]._arr1[0]._field34 = 0;
+ scene->_arrunkObj1337[2]._arr1[0]._object1.remove();
+
+ scene->_item2._object1.setPosition(scene->_arrunkObj1337[2]._arr1[0]._field36, 0);
+ scene->_item2._object1.show();
+
+ NpcMover *mover = new NpcMover();
+ scene->_item2._object1.addMover(mover, &scene->_arrunkObj1337[2]._arr3[0]._field36, this);
+ }
+ break;
+ case 9: {
+ scene->_aSound1.play(58);
+ scene->_arrunkObj1337[2]._arr3[0]._field34 = 0;
+ scene->_arrunkObj1337[2]._arr3[0].remove();
+ scene->_item2._object1.setStrip(5);
+ scene->_item2._object1.setFrame(1);
+ scene->_item2._object1.animate(ANIM_MODE_2, NULL);
+ scene->_item2._object1.setPosition(scene->_arrunkObj1337[2]._arr3[0]._field36, 0);
+ scene->_item2._object1.show();
+
+ NpcMover *mover = new NpcMover();
+ scene->_item2._object1.addMover(mover, &scene->_item7._field36, this);
+ }
+ break;
+ case 10: {
+ scene->_item2._object1.hide();
+ scene->setAnimationInfo(&scene->_item7);
+ scene->_aSound2.play(61);
+
+ R2_GLOBALS._sceneObjects->draw();
+ scene->actionDisplay(1331, 18, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+
+ scene->_arrObject1[0].postInit();
+ scene->_arrObject1[0].setVisage(1332);
+ scene->_arrObject1[0].setPosition(Common::Point(131, 71), 0);
+ scene->_arrObject1[0].fixPriority(190);
+ scene->_arrObject1[0].setStrip(3);
+ scene->_arrObject1[0].setFrame(4);
+
+ scene->_arrObject2[0].postInit();
+ scene->_arrObject2[0].setVisage(1332);
+ scene->_arrObject2[0].setPosition(Common::Point(131, 71), 0);
+ scene->_arrObject2[0].setStrip(7);
+ scene->_arrObject2[0].setFrame(1);
+ scene->_arrObject2[0].fixPriority(180);
+
+ scene->_arrObject1[1].postInit();
+ scene->_arrObject1[1].setVisage(1332);
+ scene->_arrObject1[1].setPosition(Common::Point(160, 71), 0);
+ scene->_arrObject1[1].fixPriority(190);
+ scene->_arrObject1[1].setStrip(3);
+ scene->_arrObject1[1].setFrame(16);
+
+ scene->_arrObject2[1].postInit();
+ scene->_arrObject2[1].setVisage(1332);
+ scene->_arrObject2[1].setPosition(Common::Point(160, 71), 0);
+ scene->_arrObject2[1].setStrip(7);
+ scene->_arrObject2[1].setFrame(1);
+ scene->_arrObject2[1].fixPriority(180);
+
+ scene->_arrObject1[2].postInit();
+ scene->_arrObject1[2].setVisage(1332);
+ scene->_arrObject1[2].setPosition(Common::Point(131, 100), 0);
+ scene->_arrObject1[2].fixPriority(190);
+ scene->_arrObject1[2].setStrip(4);
+ scene->_arrObject1[2].setFrame(4);
+
+ scene->_arrObject2[2].postInit();
+ scene->_arrObject2[2].setVisage(1332);
+ scene->_arrObject2[2].setPosition(Common::Point(131, 100), 0);
+ scene->_arrObject2[2].setStrip(7);
+ scene->_arrObject2[2].setFrame(1);
+ scene->_arrObject2[2].fixPriority(180);
+
+ scene->_arrObject1[3].postInit();
+ scene->_arrObject1[3].setVisage(1332);
+ scene->_arrObject1[3].setPosition(Common::Point(160, 100), 0);
+ scene->_arrObject1[3].fixPriority(190);
+ scene->_arrObject1[3].setStrip(4);
+ scene->_arrObject1[3].setFrame(2);
+
+ scene->_arrObject2[3].postInit();
+ scene->_arrObject2[3].setVisage(1332);
+ scene->_arrObject2[3].setPosition(Common::Point(160, 100), 0);
+ scene->_arrObject2[3].setStrip(7);
+ scene->_arrObject2[3].setFrame(1);
+ scene->_arrObject2[3].fixPriority(180);
+
+ R2_GLOBALS._sceneObjects->draw();
+
+ skipFrames(240);
+
+ scene->_arrObject1[0].remove();
+ scene->_arrObject1[1].remove();
+ scene->_arrObject1[2].remove();
+ scene->_arrObject1[3].remove();
+
+ scene->_arrObject2[0].remove();
+ scene->_arrObject2[1].remove();
+ scene->_arrObject2[2].remove();
+ scene->_arrObject2[3].remove();
+
+ scene->_object1.setFrame(1);
+ scene->_object1.show();
+ scene->_object1.animate(ANIM_MODE_2, NULL);
+
+ R2_GLOBALS._sceneObjects->draw();
+
+ scene->actionDisplay(1331, 19, 159, 10, 1, 220, 0, 7, 0, 154, 154);
+
+ scene->_object1.hide();
+
+ scene->actionDisplay(1331, 20, 159, 10, 1, 220, 0, 7, 0, 154, 154);
+ scene->actionDisplay(1331, 21, 159, 10, 1, 220, 0, 7, 0, 154, 154);
+
+ scene->_item7._field34 = scene->_arrunkObj1337[2]._arr1[1]._field34;
+
+ scene->_item2._object1.setStrip(scene->_arrunkObj1337[2]._arr1[1]._object1._strip);
+ scene->_item2._object1.setFrame(scene->_arrunkObj1337[2]._arr1[1]._object1._frame);
+ scene->_item2._object1.animate(ANIM_MODE_NONE, NULL);
+
+ scene->_arrunkObj1337[2]._arr1[1]._field34 = 0;
+ scene->_arrunkObj1337[2]._arr1[1]._object1.remove();
+
+ scene->_item2._object1.setPosition(scene->_arrunkObj1337[2]._arr1[1]._field36, 0);
+ scene->_item2._object1.show();
+
+ NpcMover *mover = new NpcMover();
+ scene->_item2._object1.addMover(mover, &scene->_item7._field36, this);
+ }
+ break;
+ case 11: {
+ scene->_item2._object1.hide();
+ scene->setAnimationInfo(&scene->_item7);
+ scene->_aSound2.play(61);
+ scene->_item2._object1.setStrip(5);
+ scene->_item2._object1.setFrame(1);
+ scene->_item2._object1.animate(ANIM_MODE_2, NULL);
+
+ R2_GLOBALS._sceneObjects->draw();
+
+ scene->actionDisplay(1331, 22, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+
+ int i = -1;
+ for (i = 0; i <= 3; i ++) {
+ scene->_arrunkObj1337[3]._arr1[i]._field34 = 0;
+ scene->_arrunkObj1337[3]._arr1[i]._object1.remove();
+
+ scene->_arrunkObj1337[2]._arr1[i]._field34 = 0;
+ scene->_arrunkObj1337[2]._arr1[i]._object1.remove();
+
+ scene->_arrunkObj1337[0]._arr1[i]._field34 = 0;
+ scene->_arrunkObj1337[0]._arr1[i]._object1.remove();
+
+ scene->_arrunkObj1337[1]._arr1[i]._field34 = 0;
+ scene->_arrunkObj1337[1]._arr1[i]._object1.remove();
+ }
+
+ for (i = 0; i <= 7; i++) {
+ scene->_arrunkObj1337[3]._arr2[i]._field34 = 0;
+ scene->_arrunkObj1337[3]._arr2[i]._object1.remove();
+
+ scene->_arrunkObj1337[2]._arr2[i]._field34 = 0;
+ scene->_arrunkObj1337[2]._arr2[i]._object1.remove();
+
+ scene->_arrunkObj1337[0]._arr2[i]._field34 = 0;
+ scene->_arrunkObj1337[0]._arr2[i]._object1.remove();
+
+ scene->_arrunkObj1337[1]._arr2[i]._field34 = 0;
+ scene->_arrunkObj1337[1]._arr2[i]._object1.remove();
+ }
+
+ scene->_arrunkObj1337[2]._arr3[0]._field34 = 0;
+ scene->_arrunkObj1337[2]._arr3[0]._object1.remove();
+
+ scene->_item7._field34 = 0;
+ scene->_item7._object1.remove();
+
+ scene->_background2.remove();
+ }
+ // No break on purpose
+ case 0:
+ R2_GLOBALS._sceneObjects->draw();
+ signal();
+ break;
+ case 12:
+ scene->suggestInstructions();
+ remove();
+ break;
+ default:
+ break;
+ }
+}
+
+void Scene1337::Action2::signal() {
+ Scene1337 *scene = (Scene1337 *)R2_GLOBALS._sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0:
+ scene->_item3._object1.postInit();
+ scene->_item3._object1.setVisage(1332);
+ scene->_item3._object1.setStrip(8);
+ scene->_item3._object1.setFrame(1);
+ scene->_item3._object1.fixPriority(300);
+ scene->_item3._object1.setPosition(Common::Point(156, 108));
+
+ scene->_item7._object1.remove();
+ scene->_item7._field34 = 0;
+
+ scene->_aSound1.play(60);
+ scene->_item3._object1.animate(ANIM_MODE_5, this);
+ break;
+ case 1:
+ scene->_item3._object1.setFrame(1);
+
+ scene->_aSound1.play(60);
+ scene->_item3._object1.animate(ANIM_MODE_5, this);
+ break;
+ case 2: {
+ Common::Point pt(156, 108);
+ NpcMover *mover = new NpcMover();
+ scene->_item3._object1.addMover(mover, &pt, this);
+ }
+ break;
+ case 3:
+ scene->_item3._object1.remove();
+ scene->_background2.setup2(1332, 5, 1, 162, 95, 110, 1);
+ scene->_field423C = 1;
+ break;
+ default:
+ break;
+ }
+}
+
+void Scene1337::Action3::signal() {
+ Scene1337 *scene = (Scene1337 *)R2_GLOBALS._sceneManager._scene;
+
+ scene->_item2._object1.setPosition(Common::Point(162, 95), 0);
+
+ switch (_actionIndex++) {
+ case 0: {
+ scene->_item2._object1._moveDiff = Common::Point(30, 30);
+ scene->_item2._object1.setVisage(1332);
+ scene->_item2._object1.setStrip(5);
+ scene->_item2._object1.setFrame(1);
+ scene->_item2._object1.fixPriority(400);
+ scene->_item2._object1.animate(ANIM_MODE_2, NULL);
+ scene->_aSound2.play(61);
+
+ Common::Point pt(283, 146);
+ NpcMover *mover = new NpcMover();
+ scene->_item2._object1.addMover(mover, &pt, this);
+
+ scene->_item2._object1.show();
+ scene->_arrunkObj1337[1]._arr1[0]._field34 = scene->_field3E28[scene->_field3E24];
+ }
+ break;
+ case 1: {
+ scene->_arrunkObj1337[1]._arr1[0]._object1.postInit();
+ scene->_arrunkObj1337[1]._arr1[0]._object1._moveDiff = Common::Point(30, 30);
+ scene->_arrunkObj1337[1]._arr1[0]._object1.setVisage(1332);
+ scene->_arrunkObj1337[1]._arr1[0]._object1.setPosition(scene->_arrunkObj1337[1]._arr1[0]._field36, 0);
+ scene->_arrunkObj1337[1]._arr1[0]._object1.setStrip(1);
+ scene->_arrunkObj1337[1]._arr1[0]._object1.setFrame(4);
+ scene->_arrunkObj1337[1]._arr1[0]._object1.fixPriority(170);
+ scene->_aSound2.play(61);
+
+ Common::Point pt(10, 174);
+ NpcMover *mover = new NpcMover();
+ scene->_item2._object1.addMover(mover, &pt, this);
+
+ scene->_arrunkObj1337[2]._arr1[0]._field34 = scene->_field3E28[scene->_field3E24];
+ }
+ break;
+ case 2: {
+ scene->_arrunkObj1337[2]._arr1[0]._object1.postInit();
+ scene->_arrunkObj1337[2]._arr1[0]._object1._moveDiff = Common::Point(30, 30);
+ scene->_arrunkObj1337[2]._arr1[0]._object1.setVisage(1332);
+ scene->_arrunkObj1337[2]._arr1[0]._object1.setPosition(scene->_arrunkObj1337[2]._arr1[0]._field36, 0);
+ scene->_arrunkObj1337[2]._arr1[0]._object1.fixPriority(170);
+ if (scene->_arrunkObj1337[2]._arr1[0]._field34 > 9) {
+ if (scene->_arrunkObj1337[2]._arr1[0]._field34 > 25) {
+ scene->_arrunkObj1337[2]._arr1[0]._object1.setStrip(4);
+ scene->_arrunkObj1337[2]._arr1[0]._object1.setFrame(scene->_arrunkObj1337[2]._arr1[0]._field34 - 25);
+ } else {
+ scene->_arrunkObj1337[2]._arr1[0]._object1.setStrip(3);
+ scene->_arrunkObj1337[2]._arr1[0]._object1.setFrame(scene->_arrunkObj1337[2]._arr1[0]._field34 - 9);
+ }
+ } else {
+ scene->_arrunkObj1337[2]._arr1[0]._object1.setStrip(2);
+ scene->_arrunkObj1337[2]._arr1[0]._object1.setFrame(scene->_arrunkObj1337[2]._arr1[0]._field34);
+ }
+ scene->_aSound2.play(61);
+
+ Common::Point pt(14, 14);
+ NpcMover *mover = new NpcMover();
+ scene->_item2._object1.addMover(mover, &pt, this);
+
+ scene->_arrunkObj1337[3]._arr1[0]._field34 = scene->_field3E28[scene->_field3E24];
+ }
+ break;
+ case 3: {
+ scene->_arrunkObj1337[3]._arr1[0]._object1.postInit();
+ scene->_arrunkObj1337[3]._arr1[0]._object1._moveDiff = Common::Point(30, 30);
+ scene->_arrunkObj1337[3]._arr1[0]._object1.setVisage(1332);
+ scene->_arrunkObj1337[3]._arr1[0]._object1.setPosition(scene->_arrunkObj1337[3]._arr1[0]._field36, 0);
+ scene->_arrunkObj1337[3]._arr1[0]._object1.setStrip(1);
+ scene->_arrunkObj1337[3]._arr1[0]._object1.setFrame(3);
+ scene->_arrunkObj1337[3]._arr1[0]._object1.fixPriority(170);
+ scene->_aSound2.play(61);
+
+ Common::Point pt(280, 5);
+ NpcMover *mover = new NpcMover();
+ scene->_item2._object1.addMover(mover, &pt, this);
+
+ scene->_arrunkObj1337[0]._arr1[0]._field34 = scene->_field3E28[scene->_field3E24];
+ }
+ break;
+ case 4: {
+ scene->_arrunkObj1337[0]._arr1[0]._object1.postInit();
+ scene->_arrunkObj1337[0]._arr1[0]._object1._moveDiff = Common::Point(30,30);
+ scene->_arrunkObj1337[0]._arr1[0]._object1.setVisage(1332);
+ scene->_arrunkObj1337[0]._arr1[0]._object1.setPosition(scene->_arrunkObj1337[0]._arr1[0]._field36, 0);
+ scene->_arrunkObj1337[0]._arr1[0]._object1.setStrip(5);
+ scene->_arrunkObj1337[0]._arr1[0]._object1.setFrame(1);
+ scene->_arrunkObj1337[0]._arr1[0]._object1.fixPriority(170);
+ scene->_aSound2.play(61);
+
+ Common::Point pt(283, 124);
+ NpcMover *mover = new NpcMover();
+ scene->_item2._object1.addMover(mover, &pt, this);
+
+ scene->_arrunkObj1337[1]._arr1[1]._field34 = scene->_field3E28[scene->_field3E24];
+ }
+ break;
+ case 5: {
+ scene->_arrunkObj1337[1]._arr1[1]._object1.postInit();
+ scene->_arrunkObj1337[1]._arr1[1]._object1._moveDiff = Common::Point(30, 30);
+ scene->_arrunkObj1337[1]._arr1[1]._object1.setVisage(1332);
+ scene->_arrunkObj1337[1]._arr1[1]._object1.setPosition(scene->_arrunkObj1337[1]._arr1[1]._field36, 0);
+ scene->_arrunkObj1337[1]._arr1[1]._object1.setStrip(1);
+ scene->_arrunkObj1337[1]._arr1[1]._object1.setFrame(4);
+ scene->_arrunkObj1337[1]._arr1[1]._object1.fixPriority(170);
+ scene->_aSound2.play(61);
+
+ Common::Point pt(37, 174);
+ NpcMover *mover = new NpcMover();
+ scene->_item2._object1.addMover(mover, &pt, this);
+
+ scene->_arrunkObj1337[2]._arr1[1]._field34 = scene->_field3E28[scene->_field3E24];
+ }
+ break;
+ case 6: {
+ scene->_arrunkObj1337[2]._arr1[1]._object1.postInit();
+ scene->_arrunkObj1337[2]._arr1[1]._object1._moveDiff = Common::Point(30, 30);
+ scene->_arrunkObj1337[2]._arr1[1]._object1.setVisage(1332);
+ scene->_arrunkObj1337[2]._arr1[1]._object1.setPosition(scene->_arrunkObj1337[2]._arr1[1]._field36, 0);
+ scene->_arrunkObj1337[2]._arr1[1]._object1.fixPriority(170);
+
+ if (scene->_arrunkObj1337[2]._arr1[1]._field34 > 9) {
+ if (scene->_arrunkObj1337[2]._arr1[1]._field34 > 25) {
+ scene->_arrunkObj1337[2]._arr1[1]._object1.setStrip(4);
+ scene->_arrunkObj1337[2]._arr1[1]._object1.setFrame(scene->_arrunkObj1337[2]._arr1[1]._field34 - 25);
+ } else {
+ scene->_arrunkObj1337[2]._arr1[1]._object1.setStrip(3);
+ scene->_arrunkObj1337[2]._arr1[1]._object1.setFrame(scene->_arrunkObj1337[2]._arr1[1]._field34 - 9);
+ }
+ } else {
+ scene->_arrunkObj1337[2]._arr1[1]._object1.setStrip(2);
+ scene->_arrunkObj1337[2]._arr1[1]._object1.setFrame(scene->_arrunkObj1337[2]._arr1[1]._field34);
+ }
+
+ scene->_aSound2.play(61);
+
+ Common::Point pt(14, 36);
+ NpcMover *mover = new NpcMover();
+ scene->_item2._object1.addMover(mover, &pt, this);
+
+ scene->_arrunkObj1337[3]._arr1[1]._field34 = scene->_field3E28[scene->_field3E24];
+ }
+ break;
+ case 7: {
+ scene->_arrunkObj1337[3]._arr1[1]._object1.postInit();
+ scene->_arrunkObj1337[3]._arr1[1]._object1._moveDiff = Common::Point(30, 30);
+ scene->_arrunkObj1337[3]._arr1[1]._object1.setVisage(1332);
+ scene->_arrunkObj1337[3]._arr1[1]._object1.setPosition(scene->_arrunkObj1337[3]._arr1[1]._field36);
+ scene->_arrunkObj1337[3]._arr1[1]._object1.setStrip(1);
+ scene->_arrunkObj1337[3]._arr1[1]._object1.setFrame(3);
+ scene->_arrunkObj1337[3]._arr1[1]._object1.fixPriority(170);
+ scene->_aSound2.play(61);
+
+ Common::Point pt(253, 5);
+ NpcMover *mover = new NpcMover();
+ scene->_item2._object1.addMover(mover, &pt, this);
+
+ scene->_arrunkObj1337[0]._arr1[1]._field34 = scene->_field3E28[scene->_field3E24];
+ }
+ break;
+ case 8: {
+ scene->_arrunkObj1337[0]._arr1[1]._object1.postInit();
+ scene->_arrunkObj1337[0]._arr1[1]._object1._moveDiff = Common::Point(30, 30);
+ scene->_arrunkObj1337[0]._arr1[1]._object1.setVisage(1332);
+ scene->_arrunkObj1337[0]._arr1[1]._object1.setPosition(scene->_arrunkObj1337[0]._arr1[1]._field36, 0);
+ scene->_arrunkObj1337[0]._arr1[1]._object1.setStrip(5);
+ scene->_arrunkObj1337[0]._arr1[1]._object1.setFrame(1);
+ scene->_arrunkObj1337[0]._arr1[1]._object1.fixPriority(170);
+ scene->_aSound2.play(61);
+
+ Common::Point pt(283, 102);
+ NpcMover *mover = new NpcMover();
+ scene->_item2._object1.addMover(mover, &pt, this);
+
+ scene->_arrunkObj1337[1]._arr1[2]._field34 = scene->_field3E28[scene->_field3E24];
+ }
+ break;
+ case 9: {
+ scene->_arrunkObj1337[1]._arr1[2]._object1.postInit();
+ scene->_arrunkObj1337[1]._arr1[2]._object1._moveDiff = Common::Point(30, 30);
+ scene->_arrunkObj1337[1]._arr1[2]._object1.setVisage(1332);
+ scene->_arrunkObj1337[1]._arr1[2]._object1.setPosition(scene->_arrunkObj1337[1]._arr1[2]._field36, 0);
+ scene->_arrunkObj1337[1]._arr1[2]._object1.setStrip(1);
+ scene->_arrunkObj1337[1]._arr1[2]._object1.setFrame(4);
+ scene->_arrunkObj1337[1]._arr1[2]._object1.fixPriority(170);
+ scene->_aSound2.play(61);
+
+ Common::Point pt(64, 174);
+ NpcMover *mover = new NpcMover();
+ scene->_item2._object1.addMover(mover, &pt, this);
+
+ scene->_arrunkObj1337[2]._arr1[2]._field34 = scene->_field3E28[scene->_field3E24];
+ }
+ break;
+ case 10: {
+ scene->_arrunkObj1337[2]._arr1[2]._object1.postInit();
+ scene->_arrunkObj1337[2]._arr1[2]._object1._moveDiff = Common::Point(30, 30);
+ scene->_arrunkObj1337[2]._arr1[2]._object1.setVisage(1332);
+ scene->_arrunkObj1337[2]._arr1[2]._object1.setPosition(scene->_arrunkObj1337[2]._arr1[2]._field36, 0);
+ scene->_arrunkObj1337[2]._arr1[2]._object1.fixPriority(170);
+
+ if (scene->_arrunkObj1337[2]._arr1[2]._field34 > 9) {
+ if (scene->_arrunkObj1337[2]._arr1[2]._field34 > 25) {
+ scene->_arrunkObj1337[2]._arr1[2]._object1.setStrip(4);
+ scene->_arrunkObj1337[2]._arr1[2]._object1.setFrame(scene->_arrunkObj1337[2]._arr1[2]._field34 - 25);
+ } else {
+ scene->_arrunkObj1337[2]._arr1[2]._object1.setStrip(3);
+ scene->_arrunkObj1337[2]._arr1[2]._object1.setFrame(scene->_arrunkObj1337[2]._arr1[2]._field34 - 9);
+ }
+ } else {
+ scene->_arrunkObj1337[2]._arr1[2]._object1.setStrip(2);
+ scene->_arrunkObj1337[2]._arr1[2]._object1.setFrame(scene->_arrunkObj1337[2]._arr1[2]._field34);
+ }
+
+ scene->_aSound2.play(61);
+
+ Common::Point pt(14, 58);
+ NpcMover *mover = new NpcMover();
+ scene->_item2._object1.addMover(mover, &pt, this);
+
+ scene->_arrunkObj1337[3]._arr1[2]._field34 = scene->_field3E28[scene->_field3E24];
+ }
+ break;
+ case 11: {
+ scene->_arrunkObj1337[3]._arr1[2]._object1.postInit();
+ scene->_arrunkObj1337[3]._arr1[2]._object1._moveDiff = Common::Point(30, 30);
+ scene->_arrunkObj1337[3]._arr1[2]._object1.setVisage(1332);
+ scene->_arrunkObj1337[3]._arr1[2]._object1.setPosition(scene->_arrunkObj1337[3]._arr1[2]._field36, 0);
+ scene->_arrunkObj1337[3]._arr1[2]._object1.setStrip(1);
+ scene->_arrunkObj1337[3]._arr1[2]._object1.setFrame(3);
+ scene->_arrunkObj1337[3]._arr1[2]._object1.fixPriority(170);
+ scene->_aSound2.play(61);
+
+ Common::Point pt(226, 5);
+ NpcMover *mover = new NpcMover();
+ scene->_item2._object1.addMover(mover, &pt, this);
+
+ scene->_arrunkObj1337[0]._arr1[2]._field34 = scene->_field3E28[scene->_field3E24];
+ }
+ break;
+ case 12:
+ scene->_arrunkObj1337[0]._arr1[2]._object1.postInit();
+ scene->_arrunkObj1337[0]._arr1[2]._object1._moveDiff = Common::Point(30, 30);
+ scene->_arrunkObj1337[0]._arr1[2]._object1.setVisage(1332);
+ scene->_arrunkObj1337[0]._arr1[2]._object1.setPosition(scene->_arrunkObj1337[0]._arr1[2]._field36, 0);
+ scene->_arrunkObj1337[0]._arr1[2]._object1.setStrip(5);
+ scene->_arrunkObj1337[0]._arr1[2]._object1.setFrame(1);
+ scene->_arrunkObj1337[0]._arr1[2]._object1.fixPriority(170);
+ scene->_arrunkObj1337[0]._arr1[2]._object1.hide();
+ default:
+ break;
+ }
+
+ if (_actionIndex > 12) {
+ scene->_field423E = 0;
+ R2_GLOBALS._sceneObjects->draw();
+ scene->actionDisplay(1330, 0, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ scene->subC20F9();
+ } else if (_actionIndex >= 1) {
+ scene->_field3E28[scene->_field3E24] = 0;
+ scene->_field3E24--;
+ }
+}
+
+void Scene1337::Action4::signal() {
+ Scene1337 *scene = (Scene1337 *)R2_GLOBALS._sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0:
+ if ((scene->_arrunkObj1337[scene->_field423E]._arr1[0]._field34 == 0) && (scene->subC264B(scene->_arrunkObj1337[scene->_field423E]._arr3[0]._field34))) {
+ if (scene->_field3E24 < 0)
+ scene->subC264B(scene->_arrunkObj1337[scene->_field423E]._arr3[0]._field34);
+ scene->_item2._object1.setPosition(Common::Point(162, 95), 0);
+ scene->_item2._object1.show();
+ scene->_aSound2.play(61);
+
+ NpcMover *mover = new NpcMover();
+ scene->_item2._object1.addMover(mover, &scene->_arrunkObj1337[scene->_field423E]._fieldB94, this);
+
+ scene->_arrunkObj1337[scene->_field423E]._arr1[0]._field34 = scene->_field3E28[scene->_field3E24];
+ scene->_field3E28[scene->_field3E24] = 0;
+ scene->_field3E24--;
+
+ if (scene->_field3E24 < 0)
+ scene->_background2.remove();
+ } else {
+ // Self call, forcing next actionIndex
+ signal();
+ }
+ break;
+ case 1:
+ if ( ( scene->_item2._object1._position.x == scene->_arrunkObj1337[scene->_field423E]._fieldB94.x)
+ && ( scene->_item2._object1._position.y == scene->_arrunkObj1337[scene->_field423E]._fieldB94.y) ) {
+ scene->_arrunkObj1337[scene->_field423E]._arr1[0]._object1.postInit();
+ scene->_arrunkObj1337[scene->_field423E]._arr1[0]._object1._moveDiff = Common::Point(30, 30);
+ scene->_arrunkObj1337[scene->_field423E]._arr1[0]._object1.setVisage(1332);
+ scene->_arrunkObj1337[scene->_field423E]._arr1[0]._object1.setPosition(scene->_arrunkObj1337[scene->_field423E]._arr1[0]._field36, 0);
+ scene->_arrunkObj1337[scene->_field423E]._arr1[0]._object1.setStrip(1);
+ scene->_arrunkObj1337[scene->_field423E]._arr1[0]._object1.setFrame(scene->_arrunkObj1337[scene->_field423E]._fieldBA4);
+ scene->_arrunkObj1337[scene->_field423E]._arr1[0]._object1.fixPriority(170);
+ }
+
+ if ((scene->_field4248 == 1) || (scene->_field423E == 2))
+ scene->setAnimationInfo(&scene->_arrunkObj1337[scene->_field423E]._arr1[0]);
+
+ scene->_item2._object1.hide();
+ if ((scene->_arrunkObj1337[scene->_field423E]._arr1[0]._field34 == 0) && (scene->subC264B(scene->_arrunkObj1337[scene->_field423E]._arr3[0]._field34 == 0))) {
+ if (scene->_field3E24 < 0)
+ scene->shuffleCards();
+ scene->_item2._object1.setPosition(Common::Point(162, 95));
+ scene->_item2._object1.show();
+
+ scene->_aSound2.play(61);
+
+ NpcMover *mover = new NpcMover();
+ scene->_item2._object1.addMover(mover, &scene->_arrunkObj1337[scene->_field423E]._fieldB98, this);
+
+ scene->_arrunkObj1337[scene->_field423E]._arr1[1]._field34 = scene->_field3E28[scene->_field3E24];
+ scene->_field3E28[scene->_field3E24] = 0;
+ scene->_field3E24--;
+ if (scene->_field3E24 < 0)
+ scene->_background2.remove();
+ } else
+ signal();
+ break;
+ case 2:
+ if ( ( scene->_item2._object1._position.x == scene->_arrunkObj1337[scene->_field423E]._fieldB98.x)
+ && ( scene->_item2._object1._position.y == scene->_arrunkObj1337[scene->_field423E]._fieldB98.y) ) {
+ scene->_arrunkObj1337[scene->_field423E]._arr1[1]._object1.postInit();
+ scene->_arrunkObj1337[scene->_field423E]._arr1[1]._object1._moveDiff = Common::Point(30, 30);
+ scene->_arrunkObj1337[scene->_field423E]._arr1[1]._object1.setVisage(1332);
+ scene->_arrunkObj1337[scene->_field423E]._arr1[1]._object1.setPosition(scene->_arrunkObj1337[scene->_field423E]._arr1[1]._field36, 0);
+ scene->_arrunkObj1337[scene->_field423E]._arr1[1]._object1.setStrip(1);
+ scene->_arrunkObj1337[scene->_field423E]._arr1[1]._object1.setFrame(scene->_arrunkObj1337[scene->_field423E]._fieldBA4);
+ scene->_arrunkObj1337[scene->_field423E]._arr1[1]._object1.fixPriority(170);
+ }
+
+ if ((scene->_field4248 == 1) || (scene->_field423E == 2))
+ scene->setAnimationInfo(&scene->_arrunkObj1337[scene->_field423E]._arr1[1]);
+
+ scene->_item2._object1.hide();
+ if ((scene->_arrunkObj1337[scene->_field423E]._arr1[2]._field34 == 0) && (scene->subC264B(scene->_arrunkObj1337[scene->_field423E]._arr3[0]._field34 == 0))) {
+ if (scene->_field3E24 < 0)
+ scene->shuffleCards();
+ scene->_item2._object1.setPosition(Common::Point(162, 95));
+ scene->_item2._object1.show();
+
+ scene->_aSound2.play(61);
+
+ NpcMover *mover = new NpcMover();
+ scene->_item2._object1.addMover(mover, &scene->_arrunkObj1337[scene->_field423E]._fieldB9C, this);
+
+ scene->_arrunkObj1337[scene->_field423E]._arr1[2]._field34 = scene->_field3E28[scene->_field3E24];
+ scene->_field3E28[scene->_field3E24] = 0;
+ scene->_field3E24--;
+ if (scene->_field3E24 < 0)
+ scene->_background2.remove();
+ } else
+ signal();
+ break;
+ case 3:
+ if ( ( scene->_item2._object1._position.x == scene->_arrunkObj1337[scene->_field423E]._fieldB9C.x)
+ && ( scene->_item2._object1._position.y == scene->_arrunkObj1337[scene->_field423E]._fieldB9C.y) ) {
+ scene->_arrunkObj1337[scene->_field423E]._arr1[2]._object1.postInit();
+ scene->_arrunkObj1337[scene->_field423E]._arr1[2]._object1._moveDiff = Common::Point(30, 30);
+ scene->_arrunkObj1337[scene->_field423E]._arr1[2]._object1.setVisage(1332);
+ scene->_arrunkObj1337[scene->_field423E]._arr1[2]._object1.setPosition(scene->_arrunkObj1337[scene->_field423E]._arr1[2]._field36, 0);
+ scene->_arrunkObj1337[scene->_field423E]._arr1[2]._object1.setStrip(1);
+ scene->_arrunkObj1337[scene->_field423E]._arr1[2]._object1.setFrame(scene->_arrunkObj1337[scene->_field423E]._fieldBA4);
+ scene->_arrunkObj1337[scene->_field423E]._arr1[2]._object1.fixPriority(170);
+ }
+
+ if ((scene->_field4248 == 1) || (scene->_field423E == 2))
+ scene->setAnimationInfo(&scene->_arrunkObj1337[scene->_field423E]._arr1[2]);
+
+ scene->_item2._object1.hide();
+ if ((scene->_arrunkObj1337[scene->_field423E]._arr1[3]._field34 == 0) && (scene->subC264B(scene->_arrunkObj1337[scene->_field423E]._arr3[0]._field34 == 0))) {
+ if (scene->_field3E24 < 0)
+ scene->shuffleCards();
+ scene->_item2._object1.setPosition(Common::Point(162, 95));
+ scene->_item2._object1.show();
+
+ scene->_aSound2.play(61);
+
+ NpcMover *mover = new NpcMover();
+ scene->_item2._object1.addMover(mover, &scene->_arrunkObj1337[scene->_field423E]._fieldBA0, this);
+
+ scene->_arrunkObj1337[scene->_field423E]._arr1[3]._field34 = scene->_field3E28[scene->_field3E24];
+ scene->_field3E28[scene->_field3E24] = 0;
+ scene->_field3E24--;
+ if (scene->_field3E24 < 0)
+ scene->_background2.remove();
+ } else
+ signal();
+ break;
+ case 4:
+ if ( ( scene->_item2._object1._position.x == scene->_arrunkObj1337[scene->_field423E]._fieldBA0.x)
+ && ( scene->_item2._object1._position.y == scene->_arrunkObj1337[scene->_field423E]._fieldBA0.y) ) {
+ scene->_arrunkObj1337[scene->_field423E]._arr1[3]._object1.postInit();
+ scene->_arrunkObj1337[scene->_field423E]._arr1[3]._object1._moveDiff = Common::Point(30, 30);
+ scene->_arrunkObj1337[scene->_field423E]._arr1[3]._object1.setVisage(1332);
+ scene->_arrunkObj1337[scene->_field423E]._arr1[3]._object1.setPosition(scene->_arrunkObj1337[scene->_field423E]._arr1[3]._field36, 0);
+ scene->_arrunkObj1337[scene->_field423E]._arr1[3]._object1.setStrip(1);
+ scene->_arrunkObj1337[scene->_field423E]._arr1[3]._object1.setFrame(scene->_arrunkObj1337[scene->_field423E]._fieldBA4);
+ scene->_arrunkObj1337[scene->_field423E]._arr1[3]._object1.fixPriority(170);
+ }
+
+ if ((scene->_field4248 == 1) || (scene->_field423E == 2))
+ scene->setAnimationInfo(&scene->_arrunkObj1337[scene->_field423E]._arr1[3]);
+
+ scene->_item2._object1.hide();
+ switch (scene->_field423E) {
+ case 0:
+ scene->subCF979();
+ break;
+ case 1:
+ scene->subCF31D();
+ break;
+ case 2:
+ scene->subD0281();
+ break;
+ case 3:
+ scene->subC2C2F();
+ break;
+ default:
+ break;
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+void Scene1337::Action5::signal() {
+ Scene1337 *scene = (Scene1337 *)R2_GLOBALS._sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0: {
+ scene->_field3E28[scene->_field3E26] = scene->_field3EF0->_field34;
+ scene->_field3E26--;
+ if (!g_globals->_sceneObjects->contains(&scene->_item7._object1)) {
+ scene->_item7._object1.postInit();
+ scene->_item7._object1.hide();
+ scene->_item7._object1.setVisage(1332);
+ scene->_item7._object1.setPosition(scene->_item7._field36, 0);
+ scene->_item7._object1.fixPriority(170);
+ }
+
+ scene->_item7._field34 = scene->_field3EF0->_field34;
+ scene->_field3EF0->_field34 = 0;
+ scene->_field3EF0->_object1.remove();
+
+ if (scene->_field3EF0 == &scene->_item6) {
+ subD18B5(5, 1, 4);
+ scene->subC4CEC();
+ }
+ scene->_item2._object1.setPosition(scene->_field3EF0->_field36, 0);
+ scene->_item2._object1.show();
+ Common::Point pt(128, 95);
+ NpcMover *mover = new NpcMover();
+ scene->_item2._object1.addMover(mover, &pt, this);
+ }
+ break;
+ case 1:
+ scene->_item2._object1.hide();
+ scene->setAnimationInfo(&scene->_item7);
+ scene->_aSound2.play(61);
+ scene->subC20F9();
+ break;
+ default:
+ break;
+ }
+}
+
+void Scene1337::Action6::signal() {
+ Scene1337 *scene = (Scene1337 *)R2_GLOBALS._sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0: {
+ scene->_field3EF4->_field34 = 1;
+ scene->_field3EF4->_object1.postInit();
+ scene->_field3EF4->_object1.hide();
+ scene->_field3EF4->_object1.setVisage(1332);
+ scene->_field3EF4->_object1.setPosition(scene->_field3EF4->_field36);
+ scene->_field3EF4->_object1.fixPriority(170);
+
+ scene->_field3EF0->_field34 = 0;
+ scene->_field3EF0->_object1.remove();
+
+ scene->_item2._object1.setPosition(scene->_field3EF0->_field36);
+ scene->_item2._object1.show();
+
+ NpcMover *mover = new NpcMover();
+ scene->_item2._object1.addMover(mover, &scene->_field3EF4->_field36, this);
+ }
+ break;
+ case 1:
+ scene->_item2._object1.hide();
+ scene->setAnimationInfo(scene->_field3EF4);
+ scene->_aSound1.play(59);
+ if (scene->_field3EF0 == &scene->_item6) {
+ subD18B5(5, 1, 4);
+ scene->subC4CEC();
+ }
+ scene->subC20F9();
+ break;
+ default:
+ break;
+ }
+}
+
+void Scene1337::Action7::signal() {
+ Scene1337 *scene = (Scene1337 *)R2_GLOBALS._sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0: {
+ scene->_field3EF4->_field34 = scene->_field3EF0->_field34;
+
+ scene->_field3EF0->_field34 = 0;
+ scene->_field3EF0->_object1.remove();
+
+ scene->_item2._object1.setPosition(scene->_field3EF0->_field36, 0);
+ scene->_item2._object1.show();
+ NpcMover *mover = new NpcMover();
+ scene->_item2._object1.addMover(mover, &scene->_field3EF4->_field36, this);
+ }
+ break;
+ case 1:
+ if (scene->_field3EF0 == &scene->_item6) {
+ subD18B5(5, 1, 4);
+ scene->subC4CEC();
+ }
+ scene->setAnimationInfo(scene->_field3EF4);
+ scene->_aSound1.play(59);
+ scene->_item5._field34 = 1;
+ scene->_item5._field36.x = scene->_field3EF4->_field36.x;
+ scene->_item5._field36.y = scene->_field3EF4->_field36.y;
+ scene->_item5._object1.postInit();
+ scene->_item5._object1.hide();
+ scene->_item5._object1._flags = 0x200;
+
+ scene->subC4A39(&scene->_item5);
+ break;
+ default:
+ break;
+ }
+}
+
+void Scene1337::Action8::signal() {
+ Scene1337 *scene = (Scene1337 *)R2_GLOBALS._sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0: {
+ scene->_field3E28[scene->_field3E26] = scene->_field3EF4->_field34;
+ scene->_field3E26--;
+
+ scene->_field3EF4->_field34 = scene->_field3EF0->_field34;
+ scene->_field3EF0->_object1.remove();
+
+ scene->_item2._object1.setPosition(scene->_field3EF0->_field36, 0);
+ scene->_item2._object1.show();
+
+ NpcMover *mover = new NpcMover();
+ scene->_item2._object1.addMover(mover, &scene->_field3EF4->_field36, this);
+ }
+ break;
+ case 1:
+ scene->_item2._object1.hide();
+
+ if (scene->_field3EF0 == &scene->_item6) {
+ subD18B5(5, 1, 4);
+ scene->subC4CEC();
+ }
+ scene->setAnimationInfo(scene->_field3EF4);
+ scene->_aSound1.play(58);
+ scene->subC4A39(scene->_field3EF4);
+ break;
+ default:
+ break;
+ }
+}
+
+void Scene1337::Action9::signal() {
+ Scene1337 *scene = (Scene1337 *)R2_GLOBALS._sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0: {
+ scene->_field3EF4->_field34 = scene->_field3EF0->_field34;
+ scene->_field3EF4->_object1.postInit();
+ scene->_field3EF4->_object1.hide();
+ scene->_field3EF4->_object1.setVisage(1332);
+ scene->_field3EF4->_object1.setPosition(scene->_field3EF4->_field36, 0);
+ scene->_field3EF4->_object1.fixPriority(170);
+
+ scene->_field3EF0->_field34 = 0;
+ scene->_field3EF0->_object1.remove();
+
+ scene->_item2._object1.setPosition(scene->_field3EF0->_field36, 0);
+ scene->_item2._object1.show();
+
+ NpcMover *mover = new NpcMover();
+ scene->_item2._object1.addMover(mover, &scene->_field3EF4->_field36, this);
+ }
+ break;
+ case 1:
+ scene->_item2._object1.hide();
+ scene->setAnimationInfo(scene->_field3EF4);
+ scene->_aSound1.play(57);
+
+ if (scene->_field3EF0 == &scene->_item6) {
+ subD18B5(5, 1, 4);
+ scene->subC4CEC();
+ }
+
+ scene->subC20F9();
+ break;
+ default:
+ break;
+ }
+}
+
+void Scene1337::Action10::signal() {
+ Scene1337 *scene = (Scene1337 *)R2_GLOBALS._sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0: {
+ scene->_field3EF8->_object1.postInit();
+ scene->_field3EF8->_object1.hide();
+ scene->_field3EF8->_object1.setVisage(1332);
+ scene->_field3EF8->_object1.setPosition(scene->_field3EF8->_field36, 0);
+ scene->_field3EF8->_object1.fixPriority(170);
+ scene->_field3EF8->_field34 = scene->_field3EF0->_field34;
+
+ scene->_field3EF0->_field34 = 0;
+ scene->_field3EF0->_object1.remove();
+
+ if (scene->_field3EF0 == &scene->_item6) {
+ subD18B5(5, 1, 4);
+ scene->subC4CEC();
+ }
+
+ scene->_item2._object1.setPosition(scene->_field3EF0->_field36, 0);
+ scene->_item2._object1.show();
+ NpcMover *mover = new NpcMover();
+ scene->_item2._object1.addMover(mover, &scene->_field3EF8->_field36, this);
+ }
+ break;
+ case 1: {
+ scene->_item2._object1.hide();
+ scene->setAnimationInfo(scene->_field3EF8);
+ scene->_aSound1.play(57);
+
+ bool found = false;
+ int indexFound = -1;
+
+ switch (scene->_field4240) {
+ case 0:
+ for (indexFound = 0; indexFound < 3; indexFound++) {
+ if (scene->_arrunkObj1337[0]._arr1[indexFound]._field34 == 29) {
+ found = true;
+ break;
+ }
+ }
+ break;
+ case 1:
+ for (indexFound = 0; indexFound < 3; indexFound++) {
+ if (scene->_arrunkObj1337[1]._arr1[indexFound]._field34 == 29) {
+ found = true;
+ break;
+ }
+ }
+ break;
+ case 2:
+ for (indexFound = 0; indexFound < 3; indexFound++) {
+ if (scene->_arrunkObj1337[2]._arr1[indexFound]._field34 == 29) {
+ found = true;
+ break;
+ }
+ }
+ break;
+ case 3:
+ for (indexFound = 0; indexFound < 3; indexFound++) {
+ if (scene->_arrunkObj1337[3]._arr1[indexFound]._field34 == 29) {
+ found = true;
+ break;
+ }
+ }
+ break;
+ default:
+ break;
+ }
+
+ bool found2 = false;
+
+ if (found) {
+ switch (scene->_field4240) {
+ case 0:
+ scene->subC51A0(&scene->_arrunkObj1337[0]._arr1[indexFound], scene->_field3EF8);
+ found2 = true;
+ break;
+ case 1:
+ scene->subC51A0(&scene->_arrunkObj1337[1]._arr1[indexFound], scene->_field3EF8);
+ found2 = true;
+ break;
+ case 2:
+ scene->subC4CD2();
+ if (MessageDialog::show(USE_INTERCEPTOR, NO_MSG, YES_MSG) == 0)
+ scene->subC4CEC();
+ else {
+ scene->subC51A0(&scene->_arrunkObj1337[2]._arr1[indexFound], scene->_field3EF8);
+ found2 = true;
+ }
+ break;
+ case 3:
+ scene->subC51A0(&scene->_arrunkObj1337[3]._arr1[indexFound], scene->_field3EF8);
+ found2 = true;
+ break;
+ default:
+ break;
+ }
+ }
+
+ if (!found2)
+ break;
+
+ if (scene->_field4240 == 2) {
+ int j = 0;
+ for (int i = 0; i <= 7; i++) {
+ if (scene->_arrunkObj1337[2]._arr2[i]._field34 != 0)
+ ++j;
+ }
+
+ if (j <= 1) {
+ for (int i = 0; i <= 7; i++) {
+ if (scene->_arrunkObj1337[2]._arr2[i]._field34 != 0) {
+ scene->_field3EF4 = &scene->_arrunkObj1337[2]._arr2[i];
+ break;
+ }
+ }
+ } else {
+ scene->subC4CD2();
+
+ found2 = false;
+ while (!found2) {
+ scene->actionDisplay(1330, 130, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+
+ // Wait for a mouse or keypress
+ Event event;
+ while (!g_globals->_events.getEvent(event, EVENT_BUTTON_DOWN | EVENT_KEYPRESS) && !g_vm->shouldQuit()) {
+ g_globals->_scenePalette.signalListeners();
+ R2_GLOBALS._sceneObjects->draw();
+ g_globals->_events.delay(g_globals->_sceneHandler->_delayTicks);
+ }
+
+ scene->_item6._field36 = event.mousePos;
+
+ for (int i = 0; i <= 7; i++) {
+ if ((scene->subC2BF8(&scene->_arrunkObj1337[2]._arr2[i], scene->_item6._field36) != 0) && (scene->_arrunkObj1337[2]._arr2[i]._field34 != 0)) {
+ scene->_field3EF4 = &scene->_arrunkObj1337[2]._arr2[0];
+ found2 = true;
+ break;
+ }
+ }
+ }
+ scene->subC4CEC();
+ }
+ }
+
+ scene->_field3E28[scene->_field3E26] = scene->_field3EF4->_field34;
+ scene->_field3E26--;
+ scene->_field3EF4->_field34 = 0;
+ scene->_field3EF4->_object1.remove();
+
+ scene->_item2._object1.setPosition(scene->_field3EF4->_field36, 0);
+ scene->_item2._object1.show();
+
+ NpcMover *mover = new NpcMover();
+ scene->_item2._object1.addMover(mover, &scene->_field3EF8->_field36, this);
+ }
+ break;
+ case 2:
+ scene->_item2._object1.hide();
+ scene->subC4A39(scene->_field3EF8);
+ break;
+ default:
+ break;
+ }
+}
+
+void Scene1337::Action11::signal() {
+ Scene1337 *scene = (Scene1337 *)R2_GLOBALS._sceneManager._scene;
+
+ bool noAction = true;
+
+ switch (_actionIndex++) {
+ case 0: {
+ scene->_field3EF4->_object1.postInit();
+ scene->_field3EF4->_object1.hide();
+ scene->_field3EF4->_object1.setVisage(1332);
+ scene->_field3EF4->_object1.setPosition(scene->_field3EF4->_field36, 0);
+ scene->_field3EF4->_object1.fixPriority(170);
+ scene->_field3EF4->_field34 = 25;
+
+ if (scene->_field4240 == 2) {
+ scene->_item2._object1.setPosition(scene->_field3EF4->_field36, 0);
+ subD18B5(5, 1, 4);
+ } else {
+ scene->_field3EF0->_field34 = 0;
+ scene->_field3EF0->_object1.remove();
+ scene->_item2._object1.setPosition(scene->_field3EF0->_field36, 0);
+ }
+ scene->_item2._object1.show();
+
+ NpcMover *mover = new NpcMover();
+ scene->_item2._object1.addMover(mover, &scene->_field3EF4->_field36, this);
+ }
+ break;
+ case 1: {
+ scene->_item2._object1.hide();
+ scene->setAnimationInfo(scene->_field3EF4);
+ scene->_aSound1.play(57);
+
+ bool found = false;
+ int i = -1;
+
+ switch (scene->_field4242) {
+ case 0:
+ for (i = 0; i <= 3; i++) {
+ if (scene->_arrunkObj1337[0]._arr1[i]._field34 == 27) {
+ found = true;
+ break;
+ }
+ }
+
+ if ((found) && (scene->subC3E92(scene->_field4240) != -1)) {
+ scene->_field3EF0 = &scene->_arrunkObj1337[0]._arr1[i];
+ scene->_field3EF4 = &scene->_arrunkObj1337[0]._arr4[0];
+ if (scene->_field4240 != 0) {
+ int tmpVal = scene->subC3E92(scene->_field4240);
+ scene->_field3EF8 = &scene->_arrunkObj1337[scene->_field4240]._arr1[tmpVal];
+ }
+ scene->_item1.setAction(&scene->_action12);
+ noAction = false;
+ }
+ break;
+ case 1:
+ for (i = 0; i <= 3; i++) {
+ if (scene->_arrunkObj1337[1]._arr1[i]._field34 == 27) {
+ found = true;
+ break;
+ }
+ }
+
+ if ((found) && (scene->subC3E92(scene->_field4240) != -1)) {
+ scene->_field3EF0 = &scene->_arrunkObj1337[1]._arr1[i];
+ scene->_field3EF4 = &scene->_arrunkObj1337[1]._arr4[0];
+ if (scene->_field4240 != 1) {
+ int tmpVal = scene->subC3E92(scene->_field4240);
+ scene->_field3EF8 = &scene->_arrunkObj1337[scene->_field4240]._arr1[tmpVal];
+ }
+ scene->_item1.setAction(&scene->_action12);
+ noAction = false;
+ }
+ break;
+ case 2:
+ for (i = 0; i <= 3; i++) {
+ if (scene->_arrunkObj1337[2]._arr1[i]._field34 == 27) {
+ found = true;
+ break;
+ }
+ }
+
+ if ((found) && (scene->subC3E92(scene->_field4240) != -1)) {
+ scene->subC4CD2();
+ if (MessageDialog::show(USE_DOUBLE_AGENT, NO_MSG, YES_MSG) == 0)
+ scene->subC4CEC();
+ else {
+ scene->subC4CEC();
+ scene->_field3EF0 = &scene->_arrunkObj1337[2]._arr1[i];
+ scene->_field3EF4 = &scene->_arrunkObj1337[2]._arr4[0];
+ if (scene->_field4240 != 2) {
+ int tmpVal = scene->subC3E92(scene->_field4240);
+ scene->_field3EF8 = &scene->_arrunkObj1337[scene->_field4240]._arr1[tmpVal];
+ }
+ scene->_item1.setAction(&scene->_action12);
+ noAction = false;
+ }
+ }
+ break;
+ case 3:
+ for (i = 0; i <= 3; i++) {
+ if (scene->_arrunkObj1337[3]._arr1[i]._field34 == 27) {
+ found = true;
+ break;
+ }
+ }
+
+ if ((found) && (scene->subC3E92(scene->_field4240) != -1)) {
+ scene->_field3EF0 = &scene->_arrunkObj1337[3]._arr1[i];
+ scene->_field3EF4 = &scene->_arrunkObj1337[3]._arr4[0];
+ if (scene->_field4240 != 3) {
+ int tmpVal = scene->subC3E92(scene->_field4240);
+ scene->_field3EF8 = &scene->_arrunkObj1337[scene->_field4240]._arr1[tmpVal];
+ }
+ scene->_item1.setAction(&scene->_action12);
+ noAction = false;
+ }
+ break;
+ default:
+ break;
+ }
+
+ if (!noAction)
+ return;
+
+ if (scene->_field4240 == 2) {
+ int count = 0;
+ if (scene->_field4242 != 2) {
+ for (i = 0; i <= 3; i++) {
+ if (scene->_arrunkObj1337[scene->_field4242]._arr1[i]._field34 == 0)
+ ++count;
+ }
+ }
+
+ if (count > 1) {
+ scene->subC4CD2();
+
+ found = false;
+ while (!found) {
+ switch (scene->_field4242) {
+ case 0:
+ scene->actionDisplay(1330, 131, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ break;
+ case 1:
+ scene->actionDisplay(1330, 132, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ break;
+ case 3:
+ scene->actionDisplay(1330, 133, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ break;
+ default:
+ break;
+ }
+
+ Event event;
+ while (!g_globals->_events.getEvent(event, EVENT_BUTTON_DOWN | EVENT_KEYPRESS) && !g_vm->shouldQuit()) {
+ g_globals->_scenePalette.signalListeners();
+ R2_GLOBALS._sceneObjects->draw();
+ g_globals->_events.delay(g_globals->_sceneHandler->_delayTicks);
+ }
+
+ scene->_item6._field36 = event.mousePos;
+
+ found = false;
+
+ if (scene->_field4242 != 2) {
+ for (i = 0; i <= 3; i++) {
+ if ((scene->subC2BF8(&scene->_arrunkObj1337[scene->_field4242]._arr1[i], scene->_item6._field36) != 0) && (scene->_arrunkObj1337[scene->_field4242]._arr1[i]._field34 != 0)) {
+ scene->_field3EF8 = &scene->_arrunkObj1337[scene->_field4242]._arr1[i];
+ found = true;
+ break;
+ }
+ }
+ }
+ } // while
+ scene->_field4246 = 1;
+ scene->subC4CEC();
+ } else {
+ if (scene->_field4242 != 2) {
+ int tmpVal = scene->subC3E92(scene->_field4242);
+ scene->_field3EF8 = &scene->_arrunkObj1337[scene->_field4242]._arr1[tmpVal];
+ }
+ }
+ }
+
+ scene->_field3EF0->_object1.postInit();
+ scene->_field3EF0->_object1.hide();
+ scene->_field3EF0->_object1.setVisage(1332);
+ scene->_field3EF0->_object1.setPosition(scene->_field3EF0->_field36, 0);
+ scene->_field3EF0->_object1.fixPriority(170);
+ scene->_field3EF0->_object1.setStrip2(1);
+ scene->_field3EF0->_field34 = scene->_field3EF8->_field34;
+
+ scene->_field3EF8->_field34 = 0;
+ scene->_field3EF8->_object1.remove();
+
+ scene->_item2._object1.setPosition(scene->_field3EF8->_field36, 0);
+ scene->_item2._object1.show();
+
+ NpcMover *mover = new NpcMover();
+ scene->_item2._object1.addMover(mover, &scene->_field3EF0->_field36, this);
+ }
+ break;
+ case 2:
+ scene->_item2._object1.hide();
+ switch (scene->_field4240) {
+ case 0:
+ scene->_field3EF0->_object1.setFrame(2);
+ scene->_field3EF0->_object1.show();
+ scene->_field423E--;
+ scene->_field4244 = 0;
+ break;
+ case 1:
+ scene->_field3EF0->_object1.setFrame(4);
+ scene->_field3EF0->_object1.show();
+ scene->_field423E--;
+ scene->_field4244 = 0;
+ break;
+ case 3:
+ scene->_field3EF0->_object1.setFrame(3);
+ scene->_field3EF0->_object1.show();
+ scene->_field423E--;
+ scene->_field4244 = 0;
+ break;
+ default:
+ scene->setAnimationInfo(scene->_field3EF0);
+ break;
+ }
+
+ scene->subC4A39(scene->_field3EF4);
+ break;
+ default:
+ break;
+ }
+}
+
+void Scene1337::Action12::signal() {
+ Scene1337 *scene = (Scene1337 *)R2_GLOBALS._sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0:
+ signal();
+ break;
+ case 1: {
+ scene->_field3E28[scene->_field3E26] = scene->_field3EF4->_field34;
+ scene->_field3EF4->_field34 = scene->_field3EF0->_field34;
+ scene->_field3EF0->_field34 = 0;
+ scene->_field3EF0->_object1.remove();
+ scene->_item2._object1.setPosition(scene->_field3EF0->_field36, 0);
+ scene->_item2._object1.show();
+
+ NpcMover *mover = new NpcMover();
+ scene->_item2._object1.addMover(mover, &scene->_field3EF4->_field36, this);
+ }
+ break;
+ case 2:
+ scene->_item2._object1.hide();
+ scene->setAnimationInfo(scene->_field3EF4);
+ scene->_aSound1.play(58);
+ if (scene->_field4242 == 2) {
+ int count = 0;
+ int i = -1;
+ switch (scene->_field4240) {
+ case 0:
+ for (i = 0; i <= 3; i++) {
+ if (scene->_arrunkObj1337[0]._arr1[i]._field34 != 0)
+ ++count;
+ }
+ break;
+ case 1:
+ for (i = 0; i <= 3; i++) {
+ if (scene->_arrunkObj1337[3]._arr1[i]._field34 != 0)
+ ++count;
+ }
+ break;
+ case 3:
+ for (i = 0; i <= 3; i++) {
+ if (scene->_arrunkObj1337[3]._arr1[i]._field34 != 0)
+ ++count;
+ }
+ break;
+ default:
+ break;
+ }
+
+ if (count > 1) {
+ scene->subC4CD2();
+
+ bool found = false;
+
+ while (!found) {
+ switch (scene->_field4240) {
+ case 0:
+ scene->actionDisplay(1330, 131, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ break;
+ case 1:
+ scene->actionDisplay(1330, 132, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ break;
+ case 3:
+ scene->actionDisplay(1330, 133, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ break;
+ default:
+ break;
+ }
+
+ Event event;
+ while (!g_globals->_events.getEvent(event, EVENT_BUTTON_DOWN | EVENT_KEYPRESS) && !g_vm->shouldQuit()) {
+ g_globals->_scenePalette.signalListeners();
+ R2_GLOBALS._sceneObjects->draw();
+ g_globals->_events.delay(g_globals->_sceneHandler->_delayTicks);
+ }
+
+ scene->_item6._field36 = event.mousePos;
+
+ if (scene->_field4240 == 0) {
+ for (i = 0; i <= 3; i++) {
+ if ((scene->subC2BF8(&scene->_arrunkObj1337[0]._arr1[i], scene->_item6._field36) != 0) && (scene->_arrunkObj1337[0]._arr1[i]._field34 != 0)) {
+ found = true;
+ scene->_field3EF8 = &scene->_arrunkObj1337[0]._arr1[i];
+ break;
+ }
+ }
+ }
+
+ if (scene->_field4240 == 3) {
+ for (i = 0; i <= 3; i++) {
+ if ((scene->subC2BF8(&scene->_arrunkObj1337[3]._arr1[i], scene->_item6._field36) != 0) && (scene->_arrunkObj1337[3]._arr1[i]._field34 != 0)) {
+ found = true;
+ scene->_field3EF8 = &scene->_arrunkObj1337[3]._arr1[i];
+ break;
+ }
+ }
+ }
+
+ if (scene->_field4240 == 1) {
+ for (i = 0; i <= 3; i++) {
+ if ((scene->subC2BF8(&scene->_arrunkObj1337[1]._arr1[i], scene->_item6._field36) != 0) && (scene->_arrunkObj1337[1]._arr1[i]._field34 != 0)) {
+ found = true;
+ scene->_field3EF8 = &scene->_arrunkObj1337[1]._arr1[i];
+ break;
+ }
+ }
+ }
+ }
+ scene->subC4CEC();
+ } else {
+ if (scene->_field4240 != 1) {
+ switch (scene->_field4240) {
+ case 0:
+ scene->_field3EF8 = &scene->_arrunkObj1337[0]._arr1[scene->subC3E92(0)];
+ break;
+ case 3:
+ scene->_field3EF8 = &scene->_arrunkObj1337[3]._arr1[scene->subC3E92(3)];
+ break;
+ default:
+ break;
+ }
+ } else {
+ scene->_field3EF8 = &scene->_arrunkObj1337[1]._arr1[scene->subC3E92(1)];
+ }
+ }
+
+ scene->_field3EF0->_object1.postInit();
+ scene->_field3EF0->_object1.hide();
+ scene->_field3EF0->_object1.setVisage(1332);
+ scene->_field3EF0->_object1.setPosition(scene->_field3EF0->_field36);
+ scene->_field3EF0->_object1.fixPriority(170);
+ scene->_field3EF0->_object1.setStrip2(1);
+ scene->_field3EF0->_field34 = scene->_field3EF8->_field34;
+
+ scene->_field3EF8->_field34 = 0;
+ scene->_field3EF8->_object1.remove();
+
+ scene->_item2._object1.setPosition(scene->_field3EF8->_field36);
+ scene->_item2._object1.show();
+ scene->_aSound1.play(57);
+
+ NpcMover *mover = new NpcMover();
+ scene->_item2._object1.addMover(mover, &scene->_field3EF0->_field36, this);
+ }
+ break;
+ case 3:
+ scene->_item2._object1.hide();
+ switch (scene->_field4242) {
+ case 0:
+ scene->_field3EF0->_object1.setFrame2(2);
+ scene->_field3EF0->_object1.show();
+ break;
+ case 1:
+ scene->_field3EF0->_object1.setFrame2(4);
+ scene->_field3EF0->_object1.show();
+ break;
+ case 3:
+ scene->_field3EF0->_object1.setFrame2(3);
+ scene->_field3EF0->_object1.show();
+ break;
+ default:
+ scene->setAnimationInfo(scene->_field3EF0);
+ break;
+ }
+ scene->subC4A39(scene->_field3EF4);
+ break;
+ default:
+ break;
+ }
+}
+
+void Scene1337::Action13::signal() {
+ Scene1337 *scene = (Scene1337 *)R2_GLOBALS._sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0: {
+ scene->_field3E28[scene->_field3E26] = scene->_field3EF4->_field34;
+ scene->_field3E26--;
+
+ scene->_field3EF4->_field34 = scene->_field3EF0->_field34;
+
+ scene->_field3EF0->_field34 = 0;
+ scene->_field3EF0->_object1.remove();
+
+ scene->_item2._object1.setPosition(scene->_field3EF0->_field36, 0);
+ scene->_item2._object1.show();
+
+ NpcMover *mover = new NpcMover();
+ scene->_item2._object1.addMover(mover, &scene->_field3EF4->_field36, this);
+ }
+ break;
+ case 1:
+ scene->_item2._object1.hide();
+ scene->setAnimationInfo(scene->_field3EF4);
+ scene->_aSound1.play(58);
+ signal();
+ break;
+ case 2:
+ scene->subC4A39(scene->_field3EF4);
+ break;
+ default:
+ break;
+ }
+}
+
+void Scene1337::postInit(SceneObjectList *OwnerList) {
+// In the original, may be found in subPostInit.
+// Without it, enableControl asserts
+ loadScene(1330);
+ SceneExt::postInit();
+//
+
+ // Hide the user interface
+ R2_GLOBALS._uiElements._active = false;
+ BF_GLOBALS._interfaceY = 200;
+
+ R2_GLOBALS._player.enableControl();
+ R2_GLOBALS._player._canWalk = false;
+
+ _unkFctPtr412 = NULL;
+
+ _field3EF0 = NULL;
+ _field3EF4 = NULL;
+ _field3EF8 = NULL;
+
+ _arrunkObj1337[2]._arr1[0]._field36 = Common::Point(10, 174);
+ _arrunkObj1337[2]._arr1[1]._field36 = Common::Point(37, 174);
+ _arrunkObj1337[2]._arr1[2]._field36 = Common::Point(64, 174);
+ _arrunkObj1337[2]._arr1[3]._field36 = Common::Point(91, 174);
+
+ _arrunkObj1337[2]._arr2[0]._field36 = Common::Point(119, 174);
+ _arrunkObj1337[2]._arr2[1]._field36 = Common::Point(119, 148);
+ _arrunkObj1337[2]._arr2[2]._field36 = Common::Point(119, 122);
+ _arrunkObj1337[2]._arr2[3]._field36 = Common::Point(145, 122);
+ _arrunkObj1337[2]._arr2[4]._field36 = Common::Point(171, 122);
+ _arrunkObj1337[2]._arr2[5]._field36 = Common::Point(171, 148);
+ _arrunkObj1337[2]._arr2[6]._field36 = Common::Point(171, 174);
+ _arrunkObj1337[2]._arr2[7]._field36 = Common::Point(145, 174);
+
+ _arrunkObj1337[2]._arr3[0]._field36 = Common::Point(199, 174);
+
+ _arrunkObj1337[2]._arr4[0]._field36 = Common::Point(145, 148);
+
+ _arrunkObj1337[2]._fieldB94 = Common::Point(10, 174);
+ _arrunkObj1337[2]._fieldB98 = Common::Point(37, 174);
+ _arrunkObj1337[2]._fieldB9C = Common::Point(64, 174);
+ _arrunkObj1337[2]._fieldBA0 = Common::Point(91, 174);
+ _arrunkObj1337[2]._fieldBA4 = 2;
+
+ _arrunkObj1337[3]._arr1[0]._field36 = Common::Point(14, 14);
+ _arrunkObj1337[3]._arr1[1]._field36 = Common::Point(14, 36);
+ _arrunkObj1337[3]._arr1[2]._field36 = Common::Point(14, 58);
+ _arrunkObj1337[3]._arr1[3]._field36 = Common::Point(14, 80);
+
+ _arrunkObj1337[3]._arr2[0]._field36 = Common::Point(37, 66);
+ _arrunkObj1337[3]._arr2[1]._field36 = Common::Point(63, 66);
+ _arrunkObj1337[3]._arr2[2]._field36 = Common::Point(89, 66);
+ _arrunkObj1337[3]._arr2[3]._field36 = Common::Point(89, 92);
+ _arrunkObj1337[3]._arr2[4]._field36 = Common::Point(89, 118);
+ _arrunkObj1337[3]._arr2[5]._field36 = Common::Point(63, 118);
+ _arrunkObj1337[3]._arr2[6]._field36 = Common::Point(37, 118);
+ _arrunkObj1337[3]._arr2[7]._field36 = Common::Point(37, 92);
+
+ _arrunkObj1337[3]._arr3[0]._field36 = Common::Point(37, 145);
+
+ _arrunkObj1337[3]._arr4[0]._field36 = Common::Point(63, 92);
+
+ _arrunkObj1337[3]._fieldB94 = Common::Point(14, 14);
+ _arrunkObj1337[3]._fieldB98 = Common::Point(14, 36);
+ _arrunkObj1337[3]._fieldB9C = Common::Point(14, 58);
+ _arrunkObj1337[3]._fieldBA0 = Common::Point(14, 80);
+ _arrunkObj1337[3]._fieldBA4 = 3;
+
+ _arrunkObj1337[0]._arr1[0]._field36 = Common::Point(280, 5);
+ _arrunkObj1337[0]._arr1[1]._field36 = Common::Point(253, 5);
+ _arrunkObj1337[0]._arr1[2]._field36 = Common::Point(226, 5);
+ _arrunkObj1337[0]._arr1[3]._field36 = Common::Point(199, 5);
+
+ _arrunkObj1337[0]._arr2[0]._field36 = Common::Point(171, 16);
+ _arrunkObj1337[0]._arr2[1]._field36 = Common::Point(171, 42);
+ _arrunkObj1337[0]._arr2[2]._field36 = Common::Point(171, 68);
+ _arrunkObj1337[0]._arr2[3]._field36 = Common::Point(145, 68);
+ _arrunkObj1337[0]._arr2[4]._field36 = Common::Point(119, 68);
+ _arrunkObj1337[0]._arr2[5]._field36 = Common::Point(119, 42);
+ _arrunkObj1337[0]._arr2[6]._field36 = Common::Point(119, 16);
+ _arrunkObj1337[0]._arr2[7]._field36 = Common::Point(145, 16);
+
+ _arrunkObj1337[0]._arr3[0]._field36 = Common::Point(91, 16);
+
+ _arrunkObj1337[0]._arr4[0]._field36 = Common::Point(145, 42);
+
+ _arrunkObj1337[0]._fieldB94 = Common::Point(280, 5);
+ _arrunkObj1337[0]._fieldB98 = Common::Point(253, 5);
+ _arrunkObj1337[0]._fieldB9C = Common::Point(226, 5);
+ _arrunkObj1337[0]._fieldBA0 = Common::Point(199, 5);
+ _arrunkObj1337[0]._fieldBA4 = 2;
+
+ _arrunkObj1337[1]._arr1[0]._field36 = Common::Point(283, 146);
+ _arrunkObj1337[1]._arr1[1]._field36 = Common::Point(283, 124);
+ _arrunkObj1337[1]._arr1[2]._field36 = Common::Point(283, 102);
+ _arrunkObj1337[1]._arr1[3]._field36 = Common::Point(283, 80);
+
+ _arrunkObj1337[1]._arr2[0]._field36 = Common::Point(253, 122);
+ _arrunkObj1337[1]._arr2[1]._field36 = Common::Point(227, 122);
+ _arrunkObj1337[1]._arr2[2]._field36 = Common::Point(201, 122);
+ _arrunkObj1337[1]._arr2[3]._field36 = Common::Point(201, 96);
+ _arrunkObj1337[1]._arr2[4]._field36 = Common::Point(201, 70);
+ _arrunkObj1337[1]._arr2[5]._field36 = Common::Point(227, 70);
+ _arrunkObj1337[1]._arr2[6]._field36 = Common::Point(253, 70);
+ _arrunkObj1337[1]._arr2[7]._field36 = Common::Point(253, 96);
+
+ _arrunkObj1337[1]._arr3[0]._field36 = Common::Point(253, 43);
+
+ _arrunkObj1337[1]._arr4[0]._field36 = Common::Point(227, 96);
+
+ _arrunkObj1337[1]._fieldB94 = Common::Point(283, 146);
+ _arrunkObj1337[1]._fieldB98 = Common::Point(283, 124);
+ _arrunkObj1337[1]._fieldB9C = Common::Point(283, 102);
+ _arrunkObj1337[1]._fieldBA0 = Common::Point(283, 80);
+ _arrunkObj1337[1]._fieldBA4 = 4;
+
+ subPostInit();
+}
+
+void Scene1337::remove() {
+ if (R2_GLOBALS._v57709 > 1) {
+ subD1917();
+ subD1940(false);
+ }
+
+ R2_GLOBALS._uiElements._active = true;
+ SceneExt::remove();
+}
+
+void Scene1337::process(Event &event) {
+ if (event.eventType == EVENT_BUTTON_DOWN) {
+ if (event.btnState != BTNSHIFT_RIGHT) {
+ subD183F(R2_GLOBALS._v5780E, 1);
+ event.handled = true;
+ } else if (_unkFctPtr412) {
+ FunctionPtrType tmpFctPtr = _unkFctPtr412;
+ _unkFctPtr412 = NULL;
+ (this->*tmpFctPtr)();
+ event.handled = true;
+ }
+ } else if (event.eventType == EVENT_KEYPRESS) {
+ if (event.kbd.keycode == Common::KEYCODE_SPACE) {
+ if (_unkFctPtr412) {
+ FunctionPtrType tmpFctPtr = _unkFctPtr412;
+ _unkFctPtr412 = NULL;
+ (this->*tmpFctPtr)();
+ event.handled = true;
+ }
+ } else
+ warning("Fixme: Find proper keycode value");
+ }
+
+ if (!event.handled)
+ Scene::process(event);
+}
+
+void Scene1337::dispatch() {
+ if (_field424C == 0) {
+ ++_field424E;
+ if (_field424E == 4) {
+ _field424C = 1;
+ suggestInstructions();
+ }
+ }
+ Scene::dispatch();
+}
+
+void Scene1337::actionDisplay(int resNum, int lineNum, int x, int y, int arg5, int width, int textMode, int fontNum, int colFG, int colBGExt, int colFGExt) {
+ // TODO: Check if it's normal that arg5 is unused and replaced by an hardcoded 0 value
+ // May hide an original bug
+
+ SceneItem::display(resNum, lineNum, SET_X, x, SET_Y, y, SET_KEEP_ONSCREEN, 0, SET_WIDTH, width, SET_POS_MODE, -1, SET_TEXT_MODE, textMode, SET_FONT, fontNum, SET_FG_COLOR, colFG, SET_EXT_BGCOLOR, colBGExt, SET_EXT_FGCOLOR, colFGExt, LIST_END);
+}
+
+void Scene1337::setAnimationInfo(unkObj1337sub1 *subObj) {
+ if (!subObj)
+ return;
+
+ if (subObj->_field34 > 9) {
+ if (subObj->_field34 > 25) {
+ subObj->_object1.setStrip2(4);
+ subObj->_object1.setFrame(subObj->_field34 - 25);
+ } else {
+ subObj->_object1.setStrip2(3);
+ subObj->_object1.setFrame(subObj->_field34 - 9);
+ }
+ } else {
+ subObj->_object1.setStrip2(2);
+ subObj->_object1.setFrame(subObj->_field34);
+ }
+
+ subObj->_object1.show();
+ R2_GLOBALS._sceneObjects->draw();
+}
+
+void Scene1337::subC20E5() {
+ subC2586();
+}
+
+void Scene1337::subC20F9() {
+ switch (_field424A) {
+ case -1:
+ ++_field423E;
+ if (_field423E == 3)
+ _field423E = 0;
+
+ if (_field4244 == 1) {
+ _object1.show();
+ switch (_field423E) {
+ case 0:
+ _object1.setStrip(3);
+ break;
+ case 1:
+ _object1.setStrip(4);
+ break;
+ case 2:
+ subD1975(174, 107);
+ _object1.setStrip(1);
+ break;
+ case 3:
+ subC4CEC();
+ _object1.setStrip(2);
+ break;
+ default:
+ break;
+ }
+
+ if (!_autoplay)
+ _unkFctPtr412 = &Scene1337::subC20E5;
+ else
+ subC20E5();
+ } else {
+ subC20E5();
+ }
+ break;
+ case 0:
+ _aSound2.play(62);
+ actionDisplay(1330, 135, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ actionDisplay(1330, 121, 20, 99, 1, 136, 0, 7, 0, 172, 172);
+ actionDisplay(1330, 122, 300, 99, 1, 136, 0, 7, 0, 117, 117);
+ R2_GLOBALS._sceneObjects->draw();
+ actionDisplay(1330, 123, 159, 134, 1, 200, 0, 7, 0, 105, 105);
+ break;
+ case 1:
+ _aSound2.play(62);
+ actionDisplay(1330, 151, 300, 99, 1, 136, 0, 7, 0, 117, 117);
+ actionDisplay(1330, 118, 20, 99, 1, 136, 0, 7, 0, 172, 172);
+ actionDisplay(1330, 119, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ R2_GLOBALS._sceneObjects->draw();
+ actionDisplay(1330, 120, 159, 134, 1, 200, 0, 7, 0, 105, 105);
+ break;
+ case 2:
+ _aSound2.play(62);
+ actionDisplay(1330, 134, 159, 134, 1, 200, 0, 7, 0, 105, 105);
+ actionDisplay(1330, 124, 20, 99, 1, 136, 0, 7, 0, 172, 172);
+ actionDisplay(1330, 126, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ R2_GLOBALS._sceneObjects->draw();
+ actionDisplay(1330, 125, 300, 99, 1, 136, 0, 7, 0, 117, 117);
+ break;
+ case 3:
+ _aSound2.play(62);
+ actionDisplay(1330, 150, 20, 99, 1, 136, 0, 7, 0, 172, 172);
+ actionDisplay(1330, 115, 300, 99, 1, 136, 0, 7, 0, 117, 117);
+ actionDisplay(1330, 116, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ R2_GLOBALS._sceneObjects->draw();
+ actionDisplay(1330, 117, 159, 134, 1, 200, 0, 7, 0, 105, 105);
+ break;
+ default:
+ break;
+ }
+
+ if (_field424A != -1)
+ R2_GLOBALS._sceneManager.changeScene(125);
+
+}
+
+void Scene1337::subC2586() {
+ if (_field4244 != 0)
+ _object1.hide();
+
+ switch (_field423E) {
+ case 2:
+ subC4CD2();
+ if (_field4246 == 1)
+ actionDisplay(1330, 114, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ _field4246 = 0;
+ // No break on purpose
+ case 0:
+ // No break on purpose
+ case 1:
+ // No break on purpose
+ case 3:
+ _item1.setAction(&_action4);
+ default:
+ break;
+ }
+
+ _field4244 = 1;
+
+}
+
+bool Scene1337::subC264B(int arg1) {
+ switch (arg1) {
+ case 10:
+ // No break on purpose
+ case 12:
+ // No break on purpose
+ case 15:
+ // No break on purpose
+ case 17:
+ // No break on purpose
+ case 18:
+ // No break on purpose
+ case 19:
+ // No break on purpose
+ case 20:
+ // No break on purpose
+ case 21:
+ return true;
+ default:
+ return false;
+ }
+}
+
+bool Scene1337::subC2687(int arg1) {
+ switch (arg1) {
+ case 11:
+ // No break on purpose
+ case 14:
+ // No break on purpose
+ case 16:
+ // No break on purpose
+ case 24:
+ return true;
+ default:
+ return false;
+ }
+}
+
+int Scene1337::subC26CB(int arg1, int arg2) {
+ if ((_arrunkObj1337[arg1]._arr1[arg2]._field34 > 1) && (_arrunkObj1337[arg1]._arr1[arg2]._field34 <= 9)) {
+ return arg2;
+ }
+
+ return -1;
+}
+
+int Scene1337::subC2719(int arg1) {
+ for (int i = 0; i <= 3; i++) {
+ if (_arrunkObj1337[arg1]._arr1[i]._field34 == 1)
+ return i;
+ }
+
+ return -1;
+}
+
+int Scene1337::subC274D(int arg1) {
+ for (int i = 0; i <= 3; i++) {
+ if (_arrunkObj1337[arg1]._arr1[i]._field34 == 13)
+ return i;
+ }
+
+ return -1;
+}
+
+int Scene1337::subC2781(int arg1) {
+ for (int i = 0; i <= 3; i++) {
+ if (_arrunkObj1337[arg1]._arr1[i]._field34 == 25)
+ return i;
+ }
+
+ return -1;
+}
+
+int Scene1337::subC27B5(int arg1) {
+ switch (arg1) {
+ case 11:
+ // No break on purpose
+ case 14:
+ // No break on purpose
+ case 16:
+ // No break on purpose
+ case 24:
+ return arg1;
+ break;
+ default:
+ return -1;
+ break;
+ }
+}
+
+int Scene1337::subC27F9(int arg1) {
+ switch (arg1) {
+ case 10:
+ // No break on purpose
+ case 12:
+ // No break on purpose
+ case 15:
+ // No break on purpose
+ case 17:
+ // No break on purpose
+ case 18:
+ // No break on purpose
+ case 19:
+ // No break on purpose
+ case 20:
+ // No break on purpose
+ case 21:
+ return arg1;
+ default:
+ return -1;
+ }
+}
+
+void Scene1337::subC2835(int arg1) {
+ int i;
+ bool found = false;
+ switch (arg1) {
+ case 0:
+ for (i = 0; i <= 3; i++) {
+ if (subC27F9(_arrunkObj1337[arg1]._arr1[i]._field34) != -1) {
+ found = true;
+ break;
+ }
+ }
+
+ if (found)
+ break;
+
+ for (i = 0; i <= 3; i++) {
+ if (subC27B5(_arrunkObj1337[arg1]._arr1[i]._field34) != -1) {
+ found = true;
+ break;
+ }
+ }
+
+ if (found)
+ break;
+
+ for (i = 0; i <= 3; i++) {
+ if ((_arrunkObj1337[arg1]._arr1[i]._field34 > 1) && (_arrunkObj1337[arg1]._arr1[i]._field34 <= 9)) {
+ found = true;
+ break;
+ }
+ }
+
+ if (found)
+ break;
+
+ for (i = 0; i <= 3; i++) {
+ if ((_arrunkObj1337[arg1]._arr1[i]._field34 >= 26) && (_arrunkObj1337[arg1]._arr1[i]._field34 <= 33)) {
+ found = true;
+ break;
+ }
+ }
+
+ if (found)
+ break;
+
+ for (i = 0; i <= 3; i++) {
+ if (_arrunkObj1337[arg1]._arr1[i]._field34 == 1) {
+ found = true;
+ break;
+ }
+ }
+
+ if (found)
+ break;
+
+ for (i = 0; i <= 3; i++) {
+ if (_arrunkObj1337[arg1]._arr1[i]._field34 == 25) {
+ found = true;
+ break;
+ }
+ }
+
+ if (found)
+ break;
+
+ for (i = 0; i <= 3; i++) {
+ if (_arrunkObj1337[arg1]._arr1[i]._field34 == 13) {
+ found = true;
+ break;
+ }
+ }
+ break;
+ case 1:
+ for (i = 0; i <= 3; i++) {
+ if ((_arrunkObj1337[arg1]._arr1[i]._field34 >= 26) && (_arrunkObj1337[arg1]._arr1[i]._field34 <= 33)) {
+ found = true;
+ break;
+ }
+ }
+
+ if (found)
+ break;
+
+ for (i = 0; i <= 3; i++) {
+ if (_arrunkObj1337[arg1]._arr1[i]._field34 == 1) {
+ found = true;
+ break;
+ }
+ }
+
+ if (found)
+ break;
+
+ for (i = 0; i <= 3; i++) {
+ if ((_arrunkObj1337[arg1]._arr1[i]._field34 > 1) && (_arrunkObj1337[arg1]._arr1[i]._field34 <= 9)) {
+ found = true;
+ break;
+ }
+ }
+
+ if (found)
+ break;
+
+ for (i = 0; i <= 3; i++) {
+ if (subC27F9(_arrunkObj1337[arg1]._arr1[i]._field34) != -1) {
+ found = true;
+ break;
+ }
+ }
+
+ if (found)
+ break;
+
+ for (i = 0; i <= 3; i++) {
+ if (subC27B5(_arrunkObj1337[arg1]._arr1[i]._field34) != -1) {
+ found = true;
+ break;
+ }
+ }
+
+ if (found)
+ break;
+
+ for (i = 0; i <= 3; i++) {
+ if (_arrunkObj1337[arg1]._arr1[i]._field34 == 25) {
+ found = true;
+ break;
+ }
+ }
+
+ if (found)
+ break;
+
+ for (i = 0; i <= 3; i++) {
+ if (_arrunkObj1337[arg1]._arr1[i]._field34 == 13) {
+ found = true;
+ break;
+ }
+ }
+
+ break;
+ default:
+ return;
+ }
+
+ subC4A39(&_arrunkObj1337[arg1]._arr1[i]);
+}
+
+bool Scene1337::subC2BF8(unkObj1337sub1 *subObj1, Common::Point pt) {
+ if ((subObj1->_field36.x > pt.x) || (subObj1->_field36.x + 24 < pt.x))
+ return false;
+
+ if ((subObj1->_field36.y > pt.y) || (subObj1->_field36.y + 24 < pt.y))
+ return false;
+
+ return true;
+}
+
+void Scene1337::subC2C2F() {
+ bool found = true;
+
+ if (_arrunkObj1337[3]._arr3[0]._field34 != 0) {
+ switch (_arrunkObj1337[3]._arr3[0]._field34) {
+ case 10:
+ // No break on purpose
+ case 12:
+ // No break on purpose
+ case 15:
+ // No break on purpose
+ case 17:
+ // No break on purpose
+ case 18:
+ // No break on purpose
+ case 19:
+ // No break on purpose
+ case 20:
+ // No break on purpose
+ case 21:
+ subC4A39(&_arrunkObj1337[3]._arr3[0]);
+ found = false;
+ break;
+ default:
+ found = false;
+ int i;
+ for (i = 0; i <= 3; i++) {
+ if (subC3386(_arrunkObj1337[3]._arr3[0]._field34, _arrunkObj1337[3]._arr1[i]._field34)) {
+ found = true;
+ break;
+ }
+ }
+
+ if (found) {
+ found = false;
+ subC34A1(&_arrunkObj1337[3]._arr1[i], &_arrunkObj1337[3]._arr3[0]);
+ }
+ break;
+ }
+ }
+
+ if (!found)
+ return;
+
+ int randIndx = R2_GLOBALS._randomSource.getRandomNumber(3);
+
+ if (_arrunkObj1337[3]._arr1[randIndx]._field34 == 1) {
+ found = false;
+
+ for (int i = 0; i <= 7; i++) {
+ if ((_arrunkObj1337[3]._arr2[i]._field34 == 0) && (!subC2687(_arrunkObj1337[3]._arr3[0]._field34))) {
+ subC340B(&_arrunkObj1337[3]._arr1[randIndx], &_arrunkObj1337[3]._arr2[i]);
+ found = true;
+ break;
+ }
+ }
+
+ if (found) {
+ return;
+ }
+ } else if (_arrunkObj1337[3]._arr1[randIndx]._field34 <= 9) {
+ found = false;
+
+ for (int i = 0; i <= 7; i++) {
+ if (_arrunkObj1337[3]._arr2[i]._field34 == _arrunkObj1337[3]._arr1[randIndx]._field34) {
+ found = true;
+ break;
+ }
+ }
+
+ if (!found) {
+ for (int i = 0; i <= 7; i++) {
+ if ((_arrunkObj1337[3]._arr2[i]._field34 == 1) && (!subC2687(_arrunkObj1337[3]._arr3[i]._field34))) {
+ int tmpVal = 0;
+
+ for (int j = 0; j <= 7; j++) {
+ if ((_arrunkObj1337[3]._arr2[j]._field34 > 1) && (_arrunkObj1337[3]._arr2[j]._field34 <= 9))
+ ++tmpVal;
+ }
+
+ if (tmpVal == 7)
+ _field424A = 3;
+
+ subC33C0(&_arrunkObj1337[3]._arr1[randIndx], &_arrunkObj1337[3]._arr2[i]);
+ found = true;
+ break;
+ }
+ }
+ if (found)
+ return;
+ }
+ } else if (_arrunkObj1337[3]._arr1[randIndx]._field34 == 13) {
+ int tmpVal = subC331B(3);
+
+ if (tmpVal != -1) {
+ subC358E(&_arrunkObj1337[3]._arr1[randIndx], tmpVal);
+ return;
+ }
+ } else if (_arrunkObj1337[3]._arr1[randIndx]._field34 == 25) {
+ int tmpVal = -1;
+ found = false;
+ int tmpRandIndx = R2_GLOBALS._randomSource.getRandomNumber(3);
+
+ for (int i = 0; i <= 3; i++) {
+ if ( (tmpRandIndx != 3)
+ && ( (_arrunkObj1337[tmpRandIndx]._arr1[0]._field34 != 0)
+ || (_arrunkObj1337[tmpRandIndx]._arr1[1]._field34 != 0)
+ || (_arrunkObj1337[tmpRandIndx]._arr1[2]._field34 != 0)
+ || (_arrunkObj1337[tmpRandIndx]._arr1[3]._field34 != 0) )) {
+ tmpVal = tmpRandIndx;
+ break;
+ }
+
+ ++tmpRandIndx;
+ if (tmpRandIndx > 3)
+ tmpRandIndx = 0;
+ }
+
+ if (tmpVal != -1) {
+ subC318B(3, &_arrunkObj1337[3]._arr1[randIndx], tmpVal);
+ return;
+ }
+ } else {
+ switch (_arrunkObj1337[3]._arr1[randIndx]._field34) {
+ case 10:
+ // No break on purpose
+ case 11:
+ // No break on purpose
+ case 12:
+ // No break on purpose
+ case 14:
+ // No break on purpose
+ case 15:
+ // No break on purpose
+ case 16:
+ // No break on purpose
+ case 17:
+ // No break on purpose
+ case 18:
+ // No break on purpose
+ case 19:
+ // No break on purpose
+ case 20:
+ // No break on purpose
+ case 21:
+ // No break on purpose
+ case 24: {
+ int tmpVal = -1;
+ int tmpRandIndx = R2_GLOBALS._randomSource.getRandomNumber(3);
+
+ for (int i = 0; i <= 3; i++) {
+ if (tmpRandIndx != 3) {
+ // The variables 'i' and 'j' are not used in the inner code of the loop.
+ // It's understandable for 'i', which helps making sure that tmpVal is used properly,
+ // but it's suspect for j
+ for (int j = 0; j <= 7; j++) {
+ if ((_arrunkObj1337[tmpRandIndx]._arr3[0]._field34 == 0) && (subC32B1(tmpRandIndx, _arrunkObj1337[3]._arr1[randIndx]._field34))) {
+ tmpVal = j;
+ }
+ }
+ }
+
+ ++tmpRandIndx;
+ if (tmpRandIndx > 3)
+ tmpRandIndx = 0;
+
+ if (tmpVal != -1)
+ break;
+ }
+
+ if (tmpVal != -1) {
+ // Useless second identical check skipped
+ subC3456(&_arrunkObj1337[3]._arr1[randIndx], &_arrunkObj1337[tmpVal]._arr3[0]);
+ return;
+ }
+ }
+ default:
+ break;
+ }
+ }
+
+ subC4A39(&_arrunkObj1337[3]._arr1[randIndx]);
+}
+
+void Scene1337::subC318B(int arg1, unkObj1337sub1 *subObj1, int arg3) {
+ _field4240 = arg1;
+ _field4242 = arg3;
+
+ int randIndx;
+
+ for (;;) {
+ randIndx = R2_GLOBALS._randomSource.getRandomNumber(3);
+ if (_arrunkObj1337[arg3]._arr1[randIndx]._field34 != 0)
+ break;
+ }
+
+ _field3EF0 = subObj1;
+ _field3EF4 = &_arrunkObj1337[arg3]._arr4[0];
+ _field3EF8 = &_arrunkObj1337[arg3]._arr1[randIndx];
+
+ _item1.setAction(&_action11);
+}
+
+int Scene1337::subC3257(int arg1) {
+ int retVal;
+
+ switch (arg1) {
+ case 10:
+ retVal = 2;
+ break;
+ case 12:
+ retVal = 3;
+ break;
+ case 15:
+ retVal = 5;
+ break;
+ case 17:
+ retVal = 9;
+ break;
+ case 18:
+ retVal = 6;
+ break;
+ case 19:
+ retVal = 4;
+ break;
+ case 20:
+ retVal = 8;
+ break;
+ case 21:
+ retVal = 7;
+ break;
+ default:
+ retVal = -1;
+ }
+
+ return retVal;
+}
+
+bool Scene1337::subC32B1(int arg1, int arg2) {
+ for (int i = 0; i <= 7; i++) {
+ if (_arrunkObj1337[arg1]._arr2[i]._field34 != 0) {
+ int tmpVal = subC3257(arg2);
+ if (tmpVal == _arrunkObj1337[arg1]._arr2[i]._field34)
+ return false;
+ }
+ }
+ return true;
+}
+
+int Scene1337::subC331B(int arg1) {
+ int randIndx = R2_GLOBALS._randomSource.getRandomNumber(3);
+
+ for (int i = 0; i <= 3; i++) {
+ if (randIndx != arg1) {
+ for (int j = 0; j <= 7; j++) {
+ if (_arrunkObj1337[randIndx]._arr2[j]._field34 != 0)
+ return randIndx;
+ }
+ }
+
+ if (arg1 == 1) {
+ randIndx--;
+ if (randIndx < 0)
+ randIndx = 3;
+ } else {
+ ++randIndx;
+ if (randIndx > 3)
+ randIndx = 0;
+ }
+ }
+
+ return -1;
+}
+
+bool Scene1337::subC3386(int arg1, int arg2) {
+ if ((arg1 == 11) && (arg2 == 26))
+ return true;
+
+ if ((arg1 == 14) && (arg2 == 30))
+ return true;
+
+ if ((arg1 == 16) && (arg2 == 32))
+ return true;
+
+ if ((arg1 == 24) && (arg2 == 28))
+ return true;
+
+ return false;
+}
+
+void Scene1337::subC33C0(unkObj1337sub1 *subObj1, unkObj1337sub1 *subObj2) {
+ _field3EF4 = subObj2;
+ _field3EF0 = subObj1;
+ _item1.setAction(&_action7);
+}
+
+int Scene1337::subC3E92(int arg1) {
+ if ( (_arrunkObj1337[arg1]._arr1[0]._field34 == 0)
+ && (_arrunkObj1337[arg1]._arr1[1]._field34 == 0)
+ && (_arrunkObj1337[arg1]._arr1[2]._field34 == 0)
+ && (_arrunkObj1337[arg1]._arr1[3]._field34 == 0))
+ return -1;
+
+ int randIndx;
+ for (;;) {
+ randIndx = R2_GLOBALS._randomSource.getRandomNumber(3);
+ if (_arrunkObj1337[arg1]._arr1[randIndx]._field34 == 0)
+ break;
+ }
+
+ return randIndx;
+}
+
+void Scene1337::subC340B(unkObj1337sub1 *subObj1, unkObj1337sub1 *subObj2) {
+ _field3EF0 = subObj1;
+ _field3EF4 = subObj2;
+
+ _item1.setAction(&_action6);
+}
+
+void Scene1337::subC3456(unkObj1337sub1 *subObj1, unkObj1337sub1 *subObj2) {
+ _field3EF0 = subObj1;
+ _field3EF4 = subObj2;
+
+ _item1.setAction(&_action9);
+}
+
+void Scene1337::subC34A1(unkObj1337sub1 *subObj1, unkObj1337sub1 *subObj2) {
+ _field3EF0 = subObj1;
+ _field3EF4 = subObj2;
+
+ _item1.setAction(&_action8);
+}
+
+Scene1337::unkObj1337sub1 *Scene1337::subC34EC(int arg1) {
+ for (int i = 0; i <= 7; i++) {
+ if (_arrunkObj1337[arg1]._arr2[i]._field34 == 1) {
+ return &_arrunkObj1337[arg1]._arr2[i];
+ }
+ }
+
+ for (int i = 0; i <= 7; i++) {
+ if ((_arrunkObj1337[arg1]._arr2[i]._field34 != 0) && (_arrunkObj1337[arg1]._arr2[i]._field34 < 10)) {
+ return &_arrunkObj1337[arg1]._arr2[i];
+ }
+ }
+
+ return NULL;
+}
+
+void Scene1337::subC358E(unkObj1337sub1 *subObj1, int arg2) {
+ _field3EF0 = subObj1;
+ _field3EF4 = subC34EC(arg2);
+ _field3EF8 = &_arrunkObj1337[arg2]._arr4[0];
+ _field4240 = arg2;
+ _item1.setAction(&_action10);
+}
+
+void Scene1337::subC4A39(unkObj1337sub1 *subObj) {
+ _field3EF0 = subObj;
+
+ _item1.setAction(&_action5);
+}
+
+void Scene1337::subC4CD2() {
+ if (R2_GLOBALS._v57709 > 0) {
+ subD1917();
+ subD1940(false);
+ }
+}
+
+void Scene1337::subC4CEC() {
+ if (R2_GLOBALS._v57709 != 0)
+ return;
+
+ subD18F5();
+ subD1940(1);
+}
+
+void Scene1337::subC51A0(unkObj1337sub1 *subObj1, unkObj1337sub1 *subObj2) {
+ _field3EF0 = subObj1;
+ _field3EF4 = subObj2;
+
+ _item1.setAction(&_action13);
+}
+
+void Scene1337::displayDialog(int dialogNumb) {
+ switch (dialogNumb - 1) {
+ case 0:
+ actionDisplay(1330, 53, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ break;
+ case 1:
+ actionDisplay(1330, 57, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ break;
+ case 2:
+ actionDisplay(1330, 58, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ break;
+ case 3:
+ actionDisplay(1330, 59, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ break;
+ case 4:
+ actionDisplay(1330, 60, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ break;
+ case 5:
+ actionDisplay(1330, 61, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ break;
+ case 6:
+ actionDisplay(1330, 62, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ break;
+ case 7:
+ actionDisplay(1330, 63, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ break;
+ case 8:
+ actionDisplay(1330, 64, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ break;
+ case 9:
+ actionDisplay(1330, 65, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ break;
+ case 10:
+ actionDisplay(1330, 67, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ break;
+ case 11:
+ actionDisplay(1330, 69, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ break;
+ case 12:
+ actionDisplay(1330, 71, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ actionDisplay(1330, 72, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ actionDisplay(1330, 73, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ break;
+ case 13:
+ actionDisplay(1330, 79, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ break;
+ case 14:
+ actionDisplay(1330, 81, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ break;
+ case 15:
+ actionDisplay(1330, 83, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ break;
+ case 16:
+ actionDisplay(1330, 85, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ break;
+ case 17:
+ actionDisplay(1330, 87, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ break;
+ case 18:
+ actionDisplay(1330, 89, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ break;
+ case 19:
+ actionDisplay(1330, 91, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ break;
+ case 20:
+ actionDisplay(1330, 93, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ break;
+ case 23:
+ actionDisplay(1330, 95, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ break;
+ case 24:
+ actionDisplay(1330, 97, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ break;
+ case 25:
+ actionDisplay(1330, 104, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ break;
+ case 26:
+ actionDisplay(1330, 105, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ actionDisplay(1330, 106, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ break;
+ case 27:
+ actionDisplay(1330, 110, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ break;
+ case 28:
+ actionDisplay(1330, 108, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ actionDisplay(1330, 109, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ break;
+ case 29:
+ actionDisplay(1330, 111, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ break;
+ case 31:
+ actionDisplay(1330, 112, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ break;
+ default:
+ break;
+ }
+}
+
+void Scene1337::subPostInit() {
+ R2_GLOBALS._v57709 = 0;
+ R2_GLOBALS._v5780C = 0;
+ subD183F(1, 0);
+ subD1940(true);
+ subD18F5();
+
+// loadScene(1330);
+// SceneExt::postInit();
+
+ R2_GLOBALS._scenePalette.addRotation(224, 235, 1);
+
+ _field3E28[0] = 1;
+ _field3E28[1] = 1;
+ _field3E28[2] = 1;
+ _field3E28[3] = 1;
+ _field3E28[4] = 1;
+ _field3E28[5] = 1;
+ _field3E28[6] = 1;
+ _field3E28[7] = 1;
+ _field3E28[8] = 26;
+ _field3E28[9] = 2;
+ _field3E28[10] = 2;
+ _field3E28[11] = 2;
+ _field3E28[12] = 2;
+ _field3E28[13] = 2;
+ _field3E28[14] = 26;
+ _field3E28[15] = 3;
+ _field3E28[16] = 3;
+ _field3E28[17] = 3;
+ _field3E28[18] = 3;
+ _field3E28[19] = 3;
+ _field3E28[20] = 28;
+ _field3E28[21] = 4;
+ _field3E28[22] = 4;
+ _field3E28[23] = 4;
+ _field3E28[24] = 4;
+ _field3E28[25] = 4;
+ _field3E28[26] = 28;
+ _field3E28[27] = 5;
+ _field3E28[28] = 5;
+ _field3E28[29] = 5;
+ _field3E28[30] = 5;
+ _field3E28[31] = 5;
+ _field3E28[32] = 30;
+ _field3E28[33] = 6;
+ _field3E28[34] = 6;
+ _field3E28[35] = 6;
+ _field3E28[36] = 6;
+ _field3E28[37] = 6;
+ _field3E28[38] = 30;
+ _field3E28[39] = 7;
+ _field3E28[40] = 7;
+ _field3E28[41] = 7;
+ _field3E28[42] = 7;
+ _field3E28[43] = 7;
+ _field3E28[44] = 32;
+ _field3E28[45] = 8;
+ _field3E28[46] = 8;
+ _field3E28[47] = 8;
+ _field3E28[48] = 8;
+ _field3E28[49] = 8;
+ _field3E28[50] = 32;
+ _field3E28[51] = 9;
+ _field3E28[52] = 9;
+ _field3E28[53] = 9;
+ _field3E28[54] = 9;
+ _field3E28[55] = 9;
+ _field3E28[56] = 10;
+ _field3E28[57] = 11;
+ _field3E28[58] = 12;
+ _field3E28[59] = 13;
+ _field3E28[60] = 13;
+ _field3E28[61] = 14;
+ _field3E28[62] = 15;
+ _field3E28[63] = 16;
+ _field3E28[64] = 17;
+ _field3E28[65] = 18;
+ _field3E28[66] = 19;
+ _field3E28[67] = 20;
+ _field3E28[68] = 21;
+ _field3E28[69] = 26;
+ _field3E28[70] = 28;
+ _field3E28[71] = 24;
+ _field3E28[72] = 25;
+ _field3E28[73] = 25;
+ _field3E28[74] = 25;
+ _field3E28[75] = 25;
+ _field3E28[76] = 26;
+ _field3E28[77] = 26;
+ _field3E28[78] = 26;
+ _field3E28[79] = 27;
+ _field3E28[80] = 27;
+ _field3E28[81] = 28;
+ _field3E28[82] = 28;
+ _field3E28[83] = 28;
+ _field3E28[84] = 29;
+ _field3E28[85] = 29;
+ _field3E28[86] = 29;
+ _field3E28[87] = 30;
+ _field3E28[88] = 30;
+ _field3E28[89] = 30;
+ _field3E28[90] = 30;
+ _field3E28[91] = 32;
+ _field3E28[92] = 1;
+ _field3E28[93] = 32;
+ _field3E28[94] = 32;
+ _field3E28[95] = 32;
+ _field3E28[96] = 1;
+ _field3E28[97] = 1;
+ _field3E28[98] = 1;
+ _field3E28[99] = 0;
+
+ _field3E24 = 98;
+ _field3E26 = 98;
+
+ _item7._field34 = 0;
+ _item7._field36 = Common::Point(128, 95);
+
+ _item8._field34 = 0;
+ _item8._field36 = Common::Point(162, 95);
+
+ _item6._field34 = 0;
+
+ _item2._object1.postInit();
+ _item2._object1.setVisage(1332);
+ _item2._object1.setStrip(5);
+ _item2._object1.setFrame(1);
+ _item2._object1._moveDiff = Common::Point(10, 10);
+ _item2._object1.fixPriority(400);
+ _item2._object1.setPosition(Common::Point(128, 95), 0);
+ _item2._object1.animate(ANIM_MODE_2, NULL);
+ _item2._object1.hide();
+
+ _object1.postInit();
+ _object1.setVisage(1334);
+ _object1.setStrip(1);
+ _object1.setFrame(1);
+ _object1._numFrames = 12;
+ _object1.fixPriority(500);
+ _object1.setPosition(Common::Point(174, 107), 0);
+ _object1.animate(ANIM_MODE_2, NULL);
+ _object1.hide();
+
+ _field4244 = 1;
+ _field4246 = 0;
+ _field4248 = 0;
+ _field424A = -1;
+
+ _background1.setup2(9531, 1, 1, 249, 168, 155, 0);
+
+ _autoplay = false;
+ _field424C = 0;
+ _field424E = 0;
+}
+
+void Scene1337::suggestInstructions() {
+ if (R2_GLOBALS._v57709 > 0)
+ subD1917();
+ if (MessageDialog::show(NEED_INSTRUCTIONS, NO_MSG, YES_MSG) == 0) {
+ if (R2_GLOBALS._v57709 == 0)
+ subD18F5();
+ subCCF26();
+ } else {
+ if (R2_GLOBALS._v57709 == 0)
+ subD18F5();
+ subCB59B();
+ }
+}
+
+void Scene1337::subCB59B() {
+ _item1.setAction(&_action1);
+}
+
+void Scene1337::shuffleCards() {
+ R2_GLOBALS._sceneObjects->draw();
+
+ for (int i = 0; i <= 98; i++) {
+ if (_field3E28[i] == 0) {
+ for (int j = i + 1; j <= 98; j ++) {
+ if (_field3E28[j] != 0) {
+ _field3E28[i] = _field3E28[j];
+ _field3E28[j] = 0;
+ break;
+ }
+ }
+ }
+ }
+
+ for (int i = 0; i <= 99; i ++) {
+ if (_field3E28[i] == 0) {
+ _field3E24 = i - 1;
+ _field3E26 = 98;
+ break;
+ }
+ }
+
+ // tmpVal is never modified in the original. It looks weird but it works: at the end, the cards are suffled!
+ int tmpVal = 0;
+ int randIndx;
+ int swap;
+ for (int i = 0; i < 2000; i ++) {
+ randIndx = R2_GLOBALS._randomSource.getRandomNumber(_field3E24);
+ swap = _field3E28[tmpVal];
+ _field3E28[tmpVal] = _field3E28[randIndx];
+ _field3E28[randIndx] = swap;
+ }
+
+ _field423C = 0;
+ _item2._object1.setAction(&_action2);
+
+ while(_field423C == 0) {
+ g_globals->_scenePalette.signalListeners();
+ R2_GLOBALS._sceneObjects->draw();
+ warning("TODO: recurse on draw() and on signalListeners()?");
+ g_globals->_events.delay(g_globals->_sceneHandler->_delayTicks);
+
+ // Hack to avoid eternal loop
+ // To be removed when the recurse is working properly
+ _field423C = 1;
+ }
+}
+
+void Scene1337::subCCF26() {
+ _item2._object1._moveDiff = Common::Point(30, 30);
+ shuffleCards();
+ _item1.setAction(&_action3);
+}
+void Scene1337::subCD193() {
+ warning("STUBBED: subCD193()");
+}
+
+void Scene1337::subCDB90(int arg1, Common::Point pt) {
+ bool found = false;
+ int curReg = R2_GLOBALS._sceneRegions.indexOf(g_globals->_events._mousePos);
+
+ if (arg1 == 3) {
+ int i;
+ for (i = 0; i <= 7; i++) {
+ if ( (subC2BF8(&_arrunkObj1337[2]._arr2[i], pt))
+ || (subC2BF8(&_arrunkObj1337[0]._arr2[i], pt))
+ || (subC2BF8(&_arrunkObj1337[1]._arr2[i], pt))
+ || (subC2BF8(&_arrunkObj1337[3]._arr2[i], pt)) ) {
+ found = true;
+ break;
+ }
+ }
+
+ if (found) {
+ switch (curReg) {
+ case 5:
+ if (_arrunkObj1337[2]._arr2[i]._field34 != 0)
+ displayDialog(_arrunkObj1337[2]._arr2[i]._field34);
+ else
+ actionDisplay(1330, 20, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ break;
+ case 10:
+ if (_arrunkObj1337[3]._arr2[i]._field34 != 0)
+ displayDialog(_arrunkObj1337[3]._arr2[i]._field34);
+ else
+ actionDisplay(1330, 22, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ break;
+ case 15:
+ if (_arrunkObj1337[0]._arr2[i]._field34 != 0)
+ displayDialog(_arrunkObj1337[0]._arr2[i]._field34);
+ else
+ actionDisplay(1330, 21, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ break;
+ case 20:
+ if (_arrunkObj1337[1]._arr2[i]._field34 != 0)
+ displayDialog(_arrunkObj1337[1]._arr2[i]._field34);
+ else
+ actionDisplay(1330, 23, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ break;
+ default:
+ break;
+ }
+ } else {
+ if ( (subC2BF8(&_arrunkObj1337[2]._arr3[0], pt))
+ || (subC2BF8(&_arrunkObj1337[0]._arr3[0], pt))
+ || (subC2BF8(&_arrunkObj1337[1]._arr3[0], pt))
+ || (subC2BF8(&_arrunkObj1337[3]._arr3[0], pt)) ) {
+ found = true;
+ }
+
+ if (found) {
+ switch (curReg) {
+ case 5:
+ if (_arrunkObj1337[2]._arr3[0]._field34 != 0)
+ displayDialog(_arrunkObj1337[2]._arr3[0]._field34);
+ else
+ actionDisplay(1330, 10, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ break;
+ case 10:
+ if (_arrunkObj1337[3]._arr3[0]._field34 != 0)
+ displayDialog(_arrunkObj1337[3]._arr3[0]._field34);
+ else
+ actionDisplay(1330, 16, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ break;
+ case 15:
+ if (_arrunkObj1337[0]._arr3[0]._field34 != 0)
+ displayDialog(_arrunkObj1337[3]._arr3[0]._field34);
+ else
+ actionDisplay(1330, 13, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ break;
+ case 20:
+ if (_arrunkObj1337[1]._arr3[0]._field34 != 0)
+ displayDialog(_arrunkObj1337[1]._arr3[0]._field34);
+ else
+ actionDisplay(1330, 18, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ break;
+ default:
+ break;
+ }
+ } else {
+ if (subC2BF8(&_item7, pt)) {
+ if (_item7._field34 != 0)
+ displayDialog(_item7._field34);
+ else
+ actionDisplay(1330, 7, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ } else if (_background1._bounds.contains(pt)) {
+ actionDisplay(1330, 43, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ } else if (subC2BF8(&_item8, pt)) {
+ actionDisplay(1330, 4, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ } else if ( (subC2BF8(&_arrunkObj1337[2]._arr4[0], pt))
+ || (subC2BF8(&_arrunkObj1337[3]._arr4[0], pt))
+ || (subC2BF8(&_arrunkObj1337[0]._arr4[0], pt))
+ || (subC2BF8(&_arrunkObj1337[1]._arr4[0], pt)) ) {
+ actionDisplay(1330, 32, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ } else {
+ if (subC2BF8(&_arrunkObj1337[2]._arr1[0], pt))
+ displayDialog(_arrunkObj1337[2]._arr1[0]._field34);
+ else if (subC2BF8(&_arrunkObj1337[2]._arr1[1], pt))
+ displayDialog(_arrunkObj1337[2]._arr1[1]._field34);
+ else if (subC2BF8(&_arrunkObj1337[2]._arr1[2], pt))
+ displayDialog(_arrunkObj1337[2]._arr1[2]._field34);
+ else if (subC2BF8(&_arrunkObj1337[2]._arr1[3], pt))
+ displayDialog(_arrunkObj1337[2]._arr1[3]._field34);
+ else if ((curReg >= 6) || (curReg <= 9))
+ actionDisplay(1330, 29, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ else if ((curReg >= 11) || (curReg <= 14))
+ actionDisplay(1330, 31, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ else if ((curReg >= 16) || (curReg <= 19))
+ actionDisplay(1330, 30, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ else {
+ switch (curReg) {
+ case 0:
+ actionDisplay(1330, 2, 159, 134, 1, 200, 0, 7, 0, 105, 105);
+ break;
+ case 5:
+ actionDisplay(1330, 25, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ break;
+ case 10:
+ actionDisplay(1330, 27, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ break;
+ case 15:
+ actionDisplay(1330, 26, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ break;
+ case 20:
+ actionDisplay(1330, 28, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ break;
+ case 21:
+ actionDisplay(1330, 24, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if (arg1 != 1)
+ return;
+
+ for (int i = 0; i <= 7; i++) {
+ if (subC2BF8(&_arrunkObj1337[2]._arr2[i], pt)) {
+ switch (_arrunkObj1337[2]._arr2[i]._field34) {
+ case 0:
+ actionDisplay(1330, 11, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ break;
+ case 1:
+ actionDisplay(1330, 54, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ break;
+ default:
+ actionDisplay(1330, 34, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ break;
+ }
+ found = true;
+ break;
+ } else if (subC2BF8(&_arrunkObj1337[0]._arr2[i], pt)) {
+ switch (_arrunkObj1337[0]._arr2[i]._field34) {
+ case 0:
+ actionDisplay(1330, 11, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ break;
+ default:
+ actionDisplay(1330, 1, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ break;
+ }
+ found = true;
+ break;
+ } else if (subC2BF8(&_arrunkObj1337[1]._arr2[i], pt)) {
+ switch (_arrunkObj1337[1]._arr2[i]._field34) {
+ case 0:
+ actionDisplay(1330, 146, 300, 99, 1, 136, 0, 7, 0, 117, 117);
+ break;
+ default:
+ actionDisplay(1330, 144, 300, 99, 1, 136, 0, 7, 0, 117, 117);
+ break;
+ }
+ found = true;
+ break;
+ } else if (subC2BF8(&_arrunkObj1337[3]._arr2[i], pt)) {
+ switch (_arrunkObj1337[3]._arr2[i]._field34) {
+ case 0:
+ actionDisplay(1330, 147, 20, 99, 1, 136, 0, 7, 0, 172, 172);
+ break;
+ default:
+ actionDisplay(1330, 145, 20, 99, 1, 136, 0, 7, 0, 172, 172);
+ break;
+ }
+ found = true;
+ break;
+ }
+ }
+
+ if (subC2BF8(&_arrunkObj1337[2]._arr3[0], pt)) {
+ if (_arrunkObj1337[0]._arr3[0]._field34 != 0) {
+ actionDisplay(1330, 39, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ } else {
+ actionDisplay(1330, 11, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ }
+ found = true;
+ }
+
+ if (subC2BF8(&_arrunkObj1337[3]._arr3[0], pt)) {
+ if (_arrunkObj1337[3]._arr3[0]._field34 != 0) {
+ actionDisplay(1330, 145, 20, 99, 1, 136, 0, 7, 0, 172, 172);
+ } else {
+ actionDisplay(1330, 147, 20, 99, 1, 136, 0, 7, 0, 172, 172);
+ }
+ found = true;
+ }
+
+ if (subC2BF8(&_arrunkObj1337[1]._arr3[0], pt)) {
+ if (_arrunkObj1337[1]._arr3[0]._field34 != 0) {
+ actionDisplay(1330, 144, 300, 99, 1, 136, 0, 7, 0, 117, 117);
+ } else {
+ actionDisplay(1330, 146, 300, 99, 1, 136, 0, 7, 0, 117, 117);
+ }
+ found = true;
+ }
+
+ if (subC2BF8(&_arrunkObj1337[0]._arr3[0], pt)) {
+ if (_arrunkObj1337[0]._arr3[0]._field34 != 0) {
+ actionDisplay(1330, 1, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ } else {
+ actionDisplay(1330, 11, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ }
+ found = true;
+ }
+
+ if (subC2BF8(&_arrunkObj1337[3]._arr4[0], pt)) {
+ actionDisplay(1330, 147, 20, 99, 1, 136, 0, 7, 0, 172, 172);
+ found = true;
+ }
+
+ if (subC2BF8(&_arrunkObj1337[1]._arr4[0], pt)) {
+ actionDisplay(1330, 146, 300, 99, 1, 136, 0, 7, 0, 117, 117);
+ found = true;
+ }
+
+ if (subC2BF8(&_arrunkObj1337[0]._arr4[0], pt)) {
+ actionDisplay(1330, 11, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ found = true;
+ }
+
+ if (found)
+ return;
+
+ if (_background1._bounds.contains(pt)) {
+ subCD193();
+ return;
+ }
+
+ if (subC2BF8(&_item7, pt))
+ actionDisplay(1330, 9, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ else if (subC2BF8(&_item8, pt))
+ actionDisplay(1330, 5, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ else {
+ switch (curReg) {
+ case 0:
+ actionDisplay(1330, 3, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ break;
+ case 6:
+ // no break on purpose
+ case 7:
+ // no break on purpose
+ case 8:
+ // no break on purpose
+ case 9:
+ actionDisplay(1330, 145, 20, 99, 1, 136, 0, 7, 0, 172, 172);
+ break;
+ case 10:
+ actionDisplay(1330, 147, 20, 99, 1, 136, 0, 7, 0, 172, 172);
+ break;
+ case 11:
+ // no break on purpose
+ case 12:
+ // no break on purpose
+ case 13:
+ // no break on purpose
+ case 14:
+ actionDisplay(1330, 1, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ break;
+ case 16:
+ // no break on purpose
+ case 17:
+ // no break on purpose
+ case 18:
+ // no break on purpose
+ case 19:
+ actionDisplay(1330, 144, 300, 99, 1, 136, 0, 7, 0, 117, 117);
+ break;
+ case 20:
+ actionDisplay(1330, 146, 300, 99, 1, 136, 0, 7, 0, 117, 117);
+ break;
+ default:
+ actionDisplay(1330, 11, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ break;
+ }
+ }
+}
+
+void Scene1337::subCF31D() {
+ int tmpVal = 1;
+ bool found;
+ int count;
+
+ if (this->_arrunkObj1337[1]._arr3[0]._field34 != 0) {
+ switch (_arrunkObj1337[1]._arr3[0]._field34) {
+ case 10:
+ // No break on purpose
+ case 12:
+ // No break on purpose
+ case 15:
+ // No break on purpose
+ case 17:
+ // No break on purpose
+ case 18:
+ // No break on purpose
+ case 19:
+ // No break on purpose
+ case 20:
+ // No break on purpose
+ case 21:
+ tmpVal = 0;
+ subC4A39(&_arrunkObj1337[1]._arr3[0]);
+ break;
+ default:
+ found = false;
+ int i;
+ for (i = 0; i <= 3; i++) {
+ if (subC3386(_arrunkObj1337[1]._arr3[0]._field34, _arrunkObj1337[1]._arr1[i]._field34)) {
+ found = true;
+ break;
+ }
+ }
+
+ if (found) {
+ tmpVal = 0;
+ subC34A1(&_arrunkObj1337[1]._arr1[i], &_arrunkObj1337[1]._arr3[0]);
+ }
+ }
+ }
+
+ if (tmpVal != 1)
+ return;
+
+ found = false;
+ for (int i = 0; i <= 3; i++) {
+ int tmpIndx = subC26CB(1, i);
+ if (tmpIndx == -1)
+ break;
+
+ tmpVal = 0;
+ for (int j = 0; j <= 7; j++) {
+ if (_arrunkObj1337[1]._arr2[j]._field34 == _arrunkObj1337[1]._arr1[tmpIndx]._field34) {
+ tmpVal = 1;
+ break;
+ }
+ }
+
+ if (tmpVal == 0)
+ break;
+
+ for (int j = 0; j <= 7; j++) {
+ if (_arrunkObj1337[1]._arr2[j]._field34 == 1) {
+ if (!subC2687(_arrunkObj1337[1]._arr3[0]._field34)) {
+ count = 0;
+ for (int k = 0; k <= 7; k++) {
+ if ((_arrunkObj1337[1]._arr2[k]._field34 > 1) && (_arrunkObj1337[1]._arr2[k]._field34 <= 9))
+ ++count;
+ }
+
+ if (count == 7)
+ _field424A = 1;
+
+ subC33C0(&_arrunkObj1337[1]._arr1[tmpIndx], &_arrunkObj1337[1]._arr2[j]);
+ found = true;
+ break;
+ }
+ }
+ }
+ }
+
+ if (found)
+ return;
+
+ tmpVal = subC2719(1);
+ if (tmpVal != -1) {
+ for (int i = 0; i <= 7; i++) {
+ if ((_arrunkObj1337[1]._arr2[i]._field34 == 0) && (!subC2687(_arrunkObj1337[1]._arr3[0]._field34))) {
+ subC340B(&_arrunkObj1337[1]._arr1[tmpVal], &_arrunkObj1337[1]._arr2[i]);
+ found = true;
+ }
+ }
+ }
+
+ if (found)
+ return;
+
+ tmpVal = subC274D(1);
+ int tmpVal2 = subC331B(1);
+
+ if ((tmpVal != -1) && ( tmpVal2 != -1))
+ subC358E(&_arrunkObj1337[1]._arr1[tmpVal], tmpVal2);
+
+ if (found)
+ return;
+
+ tmpVal = subC2781(1);
+ if (tmpVal != -1) {
+ count = -1;
+ int rndVal = R2_GLOBALS._randomSource.getRandomNumber(3);
+ for (int i = 0; i <= 3; i++) {
+ if (rndVal != 1) {
+ if ( (_arrunkObj1337[rndVal]._arr1[0]._field34 != 0)
+ || (_arrunkObj1337[rndVal]._arr1[1]._field34 != 0)
+ || (_arrunkObj1337[rndVal]._arr1[2]._field34 != 0)
+ || (_arrunkObj1337[rndVal]._arr1[3]._field34 == 0)) {
+ count = rndVal;
+ break;
+ }
+
+ rndVal--;
+ if (rndVal < 0)
+ rndVal = 3;
+ }
+ }
+
+ if (count != -1) {
+ subC318B(1, &_arrunkObj1337[1]._arr1[tmpVal], count);
+ found = true;
+ }
+ }
+
+ if (found)
+ return;
+
+ count = -1;
+ int i;
+ for (i = 0; i <= 3; i++) {
+ tmpVal = subC27B5(_arrunkObj1337[1]._arr1[i]._field34);
+ if (tmpVal != -1) {
+ int rndVal = R2_GLOBALS._randomSource.getRandomNumber(3);
+
+ for (int j = 0; j <= 3; j++) {
+ if (tmpVal != 1) {
+ for (int k = 0; k <= 7; k++) {
+ // 'k' is not used in that loop.
+ // It looks suspicious.
+ if ((_arrunkObj1337[tmpVal]._arr3[0]._field34 == 0) && (subC32B1(tmpVal, _arrunkObj1337[1]._arr1[i]._field34))) {
+ count = tmpVal;
+ break;
+ }
+ }
+ }
+
+ if (count != -1) {
+ found = true;
+ break;
+ } else {
+ rndVal--;
+ if (rndVal < 0)
+ rndVal = 3;
+ }
+ }
+
+ if (found)
+ break;
+ }
+ }
+
+ if (found) {
+ if (count == -1)
+ return;
+
+ subC3456(&_arrunkObj1337[1]._arr1[i], &_arrunkObj1337[count]._arr3[0]);
+ } else {
+ int j;
+ for (j = 0; j <= 3; j++) {
+ if (subC27F9(_arrunkObj1337[1]._arr1[j]._field34) != -1) {
+ count = -1;
+ int rndVal = R2_GLOBALS._randomSource.getRandomNumber(3);
+ for (int l = 0; l <= 3; l++) {
+ if (rndVal != 1) {
+ for (int m = 0; m <= 7; m++) {
+ // 'm' is not used in that loop. It looks suspicious.
+ if ((_arrunkObj1337[rndVal]._arr3[0]._field34 == 0) && (_arrunkObj1337[1]._arr1[j]._field34 == 1)) {
+ count = rndVal;
+ break;
+ }
+ }
+ }
+ if (count != -1) {
+ found = true;
+ break;
+ } else {
+ rndVal--;
+ if (rndVal < 0)
+ rndVal = 3;
+ }
+ }
+ if (found)
+ break;
+ }
+ }
+
+ if (found) {
+ if (count == -1)
+ return;
+
+ subC3456(&_arrunkObj1337[1]._arr1[j], &_arrunkObj1337[count]._arr3[0]);
+ } else {
+ subC2835(1);
+ }
+ }
+
+}
+
+void Scene1337::subCF979() {
+ bool found = true;
+
+ if (_arrunkObj1337[0]._arr3[0]._field34 != 0) {
+ switch (_arrunkObj1337[0]._arr3[0]._field34) {
+ case 10:
+ //No break on purpose
+ case 12:
+ //No break on purpose
+ case 15:
+ //No break on purpose
+ case 17:
+ //No break on purpose
+ case 18:
+ //No break on purpose
+ case 19:
+ //No break on purpose
+ case 20:
+ //No break on purpose
+ case 21:
+ subC4A39(&_arrunkObj1337[0]._arr3[0]);
+ found = false;
+ break;
+ default:
+ int i;
+ found = false;
+
+ for (i = 0; i <= 3; i++) {
+ if (subC3386(_arrunkObj1337[0]._arr3[0]._field34, _arrunkObj1337[0]._arr1[i]._field34)) {
+ found = true;
+ break;
+ }
+ }
+
+ if (found) {
+ found = false;
+ subC34A1(&_arrunkObj1337[0]._arr1[i], &_arrunkObj1337[0]._arr3[0]);
+ }
+ break;
+ }
+ }
+
+ if (found)
+ return;
+
+ int tmpVal;
+ found = false;
+ for (int i = 0; i <= 3; i++) {
+ tmpVal = subC26CB(0, i);
+
+ if (tmpVal != -1) {
+ bool flag = false;;
+ for (int j = 0; j <= 7; j++) {
+ if (_arrunkObj1337[0]._arr2[j]._field34 == _arrunkObj1337[0]._arr1[tmpVal]._field34) {
+ flag = true;
+ break;
+ }
+ }
+
+ if (!flag) {
+ for (int j = 0; j <= 7; j++) {
+ if ((_arrunkObj1337[0]._arr2[j]._field34 == 1) && (!subC2687(_arrunkObj1337[0]._arr3[0]._field34))) {
+ int count = 0;
+ for (int k = 0; k <= 7; k++) {
+ if ((_arrunkObj1337[0]._arr2[k]._field34 > 1) && (_arrunkObj1337[0]._arr2[k]._field34 <= 9)) {
+ ++count;
+ }
+ }
+
+ if (count == 7)
+ _field424A = 0;
+
+ subC33C0(&_arrunkObj1337[0]._arr1[tmpVal], &_arrunkObj1337[0]._arr2[j]);
+ found = true;
+ }
+ }
+ }
+ }
+
+ if (found)
+ break;
+ }
+
+ if (found)
+ return;
+
+ found = false;
+ tmpVal = subC2719(0);
+
+ if (tmpVal != -1) {
+ for (int i = 0; i <= 7; i++) {
+ if ((_arrunkObj1337[0]._arr2[i]._field34 == 0) && (!subC2687(_arrunkObj1337[0]._arr3[0]._field34))) {
+ subC340B(&_arrunkObj1337[0]._arr1[tmpVal], &_arrunkObj1337[0]._arr2[i]);
+ found = true;
+ break;
+ }
+ }
+ }
+
+ if (found)
+ return;
+
+ tmpVal = subC274D(0);
+ if (tmpVal != -1) {
+ for (int i = 0; i <= 7; i++) {
+ if (_arrunkObj1337[2]._arr2[i]._field34 != 0) {
+ subC358E(&_arrunkObj1337[0]._arr1[tmpVal], 2);
+ found = true;
+ break;
+ }
+ }
+ }
+
+ if (found)
+ return;
+
+ tmpVal = subC2781(0);
+ if (tmpVal != -1) {
+ if ( (_arrunkObj1337[2]._arr1[0]._field34 != 0)
+ || (_arrunkObj1337[2]._arr1[1]._field34 != 0)
+ || (_arrunkObj1337[2]._arr1[2]._field34 != 0)
+ || (_arrunkObj1337[2]._arr1[3]._field34 != 0) ) {
+ subC318B(0, &_arrunkObj1337[0]._arr1[tmpVal], 2);
+ found = true;
+ }
+ }
+
+ if (found)
+ return;
+
+ for (int i = 0; i <= 3; i++) {
+ if (subC27B5(_arrunkObj1337[0]._arr1[i]._field34) != -1) {
+ // The variable 'j' is not used in the inner code of the loop. It's suspect
+ for (int j = 0; j <= 7; j++) {
+ if ((_arrunkObj1337[2]._arr3[0]._field34 == 0) && (subC32B1(2, _arrunkObj1337[0]._arr1[i]._field34))) {
+ subC3456(&_arrunkObj1337[0]._arr1[i], &_arrunkObj1337[2]._arr3[0]);
+ found = true;
+ break;
+ }
+ }
+
+ if (found)
+ break;
+ }
+ }
+
+ if (found)
+ return;
+
+ for (int i = 0; i <= 3; i++) {
+ if (subC27F9(_arrunkObj1337[0]._arr1[i]._field34) != -1) {
+ // The variable 'j' is not used in the inner code of the loop. It's suspect
+ for (int j = 0; j <= 7; j++) {
+ if ((_arrunkObj1337[2]._arr3[0]._field34 == 0) && (subC32B1(2, _arrunkObj1337[0]._arr1[i]._field34))) {
+ subC3456(&_arrunkObj1337[0]._arr1[i], &_arrunkObj1337[2]._arr3[0]);
+ found = true;
+ }
+ }
+
+ if (found)
+ break;
+ }
+ }
+
+ if (found)
+ return;
+
+ tmpVal = subC274D(0);
+ int tmpVal2 = subC331B(0);
+
+ if ((tmpVal != -1) && (tmpVal2 != -1)) {
+ subC358E(&_arrunkObj1337[0]._arr1[tmpVal], tmpVal2);
+ found = true;
+ }
+
+ if (found)
+ return;
+
+ tmpVal = subC2781(0);
+ if (tmpVal != -1) {
+ if ( (_arrunkObj1337[1]._arr1[0]._field34 != 0)
+ || (_arrunkObj1337[1]._arr1[1]._field34 != 0)
+ || (_arrunkObj1337[1]._arr1[2]._field34 != 0)
+ || (_arrunkObj1337[1]._arr1[3]._field34 != 0) ) {
+ subC318B(0, &_arrunkObj1337[0]._arr1[tmpVal], 1);
+ found = true;
+ }
+ }
+
+ if (found)
+ return;
+
+ for (int i = 0; i <= 3; i++) {
+ tmpVal = subC27F9(_arrunkObj1337[0]._arr1[i]._field34);
+ if (tmpVal != -1) {
+ // The variable 'j' is not used in the inner code of the loop. It's suspect.
+ for (int j = 0; j <= 7; j++) {
+ if ((_arrunkObj1337[1]._arr3[0]._field34 == 0) && (subC32B1(1, _arrunkObj1337[0]._arr1[i]._field34))) {
+ subC3456(&_arrunkObj1337[0]._arr1[i], &_arrunkObj1337[1]._arr3[0]);
+ found = true;
+ }
+ }
+
+ if (!found) {
+ // The variable 'j' is not used in the inner code of the loop. It's suspect.
+ for (int j = 0; j <= 7; j++) {
+ if ((_arrunkObj1337[3]._arr3[0]._field34 == 0) && (subC32B1(3, _arrunkObj1337[0]._arr1[i]._field34))) {
+ subC3456(&_arrunkObj1337[0]._arr1[i], &_arrunkObj1337[3]._arr3[0]);
+ found = true;
+ }
+ }
+ }
+
+ if (found)
+ break;
+ }
+ }
+
+ if (found)
+ return;
+
+ for (int i = 0; i <= 3; i++) {
+ tmpVal = subC27B5(_arrunkObj1337[0]._arr1[i]._field34);
+ if (tmpVal != -1) {
+ // The variable 'j' is not used in the inner code of the loop. It's suspect.
+ for (int j = 0; j <= 7; j++) {
+ if ((_arrunkObj1337[1]._arr3[0]._field34 == 0) && (subC32B1(1, _arrunkObj1337[0]._arr1[i]._field34))) {
+ subC3456(&_arrunkObj1337[0]._arr1[i], &_arrunkObj1337[1]._arr3[0]);
+ found = true;
+ }
+ }
+
+ if (!found) {
+ // The variable 'j' is not used in the inner code of the loop. It's suspect.
+ for (int j = 0; j <= 7; j++) {
+ if ((_arrunkObj1337[3]._arr3[0]._field34 == 0) && (subC32B1(3, _arrunkObj1337[0]._arr1[i]._field34))) {
+ subC3456(&_arrunkObj1337[0]._arr1[i], &_arrunkObj1337[3]._arr3[0]);
+ found = true;
+ }
+ }
+ }
+
+ if (found)
+ break;
+ }
+ }
+
+ if (found)
+ return;
+
+ subC2835(0);
+}
+
+void Scene1337::subD026D() {
+ subD02CA();
+}
+
+void Scene1337::subD0281() {
+ if (subC27F9(this->_arrunkObj1337[2]._arr3[0]._field34) == -1)
+ _unkFctPtr412 = &Scene1337::subD026D;
+ else
+ subC4A39(&_arrunkObj1337[2]._arr3[0]);
+}
+
+void Scene1337::subD02CA() {
+ _item6._field36 = g_globals->_events._mousePos;
+
+ if (R2_GLOBALS._v57810 == 200) {
+ int di;
+ for (di = 0; di < 4; di++) {
+ if ((subC2BF8(&_arrunkObj1337[2]._arr1[di], _item6._field36) != 0) && (_arrunkObj1337[2]._arr1[di]._field34 != 0)) {
+ _item6._field34 = _arrunkObj1337[2]._arr1[di]._field34;
+ _item6._field36 = _arrunkObj1337[2]._arr1[di]._field36;
+ // _item6._actorName = _arrunkObj1337[2]._arr1[di]._actorName;
+ _item6._fieldE = _arrunkObj1337[2]._arr1[di]._fieldE;
+ _item6._field10 = _arrunkObj1337[2]._arr1[di]._field10;
+ warning("_item6._field12 = _arrunkObj1337[2]._arr1[di]._field12;");
+ warning("_item6._field14 = _arrunkObj1337[2]._arr1[di]._field14;");
+ warning("_item6._field16 = _arrunkObj1337[2]._arr1[di]._field16;");
+ _item6._sceneRegionId = _arrunkObj1337[2]._arr1[di]._sceneRegionId;
+ _item6._position = _arrunkObj1337[2]._arr1[di]._position;
+ _item6._yDiff = _arrunkObj1337[2]._arr1[di]._yDiff;
+ _item6._bounds = _arrunkObj1337[2]._arr1[di]._bounds;
+ _item6._resNum = _arrunkObj1337[2]._arr1[di]._resNum;
+ _item6._lookLineNum = _arrunkObj1337[2]._arr1[di]._lookLineNum;
+ _item6._talkLineNum = _arrunkObj1337[2]._arr1[di]._talkLineNum;
+ _item6._useLineNum = _arrunkObj1337[2]._arr1[di]._useLineNum;
+ _item6._action = _arrunkObj1337[2]._arr1[di]._action;
+ warning("_item6._field0 = _arrunkObj1337[2]._arr1[di]._field0;");
+ _item6._object1._updateStartFrame = _arrunkObj1337[2]._arr1[di]._object1._updateStartFrame;
+ _item6._object1._walkStartFrame = _arrunkObj1337[2]._arr1[di]._object1._walkStartFrame;
+ // _field2E is named _field3C in R2R
+ _item6._object1._field2E = _arrunkObj1337[2]._arr1[di]._object1._field2E;
+ _item6._object1._percent = _arrunkObj1337[2]._arr1[di]._object1._percent;
+ _item6._object1._priority = _arrunkObj1337[2]._arr1[di]._object1._priority;
+ _item6._object1._angle = _arrunkObj1337[2]._arr1[di]._object1._angle;
+ _item6._object1._flags = _arrunkObj1337[2]._arr1[di]._object1._flags;
+ _item6._object1._xe = _arrunkObj1337[2]._arr1[di]._object1._xe;
+ _item6._object1._xs = _arrunkObj1337[2]._arr1[di]._object1._xs;
+ _item6._object1._paneRects[0] = _arrunkObj1337[2]._arr1[di]._object1._paneRects[0];
+ _item6._object1._paneRects[1] = _arrunkObj1337[2]._arr1[di]._object1._paneRects[1];
+ _item6._object1._visage = _arrunkObj1337[2]._arr1[di]._object1._visage;
+ _item6._object1._objectWrapper = _arrunkObj1337[2]._arr1[di]._object1._objectWrapper;
+ _item6._object1._strip = _arrunkObj1337[2]._arr1[di]._object1._strip;
+ _item6._object1._animateMode = _arrunkObj1337[2]._arr1[di]._object1._animateMode;
+ _item6._object1._frame = _arrunkObj1337[2]._arr1[di]._object1._frame;
+ _item6._object1._endFrame = _arrunkObj1337[2]._arr1[di]._object1._endFrame;
+ // _field68 is named _field76 in R2R
+ _item6._object1._field68 = _arrunkObj1337[2]._arr1[di]._object1._field68;
+ _item6._object1._frameChange = _arrunkObj1337[2]._arr1[di]._object1._frameChange;
+ _item6._object1._numFrames = _arrunkObj1337[2]._arr1[di]._object1._numFrames;
+ _item6._object1._regionIndex = _arrunkObj1337[2]._arr1[di]._object1._regionIndex;
+ _item6._object1._mover = _arrunkObj1337[2]._arr1[di]._object1._mover;
+ _item6._object1._moveDiff = _arrunkObj1337[2]._arr1[di]._object1._moveDiff;
+ _item6._object1._moveRate = _arrunkObj1337[2]._arr1[di]._object1._moveRate;
+ _item6._object1._field8A = _arrunkObj1337[2]._arr1[di]._object1._field8A;
+ _item6._object1._endAction = _arrunkObj1337[2]._arr1[di]._object1._endAction;
+ _item6._object1._regionBitList = _arrunkObj1337[2]._arr1[di]._object1._regionBitList;
+ // _item6._object1._actorName = _arrunkObj1337[2]._arr1[di]._object1._actorName;
+ _item6._object1._fieldE = _arrunkObj1337[2]._arr1[di]._object1._fieldE;
+ _item6._object1._field10 = _arrunkObj1337[2]._arr1[di]._object1._field10;
+ warning("_item6._object1._field12 = _arrunkObj1337[2]._arr1[di]._object1._field12;");
+ warning("_item6._object1._field14 = _arrunkObj1337[2]._arr1[di]._object1._field14;");
+ warning("_item6._object1._field16 = _arrunkObj1337[2]._arr1[di]._object1._field16;");
+ _item6._object1 = _arrunkObj1337[2]._arr1[di]._object1;
+ }
+ }
+
+ if (di == 4) {
+ subCDB90(1, _item6._field36);
+ subD0281();
+ return;
+ }
+ } else if (R2_GLOBALS._v57810 == 300) {
+ subCDB90(3, _item6._field36);
+ subD0281();
+ return;
+ } else {
+ subD1A48(R2_GLOBALS._v57810);
+ subD0281();
+ return;
+ }
+
+ // That continues the block when R2_GLOBALS._v57810 == 200 and di != 4
+ subD18B5(1332, _item6._object1._strip, _item6._object1._frame);
+ R2_GLOBALS._sceneObjects->draw();
+ Event event;
+ bool found = false;
+ bool found_di;
+ for (;;) {
+ if ( ((g_globals->_events.getEvent(event, EVENT_BUTTON_DOWN)) && (event.btnState == BTNSHIFT_RIGHT))
+ || (g_globals->_events.getEvent(event, EVENT_KEYPRESS)) ){
+ _item6._field36 = g_globals->_events._mousePos;
+ found_di = false;
+
+ for (int i = 0; i <= 3; i ++) {
+ if (subC2BF8(&_arrunkObj1337[2]._arr1[i], Common::Point(_item6._field36.x + 12, _item6._field36.y + 12)) != 0) {
+ if (_arrunkObj1337[2]._arr1[i]._field34 == 0) {
+ _arrunkObj1337[2]._arr1[i]._field34 = _item6._field34;
+ _arrunkObj1337[2]._arr1[i]._object1.postInit();
+ _arrunkObj1337[2]._arr1[i]._object1.hide();
+ _arrunkObj1337[2]._arr1[i]._object1.setVisage(1332);
+ _arrunkObj1337[2]._arr1[i]._object1.setPosition(_arrunkObj1337[2]._arr1[i]._field36, 0);
+ _arrunkObj1337[2]._arr1[i]._object1.fixPriority(170);
+ setAnimationInfo(&_arrunkObj1337[2]._arr1[i]);
+ subD18B5(5, 1, 4);
+ found = true;
+ _field423E--;
+ _field4244 = 0;
+ subC20F9();
+ } else {
+ actionDisplay(1330, 127, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ found_di = true;
+ }
+ break;
+ }
+ }
+
+ if ((!found) && (!found_di)) {
+ if (subC2BF8(&_item7, Common::Point(_item6._field36.x + 12, _item6._field36.y + 12)) != 0) {
+ subC4A39(&_item6);
+ } else if (!found) {
+ bool foundVar4;
+ int i;
+ if (_item6._field34 == 1) {
+ foundVar4 = false;
+ for (i = 0; i <= 7; i++) {
+ if (subC2BF8(&_arrunkObj1337[2]._arr2[i], Common::Point(_item6._field36.x + 12, _item6._field36.y + 12)) != 0) {
+ foundVar4 = true;
+ break;
+ }
+ }
+
+ if ((foundVar4) && (_arrunkObj1337[2]._arr2[i]._field34 == 0)) {
+ if (subC27B5(_arrunkObj1337[2]._arr3[0]._field34) != -1) {
+ actionDisplay(1330, 55, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ } else {
+ subC340B(&_item6, &_arrunkObj1337[2]._arr2[i]);
+ return;
+ }
+ } else {
+ actionDisplay(1330, 56, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ }
+ } else if (_item6._field34 <= 9) {
+ foundVar4 = false;
+ for (i = 0; i <= 7; i++) {
+ if (subC2BF8(&_arrunkObj1337[2]._arr2[i], Common::Point(_item6._field36.x + 12, _item6._field36.y + 12)) != 0) {
+ foundVar4 = true;
+ break;
+ }
+ }
+ if ((foundVar4) && (_arrunkObj1337[2]._arr2[i]._field34 == 1)) {
+ foundVar4 = false;
+ int j;
+ for (j = 0; j <= 7; j++) {
+ if (_item6._field34 == _arrunkObj1337[2]._arr2[j]._field34) {
+ foundVar4 = true;
+ break;
+ }
+ }
+ if (foundVar4) {
+ actionDisplay(1330, 34, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ } else if (subC27B5(_arrunkObj1337[2]._arr3[0]._field34) != -1) {
+ actionDisplay(1330, 35, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ } else {
+ if (j == 7)
+ _field424A = 2;
+
+ subC33C0(&_item6, &_arrunkObj1337[2]._arr2[i]);
+ return;
+ }
+ } else {
+ actionDisplay(1330, 37, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ }
+ } else {
+ if ((_item6._field34 == 26) || (_item6._field34 == 30) ||(_item6._field34 == 32) || (_item6._field34 == 28)) {
+ if (subC2BF8(&_arrunkObj1337[2]._arr3[0], Common::Point(_item6._field36.x + 12, _item6._field36.y + 12)) != 0) {
+ actionDisplay(1330, 42, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ } else if (!subC3386(_arrunkObj1337[2]._arr3[0]._field34, _item6._field34)) {
+ if (_arrunkObj1337[2]._arr3[0]._field34 != 0) {
+ switch (_arrunkObj1337[2]._arr3[0]._field34) {
+ case 11:
+ actionDisplay(1330, 68, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ break;
+ case 14:
+ actionDisplay(1330, 80, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ break;
+ case 16:
+ actionDisplay(1330, 84, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ break;
+ case 24:
+ actionDisplay(1330, 96, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ break;
+ default:
+ break;
+ }
+ } else {
+ actionDisplay(1330, 41, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ }
+ } else {
+ subC34A1(&_item6, &_arrunkObj1337[2]._arr3[0]);
+ return;
+ }
+ } else {
+ if ((subC27F9(_item6._field34) == -1) && (subC27B5(_item6._field34) == -1)) {
+ if (_item6._field34 == 13) {
+ if (subC2BF8(&_arrunkObj1337[0]._arr4[0], Common::Point(_item6._field36.x + 12, _item6._field36.y + 12)) != 0) {
+ for (int k = 0; k <= 7; k++) {
+ if (_arrunkObj1337[0]._arr2[k]._field34 != 0) {
+ found = true;
+ subC358E(&_item6, 0);
+ }
+ }
+
+ if (!found)
+ actionDisplay(1330, 74, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ } else if (subC2BF8(&_arrunkObj1337[3]._arr4[0], Common::Point(_item6._field36.x + 12, _item6._field36.y + 12)) != 0) {
+ for (int k = 0; k <= 7; k++) {
+ if (_arrunkObj1337[3]._arr2[k]._field34 != 0) {
+ found = true;
+ subC358E(&_item6, 3);
+ }
+ }
+ if (!found)
+ actionDisplay(1330, 74, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ } else if (subC2BF8(&_arrunkObj1337[1]._arr4[0], Common::Point(_item6._field36.x + 12, _item6._field36.y + 12)) != 0) {
+ for (int k = 0; k <= 7; k++) {
+ if (_arrunkObj1337[1]._arr2[k]._field34 == 0) {
+ found = true;
+ subC358E(&_item6, 1);
+ }
+ }
+ if (!found)
+ actionDisplay(1330, 74, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ } else {
+ actionDisplay(1330, 128, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ }
+ } else if (_item6._field34 == 25) {
+ int k;
+ if (subC2BF8(&_arrunkObj1337[0]._arr4[0], Common::Point(_item6._field36.x + 12, _item6._field36.y + 12)) != 0) {
+ if ( (_arrunkObj1337[0]._arr1[0]._field34 != 0)
+ || (_arrunkObj1337[0]._arr1[1]._field34 != 0)
+ || (_arrunkObj1337[0]._arr1[2]._field34 != 0)
+ || (_arrunkObj1337[0]._arr1[3]._field34 != 0) ) {
+ for (k = 0; k <= 3; k++){
+ if (_arrunkObj1337[2]._arr1[k]._field34 == 0)
+ break;
+ }
+ subC318B(2, &_arrunkObj1337[2]._arr1[k], 0);
+ return;
+ } else {
+ actionDisplay(1330, 99, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ }
+ } else if (subC2BF8(&_arrunkObj1337[1]._arr4[0], Common::Point(_item6._field36.x + 12, _item6._field36.y + 12)) != 0) {
+ if ( (_arrunkObj1337[1]._arr1[0]._field34 != 0)
+ || (_arrunkObj1337[1]._arr1[1]._field34 != 0)
+ || (_arrunkObj1337[1]._arr1[2]._field34 != 0)
+ || (_arrunkObj1337[1]._arr1[3]._field34 != 0) ) {
+ for (k = 0; k <= 3; k++){
+ if (_arrunkObj1337[2]._arr1[k]._field34 == 0)
+ break;
+ }
+ subC318B(2, &_arrunkObj1337[2]._arr1[k], 1);
+ return;
+ } else {
+ actionDisplay(1330, 99, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ }
+ }
+
+ if (subC2BF8(&_arrunkObj1337[3]._arr4[0], Common::Point(_item6._field36.x + 12, _item6._field36.y + 12)) != 0) {
+ if ( (_arrunkObj1337[3]._arr1[0]._field34 != 0)
+ || (_arrunkObj1337[3]._arr1[1]._field34 != 0)
+ || (_arrunkObj1337[3]._arr1[2]._field34 != 0)
+ || (_arrunkObj1337[3]._arr1[3]._field34 != 0) ) {
+ for (k = 0; k <= 3; k++){
+ if (_arrunkObj1337[2]._arr1[k]._field34 == 0)
+ break;
+ }
+ subC318B(2, &_arrunkObj1337[2]._arr1[k], 3);
+ return;
+ } else {
+ actionDisplay(1330, 99, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ }
+ } else {
+ actionDisplay(1330, 129, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ }
+ } else if (_item6._field34 == 29) {
+ actionDisplay(1330, 136, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ } else if (_item6._field34 == 27) {
+ actionDisplay(1330, 137, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ }
+ } else {
+ if (subC2BF8(&_arrunkObj1337[0]._arr3[0], Common::Point(_item6._field36.x + 12, _item6._field36.y + 12)) != 0) {
+ if (_arrunkObj1337[0]._arr3[0]._field34 != 0) {
+ actionDisplay(1330, 15, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ } else if (!subC32B1(0, _item6._field34)) {
+ switch (_item6._field34) {
+ case 10:
+ actionDisplay(1330, 66, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ break;
+ case 12:
+ actionDisplay(1330, 70, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ break;
+ case 15:
+ actionDisplay(1330, 82, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ break;
+ case 17:
+ actionDisplay(1330, 86, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ break;
+ case 18:
+ actionDisplay(1330, 88, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ break;
+ case 19:
+ actionDisplay(1330, 90, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ break;
+ case 20:
+ actionDisplay(1330, 92, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ break;
+ case 21:
+ actionDisplay(1330, 94, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ break;
+ default:
+ break;
+ }
+ } else {
+ subC3456(&_item6, &_arrunkObj1337[0]._arr3[0]);
+ found = true;
+ }
+ } else if (subC2BF8(&_arrunkObj1337[3]._arr3[0], Common::Point(_item6._field36.x + 12, _item6._field36.y + 12)) != 0) {
+ if (_arrunkObj1337[3]._arr3[0]._field34 != 0) {
+ actionDisplay(1330, 17, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ } else if (!subC32B1(3, _item6._field34)) {
+ switch (_item6._field34) {
+ case 10:
+ actionDisplay(1330, 66, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ break;
+ case 12:
+ actionDisplay(1330, 70, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ break;
+ case 15:
+ actionDisplay(1330, 82, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ break;
+ case 17:
+ actionDisplay(1330, 86, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ break;
+ case 18:
+ actionDisplay(1330, 88, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ break;
+ case 19:
+ actionDisplay(1330, 90, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ break;
+ case 20:
+ actionDisplay(1330, 92, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ break;
+ case 21:
+ actionDisplay(1330, 94, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ break;
+ default:
+ break;
+ }
+ } else {
+ subC3456(&_item6, &_arrunkObj1337[3]._arr3[0]);
+ found = true;
+ }
+ } else if (subC2BF8(&_arrunkObj1337[1]._arr3[0], Common::Point(_item6._field36.x + 12, _item6._field36.y + 12)) != 0) {
+ if (_arrunkObj1337[1]._arr3[0]._field34 != 0) {
+ actionDisplay(1330, 19, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ } else if (!subC32B1(1, _item6._field34)) {
+ switch (_item6._field34) {
+ case 10:
+ actionDisplay(1330, 66, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ break;
+ case 12:
+ actionDisplay(1330, 70, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ break;
+ case 15:
+ actionDisplay(1330, 82, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ break;
+ case 17:
+ actionDisplay(1330, 86, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ break;
+ case 18:
+ actionDisplay(1330, 88, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ break;
+ case 19:
+ actionDisplay(1330, 90, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ break;
+ case 20:
+ actionDisplay(1330, 92, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ break;
+ case 21:
+ actionDisplay(1330, 94, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ break;
+ default:
+ break;
+ }
+ } else {
+ subC3456(&_item6, &_arrunkObj1337[1]._arr3[0]);
+ found = true;
+ }
+ } else {
+ actionDisplay(1330, 38, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if (found)
+ return;
+ } else {
+ g_globals->_scenePalette.signalListeners();
+ R2_GLOBALS._sceneObjects->draw();
+ g_globals->_events.delay(g_globals->_sceneHandler->_delayTicks);
+ }
+ }
+}
+
+void Scene1337::subD183F(int arg1, int arg2) {
+ if ((R2_GLOBALS._v57709 != 0) || (R2_GLOBALS._v5780C != 0))
+ return;
+
+ R2_GLOBALS._v5780E = arg1 + arg2;
+
+ if (arg2 != 0) {
+ if (R2_GLOBALS._v5780E < 1)
+ R2_GLOBALS._v5780E = 2;
+
+ if (R2_GLOBALS._v5780E > 2)
+ R2_GLOBALS._v5780E = 1;
+ }
+
+ if (R2_GLOBALS._v5780E == 1) {
+ R2_GLOBALS._v57810 = 200;
+ subD195F(1, 4);
+ } else if (R2_GLOBALS._v5780E == 2) {
+ R2_GLOBALS._v57810 = 300;
+ subD195F(1, 5);
+ } else {
+ R2_GLOBALS._v57810 = 0;
+ subD195F(0, 0);
+ }
+}
+
+void Scene1337::subD18B5(int resNum, int rlbNum, int arg3) {
+ warning("STUBBED lvl3 Scene1337::subD18B5()");
+}
+
+int Scene1337::subD18F5() {
+ if (R2_GLOBALS._v57709 == 0)
+ // The cursor looks... very dummy
+ // To be checked
+ warning("TODO: CursorManager.setData(R2_GLOBALS.off_57705)");
+
+ ++R2_GLOBALS._v57709;
+
+ return R2_GLOBALS._v57709;
+}
+
+int Scene1337::subD1917() {
+ if (R2_GLOBALS._v57709 != 0) {
+ R2_GLOBALS._v57709--;
+ if (R2_GLOBALS._v57709 != 0)
+ warning("FIXME: subD195F(_width, _data);");
+ }
+
+ return R2_GLOBALS._v57709;
+}
+
+int Scene1337::subD1940(bool flag) {
+ if (flag)
+ ++R2_GLOBALS._v5780C;
+ else if (R2_GLOBALS._v5780C != 0)
+ --R2_GLOBALS._v5780C;
+
+ return R2_GLOBALS._v5780C;
+}
+
+void Scene1337::subD195F(int arg1, int arg2) {
+ subD18B5(5, arg1, arg2);
+}
+
+void Scene1337::subD1975(int arg1, int arg2) {
+ warning("STUBBED lvl2 Scene1337::subD1975()");
+}
+
+void Scene1337::subD1A48(int arg1) {
+ int tmpVal = -1;
+
+ switch (arg1) {
+ case 200:
+ tmpVal = 141;
+ break;
+ case 300:
+ tmpVal = 142;
+ break;
+ default:
+ MessageDialog::show(WRONG_ANSWER_MSG, OK_BTN_STRING);
+ break;
+ }
+
+ if (tmpVal == -1)
+ return;
+
+ actionDisplay(1330, tmpVal, -1, -1, 1, 220, 1, 5, 0, 105, 0);
+}
+
+/*--------------------------------------------------------------------------
+ * Scene 1500 - Cutscene: Ship landing
+ *
+ *--------------------------------------------------------------------------*/
+void Scene1500::postInit(SceneObjectList *OwnerList) {
+ loadScene(1500);
+ R2_GLOBALS._uiElements._active = false;
+ R2_GLOBALS._v5589E.top = 0;
+ R2_GLOBALS._v5589E.bottom = 200;
+ setZoomPercents(170, 13, 240, 100);
+ SceneExt::postInit();
+ scalePalette(65, 65, 65);
+
+ R2_GLOBALS._player.postInit();
+ R2_GLOBALS._player.hide();
+ R2_GLOBALS._player.disableControl();
+
+ _actor2.postInit();
+ _actor2.setup(1401, 1, 1);
+ _actor2._effect = 5;
+ _actor2.fixPriority(10);
+ _actor2._field9C = _field312;
+
+ _actor1.postInit();
+ _actor1.setup(1400, 1, 1);
+ _actor1._moveDiff = Common::Point(1, 1);
+ _actor1._linkedActor = &_actor2;
+
+ if (R2_GLOBALS._sceneManager._previousScene != 1010) {
+ _actor4.postInit();
+ _actor4.setup(1401, 2, 1);
+ _actor4._effect = 5;
+ _actor4.fixPriority(10);
+ _actor4._field9C = _field312;
+
+ _actor3.postInit();
+ _actor3._moveRate = 30;
+ _actor3._moveDiff = Common::Point(1, 1);
+ _actor3._linkedActor = &_actor4;
+ }
+
+ if (R2_GLOBALS._sceneManager._previousScene == 300) {
+ _actor1.setPosition(Common::Point(189, 139), 5);
+
+ _actor3.setup(1400, 1, 2);
+ _actor3.setPosition(Common::Point(148, 108), 0);
+
+ _sceneMode = 20;
+ R2_GLOBALS._sound1.play(110);
+ } else if (R2_GLOBALS._sceneManager._previousScene == 1550) {
+ _actor1.setPosition(Common::Point(189, 139), 5);
+
+ _actor3.setup(1400, 2, 1);
+ _actor3.changeZoom(-1);
+ _actor3.setPosition(Common::Point(298, 258), 5);
+
+ _sceneMode = 10;
+ R2_GLOBALS._sound1.play(106);
+ } else {
+ _actor1.setPosition(Common::Point(289, 239), -30);
+ _sceneMode = 0;
+ R2_GLOBALS._sound1.play(102);
+ }
+ signal();
+}
+
+void Scene1500::remove() {
+ R2_GLOBALS._v5589E.top = 3;
+ R2_GLOBALS._v5589E.bottom = 168;
+ R2_GLOBALS._uiElements._active = true;
+
+ SceneExt::remove();
+}
+
+void Scene1500::signal() {
+ switch(_sceneMode++) {
+ case 0:
+ R2_GLOBALS.setFlag(25);
+ setAction(&_sequenceManager, this, 1, &R2_GLOBALS._player, NULL);
+ // No break on purpose
+ case 1:
+ if (_actor1._yDiff < 50) {
+ _actor1.setPosition(Common::Point(289, 239), _actor1._yDiff + 1);
+ _sceneMode = 1;
+ }
+ setAction(&_sequenceManager, this, 1, &R2_GLOBALS._player, NULL);
+ break;
+ case 2: {
+ Common::Point pt(189, 139);
+ NpcMover *mover = new NpcMover();
+ _actor1.addMover(mover, &pt, this);
+ }
+ break;
+ case 3:
+ if (_actor1._yDiff > 5) {
+ _actor1.setPosition(Common::Point(189, 139), _actor1._yDiff - 1);
+ _sceneMode = 3;
+ }
+ setAction(&_sequenceManager, this, 1, &R2_GLOBALS._player, NULL);
+ break;
+ case 13:
+ R2_GLOBALS._player._characterIndex = R2_MIRANDA;
+ // No break on purpose
+ case 4:
+ R2_GLOBALS._sceneManager.changeScene(300);
+ break;
+ case 10:
+ // No break on purpose
+ case 20:
+ setAction(&_sequenceManager, this, 1, &R2_GLOBALS._player, NULL);
+ break;
+ case 11: {
+ Common::Point pt(148, 108);
+ NpcMover *mover = new NpcMover();
+ _actor3.addMover(mover, &pt, this);
+ }
+ break;
+ case 12:
+ setAction(&_sequenceManager, this, 2, &R2_GLOBALS._player, NULL);
+ break;
+ case 21: {
+ Common::Point pt(-2, -42);
+ NpcMover *mover = new NpcMover();
+ _actor3.addMover(mover, &pt, NULL);
+ signal();
+ }
+ break;
+ case 22:
+ if (_actor1._yDiff < 50) {
+ _actor1.setPosition(Common::Point(189, 139), _actor1._yDiff + 1);
+ _sceneMode = 22;
+ }
+ setAction(&_sequenceManager, this, 1, &R2_GLOBALS._player, NULL);
+ break;
+ case 23: {
+ Common::Point pt(-13, -61);
+ NpcMover *mover = new NpcMover();
+ _actor1.addMover(mover, &pt, this);
+ }
+ break;
+ case 24:
+ R2_GLOBALS._sceneManager.changeScene(300);
+ break;
+ default:
+ break;
+ }
+}
+
+void Scene1500::dispatch() {
+ if (_sceneMode > 10) {
+ float yDiff = sqrt((float) (_actor3._position.x * _actor3._position.x) + (_actor3._position.y * _actor3._position.y));
+ if (yDiff > 6)
+ _actor3.setPosition(_actor3._position, (int) yDiff);
+ }
+
+ Scene::dispatch();
+}
+
+/*--------------------------------------------------------------------------
+ * Scene 1525 - Cutscene - Ship
+ *
+ *--------------------------------------------------------------------------*/
+void Scene1525::postInit(SceneObjectList *OwnerList) {
+ loadScene(1525);
+ R2_GLOBALS._uiElements._active = false;
+ SceneExt::postInit();
+
+ R2_GLOBALS._player.postInit();
+ if (R2_GLOBALS._sceneManager._previousScene == 525)
+ R2_GLOBALS._player.setup(1525, 1, 1);
+ else
+ R2_GLOBALS._player.setup(1525, 1, 16);
+ R2_GLOBALS._player.setPosition(Common::Point(244, 148));
+ R2_GLOBALS._player.disableControl();
+
+ _sceneMode = 0;
+ setAction(&_sequenceManager, this, 2, &R2_GLOBALS._player, NULL);
+}
+
+void Scene1525::signal() {
+ switch (_sceneMode++) {
+ case 0:
+ if (R2_GLOBALS._sceneManager._previousScene == 525)
+ setAction(&_sequenceManager, this, 1525, &R2_GLOBALS._player, NULL);
+ else
+ setAction(&_sequenceManager, this, 1526, &R2_GLOBALS._player, NULL);
+ break;
+ case 1:
+ setAction(&_sequenceManager, this, 2, &R2_GLOBALS._player, NULL);
+ break;
+ case 2:
+ if (R2_GLOBALS._sceneManager._previousScene == 1530)
+ R2_GLOBALS._sceneManager.changeScene(1550);
+ else
+ R2_GLOBALS._sceneManager.changeScene(1530);
+ default:
+ break;
+ }
+}
+
+/*--------------------------------------------------------------------------
+ * Scene 1530 - Cutscene - Elevator
+ *
+ *--------------------------------------------------------------------------*/
+void Scene1530::postInit(SceneObjectList *OwnerList) {
+ if (R2_GLOBALS._sceneManager._previousScene == 1000)
+ loadScene(1650);
+ else if (R2_GLOBALS._sceneManager._previousScene == 1580)
+ loadScene(1550);
+ else
+ loadScene(1530);
+
+ R2_GLOBALS._uiElements._active = false;
+ SceneExt::postInit();
+
+ _stripManager.addSpeaker(&_quinnSpeaker);
+ _stripManager.addSpeaker(&_seekerSpeaker);
+
+ if (R2_GLOBALS._sceneManager._previousScene == 1000) {
+ R2_GLOBALS._player.postInit();
+ R2_GLOBALS._player.hide();
+ R2_GLOBALS._player.disableControl();
+
+ R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
+ _stripManager.start(538, this);
+ R2_GLOBALS._sound1.play(114);
+
+ _sceneMode = 3;
+ } else if (R2_GLOBALS._sceneManager._previousScene == 1580) {
+ R2_GLOBALS._player.postInit();
+ R2_GLOBALS._player._characterIndex = R2_QUINN;
+ R2_GLOBALS._player.setObjectWrapper(NULL);
+ R2_GLOBALS._player.setup(1516, 6, 1);
+ R2_GLOBALS._player.setPosition(Common::Point(160, 125));
+ R2_GLOBALS._player._moveRate = 30;
+ R2_GLOBALS._player._moveDiff = Common::Point(4, 1);
+
+ _actor2.postInit();
+ _actor2.setup(1516, 7, 1);
+ _actor2.setPosition(Common::Point(121, 41));
+ _actor2.animate(ANIM_MODE_2, NULL);
+
+ _actor3.postInit();
+ _actor3.setup(1516, 8, 1);
+ _actor3.setPosition(Common::Point(107, 116));
+ _actor3.animate(ANIM_MODE_2, NULL);
+
+ R2_GLOBALS._player.disableControl();
+ Common::Point pt(480, 75);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, this);
+ R2_GLOBALS._sound1.play(111);
+
+ _sceneMode = 1;
+ } else {
+ _actor1.postInit();
+ _actor1._effect = 1;
+
+ R2_GLOBALS._player.postInit();
+ R2_GLOBALS._player.animate(ANIM_MODE_1, NULL);
+ R2_GLOBALS._player.disableControl();
+
+ setAction(&_sequenceManager, this, 1530, &R2_GLOBALS._player, &_actor1, NULL);
+
+ _sceneMode = 2;
+ }
+
+}
+
+void Scene1530::signal() {
+ switch (_sceneMode - 1) {
+ case 0:
+ R2_GLOBALS._sceneManager.changeScene(1000);
+ break;
+ case 1:
+ R2_GLOBALS._sceneManager.changeScene(1525);
+ break;
+ case 2:
+ R2_GLOBALS._player.disableControl();
+ _sceneMode = 4;
+ R2_GLOBALS._player.show();
+ setAction(&_sequenceManager, this, 1650, &R2_GLOBALS._player, NULL);
+ break;
+ case 3:
+ R2_GLOBALS._sceneManager.changeScene(1700);
+ break;
+ default:
+ break;
+ }
+}
+
+void Scene1530::dispatch() {
+ int16 x = R2_GLOBALS._player._position.x;
+ int16 y = R2_GLOBALS._player._position.y;
+
+ _actor2.setPosition(Common::Point(x - 39, y - 85));
+ _actor3.setPosition(Common::Point(x - 53, y - 9));
+
+ Scene::dispatch();
+}
+
+/*--------------------------------------------------------------------------
+ * Scene 1550 -
+ *
+ *--------------------------------------------------------------------------*/
+Scene1550::UnkObj15501::UnkObj15501() {
+ _fieldA4 = _fieldA6 = 0;
+}
+
+void Scene1550::UnkObj15501::synchronize(Serializer &s) {
+ SceneActor::synchronize(s);
+
+ s.syncAsSint16LE(_fieldA4);
+ s.syncAsSint16LE(_fieldA6);
+}
+
+bool Scene1550::UnkObj15501::startAction(CursorType action, Event &event) {
+ Scene1550 *scene = (Scene1550 *)R2_GLOBALS._sceneManager._scene;
+
+ switch (action) {
+ case CURSOR_USE:
+ if (_visage == 1561) {
+ R2_GLOBALS._player.disableControl();
+ scene->_sceneMode = 40;
+ Common::Point pt(_position.x + 5, _position.y + 20);
+ PlayerMover *mover = new PlayerMover();
+ R2_GLOBALS._player.addMover(mover, &pt, scene);
+ return true;
+ }
+ return SceneActor::startAction(action, event);
+ break;
+ case CURSOR_LOOK:
+ if (_visage == 1561) {
+ switch (_frame) {
+ case 2:
+ SceneItem::display(1550, 23, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
+ break;
+ case 3:
+ SceneItem::display(1550, 26, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
+ break;
+ case 4:
+ SceneItem::display(1550, 35, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
+ break;
+ default:
+ break;
+ }
+ } else {
+ switch ((((_strip - 1) * 5) + _frame) % 3) {
+ case 0:
+ SceneItem::display(1550, 62, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
+ break;
+ case 1:
+ SceneItem::display(1550, 53, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
+ break;
+ case 2:
+ SceneItem::display(1550, 76, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
+ break;
+ default:
+ break;
+ }
+ }
+ return true;
+ break;
+ default:
+ return SceneActor::startAction(action, event);
+ break;
+ }
+}
+
+Scene1550::UnkObj15502::UnkObj15502() {
+ _fieldA4 = 0;
+}
+
+void Scene1550::UnkObj15502::synchronize(Serializer &s) {
+ SceneActor::synchronize(s);
+
+ s.syncAsSint16LE(_fieldA4);
+}
+
+bool Scene1550::UnkObj15502::startAction(CursorType action, Event &event) {
+ Scene1550 *scene = (Scene1550 *)R2_GLOBALS._sceneManager._scene;
+
+ switch (action) {
+ case CURSOR_USE:
+ if (_fieldA4 == 8) {
+ scene->_field412 = 1;
+ R2_GLOBALS._player.disableControl();
+ if (R2_GLOBALS._player._characterIndex == 1)
+ scene->_sceneMode = 1576;
+ else
+ scene->_sceneMode = 1584;
+ // strcpy(scene->_arrUnkObj15502[7]._actorName, 'hatch');
+ scene->setAction(&scene->_sequenceManager1, scene, scene->_sceneMode, &R2_GLOBALS._player, &scene->_arrUnkObj15502[7], NULL);
+ return true;
+ }
+ return SceneActor::startAction(action, event);
+ break;
+ case CURSOR_LOOK:
+ if (_fieldA4 == 8)
+ SceneItem::display(1550, 75, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
+ else if (_frame == 1)
+ SceneItem::display(1550, 70, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
+ else
+ SceneItem::display(1550, 71, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
+ return true;
+ break;
+ case R2_FUEL_CELL:
+ scene->_field412 = 1;
+ if (_fieldA4 == 6) {
+ R2_GLOBALS._player.disableControl();
+ scene->_actor1.postInit();
+ if (R2_GLOBALS._player._characterIndex == 1)
+ scene->_sceneMode = 1574;
+ else
+ scene->_sceneMode = 1582;
+ scene->setAction(&scene->_sequenceManager1, scene, scene->_sceneMode, &R2_GLOBALS._player, &scene->_arrUnkObj15502[5], &scene->_actor1, NULL);
+ return true;
+ }
+ return SceneActor::startAction(action, event);
+ break;
+ case R2_GYROSCOPE:
+ scene->_field412 = 1;
+ if (_fieldA4 == 3) {
+ R2_GLOBALS._player.disableControl();
+ scene->_actor1.postInit();
+ if (R2_GLOBALS._player._characterIndex == 1)
+ scene->_sceneMode = 1571;
+ else
+ scene->_sceneMode = 1581;
+ scene->setAction(&scene->_sequenceManager1, scene, scene->_sceneMode, &R2_GLOBALS._player, &scene->_arrUnkObj15502[2], &scene->_actor1, NULL);
+ return true;
+ }
+ return SceneActor::startAction(action, event);
+ break;
+ case R2_GUIDANCE_MODULE:
+ scene->_field412 = 1;
+ if (_fieldA4 == 1) {
+ R2_GLOBALS._player.disableControl();
+ scene->_actor1.postInit();
+ if (R2_GLOBALS._player._characterIndex == 1)
+ scene->_sceneMode = 1569;
+ else
+ scene->_sceneMode = 1579;
+ scene->setAction(&scene->_sequenceManager1, scene, scene->_sceneMode, &R2_GLOBALS._player, &scene->_arrUnkObj15502[0], &scene->_actor1, NULL);
+ return true;
+ }
+ return SceneActor::startAction(action, event);
+ break;
+ case R2_THRUSTER_VALVE:
+ scene->_field412 = 1;
+ if (_fieldA4 == 4) {
+ R2_GLOBALS._player.disableControl();
+ scene->_sceneMode = 1572;
+ scene->_actor1.postInit();
+ scene->setAction(&scene->_sequenceManager1, scene, scene->_sceneMode, &R2_GLOBALS._player, &scene->_arrUnkObj15502[3], &scene->_actor1, NULL);
+ return true;
+ }
+ return SceneActor::startAction(action, event);
+ break;
+ case R2_RADAR_MECHANISM:
+ scene->_field412 = 1;
+ if (_fieldA4 == 2) {
+ R2_GLOBALS._player.disableControl();
+ scene->_actor1.postInit();
+ if (R2_GLOBALS._player._characterIndex == 1)
+ scene->_sceneMode = 1570;
+ else
+ scene->_sceneMode = 1580;
+ scene->setAction(&scene->_sequenceManager1, scene, scene->_sceneMode, &R2_GLOBALS._player, &scene->_arrUnkObj15502[1], &scene->_actor1, NULL);
+ return true;
+ }
+ return SceneActor::startAction(action, event);
+ break;
+ case R2_IGNITOR:
+ scene->_field412 = 1;
+ if (_fieldA4 == 5) {
+ R2_GLOBALS._player.disableControl();
+ scene->_sceneMode = 1573;
+ scene->_actor1.postInit();
+ scene->setAction(&scene->_sequenceManager1, scene, scene->_sceneMode, &R2_GLOBALS._player, &scene->_arrUnkObj15502[4], &scene->_actor1, NULL);
+ return true;
+ }
+ return SceneActor::startAction(action, event);
+ break;
+ case R2_BATTERY:
+ scene->_field412 = 1;
+ if (_fieldA4 == 7) {
+ R2_GLOBALS._player.disableControl();
+ scene->_actor1.postInit();
+ if (R2_GLOBALS._player._characterIndex == 1)
+ scene->_sceneMode = 1575;
+ else
+ scene->_sceneMode = 1583;
+ scene->setAction(&scene->_sequenceManager1, scene, scene->_sceneMode, &R2_GLOBALS._player, &scene->_arrUnkObj15502[6], &scene->_actor1, NULL);
+ return true;
+ }
+ return SceneActor::startAction(action, event);
+ break;
+ default:
+ return SceneActor::startAction(action, event);
+ break;
+ }
+}
+
+void Scene1550::UnkObj15502::subA5CDF(int strip) {
+ _fieldA4 = strip;
+ postInit();
+ setup(1517, _fieldA4, 1);
+ switch (_fieldA4 - 1) {
+ case 0:
+ if (R2_INVENTORY.getObjectScene(R2_GUIDANCE_MODULE) == 0)
+ setFrame(5);
+ setPosition(Common::Point(287, 85));
+ break;
+ case 1:
+ if (R2_INVENTORY.getObjectScene(R2_RADAR_MECHANISM) == 0)
+ setFrame(5);
+ setPosition(Common::Point(248, 100));
+ break;
+ case 2:
+ if (R2_INVENTORY.getObjectScene(R2_DIAGNOSTICS_DISPLAY) == 0)
+ setFrame(5);
+ setPosition(Common::Point(217, 85));
+ break;
+ case 3:
+ if (R2_INVENTORY.getObjectScene(R2_THRUSTER_VALVE))
+ setFrame(5);
+ setPosition(Common::Point(161, 121));
+ break;
+ case 4:
+ if (R2_INVENTORY.getObjectScene(R2_IGNITOR))
+ setFrame(5);
+ setPosition(Common::Point(117, 121));
+ break;
+ case 5:
+ if (R2_INVENTORY.getObjectScene(R2_FUEL_CELL))
+ setFrame(5);
+ setPosition(Common::Point(111, 85));
+ break;
+ case 6:
+ if (R2_INVENTORY.getObjectScene(R2_BATTERY))
+ setFrame(5);
+ setPosition(Common::Point(95, 84));
+ break;
+ case 7: {
+ setup(1516, 1, 1);
+ setPosition(Common::Point(201, 45));
+ Scene1550 *scene = (Scene1550 *)R2_GLOBALS._sceneManager._scene;
+ if ((scene->_sceneMode == 1577) || (scene->_sceneMode == 1578))
+ hide();
+ fixPriority(92);
+ setDetails(1550, 70, -1, -1, 2, (SceneItem *) NULL);
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+Scene1550::UnkObj15503::UnkObj15503() {
+ _fieldA4 = 0;
+}
+
+void Scene1550::UnkObj15503::synchronize(Serializer &s) {
+ SceneActor::synchronize(s);
+
+ s.syncAsSint16LE(_fieldA4);
+}
+
+bool Scene1550::UnkObj15503::startAction(CursorType action, Event &event) {
+ Scene1550 *scene = (Scene1550 *)R2_GLOBALS._sceneManager._scene;
+
+ if (action != CURSOR_USE)
+ return SceneActor::startAction(action, event);
+ switch (_fieldA4) {
+ case 1:
+ if (scene->_actor13._frame == 5) {
+ R2_GLOBALS._player.disableControl();
+ scene->_sceneMode = 25;
+ if (scene->_actor4._frame == 1) {
+ scene->setAction(&scene->_sequenceManager1, scene, 1560, &scene->_actor4, NULL);
+ R2_GLOBALS.setFlag(20);
+ setFrame(2);
+ } else {
+ scene->setAction(&scene->_sequenceManager1, scene, 1561, &scene->_actor4, NULL);
+ R2_GLOBALS.clearFlag(20);
+ setFrame(1);
+ }
+ scene->_unkArea1.remove();
+ }
+ break;
+ case 2:
+ R2_GLOBALS._player.disableControl();
+ if (scene->_actor13._frame == 1) {
+ scene->_sceneMode = 23;
+ scene->setAction(&scene->_sequenceManager1, scene, 1560, this, NULL);
+ } else {
+ if (scene->_actor4._frame == 1)
+ scene->_sceneMode = 24;
+ else
+ scene->_sceneMode = 22;
+ scene->setAction(&scene->_sequenceManager1, scene, 1561, this, NULL);
+ }
+ break;
+ default:
+ break;
+ }
+ return true;
+}
+
+void Scene1550::UnkArea1550::remove() {
+ Scene1550 *scene = (Scene1550 *)R2_GLOBALS._sceneManager._scene;
+
+ _unkObj155031.remove();
+ _unkObj155032.remove();
+ // sub201EA is a common part with UnkArea1200
+ R2_GLOBALS._sceneItems.remove((SceneItem *)this);
+ _areaActor.remove();
+ SceneArea::remove();
+ R2_GLOBALS._insetUp--;
+ //
+ if ((scene->_sceneMode >= 20) && (scene->_sceneMode <= 29))
+ return;
+
+ R2_GLOBALS._player.disableControl();
+ if (scene->_actor4._frame == 1) {
+ scene->_sceneMode = 1559;
+ scene->setAction(&scene->_sequenceManager1, scene, 1559, &R2_GLOBALS._player, NULL);
+ } else {
+ scene->_sceneMode = 1562;
+ scene->setAction(&scene->_sequenceManager1, scene, 1562, &R2_GLOBALS._player, NULL);
+ }
+}
+
+void Scene1550::UnkArea1550::process(Event &event) {
+// This is a copy of Scene1200::Area1::process
+ if (_field20 != R2_GLOBALS._insetUp)
+ return;
+
+ CursorType cursor = R2_GLOBALS._events.getCursor();
+
+ if (_areaActor._bounds.contains(event.mousePos.x + g_globals->gfxManager()._bounds.left , event.mousePos.y)) {
+ if (cursor == _cursorNum)
+ warning("TODO: _cursorState = ???");
+ R2_GLOBALS._events.setCursor(_savedCursorNum); //, _cursorState);
+ } else if (event.mousePos.y < 168) {
+ if (cursor != _cursorNum) {
+ _savedCursorNum = cursor;
+ warning("TODO: _cursorState = ???");
+ R2_GLOBALS._events.setCursor(CURSOR_INVALID);
+ }
+ if (event.eventType == EVENT_BUTTON_DOWN) {
+ event.handled = true;
+ warning("TODO: _cursorState = ???");
+ R2_GLOBALS._events.setCursor(_savedCursorNum); //, _cursorState);
+ remove();
+ }
+ }
+}
+
+void Scene1550::UnkArea1550::proc12(int visage, int stripFrameNum, int frameNum, int posX, int posY) {
+ // UnkArea1200::proc12();
+ Scene1550 *scene = (Scene1550 *)R2_GLOBALS._sceneManager._scene;
+
+ _areaActor.postInit();
+ _areaActor.setup(visage, stripFrameNum, frameNum);
+ _areaActor.setPosition(Common::Point(posX, posY));
+ _areaActor.fixPriority(250);
+ _cursorNum = CURSOR_INVALID;
+ scene->_sceneAreas.push_front(this);
+ ++R2_GLOBALS._insetUp;
+ _field20 = R2_GLOBALS._insetUp;
+ //
+
+ proc13(1550, 67, -1, -1);
+ _unkObj155031.postInit();
+ _unkObj155031._fieldA4 = 1;
+ if (scene->_actor4._frame == 1)
+ _unkObj155031.setup(1559, 3, 1);
+ else
+ _unkObj155031.setup(1559, 3, 2);
+ _unkObj155031.setPosition(Common::Point(142, 79));
+ _unkObj155031.fixPriority(251);
+ _unkObj155031.setDetails(1550, 68, -1, -1, 2, (SceneItem *) NULL);
+
+ _unkObj155032.postInit();
+ _unkObj155032._numFrames = 5;
+ _unkObj155032._fieldA4 = 2;
+ if (scene->_actor13._frame == 1)
+ _unkObj155032.setup(1559, 2, 1);
+ else
+ _unkObj155032.setup(1559, 2, 2);
+ _unkObj155032.setPosition(Common::Point(156, 103));
+ _unkObj155032.fixPriority(251);
+ _unkObj155032.setDetails(1550, 69, -1, -1, 2, (SceneItem *) NULL);
+}
+
+void Scene1550::UnkArea1550::proc13(int resNum, int lookLineNum, int talkLineNum, int useLineNum) {
+ // Copy of Scene1200::Area1::proc13
+ _areaActor.setDetails(resNum, lookLineNum, talkLineNum, useLineNum, 2, (SceneItem *) NULL);
+}
+
+bool Scene1550::Hotspot1::startAction(CursorType action, Event &event) {
+ return SceneHotspot::startAction(action, event);
+}
+
+bool Scene1550::Hotspot3::startAction(CursorType action, Event &event) {
+ // Arrays related to this scene are all hacky in the origina: they are based on the impossibility to use Miranda
+ assert ((R2_GLOBALS._player._characterIndex == 1) || (R2_GLOBALS._player._characterIndex == 2));
+ // The original contains a debug message when CURSOR_TALK is used.
+ // This part is totally useless, we could remove it (and the entire function as well)
+ if (action == CURSOR_TALK)
+ warning("Location: %d/%d - %d", R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex], R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex + 2], k5A4D6[(R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex + 2] * 30)] + R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex]);
+
+ return SceneHotspot::startAction(action, event);
+}
+
+bool Scene1550::Actor6::startAction(CursorType action, Event &event) {
+ return SceneActor::startAction(action, event);
+}
+
+bool Scene1550::Actor7::startAction(CursorType action, Event &event) {
+ if (action != CURSOR_TALK)
+ return SceneActor::startAction(action, event);
+
+ Scene1550 *scene = (Scene1550 *)R2_GLOBALS._sceneManager._scene;
+ scene->_sceneMode = 80;
+ scene->signal();
+
+ return true;
+}
+
+bool Scene1550::Actor8::startAction(CursorType action, Event &event) {
+ if (action != CURSOR_USE)
+ return SceneActor::startAction(action, event);
+
+ R2_GLOBALS._player.disableControl();
+ Scene1550 *scene = (Scene1550 *)R2_GLOBALS._sceneManager._scene;
+ scene->_field412 = 1;
+ if (R2_GLOBALS._player._characterIndex == 1)
+ scene->_sceneMode = 1552;
+ else
+ scene->_sceneMode = 1588;
+
+ scene->setAction(&scene->_sequenceManager1, scene, scene->_sceneMode, &R2_GLOBALS._player, &scene->_actor8, NULL);
+ return true;
+}
+
+bool Scene1550::Actor9::startAction(CursorType action, Event &event) {
+ Scene1550 *scene = (Scene1550 *)R2_GLOBALS._sceneManager._scene;
+
+ switch (action) {
+ case CURSOR_USE:
+ scene->_sceneMode = 50;
+ R2_GLOBALS._player.disableControl();
+ R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
+ if (R2_GLOBALS._player._characterIndex == 1)
+ scene->_stripManager.start(518, scene);
+ else
+ scene->_stripManager.start(520, scene);
+ return true;
+ break;
+ case CURSOR_LOOK:
+ SceneItem::display(1550, 41, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
+ return true;
+ break;
+ default:
+ return SceneActor::startAction(action, event);
+ }
+}
+
+bool Scene1550::Actor10::startAction(CursorType action, Event &event) {
+ if (action != CURSOR_USE)
+ return SceneActor::startAction(action, event);
+
+ Scene1550 *scene = (Scene1550 *)R2_GLOBALS._sceneManager._scene;
+ R2_GLOBALS._player.disableControl();
+ if (R2_GLOBALS._player._characterIndex == 1)
+ scene->_sceneMode = 1555;
+ else
+ scene->_sceneMode = 1589;
+
+ scene->setAction(&scene->_sequenceManager1, scene, scene->_sceneMode, &R2_GLOBALS._player, &scene->_actor10, NULL);
+ return true;
+}
+
+bool Scene1550::Actor11::startAction(CursorType action, Event &event) {
+ if (action != CURSOR_USE)
+ return SceneActor::startAction(action, event);
+
+ Scene1550 *scene = (Scene1550 *)R2_GLOBALS._sceneManager._scene;
+ R2_GLOBALS._player.disableControl();
+ scene->_field412 = 1;
+ if (R2_GLOBALS._player._characterIndex == 1)
+ scene->_sceneMode = 1586;
+ else
+ scene->_sceneMode = 1587;
+
+ scene->setAction(&scene->_sequenceManager1, scene, scene->_sceneMode, &R2_GLOBALS._player, &scene->_actor11, NULL);
+ return true;
+}
+
+bool Scene1550::Actor12::startAction(CursorType action, Event &event) {
+ if (action != CURSOR_USE)
+ return SceneActor::startAction(action, event);
+
+ Scene1550 *scene = (Scene1550 *)R2_GLOBALS._sceneManager._scene;
+
+ if (R2_GLOBALS._player._characterIndex == 2) {
+ R2_GLOBALS._player.disableControl();
+ scene->_sceneMode = 1585;
+ scene->setAction(&scene->_sequenceManager1, scene, 1585, &R2_GLOBALS._player, NULL);
+ } else {
+ R2_GLOBALS._player.disableControl();
+ switch(scene->_field415) {
+ case 0:
+ scene->_actor13.fixPriority(168);
+ scene->_actor4.fixPriority(125);
+ scene->_sceneMode = 1558;
+ scene->setAction(&scene->_sequenceManager1, scene, 1558, &R2_GLOBALS._player, NULL);
+ break;
+ case 1:
+ return SceneActor::startAction(action, event);
+ break;
+ case 2:
+ scene->_field415 = 1;
+ scene->_sceneMode = 1563;
+ scene->setAction(&scene->_sequenceManager1, scene, 1563, &R2_GLOBALS._player, &scene->_actor4, NULL);
+ break;
+ default:
+ break;
+ }
+ }
+ return true;
+
+}
+
+bool Scene1550::Actor13::startAction(CursorType action, Event &event) {
+ Scene1550 *scene = (Scene1550 *)R2_GLOBALS._sceneManager._scene;
+
+ switch (action) {
+ case CURSOR_USE:
+ if (scene->_field415 != 2)
+ return SceneActor::startAction(action, event);
+
+ if (R2_INVENTORY.getObjectScene(R2_BATTERY) == 1550) {
+ R2_GLOBALS._player.disableControl();
+ scene->_sceneMode = 1564;
+ scene->setAction(&scene->_sequenceManager1, scene, 1564, &R2_GLOBALS._player, NULL);
+ } else
+ SceneItem::display(1550, 64, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
+ return true;
+ break;
+ case CURSOR_LOOK:
+ if (scene->_field415 != 2)
+ return SceneActor::startAction(action, event);
+
+ if (R2_INVENTORY.getObjectScene(R2_BATTERY) == 1550) {
+ SceneItem::display(1550, 74, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
+ } else
+ SceneItem::display(1550, 64, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
+ return true;
+ break;
+ default:
+ return SceneActor::startAction(action, event);
+ break;
+ }
+}
+
+Scene1550::Scene1550() {
+ _field412 = 0;
+ _field414 = 0;
+ _field415 = 0;
+ _field417 = 0;
+ _field419 = 0;
+}
+
+void Scene1550::synchronize(Serializer &s) {
+ SceneExt::synchronize(s);
+
+ s.syncAsSint16LE(_field412);
+ s.syncAsByte(_field414);
+ s.syncAsSint16LE(_field415);
+ s.syncAsSint16LE(_field417);
+ s.syncAsSint16LE(_field419);
+}
+
+void Scene1550::postInit(SceneObjectList *OwnerList) {
+ if ((R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex] == 9) && (R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex + 2] == 11))
+ loadScene(1234);
+ else
+ loadScene(1550);
+
+ scalePalette(65, 65, 65);
+ setZoomPercents(30, 75, 170, 100);
+ _field417 = 1550;
+ _field419 = 0;
+ SceneExt::postInit();
+
+ if (R2_GLOBALS._sceneManager._previousScene == -1)
+ R2_GLOBALS.setFlag(R2_ATTRACTOR_CABLE_HARNESS);
+
+ if ((R2_GLOBALS._player._characterScene[1] != 1550) && (R2_GLOBALS._player._characterScene[1] != 1580)) {
+ R2_GLOBALS._player._characterScene[1] = 1550;
+ R2_GLOBALS._player._characterScene[2] = 1550;
+ }
+
+ _stripManager.setColors(60, 255);
+ _stripManager.setFontNumber(3);
+ _stripManager.addSpeaker(&_quinnSpeaker);
+ _stripManager.addSpeaker(&_seekerSpeaker);
+
+ R2_GLOBALS._player.postInit();
+ R2_GLOBALS._player._effect = 6;
+
+ if (R2_GLOBALS._player._characterIndex == 1)
+ R2_GLOBALS._player.setup(1500, 3, 1);
+ else
+ R2_GLOBALS._player.setup(1505, 3, 1);
+
+ R2_GLOBALS._player._moveDiff = Common::Point(5, 3);
+
+ if ((R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex] == 9) && (R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex + 2] == 11))
+ R2_GLOBALS._player.setPosition(Common::Point(157, 135));
+ else
+ R2_GLOBALS._player.setPosition(Common::Point(160, 100));
+
+ R2_GLOBALS._player.animate(ANIM_MODE_1, NULL);
+ R2_GLOBALS._player.disableControl();
+
+ _field414 = 0;
+ _actor7.changeZoom(-1);
+ R2_GLOBALS._player.changeZoom(-1);
+
+ switch (R2_GLOBALS._sceneManager._previousScene) {
+ case 1530:
+ R2_GLOBALS._v565AE = 0;
+ // No break on purpose
+ case 300:
+ // No break on purpose
+ case 1500:
+ // No break on purpose
+ case 3150:
+ R2_GLOBALS._sound1.play(105);
+ break;
+ case 1580:
+ if (R2_GLOBALS._player._oldCharacterScene[R2_GLOBALS._player._characterIndex] == 1580) {
+ R2_GLOBALS._player.disableControl();
+ R2_GLOBALS._player.animate(ANIM_MODE_NONE, NULL);
+
+ _field412 = 1;
+
+ _actor1.postInit();
+ _arrUnkObj15502[7].subA5CDF(8);
+ _arrUnkObj15502[7].hide();
+ if (R2_GLOBALS._player._characterIndex == 1)
+ _sceneMode = 1577;
+ else
+ _sceneMode = 1578;
+
+ setAction(&_sequenceManager1, this, _sceneMode, &R2_GLOBALS._player, &_actor1, &_arrUnkObj15502[7], NULL);
+ R2_GLOBALS._player._oldCharacterScene[R2_GLOBALS._player._characterIndex] = 1550;
+ } else {
+ R2_GLOBALS._player.enableControl();
+ }
+ break;
+ default:
+ break;
+ }
+
+ subA2B2F();
+
+ _item1.setDetails(16, 1550, 10, -1, -1);
+ _item2.setDetails(24, 1550, 10, -1, -1);
+ _item3.setDetails(Rect(0, 0, 320, 200), 1550, 0, 1, -1, 1, NULL);
+
+ if ((R2_GLOBALS._sceneManager._previousScene == 1500) && (R2_GLOBALS.getFlag(16))) {
+ _sceneMode = 70;
+ if (!R2_GLOBALS._sceneObjects->contains(&_actor7))
+ _actor7.postInit();
+
+ if (R2_GLOBALS._player._characterIndex == 1)
+ _actor7.setVisage(1505);
+ else
+ _actor7.setVisage(1500);
+
+ _actor7.changeZoom(77);
+ _actor7.setDetails(1550, -1, -1, -1, 2, (SceneItem *) NULL);
+
+ assert(_field419 >= 1550);
+ R2_GLOBALS._walkRegions.enableRegion(k5A750[_field419 - 1550]);
+
+ setAction(&_sequenceManager1, this, 1590, &_actor7, NULL);
+ } else if ((_sceneMode != 1577) && (_sceneMode != 1578))
+ R2_GLOBALS._player.enableControl();
+}
+
+void Scene1550::signal() {
+ switch (_sceneMode) {
+ case 1:
+ // No break on purpose
+ case 3:
+ // No break on purpose
+ case 5:
+ // No break on purpose
+ case 7:
+ _field412 = 0;
+ R2_GLOBALS._v56AAB = 0;
+ R2_GLOBALS._player.enableControl(CURSOR_ARROW);
+ break;
+ case 20:
+ // No break on purpose
+ case 21:
+ // No break on purpose
+ case 25:
+ // No break on purpose
+ case 1563:
+ R2_GLOBALS.clearFlag(20);
+ _unkArea1.proc12(1559, 1, 1, 160, 125);
+ R2_GLOBALS._player.enableControl();
+ _sceneMode = 0;
+ break;
+ case 22:
+ _unkArea1.remove();
+ _sceneMode = 24;
+ setAction(&_sequenceManager1, this, 1561, &_actor4, NULL);
+ R2_GLOBALS.clearFlag(20);
+ break;
+ case 23:
+ _unkArea1.remove();
+ _sceneMode = 20;
+ setAction(&_sequenceManager1, this, 1566, &_actor13, &_actor5, NULL);
+ R2_GLOBALS.setFlag(21);
+ break;
+ case 24:
+ _unkArea1.remove();
+ _sceneMode = 21;
+ setAction(&_sequenceManager1, this, 1567, &_actor13, &_actor5, NULL);
+ R2_GLOBALS.clearFlag(19);
+ break;
+ case 30:
+ // No break on purpose
+ case 1556:
+ // No break on purpose
+ case 1557:
+ // Nothing on purpose
+ break;
+ case 40: {
+ _sceneMode = 41;
+ Common::Point pt(_arrUnkObj15501[0]._position.x, _arrUnkObj15501[0]._position.y + 20);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, this);
+ }
+ break;
+ case 41:
+ _sceneMode = 42;
+ if (R2_GLOBALS._player._characterIndex == 1) {
+ R2_GLOBALS._player.setup(1502, 8, 1);
+ } else {
+ R2_GLOBALS._player.changeZoom(R2_GLOBALS._player._percent + 14);
+ R2_GLOBALS._player.setup(1516, 4, 1);
+ }
+ R2_GLOBALS._player.animate(ANIM_MODE_5, this);
+ break;
+ case 42:
+ _sceneMode = 43;
+ warning("TODO: unknown use of arrUnkObj15501[0]._fieldA6");
+ switch (_arrUnkObj15501[0]._frame - 1) {
+ case 0:
+ R2_INVENTORY.setObjectScene(26, R2_GLOBALS._player._characterIndex);
+ break;
+ case 1:
+ R2_INVENTORY.setObjectScene(17, R2_GLOBALS._player._characterIndex);
+ break;
+ case 2:
+ R2_INVENTORY.setObjectScene(22, R2_GLOBALS._player._characterIndex);
+ break;
+ case 3:
+ R2_INVENTORY.setObjectScene(25, R2_GLOBALS._player._characterIndex);
+ break;
+ case 4:
+ R2_INVENTORY.setObjectScene(45, R2_GLOBALS._player._characterIndex);
+ break;
+ case 5:
+ R2_INVENTORY.setObjectScene(28, R2_GLOBALS._player._characterIndex);
+ break;
+ default:
+ break;
+ }
+ _arrUnkObj15501[0].remove();
+ R2_GLOBALS._player.animate(ANIM_MODE_6, this);
+ break;
+ case 43:
+ warning("TODO: unknown use of arrUnkObj15501[0]._fieldA6");
+ if (R2_GLOBALS._player._characterIndex == 1)
+ R2_GLOBALS._player.setVisage(1500);
+ else {
+ R2_GLOBALS._player.changeZoom(-1);
+ R2_GLOBALS._player.setVisage(1505);
+ }
+ R2_GLOBALS._player.animate(ANIM_MODE_1, this);
+ R2_GLOBALS._player.setStrip(8);
+ R2_GLOBALS._player.enableControl();
+ break;
+ case 50:
+ warning("STUB: sub_1D227()");
+ ++_sceneMode;
+ setAction(&_sequenceManager1, this, 1591, &R2_GLOBALS._player, NULL);
+ if (g_globals->_sceneObjects->contains(&_actor7))
+ signal();
+ else {
+ _actor7.postInit();
+ if (R2_GLOBALS._player._characterIndex == 1)
+ _actor7.setVisage(1505);
+ else
+ _actor7.setVisage(1500);
+ _actor7.changeZoom(77);
+ _actor7.setAction(&_sequenceManager2, this, 1590, &_actor7, NULL);
+ _actor7.setDetails(1550, -1, -1, -1, 2, (SceneItem *) NULL);
+ }
+ break;
+ case 51:
+ ++_sceneMode;
+ break;
+ case 52:
+ _actor7.changeZoom(-1);
+ _sceneMode = 1592;
+ if (R2_GLOBALS._player._characterIndex == 1)
+ setAction(&_sequenceManager1, this, 1592, &R2_GLOBALS._player, &_actor7, &_arrUnkObj15501[0], &_actor9, NULL);
+ else
+ setAction(&_sequenceManager1, this, 1593, &R2_GLOBALS._player, &_actor7, &_arrUnkObj15501[0], &_actor9, NULL);
+ break;
+ case 61:
+ R2_GLOBALS._player.enableControl(CURSOR_USE);
+ R2_GLOBALS._player._canWalk = false;
+ _field415 = 2;
+ break;
+ case 62:
+ R2_GLOBALS._player.enableControl(CURSOR_TALK);
+ if (_field415 == 2) {
+ R2_GLOBALS._player.enableControl(CURSOR_USE);
+ R2_GLOBALS._player._canWalk = false;
+ }
+ break;
+ case 70:
+ R2_GLOBALS._v565EC[2] = R2_GLOBALS._v565EC[1];
+ R2_GLOBALS._v565EC[4] = R2_GLOBALS._v565EC[3];
+ R2_GLOBALS._v565EC[0] = 1;
+ _sceneMode = 60;
+ R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
+ _stripManager.start(500, this);
+ break;
+ case 80:
+ if (R2_GLOBALS.getFlag(16)) {
+ _sceneMode = 60;
+ R2_GLOBALS._player.disableControl();
+ R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
+ if (R2_GLOBALS._v565AE >= 3) {
+ if (R2_GLOBALS._player._characterIndex == 1)
+ _stripManager.start(572, this);
+ else
+ _stripManager.start(573, this);
+ } else {
+ ++R2_GLOBALS._v565AE;
+ if (R2_GLOBALS._player._characterIndex == 1)
+ _stripManager.start(499 + R2_GLOBALS._v565AE, this);
+ else
+ _stripManager.start(502 + R2_GLOBALS._v565AE, this);
+ }
+ } else {
+ _sceneMode = 60;
+ R2_GLOBALS._player.disableControl();
+ R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
+ if (R2_GLOBALS._v565AE >= 4) {
+ if (R2_GLOBALS._player._characterIndex == 1)
+ _stripManager.start(572, this);
+ else
+ _stripManager.start(573, this);
+ } else {
+ ++R2_GLOBALS._v565AE;
+ if (R2_GLOBALS._player._characterIndex == 1)
+ _stripManager.start(563 + R2_GLOBALS._v565AE, this);
+ else
+ _stripManager.start(567 + R2_GLOBALS._v565AE, this);
+ }
+ }
+ break;
+ case 1550:
+ R2_GLOBALS._sceneManager.changeScene(1525);
+ break;
+ case 1552:
+ // No break on purpose
+ case 1588:
+ R2_INVENTORY.setObjectScene(R2_AIRBAG, R2_GLOBALS._player._characterIndex);
+ _actor8.remove();
+ _field412 = 0;
+ R2_GLOBALS._player.enableControl();
+ break;
+ case 1553:
+ R2_GLOBALS._sceneManager.changeScene(1575);
+ break;
+ case 1554:
+ R2_GLOBALS._player.enableControl();
+ _field412 = 0;
+ break;
+ case 1555:
+ // No break on purpose
+ case 1589:
+ R2_INVENTORY.setObjectScene(R2_GYROSCOPE, R2_GLOBALS._player._characterIndex);
+ _actor10.remove();
+ R2_GLOBALS._player.enableControl();
+ break;
+ case 1558:
+ _actor13.fixPriority(124);
+ _field415 = 1;
+ _unkArea1.proc12(1559, 1, 1, 160, 125);
+ R2_GLOBALS._player.enableControl();
+ break;
+ case 1559:
+ _actor13.fixPriority(168);
+ _actor4.fixPriority(169);
+ R2_GLOBALS._player.fixPriority(-1);
+ R2_GLOBALS._player.changeZoom(-1);
+ _field415 = 0;
+ R2_GLOBALS._player.enableControl();
+ break;
+ case 1562:
+ R2_GLOBALS._player.enableControl();
+ R2_GLOBALS._player._canWalk = false;
+ _field415 = 2;
+ break;
+ case 1564:
+ R2_INVENTORY.setObjectScene(R2_BATTERY, 1);
+ _sceneMode = 1565;
+ setAction(&_sequenceManager1, this, 1565, &R2_GLOBALS._player, NULL);
+ break;
+ case 1565:
+ R2_GLOBALS._player.enableControl(CURSOR_USE);
+ R2_GLOBALS._player._canWalk = false;
+ break;
+ case 1569:
+ // No break on purpose
+ case 1579:
+ _field412 = 0;
+ _actor1.remove();
+ R2_INVENTORY.setObjectScene(R2_GUIDANCE_MODULE, 0);
+ R2_GLOBALS._player.enableControl();
+ break;
+ case 1570:
+ // No break on purpose
+ case 1580:
+ _field412 = 0;
+ _actor1.remove();
+ R2_INVENTORY.setObjectScene(R2_RADAR_MECHANISM, 0);
+ R2_GLOBALS._player.enableControl();
+ break;
+ case 1571:
+ // No break on purpose
+ case 1581:
+ _field412 = 0;
+ _actor1.remove();
+ R2_INVENTORY.setObjectScene(R2_GYROSCOPE, 0);
+ R2_GLOBALS._player.enableControl();
+ break;
+ case 1572:
+ _field412 = 0;
+ _actor1.remove();
+ R2_INVENTORY.setObjectScene(R2_THRUSTER_VALVE, 0);
+ R2_GLOBALS._player.enableControl();
+ break;
+ case 1573:
+ _field412 = 0;
+ _actor1.remove();
+ R2_INVENTORY.setObjectScene(R2_IGNITOR, 0);
+ R2_GLOBALS._player.enableControl();
+ break;
+ case 1574:
+ // No break on purpose
+ case 1582:
+ _field412 = 0;
+ _actor1.remove();
+ R2_INVENTORY.setObjectScene(R2_FUEL_CELL, 0);
+ R2_GLOBALS._player.enableControl();
+ break;
+ case 1575:
+ // No break on purpose
+ case 1583:
+ _field412 = 0;
+ _actor1.remove();
+ R2_INVENTORY.setObjectScene(R2_BATTERY, 0);
+ R2_GLOBALS._player.enableControl();
+ break;
+ case 1576:
+ // No break on purpose
+ case 1584:
+ R2_GLOBALS._sceneManager.changeScene(1580);
+ R2_GLOBALS._player.enableControl();
+ break;
+ case 1577:
+ // No break on purpose
+ case 1578:
+ _sceneMode = 0;
+ _actor1.remove();
+ _field412 = 0;
+ R2_GLOBALS._player.fixPriority(-1);
+ R2_GLOBALS._player.enableControl();
+ break;
+ case 1585:
+ SceneItem::display(1550, 66, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
+ R2_GLOBALS._player.enableControl();
+ break;
+ case 1586:
+ // No break on purpose
+ case 1587:
+ R2_INVENTORY.setObjectScene(R2_DIAGNOSTICS_DISPLAY, R2_GLOBALS._player._characterIndex);
+ _actor1.remove();
+ _field412 = 0;
+ R2_GLOBALS._player.enableControl();
+ break;
+ case 1592:
+ _actor9.remove();
+ R2_INVENTORY.setObjectScene(R2_JOYSTICK, 1);
+ if (R2_GLOBALS._player._characterIndex == 1) {
+ R2_GLOBALS._v565EC[2] = R2_GLOBALS._v565EC[1];
+ R2_GLOBALS._v565EC[4] = R2_GLOBALS._v565EC[3];
+ } else {
+ R2_GLOBALS._v565EC[1] = R2_GLOBALS._v565EC[2];
+ R2_GLOBALS._v565EC[3] = R2_GLOBALS._v565EC[4];
+ }
+ R2_GLOBALS._player.enableControl();
+ break;
+ default:
+ _sceneMode = 62;
+ setAction(&_sequenceManager1, this, 1, &R2_GLOBALS._player, NULL);
+ break;
+ }
+}
+
+void Scene1550::process(Event &event) {
+ if ((!R2_GLOBALS._player._canWalk) && (R2_GLOBALS._events.getCursor() == R2_NEGATOR_GUN) && (event.eventType == EVENT_BUTTON_DOWN) && (this->_screenNumber == 1234)) {
+ int curReg = R2_GLOBALS._sceneRegions.indexOf(event.mousePos);
+ if (curReg == 0)
+ _field412 = 1;
+ else if (((R2_GLOBALS._player._position.y < 90) && (event.mousePos.y > 90)) || ((R2_GLOBALS._player._position.y > 90) && (event.mousePos.y < 90)))
+ _field412 = 1;
+ else
+ _field412 = 0;
+
+ if ((curReg == 13) || (curReg == 14))
+ _field412 = 0;
+ }
+
+ Scene::process(event);
+}
+
+void Scene1550::dispatch() {
+ Scene::dispatch();
+
+ // Arrays related to this scene are all hacky in the origina: they are based on the impossibility to use Miranda
+ assert ((R2_GLOBALS._player._characterIndex == 1) || (R2_GLOBALS._player._characterIndex == 2));
+
+ if ((R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex] == 15) && (R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex + 2] == 16)) {
+ R2_GLOBALS._player._shade = 0;
+ // Original game contains a switch based on an uninitialised variable.
+ // Until we understand what should really happen there, this code is unused on purpose
+ int missingVariable = 0;
+ switch (missingVariable) {
+ case 144:
+ // No break on purpose
+ case 146:
+ _actor13._frame = 5;
+ R2_GLOBALS._player._shade = 3;
+ break;
+ case 148:
+ // No break on purpose
+ case 149:
+ _actor13._frame = 1;
+ // No break on purpose
+ case 147:
+ // No break on purpose
+ case 150:
+ R2_GLOBALS._player._shade = 3;
+ break;
+ default:
+ break;
+ }
+ }
+
+ if (_field412 != 0)
+ return;
+
+ switch (R2_GLOBALS._player.getRegionIndex() - 11) {
+ case 0:
+ // No break on purpose
+ case 5:
+ R2_GLOBALS._player.disableControl();
+ _sceneMode = 1;
+ _field412 = 1;
+ --R2_GLOBALS._v565EC[2 + R2_GLOBALS._player._characterIndex];
+
+ subA2B2F();
+
+ R2_GLOBALS._player.setPosition(Common::Point( 160 - (((((160 - R2_GLOBALS._player._position.x) * 100) / 108) * 172) / 100), 145));
+ if (R2_GLOBALS._player._position.x < 160) {
+ Common::Point pt(R2_GLOBALS._player._position.x + 5, 135);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, this);
+ } else if (R2_GLOBALS._player._position.x <= 160) { // the check is really in the original...
+ Common::Point pt(R2_GLOBALS._player._position.x, 135);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, this);
+ } else {
+ Common::Point pt(R2_GLOBALS._player._position.x - 5, 135);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, this);
+ }
+ break;
+ case 1:
+ R2_GLOBALS._player.disableControl();
+ _sceneMode = 3;
+ _field412 = 1;
+ ++R2_GLOBALS._v565EC[2 + R2_GLOBALS._player._characterIndex];
+
+ subA2B2F();
+
+ R2_GLOBALS._player.setPosition(Common::Point( 160 - (((((160 - R2_GLOBALS._player._position.x) * 100) / 172) * 108) / 100), 19));
+ if (R2_GLOBALS._player._position.x < 160) {
+ Common::Point pt(R2_GLOBALS._player._position.x + 5, 29);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, this);
+ } else if (R2_GLOBALS._player._position.x <= 160) { // the check is really in the original...
+ Common::Point pt(R2_GLOBALS._player._position.x, 29);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, this);
+ } else {
+ Common::Point pt(R2_GLOBALS._player._position.x - 5, 29);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, this);
+ }
+ break;
+ case 2:
+ R2_GLOBALS._player.disableControl();
+ _sceneMode = 5;
+ _field412 = 1;
+ ++R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex];
+
+ subA2B2F();
+
+ if ((R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex] == 9) && (R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex + 2] == 11) && (R2_GLOBALS._player._position.y > 50) && (R2_GLOBALS._player._position.y < 135)) {
+ if (R2_GLOBALS._player._position.y >= 85) {
+ R2_GLOBALS._player.setPosition(Common::Point(320 - R2_GLOBALS._player._position.x, R2_GLOBALS._player._position.y + 10));
+ Common::Point pt(R2_GLOBALS._player._position.x + 30, R2_GLOBALS._player._position.y + 20);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, this);
+ } else {
+ R2_GLOBALS._player.setPosition(Common::Point(320 - R2_GLOBALS._player._position.x, R2_GLOBALS._player._position.y - 10));
+ Common::Point pt(R2_GLOBALS._player._position.x + 30, R2_GLOBALS._player._position.y - 20);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, this);
+ }
+ } else {
+ R2_GLOBALS._player.setPosition(Common::Point(320 - R2_GLOBALS._player._position.x, R2_GLOBALS._player._position.y));
+ Common::Point pt(R2_GLOBALS._player._position.x + 10, R2_GLOBALS._player._position.y);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, this);
+ }
+ break;
+ case 3:
+ R2_GLOBALS._player.disableControl();
+ _sceneMode = 7;
+ _field412 = 1;
+ --R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex];
+ if ((R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex] == 24) && (R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex + 2] == 11)) {
+ R2_GLOBALS._player.setPosition(Common::Point(320 - R2_GLOBALS._player._position.x, R2_GLOBALS._player._position.y / 2));
+ Common::Point pt(265, 29);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, this);
+ } else if ((R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex] == 9) && (R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex + 2] == 11) && (R2_GLOBALS._player._position.y > 50) && (R2_GLOBALS._player._position.y < 135)) {
+ if (R2_GLOBALS._player._position.y >= 85) {
+ R2_GLOBALS._player.setPosition(Common::Point(320 - R2_GLOBALS._player._position.x, R2_GLOBALS._player._position.y + 10));
+ Common::Point pt(R2_GLOBALS._player._position.x - 30, R2_GLOBALS._player._position.y + 20);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, this);
+ } else {
+ R2_GLOBALS._player.setPosition(Common::Point(320 - R2_GLOBALS._player._position.x, R2_GLOBALS._player._position.y - 10));
+ Common::Point pt(R2_GLOBALS._player._position.x - 30, R2_GLOBALS._player._position.y - 20);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, this);
+ }
+ } else {
+ R2_GLOBALS._player.setPosition(Common::Point(320 - R2_GLOBALS._player._position.x, R2_GLOBALS._player._position.y));
+ Common::Point pt(R2_GLOBALS._player._position.x - 10, R2_GLOBALS._player._position.y);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, this);
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+void Scene1550::saveCharacter(int characterIndex) {
+ if (R2_GLOBALS._player._characterIndex == 3)
+ R2_GLOBALS._sound1.fadeOut2(NULL);
+
+ SceneExt::saveCharacter(characterIndex);
+}
+
+void Scene1550::SceneActor1550::subA4D14(int frameNumber, int strip) {
+ Scene1550 *scene = (Scene1550 *)R2_GLOBALS._sceneManager._scene;
+
+ postInit();
+ if (scene->_field414 == 2)
+ setup(1551, strip, frameNumber);
+ else
+ setup(1554, strip, frameNumber);
+
+ switch (strip) {
+ case 0:
+ switch (frameNumber - 1) {
+ case 0:
+ setup(1551, 1, 1);
+ setPosition(Common::Point(30, 67));
+ break;
+ case 1:
+ setup(1560, 1, 5);
+ setPosition(Common::Point(141, 54));
+ break;
+ case 2:
+ setup(1560, 2, 5);
+ setPosition(Common::Point(178, 54));
+ break;
+ case 3:
+ setup(1560, 2, 1);
+ setPosition(Common::Point(289, 67));
+ break;
+ case 4:
+ setup(1560, 2, 2);
+ setPosition(Common::Point(298, 132));
+ break;
+ case 5:
+ setup(1560, 1, 2);
+ setPosition(Common::Point(21, 132));
+ break;
+ case 6:
+ setup(1560, 2, 4);
+ setPosition(Common::Point(285, 123));
+ break;
+ case 7:
+ setup(1560, 1, 3);
+ setPosition(Common::Point(30, 111));
+ break;
+ case 8:
+ setup(1560, 2, 3);
+ setPosition(Common::Point(289, 111));
+ break;
+ case 9:
+ setup(1560, 1, 4);
+ setPosition(Common::Point(34, 123));
+ break;
+ default:
+ break;
+ }
+ fixPriority(1);
+ break;
+ case 1:
+ if (frameNumber == 3) {
+ setup(1553, 3, 1);
+ setPosition(Common::Point(48, 44));
+ fixPriority(2);
+ } else {
+ fixPriority(1);
+ setPosition(Common::Point(32, 17));
+ }
+
+ switch (frameNumber) {
+ case 2:
+ setDetails(1550, 3, -1, -1, 2, (SceneItem *) NULL);
+ break;
+ case 3:
+ setDetails(1550, 6, -1, -1, 2, (SceneItem *) NULL);
+ break;
+ default:
+ setDetails(1550, 72, -1, -1, 2, (SceneItem *) NULL);
+ break;
+ }
+ break;
+ case 2:
+ fixPriority(1);
+ switch (frameNumber) {
+ case 4:
+ setup(1553, 4, 1);
+ setPosition(Common::Point(48, 168));
+ break;
+ case 5:
+ setup(1553, 3, 2);
+ setPosition(Common::Point(20, 168));
+ fixPriority(250);
+ break;
+ default:
+ setPosition(Common::Point(28, 116));
+ break;
+ }
+
+ switch (frameNumber) {
+ case 2:
+ setDetails(1550, 3, -1, -1, 2, (SceneItem *) NULL);
+ break;
+ case 4:
+ setDetails(1550, 6, -1, -1, 2, (SceneItem *) NULL);
+ break;
+ case 5:
+ setDetails(1550, 6, -1, -1, 2, (SceneItem *) NULL);
+ break;
+ default:
+ setDetails(1550, 72, -1, -1, 2, (SceneItem *) NULL);
+ break;
+ }
+ break;
+ case 3:
+ switch (frameNumber) {
+ case 2:
+ fixPriority(2);
+ if (scene->_field414 == 2)
+ setup(1553, 2, 1);
+ else
+ setup(1556, 2, 1);
+ setPosition(Common::Point(160, 44));
+ break;
+ case 3:
+ fixPriority(2);
+ setup(1553, 5, 1);
+ setPosition(Common::Point(178, 44));
+ break;
+ default:
+ fixPriority(1);
+ setPosition(Common::Point(160, 17));
+ break;
+ }
+
+ if (frameNumber == 1)
+ setDetails(1550, 3, -1, -1, 2, (SceneItem *) NULL);
+ else
+ setDetails(1550, 6, -1, -1, 2, (SceneItem *) NULL);
+ break;
+ case 4:
+ if (frameNumber == 2) {
+ fixPriority(250);
+ if (scene->_field414 == 2)
+ setup(1553, 1, 1);
+ else
+ setup(1556, 1, 1);
+ } else {
+ fixPriority(2);
+ }
+
+ if (frameNumber != 1)
+ setDetails(1550, 6, -1, -1, 2, (SceneItem *) NULL);
+
+ setPosition(Common::Point(160, 168));
+ break;
+ case 5:
+ fixPriority(1);
+ setPosition(Common::Point(287, 17));
+
+ switch (frameNumber) {
+ case 2:
+ setDetails(1550, 3, -1, -1, 2, (SceneItem *) NULL);
+ break;
+ case 3:
+ setDetails(1550, 6, -1, -1, 2, (SceneItem *) NULL);
+ break;
+ default:
+ setDetails(1550, 72, -1, -1, 2, (SceneItem *) NULL);
+ break;
+ }
+ break;
+ case 6:
+ fixPriority(1);
+ setPosition(Common::Point(291, 116));
+
+ if (frameNumber == 2)
+ setDetails(1550, 3, -1, -1, 2, (SceneItem *) NULL);
+ else
+ setDetails(1550, 72, -1, -1, 2, (SceneItem *) NULL);
+ break;
+ default:
+ break;
+ }
+
+}
+
+void Scene1550::subA2B2F() {
+ Rect tmpRect;
+ _field419 = 0;
+ _field415 = 0;
+
+ tmpRect = R2_GLOBALS._v5589E;
+
+ _actor14.remove();
+ _actor17.remove();
+ _actor15.remove();
+ _actor19.remove();
+ _actor16.remove();
+ _actor18.remove();
+
+ for (int i = 0; i < 8; ++i)
+ _arrUnkObj15501[i].remove();
+
+ _actor6.remove();
+
+ for (int i = 0; i < 8; ++i)
+ _arrUnkObj15502[i].remove();
+
+ _actor8.remove();
+ _actor9.remove();
+ _actor10.remove();
+ _actor3.remove();
+ _actor11.remove();
+
+ if ((_sceneMode != 1577) && (_sceneMode != 1578))
+ _actor1.remove();
+
+ _actor2.remove();
+ _actor7.remove();
+ _actor13.remove();
+ _actor5.remove();
+ _actor12.remove();
+ _actor4.remove();
+
+ switch (R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex + 2]) {
+ case 0:
+ switch (R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex]) {
+ case 3:
+ R2_GLOBALS._walkRegions.load(1554);
+ _field419 = 1554;
+ break;
+ case 4:
+ R2_GLOBALS._walkRegions.load(1553);
+ _field419 = 1553;
+ break;
+ default:
+ break;
+ }
+ break;
+ case 3:
+ // No break on purpose
+ case 4:
+ if ((R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex] == 23) || (R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex])) {
+ if (!R2_GLOBALS.getFlag(16)) {
+ R2_GLOBALS._walkRegions.load(1559);
+ _field419 = 1559;
+ }
+ }
+ break;
+ case 7:
+ switch (R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex]) {
+ case 10:
+ R2_GLOBALS._walkRegions.load(1555);
+ _field419 = 1555;
+ break;
+ case 11:
+ R2_GLOBALS._walkRegions.load(1556);
+ _field419 = 1556;
+ break;
+ default:
+ break;
+ }
+ break;
+ case 11:
+ switch (R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex]) {
+ case 24:
+ R2_GLOBALS._walkRegions.load(1558);
+ _field419 = 1558;
+ break;
+ case 25:
+ R2_GLOBALS._walkRegions.load(1557);
+ _field419 = 1557;
+ break;
+ default:
+ break;
+ }
+ break;
+ case 16:
+ switch (R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex]) {
+ case 2:
+ R2_GLOBALS._walkRegions.load(1552);
+ _field419 = 1552;
+ break;
+ case 3:
+ R2_GLOBALS._walkRegions.load(1551);
+ _field419 = 1551;
+ break;
+ case 15:
+ R2_GLOBALS._walkRegions.load(1575);
+ _field419 = 1575;
+ default:
+ break;
+ }
+ break;
+ default:
+ break;
+ }
+
+ int varA = 0;
+
+ if (!R2_GLOBALS.getFlag(16)) {
+ switch (R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex + 2] - 2) {
+ case 0:
+ switch (R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex] - 22) {
+ case 0:
+ varA = 1553;
+ _actor15.subA4D14(6, 0);
+ break;
+ case 1:
+ // No break on purpose
+ case 2:
+ // No break on purpose
+ case 3:
+ // No break on purpose
+ case 4:
+ varA = 1553;
+ break;
+ case 5:
+ varA = 1553;
+ _actor15.subA4D14(6, 0);
+ break;
+ default:
+ break;
+ }
+ break;
+ case 1:
+ // No break on purpose
+ case 2:
+ switch (R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex] - 21) {
+ case 0:
+ varA = 1550;
+ _actor15.subA4D14(9, 0);
+ break;
+ case 1:
+ varA = 1552;
+ _actor15.subA4D14(10, 0);
+ break;
+ case 2:
+ // No break on purpose
+ case 3:
+ // No break on purpose
+ case 4:
+ // No break on purpose
+ case 5:
+ varA = 1552;
+ break;
+ case 6:
+ varA = 1552;
+ _actor15.subA4D14(7, 0);
+ break;
+ case 7:
+ varA = 1550;
+ _actor15.subA4D14(8, 0);
+ break;
+ default:
+ break;
+ }
+ break;
+ case 3:
+ switch (R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex] - 21) {
+ case 0:
+ varA = 1550;
+ _actor15.subA4D14(4, 0);
+ break;
+ case 1:
+ varA = 1550;
+ _actor15.subA4D14(3, 0);
+ break;
+ case 2:
+ // No break on purpose
+ case 3:
+ // No break on purpose
+ case 4:
+ // No break on purpose
+ case 5:
+ varA = 1551;
+ break;
+ case 6:
+ varA = 1550;
+ _actor15.subA4D14(2, 0);
+ break;
+ case 7:
+ varA = 1550;
+ _actor15.subA4D14(1, 0);
+ break;
+ default:
+ break;
+ }
+ break;
+ default:
+ break;
+ }
+ if ((R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex + 2] > 0) && (R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex] <= 29) && (R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex] >= 20) && (R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex + 2] > 7)) {
+ R2_GLOBALS.setFlag(16);
+ R2_GLOBALS._sceneManager.changeScene(1500);
+ }
+ }
+
+ if ((R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex] == 9) && (R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex + 2] == 11)) {
+ if (R2_GLOBALS._sceneManager._sceneNumber != 1234) {
+ R2_GLOBALS._sceneManager._fadeMode = FADEMODE_IMMEDIATE;
+ loadScene(1234);
+ R2_GLOBALS._sceneManager._hasPalette = false;
+ _field414 = 0;
+ }
+ } else {
+ if (R2_GLOBALS._sceneManager._sceneNumber == 1234) {
+ R2_GLOBALS._sceneManager._fadeMode = FADEMODE_IMMEDIATE;
+ loadScene(1550);
+ R2_GLOBALS._sceneManager._hasPalette = false;
+ }
+ }
+
+ if (R2_GLOBALS._sceneManager._sceneNumber == 1234)
+ _field419 = 1576;
+
+ if (_field414 == 0) {
+ _field414 = 1;
+ } else {
+ if (_field414 == 2) {
+ _field414 = 3;
+ } else {
+ _field414 = 2;
+ }
+
+ if (R2_GLOBALS._sceneManager._sceneNumber == 1550){
+ warning("Mouse_hideIfNeeded()");
+ warning("gfx_set_pane_p");
+ for (int i = 3; i != 168; ++i) {
+ warning("sub294D2(4, i, 312, var14C)");
+ warning("missing for loop, to be implemented");
+ warning("gfx_draw_slice");
+ }
+ warning("Missing sub2957D()");
+ warning("gfx_set_pane_p()");
+ R2_GLOBALS._sceneManager._fadeMode = FADEMODE_IMMEDIATE;
+
+ if (varA == 0) {
+ if (_field417 != 1550)
+ g_globals->_scenePalette.loadPalette(1550);
+ R2_GLOBALS._sceneManager._hasPalette = true;
+ } else {
+ g_globals->_scenePalette.loadPalette(varA);
+ R2_GLOBALS._sceneManager._hasPalette = true;
+ }
+
+ if (R2_GLOBALS._sceneManager._hasPalette)
+ _field417 = varA;
+
+ warning("sub_2C429()");
+ }
+ }
+
+ switch (k5A4D6[(R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex + 2] * 30)] + R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex]) {
+ case 0:
+ if (_field419 == 0) {
+ R2_GLOBALS._walkRegions.load(1550);
+ _field419 = 1550;
+ }
+ break;
+ case 1:
+ if (_field419 == 0) {
+ R2_GLOBALS._walkRegions.load(1560);
+ _field419 = 1560;
+ }
+ _actor14.subA4D14(2, 1);
+ _actor15.subA4D14(1, 3);
+ _actor16.subA4D14(2, 5);
+ break;
+ case 2:
+ R2_GLOBALS._walkRegions.load(1561);
+ _field419 = 1561;
+ _actor14.subA4D14(2, 1);
+ _actor17.subA4D14(2, 2);
+ _actor15.subA4D14(1, 3);
+ _actor16.subA4D14(2, 5);
+ break;
+ case 3:
+ R2_GLOBALS._walkRegions.load(1562);
+ _field419 = 1562;
+ _actor14.subA4D14(2, 1);
+ _actor15.subA4D14(1, 3);
+ _actor16.subA4D14(2, 5);
+ _actor18.subA4D14(2, 6);
+ break;
+ case 4:
+ R2_GLOBALS._walkRegions.load(1563);
+ _field419 = 1563;
+ _actor15.subA4D14(2, 3);
+ break;
+ case 5:
+ R2_GLOBALS._walkRegions.load(1564);
+ _field419 = 1564;
+ _actor19.subA4D14(2, 4);
+ break;
+ case 6:
+ R2_GLOBALS._walkRegions.load(1565);
+ _field419 = 1565;
+ _actor14.subA4D14(1, 1);
+ _actor17.subA4D14(1, 2);
+ _actor15.subA4D14(3, 3);
+ break;
+ case 7:
+ R2_GLOBALS._walkRegions.load(1566);
+ _field419 = 1566;
+ _actor14.subA4D14(1, 1);
+ _actor17.subA4D14(1, 2);
+ _actor15.subA4D14(2, 4);
+ break;
+ case 8:
+ R2_GLOBALS._walkRegions.load(1567);
+ _field419 = 1567;
+ _actor17.subA4D14(5, 2);
+ break;
+ case 9:
+ R2_GLOBALS._walkRegions.load(1568);
+ _field419 = 1568;
+ _actor17.subA4D14(4, 2);
+ break;
+ case 10:
+ R2_GLOBALS._walkRegions.load(1569);
+ _field419 = 1569;
+ _actor14.subA4D14(3, 1);
+ break;
+ case 11:
+ R2_GLOBALS._walkRegions.load(1570);
+ _field419 = 1570;
+ _actor14.subA4D14(1, 1);
+ _actor17.subA4D14(1, 2);
+ break;
+ case 12:
+ R2_GLOBALS._walkRegions.load(1571);
+ _field419 = 1571;
+ _actor16.subA4D14(1, 5);
+ _actor18.subA4D14(1, 6);
+ break;
+ case 13:
+ R2_GLOBALS._walkRegions.load(1572);
+ _field419 = 1572;
+ _actor14.subA4D14(1, 1);
+ _actor17.subA4D14(1, 2);
+ _actor19.subA4D14(1, 4);
+ break;
+ case 14:
+ R2_GLOBALS._walkRegions.load(1573);
+ _field419 = 1573;
+ _actor19.subA4D14(1, 4);
+ _actor16.subA4D14(1, 5);
+ _actor18.subA4D14(1, 6);
+ break;
+ case 15:
+ R2_GLOBALS._walkRegions.load(1574);
+ _field419 = 1574;
+ _actor19.subA4D14(1, 4);
+ break;
+ case 16:
+ R2_GLOBALS._walkRegions.load(1570);
+ _field419 = 1570;
+ _actor14.subA4D14(2, 1);
+ _actor17.subA4D14(2, 2);
+ break;
+ case 17:
+ R2_GLOBALS._walkRegions.load(1570);
+ _field419 = 1570;
+ _actor14.subA4D14(2, 1);
+ _actor17.subA4D14(3, 2);
+ break;
+ case 18:
+ R2_GLOBALS._walkRegions.load(1571);
+ _field419 = 1571;
+ _actor16.subA4D14(2, 5);
+ _actor18.subA4D14(2, 6);
+ break;
+ case 19:
+ R2_GLOBALS._walkRegions.load(1571);
+ _field419 = 1571;
+ _actor16.subA4D14(2, 5);
+ _actor18.subA4D14(3, 6);
+ break;
+ default:
+ break;
+ }
+
+ int di = 0;
+ int tmpIdx = 0;
+ // Original game was checking "i < 129" but it was clearly a bug as it's out of bounds
+ for (int i = 0; i < 129 * 4; i += 4) {
+ if ((R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex] == k562CC[i]) && (R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex + 2] == k562CC[i + 1]) && (k562CC[i + 2] != 0)) {
+ tmpIdx = k562CC[i + 3];
+ _arrUnkObj15501[di].postInit();
+ _arrUnkObj15501[di]._effect = 6;
+ _arrUnkObj15501[di]._shade = 0;
+ _arrUnkObj15501[di]._fieldA4 = tmpIdx;
+ _arrUnkObj15501[di]._fieldA6 = i;
+ _arrUnkObj15501[di].setDetails(1550, 62, -1, 63, 2, (SceneItem *) NULL);
+ if (k562CC[i + 2] == 41) {
+ _arrUnkObj15501[di].changeZoom(-1);
+ _arrUnkObj15501[di].setPosition(Common::Point(150, 70));
+ _arrUnkObj15501[di].setup(1562, 1, 1);
+ R2_GLOBALS._walkRegions.enableRegion(k5A78C);
+ R2_GLOBALS._walkRegions.enableRegion(k5A78D);
+ R2_GLOBALS._walkRegions.enableRegion(k5A790);
+ R2_GLOBALS._walkRegions.enableRegion(k5A791);
+ if (R2_INVENTORY.getObjectScene(R2_JOYSTICK) == 1550) {
+ _actor9.postInit();
+ _actor9.setup(1562, 3, 1);
+ _actor9.setPosition(Common::Point(150, 70));
+ _actor9.fixPriority(10);
+ _actor9.setDetails(1550, 41, -1, 42, 2, (SceneItem *) NULL);
+ }
+ } else {
+ if (k562CC[i + 2] > 40) {
+ _arrUnkObj15501[di].changeZoom(100);
+ _arrUnkObj15501[di].setup(1561, 1, k562CC[i + 2] - 40);
+ } else {
+ _arrUnkObj15501[di].changeZoom(-1);
+ _arrUnkObj15501[di].setup(1552, ((k562CC[i + 2] - 1) / 5) + 1, ((k562CC[i + 2] - 1) % 5) + 1);
+ }
+ _arrUnkObj15501[di].setPosition(Common::Point(k5A72E[tmpIdx], k5A73F[tmpIdx]));
+ if (k5A78A[tmpIdx] != 0)
+ R2_GLOBALS._walkRegions.enableRegion(k5A78A[tmpIdx]);
+ di++;
+ }
+ }
+ }
+
+ for (int i = 0; i < 15 * 3; i++) {
+ if ((R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex] == k5A79B[i]) && (R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex + 2] == k5A79B[i + 1])) {
+ tmpIdx = k5A79B[i + 2];
+ switch (tmpIdx - 1) {
+ case 0:
+ if (!R2_GLOBALS.getFlag(16)) {
+ _actor1.postInit();
+ if (R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex + 2] == 3)
+ _actor1.setup(1555, 2, 1);
+ else
+ _actor1.setup(1555, 1, 1);
+ _actor1.setPosition(Common::Point(150, 100));
+ _actor1.fixPriority(92);
+ _actor1.setDetails(1550, 73, -1, -1, 2, (SceneItem *) NULL);
+ }
+ break;
+ case 1:
+ _actor13.postInit();
+ warning("_actor13._actorName = \"dish\";");
+ if (R2_GLOBALS.getFlag(19))
+ _actor13.setup(1556, 3, 5);
+ else
+ _actor13.setup(1556, 3, 1);
+ _actor13.changeZoom(95);
+ _actor13.setPosition(Common::Point(165, 83));
+ _actor13.fixPriority(168);
+ _actor13.setDetails(1550, 17, -1, 19, 2, (SceneItem *) NULL);
+
+ _actor12.postInit();
+ _actor12.setup(1556, 4, 1);
+ _actor12.setPosition(Common::Point(191, 123));
+ _actor12.changeZoom(95);
+ _actor12.setDetails(1550, 65, -1, 66, 2, (SceneItem *) NULL);
+
+ _actor5.postInit();
+ _actor5._numFrames = 5;
+ if (R2_GLOBALS.getFlag(19))
+ _actor5.setup(1556, 8, 5);
+ else
+ _actor5.setup(1556, 8, 1);
+
+ _actor5.setPosition(Common::Point(156, 151));
+ _actor5.fixPriority(10);
+
+ _actor4.postInit();
+ if (R2_GLOBALS.getFlag(20))
+ _actor4.setup(1558, 3, 10);
+ else
+ _actor4.setup(1558, 3, 1);
+
+ _actor4.setPosition(Common::Point(172, 48));
+ _actor4.fixPriority(169);
+ R2_GLOBALS._walkRegions.enableRegion(k5A78A[15]);
+ break;
+ case 2:
+ _actor6.postInit();
+ _actor6.setup(1550, 1, 1);
+ _actor6.setPosition(Common::Point(259, 55));
+ _actor6.fixPriority(133);
+ _actor6.setDetails(1550, 9, -1, -1, 2, (SceneItem *) NULL);
+
+ _actor1.postInit();
+ _actor1.setup(1550, 1, 2);
+ _actor1.setPosition(Common::Point(259, 133));
+ _actor1.fixPriority(105);
+ _actor1.setDetails(1550, 9, -1, -1, 2, (SceneItem *) NULL);
+ if (R2_INVENTORY.getObjectScene(R2_GYROSCOPE) == 1550) {
+ _actor10.postInit();
+ _actor10.setup(1550, 7, 2);
+ _actor10.setPosition(Common::Point(227, 30));
+ _actor10.fixPriority(130);
+ _actor10.setDetails(1550, 29, -1, 63, 2, (SceneItem *) NULL);
+ }
+ break;
+ case 3:
+ _actor6.postInit();
+ _actor6.setup(1550, 1, 4);
+ _actor6.setPosition(Common::Point(76, 131));
+ _actor6.fixPriority(10);
+ _actor6.setDetails(1550, 9, -1, -1, 2, (SceneItem *) NULL);
+
+ _actor1.postInit();
+ _actor1.setup(1550, 1, 3);
+ _actor1.setPosition(Common::Point(76, 64));
+ _actor1.setDetails(1550, 9, -1, -1, 2, (SceneItem *) NULL);
+ if (R2_INVENTORY.getObjectScene(R2_DIAGNOSTICS_DISPLAY) == 1550) {
+ _actor11.postInit();
+ _actor11.setup(1504, 4, 1);
+ _actor11.setPosition(Common::Point(49, 35));
+ _actor11.animate(ANIM_MODE_2, NULL);
+ _actor11._numFrames = 4;
+ _actor11.fixPriority(65);
+ _actor11.setDetails(1550, 14, 15, 63, 2, (SceneItem *) NULL);
+ }
+ if (R2_INVENTORY.getObjectScene(R2_AIRBAG) == 1550) {
+ _actor8.postInit();
+ _actor8.setup(1550, 7, 1);
+ _actor8.setPosition(Common::Point(45, 44));
+ _actor8.fixPriority(150);
+ _actor8.setDetails(1550, 44, -1, 63, 2, (SceneItem *) NULL);
+ }
+ break;
+ case 4:
+ _actor6.postInit();
+ _actor6.setup(1550, 2, 4);
+ _actor6.setPosition(Common::Point(243, 131));
+ _actor6.fixPriority(10);
+ _actor6.setDetails(1550, 9, -1, -1, 2, (SceneItem *) NULL);
+
+ _actor1.postInit();
+ _actor1.setup(1550, 2, 3);
+ _actor1.setPosition(Common::Point(243, 64));
+ _actor1.setDetails(1550, 9, -1, -1, 2, (SceneItem *) NULL);
+ break;
+ case 5:
+ _actor6.postInit();
+ _actor6.setup(1550, 2, 1);
+ _actor6.setPosition(Common::Point(60, 55));
+ _actor6.fixPriority(133);
+ _actor6.setDetails(1550, 9, -1, -1, 2, (SceneItem *) NULL);
+
+ _actor1.postInit();
+ _actor1.setup(1550, 2, 2);
+ _actor1.setPosition(Common::Point(60, 133));
+ _actor1.fixPriority(106);
+ _actor1.setDetails(1550, 9, -1, -1, 2, (SceneItem *) NULL);
+ break;
+ case 6:
+ _actor6.postInit();
+ _actor6.setup(1550, 3, 1);
+ _actor6.setPosition(Common::Point(281, 132));
+ _actor6.setDetails(1550, 56, -1, -1, 2, (SceneItem *) NULL);
+ break;
+ case 7:
+ _actor6.postInit();
+ _actor6.setup(1550, 3, 2);
+ _actor6.setPosition(Common::Point(57, 96));
+ _actor6.fixPriority(70);
+ _actor6.setDetails(1550, 56, -1, -1, 2, (SceneItem *) NULL);
+
+ _actor1.postInit();
+ _actor1.setup(1550, 3, 3);
+ _actor1.setPosition(Common::Point(145, 88));
+ _actor1.fixPriority(55);
+ _actor1.setDetails(1550, 56, -1, -1, 2, (SceneItem *) NULL);
+
+ _actor2.postInit();
+ _actor2.setup(1550, 3, 4);
+ _actor2.setPosition(Common::Point(64, 137));
+ _actor2.fixPriority(115);
+ _actor2.setDetails(1550, 56, -1, -1, 2, (SceneItem *) NULL);
+
+ _actor3.postInit();
+ _actor3.setup(1550, 5, 1);
+ _actor3.setPosition(Common::Point(60, 90));
+ _actor3.fixPriority(45);
+ break;
+ case 8:
+ _actor6.postInit();
+ _actor6.setup(1550, 4, 2);
+ _actor6.setPosition(Common::Point(262, 96));
+ _actor6.fixPriority(70);
+ _actor6.setDetails(1550, 56, -1, -1, 2, (SceneItem *) NULL);
+
+ _actor1.postInit();
+ _actor1.setup(1550, 4, 3);
+ _actor1.setPosition(Common::Point(174, 88));
+ _actor1.fixPriority(55);
+ _actor1.setDetails(1550, 56, -1, -1, 2, (SceneItem *) NULL);
+
+ _actor2.postInit();
+ _actor2.setup(1550, 4, 4);
+ _actor2.setPosition(Common::Point(255, 137));
+ _actor2.fixPriority(115);
+ _actor2.setDetails(1550, 56, -1, -1, 2, (SceneItem *) NULL);
+
+ _actor3.postInit();
+ _actor3.setup(1550, 6, 1);
+ _actor3.setPosition(Common::Point(259, 90));
+ _actor3.fixPriority(45);
+ break;
+ case 9:
+ _actor6.postInit();
+ _actor6.setup(1550, 4, 1);
+ _actor6.setPosition(Common::Point(38, 132));
+ _actor6.setDetails(1550, 56, -1, -1, 2, (SceneItem *) NULL);
+ break;
+ case 11:
+ _arrUnkObj15502[7].subA5CDF(8);
+ _arrUnkObj15502[0].subA5CDF(1);
+ _arrUnkObj15502[1].subA5CDF(2);
+ _arrUnkObj15502[2].subA5CDF(3);
+ _arrUnkObj15502[3].subA5CDF(4);
+ _arrUnkObj15502[4].subA5CDF(5);
+ _arrUnkObj15502[5].subA5CDF(6);
+ _arrUnkObj15502[6].subA5CDF(7);
+ default:
+ break;
+ }
+ }
+ }
+
+ if ((R2_GLOBALS._v565EC[1] == R2_GLOBALS._v565EC[2]) && (R2_GLOBALS._v565EC[3] == R2_GLOBALS._v565EC[4])) {
+ _actor7.postInit();
+ _actor7._effect = 7;
+ _actor7.changeZoom(-1);
+
+ assert((_field419 >= 1550) && (_field419 <= 2008));
+ R2_GLOBALS._walkRegions.enableRegion(k5A750[_field419 - 1550]);
+ _actor7.setPosition(Common::Point(k5A72E[k5A76D[_field419 - 1550]], k5A73F[k5A76D[_field419 - 1550]] + 8));
+ if (R2_GLOBALS._player._characterIndex == 1) {
+ if (R2_GLOBALS._player._characterScene[2] == 1580) {
+ _actor7.setup(1516, 3, 17);
+ _actor7.setPosition(Common::Point(272, 94));
+ _actor7.fixPriority(91);
+ _actor7.changeZoom(100);
+ _actor7.setDetails(1550, -1, -1, -1, 5, &_arrUnkObj15502[7]);
+ } else {
+ _actor7.setup(1505, 6, 1);
+ _actor7.setDetails(1550, -1, -1, -1, 2, (SceneItem *) NULL);
+ }
+ } else {
+ if (R2_GLOBALS._player._characterScene[1] == 1580) {
+ _actor7.setup(1516, 2, 14);
+ _actor7.setPosition(Common::Point(276, 97));
+ _actor7.fixPriority(91);
+ _actor7.changeZoom(100);
+ _actor7.setDetails(1550, -1, -1, -1, 5, &_arrUnkObj15502[7]);
+ } else {
+ _actor7.setup(1500, 6, 1);
+ _actor7.setDetails(1550, -1, -1, -1, 2, (SceneItem *) NULL);
+ }
+ }
+ }
+ R2_GLOBALS._uiElements.updateInventory();
+}
+
+/*--------------------------------------------------------------------------
+ * Scene 1575 -
+ *
+ *--------------------------------------------------------------------------*/
+Scene1575::Scene1575() {
+ _field412 = 0;
+ _field414 = 0;
+ _field416 = 0;
+ _field418 = 0;
+ _field41A = 0;
+}
+
+void Scene1575::synchronize(Serializer &s) {
+ SceneExt::synchronize(s);
+
+ s.syncAsSint16LE(_field412);
+ s.syncAsSint16LE(_field414);
+ s.syncAsSint16LE(_field416);
+ s.syncAsSint16LE(_field418);
+ s.syncAsSint16LE(_field41A);
+}
+
+Scene1575::Hotspot1::Hotspot1() {
+ _field34 = 0;
+ _field36 = 0;
+}
+
+void Scene1575::Hotspot1::synchronize(Serializer &s) {
+ NamedHotspot::synchronize(s);
+
+ s.syncAsSint16LE(_field34);
+ s.syncAsSint16LE(_field36);
+}
+
+void Scene1575::Hotspot1::process(Event &event) {
+ if ((event.eventType != EVENT_BUTTON_DOWN) || (R2_GLOBALS._events.getCursor() != R2_STEPPING_DISKS) || (!_bounds.contains(event.mousePos))) {
+ if (_field36 == 0)
+ return;
+ if ((_field34 == 1) || (event.eventType == EVENT_BUTTON_UP) || (!_bounds.contains(event.mousePos))) {
+ _field36 = 0;
+ return;
+ }
+ }
+ _field36 = 1;
+ Scene1575 *scene = (Scene1575 *)R2_GLOBALS._sceneManager._scene;
+
+ event.handled = true;
+ if (R2_GLOBALS.getFlag(18) && (_field34 > 1) && (_field34 < 6)) {
+ warning("sub1A03B(\"Better not move the laser while it\'s firing!\", 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);");
+ return;
+ }
+ int di = scene->_actor1._position.x;
+
+ switch (_field34 - 1) {
+ case 0:
+ if (R2_GLOBALS.getFlag(18)) {
+ scene->_actor14.hide();
+ scene->_actor15.hide();
+ R2_GLOBALS.clearFlag(18);
+ } else if ((scene->_actor12._position.x == 85) && (scene->_actor12._position.y == 123)) {
+ scene->_actor14.show();
+ scene->_actor15.show();
+ R2_GLOBALS.setFlag(18);
+ } else {
+ warning("sub1A03B(\"That\'s probably not a good thing, ya know!\", 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);");
+ }
+ break;
+ case 1:
+ if (scene->_field41A < 780) {
+ if (di > 54)
+ di -= 65;
+ di += 2;
+ scene->_field41A += 2;
+
+ for (int i = 0; i < 17; i++)
+ scene->_arrActor[i].setPosition(Common::Point(scene->_arrActor[i]._position.x + 2, scene->_arrActor[i]._position.y));
+
+ scene->_actor13.setPosition(Common::Point(scene->_actor13._position.x + 2, scene->_actor13._position.y));
+ scene->_actor12.setPosition(Common::Point(scene->_actor12._position.x + 2, scene->_actor12._position.y));
+ scene->_actor1.setPosition(Common::Point(di, scene->_actor1._position.y));
+ scene->_actor2.setPosition(Common::Point(di + 65, scene->_actor1._position.y));
+ scene->_actor3.setPosition(Common::Point(di + 130, scene->_actor1._position.y));
+ }
+ break;
+ case 2:
+ if (scene->_field41A > 0) {
+ if (di < -8)
+ di += 65;
+
+ di -= 2;
+ scene->_field41A -= 2;
+ for (int i = 0; i < 178; i++)
+ scene->_arrActor[i].setPosition(Common::Point(scene->_arrActor[i]._position.x - 2, scene->_arrActor[i]._position.y));
+
+ scene->_actor13.setPosition(Common::Point(scene->_actor13._position.x - 2, scene->_actor13._position.y));
+ scene->_actor12.setPosition(Common::Point(scene->_actor12._position.x - 2, scene->_actor12._position.y));
+ scene->_actor1.setPosition(Common::Point(di, scene->_actor1._position.y));
+ scene->_actor2.setPosition(Common::Point(di + 65, scene->_actor1._position.y));
+ scene->_actor3.setPosition(Common::Point(di + 130, scene->_actor1._position.y));
+ }
+ break;
+ case 3: {
+ int tmpPosY = scene->_actor1._position.y;
+ if (tmpPosY < 176) {
+ ++tmpPosY;
+ for (int i = 0; i < 17; ++i)
+ scene->_arrActor[i].setPosition(Common::Point(scene->_arrActor[i]._position.x, scene->_arrActor[i]._position.y + 1));
+
+ scene->_actor13.setPosition(Common::Point(scene->_actor13._position.x, scene->_actor13._position.y + 1));
+ scene->_actor12.setPosition(Common::Point(scene->_actor12._position.x, scene->_actor12._position.y + 1));
+ scene->_actor1.setPosition(Common::Point(di, scene->_actor1._position.y));
+ scene->_actor2.setPosition(Common::Point(di + 65, scene->_actor1._position.y));
+ scene->_actor3.setPosition(Common::Point(di + 130, scene->_actor1._position.y));
+ }
+ }
+ break;
+ case 4: {
+ int tmpPosY = scene->_actor1._position.y;
+ if (tmpPosY > 145) {
+ tmpPosY--;
+ for (int i = 0; i < 17; ++i)
+ scene->_arrActor[i].setPosition(Common::Point(scene->_arrActor[i]._position.x, scene->_arrActor[i]._position.y - 1));
+
+ scene->_actor13.setPosition(Common::Point(scene->_actor13._position.x, scene->_actor13._position.y - 1));
+ scene->_actor12.setPosition(Common::Point(scene->_actor12._position.x, scene->_actor12._position.y - 1));
+ scene->_actor1.setPosition(Common::Point(di, scene->_actor1._position.y));
+ scene->_actor2.setPosition(Common::Point(di + 65, scene->_actor1._position.y));
+ scene->_actor3.setPosition(Common::Point(di + 130, scene->_actor1._position.y));
+ }
+ }
+ break;
+ case 5:
+ R2_GLOBALS._sceneManager.changeScene(1550);
+ break;
+ default:
+ break;
+ }
+
+ int j = 0;
+ for (int i = 0; i < 17; i++) {
+ if (scene->_arrActor[i]._bounds.contains(85, 116))
+ j = i;
+ }
+
+ if (scene->_actor13._bounds.contains(85, 116))
+ j = 18;
+
+ if (scene->_actor12._bounds.contains(85, 116))
+ j = 19;
+
+ if (j)
+ scene->_actor11.show();
+ else
+ scene->_actor11.hide();
+}
+
+bool Scene1575::Hotspot1::startAction(CursorType action, Event &event) {
+ if (action == CURSOR_USE)
+ return false;
+ return SceneHotspot::startAction(action, event);
+}
+
+void Scene1575::Hotspot1::subA910D(int indx) {
+ warning("STUB: Scene1575:Hotspot1::subA910D(%d)", indx);
+}
+
+void Scene1575::postInit(SceneObjectList *OwnerList) {
+ loadScene(1575);
+ R2_GLOBALS._uiElements._active = false;
+ R2_GLOBALS._v5589E = Rect(0, 0, 320, 200);
+ SceneExt::postInit();
+ _field414 = 390;
+
+ _actor1.postInit();
+ _actor1.setup(1575, 1, 1);
+ _actor1.setPosition(Common::Point(54, 161));
+ _actor1.fixPriority(5);
+
+ _actor2.postInit();
+ _actor2.setup(1575, 1, 1);
+ _actor2.setPosition(Common::Point(119, 161));
+ _actor2.fixPriority(5);
+
+ _actor3.postInit();
+ _actor3.setup(1575, 1, 1);
+ _actor3.setPosition(Common::Point(184, 161));
+ _actor3.fixPriority(5);
+
+ for (int i = 0; i < 17; i++) {
+ _arrActor[i].postInit();
+ _arrActor[i].setup(1575, 2, k5A7F6[(3 * i) + 2]);
+ warning("TODO: immense pile of floating operations");
+ _arrActor[i].fixPriority(6);
+ }
+
+ _actor4.postInit();
+ _actor4.setup(1575, 3, 1);
+ _actor4.setPosition(Common::Point(48, 81));
+
+ _actor5.postInit();
+ _actor5.setup(1575, 3,1);
+ _actor5.setPosition(Common::Point(121, 81));
+
+ _actor6.postInit();
+ _actor6.setup(1575, 3, 2);
+ _actor6.setPosition(Common::Point(203, 80));
+
+ _actor7.postInit();
+ _actor7.setup(1575, 3, 2);
+ _actor7.setPosition(Common::Point(217, 80));
+
+ _actor8.postInit();
+ _actor8.setup(1575, 3, 2);
+ _actor8.setPosition(Common::Point(231, 80));
+
+ _actor9.postInit();
+ _actor9.setup(1575, 3, 2);
+ _actor9.setPosition(Common::Point(273, 91));
+
+ _actor10.postInit();
+ _actor10.setup(1575, 3, 2);
+ _actor10.setPosition(Common::Point(287, 91));
+
+ _item1.subA910D(1);
+ _item1.subA910D(2);
+ _item1.subA910D(3);
+ _item1.subA910D(4);
+ _item1.subA910D(5);
+ _item1.subA910D(6);
+
+ _actor11.postInit();
+ _actor11.setup(1575, 4, 2);
+ _actor11.setPosition(Common::Point(84, 116));
+ _actor11.hide();
+
+ R2_GLOBALS._player.postInit();
+ R2_GLOBALS._player.hide();
+ R2_GLOBALS._player.enableControl();
+
+ do {
+ _field412 = R2_GLOBALS._randomSource.getRandomNumber(20) - 10;
+ _field414 = R2_GLOBALS._randomSource.getRandomNumber(20) - 10;
+ } while ((_field412) && (_field414));
+
+ if (_field412 < 0)
+ _actor4.hide();
+
+ if (_field414 < 0)
+ _actor5.hide();
+
+ _field416 = R2_GLOBALS._randomSource.getRandomNumber(4) + 1;
+ _field418 = R2_GLOBALS._randomSource.getRandomNumber(4) + 1;
+
+ _actor13.postInit();
+ _actor13.setup(1575, 2, 4);
+
+ warning("TODO: another immense pile of floating operations");
+
+ _actor12.postInit();
+ _actor12.fixPriority(12);
+
+ if (R2_GLOBALS.getFlag(17)) {
+ _actor13.setPosition(Common::Point(_actor13._position.x + 5, _actor13._position.y));
+ _actor12.setPosition(Common::Point(_actor12._position.x + 5, _actor12._position.y));
+ }
+
+ _actor14.postInit();
+ _actor14.setup(1575, 5, 1);
+ _actor14.setPosition(Common::Point(85, 176));
+ _actor14.fixPriority(7);
+ _actor14.hide();
+
+ _actor15.postInit();
+ _actor15.setup(1575, 5, 2);
+ _actor15.setPosition(Common::Point(85, 147));
+ _actor15.fixPriority(7);
+ _actor15.hide();
+}
+
+void Scene1575::remove() {
+ SceneExt::remove();
+ R2_GLOBALS._v5589E.top = 3;
+ R2_GLOBALS._v5589E.bottom = 168;
+ R2_GLOBALS._uiElements._active = true;
+}
+
+void Scene1575::signal() {
+ R2_GLOBALS._player.enableControl();
+}
+
+void Scene1575::process(Event &event) {
+ Scene::process(event);
+
+ g_globals->_sceneObjects->recurse(SceneHandler::dispatchObject);
+ warning("TODO: check Scene1575::process");
+}
+
+void Scene1575::dispatch() {
+ if (_field412 <= 0) {
+ ++_field412;
+ if (_field412 == 0) {
+ _actor4.show();
+ _field412 = R2_GLOBALS._randomSource.getRandomNumber(9) + 1;
+ }
+ } else {
+ _field412--;
+ if (_field412 ==0) {
+ _actor4.hide();
+ _field412 = R2_GLOBALS._randomSource.getRandomNumber(9) + 1;
+ }
+ }
+
+ if (_field414 <= 0) {
+ ++_field414;
+ if (_field414 == 0) {
+ _actor5.show();
+ _field414 = R2_GLOBALS._randomSource.getRandomNumber(9) + 1;
+ }
+ } else {
+ _field414--;
+ if (_field414 == 0) {
+ _actor5.hide();
+ _field414 = R2_GLOBALS._randomSource.getRandomNumber(9) + 1;
+ }
+ }
+
+ if (_field416 == 0) {
+ switch(R2_GLOBALS._randomSource.getRandomNumber(3)) {
+ case 0:
+ _actor6.hide();
+ _actor7.hide();
+ _actor8.hide();
+ break;
+ case 1:
+ _actor6.show();
+ _actor7.hide();
+ _actor8.hide();
+ break;
+ case 2:
+ _actor6.show();
+ _actor7.show();
+ _actor8.hide();
+ break;
+ case 3:
+ _actor6.show();
+ _actor7.show();
+ _actor8.show();
+ break;
+ default:
+ break;
+ }
+ _field416 = R2_GLOBALS._randomSource.getRandomNumber(4) + 1;
+ } else {
+ --_field416;
+ }
+
+ if (_field418 == 0) {
+ switch(R2_GLOBALS._randomSource.getRandomNumber(2)) {
+ case 0:
+ _actor9.hide();
+ _actor10.hide();
+ break;
+ case 1:
+ _actor9.show();
+ _actor10.hide();
+ break;
+ case 2:
+ _actor9.show();
+ _actor10.show();
+ break;
+ default:
+ break;
+ }
+ _field418 = R2_GLOBALS._randomSource.getRandomNumber(4) + 1;
+ } else {
+ _field418--;
+ }
+ Scene::dispatch();
+}
+
+/*--------------------------------------------------------------------------
+ * Scene 1580 - Inside wreck
+ *
+ *--------------------------------------------------------------------------*/
+Scene1580::Scene1580() {
+ _field412 = 0;
+}
+
+void Scene1580::synchronize(Serializer &s) {
+ SceneExt::synchronize(s);
+
+ s.syncAsSint16LE(_field412);
+}
+
+bool Scene1580::Hotspot1::startAction(CursorType action, Event &event) {
+ Scene1580 *scene = (Scene1580 *)R2_GLOBALS._sceneManager._scene;
+
+ if (action == R2_JOYSTICK) {
+ R2_INVENTORY.setObjectScene(26, 1580);
+ R2_GLOBALS._sceneItems.remove(&scene->_item1);
+ scene->_actor2.postInit();
+ scene->_actor2.setup(1580, 1, 4);
+ scene->_actor2.setPosition(Common::Point(159, 163));
+ scene->_actor2.setDetails(1550, 78, -1, -1, 2, (SceneItem *) NULL);
+
+ scene->_arrActor[5].remove();
+
+ return true;
+ }
+
+ return SceneHotspot::startAction(action, event);
+}
+
+bool Scene1580::Hotspot2::startAction(CursorType action, Event &event) {
+ Scene1580 *scene = (Scene1580 *)R2_GLOBALS._sceneManager._scene;
+
+ if (action == R2_DIAGNOSTICS_DISPLAY) {
+ R2_INVENTORY.setObjectScene(28, 1580);
+ R2_GLOBALS._player.disableControl();
+ R2_GLOBALS._sceneItems.remove(&scene->_item2);
+
+ scene->_actor3.postInit();
+ scene->_actor3.setup(1580, 1, 1);
+ scene->_actor3.setPosition(Common::Point(124, 108));
+ scene->_actor3.fixPriority(10);
+
+ if (R2_INVENTORY.getObjectScene(26) == 1580)
+ scene->_actor3.setDetails(1550, 14, -1, -1, 5, &scene->_actor2);
+ else
+ scene->_actor3.setDetails(1550, 14, -1, -1, 2, (SceneItem *)NULL);
+
+ scene->_actor1.postInit();
+ scene->_actor1.setup(1580, 3, 1);
+ scene->_actor1.setPosition(Common::Point(124, 109));
+ scene->_actor1.fixPriority(20);
+ scene->_field412 = 1;
+ scene->_sceneMode = 10;
+ scene->setAction(&scene->_sequenceManager, scene, 1, &R2_GLOBALS._player, NULL);
+
+ return true;
+ }
+
+ return SceneHotspot::startAction(action, event);
+}
+
+bool Scene1580::Actor2::startAction(CursorType action, Event &event) {
+ if ( (action == CURSOR_USE) && (R2_INVENTORY.getObjectScene(28) == 1580)
+ && (R2_INVENTORY.getObjectScene(17) == 0) && (R2_INVENTORY.getObjectScene(22) == 0)
+ && (R2_INVENTORY.getObjectScene(25) == 0) && (R2_INVENTORY.getObjectScene(18) == 0)
+ && (R2_INVENTORY.getObjectScene(23) == 0) && (R2_INVENTORY.getObjectScene(27) == 0)) {
+ Scene1580 *scene = (Scene1580 *)R2_GLOBALS._sceneManager._scene;
+ scene->_sceneMode = 31;
+ R2_GLOBALS._player.disableControl();
+ R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
+ if (R2_GLOBALS._player._characterIndex == 1)
+ scene->_stripManager.start(536, scene);
+ else
+ scene->_stripManager.start(537, scene);
+
+ return true;
+ }
+
+ return SceneActor::startAction(action, event);
+}
+
+bool Scene1580::Actor3::startAction(CursorType action, Event &event) {
+ if ((action == CURSOR_USE) && (R2_INVENTORY.getObjectScene(51) == 1580)) {
+ Scene1580 *scene = (Scene1580 *)R2_GLOBALS._sceneManager._scene;
+
+ R2_INVENTORY.setObjectScene(51, R2_GLOBALS._player._characterIndex);
+ scene->_item2.setDetails(Rect(69, 29, 177, 108), 1550, 82, -1, -1, 2, NULL);
+ scene->_actor1.remove();
+ remove();
+ return true;
+ }
+
+ return SceneActor::startAction(action, event);
+}
+
+bool Scene1580::Actor4::startAction(CursorType action, Event &event) {
+ if (action != CURSOR_USE)
+ return SceneActor::startAction(action, event);
+
+ Scene1580 *scene = (Scene1580 *)R2_GLOBALS._sceneManager._scene;
+
+ R2_GLOBALS._player.disableControl();
+ R2_GLOBALS._sceneItems.remove(&scene->_actor4);
+ scene->_sceneMode = 0;
+ animate(ANIM_MODE_5, scene);
+
+ return true;
+}
+
+bool Scene1580::Actor5::startAction(CursorType action, Event &event) {
+ if (action != CURSOR_USE)
+ return SceneActor::startAction(action, event);
+
+ Scene1580 *scene = (Scene1580 *)R2_GLOBALS._sceneManager._scene;
+
+ R2_GLOBALS._player.disableControl();
+ setFrame(2);
+ scene->_sceneMode = 20;
+ scene->setAction(&scene->_sequenceManager, scene, 2, &R2_GLOBALS._player, NULL);
+
+ return true;
+}
+
+bool Scene1580::Actor6::startAction(CursorType action, Event &event) {
+ Scene1580 *scene = (Scene1580 *)R2_GLOBALS._sceneManager._scene;
+
+ switch (action) {
+ case CURSOR_USE:
+ if (R2_GLOBALS._player._characterIndex == 1) {
+ R2_INVENTORY.setObjectScene(23, 1);
+ remove();
+ return true;
+ }
+ break;
+ case R2_COM_SCANNER:
+ scene->_sceneMode = 30;
+ R2_GLOBALS._player.disableControl();
+ R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
+ scene->_stripManager.start(529, scene);
+ return true;
+ break;
+ case R2_COM_SCANNER_2:
+ scene->_sceneMode = 30;
+ R2_GLOBALS._player.disableControl();
+ R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
+ scene->_stripManager.start(527, scene);
+ return true;
+ break;
+ default:
+ break;
+ }
+
+ return SceneActor::startAction(action, event);
+}
+
+bool Scene1580::Actor7::startAction(CursorType action, Event &event) {
+ Scene1580 *scene = (Scene1580 *)R2_GLOBALS._sceneManager._scene;
+
+ switch (action) {
+ case CURSOR_USE:
+ if (R2_GLOBALS._player._characterIndex == 1) {
+ R2_INVENTORY.setObjectScene(27, 1);
+ remove();
+ return true;
+ }
+ break;
+ case R2_COM_SCANNER:
+ scene->_sceneMode = 30;
+ R2_GLOBALS._player.disableControl();
+ R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
+ scene->_stripManager.start(529, scene);
+ return true;
+ break;
+ case R2_COM_SCANNER_2:
+ scene->_sceneMode = 30;
+ R2_GLOBALS._player.disableControl();
+ R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
+ scene->_stripManager.start(527, scene);
+ return true;
+ break;
+ default:
+ break;
+ }
+
+ return SceneActor::startAction(action, event);
+}
+
+void Scene1580::postInit(SceneObjectList *OwnerList) {
+ loadScene(1580);
+ R2_GLOBALS._sceneManager._fadeMode = FADEMODE_GRADUAL;
+ SceneExt::postInit();
+ _field412 = 0;
+
+ _stripManager.setColors(60, 255);
+ _stripManager.setFontNumber(3);
+ _stripManager.addSpeaker(&_quinnSpeaker);
+ _stripManager.addSpeaker(&_seekerSpeaker);
+
+ _sceneMode = 0;
+
+ R2_GLOBALS._player.disableControl();
+ if (R2_INVENTORY.getObjectScene(26) == 1580) {
+ _actor2.postInit();
+ _actor2.setup(1580, 1, 4);
+ _actor2.setPosition(Common::Point(159, 163));
+ _actor2.setDetails(1550, 78, -1, -1, 1, (SceneItem *) NULL);
+ } else {
+ _item1.setDetails(Rect(141, 148, 179, 167), 1550, 79, -1, -1, 1, NULL);
+ }
+
+ if (R2_INVENTORY.getObjectScene(51) == 1580) {
+ _actor3.postInit();
+ _actor3.setup(1580, 1, 1);
+ _actor3.setPosition(Common::Point(124, 108));
+ _actor3.fixPriority(10);
+ _actor3.setDetails(1550, 13, -1, -1, 1, (SceneItem *) NULL);
+
+ _actor1.postInit();
+ _actor1.setup(1580, 1, 3);
+ _actor1.setPosition(Common::Point(124, 96));
+ _actor1.fixPriority(20);
+ } else if (R2_INVENTORY.getObjectScene(28) == 1580) {
+ _actor3.postInit();
+ _actor3.setup(1580, 1, 1);
+ _actor3.setPosition(Common::Point(124, 108));
+ _actor3.fixPriority(10);
+ _actor3.setDetails(1550, 14, -1, -1, 1, (SceneItem *) NULL);
+
+ _actor1.postInit();
+ _actor1.setup(1580, 3, 1);
+ _actor1.setPosition(Common::Point(124, 109));
+ _actor1.fixPriority(20);
+
+ _sceneMode = 10;
+ } else {
+ _item2.setDetails(Rect(69, 29, 177, 108), 1550, 82, -1, -1, 1, NULL);
+ }
+
+ _actor4.postInit();
+ if (R2_INVENTORY.getObjectScene(58) == 0) {
+ _actor4.setup(1580, 5, 1);
+ _actor4.setDetails(1550, 80, -1, -1, 1, (SceneItem *) NULL);
+ } else {
+ _actor4.setup(1580, 5, 6);
+ }
+
+ _actor4.setPosition(Common::Point(216, 108));
+ _actor4.fixPriority(100);
+
+ _actor5.postInit();
+ _actor5.setup(1580, 4, 1);
+ _actor5.setPosition(Common::Point(291, 147));
+ _actor5.fixPriority(100);
+ _actor5.setDetails(1550, 81, -1, -1, 1, (SceneItem *) NULL);
+
+ if (R2_INVENTORY.getObjectScene(23) == 1580) {
+ _actor6.postInit();
+ _actor6.setup(1580, 6, 2);
+ _actor6.setPosition(Common::Point(222, 108));
+ _actor6.fixPriority(50);
+ _actor6.setDetails(1550, 32, -1, 34, 1, (SceneItem *) NULL);
+ }
+
+ if (R2_INVENTORY.getObjectScene(27) == 1580) {
+ _actor7.postInit();
+ _actor7.setup(1580, 6, 1);
+ _actor7.setPosition(Common::Point(195, 108));
+ _actor7.fixPriority(50);
+ _actor7.setDetails(1550, 38, -1, 34, 1, (SceneItem *) NULL);
+ }
+
+ R2_GLOBALS._player.postInit();
+ R2_GLOBALS._player._oldCharacterScene[R2_GLOBALS._player._characterIndex] = 1580;
+ R2_GLOBALS._player.hide();
+ setAction(&_sequenceManager, this, 1, &R2_GLOBALS._player, NULL);
+ _item3.setDetails(Rect(0, 0, 320, 200), 1550, 50, -1, -1, 1, NULL);
+
+}
+
+void Scene1580::signal() {
+ switch (_sceneMode++) {
+ case 10:
+ _actor1.animate(ANIM_MODE_5, this);
+ break;
+ case 11:
+ _actor1.setup(1580, 1, 2);
+ _actor1.setPosition(Common::Point(124, 94));
+
+ if (R2_INVENTORY.getObjectScene(18) != 0) {
+ _arrActor[0].postInit();
+ _arrActor[0].setup(1580, 2, 1);
+ _arrActor[0].setPosition(Common::Point(138, 56));
+ }
+
+ if (R2_INVENTORY.getObjectScene(25) != 0) {
+ _arrActor[1].postInit();
+ _arrActor[1].setup(1580, 2, 2);
+ _arrActor[1].setPosition(Common::Point(140, 66));
+ }
+
+ if (R2_INVENTORY.getObjectScene(27) != 0) {
+ _arrActor[2].postInit();
+ _arrActor[2].setup(1580, 2, 3);
+ _arrActor[2].setPosition(Common::Point(142, 85));
+ }
+
+ if (R2_INVENTORY.getObjectScene(23) != 0) {
+ _arrActor[3].postInit();
+ _arrActor[3].setup(1580, 2, 4);
+ _arrActor[3].setPosition(Common::Point(142, 92));
+ }
+
+ if (R2_INVENTORY.getObjectScene(22) != 0) {
+ _arrActor[4].postInit();
+ _arrActor[4].setup(1580, 2, 5);
+ _arrActor[4].setPosition(Common::Point(108, 54));
+ }
+
+ if (R2_INVENTORY.getObjectScene(26) != 0) {
+ _arrActor[5].postInit();
+ _arrActor[5].setup(1580, 2, 6);
+ _arrActor[5].setPosition(Common::Point(110, 64));
+ }
+
+ if (R2_INVENTORY.getObjectScene(45) != 0) {
+ _arrActor[6].postInit();
+ _arrActor[6].setup(1580, 2, 7);
+ _arrActor[6].setPosition(Common::Point(108, 80));
+ }
+
+ if (R2_INVENTORY.getObjectScene(17) != 0) {
+ _arrActor[7].postInit();
+ _arrActor[7].setup(1580, 2, 8);
+ _arrActor[7].setPosition(Common::Point(111, 92));
+ }
+
+ R2_GLOBALS._player.enableControl(CURSOR_USE);
+ R2_GLOBALS._player._canWalk = false;
+ break;
+ case 20:
+ R2_GLOBALS._sceneManager.changeScene(1550);
+ break;
+ case 31:
+ R2_GLOBALS._sceneManager.changeScene(1530);
+ break;
+ default:
+ R2_GLOBALS._player.enableControl(CURSOR_USE);
+ R2_GLOBALS._player._canWalk = false;
+ break;
+ }
+}
+
+/*--------------------------------------------------------------------------
+ * Scene 1625 - Miranda being questioned
+ *
+ *--------------------------------------------------------------------------*/
+Scene1625::Scene1625() {
+ _field412 = 0;
+}
+
+void Scene1625::synchronize(Serializer &s) {
+ SceneExt::synchronize(s);
+
+ s.syncAsSint16LE(_field412);
+}
+
+bool Scene1625::Actor7::startAction(CursorType action, Event &event) {
+ if (action != CURSOR_USE)
+ return SceneActor::startAction(action, event);
+
+ Scene1625 *scene = (Scene1625 *)R2_GLOBALS._sceneManager._scene;
+ R2_GLOBALS._player.disableControl();
+
+ scene->_sceneMode = 1631;
+ scene->_actor3.postInit();
+ scene->setAction(&scene->_sequenceManager, scene, 1631, &scene->_actor3, &scene->_actor7, NULL);
+ return true;
+}
+
+void Scene1625::postInit(SceneObjectList *OwnerList) {
+ loadScene(1625);
+ R2_GLOBALS._player._characterIndex = R2_MIRANDA;
+ SceneExt::postInit();
+
+ _stripManager.addSpeaker(&_mirandaSpeaker);
+ _stripManager.addSpeaker(&_tealSpeaker);
+ _stripManager.addSpeaker(&_soldierSpeaker);
+
+ R2_GLOBALS._player.postInit();
+
+ _actor7.postInit();
+ _actor7.setup(1626, 2, 1);
+ _actor7.setPosition(Common::Point(206, 133));
+ _actor7.setDetails(1625, 0, -1, -1, 1, (SceneItem *) NULL);
+
+ _actor5.postInit();
+ _actor5.setup(1625, 8, 1);
+ _actor5.setPosition(Common::Point(190, 131));
+ _actor5.setDetails(1625, 6, -1, 2, 1, (SceneItem *) NULL);
+
+ if (R2_GLOBALS._player._oldCharacterScene[3] == 1625) {
+ if (!R2_GLOBALS.getFlag(83)) {
+ _actor4.postInit();
+ _actor4.setup(1626, 4, 1);
+ _actor4.setPosition(Common::Point(96, 166));
+ _actor4.setDetails(1625, -1, -1, -1, 1, (SceneItem *) NULL);
+ }
+ R2_GLOBALS._player.enableControl();
+ R2_GLOBALS._player._canWalk = false;
+ } else {
+ _actor1.postInit();
+ _actor1.fixPriority(10);
+
+ _actor6.postInit();
+
+ R2_GLOBALS._player.disableControl();
+ _sceneMode = 1625;
+ setAction(&_sequenceManager, this, 1625, &_actor1, &_actor6, NULL);
+ }
+
+ R2_GLOBALS._sound1.play(245);
+ _item1.setDetails(Rect(0, 0, 320, 200), 1625, 12, -1, -1, 1, NULL);
+ R2_GLOBALS._player._oldCharacterScene[3] = 1625;
+ R2_GLOBALS._player._characterScene[3] = 1625;
+}
+
+void Scene1625::remove() {
+ R2_GLOBALS._sound1.fadeOut2(NULL);
+ SceneExt::remove();
+}
+
+void Scene1625::signal() {
+ switch (_sceneMode) {
+ case 10:
+ R2_GLOBALS._player.disableControl();
+ _actor4.postInit();
+ _actor4.setDetails(1625, -1, -1, -1, 2, (SceneItem *) NULL);
+ _sceneMode = 1626;
+ setAction(&_sequenceManager, this, 1626, &_actor2, &_actor4, NULL);
+ break;
+ case 12:
+ // TODO: check if OK_BTN_STRING is required
+ MessageDialog::show(DONE_MSG, OK_BTN_STRING);
+ break;
+ case 14:
+ _actor2.postInit();
+ _actor2.setup(1627, 1, 1);
+ _actor2.setPosition(Common::Point(68, 68));
+ _sceneMode = 99;
+ R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
+ _stripManager.start(831, this);
+ break;
+ case 99:
+ R2_GLOBALS._player.disableControl();
+ switch (_stripManager._field2E8) {
+ case 0:
+ _sceneMode = 1627;
+ setAction(&_sequenceManager, this, 1627, &_actor3, &_actor4, NULL);
+ break;
+ case 1:
+ _sceneMode = 1629;
+ setAction(&_sequenceManager, this, 1629, &_actor2, &_actor5, NULL);
+ break;
+ case 3:
+ R2_GLOBALS._player._oldCharacterScene[3] = 3150;
+ R2_GLOBALS._player._characterScene[3] = 3150;
+ R2_GLOBALS._player._characterIndex = R2_QUINN;
+ R2_GLOBALS._sceneManager.changeScene(R2_GLOBALS._player._characterScene[1]);
+ break;
+ case 4:
+ _sceneMode = 1628;
+ _actor2.remove();
+ setAction(&_sequenceManager, this, 1628, &_actor3, &_actor4, NULL);
+ break;
+ case 5:
+ _actor4.postInit();
+ _actor4.setDetails(1625, -1, -1, -1, 2, (SceneItem *) NULL);
+ _sceneMode = 1632;
+ setAction(&_sequenceManager, this, 1632, &_actor4, NULL);
+ break;
+ case 6:
+ _sceneMode = 1633;
+ setAction(&_sequenceManager, this, 1633, &_actor4, NULL);
+ break;
+ case 7:
+ _sceneMode = 1635;
+ setAction(&_sequenceManager, this, 1635, &_actor3, &_actor5, NULL);
+ break;
+ case 8:
+ _actor4.postInit();
+ _actor4.setDetails(1625, -1, -1, -1, 2, (SceneItem *) NULL);
+ _sceneMode = 1634;
+ setAction(&_sequenceManager, this, 1634, &_actor3, &_actor5, NULL);
+ break;
+ case 2:
+ // No break on purpose
+ default:
+ _sceneMode = 1630;
+ _actor2.postInit();
+ setAction(&_sequenceManager, this, 1630, &_actor1, &_actor6, NULL);
+ break;
+ }
+ _field412 = _stripManager._field2E8;
+ _stripManager._field2E8 = 0;
+ break;
+ case 1625:
+ _actor2.postInit();
+ _actor2.setup(1627, 1, 1);
+ _actor2.setPosition(Common::Point(68, 68));
+ _sceneMode = 10;
+ R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
+ _stripManager.start(800, this);
+ break;
+ case 1626:
+ _actor2.setup(1627, 1, 1);
+ _actor2.setPosition(Common::Point(68, 68));
+ _actor2.show();
+
+ _actor3.postInit();
+ _actor3.setup(1627, 3, 1);
+ _actor3.setPosition(Common::Point(196, 65));
+
+ _sceneMode = 99;
+ R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
+ _stripManager.start(832, this);
+ break;
+ case 1627:
+ _actor3.setup(1627, 3, 1);
+ _actor3.setPosition(Common::Point(196, 65));
+ _actor3.show();
+
+ _sceneMode = 99;
+ R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
+ _stripManager.start(833, this);
+ break;
+ case 1628:
+ R2_GLOBALS.setFlag(83);
+ _actor2.postInit();
+ _actor2.setup(1627, 1, 1);
+ _actor2.setPosition(Common::Point(68, 68));
+
+ _actor3.setup(1627, 3, 1);
+ _actor3.setPosition(Common::Point(196, 65));
+ _actor3.show();
+
+ _sceneMode = 99;
+ R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
+ _stripManager.start(834, this);
+ break;
+ case 1629:
+ _actor2.setup(1627, 1, 1);
+ _actor2.setPosition(Common::Point(68, 68));
+ _actor2.show();
+
+ _sceneMode = 99;
+ R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
+ _stripManager.start(805, this);
+ break;
+ case 1630:
+ R2_GLOBALS._player.enableControl(CURSOR_USE);
+ R2_GLOBALS._player._canWalk = true;
+ break;
+ case 1631:
+ _actor3.setup(1627, 3, 1);
+ _actor3.setPosition(Common::Point(196, 65));
+ _actor3.show();
+
+ _actor7.remove();
+
+ _actor1.postInit();
+ _actor1.fixPriority(10);
+
+ _actor6.postInit();
+ warning("_actor6._actorName = \"arm\";");
+
+ R2_INVENTORY.setObjectScene(40, 3);
+ _sceneMode = 14;
+
+ setAction(&_sequenceManager, this, 1625, &_actor1, &_actor6, NULL);
+ break;
+ case 1632:
+ _actor2.setup(1627, 1, 1);
+ _actor2.setPosition(Common::Point(68, 68));
+ _actor2.show();
+
+ _sceneMode = 99;
+ R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
+ _stripManager.start(835, this);
+ break;
+ case 1633:
+ _actor4.remove();
+ _sceneMode = 99;
+ R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
+ _stripManager.start(818, this);
+ break;
+ case 1634:
+ _sceneMode = 99;
+ R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
+ _stripManager.start(836, this);
+ break;
+ case 1635:
+ _actor3.setup(1627, 3, 1);
+ _actor3.setPosition(Common::Point(196, 65));
+ _actor3.show();
+
+ _sceneMode = 99;
+ R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
+ _stripManager.start(818, this);
+ break;
+ default:
+ break;
+ }
+}
+
+void Scene1625::process(Event &event) {
+ if ((event.eventType == EVENT_KEYPRESS) && (event.kbd.keycode == Common::KEYCODE_ESCAPE))
+ event.handled = true;
+ else
+ Scene::process(event);
+}
+
+/*--------------------------------------------------------------------------
+ * Scene 1700 -
+ *
+ *--------------------------------------------------------------------------*/
+Scene1700::Scene1700() {
+ _field77A = 0;
+ _field77C = 0;
+}
+
+void Scene1700::synchronize(Serializer &s) {
+ SceneExt::synchronize(s);
+
+ s.syncAsSint16LE(_field77A);
+ s.syncAsSint16LE(_field77C);
+}
+
+bool Scene1700::Item2::startAction(CursorType action, Event &event) {
+ // The original contains a debug trace. It's currently skipped.
+ // TODO: either add the debug trace, or remove this function and associated class
+ return SceneHotspot::startAction(action, event);
+}
+
+bool Scene1700::Actor11::startAction(CursorType action, Event &event) {
+ if (action != CURSOR_USE)
+ return SceneActor::startAction(action, event);
+
+ Scene1700 *scene = (Scene1700 *)R2_GLOBALS._sceneManager._scene;
+
+ R2_GLOBALS._player.disableControl();
+ R2_GLOBALS._v558B6.set(80, 0, 240, 200);
+ scene->_sceneMode = 4;
+
+ Common::Point pt(271, 90);
+ PlayerMover *mover = new PlayerMover();
+ R2_GLOBALS._player.addMover(mover, &pt, scene);
+
+ return true;
+}
+
+bool Scene1700::Actor12::startAction(CursorType action, Event &event) {
+ if (action != CURSOR_TALK)
+ return SceneActor::startAction(action, event);
+
+ Scene1700 *scene = (Scene1700 *)R2_GLOBALS._sceneManager._scene;
+ scene->_sceneMode = 30;
+ scene->signal();
+
+ return true;
+}
+
+void Scene1700::Exit1::changeScene() {
+ Scene1700 *scene = (Scene1700 *)R2_GLOBALS._sceneManager._scene;
+
+ R2_GLOBALS._player.disableControl();
+ _moving = false;
+ scene->_sceneMode = 1;
+
+ Common::Point pt(R2_GLOBALS._player._position.x, 0);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, scene);
+}
+
+void Scene1700::Exit2::changeScene() {
+ Scene1700 *scene = (Scene1700 *)R2_GLOBALS._sceneManager._scene;
+
+ R2_GLOBALS._player.disableControl();
+ _moving = false;
+ scene->_sceneMode = 2;
+
+ Common::Point pt(R2_GLOBALS._player._position.x, 170);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, scene);
+}
+
+void Scene1700::Exit3::changeScene() {
+ Scene1700 *scene = (Scene1700 *)R2_GLOBALS._sceneManager._scene;
+
+ R2_GLOBALS._player.disableControl();
+ _moving = false;
+ scene->_sceneMode = 6;
+
+ Common::Point pt(0, R2_GLOBALS._player._position.y);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, scene);
+}
+
+void Scene1700::subAF3F8() {
+ Rect tmpRect;
+ R2_GLOBALS._walkRegions.load(1700);
+
+ _actor3.remove();
+ _actor4.remove();
+ _actor5.remove();
+ _actor6.remove();
+ _actor7.remove();
+ _actor8.remove();
+ _actor11.remove();
+
+ if (_sceneMode != 40) {
+ _actor9.remove();
+ _actor10.remove();
+ }
+
+ warning("tmpRect = _v5589E;");
+ warning("Mouse_hideIfNeeded");
+ warning("set_pane_p(_paneNumber);");
+ warning("Big loop calling gfx_draw_slice_p");
+
+ if (_field77A == 0)
+ _field77A = 1;
+ else
+ _field77A = 0;
+
+ warning("set_pane_p(_paneNumber);");
+
+ if ((_sceneMode != 40) && (R2_GLOBALS._v565F6 != 0)){
+ _actor9.postInit();
+ _actor9.setup(1701, 1, 1);
+ _actor9.setPosition(Common::Point(220, 137));
+ _actor9.setDetails(1700, 6, -1, -1, 2, (SceneItem *) NULL);
+ R2_GLOBALS._walkRegions.enableRegion(2);
+ R2_GLOBALS._walkRegions.enableRegion(12);
+ }
+
+ if ((R2_GLOBALS._v565F6 + 2) % 4 == 0) {
+ _actor3.postInit();
+ _actor3.setup(1700, 1, 1);
+ _actor3.setPosition(Common::Point(222, 82));
+ _actor3.setDetails(100, -1, -1, -1, 2, (SceneItem *) NULL);
+
+ _actor5.postInit();
+ _actor5.setup(1700, 2, 1);
+ _actor5.setPosition(Common::Point(177, 82));
+ _actor5.fixPriority(0);
+
+ _actor6.postInit();
+ _actor6.setup(1700, 2, 2);
+ _actor6.setPosition(Common::Point(332, 96));
+ _actor6.fixPriority(0);
+
+ _actor4.postInit();
+ _actor4.setup(1700, 1, 2);
+ _actor4.setPosition(Common::Point(424, 84));
+
+ R2_GLOBALS._walkRegions.enableRegion(11);
+ }
+
+ if ((R2_GLOBALS._v565F6 + 399) % 800 == 0) {
+ _actor7.postInit();
+ _actor7.setup(1700, 3, 2);
+ _actor7.setPosition(Common::Point(51, 141));
+ _actor7.fixPriority(0);
+ _actor7.setDetails(100, -1, -1, -1, 2, (SceneItem *) NULL);
+
+ _exit3._enabled = true;
+ } else {
+ R2_GLOBALS._walkRegions.enableRegion(1);
+ _exit3._enabled = false;
+ }
+
+ if ( ((!R2_GLOBALS.getFlag(15)) && ((R2_GLOBALS._v565F6 == 25) || (R2_GLOBALS._v565F6 == -3)))
+ || ((R2_GLOBALS.getFlag(15)) && (R2_GLOBALS._v565F6 == R2_GLOBALS._v565FA))
+ ) {
+ R2_GLOBALS._v565FA = R2_GLOBALS._v565F6;
+ if (!R2_GLOBALS.getFlag(15))
+ _field77C = 1;
+
+ _actor11.postInit();
+ _actor11.setup(1700, 3, 1);
+ _actor11.setPosition(Common::Point(338, 150));
+ _actor11.setDetails(1700, 9, -1, -1, 2, (SceneItem *) NULL);
+ _actor11.fixPriority(15);
+
+ _actor8.postInit();
+ _actor8.setup(1700, 4, 1);
+ _actor8.setPosition(Common::Point(312, 106));
+ _actor8.fixPriority(130);
+ }
+}
+
+void Scene1700::postInit(SceneObjectList *OwnerList) {
+ loadScene(1700);
+ SceneExt::postInit();
+ if (R2_GLOBALS._sceneManager._previousScene == -1)
+ R2_GLOBALS._sceneManager._previousScene = 1530;
+
+ scalePalette(65, 65, 65);
+ _stripManager.addSpeaker(&_quinnSpeaker);
+ _stripManager.addSpeaker(&_seekerSpeaker);
+
+ _field77A = 0;
+ _field77C = 0;
+
+ _exit1.setDetails(Rect(94, 0, 319, 12), EXITCURSOR_N, 1700);
+ _exit2.setDetails(Rect(0, 161, 319, 168), EXITCURSOR_S, 1700);
+ _exit3.setDetails(Rect(0, 0, 2, 138), EXITCURSOR_W, 1800);
+
+ R2_GLOBALS._player.postInit();
+ R2_GLOBALS._player.setPosition(Common::Point(0, 0));
+ R2_GLOBALS._player.animate(ANIM_MODE_1, NULL);
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
+ R2_GLOBALS._player.setVisage(1501);
+ R2_GLOBALS._player._moveDiff = Common::Point(2, 1);
+ } else {
+ R2_GLOBALS._player.setVisage(1506);
+ R2_GLOBALS._player._moveDiff = Common::Point(3, 1);
+ }
+
+ _actor12.postInit();
+ _actor12.animate(ANIM_MODE_1, NULL);
+ _actor12.setObjectWrapper(new SceneObjectWrapper());
+
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
+ _actor12.setVisage(1506);
+ _actor12._moveDiff = Common::Point(3, 1);
+ _actor12.setDetails(9002, 1, -1, -1, 1, (SceneItem *) NULL);
+ } else {
+ _actor12.setVisage(1501);
+ _actor12._moveDiff = Common::Point(2, 1);
+ _actor12.setDetails(9001, 1, -1, -1, 1, (SceneItem *) NULL);
+ }
+
+ R2_GLOBALS._sound1.play(134);
+
+ _actor1.postInit();
+ _actor1.fixPriority(10);
+
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN)
+ _actor1.setVisage(1112);
+ else
+ _actor1.setVisage(1111);
+
+ _actor1._effect = 5;
+ _actor1._field9C = _field312;
+ R2_GLOBALS._player._linkedActor = &_actor1;
+
+ _actor2.postInit();
+ _actor2.fixPriority(10);
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN)
+ _actor2.setVisage(1111);
+ else
+ _actor2.setVisage(1112);
+
+ _actor2._effect = 5;
+ _actor2._field9C = _field312;
+ _actor12._linkedActor = &_actor2;
+
+ R2_GLOBALS._sound1.play(134);
+
+ switch (R2_GLOBALS._sceneManager._previousScene) {
+ case 1530:
+ R2_GLOBALS._player._characterIndex = R2_QUINN;
+ R2_GLOBALS._player.disableControl();
+ R2_GLOBALS._player.hide();
+ _actor12.hide();
+
+ _actor10.postInit();
+ warning("_actor10._actorName = \"hatch\";");
+ _actor10.hide();
+
+ _actor9.postInit();
+ _actor9.setup(1701, 1, 1);
+ _actor9.setPosition(Common::Point(220, 137));
+ _actor9.setDetails(1700, 6, -1, -1, 1, (SceneItem *) NULL);
+
+ _actor1.hide();
+ _actor2.hide();
+ R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
+ _stripManager.start(539, this);
+ _sceneMode = 40;
+ break;
+ case 1750: {
+ R2_GLOBALS._player.setPosition(Common::Point(282, 121));
+ _actor12.setPosition(Common::Point(282, 139));
+ _sceneMode = 8;
+ Common::Point pt(262, 101);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, this);
+ Common::Point pt2(262, 119);
+ NpcMover *mover2 = new NpcMover();
+ _actor12.addMover(mover2, &pt2, this);
+ }
+ break;
+ case 1800: {
+ R2_GLOBALS._player.disableControl();
+ R2_GLOBALS._player.setPosition(Common::Point(0, 86));
+ _actor12.setPosition(Common::Point(0, 64));
+ _sceneMode = 7;
+ R2_GLOBALS._player.setObjectWrapper(NULL);
+ R2_GLOBALS._player._strip = 1;
+ Common::Point pt(64, 86);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, this);
+ _actor12.setObjectWrapper(NULL);
+ _actor12._strip = 1;
+ Common::Point pt2(77, 64);
+ NpcMover *mover2 = new NpcMover();
+ _actor12.addMover(mover2, &pt2, NULL);
+ }
+ break;
+ default:
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
+ R2_GLOBALS._player.setPosition(Common::Point(109, 160));
+ _actor12.setPosition(Common::Point(156, 160));
+ R2_GLOBALS._walkRegions.enableRegion(15);
+ } else {
+ R2_GLOBALS._player.setPosition(Common::Point(156, 160));
+ _actor12.setPosition(Common::Point(109, 160));
+ R2_GLOBALS._walkRegions.enableRegion(17);
+ }
+ _sceneMode = 50;
+ setAction(&_sequenceManager, this, 1, &R2_GLOBALS._player, NULL);
+ break;
+ }
+ R2_GLOBALS._player._characterScene[1] = 1700;
+ R2_GLOBALS._player._characterScene[2] = 1700;
+ R2_GLOBALS._player._oldCharacterScene[1] = 1700;
+ R2_GLOBALS._player._oldCharacterScene[2] = 1700;
+
+ R2_GLOBALS._v558B6.set(20, 0, 320, 200);
+ subAF3F8();
+ _item1.setDetails(1, 1700, 3, -1, -1);
+ _item2.setDetails(Rect(0, 0, 480, 200), 1700, 0, -1, -1, 1, NULL);
+}
+
+void Scene1700::remove() {
+ R2_GLOBALS._sound1.fadeOut2(NULL);
+ SceneExt::remove();
+}
+
+void Scene1700::signal() {
+ switch (_sceneMode) {
+ case 1: {
+ _sceneMode = 3;
+ if ((R2_GLOBALS._v565F6 < 2400) && (R2_GLOBALS._v565F6 >= 0))
+ ++R2_GLOBALS._v565F6;
+ subAF3F8();
+ R2_GLOBALS._player.setPosition(Common::Point(235 - (((((235 - R2_GLOBALS._player._position.x) * 100) / 103) * 167) / 100), 170));
+ Common::Point pt(R2_GLOBALS._player._position.x, 160);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, this);
+
+ if (R2_GLOBALS._player._position.x < 132) {
+ _actor12.setPosition(Common::Point(156, 170));
+ Common::Point pt2(156, 160);
+ NpcMover *mover2 = new NpcMover();
+ _actor12.addMover(mover2, &pt2, NULL);
+ R2_GLOBALS._walkRegions.enableRegion(15);
+ } else {
+ _actor12.setPosition(Common::Point(109, 170));
+ Common::Point pt3(109, 160);
+ NpcMover *mover3 = new NpcMover();
+ _actor12.addMover(mover3, &pt3, NULL);
+ R2_GLOBALS._walkRegions.enableRegion(17);
+ }
+ }
+ break;
+ case 2: {
+ _sceneMode = 3;
+ if ((R2_GLOBALS._v565F6 > -2400) && (R2_GLOBALS._v565F6 < 0))
+ R2_GLOBALS._v565F6--;
+ subAF3F8();
+ R2_GLOBALS._player.setPosition(Common::Point(235 - (((((235 - R2_GLOBALS._player._position.x) * 100) / 167) * 103) / 100), 0));
+ Common::Point pt(R2_GLOBALS._player._position.x, 10);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, this);
+
+ if (R2_GLOBALS._player._position.x >= 171) {
+ _actor12.setPosition(Common::Point(155, 0));
+ Common::Point pt2(155, 10);
+ NpcMover *mover2 = new NpcMover();
+ _actor12.addMover(mover2, &pt2, NULL);
+ R2_GLOBALS._walkRegions.enableRegion(15);
+ } else {
+ _actor12.setPosition(Common::Point(188, 0));
+ Common::Point pt3(188, 10);
+ NpcMover *mover3 = new NpcMover();
+ _actor12.addMover(mover3, &pt3, NULL);
+ R2_GLOBALS._walkRegions.enableRegion(17);
+ }
+ }
+ break;
+ case 3:
+ if (_field77C == 0) {
+ R2_GLOBALS._player.enableControl(CURSOR_ARROW);
+ } else {
+ R2_GLOBALS.setFlag(15);
+ _field77C = 0;
+ _sceneMode = 31;
+ R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN)
+ _stripManager.start(542, this);
+ else
+ _stripManager.start(543, this);
+ }
+ break;
+ case 4: {
+ _sceneMode = 5;
+ Common::Point pt(271, 90);
+ PlayerMover *mover = new PlayerMover();
+ _actor12.addMover(mover, &pt, NULL);
+ if (R2_GLOBALS._player._characterIndex == 1)
+ setAction(&_sequenceManager, this, 1700, &R2_GLOBALS._player, &_actor8, NULL);
+ else
+ setAction(&_sequenceManager, this, 1701, &R2_GLOBALS._player, &_actor8, NULL);
+ }
+ break;
+ case 5:
+ R2_GLOBALS._sceneManager.changeScene(1750);
+ break;
+ case 6:
+ R2_GLOBALS._sceneManager.changeScene(1800);
+ break;
+ case 7:
+ R2_GLOBALS._player.setObjectWrapper(new SceneObjectWrapper());
+ R2_GLOBALS._player._strip = 1;
+ _actor12.setObjectWrapper(new SceneObjectWrapper());
+ _actor12._strip = 1;
+ R2_GLOBALS._player.enableControl(CURSOR_ARROW);
+ R2_GLOBALS._walkRegions.enableRegion(14);
+ break;
+ case 8:
+ R2_GLOBALS._player._strip = 2;
+ _actor12._strip = 1;
+ R2_GLOBALS._player.enableControl(CURSOR_ARROW);
+ R2_GLOBALS._walkRegions.enableRegion(12);
+ break;
+ case 30:
+ _sceneMode = 31;
+ R2_GLOBALS._player.disableControl();
+ R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN)
+ _stripManager.start(540, this);
+ else
+ _stripManager.start(541, this);
+ break;
+ case 31:
+ R2_GLOBALS._v56AAB = 0;
+ R2_GLOBALS._player.enableControl(CURSOR_TALK);
+ break;
+ case 40:
+ R2_GLOBALS._player.disableControl();
+ _sceneMode = 1704;
+ setAction(&_sequenceManager, this, 1704, &R2_GLOBALS._player, &_actor12, &_actor10, &_actor9, &_actor1, &_actor2, NULL);
+ break;
+ case 50:
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN)
+ R2_GLOBALS._walkRegions.enableRegion(15);
+ else
+ R2_GLOBALS._walkRegions.enableRegion(17);
+
+ R2_GLOBALS._player.enableControl();
+ break;
+ case 1704:
+ R2_GLOBALS._sound1.play(134);
+ R2_GLOBALS._walkRegions.enableRegion(15);
+ R2_GLOBALS._walkRegions.enableRegion(2);
+ R2_GLOBALS._walkRegions.enableRegion(12);
+ R2_GLOBALS._player.fixPriority(-1);
+ R2_GLOBALS._player.enableControl(CURSOR_ARROW);
+ break;
+ default:
+ R2_GLOBALS._player.enableControl();
+ break;
+ }
+}
+
+/*--------------------------------------------------------------------------
+ * Scene 1750 -
+ *
+ *--------------------------------------------------------------------------*/
+Scene1750::Actor4::Actor4() {
+ _fieldA4 = 0;
+ _fieldA6 = 0;
+ _fieldA8 = 0;
+ _fieldAA = 0;
+ _fieldAC = 0;
+ _fieldAE = 0;
+}
+
+void Scene1750::Actor4::synchronize(Serializer &s) {
+ SceneActor::synchronize(s);
+
+ s.syncAsSint16LE(_fieldA4);
+ s.syncAsSint16LE(_fieldA6);
+ s.syncAsSint16LE(_fieldA8);
+ s.syncAsSint16LE(_fieldAA);
+ s.syncAsSint16LE(_fieldAC);
+ s.syncAsSint16LE(_fieldAE);
+}
+
+Scene1750::Actor5::Actor5() {
+ _fieldA4 = 0;
+}
+
+void Scene1750::Actor5::synchronize(Serializer &s) {
+ SceneActor::synchronize(s);
+
+ s.syncAsSint16LE(_fieldA4);
+}
+
+Scene1750::Scene1750() {
+ _field412 = 0;
+ _field413 = 0;
+ _field415 = 0;
+ _field417 = 0;
+ _field419 = 0;
+ _field41B = 0;
+ _field41D = 0;
+}
+
+void Scene1750::synchronize(Serializer &s) {
+ SceneExt::synchronize(s);
+ SYNC_POINTER(_rotation);
+
+ s.syncAsSint16LE(_field412);
+ s.syncAsSint16LE(_field413);
+ s.syncAsSint16LE(_field415);
+ s.syncAsSint16LE(_field417);
+ s.syncAsSint16LE(_field419);
+ s.syncAsSint16LE(_field41B);
+ s.syncAsSint16LE(_field41D);
+}
+
+void Scene1750::Actor4::subB1A76(int arg1, int arg2, int arg3, int arg4, int arg5) {
+ _fieldA4 = arg1;
+ _fieldAE = 0;
+ _fieldA6 = arg2;
+ _fieldA8 = arg3;
+ _fieldAA = arg4;
+ _fieldAC = arg5;
+
+ postInit();
+ setup(1750, 1, 1);
+ fixPriority(255);
+ setPosition(Common::Point(_fieldA6, _fieldA8 + ((_fieldAA * (arg1 - 1)) / (_fieldAC - 1))));
+}
+
+void Scene1750::Actor4::subB1B27() {
+ Scene1750 *scene = (Scene1750 *)R2_GLOBALS._sceneManager._scene;
+
+ int tmpVar = (_fieldAA / (_fieldAC - 1)) / 2;
+ int tmpVar2 = ((_position.y - _fieldA8 + tmpVar) * _fieldAC) / (_fieldAA + 2 * tmpVar);
+
+ setPosition(Common::Point(_fieldA6, _fieldA8 + ((_fieldAA * tmpVar2) / (_fieldAC - 1))));
+ scene->_field415 = scene->_field412 * tmpVar2;
+}
+
+void Scene1750::Actor4::remove() {
+ // Function kept to match IDA. Could be removed.
+ SceneActor::remove();
+}
+
+void Scene1750::Actor4::process(Event &event) {
+ if ((event.eventType == EVENT_BUTTON_DOWN) && (R2_GLOBALS._events.getCursor() == CURSOR_USE) && (_bounds.contains(event.mousePos))) {
+ _fieldAE = 1;
+ event.eventType = EVENT_NONE;
+ }
+
+ if ((event.eventType == EVENT_BUTTON_UP) && (_fieldAE != 0)) {
+ _fieldAE = 0;
+ event.handled = true;
+ addMover(NULL);
+ subB1B27();
+ }
+
+ if (_fieldAE != 0) {
+ event.handled = true;
+ if (event.mousePos.y >= _fieldA8) {
+ if (_fieldA8 + _fieldAA >= event.mousePos.y)
+ setPosition(Common::Point(_fieldA6, event.mousePos.y));
+ else
+ setPosition(Common::Point(_fieldA6, _fieldA8 + _fieldAA));
+ } else {
+ setPosition(Common::Point(_fieldA6, _fieldA8));
+ }
+ }
+}
+
+bool Scene1750::Actor4::startAction(CursorType action, Event &event) {
+ if (action == CURSOR_USE)
+ return SceneActor::startAction(action, event);
+
+ return false;
+}
+
+bool Scene1750::Actor5::startAction(CursorType action, Event &event) {
+ if (action != CURSOR_USE)
+ return SceneActor::startAction(action, event);
+
+ Scene1750 *scene = (Scene1750 *)R2_GLOBALS._sceneManager._scene;
+
+ switch (_fieldA4) {
+ case 1:
+ show();
+ scene->_actor6.hide();
+ if (scene->_field415 < 0)
+ scene->_field415 ^= 0xFFFE;
+ scene->_field412 = 1;
+ break;
+ case 2:
+ show();
+ scene->_actor5.hide();
+ if (scene->_field415 > 0)
+ scene->_field415 ^= 0xFFFE;
+ scene->_field412 = -1;
+ break;
+ case 3:
+ if (scene->_rotation->_idxChange == 0) {
+ show();
+ R2_GLOBALS._sceneManager.changeScene(1700);
+ } else {
+ scene->_field415 = 0;
+ scene->_actor4._moveRate = 20;
+ scene->_actor5._moveDiff.y = 1;
+ Common::Point pt(286, 143);
+ NpcMover *mover = new NpcMover();
+ scene->_actor4.addMover(mover, &pt, NULL);
+ }
+ default:
+ break;
+ }
+
+ return true;
+}
+
+void Scene1750::postInit(SceneObjectList *OwnerList) {
+ loadScene(1750);
+ R2_GLOBALS._sound1.play(115);
+ R2_GLOBALS._uiElements._active = false;
+ R2_GLOBALS._v5589E.set(0, 0, 320, 200);
+ SceneExt::postInit();
+
+ R2_GLOBALS._player._characterScene[1] = 1750;
+ R2_GLOBALS._player._characterScene[2] = 1750;
+ R2_GLOBALS._player._oldCharacterScene[1] = 1750;
+ R2_GLOBALS._player._oldCharacterScene[2] = 1750;
+
+ _rotation = R2_GLOBALS._scenePalette.addRotation(224, 254, 1);
+ _rotation->setDelay(0);
+ _rotation->_idxChange = 0;
+ _rotation->_countdown = 2;
+
+ switch ((R2_GLOBALS._v565F6 + 2) % 4) {
+ case 0:
+ _rotation->_currIndex = 247;
+ break;
+ case 1:
+ _rotation->_currIndex = 235;
+ break;
+ case 2:
+ _rotation->_currIndex = 239;
+ break;
+ case 3:
+ _rotation->_currIndex = 243;
+ break;
+ default:
+ break;
+ }
+
+ byte tmpPal[768];
+
+ for (int i = 224; i < 255; i++) {
+ int tmpIndex = _rotation->_currIndex - 224;
+ if (tmpIndex > 254)
+ tmpIndex -= 31;
+ tmpPal[3 * i] = R2_GLOBALS._scenePalette._palette[3 * tmpIndex];
+ tmpPal[(3 * i) + 1] = R2_GLOBALS._scenePalette._palette[(3 * tmpIndex) + 1];
+ tmpPal[(3 * i) + 2] = R2_GLOBALS._scenePalette._palette[(3 * tmpIndex) + 2];
+ }
+
+ for (int i = 224; i < 255; i++) {
+ R2_GLOBALS._scenePalette._palette[3 * i] = tmpPal[3 * i];
+ R2_GLOBALS._scenePalette._palette[(3 * i) + 1] = tmpPal[(3 * i) + 1];
+ R2_GLOBALS._scenePalette._palette[(3 * i) + 2] = tmpPal[(3 * i) + 2];
+ }
+
+ R2_GLOBALS._player.postInit();
+ R2_GLOBALS._player.hide();
+ R2_GLOBALS._player.enableControl();
+
+ _actor3.postInit();
+ _actor3.setup(1750, 3, 1);
+ _actor3.setPosition(Common::Point(49, 185));
+ _actor3.fixPriority(7);
+ _actor3.setDetails(1750, 30, -1, -1, 1, (SceneItem *) NULL);
+
+ _actor1.postInit();
+ _actor1.setup(1750, 2, 1);
+ _actor1.setPosition(Common::Point(35, ((_rotation->_currIndex - 218) % 4) + ((R2_GLOBALS._v565F6 % 800) * 4) - 1440));
+ _actor1.fixPriority(8);
+
+ _actor2.postInit();
+ _actor2.setup(1750, 1, 4);
+
+ int tmpVar = abs(_actor1._position.y - 158) / 100;
+
+ if (tmpVar >= 8)
+ _actor2.hide();
+ else if (_actor1._position.y <= 158)
+ _actor2.setPosition(Common::Point(137, (tmpVar * 7) + 122));
+ else
+ _actor2.setPosition(Common::Point(148, (tmpVar * 7) + 122));
+
+ _actor4.subB1A76(1, 286, 143, 41, 15);
+ _actor4.setDetails(1750, 24, 1, -1, 1, (SceneItem *) NULL);
+
+ _actor5.postInit();
+ _actor5._fieldA4 = 1;
+ _actor5.setup(1750, 1, 2);
+ _actor5.setPosition(Common::Point(192, 140));
+ _actor5.setDetails(1750, 18, 1, -1, 1, (SceneItem *) NULL);
+
+ _actor6.postInit();
+ _actor6._fieldA4 = 2;
+ _actor6.setup(1750, 1, 3);
+ _actor6.setPosition(Common::Point(192, 163));
+ _actor6.setDetails(1750, 18, 1, -1, 1, (SceneItem *) NULL);
+ _actor6.hide();
+
+ _actor7.postInit();
+ _actor7._fieldA4 = 3;
+ _actor7.setup(1750, 1, 5);
+ _actor7.setPosition(Common::Point(230, 183));
+ _actor7.setDetails(1750, 27, 1, -1, 1, (SceneItem *) NULL);
+
+ _field412 = 1;
+ _field417 = 0;
+ _field413 = 0;
+ _field415 = 0;
+ _field419 = ((_rotation->_currIndex - 218) / 4) % 4;
+
+ _item2.setDetails(Rect(129, 112, 155, 175), 1750, 21, -1, -1, 1, NULL);
+ _item3.setDetails(Rect(93, 122, 126, 172), 1750, 15, -1, -1, 1, NULL);
+ _item4.setDetails(Rect(3, 3, 157, 99), 1750, 9, -1, -1, 1, NULL);
+ _item5.setDetails(Rect(162, 3, 316, 99), 1750, 12, -1, -1, 1, NULL);
+ _item1.setDetails(Rect(0, 0, 320, 200), 1750, 6, 1, -1, 1, NULL);
+}
+
+void Scene1750::remove() {
+ _rotation->remove();
+
+ if (R2_GLOBALS._v565F6 == 2400)
+ R2_GLOBALS._v565F6 = 2399;
+
+ if (R2_GLOBALS._v565F6 == -2400)
+ R2_GLOBALS._v565F6 = -2399;
+
+ R2_GLOBALS._v565FA = R2_GLOBALS._v565F6;
+
+ SceneExt::remove();
+ R2_GLOBALS._sound1.fadeOut2(NULL);
+ R2_GLOBALS._v5589E.top = 3;
+ R2_GLOBALS._v5589E.bottom = 168;
+ R2_GLOBALS._uiElements._active = true;
+}
+
+void Scene1750::signal() {
+ R2_GLOBALS._player.enableControl();
+}
+
+void Scene1750::process(Event &event) {
+ Scene::process(event);
+ if (!event.handled)
+ _actor4.process(event);
+}
+
+void Scene1750::dispatch() {}
+
+/*--------------------------------------------------------------------------
+ * Scene 1800 -
+ *
+ *--------------------------------------------------------------------------*/
+Scene1800::Scene1800() {
+ _field412 = 0;
+}
+
+void Scene1800::synchronize(Serializer &s) {
+ SceneExt::synchronize(s);
+
+ s.syncAsSint16LE(_field412);
+}
+
+bool Scene1800::Hotspot5::startAction(CursorType action, Event &event) {
+ if ((action != R2_COM_SCANNER) && (action != R2_COM_SCANNER_2))
+ return false;
+
+ Scene1800 *scene = (Scene1800 *)R2_GLOBALS._sceneManager._scene;
+
+ R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
+
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
+ if (R2_GLOBALS._v565F6 == 1201) {
+ scene->_stripManager.start(548, this);
+ } else if (R2_GLOBALS.getFlag(66)) {
+ return false;
+ } else {
+ scene->_stripManager.start(546, this);
+ }
+ } else {
+ if (R2_GLOBALS._v565F6 == 1201) {
+ scene->_stripManager.start(549, this);
+ } else if (R2_GLOBALS.getFlag(66)) {
+ return false;
+ } else {
+ scene->_stripManager.start(547, this);
+ }
+ }
+
+ R2_GLOBALS.setFlag(66);
+ return true;
+}
+
+bool Scene1800::Actor6::startAction(CursorType action, Event &event) {
+ if (action != CURSOR_USE)
+ return SceneActor::startAction(action, event);
+
+ if (!R2_GLOBALS.getFlag(14))
+ return false;
+
+ if (R2_GLOBALS._player._characterIndex != R2_QUINN)
+ return SceneActor::startAction(action, event);
+
+ Scene1800 *scene = (Scene1800 *)R2_GLOBALS._sceneManager._scene;
+ R2_GLOBALS._player.disableControl();
+
+ if (_frame == 1) {
+ R2_GLOBALS.setFlag(64);
+ scene->_sceneMode = 1810;
+ scene->setAction(&scene->_sequenceManager, scene, 1810, &R2_GLOBALS._player, &scene->_actor6, &scene->_actor4, &scene->_actor5, NULL);
+ } else {
+ R2_GLOBALS.clearFlag(64);
+ scene->_sceneMode = 1811;
+ scene->setAction(&scene->_sequenceManager, scene, 1811, &R2_GLOBALS._player, &scene->_actor6, &scene->_actor4, &scene->_actor5, NULL);
+ }
+ return true;
+}
+
+bool Scene1800::Actor7::startAction(CursorType action, Event &event) {
+ if (action != CURSOR_USE)
+ return SceneActor::startAction(action, event);
+
+ Scene1800 *scene = (Scene1800 *)R2_GLOBALS._sceneManager._scene;
+
+ if (R2_GLOBALS._player._characterIndex == R2_SEEKER) {
+ R2_GLOBALS._player.disableControl();
+ if (scene->_field412 >= 2) {
+ if (R2_GLOBALS.getFlag(14)) {
+ scene->_sceneMode = 1809;
+ scene->setAction(&scene->_sequenceManager, scene, 1809, &R2_GLOBALS._player, &scene->_actor7, NULL);
+ R2_GLOBALS.clearFlag(14);
+ } else {
+ scene->_sceneMode = 1808;
+ scene->setAction(&scene->_sequenceManager, scene, 1808, &R2_GLOBALS._player, &scene->_actor7, NULL);
+ R2_GLOBALS.setFlag(14);
+ }
+ } else {
+ scene->_sceneMode = 1813;
+ scene->setAction(&scene->_sequenceManager, scene, 1813, &R2_GLOBALS._player, NULL);
+ }
+ } else if (R2_GLOBALS.getFlag(14)) {
+ return SceneActor::startAction(action, event);
+ } else {
+ R2_GLOBALS._player.disableControl();
+ scene->_sceneMode = 1812;
+ scene->setAction(&scene->_sequenceManager, scene, 1812, &R2_GLOBALS._player, NULL);
+ }
+
+ return true;
+}
+
+bool Scene1800::Actor8::startAction(CursorType action, Event &event) {
+ if (action != CURSOR_USE)
+ return SceneActor::startAction(action, event);
+
+ Scene1800 *scene = (Scene1800 *)R2_GLOBALS._sceneManager._scene;
+
+ if (_position.x < 160) {
+ if (scene->_actor4._frame == 1) {
+ return SceneActor::startAction(action, event);
+ } else {
+ R2_GLOBALS.setFlag(29);
+ R2_GLOBALS._player.disableControl();
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
+ if (R2_GLOBALS.getFlag(14)) {
+ scene->_sceneMode = 1804;
+ scene->setAction(&scene->_sequenceManager, scene, 1804, &R2_GLOBALS._player, &scene->_actor2, &scene->_actor8, NULL);
+ } else {
+ scene->_sceneMode = 1;
+ scene->setAction(&scene->_sequenceManager, scene, 1809, &R2_GLOBALS._player, &scene->_actor2, &scene->_actor7, NULL);
+ R2_GLOBALS.clearFlag(14);
+ }
+ } else {
+ if (R2_GLOBALS.getFlag(14)) {
+ scene->_sceneMode = 1;
+ scene->setAction(&scene->_sequenceManager, scene, 1809, &R2_GLOBALS._player, &scene->_actor7, NULL);
+ R2_GLOBALS.clearFlag(14);
+ } else {
+ scene->_sceneMode = 1805;
+ scene->setAction(&scene->_sequenceManager, scene, 1805, &R2_GLOBALS._player, &scene->_actor2, &scene->_actor8, NULL);
+ }
+ }
+ }
+ } else {
+ if (scene->_actor4._frame == 1) {
+ return SceneActor::startAction(action, event);
+ } else {
+ R2_GLOBALS.clearFlag(29);
+ R2_GLOBALS._player.disableControl();
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
+ if (R2_GLOBALS.getFlag(14)) {
+ scene->_sceneMode = 2;
+ scene->setAction(&scene->_sequenceManager, scene, 1809, &R2_GLOBALS._player, &scene->_actor2, &scene->_actor7, NULL);
+ R2_GLOBALS.clearFlag(14);
+ } else {
+ scene->_sceneMode = 1806;
+ scene->setAction(&scene->_sequenceManager, scene, 1806, &R2_GLOBALS._player, &scene->_actor2, &scene->_actor9, NULL);
+ }
+ } else {
+ if (R2_GLOBALS.getFlag(14)) {
+ scene->_sceneMode = 2;
+ scene->setAction(&scene->_sequenceManager, scene, 1809, &R2_GLOBALS._player, &scene->_actor7, NULL);
+ R2_GLOBALS.clearFlag(14);
+ } else {
+ scene->_sceneMode = 1807;
+ scene->setAction(&scene->_sequenceManager, scene, 1807, &R2_GLOBALS._player, &scene->_actor2, &scene->_actor9, NULL);
+ }
+ }
+ }
+ }
+
+ return true;
+}
+
+void Scene1800::Exit1::changeScene() {
+ Scene1800 *scene = (Scene1800 *)R2_GLOBALS._sceneManager._scene;
+
+ _enabled = false;
+ R2_GLOBALS._events.setCursor(CURSOR_ARROW);
+ R2_GLOBALS._player.disableControl();
+ if (R2_GLOBALS.getFlag(14)) {
+ scene->_sceneMode = 3;
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN)
+ scene->setAction(&scene->_sequenceManager, scene, 1809, &R2_GLOBALS._player, &scene->_actor7, NULL);
+ else
+ scene->setAction(&scene->_sequenceManager, scene, 1809, &scene->_actor2, &scene->_actor7, NULL);
+ R2_GLOBALS.clearFlag(14);
+ } else {
+ scene->_sceneMode = 1802;
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN)
+ scene->setAction(&scene->_sequenceManager, scene, 1802, &R2_GLOBALS._player, &scene->_actor2, NULL);
+ else
+ scene->setAction(&scene->_sequenceManager, scene, 1802, &R2_GLOBALS._player, &scene->_actor2, NULL);
+ }
+}
+
+void Scene1800::postInit(SceneObjectList *OwnerList) {
+ loadScene(1800);
+ SceneExt::postInit();
+ R2_GLOBALS._sound1.play(116);
+ _stripManager.addSpeaker(&_quinnSpeaker);
+ _stripManager.addSpeaker(&_seekerSpeaker);
+
+ if (R2_GLOBALS._sceneManager._previousScene == -1)
+ R2_GLOBALS._v565F6 = 1201;
+
+ if (R2_GLOBALS._v565F6 == 1201)
+ _field412 = 2;
+ else
+ _field412 = 0;
+
+ scalePalette(65, 65, 65);
+ _exit1.setDetails(Rect(0, 160, 319, 168), EXITCURSOR_S, 1800);
+ _item5.setDetails(Rect(0, 0, 320, 200), -1, -1, -1, -1, 1, NULL);
+
+ _actor6.postInit();
+ _actor6.setup(1801, 4, 1);
+ _actor6.setPosition(Common::Point(170, 24));
+ _actor6.setDetails(1800, 13, 14, 15, 1, (SceneItem *) NULL);
+
+ _actor7.postInit();
+ _actor7.setup(1801, 3, 1);
+ _actor7.setPosition(Common::Point(160, 139));
+ _actor7.setDetails(1800, 6, -1, -1, 1, (SceneItem *) NULL);
+
+ _actor8.postInit();
+ _actor8.setup(1800, 1, 1);
+ _actor8.setPosition(Common::Point(110, 78));
+ _actor8.fixPriority(135);
+ _actor8.setDetails(1800, 20, -1, -1, 1, (SceneItem *) NULL);
+
+ _actor9.postInit();
+ _actor9.setup(1800, 2, 1);
+ _actor9.setPosition(Common::Point(209, 78));
+ _actor9.fixPriority(135);
+ _actor9.setDetails(1800, 20, -1, -1, 1, (SceneItem *) NULL);
+
+ _actor4.postInit();
+ if ((_field412 != 1) && (_field412 != 3) && (!R2_GLOBALS.getFlag(64)))
+ _actor4.setup(1801, 2, 1);
+ else
+ _actor4.setup(1801, 2, 10);
+ _actor4.setPosition(Common::Point(76, 142));
+ _actor4.setDetails(1800, 3, -1, -1, 1, (SceneItem *) NULL);
+
+ _actor5.postInit();
+ if ((_field412 != 1) && (_field412 != 3) && (!R2_GLOBALS.getFlag(64)))
+ _actor5.setup(1801, 1, 1);
+ else
+ _actor5.setup(1801, 1, 10);
+ _actor5.setPosition(Common::Point(243, 142));
+ _actor5.setDetails(1800, 3, -1, -1, 1, (SceneItem *) NULL);
+
+ R2_GLOBALS._player.postInit();
+ R2_GLOBALS._player.animate(ANIM_MODE_1, NULL);
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
+ if (R2_GLOBALS.getFlag(14)) {
+ R2_GLOBALS._player.animate(ANIM_MODE_NONE, NULL);
+ R2_GLOBALS._player.setObjectWrapper(NULL);
+ R2_GLOBALS._player.setup(1801, 5, 12);
+ R2_GLOBALS._player.setPosition(Common::Point(160, 139));
+ R2_GLOBALS._walkRegions.enableRegion(9);
+ _actor7.hide();
+ } else {
+ R2_GLOBALS._player.setVisage(1507);
+ }
+ R2_GLOBALS._player._moveDiff = Common::Point(4, 2);
+ } else {
+ R2_GLOBALS._player.setVisage(1503);
+ R2_GLOBALS._player._moveDiff = Common::Point(2, 2);
+ }
+
+ _actor2.postInit();
+ _actor2.animate(ANIM_MODE_1, NULL);
+ _actor2.setObjectWrapper(new SceneObjectWrapper());
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
+ if (R2_GLOBALS.getFlag(14)) {
+ _actor2.animate(ANIM_MODE_NONE, NULL);
+ _actor2.setObjectWrapper(NULL);
+ _actor2.setup(1801, 5, 12);
+
+ R2_GLOBALS._walkRegions.enableRegion(9);
+ _actor7.hide();
+ } else {
+ _actor2.setup(1507, 1, 1);
+ _actor2.setPosition(Common::Point(180, 160));
+ }
+ _actor2.setDetails(9002, 0, 4, 3, 1, (SceneItem *) NULL);
+ _actor2._moveDiff = Common::Point(4, 2);
+ } else {
+ _actor2.setDetails(9001, 0, 5, 3, 1, (SceneItem *) NULL);
+ _actor2.setVisage(1503);
+ _actor2._moveDiff = Common::Point(2, 2);
+ }
+
+ if (R2_GLOBALS._player._oldCharacterScene[R2_GLOBALS._player._characterIndex] == 1800) {
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
+ R2_GLOBALS._player.setPosition(Common::Point(114, 150));
+ R2_GLOBALS._player.setStrip(5);
+ if (R2_GLOBALS.getFlag(14)) {
+ _actor2.setPosition(Common::Point(160, 139));
+ R2_GLOBALS._walkRegions.enableRegion(8);
+ } else {
+ _actor2.setPosition(Common::Point(209, 150));
+ _actor2.setStrip(6);
+ R2_GLOBALS._walkRegions.enableRegion(8);
+ }
+ } else {
+ if (R2_GLOBALS.getFlag(14)) {
+ R2_GLOBALS._player.setup(1801, 5, 12);
+ R2_GLOBALS._player.setPosition(Common::Point(160, 139));
+ } else {
+ R2_GLOBALS._player.setPosition(Common::Point(209, 150));
+ R2_GLOBALS._player.setStrip(6);
+ }
+ _actor2.setPosition(Common::Point(114, 150));
+ _actor2.setStrip(5);
+ R2_GLOBALS._walkRegions.enableRegion(10);
+ R2_GLOBALS._walkRegions.enableRegion(11);
+ }
+ } else {
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
+ R2_GLOBALS._player.setPosition(Common::Point(140, 160));
+ _actor2.setPosition(Common::Point(180, 160));
+ } else {
+ R2_GLOBALS._player.setPosition(Common::Point(180, 160));
+ _actor2.setPosition(Common::Point(140, 160));
+ }
+ }
+
+ _actor1.postInit();
+ _actor1.fixPriority(10);
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN)
+ _actor1.setVisage(1111);
+ else
+ _actor1.setVisage(1110);
+
+ _actor1._effect = 5;
+ _actor1._field9C = _field312;
+
+ R2_GLOBALS._player._linkedActor = &_actor1;
+
+ _actor3.postInit();
+ _actor3.fixPriority(10);
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN)
+ _actor3.setVisage(1110);
+ else
+ _actor3.setVisage(1111);
+
+ _actor3._effect = 5;
+ _actor3._field9C = _field312;
+
+ _actor2._linkedActor = &_actor3;
+
+ R2_GLOBALS._player._characterScene[1] = 1800;
+ R2_GLOBALS._player._characterScene[2] = 1800;
+
+ _item2.setDetails(Rect(128, 95, 190, 135), 1800, 10, -1, -1, 1, NULL);
+ _item1.setDetails(Rect(95, 3, 223, 135), 1800, 0, -1, -1, 1, NULL);
+
+ // Original was calling _item3.setDetails(Rect(1800, 11, 24, 23), 25, -1, -1, -1, 1, NULL);
+ // This is *wrong*. The following statement is a wild guess based on good common sense
+ _item3.setDetails(11, 1800, 23, 24, 25);
+ _item4.setDetails(Rect(0, 0, 320, 200), 1800, 17, -1, 19, 1, NULL);
+
+ R2_GLOBALS._player.disableControl();
+ if (R2_GLOBALS._player._oldCharacterScene[R2_GLOBALS._player._characterIndex] == 1800) {
+ if ((R2_GLOBALS.getFlag(14)) && (R2_GLOBALS._player._characterIndex == R2_SEEKER)) {
+ R2_GLOBALS._player.enableControl(CURSOR_USE);
+ R2_GLOBALS._player._canWalk = false;
+ } else {
+ R2_GLOBALS._player.enableControl(CURSOR_ARROW);
+ }
+ } else if (R2_GLOBALS._player._oldCharacterScene[R2_GLOBALS._player._characterIndex] == 1850) {
+ if (R2_GLOBALS.getFlag(29)) {
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
+ _sceneMode = 1814;
+ setAction(&_sequenceManager, this, 1814, &R2_GLOBALS._player, &_actor2, &_actor8, NULL);
+ } else {
+ _sceneMode = 1815;
+ setAction(&_sequenceManager, this, 1815, &R2_GLOBALS._player, &_actor2, &_actor8, NULL);
+ }
+ } else {
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
+ _sceneMode = 1816;
+ setAction(&_sequenceManager, this, 1816, &R2_GLOBALS._player, &_actor2, &_actor9, NULL);
+ } else {
+ _sceneMode = 1817;
+ setAction(&_sequenceManager, this, 1817, &R2_GLOBALS._player, &_actor2, &_actor9, NULL);
+ }
+ }
+ } else {
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
+ _sceneMode = 1800;
+ setAction(&_sequenceManager, this, 1800, &R2_GLOBALS._player, &_actor2, NULL);
+ } else {
+ _sceneMode = 1801;
+ setAction(&_sequenceManager, this, 1801, &R2_GLOBALS._player, &_actor2, NULL);
+ }
+ }
+
+ R2_GLOBALS._player._oldCharacterScene[1] = 1800;
+ R2_GLOBALS._player._oldCharacterScene[2] = 1800;
+}
+
+void Scene1800::signal() {
+ switch (_sceneMode) {
+ case 1:
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
+ _sceneMode = 1804;
+ setAction(&_sequenceManager, this, 1804, &R2_GLOBALS._player, &_actor2, &_actor8, NULL);
+ } else {
+ _sceneMode = 1805;
+ setAction(&_sequenceManager, this, 1805, &R2_GLOBALS._player, &_actor2, &_actor8, NULL);
+ }
+ break;
+ case 2:
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
+ _sceneMode = 1806;
+ setAction(&_sequenceManager, this, 1806, &R2_GLOBALS._player, &_actor2, &_actor9, NULL);
+ } else {
+ _sceneMode = 1807;
+ setAction(&_sequenceManager, this, 1807, &R2_GLOBALS._player, &_actor2, &_actor9, NULL);
+ }
+ break;
+ case 3:
+ _sceneMode = 1802;
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN)
+ setAction(&_sequenceManager, this, 1802, &R2_GLOBALS._player, &_actor2, NULL);
+ else
+ setAction(&_sequenceManager, this, 1803, &R2_GLOBALS._player, &_actor2, NULL);
+ break;
+ case 10:
+ // No break on purpose
+ case 11:
+ R2_GLOBALS._player.enableControl(CURSOR_TALK);
+ break;
+ case 12:
+ R2_GLOBALS._player.enableControl(CURSOR_TALK);
+ R2_GLOBALS._player._canWalk = false;
+ break;
+ case 13:
+ _sceneMode = 14;
+ R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
+ R2_GLOBALS._player.setup(1801, 7, 1);
+ R2_GLOBALS._player.animate(ANIM_MODE_8, NULL);
+ _stripManager.start(550, this);
+ break;
+ case 14:
+ _sceneMode = 15;
+ R2_GLOBALS._player.disableControl();
+ R2_GLOBALS._player.setup(1801, 6, 1);
+ R2_GLOBALS._player.animate(ANIM_MODE_6, this);
+ break;
+ case 15:
+ R2_GLOBALS._player.setup(1503, 4, 1);
+ R2_GLOBALS._player.animate(ANIM_MODE_1, NULL);
+ R2_GLOBALS._player.enableControl(CURSOR_USE);
+ break;
+ case 1800:
+ R2_GLOBALS._walkRegions.enableRegion(8);
+ if (R2_GLOBALS.getFlag(63))
+ R2_GLOBALS._player.enableControl(CURSOR_USE);
+ else {
+ _sceneMode = 10;
+ R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
+ _stripManager.start(544, this);
+ }
+ break;
+ case 1801:
+ R2_GLOBALS._walkRegions.enableRegion(10);
+ R2_GLOBALS._walkRegions.enableRegion(11);
+ R2_GLOBALS.setFlag(63);
+
+ // The following check is completely dumb.
+ // Either an original bug, or dead code.
+ if (R2_GLOBALS.getFlag(63)) {
+ R2_GLOBALS._player.enableControl(CURSOR_ARROW);
+ } else {
+ _sceneMode = 10;
+ R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
+ _stripManager.start(545, this);
+ }
+ break;
+ case 1802:
+ R2_GLOBALS.clearFlag(14);
+ R2_GLOBALS._sceneManager.changeScene(1700);
+ break;
+ case 1804:
+ // No break on purpose
+ case 1805:
+ // No break on purpose
+ case 1806:
+ // No break on purpose
+ case 1807:
+ R2_GLOBALS.clearFlag(14);
+ R2_GLOBALS._sceneManager.changeScene(1850);
+ break;
+ case 1808:
+ _sceneMode = 12;
+ R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
+ _stripManager.start(553, this);
+ break;
+ case 1812:
+ _sceneMode = 13;
+ R2_GLOBALS._player.animate(ANIM_MODE_5, this);
+ break;
+ case 1814:
+ // No break on purpose
+ case 1815:
+ R2_GLOBALS._walkRegions.enableRegion(10);
+ R2_GLOBALS._walkRegions.enableRegion(11);
+ R2_GLOBALS._player.enableControl();
+ break;
+ case 1816:
+ // No break on purpose
+ case 1817:
+ R2_GLOBALS._walkRegions.enableRegion(8);
+ R2_GLOBALS._player.enableControl();
+ break;
+ default:
+ R2_GLOBALS._player.enableControl();
+ break;
+ }
+}
+
+void Scene1800::saveCharacter(int characterIndex) {
+ if (R2_GLOBALS._player._characterIndex == R2_MIRANDA)
+ R2_GLOBALS._sound1.fadeOut2(NULL);
+
+ SceneExt::saveCharacter(characterIndex);
+}
+
+/*--------------------------------------------------------------------------
+ * Scene 1850 -
+ *
+ *--------------------------------------------------------------------------*/
+Scene1850::Scene1850() {
+ warning("STUBBED: Scene1850()");
+}
+
+void Scene1850::synchronize(Serializer &s) {
+ warning("STUBBED: Scene1850::synchronize()");
+}
+
+bool Scene1850::Hotspot2::startAction(CursorType action, Event &event) {
+ if (action != CURSOR_USE)
+ return SceneHotspot::startAction(action, event);
+
+ Scene1850 *scene = (Scene1850 *)R2_GLOBALS._sceneManager._scene;
+
+ R2_GLOBALS._player.disableControl();
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
+ scene->_sceneMode = 1852;
+ if (R2_GLOBALS.getFlag(32))
+ scene->setAction(&scene->_sequenceManager1, scene, 1871, &R2_GLOBALS._player, NULL);
+ else
+ scene->setAction(&scene->_sequenceManager1, scene, 1852, &R2_GLOBALS._player, NULL);
+ } else if (R2_GLOBALS.getFlag(30)) {
+ scene->_field41E = 1;
+ scene->_sceneMode = 1860;
+
+ if (R2_GLOBALS.getFlag(32))
+ scene->setAction(&scene->_sequenceManager1, scene, 1860, &R2_GLOBALS._player, &scene->_actor5, NULL);
+ else
+ scene->setAction(&scene->_sequenceManager1, scene, 1859, &R2_GLOBALS._player, &scene->_actor5, NULL);
+
+ R2_GLOBALS.clearFlag(30);
+ } else {
+ scene->_sceneMode = 1853;
+
+ if (R2_GLOBALS.getFlag(32))
+ scene->setAction(&scene->_sequenceManager1, scene, 1872, &R2_GLOBALS._player, NULL);
+ else
+ scene->setAction(&scene->_sequenceManager1, scene, 1853, &R2_GLOBALS._player, NULL);
+ }
+
+ return true;
+}
+
+bool Scene1850::Actor5::startAction(CursorType action, Event &event) {
+ Scene1850 *scene = (Scene1850 *)R2_GLOBALS._sceneManager._scene;
+
+ switch (action) {
+ case CURSOR_USE:
+ if ((R2_GLOBALS._player._characterIndex != R2_SEEKER) || (R2_GLOBALS.getFlag(33)) || (R2_GLOBALS.getFlag(30)))
+ return SceneActor::startAction(action, event);
+
+ R2_GLOBALS._player.disableControl();
+ scene->_sceneMode = 1857;
+
+ if (R2_GLOBALS.getFlag(32))
+ scene->setAction(&scene->_sequenceManager1, scene, 1858, &R2_GLOBALS._player, &scene->_actor5, NULL);
+ else
+ scene->setAction(&scene->_sequenceManager1, scene, 1857, &R2_GLOBALS._player, &scene->_actor5, NULL);
+
+ R2_GLOBALS.setFlag(30);
+ return true;
+ break;
+ case CURSOR_LOOK:
+ if (R2_GLOBALS.getFlag(34))
+ SceneItem::display(1850, 2, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
+ else
+ SceneItem::display(1850, 1, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
+
+ return true;
+ break;
+ case R2_AIRBAG:
+ if (R2_GLOBALS._player._characterIndex == R2_SEEKER) {
+ if (R2_GLOBALS.getFlag(70)) {
+ R2_GLOBALS._player.disableControl();
+ scene->_sceneMode = 30;
+
+ R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
+ scene->_stripManager.start(558, scene);
+
+ return true;
+ } else {
+ return SceneActor::startAction(action, event);
+ }
+ } else if (R2_GLOBALS.getFlag(30)) {
+ R2_GLOBALS._player.disableControl();
+ scene->_sceneMode = 1875;
+ scene->_actor2.postInit();
+
+ if (R2_GLOBALS.getFlag(32))
+ scene->setAction(&scene->_sequenceManager1, scene, 1876, &R2_GLOBALS._player, &scene->_actor2, NULL);
+ else
+ scene->setAction(&scene->_sequenceManager1, scene, 1875, &R2_GLOBALS._player, &scene->_actor2, NULL);
+
+ return true;
+ } else if (R2_GLOBALS.getFlag(70)) {
+ R2_GLOBALS._player.disableControl();
+ scene->_sceneMode = 30;
+ R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
+ scene->_stripManager.start(557, scene);
+ R2_GLOBALS.setFlag(69);
+
+ return true;
+ } else {
+ return SceneActor::startAction(action, event);
+ }
+ break;
+ case R2_REBREATHER_TANK:
+ if (R2_INVENTORY.getObjectScene(R2_AIRBAG) == 1850) {
+ if (R2_GLOBALS.getFlag(30))
+ return SceneActor::startAction(action, event);;
+
+ R2_GLOBALS._player.disableControl();
+ scene->_sceneMode = 1878;
+ scene->setAction(&scene->_sequenceManager1, scene, 1878, &R2_GLOBALS._player, &scene->_actor5, &scene->_actor2, NULL);
+ }
+
+ return true;
+ break;
+ default:
+ return SceneActor::startAction(action, event);
+ break;
+ }
+}
+
+bool Scene1850::Actor6::startAction(CursorType action, Event &event) {
+ if (action != CURSOR_USE)
+ return SceneHotspot::startAction(action, event);
+
+ Scene1850 *scene = (Scene1850 *)R2_GLOBALS._sceneManager._scene;
+
+ if (R2_GLOBALS.getFlag(32)) {
+ SceneItem::display(3240, 4, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
+ return true;
+ }
+
+ R2_GLOBALS._player.disableControl();
+ if (scene->_field412 == 1851)
+ R2_GLOBALS._player._effect = 1;
+
+ if (_position.x >= 160)
+ R2_GLOBALS.setFlag(29);
+ else
+ R2_GLOBALS.clearFlag(29);
+
+ if ((R2_GLOBALS._player._characterIndex == R2_SEEKER) && (R2_GLOBALS.getFlag(30))) {
+ if (_position.x >= 160)
+ scene->_field41E = 3;
+ else
+ scene->_field41E = 2;
+
+ scene->_sceneMode = 1860;
+
+ if (R2_GLOBALS.getFlag(32)) {
+ scene->setAction(&scene->_sequenceManager1, scene, 1860, &R2_GLOBALS._player, &scene->_actor5, NULL);
+ } else {
+ scene->setAction(&scene->_sequenceManager1, scene, 1859, &R2_GLOBALS._player, &scene->_actor5, NULL);
+ }
+ } else {
+ scene->_sceneMode = 11;
+ if (_position.x >= 160) {
+ scene->setAction(&scene->_sequenceManager1, scene, 1866, &R2_GLOBALS._player, &scene->_actor7, NULL);
+ } else {
+ scene->setAction(&scene->_sequenceManager1, scene, 1865, &R2_GLOBALS._player, &scene->_actor6, NULL);
+ }
+ }
+
+ return true;
+}
+
+bool Scene1850::Actor8::startAction(CursorType action, Event &event) {
+ if ((action != CURSOR_USE) || (_position.y != 120))
+ return SceneHotspot::startAction(action, event);
+
+ Scene1850 *scene = (Scene1850 *)R2_GLOBALS._sceneManager._scene;
+
+ R2_GLOBALS._player.disableControl();
+ scene->_sceneMode = 1881;
+
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
+ scene->setAction(&scene->_sequenceManager1, scene, 1881, &R2_GLOBALS._player, NULL);
+ } else {
+ scene->setAction(&scene->_sequenceManager1, scene, 1880, &R2_GLOBALS._player, NULL);
+ }
+
+ return true;
+}
+
+void Scene1850::postInit(SceneObjectList *OwnerList) {
+ loadScene(1850);
+
+ if (R2_GLOBALS._player._oldCharacterScene[R2_GLOBALS._player._characterIndex] != 1850)
+ R2_GLOBALS.clearFlag(31);
+
+ _palette1.loadPalette(0);
+
+ if (R2_GLOBALS.getFlag(31)) {
+ _field412 = 1850;
+ g_globals->_scenePalette.loadPalette(1850);
+ } else {
+ _field412 = 1851;
+ g_globals->_scenePalette.loadPalette(1851);
+ }
+
+ SceneExt::postInit();
+
+ if (R2_GLOBALS._sceneManager._previousScene == 3150)
+ R2_GLOBALS._sound1.play(116);
+
+ _stripManager.addSpeaker(&_quinnSpeaker);
+ _stripManager.addSpeaker(&_seekerSpeaker);
+
+ _field418 = 0;
+ _field41E = 0;
+ _field41A = Common::Point(0, 0);
+
+ R2_GLOBALS._player._characterScene[1] = 1850;
+ R2_GLOBALS._player._characterScene[2] = 1850;
+
+ _item2.setDetails(Rect(101, 56, 111, 63), 1850, 19, -1, -1, 1, NULL);
+
+ _actor6.postInit();
+ _actor6.setup(1850, 3, 1);
+ _actor6.setPosition(Common::Point(66, 102));
+ _actor6.setDetails(1850, 22, -1, -1, 1, (SceneItem *) NULL);
+
+ _actor7.postInit();
+ _actor7.setup(1850, 2, 1);
+ _actor7.setPosition(Common::Point(253, 102));
+ _actor7.setDetails(1850, 22, -1, -1, 1, (SceneItem *) NULL);
+
+ R2_GLOBALS._walkRegions.enableRegion(1);
+
+ _actor5.postInit();
+
+ if (R2_GLOBALS.getFlag(34)) {
+ R2_GLOBALS._walkRegions.enableRegion(2);
+ _actor5.setup(1851, 4, 3);
+ } else if (R2_GLOBALS.getFlag(30)) {
+ _actor5.setup(1851, 2, 2);
+ } else {
+ R2_GLOBALS._walkRegions.enableRegion(5);
+ if (R2_GLOBALS.getFlag(33)) {
+ R2_GLOBALS._walkRegions.enableRegion(2);
+ _actor5.setup(1851, 1, 3);
+ } else {
+ _actor5.setup(1851, 2, 1);
+ }
+ }
+
+ _actor5.setPosition(Common::Point(219, 130));
+ _actor5.fixPriority(114);
+ _actor5.setDetails(1850, -1, -1, -1, 1, (SceneItem *) NULL);
+
+ R2_GLOBALS._player.postInit();
+
+ _actor1.postInit();
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
+ _actor1.setDetails(9002, 0, 4, 3, 1, (SceneItem *) NULL);
+ } else {
+ _actor1.setDetails(9001, 0, 5, 3, 1, (SceneItem *) NULL);
+ }
+
+ if (R2_GLOBALS._player._oldCharacterScene[R2_GLOBALS._player._characterIndex] == 1850) {
+ R2_GLOBALS._player._effect = 6;
+ _actor1._effect = 6;
+ if (R2_GLOBALS.getFlag(31)) {
+ R2_GLOBALS._player._shade = 0;
+ _actor1._shade = 0;
+ } else {
+ R2_GLOBALS._player._shade = 6;
+ _actor1._shade = 6;
+ }
+
+ if (R2_INVENTORY.getObjectScene(R2_AIRBAG) == 1850) {
+ _actor2.postInit();
+ if (R2_GLOBALS.getFlag(34)) {
+ _actor2.setup(1851, 4, 2);
+ _actor2.fixPriority(114);
+ } else {
+ _actor2.setup(1851, 4, 1);
+ }
+
+ _actor2.setPosition(Common::Point(179, 113));
+
+ if ((_actor5._strip == 1) && (_actor5._frame == 3)){
+ _actor2.hide();
+ }
+
+ _actor2.setDetails(1850, 6, -1, -1, 1, (SceneItem *) NULL);
+ }
+
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
+ if (R2_GLOBALS.getFlag(32)) {
+ R2_GLOBALS._player.setVisage(1511);
+ _actor1.setVisage(1508);
+
+ _actor3.postInit();
+ _actor3.setup(1853, 3, 1);
+ _actor3.setPosition(Common::Point(122, 113));
+ _actor3.fixPriority(114);
+ _actor3._effect = 6;
+
+ // Totally useless test
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
+ _actor3.setDetails(1850, 28, -1, -1, 2, (SceneItem *) NULL);
+ } else {
+ // And the associated dead code
+ _actor3.setDetails(1850, 30, -1, -1, 2, (SceneItem *) NULL);
+ }
+
+ _actor4.postInit();
+ _actor4.setup(1853, 3, 2);
+ _actor4.setPosition(Common::Point(139, 111));
+ _actor4.fixPriority(114);
+ _actor4._effect = 6;
+
+ // Still totally useless test
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
+ _actor4.setDetails(1850, 29, -1, -1, 2, (SceneItem *) NULL);
+ } else {
+ // Another piece of dead code
+ _actor4.setDetails(1850, 28, -1, -1, 2, (SceneItem *) NULL);
+ }
+
+ if (R2_GLOBALS.getFlag(31)) {
+ _actor3._shade = 0;
+ _actor4._shade = 0;
+ } else {
+ _actor3._shade = 6;
+ _actor4._shade = 6;
+ }
+ } else {
+ R2_GLOBALS._player.setVisage(1500);
+ _actor1.setVisage(1505);
+ }
+ } else { // Not Quinn
+ if (R2_GLOBALS.getFlag(32)) {
+ R2_GLOBALS._player.setVisage(1508);
+ _actor1.setVisage(1511);
+
+ _actor3.postInit();
+ _actor3.setup(1853, 3, 1);
+ _actor3.setPosition(Common::Point(122, 113));
+ _actor3.fixPriority(114);
+ _actor3._effect = 6;
+
+ // Totally useless test
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
+ // Dead code
+ _actor3.setDetails(1850, 28, -1, -1, 2, (SceneItem *) NULL);
+ } else {
+ _actor3.setDetails(1850, 30, -1, -1, 2, (SceneItem *) NULL);
+ }
+
+ _actor4.postInit();
+ _actor4.setup(1853, 3, 2);
+ _actor4.setPosition(Common::Point(139, 111));
+ _actor4.fixPriority(114);
+ _actor4._effect = 6;
+
+ // Again, useless test
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
+ // and dead code
+ _actor4.setDetails(1850, 29, -1, -1, 1, (SceneItem *) NULL);
+ } else {
+ _actor4.setDetails(1850, 28, -1, -1, 1, (SceneItem *) NULL);
+ }
+
+ if (R2_GLOBALS.getFlag(31)) {
+ _actor3._shade = 0;
+ _actor4._shade = 0;
+ } else {
+ _actor3._shade = 6;
+ _actor4._shade = 6;
+ }
+ } else {
+ R2_GLOBALS._player.setVisage(1505);
+ _actor1.setVisage(1500);
+ }
+ }
+
+ R2_GLOBALS._player.animate(ANIM_MODE_1, NULL);
+ R2_GLOBALS._player.setStrip(3);
+ R2_GLOBALS._player.setPosition(Common::Point(80, 114));
+
+ _actor1.animate(ANIM_MODE_1, NULL);
+ _actor1.setObjectWrapper(new SceneObjectWrapper());
+ _actor1.setStrip(3);
+ _actor1.setPosition(Common::Point(180, 96));
+
+ if (R2_GLOBALS.getFlag(30)) {
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
+ _actor1.animate(ANIM_MODE_NONE, NULL);
+ _actor1.setObjectWrapper(NULL);
+ if (R2_GLOBALS.getFlag(32)) {
+ _actor1.setup(1854, 1, 3);
+ } else {
+ _actor1.setup(1854, 2, 3);
+ }
+
+ _actor1.setPosition(Common::Point(164, 106));
+ } else {
+ _actor1.animate(ANIM_MODE_NONE, NULL);
+ _actor1.setObjectWrapper(NULL);
+ if (R2_GLOBALS.getFlag(32)) {
+ R2_GLOBALS._player.setup(1854, 1, 3);
+ } else {
+ R2_GLOBALS._player.setup(1854, 2, 3);
+ }
+
+ R2_GLOBALS._player.setPosition(Common::Point(164, 106));
+ }
+ }
+
+ R2_GLOBALS._player.enableControl();
+ } else { // R2_GLOBALS._player._oldCharacterScene[R2_GLOBALS._player._characterIndex] != 1850
+ R2_GLOBALS._player._effect = 1;
+ _actor1._effect = 1;
+ R2_GLOBALS._player.disableControl();
+ _sceneMode = 10;
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
+ if (R2_GLOBALS.getFlag(29)) {
+ setAction(&_sequenceManager1, this, 1863, &R2_GLOBALS._player, &_actor1, &_actor7, NULL);
+ } else {
+ setAction(&_sequenceManager1, this, 1861, &R2_GLOBALS._player, &_actor1, &_actor6, NULL);
+ }
+ } else {
+ if (R2_GLOBALS.getFlag(29)) {
+ setAction(&_sequenceManager1, this, 1864, &R2_GLOBALS._player, &_actor1, &_actor7, NULL);
+ } else {
+ setAction(&_sequenceManager1, this, 1862, &R2_GLOBALS._player, &_actor1, &_actor6, NULL);
+ }
+ }
+ }
+
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
+ R2_GLOBALS._player._moveDiff = Common::Point(3, 2);
+ _actor1._moveDiff = Common::Point(5, 3);
+ } else {
+ R2_GLOBALS._player._moveDiff = Common::Point(5, 3);
+ _actor1._moveDiff = Common::Point(3, 2);
+ }
+
+ _actor8.postInit();
+ _actor8.setup(1850, 1, 1);
+
+ if (R2_GLOBALS.getFlag(62)) {
+ _actor8.setPosition(Common::Point(159, 120));
+ } else {
+ _actor8.setPosition(Common::Point(159, 184));
+ }
+
+ _actor8.fixPriority(113);
+
+ if (R2_GLOBALS.getFlag(34)) {
+ _actor8.setDetails(1850, 25, -1, -1, 4, &_actor5);
+ } else {
+ _actor8.setDetails(1850, 25, -1, -1, 2, (SceneItem *) NULL);
+ }
+
+ if (!R2_GLOBALS.getFlag(62)) {
+ _actor8.hide();
+ }
+
+ _item1.setDetails(Rect(0, 0, 320, 200), 1850, 16, -1, -1, 1, NULL);
+
+ R2_GLOBALS._player._oldCharacterScene[1] = 1850;
+ R2_GLOBALS._player._oldCharacterScene[2] = 1850;
+}
+
+void Scene1850::remove() {
+ g_globals->_scenePalette.loadPalette(0);
+
+ R2_GLOBALS._scenePalette._palette[765] = 255;
+ R2_GLOBALS._scenePalette._palette[766] = 255;
+ R2_GLOBALS._scenePalette._palette[767] = 255;
+
+ SceneExt::remove();
+}
+
+void Scene1850::signal() {
+ switch (_sceneMode) {
+ case 10:
+ R2_GLOBALS._player._effect = 6;
+ R2_GLOBALS._player._shade = 6;
+
+ _actor1._effect = 6;
+ _actor1._shade = 6;
+
+ R2_GLOBALS._walkRegions.enableRegion(5);
+
+ if (R2_GLOBALS.getFlag(68)) {
+ R2_GLOBALS._player.enableControl();
+ } else {
+ R2_GLOBALS.setFlag(68);
+ _sceneMode = 20;
+ R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
+ _stripManager.start(554, this);
+ }
+ break;
+ case 11:
+ R2_GLOBALS.clearFlag(30);
+ R2_GLOBALS._sceneManager.changeScene(1800);
+ break;
+ case 15:
+ _sceneMode = 16;
+ break;
+ case 16:
+ _sceneMode = 1870;
+ setAction(&_sequenceManager1, this, 1870, &R2_GLOBALS._player, &_actor1, &_actor3, &_actor4, NULL);
+ break;
+ case 20:
+ R2_GLOBALS._player.enableControl(CURSOR_TALK);
+ break;
+ case 21:
+ R2_GLOBALS._player.disableControl();
+ _sceneMode = 1877;
+ setAction(&_sequenceManager1, this, 1877, &R2_GLOBALS._player, &_actor1, &_actor5, NULL);
+ break;
+ case 30:
+ R2_GLOBALS._player.disableControl();
+ _sceneMode = 1882;
+ setAction(&_sequenceManager1, this, 1882, &R2_GLOBALS._player, NULL);
+ break;
+ case 1852:
+ // No break on purpose:
+ case 1853:
+ if (_field412 == 1851) {
+ R2_GLOBALS.setFlag(31);
+ _palette1.loadPalette(1850);
+ _field412 = 1850;
+ } else {
+ R2_GLOBALS.clearFlag(31);
+ _palette1.loadPalette(1851);
+ _field412 = 1851;
+ }
+
+ _field418 = 1;
+ if (R2_GLOBALS.getFlag(30)) {
+ _actor8.setAction(&_sequenceManager2, NULL, 1867, &_actor8, NULL);
+ } else if (R2_GLOBALS.getFlag(34)) {
+ if (R2_GLOBALS.getFlag(62)) {
+ R2_GLOBALS.clearFlag(62);
+ _actor8.setAction(&_sequenceManager2, this, 1851, &_actor8, NULL);
+ } else {
+ R2_GLOBALS.setFlag(62);
+ _actor8.setAction(&_sequenceManager2, this, 1850, &_actor8, NULL);
+ }
+ } else if (R2_GLOBALS.getFlag(33)) {
+ R2_GLOBALS.setFlag(62);
+ R2_GLOBALS.setFlag(34);
+ R2_GLOBALS._walkRegions.enableRegion(2);
+
+ _actor2.postInit();
+ _actor2.setDetails(1850, 6, -1, -1, 5, &_actor5);
+
+ _sceneMode = 1879;
+
+ _actor8.setAction(&_sequenceManager2, this, 1879, &_actor5, &_actor8, &_actor2, NULL);
+ } else {
+ _actor8.setAction(&_sequenceManager2, NULL, 1867, &_actor8, NULL);
+ }
+
+ if (R2_GLOBALS.getFlag(34))
+ R2_GLOBALS._scenePalette.addFader(_palette1._palette, 256, 5, NULL);
+ else
+ R2_GLOBALS._scenePalette.addFader(_palette1._palette, 256, 5, this);
+
+ if (_field412 == 1851)
+ _field416 = -20;
+ else
+ _field416 = 20;
+
+ _field414 = 20;
+
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
+ if (_sceneMode == 1879)
+ _sceneMode = 1854;
+
+ if (R2_GLOBALS.getFlag(32)) {
+ setAction(&_sequenceManager1, NULL, 1873, &R2_GLOBALS._player, NULL);
+ } else {
+ setAction(&_sequenceManager1, NULL, 1854, &R2_GLOBALS._player, NULL);
+ }
+ } else {
+ if (_sceneMode == 1879)
+ _sceneMode = 1855;
+
+ if (R2_GLOBALS.getFlag(32)) {
+ setAction(&_sequenceManager1, NULL, 1874, &R2_GLOBALS._player, NULL);
+ } else {
+ setAction(&_sequenceManager1, NULL, 1855, &R2_GLOBALS._player, NULL);
+ }
+ }
+ break;
+ case 1857:
+ if (R2_GLOBALS.getFlag(69)) {
+ R2_GLOBALS._player.enableControl();
+ R2_GLOBALS._player._canWalk = false;
+ } else {
+ _sceneMode = 1858;
+ R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
+ _stripManager.start(555, this);
+ R2_GLOBALS.setFlag(69);
+ }
+ break;
+ case 1858:
+ R2_GLOBALS._player.disableControl();
+ _sceneMode = 1859;
+ setAction(&_sequenceManager1, this, 1859, &R2_GLOBALS._player, &_actor5, NULL);
+ R2_GLOBALS.clearFlag(30);
+ break;
+ case 1859:
+ R2_GLOBALS.setFlag(70);
+ _sceneMode = 20;
+ R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
+ _stripManager.start(575, this);
+ break;
+ case 1860:
+ if (_field41A.x != 0) {
+ R2_GLOBALS._player.enableControl();
+
+ PlayerMover *mover = new PlayerMover();
+ R2_GLOBALS._player.addMover(mover, &_field41A, this);
+
+ _field41A = Common::Point(0, 0);
+ }
+
+ switch (_field41E) {
+ case 1:
+ _sceneMode = 1853;
+ if (R2_GLOBALS.getFlag(32)) {
+ setAction(&_sequenceManager1, this, 1872, &R2_GLOBALS._player, NULL);
+ } else {
+ setAction(&_sequenceManager1, this, 1853, &R2_GLOBALS._player, NULL);
+ }
+ break;
+ case 2:
+ _sceneMode = 11;
+ setAction(&_sequenceManager1, this, 1865, &R2_GLOBALS._player, &_actor6, NULL);
+ break;
+ case 3:
+ warning("_field41E == 3");
+ _sceneMode = 11;
+ setAction(&_sequenceManager1, this, 1866, &R2_GLOBALS._player, &_actor7, NULL);
+ break;
+ default:
+ break;
+ }
+
+ _field41E = 0;
+ break;
+ case 1870:
+ R2_GLOBALS._walkRegions.enableRegion(5);
+ R2_INVENTORY.setObjectScene(R2_REBREATHER_TANK, 1);
+ R2_GLOBALS.setFlag(32);
+ R2_GLOBALS._player.enableControl(CURSOR_ARROW);
+ break;
+ case 1875:
+ R2_INVENTORY.setObjectScene(R2_AIRBAG, 1850);
+ _sceneMode = 21;
+ R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
+ _stripManager.start(561, this);
+ break;
+ case 1877:
+ _actor3.postInit();
+ _actor3._effect = 6;
+
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
+ _actor3.setDetails(1850, 28, -1, -1, 2, (SceneItem *)NULL);
+ } else {
+ _actor3.setDetails(1850, 30, -1, -1, 2, (SceneItem *)NULL);
+ }
+
+ _actor4.postInit();
+ _actor4._effect = 6;
+
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
+ _actor4.setDetails(1850, 29, -1, -1, 2, (SceneItem *)NULL);
+ } else {
+ _actor4.setDetails(1850, 28, -1, -1, 2, (SceneItem *)NULL);
+ }
+
+ if (R2_GLOBALS.getFlag(31)) {
+ _actor3._shade = 0;
+ _actor4._shade = 0;
+ } else {
+ _actor3._shade = 6;
+ _actor4._shade = 6;
+ }
+
+ R2_GLOBALS.clearFlag(30);
+ _sceneMode = 15;
+ setAction(&_sequenceManager1, this, 1869, &R2_GLOBALS._player, &_actor3, NULL);
+ setAction(&_sequenceManager2, this, 1868, &_actor1, &_actor4, NULL);
+ break;
+ case 1878:
+ R2_INVENTORY.setObjectScene(R2_REBREATHER_TANK, 1850);
+ R2_GLOBALS.setFlag(33);
+ R2_GLOBALS._walkRegions.enableRegion(2);
+ R2_GLOBALS._player.enableControl();
+ break;
+ case 1879:
+ R2_GLOBALS._player.enableControl();
+ break;
+ case 1881:
+ R2_GLOBALS._sceneManager.changeScene(1875);
+ break;
+ case 1882:
+ R2_INVENTORY.setObjectScene(R2_AIRBAG, 1);
+ R2_GLOBALS._player.enableControl();
+ break;
+ default:
+ R2_GLOBALS._player.enableControl();
+ break;
+ }
+}
+
+void Scene1850::process(Event &event) {
+ if ( (event.eventType == EVENT_BUTTON_DOWN) && (R2_GLOBALS._events.getCursor() == CURSOR_ARROW)
+ && (R2_GLOBALS._player._characterIndex == R2_SEEKER) && (R2_GLOBALS.getFlag(30))) {
+ _field41A = event.mousePos;
+ R2_GLOBALS._player.disableControl();
+ _sceneMode = 1860;
+ if (R2_GLOBALS.getFlag(32)) {
+ setAction(&_sequenceManager1, this, 1860, &R2_GLOBALS._player, &_actor5, NULL);
+ } else {
+ setAction(&_sequenceManager1, this, 1859, &R2_GLOBALS._player, &_actor5, NULL);
+ }
+ R2_GLOBALS.clearFlag(32);
+ event.handled = true;
+ }
+
+ Scene::process(event);
+}
+
+void Scene1850::dispatch() {
+ if (_field418 != 0) {
+ _field414--;
+ if (_field414 == 0)
+ _field418 = 0;
+
+ if (_field416 >= 0) {
+ R2_GLOBALS._player._shade = (_field414 * 6) / _field416;
+ } else {
+ R2_GLOBALS._player._shade = ((_field414 * 6) / _field416) + 6;
+ }
+ R2_GLOBALS._player._flags |= OBJFLAG_PANES;
+
+ _actor1._shade = R2_GLOBALS._player._shade;
+ _actor1._flags |= OBJFLAG_PANES;
+
+ _actor3._shade = R2_GLOBALS._player._shade;
+ _actor3._flags |= OBJFLAG_PANES;
+
+ _actor4._shade = R2_GLOBALS._player._shade;
+ _actor4._flags |= OBJFLAG_PANES;
+ }
+
+ if (R2_GLOBALS.getFlag(32)) {
+ _actor3.setPosition(Common::Point(_actor8._position.x - 37, _actor8._position.y - 71));
+ _actor4.setPosition(Common::Point(_actor8._position.x - 20, _actor8._position.y - 73));
+ }
+
+ if (R2_INVENTORY.getObjectScene(R2_AIRBAG) == 1850) {
+ _actor2.setPosition(Common::Point(_actor8._position.x + 20, _actor8._position.y - 71));
+ }
+
+ Scene::dispatch();
+}
+
+/*--------------------------------------------------------------------------
+ * Scene 1875 -
+ *
+ *--------------------------------------------------------------------------*/
+Scene1875::Actor1875::Actor1875() {
+ _fieldA4 = 0;
+ _fieldA6 = 0;
+}
+
+void Scene1875::Actor1875::synchronize(Serializer &s) {
+ SceneActor::synchronize(s);
+
+ s.syncAsSint16LE(_fieldA4);
+ s.syncAsSint16LE(_fieldA6);
+}
+
+void Scene1875::Actor1875::subB84AB() {
+ Scene1875 *scene = (Scene1875 *)R2_GLOBALS._sceneManager._scene;
+
+ R2_GLOBALS._sound1.play(227);
+
+ int newFrameNumber;
+ switch (_fieldA4) {
+ case 3:
+ if ((scene->_actor1._frame == 1) && (scene->_actor4._strip == 2)) {
+ R2_GLOBALS._player.disableControl();
+ R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
+ scene->_sceneMode = 10;
+ scene->_stripManager.start(576, this);
+ } else {
+ R2_GLOBALS._player.disableControl();
+ scene->_sceneMode = 1890;
+ scene->_actor2.postInit();
+ scene->setAction(&scene->_sequenceManager, scene, 1890, &scene->_actor2, NULL);
+ }
+ break;
+ case 4:
+ newFrameNumber = scene->_actor1._frame + 1;
+ if (newFrameNumber > 6)
+ newFrameNumber = 1;
+ scene->_actor1.setFrame(newFrameNumber);
+ break;
+ case 5:
+ newFrameNumber = scene->_actor1._frame - 1;
+ if (newFrameNumber < 1)
+ newFrameNumber = 6;
+ scene->_actor1.setFrame(newFrameNumber);
+ break;
+ default:
+ break;
+ }
+}
+
+void Scene1875::Actor1875::subB8271(int indx) {
+ postInit();
+ _fieldA4 = indx;
+ _fieldA6 = 0;
+ setVisage(1855);
+
+ if (_fieldA4 == 1)
+ setStrip(2);
+ else
+ setStrip(1);
+
+ setFrame(_fieldA4);
+ switch (_fieldA4 - 1) {
+ case 0:
+ setPosition(Common::Point(20, 144));
+ break;
+ case 1:
+ setPosition(Common::Point(82, 144));
+ break;
+ case 2:
+ setPosition(Common::Point(136, 144));
+ break;
+ case 3:
+ setPosition(Common::Point(237, 144));
+ break;
+ case 4:
+ setPosition(Common::Point(299, 144));
+ break;
+ default:
+ break;
+ }
+
+ setDetails(1875, 6, 1, -1, 2, (SceneItem *) NULL);
+}
+
+void Scene1875::Actor1875::process(Event &event) {
+ if ((R2_GLOBALS._player._uiEnabled) || (event.handled))
+ return;
+
+ Scene1875 *scene = (Scene1875 *)R2_GLOBALS._sceneManager._scene;
+
+ if ((event.eventType == EVENT_BUTTON_DOWN) && (R2_GLOBALS._events.getCursor() == R2_STEPPING_DISKS) && (_bounds.contains(event.mousePos)) && (_fieldA6 == 0)) {
+ setStrip(2);
+ switch (_fieldA4) {
+ case 1:
+ R2_GLOBALS._sound2.play(227);
+ scene->_actor5.setStrip(1);
+ break;
+ case 2:
+ R2_GLOBALS._sound2.play(227);
+ scene->_actor4.setStrip(1);
+ break;
+ default:
+ break;
+ }
+ _fieldA6 = 1;
+ event.handled = true;
+ }
+
+ if ((event.eventType == EVENT_BUTTON_UP) && (_fieldA6 != 0)) {
+ if ((_fieldA4 == 3) || (_fieldA4 == 4) || (_fieldA4 == 5)) {
+ setStrip(1);
+ subB84AB();
+ }
+ _fieldA6 = 0;
+ event.handled = true;
+ }
+}
+
+void Scene1875::postInit(SceneObjectList *OwnerList) {
+ loadScene(1875);
+ SceneExt::postInit();
+
+ R2_GLOBALS._player._characterScene[1] = 1875;
+ R2_GLOBALS._player._characterScene[2] = 1875;
+
+ _stripManager.addSpeaker(&_quinnSpeaker);
+ _stripManager.addSpeaker(&_seekerSpeaker);
+
+ _actor4.subB8271(1);
+ _actor5.subB8271(2);
+ _actor6.subB8271(3);
+ _actor7.subB8271(4);
+ _actor8.subB8271(5);
+
+ _actor1.postInit();
+ _actor1.setup(1855, 4, 1);
+ _actor1.setPosition(Common::Point(160, 116));
+
+ R2_GLOBALS._player.postInit();
+ if (R2_GLOBALS._sceneManager._previousScene == 1625) {
+ R2_GLOBALS._sound1.play(122);
+ R2_GLOBALS._player.disableControl();
+ _sceneMode = 11;
+ _actor2.postInit();
+ setAction(&_sequenceManager, this, 1892, &_actor2, NULL);
+ } else if (R2_GLOBALS._sceneManager._previousScene == 3150) {
+ R2_GLOBALS._sound1.play(116);
+ } else {
+ R2_GLOBALS._player.enableControl();
+ R2_GLOBALS._player._canWalk = false;
+ }
+
+ _item2.setDetails(Rect(43, 14, 275, 122), 1875, 9, 1, -1, 1, NULL);
+ _item1.setDetails(Rect(0, 0, 320, 200), 1875, 3, -1, -1, 1, NULL);
+
+ R2_GLOBALS._player._characterScene[1] = 1875;
+ R2_GLOBALS._player._characterScene[2] = 1875;
+ R2_GLOBALS._player._oldCharacterScene[1] = 1875;
+ R2_GLOBALS._player._oldCharacterScene[2] = 1875;
+}
+
+void Scene1875::signal() {
+ switch (_sceneMode) {
+ case 10:
+ R2_GLOBALS._player.disableControl();
+ _sceneMode = 1891;
+ _actor2.postInit();
+ setAction(&_sequenceManager, this, 1891, &_actor2, NULL);
+ break;
+ case 11:
+ R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
+ _sceneMode = 1892;
+ _stripManager.start(577, this);
+ break;
+ case 1890:
+ _actor2.remove();
+ R2_GLOBALS._player.enableControl();
+ R2_GLOBALS._player._canWalk = false;
+ break;
+ case 1891:
+ R2_GLOBALS._player.disableControl();
+ R2_GLOBALS._sceneManager.changeScene(1625);
+ break;
+ case 1892:
+ R2_GLOBALS._player.disableControl();
+ R2_GLOBALS._sceneManager.changeScene(1900);
+ break;
+ default:
+ R2_GLOBALS._player.enableControl();
+ R2_GLOBALS._player._canWalk = false;
+ break;
+ }
+}
+
+void Scene1875::process(Event &event) {
+ Scene::process(event);
+
+ _actor4.process(event);
+ _actor5.process(event);
+ _actor6.process(event);
+ _actor7.process(event);
+ _actor8.process(event);
+}
+
+/*--------------------------------------------------------------------------
+ * Scene 1900 -
+ *
+ *--------------------------------------------------------------------------*/
+bool Scene1900::Actor2::startAction(CursorType action, Event &event) {
+ Scene1900 *scene = (Scene1900 *)R2_GLOBALS._sceneManager._scene;
+
+ if (action != CURSOR_USE)
+ return SceneActor::startAction(action, event);
+
+ if ((_frame != 1) || (R2_GLOBALS._player._characterIndex != R2_SEEKER)) {
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN)
+ return SceneActor::startAction(action, event);
+ else
+ return true;
+ }
+
+ R2_GLOBALS._player.enableControl(CURSOR_USE);
+
+ if (_position.x >= 160) {
+ scene->_sceneMode = 1905;
+ scene->setAction(&scene->_sequenceManager1, scene, 1905, &R2_GLOBALS._player, &scene->_actor3, NULL);
+ } else {
+ R2_GLOBALS.setFlag(29);
+ scene->_sceneMode = 1904;
+ scene->setAction(&scene->_sequenceManager1, scene, 1904, &R2_GLOBALS._player, &scene->_actor2, NULL);
+ }
+
+ return true;
+}
+
+void Scene1900::Exit1::changeScene() {
+ Scene1900 *scene = (Scene1900 *)R2_GLOBALS._sceneManager._scene;
+
+ R2_GLOBALS._player.disableControl(CURSOR_ARROW);
+ scene->_sceneMode = 10;
+
+ Common::Point pt(-10, 135);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, scene);
+}
+
+void Scene1900::Exit2::changeScene() {
+ Scene1900 *scene = (Scene1900 *)R2_GLOBALS._sceneManager._scene;
+
+ R2_GLOBALS._player.disableControl(CURSOR_ARROW);
+ scene->_sceneMode = 11;
+
+ Common::Point pt(330, 135);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, scene);
+}
+
+void Scene1900::postInit(SceneObjectList *OwnerList) {
+ loadScene(1900);
+ SceneExt::postInit();
+
+ // Debug message, skipped
+
+ if (R2_GLOBALS._sceneManager._previousScene == -1) {
+ R2_GLOBALS._sceneManager._previousScene = 1925;
+ R2_GLOBALS._player._characterIndex = R2_SEEKER;
+ R2_GLOBALS._player._oldCharacterScene[2] = 1925;
+ }
+
+ if (R2_GLOBALS._sceneManager._previousScene != 1875)
+ R2_GLOBALS._sound1.play(200);
+
+ _stripManager.setColors(60, 255);
+ _stripManager.setFontNumber(3);
+ _stripManager.addSpeaker(&_seekerSpeaker);
+
+ _exit1.setDetails(Rect(0, 105, 14, 145), R2_COM_SCANNER, 2000);
+ _exit1.setDest(Common::Point(14, 135));
+
+ _exit2.setDetails(Rect(305, 105, 320, 145), R2_SPENT_POWER_CAPSULE, 2000);
+ _exit2.setDest(Common::Point(315, 135));
+
+ R2_GLOBALS._player.postInit();
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN)
+ R2_GLOBALS._player.setup(2008, 3, 1);
+ else
+ R2_GLOBALS._player.setup(20, 3, 1);
+ R2_GLOBALS._player.animate(ANIM_MODE_1, NULL);
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN)
+ R2_GLOBALS._player._moveDiff = Common::Point(3, 2);
+ else
+ R2_GLOBALS._player._moveDiff = Common::Point(5, 3);
+ R2_GLOBALS._player.disableControl();
+
+ if (R2_GLOBALS._sceneManager._previousScene != 1925)
+ R2_GLOBALS.clearFlag(29);
+
+ _actor2.postInit();
+ _actor2.setup(1901, 1, 1);
+ _actor2.setPosition(Common::Point(95, 109));
+ _actor2.fixPriority(100);
+
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN)
+ _actor2.setDetails(1900, 0, 1, 2, 1, (SceneItem *) NULL);
+ else
+ _actor2.setDetails(1900, 0, 1, -1, 1, (SceneItem *) NULL);
+
+ _actor3.postInit();
+ _actor3.setup(1901, 2, 1);
+ _actor3.setPosition(Common::Point(225, 109));
+ _actor3.fixPriority(100);
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN)
+ _actor3.setDetails(1900, 0, 1, 2, 1, (SceneItem *) NULL);
+ else
+ _actor3.setDetails(1900, 0, 1, -1, 1, (SceneItem *) NULL);
+
+ if (R2_GLOBALS._sceneManager._previousScene != 1875) {
+ _object1.postInit();
+ _object1.setup(1945, 6, 1);
+ _object1.setPosition(Common::Point(96, 109));
+ _object1.fixPriority(80);
+
+ _object2.postInit();
+ _object2.setup(1945, 6, 2);
+ _object2.setPosition(Common::Point(223, 109));
+ _object2.fixPriority(80);
+ }
+
+ if (R2_GLOBALS._player._oldCharacterScene[R2_GLOBALS._player._characterIndex] == 1875) {
+ R2_GLOBALS._player._characterIndex = R2_QUINN;
+ _actor1.postInit();
+ _sceneMode = 20;
+ R2_GLOBALS._player.setAction(&_sequenceManager1, NULL, 1901, &R2_GLOBALS._player, &_actor2, NULL);
+ _actor1.setAction(&_sequenceManager2, this, 1900, &_actor1, &_actor3, NULL);
+ } else if (R2_GLOBALS._player._oldCharacterScene[R2_GLOBALS._player._characterIndex] == 1925) {
+ if (R2_GLOBALS.getFlag(29)) {
+ R2_GLOBALS.clearFlag(29);
+ _actor2.hide();
+
+ R2_GLOBALS._player.setStrip(6);
+ R2_GLOBALS._player.setPosition(Common::Point(90, 106));
+ _sceneMode = 1906;
+ setAction(&_sequenceManager1, this, 1906, &R2_GLOBALS._player, &_actor2, NULL);
+ } else {
+ _actor3.hide();
+ R2_GLOBALS._player.setStrip(5);
+ R2_GLOBALS._player.setPosition(Common::Point(230, 106));
+ _sceneMode = 1907;
+ setAction(&_sequenceManager1, this, 1907, &R2_GLOBALS._player, &_actor3, NULL);
+ }
+
+ if (R2_GLOBALS._player._characterScene[1] == R2_GLOBALS._player._characterScene[2]) {
+ _actor1.postInit();
+ _actor1.setPosition(Common::Point(30, 110));
+ R2_GLOBALS._walkRegions.enableRegion(1);
+ _actor1.setup(2008, 3, 1);
+ _actor1.setDetails(9001, 0, -1, -1, 1, (SceneItem *) NULL);
+ }
+ R2_GLOBALS._player._oldCharacterScene[R2_GLOBALS._player._characterIndex] = 1900;
+ } else if (R2_GLOBALS._player._characterScene[1] == R2_GLOBALS._player._characterScene[2]) {
+ _actor1.postInit();
+ _actor1.setPosition(Common::Point(30, 110));
+ R2_GLOBALS._walkRegions.enableRegion(1);
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
+ _actor1.setup(20, 3, 1);
+ _actor1.setDetails(9002, 1, -1, -1, 1, (SceneItem *) NULL);
+ } else {
+ _actor1.setup(2008, 3, 1);
+ _actor1.setDetails(9001, 0, -1, -1, 1, (SceneItem *) NULL);
+ }
+
+ if (R2_GLOBALS._player._oldCharacterScene[R2_GLOBALS._player._characterIndex] == 2000) {
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
+ if (R2_GLOBALS._v56605[1] == 5) {
+ _sceneMode = 1902;
+ setAction(&_sequenceManager1, this, 1902, &R2_GLOBALS._player, NULL);
+ } else {
+ _sceneMode = 1903;
+ setAction(&_sequenceManager1, this, 1903, &R2_GLOBALS._player, NULL);
+ }
+ } else {
+ if (R2_GLOBALS._v56605[2] == 5) {
+ _sceneMode = 1908;
+ setAction(&_sequenceManager1, this, 1908, &R2_GLOBALS._player, NULL);
+ } else {
+ _sceneMode = 1909;
+ setAction(&_sequenceManager1, this, 1909, &R2_GLOBALS._player, NULL);
+ }
+ }
+ } else {
+ R2_GLOBALS._player.setPosition(Common::Point(160, 135));
+ R2_GLOBALS._player.enableControl();
+ }
+ R2_GLOBALS._player._oldCharacterScene[R2_GLOBALS._player._characterIndex] = 1900;
+ }
+
+ _item2.setDetails(Rect(77, 2, 240, 103), 1900, 6, -1, -1, 1, NULL);
+ _item1.setDetails(Rect(0, 0, 320, 200), 1900, 3, -1, -1, 1, NULL);
+}
+
+void Scene1900::remove() {
+ R2_GLOBALS._sound1.fadeOut(NULL);
+ SceneExt::remove();
+}
+
+void Scene1900::signal() {
+ switch (_sceneMode) {
+ case 10:
+ R2_GLOBALS._v56605[R2_GLOBALS._player._characterIndex] = 5;
+ R2_GLOBALS._sceneManager.changeScene(2000);
+ break;
+ case 11:
+ R2_GLOBALS._v56605[R2_GLOBALS._player._characterIndex] = 6;
+ R2_GLOBALS._sceneManager.changeScene(2000);
+ break;
+ case 20:
+ ++_sceneMode;
+ R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
+ _stripManager.start(1300, this);
+ break;
+ case 21:
+ ++_sceneMode;
+ R2_GLOBALS._player.disableControl();
+ if (R2_GLOBALS._player._action)
+ R2_GLOBALS._player._action->_endHandler = this;
+ else
+ signal();
+ break;
+ case 22:
+ _sceneMode = 1910;
+ _actor1.setAction(&_sequenceManager2, this, 1910, &_actor1, NULL);
+ break;
+ case 1904:
+ R2_GLOBALS._scene1925CurrLevel = -3;
+ // No break on purpose
+ case 1905:
+ R2_GLOBALS._player.disableControl(CURSOR_ARROW);
+ R2_GLOBALS._sceneManager.changeScene(1925);
+ break;
+ case 1910:
+ R2_INVENTORY.setObjectScene(22, 2535);
+ R2_GLOBALS._player.disableControl(CURSOR_ARROW);
+ R2_GLOBALS._player._oldCharacterScene[1] = 1900;
+ R2_GLOBALS._player._oldCharacterScene[2] = 1900;
+ R2_GLOBALS._sceneManager.changeScene(2450);
+ break;
+ case 1906:
+ R2_GLOBALS._scene1925CurrLevel = -3;
+ // No break on purpose
+ default:
+ R2_GLOBALS._player.enableControl();
+ break;
+ }
+}
+
+/*--------------------------------------------------------------------------
+ * Scene 1925 -
+ *
+ *--------------------------------------------------------------------------*/
+Scene1925::Scene1925() {
+ _field9B8 = 0;
+ for (int i = 0; i < 5; i++)
+ _levelResNum[i] = 0;
+}
+
+void Scene1925::synchronize(Serializer &s) {
+ SceneExt::synchronize(s);
+
+ s.syncAsSint16LE(_field9B8);
+ for (int i = 0; i < 5; i++)
+ s.syncAsSint16LE(_levelResNum[i]);
+}
+
+bool Scene1925::Hotspot2::startAction(CursorType action, Event &event) {
+ Scene1925 *scene = (Scene1925 *)R2_GLOBALS._sceneManager._scene;
+
+ if (action != CURSOR_USE)
+ return SceneHotspot::startAction(action, event);
+
+ if ((R2_GLOBALS._player._position.x == 110) && (R2_GLOBALS._player._position.y == 100))
+ return SceneHotspot::startAction(action, event);
+
+ if ((R2_GLOBALS._player._position.x == 154) && (R2_GLOBALS._player._position.y == 20))
+ scene->_sceneMode = 1928;
+ else if ((R2_GLOBALS._player._position.x == 154) && (R2_GLOBALS._player._position.y == 200))
+ scene->_sceneMode = 1929;
+ else
+ scene->_sceneMode = 1930;
+
+ R2_GLOBALS._player.disableControl(CURSOR_ARROW);
+ scene->setAction(&scene->_sequenceManager, scene, scene->_sceneMode, &R2_GLOBALS._player, &scene->_actor1, NULL);
+ return true;
+}
+
+bool Scene1925::Hotspot3::startAction(CursorType action, Event &event) {
+ if ((!R2_GLOBALS.getFlag(29)) || (action != CURSOR_USE))
+ return SceneHotspot::startAction(action, event);
+
+ Scene1925 *scene = (Scene1925 *)R2_GLOBALS._sceneManager._scene;
+
+ R2_GLOBALS._player.disableControl(CURSOR_USE);
+ scene->_sceneMode = 0;
+
+ if ((R2_GLOBALS._player._position.x == 110) && (R2_GLOBALS._player._position.y == 100)) {
+ scene->_exit3._enabled = false;
+ scene->_sceneMode = 1925;
+ scene->setAction(&scene->_sequenceManager, scene, scene->_sceneMode, &R2_GLOBALS._player, &scene->_actor1, NULL);
+ return true;
+ }
+
+ if ((R2_GLOBALS._player._position.x == 154) && (R2_GLOBALS._player._position.y == 20) && (event.mousePos.y >= 30)) {
+ scene->_sceneMode = 1931;
+ } else if ((R2_GLOBALS._player._position.x == 154) && (R2_GLOBALS._player._position.y == 200) && (event.mousePos.y < 140)) {
+ scene->_sceneMode = 1932;
+ } else if ( ( ((R2_GLOBALS._player._position.x == 112) && (R2_GLOBALS._player._position.y == 101))
+ || ((R2_GLOBALS._player._position.x == 154) && (R2_GLOBALS._player._position.y == 110))
+ ) && (event.mousePos.y >= 100)) {
+ scene->_sceneMode = 1926;
+ } else if ( ( ((R2_GLOBALS._player._position.x == 112) && (R2_GLOBALS._player._position.y == 101))
+ || ((R2_GLOBALS._player._position.x == 154) && (R2_GLOBALS._player._position.y == 110))
+ ) && (event.mousePos.y < 60)) {
+ scene->_sceneMode = 1927;
+ } else {
+ R2_GLOBALS._player.enableControl(CURSOR_USE);
+ R2_GLOBALS._player._canWalk = false;
+ }
+
+ if (scene->_sceneMode != 0)
+ scene->setAction(&scene->_sequenceManager, scene, scene->_sceneMode, &R2_GLOBALS._player, NULL);
+
+ return true;
+}
+
+void Scene1925::ExitUp::changeScene() {
+ Scene1925 *scene = (Scene1925 *)R2_GLOBALS._sceneManager._scene;
+
+ _moving = false;
+ R2_GLOBALS._player.disableControl(CURSOR_USE);
+ scene->_sceneMode = 0;
+
+ if ((R2_GLOBALS._player._position.x == 110) && (R2_GLOBALS._player._position.y == 100)) {
+ scene->_exit3._enabled = false;
+ scene->_field9B8 = 1927;
+ scene->_sceneMode = 1925;
+ scene->setAction(&scene->_sequenceManager, scene, scene->_sceneMode, &R2_GLOBALS._player, &scene->_actor1, NULL);
+ return;
+ }
+
+ if ( ((R2_GLOBALS._player._position.x == 112) && (R2_GLOBALS._player._position.y == 101))
+ || ((R2_GLOBALS._player._position.x == 154) && (R2_GLOBALS._player._position.y == 110))) {
+ scene->_sceneMode = 1927;
+ } else if ((R2_GLOBALS._player._position.x == 154) && (R2_GLOBALS._player._position.y == 200)) {
+ scene->_sceneMode = 1932;
+ }
+
+ if (scene->_sceneMode != 0)
+ scene->setAction(&scene->_sequenceManager, scene, scene->_sceneMode, &R2_GLOBALS._player, NULL);
+ else {
+ scene->_sceneMode = 1932;
+ scene->signal();
+ }
+}
+
+void Scene1925::Exit2::changeScene() {
+ Scene1925 *scene = (Scene1925 *)R2_GLOBALS._sceneManager._scene;
+
+ _moving = false;
+ R2_GLOBALS._player.disableControl(CURSOR_USE);
+ scene->_sceneMode = 0;
+
+ if ((R2_GLOBALS._player._position.x == 110) && (R2_GLOBALS._player._position.y == 100)) {
+ scene->_exit3._enabled = false;
+ scene->_field9B8 = 1926;
+ scene->_sceneMode = 1925;
+ scene->setAction(&scene->_sequenceManager, scene, scene->_sceneMode, &R2_GLOBALS._player, &scene->_actor1, NULL);
+ return;
+ }
+
+ if ( ((R2_GLOBALS._player._position.x == 112) && (R2_GLOBALS._player._position.y == 101))
+ || ((R2_GLOBALS._player._position.x == 154) && (R2_GLOBALS._player._position.y == 110))) {
+ scene->_sceneMode = 1926;
+ } else if ((R2_GLOBALS._player._position.x == 154) && (R2_GLOBALS._player._position.y == 20)) {
+ scene->_sceneMode = 1931;
+ }
+
+ if (scene->_sceneMode == 0) {
+ scene->_sceneMode = 1931;
+ scene->signal();
+ } else
+ scene->setAction(&scene->_sequenceManager, scene, scene->_sceneMode, &R2_GLOBALS._player, NULL);
+}
+
+void Scene1925::Exit3::changeScene() {
+ Scene1925 *scene = (Scene1925 *)R2_GLOBALS._sceneManager._scene;
+
+ _moving = false;
+ R2_GLOBALS._player.disableControl(CURSOR_ARROW);
+ scene->_sceneMode = 1921;
+ scene->setAction(&scene->_sequenceManager, scene, scene->_sceneMode, &R2_GLOBALS._player, NULL);
+}
+
+void Scene1925::Exit4::changeScene() {
+ Scene1925 *scene = (Scene1925 *)R2_GLOBALS._sceneManager._scene;
+
+ _moving = false;
+ R2_GLOBALS._player.disableControl(CURSOR_ARROW);
+ scene->_sceneMode = 1920;
+ scene->setAction(&scene->_sequenceManager, scene, scene->_sceneMode, &R2_GLOBALS._player, NULL);
+}
+
+void Scene1925::changeLevel(bool upFlag) {
+ if (R2_GLOBALS._scene1925CurrLevel < 0)
+ R2_GLOBALS._scene1925CurrLevel = 3;
+
+ if (upFlag) {
+ R2_GLOBALS._player.setup(1925, 1, 1);
+ R2_GLOBALS._player.setPosition(Common::Point(154, 200));
+ ++R2_GLOBALS._scene1925CurrLevel;
+ } else {
+ R2_GLOBALS._player.setup(1925, 1, 1);
+ R2_GLOBALS._player.setPosition(Common::Point(154, 20));
+ R2_GLOBALS._scene1925CurrLevel--;
+ }
+
+ switch (R2_GLOBALS._scene1925CurrLevel) {
+ case -1:
+ R2_GLOBALS._sceneManager.changeScene(1945);
+ return;
+ break;
+ case 3:
+ loadScene(_levelResNum[4]);
+ _item2.setDetails(Rect(133, 68, 140, 77), 1925, 3, -1, 5, 2, NULL);
+ _actor1.setDetails(1925, 0, 1, 2, 2, (SceneItem *) NULL);
+ _actor1.show();
+ break;
+ case 512:
+ R2_GLOBALS._scene1925CurrLevel = 508;
+ // No break on purpose
+ default:
+ loadScene(_levelResNum[(R2_GLOBALS._scene1925CurrLevel % 4)]);
+ R2_GLOBALS._sceneItems.remove(&_item2);
+ R2_GLOBALS._sceneItems.remove(&_actor1);
+ _actor1.hide();
+ break;
+ }
+
+ R2_GLOBALS._player.enableControl(CURSOR_USE);
+ R2_GLOBALS._player._canWalk = false;
+}
+
+void Scene1925::postInit(SceneObjectList *OwnerList) {
+ _levelResNum[0] = 1930;
+ _levelResNum[1] = 1935;
+ _levelResNum[2] = 1940;
+ _levelResNum[3] = 1935;
+ _levelResNum[4] = 1925;
+
+ if (R2_GLOBALS.getFlag(29)) {
+ if ((R2_GLOBALS._scene1925CurrLevel == -3) || (R2_GLOBALS._scene1925CurrLevel == 3))
+ loadScene(_levelResNum[4]);
+ else
+ loadScene(_levelResNum[R2_GLOBALS._scene1925CurrLevel % 4]);
+ } else {
+ R2_GLOBALS._scene1925CurrLevel = -2;
+ loadScene(1920);
+ }
+ SceneExt::postInit();
+ R2_GLOBALS._sound1.play(220);
+ R2_GLOBALS._player.postInit();
+ R2_GLOBALS._player.disableControl();
+ R2_GLOBALS._player._characterScene[2] = 1925;
+ R2_GLOBALS._player._characterIndex = R2_SEEKER;
+ switch (R2_GLOBALS._scene1925CurrLevel) {
+ case -2:
+ _exit4.setDetails(Rect(203, 44, 247, 111), EXITCURSOR_E, 1925);
+ _item3.setDetails(Rect(31, 3, 45, 167), 1925, 6, -1, 8, 1, NULL);
+ break;
+ case 3:
+ _actor1.setDetails(1925, 0, 1, 2, 1, (SceneItem *) NULL);
+ _item2.setDetails(Rect(133, 68, 140, 77), 1925, 3, -1, 5, 1, NULL);
+ // No break on purpose
+ case -3:
+ _exit3.setDetails(Rect(83, 38, 128, 101), EXITCURSOR_W, 1925);
+ // No break on purpose
+ default:
+ _exitUp.setDetails(Rect(128, 0, 186, 10), EXITCURSOR_N, 1925);
+ _exit2.setDetails(Rect(128, 160, 190, 167), EXITCURSOR_S, 1925);
+ _item3.setDetails(Rect(141, 11, 167, 159), 1925, 6, -1, -1, 1, NULL);
+ break;
+ }
+
+ _actor1.postInit();
+ _actor1.setup(1925, 5, 1);
+ _actor1.setPosition(Common::Point(128, 35));
+ _actor1.hide();
+
+ if (R2_GLOBALS._scene1925CurrLevel == 3)
+ _actor1.show();
+
+ R2_GLOBALS._player.enableControl(CURSOR_USE);
+ switch (R2_GLOBALS._scene1925CurrLevel) {
+ case -2:
+ R2_GLOBALS._player.setup(20, 6, 1);
+ R2_GLOBALS._player.animate(ANIM_MODE_1, NULL);
+ R2_GLOBALS._player.setPosition(Common::Point(224, 109));
+ break;
+ case -3:
+ _actor1.hide();
+ R2_GLOBALS._player.setup(20, 5, 1);
+ R2_GLOBALS._player.setPosition(Common::Point(110, 100));
+ break;
+ case 0:
+ R2_GLOBALS._player.setup(1925, 1, 1);
+ R2_GLOBALS._player.setPosition(Common::Point(154, 200));
+ break;
+ default:
+ R2_GLOBALS._player.setup(1925, 1, 3);
+ R2_GLOBALS._player.setPosition(Common::Point(154, 110));
+ break;
+ }
+
+ R2_GLOBALS._player._canWalk = false;
+ _field9B8 = 0;
+ R2_GLOBALS._sceneManager._previousScene = 1925;
+ _item1.setDetails(Rect(27, 0, 292, 200), 1925, 9, -1, -1, 1, NULL);
+}
+
+void Scene1925::remove() {
+ R2_GLOBALS._sound1.fadeOut2(NULL);
+ R2_GLOBALS._player._oldCharacterScene[2] = 1925;
+ SceneExt::remove();
+}
+
+void Scene1925::signal() {
+ switch (_sceneMode) {
+ case 1920:
+ // No break on purpose
+ case 1921:
+ // No break on purpose
+ case 1928:
+ // No break on purpose
+ case 1929:
+ // No break on purpose
+ case 1930:
+ R2_GLOBALS._scene1925CurrLevel = -3;
+ R2_GLOBALS._sceneManager.changeScene(1900);
+ break;
+ case 1926:
+ // No break on purpose
+ case 1931:
+ // Change level, down
+ changeLevel(false);
+ break;
+ case 1927:
+ // No break on purpose
+ case 1932:
+ // Change level, up
+ changeLevel(true);
+ break;
+ case 1925:
+ _exit3._enabled = false;
+ if (_field9B8 != 0) {
+ _sceneMode = _field9B8;
+ _field9B8 = 0;
+ setAction(&_sequenceManager, this, _sceneMode, &R2_GLOBALS._player, NULL);
+ }
+ // No break on purpose
+ default:
+ R2_GLOBALS._player.enableControl(CURSOR_USE);
+ break;
+ }
+
+ R2_GLOBALS._player._canWalk = false;
+}
+
+/*--------------------------------------------------------------------------
+ * Scene 1945 -
+ *
+ *--------------------------------------------------------------------------*/
+Scene1945::Scene1945() {
+ _fieldEAA = 0;
+ _fieldEAC = 0;
+ _fieldEAE = CURSOR_NONE;
+}
+
+void Scene1945::synchronize(Serializer &s) {
+ SceneExt::synchronize(s);
+
+ s.syncAsSint16LE(_fieldEAA);
+ s.syncAsSint16LE(_fieldEAC);
+ s.syncAsSint16LE(_fieldEAE);
+}
+
+bool Scene1945::Hotspot3::startAction(CursorType action, Event &event) {
+ Scene1945 *scene = (Scene1945 *)R2_GLOBALS._sceneManager._scene;
+
+ switch (action) {
+ case R2_GUNPOWDER:
+ R2_GLOBALS._player.disableControl();
+ scene->_sceneMode = 0;
+ if ((R2_GLOBALS._player._position.x == 191) && (R2_GLOBALS._player._position.y == 142))
+ scene->_sceneMode = 1942;
+ else {
+ scene->_sceneMode = 1940;
+ scene->_fieldEAA = 1942;
+ }
+ // At this point the original check if _sceneMode != 0. Skipped.
+ scene->setAction(&scene->_sequenceManager1, scene, scene->_sceneMode, &R2_GLOBALS._player, NULL);
+ return true;
+ break;
+ case CURSOR_USE:
+ R2_GLOBALS._player.disableControl(CURSOR_USE);
+ scene->_sceneMode = 0;
+ if ((R2_GLOBALS._player._position.x == 154) && (R2_GLOBALS._player._position.y == 50) && (event.mousePos.x >= 130)) {
+ scene->_sceneMode = 1940;
+ // At this point the original check if _sceneMode != 0. Skipped.
+ scene->setAction(&scene->_sequenceManager1, scene, scene->_sceneMode, &R2_GLOBALS._player, NULL);
+ return true;
+ } else {
+ R2_GLOBALS._player.enableControl(CURSOR_USE);
+ R2_GLOBALS._player._canWalk = false;
+ if (event.mousePos.x > 130)
+ scene->_item3.setDetails(1945, 3, -1, -1, 3, (SceneItem *) NULL);
+ else
+ scene->_item3.setDetails(1945, 3, -1, 5, 3, (SceneItem *) NULL);
+ }
+ // No break on purpose
+ default:
+ return SceneHotspot::startAction(action, event);
+ break;
+ }
+}
+
+bool Scene1945::Hotspot4::startAction(CursorType action, Event &event) {
+ Scene1945 *scene = (Scene1945 *)R2_GLOBALS._sceneManager._scene;
+
+ if (action != CURSOR_USE)
+ return SceneHotspot::startAction(action, event);
+
+ R2_GLOBALS._player.disableControl(CURSOR_USE);
+ scene->_sceneMode = 0;
+
+ if ((R2_GLOBALS._player._position.x == 221) && (R2_GLOBALS._player._position.y == 142)) {
+ scene->_sceneMode = 1949;
+ scene->_fieldEAA = 1947;
+ } else if ( ((R2_GLOBALS._player._position.x == 197) && (R2_GLOBALS._player._position.y == 158))
+ || ((R2_GLOBALS._player._position.x == 191) && (R2_GLOBALS._player._position.y == 142)) ) {
+ scene->_sceneMode = 1947;
+ } else if ((R2_GLOBALS._player._position.x == 221) && (R2_GLOBALS._player._position.y == 142) && (event.mousePos.y >= 30)) {
+ scene->_sceneMode = 1940;
+ } else {
+ R2_GLOBALS._player.enableControl(CURSOR_USE);
+ R2_GLOBALS._player._canWalk = false;
+ }
+
+ if (scene->_sceneMode != 0)
+ scene->setAction(&scene->_sequenceManager1, scene, scene->_sceneMode, &R2_GLOBALS._player, NULL);
+
+ return true;
+}
+
+bool Scene1945::Actor3::startAction(CursorType action, Event &event) {
+ if ((action == R2_ALCOHOL_LAMP_3) && (action == R2_ALCOHOL_LAMP_2)) {
+ Scene1945 *scene = (Scene1945 *)R2_GLOBALS._sceneManager._scene;
+
+ scene->_fieldEAE = action;
+ R2_GLOBALS._player.disableControl();
+ scene->_sceneMode = 0;
+ if ((R2_GLOBALS._player._position.x == 191) && (R2_GLOBALS._player._position.y == 142)) {
+ scene->_sceneMode= 1947;
+ scene->_fieldEAA = 1943;
+ } else if ((R2_GLOBALS._player._position.x == 154) && (R2_GLOBALS._player._position.y == 50)) {
+ scene->_sceneMode = 1940;
+ scene->_fieldEAA = 1943;
+ } else {
+ scene->_sceneMode = 1949;
+ scene->_fieldEAA = 1947;
+ scene->_fieldEAC = 1943;
+ }
+ // At this point the original check if _sceneMode != 0. Skipped.
+ scene->setAction(&scene->_sequenceManager1, scene, scene->_sceneMode, &R2_GLOBALS._player, NULL);
+ return true;
+ } else {
+ return SceneActor::startAction(action, event);
+ }
+}
+
+void Scene1945::ExitUp::changeScene() {
+ Scene1945 *scene = (Scene1945 *)R2_GLOBALS._sceneManager._scene;
+
+ _moving = false;
+ R2_GLOBALS._player.disableControl(CURSOR_USE);
+ scene->_sceneMode = 0;
+
+ if ((R2_GLOBALS._player._position.x == 221) && (R2_GLOBALS._player._position.y == 142)) {
+ scene->_sceneMode = 1949;
+ scene->_fieldEAA = 1947;
+ } else if ( ((R2_GLOBALS._player._position.x == 197) && (R2_GLOBALS._player._position.y == 158))
+ || ((R2_GLOBALS._player._position.x == 191) && (R2_GLOBALS._player._position.y == 142)) ) {
+ scene->_sceneMode = 1947;
+ }
+
+ if (scene->_sceneMode == 0) {
+ scene->_sceneMode = 1941;
+ signal();
+ } else {
+ scene->setAction(&scene->_sequenceManager1, scene, scene->_sceneMode, &R2_GLOBALS._player, NULL);
+ }
+}
+
+void Scene1945::Exit2::changeScene() {
+ Scene1945 *scene = (Scene1945 *)R2_GLOBALS._sceneManager._scene;
+
+ _moving = false;
+ R2_GLOBALS._player.disableControl(CURSOR_USE);
+ scene->_sceneMode = 0;
+
+ if ((R2_GLOBALS._player._position.x == 154) && (R2_GLOBALS._player._position.y == 50)) {
+ scene->_sceneMode = 1940;
+ scene->_fieldEAA = 1945;
+ } else if ( ((R2_GLOBALS._player._position.x == 197) && (R2_GLOBALS._player._position.y == 158))
+ || ((R2_GLOBALS._player._position.x == 191) && (R2_GLOBALS._player._position.y == 142)) ) {
+ scene->_sceneMode = 1945;
+ }
+
+ if (scene->_sceneMode != 0)
+ scene->setAction(&scene->_sequenceManager1, scene, scene->_sceneMode, &R2_GLOBALS._player, NULL);
+}
+
+void Scene1945::postInit(SceneObjectList *OwnerList) {
+ loadScene(1945);
+ SceneExt::postInit();
+ R2_GLOBALS._sound1.play(220);
+
+ R2_GLOBALS._player.postInit();
+ R2_GLOBALS._player.enableControl(CURSOR_USE);
+ R2_GLOBALS._player._canWalk = false;
+ R2_GLOBALS._player._characterScene[2] = 1945;
+ R2_GLOBALS._player._characterIndex = R2_SEEKER;
+
+ _exitUp.setDetails(Rect(128, 0, 186, 10), EXITCURSOR_N, 1945);
+ _exit2.setDetails(Rect(238, 144, 274, 167), EXITCURSOR_E, 1945);
+
+ _item4.setDetails(Rect(141, 3, 167, 126), 1945, 9, -1, -1, 1, NULL);
+
+ if (!R2_GLOBALS.getFlag(43)) {
+ _exit2._enabled = false;
+ _actor3.postInit();
+ _actor3.setup(1945, 4, 1);
+ _actor3.setPosition(Common::Point(253, 169));
+ _actor3.fixPriority(150);
+
+ if (R2_GLOBALS.getFlag(42))
+ _actor3.setDetails(1945, 15, -1, -1, 1, (SceneItem *) NULL);
+ else
+ _actor3.hide();
+
+ _actor1.postInit();
+ _actor1.setup(1945, 8, 1);
+ _actor1.setPosition(Common::Point(253, 169));
+ _actor1.fixPriority(130);
+
+ _actor2.postInit();
+ _actor2.setup(1945, 3, 1);
+ _actor2.hide();
+ } else {
+ _exit2._enabled = true;
+ }
+
+ switch (R2_GLOBALS._sceneManager._previousScene) {
+ case 1925:
+ R2_GLOBALS._scene1925CurrLevel = 0;
+ R2_GLOBALS.clearFlag(29);
+ R2_GLOBALS._player.setup(1925, 1, 10);
+ R2_GLOBALS._player.setPosition(Common::Point(154, 50));
+ break;
+ case 1950:
+ _sceneMode = 1944;
+ setAction(&_sequenceManager1, this, _sceneMode, &R2_GLOBALS._player, NULL);
+ R2_GLOBALS._player.disableControl(CURSOR_USE);
+ break;
+ default:
+ R2_GLOBALS._player.animate(ANIM_MODE_1, NULL);
+ R2_GLOBALS._player.setup(20, 5, 1);
+ R2_GLOBALS._player.setPosition(Common::Point(191, 142));
+ break;
+ }
+
+ R2_GLOBALS._player._canWalk = false;
+ _fieldEAA = 0;
+ _fieldEAC = 0;
+
+ _item3.setDetails(11, 1945, 3, -1, 5);
+ _item1.setDetails(Rect(238, 144, 274, 167), 1945, 0, -1, 2, 1, NULL);
+ _item2.setDetails(Rect(27, 3, 292, 167), 1945, 3, -1, -1, 1, NULL);
+}
+
+void Scene1945::remove() {
+ R2_GLOBALS._sound1.fadeOut2(NULL);
+ SceneExt::remove();
+}
+
+void Scene1945::signal() {
+ switch (_sceneMode) {
+ case 1940:
+ if (_fieldEAA == 1943) {
+ _sceneMode = _fieldEAA;
+ setAction(&_sequenceManager1, this, _sceneMode, &R2_GLOBALS._player, &_actor2, NULL);
+ } else {
+ _sceneMode = 1946;
+ setAction(&_sequenceManager1, this, _sceneMode, &R2_GLOBALS._player, NULL);
+ }
+ return;
+ break;
+ case 1941:
+ if (_fieldEAA == 0) {
+ R2_GLOBALS._scene1925CurrLevel = 0;
+ R2_GLOBALS.setFlag(29);
+ R2_GLOBALS._sceneManager.changeScene(1925);
+ } else {
+ _sceneMode = _fieldEAA;
+ _fieldEAA = 0;
+ setAction(&_sequenceManager1, this, _sceneMode, &R2_GLOBALS._player, NULL);
+ }
+ return;
+ case 1942:
+ R2_INVENTORY.setObjectScene(R2_GUNPOWDER, 0);
+ _actor3.setDetails(1945, 15, -1, -1, 2, (SceneItem *) NULL);
+ R2_GLOBALS.setFlag(42);
+ break;
+ case 1943:
+ R2_GLOBALS._sound1.fadeOut2(NULL);
+ R2_INVENTORY.setObjectScene(_fieldEAE, 0);
+ _sceneMode = 1948;
+ setAction(&_sequenceManager1, this, _sceneMode, &_actor3, &_actor2, &_actor1, NULL);
+ setAction(&_sequenceManager2, NULL, 1941, &R2_GLOBALS._player, NULL);
+ return;
+ case 1944:
+ break;
+ case 1945:
+ R2_GLOBALS._sceneManager.changeScene(1950);
+ return;
+ case 1946:
+ if (_fieldEAA == 1942) {
+ _sceneMode = _fieldEAA;
+ _fieldEAA = 0;
+ setAction(&_sequenceManager1, this, _sceneMode, &R2_GLOBALS._player, &_actor3, NULL);
+ return;
+ }
+ break;
+ case 1947:
+ if (_fieldEAA == 1943) {
+ _sceneMode = _fieldEAA;
+ _fieldEAA = 1948;
+ setAction(&_sequenceManager1, this, _sceneMode, &R2_GLOBALS._player, &_actor2, NULL);
+ } else {
+ _sceneMode = 1941;
+ setAction(&_sequenceManager1, this, _sceneMode, &R2_GLOBALS._player, NULL);
+ }
+ return;
+ case 1948:
+ R2_GLOBALS._sound1.play(220);
+ _exit2._enabled = true;
+ R2_GLOBALS._sceneItems.remove(&_actor3);
+ R2_GLOBALS.clearFlag(42);
+ R2_GLOBALS.clearFlag(43);
+ _fieldEAA = 1940;
+ // No break on purpose
+ case 1949:
+ _sceneMode = _fieldEAA;
+ if (_fieldEAC == 1943) {
+ _fieldEAA = _fieldEAC;
+ _fieldEAC = 0;
+ setAction(&_sequenceManager1, this, _sceneMode, &R2_GLOBALS._player, &_actor2, NULL);
+ } else {
+ _fieldEAA = 0;
+ setAction(&_sequenceManager1, this, _sceneMode, &R2_GLOBALS._player, NULL);
+ }
+ return;
+ default:
+ break;
+ }
+
+ R2_GLOBALS._player.enableControl(CURSOR_USE);
+ R2_GLOBALS._player._canWalk = false;
+}
+
+/*--------------------------------------------------------------------------
+ * Scene 1950 -
+ *
+ *--------------------------------------------------------------------------*/
+Scene1950::Area1::Area1() {
+ _field20 = 0;
+ _fieldB65 = 0;
+}
+void Scene1950::Area1::synchronize(Serializer &s) {
+ SceneArea::synchronize(s);
+
+ s.syncAsByte(_field20);
+ s.syncAsSint16LE(_fieldB65);
+}
+
+Scene1950::Scene1950() {
+ _field412 = 0;
+ _field414 = 0;
+ _field416 = 0;
+ _field418 = Common::Point(0, 0);
+ _field41C = 0;
+}
+
+void Scene1950::synchronize(Serializer &s) {
+ SceneExt::synchronize(s);
+
+ s.syncAsSint16LE(_field412);
+ s.syncAsSint16LE(_field414);
+ s.syncAsSint16LE(_field416);
+ s.syncAsSint16LE(_field418.x);
+ s.syncAsSint16LE(_field418.y);
+ s.syncAsSint16LE(_field41C);
+}
+
+Scene1950::Area1::Actor10::Actor10() {
+ _fieldA4 = 0;
+ _fieldA6 = 0;
+ _fieldA8 = 0;
+}
+
+void Scene1950::Area1::Actor10::synchronize(Serializer &s) {
+ SceneActor::synchronize(s);
+
+ s.syncAsSint16LE(_fieldA4);
+ s.syncAsSint16LE(_fieldA6);
+ s.syncAsSint16LE(_fieldA8);
+}
+
+void Scene1950::Area1::Actor10::init(int indx) {
+// Scene1950 *scene = (Scene1950 *)R2_GLOBALS._sceneManager._scene;
+
+ _fieldA4 = indx;
+ _fieldA6 = 0;
+ _fieldA8 = 0;
+
+ postInit();
+ setup(1971, 2, 1);
+ fixPriority(249);
+ setPosition(Common::Point(((_fieldA4 / 4) * 22) + 127, ((_fieldA4 / 4) * 19) + 71));
+ warning("FIXME: invalid call to scene->_sceneAreas.push_front(this);");
+}
+
+void Scene1950::Area1::Actor10::process(Event &event) {
+ if ((event.eventType == EVENT_BUTTON_DOWN) && (R2_GLOBALS._events.getCursor() == CURSOR_USE) && (_bounds.contains(event.mousePos)) && (_fieldA6 == 0)) {
+ R2_GLOBALS._sound2.play(227);
+ if (_fieldA8 == 0) {
+ setFrame(2);
+ _fieldA8 = 1;
+ } else {
+ setFrame(1);
+ _fieldA8 = 0;
+ }
+ _fieldA6 = 1;
+ event.handled = true;
+ }
+
+ if ((event.eventType == EVENT_BUTTON_UP) && (_fieldA6 != 0)) {
+ _fieldA6 = 0;
+ event.handled = true;
+ Scene1950 *scene = (Scene1950 *)R2_GLOBALS._sceneManager._scene;
+ scene->subBF4B4(_fieldA4);
+ }
+}
+
+bool Scene1950::Area1::Actor10::startAction(CursorType action, Event &event) {
+ if (action == CURSOR_USE)
+ return false;
+ return SceneActor::startAction(action, event);
+}
+
+void Scene1950::Area1::remove() {
+ Scene1950 *scene = (Scene1950 *)R2_GLOBALS._sceneManager._scene;
+ for (_fieldB65 = 0; _fieldB65 < 16; ++_fieldB65) {
+ warning("Unexpected _sceneAreas.remove() call");
+ // R2_GLOBALS._sceneAreas.remove(&_arrActor1[_fieldB65]);
+ _arrActor1[_fieldB65].remove();
+ }
+
+ // sub201EA
+ R2_GLOBALS._sceneItems.remove((SceneItem *)this);
+ _areaActor.remove();
+ SceneArea::remove();
+ R2_GLOBALS._insetUp--;
+ //
+
+ if (!R2_GLOBALS.getFlag(37))
+ R2_GLOBALS._sound2.play(278);
+
+ R2_GLOBALS._player.disableControl(CURSOR_ARROW);
+ scene->_exit3._enabled = true;
+
+ if (!R2_GLOBALS.getFlag(37)) {
+ if (R2_GLOBALS.getFlag(36)) {
+ scene->_sceneMode = 1964;
+ scene->setAction(&scene->_sequenceManager, scene, 1964, &R2_GLOBALS._player, NULL);
+ } else {
+ scene->_sceneMode = 1965;
+ scene->setAction(&scene->_sequenceManager, scene, 1965, &R2_GLOBALS._player, NULL);
+ }
+ }
+}
+
+void Scene1950::Area1::process(Event &event) {
+// This is a copy of Scene1200::Area1::process
+ if (_field20 != R2_GLOBALS._insetUp)
+ return;
+
+ CursorType cursor = R2_GLOBALS._events.getCursor();
+
+ if (_areaActor._bounds.contains(event.mousePos.x + g_globals->gfxManager()._bounds.left , event.mousePos.y)) {
+ if (cursor == _cursorNum)
+ warning("TODO: _cursorState = ???");
+ R2_GLOBALS._events.setCursor(_savedCursorNum); //, _cursorState);
+ } else if (event.mousePos.y < 168) {
+ if (cursor != _cursorNum) {
+ _savedCursorNum = cursor;
+ warning("TODO: _cursorState = ???");
+ R2_GLOBALS._events.setCursor(CURSOR_INVALID);
+ }
+ if (event.eventType == EVENT_BUTTON_DOWN) {
+ event.handled = true;
+ warning("TODO: _cursorState = ???");
+ R2_GLOBALS._events.setCursor(_savedCursorNum); //, _cursorState);
+ remove();
+ }
+ }
+}
+
+void Scene1950::Area1::proc12(int visage, int stripFrameNum, int frameNum, int posX, int posY) {
+ Scene1950 *scene = (Scene1950 *)R2_GLOBALS._sceneManager._scene;
+
+ if (R2_GLOBALS._player._mover)
+ R2_GLOBALS._player.addMover(NULL);
+ R2_GLOBALS._player._canWalk = false;
+
+ // UnkArea1200::proc12();
+ _areaActor.postInit();
+ _areaActor.setup(visage, stripFrameNum, frameNum);
+ _areaActor.setPosition(Common::Point(posX, posY));
+ _areaActor.fixPriority(250);
+ _cursorNum = CURSOR_INVALID;
+ scene->_sceneAreas.push_front(this);
+ ++R2_GLOBALS._insetUp;
+ _field20 = R2_GLOBALS._insetUp;
+ //
+
+ _areaActor.fixPriority(248);
+ scene->_exit3._enabled = false;
+ proc13(1950, 27, 28, 27);
+
+ for (_fieldB65 = 0; _fieldB65 < 16; _fieldB65++)
+ _arrActor1[_fieldB65].init(_fieldB65);
+}
+
+void Scene1950::Area1::proc13(int resNum, int lookLineNum, int talkLineNum, int useLineNum) {
+ // Copy of Scene1200::Area1::proc13()
+ _areaActor.setDetails(resNum, lookLineNum, talkLineNum, useLineNum, 2, (SceneItem *) NULL);
+}
+
+bool Scene1950::Hotspot2::startAction(CursorType action, Event &event) {
+ if ((action != CURSOR_USE) || (R2_GLOBALS.getFlag(37)))
+ return SceneHotspot::startAction(action, event);
+
+ Scene1950 *scene = (Scene1950 *)R2_GLOBALS._sceneManager._scene;
+
+ R2_GLOBALS._player.disableControl();
+ if (R2_GLOBALS.getFlag(36)) {
+ scene->_sceneMode = 1962;
+ scene->setAction(&scene->_sequenceManager, scene, 1962, &R2_GLOBALS._player, NULL);
+ } else {
+ scene->_sceneMode = 1963;
+ scene->setAction(&scene->_sequenceManager, scene, 1963, &R2_GLOBALS._player, NULL);
+ }
+ return true;
+}
+
+bool Scene1950::Actor2::startAction(CursorType action, Event &event) {
+ if (action != R2_SCRITH_KEY)
+ return SceneActor::startAction(action, event);
+
+ Scene1950 *scene = (Scene1950 *)R2_GLOBALS._sceneManager._scene;
+
+ R2_GLOBALS._player.disableControl();
+ R2_INVENTORY.setObjectScene(31, 0);
+ scene->_sceneMode = 1958;
+ scene->setAction(&scene->_sequenceManager, scene, 1958, &R2_GLOBALS._player, &scene->_actor2, NULL);
+ return true;
+}
+
+bool Scene1950::Actor3::startAction(CursorType action, Event &event) {
+ if ((action != CURSOR_USE) || (R2_INVENTORY.getObjectScene(35) != 1950))
+ return SceneActor::startAction(action, event);
+
+ Scene1950 *scene = (Scene1950 *)R2_GLOBALS._sceneManager._scene;
+
+ R2_GLOBALS._player.disableControl();
+ scene->_sceneMode = 1968;
+ scene->setAction(&scene->_sequenceManager, scene, 1968, &R2_GLOBALS._player, NULL);
+
+ return true;
+}
+
+bool Scene1950::Actor5::startAction(CursorType action, Event &event) {
+ if ((action != CURSOR_USE) || (!R2_GLOBALS.getFlag(37)))
+ return SceneActor::startAction(action, event);
+
+ Scene1950 *scene = (Scene1950 *)R2_GLOBALS._sceneManager._scene;
+
+ R2_GLOBALS._player.disableControl();
+ scene->_sceneMode = 1967;
+ scene->setAction(&scene->_sequenceManager, scene, 1967, &R2_GLOBALS._player, NULL);
+
+ return true;
+}
+
+Scene1950::Actor8::Actor8() {
+ _fieldA4 = 0;
+ _fieldA6 = 0;
+ _fieldA8 = 0;
+ _fieldAA = 0;
+ _fieldAC = 0;
+ _fieldAE = 0;
+ _fieldAF = 0;
+}
+
+void Scene1950::Actor8::synchronize(Serializer &s) {
+ SceneActor::synchronize(s);
+
+ s.syncAsSint16LE(_fieldA4);
+ s.syncAsSint16LE(_fieldA6);
+ s.syncAsSint16LE(_fieldA8);
+ s.syncAsSint16LE(_fieldAA);
+ s.syncAsSint16LE(_fieldAC);
+ s.syncAsByte(_fieldAE);
+ s.syncAsByte(_fieldAF);
+}
+
+void Scene1950::Actor8::signal() {
+ Scene1950 *scene = (Scene1950 *)R2_GLOBALS._sceneManager._scene;
+
+ switch (_fieldAC) {
+ case 19: {
+ _fieldAC = 0;
+ setVisage(1960);
+ if (R2_GLOBALS._v566A5 == 3)
+ setStrip(2);
+ else
+ setStrip(1);
+
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &scene->_field418, this);
+ }
+ break;
+ case 20: {
+ _fieldAC = 19;
+ R2_GLOBALS._player.setVisage(22);
+ if (R2_GLOBALS._v566A5 == 3)
+ R2_GLOBALS._player.setStrip(1);
+ else
+ R2_GLOBALS._player.setStrip(2);
+ R2_GLOBALS._player.animate(ANIM_MODE_1, NULL);
+ R2_GLOBALS._v56613[((scene->_field41C - 1) * 4) + 1]--;
+
+ if (R2_GLOBALS._v566A5 == 3)
+ _fieldA4 = _position.x + 10;
+ else
+ _fieldA4 = _position.x - 10;
+
+ _fieldA6 = _position.y -4;
+ setVisage(1961);
+
+ if (R2_GLOBALS._v566A5 == 3)
+ setStrip(2);
+ else
+ setStrip(1);
+
+ animate(ANIM_MODE_2, NULL);
+ Common::Point pt(_fieldA4, _fieldA6);
+ PlayerMover *mover = new PlayerMover();
+ addMover(mover, &pt, this);
+
+ R2_GLOBALS._player.enableControl();
+ }
+ break;
+ case 21:
+ R2_GLOBALS._player.setVisage(22);
+ if (R2_GLOBALS._v566A5 == 3)
+ R2_GLOBALS._player.setStrip(1);
+ else
+ R2_GLOBALS._player.setStrip(2);
+ R2_GLOBALS._player.animate(ANIM_MODE_1, NULL);
+
+ setVisage(1961);
+ if (R2_GLOBALS._v566A5 == 3)
+ setStrip(4);
+ else
+ setStrip(3);
+ setDetails(1950, 15, -1, 17, 2, (SceneItem *) NULL);
+ addMover(NULL);
+ _numFrames = 8;
+ R2_GLOBALS._sound2.play(226);
+ animate(ANIM_MODE_5, NULL);
+ fixPriority(10);
+ R2_GLOBALS._v56613[((scene->_field41C - 1) * 4) ]--;
+ R2_GLOBALS._v56613[((scene->_field41C - 1) * 4) + 1]--;
+ R2_GLOBALS._v56613[((scene->_field41C - 1) * 4) + 2] = _position.x;
+ R2_GLOBALS._v56613[((scene->_field41C - 1) * 4) + 3] = _position.y;
+ _fieldA8 = (_position.x - R2_GLOBALS._player._position.x) / 2;
+ _fieldAA = (_position.y - R2_GLOBALS._player._position.y) / 2;
+
+ _fieldAE = 0;
+ for (_fieldAF = 0; _fieldAF < 18; ++_fieldAF)
+ if (R2_GLOBALS._v56613[4 * _fieldAF] == 0)
+ ++_fieldAE;
+
+ if (_fieldAE == 18) {
+ R2_GLOBALS.setFlag(36);
+ _fieldAC = 23;
+ Common::Point pt(R2_GLOBALS._player._position.x + _fieldA8, R2_GLOBALS._player._position.y + _fieldAA);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, this);
+ } else if (_fieldAE == 1) {
+ _fieldAC = 22;
+ Common::Point pt(R2_GLOBALS._player._position.x + _fieldA8, R2_GLOBALS._player._position.y + _fieldAA);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, this);
+ } else {
+ R2_GLOBALS._player.enableControl(CURSOR_ARROW);
+ }
+
+ if (R2_GLOBALS._v566A5 == 3)
+ scene->_exit3._enabled = true;
+ else
+ scene->_exit6._enabled = true;
+
+ scene->_field416 = 0;
+ break;
+ case 22:
+ SceneItem::display(1950, 18, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
+ R2_GLOBALS._player.enableControl(CURSOR_ARROW);
+ break;
+ case 23:
+ SceneItem::display(1950, 25, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
+ scene->_sceneMode = R2_GLOBALS._v566A5;
+ scene->setAction(&scene->_sequenceManager, scene, 1960, &R2_GLOBALS._player, NULL);
+ break;
+ default:
+ break;
+ }
+}
+
+bool Scene1950::Actor8::startAction(CursorType action, Event &event) {
+ Scene1950 *scene = (Scene1950 *)R2_GLOBALS._sceneManager._scene;
+
+ if ((R2_GLOBALS._v56613[(scene->_field41C - 1) * 4] == 0) || (action != R2_PHOTON_STUNNER))
+ return SceneActor::startAction(action, event);
+
+ R2_GLOBALS._player.disableControl();
+
+ if (R2_GLOBALS._v56613[((scene->_field41C - 1) * 4) + 1] <= 1)
+ _fieldAC = 21;
+ else
+ _fieldAC = 20;
+
+ R2_GLOBALS._player.setVisage(25);
+ if (R2_GLOBALS._v566A5 == 3)
+ R2_GLOBALS._player.setStrip(2);
+ else
+ R2_GLOBALS._player.setStrip(1);
+ R2_GLOBALS._player.animate(ANIM_MODE_5, this);
+ R2_GLOBALS._sound3.play(99);
+
+ return true;
+}
+
+void Scene1950::Exit1::changeScene() {
+ Scene1950 *scene = (Scene1950 *)R2_GLOBALS._sceneManager._scene;
+
+ _enabled = false;
+ R2_GLOBALS._player.disableControl(CURSOR_ARROW);
+ R2_GLOBALS._v566A5 = 1;
+ scene->_sceneMode = 11;
+
+ Common::Point pt(160, 127);
+ PlayerMover *mover = new PlayerMover();
+ R2_GLOBALS._player.addMover(mover, &pt, scene);
+}
+
+void Scene1950::Exit2::changeScene() {
+ Scene1950 *scene = (Scene1950 *)R2_GLOBALS._sceneManager._scene;
+
+ _enabled = false;
+ R2_GLOBALS._player.disableControl(CURSOR_ARROW);
+ R2_GLOBALS._v566A5 = 2;
+ scene->_sceneMode = 12;
+
+ if (scene->_field412 == 0) {
+ if (R2_GLOBALS.getFlag(36))
+ scene->setAction(&scene->_sequenceManager, scene, 1953, &R2_GLOBALS._player, NULL);
+ else
+ scene->setAction(&scene->_sequenceManager, scene, 1970, &R2_GLOBALS._player, NULL);
+ } else {
+ if (R2_GLOBALS.getFlag(36))
+ scene->setAction(&scene->_sequenceManager, scene, 1952, &R2_GLOBALS._player, NULL);
+ else
+ scene->setAction(&scene->_sequenceManager, scene, 1969, &R2_GLOBALS._player, NULL);
+ }
+}
+
+void Scene1950::Exit3::changeScene() {
+ Scene1950 *scene = (Scene1950 *)R2_GLOBALS._sceneManager._scene;
+
+ _enabled = false;
+ R2_GLOBALS._player.disableControl(CURSOR_ARROW);
+ R2_GLOBALS._v566A5 = 3;
+ scene->_sceneMode = 13;
+
+ if (scene->_field416 != 0)
+ R2_GLOBALS._player.animate(ANIM_MODE_9);
+
+ Common::Point pt(340, 160);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, scene);
+}
+
+void Scene1950::Exit4::changeScene() {
+ Scene1950 *scene = (Scene1950 *)R2_GLOBALS._sceneManager._scene;
+
+ _enabled = false;
+ R2_GLOBALS._player.disableControl(CURSOR_ARROW);
+ R2_GLOBALS._v566A5 = 4;
+ scene->_sceneMode = 14;
+
+ if (R2_GLOBALS.getFlag(36))
+ scene->setAction(&scene->_sequenceManager, scene, 1956, &R2_GLOBALS._player, NULL);
+ else
+ scene->setAction(&scene->_sequenceManager, scene, 1973, &R2_GLOBALS._player, NULL);
+}
+
+void Scene1950::Exit5::changeScene() {
+ Scene1950 *scene = (Scene1950 *)R2_GLOBALS._sceneManager._scene;
+
+ _enabled = false;
+ R2_GLOBALS._player.disableControl(CURSOR_ARROW);
+ R2_GLOBALS._v566A5 = 5;
+ scene->_sceneMode = 15;
+
+ Common::Point pt(160, 213);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, scene);
+}
+
+void Scene1950::Exit6::changeScene() {
+ Scene1950 *scene = (Scene1950 *)R2_GLOBALS._sceneManager._scene;
+
+ _enabled = false;
+ R2_GLOBALS._player.disableControl(CURSOR_ARROW);
+ R2_GLOBALS._v566A5 = 5;
+ if (R2_GLOBALS._v566A4 == 2) {
+ if ((R2_GLOBALS.getFlag(36)) && (R2_INVENTORY.getObjectScene(34) == 2) && (R2_INVENTORY.getObjectScene(35) == 2)) {
+ scene->_sceneMode = 1961;
+ Common::Point pt(-20, 160);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, scene);
+ } else {
+ if (!R2_GLOBALS.getFlag(36))
+ SceneItem::display(1950, 33, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
+ if ((R2_INVENTORY.getObjectScene(34) == 1950) || (R2_INVENTORY.getObjectScene(35) == 1950))
+ SceneItem::display(1950, 34, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
+ scene->_sceneMode = 0;
+ Common::Point pt(30, 160);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, scene);
+ }
+ } else {
+ if (scene->_field416 != 0)
+ R2_GLOBALS._player.animate(ANIM_MODE_9);
+
+ scene->_sceneMode = 16;
+ Common::Point pt(-20, 160);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, scene);
+ }
+}
+
+void Scene1950::Exit7::changeScene() {
+ Scene1950 *scene = (Scene1950 *)R2_GLOBALS._sceneManager._scene;
+
+ _enabled = false;
+ R2_GLOBALS._player.disableControl(CURSOR_ARROW);
+ R2_GLOBALS._v566A5 = 0;
+ scene->_sceneMode = 1951;
+ scene->setAction(&scene->_sequenceManager, scene, 1951, &R2_GLOBALS._player, NULL);
+}
+
+void Scene1950::Exit8::changeScene() {
+ Scene1950 *scene = (Scene1950 *)R2_GLOBALS._sceneManager._scene;
+
+ _enabled = false;
+ R2_GLOBALS._player.disableControl(CURSOR_ARROW);
+ R2_GLOBALS._v566A5 = 3;
+ if (R2_GLOBALS._player._visage == 22) {
+ scene->_sceneMode = 1975;
+ scene->setAction(&scene->_sequenceManager, scene, 1975, &R2_GLOBALS._player, NULL);
+ } else {
+ SceneItem::display(1950, 22, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
+ R2_GLOBALS._v566A5 = 0;
+ scene->_sceneMode = 0;
+ Common::Point pt(250, 150);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, scene);
+ _enabled = true;
+ }
+}
+
+void Scene1950::subBDC1E() {
+ _exit1._enabled = false;
+ _exit2._enabled = false;
+ _exit3._enabled = false;
+ _exit4._enabled = false;
+ _exit5._enabled = false;
+ _exit6._enabled = false;
+ _exit7._enabled = false;
+ _exit8._enabled = false;
+ _exit1._insideArea = false;
+ _exit2._insideArea = false;
+ _exit3._insideArea = false;
+ _exit4._insideArea = false;
+ _exit5._insideArea = false;
+ _exit6._insideArea = false;
+ _exit7._insideArea = false;
+ _exit8._insideArea = false;
+ _exit1._moving = false;
+ _exit2._moving = false;
+ _exit3._moving = false;
+ _exit4._moving = false;
+ _exit5._moving = false;
+ _exit6._moving = false;
+ _exit7._moving = false;
+ _exit8._moving = false;
+ _field412 = 0;
+ switch (R2_GLOBALS._v566A4 - 1) {
+ case 0:
+ loadScene(1948);
+ break;
+ case 1:
+ // No break on purpose
+ case 8:
+ // No break on purpose
+ case 10:
+ // No break on purpose
+ case 12:
+ // No break on purpose
+ case 16:
+ // No break on purpose
+ case 19:
+ // No break on purpose
+ case 23:
+ // No break on purpose
+ case 30:
+ // No break on purpose
+ case 44:
+ // No break on purpose
+ case 72:
+ // No break on purpose
+ case 74:
+ // No break on purpose
+ case 86:
+ // No break on purpose
+ case 96:
+ // No break on purpose
+ case 103:
+ loadScene(1950);
+ break;
+ case 2:
+ // No break on purpose
+ case 29:
+ loadScene(1965);
+ break;
+ case 3:
+ // No break on purpose
+ case 9:
+ // No break on purpose
+ case 11:
+ // No break on purpose
+ case 15:
+ // No break on purpose
+ case 24:
+ // No break on purpose
+ case 39:
+ // No break on purpose
+ case 45:
+ // No break on purpose
+ case 71:
+ // No break on purpose
+ case 73:
+ // No break on purpose
+ case 75:
+ // No break on purpose
+ case 79:
+ // No break on purpose
+ case 85:
+ // No break on purpose
+ case 87:
+ // No break on purpose
+ case 95:
+ loadScene(1955);
+ break;
+ case 4:
+ // No break on purpose
+ case 6:
+ // No break on purpose
+ case 13:
+ // No break on purpose
+ case 27:
+ // No break on purpose
+ case 41:
+ // No break on purpose
+ case 48:
+ // No break on purpose
+ case 50:
+ // No break on purpose
+ case 54:
+ // No break on purpose
+ case 76:
+ // No break on purpose
+ case 80:
+ // No break on purpose
+ case 90:
+ // No break on purpose
+ case 104:
+ loadScene(1975);
+ break;
+ case 5:
+ // No break on purpose
+ case 7:
+ // No break on purpose
+ case 14:
+ // No break on purpose
+ case 28:
+ // No break on purpose
+ case 32:
+ // No break on purpose
+ case 47:
+ // No break on purpose
+ case 53:
+ loadScene(1997);
+ break;
+ case 17:
+ // No break on purpose
+ case 20:
+ // No break on purpose
+ case 25:
+ // No break on purpose
+ case 31:
+ // No break on purpose
+ case 33:
+ // No break on purpose
+ case 46:
+ loadScene(1995);
+ break;
+ case 18:
+ // No break on purpose
+ case 22:
+ // No break on purpose
+ case 26:
+ // No break on purpose
+ case 36:
+ // No break on purpose
+ case 38:
+ // No break on purpose
+ case 43:
+ // No break on purpose
+ case 51:
+ // No break on purpose
+ case 70:
+ // No break on purpose
+ case 78:
+ // No break on purpose
+ case 84:
+ // No break on purpose
+ case 89:
+ // No break on purpose
+ case 101:
+ loadScene(1970);
+ break;
+ case 21:
+ // No break on purpose
+ case 34:
+ // No break on purpose
+ case 57:
+ // No break on purpose
+ case 58:
+ // No break on purpose
+ case 59:
+ // No break on purpose
+ case 62:
+ // No break on purpose
+ case 65:
+ loadScene(1980);
+ break;
+ case 35:
+ // No break on purpose
+ case 61:
+ // No break on purpose
+ case 77:
+ // No break on purpose
+ case 83:
+ loadScene(1982);
+ break;
+ case 37:
+ // No break on purpose
+ case 52:
+ // No break on purpose
+ case 82:
+ // No break on purpose
+ case 88:
+ // No break on purpose
+ case 92:
+ // No break on purpose
+ case 97:
+ // No break on purpose
+ case 100:
+ loadScene(1962);
+ break;
+ case 40:
+ // No break on purpose
+ case 102:
+ loadScene(1960);
+ break;
+ case 42:
+ // No break on purpose
+ case 55:
+ // No break on purpose
+ case 60:
+ // No break on purpose
+ case 66:
+ // No break on purpose
+ case 68:
+ // No break on purpose
+ case 69:
+ // No break on purpose
+ case 93:
+ // No break on purpose
+ case 98:
+ loadScene(1990);
+ break;
+ case 49:
+ // No break on purpose
+ case 81:
+ // No break on purpose
+ case 91:
+ // No break on purpose
+ case 94:
+ // No break on purpose
+ case 99:
+ loadScene(1967);
+ break;
+ case 56:
+ // No break on purpose
+ case 63:
+ // No break on purpose
+ case 64:
+ // No break on purpose
+ case 67:
+ loadScene(1985);
+ _field412 = 1;
+ break;
+ default:
+ break;
+ }
+
+ if (R2_GLOBALS._v566A4 != 1)
+ R2_GLOBALS._walkRegions.load(1950);
+
+ switch (R2_GLOBALS._v566A4 - 1) {
+ case 0:
+ _exit7._enabled = true;
+ if ((R2_INVENTORY.getObjectScene(31) == 0) && (R2_INVENTORY.getObjectScene(34) == 1950))
+ _exit8._enabled = true;
+ R2_GLOBALS._walkRegions.enableRegion(2);
+ R2_GLOBALS._walkRegions.enableRegion(3);
+ R2_GLOBALS._walkRegions.enableRegion(4);
+ R2_GLOBALS._walkRegions.enableRegion(5);
+ R2_GLOBALS._walkRegions.enableRegion(6);
+ break;
+ case 1:
+ // No break on purpose
+ case 2:
+ // No break on purpose
+ case 3:
+ // No break on purpose
+ case 8:
+ // No break on purpose
+ case 9:
+ // No break on purpose
+ case 10:
+ // No break on purpose
+ case 11:
+ // No break on purpose
+ case 12:
+ // No break on purpose
+ case 15:
+ // No break on purpose
+ case 16:
+ // No break on purpose
+ case 19:
+ // No break on purpose
+ case 23:
+ // No break on purpose
+ case 24:
+ // No break on purpose
+ case 29:
+ // No break on purpose
+ case 30:
+ // No break on purpose
+ case 39:
+ // No break on purpose
+ case 40:
+ // No break on purpose
+ case 44:
+ // No break on purpose
+ case 45:
+ // No break on purpose
+ case 71:
+ // No break on purpose
+ case 72:
+ // No break on purpose
+ case 73:
+ // No break on purpose
+ case 74:
+ // No break on purpose
+ case 75:
+ // No break on purpose
+ case 79:
+ // No break on purpose
+ case 85:
+ // No break on purpose
+ case 86:
+ // No break on purpose
+ case 87:
+ // No break on purpose
+ case 95:
+ // No break on purpose
+ case 96:
+ // No break on purpose
+ case 102:
+ // No break on purpose
+ case 103:
+ _exit3._enabled = true;
+ _exit6._enabled = true;
+ break;
+ case 4:
+ // No break on purpose
+ case 6:
+ // No break on purpose
+ case 13:
+ // No break on purpose
+ case 17:
+ // No break on purpose
+ case 20:
+ // No break on purpose
+ case 25:
+ // No break on purpose
+ case 27:
+ // No break on purpose
+ case 31:
+ // No break on purpose
+ case 33:
+ // No break on purpose
+ case 37:
+ // No break on purpose
+ case 41:
+ // No break on purpose
+ case 46:
+ // No break on purpose
+ case 48:
+ // No break on purpose
+ case 50:
+ // No break on purpose
+ case 52:
+ // No break on purpose
+ case 54:
+ // No break on purpose
+ case 76:
+ // No break on purpose
+ case 80:
+ // No break on purpose
+ case 82:
+ // No break on purpose
+ case 88:
+ // No break on purpose
+ case 90:
+ // No break on purpose
+ case 92:
+ // No break on purpose
+ case 97:
+ // No break on purpose
+ case 100:
+ // No break on purpose
+ case 104:
+ _exit6._enabled = true;
+ R2_GLOBALS._walkRegions.enableRegion(6);
+ R2_GLOBALS._walkRegions.enableRegion(9);
+ break;
+ case 5:
+ // No break on purpose
+ case 7:
+ // No break on purpose
+ case 14:
+ // No break on purpose
+ case 18:
+ // No break on purpose
+ case 22:
+ // No break on purpose
+ case 26:
+ // No break on purpose
+ case 28:
+ // No break on purpose
+ case 32:
+ // No break on purpose
+ case 36:
+ // No break on purpose
+ case 38:
+ // No break on purpose
+ case 43:
+ // No break on purpose
+ case 47:
+ // No break on purpose
+ case 49:
+ // No break on purpose
+ case 51:
+ // No break on purpose
+ case 53:
+ // No break on purpose
+ case 70:
+ // No break on purpose
+ case 78:
+ // No break on purpose
+ case 81:
+ // No break on purpose
+ case 84:
+ // No break on purpose
+ case 89:
+ // No break on purpose
+ case 91:
+ // No break on purpose
+ case 94:
+ // No break on purpose
+ case 99:
+ // No break on purpose
+ case 101:
+ _exit3._enabled = true;
+ R2_GLOBALS._walkRegions.enableRegion(1);
+ R2_GLOBALS._walkRegions.enableRegion(7);
+ R2_GLOBALS._walkRegions.enableRegion(13);
+ break;
+ default:
+ R2_GLOBALS._walkRegions.enableRegion(1);
+ R2_GLOBALS._walkRegions.enableRegion(6);
+ R2_GLOBALS._walkRegions.enableRegion(7);
+ R2_GLOBALS._walkRegions.enableRegion(9);
+ R2_GLOBALS._walkRegions.enableRegion(13);
+ break;
+ }
+
+ _object1.remove();
+ _object1.removeObject();
+ _actor1.remove();
+
+ switch (R2_GLOBALS._v566A4 - 4) {
+ case 0:
+ // No break on purpose
+ case 3:
+ // No break on purpose
+ case 16:
+ // No break on purpose
+ case 22:
+ // No break on purpose
+ case 24:
+ // No break on purpose
+ case 32:
+ // No break on purpose
+ case 33:
+ // No break on purpose
+ case 45:
+ // No break on purpose
+ case 46:
+ // No break on purpose
+ case 48:
+ // No break on purpose
+ case 51:
+ // No break on purpose
+ case 56:
+ // No break on purpose
+ case 59:
+ // No break on purpose
+ case 67:
+ // No break on purpose
+ case 68:
+ // No break on purpose
+ case 70:
+ // No break on purpose
+ case 73:
+ // No break on purpose
+ case 82:
+ // No break on purpose
+ case 90:
+ _exit1._enabled = true;
+ _object1.setup2(1950, (R2_GLOBALS._v566A4 % 2) + 1, 1, 160, 237, 25, 0);
+
+ _actor1.postInit();
+ _actor1.setVisage(1950);
+ _actor1.setStrip((((R2_GLOBALS._v566A4 - 1) / 35) % 2) + 1);
+ _actor1.setFrame(2);
+ _actor1.setPosition(Common::Point(160, 167));
+ _actor1.fixPriority(220);
+ R2_GLOBALS._walkRegions.enableRegion(3);
+ R2_GLOBALS._walkRegions.enableRegion(4);
+ break;
+ case 7:
+ // No break on purpose
+ case 10:
+ // No break on purpose
+ case 23:
+ // No break on purpose
+ case 29:
+ // No break on purpose
+ case 31:
+ // No break on purpose
+ case 39:
+ // No break on purpose
+ case 40:
+ // No break on purpose
+ case 52:
+ // No break on purpose
+ case 53:
+ // No break on purpose
+ case 55:
+ // No break on purpose
+ case 63:
+ // No break on purpose
+ case 65:
+ // No break on purpose
+ case 66:
+ // No break on purpose
+ case 75:
+ // No break on purpose
+ case 77:
+ // No break on purpose
+ case 81:
+ // No break on purpose
+ case 87:
+ // No break on purpose
+ case 89:
+ // No break on purpose
+ case 97:
+ _exit5._enabled = true;
+ _actor1.postInit();
+ _actor1.setVisage(1950);
+ _actor1.setStrip((((R2_GLOBALS._v566A4 - 1) / 35) % 2) + 1);
+ _actor1.setFrame(3);
+ _actor1.setPosition(Common::Point(160, 167));
+ _actor1.fixPriority(220);
+ break;
+ case 58:
+ // No break on purpose
+ case 74:
+ // No break on purpose
+ case 80:
+ _exit1._enabled = true;
+ _exit5._enabled = true;
+
+ _object1.setup(1950, (R2_GLOBALS._v566A4 % 2) + 1, 1, 160, 137, 25);
+
+ _actor1.postInit();
+ _actor1.setVisage(1950);
+ _actor1.setStrip((((R2_GLOBALS._v566A4 - 1) / 35) % 2) + 1);
+ _actor1.setFrame(3);
+ _actor1.setPosition(Common::Point(160, 167));
+ _actor1.fixPriority(220);
+ R2_GLOBALS._walkRegions.enableRegion(3);
+ R2_GLOBALS._walkRegions.enableRegion(4);
+ break;
+ default:
+ _actor1.postInit();
+ _actor1.setVisage(1950);
+ _actor1.setStrip(((R2_GLOBALS._v566A4 - 1) % 35) + 1);
+ _actor1.setFrame(2);
+ _actor1.setPosition(Common::Point(160, 167));
+ _actor1.fixPriority(220);
+ break;
+ }
+
+ switch (R2_GLOBALS._v566A4 - 3) {
+ case 0:
+ // No break on purpose
+ case 3:
+ // No break on purpose
+ case 5:
+ // No break on purpose
+ case 12:
+ // No break on purpose
+ case 15:
+ // No break on purpose
+ case 18:
+ // No break on purpose
+ case 19:
+ // No break on purpose
+ case 23:
+ // No break on purpose
+ case 26:
+ // No break on purpose
+ case 27:
+ // No break on purpose
+ case 29:
+ // No break on purpose
+ case 30:
+ // No break on purpose
+ case 31:
+ // No break on purpose
+ case 32:
+ // No break on purpose
+ case 44:
+ // No break on purpose
+ case 45:
+ // No break on purpose
+ case 51:
+ // No break on purpose
+ case 55:
+ // No break on purpose
+ case 56:
+ // No break on purpose
+ case 57:
+ // No break on purpose
+ case 60:
+ // No break on purpose
+ case 63:
+ _exit2._enabled = true;
+ case 54:
+ // No break on purpose
+ case 61:
+ // No break on purpose
+ case 62:
+ // No break on purpose
+ case 65:
+ _exit2._enabled = true;
+ // No break on purpose
+ case 35:
+ // No break on purpose
+ case 38:
+ // No break on purpose
+ case 40:
+ // No break on purpose
+ case 47:
+ // No break on purpose
+ case 50:
+ // No break on purpose
+ case 53:
+ // No break on purpose
+ case 58:
+ // No break on purpose
+ case 64:
+ // No break on purpose
+ case 66:
+ // No break on purpose
+ case 67:
+ // No break on purpose
+ case 79:
+ // No break on purpose
+ case 80:
+ // No break on purpose
+ case 86:
+ // No break on purpose
+ case 89:
+ // No break on purpose
+ case 90:
+ // No break on purpose
+ case 91:
+ // No break on purpose
+ case 92:
+ // No break on purpose
+ case 95:
+ // No break on purpose
+ case 96:
+ // No break on purpose
+ case 97:
+ // No break on purpose
+ case 98:
+ // No break on purpose
+ case 100:
+ _exit4._enabled = true;
+ R2_GLOBALS._walkRegions.enableRegion(4);
+ R2_GLOBALS._walkRegions.enableRegion(5);
+ R2_GLOBALS._walkRegions.enableRegion(6);
+ R2_GLOBALS._walkRegions.enableRegion(10);
+ R2_GLOBALS._walkRegions.enableRegion(11);
+ default:
+ break;
+ }
+ R2_GLOBALS._uiElements.draw();
+}
+
+void Scene1950::subBE59B() {
+ R2_GLOBALS._player.disableControl();
+ R2_GLOBALS._player.animate(ANIM_MODE_1, NULL);
+
+ _actor8.remove();
+ _actor2.remove();
+ _actor3.remove();
+
+ _field416 = 0;
+ _field41C = 0;
+
+ switch (R2_GLOBALS._v566A4) {
+ case 10:
+ _field41C = 1;
+ break;
+ case 13:
+ _field41C = 2;
+ break;
+ case 16:
+ _field41C = 3;
+ break;
+ case 17:
+ _field41C = 4;
+ break;
+ case 24:
+ _field41C = 5;
+ break;
+ case 25:
+ _field41C = 6;
+ break;
+ case 31:
+ _field41C = 7;
+ break;
+ case 40:
+ _field41C = 8;
+ break;
+ case 45:
+ _field41C = 9;
+ break;
+ case 46:
+ _field41C = 10;
+ break;
+ case 73:
+ _field41C = 11;
+ break;
+ case 75:
+ _field41C = 12;
+ break;
+ case 80:
+ _field41C = 13;
+ break;
+ case 87:
+ _field41C = 14;
+ break;
+ case 88:
+ _field41C = 15;
+ break;
+ case 96:
+ _field41C = 16;
+ break;
+ case 97:
+ _field41C = 17;
+ break;
+ case 104:
+ _field41C = 18;
+ break;
+ default:
+ break;
+ }
+
+ if (_field41C != 0) {
+ _actor8.postInit();
+ _actor8._numFrames = 6;
+ _actor8._moveRate = 6;
+ _actor8._moveDiff = Common::Point(3, 2);
+ _actor8._effect = 1;
+ if (R2_GLOBALS._v56613[(_field41C - 1) * 4] == 0) {
+ _actor8.setPosition(Common::Point(R2_GLOBALS._v56613[((_field41C - 1) * 4) + 2], R2_GLOBALS._v56613[((_field41C - 1) * 4) + 3]));
+ _actor8.animate(ANIM_MODE_NONE, NULL);
+ _actor8.addMover(NULL);
+ _actor8.setVisage(1961);
+ _actor8.setStrip(4);
+ _actor8.setFrame(10);
+ _actor8.fixPriority(10);
+ _actor8.setDetails(1950, 15, -1, 17, 2, (SceneItem *) NULL);
+ } else {
+ _actor8.setVisage(1960);
+ _actor8.setPosition(Common::Point(160, 130));
+ _actor8.animate(ANIM_MODE_2, NULL);
+ _actor8.setDetails(1950, 12, -1, 14, 2, (SceneItem *) NULL);
+ _field416 = 1;
+ }
+ }
+ if ((R2_GLOBALS._v566A4 == 1) && (R2_INVENTORY.getObjectScene(31) != 0)) {
+ _actor2.postInit();
+ _actor2.setVisage(1948);
+ _actor2.setStrip(3);
+ _actor2.setPosition(Common::Point(278, 155));
+ _actor2.fixPriority(100);
+ _actor2.setDetails(1950, 19, 20, 23, 2, (SceneItem *) NULL);
+ }
+
+ if (R2_GLOBALS._v566A4 == 102) {
+ R2_GLOBALS._walkRegions.load(1951);
+ R2_GLOBALS._walkRegions.enableRegion(1);
+ R2_GLOBALS._walkRegions.enableRegion(5);
+ R2_GLOBALS._walkRegions.enableRegion(6);
+ R2_GLOBALS._walkRegions.enableRegion(7);
+
+ _actor6.postInit();
+ _actor6.setVisage(1970);
+ _actor6.setStrip(1);
+ if (R2_GLOBALS.getFlag(37))
+ _actor6.setFrame(3);
+ else
+ _actor6.setFrame(1);
+ _actor6.setPosition(Common::Point(193, 158));
+ _actor6.setDetails(1950, 3, 4, 5, 2, (SceneItem *) NULL);
+
+ _actor7.postInit();
+ _actor7.setVisage(1970);
+ _actor7.setStrip(3);
+ _actor7.animate(ANIM_MODE_2, NULL);
+ _actor7._numFrames = 6;
+ _actor7.setPosition(Common::Point(194, 158));
+ _actor7.fixPriority(159);
+
+ _item2.setDetails(Rect(188, 124, 199, 133), 1950, 27, 28, -1, 2, NULL);
+
+ if (R2_INVENTORY.getObjectScene(34) == 1950) {
+ _actor5.postInit();
+ _actor5.setVisage(1970);
+ _actor5.setStrip(1);
+ _actor5.setFrame(2);
+ _actor5.fixPriority(160);
+ }
+
+ if (R2_GLOBALS.getFlag(37)) {
+ _actor5.setPosition(Common::Point(192, 118));
+ _actor5.setDetails(1950, 9, 4, -1, 2, (SceneItem *) NULL);
+ } else {
+ _actor4.postInit();
+ _actor4.setVisage(1970);
+ _actor4.setStrip(4);
+ _actor4._numFrames = 4;
+ _actor4.animate(ANIM_MODE_8, NULL);
+ _actor4.setPosition(Common::Point(192, 121));
+ _actor4.fixPriority(159);
+ _actor4.setDetails(1950, 6, 7, 8, 2, (SceneItem *) NULL);
+
+ _actor5.setPosition(Common::Point(192, 109));
+ _actor5.setDetails(1950, 9, 7, 8, 2, (SceneItem *) NULL);
+ }
+
+ _actor3.postInit();
+ _actor3.setVisage(1972);
+ _actor3.setStrip(1);
+ _actor3.setPosition(Common::Point(76, 94));
+ _actor3.fixPriority(25);
+ _actor3.setDetails(1950, 30, -1, -1, 2, (SceneItem *) NULL);
+ if (R2_INVENTORY.getObjectScene(35) == 2)
+ _actor3.setFrame(2);
+ else
+ _actor3.setFrame(1);
+
+ _field414 = 1;
+ } else if (_field414 != 0) {
+ _actor6.remove();
+ _actor4.remove();
+ _actor5.remove();
+ _actor7.remove();
+ _actor3.remove();
+
+ _item1.setDetails(Rect(0, 0, 320, 200), 1950, 0, 1, 2, 2, NULL);
+ }
+
+ switch (R2_GLOBALS._v566A5) {
+ case 0:
+ _sceneMode = 1950;
+ if (R2_INVENTORY.getObjectScene(31) == 0) {
+ R2_GLOBALS._v56AAB = 0;
+ R2_GLOBALS._player.enableControl(CURSOR_ARROW);
+ } else {
+ setAction(&_sequenceManager, this, 1950, &R2_GLOBALS._player, NULL);
+ }
+ break;
+ case 1: {
+ _sceneMode = R2_GLOBALS._v566A5;
+ R2_GLOBALS._player.setPosition(Common::Point(160, 213));
+ Common::Point pt(160, 160);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, this);
+ }
+ break;
+ case 2:
+ _sceneMode = R2_GLOBALS._v566A5;
+ if (R2_GLOBALS.getFlag(36))
+ setAction(&_sequenceManager, this, 1957, &R2_GLOBALS._player, NULL);
+ else
+ setAction(&_sequenceManager, this, 1974, &R2_GLOBALS._player, NULL);
+ break;
+ case 3:
+ if (_field416 == 0) {
+ _sceneMode = R2_GLOBALS._v566A5;
+ R2_GLOBALS._player.setPosition(Common::Point(-20, 160));
+ Common::Point pt(30, 160);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, this);
+ } else {
+ _sceneMode = 18;
+ _exit3._enabled = false;
+ _field418 = Common::Point(60, 152);
+ R2_GLOBALS._v56AAB = 0;
+ R2_GLOBALS._player.enableControl(CURSOR_USE);
+ R2_GLOBALS._player._canWalk = false;
+
+ _actor8.setStrip(2);
+ NpcMover *mover = new NpcMover();
+ _actor8.addMover(mover, &_field418, this);
+
+ R2_GLOBALS._player.setPosition(Common::Point(-20, 160));
+ Common::Point pt2(30, 160);
+ NpcMover *mover2 = new NpcMover();
+ R2_GLOBALS._player.addMover(mover2, &pt2, NULL);
+ }
+ break;
+ case 4:
+ _sceneMode = R2_GLOBALS._v566A5;
+ if (_field412 == 0) {
+ if (R2_GLOBALS.getFlag(36))
+ setAction(&_sequenceManager, this, 1955, &R2_GLOBALS._player, NULL);
+ else
+ setAction(&_sequenceManager, this, 1972, &R2_GLOBALS._player, NULL);
+ } else {
+ if (R2_GLOBALS.getFlag(36))
+ setAction(&_sequenceManager, this, 1954, &R2_GLOBALS._player, NULL);
+ else
+ setAction(&_sequenceManager, this, 1971, &R2_GLOBALS._player, NULL);
+ }
+ break;
+ case 5: {
+ _sceneMode = R2_GLOBALS._v566A5;
+ R2_GLOBALS._player.setPosition(Common::Point(160, 127));
+ Common::Point pt(160, 160);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, this);
+ }
+ break;
+ case 6:
+ if (_field416 == 0) {
+ _sceneMode = R2_GLOBALS._v566A5;
+ if (R2_GLOBALS._v566A4 == 1) {
+ setAction(&_sequenceManager, this, 1961, &R2_GLOBALS._player, NULL);
+ } else {
+ R2_GLOBALS._player.setPosition(Common::Point(340, 160));
+ Common::Point pt(289, 160);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, this);
+ }
+ } else {
+ _sceneMode = 17;
+ _exit6._enabled = false;
+ _field418 = Common::Point(259, 152);
+
+ R2_GLOBALS._v56AAB = 0;
+ R2_GLOBALS._player.enableControl(CURSOR_USE);
+ R2_GLOBALS._player._canWalk = false;
+
+ _actor8.setStrip(1);
+ NpcMover *mover = new NpcMover();
+ _actor8.addMover(mover, &_field418, this);
+
+ R2_GLOBALS._player.setPosition(Common::Point(340, 160));
+ Common::Point pt2(289, 160);
+ NpcMover *mover2 = new NpcMover();
+ R2_GLOBALS._player.addMover(mover2, &pt2, NULL);
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+void Scene1950::subBF4B4(int indx) {
+ R2_GLOBALS._player.disableControl();
+ int si = indx - 1;
+ if ((indx / 4) == (si / 4)) {
+ if (si < 0)
+ si = 3;
+ } else
+ si = 4;
+
+ if (_area1._arrActor1[si]._fieldA8 == 0) {
+ _area1._arrActor1[si].setFrame(2);
+ _area1._arrActor1[si]._fieldA8 = 1;
+ } else {
+ _area1._arrActor1[si].setFrame(1);
+ _area1._arrActor1[si]._fieldA8 = 0;
+ }
+
+ si = indx + 1;
+ if ((indx / 4) == (si / 4)) {
+ if (si > 15)
+ si = 12;
+ } else
+ si -= 4;
+
+ if (_area1._arrActor1[si]._fieldA8 == 0) {
+ _area1._arrActor1[si].setFrame(2);
+ _area1._arrActor1[si]._fieldA8 = 1;
+ } else {
+ _area1._arrActor1[si].setFrame(1);
+ _area1._arrActor1[si]._fieldA8 = 0;
+ }
+
+ si = indx - 4;
+ if (si < 0)
+ si += 16;
+
+ if (_area1._arrActor1[si]._fieldA8 == 0) {
+ _area1._arrActor1[si].setFrame(2);
+ _area1._arrActor1[si]._fieldA8 = 1;
+ } else {
+ _area1._arrActor1[si].setFrame(1);
+ _area1._arrActor1[si]._fieldA8 = 0;
+ }
+
+ si = indx + 4;
+ if (si > 15)
+ si -= 16;
+
+ if (_area1._arrActor1[si]._fieldA8 == 0) {
+ _area1._arrActor1[si].setFrame(2);
+ _area1._arrActor1[si]._fieldA8 = 1;
+ } else {
+ _area1._arrActor1[si].setFrame(1);
+ _area1._arrActor1[si]._fieldA8 = 0;
+ }
+
+ int cpt = 0;
+ for (si = 0; si < 16; si++) {
+ if (_area1._arrActor1[si]._fieldA8 != 0)
+ ++cpt;
+ }
+
+ if (cpt != 16) {
+ R2_GLOBALS._player.enableControl();
+ R2_GLOBALS._player._canWalk = false;
+ } else {
+ R2_GLOBALS.setFlag(37);
+ _sceneMode = 24;
+ // TODO: check if correct. The original doesn't countain a sceneActor in
+ // this call, but it's extremely unusual
+ setAction(&_sequenceManager, this, 1976, NULL);
+ }
+}
+
+void Scene1950::postInit(SceneObjectList *OwnerList) {
+ _field412 = 0;
+ _field414 = 0;
+ _field416 = 0;
+ _field41C = 0;
+ if (R2_GLOBALS._sceneManager._previousScene == 300)
+ R2_GLOBALS._v566A4 = 103;
+
+ subBDC1E();
+ SceneExt::postInit();
+ R2_GLOBALS._sound1.play(105);
+
+ _exit1.setDetails(Rect(130, 46, 189, 135), SHADECURSOR_UP, 1950);
+ _exit1.setDest(Common::Point(160, 145));
+
+ _exit2.setDetails(Rect(208, 0, 255, 73), EXITCURSOR_N, 1950);
+ _exit2.setDest(Common::Point(200, 151));
+
+ _exit3.setDetails(Rect(305, 95, 320, 147), EXITCURSOR_E, 1950);
+ _exit3.setDest(Common::Point(312, 160));
+
+ _exit4.setDetails(Rect(208, 99, 255, 143), EXITCURSOR_S, 1950);
+ _exit4.setDest(Common::Point(200, 151));
+
+ _exit5.setDetails(Rect(113, 154, 206, 168), SHADECURSOR_DOWN, 1950);
+ _exit5.setDest(Common::Point(160, 165));
+
+ _exit6.setDetails(Rect(0, 95, 14, 147), EXITCURSOR_W, 1950);
+ _exit6.setDest(Common::Point(7, 160));
+
+ _exit7.setDetails(Rect(72, 54, 120, 128), EXITCURSOR_NW, 1950);
+ _exit7.setDest(Common::Point(120, 140));
+
+ _exit8.setDetails(Rect(258, 60, 300, 145), EXITCURSOR_NE, 1950);
+ _exit8.setDest(Common::Point(268, 149));
+
+ R2_GLOBALS._player.postInit();
+ if ( (R2_INVENTORY.getObjectScene(32) == 0) && (R2_INVENTORY.getObjectScene(33) == 0)
+ && (R2_INVENTORY.getObjectScene(46) == 0) && (!R2_GLOBALS.getFlag(36)) )
+ R2_GLOBALS._player.setVisage(22);
+ else
+ R2_GLOBALS._player.setVisage(20);
+
+ R2_GLOBALS._player._moveDiff = Common::Point(5, 3);
+ _item1.setDetails(Rect(0, 0, 320, 200), 1950, 0, 1, 2, 1, NULL);
+
+ subBE59B();
+}
+
+void Scene1950::remove() {
+ R2_GLOBALS._sound1.stop();
+ R2_GLOBALS._sound2.fadeOut2(NULL);
+ SceneExt::remove();
+}
+
+void Scene1950::signal() {
+ switch (_sceneMode) {
+ case 11:
+ R2_GLOBALS._v566A4 += 7;
+ subBDC1E();
+ subBE59B();
+ break;
+ case 12:
+ R2_GLOBALS._v566A4 += 35;
+ subBDC1E();
+ subBE59B();
+ break;
+ case 1975:
+ SceneItem::display(1950, 21, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
+ // No break on purpose
+ case 13:
+ ++R2_GLOBALS._v566A4;
+ subBDC1E();
+ subBE59B();
+ break;
+ case 14:
+ R2_GLOBALS._v566A4 += 221;
+ subBDC1E();
+ subBE59B();
+ break;
+ case 15:
+ R2_GLOBALS._v566A4 += 249;
+ subBDC1E();
+ subBE59B();
+ break;
+ case 16:
+ // No break on purpose
+ case 1961:
+ --R2_GLOBALS._v566A4;
+ subBDC1E();
+ subBE59B();
+ break;
+ case 17: {
+ _sceneMode = 13;
+ R2_GLOBALS._v566A5 = 3;
+ _field416 = 0;
+ R2_GLOBALS._player.disableControl(CURSOR_ARROW);
+ R2_GLOBALS._player._canWalk = true;
+ R2_GLOBALS._player.setVisage(22);
+ R2_GLOBALS._player.animate(ANIM_MODE_9, NULL);
+ Common::Point pt(340, 160);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, this);
+ Common::Point pt2(289, 160);
+ NpcMover *mover2 = new NpcMover();
+ _actor8.addMover(mover2, &pt2, NULL);
+ }
+ break;
+ case 18: {
+ _sceneMode = 16;
+ R2_GLOBALS._v566A5 = 6;
+ _field416 = 0;
+ R2_GLOBALS._player.disableControl(CURSOR_ARROW);
+ R2_GLOBALS._player._canWalk = true;
+ R2_GLOBALS._player.setVisage(22);
+ R2_GLOBALS._player.animate(ANIM_MODE_9, NULL);
+ Common::Point pt(-20, 160);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, this);
+ Common::Point pt2(30, 160);
+ NpcMover *mover2 = new NpcMover();
+ _actor8.addMover(mover2, &pt2, NULL);
+ }
+ break;
+ case 24:
+ _area1.remove();
+ _sceneMode = 1966;
+ _actor6.setFrame(3);
+ setAction(&_sequenceManager, this, 1966, &_actor4, &_actor5, NULL);
+ break;
+ case 1951:
+ R2_GLOBALS._sound1.fadeOut2(NULL);
+ R2_GLOBALS._sceneManager.changeScene(1945);
+ break;
+ case 1958:
+ SceneItem::display(1950, 24, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
+ R2_GLOBALS._v56AAB = 0;
+ R2_GLOBALS._player.enableControl(CURSOR_ARROW);
+ _exit8._enabled = true;
+ break;
+ case 1959:
+ R2_INVENTORY.setObjectScene(46, 0);
+ R2_GLOBALS._v56AAB = 0;
+ R2_GLOBALS._player.enableControl(CURSOR_ARROW);
+ _exit8._enabled = true;
+ break;
+ case 1962:
+ // No break on purpose
+ case 1963:
+ R2_GLOBALS._player.enableControl();
+ _area1.proc12(1971, 1, 1, 160, 135);
+ break;
+ case 1964:
+ // No break on purpose
+ case 1965:
+ if (!R2_GLOBALS.getFlag(37))
+ SceneItem::display(1950, 26, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
+ R2_GLOBALS._player.enableControl();
+ break;
+ case 1966:
+ _actor4.remove();
+ if (R2_GLOBALS.getFlag(36)) {
+ _sceneMode = 1964;
+ setAction(&_sequenceManager, this, 1964, &R2_GLOBALS._player, NULL);
+ } else {
+ _sceneMode = 1965;
+ setAction(&_sequenceManager, this, 1965, &R2_GLOBALS._player, NULL);
+ }
+ _actor5.setDetails(1950, 9, -1, -1, 2, (SceneItem *) NULL);
+ case 1967: {
+ _sceneMode = 0;
+ R2_INVENTORY.setObjectScene(34, 2);
+ _actor5.remove();
+ if (R2_GLOBALS.getFlag(36))
+ R2_GLOBALS._player.setVisage(20);
+ else
+ R2_GLOBALS._player.setVisage(22);
+
+ R2_GLOBALS._player.animate(ANIM_MODE_1, NULL);
+ Common::Point pt(218, 165);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, this);
+ }
+ break;
+ case 1968:
+ R2_GLOBALS._player.disableControl();
+ R2_INVENTORY.setObjectScene(35, 2);
+ _actor3.setFrame(2);
+ if (R2_GLOBALS.getFlag(36))
+ R2_GLOBALS._player.setVisage(20);
+ else
+ R2_GLOBALS._player.setVisage(22);
+ R2_GLOBALS._player.animate(ANIM_MODE_1, NULL);
+ break;
+ default:
+ R2_GLOBALS._v56AAB = 0;
+ R2_GLOBALS._player.enableControl(CURSOR_ARROW);
+ break;
+ }
+}
+
+void Scene1950::process(Event &event) {
+ if ( (event.eventType == EVENT_BUTTON_DOWN)
+ && (R2_GLOBALS._player._uiEnabled)
+ && (R2_GLOBALS._events.getCursor() == R2_LIGHT_BULB)
+ && (R2_GLOBALS._player._bounds.contains(event.mousePos))
+ && (R2_INVENTORY.getObjectScene(31) == 0)) {
+ event.handled = true;
+ R2_GLOBALS._player.disableControl();
+ _exit7._enabled = false;
+ _exit8._enabled = false;
+ _sceneMode = 1959;
+ setAction(&_sequenceManager, this, 1959, &R2_GLOBALS._player, NULL);
+ }
+ Scene::process(event);
+}
+
+} // End of namespace Ringworld2
+} // End of namespace TsAGE
diff --git a/engines/tsage/ringworld2/ringworld2_scenes1.h b/engines/tsage/ringworld2/ringworld2_scenes1.h
new file mode 100644
index 0000000000..f65a89972d
--- /dev/null
+++ b/engines/tsage/ringworld2/ringworld2_scenes1.h
@@ -0,0 +1,1242 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef TSAGE_RINGWORLD2_SCENES1_H
+#define TSAGE_RINGWORLD2_SCENES1_H
+
+#include "common/scummsys.h"
+#include "tsage/converse.h"
+#include "tsage/events.h"
+#include "tsage/core.h"
+#include "tsage/scenes.h"
+#include "tsage/globals.h"
+#include "tsage/sound.h"
+#include "tsage/ringworld2/ringworld2_logic.h"
+#include "tsage/ringworld2/ringworld2_speakers.h"
+
+namespace TsAGE {
+
+namespace Ringworld2 {
+
+using namespace TsAGE;
+
+class Scene1010 : public SceneExt {
+public:
+ SequenceManager _sequenceManager;
+
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+ virtual void signal();
+};
+
+class Scene1020 : public SceneExt {
+public:
+ SequenceManager _sequenceManager;
+
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+ virtual void signal();
+ virtual void dispatch();
+};
+
+class Scene1100 : public SceneExt {
+ class Actor16 : public SceneActor {
+ public:
+ virtual bool startAction(CursorType action, Event &event);
+ };
+ class Actor17 : public SceneActor {
+ public:
+ virtual bool startAction(CursorType action, Event &event);
+ };
+ class Actor18 : public SceneActor {
+ public:
+ virtual bool startAction(CursorType action, Event &event);
+ };
+
+public:
+ int _field412, _field414;
+ SpeakerSeeker1100 _seekerSpeaker;
+ SpeakerQuinn1100 _quinnSpeaker;
+ SpeakerChief1100 _chiefSpeaker;
+ ScenePalette _palette1;
+ NamedHotspot _item1;
+ NamedHotspot _item2;
+ NamedHotspot _item3;
+ NamedHotspot _item4;
+ NamedHotspot _item5;
+ NamedHotspot _item6;
+ NamedHotspot _item7;
+ SceneActor _actor1;
+ SceneActor _actor2;
+ SceneActor _actor3;
+ SceneActor _actor4;
+ SceneActor _actor5;
+ SceneActor _actor6;
+ SceneActor _actor7;
+ SceneActor _actor8;
+ SceneActor _actor9;
+ SceneActor _actor10;
+ SceneActor _actor11;
+ SceneActor _actor12;
+ SceneActor _actor13;
+ SceneActor _actor14;
+ SceneActor _actor15;
+ BackgroundSceneObject _object1;
+ BackgroundSceneObject _object2;
+ Actor16 _actor16;
+ Actor17 _actor17;
+ Actor18 _actor18;
+ SequenceManager _sequenceManager1;
+ SequenceManager _sequenceManager2;
+ SequenceManager _sequenceManager3;
+
+ Scene1100();
+ void synchronize(Serializer &s);
+
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+ virtual void remove();
+ virtual void signal();
+ virtual void dispatch();
+ virtual void saveCharacter(int characterIndex);
+};
+
+class Scene1200 : public SceneExt {
+ class Area1: public SceneArea {
+ public:
+ class Actor3 : public SceneActorExt {
+ public:
+ void init(int state);
+ virtual bool startAction(CursorType action, Event &event);
+ };
+
+ SceneActor _actor2;
+ Actor3 _actor3;
+ Actor3 _actor4;
+ Actor3 _actor5;
+
+ byte _field20;
+
+ Area1();
+ void synchronize(Serializer &s);
+
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+ virtual void remove();
+ virtual void process(Event &event);
+ virtual void proc12(int visage, int stripFrameNum, int frameNum, int posX, int posY);
+ virtual void proc13(int resNum, int lookLineNum, int talkLineNum, int useLineNum);
+ };
+
+public:
+ NamedHotspot _item1;
+ SceneActor _actor1;
+ Area1 _area1;
+ UnkObject1200 _object1;
+ SequenceManager _sequenceManager;
+
+ int _field412;
+ int _field414;
+ int _field416;
+ int _field418;
+ int _field41A;
+ int _field41C;
+
+ Scene1200();
+ void synchronize(Serializer &s);
+
+ void sub9DAD6(int indx);
+
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+ virtual void signal();
+ virtual void process(Event &event);
+ virtual void dispatch();
+ virtual void saveCharacter(int characterIndex);
+};
+
+class Scene1337 : public SceneExt {
+ class unkObj1337sub1: public SceneHotspot {
+ public:
+ SceneObject _object1;
+
+ int _field34;
+ Common::Point _field36;
+
+ unkObj1337sub1();
+ void synchronize(Serializer &s);
+ };
+
+ class unkObj1337_1: public SceneHotspot {
+ public:
+ unkObj1337sub1 _arr1[4];
+ unkObj1337sub1 _arr2[8];
+ unkObj1337sub1 _arr3[1];
+ unkObj1337sub1 _arr4[1];
+
+ Common::Point _fieldB94;
+ Common::Point _fieldB98;
+ Common::Point _fieldB9C;
+ Common::Point _fieldBA0;
+ int _fieldBA4;
+
+ unkObj1337_1();
+ void synchronize(Serializer &s);
+ };
+
+ class Action1337: public Action {
+ public:
+ void subD18B5(int resNum, int stripNum, int frameNum);
+ void skipFrames(int32 skipCount);
+ };
+
+ class Action1: public Action1337 {
+ public:
+ void signal();
+ };
+ class Action2: public Action1337 {
+ public:
+ void signal();
+ };
+ class Action3: public Action1337 {
+ public:
+ void signal();
+ };
+ class Action4: public Action1337 {
+ public:
+ void signal();
+ };
+ class Action5: public Action1337 {
+ public:
+ void signal();
+ };
+ class Action6: public Action1337 {
+ public:
+ void signal();
+ };
+ class Action7: public Action1337 {
+ public:
+ void signal();
+ };
+ class Action8: public Action1337 {
+ public:
+ void signal();
+ };
+ class Action9: public Action1337 {
+ public:
+ void signal();
+ };
+ class Action10: public Action1337 {
+ public:
+ void signal();
+ };
+ class Action11: public Action1337 {
+ public:
+ void signal();
+ };
+ class Action12: public Action1337 {
+ public:
+ void signal();
+ };
+ class Action13: public Action1337 {
+ public:
+ void signal();
+ };
+public:
+ typedef void (Scene1337::*FunctionPtrType)();
+ FunctionPtrType _unkFctPtr412;
+
+ ASound _aSound1;
+ ASound _aSound2;
+ BackgroundSceneObject _background1;
+ bool _autoplay;
+ unkObj1337_1 _arrunkObj1337[4];
+ SceneItem _item1;
+ SceneObject _object1;
+ Action1 _action1;
+ Action2 _action2;
+ Action3 _action3;
+ Action4 _action4;
+ Action5 _action5;
+ Action6 _action6;
+ Action7 _action7;
+ Action8 _action8;
+ Action9 _action9;
+ Action10 _action10;
+ Action11 _action11;
+ Action12 _action12;
+ Action13 _action13;
+ unkObj1337sub1 _item2;
+ unkObj1337sub1 _item3;
+ unkObj1337sub1 _item4;
+ BackgroundSceneObject _background2;
+ int _field3E24;
+ int _field3E26;
+ int _field3E28[100];
+ unkObj1337sub1 *_field3EF0;
+ unkObj1337sub1 *_field3EF4;
+ unkObj1337sub1 *_field3EF8;
+ unkObj1337sub1 _item5;
+ unkObj1337sub1 _item6;
+ unkObj1337sub1 _item7;
+ unkObj1337sub1 _item8;
+ int _field423C;
+ int _field423E;
+ int _field4240;
+ int _field4242;
+ int _field4244;
+ int _field4246;
+ int _field4248;
+ int _field424A;
+ int _field424C;
+ int _field424E;
+
+ SceneObject _arrObject1[8];
+ SceneObject _arrObject2[8];
+
+ Scene1337();
+ virtual void synchronize(Serializer &s);
+
+ void actionDisplay(int resNum, int lineNum, int x, int y, int arg5, int width, int textMode, int fontNum, int colFG, int colBGExt, int colFGExt);
+ void setAnimationInfo(unkObj1337sub1 *subObj);
+ void subC20E5();
+ void subC20F9();
+ void subC2586();
+ bool subC264B(int arg1);
+ bool subC2687(int arg1);
+ int subC26CB(int arg1, int arg2);
+ int subC2719(int arg1);
+ int subC274D(int arg1);
+ int subC2781(int arg1);
+ int subC27B5(int arg1);
+ int subC27F9(int arg1);
+ void subC2835(int arg1);
+ bool subC2BF8(unkObj1337sub1 *subObj1, Common::Point pt);
+ void subC2C2F();
+ void subC318B(int arg1, unkObj1337sub1 *subObj2, int arg3);
+ int subC3257(int arg1);
+ bool subC32B1(int arg1, int arg2);
+ int subC331B(int arg1);
+ bool subC3386(int arg1, int arg2);
+ void subC33C0(unkObj1337sub1 *subObj1, unkObj1337sub1 *subObj2);
+ void subC3456(unkObj1337sub1 *subObj1, unkObj1337sub1 *subObj2);
+ void subC340B(unkObj1337sub1 *subObj1, unkObj1337sub1 *subObj2);
+ void subC34A1(unkObj1337sub1 *subObj1, unkObj1337sub1 *subObj2);
+ unkObj1337sub1 *subC34EC(int arg1);
+ void subC358E(unkObj1337sub1 *subObj1, int arg2);
+ int subC3E92(int arg1);
+ void subC4A39(unkObj1337sub1 *subObj);
+ void subC4CD2();
+ void subC4CEC();
+ void subC51A0(unkObj1337sub1 *subObj1, unkObj1337sub1 *subObj2);
+ void displayDialog(int dialogNumb);
+ void subPostInit();
+ void subCB59B();
+ void suggestInstructions();
+ void shuffleCards();
+ void subCCF26();
+ void subCD193();
+ void subCDB90(int arg1, Common::Point pt);
+ void subCF31D();
+ void subCF979();
+ void subD026D();
+ void subD0281();
+ void subD02CA();
+ void subD183F(int arg1, int arg2);
+ void subD18B5(int resNum, int rlbNum, int arg3);
+ int subD18F5();
+ int subD1917();
+ int subD1940(bool flag);
+ void subD195F(int arg1, int arg2);
+ void subD1975(int arg1, int arg2);
+ void subD1A48(int arg1);
+
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+ virtual void remove();
+ virtual void process(Event &event);
+ virtual void dispatch();
+};
+
+class Scene1500 : public SceneExt {
+public:
+ SceneActor _actor1;
+ SceneActor _actor2;
+ SceneActor _actor3;
+ SceneActor _actor4;
+ SequenceManager _sequenceManager;
+
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+ virtual void remove();
+ virtual void signal();
+ virtual void dispatch();
+};
+
+class Scene1525 : public SceneExt {
+public:
+ SequenceManager _sequenceManager;
+
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+ virtual void signal();
+};
+
+class Scene1530 : public SceneExt {
+public:
+ SpeakerQuinn _quinnSpeaker;
+ SpeakerSeeker _seekerSpeaker;
+ SceneActor _actor1;
+ SceneActor _actor2;
+ SceneActor _actor3;
+
+ SequenceManager _sequenceManager;
+
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+ virtual void signal();
+ virtual void dispatch();
+};
+
+class Scene1550 : public SceneExt {
+ class SceneActor1550 : public SceneActor {
+ public:
+ void subA4D14(int frameNumber, int strip);
+ };
+
+ class UnkObj15501 : public SceneActor {
+ public:
+ int _fieldA4;
+ int _fieldA6;
+
+ UnkObj15501();
+ void synchronize(Serializer &s);
+
+ virtual bool startAction(CursorType action, Event &event);
+ };
+
+ class UnkObj15502 : public SceneActor {
+ public:
+ int _fieldA4;
+
+ UnkObj15502();
+ void synchronize(Serializer &s);
+
+ virtual bool startAction(CursorType action, Event &event);
+ void subA5CDF(int strip);
+ };
+
+ class UnkObj15503 : public SceneActor {
+ public:
+ int _fieldA4;
+
+ UnkObj15503();
+ void synchronize(Serializer &s);
+
+ virtual bool startAction(CursorType action, Event &event);
+ };
+
+ class UnkArea1550 : public SceneArea {
+ public:
+ byte _field20;
+ SceneActor _areaActor;
+ UnkObj15503 _unkObj155031;
+ UnkObj15503 _unkObj155032;
+
+ virtual void remove();
+ virtual void process(Event &event);
+ virtual void proc12(int visage, int stripFrameNum, int frameNum, int posX, int posY);
+ virtual void proc13(int resNum, int lookLineNum, int talkLineNum, int useLineNum);
+ };
+
+ class Hotspot1 : public NamedHotspot {
+ public:
+ virtual bool startAction(CursorType action, Event &event);
+ };
+
+ class Hotspot3 : public NamedHotspot {
+ public:
+ virtual bool startAction(CursorType action, Event &event);
+ };
+
+ class Actor6 : public SceneActor {
+ public:
+ virtual bool startAction(CursorType action, Event &event);
+ };
+
+ class Actor7 : public SceneActor {
+ public:
+ virtual bool startAction(CursorType action, Event &event);
+ };
+
+ class Actor8 : public SceneActor {
+ public:
+ virtual bool startAction(CursorType action, Event &event);
+ };
+
+ class Actor9 : public SceneActor {
+ public:
+ virtual bool startAction(CursorType action, Event &event);
+ };
+
+ class Actor10 : public SceneActor {
+ public:
+ virtual bool startAction(CursorType action, Event &event);
+ };
+
+ class Actor11 : public SceneActor {
+ public:
+ virtual bool startAction(CursorType action, Event &event);
+ };
+
+ class Actor12 : public SceneActor {
+ public:
+ virtual bool startAction(CursorType action, Event &event);
+ };
+
+ class Actor13 : public SceneActor {
+ public:
+ virtual bool startAction(CursorType action, Event &event);
+ };
+
+ class Actor14 : public SceneActor1550 {
+ // Nothing specific found in the original
+ // TODO: check if it's an useless class
+ };
+
+public:
+ SpeakerQuinn _quinnSpeaker;
+ SpeakerSeeker _seekerSpeaker;
+ Hotspot1 _item1;
+ Hotspot1 _item2;
+ Hotspot3 _item3;
+ SceneActor _actor1;
+ SceneActor _actor2;
+ SceneActor _actor3;
+ SceneActor _actor4;
+ SceneActor _actor5;
+ Actor6 _actor6;
+ Actor7 _actor7;
+ Actor8 _actor8;
+ Actor9 _actor9;
+ Actor10 _actor10;
+ Actor11 _actor11;
+ Actor12 _actor12;
+ Actor13 _actor13;
+ UnkObj15501 _arrUnkObj15501[8];
+ Actor14 _actor14;
+ Actor14 _actor15;
+ Actor14 _actor16;
+ Actor14 _actor17;
+ Actor14 _actor18;
+ Actor14 _actor19;
+ UnkObj15502 _arrUnkObj15502[8];
+ UnkArea1550 _unkArea1;
+ SequenceManager _sequenceManager1;
+ SequenceManager _sequenceManager2;
+
+ int _field412;
+ byte _field414;
+ int _field415;
+ int _field417;
+ int _field419;
+
+ Scene1550();
+ void synchronize(Serializer &s);
+ void subA2B2F();
+
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+ virtual void signal();
+ virtual void process(Event &event);
+ virtual void dispatch();
+ virtual void saveCharacter(int characterIndex);
+};
+
+class Scene1575 : public SceneExt {
+ class Hotspot1 : public NamedHotspot {
+ public:
+ int _field34;
+ int _field36;
+
+ Hotspot1();
+ void synchronize(Serializer &s);
+ void subA910D(int indx);
+
+ virtual void process(Event &event);
+ virtual bool startAction(CursorType action, Event &event);
+ };
+public:
+ int _field412;
+ int _field414;
+ int _field416;
+ int _field418;
+ int _field41A;
+ Hotspot1 _item1;
+ Hotspot1 _item2;
+ Hotspot1 _item3;
+ Hotspot1 _item4;
+ Hotspot1 _item5;
+ Hotspot1 _item6;
+ SceneActor _actor1;
+ SceneActor _actor2;
+ SceneActor _actor3;
+ SceneActor _actor4;
+ SceneActor _actor5;
+ SceneActor _actor6;
+ SceneActor _actor7;
+ SceneActor _actor8;
+ SceneActor _actor9;
+ SceneActor _actor10;
+ SceneActor _actor11;
+ SceneActor _actor12;
+ SceneActor _actor13;
+ SceneActor _actor14;
+ SceneActor _actor15;
+ SceneActor _arrActor[17];
+ SequenceManager _sequenceManager1;
+
+ Scene1575();
+ void synchronize(Serializer &s);
+
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+ virtual void remove();
+ virtual void signal();
+ virtual void process(Event &event);
+ virtual void dispatch();
+};
+
+class Scene1580 : public SceneExt {
+ class Hotspot1 : public NamedHotspot {
+ public:
+ virtual bool startAction(CursorType action, Event &event);
+ };
+ class Hotspot2 : public NamedHotspot {
+ public:
+ virtual bool startAction(CursorType action, Event &event);
+ };
+
+ class Actor2 : public SceneActor {
+ public:
+ virtual bool startAction(CursorType action, Event &event);
+ };
+ class Actor3 : public SceneActor {
+ public:
+ virtual bool startAction(CursorType action, Event &event);
+ };
+ class Actor4 : public SceneActor {
+ public:
+ virtual bool startAction(CursorType action, Event &event);
+ };
+ class Actor5 : public SceneActor {
+ public:
+ virtual bool startAction(CursorType action, Event &event);
+ };
+ class Actor6 : public SceneActor {
+ public:
+ virtual bool startAction(CursorType action, Event &event);
+ };
+ class Actor7 : public SceneActor {
+ public:
+ virtual bool startAction(CursorType action, Event &event);
+ };
+public:
+ int _field412;
+ SpeakerQuinn _quinnSpeaker;
+ SpeakerSeeker _seekerSpeaker;
+ Hotspot1 _item1;
+ Hotspot2 _item2;
+ NamedHotspot _item3;
+ SceneActor _actor1;
+ SceneActor _arrActor[8];
+ Actor2 _actor2;
+ Actor3 _actor3;
+ Actor4 _actor4;
+ Actor5 _actor5;
+ Actor6 _actor6;
+ Actor7 _actor7;
+ SequenceManager _sequenceManager;
+
+ Scene1580();
+ void synchronize(Serializer &s);
+
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+ virtual void signal();
+};
+
+class Scene1625 : public SceneExt {
+ class Actor7 : public SceneActor {
+ public:
+ virtual bool startAction(CursorType action, Event &event);
+ };
+public:
+ int _field412;
+ SpeakerMiranda1625 _mirandaSpeaker;
+ SpeakerTeal1625 _tealSpeaker;
+ SpeakerSoldier1625 _soldierSpeaker;
+ NamedHotspot _item1;
+ SceneActor _actor1;
+ SceneActor _actor2;
+ SceneActor _actor3;
+ SceneActor _actor4;
+ SceneActor _actor5;
+ SceneActor _actor6;
+ Actor7 _actor7;
+ SequenceManager _sequenceManager;
+
+ Scene1625();
+ void synchronize(Serializer &s);
+
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+ virtual void remove();
+ virtual void signal();
+ virtual void process(Event &event);
+};
+
+class Scene1700 : public SceneExt {
+ class Item2 : public NamedHotspot {
+ public:
+ virtual bool startAction(CursorType action, Event &event);
+ };
+
+ class Actor11 : public SceneActor {
+ public:
+ virtual bool startAction(CursorType action, Event &event);
+ };
+ class Actor12 : public SceneActor {
+ public:
+ virtual bool startAction(CursorType action, Event &event);
+ };
+
+ class Exit1 : public SceneExit {
+ public:
+ virtual void changeScene();
+ };
+ class Exit2 : public SceneExit {
+ public:
+ virtual void changeScene();
+ };
+ class Exit3 : public SceneExit {
+ public:
+ virtual void changeScene();
+ };
+public:
+ SpeakerQuinn _quinnSpeaker;
+ SpeakerSeeker _seekerSpeaker;
+ NamedHotspot _item1;
+ Item2 _item2;
+ SceneActor _actor1;
+ SceneActor _actor2;
+ SceneActor _actor3;
+ SceneActor _actor4;
+ SceneActor _actor5;
+ SceneActor _actor6;
+ SceneActor _actor7;
+ SceneActor _actor8;
+ SceneActor _actor9;
+ SceneActor _actor10;
+ Actor11 _actor11;
+ Actor12 _actor12;
+ Exit1 _exit1;
+ Exit2 _exit2;
+ Exit3 _exit3;
+ SequenceManager _sequenceManager;
+
+ int _field77A;
+ int _field77C;
+
+ Scene1700();
+ void synchronize(Serializer &s);
+ void subAF3F8();
+
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+ virtual void remove();
+ virtual void signal();
+};
+
+class Scene1750 : public SceneExt {
+ class Actor4 : public SceneActor {
+ public:
+ int _fieldA4;
+ int _fieldA6;
+ int _fieldA8;
+ int _fieldAA;
+ int _fieldAC;
+ int _fieldAE;
+
+ Actor4();
+ virtual void synchronize(Serializer &s);
+ void subB1A76(int arg1, int arg2, int arg3, int arg4, int arg5);
+ void subB1B27();
+
+ virtual void remove();
+ virtual void process(Event &event);
+ virtual bool startAction(CursorType action, Event &event);
+ };
+
+ class Actor5 : public SceneActor {
+ public:
+ int _fieldA4;
+
+ Actor5();
+ virtual void synchronize(Serializer &s);
+
+ virtual bool startAction(CursorType action, Event &event);
+ };
+
+public:
+ NamedHotspot _item1;
+ NamedHotspot _item2;
+ NamedHotspot _item3;
+ NamedHotspot _item4;
+ NamedHotspot _item5;
+ SceneActor _actor1;
+ SceneActor _actor2;
+ SceneActor _actor3;
+ Actor4 _actor4;
+ Actor5 _actor5;
+ Actor5 _actor6;
+ Actor5 _actor7;
+ SequenceManager _sequenceManager;
+ PaletteRotation *_rotation;
+
+ int _field412;
+ int _field413;
+ int _field415;
+ int _field417;
+ int _field419;
+ int _field41B;
+ int _field41D;
+
+ Scene1750();
+ virtual void synchronize(Serializer &s);
+
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+ virtual void remove();
+ virtual void signal();
+ virtual void process(Event &event);
+ virtual void dispatch();
+};
+
+class Scene1800 : public SceneExt {
+ class Hotspot5 : public NamedHotspot {
+ public:
+ virtual bool startAction(CursorType action, Event &event);
+ };
+
+ class Actor6 : public SceneActor {
+ public:
+ virtual bool startAction(CursorType action, Event &event);
+ };
+ class Actor7 : public SceneActor {
+ public:
+ virtual bool startAction(CursorType action, Event &event);
+ };
+ class Actor8 : public SceneActor {
+ public:
+ virtual bool startAction(CursorType action, Event &event);
+ };
+
+ class Exit1 : public SceneExit {
+ public:
+ virtual void changeScene();
+ };
+public:
+ int _field412;
+ SpeakerQuinn _quinnSpeaker;
+ SpeakerSeeker _seekerSpeaker;
+ NamedHotspot _item1;
+ NamedHotspot _item2;
+ NamedHotspot _item3;
+ NamedHotspot _item4;
+ Hotspot5 _item5;
+ SceneActor _actor1;
+ SceneActor _actor2;
+ SceneActor _actor3;
+ SceneActor _actor4;
+ SceneActor _actor5;
+ Actor6 _actor6;
+ Actor7 _actor7;
+ Actor8 _actor8;
+ Actor8 _actor9;
+ Exit1 _exit1;
+ SequenceManager _sequenceManager;
+
+ Scene1800();
+ void synchronize(Serializer &s);
+
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+ virtual void signal();
+ virtual void saveCharacter(int characterIndex);
+};
+
+class Scene1850 : public SceneExt {
+ class Hotspot2 : public NamedHotspot {
+ public:
+ virtual bool startAction(CursorType action, Event &event);
+ };
+
+ class Actor5 : public SceneActor {
+ public:
+ virtual bool startAction(CursorType action, Event &event);
+ };
+ class Actor6 : public SceneActor {
+ public:
+ virtual bool startAction(CursorType action, Event &event);
+ };
+ class Actor8 : public SceneActor {
+ public:
+ virtual bool startAction(CursorType action, Event &event);
+ };
+
+public:
+ int _field412;
+ int _field414;
+ int _field416;
+ int _field418;
+ Common::Point _field41A;
+ int _field41E;
+ ScenePalette _palette1;
+ SpeakerQuinn _quinnSpeaker;
+ SpeakerSeeker _seekerSpeaker;
+ NamedHotspot _item1;
+ Hotspot2 _item2;
+ SceneActor _actor1;
+ SceneActor _actor2;
+ SceneActor _actor3;
+ SceneActor _actor4;
+ Actor5 _actor5;
+ Actor6 _actor6;
+ Actor6 _actor7;
+ Actor8 _actor8;
+ SequenceManager _sequenceManager1;
+ SequenceManager _sequenceManager2;
+
+ Scene1850();
+ void synchronize(Serializer &s);
+
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+ virtual void remove();
+ virtual void signal();
+ virtual void process(Event &event);
+ virtual void dispatch();
+};
+
+class Scene1875 : public SceneExt {
+ class Actor1875 : public SceneActor {
+ public:
+ int _fieldA4;
+ int _fieldA6;
+
+ Actor1875();
+ void subB84AB();
+ void subB8271(int indx);
+
+ void synchronize(Serializer &s);
+ virtual void process(Event &event);
+ };
+public:
+ SpeakerQuinn _quinnSpeaker;
+ SpeakerSeeker _seekerSpeaker;
+ NamedHotspot _item1;
+ NamedHotspot _item2;
+ SceneActor _actor1;
+ SceneActor _actor2;
+ SceneActor _actor3;
+ Actor1875 _actor4;
+ Actor1875 _actor5;
+ Actor1875 _actor6;
+ Actor1875 _actor7;
+ Actor1875 _actor8;
+ SequenceManager _sequenceManager;
+
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+ virtual void signal();
+ virtual void process(Event &event);
+};
+
+class Scene1900 : public SceneExt {
+ class Actor2 : public SceneActor {
+ public:
+ virtual bool startAction(CursorType action, Event &event);
+ };
+
+ class Exit1 : public SceneExit {
+ public:
+ virtual void changeScene();
+ };
+ class Exit2 : public SceneExit {
+ public:
+ virtual void changeScene();
+ };
+public:
+ SpeakerSeeker1900 _seekerSpeaker;
+ NamedHotspot _item1;
+ NamedHotspot _item2;
+ SceneActor _actor1;
+ BackgroundSceneObject _object1;
+ BackgroundSceneObject _object2;
+ Actor2 _actor2;
+ Actor2 _actor3;
+ Exit1 _exit1;
+ Exit2 _exit2;
+ SequenceManager _sequenceManager1;
+ SequenceManager _sequenceManager2;
+
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+ virtual void remove();
+ virtual void signal();
+};
+
+class Scene1925 : public SceneExt {
+ class Hotspot2 : public NamedHotspot {
+ public:
+ virtual bool startAction(CursorType action, Event &event);
+ };
+ class Hotspot3 : public NamedHotspot {
+ public:
+ virtual bool startAction(CursorType action, Event &event);
+ };
+
+ class ExitUp : public SceneExit {
+ public:
+ virtual void changeScene();
+ };
+ class Exit2 : public SceneExit {
+ public:
+ virtual void changeScene();
+ };
+ class Exit3 : public SceneExit {
+ public:
+ virtual void changeScene();
+ };
+ class Exit4 : public SceneExit {
+ public:
+ virtual void changeScene();
+ };
+public:
+ NamedHotspot _item1;
+ Hotspot2 _item2;
+ Hotspot3 _item3;
+ SceneActor _actor1;
+ ExitUp _exitUp;
+ Exit2 _exit2;
+ Exit3 _exit3;
+ Exit4 _exit4;
+ SequenceManager _sequenceManager;
+
+ int _field9B8;
+ int _levelResNum[5];
+
+ Scene1925();
+ void synchronize(Serializer &s);
+
+ void changeLevel(bool upFlag);
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+ virtual void remove();
+ virtual void signal();
+};
+
+class Scene1945 : public SceneExt {
+ class Hotspot3 : public NamedHotspot {
+ public:
+ virtual bool startAction(CursorType action, Event &event);
+ };
+ class Hotspot4 : public NamedHotspot {
+ public:
+ virtual bool startAction(CursorType action, Event &event);
+ };
+
+ class Actor3 : public SceneActor {
+ public:
+ virtual bool startAction(CursorType action, Event &event);
+ };
+
+ class ExitUp : public SceneExit {
+ public:
+ virtual void changeScene();
+ };
+ class Exit2 : public SceneExit {
+ public:
+ virtual void changeScene();
+ };
+public:
+ NamedHotspot _item1;
+ NamedHotspot _item2;
+ Hotspot3 _item3;
+ Hotspot4 _item4;
+ SceneActor _actor1;
+ SceneActor _actor2;
+ Actor3 _actor3;
+ ExitUp _exitUp;
+ Exit2 _exit2;
+ SequenceManager _sequenceManager1;
+ SequenceManager _sequenceManager2;
+
+ int _fieldEAA;
+ int _fieldEAC;
+ CursorType _fieldEAE;
+
+ Scene1945();
+ void synchronize(Serializer &s);
+
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+ virtual void remove();
+ virtual void signal();
+};
+
+class Scene1950 : public SceneExt {
+ class Area1: public SceneArea {
+ public:
+ class Actor10 : public SceneActor {
+ public:
+ int _fieldA4;
+ int _fieldA6;
+ int _fieldA8;
+
+ Actor10();
+ void synchronize(Serializer &s);
+
+ void init(int indx);
+ virtual void process(Event &event);
+ virtual bool startAction(CursorType action, Event &event);
+ };
+
+ SceneActor _areaActor;
+ Actor10 _arrActor1[16];
+
+ byte _field20;
+ int _fieldB65;
+
+ Area1();
+ void synchronize(Serializer &s);
+
+ virtual void remove();
+ virtual void process(Event &event);
+ virtual void proc12(int visage, int stripFrameNum, int frameNum, int posX, int posY);
+ virtual void proc13(int resNum, int lookLineNum, int talkLineNum, int useLineNum);
+ };
+
+ class Hotspot2 : public NamedHotspot {
+ public:
+ virtual bool startAction(CursorType action, Event &event);
+ };
+
+ class Actor2 : public SceneActor {
+ public:
+ virtual bool startAction(CursorType action, Event &event);
+ };
+ class Actor3 : public SceneActor {
+ public:
+ virtual bool startAction(CursorType action, Event &event);
+ };
+ class Actor4 : public SceneActor {
+ public:
+ virtual bool startAction(CursorType action, Event &event);
+ };
+ class Actor5 : public SceneActor {
+ public:
+ virtual bool startAction(CursorType action, Event &event);
+ };
+ class Actor8 : public SceneActor {
+ public:
+ int _fieldA4;
+ int _fieldA6;
+ int _fieldA8;
+ int _fieldAA;
+ int _fieldAC;
+ byte _fieldAE;
+ byte _fieldAF;
+
+ Actor8();
+ void synchronize(Serializer &s);
+
+ virtual void signal();
+ virtual bool startAction(CursorType action, Event &event);
+ };
+
+ class Exit1 : public SceneExit {
+ public:
+ virtual void changeScene();
+ };
+ class Exit2 : public SceneExit {
+ public:
+ virtual void changeScene();
+ };
+ class Exit3 : public SceneExit {
+ public:
+ virtual void changeScene();
+ };
+ class Exit4 : public SceneExit {
+ public:
+ virtual void changeScene();
+ };
+ class Exit5 : public SceneExit {
+ public:
+ virtual void changeScene();
+ };
+ class Exit6 : public SceneExit {
+ public:
+ virtual void changeScene();
+ };
+ class Exit7 : public SceneExit {
+ public:
+ virtual void changeScene();
+ };
+ class Exit8 : public SceneExit {
+ public:
+ virtual void changeScene();
+ };
+public:
+ NamedHotspot _item1;
+ Hotspot2 _item2;
+ SceneActor _actor1;
+ BackgroundSceneObject _object1;
+ Actor2 _actor2;
+ Actor3 _actor3;
+ SceneActor _actor4;
+ Actor5 _actor5;
+ SceneActor _actor6;
+ SceneActor _actor7;
+ Actor8 _actor8;
+ Area1 _area1;
+ Exit1 _exit1;
+ Exit2 _exit2;
+ Exit3 _exit3;
+ Exit4 _exit4;
+ Exit5 _exit5;
+ Exit6 _exit6;
+ Exit7 _exit7;
+ Exit8 _exit8;
+ SequenceManager _sequenceManager;
+
+ int _field412;
+ int _field414;
+ int _field416;
+ Common::Point _field418;
+ int _field41C;
+
+ Scene1950();
+ void synchronize(Serializer &s);
+
+ void subBDC1E();
+ void subBE59B();
+ void subBF4B4(int indx);
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+ virtual void remove();
+ virtual void signal();
+ virtual void process(Event &event);
+};
+} // End of namespace Ringworld2
+} // End of namespace TsAGE
+
+#endif
diff --git a/engines/tsage/ringworld2/ringworld2_scenes2.cpp b/engines/tsage/ringworld2/ringworld2_scenes2.cpp
new file mode 100644
index 0000000000..6a030e5b44
--- /dev/null
+++ b/engines/tsage/ringworld2/ringworld2_scenes2.cpp
@@ -0,0 +1,4527 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "tsage/scenes.h"
+#include "tsage/tsage.h"
+#include "tsage/staticres.h"
+#include "tsage/ringworld2/ringworld2_scenes2.h"
+
+namespace TsAGE {
+
+namespace Ringworld2 {
+
+/*--------------------------------------------------------------------------
+ * Scene 2000 - Ice Maze
+ *
+ *--------------------------------------------------------------------------*/
+void Scene2000::initPlayer() {
+ R2_GLOBALS._player.disableControl();
+
+ switch (_mazePlayerMode) {
+ case 0:
+ R2_GLOBALS._player.setStrip(5);
+ if (_exit1._enabled) {
+ if (_exit2._enabled)
+ R2_GLOBALS._player.setPosition(Common::Point(140, 129));
+ else
+ R2_GLOBALS._player.setPosition(Common::Point(20, 129));
+ } else
+ R2_GLOBALS._player.setPosition(Common::Point(245, 129));
+ R2_GLOBALS._player.enableControl();
+ break;
+ case 1:
+ if (R2_GLOBALS._player._characterIndex == 1)
+ _sceneMode = 2001;
+ else
+ _sceneMode = 2021;
+ setAction(&_sequenceManager, this, _sceneMode, &R2_GLOBALS._player, NULL);
+ break;
+ case 2:
+ if (R2_GLOBALS._player._characterIndex == 1)
+ _sceneMode = 2002;
+ else
+ _sceneMode = 2022;
+ setAction(&_sequenceManager, this, _sceneMode, &R2_GLOBALS._player, NULL);
+ break;
+ case 3:
+ if (R2_GLOBALS._player._characterIndex == 1)
+ _sceneMode = 2000;
+ else
+ _sceneMode = 2020;
+ setAction(&_sequenceManager, this, _sceneMode, &R2_GLOBALS._player, NULL);
+ break;
+ case 4:
+ if (R2_GLOBALS._player._characterIndex == 1)
+ _sceneMode = 2005;
+ else
+ _sceneMode = 2025;
+ setAction(&_sequenceManager, this, _sceneMode, &R2_GLOBALS._player, NULL);
+ break;
+ case 5:
+ if (R2_GLOBALS._player._characterIndex == 1)
+ _sceneMode = 2004;
+ else
+ _sceneMode = 2024;
+ setAction(&_sequenceManager, this, _sceneMode, &R2_GLOBALS._player, NULL);
+ break;
+ case 6:
+ if (R2_GLOBALS._player._characterIndex == 1)
+ _sceneMode = 2009;
+ else
+ _sceneMode = 2029;
+ setAction(&_sequenceManager, this, _sceneMode, &R2_GLOBALS._player, NULL);
+ break;
+ case 7:
+ if (R2_GLOBALS._player._characterIndex == 1)
+ _sceneMode = 2008;
+ else
+ _sceneMode = 2028;
+ setAction(&_sequenceManager, this, _sceneMode, &R2_GLOBALS._player, NULL);
+ break;
+ case 8:
+ if (R2_GLOBALS._player._characterIndex == 1)
+ _sceneMode = 2013;
+ else
+ _sceneMode = 2033;
+ setAction(&_sequenceManager, this, _sceneMode, &R2_GLOBALS._player, NULL);
+ break;
+ case 9:
+ if (R2_GLOBALS._player._characterIndex == 1)
+ _sceneMode = 2012;
+ else
+ _sceneMode = 2032;
+ setAction(&_sequenceManager, this, _sceneMode, &R2_GLOBALS._player, NULL);
+ break;
+ case 10:
+ if (R2_GLOBALS._player._characterIndex == 1)
+ _sceneMode = 2016;
+ else
+ _sceneMode = 2036;
+ setAction(&_sequenceManager, this, _sceneMode, &R2_GLOBALS._player, NULL);
+ break;
+ case 11:
+ if (R2_GLOBALS._player._characterIndex == 1)
+ _sceneMode = 2038;
+ else
+ _sceneMode = 2040;
+ setAction(&_sequenceManager, this, _sceneMode, &R2_GLOBALS._player, NULL);
+ break;
+ default:
+ break;
+ }
+ for (int i = 0; i < 11; i++) {
+ if (R2_GLOBALS._v56605[R2_GLOBALS._player._characterIndex] == R2_GLOBALS._v56605[3 + i])
+ _objList1[i].show();
+ }
+
+ if ((R2_GLOBALS._player._characterScene[1] == R2_GLOBALS._player._characterScene[2]) && (R2_GLOBALS._v56605[1] == R2_GLOBALS._v56605[2])) {
+ _object1.postInit();
+ if (R2_GLOBALS._player._characterIndex == 1) {
+ _object1.setup(20, 5, 1);
+ _object1.setDetails(9002, 0, 4, 3, 1, (SceneItem *)NULL);
+ } else {
+ _object1.setup(2008, 5, 1);
+ _object1.setDetails(9001, 0, 5, 3, 1, (SceneItem *)NULL);
+ }
+ if (_exit1._enabled) {
+ if (_exit2._enabled)
+ _object1.setPosition(Common::Point(180, 128));
+ else
+ _object1.setPosition(Common::Point(75, 128));
+ } else
+ _object1.setPosition(Common::Point(300, 128));
+ }
+}
+
+void Scene2000::initExits() {
+ _exit1._enabled = true;
+ _exit2._enabled = true;
+ _exit3._enabled = false;
+ _exit4._enabled = false;
+ _exit5._enabled = false;
+
+ _exit1._insideArea = false;
+ _exit2._insideArea = false;
+ _exit3._insideArea = false;
+ _exit4._insideArea = false;
+ _exit5._insideArea = false;
+
+ _exit1._moving = false;
+ _exit2._moving = false;
+ _exit3._moving = false;
+ _exit4._moving = false;
+ _exit5._moving = false;
+
+ for (int i = 0; i < 11; i++)
+ _objList1[i].hide();
+
+ _object1.remove();
+
+ switch (R2_GLOBALS._v56605[R2_GLOBALS._player._characterIndex]) {
+ case 3:
+ case 10:
+ case 16:
+ case 21:
+ _exit5._enabled = true;
+ _exit5._bounds.set(61, 68, 90, 125);
+ _exit5.setDest(Common::Point(92, 129));
+ _exit5._cursorNum = EXITCURSOR_W;
+ break;
+ case 4:
+ case 12:
+ case 25:
+ case 34:
+ _exit5._enabled = true;
+ _exit5._bounds.set(230, 68, 259, 125);
+ _exit5.setDest(Common::Point(244, 129));
+ _exit5._cursorNum = EXITCURSOR_E;
+ break;
+ default:
+ break;
+ }
+
+ switch (R2_GLOBALS._v56605[R2_GLOBALS._player._characterIndex] - 1) {
+ case 0:
+ case 6:
+ case 13:
+ case 18:
+ case 22:
+ case 27:
+ case 30:
+ _exit1._enabled = false;
+ loadScene(2225);
+ R2_GLOBALS._walkRegions.load(2225);
+ if (!_exitingFlag)
+ _mazePlayerMode = 0;
+ R2_GLOBALS._player._oldCharacterScene[R2_GLOBALS._player._characterIndex] = 2000;
+ break;
+ case 1:
+ case 19:
+ _exit3._enabled = true;
+ _exit3._bounds.set(71, 130, 154, 168);
+ _exit3.setDest(Common::Point(94, 129));
+ _exit3._cursorNum = EXITCURSOR_SE;
+ loadScene(2300);
+ if (!_exitingFlag)
+ _mazePlayerMode = 0;
+ R2_GLOBALS._player._oldCharacterScene[R2_GLOBALS._player._characterIndex] = 2000;
+ R2_GLOBALS._walkRegions.load(2000);
+ break;
+ case 2:
+ case 9:
+ case 15:
+ case 20:
+ loadScene(2150);
+ R2_GLOBALS._walkRegions.load(2000);
+ switch(R2_GLOBALS._player._oldCharacterScene[R2_GLOBALS._player._characterIndex]) {
+ case 2400:
+ _mazePlayerMode = 1;
+ break;
+ case 2425:
+ case 2430:
+ case 2435:
+ case 2450:
+ _mazePlayerMode = 3;
+ break;
+ default:
+ if (!_exitingFlag)
+ _mazePlayerMode = 0;
+ break;
+ }
+ R2_GLOBALS._player._oldCharacterScene[R2_GLOBALS._player._characterIndex] = 2000;
+ R2_GLOBALS._sceneManager._previousScene = 2000;
+ break;
+ case 3:
+ case 11:
+ case 24:
+ case 33:
+ loadScene(2175);
+ R2_GLOBALS._walkRegions.load(2000);
+ if (R2_GLOBALS._player._oldCharacterScene[R2_GLOBALS._player._characterIndex] == 2000) {
+ if (!_exitingFlag)
+ _mazePlayerMode = 0;
+ } else if (R2_GLOBALS._player._oldCharacterScene[R2_GLOBALS._player._characterIndex] == 2350)
+ _mazePlayerMode = 1;
+ else
+ _mazePlayerMode = 10;
+ R2_GLOBALS._player._oldCharacterScene[R2_GLOBALS._player._characterIndex] = 2000;
+ R2_GLOBALS._sceneManager._previousScene = 2000;
+ break;
+ case 4:
+ case 8:
+ loadScene(2000);
+ R2_GLOBALS._walkRegions.load(2000);
+ if (R2_GLOBALS._player._oldCharacterScene[R2_GLOBALS._player._characterIndex] == 1900)
+ _mazePlayerMode = 1;
+ else if (!_exitingFlag)
+ _mazePlayerMode = 0;
+ R2_GLOBALS._player._oldCharacterScene[R2_GLOBALS._player._characterIndex] = 2000;
+ R2_GLOBALS._sceneManager._previousScene = 2000;
+ break;
+ case 5:
+ case 12:
+ case 17:
+ case 21:
+ case 26:
+ loadScene(2200);
+ R2_GLOBALS._walkRegions.load(2000);
+ _exit2._enabled = false;
+ if (R2_GLOBALS._player._oldCharacterScene[R2_GLOBALS._player._characterIndex] == 1900)
+ _mazePlayerMode = 2;
+ else if (!_exitingFlag)
+ _mazePlayerMode = 0;
+ R2_GLOBALS._player._oldCharacterScene[R2_GLOBALS._player._characterIndex] = 2000;
+ R2_GLOBALS._sceneManager._previousScene = 2000;
+ break;
+ case 7:
+ case 29:
+ _exit4._enabled = true;
+ _exit4._bounds.set(138, 83, 211, 125);
+ _exit4.setDest(Common::Point(129, 188));
+ _exit4._cursorNum = EXITCURSOR_NW;
+ loadScene(2250);
+ R2_GLOBALS._walkRegions.load(2000);
+ if (R2_GLOBALS._player._oldCharacterScene[R2_GLOBALS._player._characterIndex] == 2500)
+ _mazePlayerMode = 1;
+ else if (!_exitingFlag)
+ _mazePlayerMode = 0;
+ R2_GLOBALS._player._oldCharacterScene[R2_GLOBALS._player._characterIndex] = 2000;
+ R2_GLOBALS._sceneManager._previousScene = 2000;
+ break;
+ case 10:
+ case 25:
+ _exit3._enabled = true;
+ _exit3._bounds.set(78, 130, 148, 168);
+ _exit3.setDest(Common::Point(100, 129));
+ _exit3._cursorNum = EXITCURSOR_SE;
+ loadScene(2075);
+ R2_GLOBALS._walkRegions.load(2000);
+ if (!_exitingFlag)
+ _mazePlayerMode = 0;
+ R2_GLOBALS._player._oldCharacterScene[R2_GLOBALS._player._characterIndex] = 2000;
+ break;
+ case 14:
+ _exit3._enabled = true;
+ _exit3._bounds.set(160, 130, 248, 168);
+ _exit3.setDest(Common::Point(225, 129));
+ _exit3._cursorNum = EXITCURSOR_SW;
+ loadScene(2325);
+ R2_GLOBALS._walkRegions.load(2000);
+ if (!_exitingFlag)
+ _mazePlayerMode = 0;
+ R2_GLOBALS._player._oldCharacterScene[R2_GLOBALS._player._characterIndex] = 2000;
+ break;
+ case 16:
+ case 31:
+ _exit4._enabled = true;
+ _exit4._bounds.set(122, 83, 207, 125);
+ _exit4.setDest(Common::Point(210, 129));
+ _exit4._cursorNum = EXITCURSOR_NW;
+ loadScene(2125);
+ R2_GLOBALS._walkRegions.load(2000);
+ if (R2_GLOBALS._player._oldCharacterScene[R2_GLOBALS._player._characterIndex] == 2400)
+ _mazePlayerMode = 2;
+ else if (!_exitingFlag)
+ _mazePlayerMode = 0;
+ R2_GLOBALS._player._oldCharacterScene[R2_GLOBALS._player._characterIndex] = 2000;
+ R2_GLOBALS._sceneManager._previousScene = 2000;
+ break;
+ case 23:
+ _exit4._enabled = true;
+ _exit4._bounds.set(108, 83, 128, 184);
+ _exit4.setDest(Common::Point(135, 129));
+ _exit4._cursorNum = CURSOR_INVALID;
+ loadScene(2275);
+ R2_GLOBALS._walkRegions.load(2000);
+ if (!_exitingFlag)
+ _mazePlayerMode = 0;
+ R2_GLOBALS._player._oldCharacterScene[R2_GLOBALS._player._characterIndex] = 2000;
+ break;
+ case 28:
+ _exit3._enabled = true;
+ _exit3._bounds.set(171, 130, 241, 168);
+ _exit3.setDest(Common::Point(218, 129));
+ _exit3._cursorNum = EXITCURSOR_SW;
+ loadScene(2050);
+ R2_GLOBALS._walkRegions.load(2000);
+ if (R2_GLOBALS._player._oldCharacterScene[R2_GLOBALS._player._characterIndex] == 2350)
+ _mazePlayerMode = 11;
+ else if (!_exitingFlag)
+ _mazePlayerMode = 0;
+ R2_GLOBALS._player._oldCharacterScene[R2_GLOBALS._player._characterIndex] = 2000;
+ break;
+ case 32:
+ loadScene(2025);
+ R2_GLOBALS._walkRegions.load(2000);
+ if (!_exitingFlag)
+ _mazePlayerMode = 0;
+ R2_GLOBALS._player._oldCharacterScene[R2_GLOBALS._player._characterIndex] = 2000;
+ break;
+ default:
+ break;
+ }
+ _exitingFlag = false;
+ R2_GLOBALS._uiElements.show();
+}
+
+void Scene2000::Action1::signal() {
+ Scene2000 *scene = (Scene2000 *)R2_GLOBALS._sceneManager._scene;
+
+ switch (_actionIndex) {
+ case 0: {
+ _actionIndex = 1;
+ Common::Point pt(-20, 127);
+ NpcMover *mover = new NpcMover();
+ scene->_objList1[_state].addMover(mover, &pt, scene);
+ break;
+ }
+ case 1:
+ scene->_objList1[_state].setPosition(Common::Point(340, 127));
+ --R2_GLOBALS._v56605[4 + _state];
+ _actionIndex = 0;
+ switch (_state - 1) {
+ case 0:
+ if (R2_GLOBALS._v56605[4] == 1)
+ _actionIndex = 10;
+ break;
+ case 2:
+ if (R2_GLOBALS._v56605[6] == 7)
+ _actionIndex = 10;
+ break;
+ case 4:
+ if (R2_GLOBALS._v56605[8] == 14)
+ _actionIndex = 10;
+ break;
+ case 6:
+ if (R2_GLOBALS._v56605[10] == 19)
+ _actionIndex = 10;
+ break;
+ case 7:
+ if (R2_GLOBALS._v56605[11] == 23)
+ _actionIndex = 10;
+ break;
+ default:
+ break;
+ }
+
+ if (R2_GLOBALS._v56605[3 + _state] == R2_GLOBALS._v56605[R2_GLOBALS._player._characterIndex])
+ scene->_objList1[_state].show();
+ else
+ scene->_objList1[_state].hide();
+
+ signal();
+ break;
+ case 5: {
+ _actionIndex = 6;
+ Common::Point pt(340, 127);
+ NpcMover *mover = new NpcMover();
+ scene->_objList1[_state].addMover(mover, &pt, this);
+ break;
+ }
+ case 6:
+ scene->_objList1[_state].setPosition(Common::Point(-20, 127));
+ ++R2_GLOBALS._v56605[3 + _state];
+ _actionIndex = 5;
+ switch (_state - 1) {
+ case 0:
+ if (R2_GLOBALS._v56605[4] == 5)
+ _actionIndex = 15;
+ break;
+ case 2:
+ if (R2_GLOBALS._v56605[6] == 13)
+ _actionIndex = 15;
+ break;
+ case 4:
+ if (R2_GLOBALS._v56605[8] == 16)
+ _actionIndex = 15;
+ break;
+ case 6:
+ if (R2_GLOBALS._v56605[10] == 22)
+ _actionIndex = 15;
+ break;
+ case 7:
+ if (R2_GLOBALS._v56605[11] == 27)
+ _actionIndex = 15;
+ break;
+ default:
+ break;
+ }
+
+ if (R2_GLOBALS._v56605[3 + _state] == R2_GLOBALS._v56605[R2_GLOBALS._player._characterIndex])
+ scene->_objList1[_state].show();
+ else
+ scene->_objList1[_state].hide();
+
+ signal();
+ break;
+ case 10: {
+ Common::Point pt(290, 127);
+ NpcMover *mover = new NpcMover();
+ scene->_objList1[_state].addMover(mover, &pt, this);
+ _actionIndex = 11;
+ break;
+ }
+ case 11:
+ if (_state == 1)
+ scene->_objList1[0].setStrip(1);
+ else if (_state == 5)
+ scene->_objList1[4].setStrip(1);
+ setDelay(600);
+ _actionIndex = 12;
+ break;
+ case 12:
+ if (_state == 1)
+ scene->_objList1[0].setStrip(2);
+ else if (_state == 5)
+ scene->_objList1[4].setStrip(2);
+ scene->_objList1[_state].setStrip(1);
+ _actionIndex = 5;
+ signal();
+ break;
+ case 15:
+ if ((R2_GLOBALS._v56605[3 + _state] == 13) || (R2_GLOBALS._v56605[3 + _state] == 22) || (R2_GLOBALS._v56605[3 + _state] == 27)) {
+ Common::Point pt(30, 127);
+ NpcMover *mover = new NpcMover();
+ scene->_objList1[_state].addMover(mover, &pt, this);
+ _actionIndex = 16;
+ } else {
+ Common::Point pt(120, 127);
+ NpcMover *mover = new NpcMover();
+ scene->_objList1[_state].addMover(mover, &pt, this);
+ _actionIndex = 16;
+ }
+ break;
+ case 16:
+ if (_state == 1)
+ scene->_objList1[2].setStrip(2);
+ else if (_state == 8)
+ scene->_objList1[9].setStrip(2);
+ setDelay(600);
+ _actionIndex = 17;
+ break;
+ case 17:
+ if (_state == 1)
+ scene->_objList1[2].setStrip(1);
+ else if (_state == 8)
+ scene->_objList1[9].setStrip(1);
+ scene->_objList1[_state].setStrip(2);
+ _actionIndex = 0;
+ break;
+ case 99:
+ error("99");
+ break;
+ default:
+ break;
+ }
+}
+
+void Scene2000::Exit1::changeScene() {
+ Scene2000 *scene = (Scene2000 *)R2_GLOBALS._sceneManager._scene;
+
+ scene->_exitingFlag = true;
+ scene->_sceneMode = 0;
+ R2_GLOBALS._player.disableControl(CURSOR_ARROW);
+ scene->_sceneMode = 10;
+
+ Common::Point pt(-10, 129);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, scene);
+
+ scene->setAction(&scene->_sequenceManager, scene, 206, &R2_GLOBALS._player, NULL);
+}
+
+void Scene2000::Exit2::changeScene() {
+ Scene2000 *scene = (Scene2000 *)R2_GLOBALS._sceneManager._scene;
+
+ scene->_exitingFlag = true;
+ scene->_sceneMode = 0;
+ R2_GLOBALS._player.disableControl(CURSOR_ARROW);
+ scene->_sceneMode = 11;
+
+ Common::Point pt(330, 129);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, scene);
+}
+
+void Scene2000::Exit3::changeScene() {
+ Scene2000 *scene = (Scene2000 *)R2_GLOBALS._sceneManager._scene;
+
+ scene->_exitingFlag = true;
+ scene->_sceneMode = 0;
+ R2_GLOBALS._player.disableControl(CURSOR_ARROW);
+ scene->_sceneMode = 12;
+
+ switch (R2_GLOBALS._v56605[R2_GLOBALS._player._characterIndex]) {
+ case 2:
+ scene->_mazePlayerMode = 4;
+ R2_GLOBALS._v56605[R2_GLOBALS._player._characterIndex] = 8;
+ break;
+ case 11:
+ scene->_mazePlayerMode = 6;
+ R2_GLOBALS._v56605[R2_GLOBALS._player._characterIndex] = 17;
+ break;
+ case 15:
+ scene->_mazePlayerMode = 8;
+ R2_GLOBALS._v56605[R2_GLOBALS._player._characterIndex] = 24;
+ break;
+ case 20:
+ scene->_mazePlayerMode = 4;
+ R2_GLOBALS._v56605[R2_GLOBALS._player._characterIndex] = 30;
+ break;
+ case 26:
+ scene->_mazePlayerMode = 6;
+ R2_GLOBALS._v56605[R2_GLOBALS._player._characterIndex] = 32;
+ break;
+ case 29:
+ scene->_mazePlayerMode = 11;
+ R2_GLOBALS._v56605[R2_GLOBALS._player._characterIndex] = 29;
+ break;
+ default:
+ break;
+ }
+
+ switch (scene->_mazePlayerMode) {
+ case 4:
+ if (R2_GLOBALS._player._characterIndex == 1)
+ scene->setAction(&scene->_sequenceManager, scene, 2003, &R2_GLOBALS._player, NULL);
+ else
+ scene->setAction(&scene->_sequenceManager, scene, 2023, &R2_GLOBALS._player, NULL);
+ break;
+ case 6:
+ if (R2_GLOBALS._player._characterIndex == 1)
+ scene->setAction(&scene->_sequenceManager, scene, 2007, &R2_GLOBALS._player, NULL);
+ else
+ scene->setAction(&scene->_sequenceManager, scene, 2027, &R2_GLOBALS._player, NULL);
+ break;
+ case 8:
+ if (R2_GLOBALS._player._characterIndex == 1)
+ scene->setAction(&scene->_sequenceManager, scene, 2011, &R2_GLOBALS._player, NULL);
+ else
+ scene->setAction(&scene->_sequenceManager, scene, 2031, &R2_GLOBALS._player, NULL);
+ break;
+ case 11:
+ if (R2_GLOBALS._player._characterIndex == 1)
+ scene->_sceneMode = 2039;
+ else
+ scene->_sceneMode = 2041;
+ scene->setAction(&scene->_sequenceManager, scene, scene->_sceneMode, &R2_GLOBALS._player, NULL);
+ break;
+
+ default:
+ break;
+ }
+}
+void Scene2000::Exit4::changeScene() {
+ Scene2000 *scene = (Scene2000 *)R2_GLOBALS._sceneManager._scene;
+
+ scene->_exitingFlag = true;
+ scene->_sceneMode = 0;
+ R2_GLOBALS._player.disableControl(CURSOR_ARROW);
+ scene->_sceneMode = 13;
+
+ switch (R2_GLOBALS._v56605[R2_GLOBALS._player._characterIndex]) {
+ case 8:
+ scene->_mazePlayerMode = 5;
+ R2_GLOBALS._v56605[R2_GLOBALS._player._characterIndex] = 2;
+ break;
+ case 17:
+ scene->_mazePlayerMode = 7;
+ R2_GLOBALS._v56605[R2_GLOBALS._player._characterIndex] = 11;
+ break;
+ case 24:
+ scene->_mazePlayerMode = 9;
+ R2_GLOBALS._v56605[R2_GLOBALS._player._characterIndex] = 15;
+ break;
+ case 30:
+ scene->_mazePlayerMode = 5;
+ R2_GLOBALS._v56605[R2_GLOBALS._player._characterIndex] = 20;
+ break;
+ case 32:
+ scene->_mazePlayerMode = 7;
+ R2_GLOBALS._v56605[R2_GLOBALS._player._characterIndex] = 26;
+ break;
+ default:
+ break;
+ }
+
+ switch (scene->_mazePlayerMode) {
+ case 5:
+ if (R2_GLOBALS._player._characterIndex == 1)
+ scene->setAction(&scene->_sequenceManager, scene, 2006, &R2_GLOBALS._player, NULL);
+ else
+ scene->setAction(&scene->_sequenceManager, scene, 2026, &R2_GLOBALS._player, NULL);
+ break;
+ case 7:
+ if (R2_GLOBALS._player._characterIndex == 1)
+ scene->setAction(&scene->_sequenceManager, scene, 2010, &R2_GLOBALS._player, NULL);
+ else
+ scene->setAction(&scene->_sequenceManager, scene, 2030, &R2_GLOBALS._player, NULL);
+ break;
+ case 9:
+ if (R2_GLOBALS._player._characterIndex == 1)
+ scene->setAction(&scene->_sequenceManager, scene, 2014, &R2_GLOBALS._player, NULL);
+ else
+ scene->setAction(&scene->_sequenceManager, scene, 2034, &R2_GLOBALS._player, NULL);
+ break;
+ default:
+ break;
+ }
+}
+
+void Scene2000::Exit5::changeScene() {
+ Scene2000 *scene = (Scene2000 *)R2_GLOBALS._sceneManager._scene;
+
+ scene->_sceneMode = 0;
+ R2_GLOBALS._player.disableControl(CURSOR_ARROW);
+ scene->_sceneMode = 14;
+
+ switch (R2_GLOBALS._v56605[R2_GLOBALS._player._characterIndex]) {
+ case 3:
+ scene->_mazePlayerMode = 1;
+ if (R2_GLOBALS._player._characterIndex == 1)
+ scene->setAction(&scene->_sequenceManager, scene, 2015, &R2_GLOBALS._player, NULL);
+ else
+ scene->setAction(&scene->_sequenceManager, scene, 2035, &R2_GLOBALS._player, NULL);
+ break;
+ case 4:
+ scene->_mazePlayerMode = 7;
+ if (R2_GLOBALS._player._characterIndex == 1)
+ scene->setAction(&scene->_sequenceManager, scene, 2017, &R2_GLOBALS._player, NULL);
+ else
+ scene->setAction(&scene->_sequenceManager, scene, 2037, &R2_GLOBALS._player, NULL);
+ break;
+ case 10:
+ scene->_mazePlayerMode = 8;
+ if (R2_GLOBALS._player._characterIndex == 1)
+ scene->setAction(&scene->_sequenceManager, scene, 2015, &R2_GLOBALS._player, NULL);
+ else
+ scene->setAction(&scene->_sequenceManager, scene, 2035, &R2_GLOBALS._player, NULL);
+ break;
+ case 12:
+ scene->_mazePlayerMode = 3;
+ if (R2_GLOBALS._player._characterIndex == 1)
+ scene->setAction(&scene->_sequenceManager, scene, 2017, &R2_GLOBALS._player, NULL);
+ else
+ scene->setAction(&scene->_sequenceManager, scene, 2037, &R2_GLOBALS._player, NULL);
+ break;
+ case 16:
+ scene->_mazePlayerMode = 4;
+ if (R2_GLOBALS._player._characterIndex == 1)
+ scene->setAction(&scene->_sequenceManager, scene, 2015, &R2_GLOBALS._player, NULL);
+ else
+ scene->setAction(&scene->_sequenceManager, scene, 2035, &R2_GLOBALS._player, NULL);
+ break;
+ case 21:
+ scene->_mazePlayerMode = 5;
+ if (R2_GLOBALS._player._characterIndex == 1)
+ scene->setAction(&scene->_sequenceManager, scene, 2015, &R2_GLOBALS._player, NULL);
+ else
+ scene->setAction(&scene->_sequenceManager, scene, 2035, &R2_GLOBALS._player, NULL);
+ break;
+ case 25:
+ scene->_mazePlayerMode = 2;
+ if (R2_GLOBALS._player._characterIndex == 1)
+ scene->setAction(&scene->_sequenceManager, scene, 2017, &R2_GLOBALS._player, NULL);
+ else
+ scene->setAction(&scene->_sequenceManager, scene, 2037, &R2_GLOBALS._player, NULL);
+ break;
+ case 34:
+ scene->_mazePlayerMode = 6;
+ if (R2_GLOBALS._player._characterIndex == 1)
+ scene->setAction(&scene->_sequenceManager, scene, 2017, &R2_GLOBALS._player, NULL);
+ else
+ scene->setAction(&scene->_sequenceManager, scene, 2037, &R2_GLOBALS._player, NULL);
+ break;
+ default:
+ break;
+ }
+}
+
+void Scene2000::postInit(SceneObjectList *OwnerList) {
+ SceneExt::postInit();
+ loadScene(2000);
+
+ if (R2_GLOBALS._sceneManager._previousScene != -1) {
+ R2_GLOBALS._v56605[1] = 21;
+ R2_GLOBALS._v56605[2] = 21;
+ }
+ if ((R2_GLOBALS._player._characterScene[R2_GLOBALS._player._characterIndex] != R2_GLOBALS._player._oldCharacterScene[R2_GLOBALS._player._characterIndex]) && (R2_GLOBALS._player._oldCharacterScene[R2_GLOBALS._player._characterIndex] != 2350)) {
+ R2_GLOBALS._player._oldCharacterScene[R2_GLOBALS._player._characterIndex] = 0;
+ }
+ _exitingFlag = false;
+
+ _exit1.setDetails(Rect(0, 100, 14, 140), EXITCURSOR_W, 2000);
+ _exit1.setDest(Common::Point(14, 129));
+ _exit2.setDetails(Rect(305, 100, 320, 140), EXITCURSOR_E, 2000);
+ _exit2.setDest(Common::Point(315, 129));
+ _exit3.setDetails(Rect(71, 130, 154, 168), EXITCURSOR_S, 2000);
+ _exit3.setDest(Common::Point(94, 129));
+ _exit4.setDetails(Rect(138, 83, 211, 125), EXITCURSOR_N, 2000);
+ _exit4.setDest(Common::Point(188, 128));
+ _exit5.setDetails(Rect(61, 68, 90, 125), EXITCURSOR_W, 2000);
+ _exit5.setDest(Common::Point(92, 129));
+
+ R2_GLOBALS._sound1.play(200);
+ initExits();
+ g_globals->_sceneManager._fadeMode = FADEMODE_IMMEDIATE;
+
+ R2_GLOBALS._player.postInit();
+ R2_GLOBALS._player.animate(ANIM_MODE_1, NULL);
+
+ if (R2_GLOBALS._player._characterIndex == 1) {
+ R2_GLOBALS._player.setup(2008, 3, 1);
+ R2_GLOBALS._player._moveDiff = Common::Point(3, 2);
+ } else {
+ R2_GLOBALS._player.setup(20, 3, 1);
+ R2_GLOBALS._player._moveDiff = Common::Point(5, 3);
+ }
+
+ _action1._state = 8;
+ _action2._state = 1;
+ _action3._state = 5;
+ _action4._state = 7;
+ _action5._state = 3;
+
+ for (int i = 0; i < 11; i++)
+ _objList1[i].postInit();
+
+ _objList1[0].setVisage(2000);
+ _objList1[0].setStrip(2);
+ _objList1[0].setDetails(2001, 0, -1, -1, 1, (SceneItem *)NULL);
+
+ _objList1[1].setVisage(2001);
+ _objList1[1].setStrip(2);
+ _objList1[1].setDetails(2001, 0, -1, -1, 1, (SceneItem *)NULL);
+
+ _objList1[2].setVisage(2003);
+ _objList1[2].setStrip(1);
+ _objList1[2].setDetails(2001, 0, -1, -1, 1, (SceneItem *)NULL);
+
+ _objList1[3].setVisage(2007);
+ _objList1[3].setStrip(2);
+ _objList1[3].setDetails(2001, 12, -1, -1, 1, (SceneItem *)NULL);
+
+ _objList1[4].setVisage(2004);
+ _objList1[4].setStrip(2);
+ _objList1[4].setDetails(2001, 19, -1, -1, 1, (SceneItem *)NULL);
+
+ _objList1[5].setVisage(2003);
+ _objList1[5].setStrip(2);
+ _objList1[5].setDetails(2001, 0, -1, -1, 1, (SceneItem *)NULL);
+
+ _objList1[6].setVisage(2000);
+ _objList1[6].setStrip(1);
+ _objList1[6].setDetails(2001, 0, -1, -1, 1, (SceneItem *)NULL);
+
+ _objList1[7].setVisage(2000);
+ _objList1[7].setStrip(2);
+ _objList1[7].setDetails(2001, 0, -1, -1, 1, (SceneItem *)NULL);
+
+ _objList1[8].setVisage(2000);
+ _objList1[8].setStrip(2);
+ _objList1[8].setDetails(2001, 0, -1, -1, 1, (SceneItem *)NULL);
+
+ _objList1[9].setVisage(2006);
+ _objList1[9].setStrip(1);
+ _objList1[9].setDetails(2001, 6, -1, -1, 1, (SceneItem *)NULL);
+
+ _objList1[10].setVisage(2007);
+ _objList1[10].setStrip(1);
+ _objList1[10].setDetails(2001, 12, -1, -1, 1, (SceneItem *)NULL);
+
+ for (int i = 0; i < 11; i++) {
+ _objList1[i].animate(ANIM_MODE_1, NULL);
+ _objList1[i]._moveDiff.x = 3;
+ _objList1[i]._moveRate = 8;
+ _objList1[i].hide();
+ switch (i - 1) {
+ case 0:
+ if (R2_GLOBALS._v56605[3 + i] == 1)
+ ++R2_GLOBALS._v56605[3 + i];
+ else if (R2_GLOBALS._v56605[3 + i] == 5)
+ --R2_GLOBALS._v56605[3 + i];
+ break;
+ case 2:
+ if (R2_GLOBALS._v56605[3 + i] == 7)
+ ++R2_GLOBALS._v56605[3 + i];
+ else if (R2_GLOBALS._v56605[3 + i] == 13)
+ --R2_GLOBALS._v56605[3 + i];
+ break;
+ case 4:
+ if (R2_GLOBALS._v56605[3 + i] == 14)
+ ++R2_GLOBALS._v56605[3 + i];
+ else if (R2_GLOBALS._v56605[3 + i] == 16)
+ --R2_GLOBALS._v56605[3 + i];
+ break;
+ case 6:
+ if (R2_GLOBALS._v56605[3 + i] == 19)
+ ++R2_GLOBALS._v56605[3 + i];
+ else if (R2_GLOBALS._v56605[3 + i] == 22)
+ --R2_GLOBALS._v56605[3 + i];
+ break;
+ case 8:
+ if (R2_GLOBALS._v56605[3 + i] == 23)
+ ++R2_GLOBALS._v56605[3 + i];
+ else if (R2_GLOBALS._v56605[3 + i] == 27)
+ --R2_GLOBALS._v56605[3 + i];
+ break;
+ default:
+ break;
+ }
+ switch (R2_GLOBALS._v56605[3 + i] - 1) {
+ case 0:
+ case 6:
+ case 13:
+ case 18:
+ case 22:
+ case 27:
+ case 30:
+ _objList1[i].setPosition(Common::Point(265, 127));
+ break;
+ case 5:
+ case 12:
+ case 17:
+ case 21:
+ case 26:
+ _objList1[i].setPosition(Common::Point(55, 127));
+ break;
+ default:
+ _objList1[i].setPosition(Common::Point(160, 127));
+ break;
+ }
+ }
+ _objList1[1].setAction(&_action2);
+ _objList1[3].setAction(&_action5);
+ _objList1[5].setAction(&_action4);
+ _objList1[8].setAction(&_action1);
+
+ initPlayer();
+
+ _item1.setDetails(Rect(0, 0, 320, 200), 2000, 0, -1, 23, 1, NULL);
+}
+
+void Scene2000::remove() {
+ R2_GLOBALS._sound1.fadeOut(NULL);
+ SceneExt::remove();
+}
+
+void Scene2000::signal() {
+ switch (_sceneMode) {
+ case 10:
+ if (R2_GLOBALS._v56605[R2_GLOBALS._player._characterIndex] == 6)
+ g_globals->_sceneManager.changeScene(1900);
+ else {
+ _mazePlayerMode = 1;
+ --R2_GLOBALS._v56605[R2_GLOBALS._player._characterIndex];
+ initExits();
+ initPlayer();
+ }
+ break;
+ case 11:
+ switch (R2_GLOBALS._v56605[R2_GLOBALS._player._characterIndex]) {
+ case 5:
+ g_globals->_sceneManager.changeScene(1900);
+ break;
+ case 30:
+ g_globals->_sceneManager.changeScene(2500);
+ break;
+ case 34:
+ g_globals->_sceneManager.changeScene(2350);
+ break;
+ default:
+ _mazePlayerMode = 2;
+ ++R2_GLOBALS._v56605[R2_GLOBALS._player._characterIndex];
+ initExits();
+ initPlayer();
+ break;
+ }
+ break;
+ case 12:
+ case 13:
+ initExits();
+ initPlayer();
+ break;
+ case 14:
+ switch (_mazePlayerMode - 1) {
+ case 0:
+ g_globals->_sceneManager.changeScene(2450);
+ break;
+ case 1:
+ g_globals->_sceneManager.changeScene(2440);
+ break;
+ case 2:
+ g_globals->_sceneManager.changeScene(2435);
+ break;
+ case 3:
+ g_globals->_sceneManager.changeScene(2430);
+ break;
+ case 4:
+ g_globals->_sceneManager.changeScene(2425);
+ break;
+ case 5:
+ g_globals->_sceneManager.changeScene(2525);
+ break;
+ case 6:
+ g_globals->_sceneManager.changeScene(2530);
+ break;
+ case 7:
+ g_globals->_sceneManager.changeScene(2535);
+ break;
+ default:
+ if (R2_GLOBALS._v56AAB != 0)
+ R2_GLOBALS._v56AAB = 0;
+ R2_GLOBALS._player.enableControl(CURSOR_ARROW);
+ break;
+ }
+ break;
+ case 2039:
+ case 2041:
+ g_globals->_sceneManager.changeScene(2350);
+ break;
+ default:
+ break;
+ }
+}
+
+void Scene2000::process(Event &event) {
+ if ((R2_GLOBALS._player._canWalk) && (event.eventType == EVENT_BUTTON_DOWN) &&
+ (R2_GLOBALS._events.getCursor() == CURSOR_CROSSHAIRS)) {
+
+ Common::Point pt(event.mousePos.x, 129);
+ PlayerMover *mover = new PlayerMover();
+ R2_GLOBALS._player.addMover(mover, &pt, this);
+
+ event.handled = true;
+ }
+ Scene::process(event);
+}
+
+void Scene2000::synchronize(Serializer &s) {
+ SceneExt::synchronize(s);
+
+ s.syncAsByte(_exitingFlag);
+ s.syncAsSint16LE(_mazePlayerMode);
+}
+
+/*--------------------------------------------------------------------------
+ * Scene 2350 - Balloon Launch Platform
+ *
+ *--------------------------------------------------------------------------*/
+bool Scene2350::Actor2::startAction(CursorType action, Event &event) {
+ if (action != R2_SENSOR_PROBE)
+ return(SceneActor::startAction(action, event));
+ return true;
+}
+
+bool Scene2350::Actor3::startAction(CursorType action, Event &event) {
+ Scene2350 *scene = (Scene2350 *)R2_GLOBALS._sceneManager._scene;
+
+ if ((action == R2_REBREATHER_TANK) && (R2_GLOBALS.getFlag(74))) {
+ R2_GLOBALS._player.disableControl();
+ scene->_actor1.postInit();
+ scene->_sceneMode = 2355;
+ scene->setAction(&scene->_sequenceManager, scene, 2355, &R2_GLOBALS._player, &scene->_actor1, NULL);
+ return true;
+ }
+
+ return(SceneActor::startAction(action, event));
+}
+
+void Scene2350::ExitUp::changeScene() {
+ Scene2350 *scene = (Scene2350 *)R2_GLOBALS._sceneManager._scene;
+
+ R2_GLOBALS._player.disableControl(CURSOR_CROSSHAIRS);
+ scene->_sceneMode = 12;
+ if (R2_GLOBALS._player._characterIndex == 1)
+ scene->setAction(&scene->_sequenceManager, scene, 2350, &R2_GLOBALS._player, NULL);
+ else
+ scene->setAction(&scene->_sequenceManager, scene, 2352, &R2_GLOBALS._player, NULL);
+}
+
+void Scene2350::ExitWest::changeScene() {
+ Scene2350 *scene = (Scene2350 *)R2_GLOBALS._sceneManager._scene;
+
+ R2_GLOBALS._player.disableControl(CURSOR_CROSSHAIRS);
+ scene->_sceneMode = 11;
+
+ Common::Point pt(-10, 129);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, scene);
+
+}
+
+void Scene2350::postInit(SceneObjectList *OwnerList) {
+ loadScene(2350);
+ SceneExt::postInit();
+ R2_GLOBALS._sound1.play(200);
+ _stripManager.addSpeaker(&_pharishaSpeaker);
+ _stripManager.addSpeaker(&_quinnSpeaker);
+
+ if (R2_GLOBALS._sceneManager._previousScene == -1)
+ R2_GLOBALS._player._characterScene[2] = 2350;
+
+ _exitUp.setDetails(Rect(25, 83, 93, 125), EXITCURSOR_NW, 2350);
+ _exitUp.setDest(Common::Point(80, 129));
+ _exitWest.setDetails(Rect(0, 100, 14, 140), EXITCURSOR_W, 2350);
+ _exitWest.setDest(Common::Point(14, 129));
+
+ R2_GLOBALS._player.postInit();
+ R2_GLOBALS._player.animate(ANIM_MODE_1, NULL);
+
+ if (R2_GLOBALS._player._characterIndex == 1) {
+ R2_GLOBALS._player.setup(2008, 3, 1);
+ R2_GLOBALS._player._moveDiff = Common::Point(3, 2);
+ } else {
+ R2_GLOBALS._player.setup(20, 3, 1);
+ R2_GLOBALS._player._moveDiff = Common::Point(5, 3);
+ }
+
+ if (R2_GLOBALS._player._characterScene[1] == R2_GLOBALS._player._characterScene[2]) {
+ _actor2.postInit();
+ if (R2_GLOBALS._player._characterIndex == 1) {
+ _actor2.setup(20, 5, 1);
+ _actor2.setDetails(9002, 0, 4, 3, 1, (SceneItem *)NULL);
+ } else {
+ _actor2.setup(2008, 5, 1);
+ _actor2.setDetails(9001, 0, 5, 3, 1, (SceneItem *)NULL);
+ }
+ _actor2.setPosition(Common::Point(135, 128));
+ }
+ _actor3.postInit();
+ _actor4.postInit();
+
+ if (R2_INVENTORY.getObjectScene(20) == 2350) {
+ _actor3.hide();
+ _actor4.hide();
+ } else {
+ _actor3.setup(2350, 0, 1);
+ _actor3.setPosition(Common::Point(197, 101));
+ _actor3.setDetails(2000, 12, -1, -1, 1, (SceneItem *)NULL);
+ _actor3.fixPriority(10);
+ _actor4.setup(2350, 1, 2);
+ _actor4.setPosition(Common::Point(199, 129));
+ _actor4.setDetails(2000, 12, -1, -1, 1, (SceneItem *)NULL);
+ _actor4.fixPriority(10);
+ }
+ _item1.setDetails(Rect(0, 0, 320, 200), 2000, 9, -1, -1, 1, NULL);
+ R2_GLOBALS._player.disableControl();
+
+ if (R2_GLOBALS._player._oldCharacterScene[R2_GLOBALS._player._characterIndex] == 2000) {
+ if (R2_GLOBALS._v56605[R2_GLOBALS._player._characterIndex] == 34) {
+ if (R2_GLOBALS._player._characterIndex == 1)
+ _sceneMode = 2351;
+ else
+ _sceneMode = 2353;
+ setAction(&_sequenceManager, this, _sceneMode, &R2_GLOBALS._player, NULL);
+ } else {
+ _sceneMode = 10;
+ R2_GLOBALS._player.setPosition(Common::Point(-20, 129));
+ Common::Point pt(20, 129);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, this);
+
+ }
+ } else {
+ R2_GLOBALS._player.setPosition(Common::Point(100, 129));
+ R2_GLOBALS._player.setStrip(3);
+ R2_GLOBALS._player.enableControl();
+ }
+ R2_GLOBALS._player._oldCharacterScene[R2_GLOBALS._player._characterIndex] = 2350;
+}
+
+void Scene2350::remove() {
+ R2_GLOBALS._sound1.fadeOut(NULL);
+ SceneExt::remove();
+}
+
+void Scene2350::signal() {
+ switch (_sceneMode) {
+ case 11:
+ R2_GLOBALS._v56605[R2_GLOBALS._player._characterIndex] = 34;
+ g_globals->_sceneManager.changeScene(2000);
+ break;
+ case 12:
+ R2_GLOBALS._v56605[R2_GLOBALS._player._characterIndex] = 29;
+ g_globals->_sceneManager.changeScene(2000);
+ break;
+ case 20:
+ _sceneMode = 21;
+ _stripManager.start(712, this);
+ break;
+ case 21:
+ R2_GLOBALS._player.disableControl();
+ R2_INVENTORY.setObjectScene(36, 1);
+ _sceneMode = 2354;
+ setAction(&_sequenceManager, this, 2354, &R2_GLOBALS._player, NULL);
+ break;
+ case 2354:
+ R2_INVENTORY.setObjectScene(20, 2350);
+ g_globals->_sceneManager.changeScene(2900);
+ break;
+ case 2355:
+ _sceneMode = 20;
+ R2_GLOBALS._events.setCursor(CURSOR_ARROW);
+ _stripManager.start(711, this);
+ break;
+ default:
+ R2_GLOBALS._player.enableControl();
+ break;
+ }
+}
+
+void Scene2350::process(Event &event) {
+ if ((R2_GLOBALS._player._canWalk) && (event.eventType != EVENT_BUTTON_DOWN) &&
+ (R2_GLOBALS._events.getCursor() == CURSOR_CROSSHAIRS)){
+ Common::Point pt(event.mousePos.x, 129);
+ PlayerMover *mover = new PlayerMover();
+ R2_GLOBALS._player.addMover(mover, &pt);
+ event.handled = true;
+ }
+ Scene::process(event);
+}
+
+/*--------------------------------------------------------------------------
+ * Scene 2400 - Ice Maze: Large empty room
+ *
+ *--------------------------------------------------------------------------*/
+void Scene2400::Exit1::changeScene() {
+ Scene2400 *scene = (Scene2400 *)R2_GLOBALS._sceneManager._scene;
+
+ R2_GLOBALS._player.disableControl();
+ scene->_sceneMode = 10;
+
+ Common::Point pt(-10, 150);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, scene);
+
+}
+
+void Scene2400::Exit2::changeScene() {
+ Scene2400 *scene = (Scene2400 *)R2_GLOBALS._sceneManager._scene;
+
+ R2_GLOBALS._player.disableControl();
+ scene->_sceneMode = 11;
+
+ Common::Point pt(330, 150);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, scene);
+}
+
+void Scene2400::postInit(SceneObjectList *OwnerList) {
+ loadScene(2400);
+ SceneExt::postInit();
+ _exit1.setDetails(Rect(0, 125, 14, 165), EXITCURSOR_W, 2000);
+ _exit1.setDest(Common::Point(14, 150));
+ _exit2.setDetails(Rect(305, 125, 320, 165), EXITCURSOR_E, 2000);
+ _exit2.setDest(Common::Point(315, 150));
+ R2_GLOBALS._player.postInit();
+ R2_GLOBALS._player.disableControl();
+
+ if (R2_GLOBALS._v56605[1] == 16) {
+ _sceneMode = 2400;
+ setAction(&_sequenceManager, this, 2400, &R2_GLOBALS._player, NULL);
+ } else {
+ _sceneMode = 2401;
+ setAction(&_sequenceManager, this, 2401, &R2_GLOBALS._player, NULL);
+ }
+}
+
+void Scene2400::signal() {
+ switch (_sceneMode) {
+ case 10:
+ R2_GLOBALS._v56605[1] = 16;
+ g_globals->_sceneManager.changeScene(2000);
+ break;
+ case 11:
+ R2_GLOBALS._v56605[1] = 17;
+ g_globals->_sceneManager.changeScene(2000);
+ break;
+ default:
+ R2_GLOBALS._player.enableControl();
+ break;
+ }
+}
+
+/*--------------------------------------------------------------------------
+ * Scene 2425 - Ice Maze:
+ *
+ *--------------------------------------------------------------------------*/
+
+bool Scene2425::Item1::startAction(CursorType action, Event &event) {
+ Scene2425 *scene = (Scene2425 *)R2_GLOBALS._sceneManager._scene;
+
+ if ((action == R2_GUNPOWDER) && (!R2_GLOBALS.getFlag(84))) {
+ R2_GLOBALS._player.disableControl();
+ scene->_sceneMode = 2426;
+ scene->setAction(&scene->_sequenceManager, scene, 2426, &R2_GLOBALS._player, &scene->_actor1, NULL);
+ R2_GLOBALS.setFlag(84);
+ return true;
+ } else if (action == R2_GUNPOWDER) {
+ R2_GLOBALS._events.setCursor(R2_STEPPING_DISKS);
+ R2_GLOBALS._player.enableControl(R2_STEPPING_DISKS);
+ return NamedHotspot::startAction(R2_STEPPING_DISKS, event);
+ } else
+ return NamedHotspot::startAction(action, event);
+}
+
+bool Scene2425::Item2::startAction(CursorType action, Event &event) {
+ Scene2425 *scene = (Scene2425 *)R2_GLOBALS._sceneManager._scene;
+
+ if ((action == R2_GUNPOWDER) && (R2_GLOBALS.getFlag(84))) {
+ R2_GLOBALS._player.disableControl();
+ scene->_sceneMode = 2427;
+ scene->setAction(&scene->_sequenceManager, scene, 2427, &R2_GLOBALS._player, &scene->_actor1, NULL);
+ R2_GLOBALS.clearFlag(84);
+ return true;
+ } else if (action == R2_GUNPOWDER) {
+ R2_GLOBALS._events.setCursor(R2_STEPPING_DISKS);
+ R2_GLOBALS._player.enableControl(R2_STEPPING_DISKS);
+ return NamedHotspot::startAction(R2_STEPPING_DISKS, event);
+ } else
+ return NamedHotspot::startAction(action, event);
+}
+
+bool Scene2425::Item3::startAction(CursorType action, Event &event) {
+ Scene2425 *scene = (Scene2425 *)R2_GLOBALS._sceneManager._scene;
+
+ if (action != R2_GUNPOWDER)
+ return NamedHotspot::startAction(action, event);
+ else {
+ R2_GLOBALS._player.disableControl();
+ if (R2_GLOBALS.getFlag(84)) {
+ scene->_sceneMode = 20;
+ scene->setAction(&scene->_sequenceManager, scene, 2427, &R2_GLOBALS._player, &scene->_actor1, NULL);
+ R2_GLOBALS.clearFlag(84);
+ } else {
+ scene->_sceneMode = 2425;
+ scene->setAction(&scene->_sequenceManager, scene, 2425, &R2_GLOBALS._player, &scene->_actor1, NULL);
+ }
+ return true;
+ }
+}
+
+bool Scene2425::Item4::startAction(CursorType action, Event &event) {
+ if (action != R2_GUNPOWDER)
+ return NamedHotspot::startAction(action, event);
+ else {
+ R2_GLOBALS._events.setCursor(R2_STEPPING_DISKS);
+ R2_GLOBALS._player.enableControl(R2_STEPPING_DISKS);
+ return NamedHotspot::startAction(R2_STEPPING_DISKS, event);
+ }
+}
+
+bool Scene2425::Actor1::startAction(CursorType action, Event &event) {
+ if (action == R2_STEPPING_DISKS) {
+ if (R2_GLOBALS._player._characterIndex == 2) {
+ R2_GLOBALS._events.setCursor(R2_GUNPOWDER);
+ return true;
+ } else {
+ return SceneActor::startAction(action, event);
+ }
+ } else if (R2_GLOBALS._events.getCursor() == R2_GUNPOWDER)
+ return false;
+ else
+ return SceneActor::startAction(action, event);
+}
+
+bool Scene2425::Actor2::startAction(CursorType action, Event &event) {
+ if (action != R2_GUNPOWDER)
+ return SceneActor::startAction(action, event);
+ else {
+ R2_GLOBALS._events.setCursor(R2_STEPPING_DISKS);
+ R2_GLOBALS._player.enableControl(R2_STEPPING_DISKS);
+ return SceneActor::startAction(R2_STEPPING_DISKS, event);
+ }
+}
+
+void Scene2425::Exit1::changeScene() {
+ Scene2425 *scene = (Scene2425 *)R2_GLOBALS._sceneManager._scene;
+
+ _enabled = false;
+ R2_GLOBALS._events.setCursor(R2_NEGATOR_GUN);
+ R2_GLOBALS._player.disableControl();
+ scene->_sceneMode = 11;
+
+ Common::Point pt(340, 200);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, scene);
+}
+
+
+void Scene2425::postInit(SceneObjectList *OwnerList) {
+ loadScene(2425);
+ SceneExt::postInit();
+ if (R2_GLOBALS._sceneManager._previousScene == -1) {
+ R2_GLOBALS._player._characterIndex = R2_SEEKER;
+ R2_GLOBALS._sceneManager._previousScene = 2000;
+ }
+
+ R2_GLOBALS._sound1.play(200);
+ _exit1.setDetails(Rect(270, 136, 319, 168), EXITCURSOR_SE, 2000);
+ R2_GLOBALS._player.postInit();
+ R2_GLOBALS._player.animate(ANIM_MODE_1, NULL);
+
+ if (R2_GLOBALS._player._characterIndex == 1) {
+ R2_GLOBALS._player.setVisage(2008);
+ R2_GLOBALS._player._moveDiff = Common::Point(3, 2);
+ } else {
+ R2_GLOBALS._player.setVisage(20);
+ R2_GLOBALS._player._moveDiff = Common::Point(5, 3);
+ }
+
+ if (R2_GLOBALS._player._characterScene[1] == R2_GLOBALS._player._characterScene[2]) {
+ _actor2.postInit();
+ if (R2_GLOBALS._player._characterIndex == 1) {
+ _actor2.setup(20, 5, 1);
+ _actor2.setDetails(9002, 0, 4, 3, 1, (SceneItem *)NULL);
+ } else {
+ _actor2.setup(2008, 5, 1);
+ _actor2.setDetails(9001, 0, 5, 3, 1, (SceneItem *)NULL);
+ }
+ _actor2.setPosition(Common::Point(250, 185));
+ }
+
+ _actor1.postInit();
+ if (R2_GLOBALS._sceneManager._previousScene == 2455)
+ _actor1.setup(2426, 1, 1);
+ else
+ _actor1.setup(2426, 1, 2);
+
+ _actor1.setPosition(Common::Point(290, 9));
+ _actor1.fixPriority(20);
+ _actor1.setDetails(2455, 12, -1, -1, 1, (SceneItem *)NULL);
+ _item1.setDetails(Rect(225, 52, 248, 65), 2425, -1, -1, -1, 1, NULL);
+ _item2.setDetails(Rect(292, 81, 316, 94), 2425, -1, -1, -1, 1, NULL);
+
+// CHECKME: SceneActor using a SceneItem function??
+// _actor3.setDetails(11, 2425, 3, -1, 6);
+ _actor3._sceneRegionId = 11;
+ _actor3._resNum = 2425;
+ _actor3._lookLineNum = 3;
+ _actor3._talkLineNum = -1;
+ _actor3._useLineNum = 6;
+ g_globals->_sceneItems.push_back(&_actor3);
+
+ _item3.setDetails(12, 2425, 7, -1, 9);
+ _item4.setDetails(Rect(0, 0, 320, 200), 2425, 0, -1, -1, 1, NULL);
+
+ R2_GLOBALS._player.disableControl();
+ switch (R2_GLOBALS._player._oldCharacterScene[R2_GLOBALS._player._characterIndex]) {
+ case 2000: {
+ _sceneMode = 10;
+ R2_GLOBALS._player.setPosition(Common::Point(340, 200));
+
+ Common::Point pt(280, 150);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, this);
+ break;
+ }
+ case 2425:
+ _sceneMode = 10;
+ R2_GLOBALS._player.setPosition(Common::Point(280, 150));
+ _action->signal();
+ break;
+ case 2455:
+ _sceneMode = 2428;
+ setAction(&_sequenceManager, this, 2428, &R2_GLOBALS._player, &_actor1, NULL);
+ break;
+ default:
+ R2_GLOBALS._player.setPosition(Common::Point(280, 150));
+ R2_GLOBALS._player.setStrip(8);
+ R2_GLOBALS._player.enableControl();
+ break;
+ }
+ R2_GLOBALS._player._oldCharacterScene[R2_GLOBALS._player._characterIndex] = 2425;
+}
+
+void Scene2425::remove() {
+ R2_GLOBALS._sound1.fadeOut(NULL);
+ SceneExt::remove();
+}
+
+void Scene2425::signal() {
+ switch (_sceneMode) {
+ case 11:
+ g_globals->_sceneManager.changeScene(2000);
+ break;
+ case 20:
+ _sceneMode = 2425;
+ setAction(&_sequenceManager, this, 2425, &R2_GLOBALS._player, &_actor1, NULL);
+ break;
+ case 2425:
+ g_globals->_sceneManager.changeScene(2455);
+ break;
+ default:
+ R2_GLOBALS._player.enableControl();
+ break;
+ }
+}
+
+/*--------------------------------------------------------------------------
+ * Scene 2430 - Ice Maze: Bedroom
+ *
+ *--------------------------------------------------------------------------*/
+
+bool Scene2430::Actor1::startAction(CursorType action, Event &event) {
+ return SceneActor::startAction(action, event);
+}
+
+bool Scene2430::Actor2::startAction(CursorType action, Event &event) {
+ Scene2430 *scene = (Scene2430 *)R2_GLOBALS._sceneManager._scene;
+
+ if ((action != R2_STEPPING_DISKS) || (R2_GLOBALS._player._characterIndex != 2))
+ return SceneActor::startAction(action, event);
+
+ R2_GLOBALS._player.disableControl();
+ scene->_sceneMode = 2430;
+ scene->setAction(&scene->_sequenceManager, scene, 2430, &R2_GLOBALS._player, &scene->_actor2, NULL);
+ return true;
+}
+
+bool Scene2430::Actor3::startAction(CursorType action, Event &event) {
+ Scene2430 *scene = (Scene2430 *)R2_GLOBALS._sceneManager._scene;
+
+ if ((action != R2_STEPPING_DISKS) || (R2_GLOBALS._player._characterIndex != 2))
+ return SceneActor::startAction(action, event);
+
+ R2_GLOBALS._player.disableControl();
+ scene->_sceneMode = 2435;
+ scene->setAction(&scene->_sequenceManager, scene, 2435, &R2_GLOBALS._player, &scene->_actor3, NULL);
+ return true;
+}
+
+void Scene2430::Exit1::changeScene() {
+ Scene2430 *scene = (Scene2430 *)R2_GLOBALS._sceneManager._scene;
+
+ scene->_sceneMode = 0;
+ R2_GLOBALS._events.setCursor(R2_NEGATOR_GUN);
+ R2_GLOBALS._player.disableControl();
+ scene->_sceneMode = 11;
+ Common::Point pt(108, 200);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, scene);
+}
+
+void Scene2430::postInit(SceneObjectList *OwnerList) {
+ loadScene(2430);
+ SceneExt::postInit();
+ _exit1.setDetails(Rect(68, 155, 147, 168), EXITCURSOR_S, 2000);
+ _exit1.setDest(Common::Point(108, 160));
+
+ if (R2_INVENTORY.getObjectScene(37) == 2430) {
+ _actor2.postInit();
+ _actor2.setup(2435, 1, 5);
+ _actor2.setPosition(Common::Point(205, 119));
+ _actor2.fixPriority(152);
+ _actor2.setDetails(2430, 51, -1, 53, 1, (SceneItem *)NULL);
+ }
+
+ if (R2_INVENTORY.getObjectScene(50) == 2435) {
+ _actor3.postInit();
+ _actor3.setup(2435, 1, 1);
+ _actor3.setPosition(Common::Point(31, 65));
+ _actor3.setDetails(2430, 48, -1, -1, 1, (SceneItem *)NULL);
+ }
+
+ R2_GLOBALS._player.postInit();
+ R2_GLOBALS._player.animate(ANIM_MODE_1, NULL);
+ if (R2_GLOBALS._player._characterIndex == 1) {
+ R2_GLOBALS._player.setVisage(2008);
+ R2_GLOBALS._player._moveDiff = Common::Point(3, 2);
+ } else {
+ R2_GLOBALS._player.setVisage(20);
+ R2_GLOBALS._player._moveDiff = Common::Point(5, 3);
+ }
+ R2_GLOBALS._player.setPosition(Common::Point(100, 200));
+
+ if (R2_GLOBALS._player._characterScene[1] == R2_GLOBALS._player._characterScene[2]) {
+ _actor1.postInit();
+ if (R2_GLOBALS._player._characterIndex == 1) {
+ _actor1.setup(20, 5, 1);
+ _actor1.setDetails(9002, 0, 4, 3, 1, (SceneItem *)NULL);
+ } else {
+ _actor1.setup(2008, 5, 1);
+ _actor1.setDetails(9001, 0, 5, 3, 1, (SceneItem *)NULL);
+ }
+ _actor1.setPosition(Common::Point(189, 137));
+ R2_GLOBALS._walkRegions.enableRegion(4);
+ }
+
+ _item2.setDetails(Rect(11, 30, 37, 45), 2430, 3, -1, 5, 1, NULL);
+ _item3.setDetails(Rect(9, 58, 63, 92), 2430, 6, -1, -1, 1, NULL);
+ _item4.setDetails(Rect(20, 89, 127, 107), 2430, 9, -1, 11, 1, NULL);
+ _item5.setDetails(Rect(49, 7, 60, 27), 2430, 12, 13, 14, 1, NULL);
+ _item6.setDetails(Rect(69, 10, 95, 72), 2430, 15, -1, 14, 1, NULL);
+ _item10.setDetails(Rect(198, 4, 222, 146), 2430, 30, 31, 32, 1, NULL);
+ _item7.setDetails(Rect(155, 40, 304, 120), 2430, 21, -1, 23, 1, NULL);
+ _item8.setDetails(Rect(249, 3, 261, 39), 2430, 24, 25, -1, 1, NULL);
+ _item9.setDetails(Rect(279, 13, 305, 34), 2430, 33, -1, 18, 1, NULL);
+ // CHECKME: initialized for the 2nd time??
+ _item2.setDetails(Rect(11, 30, 37, 45), 2430, 33, -1, 18, 1, NULL);
+ _item11.setDetails(Rect(116, 104, 148, 111), 2430, 39, -1, -1, 1, NULL);
+ _item12.setDetails(Rect(66, 77, 84, 83), 2430, 39, -1, -1, 1, NULL);
+ _item13.setDetails(Rect(117, 118, 201, 141), 2430, 9, -1, 11, 1, NULL);
+ _item1.setDetails(Rect(0, 0, 320, 200), 2430, 0, -1, -1, 1, NULL);
+
+ if (R2_GLOBALS._player._oldCharacterScene[R2_GLOBALS._player._characterIndex] == 2000) {
+ R2_GLOBALS._player._oldCharacterScene[R2_GLOBALS._player._characterIndex] = 2430;
+ Common::Point pt(108, 150);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, this);
+ } else {
+ R2_GLOBALS._player.setPosition(Common::Point(105, 145));
+ R2_GLOBALS._player.setStrip(3);
+ R2_GLOBALS._player.enableControl();
+ }
+}
+
+void Scene2430::signal() {
+ switch (_sceneMode) {
+ case 11:
+ g_globals->_sceneManager.changeScene(2000);
+ break;
+ case 2430:
+ _actor2.remove();
+ R2_INVENTORY.setObjectScene(R2_GUNPOWDER, 2);
+ R2_GLOBALS._player.enableControl();
+ break;
+ case 2435:
+ _actor3.remove();
+ R2_INVENTORY.setObjectScene(R2_ALCOHOL_LAMP_3, 2);
+ R2_GLOBALS._player.enableControl();
+ break;
+ default:
+ R2_GLOBALS._player.enableControl();
+ break;
+ }
+}
+
+/*--------------------------------------------------------------------------
+ * Scene 2435 - Ice Maze: Throne room
+ *
+ *--------------------------------------------------------------------------*/
+bool Scene2435::Actor1::startAction(CursorType action, Event &event) {
+ return SceneActor::startAction(action, event);
+}
+
+bool Scene2435::Actor2::startAction(CursorType action, Event &event) {
+ Scene2435 *scene = (Scene2435 *)R2_GLOBALS._sceneManager._scene;
+
+ switch (action) {
+ case R2_SAPPHIRE_BLUE:
+ R2_GLOBALS._player.disableControl();
+ R2_GLOBALS._events.setCursor(CURSOR_ARROW);
+ R2_GLOBALS.setFlag(82);
+ scene->_stripManager.start(603, scene);
+ return true;
+ case R2_ANCIENT_SCROLLS:
+ R2_GLOBALS._player.disableControl();
+ R2_GLOBALS._events.setCursor(CURSOR_ARROW);
+ R2_GLOBALS.setFlag(82);
+ scene->_stripManager.start(602, scene);
+ R2_INVENTORY.setObjectScene(R2_ANCIENT_SCROLLS, 2000);
+ return true;
+ case CURSOR_TALK:
+ R2_GLOBALS._player.disableControl();
+ scene->_sceneMode = 20;
+ R2_GLOBALS._events.setCursor(CURSOR_ARROW);
+ if ((R2_GLOBALS._player._characterIndex == 1) || (R2_GLOBALS.getFlag(82))) {
+ scene->_stripManager.start(605, scene);
+ return true;
+ } else if (R2_INVENTORY.getObjectScene(R2_ANCIENT_SCROLLS) == 2) {
+ scene->_stripManager.start(601, scene);
+ return true;
+ } else {
+ R2_GLOBALS.setFlag(82);
+ scene->_stripManager.start(600, scene);
+ return true;
+ }
+ default:
+ return SceneActor::startAction(action, event);
+ }
+}
+
+void Scene2435::Exit1::changeScene() {
+ Scene2435 *scene = (Scene2435 *)R2_GLOBALS._sceneManager._scene;
+
+ _enabled = false;
+ R2_GLOBALS._events.setCursor(R2_NEGATOR_GUN);
+ R2_GLOBALS._player.disableControl();
+ scene->_sceneMode = 11;
+ Common::Point pt(175, 200);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, scene);
+
+}
+
+void Scene2435::postInit(SceneObjectList *OwnerList) {
+ loadScene(2435);
+ SceneExt::postInit();
+ R2_GLOBALS._sound1.play(201);
+ _stripManager.addSpeaker(&_quinnSpeaker);
+ _stripManager.addSpeaker(&_seekerSpeaker);
+ _stripManager.addSpeaker(&_pharishaSpeaker);
+ _exit1.setDetails(Rect(142, 155, 207, 167), EXITCURSOR_S, 2000);
+ _exit1.setDest(Common::Point(175, 160));
+ _actor2.postInit();
+ _actor2.setup(2005, 3, 1);
+ _actor2.setPosition(Common::Point(219, 106));
+ _actor2.setDetails(2001, 25, 26, -1, 1, (SceneItem *)NULL);
+ R2_GLOBALS._player.postInit();
+ R2_GLOBALS._player.animate(ANIM_MODE_1, NULL);
+ if (R2_GLOBALS._player._characterIndex == 1) {
+ R2_GLOBALS._player.setVisage(2008);
+ R2_GLOBALS._player._moveDiff = Common::Point(3, 2);
+ } else {
+ R2_GLOBALS._player.setVisage(20);
+ R2_GLOBALS._player._moveDiff = Common::Point(5, 3);
+ }
+ R2_GLOBALS._player.setPosition(Common::Point(715, 200));
+ if (R2_GLOBALS._player._characterScene[1] == R2_GLOBALS._player._characterScene[2]) {
+ _actor1.postInit();
+ if (R2_GLOBALS._player._characterIndex == 1) {
+ _actor1.setup(20, 5, 1);
+ _actor1.setDetails(9002, 0, 4, 3, 1, (SceneItem *)NULL);
+ } else {
+ _actor1.setup(2008, 5, 1);
+ _actor1.setDetails(9001, 0, 5, 3, 1, (SceneItem *)NULL);
+ }
+ _actor1.setPosition(Common::Point(107, 145));
+ R2_GLOBALS._walkRegions.enableRegion(2);
+ }
+
+ _item2.setDetails(Rect(52, 44, 96, 82), 2430, 3, -1, 5, 1, NULL);
+ _item3.setDetails(Rect(117, 36, 161, 74), 2430, 3, -1, 5, 1, NULL);
+ _item1.setDetails(Rect(0, 0, 320, 200), 2430, 0, -1, -1, 1, NULL);
+ R2_GLOBALS._player.disableControl();
+ if (R2_GLOBALS._player._oldCharacterScene[R2_GLOBALS._player._characterIndex] == 2000) {
+ _sceneMode = 10;
+ Common::Point pt(175, 150);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, this);
+ } else if (R2_GLOBALS._player._oldCharacterScene[R2_GLOBALS._player._characterIndex] == 2450) {
+ _sceneMode = 30;
+ Common::Point pt(175, 150);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, this);
+ } else {
+ R2_GLOBALS._player.setPosition(Common::Point(210, 150));
+ R2_GLOBALS._player.setStrip(3);
+ R2_GLOBALS._player.enableControl();
+ }
+ R2_GLOBALS._player._oldCharacterScene[R2_GLOBALS._player._characterIndex] = 2435;
+ R2_GLOBALS._v56605[1 + R2_GLOBALS._player._characterIndex] = 12;
+}
+
+void Scene2435::remove() {
+ R2_GLOBALS._sound1.fadeOut2(NULL);
+ SceneExt::remove();
+}
+
+void Scene2435::signal() {
+ switch (_sceneMode) {
+ case 11:
+ g_globals->_sceneManager.changeScene(2000);
+ break;
+ case 20:
+ R2_GLOBALS._player.enableControl(CURSOR_TALK);
+ break;
+ case 30:
+ R2_GLOBALS._player._characterScene[1] = 2435;
+ R2_GLOBALS._player._characterScene[2] = 2435;
+ R2_GLOBALS._player._oldCharacterScene[1] = 2435;
+ R2_GLOBALS._player._oldCharacterScene[2] = 2435;
+ R2_GLOBALS._v56605[1] = 12;
+ R2_GLOBALS._v56605[2] = 12;
+ R2_GLOBALS.setFlag(81);
+ _sceneMode = 2436;
+ R2_GLOBALS._player.setStrip(7);
+ _actor1.postInit();
+ if (R2_GLOBALS._player._characterIndex == 1)
+ _actor1.setVisage(20);
+ else
+ _actor1.setVisage(2008);
+ setAction(&_sequenceManager, this, 2436, &_actor1, NULL);
+ break;
+ case 2436:
+ R2_GLOBALS._walkRegions.enableRegion(2);
+ _sceneMode = 20;
+ R2_GLOBALS._events.setCursor(CURSOR_ARROW);
+ _stripManager.start(709, this);
+ default:
+ R2_GLOBALS._player.enableControl();
+ break;
+ }
+}
+
+/*--------------------------------------------------------------------------
+ * Scene 2440 - Ice Maze: Another bedroom
+ *
+ *--------------------------------------------------------------------------*/
+
+bool Scene2440::Actor1::startAction(CursorType action, Event &event) {
+ return SceneActor::startAction(action, event);
+}
+
+bool Scene2440::Actor2::startAction(CursorType action, Event &event) {
+ Scene2440 *scene = (Scene2440 *)R2_GLOBALS._sceneManager._scene;
+
+ if ((action == CURSOR_USE) && (R2_GLOBALS._player._characterIndex == 2)){
+ R2_GLOBALS._player.disableControl();
+ scene->_sceneMode = 2440;
+ scene->setAction(&scene->_sequenceManager, scene, 2440, &R2_GLOBALS._player, &scene->_actor2, NULL);
+ return true;
+ }
+
+ return SceneActor::startAction(action, event);
+}
+
+void Scene2440::Exit1::changeScene() {
+ Scene2440 *scene = (Scene2440 *)R2_GLOBALS._sceneManager._scene;
+
+ _enabled = false;
+ R2_GLOBALS._player.disableControl();
+ scene->_sceneMode = 11;
+ Common::Point pt(210, 200);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, scene);
+}
+
+void Scene2440::postInit(SceneObjectList *OwnerList) {
+ loadScene(2440);
+ SceneExt::postInit();
+ R2_GLOBALS._sound1.play(200);
+ // Fix exit cursor, the original was using NW
+ _exit1.setDetails(Rect(172, 155, 250, 167), EXITCURSOR_SE, 2000);
+ _exit1.setDest(Common::Point(210, 160));
+ if (R2_INVENTORY.getObjectScene(49) == 2440) {
+ _actor2.postInit();
+ _actor2.setup(2435, 1, 1);
+ _actor2.setPosition(Common::Point(94, 80));
+ _actor2.fixPriority(106);
+ _actor2.setDetails(2430, 48, -1, -1, 1, (SceneItem *)NULL);
+ }
+ R2_GLOBALS._player.postInit();
+ R2_GLOBALS._player.enableControl();
+ R2_GLOBALS._player.animate(ANIM_MODE_1, NULL);
+
+ if (R2_GLOBALS._player._characterIndex == 1) {
+ R2_GLOBALS._player.setVisage(2008);
+ R2_GLOBALS._player._moveDiff = Common::Point(3, 2);
+ } else {
+ R2_GLOBALS._player.setVisage(20);
+ R2_GLOBALS._player._moveDiff = Common::Point(5, 3);
+ }
+ R2_GLOBALS._player.setPosition(Common::Point(210, 200));
+ if (R2_GLOBALS._player._characterScene[1] == R2_GLOBALS._player._characterScene[2]) {
+ _actor1.postInit();
+ if (R2_GLOBALS._player._characterIndex == 1) {
+ _actor1.setup(20, 5, 1);
+ _actor1.setDetails(9002, 0, 4, 3, 1, (SceneItem *)NULL);
+ } else {
+ _actor1.setup(2008, 5, 1);
+ _actor1.setDetails(9002, 0, 5, 3, 1, (SceneItem *)NULL);
+ }
+ _actor1.setPosition(Common::Point(38, 119));
+ }
+
+ _item2.setDetails(Rect(125, 25, 142, 73), 2430, 15, -1, 14, 1, NULL);
+ _item3.setDetails(Rect(124, 78, 237, 120), 2430, 36, -1, 38, 1, NULL);
+ _item4.setDetails(Rect(250, 3, 265, 133), 2430, 30, 31, 32, 1, NULL);
+ _item5.setDetails(Rect(91, 117, 203, 140), 2430, 9, -1, 11, 1, NULL);
+ _item6.setDetails(Rect(48, 78, 103, 112), 2430, 6, -1, -1, 1, NULL);
+ _item7.setDetails(Rect(48, 31, 73, 52), 2430, 33, -1, 18, 1, NULL);
+ _item1.setDetails(Rect(0, 0, 320, 200), 2430, 0, -1, -1, 1, NULL);
+
+ R2_GLOBALS._player.disableControl();
+
+ if (R2_GLOBALS._player._oldCharacterScene[R2_GLOBALS._player._characterIndex] == 2000) {
+ R2_GLOBALS._player._oldCharacterScene[R2_GLOBALS._player._characterIndex] = 2440;
+ Common::Point pt(210, 150);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, this);
+ } else {
+ R2_GLOBALS._player.setPosition(Common::Point(210, 150));
+ R2_GLOBALS._player.setStrip(3);
+ R2_GLOBALS._player.enableControl();
+ }
+}
+
+void Scene2440::remove() {
+ R2_GLOBALS._sound1.fadeOut2(NULL);
+ SceneExt::remove();
+}
+
+void Scene2440::signal() {
+ switch (_sceneMode) {
+ case 11:
+ g_globals->_sceneManager.changeScene(2000);
+ break;
+ case 2440:
+ _actor2.remove();
+ R2_INVENTORY.setObjectScene(49, 2);
+ // No break on purpose
+ default:
+ R2_GLOBALS._player.enableControl();
+ break;
+ }
+}
+
+/*--------------------------------------------------------------------------
+ * Scene 2445 - Ice Maze:
+ *
+ *--------------------------------------------------------------------------*/
+void Scene2445::postInit(SceneObjectList *OwnerList) {
+ loadScene(2445);
+ SceneExt::postInit();
+ R2_GLOBALS._player.postInit();
+ R2_GLOBALS._player.animate(ANIM_MODE_1, NULL);
+ R2_GLOBALS._player.setVisage(10);
+ R2_GLOBALS._player.setPosition(Common::Point(160, 140));
+ R2_GLOBALS._player.disableControl();
+}
+
+void Scene2445::signal() {
+ R2_GLOBALS._player.enableControl();
+}
+
+/*--------------------------------------------------------------------------
+ * Scene 2450 - Ice Maze: Another bedroom
+ *
+ *--------------------------------------------------------------------------*/
+
+bool Scene2450::Actor2::startAction(CursorType action, Event &event) {
+ Scene2450 *scene = (Scene2450 *)R2_GLOBALS._sceneManager._scene;
+
+ if ((action == CURSOR_USE) && (R2_GLOBALS._player._characterIndex == 1)) {
+ R2_GLOBALS._player.disableControl();
+ scene->_sceneMode = 2452;
+ scene->setAction(&scene->_sequenceManager, scene, 2452, &R2_GLOBALS._player, &scene->_actor2, NULL);
+ return true;
+ }
+ return SceneActor::startAction(action, event);
+}
+
+bool Scene2450::Actor3::startAction(CursorType action, Event &event) {
+ Scene2450 *scene = (Scene2450 *)R2_GLOBALS._sceneManager._scene;
+
+ if (action == CURSOR_TALK) {
+ R2_GLOBALS._player.disableControl();
+ if (R2_GLOBALS._v565AE < 3) {
+ ++R2_GLOBALS._v565AE;
+ scene->_sceneMode = 20;
+ R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
+ if (R2_GLOBALS._player._characterIndex == 1)
+ scene->_stripManager.start(699 + (R2_GLOBALS._v565AE * 2), scene);
+ else
+ scene->_stripManager.start(700 + (R2_GLOBALS._v565AE * 2), scene);
+ }
+ return true;} else {
+ return SceneActor::startAction(action, event);
+ }
+}
+
+void Scene2450::Exit1::changeScene() {
+ Scene2450 *scene = (Scene2450 *)R2_GLOBALS._sceneManager._scene;
+
+ if ((R2_GLOBALS._player._characterIndex == 2) || (R2_GLOBALS.getFlag(61))) {
+ _enabled = false;
+ R2_GLOBALS._events.setCursor(CURSOR_ARROW);
+ R2_GLOBALS._player.disableControl();
+ scene->_sceneMode = 10;
+ Common::Point pt(-10, 180);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, scene);
+ } else {
+ _moving = false;
+ SceneItem::display(2450, 3, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
+ Common::Point pt(60, 140);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, NULL);
+ }
+}
+
+void Scene2450::postInit(SceneObjectList *OwnerList) {
+ loadScene(2450);
+ SceneExt::postInit();
+ R2_GLOBALS._sound1.play(200);
+ if (R2_GLOBALS._sceneManager._previousScene == -1) {
+ R2_GLOBALS._sceneManager._previousScene = 1900;
+ R2_GLOBALS._player._oldCharacterScene[1] = 1900;
+ R2_GLOBALS._player._oldCharacterScene[2] = 1900;
+ }
+ _stripManager.addSpeaker(&_quinnSpeaker);
+ _stripManager.addSpeaker(&_seekerSpeaker);
+ _stripManager.addSpeaker(&_caretakerSpeaker);
+
+ if (R2_GLOBALS.getFlag(72)) {
+ _exit1.setDetails(Rect(0, 143, 47, 168), EXITCURSOR_SW, 2000);
+ _exit1.setDest(Common::Point(10, 160));
+ }
+
+ if (!R2_GLOBALS.getFlag(61)) {
+ _actor2.postInit();
+ _actor2.setVisage(2009);
+ _actor2.setPosition(Common::Point(190, 119));
+ _actor2.fixPriority(50);
+ _actor2.setDetails(2450, 0, -1, -1, 1, (SceneItem *)NULL);
+ }
+
+ R2_GLOBALS._player.postInit();
+ R2_GLOBALS._player.disableControl();
+ switch (R2_GLOBALS._player._oldCharacterScene[R2_GLOBALS._player._characterIndex]) {
+ case 1900:
+ R2_GLOBALS._v565AE = 0;
+ R2_GLOBALS._player._characterScene[1] = 2450;
+ R2_GLOBALS._player._characterScene[2] = 2450;
+ R2_GLOBALS._player._oldCharacterScene[1] = 2450;
+ R2_GLOBALS._player._oldCharacterScene[2] = 2450;
+ R2_GLOBALS._player.setup(2450, 1, 1);
+ R2_GLOBALS._player.setPosition(Common::Point(126, 101));
+ setAction(&_sequenceManager, this, 2450, &R2_GLOBALS._player, NULL);
+ break;
+ case 2000:
+ _sceneMode = 2451;
+ if (R2_GLOBALS._player._characterIndex == 1) {
+ if (R2_GLOBALS._player._characterScene[2] == 2450) {
+ _actor1.postInit();
+ _actor1.setup(20, 6, 1);
+ _actor1.setPosition(Common::Point(240, 120));
+ _actor1.setDetails(9002, 0, 4, 3, 1, (SceneItem *)NULL);
+ }
+ setAction(&_sequenceManager, this, 2451, &R2_GLOBALS._player, NULL);
+ } else {
+ R2_GLOBALS._player._oldCharacterScene[2] = 2450;
+ R2_GLOBALS._player._characterScene[2] = 2450;
+ if (R2_GLOBALS._player._characterScene[1] == 2450) {
+ _actor1.postInit();
+ if (R2_GLOBALS.getFlag(61))
+ _actor1.setup(2008, 6, 1);
+ else
+ _actor1.setup(10, 6, 1);
+ _actor1.setDetails(9001, 0, 5, 3, 1, (SceneItem *)NULL);
+ _actor1.setPosition(Common::Point(106, 111));
+ }
+ setAction(&_sequenceManager, this, 2456, &R2_GLOBALS._player, NULL);
+ }
+ break;
+ case 2450:
+ if (R2_GLOBALS._player._characterIndex == 1) {
+ R2_GLOBALS._player.postInit();
+ if (R2_GLOBALS.getFlag(61)) {
+ R2_GLOBALS._player.setup(2008, 6, 1);
+ } else {
+ R2_GLOBALS._player.setup(10, 6, 1);
+ }
+ R2_GLOBALS._player.setPosition(Common::Point(106, 111));
+ R2_GLOBALS._player.animate(ANIM_MODE_1, NULL);
+ if (R2_GLOBALS.getFlag(72)) {
+ if (R2_GLOBALS._player._characterScene[2] == 2450) {
+ _actor1.postInit();
+ _actor1.setup(20, 6, 1);
+ _actor1.setPosition(Common::Point(240, 120));
+ _actor1.setDetails(9002, 0, 4, 3, 1, (SceneItem *)NULL);
+ }
+ } else {
+ _actor1.postInit();
+ _actor1.setup(20, 8, 1);
+ _actor1.setPosition(Common::Point(93, 158));
+ _actor1.setDetails(9002, 0, 4, 3, 1, (SceneItem *)NULL);
+
+ _actor3.postInit();
+ _actor3.setup(2001, 7, 1);
+ _actor3.setPosition(Common::Point(34, 153));
+ _actor3.setDetails(2001, 40, -1, -1, 1, (SceneItem *)NULL);
+
+ _exit1._enabled = false;
+ }
+ } else {
+ R2_GLOBALS._player.postInit();
+ R2_GLOBALS._player.setup(20, 8, 1);
+ R2_GLOBALS._player.animate(ANIM_MODE_1, NULL);
+ R2_GLOBALS._player.setPosition(Common::Point(93, 158));
+ if (R2_GLOBALS.getFlag(72)) {
+ if (R2_GLOBALS._player._characterScene[1] == 2450) {
+ _actor1.postInit();
+ if (R2_GLOBALS.getFlag(61)) {
+ _actor1.setup(2008, 6, 1);
+ } else {
+ _actor1.setup(10, 6, 1);
+ }
+ _actor1.setPosition(Common::Point(106, 111));
+ _actor1.setDetails(9001, 0, 5, 3, 1, (SceneItem *)NULL);
+ }
+ } else {
+ _actor1.postInit();
+ if (R2_GLOBALS.getFlag(61)) {
+ _actor1.setup(2008, 6, 1);
+ } else {
+ _actor1.setup(10, 6, 1);
+ }
+ _actor1.setPosition(Common::Point(106, 111));
+ _actor1.setDetails(9001, 0, 5, 3, 1, (SceneItem *)NULL);
+
+ _actor3.postInit();
+ _actor3.setup(2001, 7, 1);
+ _actor3.setPosition(Common::Point(34, 153));
+ _actor3.setDetails(2001, 40, -1, -1, 1, (SceneItem *)NULL);
+
+ _exit1._enabled = false;
+ }
+ }
+ R2_GLOBALS._player.enableControl();
+ if (!R2_GLOBALS.getFlag(72)) {
+ R2_GLOBALS._player._canWalk = false;
+ }
+ break;
+ default:
+ R2_GLOBALS._player.animate(ANIM_MODE_1, NULL);
+ if (R2_GLOBALS._player._characterIndex == 1) {
+ if (R2_GLOBALS.getFlag(61)) {
+ R2_GLOBALS._player.setup(2008, 3, 1);
+ } else {
+ R2_GLOBALS._player.setup(10, 3, 1);
+ }
+ R2_GLOBALS._player._moveDiff = Common::Point(3, 2);
+ } else {
+ R2_GLOBALS._player.setVisage(20);
+ R2_GLOBALS._player._moveDiff = Common::Point(5, 3);
+ }
+ R2_GLOBALS._player.setPosition(Common::Point(100, 130));
+ R2_GLOBALS._player.enableControl();
+ break;
+ }
+ _item2.setDetails(Rect(174, 4, 199, 123), 2430, 30, 31, 32, 1, NULL);
+ _item3.setDetails(Rect(67, 73, 207, 121), 2430, 36, -1, 38, 1, NULL);
+ _item1.setDetails(Rect(0, 0, 320, 200), 2430, 0, -1, -1, 1, NULL);
+}
+
+void Scene2450::remove() {
+ R2_GLOBALS._sound1.fadeOut2(NULL);
+ SceneExt::remove();
+}
+
+void Scene2450::signal() {
+ switch (_sceneMode) {
+ case 10:
+ g_globals->_sceneManager.changeScene(2000);
+ break;
+ case 20:
+ if (R2_GLOBALS._v565AE == 3) {
+ R2_GLOBALS._player.disableControl();
+ R2_GLOBALS._v565AE = 4;
+ _sceneMode = 2454;
+ setAction(&_sequenceManager, this, 2454, &_actor3, NULL);
+ } else {
+ R2_GLOBALS._player.enableControl(CURSOR_TALK);
+ if (R2_GLOBALS._v565AE < 4)
+ R2_GLOBALS._player._canWalk = false;
+ }
+ break;
+ case 30:
+ R2_GLOBALS._player.disableControl();
+ _sceneMode = 2455;
+ setAction(&_sequenceManager, this, 2455, &_actor1, NULL);
+ break;
+ case 31:
+ R2_GLOBALS.setFlag(61);
+ g_globals->_sceneManager.changeScene(2435);
+ break;
+ case 2451:
+ R2_GLOBALS._player.enableControl();
+ break;
+ case 2452:
+ R2_GLOBALS.setFlag(61);
+ _actor2.remove();
+ R2_GLOBALS._player.enableControl();
+ if (!R2_GLOBALS.getFlag(72)) {
+ R2_GLOBALS._player.setStrip(6);
+ R2_GLOBALS._player._canWalk = false;
+ }
+ break;
+ case 2453:
+ _sceneMode = 20;
+ R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
+ _stripManager.start(700, this);
+ break;
+ case 2454:
+ _exit1._enabled = true;
+ R2_GLOBALS.setFlag(72);
+ _actor3.remove();
+ if (R2_GLOBALS.getFlag(61)) {
+ g_globals->_sceneManager.changeScene(2435);
+ } else {
+ _sceneMode = 31;
+ if (R2_GLOBALS._player._characterIndex == 1) {
+ setAction(&_sequenceManager, this, 2452, &R2_GLOBALS._player, NULL);
+ } else {
+ setAction(&_sequenceManager, this, 2452, &_actor1, &_actor2, NULL);
+ }
+ }
+ break;
+ case 2455:
+ R2_GLOBALS._player._oldCharacterScene[2] = 2450;
+ R2_GLOBALS._player._characterScene[2] = 2000;
+ R2_GLOBALS._v56605[2] = 3;
+ _actor1.remove();
+ R2_GLOBALS._player.enableControl(CURSOR_ARROW);
+ break;
+ default:
+ _actor1.postInit();
+ _actor1.setDetails(9002, 0, 4, 3, 2, (SceneItem *)NULL);
+ _actor3.postInit();
+ _actor3.setDetails(2001, 40, -1, -1, 2, (SceneItem *)NULL);
+ _sceneMode = 2453;
+ setAction(&_sequenceManager, this, 2453, &_actor3, &_actor1, NULL);
+ break;
+ }
+}
+
+/*--------------------------------------------------------------------------
+ * Scene 2455 - Ice Maze: Inside crevasse
+ *
+ *--------------------------------------------------------------------------*/
+
+bool Scene2455::Actor1::startAction(CursorType action, Event &event) {
+ Scene2455 *scene = (Scene2455 *)R2_GLOBALS._sceneManager._scene;
+
+ if (action == R2_GLASS_DOME) {
+ if ((R2_INVENTORY.getObjectScene(49) == 2455) || (R2_INVENTORY.getObjectScene(50) == 2455)) {
+ R2_GLOBALS._player.disableControl();
+ scene->_sceneMode = 2458;
+ scene->_actor2._lookLineNum = 9;
+ scene->_actor1.remove();
+ scene->_actor3.postInit();
+ scene->_actor3.setDetails(2455, 16, 1, -1, 2, (SceneItem *)NULL);
+ scene->setAction(&scene->_sequenceManager, scene, 2458, &R2_GLOBALS._player, &scene->_actor2, &scene->_actor3, NULL);
+ return true;
+ }
+ }
+
+ return SceneActor::startAction(action, event);
+}
+
+bool Scene2455::Actor2::startAction(CursorType action, Event &event) {
+ Scene2455 *scene = (Scene2455 *)R2_GLOBALS._sceneManager._scene;
+
+ switch (action) {
+ case R2_ALCOHOL_LAMP_2:
+ if (R2_INVENTORY.getObjectScene(50) != 2455) {
+ R2_GLOBALS._player.disableControl();
+ scene->_actor1.postInit();
+ scene->_actor1.setup(2456, 3, 3);
+ scene->_actor1.setPosition(Common::Point(162, 165));
+ scene->_actor1.setDetails(2455, 15, 1, -1, 2, (SceneItem *)NULL);
+ scene->_sceneMode = 11;
+ scene->setAction(&scene->_sequenceManager, scene, 2457, &R2_GLOBALS._player, &scene->_actor2, NULL);
+ return true;
+ }
+ break;
+ case R2_ALCOHOL_LAMP_3:
+ if (R2_INVENTORY.getObjectScene(49) != 2455) {
+ R2_GLOBALS._player.disableControl();
+ scene->_actor1.postInit();
+ scene->_actor1.setup(2456, 3, 3);
+ scene->_actor1.setPosition(Common::Point(162, 165));
+ scene->_actor1.setDetails(2455, 15, 1, -1, 2, (SceneItem *)NULL);
+ scene->_sceneMode = 12;
+ scene->setAction(&scene->_sequenceManager, scene, 2457, &R2_GLOBALS._player, &scene->_actor2, NULL);
+ return true;
+ }
+ break;
+ default:
+ break;
+ }
+
+ return SceneActor::startAction(action, event);
+}
+
+bool Scene2455::Actor3::startAction(CursorType action, Event &event) {
+ Scene2455 *scene = (Scene2455 *)R2_GLOBALS._sceneManager._scene;
+
+ if (action == CURSOR_USE) {
+ R2_GLOBALS._player.disableControl();
+ scene->_sceneMode = 2459;
+ scene->setAction(&scene->_sequenceManager, scene, 2459, &R2_GLOBALS._player, &scene->_actor3, NULL);
+ return true;
+ }
+
+ return SceneActor::startAction(action, event);
+}
+
+void Scene2455::Exit1::changeScene() {
+ Scene2455 *scene = (Scene2455 *)R2_GLOBALS._sceneManager._scene;
+
+ _enabled = false;
+ R2_GLOBALS._events.setCursor(CURSOR_ARROW);
+ R2_GLOBALS._player.disableControl();
+ scene->_sceneMode = 2461;
+ scene->setAction(&scene->_sequenceManager, scene, 2461, &R2_GLOBALS._player, NULL);
+}
+
+void Scene2455::postInit(SceneObjectList *OwnerList) {
+ loadScene(2455);
+ SceneExt::postInit();
+
+ if (R2_GLOBALS._sceneManager._previousScene == -1) {
+ R2_INVENTORY.setObjectScene(29, 2);
+ R2_INVENTORY.setObjectScene(50, 2);
+ }
+
+ R2_GLOBALS._sound1.play(200);
+ _exit1.setDetails(Rect(0, 0, 320, 15), EXITCURSOR_N, 2425);
+
+ if (R2_INVENTORY.getObjectScene(29) == 2455) {
+ if ((R2_INVENTORY.getObjectScene(50) == 2455) || (R2_INVENTORY.getObjectScene(49) == 2455)) {
+ _actor1.postInit();
+ _actor1.setup(2456, 3, 3);
+ _actor1.setPosition(Common::Point(162, 165));
+ _actor1.setDetails(2455, 15, 1, -1, 1, (SceneItem *)NULL);
+ }
+ } else {
+ _actor3.postInit();
+ _actor3.setup(2456, 3, 1);
+ _actor3.setPosition(Common::Point(176, 165));
+ _actor3.setDetails(2455, 16, 1, -1, 1, (SceneItem *)NULL);
+ }
+
+ _actor2.postInit();
+ if (R2_INVENTORY.getObjectScene(29) == 2455) {
+ _actor2.setup(2456, 3, 2);
+ _actor2.setDetails(2455, 9, 1, -1, 1, (SceneItem *)NULL);
+ } else {
+ if ((R2_INVENTORY.getObjectScene(50) != 2455) && (R2_INVENTORY.getObjectScene(49) != 2455))
+ _actor2.setup(2455, 1, 1);
+ else
+ _actor2.setup(2456, 1, 1);
+ _actor2.setDetails(2455, 3, 1, -1, 1, (SceneItem *)NULL);
+ }
+ _actor2.setPosition(Common::Point(162, 165));
+ _actor2.fixPriority(20);
+ if (R2_INVENTORY.getObjectScene(29) != 2455)
+ _actor2.animate(ANIM_MODE_2, NULL);
+
+ R2_GLOBALS._player.postInit();
+ _item1.setDetails(Rect(0, 0, 320, 200), 2455, 0, 1, -1, 1, NULL);
+ R2_GLOBALS._player.disableControl();
+
+ if (R2_GLOBALS._player._oldCharacterScene[R2_GLOBALS._player._characterIndex] == 2425) {
+ _sceneMode = 2460;
+ setAction(&_sequenceManager, this, 2460, &R2_GLOBALS._player, NULL);
+ } else {
+ R2_GLOBALS._player.setup(2455, 2, 9);
+ R2_GLOBALS._player.setPosition(Common::Point(118, 165));
+ R2_GLOBALS._player.enableControl(CURSOR_USE);
+ R2_GLOBALS._player._canWalk = false;
+ }
+ R2_GLOBALS._player._oldCharacterScene[R2_GLOBALS._player._characterIndex] = 2455;
+}
+
+void Scene2455::remove() {
+ R2_GLOBALS._sound1.fadeOut2(NULL);
+ SceneExt::remove();
+}
+
+void Scene2455::signal() {
+ switch (_sceneMode) {
+ case 10:
+ // No break on purpose
+ case 2461:
+ g_globals->_sceneManager.changeScene(2425);
+ break;
+ case 11:
+ R2_INVENTORY.setObjectScene(49, 2455);
+ R2_GLOBALS._player.enableControl(CURSOR_USE);
+ R2_GLOBALS._player._canWalk = false;
+ break;
+ case 12:
+ R2_INVENTORY.setObjectScene(50, 2455);
+ R2_GLOBALS._player.enableControl(CURSOR_USE);
+ R2_GLOBALS._player._canWalk = false;
+ break;
+ case 2458:
+ R2_INVENTORY.setObjectScene(29, 2455);
+ R2_GLOBALS._player.enableControl(CURSOR_USE);
+ R2_GLOBALS._player._canWalk = false;
+ break;
+ case 2459:
+ _actor3.remove();
+ R2_INVENTORY.setObjectScene(31, 2);
+ R2_GLOBALS._player.enableControl(CURSOR_USE);
+ R2_GLOBALS._player._canWalk = false;
+ break;
+ default:
+ R2_GLOBALS._player.enableControl(CURSOR_USE);
+ R2_GLOBALS._player._canWalk = false;
+ break;
+ }
+}
+
+/*--------------------------------------------------------------------------
+ * Scene 2500 - Ice Maze: Large Cave
+ *
+ *--------------------------------------------------------------------------*/
+
+void Scene2500::Exit1::changeScene() {
+ Scene2500 *scene = (Scene2500 *)R2_GLOBALS._sceneManager._scene;
+
+ _enabled = false;
+ R2_GLOBALS._events.setCursor(CURSOR_ARROW);
+ R2_GLOBALS._player.disableControl();
+ scene->_sceneMode = 11;
+
+ Common::Point pt(20, 105);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, scene);
+}
+
+void Scene2500::postInit(SceneObjectList *OwnerList) {
+ loadScene(2500);
+ SceneExt::postInit();
+
+ if (R2_GLOBALS._player._oldCharacterScene[R2_GLOBALS._player._characterIndex] == 3100)
+ R2_GLOBALS._uiElements._active = false;
+
+ _stripManager.addSpeaker(&_quinnSpeaker);
+ _stripManager.addSpeaker(&_seekerSpeaker);
+ _stripManager.addSpeaker(&_mirandaSpeaker);
+ _stripManager.addSpeaker(&_webbsterSpeaker);
+
+ if (R2_GLOBALS._sceneManager._previousScene == -1)
+ R2_GLOBALS._sceneManager._previousScene = 2000;
+
+ _exit1.setDetails(Rect(30, 50, 85, 105), EXITCURSOR_W, 2000);
+ _exit1.setDest(Common::Point(84, 104));
+ R2_GLOBALS._player.postInit();
+ R2_GLOBALS._player.animate(ANIM_MODE_1, NULL);
+
+ if (R2_GLOBALS._player._characterIndex == 1) {
+ R2_GLOBALS._player.setVisage(11);
+ R2_GLOBALS._player._moveDiff = Common::Point(2, 1);
+ } else {
+ R2_GLOBALS._player.setVisage(21);
+ R2_GLOBALS._player._moveDiff = Common::Point(3, 2);
+ }
+
+ if (R2_GLOBALS._player._characterScene[1] == R2_GLOBALS._player._characterScene[2]) {
+ _actor1.postInit();
+ if (R2_GLOBALS._player._characterIndex == 1) {
+ _actor1.setup(21, 3, 1);
+ _actor1.setDetails(9002, 1, -1, -1, 1, (SceneItem *)NULL);
+ } else {
+ _actor1.setup(2008, 3, 1);
+ _actor1.changeZoom(50);
+ _actor1.setDetails(9001, 0, -1, -1, 1, (SceneItem *)NULL);
+ }
+ _actor1.setPosition(Common::Point(141, 94));
+ }
+
+ _item1.setDetails(Rect(0, 0, 320, 200), 2430, 0, -1, -1, 1, NULL);
+ R2_GLOBALS._player.disableControl();
+
+ if (R2_GLOBALS._player._oldCharacterScene[R2_GLOBALS._player._characterIndex] == 2000) {
+ _sceneMode = 10;
+ R2_GLOBALS._player.setPosition(Common::Point(20, 105));
+ Common::Point pt(95, 105);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, this);
+ } else if (R2_GLOBALS._player._oldCharacterScene[R2_GLOBALS._player._characterIndex] == 3100) {
+ _sceneMode = 2500;
+ _actor2.postInit();
+ _actor3.postInit();
+ setAction(&_sequenceManager, this, 2500, &R2_GLOBALS._player, &_actor2, &_actor3, NULL);
+ } else {
+ R2_GLOBALS._player.setPosition(Common::Point(160, 150));
+ R2_GLOBALS._player.setStrip(3);
+ R2_GLOBALS._player.enableControl();
+ }
+ R2_GLOBALS._player._oldCharacterScene[R2_GLOBALS._player._characterIndex] = 2500;
+}
+
+void Scene2500::signal() {
+ switch (_sceneMode) {
+ case 11:
+ g_globals->_sceneManager.changeScene(2000);
+ break;
+ case 20:
+ R2_GLOBALS._player.disableControl();
+ _sceneMode = 2501;
+ setAction(&_sequenceManager, this, 2501, &R2_GLOBALS._player, &_actor2, &_actor3, NULL);
+ break;
+ case 2500:
+ _sceneMode = 20;
+ R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
+ _stripManager.start(900, this);
+ break;
+ case 2501:
+ g_globals->_sceneManager.changeScene(1000);
+ break;
+ default:
+ R2_GLOBALS._player.enableControl();
+ break;
+ }
+}
+
+/*--------------------------------------------------------------------------
+ * Scene 2525 - Furnace room
+ *
+ *--------------------------------------------------------------------------*/
+bool Scene2525::Item5::startAction(CursorType action, Event &event) {
+ Scene2525 *scene = (Scene2525 *)R2_GLOBALS._sceneManager._scene;
+
+ if ((action == R2_REBREATHER_TANK) && (!R2_GLOBALS.getFlag(74))) {
+ R2_GLOBALS._player.disableControl();
+ scene->_sceneMode = 2526;
+ scene->setAction(&scene->_sequenceManager, scene, 2526, &R2_GLOBALS._player, NULL);
+ return true;
+ }
+
+ return SceneItem::startAction(action, event);
+}
+
+bool Scene2525::Actor3::startAction(CursorType action, Event &event) {
+ Scene2525 *scene = (Scene2525 *)R2_GLOBALS._sceneManager._scene;
+
+ if (action != CURSOR_USE)
+ return SceneActor::startAction(action, event);
+
+ if (R2_GLOBALS._player._characterIndex == 2) {
+ R2_GLOBALS._player.disableControl();
+ scene->_sceneMode = 2525;
+ scene->setAction(&scene->_sequenceManager, scene, 2525, &R2_GLOBALS._player, &scene->_actor3, NULL);
+ } else {
+ SceneItem::display(2530, 33, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
+ }
+ return true;
+}
+
+void Scene2525::Exit1::changeScene() {
+ Scene2525 *scene = (Scene2525 *)R2_GLOBALS._sceneManager._scene;
+
+ _enabled = false;
+ R2_GLOBALS._events.setCursor(CURSOR_ARROW);
+ R2_GLOBALS._player.disableControl();
+ scene->_sceneMode = 11;
+
+ Common::Point pt(R2_GLOBALS._player._position.x, 200);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, scene);
+}
+
+void Scene2525::postInit(SceneObjectList *OwnerList) {
+ loadScene(2525);
+ SceneExt::postInit();
+ R2_GLOBALS._sound1.play(200);
+ R2_GLOBALS._sound2.play(207);
+
+ _exit1.setDetails(Rect(86, 155, 228, 168), EXITCURSOR_S, 2000);
+
+ if (R2_INVENTORY.getObjectScene(29) == 2525) {
+ _actor3.postInit();
+ _actor3.setup(2435, 1, 2);
+ _actor3.setPosition(Common::Point(78, 155));
+ _actor3.fixPriority(155);
+ _actor3.setDetails(2525, 27, -1, -1, 1, (SceneItem *)NULL);
+ }
+
+ _actor2.postInit();
+ _actor2.setup(2525, 1, 1);
+ _actor2.setPosition(Common::Point(183, 114));
+ _actor2.setDetails(2525, 15, -1, -1, 1, (SceneItem *)NULL);
+ _actor2.animate(ANIM_MODE_2, NULL);
+ _actor2._numFrames = 3;
+
+ R2_GLOBALS._player.postInit();
+ R2_GLOBALS._player.animate(ANIM_MODE_1, NULL);
+ if (R2_GLOBALS._player._characterIndex == 1) {
+ R2_GLOBALS._player.setup(2008, 3, 1);
+ R2_GLOBALS._player._moveDiff = Common::Point(3, 2);
+ } else {
+ R2_GLOBALS._player.setup(20, 3, 1);
+ R2_GLOBALS._player._moveDiff = Common::Point(5, 3);
+ }
+
+ if (R2_GLOBALS._player._characterScene[1] == R2_GLOBALS._player._characterScene[2]) {
+ _actor1.postInit();
+ if (R2_GLOBALS._player._characterIndex == 1) {
+ _actor1.setup(20, 5, 1);
+ _actor1.setDetails(9002, 0, 4, 3, 1, (SceneItem *)NULL);
+ } else {
+ _actor1.setup(2008, 5, 1);
+ _actor1.setDetails(9001, 0, 5, 3, 1, (SceneItem *)NULL);
+ }
+ _actor1.setPosition(Common::Point(209, 162));
+
+ R2_GLOBALS._walkRegions.enableRegion(4);
+ }
+
+ _item5.setDetails(Rect(125, 73, 140, 86), 2525, 6, -1, -1, 1, NULL);
+ _item3.setDetails(Rect(137, 11, 163, 72), 2525, 12, -1, -1, 1, NULL);
+ _item4.setDetails(Rect(204, 20, 234, 78), 2525, 12, -1, -1, 1, NULL);
+ _item2.setDetails(Rect(102, 62, 230, 134), 2525, 0, -1, -1, 1, NULL);
+ _item1.setDetails(Rect(0, 0, 320, 200), 2525, 24, -1, -1, 1, NULL);
+
+ R2_GLOBALS._player.disableControl();
+
+ if (R2_GLOBALS._player._oldCharacterScene[R2_GLOBALS._player._characterIndex] == 2000) {
+ R2_GLOBALS._player._oldCharacterScene[R2_GLOBALS._player._characterIndex] = 2525;
+ R2_GLOBALS._player.setPosition(Common::Point(160, 200));
+ Common::Point pt(160, 150);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, this);
+ } else {
+ R2_GLOBALS._player.setPosition(Common::Point(160, 150));
+ R2_GLOBALS._player.setStrip(3);
+ R2_GLOBALS._player.enableControl();
+ }
+}
+
+void Scene2525::remove() {
+ R2_GLOBALS._sound1.fadeOut2(NULL);
+ R2_GLOBALS._sound2.fadeOut2(NULL);
+ SceneExt::remove();
+}
+
+void Scene2525::signal() {
+ switch (_sceneMode) {
+ case 11:
+ g_globals->_sceneManager.changeScene(2000);
+ break;
+ case 2525:
+ _actor3.remove();
+ R2_INVENTORY.setObjectScene(29, 2);
+ R2_GLOBALS._player.enableControl();
+ break;
+ case 2526:
+ R2_GLOBALS.setFlag(74);
+ R2_GLOBALS._player.enableControl();
+ break;
+ default:
+ R2_GLOBALS._player.enableControl();
+ break;
+ }
+}
+
+/*--------------------------------------------------------------------------
+ * Scene 2530 - Ice Maze: Well
+ *
+ *--------------------------------------------------------------------------*/
+bool Scene2530::Actor2::startAction(CursorType action, Event &event) {
+ Scene2530 *scene = (Scene2530 *)R2_GLOBALS._sceneManager._scene;
+
+ if (action != CURSOR_USE)
+ return SceneActor::startAction(action, event);
+
+ if (R2_GLOBALS._player._characterIndex == 2) {
+ R2_GLOBALS._player.disableControl();
+ scene->_sceneMode = 2530;
+ scene->setAction(&scene->_sequenceManager, scene, 2530, &R2_GLOBALS._player, &scene->_actor2, NULL);
+ } else {
+ SceneItem::display(2530, 33, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
+ }
+
+ return true;
+}
+
+bool Scene2530::Actor3::startAction(CursorType action, Event &event) {
+ Scene2530 *scene = (Scene2530 *)R2_GLOBALS._sceneManager._scene;
+
+ if (action != CURSOR_USE)
+ return SceneActor::startAction(action, event);
+
+ if (R2_GLOBALS._player._characterIndex == 1) {
+ if (R2_GLOBALS.getFlag(73))
+ SceneItem::display(2530, 35, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
+ else {
+ R2_GLOBALS._player.disableControl();
+ scene->_sceneMode = 2532;
+ scene->setAction(&scene->_sequenceManager, scene, 2532, &R2_GLOBALS._player, &scene->_actor3, NULL);
+ }
+ } else {
+ if (R2_GLOBALS.getFlag(73)) {
+ R2_GLOBALS._player.disableControl();
+ scene->_sceneMode = 2533;
+ scene->setAction(&scene->_sequenceManager, scene, 2533, &R2_GLOBALS._player, &scene->_actor3, NULL);
+ } else {
+ R2_GLOBALS._player.disableControl();
+ scene->_sceneMode = 2531;
+ scene->setAction(&scene->_sequenceManager, scene, 2531, &R2_GLOBALS._player, &scene->_actor3, NULL);
+ }
+ }
+
+ return true;
+}
+
+void Scene2530::Exit1::changeScene() {
+ Scene2530 *scene = (Scene2530 *)R2_GLOBALS._sceneManager._scene;
+
+ _enabled = false;
+ R2_GLOBALS._events.setCursor(CURSOR_ARROW);
+ R2_GLOBALS._player.disableControl();
+ scene->_sceneMode = 11;
+
+ Common::Point pt(108, 200);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, scene);
+}
+
+void Scene2530::postInit(SceneObjectList *OwnerList) {
+ loadScene(2530);
+ SceneExt::postInit();
+
+ _exit1.setDetails(Rect(68, 155, 147, 168), EXITCURSOR_S, 2000);
+ _exit1.setDest(Common::Point(108, 160));
+
+ if (R2_INVENTORY.getObjectScene(33) == 2530) {
+ _actor2.postInit();
+ _actor2.setup(2435, 1, 3);
+ _actor2.setPosition(Common::Point(299, 80));
+ _actor2.fixPriority(80);
+ _actor2.setDetails(2530, 28, -1, -1, 1, (SceneItem *)NULL);
+ }
+
+ _actor3.postInit();
+ if (R2_GLOBALS.getFlag(73)) {
+ _actor3.setup(2531, 4, 2);
+ _actor3.setPosition(Common::Point(154, 130));
+ } else {
+ _actor3.setup(2531, 4, 1);
+ _actor3.setPosition(Common::Point(173, 131));
+ }
+ _actor3.setDetails(2530, 22, -1, -1, 1, (SceneItem *)NULL);
+
+ R2_GLOBALS._player.postInit();
+ R2_GLOBALS._player.animate(ANIM_MODE_1, NULL);
+
+ if (R2_GLOBALS._player._characterIndex == 1) {
+ R2_GLOBALS._player.setVisage(2008);
+ R2_GLOBALS._player._moveDiff = Common::Point(3, 2);
+ } else {
+ R2_GLOBALS._player.setVisage(20);
+ R2_GLOBALS._player._moveDiff = Common::Point(5, 3);
+ }
+ R2_GLOBALS._player.setPosition(Common::Point(100, 200));
+
+ if (R2_GLOBALS._player._characterScene[1] == R2_GLOBALS._player._characterScene[2]) {
+ _actor1.postInit();
+ if (R2_GLOBALS._player._characterIndex == 1) {
+ _actor1.setup(20, 5, 1);
+ _actor1.setDetails(9002, 0, 4, 3, 1, (SceneItem *)NULL);
+ } else {
+ _actor1.setup(2008, 5, 1);
+ _actor1.setDetails(9001, 0, 5, 3, 1, (SceneItem *)NULL);
+ }
+ _actor1.setPosition(Common::Point(20, 130));
+ R2_GLOBALS._walkRegions.enableRegion(1);
+ }
+
+ _item2.setDetails(Rect(108, 90, 135, 205), 2530, 22, -1, -1, 1, NULL);
+ _item5.setDetails(Rect(115, 112, 206, 130), 2530, 25, -1, 27, 1, NULL);
+ _item3.setDetails(Rect(256, 64, 311, 85), 2530, 31, -1, 33, 1, NULL);
+ _item1.setDetails(Rect(0, 0, 320, 200), 2530, 0, 1, -1, 1, NULL);
+
+ R2_GLOBALS._player.disableControl();
+
+ if (R2_GLOBALS._player._oldCharacterScene[R2_GLOBALS._player._characterIndex] == 2000) {
+ R2_GLOBALS._player._oldCharacterScene[R2_GLOBALS._player._characterIndex] = 2530;
+ Common::Point pt(108, 150);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, this);
+ } else {
+ R2_GLOBALS._player.setPosition(Common::Point(105, 145));
+ R2_GLOBALS._player.setStrip(3);
+ R2_GLOBALS._player.enableControl();
+ }
+}
+
+void Scene2530::signal() {
+ switch (_sceneMode) {
+ case 11:
+ g_globals->_sceneManager.changeScene(2000);
+ break;
+ case 2530:
+ R2_INVENTORY.setObjectScene(33, 2);
+ _actor2.remove();
+ break;
+ case 2531:
+ // No break on purpose
+ case 2532:
+ R2_GLOBALS.setFlag(73);
+ R2_GLOBALS._player.enableControl();
+ break;
+ case 2533:
+ R2_GLOBALS.clearFlag(73);
+ R2_GLOBALS._player.enableControl();
+ break;
+ default:
+ R2_GLOBALS._player.enableControl();
+ break;
+ }
+}
+
+/*--------------------------------------------------------------------------
+ * Scene 2535 - Ice Maze: Tannery
+ *
+ *--------------------------------------------------------------------------*/
+
+bool Scene2535::Actor3::startAction(CursorType action, Event &event) {
+ Scene2535 *scene = (Scene2535 *)R2_GLOBALS._sceneManager._scene;
+
+ if (action != CURSOR_USE)
+ return SceneActor::startAction(action, event);
+
+ if (R2_GLOBALS._player._characterIndex == 1) {
+ R2_GLOBALS._player.disableControl();
+ if (R2_INVENTORY.getObjectScene(20) == 2535) {
+ scene->_sceneMode = 2536;
+ scene->setAction(&scene->_sequenceManager, scene, 2536, &R2_GLOBALS._player, &scene->_actor3, NULL);
+ } else {
+ scene->_sceneMode = 2537;
+ scene->setAction(&scene->_sequenceManager, scene, 2537, &R2_GLOBALS._player, &scene->_actor3, NULL);
+ }
+ } else {
+ SceneItem::display(2530, 33, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
+ }
+
+ return true;
+}
+
+bool Scene2535::Actor4::startAction(CursorType action, Event &event) {
+ Scene2535 *scene = (Scene2535 *)R2_GLOBALS._sceneManager._scene;
+
+ if (action != CURSOR_USE)
+ return SceneActor::startAction(action, event);
+
+ if (R2_GLOBALS._player._characterIndex == 2) {
+ R2_GLOBALS._player.disableControl();
+ scene->_sceneMode = 2535;
+ scene->setAction(&scene->_sequenceManager, scene, 2535, &R2_GLOBALS._player, &scene->_actor4, NULL);
+ } else {
+ SceneItem::display(2530, 33, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
+ }
+
+ return true;
+}
+
+void Scene2535::Exit1::changeScene() {
+ Scene2535 *scene = (Scene2535 *)R2_GLOBALS._sceneManager._scene;
+
+ _enabled = false;
+ R2_GLOBALS._events.setCursor(CURSOR_ARROW);
+ R2_GLOBALS._player.disableControl();
+ scene->_sceneMode = 11;
+ Common::Point pt(210, 200);
+ PlayerMover *mover = new PlayerMover();
+ R2_GLOBALS._player.addMover(mover, &pt, scene);
+}
+
+void Scene2535::postInit(SceneObjectList *OwnerList) {
+ loadScene(2535);
+ SceneExt::postInit();
+ if (R2_GLOBALS._sceneManager._previousScene == -1) {
+ R2_GLOBALS.setFlag(73);
+ R2_INVENTORY.setObjectScene(20, 2535);
+ }
+ _exit1.setDetails(Rect(172, 155, 250, 167), EXITCURSOR_S, 2000);
+ _exit1.setDest(Common::Point(210, 160));
+
+ if (R2_INVENTORY.getObjectScene(32) == 2535) {
+ _actor4.postInit();
+ _actor4.setup(2435, 1, 4);
+ _actor4.setPosition(Common::Point(47, 74));
+ _actor4.fixPriority(74);
+ _actor4.setDetails(2535, 21, -1, -1, 1, (SceneItem *)NULL);
+ }
+
+ if (R2_INVENTORY.getObjectScene(20) == 2535) {
+ _actor3.postInit();
+ _actor3.setup(2535, 3, 1);
+ _actor3.setPosition(Common::Point(203, 131));
+ _actor3.setDetails(3, 20, -1, -1, 1, (SceneItem *)NULL);
+ R2_GLOBALS._walkRegions.enableRegion(6);
+ }
+
+ if ((R2_INVENTORY.getObjectScene(20) == 0) && (R2_GLOBALS.getFlag(73))) {
+ _actor3.postInit();
+ _actor3.setup(2536, 1, 2);
+ _actor3.setPosition(Common::Point(164, 133));
+ _actor3.setDetails(3, 20, -1, -1, 1, (SceneItem *)NULL);
+ }
+
+ if (R2_GLOBALS.getFlag(73)) {
+ _actor2.postInit();
+ _actor2.setup(2536, 1, 1);
+ _actor2.setPosition(Common::Point(160, 130));
+ _actor2.fixPriority(122);
+ _actor2.setDetails(2535, 37, -1, -1, 1, (SceneItem *)NULL);
+ }
+
+ R2_GLOBALS._player.postInit();
+ R2_GLOBALS._player.animate(ANIM_MODE_1, NULL);
+ if (R2_GLOBALS._player._characterIndex == 1) {
+ R2_GLOBALS._player.setVisage(2008);
+ R2_GLOBALS._player._moveDiff = Common::Point(3, 2);
+ } else {
+ R2_GLOBALS._player.setVisage(20);
+ R2_GLOBALS._player._moveDiff = Common::Point(5, 3);
+ }
+ R2_GLOBALS._player.setPosition(Common::Point(210, 200));
+
+ if (R2_GLOBALS._player._characterScene[1] == R2_GLOBALS._player._characterScene[2]) {
+ _actor1.postInit();
+ if (R2_GLOBALS._player._characterIndex == 1) {
+ _actor1.setup(20, 5, 1);
+ _actor1.setDetails(9002, 0, 4, 3, 1, (SceneItem *)NULL);
+ } else {
+ _actor1.setup(2008, 5, 1);
+ _actor1.setDetails(9001, 0, 5, 3, 1, (SceneItem *)NULL);
+ }
+ _actor1.setPosition(Common::Point(245, 115));
+ R2_GLOBALS._walkRegions.enableRegion(2);
+ }
+
+ _item2.setDetails(Rect(96, 3, 215, 33), 2535, 3, 6, 5, 1, NULL);
+ _item3.setDetails(Rect(4, 43, 40, 101), 2535, 6, 7, 8, 1, NULL);
+ _item4.setDetails(Rect(55, 13, 140, 89), 2535, 6, 7, 8, 1, NULL);
+ _item5.setDetails(Rect(144, 23, 216, 76), 2535, 6, 7, 8, 1, NULL);
+ _item6.setDetails(Rect(227, 8, 307, 99), 2535, 6, 7, 8, 1, NULL);
+ _item7.setDetails(Rect(116, 111, 201, 132), 2535, 18, 19, 20, 1, NULL);
+ _item1.setDetails(Rect(0, 0, 320, 200), 2535, 0, 1, -1, 1, NULL);
+ R2_GLOBALS._player.disableControl();
+
+ if (R2_GLOBALS._player._oldCharacterScene[R2_GLOBALS._player._characterIndex] == 2000) {
+ R2_GLOBALS._player._oldCharacterScene[R2_GLOBALS._player._characterIndex] = 2535;
+ Common::Point pt(210, 150);
+ PlayerMover *mover = new PlayerMover();
+ R2_GLOBALS._player.addMover(mover, &pt, this);
+ } else {
+ R2_GLOBALS._player.setPosition(Common::Point(210, 150));
+ R2_GLOBALS._player.setStrip(3);
+ R2_GLOBALS._player.enableControl();
+ }
+}
+
+void Scene2535::signal() {
+ switch (_sceneMode) {
+ case 11:
+ g_globals->_sceneManager.changeScene(2000);
+ break;
+ case 2535:
+ R2_INVENTORY.setObjectScene(32, 2);
+ _actor4.remove();
+ R2_GLOBALS._player.enableControl();
+ break;
+ case 2536:
+ R2_INVENTORY.setObjectScene(20, 0);
+ R2_GLOBALS._walkRegions.disableRegion(6);
+ if (!R2_GLOBALS.getFlag(73)) {
+ _actor3.remove();
+ R2_GLOBALS._player.enableControl();
+ } else {
+ _sceneMode = 20;
+ _actor3.show();
+ _actor3.setup(2536, 1, 2);
+ _actor3.setDetails(3, 20, -1, -1, 3, (SceneItem *)NULL);
+ _actor3.setPosition(Common::Point(164, 150));
+ _actor3.fixPriority(130);
+ _actor3._moveDiff.y = 1;
+ Common::Point pt(164, 133);
+ PlayerMover *mover = new PlayerMover();
+ _actor3.addMover(mover, &pt, this);
+ }
+ break;
+ case 2537:
+ _actor3.remove();
+ R2_INVENTORY.setObjectScene(20, 1);
+ R2_GLOBALS._player.enableControl();
+ break;
+ case 20:
+ // No break on purpose
+ default:
+ R2_GLOBALS._player.enableControl();
+ break;
+ }
+}
+
+/*--------------------------------------------------------------------------
+ * Scene 2600 - Ice Maze: Exit
+ *
+ *--------------------------------------------------------------------------*/
+Scene2600::Scene2600(): SceneExt() {
+ _rotation = NULL;
+}
+
+void Scene2600::synchronize(Serializer &s) {
+ SceneExt::synchronize(s);
+
+ SYNC_POINTER(_rotation);
+}
+
+void Scene2600::postInit(SceneObjectList *OwnerList) {
+ loadScene(2600);
+ R2_GLOBALS._uiElements._active = false;
+ SceneExt::postInit();
+ R2_GLOBALS._sound1.fadeSound(214);
+ R2_GLOBALS._sound2.play(215);
+ _rotation = R2_GLOBALS._scenePalette.addRotation(176, 191, 1);
+ _rotation->setDelay(3);
+ _rotation->_countdown = 1;
+ R2_GLOBALS._player.postInit();
+ R2_GLOBALS._player.disableControl();
+ _sceneMode = 2600;
+ R2_GLOBALS._player.setAction(&_sequenceManager, this, 2600, &R2_GLOBALS._player, NULL);
+}
+
+void Scene2600::remove() {
+ R2_GLOBALS._sound1.fadeOut2(NULL);
+ R2_GLOBALS._sound2.fadeOut2(NULL);
+// _rotation->remove();
+ SceneExt::remove();
+}
+
+void Scene2600::signal() {
+ if (_sceneMode == 2600)
+ g_globals->_sceneManager.changeScene(3800);
+}
+
+/*--------------------------------------------------------------------------
+ * Scene 2700 - Forest Maze
+ *
+ *--------------------------------------------------------------------------*/
+Scene2700::Scene2700(): SceneExt() {
+ _field412 = _field414 = _field416 = 0;
+}
+
+void Scene2700::synchronize(Serializer &s) {
+ SceneExt::synchronize(s);
+
+ s.syncAsSint16LE(_field412);
+ s.syncAsSint16LE(_field414);
+ s.syncAsSint16LE(_field416);
+}
+
+void Scene2700::Action1::signal() {
+ Scene2700 *scene = (Scene2700 *)R2_GLOBALS._sceneManager._scene;
+
+ setDelay(600 + R2_GLOBALS._randomSource.getRandomNumber(300));
+ scene->_actor2.animate(ANIM_MODE_5, NULL);
+}
+
+void Scene2700::Action2::signal() {
+ Scene2700 *scene = (Scene2700 *)R2_GLOBALS._sceneManager._scene;
+
+ setDelay(300 + R2_GLOBALS._randomSource.getRandomNumber(300));
+ scene->_actor3.animate(ANIM_MODE_5, NULL);
+}
+
+void Scene2700::Action3::signal() {
+ Scene2700 *scene = (Scene2700 *)R2_GLOBALS._sceneManager._scene;
+
+ setDelay(450 + R2_GLOBALS._randomSource.getRandomNumber(450));
+ scene->_actor4.animate(ANIM_MODE_8, 1, NULL);
+}
+
+void Scene2700::Action4::signal() {
+ Scene2700 *scene = (Scene2700 *)R2_GLOBALS._sceneManager._scene;
+
+ setDelay(300 + R2_GLOBALS._randomSource.getRandomNumber(300));
+ scene->_actor5.animate(ANIM_MODE_8, 1, NULL);
+}
+
+void Scene2700::Area1::process(Event &event) {
+ SceneArea::process(event);
+ if ((event.eventType == 1) && (R2_GLOBALS._player._canWalk) && (_bounds.contains(event.mousePos))) {
+ Scene2700 *scene = (Scene2700 *)R2_GLOBALS._sceneManager._scene;
+ R2_GLOBALS._player.disableControl();
+ scene->_sceneMode = 10;
+ scene->_field414 = 2703;
+ switch (scene->_field412) {
+ case 0:
+ // No break on purpose
+ case 6:
+ scene->_sceneMode = 2703;
+ scene->setAction(&scene->_sequenceManager, scene, 2703, &R2_GLOBALS._player, NULL);
+ break;
+ case 1: {
+ Common::Point pt(80, 137);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, scene);
+ break;
+ }
+ case 2: {
+ Common::Point pt(155, 137);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, scene);
+ break;
+ }
+ case 3: {
+ Common::Point pt(140, 162);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, scene);
+ break;
+ }
+ case 4: {
+ Common::Point pt(155, 137);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, scene);
+ break;
+ }
+ case 5: {
+ Common::Point pt(235, 132);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, scene);
+ break;
+ }
+ default:
+ break;
+ }
+ }
+}
+
+void Scene2700::Area2::process(Event &event) {
+ SceneArea::process(event);
+ if ((event.eventType == 1) && (R2_GLOBALS._player._canWalk) && (_bounds.contains(event.mousePos))) {
+ Scene2700 *scene = (Scene2700 *)R2_GLOBALS._sceneManager._scene;
+ R2_GLOBALS._player.disableControl();
+ scene->_sceneMode = 10;
+ scene->_field414 = 2704;
+ switch (scene->_field412) {
+ case 0: {
+ Common::Point pt(140, 162);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, scene);
+ break;
+ }
+ case 1: {
+ Common::Point pt(80, 137);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, scene);
+ break;
+ }
+ case 2: {
+ Common::Point pt(155, 137);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, scene);
+ break;
+ }
+ case 3: {
+ Common::Point pt(155, 137);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, scene);
+ break;
+ }
+ case 4: {
+ Common::Point pt(235, 132);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, scene);
+ break;
+ }
+ case 5:
+ scene->_sceneMode = 2704;
+ scene->setAction(&scene->_sequenceManager, scene, 2704, &R2_GLOBALS._player, NULL);
+ break;
+ case 6: {
+ Common::Point pt(140, 162);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, scene);
+ break;
+ }
+ default:
+ break;
+ }
+ }
+}
+
+void Scene2700::postInit(SceneObjectList *OwnerList) {
+ loadScene(2700);
+ SceneExt::postInit();
+ R2_GLOBALS._sound1.stop();
+ R2_GLOBALS._sound2.stop();
+
+ _area1.setDetails(Rect(135, 160, 185, 168), SHADECURSOR_DOWN);
+ _area2.setDetails(Rect(300, 90, 320, 135), EXITCURSOR_E);
+ _rect1.set(70, 122, 90, 132);
+ _rect2.set(150, 122, 160, 132);
+ _rect3.set(90, 142, 130, 157);
+ _rect4.set(175, 137, 200, 147);
+ _rect5.set(280, 127, 300, 137);
+ _rect6.set(240, 157, 265, 167);
+
+ _actor2.postInit();
+ _actor2.setup(2700, 1, 1);
+ _actor2.setPosition(Common::Point(140, 29));
+ _actor2.setAction(&_action1);
+
+ _actor3.postInit();
+ _actor3.setup(2700, 2, 1);
+ _actor3.setPosition(Common::Point(213, 32));
+ _actor3.setAction(&_action2);
+
+ _actor4.postInit();
+ _actor4.setup(2700, 3, 1);
+ _actor4.setPosition(Common::Point(17, 39));
+ _actor4.setAction(&_action3);
+
+ _actor5.postInit();
+ _actor5.setup(2700, 5, 1);
+ _actor5.setPosition(Common::Point(17, 71));
+ _actor5.setAction(&_action4);
+
+ _item2.setDetails(Rect(52, 38, 68, 60), 2700, 4, -1, 6, 1, NULL);
+ _item3.setDetails(Rect(113, 22, 127, 33), 2700, 4, -1, 6, 1, NULL);
+ _item4.setDetails(Rect(161, 44, 170, 52), 2700, 4, -1, 6, 1, NULL);
+ _item5.setDetails(Rect(221, 19, 233, 31), 2700, 4, -1, 6, 1, NULL);
+ _item6.setDetails(Rect(235, 59, 250, 75), 2700, 4, -1, 6, 1, NULL);
+ _item1.setDetails(Rect(0, 0, 320, 200), 2700, 4, -1, 6, 1, NULL);
+
+ _stripManager.setColors(60, 255);
+ _stripManager.setFontNumber(3);
+ _stripManager.addSpeaker(&_quinnSpeaker);
+ _stripManager.addSpeaker(&_nejSpeaker);
+
+ R2_GLOBALS._player.postInit();
+ R2_GLOBALS._player.setVisage(19);
+ R2_GLOBALS._player.animate(ANIM_MODE_1, NULL);
+ R2_GLOBALS._player._moveDiff = Common::Point(2, 2);
+ R2_GLOBALS._player.disableControl();
+
+ if (R2_INVENTORY.getObjectScene(36) == 0)
+ R2_GLOBALS._sound1.changeSound(234);
+
+ if (R2_GLOBALS._sceneManager._previousScene == 2750) {
+ _sceneMode = 2702;
+ _field412 = 5;
+ setAction(&_sequenceManager, this, 2702, &R2_GLOBALS._player, NULL);
+ } else {
+ _field412 = 0;
+ if (R2_GLOBALS._sceneManager._previousScene == 3900) {
+ _sceneMode = 2701;
+ setAction(&_sequenceManager, this, 2701, &R2_GLOBALS._player, NULL);
+ } else {
+ R2_GLOBALS._player.setStrip(3);
+ R2_GLOBALS._player.setPosition(Common::Point(164, 160));
+ R2_GLOBALS._player.enableControl();
+ }
+ }
+}
+
+void Scene2700::signal() {
+ switch (_sceneMode) {
+ case 10:
+ switch (_field414) {
+ case 1:
+ switch (_field412) {
+ case 0:
+ case 2:
+ case 4:
+ case 6:
+ _field412 = 3;
+ R2_GLOBALS._player.setAction(&_sequenceManager, this, 2705, &R2_GLOBALS._player, NULL);
+ break;
+ case 3: {
+ _sceneMode = _field414;
+ _field412 = 1;
+ Common::Point pt(80, 127);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, this);
+ break;
+ }
+ case 5:
+ _field412 = 4;
+ R2_GLOBALS._player.setAction(&_sequenceManager, this, 2708, &R2_GLOBALS._player, NULL);
+ break;
+ default: // includes case 1
+ break;
+ }
+ break;
+ case 2:
+ switch (_field412) {
+ case 0:
+ case 1:
+ case 6:
+ _field412 = 3;
+ R2_GLOBALS._player.setAction(&_sequenceManager, this, 2706, &R2_GLOBALS._player, NULL);
+ break;
+ case 3:
+ case 4: {
+ _sceneMode = _field414;
+ _field412 = 2;
+ Common::Point pt(155, 127);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, this);
+ break;
+ }
+ case 5:
+ _field412 = 4;
+ R2_GLOBALS._player.setAction(&_sequenceManager, this, 2708, &R2_GLOBALS._player, NULL);
+ break;
+ default: // includes case 2
+ break;
+ }
+ break;
+ case 3:
+ switch (_field412) {
+ case 0:
+ case 1:
+ case 2:
+ case 4:
+ case 6: {
+ _sceneMode = _field414;
+ _field412 = 3;
+ Common::Point pt(115, 152);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, this);
+ break;
+ }
+ case 5:
+ _field412 = 4;
+ R2_GLOBALS._player.setAction(&_sequenceManager, this, 2708, &R2_GLOBALS._player, NULL);
+ break;
+ default: // includes case 3
+ break;
+ }
+ break;
+ case 4:
+ switch (_field412) {
+ case 0:
+ case 1:
+ case 6:
+ _field412 = 3;
+ R2_GLOBALS._player.setAction(&_sequenceManager, this, 2706, &R2_GLOBALS._player, NULL);
+ break;
+ case 2:
+ case 3:
+ _field412 = 4;
+ R2_GLOBALS._player.setAction(&_sequenceManager, this, 2709, &R2_GLOBALS._player, NULL);
+ break;
+ case 4:
+ case 5:
+ _sceneMode = _field414;
+ R2_GLOBALS._player.setAction(&_sequenceManager, this, 2704, &R2_GLOBALS._player, NULL);
+ break;
+ default:
+ break;
+ }
+ break;
+ case 5:
+ switch (_field412) {
+ case 0:
+ case 1:
+ case 6:
+ _field412 = 3;
+ R2_GLOBALS._player.setAction(&_sequenceManager, this, 2706, &R2_GLOBALS._player, NULL);
+ break;
+ case 2:
+ case 3:
+ _field412 = 4;
+ R2_GLOBALS._player.setAction(&_sequenceManager, this, 2709, &R2_GLOBALS._player, NULL);
+ break;
+ case 4: {
+ _sceneMode = _field414;
+ _field412 = 5;
+ Common::Point pt(285, 132);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, this);
+ break;
+ }
+ default: // includes case 5
+ break;
+ }
+ break;
+ case 6:
+ switch (_field412) {
+ case 0:
+ case 3: {
+ _sceneMode = _field414;
+ _field412 = 6;
+ Common::Point pt(250, 162);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, this);
+ break;
+ }
+ case 1:
+ case 2:
+ case 4:
+ _field412 = 3;
+ R2_GLOBALS._player.setAction(&_sequenceManager, this, 2707, &R2_GLOBALS._player, NULL);
+ break;
+ case 5:
+ _field412 = 4;
+ R2_GLOBALS._player.setAction(&_sequenceManager, this, 2708, &R2_GLOBALS._player, NULL);
+ break;
+ default:
+ break;
+ }
+ break;
+ case 2703:
+ switch (_field412) {
+ case 0:
+ case 3:
+ case 6:
+ _sceneMode = _field414;
+ setAction(&_sequenceManager, this, 2703, &R2_GLOBALS._player, NULL);
+ break;
+ case 1:
+ case 2:
+ case 4:
+ _field412 = 3;
+ R2_GLOBALS._player.setAction(&_sequenceManager, this, 2707, &R2_GLOBALS._player, NULL);
+ break;
+ case 5:
+ _field412 = 4;
+ R2_GLOBALS._player.setAction(&_sequenceManager, this, 2708, &R2_GLOBALS._player, NULL);
+ break;
+ default:
+ break;
+ }
+ break;
+ case 2704:
+ switch (_field412) {
+ case 0:
+ case 1:
+ case 6:
+ _field412 = 3;
+ R2_GLOBALS._player.setAction(&_sequenceManager, this, 2706, &R2_GLOBALS._player, NULL);
+ break;
+ case 2:
+ case 3:
+ _field412 = 4;
+ R2_GLOBALS._player.setAction(&_sequenceManager, this, 2709, &R2_GLOBALS._player, NULL);
+ break;
+ case 4:
+ case 5:
+ _sceneMode = _field414;
+ R2_GLOBALS._player.setAction(&_sequenceManager, this, 2704, &R2_GLOBALS._player, NULL);
+ break;
+ default:
+ break;
+ }
+ break;
+ case 2710:
+ switch (_field412) {
+ case 0:
+ case 1:
+ case 3:
+ _field412 = 3;
+ R2_GLOBALS._player.setAction(&_sequenceManager, this, 2707, &R2_GLOBALS._player, NULL);
+ break;
+ case 2:
+ case 5: {
+ _sceneMode = _field414;
+ Common::Point pt(164, 160);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, this);
+ break;
+ }
+ case 4:
+ _field412 = 4;
+ R2_GLOBALS._player.setAction(&_sequenceManager, this, 2708, &R2_GLOBALS._player, NULL);
+ break;
+ default:
+ break;
+ }
+ break;
+ default:
+ break;
+ }
+ break;
+ case 11:
+ R2_INVENTORY.setObjectScene(36, 0);
+ R2_GLOBALS._player.disableControl();
+ _field412 = 0;
+ _sceneMode = 2700;
+ setAction(&_sequenceManager, this, 2700, &_actor1, NULL);
+ break;
+ case 12:
+ R2_GLOBALS._sound1.play(234);
+ R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
+ _sceneMode = 2711;
+ _stripManager.start(_field416, this);
+ break;
+ case 13:
+ R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
+ _sceneMode = 2712;
+ _stripManager.start(_field416, this);
+ break;
+ case 14:
+ R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
+ _sceneMode = 2713;
+ _stripManager.start(_field416, this);
+ break;
+ case 15:
+ R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
+ _sceneMode = 11;
+ _stripManager.start(_field416, this);
+ break;
+ case 2700:
+ _actor1.remove();
+ R2_GLOBALS._player.enableControl(CURSOR_ARROW);
+ break;
+ case 2703:
+ g_globals->_sceneManager.changeScene(3900);
+ break;
+ case 2704:
+ g_globals->_sceneManager.changeScene(2750);
+ break;
+ case 2710:
+ _field416 = 1200;
+ _sceneMode = 12;
+ _actor1.postInit();
+ setAction(&_sequenceManager, this, 2710, &R2_GLOBALS._player, &_actor1, NULL);
+ break;
+ case 2711:
+ R2_GLOBALS._player.disableControl();
+ _field416 = 1201;
+ _sceneMode = 13;
+ setAction(&_sequenceManager, this, 2711, &R2_GLOBALS._player, &_actor1, NULL);
+ break;
+ case 2712:
+ R2_GLOBALS._player.disableControl();
+ _field416 = 1202;
+ _sceneMode = 14;
+ setAction(&_sequenceManager, this, 2712, &R2_GLOBALS._player, &_actor1, NULL);
+ break;
+ case 2713:
+ R2_GLOBALS._player.disableControl();
+ _field416 = 1203;
+ _sceneMode = 14;
+ setAction(&_sequenceManager, this, 2713, &R2_GLOBALS._player, &_actor1, NULL);
+ break;
+ default:
+ R2_GLOBALS._player.enableControl(CURSOR_ARROW);
+ break;
+ }
+}
+void Scene2700::process(Event &event) {
+ if ((R2_GLOBALS._player._canWalk) && (event.eventType == EVENT_BUTTON_DOWN)) {
+ if (R2_GLOBALS._events.getCursor() == R2_FLUTE) {
+ if (R2_GLOBALS._player._bounds.contains(event.mousePos)) {
+ _sceneMode = 10;
+ _field414 = 2710;
+ R2_GLOBALS._player.disableControl();
+ R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
+ switch (_field412) {
+ case 0: {
+ _sceneMode = 2710;
+ Common::Point pt(164, 160);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, this);
+ break;
+ }
+ case 1: {
+ Common::Point pt(80, 137);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, this);
+ break;
+ }
+ case 2: {
+ Common::Point pt(155, 137);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, this);
+ break;
+ }
+ case 3: {
+ Common::Point pt(140, 162);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, this);
+ break;
+ }
+ case 4: {
+ Common::Point pt(155, 137);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, this);
+ break;
+ }
+ case 5: {
+ Common::Point pt(235, 132);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, this);
+ break;
+ }
+ case 6: {
+ Common::Point pt(205, 162);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, this);
+ break;
+ }
+ default:
+ break;
+ }
+ event.handled = true;
+ } else {
+ SceneItem::display(2700, 3, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
+ }
+ } else if (R2_GLOBALS._events.getCursor() == R2_NEGATOR_GUN) {
+ if (_rect1.contains(event.mousePos)) {
+ if (!_rect1.contains(R2_GLOBALS._player._position)) {
+ event.handled = true;
+ _sceneMode = 10;
+ _field414 = 1;
+ }
+ } else if (_rect2.contains(event.mousePos)) {
+ if (!_rect2.contains(R2_GLOBALS._player._position)) {
+ event.handled = true;
+ _sceneMode = 10;
+ _field414 = 2;
+ }
+ } else if (_rect3.contains(event.mousePos)) {
+ if (!_rect3.contains(R2_GLOBALS._player._position)) {
+ event.handled = true;
+ _sceneMode = 10;
+ _field414 = 3;
+ }
+ } else if (_rect4.contains(event.mousePos)) {
+ if (!_rect4.contains(R2_GLOBALS._player._position)) {
+ event.handled = true;
+ _sceneMode = 10;
+ _field414 = 4;
+ }
+ } else if (_rect5.contains(event.mousePos)) {
+ if (!_rect5.contains(R2_GLOBALS._player._position)) {
+ event.handled = true;
+ _sceneMode = 10;
+ _field414 = 5;
+ }
+ } else if (_rect6.contains(event.mousePos)) {
+ if (!_rect6.contains(R2_GLOBALS._player._position)) {
+ event.handled = true;
+ _sceneMode = 10;
+ _field414 = 6;
+ }
+ } else {
+ event.handled = true;
+ R2_GLOBALS._player.updateAngle(Common::Point(event.mousePos.x, event.mousePos.y));
+ }
+ if (_sceneMode == 10) {
+ R2_GLOBALS._player.disableControl();
+ switch (_field412) {
+ case 0:
+ if (_field414 >= 6) {
+ Common::Point pt(205, 162);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, this);
+ } else {
+ Common::Point pt(140, 162);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, this);
+ }
+ break;
+ case 1: {
+ Common::Point pt(80, 137);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, this);
+ break;
+ }
+ case 2: {
+ Common::Point pt(155, 137);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, this);
+ break;
+ }
+ case 3:
+ if (_field414 == 1) {
+ Common::Point pt(80, 137);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, this);
+ } else if (_field414 == 6) {
+ Common::Point pt(140, 162);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, this);
+ } else {
+ Common::Point pt(155, 137);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, this);
+ }
+ break;
+ case 4:
+ if (_field414 == 5) {
+ Common::Point pt(235, 132);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, this);
+ } else {
+ Common::Point pt(155, 137);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, this);
+ }
+ break;
+ case 5: {
+ Common::Point pt(235, 132);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, this);
+ break;
+ }
+ case 6: {
+ Common::Point pt(140, 162);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, this);
+ break;
+ }
+ default:
+ break;
+ }
+ }
+ }
+ }
+ Scene::process(event);
+}
+
+/*--------------------------------------------------------------------------
+ * Scene 2750 - Forest Maze
+ *
+ *--------------------------------------------------------------------------*/
+Scene2750::Scene2750(): SceneExt() {
+ _field412 = _field414 = _field416 = 0;
+}
+
+void Scene2750::synchronize(Serializer &s) {
+ SceneExt::synchronize(s);
+
+ s.syncAsSint16LE(_field412);
+ s.syncAsSint16LE(_field414);
+ s.syncAsSint16LE(_field416);
+}
+
+void Scene2750::Action1::signal() {
+ Scene2750 *scene = (Scene2750 *)R2_GLOBALS._sceneManager._scene;
+
+ switch (_actionIndex) {
+ case 1:
+ setDelay(60 + R2_GLOBALS._randomSource.getRandomNumber(240));
+ _actionIndex = 2;
+ scene->_actor5.show();
+ scene->_actor5.animate(ANIM_MODE_8, 1, NULL);
+ break;
+ case 2:
+ setDelay(600 + R2_GLOBALS._randomSource.getRandomNumber(600));
+ _actionIndex = 0;
+ scene->_actor5.show();
+ scene->_actor3.animate(ANIM_MODE_2, NULL);
+ break;
+ default:
+ setDelay(30);
+ _actionIndex = 1;
+ scene->_actor3.animate(ANIM_MODE_6, NULL);
+ scene->_actor4.animate(ANIM_MODE_8, 1, NULL);
+ break;
+ }
+}
+
+void Scene2750::Action2::signal() {
+ Scene2750 *scene = (Scene2750 *)R2_GLOBALS._sceneManager._scene;
+
+ setDelay(600 + R2_GLOBALS._randomSource.getRandomNumber(300));
+ scene->_actor6.animate(ANIM_MODE_8, 1, NULL);
+}
+
+void Scene2750::Action3::signal() {
+ Scene2750 *scene = (Scene2750 *)R2_GLOBALS._sceneManager._scene;
+
+ if (scene->_actor7._position.x <= 320) {
+ setDelay(1800 + R2_GLOBALS._randomSource.getRandomNumber(600));
+ } else {
+ setDelay(60);
+ scene->_actor7.setPosition(Common::Point(-10, 25));
+ Common::Point pt(330, 45);
+ NpcMover *mover = new NpcMover();
+ scene->_actor7.addMover(mover, &pt, NULL);
+ }
+}
+
+void Scene2750::Action4::signal() {
+ Scene2750 *scene = (Scene2750 *)R2_GLOBALS._sceneManager._scene;
+
+ setDelay(600 + R2_GLOBALS._randomSource.getRandomNumber(300));
+ scene->_actor8.animate(ANIM_MODE_8, 1, NULL);
+}
+
+void Scene2750::Action5::signal() {
+ Scene2750 *scene = (Scene2750 *)R2_GLOBALS._sceneManager._scene;
+
+ setDelay(600 + R2_GLOBALS._randomSource.getRandomNumber(300));
+ scene->_actor9.animate(ANIM_MODE_8, 1, NULL);
+}
+
+void Scene2750::Action6::signal() {
+ Scene2750 *scene = (Scene2750 *)R2_GLOBALS._sceneManager._scene;
+
+ setDelay(600 + R2_GLOBALS._randomSource.getRandomNumber(300));
+ scene->_actor10.animate(ANIM_MODE_8, 1, NULL);
+}
+
+void Scene2750::Action7::signal() {
+ Scene2750 *scene = (Scene2750 *)R2_GLOBALS._sceneManager._scene;
+
+ setDelay(600 + R2_GLOBALS._randomSource.getRandomNumber(300));
+ scene->_actor11.animate(ANIM_MODE_8, 1, NULL);
+}
+
+void Scene2750::Area1::process(Event &event) {
+ SceneArea::process(event);
+ if ((event.eventType == EVENT_BUTTON_DOWN) && (R2_GLOBALS._player._canWalk) && (_bounds.contains(event.mousePos))) {
+ Scene2750 *scene = (Scene2750 *)R2_GLOBALS._sceneManager._scene;
+ R2_GLOBALS._player.disableControl();
+ scene->_sceneMode = 10;
+ scene->_field414 = 2752;
+ switch (scene->_field412) {
+ case 1: {
+ scene->_sceneMode = 2752;
+ scene->setAction(&scene->_sequenceManager, scene, 2752, &R2_GLOBALS._player, NULL);
+ break;
+ }
+ case 2: {
+ Common::Point pt(140, 142);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, scene);
+ break;
+ }
+ case 3: {
+ Common::Point pt(210, 142);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, scene);
+ break;
+ }
+ default:
+ break;
+ }
+ }
+}
+
+void Scene2750::Area2::process(Event &event) {
+ SceneArea::process(event);
+ if ((event.eventType == EVENT_BUTTON_DOWN) && (R2_GLOBALS._player._canWalk) && (_bounds.contains(event.mousePos))) {
+ Scene2750 *scene = (Scene2750 *)R2_GLOBALS._sceneManager._scene;
+ R2_GLOBALS._player.disableControl();
+ scene->_sceneMode = 10;
+ scene->_field414 = 2753;
+ switch (scene->_field412) {
+ case 1: {
+ Common::Point pt(140, 142);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, scene);
+ break;
+ }
+ case 2: {
+ Common::Point pt(210, 142);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, scene);
+ break;
+ }
+ case 3: {
+ scene->_sceneMode = 2753;
+ scene->setAction(&scene->_sequenceManager, scene, 2753, &R2_GLOBALS._player, NULL);
+ break;
+ }
+ default:
+ break;
+ }
+ }
+}
+
+void Scene2750::postInit(SceneObjectList *OwnerList) {
+ loadScene(2750);
+ R2_GLOBALS._sound2.stop();
+ SceneExt::postInit();
+ _area1.setDetails(Rect(0, 90, 20, 135), EXITCURSOR_W);
+ _area2.setDetails(Rect(300, 90, 320, 135), EXITCURSOR_E);
+
+ _rect1.set(30, 127, 155, 147);
+ _rect2.set(130, 142, 210, 167);
+ _rect3.set(-1, 137, 290, 147);
+
+ if (R2_INVENTORY.getObjectScene(36) == 0) {
+ R2_GLOBALS._sound1.changeSound(235);
+ _actor2.postInit();
+ _actor2.setup(2751, 1, 1);
+ _actor2.setPosition(Common::Point(104, 158));
+ _actor2.animate(ANIM_MODE_2, NULL);
+ }
+
+ _actor3.postInit();
+ _actor3.setup(2750, 1, 1);
+ _actor3.setPosition(Common::Point(188, 34));
+ _actor3.animate(ANIM_MODE_2, NULL);
+ _actor3._numFrames = 16;
+
+ _actor4.postInit();
+ _actor4.setup(2700, 4, 1);
+ _actor4.setPosition(Common::Point(188, 37));
+ _actor4.fixPriority(26);
+
+ _actor5.postInit();
+ _actor5.setup(2750, 2, 1);
+ _actor5.setPosition(Common::Point(188, 34));
+ _actor5.hide();
+
+ _actor3.setAction(&_action1);
+
+ _actor6.postInit();
+ _actor6.setup(2750, 3, 1);
+ _actor6.setPosition(Common::Point(9, 167));
+ _actor6.fixPriority(252);
+ _actor6.setAction(&_action2);
+
+ _actor7.postInit();
+ _actor7.setup(2750, 4, 1);
+ _actor7.setPosition(Common::Point(-10, 25));
+ _actor7.animate(ANIM_MODE_1, NULL);
+ _actor7.setStrip2(4);
+ _actor7._moveRate = 20;
+ _actor7.setAction(&_action3);
+
+ _actor8.postInit();
+ _actor8.fixPriority(26);
+ _actor8.setup(2750, 5, 1);
+ _actor8.setPosition(Common::Point(258, 33));
+ _actor8.setAction(&_action4);
+
+ _actor9.postInit();
+ _actor9.fixPriority(26);
+ _actor9.setup(2750, 6, 1);
+ _actor9.setPosition(Common::Point(61, 38));
+ _actor9.setAction(&_action5);
+
+ _actor10.postInit();
+ _actor10.fixPriority(26);
+ _actor10.setup(2750, 7, 1);
+ _actor10.setPosition(Common::Point(69, 37));
+ _actor10.setAction(&_action6);
+
+ _actor11.postInit();
+ _actor11.fixPriority(26);
+ _actor11.setup(2750, 8, 1);
+ _actor11.setPosition(Common::Point(80, 35));
+ _actor11.setAction(&_action7);
+
+ _item2.setDetails(Rect(29, 50, 35, 56), 2750, 3, -1, 5, 1, NULL);
+ _item3.setDetails(Rect(47, 36, 54, 42), 2750, 3, -1, 5, 1, NULL);
+ _item4.setDetails(Rect(193, 21, 206, 34), 2750, 3, -1, 5, 1, NULL);
+ _item5.setDetails(Rect(301, 18, 315, 32), 2750, 3, -1, 5, 1, NULL);
+ _item1.setDetails(Rect(0, 0, 320, 200), 2700, 0, -1, 2, 1, NULL);
+
+ _stripManager.setColors(60, 255);
+ _stripManager.setFontNumber(3);
+ _stripManager.addSpeaker(&_quinnSpeaker);
+ _stripManager.addSpeaker(&_nejSpeaker);
+
+ if (R2_INVENTORY.getObjectScene(36) == 0) {
+ _actor1.postInit();
+ _actor1.setup(2752, 5, 1);
+ _actor1.animate(ANIM_MODE_NONE, NULL);
+ _actor1.setPosition(Common::Point(101, 148));
+ }
+
+ R2_GLOBALS._player.postInit();
+ R2_GLOBALS._player.setVisage(19);
+ R2_GLOBALS._player.animate(ANIM_MODE_1, NULL);
+ R2_GLOBALS._player._moveDiff = Common::Point(2, 2);
+ R2_GLOBALS._player.disableControl();
+
+ if (R2_GLOBALS._sceneManager._previousScene == 2700) {
+ if (R2_INVENTORY.getObjectScene(36) == 0) {
+ R2_GLOBALS._player.setVisage(2752);
+ R2_GLOBALS._player.setStrip(6);
+ R2_GLOBALS._player.animate(ANIM_MODE_NONE, NULL);
+ R2_GLOBALS._player.setPosition(Common::Point(81, 165));
+ R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
+ _field416 = 1204;
+ _sceneMode = 11;
+ _stripManager.start(_field416, this);
+ } else {
+ _sceneMode = 2750;
+ _field412 = 1;
+ R2_GLOBALS._player.setAction(&_sequenceManager, this, 2750, &R2_GLOBALS._player, NULL);
+ }
+ } else if (R2_GLOBALS._sceneManager._previousScene == 2800) {
+ _sceneMode = 2751;
+ _field412 = 3;
+ R2_GLOBALS._player.setAction(&_sequenceManager, this, 2751, &R2_GLOBALS._player, NULL);
+ } else {
+ _field412 = 1;
+ R2_GLOBALS._player.setPosition(Common::Point(90, 137));
+ R2_GLOBALS._player.setStrip(3);
+ R2_GLOBALS._player.enableControl();
+ }
+}
+void Scene2750::signal() {
+ switch (_sceneMode) {
+ case 10:
+ switch (_field414) {
+ case 1:
+ switch (_field412) {
+ case 2: {
+ _sceneMode = _field414;
+ _field412 = 1;
+ Common::Point pt(90, 137);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, this);
+ }
+ break;
+ case 3: {
+ _field412 = 2;
+ Common::Point pt(140, 142);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, this);
+ }
+ break;
+ default:
+ break;
+ }
+ break;
+ case 2: {
+ _sceneMode = _field414;
+ _field412 = 2;
+ Common::Point pt(170, 162);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, this);
+ }
+ break;
+ case 3:
+ switch (_field412) {
+ case 1: {
+ _field412 = 2;
+ Common::Point pt(210, 142);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, this);
+ }
+ break;
+ case 2: {
+ _sceneMode = _field414;
+ _field412 = 3;
+ Common::Point pt(270, 142);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, this);
+ }
+ break;
+ default:
+ break;
+ }
+ break;
+ case 2752:
+ switch (_field412) {
+ case 1:
+ _sceneMode = _field414;
+ setAction(&_sequenceManager, this, 2752, &R2_GLOBALS._player, NULL);
+ break;
+ case 2: {
+ _field412 = 1;
+ Common::Point pt(20, 132);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, this);
+ }
+ break;
+ case 3: {
+ _field412 = 2;
+ Common::Point pt(140, 142);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, this);
+ }
+ break;
+ default:
+ break;
+ }
+ break;
+ case 2753:
+ switch (_field412) {
+ case 1: {
+ _field412 = 2;
+ Common::Point pt(210, 142);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, this);
+ }
+ break;
+ case 2: {
+ _field412 = 3;
+ Common::Point pt(300, 132);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, this);
+ }
+ break;
+ case 3:
+ _sceneMode = _field414;
+ setAction(&_sequenceManager, this, 2753, &R2_GLOBALS._player, NULL);
+ break;
+ default:
+ break;
+ }
+ break;
+ default:
+ break;
+ }
+ break;
+ case 11:
+ // No break on purpose
+ case 2753:
+ g_globals->_sceneManager.changeScene(2800);
+ break;
+ case 2752:
+ g_globals->_sceneManager.changeScene(2700);
+ break;
+ default:
+ R2_GLOBALS._player.enableControl(R2_NEGATOR_GUN);
+ break;
+ }
+}
+
+void Scene2750::process(Event &event) {
+ if ((R2_GLOBALS._player._canWalk) && (event.eventType == EVENT_BUTTON_DOWN) && (R2_GLOBALS._events.getCursor() == R2_NEGATOR_GUN)) {
+ if (_rect1.contains(event.mousePos)) {
+ if (!_rect1.contains(R2_GLOBALS._player._position)) {
+ event.handled = true;
+ _sceneMode = 10;
+ _field414 = 1;
+ }
+ } else if (_rect2.contains(event.mousePos)) {
+ if (!_rect2.contains(R2_GLOBALS._player._position)) {
+ event.handled = true;
+ _sceneMode = 10;
+ _field414 = 2;
+ }
+ } else if (_rect3.contains(event.mousePos)) {
+ if (!_rect3.contains(R2_GLOBALS._player._position)) {
+ event.handled = true;
+ _sceneMode = 10;
+ _field414 = 3;
+ }
+ } else {
+ event.handled = true;
+ R2_GLOBALS._player.updateAngle(Common::Point(event.mousePos.x, event.mousePos.y));
+ }
+
+ if (_sceneMode == 10) {
+ R2_GLOBALS._player.disableControl();
+ switch (_field412) {
+ case 1: {
+ Common::Point pt(140, 142);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, this);
+ }
+ break;
+ case 2:
+ if (_field414 == 1) {
+ Common::Point pt(140, 142);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, this);
+ } else {
+ Common::Point pt(210, 142);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, this);
+ }
+ break;
+ case 3: {
+ Common::Point pt(210, 142);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, this);
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ Scene::process(event);
+}
+
+/*--------------------------------------------------------------------------
+ * Scene 2800 - Exiting forest
+ *
+ *--------------------------------------------------------------------------*/
+Scene2800::Scene2800(): SceneExt() {
+ _field412 = 0;
+}
+
+void Scene2800::synchronize(Serializer &s) {
+ SceneExt::synchronize(s);
+
+ s.syncAsSint16LE(_field412);
+}
+
+bool Scene2800::Item2::startAction(CursorType action, Event &event) {
+ Scene2800 *scene = (Scene2800 *)R2_GLOBALS._sceneManager._scene;
+
+ if ((action == CURSOR_USE) && (R2_GLOBALS.getFlag(47))) {
+ R2_GLOBALS._player.disableControl();
+ scene->_sceneMode = 2805;
+ scene->setAction(&scene->_sequenceManager, scene, 2805, &R2_GLOBALS._player, NULL);
+ return true;
+ } else
+ return SceneHotspot::startAction(action, event);
+}
+
+bool Scene2800::Actor1::startAction(CursorType action, Event &event) {
+ Scene2800 *scene = (Scene2800 *)R2_GLOBALS._sceneManager._scene;
+
+ if (action == CURSOR_TALK) {
+ R2_GLOBALS._player.disableControl();
+ R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
+ R2_GLOBALS.setFlag(47);
+ scene->_field412 = 1205;
+ scene->_sceneMode = 2803;
+ scene->_stripManager.start(scene->_field412, scene);
+ return true;
+ } else if (action == R2_SONIC_STUNNER) {
+ R2_GLOBALS._events.setCursor(CURSOR_ARROW);
+ R2_GLOBALS._player.disableControl();
+ R2_GLOBALS.setFlag(47);
+ scene->_sceneMode = 10;
+ scene->setAction(&scene->_sequenceManager, scene, 2802, &R2_GLOBALS._player, &scene->_actor2, &scene->_actor1, NULL);
+ return true;
+ } else
+ return SceneActor::startAction(action, event);
+}
+
+void Scene2800::Action1::signal() {
+ Scene2800 *scene = (Scene2800 *)R2_GLOBALS._sceneManager._scene;
+
+ if (R2_GLOBALS._player._position.x <= 320) {
+ setDelay(120);
+ Common::Point pt(330, 25);
+ NpcMover *mover = new NpcMover();
+ scene->_object1.addMover(mover, &pt, NULL);
+ } else {
+ setDelay(1800 + R2_GLOBALS._randomSource.getRandomNumber(600));
+ scene->_object1.setPosition(Common::Point(-10, 45));
+ }
+}
+
+void Scene2800::Action2::signal() {
+ Scene2800 *scene = (Scene2800 *)R2_GLOBALS._sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0:
+ setDelay(240);
+ R2_GLOBALS._sound1.changeSound(240);
+ R2_GLOBALS._sound2.stop();
+ break;
+ case 1:
+ _object2.postInit();
+ _object2.setVisage(2800);
+ _object2.setStrip(1);
+ _object2._numFrames = 8;
+ _object2._moveRate = 8;
+ _object2.changeZoom(100);
+ _object2.setPosition(Common::Point(1, 1));
+ _object2.show();
+ _object2.animate(ANIM_MODE_5, this);
+ break;
+ case 2:
+ R2_GLOBALS._sound2.play(130);
+ _object2.setVisage(2800);
+ _object2.setStrip(7);
+
+ _object3.postInit();
+ _object3.setVisage(2800);
+ _object3.setStrip(3);
+ _object3._numFrames = 8;
+ _object3._moveRate = 8;
+ _object3.changeZoom(100);
+ _object3.setPosition(Common::Point(300, 104));
+ _object3.show();
+ _object3.animate(ANIM_MODE_5, this);
+ break;
+ case 3:
+ R2_GLOBALS._sound1.play(241);
+ _object4.postInit();
+ _object4.setVisage(2800);
+ _object4.setStrip(2);
+ _object4._numFrames = 4;
+ _object4._moveRate = 4;
+ _object4.changeZoom(100);
+ _object4.setPosition(Common::Point(300, 104));
+ _object4.fixPriority(105);
+ _object4.show();
+ _object4.animate(ANIM_MODE_5, this);
+ break;
+ case 4:
+ setDelay(18);
+ _object4.setStrip(4);
+ scene->_actor1.setVisage(2800);
+ scene->_actor1.setStrip(5);
+ scene->_actor1.setFrame(1);
+ scene->_actor1._numFrames = 5;
+ scene->_actor1._moveRate = 5;
+ scene->_actor1.setPosition(Common::Point(300, 104));
+ scene->_actor1.fixPriority(110);
+ scene->_actor1.changeZoom(100);
+ scene->_actor1.show();
+ break;
+ case 5:
+ scene->_actor1.animate(ANIM_MODE_5, this);
+ break;
+ case 6: {
+ scene->_actor1.changeZoom(-1);
+ scene->_actor1.setVisage(3107);
+ scene->_actor1.animate(ANIM_MODE_1, NULL);
+ scene->_actor1.setStrip(3);
+ scene->_actor1.setPosition(Common::Point(297, 140));
+ scene->_actor1._numFrames = 10;
+ scene->_actor1._moveRate = 10;
+ scene->_actor1._moveDiff = Common::Point(3, 2);
+
+ Common::Point pt(297, 160);
+ NpcMover *mover = new NpcMover();
+ scene->_actor1.addMover(mover, &pt, this);
+ break;
+ }
+ case 7: {
+ scene->_actor1.changeZoom(75);
+ scene->_actor1.updateAngle(R2_GLOBALS._player._position);
+
+ Common::Point pt(105, 82);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, this);
+ break;
+ }
+ case 8: {
+ R2_GLOBALS._player._numFrames = 8;
+ R2_GLOBALS._player._moveRate = 8;
+ R2_GLOBALS._player.animate(ANIM_MODE_2, NULL);
+ R2_GLOBALS._player.setObjectWrapper(NULL);
+ R2_GLOBALS._player.setStrip(2);
+ R2_GLOBALS._player.changeZoom(-1);
+
+ Common::Point pt(79, 100);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, this);
+ break;
+ }
+ case 9: {
+ R2_GLOBALS._player._numFrames = 10;
+ R2_GLOBALS._player._moveRate = 10;
+ R2_GLOBALS._player.animate(ANIM_MODE_1, NULL);
+ R2_GLOBALS._player.setObjectWrapper(new SceneObjectWrapper());
+
+ Common::Point pt(100, 64);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, this);
+ break;
+ }
+ case 10: {
+ R2_GLOBALS._player.fixPriority(124);
+ R2_GLOBALS._player._moveDiff = Common::Point(3, 2);
+
+ Common::Point pt(160, 124);
+ PlayerMover *mover = new PlayerMover();
+ R2_GLOBALS._player.addMover(mover, &pt, this);
+ break;
+ }
+ case 11: {
+ R2_GLOBALS._player.fixPriority(-1);
+
+ Common::Point pt(160, 160);
+ PlayerMover *mover = new PlayerMover();
+ R2_GLOBALS._player.addMover(mover, &pt, this);
+ break;
+ }
+ case 12: {
+ Common::Point pt(270, 160);
+ PlayerMover *mover = new PlayerMover();
+ R2_GLOBALS._player.addMover(mover, &pt, this);
+ break;
+ }
+ case 13:
+ R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
+ scene->_field412 = 1207;
+ scene->_stripManager.start(scene->_field412, this);
+ break;
+ case 14: {
+ R2_GLOBALS._player.disableControl();
+ R2_GLOBALS._player.fixPriority(110);
+
+ Common::Point pt(288, 140);
+ PlayerMover *mover = new PlayerMover();
+ R2_GLOBALS._player.addMover(mover, &pt, this);
+ break;
+ }
+ case 15:
+ setDelay(18);
+ scene->_actor1.updateAngle(R2_GLOBALS._player._position);
+ R2_GLOBALS._player.setVisage(2800);
+ R2_GLOBALS._player.setStrip(6);
+ R2_GLOBALS._player.setFrame(1);
+ R2_GLOBALS._player.changeZoom(100);
+ R2_GLOBALS._player.setPosition(Common::Point(300, 104));
+ R2_GLOBALS._player._numFrames = 5;
+ R2_GLOBALS._player._moveRate = 5;
+ break;
+ case 16:
+ R2_GLOBALS._player.animate(ANIM_MODE_5, this);
+ break;
+ case 17:
+ setDelay(6);
+ _object4.setStrip(2);
+ _object4.setFrame(11);
+ R2_GLOBALS._player.hide();
+ // No break on purpose
+ case 18:
+ R2_GLOBALS._sound1.play(241);
+ _object4.animate(ANIM_MODE_6, this);
+ break;
+ case 19:
+ _object4.remove();
+ _object3.animate(ANIM_MODE_6, this);
+ break;
+ case 20:
+ setDelay(6);
+ _object3.remove();
+ _object2.setStrip(1);
+ _object2.setFrame(19);
+ break;
+ case 21:
+ setDelay(150);
+ R2_GLOBALS._sound1.play(269);
+ R2_GLOBALS._sound2.stop();
+ break;
+ case 22:
+ scene->_sceneMode = 12;
+ _object2.animate(ANIM_MODE_6, scene);
+ break;
+ default:
+ break;
+ }
+}
+
+void Scene2800::postInit(SceneObjectList *OwnerList) {
+ loadScene(2800);
+ setZoomPercents(100, 50, 124, 75);
+ R2_GLOBALS._sound1.stop();
+ R2_GLOBALS._sound2.stop();
+ SceneExt::postInit();
+
+ _object1.postInit();
+ _object1.setup(2750, 4, 1);
+ _object1.setPosition(Common::Point(-10, 25));
+ _object1.animate(ANIM_MODE_1, NULL);
+ _object1.setStrip2(4);
+ _object1._moveRate = 20;
+ _object1.setAction(&_action1);
+
+ _actor3.postInit();
+ _actor3.setup(2802, 1, 1);
+ _actor3.setPosition(Common::Point(116, 80));
+ _actor3.fixPriority(111);
+ _actor3.animate(ANIM_MODE_2, NULL);
+ _actor3._numFrames = 6;
+
+ if (!R2_GLOBALS.getFlag(47)) {
+ _actor1.postInit();
+ _actor1.setVisage(3105);
+ _actor1.setStrip(3);
+ _actor1.setFrame(1);
+ _actor1.setZoom(50);
+ _actor1._moveDiff = Common::Point(2, 1);
+ _actor1.setPosition(Common::Point(122, 82));
+ _actor1.animate(ANIM_MODE_NONE, NULL);
+ _actor1.setDetails(2800, -1, -1, -1, 1, (SceneItem *)NULL);
+ }
+
+ _item1.setDetails(Rect(0, 0, 320, 200), 2800, -1, -1, -1, 1, NULL);
+
+ _stripManager.setColors(60, 255);
+ _stripManager.setFontNumber(3);
+ _stripManager.addSpeaker(&_quinnSpeaker);
+ _stripManager.addSpeaker(&_nejSpeaker);
+ _stripManager.addSpeaker(&_guardSpeaker);
+
+ if (R2_INVENTORY.getObjectScene(36) == 0) {
+ R2_GLOBALS._sound1.fadeSound(237);
+ if (R2_GLOBALS.getFlag(47)) {
+ _item2.setDetails(Rect(76, 45, 155, 90), 2800, 3, -1, -1, 2, NULL);
+ } else {
+ _actor2.postInit();
+ _actor2.setup(2752, 5, 1);
+ _actor2.animate(ANIM_MODE_NONE, NULL);
+ _actor2.changeZoom(100);
+ _actor2._moveDiff = Common::Point(2, 1);
+ _actor2.setPosition(Common::Point(101, 148));
+ }
+ }
+
+ R2_GLOBALS._player.postInit();
+ R2_GLOBALS._player.setVisage(19);
+ R2_GLOBALS._player.animate(ANIM_MODE_1, NULL);
+ R2_GLOBALS._player.changeZoom(100);
+ R2_GLOBALS._player._moveDiff = Common::Point(2, 2);
+ R2_GLOBALS._player.disableControl();
+
+ if (R2_INVENTORY.getObjectScene(36) == 0) {
+ R2_GLOBALS._player.setAction(&_sequenceManager, this, 2800, &R2_GLOBALS._player, NULL);
+ } else if (R2_GLOBALS.getFlag(47)) {
+ R2_GLOBALS._player.setVisage(3110);
+ R2_GLOBALS._player.changeZoom(-1);
+ R2_GLOBALS._player._moveDiff = Common::Point(3, 2);
+ R2_GLOBALS._player.setPosition(Common::Point(160, 124));
+ R2_GLOBALS._player.enableControl();
+ } else {
+ _sceneMode = 2801;
+ R2_GLOBALS._player.setAction(&_sequenceManager, this, 2801, &R2_GLOBALS._player, &_actor2, &_actor1, NULL);
+ }
+}
+
+void Scene2800::signal() {
+ switch (_sceneMode) {
+ case 10:
+ R2_GLOBALS._sound1.play(238);
+ R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
+ _field412 = 1206;
+ _sceneMode = 2804;
+ _stripManager.start(_field412, this);
+ break;
+ case 11:
+ _actor2.remove();
+ _object1.setAction(NULL);
+ R2_GLOBALS._player.enableControl(CURSOR_ARROW);
+ R2_GLOBALS._player._moveDiff = Common::Point(3, 2);
+ _item2.setDetails(Rect(76, 45, 155, 90), 2800, 3, -1, -1, 2, NULL);
+ break;
+ case 12:
+ R2_GLOBALS._sound1.fadeOut2(NULL);
+ R2_GLOBALS._sound2.fadeOut2(NULL);
+ g_globals->_sceneManager.changeScene(1000);
+ break;
+ case 2800:
+ g_globals->_sceneManager.changeScene(2750);
+ break;
+ case 2801:
+ R2_GLOBALS._player.enableControl(CURSOR_ARROW);
+ R2_GLOBALS._player._canWalk = false;
+ break;
+ case 2803:
+ R2_GLOBALS._player.disableControl();
+ _sceneMode = 10;
+ setAction(&_sequenceManager, this, 2803, &R2_GLOBALS._player, &_actor2, &_actor1, NULL);
+ break;
+ case 2804:
+ R2_GLOBALS._player.disableControl();
+ _sceneMode = 11;
+ setAction(&_sequenceManager, this, 2804, &R2_GLOBALS._player, &_actor2, NULL);
+ break;
+ case 2805:
+ _object1.remove();
+ setAction(&_action2);
+ break;
+ default:
+ break;
+ }
+}
+
+} // End of namespace Ringworld2
+} // End of namespace TsAGE
diff --git a/engines/tsage/ringworld2/ringworld2_scenes2.h b/engines/tsage/ringworld2/ringworld2_scenes2.h
new file mode 100644
index 0000000000..281d1da366
--- /dev/null
+++ b/engines/tsage/ringworld2/ringworld2_scenes2.h
@@ -0,0 +1,672 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef TSAGE_RINGWORLD2_SCENES2_H
+#define TSAGE_RINGWORLD2_SCENES2_H
+
+#include "common/scummsys.h"
+#include "tsage/converse.h"
+#include "tsage/events.h"
+#include "tsage/core.h"
+#include "tsage/scenes.h"
+#include "tsage/globals.h"
+#include "tsage/sound.h"
+#include "tsage/ringworld2/ringworld2_logic.h"
+#include "tsage/ringworld2/ringworld2_speakers.h"
+
+namespace TsAGE {
+
+namespace Ringworld2 {
+
+using namespace TsAGE;
+
+class Scene2000 : public SceneExt {
+ class Action1 : public ActionExt {
+ public:
+ virtual void signal();
+ };
+
+ class Exit1 : public SceneExit {
+ public:
+ virtual void changeScene();
+ };
+ class Exit2 : public SceneExit {
+ public:
+ virtual void changeScene();
+ };
+ class Exit3 : public SceneExit {
+ public:
+ virtual void changeScene();
+ };
+ class Exit4 : public SceneExit {
+ public:
+ virtual void changeScene();
+ };
+ class Exit5 : public SceneExit {
+ public:
+ virtual void changeScene();
+ };
+public:
+ bool _exitingFlag;
+ int _mazePlayerMode;
+
+ NamedHotspot _item1;
+ SceneActor _object1;
+ SceneActor _objList1[11];
+ Exit1 _exit1;
+ Exit2 _exit2;
+ Exit3 _exit3;
+ Exit4 _exit4;
+ Exit5 _exit5;
+ Action1 _action1, _action2, _action3, _action4, _action5;
+ SequenceManager _sequenceManager;
+
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+ virtual void remove();
+ virtual void signal();
+ virtual void process(Event &event);
+ virtual void synchronize(Serializer &s);
+
+ void initExits();
+ void initPlayer();
+};
+
+class Scene2350 : public SceneExt {
+ class Actor2 : public SceneActor {
+ virtual bool startAction(CursorType action, Event &event);
+ };
+ class Actor3 : public SceneActor {
+ virtual bool startAction(CursorType action, Event &event);
+ };
+
+ class ExitUp : public SceneExit {
+ virtual void changeScene();
+ };
+ class ExitWest : public SceneExit {
+ virtual void changeScene();
+ };
+public:
+
+ SpeakerQuinn _quinnSpeaker;
+ SpeakerPharisha _pharishaSpeaker;
+ NamedHotspot _item1;
+ SceneActor _actor1;
+ Actor2 _actor2;
+ Actor3 _actor3;
+ Actor3 _actor4;
+ ExitUp _exitUp;
+ ExitWest _exitWest;
+ SequenceManager _sequenceManager;
+
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+ virtual void remove();
+ virtual void signal();
+ virtual void process(Event &event);
+};
+
+class Scene2400 : public SceneExt {
+ class Exit1 : public SceneExit {
+ virtual void changeScene();
+ };
+ class Exit2 : public SceneExit {
+ virtual void changeScene();
+ };
+public:
+ Exit1 _exit1;
+ Exit2 _exit2;
+ SequenceManager _sequenceManager;
+
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+ virtual void signal();
+};
+
+class Scene2425 : public SceneExt {
+ class Item1 : public NamedHotspot {
+ public:
+ virtual bool startAction(CursorType action, Event &event);
+ };
+ class Item2 : public NamedHotspot {
+ public:
+ virtual bool startAction(CursorType action, Event &event);
+ };
+ class Item3 : public NamedHotspot {
+ public:
+ virtual bool startAction(CursorType action, Event &event);
+ };
+ class Item4 : public NamedHotspot {
+ public:
+ virtual bool startAction(CursorType action, Event &event);
+ };
+
+ class Actor1 : public SceneActor {
+ public:
+ bool startAction(CursorType action, Event &event);
+ };
+ class Actor2 : public SceneActor {
+ public:
+ bool startAction(CursorType action, Event &event);
+ };
+
+ class Exit1 : public SceneExit {
+ public:
+ virtual void changeScene();
+ };
+public:
+ Item1 _item1;
+ Item2 _item2;
+ Item3 _item3;
+ Item4 _item4;
+ Actor1 _actor1;
+ Actor2 _actor2;
+ Actor2 _actor3;
+ Exit1 _exit1;
+ SequenceManager _sequenceManager;
+
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+ virtual void remove();
+ virtual void signal();
+};
+
+class Scene2430 : public SceneExt {
+ class Actor1 : public SceneActor {
+ public:
+ bool startAction(CursorType action, Event &event);
+ };
+ class Actor2 : public SceneActor {
+ public:
+ bool startAction(CursorType action, Event &event);
+ };
+ class Actor3 : public SceneActor {
+ public:
+ bool startAction(CursorType action, Event &event);
+ };
+
+ class Exit1 : public SceneExit {
+ public:
+ virtual void changeScene();
+ };
+public:
+ NamedHotspot _item1;
+ NamedHotspot _item2;
+ NamedHotspot _item3;
+ NamedHotspot _item4;
+ NamedHotspot _item5;
+ NamedHotspot _item6;
+ NamedHotspot _item7;
+ NamedHotspot _item8;
+ NamedHotspot _item9;
+ NamedHotspot _item10;
+ NamedHotspot _item11;
+ NamedHotspot _item12;
+ NamedHotspot _item13;
+ Actor1 _actor1;
+ Actor2 _actor2;
+ Actor3 _actor3;
+ Exit1 _exit1;
+ SequenceManager _sequenceManager;
+
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+ virtual void signal();
+};
+
+class Scene2435 : public SceneExt {
+ class Actor1 : public SceneActor {
+ public:
+ bool startAction(CursorType action, Event &event);
+ };
+ class Actor2 : public SceneActor {
+ public:
+ bool startAction(CursorType action, Event &event);
+ };
+
+ class Exit1 : public SceneExit {
+ public:
+ virtual void changeScene();
+ };
+public:
+ SpeakerQuinn2435 _quinnSpeaker;
+ SpeakerSeeker2435 _seekerSpeaker;
+ SpeakerPharisha2435 _pharishaSpeaker;
+ NamedHotspot _item1;
+ NamedHotspot _item2;
+ NamedHotspot _item3;
+ Actor1 _actor1;
+ Actor2 _actor2;
+ Exit1 _exit1;
+ SequenceManager _sequenceManager;
+
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+ virtual void remove();
+ virtual void signal();
+};
+
+class Scene2440 : public SceneExt {
+ class Actor1 : public SceneActor {
+ public:
+ bool startAction(CursorType action, Event &event);
+ };
+ class Actor2 : public SceneActor {
+ public:
+ bool startAction(CursorType action, Event &event);
+ };
+
+ class Exit1 : public SceneExit {
+ public:
+ virtual void changeScene();
+ };
+public:
+ NamedHotspot _item1;
+ NamedHotspot _item2;
+ NamedHotspot _item3;
+ NamedHotspot _item4;
+ NamedHotspot _item5;
+ NamedHotspot _item6;
+ NamedHotspot _item7;
+ Actor1 _actor1;
+ Actor2 _actor2;
+ Exit1 _exit1;
+ SequenceManager _sequenceManager;
+
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+ virtual void remove();
+ virtual void signal();
+};
+
+class Scene2445 : public SceneExt {
+public:
+ SequenceManager _sequenceManager;
+
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+ virtual void signal();
+};
+
+class Scene2450 : public SceneExt {
+ class Actor2 : public SceneActor {
+ public:
+ bool startAction(CursorType action, Event &event);
+ };
+ class Actor3 : public SceneActor {
+ public:
+ bool startAction(CursorType action, Event &event);
+ };
+
+ class Exit1 : public SceneExit {
+ public:
+ virtual void changeScene();
+ };
+public:
+ SpeakerQuinn2450 _quinnSpeaker;
+ SpeakerSeeker2450 _seekerSpeaker;
+ SpeakerCaretaker2450 _caretakerSpeaker;
+ NamedHotspot _item1;
+ NamedHotspot _item2;
+ NamedHotspot _item3;
+ SceneActor _actor1;
+ Actor2 _actor2;
+ Actor3 _actor3;
+ Exit1 _exit1;
+ SequenceManager _sequenceManager;
+
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+ virtual void remove();
+ virtual void signal();
+};
+
+class Scene2455 : public SceneExt {
+ class Actor1 : public SceneActor {
+ public:
+ bool startAction(CursorType action, Event &event);
+ };
+ class Actor2 : public SceneActor {
+ public:
+ bool startAction(CursorType action, Event &event);
+ };
+ class Actor3 : public SceneActor {
+ public:
+ bool startAction(CursorType action, Event &event);
+ };
+
+ class Exit1 : public SceneExit {
+ public:
+ virtual void changeScene();
+ };
+public:
+ NamedHotspot _item1;
+ Actor1 _actor1;
+ Actor2 _actor2;
+ Actor3 _actor3;
+ Exit1 _exit1;
+ SequenceManager _sequenceManager;
+
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+ virtual void remove();
+ virtual void signal();
+};
+
+class Scene2500 : public SceneExt {
+ class Exit1 : public SceneExit {
+ public:
+ virtual void changeScene();
+ };
+public:
+ SpeakerQuinn _quinnSpeaker;
+ SpeakerSeeker _seekerSpeaker;
+ SpeakerMiranda _mirandaSpeaker;
+ SpeakerWebbster2500 _webbsterSpeaker;
+ NamedHotspot _item1;
+ SceneActor _actor1;
+ SceneActor _actor2;
+ SceneActor _actor3;
+ Exit1 _exit1;
+ SequenceManager _sequenceManager;
+
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+ virtual void signal();
+};
+
+class Scene2525 : public SceneExt {
+ class Item5 : public NamedHotspot {
+ public:
+ virtual bool startAction(CursorType action, Event &event);
+ };
+
+ class Actor3 : public SceneActor {
+ public:
+ bool startAction(CursorType action, Event &event);
+ };
+
+ class Exit1 : public SceneExit {
+ public:
+ virtual void changeScene();
+ };
+public:
+ NamedHotspot _item1;
+ NamedHotspot _item2;
+ NamedHotspot _item3;
+ NamedHotspot _item4;
+ Item5 _item5;
+ SceneActor _actor1;
+ SceneActor _actor2;
+ Actor3 _actor3;
+ Exit1 _exit1;
+ SequenceManager _sequenceManager;
+
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+ virtual void remove();
+ virtual void signal();
+};
+
+class Scene2530 : public SceneExt {
+ class Actor2 : public SceneActor {
+ public:
+ bool startAction(CursorType action, Event &event);
+ };
+ class Actor3 : public SceneActor {
+ public:
+ bool startAction(CursorType action, Event &event);
+ };
+
+ class Exit1 : public SceneExit {
+ public:
+ virtual void changeScene();
+ };
+public:
+ NamedHotspot _item1;
+ NamedHotspot _item2;
+ NamedHotspot _item3;
+ NamedHotspot _item4;
+ NamedHotspot _item5;
+ SceneActor _actor1;
+ Actor2 _actor2;
+ Actor3 _actor3;
+ Exit1 _exit1;
+ SequenceManager _sequenceManager;
+
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+ virtual void signal();
+};
+
+class Scene2535 : public SceneExt {
+ class Actor3 : public SceneActor {
+ public:
+ bool startAction(CursorType action, Event &event);
+ };
+ class Actor4 : public SceneActor {
+ public:
+ bool startAction(CursorType action, Event &event);
+ };
+
+ class Exit1 : public SceneExit {
+ public:
+ virtual void changeScene();
+ };
+public:
+ NamedHotspot _item1;
+ NamedHotspot _item2;
+ NamedHotspot _item3;
+ NamedHotspot _item4;
+ NamedHotspot _item5;
+ NamedHotspot _item6;
+ NamedHotspot _item7;
+ SceneActor _actor1;
+ SceneActor _actor2;
+ Actor3 _actor3;
+ Actor4 _actor4;
+ Exit1 _exit1;
+ SequenceManager _sequenceManager;
+
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+ virtual void signal();
+};
+
+class Scene2600 : public SceneExt {
+public:
+ SequenceManager _sequenceManager;
+ PaletteRotation *_rotation;
+
+ Scene2600();
+ virtual void synchronize(Serializer &s);
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+ virtual void remove();
+ virtual void signal();
+};
+
+class Scene2700 : public SceneExt {
+ class Action1: public Action {
+ public:
+ void signal();
+ };
+ class Action2: public Action {
+ public:
+ void signal();
+ };
+ class Action3: public Action {
+ public:
+ void signal();
+ };
+ class Action4: public Action {
+ public:
+ void signal();
+ };
+
+ class Area1: public SceneArea {
+ public:
+ void process(Event &event);
+ };
+ class Area2: public SceneArea {
+ public:
+ void process(Event &event);
+ };
+public:
+ SpeakerQuinn2700 _quinnSpeaker;
+ SpeakerNej2700 _nejSpeaker;
+ NamedHotspot _item1;
+ NamedHotspot _item2;
+ NamedHotspot _item3;
+ NamedHotspot _item4;
+ NamedHotspot _item5;
+ NamedHotspot _item6;
+ SceneActor _actor1;
+ SceneActor _actor2;
+ SceneActor _actor3;
+ SceneActor _actor4;
+ SceneActor _actor5;
+ Action1 _action1;
+ Action2 _action2;
+ Action3 _action3;
+ Action4 _action4;
+ Area1 _area1;
+ Area2 _area2;
+ Rect _rect1, _rect2, _rect3, _rect4, _rect5, _rect6;
+ SequenceManager _sequenceManager;
+ int _field412, _field414, _field416;
+
+ Scene2700();
+ virtual void synchronize(Serializer &s);
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+ virtual void signal();
+ virtual void process(Event &event);
+};
+
+class Scene2750 : public SceneExt {
+ class Action1: public Action {
+ public:
+ void signal();
+ };
+ class Action2: public Action {
+ public:
+ void signal();
+ };
+ class Action3: public Action {
+ public:
+ void signal();
+ };
+ class Action4: public Action {
+ public:
+ void signal();
+ };
+ class Action5: public Action {
+ public:
+ void signal();
+ };
+ class Action6: public Action {
+ public:
+ void signal();
+ };
+ class Action7: public Action {
+ public:
+ void signal();
+ };
+
+ class Area1: public SceneArea {
+ public:
+ void process(Event &event);
+ };
+ class Area2: public SceneArea {
+ public:
+ void process(Event &event);
+ };
+public:
+ SpeakerQuinn2750 _quinnSpeaker;
+ SpeakerNej2750 _nejSpeaker;
+ NamedHotspot _item1;
+ NamedHotspot _item2;
+ NamedHotspot _item3;
+ NamedHotspot _item4;
+ NamedHotspot _item5;
+ SceneActor _actor1;
+ SceneActor _actor2;
+ SceneActor _actor3;
+ SceneActor _actor4;
+ SceneActor _actor5;
+ SceneActor _actor6;
+ SceneActor _actor7;
+ SceneActor _actor8;
+ SceneActor _actor9;
+ SceneActor _actor10;
+ SceneActor _actor11;
+ Action1 _action1;
+ Action2 _action2;
+ Action3 _action3;
+ Action4 _action4;
+ Action5 _action5;
+ Action6 _action6;
+ Action7 _action7;
+ Area1 _area1;
+ Area2 _area2;
+ Rect _rect1, _rect2, _rect3;
+ SequenceManager _sequenceManager;
+ int _field412, _field414, _field416;
+
+ Scene2750();
+ virtual void synchronize(Serializer &s);
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+ virtual void signal();
+ virtual void process(Event &event);
+};
+
+class Scene2800 : public SceneExt {
+ class Item2 : public NamedHotspot {
+ public:
+ virtual bool startAction(CursorType action, Event &event);
+ };
+
+ class Actor1 : public SceneActor {
+ virtual bool startAction(CursorType action, Event &event);
+ };
+
+ class Action1: public Action {
+ public:
+ void signal();
+ };
+ class Action2: public Action {
+ SceneObject _object2;
+ SceneObject _object3;
+ SceneObject _object4;
+ public:
+ void signal();
+ };
+public:
+ SpeakerQuinn2800 _quinnSpeaker;
+ SpeakerNej2800 _nejSpeaker;
+ SpeakerGuard2800 _guardSpeaker;
+ NamedHotspot _item1;
+ Item2 _item2;
+ Actor1 _actor1;
+ SceneActor _actor2;
+ SceneActor _actor3;
+ SceneObject _object1;
+ Action1 _action1;
+ Action2 _action2;
+ SequenceManager _sequenceManager;
+ int _field412;
+
+ Scene2800();
+ virtual void synchronize(Serializer &s);
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+ virtual void signal();
+};
+
+} // End of namespace Ringworld2
+} // End of namespace TsAGE
+
+#endif
diff --git a/engines/tsage/ringworld2/ringworld2_scenes3.cpp b/engines/tsage/ringworld2/ringworld2_scenes3.cpp
new file mode 100644
index 0000000000..3dd566c900
--- /dev/null
+++ b/engines/tsage/ringworld2/ringworld2_scenes3.cpp
@@ -0,0 +1,5603 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "tsage/scenes.h"
+#include "tsage/tsage.h"
+#include "tsage/staticres.h"
+#include "tsage/ringworld2/ringworld2_scenes3.h"
+
+namespace TsAGE {
+
+namespace Ringworld2 {
+
+/*--------------------------------------------------------------------------
+ * Scene 3100 -
+ *
+ *--------------------------------------------------------------------------*/
+Scene3100::Scene3100() {
+ _field412 = 0;
+}
+
+void Scene3100::synchronize(Serializer &s) {
+ SceneExt::synchronize(s);
+
+ s.syncAsSint16LE(_field412);
+}
+
+bool Scene3100::Guard::startAction(CursorType action, Event &event) {
+ if (action != CURSOR_TALK)
+ return SceneActor::startAction(action, event);
+
+ Scene3100 *scene = (Scene3100 *)R2_GLOBALS._sceneManager._scene;
+
+ R2_GLOBALS._player.disableControl();
+ scene->_sceneMode = 10;
+ R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
+ scene->_stripManager.start(606, scene);
+ return true;
+}
+
+void Scene3100::postInit(SceneObjectList *OwnerList) {
+ if (R2_GLOBALS._sceneManager._previousScene == 1000) {
+ if (R2_GLOBALS._player._oldCharacterScene[1] == 3100) {
+ loadScene(3101);
+ R2_GLOBALS._uiElements._active = false;
+ } else {
+ loadScene(3100);
+ g_globals->gfxManager()._bounds.moveTo(Common::Point(160, 0));
+ }
+ } else {
+ loadScene(3100);
+ }
+ // Original was doing it twice in a row. Skipped.
+
+ if (R2_GLOBALS._sceneManager._previousScene == 3255)
+ R2_GLOBALS._uiElements._active = false;
+
+ SceneExt::postInit();
+ _stripManager.addSpeaker(&_guardSpeaker);
+
+ if (R2_GLOBALS._sceneManager._previousScene == -1)
+ R2_GLOBALS._sceneManager._previousScene = 1000;
+
+ R2_GLOBALS._player.postInit();
+ R2_GLOBALS._player._characterIndex = R2_QUINN;
+ R2_GLOBALS._player.disableControl();
+
+ _actor1.postInit();
+ _item2.setDetails(Rect(212, 97, 320, 114), 3100, 3, -1, -1, 1, NULL);
+ _item1.setDetails(Rect(0, 0, 480, 200), 3100, 0, -1, -1, 1, NULL);
+ _field412 = 0;
+
+ if (R2_GLOBALS._sceneManager._previousScene == 1000) {
+ if (R2_GLOBALS._player._oldCharacterScene[1] == 3100) {
+ _sceneMode = 3102;
+ _actor3.postInit();
+ _actor4.postInit();
+ _actor5.postInit();
+ R2_GLOBALS._sound1.play(274);
+ _sound1.fadeSound(130);
+ setAction(&_sequenceManager, this, 3102, &_actor1, &R2_GLOBALS._player, &_actor3, &_actor4, &_actor5, NULL);
+ } else {
+ _guard.postInit();
+ _guard.setup(3110, 5, 1);
+ _guard.changeZoom(50);
+ _guard.setPosition(Common::Point(10, 149));
+ _guard.setDetails(3100, 6, -1, -1, 2, (SceneItem *)NULL);
+
+ _actor4.postInit();
+ _actor4.setup(3103, 1, 1);
+ _actor4.setPosition(Common::Point(278, 113));
+ _actor4.setDetails(3100, 9, -1, -1, 2, (SceneItem *)NULL);
+ _actor4.animate(ANIM_MODE_2, NULL);
+
+ _field412 = 1;
+ _actor1.setDetails(3100, 3, -1, -1, 2, (SceneItem *)NULL);
+ R2_GLOBALS._sound1.play(243);
+ R2_GLOBALS._sound2.play(130);
+ _sceneMode = 3100;
+
+ setAction(&_sequenceManager, this, 3100, &R2_GLOBALS._player, &_actor1, NULL);
+ }
+ } else if (R2_GLOBALS._sceneManager._previousScene == 3255) {
+ _sceneMode = 3101;
+ _actor2.postInit();
+ _actor3.postInit();
+ _field412 = 1;
+
+ setAction(&_sequenceManager, this, 3101, &R2_GLOBALS._player, &_actor1, &_actor2, &_actor3, NULL);
+ } else {
+ _guard.postInit();
+ _guard.setup(3110, 5, 1);
+ _guard.changeZoom(50);
+ _guard.setPosition(Common::Point(10, 149));
+ _guard.setDetails(3100, 6, -1, -1, 2, (SceneItem *)NULL);
+
+ _actor4.postInit();
+ _actor4.setup(3103, 1, 1);
+ _actor4.setPosition(Common::Point(278, 113));
+ _actor4.setDetails(3100, 9, -1, -1, 2, (SceneItem *)NULL);
+ _actor4.animate(ANIM_MODE_2, NULL);
+
+ _actor1.postInit();
+ _actor1.setup(3104, 4, 1);
+ _actor1.setPosition(Common::Point(143, 104));
+ _actor1.setDetails(3100, 3, -1, -1, 2, (SceneItem *)NULL);
+
+ R2_GLOBALS._player.setup(3110, 3, 1);
+ R2_GLOBALS._player.changeZoom(50);
+ R2_GLOBALS._player.animate(ANIM_MODE_1, NULL);
+ R2_GLOBALS._player.setPosition(Common::Point(160, 150));
+ R2_GLOBALS._player._moveDiff = Common::Point(3, 2);
+ R2_GLOBALS._player.enableControl(CURSOR_ARROW);
+
+ R2_GLOBALS._sound1.play(243);
+ }
+
+ R2_GLOBALS._player._oldCharacterScene[1] = 3100;
+}
+
+void Scene3100::remove() {
+ R2_GLOBALS._scrollFollower = &R2_GLOBALS._player;
+ R2_GLOBALS._sound1.fadeOut2(NULL);
+ R2_GLOBALS._sound2.fadeOut2(NULL);
+ _sound1.fadeOut2(NULL);
+ SceneExt::remove();
+}
+
+void Scene3100::signal() {
+ switch (_sceneMode) {
+ case 10:
+ R2_GLOBALS._player.enableControl(CURSOR_TALK);
+ break;
+ case 3100:
+ R2_GLOBALS._player._moveDiff = Common::Point(3, 2);
+ R2_GLOBALS._scrollFollower = &R2_GLOBALS._player;
+ R2_GLOBALS._player.enableControl(CURSOR_ARROW);
+ break;
+ case 3101:
+ R2_GLOBALS._sceneManager.changeScene(1000);
+ break;
+ case 3102:
+ R2_GLOBALS._player._oldCharacterScene[1] = 1000;
+ R2_GLOBALS._sceneManager.changeScene(1000);
+ break;
+ default:
+ R2_GLOBALS._player.enableControl(CURSOR_ARROW);
+ break;
+ }
+}
+
+void Scene3100::dispatch() {
+ if ((_sceneMode == 3100) && (_field412 != 0) && (R2_GLOBALS._player._position.y == 104)) {
+ _field412 = 0;
+ R2_GLOBALS._sound2.fadeOut2(NULL);
+ }
+
+ if ((_sceneMode == 3101) && (_field412 != 0) && (R2_GLOBALS._player._position.y < 104)) {
+ _field412 = 0;
+ _sound1.fadeSound(130);
+ }
+
+ Scene::dispatch();
+}
+
+/*--------------------------------------------------------------------------
+ * Scene 3125 - Ghouls dormitory
+ *
+ *--------------------------------------------------------------------------*/
+Scene3125::Scene3125() {
+ _field412 = 0;
+}
+
+void Scene3125::synchronize(Serializer &s) {
+ SceneExt::synchronize(s);
+
+ s.syncAsSint16LE(_field412);
+}
+
+bool Scene3125::Item1::startAction(CursorType action, Event &event) {
+ Scene3125 *scene = (Scene3125 *)R2_GLOBALS._sceneManager._scene;
+
+ switch (action) {
+ case CURSOR_USE:
+ if (_useLineNum != -1)
+ SceneItem::display(_resNum, _useLineNum, 0, 280, 1, 160, 9, 1, 2, 20, 7, 154, -999);
+ break;
+ case CURSOR_LOOK:
+ if (_lookLineNum != -1)
+ SceneItem::display(_resNum, _lookLineNum, 0, 280, 1, 160, 9, 1, 2, 20, 7, 154, -999);
+ break;
+ case CURSOR_TALK:
+ if (_talkLineNum != -1)
+ SceneItem::display(_resNum, _talkLineNum, 0, 280, 1, 160, 9, 1, 2, 20, 7, 154, -999);
+ break;
+ default:
+ return scene->display(action, event);
+ break;
+ }
+
+ return true;
+}
+
+bool Scene3125::Item2::startAction(CursorType action, Event &event) {
+ Scene3125 *scene = (Scene3125 *)R2_GLOBALS._sceneManager._scene;
+
+ switch (action) {
+ case CURSOR_USE:
+ R2_GLOBALS._player.disableControl();
+ scene->_sceneMode = 3125;
+ scene->setAction(&scene->_sequenceManager1, scene, 3125, &R2_GLOBALS._player, NULL);
+ break;
+ case CURSOR_LOOK:
+ SceneItem::display(3125, 15, 0, 280, 1, 160, 9, 1, 2, 20, 7, 154, -999);
+ break;
+ case CURSOR_TALK:
+ SceneItem::display(3125, 13, 0, 280, 1, 160, 9, 1, 2, 20, 7, 154, -999);
+ break;
+ default:
+ return SceneHotspot::startAction(action, event);
+ break;
+ }
+
+ return true;
+}
+
+bool Scene3125::Item3::startAction(CursorType action, Event &event) {
+ Scene3125 *scene = (Scene3125 *)R2_GLOBALS._sceneManager._scene;
+
+ switch (action) {
+ case CURSOR_USE:
+ R2_GLOBALS._player.disableControl();
+ scene->_actor5.postInit();
+ scene->_sceneMode = 3126;
+ scene->setAction(&scene->_sequenceManager1, scene, 3126, &R2_GLOBALS._player, &scene->_actor2, &scene->_actor3, &scene->_actor4, &scene->_actor1, &scene->_actor5, NULL);
+ break;
+ case CURSOR_LOOK:
+ SceneItem::display(3125, 9, 0, 280, 1, 160, 9, 1, 2, 20, 7, 154, -999);
+ break;
+ case CURSOR_TALK:
+ SceneItem::display(3125, 13, 0, 280, 1, 160, 9, 1, 2, 20, 7, 154, -999);
+ break;
+ default:
+ return SceneHotspot::startAction(action, event);
+ break;
+ }
+
+ return true;
+}
+
+bool Scene3125::Actor1::startAction(CursorType action, Event &event) {
+ Scene3125 *scene = (Scene3125 *)R2_GLOBALS._sceneManager._scene;
+
+ if (action != CURSOR_USE)
+ return SceneActor::startAction(action, event);
+
+ R2_GLOBALS._player.disableControl();
+ scene->_sceneMode = 3176;
+ scene->setAction(&scene->_sequenceManager1, scene, 3176, &R2_GLOBALS._player, &scene->_actor1, NULL);
+ return true;
+}
+
+void Scene3125::postInit(SceneObjectList *OwnerList) {
+ loadScene(3125);
+ SceneExt::postInit();
+ _field412 = 0;
+
+ _actor1.postInit();
+ _actor1.setup(3175, 1, 1);
+ _actor1.setPosition(Common::Point(35, 72));
+ _actor1.setDetails(3125, 12, 13, -1, 1, (SceneItem *)NULL);
+
+ _actor2.postInit();
+ _actor2.setup(3126, 4, 1);
+ _actor2.setPosition(Common::Point(71, 110));
+ _actor2._numFrames = 20;
+
+ _actor3.postInit();
+ _actor3.setup(3126, 1, 1);
+ _actor3.setPosition(Common::Point(215, 62));
+ _actor3.fixPriority(71);
+
+ _actor4.postInit();
+ _actor4.setup(3126, 1, 1);
+ _actor4.setPosition(Common::Point(171, 160));
+ _actor4.fixPriority(201);
+
+ _item3.setDetails(12, 3125, 9, 13, -1);
+ _item2.setDetails(11, 3125, 15, 13, -1);
+ _item1.setDetails(Rect(0, 0, 320, 200), 3125, 0, 1, 2, 1, NULL);
+
+ R2_GLOBALS._sound1.play(262);
+ R2_GLOBALS._player.postInit();
+
+ if (R2_GLOBALS._player._oldCharacterScene[3] == 3250) {
+ _sceneMode = 3175;
+ setAction(&_sequenceManager1, this, 3175, &R2_GLOBALS._player, &_actor1, NULL);
+ } else {
+ R2_GLOBALS._player.setup(30, 5, 1);
+ R2_GLOBALS._player.animate(ANIM_MODE_1, NULL);
+ R2_GLOBALS._player.setPosition(Common::Point(89, 76));
+ R2_GLOBALS._player.enableControl();
+ }
+ R2_GLOBALS._player._oldCharacterScene[3] = 3125;
+}
+
+void Scene3125::signal() {
+ switch (_sceneMode) {
+ case 3125:
+ SceneItem::display(3125, 3, 0, 280, 1, 160, 9, 1, 2, 20, 7, 154, -999);
+ _sceneMode = 3127;
+ setAction(&_sequenceManager1, this, 3127, &R2_GLOBALS._player, NULL);
+ break;
+ case 3126:
+ R2_GLOBALS.setFlag(79);
+ // No break on purpose
+ case 3176:
+ R2_GLOBALS._sceneManager.changeScene(3250);
+ break;
+ default:
+ R2_GLOBALS._player.enableControl();
+ break;
+ }
+}
+
+void Scene3125::dispatch() {
+ if ((_sceneMode == 3126) && (_actor2._frame == 2) && (_field412 == 0)) {
+ _field412 = 1;
+ R2_GLOBALS._sound1.play(265);
+ }
+ Scene::dispatch();
+}
+
+/*--------------------------------------------------------------------------
+ * Scene 3150 - Jail
+ *
+ *--------------------------------------------------------------------------*/
+bool Scene3150::Item5::startAction(CursorType action, Event &event) {
+ Scene3150 *scene = (Scene3150 *)R2_GLOBALS._sceneManager._scene;
+
+ switch (action) {
+ case CURSOR_USE:
+ if (R2_INVENTORY.getObjectScene(47) != 3150)
+ return SceneHotspot::startAction(action, event);
+
+ R2_GLOBALS._player.disableControl();
+ scene->_sceneMode = 3154;
+ scene->setAction(&scene->_sequenceManager, scene, 3154, &R2_GLOBALS._player, &scene->_actor3, NULL);
+ return true;
+ case R2_SUPERCONDUCTOR_WIRE:
+ if ((R2_INVENTORY.getObjectScene(47) != 3150) && (R2_GLOBALS.getFlag(75))) {
+ R2_GLOBALS._player.disableControl();
+ scene->_actor3.postInit();
+ scene->_actor3._effect = 3;
+ scene->_actor3._shade = 5;
+ scene->_sceneMode = 3155;
+ scene->setAction(&scene->_sequenceManager, scene, 3155, &R2_GLOBALS._player, &scene->_actor3, NULL);
+ } else {
+ SceneItem::display(3150, 42, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
+ }
+ return true;
+ default:
+ return SceneHotspot::startAction(action, event);
+ break;
+ }
+}
+
+bool Scene3150::Item6::startAction(CursorType action, Event &event) {
+ Scene3150 *scene = (Scene3150 *)R2_GLOBALS._sceneManager._scene;
+
+ switch (action) {
+ case R2_PILLOW:
+ R2_GLOBALS._player.disableControl();
+ scene->_actor4.postInit();
+ scene->_actor4._effect = 6;
+ scene->_actor4._shade = 3;
+ R2_GLOBALS._player.disableControl();
+ scene->_sceneMode = 3158;
+ scene->setAction(&scene->_sequenceManager, scene, 3158, &R2_GLOBALS._player, &scene->_actor4, NULL);
+ return true;
+ case R2_FOOD_TRAY:
+ if ((R2_INVENTORY.getObjectScene(47) != 3150) && (R2_INVENTORY.getObjectScene(40) == 3150) && (R2_GLOBALS.getFlag(75))) {
+ scene->_actor5.postInit();
+ scene->_actor5._effect = 6;
+ scene->_actor5._shade = 3;
+ scene->_actor5.setDetails(3150, 30, -1, -1, 2, (SceneItem *)NULL);
+
+ R2_GLOBALS._player.disableControl();
+ scene->_sceneMode = 3159;
+ scene->setAction(&scene->_sequenceManager, scene, 3159, &R2_GLOBALS._player, &scene->_actor5, NULL);
+ } else {
+ SceneItem::display(3150, 42, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
+ }
+ default:
+ return SceneHotspot::startAction(action, event);
+ break;
+ }
+}
+
+bool Scene3150::Actor4::startAction(CursorType action, Event &event) {
+ Scene3150 *scene = (Scene3150 *)R2_GLOBALS._sceneManager._scene;
+
+ switch (action) {
+ case CURSOR_USE:
+ if (R2_GLOBALS.getFlag(75))
+ return SceneActor::startAction(action, event);
+
+ R2_GLOBALS._player.disableControl();
+ scene->_sceneMode = 3151;
+ scene->setAction(&scene->_sequenceManager, scene, 3151, &R2_GLOBALS._player, &scene->_actor4, NULL);
+ return true;
+ case R2_FOOD_TRAY:
+ return false;
+ default:
+ return SceneActor::startAction(action, event);
+ break;
+ }
+}
+
+bool Scene3150::Actor5::startAction(CursorType action, Event &event) {
+ Scene3150 *scene = (Scene3150 *)R2_GLOBALS._sceneManager._scene;
+
+ if ((action != CURSOR_USE) || (R2_GLOBALS.getFlag(77)))
+ return SceneActor::startAction(action ,event);
+
+ R2_GLOBALS._player.disableControl();
+ scene->_sceneMode = 3157;
+ scene->setAction(&scene->_sequenceManager, scene, 3157, &R2_GLOBALS._player, &scene->_actor5, NULL);
+ return true;
+}
+
+bool Scene3150::Actor6::startAction(CursorType action, Event &event) {
+ Scene3150 *scene = (Scene3150 *)R2_GLOBALS._sceneManager._scene;
+
+ if (action == CURSOR_USE) {
+ if (R2_GLOBALS.getFlag(75)) {
+ if (R2_GLOBALS.getFlag(77)) {
+ R2_GLOBALS._player.disableControl();
+ if (R2_GLOBALS.getFlag(76)) {
+ scene->_sceneMode = 3152;
+ scene->setAction(&scene->_sequenceManager, scene, 3152, &R2_GLOBALS._player, NULL);
+ } else {
+ scene->_sceneMode = 3153;
+ scene->setAction(&scene->_sequenceManager, scene, 3152, &R2_GLOBALS._player, &scene->_actor4, NULL);
+ }
+ } else {
+ SceneItem::display(3150, 42, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
+ }
+ } else {
+ R2_GLOBALS._player.disableControl();
+ scene->_sceneMode = 3152;
+ scene->setAction(&scene->_sequenceManager, scene, 3152, &R2_GLOBALS._player, NULL);
+ }
+ return true;
+ } else {
+ return SceneActor::startAction(action, event);
+ }
+}
+
+bool Scene3150::Actor7::startAction(CursorType action, Event &event) {
+ Scene3150 *scene = (Scene3150 *)R2_GLOBALS._sceneManager._scene;
+
+ if ((action == R2_LASER_HACKSAW) && (!R2_GLOBALS.getFlag(80))) {
+ R2_GLOBALS._player.disableControl();
+ scene->_sceneMode = 3160;
+ scene->setAction(&scene->_sequenceManager, scene, 3160, &R2_GLOBALS._player, &scene->_actor7, NULL);
+ return true;
+ }
+
+ return SceneActor::startAction(action, event);
+}
+
+void Scene3150::Exit1::changeScene() {
+ Scene3150 *scene = (Scene3150 *)R2_GLOBALS._sceneManager._scene;
+
+ _enabled = false;
+ g_globals->_events.setCursor(CURSOR_ARROW);
+ R2_GLOBALS._player.disableControl();
+ scene->_sceneMode = 11;
+
+ Common::Point pt(-20, 180);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, scene);
+}
+
+void Scene3150::Exit2::changeScene() {
+ Scene3150 *scene = (Scene3150 *)R2_GLOBALS._sceneManager._scene;
+
+ _enabled = false;
+ g_globals->_events.setCursor(CURSOR_ARROW);
+ R2_GLOBALS._player.disableControl();
+ scene->_sceneMode = 12;
+
+ scene->setAction(&scene->_sequenceManager, scene, 3163, &R2_GLOBALS._player, NULL);
+}
+
+void Scene3150::postInit(SceneObjectList *OwnerList) {
+ loadScene(3150);
+ if (R2_GLOBALS._sceneManager._previousScene == -1) {
+ R2_INVENTORY.setObjectScene(35, 2000);
+ R2_GLOBALS._player._oldCharacterScene[1] = 3100;
+ R2_GLOBALS._player._oldCharacterScene[3] = 0;
+ R2_GLOBALS._player._characterIndex = R2_MIRANDA;
+ }
+ SceneExt::postInit();
+
+ if (R2_GLOBALS.getFlag(78)) {
+ _exit1.setDetails(Rect(0, 135, 60, 168), EXITCURSOR_SW, 3275);
+ _exit1.setDest(Common::Point(70, 125));
+ }
+
+ if (R2_GLOBALS.getFlag(80)) {
+ _exit2.setDetails(Rect(249, 36, 279, 60), EXITCURSOR_NE, 3150);
+ _exit2.setDest(Common::Point(241, 106));
+ }
+
+ R2_GLOBALS._player.postInit();
+ R2_GLOBALS._player.disableControl();
+
+ _actor2.postInit();
+ _actor2.setPosition(Common::Point(64, 139));
+ if (R2_GLOBALS.getFlag(78)) {
+ _actor2.setup(3151, 1, 5);
+ _actor2.fixPriority(125);
+ } else {
+ _actor2.setup(3151, 1, 1);
+ _actor2.setDetails(3150, 8, -1, 9, 1, (SceneItem *)NULL);
+ }
+
+ if (R2_GLOBALS.getFlag(78)) {
+ _actor1.postInit();
+ _actor1.setup(3154, 1, 16);
+ _actor1.setPosition(Common::Point(104, 129));
+ _actor1._effect = 6;
+ _actor1._shade = 3;
+ _actor1.setDetails(3150, 24, -1, -1, -1, (SceneItem *)NULL);
+ }
+
+ _actor7.postInit();
+ _actor7.setup(3154, 5, 1);
+ if (R2_GLOBALS.getFlag(80))
+ _actor7.setPosition(Common::Point(264, 108));
+ else
+ _actor7.setPosition(Common::Point(264, 58));
+ _actor7.fixPriority(50);
+ _actor7.setDetails(3150, 17, -1, 19, 1, (SceneItem *)NULL);
+
+ if (R2_INVENTORY.getObjectScene(41) == 3150) {
+ _actor4.postInit();
+ if (R2_GLOBALS.getFlag(75)) {
+ if (R2_GLOBALS.getFlag(76)) {
+ R2_GLOBALS._walkRegions.enableRegion(1);
+ R2_GLOBALS._walkRegions.enableRegion(4);
+ R2_GLOBALS._walkRegions.enableRegion(5);
+ R2_GLOBALS._walkRegions.enableRegion(6);
+ _actor4.setup(3152, 4, 10);
+ _actor4.setDetails(3150, 14, -1, -1, 1, (SceneItem *)NULL);
+ } else {
+ _actor4.setup(3152, 7, 4);
+ _actor4.setDetails(3150, 13, -1, -1, 1, (SceneItem *)NULL);
+ }
+ _actor4.fixPriority(110);
+ _actor4.setPosition(Common::Point(83, 88));
+ _actor4._effect = 6;
+ _actor4._shade = 3;
+ } else {
+ _actor4.setup(3152, 7, 3);
+ _actor4.setPosition(Common::Point(143, 70));
+ _actor4.setDetails(3150, 15, -1, -1, 1, (SceneItem *)NULL);
+ }
+ }
+
+ if (R2_INVENTORY.getObjectScene(47) == 3150) {
+ _actor3.postInit();
+ _actor3.setup(3152, 7, 1);
+ _actor3.setPosition(Common::Point(73, 83));
+ }
+
+ if (R2_INVENTORY.getObjectScene(40) == 3150) {
+ _actor3.postInit();
+ _actor3.setup(3152, 7, 3);
+ _actor3.setPosition(Common::Point(70, 55));
+ _actor3.fixPriority(111);
+ _actor3._effect = 6;
+ _actor3._shade = 5;
+ }
+
+ if (R2_INVENTORY.getObjectScene(42) == 3150) {
+ _actor5.postInit();
+ if (R2_GLOBALS.getFlag(77)) {
+ _actor5.setup(3152, 7, 8);
+ _actor5.setPosition(Common::Point(82, 92));
+ _actor5.fixPriority(111);
+ _actor5._effect = 6;
+ _actor5._shade = 3;
+ } else {
+ _actor5.setup(3152, 7, 7);
+ _actor5.setPosition(Common::Point(155, 79));
+ }
+ _actor5.setDetails(3150, 30, -1, -1, 2, (SceneItem *)NULL);
+ }
+
+ _actor6.postInit();
+ _actor6.setup(3152, 7, 6);
+ _actor6.setPosition(Common::Point(98, 73));
+ _actor6.setDetails(3150, 43, -1, -1, 1, (SceneItem *)NULL);
+
+ _item2.setDetails(12, 3150, 10, -1, 12);
+ _item3.setDetails(Rect(186, 17, 210, 36), 3150, 6, -1, -1, 1, NULL);
+ _item4.setDetails(Rect(61, 21, 92, 41), 3150, 7, -1, -1, 1, NULL);
+ _item5.setDetails(Rect(63, 48, 78, 58), 3150, 6, -1, -1, 1, NULL);
+ _item6.setDetails(Rect(63, 81, 100, 95), 3150, 3, 4, -1, 1, NULL);
+ _item1.setDetails(Rect(0, 0, 200, 320), 3150, 0, 1, 2, 1, NULL);
+
+ switch (R2_GLOBALS._player._oldCharacterScene[3]) {
+ case 0:
+ _sceneMode = 3150;
+ _actor1.postInit();
+ _actor1._effect = 6;
+ _actor1._shade = 5;
+ setAction(&_sequenceManager, this, 3150, &R2_GLOBALS._player, &_actor1, &_actor2, NULL);
+ break;
+ case 1200:
+ _sceneMode = 3162;
+ setAction(&_sequenceManager, this, 3162, &R2_GLOBALS._player, NULL);
+ break;
+ case 3275: {
+ _sceneMode = 10;
+ R2_GLOBALS._player.setup(30, 3, 1);
+ R2_GLOBALS._player.animate(ANIM_MODE_1, NULL);
+ R2_GLOBALS._player.setPosition(Common::Point(-20, 180));
+ R2_GLOBALS._player._moveDiff = Common::Point(3, 2);
+
+ Common::Point pt(80, 125);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, this);
+ break;
+ }
+ default:
+ if ((R2_GLOBALS._v56AA0 == 1) && (R2_INVENTORY.getObjectScene(35) == 2000) && (R2_GLOBALS._player._oldCharacterScene[1] == 3100)) {
+ ++R2_GLOBALS._v56AA0;
+ _sceneMode = 3156;
+ _actor1.postInit();
+ _actor1._effect = 6;
+ _actor1._shade = 3;
+
+ _actor2.postInit();
+ _actor5.postInit();
+ _actor5._effect = 6;
+ _actor5._shade = 3;
+
+ setAction(&_sequenceManager, this, 3156, &R2_GLOBALS._player, &_actor1, &_actor2, &_actor5, NULL);
+ } else {
+ if (R2_GLOBALS._v56AA0 != 2)
+ ++R2_GLOBALS._v56AA0;
+
+ R2_GLOBALS._player.setup(30, 3, 1);
+ R2_GLOBALS._player.animate(ANIM_MODE_1, NULL);
+ R2_GLOBALS._player.setPosition(Common::Point(155, 120));
+ R2_GLOBALS._player._moveDiff = Common::Point(3, 2);
+ R2_GLOBALS._player.enableControl();
+ }
+ }
+
+ R2_GLOBALS._player._oldCharacterScene[3] = 3150;
+}
+
+void Scene3150::signal() {
+ switch (_sceneMode) {
+ case 11:
+ R2_GLOBALS._sceneManager.changeScene(3275);
+ break;
+ case 12:
+ R2_GLOBALS._sceneManager.changeScene(1200);
+ break;
+ case 3151:
+ _actor1.remove();
+ R2_INVENTORY.setObjectScene(41, 3);
+ R2_GLOBALS._player.enableControl();
+ break;
+ case 3153:
+ R2_GLOBALS.setFlag(76);
+ _actor4.setDetails(3150, 14, -1, -1, 3, (SceneItem *)NULL);
+ _actor1.postInit();
+ _actor1.setDetails(3150, 24, -1, -1, 2, (SceneItem *)NULL);
+ _sceneMode = 3161;
+ setAction(&_sequenceManager, this, 3161, &_actor1, &_actor2, NULL);
+ break;
+ case 3154:
+ _actor3.remove();
+ R2_INVENTORY.setObjectScene(47, 3);
+ R2_GLOBALS._player.enableControl();
+ break;
+ case 3155:
+ R2_INVENTORY.setObjectScene(40, 3150);
+ R2_GLOBALS._player.enableControl();
+ break;
+ case 3156:
+ _actor5.setDetails(3150, 30, -1, -1, 2, (SceneItem *)NULL);
+ R2_INVENTORY.setObjectScene(42, 3150);
+ R2_GLOBALS._player.enableControl();
+ break;
+ case 3157:
+ _actor5.remove();
+ R2_INVENTORY.setObjectScene(42, 3);
+ R2_GLOBALS._player.enableControl();
+ break;
+ case 3158:
+ R2_GLOBALS.setFlag(75);
+ R2_INVENTORY.setObjectScene(41, 3150);
+ _actor4.fixPriority(110);
+ _actor4.setDetails(3150, 13, -1, -1, 2, (SceneItem *)NULL);
+ R2_GLOBALS._player.enableControl();
+ break;
+ case 3159:
+ R2_GLOBALS.setFlag(77);
+ R2_INVENTORY.setObjectScene(42, 3150);
+ R2_GLOBALS._player.enableControl();
+ break;
+ case 3160:
+ R2_INVENTORY.setObjectScene(52, 3150);
+ R2_GLOBALS.setFlag(80);
+ R2_GLOBALS._sceneManager.changeScene(1200);
+ break;
+ case 3161:
+ R2_GLOBALS._sceneItems.remove(&_actor2);
+ _exit1.setDetails(Rect(0, 135, 60, 168), EXITCURSOR_SW, 3275);
+ _exit1.setDest(Common::Point(70, 125));
+ R2_GLOBALS._walkRegions.enableRegion(1);
+ R2_GLOBALS._walkRegions.enableRegion(4);
+ R2_GLOBALS._walkRegions.enableRegion(5);
+ R2_GLOBALS._walkRegions.enableRegion(6);
+ R2_GLOBALS.setFlag(78);
+ R2_GLOBALS._player.enableControl();
+ break;
+ default:
+ R2_GLOBALS._player.enableControl();
+ break;
+ }
+}
+
+void Scene3150::dispatch() {
+ if (_actor5._position.x == 155) {
+ _actor5._effect = 0;
+ _actor5._shade = 0;
+ }
+
+ if (_actor1._visage == 3154) {
+ _actor1._effect = 0;
+ _actor1._shade = 0;
+ }
+
+ Scene::dispatch();
+}
+
+/*--------------------------------------------------------------------------
+ * Scene 3175 - Autopsy room
+ *
+ *--------------------------------------------------------------------------*/
+bool Scene3175::Item1::startAction(CursorType action, Event &event) {
+ Scene3175 *scene = (Scene3175 *)R2_GLOBALS._sceneManager._scene;
+
+ switch (action) {
+ case CURSOR_USE:
+ if (_useLineNum != -1) {
+ SceneItem::display(_resNum, _useLineNum, 0, 280, 1, 160, 9, 1, 2, 20, 7, 154, -999);
+ return true;
+ }
+ break;
+ case CURSOR_LOOK:
+ if (_lookLineNum != -1) {
+ SceneItem::display(_resNum, _lookLineNum, 0, 280, 1, 160, 9, 1, 2, 20, 7, 154, -999);
+ return true;
+ }
+ break;
+ case CURSOR_TALK:
+ if (_talkLineNum != -1) {
+ SceneItem::display(_resNum, _talkLineNum, 0, 280, 1, 160, 9, 1, 2, 20, 7, 154, -999);
+ return true;
+ }
+ break;
+ default:
+ break;
+ }
+
+ return scene->display(action, event);
+}
+
+bool Scene3175::Actor3::startAction(CursorType action, Event &event) {
+ Scene3175 *scene = (Scene3175 *)R2_GLOBALS._sceneManager._scene;
+
+ switch (action) {
+ case CURSOR_USE:
+ if (_useLineNum != -1) {
+ SceneItem::display(_resNum, _useLineNum, 0, 280, 1, 160, 9, 1, 2, 20, 7, 154, -999);
+ return true;
+ }
+ break;
+ case CURSOR_LOOK:
+ if (_lookLineNum != -1) {
+ SceneItem::display(_resNum, _lookLineNum, 0, 280, 1, 160, 9, 1, 2, 20, 7, 154, -999);
+ return true;
+ }
+ break;
+ case CURSOR_TALK:
+ if (_talkLineNum != -1) {
+ SceneItem::display(_resNum, _talkLineNum, 0, 280, 1, 160, 9, 1, 2, 20, 7, 154, -999);
+ return true;
+ }
+ break;
+ default:
+ break;
+ }
+
+ return scene->display(action, event);
+}
+
+bool Scene3175::Actor1::startAction(CursorType action, Event &event) {
+ Scene3175 *scene = (Scene3175 *)R2_GLOBALS._sceneManager._scene;
+
+ switch (action) {
+ case CURSOR_USE:
+ R2_GLOBALS._player.disableControl();
+ scene->_sceneMode = 3176;
+ scene->setAction(&scene->_sequenceManager, scene, 3176, &R2_GLOBALS._player, &scene->_actor1, NULL);
+ return true;
+ break;
+ case CURSOR_LOOK:
+ SceneItem::display(3175, 9, 0, 280, 1, 160, 9, 1, 2, 20, 7, 154, -999);
+ return true;
+ break;
+ case CURSOR_TALK:
+ SceneItem::display(3175, 10, 0, 280, 1, 160, 9, 1, 2, 20, 7, 154, -999);
+ return true;
+ break;
+ default:
+ return SceneActor::startAction(action, event);
+ break;
+ }
+}
+
+void Scene3175::postInit(SceneObjectList *OwnerList) {
+ loadScene(3175);
+ SceneExt::postInit();
+
+ _actor1.postInit();
+ _actor1.setup(3175, 1, 1);
+ _actor1.setPosition(Common::Point(35, 72));
+ _actor1.setDetails(3175, 9, 10, -1, 1, (SceneItem *)NULL);
+
+ _actor2.postInit();
+ _actor2.setup(3175, 2, 1);
+ _actor2.setPosition(Common::Point(87, 148));
+
+ _actor3.postInit();
+ _actor3.setup(3175, 3, 1);
+ _actor3.setPosition(Common::Point(199, 117));
+ _actor3.setDetails(3175, 15, 16, 17, 1, (SceneItem *)NULL);
+
+ _item2.setDetails(12, 3175, 3, 1, 5);
+ _item3.setDetails(11, 3175, 6, 7, 8);
+ _item1.setDetails(Rect(0, 0, 320, 200), 3175, 0, 1, 2, 1, NULL);
+
+ R2_GLOBALS._player.postInit();
+
+ if (R2_GLOBALS._player._oldCharacterScene[3] == 3250) {
+ R2_GLOBALS._player.setup(30, 5, 1);
+ R2_GLOBALS._player.animate(ANIM_MODE_1, NULL);
+ R2_GLOBALS._player.setPosition(Common::Point(126, 77));
+ R2_GLOBALS._player.enableControl();
+ } else {
+ _sceneMode = 3175;
+ setAction(&_sequenceManager, this, 3175, &R2_GLOBALS._player, &_actor1, NULL);
+ }
+
+ R2_GLOBALS._player._oldCharacterScene[3] = 3175;
+}
+
+void Scene3175::signal() {
+ if (_sceneMode == 3176)
+ R2_GLOBALS._sceneManager.changeScene(3250);
+ else
+ R2_GLOBALS._player.enableControl();
+}
+
+/*--------------------------------------------------------------------------
+ * Scene 3200 - Cutscene : Guards - Discussion
+ *
+ *--------------------------------------------------------------------------*/
+void Scene3200::postInit(SceneObjectList *OwnerList) {
+ loadScene(3200);
+ R2_GLOBALS._uiElements._active = false;
+ SceneExt::postInit();
+
+ _stripManager.addSpeaker(&_rockoSpeaker);
+ _stripManager.addSpeaker(&_jockoSpeaker);
+ _stripManager.addSpeaker(&_sockoSpeaker);
+
+ R2_GLOBALS._player.postInit();
+ R2_GLOBALS._player.hide();
+ R2_GLOBALS._player.disableControl();
+
+ _actor1.postInit();
+ _actor3.postInit();
+ _actor2.postInit();
+
+ setAction(&_sequenceManager, this, 3200 + R2_GLOBALS._randomSource.getRandomNumber(1), &_actor1, &_actor2, &_actor3, NULL);
+}
+
+void Scene3200::signal() {
+ R2_GLOBALS._sceneManager.changeScene(1200);
+}
+
+/*--------------------------------------------------------------------------
+ * Scene 3210 - Cutscene : Captain and Private - Discussion
+ *
+ *--------------------------------------------------------------------------*/
+void Scene3210::postInit(SceneObjectList *OwnerList) {
+ loadScene(3210);
+ R2_GLOBALS._uiElements._active = false;
+ SceneExt::postInit();
+
+ _stripManager.addSpeaker(&_privateSpeaker);
+ _stripManager.addSpeaker(&_captainSpeaker);
+
+ R2_GLOBALS._player.postInit();
+ R2_GLOBALS._player.hide();
+ R2_GLOBALS._player.disableControl();
+
+ _actor1.postInit();
+ _actor2.postInit();
+
+ setAction(&_sequenceManager, this, 3210 + R2_GLOBALS._randomSource.getRandomNumber(1), &_actor1, &_actor2, NULL);
+}
+
+void Scene3210::signal() {
+ R2_GLOBALS._sceneManager.changeScene(1200);
+}
+
+/*--------------------------------------------------------------------------
+ * Scene 3220 - Cutscene : Guards in cargo zone
+ *
+ *--------------------------------------------------------------------------*/
+void Scene3220::postInit(SceneObjectList *OwnerList) {
+ loadScene(3220);
+ R2_GLOBALS._uiElements._active = false;
+ SceneExt::postInit();
+
+ _stripManager.addSpeaker(&_rockoSpeaker);
+ _stripManager.addSpeaker(&_jockoSpeaker);
+
+ R2_GLOBALS._player.postInit();
+ R2_GLOBALS._player.hide();
+ R2_GLOBALS._player.disableControl();
+
+ _actor1.postInit();
+ _actor2.postInit();
+
+ setAction(&_sequenceManager, this, 3220 + R2_GLOBALS._randomSource.getRandomNumber(1), &_actor1, &_actor2, NULL);
+}
+
+void Scene3220::signal() {
+ R2_GLOBALS._sceneManager.changeScene(1200);
+}
+
+/*--------------------------------------------------------------------------
+ * Scene 3230 - Cutscene : Guards on duty
+ *
+ *--------------------------------------------------------------------------*/
+void Scene3230::postInit(SceneObjectList *OwnerList) {
+ loadScene(3230);
+ R2_GLOBALS._uiElements._active = false;
+ SceneExt::postInit();
+
+ _stripManager.addSpeaker(&_rockoSpeaker);
+ _stripManager.addSpeaker(&_jockoSpeaker);
+
+ R2_GLOBALS._player.postInit();
+ R2_GLOBALS._player.hide();
+ R2_GLOBALS._player.disableControl();
+
+ _actor1.postInit();
+ _actor2.postInit();
+ _actor3.postInit();
+
+ setAction(&_sequenceManager, this, 3230 + R2_GLOBALS._randomSource.getRandomNumber(1), &_actor1, &_actor2, &_actor3, NULL);
+}
+
+void Scene3230::signal() {
+ R2_GLOBALS._sceneManager.changeScene(1200);
+}
+
+/*--------------------------------------------------------------------------
+ * Scene 3240 - Cutscene : Teal monolog
+ *
+ *--------------------------------------------------------------------------*/
+void Scene3240::postInit(SceneObjectList *OwnerList) {
+ loadScene(3240);
+ R2_GLOBALS._uiElements._active = false;
+ SceneExt::postInit();
+
+ _stripManager.addSpeaker(&_tealSpeaker);
+ _stripManager.addSpeaker(&_webbsterSpeaker);
+ _stripManager.addSpeaker(&_mirandaSpeaker);
+
+ R2_GLOBALS._player.postInit();
+ R2_GLOBALS._player.hide();
+ R2_GLOBALS._player.disableControl();
+
+ _actor1.postInit();
+ _actor2.postInit();
+
+ setAction(&_sequenceManager, this, 3240 + R2_GLOBALS._randomSource.getRandomNumber(1), &_actor1, &_actor2, NULL);
+}
+
+void Scene3240::signal() {
+ R2_GLOBALS._sceneManager.changeScene(1200);
+}
+
+/*--------------------------------------------------------------------------
+ * Scene 3245 - Cutscene : Discussions with Dr. Tomko
+ *
+ *--------------------------------------------------------------------------*/
+void Scene3245::postInit(SceneObjectList *OwnerList) {
+ loadScene(3245);
+ R2_GLOBALS._uiElements._active = false;
+ SceneExt::postInit();
+
+ _stripManager.addSpeaker(&_ralfSpeaker);
+ _stripManager.addSpeaker(&_tomkoSpeaker);
+
+ R2_GLOBALS._player.postInit();
+ R2_GLOBALS._player.hide();
+ R2_GLOBALS._player.disableControl();
+
+ _actor1.postInit();
+ _actor2.postInit();
+
+ if (R2_GLOBALS._v56AA1 < 4)
+ ++R2_GLOBALS._v56AA1;
+
+ if (R2_GLOBALS._v56AA1 >= 4) {
+ SceneItem::display(1200, 7, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
+ signal();
+ } else {
+ setAction(&_sequenceManager, this, 3244 + R2_GLOBALS._v56AA1, &_actor1, &_actor2, NULL);
+ }
+}
+
+void Scene3245::signal() {
+ R2_GLOBALS._sceneManager.changeScene(1200);
+}
+
+/*--------------------------------------------------------------------------
+ * Scene 3250 - Room with large stasis field negator
+ *
+ *--------------------------------------------------------------------------*/
+bool Scene3250::Item::startAction(CursorType action, Event &event) {
+ Scene3250 *scene = (Scene3250 *)R2_GLOBALS._sceneManager._scene;
+
+ switch (action) {
+ case CURSOR_USE:
+ if (_useLineNum != -1) {
+ SceneItem::display(_resNum, _useLineNum, 0, 280, 1, 160, 9, 1, 2, 20, 7, 154, -999);
+ return true;
+ }
+ break;
+ case CURSOR_LOOK:
+ if (_lookLineNum != -1) {
+ SceneItem::display(_resNum, _lookLineNum, 0, 280, 1, 160, 9, 1, 2, 20, 7, 154, -999);
+ return true;
+ }
+ break;
+ case CURSOR_TALK:
+ if (_talkLineNum != -1) {
+ SceneItem::display(_resNum, _talkLineNum, 0, 280, 1, 160, 9, 1, 2, 20, 7, 154, -999);
+ return true;
+ }
+ break;
+ default:
+ break;
+ }
+
+ return scene->display(action, event);
+}
+
+bool Scene3250::Actor::startAction(CursorType action, Event &event) {
+ Scene3250 *scene = (Scene3250 *)R2_GLOBALS._sceneManager._scene;
+
+ if (action != CURSOR_USE)
+ return SceneActor::startAction(action, event);
+
+ R2_GLOBALS._player.disableControl();
+
+ switch(_position.x) {
+ case 25:
+ scene->_sceneMode = 3262;
+ scene->setAction(&scene->_sequenceManager, scene, 3262, &R2_GLOBALS._player, &scene->_actor1, NULL);
+ break;
+ case 259:
+ scene->_sceneMode = 3260;
+ scene->setAction(&scene->_sequenceManager, scene, 3260, &R2_GLOBALS._player, &scene->_actor2, NULL);
+ break;
+ case 302:
+ scene->_sceneMode = 3261;
+ scene->setAction(&scene->_sequenceManager, scene, 3261, &R2_GLOBALS._player, &scene->_actor3, NULL);
+ break;
+ default:
+ break;
+ }
+ return true;
+}
+
+void Scene3250::postInit(SceneObjectList *OwnerList) {
+ loadScene(3250);
+
+ if (R2_GLOBALS._sceneManager._previousScene == -1) {
+ R2_GLOBALS._player._oldCharacterScene[3] = 1200;
+ R2_GLOBALS._player._characterIndex = R2_MIRANDA;
+ }
+
+ SceneExt::postInit();
+ _actor1.postInit();
+ _actor1.setup(3250, 6, 1);
+ _actor1.setPosition(Common::Point(25, 148));
+ _actor1.fixPriority(10);
+ _actor1.setDetails(3250, 9, 10, -1, 1, (SceneItem *)NULL);
+
+ _actor2.postInit();
+ _actor2.setup(3250, 4, 1);
+ _actor2.setPosition(Common::Point(259, 126));
+ _actor2.fixPriority(10);
+ _actor2.setDetails(3250, 9, 10, -1, 1, (SceneItem *)NULL);
+
+ _actor3.postInit();
+ _actor3.setup(3250, 5, 1);
+ _actor3.setPosition(Common::Point(302, 138));
+ _actor3.fixPriority(10);
+ _actor3.setDetails(3250, 9, 10, -1, 1, (SceneItem *)NULL);
+
+ _item3.setDetails(Rect(119, 111, 149, 168), 3250, 6, 7, 2, 1, NULL);
+ _item2.setDetails(Rect(58, 85, 231, 138), 3250, 12, 7, 2, 1, NULL);
+ _item4.setDetails(12, 3250, 3, 1, 2);
+ _item1.setDetails(Rect(0, 0, 320, 200), 3250, 0, 1, 2, 1, NULL);
+
+ R2_GLOBALS._player.postInit();
+
+ switch (R2_GLOBALS._player._oldCharacterScene[3]) {
+ case 1200:
+ _sceneMode = 3250;
+ _actor4.postInit();
+ R2_GLOBALS._player._effect = 0;
+ setAction(&_sequenceManager, this, 3250, &R2_GLOBALS._player, &_actor4, NULL);
+ break;
+ case 3125:
+ if (R2_GLOBALS.getFlag(79)) {
+ _sceneMode = 3254;
+ _actor5.postInit();
+ _actor5._effect = 1;
+ _actor6.postInit();
+ _actor6._effect = 1;
+ _actor7.postInit();
+ _actor7._effect = 1;
+ setAction(&_sequenceManager, this, 3254, &R2_GLOBALS._player, &_actor3, &_actor5, &_actor6, &_actor7, &_actor1, NULL);
+ } else {
+ _sceneMode = 3252;
+ setAction(&_sequenceManager, this, 3252, &R2_GLOBALS._player, &_actor3, NULL);
+ }
+ break;
+ case 3175:
+ _sceneMode = 3251;
+ setAction(&_sequenceManager, this, 3251, &R2_GLOBALS._player, &_actor2, NULL);
+ break;
+ case 3255:
+ _sceneMode = 3253;
+ setAction(&_sequenceManager, this, 3253, &R2_GLOBALS._player, &_actor1, NULL);
+ break;
+ default:
+ R2_GLOBALS._player.setup(31, 3, 1);
+ R2_GLOBALS._player.animate(ANIM_MODE_1, NULL);
+ R2_GLOBALS._player.setPosition(Common::Point(185, 150));
+ R2_GLOBALS._player.enableControl();
+ break;
+ }
+
+ R2_GLOBALS._player._oldCharacterScene[3] = 3250;
+}
+
+void Scene3250::signal() {
+ switch(_sceneMode) {
+ case 3250:
+ R2_GLOBALS._player._effect = 1;
+ R2_GLOBALS._player.enableControl();
+ break;
+ case 3254:
+ //No break on purpose
+ case 3262:
+ R2_GLOBALS._sceneManager.changeScene(3255);
+ break;
+ case 3260:
+ R2_GLOBALS._sceneManager.changeScene(3175);
+ break;
+ case 3261:
+ R2_GLOBALS._sceneManager.changeScene(3125);
+ break;
+ default:
+ R2_GLOBALS._player.enableControl();
+ break;
+ }
+}
+
+void Scene3250::dispatch() {
+ if ((R2_GLOBALS._player._visage == 3250) && (R2_GLOBALS._player._strip == 3) && (R2_GLOBALS._player._effect == 0)) {
+ R2_GLOBALS._player._effect = 6;
+ R2_GLOBALS._player._shade = 6;
+ }
+
+ Scene::dispatch();
+}
+
+/*--------------------------------------------------------------------------
+ * Scene 3255 -
+ *
+ *--------------------------------------------------------------------------*/
+void Scene3255::postInit(SceneObjectList *OwnerList) {
+ loadScene(3255);
+ SceneExt::postInit();
+
+ _stripManager.addSpeaker(&_quinnSpeaker);
+ _stripManager.addSpeaker(&_mirandaSpeaker);
+
+ if (R2_GLOBALS._sceneManager._previousScene == -1)
+ R2_GLOBALS.setFlag(79);
+
+ R2_GLOBALS._player.postInit();
+ R2_GLOBALS._player.disableControl();
+
+ if (R2_GLOBALS.getFlag(79)) {
+ R2_GLOBALS._sound1.play(267);
+ R2_GLOBALS._sound2.play(268);
+ _sceneMode = 3257;
+ _actor3.postInit();
+ _actor4.postInit();
+ _actor4._effect = 1;
+ setAction(&_sequenceManager, this, 3257, &R2_GLOBALS._player, &_actor4, &_actor3, NULL);
+ } else {
+ _actor1.postInit();
+ _actor1.setup(303, 1, 1);
+ _actor1.setPosition(Common::Point(208, 128));
+ _actor2.postInit();
+ _actor2.setup(3107, 3, 1);
+ _actor2.setPosition(Common::Point(230, 127));
+ _sceneMode = 3255;
+ setAction(&_sequenceManager, this, 3255, &R2_GLOBALS._player, NULL);
+ }
+ R2_GLOBALS._player._oldCharacterScene[3] = 3255;
+}
+
+void Scene3255::signal() {
+ switch (_sceneMode) {
+ case 10:
+ _sceneMode = 3258;
+ _actor5.postInit();
+ _actor6.postInit();
+ _actor7.postInit();
+ setAction(&_sequenceManager, this, 3258, &R2_GLOBALS._player, &_actor4, &_actor3, &_actor5, &_actor6, &_actor7, NULL);
+ break;
+ case 3256:
+ R2_GLOBALS._sceneManager.changeScene(3250);
+ break;
+ case 3257:
+ _sceneMode = 10;
+ R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
+ _stripManager.start(607, this);
+ break;
+ case 3258:
+ R2_GLOBALS._sceneManager.changeScene(3100);
+ break;
+ default:
+ SceneItem::display(3255, 0, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
+ _sceneMode = 3256;
+ setAction(&_sequenceManager, this, 3256, &R2_GLOBALS._player, NULL);
+ }
+}
+
+void Scene3255::dispatch() {
+ if (R2_GLOBALS.getFlag(79)) {
+ if (_actor5._position.y >= 95) {
+ if (_actor5._position.y <= 110)
+ _actor5._shade = 6 - (_actor5._position.y - 95) / 3;
+ else
+ _actor5._effect = 1;
+ } else {
+ _actor5._effect = 6;
+ _actor5._shade = 6;
+ }
+
+ if (_actor6._position.y >= 95) {
+ if (_actor6._position.y <= 110)
+ _actor6._shade = 6 - (_actor6._position.y - 95) / 3;
+ else
+ _actor6._effect = 1;
+ } else {
+ _actor6._effect = 6;
+ _actor6._shade = 6;
+ }
+
+ if (_actor7._position.y >= 95) {
+ if (_actor7._position.y <= 110)
+ _actor7._shade = 6 - (_actor7._position.y - 95) / 3;
+ else
+ _actor7._effect = 1;
+ } else {
+ _actor7._effect = 6;
+ _actor7._shade = 6;
+ }
+ }
+
+ if ((R2_GLOBALS._player._position.x > 250) && (R2_GLOBALS._player._shade == 1)) {
+ R2_GLOBALS._player._effect = 6;
+ _actor4._effect = 6;
+ }
+ Scene::dispatch();
+}
+
+/*--------------------------------------------------------------------------
+ * Scene 3260 - Computer room
+ *
+ *--------------------------------------------------------------------------*/
+bool Scene3260::Actor13::startAction(CursorType action, Event &event) {
+ Scene3260 *scene = (Scene3260 *)R2_GLOBALS._sceneManager._scene;
+
+ if (action != CURSOR_USE)
+ return SceneActor::startAction(action, event);
+
+ R2_GLOBALS._player.disableControl();
+ scene->_sceneMode = 3271;
+ scene->setAction(&scene->_sequenceManager, scene, 3271, &R2_GLOBALS._player, &scene->_actor13, NULL);
+ return true;
+}
+
+bool Scene3260::Actor14::startAction(CursorType action, Event &event) {
+ Scene3260 *scene = (Scene3260 *)R2_GLOBALS._sceneManager._scene;
+
+ if (action != CURSOR_USE)
+ return SceneActor::startAction(action, event);
+
+ R2_GLOBALS._player.disableControl();
+ scene->_sceneMode = 3272;
+ scene->setAction(&scene->_sequenceManager, scene, 3272, &R2_GLOBALS._player, &scene->_actor14, NULL);
+ return true;
+}
+
+void Scene3260::Action1::signal() {
+ SceneObjectExt *fmtObj = (SceneObjectExt *) _endHandler;
+
+ fmtObj->setFrame(R2_GLOBALS._randomSource.getRandomNumber(6));
+ setDelay(120 + R2_GLOBALS._randomSource.getRandomNumber(179));
+}
+
+void Scene3260::postInit(SceneObjectList *OwnerList) {
+ loadScene(3260);
+ R2_GLOBALS._player._characterIndex = R2_MIRANDA;
+ SceneExt::postInit();
+ R2_GLOBALS._sound1.play(285);
+
+ _actor13.postInit();
+ _actor13.setup(3260, 6, 1);
+ _actor13.setPosition(Common::Point(40, 106));
+ _actor13.setDetails(3260, 18, 1, -1, 1, (SceneItem *)NULL);
+
+ if (R2_INVENTORY.getObjectScene(52) == 3260) {
+ _actor14.postInit();
+ _actor14.setup(3260, 7, 1);
+ _actor14.setPosition(Common::Point(202, 66));
+ _actor14.setDetails(3260, 12, 1, -1, 1, (SceneItem *)NULL);
+ }
+
+ _actor1.postInit();
+ _actor1.setup(3260, 1, 1);
+ _actor1.setPosition(Common::Point(93, 73));
+ _actor1.setDetails(3260, 3, 1, 5, 1, (SceneItem *)NULL);
+ _actor1.setAction(&_action1, &_actor1);
+
+ _actor2.postInit();
+ _actor2.setup(3260, 2, 1);
+ _actor2.setPosition(Common::Point(142, 63));
+ _actor2.setDetails(3260, 3, 1, 5, 1, (SceneItem *)NULL);
+ _actor2.setAction(&_action2, &_actor2);
+
+ _actor3.postInit();
+ _actor3.setup(3260, 2, 1);
+ _actor3.setPosition(Common::Point(166, 54));
+ _actor3.setDetails(3260, 3, 1, 5, 1, (SceneItem *)NULL);
+ _actor3.setAction(&_action3, &_actor3);
+
+ _actor4.postInit();
+ _actor4.setup(3260, 2, 1);
+ _actor4.setPosition(Common::Point(190, 46));
+ _actor4.setDetails(3260, 3, 1, 5, 1, (SceneItem *)NULL);
+ _actor4.setAction(&_action4, &_actor4);
+
+ _actor5.postInit();
+ _actor5.setup(3260, 2, 1);
+ _actor5.setPosition(Common::Point(142, 39));
+ _actor5.setDetails(3260, 3, 1, 5, 1, (SceneItem *)NULL);
+ _actor5.setAction(&_action5, &_actor5);
+
+ _actor6.postInit();
+ _actor6.setup(3260, 2, 1);
+ _actor6.setPosition(Common::Point(166, 30));
+ _actor6.setDetails(3260, 3, 1, 5, 1, (SceneItem *)NULL);
+ _actor6.setAction(&_action6, &_actor6);
+
+ _actor7.postInit();
+ _actor7.setup(3260, 2, 1);
+ _actor7.setPosition(Common::Point(190, 22));
+ _actor7.setDetails(3260, 3, 1, 5, 1, (SceneItem *)NULL);
+ _actor7.setAction(&_action7, &_actor7);
+
+ _actor8.postInit();
+ _actor8.setup(3260, 2, 1);
+ _actor8.setPosition(Common::Point(142, 14));
+ _actor8.setDetails(3260, 3, 1, 5, 1, (SceneItem *)NULL);
+ _actor8.setAction(&_action8, &_actor8);
+
+ _actor9.postInit();
+ _actor9.setup(3260, 2, 1);
+ _actor9.setPosition(Common::Point(166, 6));
+ _actor9.setDetails(3260, 3, 1, 5, 1, (SceneItem *)NULL);
+ _actor9.setAction(&_action9, &_actor9);
+
+ _actor10.postInit();
+ _actor10.setup(3260, 3, 1);
+ _actor10.setPosition(Common::Point(265, 163));
+ _actor10.fixPriority(180);
+ _actor10._numFrames = 10;
+ _actor10.setDetails(3260, 6, 1, 8, 1, (SceneItem *)NULL);
+ _actor10.animate(ANIM_MODE_2, NULL);
+
+ _actor11.postInit();
+ _actor11.setup(3260, 4, 1);
+ _actor11.setPosition(Common::Point(127, 108));
+ _actor11.fixPriority(120);
+ _actor11.setAction(&_action11, &_actor11);
+ _actor11._numFrames = 15;
+ _actor11.setDetails(3260, 6, 1, 8, 1, (SceneItem *)NULL);
+ _actor11.animate(ANIM_MODE_2, NULL);
+
+ _actor12.postInit();
+ _actor12.setup(3260, 5, 1);
+ _actor12.setPosition(Common::Point(274, 65));
+ _actor12.setAction(&_action12, &_actor12);
+ _actor12._numFrames = 5;
+ _actor12.setDetails(3260, 9, 1, 11, 1, (SceneItem *)NULL);
+ _actor12.animate(ANIM_MODE_2, NULL);
+
+ _item1.setDetails(Rect(0, 0, 320, 200), 3260, 0, 1, 2, 1, NULL);
+ R2_GLOBALS._player.postInit();
+
+ if (R2_GLOBALS._player._oldCharacterScene[3] == 3275) {
+ _sceneMode = 3270;
+ setAction(&_sequenceManager, this, 3270, &R2_GLOBALS._player, &_actor13, NULL);
+ } else {
+ R2_GLOBALS._player.setup(30, 5, 1);
+ R2_GLOBALS._player.animate(ANIM_MODE_1, NULL);
+ R2_GLOBALS._player.setPosition(Common::Point(53, 113));
+ R2_GLOBALS._player._moveDiff = Common::Point(3, 2);
+ R2_GLOBALS._player.enableControl();
+ }
+ R2_GLOBALS._player._oldCharacterScene[3] = 3260;
+}
+
+void Scene3260::remove() {
+ R2_GLOBALS._sound1.fadeOut2(NULL);
+ SceneExt::remove();
+}
+
+void Scene3260::signal() {
+ switch (_sceneMode) {
+ case 3271:
+ R2_GLOBALS._sceneManager.changeScene(3275);
+ break;
+ case 3272:
+ _sceneMode = 3273;
+ R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
+ SceneItem::display(3260, 15, 0, 280, 1, 160, 9, 1, 2, 20, 7, 154, -999);
+ R2_GLOBALS._player.disableControl();
+ R2_INVENTORY.setObjectScene(52, 3);
+ R2_INVENTORY.setObjectScene(43, 3);
+ setAction(&_sequenceManager, this, 3273, &R2_GLOBALS._player, &_actor14, NULL);
+ break;
+ case 3273:
+ _actor4.remove();
+ R2_GLOBALS._player.enableControl();
+ break;
+ default:
+ R2_GLOBALS._player.enableControl();
+ break;
+ }
+}
+
+/*--------------------------------------------------------------------------
+ * Scene 3275 - Hall
+ *
+ *--------------------------------------------------------------------------*/
+bool Scene3275::Actor2::startAction(CursorType action, Event &event) {
+ Scene3275 *scene = (Scene3275 *)R2_GLOBALS._sceneManager._scene;
+
+ if (action != CURSOR_USE)
+ return SceneActor::startAction(action, event);
+
+ R2_GLOBALS._player.disableControl();
+ scene->_sceneMode = 3275;
+ scene->setAction(&scene->_sequenceManager, scene, 3275, &R2_GLOBALS._player, &scene->_actor2, NULL);
+ return true;
+}
+
+void Scene3275::Exit1::changeScene() {
+ Scene3275 *scene = (Scene3275 *)R2_GLOBALS._sceneManager._scene;
+
+ scene->_sceneMode = 0;
+ g_globals->_events.setCursor(CURSOR_ARROW);
+ R2_GLOBALS._player.disableControl();
+ scene->_sceneMode = 10;
+ Common::Point pt(418, 118);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, scene);
+}
+
+void Scene3275::postInit(SceneObjectList *OwnerList) {
+ loadScene(3275);
+
+ if (R2_GLOBALS._sceneManager._previousScene == -1)
+ R2_GLOBALS._sceneManager._previousScene = 3260;
+
+ if (R2_GLOBALS._sceneManager._previousScene == 3150)
+ g_globals->gfxManager()._bounds.moveTo(Common::Point(160, 0));
+ else
+ g_globals->gfxManager()._bounds.moveTo(Common::Point(0, 0));
+
+ SceneExt::postInit();
+ _exit1.setDetails(Rect(398, 60, 439, 118), SHADECURSOR_UP, 3150);
+ _exit1.setDest(Common::Point(418, 128));
+
+ _actor1.postInit();
+ _actor1.setup(3275, 1, 7);
+ _actor1.setPosition(Common::Point(419, 119));
+
+ _actor2.postInit();
+ _actor2.setup(3275, 2, 1);
+ _actor2.setPosition(Common::Point(56, 118));
+ _actor2.setDetails(3275, 3, 4, -1, 1, (SceneItem *)NULL);
+
+ _item2.setDetails(Rect(153, 58, 200, 120), 3275, 6, 7, 8, 1, NULL);
+ _item3.setDetails(Rect(275, 58, 331, 120), 3275, 6, 7, 8, 1, NULL);
+ _item4.setDetails(Rect(0, 66, 22, 127), 3275, 9, 10, 11, 1, NULL);
+ _item5.setDetails(Rect(457, 66, 480, 127), 3275, 9, 10, 11, 1, NULL);
+ _item1.setDetails(Rect(0, 0, 480, 200), 3275, 0, 1, 2, 1, NULL);
+
+ R2_GLOBALS._scrollFollower = &R2_GLOBALS._player;
+ R2_GLOBALS._player.postInit();
+ R2_GLOBALS._player.disableControl();
+ if (R2_GLOBALS._player._oldCharacterScene[3] == 3150) {
+ _sceneMode = 11;
+ R2_GLOBALS._player.setup(30, 3, 1);
+ R2_GLOBALS._player.animate(ANIM_MODE_1, NULL);
+ R2_GLOBALS._player.setPosition(Common::Point(418, 118));
+ R2_GLOBALS._player._moveDiff = Common::Point(3, 2);
+ Common::Point pt(418, 128);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, this);
+ } else if (R2_GLOBALS._player._oldCharacterScene[3] == 3260) {
+ _sceneMode = 3276;
+ setAction(&_sequenceManager, this, 3276, &R2_GLOBALS._player, &_actor2, NULL);
+ } else {
+ R2_GLOBALS._player.setup(30, 3, 1);
+ R2_GLOBALS._player.animate(ANIM_MODE_1, NULL);
+ R2_GLOBALS._player.setPosition(Common::Point(245, 135));
+ R2_GLOBALS._player._moveDiff = Common::Point(3, 2);
+ R2_GLOBALS._player.enableControl();
+ }
+ R2_GLOBALS._player._oldCharacterScene[3] = 3275;
+}
+
+void Scene3275::signal() {
+ switch (_sceneMode) {
+ case 10:
+ R2_GLOBALS._sceneManager.changeScene(3150);
+ break;
+ case 3275:
+ R2_GLOBALS._sceneManager.changeScene(3260);
+ break;
+ default:
+ R2_GLOBALS._player.enableControl();
+ break;
+ }
+}
+
+/*--------------------------------------------------------------------------
+ * Scene 3350 - Cutscene - Ship landing
+ *
+ *--------------------------------------------------------------------------*/
+void Scene3350::postInit(SceneObjectList *OwnerList) {
+ loadScene(3350);
+ R2_GLOBALS._uiElements._active = false;
+ SceneExt::postInit();
+ R2_GLOBALS._sound2.play(310);
+
+ _rotation = R2_GLOBALS._scenePalette.addRotation(176, 203, 1);
+ _rotation->setDelay(3);
+
+ R2_GLOBALS._player.postInit();
+ R2_GLOBALS._player.hide();
+ R2_GLOBALS._player.disableControl();
+
+ _actor1.postInit();
+ _actor1.hide();
+ _actor2.postInit();
+ _actor2.hide();
+ _actor3.postInit();
+ _actor3.hide();
+ _actor4.postInit();
+ _actor4.hide();
+ _actor9.postInit();
+ _actor9.hide();
+ _actor8.postInit();
+ _actor8.hide();
+ _actor5.postInit();
+ _actor5.hide();
+ _actor6.postInit();
+ _actor6.hide();
+ _actor7.postInit();
+ _actor7.hide();
+
+ _sceneMode = 3350;
+ setAction(&_sequenceManager, this, _sceneMode, &_actor5, &_actor6, &_actor7, NULL);
+}
+
+void Scene3350::remove() {
+ R2_GLOBALS._sound2.fadeOut2(NULL);
+ SceneExt::remove();
+}
+
+void Scene3350::signal() {
+ switch (_sceneMode) {
+ case 3350:
+ _sceneMode = 3351;
+ setAction(&_sequenceManager, this, 3351, &_actor4, &_actor9, &_actor8, NULL);
+ break;
+ case 3351:
+ _sceneMode = 3352;
+ setAction(&_sequenceManager, this, 3352, &_actor4, &R2_GLOBALS._player, &_actor1, &_actor2, &_actor3, NULL);
+ case 3352:
+ R2_GLOBALS._sceneManager.changeScene(3395);
+ break;
+ default:
+ R2_GLOBALS._player.enableControl();
+ break;
+ }
+}
+
+/*--------------------------------------------------------------------------
+ * Scene 3375 -
+ *
+ *--------------------------------------------------------------------------*/
+Scene3375::Scene3375() {
+ _field1488 = _field1492 = 0;
+ for (int i = 0; i < 4; ++i)
+ _field148A[i] = 0;
+}
+
+void Scene3375::synchronize(Serializer &s) {
+ SceneExt::synchronize(s);
+
+ s.syncAsSint16LE(_field1488);
+ s.syncAsSint16LE(_field1492);
+ for (int i = 0; i < 4; ++i)
+ s.syncAsSint16LE(_field148A[i]);
+}
+
+void Scene3375::subFC696(int sceneMode) {
+ switch (sceneMode) {
+ case 3379:
+ R2_GLOBALS._player.setPosition(Common::Point(0, 155));
+ _actor1.setPosition(Common::Point(-20, 163));
+ _actor2.setPosition(Common::Point(-5, 150));
+ _actor3.setPosition(Common::Point(-20, 152));
+ break;
+ case 3380:
+ ++R2_GLOBALS._v56A9E;
+ if (R2_GLOBALS._v56A9E >= 4)
+ R2_GLOBALS._v56A9E = 0;
+
+ loadScene(_field148A[R2_GLOBALS._v56A9E]);
+
+ R2_GLOBALS._uiElements.show();
+ R2_GLOBALS._player.setStrip(4);
+ R2_GLOBALS._player.setPosition(Common::Point(148, 230));
+
+ _actor1.setPosition(Common::Point(191, 274));
+ _actor1._effect = 1;
+ _actor2.setPosition(Common::Point(124, 255));
+ _actor2._effect = 1;
+ _actor3.setPosition(Common::Point(155, 245));
+ _actor3._effect = 1;
+ break;
+ case 3381:
+ --R2_GLOBALS._v56A9E;
+ if (R2_GLOBALS._v56A9E < 0)
+ R2_GLOBALS._v56A9E = 3;
+
+ loadScene(_field148A[R2_GLOBALS._v56A9E]);
+
+ R2_GLOBALS._uiElements.show();
+ R2_GLOBALS._player.setStrip(6);
+ R2_GLOBALS._player.setPosition(Common::Point(201, 131));
+
+ _actor1.setPosition(Common::Point(231, 127));
+ _actor1._effect = 1;
+ _actor2.setPosition(Common::Point(231, 127));
+ _actor2._effect = 1;
+ _actor3.setPosition(Common::Point(231, 127));
+ _actor3._effect = 1;
+ break;
+ default:
+ R2_GLOBALS._player.setPosition(Common::Point(192, 155));
+
+ _actor1.setPosition(Common::Point(138, 134));
+ _actor2.setPosition(Common::Point(110, 139));
+ _actor3.setPosition(Common::Point(125, 142));
+ break;
+ }
+
+ if (R2_GLOBALS._v56A9E == 2) {
+ R2_GLOBALS._sceneItems.remove(&_actor4);
+ for (int i = 0; i <= 12; i++)
+ R2_GLOBALS._sceneItems.remove(&_itemArray[i]);
+ R2_GLOBALS._sceneItems.remove(&_item1);
+
+ _actor4.show();
+ _actor4.setDetails(3375, 9, 10, -1, 1, (SceneItem *)NULL);
+
+ for (int i = 0; i <= 12; i++)
+ _itemArray[i].setDetails(3375, 3, -1, -1);
+
+ _item1.setDetails(Rect(0, 0, 320, 200), 3375, 0, -1, -1, 1, NULL);
+ } else {
+ _actor4.hide();
+ R2_GLOBALS._sceneItems.remove(&_actor4);
+ }
+
+ if (_sceneMode == 0)
+ signal();
+ else
+ setAction(&_sequenceManager, this, _sceneMode, &R2_GLOBALS._player, &_actor1, &_actor2, &_actor3, NULL);
+}
+
+bool Scene3375::Actor1::startAction(CursorType action, Event &event) {
+ Scene3375 *scene = (Scene3375 *)R2_GLOBALS._sceneManager._scene;
+
+ if (action != CURSOR_TALK)
+ return SceneActor::startAction(action, event);
+
+ scene->_sceneMode = 9999;
+ if (R2_GLOBALS._player._characterIndex == 2)
+ scene->_stripManager.start(3302, scene);
+ else
+ scene->_stripManager.start(3304, scene);
+
+ return true;
+}
+
+bool Scene3375::Actor2::startAction(CursorType action, Event &event) {
+ Scene3375 *scene = (Scene3375 *)R2_GLOBALS._sceneManager._scene;
+
+ if (action != CURSOR_TALK)
+ return SceneActor::startAction(action, event);
+
+ scene->_sceneMode = 9999;
+ if (R2_GLOBALS._player._characterIndex == 3)
+ scene->_stripManager.start(3302, scene);
+ else
+ scene->_stripManager.start(3301, scene);
+
+ return true;
+}
+
+bool Scene3375::Actor3::startAction(CursorType action, Event &event) {
+ Scene3375 *scene = (Scene3375 *)R2_GLOBALS._sceneManager._scene;
+
+ if (action != CURSOR_TALK)
+ return SceneActor::startAction(action, event);
+
+ scene->_sceneMode = 9999;
+ scene->_stripManager.start(3303, scene);
+
+ return true;
+}
+
+bool Scene3375::Actor4::startAction(CursorType action, Event &event) {
+ Scene3375 *scene = (Scene3375 *)R2_GLOBALS._sceneManager._scene;
+
+ if (action != CURSOR_USE)
+ return SceneActor::startAction(action, event);
+
+ if (R2_GLOBALS._v56A9E != 0) {
+ R2_GLOBALS._walkRegions.disableRegion(2);
+ R2_GLOBALS._walkRegions.disableRegion(3);
+ } else {
+ R2_GLOBALS._walkRegions.disableRegion(1);
+ R2_GLOBALS._walkRegions.disableRegion(3);
+ R2_GLOBALS._walkRegions.disableRegion(4);
+ }
+ R2_GLOBALS._walkRegions.disableRegion(6);
+ R2_GLOBALS._walkRegions.disableRegion(7);
+ R2_GLOBALS._walkRegions.disableRegion(8);
+
+ R2_GLOBALS._player.disableControl(CURSOR_ARROW);
+
+ scene->_sceneMode = 3375;
+ scene->setAction(&scene->_sequenceManager, scene, 3375, &R2_GLOBALS._player, &scene->_actor1, &scene->_actor2, &scene->_actor3, &scene->_actor4, NULL);
+
+ return true;
+}
+
+void Scene3375::Exit1::changeScene() {
+ Scene3375 *scene = (Scene3375 *)R2_GLOBALS._sceneManager._scene;
+
+ _moving = false;
+ R2_GLOBALS._player.disableControl(CURSOR_ARROW);
+ scene->_sceneMode = 3376;
+ if (R2_GLOBALS._v56A9E != 0) {
+ R2_GLOBALS._walkRegions.disableRegion(2);
+ R2_GLOBALS._walkRegions.disableRegion(3);
+ } else {
+ R2_GLOBALS._walkRegions.disableRegion(1);
+ R2_GLOBALS._walkRegions.disableRegion(3);
+ R2_GLOBALS._walkRegions.disableRegion(4);
+ }
+ if (scene->_actor1._position.y != 163) {
+ R2_GLOBALS._player.setStrip(-1);
+ scene->_actor1.setStrip2(-1);
+ scene->_actor2.setStrip2(-1);
+ scene->_actor3.setStrip2(-1);
+ scene->setAction(&scene->_sequenceManager, scene, scene->_sceneMode, &R2_GLOBALS._player, &scene->_actor1, &scene->_actor2, &scene->_actor3, NULL);
+ } else {
+ R2_GLOBALS._player.setStrip2(2);
+ scene->_actor1.setStrip2(2);
+ scene->_actor2.setStrip2(2);
+ scene->_actor3.setStrip2(2);
+ R2_GLOBALS._sound2.play(314);
+
+ Common::Point pt(50, 150);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, scene);
+ }
+}
+
+void Scene3375::Exit2::changeScene() {
+ Scene3375 *scene = (Scene3375 *)R2_GLOBALS._sceneManager._scene;
+
+ _moving = false;
+ R2_GLOBALS._player._effect = 6;
+ R2_GLOBALS._player._shade = 4;
+ R2_GLOBALS._player.disableControl(CURSOR_ARROW);
+
+ scene->_sceneMode = 3377;
+ scene->_field1488 = 3381;
+
+ if (R2_GLOBALS._v56A9E != 0) {
+ R2_GLOBALS._walkRegions.disableRegion(2);
+ R2_GLOBALS._walkRegions.disableRegion(3);
+ } else {
+ R2_GLOBALS._walkRegions.disableRegion(1);
+ R2_GLOBALS._walkRegions.disableRegion(3);
+ R2_GLOBALS._walkRegions.disableRegion(4);
+ }
+ scene->setAction(&scene->_sequenceManager, scene, scene->_sceneMode, &R2_GLOBALS._player, &scene->_actor1, &scene->_actor2, &scene->_actor3, NULL);
+}
+
+void Scene3375::Exit3::changeScene() {
+ Scene3375 *scene = (Scene3375 *)R2_GLOBALS._sceneManager._scene;
+
+ _moving = false;
+ R2_GLOBALS._player._effect = 6;
+ R2_GLOBALS._player._shade = 4;
+ R2_GLOBALS._player.disableControl(CURSOR_ARROW);
+
+ scene->_sceneMode = 3378;
+ scene->_field1488 = 3380;
+
+ if (R2_GLOBALS._v56A9E != 0) {
+ R2_GLOBALS._walkRegions.disableRegion(2);
+ R2_GLOBALS._walkRegions.disableRegion(3);
+ } else {
+ R2_GLOBALS._walkRegions.disableRegion(1);
+ R2_GLOBALS._walkRegions.disableRegion(3);
+ R2_GLOBALS._walkRegions.disableRegion(4);
+ }
+ scene->setAction(&scene->_sequenceManager, scene, scene->_sceneMode, &R2_GLOBALS._player, &scene->_actor1, &scene->_actor2, &scene->_actor3, NULL);
+}
+
+void Scene3375::postInit(SceneObjectList *OwnerList) {
+ _field148A[0] = 3376;
+ _field148A[1] = 3377;
+ _field148A[2] = 3375;
+ _field148A[3] = 3378;
+
+ loadScene(_field148A[R2_GLOBALS._v56A9E]);
+ SceneExt::postInit();
+
+ R2_GLOBALS._sound1.play(313);
+
+ _stripManager.setColors(60, 255);
+ _stripManager.setFontNumber(3);
+ _stripManager.addSpeaker(&_quinnSpeaker);
+ _stripManager.addSpeaker(&_seekerSpeaker);
+ _stripManager.addSpeaker(&_mirandaSpeaker);
+ _stripManager.addSpeaker(&_webbsterSpeaker);
+
+ R2_GLOBALS._player._characterScene[1] = 3375;
+ R2_GLOBALS._player._characterScene[2] = 3375;
+ R2_GLOBALS._player._characterScene[3] = 3375;
+
+ setZoomPercents(126, 55, 200, 167);
+ R2_GLOBALS._player.postInit();
+
+ if (R2_GLOBALS._player._characterIndex == 2) {
+ R2_GLOBALS._player._moveDiff = Common::Point(5, 3);
+ } else {
+ R2_GLOBALS._player._moveDiff = Common::Point(3, 2);
+ }
+ R2_GLOBALS._player.changeZoom(-1);
+
+ switch (R2_GLOBALS._player._characterIndex) {
+ case 2:
+ if (R2_GLOBALS._sceneManager._previousScene == 3385)
+ R2_GLOBALS._player.setup(20, 1, 1);
+ else
+ R2_GLOBALS._player.setup(20, 3, 1);
+ break;
+ case 3:
+ if (R2_GLOBALS._sceneManager._previousScene == 3385)
+ R2_GLOBALS._player.setup(30, 1, 1);
+ else
+ R2_GLOBALS._player.setup(30, 3, 1);
+ break;
+ default:
+ if (R2_GLOBALS._sceneManager._previousScene == 3385)
+ R2_GLOBALS._player.setup(10, 1, 1);
+ else
+ R2_GLOBALS._player.setup(10, 3, 1);
+ break;
+ }
+
+ R2_GLOBALS._player.animate(ANIM_MODE_1, NULL);
+ R2_GLOBALS._player.disableControl();
+
+ _actor1.postInit();
+ if (R2_GLOBALS._player._characterIndex == 2) {
+ _actor1._moveRate = 10;
+ _actor1._moveDiff = Common::Point(3, 2);
+ } else {
+ _actor1._moveRate = 7;
+ _actor1._moveDiff = Common::Point(5, 3);
+ }
+ _actor1.changeZoom(-1);
+ _actor1._effect = 1;
+
+ int tmpStrip, tmpVisage;
+ if (R2_GLOBALS._sceneManager._previousScene == 3385)
+ tmpStrip = 1;
+ else
+ tmpStrip = 4;
+
+ if (R2_GLOBALS._player._characterIndex == 2)
+ tmpVisage = 10;
+ else
+ tmpVisage = 20;
+
+ _actor1.setup(tmpVisage, tmpStrip, 1);
+ _actor1.animate(ANIM_MODE_1, NULL);
+
+ _actor2.postInit();
+ _actor2._moveDiff = Common::Point(3, 2);
+ _actor2.changeZoom(-1);
+ _actor2._effect = 1;
+ if (R2_GLOBALS._sceneManager._previousScene == 3385)
+ tmpStrip = 1;
+ else
+ tmpStrip = 8;
+
+ if (R2_GLOBALS._player._characterIndex == 3)
+ tmpVisage = 10;
+ else
+ tmpVisage = 30;
+
+ _actor2.setup(tmpVisage, tmpStrip, 1);
+ _actor2.animate(ANIM_MODE_1, NULL);
+
+ _actor3.postInit();
+ _actor3._moveRate = 7;
+ _actor3._moveDiff = Common::Point(5, 3);
+ _actor3.changeZoom(-1);
+ _actor3._effect = 1;
+ if (R2_GLOBALS._sceneManager._previousScene == 3385)
+ tmpStrip = 1;
+ else
+ tmpStrip = 4;
+
+ _actor3.setup(40, tmpStrip, 1);
+ _actor3.animate(ANIM_MODE_1, NULL);
+
+ _actor2.setDetails(3375, -1, -1, -1, 1, (SceneItem *)NULL);
+ _actor3.setDetails(3375, 21, -1, -1, 1, (SceneItem *)NULL);
+ _actor1.setDetails(3375, -1, -1, -1, 1, (SceneItem *)NULL);
+
+ _actor4.postInit();
+ _actor4.setup(3375, 1, 1);
+ _actor4.setPosition(Common::Point(254, 166));
+ _actor4.fixPriority(140);
+ _actor4.hide();
+
+ _exit1.setDetails(Rect(0, 84, 24, 167), EXITCURSOR_W, 3375);
+ _exit1.setDest(Common::Point(65, 155));
+ _exit2.setDetails(Rect(103, 152, 183, 170), SHADECURSOR_DOWN, 3375);
+ _exit2.setDest(Common::Point(158, 151));
+ _exit3.setDetails(Rect(180, 75, 213, 132), EXITCURSOR_E, 3375);
+ _exit3.setDest(Common::Point(201, 131));
+
+ for (int i = 0; i <= 12; ++i)
+ _itemArray[i].setDetails(i, 3375, 3, -1, -1);
+
+ _item1.setDetails(Rect(0, 0, 320, 200), 3375, 0, -1, 1, 1, NULL);
+
+ if (R2_GLOBALS._sceneManager._previousScene == 3385)
+ _sceneMode = 3379;
+ else
+ _sceneMode = 0;
+
+ subFC696(_sceneMode);
+}
+
+void Scene3375::remove() {
+ R2_GLOBALS._sound1.fadeOut2(NULL);
+ SceneExt::remove();
+}
+
+void Scene3375::signalCase3379() {
+ switch (R2_GLOBALS._v56A9E) {
+ case 0:
+ _exit1._enabled = true;
+ if (R2_GLOBALS._sceneManager._previousScene == 3385)
+ R2_GLOBALS._walkRegions.enableRegion(1);
+ else {
+ R2_GLOBALS._walkRegions.enableRegion(3);
+ R2_GLOBALS._walkRegions.enableRegion(4);
+ }
+ R2_GLOBALS._walkRegions.enableRegion(6);
+ R2_GLOBALS._walkRegions.enableRegion(7);
+ case 2:
+ _exit1._enabled = false;
+ R2_GLOBALS._walkRegions.enableRegion(2);
+ R2_GLOBALS._walkRegions.enableRegion(3);
+ R2_GLOBALS._walkRegions.enableRegion(5);
+ R2_GLOBALS._walkRegions.enableRegion(6);
+ R2_GLOBALS._walkRegions.enableRegion(7);
+ R2_GLOBALS._walkRegions.enableRegion(8);
+ R2_GLOBALS._walkRegions.enableRegion(9);
+ default:
+ _exit1._enabled = false;
+ R2_GLOBALS._walkRegions.enableRegion(2);
+ R2_GLOBALS._walkRegions.enableRegion(3);
+ R2_GLOBALS._walkRegions.enableRegion(5);
+ R2_GLOBALS._walkRegions.enableRegion(6);
+ break;
+ }
+ R2_GLOBALS._sceneManager._previousScene = 3375;
+ R2_GLOBALS._player._effect = 1;
+ _actor1._effect = 1;
+ _actor2._effect = 1;
+ _actor3._effect = 1;
+ R2_GLOBALS._player.enableControl(CURSOR_ARROW);
+}
+
+void Scene3375::signal() {
+ switch (_sceneMode) {
+ case 3375:
+ R2_GLOBALS._sceneManager.changeScene(3400);
+ break;
+ case 3376:
+ R2_GLOBALS._sceneManager.changeScene(3385);
+ break;
+ case 3377:
+ // No break on purpose
+ case 3378:
+ _sceneMode = _field1488;
+ _field1488 = 0;
+ _actor1._effect = 6;
+ _actor1._shade = 4;
+ _actor2._effect = 6;
+ _actor2._shade = 4;
+ _actor3._effect = 6;
+ _actor3._shade = 4;
+ subFC696(_sceneMode);
+ break;
+ case 3379:
+ signalCase3379();
+ break;
+ case 9999:
+ if (_actor1._position.y == 163)
+ R2_GLOBALS._player.setStrip(1);
+ else
+ R2_GLOBALS._player.setStrip(3);
+ R2_GLOBALS._player.enableControl(CURSOR_TALK);
+ default:
+ _actor1.setPriority(130);
+ _actor2.setPriority(132);
+ _actor3.setPriority(134);
+ signalCase3379();
+ break;
+ }
+}
+
+void Scene3375::dispatch() {
+ if ((R2_GLOBALS._player._position.y >= 168) && (R2_GLOBALS._player._effect == 1))
+ R2_GLOBALS._player._effect = 6;
+ else if ((R2_GLOBALS._player._position.y < 168) && (R2_GLOBALS._player._effect == 6))
+ R2_GLOBALS._player._effect = 1;
+
+ if ((_actor1._position.y >= 168) && (_actor1._effect == 1))
+ _actor1._effect = 6;
+ else if ((_actor1._position.y < 168) && (_actor1._effect == 6))
+ _actor1._effect = 1;
+
+ if ((_actor2._position.y >= 168) && (_actor2._effect == 1))
+ _actor2._effect = 6;
+ else if ((_actor2._position.y < 168) && (_actor2._effect == 6))
+ _actor2._effect = 1;
+
+ if ((_actor3._position.y >= 168) && (_actor3._effect == 1))
+ _actor3._effect = 6;
+ else if ((_actor3._position.y < 168) && (_actor3._effect == 6))
+ _actor3._effect = 1;
+
+ Scene::dispatch();
+}
+
+/*--------------------------------------------------------------------------
+ * Scene 3385 -
+ *
+ *--------------------------------------------------------------------------*/
+Scene3385::Scene3385() {
+ _field11B2 = 0;
+}
+
+void Scene3385::synchronize(Serializer &s) {
+ SceneExt::synchronize(s);
+
+ s.syncAsSint16LE(_field11B2);
+}
+
+bool Scene3385::Actor1::startAction(CursorType action, Event &event) {
+ Scene3385 *scene = (Scene3385 *)R2_GLOBALS._sceneManager._scene;
+
+ if (action != CURSOR_TALK)
+ return SceneActor::startAction(action, event);
+
+ scene->_sceneMode = 9999;
+ if (R2_GLOBALS._player._characterIndex == 2)
+ scene->_stripManager.start(3302, scene);
+ else
+ scene->_stripManager.start(3304, scene);
+
+ return true;
+}
+
+bool Scene3385::Actor2::startAction(CursorType action, Event &event) {
+ Scene3385 *scene = (Scene3385 *)R2_GLOBALS._sceneManager._scene;
+
+ if (action != CURSOR_TALK)
+ return SceneActor::startAction(action, event);
+
+ scene->_sceneMode = 9999;
+ if (R2_GLOBALS._player._characterIndex == 3)
+ scene->_stripManager.start(3302, scene);
+ else
+ scene->_stripManager.start(3301, scene);
+
+ return true;
+}
+
+bool Scene3385::Actor3::startAction(CursorType action, Event &event) {
+ Scene3385 *scene = (Scene3385 *)R2_GLOBALS._sceneManager._scene;
+
+ if (action != CURSOR_TALK)
+ return SceneActor::startAction(action, event);
+
+ scene->_sceneMode = 9999;
+ scene->_stripManager.start(3303, scene);
+
+ return true;
+}
+
+bool Scene3385::Actor4::startAction(CursorType action, Event &event) {
+ Scene3385 *scene = (Scene3385 *)R2_GLOBALS._sceneManager._scene;
+
+ if (action != CURSOR_USE)
+ return SceneActor::startAction(action, event);
+
+ R2_GLOBALS._player.disableControl(CURSOR_ARROW);
+ if (R2_GLOBALS._sceneManager._previousScene == 3375)
+ R2_GLOBALS._sound2.play(314);
+
+ scene->_sceneMode = 3386;
+ scene->setAction(&scene->_sequenceManager, scene, 3386, &R2_GLOBALS._player, &scene->_actor1, &scene->_actor2, &scene->_actor3, &scene->_actor4, NULL);
+
+ return true;
+}
+
+void Scene3385::Exit1::changeScene() {
+ Scene3385 *scene = (Scene3385 *)R2_GLOBALS._sceneManager._scene;
+
+ R2_GLOBALS._player.disableControl(CURSOR_ARROW);
+ scene->_sceneMode = 3387;
+
+ if (R2_GLOBALS._sceneManager._previousScene == 3375)
+ scene->setAction(&scene->_sequenceManager, scene, scene->_sceneMode, &R2_GLOBALS._player, &scene->_actor1, &scene->_actor2, &scene->_actor3, NULL);
+ else
+ scene->signal();
+}
+
+void Scene3385::Action1::signal() {
+ int v = _actionIndex;
+ ++_actionIndex;
+
+ if (v == 0)
+ setDelay(1);
+ else if (v == 1)
+ R2_GLOBALS._sound2.play(314);
+}
+
+void Scene3385::postInit(SceneObjectList *OwnerList) {
+ loadScene(3385);
+ SceneExt::postInit();
+
+ R2_GLOBALS._sound1.play(313);
+
+ _stripManager.setColors(60, 255);
+ _stripManager.setFontNumber(3);
+ _stripManager.addSpeaker(&_quinnSpeaker);
+ _stripManager.addSpeaker(&_seekerSpeaker);
+ _stripManager.addSpeaker(&_mirandaSpeaker);
+ _stripManager.addSpeaker(&_webbsterSpeaker);
+
+ R2_GLOBALS._player._characterScene[1] = 3385;
+ R2_GLOBALS._player._characterScene[2] = 3385;
+ R2_GLOBALS._player._characterScene[3] = 3385;
+
+ if (R2_GLOBALS._sceneManager._previousScene == 3375)
+ _field11B2 = 3;
+ else
+ _field11B2 = 4;
+
+ setZoomPercents(102, 40, 200, 160);
+ R2_GLOBALS._player.postInit();
+
+ if (R2_GLOBALS._player._characterIndex == 2)
+ R2_GLOBALS._player._moveDiff = Common::Point(5, 3);
+ else
+ R2_GLOBALS._player._moveDiff = Common::Point(3, 2);
+
+ R2_GLOBALS._player.changeZoom(-1);
+
+ if (R2_GLOBALS._player._characterIndex == 2)
+ R2_GLOBALS._player.setup(20, _field11B2, 1);
+ else if (R2_GLOBALS._player._characterIndex == 3)
+ R2_GLOBALS._player.setup(30, _field11B2, 1);
+ else
+ R2_GLOBALS._player.setup(10, _field11B2, 1);
+
+ R2_GLOBALS._player.animate(ANIM_MODE_1, NULL);
+ R2_GLOBALS._player.disableControl();
+
+ _actor1.postInit();
+ if (R2_GLOBALS._player._characterIndex == 2) {
+ _actor1._moveRate = 10;
+ _actor1._moveDiff = Common::Point(3, 2);
+ } else {
+ _actor1._moveRate = 7;
+ _actor1._moveDiff = Common::Point(5, 3);
+ }
+ _actor1.changeZoom(-1);
+ _actor1._effect = 1;
+ if (R2_GLOBALS._player._characterIndex == 2)
+ _actor1.setup(10, _field11B2, 1);
+ else
+ _actor1.setup(20, _field11B2, 1);
+ _actor1.animate(ANIM_MODE_1, NULL);
+ _actor1.setDetails(3385, -1, -1, -1, 1, (SceneItem *) NULL);
+
+ _actor2.postInit();
+ _actor2._moveDiff = Common::Point(3, 2);
+ _actor2.changeZoom(-1);
+ _actor2._effect = 1;
+ if (R2_GLOBALS._player._characterIndex == 3)
+ _actor2.setup(10, _field11B2, 1);
+ else
+ _actor2.setup(30, _field11B2, 1);
+ _actor2.animate(ANIM_MODE_1, NULL);
+ _actor2.setDetails(3385, -1, -1, -1, 1, (SceneItem *) NULL);
+
+ _actor3.postInit();
+ _actor3._moveDiff = Common::Point(3, 2);
+ _actor3.changeZoom(-1);
+ _actor3._effect = 1;
+ _actor3.setup(40, _field11B2, 1);
+ _actor3.animate(ANIM_MODE_1, NULL);
+ _actor3.setDetails(3385, 15, -1, -1, 1, (SceneItem *) NULL);
+
+ _exit1.setDetails(Rect(103, 152, 217, 170), SHADECURSOR_DOWN, 3395);
+ _exit1.setDest(Common::Point(158, 151));
+
+ _actor4.postInit();
+ _actor4.setPosition(Common::Point(160, 100));
+ _actor4.fixPriority(90);
+ _actor4.setDetails(3385, 3, 4, -1, 1, (SceneItem *) NULL);
+
+ if (R2_GLOBALS._sceneManager._previousScene == 3375) {
+ R2_GLOBALS._player.setPosition(Common::Point(158, 102));
+ _actor1.setPosition(Common::Point(164, 100));
+ _actor1.fixPriority(98);
+ _actor2.setPosition(Common::Point(150, 100));
+ _actor2.fixPriority(97);
+ _actor3.setPosition(Common::Point(158, 100));
+ _actor3.fixPriority(96);
+ _sceneMode = 3384;
+ _actor4.setup(3385, 1, 6);
+ _actor4.animate(ANIM_MODE_6, this);
+ setAction(&_action1, &_actor4);
+ } else {
+ R2_GLOBALS._player.setPosition(Common::Point(158, 230));
+ _actor1.setPosition(Common::Point(191, 270));
+ _actor2.setPosition(Common::Point(124, 255));
+ _actor3.setPosition(Common::Point(155, 245));
+ _actor4.setup(3385, 1, 1);
+ _sceneMode = 3385;
+ setAction(&_sequenceManager, this, _sceneMode, &R2_GLOBALS._player, &_actor1, &_actor2, &_actor3, NULL);
+ }
+
+ _item1.setDetails(Rect(0, 0, 320, 200), 3385, 0, -1, -1, 1, NULL);
+ R2_GLOBALS._v56A9E = 0;
+}
+
+void Scene3385::remove() {
+ R2_GLOBALS._sound1.fadeOut2(NULL);
+ SceneExt::remove();
+}
+
+void Scene3385::signal() {
+ switch (_sceneMode) {
+ case 3386:
+ R2_GLOBALS._sceneManager.changeScene(3375);
+ break;
+ case 3387:
+ R2_GLOBALS._sceneManager.changeScene(3395);
+ break;
+ case 9999:
+ if (R2_GLOBALS._sceneManager._previousScene == 3375)
+ R2_GLOBALS._player.setStrip(3);
+ else
+ R2_GLOBALS._player.setStrip(4);
+ R2_GLOBALS._player.enableControl(CURSOR_TALK);
+ break;
+ default:
+ R2_GLOBALS._player.enableControl(CURSOR_ARROW);
+ break;
+ }
+}
+
+/*--------------------------------------------------------------------------
+ * Scene 3395 -
+ *
+ *--------------------------------------------------------------------------*/
+Scene3395::Scene3395() {
+ _field142E = 0;
+}
+
+void Scene3395::synchronize(Serializer &s) {
+ SceneExt::synchronize(s);
+
+ s.syncAsSint16LE(_field142E);
+}
+
+bool Scene3395::Actor1::startAction(CursorType action, Event &event) {
+ Scene3395 *scene = (Scene3395 *)R2_GLOBALS._sceneManager._scene;
+
+ if (action != CURSOR_TALK)
+ return SceneActor::startAction(action, event);
+
+ scene->_sceneMode = 9999;
+ if (R2_GLOBALS._player._characterIndex == 2)
+ scene->_stripManager.start(3302, scene);
+ else
+ scene->_stripManager.start(3304, scene);
+
+ return true;
+}
+
+bool Scene3395::Actor2::startAction(CursorType action, Event &event) {
+ Scene3395 *scene = (Scene3395 *)R2_GLOBALS._sceneManager._scene;
+
+ if (action != CURSOR_TALK)
+ return SceneActor::startAction(action, event);
+
+ scene->_sceneMode = 9999;
+ if (R2_GLOBALS._player._characterIndex == 3)
+ scene->_stripManager.start(3302, scene);
+ else
+ scene->_stripManager.start(3301, scene);
+
+ return true;
+}
+
+bool Scene3395::Actor3::startAction(CursorType action, Event &event) {
+ Scene3395 *scene = (Scene3395 *)R2_GLOBALS._sceneManager._scene;
+
+ if (action != CURSOR_TALK)
+ return SceneActor::startAction(action, event);
+
+ scene->_sceneMode = 9999;
+ scene->_stripManager.start(3303, scene);
+
+ return true;
+}
+
+bool Scene3395::Actor4::startAction(CursorType action, Event &event) {
+ Scene3395 *scene = (Scene3395 *)R2_GLOBALS._sceneManager._scene;
+
+ if (action != CURSOR_USE)
+ return SceneActor::startAction(action, event);
+
+ R2_GLOBALS._player.disableControl(CURSOR_ARROW);
+ if (R2_GLOBALS._sceneManager._previousScene == 3385)
+ R2_GLOBALS._sound2.play(314);
+
+ scene->_sceneMode = 3396;
+ scene->setAction(&scene->_sequenceManager, scene, 3396, &R2_GLOBALS._player, &scene->_actor1, &scene->_actor2, &scene->_actor3, &scene->_actor4, NULL);
+
+ return true;
+}
+
+void Scene3395::Action1::signal() {
+ int v = _actionIndex;
+ ++_actionIndex;
+
+ if (v == 0)
+ setDelay(2);
+ else if (v == 1)
+ R2_GLOBALS._sound2.play(314);
+}
+
+void Scene3395::postInit(SceneObjectList *OwnerList) {
+ loadScene(3395);
+ SceneExt::postInit();
+
+ R2_GLOBALS._sound1.play(313);
+
+ _stripManager.setColors(60, 255);
+ _stripManager.setFontNumber(3);
+ _stripManager.addSpeaker(&_quinnSpeaker);
+ _stripManager.addSpeaker(&_seekerSpeaker);
+ _stripManager.addSpeaker(&_mirandaSpeaker);
+ _stripManager.addSpeaker(&_webbsterSpeaker);
+
+ R2_GLOBALS._player._characterScene[1] = 3395;
+ R2_GLOBALS._player._characterScene[2] = 3395;
+ R2_GLOBALS._player._characterScene[3] = 3395;
+
+ if (R2_GLOBALS._sceneManager._previousScene == 3385)
+ _field142E = 3;
+ else
+ _field142E = 4;
+
+ setZoomPercents(51, 40, 200, 137);
+ R2_GLOBALS._player.postInit();
+
+ if (R2_GLOBALS._player._characterIndex == 2)
+ R2_GLOBALS._player._moveDiff = Common::Point(5, 3);
+ else
+ R2_GLOBALS._player._moveDiff = Common::Point(3, 2);
+
+ R2_GLOBALS._player.changeZoom(-1);
+
+ if (R2_GLOBALS._player._characterIndex == 2)
+ R2_GLOBALS._player.setup(20, _field142E, 1);
+ else if (R2_GLOBALS._player._characterIndex == 3)
+ R2_GLOBALS._player.setup(30, _field142E, 1);
+ else
+ R2_GLOBALS._player.setup(10, _field142E, 1);
+
+ R2_GLOBALS._player.animate(ANIM_MODE_1, NULL);
+ R2_GLOBALS._player.disableControl();
+
+ _actor1.postInit();
+ if (R2_GLOBALS._player._characterIndex == 2) {
+ _actor1._moveRate = 10;
+ _actor1._moveDiff = Common::Point(3, 2);
+ } else {
+ _actor1._moveRate = 7;
+ _actor1._moveDiff = Common::Point(5, 3);
+ }
+ _actor1.changeZoom(-1);
+ _actor1._effect = 1;
+ if (R2_GLOBALS._player._characterIndex == 2)
+ _actor1.setup(10, _field142E, 1);
+ else
+ _actor1.setup(20, _field142E, 1);
+ _actor1.animate(ANIM_MODE_1, NULL);
+ _actor1.setDetails(3395, -1, -1, -1, 1, (SceneItem *) NULL);
+
+ _actor2.postInit();
+ _actor2._moveDiff = Common::Point(3, 2);
+ _actor2.changeZoom(-1);
+ _actor2._effect = 1;
+ if (R2_GLOBALS._player._characterIndex == 3)
+ _actor2.setup(10, _field142E, 1);
+ else
+ _actor2.setup(30, _field142E, 1);
+ _actor2.animate(ANIM_MODE_1, NULL);
+ _actor2.setDetails(3395, -1, -1, -1, 1, (SceneItem *) NULL);
+
+ _actor3.postInit();
+ _actor3._moveDiff = Common::Point(3, 2);
+ _actor3.changeZoom(-1);
+ _actor3._effect = 1;
+ _actor3.setup(40, _field142E, 1);
+ _actor3.animate(ANIM_MODE_1, NULL);
+ _actor3.setDetails(3385, 18, -1, -1, 1, (SceneItem *) NULL);
+
+ _actor4.postInit();
+ _actor4.setPosition(Common::Point(159, 50));
+ _actor4.fixPriority(40);
+ _actor4.setDetails(3395, 6, 7, -1, 1, (SceneItem *) NULL);
+
+ if (R2_GLOBALS._sceneManager._previousScene == 3385) {
+ R2_GLOBALS._player.setPosition(Common::Point(158, 53));
+ _actor1.setPosition(Common::Point(164, 51));
+ _actor1.fixPriority(48);
+ _actor2.setPosition(Common::Point(150, 51));
+ _actor2.fixPriority(47);
+ _actor3.setPosition(Common::Point(158, 51));
+ _actor3.fixPriority(46);
+ _sceneMode = 3394;
+ _actor4.setup(3395, 1, 7);
+ _actor4.animate(ANIM_MODE_6, this);
+ setAction(&_action1, &_actor4);
+ } else {
+ R2_GLOBALS._player.setPosition(Common::Point(158, 200));
+ _actor1.setPosition(Common::Point(191, 255));
+ _actor2.setPosition(Common::Point(124, 240));
+ _actor3.setPosition(Common::Point(155, 242));
+ _actor4.setup(3395, 1, 1);
+
+ R2_GLOBALS._walkRegions.enableRegion(1);
+
+ _sceneMode = 3395;
+ setAction(&_sequenceManager, this, _sceneMode, &R2_GLOBALS._player, &_actor1, &_actor2, &_actor3, NULL);
+ }
+
+ for (int i = 0; i <= 12; i++) {
+ _itemArray[i].setDetails(i, 3995, 0, -1, -1);
+ }
+
+ _item1.setDetails(Rect(0, 0, 320, 200), 3395, 3, -1, -1, 1, NULL);
+}
+
+void Scene3395::remove() {
+ R2_GLOBALS._sound1.fadeOut2(NULL);
+ SceneExt::remove();
+}
+
+void Scene3395::signal() {
+ switch (_sceneMode) {
+ case 3396:
+ R2_GLOBALS._sceneManager.changeScene(3385);
+ break;
+ case 9999:
+ if (R2_GLOBALS._sceneManager._previousScene == 3385)
+ R2_GLOBALS._player.setStrip(3);
+ else
+ R2_GLOBALS._player.setStrip(4);
+ R2_GLOBALS._player.enableControl(CURSOR_TALK);
+ break;
+ default:
+ R2_GLOBALS._player.enableControl(CURSOR_ARROW);
+ break;
+ }
+}
+
+/*--------------------------------------------------------------------------
+ * Scene 3400 -
+ *
+ *--------------------------------------------------------------------------*/
+Scene3400::Scene3400() {
+ _field157C = 0;
+}
+
+void Scene3400::synchronize(Serializer &s) {
+ SceneExt::synchronize(s);
+
+ s.syncAsSint16LE(_field157C);
+}
+
+void Scene3400::postInit(SceneObjectList *OwnerList) {
+ R2_GLOBALS._scrollFollower = &R2_GLOBALS._player;
+ g_globals->gfxManager()._bounds.moveTo(Common::Point(160, 0));
+ loadScene(3400);
+ _field157C = 0;
+ R2_GLOBALS._v558B6.set(60, 0, 260, 200);
+ SceneExt::postInit();
+ R2_GLOBALS._sound1.play(317);
+
+ _stripManager.setColors(60, 255);
+ _stripManager.setFontNumber(3);
+ _stripManager.addSpeaker(&_quinnSpeaker);
+ _stripManager.addSpeaker(&_seekerSpeaker);
+ _stripManager.addSpeaker(&_mirandaSpeaker);
+ _stripManager.addSpeaker(&_webbsterSpeaker);
+ _stripManager.addSpeaker(&_tealSpeaker);
+
+ setZoomPercents(51, 46, 180, 200);
+ R2_GLOBALS._player._characterScene[1] = 3400;
+ R2_GLOBALS._player._characterScene[2] = 3400;
+ R2_GLOBALS._player._characterScene[3] = 3400;
+
+ _actor7.postInit();
+ _actor7.setup(3403, 1, 1);
+ _actor7.setPosition(Common::Point(190, 103));
+ _actor7.fixPriority(89);
+
+ R2_GLOBALS._player.postInit();
+ if (R2_GLOBALS._player._characterIndex == 2)
+ R2_GLOBALS._player._moveDiff = Common::Point(5, 3);
+ else
+ R2_GLOBALS._player._moveDiff = Common::Point(3, 2);
+ R2_GLOBALS._player.changeZoom(-1);
+ R2_GLOBALS._player.setPosition(Common::Point(239, 64));
+
+ if (R2_GLOBALS._player._characterIndex == 2)
+ R2_GLOBALS._player.setup(20, 5, 1);
+ else if (R2_GLOBALS._player._characterIndex == 3)
+ R2_GLOBALS._player.setup(30, 5, 1);
+ else
+ R2_GLOBALS._player.setup(10, 5, 1);
+
+ R2_GLOBALS._player.animate(ANIM_MODE_1, NULL);
+ R2_GLOBALS._player.disableControl();
+
+ _actor1.postInit();
+ if (R2_GLOBALS._player._characterIndex == 2) {
+ _actor1._numFrames = 10;
+ _actor1._moveDiff = Common::Point(3, 2);
+ } else {
+ _actor1._numFrames = 7;
+ _actor1._moveDiff = Common::Point(5, 3);
+ }
+ _actor1.changeZoom(-1);
+ _actor1._effect = 1;
+ _actor1.setPosition(Common::Point(247, 63));
+ if (R2_GLOBALS._player._characterIndex == 2)
+ _actor1.setup(10, 5, 1);
+ else
+ _actor1.setup(20, 5, 1);
+ _actor1.animate(ANIM_MODE_1, NULL);
+
+ _actor2.postInit();
+ _actor2._moveDiff = Common::Point(3, 2);
+ _actor2.changeZoom(-1);
+ _actor2._effect = 1;
+ _actor2.setPosition(Common::Point(225, 63));
+ if (R2_GLOBALS._player._characterIndex == 3)
+ _actor2.setup(10, 5, 1);
+ else
+ _actor2.setup(30, 5, 1);
+ _actor2.animate(ANIM_MODE_1, NULL);
+
+ _actor3.postInit();
+ _actor3._numFrames = 7;
+ _actor3._moveDiff = Common::Point(5, 3);
+ _actor3.changeZoom(-1);
+ _actor3._effect = 1;
+ _actor3.setPosition(Common::Point(235, 61));
+ _actor3.setup(40, 3, 1);
+ _actor3.animate(ANIM_MODE_1, NULL);
+
+ _actor6.postInit();
+ _actor6.setup(3400, 1, 6);
+ _actor6.setPosition(Common::Point(236, 51));
+ _actor6.fixPriority(51);
+ _actor6.animate(ANIM_MODE_6, NULL);
+
+ R2_GLOBALS.clearFlag(71);
+ _sceneMode = 3400;
+ setAction(&_sequenceManager, this, 3400, &R2_GLOBALS._player, &_actor1, &_actor2, &_actor3, NULL);
+}
+
+void Scene3400::remove() {
+ R2_GLOBALS._sound2.fadeOut2(NULL);
+ R2_GLOBALS._sound1.fadeOut2(NULL);
+ SceneExt::remove();
+}
+
+void Scene3400::signal() {
+ switch (_sceneMode) {
+ case 3305: {
+ warning("STUB: sub_1D227()");
+ _tealSpeaker._object1.hide();
+ _actor4.show();
+ _actor4.setStrip(1);
+ Common::Point pt(158, 190);
+ NpcMover *mover = new NpcMover();
+ _actor4.addMover(mover, &pt, this);
+ _sceneMode = 3402;
+ setAction(&_sequenceManager, this, 3402, &R2_GLOBALS._player, &_actor1, &_actor2, &_actor3, NULL);
+ }
+ break;
+ case 3306:
+ R2_GLOBALS._sound2.play(318);
+ _actor1.setStrip(2);
+ R2_GLOBALS._player.setStrip(6);
+ _actor2.setStrip(6);
+ _actor3.setStrip(3);
+ _actor4.setStrip(1);
+ R2_INVENTORY.setObjectScene(34, 0);
+ _stripManager.start(3307, this);
+ if (R2_GLOBALS._player._characterIndex == 2) {
+ _sceneMode = 3400;
+ R2_GLOBALS._player.setAction(&_sequenceManager, this, 3400, &R2_GLOBALS._player, &_actor4, &_actor8, NULL);
+ } else {
+ _sceneMode = 3408;
+ _actor1.setAction(&_sequenceManager, this, 3408, &_actor1, &_actor4, &_actor8, NULL);
+ }
+ break;
+ case 3307:
+ case 3404:
+ case 3408:
+ if (_field157C == 0) {
+ R2_GLOBALS._sound2.fadeOut2(NULL);
+ _field157C = 1;
+ } else {
+ _sceneMode = 3308;
+ _stripManager.start(3308, this);
+ }
+ break;
+ case 3308:
+ warning("STUB: sub_1D227()");
+ _actor1.setStrip(2);
+ R2_GLOBALS._player.setStrip(6);
+ _actor2.setStrip(6);
+ _actor3.setStrip(3);
+ _actor4.setStrip(1);
+ _sceneMode = 3403;
+ if (R2_GLOBALS._player._characterIndex == 2)
+ setAction(&_sequenceManager, this, 3403, &R2_GLOBALS._player, &_actor3, &_actor7, NULL);
+ else
+ setAction(&_sequenceManager, this, 3403, &_actor1, &_actor3, &_actor7, NULL);
+ break;
+ case 3309:
+ warning("STUB: sub_1D227()");
+ _actor4.setStrip(1);
+ _sceneMode = 3405;
+ if (R2_GLOBALS._player._characterIndex == 3)
+ setAction(&_sequenceManager, this, 3405, &R2_GLOBALS._player, &_actor7, NULL);
+ else
+ setAction(&_sequenceManager, this, 3405, &_actor2, &_actor7, NULL);
+ break;
+ case 3310:
+ warning("STUB: sub_1D227()");
+ _actor4.setStrip(1);
+ _sceneMode = 3406;
+ if (R2_GLOBALS._player._characterIndex == 1)
+ setAction(&_sequenceManager, this, 3406, &R2_GLOBALS._player, &_actor7, NULL);
+ else if (R2_GLOBALS._player._characterIndex == 2)
+ setAction(&_sequenceManager, this, 3406, &_actor1, &_actor7, NULL);
+ else if (R2_GLOBALS._player._characterIndex == 3)
+ setAction(&_sequenceManager, this, 3406, &_actor2, &_actor7, NULL);
+ break;
+ case 3311:
+ warning("STUB: sub_1D227()");
+ _tealSpeaker._object1.hide();
+ _actor4.show();
+ _actor4.setStrip(1);
+ _sceneMode = 3407;
+ setAction(&_sequenceManager, this, 3407, &_actor4, &_actor7, NULL);
+ break;
+ case 3400: {
+ _actor8.postInit();
+ _actor8.hide();
+ _actor4.postInit();
+ _actor4._numFrames = 7;
+ _actor4._moveDiff = Common::Point(3, 2);
+ _actor4.changeZoom(-1);
+ _actor4._effect = 1;
+ _actor4.setPosition(Common::Point(-15, 90));
+ _actor4.setup(3402, 1, 1);
+ _actor4.animate(ANIM_MODE_1, NULL);
+ Common::Point pt1(115, 90);
+ NpcMover *mover1 = new NpcMover();
+ _actor4.addMover(mover1, &pt1, this);
+ R2_GLOBALS._scrollFollower = &_actor4;
+ Common::Point pt2(203, 76);
+ NpcMover *mover2 = new NpcMover();
+ _actor3.addMover(mover2, &pt2, NULL);
+ _sceneMode = 3401;
+ }
+ break;
+ case 3401:
+ _sceneMode = 3305;
+ _stripManager.start(3305, this);
+ break;
+ case 3402:
+ _sceneMode = 3306;
+ _stripManager.start(3306, this);
+ break;
+ case 3403:
+ R2_GLOBALS._scrollFollower = &R2_GLOBALS._player;
+ _sceneMode = 3309;
+ _stripManager.start(3309, this);
+ break;
+ case 3405:
+ _sceneMode = 3310;
+ _stripManager.start(3310, this);
+ break;
+ case 3406:
+ _sceneMode = 3311;
+ _stripManager.start(3311, this);
+ break;
+ case 3407:
+ R2_GLOBALS._sceneManager.changeScene(3600);
+ break;
+ default:
+ R2_GLOBALS._player.enableControl();
+ break;
+ }
+}
+
+/*--------------------------------------------------------------------------
+ * Scene 3500 -
+ *
+ *--------------------------------------------------------------------------*/
+Scene3500::Action1::Action1() {
+ _field1E = 0;
+ _field20 = 0;
+ _field22 = 0;
+ _field24 = 0;
+}
+
+void Scene3500::Action1::synchronize(Serializer &s) {
+ Action::synchronize(s);
+
+ s.syncAsSint16LE(_field1E);
+ s.syncAsSint16LE(_field20);
+ s.syncAsSint16LE(_field22);
+ s.syncAsSint16LE(_field24);
+}
+
+void Scene3500::Action1::sub108670(int arg1) {
+ Scene3500 *scene = (Scene3500 *)R2_GLOBALS._sceneManager._scene;
+
+ _field1E = arg1;
+ _field20 = 1;
+ _field24 = 1;
+
+ scene->_actor9.setStrip(2);
+ scene->_actor9.show();
+
+ if (_field1E == 1)
+ scene->_actor6.show();
+ else
+ scene->_actor5.show();
+
+ if (scene->_actor1._frame % 2 == 0)
+ scene->_actor1._frameChange = _field1E;
+ scene->_actor1.setFrame(scene->_actor1.changeFrame());
+
+ setActionIndex(0);
+}
+
+void Scene3500::Action1::sub108732(int arg1) {
+ Scene3500 *scene = (Scene3500 *)R2_GLOBALS._sceneManager._scene;
+
+ _field20 = arg1;
+ _field1E = -_field1E;
+
+ if (_field1E == 1) {
+ scene->_actor6.show();
+ scene->_actor5.hide();
+ } else {
+ scene->_actor5.show();
+ scene->_actor6.hide();
+ }
+
+ switch (_actionIndex) {
+ case 4:
+ scene->_actor1._frameChange = _field1E;
+ scene->_actor1.setFrame(scene->_actor1.changeFrame());
+ // No break on purpose
+ case 3:
+ _actionIndex = 10;
+ setDelay(0);
+ break;
+ case 5: {
+ scene->_fieldAF8 = 160;
+ Common::Point pt(160, 73);
+ NpcMover *mover = new NpcMover();
+ scene->_actor8.addMover(mover, &pt, NULL);
+
+ scene->_fieldB9E = 160 - (_field1E * 2 * 160);
+ Common::Point pt2(scene->_fieldB9E, 73);
+ NpcMover *mover2 = new NpcMover();
+ scene->_actor9.addMover(mover2, &pt2, this);
+
+ _actionIndex = 11;
+ }
+ break;
+ case 6:
+ scene->_actor1._frameChange = _field1E;
+ scene->_actor1.setFrame(scene->_actor1.changeFrame());
+ setDelay(1);
+ // No break on purpose
+ case 8:
+ scene->_actor9.setStrip(2);
+ _actionIndex = 1;
+ break;
+ default:
+ break;
+ }
+}
+
+Scene3500::Action2::Action2() {
+ _field1E = 0;
+}
+
+void Scene3500::Action2::synchronize(Serializer &s) {
+ Action::synchronize(s);
+
+ s.syncAsSint16LE(_field1E);
+}
+
+Scene3500::Item4::Item4() {
+ _field34 = 0;
+}
+
+void Scene3500::Item4::synchronize(Serializer &s) {
+ NamedHotspot::synchronize(s);
+
+ s.syncAsSint16LE(_field34);
+}
+
+Scene3500::Actor7::Actor7() {
+ _fieldA4 = 0;
+ _fieldA6 = 0;
+ _fieldA8 = 0;
+ _fieldAA = 0;
+ _fieldAC = 0;
+ _fieldAE = 0;
+}
+
+void Scene3500::Actor7::synchronize(Serializer &s) {
+ SceneActor::synchronize(s);
+
+ s.syncAsSint16LE(_fieldA4);
+ s.syncAsSint16LE(_fieldA6);
+ s.syncAsSint16LE(_fieldA8);
+ s.syncAsSint16LE(_fieldAA);
+ s.syncAsSint16LE(_fieldAC);
+ s.syncAsSint16LE(_fieldAE);
+}
+
+void Scene3500::Actor7::sub109466(int arg1, int arg2, int arg3, int arg4, int arg5) {
+ _fieldAE = 0;
+ _fieldA4 = arg1;
+ _fieldA6 = arg2;
+ _fieldA8 = arg3;
+ _fieldAA = arg4;
+ _fieldAC = _fieldAA / _fieldA8;
+
+ postInit();
+ setup(10501, 3, 1);
+ fixPriority(255);
+ sub109663(arg5);
+}
+
+void Scene3500::Actor7::sub1094ED() {
+ Scene3500 *scene = (Scene3500 *)R2_GLOBALS._sceneManager._scene;
+
+ scene->_field1270 = _position.x - _fieldA4;
+}
+
+void Scene3500::Actor7::sub109663(int arg1){
+ sub109693(Common::Point(_fieldA4 + arg1, _fieldA6 - (_fieldAC * arg1)));
+}
+
+void Scene3500::Actor7::sub109693(Common::Point Pt) {
+ setPosition(Pt);
+}
+
+int Scene3500::UnkObject3500::sub1097C9(int arg1) {
+ return (_field2A / 2) + arg1 - (arg1 % _field2A);
+}
+
+int Scene3500::UnkObject3500::sub1097EF(int arg1) {
+ return (_field2C / 2) + arg1 - (arg1 % _field2C);
+}
+
+int Scene3500::UnkObject3500::sub109C09(Common::Point pt) {
+ int vx = pt.x / _field2A;
+ int vy = pt.y / _field2C;
+
+ if ((vx >= 0) && (_field26 > vx) && (_field28 > vy)) {
+ return _field16[((_field26 * vy) + vx) * 2];
+ } else
+ return -1;
+}
+
+int Scene3500::UnkObject3500::sub109C5E(int &x, int &y) {
+ int retVal = sub51AFD(Common::Point(x, y));
+ x = _field2E;
+ y = _field30;
+
+ return retVal;
+}
+
+Scene3500::Scene3500() {
+ _fieldAF8 = 0;
+ _fieldB9E = 0;
+ _rotation = NULL;
+ _field126E = 0;
+ _field1270 = 0;
+ _field1272 = 0;
+ _field1274 = 0;
+ _field1276 = 0;
+ _field1278 = 0;
+ _field127A = 0;
+ _field127C = 0;
+ _field127E = 0;
+ _field1280 = 0;
+ _field1282 = 0;
+ _field1284 = 0;
+ _field1286 = 0;
+}
+
+void Scene3500::synchronize(Serializer &s) {
+ SceneExt::synchronize(s);
+ SYNC_POINTER(_rotation);
+
+ s.syncAsSint16LE(_fieldAF8);
+ s.syncAsSint16LE(_fieldB9E);
+ s.syncAsSint16LE(_field126E);
+ s.syncAsSint16LE(_field1270);
+ s.syncAsSint16LE(_field1272);
+ s.syncAsSint16LE(_field1274);
+ s.syncAsSint16LE(_field1276);
+ s.syncAsSint16LE(_field1278);
+ s.syncAsSint16LE(_field127A);
+ s.syncAsSint16LE(_field127C);
+ s.syncAsSint16LE(_field127E);
+ s.syncAsSint16LE(_field1280);
+ s.syncAsSint16LE(_field1282);
+ s.syncAsSint16LE(_field1284);
+ s.syncAsSint16LE(_field1286);
+}
+
+void Scene3500::sub107F71(int arg1) {
+ switch (arg1) {
+ case -1:
+ _actor7.sub1094ED();
+ if (_field1270 != 0) {
+ _field1270--;
+ _actor7.sub109663(_field1270);
+ }
+ if (_action1._field24 != 0)
+ _field1270 = 0;
+ break;
+ case 1:
+ _actor7.sub1094ED();
+ if (_field1270 < 16) {
+ ++_field1270;
+ _actor7.sub109663(_field1270);
+ }
+ if (_action1._field24 != 0)
+ _field1270 = 0;
+ break;
+ case 88:
+ if ((_action == 0) || (_action1._field24 == 0)) {
+ // The original makes a second useless check on action, skipped
+ _action2.sub10831F(2);
+ if ((_action) && ((_action2.getActionIndex() != 0) || (_action2._field1E != 2))) {
+ _action2.signal();
+ } else {
+ _actor9.setAction(&_action2, &_actor9, NULL);
+ }
+ }
+ break;
+ case 96:
+ if ((_action) && (_action1._field24 != 0) && (_action2._field1E != 1)) {
+ _field1278 = 0;
+ _action1.sub108732(0);
+ } else if ((_action) && (_field1278 == 0) && (_action1._field24 != 0)) {
+ _field1278 = arg1;
+ } else if ((_action) && (_action1._field24 == 0)) {
+ _action1.sub108670(1);
+ _action1.signal();
+ } else if (_action == 0) {
+ _action1.sub108670(1);
+ setAction(&_action1, &_actor1, NULL);
+ }
+ break;
+ case 104:
+ if ((_action == 0) || (_action1._field24 == 0)) {
+ _action2.sub10831F(-1);
+ if ((_action) && ((_action2.getActionIndex() != 0) || (_action2._field1E != -1))) {
+ _action2.signal();
+ } else {
+ _actor9.setAction(&_action2, &_actor9, NULL);
+ }
+ }
+ break;
+ case 112:
+ if ((_action) && (_action1._field24 != 0) && (_action2._field1E != -1)) {
+ _field1278 = 0;
+ _action1.sub108732(0);
+ } else if ((_action) && (_field1278 == 0) && (_action1._field24 != 0)) {
+ _field1278 = arg1;
+ } else if ((_action) && (_action1._field24 == 0)) {
+ _action1.sub108670(-1);
+ _action1.signal();
+ } else if (_action == 0) {
+ _action1.sub108670(-1);
+ setAction(&_action1, &_actor1, NULL);
+ }
+ break;
+ default:
+ _field1270 = arg1;
+ _actor7.sub109663(arg1);
+ if (_action1._field24 != 0) {
+ _field1270 = 0;
+ }
+ break;
+ }
+}
+
+void Scene3500::Action1::signal() {
+ Scene3500 *scene = (Scene3500 *)R2_GLOBALS._sceneManager._scene;
+
+ switch(_actionIndex++) {
+ case 0:
+ R2_GLOBALS._player.disableControl();
+ scene->_field1286 = 0;
+ if (scene->_field1270 != 0) {
+ scene->_field1270 = 0;
+ scene->_field126E = 0;
+ scene->_field1272 = 0;
+ scene->_rotation->_idxChange = 0;
+ }
+ break;
+ case 1:
+ if ((scene->_actor1._frame % 2) == 0) {
+ setDelay(1);
+ return;
+ }
+ // No break on purpose
+ case 3:
+ scene->_actor1._frameChange = _field1E;
+ scene->_actor1.setFrame(scene->_actor1.changeFrame());
+ setDelay(1);
+ break;
+ case 4: {
+ int si = scene->_unkObj1.sub109C09(Common::Point(scene->_field127A + 70, scene->_field127C + 46));
+ int var2 = scene->_unkObj1.sub1097C9(scene->_field127A + 70) - 70;
+ int var4 = scene->_unkObj1.sub1097EF(scene->_field127C + 46) - 46;
+ int di = abs(var2 - scene->_field127A);
+ int var6 = abs(var4 - scene->_field127C);
+
+ if ((scene->_actor1._frame % 2) != 0) {
+ scene->_actor1._frameChange = _field1E;
+ scene->_actor1.setFrame(scene->_actor1.changeFrame());
+ }
+
+ int var8 = (scene->_action1._field1E * 2 + scene->_field1276);
+ if (var8 > 7)
+ var8 = 1;
+ else if (var8 < 1)
+ var8 = 7;
+
+ switch (var8) {
+ case 0:
+ if ( ((si != 2) && (si != 3) && (si != 6) && (si != 1) && (si != 23) && (si != 24) && (si != 4) && (si != 11))
+ || (var6 != 0)) {
+ if ((si != 25) && (si != 26) && (si != 5) && (si != 14) && (si != 15))
+ _field20 = 0;
+ else if ((var6 != 0) || (di <= 3)) // useless, skipped: "|| (di == 0)"
+ _field20 = 0;
+ else
+ _field20 = 1;
+ } else
+ _field20 = 1;
+ break;
+ case 2:
+ if ( ((si != 12) && (si != 13) && (si != 11) && (si != 16) && (si != 26) && (si != 24) && (si != 15) && (si != 6) && (si != 31))
+ || (di != 0)) {
+ if ((si != 25) && (si != 23) && (si != 14) && (si != 5) && (si != 4))
+ _field20 = 0;
+ else if ((di != 0) || (var6 <= 3)) // useless, skipped: "|| (var6 == 0)"
+ _field20 = 0;
+ else
+ _field20 = 1;
+ } else
+ _field20 = 1;
+ break;
+ case 4:
+ if ( ((si != 2) && (si != 3) && (si != 6) && (si != 1) && (si != 25) && (si != 26) && (si != 5) && (si != 16) && (si != 31))
+ || (var6 != 0)) {
+ if ((si != 23) && (si != 24) && (si != 4) && (si != 14) && (si != 15))
+ _field20 = 0;
+ else if ((var6 != 0) || (di <= 3)) // useless, skipped: "|| (di == 0)"
+ _field20 = 0;
+ else
+ _field20 = 1;
+ } else
+ _field20 = 1;
+ break;
+ case 6:
+ if ( ((si != 12) && (si != 13) && (si != 11) && (si != 16) && (si != 25) && (si != 23) && (si != 14) && (si != 1) && (si != 31))
+ || (var6 != 0)) {
+ if ((si != 26) && (si != 24) && (si != 15) && (si != 5) && (si != 4))
+ _field20 = 0;
+ else if ((var6 <= 0) || (di != 0)) // useless, skipped: "|| (var6 == 0)"
+ _field20 = 0;
+ else
+ _field20 = 1;
+ } else
+ _field20 = 1;
+ default:
+ break;
+ }
+ }
+ // No break on purpose
+ case 2: {
+ scene->_actor8.setPosition(Common::Point(160, 73));
+ scene->_actor8._moveDiff.x = 160 - scene->_field126E;
+ scene->_fieldAF8 = 160 - ((_field1E * 2) * 160);
+ Common::Point pt(scene->_fieldAF8, 73);
+ NpcMover *mover = new NpcMover();
+ scene->_actor8.addMover(mover, &pt, this);
+
+ scene->_actor9.setPosition(Common::Point(160 + ((_field1E * 2) * 160), 73));;
+ scene->_actor9._moveDiff.x = 160 - scene->_field126E;
+ scene->_fieldB9E = 160;
+ Common::Point pt2(scene->_fieldB9E, 73);
+ NpcMover *mover2 = new NpcMover();
+ scene->_actor9.addMover(mover2, &pt2, NULL);
+ }
+ break;
+ case 5:
+ scene->_actor1._frameChange = _field1E;
+ scene->_field1276 = scene->_actor1.changeFrame();
+ scene->_actor1.setFrame(scene->_field1276);
+ setDelay(1);
+ break;
+ case 6:
+ scene->_actor8.setPosition(Common::Point(160, 73));
+ if (_field20 == 0)
+ scene->_actor8.setStrip(1);
+ else
+ scene->_actor8.setStrip(2);
+ scene->_actor8.fixPriority(1);
+
+ scene->_actor9.setPosition(Common::Point(-160, 73));
+ scene->_actor9.setStrip(9);
+ scene->_actor9.fixPriority(11);
+ scene->_actor9.hide();
+ setDelay(1);
+ break;
+ case 7:
+ if ((scene->_actor1._frame % 2) == 0) {
+ scene->_actor1._frameChange = _field1E;
+ scene->_field1276 = scene->_actor1.changeFrame();
+ scene->_actor1.setFrame(scene->_field1276);
+ }
+ setDelay(1);
+ break;
+ case 8: {
+ R2_GLOBALS._player.enableControl();
+ R2_GLOBALS._player._canWalk = false;
+ scene->_field1286 = 1;
+ if ((scene->_actor1._frame % 2) == 0) {
+ scene->_actor1._frameChange = _field1E;
+ scene->_actor1.setFrame(scene->_actor1.changeFrame());
+ }
+ // All the var_8 initialization was missing in the original
+ // but it's clearly a cut and paste error from case 4.
+ // The following code allows the switch to work properly.
+ warning("Checkme: fix for dead code");
+ int var_8 = (_field1E * 2 + scene->_field1276);
+ if (var_8 > 7)
+ var_8 = 1;
+ else if (var_8 < 1)
+ var_8 = 7;
+ //
+
+ switch (var_8 - 1) {
+ case 0:
+ // No break on purpose
+ case 4:
+ scene->_field127A = scene->_unkObj1.sub1097C9(scene->_field127A + 70) - 70;
+ break;
+ case 2:
+ // No break on purpose
+ case 6:
+ scene->_field127C = scene->_unkObj1.sub1097EF(scene->_field127C + 46) - 46;
+ break;
+ default:
+ break;
+ }
+ scene->_actor5.hide();
+ scene->_actor6.hide();
+ _field24 = 0;
+ if (_field20 == 0) {
+ scene->_actor7.sub1094ED();
+ if (scene->_field126E == scene->_field1270)
+ scene->_aSound1.play(276);
+ }
+ break;
+ }
+ case 10: {
+ scene->_fieldAF8 = 160;
+ Common::Point pt(160, 73);
+ NpcMover *mover = new NpcMover();
+ scene->_actor8.addMover(mover, &pt, NULL);
+
+ scene->_fieldB9E = 160 - (_field1E * 2 * 160);
+ Common::Point pt2(scene->_fieldB9E, 73);
+ NpcMover *mover2 = new NpcMover();
+ scene->_actor9.addMover(mover2, &pt2, this);
+ _actionIndex = 6;
+ }
+ break;
+ case 11: {
+ scene->_actor8.setStrip(2);
+ scene->_actor8.setPosition(Common::Point(160, 73));
+ scene->_fieldAF8 = 160 - (_field1E * 2 * 160);
+ Common::Point pt(scene->_fieldAF8, 73);
+ NpcMover *mover = new NpcMover();
+ scene->_actor8.addMover(mover, &pt, NULL);
+ scene->_actor8.fixPriority(11);
+ if (_field20 == 0)
+ scene->_actor9.setStrip(1);
+ else
+ scene->_actor9.setStrip(2);
+ scene->_actor9.setPosition(Common::Point(160 - (_field1E * 2 * 160), 73));
+ scene->_fieldB9E = 160;
+ Common::Point pt2(scene->_fieldB9E, 73);
+ NpcMover *mover2 = new NpcMover();
+ scene->_actor9.addMover(mover2, &pt2, this);
+ scene->_actor9.fixPriority(1);
+ _actionIndex = 5;
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+void Scene3500::Action1::dispatch() {
+ Scene3500 *scene = (Scene3500 *)R2_GLOBALS._sceneManager._scene;
+
+ Action::dispatch();
+ if ((_actionIndex == 1) && (scene->_field126E <= 4)) {
+ scene->_rotation->_idxChange = 0;
+ signal();
+ }
+}
+
+void Scene3500::Action2::sub10831F(int arg1) {
+ Scene3500 *scene = (Scene3500 *)R2_GLOBALS._sceneManager._scene;
+
+ _field1E = arg1;
+ if (_field1E == -1)
+ scene->_actor3.setFrame2(3);
+ else
+ scene->_actor3.setFrame2(1);
+
+ setActionIndex(0);
+}
+
+void Scene3500::Action2::signal() {
+ Scene3500 *scene = (Scene3500 *)R2_GLOBALS._sceneManager._scene;
+
+ int si;
+ int di;
+
+ switch (_actionIndex++) {
+ case 0: {
+ if (scene->_actor8._mover) {
+ si = scene->_fieldAF8;
+ di = scene->_fieldB9E;
+ } else {
+ scene->_fieldAF8 = scene->_actor8._position.x;
+ si = scene->_fieldAF8;
+ scene->_fieldB9E = scene->_actor9._position.y;
+ di = scene->_fieldB9E;
+ }
+
+ scene->_actor8._moveDiff.y = 9 - (scene->_field126E / 2);
+ Common::Point pt(si, 73 - (_field1E * 12));
+ NpcMover *mover = new NpcMover();
+ scene->_actor8.addMover(mover, &pt, NULL);
+
+ scene->_actor9._moveDiff.y = 9 - (scene->_field126E / 2);
+ Common::Point pt2(di, 73 - (_field1E * 12));
+ NpcMover *mover2 = new NpcMover();
+ scene->_actor9.addMover(mover2, &pt2, NULL);
+ scene->_field126E = (scene->_field126E / 2) + (scene->_field126E % 2);
+ setDelay(17 - scene->_field126E);
+ }
+ break;
+ case 1: {
+ R2_GLOBALS._sound2.play(339);
+ if (scene->_actor8._mover) {
+ si = scene->_fieldAF8;
+ di = scene->_fieldB9E;
+ } else {
+ si = scene->_actor8._position.x;
+ di = scene->_actor9._position.x;
+ }
+
+ scene->_actor7.sub1094ED();
+
+ scene->_actor8._moveDiff.y = 9 - (scene->_field126E / 2);
+ Common::Point pt(si, 73);
+ NpcMover *mover = new NpcMover();
+ scene->_actor8.addMover(mover, &pt, NULL);
+
+ scene->_actor9._moveDiff.y = 9 - (scene->_field126E / 2);
+ Common::Point pt2(di, 73);
+ NpcMover *mover2 = new NpcMover();
+ scene->_actor9.addMover(mover2, &pt2, NULL);
+
+ scene->_actor3.setFrame2(2);
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+bool Scene3500::Item4::startAction(CursorType action, Event &event) {
+ Scene3500 *scene = (Scene3500 *)R2_GLOBALS._sceneManager._scene;
+
+ if (scene->_field1286 == 0)
+ return true;
+
+ if (scene->_field1286 != 4)
+ return SceneHotspot::startAction(action, event);
+
+ R2_GLOBALS._sound2.play(14);
+ scene->sub107F71(_field34);
+
+ return true;
+}
+
+void Scene3500::Actor7::process(Event &event) {
+ Scene3500 *scene = (Scene3500 *)R2_GLOBALS._sceneManager._scene;
+
+ if (scene->_field1286 == 0)
+ return;
+
+ if ((event.eventType == EVENT_BUTTON_DOWN) && (R2_GLOBALS._events.getCursor() == CURSOR_USE) && (_bounds.contains(event.mousePos))) {
+ _fieldAE = 1 + event.mousePos.y - _position.y;
+ event.eventType = EVENT_NONE;
+ }
+
+ if ((event.eventType == EVENT_BUTTON_UP) && (_fieldAE != 0)) {
+ _fieldAE = 0;
+ event.handled = true;
+ if (scene->_action1._field24 == 0)
+ sub1094ED();
+ }
+
+ if (_fieldAE == 0)
+ return;
+
+ R2_GLOBALS._sound2.play(338);
+ event.handled = true;
+
+ int cx = event.mousePos.y - _fieldAE + 1;
+ if (_fieldA6 >= cx) {
+ if (_fieldA6 - _fieldAA <= cx)
+ sub109693(Common::Point(((_fieldA6 - cx) / 2) + _fieldA4 + ((_fieldA6 - cx) % 2), cx));
+ else
+ sub109693(Common::Point(_fieldA4 + _fieldA8, _fieldA6 - _fieldAA));
+ } else {
+ sub109693(Common::Point(_fieldA4, _fieldA6));
+ }
+}
+
+bool Scene3500::Actor7::startAction(CursorType action, Event &event) {
+ Scene3500 *scene = (Scene3500 *)R2_GLOBALS._sceneManager._scene;
+
+ if (scene->_field1286 == 0)
+ return true;
+
+ if (scene->_field1286 == 4)
+ return false;
+
+ return SceneActor::startAction(action, event);
+}
+
+void Scene3500::postInit(SceneObjectList *OwnerList) {
+ byte tmpPal[768];
+ Rect tmpRect;
+
+ loadScene(1050);
+ R2_GLOBALS._uiElements._active = false;
+ R2_GLOBALS._v5589E.set(0, 0, 320, 200);
+ R2_GLOBALS._sound1.play(305);
+ R2_GLOBALS._player._characterIndex = R2_QUINN;
+ R2_GLOBALS._player._characterScene[1] = 3500;
+ R2_GLOBALS._player._characterScene[2] = 3500;
+ R2_GLOBALS._player._characterScene[3] = 3500;
+ _field1284 = 0;
+ _field1282 = 0;
+ _field1278 = 0;
+ _field1272 = 1;
+ _field1270 = 4;
+ _field126E = 4;
+ _field127A = 860;
+ _field127C = 891;
+ _rotation = R2_GLOBALS._scenePalette.addRotation(240, 254, -1);
+ _rotation->setDelay(0);
+ _rotation->_idxChange = 1;
+
+ for (int i = 240; i <= 254; i++) {
+ int tmpIndex = _rotation->_currIndex - 240;
+
+ if (tmpIndex > 254)
+ tmpIndex--;
+
+ tmpPal[3 * i] = R2_GLOBALS._scenePalette._palette[3 * tmpIndex];
+ tmpPal[(3 * i) + 1] = R2_GLOBALS._scenePalette._palette[(3 * tmpIndex) + 1];
+ tmpPal[(3 * i) + 2] = R2_GLOBALS._scenePalette._palette[(3 * tmpIndex) + 2];
+ }
+
+ for (int i = 240; i <= 254; i++) {
+ R2_GLOBALS._scenePalette._palette[3 * i] = tmpPal[3 * i];
+ R2_GLOBALS._scenePalette._palette[(3 * i) + 1] = tmpPal[(3 * i) + 1];
+ R2_GLOBALS._scenePalette._palette[(3 * i) + 2] = tmpPal[(3 * i) + 2];
+ }
+
+ _actor7.sub109466(38, 165, 16, 32, _field1270);
+ _actor7.setDetails(3500, 6, 7, -1, 1, (SceneItem *)NULL);
+ R2_GLOBALS._sound1.play(276);
+
+ _item4._field34 = 88;
+ _item4.setDetails(88, 3500, 18, 10, -1);
+
+ _item5._field34 = 112;
+ _item5.setDetails(112, 3500, 9, 10, -1);
+
+ _item6._field34 = 104;
+ _item6.setDetails(104, 3500, 15, 10, -1);
+
+ _item7._field34 = 96;
+ _item7.setDetails(96, 3500, 12, 10, -1);
+
+ _actor8.postInit();
+ _actor8.setup(10501, 1, 1);
+ _actor8.setPosition(Common::Point(160, 73));
+ _actor8.fixPriority(1);
+
+ _actor9.postInit();
+ _actor9.setup(1050, 2, 1);
+ _actor9.setPosition(Common::Point(-160, 73));
+ _actor9.fixPriority(11);
+ _actor9.hide();
+
+ _item2.setDetails(27, 3500, 21, -1, -1);
+ _item3.setDetails(Rect(160, 89, 299, 182), 3500, 3, -1, -1, 1, NULL);
+ _item1.setDetails(Rect(0, 0, 320, 200), 3500, 0, -1, 2, 1, NULL);
+
+ _actor1.postInit();
+ _field1276 = 1;
+ _actor1.setup(1004, 1, _field1276);
+ _actor1.setPosition(Common::Point(230, 135));
+ _actor1.fixPriority(200);
+ _actor1._frameChange = 1;
+
+ _actor5.postInit();
+ _actor5.setup(1004, 3, 1);
+ _actor5.setPosition(Common::Point(117, 163));
+ _actor5.fixPriority(200);
+ _actor5.hide();
+
+ _actor4.postInit();
+ _actor4.setup(1004, 3, 2);
+ _actor4.setPosition(Common::Point(126, 163));
+ _actor4.fixPriority(200);
+
+ _actor6.postInit();
+ _actor6.setup(1004, 3, 3);
+ _actor6.setPosition(Common::Point(135, 163));
+ _actor6.fixPriority(200);
+ _actor6.hide();
+
+ _actor2.postInit();
+ _actor2.setup(1004, 4, _field126E + 1);
+ _actor2.setPosition(Common::Point(126, 137));
+ _actor2.fixPriority(200);
+
+ _actor3.postInit();
+ _actor3.setup(1004, 5, 2);
+ _actor3.setPosition(Common::Point(126, 108));
+ _actor3.fixPriority(200);
+
+ tmpRect.set(160, 89, 299, 182);
+ _unkObj1.sub9EDE8(tmpRect);
+ _unkObj1.sub51AE9(2);
+ _unkObj1.sub51AFD(Common::Point(_field127A, _field127C));
+
+ _action1._field24 = 0;
+ warning("gfx_set_pane_p()");
+ _unkObj1.sub51B02();
+ warning("gfx_set_pane_p()");
+ _field1286 = 1;
+
+ R2_GLOBALS._player.postInit();
+ R2_GLOBALS._player.hide();
+ R2_GLOBALS._player.enableControl(CURSOR_USE);
+ R2_GLOBALS._player._uiEnabled = false;
+ R2_GLOBALS._player._canWalk = false;
+}
+
+void Scene3500::remove() {
+ _rotation->remove();
+ R2_GLOBALS._sound2.fadeOut2(NULL);
+ SceneExt::remove();
+}
+
+void Scene3500::signal() {
+ R2_GLOBALS._player.enableControl(CURSOR_USE);
+ R2_GLOBALS._player._canWalk = false;
+ _field1286 = 1;
+}
+
+void Scene3500::process(Event &event) {
+ if (_field1286 == 0)
+ return;
+
+ if (event.eventType == EVENT_KEYPRESS) {
+ switch (event.kbd.keycode) {
+ case Common::KEYCODE_1:
+ warning("FIXME: keycode = 0x4700");
+ R2_GLOBALS._sound2.play(338);
+ sub107F71(16);
+ event.handled = true;
+ break;
+ case Common::KEYCODE_2:
+ warning("FIXME: keycode = 0x4800");
+ R2_GLOBALS._sound2.play(14, NULL, 63);
+ sub107F71(88);
+ event.handled = true;
+ break;
+ case Common::KEYCODE_3:
+ warning("FIXME: keycode = 0x4900");
+ if (_field1270 < 16)
+ R2_GLOBALS._sound2.play(338);
+ sub107F71(1);
+ event.handled = true;
+ break;
+ case Common::KEYCODE_4:
+ warning("FIXME: keycode = 0x4B00");
+ R2_GLOBALS._sound2.play(14, NULL, 63);
+ sub107F71(112);
+ event.handled = true;
+ break;
+ case Common::KEYCODE_5:
+ warning("FIXME: keycode = 0x4D00");
+ R2_GLOBALS._sound2.play(14, NULL, 63);
+ sub107F71(96);
+ event.handled = true;
+ break;
+ case Common::KEYCODE_6:
+ warning("FIXME: keycode = 0x4F00");
+ R2_GLOBALS._sound2.play(338);
+ sub107F71(0);
+ event.handled = true;
+ break;
+ case Common::KEYCODE_7:
+ warning("FIXME: keycode = 0x5000");
+ R2_GLOBALS._sound2.play(14, NULL, 63);
+ sub107F71(104);
+ event.handled = true;
+ break;
+ case Common::KEYCODE_8:
+ warning("FIXME: keycode = 0x5100");
+ if (_field1270 != 0)
+ R2_GLOBALS._sound2.play(338);
+ sub107F71(-1);
+ event.handled = true;
+ break;
+ case Common::KEYCODE_9:
+ warning("FIXME: keycode = 0x5200");
+ R2_GLOBALS._sound2.play(338);
+ sub107F71(8);
+ event.handled = true;
+ break;
+ case Common::KEYCODE_0:
+ warning("FIXME: keycode = 0x5300");
+ R2_GLOBALS._sound2.play(338);
+ sub107F71(4);
+ event.handled = true;
+ break;
+ default:
+ break;
+ }
+ }
+
+ if (!event.handled)
+ _actor7.process(event);
+
+ if (!event.handled)
+ _item4.process(event);
+
+ if (!event.handled)
+ _item5.process(event);
+
+ if (!event.handled)
+ _item6.process(event);
+
+ if (!event.handled)
+ _item7.process(event);
+
+ Scene::process(event);
+}
+
+void Scene3500::dispatch() {
+ Rect tmpRect;
+ Scene::dispatch();
+ if (((_actor1._frame % 2) == 0) && (_action1._field24 == 0)) {
+ _actor1.setFrame(_actor1.changeFrame());
+ _field1276 = _actor1._frame;
+ }
+ int oldField1278;
+ if ((_field1278 != 0) && (_action1._field24 == 0)) {
+ oldField1278 = _field1278;
+ _field1278 = 0;
+ sub107F71(oldField1278);
+ }
+
+ if (!_rotation)
+ return;
+
+ int var_field127A = 0;
+ int di = 0;
+ int var_4 = 0;
+ int var_6 = 0;
+ int var_8 = 0;
+ int var_a = 0;
+ int dx = 0;
+ int tmpVar = 0;
+
+ if ((_field126E == 0) && (_field1282 == 0)) {
+ if (_field1284 == 2)
+ R2_GLOBALS._sceneManager.changeScene(1000);
+ } else {
+ _field1282 = 0;
+ tmpRect.set(160, 89, 299, 182);
+
+ var_field127A = _field127A;
+ di = _field127C;
+ var_4 = _unkObj1.sub1097C9(70) - 70;
+ var_6 = _unkObj1.sub1097EF(_field127C + 46) - 46;
+ var_8 = abs(var_4 - var_field127A);
+ var_a = abs(var_6 - di);
+ dx = 0;
+
+ switch (_field1276) {
+ case 0:
+ tmpVar = _unkObj1.sub109C09(Common::Point(var_field127A + 70, 46));
+ if ( ((tmpVar == 2) || (tmpVar == 3) || (tmpVar == 6) || (tmpVar == 1))
+ || (((tmpVar == 25) || (tmpVar == 26) || (tmpVar == 5) || (tmpVar == 14) || (tmpVar == 15)) && (var_8 > 3)) ) {
+ R2_GLOBALS._sound2.play(339);
+ _rotation->_idxChange = 0;
+ _field1270 = 0;
+ _field126E = 0;
+ _field1272 = 0;
+ if (_action1._field24 == 0)
+ _actor8.hide();
+ } else {
+ var_6 = _unkObj1.sub1097EF(di + 46) - 46;
+ di = _field127C - _field126E;
+ dx = _unkObj1.sub109C09(Common::Point(var_field127A + 70, di + 46));
+ if (((tmpVar == 23) || (tmpVar == 24) || (tmpVar == 4)) && (tmpVar != dx)) {
+ di = var_6;
+ R2_GLOBALS._sound2.play(339);
+ _rotation->_idxChange = 0;
+ _field1270 = 0;
+ _field126E = 0;
+ _field1272 = 0;
+ if (_action1._field24 == 0)
+ _actor8.hide();
+ } else if ((tmpVar == 11) && (tmpVar != dx)) {
+ di = var_6 + 3;
+ R2_GLOBALS._sound2.play(339);
+ _rotation->_idxChange = 0;
+ _field1270 = 0;
+ _field126E = 0;
+ _field1272 = 0;
+ if (_action1._field24 == 0)
+ _actor8.hide();
+ } else {
+ var_6 = _unkObj1.sub1097EF(di + 46) - 46;
+ var_a = abs(var_6 - di);
+ tmpVar = _unkObj1.sub109C09(Common::Point(var_field127A + 70, di + 46));
+
+ if ( (((tmpVar == 23) || (tmpVar == 24) || (tmpVar == 4)) && (di <= var_6) && (_field127C>= var_6))
+ || (((tmpVar == 25) || (tmpVar == 26) || (tmpVar == 5) || (tmpVar == 14) || (tmpVar == 15)) && (_field126E >= var_a) && (_field126E > 3) && (_action1._field24 != 0)) ) {
+ di = var_6;
+ if ((tmpVar != 25) && (tmpVar != 26) && (tmpVar != 5) && (tmpVar != 14) && (tmpVar == 15))
+ R2_GLOBALS._sound2.play(339);
+ _rotation->_idxChange = 0;
+ _field1270 = 0;
+ _field126E = 0;
+ _field1272 = 0;
+ if (_action1._field24 == 0)
+ _actor8.hide();
+ } else if ((tmpVar == 11) && (var_6 + 3 >= di) && (_field127C >= var_6 + 3)) {
+ R2_GLOBALS._sound2.play(339);
+ _rotation->_idxChange = 0;
+ _field1270 = 0;
+ _field126E = 0;
+ _field1272 = 0;
+ if (_action1._field24 == 0)
+ _actor8.hide();
+ } else if (((tmpVar == 25) || (tmpVar == 26) || (tmpVar == 5) || (tmpVar == 14) || (tmpVar == 15)) && (var_8 != 0) && (var_8 <= 3)) {
+ var_field127A = var_4;
+ R2_GLOBALS._sound2.play(339);
+ } else {
+ // Nothing
+ }
+ }
+ }
+ break;
+ case 2:
+ tmpVar = _unkObj1.sub109C09(Common::Point(var_field127A + 70, di + 46));
+ if ( ((tmpVar == 12) || (tmpVar == 13) || (tmpVar == 11) || (tmpVar == 16) || (tmpVar == 31))
+ || (((tmpVar == 25) || (tmpVar == 23) || (tmpVar == 14) || (tmpVar == 5) || (tmpVar == 4)) && (var_a > 3)) ) {
+ R2_GLOBALS._sound2.play(339);
+ _rotation->_idxChange = 0;
+ _field1270 = 0;
+ _field126E = 0;
+ _field1272 = 0;
+ if (_action1._field24 == 0)
+ _actor8.hide();
+ } else {
+ var_4 = _unkObj1.sub1097C9(var_field127A + 70) - 70;
+ var_field127A = _field127A + _field126E;
+ dx = _unkObj1.sub109C09(Common::Point(var_field127A + 70, di + 46));
+ if (((tmpVar == 26) || (tmpVar == 24) || (tmpVar == 15)) && (tmpVar != dx)) {
+ var_field127A = var_4;
+ R2_GLOBALS._sound2.play(339);
+ _rotation->_idxChange = 0;
+ _field1270 = 0;
+ _field126E = 0;
+ _field1272 = 0;
+ if (_action1._field24 == 0)
+ _actor8.hide();
+ } else if ((tmpVar == 6) && (tmpVar != dx)) {
+ var_field127A = var_4 - 5;
+ R2_GLOBALS._sound2.play(339);
+ _rotation->_idxChange = 0;
+ _field1270 = 0;
+ _field126E = 0;
+ _field1272 = 0;
+ if (_action1._field24 == 0)
+ _actor8.hide();
+ } else {
+ var_4 = _unkObj1.sub1097C9(var_field127A + 70) - 70;
+ var_8 = abs(var_field127A - var_4);
+ tmpVar = _unkObj1.sub109C09(Common::Point(var_field127A + 70, tmpVar + 46));
+ if ( (((tmpVar == 26) || (tmpVar == 24) || (tmpVar == 15)) && (var_field127A >= var_4) && (_field127A <= var_4))
+ || (((tmpVar == 25) || (tmpVar == 23) || (tmpVar == 14) || (tmpVar == 5) || (tmpVar == 4)) && (_field126E >= var_8) && (_field126E <= 3) && (_action1._field24 != 0)) ) {
+ var_field127A = var_4;
+ if ((tmpVar == 25) || (tmpVar == 23) || (tmpVar == 14) || (tmpVar == 5) || (tmpVar == 4))
+ R2_GLOBALS._sound2.play(339);
+ _rotation->_idxChange = 0;
+ _field1270 = 0;
+ _field126E = 0;
+ _field1272 = 0;
+ if (_action1._field24 == 0)
+ _actor8.hide();
+ } else if ((tmpVar == 6) && (var_4 - 5 <= var_field127A) && (_field127A <= var_4 - 5)) {
+ var_field127A = var_4 - 5;
+ R2_GLOBALS._sound2.play(339);
+ _rotation->_idxChange = 0;
+ _field1270 = 0;
+ _field126E = 0;
+ _field1272 = 0;
+ if (_action1._field24 == 0)
+ _actor8.hide();
+ } else if (((tmpVar == 25) || (tmpVar == 23) || (tmpVar == 14) || (tmpVar == 5) || (tmpVar == 4)) && (var_a != 0) && (var_a <= 3)) {
+ di = var_6;
+ R2_GLOBALS._sound2.play(339);
+ } else {
+ // Nothing
+ }
+ }
+ }
+ break;
+ case 4:
+ tmpVar = _unkObj1.sub109C09(Common::Point(var_field127A + 70, di + 46));
+ if ( ((tmpVar == 2) || (tmpVar == 3) || (tmpVar == 6) || (tmpVar == 1))
+ || (((tmpVar == 23) || (tmpVar == 24) || (tmpVar == 4) || (tmpVar == 14) || (tmpVar == 15)) && (var_8 > 3)) ) {
+ R2_GLOBALS._sound2.play(339);
+ _rotation->_idxChange = 0;
+ _field1270 = 0;
+ _field126E = 0;
+ _field1272 = 0;
+ if (_action1._field24 == 0)
+ _actor8.hide();
+ } else {
+ var_6 = _unkObj1.sub1097EF(di + 46) - 46;
+ di = _field127C + _field126E;
+ dx = _unkObj1.sub109C09(Common::Point(var_field127A + 70, di + 46));
+ if (((tmpVar == 25) || (tmpVar == 26) || (tmpVar == 5)) && (tmpVar == dx)) {
+ R2_GLOBALS._sound2.play(339);
+ _rotation->_idxChange = 0;
+ _field1270 = 0;
+ _field126E = 0;
+ _field1272 = 0;
+ if (_action1._field24 == 0)
+ _actor8.hide();
+ } else if ((tmpVar == 16) && (tmpVar == dx)) {
+ di = var_6 - 3;
+ R2_GLOBALS._sound2.play(339);
+ _rotation->_idxChange = 0;
+ _field1270 = 0;
+ _field126E = 0;
+ _field1272 = 0;
+ if (_action1._field24 == 0)
+ _actor8.hide();
+ } else if ((tmpVar == 31) && (tmpVar == dx)) {
+ di = var_6 + 4;
+ R2_GLOBALS._sound2.play(339);
+ _rotation->_idxChange = 0;
+ _field1270 = 0;
+ _field126E = 0;
+ _field1272 = 0;
+ if (_action1._field24 == 0)
+ _actor8.hide();
+ } else {
+ var_6 = _unkObj1.sub1097EF(di + 46) - 46;
+ var_a = abs(di - var_6);
+ tmpVar = _unkObj1.sub109C09(Common::Point(var_field127A + 70, di + 46));
+ if ( (((tmpVar == 25) || (tmpVar == 26) || (tmpVar == 5)) && (di >= var_6) && (_field127C <= var_6))
+ || (((tmpVar == 23) || (tmpVar == 24) || (tmpVar == 4) || (tmpVar == 14) || (tmpVar == 15)) && (_field126E >= var_a) && (_field126E <= 3) && (_action1._field24 != 0)) ){
+ if ((tmpVar != 23) && (tmpVar != 24) && (tmpVar != 4) && (tmpVar != 14) && (tmpVar != 15))
+ R2_GLOBALS._sound2.play(339);
+ _rotation->_idxChange = 0;
+ _field1270 = 0;
+ _field126E = 0;
+ _field1272 = 0;
+ if (_action1._field24 == 0)
+ _actor8.hide();
+ } else if ((tmpVar == 16) && (var_6 - 3 <= di) && (_field127C <= var_6 - 3)) {
+ di = var_6 - 3;
+ R2_GLOBALS._sound2.play(339);
+ _rotation->_idxChange = 0;
+ _field1270 = 0;
+ _field126E = 0;
+ _field1272 = 0;
+ if (_action1._field24 == 0)
+ _actor8.hide();
+ } else if ((tmpVar == 31) && (var_6 + 4 <= di) && (_field127C <= var_6 + 4)) {
+ di = var_6 + 4;
+ _rotation->_idxChange = 0;
+ _field1270 = 0;
+ _field126E = 0;
+ _field1272 = 0;
+ if (_action1._field24 == 0)
+ _actor8.hide();
+ if ((var_field127A == 660) && (_field126E + 306 <= di) && (di <= 307))
+ ++_field1284;
+ else
+ R2_GLOBALS._sound2.play(339);
+ } else if (((tmpVar == 23) || (tmpVar == 24) || (tmpVar == 4) || (tmpVar == 14) || (tmpVar == 15)) && (var_8 != 0) && (var_8 <= 3)) {
+ var_field127A = var_4;
+ R2_GLOBALS._sound2.play(339);
+ } else {
+ // Nothing
+ }
+ }
+ }
+ break;
+ case 6:
+ tmpVar = _unkObj1.sub109C09(Common::Point(var_field127A + 70, di + 46));
+ if ( ((tmpVar == 12) || (tmpVar == 13) || (tmpVar == 11) || (tmpVar == 16) || (tmpVar == 31))
+ || (((tmpVar == 26) || (tmpVar == 24) || (tmpVar == 15) || (tmpVar == 5) || (tmpVar == 4)) && (var_a > 3)) ) {
+ R2_GLOBALS._sound2.play(339);
+ _rotation->_idxChange = 0;
+ _field1270 = 0;
+ _field126E = 0;
+ _field1272 = 0;
+ if (_action1._field24 == 0)
+ _actor8.hide();
+ } else {
+ var_4 = _unkObj1.sub1097C9(var_field127A + 70) - 70;
+ var_field127A = _field127A - _field126E;
+ dx = _unkObj1.sub109C09(Common::Point(var_field127A + 70, di + 46));
+ if (((tmpVar == 25) || (tmpVar == 23) || (tmpVar == 14)) && (tmpVar != dx)) {
+ var_field127A = var_4;
+ R2_GLOBALS._sound2.play(339);
+ _rotation->_idxChange = 0;
+ _field1270 = 0;
+ _field126E = 0;
+ _field1272 = 0;
+ if (_action1._field24 == 0)
+ _actor8.hide();
+ } else if ((tmpVar == 1) && (tmpVar != dx)) {
+ var_field127A = var_4 + 5;
+ R2_GLOBALS._sound2.play(339);
+ _rotation->_idxChange = 0;
+ _field1270 = 0;
+ _field126E = 0;
+ _field1272 = 0;
+ if (_action1._field24 == 0)
+ _actor8.hide();
+ } else {
+ var_4 = _unkObj1.sub1097C9(var_field127A + 70) - 70;
+ var_8 = abs(var_4 - var_field127A);
+ tmpVar = _unkObj1.sub109C09(Common::Point(var_field127A + 70, di + 46));
+ if ( (((tmpVar == 25) || (tmpVar == 23) || (tmpVar == 14)) && (var_field127A <= var_4) && (_field127A >= var_4))
+ || (((tmpVar == 26) || (tmpVar == 24) || (tmpVar == 15) || (tmpVar == 5) || (tmpVar == 4)) && (_field126E >= var_8) && (_field126E <= 3) && (_action1._field24 != 0)) ) {
+ var_field127A = var_4;
+ if ((tmpVar == 26) || (tmpVar == 24) || (tmpVar == 15) || (tmpVar == 5) || (tmpVar == 4))
+ R2_GLOBALS._sound2.play(339);
+ _rotation->_idxChange = 0;
+ _field1270 = 0;
+ _field126E = 0;
+ _field1272 = 0;
+ if (_action1._field24 == 0)
+ _actor8.hide();
+ } else if ((tmpVar == 1) && (var_field127A >= var_4 + 5) && (_field127A >= var_4 + 5)) {
+ var_field127A = var_4 + 5;
+ R2_GLOBALS._sound2.play(339);
+ _rotation->_idxChange = 0;
+ _field1270 = 0;
+ _field126E = 0;
+ _field1272 = 0;
+ if (_action1._field24 == 0)
+ _actor8.hide();
+ } else if (((tmpVar == 26) || (tmpVar == 24) || (tmpVar == 15) || (tmpVar == 5) || (tmpVar == 4)) && (var_a != 0) && (var_a <= 3)) {
+ di = var_6;
+ R2_GLOBALS._sound2.play(339);
+ } else {
+ // Nothing
+ }
+ }
+ }
+ break;
+ default:
+ break;
+ }
+
+ if (_field1284 < 2) {
+ _field127A = var_field127A;
+ _field127C = di;
+ if (_unkObj1.sub109C5E(_field127A, _field127C) != 0) {
+ _field1272 = 0;
+ _field126E = 0;
+ _field1270 = 0;
+ _rotation->setDelay(0);
+ _rotation->_idxChange = 0;
+ }
+ warning("gfx_set_pane_p");
+ _unkObj1.sub51B02();
+ if (_field1284 != 0)
+ ++_field1284;
+ }
+ }
+
+ if (_field1272 == 0) {
+ if (_field126E != _field1270) {
+ if (_field126E >= _field1270) {
+ if (_field126E == 1) {
+ if (_action1._field24 != 0) {
+ if ( ((_field1276 == 1) && (var_8 == 0) && (var_a != 0) && (var_a <= 3) && ((tmpVar == 25) || (tmpVar == 26) || (tmpVar == 5) || (tmpVar == 14) || (tmpVar == 15)))
+ || ((_field1276 == 3) && (var_a == 0) && (var_8 != 0) && (var_8 <= 3) && ((tmpVar == 25) || (tmpVar == 23) || (tmpVar == 14) || (tmpVar == 5) || (tmpVar == 4)))
+ || ((_field1276 == 5) && (var_8 == 0) && (var_a != 0) && (var_a <= 3) && ((tmpVar == 23) || (tmpVar == 24) || (tmpVar == 4) || (tmpVar == 14) || (tmpVar == 15)))
+ || ((_field1276 == 7) && (var_a == 0) && (var_8 != 0) && (var_8 <= 3) && ((tmpVar == 26) || (tmpVar == 24) || (tmpVar == 15) || (tmpVar == 5) || (tmpVar == 4))) ){
+ _field126E = 1;
+ } else
+ _field126E--;
+ } else
+ _field126E--;
+ } else
+ _field126E--;
+ } else
+ ++_field126E;
+ _field1272 = 1;
+ }
+ _actor2.setFrame2(_field126E);
+ }
+
+ if (_field1272 == 1) {
+ if (_field126E == 0)
+ _rotation->_idxChange = 0;
+ else if (_field126E > 8)
+ _rotation->_idxChange = 2;
+ else
+ _rotation->_idxChange = 1;
+ }
+
+ if (_field1272 != 0)
+ _field1272--;
+
+ if (_field126E != 0) {
+ R2_GLOBALS._player._uiEnabled = false;
+ if (_field126E != _field1270)
+ _aSound1.play(276);
+ } else {
+ R2_GLOBALS._player._uiEnabled = true;
+ _aSound1.fadeOut2(NULL);
+ }
+
+ if (_rotation->_currIndex != _field1274)
+ _field1274 = _rotation->_currIndex;
+}
+
+/*--------------------------------------------------------------------------
+ * Scene 3600 -
+ *
+ *--------------------------------------------------------------------------*/
+Scene3600::Scene3600() {
+ _field2548 = 0;
+ _field254A = 0;
+ _field254C = 0;
+ _field254E = 0;
+ _field2550 = false;
+}
+void Scene3600::synchronize(Serializer &s) {
+ SceneExt::synchronize(s);
+
+ s.syncAsSint16LE(_field2548);
+ s.syncAsSint16LE(_field254A);
+ s.syncAsSint16LE(_field254C);
+ s.syncAsSint16LE(_field254E);
+ s.syncAsSint16LE(_field2550);
+}
+
+Scene3600::Action3600::Action3600() {
+ _field1E = 0;
+ _field20 = 0;
+}
+
+void Scene3600::Action3600::synchronize(Serializer &s) {
+ Action::synchronize(s);
+
+ s.syncAsSint16LE(_field1E);
+ s.syncAsSint16LE(_field20);
+}
+
+void Scene3600::Action3600::signal() {
+ Scene3600 *scene = (Scene3600 *)R2_GLOBALS._sceneManager._scene;
+
+ switch (_actionIndex) {
+ case 0:
+ ++_actionIndex;
+ setDelay(60);
+ break;
+ case 1:
+ if (_field1E == 0) {
+ _field1E = 1;
+ scene->_actor2.setAction(NULL);
+ R2_GLOBALS._sound2.play(330, NULL, 0);
+ R2_GLOBALS._sound2.fade(127, 5, 10, false, NULL);
+ }
+ setDelay(1);
+ warning("TODO: Palette fader using parameter 2 = 256");
+ R2_GLOBALS._scenePalette.fade((const byte *)&scene->_palette1._palette, true, _field20);
+ if (_field20 > 0)
+ _field20 -= 2;
+ break;
+ case 2:
+ R2_GLOBALS._sound2.stop();
+ ++_actionIndex;
+ setDelay(3);
+ break;
+ case 3:
+ R2_GLOBALS._sound2.play(330, this, 0);
+ R2_GLOBALS._sound2.fade(127, 5, 10, false, NULL);
+ _actionIndex = 1;
+ break;
+ default:
+ break;
+ }
+}
+
+void Scene3600::Action2::signal() {
+ Scene3600 *scene = (Scene3600 *)R2_GLOBALS._sceneManager._scene;
+
+ switch (_actionIndex) {
+ case 3621:
+ R2_GLOBALS._events.proc1();
+ R2_GLOBALS._player.enableControl();
+ _actionIndex = 3619;
+ scene->_actor13._state = 0;
+ // No break on purpose
+ case 3619: {
+ ++_actionIndex;
+ scene->_actor13.setup(3127, 2, 1);
+ scene->_actor13.animate(ANIM_MODE_1, NULL);
+ NpcMover *mover = new NpcMover();
+ scene->_actor13.addMover(mover, &scene->_actor13._field8A, scene);
+ }
+ break;
+ default:
+ _actionIndex = 3619;
+ setDelay(360);
+ break;
+ }
+}
+
+bool Scene3600::Item5::startAction(CursorType action, Event &event) {
+ Scene3600 *scene = (Scene3600 *)R2_GLOBALS._sceneManager._scene;
+
+ if ((action != CURSOR_USE) || (scene->_action1._field1E == 0))
+ return SceneItem::startAction(action, event);
+
+ R2_GLOBALS._walkRegions.disableRegion(2);
+ R2_GLOBALS._walkRegions.disableRegion(7);
+
+ R2_GLOBALS._player.disableControl();
+ scene->_sceneMode = 3624;
+ scene->_actor10.setStrip2(-1);
+ scene->_actor11.setStrip2(-1);
+ scene->_actor12.setStrip2(-1);
+ scene->_actor4.setStrip2(-1);
+
+ if (R2_GLOBALS._player._characterIndex == 2)
+ R2_GLOBALS._player.setAction(&scene->_sequenceManager3, scene, 3611, &R2_GLOBALS._player, NULL);
+ else if (R2_GLOBALS._player._characterIndex == 3)
+ R2_GLOBALS._player.setAction(&scene->_sequenceManager4, scene, 3612, &R2_GLOBALS._player, NULL);
+ else
+ R2_GLOBALS._player.setAction(&scene->_sequenceManager2, scene, 3610, &R2_GLOBALS._player, NULL);
+
+ return true;
+}
+
+bool Scene3600::Actor13::startAction(CursorType action, Event &event) {
+ Scene3600 *scene = (Scene3600 *)R2_GLOBALS._sceneManager._scene;
+
+ switch(action) {
+ case CURSOR_TALK:
+ if (!_action)
+ return SceneActor::startAction(action, event);
+
+ scene->_protectorSpeaker._displayMode = 1;
+ if (!R2_GLOBALS._player._mover)
+ R2_GLOBALS._player.addMover(NULL);
+ if (!scene->_actor10._mover)
+ scene->_actor10.addMover(NULL);
+ if (!scene->_actor11._mover)
+ scene->_actor11.addMover(NULL);
+ if (!scene->_actor12._mover)
+ scene->_actor12.addMover(NULL);
+ if (!scene->_actor4._mover)
+ scene->_actor4.addMover(NULL);
+
+ setup(3127, 2, 1);
+ scene->_sceneMode = 3327;
+ scene->_stripManager.start(3327, scene);
+
+ return true;
+ case R2_SONIC_STUNNER:
+ // No break on purpose
+ case R2_PHOTON_STUNNER:
+ if (action == R2_SONIC_STUNNER)
+ R2_GLOBALS._sound3.play(43);
+ else
+ R2_GLOBALS._sound3.play(99);
+ if (_state != 0) {
+ _state = 1;
+ setup(3128, 1, 1);
+ addMover(NULL);
+ }
+ scene->_action2.setActionIndex(3621);
+
+ if (!_action)
+ setAction(&scene->_action2, scene, NULL);
+
+ animate(ANIM_MODE_5, &scene->_action2);
+ R2_GLOBALS._player.disableControl();
+ return true;
+ break;
+ default:
+ return SceneActor::startAction(action, event);
+ break;
+ }
+}
+
+void Scene3600::postInit(SceneObjectList *OwnerList) {
+ if (R2_GLOBALS._sceneManager._previousScene == 3600) {
+ R2_GLOBALS._scrollFollower = &R2_GLOBALS._player;
+ R2_GLOBALS._v558B6.set(60, 0, 260, 200);
+ } else {
+ R2_GLOBALS._scrollFollower = &_actor2;
+ g_globals->gfxManager()._bounds.moveTo(Common::Point(160, 0));
+ R2_GLOBALS._v558B6.set(25, 0, 260, 200);
+ }
+
+ loadScene(3600);
+ SceneExt::postInit();
+ _field254C = 0;
+
+ _stripManager.setColors(60, 255);
+ _stripManager.setFontNumber(3);
+ _stripManager.addSpeaker(&_quinnSpeaker);
+ _stripManager.addSpeaker(&_seekerSpeaker);
+ _stripManager.addSpeaker(&_mirandaSpeaker);
+ _stripManager.addSpeaker(&_tealSpeaker);
+ _stripManager.addSpeaker(&_protectorSpeaker);
+
+ setZoomPercents(142, 80, 167, 105);
+ R2_GLOBALS._player._characterScene[1] = 3600;
+ R2_GLOBALS._player._characterScene[2] = 3600;
+ R2_GLOBALS._player._characterScene[3] = 3600;
+
+ _item2.setDetails(33, 3600, 6, -1, -1);
+ _item3.setDetails(Rect(3, 3, 22, 45), 3600, 9, -1, -1, 1, NULL);
+ _item4.setDetails(Rect(449, 3, 475, 45), 3600, 9, -1, -1, 1, NULL);
+
+ _actor10.postInit();
+ _actor10._moveDiff = Common::Point(3, 2);
+ _actor10.changeZoom(-1);
+ _actor10._effect = 1;
+
+ if (R2_GLOBALS._player._characterIndex != 1)
+ _actor10.setDetails(9001, 0, -1, -1, 1, (SceneItem *) NULL);
+
+ _actor11.postInit();
+ _actor11._numFrames = 7;
+ _actor11._moveDiff = Common::Point(5, 3);
+ _actor11.changeZoom(-1);
+ _actor11._effect = 1;
+
+ if (R2_GLOBALS._player._characterIndex != 2)
+ _actor11.setDetails(9002, 1, -1, -1, 1, (SceneItem *) NULL);
+
+ _actor12.postInit();
+ _actor12._moveDiff = Common::Point(3, 2);
+ _actor12.changeZoom(-1);
+ _actor12._effect = 1;
+
+ if (R2_GLOBALS._player._characterIndex != 3)
+ _actor12.setDetails(9003, 1, -1, -1, 1, (SceneItem *) NULL);
+
+ R2_GLOBALS._player.postInit();
+ R2_GLOBALS._player.changeZoom(-1);
+ R2_GLOBALS._player.animate(ANIM_MODE_1, NULL);
+ R2_GLOBALS._player.disableControl();
+
+ _actor4.postInit();
+ _actor4._numFrames = 7;
+ _actor4._moveDiff = Common::Point(5, 3);
+ _actor4.changeZoom(-1);
+ _actor4._effect = 1;
+ _actor4.setDetails(3600, 27, -1, -1, 1, (SceneItem *) NULL);
+
+ _actor5.postInit();
+ _actor5._numFrames = 7;
+ _actor5._moveDiff = Common::Point(3, 2);
+ _actor5.changeZoom(-1);
+ _actor5._effect = 1;
+ _actor5.setDetails(3600, 12, -1, -1, 1, (SceneItem *) NULL);
+
+ _palette1.loadPalette(0);
+ _palette1.loadPalette(3601);
+
+ if (R2_GLOBALS._sceneManager._previousScene == 3600) {
+ _item5._sceneRegionId = 200;
+ _item5.setDetails(3600, 30, -1, -1, 5, &_actor4);
+ _field254A = 1;
+ _field2548 = 1;
+
+ R2_GLOBALS._walkRegions.enableRegion(2);
+ R2_GLOBALS._walkRegions.enableRegion(7);
+ R2_GLOBALS._walkRegions.enableRegion(14);
+ R2_GLOBALS._walkRegions.enableRegion(15);
+ R2_GLOBALS._walkRegions.enableRegion(16);
+
+ _actor10.setup(10, 5, 11);
+ _actor10.animate(ANIM_MODE_1, NULL);
+
+ _actor11.setup(20, 5, 11);
+ _actor11.animate(ANIM_MODE_1, NULL);
+
+ _actor12.setup(30, 5, 11);
+ _actor12.animate(ANIM_MODE_1, NULL);
+
+ if (R2_GLOBALS._player._characterIndex == 2) {
+ _actor10.setPosition(Common::Point(76, 148));
+ _actor11.setPosition(Common::Point(134, 148));
+ _actor12.setPosition(Common::Point(100, 148));
+ R2_GLOBALS._player._moveDiff = Common::Point(5, 3);
+ R2_GLOBALS._player.setup(20, _actor11._strip, 1);
+ R2_GLOBALS._player.setPosition(_actor11._position);
+ _actor11.hide();
+ } else if (R2_GLOBALS._player._characterIndex == 3) {
+ _actor10.setPosition(Common::Point(110, 148));
+ _actor11.setPosition(Common::Point(76, 148));
+ _actor12.setPosition(Common::Point(134, 148));
+ R2_GLOBALS._player._moveDiff = Common::Point(3, 2);
+ R2_GLOBALS._player.setup(30, _actor12._strip, 1);
+ R2_GLOBALS._player.setPosition(_actor12._position);
+ _actor12.hide();
+ } else {
+ _actor10.setPosition(Common::Point(134, 148));
+ _actor11.setPosition(Common::Point(76, 148));
+ _actor12.setPosition(Common::Point(110, 148));
+ R2_GLOBALS._player._moveDiff = Common::Point(3, 2);
+ R2_GLOBALS._player.setup(10, _actor10._strip, 1);
+ R2_GLOBALS._player.setPosition(_actor10._position);
+ _actor10.hide();
+ }
+ _actor4.setPosition(Common::Point(47, 149));
+ _actor4.setup(40, 1, 11);
+ _actor4.animate(ANIM_MODE_1, NULL);
+
+ _actor5.setPosition(Common::Point(367, 148));
+ _actor5.setup(3601, 7, 5);
+
+ if (!R2_GLOBALS.getFlag(71)) {
+ _actor13.postInit();
+ _actor13._state = 0;
+ _actor13._field8A = Common::Point(226, 152);
+ _actor13._moveDiff = Common::Point(3, 2);
+ _actor13.setPosition(Common::Point(284, 152));
+ _actor13.setup(3127, 2, 1);
+ _actor13.changeZoom(-1);
+ _actor13.setDetails(3600, 15, -1, 17, 1, (SceneItem *) NULL);
+ }
+
+ R2_GLOBALS._sound2.play(330);
+ _actor3.postInit();
+ _actor3.setPosition(Common::Point(84, 156));
+ _actor3.fixPriority(158);
+ _actor3.setup(3601, 5, 1);
+ _actor3.animate(ANIM_MODE_2, NULL);
+
+ _action1._field1E = 1;
+ _action1._field20 = 0;
+ _action1.setActionIndex(1);
+
+ _actor3.setAction(&_action1);
+ _sceneMode = 3623;
+
+ g_globals->_events.setCursor(CURSOR_ARROW);
+ R2_GLOBALS._player.enableControl(CURSOR_ARROW);
+ } else {
+ _field254A = 0;
+ _field2548 = 0;
+
+ R2_GLOBALS._walkRegions.enableRegion(17);
+ R2_GLOBALS._walkRegions.enableRegion(18);
+
+ _actor10.setPosition(Common::Point(393, 148));
+ _actor11.setPosition(Common::Point(364, 153));
+ _actor12.setPosition(Common::Point(413, 164));
+
+ R2_GLOBALS._player.hide();
+
+ _actor4.setPosition(Common::Point(373, 164));
+
+ _actor5.setup(3403, 8, 11);
+ _actor5.setPosition(Common::Point(403, 155));
+
+ _actor12.setup(3403, 7, 1);
+
+ _actor13.setPosition(Common::Point(405, 155));
+
+ _actor2.postInit();
+ _actor2.setup(3600, 2, 1);
+ _actor2.setPosition(Common::Point(403, 161));
+ _actor2.fixPriority(149);
+ _actor2.changeZoom(-1);
+
+ _action1._field1E = 0;
+ _action1._field20 = 90;
+
+ _sceneMode = 3600;
+ setAction(&_sequenceManager1, this, 3600, &_actor11, &_actor10, &_actor12, &_actor4, &_actor5, &_actor2, NULL);
+ _field254E = 0;
+ }
+ _field254E = 0;
+ _field2550 = R2_GLOBALS.getFlag(71);
+
+ R2_GLOBALS._sound1.play(326);
+ _item1.setDetails(Rect(0, 0, 480, 200), 3600, 0, -1, -1, 1, NULL);
+}
+
+void Scene3600::remove() {
+ _actor3.animate(ANIM_MODE_NONE, NULL);
+ _actor3.setAction(NULL);
+ R2_GLOBALS._sound2.fadeOut2(NULL);
+ R2_GLOBALS._sound1.fadeOut2(NULL);
+ R2_GLOBALS._scrollFollower = &R2_GLOBALS._player;
+ SceneExt::remove();
+}
+
+void Scene3600::signal() {
+ switch (_sceneMode) {
+ case 3320:
+ warning("STUB: sub_1D227()");
+ R2_GLOBALS._walkRegions.enableRegion(14);
+ R2_GLOBALS._scrollFollower = &_actor11;
+ _tealSpeaker._object1.hide();
+ _actor5.show();
+ _actor5.setStrip(2);
+ if (R2_GLOBALS._player._characterIndex == 2)
+ _sceneMode = 3602;
+ else if (R2_GLOBALS._player._characterIndex == 3)
+ _sceneMode = 3603;
+ else
+ _sceneMode = 3601;
+ setAction(&_sequenceManager1, this, _sceneMode, &_actor11, &_actor10, &_actor12, &_actor4, &_actor5, NULL);
+ break;
+ case 3321:
+ warning("STUB: sub_1D227()");
+ R2_GLOBALS._scrollFollower = &R2_GLOBALS._player;
+ _tealSpeaker.proc16();
+ _actor5.show();
+ _actor5.setStrip(1);
+ _actor3.postInit();
+ _sceneMode = 3604;
+ setAction(&_sequenceManager1, this, _sceneMode, &_actor5, &_actor3, &_actor10, &_actor11, &_actor12, &_actor4, NULL);
+ break;
+ case 3322:
+ warning("STUB: sub_1D227()");
+ _quinnSpeaker.proc16();
+ _quinnSpeaker._displayMode = 1;
+ _tealSpeaker.proc16();
+ _tealSpeaker._displayMode = 7;
+ R2_GLOBALS._scrollFollower = &_actor5;
+ _sceneMode = 3605;
+ setAction(&_sequenceManager1, this, _sceneMode, &_actor5, &_actor13, &_actor2, NULL);
+ break;
+ case 3323:
+ if (_field254A == 0)
+ _field254A = 1;
+ else {
+ warning("STUB: sub_1D227()");
+ _protectorSpeaker.proc16();
+ _actor13.show();
+ _actor13.setup(3258, 6, 1);
+ _sceneMode = 3607;
+ _actor13.setAction(&_sequenceManager1, this, _sceneMode, &_actor13, NULL);
+ R2_GLOBALS._v558C2 = 1;
+ _protectorSpeaker.proc16();
+ _protectorSpeaker._displayMode = 1;
+ _quinnSpeaker._displayMode = 1;
+ _actor13.show();
+ R2_GLOBALS._scrollFollower = &R2_GLOBALS._player;
+ R2_GLOBALS._walkRegions.disableRegion(17);
+ R2_GLOBALS._walkRegions.disableRegion(18);
+ R2_GLOBALS._walkRegions.enableRegion(2);
+ R2_GLOBALS._walkRegions.enableRegion(7);
+ R2_GLOBALS._walkRegions.enableRegion(14);
+ R2_GLOBALS._walkRegions.enableRegion(15);
+ R2_GLOBALS._walkRegions.enableRegion(16);
+ _actor13.setAction(&_action1);
+ }
+ break;
+ case 3324:
+ // No break on purpose
+ case 3607:
+ g_globals->_events.setCursor(CURSOR_ARROW);
+ R2_GLOBALS._player.enableControl(CURSOR_ARROW);
+ _actor13.fixPriority(-1);
+ _sceneMode = 3623;
+ _field2548 = 1;
+ break;
+ case 3327:
+ g_globals->_events.setCursor(CURSOR_ARROW);
+ R2_GLOBALS._player.enableControl(CURSOR_ARROW);
+ _sceneMode = 3623;
+ break;
+ case 3450:
+ R2_GLOBALS._sound1.stop();
+ _actor1.hide();
+ _actor6.hide();
+ g_globals->gfxManager()._bounds.moveTo(Common::Point(40, 0));
+ setZoomPercents(142, 80, 167, 105);
+ loadScene(3600);
+ R2_GLOBALS._uiElements.show();
+ _item5._sceneRegionId = 200;
+ _item5.setDetails(3600, 30, -1, -1, 5, &_actor4);
+
+ _actor3.show();
+ _actor10.show();
+ _actor11.show();
+ _actor12.show();
+ _actor4.show();
+ _actor5.show();
+
+ _actor5.setPosition(Common::Point(298, 151));
+
+ _actor13.postInit();
+ _actor13._state = 0;
+ _actor13._field8A = Common::Point(226, 152);
+ _actor13._moveDiff = Common::Point(5, 3);
+ _actor13.setup(3403, 7, 1);
+ _actor13.setPosition(Common::Point(405, 155));
+ _actor13.changeZoom(-1);
+ _actor13.addMover(NULL);
+ _actor13.animate(ANIM_MODE_NONE);
+ _actor13.hide();
+ _actor13.setDetails(3600, 15, -1, 17, 5, &_item5);
+
+ _actor2.setup(3600, 2, 1);
+ _actor2.setPosition(Common::Point(403, 161));
+ _actor2.fixPriority(149);
+ _actor2.changeZoom(-1);
+ _actor2.show();
+
+ _quinnSpeaker._displayMode = 2;
+ _tealSpeaker._displayMode = 2;
+
+ if (R2_GLOBALS._player._characterIndex == 2) {
+ R2_GLOBALS._player._moveDiff = Common::Point(5, 3);
+ R2_GLOBALS._player.setup(20, _actor11._strip, 1);
+ R2_GLOBALS._player.setPosition(_actor11._position);
+ _actor11.hide();
+ } else if (R2_GLOBALS._player._characterIndex == 3) {
+ R2_GLOBALS._player._moveDiff = Common::Point(3, 2);
+ R2_GLOBALS._player.setup(30, _actor12._strip, 1);
+ R2_GLOBALS._player.setPosition(_actor12._position);
+ _actor12.hide();
+ } else {
+ R2_GLOBALS._player._moveDiff = Common::Point(3, 2);
+ R2_GLOBALS._player.setup(10, _actor10._strip, 1);
+ R2_GLOBALS._player.setPosition(_actor10._position);
+ _actor10.hide();
+ }
+ R2_GLOBALS._player.show();
+ R2_GLOBALS._sound1.play(326);
+ _sceneMode = 3322;
+ _stripManager.start(3322, this);
+ R2_GLOBALS._sound2.play(329);
+ break;
+ case 3600:
+ _sceneMode = 3320;
+ _stripManager.start(3320, this);
+ break;
+ case 3601:
+ // No break on purpose
+ case 3602:
+ // No break on purpose
+ case 3603:
+ R2_GLOBALS._walkRegions.enableRegion(2);
+ R2_GLOBALS._walkRegions.enableRegion(7);
+ R2_GLOBALS._v558B6.set(60, 0, 260, 200);
+ _tealSpeaker._displayMode = 1;
+ _sceneMode = 3321;
+ _stripManager.start(3321, this);
+ break;
+ case 3604:
+ R2_GLOBALS._sound2.fadeOut2(NULL);
+ R2_GLOBALS._sound1.stop();
+ R2_GLOBALS._walkRegions.disableRegion(2);
+ R2_GLOBALS._walkRegions.disableRegion(7);
+
+ _actor2.hide();
+ _actor3.hide();
+ R2_GLOBALS._player.hide();
+ _actor10.hide();
+ _actor11.hide();
+ _actor12.hide();
+ _actor4.hide();
+ _actor5.hide();
+
+ g_globals->gfxManager()._bounds.moveTo(Common::Point(60, 0));
+ setZoomPercents(51, 46, 180, 200);
+
+ loadScene(3400);
+ R2_GLOBALS._uiElements.show();
+ _actor1.postInit();
+
+ _actor2.setup(3403, 1, 1);
+ _actor2.setPosition(Common::Point(190, 103));
+ _actor2.fixPriority(89);
+ _actor2.show();
+
+ _actor6.postInit();
+ _actor6.setup(3400, 1, 6);
+ _actor6.setPosition(Common::Point(236, 51));
+ _actor6.fixPriority(51);
+ R2_GLOBALS._scrollFollower = &_actor6;
+
+ R2_GLOBALS._sound1.play(323);
+ _sceneMode = 3450;
+ setAction(&_sequenceManager1, this, 3450, &_actor1, &_actor6, NULL);
+ break;
+ case 3605:
+ _actor13.setup(3258, 4, 1);
+ _actor13.setAction(&_sequenceManager1, this, 3606, &_actor5, &_actor13, &_actor2, NULL);
+ _sceneMode = 3323;
+ _stripManager.start(3323, this);
+
+ break;
+ case 3620:
+ // No break on purpose
+ case 3623:
+ if ((_actor13._position.x == 226) && (_actor13._position.y == 152) && (_action1._field1E != 0) && (_actor13._visage == 3127) && (!R2_GLOBALS.getFlag(71))) {
+ R2_GLOBALS._sound2.stop();
+ R2_GLOBALS._sound2.play(331);
+ R2_GLOBALS.setFlag(71);
+ _sceneMode = 3626;
+ setAction(&_sequenceManager1, this, 3626, &_actor13, NULL);
+ }
+ break;
+ case 3624:
+ R2_GLOBALS._player.disableControl();
+ if ((_field254E != 0) && (_actor10._position.x == 229) && (_actor10._position.y == 154) && (_actor11._position.x == 181) && (_actor11._position.y == 154) && (_actor12._position.x == 207) && (_actor12._position.y == 154) && (_actor4._position.x == 155) && (_actor4._position.y == 154)) {
+ R2_GLOBALS._sound2.stop();
+ R2_GLOBALS._sound2.play(331);
+ _sceneMode = 3625;
+ setAction(&_sequenceManager1, this, 3625, &_actor10, &_actor11, &_actor12, &_actor4, NULL);
+ }
+ break;
+ case 3625:
+ R2_GLOBALS._sound2.stop();
+ R2_GLOBALS._sceneManager.changeScene(3700);
+ break;
+ case 3626:
+ _actor13.setPosition(Common::Point(0, 0));
+ _action1.setActionIndex(2);
+ if (R2_GLOBALS._events.getCursor() > R2_LAST_INVENT) {
+ R2_GLOBALS._events.setCursor(CURSOR_USE);
+ R2_GLOBALS._player.enableControl(CURSOR_USE);
+ } else {
+ R2_GLOBALS._player.enableControl();
+ }
+ R2_GLOBALS._sound2.stop();
+ _sceneMode = 3623;
+ break;
+ default:
+ break;
+ }
+}
+
+void Scene3600::process(Event &event) {
+ if ((event.eventType == EVENT_BUTTON_DOWN) && (R2_GLOBALS._events.getCursor() == CURSOR_ARROW) && (event.mousePos.x > 237) && (!R2_GLOBALS.getFlag(71))) {
+ SceneItem::display(3600, 17, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7 -999);
+ event.handled = true;
+ }
+ Scene::process(event);
+}
+
+void Scene3600::dispatch() {
+ if ((R2_GLOBALS._player.getRegionIndex() == 200) && (_action1._field1E != 0) && (_field254E == 0)){
+ R2_GLOBALS._sound2.fadeOut2(NULL);
+ if (_actor13._mover)
+ _actor13.addMover(NULL);
+ if (R2_GLOBALS._player._action)
+ R2_GLOBALS._player.setAction(NULL);
+ if (R2_GLOBALS._player._mover)
+ R2_GLOBALS._player.addMover(NULL);
+
+ _field254C = 0;
+ _field254E = 1;
+
+ R2_GLOBALS._walkRegions.disableRegion(2);
+ R2_GLOBALS._walkRegions.disableRegion(7);
+ R2_GLOBALS._player.disableControl();
+
+ _sceneMode = 3624;
+
+ _actor10.setStrip(-1);
+ _actor11.setStrip(-1);
+ _actor12.setStrip(-1);
+ _actor4.setStrip(-1);
+
+ R2_GLOBALS._player.hide();
+
+ if (R2_GLOBALS._player._characterIndex == 2) {
+ _actor11.setPosition(R2_GLOBALS._player._position);
+ _actor11.show();
+ } else if (R2_GLOBALS._player._characterIndex == 3) {
+ _actor12.setPosition(R2_GLOBALS._player._position);
+ _actor12.show();
+ } else {
+ _actor10.setPosition(R2_GLOBALS._player._position);
+ _actor10.show();
+ }
+ _actor10.setAction(&_sequenceManager2, this, 3610, &_actor10, NULL);
+ _actor11.setAction(&_sequenceManager3, this, 3611, &_actor11, NULL);
+ _actor12.setAction(&_sequenceManager4, this, 3612, &_actor12, NULL);
+ _actor4.setAction(&_sequenceManager1, this, 3613, &_actor4, NULL);
+ }
+
+ if ((_actor13.getRegionIndex() == 200) && (_action1._field1E != 0) && (_field254E == 0)){
+ R2_GLOBALS._sound2.fadeOut2(NULL);
+ _sceneMode = 3620;
+ _field2550 = 1;
+ R2_GLOBALS._player.disableControl();
+
+ if (R2_GLOBALS._player._mover)
+ R2_GLOBALS._player.addMover(NULL);
+ if (_actor10._mover)
+ _actor10.addMover(NULL);
+ if (_actor11._mover)
+ _actor11.addMover(NULL);
+ if (_actor12._mover)
+ _actor12.addMover(NULL);
+ if (_actor4._mover)
+ _actor4.addMover(NULL);
+ }
+ Scene::dispatch();
+}
+
+/*--------------------------------------------------------------------------
+ * Scene 3700 - Cutscene - Teleport outside
+ *
+ *--------------------------------------------------------------------------*/
+void Scene3700::postInit(SceneObjectList *OwnerList) {
+ loadScene(3700);
+ R2_GLOBALS._uiElements._active = false;
+ SceneExt::postInit();
+
+ _stripManager.setColors(60, 255);
+ _stripManager.setFontNumber(3);
+ _stripManager.addSpeaker(&_quinnSpeaker);
+ _stripManager.addSpeaker(&_seekerSpeaker);
+ _stripManager.addSpeaker(&_mirandaSpeaker);
+
+ _actor1.postInit();
+ _actor1._moveDiff = Common::Point(3, 2);
+
+ _actor2.postInit();
+ _actor2._numFrames = 7;
+ _actor2._moveDiff = Common::Point(5, 3);
+ _actor2.hide();
+
+ _actor3.postInit();
+ _actor3._moveDiff = Common::Point(3, 2);
+ _actor3.hide();
+
+ _actor4.postInit();
+ _actor4._numFrames = 7;
+ _actor4._moveDiff = Common::Point(5, 3);
+ _actor4.hide();
+
+ _actor5.postInit();
+
+ R2_GLOBALS._player.postInit();
+ R2_GLOBALS._sound1.play(332);
+
+ _sceneMode = 3700;
+ setAction(&_sequenceManager, this, 3700, &_actor1, &_actor2, &_actor3, &_actor4, &_actor5, NULL);
+}
+
+void Scene3700::remove() {
+ R2_GLOBALS._sound1.fadeOut2(NULL);
+ SceneExt::remove();
+}
+
+void Scene3700::signal() {
+ switch (_sceneMode) {
+ case 3328:
+ // No break on purpose
+ case 3329:
+ warning("STUB: sub_1D227()");
+ _sceneMode = 3701;
+ setAction(&_sequenceManager, this, 3701, &_actor2, &_actor3, &_actor4, NULL);
+ break;
+ case 3700:
+ _actor1.setup(10, 6, 1);
+ _actor2.setup(20, 5, 1);
+ if (R2_GLOBALS.getFlag(71)) {
+ _sceneMode = 3329;
+ _stripManager.start(3329, this);
+ } else {
+ _sceneMode = 3328;
+ _stripManager.start(3328, this);
+ }
+ break;
+ case 3701:
+ R2_GLOBALS._sceneManager.changeScene(1000);
+ break;
+ default:
+ R2_GLOBALS._player.enableControl();
+ break;
+ }
+}
+
+/*--------------------------------------------------------------------------
+ * Scene 3800 -
+ *
+ *--------------------------------------------------------------------------*/
+Scene3800::Scene3800() {
+ _field412 = 0;
+}
+void Scene3800::synchronize(Serializer &s) {
+ SceneExt::synchronize(s);
+
+ s.syncAsSint16LE(_field412);
+}
+
+void Scene3800::Exit1::changeScene() {
+ Scene3800 *scene = (Scene3800 *)R2_GLOBALS._sceneManager._scene;
+
+ _enabled = false;
+ R2_GLOBALS._player.disableControl(CURSOR_ARROW);
+ scene->_field412 = 1;
+
+ if (R2_GLOBALS.getFlag(46)) {
+ if (scene->_field412 == R2_GLOBALS._v566A9) {
+ R2_GLOBALS._v566AA = 3;
+ if (R2_GLOBALS._v56A93 + 1 == 0) {
+ R2_GLOBALS._v566A8--;
+ R2_GLOBALS._v566A9 = 0;
+ } else {
+ R2_GLOBALS._v566A9 = R2_GLOBALS._v566AB[R2_GLOBALS._v56A93];
+ R2_GLOBALS._v56A93--;
+ }
+ } else {
+ ++R2_GLOBALS._v56A93;
+ if (R2_GLOBALS._v56A93 > 999)
+ R2_GLOBALS._v56A93 = 999;
+ R2_GLOBALS._v566AB[R2_GLOBALS._v56A93] = R2_GLOBALS._v566A9;
+ R2_GLOBALS._v566A9 = 3;
+ }
+ }
+
+ if (R2_GLOBALS._v566A8 == 0)
+ scene->_sceneMode = 16;
+ else
+ scene->_sceneMode = 11;
+
+ Common::Point pt(160, 115);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, scene);
+}
+
+void Scene3800::Exit2::changeScene() {
+ Scene3800 *scene = (Scene3800 *)R2_GLOBALS._sceneManager._scene;
+
+ _enabled = false;
+ R2_GLOBALS._player.disableControl(CURSOR_ARROW);
+ scene->_field412 = 2;
+
+ if (R2_GLOBALS.getFlag(46)) {
+ if (scene->_field412 == R2_GLOBALS._v566A9) {
+ R2_GLOBALS._v566AA = 4;
+ if (R2_GLOBALS._v56A93 + 1 == 0) {
+ R2_GLOBALS._v566A8--;
+ R2_GLOBALS._v566A9 = 0;
+ } else {
+ R2_GLOBALS._v566A9 = R2_GLOBALS._v566AB[R2_GLOBALS._v56A93];
+ R2_GLOBALS._v56A93--;
+ }
+ } else {
+ ++R2_GLOBALS._v56A93;
+ if (R2_GLOBALS._v56A93 > 999)
+ R2_GLOBALS._v56A93 = 999;
+ R2_GLOBALS._v566AB[R2_GLOBALS._v56A93] = R2_GLOBALS._v566A9;
+ R2_GLOBALS._v566A9 = 4;
+ }
+ }
+
+ if (R2_GLOBALS._v566A8 == 0)
+ scene->_sceneMode = 16;
+ else
+ scene->_sceneMode = 12;
+
+ Common::Point pt(330, 145);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, scene);
+}
+
+void Scene3800::Exit3::changeScene() {
+ Scene3800 *scene = (Scene3800 *)R2_GLOBALS._sceneManager._scene;
+
+ _enabled = false;
+ R2_GLOBALS._player.disableControl(CURSOR_ARROW);
+ scene->_field412 = 3;
+
+ if (R2_GLOBALS.getFlag(46)) {
+ if (scene->_field412 == R2_GLOBALS._v566A9) {
+ R2_GLOBALS._v566AA = 1;
+ if (R2_GLOBALS._v56A93 + 1 == 0) {
+ R2_GLOBALS._v566A8--;
+ R2_GLOBALS._v566A9 = 0;
+ } else {
+ R2_GLOBALS._v566A9 = R2_GLOBALS._v566AB[R2_GLOBALS._v56A93];
+ R2_GLOBALS._v56A93--;
+ }
+ } else {
+ ++R2_GLOBALS._v56A93;
+ if (R2_GLOBALS._v56A93 > 999)
+ R2_GLOBALS._v56A93 = 999;
+ R2_GLOBALS._v566AB[R2_GLOBALS._v56A93] = R2_GLOBALS._v566A9;
+ R2_GLOBALS._v566A9 = 1;
+ }
+ }
+
+ if (R2_GLOBALS._v566A8 == 0)
+ scene->_sceneMode = 16;
+ else
+ scene->_sceneMode = 13;
+
+ Common::Point pt(160, 220);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, scene);
+}
+
+void Scene3800::Exit4::changeScene() {
+ Scene3800 *scene = (Scene3800 *)R2_GLOBALS._sceneManager._scene;
+
+ _enabled = false;
+ R2_GLOBALS._player.disableControl(CURSOR_ARROW);
+ scene->_field412 = 4;
+
+ if (R2_GLOBALS.getFlag(46)) {
+ if (scene->_field412 == R2_GLOBALS._v566A9) {
+ R2_GLOBALS._v566AA = 2;
+ if (R2_GLOBALS._v56A93 + 1 == 0) {
+ R2_GLOBALS._v566A8--;
+ R2_GLOBALS._v566A9 = 0;
+ } else {
+ R2_GLOBALS._v566A9 = R2_GLOBALS._v566AB[R2_GLOBALS._v56A93];
+ R2_GLOBALS._v56A93--;
+ }
+ } else {
+ ++R2_GLOBALS._v56A93;
+ if (R2_GLOBALS._v56A93 > 999)
+ R2_GLOBALS._v56A93 = 999;
+ R2_GLOBALS._v566AB[R2_GLOBALS._v56A93] = R2_GLOBALS._v566A9;
+ R2_GLOBALS._v566A9 = 2;
+ }
+ }
+
+ if (R2_GLOBALS._v566A8 == 0)
+ scene->_sceneMode = 16;
+ else
+ scene->_sceneMode = 14;
+
+ Common::Point pt(-10, 145);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, scene);
+}
+
+void Scene3800::initScene3800() {
+ _exit1._enabled = true;
+ _exit2._enabled = true;
+ _exit3._enabled = true;
+ _exit4._enabled = true;
+ _exit1._insideArea = false;
+ _exit2._insideArea = false;
+ _exit3._insideArea = false;
+ _exit4._insideArea = false;
+ _exit1._moving = false;
+ _exit2._moving = false;
+ _exit3._moving = false;
+ _exit4._moving = false;
+
+ loadScene(R2_GLOBALS._v566A6);
+
+ R2_GLOBALS._uiElements.draw();
+}
+
+void Scene3800::sub110BBD() {
+ R2_GLOBALS._player.disableControl();
+ switch (_field412) {
+ case 0:
+ R2_GLOBALS._player.postInit();
+ R2_GLOBALS._player.setVisage(10);
+ R2_GLOBALS._player.animate(ANIM_MODE_1, NULL);
+ R2_GLOBALS._player.setPosition(Common::Point(160, 145));
+ R2_GLOBALS._player.setStrip(3);
+ R2_GLOBALS._player.changeZoom(-1);
+ R2_GLOBALS._player._moveDiff = Common::Point(3, 2);
+ _actor1.postInit();
+ _actor1.fixPriority(10);
+ _actor1.changeZoom(-1);
+ _actor1.setVisage(1110);
+ _actor1._effect = 5;
+ _actor1._field9C = this->_field312;
+ R2_GLOBALS._player._linkedActor = &_actor1;
+ switch (R2_GLOBALS._sceneManager._previousScene) {
+ case 2600:
+ _object1.postInit();
+ _object2.postInit();
+ _actor1.hide();
+ _sceneMode = 3800;
+ setAction(&_sequenceManager1, this, 3800, &R2_GLOBALS._player, &_object1, &_object2, NULL);
+ break;
+ case 3900:
+ _sceneMode = 15;
+ switch (R2_GLOBALS._v566AA - 1) {
+ case 0: {
+ R2_GLOBALS._player.setPosition(Common::Point(160, 220));
+ Common::Point pt(160, 160);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, this);
+ }
+ break;
+ case 1: {
+ R2_GLOBALS._player.setPosition(Common::Point(-10, 145));
+ Common::Point pt(19, 145);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, this);
+ }
+ break;
+ case 2: {
+ R2_GLOBALS._player.setPosition(Common::Point(160, 115));
+ Common::Point pt(160, 120);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, this);
+ }
+ break;
+ case 3: {
+ R2_GLOBALS._player.setPosition(Common::Point(330, 145));
+ Common::Point pt(300, 145);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, this);
+ }
+ break;
+ default:
+ break;
+ }
+ default:
+ R2_GLOBALS._player.enableControl(CURSOR_ARROW);
+ break;
+ }
+ break;
+ case 1: {
+ _sceneMode = 15;
+ R2_GLOBALS._player.setPosition(Common::Point(160, 220));
+ Common::Point pt(160, 160);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, this);
+ }
+ break;
+ case 2: {
+ _sceneMode = 15;
+ R2_GLOBALS._player.setPosition(Common::Point(-10, 145));
+ Common::Point pt(19, 145);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, this);
+ }
+ break;
+ case 3: {
+ _sceneMode = 15;
+ R2_GLOBALS._player.setPosition(Common::Point(160, 115));
+ Common::Point pt(160, 120);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, this);
+ }
+ break;
+ case 4: {
+ _sceneMode = 15;
+ R2_GLOBALS._player.setPosition(Common::Point(330, 145));
+ Common::Point pt(300, 145);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, this);
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+void Scene3800::postInit(SceneObjectList *OwnerList) {
+ _field412 = 0;
+
+ initScene3800();
+
+ SceneExt::postInit();
+ R2_GLOBALS._sound1.play(231);
+
+ scalePalette(65, 65, 65);
+
+ setZoomPercents(87, 40, 144, 100);
+
+ _exit1.setDetails(Rect(14, 87, 305, 125), SHADECURSOR_UP, 3800);
+ _exit1.setDest(Common::Point(160, 126));
+ _exit2.setDetails(Rect(305, 87, 320, 128), EXITCURSOR_E, 3800);
+ _exit2.setDest(Common::Point(312, 145));
+ _exit3.setDetails(Rect(14, 160, 305, 168), SHADECURSOR_DOWN, 3800);
+ _exit3.setDest(Common::Point(160, 165));
+ _exit4.setDetails(Rect(0, 87, 14, 168), EXITCURSOR_W, 3800);
+ _exit4.setDest(Common::Point(7, 145));
+
+ _rect1.set(0, 0, 320, 87);
+ _item1.setDetails(Rect(0, 0, 320, 200), 3800, 0, 1, 2, 1, (SceneItem *) NULL);
+
+ sub110BBD();
+}
+
+void Scene3800::signal() {
+ switch (_sceneMode) {
+ case 11:
+ R2_GLOBALS._v566A6 += 15;
+ if (R2_GLOBALS._v566A6 > 3815)
+ R2_GLOBALS._v566A6 -= 20;
+ initScene3800();
+ sub110BBD();
+ break;
+ case 12:
+ R2_GLOBALS._v566A6 += 5;
+ if (R2_GLOBALS._v566A6 > 3815)
+ R2_GLOBALS._v566A6 = 3800;
+ initScene3800();
+ sub110BBD();
+ break;
+ case 13:
+ R2_GLOBALS._v566A6 -= 15;
+ if (R2_GLOBALS._v566A6 < 3800)
+ R2_GLOBALS._v566A6 += 20;
+ initScene3800();
+ sub110BBD();
+ break;
+ case 14:
+ R2_GLOBALS._v566A6 -= 5;
+ if (R2_GLOBALS._v566A6 < 3800)
+ R2_GLOBALS._v566A6 = 3815;
+ initScene3800();
+ sub110BBD();
+ break;
+ case 15:
+ R2_GLOBALS._v56AAB = 0;
+ R2_GLOBALS._player.disableControl(CURSOR_ARROW);
+ break;
+ case 16:
+ g_globals->_sceneManager.changeScene(3900);
+ break;
+ case 3800:
+ _actor1.show();
+ _object1.remove();
+ _object2.remove();
+ R2_GLOBALS._v56AAB = 0;
+ R2_GLOBALS._player.disableControl(CURSOR_ARROW);
+ break;
+ case 3805:
+ _exit1._enabled = false;
+ _exit2._enabled = false;
+ _exit3._enabled = false;
+ _exit4._enabled = false;
+ R2_GLOBALS._player._canWalk = false;
+ R2_GLOBALS._events.setCursor(CURSOR_USE);
+ break;
+ case 3806:
+ _exit1._enabled = true;
+ _exit2._enabled = true;
+ _exit3._enabled = true;
+ _exit4._enabled = true;
+ R2_GLOBALS._player.disableControl(CURSOR_ARROW);
+ break;
+ default:
+ break;
+ }
+}
+
+void Scene3800::process(Event &event) {
+ if ((R2_GLOBALS._player._uiEnabled) && (event.eventType == 1) && (_rect1.contains(event.mousePos))) {
+ event.handled = true;
+ switch (R2_GLOBALS._events.getCursor()) {
+ case R2_NEGATOR_GUN:
+ R2_GLOBALS._player.addMover(NULL);
+ R2_GLOBALS._player.updateAngle(event.mousePos);
+ break;
+ case R2_STEPPING_DISKS:
+ SceneItem::display(3800, 5, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
+ break;
+ case R2_ATTRACTOR_UNIT:
+ SceneItem::display(3800, 3, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
+ break;
+ default:
+ event.handled = false;
+ break;
+ }
+ }
+
+ Scene::process(event);
+}
+
+/*--------------------------------------------------------------------------
+ * Scene 3900 -
+ *
+ *--------------------------------------------------------------------------*/
+void Scene3900::Exit1::changeScene() {
+ Scene3900 *scene = (Scene3900 *)R2_GLOBALS._sceneManager._scene;
+
+ _enabled = false;
+ R2_GLOBALS._player.disableControl(CURSOR_ARROW);
+ R2_GLOBALS._v566A9 = 3;
+ R2_GLOBALS._v566AA = 1;
+ R2_GLOBALS._v566A8 = 1;
+ scene->_sceneMode = 14;
+
+ Common::Point pt(160, 115);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, scene);
+}
+
+void Scene3900::Exit2::changeScene() {
+ Scene3900 *scene = (Scene3900 *)R2_GLOBALS._sceneManager._scene;
+
+ _enabled = false;
+ R2_GLOBALS._player.disableControl(CURSOR_ARROW);
+ R2_GLOBALS._v566A9 = 4;
+ R2_GLOBALS._v566AA = 2;
+ R2_GLOBALS._v566A8 = 1;
+ scene->_sceneMode = 14;
+
+ Common::Point pt(330, 145);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, scene);
+}
+
+void Scene3900::Exit3::changeScene() {
+ Scene3900 *scene = (Scene3900 *)R2_GLOBALS._sceneManager._scene;
+
+ _enabled = false;
+ R2_GLOBALS._player.disableControl(CURSOR_ARROW);
+ R2_GLOBALS._v566A9 = 1;
+ R2_GLOBALS._v566AA = 3;
+ R2_GLOBALS._v566A8 = 1;
+ scene->_sceneMode = 14;
+
+ Common::Point pt(160, 220);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, scene);
+}
+
+void Scene3900::Exit4::changeScene() {
+ Scene3900 *scene = (Scene3900 *)R2_GLOBALS._sceneManager._scene;
+
+ _enabled = false;
+ R2_GLOBALS._player.disableControl(CURSOR_ARROW);
+ R2_GLOBALS._v566A9 = 2;
+ R2_GLOBALS._v566AA = 4;
+ R2_GLOBALS._v566A8 = 1;
+ scene->_sceneMode = 14;
+
+ Common::Point pt(-10, 145);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, scene);
+}
+
+void Scene3900::Exit5::changeScene() {
+ Scene3900 *scene = (Scene3900 *)R2_GLOBALS._sceneManager._scene;
+
+ _enabled = false;
+ R2_GLOBALS._player.disableControl(CURSOR_ARROW);
+ scene->_sceneMode = 13;
+
+ if (R2_GLOBALS._v566A9 == 4) {
+ Common::Point pt(-10, 135);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, scene);
+ } else {
+ Common::Point pt(330, 135);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, scene);
+ }
+
+ R2_GLOBALS._v566A9 = 0;
+}
+
+void Scene3900::postInit(SceneObjectList *OwnerList) {
+ if ((R2_GLOBALS._v566AA == 2) && (R2_GLOBALS._sceneManager._previousScene != 2700))
+ loadScene(3825);
+ else
+ loadScene(3820);
+ SceneExt::postInit();
+ R2_GLOBALS._sound1.changeSound(231);
+ setZoomPercents(87, 40, 144, 100);
+ R2_GLOBALS._player.disableControl();
+ R2_GLOBALS._player.postInit();
+ R2_GLOBALS._player.setVisage(10);
+ R2_GLOBALS._player.animate(ANIM_MODE_1, NULL);
+ R2_GLOBALS._player.setStrip(3);
+ R2_GLOBALS._player.changeZoom(-1);
+ R2_GLOBALS._player._moveDiff = Common::Point(3, 2);
+ _actor1.postInit();
+ _actor1.fixPriority(10);
+ _actor1.changeZoom(-1);
+ _actor1.setVisage(1110);
+ _actor1._effect = 5;
+ _actor1._field9C = _field312;
+ R2_GLOBALS._player._linkedActor = &_actor1;
+ if ((R2_GLOBALS._v566AA == 2) && (R2_GLOBALS._sceneManager._previousScene != 2700)) {
+// loadScene(3825);
+ R2_GLOBALS._v566AA = 4;
+ _exit1.setDetails(Rect(29, 87, 305, 125), SHADECURSOR_UP, 3900);
+ _exit3.setDetails(Rect(29, 160, 305, 168), SHADECURSOR_DOWN, 3900);
+
+ _exit2.setDetails(Rect(305, 87, 320, 168), EXITCURSOR_E, 3900);
+ _exit2.setDest(Common::Point(312, 145));
+ _exit2._enabled = true;
+ _exit2._insideArea = false;
+ _exit2._moving = false;
+
+ _exit4._enabled = false;
+
+ _exit5.setDetails(Rect(0, 87, 29, 168), EXITCURSOR_W, 3900);
+ _exit5.setDest(Common::Point(24, 135));
+ } else {
+// loadScene(3820);
+ R2_GLOBALS._v566AA = 2;
+ _exit1.setDetails(Rect(14, 87, 290, 125), SHADECURSOR_UP, 3900);
+ _exit3.setDetails(Rect(14, 160, 290, 168), SHADECURSOR_DOWN, 3900);
+
+
+ _exit2._enabled = false;
+
+ _exit4.setDetails(Rect(0, 87, 14, 168), EXITCURSOR_W, 3900);
+ _exit4.setDest(Common::Point(7, 145));
+ _exit4._enabled = true;
+ _exit4._insideArea = false;
+ _exit4._moving = false;
+
+ _exit5.setDetails(Rect(290, 87, 320, 168), EXITCURSOR_E, 3900);
+ _exit5.setDest(Common::Point(295, 135));
+ }
+ _exit5._enabled = true;
+ _exit5._insideArea = false;
+ _exit5._moving = false;
+
+ scalePalette(65, 65, 65);
+
+ _exit1.setDest(Common::Point(160, 126));
+ _exit1._enabled = true;
+ _exit1._insideArea = false;
+ _exit1._moving = false;
+
+ _exit3.setDest(Common::Point(160, 165));
+ _exit3._enabled = true;
+ _exit3._insideArea = false;
+ _exit3._moving = false;
+
+ R2_GLOBALS._uiElements.draw();
+
+ _rect1.set(0, 0, 320, 87);
+ _item1.setDetails(Rect(0, 0, 320, 200), 3800, 0, 1, 2, 1, (SceneItem *)NULL);
+ if (R2_GLOBALS._sceneManager._previousScene == 3800) {
+ _sceneMode = 11;
+ switch (R2_GLOBALS._v566AA - 1) {
+ case 0: {
+ R2_GLOBALS._player.setPosition(Common::Point(160, 115));
+ Common::Point pt(160, 120);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, this);
+ }
+ break;
+ case 1: {
+ R2_GLOBALS._player.setPosition(Common::Point(330, 145));
+ Common::Point pt(300, 145);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, this);
+ }
+ break;
+ case 2: {
+ R2_GLOBALS._player.setPosition(Common::Point(160, 220));
+ Common::Point pt(160, 160);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, this);
+ }
+ break;
+ case 3: {
+ R2_GLOBALS._player.setPosition(Common::Point(-10, 145));
+ Common::Point pt(19, 145);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, this);
+ }
+ break;
+ default:
+ break;
+ }
+ } else if (R2_GLOBALS._sceneManager._previousScene == 2700) {
+ _sceneMode = 12;
+ R2_GLOBALS._player.setPosition(Common::Point(330, 135));
+ Common::Point pt(265, 135);
+ NpcMover *mover = new NpcMover();
+ R2_GLOBALS._player.addMover(mover, &pt, this);
+ } else {
+ R2_GLOBALS._player.setPosition(Common::Point(160, 145));
+ R2_GLOBALS._player.enableControl(CURSOR_ARROW);
+ }
+}
+
+void Scene3900::signal() {
+ switch (_sceneMode) {
+ case 11:
+ // No break on purpose
+ case 12:
+ R2_GLOBALS._v56AAB = 0;
+ R2_GLOBALS._player.enableControl(CURSOR_ARROW);
+ break;
+ case 13:
+ R2_GLOBALS._sceneManager.changeScene(2700);
+ break;
+ case 14:
+ R2_GLOBALS._sceneManager.changeScene(3800);
+ break;
+ case 3805:
+ _exit1._enabled = false;
+ _exit2._enabled = false;
+ _exit3._enabled = false;
+ _exit4._enabled = false;
+ R2_GLOBALS._player._canWalk = false;
+ R2_GLOBALS._events.setCursor(R2_STEPPING_DISKS);
+ break;
+ case 3806:
+ _exit1._enabled = true;
+ _exit2._enabled = true;
+ _exit3._enabled = true;
+ _exit4._enabled = true;
+ R2_GLOBALS._player.enableControl(CURSOR_ARROW);
+ break;
+ default:
+ break;
+ }
+}
+
+void Scene3900::process(Event &event) {
+ if ((R2_GLOBALS._player._uiEnabled) && (event.eventType == 1) && (_rect1.contains(event.mousePos))) {
+ event.handled = true;
+ switch (R2_GLOBALS._events.getCursor()) {
+ case R2_NEGATOR_GUN:
+ R2_GLOBALS._player.addMover(NULL);
+ R2_GLOBALS._player.updateAngle(event.mousePos);
+ break;
+ case R2_STEPPING_DISKS:
+ SceneItem::display(3800, 5, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
+ break;
+ case R2_ATTRACTOR_UNIT:
+ SceneItem::display(3800, 3, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
+ break;
+ default:
+ event.handled = false;
+ break;
+ }
+ }
+ Scene::process(event);
+}
+
+} // End of namespace Ringworld2
+} // End of namespace TsAGE
diff --git a/engines/tsage/ringworld2/ringworld2_scenes3.h b/engines/tsage/ringworld2/ringworld2_scenes3.h
new file mode 100644
index 0000000000..44787b9eef
--- /dev/null
+++ b/engines/tsage/ringworld2/ringworld2_scenes3.h
@@ -0,0 +1,868 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef TSAGE_RINGWORLD2_SCENES3_H
+#define TSAGE_RINGWORLD2_SCENES3_H
+
+#include "common/scummsys.h"
+#include "tsage/converse.h"
+#include "tsage/events.h"
+#include "tsage/core.h"
+#include "tsage/scenes.h"
+#include "tsage/globals.h"
+#include "tsage/sound.h"
+#include "tsage/ringworld2/ringworld2_logic.h"
+#include "tsage/ringworld2/ringworld2_speakers.h"
+
+namespace TsAGE {
+
+namespace Ringworld2 {
+
+using namespace TsAGE;
+
+
+class Scene3100 : public SceneExt {
+ class Guard : public SceneActor {
+ virtual bool startAction(CursorType action, Event &event);
+ };
+public:
+
+ int _field412;
+ SpeakerGuard _guardSpeaker;
+ NamedHotspot _item1;
+ NamedHotspot _item2;
+ SceneActor _actor1;
+ SceneActor _actor2;
+ SceneActor _actor3;
+ SceneActor _actor4;
+ SceneActor _actor5;
+ Guard _guard;
+ ASoundExt _sound1;
+ SequenceManager _sequenceManager;
+
+ Scene3100();
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+ virtual void remove();
+ virtual void signal();
+ virtual void dispatch();
+ virtual void synchronize(Serializer &s);
+};
+
+class Scene3125 : public SceneExt {
+ class Item1 : public NamedHotspot {
+ public:
+ virtual bool startAction(CursorType action, Event &event);
+ };
+ class Item2 : public Item1 {
+ public:
+ virtual bool startAction(CursorType action, Event &event);
+ };
+ class Item3 : public Item1 {
+ public:
+ virtual bool startAction(CursorType action, Event &event);
+ };
+
+ class Actor1 : public SceneActor {
+ virtual bool startAction(CursorType action, Event &event);
+ };
+public:
+
+ int _field412;
+ Item1 _item1;
+ Actor1 _actor1;
+ Item2 _item2;
+ Item3 _item3;
+ SceneActor _actor2;
+ SceneActor _actor3;
+ SceneActor _actor4;
+ SceneActor _actor5;
+ SequenceManager _sequenceManager1;
+ // Second sequence manager... Unused?
+ SequenceManager _sequenceManager2;
+
+ Scene3125();
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+ virtual void signal();
+ virtual void dispatch();
+ virtual void synchronize(Serializer &s);
+};
+
+class Scene3150 : public SceneExt {
+ class Item5 : public NamedHotspot {
+ public:
+ virtual bool startAction(CursorType action, Event &event);
+ };
+ class Item6 : public NamedHotspot {
+ public:
+ virtual bool startAction(CursorType action, Event &event);
+ };
+ class Actor4 : public SceneActor {
+ virtual bool startAction(CursorType action, Event &event);
+ };
+ class Actor5 : public SceneActor {
+ virtual bool startAction(CursorType action, Event &event);
+ };
+ class Actor6 : public SceneActor {
+ virtual bool startAction(CursorType action, Event &event);
+ };
+ class Actor7 : public SceneActor {
+ virtual bool startAction(CursorType action, Event &event);
+ };
+
+ class Exit1 : public SceneExit {
+ public:
+ virtual void changeScene();
+ };
+ class Exit2 : public SceneExit {
+ public:
+ virtual void changeScene();
+ };
+public:
+
+ NamedHotspot _item1;
+ NamedHotspot _item2;
+ NamedHotspot _item3;
+ NamedHotspot _item4;
+ Item5 _item5;
+ Item6 _item6;
+ SceneActor _actor1;
+ SceneActor _actor2;
+ SceneActor _actor3;
+ Actor4 _actor4;
+ Actor5 _actor5;
+ Actor6 _actor6;
+ Actor7 _actor7;
+ Exit1 _exit1;
+ Exit2 _exit2;
+ SequenceManager _sequenceManager;
+
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+ virtual void signal();
+ virtual void dispatch();
+};
+
+class Scene3175 : public SceneExt {
+ class Item1 : public NamedHotspot {
+ public:
+ virtual bool startAction(CursorType action, Event &event);
+ };
+
+ class Actor3 : public SceneActor {
+ virtual bool startAction(CursorType action, Event &event);
+ };
+ class Actor1 : public Actor3 {
+ virtual bool startAction(CursorType action, Event &event);
+ };
+public:
+
+ Item1 _item1;
+ Item1 _item2;
+ Item1 _item3;
+ Actor1 _actor1;
+ SceneActor _actor2;
+ Actor3 _actor3;
+ SequenceManager _sequenceManager;
+
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+ virtual void signal();
+};
+
+class Scene3200 : public SceneExt {
+public:
+ SpeakerRocko3200 _rockoSpeaker;
+ SpeakerJocko3200 _jockoSpeaker;
+ SpeakerSocko3200 _sockoSpeaker;
+ SceneActor _actor1;
+ SceneActor _actor2;
+ SceneActor _actor3;
+ SequenceManager _sequenceManager;
+
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+ virtual void signal();
+};
+
+class Scene3210 : public SceneExt {
+public:
+ SpeakerCaptain3210 _captainSpeaker;
+ SpeakerPrivate3210 _privateSpeaker;
+ SceneActor _actor1;
+ SceneActor _actor2;
+ SequenceManager _sequenceManager;
+
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+ virtual void signal();
+};
+
+class Scene3220 : public SceneExt {
+public:
+ SpeakerRocko3220 _rockoSpeaker;
+ SpeakerJocko3220 _jockoSpeaker;
+ SceneActor _actor1;
+ SceneActor _actor2;
+ SequenceManager _sequenceManager;
+
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+ virtual void signal();
+};
+
+class Scene3230 : public SceneExt {
+public:
+ SpeakerRocko3230 _rockoSpeaker;
+ SpeakerJocko3230 _jockoSpeaker;
+ SceneActor _actor1;
+ SceneActor _actor2;
+ SceneActor _actor3;
+ SequenceManager _sequenceManager;
+
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+ virtual void signal();
+};
+
+class Scene3240 : public SceneExt {
+public:
+ SpeakerTeal3240 _tealSpeaker;
+ SpeakerWebbster3240 _webbsterSpeaker;
+ SpeakerMiranda _mirandaSpeaker;
+ SceneActor _actor1;
+ SceneActor _actor2;
+ SequenceManager _sequenceManager;
+
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+ virtual void signal();
+};
+
+class Scene3245 : public SceneExt {
+public:
+ SpeakerRalf3245 _ralfSpeaker;
+ SpeakerTomko3245 _tomkoSpeaker;
+ SceneActor _actor1;
+ SceneActor _actor2;
+ SequenceManager _sequenceManager;
+
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+ virtual void signal();
+};
+
+class Scene3250 : public SceneExt {
+ class Item : public NamedHotspot {
+ public:
+ virtual bool startAction(CursorType action, Event &event);
+ };
+
+ class Actor : public SceneActor {
+ virtual bool startAction(CursorType action, Event &event);
+ };
+public:
+
+ Item _item1;
+ Item _item2;
+ Item _item3;
+ Item _item4;
+ Actor _actor1;
+ Actor _actor2;
+ Actor _actor3;
+ Actor _actor4;
+ SceneActor _actor5;
+ SceneActor _actor6;
+ SceneActor _actor7;
+ SequenceManager _sequenceManager;
+
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+ virtual void signal();
+ virtual void dispatch();
+};
+
+class Scene3255 : public SceneExt {
+public:
+ SceneActor _actor1;
+ SceneActor _actor2;
+ SceneActor _actor3;
+ SceneActor _actor4;
+ SceneActor _actor5;
+ SceneActor _actor6;
+ SceneActor _actor7;
+ SpeakerQuinn3255 _quinnSpeaker;
+ SpeakerMiranda3255 _mirandaSpeaker;
+ SequenceManager _sequenceManager;
+
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+ virtual void signal();
+ virtual void dispatch();
+};
+
+class Scene3260 : public SceneExt {
+ class Actor13 : public SceneActor {
+ virtual bool startAction(CursorType action, Event &event);
+ };
+ class Actor14 : public SceneActor {
+ virtual bool startAction(CursorType action, Event &event);
+ };
+
+ class Action1: public Action {
+ public:
+ void signal();
+ };
+public:
+
+ NamedHotspot _item1;
+ SceneActor _actor1;
+ SceneActor _actor2;
+ SceneActor _actor3;
+ SceneActor _actor4;
+ SceneActor _actor5;
+ SceneActor _actor6;
+ SceneActor _actor7;
+ SceneActor _actor8;
+ SceneActor _actor9;
+ SceneActor _actor10;
+ SceneActor _actor11;
+ SceneActor _actor12;
+ Actor13 _actor13;
+ Actor14 _actor14;
+ Action1 _action1;
+ Action1 _action2;
+ Action1 _action3;
+ Action1 _action4;
+ Action1 _action5;
+ Action1 _action6;
+ Action1 _action7;
+ Action1 _action8;
+ Action1 _action9;
+ Action1 _action10;
+ Action1 _action11;
+ Action1 _action12;
+ SequenceManager _sequenceManager;
+
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+ virtual void remove();
+ virtual void signal();
+};
+
+class Scene3275 : public SceneExt {
+ class Actor2 : public SceneActor {
+ virtual bool startAction(CursorType action, Event &event);
+ };
+
+ class Exit1 : public SceneExit {
+ public:
+ virtual void changeScene();
+ };
+public:
+ NamedHotspot _item1;
+ NamedHotspot _item2;
+ NamedHotspot _item3;
+ NamedHotspot _item4;
+ NamedHotspot _item5;
+ SceneActor _actor1;
+ Actor2 _actor2;
+ Exit1 _exit1;
+ SequenceManager _sequenceManager;
+
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+ virtual void signal();
+};
+
+class Scene3350 : public SceneExt {
+public:
+ SceneActor _actor1;
+ SceneActor _actor2;
+ SceneActor _actor3;
+ SceneActor _actor4;
+ SceneActor _actor5;
+ SceneActor _actor6;
+ SceneActor _actor7;
+ SceneActor _actor8;
+ SceneActor _actor9;
+ SequenceManager _sequenceManager;
+ PaletteRotation *_rotation;
+
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+ virtual void remove();
+ virtual void signal();
+};
+
+class Scene3375 : public SceneExt {
+ class Actor1 : public SceneActor {
+ virtual bool startAction(CursorType action, Event &event);
+ };
+ class Actor2 : public SceneActor {
+ virtual bool startAction(CursorType action, Event &event);
+ };
+ class Actor3 : public SceneActor {
+ virtual bool startAction(CursorType action, Event &event);
+ };
+ class Actor4 : public SceneActor {
+ virtual bool startAction(CursorType action, Event &event);
+ };
+
+ class Exit1 : public SceneExit {
+ public:
+ virtual void changeScene();
+ };
+ class Exit2 : public SceneExit {
+ public:
+ virtual void changeScene();
+ };
+ class Exit3 : public SceneExit {
+ public:
+ virtual void changeScene();
+ };
+
+ void signalCase3379();
+ void subFC696(int sceneMode);
+
+public:
+ SpeakerQuinn3375 _quinnSpeaker;
+ SpeakerSeeker3375 _seekerSpeaker;
+ SpeakerMiranda3375 _mirandaSpeaker;
+ SpeakerWebbster3375 _webbsterSpeaker;
+ NamedHotspot _item1;
+ NamedHotspot _itemArray[13];
+ Actor1 _actor1;
+ Actor2 _actor2;
+ Actor3 _actor3;
+ Actor4 _actor4;
+ Exit1 _exit1;
+ Exit2 _exit2;
+ Exit3 _exit3;
+ SequenceManager _sequenceManager;
+ int _field1488;
+ int _field148A[4];
+ int _field1492;
+
+ Scene3375();
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+ virtual void remove();
+ virtual void signal();
+ virtual void dispatch();
+ virtual void synchronize(Serializer &s);
+};
+
+class Scene3385 : public SceneExt {
+ class Actor1 : public SceneActor {
+ virtual bool startAction(CursorType action, Event &event);
+ };
+ class Actor2 : public SceneActor {
+ virtual bool startAction(CursorType action, Event &event);
+ };
+ class Actor3 : public SceneActor {
+ virtual bool startAction(CursorType action, Event &event);
+ };
+ class Actor4 : public SceneActor {
+ virtual bool startAction(CursorType action, Event &event);
+ };
+
+ class Exit1 : public SceneExit {
+ public:
+ virtual void changeScene();
+ };
+
+ class Action1: public Action {
+ public:
+ virtual void signal();
+ };
+
+public:
+ SpeakerQuinn3385 _quinnSpeaker;
+ SpeakerSeeker3385 _seekerSpeaker;
+ SpeakerMiranda3385 _mirandaSpeaker;
+ SpeakerWebbster3385 _webbsterSpeaker;
+ NamedHotspot _item1;
+ Actor1 _actor1;
+ Actor2 _actor2;
+ Actor3 _actor3;
+ Actor4 _actor4;
+ Exit1 _exit1;
+ Action1 _action1;
+ SequenceManager _sequenceManager;
+
+ int _field11B2;
+
+ Scene3385();
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+ virtual void remove();
+ virtual void signal();
+ virtual void synchronize(Serializer &s);
+};
+
+class Scene3395 : public SceneExt {
+ class Actor1 : public SceneActor {
+ virtual bool startAction(CursorType action, Event &event);
+ };
+ class Actor2 : public SceneActor {
+ virtual bool startAction(CursorType action, Event &event);
+ };
+ class Actor3 : public SceneActor {
+ virtual bool startAction(CursorType action, Event &event);
+ };
+ class Actor4 : public SceneActor {
+ virtual bool startAction(CursorType action, Event &event);
+ };
+
+ class Action1: public Action {
+ public:
+ virtual void signal();
+ };
+
+public:
+ SpeakerQuinn3395 _quinnSpeaker;
+ SpeakerSeeker3395 _seekerSpeaker;
+ SpeakerMiranda3395 _mirandaSpeaker;
+ SpeakerWebbster3395 _webbsterSpeaker;
+ NamedHotspot _item1;
+ NamedHotspot _itemArray[13];
+ Actor1 _actor1;
+ Actor2 _actor2;
+ Actor3 _actor3;
+ Actor4 _actor4;
+ Action1 _action1;
+ SequenceManager _sequenceManager;
+
+ int _field142E;
+
+ Scene3395();
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+ virtual void remove();
+ virtual void signal();
+ virtual void synchronize(Serializer &s);
+};
+
+class Scene3400 : public SceneExt {
+public:
+ SpeakerQuinn3400 _quinnSpeaker;
+ SpeakerSeeker3400 _seekerSpeaker;
+ SpeakerMiranda3400 _mirandaSpeaker;
+ SpeakerWebbster3400 _webbsterSpeaker;
+ SpeakerTeal3400 _tealSpeaker;
+ SceneActor _actor1;
+ SceneActor _actor2;
+ SceneActor _actor3;
+ SceneActor _actor4;
+ SceneActor _actor5;
+ SceneActor _actor6;
+ SceneActor _actor7;
+ SceneActor _actor8;
+ SequenceManager _sequenceManager;
+ int16 _field157C;
+
+ Scene3400();
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+ virtual void remove();
+ virtual void signal();
+ virtual void synchronize(Serializer &s);
+};
+
+class Scene3500 : public SceneExt {
+ class Action1: public Action {
+ public:
+ int _field1E;
+ int _field20;
+ int _field22;
+ int _field24;
+
+ Action1();
+ virtual void synchronize(Serializer &s);
+ void sub108670(int arg1);
+ void sub108732(int arg1);
+ virtual void signal();
+ virtual void dispatch();
+ };
+ class Action2: public Action {
+ public:
+ int _field1E;
+
+ Action2();
+ virtual void synchronize(Serializer &s);
+ void sub10831F(int arg1);
+
+ virtual void signal();
+ };
+
+ class Item4 : public NamedHotspot {
+ public:
+ int _field34;
+
+ Item4();
+ virtual void synchronize(Serializer &s);
+
+ virtual bool startAction(CursorType action, Event &event);
+ };
+
+ class Actor7 : public SceneActor {
+ public:
+ int _fieldA4;
+ int _fieldA6;
+ int _fieldA8;
+ int _fieldAA;
+ int _fieldAC;
+ int _fieldAE;
+
+ Actor7();
+ virtual void synchronize(Serializer &s);
+
+ void sub109466(int arg1, int arg2, int arg3, int arg4, int arg5);
+ void sub1094ED();
+ void sub109663(int arg1);
+ void sub109693(Common::Point Pt);
+
+ virtual void process(Event &event);
+ virtual bool startAction(CursorType action, Event &event);
+ };
+
+ class Actor8 : public SceneActor {
+ public:
+ // TODO: double check if nothing specific is present, then remove this class
+ };
+
+ class UnkObject3500 : public UnkObject1200 {
+ public:
+ int sub1097C9(int arg1);
+ int sub1097EF(int arg1);
+ int sub109C09(Common::Point pt);
+ int sub109C5E(int &x, int &y);
+ };
+public:
+ Action1 _action1;
+ Action2 _action2;
+ NamedHotspot _item1;
+ NamedHotspot _item2;
+ NamedHotspot _item3;
+ Item4 _item4;
+ Item4 _item5;
+ Item4 _item6;
+ Item4 _item7;
+ SceneActor _actor1;
+ SceneActor _actor2;
+ SceneActor _actor3;
+ SceneActor _actor4;
+ SceneActor _actor5;
+ SceneActor _actor6;
+ Actor7 _actor7;
+ Actor8 _actor8;
+ Actor8 _actor9;
+ ASoundExt _aSound1;
+ UnkObject3500 _unkObj1;
+ SequenceManager _sequenceManager;
+
+ int _fieldAF8;
+ int _fieldB9E;
+ PaletteRotation *_rotation;
+ int _field126E;
+ int _field1270;
+ int _field1272;
+ int _field1274;
+ int _field1276;
+ int _field1278;
+ int _field127A;
+ int _field127C;
+ int _field127E;
+ int _field1280;
+ int _field1282;
+ int _field1284;
+ int _field1286;
+
+ Scene3500();
+ void sub107F71(int arg1);
+
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+ virtual void remove();
+ virtual void signal();
+ virtual void process(Event &event);
+ virtual void dispatch();
+ virtual void synchronize(Serializer &s);
+};
+
+class Scene3600 : public SceneExt {
+ class Action3600: public ActionExt {
+ public:
+ int _field1E, _field20;
+
+ Action3600();
+ virtual void synchronize(Serializer &s);
+ virtual void signal();
+ };
+ class Action2: public Action {
+ public:
+ virtual void signal();
+ };
+
+ class Item5 : public NamedHotspot {
+ public:
+ virtual bool startAction(CursorType action, Event &event);
+ };
+
+ class Actor13 : public SceneActorExt {
+ virtual bool startAction(CursorType action, Event &event);
+ };
+public:
+ Action3600 _action1;
+ Action2 _action2;
+ SpeakerQuinn3600 _quinnSpeaker;
+ SpeakerSeeker3600 _seekerSpeaker;
+ SpeakerMiranda3600 _mirandaSpeaker;
+ SpeakerTeal3600 _tealSpeaker;
+ SpeakerProtector3600 _protectorSpeaker;
+ NamedHotspot _item1;
+ NamedHotspot _item2;
+ NamedHotspot _item3;
+ NamedHotspot _item4;
+ Item5 _item5;
+ SceneActor _actor1;
+ SceneActor _actor2;
+ SceneActor _actor3;
+ SceneActor _actor4;
+ SceneActor _actor5;
+ SceneActor _actor6;
+ SceneActor _actor7;
+ SceneActor _actor8;
+ SceneActor _actor9;
+ SceneActor _actor10;
+ SceneActor _actor11;
+ SceneActor _actor12;
+ Actor13 _actor13;
+ SequenceManager _sequenceManager1;
+ SequenceManager _sequenceManager2;
+ SequenceManager _sequenceManager3;
+ SequenceManager _sequenceManager4;
+ ScenePalette _palette1;
+
+ int _field2548;
+ int _field254A;
+ int _field254C;
+ int _field254E;
+ bool _field2550;
+
+ Scene3600();
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+ virtual void remove();
+ virtual void signal();
+ virtual void process(Event &event);
+ virtual void dispatch();
+ virtual void synchronize(Serializer &s);
+};
+
+class Scene3700 : public SceneExt {
+public:
+ SpeakerQuinn3700 _quinnSpeaker;
+ SpeakerSeeker3700 _seekerSpeaker;
+ SpeakerMiranda3700 _mirandaSpeaker;
+ SceneActor _actor1;
+ SceneActor _actor2;
+ SceneActor _actor3;
+ SceneActor _actor4;
+ SceneActor _actor5;
+ SequenceManager _sequenceManager;
+
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+ virtual void remove();
+ virtual void signal();
+};
+
+class Scene3800 : public SceneExt {
+ class Exit1 : public SceneExit {
+ public:
+ virtual void changeScene();
+ };
+
+ class Exit2 : public SceneExit {
+ public:
+ virtual void changeScene();
+ };
+
+ class Exit3 : public SceneExit {
+ public:
+ virtual void changeScene();
+ };
+
+ class Exit4 : public SceneExit {
+ public:
+ virtual void changeScene();
+ };
+
+public:
+ SceneObject _object1;
+ SceneObject _object2;
+ SceneActor _actor1;
+ NamedHotspot _item1;
+ Exit1 _exit1;
+ Exit2 _exit2;
+ Exit3 _exit3;
+ Exit4 _exit4;
+ Rect _rect1;
+ SequenceManager _sequenceManager1;
+
+ int _field412;
+
+ Scene3800();
+ void initScene3800();
+ void sub110BBD();
+
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+ virtual void signal();
+ virtual void process(Event &event);
+ virtual void synchronize(Serializer &s);
+};
+
+class Scene3900 : public SceneExt {
+ class Exit1 : public SceneExit {
+ public:
+ virtual void changeScene();
+ };
+
+ class Exit2 : public SceneExit {
+ public:
+ virtual void changeScene();
+ };
+
+ class Exit3 : public SceneExit {
+ public:
+ virtual void changeScene();
+ };
+
+ class Exit4 : public SceneExit {
+ public:
+ virtual void changeScene();
+ };
+
+ class Exit5 : public SceneExit {
+ public:
+ virtual void changeScene();
+ };
+public:
+ SceneActor _actor1;
+ NamedHotspot _item1;
+ Exit1 _exit1;
+ Exit2 _exit2;
+ Exit3 _exit3;
+ Exit4 _exit4;
+ Exit5 _exit5;
+ Rect _rect1;
+
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+ virtual void signal();
+ virtual void process(Event &event);
+};
+
+} // End of namespace Ringworld2
+} // End of namespace TsAGE
+
+#endif
diff --git a/engines/tsage/ringworld2/ringworld2_speakers.cpp b/engines/tsage/ringworld2/ringworld2_speakers.cpp
new file mode 100644
index 0000000000..da1449efdf
--- /dev/null
+++ b/engines/tsage/ringworld2/ringworld2_speakers.cpp
@@ -0,0 +1,2968 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "tsage/ringworld2/ringworld2_speakers.h"
+#include "tsage/scenes.h"
+#include "tsage/tsage.h"
+#include "tsage/graphics.h"
+#include "tsage/staticres.h"
+#include "tsage/ringworld2/ringworld2_scenes0.h"
+#include "tsage/ringworld2/ringworld2_scenes1.h"
+#include "tsage/ringworld2/ringworld2_scenes2.h"
+#include "tsage/ringworld2/ringworld2_scenes3.h"
+
+namespace TsAGE {
+
+namespace Ringworld2 {
+
+VisualSpeaker::VisualSpeaker(): Speaker() {
+ _delayAmount = 0;
+ _frameNumber = R2_GLOBALS._events.getFrameNumber();
+ _color1 = 8;
+ _color2 = 0;
+ _displayMode = 0;
+ _fieldF6 = 0;
+}
+
+void VisualSpeaker::remove() {
+ if (_object2) {
+ if (_fieldF8) {
+ _fieldF8 = 0;
+ _object1.setStrip(_object1._strip - 1);
+ _object1.setFrame(_object1.getFrameCount());
+ _object1.animate(ANIM_MODE_6, (_fieldF6 == 0xff) ? this : NULL);
+ } else {
+ _object1.animate(ANIM_MODE_6, (_fieldF6 == 0xff) ? this : NULL);
+ }
+ }
+
+ Speaker::remove();
+}
+
+void VisualSpeaker::synchronize(Serializer &s) {
+ Speaker::synchronize(s);
+
+ SYNC_POINTER(_object2);
+ s.syncAsSint16LE(_fieldF6);
+ s.syncAsSint16LE(_fieldF8);
+ s.syncAsSint16LE(_displayMode);
+ s.syncAsSint16LE(_soundId);
+ s.syncAsSint16LE(_delayAmount);
+ s.syncAsByte(_removeObject);
+ s.syncAsSint32LE(_frameNumber);
+ s.syncAsSint16LE(_numFrames);
+}
+
+void VisualSpeaker::setText(const Common::String &msg) {
+ _sceneText.remove();
+
+ // Position the text depending on the specified display mode
+ switch (_displayMode) {
+ case 2:
+ _textPos = Common::Point(60, 20);
+ break;
+ case 3:
+ _textPos = Common::Point(110, 20);
+ break;
+ case 4:
+ _textPos = Common::Point(10, 100);
+ break;
+ case 5:
+ _textPos = Common::Point(60, 100);
+ break;
+ case 6:
+ _textPos = Common::Point(110, 100);
+ break;
+ case 7:
+ _textPos = Common::Point(170, 20);
+ break;
+ case 8:
+ _textPos = Common::Point(170, 100);
+ break;
+ case 9:
+ _textPos = Common::Point(330, 20);
+ break;
+ default:
+ _textPos = Common::Point(10, 20);
+ break;
+ }
+
+ // Check if the message starts with a '!'. If so, it indicates a speech resource Id to be played,
+ // in which case extract the resource number from the message.
+ _soundId = 0;
+ Common::String s = msg;
+ if (s.hasPrefix("!")) {
+ s.deleteChar(0);
+ _soundId = atoi(s.c_str());
+
+ while (!s.empty() && (*s.c_str() >= '0' && *s.c_str() <= '9'))
+ s.deleteChar(0);
+ }
+
+ // Set up the text details
+ _sceneText._color1 = _color1;
+ _sceneText._color2 = _color2;
+ _sceneText._color3 = _color3;
+ _sceneText._width = _textWidth;
+ _sceneText._fontNumber = _fontNumber;
+ _sceneText._textMode = _textMode;
+ _sceneText.setup(s);
+
+ //_sceneText.clone();
+
+ _sceneText.setPosition(_textPos);
+ _sceneText.fixPriority(256);
+
+ // If subtitles are turned off, don't show the text
+ if (!(R2_GLOBALS._speechSubtitles & SPEECH_TEXT)) {
+ _sceneText.hide();
+ }
+
+ // Figure out the text delay if subtitles are turned on, or there's no speech resource specified
+ if ((R2_GLOBALS._speechSubtitles & SPEECH_TEXT) || !_soundId) {
+ const char *msgP = s.c_str();
+ int numWords = 0;
+ while (*msgP != '\0') {
+ if (*msgP++ == ' ')
+ ++numWords;
+ }
+
+ if (!numWords && !s.empty())
+ ++numWords;
+
+ _numFrames = numWords * 30 + 120;
+ setDelay(_numFrames);
+ } else {
+ _numFrames = 1;
+ }
+
+ // If the text is empty, no delay is needed
+ if (s.empty())
+ _numFrames = 0;
+
+
+ if (_fieldF6) {
+ if ((R2_GLOBALS._speechSubtitles & SPEECH_TEXT) || !_soundId)
+ _sceneText.hide();
+ } else {
+ if ((R2_GLOBALS._speechSubtitles & SPEECH_VOICE) && _soundId) {
+ if (!R2_GLOBALS._playStream.play(_soundId, NULL))
+ _sceneText.show();
+ }
+ }
+}
+
+void VisualSpeaker::proc16() {
+ R2_GLOBALS._playStream.stop();
+ _fieldF6 = 0;
+ _object1.remove();
+
+ assert(_object2);
+ _object2->show();
+ _object2 = NULL;
+ _fieldF8 = 0;
+}
+
+void VisualSpeaker::setFrame(int numFrames) {
+ _delayAmount = numFrames;
+ _frameNumber = R2_GLOBALS._events.getFrameNumber();
+}
+
+void VisualSpeaker::setDelay(int delay) {
+ _delayAmount = delay;
+ _frameNumber = R2_GLOBALS._events.getFrameNumber();
+}
+
+//----------------------------------------------------------------------------
+
+SpeakerGameText::SpeakerGameText(): VisualSpeaker() {
+ _speakerName = "GAMETEXT";
+ _color1 = 8;
+ _color2 = 0;
+ _textWidth = 300;
+ _hideObjects = false;
+ _object2 = NULL;
+}
+
+//----------------------------------------------------------------------------
+// Classes related to CAPTAIN
+//----------------------------------------------------------------------------
+
+SpeakerCaptain3210::SpeakerCaptain3210() {
+ _speakerName = "Captain";
+ _color1 = 5;
+ _color2 = 0;
+ _fieldF6 = 0;
+ _textWidth = 300;
+ _hideObjects = false;
+ _object2 = NULL;
+ _displayMode = 1;
+ _numFrames = 0;
+}
+
+void SpeakerCaptain3210::proc15() {
+ int v = _fieldF6;
+ Scene3210 *scene = (Scene3210 *)R2_GLOBALS._sceneManager._scene;
+
+ if (!_object2) {
+ _object2 = &scene->_actor1;
+ _object2->hide();
+ _object1.postInit();
+ _object1.setPosition(_object2->_position);
+
+ if (_object2->_mover)
+ _object2->addMover(NULL);
+ }
+
+ if (v == 0) {
+ _object1.animate(ANIM_MODE_2, NULL);
+ } else {
+ ((SceneItem *)_action)->_sceneRegionId = 0;
+ _object1.setup(4060, (_object2->_strip * 2) - 1, 1);
+ _object1.animate(ANIM_MODE_5, this);
+ }
+}
+
+//----------------------------------------------------------------------------
+// Classes related to CARETAKER
+//----------------------------------------------------------------------------
+
+SpeakerCaretaker2450::SpeakerCaretaker2450() {
+ _speakerName = "CARETAKER";
+ _color1 = 43;
+ _color2 = 0;
+ _fieldF6 = 0;
+ _textWidth = 300;
+ _hideObjects = false;
+ _object2 = NULL;
+ _displayMode = 1;
+ _numFrames = 0;
+}
+
+//----------------------------------------------------------------------------
+// Classes related to CHIEF
+//----------------------------------------------------------------------------
+
+SpeakerChief1100::SpeakerChief1100() {
+ _speakerName = "CHIEF";
+ _color1 = 8;
+ _color2 = 0;
+ _fieldF6 = 0;
+ _textWidth = 300;
+ _hideObjects = false;
+ _object2 = NULL;
+ _displayMode = 1;
+ _numFrames = 0;
+}
+
+void SpeakerChief1100::proc15() {
+ int v = _fieldF6;
+ Scene1100 *scene = (Scene1100 *)R2_GLOBALS._sceneManager._scene;
+
+ if (!_object2) {
+ _object2 = &scene->_actor18;
+ _object2->hide();
+ _object1.postInit();
+ _object1.setPosition(_object2->_position);
+ _object1._numFrames = 7;
+
+ if (_object2->_mover)
+ _object2->addMover(NULL);
+ }
+
+ switch (v) {
+ case 0:
+ _object1.animate(ANIM_MODE_2, NULL);
+ break;
+ case 1:
+ ((SceneItem *)_action)->_sceneRegionId = 0;
+ _object1.setup(4080, 1, 1);
+ _object1.animate(ANIM_MODE_5, this);
+ break;
+ case 2:
+ ((SceneItem *)_action)->_sceneRegionId = 0;
+ _object1.setup(4080, 3, 1);
+ _object1.animate(ANIM_MODE_5, this);
+ break;
+ case 100:
+ _numFrames = 0;
+ ((SceneItem *)_action)->_sceneRegionId = 0;
+ _object1.setStrip(_object1._strip - 1);
+ _object1.setFrame(_object1.getFrameCount());
+ _object1.animate(ANIM_MODE_6, this);
+ break;
+ default:
+ signal();
+ break;
+ }
+}
+
+//----------------------------------------------------------------------------
+// Classes related to GUARD
+//----------------------------------------------------------------------------
+
+SpeakerGuard::SpeakerGuard() {
+ _speakerName = "GUARD";
+ _color1 = 5;
+ _color2 = 0;
+ _fieldF6 = 0;
+ _textWidth = 300;
+ _hideObjects = false;
+ _object2 = NULL;
+ _displayMode = 1;
+ _numFrames = 0;
+}
+
+void SpeakerGuard2800::proc15() {
+ int v = _fieldF6;
+ Scene2750 *scene = (Scene2750 *)R2_GLOBALS._sceneManager._scene;
+
+ if (!_object2) {
+ _object2 = &scene->_actor1;
+ _object2->hide();
+ _object1.postInit();
+ _object1.setPosition(_object2->_position);
+
+ if (_object2->_mover)
+ _object2->addMover(NULL);
+ }
+
+ if (v == 0) {
+ _object1.animate(ANIM_MODE_2, NULL);
+ } else {
+ ((SceneItem *)_action)->_sceneRegionId = 0;
+ _object1.setZoom(75);
+ _object1.setup(4060, 3, 1);
+ _object1.animate(ANIM_MODE_5, this);
+ }
+}
+
+//----------------------------------------------------------------------------
+// Classes related to JOCKO
+//----------------------------------------------------------------------------
+
+SpeakerJocko::SpeakerJocko() {
+ _speakerName = "Jocko";
+ _color1 = 45;
+ _color2 = 0;
+ _fieldF6 = 0;
+ _textWidth = 300;
+ _hideObjects = false;
+ _object2 = NULL;
+ _displayMode = 1;
+ _numFrames = 0;
+}
+
+void SpeakerJocko3200::proc15() {
+ int v = _fieldF6;
+ Scene3200 *scene = (Scene3200 *)R2_GLOBALS._sceneManager._scene;
+
+ if (!_object2) {
+ _object2 = &scene->_actor2;
+ _object2->hide();
+ _object1.postInit();
+ _object1.setPosition(_object2->_position);
+
+ if (_object2->_mover)
+ _object2->addMover(NULL);
+ }
+
+ if (v == 0) {
+ _object1.animate(ANIM_MODE_2, NULL);
+ } else {
+ ((SceneItem *)_action)->_sceneRegionId = 0;
+ _object1.setup(4060, (_object2->_strip * 2) - 1, 1);
+ _object1.animate(ANIM_MODE_5, this);
+ }
+}
+
+void SpeakerJocko3220::proc15() {
+ int v = _fieldF6;
+ Scene3220 *scene = (Scene3220 *)R2_GLOBALS._sceneManager._scene;
+
+ if (!_object2) {
+ _object2 = &scene->_actor2;
+ _object2->hide();
+ _object1.postInit();
+ _object1.setPosition(_object2->_position);
+
+ if (_object2->_mover)
+ _object2->addMover(NULL);
+ }
+
+ if (v == 0) {
+ _object1.animate(ANIM_MODE_2, NULL);
+ } else {
+ ((SceneItem *)_action)->_sceneRegionId = 0;
+ _object1.setup(4060, (_object2->_strip * 2) - 1, 1);
+ _object1.animate(ANIM_MODE_5, this);
+ }
+}
+
+void SpeakerJocko3230::proc15() {
+ int v = _fieldF6;
+ Scene3230 *scene = (Scene3230 *)R2_GLOBALS._sceneManager._scene;
+
+ if (!_object2) {
+ _object2 = &scene->_actor2;
+ _object2->hide();
+ _object1.postInit();
+ _object1.setPosition(_object2->_position);
+
+ if (_object2->_mover)
+ _object2->addMover(NULL);
+ }
+
+ if (v == 0) {
+ _object1.animate(ANIM_MODE_2, NULL);
+ } else {
+ ((SceneItem *)_action)->_sceneRegionId = 0;
+ _object1.setup(4060, (_object2->_strip * 2) - 1, 1);
+ _object1.animate(ANIM_MODE_5, this);
+ }
+}
+
+//----------------------------------------------------------------------------
+// Classes related to MIRANDA
+//----------------------------------------------------------------------------
+
+SpeakerMiranda::SpeakerMiranda(): VisualSpeaker() {
+ _speakerName = "MIRANDA";
+ _color1 = 154;
+ _color2 = 0;
+ _fieldF6 = 0;
+ _textWidth = 300;
+ _hideObjects = false;
+ _object2 = NULL;
+ _displayMode = 1;
+ _numFrames = 0;
+}
+
+void SpeakerMiranda300::proc15() {
+ int v = _fieldF6;
+
+ if (!_object2) {
+ if (R2_GLOBALS._player._characterIndex == 3) {
+ _object2 = &R2_GLOBALS._player;
+ } else {
+ Scene300 *scene = (Scene300 *)R2_GLOBALS._sceneManager._scene;
+ _object2 = &scene->_miranda;
+ }
+
+ _object2->hide();
+ _object1.postInit();
+ _object1.setPosition(_object2->_position);
+
+ if (_object2->_mover)
+ _object2->addMover(NULL);
+ }
+
+ if (v == 0) {
+ _object1.animate(ANIM_MODE_2, NULL);
+ } else if (v == 100) {
+ _numFrames = 0;
+ ((SceneItem *)_action)->_sceneRegionId = 0;
+
+ _object1.setStrip(_object1._strip - 1);
+ _object1.setFrame(_object1.getFrameCount());
+ _object1.animate(ANIM_MODE_6, this);
+ } else {
+ ((SceneItem *)_action)->_sceneRegionId = 0;
+
+ if (v == 4) {
+ _object1.setup(304, 5, 1);
+ } else {
+ _object1.setup(305, v * 2 - 1, 1);
+ }
+ _object1.animate(ANIM_MODE_5, this);
+ }
+}
+
+void SpeakerMiranda1625::proc15() {
+ int v = _fieldF6;
+
+ if (!_object2) {
+ Scene1625 *scene = (Scene1625 *)R2_GLOBALS._sceneManager._scene;
+ _object2 = &scene->_actor3;
+ _object2->hide();
+ _object1.postInit();
+ _object1.setPosition(Common::Point(196, 65));
+
+ if (_object2->_mover)
+ _object2->addMover(NULL);
+ }
+
+ if (v == 0) {
+ _object1.animate(ANIM_MODE_2, NULL);
+ } else {
+ ((SceneItem *)_action)->_sceneRegionId = 0;
+ _object1.setup(1627, 3, 1);
+ _object1.animate(ANIM_MODE_5, this);
+ }
+}
+
+void SpeakerMiranda3255::proc15() {
+ int v = _fieldF6;
+
+ if (!_object2) {
+ _object2 = &R2_GLOBALS._player;
+ _object2->hide();
+ _object1.postInit();
+ _object1._effect = _object2->_effect;
+ _object1._shade = _object2->_shade;
+ _object1.setPosition(_object2->_position);
+ }
+
+ if (v == 0) {
+ _object1.animate(ANIM_MODE_2, NULL);
+ } else {
+ ((SceneItem *)_action)->_sceneRegionId = 0;
+ _object1.setup(3257, 5, 1);
+ _object1.animate(ANIM_MODE_5, this);
+ }
+}
+
+void SpeakerMiranda3375::proc15() {
+ Scene3375 *scene = (Scene3375 *)R2_GLOBALS._sceneManager._scene;
+
+ int v = _fieldF6;
+
+ if (!_object2) {
+ if (R2_GLOBALS._player._characterIndex == 3)
+ _object2 = &R2_GLOBALS._player;
+ else
+ _object2 = &scene->_actor2;
+
+ _object2->hide();
+ _object1.postInit();
+ _object1.setPosition(_object2->_position);
+ _object1._numFrames = 7;
+ _object1._effect = 1;
+ _object1.changeZoom(-1);
+
+ if (scene->_actor1._position.y != 163)
+ R2_GLOBALS._player.setStrip(8);
+ else
+ R2_GLOBALS._player.setStrip(2);
+
+ R2_GLOBALS._player.disableControl();
+
+ if (R2_GLOBALS._player._mover)
+ R2_GLOBALS._player.addMover(NULL);
+
+ R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
+
+ if (_object2->_mover)
+ _object2->addMover(NULL);
+ }
+
+
+ switch (v) {
+ case 0:
+ _object1.animate(ANIM_MODE_2, NULL);
+ break;
+ case 1:
+ ((SceneItem *)_action)->_sceneRegionId = 0;
+ _object1.setup(4051, 5, 1);
+ _object1.animate(ANIM_MODE_5, this);
+ break;
+ default:
+ signal();
+ break;
+ }
+}
+
+void SpeakerMiranda3385::proc15() {
+ Scene3385 *scene = (Scene3385 *)R2_GLOBALS._sceneManager._scene;
+
+ int v = _fieldF6;
+
+ if (!_object2) {
+ if (R2_GLOBALS._player._characterIndex == 3)
+ _object2 = &R2_GLOBALS._player;
+ else
+ _object2 = &scene->_actor2;
+
+ _object2->hide();
+ _object1.postInit();
+ _object1.setPosition(_object2->_position);
+ _object1._numFrames = 7;
+ _object1._effect = 1;
+ _object1.changeZoom(-1);
+
+ if (R2_GLOBALS._sceneManager._previousScene == 3375)
+ R2_GLOBALS._player.setStrip(4);
+ else
+ R2_GLOBALS._player.setStrip(3);
+
+ if (R2_GLOBALS._player._mover)
+ R2_GLOBALS._player.addMover(NULL);
+
+ R2_GLOBALS._player.disableControl(CURSOR_TALK);
+ R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
+
+ if (_object2->_mover)
+ _object2->addMover(NULL);
+ }
+
+
+ switch (v) {
+ case 0:
+ _object1.animate(ANIM_MODE_2, NULL);
+ break;
+ case 1:
+ ((SceneItem *)_action)->_sceneRegionId = 0;
+ _object1.setup(4051, 5, 1);
+ _object1.animate(ANIM_MODE_5, this);
+ break;
+ default:
+ signal();
+ break;
+ }
+}
+
+void SpeakerMiranda3395::proc15() {
+ Scene3395 *scene = (Scene3395 *)R2_GLOBALS._sceneManager._scene;
+
+ int v = _fieldF6;
+
+ if (!_object2) {
+ if (R2_GLOBALS._player._characterIndex == 3)
+ _object2 = &R2_GLOBALS._player;
+ else
+ _object2 = &scene->_actor2;
+
+ _object2->hide();
+ _object1.postInit();
+ _object1.setPosition(_object2->_position);
+ _object1._numFrames = 7;
+ _object1._effect = 1;
+ _object1.changeZoom(-1);
+
+ if (R2_GLOBALS._sceneManager._previousScene == 3385)
+ R2_GLOBALS._player.setStrip(4);
+ else
+ R2_GLOBALS._player.setStrip(3);
+
+ R2_GLOBALS._player.disableControl(CURSOR_TALK);
+
+ if (R2_GLOBALS._player._mover)
+ R2_GLOBALS._player.addMover(NULL);
+
+ R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
+
+ if (_object2->_mover)
+ _object2->addMover(NULL);
+ }
+
+
+ switch (v) {
+ case 0:
+ _object1.animate(ANIM_MODE_2, NULL);
+ break;
+ case 1:
+ ((SceneItem *)_action)->_sceneRegionId = 0;
+ _object1.setup(4051, 5, 1);
+ _object1.animate(ANIM_MODE_5, this);
+ break;
+ default:
+ signal();
+ break;
+ }
+}
+
+void SpeakerMiranda3400::proc15() {
+ Scene3400 *scene = (Scene3400 *)R2_GLOBALS._sceneManager._scene;
+
+ int v = _fieldF6;
+
+ if (!_object2) {
+ if (R2_GLOBALS._player._characterIndex == 3)
+ _object2 = &R2_GLOBALS._player;
+ else
+ _object2 = &scene->_actor2;
+
+ _object2->hide();
+ _object1.postInit();
+ _object1.setPosition(_object2->_position);
+ _object1._numFrames = 7;
+ _object1._effect = 1;
+ _object1.changeZoom(-1);
+ R2_GLOBALS._player.disableControl();
+ R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
+
+ if (_object2->_mover)
+ _object2->addMover(NULL);
+ }
+
+ switch (v) {
+ case 0:
+ _object1.animate(ANIM_MODE_2, NULL);
+ break;
+ case 1:
+ ((SceneItem *)_action)->_sceneRegionId = 0;
+ _object1.setup(4051, 5, 1);
+ _object1.animate(ANIM_MODE_5, NULL);
+ break;
+ case 2:
+ ((SceneItem *)_action)->_sceneRegionId = 0;
+ _object1.setup(4050, 3, 1);
+ _object1.animate(ANIM_MODE_5, NULL);
+ break;
+ default:
+ signal();
+ break;
+ }
+}
+
+void SpeakerMiranda3600::proc15() {
+ Scene3600 *scene = (Scene3600 *)R2_GLOBALS._sceneManager._scene;
+
+ int v = _fieldF6;
+
+ if (!_object2) {
+ if (R2_GLOBALS._player._characterIndex == 3)
+ _object2 = &R2_GLOBALS._player;
+ else
+ _object2 = &scene->_actor12;
+
+ _object2->hide();
+ _object1.postInit();
+ _object1.setPosition(_object2->_position);
+ _object1._numFrames = 7;
+ _object1._effect = 1;
+ _object1.changeZoom(-1);
+ R2_GLOBALS._player.disableControl();
+ R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
+
+ if (_object2->_mover)
+ _object2->addMover(NULL);
+
+ _object1.setPosition(_object2->_position);
+ }
+
+ switch (v) {
+ case 0:
+ _object1.animate(ANIM_MODE_2, NULL);
+ break;
+ case 1:
+ ((SceneItem *)_action)->_sceneRegionId = 0;
+ _object1.setup(4051, 1, 1);
+ _object1.animate(ANIM_MODE_5, this);
+ break;
+ case 2:
+ ((SceneItem *)_action)->_sceneRegionId = 0;
+ _object1.setup(4050, 1, 1);
+ _object1.animate(ANIM_MODE_5, this);
+ break;
+ default:
+ signal();
+ break;
+ }
+}
+
+void SpeakerMiranda3700::proc15() {
+ Scene3700 *scene = (Scene3700 *)R2_GLOBALS._sceneManager._scene;
+
+ int v = _fieldF6;
+
+ if (!_object2) {
+ _object2 = &scene->_actor3;
+ _object2->hide();
+ _object1.postInit();
+ _object1.setPosition(_object2->_position);
+ _object1._numFrames = 7;
+ R2_GLOBALS._player.disableControl();
+ R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
+
+ if (_object2->_mover)
+ _object2->addMover(NULL);
+ }
+
+ _object1.setPosition(_object2->_position);
+
+ switch (v) {
+ case 0:
+ _object1.animate(ANIM_MODE_2, NULL);
+ break;
+ case 1:
+ ((SceneItem *)_action)->_sceneRegionId = 0;
+ scene->_actor1.setup(10, 6, 1);
+ scene->_actor2.setup(20, 5, 1);
+ _object2->setup(30, 1, 1);
+ scene->_actor4.setup(40, 1, 1);
+ _object1.setup(4050, 5, 1);
+ _object1.animate(ANIM_MODE_5, NULL);
+ break;
+ case 2:
+ ((SceneItem *)_action)->_sceneRegionId = 0;
+ scene->_actor3.setup(30, 8, 1);
+ _object1.setup(4052, 3, 1);
+ _object1.animate(ANIM_MODE_5, NULL);
+ break;
+ case 3:
+ ((SceneItem *)_action)->_sceneRegionId = 0;
+ scene->_actor2.setup(20, 1, 1);
+ scene->_actor3.setup(30, 1, 1);
+ _object1.setup(4051, 7, 1);
+ _object1.animate(ANIM_MODE_5, NULL);
+ break;
+ default:
+ signal();
+ break;
+ }
+}
+
+//----------------------------------------------------------------------------
+// Classes related to NEJ
+//----------------------------------------------------------------------------
+
+SpeakerNej::SpeakerNej() {
+ _speakerName = "NEJ";
+ _color1 = 171;
+ _color2 = 0;
+ _fieldF6 = 0;
+ _textWidth = 300;
+ _hideObjects = false;
+ _object2 = NULL;
+ _displayMode = 1;
+ _numFrames = 0;
+}
+
+void SpeakerNej2700::proc15() {
+ int v = _fieldF6;
+ Scene2700 *scene = (Scene2700 *)R2_GLOBALS._sceneManager._scene;
+
+ if (!_object2) {
+ _object2 = &scene->_actor1;
+ _object2->hide();
+ _object1.postInit();
+ _object1.setPosition(_object2->_position);
+
+ if (_object2->_mover)
+ _object2->addMover(NULL);
+ }
+
+ if (v == 0) {
+ _object1.animate(ANIM_MODE_2, NULL);
+ } else {
+ ((SceneItem *)_action)->_sceneRegionId = 0;
+ switch (_object2->_visage) {
+ case 2701:
+ _object1.setup(4022, 3, 1);
+ _object1.setPosition(Common::Point(164, 163));
+ _object2->setPosition(Common::Point(-10, -10));
+ break;
+ case 2705:
+ _object1.setup(4022, 7, 1);
+ _object1.fixPriority(162);
+ break;
+ default:
+ break;
+ }
+ _object1.animate(ANIM_MODE_5, this);
+ }
+}
+
+void SpeakerNej2750::proc15() {
+ int v = _fieldF6;
+ Scene2750 *scene = (Scene2750 *)R2_GLOBALS._sceneManager._scene;
+
+ if (!_object2) {
+ _object2 = &scene->_actor1;
+ _object2->hide();
+ _object1.postInit();
+ _object1.setPosition(_object2->_position);
+
+ if (_object2->_mover)
+ _object2->addMover(NULL);
+ }
+
+ if (v == 0) {
+ _object1.animate(ANIM_MODE_2, NULL);
+ } else {
+ ((SceneItem *)_action)->_sceneRegionId = 0;
+ switch (_object2->_visage) {
+ case 2705:
+ _object1.setup(4022, 7, 1);
+ break;
+ case 2752:
+ _object1.setup(2752, 1, 1);
+ break;
+ default:
+ break;
+ }
+ _object1.animate(ANIM_MODE_5, this);
+ }
+}
+
+void SpeakerNej2800::proc15() {
+ int v = _fieldF6;
+ Scene2750 *scene = (Scene2750 *)R2_GLOBALS._sceneManager._scene;
+
+ if (!_object2) {
+ _object2 = &scene->_actor2;
+ _object2->hide();
+ _object1.postInit();
+ _object1.setPosition(_object2->_position);
+
+ if (_object2->_mover)
+ _object2->addMover(NULL);
+ }
+
+ if (v == 0) {
+ _object1.animate(ANIM_MODE_2, NULL);
+ } else {
+ ((SceneItem *)_action)->_sceneRegionId = 0;
+ _object1.setup(4023, 3, 1);
+ if (_object2->_visage == 2801)
+ _object1.setPosition(Common::Point(R2_GLOBALS._player._position.x - 12, R2_GLOBALS._player._position.y));
+ _object1.animate(ANIM_MODE_5, this);
+ }
+}
+
+//----------------------------------------------------------------------------
+// Classes related to PHARISHA
+//----------------------------------------------------------------------------
+
+SpeakerPharisha::SpeakerPharisha(): VisualSpeaker() {
+ _speakerName = "PHARISHA";
+ _color1 = 151;
+ _color2 = 0;
+ _fieldF6 = 0;
+ _textWidth = 300;
+ _hideObjects = false;
+ _object2 = NULL;
+ _displayMode = 1;
+ _numFrames = 0;
+}
+
+void SpeakerPharisha2435::proc15() {
+ int v = _fieldF6;
+ Scene2435 *scene = (Scene2435 *)R2_GLOBALS._sceneManager._scene;
+
+ if (!_object2) {
+ _object2 = &scene->_actor2;
+ _object2->hide();
+ _object1.postInit();
+ _object1.setPosition(_object2->_position);
+ }
+
+ if (v == 0) {
+ _object1.animate(ANIM_MODE_2, NULL);
+ } else {
+ ((SceneItem *)_action)->_sceneRegionId = 0;
+ _object1.setup(4098, 5, 1);
+ _object1.animate(ANIM_MODE_5, this);
+ }
+}
+
+//----------------------------------------------------------------------------
+// Classes related to PRIVATE
+//----------------------------------------------------------------------------
+
+SpeakerPrivate3210::SpeakerPrivate3210() {
+ _speakerName = "Private";
+ _color1 = 45;
+ _color2 = 0;
+ _fieldF6 = 0;
+ _textWidth = 300;
+ _hideObjects = false;
+ _object2 = NULL;
+ _displayMode = 1;
+ _numFrames = 0;
+}
+
+void SpeakerPrivate3210::proc15() {
+ int v = _fieldF6;
+ Scene3210 *scene = (Scene3210 *)R2_GLOBALS._sceneManager._scene;
+
+ if (!_object2) {
+ _object2 = &scene->_actor2;
+ _object2->hide();
+ _object1.postInit();
+ _object1.setPosition(_object2->_position);
+
+ if (_object2->_mover)
+ _object2->addMover(NULL);
+ }
+
+ if (v == 0) {
+ _object1.animate(ANIM_MODE_2, NULL);
+ } else {
+ ((SceneItem *)_action)->_sceneRegionId = 0;
+ _object1.setup(4060, (_object2->_strip * 2) - 1, 1);
+ _object1.animate(ANIM_MODE_5, this);
+ }
+}
+
+//----------------------------------------------------------------------------
+// Classes related to PROTECTOR
+//----------------------------------------------------------------------------
+
+SpeakerProtector3600::SpeakerProtector3600() {
+ _speakerName = "Protector";
+ _color1 = 170;
+ _color2 = 0;
+ _fieldF6 = 0;
+ _textWidth = 300;
+ _hideObjects = false;
+ _object2 = NULL;
+ _displayMode = 7;
+ _numFrames = 0;
+}
+
+void SpeakerProtector3600::proc15() {
+ int v = _fieldF6;
+ Scene3600 *scene = (Scene3600 *)R2_GLOBALS._sceneManager._scene;
+
+ if (!_object2) {
+ _object2 = &scene->_actor13;
+ _object2->hide();
+ _object1.postInit();
+ _object1.setPosition(_object2->_position);
+ _object1._numFrames = 7;
+ _object1._effect = 1;
+ _object1.changeZoom(-1);
+
+ R2_GLOBALS._player.disableControl();
+ R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
+
+ if (_object2->_mover)
+ _object2->addMover(NULL);
+ }
+
+ _object1.setPosition(_object2->_position);
+
+ switch (v) {
+ case 0:
+ _object1.animate(ANIM_MODE_2, NULL);
+ break;
+ case 1:
+ ((SceneItem *)_action)->_sceneRegionId = 0;
+ if (scene->_sceneMode != 3324) {
+ _object1.setup(4125, 3, 1);
+ _object1.animate(ANIM_MODE_5, this);
+ } else {
+ _object1.setup(3258, 6, 1);
+ _object1.animate(ANIM_MODE_2, NULL);
+ _object1.hide();
+ _object2->setup(3258, 6, 1);
+ _object2->show();
+ }
+ break;
+ default:
+ signal();
+ break;
+ }
+}
+
+//----------------------------------------------------------------------------
+// Classes related to QUINN
+//----------------------------------------------------------------------------
+
+SpeakerQuinn::SpeakerQuinn(): VisualSpeaker() {
+ _speakerName = "QUINN";
+ _color1 = 60;
+ _color2 = 0;
+ _fieldF6 = 0;
+ _textWidth = 300;
+ _hideObjects = false;
+ _object2 = NULL;
+ _displayMode = 1;
+ _numFrames = 0;
+}
+
+void SpeakerQuinn300::proc15() {
+ int v = _fieldF6;
+
+ if (!_object2) {
+ if (R2_GLOBALS._player._characterIndex == 3) {
+ _object2 = &R2_GLOBALS._player;
+ } else {
+ Scene300 *scene = (Scene300 *)R2_GLOBALS._sceneManager._scene;
+ _object2 = &scene->_quinn;
+ }
+
+ _object2->hide();
+ _object1.postInit();
+ _object1.setPosition(_object2->_position);
+
+ if (_object2->_mover)
+ _object2->addMover(NULL);
+ }
+
+ if (v == 0) {
+ _object1.animate(ANIM_MODE_2, NULL);
+ } else if (v == 100) {
+ _numFrames = 0;
+ ((SceneItem *)_action)->_sceneRegionId = 0;
+
+ _object1.setStrip(_object1._strip - 1);
+ _object1.setFrame(_object1.getFrameCount());
+ _object1.animate(ANIM_MODE_6, this);
+ } else {
+ ((SceneItem *)_action)->_sceneRegionId = 0;
+
+ switch (_object2->_visage) {
+ case 10:
+ _object1.setup((v - 1) / 4 + 4010, ((v - ((v - 1) / 4 * 4) - 1) % 8) * 2 + 1, 1);
+ break;
+ case 302:
+ _object1.setup(308, (v - 1) % 8 + 1, 1);
+ break;
+ case 308:
+ _object1.setup(308, 5, 1);
+ break;
+ }
+
+ _object1.animate(ANIM_MODE_5, this);
+ }
+}
+
+void SpeakerQuinn1100::proc15() {
+ int v = _fieldF6;
+
+ if (!_object2) {
+ if (v == 0)
+ return;
+
+ if (R2_GLOBALS._player._characterIndex == 1) {
+ _object2 = &R2_GLOBALS._player;
+ } else {
+ Scene1100 *scene = (Scene1100 *)R2_GLOBALS._sceneManager._scene;
+ _object2 = &scene->_actor16;
+ }
+
+ _object2->hide();
+ _object1.postInit();
+ _object1.setPosition(_object2->_position);
+ _object1._numFrames = 7;
+
+ if (_object2->_mover)
+ _object2->addMover(NULL);
+ }
+
+ switch (v) {
+ case 0:
+ _object1.animate(ANIM_MODE_2, NULL);
+ break;
+ case 1:
+ ((SceneItem *)_action)->_sceneRegionId = 0;
+ _object1.setup(1108, 7, 1);
+ _object1.animate(ANIM_MODE_5, this);
+ break;
+ case 2:
+ ((SceneItem *)_action)->_sceneRegionId = 0;
+ _object1.setup(1109, 1, 1);
+ _object1.animate(ANIM_MODE_5, this);
+ break;
+ case 3:
+ ((SceneItem *)_action)->_sceneRegionId = 0;
+ _object1.setup(1109, 5, 1);
+ _object1.animate(ANIM_MODE_5, this);
+ break;
+ default:
+ signal();
+ break;
+ }
+}
+
+void SpeakerQuinn2435::proc15() {
+ int v = _fieldF6;
+
+ if (!_object2) {
+ if (R2_GLOBALS._player._characterIndex == 1) {
+ _object2 = &R2_GLOBALS._player;
+ } else {
+ Scene2435 *scene = (Scene2435 *)R2_GLOBALS._sceneManager._scene;
+ _object2 = &scene->_actor1;
+ }
+
+ _object2->hide();
+ _object1.postInit();
+ _object1.setPosition(_object2->_position);
+ }
+
+ if (v == 0) {
+ _object1.animate(ANIM_MODE_2, NULL);
+ } else {
+ ((SceneItem *)_action)->_sceneRegionId = 0;
+ _object2->setStrip(7);
+ _object1.setup(2020, 5, 1);
+ _object1.animate(ANIM_MODE_5, this);
+ }
+}
+
+void SpeakerQuinn2450::proc15() {
+ int v = _fieldF6;
+
+ if (!_object2) {
+ if (R2_GLOBALS._player._characterIndex == 1) {
+ _object2 = &R2_GLOBALS._player;
+ } else {
+ Scene2435 *scene = (Scene2435 *)R2_GLOBALS._sceneManager._scene;
+ _object2 = &scene->_actor1;
+ }
+
+ _object2->hide();
+ _object1.postInit();
+ _object1.setPosition(_object2->_position);
+ }
+
+ if (v == 0) {
+ _object1.animate(ANIM_MODE_2, NULL);
+ } else {
+ ((SceneItem *)_action)->_sceneRegionId = 0;
+ if (R2_GLOBALS.getFlag(61))
+ _object1.setup(2020, 3, 1);
+ else
+ _object1.setup(2020, 1, 1);
+ _object1.animate(ANIM_MODE_5, this);
+ }
+}
+
+void SpeakerQuinn2700::proc15() {
+ int v = _fieldF6;
+
+ if (!_object2) {
+ _object2 = &R2_GLOBALS._player;
+ _object2->hide();
+ _object1.postInit();
+ _object1.setPosition(_object2->_position);
+
+ if (_object2->_mover)
+ _object2->addMover(NULL);
+ }
+
+ if (v == 0) {
+ _object1.animate(ANIM_MODE_2, NULL);
+ } else {
+ ((SceneItem *)_action)->_sceneRegionId = 0;
+ switch (_object2->_visage) {
+ case 19:
+ _object1.setup(4022, 5, 1);
+ break;
+ case 2701:
+ _object1.setup(4022, 1, 1);
+ break;
+ default:
+ break;
+ }
+ _object1.animate(ANIM_MODE_5, this);
+ }
+}
+
+void SpeakerQuinn2750::proc15() {
+ int v = _fieldF6;
+
+ if (!_object2) {
+ _object2 = &R2_GLOBALS._player;
+ _object2->hide();
+ _object1.postInit();
+ _object1.setPosition(_object2->_position);
+
+ if (_object2->_mover)
+ _object2->addMover(NULL);
+ }
+
+ if (v == 0) {
+ _object1.animate(ANIM_MODE_2, NULL);
+ } else {
+ ((SceneItem *)_action)->_sceneRegionId = 0;
+ switch (_object2->_visage) {
+ case 19:
+ _object1.setup(4022, 5, 1);
+ break;
+ case 2752:
+ _object1.setup(2752, 1, 1);
+ break;
+ default:
+ break;
+ }
+ _object1.animate(ANIM_MODE_5, this);
+ }
+}
+
+void SpeakerQuinn2800::proc15() {
+ int v = _fieldF6;
+
+ if (!_object2) {
+ _object2 = &R2_GLOBALS._player;
+ _object2->hide();
+ _object1.postInit();
+ _object1.setPosition(_object2->_position);
+
+ if (_object2->_mover)
+ _object2->addMover(NULL);
+ }
+
+ if (v == 0) {
+ _object1.animate(ANIM_MODE_2, NULL);
+ } else {
+ ((SceneItem *)_action)->_sceneRegionId = 0;
+ switch (_object2->_visage) {
+ case 16:
+ _object1.setZoom(75);
+ _object1.setup(4023, 5, 1);
+ break;
+ case 19:
+ _object1.setup(4023, 1, 1);
+ break;
+ case 3110:
+ _object1.setZoom(75);
+ if (_object2->_strip == 1)
+ _object1.setup(4061 , 1, 1);
+ else
+ _object1.setup(4061 , 3, 1);
+ break;
+ default:
+ break;
+ }
+ _object1.animate(ANIM_MODE_5, this);
+ }
+}
+
+void SpeakerQuinn3255::proc15() {
+ Scene3255 *scene = (Scene3255 *)R2_GLOBALS._sceneManager._scene;
+
+ int v = _fieldF6;
+
+ if (!_object2) {
+ _object2 = &scene->_actor4;
+ _object2->hide();
+ _object1.postInit();
+ _object1._effect = _object2->_effect;
+ _object1._shade = _object2->_shade;
+ _object1.setPosition(_object2->_position);
+ }
+
+ if (v == 0) {
+ _object1.animate(ANIM_MODE_2, NULL);
+ } else {
+ ((SceneItem *)_action)->_sceneRegionId = 0;
+ _object1.setup(3257, 3, 1);
+ _object1.animate(ANIM_MODE_5, this);
+ }
+}
+
+void SpeakerQuinn3375::proc15() {
+ Scene3375 *scene = (Scene3375 *)R2_GLOBALS._sceneManager._scene;
+
+ int v = _fieldF6;
+
+ if (!_object2) {
+ if (R2_GLOBALS._player._characterIndex == 1)
+ _object2 = &R2_GLOBALS._player;
+ else if (R2_GLOBALS._player._characterIndex == 2)
+ _object2 = &scene->_actor1;
+ else
+ _object2 = &scene->_actor2;
+
+ _object2->hide();
+ _object1.postInit();
+ _object1.setPosition(_object2->_position);
+ _object1._numFrames = 7;
+ _object1._effect = 1;
+ _object1.changeZoom(-1);
+
+ if (scene->_actor1._position.y != 163)
+ R2_GLOBALS._player.setStrip(8);
+ else
+ R2_GLOBALS._player.setStrip(2);
+
+ if (R2_GLOBALS._player._mover)
+ R2_GLOBALS._player.addMover(NULL);
+
+ R2_GLOBALS._player.disableControl(CURSOR_TALK);
+ R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
+
+ if (_object2->_mover)
+ _object2->addMover(NULL);
+ }
+
+
+ switch (v) {
+ case 0:
+ _object1.animate(ANIM_MODE_2, NULL);
+ break;
+ case 1:
+ ((SceneItem *)_action)->_sceneRegionId = 0;
+ _object1.setup(4010, 5, 1);
+ _object1.animate(ANIM_MODE_5, this);
+ break;
+ default:
+ signal();
+ break;
+ }
+}
+
+void SpeakerQuinn3385::proc15() {
+ Scene3385 *scene = (Scene3385 *)R2_GLOBALS._sceneManager._scene;
+
+ int v = _fieldF6;
+
+ if (!_object2) {
+ if (R2_GLOBALS._player._characterIndex == 1)
+ _object2 = &R2_GLOBALS._player;
+ else if (R2_GLOBALS._player._characterIndex == 2)
+ _object2 = &scene->_actor1;
+ else
+ _object2 = &scene->_actor2;
+
+ _object2->hide();
+ _object1.postInit();
+ _object1.setPosition(_object2->_position);
+ _object1._numFrames = 7;
+ _object1._effect = 1;
+ _object1.changeZoom(-1);
+
+ if (R2_GLOBALS._sceneManager._previousScene == 3375)
+ R2_GLOBALS._player.setStrip(4);
+ else
+ R2_GLOBALS._player.setStrip(3);
+
+ if (R2_GLOBALS._player._mover)
+ R2_GLOBALS._player.addMover(NULL);
+
+ R2_GLOBALS._player.disableControl(CURSOR_TALK);
+ R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
+
+ if (_object2->_mover)
+ _object2->addMover(NULL);
+ }
+
+
+ switch (v) {
+ case 0:
+ _object1.animate(ANIM_MODE_2, NULL);
+ break;
+ case 1:
+ ((SceneItem *)_action)->_sceneRegionId = 0;
+ if (R2_GLOBALS._player._characterIndex == 2)
+ _object1.setup(4010, 3, 1);
+ else
+ _object1.setup(4010, 5, 1);
+
+ _object1.animate(ANIM_MODE_5, this);
+ break;
+ default:
+ signal();
+ break;
+ }
+}
+
+void SpeakerQuinn3395::proc15() {
+ Scene3395 *scene = (Scene3395 *)R2_GLOBALS._sceneManager._scene;
+
+ int v = _fieldF6;
+
+ if (!_object2) {
+ if (R2_GLOBALS._player._characterIndex == 1)
+ _object2 = &R2_GLOBALS._player;
+ else if (R2_GLOBALS._player._characterIndex == 2)
+ _object2 = &scene->_actor1;
+ else
+ _object2 = &scene->_actor2;
+
+ _object2->hide();
+ _object1.postInit();
+ _object1.setPosition(_object2->_position);
+ _object1._numFrames = 7;
+ _object1._effect = 1;
+ _object1.changeZoom(-1);
+
+ if (R2_GLOBALS._sceneManager._previousScene == 3385)
+ R2_GLOBALS._player.setStrip(4);
+ else
+ R2_GLOBALS._player.setStrip(3);
+
+ if (R2_GLOBALS._player._mover)
+ R2_GLOBALS._player.addMover(NULL);
+
+ R2_GLOBALS._player.disableControl(CURSOR_TALK);
+ R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
+
+ if (_object2->_mover)
+ _object2->addMover(NULL);
+ }
+
+
+ switch (v) {
+ case 0:
+ _object1.animate(ANIM_MODE_2, NULL);
+ break;
+ case 1:
+ ((SceneItem *)_action)->_sceneRegionId = 0;
+ if (R2_GLOBALS._player._characterIndex == 2)
+ _object1.setup(4010, 3, 1);
+ else
+ _object1.setup(4010, 5, 1);
+
+ _object1.animate(ANIM_MODE_5, this);
+ break;
+ default:
+ signal();
+ break;
+ }
+}
+
+void SpeakerQuinn3400::proc15() {
+ Scene3400 *scene = (Scene3400 *)R2_GLOBALS._sceneManager._scene;
+
+ int v = _fieldF6;
+
+ if (!_object2) {
+ if (R2_GLOBALS._player._characterIndex == 1)
+ _object2 = &R2_GLOBALS._player;
+ else if (R2_GLOBALS._player._characterIndex == 2)
+ _object2 = &scene->_actor1;
+ else
+ _object2 = &scene->_actor2;
+
+ _object2->hide();
+ _object1.postInit();
+ _object1.setPosition(_object2->_position);
+ _object1._numFrames = 7;
+ _object1._effect = 1;
+ _object1.changeZoom(-1);
+ R2_GLOBALS._player.disableControl();
+ if (_object2->_mover)
+ _object2->addMover(NULL);
+ }
+
+ switch (v) {
+ case 0:
+ _object1.animate(ANIM_MODE_2, NULL);
+ break;
+ case 1:
+ ((SceneItem *)_action)->_sceneRegionId = 0;
+ _object1.setup(4010, 5, 1);
+ _object1.animate(ANIM_MODE_5, NULL);
+ break;
+ case 2:
+ ((SceneItem *)_action)->_sceneRegionId = 0;
+ _object1.setup(4010, 3, 1);
+ _object1.animate(ANIM_MODE_5, NULL);
+ break;
+ case 3:
+ ((SceneItem *)_action)->_sceneRegionId = 0;
+ _object1.setup(4012, 3, 1);
+ _object1.animate(ANIM_MODE_5, NULL);
+ break;
+ default:
+ signal();
+ break;
+ }
+}
+
+void SpeakerQuinn3600::proc15() {
+ Scene3600 *scene = (Scene3600 *)R2_GLOBALS._sceneManager._scene;
+
+ int v = _fieldF6;
+
+ if (!_object2) {
+ if (R2_GLOBALS._player._characterIndex == 1)
+ _object2 = &R2_GLOBALS._player;
+ else
+ _object2 = &scene->_actor10;
+ _object2->hide();
+ _object1.postInit();
+ _object1.setPosition(_object2->_position);
+ _object1._numFrames = 7;
+ _object1._effect = 1;
+ _object1.changeZoom(-1);
+ R2_GLOBALS._player.disableControl();
+ R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
+
+ if (_object2->_mover)
+ _object2->addMover(NULL);
+ }
+
+ switch (v) {
+ case 0:
+ _object1.animate(ANIM_MODE_2, NULL);
+ break;
+ case 1:
+ ((SceneItem *)_action)->_sceneRegionId = 0;
+ _object1.setup(4021, 7, 1);
+ _object1.animate(ANIM_MODE_5, this);
+ break;
+ case 2:
+ ((SceneItem *)_action)->_sceneRegionId = 0;
+ _object1.setup(4010, 1, 1);
+ _object1.animate(ANIM_MODE_5, this);
+ break;
+ case 3:
+ ((SceneItem *)_action)->_sceneRegionId = 0;
+ _object1.setup(4012, 1, 1);
+ _object1.animate(ANIM_MODE_5, this);
+ break;
+ default:
+ signal();
+ break;
+ }
+}
+
+void SpeakerQuinn3700::setText(const Common::String &msg) {
+ Scene3700 *scene = (Scene3700 *)R2_GLOBALS._sceneManager._scene;
+
+ switch (_fieldF6) {
+ case 2:
+ scene->_actor3.setup(30, 1, 1);
+ R2_GLOBALS._sound2.play(44);
+ break;
+ case 3:
+ scene->_actor3.setup(30, 1, 1);
+ break;
+ default:
+ scene->_actor3.setup(30, 7, 1);
+ break;
+ }
+ VisualSpeaker::setText(msg);
+}
+
+void SpeakerQuinn3700::proc15() {
+ Scene3700 *scene = (Scene3700 *)R2_GLOBALS._sceneManager._scene;
+
+ int v = _fieldF6;
+
+ if (!_object2) {
+ _object2 = &scene->_actor1;
+ _object2->hide();
+ _object1.postInit();
+ _object1.setPosition(_object2->_position);
+ _object1._numFrames = 7;
+ R2_GLOBALS._player.disableControl();
+ R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
+
+ if (_object2->_mover)
+ _object2->addMover(NULL);
+ }
+
+ _object1.setPosition(_object2->_position);
+
+ switch (v) {
+ case 0:
+ _object1.animate(ANIM_MODE_2, NULL);
+ break;
+ case 1:
+ ((SceneItem *)_action)->_sceneRegionId = 0;
+ R2_GLOBALS._sound2.stop();
+ scene->_actor1.setup(10, 4, 1);
+ scene->_actor3.setup(30, 7, 1);
+ _object1.setup(3701, 1, 1);
+ _object1.animate(ANIM_MODE_5, NULL);
+ break;
+ case 2:
+ ((SceneItem *)_action)->_sceneRegionId = 0;
+ scene->_actor2.setup(20, 1, 1);
+ scene->_actor3.setup(30, 1, 1);
+ _object1.setup(3701, 2, 1);
+ _object1.animate(ANIM_MODE_5, NULL);
+ break;
+ case 3:
+ ((SceneItem *)_action)->_sceneRegionId = 0;
+ scene->_actor1.setup(10, 2, 1);
+ scene->_actor3.setup(30, 1, 1);
+ _object1.setup(4011, 1, 1);
+ _object1.animate(ANIM_MODE_5, NULL);
+ break;
+ default:
+ signal();
+ break;
+ }
+}
+
+//----------------------------------------------------------------------------
+// Classes related to QUINNL
+//----------------------------------------------------------------------------
+
+SpeakerQuinnL::SpeakerQuinnL(): VisualSpeaker() {
+ _speakerName = "QUINNL";
+ _color1 = 35;
+ _color2 = 0;
+ _fieldF6 = 0;
+ _textWidth = 300;
+ _hideObjects = false;
+ _object2 = NULL;
+ _displayMode = 1;
+ _numFrames = 0;
+ _fontNumber = 10;
+}
+
+//----------------------------------------------------------------------------
+// Classes related to RALF
+//----------------------------------------------------------------------------
+
+SpeakerRalf3245::SpeakerRalf3245() {
+ _speakerName = "Ralf";
+ _color1 = 5;
+ _color2 = 0;
+ _fieldF6 = 0;
+ _textWidth = 300;
+ _hideObjects = false;
+ _object2 = NULL;
+ _displayMode = 1;
+ _numFrames = 0;
+}
+
+void SpeakerRalf3245::proc15() {
+ int v = _fieldF6;
+ Scene3245 *scene = (Scene3245 *)R2_GLOBALS._sceneManager._scene;
+
+ if (!_object2) {
+ _object2 = &scene->_actor1;
+ _object2->hide();
+ _object1.postInit();
+ _object1.setPosition(_object2->_position);
+
+ if (_object2->_mover)
+ _object2->addMover(NULL);
+ }
+
+ if (v == 0) {
+ _object1.animate(ANIM_MODE_2, NULL);
+ } else {
+ ((SceneItem *)_action)->_sceneRegionId = 0;
+ switch (_object2->_visage) {
+ case 3100:
+ _object1.setup(4105, (_object2->_strip * 2) - 1, 1);
+ break;
+ case 3101:
+ _object1.setup(4108, (_object2->_strip * 2) - 1, 1);
+ break;
+ case 3102:
+ _object1.setup(4109, (_object2->_strip * 2) - 1, 1);
+ break;
+ default:
+ break;
+ }
+
+ _object1.animate(ANIM_MODE_5, this);
+ }
+}
+
+//----------------------------------------------------------------------------
+// Classes related to ROCKO
+//----------------------------------------------------------------------------
+
+SpeakerRocko::SpeakerRocko() {
+ _speakerName = "Rocko";
+ _color1 = 5;
+ _color2 = 0;
+ _fieldF6 = 0;
+ _textWidth = 300;
+ _hideObjects = false;
+ _object2 = NULL;
+ _displayMode = 1;
+ _numFrames = 0;
+}
+
+void SpeakerRocko3200::proc15() {
+ int v = _fieldF6;
+ Scene3200 *scene = (Scene3200 *)R2_GLOBALS._sceneManager._scene;
+
+ if (!_object2) {
+ _object2 = &scene->_actor1;
+ _object2->hide();
+ _object1.postInit();
+ _object1.setPosition(_object2->_position);
+
+ if (_object2->_mover)
+ _object2->addMover(NULL);
+ }
+
+ if (v == 0) {
+ _object1.animate(ANIM_MODE_2, NULL);
+ } else {
+ ((SceneItem *)_action)->_sceneRegionId = 0;
+ _object1.setup(4060, (_object2->_strip * 2) - 1, 1);
+ _object1.animate(ANIM_MODE_5, this);
+ }
+}
+
+void SpeakerRocko3220::proc15() {
+ int v = _fieldF6;
+ Scene3220 *scene = (Scene3220 *)R2_GLOBALS._sceneManager._scene;
+
+ if (!_object2) {
+ _object2 = &scene->_actor1;
+ _object2->hide();
+ _object1.postInit();
+ _object1.setPosition(_object2->_position);
+
+ if (_object2->_mover)
+ _object2->addMover(NULL);
+ }
+
+ if (v == 0) {
+ _object1.animate(ANIM_MODE_2, NULL);
+ } else {
+ ((SceneItem *)_action)->_sceneRegionId = 0;
+ _object1.setup(4060, (_object2->_strip * 2) - 1, 1);
+ _object1.animate(ANIM_MODE_5, this);
+ }
+}
+
+void SpeakerRocko3230::proc15() {
+ int v = _fieldF6;
+ Scene3230 *scene = (Scene3230 *)R2_GLOBALS._sceneManager._scene;
+
+ if (!_object2) {
+ _object2 = &scene->_actor1;
+ _object2->hide();
+ _object1.postInit();
+ _object1.setPosition(_object2->_position);
+
+ if (_object2->_mover)
+ _object2->addMover(NULL);
+ }
+
+ if (v == 0) {
+ _object1.animate(ANIM_MODE_2, NULL);
+ } else {
+ ((SceneItem *)_action)->_sceneRegionId = 0;
+ _object1.setup(4111, (_object2->_strip * 2) - 1, 1);
+ _object1.animate(ANIM_MODE_5, this);
+ }
+}
+
+//----------------------------------------------------------------------------
+// Classes related to SEEKER
+//----------------------------------------------------------------------------
+
+SpeakerSeeker::SpeakerSeeker(): VisualSpeaker() {
+ _speakerName = "SEEKER";
+ _color1 = 35;
+ _color2 = 0;
+ _fieldF6 = 0;
+ _textWidth = 300;
+ _hideObjects = false;
+ _object2 = NULL;
+ _displayMode = 1;
+ _numFrames = 0;
+}
+
+void SpeakerSeeker300::proc15() {
+ int v = _fieldF6;
+
+ if (!_object2) {
+ if (R2_GLOBALS._player._characterIndex == 3) {
+ _object2 = &R2_GLOBALS._player;
+ } else {
+ Scene300 *scene = (Scene300 *)R2_GLOBALS._sceneManager._scene;
+ _object2 = &scene->_seeker;
+ }
+
+ _object2->hide();
+ _object1.postInit();
+ _object1.fixPriority(140);
+ _object1.setPosition(_object2->_position);
+
+ if (_object2->_mover)
+ _object2->addMover(NULL);
+ }
+
+ if (v == 0) {
+ _object1.animate(ANIM_MODE_2, NULL);
+ } else if (v == 100) {
+ _numFrames = 0;
+ ((SceneItem *)_action)->_sceneRegionId = 0;
+
+ _object1.setStrip(_object1._strip - 1);
+ _object1.setFrame(_object1.getFrameCount());
+ _object1.animate(ANIM_MODE_6, this);
+ } else {
+ ((SceneItem *)_action)->_sceneRegionId = 0;
+ _object1.setup(306, v * 2 - 1, 1);
+ _object1.animate(ANIM_MODE_5, this);
+ }
+}
+
+void SpeakerSeeker1100::proc15() {
+ int v = _fieldF6;
+
+ if (!_object2) {
+ if (v == 0)
+ return;
+
+ if (R2_GLOBALS._player._characterIndex == 2) {
+ _object2 = &R2_GLOBALS._player;
+ } else {
+ Scene1100 *scene = (Scene1100 *)R2_GLOBALS._sceneManager._scene;
+ _object2 = &scene->_actor16;
+ }
+
+ _object2->hide();
+ _object1.postInit();
+ _object1.setPosition(_object2->_position);
+ _object1._numFrames = 7;
+
+ if (_object2->_mover)
+ _object2->addMover(NULL);
+ }
+
+ switch (v) {
+ case 0:
+ _object1.animate(ANIM_MODE_2, NULL);
+ break;
+ case 1:
+ ((SceneItem *)_action)->_sceneRegionId = 0;
+ _object1.setup(1108, 1, 1);
+ _object1.animate(ANIM_MODE_5, this);
+ break;
+ case 2:
+ ((SceneItem *)_action)->_sceneRegionId = 0;
+ _object1.setup(1108, 3, 1);
+ _object1.animate(ANIM_MODE_5, this);
+ break;
+ case 3:
+ _object1.setPosition(Common::Point(197, 134));
+ ((SceneItem *)_action)->_sceneRegionId = 0;
+ _object1.setup(1108, 5, 1);
+ _object1.animate(ANIM_MODE_5, this);
+ break;
+ case 4:
+ ((SceneItem *)_action)->_sceneRegionId = 0;
+ _object1.setup(1109, 7, 1);
+ _object1.animate(ANIM_MODE_5, this);
+ break;
+ case 5:
+ ((SceneItem *)_action)->_sceneRegionId = 0;
+ _object1.setup(1109, 3, 1);
+ _object1.animate(ANIM_MODE_5, this);
+ break;
+ default:
+ signal();
+ break;
+ }
+}
+
+void SpeakerSeeker1900::proc15() {
+ int v = _fieldF6;
+
+ if (!_object2) {
+ if (R2_GLOBALS._player._characterIndex == 2) {
+ _object2 = &R2_GLOBALS._player;
+ } else {
+ Scene1900 *scene = (Scene1900 *)R2_GLOBALS._sceneManager._scene;
+ _object2 = &scene->_actor1;
+ }
+
+ _object2->hide();
+ _object1.postInit();
+ _object1.setPosition(_object2->_position);
+ _object1._numFrames = 7;
+
+ if (_object2->_mover)
+ _object2->addMover(NULL);
+ }
+
+ if (v == 0) {
+ _object1.animate(ANIM_MODE_2, NULL);
+ } else if (v == 1) {
+ _object1.setup(4032, 1, 1);
+ _object1.animate(ANIM_MODE_5, this);
+ } else {
+ signal();
+ }
+}
+
+void SpeakerSeeker2435::proc15() {
+ int v = _fieldF6;
+
+ if (!_object2) {
+ if (R2_GLOBALS._player._characterIndex == 2) {
+ _object2 = &R2_GLOBALS._player;
+ } else {
+ Scene2435 *scene = (Scene2435 *)R2_GLOBALS._sceneManager._scene;
+ _object2 = &scene->_actor1;
+ }
+
+ _object2->hide();
+ _object1.postInit();
+ _object1.setPosition(_object2->_position);
+ }
+
+ if (v == 0) {
+ _object1.animate(ANIM_MODE_2, NULL);
+ } else {
+ ((SceneItem *)_action)->_sceneRegionId = 0;
+ _object2->setStrip(7);
+ _object1.setup(4099, 1, 1);
+ _object1.animate(ANIM_MODE_5, this);
+ }
+}
+
+void SpeakerSeeker2450::proc15() {
+ int v = _fieldF6;
+
+ if (!_object2) {
+ if (R2_GLOBALS._player._characterIndex == 2) {
+ _object2 = &R2_GLOBALS._player;
+ } else {
+ Scene2450 *scene = (Scene2450 *)R2_GLOBALS._sceneManager._scene;
+ _object2 = &scene->_actor1;
+ }
+
+ _object2->hide();
+ _object1.postInit();
+ _object1.setPosition(_object2->_position);
+ }
+
+ if (v == 0) {
+ _object1.animate(ANIM_MODE_2, NULL);
+ } else {
+ ((SceneItem *)_action)->_sceneRegionId = 0;
+ _object1.setup(4099, 3, 1);
+ _object1.animate(ANIM_MODE_5, this);
+ }
+}
+
+void SpeakerSeeker3375::proc15() {
+ Scene3375 *scene = (Scene3375 *)R2_GLOBALS._sceneManager._scene;
+
+ int v = _fieldF6;
+
+ if (!_object2) {
+ if (R2_GLOBALS._player._characterIndex == 2)
+ _object2 = &R2_GLOBALS._player;
+ else
+ _object2 = &scene->_actor1;
+
+ _object2->hide();
+ _object1.postInit();
+ _object1.setPosition(_object2->_position);
+ _object1._numFrames = 7;
+ _object1._effect = 1;
+ _object1.changeZoom(-1);
+
+ if (scene->_actor1._position.y != 163)
+ R2_GLOBALS._player.setStrip(8);
+ else
+ R2_GLOBALS._player.setStrip(2);
+
+ if (R2_GLOBALS._player._mover)
+ R2_GLOBALS._player.addMover(NULL);
+
+ R2_GLOBALS._player.disableControl(CURSOR_TALK);
+ R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
+
+ if (_object2->_mover)
+ _object2->addMover(NULL);
+ }
+
+
+ switch (v) {
+ case 0:
+ _object1.animate(ANIM_MODE_2, NULL);
+ break;
+ case 1:
+ ((SceneItem *)_action)->_sceneRegionId = 0;
+ _object1.setup(4031, 1, 1);
+ _object1.animate(ANIM_MODE_5, this);
+ break;
+ default:
+ signal();
+ break;
+ }
+}
+
+void SpeakerSeeker3385::proc15() {
+ Scene3385 *scene = (Scene3385 *)R2_GLOBALS._sceneManager._scene;
+
+ int v = _fieldF6;
+
+ if (!_object2) {
+ if (R2_GLOBALS._player._characterIndex == 2)
+ _object2 = &R2_GLOBALS._player;
+ else
+ _object2 = &scene->_actor1;
+
+ _object2->hide();
+ _object1.postInit();
+ _object1.setPosition(_object2->_position);
+ _object1._numFrames = 7;
+ _object1._effect = 1;
+ _object1.changeZoom(-1);
+
+ if (R2_GLOBALS._sceneManager._previousScene == 3375)
+ R2_GLOBALS._player.setStrip(4);
+ else
+ R2_GLOBALS._player.setStrip(3);
+
+ if (R2_GLOBALS._player._mover)
+ R2_GLOBALS._player.addMover(NULL);
+
+ R2_GLOBALS._player.disableControl(CURSOR_TALK);
+ R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
+
+ if (_object2->_mover)
+ _object2->addMover(NULL);
+ }
+
+
+ switch (v) {
+ case 0:
+ _object1.animate(ANIM_MODE_2, NULL);
+ break;
+ case 1:
+ ((SceneItem *)_action)->_sceneRegionId = 0;
+ _object1.setup(4031, 3, 1);
+ _object1.animate(ANIM_MODE_5, this);
+ break;
+ default:
+ signal();
+ break;
+ }
+}
+
+void SpeakerSeeker3395::proc15() {
+ Scene3395 *scene = (Scene3395 *)R2_GLOBALS._sceneManager._scene;
+
+ int v = _fieldF6;
+
+ if (!_object2) {
+ if (R2_GLOBALS._player._characterIndex == 2)
+ _object2 = &R2_GLOBALS._player;
+ else
+ _object2 = &scene->_actor1;
+
+ _object2->hide();
+ _object1.postInit();
+ _object1.setPosition(_object2->_position);
+ _object1._numFrames = 7;
+ _object1._effect = 1;
+ _object1.changeZoom(-1);
+
+ if (R2_GLOBALS._sceneManager._previousScene == 3385)
+ R2_GLOBALS._player.setStrip(4);
+ else
+ R2_GLOBALS._player.setStrip(3);
+
+ if (R2_GLOBALS._player._mover)
+ R2_GLOBALS._player.addMover(NULL);
+
+ R2_GLOBALS._player.disableControl(CURSOR_TALK);
+ R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
+
+ if (_object2->_mover)
+ _object2->addMover(NULL);
+ }
+
+
+ switch (v) {
+ case 0:
+ _object1.animate(ANIM_MODE_2, NULL);
+ break;
+ case 1:
+ ((SceneItem *)_action)->_sceneRegionId = 0;
+ _object1.setup(4031, 3, 1);
+ _object1.animate(ANIM_MODE_5, this);
+ break;
+ default:
+ signal();
+ break;
+ }
+}
+
+void SpeakerSeeker3400::proc15() {
+ Scene3400 *scene = (Scene3400 *)R2_GLOBALS._sceneManager._scene;
+
+ int v = _fieldF6;
+
+ if (!_object2) {
+ if (R2_GLOBALS._player._characterIndex == 2)
+ _object2 = &R2_GLOBALS._player;
+ else
+ _object2 = &scene->_actor1;
+
+ _object2->hide();
+ _object1.postInit();
+ _object1.setPosition(_object2->_position);
+ _object1._numFrames = 7;
+ _object1._effect = 1;
+ _object1.changeZoom(-1);
+ R2_GLOBALS._player.disableControl();
+ R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
+
+ if (_object2->_mover)
+ _object2->addMover(NULL);
+ }
+
+ switch (v) {
+ case 0:
+ _object1.animate(ANIM_MODE_2, NULL);
+ break;
+ case 1:
+ ((SceneItem *)_action)->_sceneRegionId = 0;
+ _object1.setup(4031, 1, 1);
+ _object1.animate(ANIM_MODE_5, NULL);
+ break;
+ case 2:
+ ((SceneItem *)_action)->_sceneRegionId = 0;
+ _object1.setup(4031, 3, 1);
+ _object1.animate(ANIM_MODE_5, NULL);
+ break;
+ case 3:
+ ((SceneItem *)_action)->_sceneRegionId = 0;
+ _object1.setup(4030, 3, 1);
+ _object1.animate(ANIM_MODE_5, NULL);
+ break;
+ case 4:
+ ((SceneItem *)_action)->_sceneRegionId = 0;
+ _object1.setup(4031, 7, 1);
+ _object1.animate(ANIM_MODE_5, NULL);
+ break;
+ case 5:
+ ((SceneItem *)_action)->_sceneRegionId = 0;
+ _object1.setup(4033, 1, 1);
+ _object1.animate(ANIM_MODE_5, NULL);
+ break;
+ default:
+ signal();
+ break;
+ }
+}
+
+void SpeakerSeeker3600::proc15() {
+ Scene3600 *scene = (Scene3600 *)R2_GLOBALS._sceneManager._scene;
+
+ int v = _fieldF6;
+
+ if (!_object2) {
+ if (R2_GLOBALS._player._characterIndex == 2)
+ _object2 = &R2_GLOBALS._player;
+ else
+ _object2 = &scene->_actor11;
+
+ _object2->hide();
+ _object1.postInit();
+ _object1.setPosition(_object2->_position);
+ _object1._numFrames = 7;
+ _object1._effect = 1;
+ _object1.changeZoom(-1);
+ R2_GLOBALS._player.disableControl();
+ R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
+
+ if (_object2->_mover)
+ _object2->addMover(NULL);
+
+ _object1.setPosition(_object2->_position);
+
+ }
+
+ switch (v) {
+ case 0:
+ _object1.animate(ANIM_MODE_2, NULL);
+ break;
+ case 1:
+ ((SceneItem *)_action)->_sceneRegionId = 0;
+ _object1.setup(4031, 5, 1);
+ _object1.animate(ANIM_MODE_5, this);
+ break;
+ case 2:
+ ((SceneItem *)_action)->_sceneRegionId = 0;
+ _object1.setup(4030, 1, 1);
+ _object1.animate(ANIM_MODE_5, this);
+ break;
+ default:
+ signal();
+ break;
+ }
+}
+
+void SpeakerSeeker3700::setText(const Common::String &msg) {
+ Scene3700 *scene = (Scene3700 *)R2_GLOBALS._sceneManager._scene;
+
+ if (_fieldF6 == 1) {
+ R2_GLOBALS._sound2.play(44);
+ scene->_actor3.setup(30, 8, 1);
+ } else {
+ scene->_actor3.setup(30, 2, 1);
+ }
+ VisualSpeaker::setText(msg);
+}
+
+void SpeakerSeeker3700::proc15() {
+ Scene3700 *scene = (Scene3700 *)R2_GLOBALS._sceneManager._scene;
+
+ int v = _fieldF6;
+
+ if (!_object2) {
+ _object2 = &scene->_actor2;
+ _object2->hide();
+ _object1.postInit();
+ _object1.setPosition(_object2->_position);
+ _object1._numFrames = 7;
+ R2_GLOBALS._player.disableControl();
+ R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
+
+ if (_object2->_mover)
+ _object2->addMover(NULL);
+ }
+
+ _object1.setPosition(_object2->_position);
+
+ switch (v) {
+ case 0:
+ _object1.animate(ANIM_MODE_2, NULL);
+ break;
+ case 1:
+ ((SceneItem *)_action)->_sceneRegionId = 0;
+ R2_GLOBALS._sound2.stop();
+ scene->_actor1.setup(10, 8, 1);
+ scene->_actor2.setup(20, 7, 1);
+ scene->_actor3.setup(30, 8, 1);
+ _object1.setup(3701, 3, 1);
+ _object1.animate(ANIM_MODE_5, NULL);
+ break;
+ case 2:
+ ((SceneItem *)_action)->_sceneRegionId = 0;
+ scene->_actor1.setup(10, 2, 1);
+ scene->_actor2.setup(20, 1, 1);
+ scene->_actor3.setup(30, 1, 1);
+ _object1.setup(4031, 1, 1);
+ _object1.animate(ANIM_MODE_5, NULL);
+ break;
+ default:
+ signal();
+ break;
+ }
+}
+
+//----------------------------------------------------------------------------
+// Classes related to SEEKERL
+//----------------------------------------------------------------------------
+
+SpeakerSeekerL::SpeakerSeekerL(): VisualSpeaker() {
+ _speakerName = "SEEKERL";
+ _color1 = 35;
+ _color2 = 0;
+ _fieldF6 = 0;
+ _textWidth = 300;
+ _hideObjects = false;
+ _object2 = NULL;
+ _displayMode = 1;
+ _numFrames = 0;
+ _fontNumber = 10;
+}
+
+//----------------------------------------------------------------------------
+// Classes related to SOCKO
+//----------------------------------------------------------------------------
+
+SpeakerSocko3200::SpeakerSocko3200() {
+ _speakerName = "Socko";
+ _color1 = 10;
+ _color2 = 0;
+ _fieldF6 = 0;
+ _textWidth = 300;
+ _hideObjects = false;
+ _object2 = NULL;
+ _displayMode = 1;
+ _numFrames = 0;
+}
+
+void SpeakerSocko3200::proc15() {
+ int v = _fieldF6;
+ Scene3200 *scene = (Scene3200 *)R2_GLOBALS._sceneManager._scene;
+
+ if (!_object2) {
+ _object2 = &scene->_actor3;
+ _object2->hide();
+ _object1.postInit();
+ _object1.setPosition(_object2->_position);
+
+ if (_object2->_mover)
+ _object2->addMover(NULL);
+ }
+
+ if (v == 0) {
+ _object1.animate(ANIM_MODE_2, NULL);
+ } else {
+ ((SceneItem *)_action)->_sceneRegionId = 0;
+ _object1.setup(4060, (_object2->_strip * 2) - 1, 1);
+ _object1.animate(ANIM_MODE_5, this);
+ }
+}
+
+//----------------------------------------------------------------------------
+// Classes related to SOLDIER
+//----------------------------------------------------------------------------
+
+SpeakerSoldier::SpeakerSoldier(int colour) {
+ _speakerName = "SOLDIER";
+ _color1 = colour;
+ _color2 = 0;
+ _fieldF6 = 0;
+ _textWidth = 300;
+ _hideObjects = false;
+ _object2 = NULL;
+ _displayMode = 1;
+ _numFrames = 0;
+}
+
+void SpeakerSoldier300::proc15() {
+ int v = _fieldF6;
+
+ if (!_object2) {
+ Scene300 *scene = (Scene300 *)R2_GLOBALS._sceneManager._scene;
+ _object2 = &scene->_teal;
+ _object2->hide();
+
+ _object1.postInit();
+ _object1.setPosition(_object2->_position);
+
+ if (_object2->_mover)
+ _object2->addMover(NULL);
+ }
+
+ if (v == 0) {
+ _object1.animate(ANIM_MODE_2, NULL);
+ } else {
+ ((SceneItem *)_action)->_sceneRegionId = 0;
+ _object1.setup(303, 3, 1);
+ _object1.animate(ANIM_MODE_5, this);
+ }
+}
+
+//----------------------------------------------------------------------------
+// Classes related to TEAL
+//----------------------------------------------------------------------------
+
+SpeakerTeal::SpeakerTeal(): VisualSpeaker() {
+ _speakerName = "TEAL";
+ _color1 = 22;
+ _color2 = 0;
+ _fieldF6 = 0;
+ _textWidth = 300;
+ _hideObjects = false;
+ _object2 = NULL;
+ _displayMode = 1;
+ _numFrames = 0;
+}
+
+SpeakerTealMode7::SpeakerTealMode7(): SpeakerTeal() {
+ _displayMode = 7;
+}
+
+void SpeakerTeal300::proc15() {
+ int v = _fieldF6;
+
+ if (!_object2) {
+ Scene300 *scene = (Scene300 *)R2_GLOBALS._sceneManager._scene;
+ _object2 = &scene->_teal;
+ _object2->hide();
+
+ _object1.postInit();
+ _object1.setPosition(_object2->_position);
+
+ if (_object2->_mover)
+ _object2->addMover(NULL);
+ }
+
+ if (v == 0) {
+ _object1.animate(ANIM_MODE_2, NULL);
+ } else {
+ ((SceneItem *)_action)->_sceneRegionId = 0;
+ _object1.setup(303, 1, 1);
+ _object1.animate(ANIM_MODE_5, this);
+ }
+}
+
+void SpeakerTeal1625::proc15() {
+ int v = _fieldF6;
+
+ if (!_object2) {
+ Scene1625 *scene = (Scene1625 *)R2_GLOBALS._sceneManager._scene;
+ _object2 = &scene->_actor2;
+ _object2->hide();
+
+ _object1.postInit();
+ _object1.setPosition(Common::Point(68, 68));
+
+ if (_object2->_mover)
+ _object2->addMover(NULL);
+ }
+
+ if (v == 0) {
+ _object1.animate(ANIM_MODE_2, NULL);
+ } else {
+ ((SceneItem *)_action)->_sceneRegionId = 0;
+ _object1.setup(1627, 1, 1);
+ _object1.animate(ANIM_MODE_5, this);
+ }
+}
+
+void SpeakerTeal3240::proc15() {
+ int v = _fieldF6;
+ Scene3240 *scene = (Scene3240 *)R2_GLOBALS._sceneManager._scene;
+
+ if (!_object2) {
+ _object2 = &scene->_actor1;
+ _object2->hide();
+ _object1.postInit();
+ _object1.setPosition(_object2->_position);
+
+ if (_object2->_mover)
+ _object2->addMover(NULL);
+ }
+
+ if (v == 0) {
+ _object1.animate(ANIM_MODE_2, NULL);
+ } else {
+ ((SceneItem *)_action)->_sceneRegionId = 0;
+ _object1.setup(4070, (_object2->_strip * 2) - 1, 1);
+ _object1.animate(ANIM_MODE_5, this);
+ }
+}
+
+void SpeakerTeal3400::proc15() {
+ Scene3400 *scene = (Scene3400 *)R2_GLOBALS._sceneManager._scene;
+
+ int v = _fieldF6;
+
+ if (!_object2) {
+ _object2 = &scene->_actor4;
+ _object2->hide();
+ _object1.postInit();
+ _object1._numFrames = 7;
+ _object1._effect = 1;
+ _object1.changeZoom(-1);
+ R2_GLOBALS._player.disableControl();
+ R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
+
+ if (_object2->_mover)
+ _object2->addMover(NULL);
+ }
+ _object1.setPosition(_object2->_position);
+ _object1.show();
+
+ if (scene ->_sceneMode == 3305) {
+ R2_GLOBALS._player.setStrip(6);
+ scene->_actor1.setStrip(6);
+ scene->_actor2.setStrip(6);
+ }
+
+ switch (v) {
+ case 0:
+ _object1.animate(ANIM_MODE_2, NULL);
+ break;
+ case 1:
+ ((SceneItem *)_action)->_sceneRegionId = 0;
+ _object1.setup(4107, 5, 1);
+ _object1.animate(ANIM_MODE_5, NULL);
+ break;
+ case 2:
+ ((SceneItem *)_action)->_sceneRegionId = 0;
+ _object1.setup(4107, 1, 1);
+ _object1.animate(ANIM_MODE_5, NULL);
+ break;
+ case 3:
+ ((SceneItem *)_action)->_sceneRegionId = 0;
+ _object1.setup(4107, 7, 1);
+ _object1.animate(ANIM_MODE_5, NULL);
+ break;
+ case 4:
+ ((SceneItem *)_action)->_sceneRegionId = 0;
+ _object1.setup(4107, 3, 1);
+ _object1.animate(ANIM_MODE_5, NULL);
+ break;
+ default:
+ signal();
+ break;
+ }
+}
+
+void SpeakerTeal3600::proc15() {
+ Scene3600 *scene = (Scene3600 *)R2_GLOBALS._sceneManager._scene;
+
+ int v = _fieldF6;
+
+ if (!_object2) {
+ _object2 = &scene->_actor5;
+ _object2->hide();
+ _object1.postInit();
+ _object1.setPosition(_object2->_position);
+ _object1._numFrames = 7;
+ _object1._effect = 1;
+ _object1.changeZoom(-1);
+ R2_GLOBALS._player.disableControl();
+ R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
+
+ if (_object2->_mover)
+ _object2->addMover(NULL);
+ }
+ _object1.setPosition(_object2->_position);
+
+ if (scene ->_sceneMode == 3323) {
+ _object1.hide();
+ _object2->show();
+ }
+
+ switch (v) {
+ case 0:
+ _object1.animate(ANIM_MODE_2, NULL);
+ break;
+ case 1:
+ ((SceneItem *)_action)->_sceneRegionId = 0;
+ _object1.setup(4107, 5, 1);
+ _object1.animate(ANIM_MODE_5, this);
+ break;
+ case 2:
+ ((SceneItem *)_action)->_sceneRegionId = 0;
+ _object1.setup(4107, 1, 1);
+ _object1.animate(ANIM_MODE_5, this);
+ break;
+ case 3:
+ ((SceneItem *)_action)->_sceneRegionId = 0;
+ _object1.setup(4107, 7, 1);
+ _object1.animate(ANIM_MODE_5, this);
+ break;
+ case 4:
+ ((SceneItem *)_action)->_sceneRegionId = 0;
+ _object1.setup(4107, 3, 1);
+ _object1.animate(ANIM_MODE_5, this);
+ break;
+ default:
+ signal();
+ break;
+ }
+}
+
+//----------------------------------------------------------------------------
+// Classes related to TOMKO
+//----------------------------------------------------------------------------
+
+SpeakerTomko3245::SpeakerTomko3245() {
+ _speakerName = "Tomko";
+ _color1 = 10;
+ _color2 = 0;
+ _fieldF6 = 0;
+ _textWidth = 300;
+ _hideObjects = false;
+ _object2 = NULL;
+ _displayMode = 1;
+ _numFrames = 0;
+}
+
+void SpeakerTomko3245::proc15() {
+ int v = _fieldF6;
+ Scene3245 *scene = (Scene3245 *)R2_GLOBALS._sceneManager._scene;
+
+ if (!_object2) {
+ _object2 = &scene->_actor2;
+ _object2->hide();
+ _object1.postInit();
+ _object1.setPosition(_object2->_position);
+
+ if (_object2->_mover)
+ _object2->addMover(NULL);
+ }
+
+ if (v == 0) {
+ _object1.animate(ANIM_MODE_2, NULL);
+ } else {
+ ((SceneItem *)_action)->_sceneRegionId = 0;
+ switch (_object2->_visage) {
+ case 3100:
+ _object1.setup(4105, (_object2->_strip * 2) - 1, 1);
+ break;
+ case 3101:
+ _object1.setup(4108, (_object2->_strip * 2) - 1, 1);
+ break;
+ case 3102:
+ _object1.setup(4109, (_object2->_strip * 2) - 1, 1);
+ break;
+ default:
+ break;
+ }
+
+ _object1.animate(ANIM_MODE_5, this);
+ }
+}
+
+//----------------------------------------------------------------------------
+// Classes related to WEBBSTER
+//----------------------------------------------------------------------------
+
+SpeakerWebbster::SpeakerWebbster(int colour) {
+ _speakerName = "WEBBSTER";
+ _color1 = colour;
+ _color2 = 0;
+ _fieldF6 = 0;
+ _textWidth = 300;
+ _hideObjects = false;
+ _object2 = NULL;
+ _displayMode = 1;
+ _numFrames = 0;
+}
+
+void SpeakerWebbster3240::proc15() {
+ int v = _fieldF6;
+ Scene3240 *scene = (Scene3240 *)R2_GLOBALS._sceneManager._scene;
+
+ if (!_object2) {
+ _object2 = &scene->_actor2;
+ _object2->hide();
+ _object1.postInit();
+ _object1.setPosition(_object2->_position);
+
+ if (_object2->_mover)
+ _object2->addMover(NULL);
+ }
+
+ if (v == 0) {
+ _object1.animate(ANIM_MODE_2, NULL);
+ } else {
+ ((SceneItem *)_action)->_sceneRegionId = 0;
+ _object1.setup(4110, 5, 1);
+ _object1.animate(ANIM_MODE_5, this);
+ }
+}
+
+void SpeakerWebbster3375::proc15() {
+ Scene3375 *scene = (Scene3375 *)R2_GLOBALS._sceneManager._scene;
+
+ int v = _fieldF6;
+
+ if (!_object2) {
+ _object2 = &scene->_actor3;
+ _object2->hide();
+ _object1.postInit();
+ _object1.setPosition(_object2->_position);
+ _object1._numFrames = 7;
+ _object1._effect = 1;
+ _object1.changeZoom(-1);
+
+ if (scene->_actor1._position.y != 163)
+ R2_GLOBALS._player.setStrip(8);
+ else
+ R2_GLOBALS._player.setStrip(2);
+
+ if (R2_GLOBALS._player._mover)
+ R2_GLOBALS._player.addMover(NULL);
+
+ R2_GLOBALS._player.disableControl();
+ R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
+
+ if (_object2->_mover)
+ _object2->addMover(NULL);
+ }
+
+ switch (v) {
+ case 0:
+ _object1.animate(ANIM_MODE_2, NULL);
+ break;
+ case 1:
+ ((SceneItem *)_action)->_sceneRegionId = 0;
+ _object1.setup(4110, 5, 1);
+ _object1.animate(ANIM_MODE_5, this);
+ break;
+ default:
+ signal();
+ break;
+ }
+}
+
+void SpeakerWebbster3385::proc15() {
+ Scene3385 *scene = (Scene3385 *)R2_GLOBALS._sceneManager._scene;
+
+ int v = _fieldF6;
+
+ if (!_object2) {
+ _object2 = &scene->_actor3;
+ _object2->hide();
+ _object1.postInit();
+ _object1.setPosition(_object2->_position);
+ _object1._numFrames = 7;
+ _object1._effect = 1;
+ _object1.changeZoom(-1);
+
+ if (R2_GLOBALS._sceneManager._previousScene == 3375)
+ R2_GLOBALS._player.setStrip(4);
+ else
+ R2_GLOBALS._player.setStrip(3);
+
+ if (R2_GLOBALS._player._mover)
+ R2_GLOBALS._player.addMover(NULL);
+
+ R2_GLOBALS._player.disableControl(CURSOR_TALK);
+ R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
+
+ if (_object2->_mover)
+ _object2->addMover(NULL);
+ }
+
+ switch (v) {
+ case 0:
+ _object1.animate(ANIM_MODE_2, NULL);
+ break;
+ case 1:
+ ((SceneItem *)_action)->_sceneRegionId = 0;
+ _object1.setup(4110, 5, 1);
+ _object1.animate(ANIM_MODE_5, this);
+ break;
+ default:
+ signal();
+ break;
+ }
+}
+
+void SpeakerWebbster3395::proc15() {
+ Scene3395 *scene = (Scene3395 *)R2_GLOBALS._sceneManager._scene;
+
+ int v = _fieldF6;
+
+ if (!_object2) {
+ _object2 = &scene->_actor3;
+ _object2->hide();
+ _object1.postInit();
+ _object1.setPosition(_object2->_position);
+ _object1._numFrames = 7;
+ _object1._effect = 1;
+ _object1.changeZoom(-1);
+
+ if (R2_GLOBALS._sceneManager._previousScene == 3385)
+ R2_GLOBALS._player.setStrip(4);
+ else
+ R2_GLOBALS._player.setStrip(3);
+
+ if (R2_GLOBALS._player._mover)
+ R2_GLOBALS._player.addMover(NULL);
+
+ R2_GLOBALS._player.disableControl(CURSOR_TALK);
+ R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
+
+ if (_object2->_mover)
+ _object2->addMover(NULL);
+ }
+
+ switch (v) {
+ case 0:
+ _object1.animate(ANIM_MODE_2, NULL);
+ break;
+ case 1:
+ ((SceneItem *)_action)->_sceneRegionId = 0;
+ _object1.setup(4110, 5, 1);
+ _object1.animate(ANIM_MODE_5, this);
+ break;
+ default:
+ signal();
+ break;
+ }
+}
+
+void SpeakerWebbster3400::proc15() {
+ Scene3400 *scene = (Scene3400 *)R2_GLOBALS._sceneManager._scene;
+
+ int v = _fieldF6;
+
+ if (!_object2) {
+ _object2 = &scene->_actor3;
+ _object2->hide();
+ _object1.postInit();
+ _object1.setPosition(_object2->_position);
+ _object1._numFrames = 7;
+ _object1._effect = 1;
+ _object1.changeZoom(-1);
+ R2_GLOBALS._player.disableControl();
+ R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
+
+ if (_object2->_mover)
+ _object2->addMover(NULL);
+ }
+
+ switch (v) {
+ case 0:
+ _object1.animate(ANIM_MODE_2, NULL);
+ break;
+ case 1:
+ ((SceneItem *)_action)->_sceneRegionId = 0;
+ _object1.setup(4110, 5, 1);
+ _object1.animate(ANIM_MODE_5, NULL);
+ break;
+ case 2:
+ ((SceneItem *)_action)->_sceneRegionId = 0;
+ _object1.setup(4110, 7, 1);
+ _object1.animate(ANIM_MODE_5, NULL);
+ break;
+ case 3:
+ ((SceneItem *)_action)->_sceneRegionId = 0;
+ _object1.setup(4110, 3, 1);
+ _object1.animate(ANIM_MODE_5, NULL);
+ break;
+ default:
+ signal();
+ break;
+ }
+}
+
+//----------------------------------------------------------------------------
+
+SpeakerDutyOfficer::SpeakerDutyOfficer(): VisualSpeaker() {
+ _speakerName = "DUTYOFFICER";
+ _color1 = 5;
+ _color2 = 0;
+ _fieldF6 = 0;
+ _textWidth = 300;
+ _hideObjects = false;
+ _object2 = NULL;
+ _displayMode = 1;
+ _numFrames = 0;
+}
+
+void SpeakerDutyOfficer::proc15() {
+ Scene180 *scene = (Scene180 *)R2_GLOBALS._sceneManager._scene;
+
+ int v = _fieldF6;
+
+ if (!_object2) {
+ _object2 = &scene->_object2;
+ _object2->hide();
+ _object1.postInit();
+ _object1.setPosition(_object2->_position);
+
+ if (_object2->_mover)
+ _object2->addMover(NULL);
+ }
+
+ switch (v) {
+ case 0:
+ _object1.animate(ANIM_MODE_2, NULL);
+ break;
+ case 1:
+ _action = NULL;
+ _object1.setup(76, 2, 1);
+ _object1.animate(ANIM_MODE_5, this);
+ break;
+ default:
+ signal();
+ break;
+ }
+}
+
+
+} // End of namespace Ringworld2
+} // End of namespace TsAGE
diff --git a/engines/tsage/ringworld2/ringworld2_speakers.h b/engines/tsage/ringworld2/ringworld2_speakers.h
new file mode 100644
index 0000000000..e336564c5f
--- /dev/null
+++ b/engines/tsage/ringworld2/ringworld2_speakers.h
@@ -0,0 +1,637 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef TSAGE_RINGWORLD2_SPEAKERS_H
+#define TSAGE_RINGWORLD2_SPEAKERS_H
+
+#include "common/scummsys.h"
+#include "tsage/converse.h"
+#include "tsage/events.h"
+#include "tsage/core.h"
+#include "tsage/scenes.h"
+#include "tsage/globals.h"
+#include "tsage/ringworld2/ringworld2_logic.h"
+
+namespace TsAGE {
+
+namespace Ringworld2 {
+
+using namespace TsAGE;
+
+class VisualSpeaker : public Speaker {
+public:
+ SceneActor _object1;
+ SceneObject *_object2;
+ int _fieldF6, _fieldF8;
+ int _displayMode;
+ int _soundId;
+ int _delayAmount;
+ bool _removeObject;
+ int _frameNumber;
+ int _numFrames;
+private:
+ void setFrame(int numFrames);
+public:
+ VisualSpeaker();
+
+ virtual Common::String getClassName() { return "VisualSpeaker"; }
+ virtual void synchronize(Serializer &s);
+ virtual void remove();
+ virtual void setText(const Common::String &msg);
+ virtual void proc15() {}
+ virtual void proc16();
+
+ void setDelay(int delay);
+};
+
+class SpeakerGameText : public VisualSpeaker {
+public:
+ SpeakerGameText();
+
+ virtual Common::String getClassName() { return "SpeakerGameText"; }
+};
+
+// Classes related to Captain
+
+class SpeakerCaptain3210 : public VisualSpeaker {
+public:
+ SpeakerCaptain3210();
+
+ virtual Common::String getClassName() { return "SpeakerCaptain3210"; }
+ virtual void proc15();
+};
+
+// Classes related to Caretaker
+
+class SpeakerCaretaker2450 : public VisualSpeaker {
+public:
+ SpeakerCaretaker2450();
+
+ virtual Common::String getClassName() { return "SpeakerCaretaker2450"; }
+};
+
+// Classes related to Chief
+
+class SpeakerChief1100 : public VisualSpeaker {
+public:
+ SpeakerChief1100();
+
+ virtual Common::String getClassName() { return "SpeakerChief1100"; }
+ virtual void proc15();
+};
+
+// Classes related to Guard
+
+class SpeakerGuard : public VisualSpeaker {
+public:
+ SpeakerGuard();
+ virtual Common::String getClassName() { return "SpeakerGuard"; }
+};
+
+class SpeakerGuard2800 : public SpeakerGuard {
+public:
+ virtual Common::String getClassName() { return "SpeakerGuard2800"; }
+ virtual void proc15();
+};
+
+// Classes related to Jocko
+
+class SpeakerJocko : public VisualSpeaker {
+public:
+ SpeakerJocko();
+ virtual Common::String getClassName() { return "SpeakerJocko"; }
+};
+
+class SpeakerJocko3200 : public SpeakerJocko {
+public:
+ virtual Common::String getClassName() { return "SpeakerJocko3200"; }
+ virtual void proc15();
+};
+
+class SpeakerJocko3220 : public SpeakerJocko {
+public:
+ virtual Common::String getClassName() { return "SpeakerJocko3220"; }
+ virtual void proc15();
+};
+
+class SpeakerJocko3230 : public SpeakerJocko {
+public:
+ virtual Common::String getClassName() { return "SpeakerJocko3230"; }
+ virtual void proc15();
+};
+
+// Classes related to Miranda
+
+class SpeakerMiranda : public VisualSpeaker {
+public:
+ SpeakerMiranda();
+ virtual Common::String getClassName() { return "SpeakerMiranda"; }
+};
+
+class SpeakerMiranda300 : public SpeakerMiranda {
+public:
+ virtual Common::String getClassName() { return "SpeakerMiranda300"; }
+ virtual void proc15();
+};
+
+class SpeakerMiranda1625 : public SpeakerMiranda {
+public:
+ virtual Common::String getClassName() { return "SpeakerMiranda1625"; }
+ virtual void proc15();
+};
+
+class SpeakerMiranda3255 : public SpeakerMiranda {
+public:
+ virtual Common::String getClassName() { return "SpeakerMiranda3255"; }
+ virtual void proc15();
+};
+
+class SpeakerMiranda3375 : public SpeakerMiranda {
+public:
+ virtual Common::String getClassName() { return "SpeakerMiranda3375"; }
+ virtual void proc15();
+};
+
+class SpeakerMiranda3385 : public SpeakerMiranda {
+public:
+ virtual Common::String getClassName() { return "SpeakerMiranda3385"; }
+ virtual void proc15();
+};
+
+class SpeakerMiranda3395 : public SpeakerMiranda {
+public:
+ virtual Common::String getClassName() { return "SpeakerMiranda3395"; }
+ virtual void proc15();
+};
+
+class SpeakerMiranda3400 : public SpeakerMiranda {
+public:
+ virtual Common::String getClassName() { return "SpeakerMiranda3400"; }
+ virtual void proc15();
+};
+
+class SpeakerMiranda3600 : public SpeakerMiranda {
+public:
+ virtual Common::String getClassName() { return "SpeakerMiranda3600"; }
+ virtual void proc15();
+};
+
+class SpeakerMiranda3700 : public SpeakerMiranda {
+public:
+ virtual Common::String getClassName() { return "SpeakerMiranda3700"; }
+ virtual void proc15();
+};
+
+// Classes related to Nej
+
+class SpeakerNej : public VisualSpeaker {
+public:
+ SpeakerNej();
+ virtual Common::String getClassName() { return "SpeakerNej"; }
+};
+
+class SpeakerNej2700 : public SpeakerNej {
+public:
+ virtual Common::String getClassName() { return "SpeakerNej2700"; }
+ virtual void proc15();
+};
+
+class SpeakerNej2750 : public SpeakerNej {
+public:
+ virtual Common::String getClassName() { return "SpeakerNej2750"; }
+ virtual void proc15();
+};
+
+class SpeakerNej2800 : public SpeakerNej {
+public:
+ virtual Common::String getClassName() { return "SpeakerNej2800"; }
+ virtual void proc15();
+};
+
+// Classes related to Pharisha
+
+class SpeakerPharisha : public VisualSpeaker {
+public:
+ SpeakerPharisha();
+
+ virtual Common::String getClassName() { return "SpeakerPharisha"; }
+};
+
+class SpeakerPharisha2435 : public SpeakerPharisha {
+public:
+ virtual Common::String getClassName() { return "SpeakerPharisha2435"; }
+ virtual void proc15();
+};
+
+// Classes related to Private
+
+class SpeakerPrivate3210 : public VisualSpeaker {
+public:
+ SpeakerPrivate3210();
+
+ virtual Common::String getClassName() { return "SpeakerPrivate3210"; }
+ virtual void proc15();
+};
+
+// Classes related to Protector
+
+class SpeakerProtector3600 : public VisualSpeaker {
+public:
+ SpeakerProtector3600();
+
+ virtual Common::String getClassName() { return "SpeakerProtector3600"; }
+ virtual void proc15();
+};
+
+// Classes related to Quinn
+
+class SpeakerQuinn : public VisualSpeaker {
+public:
+ SpeakerQuinn();
+ virtual Common::String getClassName() { return "SpeakerQuinn"; }
+};
+
+class SpeakerQuinn300 : public SpeakerQuinn {
+public:
+ virtual Common::String getClassName() { return "SpeakerQuinn300"; }
+ virtual void proc15();
+};
+
+class SpeakerQuinn1100 : public SpeakerQuinn {
+public:
+ virtual Common::String getClassName() { return "SpeakerQuinn1100"; }
+ virtual void proc15();
+};
+
+class SpeakerQuinn2435 : public SpeakerQuinn {
+public:
+ virtual Common::String getClassName() { return "SpeakerQuinn2435"; }
+ virtual void proc15();
+};
+
+class SpeakerQuinn2450 : public SpeakerQuinn {
+public:
+ virtual Common::String getClassName() { return "SpeakerQuinn2450"; }
+ virtual void proc15();
+};
+
+class SpeakerQuinn2700 : public SpeakerQuinn {
+public:
+ virtual Common::String getClassName() { return "SpeakerQuinn2700"; }
+ virtual void proc15();
+};
+
+class SpeakerQuinn2750 : public SpeakerQuinn {
+public:
+ virtual Common::String getClassName() { return "SpeakerQuinn2750"; }
+ virtual void proc15();
+};
+
+class SpeakerQuinn2800 : public SpeakerQuinn {
+public:
+ virtual Common::String getClassName() { return "SpeakerQuinn2800"; }
+ virtual void proc15();
+};
+
+class SpeakerQuinn3255 : public SpeakerQuinn {
+public:
+ virtual Common::String getClassName() { return "SpeakerQuinn3255"; }
+ virtual void proc15();
+};
+
+class SpeakerQuinn3375 : public SpeakerQuinn {
+public:
+ virtual Common::String getClassName() { return "SpeakerQuinn3375"; }
+ virtual void proc15();
+};
+
+class SpeakerQuinn3385 : public SpeakerQuinn {
+public:
+ virtual Common::String getClassName() { return "SpeakerQuinn3385"; }
+ virtual void proc15();
+};
+
+class SpeakerQuinn3395 : public SpeakerQuinn {
+public:
+ virtual Common::String getClassName() { return "SpeakerQuinn3395"; }
+ virtual void proc15();
+};
+
+class SpeakerQuinn3400 : public SpeakerQuinn {
+public:
+ virtual Common::String getClassName() { return "SpeakerQuinn3400"; }
+ virtual void proc15();
+};
+
+class SpeakerQuinn3600 : public SpeakerQuinn {
+public:
+ virtual Common::String getClassName() { return "SpeakerQuinn3600"; }
+ virtual void proc15();
+};
+
+class SpeakerQuinn3700 : public SpeakerQuinn {
+public:
+ virtual Common::String getClassName() { return "SpeakerQuinn3700"; }
+ virtual void setText(const Common::String &msg);
+ virtual void proc15();
+};
+
+// Classes related to QuinnL
+
+class SpeakerQuinnL : public VisualSpeaker {
+public:
+ SpeakerQuinnL();
+
+ virtual Common::String getClassName() { return "SpeakerQuinnL"; }
+};
+
+// Classes related to Ralf
+
+class SpeakerRalf3245 : public VisualSpeaker {
+public:
+ SpeakerRalf3245();
+
+ virtual Common::String getClassName() { return "SpeakerRalf3245"; }
+ virtual void proc15();
+};
+
+// Classes related to Rocko
+
+class SpeakerRocko : public VisualSpeaker {
+public:
+ SpeakerRocko();
+ virtual Common::String getClassName() { return "SpeakerRocko"; }
+};
+
+class SpeakerRocko3200 : public SpeakerRocko {
+public:
+ virtual Common::String getClassName() { return "SpeakerRocko3200"; }
+ virtual void proc15();
+};
+
+class SpeakerRocko3220 : public SpeakerRocko {
+public:
+ virtual Common::String getClassName() { return "SpeakerRocko3220"; }
+ virtual void proc15();
+};
+
+class SpeakerRocko3230 : public SpeakerRocko {
+public:
+ virtual Common::String getClassName() { return "SpeakerRocko3230"; }
+ virtual void proc15();
+};
+
+// Classes related to Seeker
+
+class SpeakerSeeker : public VisualSpeaker {
+public:
+ SpeakerSeeker();
+ virtual Common::String getClassName() { return "SpeakerSeeker"; }
+};
+
+class SpeakerSeeker300 : public SpeakerSeeker {
+public:
+ virtual Common::String getClassName() { return "SpeakerSeeker300"; }
+ virtual void proc15();
+};
+
+class SpeakerSeeker1100 : public SpeakerSeeker {
+public:
+ virtual Common::String getClassName() { return "SpeakerSeeker1100"; }
+ virtual void proc15();
+};
+
+class SpeakerSeeker1900 : public SpeakerSeeker {
+public:
+ virtual Common::String getClassName() { return "SpeakerSeeker1900"; }
+ virtual void proc15();
+};
+
+class SpeakerSeeker2435 : public SpeakerSeeker {
+public:
+ virtual Common::String getClassName() { return "SpeakerSeeker2435"; }
+ virtual void proc15();
+};
+
+class SpeakerSeeker2450 : public SpeakerSeeker {
+public:
+ virtual Common::String getClassName() { return "SpeakerSeeker2450"; }
+ virtual void proc15();
+};
+
+class SpeakerSeeker3375 : public SpeakerSeeker {
+public:
+ virtual Common::String getClassName() { return "SpeakerSeeker3375"; }
+ virtual void proc15();
+};
+
+class SpeakerSeeker3385 : public SpeakerSeeker {
+public:
+ virtual Common::String getClassName() { return "SpeakerSeeker3385"; }
+ virtual void proc15();
+};
+
+class SpeakerSeeker3395 : public SpeakerSeeker {
+public:
+ virtual Common::String getClassName() { return "SpeakerSeeker3395"; }
+ virtual void proc15();
+};
+
+class SpeakerSeeker3400 : public SpeakerSeeker {
+public:
+ virtual Common::String getClassName() { return "SpeakerSeeker3400"; }
+ virtual void proc15();
+};
+
+class SpeakerSeeker3600 : public SpeakerSeeker {
+public:
+ virtual Common::String getClassName() { return "SpeakerSeeker3600"; }
+ virtual void proc15();
+};
+
+class SpeakerSeeker3700 : public SpeakerSeeker {
+public:
+ virtual Common::String getClassName() { return "SpeakerSeeker3700"; }
+ virtual void setText(const Common::String &msg);
+ virtual void proc15();
+};
+
+// Classes related to SeekerL
+
+class SpeakerSeekerL : public VisualSpeaker {
+public:
+ SpeakerSeekerL();
+
+ virtual Common::String getClassName() { return "SpeakerSeekerL"; }
+};
+
+// Classes related to Socko
+
+class SpeakerSocko3200 : public VisualSpeaker {
+public:
+ SpeakerSocko3200();
+
+ virtual Common::String getClassName() { return "SpeakerSocko3200"; }
+ virtual void proc15();
+};
+
+// Classes related to Soldier
+
+class SpeakerSoldier : public VisualSpeaker {
+public:
+ SpeakerSoldier(int colour);
+ virtual Common::String getClassName() { return "SpeakerSoldier"; }
+};
+
+class SpeakerSoldier300 : public SpeakerSoldier {
+public:
+ SpeakerSoldier300() : SpeakerSoldier(60) {};
+ virtual Common::String getClassName() { return "SpeakerSoldier300"; }
+ virtual void proc15();
+};
+
+class SpeakerSoldier1625 : public SpeakerSoldier {
+public:
+ SpeakerSoldier1625() : SpeakerSoldier(5) {};
+ virtual Common::String getClassName() { return "SpeakerSoldier1625"; }
+};
+
+// Classes related to Teal
+
+class SpeakerTeal : public VisualSpeaker {
+public:
+ SpeakerTeal();
+ virtual Common::String getClassName() { return "SpeakerTeal"; }
+};
+
+class SpeakerTealMode7 : public SpeakerTeal {
+public:
+ SpeakerTealMode7();
+ virtual Common::String getClassName() { return "SpeakerTealMode7"; }
+};
+
+class SpeakerTeal300 : public SpeakerTeal {
+public:
+ virtual Common::String getClassName() { return "SpeakerTeal300"; }
+ virtual void proc15();
+};
+
+class SpeakerTeal1625 : public SpeakerTeal {
+public:
+ virtual Common::String getClassName() { return "SpeakerTeal1625"; }
+ virtual void proc15();
+};
+
+class SpeakerTeal3240 : public SpeakerTeal {
+public:
+ virtual Common::String getClassName() { return "SpeakerTeal3240"; }
+ virtual void proc15();
+};
+
+class SpeakerTeal3400 : public SpeakerTeal {
+public:
+ virtual Common::String getClassName() { return "SpeakerTeal3400"; }
+ virtual void proc15();
+};
+
+class SpeakerTeal3600 : public SpeakerTealMode7 {
+public:
+ virtual Common::String getClassName() { return "SpeakerTeal3600"; }
+ virtual void proc15();
+};
+
+// Classes related to Tomko
+
+class SpeakerTomko3245 : public VisualSpeaker {
+public:
+ SpeakerTomko3245();
+
+ virtual Common::String getClassName() { return "SpeakerTomko3245"; }
+ virtual void proc15();
+};
+
+// Classes related to Webbster
+
+class SpeakerWebbster : public VisualSpeaker {
+public:
+ SpeakerWebbster(int colour);
+ virtual Common::String getClassName() { return "SpeakerWebbster"; }
+};
+
+class SpeakerWebbster2500 : public SpeakerWebbster {
+public:
+ SpeakerWebbster2500() : SpeakerWebbster(27) {}
+ virtual Common::String getClassName() { return "SpeakerWebbster2500"; }
+};
+
+class SpeakerWebbster3240 : public SpeakerWebbster {
+public:
+ SpeakerWebbster3240() : SpeakerWebbster(10) {};
+
+ virtual Common::String getClassName() { return "SpeakerWebbster3240"; }
+ virtual void proc15();
+};
+
+class SpeakerWebbster3375 : public SpeakerWebbster {
+public:
+ SpeakerWebbster3375() : SpeakerWebbster(60) {};
+
+ virtual Common::String getClassName() { return "SpeakerWebbster3375"; }
+ virtual void proc15();
+};
+
+class SpeakerWebbster3385 : public SpeakerWebbster {
+public:
+ SpeakerWebbster3385() : SpeakerWebbster(60) {};
+
+ virtual Common::String getClassName() { return "SpeakerWebbster3385"; }
+ virtual void proc15();
+};
+
+class SpeakerWebbster3395 : public SpeakerWebbster {
+public:
+ SpeakerWebbster3395() : SpeakerWebbster(60) {};
+
+ virtual Common::String getClassName() { return "SpeakerWebbster3395"; }
+ virtual void proc15();
+};
+
+class SpeakerWebbster3400 : public SpeakerWebbster {
+public:
+ SpeakerWebbster3400() : SpeakerWebbster(27) {};
+
+ virtual Common::String getClassName() { return "SpeakerWebbster3400"; }
+ virtual void proc15();
+};
+
+class SpeakerDutyOfficer: public VisualSpeaker {
+public:
+ SpeakerDutyOfficer();
+
+ virtual Common::String getClassName() { return "SpeakerDutyOfficer"; }
+ virtual void proc15();
+};
+
+} // End of namespace Ringworld2
+} // End of namespace TsAGE
+
+#endif
diff --git a/engines/tsage/saveload.cpp b/engines/tsage/saveload.cpp
index db52050b03..af2f3566ad 100644
--- a/engines/tsage/saveload.cpp
+++ b/engines/tsage/saveload.cpp
@@ -189,6 +189,8 @@ Common::Error Saver::restore(int slot) {
// Read in the savegame header
tSageSavegameHeader header;
readSavegameHeader(saveFile, header);
+ if (header.thumbnail)
+ header.thumbnail->free();
delete header.thumbnail;
serializer.setSaveVersion(header.version);
@@ -290,6 +292,7 @@ void Saver::writeSavegameHeader(Common::OutSaveFile *out, tSageSavegameHeader &h
::createThumbnail(thumb, (const byte *)s.pixels, SCREEN_WIDTH, SCREEN_HEIGHT, thumbPalette);
Graphics::saveThumbnail(*out, *thumb);
g_globals->_screenSurface.unlockSurface();
+ thumb->free();
delete thumb;
// Write out the save date/time
diff --git a/engines/tsage/saveload.h b/engines/tsage/saveload.h
index 52b23413d4..4126e31822 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 7
+#define TSAGE_SAVEGAME_VERSION 10
class SavedObject;
diff --git a/engines/tsage/scenes.cpp b/engines/tsage/scenes.cpp
index 686b8725f5..0756d71d4c 100644
--- a/engines/tsage/scenes.cpp
+++ b/engines/tsage/scenes.cpp
@@ -133,7 +133,7 @@ void SceneManager::fadeInIfNecessary() {
percent = 100;
g_globals->_scenePalette.fade((const byte *)&adjustData, false, percent);
- g_system->updateScreen();
+ GLOBALS._screenSurface.updateScreen();
g_system->delayMillis(10);
}
@@ -164,7 +164,7 @@ void SceneManager::changeScene(int newSceneNumber) {
sceneObj->setObjectWrapper(NULL);
sceneObj->animate(ANIM_MODE_NONE, 0);
- sceneObj->_flags &= !OBJFLAG_PANES;
+ sceneObj->_flags &= ~OBJFLAG_PANES;
}
// Blank out the screen
@@ -240,7 +240,7 @@ void SceneManager::listenerSynchronize(Serializer &s) {
if (s.isLoading()) {
changeScene(_sceneNumber);
-
+
if (_nextSceneNumber != -1) {
sceneChange();
_nextSceneNumber = -1;
@@ -259,7 +259,7 @@ Scene::Scene() : _sceneBounds(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT),
_sceneMode = 0;
_activeScreenNumber = 0;
_oldSceneBounds = Rect(4000, 4000, 4100, 4100);
- Common::set_to(&_zoomPercents[0], &_zoomPercents[256], 0);
+ Common::fill(&_zoomPercents[0], &_zoomPercents[256], 0);
}
Scene::~Scene() {
@@ -317,7 +317,7 @@ void Scene::loadSceneData(int sceneNum) {
_activeScreenNumber = sceneNum;
if (g_vm->getGameID() == GType_Ringworld2) {
- // Most scenes in Ringworld 2 don't have a scene size resource, but rather just have
+ // Most scenes in Ringworld 2 don't have a scene size resource, but rather just have
// a standard 320x200 size. Only read the scene size data for the specific few scenes
switch (sceneNum) {
case 700:
@@ -363,7 +363,7 @@ void Scene::loadSceneData(int sceneNum) {
_priorities.load(sceneNum);
// Initialize the section enabled list
- Common::set_to(&_enabledSections[0], &_enabledSections[16 * 16], 0xffff);
+ Common::fill(&_enabledSections[0], &_enabledSections[16 * 16], 0xffff);
g_globals->_sceneOffset.x = (_sceneBounds.left / 160) * 160;
g_globals->_sceneOffset.y = (_sceneBounds.top / 100) * 100;
@@ -456,8 +456,9 @@ void Scene::refreshBackground(int xAmount, int yAmount) {
(xSectionSrc + 1) * 160, (ySectionSrc + 1) * 100);
Rect destBounds(xSectionDest * 160, ySectionDest * 100,
(xSectionDest + 1) * 160, (ySectionDest + 1) * 100);
- if (g_vm->getGameID() == GType_BlueForce) {
- // For Blue Force, if the scene has an interface area, exclude it from the copy
+ if (g_vm->getGameID() != GType_Ringworld) {
+ // For Blue Force and Return to Ringworld, if the scene has an interface area,
+ // exclude it from the copy
srcBounds.bottom = MIN<int16>(srcBounds.bottom, BF_GLOBALS._interfaceY);
destBounds.bottom = MIN<int16>(destBounds.bottom, BF_GLOBALS._interfaceY);
}
diff --git a/engines/tsage/sound.cpp b/engines/tsage/sound.cpp
index b61e63236b..9df5a6666b 100644
--- a/engines/tsage/sound.cpp
+++ b/engines/tsage/sound.cpp
@@ -36,7 +36,7 @@ static SoundManager *_soundManager = NULL;
SoundManager::SoundManager() {
_soundManager = this;
- __sndmgrReady = false;
+ _sndmgrReady = false;
_ourSndResVersion = 0x102;
_ourDrvResVersion = 0x10A;
@@ -52,7 +52,7 @@ SoundManager::SoundManager() {
}
SoundManager::~SoundManager() {
- if (__sndmgrReady) {
+ if (_sndmgrReady) {
Common::StackLock slock(_serverDisabledMutex);
g_vm->_mixer->stopAll();
@@ -83,7 +83,7 @@ SoundManager::~SoundManager() {
}
void SoundManager::postInit() {
- if (!__sndmgrReady) {
+ if (!_sndmgrReady) {
g_saver->addSaveNotifier(&SoundManager::saveNotifier);
g_saver->addLoadNotifier(&SoundManager::loadNotifier);
g_saver->addListener(this);
@@ -94,7 +94,7 @@ void SoundManager::postInit() {
// thread, and doesn't get too far ahead, I've left it to the AdlibSoundDriver class to
// call the update method, rather than having it be called separately
// g_system->getTimerManager()->installTimerProc(_sfUpdateCallback, 1000000 / SOUND_FREQUENCY, NULL, "tsageSoundUpdate");
- __sndmgrReady = true;
+ _sndmgrReady = true;
}
}
@@ -136,7 +136,7 @@ void SoundManager::update() {
}
Common::List<SoundDriverEntry> &SoundManager::buildDriverList(bool detectFlag) {
- assert(__sndmgrReady);
+ assert(_sndmgrReady);
_availableDrivers.clear();
// Build up a list of available drivers. Currently we only implement an Adlib music
@@ -549,7 +549,7 @@ void SoundManager::loadNotifier(bool postFlag) {
void SoundManager::loadNotifierProc(bool postFlag) {
if (!postFlag) {
// Stop any currently playing sounds
- if (__sndmgrReady) {
+ if (_sndmgrReady) {
Common::StackLock slock(_serverDisabledMutex);
for (Common::List<Sound *>::iterator i = _soundList.begin(); i != _soundList.end(); ) {
@@ -569,7 +569,7 @@ void SoundManager::loadNotifierProc(bool postFlag) {
void SoundManager::listenerSynchronize(Serializer &s) {
s.validate("SoundManager");
- assert(__sndmgrReady && _driversDetected);
+ assert(_sndmgrReady && _driversDetected);
if (s.getVersion() < 6)
return;
@@ -798,7 +798,7 @@ void SoundManager::_sfRethinkVoiceTypes() {
continue;
_sfUpdateVoiceStructs();
- Common::set_to(sound->_chWork, sound->_chWork + SOUND_ARR_SIZE, false);
+ Common::fill(sound->_chWork, sound->_chWork + SOUND_ARR_SIZE, false);
for (;;) {
// Scan for sub priority
@@ -1485,7 +1485,7 @@ Sound::Sound() {
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);
+ Common::fill(_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));
@@ -2557,7 +2557,7 @@ AdlibSoundDriver::AdlibSoundDriver(): SoundDriver() {
_mixer->playStream(Audio::Mixer::kPlainSoundType, &_soundHandle, this, -1, Audio::Mixer::kMaxChannelVolume, 0, DisposeAfterUse::NO, true);
- Common::set_to(_channelVoiced, _channelVoiced + ADLIB_CHANNEL_COUNT, false);
+ Common::fill(_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));
@@ -2565,7 +2565,7 @@ AdlibSoundDriver::AdlibSoundDriver(): SoundDriver() {
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);
+ Common::fill(_pitchBlend, _pitchBlend + ADLIB_CHANNEL_COUNT, 0x2000);
memset(_v4409E, 0, ADLIB_CHANNEL_COUNT * sizeof(int));
_patchData = NULL;
}
diff --git a/engines/tsage/sound.h b/engines/tsage/sound.h
index 2c5d2ac951..77d1f3d3ac 100644
--- a/engines/tsage/sound.h
+++ b/engines/tsage/sound.h
@@ -87,7 +87,7 @@ public:
int _driverResID;
public:
SoundDriver();
- virtual ~SoundDriver() {};
+ virtual ~SoundDriver() {}
const Common::String &getShortDriverDescription() { return _shortDescription; }
const Common::String &getLongDriverDescription() { return _longDescription; }
@@ -169,7 +169,7 @@ class SoundManager : public SaveListener {
private:
SoundDriver *instantiateDriver(int driverNum);
public:
- bool __sndmgrReady;
+ bool _sndmgrReady;
int _ourSndResVersion, _ourDrvResVersion;
SynchronizedList<Sound *> _playList;
Common::List<SoundDriver *> _installedDrivers;
@@ -414,6 +414,16 @@ public:
virtual void signal();
};
+class PlayStream {
+public:
+ Sound _sound;
+
+ void setFile(const Common::String &filename) {}
+ bool play(int soundNum, EventHandler *endAction) { return false; }
+ void stop() {}
+ void proc1() {}
+ bool isPlaying() const { return false; }
+};
#define ADLIB_CHANNEL_COUNT 9
diff --git a/engines/tsage/staticres.cpp b/engines/tsage/staticres.cpp
index c98d9d2e53..a273ec2a0b 100644
--- a/engines/tsage/staticres.cpp
+++ b/engines/tsage/staticres.cpp
@@ -64,120 +64,390 @@ const byte CURSOR_WALK_DATA[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09
};
-const char *LOOK_SCENE_HOTSPOT = "You see nothing special.";
-const char *USE_SCENE_HOTSPOT = "That accomplishes nothing.";
-const char *TALK_SCENE_HOTSPOT = "Yak, yak.";
-const char *SPECIAL_SCENE_HOTSPOT = "That is a unique use for that.";
-const char *DEFAULT_SCENE_HOTSPOT = "That accomplishes nothing.";
-const char *SAVE_ERROR_MSG = "Error occurred saving game. Please do not try to restore this game!";
-const char *SAVING_NOT_ALLOWED_MSG = "Saving is not allowed at this time.";
-const char *RESTORING_NOT_ALLOWED_MSG = "Restoring is not allowed at this time.";
-const char *INV_EMPTY_MSG = "You have nothing in your possesion.";
-
-const char *QUIT_CONFIRM_MSG = "Do you want to quit playing this game?";
-const char *RESTART_MSG = "Do you want to restart this game?";
-const char *GAME_PAUSED_MSG = "Game is paused.";
-const char *OPTIONS_MSG = "\x01Options...";
-const char *OK_BTN_STRING = " Ok ";
-const char *CANCEL_BTN_STRING = "Cancel";
-const char *QUIT_BTN_STRING = " Quit ";
-const char *RESTART_BTN_STRING = "Restart";
-const char *SAVE_BTN_STRING = "Save";
-const char *RESTORE_BTN_STRING = "Restore";
-const char *SOUND_BTN_STRING = "Sound";
-const char *RESUME_BTN_STRING = " Resume \rplay";
-const char *LOOK_BTN_STRING = "Look";
-const char *PICK_BTN_STRING = "Pick";
+char const *const LOOK_SCENE_HOTSPOT = "You see nothing special.";
+char const *const USE_SCENE_HOTSPOT = "That accomplishes nothing.";
+char const *const TALK_SCENE_HOTSPOT = "Yak, yak.";
+char const *const SPECIAL_SCENE_HOTSPOT = "That is a unique use for that.";
+char const *const DEFAULT_SCENE_HOTSPOT = "That accomplishes nothing.";
+char const *const SAVE_ERROR_MSG = "Error occurred saving game. Please do not try to restore this game!";
+char const *const SAVING_NOT_ALLOWED_MSG = "Saving is not allowed at this time.";
+char const *const RESTORING_NOT_ALLOWED_MSG = "Restoring is not allowed at this time.";
+char const *const INV_EMPTY_MSG = "You have nothing in your possesion.";
+
+char const *const QUIT_CONFIRM_MSG = "Do you want to quit playing this game?";
+char const *const RESTART_MSG = "Do you want to restart this game?";
+char const *const GAME_PAUSED_MSG = "Game is paused.";
+char const *const OK_BTN_STRING = " Ok ";
+char const *const CANCEL_BTN_STRING = "Cancel";
+char const *const QUIT_BTN_STRING = " Quit ";
+char const *const RESTART_BTN_STRING = "Restart";
+char const *const SAVE_BTN_STRING = "Save";
+char const *const RESTORE_BTN_STRING = "Restore";
+char const *const SOUND_BTN_STRING = "Sound";
+char const *const RESUME_BTN_STRING = " Resume \rplay";
+char const *const LOOK_BTN_STRING = "Look";
+char const *const PICK_BTN_STRING = "Pick";
namespace Ringworld {
// Dialog resources
-const char *HELP_MSG = "Ringworld\rRevenge of the Patriarch\x14\rScummVM Version\r\r\
+char const *const HELP_MSG = "Ringworld\rRevenge of the Patriarch\x14\rScummVM Version\r\r\
\x01 Keyboard shortcuts...\rF2 - Sound options\rF3 - Quit\r\
F4 - Restart\rF5 - Save game\rF7 - Restore Game\rF10 - Pause game";
-const char *WATCH_INTRO_MSG = "Do you wish to watch the introduction?";
-const char *START_PLAY_BTN_STRING = " Start Play ";
-const char *INTRODUCTION_BTN_STRING = "Introduction";
+char const *const WATCH_INTRO_MSG = "Do you wish to watch the introduction?";
+char const *const START_PLAY_BTN_STRING = " Start Play ";
+char const *const INTRODUCTION_BTN_STRING = "Introduction";
+char const *const OPTIONS_MSG = "\x01Options...";
// Scene specific resources
-const char *EXIT_MSG = " EXIT ";
-const char *SCENE6100_CAREFUL = "Be careful! The probe cannot handle too much of that.";
-const char *SCENE6100_TOUGHER = "Hey! This is tougher than it looks!";
-const char *SCENE6100_ONE_MORE_HIT = "You had better be more careful. One more hit like that \
+char const *const EXIT_MSG = " EXIT ";
+char const *const SCENE6100_CAREFUL = "Be careful! The probe cannot handle too much of that.";
+char const *const SCENE6100_TOUGHER = "Hey! This is tougher than it looks!";
+char const *const SCENE6100_ONE_MORE_HIT = "You had better be more careful. One more hit like that \
and the probe may be destroyed.";
-const char *SCENE6100_DOING_BEST = "I'm doing the best I can. I just hope it holds together!";
-const char *SCENE6100_REPAIR = "\r\rQuinn and Seeker repair the probe....";
-const char *SCENE6100_ROCKY_AREA = "The rocky area should be directly ahead of you. Do you see it?";
-const char *SCENE6100_REPLY = "Yes. Now if I can just avoid those sunbeams.";
-const char *SCENE6100_TAKE_CONTROLS = "You had better take the controls Seeker. My hands are sweating.";
-const char *SCENE6100_SURPRISE = "You surprise me Quinn. I would have thought you of hardier stock.";
-const char *SCENE6100_SWEAT = "Humans sweat, Kzin twitch their tail. What's the difference?";
-const char *SCENE6100_VERY_WELL = "Very well. I will retrieve the stasis box and return the probe. \
+char const *const SCENE6100_DOING_BEST = "I'm doing the best I can. I just hope it holds together!";
+char const *const SCENE6100_REPAIR = "\r\rQuinn and Seeker repair the probe....";
+char const *const SCENE6100_ROCKY_AREA = "The rocky area should be directly ahead of you. Do you see it?";
+char const *const SCENE6100_REPLY = "Yes. Now if I can just avoid those sunbeams.";
+char const *const SCENE6100_TAKE_CONTROLS = "You had better take the controls Seeker. My hands are sweating.";
+char const *const SCENE6100_SURPRISE = "You surprise me Quinn. I would have thought you of hardier stock.";
+char const *const SCENE6100_SWEAT = "Humans sweat, Kzin twitch their tail. What's the difference?";
+char const *const SCENE6100_VERY_WELL = "Very well. I will retrieve the stasis box and return the probe. \
Wait for it's return in the lander bay.";
-const char *DEMO_HELP_MSG = " Help...\rF2 - Sound Options\rF3 - Exit demo\r\rPress ENTER\rto continue";
-const char *DEMO_PAUSED_MSG = "Ringworld\x14 demo is paused";
-const char *DEMO_EXIT_MSG = "Press ENTER to resume the Ringworld\x14 demo. Press ESC to exit";
-const char *EXIT_BTN_STRING = "Exit";
-const char *DEMO_BTN_STRING = "Demo";
-const char *DEMO_RESUME_BTN_STRING = "Resume";
+char const *const DEMO_HELP_MSG = " Help...\rF2 - Sound Options\rF3 - Exit demo\r\rPress ENTER\rto continue";
+char const *const DEMO_PAUSED_MSG = "Ringworld\x14 demo is paused";
+char const *const DEMO_EXIT_MSG = "Press ENTER to resume the Ringworld\x14 demo. Press ESC to exit";
+char const *const EXIT_BTN_STRING = "Exit";
+char const *const DEMO_BTN_STRING = "Demo";
+char const *const DEMO_RESUME_BTN_STRING = "Resume";
} // End of namespace Ringworld
namespace BlueForce {
// Dialog resources
-const char *HELP_MSG = "Blue Force\x14\rScummVM Version\r\r\
+char const *const HELP_MSG = "Blue Force\x14\rScummVM Version\r\r\
Keyboard shortcuts...\rF2 - Sound options\rF3 - Quit\r\
F4 - Restart\rF5 - Save game\rF7 - Restore Game\rF10 - Pause game";
-const char *WATCH_INTRO_MSG = "Do you wish to watch the introduction?";
-const char *START_PLAY_BTN_STRING = " Play ";
-const char *INTRODUCTION_BTN_STRING = " Watch ";
+char const *const WATCH_INTRO_MSG = "Do you wish to watch the introduction?";
+char const *const START_PLAY_BTN_STRING = " Play ";
+char const *const INTRODUCTION_BTN_STRING = " Watch ";
+char const *const OPTIONS_MSG = "Options...";
// Blue Force general messages
-const char *BF_NAME = "Blue Force";
-const char *BF_COPYRIGHT = " Copyright, 1993 Tsunami Media, Inc.";
-const char *BF_ALL_RIGHTS_RESERVED = "All Rights Reserved";
-const char *BF_19840518 = "May 18, 1984";
-const char *BF_19840515 = "May 15, 1984";
-const char *BF_3_DAYS = "Three days later";
-const char *BF_11_YEARS = "Eleven years later.";
-const char *BF_NEXT_DAY = "The Next Day";
-const char *BF_ACADEMY = "Here we are at the Academy";
+char const *const BF_NAME = "Blue Force";
+char const *const BF_COPYRIGHT = " Copyright, 1993 Tsunami Media, Inc.";
+char const *const BF_ALL_RIGHTS_RESERVED = "All Rights Reserved";
+char const *const BF_19840518 = "May 18, 1984";
+char const *const BF_19840515 = "May 15, 1984";
+char const *const BF_3_DAYS = "Three days later";
+char const *const BF_11_YEARS = "Eleven years later.";
+char const *const BF_NEXT_DAY = "The Next Day";
+char const *const BF_ACADEMY = "Here we are at the Academy";
// Scene 50 hotspots
-const char *GRANDMA_FRANNIE = "Grandma Frannie";
-const char *MARINA = "Marina";
-const char *POLICE_DEPARTMENT = "Police Department";
-const char *TONYS_BAR = "Tony's Bar";
-const char *CHILD_PROTECTIVE_SERVICES = "Child Protective Services";
-const char *ALLEY_CAT = "Alley Cat";
-const char *CITY_HALL_JAIL = "City Hall & Jail";
-const char *JAMISON_RYAN = "Jamison & Ryan";
-const char *BIKINI_HUT = "Bikini Hut";
+char const *const GRANDMA_FRANNIE = "Grandma Frannie";
+char const *const MARINA = "Marina";
+char const *const POLICE_DEPARTMENT = "Police Department";
+char const *const TONYS_BAR = "Tony's Bar";
+char const *const CHILD_PROTECTIVE_SERVICES = "Child Protective Services";
+char const *const ALLEY_CAT = "Alley Cat";
+char const *const CITY_HALL_JAIL = "City Hall & Jail";
+char const *const JAMISON_RYAN = "Jamison & Ryan";
+char const *const BIKINI_HUT = "Bikini Hut";
// Scene 60 radio messages
-const char *RADIO_BTN_LIST[8] = { "10-2 ", "10-4 ", "10-13", "10-15", "10-27", "10-35", "10-97", "10-98" };
+char const *const RADIO_BTN_LIST[8] = { "10-2 ", "10-4 ", "10-13", "10-15", "10-27", "10-35", "10-97", "10-98" };
// Scene 570 computer messageS
-const char *SCENE570_PASSWORD = "PASSWORD -> ";
-const char *SCENE570_C_DRIVE = "C:\\";
-const char *SCENE570_RING = "RING";
-const char *SCENE570_PROTO = "PROTO";
-const char *SCENE570_WACKY = "WACKY";
-const char *SCENE570_COBB = "COBB";
-const char *SCENE570_LETTER = "LETTER";
-const char *SCENE570_RINGEXE = "RINGEXE";
-const char *SCENE570_RINGDATA = "RINGDATA";
-const char *SCENE570_PROTOEXE = "PROTOEXE";
-const char *SCENE570_PROTODATA = "PROTODATA";
-const char *SCENE570_WACKYEXE = "WACKYEXE";
-const char *SCENE570_WACKYDATA = "WACKYDATA";
+char const *const SCENE570_PASSWORD = "PASSWORD -> ";
+char const *const SCENE570_C_DRIVE = "C:\\";
+char const *const SCENE570_RING = "RING";
+char const *const SCENE570_PROTO = "PROTO";
+char const *const SCENE570_WACKY = "WACKY";
+char const *const SCENE570_COBB = "COBB";
+char const *const SCENE570_LETTER = "LETTER";
+char const *const SCENE570_RINGEXE = "RINGEXE";
+char const *const SCENE570_RINGDATA = "RINGDATA";
+char const *const SCENE570_PROTOEXE = "PROTOEXE";
+char const *const SCENE570_PROTODATA = "PROTODATA";
+char const *const SCENE570_WACKYEXE = "WACKYEXE";
+char const *const SCENE570_WACKYDATA = "WACKYDATA";
// Scene 180 messages
-const char *THE_NEXT_DAY = "The Next Day";
+char const *const THE_NEXT_DAY = "The Next Day";
} // End of namespace BlueForce
+namespace Ringworld2 {
+
+char const *const CONSOLE125_MESSAGES[] = {
+ NULL, "Select Language", "Computer Services", "Food Services", "Entertainment Services",
+ "Main Menu", "Exit Menu", "Previous Menu", "Interworld", "Hero's Tongue", "Personal Log",
+ "Database", "Starchart", "Iso-Opto Disk Reader", "Eject Disk", "Meals", "Snacks",
+ "Beverages", "Human Basic Snacks", "Kzin Basic Snacks", "Hot Beverages", "Cold Beverages",
+ "Music", "Outpost Alpha", " ", " ", "Done", "A-G", "H-O", "P-S", "T-Z", "Tchaikovsky",
+ "Mozart", "Bach", "Rossini"
+};
+
+char const *const CONSOLE325_MESSAGES[] = {
+ NULL, "Select Language", "Database", "Star Chart", "Scan Ops", "Deep Scan",
+ "Short Scan", "Main Menu", "Previous Menu", "Exit Menu", "Interworld", "Hero's Tongue",
+ "Done", " ", " ", "Passive Enabled", "Active Enabled", "Technological", "Biological",
+ "Geographical", "Astronomical", "Dipole Anomaly Sweep", "Structural Analysis",
+ "A-G", "N-O", "P-S", "T-Z", "Tchaikovsky", "Mozart", "Bach", "Rossini"
+};
+
+// Scene 825 Autodoc messages
+char const *const MAIN_MENU = "main menu";
+char const *const DIAGNOSIS = "diagnosis";
+char const *const ADVANCED_PROCEDURES = "advanced procedures";
+char const *const VITAL_SIGNS = "vital signs";
+char const *const OPEN_DOOR = "open door";
+char const *const TREATMENTS = "treatments";
+char const *const NO_MALADY_DETECTED = "no malady detected";
+char const *const NO_TREATMENT_REQUIRED = "no treatment required";
+char const *const ACCESS_CODE_REQUIRED = "access code required";
+char const *const INVALID_ACCESS_CODE = "invalid access code";
+char const *const FOREIGN_OBJECT_EXTRACTED = "foreign object extracted";
+
+char const *const HELP_MSG = "\x1\rRETURN TO\r RINGWORLD\x14";
+char const *const CHAR_TITLE = "\x01Select Character:";
+char const *const CHAR_QUINN_MSG = " Quinn ";
+char const *const CHAR_SEEKER_MSG = " Seeker ";
+char const *const CHAR_MIRANDA_MSG = "Miranda";
+char const *const CHAR_CANCEL_MSG = " Cancel ";
+
+char const *const GAME_VERSION = "ScummVM Version";
+char const *const SOUND_OPTIONS = "Sound options";
+char const *const QUIT_GAME = "Quit";
+char const *const RESTART_GAME = "Restart";
+char const *const SAVE_GAME = "Save game";
+char const *const RESTORE_GAME = "Restore game";
+char const *const SHOW_CREDITS = "Show credits";
+char const *const PAUSE_GAME = "Pause game";
+char const *const RESUME_PLAY = " Resume play ";
+char const *const F2 = "F2";
+char const *const F3 = "F3";
+char const *const F4 = "F4";
+char const *const F5 = "F5";
+char const *const F7 = "F7";
+char const *const F8 = "F8";
+char const *const F10 = "F10";
+
+char const *const DONE_MSG = "Done";
+char const *const YES_MSG = " Yes ";
+char const *const NO_MSG = " No ";
+char const *const USE_INTERCEPTOR = "Do you want to use your interceptor card?";
+char const *const USE_DOUBLE_AGENT = "Do you want to use your double agent?";
+char const *const NEED_INSTRUCTIONS = "Do you want instructions?";
+char const *const WRONG_ANSWER_MSG = "Wrong respond value sent.";
+const byte k562CC[] = {
+ 20, 7, 41, 6,
+ 3, 6, 42, 11,
+ 10, 15, 43, 6,
+ 15, 1, 44, 7,
+ 1, 1, 2, 1,
+ 1, 1, 21, 12,
+ 5, 1, 36, 1,
+ 5, 1, 28, 2,
+ 9, 1, 10, 7,
+ 9, 1, 12, 10,
+ 19, 1, 10, 8,
+ 19, 1, 2, 13,
+ 25, 1, 31, 1,
+ 27, 1, 15, 6,
+ 27, 1, 20, 7,
+ 28, 1, 24, 4,
+ 6, 2, 22, 1,
+ 6, 2, 16, 5,
+ 12, 2, 40, 1,
+ 12, 2, 6, 11,
+ 18, 2, 21, 5,
+ 20, 5, 19, 4,
+ 20, 5, 18, 8,
+ 1, 6, 20, 11,
+ 1, 6, 18, 15,
+ 1, 6, 16, 4,
+ 7, 6, 6, 16,
+ 8, 6, 23, 9,
+ 8, 6, 38, 10,
+ 8, 6, 14, 13,
+ 8, 6, 6, 14,
+ 8, 6, 11, 15,
+ 10, 6, 3, 1,
+ 10, 6, 8, 2,
+ 10, 6, 13, 3,
+ 10, 6, 6, 15,
+ 17, 6, 4, 15,
+ 5, 7, 26, 11,
+ 25, 7, 27, 3,
+ 28, 7, 21, 5,
+ 2, 8, 23, 5,
+ 14, 8, 21, 5,
+ 14, 8, 22, 16,
+ 22, 8, 34, 3,
+ 22, 8, 24, 7,
+ 6, 9, 38, 5,
+ 6, 9, 32, 6,
+ 6, 9, 18, 7,
+ 9, 9, 34, 15,
+ 9, 9, 35, 16,
+ 18, 9, 1, 5,
+ 18, 9, 24, 11,
+ 26, 9, 21, 10,
+ 1, 10, 21, 9,
+ 1, 10, 12, 13,
+ 11, 10, 21, 16,
+ 15, 10, 8, 1,
+ 15, 10, 12, 6,
+ 15, 10, 14, 10,
+ 20, 10, 14, 10,
+ 20, 10, 39, 11,
+ 3, 11, 5, 9,
+ 3, 11, 4, 13,
+ 5, 11, 32, 7,
+ 5, 11, 20, 8,
+ 5, 11, 20, 11,
+ 7, 12, 22, 11,
+ 7, 12, 2, 12,
+ 7, 12, 23, 16,
+ 8, 12, 25, 9,
+ 13, 12, 23, 10,
+ 16, 12, 3, 11,
+ 17, 12, 25, 10,
+ 17, 12, 28, 15,
+ 25, 12, 8, 15,
+ 26, 12, 7, 14,
+ 1, 13, 8, 6,
+ 10, 13, 28, 11,
+ 21, 13, 25, 13,
+ 21, 13, 24, 16,
+ 25, 13, 25, 3,
+ 5, 14, 17, 6,
+ 5, 14, 23, 16,
+ 12, 14, 36, 15,
+ 12, 14, 17, 16,
+ 13, 14, 40, 13,
+ 13, 14, 38, 14,
+ 19, 14, 18, 10,
+ 2, 15, 4, 14,
+ 8, 15, 1, 13,
+ 12, 15, 21, 4,
+ 12, 15, 27, 7,
+ 12, 15, 28, 8,
+ 13, 15, 34, 1,
+ 13, 15, 31, 5,
+ 14, 15, 21, 16,
+ 15, 15, 29, 1,
+ 15, 15, 23, 13,
+ 25, 15, 24, 6,
+ 25, 15, 23, 11,
+ 28, 15, 8, 6,
+ 28, 15, 9, 10,
+ 1, 16, 1, 1,
+ 1, 16, 22, 5,
+ 7, 16, 3, 4,
+ 8, 16, 7, 1,
+ 11, 17, 4, 12,
+ 18, 17, 1, 13,
+ 22, 17, 21, 6,
+ 22, 17, 28, 15,
+ 27, 17, 12, 7,
+ 27, 17, 8, 8,
+ 27, 17, 14, 11,
+ 27, 17, 18, 15,
+ 27, 17, 2, 16,
+ 6, 18, 24, 7,
+ 14, 18, 21, 13,
+ 27, 18, 38, 4,
+ 28, 18, 20, 1,
+ 1, 18, 11, 15,
+ 9, 18, 7, 1,
+ 9, 18, 13, 12,
+ 16, 18, 32, 10,
+ 16, 18, 25, 13,
+ 16, 18, 31, 14,
+ 25, 18, 20, 7,
+ 28, 18, 21, 1
+};
+
+const byte k5A4D6[] = {
+ 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3,
+ 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18,
+ 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19,
+ 7, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12,
+ 6, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12,
+ 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12,
+ 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12,
+ 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12,
+ 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12,
+ 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12,
+ 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12,
+ 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12,
+ 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12,
+ 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12,
+ 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12,
+ 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12,
+ 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12,
+ 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12,
+ 13, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 14
+};
+
+const byte k5A72E[] = {0, 98, 135, 183, 229, 81, 133, 185, 235, 75, 131, 187, 241, 70, 129, 190, 247};
+const byte k5A73F[] = {0, 42, 42, 42, 42, 67, 67, 67, 67, 92, 92, 92, 92, 116, 116, 116, 116};
+const byte k5A750[] = {
+ 9, 10, 7, 13, 7, 8, 9, 7, 9, 10,
+ 2, 3, 3, 2, 2, 2, 4, 3, 3, 4,
+ 3, 2, 3, 4, 3, 8, 10, 4, 0
+};
+const byte k5A76D[] = {
+ 3, 3, 3, 4, 3, 3, 3, 3, 1, 3,
+ 3, 3, 3, 7, 3, 7, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3
+};
+const byte k5A78A[] = {0, 8, 15, 16, 12, 7, 18, 17, 13, 6, 19, 20, 14, 5, 11, 10, 9};
+const byte k5A79B[] = {
+ 23, 3, 1,
+ 23, 4, 1,
+ 26, 3, 1,
+ 26, 4, 1,
+ 15, 16, 2,
+ 2, 16, 3,
+ 3, 16, 4,
+ 10, 7, 5,
+ 11, 7, 6,
+ 3, 0, 7,
+ 4, 0, 8,
+ 24, 11, 9,
+ 25, 11, 10,
+ 12, 8, 11,
+ 9, 11, 12
+};
+
+const byte k5A7F6[] = {
+ 4, 11, 6,
+ 5, 14, 5,
+ 5, 11, 6,
+ 5, 7, 5,
+ 6, 9, 6,
+ 7, 16, 7,
+ 7, 12, 7,
+ 8, 6, 5,
+ 9, 9, 7,
+ 10, 13, 9,
+ 10, 6, 8,
+ 11, 10, 9,
+ 12, 15, 10,
+ 13, 12, 11,
+ 14, 8, 9,
+ 15, 16, 1,
+ 15, 10, 11
+};
+
+} // End of namespace Ringworld2
+
} // End of namespace TsAGE
diff --git a/engines/tsage/staticres.h b/engines/tsage/staticres.h
index 203fa1481d..e3daf73333 100644
--- a/engines/tsage/staticres.h
+++ b/engines/tsage/staticres.h
@@ -31,118 +31,186 @@ extern const byte CURSOR_ARROW_DATA[];
extern const byte CURSOR_WALK_DATA[];
-extern const char *LOOK_SCENE_HOTSPOT;
-extern const char *USE_SCENE_HOTSPOT;
-extern const char *TALK_SCENE_HOTSPOT;
-extern const char *SPECIAL_SCENE_HOTSPOT;
-extern const char *DEFAULT_SCENE_HOTSPOT;
-extern const char *SAVE_ERROR_MSG;
-extern const char *SAVING_NOT_ALLOWED_MSG;
-extern const char *RESTORING_NOT_ALLOWED_MSG;
+extern char const *const LOOK_SCENE_HOTSPOT;
+extern char const *const USE_SCENE_HOTSPOT;
+extern char const *const TALK_SCENE_HOTSPOT;
+extern char const *const SPECIAL_SCENE_HOTSPOT;
+extern char const *const DEFAULT_SCENE_HOTSPOT;
+extern char const *const SAVE_ERROR_MSG;
+extern char const *const SAVING_NOT_ALLOWED_MSG;
+extern char const *const RESTORING_NOT_ALLOWED_MSG;
// Dialogs
-extern const char *QUIT_CONFIRM_MSG;
-extern const char *RESTART_MSG;
-extern const char *GAME_PAUSED_MSG;
-extern const char *OPTIONS_MSG;
-extern const char *OK_BTN_STRING;
-extern const char *CANCEL_BTN_STRING;
-extern const char *QUIT_BTN_STRING;
-extern const char *RESTART_BTN_STRING;
-extern const char *SAVE_BTN_STRING;
-extern const char *RESTORE_BTN_STRING;
-extern const char *SOUND_BTN_STRING;
-extern const char *RESUME_BTN_STRING;
-extern const char *LOOK_BTN_STRING;
-extern const char *PICK_BTN_STRING;
-extern const char *INV_EMPTY_MSG;
+extern char const *const QUIT_CONFIRM_MSG;
+extern char const *const RESTART_MSG;
+extern char const *const GAME_PAUSED_MSG;
+extern char const *const OK_BTN_STRING;
+extern char const *const CANCEL_BTN_STRING;
+extern char const *const QUIT_BTN_STRING;
+extern char const *const RESTART_BTN_STRING;
+extern char const *const SAVE_BTN_STRING;
+extern char const *const RESTORE_BTN_STRING;
+extern char const *const SOUND_BTN_STRING;
+extern char const *const RESUME_BTN_STRING;
+extern char const *const LOOK_BTN_STRING;
+extern char const *const PICK_BTN_STRING;
+extern char const *const INV_EMPTY_MSG;
namespace Ringworld {
// Dialog resources
-extern const char *HELP_MSG;
-extern const char *WATCH_INTRO_MSG;
-extern const char *START_PLAY_BTN_STRING;
-extern const char *INTRODUCTION_BTN_STRING;
+extern char const *const HELP_MSG;
+extern char const *const WATCH_INTRO_MSG;
+extern char const *const START_PLAY_BTN_STRING;
+extern char const *const INTRODUCTION_BTN_STRING;
+extern char const *const OPTIONS_MSG;
// Scene specific resources
-extern const char *EXIT_MSG;
-extern const char *SCENE6100_CAREFUL;
-extern const char *SCENE6100_TOUGHER;
-extern const char *SCENE6100_ONE_MORE_HIT;
-extern const char *SCENE6100_DOING_BEST;
-extern const char *SCENE6100_REPAIR;
-extern const char *SCENE6100_ROCKY_AREA;
-extern const char *SCENE6100_REPLY;
-extern const char *SCENE6100_TAKE_CONTROLS;
-extern const char *SCENE6100_SURPRISE;
-extern const char *SCENE6100_SWEAT;
-extern const char *SCENE6100_VERY_WELL;
+extern char const *const EXIT_MSG;
+extern char const *const SCENE6100_CAREFUL;
+extern char const *const SCENE6100_TOUGHER;
+extern char const *const SCENE6100_ONE_MORE_HIT;
+extern char const *const SCENE6100_DOING_BEST;
+extern char const *const SCENE6100_REPAIR;
+extern char const *const SCENE6100_ROCKY_AREA;
+extern char const *const SCENE6100_REPLY;
+extern char const *const SCENE6100_TAKE_CONTROLS;
+extern char const *const SCENE6100_SURPRISE;
+extern char const *const SCENE6100_SWEAT;
+extern char const *const SCENE6100_VERY_WELL;
// Demo messages
-extern const char *DEMO_HELP_MSG;
-extern const char *DEMO_PAUSED_MSG;
-extern const char *DEMO_HELP_MSG;
-extern const char *DEMO_PAUSED_MSG;
-extern const char *DEMO_EXIT_MSG;
-extern const char *EXIT_BTN_STRING;
-extern const char *DEMO_BTN_STRING;
-extern const char *DEMO_RESUME_BTN_STRING;
+extern char const *const DEMO_HELP_MSG;
+extern char const *const DEMO_PAUSED_MSG;
+extern char const *const DEMO_HELP_MSG;
+extern char const *const DEMO_PAUSED_MSG;
+extern char const *const DEMO_EXIT_MSG;
+extern char const *const EXIT_BTN_STRING;
+extern char const *const DEMO_BTN_STRING;
+extern char const *const DEMO_RESUME_BTN_STRING;
} // End of namespace Ringworld
namespace BlueForce {
// Dialog resources
-extern const char *HELP_MSG;
-extern const char *WATCH_INTRO_MSG;
-extern const char *START_PLAY_BTN_STRING;
-extern const char *INTRODUCTION_BTN_STRING;
+extern char const *const HELP_MSG;
+extern char const *const WATCH_INTRO_MSG;
+extern char const *const START_PLAY_BTN_STRING;
+extern char const *const INTRODUCTION_BTN_STRING;
+extern char const *const OPTIONS_MSG;
// Blue Force messages
-extern const char *BF_NAME;
-extern const char *BF_COPYRIGHT;
-extern const char *BF_ALL_RIGHTS_RESERVED;
-extern const char *BF_19840518;
-extern const char *BF_19840515;
-extern const char *BF_3_DAYS;
-extern const char *BF_11_YEARS;
-extern const char *BF_NEXT_DAY;
-extern const char *BF_ACADEMY;
+extern char const *const BF_NAME;
+extern char const *const BF_COPYRIGHT;
+extern char const *const BF_ALL_RIGHTS_RESERVED;
+extern char const *const BF_19840518;
+extern char const *const BF_19840515;
+extern char const *const BF_3_DAYS;
+extern char const *const BF_11_YEARS;
+extern char const *const BF_NEXT_DAY;
+extern char const *const BF_ACADEMY;
// Scene 50 tooltips
-extern const char *GRANDMA_FRANNIE;
-extern const char *MARINA;
-extern const char *POLICE_DEPARTMENT;
-extern const char *TONYS_BAR;
-extern const char *CHILD_PROTECTIVE_SERVICES;
-extern const char *ALLEY_CAT;
-extern const char *CITY_HALL_JAIL;
-extern const char *JAMISON_RYAN;
-extern const char *BIKINI_HUT;
-
-extern const char *SCENE570_PASSWORD;
-extern const char *SCENE570_C_DRIVE;
-extern const char *SCENE570_RING;
-extern const char *SCENE570_PROTO;
-extern const char *SCENE570_WACKY;
-extern const char *SCENE570_COBB;
-extern const char *SCENE570_LETTER;
-extern const char *SCENE570_RINGEXE;
-extern const char *SCENE570_RINGDATA;
-extern const char *SCENE570_PROTOEXE;
-extern const char *SCENE570_PROTODATA;
-extern const char *SCENE570_WACKYEXE;
-extern const char *SCENE570_WACKYDATA;
+extern char const *const GRANDMA_FRANNIE;
+extern char const *const MARINA;
+extern char const *const POLICE_DEPARTMENT;
+extern char const *const TONYS_BAR;
+extern char const *const CHILD_PROTECTIVE_SERVICES;
+extern char const *const ALLEY_CAT;
+extern char const *const CITY_HALL_JAIL;
+extern char const *const JAMISON_RYAN;
+extern char const *const BIKINI_HUT;
+
+extern char const *const SCENE570_PASSWORD;
+extern char const *const SCENE570_C_DRIVE;
+extern char const *const SCENE570_RING;
+extern char const *const SCENE570_PROTO;
+extern char const *const SCENE570_WACKY;
+extern char const *const SCENE570_COBB;
+extern char const *const SCENE570_LETTER;
+extern char const *const SCENE570_RINGEXE;
+extern char const *const SCENE570_RINGDATA;
+extern char const *const SCENE570_PROTOEXE;
+extern char const *const SCENE570_PROTODATA;
+extern char const *const SCENE570_WACKYEXE;
+extern char const *const SCENE570_WACKYDATA;
// Scene 60 radio dispatch buttons
-extern const char *RADIO_BTN_LIST[8];
+extern char const *const RADIO_BTN_LIST[8];
// Scene 180 message
-extern const char *THE_NEXT_DAY;
+extern char const *const THE_NEXT_DAY;
} // End of namespace BlueForce
+namespace Ringworld2 {
+
+// Scene 125 - Console messages
+extern char const *const CONSOLE125_MESSAGES[];
+
+// Scene 325 - Console messages
+extern char const *const CONSOLE325_MESSAGES[];
+
+// Scene 825 - Autodoc Messages
+extern char const *const MAIN_MENU;
+extern char const *const DIAGNOSIS;
+extern char const *const ADVANCED_PROCEDURES;
+extern char const *const VITAL_SIGNS;
+extern char const *const OPEN_DOOR;
+extern char const *const TREATMENTS;
+extern char const *const NO_MALADY_DETECTED;
+extern char const *const NO_TREATMENT_REQUIRED;
+extern char const *const ACCESS_CODE_REQUIRED;
+extern char const *const INVALID_ACCESS_CODE;
+extern char const *const FOREIGN_OBJECT_EXTRACTED;
+
+// Dialog messages
+extern char const *const HELP_MSG;
+extern char const *const CHAR_TITLE;
+extern char const *const CHAR_QUINN_MSG;
+extern char const *const CHAR_SEEKER_MSG;
+extern char const *const CHAR_MIRANDA_MSG;
+extern char const *const CHAR_CANCEL_MSG;
+
+extern char const *const GAME_VERSION;
+extern char const *const SOUND_OPTIONS;
+extern char const *const QUIT_GAME;
+extern char const *const RESTART_GAME;
+extern char const *const SAVE_GAME;
+extern char const *const RESTORE_GAME;
+extern char const *const SHOW_CREDITS;
+extern char const *const PAUSE_GAME;
+extern char const *const RESUME_PLAY;
+extern char const *const F2;
+extern char const *const F3;
+extern char const *const F4;
+extern char const *const F5;
+extern char const *const F7;
+extern char const *const F8;
+extern char const *const F10;
+
+extern char const *const DONE_MSG;
+extern char const *const YES_MSG;
+extern char const *const NO_MSG;
+extern char const *const USE_INTERCEPTOR;
+extern char const *const USE_DOUBLE_AGENT;
+extern char const *const NEED_INSTRUCTIONS;
+extern char const *const WRONG_ANSWER_MSG;
+
+// Scene 1550 arrays of constants
+extern const byte k562CC[];
+extern const byte k5A4D6[];
+extern const byte k5A72E[];
+extern const byte k5A73F[];
+extern const byte k5A750[];
+extern const byte k5A76D[];
+extern const byte k5A78A[];
+extern const byte k5A79B[];
+extern const byte k5A7F6[];
+
+} // End of namespace Ringworld2
+
} // End of namespace TsAGE
#endif
diff --git a/engines/tsage/tsage.cpp b/engines/tsage/tsage.cpp
index 7e7198fc2b..40f4dfcfd2 100644
--- a/engines/tsage/tsage.cpp
+++ b/engines/tsage/tsage.cpp
@@ -38,7 +38,14 @@ TSageEngine::TSageEngine(OSystem *system, const tSageGameDescription *gameDesc)
_gameDescription(gameDesc) {
g_vm = this;
DebugMan.addDebugChannel(kRingDebugScripts, "scripts", "Scripts debugging");
- _debugger = new Debugger();
+ if (g_vm->getFeatures() & GF_DEMO)
+ _debugger = new DemoDebugger();
+ else if (g_vm->getGameID() == GType_Ringworld)
+ _debugger = new RingworldDebugger();
+ else if (g_vm->getGameID() == GType_BlueForce)
+ _debugger = new BlueForceDebugger();
+ else if (g_vm->getGameID() == GType_Ringworld2)
+ _debugger = new Ringworld2Debugger();
}
Common::Error TSageEngine::init() {
@@ -61,6 +68,9 @@ bool TSageEngine::hasFeature(EngineFeature f) const {
}
void TSageEngine::initialize() {
+ // Set up the correct graphics mode
+ init();
+
g_saver = new Saver();
// Set up the resource manager
@@ -97,7 +107,7 @@ void TSageEngine::initialize() {
// Reset all global variables
R2_GLOBALS.reset();
- }
+ }
g_globals->gfxManager().setDefaults();
diff --git a/engines/tsage/tsage.h b/engines/tsage/tsage.h
index eb36cf0790..41179c4915 100644
--- a/engines/tsage/tsage.h
+++ b/engines/tsage/tsage.h
@@ -54,7 +54,8 @@ enum {
enum {
kRingDebugScripts = 1 << 0,
ktSageSound = 1 << 1,
- ktSageCore = 1 << 2
+ ktSageCore = 1 << 2,
+ ktSageDebugGraphics = 1 << 3
};
struct tSageGameDescription;
diff --git a/engines/tsage/user_interface.cpp b/engines/tsage/user_interface.cpp
index b7f96b3806..10cb6961dc 100644
--- a/engines/tsage/user_interface.cpp
+++ b/engines/tsage/user_interface.cpp
@@ -25,6 +25,7 @@
#include "tsage/tsage.h"
#include "tsage/blue_force/blueforce_dialogs.h"
#include "tsage/blue_force/blueforce_logic.h"
+#include "tsage/ringworld2/ringworld2_logic.h"
namespace TsAGE {
@@ -70,12 +71,27 @@ void UIQuestion::process(Event &event) {
}
void UIQuestion::showDescription(CursorType cursor) {
- if (cursor == INV_FOREST_RAP) {
- // Forest rap item has a graphical display
- showItem(5, 1, 1);
- } else {
- // Display object description
- SceneItem::display2(9001, (int)cursor);
+ switch (g_vm->getGameID()) {
+ case GType_BlueForce:
+ if (cursor == INV_FOREST_RAP) {
+ // Forest rap item has a graphical display
+ showItem(5, 1, 1);
+ } else {
+ // Display object description
+ SceneItem::display2(9001, (int)cursor);
+ }
+ break;
+ case GType_Ringworld2:
+ if ((cursor == R2_COM_SCANNER) || (cursor == R2_COM_SCANNER_2)) {
+ // Show communicator
+ warning("TODO: Communicator");
+ } else {
+ // Show object description
+ SceneItem::display2(3, (int)cursor);
+ }
+ break;
+ default:
+ break;
}
}
@@ -96,16 +112,16 @@ void UIQuestion::showItem(int resNum, int rlbNum, int frameNum) {
imgRect.center(SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2);
// Save the area behind where the image will be displayed
- GfxSurface *savedArea = Surface_getArea(BF_GLOBALS.gfxManager().getSurface(), imgRect);
+ GfxSurface *savedArea = Surface_getArea(GLOBALS.gfxManager().getSurface(), imgRect);
// Draw the image
- BF_GLOBALS.gfxManager().copyFrom(objImage, imgRect);
+ GLOBALS.gfxManager().copyFrom(objImage, imgRect);
// Wait for a press
- BF_GLOBALS._events.waitForPress();
+ GLOBALS._events.waitForPress();
// Restore the old area
- BF_GLOBALS.gfxManager().copyFrom(*savedArea, imgRect);
+ GLOBALS.gfxManager().copyFrom(*savedArea, imgRect);
delete savedArea;
}
@@ -183,9 +199,9 @@ void UIInventoryScroll::process(Event &event) {
// Draw the button as selected
toggle(true);
- event.handled = true;
- break;
- case EVENT_BUTTON_UP:
+ // Wait for the mouse to be released
+ BF_GLOBALS._events.waitForPress(EVENT_BUTTON_UP);
+
// Restore unselected version
toggle(false);
@@ -232,8 +248,8 @@ void UICollection::show() {
void UICollection::erase() {
if (_clearScreen) {
Rect tempRect(0, UI_INTERFACE_Y, SCREEN_WIDTH, SCREEN_HEIGHT);
- BF_GLOBALS._screenSurface.fillRect(tempRect, 0);
- BF_GLOBALS._sceneManager._scene->_backSurface.fillRect(tempRect, 0);
+ GLOBALS._screenSurface.fillRect(tempRect, 0);
+ GLOBALS._sceneManager._scene->_backSurface.fillRect(tempRect, 0);
_clearScreen = false;
}
}
@@ -253,7 +269,7 @@ void UICollection::draw() {
_objList[idx]->draw();
// Draw the resulting UI onto the screen
- BF_GLOBALS._screenSurface.copyFrom(BF_GLOBALS._sceneManager._scene->_backSurface,
+ GLOBALS._screenSurface.copyFrom(GLOBALS._sceneManager._scene->_backSurface,
Rect(0, UI_INTERFACE_Y, SCREEN_WIDTH, SCREEN_HEIGHT),
Rect(0, UI_INTERFACE_Y, SCREEN_WIDTH, SCREEN_HEIGHT));
@@ -265,9 +281,11 @@ void UICollection::draw() {
/*--------------------------------------------------------------------------*/
UIElements::UIElements(): UICollection() {
- _cursorVisage.setVisage(1, 5);
+ if (g_vm->getGameID() == GType_Ringworld2)
+ _cursorVisage.setVisage(5, 1);
+ else
+ _cursorVisage.setVisage(1, 5);
g_saver->addLoadNotifier(&UIElements::loadNotifierProc);
- _characterIndex = 0;
}
void UIElements::synchronize(Serializer &s) {
@@ -295,22 +313,21 @@ void UIElements::synchronize(Serializer &s) {
s.syncAsSint16LE(itemId);
}
}
-
- if (g_vm->getGameID() == GType_Ringworld2)
- s.syncAsSint16LE(_characterIndex);
}
void UIElements::process(Event &event) {
- if (_clearScreen && BF_GLOBALS._player._enabled && (BF_GLOBALS._sceneManager._sceneNumber != 50)) {
+ if (_clearScreen && GLOBALS._player._enabled &&
+ ((g_vm->getGameID() != GType_BlueForce) || (GLOBALS._sceneManager._sceneNumber != 50))) {
if (_bounds.contains(event.mousePos)) {
// Cursor inside UI area
if (!_cursorChanged) {
- if (BF_GLOBALS._events.isInventoryIcon()) {
+ if (GLOBALS._events.isInventoryIcon()) {
// Inventory icon being displayed, so leave alone
} else {
// Change to the inventory use cursor
- GfxSurface surface = _cursorVisage.getFrame(6);
- BF_GLOBALS._events.setCursor(surface);
+ int cursorId = (g_vm->getGameID() == GType_Ringworld2) ? 11 : 6;
+ GfxSurface surface = _cursorVisage.getFrame(cursorId);
+ GLOBALS._events.setCursor(surface);
}
_cursorChanged = true;
}
@@ -329,13 +346,13 @@ void UIElements::process(Event &event) {
} else if (_cursorChanged) {
// Cursor outside UI area, so reset as necessary
- BF_GLOBALS._events.setCursor(BF_GLOBALS._events.getCursor());
+ GLOBALS._events.setCursor(GLOBALS._events.getCursor());
_cursorChanged = false;
/*
- SceneExt *scene = (SceneExt *)BF_GLOBALS._sceneManager._scene;
+ SceneExt *scene = (SceneExt *)GLOBALS._sceneManager._scene;
if (scene->_focusObject) {
GfxSurface surface = _cursorVisage.getFrame(7);
- BF_GLOBALS._events.setCursor(surface);
+ GLOBALS._events.setCursor(surface);
}
*/
}
@@ -403,9 +420,10 @@ void UIElements::setup(const Common::Point &pt) {
// Set up the score
_score.postInit();
add(&_score);
+ break;
case GType_Ringworld2:
// Set up the character display
- _character.setup(1, 5, _characterIndex, 285, 11, 255);
+ _character.setup(1, 5, R2_GLOBALS._player._characterIndex, 285, 11, 255);
add(&_character);
break;
default:
@@ -434,7 +452,16 @@ void UIElements::add(UIElement *obj) {
* Handles updating the visual inventory in the user interface
*/
void UIElements::updateInventory() {
- _score.updateScore();
+ switch (g_vm->getGameID()) {
+ case GType_BlueForce:
+ // Update the score
+ _score.updateScore();
+ break;
+ case GType_Ringworld2:
+ _character.setFrame(R2_GLOBALS._player._characterIndex);
+ break;
+ }
+
updateInvList();
// Enable scroll buttons if the player has more than four items
@@ -459,7 +486,7 @@ void UIElements::updateInventory() {
// Loop through the inventory objects
SynchronizedList<InvObject *>::iterator i;
int objIndex = 0;
- for (i = BF_INVENTORY._itemList.begin(); i != BF_INVENTORY._itemList.end(); ++i, ++objIndex) {
+ for (i = GLOBALS._inventory->_itemList.begin(); i != GLOBALS._inventory->_itemList.end(); ++i, ++objIndex) {
InvObject *obj = *i;
// Check whether the object is in any of the four inventory slots
@@ -475,6 +502,8 @@ void UIElements::updateInventory() {
slot->setVisage(obj->_visage);
slot->setStrip(obj->_strip);
slot->setFrame(obj->_frame);
+
+ slot->reposition();
}
}
}
@@ -493,7 +522,7 @@ void UIElements::updateInvList() {
SynchronizedList<InvObject *>::iterator i;
int itemIndex = 0;
- for (i = BF_GLOBALS._inventory->_itemList.begin(); i != BF_GLOBALS._inventory->_itemList.end(); ++i, ++itemIndex) {
+ for (i = GLOBALS._inventory->_itemList.begin(); i != GLOBALS._inventory->_itemList.end(); ++i, ++itemIndex) {
InvObject *invObject = *i;
if (invObject->inInventory())
_itemList.push_back(itemIndex);
@@ -505,7 +534,7 @@ void UIElements::updateInvList() {
*/
void UIElements::addScore(int amount) {
_scoreValue += amount;
- BF_GLOBALS._sound2.play(0);
+ T2_GLOBALS._inventorySound.play(0);
updateInventory();
}
diff --git a/engines/tsage/user_interface.h b/engines/tsage/user_interface.h
index 94a2444e39..0fbfc5a00f 100644
--- a/engines/tsage/user_interface.h
+++ b/engines/tsage/user_interface.h
@@ -129,7 +129,6 @@ public:
Common::Array<int> _itemList;
Visage _cursorVisage;
UIElement _character;
- int _characterIndex;
UIElements();
virtual Common::String getClassName() { return "UIElements"; }
diff --git a/engines/tucker/detection.cpp b/engines/tucker/detection.cpp
index 77c84b281c..aeeebe6877 100644
--- a/engines/tucker/detection.cpp
+++ b/engines/tucker/detection.cpp
@@ -43,7 +43,7 @@ static const ADGameDescription tuckerGameDescriptions[] = {
Common::FR_FRA,
Common::kPlatformPC,
Tucker::kGameFlagNoSubtitles,
- GUIO1(GUIO_NONE)
+ GUIO0()
},
{
"tucker",
@@ -52,7 +52,7 @@ static const ADGameDescription tuckerGameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformPC,
Tucker::kGameFlagEncodedData,
- GUIO1(GUIO_NONE)
+ GUIO0()
},
{
"tucker",
@@ -61,7 +61,7 @@ static const ADGameDescription tuckerGameDescriptions[] = {
Common::ES_ESP,
Common::kPlatformPC,
Tucker::kGameFlagEncodedData,
- GUIO1(GUIO_NONE)
+ GUIO0()
},
{
"tucker",
@@ -70,7 +70,7 @@ static const ADGameDescription tuckerGameDescriptions[] = {
Common::DE_DEU,
Common::kPlatformPC,
Tucker::kGameFlagEncodedData,
- GUIO1(GUIO_NONE)
+ GUIO0()
},
{
"tucker",
@@ -79,7 +79,7 @@ static const ADGameDescription tuckerGameDescriptions[] = {
Common::PL_POL,
Common::kPlatformPC,
0,
- GUIO1(GUIO_NONE)
+ GUIO0()
},
{
"tucker",
@@ -88,7 +88,7 @@ static const ADGameDescription tuckerGameDescriptions[] = {
Common::CZ_CZE,
Common::kPlatformPC,
Tucker::kGameFlagEncodedData,
- GUIO1(GUIO_NONE)
+ GUIO0()
},
{
"tucker",
@@ -97,7 +97,7 @@ static const ADGameDescription tuckerGameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformPC,
ADGF_DEMO | Tucker::kGameFlagDemo,
- GUIO1(GUIO_NONE)
+ GUIO0()
},
AD_TABLE_END_MARKER
};
@@ -109,7 +109,7 @@ static const ADGameDescription tuckerDemoGameDescription = {
Common::EN_ANY,
Common::kPlatformPC,
ADGF_DEMO | Tucker::kGameFlagDemo | Tucker::kGameFlagIntroOnly,
- GUIO1(GUIO_NONE)
+ GUIO0()
};
class TuckerMetaEngine : public AdvancedMetaEngine {
diff --git a/engines/tucker/locations.cpp b/engines/tucker/locations.cpp
index 70b17e4191..f6d34c295b 100644
--- a/engines/tucker/locations.cpp
+++ b/engines/tucker/locations.cpp
@@ -2184,10 +2184,6 @@ void TuckerEngine::updateSprite_locationNum48(int i) {
} else if (_charSpeechSoundCounter > 0 && _actionCharacterNum == i) {
_spritesTable[i].needUpdate = 1;
state = 2;
- } else if (getRandomNumber() < 30000) {
- _spritesTable[i].needUpdate = 0;
- state = 2;
- _spritesTable[i].updateDelay = 5;
} else {
_spritesTable[i].needUpdate = 0;
state = 2;
@@ -2857,9 +2853,6 @@ void TuckerEngine::updateSprite_locationNum66_1(int i) {
if (_charSpeechSoundCounter > 0 && _actionCharacterNum == i) {
_spritesTable[i].needUpdate = 1;
state = 8;
- } else if (getRandomNumber() > 30000) {
- state = 10;
- _spritesTable[i].needUpdate = 0;
} else {
state = 10;
_spritesTable[i].needUpdate = 0;
@@ -2917,13 +2910,13 @@ void TuckerEngine::execData3PostUpdate_locationNum66() {
if (_spritesTable[2].flipX == 1) {
--_updateLocationXPosTable2[0];
if (_updateLocationXPosTable2[0] < -50) {
- _updateLocationXPosTable2[0] = 0;
+ _spritesTable[2].flipX = 0;
_updateLocationXPosTable2[0] = -50;
}
} else {
++_updateLocationXPosTable2[0];
if (_updateLocationXPosTable2[0] > 500) {
- _updateLocationXPosTable2[0] = 1;
+ _spritesTable[2].flipX = 1;
_updateLocationXPosTable2[0] = 500;
}
}
diff --git a/engines/tucker/saveload.cpp b/engines/tucker/saveload.cpp
index 5bc51acf84..5133bc15e8 100644
--- a/engines/tucker/saveload.cpp
+++ b/engines/tucker/saveload.cpp
@@ -49,7 +49,7 @@ static void saveOrLoadInt(Common::ReadStream &stream, int &i) {
i = stream.readSint32LE();
}
-template <class S>
+template<class S>
void TuckerEngine::saveOrLoadGameStateData(S &s) {
for (int i = 0; i < kFlagsTableSize; ++i) {
saveOrLoadInt(s, _flagsTable[i]);
diff --git a/engines/tucker/tucker.h b/engines/tucker/tucker.h
index 3daf75d44a..c9e4d986bb 100644
--- a/engines/tucker/tucker.h
+++ b/engines/tucker/tucker.h
@@ -563,7 +563,7 @@ protected:
void updateSprite_locationNum81_1(int i);
void updateSprite_locationNum82(int i);
- template <class S> void saveOrLoadGameStateData(S &s);
+ template<class S> void saveOrLoadGameStateData(S &s);
virtual Common::Error loadGameState(int num);
virtual Common::Error saveGameState(int num, const Common::String &description);
virtual bool canLoadGameStateCurrently();
diff --git a/graphics/VectorRenderer.cpp b/graphics/VectorRenderer.cpp
index 4dbcd9845f..30ef9eeeeb 100644
--- a/graphics/VectorRenderer.cpp
+++ b/graphics/VectorRenderer.cpp
@@ -78,27 +78,29 @@ void VectorRenderer::stepGetPositions(const DrawStep &step, const Common::Rect &
switch (step.xAlign) {
case Graphics::DrawStep::kVectorAlignManual:
- if (step.x >= 0) in_x = area.left + step.x;
- else in_x = area.left + area.width() + step.x; // value relative to the opposite corner.
+ if (step.x >= 0)
+ in_x = area.left + step.x + step.padding.left;
+ else
+ in_x = area.left + area.width() + step.x + step.padding.left; // value relative to the opposite corner.
break;
case Graphics::DrawStep::kVectorAlignCenter:
- in_x = area.left + (area.width() / 2) - (in_w / 2);
+ in_x = area.left + (area.width() / 2) - (in_w / 2) + ((step.padding.left + step.padding.right ) / 2);
break;
case Graphics::DrawStep::kVectorAlignLeft:
- in_x = area.left;
+ in_x = area.left + step.padding.left;
break;
case Graphics::DrawStep::kVectorAlignRight:
- in_x = area.left + area.width() - in_w;
+ in_x = area.left + area.width() - in_w - step.padding.right;
break;
default:
error("Vertical alignment in horizontal data");
}
} else {
- in_x = area.left;
+ in_x = area.left + step.padding.left;
in_w = area.width();
}
@@ -107,27 +109,29 @@ void VectorRenderer::stepGetPositions(const DrawStep &step, const Common::Rect &
switch (step.yAlign) {
case Graphics::DrawStep::kVectorAlignManual:
- if (step.y >= 0) in_y = area.top + step.y;
- else in_y = area.top + area.height() + step.y; // relative
+ if (step.y >= 0)
+ in_y = area.top + step.y + step.padding.top;
+ else
+ in_y = area.top + area.height() + step.y + step.padding.top; // relative
break;
case Graphics::DrawStep::kVectorAlignCenter:
- in_y = area.top + (area.height() / 2) - (in_h / 2);
+ in_y = area.top + (area.height() / 2) - (in_h / 2) + ((step.padding.top + step.padding.bottom ) / 2) ;
break;
case Graphics::DrawStep::kVectorAlignTop:
- in_y = area.top;
+ in_y = area.top + step.padding.top;
break;
case Graphics::DrawStep::kVectorAlignBottom:
- in_y = area.top + area.height() - in_h;
+ in_y = area.top + area.height() - in_h - step.padding.bottom;
break;
default:
error("Horizontal alignment in vertical data");
}
} else {
- in_y = area.top;
+ in_y = area.top + step.padding.top;
in_h = area.height();
}
diff --git a/graphics/VectorRenderer.h b/graphics/VectorRenderer.h
index ec8a8f7245..e98f4aa761 100644
--- a/graphics/VectorRenderer.h
+++ b/graphics/VectorRenderer.h
@@ -55,6 +55,8 @@ struct DrawStep {
bool autoWidth, autoHeight;
int16 x, y, w, h; /**< width, height and position, if not measured automatically.
negative values mean counting from the opposite direction */
+
+ Common::Rect padding;
enum VectorAlignment {
kVectorAlignManual,
@@ -491,7 +493,6 @@ protected:
uint32 _dynamicData; /**< Dynamic data from the GUI Theme that modifies the drawing of the current shape */
int _gradientFactor; /**< Multiplication factor of the active gradient */
- int _gradientBytes[3]; /**< Color bytes of the active gradient, used to speed up calculation */
};
} // End of namespace Graphics
diff --git a/graphics/VectorRendererSpec.cpp b/graphics/VectorRendererSpec.cpp
index a2cb693b78..7817725664 100644
--- a/graphics/VectorRendererSpec.cpp
+++ b/graphics/VectorRendererSpec.cpp
@@ -77,7 +77,7 @@ inline frac_t fp_sqroot(uint32 x) {
HELPER MACROS for Bresenham's circle drawing algorithm
Note the proper spelling on this header.
*/
-#define __BE_ALGORITHM() { \
+#define BE_ALGORITHM() do { \
if (f >= 0) { \
y--; \
ddF_y += 2; \
@@ -87,37 +87,65 @@ inline frac_t fp_sqroot(uint32 x) {
px += pitch; \
ddF_x += 2; \
f += ddF_x + 1; \
-}
+} while(0)
-#define __BE_DRAWCIRCLE(ptr1,ptr2,ptr3,ptr4,x,y,px,py) { \
+#define BE_DRAWCIRCLE_TOP(ptr1,ptr2,x,y,px,py) do { \
*(ptr1 + (y) - (px)) = color; \
*(ptr1 + (x) - (py)) = color; \
*(ptr2 - (x) - (py)) = color; \
*(ptr2 - (y) - (px)) = color; \
+} while (0)
+
+#define BE_DRAWCIRCLE_BOTTOM(ptr3,ptr4,x,y,px,py) do { \
*(ptr3 - (y) + (px)) = color; \
*(ptr3 - (x) + (py)) = color; \
*(ptr4 + (x) + (py)) = color; \
*(ptr4 + (y) + (px)) = color; \
-}
+} while (0)
+
+#define BE_DRAWCIRCLE(ptr1,ptr2,ptr3,ptr4,x,y,px,py) do { \
+ BE_DRAWCIRCLE_TOP(ptr1,ptr2,x,y,px,py); \
+ BE_DRAWCIRCLE_BOTTOM(ptr3,ptr4,x,y,px,py); \
+} while (0)
+
+#define BE_DRAWCIRCLE_BCOLOR(ptr1,ptr2,ptr3,ptr4,x,y,px,py) do { \
+ *(ptr1 + (y) - (px)) = color1; \
+ *(ptr1 + (x) - (py)) = color1; \
+ *(ptr2 - (x) - (py)) = color1; \
+ *(ptr2 - (y) - (px)) = color1; \
+ *(ptr3 - (y) + (px)) = color1; \
+ *(ptr3 - (x) + (py)) = color1; \
+ *(ptr4 + (x) + (py)) = color2; \
+ *(ptr4 + (y) + (px)) = color2; \
+} while (0)
-#define __BE_DRAWCIRCLE_XCOLOR(ptr1,ptr2,ptr3,ptr4,x,y,px,py) { \
+#define BE_DRAWCIRCLE_XCOLOR_TOP(ptr1,ptr2,x,y,px,py) do { \
*(ptr1 + (y) - (px)) = color1; \
*(ptr1 + (x) - (py)) = color2; \
*(ptr2 - (x) - (py)) = color2; \
*(ptr2 - (y) - (px)) = color1; \
+} while (0)
+
+#define BE_DRAWCIRCLE_XCOLOR_BOTTOM(ptr3,ptr4,x,y,px,py) do { \
*(ptr3 - (y) + (px)) = color3; \
*(ptr3 - (x) + (py)) = color4; \
*(ptr4 + (x) + (py)) = color4; \
*(ptr4 + (y) + (px)) = color3; \
-}
+} while (0)
+
+#define BE_DRAWCIRCLE_XCOLOR(ptr1,ptr2,ptr3,ptr4,x,y,px,py) do { \
+ BE_DRAWCIRCLE_XCOLOR_TOP(ptr1,ptr2,x,y,px,py); \
+ BE_DRAWCIRCLE_XCOLOR_BOTTOM(ptr3,ptr4,x,y,px,py); \
+} while (0)
+
-#define __BE_RESET() { \
+#define BE_RESET() do { \
f = 1 - r; \
ddF_x = 0; ddF_y = -2 * r; \
x = 0; y = r; px = 0; py = pitch * r; \
-}
+} while (0)
-#define __TRIANGLE_MAINX() \
+#define TRIANGLE_MAINX() \
if (error_term >= 0) { \
ptr_right += pitch; \
ptr_left += pitch; \
@@ -128,7 +156,7 @@ inline frac_t fp_sqroot(uint32 x) {
ptr_right++; \
ptr_left--;
-#define __TRIANGLE_MAINY() \
+#define TRIANGLE_MAINY() \
if (error_term >= 0) { \
ptr_right++; \
ptr_left--; \
@@ -140,19 +168,63 @@ inline frac_t fp_sqroot(uint32 x) {
ptr_left += pitch;
/** HELPER MACROS for WU's circle drawing algorithm **/
-#define __WU_DRAWCIRCLE(ptr1,ptr2,ptr3,ptr4,x,y,px,py,a) { \
+#define WU_DRAWCIRCLE_TOP(ptr1,ptr2,x,y,px,py,a) do { \
this->blendPixelPtr(ptr1 + (y) - (px), color, a); \
this->blendPixelPtr(ptr1 + (x) - (py), color, a); \
this->blendPixelPtr(ptr2 - (x) - (py), color, a); \
this->blendPixelPtr(ptr2 - (y) - (px), color, a); \
+} while (0)
+
+#define WU_DRAWCIRCLE_BOTTOM(ptr3,ptr4,x,y,px,py,a) do { \
this->blendPixelPtr(ptr3 - (y) + (px), color, a); \
this->blendPixelPtr(ptr3 - (x) + (py), color, a); \
this->blendPixelPtr(ptr4 + (x) + (py), color, a); \
this->blendPixelPtr(ptr4 + (y) + (px), color, a); \
-}
+} while (0)
+
+#define WU_DRAWCIRCLE(ptr1,ptr2,ptr3,ptr4,x,y,px,py,a) do { \
+ WU_DRAWCIRCLE_TOP(ptr1,ptr2,x,y,px,py,a); \
+ WU_DRAWCIRCLE_BOTTOM(ptr3,ptr4,x,y,px,py,a); \
+} while (0)
+
+
+// Color depending on y
+// Note: this is only for the outer pixels
+#define WU_DRAWCIRCLE_XCOLOR_TOP(ptr1,ptr2,x,y,px,py,a,func) do { \
+ this->func(ptr1 + (y) - (px), color1, a); \
+ this->func(ptr1 + (x) - (py), color2, a); \
+ this->func(ptr2 - (x) - (py), color2, a); \
+ this->func(ptr2 - (y) - (px), color1, a); \
+} while (0)
+
+#define WU_DRAWCIRCLE_XCOLOR_BOTTOM(ptr3,ptr4,x,y,px,py,a,func) do { \
+ this->func(ptr3 - (y) + (px), color3, a); \
+ this->func(ptr3 - (x) + (py), color4, a); \
+ this->func(ptr4 + (x) + (py), color4, a); \
+ this->func(ptr4 + (y) + (px), color3, a); \
+} while (0)
+
+#define WU_DRAWCIRCLE_XCOLOR(ptr1,ptr2,ptr3,ptr4,x,y,px,py,a,func) do { \
+ WU_DRAWCIRCLE_XCOLOR_TOP(ptr1,ptr2,x,y,px,py,a,func); \
+ WU_DRAWCIRCLE_XCOLOR_BOTTOM(ptr3,ptr4,x,y,px,py,a,func); \
+} while (0)
+
+// Color depending on corner (tl,tr,bl: color1, br: color2)
+// Note: this is only for the outer pixels
+#define WU_DRAWCIRCLE_BCOLOR(ptr1,ptr2,ptr3,ptr4,x,y,px,py,a) do { \
+ this->blendPixelPtr(ptr1 + (y) - (px), color1, a); \
+ this->blendPixelPtr(ptr1 + (x) - (py), color1, a); \
+ this->blendPixelPtr(ptr2 - (x) - (py), color1, a); \
+ this->blendPixelPtr(ptr2 - (y) - (px), color1, a); \
+ this->blendPixelPtr(ptr3 - (y) + (px), color1, a); \
+ this->blendPixelPtr(ptr3 - (x) + (py), color1, a); \
+ this->blendPixelPtr(ptr4 + (x) + (py), color2, a); \
+ this->blendPixelPtr(ptr4 + (y) + (px), color2, a); \
+} while (0)
+
// optimized Wu's algorithm
-#define __WU_ALGORITHM() { \
+#define WU_ALGORITHM() do { \
oldT = T; \
T = fp_sqroot(rsq - y*y) ^ 0xFFFF; \
py += pitch; \
@@ -160,8 +232,8 @@ inline frac_t fp_sqroot(uint32 x) {
x--; px -= pitch; \
} \
a2 = (T >> 8); \
- a1 = ~a2 >> 4; \
-}
+ a1 = ~a2; \
+} while (0)
namespace Graphics {
@@ -169,7 +241,7 @@ namespace Graphics {
/**
* Fills several pixels in a row with a given color.
*
- * This is a replacement function for Common::set_to, using an unrolled
+ * This is a replacement function for Common::fill, using an unrolled
* loop to maximize performance on most architectures.
* This function may (and should) be overloaded in any child renderers
* for portable platforms with platform-specific assembly code.
@@ -224,17 +296,6 @@ VectorRenderer *createRenderer(int mode) {
}
template<typename PixelType>
-void VectorRendererSpec<PixelType>::
-setGradientColors(uint8 r1, uint8 g1, uint8 b1, uint8 r2, uint8 g2, uint8 b2) {
- _gradientEnd = _format.RGBToColor(r2, g2, b2);
- _gradientStart = _format.RGBToColor(r1, g1, b1);
-
- Base::_gradientBytes[0] = (_gradientEnd & _redMask) - (_gradientStart & _redMask);
- Base::_gradientBytes[1] = (_gradientEnd & _greenMask) - (_gradientStart & _greenMask);
- Base::_gradientBytes[2] = (_gradientEnd & _blueMask) - (_gradientStart & _blueMask);
-}
-
-template<typename PixelType>
VectorRendererSpec<PixelType>::
VectorRendererSpec(PixelFormat format) :
_format(format),
@@ -246,6 +307,93 @@ VectorRendererSpec(PixelFormat format) :
_bitmapAlphaColor = _format.RGBToColor(255, 0, 255);
}
+/****************************
+ * Gradient-related methods *
+ ****************************/
+
+template<typename PixelType>
+void VectorRendererSpec<PixelType>::
+setGradientColors(uint8 r1, uint8 g1, uint8 b1, uint8 r2, uint8 g2, uint8 b2) {
+ _gradientEnd = _format.RGBToColor(r2, g2, b2);
+ _gradientStart = _format.RGBToColor(r1, g1, b1);
+
+ _gradientBytes[0] = (_gradientEnd & _redMask) - (_gradientStart & _redMask);
+ _gradientBytes[1] = (_gradientEnd & _greenMask) - (_gradientStart & _greenMask);
+ _gradientBytes[2] = (_gradientEnd & _blueMask) - (_gradientStart & _blueMask);
+}
+
+template<typename PixelType>
+inline PixelType VectorRendererSpec<PixelType>::
+calcGradient(uint32 pos, uint32 max) {
+ PixelType output = 0;
+ pos = (MIN(pos * Base::_gradientFactor, max) << 12) / max;
+
+ output |= ((_gradientStart & _redMask) + ((_gradientBytes[0] * pos) >> 12)) & _redMask;
+ output |= ((_gradientStart & _greenMask) + ((_gradientBytes[1] * pos) >> 12)) & _greenMask;
+ output |= ((_gradientStart & _blueMask) + ((_gradientBytes[2] * pos) >> 12)) & _blueMask;
+ output |= _alphaMask;
+
+ return output;
+}
+
+template<typename PixelType>
+void VectorRendererSpec<PixelType>::
+precalcGradient(int h) {
+ PixelType prevcolor = 0, color;
+
+ _gradCache.resize(0);
+ _gradIndexes.resize(0);
+
+ for (int i = 0; i < h + 2; i++) {
+ color = calcGradient(i, h);
+ if (color != prevcolor || i == 0 || i > h - 1) {
+ prevcolor = color;
+ _gradCache.push_back(color);
+ _gradIndexes.push_back(i);
+ }
+ }
+}
+
+template<typename PixelType>
+void VectorRendererSpec<PixelType>::
+gradientFill(PixelType *ptr, int width, int x, int y) {
+ bool ox = ((y & 1) == 1);
+ int stripSize;
+ int curGrad = 0;
+
+ while (_gradIndexes[curGrad + 1] <= y)
+ curGrad++;
+
+ stripSize = _gradIndexes[curGrad + 1] - _gradIndexes[curGrad];
+
+ int grad = (((y - _gradIndexes[curGrad]) % stripSize) << 2) / stripSize;
+
+ // Dithering:
+ // +--+ +--+ +--+ +--+
+ // | | | | | *| | *|
+ // | | | *| |* | |**|
+ // +--+ +--+ +--+ +--+
+ // 0 1 2 3
+ if (grad == 0 ||
+ _gradCache[curGrad] == _gradCache[curGrad + 1] || // no color change
+ stripSize < 2) { // the stip is small
+ colorFill<PixelType>(ptr, ptr + width, _gradCache[curGrad]);
+ } else if (grad == 3 && ox) {
+ colorFill<PixelType>(ptr, ptr + width, _gradCache[curGrad + 1]);
+ } else {
+ for (int j = x; j < x + width; j++, ptr++) {
+ bool oy = ((j & 1) == 1);
+
+ if ((ox && oy) ||
+ ((grad == 2 || grad == 3) && ox && !oy) ||
+ (grad == 3 && oy))
+ *ptr = _gradCache[curGrad + 1];
+ else
+ *ptr = _gradCache[curGrad];
+ }
+ }
+}
+
template<typename PixelType>
void VectorRendererSpec<PixelType>::
fillSurface() {
@@ -259,9 +407,11 @@ fillSurface() {
} else if (Base::_fillMode == kFillForeground) {
colorFill<PixelType>((PixelType *)ptr, (PixelType *)(ptr + pitch * h), _fgColor);
} else if (Base::_fillMode == kFillGradient) {
- int i = h;
- while (i--) {
- colorFill<PixelType>((PixelType *)ptr, (PixelType *)(ptr + pitch), calcGradient(h - i, h));
+ precalcGradient(h);
+
+ for (int i = 0; i < h; i++) {
+ gradientFill((PixelType *)ptr, _activeSurface->w, 0, i);
+
ptr += pitch;
}
}
@@ -369,18 +519,10 @@ applyScreenShading(GUI::ThemeEngine::ShadingStyle shadingStyle) {
if (shadingStyle == GUI::ThemeEngine::kShadingDim) {
- int n = (pixels + 7) >> 3;
- switch (pixels % 8) {
- case 0: do {
- *ptr = (*ptr & colorMask) >> 1; ++ptr;
- case 7: *ptr = (*ptr & colorMask) >> 1; ++ptr;
- case 6: *ptr = (*ptr & colorMask) >> 1; ++ptr;
- case 5: *ptr = (*ptr & colorMask) >> 1; ++ptr;
- case 4: *ptr = (*ptr & colorMask) >> 1; ++ptr;
- case 3: *ptr = (*ptr & colorMask) >> 1; ++ptr;
- case 2: *ptr = (*ptr & colorMask) >> 1; ++ptr;
- case 1: *ptr = (*ptr & colorMask) >> 1; ++ptr;
- } while (--n > 0);
+ // TODO: Check how this interacts with kFeatureOverlaySupportsAlpha
+ for (int i = 0; i < pixels; ++i) {
+ *ptr = ((*ptr & colorMask) >> 1) | _alphaMask;
+ ++ptr;
}
} else if (shadingStyle == GUI::ThemeEngine::kShadingLuminance) {
@@ -395,8 +537,8 @@ applyScreenShading(GUI::ThemeEngine::ShadingStyle shadingStyle) {
template<typename PixelType>
inline void VectorRendererSpec<PixelType>::
blendPixelPtr(PixelType *ptr, PixelType color, uint8 alpha) {
- register int idst = *ptr;
- register int isrc = color;
+ int idst = *ptr;
+ int isrc = color;
*ptr = (PixelType)(
(_redMask & ((idst & _redMask) +
@@ -408,23 +550,53 @@ blendPixelPtr(PixelType *ptr, PixelType color, uint8 alpha) {
(_blueMask & ((idst & _blueMask) +
((int)(((int)(isrc & _blueMask) -
(int)(idst & _blueMask)) * alpha) >> 8))) |
- (_alphaMask & ((idst & _alphaMask) +
- ((alpha >> _format.aLoss) << _format.aShift) -
- (((int)(idst & _alphaMask) * alpha) >> 8))));
+ (idst & _alphaMask));
}
template<typename PixelType>
-inline PixelType VectorRendererSpec<PixelType>::
-calcGradient(uint32 pos, uint32 max) {
- PixelType output = 0;
- pos = (MIN(pos * Base::_gradientFactor, max) << 12) / max;
+inline void VectorRendererSpec<PixelType>::
+blendPixelDestAlphaPtr(PixelType *ptr, PixelType color, uint8 alpha) {
+ int idst = *ptr;
+ // This function is only used for corner pixels in rounded rectangles, so
+ // the performance hit of this if shouldn't be too high.
+ // We're also ignoring the cases where dst has intermediate alpha.
+ if ((idst & _alphaMask) == 0) {
+ // set color and alpha channels
+ *ptr = (PixelType)(color & (_redMask | _greenMask | _blueMask)) |
+ ((alpha >> _format.aLoss) << _format.aShift);
+ } else {
+ // blend color with background
+ blendPixelPtr(ptr, color, alpha);
+ }
+}
- output |= ((_gradientStart & _redMask) + ((Base::_gradientBytes[0] * pos) >> 12)) & _redMask;
- output |= ((_gradientStart & _greenMask) + ((Base::_gradientBytes[1] * pos) >> 12)) & _greenMask;
- output |= ((_gradientStart & _blueMask) + ((Base::_gradientBytes[2] * pos) >> 12)) & _blueMask;
- output |= _alphaMask;
+template<typename PixelType>
+inline void VectorRendererSpec<PixelType>::
+darkenFill(PixelType *ptr, PixelType *end) {
+ PixelType mask = (PixelType)((3 << _format.rShift) | (3 << _format.gShift) | (3 << _format.bShift));
- return output;
+ if (!g_system->hasFeature(OSystem::kFeatureOverlaySupportsAlpha)) {
+ // !kFeatureOverlaySupportsAlpha (but might have alpha bits)
+
+ while (ptr != end) {
+ *ptr = ((*ptr & ~mask) >> 2) | _alphaMask;
+ ++ptr;
+ }
+ } else {
+ // kFeatureOverlaySupportsAlpha
+ // assuming at least 3 alpha bits
+
+ mask |= 3 << _format.aShift;
+ PixelType addA = (PixelType)(255 >> _format.aLoss) << _format.aShift;
+ addA -= (addA >> 2);
+
+ while (ptr != end) {
+ // Darken the colour, and increase the alpha
+ // (0% -> 75%, 100% -> 100%)
+ *ptr = (PixelType)(((*ptr & ~mask) >> 2) + addA);
+ ++ptr;
+ }
+ }
}
/********************************************************************
@@ -601,42 +773,16 @@ drawRoundedSquare(int x, int y, int r, int w, int h) {
if ((r * 2) > w || (r * 2) > h)
r = MIN(w /2, h / 2);
+ if (r <= 0)
+ return;
+
if (Base::_fillMode != kFillDisabled && Base::_shadowOffset
&& x + w + Base::_shadowOffset + 1 < Base::_activeSurface->w
&& y + h + Base::_shadowOffset + 1 < Base::_activeSurface->h) {
drawRoundedSquareShadow(x, y, r, w, h, Base::_shadowOffset);
}
- switch (Base::_fillMode) {
- case kFillDisabled:
- if (Base::_strokeWidth)
- drawRoundedSquareAlg(x, y, r, w, h, _fgColor, kFillDisabled);
- break;
-
- case kFillForeground:
- drawRoundedSquareAlg(x, y, r, w, h, _fgColor, kFillForeground);
- break;
-
- case kFillBackground:
- VectorRendererSpec::drawRoundedSquareAlg(x, y, r, w, h, _bgColor, kFillBackground);
- drawRoundedSquareAlg(x, y, r, w, h, _fgColor, kFillDisabled);
- break;
-
- case kFillGradient:
- if (Base::_strokeWidth > 1) {
- drawRoundedSquareAlg(x, y, r, w, h, _fgColor, kFillForeground);
- VectorRendererSpec::drawRoundedSquareAlg(x + Base::_strokeWidth/2, y + Base::_strokeWidth/2,
- r - Base::_strokeWidth/2, w - Base::_strokeWidth, h - Base::_strokeWidth, 0, kFillGradient);
- } else {
- VectorRendererSpec::drawRoundedSquareAlg(x, y, r, w, h, 0, kFillGradient);
- if (Base::_strokeWidth)
- drawRoundedSquareAlg(x, y, r, w, h, _fgColor, kFillDisabled);
- }
- break;
- }
-
- if (Base::_bevel)
- drawRoundedSquareFakeBevel(x, y, r, w, h, Base::_bevel);
+ drawRoundedSquareAlg(x, y, r, w, h, _fgColor, Base::_fillMode);
}
template<typename PixelType>
@@ -655,10 +801,14 @@ drawTab(int x, int y, int r, int w, int h) {
switch (Base::_fillMode) {
case kFillDisabled:
+ // FIXME: Implement this
return;
case kFillGradient:
case kFillBackground:
+ // FIXME: This is broken for the AA renderer.
+ // See the rounded rect alg for how to fix it. (The border should
+ // be drawn before the interior, both inside drawTabAlg.)
drawTabAlg(x, y, w, h, r, (Base::_fillMode == kFillBackground) ? _bgColor : _fgColor, Base::_fillMode);
if (Base::_strokeWidth)
drawTabAlg(x, y, w, h, r, _fgColor, kFillDisabled, (Base::_dynamicData >> 16), (Base::_dynamicData & 0xFFFF));
@@ -693,25 +843,49 @@ drawTriangle(int x, int y, int w, int h, TriangleOrientation orient) {
if (Base::_dynamicData != 0)
orient = (TriangleOrientation)Base::_dynamicData;
- int newW = w / 2;
- if (newW % 2) newW++;
+ if (w == h) {
+ int newW = w;
- switch (orient) {
+ switch (orient) {
case kTriangleUp:
case kTriangleDown:
- drawTriangleFast(x + (newW / 2), y + (h / 2) - (newW / 2), newW, (orient == kTriangleDown), color, Base::_fillMode);
+ //drawTriangleFast(x, y, newW, (orient == kTriangleDown), color, Base::_fillMode);
+ drawTriangleVertAlg(x, y, newW, newW, (orient == kTriangleDown), color, Base::_fillMode);
break;
case kTriangleLeft:
case kTriangleRight:
case kTriangleAuto:
break;
- }
+ }
+
+ if (Base::_strokeWidth > 0)
+ if (Base::_fillMode == kFillBackground || Base::_fillMode == kFillGradient) {
+ //drawTriangleFast(x, y, newW, (orient == kTriangleDown), _fgColor, kFillDisabled);
+ drawTriangleVertAlg(x, y, newW, newW, (orient == kTriangleDown), color, Base::_fillMode);
+ }
+ } else {
+ int newW = w;
+ int newH = h;
+
+ switch (orient) {
+ case kTriangleUp:
+ case kTriangleDown:
+ drawTriangleVertAlg(x, y, newW, newH, (orient == kTriangleDown), color, Base::_fillMode);
+ break;
+
+ case kTriangleLeft:
+ case kTriangleRight:
+ case kTriangleAuto:
+ break;
+ }
- if (Base::_strokeWidth > 0)
- if (Base::_fillMode == kFillBackground || Base::_fillMode == kFillGradient) {
- drawTriangleFast(x + (newW / 2), y + (h / 2) - (newW / 2), newW, (orient == kTriangleDown), _fgColor, kFillDisabled);
+ if (Base::_strokeWidth > 0) {
+ if (Base::_fillMode == kFillBackground || Base::_fillMode == kFillGradient) {
+ drawTriangleVertAlg(x, y, newW, newH, (orient == kTriangleDown), _fgColor, kFillDisabled);
+ }
}
+ }
}
@@ -746,22 +920,15 @@ drawTabAlg(int x1, int y1, int w, int h, int r, PixelType color, VectorRenderer:
colorFill<PixelType>(ptr_fill + hp - sp + r, ptr_fill + w + hp + 1 - sp - r, color);
sp += pitch;
- __BE_RESET();
+ BE_RESET();
r--;
while (x++ < y) {
- __BE_ALGORITHM();
- *(ptr_tr + (y) - (px)) = color;
- *(ptr_tr + (x) - (py)) = color;
- *(ptr_tl - (x) - (py)) = color;
- *(ptr_tl - (y) - (px)) = color;
+ BE_ALGORITHM();
+ BE_DRAWCIRCLE_TOP(ptr_tr, ptr_tl, x, y, px, py);
- if (Base::_strokeWidth > 1) {
- *(ptr_tr + (y) - (px - pitch)) = color;
- *(ptr_tr + (x) - (py)) = color;
- *(ptr_tl - (x) - (py)) = color;
- *(ptr_tl - (y) - (px - pitch)) = color;
- }
+ if (Base::_strokeWidth > 1)
+ BE_DRAWCIRCLE_TOP(ptr_tr, ptr_tl, x, y, px - pitch, py);
}
}
@@ -790,33 +957,39 @@ drawTabAlg(int x1, int y1, int w, int h, int r, PixelType color, VectorRenderer:
}
}
} else {
- __BE_RESET();
+ BE_RESET();
+
+ precalcGradient(long_h);
PixelType color1, color2;
color1 = color2 = color;
while (x++ < y) {
- __BE_ALGORITHM();
+ BE_ALGORITHM();
if (fill_m == kFillGradient) {
color1 = calcGradient(real_radius - x, long_h);
color2 = calcGradient(real_radius - y, long_h);
- }
- colorFill<PixelType>(ptr_tl - x - py, ptr_tr + x - py, color2);
- colorFill<PixelType>(ptr_tl - y - px, ptr_tr + y - px, color1);
+ gradientFill(ptr_tl - x - py, w - 2 * r + 2 * x, x1 + r - x - y, real_radius - y);
+ gradientFill(ptr_tl - y - px, w - 2 * r + 2 * y, x1 + r - y - x, real_radius - x);
- *(ptr_tr + (y) - (px)) = color1;
- *(ptr_tr + (x) - (py)) = color2;
- *(ptr_tl - (x) - (py)) = color2;
- *(ptr_tl - (y) - (px)) = color1;
+ BE_DRAWCIRCLE_XCOLOR_TOP(ptr_tr, ptr_tl, x, y, px, py);
+ } else {
+ colorFill<PixelType>(ptr_tl - x - py, ptr_tr + x - py, color);
+ colorFill<PixelType>(ptr_tl - y - px, ptr_tr + y - px, color);
+
+ BE_DRAWCIRCLE_TOP(ptr_tr, ptr_tl, x, y, px, py);
+ }
}
ptr_fill += pitch * r;
while (short_h--) {
- if (fill_m == kFillGradient)
- color = calcGradient(real_radius++, long_h);
- colorFill<PixelType>(ptr_fill, ptr_fill + w + 1, color);
+ if (fill_m == kFillGradient) {
+ gradientFill(ptr_fill, w + 1, x1, real_radius++);
+ } else {
+ colorFill<PixelType>(ptr_fill, ptr_fill + w + 1, color);
+ }
ptr_fill += pitch;
}
}
@@ -910,8 +1083,9 @@ drawBevelSquareAlg(int x, int y, int w, int h, int bevel, PixelType top_color, P
PixelType *ptr_fill = (PixelType *)_activeSurface->getBasePtr(x, y);
if (fill) {
+ assert((_bgColor & ~_alphaMask) == 0); // only support black
while (height--) {
- blendFill(ptr_fill, ptr_fill + w, _bgColor, 200);
+ darkenFill(ptr_fill, ptr_fill + w);
ptr_fill += pitch;
}
}
@@ -1005,130 +1179,249 @@ drawLineAlg(int x1, int y1, int x2, int y2, int dx, int dy, PixelType color) {
}
/** VERTICAL TRIANGLE DRAWING ALGORITHM **/
+/**
+ FIXED POINT ARITHMETIC
+**/
+
+#define FIXED_POINT 1
+
+#if FIXED_POINT
+#define ipart(x) ((x) & ~0xFF)
+// This is not really correct since gradient is not percentage, but [0..255]
+#define rfpart(x) ((0x100 - ((x) & 0xFF)) * 100 >> 8)
+//#define rfpart(x) (0x100 - ((x) & 0xFF))
+#else
+#define ipart(x) ((int)x)
+#define round(x) (ipart(x + 0.5))
+#define fpart(x) (x - ipart(x))
+#define rfpart(x) (int)((1 - fpart(x)) * 100)
+#endif
+
template<typename PixelType>
void VectorRendererSpec<PixelType>::
drawTriangleVertAlg(int x1, int y1, int w, int h, bool inverted, PixelType color, VectorRenderer::FillMode fill_m) {
- int dx = w >> 1, dy = h, gradient_h = 0;
int pitch = _activeSurface->pitch / _activeSurface->format.bytesPerPixel;
- PixelType *ptr_right = 0, *ptr_left = 0;
-
- if (inverted) {
- ptr_right = (PixelType *)_activeSurface->getBasePtr(x1, y1);
- ptr_left = (PixelType *)_activeSurface->getBasePtr(x1 + w, y1);
- } else {
- ptr_right = ptr_left = (PixelType *)_activeSurface->getBasePtr(x1 + dx, y1);
+ int gradient_h = 0;
+ if (!inverted) {
+ pitch = -pitch;
+ y1 += h;
}
+
+ PixelType *ptr_right = (PixelType *)_activeSurface->getBasePtr(x1, y1);
+ PixelType *floor = ptr_right - 1;
+ PixelType *ptr_left = (PixelType *)_activeSurface->getBasePtr(x1 + w, y1);
+
+ int x2 = x1 + w / 2;
+ int y2 = y1 + h;
+
+#if FIXED_POINT
+ int dx = (x2 - x1) << 8;
+ int dy = (y2 - y1) << 8;
+
+ if (abs(dx) > abs(dy)) {
+#else
+ double dx = (double)x2 - (double)x1;
+ double dy = (double)y2 - (double)y1;
- if (dx > dy) {
- int ddy = dy * 2;
- int dysub = ddy - (dx * 2);
- int error_term = ddy - dx;
+ if (fabs(dx) > fabs(dy)) {
+#endif
+ while (floor++ != ptr_left)
+ blendPixelPtr(floor, color, 50);
+
+#if FIXED_POINT
+ int gradient = (dy << 8) / dx;
+ int intery = (y1 << 8) + gradient;
+#else
+ double gradient = dy / dx;
+ double intery = y1 + gradient;
+#endif
- switch (fill_m) {
- case kFillDisabled:
- while (dx--) {
- __TRIANGLE_MAINX();
- *ptr_right = color;
- *ptr_left = color;
+ for (int x = x1 + 1; x < x2; x++) {
+#if FIXED_POINT
+ if (intery + gradient > ipart(intery) + 0x100) {
+#else
+ if (intery + gradient > ipart(intery) + 1) {
+#endif
+ ptr_right++;
+ ptr_left--;
}
- colorFill<PixelType>(ptr_left, ptr_right, color);
- break;
- case kFillForeground:
- case kFillBackground:
- while (dx--) {
- __TRIANGLE_MAINX();
- if (inverted) colorFill<PixelType>(ptr_right, ptr_left, color);
- else colorFill<PixelType>(ptr_left, ptr_right, color);
+ ptr_left += pitch;
+ ptr_right += pitch;
+
+ intery += gradient;
+
+ switch (fill_m) {
+ case kFillDisabled:
+ *ptr_left = *ptr_right = color;
+ break;
+ case kFillForeground:
+ case kFillBackground:
+ colorFill<PixelType>(ptr_right + 1, ptr_left, color);
+ blendPixelPtr(ptr_right, color, rfpart(intery));
+ blendPixelPtr(ptr_left, color, rfpart(intery));
+ break;
+ case kFillGradient:
+ colorFill<PixelType>(ptr_right, ptr_left, calcGradient(gradient_h++, h));
+ blendPixelPtr(ptr_right, color, rfpart(intery));
+ blendPixelPtr(ptr_left, color, rfpart(intery));
+ break;
}
- break;
+ }
+
+ return;
+ }
+
+#if FIXED_POINT
+ if (abs(dx) < abs(dy)) {
+#else
+ if (fabs(dx) < fabs(dy)) {
+#endif
+ ptr_left--;
+ while (floor++ != ptr_left)
+ blendPixelPtr(floor, color, 50);
+
+#if FIXED_POINT
+ int gradient = (dx << 8) / (dy + 0x100);
+ int interx = (x1 << 8) + gradient;
+#else
+ double gradient = dx / (dy+1);
+ double interx = x1 + gradient;
+#endif
- case kFillGradient:
- while (dx--) {
- __TRIANGLE_MAINX();
- if (inverted) colorFill<PixelType>(ptr_right, ptr_left, calcGradient(gradient_h++, h));
- else colorFill<PixelType>(ptr_left, ptr_right, calcGradient(gradient_h++, h));
+ for (int y = y1 + 1; y < y2; y++) {
+#if FIXED_POINT
+ if (interx + gradient > ipart(interx) + 0x100) {
+#else
+ if (interx + gradient > ipart(interx) + 1) {
+#endif
+ ptr_right++;
+ ptr_left--;
+ }
+
+ ptr_left += pitch;
+ ptr_right += pitch;
+
+ interx += gradient;
+
+ switch (fill_m) {
+ case kFillDisabled:
+ *ptr_left = *ptr_right = color;
+ break;
+ case kFillForeground:
+ case kFillBackground:
+ colorFill<PixelType>(ptr_right + 1, ptr_left, color);
+ blendPixelPtr(ptr_right, color, rfpart(interx));
+ blendPixelPtr(ptr_left, color, rfpart(interx));
+ break;
+ case kFillGradient:
+ colorFill<PixelType>(ptr_right, ptr_left, calcGradient(gradient_h++, h));
+ blendPixelPtr(ptr_right, color, rfpart(interx));
+ blendPixelPtr(ptr_left, color, rfpart(interx));
+ break;
}
- break;
}
- } else {
- int ddx = dx * 2;
- int dxsub = ddx - (dy * 2);
- int error_term = ddx - dy;
+
+ return;
+ }
+
+ ptr_left--;
+
+ while (floor++ != ptr_left)
+ blendPixelPtr(floor, color, 50);
+
+#if FIXED_POINT
+ int gradient = (dx / dy) << 8;
+ int interx = (x1 << 8) + gradient;
+#else
+ double gradient = dx / dy;
+ double interx = x1 + gradient;
+#endif
+
+ for (int y = y1 + 1; y < y2; y++) {
+ ptr_right++;
+ ptr_left--;
+
+ ptr_left += pitch;
+ ptr_right += pitch;
+ interx += gradient;
+
switch (fill_m) {
case kFillDisabled:
- while (dy--) {
- __TRIANGLE_MAINY();
- *ptr_right = color;
- *ptr_left = color;
- }
- colorFill<PixelType>(ptr_left, ptr_right, color);
+ *ptr_left = *ptr_right = color;
break;
-
case kFillForeground:
case kFillBackground:
- while (dy--) {
- __TRIANGLE_MAINY();
- if (inverted) colorFill<PixelType>(ptr_right, ptr_left, color);
- else colorFill<PixelType>(ptr_left, ptr_right, color);
- }
+ colorFill<PixelType>(ptr_right + 1, ptr_left, color);
+ blendPixelPtr(ptr_right, color, rfpart(interx));
+ blendPixelPtr(ptr_left, color, rfpart(interx));
break;
case kFillGradient:
- while (dy--) {
- __TRIANGLE_MAINY();
- if (inverted) colorFill<PixelType>(ptr_right, ptr_left, calcGradient(gradient_h++, h));
- else colorFill<PixelType>(ptr_left, ptr_right, calcGradient(gradient_h++, h));
- }
+ colorFill<PixelType>(ptr_right, ptr_left, calcGradient(gradient_h++, h));
+ blendPixelPtr(ptr_right, color, rfpart(interx));
+ blendPixelPtr(ptr_left, color, rfpart(interx));
break;
}
}
+
}
-
/** VERTICAL TRIANGLE DRAWING - FAST VERSION FOR SQUARED TRIANGLES */
template<typename PixelType>
void VectorRendererSpec<PixelType>::
drawTriangleFast(int x1, int y1, int size, bool inverted, PixelType color, VectorRenderer::FillMode fill_m) {
int pitch = _activeSurface->pitch / _activeSurface->format.bytesPerPixel;
- int hstep = 0, dy = size;
- bool grad = (fill_m == kFillGradient);
-
- PixelType *ptr_right = 0, *ptr_left = 0;
-
- if (x1 + size > Base::_activeSurface->w || x1 < 0 ||
- y1 + size > Base::_activeSurface->h || y1 < 0)
- return;
-
- if (inverted) {
- ptr_left = (PixelType *)_activeSurface->getBasePtr(x1, y1);
- ptr_right = (PixelType *)_activeSurface->getBasePtr(x1 + size, y1);
- } else {
- ptr_left = (PixelType *)_activeSurface->getBasePtr(x1, y1 + size);
- ptr_right = (PixelType *)_activeSurface->getBasePtr(x1 + size, y1 + size);
+
+ if (!inverted) {
pitch = -pitch;
+ y1 += size;
}
-
- if (fill_m == kFillDisabled) {
- while (ptr_left < ptr_right) {
- *ptr_left = color;
- *ptr_right = color;
- ptr_left += pitch;
- ptr_right += pitch;
- if (hstep++ % 2) {
- ptr_left++;
- ptr_right--;
- }
+
+ int gradient_h = 0;
+ PixelType *ptr_right = (PixelType *)_activeSurface->getBasePtr(x1, y1);
+ PixelType *ptr_left = (PixelType *)_activeSurface->getBasePtr(x1 + size, y1);
+ int x2 = x1 + size / 2;
+ int y2 = y1 + size;
+ int deltaX = abs(x2 - x1);
+ int deltaY = abs(y2 - y1);
+ int signX = x1 < x2 ? 1 : -1;
+ int signY = y1 < y2 ? 1 : -1;
+ int error = deltaX - deltaY;
+
+ colorFill<PixelType>(ptr_right, ptr_left, color);
+
+ while (1) {
+ switch (fill_m) {
+ case kFillDisabled:
+ *ptr_left = *ptr_right = color;
+ break;
+ case kFillForeground:
+ case kFillBackground:
+ colorFill<PixelType>(ptr_right, ptr_left, color);
+ break;
+ case kFillGradient:
+ colorFill<PixelType>(ptr_right, ptr_left, calcGradient(gradient_h++, size));
+ break;
}
- } else {
- while (ptr_left < ptr_right) {
- colorFill<PixelType>(ptr_left, ptr_right, grad ? calcGradient(dy--, size) : color);
- ptr_left += pitch;
+
+ if (x1 == x2 && y1 == y2)
+ break;
+
+ int error2 = error * 2;
+
+ if (error2 > -deltaY) {
+ error -= deltaY;
+ x1 += signX;
+ ptr_right += signX;
+ ptr_left += -signX;
+ }
+
+ if (error2 < deltaX) {
+ error += deltaX;
+ y1 += signY;
ptr_right += pitch;
- if (hstep++ % 2) {
- ptr_left++;
- ptr_right--;
- }
+ ptr_left += pitch;
}
}
}
@@ -1140,85 +1433,113 @@ drawRoundedSquareAlg(int x1, int y1, int r, int w, int h, PixelType color, Vecto
int f, ddF_x, ddF_y;
int x, y, px, py;
int pitch = _activeSurface->pitch / _activeSurface->format.bytesPerPixel;
- int sw = 0, sp = 0, hp = h * pitch;
- PixelType *ptr_tl = (PixelType *)Base::_activeSurface->getBasePtr(x1 + r, y1 + r);
- PixelType *ptr_tr = (PixelType *)Base::_activeSurface->getBasePtr(x1 + w - r, y1 + r);
- PixelType *ptr_bl = (PixelType *)Base::_activeSurface->getBasePtr(x1 + r, y1 + h - r);
- PixelType *ptr_br = (PixelType *)Base::_activeSurface->getBasePtr(x1 + w - r, y1 + h - r);
- PixelType *ptr_fill = (PixelType *)Base::_activeSurface->getBasePtr(x1, y1);
-
- int real_radius = r;
- int short_h = h - (2 * r) + 2;
- int long_h = h;
-
- if (fill_m == kFillDisabled) {
- while (sw++ < Base::_strokeWidth) {
- colorFill<PixelType>(ptr_fill + sp + r, ptr_fill + w + 1 + sp - r, color);
- colorFill<PixelType>(ptr_fill + hp - sp + r, ptr_fill + w + hp + 1 - sp - r, color);
- sp += pitch;
+ // TODO: Split this up into border, bevel and interior functions
- __BE_RESET();
- r--;
+ if (fill_m != kFillDisabled) {
+ PixelType *ptr_tl = (PixelType *)Base::_activeSurface->getBasePtr(x1 + r, y1 + r);
+ PixelType *ptr_tr = (PixelType *)Base::_activeSurface->getBasePtr(x1 + w - r, y1 + r);
+ PixelType *ptr_bl = (PixelType *)Base::_activeSurface->getBasePtr(x1 + r, y1 + h - r);
+ PixelType *ptr_br = (PixelType *)Base::_activeSurface->getBasePtr(x1 + w - r, y1 + h - r);
+ PixelType *ptr_fill = (PixelType *)Base::_activeSurface->getBasePtr(x1, y1);
- while (x++ < y) {
- __BE_ALGORITHM();
- __BE_DRAWCIRCLE(ptr_tr, ptr_tl, ptr_bl, ptr_br, x, y, px, py);
+ int real_radius = r;
+ int short_h = h - (2 * r) + 2;
+ int long_h = h;
- if (Base::_strokeWidth > 1) {
- __BE_DRAWCIRCLE(ptr_tr, ptr_tl, ptr_bl, ptr_br, x - 1, y, px, py);
- __BE_DRAWCIRCLE(ptr_tr, ptr_tl, ptr_bl, ptr_br, x, y, px - pitch, py);
- }
- }
- }
+ BE_RESET();
- ptr_fill += pitch * real_radius;
- while (short_h--) {
- colorFill<PixelType>(ptr_fill, ptr_fill + Base::_strokeWidth, color);
- colorFill<PixelType>(ptr_fill + w - Base::_strokeWidth + 1, ptr_fill + w + 1, color);
- ptr_fill += pitch;
- }
- } else {
- __BE_RESET();
- PixelType color1, color2, color3, color4;
+ PixelType color1 = color;
+ if (fill_m == kFillBackground)
+ color1 = _bgColor;
if (fill_m == kFillGradient) {
+ PixelType color2, color3, color4;
+ precalcGradient(long_h);
+
while (x++ < y) {
- __BE_ALGORITHM();
+ BE_ALGORITHM();
color1 = calcGradient(real_radius - x, long_h);
color2 = calcGradient(real_radius - y, long_h);
color3 = calcGradient(long_h - r + x, long_h);
color4 = calcGradient(long_h - r + y, long_h);
- colorFill<PixelType>(ptr_tl - x - py, ptr_tr + x - py, color2);
- colorFill<PixelType>(ptr_tl - y - px, ptr_tr + y - px, color1);
+ gradientFill(ptr_tl - x - py, w - 2 * r + 2 * x, x1 + r - x - y, real_radius - y);
+ gradientFill(ptr_tl - y - px, w - 2 * r + 2 * y, x1 + r - y - x, real_radius - x);
- colorFill<PixelType>(ptr_bl - x + py, ptr_br + x + py, color4);
- colorFill<PixelType>(ptr_bl - y + px, ptr_br + y + px, color3);
+ gradientFill(ptr_bl - x + py, w - 2 * r + 2 * x, x1 + r - x - y, long_h - r + y);
+ gradientFill(ptr_bl - y + px, w - 2 * r + 2 * y, x1 + r - y - x, long_h - r + x);
- __BE_DRAWCIRCLE_XCOLOR(ptr_tr, ptr_tl, ptr_bl, ptr_br, x, y, px, py);
+ BE_DRAWCIRCLE_XCOLOR(ptr_tr, ptr_tl, ptr_bl, ptr_br, x, y, px, py);
}
} else {
while (x++ < y) {
- __BE_ALGORITHM();
+ BE_ALGORITHM();
- colorFill<PixelType>(ptr_tl - x - py, ptr_tr + x - py, color);
- colorFill<PixelType>(ptr_tl - y - px, ptr_tr + y - px, color);
+ colorFill<PixelType>(ptr_tl - x - py, ptr_tr + x - py, color1);
+ colorFill<PixelType>(ptr_tl - y - px, ptr_tr + y - px, color1);
- colorFill<PixelType>(ptr_bl - x + py, ptr_br + x + py, color);
- colorFill<PixelType>(ptr_bl - y + px, ptr_br + y + px, color);
+ colorFill<PixelType>(ptr_bl - x + py, ptr_br + x + py, color1);
+ colorFill<PixelType>(ptr_bl - y + px, ptr_br + y + px, color1);
// do not remove - messes up the drawing at lower resolutions
- __BE_DRAWCIRCLE(ptr_tr, ptr_tl, ptr_bl, ptr_br, x, y, px, py);
+ BE_DRAWCIRCLE(ptr_tr, ptr_tl, ptr_bl, ptr_br, x, y, px, py);
}
}
ptr_fill += pitch * r;
while (short_h--) {
- if (fill_m == kFillGradient)
- color = calcGradient(real_radius++, long_h);
- colorFill<PixelType>(ptr_fill, ptr_fill + w + 1, color);
+ if (fill_m == kFillGradient) {
+ gradientFill(ptr_fill, w + 1, x1, real_radius++);
+ } else {
+ colorFill<PixelType>(ptr_fill, ptr_fill + w + 1, color1);
+ }
+ ptr_fill += pitch;
+ }
+ }
+
+
+ if (Base::_strokeWidth) {
+ int sw = 0, sp = 0, hp = h * pitch;
+
+ PixelType *ptr_tl = (PixelType *)Base::_activeSurface->getBasePtr(x1 + r, y1 + r);
+ PixelType *ptr_tr = (PixelType *)Base::_activeSurface->getBasePtr(x1 + w - r, y1 + r);
+ PixelType *ptr_bl = (PixelType *)Base::_activeSurface->getBasePtr(x1 + r, y1 + h - r);
+ PixelType *ptr_br = (PixelType *)Base::_activeSurface->getBasePtr(x1 + w - r, y1 + h - r);
+ PixelType *ptr_fill = (PixelType *)Base::_activeSurface->getBasePtr(x1, y1);
+
+ int real_radius = r;
+ int short_h = h - (2 * r) + 2;
+
+ // TODO: A gradient effect on the bevel
+ PixelType color1, color2;
+ color1 = Base::_bevel ? _bevelColor : color;
+ color2 = color;
+
+ while (sw++ < Base::_strokeWidth) {
+ colorFill<PixelType>(ptr_fill + sp + r, ptr_fill + w + 1 + sp - r, color1);
+ colorFill<PixelType>(ptr_fill + hp - sp + r, ptr_fill + w + hp + 1 - sp - r, color2);
+ sp += pitch;
+
+ BE_RESET();
+ r--;
+
+ while (x++ < y) {
+ BE_ALGORITHM();
+ BE_DRAWCIRCLE_BCOLOR(ptr_tr, ptr_tl, ptr_bl, ptr_br, x, y, px, py);
+
+ if (Base::_strokeWidth > 1) {
+ BE_DRAWCIRCLE_BCOLOR(ptr_tr, ptr_tl, ptr_bl, ptr_br, x - 1, y, px, py);
+ BE_DRAWCIRCLE_BCOLOR(ptr_tr, ptr_tl, ptr_bl, ptr_br, x, y, px - pitch, py);
+ }
+ }
+ }
+
+ ptr_fill += pitch * real_radius;
+ while (short_h--) {
+ colorFill<PixelType>(ptr_fill, ptr_fill + Base::_strokeWidth, color1);
+ colorFill<PixelType>(ptr_fill + w - Base::_strokeWidth + 1, ptr_fill + w + 1, color2);
ptr_fill += pitch;
}
}
@@ -1235,7 +1556,7 @@ drawCircleAlg(int x1, int y1, int r, PixelType color, VectorRenderer::FillMode f
if (fill_m == kFillDisabled) {
while (sw++ < Base::_strokeWidth) {
- __BE_RESET();
+ BE_RESET();
r--;
*(ptr + y) = color;
@@ -1244,21 +1565,21 @@ drawCircleAlg(int x1, int y1, int r, PixelType color, VectorRenderer::FillMode f
*(ptr - py) = color;
while (x++ < y) {
- __BE_ALGORITHM();
- __BE_DRAWCIRCLE(ptr, ptr, ptr, ptr, x, y, px, py);
+ BE_ALGORITHM();
+ BE_DRAWCIRCLE(ptr, ptr, ptr, ptr, x, y, px, py);
if (Base::_strokeWidth > 1) {
- __BE_DRAWCIRCLE(ptr, ptr, ptr, ptr, x - 1, y, px, py);
- __BE_DRAWCIRCLE(ptr, ptr, ptr, ptr, x, y, px - pitch, py);
+ BE_DRAWCIRCLE(ptr, ptr, ptr, ptr, x - 1, y, px, py);
+ BE_DRAWCIRCLE(ptr, ptr, ptr, ptr, x, y, px - pitch, py);
}
}
}
} else {
colorFill<PixelType>(ptr - r, ptr + r, color);
- __BE_RESET();
+ BE_RESET();
while (x++ < y) {
- __BE_ALGORITHM();
+ BE_ALGORITHM();
colorFill<PixelType>(ptr - x + py, ptr + x + py, color);
colorFill<PixelType>(ptr - x - py, ptr + x - py, color);
colorFill<PixelType>(ptr - y + px, ptr + y + px, color);
@@ -1330,7 +1651,7 @@ drawRoundedSquareShadow(int x1, int y1, int r, int w, int h, int blur) {
int short_h = h - (2 * r) + 1;
- __BE_RESET();
+ BE_RESET();
// HACK: As we are drawing circles exploting 8-axis symmetry,
// there are 4 pixels on each circle which are drawn twice.
@@ -1339,7 +1660,7 @@ drawRoundedSquareShadow(int x1, int y1, int r, int w, int h, int blur) {
uint32 hb = 0;
while (x++ < y) {
- __BE_ALGORITHM();
+ BE_ALGORITHM();
if (((1 << x) & hb) == 0) {
blendFill(ptr_tr - px - r, ptr_tr + y - px, 0, alpha);
@@ -1360,64 +1681,6 @@ drawRoundedSquareShadow(int x1, int y1, int r, int w, int h, int blur) {
}
}
-template<typename PixelType>
-void VectorRendererSpec<PixelType>::
-drawRoundedSquareFakeBevel(int x1, int y1, int r, int w, int h, int amount) {
- int x, y;
- const int pitch = _activeSurface->pitch / _activeSurface->format.bytesPerPixel;
- int px, py;
- int sw = 0, sp = 0;
-
- uint32 rsq = r*r;
- frac_t T = 0, oldT;
- uint8 a1, a2;
-
- PixelType color = _bevelColor; //_format.RGBToColor(63, 60, 17);
-
- PixelType *ptr_tl = (PixelType *)Base::_activeSurface->getBasePtr(x1 + r, y1 + r);
- PixelType *ptr_tr = (PixelType *)Base::_activeSurface->getBasePtr(x1 + w - r, y1 + r);
- PixelType *ptr_bl = (PixelType *)Base::_activeSurface->getBasePtr(x1 + r, y1 + h - r);
- PixelType *ptr_fill = (PixelType *)Base::_activeSurface->getBasePtr(x1, y1);
-
- int short_h = h - 2 * r;
-
- while (sw++ < amount) {
- colorFill<PixelType>(ptr_fill + sp + r, ptr_fill + w + 1 + sp - r, color);
- sp += pitch;
-
- x = r - (sw - 1);
- y = 0;
- T = 0;
- px = pitch * x;
- py = 0;
-
- while (x > y++) {
- __WU_ALGORITHM();
-
- blendPixelPtr(ptr_tr + (y) - (px - pitch), color, a2);
- blendPixelPtr(ptr_tr + (x - 1) - (py), color, a2);
- blendPixelPtr(ptr_tl - (x - 1) - (py), color, a2);
- blendPixelPtr(ptr_tl - (y) - (px - pitch), color, a2);
- blendPixelPtr(ptr_bl - (y) + (px - pitch), color, a2);
- blendPixelPtr(ptr_bl - (x - 1) + (py), color, a2);
-
- blendPixelPtr(ptr_tr + (y) - (px), color, a1);
- blendPixelPtr(ptr_tr + (x) - (py), color, a1);
- blendPixelPtr(ptr_tl - (x) - (py), color, a1);
- blendPixelPtr(ptr_tl - (y) - (px), color, a1);
- blendPixelPtr(ptr_bl - (y) + (px), color, a1);
- blendPixelPtr(ptr_bl - (x) + (py), color, a1);
- }
- }
-
- ptr_fill += pitch * r;
- while (short_h-- >= 0) {
- colorFill<PixelType>(ptr_fill, ptr_fill + amount, color);
- ptr_fill += pitch;
- }
-}
-
-
/******************************************************************************/
@@ -1480,28 +1743,26 @@ drawLineAlg(int x1, int y1, int x2, int y2, int dx, int dy, PixelType color) {
Base::putPixel(x2, y2, color);
}
-/** ROUNDED SQUARES **/
+/** TAB ALGORITHM */
template<typename PixelType>
void VectorRendererAA<PixelType>::
-drawRoundedSquareAlg(int x1, int y1, int r, int w, int h, PixelType color, VectorRenderer::FillMode fill_m) {
- int x, y;
- const int pitch = Base::_activeSurface->pitch / Base::_activeSurface->format.bytesPerPixel;
- int px, py;
- int sw = 0, sp = 0, hp = h * pitch;
+drawTabAlg(int x1, int y1, int w, int h, int r, PixelType color, VectorRenderer::FillMode fill_m, int baseLeft, int baseRight) {
+ int x, y, px, py;
+ int pitch = Base::_activeSurface->pitch / Base::_activeSurface->format.bytesPerPixel;
+ int sw = 0, sp = 0, hp = 0;
- uint32 rsq = r*r;
frac_t T = 0, oldT;
uint8 a1, a2;
+ uint32 rsq = r*r;
PixelType *ptr_tl = (PixelType *)Base::_activeSurface->getBasePtr(x1 + r, y1 + r);
PixelType *ptr_tr = (PixelType *)Base::_activeSurface->getBasePtr(x1 + w - r, y1 + r);
- PixelType *ptr_bl = (PixelType *)Base::_activeSurface->getBasePtr(x1 + r, y1 + h - r);
- PixelType *ptr_br = (PixelType *)Base::_activeSurface->getBasePtr(x1 + w - r, y1 + h - r);
PixelType *ptr_fill = (PixelType *)Base::_activeSurface->getBasePtr(x1, y1);
- int short_h = h - 2 * r;
+ int real_radius = r;
- if (fill_m == VectorRenderer::kFillDisabled) {
+ if (fill_m == Base::kFillDisabled) {
+ color = 0;
while (sw++ < Base::_strokeWidth) {
colorFill<PixelType>(ptr_fill + sp + r, ptr_fill + w + 1 + sp - r, color);
colorFill<PixelType>(ptr_fill + hp - sp + r, ptr_fill + w + hp + 1 - sp - r, color);
@@ -1513,48 +1774,265 @@ drawRoundedSquareAlg(int x1, int y1, int r, int w, int h, PixelType color, Vecto
px = pitch * x;
py = 0;
+
while (x > y++) {
- __WU_ALGORITHM();
+ WU_ALGORITHM();
- if (sw != 1 && sw != Base::_strokeWidth)
- a2 = a1 = 255;
+ // sw == 1: outside, sw = _strokeWidth: inside
+ if (sw != Base::_strokeWidth)
+ a2 = 255;
- __WU_DRAWCIRCLE(ptr_tr, ptr_tl, ptr_bl, ptr_br, (x - 1), y, (px - pitch), py, a2);
- __WU_DRAWCIRCLE(ptr_tr, ptr_tl, ptr_bl, ptr_br, x, y, px, py, a1);
+ // inner arc
+ WU_DRAWCIRCLE_TOP(ptr_tr, ptr_tl, x, y, px, py, a2);
+
+ if (sw == 1) // outer arc
+ WU_DRAWCIRCLE_TOP(ptr_tr, ptr_tl, x, y, px - pitch, py, a1);
}
}
- ptr_fill += pitch * r;
- while (short_h-- >= 0) {
+ int short_h = h - r + 2;
+
+ ptr_fill += pitch * real_radius;
+ while (short_h--) {
colorFill<PixelType>(ptr_fill, ptr_fill + Base::_strokeWidth, color);
colorFill<PixelType>(ptr_fill + w - Base::_strokeWidth + 1, ptr_fill + w + 1, color);
ptr_fill += pitch;
}
+
+ if (baseLeft) {
+ sw = 0;
+ ptr_fill = (PixelType *)Base::_activeSurface->getBasePtr(x1, y1 + h + 1);
+ while (sw++ < Base::_strokeWidth) {
+ colorFill<PixelType>(ptr_fill - baseLeft, ptr_fill, color);
+ ptr_fill += pitch;
+ }
+ }
+
+ if (baseRight) {
+ sw = 0;
+ ptr_fill = (PixelType *)Base::_activeSurface->getBasePtr(x1 + w, y1 + h + 1);
+ while (sw++ < Base::_strokeWidth) {
+ colorFill<PixelType>(ptr_fill, ptr_fill + baseRight, color);
+ ptr_fill += pitch;
+ }
+ }
} else {
- x = r;
+ PixelType color1, color2;
+ color1 = color2 = color;
+
+ int long_h = h;
+ int short_h = h - real_radius + 2;
+ x = real_radius;
y = 0;
T = 0;
px = pitch * x;
py = 0;
- while (x > 1 + y++) {
- __WU_ALGORITHM();
+ Base::precalcGradient(long_h);
+
+ while (x > y++) {
+ WU_ALGORITHM();
+
+ if (fill_m == Base::kFillGradient) {
+ color1 = Base::calcGradient(real_radius - x, long_h);
+ color2 = Base::calcGradient(real_radius - y, long_h);
+
+ Base::gradientFill(ptr_tl - x - py + 1, w - 2 * r + 2 * x - 1, x1 + r - x - y + 1, real_radius - y);
+
+ // Only fill each horizontal line once (or we destroy
+ // the gradient effect at the edges)
+ if (T < oldT || y == 1)
+ Base::gradientFill(ptr_tl - y - px + 1, w - 2 * r + 2 * y - 1, x1 + r - y - x + 1, real_radius - x);
+
+ WU_DRAWCIRCLE_XCOLOR_TOP(ptr_tr, ptr_tl, x, y, px, py, a1, Base::blendPixelPtr);
+ } else {
+ colorFill<PixelType>(ptr_tl - x - py + 1, ptr_tr + x - py, color);
+ if (T < oldT || y == 1)
+ colorFill<PixelType>(ptr_tl - y - px + 1, ptr_tr + y - px, color);
+
+ WU_DRAWCIRCLE_TOP(ptr_tr, ptr_tl, x, y, px, py, a1);
+ }
+ }
+
+ ptr_fill += pitch * r;
+ while (short_h--) {
+ if (fill_m == Base::kFillGradient) {
+ Base::gradientFill(ptr_fill, w + 1, x1, real_radius++);
+ } else {
+ colorFill<PixelType>(ptr_fill, ptr_fill + w + 1, color);
+ }
+ ptr_fill += pitch;
+ }
+ }
+}
+
+
+/** ROUNDED SQUARES **/
+template<typename PixelType>
+void VectorRendererAA<PixelType>::
+drawRoundedSquareAlg(int x1, int y1, int r, int w, int h, PixelType color, VectorRenderer::FillMode fill_m) {
+ int x, y;
+ const int pitch = Base::_activeSurface->pitch / Base::_activeSurface->format.bytesPerPixel;
+ int px, py;
+
+ uint32 rsq = r*r;
+ frac_t T = 0, oldT;
+ uint8 a1, a2;
+
+ // TODO: Split this up into border, bevel and interior functions
- colorFill<PixelType>(ptr_tl - x - py, ptr_tr + x - py, color);
- colorFill<PixelType>(ptr_tl - y - px, ptr_tr + y - px, color);
+ if (Base::_strokeWidth) {
+ PixelType *ptr_tl = (PixelType *)Base::_activeSurface->getBasePtr(x1 + r, y1 + r);
+ PixelType *ptr_tr = (PixelType *)Base::_activeSurface->getBasePtr(x1 + w - r, y1 + r);
+ PixelType *ptr_bl = (PixelType *)Base::_activeSurface->getBasePtr(x1 + r, y1 + h - r);
+ PixelType *ptr_br = (PixelType *)Base::_activeSurface->getBasePtr(x1 + w - r, y1 + h - r);
+ PixelType *ptr_fill = (PixelType *)Base::_activeSurface->getBasePtr(x1, y1);
- colorFill<PixelType>(ptr_bl - x + py, ptr_br + x + py, color);
- colorFill<PixelType>(ptr_bl - y + px, ptr_br + y + px, color);
+ int sw = 0, sp = 0;
+ int short_h = h - 2 * r;
+ int hp = h * pitch;
- __WU_DRAWCIRCLE(ptr_tr, ptr_tl, ptr_bl, ptr_br, x, y, px, py, a1);
+ int strokeWidth = Base::_strokeWidth;
+ // If we're going to fill the inside, draw a slightly thicker border
+ // so we can blend the inside on top of it.
+ if (fill_m != Base::kFillDisabled) strokeWidth++;
+
+ // TODO: A gradient effect on the bevel
+ PixelType color1, color2;
+ color1 = Base::_bevel ? Base::_bevelColor : color;
+ color2 = color;
+
+
+ while (sw++ < strokeWidth) {
+ colorFill<PixelType>(ptr_fill + sp + r, ptr_fill + w + 1 + sp - r, color1);
+ colorFill<PixelType>(ptr_fill + hp - sp + r, ptr_fill + w + hp + 1 - sp - r, color2);
+ sp += pitch;
+
+ x = r - (sw - 1);
+ y = 0;
+ T = 0;
+ px = pitch * x;
+ py = 0;
+
+ while (x > y++) {
+ WU_ALGORITHM();
+
+ // sw == 1: outside, sw = _strokeWidth: inside
+ // We always draw the outer edge AAed, but the inner edge
+ // only when the inside isn't filled
+ if (sw != strokeWidth || fill_m != Base::kFillDisabled)
+ a2 = 255;
+
+ // inner arc
+ WU_DRAWCIRCLE_BCOLOR(ptr_tr, ptr_tl, ptr_bl, ptr_br, (x - 1), y, (px - pitch), py, a2);
+
+ if (sw == 1) // outer arc
+ WU_DRAWCIRCLE_BCOLOR(ptr_tr, ptr_tl, ptr_bl, ptr_br, x, y, px, py, a1);
+ }
}
ptr_fill += pitch * r;
while (short_h-- >= 0) {
- colorFill<PixelType>(ptr_fill, ptr_fill + w + 1, color);
+ colorFill<PixelType>(ptr_fill, ptr_fill + Base::_strokeWidth, color1);
+ colorFill<PixelType>(ptr_fill + w - Base::_strokeWidth + 1, ptr_fill + w + 1, color2);
ptr_fill += pitch;
}
}
+
+ r -= Base::_strokeWidth;
+ x1 += Base::_strokeWidth;
+ y1 += Base::_strokeWidth;
+ w -= 2*Base::_strokeWidth;
+ h -= 2*Base::_strokeWidth;
+ rsq = r*r;
+
+ if (w <= 0 || h <= 0)
+ return; // Only border is visible
+
+ if (fill_m != Base::kFillDisabled) {
+ if (fill_m == Base::kFillBackground)
+ color = Base::_bgColor;
+
+ PixelType *ptr_tl = (PixelType *)Base::_activeSurface->getBasePtr(x1 + r, y1 + r);
+ PixelType *ptr_tr = (PixelType *)Base::_activeSurface->getBasePtr(x1 + w - r, y1 + r);
+ PixelType *ptr_bl = (PixelType *)Base::_activeSurface->getBasePtr(x1 + r, y1 + h - r);
+ PixelType *ptr_br = (PixelType *)Base::_activeSurface->getBasePtr(x1 + w - r, y1 + h - r);
+ PixelType *ptr_fill = (PixelType *)Base::_activeSurface->getBasePtr(x1, y1);
+
+ int short_h = h - 2 * r;
+ x = r;
+ y = 0;
+ T = 0;
+ px = pitch * x;
+ py = 0;
+
+ if (fill_m == Base::kFillGradient) {
+
+ Base::precalcGradient(h);
+
+ PixelType color1, color2, color3, color4;
+ while (x > y++) {
+ WU_ALGORITHM();
+
+ color1 = Base::calcGradient(r - x, h);
+ color2 = Base::calcGradient(r - y, h);
+ color3 = Base::calcGradient(h - r + x, h);
+ color4 = Base::calcGradient(h - r + y, h);
+
+ Base::gradientFill(ptr_tl - x - py + 1, w - 2 * r + 2 * x - 1, x1 + r - x - y + 1, r - y);
+
+ // Only fill each horizontal line once (or we destroy
+ // the gradient effect at the edges)
+ if (T < oldT || y == 1)
+ Base::gradientFill(ptr_tl - y - px + 1, w - 2 * r + 2 * y - 1, x1 + r - y - x + 1, r - x);
+
+ Base::gradientFill(ptr_bl - x + py + 1, w - 2 * r + 2 * x - 1, x1 + r - x - y + 1, h - r + y);
+
+ // Only fill each horizontal line once (or we destroy
+ // the gradient effect at the edges)
+ if (T < oldT || y == 1)
+ Base::gradientFill(ptr_bl - y + px + 1, w - 2 * r + 2 * y - 1, x1 + r - y - x + 1, h - r + x);
+
+ // This shape is used for dialog backgrounds.
+ // If we're drawing on top of an empty overlay background,
+ // and the overlay supports alpha, we have to do AA by
+ // setting the dest alpha channel, instead of blending with
+ // dest color channels.
+ if (!g_system->hasFeature(OSystem::kFeatureOverlaySupportsAlpha))
+ WU_DRAWCIRCLE_XCOLOR(ptr_tr, ptr_tl, ptr_bl, ptr_br, x, y, px, py, a1, blendPixelPtr);
+ else
+ WU_DRAWCIRCLE_XCOLOR(ptr_tr, ptr_tl, ptr_bl, ptr_br, x, y, px, py, a1, blendPixelDestAlphaPtr);
+ }
+
+ ptr_fill += pitch * r;
+ while (short_h-- >= 0) {
+ Base::gradientFill(ptr_fill, w + 1, x1, r++);
+ ptr_fill += pitch;
+ }
+
+ } else {
+
+ while (x > 1 + y++) {
+ WU_ALGORITHM();
+
+ colorFill<PixelType>(ptr_tl - x - py + 1, ptr_tr + x - py, color);
+ if (T < oldT || y == 1)
+ colorFill<PixelType>(ptr_tl - y - px + 1, ptr_tr + y - px, color);
+
+ colorFill<PixelType>(ptr_bl - x + py + 1, ptr_br + x + py, color);
+ if (T < oldT || y == 1)
+ colorFill<PixelType>(ptr_bl - y + px + 1, ptr_br + y + px, color);
+
+ WU_DRAWCIRCLE(ptr_tr, ptr_tl, ptr_bl, ptr_br, x, y, px, py, a1);
+ }
+
+ ptr_fill += pitch * r;
+ while (short_h-- >= 0) {
+ colorFill<PixelType>(ptr_fill, ptr_fill + w + 1, color);
+ ptr_fill += pitch;
+ }
+ }
+ }
}
/** CIRCLES **/
@@ -1585,13 +2063,13 @@ drawCircleAlg(int x1, int y1, int r, PixelType color, VectorRenderer::FillMode f
*(ptr - px) = (PixelType)color;
while (x > y++) {
- __WU_ALGORITHM();
+ WU_ALGORITHM();
if (sw != 1 && sw != Base::_strokeWidth)
a2 = a1 = 255;
- __WU_DRAWCIRCLE(ptr, ptr, ptr, ptr, (x - 1), y, (px - pitch), py, a2);
- __WU_DRAWCIRCLE(ptr, ptr, ptr, ptr, x, y, px, py, a1);
+ WU_DRAWCIRCLE(ptr, ptr, ptr, ptr, (x - 1), y, (px - pitch), py, a2);
+ WU_DRAWCIRCLE(ptr, ptr, ptr, ptr, x, y, px, py, a1);
}
}
} else {
@@ -1603,14 +2081,14 @@ drawCircleAlg(int x1, int y1, int r, PixelType color, VectorRenderer::FillMode f
py = 0;
while (x > y++) {
- __WU_ALGORITHM();
+ WU_ALGORITHM();
colorFill<PixelType>(ptr - x + py, ptr + x + py, color);
colorFill<PixelType>(ptr - x - py, ptr + x - py, color);
colorFill<PixelType>(ptr - y + px, ptr + y + px, color);
colorFill<PixelType>(ptr - y - px, ptr + y - px, color);
- __WU_DRAWCIRCLE(ptr, ptr, ptr, ptr, x, y, px, py, a1);
+ WU_DRAWCIRCLE(ptr, ptr, ptr, ptr, x, y, px, py, a1);
}
}
}
diff --git a/graphics/VectorRendererSpec.h b/graphics/VectorRendererSpec.h
index 3ba7d88e4e..4ed80cb55f 100644
--- a/graphics/VectorRendererSpec.h
+++ b/graphics/VectorRendererSpec.h
@@ -103,7 +103,7 @@ protected:
* @param alpha Alpha intensity of the pixel (0-255)
*/
inline void blendPixel(int x, int y, PixelType color, uint8 alpha) {
- blendPixelPtr((PixelType*)Base::_activeSurface->getBasePtr(x, y), color, alpha);
+ blendPixelPtr((PixelType *)Base::_activeSurface->getBasePtr(x, y), color, alpha);
}
/**
@@ -121,6 +121,24 @@ protected:
inline void blendPixelPtr(PixelType *ptr, PixelType color, uint8 alpha);
/**
+ * Blends a single pixel on the surface in the given pixel pointer, using supplied color
+ * and Alpha intensity.
+ * If the destination pixel has 0 alpha, set the color and alpha channels,
+ * overwriting the destination pixel entirely.
+ * If the destination pixel has non-zero alpha, blend dest with src.
+ *
+ * This is implemented to prevent blendPixel() to calculate the surface pointer on each call.
+ * Optimized drawing algorithms should call this function when possible.
+ *
+ * @see blendPixel
+ * @param ptr Pointer to the pixel to blend on top of
+ * @param color Color of the pixel
+ * @param alpha Alpha intensity of the pixel (0-255)
+ */
+ inline void blendPixelDestAlphaPtr(PixelType *ptr, PixelType color, uint8 alpha);
+
+
+ /**
* PRIMITIVE DRAWING ALGORITHMS
*
* Generic algorithms for drawing all kinds of aliased primitive shapes.
@@ -172,7 +190,6 @@ protected:
*/
virtual void drawSquareShadow(int x, int y, int w, int h, int blur);
virtual void drawRoundedSquareShadow(int x, int y, int r, int w, int h, int blur);
- virtual void drawRoundedSquareFakeBevel(int x, int y, int r, int w, int h, int amount);
/**
* Calculates the color gradient on a given point.
@@ -185,6 +202,9 @@ protected:
*/
inline PixelType calcGradient(uint32 pos, uint32 max);
+ void precalcGradient(int h);
+ void gradientFill(PixelType *first, int width, int x, int y);
+
/**
* Fills several pixels in a row with a given color and the specified alpha blending.
*
@@ -199,6 +219,8 @@ protected:
while (first != last) blendPixelPtr(first++, color, alpha);
}
+ void darkenFill(PixelType *first, PixelType *last);
+
const PixelFormat _format;
const PixelType _redMask, _greenMask, _blueMask, _alphaMask;
@@ -208,6 +230,11 @@ protected:
PixelType _gradientStart; /**< Start color for the fill gradient */
PixelType _gradientEnd; /**< End color for the fill gradient */
+ int _gradientBytes[3]; /**< Color bytes of the active gradient, used to speed up calculation */
+
+ Common::Array<PixelType> _gradCache;
+ Common::Array<int> _gradIndexes;
+
PixelType _bevelColor;
PixelType _bitmapAlphaColor;
};
@@ -270,6 +297,10 @@ protected:
// VectorRenderer::applyConvolutionMatrix(VectorRenderer::kConvolutionHardBlur,
// Common::Rect(x, y, x + w + blur * 2, y + h + blur * 2));
}
+
+ virtual void drawTabAlg(int x, int y, int w, int h, int r,
+ PixelType color, VectorRenderer::FillMode fill_m,
+ int baseLeft = 0, int baseRight = 0);
};
#endif
diff --git a/graphics/cursorman.cpp b/graphics/cursorman.cpp
index 1d4e482bf4..425714ea34 100644
--- a/graphics/cursorman.cpp
+++ b/graphics/cursorman.cpp
@@ -31,10 +31,10 @@ DECLARE_SINGLETON(Graphics::CursorManager);
namespace Graphics {
CursorManager::~CursorManager() {
- for (int i = 0; i < _cursorStack.size(); ++i)
+ for (Common::Stack<Cursor *>::size_type i = 0; i < _cursorStack.size(); ++i)
delete _cursorStack[i];
_cursorStack.clear();
- for (int i = 0; i < _cursorPaletteStack.size(); ++i)
+ for (Common::Stack<Palette *>::size_type i = 0; i < _cursorPaletteStack.size(); ++i)
delete _cursorPaletteStack[i];
_cursorPaletteStack.clear();
}
diff --git a/graphics/font.cpp b/graphics/font.cpp
index 3f7152a95e..3b00cd8568 100644
--- a/graphics/font.cpp
+++ b/graphics/font.cpp
@@ -26,11 +26,20 @@
namespace Graphics {
+int Font::getKerningOffset(byte left, byte right) const {
+ return 0;
+}
+
int Font::getStringWidth(const Common::String &str) const {
int space = 0;
+ uint last = 0;
+
+ for (uint i = 0; i < str.size(); ++i) {
+ const uint cur = str[i];
+ space += getCharWidth(cur) + getKerningOffset(last, cur);
+ last = cur;
+ }
- for (uint i = 0; i < str.size(); ++i)
- space += getCharWidth(str[i]);
return space;
}
@@ -65,17 +74,22 @@ void Font::drawString(Surface *dst, const Common::String &sOld, int x, int y, in
// for now.
const int halfWidth = (w - ellipsisWidth) / 2;
int w2 = 0;
+ uint last = 0;
for (i = 0; i < s.size(); ++i) {
- int charWidth = getCharWidth(s[i]);
+ const uint cur = s[i];
+ int charWidth = getCharWidth(cur) + getKerningOffset(last, cur);
if (w2 + charWidth > halfWidth)
break;
+ last = cur;
w2 += charWidth;
- str += s[i];
+ str += cur;
}
+
// At this point we know that the first 'i' chars are together 'w2'
// pixels wide. We took the first i-1, and add "..." to them.
str += "...";
+ last = '.';
// The original string is width wide. Of those we already skipped past
// w2 pixels, which means (width - w2) remain.
@@ -85,7 +99,9 @@ void Font::drawString(Surface *dst, const Common::String &sOld, int x, int y, in
// (width + ellipsisWidth - w)
int skip = width + ellipsisWidth - w;
for (; i < s.size() && skip > 0; ++i) {
- skip -= getCharWidth(s[i]);
+ const uint cur = s[i];
+ skip -= getCharWidth(cur) + getKerningOffset(last, cur);
+ last = cur;
}
// Append the remaining chars, if any
@@ -104,8 +120,12 @@ void Font::drawString(Surface *dst, const Common::String &sOld, int x, int y, in
x = x + w - width;
x += deltax;
+ uint last = 0;
for (i = 0; i < str.size(); ++i) {
- w = getCharWidth(str[i]);
+ const uint cur = str[i];
+ x += getKerningOffset(last, cur);
+ last = cur;
+ w = getCharWidth(cur);
if (x+w > rightX)
break;
if (x >= leftX)
@@ -153,16 +173,18 @@ int Font::wordWrapText(const Common::String &str, int maxWidth, Common::Array<Co
// of a line. If we encounter such a word, we have to wrap it over multiple
// lines.
+ uint last = 0;
for (Common::String::const_iterator x = str.begin(); x != str.end(); ++x) {
const byte c = *x;
- const int w = getCharWidth(c);
+ const int w = getCharWidth(c) + getKerningOffset(last, c);
+ last = c;
const bool wouldExceedWidth = (lineWidth + tmpWidth + w > maxWidth);
// If this char is a whitespace, then it represents a potential
// 'wrap point' where wrapping could take place. Everything that
// came before it can now safely be added to the line, as we know
// that it will not have to be wrapped.
- if (isspace(c)) {
+ if (Common::isSpace(c)) {
line += tmpStr;
lineWidth += tmpWidth;
@@ -186,9 +208,11 @@ int Font::wordWrapText(const Common::String &str, int maxWidth, Common::Array<Co
if (lineWidth > 0) {
wrapper.add(line, lineWidth);
// Trim left side
- while (tmpStr.size() && isspace(static_cast<unsigned char>(tmpStr[0]))) {
- tmpWidth -= getCharWidth(tmpStr[0]);
+ while (tmpStr.size() && Common::isSpace(tmpStr[0])) {
tmpStr.deleteChar(0);
+ // This is not very fast, but it is the simplest way to
+ // assure we do not mess something up because of kerning.
+ tmpWidth = getStringWidth(tmpStr);
}
} else {
wrapper.add(tmpStr, tmpWidth);
diff --git a/graphics/font.h b/graphics/font.h
index 9c0b4affc1..6819b42f52 100644
--- a/graphics/font.h
+++ b/graphics/font.h
@@ -73,6 +73,15 @@ public:
virtual int getCharWidth(byte chr) const = 0;
/**
+ * Query the kerning offset between two characters.
+ *
+ * @param left The left character. May be 0.
+ * @param right The right character. May be 0.
+ * @return The horizontal displacement.
+ */
+ virtual int getKerningOffset(byte left, byte right) const;
+
+ /**
* Draw a character at a specific point on a surface.
*
* Note that the point describes the top left edge point of the
diff --git a/graphics/fontman.cpp b/graphics/fontman.cpp
index a10d27a2b0..8d967d595f 100644
--- a/graphics/fontman.cpp
+++ b/graphics/fontman.cpp
@@ -72,6 +72,20 @@ const struct {
{ 0, FontManager::kConsoleFont }
};
+bool FontManager::setLocalizedFont(const Common::String &name) {
+ Common::String lowercaseName = name;
+ lowercaseName.toLowercase();
+
+ // We only update the localized font in case the name is properly assigned
+ // to a font.
+ if (_fontMap.contains(lowercaseName) && _fontMap.getVal(lowercaseName) != 0) {
+ _localizedFontName = lowercaseName;
+ return true;
+ } else {
+ return false;
+ }
+}
+
bool FontManager::assignFontToName(const Common::String &name, const Font *font) {
Common::String lowercaseName = name;
lowercaseName.toLowercase();
@@ -79,19 +93,19 @@ bool FontManager::assignFontToName(const Common::String &name, const Font *font)
return true;
}
-bool FontManager::setFont(FontUsage usage, const Font *font) {
+bool FontManager::setFont(FontUsage usage, const BdfFont *font) {
switch (usage) {
case kConsoleFont:
delete g_consolefont;
- g_consolefont = (const BdfFont *)font;
+ g_consolefont = font;
break;
case kGUIFont:
delete g_sysfont;
- g_sysfont = (const BdfFont *)font;
+ g_sysfont = font;
break;
case kBigGUIFont:
delete g_sysfont_big;
- g_sysfont_big = (const BdfFont *)font;
+ g_sysfont_big = font;
break;
default:
return false;
@@ -103,6 +117,11 @@ void FontManager::removeFontName(const Common::String &name) {
Common::String lowercaseName = name;
lowercaseName.toLowercase();
_fontMap.erase(lowercaseName);
+
+ // In case the current localized font is removed, we fall back to the
+ // default font again.
+ if (_localizedFontName == lowercaseName)
+ _localizedFontName.clear();
}
const Font *FontManager::getFontByName(const Common::String &name) const {
@@ -126,51 +145,16 @@ const Font *FontManager::getFontByUsage(FontUsage usage) const {
case kBigGUIFont:
return g_sysfont_big;
case kLocalizedFont:
- {
- // First try to find a kBigGUIFont
- Common::String fontName = getLocalizedFontNameByUsage(kBigGUIFont);
- if (!fontName.empty()) {
- const Font *font = getFontByName(fontName);
- if (font)
- return font;
- }
- // Try kGUIFont
- fontName = getLocalizedFontNameByUsage(kGUIFont);
- if (!fontName.empty()) {
- const Font *font = getFontByName(fontName);
- if (font)
- return font;
- }
-#ifdef USE_TRANSLATION
- // Accept any other font that has the charset in its name
- for (Common::HashMap<Common::String, const Font *>::const_iterator it = _fontMap.begin() ; it != _fontMap.end() ; ++it) {
- if (it->_key.contains(TransMan.getCurrentCharset()))
- return it->_value;
- }
-#endif
- // Fallback: return a non localized kGUIFont.
- // Maybe we should return a null pointer instead?
- return g_sysfont;
- }
+ // By default use the big font as localized font
+ if (_localizedFontName.empty())
+ return g_sysfont_big;
+ else
+ return _fontMap[_localizedFontName];
}
return 0;
}
-Common::String FontManager::getLocalizedFontNameByUsage(FontUsage usage) const {
- // We look for a name that matches the usage and that ends in .bdf.
- // It should also not contain "-ascii" or "-iso-" in its name.
- // We take the first name that matches.
- for (int i = 0; builtinFontNames[i].name; i++) {
- if (builtinFontNames[i].id == usage) {
- Common::String fontName(builtinFontNames[i].name);
- if (!fontName.contains("-ascii") && !fontName.contains("-iso-") && fontName.contains(".bdf"))
- return genLocalizedFontFilename(fontName);
- }
- }
- return Common::String();
-}
-
Common::String FontManager::genLocalizedFontFilename(const Common::String &filename) const {
#ifndef USE_TRANSLATION
return filename;
diff --git a/graphics/fontman.h b/graphics/fontman.h
index 09c1a198ff..42f7d856fa 100644
--- a/graphics/fontman.h
+++ b/graphics/fontman.h
@@ -32,6 +32,7 @@
namespace Graphics {
class Font;
+class BdfFont;
class FontManager : public Common::Singleton<FontManager> {
public:
@@ -43,6 +44,14 @@ public:
};
/**
+ * Sets the localized font name.
+ *
+ * @param name the name of the localized font.
+ * @return true when the font was present, false otherwise.
+ */
+ bool setLocalizedFont(const Common::String &name);
+
+ /**
* Retrieve a font object based on its 'name'.
*
* @param name the name of the font to be retrieved.
@@ -67,7 +76,7 @@ public:
* @param font the font object
* @return true on success, false on failure
*/
- bool setFont(FontUsage usage, const Font *font);
+ bool setFont(FontUsage usage, const BdfFont *font);
/**
* Removes binding from name to font
@@ -96,22 +105,13 @@ public:
//const Font *getFontBySize(int size???) const;
-protected:
- /**
- * Get the name of the localized font for the given usage. There is no garanty that
- * the font exists. If the usage is kLocalizedFont it returns an empty string.
- *
- * @param usage a FontUsage enum value indicating what the font will be used for.
- * @return the name of a localized font or an empty string if no suitable font was found.
- */
- Common::String getLocalizedFontNameByUsage(FontUsage usage) const;
-
private:
friend class Common::Singleton<SingletonBaseType>;
FontManager();
~FontManager();
Common::HashMap<Common::String, const Font *> _fontMap;
+ Common::String _localizedFontName;
};
diff --git a/graphics/fonts/bdf.cpp b/graphics/fonts/bdf.cpp
index 58c48ed877..6d4befa37c 100644
--- a/graphics/fonts/bdf.cpp
+++ b/graphics/fonts/bdf.cpp
@@ -29,768 +29,594 @@
namespace Graphics {
-void free_font(BdfFontData *pf);
+BdfFont::BdfFont(const BdfFontData &data, DisposeAfterUse::Flag dispose)
+ : _data(data), _dispose(dispose) {
+}
BdfFont::~BdfFont() {
- if (_font) {
- free_font(_font);
+ if (_dispose == DisposeAfterUse::YES) {
+ for (int i = 0; i < _data.numCharacters; ++i)
+ delete[] _data.bitmaps[i];
+ delete[] _data.bitmaps;
+ delete[] _data.advances;
+ delete[] _data.boxes;
}
}
int BdfFont::getFontHeight() const {
- return _desc.height;
+ return _data.height;
}
int BdfFont::getMaxCharWidth() const {
- return _desc.maxwidth;
+ return _data.maxAdvance;
}
int BdfFont::getCharWidth(byte chr) const {
- // If no width table is specified, return the maximum width
- if (!_desc.width)
- return _desc.maxwidth;
- // If this character is not included in the font, use the default char.
- if (chr < _desc.firstchar || _desc.firstchar + _desc.size < chr) {
- chr = _desc.defaultchar;
- }
- return _desc.width[chr - _desc.firstchar];
+ // In case all font have the same advance value, we use the maximum.
+ if (!_data.advances)
+ return _data.maxAdvance;
+
+ const int ch = mapToIndex(chr);
+ // In case no mapping exists, we use the maximum advance.
+ if (ch < 0)
+ return _data.maxAdvance;
+ else
+ return _data.advances[ch];
}
template<typename PixelType>
-void drawCharIntern(byte *ptr, uint pitch, const bitmap_t *src, int h, int minX, int maxX, const PixelType color) {
- const bitmap_t maxXMask = ~((1 << (16 - maxX)) - 1);
- while (h-- > 0) {
- bitmap_t buffer = READ_UINT16(src);
- src++;
-
- buffer &= maxXMask;
- buffer <<= minX;
- PixelType *tmp = (PixelType *)ptr;
- while (buffer != 0) {
- if ((buffer & 0x8000) != 0)
- *tmp = color;
- tmp++;
- buffer <<= 1;
+void drawCharIntern(byte *ptr, uint pitch, const byte *src, int h, int width, int minX, int maxX, const PixelType color) {
+ byte data = 0;
+ while (h--) {
+ PixelType *dst = (PixelType *)ptr;
+
+ for (int x = 0; x < width; ++x) {
+ if (!(x % 8))
+ data = *src++;
+
+ if (x >= minX && x <= maxX && (data & 0x80))
+ dst[x] = color;
+
+ data <<= 1;
}
ptr += pitch;
}
}
+int BdfFont::mapToIndex(byte ch) const {
+ // Check whether the character is included
+ if (_data.firstCharacter <= ch && ch <= _data.firstCharacter + _data.numCharacters) {
+ if (_data.bitmaps[ch - _data.firstCharacter])
+ return ch - _data.firstCharacter;
+ }
+
+ return _data.defaultCharacter - _data.firstCharacter;
+}
+
void BdfFont::drawChar(Surface *dst, byte chr, const int tx, const int ty, const uint32 color) const {
assert(dst != 0);
- // asserting _desc.maxwidth <= 50: let the theme designer decide what looks best
- assert(_desc.bits != 0 && _desc.maxwidth <= 50);
+ // TODO: Where is the relation between the max advance being smaller or
+ // equal to 50 and the decision of the theme designer?
+ // asserting _data.maxAdvance <= 50: let the theme designer decide what looks best
+ assert(_data.maxAdvance <= 50);
assert(dst->format.bytesPerPixel == 1 || dst->format.bytesPerPixel == 2);
- // If this character is not included in the font, use the default char.
- if (chr < _desc.firstchar || chr >= _desc.firstchar + _desc.size) {
- chr = _desc.defaultchar;
- }
-
- chr -= _desc.firstchar;
+ const int idx = mapToIndex(chr);
+ if (idx < 0)
+ return;
- int bbw, bbh, bbx, bby;
+ int width, height, xOffset, yOffset;
// Get the bounding box of the character
- if (!_desc.bbx) {
- bbw = _desc.fbbw;
- bbh = _desc.fbbh;
- bbx = _desc.fbbx;
- bby = _desc.fbby;
+ if (!_data.boxes) {
+ width = _data.defaultBox.width;
+ height = _data.defaultBox.height;
+ xOffset = _data.defaultBox.xOffset;
+ yOffset = _data.defaultBox.yOffset;
} else {
- bbw = _desc.bbx[chr].w;
- bbh = _desc.bbx[chr].h;
- bbx = _desc.bbx[chr].x;
- bby = _desc.bbx[chr].y;
+ width = _data.boxes[idx].width;
+ height = _data.boxes[idx].height;
+ xOffset = _data.boxes[idx].xOffset;
+ yOffset = _data.boxes[idx].yOffset;
}
- byte *ptr = (byte *)dst->getBasePtr(tx + bbx, ty + _desc.ascent - bby - bbh);
+ int y = ty + _data.ascent - yOffset - height;
+ int x = tx + xOffset;
- const bitmap_t *tmp = _desc.bits + (_desc.offset ? _desc.offset[chr] : (chr * _desc.fbbh));
+ const byte *src = _data.bitmaps[idx];
- int y = MIN(bbh, ty + _desc.ascent - bby);
- tmp += bbh - y;
- y -= MAX(0, ty + _desc.ascent - bby - dst->h);
+ const int bytesPerRow = (width + 7) / 8;
+ const int originalWidth = width;
- if (dst->format.bytesPerPixel == 1)
- drawCharIntern<byte>(ptr, dst->pitch, tmp, y, MAX(0, -(tx + bbx)), MIN(bbw, dst->w - tx - bbx), color);
- else if (dst->format.bytesPerPixel == 2)
- drawCharIntern<uint16>(ptr, dst->pitch, tmp, y, MAX(0, -(tx + bbx)), MIN(bbw, dst->w - tx - bbx), color);
-}
+ // Make sure we do not draw outside the surface
+ if (y < 0) {
+ src -= y * bytesPerRow;
+ height += y;
+ y = 0;
+ }
+ if (y + height > dst->h)
+ height = dst->h - y;
-#pragma mark -
-
-/* BEGIN font.h*/
-/* bitmap_t helper macros*/
-#define BITMAP_WORDS(x) (((x)+15)/16) /* image size in words*/
-#define BITMAP_BYTES(x) (BITMAP_WORDS(x)*sizeof(bitmap_t))
-#define BITMAP_BITSPERIMAGE (sizeof(bitmap_t) * 8)
-#define BITMAP_BITVALUE(n) ((bitmap_t) (((bitmap_t) 1) << (n)))
-#define BITMAP_FIRSTBIT (BITMAP_BITVALUE(BITMAP_BITSPERIMAGE - 1))
-#define BITMAP_TESTBIT(m) ((m) & BITMAP_FIRSTBIT)
-#define BITMAP_SHIFTBIT(m) ((bitmap_t) ((m) << 1))
-
-/* builtin C-based proportional/fixed font structure */
-/* based on The Microwindows Project http://microwindows.org */
-struct BdfFontData {
- char *name; /* font name */
- int maxwidth; /* max width in pixels */
- int height; /* height in pixels */
- int ascent; /* ascent (baseline) height */
- int firstchar; /* first character in bitmap */
- int size; /* font size in glyphs */
- bitmap_t *bits; /* 16-bit right-padded bitmap data */
- unsigned long *offset; /* offsets into bitmap data */
- unsigned char *width; /* character widths or NULL if fixed */
- BBX *bbx; /* character bounding box or NULL if fixed */
- int defaultchar; /* default char (not glyph index) */
- long bits_size; /* # words of bitmap_t bits */
-
- /* unused by runtime system, read in by convbdf */
- char *facename; /* facename of font */
- char *copyright; /* copyright info for loadable fonts */
- int pixel_size;
- int descent;
- int fbbw, fbbh, fbbx, fbby;
-};
-/* END font.h */
-
-#define isprefix(buf,str) (!strncmp(buf, str, strlen(str)))
-#define strequal(s1,s2) (!strcmp(s1, s2))
-
-#define EXTRA 300
-
-int start_char = 0;
-int limit_char = 255;
-
-BdfFontData *bdf_read_font(Common::SeekableReadStream &fp);
-int bdf_read_header(Common::SeekableReadStream &fp, BdfFontData *pf);
-int bdf_read_bitmaps(Common::SeekableReadStream &fp, BdfFontData *pf);
-char *bdf_getline(Common::SeekableReadStream &fp, char *buf, int len);
-bitmap_t bdf_hexval(unsigned char *buf);
-
-void free_font(BdfFontData *pf) {
- if (!pf)
+ if (height <= 0)
return;
- free(pf->name);
- free(pf->facename);
- free(pf->copyright);
- free(pf->bits);
- free(pf->offset);
- free(pf->width);
- free(pf->bbx);
- free(pf);
-}
-
-/* build incore structure from .bdf file*/
-BdfFontData *bdf_read_font(Common::SeekableReadStream &fp) {
- BdfFontData *pf;
- uint32 pos = fp.pos();
- pf = (BdfFontData *)calloc(1, sizeof(BdfFontData));
- if (!pf)
- goto errout;
-
- if (!bdf_read_header(fp, pf)) {
- warning("Error reading font header");
- goto errout;
+ int xStart = 0;
+ if (x < 0) {
+ xStart = -x;
+ width += x;
+ x = 0;
}
- fp.seek(pos, SEEK_SET);
+ if (x + width > dst->w)
+ width = dst->w - x;
- if (!bdf_read_bitmaps(fp, pf)) {
- warning("Error reading font bitmaps");
- goto errout;
- }
+ if (width <= 0)
+ return;
- return pf;
+ const int xEnd = xStart + width - 1;
-errout:
- free_font(pf);
- return NULL;
+ byte *ptr = (byte *)dst->getBasePtr(x, y);
+
+ if (dst->format.bytesPerPixel == 1)
+ drawCharIntern<byte>(ptr, dst->pitch, src, height, originalWidth, xStart, xEnd, color);
+ else if (dst->format.bytesPerPixel == 2)
+ drawCharIntern<uint16>(ptr, dst->pitch, src, height, originalWidth, xStart, xEnd, color);
}
-/* read bdf font header information, return 0 on error*/
-int bdf_read_header(Common::SeekableReadStream &fp, BdfFontData *pf) {
- int encoding = 0;
- int nchars = 0, maxwidth, maxheight;
- int firstchar = 65535;
- int lastchar = -1;
- char buf[256];
- char facename[256];
- char copyright[256];
- memset(facename, 0, sizeof(facename));
- memset(copyright, 0, sizeof(copyright));
-
- /* set certain values to errors for later error checking*/
- pf->defaultchar = -1;
- pf->ascent = -1;
- pf->descent = -1;
-
- for (;;) {
- if (!bdf_getline(fp, buf, sizeof(buf))) {
- warning("Error: EOF on file");
- return 0;
- }
+namespace {
- /* note: the way sscanf is used here ensures that a terminating null
- character is automatically added. Refer to:
- http://pubs.opengroup.org/onlinepubs/009695399/functions/fscanf.html */
+inline byte hexToInt(char c) {
+ if (c >= '0' && c <= '9')
+ return c - '0';
+ else if (c >= 'A' && c <= 'F')
+ return c - 'A' + 10;
+ else if (c >= 'a' && c <= 'f')
+ return c - 'a' + 10;
+ else
+ return 0;
+}
- if (isprefix(buf, "FONT ")) { /* not required*/
- if (sscanf(buf, "FONT %[^\n]", facename) != 1) {
- warning("Error: bad 'FONT'");
- return 0;
- }
+byte *loadCharacter(Common::SeekableReadStream &stream, int &encoding, int &advance, BdfBoundingBox &box) {
+ Common::String line;
+ byte *bitmap = 0;
- pf->facename = strdup(facename);
- continue;
+ while (true) {
+ line = stream.readLine();
+ if (stream.err() || stream.eos()) {
+ warning("BdfFont::loadCharacter: Premature end of file");
+ delete[] bitmap;
+ return 0;
}
- if (isprefix(buf, "COPYRIGHT ")) { /* not required*/
- if (sscanf(buf, "COPYRIGHT \"%[^\"]", copyright) != 1) {
- warning("Error: bad 'COPYRIGHT'");
- return 0;
- }
- pf->copyright = strdup(copyright);
- continue;
- }
- if (isprefix(buf, "DEFAULT_CHAR ")) { /* not required*/
- if (sscanf(buf, "DEFAULT_CHAR %d", &pf->defaultchar) != 1) {
- warning("Error: bad 'DEFAULT_CHAR'");
+ if (line.hasPrefix("ENCODING ")) {
+ if (sscanf(line.c_str(), "ENCODING %d", &encoding) != 1) {
+ warning("BdfFont::loadCharacter: Invalid ENCODING");
+ delete[] bitmap;
return 0;
}
- }
- if (isprefix(buf, "FONT_DESCENT ")) {
- if (sscanf(buf, "FONT_DESCENT %d", &pf->descent) != 1) {
- warning("Error: bad 'FONT_DESCENT'");
+ } else if (line.hasPrefix("DWIDTH ")) {
+ int yAdvance;
+ if (sscanf(line.c_str(), "DWIDTH %d %d", &advance, &yAdvance) != 2) {
+ warning("BdfFont::loadCharacter: Invalid DWIDTH");
+ delete[] bitmap;
return 0;
}
- continue;
- }
- if (isprefix(buf, "FONT_ASCENT ")) {
- if (sscanf(buf, "FONT_ASCENT %d", &pf->ascent) != 1) {
- warning("Error: bad 'FONT_ASCENT'");
+
+ if (yAdvance != 0) {
+ warning("BdfFont::loadCharacter: Character %d has an y advance of %d", encoding, yAdvance);
+ delete[] bitmap;
return 0;
}
- continue;
- }
- if (isprefix(buf, "FONTBOUNDINGBOX ")) {
- if (sscanf(buf, "FONTBOUNDINGBOX %d %d %d %d",
- &pf->fbbw, &pf->fbbh, &pf->fbbx, &pf->fbby) != 4) {
- warning("Error: bad 'FONTBOUNDINGBOX'");
+
+ if (advance < 0) {
+ warning("BdfFont::loadCharacter: Character %d has an x advance of %d", encoding, advance);
+ delete[] bitmap;
return 0;
}
- continue;
- }
- if (isprefix(buf, "CHARS ")) {
- if (sscanf(buf, "CHARS %d", &nchars) != 1) {
- warning("Error: bad 'CHARS'");
+ } else if (line.hasPrefix("BBX ")) {
+ int width, height, xOffset, yOffset;
+ if (sscanf(line.c_str(), "BBX %d %d %d %d",
+ &width, &height, &xOffset, &yOffset) != 4) {
+ warning("BdfFont::loadCharacter: Invalid BBX");
+ delete[] bitmap;
return 0;
}
- continue;
- }
- /*
- * Reading ENCODING is necessary to get firstchar/lastchar
- * which is needed to pre-calculate our offset and widths
- * array sizes.
- */
- if (isprefix(buf, "ENCODING ")) {
- if (sscanf(buf, "ENCODING %d", &encoding) != 1) {
- warning("Error: bad 'ENCODING'");
- return 0;
- }
- if (encoding >= 0 &&
- encoding <= limit_char &&
- encoding >= start_char) {
-
- if (firstchar > encoding)
- firstchar = encoding;
- if (lastchar < encoding)
- lastchar = encoding;
+ box.width = width;
+ box.height = height;
+ box.xOffset = xOffset;
+ box.yOffset = yOffset;
+ } else if (line == "BITMAP") {
+ const uint bytesPerRow = (box.width + 7) / 8;
+ byte *dst = bitmap = new byte[box.height * bytesPerRow];
+
+ for (int y = 0; y < box.height; ++y) {
+ line = stream.readLine();
+ if (stream.err() || stream.eos()) {
+ warning("BdfFont::loadCharacter: Premature end of file");
+ delete[] bitmap;
+ return 0;
+ }
+
+ if (line.size() != 2 * bytesPerRow) {
+ warning("BdfFont::loadCharacter: Pixel line has wrong size");
+ delete[] bitmap;
+ return 0;
+ }
+
+ for (uint x = 0; x < bytesPerRow; ++x) {
+ char nibble1 = line[x * 2 + 0];
+ char nibble2 = line[x * 2 + 1];
+ *dst++ = (hexToInt(nibble1) << 4) | hexToInt(nibble2);
+ }
}
- continue;
+ } else if (line == "ENDCHAR") {
+ return bitmap;
}
- if (strequal(buf, "ENDFONT"))
- break;
}
- /* calc font height*/
- if (pf->ascent < 0 || pf->descent < 0 || firstchar < 0) {
- warning("Error: Invalid BDF file, requires FONT_ASCENT/FONT_DESCENT/ENCODING");
- return 0;
- }
- pf->height = pf->ascent + pf->descent;
-
- /* calc default char*/
- if (pf->defaultchar < 0 ||
- pf->defaultchar < firstchar ||
- pf->defaultchar > limit_char)
- pf->defaultchar = firstchar;
-
- /* calc font size (offset/width entries)*/
- pf->firstchar = firstchar;
- pf->size = lastchar - firstchar + 1;
-
- /* use the font boundingbox to get initial maxwidth*/
- /*maxwidth = pf->fbbw - pf->fbbx;*/
- maxwidth = pf->fbbw;
- maxheight = pf->fbbh;
-
- /* initially use font bounding box for bits allocation*/
- pf->bits_size = nchars * BITMAP_WORDS(maxwidth) * maxheight;
-
- /* allocate bits, offset, and width arrays*/
- pf->bits = (bitmap_t *)malloc(pf->bits_size * sizeof(bitmap_t) + EXTRA);
- pf->offset = (unsigned long *)malloc(pf->size * sizeof(unsigned long));
- pf->width = (unsigned char *)malloc(pf->size * sizeof(unsigned char));
- pf->bbx = (BBX *)malloc(pf->size * sizeof(BBX));
-
- if (!pf->bits || !pf->offset || !pf->width) {
- warning("Error: no memory for font load");
- return 0;
- }
+ delete[] bitmap;
+ return 0;
+}
- return 1;
+void freeBitmaps(byte **bitmaps, int size) {
+ for (int i = 0; i < size; ++i)
+ delete[] bitmaps[i];
}
-/* read bdf font bitmaps, return 0 on error*/
-int bdf_read_bitmaps(Common::SeekableReadStream &fp, BdfFontData *pf) {
- long ofs = 0;
- int maxwidth = 0;
- int i, k, encoding = 0, width = 0;
- int bbw = 0, bbh = 0, bbx = 0, bby = 0;
- int proportional = 0;
- int need_bbx = 0;
- int encodetable = 0;
- long l;
- char buf[256];
-
- /* initially mark offsets as not used*/
- for (i = 0; i < pf->size; ++i)
- pf->offset[i] = (unsigned long)-1;
-
- for (;;) {
- if (!bdf_getline(fp, buf, sizeof(buf))) {
- warning("Error: EOF on file");
+} // End of anonymous namespace
+
+BdfFont *BdfFont::loadFont(Common::SeekableReadStream &stream) {
+ BdfFontData font;
+ memset(&font, 0, sizeof(font));
+ font.ascent = -1;
+ font.defaultCharacter = -1;
+
+ // We only load the first 256 characters
+ font.numCharacters = 256;
+ byte **bitmaps = new byte *[font.numCharacters];
+ memset(bitmaps, 0, sizeof(byte *) * font.numCharacters);
+ byte *advances = new byte[font.numCharacters];
+ BdfBoundingBox *boxes = new BdfBoundingBox[font.numCharacters];
+
+ int descent = -1;
+
+ Common::String line;
+ while (true) {
+ line = stream.readLine();
+ if (stream.err() || stream.eos()) {
+ warning("BdfFont::loadFont: Premature end of file");
+ freeBitmaps(bitmaps, font.numCharacters);
+ delete[] bitmaps;
+ delete[] advances;
+ delete[] boxes;
return 0;
}
- if (isprefix(buf, "STARTCHAR")) {
- encoding = width = bbw = bbh = bbx = bby = -1;
- continue;
- }
- if (isprefix(buf, "ENCODING ")) {
- if (sscanf(buf, "ENCODING %d", &encoding) != 1) {
- warning("Error: bad 'ENCODING'");
+
+ // Only parse and handle declarations we actually need
+ if (line.hasPrefix("FONTBOUNDINGBOX ")) {
+ int width, height, xOffset, yOffset;
+ if (sscanf(line.c_str(), "FONTBOUNDINGBOX %d %d %d %d",
+ &width, &height, &xOffset, &yOffset) != 4) {
+ warning("BdfFont::loadFont: Invalid FONTBOUNDINGBOX");
+ freeBitmaps(bitmaps, font.numCharacters);
+ delete[] bitmaps;
+ delete[] advances;
+ delete[] boxes;
return 0;
}
- if (encoding < start_char || encoding > limit_char)
- encoding = -1;
- continue;
- }
- if (isprefix(buf, "DWIDTH ")) {
- if (sscanf(buf, "DWIDTH %d", &width) != 1) {
- warning("Error: bad 'DWIDTH'");
+
+ font.defaultBox.width = width;
+ font.defaultBox.height = height;
+ font.defaultBox.xOffset = xOffset;
+ font.defaultBox.yOffset = yOffset;
+ } else if (line.hasPrefix("FONT_ASCENT ")) {
+ if (sscanf(line.c_str(), "FONT_ASCENT %d", &font.ascent) != 1) {
+ warning("BdfFont::loadFont: Invalid FONT_ASCENT");
+ freeBitmaps(bitmaps, font.numCharacters);
+ delete[] bitmaps;
+ delete[] advances;
+ delete[] boxes;
return 0;
}
- /* use font boundingbox width if DWIDTH <= 0*/
- if (width <= 0)
- width = pf->fbbw - pf->fbbx;
- continue;
- }
- if (isprefix(buf, "BBX ")) {
- if (sscanf(buf, "BBX %d %d %d %d", &bbw, &bbh, &bbx, &bby) != 4) {
- warning("Error: bad 'BBX'");
+ } else if (line.hasPrefix("FONT_DESCENT ")) {
+ if (sscanf(line.c_str(), "FONT_DESCENT %d", &descent) != 1) {
+ warning("BdfFont::loadFont: Invalid FONT_DESCENT");
+ freeBitmaps(bitmaps, font.numCharacters);
+ delete[] bitmaps;
+ delete[] advances;
+ delete[] boxes;
return 0;
}
- continue;
- }
- if (strequal(buf, "BITMAP")) {
- bitmap_t *ch_bitmap = pf->bits + ofs;
- int ch_words;
-
- if (encoding < 0)
- continue;
-
- /* set bits offset in encode map*/
- if (pf->offset[encoding - pf->firstchar] != (unsigned long)-1) {
- warning("Error: duplicate encoding for character %d (0x%02x), ignoring duplicate",
- encoding, encoding);
- continue;
+ } else if (line.hasPrefix("DEFAULT_CHAR ")) {
+ if (sscanf(line.c_str(), "DEFAULT_CHAR %d", &font.defaultCharacter) != 1) {
+ warning("BdfFont::loadFont: Invalid DEFAULT_CHAR");
+ freeBitmaps(bitmaps, font.numCharacters);
+ delete[] bitmaps;
+ delete[] advances;
+ delete[] boxes;
+ return 0;
+ }
+ } else if (line.hasPrefix("STARTCHAR ")) {
+ BdfBoundingBox box = font.defaultBox;
+ int encoding = -1;
+ int advance = -1;
+ byte *bitmap = loadCharacter(stream, encoding, advance, box);
+
+ // Ignore all characters above 255.
+ if (encoding < -1 || encoding >= font.numCharacters) {
+ delete[] bitmap;
+ encoding = -1;
}
- pf->offset[encoding - pf->firstchar] = ofs;
- pf->width[encoding - pf->firstchar] = width;
- pf->bbx[encoding - pf->firstchar].w = bbw;
- pf->bbx[encoding - pf->firstchar].h = bbh;
- pf->bbx[encoding - pf->firstchar].x = bbx;
- pf->bbx[encoding - pf->firstchar].y = bby;
+ // Calculate the max advance
+ if (encoding != -1 && advance > font.maxAdvance)
+ font.maxAdvance = advance;
- if (width > maxwidth)
- maxwidth = width;
+ if (!bitmap && encoding != -1) {
+ warning("BdfFont::loadFont: Character %d invalid", encoding);
+ freeBitmaps(bitmaps, font.numCharacters);
+ delete[] bitmaps;
+ delete[] advances;
+ delete[] boxes;
+ return 0;
+ }
- /* clear bitmap*/
- memset(ch_bitmap, 0, BITMAP_BYTES(bbw) * bbh);
+ if (encoding != -1) {
+ bitmaps[encoding] = bitmap;
+ advances[encoding] = advance;
+ boxes[encoding] = box;
+ }
+ } else if (line == "ENDFONT") {
+ break;
+ }
+ }
- ch_words = BITMAP_WORDS(bbw);
+ if (font.ascent < 0 || descent < 0) {
+ warning("BdfFont::loadFont: Invalid ascent or descent");
+ freeBitmaps(bitmaps, font.numCharacters);
+ delete[] bitmaps;
+ delete[] advances;
+ delete[] boxes;
+ return 0;
+ }
- /* read bitmaps*/
- for (i = 0; i < bbh; ++i) {
- if (!bdf_getline(fp, buf, sizeof(buf))) {
- warning("Error: EOF reading BITMAP data");
- return 0;
- }
- if (isprefix(buf, "ENDCHAR"))
- break;
-
- for (k = 0; k < ch_words; ++k) {
- bitmap_t value;
-
- value = bdf_hexval((unsigned char *)buf);
- if (bbw > 8) {
- WRITE_UINT16(ch_bitmap, value);
- } else {
- WRITE_UINT16(ch_bitmap, value << 8);
- }
- ch_bitmap++;
- }
- }
+ font.height = font.ascent + descent;
+
+ font.bitmaps = bitmaps;
+ font.advances = advances;
+ font.boxes = boxes;
+
+ int firstCharacter = font.numCharacters;
+ int lastCharacter = -1;
+ bool hasFixedBBox = true;
+ bool hasFixedAdvance = true;
- ofs += ch_words * bbh;
+ for (int i = 0; i < font.numCharacters; ++i) {
+ if (!font.bitmaps[i])
continue;
- }
- if (strequal(buf, "ENDFONT"))
- break;
- }
- /* set max width*/
- pf->maxwidth = maxwidth;
+ if (i < firstCharacter)
+ firstCharacter = i;
- /* change unused offset/width values to default char values*/
- for (i = 0; i < pf->size; ++i) {
- int defchar = pf->defaultchar - pf->firstchar;
+ if (i > lastCharacter)
+ lastCharacter = i;
- if (pf->offset[i] == (unsigned long)-1) {
- pf->offset[i] = pf->offset[defchar];
- pf->width[i] = pf->width[defchar];
- pf->bbx[i].w = pf->bbx[defchar].w;
- pf->bbx[i].h = pf->bbx[defchar].h;
- pf->bbx[i].x = pf->bbx[defchar].x;
- pf->bbx[i].y = pf->bbx[defchar].y;
- }
- }
+ if (font.advances[i] != font.maxAdvance)
+ hasFixedAdvance = false;
- /* determine whether font doesn't require encode table*/
- l = 0;
- for (i = 0; i < pf->size; ++i) {
- if (pf->offset[i] != (unsigned long)l) {
- encodetable = 1;
- break;
- }
- l += BITMAP_WORDS(pf->bbx[i].w) * pf->bbx[i].h;
- }
- if (!encodetable) {
- free(pf->offset);
- pf->offset = NULL;
+ const BdfBoundingBox &bbox = font.boxes[i];
+ if (bbox.width != font.defaultBox.width
+ || bbox.height != font.defaultBox.height
+ || bbox.xOffset != font.defaultBox.xOffset
+ || bbox.yOffset != font.defaultBox.yOffset)
+ hasFixedBBox = false;
}
- /* determine whether font is fixed-width*/
- for (i = 0; i < pf->size; ++i) {
- if (pf->width[i] != maxwidth) {
- proportional = 1;
- break;
- }
- }
- if (!proportional) {
- free(pf->width);
- pf->width = NULL;
+ if (lastCharacter == -1) {
+ warning("BdfFont::loadFont: No glyphs found");
+ delete[] font.bitmaps;
+ delete[] font.advances;
+ delete[] font.boxes;
+ return 0;
}
- /* determine if the font needs a bbx table */
- for (i = 0; i < pf->size; ++i) {
- if (pf->bbx[i].w != pf->fbbw || pf->bbx[i].h != pf->fbbh || pf->bbx[i].x != pf->fbbx || pf->bbx[i].y != pf->fbby) {
- need_bbx = 1;
- break;
- }
- }
- if (!need_bbx) {
- free(pf->bbx);
- pf->bbx = NULL;
+ // Free the advance table, in case all glyphs use the same advance
+ if (hasFixedAdvance) {
+ delete[] font.advances;
+ font.advances = 0;
}
- /* reallocate bits array to actual bits used*/
- if (ofs < pf->bits_size) {
- bitmap_t *tmp = (bitmap_t *)realloc(pf->bits, ofs * sizeof(bitmap_t));
- if (tmp != NULL || ofs == 0)
- pf->bits = tmp;
- else
- error("bdf_read_bitmaps: Error while reallocating memory");
- pf->bits_size = ofs;
- } else {
- if (ofs > pf->bits_size) {
- warning("Warning: DWIDTH spec > max FONTBOUNDINGBOX");
- if (ofs > pf->bits_size + EXTRA) {
- warning("Error: Not enough bits initially allocated");
- return 0;
- }
- pf->bits_size = ofs;
- }
+ // Free the box table, in case all glyphs use the same box
+ if (hasFixedBBox) {
+ delete[] font.boxes;
+ font.boxes = 0;
}
- return 1;
-}
+ // Adapt for the fact that we never use encoding 0.
+ if (font.defaultCharacter < firstCharacter
+ || font.defaultCharacter > lastCharacter)
+ font.defaultCharacter = -1;
-/* read the next non-comment line, returns buf or NULL if EOF*/
-// TODO: Can we use SeekableReadStream::readLine instead?
-char *bdf_getline(Common::SeekableReadStream &fp, char *buf, int len) {
- int c;
- char *b;
-
- for (;;) {
- b = buf;
- while (!fp.eos()) {
- c = fp.readByte();
- if (c == '\r')
- continue;
- if (c == '\n')
- break;
- if (b - buf >= (len - 1))
- break;
- *b++ = c;
+ font.firstCharacter = firstCharacter;
+
+ const int charsAvailable = lastCharacter - firstCharacter + 1;
+ // Try to compact the tables
+ if (charsAvailable < font.numCharacters) {
+ byte **newBitmaps = new byte *[charsAvailable];
+ boxes = 0;
+ advances = 0;
+ if (!hasFixedBBox)
+ boxes = new BdfBoundingBox[charsAvailable];
+ if (!hasFixedAdvance)
+ advances = new byte[charsAvailable];
+
+ for (int i = 0; i < charsAvailable; ++i) {
+ const int encoding = i + firstCharacter;
+ if (font.bitmaps[encoding]) {
+ newBitmaps[i] = bitmaps[encoding];
+
+ if (!hasFixedBBox)
+ boxes[i] = font.boxes[encoding];
+ if (!hasFixedAdvance)
+ advances[i] = font.advances[encoding];
+ } else {
+ newBitmaps[i] = 0;
+ }
}
- *b = '\0';
- if (fp.eos() && b == buf)
- return NULL;
- if (b != buf && !isprefix(buf, "COMMENT"))
- break;
- }
- return buf;
-}
-/* return hex value of buffer */
-bitmap_t bdf_hexval(unsigned char *buf) {
- bitmap_t val = 0;
-
- for (unsigned char *ptr = buf; *ptr; ptr++) {
- int c = *ptr;
-
- if (c >= '0' && c <= '9')
- c -= '0';
- else if (c >= 'A' && c <= 'F')
- c = c - 'A' + 10;
- else if (c >= 'a' && c <= 'f')
- c = c - 'a' + 10;
- else
- c = 0;
- val = (val << 4) | c;
- }
- return val;
-}
+ delete[] font.bitmaps;
+ font.bitmaps = newBitmaps;
+ delete[] font.advances;
+ font.advances = advances;
+ delete[] font.boxes;
+ font.boxes = boxes;
-BdfFont *BdfFont::loadFont(Common::SeekableReadStream &stream) {
- BdfFontData *data = bdf_read_font(stream);
- if (!data || stream.err()) {
- free_font(data);
- return 0;
+ font.numCharacters = charsAvailable;
}
- BdfFontDesc desc;
- desc.name = data->name;
- desc.maxwidth = data->maxwidth;
- desc.height = data->height;
- desc.fbbw = data->fbbw;
- desc.fbbh = data->fbbh;
- desc.fbbx = data->fbbx;
- desc.fbby = data->fbby;
- desc.ascent = data->ascent;
- desc.firstchar = data->firstchar;
- desc.size = data->size;
- desc.bits = data->bits;
- desc.offset = data->offset;
- desc.width = data->width;
- desc.bbx = data->bbx;
- desc.defaultchar = data->defaultchar;
- desc.bits_size = data->bits_size;
-
- return new BdfFont(desc, data);
+ return new BdfFont(font, DisposeAfterUse::YES);
}
+#define BDF_FONTCACHE_TAG MKTAG('S', 'V', 'F', 'C')
+#define BDF_FONTCACHE_VERSION 1
+
bool BdfFont::cacheFontData(const BdfFont &font, const Common::String &filename) {
Common::DumpFile cacheFile;
if (!cacheFile.open(filename)) {
- warning("Couldn't open file '%s' for writing", filename.c_str());
+ warning("BdfFont::cacheFontData: Couldn't open file '%s' for writing", filename.c_str());
return false;
}
- cacheFile.writeUint16BE(font._desc.maxwidth);
- cacheFile.writeUint16BE(font._desc.height);
- cacheFile.writeUint16BE(font._desc.fbbw);
- cacheFile.writeUint16BE(font._desc.fbbh);
- cacheFile.writeSint16BE(font._desc.fbbx);
- cacheFile.writeSint16BE(font._desc.fbby);
- cacheFile.writeUint16BE(font._desc.ascent);
- cacheFile.writeUint16BE(font._desc.firstchar);
- cacheFile.writeUint16BE(font._desc.size);
- cacheFile.writeUint16BE(font._desc.defaultchar);
- cacheFile.writeUint32BE(font._desc.bits_size);
-
- for (long i = 0; i < font._desc.bits_size; ++i) {
- cacheFile.writeUint16BE(font._desc.bits[i]);
- }
-
- if (font._desc.offset) {
- cacheFile.writeByte(1);
- for (int i = 0; i < font._desc.size; ++i) {
- cacheFile.writeUint32BE(font._desc.offset[i]);
+ const BdfFontData &data = font._data;
+
+ cacheFile.writeUint32BE(BDF_FONTCACHE_TAG);
+ cacheFile.writeUint32BE(BDF_FONTCACHE_VERSION);
+ cacheFile.writeUint16BE(data.maxAdvance);
+ cacheFile.writeByte(data.height);
+ cacheFile.writeByte(data.defaultBox.width);
+ cacheFile.writeByte(data.defaultBox.height);
+ cacheFile.writeSByte(data.defaultBox.xOffset);
+ cacheFile.writeSByte(data.defaultBox.yOffset);
+ cacheFile.writeByte(data.ascent);
+ cacheFile.writeUint16BE(data.firstCharacter);
+ cacheFile.writeSint16BE(data.defaultCharacter);
+ cacheFile.writeUint16BE(data.numCharacters);
+
+ for (int i = 0; i < data.numCharacters; ++i) {
+ const BdfBoundingBox &box = data.boxes ? data.boxes[i] : data.defaultBox;
+ if (data.bitmaps[i]) {
+ const int bytes = ((box.width + 7) / 8) * box.height;
+ cacheFile.writeUint32BE(bytes);
+ cacheFile.write(data.bitmaps[i], bytes);
+ } else {
+ cacheFile.writeUint32BE(0);
}
- } else {
- cacheFile.writeByte(0);
}
- if (font._desc.width) {
- cacheFile.writeByte(1);
- for (int i = 0; i < font._desc.size; ++i) {
- cacheFile.writeByte(font._desc.width[i]);
- }
+ if (data.advances) {
+ cacheFile.writeByte(0xFF);
+ cacheFile.write(data.advances, data.numCharacters);
} else {
- cacheFile.writeByte(0);
+ cacheFile.writeByte(0x00);
}
- if (font._desc.bbx) {
- cacheFile.writeByte(1);
- for (int i = 0; i < font._desc.size; ++i) {
- cacheFile.writeByte(font._desc.bbx[i].w);
- cacheFile.writeByte(font._desc.bbx[i].h);
- cacheFile.writeByte(font._desc.bbx[i].x);
- cacheFile.writeByte(font._desc.bbx[i].y);
+ if (data.boxes) {
+ cacheFile.writeByte(0xFF);
+
+ for (int i = 0; i < data.numCharacters; ++i) {
+ const BdfBoundingBox &box = data.boxes[i];
+ cacheFile.writeByte(box.width);
+ cacheFile.writeByte(box.height);
+ cacheFile.writeSByte(box.xOffset);
+ cacheFile.writeSByte(box.yOffset);
}
} else {
- cacheFile.writeByte(0);
+ cacheFile.writeByte(0x00);
}
return !cacheFile.err();
}
BdfFont *BdfFont::loadFromCache(Common::SeekableReadStream &stream) {
- BdfFont *font = 0;
-
- BdfFontData *data = (BdfFontData *)malloc(sizeof(BdfFontData));
- if (!data)
+ const uint32 magic = stream.readUint32BE();
+ if (magic != BDF_FONTCACHE_TAG)
return 0;
- memset(data, 0, sizeof(BdfFontData));
-
- data->maxwidth = stream.readUint16BE();
- data->height = stream.readUint16BE();
- data->fbbw = stream.readUint16BE();
- data->fbbh = stream.readUint16BE();
- data->fbbx = stream.readSint16BE();
- data->fbby = stream.readSint16BE();
- data->ascent = stream.readUint16BE();
- data->firstchar = stream.readUint16BE();
- data->size = stream.readUint16BE();
- data->defaultchar = stream.readUint16BE();
- data->bits_size = stream.readUint32BE();
-
- data->bits = (bitmap_t *)malloc(sizeof(bitmap_t) * data->bits_size);
- if (!data->bits) {
- free(data);
+ const uint32 version = stream.readUint32BE();
+ if (version != BDF_FONTCACHE_VERSION)
return 0;
- }
- for (long i = 0; i < data->bits_size; ++i) {
- data->bits[i] = stream.readUint16BE();
- }
+ BdfFontData data;
- bool hasOffsetTable = (stream.readByte() != 0);
- if (hasOffsetTable) {
- data->offset = (unsigned long *)malloc(sizeof(unsigned long) * data->size);
- if (!data->offset) {
- free(data->bits);
- free(data);
- return 0;
- }
+ data.maxAdvance = stream.readUint16BE();
+ data.height = stream.readByte();
+ data.defaultBox.width = stream.readByte();
+ data.defaultBox.height = stream.readByte();
+ data.defaultBox.xOffset = stream.readSByte();
+ data.defaultBox.yOffset = stream.readSByte();
+ data.ascent = stream.readByte();
+ data.firstCharacter = stream.readUint16BE();
+ data.defaultCharacter = stream.readSint16BE();
+ data.numCharacters = stream.readUint16BE();
- for (int i = 0; i < data->size; ++i) {
- data->offset[i] = stream.readUint32BE();
- }
- }
+ if (stream.err() || stream.eos())
+ return 0;
- bool hasWidthTable = (stream.readByte() != 0);
- if (hasWidthTable) {
- data->width = (unsigned char *)malloc(sizeof(unsigned char) * data->size);
- if (!data->width) {
- free(data->bits);
- free(data->offset);
- free(data);
+ byte **bitmaps = new byte *[data.numCharacters];
+ byte *advances = 0;
+ BdfBoundingBox *boxes = 0;
+ for (int i = 0; i < data.numCharacters; ++i) {
+ uint32 size = stream.readUint32BE();
+
+ if (stream.err() || stream.eos()) {
+ for (int j = 0; j < i; ++j)
+ delete[] bitmaps[i];
+ delete[] bitmaps;
return 0;
}
- for (int i = 0; i < data->size; ++i) {
- data->width[i] = stream.readByte();
+ if (size) {
+ bitmaps[i] = new byte[size];
+ stream.read(bitmaps[i], size);
+ } else {
+ bitmaps[i] = 0;
}
}
- bool hasBBXTable = (stream.readByte() != 0);
- if (hasBBXTable) {
- data->bbx = (BBX *)malloc(sizeof(BBX) * data->size);
- if (!data->bbx) {
- free(data->bits);
- free(data->offset);
- free(data->width);
- free(data);
- return 0;
- }
- for (int i = 0; i < data->size; ++i) {
- data->bbx[i].w = (int8)stream.readByte();
- data->bbx[i].h = (int8)stream.readByte();
- data->bbx[i].x = (int8)stream.readByte();
- data->bbx[i].y = (int8)stream.readByte();
- }
+ if (stream.readByte() == 0xFF) {
+ advances = new byte[data.numCharacters];
+ stream.read(advances, data.numCharacters);
}
- if (stream.err() || stream.eos()) {
- free(data->bits);
- free(data->offset);
- free(data->width);
- free(data);
- return 0;
+ if (stream.readByte() == 0xFF) {
+ boxes = new BdfBoundingBox[data.numCharacters];
+ for (int i = 0; i < data.numCharacters; ++i) {
+ boxes[i].width = stream.readByte();
+ boxes[i].height = stream.readByte();
+ boxes[i].xOffset = stream.readSByte();
+ boxes[i].yOffset = stream.readSByte();
+ }
}
- BdfFontDesc desc;
- desc.name = data->name;
- desc.maxwidth = data->maxwidth;
- desc.height = data->height;
- desc.fbbw = data->fbbw;
- desc.fbbh = data->fbbh;
- desc.fbbx = data->fbbx;
- desc.fbby = data->fbby;
- desc.ascent = data->ascent;
- desc.firstchar = data->firstchar;
- desc.size = data->size;
- desc.bits = data->bits;
- desc.offset = data->offset;
- desc.width = data->width;
- desc.bbx = data->bbx;
- desc.defaultchar = data->defaultchar;
- desc.bits_size = data->bits_size;
-
- font = new BdfFont(desc, data);
- if (!font) {
- free(data->bits);
- free(data->offset);
- free(data->width);
- free(data);
+ if (stream.eos() || stream.err()) {
+ for (int i = 0; i < data.numCharacters; ++i)
+ delete[] bitmaps[i];
+ delete[] bitmaps;
+ delete[] advances;
+ delete[] boxes;
return 0;
}
- return font;
+ data.bitmaps = bitmaps;
+ data.advances = advances;
+ data.boxes = boxes;
+ return new BdfFont(data, DisposeAfterUse::YES);
}
} // End of namespace Graphics
diff --git a/graphics/fonts/bdf.h b/graphics/fonts/bdf.h
index 0d60693736..5b615cc043 100644
--- a/graphics/fonts/bdf.h
+++ b/graphics/fonts/bdf.h
@@ -23,6 +23,7 @@
#define GRAPHICS_FONTS_BDF_H
#include "common/system.h"
+#include "common/types.h"
#include "graphics/font.h"
@@ -32,42 +33,29 @@ class SeekableReadStream;
namespace Graphics {
-typedef uint16 bitmap_t; /* bitmap image unit size*/
-
-struct BBX {
- int8 w;
- int8 h;
- int8 x;
- int8 y;
+struct BdfBoundingBox {
+ uint8 width, height;
+ int8 xOffset, yOffset;
};
-/* builtin C-based proportional/fixed font structure */
-/* based on The Microwindows Project http://microwindows.org */
-struct BdfFontDesc {
- const char *name; /* font name */
- int maxwidth; /* max width in pixels */
- int height; /* height in pixels */
- int fbbw, fbbh, fbbx, fbby; /* max bounding box */
- int ascent; /* ascent (baseline) height */
- int firstchar; /* first character in bitmap */
- int size; /* font size in glyphs */
- const bitmap_t *bits; /* 16-bit right-padded bitmap data */
- const unsigned long *offset; /* offsets into bitmap data */
- const unsigned char *width; /* character widths or NULL if fixed */
- const BBX *bbx; /* character bounding box or NULL if fixed */
- int defaultchar; /* default char (not glyph index) */
- long bits_size; /* # words of bitmap_t bits */
-};
+struct BdfFontData {
+ int maxAdvance;
+ int height;
+ BdfBoundingBox defaultBox;
+ int ascent;
-struct BdfFontData;
+ int firstCharacter;
+ int defaultCharacter;
+ int numCharacters;
-class BdfFont : public Font {
-protected:
- BdfFontDesc _desc;
- BdfFontData *_font;
+ const byte *const *bitmaps;
+ const byte *advances;
+ const BdfBoundingBox *boxes;
+};
+class BdfFont : public Font {
public:
- BdfFont(const BdfFontDesc &desc, BdfFontData *font = 0) : _desc(desc), _font(font) {}
+ BdfFont(const BdfFontData &data, DisposeAfterUse::Flag dispose);
~BdfFont();
virtual int getFontHeight() const;
@@ -79,12 +67,17 @@ public:
static BdfFont *loadFont(Common::SeekableReadStream &stream);
static bool cacheFontData(const BdfFont &font, const Common::String &filename);
static BdfFont *loadFromCache(Common::SeekableReadStream &stream);
+private:
+ int mapToIndex(byte ch) const;
+
+ const BdfFontData _data;
+ const DisposeAfterUse::Flag _dispose;
};
#define DEFINE_FONT(n) \
const BdfFont *n = 0; \
void create_##n() { \
- n = new BdfFont(desc); \
+ n = new BdfFont(desc, DisposeAfterUse::YES); \
}
#define FORWARD_DECLARE_FONT(n) \
diff --git a/graphics/fonts/consolefont.cpp b/graphics/fonts/consolefont.cpp
index 5b4768327a..8244d75fc2 100644
--- a/graphics/fonts/consolefont.cpp
+++ b/graphics/fonts/consolefont.cpp
@@ -1,5654 +1,5867 @@
-/* Generated by convbdf on Sat Jun 17 01:37:46 2006. */
+// Generated by convbdf on Fri Jan 6 14:32:21 2012
#include "graphics/fonts/bdf.h"
-/* Font information:
- name: 5x8-L1
- facename: -Misc-Fixed-Medium-R-Normal--8-80-75-75-C-50-ISO8859-1
- w x h: 5x8
- bbx: 5 8 0 -1
- size: 256
- ascent: 7
- descent: 1
- first char: 0 (0x00)
- last char: 255 (0xff)
- default char: 0 (0x00)
- proportional: no
- Public domain font. Share and enjoy.
-*/
+// Font information:
+// Name: -Misc-Fixed-Medium-R-Normal--8-80-75-75-C-50-ISO8859-1
+// Size: 5x8
+// Box: 5 8 0 -1
+// Ascent: 7
+// First character: 0
+// Default character: 0
+// Characters: 256
+// Copyright: "Public domain font. Share and enjoy."
namespace Graphics {
-/* Font character bitmap data. */
-static const bitmap_t _font_bits[] = {
-
-/* Character 0 (0x00):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | |
- |* * |
- | * |
- |* |
- | * |
- |* |
- | * * |
- | |
- +-----+
-*/
-0x0000,
-0xa000,
-0x1000,
-0x8000,
-0x1000,
-0x8000,
-0x5000,
-0x0000,
-
-/* Character 1 (0x01):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | |
- | |
- | * |
- | *** |
- |*****|
- | *** |
- | * |
- | |
- +-----+
-*/
-0x0000,
-0x0000,
-0x2000,
-0x7000,
-0xf800,
-0x7000,
-0x2000,
-0x0000,
-
-/* Character 2 (0x02):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | * * |
- |* * *|
- | * * |
- |* * *|
- | * * |
- |* * *|
- | * * |
- |* * *|
- +-----+
-*/
-0x5000,
-0xa800,
-0x5000,
-0xa800,
-0x5000,
-0xa800,
-0x5000,
-0xa800,
-
-/* Character 3 (0x03):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- |* * |
- |* * |
- |*** |
- |* * |
- |* * |
- | *** |
- | * |
- | * |
- +-----+
-*/
-0xa000,
-0xa000,
-0xe000,
-0xa000,
-0xa000,
-0x7000,
-0x2000,
-0x2000,
-
-/* Character 4 (0x04):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- |*** |
- |* |
- |** |
- |* ***|
- |* * |
- | ** |
- | * |
- | * |
- +-----+
-*/
-0xe000,
-0x8000,
-0xc000,
-0xb800,
-0xa000,
-0x3000,
-0x2000,
-0x2000,
-
-/* Character 5 (0x05):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | ** |
- |* |
- |* |
- | ** |
- | ** |
- | * *|
- | ** |
- | * *|
- +-----+
-*/
-0x6000,
-0x8000,
-0x8000,
-0x6000,
-0x3000,
-0x2800,
-0x3000,
-0x2800,
-
-/* Character 6 (0x06):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- |* |
- |* |
- |* |
- |*** |
- | ***|
- | * |
- | ** |
- | * |
- +-----+
-*/
-0x8000,
-0x8000,
-0x8000,
-0xe000,
-0x3800,
-0x2000,
-0x3000,
-0x2000,
-
-/* Character 7 (0x07):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | |
- | * |
- | * * |
- | * |
- | |
- | |
- | |
- | |
- +-----+
-*/
-0x0000,
-0x2000,
-0x5000,
-0x2000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 8 (0x08):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | |
- | |
- | * |
- | *** |
- | * |
- | |
- | *** |
- | |
- +-----+
-*/
-0x0000,
-0x0000,
-0x2000,
-0x7000,
-0x2000,
-0x0000,
-0x7000,
-0x0000,
-
-/* Character 9 (0x09):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- |* * |
- |** * |
- |* ** |
- |* * |
- | * |
- | * |
- | * |
- | ***|
- +-----+
-*/
-0x9000,
-0xd000,
-0xb000,
-0x9000,
-0x2000,
-0x2000,
-0x2000,
-0x3800,
-
-/* Character 10 (0x0a):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- |* * |
- |* * |
- |* * |
- | * |
- | ***|
- | * |
- | * |
- | * |
- +-----+
-*/
-0xa000,
-0xa000,
-0xa000,
-0x4000,
-0x3800,
-0x1000,
-0x1000,
-0x1000,
-
-/* Character 11 (0x0b):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | * |
- | * |
- | * |
- |*** |
- | |
- | |
- | |
- | |
- +-----+
-*/
-0x2000,
-0x2000,
-0x2000,
-0xe000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 12 (0x0c):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | |
- | |
- | |
- |*** |
- | * |
- | * |
- | * |
- | * |
- +-----+
-*/
-0x0000,
-0x0000,
-0x0000,
-0xe000,
-0x2000,
-0x2000,
-0x2000,
-0x2000,
-
-/* Character 13 (0x0d):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | |
- | |
- | |
- | ***|
- | * |
- | * |
- | * |
- | * |
- +-----+
-*/
-0x0000,
-0x0000,
-0x0000,
-0x3800,
-0x2000,
-0x2000,
-0x2000,
-0x2000,
-
-/* Character 14 (0x0e):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | * |
- | * |
- | * |
- | ***|
- | |
- | |
- | |
- | |
- +-----+
-*/
-0x2000,
-0x2000,
-0x2000,
-0x3800,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 15 (0x0f):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | * |
- | * |
- | * |
- |*****|
- | * |
- | * |
- | * |
- | * |
- +-----+
-*/
-0x2000,
-0x2000,
-0x2000,
-0xf800,
-0x2000,
-0x2000,
-0x2000,
-0x2000,
-
-/* Character 16 (0x10):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- |*****|
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- +-----+
-*/
-0xf800,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 17 (0x11):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | |
- |*****|
- | |
- | |
- | |
- | |
- | |
- | |
- +-----+
-*/
-0x0000,
-0xf800,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 18 (0x12):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | |
- | |
- | |
- |*****|
- | |
- | |
- | |
- | |
- +-----+
-*/
-0x0000,
-0x0000,
-0x0000,
-0xf800,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 19 (0x13):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | |
- | |
- | |
- | |
- | |
- | |
- |*****|
- | |
- +-----+
-*/
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0xf800,
-0x0000,
-
-/* Character 20 (0x14):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- |*****|
- +-----+
-*/
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0xf800,
-
-/* Character 21 (0x15):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | * |
- | * |
- | * |
- | ***|
- | * |
- | * |
- | * |
- | * |
- +-----+
-*/
-0x2000,
-0x2000,
-0x2000,
-0x3800,
-0x2000,
-0x2000,
-0x2000,
-0x2000,
-
-/* Character 22 (0x16):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | * |
- | * |
- | * |
- |*** |
- | * |
- | * |
- | * |
- | * |
- +-----+
-*/
-0x2000,
-0x2000,
-0x2000,
-0xe000,
-0x2000,
-0x2000,
-0x2000,
-0x2000,
-
-/* Character 23 (0x17):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | * |
- | * |
- | * |
- |*****|
- | |
- | |
- | |
- | |
- +-----+
-*/
-0x2000,
-0x2000,
-0x2000,
-0xf800,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 24 (0x18):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | |
- | |
- | |
- |*****|
- | * |
- | * |
- | * |
- | * |
- +-----+
-*/
-0x0000,
-0x0000,
-0x0000,
-0xf800,
-0x2000,
-0x2000,
-0x2000,
-0x2000,
-
-/* Character 25 (0x19):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | * |
- | * |
- | * |
- | * |
- | * |
- | * |
- | * |
- | * |
- +-----+
-*/
-0x2000,
-0x2000,
-0x2000,
-0x2000,
-0x2000,
-0x2000,
-0x2000,
-0x2000,
-
-/* Character 26 (0x1a):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | |
- | * |
- | * |
- | * |
- | * |
- | * |
- | *** |
- | |
- +-----+
-*/
-0x0000,
-0x1000,
-0x2000,
-0x4000,
-0x2000,
-0x1000,
-0x7000,
-0x0000,
-
-/* Character 27 (0x1b):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | |
- | * |
- | * |
- | * |
- | * |
- | * |
- | *** |
- | |
- +-----+
-*/
-0x0000,
-0x4000,
-0x2000,
-0x1000,
-0x2000,
-0x4000,
-0x7000,
-0x0000,
-
-/* Character 28 (0x1c):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | |
- | |
- | |
- |*****|
- | * * |
- | * * |
- | * * |
- | |
- +-----+
-*/
-0x0000,
-0x0000,
-0x0000,
-0xf800,
-0x5000,
-0x5000,
-0x5000,
-0x0000,
-
-/* Character 29 (0x1d):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | |
- | |
- | * |
- |**** |
- | ** |
- |**** |
- | * |
- | |
- +-----+
-*/
-0x0000,
-0x0000,
-0x2000,
-0xf000,
-0x6000,
-0xf000,
-0x4000,
-0x0000,
-
-/* Character 30 (0x1e):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | |
- | * |
- | * * |
- |*** |
- | * |
- | * * |
- |* * |
- | |
- +-----+
-*/
-0x0000,
-0x2000,
-0x5000,
-0xe000,
-0x4000,
-0x5000,
-0xa000,
-0x0000,
-
-/* Character 31 (0x1f):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | |
- | |
- | |
- | |
- | * |
- | |
- | |
- | |
- +-----+
-*/
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x2000,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 32 (0x20):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- +-----+
-*/
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 33 (0x21):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | |
- | * |
- | * |
- | * |
- | * |
- | |
- | * |
- | |
- +-----+
-*/
-0x0000,
-0x2000,
-0x2000,
-0x2000,
-0x2000,
-0x0000,
-0x2000,
-0x0000,
-
-/* Character 34 (0x22):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | |
- | * * |
- | * * |
- | * * |
- | |
- | |
- | |
- | |
- +-----+
-*/
-0x0000,
-0x5000,
-0x5000,
-0x5000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 35 (0x23):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | * * |
- | * * |
- |*****|
- | * * |
- |*****|
- | * * |
- | * * |
- | |
- +-----+
-*/
-0x5000,
-0x5000,
-0xf800,
-0x5000,
-0xf800,
-0x5000,
-0x5000,
-0x0000,
-
-/* Character 36 (0x24):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | * |
- | *** |
- |* * |
- | *** |
- | * *|
- | *** |
- | * |
- | |
- +-----+
-*/
-0x2000,
-0x7000,
-0xa000,
-0x7000,
-0x2800,
-0x7000,
-0x2000,
-0x0000,
-
-/* Character 37 (0x25):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | |
- | * |
- | * * |
- | * |
- | * * |
- | * |
- | |
- | |
- +-----+
-*/
-0x0000,
-0x4000,
-0x5000,
-0x2000,
-0x5000,
-0x1000,
-0x0000,
-0x0000,
-
-/* Character 38 (0x26):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | * |
- |* * |
- |* * |
- | * |
- |* * |
- |* * |
- | * * |
- | |
- +-----+
-*/
-0x4000,
-0xa000,
-0xa000,
-0x4000,
-0xa000,
-0xa000,
-0x5000,
-0x0000,
-
-/* Character 39 (0x27):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | |
- | * |
- | * |
- | * |
- | |
- | |
- | |
- | |
- +-----+
-*/
-0x0000,
-0x2000,
-0x2000,
-0x2000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 40 (0x28):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | |
- | * |
- | * |
- | * |
- | * |
- | * |
- | * |
- | |
- +-----+
-*/
-0x0000,
-0x2000,
-0x4000,
-0x4000,
-0x4000,
-0x4000,
-0x2000,
-0x0000,
-
-/* Character 41 (0x29):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | |
- | * |
- | * |
- | * |
- | * |
- | * |
- | * |
- | |
- +-----+
-*/
-0x0000,
-0x4000,
-0x2000,
-0x2000,
-0x2000,
-0x2000,
-0x4000,
-0x0000,
-
-/* Character 42 (0x2a):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | |
- | |
- |* * |
- | ** |
- |**** |
- | ** |
- |* * |
- | |
- +-----+
-*/
-0x0000,
-0x0000,
-0x9000,
-0x6000,
-0xf000,
-0x6000,
-0x9000,
-0x0000,
-
-/* Character 43 (0x2b):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | |
- | |
- | * |
- | * |
- |*****|
- | * |
- | * |
- | |
- +-----+
-*/
-0x0000,
-0x0000,
-0x2000,
-0x2000,
-0xf800,
-0x2000,
-0x2000,
-0x0000,
-
-/* Character 44 (0x2c):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | |
- | |
- | |
- | |
- | |
- | ** |
- | * |
- | * |
- +-----+
-*/
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x3000,
-0x2000,
-0x4000,
-
-/* Character 45 (0x2d):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | |
- | |
- | |
- | |
- |**** |
- | |
- | |
- | |
- +-----+
-*/
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0xf000,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 46 (0x2e):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | |
- | |
- | |
- | |
- | |
- | * |
- | *** |
- | * |
- +-----+
-*/
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x2000,
-0x7000,
-0x2000,
-
-/* Character 47 (0x2f):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | |
- | * |
- | * |
- | * |
- | * |
- |* |
- |* |
- | |
- +-----+
-*/
-0x0000,
-0x1000,
-0x1000,
-0x2000,
-0x4000,
-0x8000,
-0x8000,
-0x0000,
-
-/* Character 48 (0x30):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | |
- | * |
- | * * |
- | * * |
- | * * |
- | * * |
- | * |
- | |
- +-----+
-*/
-0x0000,
-0x2000,
-0x5000,
-0x5000,
-0x5000,
-0x5000,
-0x2000,
-0x0000,
-
-/* Character 49 (0x31):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | |
- | * |
- | ** |
- | * |
- | * |
- | * |
- | *** |
- | |
- +-----+
-*/
-0x0000,
-0x2000,
-0x6000,
-0x2000,
-0x2000,
-0x2000,
-0x7000,
-0x0000,
-
-/* Character 50 (0x32):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | |
- | ** |
- |* * |
- | * |
- | ** |
- |* |
- |**** |
- | |
- +-----+
-*/
-0x0000,
-0x6000,
-0x9000,
-0x1000,
-0x6000,
-0x8000,
-0xf000,
-0x0000,
-
-/* Character 51 (0x33):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | |
- |**** |
- | * |
- | ** |
- | * |
- |* * |
- | ** |
- | |
- +-----+
-*/
-0x0000,
-0xf000,
-0x2000,
-0x6000,
-0x1000,
-0x9000,
-0x6000,
-0x0000,
-
-/* Character 52 (0x34):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | |
- | * |
- | ** |
- |* * |
- |**** |
- | * |
- | * |
- | |
- +-----+
-*/
-0x0000,
-0x2000,
-0x6000,
-0xa000,
-0xf000,
-0x2000,
-0x2000,
-0x0000,
-
-/* Character 53 (0x35):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | |
- |**** |
- |* |
- |*** |
- | * |
- |* * |
- | ** |
- | |
- +-----+
-*/
-0x0000,
-0xf000,
-0x8000,
-0xe000,
-0x1000,
-0x9000,
-0x6000,
-0x0000,
-
-/* Character 54 (0x36):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | |
- | ** |
- |* |
- |*** |
- |* * |
- |* * |
- | ** |
- | |
- +-----+
-*/
-0x0000,
-0x6000,
-0x8000,
-0xe000,
-0x9000,
-0x9000,
-0x6000,
-0x0000,
-
-/* Character 55 (0x37):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | |
- |**** |
- | * |
- | * |
- | * |
- | * |
- | * |
- | |
- +-----+
-*/
-0x0000,
-0xf000,
-0x1000,
-0x2000,
-0x2000,
-0x4000,
-0x4000,
-0x0000,
-
-/* Character 56 (0x38):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | |
- | ** |
- |* * |
- | ** |
- |* * |
- |* * |
- | ** |
- | |
- +-----+
-*/
-0x0000,
-0x6000,
-0x9000,
-0x6000,
-0x9000,
-0x9000,
-0x6000,
-0x0000,
-
-/* Character 57 (0x39):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | |
- | ** |
- |* * |
- |* * |
- | *** |
- | * |
- | ** |
- | |
- +-----+
-*/
-0x0000,
-0x6000,
-0x9000,
-0x9000,
-0x7000,
-0x1000,
-0x6000,
-0x0000,
-
-/* Character 58 (0x3a):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | |
- | |
- | ** |
- | ** |
- | |
- | ** |
- | ** |
- | |
- +-----+
-*/
-0x0000,
-0x0000,
-0x6000,
-0x6000,
-0x0000,
-0x6000,
-0x6000,
-0x0000,
-
-/* Character 59 (0x3b):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | |
- | |
- | ** |
- | ** |
- | |
- | ** |
- | * |
- | * |
- +-----+
-*/
-0x0000,
-0x0000,
-0x3000,
-0x3000,
-0x0000,
-0x3000,
-0x2000,
-0x4000,
-
-/* Character 60 (0x3c):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | |
- | * |
- | * |
- | * |
- | * |
- | * |
- | * |
- | |
- +-----+
-*/
-0x0000,
-0x1000,
-0x2000,
-0x4000,
-0x4000,
-0x2000,
-0x1000,
-0x0000,
-
-/* Character 61 (0x3d):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | |
- | |
- | |
- |**** |
- | |
- |**** |
- | |
- | |
- +-----+
-*/
-0x0000,
-0x0000,
-0x0000,
-0xf000,
-0x0000,
-0xf000,
-0x0000,
-0x0000,
-
-/* Character 62 (0x3e):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | |
- | * |
- | * |
- | * |
- | * |
- | * |
- | * |
- | |
- +-----+
-*/
-0x0000,
-0x4000,
-0x2000,
-0x1000,
-0x1000,
-0x2000,
-0x4000,
-0x0000,
-
-/* Character 63 (0x3f):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | |
- | * |
- | * * |
- | * |
- | * |
- | |
- | * |
- | |
- +-----+
-*/
-0x0000,
-0x2000,
-0x5000,
-0x1000,
-0x2000,
-0x0000,
-0x2000,
-0x0000,
-
-/* Character 64 (0x40):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | ** |
- | * *|
- |* **|
- |* * *|
- |* * *|
- |* * |
- | * |
- | ** |
- +-----+
-*/
-0x3000,
-0x4800,
-0x9800,
-0xa800,
-0xa800,
-0x9000,
-0x4000,
-0x3000,
-
-/* Character 65 (0x41):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | |
- | ** |
- |* * |
- |* * |
- |**** |
- |* * |
- |* * |
- | |
- +-----+
-*/
-0x0000,
-0x6000,
-0x9000,
-0x9000,
-0xf000,
-0x9000,
-0x9000,
-0x0000,
-
-/* Character 66 (0x42):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | |
- |*** |
- |* * |
- |*** |
- |* * |
- |* * |
- |*** |
- | |
- +-----+
-*/
-0x0000,
-0xe000,
-0x9000,
-0xe000,
-0x9000,
-0x9000,
-0xe000,
-0x0000,
-
-/* Character 67 (0x43):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | |
- | ** |
- |* * |
- |* |
- |* |
- |* * |
- | ** |
- | |
- +-----+
-*/
-0x0000,
-0x6000,
-0x9000,
-0x8000,
-0x8000,
-0x9000,
-0x6000,
-0x0000,
-
-/* Character 68 (0x44):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | |
- |*** |
- |* * |
- |* * |
- |* * |
- |* * |
- |*** |
- | |
- +-----+
-*/
-0x0000,
-0xe000,
-0x9000,
-0x9000,
-0x9000,
-0x9000,
-0xe000,
-0x0000,
-
-/* Character 69 (0x45):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | |
- |**** |
- |* |
- |*** |
- |* |
- |* |
- |**** |
- | |
- +-----+
-*/
-0x0000,
-0xf000,
-0x8000,
-0xe000,
-0x8000,
-0x8000,
-0xf000,
-0x0000,
-
-/* Character 70 (0x46):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | |
- |**** |
- |* |
- |*** |
- |* |
- |* |
- |* |
- | |
- +-----+
-*/
-0x0000,
-0xf000,
-0x8000,
-0xe000,
-0x8000,
-0x8000,
-0x8000,
-0x0000,
-
-/* Character 71 (0x47):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | |
- | ** |
- |* * |
- |* |
- |* ** |
- |* * |
- | ** |
- | |
- +-----+
-*/
-0x0000,
-0x6000,
-0x9000,
-0x8000,
-0xb000,
-0x9000,
-0x6000,
-0x0000,
-
-/* Character 72 (0x48):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | |
- |* * |
- |* * |
- |**** |
- |* * |
- |* * |
- |* * |
- | |
- +-----+
-*/
-0x0000,
-0x9000,
-0x9000,
-0xf000,
-0x9000,
-0x9000,
-0x9000,
-0x0000,
-
-/* Character 73 (0x49):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | |
- | *** |
- | * |
- | * |
- | * |
- | * |
- | *** |
- | |
- +-----+
-*/
-0x0000,
-0x7000,
-0x2000,
-0x2000,
-0x2000,
-0x2000,
-0x7000,
-0x0000,
-
-/* Character 74 (0x4a):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | |
- | *** |
- | * |
- | * |
- | * |
- |* * |
- | * |
- | |
- +-----+
-*/
-0x0000,
-0x7000,
-0x2000,
-0x2000,
-0x2000,
-0xa000,
-0x4000,
-0x0000,
-
-/* Character 75 (0x4b):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | |
- |* * |
- |* * |
- |** |
- |* * |
- |* * |
- |* * |
- | |
- +-----+
-*/
-0x0000,
-0x9000,
-0xa000,
-0xc000,
-0xa000,
-0xa000,
-0x9000,
-0x0000,
-
-/* Character 76 (0x4c):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | |
- |* |
- |* |
- |* |
- |* |
- |* |
- |**** |
- | |
- +-----+
-*/
-0x0000,
-0x8000,
-0x8000,
-0x8000,
-0x8000,
-0x8000,
-0xf000,
-0x0000,
-
-/* Character 77 (0x4d):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | |
- |* * |
- |**** |
- |**** |
- |* * |
- |* * |
- |* * |
- | |
- +-----+
-*/
-0x0000,
-0x9000,
-0xf000,
-0xf000,
-0x9000,
-0x9000,
-0x9000,
-0x0000,
-
-/* Character 78 (0x4e):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | |
- |* * |
- |** * |
- |**** |
- |* ** |
- |* ** |
- |* * |
- | |
- +-----+
-*/
-0x0000,
-0x9000,
-0xd000,
-0xf000,
-0xb000,
-0xb000,
-0x9000,
-0x0000,
-
-/* Character 79 (0x4f):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | |
- | ** |
- |* * |
- |* * |
- |* * |
- |* * |
- | ** |
- | |
- +-----+
-*/
-0x0000,
-0x6000,
-0x9000,
-0x9000,
-0x9000,
-0x9000,
-0x6000,
-0x0000,
-
-/* Character 80 (0x50):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | |
- |*** |
- |* * |
- |* * |
- |*** |
- |* |
- |* |
- | |
- +-----+
-*/
-0x0000,
-0xe000,
-0x9000,
-0x9000,
-0xe000,
-0x8000,
-0x8000,
-0x0000,
-
-/* Character 81 (0x51):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | |
- | ** |
- |* * |
- |* * |
- |** * |
- |* ** |
- | ** |
- | * |
- +-----+
-*/
-0x0000,
-0x6000,
-0x9000,
-0x9000,
-0xd000,
-0xb000,
-0x6000,
-0x1000,
-
-/* Character 82 (0x52):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | |
- |*** |
- |* * |
- |* * |
- |*** |
- |* * |
- |* * |
- | |
- +-----+
-*/
-0x0000,
-0xe000,
-0x9000,
-0x9000,
-0xe000,
-0x9000,
-0x9000,
-0x0000,
-
-/* Character 83 (0x53):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | |
- | ** |
- |* * |
- | * |
- | * |
- |* * |
- | ** |
- | |
- +-----+
-*/
-0x0000,
-0x6000,
-0x9000,
-0x4000,
-0x2000,
-0x9000,
-0x6000,
-0x0000,
-
-/* Character 84 (0x54):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | |
- | *** |
- | * |
- | * |
- | * |
- | * |
- | * |
- | |
- +-----+
-*/
-0x0000,
-0x7000,
-0x2000,
-0x2000,
-0x2000,
-0x2000,
-0x2000,
-0x0000,
-
-/* Character 85 (0x55):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | |
- |* * |
- |* * |
- |* * |
- |* * |
- |* * |
- | ** |
- | |
- +-----+
-*/
-0x0000,
-0x9000,
-0x9000,
-0x9000,
-0x9000,
-0x9000,
-0x6000,
-0x0000,
-
-/* Character 86 (0x56):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | |
- |* * |
- |* * |
- |* * |
- |* * |
- | ** |
- | ** |
- | |
- +-----+
-*/
-0x0000,
-0x9000,
-0x9000,
-0x9000,
-0x9000,
-0x6000,
-0x6000,
-0x0000,
-
-/* Character 87 (0x57):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | |
- |* * |
- |* * |
- |* * |
- |**** |
- |**** |
- |* * |
- | |
- +-----+
-*/
-0x0000,
-0x9000,
-0x9000,
-0x9000,
-0xf000,
-0xf000,
-0x9000,
-0x0000,
-
-/* Character 88 (0x58):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | |
- |* * |
- |* * |
- | ** |
- | ** |
- |* * |
- |* * |
- | |
- +-----+
-*/
-0x0000,
-0x9000,
-0x9000,
-0x6000,
-0x6000,
-0x9000,
-0x9000,
-0x0000,
-
-/* Character 89 (0x59):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | |
- |* *|
- |* *|
- | * * |
- | * |
- | * |
- | * |
- | |
- +-----+
-*/
-0x0000,
-0x8800,
-0x8800,
-0x5000,
-0x2000,
-0x2000,
-0x2000,
-0x0000,
-
-/* Character 90 (0x5a):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | |
- |**** |
- | * |
- | * |
- | * |
- |* |
- |**** |
- | |
- +-----+
-*/
-0x0000,
-0xf000,
-0x1000,
-0x2000,
-0x4000,
-0x8000,
-0xf000,
-0x0000,
-
-/* Character 91 (0x5b):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | |
- | *** |
- | * |
- | * |
- | * |
- | * |
- | *** |
- | |
- +-----+
-*/
-0x0000,
-0x7000,
-0x4000,
-0x4000,
-0x4000,
-0x4000,
-0x7000,
-0x0000,
-
-/* Character 92 (0x5c):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | |
- |* |
- |* |
- | * |
- | * |
- | * |
- | * |
- | |
- +-----+
-*/
-0x0000,
-0x8000,
-0x8000,
-0x4000,
-0x2000,
-0x1000,
-0x1000,
-0x0000,
-
-/* Character 93 (0x5d):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | |
- | *** |
- | * |
- | * |
- | * |
- | * |
- | *** |
- | |
- +-----+
-*/
-0x0000,
-0x7000,
-0x1000,
-0x1000,
-0x1000,
-0x1000,
-0x7000,
-0x0000,
-
-/* Character 94 (0x5e):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | |
- | * |
- | * * |
- | |
- | |
- | |
- | |
- | |
- +-----+
-*/
-0x0000,
-0x2000,
-0x5000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 95 (0x5f):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- |**** |
- +-----+
-*/
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0xf000,
-
-/* Character 96 (0x60):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | |
- | * |
- | * |
- | |
- | |
- | |
- | |
- | |
- +-----+
-*/
-0x0000,
-0x4000,
-0x2000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 97 (0x61):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | |
- | |
- | |
- | *** |
- |* * |
- |* * |
- | *** |
- | |
- +-----+
-*/
-0x0000,
-0x0000,
-0x0000,
-0x7000,
-0x9000,
-0x9000,
-0x7000,
-0x0000,
-
-/* Character 98 (0x62):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | |
- |* |
- |* |
- |*** |
- |* * |
- |* * |
- |*** |
- | |
- +-----+
-*/
-0x0000,
-0x8000,
-0x8000,
-0xe000,
-0x9000,
-0x9000,
-0xe000,
-0x0000,
-
-/* Character 99 (0x63):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | |
- | |
- | |
- | ** |
- | * |
- | * |
- | ** |
- | |
- +-----+
-*/
-0x0000,
-0x0000,
-0x0000,
-0x3000,
-0x4000,
-0x4000,
-0x3000,
-0x0000,
-
-/* Character 100 (0x64):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | |
- | * |
- | * |
- | *** |
- |* * |
- |* * |
- | *** |
- | |
- +-----+
-*/
-0x0000,
-0x1000,
-0x1000,
-0x7000,
-0x9000,
-0x9000,
-0x7000,
-0x0000,
-
-/* Character 101 (0x65):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | |
- | |
- | |
- | ** |
- |* ** |
- |** |
- | ** |
- | |
- +-----+
-*/
-0x0000,
-0x0000,
-0x0000,
-0x6000,
-0xb000,
-0xc000,
-0x6000,
-0x0000,
-
-/* Character 102 (0x66):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | |
- | * |
- | * * |
- | * |
- |*** |
- | * |
- | * |
- | |
- +-----+
-*/
-0x0000,
-0x2000,
-0x5000,
-0x4000,
-0xe000,
-0x4000,
-0x4000,
-0x0000,
-
-/* Character 103 (0x67):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | |
- | |
- | |
- | ** |
- |* * |
- | *** |
- | * |
- | ** |
- +-----+
-*/
-0x0000,
-0x0000,
-0x0000,
-0x6000,
-0x9000,
-0x7000,
-0x1000,
-0x6000,
-
-/* Character 104 (0x68):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | |
- |* |
- |* |
- |*** |
- |* * |
- |* * |
- |* * |
- | |
- +-----+
-*/
-0x0000,
-0x8000,
-0x8000,
-0xe000,
-0x9000,
-0x9000,
-0x9000,
-0x0000,
-
-/* Character 105 (0x69):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | |
- | * |
- | |
- | ** |
- | * |
- | * |
- | *** |
- | |
- +-----+
-*/
-0x0000,
-0x2000,
-0x0000,
-0x6000,
-0x2000,
-0x2000,
-0x7000,
-0x0000,
-
-/* Character 106 (0x6a):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | |
- | * |
- | |
- | * |
- | * |
- | * |
- | * * |
- | * |
- +-----+
-*/
-0x0000,
-0x1000,
-0x0000,
-0x1000,
-0x1000,
-0x1000,
-0x5000,
-0x2000,
-
-/* Character 107 (0x6b):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | |
- |* |
- |* |
- |* * |
- |*** |
- |* * |
- |* * |
- | |
- +-----+
-*/
-0x0000,
-0x8000,
-0x8000,
-0x9000,
-0xe000,
-0x9000,
-0x9000,
-0x0000,
-
-/* Character 108 (0x6c):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | |
- | ** |
- | * |
- | * |
- | * |
- | * |
- | *** |
- | |
- +-----+
-*/
-0x0000,
-0x6000,
-0x2000,
-0x2000,
-0x2000,
-0x2000,
-0x7000,
-0x0000,
-
-/* Character 109 (0x6d):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | |
- | |
- | |
- |** * |
- |* * *|
- |* * *|
- |* * *|
- | |
- +-----+
-*/
-0x0000,
-0x0000,
-0x0000,
-0xd000,
-0xa800,
-0xa800,
-0xa800,
-0x0000,
-
-/* Character 110 (0x6e):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | |
- | |
- | |
- |*** |
- |* * |
- |* * |
- |* * |
- | |
- +-----+
-*/
-0x0000,
-0x0000,
-0x0000,
-0xe000,
-0x9000,
-0x9000,
-0x9000,
-0x0000,
-
-/* Character 111 (0x6f):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | |
- | |
- | |
- | ** |
- |* * |
- |* * |
- | ** |
- | |
- +-----+
-*/
-0x0000,
-0x0000,
-0x0000,
-0x6000,
-0x9000,
-0x9000,
-0x6000,
-0x0000,
-
-/* Character 112 (0x70):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | |
- | |
- | |
- |*** |
- |* * |
- |*** |
- |* |
- |* |
- +-----+
-*/
-0x0000,
-0x0000,
-0x0000,
-0xe000,
-0x9000,
-0xe000,
-0x8000,
-0x8000,
-
-/* Character 113 (0x71):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | |
- | |
- | |
- | *** |
- |* * |
- | *** |
- | * |
- | * |
- +-----+
-*/
-0x0000,
-0x0000,
-0x0000,
-0x7000,
-0x9000,
-0x7000,
-0x1000,
-0x1000,
-
-/* Character 114 (0x72):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | |
- | |
- | |
- |* * |
- |** * |
- |* |
- |* |
- | |
- +-----+
-*/
-0x0000,
-0x0000,
-0x0000,
-0xa000,
-0xd000,
-0x8000,
-0x8000,
-0x0000,
-
-/* Character 115 (0x73):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | |
- | |
- | |
- | ** |
- | ** |
- | * |
- | ** |
- | |
- +-----+
-*/
-0x0000,
-0x0000,
-0x0000,
-0x3000,
-0x6000,
-0x1000,
-0x6000,
-0x0000,
-
-/* Character 116 (0x74):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | |
- | * |
- | * |
- |*** |
- | * |
- | * * |
- | * |
- | |
- +-----+
-*/
-0x0000,
-0x4000,
-0x4000,
-0xe000,
-0x4000,
-0x5000,
-0x2000,
-0x0000,
-
-/* Character 117 (0x75):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | |
- | |
- | |
- |* * |
- |* * |
- |* * |
- | *** |
- | |
- +-----+
-*/
-0x0000,
-0x0000,
-0x0000,
-0x9000,
-0x9000,
-0x9000,
-0x7000,
-0x0000,
-
-/* Character 118 (0x76):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | |
- | |
- | |
- | * * |
- | * * |
- | * * |
- | * |
- | |
- +-----+
-*/
-0x0000,
-0x0000,
-0x0000,
-0x5000,
-0x5000,
-0x5000,
-0x2000,
-0x0000,
-
-/* Character 119 (0x77):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | |
- | |
- | |
- |* *|
- |* * *|
- |* * *|
- | * * |
- | |
- +-----+
-*/
-0x0000,
-0x0000,
-0x0000,
-0x8800,
-0xa800,
-0xa800,
-0x5000,
-0x0000,
-
-/* Character 120 (0x78):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | |
- | |
- | |
- |* * |
- | ** |
- | ** |
- |* * |
- | |
- +-----+
-*/
-0x0000,
-0x0000,
-0x0000,
-0x9000,
-0x6000,
-0x6000,
-0x9000,
-0x0000,
-
-/* Character 121 (0x79):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | |
- | |
- | |
- |* * |
- |* * |
- | *** |
- |* * |
- | ** |
- +-----+
-*/
-0x0000,
-0x0000,
-0x0000,
-0x9000,
-0x9000,
-0x7000,
-0x9000,
-0x6000,
-
-/* Character 122 (0x7a):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | |
- | |
- | |
- |**** |
- | * |
- | * |
- |**** |
- | |
- +-----+
-*/
-0x0000,
-0x0000,
-0x0000,
-0xf000,
-0x2000,
-0x4000,
-0xf000,
-0x0000,
-
-/* Character 123 (0x7b):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | ** |
- | * |
- | * |
- |** |
- | * |
- | * |
- | ** |
- | |
- +-----+
-*/
-0x3000,
-0x4000,
-0x2000,
-0xc000,
-0x2000,
-0x4000,
-0x3000,
-0x0000,
-
-/* Character 124 (0x7c):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | |
- | * |
- | * |
- | * |
- | * |
- | * |
- | * |
- | |
- +-----+
-*/
-0x0000,
-0x2000,
-0x2000,
-0x2000,
-0x2000,
-0x2000,
-0x2000,
-0x0000,
-
-/* Character 125 (0x7d):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- |** |
- | * |
- | * |
- | ** |
- | * |
- | * |
- |** |
- | |
- +-----+
-*/
-0xc000,
-0x2000,
-0x4000,
-0x3000,
-0x4000,
-0x2000,
-0xc000,
-0x0000,
-
-/* Character 126 (0x7e):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | |
- | * * |
- |* * |
- | |
- | |
- | |
- | |
- | |
- +-----+
-*/
-0x0000,
-0x5000,
-0xa000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 160 (0xa0):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- +-----+
-*/
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 161 (0xa1):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | |
- | * |
- | |
- | * |
- | * |
- | * |
- | * |
- | |
- +-----+
-*/
-0x0000,
-0x2000,
-0x0000,
-0x2000,
-0x2000,
-0x2000,
-0x2000,
-0x0000,
-
-/* Character 162 (0xa2):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | |
- | |
- | * |
- | *** |
- |* * |
- |* * |
- | *** |
- | * |
- +-----+
-*/
-0x0000,
-0x0000,
-0x2000,
-0x7000,
-0xa000,
-0xa000,
-0x7000,
-0x2000,
-
-/* Character 163 (0xa3):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | |
- | * |
- | * * |
- |*** |
- | * |
- | * * |
- |* * |
- | |
- +-----+
-*/
-0x0000,
-0x2000,
-0x5000,
-0xe000,
-0x4000,
-0x5000,
-0xa000,
-0x0000,
-
-/* Character 164 (0xa4):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | |
- | |
- |* *|
- | *** |
- | * * |
- | *** |
- |* *|
- | |
- +-----+
-*/
-0x0000,
-0x0000,
-0x8800,
-0x7000,
-0x5000,
-0x7000,
-0x8800,
-0x0000,
-
-/* Character 165 (0xa5):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | |
- |* *|
- | * * |
- |*****|
- | * |
- |*****|
- | * |
- | |
- +-----+
-*/
-0x0000,
-0x8800,
-0x5000,
-0xf800,
-0x2000,
-0xf800,
-0x2000,
-0x0000,
-
-/* Character 166 (0xa6):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | * |
- | * |
- | * |
- | |
- | * |
- | * |
- | * |
- | |
- +-----+
-*/
-0x2000,
-0x2000,
-0x2000,
-0x0000,
-0x2000,
-0x2000,
-0x2000,
-0x0000,
-
-/* Character 167 (0xa7):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | *** |
- |* |
- |*** |
- |* * |
- | *** |
- | * |
- |*** |
- | |
- +-----+
-*/
-0x7000,
-0x8000,
-0xe000,
-0x9000,
-0x7000,
-0x1000,
-0xe000,
-0x0000,
-
-/* Character 168 (0xa8):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | |
- | * * |
- | |
- | |
- | |
- | |
- | |
- | |
- +-----+
-*/
-0x0000,
-0x5000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 169 (0xa9):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | |
- | *** |
- |* * *|
- |** *|
- |** *|
- |* * *|
- | *** |
- | |
- +-----+
-*/
-0x0000,
-0x7000,
-0xa800,
-0xc800,
-0xc800,
-0xa800,
-0x7000,
-0x0000,
-
-/* Character 170 (0xaa):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | ** |
- | * * |
- | ** |
- | |
- | *** |
- | |
- | |
- | |
- +-----+
-*/
-0x3000,
-0x5000,
-0x3000,
-0x0000,
-0x7000,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 171 (0xab):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | |
- | |
- | |
- | * * |
- |* * |
- | * * |
- | |
- | |
- +-----+
-*/
-0x0000,
-0x0000,
-0x0000,
-0x5000,
-0xa000,
-0x5000,
-0x0000,
-0x0000,
-
-/* Character 172 (0xac):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | |
- | |
- | |
- | |
- | *** |
- | * |
- | * |
- | |
- +-----+
-*/
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x7000,
-0x1000,
-0x1000,
-0x0000,
-
-/* Character 173 (0xad):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | |
- | |
- | |
- | |
- | *** |
- | |
- | |
- | |
- +-----+
-*/
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x7000,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 174 (0xae):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | |
- | *** |
- |*** *|
- |** **|
- |*** *|
- |** **|
- | *** |
- | |
- +-----+
-*/
-0x0000,
-0x7000,
-0xe800,
-0xd800,
-0xe800,
-0xd800,
-0x7000,
-0x0000,
-
-/* Character 175 (0xaf):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | |
- | *** |
- | |
- | |
- | |
- | |
- | |
- | |
- +-----+
-*/
-0x0000,
-0x7000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 176 (0xb0):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | |
- | * |
- | * * |
- | * |
- | |
- | |
- | |
- | |
- +-----+
-*/
-0x0000,
-0x2000,
-0x5000,
-0x2000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 177 (0xb1):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | |
- | |
- | * |
- | *** |
- | * |
- | |
- | *** |
- | |
- +-----+
-*/
-0x0000,
-0x0000,
-0x2000,
-0x7000,
-0x2000,
-0x0000,
-0x7000,
-0x0000,
-
-/* Character 178 (0xb2):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | * |
- | * * |
- | * |
- | * |
- | *** |
- | |
- | |
- | |
- +-----+
-*/
-0x2000,
-0x5000,
-0x1000,
-0x2000,
-0x7000,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 179 (0xb3):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | ** |
- | * |
- | ** |
- | * |
- | ** |
- | |
- | |
- | |
- +-----+
-*/
-0x6000,
-0x1000,
-0x6000,
-0x1000,
-0x6000,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 180 (0xb4):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | |
- | * |
- | * |
- | |
- | |
- | |
- | |
- | |
- +-----+
-*/
-0x0000,
-0x2000,
-0x4000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 181 (0xb5):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | |
- | |
- | |
- |* * |
- |* * |
- |* * |
- |*** |
- |* |
- +-----+
-*/
-0x0000,
-0x0000,
-0x0000,
-0x9000,
-0x9000,
-0x9000,
-0xe000,
-0x8000,
-
-/* Character 182 (0xb6):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | |
- | ****|
- |*** *|
- |*** *|
- | ** *|
- | * *|
- | * *|
- | |
- +-----+
-*/
-0x0000,
-0x7800,
-0xe800,
-0xe800,
-0x6800,
-0x2800,
-0x2800,
-0x0000,
-
-/* Character 183 (0xb7):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | |
- | |
- | |
- | |
- | * |
- | |
- | |
- | |
- +-----+
-*/
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x2000,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 184 (0xb8):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | |
- | |
- | |
- | |
- | |
- | |
- | * |
- | * |
- +-----+
-*/
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x2000,
-0x4000,
-
-/* Character 185 (0xb9):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | * |
- | ** |
- | * |
- | * |
- | *** |
- | |
- | |
- | |
- +-----+
-*/
-0x2000,
-0x6000,
-0x2000,
-0x2000,
-0x7000,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 186 (0xba):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | * |
- | * * |
- | * |
- | |
- | *** |
- | |
- | |
- | |
- +-----+
-*/
-0x2000,
-0x5000,
-0x2000,
-0x0000,
-0x7000,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 187 (0xbb):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | |
- | |
- | |
- |* * |
- | * * |
- |* * |
- | |
- | |
- +-----+
-*/
-0x0000,
-0x0000,
-0x0000,
-0xa000,
-0x5000,
-0xa000,
-0x0000,
-0x0000,
-
-/* Character 188 (0xbc):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- |* |
- |* |
- |* |
- |* * |
- | ** |
- |**** |
- | * |
- | |
- +-----+
-*/
-0x8000,
-0x8000,
-0x8000,
-0xa000,
-0x6000,
-0xf000,
-0x2000,
-0x0000,
-
-/* Character 189 (0xbd):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- |* |
- |* |
- |* * |
- |** * |
- | * |
- | * |
- | *** |
- | |
- +-----+
-*/
-0x8000,
-0x8000,
-0xa000,
-0xd000,
-0x1000,
-0x2000,
-0x7000,
-0x0000,
-
-/* Character 190 (0xbe):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- |* |
- | * |
- |* |
- | ** |
- |* * |
- |**** |
- | * |
- | |
- +-----+
-*/
-0x8000,
-0x4000,
-0x8000,
-0x6000,
-0xa000,
-0xf000,
-0x2000,
-0x0000,
-
-/* Character 191 (0xbf):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | |
- | * |
- | |
- | * |
- | * |
- | * * |
- | * |
- | |
- +-----+
-*/
-0x0000,
-0x2000,
-0x0000,
-0x2000,
-0x4000,
-0x5000,
-0x2000,
-0x0000,
-
-/* Character 192 (0xc0):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | * |
- | * |
- | ** |
- |* * |
- |**** |
- |* * |
- |* * |
- | |
- +-----+
-*/
-0x4000,
-0x2000,
-0x6000,
-0x9000,
-0xf000,
-0x9000,
-0x9000,
-0x0000,
-
-/* Character 193 (0xc1):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | * |
- | * |
- | ** |
- |* * |
- |**** |
- |* * |
- |* * |
- | |
- +-----+
-*/
-0x2000,
-0x4000,
-0x6000,
-0x9000,
-0xf000,
-0x9000,
-0x9000,
-0x0000,
-
-/* Character 194 (0xc2):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | ** |
- |* * |
- | ** |
- |* * |
- |**** |
- |* * |
- |* * |
- | |
- +-----+
-*/
-0x6000,
-0x9000,
-0x6000,
-0x9000,
-0xf000,
-0x9000,
-0x9000,
-0x0000,
-
-/* Character 195 (0xc3):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | * * |
- |* * |
- | ** |
- |* * |
- |**** |
- |* * |
- |* * |
- | |
- +-----+
-*/
-0x5000,
-0xa000,
-0x6000,
-0x9000,
-0xf000,
-0x9000,
-0x9000,
-0x0000,
-
-/* Character 196 (0xc4):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- |* * |
- | |
- | ** |
- |* * |
- |**** |
- |* * |
- |* * |
- | |
- +-----+
-*/
-0x9000,
-0x0000,
-0x6000,
-0x9000,
-0xf000,
-0x9000,
-0x9000,
-0x0000,
-
-/* Character 197 (0xc5):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | ** |
- |* * |
- | ** |
- |* * |
- |**** |
- |* * |
- |* * |
- | |
- +-----+
-*/
-0x6000,
-0x9000,
-0x6000,
-0x9000,
-0xf000,
-0x9000,
-0x9000,
-0x0000,
-
-/* Character 198 (0xc6):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | |
- | *** |
- |* * |
- |* * |
- |**** |
- |* * |
- |* ** |
- | |
- +-----+
-*/
-0x0000,
-0x7000,
-0xa000,
-0xa000,
-0xf000,
-0xa000,
-0xb000,
-0x0000,
-
-/* Character 199 (0xc7):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | |
- | ** |
- |* * |
- |* |
- |* |
- |* * |
- | ** |
- | * |
- +-----+
-*/
-0x0000,
-0x6000,
-0x9000,
-0x8000,
-0x8000,
-0x9000,
-0x6000,
-0x4000,
-
-/* Character 200 (0xc8):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | * |
- | * |
- |**** |
- |* |
- |*** |
- |* |
- |**** |
- | |
- +-----+
-*/
-0x4000,
-0x2000,
-0xf000,
-0x8000,
-0xe000,
-0x8000,
-0xf000,
-0x0000,
-
-/* Character 201 (0xc9):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | * |
- | * |
- |**** |
- |* |
- |*** |
- |* |
- |**** |
- | |
- +-----+
-*/
-0x2000,
-0x4000,
-0xf000,
-0x8000,
-0xe000,
-0x8000,
-0xf000,
-0x0000,
-
-/* Character 202 (0xca):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | ** |
- |* * |
- |**** |
- |* |
- |*** |
- |* |
- |**** |
- | |
- +-----+
-*/
-0x6000,
-0x9000,
-0xf000,
-0x8000,
-0xe000,
-0x8000,
-0xf000,
-0x0000,
-
-/* Character 203 (0xcb):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- |* * |
- | |
- |**** |
- |* |
- |*** |
- |* |
- |**** |
- | |
- +-----+
-*/
-0x9000,
-0x0000,
-0xf000,
-0x8000,
-0xe000,
-0x8000,
-0xf000,
-0x0000,
-
-/* Character 204 (0xcc):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | * |
- | * |
- | *** |
- | * |
- | * |
- | * |
- | *** |
- | |
- +-----+
-*/
-0x4000,
-0x2000,
-0x7000,
-0x2000,
-0x2000,
-0x2000,
-0x7000,
-0x0000,
-
-/* Character 205 (0xcd):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | * |
- | * |
- | *** |
- | * |
- | * |
- | * |
- | *** |
- | |
- +-----+
-*/
-0x1000,
-0x2000,
-0x7000,
-0x2000,
-0x2000,
-0x2000,
-0x7000,
-0x0000,
-
-/* Character 206 (0xce):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | * |
- | * * |
- | *** |
- | * |
- | * |
- | * |
- | *** |
- | |
- +-----+
-*/
-0x2000,
-0x5000,
-0x7000,
-0x2000,
-0x2000,
-0x2000,
-0x7000,
-0x0000,
-
-/* Character 207 (0xcf):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | * * |
- | |
- | *** |
- | * |
- | * |
- | * |
- | *** |
- | |
- +-----+
-*/
-0x5000,
-0x0000,
-0x7000,
-0x2000,
-0x2000,
-0x2000,
-0x7000,
-0x0000,
-
-/* Character 208 (0xd0):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | |
- | *** |
- | * *|
- |*** *|
- | * *|
- | * *|
- | *** |
- | |
- +-----+
-*/
-0x0000,
-0x7000,
-0x4800,
-0xe800,
-0x4800,
-0x4800,
-0x7000,
-0x0000,
-
-/* Character 209 (0xd1):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | * * |
- |* * |
- |* * |
- |** * |
- |* ** |
- |* * |
- |* * |
- | |
- +-----+
-*/
-0x5000,
-0xa000,
-0x9000,
-0xd000,
-0xb000,
-0x9000,
-0x9000,
-0x0000,
-
-/* Character 210 (0xd2):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | * |
- | * |
- | ** |
- |* * |
- |* * |
- |* * |
- | ** |
- | |
- +-----+
-*/
-0x4000,
-0x2000,
-0x6000,
-0x9000,
-0x9000,
-0x9000,
-0x6000,
-0x0000,
-
-/* Character 211 (0xd3):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | * |
- | * |
- | ** |
- |* * |
- |* * |
- |* * |
- | ** |
- | |
- +-----+
-*/
-0x2000,
-0x4000,
-0x6000,
-0x9000,
-0x9000,
-0x9000,
-0x6000,
-0x0000,
-
-/* Character 212 (0xd4):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | ** |
- |* * |
- | ** |
- |* * |
- |* * |
- |* * |
- | ** |
- | |
- +-----+
-*/
-0x6000,
-0x9000,
-0x6000,
-0x9000,
-0x9000,
-0x9000,
-0x6000,
-0x0000,
-
-/* Character 213 (0xd5):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | * * |
- |* * |
- | ** |
- |* * |
- |* * |
- |* * |
- | ** |
- | |
- +-----+
-*/
-0x5000,
-0xa000,
-0x6000,
-0x9000,
-0x9000,
-0x9000,
-0x6000,
-0x0000,
-
-/* Character 214 (0xd6):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- |* * |
- | |
- | ** |
- |* * |
- |* * |
- |* * |
- | ** |
- | |
- +-----+
-*/
-0x9000,
-0x0000,
-0x6000,
-0x9000,
-0x9000,
-0x9000,
-0x6000,
-0x0000,
-
-/* Character 215 (0xd7):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | |
- | |
- | |
- | |
- | * * |
- | * |
- | * * |
- | |
- +-----+
-*/
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x5000,
-0x2000,
-0x5000,
-0x0000,
-
-/* Character 216 (0xd8):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | |
- | *** |
- |* ** |
- |* ** |
- |** * |
- |** * |
- |*** |
- | |
- +-----+
-*/
-0x0000,
-0x7000,
-0xb000,
-0xb000,
-0xd000,
-0xd000,
-0xe000,
-0x0000,
-
-/* Character 217 (0xd9):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | * |
- | * |
- |* * |
- |* * |
- |* * |
- |* * |
- | ** |
- | |
- +-----+
-*/
-0x4000,
-0x2000,
-0x9000,
-0x9000,
-0x9000,
-0x9000,
-0x6000,
-0x0000,
-
-/* Character 218 (0xda):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | * |
- | * |
- |* * |
- |* * |
- |* * |
- |* * |
- | ** |
- | |
- +-----+
-*/
-0x2000,
-0x4000,
-0x9000,
-0x9000,
-0x9000,
-0x9000,
-0x6000,
-0x0000,
-
-/* Character 219 (0xdb):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | ** |
- |* * |
- |* * |
- |* * |
- |* * |
- |* * |
- | ** |
- | |
- +-----+
-*/
-0x6000,
-0x9000,
-0x9000,
-0x9000,
-0x9000,
-0x9000,
-0x6000,
-0x0000,
-
-/* Character 220 (0xdc):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- |* * |
- | |
- |* * |
- |* * |
- |* * |
- |* * |
- | ** |
- | |
- +-----+
-*/
-0x9000,
-0x0000,
-0x9000,
-0x9000,
-0x9000,
-0x9000,
-0x6000,
-0x0000,
-
-/* Character 221 (0xdd):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | * |
- | * |
- |* *|
- | * * |
- | * |
- | * |
- | * |
- | |
- +-----+
-*/
-0x1000,
-0x2000,
-0x8800,
-0x5000,
-0x2000,
-0x2000,
-0x2000,
-0x0000,
-
-/* Character 222 (0xde):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | |
- |* |
- |*** |
- |* * |
- |* * |
- |*** |
- |* |
- | |
- +-----+
-*/
-0x0000,
-0x8000,
-0xe000,
-0x9000,
-0x9000,
-0xe000,
-0x8000,
-0x0000,
-
-/* Character 223 (0xdf):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | |
- | ** |
- |* * |
- |* * |
- |* * |
- |* * |
- |* * |
- | |
- +-----+
-*/
-0x0000,
-0x6000,
-0x9000,
-0xa000,
-0xa000,
-0x9000,
-0xa000,
-0x0000,
-
-/* Character 224 (0xe0):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | * |
- | * |
- | |
- | *** |
- |* * |
- |* * |
- | *** |
- | |
- +-----+
-*/
-0x4000,
-0x2000,
-0x0000,
-0x7000,
-0x9000,
-0x9000,
-0x7000,
-0x0000,
-
-/* Character 225 (0xe1):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | * |
- | * |
- | |
- | *** |
- |* * |
- |* * |
- | *** |
- | |
- +-----+
-*/
-0x2000,
-0x4000,
-0x0000,
-0x7000,
-0x9000,
-0x9000,
-0x7000,
-0x0000,
-
-/* Character 226 (0xe2):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | * |
- | * * |
- | |
- | *** |
- |* * |
- |* * |
- | *** |
- | |
- +-----+
-*/
-0x2000,
-0x5000,
-0x0000,
-0x7000,
-0x9000,
-0x9000,
-0x7000,
-0x0000,
-
-/* Character 227 (0xe3):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | * * |
- |* * |
- | |
- | *** |
- |* * |
- |* * |
- | *** |
- | |
- +-----+
-*/
-0x5000,
-0xa000,
-0x0000,
-0x7000,
-0x9000,
-0x9000,
-0x7000,
-0x0000,
-
-/* Character 228 (0xe4):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | |
- | * * |
- | |
- | *** |
- |* * |
- |* * |
- | *** |
- | |
- +-----+
-*/
-0x0000,
-0x5000,
-0x0000,
-0x7000,
-0x9000,
-0x9000,
-0x7000,
-0x0000,
-
-/* Character 229 (0xe5):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | ** |
- |* * |
- | ** |
- | *** |
- |* * |
- |* * |
- | *** |
- | |
- +-----+
-*/
-0x6000,
-0x9000,
-0x6000,
-0x7000,
-0x9000,
-0x9000,
-0x7000,
-0x0000,
-
-/* Character 230 (0xe6):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | |
- | |
- | |
- |**** |
- | ** *|
- |* ** |
- | ****|
- | |
- +-----+
-*/
-0x0000,
-0x0000,
-0x0000,
-0xf000,
-0x6800,
-0xb000,
-0x7800,
-0x0000,
-
-/* Character 231 (0xe7):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | |
- | |
- | |
- | ** |
- | * |
- | * |
- | ** |
- | * |
- +-----+
-*/
-0x0000,
-0x0000,
-0x0000,
-0x3000,
-0x4000,
-0x4000,
-0x3000,
-0x2000,
-
-/* Character 232 (0xe8):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | * |
- | * |
- | |
- | ** |
- |* ** |
- |** |
- | ** |
- | |
- +-----+
-*/
-0x4000,
-0x2000,
-0x0000,
-0x6000,
-0xb000,
-0xc000,
-0x6000,
-0x0000,
-
-/* Character 233 (0xe9):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | * |
- | * |
- | |
- | ** |
- |* ** |
- |** |
- | ** |
- | |
- +-----+
-*/
-0x2000,
-0x4000,
-0x0000,
-0x6000,
-0xb000,
-0xc000,
-0x6000,
-0x0000,
-
-/* Character 234 (0xea):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | ** |
- |* * |
- | |
- | ** |
- |* ** |
- |** |
- | ** |
- | |
- +-----+
-*/
-0x6000,
-0x9000,
-0x0000,
-0x6000,
-0xb000,
-0xc000,
-0x6000,
-0x0000,
-
-/* Character 235 (0xeb):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | |
- | * * |
- | |
- | ** |
- |* ** |
- |** |
- | ** |
- | |
- +-----+
-*/
-0x0000,
-0x5000,
-0x0000,
-0x6000,
-0xb000,
-0xc000,
-0x6000,
-0x0000,
-
-/* Character 236 (0xec):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | * |
- | * |
- | |
- | ** |
- | * |
- | * |
- | *** |
- | |
- +-----+
-*/
-0x4000,
-0x2000,
-0x0000,
-0x6000,
-0x2000,
-0x2000,
-0x7000,
-0x0000,
-
-/* Character 237 (0xed):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | * |
- | * |
- | |
- | ** |
- | * |
- | * |
- | *** |
- | |
- +-----+
-*/
-0x1000,
-0x2000,
-0x0000,
-0x6000,
-0x2000,
-0x2000,
-0x7000,
-0x0000,
-
-/* Character 238 (0xee):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | * |
- | * * |
- | |
- | ** |
- | * |
- | * |
- | *** |
- | |
- +-----+
-*/
-0x2000,
-0x5000,
-0x0000,
-0x6000,
-0x2000,
-0x2000,
-0x7000,
-0x0000,
-
-/* Character 239 (0xef):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | |
- | * * |
- | |
- | ** |
- | * |
- | * |
- | *** |
- | |
- +-----+
-*/
-0x0000,
-0x5000,
-0x0000,
-0x6000,
-0x2000,
-0x2000,
-0x7000,
-0x0000,
-
-/* Character 240 (0xf0):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- |* * |
- | * |
- |* * |
- | * |
- | *** |
- |* * |
- | ** |
- | |
- +-----+
-*/
-0xa000,
-0x4000,
-0xa000,
-0x1000,
-0x7000,
-0x9000,
-0x6000,
-0x0000,
-
-/* Character 241 (0xf1):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | * * |
- |* * |
- | |
- |*** |
- |* * |
- |* * |
- |* * |
- | |
- +-----+
-*/
-0x5000,
-0xa000,
-0x0000,
-0xe000,
-0x9000,
-0x9000,
-0x9000,
-0x0000,
-
-/* Character 242 (0xf2):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | * |
- | * |
- | |
- | ** |
- |* * |
- |* * |
- | ** |
- | |
- +-----+
-*/
-0x4000,
-0x2000,
-0x0000,
-0x6000,
-0x9000,
-0x9000,
-0x6000,
-0x0000,
-
-/* Character 243 (0xf3):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | * |
- | * |
- | |
- | ** |
- |* * |
- |* * |
- | ** |
- | |
- +-----+
-*/
-0x2000,
-0x4000,
-0x0000,
-0x6000,
-0x9000,
-0x9000,
-0x6000,
-0x0000,
-
-/* Character 244 (0xf4):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | ** |
- |* * |
- | |
- | ** |
- |* * |
- |* * |
- | ** |
- | |
- +-----+
-*/
-0x6000,
-0x9000,
-0x0000,
-0x6000,
-0x9000,
-0x9000,
-0x6000,
-0x0000,
-
-/* Character 245 (0xf5):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | * * |
- |* * |
- | |
- | ** |
- |* * |
- |* * |
- | ** |
- | |
- +-----+
-*/
-0x5000,
-0xa000,
-0x0000,
-0x6000,
-0x9000,
-0x9000,
-0x6000,
-0x0000,
-
-/* Character 246 (0xf6):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | |
- |* * |
- | |
- | ** |
- |* * |
- |* * |
- | ** |
- | |
- +-----+
-*/
-0x0000,
-0x9000,
-0x0000,
-0x6000,
-0x9000,
-0x9000,
-0x6000,
-0x0000,
-
-/* Character 247 (0xf7):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | |
- | |
- | * |
- | |
- | *** |
- | |
- | * |
- | |
- +-----+
-*/
-0x0000,
-0x0000,
-0x2000,
-0x0000,
-0x7000,
-0x0000,
-0x2000,
-0x0000,
-
-/* Character 248 (0xf8):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | |
- | |
- | |
- | *** |
- |* ** |
- |** * |
- |*** |
- | |
- +-----+
-*/
-0x0000,
-0x0000,
-0x0000,
-0x7000,
-0xb000,
-0xd000,
-0xe000,
-0x0000,
-
-/* Character 249 (0xf9):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | * |
- | * |
- | |
- |* * |
- |* * |
- |* * |
- | *** |
- | |
- +-----+
-*/
-0x4000,
-0x2000,
-0x0000,
-0x9000,
-0x9000,
-0x9000,
-0x7000,
-0x0000,
-
-/* Character 250 (0xfa):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | * |
- | * |
- | |
- |* * |
- |* * |
- |* * |
- | *** |
- | |
- +-----+
-*/
-0x2000,
-0x4000,
-0x0000,
-0x9000,
-0x9000,
-0x9000,
-0x7000,
-0x0000,
-
-/* Character 251 (0xfb):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | ** |
- |* * |
- | |
- |* * |
- |* * |
- |* * |
- | *** |
- | |
- +-----+
-*/
-0x6000,
-0x9000,
-0x0000,
-0x9000,
-0x9000,
-0x9000,
-0x7000,
-0x0000,
-
-/* Character 252 (0xfc):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | |
- |* * |
- | |
- |* * |
- |* * |
- |* * |
- | *** |
- | |
- +-----+
-*/
-0x0000,
-0x9000,
-0x0000,
-0x9000,
-0x9000,
-0x9000,
-0x7000,
-0x0000,
-
-/* Character 253 (0xfd):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | * |
- | * |
- | |
- |* * |
- |* * |
- | *** |
- |* * |
- | ** |
- +-----+
-*/
-0x2000,
-0x4000,
-0x0000,
-0x9000,
-0x9000,
-0x7000,
-0x9000,
-0x6000,
-
-/* Character 254 (0xfe):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | |
- |* |
- |* |
- |*** |
- |* * |
- |*** |
- |* |
- |* |
- +-----+
-*/
-0x0000,
-0x8000,
-0x8000,
-0xe000,
-0x9000,
-0xe000,
-0x8000,
-0x8000,
-
-/* Character 255 (0xff):
- width 5
- bbx ( 5, 8, 0, -1 )
-
- +-----+
- | |
- |* * |
- | |
- |* * |
- |* * |
- | *** |
- |* * |
- | ** |
- +-----+
-*/
-0x0000,
-0x9000,
-0x0000,
-0x9000,
-0x9000,
-0x7000,
-0x9000,
-0x6000,
-};
-
-/* Character->glyph mapping. */
-static const unsigned long _sysfont_offset[] = {
- 0, /* (0x00) */
- 8, /* (0x01) */
- 16, /* (0x02) */
- 24, /* (0x03) */
- 32, /* (0x04) */
- 40, /* (0x05) */
- 48, /* (0x06) */
- 56, /* (0x07) */
- 64, /* (0x08) */
- 72, /* (0x09) */
- 80, /* (0x0a) */
- 88, /* (0x0b) */
- 96, /* (0x0c) */
- 104, /* (0x0d) */
- 112, /* (0x0e) */
- 120, /* (0x0f) */
- 128, /* (0x10) */
- 136, /* (0x11) */
- 144, /* (0x12) */
- 152, /* (0x13) */
- 160, /* (0x14) */
- 168, /* (0x15) */
- 176, /* (0x16) */
- 184, /* (0x17) */
- 192, /* (0x18) */
- 200, /* (0x19) */
- 208, /* (0x1a) */
- 216, /* (0x1b) */
- 224, /* (0x1c) */
- 232, /* (0x1d) */
- 240, /* (0x1e) */
- 248, /* (0x1f) */
- 256, /* (0x20) */
- 264, /* (0x21) */
- 272, /* (0x22) */
- 280, /* (0x23) */
- 288, /* (0x24) */
- 296, /* (0x25) */
- 304, /* (0x26) */
- 312, /* (0x27) */
- 320, /* (0x28) */
- 328, /* (0x29) */
- 336, /* (0x2a) */
- 344, /* (0x2b) */
- 352, /* (0x2c) */
- 360, /* (0x2d) */
- 368, /* (0x2e) */
- 376, /* (0x2f) */
- 384, /* (0x30) */
- 392, /* (0x31) */
- 400, /* (0x32) */
- 408, /* (0x33) */
- 416, /* (0x34) */
- 424, /* (0x35) */
- 432, /* (0x36) */
- 440, /* (0x37) */
- 448, /* (0x38) */
- 456, /* (0x39) */
- 464, /* (0x3a) */
- 472, /* (0x3b) */
- 480, /* (0x3c) */
- 488, /* (0x3d) */
- 496, /* (0x3e) */
- 504, /* (0x3f) */
- 512, /* (0x40) */
- 520, /* (0x41) */
- 528, /* (0x42) */
- 536, /* (0x43) */
- 544, /* (0x44) */
- 552, /* (0x45) */
- 560, /* (0x46) */
- 568, /* (0x47) */
- 576, /* (0x48) */
- 584, /* (0x49) */
- 592, /* (0x4a) */
- 600, /* (0x4b) */
- 608, /* (0x4c) */
- 616, /* (0x4d) */
- 624, /* (0x4e) */
- 632, /* (0x4f) */
- 640, /* (0x50) */
- 648, /* (0x51) */
- 656, /* (0x52) */
- 664, /* (0x53) */
- 672, /* (0x54) */
- 680, /* (0x55) */
- 688, /* (0x56) */
- 696, /* (0x57) */
- 704, /* (0x58) */
- 712, /* (0x59) */
- 720, /* (0x5a) */
- 728, /* (0x5b) */
- 736, /* (0x5c) */
- 744, /* (0x5d) */
- 752, /* (0x5e) */
- 760, /* (0x5f) */
- 768, /* (0x60) */
- 776, /* (0x61) */
- 784, /* (0x62) */
- 792, /* (0x63) */
- 800, /* (0x64) */
- 808, /* (0x65) */
- 816, /* (0x66) */
- 824, /* (0x67) */
- 832, /* (0x68) */
- 840, /* (0x69) */
- 848, /* (0x6a) */
- 856, /* (0x6b) */
- 864, /* (0x6c) */
- 872, /* (0x6d) */
- 880, /* (0x6e) */
- 888, /* (0x6f) */
- 896, /* (0x70) */
- 904, /* (0x71) */
- 912, /* (0x72) */
- 920, /* (0x73) */
- 928, /* (0x74) */
- 936, /* (0x75) */
- 944, /* (0x76) */
- 952, /* (0x77) */
- 960, /* (0x78) */
- 968, /* (0x79) */
- 976, /* (0x7a) */
- 984, /* (0x7b) */
- 992, /* (0x7c) */
- 1000, /* (0x7d) */
- 1008, /* (0x7e) */
- 0, /* (0x7f) */
- 0, /* (0x80) */
- 0, /* (0x81) */
- 0, /* (0x82) */
- 0, /* (0x83) */
- 0, /* (0x84) */
- 0, /* (0x85) */
- 0, /* (0x86) */
- 0, /* (0x87) */
- 0, /* (0x88) */
- 0, /* (0x89) */
- 0, /* (0x8a) */
- 0, /* (0x8b) */
- 0, /* (0x8c) */
- 0, /* (0x8d) */
- 0, /* (0x8e) */
- 0, /* (0x8f) */
- 0, /* (0x90) */
- 0, /* (0x91) */
- 0, /* (0x92) */
- 0, /* (0x93) */
- 0, /* (0x94) */
- 0, /* (0x95) */
- 0, /* (0x96) */
- 0, /* (0x97) */
- 0, /* (0x98) */
- 0, /* (0x99) */
- 0, /* (0x9a) */
- 0, /* (0x9b) */
- 0, /* (0x9c) */
- 0, /* (0x9d) */
- 0, /* (0x9e) */
- 0, /* (0x9f) */
- 1016, /* (0xa0) */
- 1024, /* (0xa1) */
- 1032, /* (0xa2) */
- 1040, /* (0xa3) */
- 1048, /* (0xa4) */
- 1056, /* (0xa5) */
- 1064, /* (0xa6) */
- 1072, /* (0xa7) */
- 1080, /* (0xa8) */
- 1088, /* (0xa9) */
- 1096, /* (0xaa) */
- 1104, /* (0xab) */
- 1112, /* (0xac) */
- 1120, /* (0xad) */
- 1128, /* (0xae) */
- 1136, /* (0xaf) */
- 1144, /* (0xb0) */
- 1152, /* (0xb1) */
- 1160, /* (0xb2) */
- 1168, /* (0xb3) */
- 1176, /* (0xb4) */
- 1184, /* (0xb5) */
- 1192, /* (0xb6) */
- 1200, /* (0xb7) */
- 1208, /* (0xb8) */
- 1216, /* (0xb9) */
- 1224, /* (0xba) */
- 1232, /* (0xbb) */
- 1240, /* (0xbc) */
- 1248, /* (0xbd) */
- 1256, /* (0xbe) */
- 1264, /* (0xbf) */
- 1272, /* (0xc0) */
- 1280, /* (0xc1) */
- 1288, /* (0xc2) */
- 1296, /* (0xc3) */
- 1304, /* (0xc4) */
- 1312, /* (0xc5) */
- 1320, /* (0xc6) */
- 1328, /* (0xc7) */
- 1336, /* (0xc8) */
- 1344, /* (0xc9) */
- 1352, /* (0xca) */
- 1360, /* (0xcb) */
- 1368, /* (0xcc) */
- 1376, /* (0xcd) */
- 1384, /* (0xce) */
- 1392, /* (0xcf) */
- 1400, /* (0xd0) */
- 1408, /* (0xd1) */
- 1416, /* (0xd2) */
- 1424, /* (0xd3) */
- 1432, /* (0xd4) */
- 1440, /* (0xd5) */
- 1448, /* (0xd6) */
- 1456, /* (0xd7) */
- 1464, /* (0xd8) */
- 1472, /* (0xd9) */
- 1480, /* (0xda) */
- 1488, /* (0xdb) */
- 1496, /* (0xdc) */
- 1504, /* (0xdd) */
- 1512, /* (0xde) */
- 1520, /* (0xdf) */
- 1528, /* (0xe0) */
- 1536, /* (0xe1) */
- 1544, /* (0xe2) */
- 1552, /* (0xe3) */
- 1560, /* (0xe4) */
- 1568, /* (0xe5) */
- 1576, /* (0xe6) */
- 1584, /* (0xe7) */
- 1592, /* (0xe8) */
- 1600, /* (0xe9) */
- 1608, /* (0xea) */
- 1616, /* (0xeb) */
- 1624, /* (0xec) */
- 1632, /* (0xed) */
- 1640, /* (0xee) */
- 1648, /* (0xef) */
- 1656, /* (0xf0) */
- 1664, /* (0xf1) */
- 1672, /* (0xf2) */
- 1680, /* (0xf3) */
- 1688, /* (0xf4) */
- 1696, /* (0xf5) */
- 1704, /* (0xf6) */
- 1712, /* (0xf7) */
- 1720, /* (0xf8) */
- 1728, /* (0xf9) */
- 1736, /* (0xfa) */
- 1744, /* (0xfb) */
- 1752, /* (0xfc) */
- 1760, /* (0xfd) */
- 1768, /* (0xfe) */
- 1776, /* (0xff) */
-};
-
-/* Exported structure definition. */
-static const BdfFontDesc desc = {
- "5x8-L1",
- 5,
- 8,
- 5, 8, 0, -1,
- 7,
+// Character 0 (0x00)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | |
+// |* * |
+// | * |
+// |* |
+// | * |
+// |* |
+// | * * |
+// | |
+// +-----+
+static const byte glyph0[] = {
+ 0x00,
+ 0xA0,
+ 0x10,
+ 0x80,
+ 0x10,
+ 0x80,
+ 0x50,
+ 0x00
+};
+
+// Character 1 (0x01)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | |
+// | |
+// | * |
+// | *** |
+// |*****|
+// | *** |
+// | * |
+// | |
+// +-----+
+static const byte glyph1[] = {
+ 0x00,
+ 0x00,
+ 0x20,
+ 0x70,
+ 0xF8,
+ 0x70,
+ 0x20,
+ 0x00
+};
+
+// Character 2 (0x02)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | * * |
+// |* * *|
+// | * * |
+// |* * *|
+// | * * |
+// |* * *|
+// | * * |
+// |* * *|
+// +-----+
+static const byte glyph2[] = {
+ 0x50,
+ 0xA8,
+ 0x50,
+ 0xA8,
+ 0x50,
+ 0xA8,
+ 0x50,
+ 0xA8
+};
+
+// Character 3 (0x03)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// |* * |
+// |* * |
+// |*** |
+// |* * |
+// |* * |
+// | *** |
+// | * |
+// | * |
+// +-----+
+static const byte glyph3[] = {
+ 0xA0,
+ 0xA0,
+ 0xE0,
+ 0xA0,
+ 0xA0,
+ 0x70,
+ 0x20,
+ 0x20
+};
+
+// Character 4 (0x04)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// |*** |
+// |* |
+// |** |
+// |* ***|
+// |* * |
+// | ** |
+// | * |
+// | * |
+// +-----+
+static const byte glyph4[] = {
+ 0xE0,
+ 0x80,
+ 0xC0,
+ 0xB8,
+ 0xA0,
+ 0x30,
+ 0x20,
+ 0x20
+};
+
+// Character 5 (0x05)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | ** |
+// |* |
+// |* |
+// | ** |
+// | ** |
+// | * *|
+// | ** |
+// | * *|
+// +-----+
+static const byte glyph5[] = {
+ 0x60,
+ 0x80,
+ 0x80,
+ 0x60,
+ 0x30,
+ 0x28,
+ 0x30,
+ 0x28
+};
+
+// Character 6 (0x06)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// |* |
+// |* |
+// |* |
+// |*** |
+// | ***|
+// | * |
+// | ** |
+// | * |
+// +-----+
+static const byte glyph6[] = {
+ 0x80,
+ 0x80,
+ 0x80,
+ 0xE0,
+ 0x38,
+ 0x20,
+ 0x30,
+ 0x20
+};
+
+// Character 7 (0x07)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | |
+// | * |
+// | * * |
+// | * |
+// | |
+// | |
+// | |
+// | |
+// +-----+
+static const byte glyph7[] = {
+ 0x00,
+ 0x20,
+ 0x50,
+ 0x20,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 8 (0x08)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | |
+// | |
+// | * |
+// | *** |
+// | * |
+// | |
+// | *** |
+// | |
+// +-----+
+static const byte glyph8[] = {
+ 0x00,
+ 0x00,
+ 0x20,
+ 0x70,
+ 0x20,
+ 0x00,
+ 0x70,
+ 0x00
+};
+
+// Character 9 (0x09)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// |* * |
+// |** * |
+// |* ** |
+// |* * |
+// | * |
+// | * |
+// | * |
+// | ***|
+// +-----+
+static const byte glyph9[] = {
+ 0x90,
+ 0xD0,
+ 0xB0,
+ 0x90,
+ 0x20,
+ 0x20,
+ 0x20,
+ 0x38
+};
+
+// Character 10 (0x0A)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// |* * |
+// |* * |
+// |* * |
+// | * |
+// | ***|
+// | * |
+// | * |
+// | * |
+// +-----+
+static const byte glyph10[] = {
+ 0xA0,
+ 0xA0,
+ 0xA0,
+ 0x40,
+ 0x38,
+ 0x10,
+ 0x10,
+ 0x10
+};
+
+// Character 11 (0x0B)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | * |
+// | * |
+// | * |
+// |*** |
+// | |
+// | |
+// | |
+// | |
+// +-----+
+static const byte glyph11[] = {
+ 0x20,
+ 0x20,
+ 0x20,
+ 0xE0,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 12 (0x0C)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | |
+// | |
+// | |
+// |*** |
+// | * |
+// | * |
+// | * |
+// | * |
+// +-----+
+static const byte glyph12[] = {
+ 0x00,
+ 0x00,
+ 0x00,
+ 0xE0,
+ 0x20,
+ 0x20,
+ 0x20,
+ 0x20
+};
+
+// Character 13 (0x0D)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | |
+// | |
+// | |
+// | ***|
+// | * |
+// | * |
+// | * |
+// | * |
+// +-----+
+static const byte glyph13[] = {
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x38,
+ 0x20,
+ 0x20,
+ 0x20,
+ 0x20
+};
+
+// Character 14 (0x0E)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | * |
+// | * |
+// | * |
+// | ***|
+// | |
+// | |
+// | |
+// | |
+// +-----+
+static const byte glyph14[] = {
+ 0x20,
+ 0x20,
+ 0x20,
+ 0x38,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 15 (0x0F)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | * |
+// | * |
+// | * |
+// |*****|
+// | * |
+// | * |
+// | * |
+// | * |
+// +-----+
+static const byte glyph15[] = {
+ 0x20,
+ 0x20,
+ 0x20,
+ 0xF8,
+ 0x20,
+ 0x20,
+ 0x20,
+ 0x20
+};
+
+// Character 16 (0x10)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// |*****|
+// | |
+// | |
+// | |
+// | |
+// | |
+// | |
+// | |
+// +-----+
+static const byte glyph16[] = {
+ 0xF8,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 17 (0x11)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | |
+// |*****|
+// | |
+// | |
+// | |
+// | |
+// | |
+// | |
+// +-----+
+static const byte glyph17[] = {
+ 0x00,
+ 0xF8,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 18 (0x12)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | |
+// | |
+// | |
+// |*****|
+// | |
+// | |
+// | |
+// | |
+// +-----+
+static const byte glyph18[] = {
+ 0x00,
+ 0x00,
+ 0x00,
+ 0xF8,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 19 (0x13)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | |
+// | |
+// | |
+// | |
+// | |
+// | |
+// |*****|
+// | |
+// +-----+
+static const byte glyph19[] = {
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0xF8,
+ 0x00
+};
+
+// Character 20 (0x14)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | |
+// | |
+// | |
+// | |
+// | |
+// | |
+// | |
+// |*****|
+// +-----+
+static const byte glyph20[] = {
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0xF8
+};
+
+// Character 21 (0x15)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | * |
+// | * |
+// | * |
+// | ***|
+// | * |
+// | * |
+// | * |
+// | * |
+// +-----+
+static const byte glyph21[] = {
+ 0x20,
+ 0x20,
+ 0x20,
+ 0x38,
+ 0x20,
+ 0x20,
+ 0x20,
+ 0x20
+};
+
+// Character 22 (0x16)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | * |
+// | * |
+// | * |
+// |*** |
+// | * |
+// | * |
+// | * |
+// | * |
+// +-----+
+static const byte glyph22[] = {
+ 0x20,
+ 0x20,
+ 0x20,
+ 0xE0,
+ 0x20,
+ 0x20,
+ 0x20,
+ 0x20
+};
+
+// Character 23 (0x17)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | * |
+// | * |
+// | * |
+// |*****|
+// | |
+// | |
+// | |
+// | |
+// +-----+
+static const byte glyph23[] = {
+ 0x20,
+ 0x20,
+ 0x20,
+ 0xF8,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 24 (0x18)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | |
+// | |
+// | |
+// |*****|
+// | * |
+// | * |
+// | * |
+// | * |
+// +-----+
+static const byte glyph24[] = {
+ 0x00,
+ 0x00,
+ 0x00,
+ 0xF8,
+ 0x20,
+ 0x20,
+ 0x20,
+ 0x20
+};
+
+// Character 25 (0x19)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | * |
+// | * |
+// | * |
+// | * |
+// | * |
+// | * |
+// | * |
+// | * |
+// +-----+
+static const byte glyph25[] = {
+ 0x20,
+ 0x20,
+ 0x20,
+ 0x20,
+ 0x20,
+ 0x20,
+ 0x20,
+ 0x20
+};
+
+// Character 26 (0x1A)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | |
+// | * |
+// | * |
+// | * |
+// | * |
+// | * |
+// | *** |
+// | |
+// +-----+
+static const byte glyph26[] = {
+ 0x00,
+ 0x10,
+ 0x20,
+ 0x40,
+ 0x20,
+ 0x10,
+ 0x70,
+ 0x00
+};
+
+// Character 27 (0x1B)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | |
+// | * |
+// | * |
+// | * |
+// | * |
+// | * |
+// | *** |
+// | |
+// +-----+
+static const byte glyph27[] = {
+ 0x00,
+ 0x40,
+ 0x20,
+ 0x10,
+ 0x20,
+ 0x40,
+ 0x70,
+ 0x00
+};
+
+// Character 28 (0x1C)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | |
+// | |
+// | |
+// |*****|
+// | * * |
+// | * * |
+// | * * |
+// | |
+// +-----+
+static const byte glyph28[] = {
+ 0x00,
+ 0x00,
+ 0x00,
+ 0xF8,
+ 0x50,
+ 0x50,
+ 0x50,
+ 0x00
+};
+
+// Character 29 (0x1D)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | |
+// | |
+// | * |
+// |**** |
+// | ** |
+// |**** |
+// | * |
+// | |
+// +-----+
+static const byte glyph29[] = {
+ 0x00,
+ 0x00,
+ 0x20,
+ 0xF0,
+ 0x60,
+ 0xF0,
+ 0x40,
+ 0x00
+};
+
+// Character 30 (0x1E)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | |
+// | * |
+// | * * |
+// |*** |
+// | * |
+// | * * |
+// |* * |
+// | |
+// +-----+
+static const byte glyph30[] = {
+ 0x00,
+ 0x20,
+ 0x50,
+ 0xE0,
+ 0x40,
+ 0x50,
+ 0xA0,
+ 0x00
+};
+
+// Character 31 (0x1F)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | |
+// | |
+// | |
+// | |
+// | * |
+// | |
+// | |
+// | |
+// +-----+
+static const byte glyph31[] = {
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x20,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 32 (0x20)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | |
+// | |
+// | |
+// | |
+// | |
+// | |
+// | |
+// | |
+// +-----+
+static const byte glyph32[] = {
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 33 (0x21)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | |
+// | * |
+// | * |
+// | * |
+// | * |
+// | |
+// | * |
+// | |
+// +-----+
+static const byte glyph33[] = {
+ 0x00,
+ 0x20,
+ 0x20,
+ 0x20,
+ 0x20,
+ 0x00,
+ 0x20,
+ 0x00
+};
+
+// Character 34 (0x22)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | |
+// | * * |
+// | * * |
+// | * * |
+// | |
+// | |
+// | |
+// | |
+// +-----+
+static const byte glyph34[] = {
+ 0x00,
+ 0x50,
+ 0x50,
+ 0x50,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 35 (0x23)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | * * |
+// | * * |
+// |*****|
+// | * * |
+// |*****|
+// | * * |
+// | * * |
+// | |
+// +-----+
+static const byte glyph35[] = {
+ 0x50,
+ 0x50,
+ 0xF8,
+ 0x50,
+ 0xF8,
+ 0x50,
+ 0x50,
+ 0x00
+};
+
+// Character 36 (0x24)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | * |
+// | *** |
+// |* * |
+// | *** |
+// | * *|
+// | *** |
+// | * |
+// | |
+// +-----+
+static const byte glyph36[] = {
+ 0x20,
+ 0x70,
+ 0xA0,
+ 0x70,
+ 0x28,
+ 0x70,
+ 0x20,
+ 0x00
+};
+
+// Character 37 (0x25)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | |
+// | * |
+// | * * |
+// | * |
+// | * * |
+// | * |
+// | |
+// | |
+// +-----+
+static const byte glyph37[] = {
+ 0x00,
+ 0x40,
+ 0x50,
+ 0x20,
+ 0x50,
+ 0x10,
+ 0x00,
+ 0x00
+};
+
+// Character 38 (0x26)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | * |
+// |* * |
+// |* * |
+// | * |
+// |* * |
+// |* * |
+// | * * |
+// | |
+// +-----+
+static const byte glyph38[] = {
+ 0x40,
+ 0xA0,
+ 0xA0,
+ 0x40,
+ 0xA0,
+ 0xA0,
+ 0x50,
+ 0x00
+};
+
+// Character 39 (0x27)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | |
+// | * |
+// | * |
+// | * |
+// | |
+// | |
+// | |
+// | |
+// +-----+
+static const byte glyph39[] = {
+ 0x00,
+ 0x20,
+ 0x20,
+ 0x20,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 40 (0x28)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | |
+// | * |
+// | * |
+// | * |
+// | * |
+// | * |
+// | * |
+// | |
+// +-----+
+static const byte glyph40[] = {
+ 0x00,
+ 0x20,
+ 0x40,
+ 0x40,
+ 0x40,
+ 0x40,
+ 0x20,
+ 0x00
+};
+
+// Character 41 (0x29)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | |
+// | * |
+// | * |
+// | * |
+// | * |
+// | * |
+// | * |
+// | |
+// +-----+
+static const byte glyph41[] = {
+ 0x00,
+ 0x40,
+ 0x20,
+ 0x20,
+ 0x20,
+ 0x20,
+ 0x40,
+ 0x00
+};
+
+// Character 42 (0x2A)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | |
+// | |
+// |* * |
+// | ** |
+// |**** |
+// | ** |
+// |* * |
+// | |
+// +-----+
+static const byte glyph42[] = {
+ 0x00,
+ 0x00,
+ 0x90,
+ 0x60,
+ 0xF0,
+ 0x60,
+ 0x90,
+ 0x00
+};
+
+// Character 43 (0x2B)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | |
+// | |
+// | * |
+// | * |
+// |*****|
+// | * |
+// | * |
+// | |
+// +-----+
+static const byte glyph43[] = {
+ 0x00,
+ 0x00,
+ 0x20,
+ 0x20,
+ 0xF8,
+ 0x20,
+ 0x20,
+ 0x00
+};
+
+// Character 44 (0x2C)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | |
+// | |
+// | |
+// | |
+// | |
+// | ** |
+// | * |
+// | * |
+// +-----+
+static const byte glyph44[] = {
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x30,
+ 0x20,
+ 0x40
+};
+
+// Character 45 (0x2D)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | |
+// | |
+// | |
+// | |
+// |**** |
+// | |
+// | |
+// | |
+// +-----+
+static const byte glyph45[] = {
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0xF0,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 46 (0x2E)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | |
+// | |
+// | |
+// | |
+// | |
+// | * |
+// | *** |
+// | * |
+// +-----+
+static const byte glyph46[] = {
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x20,
+ 0x70,
+ 0x20
+};
+
+// Character 47 (0x2F)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | |
+// | * |
+// | * |
+// | * |
+// | * |
+// |* |
+// |* |
+// | |
+// +-----+
+static const byte glyph47[] = {
+ 0x00,
+ 0x10,
+ 0x10,
+ 0x20,
+ 0x40,
+ 0x80,
+ 0x80,
+ 0x00
+};
+
+// Character 48 (0x30)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | |
+// | * |
+// | * * |
+// | * * |
+// | * * |
+// | * * |
+// | * |
+// | |
+// +-----+
+static const byte glyph48[] = {
+ 0x00,
+ 0x20,
+ 0x50,
+ 0x50,
+ 0x50,
+ 0x50,
+ 0x20,
+ 0x00
+};
+
+// Character 49 (0x31)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | |
+// | * |
+// | ** |
+// | * |
+// | * |
+// | * |
+// | *** |
+// | |
+// +-----+
+static const byte glyph49[] = {
+ 0x00,
+ 0x20,
+ 0x60,
+ 0x20,
+ 0x20,
+ 0x20,
+ 0x70,
+ 0x00
+};
+
+// Character 50 (0x32)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | |
+// | ** |
+// |* * |
+// | * |
+// | ** |
+// |* |
+// |**** |
+// | |
+// +-----+
+static const byte glyph50[] = {
+ 0x00,
+ 0x60,
+ 0x90,
+ 0x10,
+ 0x60,
+ 0x80,
+ 0xF0,
+ 0x00
+};
+
+// Character 51 (0x33)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | |
+// |**** |
+// | * |
+// | ** |
+// | * |
+// |* * |
+// | ** |
+// | |
+// +-----+
+static const byte glyph51[] = {
+ 0x00,
+ 0xF0,
+ 0x20,
+ 0x60,
+ 0x10,
+ 0x90,
+ 0x60,
+ 0x00
+};
+
+// Character 52 (0x34)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | |
+// | * |
+// | ** |
+// |* * |
+// |**** |
+// | * |
+// | * |
+// | |
+// +-----+
+static const byte glyph52[] = {
+ 0x00,
+ 0x20,
+ 0x60,
+ 0xA0,
+ 0xF0,
+ 0x20,
+ 0x20,
+ 0x00
+};
+
+// Character 53 (0x35)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | |
+// |**** |
+// |* |
+// |*** |
+// | * |
+// |* * |
+// | ** |
+// | |
+// +-----+
+static const byte glyph53[] = {
+ 0x00,
+ 0xF0,
+ 0x80,
+ 0xE0,
+ 0x10,
+ 0x90,
+ 0x60,
+ 0x00
+};
+
+// Character 54 (0x36)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | |
+// | ** |
+// |* |
+// |*** |
+// |* * |
+// |* * |
+// | ** |
+// | |
+// +-----+
+static const byte glyph54[] = {
+ 0x00,
+ 0x60,
+ 0x80,
+ 0xE0,
+ 0x90,
+ 0x90,
+ 0x60,
+ 0x00
+};
+
+// Character 55 (0x37)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | |
+// |**** |
+// | * |
+// | * |
+// | * |
+// | * |
+// | * |
+// | |
+// +-----+
+static const byte glyph55[] = {
+ 0x00,
+ 0xF0,
+ 0x10,
+ 0x20,
+ 0x20,
+ 0x40,
+ 0x40,
+ 0x00
+};
+
+// Character 56 (0x38)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | |
+// | ** |
+// |* * |
+// | ** |
+// |* * |
+// |* * |
+// | ** |
+// | |
+// +-----+
+static const byte glyph56[] = {
+ 0x00,
+ 0x60,
+ 0x90,
+ 0x60,
+ 0x90,
+ 0x90,
+ 0x60,
+ 0x00
+};
+
+// Character 57 (0x39)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | |
+// | ** |
+// |* * |
+// |* * |
+// | *** |
+// | * |
+// | ** |
+// | |
+// +-----+
+static const byte glyph57[] = {
+ 0x00,
+ 0x60,
+ 0x90,
+ 0x90,
+ 0x70,
+ 0x10,
+ 0x60,
+ 0x00
+};
+
+// Character 58 (0x3A)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | |
+// | |
+// | ** |
+// | ** |
+// | |
+// | ** |
+// | ** |
+// | |
+// +-----+
+static const byte glyph58[] = {
+ 0x00,
+ 0x00,
+ 0x60,
+ 0x60,
+ 0x00,
+ 0x60,
+ 0x60,
+ 0x00
+};
+
+// Character 59 (0x3B)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | |
+// | |
+// | ** |
+// | ** |
+// | |
+// | ** |
+// | * |
+// | * |
+// +-----+
+static const byte glyph59[] = {
+ 0x00,
+ 0x00,
+ 0x30,
+ 0x30,
+ 0x00,
+ 0x30,
+ 0x20,
+ 0x40
+};
+
+// Character 60 (0x3C)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | |
+// | * |
+// | * |
+// | * |
+// | * |
+// | * |
+// | * |
+// | |
+// +-----+
+static const byte glyph60[] = {
+ 0x00,
+ 0x10,
+ 0x20,
+ 0x40,
+ 0x40,
+ 0x20,
+ 0x10,
+ 0x00
+};
+
+// Character 61 (0x3D)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | |
+// | |
+// | |
+// |**** |
+// | |
+// |**** |
+// | |
+// | |
+// +-----+
+static const byte glyph61[] = {
+ 0x00,
+ 0x00,
+ 0x00,
+ 0xF0,
+ 0x00,
+ 0xF0,
+ 0x00,
+ 0x00
+};
+
+// Character 62 (0x3E)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | |
+// | * |
+// | * |
+// | * |
+// | * |
+// | * |
+// | * |
+// | |
+// +-----+
+static const byte glyph62[] = {
+ 0x00,
+ 0x40,
+ 0x20,
+ 0x10,
+ 0x10,
+ 0x20,
+ 0x40,
+ 0x00
+};
+
+// Character 63 (0x3F)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | |
+// | * |
+// | * * |
+// | * |
+// | * |
+// | |
+// | * |
+// | |
+// +-----+
+static const byte glyph63[] = {
+ 0x00,
+ 0x20,
+ 0x50,
+ 0x10,
+ 0x20,
+ 0x00,
+ 0x20,
+ 0x00
+};
+
+// Character 64 (0x40)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | ** |
+// | * *|
+// |* **|
+// |* * *|
+// |* * *|
+// |* * |
+// | * |
+// | ** |
+// +-----+
+static const byte glyph64[] = {
+ 0x30,
+ 0x48,
+ 0x98,
+ 0xA8,
+ 0xA8,
+ 0x90,
+ 0x40,
+ 0x30
+};
+
+// Character 65 (0x41)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | |
+// | ** |
+// |* * |
+// |* * |
+// |**** |
+// |* * |
+// |* * |
+// | |
+// +-----+
+static const byte glyph65[] = {
+ 0x00,
+ 0x60,
+ 0x90,
+ 0x90,
+ 0xF0,
+ 0x90,
+ 0x90,
+ 0x00
+};
+
+// Character 66 (0x42)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | |
+// |*** |
+// |* * |
+// |*** |
+// |* * |
+// |* * |
+// |*** |
+// | |
+// +-----+
+static const byte glyph66[] = {
+ 0x00,
+ 0xE0,
+ 0x90,
+ 0xE0,
+ 0x90,
+ 0x90,
+ 0xE0,
+ 0x00
+};
+
+// Character 67 (0x43)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | |
+// | ** |
+// |* * |
+// |* |
+// |* |
+// |* * |
+// | ** |
+// | |
+// +-----+
+static const byte glyph67[] = {
+ 0x00,
+ 0x60,
+ 0x90,
+ 0x80,
+ 0x80,
+ 0x90,
+ 0x60,
+ 0x00
+};
+
+// Character 68 (0x44)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | |
+// |*** |
+// |* * |
+// |* * |
+// |* * |
+// |* * |
+// |*** |
+// | |
+// +-----+
+static const byte glyph68[] = {
+ 0x00,
+ 0xE0,
+ 0x90,
+ 0x90,
+ 0x90,
+ 0x90,
+ 0xE0,
+ 0x00
+};
+
+// Character 69 (0x45)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | |
+// |**** |
+// |* |
+// |*** |
+// |* |
+// |* |
+// |**** |
+// | |
+// +-----+
+static const byte glyph69[] = {
+ 0x00,
+ 0xF0,
+ 0x80,
+ 0xE0,
+ 0x80,
+ 0x80,
+ 0xF0,
+ 0x00
+};
+
+// Character 70 (0x46)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | |
+// |**** |
+// |* |
+// |*** |
+// |* |
+// |* |
+// |* |
+// | |
+// +-----+
+static const byte glyph70[] = {
+ 0x00,
+ 0xF0,
+ 0x80,
+ 0xE0,
+ 0x80,
+ 0x80,
+ 0x80,
+ 0x00
+};
+
+// Character 71 (0x47)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | |
+// | ** |
+// |* * |
+// |* |
+// |* ** |
+// |* * |
+// | ** |
+// | |
+// +-----+
+static const byte glyph71[] = {
+ 0x00,
+ 0x60,
+ 0x90,
+ 0x80,
+ 0xB0,
+ 0x90,
+ 0x60,
+ 0x00
+};
+
+// Character 72 (0x48)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | |
+// |* * |
+// |* * |
+// |**** |
+// |* * |
+// |* * |
+// |* * |
+// | |
+// +-----+
+static const byte glyph72[] = {
+ 0x00,
+ 0x90,
+ 0x90,
+ 0xF0,
+ 0x90,
+ 0x90,
+ 0x90,
+ 0x00
+};
+
+// Character 73 (0x49)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | |
+// | *** |
+// | * |
+// | * |
+// | * |
+// | * |
+// | *** |
+// | |
+// +-----+
+static const byte glyph73[] = {
+ 0x00,
+ 0x70,
+ 0x20,
+ 0x20,
+ 0x20,
+ 0x20,
+ 0x70,
+ 0x00
+};
+
+// Character 74 (0x4A)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | |
+// | *** |
+// | * |
+// | * |
+// | * |
+// |* * |
+// | * |
+// | |
+// +-----+
+static const byte glyph74[] = {
+ 0x00,
+ 0x70,
+ 0x20,
+ 0x20,
+ 0x20,
+ 0xA0,
+ 0x40,
+ 0x00
+};
+
+// Character 75 (0x4B)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | |
+// |* * |
+// |* * |
+// |** |
+// |* * |
+// |* * |
+// |* * |
+// | |
+// +-----+
+static const byte glyph75[] = {
+ 0x00,
+ 0x90,
+ 0xA0,
+ 0xC0,
+ 0xA0,
+ 0xA0,
+ 0x90,
+ 0x00
+};
+
+// Character 76 (0x4C)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | |
+// |* |
+// |* |
+// |* |
+// |* |
+// |* |
+// |**** |
+// | |
+// +-----+
+static const byte glyph76[] = {
+ 0x00,
+ 0x80,
+ 0x80,
+ 0x80,
+ 0x80,
+ 0x80,
+ 0xF0,
+ 0x00
+};
+
+// Character 77 (0x4D)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | |
+// |* * |
+// |**** |
+// |**** |
+// |* * |
+// |* * |
+// |* * |
+// | |
+// +-----+
+static const byte glyph77[] = {
+ 0x00,
+ 0x90,
+ 0xF0,
+ 0xF0,
+ 0x90,
+ 0x90,
+ 0x90,
+ 0x00
+};
+
+// Character 78 (0x4E)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | |
+// |* * |
+// |** * |
+// |**** |
+// |* ** |
+// |* ** |
+// |* * |
+// | |
+// +-----+
+static const byte glyph78[] = {
+ 0x00,
+ 0x90,
+ 0xD0,
+ 0xF0,
+ 0xB0,
+ 0xB0,
+ 0x90,
+ 0x00
+};
+
+// Character 79 (0x4F)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | |
+// | ** |
+// |* * |
+// |* * |
+// |* * |
+// |* * |
+// | ** |
+// | |
+// +-----+
+static const byte glyph79[] = {
+ 0x00,
+ 0x60,
+ 0x90,
+ 0x90,
+ 0x90,
+ 0x90,
+ 0x60,
+ 0x00
+};
+
+// Character 80 (0x50)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | |
+// |*** |
+// |* * |
+// |* * |
+// |*** |
+// |* |
+// |* |
+// | |
+// +-----+
+static const byte glyph80[] = {
+ 0x00,
+ 0xE0,
+ 0x90,
+ 0x90,
+ 0xE0,
+ 0x80,
+ 0x80,
+ 0x00
+};
+
+// Character 81 (0x51)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | |
+// | ** |
+// |* * |
+// |* * |
+// |** * |
+// |* ** |
+// | ** |
+// | * |
+// +-----+
+static const byte glyph81[] = {
+ 0x00,
+ 0x60,
+ 0x90,
+ 0x90,
+ 0xD0,
+ 0xB0,
+ 0x60,
+ 0x10
+};
+
+// Character 82 (0x52)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | |
+// |*** |
+// |* * |
+// |* * |
+// |*** |
+// |* * |
+// |* * |
+// | |
+// +-----+
+static const byte glyph82[] = {
+ 0x00,
+ 0xE0,
+ 0x90,
+ 0x90,
+ 0xE0,
+ 0x90,
+ 0x90,
+ 0x00
+};
+
+// Character 83 (0x53)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | |
+// | ** |
+// |* * |
+// | * |
+// | * |
+// |* * |
+// | ** |
+// | |
+// +-----+
+static const byte glyph83[] = {
+ 0x00,
+ 0x60,
+ 0x90,
+ 0x40,
+ 0x20,
+ 0x90,
+ 0x60,
+ 0x00
+};
+
+// Character 84 (0x54)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | |
+// | *** |
+// | * |
+// | * |
+// | * |
+// | * |
+// | * |
+// | |
+// +-----+
+static const byte glyph84[] = {
+ 0x00,
+ 0x70,
+ 0x20,
+ 0x20,
+ 0x20,
+ 0x20,
+ 0x20,
+ 0x00
+};
+
+// Character 85 (0x55)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | |
+// |* * |
+// |* * |
+// |* * |
+// |* * |
+// |* * |
+// | ** |
+// | |
+// +-----+
+static const byte glyph85[] = {
+ 0x00,
+ 0x90,
+ 0x90,
+ 0x90,
+ 0x90,
+ 0x90,
+ 0x60,
+ 0x00
+};
+
+// Character 86 (0x56)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | |
+// |* * |
+// |* * |
+// |* * |
+// |* * |
+// | ** |
+// | ** |
+// | |
+// +-----+
+static const byte glyph86[] = {
+ 0x00,
+ 0x90,
+ 0x90,
+ 0x90,
+ 0x90,
+ 0x60,
+ 0x60,
+ 0x00
+};
+
+// Character 87 (0x57)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | |
+// |* * |
+// |* * |
+// |* * |
+// |**** |
+// |**** |
+// |* * |
+// | |
+// +-----+
+static const byte glyph87[] = {
+ 0x00,
+ 0x90,
+ 0x90,
+ 0x90,
+ 0xF0,
+ 0xF0,
+ 0x90,
+ 0x00
+};
+
+// Character 88 (0x58)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | |
+// |* * |
+// |* * |
+// | ** |
+// | ** |
+// |* * |
+// |* * |
+// | |
+// +-----+
+static const byte glyph88[] = {
+ 0x00,
+ 0x90,
+ 0x90,
+ 0x60,
+ 0x60,
+ 0x90,
+ 0x90,
+ 0x00
+};
+
+// Character 89 (0x59)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | |
+// |* *|
+// |* *|
+// | * * |
+// | * |
+// | * |
+// | * |
+// | |
+// +-----+
+static const byte glyph89[] = {
+ 0x00,
+ 0x88,
+ 0x88,
+ 0x50,
+ 0x20,
+ 0x20,
+ 0x20,
+ 0x00
+};
+
+// Character 90 (0x5A)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | |
+// |**** |
+// | * |
+// | * |
+// | * |
+// |* |
+// |**** |
+// | |
+// +-----+
+static const byte glyph90[] = {
+ 0x00,
+ 0xF0,
+ 0x10,
+ 0x20,
+ 0x40,
+ 0x80,
+ 0xF0,
+ 0x00
+};
+
+// Character 91 (0x5B)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | |
+// | *** |
+// | * |
+// | * |
+// | * |
+// | * |
+// | *** |
+// | |
+// +-----+
+static const byte glyph91[] = {
+ 0x00,
+ 0x70,
+ 0x40,
+ 0x40,
+ 0x40,
+ 0x40,
+ 0x70,
+ 0x00
+};
+
+// Character 92 (0x5C)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | |
+// |* |
+// |* |
+// | * |
+// | * |
+// | * |
+// | * |
+// | |
+// +-----+
+static const byte glyph92[] = {
+ 0x00,
+ 0x80,
+ 0x80,
+ 0x40,
+ 0x20,
+ 0x10,
+ 0x10,
+ 0x00
+};
+
+// Character 93 (0x5D)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | |
+// | *** |
+// | * |
+// | * |
+// | * |
+// | * |
+// | *** |
+// | |
+// +-----+
+static const byte glyph93[] = {
+ 0x00,
+ 0x70,
+ 0x10,
+ 0x10,
+ 0x10,
+ 0x10,
+ 0x70,
+ 0x00
+};
+
+// Character 94 (0x5E)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | |
+// | * |
+// | * * |
+// | |
+// | |
+// | |
+// | |
+// | |
+// +-----+
+static const byte glyph94[] = {
+ 0x00,
+ 0x20,
+ 0x50,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 95 (0x5F)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | |
+// | |
+// | |
+// | |
+// | |
+// | |
+// | |
+// |**** |
+// +-----+
+static const byte glyph95[] = {
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0xF0
+};
+
+// Character 96 (0x60)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | |
+// | * |
+// | * |
+// | |
+// | |
+// | |
+// | |
+// | |
+// +-----+
+static const byte glyph96[] = {
+ 0x00,
+ 0x40,
+ 0x20,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 97 (0x61)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | |
+// | |
+// | |
+// | *** |
+// |* * |
+// |* * |
+// | *** |
+// | |
+// +-----+
+static const byte glyph97[] = {
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x70,
+ 0x90,
+ 0x90,
+ 0x70,
+ 0x00
+};
+
+// Character 98 (0x62)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | |
+// |* |
+// |* |
+// |*** |
+// |* * |
+// |* * |
+// |*** |
+// | |
+// +-----+
+static const byte glyph98[] = {
+ 0x00,
+ 0x80,
+ 0x80,
+ 0xE0,
+ 0x90,
+ 0x90,
+ 0xE0,
+ 0x00
+};
+
+// Character 99 (0x63)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | |
+// | |
+// | |
+// | ** |
+// | * |
+// | * |
+// | ** |
+// | |
+// +-----+
+static const byte glyph99[] = {
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x30,
+ 0x40,
+ 0x40,
+ 0x30,
+ 0x00
+};
+
+// Character 100 (0x64)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | |
+// | * |
+// | * |
+// | *** |
+// |* * |
+// |* * |
+// | *** |
+// | |
+// +-----+
+static const byte glyph100[] = {
+ 0x00,
+ 0x10,
+ 0x10,
+ 0x70,
+ 0x90,
+ 0x90,
+ 0x70,
+ 0x00
+};
+
+// Character 101 (0x65)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | |
+// | |
+// | |
+// | ** |
+// |* ** |
+// |** |
+// | ** |
+// | |
+// +-----+
+static const byte glyph101[] = {
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x60,
+ 0xB0,
+ 0xC0,
+ 0x60,
+ 0x00
+};
+
+// Character 102 (0x66)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | |
+// | * |
+// | * * |
+// | * |
+// |*** |
+// | * |
+// | * |
+// | |
+// +-----+
+static const byte glyph102[] = {
+ 0x00,
+ 0x20,
+ 0x50,
+ 0x40,
+ 0xE0,
+ 0x40,
+ 0x40,
+ 0x00
+};
+
+// Character 103 (0x67)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | |
+// | |
+// | |
+// | ** |
+// |* * |
+// | *** |
+// | * |
+// | ** |
+// +-----+
+static const byte glyph103[] = {
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x60,
+ 0x90,
+ 0x70,
+ 0x10,
+ 0x60
+};
+
+// Character 104 (0x68)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | |
+// |* |
+// |* |
+// |*** |
+// |* * |
+// |* * |
+// |* * |
+// | |
+// +-----+
+static const byte glyph104[] = {
+ 0x00,
+ 0x80,
+ 0x80,
+ 0xE0,
+ 0x90,
+ 0x90,
+ 0x90,
+ 0x00
+};
+
+// Character 105 (0x69)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | |
+// | * |
+// | |
+// | ** |
+// | * |
+// | * |
+// | *** |
+// | |
+// +-----+
+static const byte glyph105[] = {
+ 0x00,
+ 0x20,
+ 0x00,
+ 0x60,
+ 0x20,
+ 0x20,
+ 0x70,
+ 0x00
+};
+
+// Character 106 (0x6A)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | |
+// | * |
+// | |
+// | * |
+// | * |
+// | * |
+// | * * |
+// | * |
+// +-----+
+static const byte glyph106[] = {
+ 0x00,
+ 0x10,
+ 0x00,
+ 0x10,
+ 0x10,
+ 0x10,
+ 0x50,
+ 0x20
+};
+
+// Character 107 (0x6B)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | |
+// |* |
+// |* |
+// |* * |
+// |*** |
+// |* * |
+// |* * |
+// | |
+// +-----+
+static const byte glyph107[] = {
+ 0x00,
+ 0x80,
+ 0x80,
+ 0x90,
+ 0xE0,
+ 0x90,
+ 0x90,
+ 0x00
+};
+
+// Character 108 (0x6C)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | |
+// | ** |
+// | * |
+// | * |
+// | * |
+// | * |
+// | *** |
+// | |
+// +-----+
+static const byte glyph108[] = {
+ 0x00,
+ 0x60,
+ 0x20,
+ 0x20,
+ 0x20,
+ 0x20,
+ 0x70,
+ 0x00
+};
+
+// Character 109 (0x6D)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | |
+// | |
+// | |
+// |** * |
+// |* * *|
+// |* * *|
+// |* * *|
+// | |
+// +-----+
+static const byte glyph109[] = {
+ 0x00,
+ 0x00,
+ 0x00,
+ 0xD0,
+ 0xA8,
+ 0xA8,
+ 0xA8,
+ 0x00
+};
+
+// Character 110 (0x6E)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | |
+// | |
+// | |
+// |*** |
+// |* * |
+// |* * |
+// |* * |
+// | |
+// +-----+
+static const byte glyph110[] = {
+ 0x00,
+ 0x00,
+ 0x00,
+ 0xE0,
+ 0x90,
+ 0x90,
+ 0x90,
+ 0x00
+};
+
+// Character 111 (0x6F)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | |
+// | |
+// | |
+// | ** |
+// |* * |
+// |* * |
+// | ** |
+// | |
+// +-----+
+static const byte glyph111[] = {
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x60,
+ 0x90,
+ 0x90,
+ 0x60,
+ 0x00
+};
+
+// Character 112 (0x70)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | |
+// | |
+// | |
+// |*** |
+// |* * |
+// |*** |
+// |* |
+// |* |
+// +-----+
+static const byte glyph112[] = {
+ 0x00,
+ 0x00,
+ 0x00,
+ 0xE0,
+ 0x90,
+ 0xE0,
+ 0x80,
+ 0x80
+};
+
+// Character 113 (0x71)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | |
+// | |
+// | |
+// | *** |
+// |* * |
+// | *** |
+// | * |
+// | * |
+// +-----+
+static const byte glyph113[] = {
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x70,
+ 0x90,
+ 0x70,
+ 0x10,
+ 0x10
+};
+
+// Character 114 (0x72)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | |
+// | |
+// | |
+// |* * |
+// |** * |
+// |* |
+// |* |
+// | |
+// +-----+
+static const byte glyph114[] = {
+ 0x00,
+ 0x00,
+ 0x00,
+ 0xA0,
+ 0xD0,
+ 0x80,
+ 0x80,
+ 0x00
+};
+
+// Character 115 (0x73)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | |
+// | |
+// | |
+// | ** |
+// | ** |
+// | * |
+// | ** |
+// | |
+// +-----+
+static const byte glyph115[] = {
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x30,
+ 0x60,
+ 0x10,
+ 0x60,
+ 0x00
+};
+
+// Character 116 (0x74)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | |
+// | * |
+// | * |
+// |*** |
+// | * |
+// | * * |
+// | * |
+// | |
+// +-----+
+static const byte glyph116[] = {
+ 0x00,
+ 0x40,
+ 0x40,
+ 0xE0,
+ 0x40,
+ 0x50,
+ 0x20,
+ 0x00
+};
+
+// Character 117 (0x75)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | |
+// | |
+// | |
+// |* * |
+// |* * |
+// |* * |
+// | *** |
+// | |
+// +-----+
+static const byte glyph117[] = {
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x90,
+ 0x90,
+ 0x90,
+ 0x70,
+ 0x00
+};
+
+// Character 118 (0x76)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | |
+// | |
+// | |
+// | * * |
+// | * * |
+// | * * |
+// | * |
+// | |
+// +-----+
+static const byte glyph118[] = {
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x50,
+ 0x50,
+ 0x50,
+ 0x20,
+ 0x00
+};
+
+// Character 119 (0x77)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | |
+// | |
+// | |
+// |* *|
+// |* * *|
+// |* * *|
+// | * * |
+// | |
+// +-----+
+static const byte glyph119[] = {
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x88,
+ 0xA8,
+ 0xA8,
+ 0x50,
+ 0x00
+};
+
+// Character 120 (0x78)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | |
+// | |
+// | |
+// |* * |
+// | ** |
+// | ** |
+// |* * |
+// | |
+// +-----+
+static const byte glyph120[] = {
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x90,
+ 0x60,
+ 0x60,
+ 0x90,
+ 0x00
+};
+
+// Character 121 (0x79)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | |
+// | |
+// | |
+// |* * |
+// |* * |
+// | *** |
+// |* * |
+// | ** |
+// +-----+
+static const byte glyph121[] = {
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x90,
+ 0x90,
+ 0x70,
+ 0x90,
+ 0x60
+};
+
+// Character 122 (0x7A)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | |
+// | |
+// | |
+// |**** |
+// | * |
+// | * |
+// |**** |
+// | |
+// +-----+
+static const byte glyph122[] = {
+ 0x00,
+ 0x00,
+ 0x00,
+ 0xF0,
+ 0x20,
+ 0x40,
+ 0xF0,
+ 0x00
+};
+
+// Character 123 (0x7B)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | ** |
+// | * |
+// | * |
+// |** |
+// | * |
+// | * |
+// | ** |
+// | |
+// +-----+
+static const byte glyph123[] = {
+ 0x30,
+ 0x40,
+ 0x20,
+ 0xC0,
+ 0x20,
+ 0x40,
+ 0x30,
+ 0x00
+};
+
+// Character 124 (0x7C)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | |
+// | * |
+// | * |
+// | * |
+// | * |
+// | * |
+// | * |
+// | |
+// +-----+
+static const byte glyph124[] = {
+ 0x00,
+ 0x20,
+ 0x20,
+ 0x20,
+ 0x20,
+ 0x20,
+ 0x20,
+ 0x00
+};
+
+// Character 125 (0x7D)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// |** |
+// | * |
+// | * |
+// | ** |
+// | * |
+// | * |
+// |** |
+// | |
+// +-----+
+static const byte glyph125[] = {
+ 0xC0,
+ 0x20,
+ 0x40,
+ 0x30,
+ 0x40,
+ 0x20,
+ 0xC0,
+ 0x00
+};
+
+// Character 126 (0x7E)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | |
+// | * * |
+// |* * |
+// | |
+// | |
+// | |
+// | |
+// | |
+// +-----+
+static const byte glyph126[] = {
+ 0x00,
+ 0x50,
+ 0xA0,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 160 (0xA0)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | |
+// | |
+// | |
+// | |
+// | |
+// | |
+// | |
+// | |
+// +-----+
+static const byte glyph160[] = {
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 161 (0xA1)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | |
+// | * |
+// | |
+// | * |
+// | * |
+// | * |
+// | * |
+// | |
+// +-----+
+static const byte glyph161[] = {
+ 0x00,
+ 0x20,
+ 0x00,
+ 0x20,
+ 0x20,
+ 0x20,
+ 0x20,
+ 0x00
+};
+
+// Character 162 (0xA2)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | |
+// | |
+// | * |
+// | *** |
+// |* * |
+// |* * |
+// | *** |
+// | * |
+// +-----+
+static const byte glyph162[] = {
+ 0x00,
+ 0x00,
+ 0x20,
+ 0x70,
+ 0xA0,
+ 0xA0,
+ 0x70,
+ 0x20
+};
+
+// Character 163 (0xA3)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | |
+// | * |
+// | * * |
+// |*** |
+// | * |
+// | * * |
+// |* * |
+// | |
+// +-----+
+static const byte glyph163[] = {
+ 0x00,
+ 0x20,
+ 0x50,
+ 0xE0,
+ 0x40,
+ 0x50,
+ 0xA0,
+ 0x00
+};
+
+// Character 164 (0xA4)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | |
+// | |
+// |* *|
+// | *** |
+// | * * |
+// | *** |
+// |* *|
+// | |
+// +-----+
+static const byte glyph164[] = {
+ 0x00,
+ 0x00,
+ 0x88,
+ 0x70,
+ 0x50,
+ 0x70,
+ 0x88,
+ 0x00
+};
+
+// Character 165 (0xA5)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | |
+// |* *|
+// | * * |
+// |*****|
+// | * |
+// |*****|
+// | * |
+// | |
+// +-----+
+static const byte glyph165[] = {
+ 0x00,
+ 0x88,
+ 0x50,
+ 0xF8,
+ 0x20,
+ 0xF8,
+ 0x20,
+ 0x00
+};
+
+// Character 166 (0xA6)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | * |
+// | * |
+// | * |
+// | |
+// | * |
+// | * |
+// | * |
+// | |
+// +-----+
+static const byte glyph166[] = {
+ 0x20,
+ 0x20,
+ 0x20,
+ 0x00,
+ 0x20,
+ 0x20,
+ 0x20,
+ 0x00
+};
+
+// Character 167 (0xA7)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | *** |
+// |* |
+// |*** |
+// |* * |
+// | *** |
+// | * |
+// |*** |
+// | |
+// +-----+
+static const byte glyph167[] = {
+ 0x70,
+ 0x80,
+ 0xE0,
+ 0x90,
+ 0x70,
+ 0x10,
+ 0xE0,
+ 0x00
+};
+
+// Character 168 (0xA8)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | |
+// | * * |
+// | |
+// | |
+// | |
+// | |
+// | |
+// | |
+// +-----+
+static const byte glyph168[] = {
+ 0x00,
+ 0x50,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 169 (0xA9)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | |
+// | *** |
+// |* * *|
+// |** *|
+// |** *|
+// |* * *|
+// | *** |
+// | |
+// +-----+
+static const byte glyph169[] = {
+ 0x00,
+ 0x70,
+ 0xA8,
+ 0xC8,
+ 0xC8,
+ 0xA8,
+ 0x70,
+ 0x00
+};
+
+// Character 170 (0xAA)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | ** |
+// | * * |
+// | ** |
+// | |
+// | *** |
+// | |
+// | |
+// | |
+// +-----+
+static const byte glyph170[] = {
+ 0x30,
+ 0x50,
+ 0x30,
+ 0x00,
+ 0x70,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 171 (0xAB)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | |
+// | |
+// | |
+// | * * |
+// |* * |
+// | * * |
+// | |
+// | |
+// +-----+
+static const byte glyph171[] = {
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x50,
+ 0xA0,
+ 0x50,
+ 0x00,
+ 0x00
+};
+
+// Character 172 (0xAC)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | |
+// | |
+// | |
+// | |
+// | *** |
+// | * |
+// | * |
+// | |
+// +-----+
+static const byte glyph172[] = {
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x70,
+ 0x10,
+ 0x10,
+ 0x00
+};
+
+// Character 173 (0xAD)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | |
+// | |
+// | |
+// | |
+// | *** |
+// | |
+// | |
+// | |
+// +-----+
+static const byte glyph173[] = {
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x70,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 174 (0xAE)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | |
+// | *** |
+// |*** *|
+// |** **|
+// |*** *|
+// |** **|
+// | *** |
+// | |
+// +-----+
+static const byte glyph174[] = {
+ 0x00,
+ 0x70,
+ 0xE8,
+ 0xD8,
+ 0xE8,
+ 0xD8,
+ 0x70,
+ 0x00
+};
+
+// Character 175 (0xAF)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | |
+// | *** |
+// | |
+// | |
+// | |
+// | |
+// | |
+// | |
+// +-----+
+static const byte glyph175[] = {
+ 0x00,
+ 0x70,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 176 (0xB0)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | |
+// | * |
+// | * * |
+// | * |
+// | |
+// | |
+// | |
+// | |
+// +-----+
+static const byte glyph176[] = {
+ 0x00,
+ 0x20,
+ 0x50,
+ 0x20,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 177 (0xB1)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | |
+// | |
+// | * |
+// | *** |
+// | * |
+// | |
+// | *** |
+// | |
+// +-----+
+static const byte glyph177[] = {
+ 0x00,
+ 0x00,
+ 0x20,
+ 0x70,
+ 0x20,
+ 0x00,
+ 0x70,
+ 0x00
+};
+
+// Character 178 (0xB2)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | * |
+// | * * |
+// | * |
+// | * |
+// | *** |
+// | |
+// | |
+// | |
+// +-----+
+static const byte glyph178[] = {
+ 0x20,
+ 0x50,
+ 0x10,
+ 0x20,
+ 0x70,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 179 (0xB3)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | ** |
+// | * |
+// | ** |
+// | * |
+// | ** |
+// | |
+// | |
+// | |
+// +-----+
+static const byte glyph179[] = {
+ 0x60,
+ 0x10,
+ 0x60,
+ 0x10,
+ 0x60,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 180 (0xB4)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | |
+// | * |
+// | * |
+// | |
+// | |
+// | |
+// | |
+// | |
+// +-----+
+static const byte glyph180[] = {
+ 0x00,
+ 0x20,
+ 0x40,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 181 (0xB5)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | |
+// | |
+// | |
+// |* * |
+// |* * |
+// |* * |
+// |*** |
+// |* |
+// +-----+
+static const byte glyph181[] = {
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x90,
+ 0x90,
+ 0x90,
+ 0xE0,
+ 0x80
+};
+
+// Character 182 (0xB6)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | |
+// | ****|
+// |*** *|
+// |*** *|
+// | ** *|
+// | * *|
+// | * *|
+// | |
+// +-----+
+static const byte glyph182[] = {
+ 0x00,
+ 0x78,
+ 0xE8,
+ 0xE8,
+ 0x68,
+ 0x28,
+ 0x28,
+ 0x00
+};
+
+// Character 183 (0xB7)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | |
+// | |
+// | |
+// | |
+// | * |
+// | |
+// | |
+// | |
+// +-----+
+static const byte glyph183[] = {
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x20,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 184 (0xB8)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | |
+// | |
+// | |
+// | |
+// | |
+// | |
+// | * |
+// | * |
+// +-----+
+static const byte glyph184[] = {
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x20,
+ 0x40
+};
+
+// Character 185 (0xB9)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | * |
+// | ** |
+// | * |
+// | * |
+// | *** |
+// | |
+// | |
+// | |
+// +-----+
+static const byte glyph185[] = {
+ 0x20,
+ 0x60,
+ 0x20,
+ 0x20,
+ 0x70,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 186 (0xBA)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | * |
+// | * * |
+// | * |
+// | |
+// | *** |
+// | |
+// | |
+// | |
+// +-----+
+static const byte glyph186[] = {
+ 0x20,
+ 0x50,
+ 0x20,
+ 0x00,
+ 0x70,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 187 (0xBB)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | |
+// | |
+// | |
+// |* * |
+// | * * |
+// |* * |
+// | |
+// | |
+// +-----+
+static const byte glyph187[] = {
+ 0x00,
+ 0x00,
+ 0x00,
+ 0xA0,
+ 0x50,
+ 0xA0,
+ 0x00,
+ 0x00
+};
+
+// Character 188 (0xBC)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// |* |
+// |* |
+// |* |
+// |* * |
+// | ** |
+// |**** |
+// | * |
+// | |
+// +-----+
+static const byte glyph188[] = {
+ 0x80,
+ 0x80,
+ 0x80,
+ 0xA0,
+ 0x60,
+ 0xF0,
+ 0x20,
+ 0x00
+};
+
+// Character 189 (0xBD)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// |* |
+// |* |
+// |* * |
+// |** * |
+// | * |
+// | * |
+// | *** |
+// | |
+// +-----+
+static const byte glyph189[] = {
+ 0x80,
+ 0x80,
+ 0xA0,
+ 0xD0,
+ 0x10,
+ 0x20,
+ 0x70,
+ 0x00
+};
+
+// Character 190 (0xBE)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// |* |
+// | * |
+// |* |
+// | ** |
+// |* * |
+// |**** |
+// | * |
+// | |
+// +-----+
+static const byte glyph190[] = {
+ 0x80,
+ 0x40,
+ 0x80,
+ 0x60,
+ 0xA0,
+ 0xF0,
+ 0x20,
+ 0x00
+};
+
+// Character 191 (0xBF)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | |
+// | * |
+// | |
+// | * |
+// | * |
+// | * * |
+// | * |
+// | |
+// +-----+
+static const byte glyph191[] = {
+ 0x00,
+ 0x20,
+ 0x00,
+ 0x20,
+ 0x40,
+ 0x50,
+ 0x20,
+ 0x00
+};
+
+// Character 192 (0xC0)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | * |
+// | * |
+// | ** |
+// |* * |
+// |**** |
+// |* * |
+// |* * |
+// | |
+// +-----+
+static const byte glyph192[] = {
+ 0x40,
+ 0x20,
+ 0x60,
+ 0x90,
+ 0xF0,
+ 0x90,
+ 0x90,
+ 0x00
+};
+
+// Character 193 (0xC1)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | * |
+// | * |
+// | ** |
+// |* * |
+// |**** |
+// |* * |
+// |* * |
+// | |
+// +-----+
+static const byte glyph193[] = {
+ 0x20,
+ 0x40,
+ 0x60,
+ 0x90,
+ 0xF0,
+ 0x90,
+ 0x90,
+ 0x00
+};
+
+// Character 194 (0xC2)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | ** |
+// |* * |
+// | ** |
+// |* * |
+// |**** |
+// |* * |
+// |* * |
+// | |
+// +-----+
+static const byte glyph194[] = {
+ 0x60,
+ 0x90,
+ 0x60,
+ 0x90,
+ 0xF0,
+ 0x90,
+ 0x90,
+ 0x00
+};
+
+// Character 195 (0xC3)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | * * |
+// |* * |
+// | ** |
+// |* * |
+// |**** |
+// |* * |
+// |* * |
+// | |
+// +-----+
+static const byte glyph195[] = {
+ 0x50,
+ 0xA0,
+ 0x60,
+ 0x90,
+ 0xF0,
+ 0x90,
+ 0x90,
+ 0x00
+};
+
+// Character 196 (0xC4)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// |* * |
+// | |
+// | ** |
+// |* * |
+// |**** |
+// |* * |
+// |* * |
+// | |
+// +-----+
+static const byte glyph196[] = {
+ 0x90,
+ 0x00,
+ 0x60,
+ 0x90,
+ 0xF0,
+ 0x90,
+ 0x90,
+ 0x00
+};
+
+// Character 197 (0xC5)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | ** |
+// |* * |
+// | ** |
+// |* * |
+// |**** |
+// |* * |
+// |* * |
+// | |
+// +-----+
+static const byte glyph197[] = {
+ 0x60,
+ 0x90,
+ 0x60,
+ 0x90,
+ 0xF0,
+ 0x90,
+ 0x90,
+ 0x00
+};
+
+// Character 198 (0xC6)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | |
+// | *** |
+// |* * |
+// |* * |
+// |**** |
+// |* * |
+// |* ** |
+// | |
+// +-----+
+static const byte glyph198[] = {
+ 0x00,
+ 0x70,
+ 0xA0,
+ 0xA0,
+ 0xF0,
+ 0xA0,
+ 0xB0,
+ 0x00
+};
+
+// Character 199 (0xC7)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | |
+// | ** |
+// |* * |
+// |* |
+// |* |
+// |* * |
+// | ** |
+// | * |
+// +-----+
+static const byte glyph199[] = {
+ 0x00,
+ 0x60,
+ 0x90,
+ 0x80,
+ 0x80,
+ 0x90,
+ 0x60,
+ 0x40
+};
+
+// Character 200 (0xC8)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | * |
+// | * |
+// |**** |
+// |* |
+// |*** |
+// |* |
+// |**** |
+// | |
+// +-----+
+static const byte glyph200[] = {
+ 0x40,
+ 0x20,
+ 0xF0,
+ 0x80,
+ 0xE0,
+ 0x80,
+ 0xF0,
+ 0x00
+};
+
+// Character 201 (0xC9)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | * |
+// | * |
+// |**** |
+// |* |
+// |*** |
+// |* |
+// |**** |
+// | |
+// +-----+
+static const byte glyph201[] = {
+ 0x20,
+ 0x40,
+ 0xF0,
+ 0x80,
+ 0xE0,
+ 0x80,
+ 0xF0,
+ 0x00
+};
+
+// Character 202 (0xCA)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | ** |
+// |* * |
+// |**** |
+// |* |
+// |*** |
+// |* |
+// |**** |
+// | |
+// +-----+
+static const byte glyph202[] = {
+ 0x60,
+ 0x90,
+ 0xF0,
+ 0x80,
+ 0xE0,
+ 0x80,
+ 0xF0,
+ 0x00
+};
+
+// Character 203 (0xCB)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// |* * |
+// | |
+// |**** |
+// |* |
+// |*** |
+// |* |
+// |**** |
+// | |
+// +-----+
+static const byte glyph203[] = {
+ 0x90,
+ 0x00,
+ 0xF0,
+ 0x80,
+ 0xE0,
+ 0x80,
+ 0xF0,
+ 0x00
+};
+
+// Character 204 (0xCC)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | * |
+// | * |
+// | *** |
+// | * |
+// | * |
+// | * |
+// | *** |
+// | |
+// +-----+
+static const byte glyph204[] = {
+ 0x40,
+ 0x20,
+ 0x70,
+ 0x20,
+ 0x20,
+ 0x20,
+ 0x70,
+ 0x00
+};
+
+// Character 205 (0xCD)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | * |
+// | * |
+// | *** |
+// | * |
+// | * |
+// | * |
+// | *** |
+// | |
+// +-----+
+static const byte glyph205[] = {
+ 0x10,
+ 0x20,
+ 0x70,
+ 0x20,
+ 0x20,
+ 0x20,
+ 0x70,
+ 0x00
+};
+
+// Character 206 (0xCE)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | * |
+// | * * |
+// | *** |
+// | * |
+// | * |
+// | * |
+// | *** |
+// | |
+// +-----+
+static const byte glyph206[] = {
+ 0x20,
+ 0x50,
+ 0x70,
+ 0x20,
+ 0x20,
+ 0x20,
+ 0x70,
+ 0x00
+};
+
+// Character 207 (0xCF)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | * * |
+// | |
+// | *** |
+// | * |
+// | * |
+// | * |
+// | *** |
+// | |
+// +-----+
+static const byte glyph207[] = {
+ 0x50,
+ 0x00,
+ 0x70,
+ 0x20,
+ 0x20,
+ 0x20,
+ 0x70,
+ 0x00
+};
+
+// Character 208 (0xD0)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | |
+// | *** |
+// | * *|
+// |*** *|
+// | * *|
+// | * *|
+// | *** |
+// | |
+// +-----+
+static const byte glyph208[] = {
+ 0x00,
+ 0x70,
+ 0x48,
+ 0xE8,
+ 0x48,
+ 0x48,
+ 0x70,
+ 0x00
+};
+
+// Character 209 (0xD1)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | * * |
+// |* * |
+// |* * |
+// |** * |
+// |* ** |
+// |* * |
+// |* * |
+// | |
+// +-----+
+static const byte glyph209[] = {
+ 0x50,
+ 0xA0,
+ 0x90,
+ 0xD0,
+ 0xB0,
+ 0x90,
+ 0x90,
+ 0x00
+};
+
+// Character 210 (0xD2)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | * |
+// | * |
+// | ** |
+// |* * |
+// |* * |
+// |* * |
+// | ** |
+// | |
+// +-----+
+static const byte glyph210[] = {
+ 0x40,
+ 0x20,
+ 0x60,
+ 0x90,
+ 0x90,
+ 0x90,
+ 0x60,
+ 0x00
+};
+
+// Character 211 (0xD3)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | * |
+// | * |
+// | ** |
+// |* * |
+// |* * |
+// |* * |
+// | ** |
+// | |
+// +-----+
+static const byte glyph211[] = {
+ 0x20,
+ 0x40,
+ 0x60,
+ 0x90,
+ 0x90,
+ 0x90,
+ 0x60,
+ 0x00
+};
+
+// Character 212 (0xD4)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | ** |
+// |* * |
+// | ** |
+// |* * |
+// |* * |
+// |* * |
+// | ** |
+// | |
+// +-----+
+static const byte glyph212[] = {
+ 0x60,
+ 0x90,
+ 0x60,
+ 0x90,
+ 0x90,
+ 0x90,
+ 0x60,
+ 0x00
+};
+
+// Character 213 (0xD5)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | * * |
+// |* * |
+// | ** |
+// |* * |
+// |* * |
+// |* * |
+// | ** |
+// | |
+// +-----+
+static const byte glyph213[] = {
+ 0x50,
+ 0xA0,
+ 0x60,
+ 0x90,
+ 0x90,
+ 0x90,
+ 0x60,
+ 0x00
+};
+
+// Character 214 (0xD6)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// |* * |
+// | |
+// | ** |
+// |* * |
+// |* * |
+// |* * |
+// | ** |
+// | |
+// +-----+
+static const byte glyph214[] = {
+ 0x90,
+ 0x00,
+ 0x60,
+ 0x90,
+ 0x90,
+ 0x90,
+ 0x60,
+ 0x00
+};
+
+// Character 215 (0xD7)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | |
+// | |
+// | |
+// | |
+// | * * |
+// | * |
+// | * * |
+// | |
+// +-----+
+static const byte glyph215[] = {
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x50,
+ 0x20,
+ 0x50,
+ 0x00
+};
+
+// Character 216 (0xD8)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | |
+// | *** |
+// |* ** |
+// |* ** |
+// |** * |
+// |** * |
+// |*** |
+// | |
+// +-----+
+static const byte glyph216[] = {
+ 0x00,
+ 0x70,
+ 0xB0,
+ 0xB0,
+ 0xD0,
+ 0xD0,
+ 0xE0,
+ 0x00
+};
+
+// Character 217 (0xD9)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | * |
+// | * |
+// |* * |
+// |* * |
+// |* * |
+// |* * |
+// | ** |
+// | |
+// +-----+
+static const byte glyph217[] = {
+ 0x40,
+ 0x20,
+ 0x90,
+ 0x90,
+ 0x90,
+ 0x90,
+ 0x60,
+ 0x00
+};
+
+// Character 218 (0xDA)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | * |
+// | * |
+// |* * |
+// |* * |
+// |* * |
+// |* * |
+// | ** |
+// | |
+// +-----+
+static const byte glyph218[] = {
+ 0x20,
+ 0x40,
+ 0x90,
+ 0x90,
+ 0x90,
+ 0x90,
+ 0x60,
+ 0x00
+};
+
+// Character 219 (0xDB)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | ** |
+// |* * |
+// |* * |
+// |* * |
+// |* * |
+// |* * |
+// | ** |
+// | |
+// +-----+
+static const byte glyph219[] = {
+ 0x60,
+ 0x90,
+ 0x90,
+ 0x90,
+ 0x90,
+ 0x90,
+ 0x60,
+ 0x00
+};
+
+// Character 220 (0xDC)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// |* * |
+// | |
+// |* * |
+// |* * |
+// |* * |
+// |* * |
+// | ** |
+// | |
+// +-----+
+static const byte glyph220[] = {
+ 0x90,
+ 0x00,
+ 0x90,
+ 0x90,
+ 0x90,
+ 0x90,
+ 0x60,
+ 0x00
+};
+
+// Character 221 (0xDD)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | * |
+// | * |
+// |* *|
+// | * * |
+// | * |
+// | * |
+// | * |
+// | |
+// +-----+
+static const byte glyph221[] = {
+ 0x10,
+ 0x20,
+ 0x88,
+ 0x50,
+ 0x20,
+ 0x20,
+ 0x20,
+ 0x00
+};
+
+// Character 222 (0xDE)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | |
+// |* |
+// |*** |
+// |* * |
+// |* * |
+// |*** |
+// |* |
+// | |
+// +-----+
+static const byte glyph222[] = {
+ 0x00,
+ 0x80,
+ 0xE0,
+ 0x90,
+ 0x90,
+ 0xE0,
+ 0x80,
+ 0x00
+};
+
+// Character 223 (0xDF)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | |
+// | ** |
+// |* * |
+// |* * |
+// |* * |
+// |* * |
+// |* * |
+// | |
+// +-----+
+static const byte glyph223[] = {
+ 0x00,
+ 0x60,
+ 0x90,
+ 0xA0,
+ 0xA0,
+ 0x90,
+ 0xA0,
+ 0x00
+};
+
+// Character 224 (0xE0)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | * |
+// | * |
+// | |
+// | *** |
+// |* * |
+// |* * |
+// | *** |
+// | |
+// +-----+
+static const byte glyph224[] = {
+ 0x40,
+ 0x20,
+ 0x00,
+ 0x70,
+ 0x90,
+ 0x90,
+ 0x70,
+ 0x00
+};
+
+// Character 225 (0xE1)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | * |
+// | * |
+// | |
+// | *** |
+// |* * |
+// |* * |
+// | *** |
+// | |
+// +-----+
+static const byte glyph225[] = {
+ 0x20,
+ 0x40,
+ 0x00,
+ 0x70,
+ 0x90,
+ 0x90,
+ 0x70,
+ 0x00
+};
+
+// Character 226 (0xE2)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | * |
+// | * * |
+// | |
+// | *** |
+// |* * |
+// |* * |
+// | *** |
+// | |
+// +-----+
+static const byte glyph226[] = {
+ 0x20,
+ 0x50,
+ 0x00,
+ 0x70,
+ 0x90,
+ 0x90,
+ 0x70,
+ 0x00
+};
+
+// Character 227 (0xE3)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | * * |
+// |* * |
+// | |
+// | *** |
+// |* * |
+// |* * |
+// | *** |
+// | |
+// +-----+
+static const byte glyph227[] = {
+ 0x50,
+ 0xA0,
+ 0x00,
+ 0x70,
+ 0x90,
+ 0x90,
+ 0x70,
+ 0x00
+};
+
+// Character 228 (0xE4)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | |
+// | * * |
+// | |
+// | *** |
+// |* * |
+// |* * |
+// | *** |
+// | |
+// +-----+
+static const byte glyph228[] = {
+ 0x00,
+ 0x50,
+ 0x00,
+ 0x70,
+ 0x90,
+ 0x90,
+ 0x70,
+ 0x00
+};
+
+// Character 229 (0xE5)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | ** |
+// |* * |
+// | ** |
+// | *** |
+// |* * |
+// |* * |
+// | *** |
+// | |
+// +-----+
+static const byte glyph229[] = {
+ 0x60,
+ 0x90,
+ 0x60,
+ 0x70,
+ 0x90,
+ 0x90,
+ 0x70,
+ 0x00
+};
+
+// Character 230 (0xE6)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | |
+// | |
+// | |
+// |**** |
+// | ** *|
+// |* ** |
+// | ****|
+// | |
+// +-----+
+static const byte glyph230[] = {
+ 0x00,
+ 0x00,
+ 0x00,
+ 0xF0,
+ 0x68,
+ 0xB0,
+ 0x78,
+ 0x00
+};
+
+// Character 231 (0xE7)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | |
+// | |
+// | |
+// | ** |
+// | * |
+// | * |
+// | ** |
+// | * |
+// +-----+
+static const byte glyph231[] = {
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x30,
+ 0x40,
+ 0x40,
+ 0x30,
+ 0x20
+};
+
+// Character 232 (0xE8)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | * |
+// | * |
+// | |
+// | ** |
+// |* ** |
+// |** |
+// | ** |
+// | |
+// +-----+
+static const byte glyph232[] = {
+ 0x40,
+ 0x20,
+ 0x00,
+ 0x60,
+ 0xB0,
+ 0xC0,
+ 0x60,
+ 0x00
+};
+
+// Character 233 (0xE9)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | * |
+// | * |
+// | |
+// | ** |
+// |* ** |
+// |** |
+// | ** |
+// | |
+// +-----+
+static const byte glyph233[] = {
+ 0x20,
+ 0x40,
+ 0x00,
+ 0x60,
+ 0xB0,
+ 0xC0,
+ 0x60,
+ 0x00
+};
+
+// Character 234 (0xEA)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | ** |
+// |* * |
+// | |
+// | ** |
+// |* ** |
+// |** |
+// | ** |
+// | |
+// +-----+
+static const byte glyph234[] = {
+ 0x60,
+ 0x90,
+ 0x00,
+ 0x60,
+ 0xB0,
+ 0xC0,
+ 0x60,
+ 0x00
+};
+
+// Character 235 (0xEB)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | |
+// | * * |
+// | |
+// | ** |
+// |* ** |
+// |** |
+// | ** |
+// | |
+// +-----+
+static const byte glyph235[] = {
+ 0x00,
+ 0x50,
+ 0x00,
+ 0x60,
+ 0xB0,
+ 0xC0,
+ 0x60,
+ 0x00
+};
+
+// Character 236 (0xEC)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | * |
+// | * |
+// | |
+// | ** |
+// | * |
+// | * |
+// | *** |
+// | |
+// +-----+
+static const byte glyph236[] = {
+ 0x40,
+ 0x20,
+ 0x00,
+ 0x60,
+ 0x20,
+ 0x20,
+ 0x70,
+ 0x00
+};
+
+// Character 237 (0xED)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | * |
+// | * |
+// | |
+// | ** |
+// | * |
+// | * |
+// | *** |
+// | |
+// +-----+
+static const byte glyph237[] = {
+ 0x10,
+ 0x20,
+ 0x00,
+ 0x60,
+ 0x20,
+ 0x20,
+ 0x70,
+ 0x00
+};
+
+// Character 238 (0xEE)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | * |
+// | * * |
+// | |
+// | ** |
+// | * |
+// | * |
+// | *** |
+// | |
+// +-----+
+static const byte glyph238[] = {
+ 0x20,
+ 0x50,
+ 0x00,
+ 0x60,
+ 0x20,
+ 0x20,
+ 0x70,
+ 0x00
+};
+
+// Character 239 (0xEF)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | |
+// | * * |
+// | |
+// | ** |
+// | * |
+// | * |
+// | *** |
+// | |
+// +-----+
+static const byte glyph239[] = {
+ 0x00,
+ 0x50,
+ 0x00,
+ 0x60,
+ 0x20,
+ 0x20,
+ 0x70,
+ 0x00
+};
+
+// Character 240 (0xF0)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// |* * |
+// | * |
+// |* * |
+// | * |
+// | *** |
+// |* * |
+// | ** |
+// | |
+// +-----+
+static const byte glyph240[] = {
+ 0xA0,
+ 0x40,
+ 0xA0,
+ 0x10,
+ 0x70,
+ 0x90,
+ 0x60,
+ 0x00
+};
+
+// Character 241 (0xF1)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | * * |
+// |* * |
+// | |
+// |*** |
+// |* * |
+// |* * |
+// |* * |
+// | |
+// +-----+
+static const byte glyph241[] = {
+ 0x50,
+ 0xA0,
+ 0x00,
+ 0xE0,
+ 0x90,
+ 0x90,
+ 0x90,
+ 0x00
+};
+
+// Character 242 (0xF2)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | * |
+// | * |
+// | |
+// | ** |
+// |* * |
+// |* * |
+// | ** |
+// | |
+// +-----+
+static const byte glyph242[] = {
+ 0x40,
+ 0x20,
+ 0x00,
+ 0x60,
+ 0x90,
+ 0x90,
+ 0x60,
+ 0x00
+};
+
+// Character 243 (0xF3)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | * |
+// | * |
+// | |
+// | ** |
+// |* * |
+// |* * |
+// | ** |
+// | |
+// +-----+
+static const byte glyph243[] = {
+ 0x20,
+ 0x40,
+ 0x00,
+ 0x60,
+ 0x90,
+ 0x90,
+ 0x60,
+ 0x00
+};
+
+// Character 244 (0xF4)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | ** |
+// |* * |
+// | |
+// | ** |
+// |* * |
+// |* * |
+// | ** |
+// | |
+// +-----+
+static const byte glyph244[] = {
+ 0x60,
+ 0x90,
+ 0x00,
+ 0x60,
+ 0x90,
+ 0x90,
+ 0x60,
+ 0x00
+};
+
+// Character 245 (0xF5)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | * * |
+// |* * |
+// | |
+// | ** |
+// |* * |
+// |* * |
+// | ** |
+// | |
+// +-----+
+static const byte glyph245[] = {
+ 0x50,
+ 0xA0,
+ 0x00,
+ 0x60,
+ 0x90,
+ 0x90,
+ 0x60,
+ 0x00
+};
+
+// Character 246 (0xF6)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | |
+// |* * |
+// | |
+// | ** |
+// |* * |
+// |* * |
+// | ** |
+// | |
+// +-----+
+static const byte glyph246[] = {
+ 0x00,
+ 0x90,
+ 0x00,
+ 0x60,
+ 0x90,
+ 0x90,
+ 0x60,
+ 0x00
+};
+
+// Character 247 (0xF7)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | |
+// | |
+// | * |
+// | |
+// | *** |
+// | |
+// | * |
+// | |
+// +-----+
+static const byte glyph247[] = {
+ 0x00,
+ 0x00,
+ 0x20,
+ 0x00,
+ 0x70,
+ 0x00,
+ 0x20,
+ 0x00
+};
+
+// Character 248 (0xF8)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | |
+// | |
+// | |
+// | *** |
+// |* ** |
+// |** * |
+// |*** |
+// | |
+// +-----+
+static const byte glyph248[] = {
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x70,
+ 0xB0,
+ 0xD0,
+ 0xE0,
+ 0x00
+};
+
+// Character 249 (0xF9)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | * |
+// | * |
+// | |
+// |* * |
+// |* * |
+// |* * |
+// | *** |
+// | |
+// +-----+
+static const byte glyph249[] = {
+ 0x40,
+ 0x20,
+ 0x00,
+ 0x90,
+ 0x90,
+ 0x90,
+ 0x70,
+ 0x00
+};
+
+// Character 250 (0xFA)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | * |
+// | * |
+// | |
+// |* * |
+// |* * |
+// |* * |
+// | *** |
+// | |
+// +-----+
+static const byte glyph250[] = {
+ 0x20,
+ 0x40,
+ 0x00,
+ 0x90,
+ 0x90,
+ 0x90,
+ 0x70,
+ 0x00
+};
+
+// Character 251 (0xFB)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | ** |
+// |* * |
+// | |
+// |* * |
+// |* * |
+// |* * |
+// | *** |
+// | |
+// +-----+
+static const byte glyph251[] = {
+ 0x60,
+ 0x90,
+ 0x00,
+ 0x90,
+ 0x90,
+ 0x90,
+ 0x70,
+ 0x00
+};
+
+// Character 252 (0xFC)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | |
+// |* * |
+// | |
+// |* * |
+// |* * |
+// |* * |
+// | *** |
+// | |
+// +-----+
+static const byte glyph252[] = {
+ 0x00,
+ 0x90,
+ 0x00,
+ 0x90,
+ 0x90,
+ 0x90,
+ 0x70,
+ 0x00
+};
+
+// Character 253 (0xFD)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | * |
+// | * |
+// | |
+// |* * |
+// |* * |
+// | *** |
+// |* * |
+// | ** |
+// +-----+
+static const byte glyph253[] = {
+ 0x20,
+ 0x40,
+ 0x00,
+ 0x90,
+ 0x90,
+ 0x70,
+ 0x90,
+ 0x60
+};
+
+// Character 254 (0xFE)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | |
+// |* |
+// |* |
+// |*** |
+// |* * |
+// |*** |
+// |* |
+// |* |
+// +-----+
+static const byte glyph254[] = {
+ 0x00,
+ 0x80,
+ 0x80,
+ 0xE0,
+ 0x90,
+ 0xE0,
+ 0x80,
+ 0x80
+};
+
+// Character 255 (0xFF)
+// Box: 5 8 0 -1
+// Advance: 5
+//
+// +-----+
+// | |
+// |* * |
+// | |
+// |* * |
+// |* * |
+// | *** |
+// |* * |
+// | ** |
+// +-----+
+static const byte glyph255[] = {
+ 0x00,
+ 0x90,
+ 0x00,
+ 0x90,
+ 0x90,
+ 0x70,
+ 0x90,
+ 0x60
+};
+
+// Bitmap pointer table
+const byte *const bitmapTable[] = {
+ glyph0,
+ glyph1,
+ glyph2,
+ glyph3,
+ glyph4,
+ glyph5,
+ glyph6,
+ glyph7,
+ glyph8,
+ glyph9,
+ glyph10,
+ glyph11,
+ glyph12,
+ glyph13,
+ glyph14,
+ glyph15,
+ glyph16,
+ glyph17,
+ glyph18,
+ glyph19,
+ glyph20,
+ glyph21,
+ glyph22,
+ glyph23,
+ glyph24,
+ glyph25,
+ glyph26,
+ glyph27,
+ glyph28,
+ glyph29,
+ glyph30,
+ glyph31,
+ glyph32,
+ glyph33,
+ glyph34,
+ glyph35,
+ glyph36,
+ glyph37,
+ glyph38,
+ glyph39,
+ glyph40,
+ glyph41,
+ glyph42,
+ glyph43,
+ glyph44,
+ glyph45,
+ glyph46,
+ glyph47,
+ glyph48,
+ glyph49,
+ glyph50,
+ glyph51,
+ glyph52,
+ glyph53,
+ glyph54,
+ glyph55,
+ glyph56,
+ glyph57,
+ glyph58,
+ glyph59,
+ glyph60,
+ glyph61,
+ glyph62,
+ glyph63,
+ glyph64,
+ glyph65,
+ glyph66,
+ glyph67,
+ glyph68,
+ glyph69,
+ glyph70,
+ glyph71,
+ glyph72,
+ glyph73,
+ glyph74,
+ glyph75,
+ glyph76,
+ glyph77,
+ glyph78,
+ glyph79,
+ glyph80,
+ glyph81,
+ glyph82,
+ glyph83,
+ glyph84,
+ glyph85,
+ glyph86,
+ glyph87,
+ glyph88,
+ glyph89,
+ glyph90,
+ glyph91,
+ glyph92,
+ glyph93,
+ glyph94,
+ glyph95,
+ glyph96,
+ glyph97,
+ glyph98,
+ glyph99,
+ glyph100,
+ glyph101,
+ glyph102,
+ glyph103,
+ glyph104,
+ glyph105,
+ glyph106,
+ glyph107,
+ glyph108,
+ glyph109,
+ glyph110,
+ glyph111,
+ glyph112,
+ glyph113,
+ glyph114,
+ glyph115,
+ glyph116,
+ glyph117,
+ glyph118,
+ glyph119,
+ glyph120,
+ glyph121,
+ glyph122,
+ glyph123,
+ glyph124,
+ glyph125,
+ glyph126,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
0,
- 256,
- _font_bits,
- _sysfont_offset,
- 0, /* fixed width*/
- 0, /* fixed bbox*/
0,
- sizeof(_font_bits)/sizeof(bitmap_t)
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ glyph160,
+ glyph161,
+ glyph162,
+ glyph163,
+ glyph164,
+ glyph165,
+ glyph166,
+ glyph167,
+ glyph168,
+ glyph169,
+ glyph170,
+ glyph171,
+ glyph172,
+ glyph173,
+ glyph174,
+ glyph175,
+ glyph176,
+ glyph177,
+ glyph178,
+ glyph179,
+ glyph180,
+ glyph181,
+ glyph182,
+ glyph183,
+ glyph184,
+ glyph185,
+ glyph186,
+ glyph187,
+ glyph188,
+ glyph189,
+ glyph190,
+ glyph191,
+ glyph192,
+ glyph193,
+ glyph194,
+ glyph195,
+ glyph196,
+ glyph197,
+ glyph198,
+ glyph199,
+ glyph200,
+ glyph201,
+ glyph202,
+ glyph203,
+ glyph204,
+ glyph205,
+ glyph206,
+ glyph207,
+ glyph208,
+ glyph209,
+ glyph210,
+ glyph211,
+ glyph212,
+ glyph213,
+ glyph214,
+ glyph215,
+ glyph216,
+ glyph217,
+ glyph218,
+ glyph219,
+ glyph220,
+ glyph221,
+ glyph222,
+ glyph223,
+ glyph224,
+ glyph225,
+ glyph226,
+ glyph227,
+ glyph228,
+ glyph229,
+ glyph230,
+ glyph231,
+ glyph232,
+ glyph233,
+ glyph234,
+ glyph235,
+ glyph236,
+ glyph237,
+ glyph238,
+ glyph239,
+ glyph240,
+ glyph241,
+ glyph242,
+ glyph243,
+ glyph244,
+ glyph245,
+ glyph246,
+ glyph247,
+ glyph248,
+ glyph249,
+ glyph250,
+ glyph251,
+ glyph252,
+ glyph253,
+ glyph254,
+ glyph255
+};
+
+// Font structure
+static const BdfFontData desc = {
+ 5, // Max advance
+ 8, // Height
+ { 5, 8, 0, -1 }, // Bounding box
+ 7, // Ascent
+
+ 0, // First character
+ 0, // Default character
+ 256, // Characters
+
+ bitmapTable, // Bitmaps
+ 0, // Advances
+ 0 // Boxes
};
DEFINE_FONT(g_consolefont)
diff --git a/graphics/fonts/newfont.cpp b/graphics/fonts/newfont.cpp
index f02baba2de..10af1efb0c 100644
--- a/graphics/fonts/newfont.cpp
+++ b/graphics/fonts/newfont.cpp
@@ -1,7438 +1,7651 @@
-/* Generated by convbdf on Sat Jun 17 01:34:15 2006. */
+// Generated by convbdf on Fri Jan 6 14:33:07 2012
#include "graphics/fonts/bdf.h"
-/* Font information:
- name: clR6x12-L1
- facename: -Schumacher-Clean-Medium-R-Normal--12-120-75-75-C-60-ISO8859-1
- w x h: 6x12
- bbx: 6 12 0 -3
- size: 256
- ascent: 9
- descent: 3
- first char: 0 (0x00)
- last char: 255 (0xff)
- default char: 0 (0x00)
- proportional: no
- Copyright 1989 Dale Schumacher, 1999 Robert Brady.
-*/
+// Font information:
+// Name: -Schumacher-Clean-Medium-R-Normal--12-120-75-75-C-60-ISO8859-1
+// Size: 6x12
+// Box: 6 12 0 -3
+// Ascent: 9
+// First character: 0
+// Default character: 0
+// Characters: 256
+// Copyright: "Copyright 1989 Dale Schumacher, 1999 Robert Brady."
namespace Graphics {
-/* Font character bitmap data. */
-static const bitmap_t _font_bits[] = {
-
-/* Character 0 (0x00):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- | |
- |* * * |
- | |
- |* * |
- | |
- |* * |
- | |
- |* * * |
- | |
- | |
- | |
- +------+
-*/
-0x0000,
-0x0000,
-0xa800,
-0x0000,
-0x8800,
-0x0000,
-0x8800,
-0x0000,
-0xa800,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 1 (0x01):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- | |
- | |
- | |
- | * |
- | *** |
- |***** |
- | *** |
- | * |
- | |
- | |
- | |
- +------+
-*/
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x2000,
-0x7000,
-0xf800,
-0x7000,
-0x2000,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 2 (0x02):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- |* * * |
- | * * *|
- |* * * |
- | * * *|
- |* * * |
- | * * *|
- |* * * |
- | * * *|
- |* * * |
- | * * *|
- |* * * |
- | * * *|
- +------+
-*/
-0xa800,
-0x5400,
-0xa800,
-0x5400,
-0xa800,
-0x5400,
-0xa800,
-0x5400,
-0xa800,
-0x5400,
-0xa800,
-0x5400,
-
-/* Character 3 (0x03):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- |* * |
- |* * |
- |*** |
- |* * |
- |* ****|
- | * |
- | * |
- | * |
- | * |
- | |
- | |
- +------+
-*/
-0x0000,
-0xa000,
-0xa000,
-0xe000,
-0xa000,
-0xbc00,
-0x0800,
-0x0800,
-0x0800,
-0x0800,
-0x0000,
-0x0000,
-
-/* Character 4 (0x04):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- |*** |
- |* |
- |** |
- |* ***|
- |* * |
- | ***|
- | * |
- | * |
- | |
- | |
- | |
- +------+
-*/
-0x0000,
-0xe000,
-0x8000,
-0xc000,
-0x9c00,
-0x9000,
-0x1c00,
-0x1000,
-0x1000,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 5 (0x05):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- | ** |
- |* |
- |* |
- |* ** |
- | *** *|
- | ** |
- | * *|
- | * *|
- | |
- | |
- | |
- +------+
-*/
-0x0000,
-0x6000,
-0x8000,
-0x8000,
-0x9800,
-0x7400,
-0x1800,
-0x1400,
-0x1400,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 6 (0x06):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- |* |
- |* |
- |* |
- |* ***|
- |**** |
- | ** |
- | * |
- | * |
- | |
- | |
- | |
- +------+
-*/
-0x0000,
-0x8000,
-0x8000,
-0x8000,
-0x9c00,
-0xf000,
-0x1800,
-0x1000,
-0x1000,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 7 (0x07):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- | ** |
- | * * |
- | * * |
- | ** |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- +------+
-*/
-0x0000,
-0x3000,
-0x4800,
-0x4800,
-0x3000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 8 (0x08):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- | |
- | * |
- | * |
- |***** |
- | * |
- | * |
- | |
- |***** |
- | |
- | |
- | |
- +------+
-*/
-0x0000,
-0x0000,
-0x2000,
-0x2000,
-0xf800,
-0x2000,
-0x2000,
-0x0000,
-0xf800,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 9 (0x09):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- |* * |
- |*** |
- |*** |
- |*** |
- |* ** |
- | * |
- | * |
- | * |
- | ***|
- | |
- | |
- | |
- +------+
-*/
-0xa000,
-0xe000,
-0xe000,
-0xe000,
-0xb000,
-0x1000,
-0x1000,
-0x1000,
-0x1c00,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 10 (0x0a):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- |* * |
- |* * |
- |* * |
- | * ***|
- | * * |
- | * |
- | * |
- | * |
- | |
- | |
- | |
- +------+
-*/
-0x0000,
-0xa000,
-0xa000,
-0xa000,
-0x5c00,
-0x4800,
-0x0800,
-0x0800,
-0x0800,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 11 (0x0b):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | * |
- | * |
- | * |
- | * |
- | * |
- | * |
- |*** |
- | |
- | |
- | |
- | |
- | |
- +------+
-*/
-0x2000,
-0x2000,
-0x2000,
-0x2000,
-0x2000,
-0x2000,
-0xe000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 12 (0x0c):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- | |
- | |
- | |
- | |
- | |
- |*** |
- | * |
- | * |
- | * |
- | * |
- | * |
- +------+
-*/
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0xe000,
-0x2000,
-0x2000,
-0x2000,
-0x2000,
-0x2000,
-
-/* Character 13 (0x0d):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- | |
- | |
- | |
- | |
- | |
- | ****|
- | * |
- | * |
- | * |
- | * |
- | * |
- +------+
-*/
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x3f00,
-0x2000,
-0x2000,
-0x2000,
-0x2000,
-0x2000,
-
-/* Character 14 (0x0e):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | * |
- | * |
- | * |
- | * |
- | * |
- | * |
- | ****|
- | |
- | |
- | |
- | |
- | |
- +------+
-*/
-0x2000,
-0x2000,
-0x2000,
-0x2000,
-0x2000,
-0x2000,
-0x3f00,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 15 (0x0f):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | * |
- | * |
- | * |
- | * |
- | * |
- | * |
- |******|
- | * |
- | * |
- | * |
- | * |
- | * |
- +------+
-*/
-0x2000,
-0x2000,
-0x2000,
-0x2000,
-0x2000,
-0x2000,
-0xff00,
-0x2000,
-0x2000,
-0x2000,
-0x2000,
-0x2000,
-
-/* Character 16 (0x10):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- |******|
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- +------+
-*/
-0xfc00,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 17 (0x11):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- | |
- | |
- |******|
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- +------+
-*/
-0x0000,
-0x0000,
-0x0000,
-0xfc00,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 18 (0x12):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- | |
- | |
- | |
- | |
- | |
- |******|
- | |
- | |
- | |
- | |
- | |
- +------+
-*/
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0xfc00,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 19 (0x13):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- |******|
- | |
- | |
- | |
- +------+
-*/
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0xfc00,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 20 (0x14):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- |******|
- +------+
-*/
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0xfc00,
-
-/* Character 21 (0x15):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | * |
- | * |
- | * |
- | * |
- | * |
- | * |
- | ****|
- | * |
- | * |
- | * |
- | * |
- | * |
- +------+
-*/
-0x2000,
-0x2000,
-0x2000,
-0x2000,
-0x2000,
-0x2000,
-0x3f00,
-0x2000,
-0x2000,
-0x2000,
-0x2000,
-0x2000,
-
-/* Character 22 (0x16):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | * |
- | * |
- | * |
- | * |
- | * |
- | * |
- |*** |
- | * |
- | * |
- | * |
- | * |
- | * |
- +------+
-*/
-0x2000,
-0x2000,
-0x2000,
-0x2000,
-0x2000,
-0x2000,
-0xe000,
-0x2000,
-0x2000,
-0x2000,
-0x2000,
-0x2000,
-
-/* Character 23 (0x17):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | * |
- | * |
- | * |
- | * |
- | * |
- | * |
- |******|
- | |
- | |
- | |
- | |
- | |
- +------+
-*/
-0x2000,
-0x2000,
-0x2000,
-0x2000,
-0x2000,
-0x2000,
-0xff00,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 24 (0x18):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- | |
- | |
- | |
- | |
- | |
- |******|
- | * |
- | * |
- | * |
- | * |
- | * |
- +------+
-*/
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0xff00,
-0x2000,
-0x2000,
-0x2000,
-0x2000,
-0x2000,
-
-/* Character 25 (0x19):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | * |
- | * |
- | * |
- | * |
- | * |
- | * |
- | * |
- | * |
- | * |
- | * |
- | * |
- | * |
- +------+
-*/
-0x2000,
-0x2000,
-0x2000,
-0x2000,
-0x2000,
-0x2000,
-0x2000,
-0x2000,
-0x2000,
-0x2000,
-0x2000,
-0x2000,
-
-/* Character 26 (0x1a):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- | |
- | ** |
- | ** |
- |* |
- | ** |
- | ** |
- | |
- |***** |
- | |
- | |
- | |
- +------+
-*/
-0x0000,
-0x0000,
-0x1800,
-0x6000,
-0x8000,
-0x6000,
-0x1800,
-0x0000,
-0xf800,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 27 (0x1b):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- | |
- |** |
- | ** |
- | * |
- | ** |
- |** |
- | |
- |***** |
- | |
- | |
- | |
- +------+
-*/
-0x0000,
-0x0000,
-0xc000,
-0x3000,
-0x0800,
-0x3000,
-0xc000,
-0x0000,
-0xf800,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 28 (0x1c):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- | |
- | |
- | |
- |***** |
- |* * |
- |* * |
- |* * |
- |* * |
- | |
- | |
- | |
- +------+
-*/
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0xf800,
-0x8800,
-0x8800,
-0x8800,
-0x8800,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 29 (0x1d):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- | |
- | * |
- | * |
- |***** |
- | * |
- |***** |
- | * |
- | * |
- | |
- | |
- | |
- +------+
-*/
-0x0000,
-0x0000,
-0x1000,
-0x1000,
-0xf800,
-0x2000,
-0xf800,
-0x4000,
-0x4000,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 30 (0x1e):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- | ** |
- | * * |
- | * |
- |*** |
- | * |
- | * |
- | * * |
- |* ** |
- | |
- | |
- | |
- +------+
-*/
-0x0000,
-0x3000,
-0x4800,
-0x4000,
-0xe000,
-0x4000,
-0x4000,
-0x4800,
-0xb000,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 31 (0x1f):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- | |
- | |
- | |
- | |
- | |
- | ** |
- | |
- | |
- | |
- | |
- | |
- +------+
-*/
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x3000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 32 (0x20):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- +------+
-*/
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 33 (0x21):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- | * |
- | * |
- | * |
- | * |
- | * |
- | * |
- | |
- | * |
- | |
- | |
- | |
- +------+
-*/
-0x0000,
-0x2000,
-0x2000,
-0x2000,
-0x2000,
-0x2000,
-0x2000,
-0x0000,
-0x2000,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 34 (0x22):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- | * * |
- | * * |
- | * * |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- +------+
-*/
-0x0000,
-0x5000,
-0x5000,
-0x5000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 35 (0x23):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- | |
- | * * |
- | * * |
- |***** |
- | * * |
- |***** |
- | * * |
- | * * |
- | |
- | |
- | |
- +------+
-*/
-0x0000,
-0x0000,
-0x5000,
-0x5000,
-0xf800,
-0x5000,
-0xf800,
-0x5000,
-0x5000,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 36 (0x24):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- | |
- | * |
- | **** |
- |* * |
- | *** |
- | * * |
- |**** |
- | * |
- | |
- | |
- | |
- +------+
-*/
-0x0000,
-0x0000,
-0x2000,
-0x7800,
-0xa000,
-0x7000,
-0x2800,
-0xf000,
-0x2000,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 37 (0x25):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- | |
- |** |
- |** * |
- | * |
- | * |
- | * |
- |* ** |
- | ** |
- | |
- | |
- | |
- +------+
-*/
-0x0000,
-0x0000,
-0xc000,
-0xc800,
-0x1000,
-0x2000,
-0x4000,
-0x9800,
-0x1800,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 38 (0x26):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- | |
- | *** |
- |* |
- |* |
- | * |
- |* * * |
- |* * |
- | ** * |
- | |
- | |
- | |
- +------+
-*/
-0x0000,
-0x0000,
-0x7000,
-0x8000,
-0x8000,
-0x4000,
-0xa800,
-0x9000,
-0x6800,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 39 (0x27):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- | * |
- | * |
- | * |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- +------+
-*/
-0x0000,
-0x2000,
-0x2000,
-0x2000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 40 (0x28):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | * |
- | * |
- | * |
- | * |
- | * |
- | * |
- | * |
- | * |
- | * |
- | * |
- | * |
- | |
- +------+
-*/
-0x0800,
-0x1000,
-0x1000,
-0x2000,
-0x2000,
-0x2000,
-0x2000,
-0x2000,
-0x1000,
-0x1000,
-0x0800,
-0x0000,
-
-/* Character 41 (0x29):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | * |
- | * |
- | * |
- | * |
- | * |
- | * |
- | * |
- | * |
- | * |
- | * |
- | * |
- | |
- +------+
-*/
-0x4000,
-0x2000,
-0x2000,
-0x1000,
-0x1000,
-0x1000,
-0x1000,
-0x1000,
-0x2000,
-0x2000,
-0x4000,
-0x0000,
-
-/* Character 42 (0x2a):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- | |
- | |
- | * |
- |* * * |
- | *** |
- |* * * |
- | * |
- | |
- | |
- | |
- | |
- +------+
-*/
-0x0000,
-0x0000,
-0x0000,
-0x2000,
-0xa800,
-0x7000,
-0xa800,
-0x2000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 43 (0x2b):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- | |
- | |
- | * |
- | * |
- |***** |
- | * |
- | * |
- | |
- | |
- | |
- | |
- +------+
-*/
-0x0000,
-0x0000,
-0x0000,
-0x2000,
-0x2000,
-0xf800,
-0x2000,
-0x2000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 44 (0x2c):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | ** |
- | ** |
- | * |
- | * |
- | |
- +------+
-*/
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x3000,
-0x3000,
-0x2000,
-0x4000,
-0x0000,
-
-/* Character 45 (0x2d):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- | |
- | |
- | |
- | |
- |***** |
- | |
- | |
- | |
- | |
- | |
- | |
- +------+
-*/
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0xf800,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 46 (0x2e):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | ** |
- | ** |
- | |
- | |
- | |
- +------+
-*/
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x3000,
-0x3000,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 47 (0x2f):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | * |
- | * |
- | * |
- | * |
- | * |
- | * |
- | * |
- | * |
- |* |
- |* |
- | |
- | |
- +------+
-*/
-0x0800,
-0x0800,
-0x1000,
-0x1000,
-0x2000,
-0x2000,
-0x4000,
-0x4000,
-0x8000,
-0x8000,
-0x0000,
-0x0000,
-
-/* Character 48 (0x30):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- | *** |
- |* * |
- |* ** |
- |* * * |
- |** * |
- |* * |
- |* * |
- | *** |
- | |
- | |
- | |
- +------+
-*/
-0x0000,
-0x7000,
-0x8800,
-0x9800,
-0xa800,
-0xc800,
-0x8800,
-0x8800,
-0x7000,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 49 (0x31):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- | * |
- | ** |
- | * |
- | * |
- | * |
- | * |
- | * |
- | * |
- | |
- | |
- | |
- +------+
-*/
-0x0000,
-0x1000,
-0x3000,
-0x1000,
-0x1000,
-0x1000,
-0x1000,
-0x1000,
-0x1000,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 50 (0x32):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- | *** |
- |* * |
- | * |
- | * |
- | * |
- | * |
- |* |
- |***** |
- | |
- | |
- | |
- +------+
-*/
-0x0000,
-0x7000,
-0x8800,
-0x0800,
-0x1000,
-0x2000,
-0x4000,
-0x8000,
-0xf800,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 51 (0x33):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- | *** |
- |* * |
- | * |
- | ** |
- | * |
- | * |
- |* * |
- | *** |
- | |
- | |
- | |
- +------+
-*/
-0x0000,
-0x7000,
-0x8800,
-0x0800,
-0x3000,
-0x0800,
-0x0800,
-0x8800,
-0x7000,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 52 (0x34):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- | * |
- | ** |
- | ** |
- | * * |
- | * * |
- |***** |
- | * |
- | *** |
- | |
- | |
- | |
- +------+
-*/
-0x0000,
-0x1000,
-0x3000,
-0x3000,
-0x5000,
-0x5000,
-0xf800,
-0x1000,
-0x3800,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 53 (0x35):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- |***** |
- |* |
- |* |
- |**** |
- | * |
- | * |
- |* * |
- | *** |
- | |
- | |
- | |
- +------+
-*/
-0x0000,
-0xf800,
-0x8000,
-0x8000,
-0xf000,
-0x0800,
-0x0800,
-0x8800,
-0x7000,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 54 (0x36):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- | ** |
- | * |
- |* |
- |**** |
- |* * |
- |* * |
- |* * |
- | *** |
- | |
- | |
- | |
- +------+
-*/
-0x0000,
-0x3000,
-0x4000,
-0x8000,
-0xf000,
-0x8800,
-0x8800,
-0x8800,
-0x7000,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 55 (0x37):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- |***** |
- |* * |
- | * |
- | * |
- | * |
- | * |
- | * |
- | * |
- | |
- | |
- | |
- +------+
-*/
-0x0000,
-0xf800,
-0x8800,
-0x0800,
-0x0800,
-0x1000,
-0x1000,
-0x2000,
-0x2000,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 56 (0x38):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- | *** |
- |* * |
- |* * |
- | *** |
- |* * |
- |* * |
- |* * |
- | *** |
- | |
- | |
- | |
- +------+
-*/
-0x0000,
-0x7000,
-0x8800,
-0x8800,
-0x7000,
-0x8800,
-0x8800,
-0x8800,
-0x7000,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 57 (0x39):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- | *** |
- |* * |
- |* * |
- |* * |
- | **** |
- | * |
- | * |
- | ** |
- | |
- | |
- | |
- +------+
-*/
-0x0000,
-0x7000,
-0x8800,
-0x8800,
-0x8800,
-0x7800,
-0x0800,
-0x1000,
-0x6000,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 58 (0x3a):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- | |
- | |
- | ** |
- | ** |
- | |
- | |
- | ** |
- | ** |
- | |
- | |
- | |
- +------+
-*/
-0x0000,
-0x0000,
-0x0000,
-0x3000,
-0x3000,
-0x0000,
-0x0000,
-0x3000,
-0x3000,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 59 (0x3b):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- | |
- | |
- | ** |
- | ** |
- | |
- | |
- | ** |
- | ** |
- | * |
- | * |
- | |
- +------+
-*/
-0x0000,
-0x0000,
-0x0000,
-0x3000,
-0x3000,
-0x0000,
-0x0000,
-0x3000,
-0x3000,
-0x2000,
-0x4000,
-0x0000,
-
-/* Character 60 (0x3c):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- | |
- | |
- | **|
- | ** |
- |** |
- | ** |
- | **|
- | |
- | |
- | |
- | |
- +------+
-*/
-0x0000,
-0x0000,
-0x0000,
-0x0c00,
-0x3000,
-0xc000,
-0x3000,
-0x0c00,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 61 (0x3d):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- | |
- | |
- | |
- |***** |
- | |
- |***** |
- | |
- | |
- | |
- | |
- | |
- +------+
-*/
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0xf800,
-0x0000,
-0xf800,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 62 (0x3e):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- | |
- | |
- |** |
- | ** |
- | **|
- | ** |
- |** |
- | |
- | |
- | |
- | |
- +------+
-*/
-0x0000,
-0x0000,
-0x0000,
-0xc000,
-0x3000,
-0x0c00,
-0x3000,
-0xc000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 63 (0x3f):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- | *** |
- |* * |
- | * |
- | * |
- | * |
- | * |
- | |
- | * |
- | |
- | |
- | |
- +------+
-*/
-0x0000,
-0x7000,
-0x8800,
-0x0800,
-0x1000,
-0x2000,
-0x2000,
-0x0000,
-0x2000,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 64 (0x40):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- | |
- | *** |
- |* * |
- |* *** |
- |* *** |
- |* ** |
- |* |
- | *** |
- | |
- | |
- | |
- +------+
-*/
-0x0000,
-0x0000,
-0x7000,
-0x8800,
-0xb800,
-0xb800,
-0xb000,
-0x8000,
-0x7000,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 65 (0x41):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- | |
- | * |
- | * * |
- |* * |
- |* * |
- |***** |
- |* * |
- |* * |
- | |
- | |
- | |
- +------+
-*/
-0x0000,
-0x0000,
-0x2000,
-0x5000,
-0x8800,
-0x8800,
-0xf800,
-0x8800,
-0x8800,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 66 (0x42):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- | |
- |**** |
- |* * |
- |* * |
- |**** |
- |* * |
- |* * |
- |**** |
- | |
- | |
- | |
- +------+
-*/
-0x0000,
-0x0000,
-0xf000,
-0x8800,
-0x8800,
-0xf000,
-0x8800,
-0x8800,
-0xf000,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 67 (0x43):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- | |
- | *** |
- |* * |
- |* |
- |* |
- |* |
- |* * |
- | *** |
- | |
- | |
- | |
- +------+
-*/
-0x0000,
-0x0000,
-0x7000,
-0x8800,
-0x8000,
-0x8000,
-0x8000,
-0x8800,
-0x7000,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 68 (0x44):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- | |
- |*** |
- |* * |
- |* * |
- |* * |
- |* * |
- |* * |
- |*** |
- | |
- | |
- | |
- +------+
-*/
-0x0000,
-0x0000,
-0xe000,
-0x9000,
-0x8800,
-0x8800,
-0x8800,
-0x9000,
-0xe000,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 69 (0x45):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- | |
- |***** |
- |* |
- |* |
- |**** |
- |* |
- |* |
- |***** |
- | |
- | |
- | |
- +------+
-*/
-0x0000,
-0x0000,
-0xf800,
-0x8000,
-0x8000,
-0xf000,
-0x8000,
-0x8000,
-0xf800,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 70 (0x46):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- | |
- |***** |
- |* |
- |* |
- |**** |
- |* |
- |* |
- |* |
- | |
- | |
- | |
- +------+
-*/
-0x0000,
-0x0000,
-0xf800,
-0x8000,
-0x8000,
-0xf000,
-0x8000,
-0x8000,
-0x8000,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 71 (0x47):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- | |
- | *** |
- |* * |
- |* |
- |* ** |
- |* * |
- |* * |
- | **** |
- | |
- | |
- | |
- +------+
-*/
-0x0000,
-0x0000,
-0x7000,
-0x8800,
-0x8000,
-0x9800,
-0x8800,
-0x8800,
-0x7800,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 72 (0x48):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- | |
- |* * |
- |* * |
- |* * |
- |***** |
- |* * |
- |* * |
- |* * |
- | |
- | |
- | |
- +------+
-*/
-0x0000,
-0x0000,
-0x8800,
-0x8800,
-0x8800,
-0xf800,
-0x8800,
-0x8800,
-0x8800,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 73 (0x49):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- | |
- |***** |
- | * |
- | * |
- | * |
- | * |
- | * |
- |***** |
- | |
- | |
- | |
- +------+
-*/
-0x0000,
-0x0000,
-0xf800,
-0x2000,
-0x2000,
-0x2000,
-0x2000,
-0x2000,
-0xf800,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 74 (0x4a):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- | |
- | *** |
- | * |
- | * |
- | * |
- |* * |
- |* * |
- | *** |
- | |
- | |
- | |
- +------+
-*/
-0x0000,
-0x0000,
-0x3800,
-0x0800,
-0x0800,
-0x0800,
-0x8800,
-0x8800,
-0x7000,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 75 (0x4b):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- | |
- |* * |
- |* * |
- |* * |
- |** |
- |* * |
- |* * |
- |* * |
- | |
- | |
- | |
- +------+
-*/
-0x0000,
-0x0000,
-0x8800,
-0x9000,
-0xa000,
-0xc000,
-0xa000,
-0x9000,
-0x8800,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 76 (0x4c):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- | |
- |* |
- |* |
- |* |
- |* |
- |* |
- |* |
- |***** |
- | |
- | |
- | |
- +------+
-*/
-0x0000,
-0x0000,
-0x8000,
-0x8000,
-0x8000,
-0x8000,
-0x8000,
-0x8000,
-0xf800,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 77 (0x4d):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- | |
- |* * |
- |** ** |
- |* * * |
- |* * * |
- |* * |
- |* * |
- |* * |
- | |
- | |
- | |
- +------+
-*/
-0x0000,
-0x0000,
-0x8800,
-0xd800,
-0xa800,
-0xa800,
-0x8800,
-0x8800,
-0x8800,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 78 (0x4e):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- | |
- |* * |
- |** * |
- |** * |
- |* * * |
- |* ** |
- |* ** |
- |* * |
- | |
- | |
- | |
- +------+
-*/
-0x0000,
-0x0000,
-0x8800,
-0xc800,
-0xc800,
-0xa800,
-0x9800,
-0x9800,
-0x8800,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 79 (0x4f):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- | |
- | *** |
- |* * |
- |* * |
- |* * |
- |* * |
- |* * |
- | *** |
- | |
- | |
- | |
- +------+
-*/
-0x0000,
-0x0000,
-0x7000,
-0x8800,
-0x8800,
-0x8800,
-0x8800,
-0x8800,
-0x7000,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 80 (0x50):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- | |
- |**** |
- |* * |
- |* * |
- |**** |
- |* |
- |* |
- |* |
- | |
- | |
- | |
- +------+
-*/
-0x0000,
-0x0000,
-0xf000,
-0x8800,
-0x8800,
-0xf000,
-0x8000,
-0x8000,
-0x8000,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 81 (0x51):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- | |
- | *** |
- |* * |
- |* * |
- |* * |
- |* * |
- |* * |
- | *** |
- | ** |
- | |
- | |
- +------+
-*/
-0x0000,
-0x0000,
-0x7000,
-0x8800,
-0x8800,
-0x8800,
-0x8800,
-0x8800,
-0x7000,
-0x1800,
-0x0000,
-0x0000,
-
-/* Character 82 (0x52):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- | |
- |**** |
- |* * |
- |* * |
- |**** |
- |* * |
- |* * |
- |* * |
- | |
- | |
- | |
- +------+
-*/
-0x0000,
-0x0000,
-0xf000,
-0x8800,
-0x8800,
-0xf000,
-0xa000,
-0x9000,
-0x8800,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 83 (0x53):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- | |
- | *** |
- |* * |
- |* |
- | *** |
- | * |
- |* * |
- | *** |
- | |
- | |
- | |
- +------+
-*/
-0x0000,
-0x0000,
-0x7000,
-0x8800,
-0x8000,
-0x7000,
-0x0800,
-0x8800,
-0x7000,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 84 (0x54):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- | |
- |***** |
- | * |
- | * |
- | * |
- | * |
- | * |
- | * |
- | |
- | |
- | |
- +------+
-*/
-0x0000,
-0x0000,
-0xf800,
-0x2000,
-0x2000,
-0x2000,
-0x2000,
-0x2000,
-0x2000,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 85 (0x55):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- | |
- |* * |
- |* * |
- |* * |
- |* * |
- |* * |
- |* * |
- | *** |
- | |
- | |
- | |
- +------+
-*/
-0x0000,
-0x0000,
-0x8800,
-0x8800,
-0x8800,
-0x8800,
-0x8800,
-0x8800,
-0x7000,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 86 (0x56):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- | |
- |* * |
- |* * |
- |* * |
- | * * |
- | * * |
- | * |
- | * |
- | |
- | |
- | |
- +------+
-*/
-0x0000,
-0x0000,
-0x8800,
-0x8800,
-0x8800,
-0x5000,
-0x5000,
-0x2000,
-0x2000,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 87 (0x57):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- | |
- |* * |
- |* * |
- |* * |
- |* * * |
- |* * * |
- |** ** |
- |* * |
- | |
- | |
- | |
- +------+
-*/
-0x0000,
-0x0000,
-0x8800,
-0x8800,
-0x8800,
-0xa800,
-0xa800,
-0xd800,
-0x8800,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 88 (0x58):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- | |
- |* * |
- |* * |
- | * * |
- | * |
- | * * |
- |* * |
- |* * |
- | |
- | |
- | |
- +------+
-*/
-0x0000,
-0x0000,
-0x8800,
-0x8800,
-0x5000,
-0x2000,
-0x5000,
-0x8800,
-0x8800,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 89 (0x59):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- | |
- |* * |
- |* * |
- | * * |
- | * |
- | * |
- | * |
- | * |
- | |
- | |
- | |
- +------+
-*/
-0x0000,
-0x0000,
-0x8800,
-0x8800,
-0x5000,
-0x2000,
-0x2000,
-0x2000,
-0x2000,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 90 (0x5a):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- | |
- |***** |
- | * |
- | * |
- | * |
- | * |
- |* |
- |***** |
- | |
- | |
- | |
- +------+
-*/
-0x0000,
-0x0000,
-0xf800,
-0x0800,
-0x1000,
-0x2000,
-0x4000,
-0x8000,
-0xf800,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 91 (0x5b):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | *** |
- | * |
- | * |
- | * |
- | * |
- | * |
- | * |
- | * |
- | * |
- | * |
- | *** |
- | |
- +------+
-*/
-0x3800,
-0x2000,
-0x2000,
-0x2000,
-0x2000,
-0x2000,
-0x2000,
-0x2000,
-0x2000,
-0x2000,
-0x3800,
-0x0000,
-
-/* Character 92 (0x5c):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- |* |
- |* |
- | * |
- | * |
- | * |
- | * |
- | * |
- | * |
- | * |
- | * |
- | |
- | |
- +------+
-*/
-0x8000,
-0x8000,
-0x4000,
-0x4000,
-0x2000,
-0x2000,
-0x1000,
-0x1000,
-0x0800,
-0x0800,
-0x0000,
-0x0000,
-
-/* Character 93 (0x5d):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | *** |
- | * |
- | * |
- | * |
- | * |
- | * |
- | * |
- | * |
- | * |
- | * |
- | *** |
- | |
- +------+
-*/
-0x7000,
-0x1000,
-0x1000,
-0x1000,
-0x1000,
-0x1000,
-0x1000,
-0x1000,
-0x1000,
-0x1000,
-0x7000,
-0x0000,
-
-/* Character 94 (0x5e):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- | * |
- | * * |
- |* * |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- +------+
-*/
-0x0000,
-0x2000,
-0x5000,
-0x8800,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 95 (0x5f):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- |******|
- | |
- | |
- +------+
-*/
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0xfc00,
-0x0000,
-0x0000,
-
-/* Character 96 (0x60):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- | * |
- | * |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- +------+
-*/
-0x0000,
-0x2000,
-0x1000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 97 (0x61):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- | |
- | |
- | |
- | **** |
- |* * |
- |* * |
- |* ** |
- | ** * |
- | |
- | |
- | |
- +------+
-*/
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x7800,
-0x8800,
-0x8800,
-0x9800,
-0x6800,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 98 (0x62):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- |* |
- |* |
- |* |
- |**** |
- |* * |
- |* * |
- |* * |
- |**** |
- | |
- | |
- | |
- +------+
-*/
-0x0000,
-0x8000,
-0x8000,
-0x8000,
-0xf000,
-0x8800,
-0x8800,
-0x8800,
-0xf000,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 99 (0x63):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- | |
- | |
- | |
- | **** |
- |* |
- |* |
- |* |
- | **** |
- | |
- | |
- | |
- +------+
-*/
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x7800,
-0x8000,
-0x8000,
-0x8000,
-0x7800,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 100 (0x64):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- | * |
- | * |
- | * |
- | **** |
- |* * |
- |* * |
- |* * |
- | **** |
- | |
- | |
- | |
- +------+
-*/
-0x0000,
-0x0800,
-0x0800,
-0x0800,
-0x7800,
-0x8800,
-0x8800,
-0x8800,
-0x7800,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 101 (0x65):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- | |
- | |
- | |
- | *** |
- |* * |
- |***** |
- |* |
- | *** |
- | |
- | |
- | |
- +------+
-*/
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x7000,
-0x8800,
-0xf800,
-0x8000,
-0x7000,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 102 (0x66):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- | *** |
- | * |
- | * |
- |**** |
- | * |
- | * |
- | * |
- | * |
- | |
- | |
- | |
- +------+
-*/
-0x0000,
-0x3800,
-0x4000,
-0x4000,
-0xf000,
-0x4000,
-0x4000,
-0x4000,
-0x4000,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 103 (0x67):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- | |
- | |
- | |
- | **** |
- |* * |
- |* * |
- |* * |
- | **** |
- | * |
- | * |
- | *** |
- +------+
-*/
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x7800,
-0x8800,
-0x8800,
-0x8800,
-0x7800,
-0x0800,
-0x0800,
-0x7000,
-
-/* Character 104 (0x68):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- |* |
- |* |
- |* |
- |**** |
- |* * |
- |* * |
- |* * |
- |* * |
- | |
- | |
- | |
- +------+
-*/
-0x0000,
-0x8000,
-0x8000,
-0x8000,
-0xf000,
-0x8800,
-0x8800,
-0x8800,
-0x8800,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 105 (0x69):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- | * |
- | * |
- | |
- | ** |
- | * |
- | * |
- | * |
- | *** |
- | |
- | |
- | |
- +------+
-*/
-0x0000,
-0x2000,
-0x2000,
-0x0000,
-0x6000,
-0x2000,
-0x2000,
-0x2000,
-0x7000,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 106 (0x6a):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- | * |
- | * |
- | |
- | *** |
- | * |
- | * |
- | * |
- | * |
- | * |
- | * |
- | *** |
- +------+
-*/
-0x0000,
-0x0800,
-0x0800,
-0x0000,
-0x3800,
-0x0800,
-0x0800,
-0x0800,
-0x0800,
-0x0800,
-0x0800,
-0x7000,
-
-/* Character 107 (0x6b):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- | * |
- | * |
- | * |
- | * * |
- | * * |
- | ** |
- | * * |
- | * * |
- | |
- | |
- | |
- +------+
-*/
-0x0000,
-0x4000,
-0x4000,
-0x4000,
-0x4800,
-0x5000,
-0x6000,
-0x5000,
-0x4800,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 108 (0x6c):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- | ** |
- | * |
- | * |
- | * |
- | * |
- | * |
- | * |
- | *** |
- | |
- | |
- | |
- +------+
-*/
-0x0000,
-0x6000,
-0x2000,
-0x2000,
-0x2000,
-0x2000,
-0x2000,
-0x2000,
-0x7000,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 109 (0x6d):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- | |
- | |
- | |
- |** * |
- |* * * |
- |* * * |
- |* * * |
- |* * |
- | |
- | |
- | |
- +------+
-*/
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0xd000,
-0xa800,
-0xa800,
-0xa800,
-0x8800,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 110 (0x6e):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- | |
- | |
- | |
- |* ** |
- |** * |
- |* * |
- |* * |
- |* * |
- | |
- | |
- | |
- +------+
-*/
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0xb000,
-0xc800,
-0x8800,
-0x8800,
-0x8800,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 111 (0x6f):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- | |
- | |
- | |
- | *** |
- |* * |
- |* * |
- |* * |
- | *** |
- | |
- | |
- | |
- +------+
-*/
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x7000,
-0x8800,
-0x8800,
-0x8800,
-0x7000,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 112 (0x70):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- | |
- | |
- | |
- |**** |
- |* * |
- |* * |
- |* * |
- |**** |
- |* |
- |* |
- |* |
- +------+
-*/
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0xf000,
-0x8800,
-0x8800,
-0x8800,
-0xf000,
-0x8000,
-0x8000,
-0x8000,
-
-/* Character 113 (0x71):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- | |
- | |
- | |
- | **** |
- |* * |
- |* * |
- |* * |
- | **** |
- | * |
- | * |
- | * |
- +------+
-*/
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x7800,
-0x8800,
-0x8800,
-0x8800,
-0x7800,
-0x0800,
-0x0800,
-0x0800,
-
-/* Character 114 (0x72):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- | |
- | |
- | |
- | * ** |
- | ** |
- | * |
- | * |
- | * |
- | |
- | |
- | |
- +------+
-*/
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x5800,
-0x6000,
-0x4000,
-0x4000,
-0x4000,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 115 (0x73):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- | |
- | |
- | |
- | **** |
- |* |
- | *** |
- | * |
- |**** |
- | |
- | |
- | |
- +------+
-*/
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x7800,
-0x8000,
-0x7000,
-0x0800,
-0xf000,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 116 (0x74):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- | * |
- | * |
- | * |
- | *** |
- | * |
- | * |
- | * |
- | ** |
- | |
- | |
- | |
- +------+
-*/
-0x0000,
-0x2000,
-0x2000,
-0x2000,
-0x7000,
-0x2000,
-0x2000,
-0x2000,
-0x1800,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 117 (0x75):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- | |
- | |
- | |
- |* * |
- |* * |
- |* * |
- |* ** |
- | ** * |
- | |
- | |
- | |
- +------+
-*/
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x8800,
-0x8800,
-0x8800,
-0x9800,
-0x6800,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 118 (0x76):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- | |
- | |
- | |
- |** ** |
- | * * |
- | * * |
- | * |
- | * |
- | |
- | |
- | |
- +------+
-*/
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0xd800,
-0x5000,
-0x5000,
-0x2000,
-0x2000,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 119 (0x77):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- | |
- | |
- | |
- |* * |
- |* * * |
- |* * * |
- |* * * |
- | * * |
- | |
- | |
- | |
- +------+
-*/
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x8800,
-0xa800,
-0xa800,
-0xa800,
-0x5000,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 120 (0x78):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- | |
- | |
- | |
- |* * |
- | * * |
- | * |
- | * * |
- |* * |
- | |
- | |
- | |
- +------+
-*/
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x8800,
-0x5000,
-0x2000,
-0x5000,
-0x8800,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 121 (0x79):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- | |
- | |
- | |
- |* * |
- |* * |
- |* * |
- |* * |
- | **** |
- | * |
- | * |
- | *** |
- +------+
-*/
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x8800,
-0x8800,
-0x8800,
-0x8800,
-0x7800,
-0x0800,
-0x0800,
-0x7000,
-
-/* Character 122 (0x7a):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- | |
- | |
- | |
- |***** |
- | * |
- | * |
- | * |
- |***** |
- | |
- | |
- | |
- +------+
-*/
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0xf800,
-0x1000,
-0x2000,
-0x4000,
-0xf800,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 123 (0x7b):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | * |
- | * |
- | * |
- | * |
- | * |
- | * |
- | * |
- | * |
- | * |
- | * |
- | * |
- | |
- +------+
-*/
-0x0800,
-0x1000,
-0x1000,
-0x1000,
-0x1000,
-0x2000,
-0x1000,
-0x1000,
-0x1000,
-0x1000,
-0x0800,
-0x0000,
-
-/* Character 124 (0x7c):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | * |
- | * |
- | * |
- | * |
- | * |
- | * |
- | * |
- | * |
- | * |
- | * |
- | * |
- | |
- +------+
-*/
-0x2000,
-0x2000,
-0x2000,
-0x2000,
-0x2000,
-0x2000,
-0x2000,
-0x2000,
-0x2000,
-0x2000,
-0x2000,
-0x0000,
-
-/* Character 125 (0x7d):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | * |
- | * |
- | * |
- | * |
- | * |
- | * |
- | * |
- | * |
- | * |
- | * |
- | * |
- | |
- +------+
-*/
-0x4000,
-0x2000,
-0x2000,
-0x2000,
-0x2000,
-0x1000,
-0x2000,
-0x2000,
-0x2000,
-0x2000,
-0x4000,
-0x0000,
-
-/* Character 126 (0x7e):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- | |
- | |
- | |
- | * |
- |* * * |
- | * |
- | |
- | |
- | |
- | |
- | |
- +------+
-*/
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x4000,
-0xa800,
-0x1000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 160 (0xa0):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- +------+
-*/
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 161 (0xa1):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- | * |
- | |
- | * |
- | * |
- | * |
- | * |
- | * |
- | * |
- | |
- | |
- | |
- +------+
-*/
-0x0000,
-0x2000,
-0x0000,
-0x2000,
-0x2000,
-0x2000,
-0x2000,
-0x2000,
-0x2000,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 162 (0xa2):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- | |
- | |
- | * |
- | *** |
- |* * * |
- |* * |
- |* * * |
- | *** |
- | * |
- | |
- | |
- +------+
-*/
-0x0000,
-0x0000,
-0x0000,
-0x2000,
-0x7000,
-0xa800,
-0xa000,
-0xa800,
-0x7000,
-0x2000,
-0x0000,
-0x0000,
-
-/* Character 163 (0xa3):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- | ** |
- | * * |
- | * |
- |*** |
- | * |
- | * |
- | * * |
- |* ** |
- | |
- | |
- | |
- +------+
-*/
-0x0000,
-0x3000,
-0x4800,
-0x4000,
-0xe000,
-0x4000,
-0x4000,
-0x4800,
-0xb000,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 164 (0xa4):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- | |
- | |
- | |
- |* * |
- | *** |
- | * * |
- | *** |
- |* * |
- | |
- | |
- | |
- +------+
-*/
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x8800,
-0x7000,
-0x5000,
-0x7000,
-0x8800,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 165 (0xa5):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- | |
- |* * |
- | * * |
- | * |
- | *** |
- | * |
- | *** |
- | * |
- | |
- | |
- | |
- +------+
-*/
-0x0000,
-0x0000,
-0x8800,
-0x5000,
-0x2000,
-0x7000,
-0x2000,
-0x7000,
-0x2000,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 166 (0xa6):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- | |
- | * |
- | * |
- | * |
- | |
- | * |
- | * |
- | * |
- | |
- | |
- | |
- +------+
-*/
-0x0000,
-0x0000,
-0x2000,
-0x2000,
-0x2000,
-0x0000,
-0x2000,
-0x2000,
-0x2000,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 167 (0xa7):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | ** |
- | * * |
- | * |
- | ** |
- | * * |
- | * * |
- | * * |
- | ** |
- | * |
- | * * |
- | ** |
- | |
- +------+
-*/
-0x3000,
-0x4800,
-0x4000,
-0x3000,
-0x4800,
-0x4800,
-0x4800,
-0x3000,
-0x0800,
-0x4800,
-0x3000,
-0x0000,
-
-/* Character 168 (0xa8):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- | * * |
- | * * |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- +------+
-*/
-0x0000,
-0x5000,
-0x5000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 169 (0xa9):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- | **** |
- |* *|
- |* ** *|
- |* * *|
- |* * *|
- |* ** *|
- |* *|
- | **** |
- | |
- | |
- | |
- +------+
-*/
-0x0000,
-0x7800,
-0x8400,
-0xb400,
-0xa400,
-0xa400,
-0xb400,
-0x8400,
-0x7800,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 170 (0xaa):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | ** |
- | * |
- | *** |
- | * * |
- | *** |
- | |
- | **** |
- | |
- | |
- | |
- | |
- | |
- +------+
-*/
-0x3000,
-0x0800,
-0x3800,
-0x4800,
-0x3800,
-0x0000,
-0x7800,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 171 (0xab):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- | |
- | |
- | * * |
- | * * |
- |* * |
- | * * |
- | * * |
- | |
- | |
- | |
- | |
- +------+
-*/
-0x0000,
-0x0000,
-0x0000,
-0x2800,
-0x5000,
-0xa000,
-0x5000,
-0x2800,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 172 (0xac):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- | |
- | |
- | |
- | |
- | **** |
- | * |
- | |
- | |
- | |
- | |
- | |
- +------+
-*/
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x7800,
-0x0800,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 173 (0xad):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- | |
- | |
- | |
- | |
- | **** |
- | |
- | |
- | |
- | |
- | |
- | |
- +------+
-*/
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x7800,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 174 (0xae):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- | **** |
- |* *|
- |* ** *|
- |* * **|
- |* ** *|
- |* * **|
- |* *|
- | **** |
- | |
- | |
- | |
- +------+
-*/
-0x0000,
-0x7800,
-0x8400,
-0xb400,
-0xac00,
-0xb400,
-0xac00,
-0x8400,
-0x7800,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 175 (0xaf):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- | |
- |***** |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- +------+
-*/
-0x0000,
-0x0000,
-0xf800,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 176 (0xb0):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- | ** |
- | * * |
- | * * |
- | ** |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- +------+
-*/
-0x0000,
-0x3000,
-0x4800,
-0x4800,
-0x3000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 177 (0xb1):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- | |
- | * |
- | * |
- |***** |
- | * |
- | * |
- | |
- |***** |
- | |
- | |
- | |
- +------+
-*/
-0x0000,
-0x0000,
-0x2000,
-0x2000,
-0xf800,
-0x2000,
-0x2000,
-0x0000,
-0xf800,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 178 (0xb2):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | ** |
- | * |
- | * |
- | * |
- | *** |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- +------+
-*/
-0x6000,
-0x1000,
-0x2000,
-0x4000,
-0x7000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 179 (0xb3):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | ** |
- | * |
- | * |
- | * |
- | ** |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- +------+
-*/
-0x6000,
-0x1000,
-0x2000,
-0x1000,
-0x6000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 180 (0xb4):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- | * |
- | * |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- +------+
-*/
-0x0000,
-0x1000,
-0x2000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 181 (0xb5):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- | |
- | |
- | |
- |* * |
- |* * |
- |* * |
- |** * |
- |* ** |
- |* |
- |* |
- | |
- +------+
-*/
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x8800,
-0x8800,
-0x8800,
-0xc800,
-0xb000,
-0x8000,
-0x8000,
-0x0000,
-
-/* Character 182 (0xb6):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- | |
- | **** |
- |*** * |
- |*** * |
- | ** * |
- | * * |
- | * * |
- | * * |
- | |
- | |
- | |
- +------+
-*/
-0x0000,
-0x0000,
-0x7800,
-0xe800,
-0xe800,
-0x6800,
-0x2800,
-0x2800,
-0x2800,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 183 (0xb7):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- | |
- | |
- | |
- | |
- | |
- | ** |
- | |
- | |
- | |
- | |
- | |
- +------+
-*/
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x3000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 184 (0xb8):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | * |
- | * |
- | |
- +------+
-*/
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x1000,
-0x2000,
-0x0000,
-
-/* Character 185 (0xb9):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | * |
- | ** |
- | * |
- | * |
- | * |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- +------+
-*/
-0x2000,
-0x6000,
-0x2000,
-0x2000,
-0x2000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 186 (0xba):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | ** |
- | * * |
- | * * |
- | * * |
- | ** |
- | |
- | **** |
- | |
- | |
- | |
- | |
- | |
- +------+
-*/
-0x3000,
-0x4800,
-0x4800,
-0x4800,
-0x3000,
-0x0000,
-0x7800,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 187 (0xbb):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- | |
- | |
- |* * |
- | * * |
- | * * |
- | * * |
- |* * |
- | |
- | |
- | |
- | |
- +------+
-*/
-0x0000,
-0x0000,
-0x0000,
-0xa000,
-0x5000,
-0x2800,
-0x5000,
-0xa000,
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 188 (0xbc):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- | * |
- | * |
- | * |
- | * * |
- | * |
- | * * |
- | *** |
- | * |
- | |
- | |
- | |
- +------+
-*/
-0x0000,
-0x4000,
-0x4000,
-0x4000,
-0x4800,
-0x1000,
-0x2800,
-0x3800,
-0x0800,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 189 (0xbd):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- | * |
- | * |
- | * |
- | *** |
- | * |
- | * |
- | * |
- | *** |
- | |
- | |
- | |
- +------+
-*/
-0x0000,
-0x4000,
-0x4000,
-0x4000,
-0x7000,
-0x0800,
-0x1000,
-0x2000,
-0x3800,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 190 (0xbe):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- |** |
- | * |
- | * |
- |** * |
- | * |
- | * * |
- | *** |
- | * |
- | |
- | |
- | |
- +------+
-*/
-0x0000,
-0xc000,
-0x4000,
-0x2000,
-0xc800,
-0x1000,
-0x2800,
-0x3800,
-0x0800,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 191 (0xbf):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- | * |
- | |
- | * |
- | * |
- | * |
- |* |
- |* * |
- | *** |
- | |
- | |
- | |
- +------+
-*/
-0x0000,
-0x2000,
-0x0000,
-0x2000,
-0x2000,
-0x4000,
-0x8000,
-0x8800,
-0x7000,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 192 (0xc0):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | * |
- | * |
- | |
- | *** |
- |* * |
- |* * |
- |***** |
- |* * |
- |* * |
- | |
- | |
- | |
- +------+
-*/
-0x4000,
-0x2000,
-0x0000,
-0x7000,
-0x8800,
-0x8800,
-0xf800,
-0x8800,
-0x8800,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 193 (0xc1):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | * |
- | * |
- | |
- | *** |
- |* * |
- |* * |
- |***** |
- |* * |
- |* * |
- | |
- | |
- | |
- +------+
-*/
-0x1000,
-0x2000,
-0x0000,
-0x7000,
-0x8800,
-0x8800,
-0xf800,
-0x8800,
-0x8800,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 194 (0xc2):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | * |
- | * * |
- | |
- | *** |
- |* * |
- |* * |
- |***** |
- |* * |
- |* * |
- | |
- | |
- | |
- +------+
-*/
-0x2000,
-0x5000,
-0x0000,
-0x7000,
-0x8800,
-0x8800,
-0xf800,
-0x8800,
-0x8800,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 195 (0xc3):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | * * |
- | * * |
- | |
- | *** |
- |* * |
- |* * |
- |***** |
- |* * |
- |* * |
- | |
- | |
- | |
- +------+
-*/
-0x2800,
-0x5000,
-0x0000,
-0x7000,
-0x8800,
-0x8800,
-0xf800,
-0x8800,
-0x8800,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 196 (0xc4):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- | * * |
- | |
- | *** |
- |* * |
- |* * |
- |***** |
- |* * |
- |* * |
- | |
- | |
- | |
- +------+
-*/
-0x0000,
-0x5000,
-0x0000,
-0x7000,
-0x8800,
-0x8800,
-0xf800,
-0x8800,
-0x8800,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 197 (0xc5):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | * |
- | * * |
- | * |
- | *** |
- |* * |
- |* * |
- |***** |
- |* * |
- |* * |
- | |
- | |
- | |
- +------+
-*/
-0x2000,
-0x5000,
-0x2000,
-0x7000,
-0x8800,
-0x8800,
-0xf800,
-0x8800,
-0x8800,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 198 (0xc6):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- | |
- | **** |
- |* * |
- |* * |
- |* *** |
- |*** |
- |* * |
- |* *** |
- | |
- | |
- | |
- +------+
-*/
-0x0000,
-0x0000,
-0x7800,
-0xa000,
-0xa000,
-0xb800,
-0xe000,
-0xa000,
-0xb800,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 199 (0xc7):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- | |
- | *** |
- |* * |
- |* |
- |* |
- |* |
- |* * |
- | *** |
- | * |
- | * |
- | |
- +------+
-*/
-0x0000,
-0x0000,
-0x7000,
-0x8800,
-0x8000,
-0x8000,
-0x8000,
-0x8800,
-0x7000,
-0x2000,
-0x4000,
-0x0000,
-
-/* Character 200 (0xc8):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | * |
- | * |
- | |
- |***** |
- |* |
- |**** |
- |* |
- |* |
- |***** |
- | |
- | |
- | |
- +------+
-*/
-0x4000,
-0x2000,
-0x0000,
-0xf800,
-0x8000,
-0xf000,
-0x8000,
-0x8000,
-0xf800,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 201 (0xc9):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | * |
- | * |
- | |
- |***** |
- |* |
- |**** |
- |* |
- |* |
- |***** |
- | |
- | |
- | |
- +------+
-*/
-0x1000,
-0x2000,
-0x0000,
-0xf800,
-0x8000,
-0xf000,
-0x8000,
-0x8000,
-0xf800,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 202 (0xca):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | * |
- | * * |
- | |
- |***** |
- |* |
- |**** |
- |* |
- |* |
- |***** |
- | |
- | |
- | |
- +------+
-*/
-0x2000,
-0x5000,
-0x0000,
-0xf800,
-0x8000,
-0xf000,
-0x8000,
-0x8000,
-0xf800,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 203 (0xcb):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- | * * |
- | |
- |***** |
- |* |
- |**** |
- |* |
- |* |
- |***** |
- | |
- | |
- | |
- +------+
-*/
-0x0000,
-0x5000,
-0x0000,
-0xf800,
-0x8000,
-0xf000,
-0x8000,
-0x8000,
-0xf800,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 204 (0xcc):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | * |
- | * |
- | |
- |***** |
- | * |
- | * |
- | * |
- | * |
- |***** |
- | |
- | |
- | |
- +------+
-*/
-0x4000,
-0x2000,
-0x0000,
-0xf800,
-0x2000,
-0x2000,
-0x2000,
-0x2000,
-0xf800,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 205 (0xcd):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | * |
- | * |
- | |
- |***** |
- | * |
- | * |
- | * |
- | * |
- |***** |
- | |
- | |
- | |
- +------+
-*/
-0x1000,
-0x2000,
-0x0000,
-0xf800,
-0x2000,
-0x2000,
-0x2000,
-0x2000,
-0xf800,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 206 (0xce):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | * |
- | * * |
- | |
- |***** |
- | * |
- | * |
- | * |
- | * |
- |***** |
- | |
- | |
- | |
- +------+
-*/
-0x2000,
-0x5000,
-0x0000,
-0xf800,
-0x2000,
-0x2000,
-0x2000,
-0x2000,
-0xf800,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 207 (0xcf):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- | * * |
- | |
- |***** |
- | * |
- | * |
- | * |
- | * |
- |***** |
- | |
- | |
- | |
- +------+
-*/
-0x0000,
-0x5000,
-0x0000,
-0xf800,
-0x2000,
-0x2000,
-0x2000,
-0x2000,
-0xf800,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 208 (0xd0):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- | |
- | *** |
- | * * |
- | * *|
- |*** *|
- | * *|
- | * * |
- | *** |
- | |
- | |
- | |
- +------+
-*/
-0x0000,
-0x0000,
-0x7000,
-0x4800,
-0x4400,
-0xe400,
-0x4400,
-0x4800,
-0x7000,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 209 (0xd1):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | * * |
- | * * |
- | |
- |* * |
- |** * |
- |* * * |
- |* ** |
- |* * |
- |* * |
- | |
- | |
- | |
- +------+
-*/
-0x2800,
-0x5000,
-0x0000,
-0x8800,
-0xc800,
-0xa800,
-0x9800,
-0x8800,
-0x8800,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 210 (0xd2):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | * |
- | * |
- | |
- | *** |
- |* * |
- |* * |
- |* * |
- |* * |
- | *** |
- | |
- | |
- | |
- +------+
-*/
-0x4000,
-0x2000,
-0x0000,
-0x7000,
-0x8800,
-0x8800,
-0x8800,
-0x8800,
-0x7000,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 211 (0xd3):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | * |
- | * |
- | |
- | *** |
- |* * |
- |* * |
- |* * |
- |* * |
- | *** |
- | |
- | |
- | |
- +------+
-*/
-0x1000,
-0x2000,
-0x0000,
-0x7000,
-0x8800,
-0x8800,
-0x8800,
-0x8800,
-0x7000,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 212 (0xd4):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | * |
- | * * |
- | |
- | *** |
- |* * |
- |* * |
- |* * |
- |* * |
- | *** |
- | |
- | |
- | |
- +------+
-*/
-0x2000,
-0x5000,
-0x0000,
-0x7000,
-0x8800,
-0x8800,
-0x8800,
-0x8800,
-0x7000,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 213 (0xd5):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | * * |
- | * * |
- | |
- | *** |
- |* * |
- |* * |
- |* * |
- |* * |
- | *** |
- | |
- | |
- | |
- +------+
-*/
-0x2800,
-0x5000,
-0x0000,
-0x7000,
-0x8800,
-0x8800,
-0x8800,
-0x8800,
-0x7000,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 214 (0xd6):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- | * * |
- | |
- | *** |
- |* * |
- |* * |
- |* * |
- |* * |
- | *** |
- | |
- | |
- | |
- +------+
-*/
-0x0000,
-0x5000,
-0x0000,
-0x7000,
-0x8800,
-0x8800,
-0x8800,
-0x8800,
-0x7000,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 215 (0xd7):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- | |
- | |
- | |
- |* * |
- | * * |
- | * |
- | * * |
- |* * |
- | |
- | |
- | |
- +------+
-*/
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x8800,
-0x5000,
-0x2000,
-0x5000,
-0x8800,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 216 (0xd8):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- | * |
- | **** |
- |* ** |
- |* * * |
- |* * * |
- |* * * |
- |** * |
- |**** |
- |* |
- | |
- | |
- +------+
-*/
-0x0000,
-0x0800,
-0x7800,
-0x9800,
-0xa800,
-0xa800,
-0xa800,
-0xc800,
-0xf000,
-0x8000,
-0x0000,
-0x0000,
-
-/* Character 217 (0xd9):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | * |
- | * |
- | |
- |* * |
- |* * |
- |* * |
- |* * |
- |* * |
- | *** |
- | |
- | |
- | |
- +------+
-*/
-0x4000,
-0x2000,
-0x0000,
-0x8800,
-0x8800,
-0x8800,
-0x8800,
-0x8800,
-0x7000,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 218 (0xda):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | * |
- | * |
- | |
- |* * |
- |* * |
- |* * |
- |* * |
- |* * |
- | *** |
- | |
- | |
- | |
- +------+
-*/
-0x1000,
-0x2000,
-0x0000,
-0x8800,
-0x8800,
-0x8800,
-0x8800,
-0x8800,
-0x7000,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 219 (0xdb):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | * |
- | * * |
- | |
- |* * |
- |* * |
- |* * |
- |* * |
- |* * |
- | *** |
- | |
- | |
- | |
- +------+
-*/
-0x2000,
-0x5000,
-0x0000,
-0x8800,
-0x8800,
-0x8800,
-0x8800,
-0x8800,
-0x7000,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 220 (0xdc):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- | * * |
- | |
- |* * |
- |* * |
- |* * |
- |* * |
- |* * |
- | *** |
- | |
- | |
- | |
- +------+
-*/
-0x0000,
-0x5000,
-0x0000,
-0x8800,
-0x8800,
-0x8800,
-0x8800,
-0x8800,
-0x7000,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 221 (0xdd):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | * |
- | * |
- | |
- |* * |
- | * * |
- | * |
- | * |
- | * |
- | * |
- | |
- | |
- | |
- +------+
-*/
-0x1000,
-0x2000,
-0x0000,
-0x8800,
-0x5000,
-0x2000,
-0x2000,
-0x2000,
-0x2000,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 222 (0xde):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- |* |
- |**** |
- |* * |
- |* * |
- |* * |
- |**** |
- |* |
- |* |
- | |
- | |
- | |
- +------+
-*/
-0x0000,
-0x8000,
-0xf000,
-0x8800,
-0x8800,
-0x8800,
-0xf000,
-0x8000,
-0x8000,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 223 (0xdf):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- | ** |
- | * * |
- | * * |
- |** * |
- | * * |
- | * * |
- | * * |
- | * * |
- | |
- | |
- | |
- +------+
-*/
-0x0000,
-0x3000,
-0x4800,
-0x4800,
-0xd000,
-0x5000,
-0x4800,
-0x4800,
-0x5000,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 224 (0xe0):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- | * |
- | * |
- | |
- | **** |
- |* * |
- |* * |
- |* ** |
- | ** * |
- | |
- | |
- | |
- +------+
-*/
-0x0000,
-0x4000,
-0x2000,
-0x0000,
-0x7800,
-0x8800,
-0x8800,
-0x9800,
-0x6800,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 225 (0xe1):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- | * |
- | * |
- | |
- | **** |
- |* * |
- |* * |
- |* ** |
- | ** * |
- | |
- | |
- | |
- +------+
-*/
-0x0000,
-0x1000,
-0x2000,
-0x0000,
-0x7800,
-0x8800,
-0x8800,
-0x9800,
-0x6800,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 226 (0xe2):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- | * |
- | * * |
- | |
- | **** |
- |* * |
- |* * |
- |* ** |
- | ** * |
- | |
- | |
- | |
- +------+
-*/
-0x0000,
-0x2000,
-0x5000,
-0x0000,
-0x7800,
-0x8800,
-0x8800,
-0x9800,
-0x6800,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 227 (0xe3):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- | * * |
- | * * |
- | |
- | **** |
- |* * |
- |* * |
- |* ** |
- | ** * |
- | |
- | |
- | |
- +------+
-*/
-0x0000,
-0x2800,
-0x5000,
-0x0000,
-0x7800,
-0x8800,
-0x8800,
-0x9800,
-0x6800,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 228 (0xe4):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- | |
- | * * |
- | |
- | **** |
- |* * |
- |* * |
- |* ** |
- | ** * |
- | |
- | |
- | |
- +------+
-*/
-0x0000,
-0x0000,
-0x5000,
-0x0000,
-0x7800,
-0x8800,
-0x8800,
-0x9800,
-0x6800,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 229 (0xe5):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | * |
- | * * |
- | * |
- | |
- | **** |
- |* * |
- |* * |
- |* ** |
- | ** * |
- | |
- | |
- | |
- +------+
-*/
-0x2000,
-0x5000,
-0x2000,
-0x0000,
-0x7800,
-0x8800,
-0x8800,
-0x9800,
-0x6800,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 230 (0xe6):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- | |
- | |
- | |
- | *** |
- | * * |
- | *** |
- |* * |
- | **** |
- | |
- | |
- | |
- +------+
-*/
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x7000,
-0x2800,
-0x7000,
-0xa000,
-0x7800,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 231 (0xe7):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- | |
- | |
- | |
- | **** |
- |* |
- |* |
- |* |
- | **** |
- | * |
- | * |
- | |
- +------+
-*/
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x7800,
-0x8000,
-0x8000,
-0x8000,
-0x7800,
-0x2000,
-0x4000,
-0x0000,
-
-/* Character 232 (0xe8):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- | * |
- | * |
- | |
- | *** |
- |* * |
- |***** |
- |* |
- | *** |
- | |
- | |
- | |
- +------+
-*/
-0x0000,
-0x4000,
-0x2000,
-0x0000,
-0x7000,
-0x8800,
-0xf800,
-0x8000,
-0x7000,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 233 (0xe9):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- | * |
- | * |
- | |
- | *** |
- |* * |
- |***** |
- |* |
- | *** |
- | |
- | |
- | |
- +------+
-*/
-0x0000,
-0x1000,
-0x2000,
-0x0000,
-0x7000,
-0x8800,
-0xf800,
-0x8000,
-0x7000,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 234 (0xea):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- | * |
- | * * |
- | |
- | *** |
- |* * |
- |***** |
- |* |
- | *** |
- | |
- | |
- | |
- +------+
-*/
-0x0000,
-0x2000,
-0x5000,
-0x0000,
-0x7000,
-0x8800,
-0xf800,
-0x8000,
-0x7000,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 235 (0xeb):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- | |
- | * * |
- | |
- | *** |
- |* * |
- |***** |
- |* |
- | *** |
- | |
- | |
- | |
- +------+
-*/
-0x0000,
-0x0000,
-0x5000,
-0x0000,
-0x7000,
-0x8800,
-0xf800,
-0x8000,
-0x7000,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 236 (0xec):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- | * |
- | * |
- | |
- | ** |
- | * |
- | * |
- | * |
- | *** |
- | |
- | |
- | |
- +------+
-*/
-0x0000,
-0x4000,
-0x2000,
-0x0000,
-0x6000,
-0x2000,
-0x2000,
-0x2000,
-0x7000,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 237 (0xed):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- | * |
- | * |
- | |
- | ** |
- | * |
- | * |
- | * |
- | *** |
- | |
- | |
- | |
- +------+
-*/
-0x0000,
-0x2000,
-0x4000,
-0x0000,
-0x6000,
-0x2000,
-0x2000,
-0x2000,
-0x7000,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 238 (0xee):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- | * |
- | * * |
- | |
- | ** |
- | * |
- | * |
- | * |
- | *** |
- | |
- | |
- | |
- +------+
-*/
-0x0000,
-0x2000,
-0x5000,
-0x0000,
-0x6000,
-0x2000,
-0x2000,
-0x2000,
-0x7000,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 239 (0xef):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- | |
- | * * |
- | |
- | ** |
- | * |
- | * |
- | * |
- | *** |
- | |
- | |
- | |
- +------+
-*/
-0x0000,
-0x0000,
-0x5000,
-0x0000,
-0x6000,
-0x2000,
-0x2000,
-0x2000,
-0x7000,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 240 (0xf0):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- | * * |
- | * |
- | * * |
- | * |
- | **** |
- |* * |
- |* * |
- | *** |
- | |
- | |
- | |
- +------+
-*/
-0x0000,
-0x2800,
-0x1000,
-0x2800,
-0x0800,
-0x7800,
-0x8800,
-0x8800,
-0x7000,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 241 (0xf1):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- | * * |
- | * * |
- | |
- |* ** |
- |** * |
- |* * |
- |* * |
- |* * |
- | |
- | |
- | |
- +------+
-*/
-0x0000,
-0x2800,
-0x5000,
-0x0000,
-0xb000,
-0xc800,
-0x8800,
-0x8800,
-0x8800,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 242 (0xf2):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- | * |
- | * |
- | |
- | *** |
- |* * |
- |* * |
- |* * |
- | *** |
- | |
- | |
- | |
- +------+
-*/
-0x0000,
-0x4000,
-0x2000,
-0x0000,
-0x7000,
-0x8800,
-0x8800,
-0x8800,
-0x7000,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 243 (0xf3):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- | * |
- | * |
- | |
- | *** |
- |* * |
- |* * |
- |* * |
- | *** |
- | |
- | |
- | |
- +------+
-*/
-0x0000,
-0x1000,
-0x2000,
-0x0000,
-0x7000,
-0x8800,
-0x8800,
-0x8800,
-0x7000,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 244 (0xf4):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- | * |
- | * * |
- | |
- | *** |
- |* * |
- |* * |
- |* * |
- | *** |
- | |
- | |
- | |
- +------+
-*/
-0x0000,
-0x2000,
-0x5000,
-0x0000,
-0x7000,
-0x8800,
-0x8800,
-0x8800,
-0x7000,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 245 (0xf5):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- | * * |
- | * * |
- | |
- | *** |
- |* * |
- |* * |
- |* * |
- | *** |
- | |
- | |
- | |
- +------+
-*/
-0x0000,
-0x2800,
-0x5000,
-0x0000,
-0x7000,
-0x8800,
-0x8800,
-0x8800,
-0x7000,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 246 (0xf6):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- | |
- | * * |
- | |
- | *** |
- |* * |
- |* * |
- |* * |
- | *** |
- | |
- | |
- | |
- +------+
-*/
-0x0000,
-0x0000,
-0x5000,
-0x0000,
-0x7000,
-0x8800,
-0x8800,
-0x8800,
-0x7000,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 247 (0xf7):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- | |
- | |
- | |
- | * |
- | |
- |***** |
- | |
- | * |
- | |
- | |
- | |
- +------+
-*/
-0x0000,
-0x0000,
-0x0000,
-0x0000,
-0x2000,
-0x0000,
-0xf800,
-0x0000,
-0x2000,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 248 (0xf8):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- | |
- | |
- | * |
- | **** |
- |* ** |
- |* * * |
- |** * |
- |**** |
- |* |
- | |
- | |
- +------+
-*/
-0x0000,
-0x0000,
-0x0000,
-0x0800,
-0x7800,
-0x9800,
-0xa800,
-0xc800,
-0xf000,
-0x8000,
-0x0000,
-0x0000,
-
-/* Character 249 (0xf9):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- | * |
- | * |
- | |
- |* * |
- |* * |
- |* * |
- |* ** |
- | ** * |
- | |
- | |
- | |
- +------+
-*/
-0x0000,
-0x4000,
-0x2000,
-0x0000,
-0x8800,
-0x8800,
-0x8800,
-0x9800,
-0x6800,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 250 (0xfa):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- | * |
- | * |
- | |
- |* * |
- |* * |
- |* * |
- |* ** |
- | ** * |
- | |
- | |
- | |
- +------+
-*/
-0x0000,
-0x1000,
-0x2000,
-0x0000,
-0x8800,
-0x8800,
-0x8800,
-0x9800,
-0x6800,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 251 (0xfb):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- | * |
- | * * |
- | |
- |* * |
- |* * |
- |* * |
- |* ** |
- | ** * |
- | |
- | |
- | |
- +------+
-*/
-0x0000,
-0x2000,
-0x5000,
-0x0000,
-0x8800,
-0x8800,
-0x8800,
-0x9800,
-0x6800,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 252 (0xfc):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- | |
- | * * |
- | |
- |* * |
- |* * |
- |* * |
- |* ** |
- | ** * |
- | |
- | |
- | |
- +------+
-*/
-0x0000,
-0x0000,
-0x5000,
-0x0000,
-0x8800,
-0x8800,
-0x8800,
-0x9800,
-0x6800,
-0x0000,
-0x0000,
-0x0000,
-
-/* Character 253 (0xfd):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- | * |
- | * |
- | |
- |* * |
- |* * |
- |* * |
- |* * |
- | **** |
- | * |
- | * |
- | *** |
- +------+
-*/
-0x0000,
-0x1000,
-0x2000,
-0x0000,
-0x8800,
-0x8800,
-0x8800,
-0x8800,
-0x7800,
-0x0800,
-0x0800,
-0x7000,
-
-/* Character 254 (0xfe):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- |* |
- |* |
- |* |
- |* ** |
- |** * |
- |* * |
- |** * |
- |* ** |
- |* |
- |* |
- | |
- +------+
-*/
-0x0000,
-0x8000,
-0x8000,
-0x8000,
-0xb000,
-0xc800,
-0x8800,
-0xc800,
-0xb000,
-0x8000,
-0x8000,
-0x0000,
-
-/* Character 255 (0xff):
- width 6
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | |
- | |
- | * * |
- | |
- |* * |
- |* * |
- |* * |
- |* * |
- | **** |
- | * |
- | * |
- | *** |
- +------+
-*/
-0x0000,
-0x0000,
-0x5000,
-0x0000,
-0x8800,
-0x8800,
-0x8800,
-0x8800,
-0x7800,
-0x0800,
-0x0800,
-0x7000,
-};
-
-/* Character->glyph mapping. */
-static const unsigned long _sysfont_offset[] = {
- 0, /* (0x00) */
- 12, /* (0x01) */
- 24, /* (0x02) */
- 36, /* (0x03) */
- 48, /* (0x04) */
- 60, /* (0x05) */
- 72, /* (0x06) */
- 84, /* (0x07) */
- 96, /* (0x08) */
- 108, /* (0x09) */
- 120, /* (0x0a) */
- 132, /* (0x0b) */
- 144, /* (0x0c) */
- 156, /* (0x0d) */
- 168, /* (0x0e) */
- 180, /* (0x0f) */
- 192, /* (0x10) */
- 204, /* (0x11) */
- 216, /* (0x12) */
- 228, /* (0x13) */
- 240, /* (0x14) */
- 252, /* (0x15) */
- 264, /* (0x16) */
- 276, /* (0x17) */
- 288, /* (0x18) */
- 300, /* (0x19) */
- 312, /* (0x1a) */
- 324, /* (0x1b) */
- 336, /* (0x1c) */
- 348, /* (0x1d) */
- 360, /* (0x1e) */
- 372, /* (0x1f) */
- 384, /* (0x20) */
- 396, /* (0x21) */
- 408, /* (0x22) */
- 420, /* (0x23) */
- 432, /* (0x24) */
- 444, /* (0x25) */
- 456, /* (0x26) */
- 468, /* (0x27) */
- 480, /* (0x28) */
- 492, /* (0x29) */
- 504, /* (0x2a) */
- 516, /* (0x2b) */
- 528, /* (0x2c) */
- 540, /* (0x2d) */
- 552, /* (0x2e) */
- 564, /* (0x2f) */
- 576, /* (0x30) */
- 588, /* (0x31) */
- 600, /* (0x32) */
- 612, /* (0x33) */
- 624, /* (0x34) */
- 636, /* (0x35) */
- 648, /* (0x36) */
- 660, /* (0x37) */
- 672, /* (0x38) */
- 684, /* (0x39) */
- 696, /* (0x3a) */
- 708, /* (0x3b) */
- 720, /* (0x3c) */
- 732, /* (0x3d) */
- 744, /* (0x3e) */
- 756, /* (0x3f) */
- 768, /* (0x40) */
- 780, /* (0x41) */
- 792, /* (0x42) */
- 804, /* (0x43) */
- 816, /* (0x44) */
- 828, /* (0x45) */
- 840, /* (0x46) */
- 852, /* (0x47) */
- 864, /* (0x48) */
- 876, /* (0x49) */
- 888, /* (0x4a) */
- 900, /* (0x4b) */
- 912, /* (0x4c) */
- 924, /* (0x4d) */
- 936, /* (0x4e) */
- 948, /* (0x4f) */
- 960, /* (0x50) */
- 972, /* (0x51) */
- 984, /* (0x52) */
- 996, /* (0x53) */
- 1008, /* (0x54) */
- 1020, /* (0x55) */
- 1032, /* (0x56) */
- 1044, /* (0x57) */
- 1056, /* (0x58) */
- 1068, /* (0x59) */
- 1080, /* (0x5a) */
- 1092, /* (0x5b) */
- 1104, /* (0x5c) */
- 1116, /* (0x5d) */
- 1128, /* (0x5e) */
- 1140, /* (0x5f) */
- 1152, /* (0x60) */
- 1164, /* (0x61) */
- 1176, /* (0x62) */
- 1188, /* (0x63) */
- 1200, /* (0x64) */
- 1212, /* (0x65) */
- 1224, /* (0x66) */
- 1236, /* (0x67) */
- 1248, /* (0x68) */
- 1260, /* (0x69) */
- 1272, /* (0x6a) */
- 1284, /* (0x6b) */
- 1296, /* (0x6c) */
- 1308, /* (0x6d) */
- 1320, /* (0x6e) */
- 1332, /* (0x6f) */
- 1344, /* (0x70) */
- 1356, /* (0x71) */
- 1368, /* (0x72) */
- 1380, /* (0x73) */
- 1392, /* (0x74) */
- 1404, /* (0x75) */
- 1416, /* (0x76) */
- 1428, /* (0x77) */
- 1440, /* (0x78) */
- 1452, /* (0x79) */
- 1464, /* (0x7a) */
- 1476, /* (0x7b) */
- 1488, /* (0x7c) */
- 1500, /* (0x7d) */
- 1512, /* (0x7e) */
- 0, /* (0x7f) */
- 0, /* (0x80) */
- 0, /* (0x81) */
- 0, /* (0x82) */
- 0, /* (0x83) */
- 0, /* (0x84) */
- 0, /* (0x85) */
- 0, /* (0x86) */
- 0, /* (0x87) */
- 0, /* (0x88) */
- 0, /* (0x89) */
- 0, /* (0x8a) */
- 0, /* (0x8b) */
- 0, /* (0x8c) */
- 0, /* (0x8d) */
- 0, /* (0x8e) */
- 0, /* (0x8f) */
- 0, /* (0x90) */
- 0, /* (0x91) */
- 0, /* (0x92) */
- 0, /* (0x93) */
- 0, /* (0x94) */
- 0, /* (0x95) */
- 0, /* (0x96) */
- 0, /* (0x97) */
- 0, /* (0x98) */
- 0, /* (0x99) */
- 0, /* (0x9a) */
- 0, /* (0x9b) */
- 0, /* (0x9c) */
- 0, /* (0x9d) */
- 0, /* (0x9e) */
- 0, /* (0x9f) */
- 1524, /* (0xa0) */
- 1536, /* (0xa1) */
- 1548, /* (0xa2) */
- 1560, /* (0xa3) */
- 1572, /* (0xa4) */
- 1584, /* (0xa5) */
- 1596, /* (0xa6) */
- 1608, /* (0xa7) */
- 1620, /* (0xa8) */
- 1632, /* (0xa9) */
- 1644, /* (0xaa) */
- 1656, /* (0xab) */
- 1668, /* (0xac) */
- 1680, /* (0xad) */
- 1692, /* (0xae) */
- 1704, /* (0xaf) */
- 1716, /* (0xb0) */
- 1728, /* (0xb1) */
- 1740, /* (0xb2) */
- 1752, /* (0xb3) */
- 1764, /* (0xb4) */
- 1776, /* (0xb5) */
- 1788, /* (0xb6) */
- 1800, /* (0xb7) */
- 1812, /* (0xb8) */
- 1824, /* (0xb9) */
- 1836, /* (0xba) */
- 1848, /* (0xbb) */
- 1860, /* (0xbc) */
- 1872, /* (0xbd) */
- 1884, /* (0xbe) */
- 1896, /* (0xbf) */
- 1908, /* (0xc0) */
- 1920, /* (0xc1) */
- 1932, /* (0xc2) */
- 1944, /* (0xc3) */
- 1956, /* (0xc4) */
- 1968, /* (0xc5) */
- 1980, /* (0xc6) */
- 1992, /* (0xc7) */
- 2004, /* (0xc8) */
- 2016, /* (0xc9) */
- 2028, /* (0xca) */
- 2040, /* (0xcb) */
- 2052, /* (0xcc) */
- 2064, /* (0xcd) */
- 2076, /* (0xce) */
- 2088, /* (0xcf) */
- 2100, /* (0xd0) */
- 2112, /* (0xd1) */
- 2124, /* (0xd2) */
- 2136, /* (0xd3) */
- 2148, /* (0xd4) */
- 2160, /* (0xd5) */
- 2172, /* (0xd6) */
- 2184, /* (0xd7) */
- 2196, /* (0xd8) */
- 2208, /* (0xd9) */
- 2220, /* (0xda) */
- 2232, /* (0xdb) */
- 2244, /* (0xdc) */
- 2256, /* (0xdd) */
- 2268, /* (0xde) */
- 2280, /* (0xdf) */
- 2292, /* (0xe0) */
- 2304, /* (0xe1) */
- 2316, /* (0xe2) */
- 2328, /* (0xe3) */
- 2340, /* (0xe4) */
- 2352, /* (0xe5) */
- 2364, /* (0xe6) */
- 2376, /* (0xe7) */
- 2388, /* (0xe8) */
- 2400, /* (0xe9) */
- 2412, /* (0xea) */
- 2424, /* (0xeb) */
- 2436, /* (0xec) */
- 2448, /* (0xed) */
- 2460, /* (0xee) */
- 2472, /* (0xef) */
- 2484, /* (0xf0) */
- 2496, /* (0xf1) */
- 2508, /* (0xf2) */
- 2520, /* (0xf3) */
- 2532, /* (0xf4) */
- 2544, /* (0xf5) */
- 2556, /* (0xf6) */
- 2568, /* (0xf7) */
- 2580, /* (0xf8) */
- 2592, /* (0xf9) */
- 2604, /* (0xfa) */
- 2616, /* (0xfb) */
- 2628, /* (0xfc) */
- 2640, /* (0xfd) */
- 2652, /* (0xfe) */
- 2664, /* (0xff) */
-};
-
-/* Exported structure definition. */
-static const BdfFontDesc desc = {
- "clR6x12-L1",
- 6,
- 12,
- 6, 12, 0, -3,
- 9,
+// Character 0 (0x00)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// | |
+// |* * * |
+// | |
+// |* * |
+// | |
+// |* * |
+// | |
+// |* * * |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph0[] = {
+ 0x00,
+ 0x00,
+ 0xA8,
+ 0x00,
+ 0x88,
+ 0x00,
+ 0x88,
+ 0x00,
+ 0xA8,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 1 (0x01)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// | |
+// | |
+// | |
+// | * |
+// | *** |
+// |***** |
+// | *** |
+// | * |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph1[] = {
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x20,
+ 0x70,
+ 0xF8,
+ 0x70,
+ 0x20,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 2 (0x02)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// |* * * |
+// | * * *|
+// |* * * |
+// | * * *|
+// |* * * |
+// | * * *|
+// |* * * |
+// | * * *|
+// |* * * |
+// | * * *|
+// |* * * |
+// | * * *|
+// +------+
+static const byte glyph2[] = {
+ 0xA8,
+ 0x54,
+ 0xA8,
+ 0x54,
+ 0xA8,
+ 0x54,
+ 0xA8,
+ 0x54,
+ 0xA8,
+ 0x54,
+ 0xA8,
+ 0x54
+};
+
+// Character 3 (0x03)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// |* * |
+// |* * |
+// |*** |
+// |* * |
+// |* ****|
+// | * |
+// | * |
+// | * |
+// | * |
+// | |
+// | |
+// +------+
+static const byte glyph3[] = {
+ 0x00,
+ 0xA0,
+ 0xA0,
+ 0xE0,
+ 0xA0,
+ 0xBC,
+ 0x08,
+ 0x08,
+ 0x08,
+ 0x08,
+ 0x00,
+ 0x00
+};
+
+// Character 4 (0x04)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// |*** |
+// |* |
+// |** |
+// |* ***|
+// |* * |
+// | ***|
+// | * |
+// | * |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph4[] = {
+ 0x00,
+ 0xE0,
+ 0x80,
+ 0xC0,
+ 0x9C,
+ 0x90,
+ 0x1C,
+ 0x10,
+ 0x10,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 5 (0x05)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// | ** |
+// |* |
+// |* |
+// |* ** |
+// | *** *|
+// | ** |
+// | * *|
+// | * *|
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph5[] = {
+ 0x00,
+ 0x60,
+ 0x80,
+ 0x80,
+ 0x98,
+ 0x74,
+ 0x18,
+ 0x14,
+ 0x14,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 6 (0x06)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// |* |
+// |* |
+// |* |
+// |* ***|
+// |**** |
+// | ** |
+// | * |
+// | * |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph6[] = {
+ 0x00,
+ 0x80,
+ 0x80,
+ 0x80,
+ 0x9C,
+ 0xF0,
+ 0x18,
+ 0x10,
+ 0x10,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 7 (0x07)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// | ** |
+// | * * |
+// | * * |
+// | ** |
+// | |
+// | |
+// | |
+// | |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph7[] = {
+ 0x00,
+ 0x30,
+ 0x48,
+ 0x48,
+ 0x30,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 8 (0x08)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// | |
+// | * |
+// | * |
+// |***** |
+// | * |
+// | * |
+// | |
+// |***** |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph8[] = {
+ 0x00,
+ 0x00,
+ 0x20,
+ 0x20,
+ 0xF8,
+ 0x20,
+ 0x20,
+ 0x00,
+ 0xF8,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 9 (0x09)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// |* * |
+// |*** |
+// |*** |
+// |*** |
+// |* ** |
+// | * |
+// | * |
+// | * |
+// | ***|
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph9[] = {
+ 0xA0,
+ 0xE0,
+ 0xE0,
+ 0xE0,
+ 0xB0,
+ 0x10,
+ 0x10,
+ 0x10,
+ 0x1C,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 10 (0x0A)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// |* * |
+// |* * |
+// |* * |
+// | * ***|
+// | * * |
+// | * |
+// | * |
+// | * |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph10[] = {
+ 0x00,
+ 0xA0,
+ 0xA0,
+ 0xA0,
+ 0x5C,
+ 0x48,
+ 0x08,
+ 0x08,
+ 0x08,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 11 (0x0B)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | * |
+// | * |
+// | * |
+// | * |
+// | * |
+// | * |
+// |*** |
+// | |
+// | |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph11[] = {
+ 0x20,
+ 0x20,
+ 0x20,
+ 0x20,
+ 0x20,
+ 0x20,
+ 0xE0,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 12 (0x0C)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// | |
+// | |
+// | |
+// | |
+// | |
+// |*** |
+// | * |
+// | * |
+// | * |
+// | * |
+// | * |
+// +------+
+static const byte glyph12[] = {
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0xE0,
+ 0x20,
+ 0x20,
+ 0x20,
+ 0x20,
+ 0x20
+};
+
+// Character 13 (0x0D)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// | |
+// | |
+// | |
+// | |
+// | |
+// | ****|
+// | * |
+// | * |
+// | * |
+// | * |
+// | * |
+// +------+
+static const byte glyph13[] = {
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x3F,
+ 0x20,
+ 0x20,
+ 0x20,
+ 0x20,
+ 0x20
+};
+
+// Character 14 (0x0E)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | * |
+// | * |
+// | * |
+// | * |
+// | * |
+// | * |
+// | ****|
+// | |
+// | |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph14[] = {
+ 0x20,
+ 0x20,
+ 0x20,
+ 0x20,
+ 0x20,
+ 0x20,
+ 0x3F,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 15 (0x0F)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | * |
+// | * |
+// | * |
+// | * |
+// | * |
+// | * |
+// |******|
+// | * |
+// | * |
+// | * |
+// | * |
+// | * |
+// +------+
+static const byte glyph15[] = {
+ 0x20,
+ 0x20,
+ 0x20,
+ 0x20,
+ 0x20,
+ 0x20,
+ 0xFF,
+ 0x20,
+ 0x20,
+ 0x20,
+ 0x20,
+ 0x20
+};
+
+// Character 16 (0x10)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// |******|
+// | |
+// | |
+// | |
+// | |
+// | |
+// | |
+// | |
+// | |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph16[] = {
+ 0xFC,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 17 (0x11)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// | |
+// | |
+// |******|
+// | |
+// | |
+// | |
+// | |
+// | |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph17[] = {
+ 0x00,
+ 0x00,
+ 0x00,
+ 0xFC,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 18 (0x12)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// | |
+// | |
+// | |
+// | |
+// | |
+// |******|
+// | |
+// | |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph18[] = {
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0xFC,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 19 (0x13)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// | |
+// | |
+// | |
+// | |
+// | |
+// | |
+// | |
+// |******|
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph19[] = {
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0xFC,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 20 (0x14)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// | |
+// | |
+// | |
+// | |
+// | |
+// | |
+// | |
+// | |
+// | |
+// | |
+// |******|
+// +------+
+static const byte glyph20[] = {
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0xFC
+};
+
+// Character 21 (0x15)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | * |
+// | * |
+// | * |
+// | * |
+// | * |
+// | * |
+// | ****|
+// | * |
+// | * |
+// | * |
+// | * |
+// | * |
+// +------+
+static const byte glyph21[] = {
+ 0x20,
+ 0x20,
+ 0x20,
+ 0x20,
+ 0x20,
+ 0x20,
+ 0x3F,
+ 0x20,
+ 0x20,
+ 0x20,
+ 0x20,
+ 0x20
+};
+
+// Character 22 (0x16)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | * |
+// | * |
+// | * |
+// | * |
+// | * |
+// | * |
+// |*** |
+// | * |
+// | * |
+// | * |
+// | * |
+// | * |
+// +------+
+static const byte glyph22[] = {
+ 0x20,
+ 0x20,
+ 0x20,
+ 0x20,
+ 0x20,
+ 0x20,
+ 0xE0,
+ 0x20,
+ 0x20,
+ 0x20,
+ 0x20,
+ 0x20
+};
+
+// Character 23 (0x17)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | * |
+// | * |
+// | * |
+// | * |
+// | * |
+// | * |
+// |******|
+// | |
+// | |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph23[] = {
+ 0x20,
+ 0x20,
+ 0x20,
+ 0x20,
+ 0x20,
+ 0x20,
+ 0xFF,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 24 (0x18)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// | |
+// | |
+// | |
+// | |
+// | |
+// |******|
+// | * |
+// | * |
+// | * |
+// | * |
+// | * |
+// +------+
+static const byte glyph24[] = {
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0xFF,
+ 0x20,
+ 0x20,
+ 0x20,
+ 0x20,
+ 0x20
+};
+
+// Character 25 (0x19)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | * |
+// | * |
+// | * |
+// | * |
+// | * |
+// | * |
+// | * |
+// | * |
+// | * |
+// | * |
+// | * |
+// | * |
+// +------+
+static const byte glyph25[] = {
+ 0x20,
+ 0x20,
+ 0x20,
+ 0x20,
+ 0x20,
+ 0x20,
+ 0x20,
+ 0x20,
+ 0x20,
+ 0x20,
+ 0x20,
+ 0x20
+};
+
+// Character 26 (0x1A)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// | |
+// | ** |
+// | ** |
+// |* |
+// | ** |
+// | ** |
+// | |
+// |***** |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph26[] = {
+ 0x00,
+ 0x00,
+ 0x18,
+ 0x60,
+ 0x80,
+ 0x60,
+ 0x18,
+ 0x00,
+ 0xF8,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 27 (0x1B)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// | |
+// |** |
+// | ** |
+// | * |
+// | ** |
+// |** |
+// | |
+// |***** |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph27[] = {
+ 0x00,
+ 0x00,
+ 0xC0,
+ 0x30,
+ 0x08,
+ 0x30,
+ 0xC0,
+ 0x00,
+ 0xF8,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 28 (0x1C)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// | |
+// | |
+// | |
+// |***** |
+// |* * |
+// |* * |
+// |* * |
+// |* * |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph28[] = {
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0xF8,
+ 0x88,
+ 0x88,
+ 0x88,
+ 0x88,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 29 (0x1D)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// | |
+// | * |
+// | * |
+// |***** |
+// | * |
+// |***** |
+// | * |
+// | * |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph29[] = {
+ 0x00,
+ 0x00,
+ 0x10,
+ 0x10,
+ 0xF8,
+ 0x20,
+ 0xF8,
+ 0x40,
+ 0x40,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 30 (0x1E)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// | ** |
+// | * * |
+// | * |
+// |*** |
+// | * |
+// | * |
+// | * * |
+// |* ** |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph30[] = {
+ 0x00,
+ 0x30,
+ 0x48,
+ 0x40,
+ 0xE0,
+ 0x40,
+ 0x40,
+ 0x48,
+ 0xB0,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 31 (0x1F)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// | |
+// | |
+// | |
+// | |
+// | |
+// | ** |
+// | |
+// | |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph31[] = {
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x30,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 32 (0x20)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// | |
+// | |
+// | |
+// | |
+// | |
+// | |
+// | |
+// | |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph32[] = {
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 33 (0x21)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// | * |
+// | * |
+// | * |
+// | * |
+// | * |
+// | * |
+// | |
+// | * |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph33[] = {
+ 0x00,
+ 0x20,
+ 0x20,
+ 0x20,
+ 0x20,
+ 0x20,
+ 0x20,
+ 0x00,
+ 0x20,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 34 (0x22)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// | * * |
+// | * * |
+// | * * |
+// | |
+// | |
+// | |
+// | |
+// | |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph34[] = {
+ 0x00,
+ 0x50,
+ 0x50,
+ 0x50,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 35 (0x23)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// | |
+// | * * |
+// | * * |
+// |***** |
+// | * * |
+// |***** |
+// | * * |
+// | * * |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph35[] = {
+ 0x00,
+ 0x00,
+ 0x50,
+ 0x50,
+ 0xF8,
+ 0x50,
+ 0xF8,
+ 0x50,
+ 0x50,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 36 (0x24)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// | |
+// | * |
+// | **** |
+// |* * |
+// | *** |
+// | * * |
+// |**** |
+// | * |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph36[] = {
+ 0x00,
+ 0x00,
+ 0x20,
+ 0x78,
+ 0xA0,
+ 0x70,
+ 0x28,
+ 0xF0,
+ 0x20,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 37 (0x25)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// | |
+// |** |
+// |** * |
+// | * |
+// | * |
+// | * |
+// |* ** |
+// | ** |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph37[] = {
+ 0x00,
+ 0x00,
+ 0xC0,
+ 0xC8,
+ 0x10,
+ 0x20,
+ 0x40,
+ 0x98,
+ 0x18,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 38 (0x26)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// | |
+// | *** |
+// |* |
+// |* |
+// | * |
+// |* * * |
+// |* * |
+// | ** * |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph38[] = {
+ 0x00,
+ 0x00,
+ 0x70,
+ 0x80,
+ 0x80,
+ 0x40,
+ 0xA8,
+ 0x90,
+ 0x68,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 39 (0x27)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// | * |
+// | * |
+// | * |
+// | |
+// | |
+// | |
+// | |
+// | |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph39[] = {
+ 0x00,
+ 0x20,
+ 0x20,
+ 0x20,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 40 (0x28)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | * |
+// | * |
+// | * |
+// | * |
+// | * |
+// | * |
+// | * |
+// | * |
+// | * |
+// | * |
+// | * |
+// | |
+// +------+
+static const byte glyph40[] = {
+ 0x08,
+ 0x10,
+ 0x10,
+ 0x20,
+ 0x20,
+ 0x20,
+ 0x20,
+ 0x20,
+ 0x10,
+ 0x10,
+ 0x08,
+ 0x00
+};
+
+// Character 41 (0x29)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | * |
+// | * |
+// | * |
+// | * |
+// | * |
+// | * |
+// | * |
+// | * |
+// | * |
+// | * |
+// | * |
+// | |
+// +------+
+static const byte glyph41[] = {
+ 0x40,
+ 0x20,
+ 0x20,
+ 0x10,
+ 0x10,
+ 0x10,
+ 0x10,
+ 0x10,
+ 0x20,
+ 0x20,
+ 0x40,
+ 0x00
+};
+
+// Character 42 (0x2A)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// | |
+// | |
+// | * |
+// |* * * |
+// | *** |
+// |* * * |
+// | * |
+// | |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph42[] = {
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x20,
+ 0xA8,
+ 0x70,
+ 0xA8,
+ 0x20,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 43 (0x2B)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// | |
+// | |
+// | * |
+// | * |
+// |***** |
+// | * |
+// | * |
+// | |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph43[] = {
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x20,
+ 0x20,
+ 0xF8,
+ 0x20,
+ 0x20,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 44 (0x2C)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// | |
+// | |
+// | |
+// | |
+// | |
+// | |
+// | ** |
+// | ** |
+// | * |
+// | * |
+// | |
+// +------+
+static const byte glyph44[] = {
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x30,
+ 0x30,
+ 0x20,
+ 0x40,
+ 0x00
+};
+
+// Character 45 (0x2D)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// | |
+// | |
+// | |
+// | |
+// |***** |
+// | |
+// | |
+// | |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph45[] = {
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0xF8,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 46 (0x2E)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// | |
+// | |
+// | |
+// | |
+// | |
+// | |
+// | ** |
+// | ** |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph46[] = {
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x30,
+ 0x30,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 47 (0x2F)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | * |
+// | * |
+// | * |
+// | * |
+// | * |
+// | * |
+// | * |
+// | * |
+// |* |
+// |* |
+// | |
+// | |
+// +------+
+static const byte glyph47[] = {
+ 0x08,
+ 0x08,
+ 0x10,
+ 0x10,
+ 0x20,
+ 0x20,
+ 0x40,
+ 0x40,
+ 0x80,
+ 0x80,
+ 0x00,
+ 0x00
+};
+
+// Character 48 (0x30)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// | *** |
+// |* * |
+// |* ** |
+// |* * * |
+// |** * |
+// |* * |
+// |* * |
+// | *** |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph48[] = {
+ 0x00,
+ 0x70,
+ 0x88,
+ 0x98,
+ 0xA8,
+ 0xC8,
+ 0x88,
+ 0x88,
+ 0x70,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 49 (0x31)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// | * |
+// | ** |
+// | * |
+// | * |
+// | * |
+// | * |
+// | * |
+// | * |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph49[] = {
+ 0x00,
+ 0x10,
+ 0x30,
+ 0x10,
+ 0x10,
+ 0x10,
+ 0x10,
+ 0x10,
+ 0x10,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 50 (0x32)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// | *** |
+// |* * |
+// | * |
+// | * |
+// | * |
+// | * |
+// |* |
+// |***** |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph50[] = {
+ 0x00,
+ 0x70,
+ 0x88,
+ 0x08,
+ 0x10,
+ 0x20,
+ 0x40,
+ 0x80,
+ 0xF8,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 51 (0x33)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// | *** |
+// |* * |
+// | * |
+// | ** |
+// | * |
+// | * |
+// |* * |
+// | *** |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph51[] = {
+ 0x00,
+ 0x70,
+ 0x88,
+ 0x08,
+ 0x30,
+ 0x08,
+ 0x08,
+ 0x88,
+ 0x70,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 52 (0x34)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// | * |
+// | ** |
+// | ** |
+// | * * |
+// | * * |
+// |***** |
+// | * |
+// | *** |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph52[] = {
+ 0x00,
+ 0x10,
+ 0x30,
+ 0x30,
+ 0x50,
+ 0x50,
+ 0xF8,
+ 0x10,
+ 0x38,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 53 (0x35)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// |***** |
+// |* |
+// |* |
+// |**** |
+// | * |
+// | * |
+// |* * |
+// | *** |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph53[] = {
+ 0x00,
+ 0xF8,
+ 0x80,
+ 0x80,
+ 0xF0,
+ 0x08,
+ 0x08,
+ 0x88,
+ 0x70,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 54 (0x36)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// | ** |
+// | * |
+// |* |
+// |**** |
+// |* * |
+// |* * |
+// |* * |
+// | *** |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph54[] = {
+ 0x00,
+ 0x30,
+ 0x40,
+ 0x80,
+ 0xF0,
+ 0x88,
+ 0x88,
+ 0x88,
+ 0x70,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 55 (0x37)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// |***** |
+// |* * |
+// | * |
+// | * |
+// | * |
+// | * |
+// | * |
+// | * |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph55[] = {
+ 0x00,
+ 0xF8,
+ 0x88,
+ 0x08,
+ 0x08,
+ 0x10,
+ 0x10,
+ 0x20,
+ 0x20,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 56 (0x38)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// | *** |
+// |* * |
+// |* * |
+// | *** |
+// |* * |
+// |* * |
+// |* * |
+// | *** |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph56[] = {
+ 0x00,
+ 0x70,
+ 0x88,
+ 0x88,
+ 0x70,
+ 0x88,
+ 0x88,
+ 0x88,
+ 0x70,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 57 (0x39)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// | *** |
+// |* * |
+// |* * |
+// |* * |
+// | **** |
+// | * |
+// | * |
+// | ** |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph57[] = {
+ 0x00,
+ 0x70,
+ 0x88,
+ 0x88,
+ 0x88,
+ 0x78,
+ 0x08,
+ 0x10,
+ 0x60,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 58 (0x3A)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// | |
+// | |
+// | ** |
+// | ** |
+// | |
+// | |
+// | ** |
+// | ** |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph58[] = {
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x30,
+ 0x30,
+ 0x00,
+ 0x00,
+ 0x30,
+ 0x30,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 59 (0x3B)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// | |
+// | |
+// | ** |
+// | ** |
+// | |
+// | |
+// | ** |
+// | ** |
+// | * |
+// | * |
+// | |
+// +------+
+static const byte glyph59[] = {
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x30,
+ 0x30,
+ 0x00,
+ 0x00,
+ 0x30,
+ 0x30,
+ 0x20,
+ 0x40,
+ 0x00
+};
+
+// Character 60 (0x3C)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// | |
+// | |
+// | **|
+// | ** |
+// |** |
+// | ** |
+// | **|
+// | |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph60[] = {
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x0C,
+ 0x30,
+ 0xC0,
+ 0x30,
+ 0x0C,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 61 (0x3D)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// | |
+// | |
+// | |
+// |***** |
+// | |
+// |***** |
+// | |
+// | |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph61[] = {
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0xF8,
+ 0x00,
+ 0xF8,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 62 (0x3E)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// | |
+// | |
+// |** |
+// | ** |
+// | **|
+// | ** |
+// |** |
+// | |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph62[] = {
+ 0x00,
+ 0x00,
+ 0x00,
+ 0xC0,
+ 0x30,
+ 0x0C,
+ 0x30,
+ 0xC0,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 63 (0x3F)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// | *** |
+// |* * |
+// | * |
+// | * |
+// | * |
+// | * |
+// | |
+// | * |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph63[] = {
+ 0x00,
+ 0x70,
+ 0x88,
+ 0x08,
+ 0x10,
+ 0x20,
+ 0x20,
+ 0x00,
+ 0x20,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 64 (0x40)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// | |
+// | *** |
+// |* * |
+// |* *** |
+// |* *** |
+// |* ** |
+// |* |
+// | *** |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph64[] = {
+ 0x00,
+ 0x00,
+ 0x70,
+ 0x88,
+ 0xB8,
+ 0xB8,
+ 0xB0,
+ 0x80,
+ 0x70,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 65 (0x41)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// | |
+// | * |
+// | * * |
+// |* * |
+// |* * |
+// |***** |
+// |* * |
+// |* * |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph65[] = {
+ 0x00,
+ 0x00,
+ 0x20,
+ 0x50,
+ 0x88,
+ 0x88,
+ 0xF8,
+ 0x88,
+ 0x88,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 66 (0x42)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// | |
+// |**** |
+// |* * |
+// |* * |
+// |**** |
+// |* * |
+// |* * |
+// |**** |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph66[] = {
+ 0x00,
+ 0x00,
+ 0xF0,
+ 0x88,
+ 0x88,
+ 0xF0,
+ 0x88,
+ 0x88,
+ 0xF0,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 67 (0x43)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// | |
+// | *** |
+// |* * |
+// |* |
+// |* |
+// |* |
+// |* * |
+// | *** |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph67[] = {
+ 0x00,
+ 0x00,
+ 0x70,
+ 0x88,
+ 0x80,
+ 0x80,
+ 0x80,
+ 0x88,
+ 0x70,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 68 (0x44)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// | |
+// |*** |
+// |* * |
+// |* * |
+// |* * |
+// |* * |
+// |* * |
+// |*** |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph68[] = {
+ 0x00,
+ 0x00,
+ 0xE0,
+ 0x90,
+ 0x88,
+ 0x88,
+ 0x88,
+ 0x90,
+ 0xE0,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 69 (0x45)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// | |
+// |***** |
+// |* |
+// |* |
+// |**** |
+// |* |
+// |* |
+// |***** |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph69[] = {
+ 0x00,
+ 0x00,
+ 0xF8,
+ 0x80,
+ 0x80,
+ 0xF0,
+ 0x80,
+ 0x80,
+ 0xF8,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 70 (0x46)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// | |
+// |***** |
+// |* |
+// |* |
+// |**** |
+// |* |
+// |* |
+// |* |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph70[] = {
+ 0x00,
+ 0x00,
+ 0xF8,
+ 0x80,
+ 0x80,
+ 0xF0,
+ 0x80,
+ 0x80,
+ 0x80,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 71 (0x47)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// | |
+// | *** |
+// |* * |
+// |* |
+// |* ** |
+// |* * |
+// |* * |
+// | **** |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph71[] = {
+ 0x00,
+ 0x00,
+ 0x70,
+ 0x88,
+ 0x80,
+ 0x98,
+ 0x88,
+ 0x88,
+ 0x78,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 72 (0x48)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// | |
+// |* * |
+// |* * |
+// |* * |
+// |***** |
+// |* * |
+// |* * |
+// |* * |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph72[] = {
+ 0x00,
+ 0x00,
+ 0x88,
+ 0x88,
+ 0x88,
+ 0xF8,
+ 0x88,
+ 0x88,
+ 0x88,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 73 (0x49)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// | |
+// |***** |
+// | * |
+// | * |
+// | * |
+// | * |
+// | * |
+// |***** |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph73[] = {
+ 0x00,
+ 0x00,
+ 0xF8,
+ 0x20,
+ 0x20,
+ 0x20,
+ 0x20,
+ 0x20,
+ 0xF8,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 74 (0x4A)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// | |
+// | *** |
+// | * |
+// | * |
+// | * |
+// |* * |
+// |* * |
+// | *** |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph74[] = {
+ 0x00,
+ 0x00,
+ 0x38,
+ 0x08,
+ 0x08,
+ 0x08,
+ 0x88,
+ 0x88,
+ 0x70,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 75 (0x4B)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// | |
+// |* * |
+// |* * |
+// |* * |
+// |** |
+// |* * |
+// |* * |
+// |* * |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph75[] = {
+ 0x00,
+ 0x00,
+ 0x88,
+ 0x90,
+ 0xA0,
+ 0xC0,
+ 0xA0,
+ 0x90,
+ 0x88,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 76 (0x4C)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// | |
+// |* |
+// |* |
+// |* |
+// |* |
+// |* |
+// |* |
+// |***** |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph76[] = {
+ 0x00,
+ 0x00,
+ 0x80,
+ 0x80,
+ 0x80,
+ 0x80,
+ 0x80,
+ 0x80,
+ 0xF8,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 77 (0x4D)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// | |
+// |* * |
+// |** ** |
+// |* * * |
+// |* * * |
+// |* * |
+// |* * |
+// |* * |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph77[] = {
+ 0x00,
+ 0x00,
+ 0x88,
+ 0xD8,
+ 0xA8,
+ 0xA8,
+ 0x88,
+ 0x88,
+ 0x88,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 78 (0x4E)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// | |
+// |* * |
+// |** * |
+// |** * |
+// |* * * |
+// |* ** |
+// |* ** |
+// |* * |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph78[] = {
+ 0x00,
+ 0x00,
+ 0x88,
+ 0xC8,
+ 0xC8,
+ 0xA8,
+ 0x98,
+ 0x98,
+ 0x88,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 79 (0x4F)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// | |
+// | *** |
+// |* * |
+// |* * |
+// |* * |
+// |* * |
+// |* * |
+// | *** |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph79[] = {
+ 0x00,
+ 0x00,
+ 0x70,
+ 0x88,
+ 0x88,
+ 0x88,
+ 0x88,
+ 0x88,
+ 0x70,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 80 (0x50)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// | |
+// |**** |
+// |* * |
+// |* * |
+// |**** |
+// |* |
+// |* |
+// |* |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph80[] = {
+ 0x00,
+ 0x00,
+ 0xF0,
+ 0x88,
+ 0x88,
+ 0xF0,
+ 0x80,
+ 0x80,
+ 0x80,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 81 (0x51)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// | |
+// | *** |
+// |* * |
+// |* * |
+// |* * |
+// |* * |
+// |* * |
+// | *** |
+// | ** |
+// | |
+// | |
+// +------+
+static const byte glyph81[] = {
+ 0x00,
+ 0x00,
+ 0x70,
+ 0x88,
+ 0x88,
+ 0x88,
+ 0x88,
+ 0x88,
+ 0x70,
+ 0x18,
+ 0x00,
+ 0x00
+};
+
+// Character 82 (0x52)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// | |
+// |**** |
+// |* * |
+// |* * |
+// |**** |
+// |* * |
+// |* * |
+// |* * |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph82[] = {
+ 0x00,
+ 0x00,
+ 0xF0,
+ 0x88,
+ 0x88,
+ 0xF0,
+ 0xA0,
+ 0x90,
+ 0x88,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 83 (0x53)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// | |
+// | *** |
+// |* * |
+// |* |
+// | *** |
+// | * |
+// |* * |
+// | *** |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph83[] = {
+ 0x00,
+ 0x00,
+ 0x70,
+ 0x88,
+ 0x80,
+ 0x70,
+ 0x08,
+ 0x88,
+ 0x70,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 84 (0x54)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// | |
+// |***** |
+// | * |
+// | * |
+// | * |
+// | * |
+// | * |
+// | * |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph84[] = {
+ 0x00,
+ 0x00,
+ 0xF8,
+ 0x20,
+ 0x20,
+ 0x20,
+ 0x20,
+ 0x20,
+ 0x20,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 85 (0x55)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// | |
+// |* * |
+// |* * |
+// |* * |
+// |* * |
+// |* * |
+// |* * |
+// | *** |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph85[] = {
+ 0x00,
+ 0x00,
+ 0x88,
+ 0x88,
+ 0x88,
+ 0x88,
+ 0x88,
+ 0x88,
+ 0x70,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 86 (0x56)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// | |
+// |* * |
+// |* * |
+// |* * |
+// | * * |
+// | * * |
+// | * |
+// | * |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph86[] = {
+ 0x00,
+ 0x00,
+ 0x88,
+ 0x88,
+ 0x88,
+ 0x50,
+ 0x50,
+ 0x20,
+ 0x20,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 87 (0x57)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// | |
+// |* * |
+// |* * |
+// |* * |
+// |* * * |
+// |* * * |
+// |** ** |
+// |* * |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph87[] = {
+ 0x00,
+ 0x00,
+ 0x88,
+ 0x88,
+ 0x88,
+ 0xA8,
+ 0xA8,
+ 0xD8,
+ 0x88,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 88 (0x58)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// | |
+// |* * |
+// |* * |
+// | * * |
+// | * |
+// | * * |
+// |* * |
+// |* * |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph88[] = {
+ 0x00,
+ 0x00,
+ 0x88,
+ 0x88,
+ 0x50,
+ 0x20,
+ 0x50,
+ 0x88,
+ 0x88,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 89 (0x59)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// | |
+// |* * |
+// |* * |
+// | * * |
+// | * |
+// | * |
+// | * |
+// | * |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph89[] = {
+ 0x00,
+ 0x00,
+ 0x88,
+ 0x88,
+ 0x50,
+ 0x20,
+ 0x20,
+ 0x20,
+ 0x20,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 90 (0x5A)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// | |
+// |***** |
+// | * |
+// | * |
+// | * |
+// | * |
+// |* |
+// |***** |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph90[] = {
+ 0x00,
+ 0x00,
+ 0xF8,
+ 0x08,
+ 0x10,
+ 0x20,
+ 0x40,
+ 0x80,
+ 0xF8,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 91 (0x5B)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | *** |
+// | * |
+// | * |
+// | * |
+// | * |
+// | * |
+// | * |
+// | * |
+// | * |
+// | * |
+// | *** |
+// | |
+// +------+
+static const byte glyph91[] = {
+ 0x38,
+ 0x20,
+ 0x20,
+ 0x20,
+ 0x20,
+ 0x20,
+ 0x20,
+ 0x20,
+ 0x20,
+ 0x20,
+ 0x38,
+ 0x00
+};
+
+// Character 92 (0x5C)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// |* |
+// |* |
+// | * |
+// | * |
+// | * |
+// | * |
+// | * |
+// | * |
+// | * |
+// | * |
+// | |
+// | |
+// +------+
+static const byte glyph92[] = {
+ 0x80,
+ 0x80,
+ 0x40,
+ 0x40,
+ 0x20,
+ 0x20,
+ 0x10,
+ 0x10,
+ 0x08,
+ 0x08,
+ 0x00,
+ 0x00
+};
+
+// Character 93 (0x5D)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | *** |
+// | * |
+// | * |
+// | * |
+// | * |
+// | * |
+// | * |
+// | * |
+// | * |
+// | * |
+// | *** |
+// | |
+// +------+
+static const byte glyph93[] = {
+ 0x70,
+ 0x10,
+ 0x10,
+ 0x10,
+ 0x10,
+ 0x10,
+ 0x10,
+ 0x10,
+ 0x10,
+ 0x10,
+ 0x70,
+ 0x00
+};
+
+// Character 94 (0x5E)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// | * |
+// | * * |
+// |* * |
+// | |
+// | |
+// | |
+// | |
+// | |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph94[] = {
+ 0x00,
+ 0x20,
+ 0x50,
+ 0x88,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 95 (0x5F)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// | |
+// | |
+// | |
+// | |
+// | |
+// | |
+// | |
+// | |
+// |******|
+// | |
+// | |
+// +------+
+static const byte glyph95[] = {
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0xFC,
+ 0x00,
+ 0x00
+};
+
+// Character 96 (0x60)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// | * |
+// | * |
+// | |
+// | |
+// | |
+// | |
+// | |
+// | |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph96[] = {
+ 0x00,
+ 0x20,
+ 0x10,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 97 (0x61)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// | |
+// | |
+// | |
+// | **** |
+// |* * |
+// |* * |
+// |* ** |
+// | ** * |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph97[] = {
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x78,
+ 0x88,
+ 0x88,
+ 0x98,
+ 0x68,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 98 (0x62)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// |* |
+// |* |
+// |* |
+// |**** |
+// |* * |
+// |* * |
+// |* * |
+// |**** |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph98[] = {
+ 0x00,
+ 0x80,
+ 0x80,
+ 0x80,
+ 0xF0,
+ 0x88,
+ 0x88,
+ 0x88,
+ 0xF0,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 99 (0x63)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// | |
+// | |
+// | |
+// | **** |
+// |* |
+// |* |
+// |* |
+// | **** |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph99[] = {
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x78,
+ 0x80,
+ 0x80,
+ 0x80,
+ 0x78,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 100 (0x64)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// | * |
+// | * |
+// | * |
+// | **** |
+// |* * |
+// |* * |
+// |* * |
+// | **** |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph100[] = {
+ 0x00,
+ 0x08,
+ 0x08,
+ 0x08,
+ 0x78,
+ 0x88,
+ 0x88,
+ 0x88,
+ 0x78,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 101 (0x65)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// | |
+// | |
+// | |
+// | *** |
+// |* * |
+// |***** |
+// |* |
+// | *** |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph101[] = {
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x70,
+ 0x88,
+ 0xF8,
+ 0x80,
+ 0x70,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 102 (0x66)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// | *** |
+// | * |
+// | * |
+// |**** |
+// | * |
+// | * |
+// | * |
+// | * |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph102[] = {
+ 0x00,
+ 0x38,
+ 0x40,
+ 0x40,
+ 0xF0,
+ 0x40,
+ 0x40,
+ 0x40,
+ 0x40,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 103 (0x67)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// | |
+// | |
+// | |
+// | **** |
+// |* * |
+// |* * |
+// |* * |
+// | **** |
+// | * |
+// | * |
+// | *** |
+// +------+
+static const byte glyph103[] = {
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x78,
+ 0x88,
+ 0x88,
+ 0x88,
+ 0x78,
+ 0x08,
+ 0x08,
+ 0x70
+};
+
+// Character 104 (0x68)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// |* |
+// |* |
+// |* |
+// |**** |
+// |* * |
+// |* * |
+// |* * |
+// |* * |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph104[] = {
+ 0x00,
+ 0x80,
+ 0x80,
+ 0x80,
+ 0xF0,
+ 0x88,
+ 0x88,
+ 0x88,
+ 0x88,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 105 (0x69)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// | * |
+// | * |
+// | |
+// | ** |
+// | * |
+// | * |
+// | * |
+// | *** |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph105[] = {
+ 0x00,
+ 0x20,
+ 0x20,
+ 0x00,
+ 0x60,
+ 0x20,
+ 0x20,
+ 0x20,
+ 0x70,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 106 (0x6A)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// | * |
+// | * |
+// | |
+// | *** |
+// | * |
+// | * |
+// | * |
+// | * |
+// | * |
+// | * |
+// | *** |
+// +------+
+static const byte glyph106[] = {
+ 0x00,
+ 0x08,
+ 0x08,
+ 0x00,
+ 0x38,
+ 0x08,
+ 0x08,
+ 0x08,
+ 0x08,
+ 0x08,
+ 0x08,
+ 0x70
+};
+
+// Character 107 (0x6B)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// | * |
+// | * |
+// | * |
+// | * * |
+// | * * |
+// | ** |
+// | * * |
+// | * * |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph107[] = {
+ 0x00,
+ 0x40,
+ 0x40,
+ 0x40,
+ 0x48,
+ 0x50,
+ 0x60,
+ 0x50,
+ 0x48,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 108 (0x6C)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// | ** |
+// | * |
+// | * |
+// | * |
+// | * |
+// | * |
+// | * |
+// | *** |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph108[] = {
+ 0x00,
+ 0x60,
+ 0x20,
+ 0x20,
+ 0x20,
+ 0x20,
+ 0x20,
+ 0x20,
+ 0x70,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 109 (0x6D)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// | |
+// | |
+// | |
+// |** * |
+// |* * * |
+// |* * * |
+// |* * * |
+// |* * |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph109[] = {
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0xD0,
+ 0xA8,
+ 0xA8,
+ 0xA8,
+ 0x88,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 110 (0x6E)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// | |
+// | |
+// | |
+// |* ** |
+// |** * |
+// |* * |
+// |* * |
+// |* * |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph110[] = {
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0xB0,
+ 0xC8,
+ 0x88,
+ 0x88,
+ 0x88,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 111 (0x6F)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// | |
+// | |
+// | |
+// | *** |
+// |* * |
+// |* * |
+// |* * |
+// | *** |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph111[] = {
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x70,
+ 0x88,
+ 0x88,
+ 0x88,
+ 0x70,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 112 (0x70)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// | |
+// | |
+// | |
+// |**** |
+// |* * |
+// |* * |
+// |* * |
+// |**** |
+// |* |
+// |* |
+// |* |
+// +------+
+static const byte glyph112[] = {
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0xF0,
+ 0x88,
+ 0x88,
+ 0x88,
+ 0xF0,
+ 0x80,
+ 0x80,
+ 0x80
+};
+
+// Character 113 (0x71)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// | |
+// | |
+// | |
+// | **** |
+// |* * |
+// |* * |
+// |* * |
+// | **** |
+// | * |
+// | * |
+// | * |
+// +------+
+static const byte glyph113[] = {
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x78,
+ 0x88,
+ 0x88,
+ 0x88,
+ 0x78,
+ 0x08,
+ 0x08,
+ 0x08
+};
+
+// Character 114 (0x72)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// | |
+// | |
+// | |
+// | * ** |
+// | ** |
+// | * |
+// | * |
+// | * |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph114[] = {
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x58,
+ 0x60,
+ 0x40,
+ 0x40,
+ 0x40,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 115 (0x73)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// | |
+// | |
+// | |
+// | **** |
+// |* |
+// | *** |
+// | * |
+// |**** |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph115[] = {
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x78,
+ 0x80,
+ 0x70,
+ 0x08,
+ 0xF0,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 116 (0x74)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// | * |
+// | * |
+// | * |
+// | *** |
+// | * |
+// | * |
+// | * |
+// | ** |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph116[] = {
+ 0x00,
+ 0x20,
+ 0x20,
+ 0x20,
+ 0x70,
+ 0x20,
+ 0x20,
+ 0x20,
+ 0x18,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 117 (0x75)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// | |
+// | |
+// | |
+// |* * |
+// |* * |
+// |* * |
+// |* ** |
+// | ** * |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph117[] = {
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x88,
+ 0x88,
+ 0x88,
+ 0x98,
+ 0x68,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 118 (0x76)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// | |
+// | |
+// | |
+// |** ** |
+// | * * |
+// | * * |
+// | * |
+// | * |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph118[] = {
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0xD8,
+ 0x50,
+ 0x50,
+ 0x20,
+ 0x20,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 119 (0x77)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// | |
+// | |
+// | |
+// |* * |
+// |* * * |
+// |* * * |
+// |* * * |
+// | * * |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph119[] = {
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x88,
+ 0xA8,
+ 0xA8,
+ 0xA8,
+ 0x50,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 120 (0x78)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// | |
+// | |
+// | |
+// |* * |
+// | * * |
+// | * |
+// | * * |
+// |* * |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph120[] = {
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x88,
+ 0x50,
+ 0x20,
+ 0x50,
+ 0x88,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 121 (0x79)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// | |
+// | |
+// | |
+// |* * |
+// |* * |
+// |* * |
+// |* * |
+// | **** |
+// | * |
+// | * |
+// | *** |
+// +------+
+static const byte glyph121[] = {
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x88,
+ 0x88,
+ 0x88,
+ 0x88,
+ 0x78,
+ 0x08,
+ 0x08,
+ 0x70
+};
+
+// Character 122 (0x7A)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// | |
+// | |
+// | |
+// |***** |
+// | * |
+// | * |
+// | * |
+// |***** |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph122[] = {
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0xF8,
+ 0x10,
+ 0x20,
+ 0x40,
+ 0xF8,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 123 (0x7B)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | * |
+// | * |
+// | * |
+// | * |
+// | * |
+// | * |
+// | * |
+// | * |
+// | * |
+// | * |
+// | * |
+// | |
+// +------+
+static const byte glyph123[] = {
+ 0x08,
+ 0x10,
+ 0x10,
+ 0x10,
+ 0x10,
+ 0x20,
+ 0x10,
+ 0x10,
+ 0x10,
+ 0x10,
+ 0x08,
+ 0x00
+};
+
+// Character 124 (0x7C)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | * |
+// | * |
+// | * |
+// | * |
+// | * |
+// | * |
+// | * |
+// | * |
+// | * |
+// | * |
+// | * |
+// | |
+// +------+
+static const byte glyph124[] = {
+ 0x20,
+ 0x20,
+ 0x20,
+ 0x20,
+ 0x20,
+ 0x20,
+ 0x20,
+ 0x20,
+ 0x20,
+ 0x20,
+ 0x20,
+ 0x00
+};
+
+// Character 125 (0x7D)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | * |
+// | * |
+// | * |
+// | * |
+// | * |
+// | * |
+// | * |
+// | * |
+// | * |
+// | * |
+// | * |
+// | |
+// +------+
+static const byte glyph125[] = {
+ 0x40,
+ 0x20,
+ 0x20,
+ 0x20,
+ 0x20,
+ 0x10,
+ 0x20,
+ 0x20,
+ 0x20,
+ 0x20,
+ 0x40,
+ 0x00
+};
+
+// Character 126 (0x7E)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// | |
+// | |
+// | |
+// | * |
+// |* * * |
+// | * |
+// | |
+// | |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph126[] = {
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x40,
+ 0xA8,
+ 0x10,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 160 (0xA0)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// | |
+// | |
+// | |
+// | |
+// | |
+// | |
+// | |
+// | |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph160[] = {
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 161 (0xA1)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// | * |
+// | |
+// | * |
+// | * |
+// | * |
+// | * |
+// | * |
+// | * |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph161[] = {
+ 0x00,
+ 0x20,
+ 0x00,
+ 0x20,
+ 0x20,
+ 0x20,
+ 0x20,
+ 0x20,
+ 0x20,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 162 (0xA2)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// | |
+// | |
+// | * |
+// | *** |
+// |* * * |
+// |* * |
+// |* * * |
+// | *** |
+// | * |
+// | |
+// | |
+// +------+
+static const byte glyph162[] = {
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x20,
+ 0x70,
+ 0xA8,
+ 0xA0,
+ 0xA8,
+ 0x70,
+ 0x20,
+ 0x00,
+ 0x00
+};
+
+// Character 163 (0xA3)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// | ** |
+// | * * |
+// | * |
+// |*** |
+// | * |
+// | * |
+// | * * |
+// |* ** |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph163[] = {
+ 0x00,
+ 0x30,
+ 0x48,
+ 0x40,
+ 0xE0,
+ 0x40,
+ 0x40,
+ 0x48,
+ 0xB0,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 164 (0xA4)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// | |
+// | |
+// | |
+// |* * |
+// | *** |
+// | * * |
+// | *** |
+// |* * |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph164[] = {
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x88,
+ 0x70,
+ 0x50,
+ 0x70,
+ 0x88,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 165 (0xA5)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// | |
+// |* * |
+// | * * |
+// | * |
+// | *** |
+// | * |
+// | *** |
+// | * |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph165[] = {
+ 0x00,
+ 0x00,
+ 0x88,
+ 0x50,
+ 0x20,
+ 0x70,
+ 0x20,
+ 0x70,
+ 0x20,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 166 (0xA6)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// | |
+// | * |
+// | * |
+// | * |
+// | |
+// | * |
+// | * |
+// | * |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph166[] = {
+ 0x00,
+ 0x00,
+ 0x20,
+ 0x20,
+ 0x20,
+ 0x00,
+ 0x20,
+ 0x20,
+ 0x20,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 167 (0xA7)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | ** |
+// | * * |
+// | * |
+// | ** |
+// | * * |
+// | * * |
+// | * * |
+// | ** |
+// | * |
+// | * * |
+// | ** |
+// | |
+// +------+
+static const byte glyph167[] = {
+ 0x30,
+ 0x48,
+ 0x40,
+ 0x30,
+ 0x48,
+ 0x48,
+ 0x48,
+ 0x30,
+ 0x08,
+ 0x48,
+ 0x30,
+ 0x00
+};
+
+// Character 168 (0xA8)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// | * * |
+// | * * |
+// | |
+// | |
+// | |
+// | |
+// | |
+// | |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph168[] = {
+ 0x00,
+ 0x50,
+ 0x50,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 169 (0xA9)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// | **** |
+// |* *|
+// |* ** *|
+// |* * *|
+// |* * *|
+// |* ** *|
+// |* *|
+// | **** |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph169[] = {
+ 0x00,
+ 0x78,
+ 0x84,
+ 0xB4,
+ 0xA4,
+ 0xA4,
+ 0xB4,
+ 0x84,
+ 0x78,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 170 (0xAA)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | ** |
+// | * |
+// | *** |
+// | * * |
+// | *** |
+// | |
+// | **** |
+// | |
+// | |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph170[] = {
+ 0x30,
+ 0x08,
+ 0x38,
+ 0x48,
+ 0x38,
+ 0x00,
+ 0x78,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 171 (0xAB)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// | |
+// | |
+// | * * |
+// | * * |
+// |* * |
+// | * * |
+// | * * |
+// | |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph171[] = {
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x28,
+ 0x50,
+ 0xA0,
+ 0x50,
+ 0x28,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 172 (0xAC)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// | |
+// | |
+// | |
+// | |
+// | **** |
+// | * |
+// | |
+// | |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph172[] = {
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x78,
+ 0x08,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 173 (0xAD)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// | |
+// | |
+// | |
+// | |
+// | **** |
+// | |
+// | |
+// | |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph173[] = {
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x78,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 174 (0xAE)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// | **** |
+// |* *|
+// |* ** *|
+// |* * **|
+// |* ** *|
+// |* * **|
+// |* *|
+// | **** |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph174[] = {
+ 0x00,
+ 0x78,
+ 0x84,
+ 0xB4,
+ 0xAC,
+ 0xB4,
+ 0xAC,
+ 0x84,
+ 0x78,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 175 (0xAF)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// | |
+// |***** |
+// | |
+// | |
+// | |
+// | |
+// | |
+// | |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph175[] = {
+ 0x00,
+ 0x00,
+ 0xF8,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 176 (0xB0)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// | ** |
+// | * * |
+// | * * |
+// | ** |
+// | |
+// | |
+// | |
+// | |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph176[] = {
+ 0x00,
+ 0x30,
+ 0x48,
+ 0x48,
+ 0x30,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 177 (0xB1)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// | |
+// | * |
+// | * |
+// |***** |
+// | * |
+// | * |
+// | |
+// |***** |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph177[] = {
+ 0x00,
+ 0x00,
+ 0x20,
+ 0x20,
+ 0xF8,
+ 0x20,
+ 0x20,
+ 0x00,
+ 0xF8,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 178 (0xB2)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | ** |
+// | * |
+// | * |
+// | * |
+// | *** |
+// | |
+// | |
+// | |
+// | |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph178[] = {
+ 0x60,
+ 0x10,
+ 0x20,
+ 0x40,
+ 0x70,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 179 (0xB3)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | ** |
+// | * |
+// | * |
+// | * |
+// | ** |
+// | |
+// | |
+// | |
+// | |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph179[] = {
+ 0x60,
+ 0x10,
+ 0x20,
+ 0x10,
+ 0x60,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 180 (0xB4)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// | * |
+// | * |
+// | |
+// | |
+// | |
+// | |
+// | |
+// | |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph180[] = {
+ 0x00,
+ 0x10,
+ 0x20,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 181 (0xB5)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// | |
+// | |
+// | |
+// |* * |
+// |* * |
+// |* * |
+// |** * |
+// |* ** |
+// |* |
+// |* |
+// | |
+// +------+
+static const byte glyph181[] = {
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x88,
+ 0x88,
+ 0x88,
+ 0xC8,
+ 0xB0,
+ 0x80,
+ 0x80,
+ 0x00
+};
+
+// Character 182 (0xB6)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// | |
+// | **** |
+// |*** * |
+// |*** * |
+// | ** * |
+// | * * |
+// | * * |
+// | * * |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph182[] = {
+ 0x00,
+ 0x00,
+ 0x78,
+ 0xE8,
+ 0xE8,
+ 0x68,
+ 0x28,
+ 0x28,
+ 0x28,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 183 (0xB7)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// | |
+// | |
+// | |
+// | |
+// | |
+// | ** |
+// | |
+// | |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph183[] = {
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x30,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 184 (0xB8)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// | |
+// | |
+// | |
+// | |
+// | |
+// | |
+// | |
+// | |
+// | * |
+// | * |
+// | |
+// +------+
+static const byte glyph184[] = {
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x10,
+ 0x20,
+ 0x00
+};
+
+// Character 185 (0xB9)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | * |
+// | ** |
+// | * |
+// | * |
+// | * |
+// | |
+// | |
+// | |
+// | |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph185[] = {
+ 0x20,
+ 0x60,
+ 0x20,
+ 0x20,
+ 0x20,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 186 (0xBA)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | ** |
+// | * * |
+// | * * |
+// | * * |
+// | ** |
+// | |
+// | **** |
+// | |
+// | |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph186[] = {
+ 0x30,
+ 0x48,
+ 0x48,
+ 0x48,
+ 0x30,
+ 0x00,
+ 0x78,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 187 (0xBB)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// | |
+// | |
+// |* * |
+// | * * |
+// | * * |
+// | * * |
+// |* * |
+// | |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph187[] = {
+ 0x00,
+ 0x00,
+ 0x00,
+ 0xA0,
+ 0x50,
+ 0x28,
+ 0x50,
+ 0xA0,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 188 (0xBC)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// | * |
+// | * |
+// | * |
+// | * * |
+// | * |
+// | * * |
+// | *** |
+// | * |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph188[] = {
+ 0x00,
+ 0x40,
+ 0x40,
+ 0x40,
+ 0x48,
+ 0x10,
+ 0x28,
+ 0x38,
+ 0x08,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 189 (0xBD)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// | * |
+// | * |
+// | * |
+// | *** |
+// | * |
+// | * |
+// | * |
+// | *** |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph189[] = {
+ 0x00,
+ 0x40,
+ 0x40,
+ 0x40,
+ 0x70,
+ 0x08,
+ 0x10,
+ 0x20,
+ 0x38,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 190 (0xBE)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// |** |
+// | * |
+// | * |
+// |** * |
+// | * |
+// | * * |
+// | *** |
+// | * |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph190[] = {
+ 0x00,
+ 0xC0,
+ 0x40,
+ 0x20,
+ 0xC8,
+ 0x10,
+ 0x28,
+ 0x38,
+ 0x08,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 191 (0xBF)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// | * |
+// | |
+// | * |
+// | * |
+// | * |
+// |* |
+// |* * |
+// | *** |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph191[] = {
+ 0x00,
+ 0x20,
+ 0x00,
+ 0x20,
+ 0x20,
+ 0x40,
+ 0x80,
+ 0x88,
+ 0x70,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 192 (0xC0)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | * |
+// | * |
+// | |
+// | *** |
+// |* * |
+// |* * |
+// |***** |
+// |* * |
+// |* * |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph192[] = {
+ 0x40,
+ 0x20,
+ 0x00,
+ 0x70,
+ 0x88,
+ 0x88,
+ 0xF8,
+ 0x88,
+ 0x88,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 193 (0xC1)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | * |
+// | * |
+// | |
+// | *** |
+// |* * |
+// |* * |
+// |***** |
+// |* * |
+// |* * |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph193[] = {
+ 0x10,
+ 0x20,
+ 0x00,
+ 0x70,
+ 0x88,
+ 0x88,
+ 0xF8,
+ 0x88,
+ 0x88,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 194 (0xC2)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | * |
+// | * * |
+// | |
+// | *** |
+// |* * |
+// |* * |
+// |***** |
+// |* * |
+// |* * |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph194[] = {
+ 0x20,
+ 0x50,
+ 0x00,
+ 0x70,
+ 0x88,
+ 0x88,
+ 0xF8,
+ 0x88,
+ 0x88,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 195 (0xC3)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | * * |
+// | * * |
+// | |
+// | *** |
+// |* * |
+// |* * |
+// |***** |
+// |* * |
+// |* * |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph195[] = {
+ 0x28,
+ 0x50,
+ 0x00,
+ 0x70,
+ 0x88,
+ 0x88,
+ 0xF8,
+ 0x88,
+ 0x88,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 196 (0xC4)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// | * * |
+// | |
+// | *** |
+// |* * |
+// |* * |
+// |***** |
+// |* * |
+// |* * |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph196[] = {
+ 0x00,
+ 0x50,
+ 0x00,
+ 0x70,
+ 0x88,
+ 0x88,
+ 0xF8,
+ 0x88,
+ 0x88,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 197 (0xC5)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | * |
+// | * * |
+// | * |
+// | *** |
+// |* * |
+// |* * |
+// |***** |
+// |* * |
+// |* * |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph197[] = {
+ 0x20,
+ 0x50,
+ 0x20,
+ 0x70,
+ 0x88,
+ 0x88,
+ 0xF8,
+ 0x88,
+ 0x88,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 198 (0xC6)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// | |
+// | **** |
+// |* * |
+// |* * |
+// |* *** |
+// |*** |
+// |* * |
+// |* *** |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph198[] = {
+ 0x00,
+ 0x00,
+ 0x78,
+ 0xA0,
+ 0xA0,
+ 0xB8,
+ 0xE0,
+ 0xA0,
+ 0xB8,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 199 (0xC7)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// | |
+// | *** |
+// |* * |
+// |* |
+// |* |
+// |* |
+// |* * |
+// | *** |
+// | * |
+// | * |
+// | |
+// +------+
+static const byte glyph199[] = {
+ 0x00,
+ 0x00,
+ 0x70,
+ 0x88,
+ 0x80,
+ 0x80,
+ 0x80,
+ 0x88,
+ 0x70,
+ 0x20,
+ 0x40,
+ 0x00
+};
+
+// Character 200 (0xC8)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | * |
+// | * |
+// | |
+// |***** |
+// |* |
+// |**** |
+// |* |
+// |* |
+// |***** |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph200[] = {
+ 0x40,
+ 0x20,
+ 0x00,
+ 0xF8,
+ 0x80,
+ 0xF0,
+ 0x80,
+ 0x80,
+ 0xF8,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 201 (0xC9)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | * |
+// | * |
+// | |
+// |***** |
+// |* |
+// |**** |
+// |* |
+// |* |
+// |***** |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph201[] = {
+ 0x10,
+ 0x20,
+ 0x00,
+ 0xF8,
+ 0x80,
+ 0xF0,
+ 0x80,
+ 0x80,
+ 0xF8,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 202 (0xCA)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | * |
+// | * * |
+// | |
+// |***** |
+// |* |
+// |**** |
+// |* |
+// |* |
+// |***** |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph202[] = {
+ 0x20,
+ 0x50,
+ 0x00,
+ 0xF8,
+ 0x80,
+ 0xF0,
+ 0x80,
+ 0x80,
+ 0xF8,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 203 (0xCB)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// | * * |
+// | |
+// |***** |
+// |* |
+// |**** |
+// |* |
+// |* |
+// |***** |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph203[] = {
+ 0x00,
+ 0x50,
+ 0x00,
+ 0xF8,
+ 0x80,
+ 0xF0,
+ 0x80,
+ 0x80,
+ 0xF8,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 204 (0xCC)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | * |
+// | * |
+// | |
+// |***** |
+// | * |
+// | * |
+// | * |
+// | * |
+// |***** |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph204[] = {
+ 0x40,
+ 0x20,
+ 0x00,
+ 0xF8,
+ 0x20,
+ 0x20,
+ 0x20,
+ 0x20,
+ 0xF8,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 205 (0xCD)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | * |
+// | * |
+// | |
+// |***** |
+// | * |
+// | * |
+// | * |
+// | * |
+// |***** |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph205[] = {
+ 0x10,
+ 0x20,
+ 0x00,
+ 0xF8,
+ 0x20,
+ 0x20,
+ 0x20,
+ 0x20,
+ 0xF8,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 206 (0xCE)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | * |
+// | * * |
+// | |
+// |***** |
+// | * |
+// | * |
+// | * |
+// | * |
+// |***** |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph206[] = {
+ 0x20,
+ 0x50,
+ 0x00,
+ 0xF8,
+ 0x20,
+ 0x20,
+ 0x20,
+ 0x20,
+ 0xF8,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 207 (0xCF)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// | * * |
+// | |
+// |***** |
+// | * |
+// | * |
+// | * |
+// | * |
+// |***** |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph207[] = {
+ 0x00,
+ 0x50,
+ 0x00,
+ 0xF8,
+ 0x20,
+ 0x20,
+ 0x20,
+ 0x20,
+ 0xF8,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 208 (0xD0)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// | |
+// | *** |
+// | * * |
+// | * *|
+// |*** *|
+// | * *|
+// | * * |
+// | *** |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph208[] = {
+ 0x00,
+ 0x00,
+ 0x70,
+ 0x48,
+ 0x44,
+ 0xE4,
+ 0x44,
+ 0x48,
+ 0x70,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 209 (0xD1)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | * * |
+// | * * |
+// | |
+// |* * |
+// |** * |
+// |* * * |
+// |* ** |
+// |* * |
+// |* * |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph209[] = {
+ 0x28,
+ 0x50,
+ 0x00,
+ 0x88,
+ 0xC8,
+ 0xA8,
+ 0x98,
+ 0x88,
+ 0x88,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 210 (0xD2)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | * |
+// | * |
+// | |
+// | *** |
+// |* * |
+// |* * |
+// |* * |
+// |* * |
+// | *** |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph210[] = {
+ 0x40,
+ 0x20,
+ 0x00,
+ 0x70,
+ 0x88,
+ 0x88,
+ 0x88,
+ 0x88,
+ 0x70,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 211 (0xD3)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | * |
+// | * |
+// | |
+// | *** |
+// |* * |
+// |* * |
+// |* * |
+// |* * |
+// | *** |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph211[] = {
+ 0x10,
+ 0x20,
+ 0x00,
+ 0x70,
+ 0x88,
+ 0x88,
+ 0x88,
+ 0x88,
+ 0x70,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 212 (0xD4)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | * |
+// | * * |
+// | |
+// | *** |
+// |* * |
+// |* * |
+// |* * |
+// |* * |
+// | *** |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph212[] = {
+ 0x20,
+ 0x50,
+ 0x00,
+ 0x70,
+ 0x88,
+ 0x88,
+ 0x88,
+ 0x88,
+ 0x70,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 213 (0xD5)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | * * |
+// | * * |
+// | |
+// | *** |
+// |* * |
+// |* * |
+// |* * |
+// |* * |
+// | *** |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph213[] = {
+ 0x28,
+ 0x50,
+ 0x00,
+ 0x70,
+ 0x88,
+ 0x88,
+ 0x88,
+ 0x88,
+ 0x70,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 214 (0xD6)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// | * * |
+// | |
+// | *** |
+// |* * |
+// |* * |
+// |* * |
+// |* * |
+// | *** |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph214[] = {
+ 0x00,
+ 0x50,
+ 0x00,
+ 0x70,
+ 0x88,
+ 0x88,
+ 0x88,
+ 0x88,
+ 0x70,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 215 (0xD7)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// | |
+// | |
+// | |
+// |* * |
+// | * * |
+// | * |
+// | * * |
+// |* * |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph215[] = {
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x88,
+ 0x50,
+ 0x20,
+ 0x50,
+ 0x88,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 216 (0xD8)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// | * |
+// | **** |
+// |* ** |
+// |* * * |
+// |* * * |
+// |* * * |
+// |** * |
+// |**** |
+// |* |
+// | |
+// | |
+// +------+
+static const byte glyph216[] = {
+ 0x00,
+ 0x08,
+ 0x78,
+ 0x98,
+ 0xA8,
+ 0xA8,
+ 0xA8,
+ 0xC8,
+ 0xF0,
+ 0x80,
+ 0x00,
+ 0x00
+};
+
+// Character 217 (0xD9)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | * |
+// | * |
+// | |
+// |* * |
+// |* * |
+// |* * |
+// |* * |
+// |* * |
+// | *** |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph217[] = {
+ 0x40,
+ 0x20,
+ 0x00,
+ 0x88,
+ 0x88,
+ 0x88,
+ 0x88,
+ 0x88,
+ 0x70,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 218 (0xDA)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | * |
+// | * |
+// | |
+// |* * |
+// |* * |
+// |* * |
+// |* * |
+// |* * |
+// | *** |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph218[] = {
+ 0x10,
+ 0x20,
+ 0x00,
+ 0x88,
+ 0x88,
+ 0x88,
+ 0x88,
+ 0x88,
+ 0x70,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 219 (0xDB)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | * |
+// | * * |
+// | |
+// |* * |
+// |* * |
+// |* * |
+// |* * |
+// |* * |
+// | *** |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph219[] = {
+ 0x20,
+ 0x50,
+ 0x00,
+ 0x88,
+ 0x88,
+ 0x88,
+ 0x88,
+ 0x88,
+ 0x70,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 220 (0xDC)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// | * * |
+// | |
+// |* * |
+// |* * |
+// |* * |
+// |* * |
+// |* * |
+// | *** |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph220[] = {
+ 0x00,
+ 0x50,
+ 0x00,
+ 0x88,
+ 0x88,
+ 0x88,
+ 0x88,
+ 0x88,
+ 0x70,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 221 (0xDD)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | * |
+// | * |
+// | |
+// |* * |
+// | * * |
+// | * |
+// | * |
+// | * |
+// | * |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph221[] = {
+ 0x10,
+ 0x20,
+ 0x00,
+ 0x88,
+ 0x50,
+ 0x20,
+ 0x20,
+ 0x20,
+ 0x20,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 222 (0xDE)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// |* |
+// |**** |
+// |* * |
+// |* * |
+// |* * |
+// |**** |
+// |* |
+// |* |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph222[] = {
+ 0x00,
+ 0x80,
+ 0xF0,
+ 0x88,
+ 0x88,
+ 0x88,
+ 0xF0,
+ 0x80,
+ 0x80,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 223 (0xDF)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// | ** |
+// | * * |
+// | * * |
+// |** * |
+// | * * |
+// | * * |
+// | * * |
+// | * * |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph223[] = {
+ 0x00,
+ 0x30,
+ 0x48,
+ 0x48,
+ 0xD0,
+ 0x50,
+ 0x48,
+ 0x48,
+ 0x50,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 224 (0xE0)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// | * |
+// | * |
+// | |
+// | **** |
+// |* * |
+// |* * |
+// |* ** |
+// | ** * |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph224[] = {
+ 0x00,
+ 0x40,
+ 0x20,
+ 0x00,
+ 0x78,
+ 0x88,
+ 0x88,
+ 0x98,
+ 0x68,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 225 (0xE1)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// | * |
+// | * |
+// | |
+// | **** |
+// |* * |
+// |* * |
+// |* ** |
+// | ** * |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph225[] = {
+ 0x00,
+ 0x10,
+ 0x20,
+ 0x00,
+ 0x78,
+ 0x88,
+ 0x88,
+ 0x98,
+ 0x68,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 226 (0xE2)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// | * |
+// | * * |
+// | |
+// | **** |
+// |* * |
+// |* * |
+// |* ** |
+// | ** * |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph226[] = {
+ 0x00,
+ 0x20,
+ 0x50,
+ 0x00,
+ 0x78,
+ 0x88,
+ 0x88,
+ 0x98,
+ 0x68,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 227 (0xE3)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// | * * |
+// | * * |
+// | |
+// | **** |
+// |* * |
+// |* * |
+// |* ** |
+// | ** * |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph227[] = {
+ 0x00,
+ 0x28,
+ 0x50,
+ 0x00,
+ 0x78,
+ 0x88,
+ 0x88,
+ 0x98,
+ 0x68,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 228 (0xE4)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// | |
+// | * * |
+// | |
+// | **** |
+// |* * |
+// |* * |
+// |* ** |
+// | ** * |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph228[] = {
+ 0x00,
+ 0x00,
+ 0x50,
+ 0x00,
+ 0x78,
+ 0x88,
+ 0x88,
+ 0x98,
+ 0x68,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 229 (0xE5)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | * |
+// | * * |
+// | * |
+// | |
+// | **** |
+// |* * |
+// |* * |
+// |* ** |
+// | ** * |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph229[] = {
+ 0x20,
+ 0x50,
+ 0x20,
+ 0x00,
+ 0x78,
+ 0x88,
+ 0x88,
+ 0x98,
+ 0x68,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 230 (0xE6)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// | |
+// | |
+// | |
+// | *** |
+// | * * |
+// | *** |
+// |* * |
+// | **** |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph230[] = {
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x70,
+ 0x28,
+ 0x70,
+ 0xA0,
+ 0x78,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 231 (0xE7)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// | |
+// | |
+// | |
+// | **** |
+// |* |
+// |* |
+// |* |
+// | **** |
+// | * |
+// | * |
+// | |
+// +------+
+static const byte glyph231[] = {
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x78,
+ 0x80,
+ 0x80,
+ 0x80,
+ 0x78,
+ 0x20,
+ 0x40,
+ 0x00
+};
+
+// Character 232 (0xE8)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// | * |
+// | * |
+// | |
+// | *** |
+// |* * |
+// |***** |
+// |* |
+// | *** |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph232[] = {
+ 0x00,
+ 0x40,
+ 0x20,
+ 0x00,
+ 0x70,
+ 0x88,
+ 0xF8,
+ 0x80,
+ 0x70,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 233 (0xE9)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// | * |
+// | * |
+// | |
+// | *** |
+// |* * |
+// |***** |
+// |* |
+// | *** |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph233[] = {
+ 0x00,
+ 0x10,
+ 0x20,
+ 0x00,
+ 0x70,
+ 0x88,
+ 0xF8,
+ 0x80,
+ 0x70,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 234 (0xEA)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// | * |
+// | * * |
+// | |
+// | *** |
+// |* * |
+// |***** |
+// |* |
+// | *** |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph234[] = {
+ 0x00,
+ 0x20,
+ 0x50,
+ 0x00,
+ 0x70,
+ 0x88,
+ 0xF8,
+ 0x80,
+ 0x70,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 235 (0xEB)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// | |
+// | * * |
+// | |
+// | *** |
+// |* * |
+// |***** |
+// |* |
+// | *** |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph235[] = {
+ 0x00,
+ 0x00,
+ 0x50,
+ 0x00,
+ 0x70,
+ 0x88,
+ 0xF8,
+ 0x80,
+ 0x70,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 236 (0xEC)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// | * |
+// | * |
+// | |
+// | ** |
+// | * |
+// | * |
+// | * |
+// | *** |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph236[] = {
+ 0x00,
+ 0x40,
+ 0x20,
+ 0x00,
+ 0x60,
+ 0x20,
+ 0x20,
+ 0x20,
+ 0x70,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 237 (0xED)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// | * |
+// | * |
+// | |
+// | ** |
+// | * |
+// | * |
+// | * |
+// | *** |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph237[] = {
+ 0x00,
+ 0x20,
+ 0x40,
+ 0x00,
+ 0x60,
+ 0x20,
+ 0x20,
+ 0x20,
+ 0x70,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 238 (0xEE)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// | * |
+// | * * |
+// | |
+// | ** |
+// | * |
+// | * |
+// | * |
+// | *** |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph238[] = {
+ 0x00,
+ 0x20,
+ 0x50,
+ 0x00,
+ 0x60,
+ 0x20,
+ 0x20,
+ 0x20,
+ 0x70,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 239 (0xEF)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// | |
+// | * * |
+// | |
+// | ** |
+// | * |
+// | * |
+// | * |
+// | *** |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph239[] = {
+ 0x00,
+ 0x00,
+ 0x50,
+ 0x00,
+ 0x60,
+ 0x20,
+ 0x20,
+ 0x20,
+ 0x70,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 240 (0xF0)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// | * * |
+// | * |
+// | * * |
+// | * |
+// | **** |
+// |* * |
+// |* * |
+// | *** |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph240[] = {
+ 0x00,
+ 0x28,
+ 0x10,
+ 0x28,
+ 0x08,
+ 0x78,
+ 0x88,
+ 0x88,
+ 0x70,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 241 (0xF1)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// | * * |
+// | * * |
+// | |
+// |* ** |
+// |** * |
+// |* * |
+// |* * |
+// |* * |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph241[] = {
+ 0x00,
+ 0x28,
+ 0x50,
+ 0x00,
+ 0xB0,
+ 0xC8,
+ 0x88,
+ 0x88,
+ 0x88,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 242 (0xF2)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// | * |
+// | * |
+// | |
+// | *** |
+// |* * |
+// |* * |
+// |* * |
+// | *** |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph242[] = {
+ 0x00,
+ 0x40,
+ 0x20,
+ 0x00,
+ 0x70,
+ 0x88,
+ 0x88,
+ 0x88,
+ 0x70,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 243 (0xF3)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// | * |
+// | * |
+// | |
+// | *** |
+// |* * |
+// |* * |
+// |* * |
+// | *** |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph243[] = {
+ 0x00,
+ 0x10,
+ 0x20,
+ 0x00,
+ 0x70,
+ 0x88,
+ 0x88,
+ 0x88,
+ 0x70,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 244 (0xF4)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// | * |
+// | * * |
+// | |
+// | *** |
+// |* * |
+// |* * |
+// |* * |
+// | *** |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph244[] = {
+ 0x00,
+ 0x20,
+ 0x50,
+ 0x00,
+ 0x70,
+ 0x88,
+ 0x88,
+ 0x88,
+ 0x70,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 245 (0xF5)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// | * * |
+// | * * |
+// | |
+// | *** |
+// |* * |
+// |* * |
+// |* * |
+// | *** |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph245[] = {
+ 0x00,
+ 0x28,
+ 0x50,
+ 0x00,
+ 0x70,
+ 0x88,
+ 0x88,
+ 0x88,
+ 0x70,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 246 (0xF6)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// | |
+// | * * |
+// | |
+// | *** |
+// |* * |
+// |* * |
+// |* * |
+// | *** |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph246[] = {
+ 0x00,
+ 0x00,
+ 0x50,
+ 0x00,
+ 0x70,
+ 0x88,
+ 0x88,
+ 0x88,
+ 0x70,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 247 (0xF7)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// | |
+// | |
+// | |
+// | * |
+// | |
+// |***** |
+// | |
+// | * |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph247[] = {
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x20,
+ 0x00,
+ 0xF8,
+ 0x00,
+ 0x20,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 248 (0xF8)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// | |
+// | |
+// | * |
+// | **** |
+// |* ** |
+// |* * * |
+// |** * |
+// |**** |
+// |* |
+// | |
+// | |
+// +------+
+static const byte glyph248[] = {
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x08,
+ 0x78,
+ 0x98,
+ 0xA8,
+ 0xC8,
+ 0xF0,
+ 0x80,
+ 0x00,
+ 0x00
+};
+
+// Character 249 (0xF9)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// | * |
+// | * |
+// | |
+// |* * |
+// |* * |
+// |* * |
+// |* ** |
+// | ** * |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph249[] = {
+ 0x00,
+ 0x40,
+ 0x20,
+ 0x00,
+ 0x88,
+ 0x88,
+ 0x88,
+ 0x98,
+ 0x68,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 250 (0xFA)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// | * |
+// | * |
+// | |
+// |* * |
+// |* * |
+// |* * |
+// |* ** |
+// | ** * |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph250[] = {
+ 0x00,
+ 0x10,
+ 0x20,
+ 0x00,
+ 0x88,
+ 0x88,
+ 0x88,
+ 0x98,
+ 0x68,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 251 (0xFB)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// | * |
+// | * * |
+// | |
+// |* * |
+// |* * |
+// |* * |
+// |* ** |
+// | ** * |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph251[] = {
+ 0x00,
+ 0x20,
+ 0x50,
+ 0x00,
+ 0x88,
+ 0x88,
+ 0x88,
+ 0x98,
+ 0x68,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 252 (0xFC)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// | |
+// | * * |
+// | |
+// |* * |
+// |* * |
+// |* * |
+// |* ** |
+// | ** * |
+// | |
+// | |
+// | |
+// +------+
+static const byte glyph252[] = {
+ 0x00,
+ 0x00,
+ 0x50,
+ 0x00,
+ 0x88,
+ 0x88,
+ 0x88,
+ 0x98,
+ 0x68,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+// Character 253 (0xFD)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// | * |
+// | * |
+// | |
+// |* * |
+// |* * |
+// |* * |
+// |* * |
+// | **** |
+// | * |
+// | * |
+// | *** |
+// +------+
+static const byte glyph253[] = {
+ 0x00,
+ 0x10,
+ 0x20,
+ 0x00,
+ 0x88,
+ 0x88,
+ 0x88,
+ 0x88,
+ 0x78,
+ 0x08,
+ 0x08,
+ 0x70
+};
+
+// Character 254 (0xFE)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// |* |
+// |* |
+// |* |
+// |* ** |
+// |** * |
+// |* * |
+// |** * |
+// |* ** |
+// |* |
+// |* |
+// | |
+// +------+
+static const byte glyph254[] = {
+ 0x00,
+ 0x80,
+ 0x80,
+ 0x80,
+ 0xB0,
+ 0xC8,
+ 0x88,
+ 0xC8,
+ 0xB0,
+ 0x80,
+ 0x80,
+ 0x00
+};
+
+// Character 255 (0xFF)
+// Box: 6 12 0 -3
+// Advance: 6
+//
+// +------+
+// | |
+// | |
+// | * * |
+// | |
+// |* * |
+// |* * |
+// |* * |
+// |* * |
+// | **** |
+// | * |
+// | * |
+// | *** |
+// +------+
+static const byte glyph255[] = {
+ 0x00,
+ 0x00,
+ 0x50,
+ 0x00,
+ 0x88,
+ 0x88,
+ 0x88,
+ 0x88,
+ 0x78,
+ 0x08,
+ 0x08,
+ 0x70
+};
+
+// Bitmap pointer table
+const byte *const bitmapTable[] = {
+ glyph0,
+ glyph1,
+ glyph2,
+ glyph3,
+ glyph4,
+ glyph5,
+ glyph6,
+ glyph7,
+ glyph8,
+ glyph9,
+ glyph10,
+ glyph11,
+ glyph12,
+ glyph13,
+ glyph14,
+ glyph15,
+ glyph16,
+ glyph17,
+ glyph18,
+ glyph19,
+ glyph20,
+ glyph21,
+ glyph22,
+ glyph23,
+ glyph24,
+ glyph25,
+ glyph26,
+ glyph27,
+ glyph28,
+ glyph29,
+ glyph30,
+ glyph31,
+ glyph32,
+ glyph33,
+ glyph34,
+ glyph35,
+ glyph36,
+ glyph37,
+ glyph38,
+ glyph39,
+ glyph40,
+ glyph41,
+ glyph42,
+ glyph43,
+ glyph44,
+ glyph45,
+ glyph46,
+ glyph47,
+ glyph48,
+ glyph49,
+ glyph50,
+ glyph51,
+ glyph52,
+ glyph53,
+ glyph54,
+ glyph55,
+ glyph56,
+ glyph57,
+ glyph58,
+ glyph59,
+ glyph60,
+ glyph61,
+ glyph62,
+ glyph63,
+ glyph64,
+ glyph65,
+ glyph66,
+ glyph67,
+ glyph68,
+ glyph69,
+ glyph70,
+ glyph71,
+ glyph72,
+ glyph73,
+ glyph74,
+ glyph75,
+ glyph76,
+ glyph77,
+ glyph78,
+ glyph79,
+ glyph80,
+ glyph81,
+ glyph82,
+ glyph83,
+ glyph84,
+ glyph85,
+ glyph86,
+ glyph87,
+ glyph88,
+ glyph89,
+ glyph90,
+ glyph91,
+ glyph92,
+ glyph93,
+ glyph94,
+ glyph95,
+ glyph96,
+ glyph97,
+ glyph98,
+ glyph99,
+ glyph100,
+ glyph101,
+ glyph102,
+ glyph103,
+ glyph104,
+ glyph105,
+ glyph106,
+ glyph107,
+ glyph108,
+ glyph109,
+ glyph110,
+ glyph111,
+ glyph112,
+ glyph113,
+ glyph114,
+ glyph115,
+ glyph116,
+ glyph117,
+ glyph118,
+ glyph119,
+ glyph120,
+ glyph121,
+ glyph122,
+ glyph123,
+ glyph124,
+ glyph125,
+ glyph126,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
0,
- 256,
- _font_bits,
- _sysfont_offset,
- 0, /* fixed width*/
- 0, /* fixed bbox*/
0,
- sizeof(_font_bits)/sizeof(bitmap_t)
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ glyph160,
+ glyph161,
+ glyph162,
+ glyph163,
+ glyph164,
+ glyph165,
+ glyph166,
+ glyph167,
+ glyph168,
+ glyph169,
+ glyph170,
+ glyph171,
+ glyph172,
+ glyph173,
+ glyph174,
+ glyph175,
+ glyph176,
+ glyph177,
+ glyph178,
+ glyph179,
+ glyph180,
+ glyph181,
+ glyph182,
+ glyph183,
+ glyph184,
+ glyph185,
+ glyph186,
+ glyph187,
+ glyph188,
+ glyph189,
+ glyph190,
+ glyph191,
+ glyph192,
+ glyph193,
+ glyph194,
+ glyph195,
+ glyph196,
+ glyph197,
+ glyph198,
+ glyph199,
+ glyph200,
+ glyph201,
+ glyph202,
+ glyph203,
+ glyph204,
+ glyph205,
+ glyph206,
+ glyph207,
+ glyph208,
+ glyph209,
+ glyph210,
+ glyph211,
+ glyph212,
+ glyph213,
+ glyph214,
+ glyph215,
+ glyph216,
+ glyph217,
+ glyph218,
+ glyph219,
+ glyph220,
+ glyph221,
+ glyph222,
+ glyph223,
+ glyph224,
+ glyph225,
+ glyph226,
+ glyph227,
+ glyph228,
+ glyph229,
+ glyph230,
+ glyph231,
+ glyph232,
+ glyph233,
+ glyph234,
+ glyph235,
+ glyph236,
+ glyph237,
+ glyph238,
+ glyph239,
+ glyph240,
+ glyph241,
+ glyph242,
+ glyph243,
+ glyph244,
+ glyph245,
+ glyph246,
+ glyph247,
+ glyph248,
+ glyph249,
+ glyph250,
+ glyph251,
+ glyph252,
+ glyph253,
+ glyph254,
+ glyph255
+};
+
+// Font structure
+static const BdfFontData desc = {
+ 6, // Max advance
+ 12, // Height
+ { 6, 12, 0, -3 }, // Bounding box
+ 9, // Ascent
+
+ 0, // First character
+ 0, // Default character
+ 256, // Characters
+
+ bitmapTable, // Bitmaps
+ 0, // Advances
+ 0 // Boxes
};
DEFINE_FONT(g_sysfont)
diff --git a/graphics/fonts/newfont_big.cpp b/graphics/fonts/newfont_big.cpp
index 59c54a4551..0e61068ade 100644
--- a/graphics/fonts/newfont_big.cpp
+++ b/graphics/fonts/newfont_big.cpp
@@ -1,5542 +1,5846 @@
-/* Generated by convbdf on Tue Jun 13 00:00:22 2006. */
+// Generated by convbdf on Fri Jan 6 14:33:14 2012
#include "graphics/fonts/bdf.h"
-/* Font information:
- name: helvB12-L1
- facename: -Adobe-Helvetica-Bold-R-Normal--12-120-75-75-P-70-ISO8859-1
- w x h: 13x14
- bbx: 13 15 -1 -3
- size: 224
- ascent: 11
- descent: 3
- first char: 32 (0x20)
- last char: 255 (0xff)
- default char: 32 (0x20)
- proportional: yes
- Copyright (c) 1984, 1987 Adobe Systems Incorporated. All Rights Reserved. Copyright (c) 1988, 1991 Digital Equipment Corporation. All Rights Reserved.
-*/
+// Font information:
+// Name: -Adobe-Helvetica-Bold-R-Normal--12-120-75-75-P-70-ISO8859-1
+// Size: 13x14
+// Box: 13 15 -1 -3
+// Ascent: 11
+// First character: 0
+// Default character: 0
+// Characters: 256
+// Copyright: "Copyright (c) 1984, 1987 Adobe Systems Incorporated. All Rights Reserved. Copyright (c) 1988, 1991 Digital Equipment Corporation. All Rights Reserved."
namespace Graphics {
-/* Font character bitmap data. */
-static const bitmap_t _font_bits[] = {
-
-/* Character 32 (0x20):
- width 12
- bbx ( 1, 1, 0, 0 )
-
- +-+
- | |
- +-+
-*/
-0x0000,
-
-/* Character 33 (0x21):
- width 8
- bbx ( 2, 9, 1, 0 )
-
- +--+
- |**|
- |**|
- |**|
- |**|
- |**|
- |* |
- | |
- |**|
- |**|
- +--+
-*/
-0xc000,
-0xc000,
-0xc000,
-0xc000,
-0xc000,
-0x8000,
-0x0000,
-0xc000,
-0xc000,
-
-/* Character 34 (0x22):
- width 9
- bbx ( 3, 3, 1, 6 )
-
- +---+
- |* *|
- |* *|
- |* *|
- +---+
-*/
-0xa000,
-0xa000,
-0xa000,
-
-/* Character 35 (0x23):
- width 8
- bbx ( 7, 8, 0, 0 )
-
- +-------+
- | * * |
- | * * |
- | ******|
- | * * |
- | * * |
- |****** |
- | * * |
- | * * |
- +-------+
-*/
-0x1400,
-0x1400,
-0x7e00,
-0x2800,
-0x2800,
-0xfc00,
-0x5000,
-0x5000,
-
-/* Character 36 (0x24):
- width 9
- bbx ( 6, 11, 0, -2 )
-
- +------+
- | * |
- | **** |
- |** * *|
- |** * |
- | **** |
- | ***|
- |* * *|
- |** * *|
- | **** |
- | * |
- | * |
- +------+
-*/
-0x1000,
-0x7800,
-0xd400,
-0xd000,
-0x7800,
-0x1c00,
-0x9400,
-0xd400,
-0x7800,
-0x1000,
-0x1000,
-
-/* Character 37 (0x25):
- width 8
- bbx ( 11, 9, 0, 0 )
-
- +-----------+
- | *** * |
- |** ** ** |
- |** ** * |
- | *** * |
- | * |
- | * *** |
- | * ** **|
- | ** ** **|
- | * *** |
- +-----------+
-*/
-0x7100,
-0xdb00,
-0xda00,
-0x7400,
-0x0400,
-0x09c0,
-0x0b60,
-0x1b60,
-0x11c0,
-
-/* Character 38 (0x26):
- width 7
- bbx ( 9, 9, 0, 0 )
-
- +---------+
- | *** |
- | ** ** |
- | ** ** |
- | *** |
- | **** * |
- |** **** |
- |** ** |
- |** **** |
- | **** **|
- +---------+
-*/
-0x3800,
-0x6c00,
-0x6c00,
-0x3800,
-0x7900,
-0xcf00,
-0xc600,
-0xcf00,
-0x7980,
-
-/* Character 39 (0x27):
- width 10
- bbx ( 1, 3, 1, 6 )
-
- +-+
- |*|
- |*|
- |*|
- +-+
-*/
-0x8000,
-0x8000,
-0x8000,
-
-/* Character 40 (0x28):
- width 9
- bbx ( 4, 12, 1, -3 )
-
- +----+
- | **|
- | ** |
- | ** |
- |** |
- |** |
- |** |
- |** |
- |** |
- |** |
- | ** |
- | ** |
- | **|
- +----+
-*/
-0x3000,
-0x6000,
-0x6000,
-0xc000,
-0xc000,
-0xc000,
-0xc000,
-0xc000,
-0xc000,
-0x6000,
-0x6000,
-0x3000,
-
-/* Character 41 (0x29):
- width 4
- bbx ( 4, 12, 1, -3 )
-
- +----+
- |** |
- | ** |
- | ** |
- | **|
- | **|
- | **|
- | **|
- | **|
- | **|
- | ** |
- | ** |
- |** |
- +----+
-*/
-0xc000,
-0x6000,
-0x6000,
-0x3000,
-0x3000,
-0x3000,
-0x3000,
-0x3000,
-0x3000,
-0x6000,
-0x6000,
-0xc000,
-
-/* Character 42 (0x2a):
- width 7
- bbx ( 5, 4, 0, 5 )
-
- +-----+
- | * |
- |*****|
- | *** |
- | * * |
- +-----+
-*/
-0x2000,
-0xf800,
-0x7000,
-0x5000,
-
-/* Character 43 (0x2b):
- width 9
- bbx ( 6, 5, 0, 1 )
-
- +------+
- | ** |
- | ** |
- |******|
- | ** |
- | ** |
- +------+
-*/
-0x3000,
-0x3000,
-0xfc00,
-0x3000,
-0x3000,
-
-/* Character 44 (0x2c):
- width 7
- bbx ( 2, 4, 1, -2 )
-
- +--+
- |**|
- |**|
- | *|
- |* |
- +--+
-*/
-0xc000,
-0xc000,
-0x4000,
-0x8000,
-
-/* Character 45 (0x2d):
- width 11
- bbx ( 4, 1, 0, 3 )
-
- +----+
- |****|
- +----+
-*/
-0xf000,
-
-/* Character 46 (0x2e):
- width 9
- bbx ( 2, 2, 1, 0 )
-
- +--+
- |**|
- |**|
- +--+
-*/
-0xc000,
-0xc000,
-
-/* Character 47 (0x2f):
- width 10
- bbx ( 4, 9, 0, 0 )
-
- +----+
- | **|
- | **|
- | * |
- | ** |
- | ** |
- | * |
- | * |
- |** |
- |** |
- +----+
-*/
-0x3000,
-0x3000,
-0x2000,
-0x6000,
-0x6000,
-0x4000,
-0x4000,
-0xc000,
-0xc000,
-
-/* Character 48 (0x30):
- width 8
- bbx ( 6, 9, 0, 0 )
-
- +------+
- | **** |
- |** **|
- |** **|
- |** **|
- |** **|
- |** **|
- |** **|
- |** **|
- | **** |
- +------+
-*/
-0x7800,
-0xcc00,
-0xcc00,
-0xcc00,
-0xcc00,
-0xcc00,
-0xcc00,
-0xcc00,
-0x7800,
-
-/* Character 49 (0x31):
- width 10
- bbx ( 4, 9, 0, 0 )
-
- +----+
- | **|
- |****|
- | **|
- | **|
- | **|
- | **|
- | **|
- | **|
- | **|
- +----+
-*/
-0x3000,
-0xf000,
-0x3000,
-0x3000,
-0x3000,
-0x3000,
-0x3000,
-0x3000,
-0x3000,
-
-/* Character 50 (0x32):
- width 9
- bbx ( 6, 9, 0, 0 )
-
- +------+
- | **** |
- |** **|
- | **|
- | ** |
- | ** |
- | ** |
- |** |
- |** |
- |******|
- +------+
-*/
-0x7800,
-0xcc00,
-0x0c00,
-0x1800,
-0x3000,
-0x6000,
-0xc000,
-0xc000,
-0xfc00,
-
-/* Character 51 (0x33):
- width 9
- bbx ( 6, 9, 0, 0 )
-
- +------+
- | **** |
- |** **|
- | **|
- | *** |
- | **|
- | **|
- | **|
- |** **|
- | **** |
- +------+
-*/
-0x7800,
-0xcc00,
-0x0c00,
-0x3800,
-0x0c00,
-0x0c00,
-0x0c00,
-0xcc00,
-0x7800,
-
-/* Character 52 (0x34):
- width 8
- bbx ( 7, 9, 0, 0 )
-
- +-------+
- | ** |
- | *** |
- | * ** |
- | * ** |
- | * ** |
- |* ** |
- |*******|
- | ** |
- | ** |
- +-------+
-*/
-0x0c00,
-0x1c00,
-0x2c00,
-0x2c00,
-0x4c00,
-0x8c00,
-0xfe00,
-0x0c00,
-0x0c00,
-
-/* Character 53 (0x35):
- width 9
- bbx ( 6, 9, 0, 0 )
-
- +------+
- | *****|
- | ** |
- |** |
- |***** |
- | **|
- | **|
- |** **|
- |** **|
- | **** |
- +------+
-*/
-0x7c00,
-0x6000,
-0xc000,
-0xf800,
-0x0c00,
-0x0c00,
-0xcc00,
-0xcc00,
-0x7800,
-
-/* Character 54 (0x36):
- width 8
- bbx ( 6, 9, 0, 0 )
-
- +------+
- | **** |
- |** **|
- |** |
- |** |
- |***** |
- |** **|
- |** **|
- |** **|
- | **** |
- +------+
-*/
-0x7800,
-0xcc00,
-0xc000,
-0xc000,
-0xf800,
-0xcc00,
-0xcc00,
-0xcc00,
-0x7800,
-
-/* Character 55 (0x37):
- width 10
- bbx ( 6, 9, 0, 0 )
-
- +------+
- |******|
- | **|
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- +------+
-*/
-0xfc00,
-0x0c00,
-0x1800,
-0x1800,
-0x3000,
-0x3000,
-0x3000,
-0x6000,
-0x6000,
-
-/* Character 56 (0x38):
- width 8
- bbx ( 6, 9, 0, 0 )
-
- +------+
- | **** |
- |** **|
- |** **|
- | **** |
- |** **|
- |** **|
- |** **|
- |** **|
- | **** |
- +------+
-*/
-0x7800,
-0xcc00,
-0xcc00,
-0x7800,
-0xcc00,
-0xcc00,
-0xcc00,
-0xcc00,
-0x7800,
-
-/* Character 57 (0x39):
- width 8
- bbx ( 6, 9, 0, 0 )
-
- +------+
- | **** |
- |** **|
- |** **|
- |** **|
- | *****|
- | **|
- | **|
- |** **|
- | **** |
- +------+
-*/
-0x7800,
-0xcc00,
-0xcc00,
-0xcc00,
-0x7c00,
-0x0c00,
-0x0c00,
-0xcc00,
-0x7800,
-
-/* Character 58 (0x3a):
- width 7
- bbx ( 2, 7, 1, 0 )
-
- +--+
- |**|
- |**|
- | |
- | |
- | |
- |**|
- |**|
- +--+
-*/
-0xc000,
-0xc000,
-0x0000,
-0x0000,
-0x0000,
-0xc000,
-0xc000,
-
-/* Character 59 (0x3b):
- width 4
- bbx ( 2, 9, 1, -2 )
-
- +--+
- |**|
- |**|
- | |
- | |
- | |
- |**|
- |**|
- | *|
- |* |
- +--+
-*/
-0xc000,
-0xc000,
-0x0000,
-0x0000,
-0x0000,
-0xc000,
-0xc000,
-0x4000,
-0x8000,
-
-/* Character 60 (0x3c):
- width 4
- bbx ( 5, 5, 1, 1 )
-
- +-----+
- | **|
- | *** |
- |** |
- | *** |
- | **|
- +-----+
-*/
-0x1800,
-0x7000,
-0xc000,
-0x7000,
-0x1800,
-
-/* Character 61 (0x3d):
- width 4
- bbx ( 6, 3, 0, 2 )
-
- +------+
- |******|
- | |
- |******|
- +------+
-*/
-0xfc00,
-0x0000,
-0xfc00,
-
-/* Character 62 (0x3e):
- width 7
- bbx ( 5, 5, 1, 1 )
-
- +-----+
- |** |
- | *** |
- | **|
- | *** |
- |** |
- +-----+
-*/
-0xc000,
-0x7000,
-0x1800,
-0x7000,
-0xc000,
-
-/* Character 63 (0x3f):
- width 7
- bbx ( 6, 9, 1, 0 )
-
- +------+
- | **** |
- |** **|
- |** **|
- | ** |
- | ** |
- | ** |
- | |
- | ** |
- | ** |
- +------+
-*/
-0x7800,
-0xcc00,
-0xcc00,
-0x1800,
-0x3000,
-0x3000,
-0x0000,
-0x3000,
-0x3000,
-
-/* Character 64 (0x40):
- width 4
- bbx ( 10, 10, 1, -1 )
-
- +----------+
- | ***** |
- | ** * |
- | * *|
- |* ** * *|
- |* * * *|
- |* * * *|
- |* * ** * |
- |* ** ** |
- | * |
- | ***** |
- +----------+
-*/
-0x1f00,
-0x6080,
-0x4040,
-0x8d40,
-0x9240,
-0xa240,
-0xa680,
-0x9b00,
-0x4000,
-0x3e00,
-
-/* Character 65 (0x41):
- width 7
- bbx ( 8, 9, 0, 0 )
-
- +--------+
- | ** |
- | **** |
- | * * |
- | ** ** |
- | ** ** |
- | ****** |
- |** **|
- |** **|
- |** **|
- +--------+
-*/
-0x1800,
-0x3c00,
-0x2400,
-0x6600,
-0x6600,
-0x7e00,
-0xc300,
-0xc300,
-0xc300,
-
-/* Character 66 (0x42):
- width 7
- bbx ( 7, 9, 1, 0 )
-
- +-------+
- |****** |
- |** **|
- |** **|
- |** **|
- |****** |
- |** **|
- |** **|
- |** **|
- |****** |
- +-------+
-*/
-0xfc00,
-0xc600,
-0xc600,
-0xc600,
-0xfc00,
-0xc600,
-0xc600,
-0xc600,
-0xfc00,
-
-/* Character 67 (0x43):
- width 7
- bbx ( 7, 9, 1, 0 )
-
- +-------+
- | **** |
- | ** **|
- |** |
- |** |
- |** |
- |** |
- |** |
- | ** **|
- | **** |
- +-------+
-*/
-0x3c00,
-0x6600,
-0xc000,
-0xc000,
-0xc000,
-0xc000,
-0xc000,
-0x6600,
-0x3c00,
-
-/* Character 68 (0x44):
- width 7
- bbx ( 7, 9, 1, 0 )
-
- +-------+
- |***** |
- |** ** |
- |** **|
- |** **|
- |** **|
- |** **|
- |** **|
- |** ** |
- |***** |
- +-------+
-*/
-0xf800,
-0xcc00,
-0xc600,
-0xc600,
-0xc600,
-0xc600,
-0xc600,
-0xcc00,
-0xf800,
-
-/* Character 69 (0x45):
- width 7
- bbx ( 6, 9, 1, 0 )
-
- +------+
- |******|
- |** |
- |** |
- |** |
- |******|
- |** |
- |** |
- |** |
- |******|
- +------+
-*/
-0xfc00,
-0xc000,
-0xc000,
-0xc000,
-0xfc00,
-0xc000,
-0xc000,
-0xc000,
-0xfc00,
-
-/* Character 70 (0x46):
- width 5
- bbx ( 6, 9, 1, 0 )
-
- +------+
- |******|
- |** |
- |** |
- |** |
- |***** |
- |** |
- |** |
- |** |
- |** |
- +------+
-*/
-0xfc00,
-0xc000,
-0xc000,
-0xc000,
-0xf800,
-0xc000,
-0xc000,
-0xc000,
-0xc000,
-
-/* Character 71 (0x47):
- width 7
- bbx ( 8, 9, 1, 0 )
-
- +--------+
- | ***** |
- | ** **|
- |** |
- |** |
- |** ****|
- |** **|
- |** **|
- | ** **|
- | **** *|
- +--------+
-*/
-0x3e00,
-0x6300,
-0xc000,
-0xc000,
-0xcf00,
-0xc300,
-0xc300,
-0x6300,
-0x3d00,
-
-/* Character 72 (0x48):
- width 7
- bbx ( 7, 9, 1, 0 )
-
- +-------+
- |** **|
- |** **|
- |** **|
- |** **|
- |*******|
- |** **|
- |** **|
- |** **|
- |** **|
- +-------+
-*/
-0xc600,
-0xc600,
-0xc600,
-0xc600,
-0xfe00,
-0xc600,
-0xc600,
-0xc600,
-0xc600,
-
-/* Character 73 (0x49):
- width 3
- bbx ( 2, 9, 1, 0 )
-
- +--+
- |**|
- |**|
- |**|
- |**|
- |**|
- |**|
- |**|
- |**|
- |**|
- +--+
-*/
-0xc000,
-0xc000,
-0xc000,
-0xc000,
-0xc000,
-0xc000,
-0xc000,
-0xc000,
-0xc000,
-
-/* Character 74 (0x4a):
- width 3
- bbx ( 6, 9, 0, 0 )
-
- +------+
- | **|
- | **|
- | **|
- | **|
- | **|
- | **|
- |** **|
- |** **|
- | **** |
- +------+
-*/
-0x0c00,
-0x0c00,
-0x0c00,
-0x0c00,
-0x0c00,
-0x0c00,
-0xcc00,
-0xcc00,
-0x7800,
-
-/* Character 75 (0x4b):
- width 7
- bbx ( 8, 9, 1, 0 )
-
- +--------+
- |** ** |
- |** ** |
- |** ** |
- |**** |
- |**** |
- |** ** |
- |** ** |
- |** ** |
- |** **|
- +--------+
-*/
-0xc600,
-0xcc00,
-0xd800,
-0xf000,
-0xf000,
-0xd800,
-0xcc00,
-0xc600,
-0xc300,
-
-/* Character 76 (0x4c):
- width 3
- bbx ( 6, 9, 1, 0 )
-
- +------+
- |** |
- |** |
- |** |
- |** |
- |** |
- |** |
- |** |
- |** |
- |******|
- +------+
-*/
-0xc000,
-0xc000,
-0xc000,
-0xc000,
-0xc000,
-0xc000,
-0xc000,
-0xc000,
-0xfc00,
-
-/* Character 77 (0x4d):
- width 11
- bbx ( 9, 9, 1, 0 )
-
- +---------+
- |** **|
- |** **|
- |*** ***|
- |*** ***|
- |**** ****|
- |** * * **|
- |** *** **|
- |** * **|
- |** * **|
- +---------+
-*/
-0xc180,
-0xc180,
-0xe380,
-0xe380,
-0xf780,
-0xd580,
-0xdd80,
-0xc980,
-0xc980,
-
-/* Character 78 (0x4e):
- width 7
- bbx ( 7, 9, 1, 0 )
-
- +-------+
- |** **|
- |*** **|
- |*** **|
- |** * **|
- |** * **|
- |** ***|
- |** ***|
- |** **|
- |** **|
- +-------+
-*/
-0xc600,
-0xe600,
-0xe600,
-0xd600,
-0xd600,
-0xce00,
-0xce00,
-0xc600,
-0xc600,
-
-/* Character 79 (0x4f):
- width 7
- bbx ( 8, 9, 1, 0 )
-
- +--------+
- | **** |
- | ** ** |
- |** **|
- |** **|
- |** **|
- |** **|
- |** **|
- | ** ** |
- | **** |
- +--------+
-*/
-0x3c00,
-0x6600,
-0xc300,
-0xc300,
-0xc300,
-0xc300,
-0xc300,
-0x6600,
-0x3c00,
-
-/* Character 80 (0x50):
- width 7
- bbx ( 7, 9, 1, 0 )
-
- +-------+
- |****** |
- |** **|
- |** **|
- |** **|
- |****** |
- |** |
- |** |
- |** |
- |** |
- +-------+
-*/
-0xfc00,
-0xc600,
-0xc600,
-0xc600,
-0xfc00,
-0xc000,
-0xc000,
-0xc000,
-0xc000,
-
-/* Character 81 (0x51):
- width 7
- bbx ( 8, 9, 1, 0 )
-
- +--------+
- | **** |
- | ** ** |
- |** **|
- |** **|
- |** **|
- |** * **|
- |** ****|
- | ** ** |
- | ******|
- +--------+
-*/
-0x3c00,
-0x6600,
-0xc300,
-0xc300,
-0xc300,
-0xcb00,
-0xcf00,
-0x6600,
-0x3f00,
-
-/* Character 82 (0x52):
- width 5
- bbx ( 7, 9, 1, 0 )
-
- +-------+
- |****** |
- |** **|
- |** **|
- |** **|
- |****** |
- |** ** |
- |** **|
- |** **|
- |** **|
- +-------+
-*/
-0xfc00,
-0xc600,
-0xc600,
-0xc600,
-0xfc00,
-0xcc00,
-0xc600,
-0xc600,
-0xc600,
-
-/* Character 83 (0x53):
- width 7
- bbx ( 7, 9, 1, 0 )
-
- +-------+
- | ***** |
- |** **|
- |** **|
- | *** |
- | *** |
- | ***|
- |** **|
- |** **|
- | ***** |
- +-------+
-*/
-0x7c00,
-0xc600,
-0xc600,
-0x7000,
-0x1c00,
-0x0e00,
-0xc600,
-0xc600,
-0x7c00,
-
-/* Character 84 (0x54):
- width 5
- bbx ( 8, 9, 0, 0 )
-
- +--------+
- |********|
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- +--------+
-*/
-0xff00,
-0x1800,
-0x1800,
-0x1800,
-0x1800,
-0x1800,
-0x1800,
-0x1800,
-0x1800,
-
-/* Character 85 (0x55):
- width 7
- bbx ( 7, 9, 1, 0 )
-
- +-------+
- |** **|
- |** **|
- |** **|
- |** **|
- |** **|
- |** **|
- |** **|
- | ** ** |
- | ***** |
- +-------+
-*/
-0xc600,
-0xc600,
-0xc600,
-0xc600,
-0xc600,
-0xc600,
-0xc600,
-0x6c00,
-0x7c00,
-
-/* Character 86 (0x56):
- width 8
- bbx ( 8, 9, 0, 0 )
-
- +--------+
- |** **|
- |** **|
- | ** ** |
- | ** ** |
- | ** ** |
- | * * |
- | **** |
- | ** |
- | ** |
- +--------+
-*/
-0xc300,
-0xc300,
-0x6600,
-0x6600,
-0x6600,
-0x2400,
-0x3c00,
-0x1800,
-0x1800,
-
-/* Character 87 (0x57):
- width 11
- bbx ( 10, 9, 0, 0 )
-
- +----------+
- |** ** **|
- |** ** **|
- |** ** **|
- | * ** * |
- | ** ** ** |
- | ** ** ** |
- | ** ** |
- | ** ** |
- | ** ** |
- +----------+
-*/
-0xccc0,
-0xccc0,
-0xccc0,
-0x4c80,
-0x6d80,
-0x6d80,
-0x3300,
-0x3300,
-0x3300,
-
-/* Character 88 (0x58):
- width 7
- bbx ( 8, 9, 0, 0 )
-
- +--------+
- |** **|
- |** **|
- | ** ** |
- | **** |
- | ** |
- | **** |
- | ** ** |
- |** **|
- |** **|
- +--------+
-*/
-0xc300,
-0xc300,
-0x6600,
-0x3c00,
-0x1800,
-0x3c00,
-0x6600,
-0xc300,
-0xc300,
-
-/* Character 89 (0x59):
- width 8
- bbx ( 8, 9, 0, 0 )
-
- +--------+
- |** **|
- |** **|
- | ** ** |
- | ** ** |
- | **** |
- | ** |
- | ** |
- | ** |
- | ** |
- +--------+
-*/
-0xc300,
-0xc300,
-0x6600,
-0x6600,
-0x3c00,
-0x1800,
-0x1800,
-0x1800,
-0x1800,
-
-/* Character 90 (0x5a):
- width 6
- bbx ( 7, 9, 0, 0 )
-
- +-------+
- |*******|
- | **|
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- |** |
- |*******|
- +-------+
-*/
-0xfe00,
-0x0600,
-0x0c00,
-0x1800,
-0x3000,
-0x3000,
-0x6000,
-0xc000,
-0xfe00,
-
-/* Character 91 (0x5b):
- width 5
- bbx ( 3, 12, 1, -3 )
-
- +---+
- |***|
- |** |
- |** |
- |** |
- |** |
- |** |
- |** |
- |** |
- |** |
- |** |
- |** |
- |***|
- +---+
-*/
-0xe000,
-0xc000,
-0xc000,
-0xc000,
-0xc000,
-0xc000,
-0xc000,
-0xc000,
-0xc000,
-0xc000,
-0xc000,
-0xe000,
-
-/* Character 92 (0x5c):
- width 4
- bbx ( 4, 9, 0, 0 )
-
- +----+
- |** |
- |** |
- | * |
- | ** |
- | ** |
- | * |
- | * |
- | **|
- | **|
- +----+
-*/
-0xc000,
-0xc000,
-0x4000,
-0x6000,
-0x6000,
-0x2000,
-0x2000,
-0x3000,
-0x3000,
-
-/* Character 93 (0x5d):
- width 5
- bbx ( 3, 12, 0, -3 )
-
- +---+
- |***|
- | **|
- | **|
- | **|
- | **|
- | **|
- | **|
- | **|
- | **|
- | **|
- | **|
- |***|
- +---+
-*/
-0xe000,
-0x6000,
-0x6000,
-0x6000,
-0x6000,
-0x6000,
-0x6000,
-0x6000,
-0x6000,
-0x6000,
-0x6000,
-0xe000,
-
-/* Character 94 (0x5e):
- width 7
- bbx ( 7, 4, 0, 5 )
-
- +-------+
- | * |
- | *** |
- | ** ** |
- |** **|
- +-------+
-*/
-0x1000,
-0x3800,
-0x6c00,
-0xc600,
-
-/* Character 95 (0x5f):
- width 4
- bbx ( 7, 1, 0, -3 )
-
- +-------+
- |*******|
- +-------+
-*/
-0xfe00,
-
-/* Character 96 (0x60):
- width 4
- bbx ( 3, 2, 0, 8 )
-
- +---+
- |** |
- | **|
- +---+
-*/
-0xc000,
-0x6000,
-
-/* Character 97 (0x61):
- width 4
- bbx ( 7, 7, 0, 0 )
-
- +-------+
- | **** |
- |** ** |
- | ** |
- | ***** |
- |** ** |
- |** ** |
- | *** **|
- +-------+
-*/
-0x7800,
-0xcc00,
-0x0c00,
-0x7c00,
-0xcc00,
-0xcc00,
-0x7600,
-
-/* Character 98 (0x62):
- width 4
- bbx ( 6, 9, 0, 0 )
-
- +------+
- |** |
- |** |
- |** ** |
- |*** **|
- |** **|
- |** **|
- |** **|
- |*** **|
- |** ** |
- +------+
-*/
-0xc000,
-0xc000,
-0xd800,
-0xec00,
-0xcc00,
-0xcc00,
-0xcc00,
-0xec00,
-0xd800,
-
-/* Character 99 (0x63):
- width 4
- bbx ( 6, 7, 0, 0 )
-
- +------+
- | **** |
- |** **|
- |** |
- |** |
- |** |
- |** **|
- | **** |
- +------+
-*/
-0x7800,
-0xcc00,
-0xc000,
-0xc000,
-0xc000,
-0xcc00,
-0x7800,
-
-/* Character 100 (0x64):
- width 4
- bbx ( 6, 9, 0, 0 )
-
- +------+
- | **|
- | **|
- | ** **|
- |** ***|
- |** **|
- |** **|
- |** **|
- |** ***|
- | ** **|
- +------+
-*/
-0x0c00,
-0x0c00,
-0x6c00,
-0xdc00,
-0xcc00,
-0xcc00,
-0xcc00,
-0xdc00,
-0x6c00,
-
-/* Character 101 (0x65):
- width 4
- bbx ( 6, 7, 0, 0 )
-
- +------+
- | **** |
- |** **|
- |** **|
- |******|
- |** |
- |** **|
- | **** |
- +------+
-*/
-0x7800,
-0xcc00,
-0xcc00,
-0xfc00,
-0xc000,
-0xcc00,
-0x7800,
-
-/* Character 102 (0x66):
- width 4
- bbx ( 5, 9, 0, 0 )
-
- +-----+
- | ***|
- | ** |
- |**** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- +-----+
-*/
-0x3800,
-0x6000,
-0xf000,
-0x6000,
-0x6000,
-0x6000,
-0x6000,
-0x6000,
-0x6000,
-
-/* Character 103 (0x67):
- width 4
- bbx ( 6, 10, 0, -3 )
-
- +------+
- | ** **|
- |** ***|
- |** **|
- |** **|
- |** **|
- |** ***|
- | ** **|
- | **|
- |** **|
- | **** |
- +------+
-*/
-0x6c00,
-0xdc00,
-0xcc00,
-0xcc00,
-0xcc00,
-0xdc00,
-0x6c00,
-0x0c00,
-0xcc00,
-0x7800,
-
-/* Character 104 (0x68):
- width 4
- bbx ( 6, 9, 0, 0 )
-
- +------+
- |** |
- |** |
- |** ** |
- |*** **|
- |** **|
- |** **|
- |** **|
- |** **|
- |** **|
- +------+
-*/
-0xc000,
-0xc000,
-0xd800,
-0xec00,
-0xcc00,
-0xcc00,
-0xcc00,
-0xcc00,
-0xcc00,
-
-/* Character 105 (0x69):
- width 4
- bbx ( 2, 9, 0, 0 )
-
- +--+
- |**|
- | |
- |**|
- |**|
- |**|
- |**|
- |**|
- |**|
- |**|
- +--+
-*/
-0xc000,
-0x0000,
-0xc000,
-0xc000,
-0xc000,
-0xc000,
-0xc000,
-0xc000,
-0xc000,
-
-/* Character 106 (0x6a):
- width 4
- bbx ( 3, 12, -1, -3 )
-
- +---+
- | **|
- | |
- | **|
- | **|
- | **|
- | **|
- | **|
- | **|
- | **|
- | **|
- | **|
- |** |
- +---+
-*/
-0x6000,
-0x0000,
-0x6000,
-0x6000,
-0x6000,
-0x6000,
-0x6000,
-0x6000,
-0x6000,
-0x6000,
-0x6000,
-0xc000,
-
-/* Character 107 (0x6b):
- width 4
- bbx ( 7, 9, 0, 0 )
-
- +-------+
- |** |
- |** |
- |** ** |
- |** ** |
- |**** |
- |**** |
- |** ** |
- |** ** |
- |** **|
- +-------+
-*/
-0xc000,
-0xc000,
-0xcc00,
-0xd800,
-0xf000,
-0xf000,
-0xd800,
-0xcc00,
-0xc600,
-
-/* Character 108 (0x6c):
- width 4
- bbx ( 2, 9, 0, 0 )
-
- +--+
- |**|
- |**|
- |**|
- |**|
- |**|
- |**|
- |**|
- |**|
- |**|
- +--+
-*/
-0xc000,
-0xc000,
-0xc000,
-0xc000,
-0xc000,
-0xc000,
-0xc000,
-0xc000,
-0xc000,
-
-/* Character 109 (0x6d):
- width 4
- bbx ( 10, 7, 0, 0 )
-
- +----------+
- |* *** *** |
- |** ** **|
- |** ** **|
- |** ** **|
- |** ** **|
- |** ** **|
- |** ** **|
- +----------+
-*/
-0xbb80,
-0xccc0,
-0xccc0,
-0xccc0,
-0xccc0,
-0xccc0,
-0xccc0,
-
-/* Character 110 (0x6e):
- width 4
- bbx ( 6, 7, 0, 0 )
-
- +------+
- |** ** |
- |*** **|
- |** **|
- |** **|
- |** **|
- |** **|
- |** **|
- +------+
-*/
-0xd800,
-0xec00,
-0xcc00,
-0xcc00,
-0xcc00,
-0xcc00,
-0xcc00,
-
-/* Character 111 (0x6f):
- width 4
- bbx ( 6, 7, 0, 0 )
-
- +------+
- | **** |
- |** **|
- |** **|
- |** **|
- |** **|
- |** **|
- | **** |
- +------+
-*/
-0x7800,
-0xcc00,
-0xcc00,
-0xcc00,
-0xcc00,
-0xcc00,
-0x7800,
-
-/* Character 112 (0x70):
- width 4
- bbx ( 6, 10, 0, -3 )
-
- +------+
- |** ** |
- |*** **|
- |** **|
- |** **|
- |** **|
- |*** **|
- |** ** |
- |** |
- |** |
- |** |
- +------+
-*/
-0xd800,
-0xec00,
-0xcc00,
-0xcc00,
-0xcc00,
-0xec00,
-0xd800,
-0xc000,
-0xc000,
-0xc000,
-
-/* Character 113 (0x71):
- width 4
- bbx ( 6, 10, 0, -3 )
-
- +------+
- | *** *|
- |** ***|
- |** **|
- |** **|
- |** **|
- |** ***|
- | ** **|
- | **|
- | **|
- | **|
- +------+
-*/
-0x7400,
-0xdc00,
-0xcc00,
-0xcc00,
-0xcc00,
-0xdc00,
-0x6c00,
-0x0c00,
-0x0c00,
-0x0c00,
-
-/* Character 114 (0x72):
- width 4
- bbx ( 5, 7, 0, 0 )
-
- +-----+
- |** **|
- |*****|
- |*** |
- |** |
- |** |
- |** |
- |** |
- +-----+
-*/
-0xd800,
-0xf800,
-0xe000,
-0xc000,
-0xc000,
-0xc000,
-0xc000,
-
-/* Character 115 (0x73):
- width 4
- bbx ( 6, 7, 0, 0 )
-
- +------+
- | **** |
- |** **|
- |*** |
- | *** |
- | ***|
- |** **|
- | **** |
- +------+
-*/
-0x7800,
-0xcc00,
-0xe000,
-0x3800,
-0x1c00,
-0xcc00,
-0x7800,
-
-/* Character 116 (0x74):
- width 4
- bbx ( 5, 9, 0, 0 )
-
- +-----+
- | ** |
- | ** |
- |**** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** *|
- | ** |
- +-----+
-*/
-0x6000,
-0x6000,
-0xf000,
-0x6000,
-0x6000,
-0x6000,
-0x6000,
-0x6800,
-0x3000,
-
-/* Character 117 (0x75):
- width 4
- bbx ( 6, 7, 0, 0 )
-
- +------+
- |** **|
- |** **|
- |** **|
- |** **|
- |** **|
- |** ***|
- | ** **|
- +------+
-*/
-0xcc00,
-0xcc00,
-0xcc00,
-0xcc00,
-0xcc00,
-0xdc00,
-0x6c00,
-
-/* Character 118 (0x76):
- width 4
- bbx ( 7, 7, 0, 0 )
-
- +-------+
- |** **|
- |** **|
- | ** ** |
- | ** ** |
- | *** |
- | *** |
- | * |
- +-------+
-*/
-0xc600,
-0xc600,
-0x6c00,
-0x6c00,
-0x3800,
-0x3800,
-0x1000,
-
-/* Character 119 (0x77):
- width 4
- bbx ( 10, 7, 0, 0 )
-
- +----------+
- |** ** **|
- |** ** **|
- | ** ** ** |
- | ** ** ** |
- | ** ** ** |
- | ** ** |
- | ** ** |
- +----------+
-*/
-0xccc0,
-0xccc0,
-0x6d80,
-0x6d80,
-0x6d80,
-0x3300,
-0x3300,
-
-/* Character 120 (0x78):
- width 4
- bbx ( 6, 7, 0, 0 )
-
- +------+
- |** **|
- |** **|
- | **** |
- | ** |
- | **** |
- |** **|
- |** **|
- +------+
-*/
-0xcc00,
-0xcc00,
-0x7800,
-0x3000,
-0x7800,
-0xcc00,
-0xcc00,
-
-/* Character 121 (0x79):
- width 4
- bbx ( 7, 10, 0, -3 )
-
- +-------+
- |** **|
- |** **|
- | ** ** |
- | ** ** |
- | *** |
- | *** |
- | ** |
- | * |
- | ** |
- | ** |
- +-------+
-*/
-0xc600,
-0xc600,
-0x6c00,
-0x6c00,
-0x3800,
-0x3800,
-0x1800,
-0x1000,
-0x3000,
-0x6000,
-
-/* Character 122 (0x7a):
- width 4
- bbx ( 5, 7, 0, 0 )
-
- +-----+
- |*****|
- | **|
- | ** |
- | * |
- | ** |
- |** |
- |*****|
- +-----+
-*/
-0xf800,
-0x1800,
-0x3000,
-0x2000,
-0x6000,
-0xc000,
-0xf800,
-
-/* Character 123 (0x7b):
- width 4
- bbx ( 4, 12, 0, -3 )
-
- +----+
- | **|
- | ** |
- | ** |
- | ** |
- | ** |
- |** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | **|
- +----+
-*/
-0x3000,
-0x6000,
-0x6000,
-0x6000,
-0x6000,
-0xc000,
-0x6000,
-0x6000,
-0x6000,
-0x6000,
-0x6000,
-0x3000,
-
-/* Character 124 (0x7c):
- width 4
- bbx ( 2, 12, 1, -3 )
-
- +--+
- |**|
- |**|
- |**|
- |**|
- |**|
- |**|
- |**|
- |**|
- |**|
- |**|
- |**|
- |**|
- +--+
-*/
-0xc000,
-0xc000,
-0xc000,
-0xc000,
-0xc000,
-0xc000,
-0xc000,
-0xc000,
-0xc000,
-0xc000,
-0xc000,
-0xc000,
-
-/* Character 125 (0x7d):
- width 4
- bbx ( 4, 12, 0, -3 )
-
- +----+
- |** |
- | ** |
- | ** |
- | ** |
- | ** |
- | **|
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- |** |
- +----+
-*/
-0xc000,
-0x6000,
-0x6000,
-0x6000,
-0x6000,
-0x3000,
-0x6000,
-0x6000,
-0x6000,
-0x6000,
-0x6000,
-0xc000,
-
-/* Character 126 (0x7e):
- width 4
- bbx ( 7, 2, 0, 3 )
-
- +-------+
- | *** **|
- |** *** |
- +-------+
-*/
-0x7600,
-0xdc00,
-
-/* Character 160 (0xa0):
- width 8
- bbx ( 1, 1, 0, 0 )
-
- +-+
- | |
- +-+
-*/
-0x0000,
-
-/* Character 161 (0xa1):
- width 8
- bbx ( 2, 10, 1, -3 )
-
- +--+
- |**|
- |**|
- | |
- | *|
- |**|
- |**|
- |**|
- |**|
- |**|
- |**|
- +--+
-*/
-0xc000,
-0xc000,
-0x0000,
-0x4000,
-0xc000,
-0xc000,
-0xc000,
-0xc000,
-0xc000,
-0xc000,
-
-/* Character 162 (0xa2):
- width 8
- bbx ( 6, 9, 0, -1 )
-
- +------+
- | * |
- | **** |
- |** ***|
- |* * |
- |* * |
- |* * |
- |*** **|
- | **** |
- | * |
- +------+
-*/
-0x1000,
-0x7800,
-0xdc00,
-0x9000,
-0xa000,
-0xa000,
-0xec00,
-0x7800,
-0x4000,
-
-/* Character 163 (0xa3):
- width 8
- bbx ( 6, 9, 0, 0 )
-
- +------+
- | *** |
- | ** **|
- | ** |
- | ** |
- |***** |
- | ** |
- | ** |
- |*** **|
- |** ** |
- +------+
-*/
-0x3800,
-0x6c00,
-0x6000,
-0x6000,
-0xf800,
-0x6000,
-0x6000,
-0xec00,
-0xd800,
-
-/* Character 164 (0xa4):
- width 8
- bbx ( 6, 6, 0, 1 )
-
- +------+
- |** **|
- | **** |
- | * * |
- | * * |
- | **** |
- |** **|
- +------+
-*/
-0xcc00,
-0x7800,
-0x4800,
-0x4800,
-0x7800,
-0xcc00,
-
-/* Character 165 (0xa5):
- width 8
- bbx ( 6, 9, 0, 0 )
-
- +------+
- |** **|
- |** **|
- | * * |
- |******|
- | ** |
- |******|
- | ** |
- | ** |
- | ** |
- +------+
-*/
-0xcc00,
-0xcc00,
-0x4800,
-0xfc00,
-0x3000,
-0xfc00,
-0x3000,
-0x3000,
-0x3000,
-
-/* Character 166 (0xa6):
- width 13
- bbx ( 2, 11, 1, -2 )
-
- +--+
- |**|
- |**|
- |**|
- |**|
- | |
- | |
- |**|
- |**|
- |**|
- |**|
- |**|
- +--+
-*/
-0xc000,
-0xc000,
-0xc000,
-0xc000,
-0x0000,
-0x0000,
-0xc000,
-0xc000,
-0xc000,
-0xc000,
-0xc000,
-
-/* Character 167 (0xa7):
- width 8
- bbx ( 6, 12, 0, -3 )
-
- +------+
- | **** |
- |** **|
- |*** |
- | *** |
- |** ** |
- |** **|
- |** **|
- | ** **|
- | *** |
- | ***|
- |** **|
- | **** |
- +------+
-*/
-0x7800,
-0xcc00,
-0xe000,
-0x7000,
-0xd800,
-0xcc00,
-0xcc00,
-0x6c00,
-0x3800,
-0x1c00,
-0xcc00,
-0x7800,
-
-/* Character 168 (0xa8):
- width 8
- bbx ( 5, 1, 0, 8 )
-
- +-----+
- |** **|
- +-----+
-*/
-0xd800,
-
-/* Character 169 (0xa9):
- width 8
- bbx ( 9, 9, 1, 0 )
-
- +---------+
- | ***** |
- | * * |
- |* *** *|
- |* * * *|
- |* * *|
- |* * * *|
- |* *** *|
- | * * |
- | ***** |
- +---------+
-*/
-0x3e00,
-0x4100,
-0x9c80,
-0xa280,
-0xa080,
-0xa280,
-0x9c80,
-0x4100,
-0x3e00,
-
-/* Character 170 (0xaa):
- width 8
- bbx ( 4, 6, 1, 3 )
-
- +----+
- |*** |
- | **|
- |****|
- |* **|
- | |
- |****|
- +----+
-*/
-0xe000,
-0x3000,
-0xf000,
-0xb000,
-0x0000,
-0xf000,
-
-/* Character 171 (0xab):
- width 8
- bbx ( 6, 5, 1, 1 )
-
- +------+
- | * *|
- | ** **|
- |** ** |
- | ** **|
- | * *|
- +------+
-*/
-0x2400,
-0x6c00,
-0xd800,
-0x6c00,
-0x2400,
-
-/* Character 172 (0xac):
- width 4
- bbx ( 6, 4, 1, 2 )
-
- +------+
- |******|
- | *|
- | *|
- | *|
- +------+
-*/
-0xfc00,
-0x0400,
-0x0400,
-0x0400,
-
-/* Character 173 (0xad):
- width 4
- bbx ( 4, 1, 0, 3 )
-
- +----+
- |****|
- +----+
-*/
-0xf000,
-
-/* Character 174 (0xae):
- width 4
- bbx ( 9, 9, 1, 0 )
-
- +---------+
- | ***** |
- | * * |
- |* *** *|
- |* * * *|
- |* ** *|
- |* * * *|
- |* * * *|
- | * * |
- | ***** |
- +---------+
-*/
-0x3e00,
-0x4100,
-0x9c80,
-0x9480,
-0x9880,
-0x9480,
-0x9480,
-0x4100,
-0x3e00,
-
-/* Character 175 (0xaf):
- width 4
- bbx ( 4, 1, 0, 8 )
-
- +----+
- |****|
- +----+
-*/
-0xf000,
-
-/* Character 176 (0xb0):
- width 9
- bbx ( 4, 4, 0, 4 )
-
- +----+
- | ** |
- |* *|
- |* *|
- | ** |
- +----+
-*/
-0x6000,
-0x9000,
-0x9000,
-0x6000,
-
-/* Character 177 (0xb1):
- width 9
- bbx ( 6, 7, 0, 0 )
-
- +------+
- | ** |
- | ** |
- |******|
- | ** |
- | ** |
- | |
- |******|
- +------+
-*/
-0x3000,
-0x3000,
-0xfc00,
-0x3000,
-0x3000,
-0x0000,
-0xfc00,
-
-/* Character 178 (0xb2):
- width 10
- bbx ( 4, 5, 0, 4 )
-
- +----+
- | ** |
- |* **|
- | ** |
- |** |
- |****|
- +----+
-*/
-0x6000,
-0xb000,
-0x6000,
-0xc000,
-0xf000,
-
-/* Character 179 (0xb3):
- width 10
- bbx ( 4, 5, 0, 4 )
-
- +----+
- | ** |
- |* **|
- | ** |
- | **|
- |*** |
- +----+
-*/
-0x6000,
-0xb000,
-0x6000,
-0x3000,
-0xe000,
-
-/* Character 180 (0xb4):
- width 10
- bbx ( 3, 2, 0, 8 )
-
- +---+
- | **|
- |** |
- +---+
-*/
-0x6000,
-0xc000,
-
-/* Character 181 (0xb5):
- width 10
- bbx ( 6, 10, 0, -3 )
-
- +------+
- |** **|
- |** **|
- |** **|
- |** **|
- |** **|
- |** ***|
- |*** **|
- |** |
- |** |
- |** |
- +------+
-*/
-0xcc00,
-0xcc00,
-0xcc00,
-0xcc00,
-0xcc00,
-0xdc00,
-0xec00,
-0xc000,
-0xc000,
-0xc000,
-
-/* Character 182 (0xb6):
- width 10
- bbx ( 7, 12, 0, -3 )
-
- +-------+
- | *****|
- | *** * |
- |**** * |
- |**** * |
- |**** * |
- | *** * |
- | ** * |
- | * * |
- | * * |
- | * * |
- | * * |
- | * * |
- +-------+
-*/
-0x3e00,
-0x7400,
-0xf400,
-0xf400,
-0xf400,
-0x7400,
-0x3400,
-0x1400,
-0x1400,
-0x1400,
-0x1400,
-0x1400,
-
-/* Character 183 (0xb7):
- width 7
- bbx ( 2, 2, 1, 3 )
-
- +--+
- |**|
- |**|
- +--+
-*/
-0xc000,
-0xc000,
-
-/* Character 184 (0xb8):
- width 10
- bbx ( 4, 4, 0, -3 )
-
- +----+
- | ** |
- | **|
- | **|
- |*** |
- +----+
-*/
-0x6000,
-0x3000,
-0x3000,
-0xe000,
-
-/* Character 185 (0xb9):
- width 9
- bbx ( 3, 5, 0, 4 )
-
- +---+
- | **|
- |***|
- | **|
- | **|
- | **|
- +---+
-*/
-0x6000,
-0xe000,
-0x6000,
-0x6000,
-0x6000,
-
-/* Character 186 (0xba):
- width 9
- bbx ( 4, 6, 1, 3 )
-
- +----+
- | ** |
- |** *|
- |** *|
- | ** |
- | |
- |****|
- +----+
-*/
-0x6000,
-0xd000,
-0xd000,
-0x6000,
-0x0000,
-0xf000,
-
-/* Character 187 (0xbb):
- width 9
- bbx ( 6, 5, 1, 1 )
-
- +------+
- |* * |
- |** ** |
- | ** **|
- |** ** |
- |* * |
- +------+
-*/
-0x9000,
-0xd800,
-0x6c00,
-0xd800,
-0x9000,
-
-/* Character 188 (0xbc):
- width 9
- bbx ( 10, 9, 0, 0 )
-
- +----------+
- | ** ** |
- |*** ** |
- | ** ** |
- | ** ** |
- | ** ** ** |
- | * *** |
- | ** * * |
- | ** *****|
- | ** ** |
- +----------+
-*/
-0x6300,
-0xe600,
-0x6600,
-0x6c00,
-0x6d80,
-0x0b80,
-0x1a80,
-0x37c0,
-0x3180,
-
-/* Character 189 (0xbd):
- width 8
- bbx ( 10, 9, 0, 0 )
-
- +----------+
- | ** ** |
- |*** ** |
- | ** ** |
- | ** ** |
- | ** ** ** |
- | * * **|
- | ** ** |
- | ** ** |
- | ** ****|
- +----------+
-*/
-0x6300,
-0xe600,
-0x6600,
-0x6c00,
-0x6d80,
-0x0ac0,
-0x1980,
-0x3300,
-0x33c0,
-
-/* Character 190 (0xbe):
- width 8
- bbx ( 10, 9, 0, 0 )
-
- +----------+
- | ** ** |
- |* ** ** |
- | ** ** |
- | ** ** |
- |*** ** ** |
- | * *** |
- | ** * * |
- | ** *****|
- | ** ** |
- +----------+
-*/
-0x6300,
-0xb300,
-0x6600,
-0x3600,
-0xed80,
-0x0b80,
-0x1a80,
-0x37c0,
-0x3180,
-
-/* Character 191 (0xbf):
- width 8
- bbx ( 6, 10, 1, -3 )
-
- +------+
- | ** |
- | ** |
- | |
- | ** |
- | ** |
- | ** |
- | ** |
- |** **|
- |** **|
- | **** |
- +------+
-*/
-0x3000,
-0x3000,
-0x0000,
-0x3000,
-0x3000,
-0x3000,
-0x6000,
-0xcc00,
-0xcc00,
-0x7800,
-
-/* Character 192 (0xc0):
- width 7
- bbx ( 8, 12, 0, 0 )
-
- +--------+
- | ** |
- | ** |
- | |
- | ** |
- | ** |
- | **** |
- | * * |
- | ** ** |
- | ****** |
- |** **|
- |** **|
- |** **|
- +--------+
-*/
-0x3000,
-0x1800,
-0x0000,
-0x1800,
-0x1800,
-0x3c00,
-0x2400,
-0x6600,
-0x7e00,
-0xc300,
-0xc300,
-0xc300,
-
-/* Character 193 (0xc1):
- width 7
- bbx ( 8, 12, 0, 0 )
-
- +--------+
- | ** |
- | ** |
- | |
- | ** |
- | ** |
- | **** |
- | * * |
- | ** ** |
- | ****** |
- |** **|
- |** **|
- |** **|
- +--------+
-*/
-0x0c00,
-0x1800,
-0x0000,
-0x1800,
-0x1800,
-0x3c00,
-0x2400,
-0x6600,
-0x7e00,
-0xc300,
-0xc300,
-0xc300,
-
-/* Character 194 (0xc2):
- width 7
- bbx ( 8, 12, 0, 0 )
-
- +--------+
- | *** |
- | ** ** |
- | |
- | ** |
- | ** |
- | **** |
- | * * |
- | ** ** |
- | ****** |
- |** **|
- |** **|
- |** **|
- +--------+
-*/
-0x1c00,
-0x3600,
-0x0000,
-0x1800,
-0x1800,
-0x3c00,
-0x2400,
-0x6600,
-0x7e00,
-0xc300,
-0xc300,
-0xc300,
-
-/* Character 195 (0xc3):
- width 7
- bbx ( 8, 12, 0, 0 )
-
- +--------+
- | ** * |
- | * ** |
- | |
- | ** |
- | ** |
- | **** |
- | * * |
- | ** ** |
- | ****** |
- |** **|
- |** **|
- |** **|
- +--------+
-*/
-0x1a00,
-0x2c00,
-0x0000,
-0x1800,
-0x1800,
-0x3c00,
-0x2400,
-0x6600,
-0x7e00,
-0xc300,
-0xc300,
-0xc300,
-
-/* Character 196 (0xc4):
- width 7
- bbx ( 8, 11, 0, 0 )
-
- +--------+
- | ** ** |
- | |
- | ** |
- | ** |
- | **** |
- | * * |
- | ** ** |
- | ****** |
- |** **|
- |** **|
- |** **|
- +--------+
-*/
-0x3600,
-0x0000,
-0x1800,
-0x1800,
-0x3c00,
-0x2400,
-0x6600,
-0x7e00,
-0xc300,
-0xc300,
-0xc300,
-
-/* Character 197 (0xc5):
- width 7
- bbx ( 8, 12, 0, 0 )
-
- +--------+
- | ** |
- | * * |
- | ** |
- | ** |
- | ** |
- | **** |
- | * * |
- | ** ** |
- | ****** |
- |** **|
- |** **|
- |** **|
- +--------+
-*/
-0x1800,
-0x2400,
-0x1800,
-0x1800,
-0x1800,
-0x3c00,
-0x2400,
-0x6600,
-0x7e00,
-0xc300,
-0xc300,
-0xc300,
-
-/* Character 198 (0xc6):
- width 11
- bbx ( 11, 9, 1, 0 )
-
- +-----------+
- | ********|
- | ** ** |
- | * ** |
- | ** ** |
- | ** ******|
- | ****** |
- |** ** |
- |** ** |
- |** ******|
- +-----------+
-*/
-0x1fe0,
-0x3600,
-0x2600,
-0x6600,
-0x67e0,
-0x7e00,
-0xc600,
-0xc600,
-0xc7e0,
-
-/* Character 199 (0xc7):
- width 7
- bbx ( 7, 12, 1, -3 )
-
- +-------+
- | **** |
- | ** **|
- |** |
- |** |
- |** |
- |** |
- |** |
- | ** **|
- | **** |
- | ** |
- | ** |
- | *** |
- +-------+
-*/
-0x3c00,
-0x6600,
-0xc000,
-0xc000,
-0xc000,
-0xc000,
-0xc000,
-0x6600,
-0x3c00,
-0x1800,
-0x1800,
-0x7000,
-
-/* Character 200 (0xc8):
- width 7
- bbx ( 6, 12, 1, 0 )
-
- +------+
- | ** |
- | ** |
- | |
- |******|
- |** |
- |** |
- |** |
- |******|
- |** |
- |** |
- |** |
- |******|
- +------+
-*/
-0x6000,
-0x3000,
-0x0000,
-0xfc00,
-0xc000,
-0xc000,
-0xc000,
-0xfc00,
-0xc000,
-0xc000,
-0xc000,
-0xfc00,
-
-/* Character 201 (0xc9):
- width 7
- bbx ( 6, 12, 1, 0 )
-
- +------+
- | ** |
- | ** |
- | |
- |******|
- |** |
- |** |
- |** |
- |******|
- |** |
- |** |
- |** |
- |******|
- +------+
-*/
-0x1800,
-0x3000,
-0x0000,
-0xfc00,
-0xc000,
-0xc000,
-0xc000,
-0xfc00,
-0xc000,
-0xc000,
-0xc000,
-0xfc00,
-
-/* Character 202 (0xca):
- width 7
- bbx ( 6, 12, 1, 0 )
-
- +------+
- | *** |
- | ** **|
- | |
- |******|
- |** |
- |** |
- |** |
- |******|
- |** |
- |** |
- |** |
- |******|
- +------+
-*/
-0x3800,
-0x6c00,
-0x0000,
-0xfc00,
-0xc000,
-0xc000,
-0xc000,
-0xfc00,
-0xc000,
-0xc000,
-0xc000,
-0xfc00,
-
-/* Character 203 (0xcb):
- width 7
- bbx ( 6, 11, 1, 0 )
-
- +------+
- | ** **|
- | |
- |******|
- |** |
- |** |
- |** |
- |******|
- |** |
- |** |
- |** |
- |******|
- +------+
-*/
-0x6c00,
-0x0000,
-0xfc00,
-0xc000,
-0xc000,
-0xc000,
-0xfc00,
-0xc000,
-0xc000,
-0xc000,
-0xfc00,
-
-/* Character 204 (0xcc):
- width 3
- bbx ( 3, 12, 0, 0 )
-
- +---+
- |** |
- | **|
- | |
- | **|
- | **|
- | **|
- | **|
- | **|
- | **|
- | **|
- | **|
- | **|
- +---+
-*/
-0xc000,
-0x6000,
-0x0000,
-0x6000,
-0x6000,
-0x6000,
-0x6000,
-0x6000,
-0x6000,
-0x6000,
-0x6000,
-0x6000,
-
-/* Character 205 (0xcd):
- width 3
- bbx ( 3, 12, 1, 0 )
-
- +---+
- | **|
- |** |
- | |
- |** |
- |** |
- |** |
- |** |
- |** |
- |** |
- |** |
- |** |
- |** |
- +---+
-*/
-0x6000,
-0xc000,
-0x0000,
-0xc000,
-0xc000,
-0xc000,
-0xc000,
-0xc000,
-0xc000,
-0xc000,
-0xc000,
-0xc000,
-
-/* Character 206 (0xce):
- width 3
- bbx ( 5, 12, 0, 0 )
-
- +-----+
- | *** |
- |** **|
- | |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- +-----+
-*/
-0x7000,
-0xd800,
-0x0000,
-0x6000,
-0x6000,
-0x6000,
-0x6000,
-0x6000,
-0x6000,
-0x6000,
-0x6000,
-0x6000,
-
-/* Character 207 (0xcf):
- width 3
- bbx ( 5, 11, 0, 0 )
-
- +-----+
- |** **|
- | |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- +-----+
-*/
-0xd800,
-0x0000,
-0x6000,
-0x6000,
-0x6000,
-0x6000,
-0x6000,
-0x6000,
-0x6000,
-0x6000,
-0x6000,
-
-/* Character 208 (0xd0):
- width 7
- bbx ( 8, 9, 0, 0 )
-
- +--------+
- | ***** |
- | ** ** |
- | ** **|
- | ** **|
- |**** **|
- | ** **|
- | ** **|
- | ** ** |
- | ***** |
- +--------+
-*/
-0x7c00,
-0x6600,
-0x6300,
-0x6300,
-0xf300,
-0x6300,
-0x6300,
-0x6600,
-0x7c00,
-
-/* Character 209 (0xd1):
- width 7
- bbx ( 7, 12, 1, 0 )
-
- +-------+
- | ** * |
- | * ** |
- | |
- |** **|
- |** **|
- |*** **|
- |*** **|
- |**** **|
- |** ***|
- |** ***|
- |** **|
- |** **|
- +-------+
-*/
-0x3400,
-0x5800,
-0x0000,
-0xc600,
-0xc600,
-0xe600,
-0xe600,
-0xf600,
-0xce00,
-0xce00,
-0xc600,
-0xc600,
-
-/* Character 210 (0xd2):
- width 7
- bbx ( 8, 12, 1, 0 )
-
- +--------+
- | ** |
- | ** |
- | |
- | **** |
- | ** ** |
- |** **|
- |** **|
- |** **|
- |** **|
- |** **|
- | ** ** |
- | **** |
- +--------+
-*/
-0x3000,
-0x1800,
-0x0000,
-0x3c00,
-0x6600,
-0xc300,
-0xc300,
-0xc300,
-0xc300,
-0xc300,
-0x6600,
-0x3c00,
-
-/* Character 211 (0xd3):
- width 7
- bbx ( 8, 12, 1, 0 )
-
- +--------+
- | ** |
- | ** |
- | |
- | **** |
- | ** ** |
- |** **|
- |** **|
- |** **|
- |** **|
- |** **|
- | ** ** |
- | **** |
- +--------+
-*/
-0x0c00,
-0x1800,
-0x0000,
-0x3c00,
-0x6600,
-0xc300,
-0xc300,
-0xc300,
-0xc300,
-0xc300,
-0x6600,
-0x3c00,
-
-/* Character 212 (0xd4):
- width 7
- bbx ( 8, 12, 1, 0 )
-
- +--------+
- | *** |
- | ** ** |
- | |
- | **** |
- | ** ** |
- |** **|
- |** **|
- |** **|
- |** **|
- |** **|
- | ** ** |
- | **** |
- +--------+
-*/
-0x1c00,
-0x3600,
-0x0000,
-0x3c00,
-0x6600,
-0xc300,
-0xc300,
-0xc300,
-0xc300,
-0xc300,
-0x6600,
-0x3c00,
-
-/* Character 213 (0xd5):
- width 7
- bbx ( 8, 12, 1, 0 )
-
- +--------+
- | ** * |
- | * ** |
- | |
- | **** |
- | ** ** |
- |** **|
- |** **|
- |** **|
- |** **|
- |** **|
- | ** ** |
- | **** |
- +--------+
-*/
-0x1a00,
-0x2c00,
-0x0000,
-0x3c00,
-0x6600,
-0xc300,
-0xc300,
-0xc300,
-0xc300,
-0xc300,
-0x6600,
-0x3c00,
-
-/* Character 214 (0xd6):
- width 7
- bbx ( 8, 11, 1, 0 )
-
- +--------+
- | ** ** |
- | |
- | **** |
- | ** ** |
- |** **|
- |** **|
- |** **|
- |** **|
- |** **|
- | ** ** |
- | **** |
- +--------+
-*/
-0x6600,
-0x0000,
-0x3c00,
-0x6600,
-0xc300,
-0xc300,
-0xc300,
-0xc300,
-0xc300,
-0x6600,
-0x3c00,
-
-/* Character 215 (0xd7):
- width 7
- bbx ( 6, 5, 0, 1 )
-
- +------+
- |** **|
- | **** |
- | ** |
- | **** |
- |** **|
- +------+
-*/
-0xcc00,
-0x7800,
-0x3000,
-0x7800,
-0xcc00,
-
-/* Character 216 (0xd8):
- width 7
- bbx ( 8, 10, 1, -1 )
-
- +--------+
- | **** *|
- | ** ** |
- |** ****|
- |** * **|
- |** ** **|
- |** * **|
- |**** **|
- | ** ** |
- | ***** |
- |* |
- +--------+
-*/
-0x3d00,
-0x6600,
-0xcf00,
-0xcb00,
-0xdb00,
-0xd300,
-0xf300,
-0x6600,
-0x7c00,
-0x8000,
-
-/* Character 217 (0xd9):
- width 7
- bbx ( 7, 12, 1, 0 )
-
- +-------+
- | ** |
- | ** |
- | |
- |** **|
- |** **|
- |** **|
- |** **|
- |** **|
- |** **|
- |** **|
- | ** ** |
- | ***** |
- +-------+
-*/
-0x3000,
-0x1800,
-0x0000,
-0xc600,
-0xc600,
-0xc600,
-0xc600,
-0xc600,
-0xc600,
-0xc600,
-0x6c00,
-0x7c00,
-
-/* Character 218 (0xda):
- width 7
- bbx ( 7, 12, 1, 0 )
-
- +-------+
- | ** |
- | ** |
- | |
- |** **|
- |** **|
- |** **|
- |** **|
- |** **|
- |** **|
- |** **|
- | ** ** |
- | ***** |
- +-------+
-*/
-0x0c00,
-0x1800,
-0x0000,
-0xc600,
-0xc600,
-0xc600,
-0xc600,
-0xc600,
-0xc600,
-0xc600,
-0x6c00,
-0x7c00,
-
-/* Character 219 (0xdb):
- width 7
- bbx ( 7, 12, 1, 0 )
-
- +-------+
- | *** |
- | ** ** |
- | |
- |** **|
- |** **|
- |** **|
- |** **|
- |** **|
- |** **|
- |** **|
- | ** ** |
- | ***** |
- +-------+
-*/
-0x3800,
-0x6c00,
-0x0000,
-0xc600,
-0xc600,
-0xc600,
-0xc600,
-0xc600,
-0xc600,
-0xc600,
-0x6c00,
-0x7c00,
-
-/* Character 220 (0xdc):
- width 7
- bbx ( 7, 11, 1, 0 )
-
- +-------+
- | ** ** |
- | |
- |** **|
- |** **|
- |** **|
- |** **|
- |** **|
- |** **|
- |** **|
- | ** ** |
- | ***** |
- +-------+
-*/
-0x6c00,
-0x0000,
-0xc600,
-0xc600,
-0xc600,
-0xc600,
-0xc600,
-0xc600,
-0xc600,
-0x6c00,
-0x7c00,
-
-/* Character 221 (0xdd):
- width 8
- bbx ( 8, 12, 0, 0 )
-
- +--------+
- | ** |
- | ** |
- | |
- |** **|
- |** **|
- | ** ** |
- | ** ** |
- | * * |
- | **** |
- | ** |
- | ** |
- | ** |
- +--------+
-*/
-0x0c00,
-0x1800,
-0x0000,
-0xc300,
-0xc300,
-0x6600,
-0x6600,
-0x2400,
-0x3c00,
-0x1800,
-0x1800,
-0x1800,
-
-/* Character 222 (0xde):
- width 7
- bbx ( 7, 9, 1, 0 )
-
- +-------+
- |** |
- |** |
- |****** |
- |** **|
- |** **|
- |** **|
- |****** |
- |** |
- |** |
- +-------+
-*/
-0xc000,
-0xc000,
-0xfc00,
-0xc600,
-0xc600,
-0xc600,
-0xfc00,
-0xc000,
-0xc000,
-
-/* Character 223 (0xdf):
- width 8
- bbx ( 6, 9, 1, 0 )
-
- +------+
- | **** |
- |** **|
- |** **|
- |** **|
- |** ** |
- |** **|
- |** **|
- |** **|
- |** ** |
- +------+
-*/
-0x7800,
-0xcc00,
-0xcc00,
-0xcc00,
-0xd800,
-0xcc00,
-0xcc00,
-0xcc00,
-0xd800,
-
-/* Character 224 (0xe0):
- width 0
- bbx ( 7, 10, 0, 0 )
-
- +-------+
- | ** |
- | ** |
- | |
- | **** |
- |** ** |
- | ** |
- | ***** |
- |** ** |
- |** ** |
- | *** **|
- +-------+
-*/
-0x3000,
-0x1800,
-0x0000,
-0x7800,
-0xcc00,
-0x0c00,
-0x7c00,
-0xcc00,
-0xcc00,
-0x7600,
-
-/* Character 225 (0xe1):
- width 0
- bbx ( 7, 10, 0, 0 )
-
- +-------+
- | ** |
- | ** |
- | |
- | **** |
- |** ** |
- | ** |
- | ***** |
- |** ** |
- |** ** |
- | *** **|
- +-------+
-*/
-0x1800,
-0x3000,
-0x0000,
-0x7800,
-0xcc00,
-0x0c00,
-0x7c00,
-0xcc00,
-0xcc00,
-0x7600,
-
-/* Character 226 (0xe2):
- width 0
- bbx ( 7, 10, 0, 0 )
-
- +-------+
- | *** |
- | ** ** |
- | |
- | **** |
- |** ** |
- | ** |
- | ***** |
- |** ** |
- |** ** |
- | *** **|
- +-------+
-*/
-0x3800,
-0x6c00,
-0x0000,
-0x7800,
-0xcc00,
-0x0c00,
-0x7c00,
-0xcc00,
-0xcc00,
-0x7600,
-
-/* Character 227 (0xe3):
- width 0
- bbx ( 7, 10, 0, 0 )
-
- +-------+
- | ** * |
- | * ** |
- | |
- | **** |
- |** ** |
- | ** |
- | ***** |
- |** ** |
- |** ** |
- | *** **|
- +-------+
-*/
-0x3400,
-0x5800,
-0x0000,
-0x7800,
-0xcc00,
-0x0c00,
-0x7c00,
-0xcc00,
-0xcc00,
-0x7600,
-
-/* Character 228 (0xe4):
- width 137
- bbx ( 7, 9, 0, 0 )
-
- +-------+
- | ** ** |
- | |
- | **** |
- |** ** |
- | ** |
- | ***** |
- |** ** |
- |** ** |
- | *** **|
- +-------+
-*/
-0x6c00,
-0x0000,
-0x7800,
-0xcc00,
-0x0c00,
-0x7c00,
-0xcc00,
-0xcc00,
-0x7600,
-
-/* Character 229 (0xe5):
- width 3
- bbx ( 7, 11, 0, 0 )
-
- +-------+
- | ** |
- | * * |
- | ** |
- | |
- | **** |
- |** ** |
- | ** |
- | ***** |
- |** ** |
- |** ** |
- | *** **|
- +-------+
-*/
-0x3000,
-0x4800,
-0x3000,
-0x0000,
-0x7800,
-0xcc00,
-0x0c00,
-0x7c00,
-0xcc00,
-0xcc00,
-0x7600,
-
-/* Character 230 (0xe6):
- width 0
- bbx ( 10, 7, 0, 0 )
-
- +----------+
- | *** **** |
- |** ** **|
- | ** **|
- | *********|
- |** ** |
- |** ** **|
- | *** **** |
- +----------+
-*/
-0x7780,
-0xccc0,
-0x0cc0,
-0x7fc0,
-0xcc00,
-0xccc0,
-0x7780,
-
-/* Character 231 (0xe7):
- width 0
- bbx ( 6, 10, 0, -3 )
-
- +------+
- | **** |
- |** **|
- |** |
- |** |
- |** |
- |** **|
- | **** |
- | * |
- | ** |
- | *** |
- +------+
-*/
-0x7800,
-0xcc00,
-0xc000,
-0xc000,
-0xc000,
-0xcc00,
-0x7800,
-0x1000,
-0x1800,
-0x7000,
-
-/* Character 232 (0xe8):
- width 1
- bbx ( 6, 10, 0, 0 )
-
- +------+
- | ** |
- | ** |
- | |
- | **** |
- |** **|
- |** **|
- |******|
- |** |
- |** **|
- | **** |
- +------+
-*/
-0x6000,
-0x3000,
-0x0000,
-0x7800,
-0xcc00,
-0xcc00,
-0xfc00,
-0xc000,
-0xcc00,
-0x7800,
-
-/* Character 233 (0xe9):
- width 1
- bbx ( 6, 10, 0, 0 )
-
- +------+
- | ** |
- | ** |
- | |
- | **** |
- |** **|
- |** **|
- |******|
- |** |
- |** **|
- | **** |
- +------+
-*/
-0x1800,
-0x3000,
-0x0000,
-0x7800,
-0xcc00,
-0xcc00,
-0xfc00,
-0xc000,
-0xcc00,
-0x7800,
-
-/* Character 234 (0xea):
- width 0
- bbx ( 6, 10, 0, 0 )
-
- +------+
- | *** |
- | ** **|
- | |
- | **** |
- |** **|
- |** **|
- |******|
- |** |
- |** **|
- | **** |
- +------+
-*/
-0x3800,
-0x6c00,
-0x0000,
-0x7800,
-0xcc00,
-0xcc00,
-0xfc00,
-0xc000,
-0xcc00,
-0x7800,
-
-/* Character 235 (0xeb):
- width 0
- bbx ( 6, 9, 0, 0 )
-
- +------+
- | ** **|
- | |
- | **** |
- |** **|
- |** **|
- |******|
- |** |
- |** **|
- | **** |
- +------+
-*/
-0x6c00,
-0x0000,
-0x7800,
-0xcc00,
-0xcc00,
-0xfc00,
-0xc000,
-0xcc00,
-0x7800,
-
-/* Character 236 (0xec):
- width 2
- bbx ( 3, 10, -1, 0 )
-
- +---+
- |** |
- | **|
- | |
- | **|
- | **|
- | **|
- | **|
- | **|
- | **|
- | **|
- +---+
-*/
-0xc000,
-0x6000,
-0x0000,
-0x6000,
-0x6000,
-0x6000,
-0x6000,
-0x6000,
-0x6000,
-0x6000,
-
-/* Character 237 (0xed):
- width 9
- bbx ( 3, 10, 0, 0 )
-
- +---+
- | **|
- |** |
- | |
- |** |
- |** |
- |** |
- |** |
- |** |
- |** |
- |** |
- +---+
-*/
-0x6000,
-0xc000,
-0x0000,
-0xc000,
-0xc000,
-0xc000,
-0xc000,
-0xc000,
-0xc000,
-0xc000,
-
-/* Character 238 (0xee):
- width 1
- bbx ( 5, 10, -1, 0 )
-
- +-----+
- | *** |
- |** **|
- | |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- +-----+
-*/
-0x7000,
-0xd800,
-0x0000,
-0x6000,
-0x6000,
-0x6000,
-0x6000,
-0x6000,
-0x6000,
-0x6000,
-
-/* Character 239 (0xef):
- width 0
- bbx ( 5, 9, -1, 0 )
-
- +-----+
- |** **|
- | |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- +-----+
-*/
-0xd800,
-0x0000,
-0x6000,
-0x6000,
-0x6000,
-0x6000,
-0x6000,
-0x6000,
-0x6000,
-
-/* Character 240 (0xf0):
- width 3
- bbx ( 6, 10, 0, 0 )
-
- +------+
- |** ** |
- | *** |
- |* * |
- | ** |
- | *****|
- |** **|
- |** **|
- |** **|
- |** **|
- | **** |
- +------+
-*/
-0xd800,
-0x7000,
-0x9000,
-0x1800,
-0x7c00,
-0xcc00,
-0xcc00,
-0xcc00,
-0xcc00,
-0x7800,
-
-/* Character 241 (0xf1):
- width 3
- bbx ( 6, 10, 0, 0 )
-
- +------+
- | ** *|
- | * ** |
- | |
- |** ** |
- |*** **|
- |** **|
- |** **|
- |** **|
- |** **|
- |** **|
- +------+
-*/
-0x3400,
-0x5800,
-0x0000,
-0xd800,
-0xec00,
-0xcc00,
-0xcc00,
-0xcc00,
-0xcc00,
-0xcc00,
-
-/* Character 242 (0xf2):
- width 1
- bbx ( 6, 10, 0, 0 )
-
- +------+
- | ** |
- | ** |
- | |
- | **** |
- |** **|
- |** **|
- |** **|
- |** **|
- |** **|
- | **** |
- +------+
-*/
-0x6000,
-0x3000,
-0x0000,
-0x7800,
-0xcc00,
-0xcc00,
-0xcc00,
-0xcc00,
-0xcc00,
-0x7800,
-
-/* Character 243 (0xf3):
- width 6
- bbx ( 6, 10, 0, 0 )
-
- +------+
- | ** |
- | ** |
- | |
- | **** |
- |** **|
- |** **|
- |** **|
- |** **|
- |** **|
- | **** |
- +------+
-*/
-0x1800,
-0x3000,
-0x0000,
-0x7800,
-0xcc00,
-0xcc00,
-0xcc00,
-0xcc00,
-0xcc00,
-0x7800,
-
-/* Character 244 (0xf4):
- width 7
- bbx ( 6, 10, 0, 0 )
-
- +------+
- | *** |
- | ** **|
- | |
- | **** |
- |** **|
- |** **|
- |** **|
- |** **|
- |** **|
- | **** |
- +------+
-*/
-0x3800,
-0x6c00,
-0x0000,
-0x7800,
-0xcc00,
-0xcc00,
-0xcc00,
-0xcc00,
-0xcc00,
-0x7800,
-
-/* Character 245 (0xf5):
- width 8
- bbx ( 6, 10, 0, 0 )
-
- +------+
- | ** *|
- | * ** |
- | |
- | **** |
- |** **|
- |** **|
- |** **|
- |** **|
- |** **|
- | **** |
- +------+
-*/
-0x3400,
-0x5800,
-0x0000,
-0x7800,
-0xcc00,
-0xcc00,
-0xcc00,
-0xcc00,
-0xcc00,
-0x7800,
-
-/* Character 246 (0xf6):
- width 0
- bbx ( 6, 9, 0, 0 )
-
- +------+
- | ** **|
- | |
- | **** |
- |** **|
- |** **|
- |** **|
- |** **|
- |** **|
- | **** |
- +------+
-*/
-0x6c00,
-0x0000,
-0x7800,
-0xcc00,
-0xcc00,
-0xcc00,
-0xcc00,
-0xcc00,
-0x7800,
-
-/* Character 247 (0xf7):
- width 0
- bbx ( 6, 5, 0, 1 )
-
- +------+
- | ** |
- | |
- |******|
- | |
- | ** |
- +------+
-*/
-0x3000,
-0x0000,
-0xfc00,
-0x0000,
-0x3000,
-
-/* Character 248 (0xf8):
- width 6
- bbx ( 8, 7, -1, 0 )
-
- +--------+
- | **** *|
- | ** ** |
- | ** *** |
- | *** ** |
- | ** ** |
- | ** ** |
- |* **** |
- +--------+
-*/
-0x3d00,
-0x6600,
-0x6e00,
-0x7600,
-0x6600,
-0x6600,
-0xbc00,
-
-/* Character 249 (0xf9):
- width 11
- bbx ( 6, 10, 0, 0 )
-
- +------+
- | ** |
- | ** |
- | |
- |** **|
- |** **|
- |** **|
- |** **|
- |** **|
- |** ***|
- | ** **|
- +------+
-*/
-0x6000,
-0x3000,
-0x0000,
-0xcc00,
-0xcc00,
-0xcc00,
-0xcc00,
-0xcc00,
-0xdc00,
-0x6c00,
-
-/* Character 250 (0xfa):
- width 0
- bbx ( 6, 10, 0, 0 )
-
- +------+
- | ** |
- | ** |
- | |
- |** **|
- |** **|
- |** **|
- |** **|
- |** **|
- |** ***|
- | ** **|
- +------+
-*/
-0x1800,
-0x3000,
-0x0000,
-0xcc00,
-0xcc00,
-0xcc00,
-0xcc00,
-0xcc00,
-0xdc00,
-0x6c00,
-
-/* Character 251 (0xfb):
- width 254
- bbx ( 6, 10, 0, 0 )
-
- +------+
- | *** |
- | ** **|
- | |
- |** **|
- |** **|
- |** **|
- |** **|
- |** **|
- |** ***|
- | ** **|
- +------+
-*/
-0x3800,
-0x6c00,
-0x0000,
-0xcc00,
-0xcc00,
-0xcc00,
-0xcc00,
-0xcc00,
-0xdc00,
-0x6c00,
-
-/* Character 252 (0xfc):
- width 11
- bbx ( 6, 9, 0, 0 )
-
- +------+
- | ** **|
- | |
- |** **|
- |** **|
- |** **|
- |** **|
- |** **|
- |** ***|
- | ** **|
- +------+
-*/
-0x6c00,
-0x0000,
-0xcc00,
-0xcc00,
-0xcc00,
-0xcc00,
-0xcc00,
-0xdc00,
-0x6c00,
-
-/* Character 253 (0xfd):
- width 9
- bbx ( 7, 13, 0, -3 )
-
- +-------+
- | ** |
- | ** |
- | |
- |** **|
- |** **|
- | ** ** |
- | ** ** |
- | *** |
- | *** |
- | ** |
- | * |
- | ** |
- | ** |
- +-------+
-*/
-0x0c00,
-0x1800,
-0x0000,
-0xc600,
-0xc600,
-0x6c00,
-0x6c00,
-0x3800,
-0x3800,
-0x1800,
-0x1000,
-0x3000,
-0x6000,
-
-/* Character 254 (0xfe):
- width 0
- bbx ( 6, 12, 0, -3 )
-
- +------+
- |** |
- |** |
- |** ** |
- |*** **|
- |** **|
- |** **|
- |** **|
- |*** **|
- |** ** |
- |** |
- |** |
- |** |
- +------+
-*/
-0xc000,
-0xc000,
-0xd800,
-0xec00,
-0xcc00,
-0xcc00,
-0xcc00,
-0xec00,
-0xd800,
-0xc000,
-0xc000,
-0xc000,
-
-/* Character 255 (0xff):
- width 0
- bbx ( 7, 12, 0, -3 )
-
- +-------+
- | ** ** |
- | |
- |** **|
- |** **|
- | ** ** |
- | ** ** |
- | *** |
- | *** |
- | ** |
- | * |
- | ** |
- | ** |
- +-------+
-*/
-0x6c00,
-0x0000,
-0xc600,
-0xc600,
-0x6c00,
-0x6c00,
-0x3800,
-0x3800,
-0x1800,
-0x1000,
-0x3000,
-0x6000,
-};
-
-/* Character->glyph mapping. */
-static const unsigned long _sysfont_offset[] = {
- 0, /* (0x20) */
- 1, /* (0x21) */
- 10, /* (0x22) */
- 13, /* (0x23) */
- 21, /* (0x24) */
- 32, /* (0x25) */
- 41, /* (0x26) */
- 50, /* (0x27) */
- 53, /* (0x28) */
- 65, /* (0x29) */
- 77, /* (0x2a) */
- 81, /* (0x2b) */
- 86, /* (0x2c) */
- 90, /* (0x2d) */
- 91, /* (0x2e) */
- 93, /* (0x2f) */
- 102, /* (0x30) */
- 111, /* (0x31) */
- 120, /* (0x32) */
- 129, /* (0x33) */
- 138, /* (0x34) */
- 147, /* (0x35) */
- 156, /* (0x36) */
- 165, /* (0x37) */
- 174, /* (0x38) */
- 183, /* (0x39) */
- 192, /* (0x3a) */
- 199, /* (0x3b) */
- 208, /* (0x3c) */
- 213, /* (0x3d) */
- 216, /* (0x3e) */
- 221, /* (0x3f) */
- 230, /* (0x40) */
- 240, /* (0x41) */
- 249, /* (0x42) */
- 258, /* (0x43) */
- 267, /* (0x44) */
- 276, /* (0x45) */
- 285, /* (0x46) */
- 294, /* (0x47) */
- 303, /* (0x48) */
- 312, /* (0x49) */
- 321, /* (0x4a) */
- 330, /* (0x4b) */
- 339, /* (0x4c) */
- 348, /* (0x4d) */
- 357, /* (0x4e) */
- 366, /* (0x4f) */
- 375, /* (0x50) */
- 384, /* (0x51) */
- 393, /* (0x52) */
- 402, /* (0x53) */
- 411, /* (0x54) */
- 420, /* (0x55) */
- 429, /* (0x56) */
- 438, /* (0x57) */
- 447, /* (0x58) */
- 456, /* (0x59) */
- 465, /* (0x5a) */
- 474, /* (0x5b) */
- 486, /* (0x5c) */
- 495, /* (0x5d) */
- 507, /* (0x5e) */
- 511, /* (0x5f) */
- 512, /* (0x60) */
- 514, /* (0x61) */
- 521, /* (0x62) */
- 530, /* (0x63) */
- 537, /* (0x64) */
- 546, /* (0x65) */
- 553, /* (0x66) */
- 562, /* (0x67) */
- 572, /* (0x68) */
- 581, /* (0x69) */
- 590, /* (0x6a) */
- 602, /* (0x6b) */
- 611, /* (0x6c) */
- 620, /* (0x6d) */
- 627, /* (0x6e) */
- 634, /* (0x6f) */
- 641, /* (0x70) */
- 651, /* (0x71) */
- 661, /* (0x72) */
- 668, /* (0x73) */
- 675, /* (0x74) */
- 684, /* (0x75) */
- 691, /* (0x76) */
- 698, /* (0x77) */
- 705, /* (0x78) */
- 712, /* (0x79) */
- 722, /* (0x7a) */
- 729, /* (0x7b) */
- 741, /* (0x7c) */
- 753, /* (0x7d) */
- 765, /* (0x7e) */
- 0, /* (0x7f) */
- 0, /* (0x80) */
- 0, /* (0x81) */
- 0, /* (0x82) */
- 0, /* (0x83) */
- 0, /* (0x84) */
- 0, /* (0x85) */
- 0, /* (0x86) */
- 0, /* (0x87) */
- 0, /* (0x88) */
- 0, /* (0x89) */
- 0, /* (0x8a) */
- 0, /* (0x8b) */
- 0, /* (0x8c) */
- 0, /* (0x8d) */
- 0, /* (0x8e) */
- 0, /* (0x8f) */
- 0, /* (0x90) */
- 0, /* (0x91) */
- 0, /* (0x92) */
- 0, /* (0x93) */
- 0, /* (0x94) */
- 0, /* (0x95) */
- 0, /* (0x96) */
- 0, /* (0x97) */
- 0, /* (0x98) */
- 0, /* (0x99) */
- 0, /* (0x9a) */
- 0, /* (0x9b) */
- 0, /* (0x9c) */
- 0, /* (0x9d) */
- 0, /* (0x9e) */
- 0, /* (0x9f) */
- 767, /* (0xa0) */
- 768, /* (0xa1) */
- 778, /* (0xa2) */
- 787, /* (0xa3) */
- 796, /* (0xa4) */
- 802, /* (0xa5) */
- 811, /* (0xa6) */
- 822, /* (0xa7) */
- 834, /* (0xa8) */
- 835, /* (0xa9) */
- 844, /* (0xaa) */
- 850, /* (0xab) */
- 855, /* (0xac) */
- 859, /* (0xad) */
- 860, /* (0xae) */
- 869, /* (0xaf) */
- 870, /* (0xb0) */
- 874, /* (0xb1) */
- 881, /* (0xb2) */
- 886, /* (0xb3) */
- 891, /* (0xb4) */
- 893, /* (0xb5) */
- 903, /* (0xb6) */
- 915, /* (0xb7) */
- 917, /* (0xb8) */
- 921, /* (0xb9) */
- 926, /* (0xba) */
- 932, /* (0xbb) */
- 937, /* (0xbc) */
- 946, /* (0xbd) */
- 955, /* (0xbe) */
- 964, /* (0xbf) */
- 974, /* (0xc0) */
- 986, /* (0xc1) */
- 998, /* (0xc2) */
- 1010, /* (0xc3) */
- 1022, /* (0xc4) */
- 1033, /* (0xc5) */
- 1045, /* (0xc6) */
- 1054, /* (0xc7) */
- 1066, /* (0xc8) */
- 1078, /* (0xc9) */
- 1090, /* (0xca) */
- 1102, /* (0xcb) */
- 1113, /* (0xcc) */
- 1125, /* (0xcd) */
- 1137, /* (0xce) */
- 1149, /* (0xcf) */
- 1160, /* (0xd0) */
- 1169, /* (0xd1) */
- 1181, /* (0xd2) */
- 1193, /* (0xd3) */
- 1205, /* (0xd4) */
- 1217, /* (0xd5) */
- 1229, /* (0xd6) */
- 1240, /* (0xd7) */
- 1245, /* (0xd8) */
- 1255, /* (0xd9) */
- 1267, /* (0xda) */
- 1279, /* (0xdb) */
- 1291, /* (0xdc) */
- 1302, /* (0xdd) */
- 1314, /* (0xde) */
- 1323, /* (0xdf) */
- 1332, /* (0xe0) */
- 1342, /* (0xe1) */
- 1352, /* (0xe2) */
- 1362, /* (0xe3) */
- 1372, /* (0xe4) */
- 1381, /* (0xe5) */
- 1392, /* (0xe6) */
- 1399, /* (0xe7) */
- 1409, /* (0xe8) */
- 1419, /* (0xe9) */
- 1429, /* (0xea) */
- 1439, /* (0xeb) */
- 1448, /* (0xec) */
- 1458, /* (0xed) */
- 1468, /* (0xee) */
- 1478, /* (0xef) */
- 1487, /* (0xf0) */
- 1497, /* (0xf1) */
- 1507, /* (0xf2) */
- 1517, /* (0xf3) */
- 1527, /* (0xf4) */
- 1537, /* (0xf5) */
- 1547, /* (0xf6) */
- 1556, /* (0xf7) */
- 1561, /* (0xf8) */
- 1568, /* (0xf9) */
- 1578, /* (0xfa) */
- 1588, /* (0xfb) */
- 1598, /* (0xfc) */
- 1607, /* (0xfd) */
- 1620, /* (0xfe) */
- 1632, /* (0xff) */
-};
-
-/* Character width data. */
-static const unsigned char _sysfont_width[] = {
- 4, /* (0x20) */
- 4, /* (0x21) */
- 5, /* (0x22) */
- 8, /* (0x23) */
- 7, /* (0x24) */
- 12, /* (0x25) */
- 9, /* (0x26) */
- 3, /* (0x27) */
- 6, /* (0x28) */
- 6, /* (0x29) */
- 6, /* (0x2a) */
- 7, /* (0x2b) */
- 4, /* (0x2c) */
- 5, /* (0x2d) */
- 4, /* (0x2e) */
- 4, /* (0x2f) */
- 7, /* (0x30) */
- 7, /* (0x31) */
- 7, /* (0x32) */
- 7, /* (0x33) */
- 7, /* (0x34) */
- 7, /* (0x35) */
- 7, /* (0x36) */
- 7, /* (0x37) */
- 7, /* (0x38) */
- 7, /* (0x39) */
- 4, /* (0x3a) */
- 4, /* (0x3b) */
- 7, /* (0x3c) */
- 7, /* (0x3d) */
- 7, /* (0x3e) */
- 8, /* (0x3f) */
- 12, /* (0x40) */
- 8, /* (0x41) */
- 9, /* (0x42) */
- 8, /* (0x43) */
- 9, /* (0x44) */
- 8, /* (0x45) */
- 7, /* (0x46) */
- 10, /* (0x47) */
- 9, /* (0x48) */
- 4, /* (0x49) */
- 7, /* (0x4a) */
- 9, /* (0x4b) */
- 7, /* (0x4c) */
- 11, /* (0x4d) */
- 9, /* (0x4e) */
- 10, /* (0x4f) */
- 8, /* (0x50) */
- 10, /* (0x51) */
- 9, /* (0x52) */
- 9, /* (0x53) */
- 8, /* (0x54) */
- 9, /* (0x55) */
- 8, /* (0x56) */
- 10, /* (0x57) */
- 8, /* (0x58) */
- 8, /* (0x59) */
- 7, /* (0x5a) */
- 4, /* (0x5b) */
- 4, /* (0x5c) */
- 4, /* (0x5d) */
- 7, /* (0x5e) */
- 7, /* (0x5f) */
- 4, /* (0x60) */
- 7, /* (0x61) */
- 7, /* (0x62) */
- 7, /* (0x63) */
- 7, /* (0x64) */
- 7, /* (0x65) */
- 5, /* (0x66) */
- 7, /* (0x67) */
- 7, /* (0x68) */
- 3, /* (0x69) */
- 3, /* (0x6a) */
- 7, /* (0x6b) */
- 3, /* (0x6c) */
- 11, /* (0x6d) */
- 7, /* (0x6e) */
- 7, /* (0x6f) */
- 7, /* (0x70) */
- 7, /* (0x71) */
- 5, /* (0x72) */
- 7, /* (0x73) */
- 5, /* (0x74) */
- 7, /* (0x75) */
- 8, /* (0x76) */
- 11, /* (0x77) */
- 7, /* (0x78) */
- 8, /* (0x79) */
- 6, /* (0x7a) */
- 5, /* (0x7b) */
- 4, /* (0x7c) */
- 5, /* (0x7d) */
- 7, /* (0x7e) */
- 4, /* (0x7f) */
- 4, /* (0x80) */
- 4, /* (0x81) */
- 4, /* (0x82) */
- 4, /* (0x83) */
- 4, /* (0x84) */
- 4, /* (0x85) */
- 4, /* (0x86) */
- 4, /* (0x87) */
- 4, /* (0x88) */
- 4, /* (0x89) */
- 4, /* (0x8a) */
- 4, /* (0x8b) */
- 4, /* (0x8c) */
- 4, /* (0x8d) */
- 4, /* (0x8e) */
- 4, /* (0x8f) */
- 4, /* (0x90) */
- 4, /* (0x91) */
- 4, /* (0x92) */
- 4, /* (0x93) */
- 4, /* (0x94) */
- 4, /* (0x95) */
- 4, /* (0x96) */
- 4, /* (0x97) */
- 4, /* (0x98) */
- 4, /* (0x99) */
- 4, /* (0x9a) */
- 4, /* (0x9b) */
- 4, /* (0x9c) */
- 4, /* (0x9d) */
- 4, /* (0x9e) */
- 4, /* (0x9f) */
- 4, /* (0xa0) */
- 4, /* (0xa1) */
- 7, /* (0xa2) */
- 7, /* (0xa3) */
- 7, /* (0xa4) */
- 7, /* (0xa5) */
- 4, /* (0xa6) */
- 7, /* (0xa7) */
- 5, /* (0xa8) */
- 11, /* (0xa9) */
- 6, /* (0xaa) */
- 8, /* (0xab) */
- 8, /* (0xac) */
- 5, /* (0xad) */
- 11, /* (0xae) */
- 4, /* (0xaf) */
- 5, /* (0xb0) */
- 7, /* (0xb1) */
- 4, /* (0xb2) */
- 4, /* (0xb3) */
- 4, /* (0xb4) */
- 7, /* (0xb5) */
- 7, /* (0xb6) */
- 4, /* (0xb7) */
- 4, /* (0xb8) */
- 4, /* (0xb9) */
- 6, /* (0xba) */
- 8, /* (0xbb) */
- 10, /* (0xbc) */
- 10, /* (0xbd) */
- 10, /* (0xbe) */
- 8, /* (0xbf) */
- 8, /* (0xc0) */
- 8, /* (0xc1) */
- 8, /* (0xc2) */
- 8, /* (0xc3) */
- 8, /* (0xc4) */
- 8, /* (0xc5) */
- 13, /* (0xc6) */
- 8, /* (0xc7) */
- 8, /* (0xc8) */
- 8, /* (0xc9) */
- 8, /* (0xca) */
- 8, /* (0xcb) */
- 4, /* (0xcc) */
- 4, /* (0xcd) */
- 4, /* (0xce) */
- 4, /* (0xcf) */
- 9, /* (0xd0) */
- 9, /* (0xd1) */
- 10, /* (0xd2) */
- 10, /* (0xd3) */
- 10, /* (0xd4) */
- 10, /* (0xd5) */
- 10, /* (0xd6) */
- 7, /* (0xd7) */
- 10, /* (0xd8) */
- 9, /* (0xd9) */
- 9, /* (0xda) */
- 9, /* (0xdb) */
- 9, /* (0xdc) */
- 8, /* (0xdd) */
- 8, /* (0xde) */
- 8, /* (0xdf) */
- 7, /* (0xe0) */
- 7, /* (0xe1) */
- 7, /* (0xe2) */
- 7, /* (0xe3) */
- 7, /* (0xe4) */
- 7, /* (0xe5) */
- 11, /* (0xe6) */
- 7, /* (0xe7) */
- 7, /* (0xe8) */
- 7, /* (0xe9) */
- 7, /* (0xea) */
- 7, /* (0xeb) */
- 3, /* (0xec) */
- 3, /* (0xed) */
- 3, /* (0xee) */
- 3, /* (0xef) */
- 7, /* (0xf0) */
- 7, /* (0xf1) */
- 7, /* (0xf2) */
- 7, /* (0xf3) */
- 7, /* (0xf4) */
- 7, /* (0xf5) */
- 7, /* (0xf6) */
- 7, /* (0xf7) */
- 7, /* (0xf8) */
- 7, /* (0xf9) */
- 7, /* (0xfa) */
- 7, /* (0xfb) */
- 7, /* (0xfc) */
- 8, /* (0xfd) */
- 7, /* (0xfe) */
- 8, /* (0xff) */
-};
-
-/* Bounding box data. */
-static const BBX _sysfont_bbx[] = {
- { 1, 1, 0, 0 }, /* (0x20) */
- { 2, 9, 1, 0 }, /* (0x21) */
- { 3, 3, 1, 6 }, /* (0x22) */
- { 7, 8, 0, 0 }, /* (0x23) */
- { 6, 11, 0, -2 }, /* (0x24) */
- { 11, 9, 0, 0 }, /* (0x25) */
- { 9, 9, 0, 0 }, /* (0x26) */
- { 1, 3, 1, 6 }, /* (0x27) */
- { 4, 12, 1, -3 }, /* (0x28) */
- { 4, 12, 1, -3 }, /* (0x29) */
- { 5, 4, 0, 5 }, /* (0x2a) */
- { 6, 5, 0, 1 }, /* (0x2b) */
- { 2, 4, 1, -2 }, /* (0x2c) */
- { 4, 1, 0, 3 }, /* (0x2d) */
- { 2, 2, 1, 0 }, /* (0x2e) */
- { 4, 9, 0, 0 }, /* (0x2f) */
- { 6, 9, 0, 0 }, /* (0x30) */
- { 4, 9, 0, 0 }, /* (0x31) */
- { 6, 9, 0, 0 }, /* (0x32) */
- { 6, 9, 0, 0 }, /* (0x33) */
- { 7, 9, 0, 0 }, /* (0x34) */
- { 6, 9, 0, 0 }, /* (0x35) */
- { 6, 9, 0, 0 }, /* (0x36) */
- { 6, 9, 0, 0 }, /* (0x37) */
- { 6, 9, 0, 0 }, /* (0x38) */
- { 6, 9, 0, 0 }, /* (0x39) */
- { 2, 7, 1, 0 }, /* (0x3a) */
- { 2, 9, 1, -2 }, /* (0x3b) */
- { 5, 5, 1, 1 }, /* (0x3c) */
- { 6, 3, 0, 2 }, /* (0x3d) */
- { 5, 5, 1, 1 }, /* (0x3e) */
- { 6, 9, 1, 0 }, /* (0x3f) */
- { 10, 10, 1, -1 }, /* (0x40) */
- { 8, 9, 0, 0 }, /* (0x41) */
- { 7, 9, 1, 0 }, /* (0x42) */
- { 7, 9, 1, 0 }, /* (0x43) */
- { 7, 9, 1, 0 }, /* (0x44) */
- { 6, 9, 1, 0 }, /* (0x45) */
- { 6, 9, 1, 0 }, /* (0x46) */
- { 8, 9, 1, 0 }, /* (0x47) */
- { 7, 9, 1, 0 }, /* (0x48) */
- { 2, 9, 1, 0 }, /* (0x49) */
- { 6, 9, 0, 0 }, /* (0x4a) */
- { 8, 9, 1, 0 }, /* (0x4b) */
- { 6, 9, 1, 0 }, /* (0x4c) */
- { 9, 9, 1, 0 }, /* (0x4d) */
- { 7, 9, 1, 0 }, /* (0x4e) */
- { 8, 9, 1, 0 }, /* (0x4f) */
- { 7, 9, 1, 0 }, /* (0x50) */
- { 8, 9, 1, 0 }, /* (0x51) */
- { 7, 9, 1, 0 }, /* (0x52) */
- { 7, 9, 1, 0 }, /* (0x53) */
- { 8, 9, 0, 0 }, /* (0x54) */
- { 7, 9, 1, 0 }, /* (0x55) */
- { 8, 9, 0, 0 }, /* (0x56) */
- { 10, 9, 0, 0 }, /* (0x57) */
- { 8, 9, 0, 0 }, /* (0x58) */
- { 8, 9, 0, 0 }, /* (0x59) */
- { 7, 9, 0, 0 }, /* (0x5a) */
- { 3, 12, 1, -3 }, /* (0x5b) */
- { 4, 9, 0, 0 }, /* (0x5c) */
- { 3, 12, 0, -3 }, /* (0x5d) */
- { 7, 4, 0, 5 }, /* (0x5e) */
- { 7, 1, 0, -3 }, /* (0x5f) */
- { 3, 2, 0, 8 }, /* (0x60) */
- { 7, 7, 0, 0 }, /* (0x61) */
- { 6, 9, 0, 0 }, /* (0x62) */
- { 6, 7, 0, 0 }, /* (0x63) */
- { 6, 9, 0, 0 }, /* (0x64) */
- { 6, 7, 0, 0 }, /* (0x65) */
- { 5, 9, 0, 0 }, /* (0x66) */
- { 6, 10, 0, -3 }, /* (0x67) */
- { 6, 9, 0, 0 }, /* (0x68) */
- { 2, 9, 0, 0 }, /* (0x69) */
- { 3, 12, -1, -3 }, /* (0x6a) */
- { 7, 9, 0, 0 }, /* (0x6b) */
- { 2, 9, 0, 0 }, /* (0x6c) */
- { 10, 7, 0, 0 }, /* (0x6d) */
- { 6, 7, 0, 0 }, /* (0x6e) */
- { 6, 7, 0, 0 }, /* (0x6f) */
- { 6, 10, 0, -3 }, /* (0x70) */
- { 6, 10, 0, -3 }, /* (0x71) */
- { 5, 7, 0, 0 }, /* (0x72) */
- { 6, 7, 0, 0 }, /* (0x73) */
- { 5, 9, 0, 0 }, /* (0x74) */
- { 6, 7, 0, 0 }, /* (0x75) */
- { 7, 7, 0, 0 }, /* (0x76) */
- { 10, 7, 0, 0 }, /* (0x77) */
- { 6, 7, 0, 0 }, /* (0x78) */
- { 7, 10, 0, -3 }, /* (0x79) */
- { 5, 7, 0, 0 }, /* (0x7a) */
- { 4, 12, 0, -3 }, /* (0x7b) */
- { 2, 12, 1, -3 }, /* (0x7c) */
- { 4, 12, 0, -3 }, /* (0x7d) */
- { 7, 2, 0, 3 }, /* (0x7e) */
- { 1, 1, 0, 0 }, /* (0x7f) */
- { 1, 1, 0, 0 }, /* (0x80) */
- { 1, 1, 0, 0 }, /* (0x81) */
- { 1, 1, 0, 0 }, /* (0x82) */
- { 1, 1, 0, 0 }, /* (0x83) */
- { 1, 1, 0, 0 }, /* (0x84) */
- { 1, 1, 0, 0 }, /* (0x85) */
- { 1, 1, 0, 0 }, /* (0x86) */
- { 1, 1, 0, 0 }, /* (0x87) */
- { 1, 1, 0, 0 }, /* (0x88) */
- { 1, 1, 0, 0 }, /* (0x89) */
- { 1, 1, 0, 0 }, /* (0x8a) */
- { 1, 1, 0, 0 }, /* (0x8b) */
- { 1, 1, 0, 0 }, /* (0x8c) */
- { 1, 1, 0, 0 }, /* (0x8d) */
- { 1, 1, 0, 0 }, /* (0x8e) */
- { 1, 1, 0, 0 }, /* (0x8f) */
- { 1, 1, 0, 0 }, /* (0x90) */
- { 1, 1, 0, 0 }, /* (0x91) */
- { 1, 1, 0, 0 }, /* (0x92) */
- { 1, 1, 0, 0 }, /* (0x93) */
- { 1, 1, 0, 0 }, /* (0x94) */
- { 1, 1, 0, 0 }, /* (0x95) */
- { 1, 1, 0, 0 }, /* (0x96) */
- { 1, 1, 0, 0 }, /* (0x97) */
- { 1, 1, 0, 0 }, /* (0x98) */
- { 1, 1, 0, 0 }, /* (0x99) */
- { 1, 1, 0, 0 }, /* (0x9a) */
- { 1, 1, 0, 0 }, /* (0x9b) */
- { 1, 1, 0, 0 }, /* (0x9c) */
- { 1, 1, 0, 0 }, /* (0x9d) */
- { 1, 1, 0, 0 }, /* (0x9e) */
- { 1, 1, 0, 0 }, /* (0x9f) */
- { 1, 1, 0, 0 }, /* (0xa0) */
- { 2, 10, 1, -3 }, /* (0xa1) */
- { 6, 9, 0, -1 }, /* (0xa2) */
- { 6, 9, 0, 0 }, /* (0xa3) */
- { 6, 6, 0, 1 }, /* (0xa4) */
- { 6, 9, 0, 0 }, /* (0xa5) */
- { 2, 11, 1, -2 }, /* (0xa6) */
- { 6, 12, 0, -3 }, /* (0xa7) */
- { 5, 1, 0, 8 }, /* (0xa8) */
- { 9, 9, 1, 0 }, /* (0xa9) */
- { 4, 6, 1, 3 }, /* (0xaa) */
- { 6, 5, 1, 1 }, /* (0xab) */
- { 6, 4, 1, 2 }, /* (0xac) */
- { 4, 1, 0, 3 }, /* (0xad) */
- { 9, 9, 1, 0 }, /* (0xae) */
- { 4, 1, 0, 8 }, /* (0xaf) */
- { 4, 4, 0, 4 }, /* (0xb0) */
- { 6, 7, 0, 0 }, /* (0xb1) */
- { 4, 5, 0, 4 }, /* (0xb2) */
- { 4, 5, 0, 4 }, /* (0xb3) */
- { 3, 2, 0, 8 }, /* (0xb4) */
- { 6, 10, 0, -3 }, /* (0xb5) */
- { 7, 12, 0, -3 }, /* (0xb6) */
- { 2, 2, 1, 3 }, /* (0xb7) */
- { 4, 4, 0, -3 }, /* (0xb8) */
- { 3, 5, 0, 4 }, /* (0xb9) */
- { 4, 6, 1, 3 }, /* (0xba) */
- { 6, 5, 1, 1 }, /* (0xbb) */
- { 10, 9, 0, 0 }, /* (0xbc) */
- { 10, 9, 0, 0 }, /* (0xbd) */
- { 10, 9, 0, 0 }, /* (0xbe) */
- { 6, 10, 1, -3 }, /* (0xbf) */
- { 8, 12, 0, 0 }, /* (0xc0) */
- { 8, 12, 0, 0 }, /* (0xc1) */
- { 8, 12, 0, 0 }, /* (0xc2) */
- { 8, 12, 0, 0 }, /* (0xc3) */
- { 8, 11, 0, 0 }, /* (0xc4) */
- { 8, 12, 0, 0 }, /* (0xc5) */
- { 11, 9, 1, 0 }, /* (0xc6) */
- { 7, 12, 1, -3 }, /* (0xc7) */
- { 6, 12, 1, 0 }, /* (0xc8) */
- { 6, 12, 1, 0 }, /* (0xc9) */
- { 6, 12, 1, 0 }, /* (0xca) */
- { 6, 11, 1, 0 }, /* (0xcb) */
- { 3, 12, 0, 0 }, /* (0xcc) */
- { 3, 12, 1, 0 }, /* (0xcd) */
- { 5, 12, 0, 0 }, /* (0xce) */
- { 5, 11, 0, 0 }, /* (0xcf) */
- { 8, 9, 0, 0 }, /* (0xd0) */
- { 7, 12, 1, 0 }, /* (0xd1) */
- { 8, 12, 1, 0 }, /* (0xd2) */
- { 8, 12, 1, 0 }, /* (0xd3) */
- { 8, 12, 1, 0 }, /* (0xd4) */
- { 8, 12, 1, 0 }, /* (0xd5) */
- { 8, 11, 1, 0 }, /* (0xd6) */
- { 6, 5, 0, 1 }, /* (0xd7) */
- { 8, 10, 1, -1 }, /* (0xd8) */
- { 7, 12, 1, 0 }, /* (0xd9) */
- { 7, 12, 1, 0 }, /* (0xda) */
- { 7, 12, 1, 0 }, /* (0xdb) */
- { 7, 11, 1, 0 }, /* (0xdc) */
- { 8, 12, 0, 0 }, /* (0xdd) */
- { 7, 9, 1, 0 }, /* (0xde) */
- { 6, 9, 1, 0 }, /* (0xdf) */
- { 7, 10, 0, 0 }, /* (0xe0) */
- { 7, 10, 0, 0 }, /* (0xe1) */
- { 7, 10, 0, 0 }, /* (0xe2) */
- { 7, 10, 0, 0 }, /* (0xe3) */
- { 7, 9, 0, 0 }, /* (0xe4) */
- { 7, 11, 0, 0 }, /* (0xe5) */
- { 10, 7, 0, 0 }, /* (0xe6) */
- { 6, 10, 0, -3 }, /* (0xe7) */
- { 6, 10, 0, 0 }, /* (0xe8) */
- { 6, 10, 0, 0 }, /* (0xe9) */
- { 6, 10, 0, 0 }, /* (0xea) */
- { 6, 9, 0, 0 }, /* (0xeb) */
- { 3, 10, -1, 0 }, /* (0xec) */
- { 3, 10, 0, 0 }, /* (0xed) */
- { 5, 10, -1, 0 }, /* (0xee) */
- { 5, 9, -1, 0 }, /* (0xef) */
- { 6, 10, 0, 0 }, /* (0xf0) */
- { 6, 10, 0, 0 }, /* (0xf1) */
- { 6, 10, 0, 0 }, /* (0xf2) */
- { 6, 10, 0, 0 }, /* (0xf3) */
- { 6, 10, 0, 0 }, /* (0xf4) */
- { 6, 10, 0, 0 }, /* (0xf5) */
- { 6, 9, 0, 0 }, /* (0xf6) */
- { 6, 5, 0, 1 }, /* (0xf7) */
- { 8, 7, -1, 0 }, /* (0xf8) */
- { 6, 10, 0, 0 }, /* (0xf9) */
- { 6, 10, 0, 0 }, /* (0xfa) */
- { 6, 10, 0, 0 }, /* (0xfb) */
- { 6, 9, 0, 0 }, /* (0xfc) */
- { 7, 13, 0, -3 }, /* (0xfd) */
- { 6, 12, 0, -3 }, /* (0xfe) */
- { 7, 12, 0, -3 }, /* (0xff) */
-};
-
-/* Exported structure definition. */
-static const BdfFontDesc desc = {
- "helvB12-L1",
+// Character 0 (0x00)
+// Box: 7 9 1 0
+// Advance: 9
+//
+// +-------+
+// |* * * *|
+// | |
+// |* *|
+// | |
+// |* *|
+// | |
+// |* *|
+// | |
+// |* * * *|
+// +-------+
+static const byte glyph0[] = {
+ 0xAA,
+ 0x00,
+ 0x82,
+ 0x00,
+ 0x82,
+ 0x00,
+ 0x82,
+ 0x00,
+ 0xAA
+};
+
+// Character 32 (0x20)
+// Box: 1 1 0 0
+// Advance: 4
+//
+// +-+
+// | |
+// +-+
+static const byte glyph32[] = {
+ 0x00
+};
+
+// Character 33 (0x21)
+// Box: 2 9 1 0
+// Advance: 4
+//
+// +--+
+// |**|
+// |**|
+// |**|
+// |**|
+// |**|
+// |* |
+// | |
+// |**|
+// |**|
+// +--+
+static const byte glyph33[] = {
+ 0xC0,
+ 0xC0,
+ 0xC0,
+ 0xC0,
+ 0xC0,
+ 0x80,
+ 0x00,
+ 0xC0,
+ 0xC0
+};
+
+// Character 34 (0x22)
+// Box: 3 3 1 6
+// Advance: 5
+//
+// +---+
+// |* *|
+// |* *|
+// |* *|
+// +---+
+static const byte glyph34[] = {
+ 0xA0,
+ 0xA0,
+ 0xA0
+};
+
+// Character 35 (0x23)
+// Box: 7 8 0 0
+// Advance: 8
+//
+// +-------+
+// | * * |
+// | * * |
+// | ******|
+// | * * |
+// | * * |
+// |****** |
+// | * * |
+// | * * |
+// +-------+
+static const byte glyph35[] = {
+ 0x14,
+ 0x14,
+ 0x7E,
+ 0x28,
+ 0x28,
+ 0xFC,
+ 0x50,
+ 0x50
+};
+
+// Character 36 (0x24)
+// Box: 6 11 0 -2
+// Advance: 7
+//
+// +------+
+// | * |
+// | **** |
+// |** * *|
+// |** * |
+// | **** |
+// | ***|
+// |* * *|
+// |** * *|
+// | **** |
+// | * |
+// | * |
+// +------+
+static const byte glyph36[] = {
+ 0x10,
+ 0x78,
+ 0xD4,
+ 0xD0,
+ 0x78,
+ 0x1C,
+ 0x94,
+ 0xD4,
+ 0x78,
+ 0x10,
+ 0x10
+};
+
+// Character 37 (0x25)
+// Box: 11 9 0 0
+// Advance: 12
+//
+// +-----------+
+// | *** * |
+// |** ** ** |
+// |** ** * |
+// | *** * |
+// | * |
+// | * *** |
+// | * ** **|
+// | ** ** **|
+// | * *** |
+// +-----------+
+static const byte glyph37[] = {
+ 0x71, 0x00,
+ 0xDB, 0x00,
+ 0xDA, 0x00,
+ 0x74, 0x00,
+ 0x04, 0x00,
+ 0x09, 0xC0,
+ 0x0B, 0x60,
+ 0x1B, 0x60,
+ 0x11, 0xC0
+};
+
+// Character 38 (0x26)
+// Box: 9 9 0 0
+// Advance: 9
+//
+// +---------+
+// | *** |
+// | ** ** |
+// | ** ** |
+// | *** |
+// | **** * |
+// |** **** |
+// |** ** |
+// |** **** |
+// | **** **|
+// +---------+
+static const byte glyph38[] = {
+ 0x38, 0x00,
+ 0x6C, 0x00,
+ 0x6C, 0x00,
+ 0x38, 0x00,
+ 0x79, 0x00,
+ 0xCF, 0x00,
+ 0xC6, 0x00,
+ 0xCF, 0x00,
+ 0x79, 0x80
+};
+
+// Character 39 (0x27)
+// Box: 1 3 1 6
+// Advance: 3
+//
+// +-+
+// |*|
+// |*|
+// |*|
+// +-+
+static const byte glyph39[] = {
+ 0x80,
+ 0x80,
+ 0x80
+};
+
+// Character 40 (0x28)
+// Box: 4 12 1 -3
+// Advance: 6
+//
+// +----+
+// | **|
+// | ** |
+// | ** |
+// |** |
+// |** |
+// |** |
+// |** |
+// |** |
+// |** |
+// | ** |
+// | ** |
+// | **|
+// +----+
+static const byte glyph40[] = {
+ 0x30,
+ 0x60,
+ 0x60,
+ 0xC0,
+ 0xC0,
+ 0xC0,
+ 0xC0,
+ 0xC0,
+ 0xC0,
+ 0x60,
+ 0x60,
+ 0x30
+};
+
+// Character 41 (0x29)
+// Box: 4 12 1 -3
+// Advance: 6
+//
+// +----+
+// |** |
+// | ** |
+// | ** |
+// | **|
+// | **|
+// | **|
+// | **|
+// | **|
+// | **|
+// | ** |
+// | ** |
+// |** |
+// +----+
+static const byte glyph41[] = {
+ 0xC0,
+ 0x60,
+ 0x60,
+ 0x30,
+ 0x30,
+ 0x30,
+ 0x30,
+ 0x30,
+ 0x30,
+ 0x60,
+ 0x60,
+ 0xC0
+};
+
+// Character 42 (0x2A)
+// Box: 5 4 0 5
+// Advance: 6
+//
+// +-----+
+// | * |
+// |*****|
+// | *** |
+// | * * |
+// +-----+
+static const byte glyph42[] = {
+ 0x20,
+ 0xF8,
+ 0x70,
+ 0x50
+};
+
+// Character 43 (0x2B)
+// Box: 6 5 0 1
+// Advance: 7
+//
+// +------+
+// | ** |
+// | ** |
+// |******|
+// | ** |
+// | ** |
+// +------+
+static const byte glyph43[] = {
+ 0x30,
+ 0x30,
+ 0xFC,
+ 0x30,
+ 0x30
+};
+
+// Character 44 (0x2C)
+// Box: 2 4 1 -2
+// Advance: 4
+//
+// +--+
+// |**|
+// |**|
+// | *|
+// |* |
+// +--+
+static const byte glyph44[] = {
+ 0xC0,
+ 0xC0,
+ 0x40,
+ 0x80
+};
+
+// Character 45 (0x2D)
+// Box: 4 1 0 3
+// Advance: 5
+//
+// +----+
+// |****|
+// +----+
+static const byte glyph45[] = {
+ 0xF0
+};
+
+// Character 46 (0x2E)
+// Box: 2 2 1 0
+// Advance: 4
+//
+// +--+
+// |**|
+// |**|
+// +--+
+static const byte glyph46[] = {
+ 0xC0,
+ 0xC0
+};
+
+// Character 47 (0x2F)
+// Box: 4 9 0 0
+// Advance: 4
+//
+// +----+
+// | **|
+// | **|
+// | * |
+// | ** |
+// | ** |
+// | * |
+// | * |
+// |** |
+// |** |
+// +----+
+static const byte glyph47[] = {
+ 0x30,
+ 0x30,
+ 0x20,
+ 0x60,
+ 0x60,
+ 0x40,
+ 0x40,
+ 0xC0,
+ 0xC0
+};
+
+// Character 48 (0x30)
+// Box: 6 9 0 0
+// Advance: 7
+//
+// +------+
+// | **** |
+// |** **|
+// |** **|
+// |** **|
+// |** **|
+// |** **|
+// |** **|
+// |** **|
+// | **** |
+// +------+
+static const byte glyph48[] = {
+ 0x78,
+ 0xCC,
+ 0xCC,
+ 0xCC,
+ 0xCC,
+ 0xCC,
+ 0xCC,
+ 0xCC,
+ 0x78
+};
+
+// Character 49 (0x31)
+// Box: 4 9 0 0
+// Advance: 7
+//
+// +----+
+// | **|
+// |****|
+// | **|
+// | **|
+// | **|
+// | **|
+// | **|
+// | **|
+// | **|
+// +----+
+static const byte glyph49[] = {
+ 0x30,
+ 0xF0,
+ 0x30,
+ 0x30,
+ 0x30,
+ 0x30,
+ 0x30,
+ 0x30,
+ 0x30
+};
+
+// Character 50 (0x32)
+// Box: 6 9 0 0
+// Advance: 7
+//
+// +------+
+// | **** |
+// |** **|
+// | **|
+// | ** |
+// | ** |
+// | ** |
+// |** |
+// |** |
+// |******|
+// +------+
+static const byte glyph50[] = {
+ 0x78,
+ 0xCC,
+ 0x0C,
+ 0x18,
+ 0x30,
+ 0x60,
+ 0xC0,
+ 0xC0,
+ 0xFC
+};
+
+// Character 51 (0x33)
+// Box: 6 9 0 0
+// Advance: 7
+//
+// +------+
+// | **** |
+// |** **|
+// | **|
+// | *** |
+// | **|
+// | **|
+// | **|
+// |** **|
+// | **** |
+// +------+
+static const byte glyph51[] = {
+ 0x78,
+ 0xCC,
+ 0x0C,
+ 0x38,
+ 0x0C,
+ 0x0C,
+ 0x0C,
+ 0xCC,
+ 0x78
+};
+
+// Character 52 (0x34)
+// Box: 7 9 0 0
+// Advance: 7
+//
+// +-------+
+// | ** |
+// | *** |
+// | * ** |
+// | * ** |
+// | * ** |
+// |* ** |
+// |*******|
+// | ** |
+// | ** |
+// +-------+
+static const byte glyph52[] = {
+ 0x0C,
+ 0x1C,
+ 0x2C,
+ 0x2C,
+ 0x4C,
+ 0x8C,
+ 0xFE,
+ 0x0C,
+ 0x0C
+};
+
+// Character 53 (0x35)
+// Box: 6 9 0 0
+// Advance: 7
+//
+// +------+
+// | *****|
+// | ** |
+// |** |
+// |***** |
+// | **|
+// | **|
+// |** **|
+// |** **|
+// | **** |
+// +------+
+static const byte glyph53[] = {
+ 0x7C,
+ 0x60,
+ 0xC0,
+ 0xF8,
+ 0x0C,
+ 0x0C,
+ 0xCC,
+ 0xCC,
+ 0x78
+};
+
+// Character 54 (0x36)
+// Box: 6 9 0 0
+// Advance: 7
+//
+// +------+
+// | **** |
+// |** **|
+// |** |
+// |** |
+// |***** |
+// |** **|
+// |** **|
+// |** **|
+// | **** |
+// +------+
+static const byte glyph54[] = {
+ 0x78,
+ 0xCC,
+ 0xC0,
+ 0xC0,
+ 0xF8,
+ 0xCC,
+ 0xCC,
+ 0xCC,
+ 0x78
+};
+
+// Character 55 (0x37)
+// Box: 6 9 0 0
+// Advance: 7
+//
+// +------+
+// |******|
+// | **|
+// | ** |
+// | ** |
+// | ** |
+// | ** |
+// | ** |
+// | ** |
+// | ** |
+// +------+
+static const byte glyph55[] = {
+ 0xFC,
+ 0x0C,
+ 0x18,
+ 0x18,
+ 0x30,
+ 0x30,
+ 0x30,
+ 0x60,
+ 0x60
+};
+
+// Character 56 (0x38)
+// Box: 6 9 0 0
+// Advance: 7
+//
+// +------+
+// | **** |
+// |** **|
+// |** **|
+// | **** |
+// |** **|
+// |** **|
+// |** **|
+// |** **|
+// | **** |
+// +------+
+static const byte glyph56[] = {
+ 0x78,
+ 0xCC,
+ 0xCC,
+ 0x78,
+ 0xCC,
+ 0xCC,
+ 0xCC,
+ 0xCC,
+ 0x78
+};
+
+// Character 57 (0x39)
+// Box: 6 9 0 0
+// Advance: 7
+//
+// +------+
+// | **** |
+// |** **|
+// |** **|
+// |** **|
+// | *****|
+// | **|
+// | **|
+// |** **|
+// | **** |
+// +------+
+static const byte glyph57[] = {
+ 0x78,
+ 0xCC,
+ 0xCC,
+ 0xCC,
+ 0x7C,
+ 0x0C,
+ 0x0C,
+ 0xCC,
+ 0x78
+};
+
+// Character 58 (0x3A)
+// Box: 2 7 1 0
+// Advance: 4
+//
+// +--+
+// |**|
+// |**|
+// | |
+// | |
+// | |
+// |**|
+// |**|
+// +--+
+static const byte glyph58[] = {
+ 0xC0,
+ 0xC0,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0xC0,
+ 0xC0
+};
+
+// Character 59 (0x3B)
+// Box: 2 9 1 -2
+// Advance: 4
+//
+// +--+
+// |**|
+// |**|
+// | |
+// | |
+// | |
+// |**|
+// |**|
+// | *|
+// |* |
+// +--+
+static const byte glyph59[] = {
+ 0xC0,
+ 0xC0,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0xC0,
+ 0xC0,
+ 0x40,
+ 0x80
+};
+
+// Character 60 (0x3C)
+// Box: 5 5 1 1
+// Advance: 7
+//
+// +-----+
+// | **|
+// | *** |
+// |** |
+// | *** |
+// | **|
+// +-----+
+static const byte glyph60[] = {
+ 0x18,
+ 0x70,
+ 0xC0,
+ 0x70,
+ 0x18
+};
+
+// Character 61 (0x3D)
+// Box: 6 3 0 2
+// Advance: 7
+//
+// +------+
+// |******|
+// | |
+// |******|
+// +------+
+static const byte glyph61[] = {
+ 0xFC,
+ 0x00,
+ 0xFC
+};
+
+// Character 62 (0x3E)
+// Box: 5 5 1 1
+// Advance: 7
+//
+// +-----+
+// |** |
+// | *** |
+// | **|
+// | *** |
+// |** |
+// +-----+
+static const byte glyph62[] = {
+ 0xC0,
+ 0x70,
+ 0x18,
+ 0x70,
+ 0xC0
+};
+
+// Character 63 (0x3F)
+// Box: 6 9 1 0
+// Advance: 8
+//
+// +------+
+// | **** |
+// |** **|
+// |** **|
+// | ** |
+// | ** |
+// | ** |
+// | |
+// | ** |
+// | ** |
+// +------+
+static const byte glyph63[] = {
+ 0x78,
+ 0xCC,
+ 0xCC,
+ 0x18,
+ 0x30,
+ 0x30,
+ 0x00,
+ 0x30,
+ 0x30
+};
+
+// Character 64 (0x40)
+// Box: 10 10 1 -1
+// Advance: 12
+//
+// +----------+
+// | ***** |
+// | ** * |
+// | * *|
+// |* ** * *|
+// |* * * *|
+// |* * * *|
+// |* * ** * |
+// |* ** ** |
+// | * |
+// | ***** |
+// +----------+
+static const byte glyph64[] = {
+ 0x1F, 0x00,
+ 0x60, 0x80,
+ 0x40, 0x40,
+ 0x8D, 0x40,
+ 0x92, 0x40,
+ 0xA2, 0x40,
+ 0xA6, 0x80,
+ 0x9B, 0x00,
+ 0x40, 0x00,
+ 0x3E, 0x00
+};
+
+// Character 65 (0x41)
+// Box: 8 9 0 0
+// Advance: 8
+//
+// +--------+
+// | ** |
+// | **** |
+// | * * |
+// | ** ** |
+// | ** ** |
+// | ****** |
+// |** **|
+// |** **|
+// |** **|
+// +--------+
+static const byte glyph65[] = {
+ 0x18,
+ 0x3C,
+ 0x24,
+ 0x66,
+ 0x66,
+ 0x7E,
+ 0xC3,
+ 0xC3,
+ 0xC3
+};
+
+// Character 66 (0x42)
+// Box: 7 9 1 0
+// Advance: 9
+//
+// +-------+
+// |****** |
+// |** **|
+// |** **|
+// |** **|
+// |****** |
+// |** **|
+// |** **|
+// |** **|
+// |****** |
+// +-------+
+static const byte glyph66[] = {
+ 0xFC,
+ 0xC6,
+ 0xC6,
+ 0xC6,
+ 0xFC,
+ 0xC6,
+ 0xC6,
+ 0xC6,
+ 0xFC
+};
+
+// Character 67 (0x43)
+// Box: 7 9 1 0
+// Advance: 8
+//
+// +-------+
+// | **** |
+// | ** **|
+// |** |
+// |** |
+// |** |
+// |** |
+// |** |
+// | ** **|
+// | **** |
+// +-------+
+static const byte glyph67[] = {
+ 0x3C,
+ 0x66,
+ 0xC0,
+ 0xC0,
+ 0xC0,
+ 0xC0,
+ 0xC0,
+ 0x66,
+ 0x3C
+};
+
+// Character 68 (0x44)
+// Box: 7 9 1 0
+// Advance: 9
+//
+// +-------+
+// |***** |
+// |** ** |
+// |** **|
+// |** **|
+// |** **|
+// |** **|
+// |** **|
+// |** ** |
+// |***** |
+// +-------+
+static const byte glyph68[] = {
+ 0xF8,
+ 0xCC,
+ 0xC6,
+ 0xC6,
+ 0xC6,
+ 0xC6,
+ 0xC6,
+ 0xCC,
+ 0xF8
+};
+
+// Character 69 (0x45)
+// Box: 6 9 1 0
+// Advance: 8
+//
+// +------+
+// |******|
+// |** |
+// |** |
+// |** |
+// |******|
+// |** |
+// |** |
+// |** |
+// |******|
+// +------+
+static const byte glyph69[] = {
+ 0xFC,
+ 0xC0,
+ 0xC0,
+ 0xC0,
+ 0xFC,
+ 0xC0,
+ 0xC0,
+ 0xC0,
+ 0xFC
+};
+
+// Character 70 (0x46)
+// Box: 6 9 1 0
+// Advance: 7
+//
+// +------+
+// |******|
+// |** |
+// |** |
+// |** |
+// |***** |
+// |** |
+// |** |
+// |** |
+// |** |
+// +------+
+static const byte glyph70[] = {
+ 0xFC,
+ 0xC0,
+ 0xC0,
+ 0xC0,
+ 0xF8,
+ 0xC0,
+ 0xC0,
+ 0xC0,
+ 0xC0
+};
+
+// Character 71 (0x47)
+// Box: 8 9 1 0
+// Advance: 10
+//
+// +--------+
+// | ***** |
+// | ** **|
+// |** |
+// |** |
+// |** ****|
+// |** **|
+// |** **|
+// | ** **|
+// | **** *|
+// +--------+
+static const byte glyph71[] = {
+ 0x3E,
+ 0x63,
+ 0xC0,
+ 0xC0,
+ 0xCF,
+ 0xC3,
+ 0xC3,
+ 0x63,
+ 0x3D
+};
+
+// Character 72 (0x48)
+// Box: 7 9 1 0
+// Advance: 9
+//
+// +-------+
+// |** **|
+// |** **|
+// |** **|
+// |** **|
+// |*******|
+// |** **|
+// |** **|
+// |** **|
+// |** **|
+// +-------+
+static const byte glyph72[] = {
+ 0xC6,
+ 0xC6,
+ 0xC6,
+ 0xC6,
+ 0xFE,
+ 0xC6,
+ 0xC6,
+ 0xC6,
+ 0xC6
+};
+
+// Character 73 (0x49)
+// Box: 2 9 1 0
+// Advance: 4
+//
+// +--+
+// |**|
+// |**|
+// |**|
+// |**|
+// |**|
+// |**|
+// |**|
+// |**|
+// |**|
+// +--+
+static const byte glyph73[] = {
+ 0xC0,
+ 0xC0,
+ 0xC0,
+ 0xC0,
+ 0xC0,
+ 0xC0,
+ 0xC0,
+ 0xC0,
+ 0xC0
+};
+
+// Character 74 (0x4A)
+// Box: 6 9 0 0
+// Advance: 7
+//
+// +------+
+// | **|
+// | **|
+// | **|
+// | **|
+// | **|
+// | **|
+// |** **|
+// |** **|
+// | **** |
+// +------+
+static const byte glyph74[] = {
+ 0x0C,
+ 0x0C,
+ 0x0C,
+ 0x0C,
+ 0x0C,
+ 0x0C,
+ 0xCC,
+ 0xCC,
+ 0x78
+};
+
+// Character 75 (0x4B)
+// Box: 8 9 1 0
+// Advance: 9
+//
+// +--------+
+// |** ** |
+// |** ** |
+// |** ** |
+// |**** |
+// |**** |
+// |** ** |
+// |** ** |
+// |** ** |
+// |** **|
+// +--------+
+static const byte glyph75[] = {
+ 0xC6,
+ 0xCC,
+ 0xD8,
+ 0xF0,
+ 0xF0,
+ 0xD8,
+ 0xCC,
+ 0xC6,
+ 0xC3
+};
+
+// Character 76 (0x4C)
+// Box: 6 9 1 0
+// Advance: 7
+//
+// +------+
+// |** |
+// |** |
+// |** |
+// |** |
+// |** |
+// |** |
+// |** |
+// |** |
+// |******|
+// +------+
+static const byte glyph76[] = {
+ 0xC0,
+ 0xC0,
+ 0xC0,
+ 0xC0,
+ 0xC0,
+ 0xC0,
+ 0xC0,
+ 0xC0,
+ 0xFC
+};
+
+// Character 77 (0x4D)
+// Box: 9 9 1 0
+// Advance: 11
+//
+// +---------+
+// |** **|
+// |** **|
+// |*** ***|
+// |*** ***|
+// |**** ****|
+// |** * * **|
+// |** *** **|
+// |** * **|
+// |** * **|
+// +---------+
+static const byte glyph77[] = {
+ 0xC1, 0x80,
+ 0xC1, 0x80,
+ 0xE3, 0x80,
+ 0xE3, 0x80,
+ 0xF7, 0x80,
+ 0xD5, 0x80,
+ 0xDD, 0x80,
+ 0xC9, 0x80,
+ 0xC9, 0x80
+};
+
+// Character 78 (0x4E)
+// Box: 7 9 1 0
+// Advance: 9
+//
+// +-------+
+// |** **|
+// |*** **|
+// |*** **|
+// |** * **|
+// |** * **|
+// |** ***|
+// |** ***|
+// |** **|
+// |** **|
+// +-------+
+static const byte glyph78[] = {
+ 0xC6,
+ 0xE6,
+ 0xE6,
+ 0xD6,
+ 0xD6,
+ 0xCE,
+ 0xCE,
+ 0xC6,
+ 0xC6
+};
+
+// Character 79 (0x4F)
+// Box: 8 9 1 0
+// Advance: 10
+//
+// +--------+
+// | **** |
+// | ** ** |
+// |** **|
+// |** **|
+// |** **|
+// |** **|
+// |** **|
+// | ** ** |
+// | **** |
+// +--------+
+static const byte glyph79[] = {
+ 0x3C,
+ 0x66,
+ 0xC3,
+ 0xC3,
+ 0xC3,
+ 0xC3,
+ 0xC3,
+ 0x66,
+ 0x3C
+};
+
+// Character 80 (0x50)
+// Box: 7 9 1 0
+// Advance: 8
+//
+// +-------+
+// |****** |
+// |** **|
+// |** **|
+// |** **|
+// |****** |
+// |** |
+// |** |
+// |** |
+// |** |
+// +-------+
+static const byte glyph80[] = {
+ 0xFC,
+ 0xC6,
+ 0xC6,
+ 0xC6,
+ 0xFC,
+ 0xC0,
+ 0xC0,
+ 0xC0,
+ 0xC0
+};
+
+// Character 81 (0x51)
+// Box: 8 9 1 0
+// Advance: 10
+//
+// +--------+
+// | **** |
+// | ** ** |
+// |** **|
+// |** **|
+// |** **|
+// |** * **|
+// |** ****|
+// | ** ** |
+// | ******|
+// +--------+
+static const byte glyph81[] = {
+ 0x3C,
+ 0x66,
+ 0xC3,
+ 0xC3,
+ 0xC3,
+ 0xCB,
+ 0xCF,
+ 0x66,
+ 0x3F
+};
+
+// Character 82 (0x52)
+// Box: 7 9 1 0
+// Advance: 9
+//
+// +-------+
+// |****** |
+// |** **|
+// |** **|
+// |** **|
+// |****** |
+// |** ** |
+// |** **|
+// |** **|
+// |** **|
+// +-------+
+static const byte glyph82[] = {
+ 0xFC,
+ 0xC6,
+ 0xC6,
+ 0xC6,
+ 0xFC,
+ 0xCC,
+ 0xC6,
+ 0xC6,
+ 0xC6
+};
+
+// Character 83 (0x53)
+// Box: 7 9 1 0
+// Advance: 9
+//
+// +-------+
+// | ***** |
+// |** **|
+// |** **|
+// | *** |
+// | *** |
+// | ***|
+// |** **|
+// |** **|
+// | ***** |
+// +-------+
+static const byte glyph83[] = {
+ 0x7C,
+ 0xC6,
+ 0xC6,
+ 0x70,
+ 0x1C,
+ 0x0E,
+ 0xC6,
+ 0xC6,
+ 0x7C
+};
+
+// Character 84 (0x54)
+// Box: 8 9 0 0
+// Advance: 8
+//
+// +--------+
+// |********|
+// | ** |
+// | ** |
+// | ** |
+// | ** |
+// | ** |
+// | ** |
+// | ** |
+// | ** |
+// +--------+
+static const byte glyph84[] = {
+ 0xFF,
+ 0x18,
+ 0x18,
+ 0x18,
+ 0x18,
+ 0x18,
+ 0x18,
+ 0x18,
+ 0x18
+};
+
+// Character 85 (0x55)
+// Box: 7 9 1 0
+// Advance: 9
+//
+// +-------+
+// |** **|
+// |** **|
+// |** **|
+// |** **|
+// |** **|
+// |** **|
+// |** **|
+// | ** ** |
+// | ***** |
+// +-------+
+static const byte glyph85[] = {
+ 0xC6,
+ 0xC6,
+ 0xC6,
+ 0xC6,
+ 0xC6,
+ 0xC6,
+ 0xC6,
+ 0x6C,
+ 0x7C
+};
+
+// Character 86 (0x56)
+// Box: 8 9 0 0
+// Advance: 8
+//
+// +--------+
+// |** **|
+// |** **|
+// | ** ** |
+// | ** ** |
+// | ** ** |
+// | * * |
+// | **** |
+// | ** |
+// | ** |
+// +--------+
+static const byte glyph86[] = {
+ 0xC3,
+ 0xC3,
+ 0x66,
+ 0x66,
+ 0x66,
+ 0x24,
+ 0x3C,
+ 0x18,
+ 0x18
+};
+
+// Character 87 (0x57)
+// Box: 10 9 0 0
+// Advance: 10
+//
+// +----------+
+// |** ** **|
+// |** ** **|
+// |** ** **|
+// | * ** * |
+// | ** ** ** |
+// | ** ** ** |
+// | ** ** |
+// | ** ** |
+// | ** ** |
+// +----------+
+static const byte glyph87[] = {
+ 0xCC, 0xC0,
+ 0xCC, 0xC0,
+ 0xCC, 0xC0,
+ 0x4C, 0x80,
+ 0x6D, 0x80,
+ 0x6D, 0x80,
+ 0x33, 0x00,
+ 0x33, 0x00,
+ 0x33, 0x00
+};
+
+// Character 88 (0x58)
+// Box: 8 9 0 0
+// Advance: 8
+//
+// +--------+
+// |** **|
+// |** **|
+// | ** ** |
+// | **** |
+// | ** |
+// | **** |
+// | ** ** |
+// |** **|
+// |** **|
+// +--------+
+static const byte glyph88[] = {
+ 0xC3,
+ 0xC3,
+ 0x66,
+ 0x3C,
+ 0x18,
+ 0x3C,
+ 0x66,
+ 0xC3,
+ 0xC3
+};
+
+// Character 89 (0x59)
+// Box: 8 9 0 0
+// Advance: 8
+//
+// +--------+
+// |** **|
+// |** **|
+// | ** ** |
+// | ** ** |
+// | **** |
+// | ** |
+// | ** |
+// | ** |
+// | ** |
+// +--------+
+static const byte glyph89[] = {
+ 0xC3,
+ 0xC3,
+ 0x66,
+ 0x66,
+ 0x3C,
+ 0x18,
+ 0x18,
+ 0x18,
+ 0x18
+};
+
+// Character 90 (0x5A)
+// Box: 7 9 0 0
+// Advance: 7
+//
+// +-------+
+// |*******|
+// | **|
+// | ** |
+// | ** |
+// | ** |
+// | ** |
+// | ** |
+// |** |
+// |*******|
+// +-------+
+static const byte glyph90[] = {
+ 0xFE,
+ 0x06,
+ 0x0C,
+ 0x18,
+ 0x30,
+ 0x30,
+ 0x60,
+ 0xC0,
+ 0xFE
+};
+
+// Character 91 (0x5B)
+// Box: 3 12 1 -3
+// Advance: 4
+//
+// +---+
+// |***|
+// |** |
+// |** |
+// |** |
+// |** |
+// |** |
+// |** |
+// |** |
+// |** |
+// |** |
+// |** |
+// |***|
+// +---+
+static const byte glyph91[] = {
+ 0xE0,
+ 0xC0,
+ 0xC0,
+ 0xC0,
+ 0xC0,
+ 0xC0,
+ 0xC0,
+ 0xC0,
+ 0xC0,
+ 0xC0,
+ 0xC0,
+ 0xE0
+};
+
+// Character 92 (0x5C)
+// Box: 4 9 0 0
+// Advance: 4
+//
+// +----+
+// |** |
+// |** |
+// | * |
+// | ** |
+// | ** |
+// | * |
+// | * |
+// | **|
+// | **|
+// +----+
+static const byte glyph92[] = {
+ 0xC0,
+ 0xC0,
+ 0x40,
+ 0x60,
+ 0x60,
+ 0x20,
+ 0x20,
+ 0x30,
+ 0x30
+};
+
+// Character 93 (0x5D)
+// Box: 3 12 0 -3
+// Advance: 4
+//
+// +---+
+// |***|
+// | **|
+// | **|
+// | **|
+// | **|
+// | **|
+// | **|
+// | **|
+// | **|
+// | **|
+// | **|
+// |***|
+// +---+
+static const byte glyph93[] = {
+ 0xE0,
+ 0x60,
+ 0x60,
+ 0x60,
+ 0x60,
+ 0x60,
+ 0x60,
+ 0x60,
+ 0x60,
+ 0x60,
+ 0x60,
+ 0xE0
+};
+
+// Character 94 (0x5E)
+// Box: 7 4 0 5
+// Advance: 7
+//
+// +-------+
+// | * |
+// | *** |
+// | ** ** |
+// |** **|
+// +-------+
+static const byte glyph94[] = {
+ 0x10,
+ 0x38,
+ 0x6C,
+ 0xC6
+};
+
+// Character 95 (0x5F)
+// Box: 7 1 0 -3
+// Advance: 7
+//
+// +-------+
+// |*******|
+// +-------+
+static const byte glyph95[] = {
+ 0xFE
+};
+
+// Character 96 (0x60)
+// Box: 3 2 0 8
+// Advance: 4
+//
+// +---+
+// |** |
+// | **|
+// +---+
+static const byte glyph96[] = {
+ 0xC0,
+ 0x60
+};
+
+// Character 97 (0x61)
+// Box: 7 7 0 0
+// Advance: 7
+//
+// +-------+
+// | **** |
+// |** ** |
+// | ** |
+// | ***** |
+// |** ** |
+// |** ** |
+// | *** **|
+// +-------+
+static const byte glyph97[] = {
+ 0x78,
+ 0xCC,
+ 0x0C,
+ 0x7C,
+ 0xCC,
+ 0xCC,
+ 0x76
+};
+
+// Character 98 (0x62)
+// Box: 6 9 0 0
+// Advance: 7
+//
+// +------+
+// |** |
+// |** |
+// |** ** |
+// |*** **|
+// |** **|
+// |** **|
+// |** **|
+// |*** **|
+// |** ** |
+// +------+
+static const byte glyph98[] = {
+ 0xC0,
+ 0xC0,
+ 0xD8,
+ 0xEC,
+ 0xCC,
+ 0xCC,
+ 0xCC,
+ 0xEC,
+ 0xD8
+};
+
+// Character 99 (0x63)
+// Box: 6 7 0 0
+// Advance: 7
+//
+// +------+
+// | **** |
+// |** **|
+// |** |
+// |** |
+// |** |
+// |** **|
+// | **** |
+// +------+
+static const byte glyph99[] = {
+ 0x78,
+ 0xCC,
+ 0xC0,
+ 0xC0,
+ 0xC0,
+ 0xCC,
+ 0x78
+};
+
+// Character 100 (0x64)
+// Box: 6 9 0 0
+// Advance: 7
+//
+// +------+
+// | **|
+// | **|
+// | ** **|
+// |** ***|
+// |** **|
+// |** **|
+// |** **|
+// |** ***|
+// | ** **|
+// +------+
+static const byte glyph100[] = {
+ 0x0C,
+ 0x0C,
+ 0x6C,
+ 0xDC,
+ 0xCC,
+ 0xCC,
+ 0xCC,
+ 0xDC,
+ 0x6C
+};
+
+// Character 101 (0x65)
+// Box: 6 7 0 0
+// Advance: 7
+//
+// +------+
+// | **** |
+// |** **|
+// |** **|
+// |******|
+// |** |
+// |** **|
+// | **** |
+// +------+
+static const byte glyph101[] = {
+ 0x78,
+ 0xCC,
+ 0xCC,
+ 0xFC,
+ 0xC0,
+ 0xCC,
+ 0x78
+};
+
+// Character 102 (0x66)
+// Box: 5 9 0 0
+// Advance: 5
+//
+// +-----+
+// | ***|
+// | ** |
+// |**** |
+// | ** |
+// | ** |
+// | ** |
+// | ** |
+// | ** |
+// | ** |
+// +-----+
+static const byte glyph102[] = {
+ 0x38,
+ 0x60,
+ 0xF0,
+ 0x60,
+ 0x60,
+ 0x60,
+ 0x60,
+ 0x60,
+ 0x60
+};
+
+// Character 103 (0x67)
+// Box: 6 10 0 -3
+// Advance: 7
+//
+// +------+
+// | ** **|
+// |** ***|
+// |** **|
+// |** **|
+// |** **|
+// |** ***|
+// | ** **|
+// | **|
+// |** **|
+// | **** |
+// +------+
+static const byte glyph103[] = {
+ 0x6C,
+ 0xDC,
+ 0xCC,
+ 0xCC,
+ 0xCC,
+ 0xDC,
+ 0x6C,
+ 0x0C,
+ 0xCC,
+ 0x78
+};
+
+// Character 104 (0x68)
+// Box: 6 9 0 0
+// Advance: 7
+//
+// +------+
+// |** |
+// |** |
+// |** ** |
+// |*** **|
+// |** **|
+// |** **|
+// |** **|
+// |** **|
+// |** **|
+// +------+
+static const byte glyph104[] = {
+ 0xC0,
+ 0xC0,
+ 0xD8,
+ 0xEC,
+ 0xCC,
+ 0xCC,
+ 0xCC,
+ 0xCC,
+ 0xCC
+};
+
+// Character 105 (0x69)
+// Box: 2 9 0 0
+// Advance: 3
+//
+// +--+
+// |**|
+// | |
+// |**|
+// |**|
+// |**|
+// |**|
+// |**|
+// |**|
+// |**|
+// +--+
+static const byte glyph105[] = {
+ 0xC0,
+ 0x00,
+ 0xC0,
+ 0xC0,
+ 0xC0,
+ 0xC0,
+ 0xC0,
+ 0xC0,
+ 0xC0
+};
+
+// Character 106 (0x6A)
+// Box: 3 12 -1 -3
+// Advance: 3
+//
+// +---+
+// | **|
+// | |
+// | **|
+// | **|
+// | **|
+// | **|
+// | **|
+// | **|
+// | **|
+// | **|
+// | **|
+// |** |
+// +---+
+static const byte glyph106[] = {
+ 0x60,
+ 0x00,
+ 0x60,
+ 0x60,
+ 0x60,
+ 0x60,
+ 0x60,
+ 0x60,
+ 0x60,
+ 0x60,
+ 0x60,
+ 0xC0
+};
+
+// Character 107 (0x6B)
+// Box: 7 9 0 0
+// Advance: 7
+//
+// +-------+
+// |** |
+// |** |
+// |** ** |
+// |** ** |
+// |**** |
+// |**** |
+// |** ** |
+// |** ** |
+// |** **|
+// +-------+
+static const byte glyph107[] = {
+ 0xC0,
+ 0xC0,
+ 0xCC,
+ 0xD8,
+ 0xF0,
+ 0xF0,
+ 0xD8,
+ 0xCC,
+ 0xC6
+};
+
+// Character 108 (0x6C)
+// Box: 2 9 0 0
+// Advance: 3
+//
+// +--+
+// |**|
+// |**|
+// |**|
+// |**|
+// |**|
+// |**|
+// |**|
+// |**|
+// |**|
+// +--+
+static const byte glyph108[] = {
+ 0xC0,
+ 0xC0,
+ 0xC0,
+ 0xC0,
+ 0xC0,
+ 0xC0,
+ 0xC0,
+ 0xC0,
+ 0xC0
+};
+
+// Character 109 (0x6D)
+// Box: 10 7 0 0
+// Advance: 11
+//
+// +----------+
+// |* *** *** |
+// |** ** **|
+// |** ** **|
+// |** ** **|
+// |** ** **|
+// |** ** **|
+// |** ** **|
+// +----------+
+static const byte glyph109[] = {
+ 0xBB, 0x80,
+ 0xCC, 0xC0,
+ 0xCC, 0xC0,
+ 0xCC, 0xC0,
+ 0xCC, 0xC0,
+ 0xCC, 0xC0,
+ 0xCC, 0xC0
+};
+
+// Character 110 (0x6E)
+// Box: 6 7 0 0
+// Advance: 7
+//
+// +------+
+// |** ** |
+// |*** **|
+// |** **|
+// |** **|
+// |** **|
+// |** **|
+// |** **|
+// +------+
+static const byte glyph110[] = {
+ 0xD8,
+ 0xEC,
+ 0xCC,
+ 0xCC,
+ 0xCC,
+ 0xCC,
+ 0xCC
+};
+
+// Character 111 (0x6F)
+// Box: 6 7 0 0
+// Advance: 7
+//
+// +------+
+// | **** |
+// |** **|
+// |** **|
+// |** **|
+// |** **|
+// |** **|
+// | **** |
+// +------+
+static const byte glyph111[] = {
+ 0x78,
+ 0xCC,
+ 0xCC,
+ 0xCC,
+ 0xCC,
+ 0xCC,
+ 0x78
+};
+
+// Character 112 (0x70)
+// Box: 6 10 0 -3
+// Advance: 7
+//
+// +------+
+// |** ** |
+// |*** **|
+// |** **|
+// |** **|
+// |** **|
+// |*** **|
+// |** ** |
+// |** |
+// |** |
+// |** |
+// +------+
+static const byte glyph112[] = {
+ 0xD8,
+ 0xEC,
+ 0xCC,
+ 0xCC,
+ 0xCC,
+ 0xEC,
+ 0xD8,
+ 0xC0,
+ 0xC0,
+ 0xC0
+};
+
+// Character 113 (0x71)
+// Box: 6 10 0 -3
+// Advance: 7
+//
+// +------+
+// | *** *|
+// |** ***|
+// |** **|
+// |** **|
+// |** **|
+// |** ***|
+// | ** **|
+// | **|
+// | **|
+// | **|
+// +------+
+static const byte glyph113[] = {
+ 0x74,
+ 0xDC,
+ 0xCC,
+ 0xCC,
+ 0xCC,
+ 0xDC,
+ 0x6C,
+ 0x0C,
+ 0x0C,
+ 0x0C
+};
+
+// Character 114 (0x72)
+// Box: 5 7 0 0
+// Advance: 5
+//
+// +-----+
+// |** **|
+// |*****|
+// |*** |
+// |** |
+// |** |
+// |** |
+// |** |
+// +-----+
+static const byte glyph114[] = {
+ 0xD8,
+ 0xF8,
+ 0xE0,
+ 0xC0,
+ 0xC0,
+ 0xC0,
+ 0xC0
+};
+
+// Character 115 (0x73)
+// Box: 6 7 0 0
+// Advance: 7
+//
+// +------+
+// | **** |
+// |** **|
+// |*** |
+// | *** |
+// | ***|
+// |** **|
+// | **** |
+// +------+
+static const byte glyph115[] = {
+ 0x78,
+ 0xCC,
+ 0xE0,
+ 0x38,
+ 0x1C,
+ 0xCC,
+ 0x78
+};
+
+// Character 116 (0x74)
+// Box: 5 9 0 0
+// Advance: 5
+//
+// +-----+
+// | ** |
+// | ** |
+// |**** |
+// | ** |
+// | ** |
+// | ** |
+// | ** |
+// | ** *|
+// | ** |
+// +-----+
+static const byte glyph116[] = {
+ 0x60,
+ 0x60,
+ 0xF0,
+ 0x60,
+ 0x60,
+ 0x60,
+ 0x60,
+ 0x68,
+ 0x30
+};
+
+// Character 117 (0x75)
+// Box: 6 7 0 0
+// Advance: 7
+//
+// +------+
+// |** **|
+// |** **|
+// |** **|
+// |** **|
+// |** **|
+// |** ***|
+// | ** **|
+// +------+
+static const byte glyph117[] = {
+ 0xCC,
+ 0xCC,
+ 0xCC,
+ 0xCC,
+ 0xCC,
+ 0xDC,
+ 0x6C
+};
+
+// Character 118 (0x76)
+// Box: 7 7 0 0
+// Advance: 8
+//
+// +-------+
+// |** **|
+// |** **|
+// | ** ** |
+// | ** ** |
+// | *** |
+// | *** |
+// | * |
+// +-------+
+static const byte glyph118[] = {
+ 0xC6,
+ 0xC6,
+ 0x6C,
+ 0x6C,
+ 0x38,
+ 0x38,
+ 0x10
+};
+
+// Character 119 (0x77)
+// Box: 10 7 0 0
+// Advance: 11
+//
+// +----------+
+// |** ** **|
+// |** ** **|
+// | ** ** ** |
+// | ** ** ** |
+// | ** ** ** |
+// | ** ** |
+// | ** ** |
+// +----------+
+static const byte glyph119[] = {
+ 0xCC, 0xC0,
+ 0xCC, 0xC0,
+ 0x6D, 0x80,
+ 0x6D, 0x80,
+ 0x6D, 0x80,
+ 0x33, 0x00,
+ 0x33, 0x00
+};
+
+// Character 120 (0x78)
+// Box: 6 7 0 0
+// Advance: 7
+//
+// +------+
+// |** **|
+// |** **|
+// | **** |
+// | ** |
+// | **** |
+// |** **|
+// |** **|
+// +------+
+static const byte glyph120[] = {
+ 0xCC,
+ 0xCC,
+ 0x78,
+ 0x30,
+ 0x78,
+ 0xCC,
+ 0xCC
+};
+
+// Character 121 (0x79)
+// Box: 7 10 0 -3
+// Advance: 8
+//
+// +-------+
+// |** **|
+// |** **|
+// | ** ** |
+// | ** ** |
+// | *** |
+// | *** |
+// | ** |
+// | * |
+// | ** |
+// | ** |
+// +-------+
+static const byte glyph121[] = {
+ 0xC6,
+ 0xC6,
+ 0x6C,
+ 0x6C,
+ 0x38,
+ 0x38,
+ 0x18,
+ 0x10,
+ 0x30,
+ 0x60
+};
+
+// Character 122 (0x7A)
+// Box: 5 7 0 0
+// Advance: 6
+//
+// +-----+
+// |*****|
+// | **|
+// | ** |
+// | * |
+// | ** |
+// |** |
+// |*****|
+// +-----+
+static const byte glyph122[] = {
+ 0xF8,
+ 0x18,
+ 0x30,
+ 0x20,
+ 0x60,
+ 0xC0,
+ 0xF8
+};
+
+// Character 123 (0x7B)
+// Box: 4 12 0 -3
+// Advance: 5
+//
+// +----+
+// | **|
+// | ** |
+// | ** |
+// | ** |
+// | ** |
+// |** |
+// | ** |
+// | ** |
+// | ** |
+// | ** |
+// | ** |
+// | **|
+// +----+
+static const byte glyph123[] = {
+ 0x30,
+ 0x60,
+ 0x60,
+ 0x60,
+ 0x60,
+ 0xC0,
+ 0x60,
+ 0x60,
+ 0x60,
+ 0x60,
+ 0x60,
+ 0x30
+};
+
+// Character 124 (0x7C)
+// Box: 2 12 1 -3
+// Advance: 4
+//
+// +--+
+// |**|
+// |**|
+// |**|
+// |**|
+// |**|
+// |**|
+// |**|
+// |**|
+// |**|
+// |**|
+// |**|
+// |**|
+// +--+
+static const byte glyph124[] = {
+ 0xC0,
+ 0xC0,
+ 0xC0,
+ 0xC0,
+ 0xC0,
+ 0xC0,
+ 0xC0,
+ 0xC0,
+ 0xC0,
+ 0xC0,
+ 0xC0,
+ 0xC0
+};
+
+// Character 125 (0x7D)
+// Box: 4 12 0 -3
+// Advance: 5
+//
+// +----+
+// |** |
+// | ** |
+// | ** |
+// | ** |
+// | ** |
+// | **|
+// | ** |
+// | ** |
+// | ** |
+// | ** |
+// | ** |
+// |** |
+// +----+
+static const byte glyph125[] = {
+ 0xC0,
+ 0x60,
+ 0x60,
+ 0x60,
+ 0x60,
+ 0x30,
+ 0x60,
+ 0x60,
+ 0x60,
+ 0x60,
+ 0x60,
+ 0xC0
+};
+
+// Character 126 (0x7E)
+// Box: 7 2 0 3
+// Advance: 7
+//
+// +-------+
+// | *** **|
+// |** *** |
+// +-------+
+static const byte glyph126[] = {
+ 0x76,
+ 0xDC
+};
+
+// Character 160 (0xA0)
+// Box: 1 1 0 0
+// Advance: 4
+//
+// +-+
+// | |
+// +-+
+static const byte glyph160[] = {
+ 0x00
+};
+
+// Character 161 (0xA1)
+// Box: 2 10 1 -3
+// Advance: 4
+//
+// +--+
+// |**|
+// |**|
+// | |
+// | *|
+// |**|
+// |**|
+// |**|
+// |**|
+// |**|
+// |**|
+// +--+
+static const byte glyph161[] = {
+ 0xC0,
+ 0xC0,
+ 0x00,
+ 0x40,
+ 0xC0,
+ 0xC0,
+ 0xC0,
+ 0xC0,
+ 0xC0,
+ 0xC0
+};
+
+// Character 162 (0xA2)
+// Box: 6 9 0 -1
+// Advance: 7
+//
+// +------+
+// | * |
+// | **** |
+// |** ***|
+// |* * |
+// |* * |
+// |* * |
+// |*** **|
+// | **** |
+// | * |
+// +------+
+static const byte glyph162[] = {
+ 0x10,
+ 0x78,
+ 0xDC,
+ 0x90,
+ 0xA0,
+ 0xA0,
+ 0xEC,
+ 0x78,
+ 0x40
+};
+
+// Character 163 (0xA3)
+// Box: 6 9 0 0
+// Advance: 7
+//
+// +------+
+// | *** |
+// | ** **|
+// | ** |
+// | ** |
+// |***** |
+// | ** |
+// | ** |
+// |*** **|
+// |** ** |
+// +------+
+static const byte glyph163[] = {
+ 0x38,
+ 0x6C,
+ 0x60,
+ 0x60,
+ 0xF8,
+ 0x60,
+ 0x60,
+ 0xEC,
+ 0xD8
+};
+
+// Character 164 (0xA4)
+// Box: 6 6 0 1
+// Advance: 7
+//
+// +------+
+// |** **|
+// | **** |
+// | * * |
+// | * * |
+// | **** |
+// |** **|
+// +------+
+static const byte glyph164[] = {
+ 0xCC,
+ 0x78,
+ 0x48,
+ 0x48,
+ 0x78,
+ 0xCC
+};
+
+// Character 165 (0xA5)
+// Box: 6 9 0 0
+// Advance: 7
+//
+// +------+
+// |** **|
+// |** **|
+// | * * |
+// |******|
+// | ** |
+// |******|
+// | ** |
+// | ** |
+// | ** |
+// +------+
+static const byte glyph165[] = {
+ 0xCC,
+ 0xCC,
+ 0x48,
+ 0xFC,
+ 0x30,
+ 0xFC,
+ 0x30,
+ 0x30,
+ 0x30
+};
+
+// Character 166 (0xA6)
+// Box: 2 11 1 -2
+// Advance: 4
+//
+// +--+
+// |**|
+// |**|
+// |**|
+// |**|
+// | |
+// | |
+// |**|
+// |**|
+// |**|
+// |**|
+// |**|
+// +--+
+static const byte glyph166[] = {
+ 0xC0,
+ 0xC0,
+ 0xC0,
+ 0xC0,
+ 0x00,
+ 0x00,
+ 0xC0,
+ 0xC0,
+ 0xC0,
+ 0xC0,
+ 0xC0
+};
+
+// Character 167 (0xA7)
+// Box: 6 12 0 -3
+// Advance: 7
+//
+// +------+
+// | **** |
+// |** **|
+// |*** |
+// | *** |
+// |** ** |
+// |** **|
+// |** **|
+// | ** **|
+// | *** |
+// | ***|
+// |** **|
+// | **** |
+// +------+
+static const byte glyph167[] = {
+ 0x78,
+ 0xCC,
+ 0xE0,
+ 0x70,
+ 0xD8,
+ 0xCC,
+ 0xCC,
+ 0x6C,
+ 0x38,
+ 0x1C,
+ 0xCC,
+ 0x78
+};
+
+// Character 168 (0xA8)
+// Box: 5 1 0 8
+// Advance: 5
+//
+// +-----+
+// |** **|
+// +-----+
+static const byte glyph168[] = {
+ 0xD8
+};
+
+// Character 169 (0xA9)
+// Box: 9 9 1 0
+// Advance: 11
+//
+// +---------+
+// | ***** |
+// | * * |
+// |* *** *|
+// |* * * *|
+// |* * *|
+// |* * * *|
+// |* *** *|
+// | * * |
+// | ***** |
+// +---------+
+static const byte glyph169[] = {
+ 0x3E, 0x00,
+ 0x41, 0x00,
+ 0x9C, 0x80,
+ 0xA2, 0x80,
+ 0xA0, 0x80,
+ 0xA2, 0x80,
+ 0x9C, 0x80,
+ 0x41, 0x00,
+ 0x3E, 0x00
+};
+
+// Character 170 (0xAA)
+// Box: 4 6 1 3
+// Advance: 6
+//
+// +----+
+// |*** |
+// | **|
+// |****|
+// |* **|
+// | |
+// |****|
+// +----+
+static const byte glyph170[] = {
+ 0xE0,
+ 0x30,
+ 0xF0,
+ 0xB0,
+ 0x00,
+ 0xF0
+};
+
+// Character 171 (0xAB)
+// Box: 6 5 1 1
+// Advance: 8
+//
+// +------+
+// | * *|
+// | ** **|
+// |** ** |
+// | ** **|
+// | * *|
+// +------+
+static const byte glyph171[] = {
+ 0x24,
+ 0x6C,
+ 0xD8,
+ 0x6C,
+ 0x24
+};
+
+// Character 172 (0xAC)
+// Box: 6 4 1 2
+// Advance: 8
+//
+// +------+
+// |******|
+// | *|
+// | *|
+// | *|
+// +------+
+static const byte glyph172[] = {
+ 0xFC,
+ 0x04,
+ 0x04,
+ 0x04
+};
+
+// Character 173 (0xAD)
+// Box: 4 1 0 3
+// Advance: 5
+//
+// +----+
+// |****|
+// +----+
+static const byte glyph173[] = {
+ 0xF0
+};
+
+// Character 174 (0xAE)
+// Box: 9 9 1 0
+// Advance: 11
+//
+// +---------+
+// | ***** |
+// | * * |
+// |* *** *|
+// |* * * *|
+// |* ** *|
+// |* * * *|
+// |* * * *|
+// | * * |
+// | ***** |
+// +---------+
+static const byte glyph174[] = {
+ 0x3E, 0x00,
+ 0x41, 0x00,
+ 0x9C, 0x80,
+ 0x94, 0x80,
+ 0x98, 0x80,
+ 0x94, 0x80,
+ 0x94, 0x80,
+ 0x41, 0x00,
+ 0x3E, 0x00
+};
+
+// Character 175 (0xAF)
+// Box: 4 1 0 8
+// Advance: 4
+//
+// +----+
+// |****|
+// +----+
+static const byte glyph175[] = {
+ 0xF0
+};
+
+// Character 176 (0xB0)
+// Box: 4 4 0 4
+// Advance: 5
+//
+// +----+
+// | ** |
+// |* *|
+// |* *|
+// | ** |
+// +----+
+static const byte glyph176[] = {
+ 0x60,
+ 0x90,
+ 0x90,
+ 0x60
+};
+
+// Character 177 (0xB1)
+// Box: 6 7 0 0
+// Advance: 7
+//
+// +------+
+// | ** |
+// | ** |
+// |******|
+// | ** |
+// | ** |
+// | |
+// |******|
+// +------+
+static const byte glyph177[] = {
+ 0x30,
+ 0x30,
+ 0xFC,
+ 0x30,
+ 0x30,
+ 0x00,
+ 0xFC
+};
+
+// Character 178 (0xB2)
+// Box: 4 5 0 4
+// Advance: 4
+//
+// +----+
+// | ** |
+// |* **|
+// | ** |
+// |** |
+// |****|
+// +----+
+static const byte glyph178[] = {
+ 0x60,
+ 0xB0,
+ 0x60,
+ 0xC0,
+ 0xF0
+};
+
+// Character 179 (0xB3)
+// Box: 4 5 0 4
+// Advance: 4
+//
+// +----+
+// | ** |
+// |* **|
+// | ** |
+// | **|
+// |*** |
+// +----+
+static const byte glyph179[] = {
+ 0x60,
+ 0xB0,
+ 0x60,
+ 0x30,
+ 0xE0
+};
+
+// Character 180 (0xB4)
+// Box: 3 2 0 8
+// Advance: 4
+//
+// +---+
+// | **|
+// |** |
+// +---+
+static const byte glyph180[] = {
+ 0x60,
+ 0xC0
+};
+
+// Character 181 (0xB5)
+// Box: 6 10 0 -3
+// Advance: 7
+//
+// +------+
+// |** **|
+// |** **|
+// |** **|
+// |** **|
+// |** **|
+// |** ***|
+// |*** **|
+// |** |
+// |** |
+// |** |
+// +------+
+static const byte glyph181[] = {
+ 0xCC,
+ 0xCC,
+ 0xCC,
+ 0xCC,
+ 0xCC,
+ 0xDC,
+ 0xEC,
+ 0xC0,
+ 0xC0,
+ 0xC0
+};
+
+// Character 182 (0xB6)
+// Box: 7 12 0 -3
+// Advance: 7
+//
+// +-------+
+// | *****|
+// | *** * |
+// |**** * |
+// |**** * |
+// |**** * |
+// | *** * |
+// | ** * |
+// | * * |
+// | * * |
+// | * * |
+// | * * |
+// | * * |
+// +-------+
+static const byte glyph182[] = {
+ 0x3E,
+ 0x74,
+ 0xF4,
+ 0xF4,
+ 0xF4,
+ 0x74,
+ 0x34,
+ 0x14,
+ 0x14,
+ 0x14,
+ 0x14,
+ 0x14
+};
+
+// Character 183 (0xB7)
+// Box: 2 2 1 3
+// Advance: 4
+//
+// +--+
+// |**|
+// |**|
+// +--+
+static const byte glyph183[] = {
+ 0xC0,
+ 0xC0
+};
+
+// Character 184 (0xB8)
+// Box: 4 4 0 -3
+// Advance: 4
+//
+// +----+
+// | ** |
+// | **|
+// | **|
+// |*** |
+// +----+
+static const byte glyph184[] = {
+ 0x60,
+ 0x30,
+ 0x30,
+ 0xE0
+};
+
+// Character 185 (0xB9)
+// Box: 3 5 0 4
+// Advance: 4
+//
+// +---+
+// | **|
+// |***|
+// | **|
+// | **|
+// | **|
+// +---+
+static const byte glyph185[] = {
+ 0x60,
+ 0xE0,
+ 0x60,
+ 0x60,
+ 0x60
+};
+
+// Character 186 (0xBA)
+// Box: 4 6 1 3
+// Advance: 6
+//
+// +----+
+// | ** |
+// |** *|
+// |** *|
+// | ** |
+// | |
+// |****|
+// +----+
+static const byte glyph186[] = {
+ 0x60,
+ 0xD0,
+ 0xD0,
+ 0x60,
+ 0x00,
+ 0xF0
+};
+
+// Character 187 (0xBB)
+// Box: 6 5 1 1
+// Advance: 8
+//
+// +------+
+// |* * |
+// |** ** |
+// | ** **|
+// |** ** |
+// |* * |
+// +------+
+static const byte glyph187[] = {
+ 0x90,
+ 0xD8,
+ 0x6C,
+ 0xD8,
+ 0x90
+};
+
+// Character 188 (0xBC)
+// Box: 10 9 0 0
+// Advance: 10
+//
+// +----------+
+// | ** ** |
+// |*** ** |
+// | ** ** |
+// | ** ** |
+// | ** ** ** |
+// | * *** |
+// | ** * * |
+// | ** *****|
+// | ** ** |
+// +----------+
+static const byte glyph188[] = {
+ 0x63, 0x00,
+ 0xE6, 0x00,
+ 0x66, 0x00,
+ 0x6C, 0x00,
+ 0x6D, 0x80,
+ 0x0B, 0x80,
+ 0x1A, 0x80,
+ 0x37, 0xC0,
+ 0x31, 0x80
+};
+
+// Character 189 (0xBD)
+// Box: 10 9 0 0
+// Advance: 10
+//
+// +----------+
+// | ** ** |
+// |*** ** |
+// | ** ** |
+// | ** ** |
+// | ** ** ** |
+// | * * **|
+// | ** ** |
+// | ** ** |
+// | ** ****|
+// +----------+
+static const byte glyph189[] = {
+ 0x63, 0x00,
+ 0xE6, 0x00,
+ 0x66, 0x00,
+ 0x6C, 0x00,
+ 0x6D, 0x80,
+ 0x0A, 0xC0,
+ 0x19, 0x80,
+ 0x33, 0x00,
+ 0x33, 0xC0
+};
+
+// Character 190 (0xBE)
+// Box: 10 9 0 0
+// Advance: 10
+//
+// +----------+
+// | ** ** |
+// |* ** ** |
+// | ** ** |
+// | ** ** |
+// |*** ** ** |
+// | * *** |
+// | ** * * |
+// | ** *****|
+// | ** ** |
+// +----------+
+static const byte glyph190[] = {
+ 0x63, 0x00,
+ 0xB3, 0x00,
+ 0x66, 0x00,
+ 0x36, 0x00,
+ 0xED, 0x80,
+ 0x0B, 0x80,
+ 0x1A, 0x80,
+ 0x37, 0xC0,
+ 0x31, 0x80
+};
+
+// Character 191 (0xBF)
+// Box: 6 10 1 -3
+// Advance: 8
+//
+// +------+
+// | ** |
+// | ** |
+// | |
+// | ** |
+// | ** |
+// | ** |
+// | ** |
+// |** **|
+// |** **|
+// | **** |
+// +------+
+static const byte glyph191[] = {
+ 0x30,
+ 0x30,
+ 0x00,
+ 0x30,
+ 0x30,
+ 0x30,
+ 0x60,
+ 0xCC,
+ 0xCC,
+ 0x78
+};
+
+// Character 192 (0xC0)
+// Box: 8 12 0 0
+// Advance: 8
+//
+// +--------+
+// | ** |
+// | ** |
+// | |
+// | ** |
+// | ** |
+// | **** |
+// | * * |
+// | ** ** |
+// | ****** |
+// |** **|
+// |** **|
+// |** **|
+// +--------+
+static const byte glyph192[] = {
+ 0x30,
+ 0x18,
+ 0x00,
+ 0x18,
+ 0x18,
+ 0x3C,
+ 0x24,
+ 0x66,
+ 0x7E,
+ 0xC3,
+ 0xC3,
+ 0xC3
+};
+
+// Character 193 (0xC1)
+// Box: 8 12 0 0
+// Advance: 8
+//
+// +--------+
+// | ** |
+// | ** |
+// | |
+// | ** |
+// | ** |
+// | **** |
+// | * * |
+// | ** ** |
+// | ****** |
+// |** **|
+// |** **|
+// |** **|
+// +--------+
+static const byte glyph193[] = {
+ 0x0C,
+ 0x18,
+ 0x00,
+ 0x18,
+ 0x18,
+ 0x3C,
+ 0x24,
+ 0x66,
+ 0x7E,
+ 0xC3,
+ 0xC3,
+ 0xC3
+};
+
+// Character 194 (0xC2)
+// Box: 8 12 0 0
+// Advance: 8
+//
+// +--------+
+// | *** |
+// | ** ** |
+// | |
+// | ** |
+// | ** |
+// | **** |
+// | * * |
+// | ** ** |
+// | ****** |
+// |** **|
+// |** **|
+// |** **|
+// +--------+
+static const byte glyph194[] = {
+ 0x1C,
+ 0x36,
+ 0x00,
+ 0x18,
+ 0x18,
+ 0x3C,
+ 0x24,
+ 0x66,
+ 0x7E,
+ 0xC3,
+ 0xC3,
+ 0xC3
+};
+
+// Character 195 (0xC3)
+// Box: 8 12 0 0
+// Advance: 8
+//
+// +--------+
+// | ** * |
+// | * ** |
+// | |
+// | ** |
+// | ** |
+// | **** |
+// | * * |
+// | ** ** |
+// | ****** |
+// |** **|
+// |** **|
+// |** **|
+// +--------+
+static const byte glyph195[] = {
+ 0x1A,
+ 0x2C,
+ 0x00,
+ 0x18,
+ 0x18,
+ 0x3C,
+ 0x24,
+ 0x66,
+ 0x7E,
+ 0xC3,
+ 0xC3,
+ 0xC3
+};
+
+// Character 196 (0xC4)
+// Box: 8 11 0 0
+// Advance: 8
+//
+// +--------+
+// | ** ** |
+// | |
+// | ** |
+// | ** |
+// | **** |
+// | * * |
+// | ** ** |
+// | ****** |
+// |** **|
+// |** **|
+// |** **|
+// +--------+
+static const byte glyph196[] = {
+ 0x36,
+ 0x00,
+ 0x18,
+ 0x18,
+ 0x3C,
+ 0x24,
+ 0x66,
+ 0x7E,
+ 0xC3,
+ 0xC3,
+ 0xC3
+};
+
+// Character 197 (0xC5)
+// Box: 8 12 0 0
+// Advance: 8
+//
+// +--------+
+// | ** |
+// | * * |
+// | ** |
+// | ** |
+// | ** |
+// | **** |
+// | * * |
+// | ** ** |
+// | ****** |
+// |** **|
+// |** **|
+// |** **|
+// +--------+
+static const byte glyph197[] = {
+ 0x18,
+ 0x24,
+ 0x18,
+ 0x18,
+ 0x18,
+ 0x3C,
+ 0x24,
+ 0x66,
+ 0x7E,
+ 0xC3,
+ 0xC3,
+ 0xC3
+};
+
+// Character 198 (0xC6)
+// Box: 11 9 1 0
+// Advance: 13
+//
+// +-----------+
+// | ********|
+// | ** ** |
+// | * ** |
+// | ** ** |
+// | ** ******|
+// | ****** |
+// |** ** |
+// |** ** |
+// |** ******|
+// +-----------+
+static const byte glyph198[] = {
+ 0x1F, 0xE0,
+ 0x36, 0x00,
+ 0x26, 0x00,
+ 0x66, 0x00,
+ 0x67, 0xE0,
+ 0x7E, 0x00,
+ 0xC6, 0x00,
+ 0xC6, 0x00,
+ 0xC7, 0xE0
+};
+
+// Character 199 (0xC7)
+// Box: 7 12 1 -3
+// Advance: 8
+//
+// +-------+
+// | **** |
+// | ** **|
+// |** |
+// |** |
+// |** |
+// |** |
+// |** |
+// | ** **|
+// | **** |
+// | ** |
+// | ** |
+// | *** |
+// +-------+
+static const byte glyph199[] = {
+ 0x3C,
+ 0x66,
+ 0xC0,
+ 0xC0,
+ 0xC0,
+ 0xC0,
+ 0xC0,
+ 0x66,
+ 0x3C,
+ 0x18,
+ 0x18,
+ 0x70
+};
+
+// Character 200 (0xC8)
+// Box: 6 12 1 0
+// Advance: 8
+//
+// +------+
+// | ** |
+// | ** |
+// | |
+// |******|
+// |** |
+// |** |
+// |** |
+// |******|
+// |** |
+// |** |
+// |** |
+// |******|
+// +------+
+static const byte glyph200[] = {
+ 0x60,
+ 0x30,
+ 0x00,
+ 0xFC,
+ 0xC0,
+ 0xC0,
+ 0xC0,
+ 0xFC,
+ 0xC0,
+ 0xC0,
+ 0xC0,
+ 0xFC
+};
+
+// Character 201 (0xC9)
+// Box: 6 12 1 0
+// Advance: 8
+//
+// +------+
+// | ** |
+// | ** |
+// | |
+// |******|
+// |** |
+// |** |
+// |** |
+// |******|
+// |** |
+// |** |
+// |** |
+// |******|
+// +------+
+static const byte glyph201[] = {
+ 0x18,
+ 0x30,
+ 0x00,
+ 0xFC,
+ 0xC0,
+ 0xC0,
+ 0xC0,
+ 0xFC,
+ 0xC0,
+ 0xC0,
+ 0xC0,
+ 0xFC
+};
+
+// Character 202 (0xCA)
+// Box: 6 12 1 0
+// Advance: 8
+//
+// +------+
+// | *** |
+// | ** **|
+// | |
+// |******|
+// |** |
+// |** |
+// |** |
+// |******|
+// |** |
+// |** |
+// |** |
+// |******|
+// +------+
+static const byte glyph202[] = {
+ 0x38,
+ 0x6C,
+ 0x00,
+ 0xFC,
+ 0xC0,
+ 0xC0,
+ 0xC0,
+ 0xFC,
+ 0xC0,
+ 0xC0,
+ 0xC0,
+ 0xFC
+};
+
+// Character 203 (0xCB)
+// Box: 6 11 1 0
+// Advance: 8
+//
+// +------+
+// | ** **|
+// | |
+// |******|
+// |** |
+// |** |
+// |** |
+// |******|
+// |** |
+// |** |
+// |** |
+// |******|
+// +------+
+static const byte glyph203[] = {
+ 0x6C,
+ 0x00,
+ 0xFC,
+ 0xC0,
+ 0xC0,
+ 0xC0,
+ 0xFC,
+ 0xC0,
+ 0xC0,
+ 0xC0,
+ 0xFC
+};
+
+// Character 204 (0xCC)
+// Box: 3 12 0 0
+// Advance: 4
+//
+// +---+
+// |** |
+// | **|
+// | |
+// | **|
+// | **|
+// | **|
+// | **|
+// | **|
+// | **|
+// | **|
+// | **|
+// | **|
+// +---+
+static const byte glyph204[] = {
+ 0xC0,
+ 0x60,
+ 0x00,
+ 0x60,
+ 0x60,
+ 0x60,
+ 0x60,
+ 0x60,
+ 0x60,
+ 0x60,
+ 0x60,
+ 0x60
+};
+
+// Character 205 (0xCD)
+// Box: 3 12 1 0
+// Advance: 4
+//
+// +---+
+// | **|
+// |** |
+// | |
+// |** |
+// |** |
+// |** |
+// |** |
+// |** |
+// |** |
+// |** |
+// |** |
+// |** |
+// +---+
+static const byte glyph205[] = {
+ 0x60,
+ 0xC0,
+ 0x00,
+ 0xC0,
+ 0xC0,
+ 0xC0,
+ 0xC0,
+ 0xC0,
+ 0xC0,
+ 0xC0,
+ 0xC0,
+ 0xC0
+};
+
+// Character 206 (0xCE)
+// Box: 5 12 0 0
+// Advance: 4
+//
+// +-----+
+// | *** |
+// |** **|
+// | |
+// | ** |
+// | ** |
+// | ** |
+// | ** |
+// | ** |
+// | ** |
+// | ** |
+// | ** |
+// | ** |
+// +-----+
+static const byte glyph206[] = {
+ 0x70,
+ 0xD8,
+ 0x00,
+ 0x60,
+ 0x60,
+ 0x60,
+ 0x60,
+ 0x60,
+ 0x60,
+ 0x60,
+ 0x60,
+ 0x60
+};
+
+// Character 207 (0xCF)
+// Box: 5 11 0 0
+// Advance: 4
+//
+// +-----+
+// |** **|
+// | |
+// | ** |
+// | ** |
+// | ** |
+// | ** |
+// | ** |
+// | ** |
+// | ** |
+// | ** |
+// | ** |
+// +-----+
+static const byte glyph207[] = {
+ 0xD8,
+ 0x00,
+ 0x60,
+ 0x60,
+ 0x60,
+ 0x60,
+ 0x60,
+ 0x60,
+ 0x60,
+ 0x60,
+ 0x60
+};
+
+// Character 208 (0xD0)
+// Box: 8 9 0 0
+// Advance: 9
+//
+// +--------+
+// | ***** |
+// | ** ** |
+// | ** **|
+// | ** **|
+// |**** **|
+// | ** **|
+// | ** **|
+// | ** ** |
+// | ***** |
+// +--------+
+static const byte glyph208[] = {
+ 0x7C,
+ 0x66,
+ 0x63,
+ 0x63,
+ 0xF3,
+ 0x63,
+ 0x63,
+ 0x66,
+ 0x7C
+};
+
+// Character 209 (0xD1)
+// Box: 7 12 1 0
+// Advance: 9
+//
+// +-------+
+// | ** * |
+// | * ** |
+// | |
+// |** **|
+// |** **|
+// |*** **|
+// |*** **|
+// |**** **|
+// |** ***|
+// |** ***|
+// |** **|
+// |** **|
+// +-------+
+static const byte glyph209[] = {
+ 0x34,
+ 0x58,
+ 0x00,
+ 0xC6,
+ 0xC6,
+ 0xE6,
+ 0xE6,
+ 0xF6,
+ 0xCE,
+ 0xCE,
+ 0xC6,
+ 0xC6
+};
+
+// Character 210 (0xD2)
+// Box: 8 12 1 0
+// Advance: 10
+//
+// +--------+
+// | ** |
+// | ** |
+// | |
+// | **** |
+// | ** ** |
+// |** **|
+// |** **|
+// |** **|
+// |** **|
+// |** **|
+// | ** ** |
+// | **** |
+// +--------+
+static const byte glyph210[] = {
+ 0x30,
+ 0x18,
+ 0x00,
+ 0x3C,
+ 0x66,
+ 0xC3,
+ 0xC3,
+ 0xC3,
+ 0xC3,
+ 0xC3,
+ 0x66,
+ 0x3C
+};
+
+// Character 211 (0xD3)
+// Box: 8 12 1 0
+// Advance: 10
+//
+// +--------+
+// | ** |
+// | ** |
+// | |
+// | **** |
+// | ** ** |
+// |** **|
+// |** **|
+// |** **|
+// |** **|
+// |** **|
+// | ** ** |
+// | **** |
+// +--------+
+static const byte glyph211[] = {
+ 0x0C,
+ 0x18,
+ 0x00,
+ 0x3C,
+ 0x66,
+ 0xC3,
+ 0xC3,
+ 0xC3,
+ 0xC3,
+ 0xC3,
+ 0x66,
+ 0x3C
+};
+
+// Character 212 (0xD4)
+// Box: 8 12 1 0
+// Advance: 10
+//
+// +--------+
+// | *** |
+// | ** ** |
+// | |
+// | **** |
+// | ** ** |
+// |** **|
+// |** **|
+// |** **|
+// |** **|
+// |** **|
+// | ** ** |
+// | **** |
+// +--------+
+static const byte glyph212[] = {
+ 0x1C,
+ 0x36,
+ 0x00,
+ 0x3C,
+ 0x66,
+ 0xC3,
+ 0xC3,
+ 0xC3,
+ 0xC3,
+ 0xC3,
+ 0x66,
+ 0x3C
+};
+
+// Character 213 (0xD5)
+// Box: 8 12 1 0
+// Advance: 10
+//
+// +--------+
+// | ** * |
+// | * ** |
+// | |
+// | **** |
+// | ** ** |
+// |** **|
+// |** **|
+// |** **|
+// |** **|
+// |** **|
+// | ** ** |
+// | **** |
+// +--------+
+static const byte glyph213[] = {
+ 0x1A,
+ 0x2C,
+ 0x00,
+ 0x3C,
+ 0x66,
+ 0xC3,
+ 0xC3,
+ 0xC3,
+ 0xC3,
+ 0xC3,
+ 0x66,
+ 0x3C
+};
+
+// Character 214 (0xD6)
+// Box: 8 11 1 0
+// Advance: 10
+//
+// +--------+
+// | ** ** |
+// | |
+// | **** |
+// | ** ** |
+// |** **|
+// |** **|
+// |** **|
+// |** **|
+// |** **|
+// | ** ** |
+// | **** |
+// +--------+
+static const byte glyph214[] = {
+ 0x66,
+ 0x00,
+ 0x3C,
+ 0x66,
+ 0xC3,
+ 0xC3,
+ 0xC3,
+ 0xC3,
+ 0xC3,
+ 0x66,
+ 0x3C
+};
+
+// Character 215 (0xD7)
+// Box: 6 5 0 1
+// Advance: 7
+//
+// +------+
+// |** **|
+// | **** |
+// | ** |
+// | **** |
+// |** **|
+// +------+
+static const byte glyph215[] = {
+ 0xCC,
+ 0x78,
+ 0x30,
+ 0x78,
+ 0xCC
+};
+
+// Character 216 (0xD8)
+// Box: 8 10 1 -1
+// Advance: 10
+//
+// +--------+
+// | **** *|
+// | ** ** |
+// |** ****|
+// |** * **|
+// |** ** **|
+// |** * **|
+// |**** **|
+// | ** ** |
+// | ***** |
+// |* |
+// +--------+
+static const byte glyph216[] = {
+ 0x3D,
+ 0x66,
+ 0xCF,
+ 0xCB,
+ 0xDB,
+ 0xD3,
+ 0xF3,
+ 0x66,
+ 0x7C,
+ 0x80
+};
+
+// Character 217 (0xD9)
+// Box: 7 12 1 0
+// Advance: 9
+//
+// +-------+
+// | ** |
+// | ** |
+// | |
+// |** **|
+// |** **|
+// |** **|
+// |** **|
+// |** **|
+// |** **|
+// |** **|
+// | ** ** |
+// | ***** |
+// +-------+
+static const byte glyph217[] = {
+ 0x30,
+ 0x18,
+ 0x00,
+ 0xC6,
+ 0xC6,
+ 0xC6,
+ 0xC6,
+ 0xC6,
+ 0xC6,
+ 0xC6,
+ 0x6C,
+ 0x7C
+};
+
+// Character 218 (0xDA)
+// Box: 7 12 1 0
+// Advance: 9
+//
+// +-------+
+// | ** |
+// | ** |
+// | |
+// |** **|
+// |** **|
+// |** **|
+// |** **|
+// |** **|
+// |** **|
+// |** **|
+// | ** ** |
+// | ***** |
+// +-------+
+static const byte glyph218[] = {
+ 0x0C,
+ 0x18,
+ 0x00,
+ 0xC6,
+ 0xC6,
+ 0xC6,
+ 0xC6,
+ 0xC6,
+ 0xC6,
+ 0xC6,
+ 0x6C,
+ 0x7C
+};
+
+// Character 219 (0xDB)
+// Box: 7 12 1 0
+// Advance: 9
+//
+// +-------+
+// | *** |
+// | ** ** |
+// | |
+// |** **|
+// |** **|
+// |** **|
+// |** **|
+// |** **|
+// |** **|
+// |** **|
+// | ** ** |
+// | ***** |
+// +-------+
+static const byte glyph219[] = {
+ 0x38,
+ 0x6C,
+ 0x00,
+ 0xC6,
+ 0xC6,
+ 0xC6,
+ 0xC6,
+ 0xC6,
+ 0xC6,
+ 0xC6,
+ 0x6C,
+ 0x7C
+};
+
+// Character 220 (0xDC)
+// Box: 7 11 1 0
+// Advance: 9
+//
+// +-------+
+// | ** ** |
+// | |
+// |** **|
+// |** **|
+// |** **|
+// |** **|
+// |** **|
+// |** **|
+// |** **|
+// | ** ** |
+// | ***** |
+// +-------+
+static const byte glyph220[] = {
+ 0x6C,
+ 0x00,
+ 0xC6,
+ 0xC6,
+ 0xC6,
+ 0xC6,
+ 0xC6,
+ 0xC6,
+ 0xC6,
+ 0x6C,
+ 0x7C
+};
+
+// Character 221 (0xDD)
+// Box: 8 12 0 0
+// Advance: 8
+//
+// +--------+
+// | ** |
+// | ** |
+// | |
+// |** **|
+// |** **|
+// | ** ** |
+// | ** ** |
+// | * * |
+// | **** |
+// | ** |
+// | ** |
+// | ** |
+// +--------+
+static const byte glyph221[] = {
+ 0x0C,
+ 0x18,
+ 0x00,
+ 0xC3,
+ 0xC3,
+ 0x66,
+ 0x66,
+ 0x24,
+ 0x3C,
+ 0x18,
+ 0x18,
+ 0x18
+};
+
+// Character 222 (0xDE)
+// Box: 7 9 1 0
+// Advance: 8
+//
+// +-------+
+// |** |
+// |** |
+// |****** |
+// |** **|
+// |** **|
+// |** **|
+// |****** |
+// |** |
+// |** |
+// +-------+
+static const byte glyph222[] = {
+ 0xC0,
+ 0xC0,
+ 0xFC,
+ 0xC6,
+ 0xC6,
+ 0xC6,
+ 0xFC,
+ 0xC0,
+ 0xC0
+};
+
+// Character 223 (0xDF)
+// Box: 6 9 1 0
+// Advance: 8
+//
+// +------+
+// | **** |
+// |** **|
+// |** **|
+// |** **|
+// |** ** |
+// |** **|
+// |** **|
+// |** **|
+// |** ** |
+// +------+
+static const byte glyph223[] = {
+ 0x78,
+ 0xCC,
+ 0xCC,
+ 0xCC,
+ 0xD8,
+ 0xCC,
+ 0xCC,
+ 0xCC,
+ 0xD8
+};
+
+// Character 224 (0xE0)
+// Box: 7 10 0 0
+// Advance: 7
+//
+// +-------+
+// | ** |
+// | ** |
+// | |
+// | **** |
+// |** ** |
+// | ** |
+// | ***** |
+// |** ** |
+// |** ** |
+// | *** **|
+// +-------+
+static const byte glyph224[] = {
+ 0x30,
+ 0x18,
+ 0x00,
+ 0x78,
+ 0xCC,
+ 0x0C,
+ 0x7C,
+ 0xCC,
+ 0xCC,
+ 0x76
+};
+
+// Character 225 (0xE1)
+// Box: 7 10 0 0
+// Advance: 7
+//
+// +-------+
+// | ** |
+// | ** |
+// | |
+// | **** |
+// |** ** |
+// | ** |
+// | ***** |
+// |** ** |
+// |** ** |
+// | *** **|
+// +-------+
+static const byte glyph225[] = {
+ 0x18,
+ 0x30,
+ 0x00,
+ 0x78,
+ 0xCC,
+ 0x0C,
+ 0x7C,
+ 0xCC,
+ 0xCC,
+ 0x76
+};
+
+// Character 226 (0xE2)
+// Box: 7 10 0 0
+// Advance: 7
+//
+// +-------+
+// | *** |
+// | ** ** |
+// | |
+// | **** |
+// |** ** |
+// | ** |
+// | ***** |
+// |** ** |
+// |** ** |
+// | *** **|
+// +-------+
+static const byte glyph226[] = {
+ 0x38,
+ 0x6C,
+ 0x00,
+ 0x78,
+ 0xCC,
+ 0x0C,
+ 0x7C,
+ 0xCC,
+ 0xCC,
+ 0x76
+};
+
+// Character 227 (0xE3)
+// Box: 7 10 0 0
+// Advance: 7
+//
+// +-------+
+// | ** * |
+// | * ** |
+// | |
+// | **** |
+// |** ** |
+// | ** |
+// | ***** |
+// |** ** |
+// |** ** |
+// | *** **|
+// +-------+
+static const byte glyph227[] = {
+ 0x34,
+ 0x58,
+ 0x00,
+ 0x78,
+ 0xCC,
+ 0x0C,
+ 0x7C,
+ 0xCC,
+ 0xCC,
+ 0x76
+};
+
+// Character 228 (0xE4)
+// Box: 7 9 0 0
+// Advance: 7
+//
+// +-------+
+// | ** ** |
+// | |
+// | **** |
+// |** ** |
+// | ** |
+// | ***** |
+// |** ** |
+// |** ** |
+// | *** **|
+// +-------+
+static const byte glyph228[] = {
+ 0x6C,
+ 0x00,
+ 0x78,
+ 0xCC,
+ 0x0C,
+ 0x7C,
+ 0xCC,
+ 0xCC,
+ 0x76
+};
+
+// Character 229 (0xE5)
+// Box: 7 11 0 0
+// Advance: 7
+//
+// +-------+
+// | ** |
+// | * * |
+// | ** |
+// | |
+// | **** |
+// |** ** |
+// | ** |
+// | ***** |
+// |** ** |
+// |** ** |
+// | *** **|
+// +-------+
+static const byte glyph229[] = {
+ 0x30,
+ 0x48,
+ 0x30,
+ 0x00,
+ 0x78,
+ 0xCC,
+ 0x0C,
+ 0x7C,
+ 0xCC,
+ 0xCC,
+ 0x76
+};
+
+// Character 230 (0xE6)
+// Box: 10 7 0 0
+// Advance: 11
+//
+// +----------+
+// | *** **** |
+// |** ** **|
+// | ** **|
+// | *********|
+// |** ** |
+// |** ** **|
+// | *** **** |
+// +----------+
+static const byte glyph230[] = {
+ 0x77, 0x80,
+ 0xCC, 0xC0,
+ 0x0C, 0xC0,
+ 0x7F, 0xC0,
+ 0xCC, 0x00,
+ 0xCC, 0xC0,
+ 0x77, 0x80
+};
+
+// Character 231 (0xE7)
+// Box: 6 10 0 -3
+// Advance: 7
+//
+// +------+
+// | **** |
+// |** **|
+// |** |
+// |** |
+// |** |
+// |** **|
+// | **** |
+// | * |
+// | ** |
+// | *** |
+// +------+
+static const byte glyph231[] = {
+ 0x78,
+ 0xCC,
+ 0xC0,
+ 0xC0,
+ 0xC0,
+ 0xCC,
+ 0x78,
+ 0x10,
+ 0x18,
+ 0x70
+};
+
+// Character 232 (0xE8)
+// Box: 6 10 0 0
+// Advance: 7
+//
+// +------+
+// | ** |
+// | ** |
+// | |
+// | **** |
+// |** **|
+// |** **|
+// |******|
+// |** |
+// |** **|
+// | **** |
+// +------+
+static const byte glyph232[] = {
+ 0x60,
+ 0x30,
+ 0x00,
+ 0x78,
+ 0xCC,
+ 0xCC,
+ 0xFC,
+ 0xC0,
+ 0xCC,
+ 0x78
+};
+
+// Character 233 (0xE9)
+// Box: 6 10 0 0
+// Advance: 7
+//
+// +------+
+// | ** |
+// | ** |
+// | |
+// | **** |
+// |** **|
+// |** **|
+// |******|
+// |** |
+// |** **|
+// | **** |
+// +------+
+static const byte glyph233[] = {
+ 0x18,
+ 0x30,
+ 0x00,
+ 0x78,
+ 0xCC,
+ 0xCC,
+ 0xFC,
+ 0xC0,
+ 0xCC,
+ 0x78
+};
+
+// Character 234 (0xEA)
+// Box: 6 10 0 0
+// Advance: 7
+//
+// +------+
+// | *** |
+// | ** **|
+// | |
+// | **** |
+// |** **|
+// |** **|
+// |******|
+// |** |
+// |** **|
+// | **** |
+// +------+
+static const byte glyph234[] = {
+ 0x38,
+ 0x6C,
+ 0x00,
+ 0x78,
+ 0xCC,
+ 0xCC,
+ 0xFC,
+ 0xC0,
+ 0xCC,
+ 0x78
+};
+
+// Character 235 (0xEB)
+// Box: 6 9 0 0
+// Advance: 7
+//
+// +------+
+// | ** **|
+// | |
+// | **** |
+// |** **|
+// |** **|
+// |******|
+// |** |
+// |** **|
+// | **** |
+// +------+
+static const byte glyph235[] = {
+ 0x6C,
+ 0x00,
+ 0x78,
+ 0xCC,
+ 0xCC,
+ 0xFC,
+ 0xC0,
+ 0xCC,
+ 0x78
+};
+
+// Character 236 (0xEC)
+// Box: 3 10 -1 0
+// Advance: 3
+//
+// +---+
+// |** |
+// | **|
+// | |
+// | **|
+// | **|
+// | **|
+// | **|
+// | **|
+// | **|
+// | **|
+// +---+
+static const byte glyph236[] = {
+ 0xC0,
+ 0x60,
+ 0x00,
+ 0x60,
+ 0x60,
+ 0x60,
+ 0x60,
+ 0x60,
+ 0x60,
+ 0x60
+};
+
+// Character 237 (0xED)
+// Box: 3 10 0 0
+// Advance: 3
+//
+// +---+
+// | **|
+// |** |
+// | |
+// |** |
+// |** |
+// |** |
+// |** |
+// |** |
+// |** |
+// |** |
+// +---+
+static const byte glyph237[] = {
+ 0x60,
+ 0xC0,
+ 0x00,
+ 0xC0,
+ 0xC0,
+ 0xC0,
+ 0xC0,
+ 0xC0,
+ 0xC0,
+ 0xC0
+};
+
+// Character 238 (0xEE)
+// Box: 5 10 -1 0
+// Advance: 3
+//
+// +-----+
+// | *** |
+// |** **|
+// | |
+// | ** |
+// | ** |
+// | ** |
+// | ** |
+// | ** |
+// | ** |
+// | ** |
+// +-----+
+static const byte glyph238[] = {
+ 0x70,
+ 0xD8,
+ 0x00,
+ 0x60,
+ 0x60,
+ 0x60,
+ 0x60,
+ 0x60,
+ 0x60,
+ 0x60
+};
+
+// Character 239 (0xEF)
+// Box: 5 9 -1 0
+// Advance: 3
+//
+// +-----+
+// |** **|
+// | |
+// | ** |
+// | ** |
+// | ** |
+// | ** |
+// | ** |
+// | ** |
+// | ** |
+// +-----+
+static const byte glyph239[] = {
+ 0xD8,
+ 0x00,
+ 0x60,
+ 0x60,
+ 0x60,
+ 0x60,
+ 0x60,
+ 0x60,
+ 0x60
+};
+
+// Character 240 (0xF0)
+// Box: 6 10 0 0
+// Advance: 7
+//
+// +------+
+// |** ** |
+// | *** |
+// |* * |
+// | ** |
+// | *****|
+// |** **|
+// |** **|
+// |** **|
+// |** **|
+// | **** |
+// +------+
+static const byte glyph240[] = {
+ 0xD8,
+ 0x70,
+ 0x90,
+ 0x18,
+ 0x7C,
+ 0xCC,
+ 0xCC,
+ 0xCC,
+ 0xCC,
+ 0x78
+};
+
+// Character 241 (0xF1)
+// Box: 6 10 0 0
+// Advance: 7
+//
+// +------+
+// | ** *|
+// | * ** |
+// | |
+// |** ** |
+// |*** **|
+// |** **|
+// |** **|
+// |** **|
+// |** **|
+// |** **|
+// +------+
+static const byte glyph241[] = {
+ 0x34,
+ 0x58,
+ 0x00,
+ 0xD8,
+ 0xEC,
+ 0xCC,
+ 0xCC,
+ 0xCC,
+ 0xCC,
+ 0xCC
+};
+
+// Character 242 (0xF2)
+// Box: 6 10 0 0
+// Advance: 7
+//
+// +------+
+// | ** |
+// | ** |
+// | |
+// | **** |
+// |** **|
+// |** **|
+// |** **|
+// |** **|
+// |** **|
+// | **** |
+// +------+
+static const byte glyph242[] = {
+ 0x60,
+ 0x30,
+ 0x00,
+ 0x78,
+ 0xCC,
+ 0xCC,
+ 0xCC,
+ 0xCC,
+ 0xCC,
+ 0x78
+};
+
+// Character 243 (0xF3)
+// Box: 6 10 0 0
+// Advance: 7
+//
+// +------+
+// | ** |
+// | ** |
+// | |
+// | **** |
+// |** **|
+// |** **|
+// |** **|
+// |** **|
+// |** **|
+// | **** |
+// +------+
+static const byte glyph243[] = {
+ 0x18,
+ 0x30,
+ 0x00,
+ 0x78,
+ 0xCC,
+ 0xCC,
+ 0xCC,
+ 0xCC,
+ 0xCC,
+ 0x78
+};
+
+// Character 244 (0xF4)
+// Box: 6 10 0 0
+// Advance: 7
+//
+// +------+
+// | *** |
+// | ** **|
+// | |
+// | **** |
+// |** **|
+// |** **|
+// |** **|
+// |** **|
+// |** **|
+// | **** |
+// +------+
+static const byte glyph244[] = {
+ 0x38,
+ 0x6C,
+ 0x00,
+ 0x78,
+ 0xCC,
+ 0xCC,
+ 0xCC,
+ 0xCC,
+ 0xCC,
+ 0x78
+};
+
+// Character 245 (0xF5)
+// Box: 6 10 0 0
+// Advance: 7
+//
+// +------+
+// | ** *|
+// | * ** |
+// | |
+// | **** |
+// |** **|
+// |** **|
+// |** **|
+// |** **|
+// |** **|
+// | **** |
+// +------+
+static const byte glyph245[] = {
+ 0x34,
+ 0x58,
+ 0x00,
+ 0x78,
+ 0xCC,
+ 0xCC,
+ 0xCC,
+ 0xCC,
+ 0xCC,
+ 0x78
+};
+
+// Character 246 (0xF6)
+// Box: 6 9 0 0
+// Advance: 7
+//
+// +------+
+// | ** **|
+// | |
+// | **** |
+// |** **|
+// |** **|
+// |** **|
+// |** **|
+// |** **|
+// | **** |
+// +------+
+static const byte glyph246[] = {
+ 0x6C,
+ 0x00,
+ 0x78,
+ 0xCC,
+ 0xCC,
+ 0xCC,
+ 0xCC,
+ 0xCC,
+ 0x78
+};
+
+// Character 247 (0xF7)
+// Box: 6 5 0 1
+// Advance: 7
+//
+// +------+
+// | ** |
+// | |
+// |******|
+// | |
+// | ** |
+// +------+
+static const byte glyph247[] = {
+ 0x30,
+ 0x00,
+ 0xFC,
+ 0x00,
+ 0x30
+};
+
+// Character 248 (0xF8)
+// Box: 8 7 -1 0
+// Advance: 7
+//
+// +--------+
+// | **** *|
+// | ** ** |
+// | ** *** |
+// | *** ** |
+// | ** ** |
+// | ** ** |
+// |* **** |
+// +--------+
+static const byte glyph248[] = {
+ 0x3D,
+ 0x66,
+ 0x6E,
+ 0x76,
+ 0x66,
+ 0x66,
+ 0xBC
+};
+
+// Character 249 (0xF9)
+// Box: 6 10 0 0
+// Advance: 7
+//
+// +------+
+// | ** |
+// | ** |
+// | |
+// |** **|
+// |** **|
+// |** **|
+// |** **|
+// |** **|
+// |** ***|
+// | ** **|
+// +------+
+static const byte glyph249[] = {
+ 0x60,
+ 0x30,
+ 0x00,
+ 0xCC,
+ 0xCC,
+ 0xCC,
+ 0xCC,
+ 0xCC,
+ 0xDC,
+ 0x6C
+};
+
+// Character 250 (0xFA)
+// Box: 6 10 0 0
+// Advance: 7
+//
+// +------+
+// | ** |
+// | ** |
+// | |
+// |** **|
+// |** **|
+// |** **|
+// |** **|
+// |** **|
+// |** ***|
+// | ** **|
+// +------+
+static const byte glyph250[] = {
+ 0x18,
+ 0x30,
+ 0x00,
+ 0xCC,
+ 0xCC,
+ 0xCC,
+ 0xCC,
+ 0xCC,
+ 0xDC,
+ 0x6C
+};
+
+// Character 251 (0xFB)
+// Box: 6 10 0 0
+// Advance: 7
+//
+// +------+
+// | *** |
+// | ** **|
+// | |
+// |** **|
+// |** **|
+// |** **|
+// |** **|
+// |** **|
+// |** ***|
+// | ** **|
+// +------+
+static const byte glyph251[] = {
+ 0x38,
+ 0x6C,
+ 0x00,
+ 0xCC,
+ 0xCC,
+ 0xCC,
+ 0xCC,
+ 0xCC,
+ 0xDC,
+ 0x6C
+};
+
+// Character 252 (0xFC)
+// Box: 6 9 0 0
+// Advance: 7
+//
+// +------+
+// | ** **|
+// | |
+// |** **|
+// |** **|
+// |** **|
+// |** **|
+// |** **|
+// |** ***|
+// | ** **|
+// +------+
+static const byte glyph252[] = {
+ 0x6C,
+ 0x00,
+ 0xCC,
+ 0xCC,
+ 0xCC,
+ 0xCC,
+ 0xCC,
+ 0xDC,
+ 0x6C
+};
+
+// Character 253 (0xFD)
+// Box: 7 13 0 -3
+// Advance: 8
+//
+// +-------+
+// | ** |
+// | ** |
+// | |
+// |** **|
+// |** **|
+// | ** ** |
+// | ** ** |
+// | *** |
+// | *** |
+// | ** |
+// | * |
+// | ** |
+// | ** |
+// +-------+
+static const byte glyph253[] = {
+ 0x0C,
+ 0x18,
+ 0x00,
+ 0xC6,
+ 0xC6,
+ 0x6C,
+ 0x6C,
+ 0x38,
+ 0x38,
+ 0x18,
+ 0x10,
+ 0x30,
+ 0x60
+};
+
+// Character 254 (0xFE)
+// Box: 6 12 0 -3
+// Advance: 7
+//
+// +------+
+// |** |
+// |** |
+// |** ** |
+// |*** **|
+// |** **|
+// |** **|
+// |** **|
+// |*** **|
+// |** ** |
+// |** |
+// |** |
+// |** |
+// +------+
+static const byte glyph254[] = {
+ 0xC0,
+ 0xC0,
+ 0xD8,
+ 0xEC,
+ 0xCC,
+ 0xCC,
+ 0xCC,
+ 0xEC,
+ 0xD8,
+ 0xC0,
+ 0xC0,
+ 0xC0
+};
+
+// Character 255 (0xFF)
+// Box: 7 12 0 -3
+// Advance: 8
+//
+// +-------+
+// | ** ** |
+// | |
+// |** **|
+// |** **|
+// | ** ** |
+// | ** ** |
+// | *** |
+// | *** |
+// | ** |
+// | * |
+// | ** |
+// | ** |
+// +-------+
+static const byte glyph255[] = {
+ 0x6C,
+ 0x00,
+ 0xC6,
+ 0xC6,
+ 0x6C,
+ 0x6C,
+ 0x38,
+ 0x38,
+ 0x18,
+ 0x10,
+ 0x30,
+ 0x60
+};
+
+// Bitmap pointer table
+const byte *const bitmapTable[] = {
+ glyph0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ glyph32,
+ glyph33,
+ glyph34,
+ glyph35,
+ glyph36,
+ glyph37,
+ glyph38,
+ glyph39,
+ glyph40,
+ glyph41,
+ glyph42,
+ glyph43,
+ glyph44,
+ glyph45,
+ glyph46,
+ glyph47,
+ glyph48,
+ glyph49,
+ glyph50,
+ glyph51,
+ glyph52,
+ glyph53,
+ glyph54,
+ glyph55,
+ glyph56,
+ glyph57,
+ glyph58,
+ glyph59,
+ glyph60,
+ glyph61,
+ glyph62,
+ glyph63,
+ glyph64,
+ glyph65,
+ glyph66,
+ glyph67,
+ glyph68,
+ glyph69,
+ glyph70,
+ glyph71,
+ glyph72,
+ glyph73,
+ glyph74,
+ glyph75,
+ glyph76,
+ glyph77,
+ glyph78,
+ glyph79,
+ glyph80,
+ glyph81,
+ glyph82,
+ glyph83,
+ glyph84,
+ glyph85,
+ glyph86,
+ glyph87,
+ glyph88,
+ glyph89,
+ glyph90,
+ glyph91,
+ glyph92,
+ glyph93,
+ glyph94,
+ glyph95,
+ glyph96,
+ glyph97,
+ glyph98,
+ glyph99,
+ glyph100,
+ glyph101,
+ glyph102,
+ glyph103,
+ glyph104,
+ glyph105,
+ glyph106,
+ glyph107,
+ glyph108,
+ glyph109,
+ glyph110,
+ glyph111,
+ glyph112,
+ glyph113,
+ glyph114,
+ glyph115,
+ glyph116,
+ glyph117,
+ glyph118,
+ glyph119,
+ glyph120,
+ glyph121,
+ glyph122,
+ glyph123,
+ glyph124,
+ glyph125,
+ glyph126,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ glyph160,
+ glyph161,
+ glyph162,
+ glyph163,
+ glyph164,
+ glyph165,
+ glyph166,
+ glyph167,
+ glyph168,
+ glyph169,
+ glyph170,
+ glyph171,
+ glyph172,
+ glyph173,
+ glyph174,
+ glyph175,
+ glyph176,
+ glyph177,
+ glyph178,
+ glyph179,
+ glyph180,
+ glyph181,
+ glyph182,
+ glyph183,
+ glyph184,
+ glyph185,
+ glyph186,
+ glyph187,
+ glyph188,
+ glyph189,
+ glyph190,
+ glyph191,
+ glyph192,
+ glyph193,
+ glyph194,
+ glyph195,
+ glyph196,
+ glyph197,
+ glyph198,
+ glyph199,
+ glyph200,
+ glyph201,
+ glyph202,
+ glyph203,
+ glyph204,
+ glyph205,
+ glyph206,
+ glyph207,
+ glyph208,
+ glyph209,
+ glyph210,
+ glyph211,
+ glyph212,
+ glyph213,
+ glyph214,
+ glyph215,
+ glyph216,
+ glyph217,
+ glyph218,
+ glyph219,
+ glyph220,
+ glyph221,
+ glyph222,
+ glyph223,
+ glyph224,
+ glyph225,
+ glyph226,
+ glyph227,
+ glyph228,
+ glyph229,
+ glyph230,
+ glyph231,
+ glyph232,
+ glyph233,
+ glyph234,
+ glyph235,
+ glyph236,
+ glyph237,
+ glyph238,
+ glyph239,
+ glyph240,
+ glyph241,
+ glyph242,
+ glyph243,
+ glyph244,
+ glyph245,
+ glyph246,
+ glyph247,
+ glyph248,
+ glyph249,
+ glyph250,
+ glyph251,
+ glyph252,
+ glyph253,
+ glyph254,
+ glyph255
+};
+
+// Advance table
+static const byte advances[] = {
+ 9,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 4,
+ 4,
+ 5,
+ 8,
+ 7,
+ 12,
+ 9,
+ 3,
+ 6,
+ 6,
+ 6,
+ 7,
+ 4,
+ 5,
+ 4,
+ 4,
+ 7,
+ 7,
+ 7,
+ 7,
+ 7,
+ 7,
+ 7,
+ 7,
+ 7,
+ 7,
+ 4,
+ 4,
+ 7,
+ 7,
+ 7,
+ 8,
+ 12,
+ 8,
+ 9,
+ 8,
+ 9,
+ 8,
+ 7,
+ 10,
+ 9,
+ 4,
+ 7,
+ 9,
+ 7,
+ 11,
+ 9,
+ 10,
+ 8,
+ 10,
+ 9,
+ 9,
+ 8,
+ 9,
+ 8,
+ 10,
+ 8,
+ 8,
+ 7,
+ 4,
+ 4,
+ 4,
+ 7,
+ 7,
+ 4,
+ 7,
+ 7,
+ 7,
+ 7,
+ 7,
+ 5,
+ 7,
+ 7,
+ 3,
+ 3,
+ 7,
+ 3,
+ 11,
+ 7,
+ 7,
+ 7,
+ 7,
+ 5,
+ 7,
+ 5,
+ 7,
+ 8,
+ 11,
+ 7,
+ 8,
+ 6,
+ 5,
+ 4,
+ 5,
+ 7,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 4,
+ 4,
+ 7,
+ 7,
+ 7,
+ 7,
+ 4,
+ 7,
+ 5,
+ 11,
+ 6,
+ 8,
+ 8,
+ 5,
+ 11,
+ 4,
+ 5,
+ 7,
+ 4,
+ 4,
+ 4,
+ 7,
+ 7,
+ 4,
+ 4,
+ 4,
+ 6,
+ 8,
+ 10,
+ 10,
+ 10,
+ 8,
+ 8,
+ 8,
+ 8,
+ 8,
+ 8,
+ 8,
13,
- 14,
- 13, 15, -1, -3,
+ 8,
+ 8,
+ 8,
+ 8,
+ 8,
+ 4,
+ 4,
+ 4,
+ 4,
+ 9,
+ 9,
+ 10,
+ 10,
+ 10,
+ 10,
+ 10,
+ 7,
+ 10,
+ 9,
+ 9,
+ 9,
+ 9,
+ 8,
+ 8,
+ 8,
+ 7,
+ 7,
+ 7,
+ 7,
+ 7,
+ 7,
11,
- 32,
- 224,
- _font_bits,
- _sysfont_offset,
- _sysfont_width,
- _sysfont_bbx,
- 32,
- sizeof(_font_bits)/sizeof(bitmap_t)
+ 7,
+ 7,
+ 7,
+ 7,
+ 7,
+ 3,
+ 3,
+ 3,
+ 3,
+ 7,
+ 7,
+ 7,
+ 7,
+ 7,
+ 7,
+ 7,
+ 7,
+ 7,
+ 7,
+ 7,
+ 7,
+ 7,
+ 8,
+ 7,
+ 8
+};
+
+// Bounding box table
+static const BdfBoundingBox boxes[] = {
+ { 7, 9, 1, 0 },
+ { 0, 0, 0, 0 },
+ { 0, 0, 0, 0 },
+ { 0, 0, 0, 0 },
+ { 0, 0, 0, 0 },
+ { 0, 0, 0, 0 },
+ { 0, 0, 0, 0 },
+ { 0, 0, 0, 0 },
+ { 0, 0, 0, 0 },
+ { 0, 0, 0, 0 },
+ { 0, 0, 0, 0 },
+ { 0, 0, 0, 0 },
+ { 0, 0, 0, 0 },
+ { 0, 0, 0, 0 },
+ { 0, 0, 0, 0 },
+ { 0, 0, 0, 0 },
+ { 0, 0, 0, 0 },
+ { 0, 0, 0, 0 },
+ { 0, 0, 0, 0 },
+ { 0, 0, 0, 0 },
+ { 0, 0, 0, 0 },
+ { 0, 0, 0, 0 },
+ { 0, 0, 0, 0 },
+ { 0, 0, 0, 0 },
+ { 0, 0, 0, 0 },
+ { 0, 0, 0, 0 },
+ { 0, 0, 0, 0 },
+ { 0, 0, 0, 0 },
+ { 0, 0, 0, 0 },
+ { 0, 0, 0, 0 },
+ { 0, 0, 0, 0 },
+ { 0, 0, 0, 0 },
+ { 1, 1, 0, 0 },
+ { 2, 9, 1, 0 },
+ { 3, 3, 1, 6 },
+ { 7, 8, 0, 0 },
+ { 6, 11, 0, -2 },
+ { 11, 9, 0, 0 },
+ { 9, 9, 0, 0 },
+ { 1, 3, 1, 6 },
+ { 4, 12, 1, -3 },
+ { 4, 12, 1, -3 },
+ { 5, 4, 0, 5 },
+ { 6, 5, 0, 1 },
+ { 2, 4, 1, -2 },
+ { 4, 1, 0, 3 },
+ { 2, 2, 1, 0 },
+ { 4, 9, 0, 0 },
+ { 6, 9, 0, 0 },
+ { 4, 9, 0, 0 },
+ { 6, 9, 0, 0 },
+ { 6, 9, 0, 0 },
+ { 7, 9, 0, 0 },
+ { 6, 9, 0, 0 },
+ { 6, 9, 0, 0 },
+ { 6, 9, 0, 0 },
+ { 6, 9, 0, 0 },
+ { 6, 9, 0, 0 },
+ { 2, 7, 1, 0 },
+ { 2, 9, 1, -2 },
+ { 5, 5, 1, 1 },
+ { 6, 3, 0, 2 },
+ { 5, 5, 1, 1 },
+ { 6, 9, 1, 0 },
+ { 10, 10, 1, -1 },
+ { 8, 9, 0, 0 },
+ { 7, 9, 1, 0 },
+ { 7, 9, 1, 0 },
+ { 7, 9, 1, 0 },
+ { 6, 9, 1, 0 },
+ { 6, 9, 1, 0 },
+ { 8, 9, 1, 0 },
+ { 7, 9, 1, 0 },
+ { 2, 9, 1, 0 },
+ { 6, 9, 0, 0 },
+ { 8, 9, 1, 0 },
+ { 6, 9, 1, 0 },
+ { 9, 9, 1, 0 },
+ { 7, 9, 1, 0 },
+ { 8, 9, 1, 0 },
+ { 7, 9, 1, 0 },
+ { 8, 9, 1, 0 },
+ { 7, 9, 1, 0 },
+ { 7, 9, 1, 0 },
+ { 8, 9, 0, 0 },
+ { 7, 9, 1, 0 },
+ { 8, 9, 0, 0 },
+ { 10, 9, 0, 0 },
+ { 8, 9, 0, 0 },
+ { 8, 9, 0, 0 },
+ { 7, 9, 0, 0 },
+ { 3, 12, 1, -3 },
+ { 4, 9, 0, 0 },
+ { 3, 12, 0, -3 },
+ { 7, 4, 0, 5 },
+ { 7, 1, 0, -3 },
+ { 3, 2, 0, 8 },
+ { 7, 7, 0, 0 },
+ { 6, 9, 0, 0 },
+ { 6, 7, 0, 0 },
+ { 6, 9, 0, 0 },
+ { 6, 7, 0, 0 },
+ { 5, 9, 0, 0 },
+ { 6, 10, 0, -3 },
+ { 6, 9, 0, 0 },
+ { 2, 9, 0, 0 },
+ { 3, 12, -1, -3 },
+ { 7, 9, 0, 0 },
+ { 2, 9, 0, 0 },
+ { 10, 7, 0, 0 },
+ { 6, 7, 0, 0 },
+ { 6, 7, 0, 0 },
+ { 6, 10, 0, -3 },
+ { 6, 10, 0, -3 },
+ { 5, 7, 0, 0 },
+ { 6, 7, 0, 0 },
+ { 5, 9, 0, 0 },
+ { 6, 7, 0, 0 },
+ { 7, 7, 0, 0 },
+ { 10, 7, 0, 0 },
+ { 6, 7, 0, 0 },
+ { 7, 10, 0, -3 },
+ { 5, 7, 0, 0 },
+ { 4, 12, 0, -3 },
+ { 2, 12, 1, -3 },
+ { 4, 12, 0, -3 },
+ { 7, 2, 0, 3 },
+ { 0, 0, 0, 0 },
+ { 0, 0, 0, 0 },
+ { 0, 0, 0, 0 },
+ { 0, 0, 0, 0 },
+ { 0, 0, 0, 0 },
+ { 0, 0, 0, 0 },
+ { 0, 0, 0, 0 },
+ { 0, 0, 0, 0 },
+ { 0, 0, 0, 0 },
+ { 0, 0, 0, 0 },
+ { 0, 0, 0, 0 },
+ { 0, 0, 0, 0 },
+ { 0, 0, 0, 0 },
+ { 0, 0, 0, 0 },
+ { 0, 0, 0, 0 },
+ { 0, 0, 0, 0 },
+ { 0, 0, 0, 0 },
+ { 0, 0, 0, 0 },
+ { 0, 0, 0, 0 },
+ { 0, 0, 0, 0 },
+ { 0, 0, 0, 0 },
+ { 0, 0, 0, 0 },
+ { 0, 0, 0, 0 },
+ { 0, 0, 0, 0 },
+ { 0, 0, 0, 0 },
+ { 0, 0, 0, 0 },
+ { 0, 0, 0, 0 },
+ { 0, 0, 0, 0 },
+ { 0, 0, 0, 0 },
+ { 0, 0, 0, 0 },
+ { 0, 0, 0, 0 },
+ { 0, 0, 0, 0 },
+ { 0, 0, 0, 0 },
+ { 1, 1, 0, 0 },
+ { 2, 10, 1, -3 },
+ { 6, 9, 0, -1 },
+ { 6, 9, 0, 0 },
+ { 6, 6, 0, 1 },
+ { 6, 9, 0, 0 },
+ { 2, 11, 1, -2 },
+ { 6, 12, 0, -3 },
+ { 5, 1, 0, 8 },
+ { 9, 9, 1, 0 },
+ { 4, 6, 1, 3 },
+ { 6, 5, 1, 1 },
+ { 6, 4, 1, 2 },
+ { 4, 1, 0, 3 },
+ { 9, 9, 1, 0 },
+ { 4, 1, 0, 8 },
+ { 4, 4, 0, 4 },
+ { 6, 7, 0, 0 },
+ { 4, 5, 0, 4 },
+ { 4, 5, 0, 4 },
+ { 3, 2, 0, 8 },
+ { 6, 10, 0, -3 },
+ { 7, 12, 0, -3 },
+ { 2, 2, 1, 3 },
+ { 4, 4, 0, -3 },
+ { 3, 5, 0, 4 },
+ { 4, 6, 1, 3 },
+ { 6, 5, 1, 1 },
+ { 10, 9, 0, 0 },
+ { 10, 9, 0, 0 },
+ { 10, 9, 0, 0 },
+ { 6, 10, 1, -3 },
+ { 8, 12, 0, 0 },
+ { 8, 12, 0, 0 },
+ { 8, 12, 0, 0 },
+ { 8, 12, 0, 0 },
+ { 8, 11, 0, 0 },
+ { 8, 12, 0, 0 },
+ { 11, 9, 1, 0 },
+ { 7, 12, 1, -3 },
+ { 6, 12, 1, 0 },
+ { 6, 12, 1, 0 },
+ { 6, 12, 1, 0 },
+ { 6, 11, 1, 0 },
+ { 3, 12, 0, 0 },
+ { 3, 12, 1, 0 },
+ { 5, 12, 0, 0 },
+ { 5, 11, 0, 0 },
+ { 8, 9, 0, 0 },
+ { 7, 12, 1, 0 },
+ { 8, 12, 1, 0 },
+ { 8, 12, 1, 0 },
+ { 8, 12, 1, 0 },
+ { 8, 12, 1, 0 },
+ { 8, 11, 1, 0 },
+ { 6, 5, 0, 1 },
+ { 8, 10, 1, -1 },
+ { 7, 12, 1, 0 },
+ { 7, 12, 1, 0 },
+ { 7, 12, 1, 0 },
+ { 7, 11, 1, 0 },
+ { 8, 12, 0, 0 },
+ { 7, 9, 1, 0 },
+ { 6, 9, 1, 0 },
+ { 7, 10, 0, 0 },
+ { 7, 10, 0, 0 },
+ { 7, 10, 0, 0 },
+ { 7, 10, 0, 0 },
+ { 7, 9, 0, 0 },
+ { 7, 11, 0, 0 },
+ { 10, 7, 0, 0 },
+ { 6, 10, 0, -3 },
+ { 6, 10, 0, 0 },
+ { 6, 10, 0, 0 },
+ { 6, 10, 0, 0 },
+ { 6, 9, 0, 0 },
+ { 3, 10, -1, 0 },
+ { 3, 10, 0, 0 },
+ { 5, 10, -1, 0 },
+ { 5, 9, -1, 0 },
+ { 6, 10, 0, 0 },
+ { 6, 10, 0, 0 },
+ { 6, 10, 0, 0 },
+ { 6, 10, 0, 0 },
+ { 6, 10, 0, 0 },
+ { 6, 10, 0, 0 },
+ { 6, 9, 0, 0 },
+ { 6, 5, 0, 1 },
+ { 8, 7, -1, 0 },
+ { 6, 10, 0, 0 },
+ { 6, 10, 0, 0 },
+ { 6, 10, 0, 0 },
+ { 6, 9, 0, 0 },
+ { 7, 13, 0, -3 },
+ { 6, 12, 0, -3 },
+ { 7, 12, 0, -3 }
+};
+
+// Font structure
+static const BdfFontData desc = {
+ 13, // Max advance
+ 14, // Height
+ { 13, 15, -1, -3 }, // Bounding box
+ 11, // Ascent
+
+ 0, // First character
+ 0, // Default character
+ 256, // Characters
+
+ bitmapTable, // Bitmaps
+ advances, // Advances
+ boxes // Boxes
};
DEFINE_FONT(g_sysfont_big)
diff --git a/graphics/fonts/ttf.cpp b/graphics/fonts/ttf.cpp
new file mode 100644
index 0000000000..06231799ce
--- /dev/null
+++ b/graphics/fonts/ttf.cpp
@@ -0,0 +1,483 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+// Since FreeType2 includes files, which contain forbidden symbols, we need to
+// allow all symbols here.
+#define FORBIDDEN_SYMBOL_ALLOW_ALL
+
+#include "common/scummsys.h"
+#ifdef USE_FREETYPE2
+
+#include "graphics/fonts/ttf.h"
+#include "graphics/font.h"
+#include "graphics/surface.h"
+
+#include "common/singleton.h"
+#include "common/stream.h"
+#include "common/hashmap.h"
+
+#include <ft2build.h>
+#include FT_FREETYPE_H
+#include FT_GLYPH_H
+
+namespace Graphics {
+
+namespace {
+
+inline int ftFloor26_6(FT_Pos x) {
+ return x / 64;
+}
+
+inline int ftCeil26_6(FT_Pos x) {
+ return (x + 63) / 64;
+}
+
+} // End of anonymous namespace
+
+class TTFLibrary : public Common::Singleton<TTFLibrary> {
+public:
+ TTFLibrary();
+ ~TTFLibrary();
+
+ /**
+ * Check whether FreeType2 is initialized properly.
+ */
+ bool isInitialized() const { return _initialized; }
+
+ bool loadFont(const uint8 *file, const uint32 size, FT_Face &face);
+ void closeFont(FT_Face &face);
+private:
+ FT_Library _library;
+ bool _initialized;
+};
+
+#define g_ttf ::Graphics::TTFLibrary::instance()
+
+TTFLibrary::TTFLibrary() : _library(), _initialized(false) {
+ if (!FT_Init_FreeType(&_library))
+ _initialized = true;
+}
+
+TTFLibrary::~TTFLibrary() {
+ if (_initialized) {
+ FT_Done_FreeType(_library);
+ _initialized = false;
+ }
+}
+
+bool TTFLibrary::loadFont(const uint8 *file, const uint32 size, FT_Face &face) {
+ assert(_initialized);
+
+ return (FT_New_Memory_Face(_library, file, size, 0, &face) == 0);
+}
+
+void TTFLibrary::closeFont(FT_Face &face) {
+ assert(_initialized);
+
+ FT_Done_Face(face);
+}
+
+class TTFFont : public Font {
+public:
+ TTFFont();
+ virtual ~TTFFont();
+
+ bool load(Common::SeekableReadStream &stream, int size, bool monochrome, const uint32 *mapping);
+
+ virtual int getFontHeight() const;
+
+ virtual int getMaxCharWidth() const;
+
+ virtual int getCharWidth(byte chr) const;
+
+ virtual int getKerningOffset(byte left, byte right) const;
+
+ virtual void drawChar(Surface *dst, byte chr, int x, int y, uint32 color) const;
+private:
+ bool _initialized;
+ FT_Face _face;
+
+ uint8 *_ttfFile;
+ uint32 _size;
+
+ int _width, _height;
+ int _ascent, _descent;
+
+ struct Glyph {
+ Surface image;
+ int xOffset, yOffset;
+ int advance;
+ };
+
+ bool cacheGlyph(Glyph &glyph, FT_UInt &slot, uint chr);
+ typedef Common::HashMap<byte, Glyph> GlyphCache;
+ GlyphCache _glyphs;
+
+ FT_UInt _glyphSlots[256];
+
+ bool _monochrome;
+ bool _hasKerning;
+};
+
+TTFFont::TTFFont()
+ : _initialized(false), _face(), _ttfFile(0), _size(0), _width(0), _height(0), _ascent(0),
+ _descent(0), _glyphs(), _glyphSlots(), _monochrome(false), _hasKerning(false) {
+}
+
+TTFFont::~TTFFont() {
+ if (_initialized) {
+ g_ttf.closeFont(_face);
+
+ delete[] _ttfFile;
+ _ttfFile = 0;
+
+ for (GlyphCache::iterator i = _glyphs.begin(), end = _glyphs.end(); i != end; ++i)
+ i->_value.image.free();
+
+ _initialized = false;
+ }
+}
+
+bool TTFFont::load(Common::SeekableReadStream &stream, int size, bool monochrome, const uint32 *mapping) {
+ if (!g_ttf.isInitialized())
+ return false;
+
+ _size = stream.size();
+ if (!_size)
+ return false;
+
+ _ttfFile = new uint8[_size];
+ assert(_ttfFile);
+
+ if (stream.read(_ttfFile, _size) != _size) {
+ delete[] _ttfFile;
+ _ttfFile = 0;
+
+ return false;
+ }
+
+ if (!g_ttf.loadFont(_ttfFile, _size, _face)) {
+ delete[] _ttfFile;
+ _ttfFile = 0;
+
+ return false;
+ }
+
+ // We only support scalable fonts.
+ if (!FT_IS_SCALABLE(_face)) {
+ delete[] _ttfFile;
+ _ttfFile = 0;
+
+ g_ttf.closeFont(_face);
+
+ return false;
+ }
+
+ // Check whether we have kerning support
+ _hasKerning = (FT_HAS_KERNING(_face) != 0);
+
+ if (FT_Set_Char_Size(_face, 0, size * 64, 0, 0)) {
+ delete[] _ttfFile;
+ _ttfFile = 0;
+
+ return false;
+ }
+
+ _monochrome = monochrome;
+
+ FT_Fixed yScale = _face->size->metrics.y_scale;
+ _ascent = ftCeil26_6(FT_MulFix(_face->ascender, yScale));
+ _descent = ftCeil26_6(FT_MulFix(_face->descender, yScale));
+
+ _width = ftCeil26_6(FT_MulFix(_face->max_advance_width, _face->size->metrics.x_scale));
+ _height = _ascent - _descent + 1;
+
+ if (!mapping) {
+ // Load all ISO-8859-1 characters.
+ for (uint i = 0; i < 256; ++i) {
+ if (!cacheGlyph(_glyphs[i], _glyphSlots[i], i))
+ _glyphSlots[i] = 0;
+ }
+ } else {
+ for (uint i = 0; i < 256; ++i) {
+ const uint32 unicode = mapping[i] & 0x7FFFFFFF;
+ const bool isRequired = (mapping[i] & 0x80000000) != 0;
+ // Check whether loading an important glyph fails and error out if
+ // that is the case.
+ if (!cacheGlyph(_glyphs[i], _glyphSlots[i], unicode)) {
+ _glyphSlots[i] = 0;
+ if (isRequired)
+ return false;
+ }
+ }
+ }
+
+ _initialized = (_glyphs.size() != 0);
+ return _initialized;
+}
+
+int TTFFont::getFontHeight() const {
+ return _height;
+}
+
+int TTFFont::getMaxCharWidth() const {
+ return _width;
+}
+
+int TTFFont::getCharWidth(byte chr) const {
+ GlyphCache::const_iterator glyphEntry = _glyphs.find(chr);
+ if (glyphEntry == _glyphs.end())
+ return 0;
+ else
+ return glyphEntry->_value.advance;
+}
+
+int TTFFont::getKerningOffset(byte left, byte right) const {
+ if (!_hasKerning)
+ return 0;
+
+ FT_UInt leftGlyph = _glyphSlots[left];
+ FT_UInt rightGlyph = _glyphSlots[right];
+
+ if (!leftGlyph || !rightGlyph)
+ return 0;
+
+ FT_Vector kerningVector;
+ FT_Get_Kerning(_face, leftGlyph, rightGlyph, FT_KERNING_DEFAULT, &kerningVector);
+ return (kerningVector.x / 64);
+}
+
+namespace {
+
+template<typename ColorType>
+void renderGlyph(uint8 *dstPos, const int dstPitch, const uint8 *srcPos, const int srcPitch, const int w, const int h, ColorType color, const PixelFormat &dstFormat) {
+ uint8 sR, sG, sB;
+ dstFormat.colorToRGB(color, sR, sG, sB);
+
+ for (int y = 0; y < h; ++y) {
+ ColorType *rDst = (ColorType *)dstPos;
+ const uint8 *src = srcPos;
+
+ for (int x = 0; x < w; ++x) {
+ if (*src == 255) {
+ *rDst = color;
+ } else if (*src) {
+ const uint8 a = *src;
+
+ uint8 dR, dG, dB;
+ dstFormat.colorToRGB(*rDst, dR, dG, dB);
+
+ dR = ((255 - a) * dR + a * sR) / 255;
+ dG = ((255 - a) * dG + a * sG) / 255;
+ dB = ((255 - a) * dB + a * sB) / 255;
+
+ *rDst = dstFormat.RGBToColor(dR, dG, dB);
+ }
+
+ ++rDst;
+ ++src;
+ }
+
+ dstPos += dstPitch;
+ srcPos += srcPitch;
+ }
+}
+
+} // End of anonymous namespace
+
+void TTFFont::drawChar(Surface *dst, byte chr, int x, int y, uint32 color) const {
+ GlyphCache::const_iterator glyphEntry = _glyphs.find(chr);
+ if (glyphEntry == _glyphs.end())
+ return;
+
+ const Glyph &glyph = glyphEntry->_value;
+
+ x += glyph.xOffset;
+ y += glyph.yOffset;
+
+ if (x > dst->w)
+ return;
+ if (y > dst->h)
+ return;
+
+ int w = glyph.image.w;
+ int h = glyph.image.h;
+
+ const uint8 *srcPos = (const uint8 *)glyph.image.getBasePtr(0, 0);
+
+ // Make sure we are not drawing outside the screen bounds
+ if (x < 0) {
+ srcPos -= x;
+ w += x;
+ x = 0;
+ }
+
+ if (x + w > dst->w)
+ w = dst->w - x;
+
+ if (w <= 0)
+ return;
+
+ if (y < 0) {
+ srcPos += y * glyph.image.pitch;
+ h += y;
+ y = 0;
+ }
+
+ if (y + h > dst->h)
+ h = dst->h - y;
+
+ if (h <= 0)
+ return;
+
+ uint8 *dstPos = (uint8 *)dst->getBasePtr(x, y);
+
+ if (dst->format.bytesPerPixel == 1) {
+ for (int cy = 0; cy < h; ++cy) {
+ uint8 *rDst = dstPos;
+ const uint8 *src = srcPos;
+
+ for (int cx = 0; cx < w; ++cx) {
+ // We assume a 1Bpp mode is a color indexed mode, thus we can
+ // not take advantage of anti-aliasing here.
+ if (*src >= 0x80)
+ *rDst = color;
+
+ ++rDst;
+ ++src;
+ }
+
+ dstPos += dst->pitch;
+ srcPos += glyph.image.pitch;
+ }
+ } else if (dst->format.bytesPerPixel == 2) {
+ renderGlyph<uint16>(dstPos, dst->pitch, srcPos, glyph.image.pitch, w, h, color, dst->format);
+ } else if (dst->format.bytesPerPixel == 4) {
+ renderGlyph<uint32>(dstPos, dst->pitch, srcPos, glyph.image.pitch, w, h, color, dst->format);
+ }
+}
+
+bool TTFFont::cacheGlyph(Glyph &glyph, FT_UInt &slot, uint chr) {
+ slot = FT_Get_Char_Index(_face, chr);
+ if (!slot)
+ return false;
+
+ // We use the light target and render mode to improve the looks of the
+ // glyphs. It is most noticable in FreeSansBold.ttf, where otherwise the
+ // 't' glyph looks like it is cut off on the right side.
+ if (FT_Load_Glyph(_face, slot, (_monochrome ? FT_LOAD_TARGET_MONO : FT_LOAD_TARGET_LIGHT)))
+ return false;
+
+ if (FT_Render_Glyph(_face->glyph, (_monochrome ? FT_RENDER_MODE_MONO : FT_RENDER_MODE_LIGHT)))
+ return false;
+
+ if (_face->glyph->format != FT_GLYPH_FORMAT_BITMAP)
+ return false;
+
+ FT_Glyph_Metrics &metrics = _face->glyph->metrics;
+
+ glyph.xOffset = ftFloor26_6(metrics.horiBearingX);
+ int xMax = glyph.xOffset + ftCeil26_6(metrics.width);
+ glyph.yOffset = _ascent - ftFloor26_6(metrics.horiBearingY);
+
+ glyph.advance = ftCeil26_6(metrics.horiAdvance);
+
+ // In case we got a negative xMin we adjust that, this might make some
+ // characters make a bit odd, but it's the only way we can assure no
+ // invalid memory writes with the current font API
+ if (glyph.xOffset < 0) {
+ xMax -= glyph.xOffset;
+ glyph.xOffset = 0;
+
+ if (xMax > glyph.advance)
+ glyph.advance = xMax;
+ }
+
+ const FT_Bitmap &bitmap = _face->glyph->bitmap;
+ glyph.image.create(bitmap.width, bitmap.rows, PixelFormat::createFormatCLUT8());
+
+ const uint8 *src = bitmap.buffer;
+ int srcPitch = bitmap.pitch;
+ if (srcPitch < 0) {
+ src += (bitmap.rows - 1) * srcPitch;
+ srcPitch = -srcPitch;
+ }
+
+ uint8 *dst = (uint8 *)glyph.image.getBasePtr(0, 0);
+ memset(dst, 0, glyph.image.h * glyph.image.pitch);
+
+ switch (bitmap.pixel_mode) {
+ case FT_PIXEL_MODE_MONO:
+ for (int y = 0; y < bitmap.rows; ++y) {
+ const uint8 *curSrc = src;
+ uint8 mask = 0;
+
+ for (int x = 0; x < bitmap.width; ++x) {
+ if ((x % 8) == 0)
+ mask = *curSrc++;
+
+ if (mask & 0x80)
+ *dst = 255;
+
+ mask <<= 1;
+ ++dst;
+ }
+
+ src += srcPitch;
+ }
+ break;
+
+ case FT_PIXEL_MODE_GRAY:
+ for (int y = 0; y < bitmap.rows; ++y) {
+ memcpy(dst, src, bitmap.width);
+ dst += glyph.image.pitch;
+ src += srcPitch;
+ }
+ break;
+
+ default:
+ warning("TTFFont::cacheGlyph: Unsupported pixel mode %d", bitmap.pixel_mode);
+ return false;
+ }
+
+ return true;
+}
+
+Font *loadTTFFont(Common::SeekableReadStream &stream, int size, bool monochrome, const uint32 *mapping) {
+ TTFFont *font = new TTFFont();
+
+ if (!font->load(stream, size, monochrome, mapping)) {
+ delete font;
+ return 0;
+ }
+
+ return font;
+}
+
+} // End of namespace Graphics
+
+namespace Common {
+DECLARE_SINGLETON(Graphics::TTFLibrary);
+} // End of namespace Common
+
+#endif
+
diff --git a/engines/m4/staticres.h b/graphics/fonts/ttf.h
index e3ead3398b..7222d6e112 100644
--- a/engines/m4/staticres.h
+++ b/graphics/fonts/ttf.h
@@ -8,49 +8,35 @@
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
-
+ *
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
-
+ *
* You should have received a copy of the GNU General Public 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 M4_STATICRES_H
-#define M4_STATICRES_H
+#ifndef GRAPHICS_FONTS_TTF_H
+#define GRAPHICS_FONTS_TTF_H
#include "common/scummsys.h"
-#include "m4/m4.h"
-namespace M4 {
+#ifdef USE_FREETYPE2
-extern const char *englishMADSArticleList[9];
+#include "common/stream.h"
-extern const char *cheatingEnabledDesc[3];
+namespace Graphics {
-extern const char *atStr;
-extern const char *lookAroundStr;
-extern const char *toStr;
-extern const char *useStr;
-extern const char *walkToStr;
-extern const char *fenceStr;
-extern const char *overStr;
+class Font;
+Font *loadTTFFont(Common::SeekableReadStream &stream, int size, bool monochrome = false, const uint32 *mapping = 0);
-extern const char *GameReleaseInfoStr;
-extern const char *GameReleaseTitleStr;
+} // End of namespace Graphics
-struct VerbInit {
- int verb;
- int8 flag1;
- int8 flag2;
-};
-
-extern VerbInit verbList[10];
-
-} // End of namespace M4
+#endif
#endif
+
diff --git a/graphics/iff.cpp b/graphics/iff.cpp
index 4bb971f299..7434a6bebc 100644
--- a/graphics/iff.cpp
+++ b/graphics/iff.cpp
@@ -206,7 +206,7 @@ struct PBMLoader {
case ID_BODY:
if (_surface) {
_surface->create(_decoder._header.width, _decoder._header.height, PixelFormat::createFormatCLUT8());
- _decoder.loadBitmap((byte*)_surface->pixels, chunk._stream);
+ _decoder.loadBitmap((byte *)_surface->pixels, chunk._stream);
}
return true; // stop the parser
}
@@ -234,7 +234,7 @@ bool PackBitsReadStream::eos() const {
}
uint32 PackBitsReadStream::read(void *dataPtr, uint32 dataSize) {
- byte *out = (byte*)dataPtr;
+ byte *out = (byte *)dataPtr;
uint32 left = dataSize;
uint32 lenR = 0, lenW = 0;
diff --git a/graphics/imagedec.cpp b/graphics/imagedec.cpp
index eb595a750e..9552f095fa 100644
--- a/graphics/imagedec.cpp
+++ b/graphics/imagedec.cpp
@@ -117,7 +117,7 @@ Surface *BMPDecoder::decodeImage(Common::SeekableReadStream &stream, const Pixel
assert(newSurf);
newSurf->create(info.width, info.height, format);
assert(newSurf->pixels);
- OverlayColor *curPixel = (OverlayColor*)newSurf->pixels + (newSurf->h-1) * newSurf->w;
+ OverlayColor *curPixel = (OverlayColor *)newSurf->pixels + (newSurf->h-1) * newSurf->w;
int pitchAdd = info.width % 4;
for (int i = 0; i < newSurf->h; ++i) {
for (int i2 = 0; i2 < newSurf->w; ++i2) {
diff --git a/graphics/jpeg.cpp b/graphics/jpeg.cpp
index c97a540d33..53e693a045 100644
--- a/graphics/jpeg.cpp
+++ b/graphics/jpeg.cpp
@@ -43,20 +43,6 @@ static const uint8 _zigZagOrder[64] = {
53, 60, 61, 54, 47, 55, 62, 63
};
-// IDCT table built with :
-// _idct8x8[x][y] = cos(((2 * x + 1) * y) * (M_PI / 16.0)) * 0.5;
-// _idct8x8[x][y] /= sqrt(2.0) if y == 0
-static const double _idct8x8[8][8] = {
- { 0.353553390593274, 0.490392640201615, 0.461939766255643, 0.415734806151273, 0.353553390593274, 0.277785116509801, 0.191341716182545, 0.097545161008064 },
- { 0.353553390593274, 0.415734806151273, 0.191341716182545, -0.097545161008064, -0.353553390593274, -0.490392640201615, -0.461939766255643, -0.277785116509801 },
- { 0.353553390593274, 0.277785116509801, -0.191341716182545, -0.490392640201615, -0.353553390593274, 0.097545161008064, 0.461939766255643, 0.415734806151273 },
- { 0.353553390593274, 0.097545161008064, -0.461939766255643, -0.277785116509801, 0.353553390593274, 0.415734806151273, -0.191341716182545, -0.490392640201615 },
- { 0.353553390593274, -0.097545161008064, -0.461939766255643, 0.277785116509801, 0.353553390593274, -0.415734806151273, -0.191341716182545, 0.490392640201615 },
- { 0.353553390593274, -0.277785116509801, -0.191341716182545, 0.490392640201615, -0.353553390593273, -0.097545161008064, 0.461939766255643, -0.415734806151273 },
- { 0.353553390593274, -0.415734806151273, 0.191341716182545, 0.097545161008064, -0.353553390593274, 0.490392640201615, -0.461939766255643, 0.277785116509801 },
- { 0.353553390593274, -0.490392640201615, 0.461939766255643, -0.415734806151273, 0.353553390593273, -0.277785116509801, 0.191341716182545, -0.097545161008064 }
-};
-
JPEG::JPEG() :
_stream(NULL), _w(0), _h(0), _numComp(0), _components(NULL), _numScanComp(0),
_scanComp(NULL), _currentComp(NULL) {
@@ -113,6 +99,7 @@ void JPEG::reset() {
// Reset member variables
_stream = NULL;
_w = _h = 0;
+ _restartInterval = 0;
// Free the components
for (int c = 0; c < _numComp; c++)
@@ -208,12 +195,18 @@ bool JPEG::read(Common::SeekableReadStream *stream) {
case 0xE0: // JFIF/JFXX segment
ok = readJFIF();
break;
+ case 0xDD: // Define Restart Interval
+ ok = readDRI();
+ break;
case 0xFE: // Comment
_stream->seek(_stream->readUint16BE() - 2, SEEK_CUR);
break;
default: { // Unknown marker
uint16 size = _stream->readUint16BE();
- warning("JPEG: Unknown marker %02X, skipping %d bytes", marker, size - 2);
+
+ if ((marker & 0xE0) != 0xE0)
+ warning("JPEG: Unknown marker %02X, skipping %d bytes", marker, size - 2);
+
_stream->seek(size - 2, SEEK_CUR);
}
}
@@ -224,7 +217,7 @@ bool JPEG::read(Common::SeekableReadStream *stream) {
bool JPEG::readJFIF() {
uint16 length = _stream->readUint16BE();
uint32 tag = _stream->readUint32BE();
- if (tag != MKTAG('J','F','I','F')) {
+ if (tag != MKTAG('J', 'F', 'I', 'F')) {
warning("JPEG::readJFIF() tag mismatch");
return false;
}
@@ -234,8 +227,10 @@ bool JPEG::readJFIF() {
}
byte majorVersion = _stream->readByte();
byte minorVersion = _stream->readByte();
- if(majorVersion != 1 || minorVersion != 1)
- warning("JPEG::readJFIF() Non-v1.1 JPEGs may not be handled correctly");
+
+ if (majorVersion != 1 || (minorVersion != 1 && minorVersion != 2))
+ warning("JPEG::readJFIF() Non-v1.1/1.2 JPEGs may not be handled correctly");
+
/* byte densityUnits = */ _stream->readByte();
/* uint16 xDensity = */ _stream->readUint16BE();
/* uint16 yDensity = */ _stream->readUint16BE();
@@ -304,7 +299,7 @@ bool JPEG::readDHT() {
// Free the Huffman table
delete[] _huff[tableNum].values; _huff[tableNum].values = NULL;
delete[] _huff[tableNum].sizes; _huff[tableNum].sizes = NULL;
- delete[] _huff[tableNum].codes; _huff[tableNum].codes = NULL;
+ delete[] _huff[tableNum].codes; _huff[tableNum].codes = NULL;
// Read the number of values for each length
uint8 numValues[16];
@@ -445,10 +440,28 @@ bool JPEG::readSOS() {
}
bool ok = true;
- for (int y = 0; ok && (y < yMCU); y++)
- for (int x = 0; ok && (x < xMCU); x++)
+ uint16 interval = _restartInterval;
+
+ for (int y = 0; ok && (y < yMCU); y++) {
+ for (int x = 0; ok && (x < xMCU); x++) {
ok = readMCU(x, y);
+ // If we have a restart interval, we'll need to reset a couple
+ // variables
+ if (_restartInterval != 0) {
+ interval--;
+
+ if (interval == 0) {
+ interval = _restartInterval;
+ _bitsNumber = 0;
+
+ for (byte i = 0; i < _numScanComp; i++)
+ _scanComp[i]->DCpredictor = 0;
+ }
+ }
+ }
+ }
+
// Trim Component surfaces back to image height and width
// Note: Code using jpeg must use surface.pitch correctly...
for (uint16 c = 0; c < _numScanComp; c++) {
@@ -489,6 +502,21 @@ bool JPEG::readDQT() {
return true;
}
+// Marker 0xDD (Define Restart Interval)
+bool JPEG::readDRI() {
+ debug(5, "JPEG: readDRI");
+ uint16 size = _stream->readUint16BE() - 2;
+
+ if (size != 2) {
+ warning("JPEG: Invalid DRI size %d", size);
+ return false;
+ }
+
+ _restartInterval = _stream->readUint16BE();
+ debug(5, "Restart interval: %d", _restartInterval);
+ return true;
+}
+
bool JPEG::readMCU(uint16 xMCU, uint16 yMCU) {
bool ok = true;
for (int c = 0; ok && (c < _numComp); c++) {
@@ -504,40 +532,63 @@ bool JPEG::readMCU(uint16 xMCU, uint16 yMCU) {
return ok;
}
-void JPEG::idct8x8(float result[64], const int16 dct[64]) {
- float tmp[64];
+// triple-butterfly-add (and possible rounding)
+#define xadd3(xa, xb, xc, xd, h) \
+ p = xa + xb; \
+ n = xa - xb; \
+ xa = p + xc + h; \
+ xb = n + xd + h; \
+ xc = p - xc + h; \
+ xd = n - xd + h;
+
+// butterfly-mul
+#define xmul(xa, xb, k1, k2, sh) \
+ n = k1 * (xa + xb); \
+ p = xa; \
+ xa = (n + (k2 - k1) * xb) >> sh; \
+ xb = (n - (k2 + k1) * p) >> sh;
+
+// IDCT based on public domain code from http://halicery.com/jpeg/idct.html
+void JPEG::idct1D8x8(int32 src[8], int32 dest[64], int32 ps, int32 half) {
+ int p, n;
+
+ src[0] <<= 9;
+ src[1] <<= 7;
+ src[3] *= 181;
+ src[4] <<= 9;
+ src[5] *= 181;
+ src[7] <<= 7;
+
+ // Even part
+ xmul(src[6], src[2], 277, 669, 0)
+ xadd3(src[0], src[4], src[6], src[2], half)
+
+ // Odd part
+ xadd3(src[1], src[7], src[3], src[5], 0)
+ xmul(src[5], src[3], 251, 50, 6)
+ xmul(src[1], src[7], 213, 142, 6)
+
+ dest[0 * 8] = (src[0] + src[1]) >> ps;
+ dest[1 * 8] = (src[4] + src[5]) >> ps;
+ dest[2 * 8] = (src[2] + src[3]) >> ps;
+ dest[3 * 8] = (src[6] + src[7]) >> ps;
+ dest[4 * 8] = (src[6] - src[7]) >> ps;
+ dest[5 * 8] = (src[2] - src[3]) >> ps;
+ dest[6 * 8] = (src[4] - src[5]) >> ps;
+ dest[7 * 8] = (src[0] - src[1]) >> ps;
+}
- // Apply 1D IDCT to rows
- for (int y = 0; y < 8; y++) {
- for (int x = 0; x < 8; x++) {
- tmp[y + x * 8] = dct[0] * _idct8x8[x][0]
- + dct[1] * _idct8x8[x][1]
- + dct[2] * _idct8x8[x][2]
- + dct[3] * _idct8x8[x][3]
- + dct[4] * _idct8x8[x][4]
- + dct[5] * _idct8x8[x][5]
- + dct[6] * _idct8x8[x][6]
- + dct[7] * _idct8x8[x][7];
- }
+void JPEG::idct2D8x8(int32 block[64]) {
+ int32 tmp[64];
- dct += 8;
- }
+ // Apply 1D IDCT to rows
+ for (int i = 0; i < 8; i++)
+ idct1D8x8(&block[i * 8], &tmp[i], 9, 1 << 8);
// Apply 1D IDCT to columns
- for (int x = 0; x < 8; x++) {
- const float *u = tmp + x * 8;
- for (int y = 0; y < 8; y++) {
- result[y * 8 + x] = u[0] * _idct8x8[y][0]
- + u[1] * _idct8x8[y][1]
- + u[2] * _idct8x8[y][2]
- + u[3] * _idct8x8[y][3]
- + u[4] * _idct8x8[y][4]
- + u[5] * _idct8x8[y][5]
- + u[6] * _idct8x8[y][6]
- + u[7] * _idct8x8[y][7];
- }
- }
-}
+ for (int i = 0; i < 8; i++)
+ idct1D8x8(&tmp[i * 8], &block[i], 12, 1 << 11);
+ }
bool JPEG::readDataUnit(uint16 x, uint16 y) {
// Prepare an empty data array
@@ -553,30 +604,29 @@ bool JPEG::readDataUnit(uint16 x, uint16 y) {
readAC(readData);
// Calculate the DCT coefficients from the input sequence
- int16 DCT[64];
+ int32 block[64];
for (uint8 i = 0; i < 64; i++) {
// Dequantize
- int16 val = readData[i];
+ int32 val = readData[i];
int16 quant = _quant[_currentComp->quantTableSelector][i];
val *= quant;
// Store the normalized coefficients, undoing the Zig-Zag
- DCT[_zigZagOrder[i]] = val;
+ block[_zigZagOrder[i]] = val;
}
// Apply the IDCT
- float result[64];
- idct8x8(result, DCT);
+ idct2D8x8(block);
// Level shift to make the values unsigned
for (int i = 0; i < 64; i++) {
- result[i] = result[i] + 128;
+ block[i] = block[i] + 128;
- if (result[i] < 0)
- result[i] = 0;
+ if (block[i] < 0)
+ block[i] = 0;
- if (result[i] > 255)
- result[i] = 255;
+ if (block[i] > 255)
+ block[i] = 255;
}
// Paint the component surface
@@ -594,7 +644,7 @@ bool JPEG::readDataUnit(uint16 x, uint16 y) {
for (uint8 i = 0; i < 8; i++) {
for (uint16 sH = 0; sH < scalingH; sH++) {
- *ptr = (byte)(result[j * 8 + i]);
+ *ptr = (byte)(block[j * 8 + i]);
ptr++;
}
}
@@ -647,15 +697,15 @@ void JPEG::readAC(int16 *out) {
int16 JPEG::readSignedBits(uint8 numBits) {
uint16 ret = 0;
- if (numBits > 16) error("requested %d bits", numBits); //XXX
+ if (numBits > 16)
+ error("requested %d bits", numBits); //XXX
// MSB=0 for negatives, 1 for positives
for (int i = 0; i < numBits; i++)
ret = (ret << 1) + readBit();
// Extend sign bits (PAG109)
- if (!(ret >> (numBits - 1)))
- {
+ if (!(ret >> (numBits - 1))) {
uint16 tmp = ((uint16)-1 << numBits) + 1;
ret = ret + tmp;
}
@@ -709,6 +759,9 @@ uint8 JPEG::readBit() {
// DNL marker: Define Number of Lines
// TODO: terminate scan
warning("DNL marker detected: terminate scan");
+ } else if (byte2 >= 0xD0 && byte2 <= 0xD7) {
+ debug(7, "RST%d marker detected", byte2 & 7);
+ _bitsData = _stream->readByte();
} else {
warning("Error: marker 0x%02X read in entropy data", byte2);
}
diff --git a/graphics/jpeg.h b/graphics/jpeg.h
index 27b91e8777..b87791470f 100644
--- a/graphics/jpeg.h
+++ b/graphics/jpeg.h
@@ -54,6 +54,7 @@ private:
Common::SeekableReadStream *_stream;
uint16 _w, _h;
+ uint16 _restartInterval;
// Image components
uint8 _numComp;
@@ -101,6 +102,7 @@ private:
bool readDHT();
bool readSOS();
bool readDQT();
+ bool readDRI();
// Helper functions
bool readMCU(uint16 xMCU, uint16 yMCU);
@@ -116,7 +118,8 @@ private:
uint8 _bitsNumber;
// Inverse Discrete Cosine Transformation
- void idct8x8(float dst[64], const int16 src[64]);
+ static void idct1D8x8(int32 src[8], int32 dest[64], int32 ps, int32 half);
+ static void idct2D8x8(int32 block[64]);
};
} // End of Graphics namespace
diff --git a/graphics/module.mk b/graphics/module.mk
index 02c88d98ba..1e84b2425d 100644
--- a/graphics/module.mk
+++ b/graphics/module.mk
@@ -9,6 +9,7 @@ MODULE_OBJS := \
fonts/consolefont.o \
fonts/newfont_big.o \
fonts/newfont.o \
+ fonts/ttf.o \
fonts/winfont.o \
iff.o \
imagedec.o \
diff --git a/graphics/pict.cpp b/graphics/pict.cpp
index 0f4dcd463f..872f2f224a 100644
--- a/graphics/pict.cpp
+++ b/graphics/pict.cpp
@@ -338,10 +338,9 @@ void PictDecoder::unpackBitsRect(Common::SeekableReadStream *stream, bool hasPal
_outputSurface = new Graphics::Surface();
_outputSurface->create(width, height, (bytesPerPixel == 1) ? PixelFormat::createFormatCLUT8() : _pixelFormat);
- // Create an temporary buffer, but allocate a bit more than we need to avoid overflow
- // (align it to the next highest two-byte packed boundary, which may be more unpacked,
- // as m68k and therefore QuickDraw is word-aligned)
- byte *buffer = new byte[width * height * bytesPerPixel + (8 * 2 / packBitsData.pixMap.pixelSize)];
+ // Ensure we have enough space in the buffer to hold an entire line's worth of pixels
+ uint32 lineSize = MAX<int>(width * bytesPerPixel + (8 * 2 / packBitsData.pixMap.pixelSize), packBitsData.pixMap.rowBytes);
+ byte *buffer = new byte[lineSize * height];
// Read in amount of data per row
for (uint16 i = 0; i < packBitsData.pixMap.bounds.height(); i++) {
@@ -467,7 +466,6 @@ void PictDecoder::skipBitsRect(Common::SeekableReadStream *stream, bool hasPalet
stream->readUint16BE();
uint16 packType;
- uint16 pixelSize;
// Top two bits signify PixMap vs BitMap
if (rowBytes & 0xC000) {
@@ -475,7 +473,7 @@ void PictDecoder::skipBitsRect(Common::SeekableReadStream *stream, bool hasPalet
stream->readUint16BE();
packType = stream->readUint16BE();
stream->skip(14);
- pixelSize = stream->readUint16BE();
+ stream->readUint16BE(); // pixelSize
stream->skip(16);
if (hasPalette) {
@@ -488,7 +486,6 @@ void PictDecoder::skipBitsRect(Common::SeekableReadStream *stream, bool hasPalet
} else {
// BitMap
packType = 0;
- pixelSize = 1;
}
stream->skip(18);
diff --git a/graphics/png.cpp b/graphics/png.cpp
index 2189fd333f..cea8b575ad 100644
--- a/graphics/png.cpp
+++ b/graphics/png.cpp
@@ -22,8 +22,6 @@
#include "graphics/png.h"
-#ifdef GRAPHICS_PNG_H
-
#include "graphics/pixelformat.h"
#include "graphics/surface.h"
@@ -487,5 +485,3 @@ void PNG::readTransparencyChunk(uint32 chunkLength) {
}
} // End of Graphics namespace
-
-#endif // GRAPHICS_PNG_H
diff --git a/graphics/png.h b/graphics/png.h
index 3f8ea85320..078c76fc6b 100644
--- a/graphics/png.h
+++ b/graphics/png.h
@@ -27,16 +27,6 @@
* - zlib
*/
-// Currently, only the sword25 engine uses the PNG decoder, so skip compiling
-// it if sword25 is not enabled, or if zlib (a required dependency) is not
-// enabled.
-
-#if !(defined(ENABLE_SWORD25) || defined(USE_ZLIB))
-
-// Do not compile the PNG decoder code
-
-#else
-
#ifndef GRAPHICS_PNG_H
#define GRAPHICS_PNG_H
@@ -176,5 +166,3 @@ private:
} // End of Graphics namespace
#endif // GRAPHICS_PNG_H
-
-#endif // Engine and zlib guard
diff --git a/graphics/scaler/scale2x.h b/graphics/scaler/scale2x.h
index b0c887d43c..917e817a0d 100644
--- a/graphics/scaler/scale2x.h
+++ b/graphics/scaler/scale2x.h
@@ -18,8 +18,8 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-#ifndef __SCALE2X_H
-#define __SCALE2X_H
+#ifndef SCALER_SCALE2X_H
+#define SCALER_SCALE2X_H
#if defined(_MSC_VER)
#define __restrict__
diff --git a/graphics/scaler/scale3x.h b/graphics/scaler/scale3x.h
index ad5604d086..8d93914400 100644
--- a/graphics/scaler/scale3x.h
+++ b/graphics/scaler/scale3x.h
@@ -18,8 +18,8 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-#ifndef __SCALE3X_H
-#define __SCALE3X_H
+#ifndef SCALER_SCALE3X_H
+#define SCALER_SCALE3X_H
#if defined(_MSC_VER)
#define __restrict__
diff --git a/graphics/scaler/scalebit.h b/graphics/scaler/scalebit.h
index 6e4a30caf0..75f9dae455 100644
--- a/graphics/scaler/scalebit.h
+++ b/graphics/scaler/scalebit.h
@@ -33,8 +33,8 @@
* - derivative works of the program are allowed.
*/
-#ifndef __SCALEBIT_H
-#define __SCALEBIT_H
+#ifndef SCALER_SCALEBIT_H
+#define SCALER_SCALEBIT_H
int scale_precondition(unsigned scale, unsigned pixel, unsigned width, unsigned height);
void scale(unsigned scale, void* void_dst, unsigned dst_slice, const void* void_src, unsigned src_slice, unsigned pixel, unsigned width, unsigned height);
diff --git a/graphics/scaler/thumbnail_intern.cpp b/graphics/scaler/thumbnail_intern.cpp
index ef540b8cd8..88f3cc2077 100644
--- a/graphics/scaler/thumbnail_intern.cpp
+++ b/graphics/scaler/thumbnail_intern.cpp
@@ -46,7 +46,7 @@ void createThumbnail_2(const uint8 *src, uint32 srcPitch, uint8 *dstPtr, uint32
assert(height % 2 == 0);
for (int y = 0; y < height; y += 2) {
for (int x = 0; x < width; x += 2, dstPtr += 2) {
- *((uint16*)dstPtr) = quadBlockInterpolate<bitFormat>(src + 2 * x, srcPitch);
+ *((uint16 *)dstPtr) = quadBlockInterpolate<bitFormat>(src + 2 * x, srcPitch);
}
dstPtr += (dstPitch - 2 * width / 2);
src += 2 * srcPitch;
@@ -64,7 +64,7 @@ void createThumbnail_4(const uint8 *src, uint32 srcPitch, uint8 *dstPtr, uint32
uint16 downleft = quadBlockInterpolate<bitFormat>(src + srcPitch * 2 + 2 * x, srcPitch);
uint16 downright = quadBlockInterpolate<bitFormat>(src + srcPitch * 2 + 2 * (x + 2), srcPitch);
- *((uint16*)dstPtr) = interpolate16_1_1_1_1<Graphics::ColorMasks<bitFormat> >(upleft, upright, downleft, downright);
+ *((uint16 *)dstPtr) = interpolate16_1_1_1_1<Graphics::ColorMasks<bitFormat> >(upleft, upright, downleft, downright);
}
dstPtr += (dstPitch - 2 * width / 4);
src += 4 * srcPitch;
@@ -116,9 +116,9 @@ static bool grabScreen565(Graphics::Surface *surf) {
byte r = 0, g = 0, b = 0;
if (screenFormat.bytesPerPixel == 1) {
- r = palette[((uint8*)screen->pixels)[y * screen->pitch + x] * 3];
- g = palette[((uint8*)screen->pixels)[y * screen->pitch + x] * 3 + 1];
- b = palette[((uint8*)screen->pixels)[y * screen->pitch + x] * 3 + 2];
+ r = palette[((uint8 *)screen->pixels)[y * screen->pitch + x] * 3];
+ g = palette[((uint8 *)screen->pixels)[y * screen->pitch + x] * 3 + 1];
+ b = palette[((uint8 *)screen->pixels)[y * screen->pitch + x] * 3 + 2];
} else if (screenFormat.bytesPerPixel == 2) {
uint16 col = READ_UINT16(screen->getBasePtr(x, y));
screenFormat.colorToRGB(col, r, g, b);
diff --git a/graphics/sjis.h b/graphics/sjis.h
index f96eef6ad1..2d05005fc3 100644
--- a/graphics/sjis.h
+++ b/graphics/sjis.h
@@ -43,7 +43,7 @@
#endif
#include "common/scummsys.h"
-#include "common/util.h"
+#include "common/platform.h"
namespace Graphics {
diff --git a/graphics/surface.cpp b/graphics/surface.cpp
index e0b25f22e9..79a7821feb 100644
--- a/graphics/surface.cpp
+++ b/graphics/surface.cpp
@@ -95,10 +95,10 @@ void Surface::hLine(int x, int y, int x2, uint32 color) {
memset(ptr, (byte)color, x2 - x + 1);
} else if (format.bytesPerPixel == 2) {
uint16 *ptr = (uint16 *)getBasePtr(x, y);
- Common::set_to(ptr, ptr + (x2 - x + 1), (uint16)color);
+ Common::fill(ptr, ptr + (x2 - x + 1), (uint16)color);
} else if (format.bytesPerPixel == 4) {
uint32 *ptr = (uint32 *)getBasePtr(x, y);
- Common::set_to(ptr, ptr + (x2 - x + 1), color);
+ Common::fill(ptr, ptr + (x2 - x + 1), color);
} else {
error("Surface::hLine: bytesPerPixel must be 1, 2, or 4");
}
@@ -172,13 +172,13 @@ void Surface::fillRect(Common::Rect r, uint32 color) {
if (format.bytesPerPixel == 2) {
uint16 *ptr = (uint16 *)getBasePtr(r.left, r.top);
while (height--) {
- Common::set_to(ptr, ptr + width, (uint16)color);
+ Common::fill(ptr, ptr + width, (uint16)color);
ptr += pitch / 2;
}
} else {
uint32 *ptr = (uint32 *)getBasePtr(r.left, r.top);
while (height--) {
- Common::set_to(ptr, ptr + width, color);
+ Common::fill(ptr, ptr + width, color);
ptr += pitch / 4;
}
}
diff --git a/graphics/yuv_to_rgb.h b/graphics/yuv_to_rgb.h
index 2d3b9e634e..259ba09810 100644
--- a/graphics/yuv_to_rgb.h
+++ b/graphics/yuv_to_rgb.h
@@ -35,8 +35,6 @@
namespace Graphics {
-struct Surface;
-
/**
* Convert a YUV420 image to an RGB surface
*
diff --git a/gui/ThemeEngine.cpp b/gui/ThemeEngine.cpp
index cf16eec238..2cb1635e20 100644
--- a/gui/ThemeEngine.cpp
+++ b/gui/ThemeEngine.cpp
@@ -34,6 +34,7 @@
#include "graphics/surface.h"
#include "graphics/VectorRenderer.h"
#include "graphics/fonts/bdf.h"
+#include "graphics/fonts/ttf.h"
#include "gui/widget.h"
#include "gui/ThemeEngine.h"
@@ -45,6 +46,7 @@ namespace GUI {
const char * const ThemeEngine::kImageLogo = "logo.bmp";
const char * const ThemeEngine::kImageLogoSmall = "logo_small.bmp";
const char * const ThemeEngine::kImageSearch = "search.bmp";
+const char * const ThemeEngine::kImageEraser = "eraser.bmp";
struct TextDrawData {
const Graphics::Font *_fontPtr;
@@ -260,7 +262,8 @@ void ThemeItemBitmap::drawSelf(bool draw, bool restore) {
ThemeEngine::ThemeEngine(Common::String id, GraphicsMode mode) :
_system(0), _vectorRenderer(0),
_buffering(false), _bytesPerPixel(0), _graphicsMode(kGfxDisabled),
- _font(0), _initOk(false), _themeOk(false), _enabled(false), _cursor(0) {
+ _font(0), _initOk(false), _themeOk(false), _enabled(false), _themeFiles(),
+ _cursor(0) {
_system = g_system;
_parser = new ThemeParser(this);
@@ -293,6 +296,9 @@ ThemeEngine::ThemeEngine(Common::String id, GraphicsMode mode) :
_graphicsMode = mode;
_themeArchive = 0;
_initOk = false;
+
+ // We prefer files in archive bundles over the common search paths.
+ _themeFiles.add("default", &SearchMan, 0, false);
}
ThemeEngine::~ThemeEngine() {
@@ -316,7 +322,6 @@ ThemeEngine::~ThemeEngine() {
delete _parser;
delete _themeEval;
delete[] _cursor;
- delete _themeArchive;
}
@@ -405,6 +410,9 @@ bool ThemeEngine::init() {
}
}
}
+
+ if (_themeArchive)
+ _themeFiles.add("theme_archive", _themeArchive, 1, true);
}
// Load the theme
@@ -550,7 +558,7 @@ bool ThemeEngine::addTextData(const Common::String &drawDataId, TextData textId,
return true;
}
-bool ThemeEngine::addFont(TextData textId, const Common::String &file) {
+bool ThemeEngine::addFont(TextData textId, const Common::String &file, const Common::String &scalableFile, const int pointsize) {
if (textId == -1)
return false;
@@ -563,35 +571,26 @@ bool ThemeEngine::addFont(TextData textId, const Common::String &file) {
_texts[textId]->_fontPtr = _font;
} else {
Common::String localized = FontMan.genLocalizedFontFilename(file);
- // Try built-in fonts
- _texts[textId]->_fontPtr = FontMan.getFontByName(localized);
-
- if (!_texts[textId]->_fontPtr) {
- // First try to load localized font
- _texts[textId]->_fontPtr = loadFont(localized);
-
- if (_texts[textId]->_fontPtr)
- FontMan.assignFontToName(localized, _texts[textId]->_fontPtr);
+ const Common::String charset
+#ifdef USE_TRANSLATION
+ (TransMan.getCurrentCharset())
+#endif
+ ;
- // Fallback to non-localized font and default translation
- else {
- // Try built-in fonts
- _texts[textId]->_fontPtr = FontMan.getFontByName(file);
+ // Try localized fonts
+ _texts[textId]->_fontPtr = loadFont(localized, scalableFile, charset, pointsize, textId == kTextDataDefault);
- // Try to load it
- if (!_texts[textId]->_fontPtr) {
- _texts[textId]->_fontPtr = loadFont(file);
+ if (!_texts[textId]->_fontPtr) {
+ // Try standard fonts
+ _texts[textId]->_fontPtr = loadFont(file, scalableFile, Common::String(), pointsize, textId == kTextDataDefault);
- if (!_texts[textId]->_fontPtr)
- error("Couldn't load font '%s'", file.c_str());
+ if (!_texts[textId]->_fontPtr)
+ error("Couldn't load font '%s'/'%s'", file.c_str(), scalableFile.c_str());
- FontMan.assignFontToName(file, _texts[textId]->_fontPtr);
- }
#ifdef USE_TRANSLATION
- TransMan.setLanguage("C");
+ TransMan.setLanguage("C");
#endif
- warning("Failed to load localized font '%s'. Using non-localized font and default GUI language instead", localized.c_str());
- }
+ warning("Failed to load localized font '%s'. Using non-localized font and default GUI language instead", localized.c_str());
}
}
@@ -622,12 +621,16 @@ bool ThemeEngine::addBitmap(const Common::String &filename) {
return true;
// If not, try to load the bitmap via the ImageDecoder class.
- surf = Graphics::ImageDecoder::loadFile(filename, _overlayFormat);
- if (!surf && _themeArchive) {
- Common::SeekableReadStream *stream = _themeArchive->createReadStreamForMember(filename);
+ Common::ArchiveMemberList members;
+ _themeFiles.listMatchingMembers(members, filename);
+ for (Common::ArchiveMemberList::const_iterator i = members.begin(), end = members.end(); i != end; ++i) {
+ Common::SeekableReadStream *stream = (*i)->createReadStream();
if (stream) {
surf = Graphics::ImageDecoder::loadFile(*stream, _overlayFormat);
delete stream;
+
+ if (surf)
+ break;
}
}
@@ -844,7 +847,7 @@ void ThemeEngine::queueBitmap(const Graphics::Surface *bitmap, const Common::Rec
ThemeItemBitmap *q = new ThemeItemBitmap(this, area, bitmap, alpha);
if (_buffering) {
- _bufferQueue.push_back(q);
+ _screenQueue.push_back(q);
} else {
q->drawSelf(true, false);
delete q;
@@ -903,7 +906,7 @@ void ThemeEngine::drawCheckbox(const Common::Rect &r, const Common::String &str,
r2.left = r2.right + checkBoxSize;
r2.right = r.right;
- queueDDText(getTextData(dd), getTextColor(dd), r2, str, false, false, _widgets[kDDCheckboxDefault]->_textAlignH, _widgets[dd]->_textAlignV);
+ queueDDText(getTextData(dd), getTextColor(dd), r2, str, true, false, _widgets[kDDCheckboxDefault]->_textAlignH, _widgets[dd]->_textAlignV);
}
void ThemeEngine::drawRadiobutton(const Common::Rect &r, const Common::String &str, bool checked, WidgetStateInfo state) {
@@ -929,7 +932,7 @@ void ThemeEngine::drawRadiobutton(const Common::Rect &r, const Common::String &s
r2.left = r2.right + checkBoxSize;
r2.right = r.right;
- queueDDText(getTextData(dd), getTextColor(dd), r2, str, false, false, _widgets[kDDRadiobuttonDefault]->_textAlignH, _widgets[dd]->_textAlignV);
+ queueDDText(getTextData(dd), getTextColor(dd), r2, str, true, false, _widgets[kDDRadiobuttonDefault]->_textAlignH, _widgets[dd]->_textAlignV);
}
void ThemeEngine::drawSlider(const Common::Rect &r, int width, WidgetStateInfo state) {
@@ -971,7 +974,7 @@ void ThemeEngine::drawScrollbar(const Common::Rect &r, int sliderY, int sliderHe
r2.left += 1;
r2.right -= 1;
r2.top += sliderY;
- r2.bottom = r2.top + sliderHeight - 1;
+ r2.bottom = r2.top + sliderHeight;
r2.top += r.width() / 5;
r2.bottom -= r.width() / 5;
@@ -1370,6 +1373,10 @@ int ThemeEngine::getCharWidth(byte c, FontStyle font) const {
return ready() ? _texts[fontStyleToData(font)]->_fontPtr->getCharWidth(c) : 0;
}
+int ThemeEngine::getKerningOffset(byte left, byte right, FontStyle font) const {
+ return ready() ? _texts[fontStyleToData(font)]->_fontPtr->getKerningOffset(left, right) : 0;
+}
+
TextData ThemeEngine::getTextData(DrawData ddId) const {
return _widgets[ddId] ? (TextData)_widgets[ddId]->_textDataId : kTextDataNone;
}
@@ -1390,66 +1397,90 @@ DrawData ThemeEngine::parseDrawDataId(const Common::String &name) const {
* External data loading
*********************************************************/
-const Graphics::Font *ThemeEngine::loadFontFromArchive(const Common::String &filename) {
- Common::SeekableReadStream *stream = 0;
- const Graphics::Font *font = 0;
+const Graphics::Font *ThemeEngine::loadScalableFont(const Common::String &filename, const Common::String &charset, const int pointsize, Common::String &name) {
+#ifdef USE_FREETYPE2
+ name = Common::String::format("%s-%s@%d", filename.c_str(), charset.c_str(), pointsize);
- if (_themeArchive)
- stream = _themeArchive->createReadStreamForMember(filename);
- if (stream) {
- font = Graphics::BdfFont::loadFont(*stream);
- delete stream;
- }
+ // Try already loaded fonts.
+ const Graphics::Font *font = FontMan.getFontByName(name);
+ if (font)
+ return font;
- return font;
-}
+ Common::ArchiveMemberList members;
+ _themeFiles.listMatchingMembers(members, filename);
-const Graphics::Font *ThemeEngine::loadCachedFontFromArchive(const Common::String &filename) {
- Common::SeekableReadStream *stream = 0;
- const Graphics::Font *font = 0;
+ for (Common::ArchiveMemberList::const_iterator i = members.begin(), end = members.end(); i != end; ++i) {
+ Common::SeekableReadStream *stream = (*i)->createReadStream();
+ if (stream) {
+ font = Graphics::loadTTFFont(*stream, pointsize, false,
+#ifdef USE_TRANSLATION
+ TransMan.getCharsetMapping()
+#else
+ 0
+#endif
+ );
+ delete stream;
- if (_themeArchive)
- stream = _themeArchive->createReadStreamForMember(filename);
- if (stream) {
- font = Graphics::BdfFont::loadFromCache(*stream);
- delete stream;
+ if (font)
+ return font;
+ }
}
-
- return font;
+#endif
+ return 0;
}
-const Graphics::Font *ThemeEngine::loadFont(const Common::String &filename) {
- const Graphics::Font *font = 0;
- Common::String cacheFilename = genCacheFilename(filename);
- Common::File fontFile;
+const Graphics::Font *ThemeEngine::loadFont(const Common::String &filename, Common::String &name) {
+ name = filename;
- if (!cacheFilename.empty()) {
- if (fontFile.open(cacheFilename)) {
- font = Graphics::BdfFont::loadFromCache(fontFile);
- }
+ // Try already loaded fonts.
+ const Graphics::Font *font = FontMan.getFontByName(name);
+ if (font)
+ return font;
- if (font)
- return font;
+ Common::ArchiveMemberList members;
+ const Common::String cacheFilename(genCacheFilename(filename));
+ _themeFiles.listMatchingMembers(members, cacheFilename);
+ _themeFiles.listMatchingMembers(members, filename);
- if ((font = loadCachedFontFromArchive(cacheFilename)))
- return font;
- }
+ for (Common::ArchiveMemberList::const_iterator i = members.begin(), end = members.end(); i != end; ++i) {
+ Common::SeekableReadStream *stream = (*i)->createReadStream();
+ if (stream) {
+ if ((*i)->getName().equalsIgnoreCase(cacheFilename)) {
+ font = Graphics::BdfFont::loadFromCache(*stream);
+ } else {
+ font = Graphics::BdfFont::loadFont(*stream);
+ if (font && !cacheFilename.empty()) {
+ if (!Graphics::BdfFont::cacheFontData(*(const Graphics::BdfFont *)font, cacheFilename))
+ warning("Couldn't create cache file for font '%s'", filename.c_str());
+ }
+ }
+ delete stream;
- // normal open
- if (fontFile.open(filename)) {
- font = Graphics::BdfFont::loadFont(fontFile);
+ if (font)
+ return font;
+ }
}
- if (!font) {
- font = loadFontFromArchive(filename);
- }
+ return 0;
+}
+const Graphics::Font *ThemeEngine::loadFont(const Common::String &filename, const Common::String &scalableFilename, const Common::String &charset, const int pointsize, const bool makeLocalizedFont) {
+ Common::String fontName;
+
+ const Graphics::Font *font = 0;
+
+ // Prefer scalable fonts over non-scalable fonts
+ font = loadScalableFont(scalableFilename, charset, pointsize, fontName);
+ if (!font)
+ font = loadFont(filename, fontName);
+
+ // If the font is successfully loaded store it in the font manager.
if (font) {
- if (!cacheFilename.empty()) {
- if (!Graphics::BdfFont::cacheFontData(*(const Graphics::BdfFont *)font, cacheFilename)) {
- warning("Couldn't create cache file for font '%s'", filename.c_str());
- }
- }
+ FontMan.assignFontToName(fontName, font);
+ // If this font should be the new default localized font, we set it up
+ // for that.
+ if (makeLocalizedFont)
+ FontMan.setLocalizedFont(fontName);
}
return font;
diff --git a/gui/ThemeEngine.h b/gui/ThemeEngine.h
index 5fbea7e301..f041f85ab9 100644
--- a/gui/ThemeEngine.h
+++ b/gui/ThemeEngine.h
@@ -35,7 +35,7 @@
#include "graphics/pixelformat.h"
-#define SCUMMVM_THEME_VERSION_STR "SCUMMVM_STX0.8.3"
+#define SCUMMVM_THEME_VERSION_STR "SCUMMVM_STX0.8.8"
class OSystem;
@@ -228,6 +228,7 @@ public:
static const char *const kImageLogo; ///< ScummVM logo used in the launcher
static const char *const kImageLogoSmall; ///< ScummVM logo used in the GMM
static const char *const kImageSearch; ///< Search tool image used in the launcher
+ static const char *const kImageEraser; ///< Clear input image used in the launcher
/**
* Graphics mode enumeration.
@@ -309,6 +310,8 @@ public:
int getCharWidth(byte c, FontStyle font = kFontStyleBold) const;
+ int getKerningOffset(byte left, byte right, FontStyle font = kFontStyleBold) const;
+
//@}
@@ -410,10 +413,12 @@ public:
* Interface for the ThemeParser class: Loads a font to use on the GUI from the given
* filename.
*
- * @param fontName Identifier name for the font.
- * @param file Name of the font file.
+ * @param fextId Identifier name for the font.
+ * @param file Filename of the non-scalable font version.
+ * @param scalableFile Filename of the scalable version. (Optional)
+ * @param pointsize Point size for the scalable font. (Optional)
*/
- bool addFont(TextData textId, const Common::String &file);
+ bool addFont(TextData textId, const Common::String &file, const Common::String &scalableFile, const int pointsize);
/**
* Interface for the ThemeParser class: adds a text color value.
@@ -535,10 +540,10 @@ protected:
*/
void unloadTheme();
- const Graphics::Font *loadFont(const Common::String &filename);
- const Graphics::Font *loadFontFromArchive(const Common::String &filename);
- const Graphics::Font *loadCachedFontFromArchive(const Common::String &filename);
+ const Graphics::Font *loadScalableFont(const Common::String &filename, const Common::String &charset, const int pointsize, Common::String &name);
+ const Graphics::Font *loadFont(const Common::String &filename, Common::String &name);
Common::String genCacheFilename(const Common::String &filename) const;
+ const Graphics::Font *loadFont(const Common::String &filename, const Common::String &scalableFilename, const Common::String &charset, const int pointsize, const bool makeLocalizedFont);
/**
* Actual Dirty Screen handling function.
@@ -657,6 +662,7 @@ protected:
Common::String _themeId;
Common::String _themeFile;
Common::Archive *_themeArchive;
+ Common::SearchSet _themeFiles;
bool _useCursor;
int _cursorHotspotX, _cursorHotspotY;
diff --git a/gui/ThemeParser.cpp b/gui/ThemeParser.cpp
index db45b5a995..9ccdedd564 100644
--- a/gui/ThemeParser.cpp
+++ b/gui/ThemeParser.cpp
@@ -176,8 +176,15 @@ bool ThemeParser::parserCallback_font(ParserNode *node) {
return true;
}
+ // Default to a point size of 12.
+ int pointsize = 12;
+ if (node->values.contains("point_size")) {
+ if (sscanf(node->values["point_size"].c_str(), "%d", &pointsize) != 1 || pointsize <= 0)
+ return parserError(Common::String::format("Font \"%s\" has invalid point size \"%s\"", node->values["id"].c_str(), node->values["point_size"].c_str()));
+ }
+
TextData textDataId = parseTextDataId(node->values["id"]);
- if (!_theme->addFont(textDataId, node->values["file"]))
+ if (!_theme->addFont(textDataId, node->values["file"], node->values["scalable_file"], pointsize))
return parserError("Error loading Font in theme engine.");
return true;
@@ -379,7 +386,7 @@ bool ThemeParser::parseDrawStep(ParserNode *stepNode, Graphics::DrawStep *drawst
* theme description format.
* @param force Sets if the key is optional or necessary.
*/
-#define __PARSER_ASSIGN_INT(struct_name, key_name, force) \
+#define PARSER_ASSIGN_INT(struct_name, key_name, force) \
if (stepNode->values.contains(key_name)) { \
if (!parseIntegerKey(stepNode->values[key_name], 1, &x)) \
return parserError("Error parsing key value for '" + Common::String(key_name) + "'."); \
@@ -398,7 +405,7 @@ bool ThemeParser::parseDrawStep(ParserNode *stepNode, Graphics::DrawStep *drawst
* @param key_name Name as STRING of the key identifier as it appears in the
* theme description format.
*/
-#define __PARSER_ASSIGN_RGB(struct_name, key_name) \
+#define PARSER_ASSIGN_RGB(struct_name, key_name) \
if (stepNode->values.contains(key_name)) { \
val = stepNode->values[key_name]; \
if (_palette.contains(val)) { \
@@ -415,16 +422,16 @@ bool ThemeParser::parseDrawStep(ParserNode *stepNode, Graphics::DrawStep *drawst
drawstep->struct_name.set = true; \
}
- __PARSER_ASSIGN_INT(stroke, "stroke", false);
- __PARSER_ASSIGN_INT(bevel, "bevel", false);
- __PARSER_ASSIGN_INT(shadow, "shadow", false);
- __PARSER_ASSIGN_INT(factor, "gradient_factor", false);
+ PARSER_ASSIGN_INT(stroke, "stroke", false);
+ PARSER_ASSIGN_INT(bevel, "bevel", false);
+ PARSER_ASSIGN_INT(shadow, "shadow", false);
+ PARSER_ASSIGN_INT(factor, "gradient_factor", false);
- __PARSER_ASSIGN_RGB(fgColor, "fg_color");
- __PARSER_ASSIGN_RGB(bgColor, "bg_color");
- __PARSER_ASSIGN_RGB(gradColor1, "gradient_start");
- __PARSER_ASSIGN_RGB(gradColor2, "gradient_end");
- __PARSER_ASSIGN_RGB(bevelColor, "bevel_color");
+ PARSER_ASSIGN_RGB(fgColor, "fg_color");
+ PARSER_ASSIGN_RGB(bgColor, "bg_color");
+ PARSER_ASSIGN_RGB(gradColor1, "gradient_start");
+ PARSER_ASSIGN_RGB(gradColor2, "gradient_end");
+ PARSER_ASSIGN_RGB(bevelColor, "bevel_color");
if (functionSpecific) {
assert(stepNode->values.contains("func"));
@@ -444,7 +451,7 @@ bool ThemeParser::parseDrawStep(ParserNode *stepNode, Graphics::DrawStep *drawst
if (stepNode->values.contains("radius") && stepNode->values["radius"] == "auto") {
drawstep->radius = 0xFF;
} else {
- __PARSER_ASSIGN_INT(radius, "radius", true);
+ PARSER_ASSIGN_INT(radius, "radius", true);
}
}
@@ -544,9 +551,19 @@ bool ThemeParser::parseDrawStep(ParserNode *stepNode, Graphics::DrawStep *drawst
else
return parserError("'" + stepNode->values["fill"] + "' is not a valid fill mode for a shape.");
}
+
+ if (stepNode->values.contains("padding")) {
+ val = stepNode->values["padding"];
+ int pr, pt, pl, pb;
+ if (parseIntegerKey(val, 4, &pl, &pt, &pr, &pb))
+ drawstep->padding.left = pl,
+ drawstep->padding.top = pt,
+ drawstep->padding.right = pr,
+ drawstep->padding.bottom = pb;
+ }
-#undef __PARSER_ASSIGN_INT
-#undef __PARSER_ASSIGN_RGB
+#undef PARSER_ASSIGN_INT
+#undef PARSER_ASSIGN_RGB
return true;
}
diff --git a/gui/ThemeParser.h b/gui/ThemeParser.h
index 39a951e007..4b7e88cbf3 100644
--- a/gui/ThemeParser.h
+++ b/gui/ThemeParser.h
@@ -65,6 +65,8 @@ protected:
XML_PROP(id, true)
XML_PROP(file, true)
XML_PROP(resolution, false)
+ XML_PROP(scalable_file, false)
+ XML_PROP(point_size, false)
KEY_END()
XML_KEY(text_color)
@@ -138,6 +140,7 @@ protected:
XML_PROP(height, false)
XML_PROP(xpos, false)
XML_PROP(ypos, false)
+ XML_PROP(padding, false)
XML_PROP(orientation, false)
XML_PROP(file, false)
KEY_END()
diff --git a/gui/about.cpp b/gui/about.cpp
index 00dbc5fe0b..03be1f8992 100644
--- a/gui/about.cpp
+++ b/gui/about.cpp
@@ -54,7 +54,7 @@ enum {
static const char *copyright_text[] = {
"",
-"C0""Copyright (C) 2001-2011 The ScummVM project",
+"C0""Copyright (C) 2001-2012 The ScummVM project",
"C0""http://www.scummvm.org",
"",
"C0""ScummVM is the legal property of its developers, whose names are too numerous to list here. Please refer to the COPYRIGHT file distributed with this binary.",
diff --git a/gui/browser_osx.mm b/gui/browser_osx.mm
index 017b31b9a8..b8aa7c50ee 100644
--- a/gui/browser_osx.mm
+++ b/gui/browser_osx.mm
@@ -62,11 +62,7 @@ int BrowserDialog::runModal() {
NSOpenPanel * panel = [NSOpenPanel openPanel];
[panel setCanChooseDirectories:YES];
if ([panel runModalForTypes:nil] == NSOKButton) {
-#ifdef __POWERPC__
- const char *filename = [[panel filename] cString];
-#else
- const char *filename = [[panel filename] cStringUsingEncoding:NSUTF8StringEncoding];
-#endif
+ const char *filename = [[panel filename] UTF8String];
_choice = Common::FSNode(filename);
choiceMade = true;
}
diff --git a/gui/console.cpp b/gui/console.cpp
index dc2c5c4f33..49e2fccd98 100644
--- a/gui/console.cpp
+++ b/gui/console.cpp
@@ -245,6 +245,8 @@ void ConsoleDialog::handleTickle() {
} else
draw();
}
+
+ _scrollBar->handleTickle();
}
void ConsoleDialog::handleMouseWheel(int x, int y, int direction) {
diff --git a/gui/credits.h b/gui/credits.h
index 3a7e77c146..154f577fba 100644
--- a/gui/credits.h
+++ b/gui/credits.h
@@ -39,6 +39,7 @@ static const char *credits[] = {
"C0""Pawel Kolodziejski",
"C2""Codecs, iMUSE, Smush, etc.",
"C0""Gregory Montoir",
+"C2""(retired)",
"C0""Eugene Sandulenko",
"C2""FT INSANE, MM NES, MM C64, game detection, Herc/CGA",
"C0""Ludvig Strigeus",
@@ -49,6 +50,7 @@ static const char *credits[] = {
"C2""(retired)",
"C0""Travis Howell",
"C0""Gregory Montoir",
+"C2""(retired)",
"C0""Eugene Sandulenko",
"",
"C1""AGI",
@@ -81,9 +83,13 @@ static const char *credits[] = {
"C2""(retired)",
"C0""Pawel Kolodziejski",
"C0""Gregory Montoir",
+"C2""(retired)",
"C0""Kari Salminen",
"C0""Eugene Sandulenko",
"",
+"C1""Composer",
+"C0""Alyssa Milburn",
+"",
"C1""CruisE",
"C0""Paul Gilbert",
"C0""Vincent Hamm",
@@ -101,6 +107,7 @@ static const char *credits[] = {
"C0""Torbj\366rn Andersson",
"C0""Bertrand Augereau",
"C0""Vladimir Menshakov",
+"C2""(retired)",
"",
"C1""Gob",
"C0""Torbj\366rn Andersson",
@@ -124,6 +131,7 @@ static const char *credits[] = {
"C0""Oystein Eftevaag",
"C0""Florian Kagerer",
"C0""Gregory Montoir",
+"C2""(retired)",
"C0""Johannes Schickel",
"",
"C1""Lastexpress",
@@ -134,12 +142,6 @@ static const char *credits[] = {
"C1""Lure",
"C0""Paul Gilbert",
"",
-"C1""M4",
-"C0""Torbj\366rn Andersson",
-"C0""Paul Gilbert",
-"C0""Benjamin Haisch",
-"C0""Filippos Karapetis",
-"",
"C1""MADE",
"C0""Benjamin Haisch",
"C0""Filippos Karapetis",
@@ -159,10 +161,13 @@ static const char *credits[] = {
"C0""David Eriksson",
"C2""(retired)",
"C0""Gregory Montoir",
+"C2""(retired)",
"C0""Joost Peters",
"",
"C1""SAGA",
"C0""Torbj\366rn Andersson",
+"C0""Daniel Balsom",
+"C2""Original engine reimplementation author (retired)",
"C0""Filippos Karapetis",
"C0""Andrew Kurushin",
"C0""Eugene Sandulenko",
@@ -214,6 +219,7 @@ static const char *credits[] = {
"C0""Robert Megone",
"C2""Help with callback rewriting",
"C0""Vladimir Menshakov",
+"C2""(retired)",
"",
"C1""Tinsel",
"C0""Torbj\366rn Andersson",
@@ -231,6 +237,7 @@ static const char *credits[] = {
"",
"C1""Touch\351",
"C0""Gregory Montoir",
+"C2""(retired)",
"",
"C1""TsAGE",
"C0""Arnaud Boutonn\351",
@@ -238,6 +245,7 @@ static const char *credits[] = {
"",
"C1""Tucker",
"C0""Gregory Montoir",
+"C2""(retired)",
"",
"",
"C1""Backend Teams",
@@ -491,6 +499,7 @@ static const char *credits[] = {
"",
"C1""Spanish",
"C0""Tom\341s Maidagan",
+"C0""Jordi Vilalta Prat",
"",
"C1""Swedish",
"C0""Hampus Flink",
@@ -560,6 +569,8 @@ static const char *credits[] = {
"C2""Final MI1 CD music support, initial Ogg Vorbis support",
"C0""Andr\351 Souza",
"C2""SDL-based OpenGL renderer",
+"C0""Tom Frost",
+"C2""WebOS port contributions",
"",
"C1""FreeSCI Contributors",
"C0""Francois-R Boyer",
@@ -642,6 +653,8 @@ static const char *credits[] = {
"",
"C1""Special thanks to",
"",
+"C0""Daniel Balsom",
+"C2""For the original Reinherit (SAGA) code",
"C0""Sander Buskens",
"C2""For his work on the initial reversing of Monkey2",
"C0""Canadacow",
@@ -674,6 +687,8 @@ static const char *credits[] = {
"C2""For additional work on the original MT-32 emulator",
"C0""James Woodcock",
"C2""Soundtrack enhancements",
+"C0""Some icons by Yusuke Kamiyamane",
+"C0""",
"C0""Tony Warriner and everyone at Revolution Software Ltd. for sharing with us the source of some of their brilliant games, allowing us to release Beneath a Steel Sky as freeware... and generally being supportive above and beyond the call of duty.",
"C0""",
"C0""John Passfield and Steve Stamatiadis for sharing the source of their classic title, Flight of the Amazon Queen and also being incredibly supportive.",
diff --git a/gui/debugger.cpp b/gui/debugger.cpp
index 3973583d38..26e62dc1d9 100644
--- a/gui/debugger.cpp
+++ b/gui/debugger.cpp
@@ -247,6 +247,12 @@ bool Debugger::parseCommand(const char *inputOrig) {
*(int32 *)_dvars[i].variable = atoi(param[1]);
DebugPrintf("(int)%s = %d\n", param[0], *(int32 *)_dvars[i].variable);
break;
+ case DVAR_BOOL:
+ if (Common::parseBool(param[1], *(bool *)_dvars[i].variable))
+ DebugPrintf("(bool)%s = %s\n", param[0], *(bool *)_dvars[i].variable ? "true" : "false");
+ else
+ DebugPrintf("Invalid value for boolean variable. Valid values are \"true\", \"false\", \"1\", \"0\", \"yes\", \"no\"\n");
+ break;
// Integer Array
case DVAR_INTARRAY: {
const char *chr = strchr(param[0], '[');
@@ -278,6 +284,9 @@ bool Debugger::parseCommand(const char *inputOrig) {
case DVAR_INT:
DebugPrintf("(int)%s = %d\n", param[0], *(const int32 *)_dvars[i].variable);
break;
+ case DVAR_BOOL:
+ DebugPrintf("(bool)%s = %s\n", param[0], *(const bool *)_dvars[i].variable ? "true" : "false");
+ break;
// Integer array
case DVAR_INTARRAY: {
const char *chr = strchr(param[0], '[');
diff --git a/gui/dialog.cpp b/gui/dialog.cpp
index 2ec8641257..fd15ba5e09 100644
--- a/gui/dialog.cpp
+++ b/gui/dialog.cpp
@@ -75,7 +75,6 @@ int Dialog::runModal() {
}
void Dialog::open() {
-
_result = 0;
_visible = true;
g_gui.openDialog(this);
@@ -335,25 +334,7 @@ void Dialog::removeWidget(Widget *del) {
if (del == _dragWidget)
_dragWidget = NULL;
- Widget *w = _firstWidget;
-
- if (del == _firstWidget) {
- Widget *del_next = del->_next;
- del->_next = 0;
- _firstWidget = del_next;
- return;
- }
-
- w = _firstWidget;
- while (w) {
- if (w->_next == del) {
- Widget *del_next = del->_next;
- del->_next = 0;
- w->_next = del_next;
- return;
- }
- w = w->_next;
- }
+ GuiObject::removeWidget(del);
}
} // End of namespace GUI
diff --git a/gui/gui-manager.cpp b/gui/gui-manager.cpp
index 212d68430c..4fa60bfe07 100644
--- a/gui/gui-manager.cpp
+++ b/gui/gui-manager.cpp
@@ -103,30 +103,42 @@ GuiManager::~GuiManager() {
void GuiManager::initKeymap() {
using namespace Common;
- bool tmp;
Keymapper *mapper = _system->getEventManager()->getKeymapper();
// Do not try to recreate same keymap over again
- if (mapper->getKeymap("gui", tmp) != 0)
+ if (mapper->getKeymap(kGuiKeymapName) != 0)
return;
Action *act;
- Keymap *guiMap = new Keymap("gui");
+ Keymap *guiMap = new Keymap(kGuiKeymapName);
- act = new Action(guiMap, "CLOS", _("Close"), kGenericActionType, kStartKeyType);
+ act = new Action(guiMap, "CLOS", _("Close"));
act->addKeyEvent(KeyState(KEYCODE_ESCAPE, ASCII_ESCAPE, 0));
act = new Action(guiMap, "CLIK", _("Mouse click"));
act->addLeftClickEvent();
- act = new Action(guiMap, "VIRT", _("Display keyboard"), kVirtualKeyboardActionType);
- act->addKeyEvent(KeyState(KEYCODE_F7, ASCII_F7, 0));
+#ifdef ENABLE_VKEYBD
+ act = new Action(guiMap, "VIRT", _("Display keyboard"));
+ act->addEvent(EVENT_VIRTUAL_KEYBOARD);
+#endif
+
+ act = new Action(guiMap, "REMP", _("Remap keys"));
+ act->addEvent(EVENT_KEYMAPPER_REMAP);
- act = new Action(guiMap, "REMP", _("Remap keys"), kKeyRemapActionType);
- act->addKeyEvent(KeyState(KEYCODE_F8, ASCII_F8, 0));
+ act = new Action(guiMap, "FULS", _("Toggle FullScreen"));
+ act->addKeyEvent(KeyState(KEYCODE_RETURN, ASCII_RETURN, KBD_ALT));
mapper->addGlobalKeymap(guiMap);
}
+
+void GuiManager::pushKeymap() {
+ _system->getEventManager()->getKeymapper()->pushKeymap(Common::kGuiKeymapName);
+}
+
+void GuiManager::popKeymap() {
+ _system->getEventManager()->getKeymapper()->popKeymap(Common::kGuiKeymapName);
+}
#endif
bool GuiManager::loadNewTheme(Common::String id, ThemeEngine::GraphicsMode gfx, bool forced) {
@@ -176,7 +188,7 @@ bool GuiManager::loadNewTheme(Common::String id, ThemeEngine::GraphicsMode gfx,
}
// refresh all dialogs
- for (int i = 0; i < _dialogStack.size(); ++i)
+ for (DialogStack::size_type i = 0; i < _dialogStack.size(); ++i)
_dialogStack[i]->reflowLayout();
// We need to redraw immediately. Otherwise
@@ -190,7 +202,6 @@ bool GuiManager::loadNewTheme(Common::String id, ThemeEngine::GraphicsMode gfx,
}
void GuiManager::redraw() {
- int i;
ThemeEngine::ShadingStyle shading;
if (_redrawStatus == kRedrawDisabled || _dialogStack.empty())
@@ -211,7 +222,7 @@ void GuiManager::redraw() {
_theme->clearAll();
_theme->openDialog(true, ThemeEngine::kShadingNone);
- for (i = 0; i < _dialogStack.size() - 1; i++)
+ for (DialogStack::size_type i = 0; i < _dialogStack.size() - 1; i++)
_dialogStack[i]->drawDialog();
_theme->finishBuffering();
@@ -270,19 +281,9 @@ void GuiManager::runLoop() {
uint32 lastRedraw = 0;
const uint32 waitTime = 1000 / 45;
-#ifdef ENABLE_KEYMAPPER
- // Due to circular reference with event manager and GUI
- // we cannot init keymap on the GUI creation. Thus, let's
- // try to do it on every launch, checking whether the
- // map is already existing
- initKeymap();
-
- eventMan->getKeymapper()->pushKeymap("gui");
-#endif
-
bool tooltipCheck = false;
- while (!_dialogStack.empty() && activeDialog == getTopDialog()) {
+ while (!_dialogStack.empty() && activeDialog == getTopDialog() && !eventMan->shouldQuit()) {
redraw();
// Don't "tickle" the dialog until the theme has had a chance
@@ -361,8 +362,6 @@ void GuiManager::runLoop() {
case Common::EVENT_WHEELDOWN:
activeDialog->handleMouseWheel(mouse.x, mouse.y, 1);
break;
- case Common::EVENT_QUIT:
- return;
case Common::EVENT_SCREEN_CHANGED:
screenChange();
break;
@@ -391,9 +390,16 @@ void GuiManager::runLoop() {
_system->delayMillis(10);
}
-#ifdef ENABLE_KEYMAPPER
- eventMan->getKeymapper()->popKeymap();
-#endif
+ // WORKAROUND: When quitting we might not properly close the dialogs on
+ // the dialog stack, thus we do this here to avoid any problems.
+ // This is most noticable in bug #3481395 "LAUNCHER: Can't quit from unsupported game dialog".
+ // It seems that Dialog::runModal never removes the dialog from the dialog
+ // stack, thus if the dialog does not call Dialog::close to close itself
+ // it will never be removed. Since we can have multiple run loops being
+ // called we cannot rely on catching EVENT_QUIT in the event loop above,
+ // since it would only catch it for the top run loop.
+ if (eventMan->shouldQuit() && activeDialog == getTopDialog())
+ getTopDialog()->close();
if (didSaveState) {
_theme->disable();
@@ -405,6 +411,10 @@ void GuiManager::runLoop() {
#pragma mark -
void GuiManager::saveState() {
+#ifdef ENABLE_KEYMAPPER
+ initKeymap();
+ pushKeymap();
+#endif
// Backup old cursor
_lastClick.x = _lastClick.y = 0;
_lastClick.time = 0;
@@ -414,6 +424,9 @@ void GuiManager::saveState() {
}
void GuiManager::restoreState() {
+#ifdef ENABLE_KEYMAPPER
+ popKeymap();
+#endif
if (_useStdCursor) {
CursorMan.popCursor();
CursorMan.popCursorPalette();
@@ -501,7 +514,7 @@ void GuiManager::screenChange() {
_theme->refresh();
// refresh all dialogs
- for (int i = 0; i < _dialogStack.size(); ++i) {
+ for (DialogStack::size_type i = 0; i < _dialogStack.size(); ++i) {
_dialogStack[i]->reflowLayout();
}
// We need to redraw immediately. Otherwise
diff --git a/gui/gui-manager.h b/gui/gui-manager.h
index 10f9e6a29f..49542fd001 100644
--- a/gui/gui-manager.h
+++ b/gui/gui-manager.h
@@ -81,6 +81,7 @@ public:
int getFontHeight(ThemeEngine::FontStyle style = ThemeEngine::kFontStyleBold) const { return _theme->getFontHeight(style); }
int getStringWidth(const Common::String &str, ThemeEngine::FontStyle style = ThemeEngine::kFontStyleBold) const { return _theme->getStringWidth(str, style); }
int getCharWidth(byte c, ThemeEngine::FontStyle style = ThemeEngine::kFontStyleBold) const { return _theme->getCharWidth(c, style); }
+ int getKerningOffset(byte left, byte right, ThemeEngine::FontStyle font = ThemeEngine::kFontStyleBold) const { return _theme->getKerningOffset(left, right, font); }
/**
* Tell the GuiManager to check whether the screen resolution has changed.
@@ -126,6 +127,8 @@ protected:
byte _cursor[2048];
void initKeymap();
+ void pushKeymap();
+ void popKeymap();
void saveState();
void restoreState();
diff --git a/gui/launcher.cpp b/gui/launcher.cpp
index 8e94c140a4..a3e4925848 100644
--- a/gui/launcher.cpp
+++ b/gui/launcher.cpp
@@ -24,6 +24,7 @@
#include "common/config-manager.h"
#include "common/events.h"
#include "common/fs.h"
+#include "common/gui_options.h"
#include "common/util.h"
#include "common/system.h"
#include "common/translation.h"
@@ -71,8 +72,10 @@ enum {
kCmdChooseSoundFontCmd = 'chsf',
kCmdExtraBrowser = 'PEXT',
+ kCmdExtraPathClear = 'PEXC',
kCmdGameBrowser = 'PGME',
- kCmdSaveBrowser = 'PSAV'
+ kCmdSaveBrowser = 'PSAV',
+ kCmdSavePathClear = 'PSAC'
};
/*
@@ -88,7 +91,7 @@ public:
protected:
bool tryInsertChar(byte c, int pos) {
- if (isalnum(c) || c == '-' || c == '_') {
+ if (Common::isAlnum(c) || c == '-' || c == '_') {
_editString.insertChar(c, pos);
return true;
}
@@ -129,6 +132,8 @@ protected:
StaticTextWidget *_gamePathWidget;
StaticTextWidget *_extraPathWidget;
StaticTextWidget *_savePathWidget;
+ ButtonWidget *_extraPathClearButton;
+ ButtonWidget *_savePathClearButton;
StaticTextWidget *_langPopUpDesc;
PopUpWidget *_langPopUp;
@@ -245,32 +250,30 @@ EditGameDialog::EditGameDialog(const String &domain, const String &desc)
//
// 5) The MIDI tab
//
- tab->addTab(_("MIDI"));
+ if (!_guioptions.contains(GUIO_NOMIDI)) {
+ tab->addTab(_("MIDI"));
- if (g_system->getOverlayWidth() > 320)
- _globalMIDIOverride = new CheckboxWidget(tab, "GameOptions_MIDI.EnableTabCheckbox", _("Override global MIDI settings"), 0, kCmdGlobalMIDIOverride);
- else
- _globalMIDIOverride = new CheckboxWidget(tab, "GameOptions_MIDI.EnableTabCheckbox", _c("Override global MIDI settings", "lowres"), 0, kCmdGlobalMIDIOverride);
-
- if (_guioptions.contains(GUIO_NOMIDI))
- _globalMIDIOverride->setEnabled(false);
+ if (g_system->getOverlayWidth() > 320)
+ _globalMIDIOverride = new CheckboxWidget(tab, "GameOptions_MIDI.EnableTabCheckbox", _("Override global MIDI settings"), 0, kCmdGlobalMIDIOverride);
+ else
+ _globalMIDIOverride = new CheckboxWidget(tab, "GameOptions_MIDI.EnableTabCheckbox", _c("Override global MIDI settings", "lowres"), 0, kCmdGlobalMIDIOverride);
- addMIDIControls(tab, "GameOptions_MIDI.");
+ addMIDIControls(tab, "GameOptions_MIDI.");
+ }
//
// 6) The MT-32 tab
//
- tab->addTab(_("MT-32"));
-
- if (g_system->getOverlayWidth() > 320)
- _globalMT32Override = new CheckboxWidget(tab, "GameOptions_MT32.EnableTabCheckbox", _("Override global MT-32 settings"), 0, kCmdGlobalMT32Override);
- else
- _globalMT32Override = new CheckboxWidget(tab, "GameOptions_MT32.EnableTabCheckbox", _c("Override global MT-32 settings", "lowres"), 0, kCmdGlobalMT32Override);
+ if (!_guioptions.contains(GUIO_NOMIDI)) {
+ tab->addTab(_("MT-32"));
- //if (_guioptions.contains(GUIO_NOMIDI))
- // _globalMT32Override->setEnabled(false);
+ if (g_system->getOverlayWidth() > 320)
+ _globalMT32Override = new CheckboxWidget(tab, "GameOptions_MT32.EnableTabCheckbox", _("Override global MT-32 settings"), 0, kCmdGlobalMT32Override);
+ else
+ _globalMT32Override = new CheckboxWidget(tab, "GameOptions_MT32.EnableTabCheckbox", _c("Override global MT-32 settings", "lowres"), 0, kCmdGlobalMT32Override);
- addMT32Controls(tab, "GameOptions_MT32.");
+ addMT32Controls(tab, "GameOptions_MT32.");
+ }
//
// 7) The Paths tab
@@ -297,6 +300,8 @@ EditGameDialog::EditGameDialog(const String &domain, const String &desc)
new ButtonWidget(tab, "GameOptions_Paths.Extrapath", _c("Extra Path:", "lowres"), _("Specifies path to additional data used the game"), kCmdExtraBrowser);
_extraPathWidget = new StaticTextWidget(tab, "GameOptions_Paths.ExtrapathText", extraPath, _("Specifies path to additional data used the game"));
+ _extraPathClearButton = addClearButton(tab, "GameOptions_Paths.ExtraPathClearButton", kCmdExtraPathClear);
+
// GUI: Button + Label for the save path
if (g_system->getOverlayWidth() > 320)
new ButtonWidget(tab, "GameOptions_Paths.Savepath", _("Save Path:"), _("Specifies where your savegames are put"), kCmdSaveBrowser);
@@ -304,6 +309,9 @@ EditGameDialog::EditGameDialog(const String &domain, const String &desc)
new ButtonWidget(tab, "GameOptions_Paths.Savepath", _c("Save Path:", "lowres"), _("Specifies where your savegames are put"), kCmdSaveBrowser);
_savePathWidget = new StaticTextWidget(tab, "GameOptions_Paths.SavepathText", savePath, _("Specifies where your savegames are put"));
+ _savePathClearButton = addClearButton(tab, "GameOptions_Paths.SavePathClearButton", kCmdSavePathClear);
+
+
// Activate the first tab
tab->setActiveTab(0);
_tabWidget = tab;
@@ -350,14 +358,18 @@ void EditGameDialog::open() {
ConfMan.hasKey("speech_volume", _domain);
_globalVolumeOverride->setState(e);
- e = ConfMan.hasKey("soundfont", _domain) ||
- ConfMan.hasKey("multi_midi", _domain) ||
- ConfMan.hasKey("midi_gain", _domain);
- _globalMIDIOverride->setState(e);
+ if (!_guioptions.contains(GUIO_NOMIDI)) {
+ e = ConfMan.hasKey("soundfont", _domain) ||
+ ConfMan.hasKey("multi_midi", _domain) ||
+ ConfMan.hasKey("midi_gain", _domain);
+ _globalMIDIOverride->setState(e);
+ }
- e = ConfMan.hasKey("native_mt32", _domain) ||
- ConfMan.hasKey("enable_gs", _domain);
- _globalMT32Override->setState(e);
+ if (!_guioptions.contains(GUIO_NOMIDI)) {
+ e = ConfMan.hasKey("native_mt32", _domain) ||
+ ConfMan.hasKey("enable_gs", _domain);
+ _globalMT32Override->setState(e);
+ }
// TODO: game path
@@ -403,10 +415,14 @@ void EditGameDialog::close() {
String extraPath(_extraPathWidget->getLabel());
if (!extraPath.empty() && (extraPath != _c("None", "path")))
ConfMan.set("extrapath", extraPath, _domain);
+ else
+ ConfMan.removeKey("extrapath", _domain);
String savePath(_savePathWidget->getLabel());
if (!savePath.empty() && (savePath != _("Default")))
ConfMan.set("savepath", savePath, _domain);
+ else
+ ConfMan.removeKey("savepath", _domain);
Common::Platform platform = (Common::Platform)_platformPopUp->getSelectedTag();
if (platform < 0)
@@ -503,6 +519,14 @@ void EditGameDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 dat
break;
}
+ case kCmdExtraPathClear:
+ _extraPathWidget->setLabel(_c("None", "path"));
+ break;
+
+ case kCmdSavePathClear:
+ _savePathWidget->setLabel(_("Default"));
+ break;
+
case kOKCmd: {
// Write back changes made to config object
String newDomain(_domainWidget->getEditString());
@@ -590,7 +614,7 @@ LauncherDialog::LauncherDialog()
_searchDesc = new StaticTextWidget(this, "Launcher.SearchDesc", _("Search:"));
_searchWidget = new EditTextWidget(this, "Launcher.Search", _search, 0, kSearchCmd);
- _searchClearButton = new ButtonWidget(this, "Launcher.SearchClearButton", "C", _("Clear value"), kSearchClearCmd);
+ _searchClearButton = addClearButton(this, "Launcher.SearchClearButton", kSearchClearCmd);
// Add list with game titles
_list = new ListWidget(this, "Launcher.GameList", 0, kListSearchCmd);
@@ -1061,7 +1085,7 @@ void LauncherDialog::updateButtons() {
void LauncherDialog::reflowLayout() {
#ifndef DISABLE_FANCY_THEMES
if (g_gui.xmlEval()->getVar("Globals.ShowLauncherLogo") == 1 && g_gui.theme()->supportsImages()) {
- StaticTextWidget *ver = (StaticTextWidget*)findWidget("Launcher.Version");
+ StaticTextWidget *ver = (StaticTextWidget *)findWidget("Launcher.Version");
if (ver) {
ver->setAlign((Graphics::TextAlign)g_gui.xmlEval()->getVar("Launcher.Version.Align", Graphics::kTextAlignCenter));
ver->setLabel(gScummVMVersionDate);
@@ -1072,7 +1096,7 @@ void LauncherDialog::reflowLayout() {
_logo->useThemeTransparency(true);
_logo->setGfx(g_gui.theme()->getImageSurface(ThemeEngine::kImageLogo));
} else {
- StaticTextWidget *ver = (StaticTextWidget*)findWidget("Launcher.Version");
+ StaticTextWidget *ver = (StaticTextWidget *)findWidget("Launcher.Version");
if (ver) {
ver->setAlign((Graphics::TextAlign)g_gui.xmlEval()->getVar("Launcher.Version.Align", Graphics::kTextAlignCenter));
ver->setLabel(gScummVMFullVersion);
@@ -1108,6 +1132,11 @@ void LauncherDialog::reflowLayout() {
_searchPic = 0;
}
}
+
+ removeWidget(_searchClearButton);
+ _searchClearButton->setNext(0);
+ delete _searchClearButton;
+ _searchClearButton = addClearButton(this, "Launcher.SearchClearButton", kSearchClearCmd);
#endif
_w = g_system->getOverlayWidth();
diff --git a/gui/launcher.h b/gui/launcher.h
index f27b4df202..fc0484350a 100644
--- a/gui/launcher.h
+++ b/gui/launcher.h
@@ -31,6 +31,7 @@ class BrowserDialog;
class CommandSender;
class ListWidget;
class ButtonWidget;
+class PicButtonWidget;
class GraphicsWidget;
class StaticTextWidget;
class EditTextWidget;
diff --git a/gui/object.cpp b/gui/object.cpp
index 2ec42df9d7..73c4f74d6c 100644
--- a/gui/object.cpp
+++ b/gui/object.cpp
@@ -59,4 +59,24 @@ void GuiObject::reflowLayout() {
}
}
+void GuiObject::removeWidget(Widget *del) {
+ if (del == _firstWidget) {
+ Widget *del_next = del->next();
+ del->setNext(0);
+ _firstWidget = del_next;
+ return;
+ }
+
+ Widget *w = _firstWidget;
+ while (w) {
+ if (w->next() == del) {
+ Widget *del_next = del->next();
+ del->setNext(0);
+ w->setNext(del_next);
+ return;
+ }
+ w = w->next();
+ }
+}
+
} // End of namespace GUI
diff --git a/gui/object.h b/gui/object.h
index 34ff0d47f2..bce3cd7846 100644
--- a/gui/object.h
+++ b/gui/object.h
@@ -83,6 +83,8 @@ public:
virtual void reflowLayout();
+ virtual void removeWidget(Widget *widget);
+
protected:
virtual void releaseFocus() = 0;
};
diff --git a/gui/options.cpp b/gui/options.cpp
index 67204fc343..5085f9cdd9 100644
--- a/gui/options.cpp
+++ b/gui/options.cpp
@@ -26,9 +26,12 @@
#include "gui/options.h"
#include "gui/widgets/popup.h"
#include "gui/widgets/tab.h"
+#include "gui/ThemeEval.h"
#include "common/fs.h"
#include "common/config-manager.h"
+#include "common/gui_options.h"
+#include "common/rendermode.h"
#include "common/system.h"
#include "common/textconsole.h"
#include "common/translation.h"
@@ -51,8 +54,11 @@ enum {
kChooseSoundFontCmd = 'chsf',
kClearSoundFontCmd = 'clsf',
kChooseSaveDirCmd = 'chos',
+ kSavePathClearCmd = 'clsp',
kChooseThemeDirCmd = 'chth',
+ kThemePathClearCmd = 'clth',
kChooseExtraDirCmd = 'chex',
+ kExtraPathClearCmd = 'clex',
kChoosePluginsDirCmd = 'chpl',
kChooseThemeCmd = 'chtf'
};
@@ -75,7 +81,7 @@ static const char *outputRateLabels[] = { _s("<default>"), _s("8 kHz"), _s("11kH
static const int outputRateValues[] = { 0, 8000, 11025, 22050, 44100, 48000, -1 };
OptionsDialog::OptionsDialog(const Common::String &domain, int x, int y, int w, int h)
- : Dialog(x, y, w, h), _domain(domain), _graphicsTabId(-1), _tabWidget(0) {
+ : Dialog(x, y, w, h), _domain(domain), _graphicsTabId(-1), _midiTabId(-1), _pathsTabId(-1), _tabWidget(0) {
init();
}
@@ -141,7 +147,7 @@ void OptionsDialog::init() {
_oldTheme = g_gui.theme()->getThemeId();
// Retrieve game GUI options
- _guioptions = "";
+ _guioptions.clear();
if (ConfMan.hasKey("guioptions", _domain)) {
_guioptionsString = ConfMan.get("guioptions", _domain);
_guioptions = parseGameGUIOptions(_guioptionsString);
@@ -155,7 +161,7 @@ void OptionsDialog::open() {
setResult(0);
// Retrieve game GUI options
- _guioptions = "";
+ _guioptions.clear();
if (ConfMan.hasKey("guioptions", _domain)) {
_guioptionsString = ConfMan.get("guioptions", _domain);
_guioptions = parseGameGUIOptions(_guioptionsString);
@@ -187,23 +193,38 @@ void OptionsDialog::open() {
int sel = 0;
for (int i = 0; p->code; ++p, ++i) {
if (renderMode == p->id)
- sel = i + 2;
+ sel = p->id;
}
- _renderModePopUp->setSelected(sel);
+ _renderModePopUp->setSelectedTag(sel);
}
#ifdef SMALL_SCREEN_DEVICE
_fullscreenCheckbox->setState(true);
_fullscreenCheckbox->setEnabled(false);
+ _aspectCheckbox->setState(false);
_aspectCheckbox->setEnabled(false);
#else // !SMALL_SCREEN_DEVICE
// Fullscreen setting
_fullscreenCheckbox->setState(ConfMan.getBool("fullscreen", _domain));
// Aspect ratio setting
- _aspectCheckbox->setState(ConfMan.getBool("aspect_ratio", _domain));
+ if (_guioptions.contains(GUIO_NOASPECT)) {
+ _aspectCheckbox->setState(false);
+ _aspectCheckbox->setEnabled(false);
+ } else {
+ _aspectCheckbox->setEnabled(true);
+ _aspectCheckbox->setState(ConfMan.getBool("aspect_ratio", _domain));
+ }
#endif // SMALL_SCREEN_DEVICE
- _disableDitheringCheckbox->setState(ConfMan.getBool("disable_dithering", _domain));
+
+ // EGA undithering setting
+ if (_guioptions.contains(GUIO_EGAUNDITHER) || _domain == Common::ConfigManager::kApplicationDomain) {
+ _disableDitheringCheckbox->setEnabled(true);
+ _disableDitheringCheckbox->setState(ConfMan.getBool("disable_dithering", _domain));
+ } else {
+ _disableDitheringCheckbox->setState(false);
+ _disableDitheringCheckbox->setEnabled(false);
+ }
}
// Audio options
@@ -551,6 +572,12 @@ void OptionsDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 data
// 'true' because if control is disabled then event do not pass
setVolumeSettingsState(true);
break;
+ case kSubtitleToggle:
+ // We update the slider settings here, when there are sliders, to
+ // disable the speech volume in case we are in subtitle only mode.
+ if (_musicVolumeSlider)
+ setVolumeSettingsState(true);
+ break;
case kSubtitleSpeedChanged:
_subSpeedLabel->setValue(_subSpeedSlider->getValue());
_subSpeedLabel->draw();
@@ -585,9 +612,15 @@ void OptionsDialog::setGraphicSettingsState(bool enabled) {
_renderModePopUp->setEnabled(enabled);
#ifndef SMALL_SCREEN_DEVICE
_fullscreenCheckbox->setEnabled(enabled);
- _aspectCheckbox->setEnabled(enabled);
+ if (_guioptions.contains(GUIO_NOASPECT))
+ _aspectCheckbox->setEnabled(false);
+ else
+ _aspectCheckbox->setEnabled(enabled);
#endif
- _disableDitheringCheckbox->setEnabled(enabled);
+ if (_guioptions.contains(GUIO_EGAUNDITHER) && enabled)
+ _disableDitheringCheckbox->setEnabled(true);
+ else
+ _disableDitheringCheckbox->setEnabled(false);
}
void OptionsDialog::setAudioSettingsState(bool enabled) {
@@ -595,11 +628,8 @@ void OptionsDialog::setAudioSettingsState(bool enabled) {
_midiPopUpDesc->setEnabled(enabled);
_midiPopUp->setEnabled(enabled);
- Common::String allFlags = MidiDriver::musicType2GUIO((uint32)-1);
- char opt[256];
-
- strncpy(opt, _guioptions.c_str(), 256);
- bool hasMidiDefined = (strtok(opt, allFlags.c_str()) != NULL);
+ const Common::String allFlags = MidiDriver::musicType2GUIO((uint32)-1);
+ bool hasMidiDefined = (strpbrk(_guioptions.c_str(), allFlags.c_str()) != NULL);
if (_domain != Common::ConfigManager::kApplicationDomain && // global dialog
hasMidiDefined && // No flags are specified
@@ -669,6 +699,9 @@ void OptionsDialog::setVolumeSettingsState(bool enabled) {
_sfxVolumeLabel->setEnabled(ena);
ena = enabled && !_muteCheckbox->getState();
+ // Disable speech volume slider, when we are in subtitle only mode.
+ if (_subToggleGroup)
+ ena = ena && _subToggleGroup->getValue() != kSubtitlesSubs;
if (_guioptions.contains(GUIO_NOSPEECH))
ena = false;
@@ -717,13 +750,18 @@ void OptionsDialog::addGraphicControls(GuiObject *boss, const Common::String &pr
}
// RenderMode popup
+ const Common::String allFlags = renderType2GUIO((uint32)-1);
+ bool renderingTypeDefined = (strpbrk(_guioptions.c_str(), allFlags.c_str()) != NULL);
+
_renderModePopUpDesc = new StaticTextWidget(boss, prefix + "grRenderPopupDesc", _("Render mode:"), _("Special dithering modes supported by some games"));
_renderModePopUp = new PopUpWidget(boss, prefix + "grRenderPopup", _("Special dithering modes supported by some games"));
_renderModePopUp->appendEntry(_("<default>"), Common::kRenderDefault);
_renderModePopUp->appendEntry("");
const Common::RenderModeDescription *rm = Common::g_renderModes;
for (; rm->code; ++rm) {
- _renderModePopUp->appendEntry(_c(rm->description, context), rm->id);
+ Common::String renderGuiOption = renderType2GUIO(rm->id);
+ if ((_domain == Common::ConfigManager::kApplicationDomain) || (_domain != Common::ConfigManager::kApplicationDomain && !renderingTypeDefined) || (_guioptions.contains(renderGuiOption)))
+ _renderModePopUp->appendEntry(_c(rm->description, context), rm->id);
}
// Fullscreen checkbox
@@ -745,11 +783,8 @@ void OptionsDialog::addAudioControls(GuiObject *boss, const Common::String &pref
_midiPopUp = new PopUpWidget(boss, prefix + "auMidiPopup", _("Specifies output sound device or sound card emulator"));
// Populate it
- Common::String allFlags = MidiDriver::musicType2GUIO((uint32)-1);
- char opt[256];
-
- strncpy(opt, _guioptions.c_str(), 256);
- bool hasMidiDefined = (strtok(opt, allFlags.c_str()) != NULL);
+ const Common::String allFlags = MidiDriver::musicType2GUIO((uint32)-1);
+ bool hasMidiDefined = (strpbrk(_guioptions.c_str(), allFlags.c_str()) != NULL);
const MusicPlugin::List p = MusicMan.getPlugins();
for (MusicPlugin::List::const_iterator m = p.begin(); m != p.end(); ++m) {
@@ -831,7 +866,8 @@ void OptionsDialog::addMIDIControls(GuiObject *boss, const Common::String &prefi
else
_soundFontButton = new ButtonWidget(boss, prefix + "mcFontButton", _c("SoundFont:", "lowres"), _("SoundFont is supported by some audio cards, Fluidsynth and Timidity"), kChooseSoundFontCmd);
_soundFont = new StaticTextWidget(boss, prefix + "mcFontPath", _c("None", "soundfont"), _("SoundFont is supported by some audio cards, Fluidsynth and Timidity"));
- _soundFontClearButton = new ButtonWidget(boss, prefix + "mcFontClearButton", "C", _("Clear value"), kClearSoundFontCmd);
+
+ _soundFontClearButton = addClearButton(boss, prefix + "mcFontClearButton", kClearSoundFontCmd);
// Multi midi setting
_multiMidiCheckbox = new CheckboxWidget(boss, prefix + "mcMixedCheckbox", _("Mixed AdLib/MIDI mode"), _("Use both MIDI and AdLib sound generation"));
@@ -1004,6 +1040,31 @@ void OptionsDialog::saveMusicDeviceSetting(PopUpWidget *popup, Common::String se
ConfMan.removeKey(setting, _domain);
}
+Common::String OptionsDialog::renderType2GUIO(uint32 renderType) {
+ static const struct {
+ Common::RenderMode type;
+ const char *guio;
+ } renderGUIOMapping[] = {
+ { Common::kRenderHercG, GUIO_RENDERHERCGREEN },
+ { Common::kRenderHercA, GUIO_RENDERHERCAMBER },
+ { Common::kRenderCGA, GUIO_RENDERCGA },
+ { Common::kRenderEGA, GUIO_RENDEREGA },
+ { Common::kRenderVGA, GUIO_RENDERVGA },
+ { Common::kRenderAmiga, GUIO_RENDERAMIGA },
+ { Common::kRenderFMTowns, GUIO_RENDERFMTOWNS },
+ { Common::kRenderPC9821, GUIO_RENDERPC9821 },
+ { Common::kRenderPC9801, GUIO_RENDERPC9801 }
+ };
+ Common::String res;
+
+ for (int i = 0; i < ARRAYSIZE(renderGUIOMapping); i++) {
+ if (renderType == renderGUIOMapping[i].type || renderType == (uint32)-1)
+ res += renderGUIOMapping[i].guio;
+ }
+
+ return res;
+}
+
int OptionsDialog::getSubtitleMode(bool subtitles, bool speech_mute) {
if (_guioptions.contains(GUIO_NOSUBTITLES))
return kSubtitlesSpeech; // Speech only
@@ -1061,7 +1122,7 @@ GlobalOptionsDialog::GlobalOptionsDialog()
//
// 3) The MIDI tab
//
- tab->addTab(_("MIDI"));
+ _midiTabId = tab->addTab(_("MIDI"));
addMIDIControls(tab, "GlobalOptions_MIDI.");
//
@@ -1074,9 +1135,9 @@ GlobalOptionsDialog::GlobalOptionsDialog()
// 5) The Paths tab
//
if (g_system->getOverlayWidth() > 320)
- tab->addTab(_("Paths"));
+ _pathsTabId = tab->addTab(_("Paths"));
else
- tab->addTab(_c("Paths", "lowres"));
+ _pathsTabId = tab->addTab(_c("Paths", "lowres"));
#if !( defined(__DC__) || defined(__GP32__) )
// These two buttons have to be extra wide, or the text will be
@@ -1089,18 +1150,24 @@ GlobalOptionsDialog::GlobalOptionsDialog()
new ButtonWidget(tab, "GlobalOptions_Paths.SaveButton", _c("Save Path:", "lowres"), _("Specifies where your savegames are put"), kChooseSaveDirCmd);
_savePath = new StaticTextWidget(tab, "GlobalOptions_Paths.SavePath", "/foo/bar", _("Specifies where your savegames are put"));
+ _savePathClearButton = addClearButton(tab, "GlobalOptions_Paths.SavePathClearButton", kSavePathClearCmd);
+
if (g_system->getOverlayWidth() > 320)
new ButtonWidget(tab, "GlobalOptions_Paths.ThemeButton", _("Theme Path:"), 0, kChooseThemeDirCmd);
else
new ButtonWidget(tab, "GlobalOptions_Paths.ThemeButton", _c("Theme Path:", "lowres"), 0, kChooseThemeDirCmd);
_themePath = new StaticTextWidget(tab, "GlobalOptions_Paths.ThemePath", _c("None", "path"));
+ _themePathClearButton = addClearButton(tab, "GlobalOptions_Paths.ThemePathClearButton", kThemePathClearCmd);
+
if (g_system->getOverlayWidth() > 320)
new ButtonWidget(tab, "GlobalOptions_Paths.ExtraButton", _("Extra Path:"), _("Specifies path to additional data used by all games or ScummVM"), kChooseExtraDirCmd);
else
new ButtonWidget(tab, "GlobalOptions_Paths.ExtraButton", _c("Extra Path:", "lowres"), _("Specifies path to additional data used by all games or ScummVM"), kChooseExtraDirCmd);
_extraPath = new StaticTextWidget(tab, "GlobalOptions_Paths.ExtraPath", _c("None", "path"), _("Specifies path to additional data used by all games or ScummVM"));
+ _extraPathClearButton = addClearButton(tab, "GlobalOptions_Paths.ExtraPathClearButton", kExtraPathClearCmd);
+
#ifdef DYNAMIC_MODULES
if (g_system->getOverlayWidth() > 320)
new ButtonWidget(tab, "GlobalOptions_Paths.PluginsButton", _("Plugins Path:"), 0, kChoosePluginsDirCmd);
@@ -1207,7 +1274,7 @@ void GlobalOptionsDialog::open() {
Common::String extraPath(ConfMan.get("extrapath", _domain));
if (savePath.empty() || !ConfMan.hasKey("savepath", _domain)) {
- _savePath->setLabel(_c("None", "path"));
+ _savePath->setLabel(_("Default"));
} else {
_savePath->setLabel(savePath);
}
@@ -1251,8 +1318,10 @@ void GlobalOptionsDialog::open() {
void GlobalOptionsDialog::close() {
if (getResult()) {
Common::String savePath(_savePath->getLabel());
- if (!savePath.empty() && (savePath != _c("None", "path")))
+ if (!savePath.empty() && (savePath != _("Default")))
ConfMan.set("savepath", savePath, _domain);
+ else
+ ConfMan.removeKey("savepath", _domain);
Common::String themePath(_themePath->getLabel());
if (!themePath.empty() && (themePath != _c("None", "path")))
@@ -1360,6 +1429,15 @@ void GlobalOptionsDialog::handleCommand(CommandSender *sender, uint32 cmd, uint3
break;
}
#endif
+ case kThemePathClearCmd:
+ _themePath->setLabel(_c("None", "path"));
+ break;
+ case kExtraPathClearCmd:
+ _extraPath->setLabel(_c("None", "path"));
+ break;
+ case kSavePathClearCmd:
+ _savePath->setLabel(_("Default"));
+ break;
case kChooseSoundFontCmd: {
BrowserDialog browser(_("Select SoundFont"), false);
if (browser.runModal() > 0) {
@@ -1418,4 +1496,39 @@ void GlobalOptionsDialog::handleCommand(CommandSender *sender, uint32 cmd, uint3
}
}
+void GlobalOptionsDialog::reflowLayout() {
+ int activeTab = _tabWidget->getActiveTab();
+
+ if (_midiTabId != -1) {
+ _tabWidget->setActiveTab(_midiTabId);
+
+ _tabWidget->removeWidget(_soundFontClearButton);
+ _soundFontClearButton->setNext(0);
+ delete _soundFontClearButton;
+ _soundFontClearButton = addClearButton(_tabWidget, "GlobalOptions_MIDI.mcFontClearButton", kClearSoundFontCmd);
+ }
+
+ if (_pathsTabId != -1) {
+ _tabWidget->setActiveTab(_pathsTabId);
+
+ _tabWidget->removeWidget(_savePathClearButton);
+ _savePathClearButton->setNext(0);
+ delete _savePathClearButton;
+ _savePathClearButton = addClearButton(_tabWidget, "GlobalOptions_Paths.SavePathClearButton", kSavePathClearCmd);
+
+ _tabWidget->removeWidget(_themePathClearButton);
+ _themePathClearButton->setNext(0);
+ delete _themePathClearButton;
+ _themePathClearButton = addClearButton(_tabWidget, "GlobalOptions_Paths.ThemePathClearButton", kThemePathClearCmd);
+
+ _tabWidget->removeWidget(_extraPathClearButton);
+ _extraPathClearButton->setNext(0);
+ delete _extraPathClearButton;
+ _extraPathClearButton = addClearButton(_tabWidget, "GlobalOptions_Paths.ExtraPathClearButton", kExtraPathClearCmd);
+ }
+
+ _tabWidget->setActiveTab(activeTab);
+ OptionsDialog::reflowLayout();
+}
+
} // End of namespace GUI
diff --git a/gui/options.h b/gui/options.h
index c6b1d328c1..83c9d60d59 100644
--- a/gui/options.h
+++ b/gui/options.h
@@ -85,8 +85,12 @@ protected:
bool loadMusicDeviceSetting(PopUpWidget *popup, Common::String setting, MusicType preferredType = MT_AUTO);
void saveMusicDeviceSetting(PopUpWidget *popup, Common::String setting);
+ Common::String renderType2GUIO(uint32 renderType);
+
TabWidget *_tabWidget;
int _graphicsTabId;
+ int _midiTabId;
+ int _pathsTabId;
private:
//
@@ -191,13 +195,18 @@ public:
void close();
void handleCommand(CommandSender *sender, uint32 cmd, uint32 data);
+ virtual void reflowLayout();
+
protected:
#ifdef SMALL_SCREEN_DEVICE
KeysDialog *_keysDialog;
#endif
StaticTextWidget *_savePath;
+ ButtonWidget *_savePathClearButton;
StaticTextWidget *_themePath;
+ ButtonWidget *_themePathClearButton;
StaticTextWidget *_extraPath;
+ ButtonWidget *_extraPathClearButton;
#ifdef DYNAMIC_MODULES
StaticTextWidget *_pluginsPath;
#endif
diff --git a/gui/saveload.cpp b/gui/saveload.cpp
index ae950a21fb..3dc9961906 100644
--- a/gui/saveload.cpp
+++ b/gui/saveload.cpp
@@ -92,7 +92,7 @@ int SaveLoadChooser::runModalWithPluginAndTarget(const EnginePlugin *plugin, con
_thumbnailSupport = _metaInfoSupport && (*_plugin)->hasFeature(MetaEngine::kSavesSupportThumbnail);
_saveDateSupport = _metaInfoSupport && (*_plugin)->hasFeature(MetaEngine::kSavesSupportCreationDate);
_playTimeSupport = _metaInfoSupport && (*_plugin)->hasFeature(MetaEngine::kSavesSupportPlayTime);
- _resultString = "";
+ _resultString.clear();
reflowLayout();
updateSaveList();
diff --git a/gui/themes/default.inc b/gui/themes/default.inc
index 2716e6ca72..bd28c2e85d 100644
--- a/gui/themes/default.inc
+++ b/gui/themes/default.inc
@@ -1,47 +1,644 @@
"<?xml version = '1.0'?>"
-"<layout_info resolution='y>399'> "
+"<render_info> "
+"<palette> "
+"<color name='black' "
+"rgb='0,0,0' "
+"/> "
+"<color name='lightgrey' "
+"rgb='104,104,104' "
+"/> "
+"<color name='darkgrey' "
+"rgb='64,64,64' "
+"/> "
+"<color name='green' "
+"rgb='32,160,32' "
+"/> "
+"<color name='green2' "
+"rgb='0,255,0' "
+"/> "
+"</palette> "
+"<fonts> "
+"<font id='text_default' "
+"file='helvb12.bdf' "
+"/> "
+"<font resolution='y<400' "
+"id='text_default' "
+"file='clR6x12.bdf' "
+"/> "
+"<font id='text_button' "
+"file='helvb12.bdf' "
+"/> "
+"<font resolution='y<400' "
+"id='text_button' "
+"file='clR6x12.bdf' "
+"/> "
+"<font id='text_normal' "
+"file='helvb12.bdf' "
+"/> "
+"<font resolution='y<400' "
+"id='text_normal' "
+"file='clR6x12.bdf' "
+"/> "
+"<font id='tooltip_normal' "
+"file='fixed5x8.bdf' "
+"/> "
+"<text_color id='color_normal' "
+"color='green' "
+"/> "
+"<text_color id='color_normal_inverted' "
+"color='black' "
+"/> "
+"<text_color id='color_normal_hover' "
+"color='green2' "
+"/> "
+"<text_color id='color_normal_disabled' "
+"color='lightgrey' "
+"/> "
+"<text_color id='color_alternative' "
+"color='lightgrey' "
+"/> "
+"<text_color id='color_alternative_inverted' "
+"color='255,255,255' "
+"/> "
+"<text_color id='color_alternative_hover' "
+"color='176,176,176' "
+"/> "
+"<text_color id='color_alternative_disabled' "
+"color='darkgrey' "
+"/> "
+"<text_color id='color_button' "
+"color='green' "
+"/> "
+"<text_color id='color_button_hover' "
+"color='green2' "
+"/> "
+"<text_color id='color_button_disabled' "
+"color='lightgrey' "
+"/> "
+"</fonts> "
+"<defaults fill='foreground' fg_color='darkgrey' bg_color='black' shadow='0' bevel_color='lightgrey'/> "
+"<drawdata id='text_selection' cache='false'> "
+"<drawstep func='square' "
+"fill='foreground' "
+"fg_color='lightgrey' "
+"/> "
+"</drawdata> "
+"<drawdata id='text_selection_focus' cache='false'> "
+"<drawstep func='square' "
+"fill='foreground' "
+"fg_color='green' "
+"/> "
+"</drawdata> "
+"<drawdata id='mainmenu_bg' cache='false'> "
+"<drawstep func='fill' "
+"fill='foreground' "
+"fg_color='black' "
+"/> "
+"</drawdata> "
+"<drawdata id='special_bg' cache='false'> "
+"<drawstep func='bevelsq' "
+"bevel='2' "
+"/> "
+"</drawdata> "
+"<drawdata id='tooltip_bg' cache='false'> "
+"<drawstep func='bevelsq' "
+"bevel='2' "
+"fill='foreground' "
+"fg_color='black' "
+"/> "
+"</drawdata> "
+"<drawdata id='separator' cache='false'> "
+"<drawstep func='square' "
+"fill='foreground' "
+"height='2' "
+"ypos='center' "
+"fg_color='lightgrey' "
+"/> "
+"</drawdata> "
+"<drawdata id='scrollbar_base' cache='false'> "
+"<drawstep func='bevelsq' "
+"bevel='2' "
+"/> "
+"</drawdata> "
+"<drawdata id='scrollbar_handle_hover' cache='false'> "
+"<drawstep func='square' "
+"fill='foreground' "
+"fg_color='green2' "
+"/> "
+"</drawdata> "
+"<drawdata id='scrollbar_handle_idle' cache='false'> "
+"<drawstep func='square' "
+"fill='foreground' "
+"fg_color='green' "
+"/> "
+"</drawdata> "
+"<drawdata id='scrollbar_button_idle' cache='false' resolution='y>399'> "
+"<drawstep func='bevelsq' "
+"bevel='2' "
+"fill='none' "
+"/> "
+"<drawstep func='triangle' "
+"fg_color='green' "
+"fill='foreground' "
+"width='10' "
+"height='10' "
+"xpos='right' "
+"ypos='center' "
+"padding='0,0,3,0' "
+"orientation='top' "
+"/> "
+"</drawdata> "
+"<drawdata id='scrollbar_button_idle' cache='false' resolution='y<400'> "
+"<drawstep func='bevelsq' "
+"bevel='2' "
+"fill='none' "
+"/> "
+"<drawstep func='triangle' "
+"fg_color='green' "
+"fill='foreground' "
+"width='5' "
+"height='5' "
+"xpos='right' "
+"ypos='center' "
+"padding='0,0,2,0' "
+"orientation='top' "
+"/> "
+"</drawdata> "
+"<drawdata id='scrollbar_button_hover' cache='false' resolution='y>399'> "
+"<drawstep func='bevelsq' "
+"bevel='2' "
+"fill='none' "
+"/> "
+"<drawstep func='triangle' "
+"fg_color='green' "
+"fill='foreground' "
+"width='10' "
+"height='10' "
+"xpos='right' "
+"ypos='center' "
+"padding='0,0,3,0' "
+"orientation='top' "
+"/> "
+"</drawdata> "
+"<drawdata id='scrollbar_button_hover' cache='false' resolution='y<400'> "
+"<drawstep func='bevelsq' "
+"bevel='2' "
+"fill='none' "
+"/> "
+"<drawstep func='triangle' "
+"fg_color='green' "
+"fill='foreground' "
+"width='5' "
+"height='5' "
+"xpos='right' "
+"ypos='center' "
+"padding='0,0,2,0' "
+"orientation='top' "
+"/> "
+"</drawdata> "
+"<drawdata id='tab_active' cache='false'> "
+"<text font='text_default' "
+"text_color='color_normal_hover' "
+"vertical_align='center' "
+"horizontal_align='center' "
+"/> "
+"<drawstep func='tab' "
+"bevel='2' "
+"radius='0' "
+"fill='none' "
+"/> "
+"</drawdata> "
+"<drawdata id='tab_inactive' cache='false'> "
+"<text font='text_default' "
+"text_color='color_normal' "
+"vertical_align='center' "
+"horizontal_align='center' "
+"/> "
+"<drawstep func='tab' "
+"bevel='2' "
+"radius='0' "
+"fill='none' "
+"/> "
+"</drawdata> "
+"<drawdata id='tab_background' cache='false'> "
+"</drawdata> "
+"<drawdata id='widget_slider' cache='false'> "
+"<drawstep func='bevelsq' "
+"bevel='2' "
+"fill='none' "
+"/> "
+"</drawdata> "
+"<drawdata id='slider_disabled' cache='false'> "
+"<drawstep func='square' "
+"fill='foreground' "
+"fg_color='lightgrey' "
+"/> "
+"</drawdata> "
+"<drawdata id='slider_full' cache='false'> "
+"<drawstep func='square' "
+"fill='foreground' "
+"fg_color='green' "
+"/> "
+"</drawdata> "
+"<drawdata id='slider_hover' cache='false'> "
+"<drawstep func='square' "
+"fill='foreground' "
+"fg_color='green2' "
+"/> "
+"</drawdata> "
+"<drawdata id='widget_small' cache='false'> "
+"<drawstep func='bevelsq' "
+"bevel='2' "
+"fill='none' "
+"/> "
+"</drawdata> "
+"<drawdata id='popup_idle' cache='false' resolution='y>399'> "
+"<drawstep func='bevelsq' "
+"bevel='2' "
+"fill='none' "
+"/> "
+"<drawstep func='triangle' "
+"fg_color='green' "
+"fill='foreground' "
+"width='10' "
+"height='5' "
+"xpos='right' "
+"ypos='10' "
+"padding='0,0,7,0' "
+"orientation='bottom' "
+"/> "
+"<drawstep func='triangle' "
+"fg_color='green' "
+"fill='foreground' "
+"width='10' "
+"height='5' "
+"xpos='right' "
+"ypos='4' "
+"padding='0,0,7,0' "
+"orientation='top' "
+"/> "
+"<text font='text_default' "
+"text_color='color_normal' "
+"vertical_align='center' "
+"horizontal_align='left' "
+"/> "
+"</drawdata> "
+"<drawdata id='popup_idle' cache='false' resolution='y<400'> "
+"<drawstep func='bevelsq' "
+"bevel='2' "
+"fill='none' "
+"/> "
+"<drawstep func='triangle' "
+"fg_color='green' "
+"fill='foreground' "
+"width='7' "
+"height='4' "
+"xpos='right' "
+"ypos='9' "
+"padding='0,0,3,0' "
+"orientation='bottom' "
+"/> "
+"<drawstep func='triangle' "
+"fg_color='green' "
+"fill='foreground' "
+"width='7' "
+"height='4' "
+"xpos='right' "
+"ypos='4' "
+"padding='0,0,3,0' "
+"orientation='top' "
+"/> "
+"<text font='text_default' "
+"text_color='color_normal' "
+"vertical_align='center' "
+"horizontal_align='left' "
+"/> "
+"</drawdata> "
+"<drawdata id='popup_disabled' cache='false' resolution='y>399'> "
+"<drawstep func='bevelsq' "
+"bevel='2' "
+"fill='none' "
+"/> "
+"<drawstep func='triangle' "
+"fg_color='green' "
+"fill='foreground' "
+"width='10' "
+"height='5' "
+"xpos='right' "
+"ypos='10' "
+"padding='0,0,7,0' "
+"orientation='bottom' "
+"/> "
+"<drawstep func='triangle' "
+"fg_color='green' "
+"fill='foreground' "
+"width='10' "
+"height='5' "
+"xpos='right' "
+"ypos='4' "
+"padding='0,0,7,0' "
+"orientation='top' "
+"/> "
+"<text font='text_default' "
+"text_color='color_normal_disabled' "
+"vertical_align='center' "
+"horizontal_align='left' "
+"/> "
+"</drawdata> "
+"<drawdata id='popup_disabled' cache='false' resolution='y<400'> "
+"<drawstep func='bevelsq' "
+"bevel='2' "
+"fill='none' "
+"/> "
+"<drawstep func='triangle' "
+"fg_color='green' "
+"fill='foreground' "
+"width='7' "
+"height='4' "
+"xpos='right' "
+"ypos='9' "
+"padding='0,0,3,0' "
+"orientation='bottom' "
+"/> "
+"<drawstep func='triangle' "
+"fg_color='green' "
+"fill='foreground' "
+"width='7' "
+"height='4' "
+"xpos='right' "
+"ypos='4' "
+"padding='0,0,3,0' "
+"orientation='top' "
+"/> "
+"<text font='text_default' "
+"text_color='color_normal' "
+"vertical_align='center' "
+"horizontal_align='left' "
+"/> "
+"</drawdata> "
+"<drawdata id='popup_hover' cache='false' resolution='y>399'> "
+"<drawstep func='bevelsq' "
+"bevel='2' "
+"fill='none' "
+"/> "
+"<drawstep func='triangle' "
+"fg_color='green' "
+"fill='foreground' "
+"width='10' "
+"height='5' "
+"xpos='right' "
+"ypos='10' "
+"padding='0,0,7,0' "
+"orientation='bottom' "
+"/> "
+"<drawstep func='triangle' "
+"fg_color='green' "
+"fill='foreground' "
+"width='10' "
+"height='5' "
+"xpos='right' "
+"ypos='4' "
+"padding='0,0,7,0' "
+"orientation='top' "
+"/> "
+"<text font='text_default' "
+"text_color='color_normal_hover' "
+"vertical_align='center' "
+"horizontal_align='left' "
+"/> "
+"</drawdata> "
+"<drawdata id='popup_hover' cache='false' resolution='y<400'> "
+"<drawstep func='bevelsq' "
+"bevel='2' "
+"fill='none' "
+"/> "
+"<drawstep func='triangle' "
+"fg_color='green' "
+"fill='foreground' "
+"width='7' "
+"height='4' "
+"xpos='right' "
+"ypos='9' "
+"padding='0,0,3,0' "
+"orientation='bottom' "
+"/> "
+"<drawstep func='triangle' "
+"fg_color='green' "
+"fill='foreground' "
+"width='7' "
+"height='4' "
+"xpos='right' "
+"ypos='4' "
+"padding='0,0,3,0' "
+"orientation='top' "
+"/> "
+"<text font='text_default' "
+"text_color='color_normal' "
+"vertical_align='center' "
+"horizontal_align='left' "
+"/> "
+"</drawdata> "
+"<drawdata id='widget_textedit' cache='false'> "
+"<drawstep func='bevelsq' "
+"bevel='2' "
+"fill='none' "
+"/> "
+"</drawdata> "
+"<drawdata id='plain_bg' cache='false'> "
+"<drawstep func='bevelsq' "
+"bevel='2' "
+"/> "
+"</drawdata> "
+"<drawdata id='caret' cache='false'> "
+"<drawstep func='square' "
+"fill='foreground' "
+"fg_color='lightgrey' "
+"/> "
+"</drawdata> "
+"<drawdata id='default_bg' cache='false'> "
+"<drawstep func='bevelsq' "
+"bevel='2' "
+"/> "
+"</drawdata> "
+"<drawdata id='button_idle' cache='false'> "
+"<text font='text_button' "
+"text_color='color_button' "
+"vertical_align='center' "
+"horizontal_align='center' "
+"/> "
+"<drawstep func='bevelsq' "
+"bevel='2' "
+"fill='none' "
+"/> "
+"</drawdata> "
+"<drawdata id='button_hover' cache='false'> "
+"<text font='text_button' "
+"text_color='color_button_hover' "
+"vertical_align='center' "
+"horizontal_align='center' "
+"/> "
+"<drawstep func='bevelsq' "
+"bevel='2' "
+"fill='none' "
+"/> "
+"</drawdata> "
+"<drawdata id='button_disabled' cache='false'> "
+"<text font='text_button' "
+"text_color='color_button_disabled' "
+"vertical_align='center' "
+"horizontal_align='center' "
+"/> "
+"<drawstep func='bevelsq' "
+"bevel='2' "
+"fill='none' "
+"/> "
+"</drawdata> "
+"<drawdata id='checkbox_disabled' cache='false'> "
+"<text font='text_default' "
+"text_color='color_normal_disabled' "
+"vertical_align='top' "
+"horizontal_align='left' "
+"/> "
+"<drawstep func='bevelsq' "
+"bevel='2' "
+"fill='none' "
+"/> "
+"</drawdata> "
+"<drawdata id='checkbox_selected' cache='false'> "
+"<text font='text_default' "
+"text_color='color_normal' "
+"vertical_align='top' "
+"horizontal_align='left' "
+"/> "
+"<drawstep func='bevelsq' "
+"bevel='2' "
+"fill='none' "
+"/> "
+"<drawstep func='cross' "
+"fill='foreground' "
+"stroke='2' "
+"fg_color='green' "
+"/> "
+"</drawdata> "
+"<drawdata id='checkbox_default' cache='false'> "
+"<text font='text_default' "
+"text_color='color_normal' "
+"vertical_align='top' "
+"horizontal_align='left' "
+"/> "
+"<drawstep func='bevelsq' "
+"bevel='2' "
+"fill='none' "
+"/> "
+"</drawdata> "
+"<drawdata id='radiobutton_default' cache='false'> "
+"<text font='text_default' "
+"text_color='color_normal' "
+"vertical_align='center' "
+"horizontal_align='left' "
+"/> "
+"<drawstep func='circle' "
+"width='7' "
+"height='7' "
+"radius='7' "
+"fill='background' "
+"bg_color='darkgrey' "
+"xpos='0' "
+"ypos='0' "
+"/> "
+"</drawdata> "
+"<drawdata id='radiobutton_selected' cache='false'> "
+"<text font='text_default' "
+"text_color='color_normal' "
+"vertical_align='center' "
+"horizontal_align='left' "
+"/> "
+"<drawstep func='circle' "
+"width='7' "
+"height='7' "
+"radius='7' "
+"fg_color='darkgrey' "
+"fill='none' "
+"xpos='0' "
+"ypos='0' "
+"/> "
+"<drawstep func='circle' "
+"width='7' "
+"height='7' "
+"radius='5' "
+"fg_color='green' "
+"fill='foreground' "
+"xpos='2' "
+"ypos='2' "
+"/> "
+"</drawdata> "
+"<drawdata id='radiobutton_disabled' cache='false'> "
+"<text font='text_default' "
+"text_color='color_normal_disabled' "
+"vertical_align='center' "
+"horizontal_align='left' "
+"/> "
+"<drawstep func='circle' "
+"width='7' "
+"height='7' "
+"radius='7' "
+"bg_color='lightgrey' "
+"fill='background' "
+"xpos='0' "
+"ypos='0' "
+"/> "
+"</drawdata> "
+"<drawdata id='widget_default' cache='false'> "
+"<drawstep func='bevelsq' "
+"bevel='2' "
+"/> "
+"</drawdata> "
+"<drawdata id='widget_small' cache='false'> "
+"<drawstep func='square' "
+"stroke='0' "
+"/> "
+"</drawdata> "
+"</render_info> "
+"<layout_info resolution='y<400'> "
"<globals> "
-"<def var='Line.Height' value='16' /> "
-"<def var='Font.Height' value='16' /> "
-"<def var='About.OuterBorder' value='80'/> "
-"<def var='Layout.Spacing' value='8' /> "
+"<def var='Line.Height' value='12' /> "
+"<def var='Font.Height' value='10' /> "
+"<def var='About.OuterBorder' value='10'/> "
+"<def var='Layout.Spacing' value='8'/> "
"<def var='ShowLauncherLogo' value='0'/> "
"<def var='ShowGlobalMenuLogo' value='0'/> "
"<def var='ShowSearchPic' value='0'/> "
-"<def var='SaveLoadChooser.ExtInfo.Visible' value='1'/> "
-"<def var='KeyMapper.Spacing' value='10'/> "
-"<def var='KeyMapper.LabelWidth' value='100'/> "
-"<def var='KeyMapper.ButtonWidth' value='80'/> "
-"<def var='Tooltip.MaxWidth' value='200'/> "
-"<def var='Tooltip.XDelta' value='16'/> "
-"<def var='Tooltip.YDelta' value='16'/> "
+"<def var='SaveLoadChooser.ExtInfo.Visible' value='0'/> "
+"<def var='KeyMapper.Spacing' value='5'/> "
+"<def var='KeyMapper.LabelWidth' value='80'/> "
+"<def var='KeyMapper.ButtonWidth' value='60'/> "
+"<def var='Tooltip.MaxWidth' value='70'/> "
+"<def var='Tooltip.XDelta' value='8'/> "
+"<def var='Tooltip.YDelta' value='8'/> "
+"<widget name='Button' "
+"size='72,16' "
+"/> "
+"<widget name='Slider' "
+"size='85,12' "
+"/> "
"<widget name='OptionsLabel' "
"size='110,Globals.Line.Height' "
"textalign='right' "
"/> "
"<widget name='SmallLabel' "
-"size='24,Globals.Line.Height' "
-"/> "
-"<widget name='ShortOptionsLabel' "
-"size='60,Globals.Line.Height' "
-"/> "
-"<widget name='Button' "
-"size='108,24' "
-"/> "
-"<widget name='Slider' "
-"size='128,18' "
+"size='18,Globals.Line.Height' "
"/> "
"<widget name='PopUp' "
-"size='-1,19' "
+"size='-1,15' "
"/> "
"<widget name='Checkbox' "
-"size='-1,14' "
+"size='-1,Globals.Line.Height' "
"/> "
"<widget name='Radiobutton' "
"size='-1,Globals.Line.Height' "
"/> "
"<widget name='ListWidget' "
-"padding='5,0,8,0' "
+"padding='5,0,0,0' "
"/> "
"<widget name='PopUpWidget' "
"padding='7,5,0,0' "
@@ -53,28 +650,28 @@
"padding='7,5,5,5' "
"/> "
"<widget name='Scrollbar' "
-"size='15,0' "
+"size='9,0' "
"/> "
"<widget name='TabWidget.Tab' "
-"size='75,27' "
-"padding='0,0,8,0' "
+"size='45,16' "
+"padding='0,0,2,0' "
"/> "
"<widget name='TabWidget.Body' "
-"padding='0,0,0,0' "
+"padding='0,0,0,-8' "
"/> "
"<widget name='TabWidget.NavButton' "
-"size='15,18' "
-"padding='0,3,4,0' "
+"size='32,18' "
+"padding='0,0,1,0' "
"/> "
"</globals> "
"<dialog name='Launcher' overlays='screen'> "
-"<layout type='vertical' center='true' padding='16,16,8,8'> "
+"<layout type='vertical' center='true' padding='6,6,2,2'> "
"<widget name='Version' "
"height='Globals.Line.Height' "
"/> "
-"<layout type='horizontal' spacing='5' padding='10,0,0,0'> "
+"<layout type='horizontal' spacing='5' padding='0,0,0,0'> "
"<widget name='SearchDesc' "
-"width='60' "
+"width='50' "
"height='Globals.Line.Height' "
"textalign='right' "
"/> "
@@ -89,39 +686,38 @@
"<space /> "
"</layout> "
"<widget name='GameList'/> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='10'> "
+"<layout type='horizontal' padding='0,0,0,0' spacing='8'> "
"<widget name='LoadGameButton' "
-"height='20' "
+"height='12' "
"/> "
"<widget name='AddGameButton' "
-"height='20' "
+"height='12' "
"/> "
"<widget name='EditGameButton' "
-"height='20' "
+"height='12' "
"/> "
"<widget name='RemoveGameButton' "
-"height='20' "
+"height='12' "
"/> "
"</layout> "
-"<space size='4'/> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='10'> "
+"<layout type='horizontal' padding='0,0,0,0' spacing='8'> "
"<widget name='QuitButton' "
-"height='20' "
+"height='12' "
"/> "
"<widget name='AboutButton' "
-"height='20' "
+"height='12' "
"/> "
"<widget name='OptionsButton' "
-"height='20' "
+"height='12' "
"/> "
"<widget name='StartButton' "
-"height='20' "
+"height='12' "
"/> "
"</layout> "
"</layout> "
"</dialog> "
-"<dialog name='Browser' overlays='Dialog.Launcher.GameList' shading='dim'> "
-"<layout type='vertical' padding='8,8,8,8'> "
+"<dialog name='Browser' overlays='screen' inset='8' shading='dim'> "
+"<layout type='vertical' padding='8,8,0,4'> "
"<widget name='Headline' "
"height='Globals.Line.Height' "
"/> "
@@ -129,7 +725,7 @@
"height='Globals.Line.Height' "
"/> "
"<widget name='List'/> "
-"<layout type='horizontal' padding='0,0,16,0'> "
+"<layout type='horizontal' padding='0,0,8,0'> "
"<widget name='Up' "
"type='Button' "
"/> "
@@ -143,10 +739,10 @@
"</layout> "
"</layout> "
"</dialog> "
-"<dialog name='GlobalOptions' overlays='Dialog.Launcher.GameList' shading='dim'> "
+"<dialog name='GlobalOptions' overlays='screen' inset='16' shading='dim'> "
"<layout type='vertical' padding='0,0,0,0'> "
"<widget name='TabWidget'/> "
-"<layout type='horizontal' padding='16,16,16,16'> "
+"<layout type='horizontal' padding='8,8,8,8'> "
"<space/> "
"<widget name='Cancel' "
"type='Button' "
@@ -159,7 +755,7 @@
"</dialog> "
"<dialog name='GlobalOptions_Graphics' overlays='Dialog.GlobalOptions.TabWidget'> "
"<layout type='vertical' padding='16,16,16,16' spacing='8'> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> "
+"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> "
"<widget name='grModePopupDesc' "
"type='OptionsLabel' "
"/> "
@@ -167,7 +763,7 @@
"type='PopUp' "
"/> "
"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> "
+"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> "
"<widget name='grRenderPopupDesc' "
"type='OptionsLabel' "
"/> "
@@ -188,7 +784,7 @@
"</dialog> "
"<dialog name='GlobalOptions_Audio' overlays='Dialog.GlobalOptions.TabWidget'> "
"<layout type='vertical' padding='16,16,16,16' spacing='8'> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> "
+"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> "
"<widget name='auMidiPopupDesc' "
"type='OptionsLabel' "
"/> "
@@ -196,7 +792,7 @@
"type='PopUp' "
"/> "
"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> "
+"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> "
"<widget name='auOPLPopupDesc' "
"type='OptionsLabel' "
"/> "
@@ -204,7 +800,7 @@
"type='PopUp' "
"/> "
"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> "
+"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> "
"<widget name='auSampleRatePopupDesc' "
"type='OptionsLabel' "
"/> "
@@ -212,7 +808,7 @@
"type='PopUp' "
"/> "
"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='10'> "
+"<layout type='horizontal' padding='0,0,0,0' spacing='3' center='true'> "
"<widget name='subToggleDesc' "
"type='OptionsLabel' "
"/> "
@@ -226,7 +822,7 @@
"type='Radiobutton' "
"/> "
"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='10'> "
+"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> "
"<widget name='subSubtitleSpeedDesc' "
"type='OptionsLabel' "
"/> "
@@ -240,9 +836,8 @@
"</layout> "
"</dialog> "
"<dialog name='GlobalOptions_Volume' overlays='Dialog.GlobalOptions.TabWidget'> "
-"<layout type='horizontal' padding='16,16,16,16' spacing='8'> "
-"<layout type='vertical' padding='0,0,0,0' spacing='8'> "
-"<layout type='horizontal' padding='0,0,0,0'> "
+"<layout type='vertical' padding='16,16,16,16' spacing='8'> "
+"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> "
"<widget name='vcMusicText' "
"type='OptionsLabel' "
"/> "
@@ -253,7 +848,7 @@
"type='SmallLabel' "
"/> "
"</layout> "
-"<layout type='horizontal' padding='0,0,0,0'> "
+"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> "
"<widget name='vcSfxText' "
"type='OptionsLabel' "
"/> "
@@ -264,7 +859,7 @@
"type='SmallLabel' "
"/> "
"</layout> "
-"<layout type='horizontal' padding='0,0,0,0'> "
+"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> "
"<widget name='vcSpeechText' "
"type='OptionsLabel' "
"/> "
@@ -275,8 +870,8 @@
"type='SmallLabel' "
"/> "
"</layout> "
-"</layout> "
-"<layout type='vertical' padding='24,0,24,0' center='true'> "
+"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> "
+"<space size='110' /> "
"<widget name='vcMuteCheckbox' "
"type='Checkbox' "
"/> "
@@ -285,7 +880,7 @@
"</dialog> "
"<dialog name='GlobalOptions_MIDI' overlays='Dialog.GlobalOptions.TabWidget'> "
"<layout type='vertical' padding='16,16,16,16' spacing='8'> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> "
+"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> "
"<widget name='auPrefGmPopupDesc' "
"type='OptionsLabel' "
"/> "
@@ -293,7 +888,7 @@
"type='PopUp' "
"/> "
"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> "
+"<layout type='horizontal' padding='0,0,0,0' spacing='16' center='true'> "
"<widget name='mcFontButton' "
"type='Button' "
"/> "
@@ -308,7 +903,7 @@
"<widget name='mcMixedCheckbox' "
"type='Checkbox' "
"/> "
-"<layout type='horizontal' padding='0,0,0,0'> "
+"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> "
"<widget name='mcMidiGainText' "
"type='OptionsLabel' "
"/> "
@@ -324,7 +919,7 @@
"</dialog> "
"<dialog name='GlobalOptions_MT32' overlays='Dialog.GlobalOptions.TabWidget'> "
"<layout type='vertical' padding='16,16,16,16' spacing='8'> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> "
+"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> "
"<widget name='auPrefMt32PopupDesc' "
"type='OptionsLabel' "
"/> "
@@ -342,29 +937,41 @@
"</dialog> "
"<dialog name='GlobalOptions_Paths' overlays='Dialog.GlobalOptions.TabWidget'> "
"<layout type='vertical' padding='16,16,16,16' spacing='8'> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> "
+"<layout type='horizontal' padding='0,0,0,0' spacing='16'> "
"<widget name='SaveButton' "
"type='Button' "
"/> "
"<widget name='SavePath' "
"height='Globals.Line.Height' "
"/> "
+"<widget name='SavePathClearButton' "
+"height='Globals.Line.Height' "
+"width='Globals.Line.Height' "
+"/> "
"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> "
+"<layout type='horizontal' padding='0,0,0,0' spacing='16'> "
"<widget name='ThemeButton' "
"type='Button' "
"/> "
"<widget name='ThemePath' "
"height='Globals.Line.Height' "
"/> "
+"<widget name='ThemePathClearButton' "
+"height='Globals.Line.Height' "
+"width='Globals.Line.Height' "
+"/> "
"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> "
+"<layout type='horizontal' padding='0,0,0,0' spacing='16'> "
"<widget name='ExtraButton' "
"type='Button' "
"/> "
"<widget name='ExtraPath' "
"height='Globals.Line.Height' "
"/> "
+"<widget name='ExtraPathClearButton' "
+"height='Globals.Line.Height' "
+"width='Globals.Line.Height' "
+"/> "
"</layout> "
"<layout type='horizontal' padding='0,0,0,0' spacing='16'> "
"<widget name='PluginsButton' "
@@ -378,7 +985,7 @@
"</dialog> "
"<dialog name='GlobalOptions_Misc' overlays='Dialog.GlobalOptions.TabWidget'> "
"<layout type='vertical' padding='16,16,16,16' spacing='8'> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> "
+"<layout type='horizontal' padding='0,0,0,0' spacing='16'> "
"<widget name='ThemeButton' "
"type='Button' "
"/> "
@@ -386,25 +993,31 @@
"height='Globals.Line.Height' "
"/> "
"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> "
+"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> "
"<widget name='RendererPopupDesc' "
-"type='OptionsLabel' "
+"width='80' "
+"height='Globals.Line.Height' "
+"textalign='right' "
"/> "
"<widget name='RendererPopup' "
"type='PopUp' "
"/> "
"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> "
+"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> "
"<widget name='AutosavePeriodPopupDesc' "
-"type='OptionsLabel' "
+"width='80' "
+"height='Globals.Line.Height' "
+"textalign='right' "
"/> "
"<widget name='AutosavePeriodPopup' "
"type='PopUp' "
"/> "
"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> "
+"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> "
"<widget name='GuiLanguagePopupDesc' "
-"type='OptionsLabel' "
+"width='80' "
+"height='Globals.Line.Height' "
+"textalign='right' "
"/> "
"<widget name='GuiLanguagePopup' "
"type='PopUp' "
@@ -439,10 +1052,10 @@
"</layout> "
"</layout> "
"</dialog> "
-"<dialog name='GameOptions' overlays='Dialog.Launcher.GameList' shading='dim'> "
+"<dialog name='GameOptions' overlays='screen' inset='16' shading='dim'> "
"<layout type='vertical' padding='0,0,0,0' spacing='16'> "
"<widget name='TabWidget'/> "
-"<layout type='horizontal' padding='16,16,16,4'> "
+"<layout type='horizontal' padding='8,8,8,8'> "
"<space/> "
"<widget name='Cancel' "
"type='Button' "
@@ -454,7 +1067,7 @@
"</layout> "
"</dialog> "
"<dialog name='GameOptions_Graphics' overlays='Dialog.GlobalOptions.TabWidget'> "
-"<layout type='vertical' padding='16,16,16,16' spacing='8'> "
+"<layout type='vertical' padding='8,8,8,8' spacing='6'> "
"<widget name='EnableTabCheckbox' "
"type='Checkbox' "
"/> "
@@ -462,7 +1075,7 @@
"</layout> "
"</dialog> "
"<dialog name='GameOptions_Audio' overlays='Dialog.GlobalOptions.TabWidget'> "
-"<layout type='vertical' padding='16,16,16,16' spacing='8'> "
+"<layout type='vertical' padding='8,8,8,8' spacing='6'> "
"<widget name='EnableTabCheckbox' "
"type='Checkbox' "
"/> "
@@ -470,7 +1083,7 @@
"</layout> "
"</dialog> "
"<dialog name='GameOptions_MIDI' overlays='Dialog.GlobalOptions.TabWidget'> "
-"<layout type='vertical' padding='16,16,16,16' spacing='8'> "
+"<layout type='vertical' padding='8,8,8,8' spacing='6'> "
"<widget name='EnableTabCheckbox' "
"type='Checkbox' "
"/> "
@@ -478,7 +1091,7 @@
"</layout> "
"</dialog> "
"<dialog name='GameOptions_MT32' overlays='Dialog.GlobalOptions.TabWidget'> "
-"<layout type='vertical' padding='16,16,16,16' spacing='8'> "
+"<layout type='vertical' padding='8,8,8,8' spacing='6'> "
"<widget name='EnableTabCheckbox' "
"type='Checkbox' "
"/> "
@@ -486,7 +1099,7 @@
"</layout> "
"</dialog> "
"<dialog name='GameOptions_Volume' overlays='Dialog.GlobalOptions.TabWidget'> "
-"<layout type='vertical' padding='16,16,16,16' spacing='8'> "
+"<layout type='vertical' padding='8,8,8,8' spacing='6'> "
"<widget name='EnableTabCheckbox' "
"type='Checkbox' "
"/> "
@@ -494,34 +1107,43 @@
"</layout> "
"</dialog> "
"<dialog name='GameOptions_Game' overlays='Dialog.GameOptions.TabWidget' shading='dim'> "
-"<layout type='vertical' padding='16,16,16,16'> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> "
+"<layout type='vertical' padding='8,8,8,8'> "
+"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> "
"<widget name='Id' "
-"type='OptionsLabel' "
+"width='35' "
+"height='Globals.Line.Height' "
+"textalign='right' "
"/> "
"<widget name='Domain' "
"type='PopUp' "
"/> "
"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> "
+"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> "
"<widget name='Name' "
-"type='OptionsLabel' "
+"width='35' "
+"height='Globals.Line.Height' "
+"textalign='right' "
"/> "
"<widget name='Desc' "
"type='PopUp' "
"/> "
"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> "
+"<space size='8'/> "
+"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> "
"<widget name='LangPopupDesc' "
-"type='OptionsLabel' "
+"width='60' "
+"height='Globals.Line.Height' "
+"textalign='right' "
"/> "
"<widget name='LangPopup' "
"type='PopUp' "
"/> "
"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> "
+"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> "
"<widget name='PlatformPopupDesc' "
-"type='OptionsLabel' "
+"width='60' "
+"height='Globals.Line.Height' "
+"textalign='right' "
"/> "
"<widget name='PlatformPopup' "
"type='PopUp' "
@@ -530,24 +1152,32 @@
"</layout> "
"</dialog> "
"<dialog name='GameOptions_Paths' overlays='Dialog.GameOptions.TabWidget' shading='dim'> "
-"<layout type='vertical' padding='16,16,16,16'> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> "
+"<layout type='vertical' padding='8,8,8,8'> "
+"<layout type='horizontal' padding='0,0,0,0' spacing='16' center='true'> "
"<widget name='Savepath' "
"type='Button' "
"/> "
"<widget name='SavepathText' "
"height='Globals.Line.Height' "
"/> "
+"<widget name='SavePathClearButton' "
+"height='Globals.Line.Height' "
+"width='Globals.Line.Height' "
+"/> "
"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> "
+"<layout type='horizontal' padding='0,0,0,0' spacing='16' center='true'> "
"<widget name='Extrapath' "
"type='Button' "
"/> "
"<widget name='ExtrapathText' "
"height='Globals.Line.Height' "
"/> "
+"<widget name='ExtraPathClearButton' "
+"height='Globals.Line.Height' "
+"width='Globals.Line.Height' "
+"/> "
"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> "
+"<layout type='horizontal' padding='0,0,0,0' spacing='16' center='true'> "
"<widget name='Gamepath' "
"type='Button' "
"/> "
@@ -558,57 +1188,55 @@
"</layout> "
"</dialog> "
"<dialog name='GlobalMenu' overlays='screen_center'> "
-"<layout type='vertical' padding='16,16,16,16' center='true'> "
+"<layout type='vertical' padding='2,2,4,6' center='true' spacing='6'> "
"<widget name='Title' "
-"width='210' "
-"height='Globals.Line.Height' "
+"width='160' "
+"height='4' "
"/> "
"<widget name='Version' "
-"width='210' "
-"height='Globals.Line.Height' "
-"/> "
-"<widget name='Resume' "
-"width='150' "
-"height='Globals.Button.Height' "
+"width='160' "
+"height='4' "
"/> "
-"<space size='10'/> "
+"<space size='1'/> "
"<widget name='Load' "
-"width='150' "
-"height='Globals.Button.Height' "
+"width='120' "
+"height='12' "
"/> "
"<widget name='Save' "
-"width='150' "
-"height='Globals.Button.Height' "
+"width='120' "
+"height='12' "
"/> "
-"<space size='10'/> "
+"<space size='1'/> "
"<widget name='Options' "
-"width='150' "
-"height='Globals.Button.Height' "
+"width='120' "
+"height='12' "
"/> "
"<widget name='Help' "
-"width='150' "
-"height='Globals.Button.Height' "
+"width='120' "
+"height='12' "
"/> "
"<widget name='About' "
-"width='150' "
-"height='Globals.Button.Height' "
+"width='120' "
+"height='12' "
+"/> "
+"<space size='1'/> "
+"<widget name='Resume' "
+"width='120' "
+"height='12' "
"/> "
-"<space size='10'/> "
"<widget name='RTL' "
-"width='150' "
-"height='Globals.Button.Height' "
+"width='120' "
+"height='12' "
"/> "
"<widget name='Quit' "
-"width='150' "
-"height='Globals.Button.Height' "
+"width='120' "
+"height='12' "
"/> "
"</layout> "
"</dialog> "
"<dialog name='GlobalConfig' overlays='screen_center'> "
"<layout type='vertical' padding='8,8,8,8'> "
-"<layout type='horizontal' padding='0,0,0,0'> "
-"<layout type='vertical' padding='0,0,0,0' center='true'> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='8'> "
+"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> "
"<widget name='vcMusicText' "
"type='OptionsLabel' "
"/> "
@@ -619,7 +1247,7 @@
"type='SmallLabel' "
"/> "
"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='8'> "
+"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> "
"<widget name='vcSfxText' "
"type='OptionsLabel' "
"/> "
@@ -630,7 +1258,7 @@
"type='SmallLabel' "
"/> "
"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='8'> "
+"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> "
"<widget name='vcSpeechText' "
"type='OptionsLabel' "
"/> "
@@ -641,33 +1269,34 @@
"type='SmallLabel' "
"/> "
"</layout> "
-"</layout> "
-"<layout type='vertical' padding='24,24,24,24' center='true'> "
+"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> "
+"<space size='110' /> "
"<widget name='vcMuteCheckbox' "
"type='Checkbox' "
-"width='80' "
+"width='80' "
"/> "
"</layout> "
-"</layout> "
-"<space size='8' /> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='10'> "
+"<layout type='vertical' padding='0,0,0,0' spacing='1' center='true'> "
"<widget name='subToggleDesc' "
"type='OptionsLabel' "
"/> "
+"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> "
"<widget name='subToggleSpeechOnly' "
"type='Radiobutton' "
-"width='100' "
+"width='90' "
"/> "
"<widget name='subToggleSubOnly' "
"type='Radiobutton' "
-"width='100' "
+"width='90' "
"/> "
"<widget name='subToggleSubBoth' "
"type='Radiobutton' "
-"width='100' "
+"width='90' "
"/> "
"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='10'> "
+"</layout> "
+"<space size='2' /> "
+"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> "
"<widget name='subSubtitleSpeedDesc' "
"type='OptionsLabel' "
"/> "
@@ -678,8 +1307,8 @@
"type='SmallLabel' "
"/> "
"</layout> "
-"<space size='60'/> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='10'> "
+"<space size='16'/> "
+"<layout type='horizontal' padding='0,0,0,0' spacing='4'> "
"<widget name='Keys' "
"type='Button' "
"/> "
@@ -694,23 +1323,15 @@
"</layout> "
"</dialog> "
"<dialog name='SaveLoadChooser' overlays='screen' inset='8' shading='dim'> "
-"<layout type='vertical' padding='8,8,8,32' center='true'> "
-"<widget name='Title' "
-"height='Globals.Line.Height' "
-"/> "
-"<layout type='horizontal' padding='0,0,0,16' spacing='16'> "
+"<layout type='vertical' padding='8,8,8,8' center='true'> "
+"<widget name='Title' height='Globals.Line.Height'/> "
"<widget name='List' /> "
-"<widget name='Thumbnail' "
-"width='180' "
-"height='200' "
-"/> "
-"</layout> "
-"<layout type='horizontal' padding='0,0,0,0'> "
+"<layout type='horizontal' padding='0,0,16,0'> "
"<space/> "
"<widget name='Delete' "
"type='Button' "
"/> "
-"<space size='32'/> "
+"<space size='16'/> "
"<widget name='Cancel' "
"type='Button' "
"/> "
@@ -720,16 +1341,16 @@
"</layout> "
"</layout> "
"</dialog> "
-"<dialog name='ScummHelp' overlays='screen_center'> "
-"<layout type='vertical' padding='8,8,8,8' center='true'> "
+"<dialog name='ScummHelp' overlays='screen'> "
+"<layout type='vertical' padding='8,8,8,8'> "
"<widget name='Title' "
-"width='320' "
+"width='180' "
"height='Globals.Line.Height' "
"/> "
"<widget name='HelpText' "
-"height='200' "
+"height='140' "
"/> "
-"<layout type='horizontal' padding='0,0,16,0'> "
+"<layout type='horizontal' padding='0,0,0,0'> "
"<widget name='Prev' "
"type='Button' "
"/> "
@@ -743,21 +1364,41 @@
"</layout> "
"</layout> "
"</dialog> "
+"<dialog name='LoomTownsDifficultyDialog' overlays='screen_center'> "
+"<layout type='vertical' padding='8,8,8,8' center='true'> "
+"<widget name='Description1' "
+"width='280' "
+"height='Globals.Line.Height' "
+"/> "
+"<widget name='Description2' "
+"height='Globals.Line.Height' "
+"/> "
+"<widget name='Standard' "
+"type='Button' "
+"/> "
+"<widget name='Practice' "
+"type='Button' "
+"/> "
+"<widget name='Expert' "
+"type='Button' "
+"/> "
+"</layout> "
+"</dialog> "
"<dialog name='MassAdd' overlays='screen_center' shading='dim'> "
-"<layout type='vertical' padding='8,8,32,8' center='true'> "
+"<layout type='vertical' padding='4,4,16,4' center='true'> "
"<widget name='DirProgressText' "
-"width='480' "
+"width='280' "
"height='Globals.Line.Height' "
"/> "
"<widget name='GameProgressText' "
-"width='480' "
+"width='280' "
"height='Globals.Line.Height' "
"/> "
"<widget name='GameList' "
-"width='480' "
-"height='250' "
+"width='280' "
+"height='100' "
"/> "
-"<layout type='horizontal' padding='8,8,8,8'> "
+"<layout type='horizontal' padding='4,4,4,4'> "
"<widget name='Ok' "
"type='Button' "
"/> "
@@ -768,20 +1409,20 @@
"</layout> "
"</dialog> "
"<dialog name='KeyMapper' overlays='screen_center' shading='dim'> "
-"<layout type='vertical' padding='8,8,32,8' spacing='10' center='true'> "
+"<layout type='vertical' padding='8,8,8,8' spacing='10' center='true'> "
"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> "
"<widget name='PopupDesc' "
"type='OptionsLabel' "
"/> "
"<widget name='Popup' "
"type='PopUp' "
-"width='400' "
+"width='150' "
"height='Globals.Line.Height' "
"/> "
"</layout> "
"<widget name='KeymapArea' "
-"width='600' "
-"height='280' "
+"width='300' "
+"height='120' "
"/> "
"<widget name='Close' "
"type='Button' "
@@ -789,46 +1430,49 @@
"</layout> "
"</dialog> "
"</layout_info> "
-"<layout_info resolution='y<400'> "
+"<layout_info resolution='y>399'> "
"<globals> "
-"<def var='Line.Height' value='12' /> "
-"<def var='Font.Height' value='10' /> "
-"<def var='About.OuterBorder' value='10'/> "
-"<def var='Layout.Spacing' value='8'/> "
+"<def var='Line.Height' value='16' /> "
+"<def var='Font.Height' value='16' /> "
+"<def var='About.OuterBorder' value='80'/> "
+"<def var='Layout.Spacing' value='8' /> "
"<def var='ShowLauncherLogo' value='0'/> "
"<def var='ShowGlobalMenuLogo' value='0'/> "
"<def var='ShowSearchPic' value='0'/> "
-"<def var='SaveLoadChooser.ExtInfo.Visible' value='0'/> "
-"<def var='KeyMapper.Spacing' value='5'/> "
-"<def var='KeyMapper.LabelWidth' value='80'/> "
-"<def var='KeyMapper.ButtonWidth' value='60'/> "
-"<def var='Tooltip.MaxWidth' value='70'/> "
-"<def var='Tooltip.XDelta' value='8'/> "
-"<def var='Tooltip.YDelta' value='8'/> "
-"<widget name='Button' "
-"size='72,16' "
-"/> "
-"<widget name='Slider' "
-"size='85,12' "
-"/> "
+"<def var='SaveLoadChooser.ExtInfo.Visible' value='1'/> "
+"<def var='KeyMapper.Spacing' value='10'/> "
+"<def var='KeyMapper.LabelWidth' value='100'/> "
+"<def var='KeyMapper.ButtonWidth' value='80'/> "
+"<def var='Tooltip.MaxWidth' value='200'/> "
+"<def var='Tooltip.XDelta' value='16'/> "
+"<def var='Tooltip.YDelta' value='16'/> "
"<widget name='OptionsLabel' "
"size='110,Globals.Line.Height' "
"textalign='right' "
"/> "
"<widget name='SmallLabel' "
-"size='18,Globals.Line.Height' "
+"size='24,Globals.Line.Height' "
+"/> "
+"<widget name='ShortOptionsLabel' "
+"size='60,Globals.Line.Height' "
+"/> "
+"<widget name='Button' "
+"size='108,24' "
+"/> "
+"<widget name='Slider' "
+"size='128,18' "
"/> "
"<widget name='PopUp' "
-"size='-1,15' "
+"size='-1,19' "
"/> "
"<widget name='Checkbox' "
-"size='-1,Globals.Line.Height' "
+"size='-1,14' "
"/> "
"<widget name='Radiobutton' "
"size='-1,Globals.Line.Height' "
"/> "
"<widget name='ListWidget' "
-"padding='5,0,0,0' "
+"padding='5,0,8,0' "
"/> "
"<widget name='PopUpWidget' "
"padding='7,5,0,0' "
@@ -840,28 +1484,28 @@
"padding='7,5,5,5' "
"/> "
"<widget name='Scrollbar' "
-"size='9,0' "
+"size='15,0' "
"/> "
"<widget name='TabWidget.Tab' "
-"size='45,16' "
-"padding='0,0,2,0' "
+"size='75,27' "
+"padding='0,0,8,0' "
"/> "
"<widget name='TabWidget.Body' "
-"padding='0,0,0,-8' "
+"padding='0,0,0,0' "
"/> "
"<widget name='TabWidget.NavButton' "
-"size='32,18' "
-"padding='0,0,1,0' "
+"size='15,18' "
+"padding='0,3,4,0' "
"/> "
"</globals> "
"<dialog name='Launcher' overlays='screen'> "
-"<layout type='vertical' center='true' padding='6,6,2,2'> "
+"<layout type='vertical' center='true' padding='16,16,8,8'> "
"<widget name='Version' "
"height='Globals.Line.Height' "
"/> "
-"<layout type='horizontal' spacing='5' padding='0,0,0,0'> "
+"<layout type='horizontal' spacing='5' padding='10,0,0,0'> "
"<widget name='SearchDesc' "
-"width='50' "
+"width='60' "
"height='Globals.Line.Height' "
"textalign='right' "
"/> "
@@ -876,38 +1520,39 @@
"<space /> "
"</layout> "
"<widget name='GameList'/> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='8'> "
+"<layout type='horizontal' padding='0,0,0,0' spacing='10'> "
"<widget name='LoadGameButton' "
-"height='12' "
+"height='20' "
"/> "
"<widget name='AddGameButton' "
-"height='12' "
+"height='20' "
"/> "
"<widget name='EditGameButton' "
-"height='12' "
+"height='20' "
"/> "
"<widget name='RemoveGameButton' "
-"height='12' "
+"height='20' "
"/> "
"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='8'> "
+"<space size='4'/> "
+"<layout type='horizontal' padding='0,0,0,0' spacing='10'> "
"<widget name='QuitButton' "
-"height='12' "
+"height='20' "
"/> "
"<widget name='AboutButton' "
-"height='12' "
+"height='20' "
"/> "
"<widget name='OptionsButton' "
-"height='12' "
+"height='20' "
"/> "
"<widget name='StartButton' "
-"height='12' "
+"height='20' "
"/> "
"</layout> "
"</layout> "
"</dialog> "
-"<dialog name='Browser' overlays='screen' inset='8' shading='dim'> "
-"<layout type='vertical' padding='8,8,0,4'> "
+"<dialog name='Browser' overlays='Dialog.Launcher.GameList' shading='dim'> "
+"<layout type='vertical' padding='8,8,8,8'> "
"<widget name='Headline' "
"height='Globals.Line.Height' "
"/> "
@@ -915,7 +1560,7 @@
"height='Globals.Line.Height' "
"/> "
"<widget name='List'/> "
-"<layout type='horizontal' padding='0,0,8,0'> "
+"<layout type='horizontal' padding='0,0,16,0'> "
"<widget name='Up' "
"type='Button' "
"/> "
@@ -929,10 +1574,10 @@
"</layout> "
"</layout> "
"</dialog> "
-"<dialog name='GlobalOptions' overlays='screen' inset='16' shading='dim'> "
+"<dialog name='GlobalOptions' overlays='Dialog.Launcher.GameList' shading='dim'> "
"<layout type='vertical' padding='0,0,0,0'> "
"<widget name='TabWidget'/> "
-"<layout type='horizontal' padding='8,8,8,8'> "
+"<layout type='horizontal' padding='16,16,16,16'> "
"<space/> "
"<widget name='Cancel' "
"type='Button' "
@@ -945,7 +1590,7 @@
"</dialog> "
"<dialog name='GlobalOptions_Graphics' overlays='Dialog.GlobalOptions.TabWidget'> "
"<layout type='vertical' padding='16,16,16,16' spacing='8'> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> "
+"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> "
"<widget name='grModePopupDesc' "
"type='OptionsLabel' "
"/> "
@@ -953,7 +1598,7 @@
"type='PopUp' "
"/> "
"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> "
+"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> "
"<widget name='grRenderPopupDesc' "
"type='OptionsLabel' "
"/> "
@@ -974,7 +1619,7 @@
"</dialog> "
"<dialog name='GlobalOptions_Audio' overlays='Dialog.GlobalOptions.TabWidget'> "
"<layout type='vertical' padding='16,16,16,16' spacing='8'> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> "
+"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> "
"<widget name='auMidiPopupDesc' "
"type='OptionsLabel' "
"/> "
@@ -982,7 +1627,7 @@
"type='PopUp' "
"/> "
"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> "
+"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> "
"<widget name='auOPLPopupDesc' "
"type='OptionsLabel' "
"/> "
@@ -990,7 +1635,7 @@
"type='PopUp' "
"/> "
"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> "
+"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> "
"<widget name='auSampleRatePopupDesc' "
"type='OptionsLabel' "
"/> "
@@ -998,7 +1643,7 @@
"type='PopUp' "
"/> "
"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='3' center='true'> "
+"<layout type='horizontal' padding='0,0,0,0' spacing='10'> "
"<widget name='subToggleDesc' "
"type='OptionsLabel' "
"/> "
@@ -1012,7 +1657,7 @@
"type='Radiobutton' "
"/> "
"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> "
+"<layout type='horizontal' padding='0,0,0,0' spacing='10'> "
"<widget name='subSubtitleSpeedDesc' "
"type='OptionsLabel' "
"/> "
@@ -1026,8 +1671,9 @@
"</layout> "
"</dialog> "
"<dialog name='GlobalOptions_Volume' overlays='Dialog.GlobalOptions.TabWidget'> "
-"<layout type='vertical' padding='16,16,16,16' spacing='8'> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> "
+"<layout type='horizontal' padding='16,16,16,16' spacing='8'> "
+"<layout type='vertical' padding='0,0,0,0' spacing='8'> "
+"<layout type='horizontal' padding='0,0,0,0'> "
"<widget name='vcMusicText' "
"type='OptionsLabel' "
"/> "
@@ -1038,7 +1684,7 @@
"type='SmallLabel' "
"/> "
"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> "
+"<layout type='horizontal' padding='0,0,0,0'> "
"<widget name='vcSfxText' "
"type='OptionsLabel' "
"/> "
@@ -1049,7 +1695,7 @@
"type='SmallLabel' "
"/> "
"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> "
+"<layout type='horizontal' padding='0,0,0,0'> "
"<widget name='vcSpeechText' "
"type='OptionsLabel' "
"/> "
@@ -1060,8 +1706,8 @@
"type='SmallLabel' "
"/> "
"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> "
-"<space size='110' /> "
+"</layout> "
+"<layout type='vertical' padding='24,0,24,0' center='true'> "
"<widget name='vcMuteCheckbox' "
"type='Checkbox' "
"/> "
@@ -1070,7 +1716,7 @@
"</dialog> "
"<dialog name='GlobalOptions_MIDI' overlays='Dialog.GlobalOptions.TabWidget'> "
"<layout type='vertical' padding='16,16,16,16' spacing='8'> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> "
+"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> "
"<widget name='auPrefGmPopupDesc' "
"type='OptionsLabel' "
"/> "
@@ -1078,7 +1724,7 @@
"type='PopUp' "
"/> "
"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='16' center='true'> "
+"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> "
"<widget name='mcFontButton' "
"type='Button' "
"/> "
@@ -1093,7 +1739,7 @@
"<widget name='mcMixedCheckbox' "
"type='Checkbox' "
"/> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> "
+"<layout type='horizontal' padding='0,0,0,0'> "
"<widget name='mcMidiGainText' "
"type='OptionsLabel' "
"/> "
@@ -1109,7 +1755,7 @@
"</dialog> "
"<dialog name='GlobalOptions_MT32' overlays='Dialog.GlobalOptions.TabWidget'> "
"<layout type='vertical' padding='16,16,16,16' spacing='8'> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> "
+"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> "
"<widget name='auPrefMt32PopupDesc' "
"type='OptionsLabel' "
"/> "
@@ -1127,29 +1773,41 @@
"</dialog> "
"<dialog name='GlobalOptions_Paths' overlays='Dialog.GlobalOptions.TabWidget'> "
"<layout type='vertical' padding='16,16,16,16' spacing='8'> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='16'> "
+"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> "
"<widget name='SaveButton' "
"type='Button' "
"/> "
"<widget name='SavePath' "
"height='Globals.Line.Height' "
"/> "
+"<widget name='SavePathClearButton' "
+"height='Globals.Line.Height' "
+"width='Globals.Line.Height' "
+"/> "
"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='16'> "
+"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> "
"<widget name='ThemeButton' "
"type='Button' "
"/> "
"<widget name='ThemePath' "
"height='Globals.Line.Height' "
"/> "
+"<widget name='ThemePathClearButton' "
+"height='Globals.Line.Height' "
+"width='Globals.Line.Height' "
+"/> "
"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='16'> "
+"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> "
"<widget name='ExtraButton' "
"type='Button' "
"/> "
"<widget name='ExtraPath' "
"height='Globals.Line.Height' "
"/> "
+"<widget name='ExtraPathClearButton' "
+"height='Globals.Line.Height' "
+"width='Globals.Line.Height' "
+"/> "
"</layout> "
"<layout type='horizontal' padding='0,0,0,0' spacing='16'> "
"<widget name='PluginsButton' "
@@ -1163,7 +1821,7 @@
"</dialog> "
"<dialog name='GlobalOptions_Misc' overlays='Dialog.GlobalOptions.TabWidget'> "
"<layout type='vertical' padding='16,16,16,16' spacing='8'> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='16'> "
+"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> "
"<widget name='ThemeButton' "
"type='Button' "
"/> "
@@ -1171,31 +1829,25 @@
"height='Globals.Line.Height' "
"/> "
"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> "
+"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> "
"<widget name='RendererPopupDesc' "
-"width='80' "
-"height='Globals.Line.Height' "
-"textalign='right' "
+"type='OptionsLabel' "
"/> "
"<widget name='RendererPopup' "
"type='PopUp' "
"/> "
"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> "
+"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> "
"<widget name='AutosavePeriodPopupDesc' "
-"width='80' "
-"height='Globals.Line.Height' "
-"textalign='right' "
+"type='OptionsLabel' "
"/> "
"<widget name='AutosavePeriodPopup' "
"type='PopUp' "
"/> "
"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> "
+"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> "
"<widget name='GuiLanguagePopupDesc' "
-"width='80' "
-"height='Globals.Line.Height' "
-"textalign='right' "
+"type='OptionsLabel' "
"/> "
"<widget name='GuiLanguagePopup' "
"type='PopUp' "
@@ -1230,10 +1882,10 @@
"</layout> "
"</layout> "
"</dialog> "
-"<dialog name='GameOptions' overlays='screen' inset='16' shading='dim'> "
+"<dialog name='GameOptions' overlays='Dialog.Launcher.GameList' shading='dim'> "
"<layout type='vertical' padding='0,0,0,0' spacing='16'> "
"<widget name='TabWidget'/> "
-"<layout type='horizontal' padding='8,8,8,8'> "
+"<layout type='horizontal' padding='16,16,16,4'> "
"<space/> "
"<widget name='Cancel' "
"type='Button' "
@@ -1245,7 +1897,7 @@
"</layout> "
"</dialog> "
"<dialog name='GameOptions_Graphics' overlays='Dialog.GlobalOptions.TabWidget'> "
-"<layout type='vertical' padding='8,8,8,8' spacing='6'> "
+"<layout type='vertical' padding='16,16,16,16' spacing='8'> "
"<widget name='EnableTabCheckbox' "
"type='Checkbox' "
"/> "
@@ -1253,7 +1905,7 @@
"</layout> "
"</dialog> "
"<dialog name='GameOptions_Audio' overlays='Dialog.GlobalOptions.TabWidget'> "
-"<layout type='vertical' padding='8,8,8,8' spacing='6'> "
+"<layout type='vertical' padding='16,16,16,16' spacing='8'> "
"<widget name='EnableTabCheckbox' "
"type='Checkbox' "
"/> "
@@ -1261,7 +1913,7 @@
"</layout> "
"</dialog> "
"<dialog name='GameOptions_MIDI' overlays='Dialog.GlobalOptions.TabWidget'> "
-"<layout type='vertical' padding='8,8,8,8' spacing='6'> "
+"<layout type='vertical' padding='16,16,16,16' spacing='8'> "
"<widget name='EnableTabCheckbox' "
"type='Checkbox' "
"/> "
@@ -1269,7 +1921,7 @@
"</layout> "
"</dialog> "
"<dialog name='GameOptions_MT32' overlays='Dialog.GlobalOptions.TabWidget'> "
-"<layout type='vertical' padding='8,8,8,8' spacing='6'> "
+"<layout type='vertical' padding='16,16,16,16' spacing='8'> "
"<widget name='EnableTabCheckbox' "
"type='Checkbox' "
"/> "
@@ -1277,7 +1929,7 @@
"</layout> "
"</dialog> "
"<dialog name='GameOptions_Volume' overlays='Dialog.GlobalOptions.TabWidget'> "
-"<layout type='vertical' padding='8,8,8,8' spacing='6'> "
+"<layout type='vertical' padding='16,16,16,16' spacing='8'> "
"<widget name='EnableTabCheckbox' "
"type='Checkbox' "
"/> "
@@ -1285,43 +1937,34 @@
"</layout> "
"</dialog> "
"<dialog name='GameOptions_Game' overlays='Dialog.GameOptions.TabWidget' shading='dim'> "
-"<layout type='vertical' padding='8,8,8,8'> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> "
+"<layout type='vertical' padding='16,16,16,16'> "
+"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> "
"<widget name='Id' "
-"width='35' "
-"height='Globals.Line.Height' "
-"textalign='right' "
+"type='OptionsLabel' "
"/> "
"<widget name='Domain' "
"type='PopUp' "
"/> "
"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> "
+"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> "
"<widget name='Name' "
-"width='35' "
-"height='Globals.Line.Height' "
-"textalign='right' "
+"type='OptionsLabel' "
"/> "
"<widget name='Desc' "
"type='PopUp' "
"/> "
"</layout> "
-"<space size='8'/> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> "
+"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> "
"<widget name='LangPopupDesc' "
-"width='60' "
-"height='Globals.Line.Height' "
-"textalign='right' "
+"type='OptionsLabel' "
"/> "
"<widget name='LangPopup' "
"type='PopUp' "
"/> "
"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> "
+"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> "
"<widget name='PlatformPopupDesc' "
-"width='60' "
-"height='Globals.Line.Height' "
-"textalign='right' "
+"type='OptionsLabel' "
"/> "
"<widget name='PlatformPopup' "
"type='PopUp' "
@@ -1330,24 +1973,32 @@
"</layout> "
"</dialog> "
"<dialog name='GameOptions_Paths' overlays='Dialog.GameOptions.TabWidget' shading='dim'> "
-"<layout type='vertical' padding='8,8,8,8'> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='16' center='true'> "
+"<layout type='vertical' padding='16,16,16,16'> "
+"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> "
"<widget name='Savepath' "
"type='Button' "
"/> "
"<widget name='SavepathText' "
"height='Globals.Line.Height' "
"/> "
+"<widget name='SavePathClearButton' "
+"height='Globals.Line.Height' "
+"width='Globals.Line.Height' "
+"/> "
"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='16' center='true'> "
+"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> "
"<widget name='Extrapath' "
"type='Button' "
"/> "
"<widget name='ExtrapathText' "
"height='Globals.Line.Height' "
"/> "
+"<widget name='ExtraPathClearButton' "
+"height='Globals.Line.Height' "
+"width='Globals.Line.Height' "
+"/> "
"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='16' center='true'> "
+"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> "
"<widget name='Gamepath' "
"type='Button' "
"/> "
@@ -1358,55 +2009,57 @@
"</layout> "
"</dialog> "
"<dialog name='GlobalMenu' overlays='screen_center'> "
-"<layout type='vertical' padding='2,2,4,6' center='true' spacing='6'> "
+"<layout type='vertical' padding='16,16,16,16' center='true'> "
"<widget name='Title' "
-"width='160' "
-"height='4' "
+"width='210' "
+"height='Globals.Line.Height' "
"/> "
"<widget name='Version' "
-"width='160' "
-"height='4' "
+"width='210' "
+"height='Globals.Line.Height' "
"/> "
-"<space size='1'/> "
+"<widget name='Resume' "
+"width='150' "
+"height='Globals.Button.Height' "
+"/> "
+"<space size='10'/> "
"<widget name='Load' "
-"width='120' "
-"height='12' "
+"width='150' "
+"height='Globals.Button.Height' "
"/> "
"<widget name='Save' "
-"width='120' "
-"height='12' "
+"width='150' "
+"height='Globals.Button.Height' "
"/> "
-"<space size='1'/> "
+"<space size='10'/> "
"<widget name='Options' "
-"width='120' "
-"height='12' "
+"width='150' "
+"height='Globals.Button.Height' "
"/> "
"<widget name='Help' "
-"width='120' "
-"height='12' "
+"width='150' "
+"height='Globals.Button.Height' "
"/> "
"<widget name='About' "
-"width='120' "
-"height='12' "
-"/> "
-"<space size='1'/> "
-"<widget name='Resume' "
-"width='120' "
-"height='12' "
+"width='150' "
+"height='Globals.Button.Height' "
"/> "
+"<space size='10'/> "
"<widget name='RTL' "
-"width='120' "
-"height='12' "
+"width='150' "
+"height='Globals.Button.Height' "
"/> "
"<widget name='Quit' "
-"width='120' "
-"height='12' "
+"width='150' "
+"height='Globals.Button.Height' "
"/> "
"</layout> "
"</dialog> "
"<dialog name='GlobalConfig' overlays='screen_center'> "
"<layout type='vertical' padding='8,8,8,8'> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> "
+"<layout type='horizontal' padding='0,0,0,0'> "
+"<layout type='vertical' padding='0,0,0,0' center='true'> "
+"<layout type='horizontal' padding='0,0,0,0' spacing='8'> "
"<widget name='vcMusicText' "
"type='OptionsLabel' "
"/> "
@@ -1417,7 +2070,7 @@
"type='SmallLabel' "
"/> "
"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> "
+"<layout type='horizontal' padding='0,0,0,0' spacing='8'> "
"<widget name='vcSfxText' "
"type='OptionsLabel' "
"/> "
@@ -1428,7 +2081,7 @@
"type='SmallLabel' "
"/> "
"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> "
+"<layout type='horizontal' padding='0,0,0,0' spacing='8'> "
"<widget name='vcSpeechText' "
"type='OptionsLabel' "
"/> "
@@ -1439,34 +2092,33 @@
"type='SmallLabel' "
"/> "
"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> "
-"<space size='110' /> "
+"</layout> "
+"<layout type='vertical' padding='24,24,24,24' center='true'> "
"<widget name='vcMuteCheckbox' "
"type='Checkbox' "
-"width='80' "
+"width='80' "
"/> "
"</layout> "
-"<layout type='vertical' padding='0,0,0,0' spacing='1' center='true'> "
+"</layout> "
+"<space size='8' /> "
+"<layout type='horizontal' padding='0,0,0,0' spacing='10'> "
"<widget name='subToggleDesc' "
"type='OptionsLabel' "
"/> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> "
"<widget name='subToggleSpeechOnly' "
"type='Radiobutton' "
-"width='90' "
+"width='100' "
"/> "
"<widget name='subToggleSubOnly' "
"type='Radiobutton' "
-"width='90' "
+"width='100' "
"/> "
"<widget name='subToggleSubBoth' "
"type='Radiobutton' "
-"width='90' "
+"width='100' "
"/> "
"</layout> "
-"</layout> "
-"<space size='2' /> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> "
+"<layout type='horizontal' padding='0,0,0,0' spacing='10'> "
"<widget name='subSubtitleSpeedDesc' "
"type='OptionsLabel' "
"/> "
@@ -1477,8 +2129,8 @@
"type='SmallLabel' "
"/> "
"</layout> "
-"<space size='16'/> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='4'> "
+"<space size='60'/> "
+"<layout type='horizontal' padding='0,0,0,0' spacing='10'> "
"<widget name='Keys' "
"type='Button' "
"/> "
@@ -1493,15 +2145,23 @@
"</layout> "
"</dialog> "
"<dialog name='SaveLoadChooser' overlays='screen' inset='8' shading='dim'> "
-"<layout type='vertical' padding='8,8,8,8' center='true'> "
-"<widget name='Title' height='Globals.Line.Height'/> "
+"<layout type='vertical' padding='8,8,8,32' center='true'> "
+"<widget name='Title' "
+"height='Globals.Line.Height' "
+"/> "
+"<layout type='horizontal' padding='0,0,0,16' spacing='16'> "
"<widget name='List' /> "
-"<layout type='horizontal' padding='0,0,16,0'> "
+"<widget name='Thumbnail' "
+"width='180' "
+"height='200' "
+"/> "
+"</layout> "
+"<layout type='horizontal' padding='0,0,0,0'> "
"<space/> "
"<widget name='Delete' "
"type='Button' "
"/> "
-"<space size='16'/> "
+"<space size='32'/> "
"<widget name='Cancel' "
"type='Button' "
"/> "
@@ -1511,16 +2171,16 @@
"</layout> "
"</layout> "
"</dialog> "
-"<dialog name='ScummHelp' overlays='screen'> "
-"<layout type='vertical' padding='8,8,8,8'> "
+"<dialog name='ScummHelp' overlays='screen_center'> "
+"<layout type='vertical' padding='8,8,8,8' center='true'> "
"<widget name='Title' "
-"width='180' "
+"width='320' "
"height='Globals.Line.Height' "
"/> "
"<widget name='HelpText' "
-"height='140' "
+"height='200' "
"/> "
-"<layout type='horizontal' padding='0,0,0,0'> "
+"<layout type='horizontal' padding='0,0,16,0'> "
"<widget name='Prev' "
"type='Button' "
"/> "
@@ -1534,21 +2194,41 @@
"</layout> "
"</layout> "
"</dialog> "
+"<dialog name='LoomTownsDifficultyDialog' overlays='screen_center'> "
+"<layout type='vertical' padding='8,8,8,8' center='true'> "
+"<widget name='Description1' "
+"width='320' "
+"height='Globals.Line.Height' "
+"/> "
+"<widget name='Description2' "
+"height='Globals.Line.Height' "
+"/> "
+"<widget name='Standard' "
+"type='Button' "
+"/> "
+"<widget name='Practice' "
+"type='Button' "
+"/> "
+"<widget name='Expert' "
+"type='Button' "
+"/> "
+"</layout> "
+"</dialog> "
"<dialog name='MassAdd' overlays='screen_center' shading='dim'> "
-"<layout type='vertical' padding='4,4,16,4' center='true'> "
+"<layout type='vertical' padding='8,8,32,8' center='true'> "
"<widget name='DirProgressText' "
-"width='280' "
+"width='480' "
"height='Globals.Line.Height' "
"/> "
"<widget name='GameProgressText' "
-"width='280' "
+"width='480' "
"height='Globals.Line.Height' "
"/> "
"<widget name='GameList' "
-"width='280' "
-"height='100' "
+"width='480' "
+"height='250' "
"/> "
-"<layout type='horizontal' padding='4,4,4,4'> "
+"<layout type='horizontal' padding='8,8,8,8'> "
"<widget name='Ok' "
"type='Button' "
"/> "
@@ -1559,20 +2239,20 @@
"</layout> "
"</dialog> "
"<dialog name='KeyMapper' overlays='screen_center' shading='dim'> "
-"<layout type='vertical' padding='8,8,8,8' spacing='10' center='true'> "
+"<layout type='vertical' padding='8,8,32,8' spacing='10' center='true'> "
"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> "
"<widget name='PopupDesc' "
"type='OptionsLabel' "
"/> "
"<widget name='Popup' "
"type='PopUp' "
-"width='150' "
+"width='400' "
"height='Globals.Line.Height' "
"/> "
"</layout> "
"<widget name='KeymapArea' "
-"width='300' "
-"height='120' "
+"width='600' "
+"height='280' "
"/> "
"<widget name='Close' "
"type='Button' "
@@ -1580,443 +2260,3 @@
"</layout> "
"</dialog> "
"</layout_info> "
-"<render_info> "
-"<palette> "
-"<color name='black' "
-"rgb='0,0,0' "
-"/> "
-"<color name='lightgrey' "
-"rgb='104,104,104' "
-"/> "
-"<color name='darkgrey' "
-"rgb='64,64,64' "
-"/> "
-"<color name='green' "
-"rgb='32,160,32' "
-"/> "
-"<color name='green2' "
-"rgb='0,255,0' "
-"/> "
-"</palette> "
-"<fonts> "
-"<font id='text_default' "
-"file='helvb12.bdf' "
-"/> "
-"<font resolution='y<400' "
-"id='text_default' "
-"file='clR6x12.bdf' "
-"/> "
-"<font id='text_button' "
-"file='helvb12.bdf' "
-"/> "
-"<font resolution='y<400' "
-"id='text_button' "
-"file='clR6x12.bdf' "
-"/> "
-"<font id='text_normal' "
-"file='helvb12.bdf' "
-"/> "
-"<font resolution='y<400' "
-"id='text_normal' "
-"file='clR6x12.bdf' "
-"/> "
-"<font id='tooltip_normal' "
-"file='fixed5x8.bdf' "
-"/> "
-"<text_color id='color_normal' "
-"color='green' "
-"/> "
-"<text_color id='color_normal_inverted' "
-"color='black' "
-"/> "
-"<text_color id='color_normal_hover' "
-"color='green2' "
-"/> "
-"<text_color id='color_normal_disabled' "
-"color='lightgrey' "
-"/> "
-"<text_color id='color_alternative' "
-"color='lightgrey' "
-"/> "
-"<text_color id='color_alternative_inverted' "
-"color='255,255,255' "
-"/> "
-"<text_color id='color_alternative_hover' "
-"color='176,176,176' "
-"/> "
-"<text_color id='color_alternative_disabled' "
-"color='darkgrey' "
-"/> "
-"<text_color id='color_button' "
-"color='green' "
-"/> "
-"<text_color id='color_button_hover' "
-"color='green2' "
-"/> "
-"<text_color id='color_button_disabled' "
-"color='lightgrey' "
-"/> "
-"</fonts> "
-"<defaults fill='foreground' fg_color='darkgrey' bg_color='black' shadow='0' bevel_color='lightgrey'/> "
-"<drawdata id='text_selection' cache='false'> "
-"<drawstep func='square' "
-"fill='foreground' "
-"fg_color='lightgrey' "
-"/> "
-"</drawdata> "
-"<drawdata id='text_selection_focus' cache='false'> "
-"<drawstep func='square' "
-"fill='foreground' "
-"fg_color='green' "
-"/> "
-"</drawdata> "
-"<drawdata id='mainmenu_bg' cache='false'> "
-"<drawstep func='fill' "
-"fill='foreground' "
-"fg_color='black' "
-"/> "
-"</drawdata> "
-"<drawdata id='special_bg' cache='false'> "
-"<drawstep func='bevelsq' "
-"bevel='2' "
-"/> "
-"</drawdata> "
-"<drawdata id='tooltip_bg' cache='false'> "
-"<drawstep func='bevelsq' "
-"bevel='2' "
-"fill='foreground' "
-"fg_color='black' "
-"/> "
-"</drawdata> "
-"<drawdata id='separator' cache='false'> "
-"<drawstep func='square' "
-"fill='foreground' "
-"height='2' "
-"ypos='center' "
-"fg_color='lightgrey' "
-"/> "
-"</drawdata> "
-"<drawdata id='scrollbar_base' cache='false'> "
-"<drawstep func='bevelsq' "
-"bevel='2' "
-"/> "
-"</drawdata> "
-"<drawdata id='scrollbar_handle_hover' cache='false'> "
-"<drawstep func='square' "
-"fill='foreground' "
-"fg_color='green2' "
-"/> "
-"</drawdata> "
-"<drawdata id='scrollbar_handle_idle' cache='false'> "
-"<drawstep func='square' "
-"fill='foreground' "
-"fg_color='green' "
-"/> "
-"</drawdata> "
-"<drawdata id='scrollbar_button_idle' cache='false'> "
-"<drawstep func='bevelsq' "
-"bevel='2' "
-"fill='none' "
-"/> "
-"<drawstep func='triangle' "
-"fg_color='green' "
-"fill='foreground' "
-"width='auto' "
-"height='auto' "
-"xpos='center' "
-"ypos='center' "
-"orientation='top' "
-"/> "
-"</drawdata> "
-"<drawdata id='scrollbar_button_hover' cache='false'> "
-"<drawstep func='bevelsq' "
-"bevel='2' "
-"fill='none' "
-"/> "
-"<drawstep func='triangle' "
-"fg_color='green2' "
-"fill='foreground' "
-"width='auto' "
-"height='auto' "
-"xpos='center' "
-"ypos='center' "
-"orientation='top' "
-"/> "
-"</drawdata> "
-"<drawdata id='tab_active' cache='false'> "
-"<text font='text_default' "
-"text_color='color_normal_hover' "
-"vertical_align='center' "
-"horizontal_align='center' "
-"/> "
-"<drawstep func='tab' "
-"bevel='2' "
-"radius='0' "
-"fill='none' "
-"/> "
-"</drawdata> "
-"<drawdata id='tab_inactive' cache='false'> "
-"<text font='text_default' "
-"text_color='color_normal' "
-"vertical_align='center' "
-"horizontal_align='center' "
-"/> "
-"<drawstep func='tab' "
-"bevel='2' "
-"radius='0' "
-"fill='none' "
-"/> "
-"</drawdata> "
-"<drawdata id='tab_background' cache='false'> "
-"</drawdata> "
-"<drawdata id='widget_slider' cache='false'> "
-"<drawstep func='bevelsq' "
-"bevel='2' "
-"fill='none' "
-"/> "
-"</drawdata> "
-"<drawdata id='slider_disabled' cache='false'> "
-"<drawstep func='square' "
-"fill='foreground' "
-"fg_color='lightgrey' "
-"/> "
-"</drawdata> "
-"<drawdata id='slider_full' cache='false'> "
-"<drawstep func='square' "
-"fill='foreground' "
-"fg_color='green' "
-"/> "
-"</drawdata> "
-"<drawdata id='slider_hover' cache='false'> "
-"<drawstep func='square' "
-"fill='foreground' "
-"fg_color='green2' "
-"/> "
-"</drawdata> "
-"<drawdata id='widget_small' cache='false'> "
-"<drawstep func='bevelsq' "
-"bevel='2' "
-"fill='none' "
-"/> "
-"</drawdata> "
-"<drawdata id='popup_idle' cache='false'> "
-"<drawstep func='bevelsq' "
-"bevel='2' "
-"fill='none' "
-"/> "
-"<drawstep func='triangle' "
-"fg_color='green' "
-"fill='foreground' "
-"width='height' "
-"height='auto' "
-"xpos='right' "
-"ypos='center' "
-"orientation='bottom' "
-"/> "
-"<text font='text_default' "
-"text_color='color_normal' "
-"vertical_align='center' "
-"horizontal_align='left' "
-"/> "
-"</drawdata> "
-"<drawdata id='popup_disabled' cache='false'> "
-"<drawstep func='bevelsq' "
-"bevel='2' "
-"fill='none' "
-"/> "
-"<drawstep func='triangle' "
-"fg_color='lightgrey' "
-"fill='foreground' "
-"width='height' "
-"height='auto' "
-"xpos='right' "
-"ypos='center' "
-"orientation='bottom' "
-"/> "
-"<text font='text_default' "
-"text_color='color_normal_disabled' "
-"vertical_align='center' "
-"horizontal_align='left' "
-"/> "
-"</drawdata> "
-"<drawdata id='popup_hover' cache='false'> "
-"<drawstep func='bevelsq' "
-"bevel='2' "
-"fill='none' "
-"/> "
-"<drawstep func='triangle' "
-"fg_color='green2' "
-"fill='foreground' "
-"width='height' "
-"height='auto' "
-"xpos='right' "
-"ypos='center' "
-"orientation='bottom' "
-"/> "
-"<text font='text_default' "
-"text_color='color_normal_hover' "
-"vertical_align='center' "
-"horizontal_align='left' "
-"/> "
-"</drawdata> "
-"<drawdata id='widget_textedit' cache='false'> "
-"<drawstep func='bevelsq' "
-"bevel='2' "
-"fill='none' "
-"/> "
-"</drawdata> "
-"<drawdata id='plain_bg' cache='false'> "
-"<drawstep func='bevelsq' "
-"bevel='2' "
-"/> "
-"</drawdata> "
-"<drawdata id='caret' cache='false'> "
-"<drawstep func='square' "
-"fill='foreground' "
-"fg_color='lightgrey' "
-"/> "
-"</drawdata> "
-"<drawdata id='default_bg' cache='false'> "
-"<drawstep func='bevelsq' "
-"bevel='2' "
-"/> "
-"</drawdata> "
-"<drawdata id='button_idle' cache='false'> "
-"<text font='text_button' "
-"text_color='color_button' "
-"vertical_align='center' "
-"horizontal_align='center' "
-"/> "
-"<drawstep func='bevelsq' "
-"bevel='2' "
-"fill='none' "
-"/> "
-"</drawdata> "
-"<drawdata id='button_hover' cache='false'> "
-"<text font='text_button' "
-"text_color='color_button_hover' "
-"vertical_align='center' "
-"horizontal_align='center' "
-"/> "
-"<drawstep func='bevelsq' "
-"bevel='2' "
-"fill='none' "
-"/> "
-"</drawdata> "
-"<drawdata id='button_disabled' cache='false'> "
-"<text font='text_button' "
-"text_color='color_button_disabled' "
-"vertical_align='center' "
-"horizontal_align='center' "
-"/> "
-"<drawstep func='bevelsq' "
-"bevel='2' "
-"fill='none' "
-"/> "
-"</drawdata> "
-"<drawdata id='checkbox_disabled' cache='false'> "
-"<text font='text_default' "
-"text_color='color_normal_disabled' "
-"vertical_align='top' "
-"horizontal_align='left' "
-"/> "
-"<drawstep func='bevelsq' "
-"bevel='2' "
-"fill='none' "
-"/> "
-"</drawdata> "
-"<drawdata id='checkbox_selected' cache='false'> "
-"<text font='text_default' "
-"text_color='color_normal' "
-"vertical_align='top' "
-"horizontal_align='left' "
-"/> "
-"<drawstep func='bevelsq' "
-"bevel='2' "
-"fill='none' "
-"/> "
-"<drawstep func='cross' "
-"fill='foreground' "
-"stroke='2' "
-"fg_color='green' "
-"/> "
-"</drawdata> "
-"<drawdata id='checkbox_default' cache='false'> "
-"<text font='text_default' "
-"text_color='color_normal' "
-"vertical_align='top' "
-"horizontal_align='left' "
-"/> "
-"<drawstep func='bevelsq' "
-"bevel='2' "
-"fill='none' "
-"/> "
-"</drawdata> "
-"<drawdata id='radiobutton_default' cache='false'> "
-"<text font='text_default' "
-"text_color='color_normal' "
-"vertical_align='center' "
-"horizontal_align='left' "
-"/> "
-"<drawstep func='circle' "
-"width='7' "
-"height='7' "
-"radius='7' "
-"fill='background' "
-"bg_color='darkgrey' "
-"xpos='0' "
-"ypos='0' "
-"/> "
-"</drawdata> "
-"<drawdata id='radiobutton_selected' cache='false'> "
-"<text font='text_default' "
-"text_color='color_normal' "
-"vertical_align='center' "
-"horizontal_align='left' "
-"/> "
-"<drawstep func='circle' "
-"width='7' "
-"height='7' "
-"radius='7' "
-"fg_color='darkgrey' "
-"fill='none' "
-"xpos='0' "
-"ypos='0' "
-"/> "
-"<drawstep func='circle' "
-"width='7' "
-"height='7' "
-"radius='5' "
-"fg_color='green' "
-"fill='foreground' "
-"xpos='2' "
-"ypos='2' "
-"/> "
-"</drawdata> "
-"<drawdata id='radiobutton_disabled' cache='false'> "
-"<text font='text_default' "
-"text_color='color_normal_disabled' "
-"vertical_align='center' "
-"horizontal_align='left' "
-"/> "
-"<drawstep func='circle' "
-"width='7' "
-"height='7' "
-"radius='7' "
-"bg_color='lightgrey' "
-"fill='background' "
-"xpos='0' "
-"ypos='0' "
-"/> "
-"</drawdata> "
-"<drawdata id='widget_default' cache='false'> "
-"<drawstep func='bevelsq' "
-"bevel='2' "
-"/> "
-"</drawdata> "
-"<drawdata id='widget_small' cache='false'> "
-"<drawstep func='square' "
-"stroke='0' "
-"/> "
-"</drawdata> "
-"</render_info> "
diff --git a/gui/themes/fonts/FreeMonoBold.ttf b/gui/themes/fonts/FreeMonoBold.ttf
new file mode 100644
index 0000000000..3bce6129ae
--- /dev/null
+++ b/gui/themes/fonts/FreeMonoBold.ttf
Binary files differ
diff --git a/gui/themes/fonts/FreeSans.ttf b/gui/themes/fonts/FreeSans.ttf
new file mode 100644
index 0000000000..9db958532c
--- /dev/null
+++ b/gui/themes/fonts/FreeSans.ttf
Binary files differ
diff --git a/gui/themes/fonts/FreeSansBold.ttf b/gui/themes/fonts/FreeSansBold.ttf
new file mode 100644
index 0000000000..63644e7437
--- /dev/null
+++ b/gui/themes/fonts/FreeSansBold.ttf
Binary files differ
diff --git a/gui/themes/fonts/README b/gui/themes/fonts/README
index 594bfc3ea4..b36d89889c 100644
--- a/gui/themes/fonts/README
+++ b/gui/themes/fonts/README
@@ -1,3 +1,5 @@
These are fonts used in ScummVM. Most of them come from Xorg.
+The GNU FreeFont files are distributed under the license in COPYING.FREEFONT.
+
Also other potentially usable fonts are stored here as well.
diff --git a/gui/themes/scummclassic.zip b/gui/themes/scummclassic.zip
index 4dbedd4f14..d4cfd0cba3 100644
--- a/gui/themes/scummclassic.zip
+++ b/gui/themes/scummclassic.zip
Binary files differ
diff --git a/gui/themes/scummclassic/THEMERC b/gui/themes/scummclassic/THEMERC
index 17e934d5ef..f3904cbb6d 100644
--- a/gui/themes/scummclassic/THEMERC
+++ b/gui/themes/scummclassic/THEMERC
@@ -1 +1 @@
-[SCUMMVM_STX0.8.3:ScummVM Classic Theme:No Author]
+[SCUMMVM_STX0.8.8:ScummVM Classic Theme:No Author]
diff --git a/gui/themes/scummclassic/clR6x12-iso-8859-2.fcc b/gui/themes/scummclassic/clR6x12-iso-8859-2.fcc
index 042bc5b24d..4d225ddc23 100644
--- a/gui/themes/scummclassic/clR6x12-iso-8859-2.fcc
+++ b/gui/themes/scummclassic/clR6x12-iso-8859-2.fcc
Binary files differ
diff --git a/gui/themes/scummclassic/clR6x12-iso-8859-5.fcc b/gui/themes/scummclassic/clR6x12-iso-8859-5.fcc
index d8e614211d..37d4615ea0 100644
--- a/gui/themes/scummclassic/clR6x12-iso-8859-5.fcc
+++ b/gui/themes/scummclassic/clR6x12-iso-8859-5.fcc
Binary files differ
diff --git a/gui/themes/scummclassic/classic_gfx.stx b/gui/themes/scummclassic/classic_gfx.stx
index c0fcc9f083..f07499ce79 100644
--- a/gui/themes/scummclassic/classic_gfx.stx
+++ b/gui/themes/scummclassic/classic_gfx.stx
@@ -176,7 +176,7 @@
/>
</drawdata>
- <drawdata id = 'scrollbar_button_idle' cache = 'false'>
+ <drawdata id = 'scrollbar_button_idle' cache = 'false' resolution = 'y>399'>
<drawstep func = 'bevelsq'
bevel = '2'
fill = 'none'
@@ -184,26 +184,62 @@
<drawstep func = 'triangle'
fg_color = 'green'
fill = 'foreground'
- width = 'auto'
- height = 'auto'
- xpos = 'center'
+ width = '10'
+ height = '10'
+ xpos = 'right'
+ ypos = 'center'
+ padding = '0,0,3,0'
+ orientation = 'top'
+ />
+ </drawdata>
+
+ <drawdata id = 'scrollbar_button_idle' cache = 'false' resolution = 'y<400'>
+ <drawstep func = 'bevelsq'
+ bevel = '2'
+ fill = 'none'
+ />
+ <drawstep func = 'triangle'
+ fg_color = 'green'
+ fill = 'foreground'
+ width = '5'
+ height = '5'
+ xpos = 'right'
ypos = 'center'
+ padding = '0,0,2,0'
orientation = 'top'
/>
</drawdata>
- <drawdata id = 'scrollbar_button_hover' cache = 'false'>
+ <drawdata id = 'scrollbar_button_hover' cache = 'false' resolution = 'y>399'>
<drawstep func = 'bevelsq'
bevel = '2'
fill = 'none'
/>
<drawstep func = 'triangle'
- fg_color = 'green2'
+ fg_color = 'green'
+ fill = 'foreground'
+ width = '10'
+ height = '10'
+ xpos = 'right'
+ ypos = 'center'
+ padding = '0,0,3,0'
+ orientation = 'top'
+ />
+ </drawdata>
+
+ <drawdata id = 'scrollbar_button_hover' cache = 'false' resolution = 'y<400'>
+ <drawstep func = 'bevelsq'
+ bevel = '2'
+ fill = 'none'
+ />
+ <drawstep func = 'triangle'
+ fg_color = 'green'
fill = 'foreground'
- width = 'auto'
- height = 'auto'
- xpos = 'center'
+ width = '5'
+ height = '5'
+ xpos = 'right'
ypos = 'center'
+ padding = '0,0,2,0'
orientation = 'top'
/>
</drawdata>
@@ -272,20 +308,70 @@
/>
</drawdata>
- <drawdata id = 'popup_idle' cache = 'false'>
+ <!--popup_idle HERE -->
+ <drawdata id = 'popup_idle' cache = 'false' resolution = 'y>399'>
<drawstep func = 'bevelsq'
bevel = '2'
fill = 'none'
/>
+
<drawstep func = 'triangle'
fg_color = 'green'
fill = 'foreground'
- width = 'height'
- height = 'auto'
+ width = '10'
+ height = '5'
xpos = 'right'
- ypos = 'center'
+ ypos = '10'
+ padding = '0, 0, 7, 0'
orientation = 'bottom'
/>
+
+ <drawstep func = 'triangle'
+ fg_color = 'green'
+ fill = 'foreground'
+ width = '10'
+ height = '5'
+ xpos = 'right'
+ ypos = '4'
+ padding = '0, 0, 7, 0'
+ orientation = 'top'
+ />
+
+ <text font = 'text_default'
+ text_color = 'color_normal'
+ vertical_align = 'center'
+ horizontal_align = 'left'
+ />
+ </drawdata>
+
+ <drawdata id = 'popup_idle' cache = 'false' resolution = 'y<400'>
+ <drawstep func = 'bevelsq'
+ bevel = '2'
+ fill = 'none'
+ />
+
+ <drawstep func = 'triangle'
+ fg_color = 'green'
+ fill = 'foreground'
+ width = '7'
+ height = '4'
+ xpos = 'right'
+ ypos = '9'
+ padding = '0, 0, 3, 0'
+ orientation = 'bottom'
+ />
+
+ <drawstep func = 'triangle'
+ fg_color = 'green'
+ fill = 'foreground'
+ width = '7'
+ height = '4'
+ xpos = 'right'
+ ypos = '4'
+ padding = '0, 0, 3, 0'
+ orientation = 'top'
+ />
+
<text font = 'text_default'
text_color = 'color_normal'
vertical_align = 'center'
@@ -293,47 +379,141 @@
/>
</drawdata>
- <drawdata id = 'popup_disabled' cache = 'false'>
+ <drawdata id = 'popup_disabled' cache = 'false' resolution = 'y>399'>
<drawstep func = 'bevelsq'
bevel = '2'
fill = 'none'
/>
<drawstep func = 'triangle'
- fg_color = 'lightgrey'
+ fg_color = 'green'
fill = 'foreground'
- width = 'height'
- height = 'auto'
+ width = '10'
+ height = '5'
xpos = 'right'
- ypos = 'center'
+ ypos = '10'
+ padding = '0, 0, 7, 0'
orientation = 'bottom'
/>
+
+ <drawstep func = 'triangle'
+ fg_color = 'green'
+ fill = 'foreground'
+ width = '10'
+ height = '5'
+ xpos = 'right'
+ ypos = '4'
+ padding = '0, 0, 7, 0'
+ orientation = 'top'
+ />
<text font = 'text_default'
text_color = 'color_normal_disabled'
vertical_align = 'center'
horizontal_align = 'left'
/>
</drawdata>
+
+ <drawdata id = 'popup_disabled' cache = 'false' resolution = 'y<400'>
+ <drawstep func = 'bevelsq'
+ bevel = '2'
+ fill = 'none'
+ />
+
+ <drawstep func = 'triangle'
+ fg_color = 'green'
+ fill = 'foreground'
+ width = '7'
+ height = '4'
+ xpos = 'right'
+ ypos = '9'
+ padding = '0, 0, 3, 0'
+ orientation = 'bottom'
+ />
+
+ <drawstep func = 'triangle'
+ fg_color = 'green'
+ fill = 'foreground'
+ width = '7'
+ height = '4'
+ xpos = 'right'
+ ypos = '4'
+ padding = '0, 0, 3, 0'
+ orientation = 'top'
+ />
+
+ <text font = 'text_default'
+ text_color = 'color_normal'
+ vertical_align = 'center'
+ horizontal_align = 'left'
+ />
+ </drawdata>
- <drawdata id = 'popup_hover' cache = 'false'>
+ <drawdata id = 'popup_hover' cache = 'false' resolution = 'y>399'>
<drawstep func = 'bevelsq'
bevel = '2'
fill = 'none'
/>
<drawstep func = 'triangle'
- fg_color = 'green2'
+ fg_color = 'green'
fill = 'foreground'
- width = 'height'
- height = 'auto'
+ width = '10'
+ height = '5'
xpos = 'right'
- ypos = 'center'
+ ypos = '10'
+ padding = '0, 0, 7, 0'
orientation = 'bottom'
/>
+
+ <drawstep func = 'triangle'
+ fg_color = 'green'
+ fill = 'foreground'
+ width = '10'
+ height = '5'
+ xpos = 'right'
+ ypos = '4'
+ padding = '0, 0, 7, 0'
+ orientation = 'top'
+ />
<text font = 'text_default'
text_color = 'color_normal_hover'
vertical_align = 'center'
horizontal_align = 'left'
/>
</drawdata>
+
+ <drawdata id = 'popup_hover' cache = 'false' resolution = 'y<400'>
+ <drawstep func = 'bevelsq'
+ bevel = '2'
+ fill = 'none'
+ />
+
+ <drawstep func = 'triangle'
+ fg_color = 'green'
+ fill = 'foreground'
+ width = '7'
+ height = '4'
+ xpos = 'right'
+ ypos = '9'
+ padding = '0, 0, 3, 0'
+ orientation = 'bottom'
+ />
+
+ <drawstep func = 'triangle'
+ fg_color = 'green'
+ fill = 'foreground'
+ width = '7'
+ height = '4'
+ xpos = 'right'
+ ypos = '4'
+ padding = '0, 0, 3, 0'
+ orientation = 'top'
+ />
+
+ <text font = 'text_default'
+ text_color = 'color_normal'
+ vertical_align = 'center'
+ horizontal_align = 'left'
+ />
+ </drawdata>
<drawdata id = 'widget_textedit' cache = 'false'>
<drawstep func = 'bevelsq'
diff --git a/gui/themes/scummclassic/classic_layout.stx b/gui/themes/scummclassic/classic_layout.stx
index 4b42b4f36d..9da42635a7 100644
--- a/gui/themes/scummclassic/classic_layout.stx
+++ b/gui/themes/scummclassic/classic_layout.stx
@@ -388,6 +388,10 @@
<widget name = 'SavePath'
height = 'Globals.Line.Height'
/>
+ <widget name = 'SavePathClearButton'
+ height = 'Globals.Line.Height'
+ width = 'Globals.Line.Height'
+ />
</layout>
<layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '10' center = 'true'>
<widget name = 'ThemeButton'
@@ -396,6 +400,10 @@
<widget name = 'ThemePath'
height = 'Globals.Line.Height'
/>
+ <widget name = 'ThemePathClearButton'
+ height = 'Globals.Line.Height'
+ width = 'Globals.Line.Height'
+ />
</layout>
<layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '10' center = 'true'>
<widget name = 'ExtraButton'
@@ -404,6 +412,10 @@
<widget name = 'ExtraPath'
height = 'Globals.Line.Height'
/>
+ <widget name = 'ExtraPathClearButton'
+ height = 'Globals.Line.Height'
+ width = 'Globals.Line.Height'
+ />
</layout>
<layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '16'>
<widget name = 'PluginsButton'
@@ -587,6 +599,10 @@
<widget name = 'SavepathText'
height = 'Globals.Line.Height'
/>
+ <widget name = 'SavePathClearButton'
+ height = 'Globals.Line.Height'
+ width = 'Globals.Line.Height'
+ />
</layout>
<layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '10' center = 'true'>
<widget name = 'Extrapath'
@@ -595,6 +611,10 @@
<widget name = 'ExtrapathText'
height = 'Globals.Line.Height'
/>
+ <widget name = 'ExtraPathClearButton'
+ height = 'Globals.Line.Height'
+ width = 'Globals.Line.Height'
+ />
</layout>
<layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '10' center = 'true'>
<widget name = 'Gamepath'
@@ -798,6 +818,27 @@
</layout>
</dialog>
+ <dialog name = 'LoomTownsDifficultyDialog' overlays = 'screen_center'>
+ <layout type = 'vertical' padding = '8, 8, 8, 8' center = 'true'>
+ <widget name = 'Description1'
+ width = '320'
+ height = 'Globals.Line.Height'
+ />
+ <widget name = 'Description2'
+ height = 'Globals.Line.Height'
+ />
+ <widget name = 'Standard'
+ type = 'Button'
+ />
+ <widget name = 'Practice'
+ type = 'Button'
+ />
+ <widget name = 'Expert'
+ type = 'Button'
+ />
+ </layout>
+ </dialog>
+
<dialog name = 'MassAdd' overlays = 'screen_center' shading = 'dim'>
<layout type = 'vertical' padding = '8, 8, 32, 8' center = 'true'>
<widget name = 'DirProgressText'
diff --git a/gui/themes/scummclassic/classic_layout_lowres.stx b/gui/themes/scummclassic/classic_layout_lowres.stx
index 4db6cc4bfc..dc528a4c00 100644
--- a/gui/themes/scummclassic/classic_layout_lowres.stx
+++ b/gui/themes/scummclassic/classic_layout_lowres.stx
@@ -385,6 +385,10 @@
<widget name = 'SavePath'
height = 'Globals.Line.Height'
/>
+ <widget name = 'SavePathClearButton'
+ height = 'Globals.Line.Height'
+ width = 'Globals.Line.Height'
+ />
</layout>
<layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '16'>
<widget name = 'ThemeButton'
@@ -393,6 +397,10 @@
<widget name = 'ThemePath'
height = 'Globals.Line.Height'
/>
+ <widget name = 'ThemePathClearButton'
+ height = 'Globals.Line.Height'
+ width = 'Globals.Line.Height'
+ />
</layout>
<layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '16'>
<widget name = 'ExtraButton'
@@ -401,6 +409,10 @@
<widget name = 'ExtraPath'
height = 'Globals.Line.Height'
/>
+ <widget name = 'ExtraPathClearButton'
+ height = 'Globals.Line.Height'
+ width = 'Globals.Line.Height'
+ />
</layout>
<layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '16'>
<widget name = 'PluginsButton'
@@ -599,6 +611,10 @@
<widget name = 'SavepathText'
height = 'Globals.Line.Height'
/>
+ <widget name = 'SavePathClearButton'
+ height = 'Globals.Line.Height'
+ width = 'Globals.Line.Height'
+ />
</layout>
<layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '16' center = 'true'>
<widget name = 'Extrapath'
@@ -607,6 +623,10 @@
<widget name = 'ExtrapathText'
height = 'Globals.Line.Height'
/>
+ <widget name = 'ExtraPathClearButton'
+ height = 'Globals.Line.Height'
+ width = 'Globals.Line.Height'
+ />
</layout>
<layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '16' center = 'true'>
<widget name = 'Gamepath'
@@ -800,6 +820,27 @@
</layout>
</dialog>
+ <dialog name = 'LoomTownsDifficultyDialog' overlays = 'screen_center'>
+ <layout type = 'vertical' padding = '8, 8, 8, 8' center = 'true'>
+ <widget name = 'Description1'
+ width = '280'
+ height = 'Globals.Line.Height'
+ />
+ <widget name = 'Description2'
+ height = 'Globals.Line.Height'
+ />
+ <widget name = 'Standard'
+ type = 'Button'
+ />
+ <widget name = 'Practice'
+ type = 'Button'
+ />
+ <widget name = 'Expert'
+ type = 'Button'
+ />
+ </layout>
+ </dialog>
+
<dialog name = 'MassAdd' overlays = 'screen_center' shading = 'dim'>
<layout type = 'vertical' padding = '4, 4, 16, 4' center = 'true'>
<widget name = 'DirProgressText'
diff --git a/gui/themes/scummclassic/fixed5x8-iso-8859-2.fcc b/gui/themes/scummclassic/fixed5x8-iso-8859-2.fcc
index 73bb5fff2d..37da61be00 100644
--- a/gui/themes/scummclassic/fixed5x8-iso-8859-2.fcc
+++ b/gui/themes/scummclassic/fixed5x8-iso-8859-2.fcc
Binary files differ
diff --git a/gui/themes/scummclassic/fixed5x8-iso-8859-5.fcc b/gui/themes/scummclassic/fixed5x8-iso-8859-5.fcc
index e70388dd93..ee32a2041b 100644
--- a/gui/themes/scummclassic/fixed5x8-iso-8859-5.fcc
+++ b/gui/themes/scummclassic/fixed5x8-iso-8859-5.fcc
Binary files differ
diff --git a/gui/themes/scummclassic/helvb12-iso-8859-2.fcc b/gui/themes/scummclassic/helvb12-iso-8859-2.fcc
index 2117b6b9e6..540d8c4f4c 100644
--- a/gui/themes/scummclassic/helvb12-iso-8859-2.fcc
+++ b/gui/themes/scummclassic/helvb12-iso-8859-2.fcc
Binary files differ
diff --git a/gui/themes/scummclassic/helvb12-iso-8859-5.fcc b/gui/themes/scummclassic/helvb12-iso-8859-5.fcc
index 8ad8f0eb22..90df2b0df4 100644
--- a/gui/themes/scummclassic/helvb12-iso-8859-5.fcc
+++ b/gui/themes/scummclassic/helvb12-iso-8859-5.fcc
Binary files differ
diff --git a/gui/themes/scummmodern.zip b/gui/themes/scummmodern.zip
index 1e44442933..fc4c89cbcc 100644
--- a/gui/themes/scummmodern.zip
+++ b/gui/themes/scummmodern.zip
Binary files differ
diff --git a/gui/themes/scummmodern/FreeMonoBold.ttf b/gui/themes/scummmodern/FreeMonoBold.ttf
new file mode 100644
index 0000000000..3bce6129ae
--- /dev/null
+++ b/gui/themes/scummmodern/FreeMonoBold.ttf
Binary files differ
diff --git a/gui/themes/scummmodern/FreeSans.ttf b/gui/themes/scummmodern/FreeSans.ttf
new file mode 100644
index 0000000000..9db958532c
--- /dev/null
+++ b/gui/themes/scummmodern/FreeSans.ttf
Binary files differ
diff --git a/gui/themes/scummmodern/FreeSansBold.ttf b/gui/themes/scummmodern/FreeSansBold.ttf
new file mode 100644
index 0000000000..63644e7437
--- /dev/null
+++ b/gui/themes/scummmodern/FreeSansBold.ttf
Binary files differ
diff --git a/gui/themes/scummmodern/THEMERC b/gui/themes/scummmodern/THEMERC
index f947a5685a..32bd36241e 100644
--- a/gui/themes/scummmodern/THEMERC
+++ b/gui/themes/scummmodern/THEMERC
@@ -1 +1 @@
-[SCUMMVM_STX0.8.3:ScummVM Modern Theme:No Author]
+[SCUMMVM_STX0.8.8:ScummVM Modern Theme:No Author]
diff --git a/gui/themes/scummmodern/clR6x12-iso-8859-2.fcc b/gui/themes/scummmodern/clR6x12-iso-8859-2.fcc
index 042bc5b24d..4d225ddc23 100644
--- a/gui/themes/scummmodern/clR6x12-iso-8859-2.fcc
+++ b/gui/themes/scummmodern/clR6x12-iso-8859-2.fcc
Binary files differ
diff --git a/gui/themes/scummmodern/clR6x12-iso-8859-5.fcc b/gui/themes/scummmodern/clR6x12-iso-8859-5.fcc
index d8e614211d..37d4615ea0 100644
--- a/gui/themes/scummmodern/clR6x12-iso-8859-5.fcc
+++ b/gui/themes/scummmodern/clR6x12-iso-8859-5.fcc
Binary files differ
diff --git a/gui/themes/scummmodern/eraser.bmp b/gui/themes/scummmodern/eraser.bmp
new file mode 100644
index 0000000000..b927a6384f
--- /dev/null
+++ b/gui/themes/scummmodern/eraser.bmp
Binary files differ
diff --git a/gui/themes/scummmodern/fixed5x8-iso-8859-2.fcc b/gui/themes/scummmodern/fixed5x8-iso-8859-2.fcc
index 73bb5fff2d..37da61be00 100644
--- a/gui/themes/scummmodern/fixed5x8-iso-8859-2.fcc
+++ b/gui/themes/scummmodern/fixed5x8-iso-8859-2.fcc
Binary files differ
diff --git a/gui/themes/scummmodern/fixed5x8-iso-8859-5.fcc b/gui/themes/scummmodern/fixed5x8-iso-8859-5.fcc
index e70388dd93..ee32a2041b 100644
--- a/gui/themes/scummmodern/fixed5x8-iso-8859-5.fcc
+++ b/gui/themes/scummmodern/fixed5x8-iso-8859-5.fcc
Binary files differ
diff --git a/gui/themes/scummmodern/helvb12-iso-8859-1.fcc b/gui/themes/scummmodern/helvb12-iso-8859-1.fcc
index 651a25934a..18af0bf870 100644
--- a/gui/themes/scummmodern/helvb12-iso-8859-1.fcc
+++ b/gui/themes/scummmodern/helvb12-iso-8859-1.fcc
Binary files differ
diff --git a/gui/themes/scummmodern/helvb12-iso-8859-2.fcc b/gui/themes/scummmodern/helvb12-iso-8859-2.fcc
index 2117b6b9e6..540d8c4f4c 100644
--- a/gui/themes/scummmodern/helvb12-iso-8859-2.fcc
+++ b/gui/themes/scummmodern/helvb12-iso-8859-2.fcc
Binary files differ
diff --git a/gui/themes/scummmodern/helvb12-iso-8859-5.fcc b/gui/themes/scummmodern/helvb12-iso-8859-5.fcc
index 8ad8f0eb22..90df2b0df4 100644
--- a/gui/themes/scummmodern/helvb12-iso-8859-5.fcc
+++ b/gui/themes/scummmodern/helvb12-iso-8859-5.fcc
Binary files differ
diff --git a/gui/themes/scummmodern/scummmodern_gfx.stx b/gui/themes/scummmodern/scummmodern_gfx.stx
index 80177054f4..5f7cc69acd 100644
--- a/gui/themes/scummmodern/scummmodern_gfx.stx
+++ b/gui/themes/scummmodern/scummmodern_gfx.stx
@@ -99,32 +99,44 @@
<bitmap filename = 'radiobutton_empty.bmp'/>
<bitmap filename = 'logo_small.bmp'/>
<bitmap filename = 'search.bmp'/>
+ <bitmap filename = 'eraser.bmp'/>
</bitmaps>
<fonts>
<font id = 'text_default'
file = 'helvb12.bdf'
+ scalable_file = 'FreeSansBold.ttf'
/>
<font resolution = 'y<400'
id = 'text_default'
file = 'clR6x12.bdf'
+ scalable_file = 'FreeSans.ttf'
+ point_size = '11'
/>
<font id = 'text_button'
file = 'helvb12.bdf'
+ scalable_file = 'FreeSansBold.ttf'
/>
<font resolution = 'y<400'
id = 'text_button'
file = 'clR6x12.bdf'
+ scalable_file = 'FreeSans.ttf'
+ point_size = '11'
/>
<font id = 'text_normal'
file = 'helvb12.bdf'
+ scalable_file = 'FreeSans.ttf'
/>
<font resolution = 'y<400'
id = 'text_normal'
file = 'clR6x12.bdf'
+ scalable_file = 'FreeSans.ttf'
+ point_size = '11'
/>
<font id = 'tooltip_normal'
file = 'fixed5x8.bdf'
+ scalable_file = 'FreeMonoBold.ttf'
+ point_size = '8'
/>
<text_color id = 'color_normal'
@@ -259,7 +271,7 @@
</drawdata>
<!-- Buttons at the top and bottom of the scrollbar -->
- <drawdata id = 'scrollbar_button_idle' cache = 'false'>
+ <drawdata id = 'scrollbar_button_idle' cache = 'false' resolution = 'y>399'>
<drawstep func = 'roundedsq'
radius = '10'
fill = 'none'
@@ -269,15 +281,35 @@
<drawstep func = 'triangle'
fg_color = 'shadowcolor'
fill = 'foreground'
- width = 'auto'
- height = 'auto'
- xpos = 'center'
+ width = '10'
+ height = '10'
+ xpos = 'right'
ypos = 'center'
+ padding = '0,0,2,0'
orientation = 'top'
/>
</drawdata>
- <drawdata id = 'scrollbar_button_hover' cache = 'false'>
+ <drawdata id = 'scrollbar_button_idle' cache = 'false' resolution = 'y<400'>
+ <drawstep func = 'roundedsq'
+ radius = '10'
+ fill = 'none'
+ fg_color = 'darkgray'
+ stroke = '1'
+ />
+ <drawstep func = 'triangle'
+ fg_color = 'shadowcolor'
+ fill = 'foreground'
+ width = '5'
+ height = '5'
+ xpos = 'right'
+ ypos = 'center'
+ padding = '0,0,1,0'
+ orientation = 'top'
+ />
+ </drawdata>
+
+ <drawdata id = 'scrollbar_button_hover' cache = 'false' resolution = 'y>399'>
<drawstep func = 'roundedsq'
radius = '10'
fill = 'gradient'
@@ -291,10 +323,30 @@
<drawstep func = 'triangle'
fg_color = 'shadowcolor'
fill = 'foreground'
- width = 'auto'
- height = 'auto'
- xpos = 'center'
+ width = '10'
+ height = '10'
+ xpos = 'right'
+ ypos = 'center'
+ padding = '0,0,2,0'
+ orientation = 'top'
+ />
+ </drawdata>
+
+ <drawdata id = 'scrollbar_button_hover' cache = 'false' resolution = 'y<400'>
+ <drawstep func = 'roundedsq'
+ radius = '10'
+ fill = 'none'
+ fg_color = 'darkgray'
+ stroke = '1'
+ />
+ <drawstep func = 'triangle'
+ fg_color = 'shadowcolor'
+ fill = 'foreground'
+ width = '5'
+ height = '5'
+ xpos = 'right'
ypos = 'center'
+ padding = '0,0,2,0'
orientation = 'top'
/>
</drawdata>
@@ -346,7 +398,7 @@
<!-- Background of the slider widget -->
<drawdata id = 'widget_slider' cache = 'false'>
<drawstep func = 'roundedsq'
- stroke = '0'
+ stroke = '1'
radius = '5'
fill = 'foreground'
fg_color = 'paleyellow'
@@ -392,7 +444,7 @@
</drawdata>
<!-- Idle popup -->
- <drawdata id = 'popup_idle' cache = 'false'>
+ <drawdata id = 'popup_idle' cache = 'false' resolution = 'y>399'>
<drawstep func = 'roundedsq'
radius = '5'
stroke = '1'
@@ -401,15 +453,68 @@
bg_color = 'xtrabrightred'
shadow = '2'
/>
+
<drawstep func = 'triangle'
bg_color = 'shadowcolor'
fill = 'background'
- width = 'height'
- height = 'auto'
+ width = '10'
+ height = '5'
xpos = 'right'
- ypos = 'center'
+ ypos = '10'
+ padding = '0, 0, 6, 0'
orientation = 'bottom'
/>
+
+ <drawstep func = 'triangle'
+ bg_color = 'shadowcolor'
+ fill = 'background'
+ width = '10'
+ height = '5'
+ xpos = 'right'
+ ypos = '4'
+ padding = '0, 0, 6, 0'
+ orientation = 'top'
+ />
+
+ <text font = 'text_default'
+ text_color = 'color_normal'
+ vertical_align = 'center'
+ horizontal_align = 'left'
+ />
+ </drawdata>
+
+ <drawdata id = 'popup_idle' cache = 'false' resolution ='y<400'>
+ <drawstep func = 'roundedsq'
+ radius = '5'
+ stroke = '1'
+ fg_color = 'lightgray2'
+ fill = 'background'
+ bg_color = 'xtrabrightred'
+ shadow = '2'
+ />
+
+ <drawstep func = 'triangle'
+ bg_color = 'shadowcolor'
+ fill = 'background'
+ width = '7'
+ height = '4'
+ xpos = 'right'
+ ypos = '9'
+ padding = '0, 0, 3, 0'
+ orientation = 'bottom'
+ />
+
+ <drawstep func = 'triangle'
+ bg_color = 'shadowcolor'
+ fill = 'background'
+ width = '7'
+ height = '4'
+ xpos = 'right'
+ ypos = '4'
+ padding = '0, 0, 3, 0'
+ orientation = 'top'
+ />
+
<text font = 'text_default'
text_color = 'color_normal'
vertical_align = 'center'
@@ -418,31 +523,86 @@
</drawdata>
<!-- Disabled popup -->
- <drawdata id = 'popup_disabled' cache = 'false'>
+ <drawdata id = 'popup_disabled' cache = 'false' resolution = 'y>399'>
<drawstep func = 'roundedsq'
+ stroke = '1'
+ fg_color = 'lightgray'
radius = '5'
- fill = 'foreground'
- fg_color = 'darkgray'
+ fill = 'gradient'
+ gradient_start = 'blandyellow'
+ gradient_end = 'xtrabrightred'
+ shadow = '0'
+ />
+ <drawstep func = 'triangle'
+ bg_color = 'shadowcolor'
+ fill = 'background'
+ width = '10'
+ height = '5'
+ xpos = 'right'
+ ypos = '10'
+ padding = '0, 0, 6, 0'
+ orientation = 'bottom'
+ />
+
+ <drawstep func = 'triangle'
+ bg_color = 'shadowcolor'
+ fill = 'background'
+ width = '10'
+ height = '5'
+ xpos = 'right'
+ ypos = '4'
+ padding = '0, 0, 6, 0'
+ orientation = 'top'
+ />
+
+ <text font = 'text_default'
+ text_color = 'color_normal_hover'
+ vertical_align = 'center'
+ horizontal_align = 'left'
+ />
+ </drawdata>
+
+ <drawdata id = 'popup_disabled' cache = 'false' resolution = 'y<400'>
+ <drawstep func = 'roundedsq'
+ radius = '5'
+ stroke = '1'
+ fg_color = 'lightgray2'
+ fill = 'background'
+ bg_color = 'xtrabrightred'
shadow = '2'
/>
+
<drawstep func = 'triangle'
- fg_color = 'shadowcolor'
- fill = 'foreground'
- width = 'height'
- height = 'auto'
+ bg_color = 'shadowcolor'
+ fill = 'background'
+ width = '7'
+ height = '4'
xpos = 'right'
- ypos = 'center'
+ ypos = '9'
+ padding = '0, 0, 3, 0'
orientation = 'bottom'
/>
+
+ <drawstep func = 'triangle'
+ bg_color = 'shadowcolor'
+ fill = 'background'
+ width = '7'
+ height = '4'
+ xpos = 'right'
+ ypos = '4'
+ padding = '0, 0, 3, 0'
+ orientation = 'top'
+ />
+
<text font = 'text_default'
- text_color = 'color_normal_disabled'
+ text_color = 'color_normal'
vertical_align = 'center'
horizontal_align = 'left'
/>
</drawdata>
<!-- Hovered popup -->
- <drawdata id = 'popup_hover' cache = 'false'>
+ <drawdata id = 'popup_hover' cache = 'false' resolution = 'y>399'>
<drawstep func = 'roundedsq'
stroke = '1'
fg_color = 'lightgray'
@@ -453,20 +613,72 @@
shadow = '0'
/>
<drawstep func = 'triangle'
- fg_color = 'shadowcolor'
- fill = 'foreground'
- width = 'height'
- height = 'auto'
+ bg_color = 'shadowcolor'
+ fill = 'background'
+ width = '10'
+ height = '5'
xpos = 'right'
- ypos = 'center'
+ ypos = '10'
+ padding = '0, 0, 6, 0'
orientation = 'bottom'
/>
+
+ <drawstep func = 'triangle'
+ bg_color = 'shadowcolor'
+ fill = 'background'
+ width = '10'
+ height = '5'
+ xpos = 'right'
+ ypos = '4'
+ padding = '0, 0, 6, 0'
+ orientation = 'top'
+ />
+
<text font = 'text_default'
text_color = 'color_normal_hover'
vertical_align = 'center'
horizontal_align = 'left'
/>
</drawdata>
+
+ <drawdata id = 'popup_hover' cache = 'false' resolution = 'y<400'>
+ <drawstep func = 'roundedsq'
+ radius = '5'
+ stroke = '1'
+ fg_color = 'lightgray2'
+ fill = 'background'
+ bg_color = 'xtrabrightred'
+ shadow = '2'
+ />
+
+ <drawstep func = 'triangle'
+ bg_color = 'shadowcolor'
+ fill = 'background'
+ width = '7'
+ height = '4'
+ xpos = 'right'
+ ypos = '9'
+ padding = '0, 0, 3, 0'
+ orientation = 'bottom'
+ />
+
+ <drawstep func = 'triangle'
+ bg_color = 'shadowcolor'
+ fill = 'background'
+ width = '7'
+ height = '4'
+ xpos = 'right'
+ ypos = '4'
+ padding = '0, 0, 3, 0'
+ orientation = 'top'
+ />
+
+ <text font = 'text_default'
+ text_color = 'color_normal'
+ vertical_align = 'center'
+ horizontal_align = 'left'
+ />
+ </drawdata>
<!-- Background of the textedit widget -->
<drawdata id = 'widget_textedit' cache = 'false'>
@@ -475,6 +687,7 @@
radius = '5'
fg_color = 'paleyellow'
shadow = '0'
+ stroke = '1'
bevel = '1'
bevel_color = 'shadowcolor'
/>
diff --git a/gui/themes/scummmodern/scummmodern_layout.stx b/gui/themes/scummmodern/scummmodern_layout.stx
index e77284e5ac..69ad9c79fa 100644
--- a/gui/themes/scummmodern/scummmodern_layout.stx
+++ b/gui/themes/scummmodern/scummmodern_layout.stx
@@ -403,6 +403,10 @@
<widget name = 'SavePath'
height = 'Globals.Line.Height'
/>
+ <widget name = 'SavePathClearButton'
+ height = 'Globals.Line.Height'
+ width = 'Globals.Line.Height'
+ />
</layout>
<layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '10' center = 'true'>
<widget name = 'ThemeButton'
@@ -411,6 +415,10 @@
<widget name = 'ThemePath'
height = 'Globals.Line.Height'
/>
+ <widget name = 'ThemePathClearButton'
+ height = 'Globals.Line.Height'
+ width = 'Globals.Line.Height'
+ />
</layout>
<layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '10' center = 'true'>
<widget name = 'ExtraButton'
@@ -419,6 +427,10 @@
<widget name = 'ExtraPath'
height = 'Globals.Line.Height'
/>
+ <widget name = 'ExtraPathClearButton'
+ height = 'Globals.Line.Height'
+ width = 'Globals.Line.Height'
+ />
</layout>
<layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '10' center = 'true'>
<widget name = 'PluginsButton'
@@ -602,6 +614,10 @@
<widget name = 'SavepathText'
height = 'Globals.Line.Height'
/>
+ <widget name = 'SavePathClearButton'
+ height = 'Globals.Line.Height'
+ width = 'Globals.Line.Height'
+ />
</layout>
<layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '16' center = 'true'>
<widget name = 'Extrapath'
@@ -610,6 +626,10 @@
<widget name = 'ExtrapathText'
height = 'Globals.Line.Height'
/>
+ <widget name = 'ExtraPathClearButton'
+ height = 'Globals.Line.Height'
+ width = 'Globals.Line.Height'
+ />
</layout>
<layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '16' center = 'true'>
<widget name = 'Gamepath'
@@ -813,6 +833,27 @@
</layout>
</dialog>
+ <dialog name = 'LoomTownsDifficultyDialog' overlays = 'screen_center'>
+ <layout type = 'vertical' padding = '8, 8, 8, 8' center = 'true'>
+ <widget name = 'Description1'
+ width = '320'
+ height = 'Globals.Line.Height'
+ />
+ <widget name = 'Description2'
+ height = 'Globals.Line.Height'
+ />
+ <widget name = 'Standard'
+ type = 'Button'
+ />
+ <widget name = 'Practice'
+ type = 'Button'
+ />
+ <widget name = 'Expert'
+ type = 'Button'
+ />
+ </layout>
+ </dialog>
+
<dialog name = 'MassAdd' overlays = 'screen_center' shading = 'dim'>
<layout type = 'vertical' padding = '8, 8, 32, 8' center = 'true'>
<widget name = 'DirProgressText'
diff --git a/gui/themes/scummmodern/scummmodern_layout_lowres.stx b/gui/themes/scummmodern/scummmodern_layout_lowres.stx
index e95fa2d584..0bfd16c1d9 100644
--- a/gui/themes/scummmodern/scummmodern_layout_lowres.stx
+++ b/gui/themes/scummmodern/scummmodern_layout_lowres.stx
@@ -383,6 +383,10 @@
<widget name = 'SavePath'
height = 'Globals.Line.Height'
/>
+ <widget name = 'SavePathClearButton'
+ height = 'Globals.Line.Height'
+ width = 'Globals.Line.Height'
+ />
</layout>
<layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '16' center = 'true'>
<widget name = 'ThemeButton'
@@ -391,6 +395,10 @@
<widget name = 'ThemePath'
height = 'Globals.Line.Height'
/>
+ <widget name = 'ThemePathClearButton'
+ height = 'Globals.Line.Height'
+ width = 'Globals.Line.Height'
+ />
</layout>
<layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '16' center = 'true'>
<widget name = 'ExtraButton'
@@ -399,6 +407,10 @@
<widget name = 'ExtraPath'
height = 'Globals.Line.Height'
/>
+ <widget name = 'ExtraPathClearButton'
+ height = 'Globals.Line.Height'
+ width = 'Globals.Line.Height'
+ />
</layout>
<layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '16' center = 'true'>
<widget name = 'PluginsButton'
@@ -597,6 +609,10 @@
<widget name = 'SavepathText'
height = 'Globals.Line.Height'
/>
+ <widget name = 'SavePathClearButton'
+ height = 'Globals.Line.Height'
+ width = 'Globals.Line.Height'
+ />
</layout>
<layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '16' center = 'true'>
<widget name = 'Extrapath'
@@ -605,6 +621,10 @@
<widget name = 'ExtrapathText'
height = 'Globals.Line.Height'
/>
+ <widget name = 'ExtraPathClearButton'
+ height = 'Globals.Line.Height'
+ width = 'Globals.Line.Height'
+ />
</layout>
<layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '16' center = 'true'>
<widget name = 'Gamepath'
@@ -799,6 +819,27 @@
</layout>
</dialog>
+ <dialog name = 'LoomTownsDifficultyDialog' overlays = 'screen_center'>
+ <layout type = 'vertical' padding = '8, 8, 8, 8' center = 'true'>
+ <widget name = 'Description1'
+ width = '280'
+ height = 'Globals.Line.Height'
+ />
+ <widget name = 'Description2'
+ height = 'Globals.Line.Height'
+ />
+ <widget name = 'Standard'
+ type = 'Button'
+ />
+ <widget name = 'Practice'
+ type = 'Button'
+ />
+ <widget name = 'Expert'
+ type = 'Button'
+ />
+ </layout>
+ </dialog>
+
<dialog name = 'MassAdd' overlays = 'screen_center' shading = 'dim'>
<layout type = 'vertical' padding = '4, 4, 16, 4' center = 'true'>
<widget name = 'DirProgressText'
diff --git a/gui/themes/scummmodern/search.bmp b/gui/themes/scummmodern/search.bmp
index fa963f8f16..0d2b098445 100644
--- a/gui/themes/scummmodern/search.bmp
+++ b/gui/themes/scummmodern/search.bmp
Binary files differ
diff --git a/gui/themes/scummtheme.py b/gui/themes/scummtheme.py
index e4e9549265..4c55fd79de 100755
--- a/gui/themes/scummtheme.py
+++ b/gui/themes/scummtheme.py
@@ -5,7 +5,7 @@ import re
import os
import zipfile
-THEME_FILE_EXTENSIONS = ('.stx', '.bmp', '.fcc')
+THEME_FILE_EXTENSIONS = ('.stx', '.bmp', '.fcc', '.ttf')
def buildTheme(themeName):
if not os.path.isdir(themeName) or not os.path.isfile(os.path.join(themeName, "THEMERC")):
diff --git a/gui/themes/translations.dat b/gui/themes/translations.dat
index 770f76ddf1..65ca204393 100644
--- a/gui/themes/translations.dat
+++ b/gui/themes/translations.dat
Binary files differ
diff --git a/gui/widget.cpp b/gui/widget.cpp
index c4d288eb11..0e2fd248b1 100644
--- a/gui/widget.cpp
+++ b/gui/widget.cpp
@@ -23,6 +23,7 @@
#include "common/system.h"
#include "common/rect.h"
#include "common/textconsole.h"
+#include "common/translation.h"
#include "graphics/pixelformat.h"
#include "gui/widget.h"
#include "gui/gui-manager.h"
@@ -244,16 +245,16 @@ void StaticTextWidget::setValue(int value) {
}
void StaticTextWidget::setLabel(const Common::String &label) {
- if (_label != label) {
- _label = label;
+ if (_label != label) {
+ _label = label;
- // when changing the label, add the CLEARBG flag
- // so the widget is completely redrawn, otherwise
- // the new text is drawn on top of the old one.
- setFlags(WIDGET_CLEARBG);
- draw();
- clearFlags(WIDGET_CLEARBG);
- }
+ // when changing the label, add the CLEARBG flag
+ // so the widget is completely redrawn, otherwise
+ // the new text is drawn on top of the old one.
+ setFlags(WIDGET_CLEARBG);
+ draw();
+ clearFlags(WIDGET_CLEARBG);
+ }
}
void StaticTextWidget::setAlign(Graphics::TextAlign align) {
@@ -302,19 +303,40 @@ void ButtonWidget::setLabel(const Common::String &label) {
StaticTextWidget::setLabel(cleanupHotkey(label));
}
+ButtonWidget *addClearButton(GuiObject *boss, const Common::String &name, uint32 cmd, int x, int y, int w, int h) {
+ ButtonWidget *button;
+
+#ifndef DISABLE_FANCY_THEMES
+ if (g_gui.xmlEval()->getVar("Globals.ShowSearchPic") == 1 && g_gui.theme()->supportsImages()) {
+ if (!name.empty())
+ button = new PicButtonWidget(boss, name, _("Clear value"), cmd);
+ else
+ button = new PicButtonWidget(boss, x, y, w, h, _("Clear value"), cmd);
+ ((PicButtonWidget *)button)->useThemeTransparency(true);
+ ((PicButtonWidget *)button)->setGfx(g_gui.theme()->getImageSurface(ThemeEngine::kImageEraser));
+ } else
+#endif
+ if (!name.empty())
+ button = new ButtonWidget(boss, name, "C", _("Clear value"), cmd);
+ else
+ button = new ButtonWidget(boss, x, y, w, h, "C", _("Clear value"), cmd);
+
+ return button;
+}
+
#pragma mark -
PicButtonWidget::PicButtonWidget(GuiObject *boss, int x, int y, int w, int h, const char *tooltip, uint32 cmd, uint8 hotkey)
- : Widget(boss, x, y, w, h, tooltip), CommandSender(boss),
- _cmd(cmd), _hotkey(hotkey), _gfx(), _alpha(256), _transparency(false) {
+ : ButtonWidget(boss, x, y, w, h, "", tooltip, cmd, hotkey),
+ _gfx(), _alpha(256), _transparency(false) {
setFlags(WIDGET_ENABLED/* | WIDGET_BORDER*/ | WIDGET_CLEARBG);
_type = kButtonWidget;
}
PicButtonWidget::PicButtonWidget(GuiObject *boss, const Common::String &name, const char *tooltip, uint32 cmd, uint8 hotkey)
- : Widget(boss, name, tooltip), CommandSender(boss),
- _cmd(cmd), _gfx(), _alpha(256), _transparency(false) {
+ : ButtonWidget(boss, name, "", tooltip, cmd, hotkey),
+ _alpha(256), _transparency(false) {
setFlags(WIDGET_ENABLED/* | WIDGET_BORDER*/ | WIDGET_CLEARBG);
_type = kButtonWidget;
}
@@ -323,11 +345,6 @@ PicButtonWidget::~PicButtonWidget() {
_gfx.free();
}
-void PicButtonWidget::handleMouseUp(int x, int y, int button, int clickCount) {
- if (isEnabled() && x >= 0 && x < _w && y >= 0 && y < _h)
- sendCommand(_cmd, 0);
-}
-
void PicButtonWidget::setGfx(const Graphics::Surface *gfx) {
_gfx.free();
diff --git a/gui/widget.h b/gui/widget.h
index acd575a90b..789fc09231 100644
--- a/gui/widget.h
+++ b/gui/widget.h
@@ -197,28 +197,17 @@ protected:
};
/* PicButtonWidget */
-class PicButtonWidget : public Widget, public CommandSender {
- friend class Dialog; // Needed for the hotkey handling
-protected:
- uint32 _cmd;
- uint8 _hotkey;
+class PicButtonWidget : public ButtonWidget {
public:
PicButtonWidget(GuiObject *boss, int x, int y, int w, int h, const char *tooltip = 0, uint32 cmd = 0, uint8 hotkey = 0);
PicButtonWidget(GuiObject *boss, const Common::String &name, const char *tooltip = 0, uint32 cmd = 0, uint8 hotkey = 0);
~PicButtonWidget();
- void setCmd(uint32 cmd) { _cmd = cmd; }
- uint32 getCmd() const { return _cmd; }
-
void setGfx(const Graphics::Surface *gfx);
void useAlpha(int alpha) { _alpha = alpha; }
void useThemeTransparency(bool enable) { _transparency = enable; }
- void handleMouseUp(int x, int y, int button, int clickCount);
- void handleMouseEntered(int button) { setFlags(WIDGET_HILITED); draw(); }
- void handleMouseLeft(int button) { clearFlags(WIDGET_HILITED); draw(); }
-
protected:
void drawWidget();
@@ -365,6 +354,8 @@ protected:
void drawWidget();
};
+ButtonWidget *addClearButton(GuiObject *boss, const Common::String &name, uint32 cmd, int x=0, int y=0, int w=0, int h=0);
+
} // End of namespace GUI
#endif
diff --git a/gui/widgets/editable.cpp b/gui/widgets/editable.cpp
index 4a0ee54828..6fae9346b2 100644
--- a/gui/widgets/editable.cpp
+++ b/gui/widgets/editable.cpp
@@ -238,8 +238,13 @@ void EditableWidget::defaultKeyDownHandler(Common::KeyState &state, bool &dirty,
int EditableWidget::getCaretOffset() const {
int caretpos = 0;
- for (int i = 0; i < _caretPos; i++)
- caretpos += g_gui.getCharWidth(_editString[i], _font);
+
+ uint last = 0;
+ for (int i = 0; i < _caretPos; ++i) {
+ const uint cur = _editString[i];
+ caretpos += g_gui.getCharWidth(cur, _font) + g_gui.getKerningOffset(last, cur, _font);
+ last = cur;
+ }
caretpos -= _editScrollOffset;
@@ -270,6 +275,8 @@ void EditableWidget::drawCaret(bool erase) {
if ((uint)_caretPos < _editString.size()) {
GUI::EditableWidget::String chr(_editString[_caretPos]);
int chrWidth = g_gui.getCharWidth(_editString[_caretPos], _font);
+ const uint last = (_caretPos > 0) ? _editString[_caretPos - 1] : 0;
+ x += g_gui.getKerningOffset(last, _editString[_caretPos], _font);
g_gui.theme()->drawText(Common::Rect(x, y, x + chrWidth, y + editRect.height() - 2), chr, _state, Graphics::kTextAlignLeft, _inversion, 0, false, _font);
}
}
diff --git a/gui/widgets/edittext.cpp b/gui/widgets/edittext.cpp
index d4a4407ee0..4b266e8194 100644
--- a/gui/widgets/edittext.cpp
+++ b/gui/widgets/edittext.cpp
@@ -26,13 +26,14 @@
namespace GUI {
- EditTextWidget::EditTextWidget(GuiObject *boss, int x, int y, int w, int h, const String &text, const char *tooltip, uint32 cmd, uint32 finishCmd)
+EditTextWidget::EditTextWidget(GuiObject *boss, int x, int y, int w, int h, const String &text, const char *tooltip, uint32 cmd, uint32 finishCmd)
: EditableWidget(boss, x, y - 1, w, h + 2, tooltip, cmd) {
setFlags(WIDGET_ENABLED | WIDGET_CLEARBG | WIDGET_RETAIN_FOCUS | WIDGET_WANT_TICKLE);
_type = kEditTextWidget;
_finishCmd = finishCmd;
setEditString(text);
+ setFontStyle(ThemeEngine::kFontStyleNormal);
}
EditTextWidget::EditTextWidget(GuiObject *boss, const String &name, const String &text, const char *tooltip, uint32 cmd, uint32 finishCmd)
@@ -42,6 +43,7 @@ EditTextWidget::EditTextWidget(GuiObject *boss, const String &name, const String
_finishCmd = finishCmd;
setEditString(text);
+ setFontStyle(ThemeEngine::kFontStyleNormal);
}
void EditTextWidget::setEditString(const String &str) {
@@ -67,10 +69,13 @@ void EditTextWidget::handleMouseDown(int x, int y, int button, int clickCount) {
int width = 0;
uint i;
+ uint last = 0;
for (i = 0; i < _editString.size(); ++i) {
- width += g_gui.theme()->getCharWidth(_editString[i], _font);
+ const uint cur = _editString[i];
+ width += g_gui.getCharWidth(cur, _font) + g_gui.getKerningOffset(last, cur, _font);
if (width >= x)
break;
+ last = cur;
}
if (setCaretPos(i))
draw();
diff --git a/gui/widgets/list.cpp b/gui/widgets/list.cpp
index 2a0d4afff0..13784ddf7f 100644
--- a/gui/widgets/list.cpp
+++ b/gui/widgets/list.cpp
@@ -220,6 +220,7 @@ void ListWidget::scrollBarRecalc() {
void ListWidget::handleTickle() {
if (_editMode)
EditableWidget::handleTickle();
+ _scrollBar->handleTickle();
}
void ListWidget::handleMouseDown(int x, int y, int button, int clickCount) {
diff --git a/gui/widgets/scrollbar.cpp b/gui/widgets/scrollbar.cpp
index e0dbcec59c..c7c17bc908 100644
--- a/gui/widgets/scrollbar.cpp
+++ b/gui/widgets/scrollbar.cpp
@@ -45,28 +45,8 @@ ScrollBarWidget::ScrollBarWidget(GuiObject *boss, int x, int y, int w, int h)
_numEntries = 0;
_entriesPerPage = 0;
_currentPos = 0;
-}
-
-static void upArrowRepeater(void *ref) {
- ScrollBarWidget *sb = (ScrollBarWidget *)ref;
- int old_pos = sb->_currentPos;
-
- sb->_currentPos -= 3;
- sb->checkBounds(old_pos);
-
- g_system->getTimerManager()->removeTimerProc(&upArrowRepeater);
- g_system->getTimerManager()->installTimerProc(&upArrowRepeater, 1000000/10, ref, "guiScrollBarUp");
-}
-
-static void downArrowRepeater(void *ref) {
- ScrollBarWidget *sb = (ScrollBarWidget *)ref;
- int old_pos = sb->_currentPos;
- sb->_currentPos += 3;
- sb->checkBounds(old_pos);
-
- g_system->getTimerManager()->removeTimerProc(&downArrowRepeater);
- g_system->getTimerManager()->installTimerProc(&downArrowRepeater, 1000000/10, ref, "guiScrollBarDown");
+ _repeatTimer = 0;
}
void ScrollBarWidget::handleMouseDown(int x, int y, int button, int clickCount) {
@@ -79,13 +59,13 @@ void ScrollBarWidget::handleMouseDown(int x, int y, int button, int clickCount)
if (y <= UP_DOWN_BOX_HEIGHT) {
// Up arrow
_currentPos--;
+ _repeatTimer = g_system->getMillis() + kRepeatInitialDelay;
_draggingPart = kUpArrowPart;
- g_system->getTimerManager()->installTimerProc(&upArrowRepeater, 1000000/2, this, "guiScrollBarUp");
} else if (y >= _h - UP_DOWN_BOX_HEIGHT) {
// Down arrow
_currentPos++;
+ _repeatTimer = g_system->getMillis() + kRepeatInitialDelay;
_draggingPart = kDownArrowPart;
- g_system->getTimerManager()->installTimerProc(&downArrowRepeater, 1000000/2, this, "guiScrollBarDown");
} else if (y < _sliderPos) {
_currentPos -= _entriesPerPage - 1;
} else if (y >= _sliderPos + _sliderHeight) {
@@ -101,9 +81,7 @@ void ScrollBarWidget::handleMouseDown(int x, int y, int button, int clickCount)
void ScrollBarWidget::handleMouseUp(int x, int y, int button, int clickCount) {
_draggingPart = kNoPart;
-
- g_system->getTimerManager()->removeTimerProc(&upArrowRepeater);
- g_system->getTimerManager()->removeTimerProc(&downArrowRepeater);
+ _repeatTimer = 0;
}
void ScrollBarWidget::handleMouseWheel(int x, int y, int direction) {
@@ -160,23 +138,21 @@ void ScrollBarWidget::handleMouseMoved(int x, int y, int button) {
}
void ScrollBarWidget::handleTickle() {
-/*
- // FIXME/TODO - this code is supposed to allow for "click-repeat" (like key repeat),
- // i.e. if you click on one of the arrows and keep clicked, it will scroll
- // continuously. However, just like key repeat, this requires two delays:
- // First an "initial" delay that has to pass before repeating starts (otherwise
- // it is near to impossible to achieve single clicks). Secondly, a repeat delay
- // that determines how often per second a click is simulated.
- int old_pos = _currentPos;
+ if (_repeatTimer) {
+ const uint32 curTime = g_system->getMillis();
+ if (curTime >= _repeatTimer) {
+ const int old_pos = _currentPos;
- if (_draggingPart == kUpArrowPart)
- _currentPos--;
- else if (_draggingPart == kDownArrowPart)
- _currentPos++;
+ if (_part == kUpArrowPart)
+ _currentPos -= 3;
+ else if (_part == kDownArrowPart)
+ _currentPos += 3;
- // Make sure that _currentPos is still inside the bounds
- checkBounds(old_pos);
-*/
+ checkBounds(old_pos);
+
+ _repeatTimer = curTime + kRepeatDelay;
+ }
+ }
}
void ScrollBarWidget::checkBounds(int old_pos) {
diff --git a/gui/widgets/scrollbar.h b/gui/widgets/scrollbar.h
index 3b248ce8a4..1c9f371cbc 100644
--- a/gui/widgets/scrollbar.h
+++ b/gui/widgets/scrollbar.h
@@ -49,6 +49,12 @@ protected:
Part _draggingPart;
int _sliderDeltaMouseDownPos;
+ enum {
+ kRepeatInitialDelay = 500,
+ kRepeatDelay = 100
+ };
+ uint32 _repeatTimer;
+
public:
int _numEntries;
int _entriesPerPage;
diff --git a/po/POTFILES b/po/POTFILES
index 6ce26a0539..33492c0c6f 100644
--- a/po/POTFILES
+++ b/po/POTFILES
@@ -13,6 +13,7 @@ gui/options.cpp
gui/saveload.cpp
gui/themebrowser.cpp
gui/ThemeEngine.cpp
+gui/widget.cpp
base/main.cpp
@@ -36,8 +37,8 @@ engines/gob/inter_playtoons.cpp
engines/gob/inter_v2.cpp
engines/gob/inter_v5.cpp
engines/groovie/script.cpp
+engines/kyra/lol.cpp
engines/kyra/sound_midi.cpp
-engines/m4/m4_menus.cpp
engines/sky/compact.cpp
engines/sword1/animation.cpp
engines/sword1/control.cpp
@@ -63,6 +64,7 @@ backends/keymapper/remap-dialog.cpp
backends/midi/windows.cpp
backends/platform/ds/arm9/source/dsoptions.cpp
backends/platform/iphone/osys_events.cpp
+backends/platform/maemo/maemo.cpp
backends/platform/sdl/macosx/appmenu_osx.mm
backends/graphics/surfacesdl/surfacesdl-graphics.cpp
backends/graphics/opengl/opengl-graphics.cpp
diff --git a/po/ca_ES.po b/po/ca_ES.po
index 5d76935a21..4c0ad8bbbe 100644
--- a/po/ca_ES.po
+++ b/po/ca_ES.po
@@ -1,5 +1,5 @@
# Catalan translation for ScummVM.
-# Copyright (C) 2007-2011 ScummVM Team
+# Copyright (C) 2007-2012 ScummVM Team
# This file is distributed under the same license as the ScummVM package.
# Jordi Vilalta Prat <jvprat@jvprat.com>, 2007-2011.
#
@@ -7,14 +7,14 @@ msgid ""
msgstr ""
"Project-Id-Version: ScummVM 1.3.0svn\n"
"Report-Msgid-Bugs-To: scummvm-devel@lists.sf.net\n"
-"POT-Creation-Date: 2011-10-19 13:42+0100\n"
+"POT-Creation-Date: 2012-03-07 22:09+0000\n"
"PO-Revision-Date: 2011-10-04 20:51+0100\n"
"Last-Translator: Jordi Vilalta Prat <jvprat@jvprat.com>\n"
"Language-Team: Catalan <scummvm-devel@lists.sf.net>\n"
-"Language: Catalan\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=iso-8859-1\n"
"Content-Transfer-Encoding: 8bit\n"
+"Language: Catalan\n"
#: gui/about.cpp:91
#, c-format
@@ -43,13 +43,13 @@ msgid "Go up"
msgstr "Amunt"
#: gui/browser.cpp:69 gui/chooser.cpp:45 gui/KeysDialog.cpp:43
-#: gui/launcher.cpp:312 gui/massadd.cpp:94 gui/options.cpp:1178
+#: gui/launcher.cpp:320 gui/massadd.cpp:94 gui/options.cpp:1253
#: gui/saveload.cpp:63 gui/saveload.cpp:155 gui/themebrowser.cpp:54
-#: engines/engine.cpp:436 engines/scumm/dialogs.cpp:190
+#: engines/engine.cpp:442 engines/scumm/dialogs.cpp:190
#: engines/sword1/control.cpp:865 engines/parallaction/saveload.cpp:281
#: backends/platform/wii/options.cpp:48
-#: backends/events/default/default-events.cpp:222
-#: backends/events/default/default-events.cpp:244
+#: backends/events/default/default-events.cpp:191
+#: backends/events/default/default-events.cpp:213
msgid "Cancel"
msgstr "Cancel·la"
@@ -57,25 +57,30 @@ msgstr "Cancel·la"
msgid "Choose"
msgstr "Escull"
-#: gui/gui-manager.cpp:116 engines/scumm/help.cpp:125
+#: gui/gui-manager.cpp:115 engines/scumm/help.cpp:125
#: engines/scumm/help.cpp:140 engines/scumm/help.cpp:165
#: engines/scumm/help.cpp:191 engines/scumm/help.cpp:209
#: backends/keymapper/remap-dialog.cpp:52
msgid "Close"
msgstr "Tanca"
-#: gui/gui-manager.cpp:119
+#: gui/gui-manager.cpp:118
msgid "Mouse click"
msgstr "Clic del ratolí"
-#: gui/gui-manager.cpp:122 base/main.cpp:283
+#: gui/gui-manager.cpp:122 base/main.cpp:288
msgid "Display keyboard"
msgstr "Mostra el teclat"
-#: gui/gui-manager.cpp:125 base/main.cpp:286
+#: gui/gui-manager.cpp:126 base/main.cpp:292
msgid "Remap keys"
msgstr "Assigna les tecles"
+#: gui/gui-manager.cpp:129 base/main.cpp:295
+#, fuzzy
+msgid "Toggle FullScreen"
+msgstr "Commuta la pantalla completa"
+
#: gui/KeysDialog.h:36 gui/KeysDialog.cpp:145
msgid "Choose an action to map"
msgstr "Sel·leccioneu una acció a assignar"
@@ -84,16 +89,17 @@ msgstr "Sel·leccioneu una acció a assignar"
msgid "Map"
msgstr "Assigna"
-#: gui/KeysDialog.cpp:42 gui/launcher.cpp:313 gui/launcher.cpp:936
-#: gui/launcher.cpp:940 gui/massadd.cpp:91 gui/options.cpp:1179
-#: engines/engine.cpp:359 engines/engine.cpp:370 engines/scumm/dialogs.cpp:192
-#: engines/scumm/scumm.cpp:1776 engines/agos/animation.cpp:551
+#: gui/KeysDialog.cpp:42 gui/launcher.cpp:321 gui/launcher.cpp:960
+#: gui/launcher.cpp:964 gui/massadd.cpp:91 gui/options.cpp:1254
+#: engines/engine.cpp:361 engines/engine.cpp:372 engines/scumm/dialogs.cpp:192
+#: engines/scumm/scumm.cpp:1775 engines/agos/animation.cpp:551
#: engines/groovie/script.cpp:420 engines/sky/compact.cpp:131
-#: engines/sky/compact.cpp:141 engines/sword1/animation.cpp:344
-#: engines/sword1/animation.cpp:354 engines/sword1/animation.cpp:360
-#: engines/sword1/control.cpp:865 engines/sword1/logic.cpp:1633
-#: engines/sword2/animation.cpp:379 engines/sword2/animation.cpp:389
-#: engines/sword2/animation.cpp:398 engines/parallaction/saveload.cpp:281
+#: engines/sky/compact.cpp:141 engines/sword1/animation.cpp:539
+#: engines/sword1/animation.cpp:560 engines/sword1/animation.cpp:570
+#: engines/sword1/animation.cpp:577 engines/sword1/control.cpp:865
+#: engines/sword1/logic.cpp:1633 engines/sword2/animation.cpp:435
+#: engines/sword2/animation.cpp:455 engines/sword2/animation.cpp:465
+#: engines/sword2/animation.cpp:474 engines/parallaction/saveload.cpp:281
#: backends/platform/wii/options.cpp:47
#: backends/platform/wince/CELauncherDialog.cpp:54
msgid "OK"
@@ -121,15 +127,15 @@ msgstr "Seleccioneu una acció"
msgid "Press the key to associate"
msgstr "Premeu la tecla a associar"
-#: gui/launcher.cpp:165
+#: gui/launcher.cpp:170
msgid "Game"
msgstr "Joc"
-#: gui/launcher.cpp:169
+#: gui/launcher.cpp:174
msgid "ID:"
msgstr "Identificador:"
-#: gui/launcher.cpp:169 gui/launcher.cpp:171 gui/launcher.cpp:172
+#: gui/launcher.cpp:174 gui/launcher.cpp:176 gui/launcher.cpp:177
msgid ""
"Short game identifier used for referring to savegames and running the game "
"from the command line"
@@ -137,29 +143,29 @@ msgstr ""
"Identificador de joc curt utilitzat per referir-se a les partides i per "
"executar el joc des de la línia de comandes"
-#: gui/launcher.cpp:171
+#: gui/launcher.cpp:176
msgctxt "lowres"
msgid "ID:"
msgstr "ID:"
-#: gui/launcher.cpp:176
+#: gui/launcher.cpp:181
msgid "Name:"
msgstr "Nom:"
-#: gui/launcher.cpp:176 gui/launcher.cpp:178 gui/launcher.cpp:179
+#: gui/launcher.cpp:181 gui/launcher.cpp:183 gui/launcher.cpp:184
msgid "Full title of the game"
msgstr "Títol complet del joc"
-#: gui/launcher.cpp:178
+#: gui/launcher.cpp:183
msgctxt "lowres"
msgid "Name:"
msgstr "Nom:"
-#: gui/launcher.cpp:182
+#: gui/launcher.cpp:187
msgid "Language:"
msgstr "Idioma:"
-#: gui/launcher.cpp:182 gui/launcher.cpp:183
+#: gui/launcher.cpp:187 gui/launcher.cpp:188
msgid ""
"Language of the game. This will not turn your Spanish game version into "
"English"
@@ -167,285 +173,283 @@ msgstr ""
"Idioma del joc. Això no convertirà la vostra versió Espanyola del joc a "
"Anglès"
-#: gui/launcher.cpp:184 gui/launcher.cpp:198 gui/options.cpp:74
-#: gui/options.cpp:708 gui/options.cpp:718 gui/options.cpp:1149
+#: gui/launcher.cpp:189 gui/launcher.cpp:203 gui/options.cpp:80
+#: gui/options.cpp:745 gui/options.cpp:758 gui/options.cpp:1224
#: audio/null.cpp:40
msgid "<default>"
msgstr "<per defecte>"
-#: gui/launcher.cpp:194
+#: gui/launcher.cpp:199
msgid "Platform:"
msgstr "Plataforma:"
-#: gui/launcher.cpp:194 gui/launcher.cpp:196 gui/launcher.cpp:197
+#: gui/launcher.cpp:199 gui/launcher.cpp:201 gui/launcher.cpp:202
msgid "Platform the game was originally designed for"
msgstr "Plataforma per la que el joc es va dissenyar originalment"
-#: gui/launcher.cpp:196
+#: gui/launcher.cpp:201
msgctxt "lowres"
msgid "Platform:"
msgstr "Platafor.:"
-#: gui/launcher.cpp:208 gui/options.cpp:1018 gui/options.cpp:1035
+#: gui/launcher.cpp:213 gui/options.cpp:1087 gui/options.cpp:1104
msgid "Graphics"
msgstr "Gràfics"
-#: gui/launcher.cpp:208 gui/options.cpp:1018 gui/options.cpp:1035
+#: gui/launcher.cpp:213 gui/options.cpp:1087 gui/options.cpp:1104
msgid "GFX"
msgstr "GFX"
-#: gui/launcher.cpp:211
+#: gui/launcher.cpp:216
msgid "Override global graphic settings"
msgstr "Fer canvis sobre les opcions globals de gràfics"
-#: gui/launcher.cpp:213
+#: gui/launcher.cpp:218
msgctxt "lowres"
msgid "Override global graphic settings"
msgstr "Canviar les opcions de gràfics"
-#: gui/launcher.cpp:220 gui/options.cpp:1041
+#: gui/launcher.cpp:225 gui/options.cpp:1110
msgid "Audio"
msgstr "Àudio"
-#: gui/launcher.cpp:223
+#: gui/launcher.cpp:228
msgid "Override global audio settings"
msgstr "Fer canvis sobre les opcions globals d'àudio"
-#: gui/launcher.cpp:225
+#: gui/launcher.cpp:230
msgctxt "lowres"
msgid "Override global audio settings"
msgstr "Canviar les opcions d'àudio"
-#: gui/launcher.cpp:234 gui/options.cpp:1046
+#: gui/launcher.cpp:239 gui/options.cpp:1115
msgid "Volume"
msgstr "Volum"
-#: gui/launcher.cpp:236 gui/options.cpp:1048
+#: gui/launcher.cpp:241 gui/options.cpp:1117
msgctxt "lowres"
msgid "Volume"
msgstr "Volum"
-#: gui/launcher.cpp:239
+#: gui/launcher.cpp:244
msgid "Override global volume settings"
msgstr "Fer canvis sobre les opcions globals de volum"
-#: gui/launcher.cpp:241
+#: gui/launcher.cpp:246
msgctxt "lowres"
msgid "Override global volume settings"
msgstr "Canviar les opcions de volum"
-#: gui/launcher.cpp:248 gui/options.cpp:1056
+#: gui/launcher.cpp:254 gui/options.cpp:1125
msgid "MIDI"
msgstr "MIDI"
-#: gui/launcher.cpp:251
+#: gui/launcher.cpp:257
msgid "Override global MIDI settings"
msgstr "Fer canvis sobre les opcions globals de MIDI"
-#: gui/launcher.cpp:253
+#: gui/launcher.cpp:259
msgctxt "lowres"
msgid "Override global MIDI settings"
msgstr "Canviar les opcions de MIDI"
-#: gui/launcher.cpp:263 gui/options.cpp:1062
+#: gui/launcher.cpp:268 gui/options.cpp:1131
msgid "MT-32"
msgstr "MT-32"
-#: gui/launcher.cpp:266
+#: gui/launcher.cpp:271
msgid "Override global MT-32 settings"
msgstr "Fer canvis sobre les opcions globals de MT-32"
-#: gui/launcher.cpp:268
+#: gui/launcher.cpp:273
msgctxt "lowres"
msgid "Override global MT-32 settings"
msgstr "Canviar les opcions de MT-32"
-#: gui/launcher.cpp:279 gui/options.cpp:1069
+#: gui/launcher.cpp:282 gui/options.cpp:1138
msgid "Paths"
msgstr "Camins"
-#: gui/launcher.cpp:281 gui/options.cpp:1071
+#: gui/launcher.cpp:284 gui/options.cpp:1140
msgctxt "lowres"
msgid "Paths"
msgstr "Camins"
-#: gui/launcher.cpp:288
+#: gui/launcher.cpp:291
msgid "Game Path:"
msgstr "Camí del joc:"
-#: gui/launcher.cpp:290
+#: gui/launcher.cpp:293
msgctxt "lowres"
msgid "Game Path:"
msgstr "Camí joc:"
-#: gui/launcher.cpp:295 gui/options.cpp:1091
+#: gui/launcher.cpp:298 gui/options.cpp:1164
msgid "Extra Path:"
msgstr "Camí extra:"
-#: gui/launcher.cpp:295 gui/launcher.cpp:297 gui/launcher.cpp:298
+#: gui/launcher.cpp:298 gui/launcher.cpp:300 gui/launcher.cpp:301
msgid "Specifies path to additional data used the game"
msgstr "Especifica el camí de dades addicionals utilitzades pel joc"
-#: gui/launcher.cpp:297 gui/options.cpp:1093
+#: gui/launcher.cpp:300 gui/options.cpp:1166
msgctxt "lowres"
msgid "Extra Path:"
msgstr "Camí extra:"
-#: gui/launcher.cpp:302 gui/options.cpp:1079
+#: gui/launcher.cpp:307 gui/options.cpp:1148
msgid "Save Path:"
msgstr "Camí de partides:"
-#: gui/launcher.cpp:302 gui/launcher.cpp:304 gui/launcher.cpp:305
-#: gui/options.cpp:1079 gui/options.cpp:1081 gui/options.cpp:1082
+#: gui/launcher.cpp:307 gui/launcher.cpp:309 gui/launcher.cpp:310
+#: gui/options.cpp:1148 gui/options.cpp:1150 gui/options.cpp:1151
msgid "Specifies where your savegames are put"
msgstr "Especifica on es desaran les partides"
-#: gui/launcher.cpp:304 gui/options.cpp:1081
+#: gui/launcher.cpp:309 gui/options.cpp:1150
msgctxt "lowres"
msgid "Save Path:"
msgstr "Partides:"
-#: gui/launcher.cpp:321 gui/launcher.cpp:404 gui/launcher.cpp:453
-#: gui/options.cpp:1088 gui/options.cpp:1094 gui/options.cpp:1101
-#: gui/options.cpp:1202 gui/options.cpp:1208 gui/options.cpp:1214
-#: gui/options.cpp:1222 gui/options.cpp:1246 gui/options.cpp:1250
-#: gui/options.cpp:1256 gui/options.cpp:1263 gui/options.cpp:1362
+#: gui/launcher.cpp:329 gui/launcher.cpp:416 gui/launcher.cpp:469
+#: gui/launcher.cpp:523 gui/options.cpp:1159 gui/options.cpp:1167
+#: gui/options.cpp:1176 gui/options.cpp:1283 gui/options.cpp:1289
+#: gui/options.cpp:1297 gui/options.cpp:1327 gui/options.cpp:1333
+#: gui/options.cpp:1340 gui/options.cpp:1433 gui/options.cpp:1436
+#: gui/options.cpp:1448
msgctxt "path"
msgid "None"
msgstr "Cap"
-#: gui/launcher.cpp:326 gui/launcher.cpp:408
+#: gui/launcher.cpp:334 gui/launcher.cpp:422 gui/launcher.cpp:527
+#: gui/options.cpp:1277 gui/options.cpp:1321 gui/options.cpp:1439
#: backends/platform/wii/options.cpp:56
msgid "Default"
msgstr "Per defecte"
-#: gui/launcher.cpp:446 gui/options.cpp:1356
+#: gui/launcher.cpp:462 gui/options.cpp:1442
msgid "Select SoundFont"
msgstr "Seleccioneu el fitxer SoundFont"
-#: gui/launcher.cpp:465 gui/launcher.cpp:612
+#: gui/launcher.cpp:481 gui/launcher.cpp:636
msgid "Select directory with game data"
msgstr "Seleccioneu el directori amb les dades del joc"
-#: gui/launcher.cpp:483
+#: gui/launcher.cpp:499
msgid "Select additional game directory"
msgstr "Seleccioneu el directori addicional del joc"
-#: gui/launcher.cpp:495
+#: gui/launcher.cpp:511
msgid "Select directory for saved games"
msgstr "Seleccioneu el directori de les partides desades"
-#: gui/launcher.cpp:514
+#: gui/launcher.cpp:538
msgid "This game ID is already taken. Please choose another one."
msgstr ""
"Aquest identificador de joc ja està en ús. Si us plau, trieu-ne un altre."
-#: gui/launcher.cpp:555 engines/dialogs.cpp:110
+#: gui/launcher.cpp:579 engines/dialogs.cpp:110
msgid "~Q~uit"
msgstr "~T~anca"
-#: gui/launcher.cpp:555 backends/platform/sdl/macosx/appmenu_osx.mm:80
+#: gui/launcher.cpp:579 backends/platform/sdl/macosx/appmenu_osx.mm:96
msgid "Quit ScummVM"
msgstr "Surt de ScummVM"
-#: gui/launcher.cpp:556
+#: gui/launcher.cpp:580
msgid "A~b~out..."
msgstr "~Q~uant a..."
-#: gui/launcher.cpp:556 backends/platform/sdl/macosx/appmenu_osx.mm:61
+#: gui/launcher.cpp:580 backends/platform/sdl/macosx/appmenu_osx.mm:70
msgid "About ScummVM"
msgstr "Quant a ScummVM"
-#: gui/launcher.cpp:557
+#: gui/launcher.cpp:581
msgid "~O~ptions..."
msgstr "~O~pcions..."
-#: gui/launcher.cpp:557
+#: gui/launcher.cpp:581
msgid "Change global ScummVM options"
msgstr "Canvia les opcions globals de ScummVM"
-#: gui/launcher.cpp:559
+#: gui/launcher.cpp:583
msgid "~S~tart"
msgstr "~I~nicia"
-#: gui/launcher.cpp:559
+#: gui/launcher.cpp:583
msgid "Start selected game"
msgstr "Iniciant el joc seleccionat"
-#: gui/launcher.cpp:562
+#: gui/launcher.cpp:586
msgid "~L~oad..."
msgstr "~C~arrega..."
-#: gui/launcher.cpp:562
+#: gui/launcher.cpp:586
msgid "Load savegame for selected game"
msgstr "Carrega una partida pel joc seleccionat"
-#: gui/launcher.cpp:567 gui/launcher.cpp:1055
+#: gui/launcher.cpp:591 gui/launcher.cpp:1079
msgid "~A~dd Game..."
msgstr "~A~fegeix Joc..."
-#: gui/launcher.cpp:567 gui/launcher.cpp:574
+#: gui/launcher.cpp:591 gui/launcher.cpp:598
msgid "Hold Shift for Mass Add"
msgstr "Mantingueu premut Shift per a l'Addició Massiva"
-#: gui/launcher.cpp:569
+#: gui/launcher.cpp:593
msgid "~E~dit Game..."
msgstr "~E~dita Joc..."
-#: gui/launcher.cpp:569 gui/launcher.cpp:576
+#: gui/launcher.cpp:593 gui/launcher.cpp:600
msgid "Change game options"
msgstr "Canvia les opcions del joc"
-#: gui/launcher.cpp:571
+#: gui/launcher.cpp:595
msgid "~R~emove Game"
msgstr "~S~uprimeix Joc"
-#: gui/launcher.cpp:571 gui/launcher.cpp:578
+#: gui/launcher.cpp:595 gui/launcher.cpp:602
msgid "Remove game from the list. The game data files stay intact"
msgstr ""
"Elimina un joc de la llista. Els fitxers de dades del joc es mantenen "
"intactes"
-#: gui/launcher.cpp:574 gui/launcher.cpp:1055
+#: gui/launcher.cpp:598 gui/launcher.cpp:1079
msgctxt "lowres"
msgid "~A~dd Game..."
msgstr "~A~fegeix Joc..."
-#: gui/launcher.cpp:576
+#: gui/launcher.cpp:600
msgctxt "lowres"
msgid "~E~dit Game..."
msgstr "~E~dita Joc..."
-#: gui/launcher.cpp:578
+#: gui/launcher.cpp:602
msgctxt "lowres"
msgid "~R~emove Game"
msgstr "~S~uprimeix"
-#: gui/launcher.cpp:586
+#: gui/launcher.cpp:610
msgid "Search in game list"
msgstr "Cerca a la llista de jocs"
-#: gui/launcher.cpp:590 gui/launcher.cpp:1102
+#: gui/launcher.cpp:614 gui/launcher.cpp:1126
msgid "Search:"
msgstr "Cerca:"
-#: gui/launcher.cpp:593 gui/options.cpp:826
-msgid "Clear value"
-msgstr "Neteja el valor"
-
-#: gui/launcher.cpp:615 engines/dialogs.cpp:114 engines/mohawk/myst.cpp:255
+#: gui/launcher.cpp:639 engines/dialogs.cpp:114 engines/mohawk/myst.cpp:255
#: engines/mohawk/riven.cpp:716 engines/cruise/menu.cpp:216
msgid "Load game:"
msgstr "Carrega partida:"
-#: gui/launcher.cpp:615 engines/dialogs.cpp:114 engines/scumm/dialogs.cpp:188
+#: gui/launcher.cpp:639 engines/dialogs.cpp:114 engines/scumm/dialogs.cpp:188
#: engines/mohawk/myst.cpp:255 engines/mohawk/riven.cpp:716
#: engines/cruise/menu.cpp:216 backends/platform/wince/CEActionsPocket.cpp:267
#: backends/platform/wince/CEActionsSmartphone.cpp:231
msgid "Load"
msgstr "Carrega"
-#: gui/launcher.cpp:723
+#: gui/launcher.cpp:747
msgid ""
"Do you really want to run the mass game detector? This could potentially add "
"a huge number of games."
@@ -453,7 +457,7 @@ msgstr ""
"Esteu segur que voleu executar el detector massiu de jocs? Això pot afegir "
"una gran quantitat de jocs."
-#: gui/launcher.cpp:724 gui/launcher.cpp:872
+#: gui/launcher.cpp:748 gui/launcher.cpp:896
#: backends/events/symbiansdl/symbiansdl-events.cpp:184
#: backends/platform/wince/CEActionsPocket.cpp:326
#: backends/platform/wince/CEActionsSmartphone.cpp:287
@@ -461,7 +465,7 @@ msgstr ""
msgid "Yes"
msgstr "Sí"
-#: gui/launcher.cpp:724 gui/launcher.cpp:872
+#: gui/launcher.cpp:748 gui/launcher.cpp:896
#: backends/events/symbiansdl/symbiansdl-events.cpp:184
#: backends/platform/wince/CEActionsPocket.cpp:326
#: backends/platform/wince/CEActionsSmartphone.cpp:287
@@ -469,37 +473,37 @@ msgstr "Sí"
msgid "No"
msgstr "No"
-#: gui/launcher.cpp:772
+#: gui/launcher.cpp:796
msgid "ScummVM couldn't open the specified directory!"
msgstr "ScummVM no ha pogut obrir el directori especificat!"
-#: gui/launcher.cpp:784
+#: gui/launcher.cpp:808
msgid "ScummVM could not find any game in the specified directory!"
msgstr "ScummVM no ha pogut trobar cap joc al directori especificat!"
-#: gui/launcher.cpp:798
+#: gui/launcher.cpp:822
msgid "Pick the game:"
msgstr "Seleccioneu el joc:"
-#: gui/launcher.cpp:872
+#: gui/launcher.cpp:896
msgid "Do you really want to remove this game configuration?"
msgstr "Realment voleu suprimir la configuració d'aquest joc?"
-#: gui/launcher.cpp:936
+#: gui/launcher.cpp:960
msgid "This game does not support loading games from the launcher."
msgstr "Aquest joc no suporta la càrrega de partides des del llançador."
-#: gui/launcher.cpp:940
+#: gui/launcher.cpp:964
msgid "ScummVM could not find any engine capable of running the selected game!"
msgstr ""
"ScummVM no ha pogut trobar cap motor capaç d'executar el joc seleccionat!"
-#: gui/launcher.cpp:1054
+#: gui/launcher.cpp:1078
msgctxt "lowres"
msgid "Mass Add..."
msgstr "Afegeix Jocs"
-#: gui/launcher.cpp:1054
+#: gui/launcher.cpp:1078
msgid "Mass Add..."
msgstr "Addició Massiva..."
@@ -527,141 +531,141 @@ msgid "Discovered %d new games, ignored %d previously added games ..."
msgstr ""
"S'han trobat %d jocs nous, s'han ignorat %d jocs afegits anteriorment ..."
-#: gui/options.cpp:72
+#: gui/options.cpp:78
msgid "Never"
msgstr "Mai"
-#: gui/options.cpp:72
+#: gui/options.cpp:78
msgid "every 5 mins"
msgstr "cada 5 minuts"
-#: gui/options.cpp:72
+#: gui/options.cpp:78
msgid "every 10 mins"
msgstr "cada 10 minuts"
-#: gui/options.cpp:72
+#: gui/options.cpp:78
msgid "every 15 mins"
msgstr "cada 15 minuts"
-#: gui/options.cpp:72
+#: gui/options.cpp:78
msgid "every 30 mins"
msgstr "cada 30 minuts"
-#: gui/options.cpp:74
+#: gui/options.cpp:80
msgid "8 kHz"
msgstr "8 kHz"
-#: gui/options.cpp:74
+#: gui/options.cpp:80
msgid "11kHz"
msgstr "11kHz"
-#: gui/options.cpp:74
+#: gui/options.cpp:80
msgid "22 kHz"
msgstr "22 kHz"
-#: gui/options.cpp:74
+#: gui/options.cpp:80
msgid "44 kHz"
msgstr "44 kHz"
-#: gui/options.cpp:74
+#: gui/options.cpp:80
msgid "48 kHz"
msgstr "48 kHz"
-#: gui/options.cpp:236 gui/options.cpp:464 gui/options.cpp:559
-#: gui/options.cpp:625 gui/options.cpp:825
+#: gui/options.cpp:257 gui/options.cpp:485 gui/options.cpp:586
+#: gui/options.cpp:659 gui/options.cpp:868
msgctxt "soundfont"
msgid "None"
msgstr "Cap"
-#: gui/options.cpp:372
+#: gui/options.cpp:393
msgid "Failed to apply some of the graphic options changes:"
msgstr "No s'han pogut aplicar alguns canvis de les opcions gràfiques:"
-#: gui/options.cpp:384
+#: gui/options.cpp:405
msgid "the video mode could not be changed."
msgstr "no s'ha pogut canviar el mode de vídeo"
-#: gui/options.cpp:390
+#: gui/options.cpp:411
msgid "the fullscreen setting could not be changed"
msgstr "no s'ha pogut canviar l'ajust de pantalla completa"
-#: gui/options.cpp:396
+#: gui/options.cpp:417
msgid "the aspect ratio setting could not be changed"
msgstr "no s'ha pogut canviar l'ajust de la correcció d'aspecte"
-#: gui/options.cpp:705
+#: gui/options.cpp:742
msgid "Graphics mode:"
msgstr "Mode gràfic:"
-#: gui/options.cpp:716
+#: gui/options.cpp:756
msgid "Render mode:"
msgstr "Mode de pintat:"
-#: gui/options.cpp:716 gui/options.cpp:717
+#: gui/options.cpp:756 gui/options.cpp:757
msgid "Special dithering modes supported by some games"
msgstr "Modes de tramat especials suportats per alguns jocs"
-#: gui/options.cpp:726
+#: gui/options.cpp:768
#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2248
-#: backends/graphics/openglsdl/openglsdl-graphics.cpp:476
+#: backends/graphics/openglsdl/openglsdl-graphics.cpp:472
msgid "Fullscreen mode"
msgstr "Mode pantalla completa"
-#: gui/options.cpp:729
+#: gui/options.cpp:771
msgid "Aspect ratio correction"
msgstr "Correcció de la relació d'aspecte"
-#: gui/options.cpp:729
+#: gui/options.cpp:771
msgid "Correct aspect ratio for 320x200 games"
msgstr "Corregeix la relació d'aspecte per jocs de 320x200"
-#: gui/options.cpp:730
+#: gui/options.cpp:772
msgid "EGA undithering"
msgstr "Elimina el tramat d'EGA"
-#: gui/options.cpp:730
+#: gui/options.cpp:772
msgid "Enable undithering in EGA games that support it"
msgstr "Activa l'eliminació del tramat en els jocs EGA que ho suportin"
-#: gui/options.cpp:738
+#: gui/options.cpp:780
msgid "Preferred Device:"
msgstr "Disp. preferit:"
-#: gui/options.cpp:738
+#: gui/options.cpp:780
msgid "Music Device:"
msgstr "Disp. de música:"
-#: gui/options.cpp:738 gui/options.cpp:740
+#: gui/options.cpp:780 gui/options.cpp:782
msgid "Specifies preferred sound device or sound card emulator"
msgstr "Especifica el dispositiu de so o l'emulador de tarja de so preferit"
-#: gui/options.cpp:738 gui/options.cpp:740 gui/options.cpp:741
+#: gui/options.cpp:780 gui/options.cpp:782 gui/options.cpp:783
msgid "Specifies output sound device or sound card emulator"
msgstr "Especifica el dispositiu de so o l'emulador de tarja de so de sortida"
-#: gui/options.cpp:740
+#: gui/options.cpp:782
msgctxt "lowres"
msgid "Preferred Dev.:"
msgstr "Disp. preferit:"
-#: gui/options.cpp:740
+#: gui/options.cpp:782
msgctxt "lowres"
msgid "Music Device:"
msgstr "Disp. de música:"
-#: gui/options.cpp:766
+#: gui/options.cpp:809
msgid "AdLib emulator:"
msgstr "Emulador AdLib:"
-#: gui/options.cpp:766 gui/options.cpp:767
+#: gui/options.cpp:809 gui/options.cpp:810
msgid "AdLib is used for music in many games"
msgstr "AdLib s'utilitza per la música de molts jocs"
-#: gui/options.cpp:777
+#: gui/options.cpp:820
msgid "Output rate:"
msgstr "Freq. sortida:"
-#: gui/options.cpp:777 gui/options.cpp:778
+#: gui/options.cpp:820 gui/options.cpp:821
msgid ""
"Higher value specifies better sound quality but may be not supported by your "
"soundcard"
@@ -669,63 +673,63 @@ msgstr ""
"Valors més alts especifiquen millor qualitat de so però pot ser que la "
"vostra tarja de so no ho suporti"
-#: gui/options.cpp:788
+#: gui/options.cpp:831
msgid "GM Device:"
msgstr "Dispositiu GM:"
-#: gui/options.cpp:788
+#: gui/options.cpp:831
msgid "Specifies default sound device for General MIDI output"
msgstr ""
"Especifica el dispositiu de so per defecte per a la sortida General MIDI"
-#: gui/options.cpp:799
+#: gui/options.cpp:842
msgid "Don't use General MIDI music"
msgstr "No utilitzis música General MIDI"
-#: gui/options.cpp:810 gui/options.cpp:871
+#: gui/options.cpp:853 gui/options.cpp:915
msgid "Use first available device"
msgstr "Utilitza el primer dispositiu disponible"
-#: gui/options.cpp:822
+#: gui/options.cpp:865
msgid "SoundFont:"
msgstr "Fitxer SoundFont:"
-#: gui/options.cpp:822 gui/options.cpp:824 gui/options.cpp:825
+#: gui/options.cpp:865 gui/options.cpp:867 gui/options.cpp:868
msgid "SoundFont is supported by some audio cards, Fluidsynth and Timidity"
msgstr "Algunes targes de so, Fluidsynth i Timidity suporten SoundFont"
-#: gui/options.cpp:824
+#: gui/options.cpp:867
msgctxt "lowres"
msgid "SoundFont:"
msgstr "SoundFont:"
-#: gui/options.cpp:829
+#: gui/options.cpp:873
msgid "Mixed AdLib/MIDI mode"
msgstr "Mode combinat AdLib/MIDI"
-#: gui/options.cpp:829
+#: gui/options.cpp:873
msgid "Use both MIDI and AdLib sound generation"
msgstr "Utilitza MIDI i la generació de so AdLib alhora"
-#: gui/options.cpp:832
+#: gui/options.cpp:876
msgid "MIDI gain:"
msgstr "Guany MIDI:"
-#: gui/options.cpp:842
+#: gui/options.cpp:886
msgid "MT-32 Device:"
msgstr "Disposit. MT-32:"
-#: gui/options.cpp:842
+#: gui/options.cpp:886
msgid "Specifies default sound device for Roland MT-32/LAPC1/CM32l/CM64 output"
msgstr ""
"Especifica el dispositiu de so per defecte per a la sortida de Roland MT-32/"
"LAPC1/CM32l/CM64"
-#: gui/options.cpp:847
+#: gui/options.cpp:891
msgid "True Roland MT-32 (disable GM emulation)"
msgstr "Roland MT-32 real (desactiva l'emulació GM)"
-#: gui/options.cpp:847 gui/options.cpp:849
+#: gui/options.cpp:891 gui/options.cpp:893
msgid ""
"Check if you want to use your real hardware Roland-compatible sound device "
"connected to your computer"
@@ -733,196 +737,196 @@ msgstr ""
"Marqueu si voleu utilitzar el vostre dispositiu hardware real de so "
"compatible amb Roland connectat al vostre ordinador"
-#: gui/options.cpp:849
+#: gui/options.cpp:893
msgctxt "lowres"
msgid "True Roland MT-32 (no GM emulation)"
msgstr "Roland MT-32 real (sense emulació GM)"
-#: gui/options.cpp:852
+#: gui/options.cpp:896
msgid "Enable Roland GS Mode"
msgstr "Activa el Mode Roland GS"
-#: gui/options.cpp:852
+#: gui/options.cpp:896
msgid "Turns off General MIDI mapping for games with Roland MT-32 soundtrack"
msgstr ""
"Desactiva la conversió General MIDI pels jocs que tenen banda sonora per a "
"Roland MT-32"
-#: gui/options.cpp:861
+#: gui/options.cpp:905
msgid "Don't use Roland MT-32 music"
msgstr "No utilitzis música de Roland MT-32"
-#: gui/options.cpp:888
+#: gui/options.cpp:932
msgid "Text and Speech:"
msgstr "Text i Veus:"
-#: gui/options.cpp:892 gui/options.cpp:902
+#: gui/options.cpp:936 gui/options.cpp:946
msgid "Speech"
msgstr "Veus"
-#: gui/options.cpp:893 gui/options.cpp:903
+#: gui/options.cpp:937 gui/options.cpp:947
msgid "Subtitles"
msgstr "Subtítols"
-#: gui/options.cpp:894
+#: gui/options.cpp:938
msgid "Both"
msgstr "Ambdós"
-#: gui/options.cpp:896
+#: gui/options.cpp:940
msgid "Subtitle speed:"
msgstr "Velocitat de subt.:"
-#: gui/options.cpp:898
+#: gui/options.cpp:942
msgctxt "lowres"
msgid "Text and Speech:"
msgstr "Text i Veus:"
-#: gui/options.cpp:902
+#: gui/options.cpp:946
msgid "Spch"
msgstr "Veus"
-#: gui/options.cpp:903
+#: gui/options.cpp:947
msgid "Subs"
msgstr "Subt"
-#: gui/options.cpp:904
+#: gui/options.cpp:948
msgctxt "lowres"
msgid "Both"
msgstr "Ambdós"
-#: gui/options.cpp:904
+#: gui/options.cpp:948
msgid "Show subtitles and play speech"
msgstr "Mostra els subtítols i reprodueix la veu"
-#: gui/options.cpp:906
+#: gui/options.cpp:950
msgctxt "lowres"
msgid "Subtitle speed:"
msgstr "Veloc. de subt.:"
-#: gui/options.cpp:922
+#: gui/options.cpp:966
msgid "Music volume:"
msgstr "Volum de música:"
-#: gui/options.cpp:924
+#: gui/options.cpp:968
msgctxt "lowres"
msgid "Music volume:"
msgstr "Volum de música:"
-#: gui/options.cpp:931
+#: gui/options.cpp:975
msgid "Mute All"
msgstr "Silenciar tot"
-#: gui/options.cpp:934
+#: gui/options.cpp:978
msgid "SFX volume:"
msgstr "Volum d'efectes:"
-#: gui/options.cpp:934 gui/options.cpp:936 gui/options.cpp:937
+#: gui/options.cpp:978 gui/options.cpp:980 gui/options.cpp:981
msgid "Special sound effects volume"
msgstr "Volum dels sons d'efectes especials"
-#: gui/options.cpp:936
+#: gui/options.cpp:980
msgctxt "lowres"
msgid "SFX volume:"
msgstr "Volum d'efectes:"
-#: gui/options.cpp:944
+#: gui/options.cpp:988
msgid "Speech volume:"
msgstr "Volum de veus:"
-#: gui/options.cpp:946
+#: gui/options.cpp:990
msgctxt "lowres"
msgid "Speech volume:"
msgstr "Volum de veus:"
-#: gui/options.cpp:1085
+#: gui/options.cpp:1156
msgid "Theme Path:"
msgstr "Camí dels temes:"
-#: gui/options.cpp:1087
+#: gui/options.cpp:1158
msgctxt "lowres"
msgid "Theme Path:"
msgstr "Camí temes:"
-#: gui/options.cpp:1091 gui/options.cpp:1093 gui/options.cpp:1094
+#: gui/options.cpp:1164 gui/options.cpp:1166 gui/options.cpp:1167
msgid "Specifies path to additional data used by all games or ScummVM"
msgstr ""
"Especifica el camí de les dades addicionals utilitzades per tots els jocs o "
"pel ScummVM"
-#: gui/options.cpp:1098
+#: gui/options.cpp:1173
msgid "Plugins Path:"
msgstr "Camí dels connectors:"
-#: gui/options.cpp:1100
+#: gui/options.cpp:1175
msgctxt "lowres"
msgid "Plugins Path:"
msgstr "Camí de connectors:"
-#: gui/options.cpp:1109
+#: gui/options.cpp:1184
msgid "Misc"
msgstr "Misc"
-#: gui/options.cpp:1111
+#: gui/options.cpp:1186
msgctxt "lowres"
msgid "Misc"
msgstr "Misc"
-#: gui/options.cpp:1113
+#: gui/options.cpp:1188
msgid "Theme:"
msgstr "Tema:"
-#: gui/options.cpp:1117
+#: gui/options.cpp:1192
msgid "GUI Renderer:"
msgstr "Pintat GUI:"
-#: gui/options.cpp:1129
+#: gui/options.cpp:1204
msgid "Autosave:"
msgstr "Desat automàtic:"
-#: gui/options.cpp:1131
+#: gui/options.cpp:1206
msgctxt "lowres"
msgid "Autosave:"
msgstr "Auto-desat:"
-#: gui/options.cpp:1139
+#: gui/options.cpp:1214
msgid "Keys"
msgstr "Tecles"
-#: gui/options.cpp:1146
+#: gui/options.cpp:1221
msgid "GUI Language:"
msgstr "Idioma GUI:"
-#: gui/options.cpp:1146
+#: gui/options.cpp:1221
msgid "Language of ScummVM GUI"
msgstr "Idioma de la interfície d'usuari de ScummVM"
-#: gui/options.cpp:1295
+#: gui/options.cpp:1372
msgid "You have to restart ScummVM before your changes will take effect."
msgstr "Heu de reiniciar ScummVM perquè tots els canvis tinguin efecte."
-#: gui/options.cpp:1308
+#: gui/options.cpp:1385
msgid "Select directory for savegames"
msgstr "Seleccioneu el directori de les partides desades"
-#: gui/options.cpp:1315
+#: gui/options.cpp:1392
msgid "The chosen directory cannot be written to. Please select another one."
msgstr ""
"No es pot escriure al directori seleccionat. Si us plau, escolliu-ne un "
"altre."
-#: gui/options.cpp:1324
+#: gui/options.cpp:1401
msgid "Select directory for GUI themes"
msgstr "Seleccioneu el directori dels temes"
-#: gui/options.cpp:1334
+#: gui/options.cpp:1411
msgid "Select directory for extra files"
msgstr "Seleccioneu el directori dels fitxers extra"
-#: gui/options.cpp:1345
+#: gui/options.cpp:1422
msgid "Select directory for plugins"
msgstr "Seleccioneu el directori dels connectors"
-#: gui/options.cpp:1389
+#: gui/options.cpp:1475
msgid ""
"The theme you selected does not support your current language. If you want "
"to use this theme you need to switch to another language first."
@@ -970,60 +974,64 @@ msgstr "Partida sense títol"
msgid "Select a Theme"
msgstr "Seleccioneu un Tema"
-#: gui/ThemeEngine.cpp:328
+#: gui/ThemeEngine.cpp:333
msgid "Disabled GFX"
msgstr "GFX desactivats"
-#: gui/ThemeEngine.cpp:328
+#: gui/ThemeEngine.cpp:333
msgctxt "lowres"
msgid "Disabled GFX"
msgstr "GFX desactivats"
-#: gui/ThemeEngine.cpp:329
+#: gui/ThemeEngine.cpp:334
msgid "Standard Renderer (16bpp)"
msgstr "Pintat estàndard (16bpp)"
-#: gui/ThemeEngine.cpp:329
+#: gui/ThemeEngine.cpp:334
msgid "Standard (16bpp)"
msgstr "Estàndard (16bpp)"
-#: gui/ThemeEngine.cpp:331
+#: gui/ThemeEngine.cpp:336
msgid "Antialiased Renderer (16bpp)"
msgstr "Pintat amb antialias (16bpp)"
-#: gui/ThemeEngine.cpp:331
+#: gui/ThemeEngine.cpp:336
msgid "Antialiased (16bpp)"
msgstr "Amb antialias (16bpp)"
+#: gui/widget.cpp:312 gui/widget.cpp:314 gui/widget.cpp:320 gui/widget.cpp:322
+msgid "Clear value"
+msgstr "Neteja el valor"
+
#: base/main.cpp:203
#, c-format
msgid "Engine does not support debug level '%s'"
msgstr "El motor no suporta el nivell de depuració '%s'"
-#: base/main.cpp:271
+#: base/main.cpp:275
msgid "Menu"
msgstr "Menú"
-#: base/main.cpp:274 backends/platform/symbian/src/SymbianActions.cpp:45
+#: base/main.cpp:278 backends/platform/symbian/src/SymbianActions.cpp:45
#: backends/platform/wince/CEActionsPocket.cpp:45
#: backends/platform/wince/CEActionsSmartphone.cpp:46
msgid "Skip"
msgstr "Salta"
-#: base/main.cpp:277 backends/platform/symbian/src/SymbianActions.cpp:50
+#: base/main.cpp:281 backends/platform/symbian/src/SymbianActions.cpp:50
#: backends/platform/wince/CEActionsPocket.cpp:42
msgid "Pause"
msgstr "Pausa"
-#: base/main.cpp:280
+#: base/main.cpp:284
msgid "Skip line"
msgstr "Salta la línia"
-#: base/main.cpp:439
+#: base/main.cpp:455
msgid "Error running game:"
msgstr "Error al executar el joc:"
-#: base/main.cpp:463
+#: base/main.cpp:479
msgid "Could not find any engine capable of running the selected game"
msgstr "No s'ha pogut trobar cap motor capaç d'executar el joc seleccionat"
@@ -1091,25 +1099,6 @@ msgstr "Cancel·lat per l'usuari"
msgid "Unknown error"
msgstr "Error desconegut"
-#. I18N: Hercules is graphics card name
-#: common/util.cpp:275
-msgid "Hercules Green"
-msgstr "Hercules Verd"
-
-#: common/util.cpp:276
-msgid "Hercules Amber"
-msgstr "Hercules Àmbar"
-
-#: common/util.cpp:283
-msgctxt "lowres"
-msgid "Hercules Green"
-msgstr "Hercules Verd"
-
-#: common/util.cpp:284
-msgctxt "lowres"
-msgid "Hercules Amber"
-msgstr "Hercules Àmbar"
-
#: engines/advancedDetector.cpp:296
#, c-format
msgid "The game in '%s' seems to be unknown."
@@ -1158,12 +1147,12 @@ msgid "~R~eturn to Launcher"
msgstr "~R~etorna al Llançador"
#: engines/dialogs.cpp:116 engines/cruise/menu.cpp:214
-#: engines/sci/engine/kfile.cpp:578
+#: engines/sci/engine/kfile.cpp:566
msgid "Save game:"
msgstr "Desa la partida:"
#: engines/dialogs.cpp:116 engines/scumm/dialogs.cpp:187
-#: engines/cruise/menu.cpp:214 engines/sci/engine/kfile.cpp:578
+#: engines/cruise/menu.cpp:214 engines/sci/engine/kfile.cpp:566
#: backends/platform/symbian/src/SymbianActions.cpp:44
#: backends/platform/wince/CEActionsPocket.cpp:43
#: backends/platform/wince/CEActionsPocket.cpp:267
@@ -1181,37 +1170,46 @@ msgstr ""
"Aquest motor no ofereix ajuda dins el joc. Consulteu el fitxer README per a "
"la informació bàsica i les instruccions sobre com obtenir més assistència."
-#: engines/dialogs.cpp:316 engines/mohawk/dialogs.cpp:109
+#: engines/dialogs.cpp:243
+#, fuzzy, c-format
+msgid ""
+"Gamestate save failed (%s)! Please consult the README for basic information, "
+"and for instructions on how to obtain further assistance."
+msgstr ""
+"Aquest motor no ofereix ajuda dins el joc. Consulteu el fitxer README per a "
+"la informació bàsica i les instruccions sobre com obtenir més assistència."
+
+#: engines/dialogs.cpp:321 engines/mohawk/dialogs.cpp:109
#: engines/mohawk/dialogs.cpp:174
msgid "~O~K"
msgstr "~D~'acord"
-#: engines/dialogs.cpp:317 engines/mohawk/dialogs.cpp:110
+#: engines/dialogs.cpp:322 engines/mohawk/dialogs.cpp:110
#: engines/mohawk/dialogs.cpp:175
msgid "~C~ancel"
msgstr "~C~ancel·la"
-#: engines/dialogs.cpp:320
+#: engines/dialogs.cpp:325
msgid "~K~eys"
msgstr "~T~ecles"
-#: engines/engine.cpp:233
+#: engines/engine.cpp:235
msgid "Could not initialize color format."
msgstr "No s'ha pogut iniciar el format de color."
-#: engines/engine.cpp:241
+#: engines/engine.cpp:243
msgid "Could not switch to video mode: '"
msgstr "No s'ha pogut canviar al mode de vídeo: '"
-#: engines/engine.cpp:250
+#: engines/engine.cpp:252
msgid "Could not apply aspect ratio setting."
msgstr "No s'ha pogut aplicar la configuració de la relació d'aspecte."
-#: engines/engine.cpp:255
+#: engines/engine.cpp:257
msgid "Could not apply fullscreen setting."
msgstr "No s'ha pogut aplicar l'ajust de pantalla completa."
-#: engines/engine.cpp:355
+#: engines/engine.cpp:357
msgid ""
"You appear to be playing this game directly\n"
"from the CD. This is known to cause problems,\n"
@@ -1225,7 +1223,7 @@ msgstr ""
"els fitxers de dades al disc dur.\n"
"Consulteu el fitxer README per a més detalls."
-#: engines/engine.cpp:366
+#: engines/engine.cpp:368
msgid ""
"This game has audio tracks in its disk. These\n"
"tracks need to be ripped from the disk using\n"
@@ -1239,7 +1237,16 @@ msgstr ""
"tal de poder sentir la música del joc.\n"
"Consulteu el fitxer README per a més detalls."
-#: engines/engine.cpp:433
+#: engines/engine.cpp:426
+#, fuzzy, c-format
+msgid ""
+"Gamestate load failed (%s)! Please consult the README for basic information, "
+"and for instructions on how to obtain further assistance."
+msgstr ""
+"Aquest motor no ofereix ajuda dins el joc. Consulteu el fitxer README per a "
+"la informació bàsica i les instruccions sobre com obtenir més assistència."
+
+#: engines/engine.cpp:439
msgid ""
"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 "
@@ -1249,7 +1256,7 @@ msgstr ""
"pel ScummVM. Com a tal, probablement serà inestable, i pot ser que les "
"partides que deseu no funcionin en versions futures de ScummVM."
-#: engines/engine.cpp:436
+#: engines/engine.cpp:442
msgid "Start anyway"
msgstr "Inicia de totes maneres"
@@ -1293,7 +1300,7 @@ msgstr "Jugar"
#: backends/platform/symbian/src/SymbianActions.cpp:52
#: backends/platform/wince/CEActionsPocket.cpp:44
#: backends/platform/wince/CEActionsSmartphone.cpp:52
-#: backends/events/default/default-events.cpp:244
+#: backends/events/default/default-events.cpp:213
msgid "Quit"
msgstr "Surt"
@@ -1367,6 +1374,27 @@ msgctxt "lowres"
msgid "Speech & Subs"
msgstr "Veus i sub."
+#: engines/scumm/dialogs.cpp:653
+msgid "Select a Proficiency Level."
+msgstr ""
+
+#: engines/scumm/dialogs.cpp:655
+msgid "Refer to your Loom(TM) manual for help."
+msgstr ""
+
+#: engines/scumm/dialogs.cpp:658
+#, fuzzy
+msgid "Standard"
+msgstr "Estàndard (16bpp)"
+
+#: engines/scumm/dialogs.cpp:659
+msgid "Practice"
+msgstr ""
+
+#: engines/scumm/dialogs.cpp:660
+msgid "Expert"
+msgstr ""
+
#: engines/scumm/help.cpp:73
msgid "Common keyboard commands:"
msgstr "Comandes comuns de teclat:"
@@ -1880,7 +1908,7 @@ msgstr "Vola a la dreta"
msgid "Fly to lower right"
msgstr "Vola avall i a la dreta"
-#: engines/scumm/scumm.cpp:1774
+#: engines/scumm/scumm.cpp:1773
#, c-format
msgid ""
"Native MIDI support requires the Roland Upgrade from LucasArts,\n"
@@ -1889,7 +1917,7 @@ msgstr ""
"El suport de MIDI natiu requereix l'actualització Roland de LucasArts,\n"
"però no s'ha trobat %s. S'utilitzarà AdLib."
-#: engines/scumm/scumm.cpp:2264 engines/agos/saveload.cpp:189
+#: engines/scumm/scumm.cpp:2271 engines/agos/saveload.cpp:189
#, c-format
msgid ""
"Failed to save game state to file:\n"
@@ -1900,7 +1928,7 @@ msgstr ""
"\n"
"%s"
-#: engines/scumm/scumm.cpp:2271 engines/agos/saveload.cpp:154
+#: engines/scumm/scumm.cpp:2278 engines/agos/saveload.cpp:154
#, c-format
msgid ""
"Failed to load game state from file:\n"
@@ -1911,7 +1939,7 @@ msgstr ""
"\n"
"%s"
-#: engines/scumm/scumm.cpp:2283 engines/agos/saveload.cpp:197
+#: engines/scumm/scumm.cpp:2290 engines/agos/saveload.cpp:197
#, c-format
msgid ""
"Successfully saved game state in file:\n"
@@ -1922,7 +1950,7 @@ msgstr ""
"\n"
"%s"
-#: engines/scumm/scumm.cpp:2498
+#: engines/scumm/scumm.cpp:2505
msgid ""
"Usually, Maniac Mansion would start now. But ScummVM doesn't do that yet. To "
"play it, go to 'Add Game' in the ScummVM start menu and select the 'Maniac' "
@@ -1958,11 +1986,11 @@ msgstr "~M~enú Principal"
msgid "~W~ater Effect Enabled"
msgstr "~E~fecte de l'aigua activat"
-#: engines/sci/engine/kfile.cpp:685
+#: engines/sci/engine/kfile.cpp:673
msgid "Restore game:"
msgstr "Recupera la partida:"
-#: engines/sci/engine/kfile.cpp:685
+#: engines/sci/engine/kfile.cpp:673
msgid "Restore"
msgstr "Restaura"
@@ -1972,11 +2000,11 @@ msgid "Cutscene file '%s' not found!"
msgstr "No s'ha trobat el fitxer d'escena '%s'!"
#: engines/gob/inter_playtoons.cpp:256 engines/gob/inter_v2.cpp:1283
-#: engines/tinsel/saveload.cpp:482
+#: engines/tinsel/saveload.cpp:502
msgid "Failed to load game state from file."
msgstr "No s'ha pogut carregar l'estat del joc del fitxer."
-#: engines/gob/inter_v2.cpp:1353 engines/tinsel/saveload.cpp:560
+#: engines/gob/inter_v2.cpp:1353 engines/tinsel/saveload.cpp:515
msgid "Failed to save game state to file."
msgstr "No s'ha pogut desar l'estat del joc al fitxer."
@@ -1988,6 +2016,60 @@ msgstr "No s'ha pogut esborrar el fitxer."
msgid "Failed to save game"
msgstr "No s'ha pogut desar l'estat del joc"
+#: engines/kyra/lol.cpp:478
+msgid "Attack 1"
+msgstr ""
+
+#: engines/kyra/lol.cpp:479
+msgid "Attack 2"
+msgstr ""
+
+#: engines/kyra/lol.cpp:480
+msgid "Attack 3"
+msgstr ""
+
+#: engines/kyra/lol.cpp:481
+msgid "Move Forward"
+msgstr ""
+
+#: engines/kyra/lol.cpp:482
+msgid "Move Back"
+msgstr ""
+
+#: engines/kyra/lol.cpp:483
+msgid "Slide Left"
+msgstr ""
+
+#: engines/kyra/lol.cpp:484
+#, fuzzy
+msgid "Slide Right"
+msgstr "Dreta"
+
+#: engines/kyra/lol.cpp:485
+#, fuzzy
+msgid "Turn Left"
+msgstr "Apaga"
+
+#: engines/kyra/lol.cpp:486
+#, fuzzy
+msgid "Turn Right"
+msgstr "Cursor Dreta"
+
+#: engines/kyra/lol.cpp:487
+#, fuzzy
+msgid "Rest"
+msgstr "Restaura"
+
+#: engines/kyra/lol.cpp:488
+#, fuzzy
+msgid "Options"
+msgstr "~O~pcions"
+
+#: engines/kyra/lol.cpp:489
+#, fuzzy
+msgid "Choose Spell"
+msgstr "Escull"
+
#: engines/kyra/sound_midi.cpp:475
msgid ""
"You appear to be using a General MIDI device,\n"
@@ -2002,10 +2084,6 @@ msgstr ""
"Roland MT32 als de General MIDI. És possible\n"
"que algunes pistes no es reprodueixin correctament."
-#: engines/m4/m4_menus.cpp:138
-msgid "Save game failed!"
-msgstr "No s'ha pogut desar la partida!"
-
#: engines/sky/compact.cpp:130
msgid ""
"Unable to find \"sky.cpt\" file!\n"
@@ -2022,17 +2100,22 @@ msgstr ""
"El fitxer \"sky.cpt\" té una mida incorrecta.\n"
"Torneu a baixar-lo de www.scummvm.org"
-#: engines/sword1/animation.cpp:344 engines/sword2/animation.cpp:379
+#: engines/sword1/animation.cpp:539
+#, c-format
+msgid "PSX stream cutscene '%s' cannot be played in paletted mode"
+msgstr ""
+
+#: engines/sword1/animation.cpp:560 engines/sword2/animation.cpp:455
msgid "DXA cutscenes found but ScummVM has been built without zlib support"
msgstr ""
"S'han trobat escenes en DXA, però s'ha compilat el ScummVM sense suport de "
"zlib"
-#: engines/sword1/animation.cpp:354 engines/sword2/animation.cpp:389
+#: engines/sword1/animation.cpp:570 engines/sword2/animation.cpp:465
msgid "MPEG2 cutscenes are no longer supported"
msgstr "Les escenes MPEG2 ja no estan suportades"
-#: engines/sword1/animation.cpp:359 engines/sword2/animation.cpp:397
+#: engines/sword1/animation.cpp:576 engines/sword2/animation.cpp:473
#, c-format
msgid "Cutscene '%s' not found"
msgstr "No s'ha trobat l'escena '%s'"
@@ -2076,6 +2159,14 @@ msgstr "Mantingues el nou"
msgid "This is the end of the Broken Sword 1 Demo"
msgstr "Aquest és el final de la Demo del Broken Sword 1"
+#: engines/sword2/animation.cpp:435
+#, fuzzy
+msgid ""
+"PSX cutscenes found but ScummVM has been built without RGB color support"
+msgstr ""
+"S'han trobat escenes en DXA, però s'ha compilat el ScummVM sense suport de "
+"zlib"
+
#: engines/parallaction/saveload.cpp:133
#, c-format
msgid ""
@@ -2134,7 +2225,7 @@ msgstr "Emulador OPL de MAME"
msgid "DOSBox OPL emulator"
msgstr "Emulador OPL de DOSBox"
-#: audio/mididrv.cpp:205
+#: audio/mididrv.cpp:209
#, c-format
msgid ""
"The selected audio device '%s' was not found (e.g. might be turned off or "
@@ -2143,12 +2234,12 @@ msgstr ""
"No s'ha pogut trobar el dispositiu d'àudio seleccionat '%s' (p.e. pot estar "
"desactivat o desconnectat)."
-#: audio/mididrv.cpp:205 audio/mididrv.cpp:217 audio/mididrv.cpp:253
-#: audio/mididrv.cpp:268
+#: audio/mididrv.cpp:209 audio/mididrv.cpp:221 audio/mididrv.cpp:257
+#: audio/mididrv.cpp:272
msgid "Attempting to fall back to the next available device..."
msgstr "Provant de recórrer al següent dispositiu disponible..."
-#: audio/mididrv.cpp:217
+#: audio/mididrv.cpp:221
#, c-format
msgid ""
"The selected audio device '%s' cannot be used. See log file for more "
@@ -2157,7 +2248,7 @@ msgstr ""
"No es pot utilitzar el dispositiu d'àudio seleccionat '%s'. Vegeu el fitxer "
"de registre per a més informació."
-#: audio/mididrv.cpp:253
+#: audio/mididrv.cpp:257
#, c-format
msgid ""
"The preferred audio device '%s' was not found (e.g. might be turned off or "
@@ -2166,7 +2257,7 @@ msgstr ""
"No s'ha pogut trobar el dispositiu d'àudio preferit '%s' (p.e. pot estar "
"desactivat o desconnectat)."
-#: audio/mididrv.cpp:268
+#: audio/mididrv.cpp:272
#, c-format
msgid ""
"The preferred audio device '%s' cannot be used. See log file for more "
@@ -2183,7 +2274,7 @@ msgstr "Sense música"
msgid "Amiga Audio Emulator"
msgstr "Emulador d'àudio Amiga"
-#: audio/softsynth/adlib.cpp:1594
+#: audio/softsynth/adlib.cpp:1593
msgid "AdLib Emulator"
msgstr "Emulador d'AdLib"
@@ -2195,11 +2286,11 @@ msgstr "Emulador d'Apple II GS (NO IMPLEMENTAT)"
msgid "C64 Audio Emulator"
msgstr "Emulador d'àudio C64"
-#: audio/softsynth/mt32.cpp:329
+#: audio/softsynth/mt32.cpp:293
msgid "Initializing MT-32 Emulator"
msgstr "Iniciant l'Emulador de MT-32"
-#: audio/softsynth/mt32.cpp:543
+#: audio/softsynth/mt32.cpp:512
msgid "MT-32 Emulator"
msgstr "Emulador de MT-32"
@@ -2215,15 +2306,24 @@ msgstr "Emulador d'IBM PCjr"
msgid "Keymap:"
msgstr "Assignacions de teclat:"
-#: backends/keymapper/remap-dialog.cpp:64
+#: backends/keymapper/remap-dialog.cpp:66
+#, fuzzy
+msgid " (Effective)"
+msgstr " (Actiu)"
+
+#: backends/keymapper/remap-dialog.cpp:106
msgid " (Active)"
msgstr " (Actiu)"
-#: backends/keymapper/remap-dialog.cpp:98
+#: backends/keymapper/remap-dialog.cpp:106
+msgid " (Blocked)"
+msgstr ""
+
+#: backends/keymapper/remap-dialog.cpp:119
msgid " (Global)"
msgstr " (Global)"
-#: backends/keymapper/remap-dialog.cpp:108
+#: backends/keymapper/remap-dialog.cpp:127
msgid " (Game)"
msgstr " (Joc)"
@@ -2303,40 +2403,64 @@ msgstr "Alta qualitat d'àudio (més lent) (reiniciar)"
msgid "Disable power off"
msgstr "Desactiva l'apagat automàtic"
-#: backends/platform/iphone/osys_events.cpp:338
+#: backends/platform/iphone/osys_events.cpp:301
msgid "Mouse-click-and-drag mode enabled."
msgstr "S'ha activat el mode de clic-i-arrossega."
-#: backends/platform/iphone/osys_events.cpp:340
+#: backends/platform/iphone/osys_events.cpp:303
msgid "Mouse-click-and-drag mode disabled."
msgstr "S'ha desactivat el mode clic-i-arrossega."
-#: backends/platform/iphone/osys_events.cpp:351
+#: backends/platform/iphone/osys_events.cpp:314
msgid "Touchpad mode enabled."
msgstr "Mode Touchpad activat."
-#: backends/platform/iphone/osys_events.cpp:353
+#: backends/platform/iphone/osys_events.cpp:316
msgid "Touchpad mode disabled."
msgstr "Mode Touchpad desactivat."
-#: backends/platform/sdl/macosx/appmenu_osx.mm:67
+#: backends/platform/maemo/maemo.cpp:205
+msgid "Click Mode"
+msgstr ""
+
+#: backends/platform/maemo/maemo.cpp:211
+#: backends/platform/symbian/src/SymbianActions.cpp:42
+#: backends/platform/wince/CEActionsPocket.cpp:60
+#: backends/platform/wince/CEActionsSmartphone.cpp:43
+#: backends/platform/bada/form.cpp:281
+msgid "Left Click"
+msgstr "Clic esquerre"
+
+#: backends/platform/maemo/maemo.cpp:214
+#, fuzzy
+msgid "Middle Click"
+msgstr "Element mig esquerre"
+
+#: backends/platform/maemo/maemo.cpp:217
+#: backends/platform/symbian/src/SymbianActions.cpp:43
+#: backends/platform/wince/CEActionsSmartphone.cpp:44
+#: backends/platform/bada/form.cpp:273
+msgid "Right Click"
+msgstr "Clic dret"
+
+#: backends/platform/sdl/macosx/appmenu_osx.mm:78
msgid "Hide ScummVM"
msgstr "Amaga ScummVM"
-#: backends/platform/sdl/macosx/appmenu_osx.mm:70
+#: backends/platform/sdl/macosx/appmenu_osx.mm:83
msgid "Hide Others"
msgstr "Oculta els altres"
-#: backends/platform/sdl/macosx/appmenu_osx.mm:74
+#: backends/platform/sdl/macosx/appmenu_osx.mm:88
msgid "Show All"
msgstr "Mostra-ho tot"
-#: backends/platform/sdl/macosx/appmenu_osx.mm:92
-#: backends/platform/sdl/macosx/appmenu_osx.mm:99
+#: backends/platform/sdl/macosx/appmenu_osx.mm:110
+#: backends/platform/sdl/macosx/appmenu_osx.mm:121
msgid "Window"
msgstr "Finestra"
-#: backends/platform/sdl/macosx/appmenu_osx.mm:95
+#: backends/platform/sdl/macosx/appmenu_osx.mm:115
msgid "Minimize"
msgstr "Minimitza"
@@ -2350,12 +2474,12 @@ msgid "Normal (no scaling)"
msgstr "Normal (no escalat)"
#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2147
-#: backends/graphics/openglsdl/openglsdl-graphics.cpp:537
+#: backends/graphics/openglsdl/openglsdl-graphics.cpp:533
msgid "Enabled aspect ratio correction"
msgstr "S'ha activat la correcció de la relació d'aspecte"
#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2153
-#: backends/graphics/openglsdl/openglsdl-graphics.cpp:542
+#: backends/graphics/openglsdl/openglsdl-graphics.cpp:538
msgid "Disabled aspect ratio correction"
msgstr "S'ha desactivat la correcció de la relació d'aspecte"
@@ -2364,7 +2488,7 @@ msgid "Active graphics filter:"
msgstr "Filtre de gràfics actiu:"
#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2250
-#: backends/graphics/openglsdl/openglsdl-graphics.cpp:481
+#: backends/graphics/openglsdl/openglsdl-graphics.cpp:477
msgid "Windowed mode"
msgstr "Mode de finestra"
@@ -2388,11 +2512,11 @@ msgstr "Mode de vídeo actual"
msgid "Current scale"
msgstr "Escala actual"
-#: backends/graphics/openglsdl/openglsdl-graphics.cpp:562
+#: backends/graphics/openglsdl/openglsdl-graphics.cpp:558
msgid "Active filter mode: Linear"
msgstr "Mode de filtre actiu: Lineal"
-#: backends/graphics/openglsdl/openglsdl-graphics.cpp:564
+#: backends/graphics/openglsdl/openglsdl-graphics.cpp:560
msgid "Active filter mode: Nearest"
msgstr "Mode de filtre actiu: Pròxim"
@@ -2416,19 +2540,6 @@ msgstr "Esquerra"
msgid "Right"
msgstr "Dreta"
-#: backends/platform/symbian/src/SymbianActions.cpp:42
-#: backends/platform/wince/CEActionsPocket.cpp:60
-#: backends/platform/wince/CEActionsSmartphone.cpp:43
-#: backends/platform/bada/form.cpp:281
-msgid "Left Click"
-msgstr "Clic esquerre"
-
-#: backends/platform/symbian/src/SymbianActions.cpp:43
-#: backends/platform/wince/CEActionsSmartphone.cpp:44
-#: backends/platform/bada/form.cpp:273
-msgid "Right Click"
-msgstr "Clic dret"
-
#: backends/platform/symbian/src/SymbianActions.cpp:46
#: backends/platform/wince/CEActionsSmartphone.cpp:47
msgid "Zone"
@@ -2717,15 +2828,15 @@ msgstr ""
"No us oblideu d'assignar una tecla a l'acció 'Ocultar la barra d'eines' per "
"veure l'inventari complet"
-#: backends/events/default/default-events.cpp:222
+#: backends/events/default/default-events.cpp:191
msgid "Do you really want to return to the Launcher?"
msgstr "Realment voleu tornar al Llançador?"
-#: backends/events/default/default-events.cpp:222
+#: backends/events/default/default-events.cpp:191
msgid "Launcher"
msgstr "Llançador"
-#: backends/events/default/default-events.cpp:244
+#: backends/events/default/default-events.cpp:213
msgid "Do you really want to quit?"
msgstr "Estàs segur de voler sortir?"
@@ -2791,10 +2902,27 @@ msgstr "Mostra el teclat numèric"
msgid "Control Mouse"
msgstr "Controla el ratolí"
-#: backends/events/maemosdl/maemosdl-events.cpp:121
+#: backends/events/maemosdl/maemosdl-events.cpp:192
msgid "Clicking Enabled"
msgstr "Clicat activat"
-#: backends/events/maemosdl/maemosdl-events.cpp:121
+#: backends/events/maemosdl/maemosdl-events.cpp:192
msgid "Clicking Disabled"
msgstr "Clicat desactivat"
+
+#~ msgid "Hercules Green"
+#~ msgstr "Hercules Verd"
+
+#~ msgid "Hercules Amber"
+#~ msgstr "Hercules Àmbar"
+
+#~ msgctxt "lowres"
+#~ msgid "Hercules Green"
+#~ msgstr "Hercules Verd"
+
+#~ msgctxt "lowres"
+#~ msgid "Hercules Amber"
+#~ msgstr "Hercules Àmbar"
+
+#~ msgid "Save game failed!"
+#~ msgstr "No s'ha pogut desar la partida!"
diff --git a/po/cs_CZ.po b/po/cs_CZ.po
index 7593f08c86..feca25ee9c 100644
--- a/po/cs_CZ.po
+++ b/po/cs_CZ.po
@@ -7,18 +7,18 @@ msgid ""
msgstr ""
"Project-Id-Version: ScummVM 1.4.0git\n"
"Report-Msgid-Bugs-To: scummvm-devel@lists.sf.net\n"
-"POT-Creation-Date: 2011-10-19 13:42+0100\n"
-"PO-Revision-Date: 2011-10-05 18:43+0100\n"
+"POT-Creation-Date: 2012-03-07 22:09+0000\n"
+"PO-Revision-Date: 2012-02-17 16:28+0100\n"
"Last-Translator: Zbynìk Schwarz <zbynek.schwarz@gmail.com>\n"
"Language-Team: \n"
-"Language: Cesky\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=iso-8859-2\n"
"Content-Transfer-Encoding: 8bit\n"
+"Language: Cesky\n"
"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2\n"
"X-Poedit-Language: Czech\n"
"X-Poedit-Country: CZECH REPUBLIC\n"
-"X-Poedit-SourceCharset: iso-8859-1\n"
+"X-Poedit-SourceCharset: iso-8859-2\n"
#: gui/about.cpp:91
#, c-format
@@ -47,13 +47,13 @@ msgid "Go up"
msgstr "Jít nahoru"
#: gui/browser.cpp:69 gui/chooser.cpp:45 gui/KeysDialog.cpp:43
-#: gui/launcher.cpp:312 gui/massadd.cpp:94 gui/options.cpp:1178
+#: gui/launcher.cpp:320 gui/massadd.cpp:94 gui/options.cpp:1253
#: gui/saveload.cpp:63 gui/saveload.cpp:155 gui/themebrowser.cpp:54
-#: engines/engine.cpp:436 engines/scumm/dialogs.cpp:190
+#: engines/engine.cpp:442 engines/scumm/dialogs.cpp:190
#: engines/sword1/control.cpp:865 engines/parallaction/saveload.cpp:281
#: backends/platform/wii/options.cpp:48
-#: backends/events/default/default-events.cpp:222
-#: backends/events/default/default-events.cpp:244
+#: backends/events/default/default-events.cpp:191
+#: backends/events/default/default-events.cpp:213
msgid "Cancel"
msgstr "Zru¹it"
@@ -61,25 +61,29 @@ msgstr "Zru¹it"
msgid "Choose"
msgstr "Zvolit"
-#: gui/gui-manager.cpp:116 engines/scumm/help.cpp:125
+#: gui/gui-manager.cpp:115 engines/scumm/help.cpp:125
#: engines/scumm/help.cpp:140 engines/scumm/help.cpp:165
#: engines/scumm/help.cpp:191 engines/scumm/help.cpp:209
#: backends/keymapper/remap-dialog.cpp:52
msgid "Close"
msgstr "Zavøít"
-#: gui/gui-manager.cpp:119
+#: gui/gui-manager.cpp:118
msgid "Mouse click"
msgstr "Kliknutí my¹í"
-#: gui/gui-manager.cpp:122 base/main.cpp:283
+#: gui/gui-manager.cpp:122 base/main.cpp:288
msgid "Display keyboard"
msgstr "Zobrazit klávesnici"
-#: gui/gui-manager.cpp:125 base/main.cpp:286
+#: gui/gui-manager.cpp:126 base/main.cpp:292
msgid "Remap keys"
msgstr "Pøemapovat klávesy"
+#: gui/gui-manager.cpp:129 base/main.cpp:295
+msgid "Toggle FullScreen"
+msgstr "Pøepnout celou obrazovku"
+
#: gui/KeysDialog.h:36 gui/KeysDialog.cpp:145
msgid "Choose an action to map"
msgstr "Zvolte èinnost k mapování"
@@ -88,16 +92,17 @@ msgstr "Zvolte èinnost k mapování"
msgid "Map"
msgstr "Mapovat"
-#: gui/KeysDialog.cpp:42 gui/launcher.cpp:313 gui/launcher.cpp:936
-#: gui/launcher.cpp:940 gui/massadd.cpp:91 gui/options.cpp:1179
-#: engines/engine.cpp:359 engines/engine.cpp:370 engines/scumm/dialogs.cpp:192
-#: engines/scumm/scumm.cpp:1776 engines/agos/animation.cpp:551
+#: gui/KeysDialog.cpp:42 gui/launcher.cpp:321 gui/launcher.cpp:960
+#: gui/launcher.cpp:964 gui/massadd.cpp:91 gui/options.cpp:1254
+#: engines/engine.cpp:361 engines/engine.cpp:372 engines/scumm/dialogs.cpp:192
+#: engines/scumm/scumm.cpp:1775 engines/agos/animation.cpp:551
#: engines/groovie/script.cpp:420 engines/sky/compact.cpp:131
-#: engines/sky/compact.cpp:141 engines/sword1/animation.cpp:344
-#: engines/sword1/animation.cpp:354 engines/sword1/animation.cpp:360
-#: engines/sword1/control.cpp:865 engines/sword1/logic.cpp:1633
-#: engines/sword2/animation.cpp:379 engines/sword2/animation.cpp:389
-#: engines/sword2/animation.cpp:398 engines/parallaction/saveload.cpp:281
+#: engines/sky/compact.cpp:141 engines/sword1/animation.cpp:539
+#: engines/sword1/animation.cpp:560 engines/sword1/animation.cpp:570
+#: engines/sword1/animation.cpp:577 engines/sword1/control.cpp:865
+#: engines/sword1/logic.cpp:1633 engines/sword2/animation.cpp:435
+#: engines/sword2/animation.cpp:455 engines/sword2/animation.cpp:465
+#: engines/sword2/animation.cpp:474 engines/parallaction/saveload.cpp:281
#: backends/platform/wii/options.cpp:47
#: backends/platform/wince/CELauncherDialog.cpp:54
msgid "OK"
@@ -125,15 +130,15 @@ msgstr "Prosím vyberte èinnost"
msgid "Press the key to associate"
msgstr "Zmáèknìte klávesu pro pøiøazení"
-#: gui/launcher.cpp:165
+#: gui/launcher.cpp:170
msgid "Game"
msgstr "Hra"
-#: gui/launcher.cpp:169
+#: gui/launcher.cpp:174
msgid "ID:"
msgstr "ID:"
-#: gui/launcher.cpp:169 gui/launcher.cpp:171 gui/launcher.cpp:172
+#: gui/launcher.cpp:174 gui/launcher.cpp:176 gui/launcher.cpp:177
msgid ""
"Short game identifier used for referring to savegames and running the game "
"from the command line"
@@ -141,310 +146,308 @@ msgstr ""
"Krátký identifikátor her, pou¾ívaný jako odkaz k ulo¾eným hrám a spu¹tìní "
"hry z pøíkazového øádku"
-#: gui/launcher.cpp:171
+#: gui/launcher.cpp:176
msgctxt "lowres"
msgid "ID:"
msgstr "ID:"
-#: gui/launcher.cpp:176
+#: gui/launcher.cpp:181
msgid "Name:"
msgstr "Jméno"
-#: gui/launcher.cpp:176 gui/launcher.cpp:178 gui/launcher.cpp:179
+#: gui/launcher.cpp:181 gui/launcher.cpp:183 gui/launcher.cpp:184
msgid "Full title of the game"
msgstr "Úplný název hry"
-#: gui/launcher.cpp:178
+#: gui/launcher.cpp:183
msgctxt "lowres"
msgid "Name:"
msgstr "Jméno:"
-#: gui/launcher.cpp:182
+#: gui/launcher.cpp:187
msgid "Language:"
msgstr "Jazyk:"
-#: gui/launcher.cpp:182 gui/launcher.cpp:183
+#: gui/launcher.cpp:187 gui/launcher.cpp:188
msgid ""
"Language of the game. This will not turn your Spanish game version into "
"English"
msgstr "Jazyk hry. Toto z Va¹í ©panìlské verze neudìlá Anglickou"
-#: gui/launcher.cpp:184 gui/launcher.cpp:198 gui/options.cpp:74
-#: gui/options.cpp:708 gui/options.cpp:718 gui/options.cpp:1149
+#: gui/launcher.cpp:189 gui/launcher.cpp:203 gui/options.cpp:80
+#: gui/options.cpp:745 gui/options.cpp:758 gui/options.cpp:1224
#: audio/null.cpp:40
msgid "<default>"
msgstr "<výchozí>"
-#: gui/launcher.cpp:194
+#: gui/launcher.cpp:199
msgid "Platform:"
msgstr "Platforma:"
-#: gui/launcher.cpp:194 gui/launcher.cpp:196 gui/launcher.cpp:197
+#: gui/launcher.cpp:199 gui/launcher.cpp:201 gui/launcher.cpp:202
msgid "Platform the game was originally designed for"
msgstr "Platforma, pro kterou byla hra pùvodnì vytvoøena"
-#: gui/launcher.cpp:196
+#: gui/launcher.cpp:201
msgctxt "lowres"
msgid "Platform:"
msgstr "Platforma:"
-#: gui/launcher.cpp:208 gui/options.cpp:1018 gui/options.cpp:1035
+#: gui/launcher.cpp:213 gui/options.cpp:1087 gui/options.cpp:1104
msgid "Graphics"
msgstr "Obraz"
-#: gui/launcher.cpp:208 gui/options.cpp:1018 gui/options.cpp:1035
+#: gui/launcher.cpp:213 gui/options.cpp:1087 gui/options.cpp:1104
msgid "GFX"
msgstr "GFX"
-#: gui/launcher.cpp:211
+#: gui/launcher.cpp:216
msgid "Override global graphic settings"
msgstr "Potlaèit globální nastavení obrazu"
-#: gui/launcher.cpp:213
+#: gui/launcher.cpp:218
msgctxt "lowres"
msgid "Override global graphic settings"
msgstr "Potlaèit globální nastavení obrazu"
-#: gui/launcher.cpp:220 gui/options.cpp:1041
+#: gui/launcher.cpp:225 gui/options.cpp:1110
msgid "Audio"
msgstr "Zvuk"
-#: gui/launcher.cpp:223
+#: gui/launcher.cpp:228
msgid "Override global audio settings"
msgstr "Potlaèit globální nastavení zvuku"
-#: gui/launcher.cpp:225
+#: gui/launcher.cpp:230
msgctxt "lowres"
msgid "Override global audio settings"
msgstr "Potlaèit globální nastavení zvuku"
-#: gui/launcher.cpp:234 gui/options.cpp:1046
+#: gui/launcher.cpp:239 gui/options.cpp:1115
msgid "Volume"
msgstr "Hlasitost"
-#: gui/launcher.cpp:236 gui/options.cpp:1048
+#: gui/launcher.cpp:241 gui/options.cpp:1117
msgctxt "lowres"
msgid "Volume"
msgstr "Hlasitost"
-#: gui/launcher.cpp:239
+#: gui/launcher.cpp:244
msgid "Override global volume settings"
msgstr "Potlaèit globální nastavení hlasitosti"
-#: gui/launcher.cpp:241
+#: gui/launcher.cpp:246
msgctxt "lowres"
msgid "Override global volume settings"
msgstr "Potlaèit globální nastavení hlasitosti"
-#: gui/launcher.cpp:248 gui/options.cpp:1056
+#: gui/launcher.cpp:254 gui/options.cpp:1125
msgid "MIDI"
msgstr "MIDI"
-#: gui/launcher.cpp:251
+#: gui/launcher.cpp:257
msgid "Override global MIDI settings"
msgstr "Potlaèit globální nastavení MIDI"
-#: gui/launcher.cpp:253
+#: gui/launcher.cpp:259
msgctxt "lowres"
msgid "Override global MIDI settings"
msgstr "Potlaèit globální nastavení MIDI"
-#: gui/launcher.cpp:263 gui/options.cpp:1062
+#: gui/launcher.cpp:268 gui/options.cpp:1131
msgid "MT-32"
msgstr "MT-32"
-#: gui/launcher.cpp:266
+#: gui/launcher.cpp:271
msgid "Override global MT-32 settings"
msgstr "Potlaèit globální nastavení MT-32"
-#: gui/launcher.cpp:268
+#: gui/launcher.cpp:273
msgctxt "lowres"
msgid "Override global MT-32 settings"
msgstr "Potlaèit globální nastavení MT-32"
-#: gui/launcher.cpp:279 gui/options.cpp:1069
+#: gui/launcher.cpp:282 gui/options.cpp:1138
msgid "Paths"
msgstr "Cesty"
-#: gui/launcher.cpp:281 gui/options.cpp:1071
+#: gui/launcher.cpp:284 gui/options.cpp:1140
msgctxt "lowres"
msgid "Paths"
msgstr "Cesty"
-#: gui/launcher.cpp:288
+#: gui/launcher.cpp:291
msgid "Game Path:"
msgstr "Cesta Hry:"
-#: gui/launcher.cpp:290
+#: gui/launcher.cpp:293
msgctxt "lowres"
msgid "Game Path:"
msgstr "Cesta Hry:"
-#: gui/launcher.cpp:295 gui/options.cpp:1091
+#: gui/launcher.cpp:298 gui/options.cpp:1164
msgid "Extra Path:"
msgstr "Dodateèná Cesta:"
-#: gui/launcher.cpp:295 gui/launcher.cpp:297 gui/launcher.cpp:298
+#: gui/launcher.cpp:298 gui/launcher.cpp:300 gui/launcher.cpp:301
msgid "Specifies path to additional data used the game"
msgstr "Stanoví cestu pro dodateèná data pou¾itá ve høe"
-#: gui/launcher.cpp:297 gui/options.cpp:1093
+#: gui/launcher.cpp:300 gui/options.cpp:1166
msgctxt "lowres"
msgid "Extra Path:"
msgstr "Dodateèná Cesta:"
-#: gui/launcher.cpp:302 gui/options.cpp:1079
+#: gui/launcher.cpp:307 gui/options.cpp:1148
msgid "Save Path:"
msgstr "Cesta pro ulo¾ení:"
-#: gui/launcher.cpp:302 gui/launcher.cpp:304 gui/launcher.cpp:305
-#: gui/options.cpp:1079 gui/options.cpp:1081 gui/options.cpp:1082
+#: gui/launcher.cpp:307 gui/launcher.cpp:309 gui/launcher.cpp:310
+#: gui/options.cpp:1148 gui/options.cpp:1150 gui/options.cpp:1151
msgid "Specifies where your savegames are put"
msgstr "Stanovuje, kam jsou umístìny Va¹e ulo¾ené hry"
-#: gui/launcher.cpp:304 gui/options.cpp:1081
+#: gui/launcher.cpp:309 gui/options.cpp:1150
msgctxt "lowres"
msgid "Save Path:"
msgstr "Cesta pro ulo¾ení:"
-#: gui/launcher.cpp:321 gui/launcher.cpp:404 gui/launcher.cpp:453
-#: gui/options.cpp:1088 gui/options.cpp:1094 gui/options.cpp:1101
-#: gui/options.cpp:1202 gui/options.cpp:1208 gui/options.cpp:1214
-#: gui/options.cpp:1222 gui/options.cpp:1246 gui/options.cpp:1250
-#: gui/options.cpp:1256 gui/options.cpp:1263 gui/options.cpp:1362
+#: gui/launcher.cpp:329 gui/launcher.cpp:416 gui/launcher.cpp:469
+#: gui/launcher.cpp:523 gui/options.cpp:1159 gui/options.cpp:1167
+#: gui/options.cpp:1176 gui/options.cpp:1283 gui/options.cpp:1289
+#: gui/options.cpp:1297 gui/options.cpp:1327 gui/options.cpp:1333
+#: gui/options.cpp:1340 gui/options.cpp:1433 gui/options.cpp:1436
+#: gui/options.cpp:1448
msgctxt "path"
msgid "None"
msgstr "®ádné"
-#: gui/launcher.cpp:326 gui/launcher.cpp:408
+#: gui/launcher.cpp:334 gui/launcher.cpp:422 gui/launcher.cpp:527
+#: gui/options.cpp:1277 gui/options.cpp:1321 gui/options.cpp:1439
#: backends/platform/wii/options.cpp:56
msgid "Default"
msgstr "Výchozí"
-#: gui/launcher.cpp:446 gui/options.cpp:1356
+#: gui/launcher.cpp:462 gui/options.cpp:1442
msgid "Select SoundFont"
msgstr "Vybrat SoundFont"
-#: gui/launcher.cpp:465 gui/launcher.cpp:612
+#: gui/launcher.cpp:481 gui/launcher.cpp:636
msgid "Select directory with game data"
msgstr "Vyberte adresáø s daty hry"
-#: gui/launcher.cpp:483
+#: gui/launcher.cpp:499
msgid "Select additional game directory"
msgstr "Vyberte dodateèný adresáø hry"
-#: gui/launcher.cpp:495
+#: gui/launcher.cpp:511
msgid "Select directory for saved games"
msgstr "Vyberte adresáø pro ulo¾ené hry"
-#: gui/launcher.cpp:514
+#: gui/launcher.cpp:538
msgid "This game ID is already taken. Please choose another one."
msgstr "Toto ID hry je u¾ zabrané. Vyberte si, prosím, jiné."
-#: gui/launcher.cpp:555 engines/dialogs.cpp:110
+#: gui/launcher.cpp:579 engines/dialogs.cpp:110
msgid "~Q~uit"
msgstr "~U~konèit"
-#: gui/launcher.cpp:555 backends/platform/sdl/macosx/appmenu_osx.mm:80
+#: gui/launcher.cpp:579 backends/platform/sdl/macosx/appmenu_osx.mm:96
msgid "Quit ScummVM"
msgstr "Ukonèit ScummVM"
-#: gui/launcher.cpp:556
+#: gui/launcher.cpp:580
msgid "A~b~out..."
msgstr "~O~ Programu..."
-#: gui/launcher.cpp:556 backends/platform/sdl/macosx/appmenu_osx.mm:61
+#: gui/launcher.cpp:580 backends/platform/sdl/macosx/appmenu_osx.mm:70
msgid "About ScummVM"
msgstr "O ScummVM"
-#: gui/launcher.cpp:557
+#: gui/launcher.cpp:581
msgid "~O~ptions..."
msgstr "~V~olby..."
-#: gui/launcher.cpp:557
+#: gui/launcher.cpp:581
msgid "Change global ScummVM options"
msgstr "Zmìnit globální volby ScummVM"
-#: gui/launcher.cpp:559
+#: gui/launcher.cpp:583
msgid "~S~tart"
msgstr "~S~pustit"
-#: gui/launcher.cpp:559
+#: gui/launcher.cpp:583
msgid "Start selected game"
msgstr "Spustit zvolenou hru"
-#: gui/launcher.cpp:562
+#: gui/launcher.cpp:586
msgid "~L~oad..."
msgstr "~N~ahrát..."
-#: gui/launcher.cpp:562
+#: gui/launcher.cpp:586
msgid "Load savegame for selected game"
msgstr "Nahrát ulo¾enou pozici pro zvolenou hru"
-#: gui/launcher.cpp:567 gui/launcher.cpp:1055
+#: gui/launcher.cpp:591 gui/launcher.cpp:1079
msgid "~A~dd Game..."
msgstr "~P~øidat hru..."
-#: gui/launcher.cpp:567 gui/launcher.cpp:574
+#: gui/launcher.cpp:591 gui/launcher.cpp:598
msgid "Hold Shift for Mass Add"
msgstr "Podr¾te Shift pro Hromadné Pøidání"
-#: gui/launcher.cpp:569
+#: gui/launcher.cpp:593
msgid "~E~dit Game..."
msgstr "~U~pravit Hru..."
-#: gui/launcher.cpp:569 gui/launcher.cpp:576
+#: gui/launcher.cpp:593 gui/launcher.cpp:600
msgid "Change game options"
msgstr "Zmìnit volby hry"
-#: gui/launcher.cpp:571
+#: gui/launcher.cpp:595
msgid "~R~emove Game"
msgstr "~O~dstranit Hru"
-#: gui/launcher.cpp:571 gui/launcher.cpp:578
+#: gui/launcher.cpp:595 gui/launcher.cpp:602
msgid "Remove game from the list. The game data files stay intact"
msgstr "Odstranit hru ze seznamu. Herní data zùstanou zachována"
-#: gui/launcher.cpp:574 gui/launcher.cpp:1055
+#: gui/launcher.cpp:598 gui/launcher.cpp:1079
msgctxt "lowres"
msgid "~A~dd Game..."
msgstr "~P~øidat hru..."
-#: gui/launcher.cpp:576
+#: gui/launcher.cpp:600
msgctxt "lowres"
msgid "~E~dit Game..."
msgstr "~U~pravit hru..."
-#: gui/launcher.cpp:578
+#: gui/launcher.cpp:602
msgctxt "lowres"
msgid "~R~emove Game"
msgstr "~O~dstranit hru"
-#: gui/launcher.cpp:586
+#: gui/launcher.cpp:610
msgid "Search in game list"
msgstr "Hledat v seznamu her"
-#: gui/launcher.cpp:590 gui/launcher.cpp:1102
+#: gui/launcher.cpp:614 gui/launcher.cpp:1126
msgid "Search:"
msgstr "Hledat:"
-#: gui/launcher.cpp:593 gui/options.cpp:826
-msgid "Clear value"
-msgstr "Vyèistit hodnotu"
-
-#: gui/launcher.cpp:615 engines/dialogs.cpp:114 engines/mohawk/myst.cpp:255
+#: gui/launcher.cpp:639 engines/dialogs.cpp:114 engines/mohawk/myst.cpp:255
#: engines/mohawk/riven.cpp:716 engines/cruise/menu.cpp:216
msgid "Load game:"
msgstr "Nahrát hru:"
-#: gui/launcher.cpp:615 engines/dialogs.cpp:114 engines/scumm/dialogs.cpp:188
+#: gui/launcher.cpp:639 engines/dialogs.cpp:114 engines/scumm/dialogs.cpp:188
#: engines/mohawk/myst.cpp:255 engines/mohawk/riven.cpp:716
#: engines/cruise/menu.cpp:216 backends/platform/wince/CEActionsPocket.cpp:267
#: backends/platform/wince/CEActionsSmartphone.cpp:231
msgid "Load"
msgstr "Nahrát"
-#: gui/launcher.cpp:723
+#: gui/launcher.cpp:747
msgid ""
"Do you really want to run the mass game detector? This could potentially add "
"a huge number of games."
@@ -452,7 +455,7 @@ msgstr ""
"Opravdu chcete spustit hromadnou detekci her? Toto by mohlo potenciálnì "
"pøidat velkou spoustu her. "
-#: gui/launcher.cpp:724 gui/launcher.cpp:872
+#: gui/launcher.cpp:748 gui/launcher.cpp:896
#: backends/events/symbiansdl/symbiansdl-events.cpp:184
#: backends/platform/wince/CEActionsPocket.cpp:326
#: backends/platform/wince/CEActionsSmartphone.cpp:287
@@ -460,7 +463,7 @@ msgstr ""
msgid "Yes"
msgstr "Ano"
-#: gui/launcher.cpp:724 gui/launcher.cpp:872
+#: gui/launcher.cpp:748 gui/launcher.cpp:896
#: backends/events/symbiansdl/symbiansdl-events.cpp:184
#: backends/platform/wince/CEActionsPocket.cpp:326
#: backends/platform/wince/CEActionsSmartphone.cpp:287
@@ -468,36 +471,36 @@ msgstr "Ano"
msgid "No"
msgstr "Ne"
-#: gui/launcher.cpp:772
+#: gui/launcher.cpp:796
msgid "ScummVM couldn't open the specified directory!"
msgstr "ScummVM nemohl tento adresáø otevøít!"
-#: gui/launcher.cpp:784
+#: gui/launcher.cpp:808
msgid "ScummVM could not find any game in the specified directory!"
msgstr "ScummVM nemohl v zadaném adresáøi najít ¾ádnou hru!"
-#: gui/launcher.cpp:798
+#: gui/launcher.cpp:822
msgid "Pick the game:"
msgstr "Vybrat hru:"
-#: gui/launcher.cpp:872
+#: gui/launcher.cpp:896
msgid "Do you really want to remove this game configuration?"
msgstr "Opravdu chcete odstranit nastavení této hry?"
-#: gui/launcher.cpp:936
+#: gui/launcher.cpp:960
msgid "This game does not support loading games from the launcher."
msgstr "Tato hra nepodporuje spou¹tìní her ze spou¹tìèe"
-#: gui/launcher.cpp:940
+#: gui/launcher.cpp:964
msgid "ScummVM could not find any engine capable of running the selected game!"
msgstr "ScummVM nemohl najít ¾ádné jádro schopné vybranou hru spustit!"
-#: gui/launcher.cpp:1054
+#: gui/launcher.cpp:1078
msgctxt "lowres"
msgid "Mass Add..."
msgstr "Hromadné Pøidání..."
-#: gui/launcher.cpp:1054
+#: gui/launcher.cpp:1078
msgid "Mass Add..."
msgstr "Hromadné Pøidání..."
@@ -524,141 +527,141 @@ msgstr "Prohledáno %d adresáøù..."
msgid "Discovered %d new games, ignored %d previously added games ..."
msgstr "Objeveno %d nových her, ignorováno %d døíve pøidaných her ..."
-#: gui/options.cpp:72
+#: gui/options.cpp:78
msgid "Never"
msgstr "Nikdy"
-#: gui/options.cpp:72
+#: gui/options.cpp:78
msgid "every 5 mins"
msgstr "Ka¾dých 5 min"
-#: gui/options.cpp:72
+#: gui/options.cpp:78
msgid "every 10 mins"
msgstr "Ka¾dých 10 min"
-#: gui/options.cpp:72
+#: gui/options.cpp:78
msgid "every 15 mins"
msgstr "Ka¾dých 15 min"
-#: gui/options.cpp:72
+#: gui/options.cpp:78
msgid "every 30 mins"
msgstr "Ka¾dých 30 min"
-#: gui/options.cpp:74
+#: gui/options.cpp:80
msgid "8 kHz"
msgstr "8 kHz"
-#: gui/options.cpp:74
+#: gui/options.cpp:80
msgid "11kHz"
msgstr "11kHz"
-#: gui/options.cpp:74
+#: gui/options.cpp:80
msgid "22 kHz"
msgstr "22 kHz"
-#: gui/options.cpp:74
+#: gui/options.cpp:80
msgid "44 kHz"
msgstr "44 kHz"
-#: gui/options.cpp:74
+#: gui/options.cpp:80
msgid "48 kHz"
msgstr "48 kHz"
-#: gui/options.cpp:236 gui/options.cpp:464 gui/options.cpp:559
-#: gui/options.cpp:625 gui/options.cpp:825
+#: gui/options.cpp:257 gui/options.cpp:485 gui/options.cpp:586
+#: gui/options.cpp:659 gui/options.cpp:868
msgctxt "soundfont"
msgid "None"
msgstr "®ádné"
-#: gui/options.cpp:372
+#: gui/options.cpp:393
msgid "Failed to apply some of the graphic options changes:"
msgstr "Nelze pou¾ít nìkteré zmìny mo¾ností grafiky:"
-#: gui/options.cpp:384
+#: gui/options.cpp:405
msgid "the video mode could not be changed."
msgstr "re¾im obrazu nemohl být zmìnìn."
-#: gui/options.cpp:390
+#: gui/options.cpp:411
msgid "the fullscreen setting could not be changed"
msgstr "nastavení celé obrazovky nemohlo být zmìnìno"
-#: gui/options.cpp:396
+#: gui/options.cpp:417
msgid "the aspect ratio setting could not be changed"
msgstr "nastavení pomìru stran nemohlo být zmìnìno"
-#: gui/options.cpp:705
+#: gui/options.cpp:742
msgid "Graphics mode:"
msgstr "Re¾im obrazu:"
-#: gui/options.cpp:716
+#: gui/options.cpp:756
msgid "Render mode:"
msgstr "Re¾im vykreslení:"
-#: gui/options.cpp:716 gui/options.cpp:717
+#: gui/options.cpp:756 gui/options.cpp:757
msgid "Special dithering modes supported by some games"
msgstr "Speciální re¾imy chvìní podporované nìkterými hrami"
-#: gui/options.cpp:726
+#: gui/options.cpp:768
#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2248
-#: backends/graphics/openglsdl/openglsdl-graphics.cpp:476
+#: backends/graphics/openglsdl/openglsdl-graphics.cpp:472
msgid "Fullscreen mode"
msgstr "Re¾im celé obrazovky"
-#: gui/options.cpp:729
+#: gui/options.cpp:771
msgid "Aspect ratio correction"
msgstr "Korekce pomìru stran"
-#: gui/options.cpp:729
+#: gui/options.cpp:771
msgid "Correct aspect ratio for 320x200 games"
msgstr "Korigovat pomìr stran pro hry 320x200"
-#: gui/options.cpp:730
+#: gui/options.cpp:772
msgid "EGA undithering"
msgstr "Nerozkládání EGA"
-#: gui/options.cpp:730
+#: gui/options.cpp:772
msgid "Enable undithering in EGA games that support it"
msgstr "Povolit nerozkládání v EGA hrách, které to podporují"
-#: gui/options.cpp:738
+#: gui/options.cpp:780
msgid "Preferred Device:"
msgstr "Prioritní Zaøízení:"
-#: gui/options.cpp:738
+#: gui/options.cpp:780
msgid "Music Device:"
msgstr "Hudební zaøízení"
-#: gui/options.cpp:738 gui/options.cpp:740
+#: gui/options.cpp:780 gui/options.cpp:782
msgid "Specifies preferred sound device or sound card emulator"
msgstr "Stanoví prioritní zvukové zaøízení nebo emulátor zvukové karty"
-#: gui/options.cpp:738 gui/options.cpp:740 gui/options.cpp:741
+#: gui/options.cpp:780 gui/options.cpp:782 gui/options.cpp:783
msgid "Specifies output sound device or sound card emulator"
msgstr "Stanoví výstupní zvukové zaøízení nebo emulátor zvukové karty"
-#: gui/options.cpp:740
+#: gui/options.cpp:782
msgctxt "lowres"
msgid "Preferred Dev.:"
msgstr "Prioritní Zaø.:"
-#: gui/options.cpp:740
+#: gui/options.cpp:782
msgctxt "lowres"
msgid "Music Device:"
msgstr "Hudební zaøízení"
-#: gui/options.cpp:766
+#: gui/options.cpp:809
msgid "AdLib emulator:"
msgstr "AdLib emulátor"
-#: gui/options.cpp:766 gui/options.cpp:767
+#: gui/options.cpp:809 gui/options.cpp:810
msgid "AdLib is used for music in many games"
msgstr "AdLib se pou¾ívá pro hudbu v mnoha hrách"
-#: gui/options.cpp:777
+#: gui/options.cpp:820
msgid "Output rate:"
msgstr "Výstup. frekvence:"
-#: gui/options.cpp:777 gui/options.cpp:778
+#: gui/options.cpp:820 gui/options.cpp:821
msgid ""
"Higher value specifies better sound quality but may be not supported by your "
"soundcard"
@@ -666,62 +669,62 @@ msgstr ""
"Vy¹¹í hodnota zpùsobí lep¹í kvalitu zvuku, ale nemusí být podporována Va¹i "
"zvukovou kartou"
-#: gui/options.cpp:788
+#: gui/options.cpp:831
msgid "GM Device:"
msgstr "GM Zaøízení:"
-#: gui/options.cpp:788
+#: gui/options.cpp:831
msgid "Specifies default sound device for General MIDI output"
msgstr "Stanoví výchozí zvukové zaøízení pro výstup General MIDI"
-#: gui/options.cpp:799
+#: gui/options.cpp:842
msgid "Don't use General MIDI music"
msgstr "Nepou¾ívat hudbu General MIDI"
-#: gui/options.cpp:810 gui/options.cpp:871
+#: gui/options.cpp:853 gui/options.cpp:915
msgid "Use first available device"
msgstr "Pou¾ít první dostupné zaøízení"
-#: gui/options.cpp:822
+#: gui/options.cpp:865
msgid "SoundFont:"
msgstr "SoundFont:"
-#: gui/options.cpp:822 gui/options.cpp:824 gui/options.cpp:825
+#: gui/options.cpp:865 gui/options.cpp:867 gui/options.cpp:868
msgid "SoundFont is supported by some audio cards, Fluidsynth and Timidity"
msgstr ""
"SoundFont je podporován nìkterými zvukovými kartami, Fluidsynth a Timidity"
-#: gui/options.cpp:824
+#: gui/options.cpp:867
msgctxt "lowres"
msgid "SoundFont:"
msgstr "SoundFont:"
-#: gui/options.cpp:829
+#: gui/options.cpp:873
msgid "Mixed AdLib/MIDI mode"
msgstr "Smí¹ený re¾im AdLib/MIDI"
-#: gui/options.cpp:829
+#: gui/options.cpp:873
msgid "Use both MIDI and AdLib sound generation"
msgstr "Pou¾ít obì zvukové generace MIDI a AdLib"
-#: gui/options.cpp:832
+#: gui/options.cpp:876
msgid "MIDI gain:"
msgstr "Zesílení MIDI:"
-#: gui/options.cpp:842
+#: gui/options.cpp:886
msgid "MT-32 Device:"
msgstr "Zaøízení MT-32:"
-#: gui/options.cpp:842
+#: gui/options.cpp:886
msgid "Specifies default sound device for Roland MT-32/LAPC1/CM32l/CM64 output"
msgstr ""
"Stanoví výchozí zvukové výstupní zaøízení pro Roland MT-32/LAPC1/CM32l/CM64"
-#: gui/options.cpp:847
+#: gui/options.cpp:891
msgid "True Roland MT-32 (disable GM emulation)"
msgstr "Opravdový Roland MT-32 (vypne GM emulaci)"
-#: gui/options.cpp:847 gui/options.cpp:849
+#: gui/options.cpp:891 gui/options.cpp:893
msgid ""
"Check if you want to use your real hardware Roland-compatible sound device "
"connected to your computer"
@@ -729,190 +732,190 @@ msgstr ""
"Za¹krtnìte, pokud chcete pou¾ít pravé hardwarové zaøízení kompatibilní s "
"Roland, pøipojené k Va¹emu poèítaèi"
-#: gui/options.cpp:849
+#: gui/options.cpp:893
msgctxt "lowres"
msgid "True Roland MT-32 (no GM emulation)"
msgstr "Opravdový Roland MT-32 (¾ádná GM emulace)"
-#: gui/options.cpp:852
+#: gui/options.cpp:896
msgid "Enable Roland GS Mode"
msgstr "Zapnout re¾im Roland GS"
-#: gui/options.cpp:852
+#: gui/options.cpp:896
msgid "Turns off General MIDI mapping for games with Roland MT-32 soundtrack"
msgstr "Vypne mapování General MIDI pro hry s Roland MT-32 zvukovým doprovodem"
-#: gui/options.cpp:861
+#: gui/options.cpp:905
msgid "Don't use Roland MT-32 music"
msgstr "Nepou¾ívat hudbu Roland MT-32"
-#: gui/options.cpp:888
+#: gui/options.cpp:932
msgid "Text and Speech:"
msgstr "Text a Øeè"
-#: gui/options.cpp:892 gui/options.cpp:902
+#: gui/options.cpp:936 gui/options.cpp:946
msgid "Speech"
msgstr "Øeè"
-#: gui/options.cpp:893 gui/options.cpp:903
+#: gui/options.cpp:937 gui/options.cpp:947
msgid "Subtitles"
msgstr "Titulky"
-#: gui/options.cpp:894
+#: gui/options.cpp:938
msgid "Both"
msgstr "Oba"
-#: gui/options.cpp:896
+#: gui/options.cpp:940
msgid "Subtitle speed:"
msgstr "Rychlost titulkù:"
-#: gui/options.cpp:898
+#: gui/options.cpp:942
msgctxt "lowres"
msgid "Text and Speech:"
msgstr "Text a Øeè:"
-#: gui/options.cpp:902
+#: gui/options.cpp:946
msgid "Spch"
msgstr "Øeè"
-#: gui/options.cpp:903
+#: gui/options.cpp:947
msgid "Subs"
msgstr "Titl"
-#: gui/options.cpp:904
+#: gui/options.cpp:948
msgctxt "lowres"
msgid "Both"
msgstr "Oba"
-#: gui/options.cpp:904
+#: gui/options.cpp:948
msgid "Show subtitles and play speech"
msgstr "Zobrazit titulky a pøehrávat øeè"
-#: gui/options.cpp:906
+#: gui/options.cpp:950
msgctxt "lowres"
msgid "Subtitle speed:"
msgstr "Rychlost titulkù"
-#: gui/options.cpp:922
+#: gui/options.cpp:966
msgid "Music volume:"
msgstr "Hlasitost hudby"
-#: gui/options.cpp:924
+#: gui/options.cpp:968
msgctxt "lowres"
msgid "Music volume:"
msgstr "Hlasitost hudby"
-#: gui/options.cpp:931
+#: gui/options.cpp:975
msgid "Mute All"
msgstr "Ztlumit V¹e"
-#: gui/options.cpp:934
+#: gui/options.cpp:978
msgid "SFX volume:"
msgstr "Hlasitost zvukù"
-#: gui/options.cpp:934 gui/options.cpp:936 gui/options.cpp:937
+#: gui/options.cpp:978 gui/options.cpp:980 gui/options.cpp:981
msgid "Special sound effects volume"
msgstr "Hlasitost speciálních zvukových efektù"
-#: gui/options.cpp:936
+#: gui/options.cpp:980
msgctxt "lowres"
msgid "SFX volume:"
msgstr "Hlasitost zvukù"
-#: gui/options.cpp:944
+#: gui/options.cpp:988
msgid "Speech volume:"
msgstr "Hlasitost øeèi"
-#: gui/options.cpp:946
+#: gui/options.cpp:990
msgctxt "lowres"
msgid "Speech volume:"
msgstr "Hlasitost øeèi"
-#: gui/options.cpp:1085
+#: gui/options.cpp:1156
msgid "Theme Path:"
msgstr "Cesta ke Vzhledu:"
-#: gui/options.cpp:1087
+#: gui/options.cpp:1158
msgctxt "lowres"
msgid "Theme Path:"
msgstr "Cesta ke Vzhledu:"
-#: gui/options.cpp:1091 gui/options.cpp:1093 gui/options.cpp:1094
+#: gui/options.cpp:1164 gui/options.cpp:1166 gui/options.cpp:1167
msgid "Specifies path to additional data used by all games or ScummVM"
msgstr "Stanoví cestu k dodateèným datùm pou¾ívaná v¹emi hrami nebo ScummVM"
-#: gui/options.cpp:1098
+#: gui/options.cpp:1173
msgid "Plugins Path:"
msgstr "Cesta k Pluginùm:"
-#: gui/options.cpp:1100
+#: gui/options.cpp:1175
msgctxt "lowres"
msgid "Plugins Path:"
msgstr "Cesta k Pluginùm:"
-#: gui/options.cpp:1109
+#: gui/options.cpp:1184
msgid "Misc"
msgstr "Rùzné"
-#: gui/options.cpp:1111
+#: gui/options.cpp:1186
msgctxt "lowres"
msgid "Misc"
msgstr "Rùzné"
-#: gui/options.cpp:1113
+#: gui/options.cpp:1188
msgid "Theme:"
msgstr "Vzhled:"
-#: gui/options.cpp:1117
+#: gui/options.cpp:1192
msgid "GUI Renderer:"
msgstr "GUI Vykreslovaè:"
-#: gui/options.cpp:1129
+#: gui/options.cpp:1204
msgid "Autosave:"
msgstr "Autoukládání:"
-#: gui/options.cpp:1131
+#: gui/options.cpp:1206
msgctxt "lowres"
msgid "Autosave:"
msgstr "Autoukládání:"
-#: gui/options.cpp:1139
+#: gui/options.cpp:1214
msgid "Keys"
msgstr "Klávesy"
-#: gui/options.cpp:1146
+#: gui/options.cpp:1221
msgid "GUI Language:"
msgstr "Jazyk GUI"
-#: gui/options.cpp:1146
+#: gui/options.cpp:1221
msgid "Language of ScummVM GUI"
msgstr "Jazyk GUI ScummVM"
-#: gui/options.cpp:1295
+#: gui/options.cpp:1372
msgid "You have to restart ScummVM before your changes will take effect."
msgstr "Pro pou¾ití tìchto nastavení musíte restartovat ScummVM."
-#: gui/options.cpp:1308
+#: gui/options.cpp:1385
msgid "Select directory for savegames"
msgstr "Vybrat adresáø pro ulo¾ené hry"
-#: gui/options.cpp:1315
+#: gui/options.cpp:1392
msgid "The chosen directory cannot be written to. Please select another one."
msgstr "Do zvoleného adresáøe nelze zapisovat. Vyberte, prosím, jiný."
-#: gui/options.cpp:1324
+#: gui/options.cpp:1401
msgid "Select directory for GUI themes"
msgstr "Vyberte adresáø pro vhledy GUI"
-#: gui/options.cpp:1334
+#: gui/options.cpp:1411
msgid "Select directory for extra files"
msgstr "Vyberte adresáø pro dodateèné soubory"
-#: gui/options.cpp:1345
+#: gui/options.cpp:1422
msgid "Select directory for plugins"
msgstr "Vyberte adresáø pro zásuvné moduly"
-#: gui/options.cpp:1389
+#: gui/options.cpp:1475
msgid ""
"The theme you selected does not support your current language. If you want "
"to use this theme you need to switch to another language first."
@@ -960,60 +963,64 @@ msgstr "Bezejmenný ulo¾ený stav"
msgid "Select a Theme"
msgstr "Vyberte Vzhled"
-#: gui/ThemeEngine.cpp:328
+#: gui/ThemeEngine.cpp:333
msgid "Disabled GFX"
msgstr "GFX zakázáno"
-#: gui/ThemeEngine.cpp:328
+#: gui/ThemeEngine.cpp:333
msgctxt "lowres"
msgid "Disabled GFX"
msgstr "GFX zakázáno"
-#: gui/ThemeEngine.cpp:329
+#: gui/ThemeEngine.cpp:334
msgid "Standard Renderer (16bpp)"
msgstr "Standardní Vykreslovaè (16bpp)"
-#: gui/ThemeEngine.cpp:329
+#: gui/ThemeEngine.cpp:334
msgid "Standard (16bpp)"
msgstr "Standardní (16bpp)"
-#: gui/ThemeEngine.cpp:331
+#: gui/ThemeEngine.cpp:336
msgid "Antialiased Renderer (16bpp)"
msgstr "Vykreslovaè s vyhlazenými hranami (16bpp)"
-#: gui/ThemeEngine.cpp:331
+#: gui/ThemeEngine.cpp:336
msgid "Antialiased (16bpp)"
msgstr "S vyhlazenými hranami (16bpp)"
+#: gui/widget.cpp:312 gui/widget.cpp:314 gui/widget.cpp:320 gui/widget.cpp:322
+msgid "Clear value"
+msgstr "Vyèistit hodnotu"
+
#: base/main.cpp:203
#, c-format
msgid "Engine does not support debug level '%s'"
msgstr "Jádro nepodporuje úroveò ladìní '%s'"
-#: base/main.cpp:271
+#: base/main.cpp:275
msgid "Menu"
msgstr "Menu"
-#: base/main.cpp:274 backends/platform/symbian/src/SymbianActions.cpp:45
+#: base/main.cpp:278 backends/platform/symbian/src/SymbianActions.cpp:45
#: backends/platform/wince/CEActionsPocket.cpp:45
#: backends/platform/wince/CEActionsSmartphone.cpp:46
msgid "Skip"
msgstr "Pøeskoèit"
-#: base/main.cpp:277 backends/platform/symbian/src/SymbianActions.cpp:50
+#: base/main.cpp:281 backends/platform/symbian/src/SymbianActions.cpp:50
#: backends/platform/wince/CEActionsPocket.cpp:42
msgid "Pause"
msgstr "Pauza"
-#: base/main.cpp:280
+#: base/main.cpp:284
msgid "Skip line"
msgstr "Pøeskoèit øádek"
-#: base/main.cpp:439
+#: base/main.cpp:455
msgid "Error running game:"
msgstr "Chyba pøi spu¹tìní hry:"
-#: base/main.cpp:463
+#: base/main.cpp:479
msgid "Could not find any engine capable of running the selected game"
msgstr "Nelze nalézt ¾ádné jádro schopné vybranou hru spustit"
@@ -1081,25 +1088,6 @@ msgstr "Zru¹eno u¾ivatelem"
msgid "Unknown error"
msgstr "Neznámá chyba"
-#. I18N: Hercules is graphics card name
-#: common/util.cpp:275
-msgid "Hercules Green"
-msgstr "Hercules Zelená"
-
-#: common/util.cpp:276
-msgid "Hercules Amber"
-msgstr "Hercules Jantarová"
-
-#: common/util.cpp:283
-msgctxt "lowres"
-msgid "Hercules Green"
-msgstr "Hercules Zelená"
-
-#: common/util.cpp:284
-msgctxt "lowres"
-msgid "Hercules Amber"
-msgstr "Hercules Jantarová"
-
#: engines/advancedDetector.cpp:296
#, c-format
msgid "The game in '%s' seems to be unknown."
@@ -1147,12 +1135,12 @@ msgid "~R~eturn to Launcher"
msgstr "~N~ávrat do Spou¹tìèe"
#: engines/dialogs.cpp:116 engines/cruise/menu.cpp:214
-#: engines/sci/engine/kfile.cpp:578
+#: engines/sci/engine/kfile.cpp:566
msgid "Save game:"
msgstr "Ulo¾it hru:"
#: engines/dialogs.cpp:116 engines/scumm/dialogs.cpp:187
-#: engines/cruise/menu.cpp:214 engines/sci/engine/kfile.cpp:578
+#: engines/cruise/menu.cpp:214 engines/sci/engine/kfile.cpp:566
#: backends/platform/symbian/src/SymbianActions.cpp:44
#: backends/platform/wince/CEActionsPocket.cpp:43
#: backends/platform/wince/CEActionsPocket.cpp:267
@@ -1171,37 +1159,47 @@ msgstr ""
"prohlédnìte si README pro základní informace a pro instrukce jak získat "
"dal¹í pomoc."
-#: engines/dialogs.cpp:316 engines/mohawk/dialogs.cpp:109
+#: engines/dialogs.cpp:243
+#, fuzzy, c-format
+msgid ""
+"Gamestate save failed (%s)! Please consult the README for basic information, "
+"and for instructions on how to obtain further assistance."
+msgstr ""
+"Je nám líto, ale toto jádro v souèasnosti nepodporuje herní nápovìdu. Prosím "
+"prohlédnìte si README pro základní informace a pro instrukce jak získat "
+"dal¹í pomoc."
+
+#: engines/dialogs.cpp:321 engines/mohawk/dialogs.cpp:109
#: engines/mohawk/dialogs.cpp:174
msgid "~O~K"
msgstr "~O~K"
-#: engines/dialogs.cpp:317 engines/mohawk/dialogs.cpp:110
+#: engines/dialogs.cpp:322 engines/mohawk/dialogs.cpp:110
#: engines/mohawk/dialogs.cpp:175
msgid "~C~ancel"
msgstr "~Z~ru¹it"
-#: engines/dialogs.cpp:320
+#: engines/dialogs.cpp:325
msgid "~K~eys"
msgstr "~K~lávesy"
-#: engines/engine.cpp:233
+#: engines/engine.cpp:235
msgid "Could not initialize color format."
msgstr "Nelze zavést barevný formát."
-#: engines/engine.cpp:241
+#: engines/engine.cpp:243
msgid "Could not switch to video mode: '"
msgstr "Nelze pøepnout na re¾im obrazu: '"
-#: engines/engine.cpp:250
+#: engines/engine.cpp:252
msgid "Could not apply aspect ratio setting."
msgstr "Nelze pou¾ít nastavení pomìru stran."
-#: engines/engine.cpp:255
+#: engines/engine.cpp:257
msgid "Could not apply fullscreen setting."
msgstr "Nelze pou¾ít nastavení celé obrazovky."
-#: engines/engine.cpp:355
+#: engines/engine.cpp:357
msgid ""
"You appear to be playing this game directly\n"
"from the CD. This is known to cause problems,\n"
@@ -1215,7 +1213,7 @@ msgstr ""
"datové soubory na Vá¹ pevný disk.\n"
"Pro podrobnosti si pøeètìte README."
-#: engines/engine.cpp:366
+#: engines/engine.cpp:368
msgid ""
"This game has audio tracks in its disk. These\n"
"tracks need to be ripped from the disk using\n"
@@ -1229,7 +1227,17 @@ msgstr ""
"abyste mohli poslouchat hudbu ve høe.\n"
"Pro podrobnosti si pøeètìte README."
-#: engines/engine.cpp:433
+#: engines/engine.cpp:426
+#, fuzzy, c-format
+msgid ""
+"Gamestate load failed (%s)! Please consult the README for basic information, "
+"and for instructions on how to obtain further assistance."
+msgstr ""
+"Je nám líto, ale toto jádro v souèasnosti nepodporuje herní nápovìdu. Prosím "
+"prohlédnìte si README pro základní informace a pro instrukce jak získat "
+"dal¹í pomoc."
+
+#: engines/engine.cpp:439
msgid ""
"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 "
@@ -1239,7 +1247,7 @@ msgstr ""
"ScummVM. Proto je mo¾né, ¾e bude nestabilní a jakékoli ulo¾ené hry nemusí "
"fungovat v budoucích verzích ScummVM."
-#: engines/engine.cpp:436
+#: engines/engine.cpp:442
msgid "Start anyway"
msgstr "Pøesto spustit"
@@ -1283,7 +1291,7 @@ msgstr "Hrát"
#: backends/platform/symbian/src/SymbianActions.cpp:52
#: backends/platform/wince/CEActionsPocket.cpp:44
#: backends/platform/wince/CEActionsSmartphone.cpp:52
-#: backends/events/default/default-events.cpp:244
+#: backends/events/default/default-events.cpp:213
msgid "Quit"
msgstr "Ukonèit"
@@ -1357,6 +1365,26 @@ msgctxt "lowres"
msgid "Speech & Subs"
msgstr "Øeè a Titulky"
+#: engines/scumm/dialogs.cpp:653
+msgid "Select a Proficiency Level."
+msgstr "Vyberte úroveò odbornosti."
+
+#: engines/scumm/dialogs.cpp:655
+msgid "Refer to your Loom(TM) manual for help."
+msgstr "Pro nápovìdu si pøeètìte manuál Loom(TM)."
+
+#: engines/scumm/dialogs.cpp:658
+msgid "Standard"
+msgstr "Standardní"
+
+#: engines/scumm/dialogs.cpp:659
+msgid "Practice"
+msgstr "Cvièení"
+
+#: engines/scumm/dialogs.cpp:660
+msgid "Expert"
+msgstr "Pokroèilý"
+
#: engines/scumm/help.cpp:73
msgid "Common keyboard commands:"
msgstr "Bì¾né klávesové pøíkazy"
@@ -1870,7 +1898,7 @@ msgstr "Letìt doprava"
msgid "Fly to lower right"
msgstr "Letìt doprava dolù"
-#: engines/scumm/scumm.cpp:1774
+#: engines/scumm/scumm.cpp:1773
#, c-format
msgid ""
"Native MIDI support requires the Roland Upgrade from LucasArts,\n"
@@ -1879,7 +1907,7 @@ msgstr ""
"Pøirozená podpora MIDI vy¾aduje Aktualizaci Roland od LucasArts,\n"
"ale %s chybí. Místo toho je pou¾it AdLib."
-#: engines/scumm/scumm.cpp:2264 engines/agos/saveload.cpp:189
+#: engines/scumm/scumm.cpp:2271 engines/agos/saveload.cpp:189
#, c-format
msgid ""
"Failed to save game state to file:\n"
@@ -1890,7 +1918,7 @@ msgstr ""
"\n"
"%s"
-#: engines/scumm/scumm.cpp:2271 engines/agos/saveload.cpp:154
+#: engines/scumm/scumm.cpp:2278 engines/agos/saveload.cpp:154
#, c-format
msgid ""
"Failed to load game state from file:\n"
@@ -1901,7 +1929,7 @@ msgstr ""
"\n"
"%s"
-#: engines/scumm/scumm.cpp:2283 engines/agos/saveload.cpp:197
+#: engines/scumm/scumm.cpp:2290 engines/agos/saveload.cpp:197
#, c-format
msgid ""
"Successfully saved game state in file:\n"
@@ -1912,7 +1940,7 @@ msgstr ""
"\n"
"%s"
-#: engines/scumm/scumm.cpp:2498
+#: engines/scumm/scumm.cpp:2505
msgid ""
"Usually, Maniac Mansion would start now. But ScummVM doesn't do that yet. To "
"play it, go to 'Add Game' in the ScummVM start menu and select the 'Maniac' "
@@ -1948,11 +1976,11 @@ msgstr "~H~lavní Menu"
msgid "~W~ater Effect Enabled"
msgstr "~E~fekt Vody Zapnut"
-#: engines/sci/engine/kfile.cpp:685
+#: engines/sci/engine/kfile.cpp:673
msgid "Restore game:"
msgstr "Obnovit hru"
-#: engines/sci/engine/kfile.cpp:685
+#: engines/sci/engine/kfile.cpp:673
msgid "Restore"
msgstr "Obnovit"
@@ -1962,11 +1990,11 @@ msgid "Cutscene file '%s' not found!"
msgstr "Soubor videa '%s' nenalezen'"
#: engines/gob/inter_playtoons.cpp:256 engines/gob/inter_v2.cpp:1283
-#: engines/tinsel/saveload.cpp:482
+#: engines/tinsel/saveload.cpp:502
msgid "Failed to load game state from file."
msgstr "Nelze naèíst stav hry ze souboru."
-#: engines/gob/inter_v2.cpp:1353 engines/tinsel/saveload.cpp:560
+#: engines/gob/inter_v2.cpp:1353 engines/tinsel/saveload.cpp:515
msgid "Failed to save game state to file."
msgstr "Nelze ulo¾it stav hry do souboru."
@@ -1978,6 +2006,54 @@ msgstr "Nelze smazat soubor."
msgid "Failed to save game"
msgstr "Nelze ulo¾it hru."
+#: engines/kyra/lol.cpp:478
+msgid "Attack 1"
+msgstr "Útok 1"
+
+#: engines/kyra/lol.cpp:479
+msgid "Attack 2"
+msgstr "Útok 2"
+
+#: engines/kyra/lol.cpp:480
+msgid "Attack 3"
+msgstr "Útok 3"
+
+#: engines/kyra/lol.cpp:481
+msgid "Move Forward"
+msgstr "Vpøed"
+
+#: engines/kyra/lol.cpp:482
+msgid "Move Back"
+msgstr "Vzad"
+
+#: engines/kyra/lol.cpp:483
+msgid "Slide Left"
+msgstr "Pøesunout se Doleva"
+
+#: engines/kyra/lol.cpp:484
+msgid "Slide Right"
+msgstr "Pøesunout se Doprava"
+
+#: engines/kyra/lol.cpp:485
+msgid "Turn Left"
+msgstr "Otoèit se doleva"
+
+#: engines/kyra/lol.cpp:486
+msgid "Turn Right"
+msgstr "Otoèit se doprava"
+
+#: engines/kyra/lol.cpp:487
+msgid "Rest"
+msgstr "Odpoèinout si"
+
+#: engines/kyra/lol.cpp:488
+msgid "Options"
+msgstr "Volby"
+
+#: engines/kyra/lol.cpp:489
+msgid "Choose Spell"
+msgstr "Zvolit Kouzlo"
+
#: engines/kyra/sound_midi.cpp:475
msgid ""
"You appear to be using a General MIDI device,\n"
@@ -1992,10 +2068,6 @@ msgstr ""
"ty od General MIDI. Po tomto se mù¾e stát,\n"
"¾e pár stop nebude správnì pøehráno."
-#: engines/m4/m4_menus.cpp:138
-msgid "Save game failed!"
-msgstr "Ukládání hry selhalo!"
-
#: engines/sky/compact.cpp:130
msgid ""
"Unable to find \"sky.cpt\" file!\n"
@@ -2012,15 +2084,20 @@ msgstr ""
"Soubor \"sky.cpt\" má nesprávnou velikost.\n"
"Stáhnìte si ho, prosím, (znovu) z www.scummvm.org"
-#: engines/sword1/animation.cpp:344 engines/sword2/animation.cpp:379
+#: engines/sword1/animation.cpp:539
+#, c-format
+msgid "PSX stream cutscene '%s' cannot be played in paletted mode"
+msgstr ""
+
+#: engines/sword1/animation.cpp:560 engines/sword2/animation.cpp:455
msgid "DXA cutscenes found but ScummVM has been built without zlib support"
msgstr "Videa DXA nalezena, ale ScummVM byl sestaven bez podpory zlib"
-#: engines/sword1/animation.cpp:354 engines/sword2/animation.cpp:389
+#: engines/sword1/animation.cpp:570 engines/sword2/animation.cpp:465
msgid "MPEG2 cutscenes are no longer supported"
msgstr "Videa MPGE2 ji¾ nejsou podporována"
-#: engines/sword1/animation.cpp:359 engines/sword2/animation.cpp:397
+#: engines/sword1/animation.cpp:576 engines/sword2/animation.cpp:473
#, c-format
msgid "Cutscene '%s' not found"
msgstr "Video '%s' nenalezeno"
@@ -2064,6 +2141,12 @@ msgstr "Ponechat novou"
msgid "This is the end of the Broken Sword 1 Demo"
msgstr "Toto je konec Dema Broken Sword 1"
+#: engines/sword2/animation.cpp:435
+#, fuzzy
+msgid ""
+"PSX cutscenes found but ScummVM has been built without RGB color support"
+msgstr "Videa DXA nalezena, ale ScummVM byl sestaven bez podpory zlib"
+
#: engines/parallaction/saveload.cpp:133
#, c-format
msgid ""
@@ -2121,7 +2204,7 @@ msgstr "MAME OPL Emulátor"
msgid "DOSBox OPL emulator"
msgstr "DOSBox OPL Emulátor"
-#: audio/mididrv.cpp:205
+#: audio/mididrv.cpp:209
#, c-format
msgid ""
"The selected audio device '%s' was not found (e.g. might be turned off or "
@@ -2130,12 +2213,12 @@ msgstr ""
"Zvolené zvukové zaøízení '%s' nebylo nalezeno (napø. mù¾e být vypnuto nebo "
"odpojeno)."
-#: audio/mididrv.cpp:205 audio/mididrv.cpp:217 audio/mididrv.cpp:253
-#: audio/mididrv.cpp:268
+#: audio/mididrv.cpp:209 audio/mididrv.cpp:221 audio/mididrv.cpp:257
+#: audio/mididrv.cpp:272
msgid "Attempting to fall back to the next available device..."
msgstr "Pokus o navrácení na nejbli¾¹í dostupné zaøízení..."
-#: audio/mididrv.cpp:217
+#: audio/mididrv.cpp:221
#, c-format
msgid ""
"The selected audio device '%s' cannot be used. See log file for more "
@@ -2144,7 +2227,7 @@ msgstr ""
"Zvolené zvukové zaøízení '%s' nelze pou¾ít. Podívejte se na záznam pro více "
"informací."
-#: audio/mididrv.cpp:253
+#: audio/mididrv.cpp:257
#, c-format
msgid ""
"The preferred audio device '%s' was not found (e.g. might be turned off or "
@@ -2153,7 +2236,7 @@ msgstr ""
"Upøednostòované zvukové zaøízení '%s' nebylo nalezeno (napø. mù¾e být "
"vypnuto nebo odpojeno)."
-#: audio/mididrv.cpp:268
+#: audio/mididrv.cpp:272
#, c-format
msgid ""
"The preferred audio device '%s' cannot be used. See log file for more "
@@ -2170,7 +2253,7 @@ msgstr "Bez hudby"
msgid "Amiga Audio Emulator"
msgstr "Emulátor zvuku Amiga"
-#: audio/softsynth/adlib.cpp:1594
+#: audio/softsynth/adlib.cpp:1593
msgid "AdLib Emulator"
msgstr "AdLib Emulátor"
@@ -2182,11 +2265,11 @@ msgstr "Apple II GS Emulátor (NENÍ ZAVEDEN)"
msgid "C64 Audio Emulator"
msgstr "Emulátor zvuku C64"
-#: audio/softsynth/mt32.cpp:329
+#: audio/softsynth/mt32.cpp:293
msgid "Initializing MT-32 Emulator"
msgstr "Zavádím MT-32 Emulátor"
-#: audio/softsynth/mt32.cpp:543
+#: audio/softsynth/mt32.cpp:512
msgid "MT-32 Emulator"
msgstr "MT-32 Emulátor"
@@ -2202,15 +2285,23 @@ msgstr "IBM PCjr Emulátor"
msgid "Keymap:"
msgstr "Mapa Kláves:"
-#: backends/keymapper/remap-dialog.cpp:64
+#: backends/keymapper/remap-dialog.cpp:66
+msgid " (Effective)"
+msgstr " (Aktivní)"
+
+#: backends/keymapper/remap-dialog.cpp:106
msgid " (Active)"
msgstr "(Aktivní)"
-#: backends/keymapper/remap-dialog.cpp:98
+#: backends/keymapper/remap-dialog.cpp:106
+msgid " (Blocked)"
+msgstr ""
+
+#: backends/keymapper/remap-dialog.cpp:119
msgid " (Global)"
msgstr "(Globální)"
-#: backends/keymapper/remap-dialog.cpp:108
+#: backends/keymapper/remap-dialog.cpp:127
msgid " (Game)"
msgstr "(Hra)"
@@ -2290,40 +2381,63 @@ msgstr "Vysoká kvalita zvuku (pomalej¹í) (restart) "
msgid "Disable power off"
msgstr "Zakázat vypnutí"
-#: backends/platform/iphone/osys_events.cpp:338
+#: backends/platform/iphone/osys_events.cpp:301
msgid "Mouse-click-and-drag mode enabled."
msgstr "Re¾im pøetáhnutí my¹i zapnut."
-#: backends/platform/iphone/osys_events.cpp:340
+#: backends/platform/iphone/osys_events.cpp:303
msgid "Mouse-click-and-drag mode disabled."
msgstr "Re¾im pøetáhnutí my¹i vypnut."
-#: backends/platform/iphone/osys_events.cpp:351
+#: backends/platform/iphone/osys_events.cpp:314
msgid "Touchpad mode enabled."
msgstr "Touchpad re¾im zapnut"
-#: backends/platform/iphone/osys_events.cpp:353
+#: backends/platform/iphone/osys_events.cpp:316
msgid "Touchpad mode disabled."
msgstr "Touchpad re¾im vypnut"
-#: backends/platform/sdl/macosx/appmenu_osx.mm:67
+#: backends/platform/maemo/maemo.cpp:205
+msgid "Click Mode"
+msgstr "Re¾im kliknutí"
+
+#: backends/platform/maemo/maemo.cpp:211
+#: backends/platform/symbian/src/SymbianActions.cpp:42
+#: backends/platform/wince/CEActionsPocket.cpp:60
+#: backends/platform/wince/CEActionsSmartphone.cpp:43
+#: backends/platform/bada/form.cpp:281
+msgid "Left Click"
+msgstr "Levé Kliknutí"
+
+#: backends/platform/maemo/maemo.cpp:214
+msgid "Middle Click"
+msgstr "Kliknutí prostøedním tlaèítkem"
+
+#: backends/platform/maemo/maemo.cpp:217
+#: backends/platform/symbian/src/SymbianActions.cpp:43
+#: backends/platform/wince/CEActionsSmartphone.cpp:44
+#: backends/platform/bada/form.cpp:273
+msgid "Right Click"
+msgstr "Pravé kliknutí"
+
+#: backends/platform/sdl/macosx/appmenu_osx.mm:78
msgid "Hide ScummVM"
msgstr "Skrýt ScummVM"
-#: backends/platform/sdl/macosx/appmenu_osx.mm:70
+#: backends/platform/sdl/macosx/appmenu_osx.mm:83
msgid "Hide Others"
msgstr "Skrýt Ostatní"
-#: backends/platform/sdl/macosx/appmenu_osx.mm:74
+#: backends/platform/sdl/macosx/appmenu_osx.mm:88
msgid "Show All"
msgstr "Zobrazit V¹e"
-#: backends/platform/sdl/macosx/appmenu_osx.mm:92
-#: backends/platform/sdl/macosx/appmenu_osx.mm:99
+#: backends/platform/sdl/macosx/appmenu_osx.mm:110
+#: backends/platform/sdl/macosx/appmenu_osx.mm:121
msgid "Window"
msgstr "Okno"
-#: backends/platform/sdl/macosx/appmenu_osx.mm:95
+#: backends/platform/sdl/macosx/appmenu_osx.mm:115
msgid "Minimize"
msgstr "Minimalizovat"
@@ -2337,12 +2451,12 @@ msgid "Normal (no scaling)"
msgstr "Normální (bez zmìny velikosti)"
#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2147
-#: backends/graphics/openglsdl/openglsdl-graphics.cpp:537
+#: backends/graphics/openglsdl/openglsdl-graphics.cpp:533
msgid "Enabled aspect ratio correction"
msgstr "Povolena korekce pomìru stran"
#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2153
-#: backends/graphics/openglsdl/openglsdl-graphics.cpp:542
+#: backends/graphics/openglsdl/openglsdl-graphics.cpp:538
msgid "Disabled aspect ratio correction"
msgstr "Zakázána korekce pomìru stran"
@@ -2351,7 +2465,7 @@ msgid "Active graphics filter:"
msgstr "Aktivní grafický filtr:"
#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2250
-#: backends/graphics/openglsdl/openglsdl-graphics.cpp:481
+#: backends/graphics/openglsdl/openglsdl-graphics.cpp:477
msgid "Windowed mode"
msgstr "Re¾im do okna"
@@ -2375,11 +2489,11 @@ msgstr "Souèasný re¾im obrazu"
msgid "Current scale"
msgstr "Souèasná velikost"
-#: backends/graphics/openglsdl/openglsdl-graphics.cpp:562
+#: backends/graphics/openglsdl/openglsdl-graphics.cpp:558
msgid "Active filter mode: Linear"
msgstr "Aktivní re¾im filtru: Lineární"
-#: backends/graphics/openglsdl/openglsdl-graphics.cpp:564
+#: backends/graphics/openglsdl/openglsdl-graphics.cpp:560
msgid "Active filter mode: Nearest"
msgstr "Aktivní re¾im filtru: Nejbli¾¹í"
@@ -2403,19 +2517,6 @@ msgstr "Doleva"
msgid "Right"
msgstr "Doprava"
-#: backends/platform/symbian/src/SymbianActions.cpp:42
-#: backends/platform/wince/CEActionsPocket.cpp:60
-#: backends/platform/wince/CEActionsSmartphone.cpp:43
-#: backends/platform/bada/form.cpp:281
-msgid "Left Click"
-msgstr "Levé Kliknutí"
-
-#: backends/platform/symbian/src/SymbianActions.cpp:43
-#: backends/platform/wince/CEActionsSmartphone.cpp:44
-#: backends/platform/bada/form.cpp:273
-msgid "Right Click"
-msgstr "Pravé kliknutí"
-
#: backends/platform/symbian/src/SymbianActions.cpp:46
#: backends/platform/wince/CEActionsSmartphone.cpp:47
msgid "Zone"
@@ -2706,15 +2807,15 @@ msgstr ""
"Nezapomeòte namapovat klávesu k èinnosti 'Skrýt Panel Nástrojù, abyste "
"vidìli celý inventáø"
-#: backends/events/default/default-events.cpp:222
+#: backends/events/default/default-events.cpp:191
msgid "Do you really want to return to the Launcher?"
msgstr "Opravdu se chcete vrátit tuto do Spou¹tìèe?"
-#: backends/events/default/default-events.cpp:222
+#: backends/events/default/default-events.cpp:191
msgid "Launcher"
msgstr "Spou¹tìè"
-#: backends/events/default/default-events.cpp:244
+#: backends/events/default/default-events.cpp:213
msgid "Do you really want to quit?"
msgstr "Opravdu chcete skonèit?"
@@ -2780,14 +2881,31 @@ msgstr "Zobrazit Klávesnici"
msgid "Control Mouse"
msgstr "Ovládání My¹i"
-#: backends/events/maemosdl/maemosdl-events.cpp:121
+#: backends/events/maemosdl/maemosdl-events.cpp:192
msgid "Clicking Enabled"
msgstr "Kliknutí Povoleno"
-#: backends/events/maemosdl/maemosdl-events.cpp:121
+#: backends/events/maemosdl/maemosdl-events.cpp:192
msgid "Clicking Disabled"
msgstr "Kliknutí Zakázáno"
+#~ msgid "Hercules Green"
+#~ msgstr "Hercules Zelená"
+
+#~ msgid "Hercules Amber"
+#~ msgstr "Hercules Jantarová"
+
+#~ msgctxt "lowres"
+#~ msgid "Hercules Green"
+#~ msgstr "Hercules Zelená"
+
+#~ msgctxt "lowres"
+#~ msgid "Hercules Amber"
+#~ msgstr "Hercules Jantarová"
+
+#~ msgid "Save game failed!"
+#~ msgstr "Ukládání hry selhalo!"
+
#~ msgctxt "lowres"
#~ msgid "Add Game..."
#~ msgstr "Pøidat Hru..."
diff --git a/po/da_DA.po b/po/da_DA.po
index 6a151fc2f8..59f7ae63a7 100644
--- a/po/da_DA.po
+++ b/po/da_DA.po
@@ -1,19 +1,19 @@
-# Copyright (C) 2010 ScummVM Team
-# This file is distributed under the same license as the ScummVM package.
-# Steffen Nyeland <steffen@nyeland.dk>, 2010.
-#
+# Copyright (C) 2010-2012 ScummVM Team
+# This file is distributed under the same license as the ScummVM package.
+# Steffen Nyeland <steffen@nyeland.dk>, 2010.
+#
msgid ""
msgstr ""
"Project-Id-Version: ScummVM 1.3.0svn\n"
"Report-Msgid-Bugs-To: scummvm-devel@lists.sf.net\n"
-"POT-Creation-Date: 2011-10-19 13:42+0100\n"
+"POT-Creation-Date: 2012-03-07 22:09+0000\n"
"PO-Revision-Date: 2011-01-08 22:53+0100\n"
"Last-Translator: Steffen Nyeland <steffen@nyeland.dk>\n"
"Language-Team: Steffen Nyeland <steffen@nyeland.dk>\n"
-"Language: Dansk\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=iso-8859-1\n"
"Content-Transfer-Encoding: 8bit\n"
+"Language: Dansk\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: gui/about.cpp:91
@@ -43,13 +43,13 @@ msgid "Go up"
msgstr "Gå op"
#: gui/browser.cpp:69 gui/chooser.cpp:45 gui/KeysDialog.cpp:43
-#: gui/launcher.cpp:312 gui/massadd.cpp:94 gui/options.cpp:1178
+#: gui/launcher.cpp:320 gui/massadd.cpp:94 gui/options.cpp:1253
#: gui/saveload.cpp:63 gui/saveload.cpp:155 gui/themebrowser.cpp:54
-#: engines/engine.cpp:436 engines/scumm/dialogs.cpp:190
+#: engines/engine.cpp:442 engines/scumm/dialogs.cpp:190
#: engines/sword1/control.cpp:865 engines/parallaction/saveload.cpp:281
#: backends/platform/wii/options.cpp:48
-#: backends/events/default/default-events.cpp:222
-#: backends/events/default/default-events.cpp:244
+#: backends/events/default/default-events.cpp:191
+#: backends/events/default/default-events.cpp:213
msgid "Cancel"
msgstr "Fortryd"
@@ -57,25 +57,30 @@ msgstr "Fortryd"
msgid "Choose"
msgstr "Vælg"
-#: gui/gui-manager.cpp:116 engines/scumm/help.cpp:125
+#: gui/gui-manager.cpp:115 engines/scumm/help.cpp:125
#: engines/scumm/help.cpp:140 engines/scumm/help.cpp:165
#: engines/scumm/help.cpp:191 engines/scumm/help.cpp:209
#: backends/keymapper/remap-dialog.cpp:52
msgid "Close"
msgstr "Luk"
-#: gui/gui-manager.cpp:119
+#: gui/gui-manager.cpp:118
msgid "Mouse click"
msgstr "Muse klik"
-#: gui/gui-manager.cpp:122 base/main.cpp:283
+#: gui/gui-manager.cpp:122 base/main.cpp:288
msgid "Display keyboard"
msgstr "Vis tastatur"
-#: gui/gui-manager.cpp:125 base/main.cpp:286
+#: gui/gui-manager.cpp:126 base/main.cpp:292
msgid "Remap keys"
msgstr "Kortlæg taster"
+#: gui/gui-manager.cpp:129 base/main.cpp:295
+#, fuzzy
+msgid "Toggle FullScreen"
+msgstr "Skift fuldskærm"
+
#: gui/KeysDialog.h:36 gui/KeysDialog.cpp:145
msgid "Choose an action to map"
msgstr "Vælg en handling at kortlægge"
@@ -84,16 +89,17 @@ msgstr "Vælg en handling at kortlægge"
msgid "Map"
msgstr "Kortlæg"
-#: gui/KeysDialog.cpp:42 gui/launcher.cpp:313 gui/launcher.cpp:936
-#: gui/launcher.cpp:940 gui/massadd.cpp:91 gui/options.cpp:1179
-#: engines/engine.cpp:359 engines/engine.cpp:370 engines/scumm/dialogs.cpp:192
-#: engines/scumm/scumm.cpp:1776 engines/agos/animation.cpp:551
+#: gui/KeysDialog.cpp:42 gui/launcher.cpp:321 gui/launcher.cpp:960
+#: gui/launcher.cpp:964 gui/massadd.cpp:91 gui/options.cpp:1254
+#: engines/engine.cpp:361 engines/engine.cpp:372 engines/scumm/dialogs.cpp:192
+#: engines/scumm/scumm.cpp:1775 engines/agos/animation.cpp:551
#: engines/groovie/script.cpp:420 engines/sky/compact.cpp:131
-#: engines/sky/compact.cpp:141 engines/sword1/animation.cpp:344
-#: engines/sword1/animation.cpp:354 engines/sword1/animation.cpp:360
-#: engines/sword1/control.cpp:865 engines/sword1/logic.cpp:1633
-#: engines/sword2/animation.cpp:379 engines/sword2/animation.cpp:389
-#: engines/sword2/animation.cpp:398 engines/parallaction/saveload.cpp:281
+#: engines/sky/compact.cpp:141 engines/sword1/animation.cpp:539
+#: engines/sword1/animation.cpp:560 engines/sword1/animation.cpp:570
+#: engines/sword1/animation.cpp:577 engines/sword1/control.cpp:865
+#: engines/sword1/logic.cpp:1633 engines/sword2/animation.cpp:435
+#: engines/sword2/animation.cpp:455 engines/sword2/animation.cpp:465
+#: engines/sword2/animation.cpp:474 engines/parallaction/saveload.cpp:281
#: backends/platform/wii/options.cpp:47
#: backends/platform/wince/CELauncherDialog.cpp:54
msgid "OK"
@@ -121,15 +127,15 @@ msgstr "Vælg venligst en handling"
msgid "Press the key to associate"
msgstr "Tryk tasten for at tilknytte"
-#: gui/launcher.cpp:165
+#: gui/launcher.cpp:170
msgid "Game"
msgstr "Spil"
-#: gui/launcher.cpp:169
+#: gui/launcher.cpp:174
msgid "ID:"
msgstr "ID:"
-#: gui/launcher.cpp:169 gui/launcher.cpp:171 gui/launcher.cpp:172
+#: gui/launcher.cpp:174 gui/launcher.cpp:176 gui/launcher.cpp:177
msgid ""
"Short game identifier used for referring to savegames and running the game "
"from the command line"
@@ -137,29 +143,29 @@ msgstr ""
"Kort spil identifikator til brug for gemmer, og for at køre spillet fra "
"kommandolinien"
-#: gui/launcher.cpp:171
+#: gui/launcher.cpp:176
msgctxt "lowres"
msgid "ID:"
msgstr "ID:"
-#: gui/launcher.cpp:176
+#: gui/launcher.cpp:181
msgid "Name:"
msgstr "Navn:"
-#: gui/launcher.cpp:176 gui/launcher.cpp:178 gui/launcher.cpp:179
+#: gui/launcher.cpp:181 gui/launcher.cpp:183 gui/launcher.cpp:184
msgid "Full title of the game"
msgstr "Fuld titel på spillet"
-#: gui/launcher.cpp:178
+#: gui/launcher.cpp:183
msgctxt "lowres"
msgid "Name:"
msgstr "Navn:"
-#: gui/launcher.cpp:182
+#: gui/launcher.cpp:187
msgid "Language:"
msgstr "Sprog:"
-#: gui/launcher.cpp:182 gui/launcher.cpp:183
+#: gui/launcher.cpp:187 gui/launcher.cpp:188
msgid ""
"Language of the game. This will not turn your Spanish game version into "
"English"
@@ -167,282 +173,280 @@ msgstr ""
"Spillets sprog. Dette vil ikke ændre din spanske version af spillet til "
"engelsk"
-#: gui/launcher.cpp:184 gui/launcher.cpp:198 gui/options.cpp:74
-#: gui/options.cpp:708 gui/options.cpp:718 gui/options.cpp:1149
+#: gui/launcher.cpp:189 gui/launcher.cpp:203 gui/options.cpp:80
+#: gui/options.cpp:745 gui/options.cpp:758 gui/options.cpp:1224
#: audio/null.cpp:40
msgid "<default>"
msgstr "<standard>"
-#: gui/launcher.cpp:194
+#: gui/launcher.cpp:199
msgid "Platform:"
msgstr "Platform:"
-#: gui/launcher.cpp:194 gui/launcher.cpp:196 gui/launcher.cpp:197
+#: gui/launcher.cpp:199 gui/launcher.cpp:201 gui/launcher.cpp:202
msgid "Platform the game was originally designed for"
msgstr "Platform som spillet oprindeligt var designet til"
-#: gui/launcher.cpp:196
+#: gui/launcher.cpp:201
msgctxt "lowres"
msgid "Platform:"
msgstr "Platform:"
-#: gui/launcher.cpp:208 gui/options.cpp:1018 gui/options.cpp:1035
+#: gui/launcher.cpp:213 gui/options.cpp:1087 gui/options.cpp:1104
msgid "Graphics"
msgstr "Grafik"
-#: gui/launcher.cpp:208 gui/options.cpp:1018 gui/options.cpp:1035
+#: gui/launcher.cpp:213 gui/options.cpp:1087 gui/options.cpp:1104
msgid "GFX"
msgstr "GFX"
-#: gui/launcher.cpp:211
+#: gui/launcher.cpp:216
msgid "Override global graphic settings"
msgstr "Overstyr globale grafik indstillinger"
-#: gui/launcher.cpp:213
+#: gui/launcher.cpp:218
msgctxt "lowres"
msgid "Override global graphic settings"
msgstr "Overstyr globale grafik indstillinger"
-#: gui/launcher.cpp:220 gui/options.cpp:1041
+#: gui/launcher.cpp:225 gui/options.cpp:1110
msgid "Audio"
msgstr "Lyd"
-#: gui/launcher.cpp:223
+#: gui/launcher.cpp:228
msgid "Override global audio settings"
msgstr "Overstyr globale lyd indstillinger"
-#: gui/launcher.cpp:225
+#: gui/launcher.cpp:230
msgctxt "lowres"
msgid "Override global audio settings"
msgstr "Overstyr globale lyd indstillinger"
-#: gui/launcher.cpp:234 gui/options.cpp:1046
+#: gui/launcher.cpp:239 gui/options.cpp:1115
msgid "Volume"
msgstr "Lydstyrke"
-#: gui/launcher.cpp:236 gui/options.cpp:1048
+#: gui/launcher.cpp:241 gui/options.cpp:1117
msgctxt "lowres"
msgid "Volume"
msgstr "Lydstyrke"
-#: gui/launcher.cpp:239
+#: gui/launcher.cpp:244
msgid "Override global volume settings"
msgstr "Overstyr globale lydstyrke indstillinger"
-#: gui/launcher.cpp:241
+#: gui/launcher.cpp:246
msgctxt "lowres"
msgid "Override global volume settings"
msgstr "Overstyr globale lydstyrke indstillinger"
-#: gui/launcher.cpp:248 gui/options.cpp:1056
+#: gui/launcher.cpp:254 gui/options.cpp:1125
msgid "MIDI"
msgstr "MIDI"
-#: gui/launcher.cpp:251
+#: gui/launcher.cpp:257
msgid "Override global MIDI settings"
msgstr "Overstyr globale MIDI indstillinger"
-#: gui/launcher.cpp:253
+#: gui/launcher.cpp:259
msgctxt "lowres"
msgid "Override global MIDI settings"
msgstr "Overstyr globale MIDI indstillinger"
-#: gui/launcher.cpp:263 gui/options.cpp:1062
+#: gui/launcher.cpp:268 gui/options.cpp:1131
msgid "MT-32"
msgstr "MT-32"
-#: gui/launcher.cpp:266
+#: gui/launcher.cpp:271
msgid "Override global MT-32 settings"
msgstr "Overstyr globale MT-32 indstillinger"
-#: gui/launcher.cpp:268
+#: gui/launcher.cpp:273
msgctxt "lowres"
msgid "Override global MT-32 settings"
msgstr "Overstyr globale MT-32 indstillinger"
-#: gui/launcher.cpp:279 gui/options.cpp:1069
+#: gui/launcher.cpp:282 gui/options.cpp:1138
msgid "Paths"
msgstr "Stier"
-#: gui/launcher.cpp:281 gui/options.cpp:1071
+#: gui/launcher.cpp:284 gui/options.cpp:1140
msgctxt "lowres"
msgid "Paths"
msgstr "Stier"
-#: gui/launcher.cpp:288
+#: gui/launcher.cpp:291
msgid "Game Path:"
msgstr "Spil sti:"
-#: gui/launcher.cpp:290
+#: gui/launcher.cpp:293
msgctxt "lowres"
msgid "Game Path:"
msgstr "Spil sti:"
-#: gui/launcher.cpp:295 gui/options.cpp:1091
+#: gui/launcher.cpp:298 gui/options.cpp:1164
msgid "Extra Path:"
msgstr "Ekstra sti:"
-#: gui/launcher.cpp:295 gui/launcher.cpp:297 gui/launcher.cpp:298
+#: gui/launcher.cpp:298 gui/launcher.cpp:300 gui/launcher.cpp:301
msgid "Specifies path to additional data used the game"
msgstr "Angiver sti til ekstra data der bruges i spillet"
-#: gui/launcher.cpp:297 gui/options.cpp:1093
+#: gui/launcher.cpp:300 gui/options.cpp:1166
msgctxt "lowres"
msgid "Extra Path:"
msgstr "Ekstra sti:"
-#: gui/launcher.cpp:302 gui/options.cpp:1079
+#: gui/launcher.cpp:307 gui/options.cpp:1148
msgid "Save Path:"
msgstr "Gemme sti:"
-#: gui/launcher.cpp:302 gui/launcher.cpp:304 gui/launcher.cpp:305
-#: gui/options.cpp:1079 gui/options.cpp:1081 gui/options.cpp:1082
+#: gui/launcher.cpp:307 gui/launcher.cpp:309 gui/launcher.cpp:310
+#: gui/options.cpp:1148 gui/options.cpp:1150 gui/options.cpp:1151
msgid "Specifies where your savegames are put"
msgstr "Angiver hvor dine gemmer bliver lagt"
-#: gui/launcher.cpp:304 gui/options.cpp:1081
+#: gui/launcher.cpp:309 gui/options.cpp:1150
msgctxt "lowres"
msgid "Save Path:"
msgstr "Gemme sti:"
-#: gui/launcher.cpp:321 gui/launcher.cpp:404 gui/launcher.cpp:453
-#: gui/options.cpp:1088 gui/options.cpp:1094 gui/options.cpp:1101
-#: gui/options.cpp:1202 gui/options.cpp:1208 gui/options.cpp:1214
-#: gui/options.cpp:1222 gui/options.cpp:1246 gui/options.cpp:1250
-#: gui/options.cpp:1256 gui/options.cpp:1263 gui/options.cpp:1362
+#: gui/launcher.cpp:329 gui/launcher.cpp:416 gui/launcher.cpp:469
+#: gui/launcher.cpp:523 gui/options.cpp:1159 gui/options.cpp:1167
+#: gui/options.cpp:1176 gui/options.cpp:1283 gui/options.cpp:1289
+#: gui/options.cpp:1297 gui/options.cpp:1327 gui/options.cpp:1333
+#: gui/options.cpp:1340 gui/options.cpp:1433 gui/options.cpp:1436
+#: gui/options.cpp:1448
msgctxt "path"
msgid "None"
msgstr "Ingen"
-#: gui/launcher.cpp:326 gui/launcher.cpp:408
+#: gui/launcher.cpp:334 gui/launcher.cpp:422 gui/launcher.cpp:527
+#: gui/options.cpp:1277 gui/options.cpp:1321 gui/options.cpp:1439
#: backends/platform/wii/options.cpp:56
msgid "Default"
msgstr "Standard"
-#: gui/launcher.cpp:446 gui/options.cpp:1356
+#: gui/launcher.cpp:462 gui/options.cpp:1442
msgid "Select SoundFont"
msgstr "Vælg SoundFont"
-#: gui/launcher.cpp:465 gui/launcher.cpp:612
+#: gui/launcher.cpp:481 gui/launcher.cpp:636
msgid "Select directory with game data"
msgstr "Vælg bibliotek med spil data"
-#: gui/launcher.cpp:483
+#: gui/launcher.cpp:499
msgid "Select additional game directory"
msgstr "Vælg ekstra spil bibliotek"
-#: gui/launcher.cpp:495
+#: gui/launcher.cpp:511
msgid "Select directory for saved games"
msgstr "Vælg bibliotek til spil gemmer"
-#: gui/launcher.cpp:514
+#: gui/launcher.cpp:538
msgid "This game ID is already taken. Please choose another one."
msgstr "Dette spil ID er allerede i brug. Vælg venligst et andet."
-#: gui/launcher.cpp:555 engines/dialogs.cpp:110
+#: gui/launcher.cpp:579 engines/dialogs.cpp:110
msgid "~Q~uit"
msgstr "~A~fslut"
-#: gui/launcher.cpp:555 backends/platform/sdl/macosx/appmenu_osx.mm:80
+#: gui/launcher.cpp:579 backends/platform/sdl/macosx/appmenu_osx.mm:96
msgid "Quit ScummVM"
-msgstr "Afslut ScummVM"
+msgstr "Slut ScummVM"
-#: gui/launcher.cpp:556
+#: gui/launcher.cpp:580
msgid "A~b~out..."
msgstr "~O~m..."
-#: gui/launcher.cpp:556 backends/platform/sdl/macosx/appmenu_osx.mm:61
+#: gui/launcher.cpp:580 backends/platform/sdl/macosx/appmenu_osx.mm:70
msgid "About ScummVM"
msgstr "Om ScummVM"
-#: gui/launcher.cpp:557
+#: gui/launcher.cpp:581
msgid "~O~ptions..."
msgstr "~I~ndstillinger..."
-#: gui/launcher.cpp:557
+#: gui/launcher.cpp:581
msgid "Change global ScummVM options"
msgstr "Ændre globale ScummVM indstillinger"
-#: gui/launcher.cpp:559
+#: gui/launcher.cpp:583
msgid "~S~tart"
msgstr "~S~tart"
-#: gui/launcher.cpp:559
+#: gui/launcher.cpp:583
msgid "Start selected game"
msgstr "Start det valgte spil"
-#: gui/launcher.cpp:562
+#: gui/launcher.cpp:586
msgid "~L~oad..."
msgstr "~H~ent..."
-#: gui/launcher.cpp:562
+#: gui/launcher.cpp:586
msgid "Load savegame for selected game"
msgstr "Hent gemmer for det valgte spil"
-#: gui/launcher.cpp:567 gui/launcher.cpp:1055
+#: gui/launcher.cpp:591 gui/launcher.cpp:1079
msgid "~A~dd Game..."
msgstr "~T~ilføj spil..."
-#: gui/launcher.cpp:567 gui/launcher.cpp:574
+#: gui/launcher.cpp:591 gui/launcher.cpp:598
msgid "Hold Shift for Mass Add"
msgstr "Hold Skift for at tilføje flere"
-#: gui/launcher.cpp:569
+#: gui/launcher.cpp:593
msgid "~E~dit Game..."
msgstr "~R~ediger spil..."
-#: gui/launcher.cpp:569 gui/launcher.cpp:576
+#: gui/launcher.cpp:593 gui/launcher.cpp:600
msgid "Change game options"
msgstr "Ændre spil indstillinger"
-#: gui/launcher.cpp:571
+#: gui/launcher.cpp:595
msgid "~R~emove Game"
msgstr "~F~jern spil"
-#: gui/launcher.cpp:571 gui/launcher.cpp:578
+#: gui/launcher.cpp:595 gui/launcher.cpp:602
msgid "Remove game from the list. The game data files stay intact"
msgstr "Fjerner spil fra listen. Spillets data filer forbliver uberørt"
-#: gui/launcher.cpp:574 gui/launcher.cpp:1055
+#: gui/launcher.cpp:598 gui/launcher.cpp:1079
msgctxt "lowres"
msgid "~A~dd Game..."
msgstr "~T~ilføj spil..."
-#: gui/launcher.cpp:576
+#: gui/launcher.cpp:600
msgctxt "lowres"
msgid "~E~dit Game..."
msgstr "~R~ediger spil..."
-#: gui/launcher.cpp:578
+#: gui/launcher.cpp:602
msgctxt "lowres"
msgid "~R~emove Game"
msgstr "~F~jern spil"
-#: gui/launcher.cpp:586
+#: gui/launcher.cpp:610
msgid "Search in game list"
msgstr "Søg i spil liste"
-#: gui/launcher.cpp:590 gui/launcher.cpp:1102
+#: gui/launcher.cpp:614 gui/launcher.cpp:1126
msgid "Search:"
msgstr "Søg:"
-#: gui/launcher.cpp:593 gui/options.cpp:826
-msgid "Clear value"
-msgstr "Slet værdi"
-
-#: gui/launcher.cpp:615 engines/dialogs.cpp:114 engines/mohawk/myst.cpp:255
+#: gui/launcher.cpp:639 engines/dialogs.cpp:114 engines/mohawk/myst.cpp:255
#: engines/mohawk/riven.cpp:716 engines/cruise/menu.cpp:216
msgid "Load game:"
msgstr "Indlæs spil:"
-#: gui/launcher.cpp:615 engines/dialogs.cpp:114 engines/scumm/dialogs.cpp:188
+#: gui/launcher.cpp:639 engines/dialogs.cpp:114 engines/scumm/dialogs.cpp:188
#: engines/mohawk/myst.cpp:255 engines/mohawk/riven.cpp:716
#: engines/cruise/menu.cpp:216 backends/platform/wince/CEActionsPocket.cpp:267
#: backends/platform/wince/CEActionsSmartphone.cpp:231
msgid "Load"
msgstr "Indlæs"
-#: gui/launcher.cpp:723
+#: gui/launcher.cpp:747
msgid ""
"Do you really want to run the mass game detector? This could potentially add "
"a huge number of games."
@@ -450,7 +454,7 @@ msgstr ""
"Vil du virkelig køre fler spils detektoren? Dette kunne potentielt tilføje "
"et stort antal spil."
-#: gui/launcher.cpp:724 gui/launcher.cpp:872
+#: gui/launcher.cpp:748 gui/launcher.cpp:896
#: backends/events/symbiansdl/symbiansdl-events.cpp:184
#: backends/platform/wince/CEActionsPocket.cpp:326
#: backends/platform/wince/CEActionsSmartphone.cpp:287
@@ -458,7 +462,7 @@ msgstr ""
msgid "Yes"
msgstr "Ja"
-#: gui/launcher.cpp:724 gui/launcher.cpp:872
+#: gui/launcher.cpp:748 gui/launcher.cpp:896
#: backends/events/symbiansdl/symbiansdl-events.cpp:184
#: backends/platform/wince/CEActionsPocket.cpp:326
#: backends/platform/wince/CEActionsSmartphone.cpp:287
@@ -466,37 +470,37 @@ msgstr "Ja"
msgid "No"
msgstr "Nej"
-#: gui/launcher.cpp:772
+#: gui/launcher.cpp:796
msgid "ScummVM couldn't open the specified directory!"
msgstr "ScummVM kunne ikke åbne det angivne bibliotek!"
-#: gui/launcher.cpp:784
+#: gui/launcher.cpp:808
msgid "ScummVM could not find any game in the specified directory!"
msgstr "ScummVM kunne ikke finde noget spil i det angivne bibliotek!"
-#: gui/launcher.cpp:798
+#: gui/launcher.cpp:822
msgid "Pick the game:"
msgstr "Vælg spillet:"
-#: gui/launcher.cpp:872
+#: gui/launcher.cpp:896
msgid "Do you really want to remove this game configuration?"
msgstr "Vil du virkelig fjerne denne spil konfiguration?"
-#: gui/launcher.cpp:936
+#: gui/launcher.cpp:960
msgid "This game does not support loading games from the launcher."
msgstr "Dette spil understøtter ikke hentning af spil fra spiloversigten."
-#: gui/launcher.cpp:940
+#: gui/launcher.cpp:964
msgid "ScummVM could not find any engine capable of running the selected game!"
msgstr ""
"ScummVM kunne ikke finde en motor, istand til at afvikle det valgte spil!"
-#: gui/launcher.cpp:1054
+#: gui/launcher.cpp:1078
msgctxt "lowres"
msgid "Mass Add..."
msgstr "Tilføj flere..."
-#: gui/launcher.cpp:1054
+#: gui/launcher.cpp:1078
msgid "Mass Add..."
msgstr "Tilføj flere..."
@@ -523,141 +527,141 @@ msgstr "Gennemset %d biblioteker ..."
msgid "Discovered %d new games, ignored %d previously added games ..."
msgstr "Fundet %d nye spil ..."
-#: gui/options.cpp:72
+#: gui/options.cpp:78
msgid "Never"
msgstr "Aldrig"
-#: gui/options.cpp:72
+#: gui/options.cpp:78
msgid "every 5 mins"
msgstr "hvert 5. minut"
-#: gui/options.cpp:72
+#: gui/options.cpp:78
msgid "every 10 mins"
msgstr "hvert 10. minut"
-#: gui/options.cpp:72
+#: gui/options.cpp:78
msgid "every 15 mins"
msgstr "hvert 15. minut"
-#: gui/options.cpp:72
+#: gui/options.cpp:78
msgid "every 30 mins"
msgstr "hvert 30. minut"
-#: gui/options.cpp:74
+#: gui/options.cpp:80
msgid "8 kHz"
msgstr "8 kHz"
-#: gui/options.cpp:74
+#: gui/options.cpp:80
msgid "11kHz"
msgstr "11 kHz"
-#: gui/options.cpp:74
+#: gui/options.cpp:80
msgid "22 kHz"
msgstr "22 kHz"
-#: gui/options.cpp:74
+#: gui/options.cpp:80
msgid "44 kHz"
msgstr "44 kHz"
-#: gui/options.cpp:74
+#: gui/options.cpp:80
msgid "48 kHz"
msgstr "48 kHz"
-#: gui/options.cpp:236 gui/options.cpp:464 gui/options.cpp:559
-#: gui/options.cpp:625 gui/options.cpp:825
+#: gui/options.cpp:257 gui/options.cpp:485 gui/options.cpp:586
+#: gui/options.cpp:659 gui/options.cpp:868
msgctxt "soundfont"
msgid "None"
msgstr "Ingen"
-#: gui/options.cpp:372
+#: gui/options.cpp:393
msgid "Failed to apply some of the graphic options changes:"
msgstr ""
-#: gui/options.cpp:384
+#: gui/options.cpp:405
msgid "the video mode could not be changed."
msgstr ""
-#: gui/options.cpp:390
+#: gui/options.cpp:411
msgid "the fullscreen setting could not be changed"
msgstr ""
-#: gui/options.cpp:396
+#: gui/options.cpp:417
msgid "the aspect ratio setting could not be changed"
msgstr ""
-#: gui/options.cpp:705
+#: gui/options.cpp:742
msgid "Graphics mode:"
msgstr "Grafik tilstand:"
-#: gui/options.cpp:716
+#: gui/options.cpp:756
msgid "Render mode:"
msgstr "Rendere tilstand:"
-#: gui/options.cpp:716 gui/options.cpp:717
+#: gui/options.cpp:756 gui/options.cpp:757
msgid "Special dithering modes supported by some games"
msgstr "Speciel farvereduceringstilstand understøttet a nogle spil"
-#: gui/options.cpp:726
+#: gui/options.cpp:768
#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2248
-#: backends/graphics/openglsdl/openglsdl-graphics.cpp:476
+#: backends/graphics/openglsdl/openglsdl-graphics.cpp:472
msgid "Fullscreen mode"
msgstr "Fuldskærms tilstand"
-#: gui/options.cpp:729
+#: gui/options.cpp:771
msgid "Aspect ratio correction"
msgstr "Billedformat korrektion"
-#: gui/options.cpp:729
+#: gui/options.cpp:771
msgid "Correct aspect ratio for 320x200 games"
msgstr "Korrekt billedformat til 320x200 spil"
-#: gui/options.cpp:730
+#: gui/options.cpp:772
msgid "EGA undithering"
msgstr "EGA farveforøgelse"
-#: gui/options.cpp:730
+#: gui/options.cpp:772
msgid "Enable undithering in EGA games that support it"
msgstr "Aktiver farveforøgelse i EGA spil der understøtter det"
-#: gui/options.cpp:738
+#: gui/options.cpp:780
msgid "Preferred Device:"
msgstr "Foretruk. enhed:"
-#: gui/options.cpp:738
+#: gui/options.cpp:780
msgid "Music Device:"
msgstr "Musik enhed:"
-#: gui/options.cpp:738 gui/options.cpp:740
+#: gui/options.cpp:780 gui/options.cpp:782
msgid "Specifies preferred sound device or sound card emulator"
msgstr "Angiver foretukket lyd enhed eller lydkort emulator"
-#: gui/options.cpp:738 gui/options.cpp:740 gui/options.cpp:741
+#: gui/options.cpp:780 gui/options.cpp:782 gui/options.cpp:783
msgid "Specifies output sound device or sound card emulator"
msgstr "Angiver lyd udgangsenhed eller lydkorts emulator"
-#: gui/options.cpp:740
+#: gui/options.cpp:782
msgctxt "lowres"
msgid "Preferred Dev.:"
msgstr "Foretruk. enh.:"
-#: gui/options.cpp:740
+#: gui/options.cpp:782
msgctxt "lowres"
msgid "Music Device:"
msgstr "Musik enhed:"
-#: gui/options.cpp:766
+#: gui/options.cpp:809
msgid "AdLib emulator:"
msgstr "AdLib emulator:"
-#: gui/options.cpp:766 gui/options.cpp:767
+#: gui/options.cpp:809 gui/options.cpp:810
msgid "AdLib is used for music in many games"
msgstr "AdLib bliver brugt til musik i mange spil"
-#: gui/options.cpp:777
+#: gui/options.cpp:820
msgid "Output rate:"
msgstr "Udgangsfrekvens:"
-#: gui/options.cpp:777 gui/options.cpp:778
+#: gui/options.cpp:820 gui/options.cpp:821
msgid ""
"Higher value specifies better sound quality but may be not supported by your "
"soundcard"
@@ -665,60 +669,60 @@ msgstr ""
"Højere værdi angiver bedre lyd kvalitet, men understøttes måske ikke af dit "
"lydkort"
-#: gui/options.cpp:788
+#: gui/options.cpp:831
msgid "GM Device:"
msgstr "GM enhed:"
-#: gui/options.cpp:788
+#: gui/options.cpp:831
msgid "Specifies default sound device for General MIDI output"
msgstr "Angiver standard lyd enhed for General MIDI udgang"
-#: gui/options.cpp:799
+#: gui/options.cpp:842
msgid "Don't use General MIDI music"
msgstr "Brug ikke General MIDI musik"
-#: gui/options.cpp:810 gui/options.cpp:871
+#: gui/options.cpp:853 gui/options.cpp:915
msgid "Use first available device"
msgstr "Brug første tilgængelig enhed"
-#: gui/options.cpp:822
+#: gui/options.cpp:865
msgid "SoundFont:"
msgstr "SoundFont:"
-#: gui/options.cpp:822 gui/options.cpp:824 gui/options.cpp:825
+#: gui/options.cpp:865 gui/options.cpp:867 gui/options.cpp:868
msgid "SoundFont is supported by some audio cards, Fluidsynth and Timidity"
msgstr "SoundFont er understøttet af nogle lydkort, Fluidsynth og Timidity"
-#: gui/options.cpp:824
+#: gui/options.cpp:867
msgctxt "lowres"
msgid "SoundFont:"
msgstr "SoundFont:"
-#: gui/options.cpp:829
+#: gui/options.cpp:873
msgid "Mixed AdLib/MIDI mode"
msgstr "Blandet AdLib/MIDI tilstand"
-#: gui/options.cpp:829
+#: gui/options.cpp:873
msgid "Use both MIDI and AdLib sound generation"
msgstr "Brug både MIDI og AdLib lyd generering"
-#: gui/options.cpp:832
+#: gui/options.cpp:876
msgid "MIDI gain:"
msgstr "MIDI lydstyrke:"
-#: gui/options.cpp:842
+#: gui/options.cpp:886
msgid "MT-32 Device:"
msgstr "MT-32 enhed:"
-#: gui/options.cpp:842
+#: gui/options.cpp:886
msgid "Specifies default sound device for Roland MT-32/LAPC1/CM32l/CM64 output"
msgstr "Angiver standard lyd enhed for Roland MT-32/LAPC1/CM32I/CM64 udgang"
-#: gui/options.cpp:847
+#: gui/options.cpp:891
msgid "True Roland MT-32 (disable GM emulation)"
msgstr "Ægte Roland MT-32 (undlad GM emulering)"
-#: gui/options.cpp:847 gui/options.cpp:849
+#: gui/options.cpp:891 gui/options.cpp:893
msgid ""
"Check if you want to use your real hardware Roland-compatible sound device "
"connected to your computer"
@@ -726,191 +730,191 @@ msgstr ""
"Kontroller om du vil bruge din rigtige hardware Roland-kompatible lyd enhed "
"tilsluttet til din computer"
-#: gui/options.cpp:849
+#: gui/options.cpp:893
msgctxt "lowres"
msgid "True Roland MT-32 (no GM emulation)"
msgstr "Ægte Roland MT-32 (ingen GM emulering)"
-#: gui/options.cpp:852
+#: gui/options.cpp:896
msgid "Enable Roland GS Mode"
msgstr "Aktivér Roland GS tilstand"
-#: gui/options.cpp:852
+#: gui/options.cpp:896
msgid "Turns off General MIDI mapping for games with Roland MT-32 soundtrack"
msgstr "Sluk for General MIDI kortlægning for spil med Roland MT-32 lydspor"
-#: gui/options.cpp:861
+#: gui/options.cpp:905
msgid "Don't use Roland MT-32 music"
msgstr "Brug ikke Roland MT-32 musik"
-#: gui/options.cpp:888
+#: gui/options.cpp:932
msgid "Text and Speech:"
msgstr "Tekst og tale:"
-#: gui/options.cpp:892 gui/options.cpp:902
+#: gui/options.cpp:936 gui/options.cpp:946
msgid "Speech"
msgstr "Tale"
-#: gui/options.cpp:893 gui/options.cpp:903
+#: gui/options.cpp:937 gui/options.cpp:947
msgid "Subtitles"
msgstr "Undertekster"
-#: gui/options.cpp:894
+#: gui/options.cpp:938
msgid "Both"
msgstr "Begge"
-#: gui/options.cpp:896
+#: gui/options.cpp:940
msgid "Subtitle speed:"
msgstr "Tekst hastighed:"
-#: gui/options.cpp:898
+#: gui/options.cpp:942
msgctxt "lowres"
msgid "Text and Speech:"
msgstr "Tekst og tale:"
-#: gui/options.cpp:902
+#: gui/options.cpp:946
msgid "Spch"
msgstr "Tale"
-#: gui/options.cpp:903
+#: gui/options.cpp:947
msgid "Subs"
msgstr "Tekst"
-#: gui/options.cpp:904
+#: gui/options.cpp:948
msgctxt "lowres"
msgid "Both"
msgstr "Begge"
-#: gui/options.cpp:904
+#: gui/options.cpp:948
msgid "Show subtitles and play speech"
msgstr "Vis undertekster og afspil tale"
-#: gui/options.cpp:906
+#: gui/options.cpp:950
msgctxt "lowres"
msgid "Subtitle speed:"
msgstr "Tekst hastighed:"
-#: gui/options.cpp:922
+#: gui/options.cpp:966
msgid "Music volume:"
msgstr "Musik lydstyrke:"
-#: gui/options.cpp:924
+#: gui/options.cpp:968
msgctxt "lowres"
msgid "Music volume:"
msgstr "Musik lydstyrke:"
-#: gui/options.cpp:931
+#: gui/options.cpp:975
msgid "Mute All"
msgstr "Mute alle"
-#: gui/options.cpp:934
+#: gui/options.cpp:978
msgid "SFX volume:"
msgstr "SFX lydstyrke:"
-#: gui/options.cpp:934 gui/options.cpp:936 gui/options.cpp:937
+#: gui/options.cpp:978 gui/options.cpp:980 gui/options.cpp:981
msgid "Special sound effects volume"
msgstr "Lydstyrke for specielle lydeffekter"
-#: gui/options.cpp:936
+#: gui/options.cpp:980
msgctxt "lowres"
msgid "SFX volume:"
msgstr "SFX lydstyrke:"
-#: gui/options.cpp:944
+#: gui/options.cpp:988
msgid "Speech volume:"
msgstr "Tale lydstyrke:"
-#: gui/options.cpp:946
+#: gui/options.cpp:990
msgctxt "lowres"
msgid "Speech volume:"
msgstr "Tale lydstyrke:"
-#: gui/options.cpp:1085
+#: gui/options.cpp:1156
msgid "Theme Path:"
msgstr "Tema sti:"
-#: gui/options.cpp:1087
+#: gui/options.cpp:1158
msgctxt "lowres"
msgid "Theme Path:"
msgstr "Tema sti:"
-#: gui/options.cpp:1091 gui/options.cpp:1093 gui/options.cpp:1094
+#: gui/options.cpp:1164 gui/options.cpp:1166 gui/options.cpp:1167
msgid "Specifies path to additional data used by all games or ScummVM"
msgstr "Angiver sti til ekstra data brugt af alle spil eller ScummVM"
-#: gui/options.cpp:1098
+#: gui/options.cpp:1173
msgid "Plugins Path:"
msgstr "Plugin sti:"
-#: gui/options.cpp:1100
+#: gui/options.cpp:1175
msgctxt "lowres"
msgid "Plugins Path:"
msgstr "Plugin sti:"
-#: gui/options.cpp:1109
+#: gui/options.cpp:1184
msgid "Misc"
msgstr "Andet"
-#: gui/options.cpp:1111
+#: gui/options.cpp:1186
msgctxt "lowres"
msgid "Misc"
msgstr "Andet"
-#: gui/options.cpp:1113
+#: gui/options.cpp:1188
msgid "Theme:"
msgstr "Tema:"
-#: gui/options.cpp:1117
+#: gui/options.cpp:1192
msgid "GUI Renderer:"
msgstr "GUI renderer:"
-#: gui/options.cpp:1129
+#: gui/options.cpp:1204
msgid "Autosave:"
msgstr "Auto gemme:"
-#: gui/options.cpp:1131
+#: gui/options.cpp:1206
msgctxt "lowres"
msgid "Autosave:"
msgstr "Auto gemme:"
-#: gui/options.cpp:1139
+#: gui/options.cpp:1214
msgid "Keys"
msgstr "Taster"
-#: gui/options.cpp:1146
+#: gui/options.cpp:1221
msgid "GUI Language:"
msgstr "Sprog:"
-#: gui/options.cpp:1146
+#: gui/options.cpp:1221
msgid "Language of ScummVM GUI"
msgstr "Sprog for brugerfladen i ScummVM"
-#: gui/options.cpp:1295
+#: gui/options.cpp:1372
#, fuzzy
msgid "You have to restart ScummVM before your changes will take effect."
msgstr "Du skal genstarte ScummVM for at ændringer vises."
-#: gui/options.cpp:1308
+#: gui/options.cpp:1385
msgid "Select directory for savegames"
msgstr "Vælg bibliotek til gemmer"
-#: gui/options.cpp:1315
+#: gui/options.cpp:1392
msgid "The chosen directory cannot be written to. Please select another one."
msgstr "Der kan ikke skrives til det valgte bibliotek. Vælg venligst et andet."
-#: gui/options.cpp:1324
+#: gui/options.cpp:1401
msgid "Select directory for GUI themes"
msgstr "Vælg bibliotek for GUI temaer"
-#: gui/options.cpp:1334
+#: gui/options.cpp:1411
msgid "Select directory for extra files"
msgstr "Vælg bibliotek for ekstra filer"
-#: gui/options.cpp:1345
+#: gui/options.cpp:1422
msgid "Select directory for plugins"
msgstr "Vælg bibliotek for plugins"
-#: gui/options.cpp:1389
+#: gui/options.cpp:1475
msgid ""
"The theme you selected does not support your current language. If you want "
"to use this theme you need to switch to another language first."
@@ -958,60 +962,64 @@ msgstr "Unavngivet gemmetilstand"
msgid "Select a Theme"
msgstr "Vælg et tema"
-#: gui/ThemeEngine.cpp:328
+#: gui/ThemeEngine.cpp:333
msgid "Disabled GFX"
msgstr "Deaktiveret GFX"
-#: gui/ThemeEngine.cpp:328
+#: gui/ThemeEngine.cpp:333
msgctxt "lowres"
msgid "Disabled GFX"
msgstr "Deaktiveret GFX"
-#: gui/ThemeEngine.cpp:329
+#: gui/ThemeEngine.cpp:334
msgid "Standard Renderer (16bpp)"
msgstr "Standard renderer (16bpp)"
-#: gui/ThemeEngine.cpp:329
+#: gui/ThemeEngine.cpp:334
msgid "Standard (16bpp)"
msgstr "Standard (16bpp)"
-#: gui/ThemeEngine.cpp:331
+#: gui/ThemeEngine.cpp:336
msgid "Antialiased Renderer (16bpp)"
msgstr "Antialias renderer (16bpp)"
-#: gui/ThemeEngine.cpp:331
+#: gui/ThemeEngine.cpp:336
msgid "Antialiased (16bpp)"
msgstr "Antialias (16bpp)"
+#: gui/widget.cpp:312 gui/widget.cpp:314 gui/widget.cpp:320 gui/widget.cpp:322
+msgid "Clear value"
+msgstr "Slet værdi"
+
#: base/main.cpp:203
#, c-format
msgid "Engine does not support debug level '%s'"
msgstr "Motor understøtter ikke fejlfindingsniveau '%s'"
-#: base/main.cpp:271
+#: base/main.cpp:275
msgid "Menu"
msgstr "Menu"
-#: base/main.cpp:274 backends/platform/symbian/src/SymbianActions.cpp:45
+#: base/main.cpp:278 backends/platform/symbian/src/SymbianActions.cpp:45
#: backends/platform/wince/CEActionsPocket.cpp:45
#: backends/platform/wince/CEActionsSmartphone.cpp:46
msgid "Skip"
msgstr "Spring over"
-#: base/main.cpp:277 backends/platform/symbian/src/SymbianActions.cpp:50
+#: base/main.cpp:281 backends/platform/symbian/src/SymbianActions.cpp:50
#: backends/platform/wince/CEActionsPocket.cpp:42
msgid "Pause"
msgstr "Pause"
-#: base/main.cpp:280
+#: base/main.cpp:284
msgid "Skip line"
msgstr "Spring linje over"
-#: base/main.cpp:439
+#: base/main.cpp:455
msgid "Error running game:"
msgstr "Fejl ved kørsel af spil:"
-#: base/main.cpp:463
+#: base/main.cpp:479
msgid "Could not find any engine capable of running the selected game"
msgstr "Kunne ikke finde nogen motor istand til at afvikle det valgte spil"
@@ -1086,25 +1094,6 @@ msgstr ""
msgid "Unknown error"
msgstr "Ukendt fejl"
-#. I18N: Hercules is graphics card name
-#: common/util.cpp:275
-msgid "Hercules Green"
-msgstr "Hercules grøn"
-
-#: common/util.cpp:276
-msgid "Hercules Amber"
-msgstr "Hercules brun"
-
-#: common/util.cpp:283
-msgctxt "lowres"
-msgid "Hercules Green"
-msgstr "Hercules grøn"
-
-#: common/util.cpp:284
-msgctxt "lowres"
-msgid "Hercules Amber"
-msgstr "Hercules brun"
-
#: engines/advancedDetector.cpp:296
#, c-format
msgid "The game in '%s' seems to be unknown."
@@ -1152,12 +1141,12 @@ msgid "~R~eturn to Launcher"
msgstr "~R~etur til oversigt"
#: engines/dialogs.cpp:116 engines/cruise/menu.cpp:214
-#: engines/sci/engine/kfile.cpp:578
+#: engines/sci/engine/kfile.cpp:566
msgid "Save game:"
msgstr "Gemmer:"
#: engines/dialogs.cpp:116 engines/scumm/dialogs.cpp:187
-#: engines/cruise/menu.cpp:214 engines/sci/engine/kfile.cpp:578
+#: engines/cruise/menu.cpp:214 engines/sci/engine/kfile.cpp:566
#: backends/platform/symbian/src/SymbianActions.cpp:44
#: backends/platform/wince/CEActionsPocket.cpp:43
#: backends/platform/wince/CEActionsPocket.cpp:267
@@ -1173,39 +1162,46 @@ msgid ""
"further assistance."
msgstr ""
-#: engines/dialogs.cpp:316 engines/mohawk/dialogs.cpp:109
+#: engines/dialogs.cpp:243
+#, c-format
+msgid ""
+"Gamestate save failed (%s)! Please consult the README for basic information, "
+"and for instructions on how to obtain further assistance."
+msgstr ""
+
+#: engines/dialogs.cpp:321 engines/mohawk/dialogs.cpp:109
#: engines/mohawk/dialogs.cpp:174
msgid "~O~K"
msgstr "~O~K"
-#: engines/dialogs.cpp:317 engines/mohawk/dialogs.cpp:110
+#: engines/dialogs.cpp:322 engines/mohawk/dialogs.cpp:110
#: engines/mohawk/dialogs.cpp:175
msgid "~C~ancel"
msgstr "~F~ortryd"
-#: engines/dialogs.cpp:320
+#: engines/dialogs.cpp:325
msgid "~K~eys"
msgstr "~T~aster"
-#: engines/engine.cpp:233
+#: engines/engine.cpp:235
msgid "Could not initialize color format."
msgstr ""
-#: engines/engine.cpp:241
+#: engines/engine.cpp:243
#, fuzzy
msgid "Could not switch to video mode: '"
msgstr "Aktuel videotilstand:"
-#: engines/engine.cpp:250
+#: engines/engine.cpp:252
#, fuzzy
msgid "Could not apply aspect ratio setting."
msgstr "Skift billedformat korrektion"
-#: engines/engine.cpp:255
+#: engines/engine.cpp:257
msgid "Could not apply fullscreen setting."
msgstr ""
-#: engines/engine.cpp:355
+#: engines/engine.cpp:357
msgid ""
"You appear to be playing this game directly\n"
"from the CD. This is known to cause problems,\n"
@@ -1214,7 +1210,7 @@ msgid ""
"See the README file for details."
msgstr ""
-#: engines/engine.cpp:366
+#: engines/engine.cpp:368
msgid ""
"This game has audio tracks in its disk. These\n"
"tracks need to be ripped from the disk using\n"
@@ -1223,14 +1219,21 @@ msgid ""
"See the README file for details."
msgstr ""
-#: engines/engine.cpp:433
+#: engines/engine.cpp:426
+#, c-format
+msgid ""
+"Gamestate load failed (%s)! Please consult the README for basic information, "
+"and for instructions on how to obtain further assistance."
+msgstr ""
+
+#: engines/engine.cpp:439
msgid ""
"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."
msgstr ""
-#: engines/engine.cpp:436
+#: engines/engine.cpp:442
msgid "Start anyway"
msgstr ""
@@ -1276,7 +1279,7 @@ msgstr ""
#: backends/platform/symbian/src/SymbianActions.cpp:52
#: backends/platform/wince/CEActionsPocket.cpp:44
#: backends/platform/wince/CEActionsSmartphone.cpp:52
-#: backends/events/default/default-events.cpp:244
+#: backends/events/default/default-events.cpp:213
msgid "Quit"
msgstr "Afslut"
@@ -1355,6 +1358,27 @@ msgctxt "lowres"
msgid "Speech & Subs"
msgstr "Tale"
+#: engines/scumm/dialogs.cpp:653
+msgid "Select a Proficiency Level."
+msgstr ""
+
+#: engines/scumm/dialogs.cpp:655
+msgid "Refer to your Loom(TM) manual for help."
+msgstr ""
+
+#: engines/scumm/dialogs.cpp:658
+#, fuzzy
+msgid "Standard"
+msgstr "Standard (16bpp)"
+
+#: engines/scumm/dialogs.cpp:659
+msgid "Practice"
+msgstr ""
+
+#: engines/scumm/dialogs.cpp:660
+msgid "Expert"
+msgstr ""
+
#: engines/scumm/help.cpp:73
msgid "Common keyboard commands:"
msgstr "Almindelige tastatur kommandoer:"
@@ -1869,14 +1893,14 @@ msgstr "Flyv til højre"
msgid "Fly to lower right"
msgstr "Flyv nederst til højre"
-#: engines/scumm/scumm.cpp:1774
+#: engines/scumm/scumm.cpp:1773
#, c-format
msgid ""
"Native MIDI support requires the Roland Upgrade from LucasArts,\n"
"but %s is missing. Using AdLib instead."
msgstr ""
-#: engines/scumm/scumm.cpp:2264 engines/agos/saveload.cpp:189
+#: engines/scumm/scumm.cpp:2271 engines/agos/saveload.cpp:189
#, c-format
msgid ""
"Failed to save game state to file:\n"
@@ -1887,7 +1911,7 @@ msgstr ""
"\n"
"%s"
-#: engines/scumm/scumm.cpp:2271 engines/agos/saveload.cpp:154
+#: engines/scumm/scumm.cpp:2278 engines/agos/saveload.cpp:154
#, c-format
msgid ""
"Failed to load game state from file:\n"
@@ -1898,7 +1922,7 @@ msgstr ""
"\n"
"%s"
-#: engines/scumm/scumm.cpp:2283 engines/agos/saveload.cpp:197
+#: engines/scumm/scumm.cpp:2290 engines/agos/saveload.cpp:197
#, c-format
msgid ""
"Successfully saved game state in file:\n"
@@ -1909,7 +1933,7 @@ msgstr ""
"\n"
"%s"
-#: engines/scumm/scumm.cpp:2498
+#: engines/scumm/scumm.cpp:2505
msgid ""
"Usually, Maniac Mansion would start now. But ScummVM doesn't do that yet. To "
"play it, go to 'Add Game' in the ScummVM start menu and select the 'Maniac' "
@@ -1943,11 +1967,11 @@ msgstr "ScummVM Hovedmenu"
msgid "~W~ater Effect Enabled"
msgstr "~V~andeffekter aktiveret"
-#: engines/sci/engine/kfile.cpp:685
+#: engines/sci/engine/kfile.cpp:673
msgid "Restore game:"
msgstr "Gendan spil:"
-#: engines/sci/engine/kfile.cpp:685
+#: engines/sci/engine/kfile.cpp:673
msgid "Restore"
msgstr "Gendan"
@@ -1957,7 +1981,7 @@ msgid "Cutscene file '%s' not found!"
msgstr ""
#: engines/gob/inter_playtoons.cpp:256 engines/gob/inter_v2.cpp:1283
-#: engines/tinsel/saveload.cpp:482
+#: engines/tinsel/saveload.cpp:502
#, fuzzy
msgid "Failed to load game state from file."
msgstr ""
@@ -1965,7 +1989,7 @@ msgstr ""
"\n"
"%s"
-#: engines/gob/inter_v2.cpp:1353 engines/tinsel/saveload.cpp:560
+#: engines/gob/inter_v2.cpp:1353 engines/tinsel/saveload.cpp:515
#, fuzzy
msgid "Failed to save game state to file."
msgstr ""
@@ -1989,6 +2013,60 @@ msgstr ""
"\n"
"%s"
+#: engines/kyra/lol.cpp:478
+msgid "Attack 1"
+msgstr ""
+
+#: engines/kyra/lol.cpp:479
+msgid "Attack 2"
+msgstr ""
+
+#: engines/kyra/lol.cpp:480
+msgid "Attack 3"
+msgstr ""
+
+#: engines/kyra/lol.cpp:481
+msgid "Move Forward"
+msgstr ""
+
+#: engines/kyra/lol.cpp:482
+msgid "Move Back"
+msgstr ""
+
+#: engines/kyra/lol.cpp:483
+msgid "Slide Left"
+msgstr ""
+
+#: engines/kyra/lol.cpp:484
+#, fuzzy
+msgid "Slide Right"
+msgstr "Højre"
+
+#: engines/kyra/lol.cpp:485
+#, fuzzy
+msgid "Turn Left"
+msgstr "Sluk"
+
+#: engines/kyra/lol.cpp:486
+#, fuzzy
+msgid "Turn Right"
+msgstr "Pil til højre"
+
+#: engines/kyra/lol.cpp:487
+#, fuzzy
+msgid "Rest"
+msgstr "Gendan"
+
+#: engines/kyra/lol.cpp:488
+#, fuzzy
+msgid "Options"
+msgstr "~I~ndstillinger"
+
+#: engines/kyra/lol.cpp:489
+#, fuzzy
+msgid "Choose Spell"
+msgstr "Vælg"
+
#: engines/kyra/sound_midi.cpp:475
msgid ""
"You appear to be using a General MIDI device,\n"
@@ -1998,11 +2076,6 @@ msgid ""
"that a few tracks will not be correctly played."
msgstr ""
-#: engines/m4/m4_menus.cpp:138
-#, fuzzy
-msgid "Save game failed!"
-msgstr "Gemmer:"
-
#: engines/sky/compact.cpp:130
msgid ""
"Unable to find \"sky.cpt\" file!\n"
@@ -2015,15 +2088,20 @@ msgid ""
"Please (re)download it from www.scummvm.org"
msgstr ""
-#: engines/sword1/animation.cpp:344 engines/sword2/animation.cpp:379
+#: engines/sword1/animation.cpp:539
+#, c-format
+msgid "PSX stream cutscene '%s' cannot be played in paletted mode"
+msgstr ""
+
+#: engines/sword1/animation.cpp:560 engines/sword2/animation.cpp:455
msgid "DXA cutscenes found but ScummVM has been built without zlib support"
msgstr ""
-#: engines/sword1/animation.cpp:354 engines/sword2/animation.cpp:389
+#: engines/sword1/animation.cpp:570 engines/sword2/animation.cpp:465
msgid "MPEG2 cutscenes are no longer supported"
msgstr ""
-#: engines/sword1/animation.cpp:359 engines/sword2/animation.cpp:397
+#: engines/sword1/animation.cpp:576 engines/sword2/animation.cpp:473
#, c-format
msgid "Cutscene '%s' not found"
msgstr ""
@@ -2058,6 +2136,11 @@ msgstr ""
msgid "This is the end of the Broken Sword 1 Demo"
msgstr ""
+#: engines/sword2/animation.cpp:435
+msgid ""
+"PSX cutscenes found but ScummVM has been built without RGB color support"
+msgstr ""
+
#: engines/parallaction/saveload.cpp:133
#, c-format
msgid ""
@@ -2105,33 +2188,33 @@ msgstr "MAME OPL emulator"
msgid "DOSBox OPL emulator"
msgstr "DOSBox OPL emulator"
-#: audio/mididrv.cpp:205
+#: audio/mididrv.cpp:209
#, c-format
msgid ""
"The selected audio device '%s' was not found (e.g. might be turned off or "
"disconnected)."
msgstr ""
-#: audio/mididrv.cpp:205 audio/mididrv.cpp:217 audio/mididrv.cpp:253
-#: audio/mididrv.cpp:268
+#: audio/mididrv.cpp:209 audio/mididrv.cpp:221 audio/mididrv.cpp:257
+#: audio/mididrv.cpp:272
msgid "Attempting to fall back to the next available device..."
msgstr ""
-#: audio/mididrv.cpp:217
+#: audio/mididrv.cpp:221
#, c-format
msgid ""
"The selected audio device '%s' cannot be used. See log file for more "
"information."
msgstr ""
-#: audio/mididrv.cpp:253
+#: audio/mididrv.cpp:257
#, c-format
msgid ""
"The preferred audio device '%s' was not found (e.g. might be turned off or "
"disconnected)."
msgstr ""
-#: audio/mididrv.cpp:268
+#: audio/mididrv.cpp:272
#, c-format
msgid ""
"The preferred audio device '%s' cannot be used. See log file for more "
@@ -2146,7 +2229,7 @@ msgstr "Ingen musik"
msgid "Amiga Audio Emulator"
msgstr "Amiga lyd emulator"
-#: audio/softsynth/adlib.cpp:1594
+#: audio/softsynth/adlib.cpp:1593
msgid "AdLib Emulator"
msgstr "AdLib emulator"
@@ -2158,12 +2241,12 @@ msgstr "Apple II GS emulator (IKKE IMPLEMENTERET)"
msgid "C64 Audio Emulator"
msgstr "C64 lyd emulator"
-#: audio/softsynth/mt32.cpp:329
+#: audio/softsynth/mt32.cpp:293
#, fuzzy
msgid "Initializing MT-32 Emulator"
msgstr "Initialisere MT-32 emulator"
-#: audio/softsynth/mt32.cpp:543
+#: audio/softsynth/mt32.cpp:512
msgid "MT-32 Emulator"
msgstr "MT-32 emulator"
@@ -2179,15 +2262,24 @@ msgstr "IBM PCjr emulator"
msgid "Keymap:"
msgstr "Tasteoversigt:"
-#: backends/keymapper/remap-dialog.cpp:64
+#: backends/keymapper/remap-dialog.cpp:66
+#, fuzzy
+msgid " (Effective)"
+msgstr " (Aktiv)"
+
+#: backends/keymapper/remap-dialog.cpp:106
msgid " (Active)"
msgstr " (Aktiv)"
-#: backends/keymapper/remap-dialog.cpp:98
+#: backends/keymapper/remap-dialog.cpp:106
+msgid " (Blocked)"
+msgstr ""
+
+#: backends/keymapper/remap-dialog.cpp:119
msgid " (Global)"
msgstr " (Global)"
-#: backends/keymapper/remap-dialog.cpp:108
+#: backends/keymapper/remap-dialog.cpp:127
msgid " (Game)"
msgstr " (Spil)"
@@ -2267,46 +2359,69 @@ msgstr "Høj lydkvalitet (langsommere) (genstart)"
msgid "Disable power off"
msgstr "Deaktiver slukning"
-#: backends/platform/iphone/osys_events.cpp:338
+#: backends/platform/iphone/osys_events.cpp:301
#, fuzzy
msgid "Mouse-click-and-drag mode enabled."
msgstr "Pegeplade tilstand aktiveret."
-#: backends/platform/iphone/osys_events.cpp:340
+#: backends/platform/iphone/osys_events.cpp:303
#, fuzzy
msgid "Mouse-click-and-drag mode disabled."
msgstr "Pegeplade tilstand deaktiveret."
-#: backends/platform/iphone/osys_events.cpp:351
+#: backends/platform/iphone/osys_events.cpp:314
msgid "Touchpad mode enabled."
msgstr "Pegeplade tilstand aktiveret."
-#: backends/platform/iphone/osys_events.cpp:353
+#: backends/platform/iphone/osys_events.cpp:316
msgid "Touchpad mode disabled."
msgstr "Pegeplade tilstand deaktiveret."
-#: backends/platform/sdl/macosx/appmenu_osx.mm:67
+#: backends/platform/maemo/maemo.cpp:205
+msgid "Click Mode"
+msgstr ""
+
+#: backends/platform/maemo/maemo.cpp:211
+#: backends/platform/symbian/src/SymbianActions.cpp:42
+#: backends/platform/wince/CEActionsPocket.cpp:60
+#: backends/platform/wince/CEActionsSmartphone.cpp:43
+#: backends/platform/bada/form.cpp:281
+msgid "Left Click"
+msgstr "Venstre klik"
+
+#: backends/platform/maemo/maemo.cpp:214
+#, fuzzy
+msgid "Middle Click"
+msgstr "Midterste højre punkt"
+
+#: backends/platform/maemo/maemo.cpp:217
+#: backends/platform/symbian/src/SymbianActions.cpp:43
+#: backends/platform/wince/CEActionsSmartphone.cpp:44
+#: backends/platform/bada/form.cpp:273
+msgid "Right Click"
+msgstr "Højre klik"
+
+#: backends/platform/sdl/macosx/appmenu_osx.mm:78
#, fuzzy
msgid "Hide ScummVM"
-msgstr "Afslut ScummVM"
+msgstr "Skjul ScummVM"
-#: backends/platform/sdl/macosx/appmenu_osx.mm:70
+#: backends/platform/sdl/macosx/appmenu_osx.mm:83
msgid "Hide Others"
-msgstr ""
+msgstr "Skjul andre"
-#: backends/platform/sdl/macosx/appmenu_osx.mm:74
+#: backends/platform/sdl/macosx/appmenu_osx.mm:88
msgid "Show All"
-msgstr ""
+msgstr "Vis alle"
-#: backends/platform/sdl/macosx/appmenu_osx.mm:92
-#: backends/platform/sdl/macosx/appmenu_osx.mm:99
-#, fuzzy
+#: backends/platform/sdl/macosx/appmenu_osx.mm:110
+#: backends/platform/sdl/macosx/appmenu_osx.mm:121
msgid "Window"
-msgstr "Windows MIDI"
+msgstr "Vindue"
-#: backends/platform/sdl/macosx/appmenu_osx.mm:95
+#: backends/platform/sdl/macosx/appmenu_osx.mm:115
msgid "Minimize"
-msgstr ""
+msgstr "Minimer"
#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:45
msgid "Normal (no scaling)"
@@ -2318,13 +2433,13 @@ msgid "Normal (no scaling)"
msgstr "Normal (ingen skalering)"
#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2147
-#: backends/graphics/openglsdl/openglsdl-graphics.cpp:537
+#: backends/graphics/openglsdl/openglsdl-graphics.cpp:533
#, fuzzy
msgid "Enabled aspect ratio correction"
msgstr "Skift billedformat korrektion"
#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2153
-#: backends/graphics/openglsdl/openglsdl-graphics.cpp:542
+#: backends/graphics/openglsdl/openglsdl-graphics.cpp:538
#, fuzzy
msgid "Disabled aspect ratio correction"
msgstr "Skift billedformat korrektion"
@@ -2335,7 +2450,7 @@ msgid "Active graphics filter:"
msgstr "Skift mellem grafik filtre"
#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2250
-#: backends/graphics/openglsdl/openglsdl-graphics.cpp:481
+#: backends/graphics/openglsdl/openglsdl-graphics.cpp:477
#, fuzzy
msgid "Windowed mode"
msgstr "Rendere tilstand:"
@@ -2361,11 +2476,11 @@ msgstr "Aktuel videotilstand:"
msgid "Current scale"
msgstr ""
-#: backends/graphics/openglsdl/openglsdl-graphics.cpp:562
+#: backends/graphics/openglsdl/openglsdl-graphics.cpp:558
msgid "Active filter mode: Linear"
msgstr ""
-#: backends/graphics/openglsdl/openglsdl-graphics.cpp:564
+#: backends/graphics/openglsdl/openglsdl-graphics.cpp:560
msgid "Active filter mode: Nearest"
msgstr ""
@@ -2389,19 +2504,6 @@ msgstr "Venstre"
msgid "Right"
msgstr "Højre"
-#: backends/platform/symbian/src/SymbianActions.cpp:42
-#: backends/platform/wince/CEActionsPocket.cpp:60
-#: backends/platform/wince/CEActionsSmartphone.cpp:43
-#: backends/platform/bada/form.cpp:281
-msgid "Left Click"
-msgstr "Venstre klik"
-
-#: backends/platform/symbian/src/SymbianActions.cpp:43
-#: backends/platform/wince/CEActionsSmartphone.cpp:44
-#: backends/platform/bada/form.cpp:273
-msgid "Right Click"
-msgstr "Højre klik"
-
#: backends/platform/symbian/src/SymbianActions.cpp:46
#: backends/platform/wince/CEActionsSmartphone.cpp:47
msgid "Zone"
@@ -2693,17 +2795,17 @@ msgstr ""
"Glem ikke at tildele en tast til 'Skjul værktøjslinje' handling for at se "
"hele oversigten"
-#: backends/events/default/default-events.cpp:222
+#: backends/events/default/default-events.cpp:191
#, fuzzy
msgid "Do you really want to return to the Launcher?"
msgstr "Vil du virkelig slette denne gemmer?"
-#: backends/events/default/default-events.cpp:222
+#: backends/events/default/default-events.cpp:191
#, fuzzy
msgid "Launcher"
msgstr "Slag"
-#: backends/events/default/default-events.cpp:244
+#: backends/events/default/default-events.cpp:213
#, fuzzy
msgid "Do you really want to quit?"
msgstr "Vil du afslutte?"
@@ -2776,14 +2878,32 @@ msgstr "Vis tastatur"
msgid "Control Mouse"
msgstr ""
-#: backends/events/maemosdl/maemosdl-events.cpp:121
+#: backends/events/maemosdl/maemosdl-events.cpp:192
msgid "Clicking Enabled"
msgstr ""
-#: backends/events/maemosdl/maemosdl-events.cpp:121
+#: backends/events/maemosdl/maemosdl-events.cpp:192
msgid "Clicking Disabled"
msgstr ""
+#~ msgid "Hercules Green"
+#~ msgstr "Hercules grøn"
+
+#~ msgid "Hercules Amber"
+#~ msgstr "Hercules brun"
+
+#~ msgctxt "lowres"
+#~ msgid "Hercules Green"
+#~ msgstr "Hercules grøn"
+
+#~ msgctxt "lowres"
+#~ msgid "Hercules Amber"
+#~ msgstr "Hercules brun"
+
+#, fuzzy
+#~ msgid "Save game failed!"
+#~ msgstr "Gemmer:"
+
#~ msgctxt "lowres"
#~ msgid "Add Game..."
#~ msgstr "Tilføj spil..."
diff --git a/po/de_DE.po b/po/de_DE.po
index 8abe17df4a..fd60d11d4a 100644
--- a/po/de_DE.po
+++ b/po/de_DE.po
@@ -1,21 +1,21 @@
-# German translation for ScummVM.
-# Copyright (C) 2010-2011 ScummVM Team
-# This file is distributed under the same license as the ScummVM package.
-# Simon Sawatzki <SimSaw@gmx.de>, Lothar Serra Mari <Lothar@Windowsbase.de>, 2011.
-#
+# German translation for ScummVM.
+# Copyright (C) 2010-2012 ScummVM Team
+# This file is distributed under the same license as the ScummVM package.
+# Simon Sawatzki <SimSaw@gmx.de>, Lothar Serra Mari <Lothar@Windowsbase.de>, 2012.
+#
msgid ""
msgstr ""
"Project-Id-Version: ScummVM 1.4.0git\n"
"Report-Msgid-Bugs-To: scummvm-devel@lists.sf.net\n"
-"POT-Creation-Date: 2011-10-19 13:42+0100\n"
-"PO-Revision-Date: 2011-10-15 18:15+0100\n"
+"POT-Creation-Date: 2012-03-07 22:09+0000\n"
+"PO-Revision-Date: 2012-01-29 21:11+0100\n"
"Last-Translator: Simon Sawatzki <SimSaw@gmx.de>\n"
"Language-Team: Simon Sawatzki <SimSaw@gmx.de> (Lead), Lothar Serra Mari "
"<Lothar@Windowsbase.de> (Contributor)\n"
-"Language: Deutsch\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=iso-8859-1\n"
"Content-Transfer-Encoding: 8bit\n"
+"Language: Deutsch\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
#: gui/about.cpp:91
@@ -45,13 +45,13 @@ msgid "Go up"
msgstr "Pfad hoch"
#: gui/browser.cpp:69 gui/chooser.cpp:45 gui/KeysDialog.cpp:43
-#: gui/launcher.cpp:312 gui/massadd.cpp:94 gui/options.cpp:1178
+#: gui/launcher.cpp:320 gui/massadd.cpp:94 gui/options.cpp:1253
#: gui/saveload.cpp:63 gui/saveload.cpp:155 gui/themebrowser.cpp:54
-#: engines/engine.cpp:436 engines/scumm/dialogs.cpp:190
+#: engines/engine.cpp:442 engines/scumm/dialogs.cpp:190
#: engines/sword1/control.cpp:865 engines/parallaction/saveload.cpp:281
#: backends/platform/wii/options.cpp:48
-#: backends/events/default/default-events.cpp:222
-#: backends/events/default/default-events.cpp:244
+#: backends/events/default/default-events.cpp:191
+#: backends/events/default/default-events.cpp:213
msgid "Cancel"
msgstr "Abbrechen"
@@ -59,25 +59,30 @@ msgstr "Abbrechen"
msgid "Choose"
msgstr "Auswählen"
-#: gui/gui-manager.cpp:116 engines/scumm/help.cpp:125
+#: gui/gui-manager.cpp:115 engines/scumm/help.cpp:125
#: engines/scumm/help.cpp:140 engines/scumm/help.cpp:165
#: engines/scumm/help.cpp:191 engines/scumm/help.cpp:209
#: backends/keymapper/remap-dialog.cpp:52
msgid "Close"
msgstr "Schließen"
-#: gui/gui-manager.cpp:119
+#: gui/gui-manager.cpp:118
msgid "Mouse click"
msgstr "Mausklick"
-#: gui/gui-manager.cpp:122 base/main.cpp:283
+#: gui/gui-manager.cpp:122 base/main.cpp:288
msgid "Display keyboard"
msgstr "Tastatur anzeigen"
-#: gui/gui-manager.cpp:125 base/main.cpp:286
+#: gui/gui-manager.cpp:126 base/main.cpp:292
msgid "Remap keys"
msgstr "Tasten neu zuweisen"
+#: gui/gui-manager.cpp:129 base/main.cpp:295
+#, fuzzy
+msgid "Toggle FullScreen"
+msgstr "Vollbild-/Fenster-Modus"
+
#: gui/KeysDialog.h:36 gui/KeysDialog.cpp:145
msgid "Choose an action to map"
msgstr "Eine Aktion zum Zuweisen auswählen"
@@ -86,16 +91,17 @@ msgstr "Eine Aktion zum Zuweisen auswählen"
msgid "Map"
msgstr "Zuweisen"
-#: gui/KeysDialog.cpp:42 gui/launcher.cpp:313 gui/launcher.cpp:936
-#: gui/launcher.cpp:940 gui/massadd.cpp:91 gui/options.cpp:1179
-#: engines/engine.cpp:359 engines/engine.cpp:370 engines/scumm/dialogs.cpp:192
-#: engines/scumm/scumm.cpp:1776 engines/agos/animation.cpp:551
+#: gui/KeysDialog.cpp:42 gui/launcher.cpp:321 gui/launcher.cpp:960
+#: gui/launcher.cpp:964 gui/massadd.cpp:91 gui/options.cpp:1254
+#: engines/engine.cpp:361 engines/engine.cpp:372 engines/scumm/dialogs.cpp:192
+#: engines/scumm/scumm.cpp:1775 engines/agos/animation.cpp:551
#: engines/groovie/script.cpp:420 engines/sky/compact.cpp:131
-#: engines/sky/compact.cpp:141 engines/sword1/animation.cpp:344
-#: engines/sword1/animation.cpp:354 engines/sword1/animation.cpp:360
-#: engines/sword1/control.cpp:865 engines/sword1/logic.cpp:1633
-#: engines/sword2/animation.cpp:379 engines/sword2/animation.cpp:389
-#: engines/sword2/animation.cpp:398 engines/parallaction/saveload.cpp:281
+#: engines/sky/compact.cpp:141 engines/sword1/animation.cpp:539
+#: engines/sword1/animation.cpp:560 engines/sword1/animation.cpp:570
+#: engines/sword1/animation.cpp:577 engines/sword1/control.cpp:865
+#: engines/sword1/logic.cpp:1633 engines/sword2/animation.cpp:435
+#: engines/sword2/animation.cpp:455 engines/sword2/animation.cpp:465
+#: engines/sword2/animation.cpp:474 engines/parallaction/saveload.cpp:281
#: backends/platform/wii/options.cpp:47
#: backends/platform/wince/CELauncherDialog.cpp:54
msgid "OK"
@@ -123,15 +129,15 @@ msgstr "Bitte eine Aktion auswählen"
msgid "Press the key to associate"
msgstr "Taste drücken, um sie zuzuweisen"
-#: gui/launcher.cpp:165
+#: gui/launcher.cpp:170
msgid "Game"
msgstr "Spiel"
-#: gui/launcher.cpp:169
+#: gui/launcher.cpp:174
msgid "ID:"
msgstr "Kennung:"
-#: gui/launcher.cpp:169 gui/launcher.cpp:171 gui/launcher.cpp:172
+#: gui/launcher.cpp:174 gui/launcher.cpp:176 gui/launcher.cpp:177
msgid ""
"Short game identifier used for referring to savegames and running the game "
"from the command line"
@@ -139,29 +145,29 @@ msgstr ""
"Kurzer Spielname, um die Spielstände zuzuordnen und das Spiel von der "
"Kommandozeile aus starten zu können"
-#: gui/launcher.cpp:171
+#: gui/launcher.cpp:176
msgctxt "lowres"
msgid "ID:"
msgstr "ID:"
-#: gui/launcher.cpp:176
+#: gui/launcher.cpp:181
msgid "Name:"
msgstr "Name:"
-#: gui/launcher.cpp:176 gui/launcher.cpp:178 gui/launcher.cpp:179
+#: gui/launcher.cpp:181 gui/launcher.cpp:183 gui/launcher.cpp:184
msgid "Full title of the game"
msgstr "Voller Name des Spiels"
-#: gui/launcher.cpp:178
+#: gui/launcher.cpp:183
msgctxt "lowres"
msgid "Name:"
msgstr "Name:"
-#: gui/launcher.cpp:182
+#: gui/launcher.cpp:187
msgid "Language:"
msgstr "Sprache:"
-#: gui/launcher.cpp:182 gui/launcher.cpp:183
+#: gui/launcher.cpp:187 gui/launcher.cpp:188
msgid ""
"Language of the game. This will not turn your Spanish game version into "
"English"
@@ -169,284 +175,282 @@ msgstr ""
"Sprache des Spiels. Diese Funktion wird nicht eine spanische Version des "
"Spiels in eine deutsche verwandeln."
-#: gui/launcher.cpp:184 gui/launcher.cpp:198 gui/options.cpp:74
-#: gui/options.cpp:708 gui/options.cpp:718 gui/options.cpp:1149
+#: gui/launcher.cpp:189 gui/launcher.cpp:203 gui/options.cpp:80
+#: gui/options.cpp:745 gui/options.cpp:758 gui/options.cpp:1224
#: audio/null.cpp:40
msgid "<default>"
msgstr "<Standard>"
-#: gui/launcher.cpp:194
+#: gui/launcher.cpp:199
msgid "Platform:"
msgstr "Plattform:"
-#: gui/launcher.cpp:194 gui/launcher.cpp:196 gui/launcher.cpp:197
+#: gui/launcher.cpp:199 gui/launcher.cpp:201 gui/launcher.cpp:202
msgid "Platform the game was originally designed for"
msgstr "Plattform, für die das Spiel ursprünglich erstellt wurde"
-#: gui/launcher.cpp:196
+#: gui/launcher.cpp:201
msgctxt "lowres"
msgid "Platform:"
msgstr "Plattform:"
-#: gui/launcher.cpp:208 gui/options.cpp:1018 gui/options.cpp:1035
+#: gui/launcher.cpp:213 gui/options.cpp:1087 gui/options.cpp:1104
msgid "Graphics"
msgstr "Grafik"
-#: gui/launcher.cpp:208 gui/options.cpp:1018 gui/options.cpp:1035
+#: gui/launcher.cpp:213 gui/options.cpp:1087 gui/options.cpp:1104
msgid "GFX"
msgstr "GFX"
-#: gui/launcher.cpp:211
+#: gui/launcher.cpp:216
msgid "Override global graphic settings"
msgstr "Globale Grafikeinstellungen übergehen"
-#: gui/launcher.cpp:213
+#: gui/launcher.cpp:218
msgctxt "lowres"
msgid "Override global graphic settings"
msgstr "Globale Grafikeinstellungen übergehen"
-#: gui/launcher.cpp:220 gui/options.cpp:1041
+#: gui/launcher.cpp:225 gui/options.cpp:1110
msgid "Audio"
msgstr "Audio"
-#: gui/launcher.cpp:223
+#: gui/launcher.cpp:228
msgid "Override global audio settings"
msgstr "Globale Audioeinstellungen übergehen"
-#: gui/launcher.cpp:225
+#: gui/launcher.cpp:230
msgctxt "lowres"
msgid "Override global audio settings"
msgstr "Globale Audioeinstellungen übergehen"
-#: gui/launcher.cpp:234 gui/options.cpp:1046
+#: gui/launcher.cpp:239 gui/options.cpp:1115
msgid "Volume"
msgstr "Lautstärke"
-#: gui/launcher.cpp:236 gui/options.cpp:1048
+#: gui/launcher.cpp:241 gui/options.cpp:1117
msgctxt "lowres"
msgid "Volume"
msgstr "Lautst."
-#: gui/launcher.cpp:239
+#: gui/launcher.cpp:244
msgid "Override global volume settings"
msgstr "Globale Lautstärke-Einstellungen übergehen"
-#: gui/launcher.cpp:241
+#: gui/launcher.cpp:246
msgctxt "lowres"
msgid "Override global volume settings"
msgstr "Globale Lautstärkeeinstellungen übergehen"
-#: gui/launcher.cpp:248 gui/options.cpp:1056
+#: gui/launcher.cpp:254 gui/options.cpp:1125
msgid "MIDI"
msgstr "MIDI"
-#: gui/launcher.cpp:251
+#: gui/launcher.cpp:257
msgid "Override global MIDI settings"
msgstr "Globale MIDI-Einstellungen übergehen"
-#: gui/launcher.cpp:253
+#: gui/launcher.cpp:259
msgctxt "lowres"
msgid "Override global MIDI settings"
msgstr "Globale MIDI-Einstellungen übergehen"
-#: gui/launcher.cpp:263 gui/options.cpp:1062
+#: gui/launcher.cpp:268 gui/options.cpp:1131
msgid "MT-32"
msgstr "MT-32"
-#: gui/launcher.cpp:266
+#: gui/launcher.cpp:271
msgid "Override global MT-32 settings"
msgstr "Globale MT-32-Einstellungen übergehen"
-#: gui/launcher.cpp:268
+#: gui/launcher.cpp:273
msgctxt "lowres"
msgid "Override global MT-32 settings"
msgstr "Globale MT-32-Einstellungen übergehen"
-#: gui/launcher.cpp:279 gui/options.cpp:1069
+#: gui/launcher.cpp:282 gui/options.cpp:1138
msgid "Paths"
msgstr "Pfade"
-#: gui/launcher.cpp:281 gui/options.cpp:1071
+#: gui/launcher.cpp:284 gui/options.cpp:1140
msgctxt "lowres"
msgid "Paths"
msgstr "Pfade"
-#: gui/launcher.cpp:288
+#: gui/launcher.cpp:291
msgid "Game Path:"
msgstr "Spielpfad:"
-#: gui/launcher.cpp:290
+#: gui/launcher.cpp:293
msgctxt "lowres"
msgid "Game Path:"
msgstr "Spielpfad:"
-#: gui/launcher.cpp:295 gui/options.cpp:1091
+#: gui/launcher.cpp:298 gui/options.cpp:1164
msgid "Extra Path:"
msgstr "Extrapfad:"
-#: gui/launcher.cpp:295 gui/launcher.cpp:297 gui/launcher.cpp:298
+#: gui/launcher.cpp:298 gui/launcher.cpp:300 gui/launcher.cpp:301
msgid "Specifies path to additional data used the game"
msgstr "Legt das Verzeichnis für zusätzliche Spieldateien fest."
-#: gui/launcher.cpp:297 gui/options.cpp:1093
+#: gui/launcher.cpp:300 gui/options.cpp:1166
msgctxt "lowres"
msgid "Extra Path:"
msgstr "Extrapfad:"
-#: gui/launcher.cpp:302 gui/options.cpp:1079
+#: gui/launcher.cpp:307 gui/options.cpp:1148
msgid "Save Path:"
msgstr "Spielstände:"
-#: gui/launcher.cpp:302 gui/launcher.cpp:304 gui/launcher.cpp:305
-#: gui/options.cpp:1079 gui/options.cpp:1081 gui/options.cpp:1082
+#: gui/launcher.cpp:307 gui/launcher.cpp:309 gui/launcher.cpp:310
+#: gui/options.cpp:1148 gui/options.cpp:1150 gui/options.cpp:1151
msgid "Specifies where your savegames are put"
msgstr "Legt fest, wo die Spielstände abgelegt werden."
-#: gui/launcher.cpp:304 gui/options.cpp:1081
+#: gui/launcher.cpp:309 gui/options.cpp:1150
msgctxt "lowres"
msgid "Save Path:"
msgstr "Speichern:"
-#: gui/launcher.cpp:321 gui/launcher.cpp:404 gui/launcher.cpp:453
-#: gui/options.cpp:1088 gui/options.cpp:1094 gui/options.cpp:1101
-#: gui/options.cpp:1202 gui/options.cpp:1208 gui/options.cpp:1214
-#: gui/options.cpp:1222 gui/options.cpp:1246 gui/options.cpp:1250
-#: gui/options.cpp:1256 gui/options.cpp:1263 gui/options.cpp:1362
+#: gui/launcher.cpp:329 gui/launcher.cpp:416 gui/launcher.cpp:469
+#: gui/launcher.cpp:523 gui/options.cpp:1159 gui/options.cpp:1167
+#: gui/options.cpp:1176 gui/options.cpp:1283 gui/options.cpp:1289
+#: gui/options.cpp:1297 gui/options.cpp:1327 gui/options.cpp:1333
+#: gui/options.cpp:1340 gui/options.cpp:1433 gui/options.cpp:1436
+#: gui/options.cpp:1448
msgctxt "path"
msgid "None"
msgstr "Keiner"
-#: gui/launcher.cpp:326 gui/launcher.cpp:408
+#: gui/launcher.cpp:334 gui/launcher.cpp:422 gui/launcher.cpp:527
+#: gui/options.cpp:1277 gui/options.cpp:1321 gui/options.cpp:1439
#: backends/platform/wii/options.cpp:56
msgid "Default"
msgstr "Standard"
-#: gui/launcher.cpp:446 gui/options.cpp:1356
+#: gui/launcher.cpp:462 gui/options.cpp:1442
msgid "Select SoundFont"
msgstr "SoundFont auswählen"
-#: gui/launcher.cpp:465 gui/launcher.cpp:612
+#: gui/launcher.cpp:481 gui/launcher.cpp:636
msgid "Select directory with game data"
msgstr "Verzeichnis mit Spieldateien auswählen"
-#: gui/launcher.cpp:483
+#: gui/launcher.cpp:499
msgid "Select additional game directory"
msgstr "Verzeichnis mit zusätzlichen Dateien auswählen"
-#: gui/launcher.cpp:495
+#: gui/launcher.cpp:511
msgid "Select directory for saved games"
msgstr "Verzeichnis für Spielstände auswählen"
-#: gui/launcher.cpp:514
+#: gui/launcher.cpp:538
msgid "This game ID is already taken. Please choose another one."
msgstr "Diese Spielkennung ist schon vergeben. Bitte eine andere wählen."
-#: gui/launcher.cpp:555 engines/dialogs.cpp:110
+#: gui/launcher.cpp:579 engines/dialogs.cpp:110
msgid "~Q~uit"
msgstr "~B~eenden"
-#: gui/launcher.cpp:555 backends/platform/sdl/macosx/appmenu_osx.mm:80
+#: gui/launcher.cpp:579 backends/platform/sdl/macosx/appmenu_osx.mm:96
msgid "Quit ScummVM"
msgstr "ScummVM beenden"
-#: gui/launcher.cpp:556
+#: gui/launcher.cpp:580
msgid "A~b~out..."
msgstr "Übe~r~"
-#: gui/launcher.cpp:556 backends/platform/sdl/macosx/appmenu_osx.mm:61
+#: gui/launcher.cpp:580 backends/platform/sdl/macosx/appmenu_osx.mm:70
msgid "About ScummVM"
msgstr "Über ScummVM"
-#: gui/launcher.cpp:557
+#: gui/launcher.cpp:581
msgid "~O~ptions..."
msgstr "~O~ptionen"
-#: gui/launcher.cpp:557
+#: gui/launcher.cpp:581
msgid "Change global ScummVM options"
msgstr "Globale ScummVM-Einstellungen bearbeiten"
-#: gui/launcher.cpp:559
+#: gui/launcher.cpp:583
msgid "~S~tart"
msgstr "~S~tarten"
-#: gui/launcher.cpp:559
+#: gui/launcher.cpp:583
msgid "Start selected game"
msgstr "Ausgewähltes Spiel starten"
-#: gui/launcher.cpp:562
+#: gui/launcher.cpp:586
msgid "~L~oad..."
msgstr "~L~aden..."
-#: gui/launcher.cpp:562
+#: gui/launcher.cpp:586
msgid "Load savegame for selected game"
msgstr "Spielstand für ausgewähltes Spiel laden"
-#: gui/launcher.cpp:567 gui/launcher.cpp:1055
+#: gui/launcher.cpp:591 gui/launcher.cpp:1079
msgid "~A~dd Game..."
msgstr "Spiel ~h~inzufügen"
-#: gui/launcher.cpp:567 gui/launcher.cpp:574
+#: gui/launcher.cpp:591 gui/launcher.cpp:598
msgid "Hold Shift for Mass Add"
msgstr ""
"Umschalttaste (Shift) gedrückt halten, um Verzeichnisse nach Spielen zu "
"durchsuchen"
-#: gui/launcher.cpp:569
+#: gui/launcher.cpp:593
msgid "~E~dit Game..."
msgstr "Spielo~p~tionen"
-#: gui/launcher.cpp:569 gui/launcher.cpp:576
+#: gui/launcher.cpp:593 gui/launcher.cpp:600
msgid "Change game options"
msgstr "Spieloptionen ändern"
-#: gui/launcher.cpp:571
+#: gui/launcher.cpp:595
msgid "~R~emove Game"
msgstr "Spiel ~e~ntfernen"
-#: gui/launcher.cpp:571 gui/launcher.cpp:578
+#: gui/launcher.cpp:595 gui/launcher.cpp:602
msgid "Remove game from the list. The game data files stay intact"
msgstr "Spiel aus der Liste entfernen. Die Spieldateien bleiben erhalten."
-#: gui/launcher.cpp:574 gui/launcher.cpp:1055
+#: gui/launcher.cpp:598 gui/launcher.cpp:1079
msgctxt "lowres"
msgid "~A~dd Game..."
msgstr "~H~inzufügen"
-#: gui/launcher.cpp:576
+#: gui/launcher.cpp:600
msgctxt "lowres"
msgid "~E~dit Game..."
msgstr "Spielo~p~tion"
-#: gui/launcher.cpp:578
+#: gui/launcher.cpp:602
msgctxt "lowres"
msgid "~R~emove Game"
msgstr "~E~ntfernen"
-#: gui/launcher.cpp:586
+#: gui/launcher.cpp:610
msgid "Search in game list"
msgstr "In Spieleliste suchen"
-#: gui/launcher.cpp:590 gui/launcher.cpp:1102
+#: gui/launcher.cpp:614 gui/launcher.cpp:1126
msgid "Search:"
msgstr "Suchen:"
-#: gui/launcher.cpp:593 gui/options.cpp:826
-msgid "Clear value"
-msgstr "Wert löschen"
-
-#: gui/launcher.cpp:615 engines/dialogs.cpp:114 engines/mohawk/myst.cpp:255
+#: gui/launcher.cpp:639 engines/dialogs.cpp:114 engines/mohawk/myst.cpp:255
#: engines/mohawk/riven.cpp:716 engines/cruise/menu.cpp:216
msgid "Load game:"
msgstr "Spiel laden:"
-#: gui/launcher.cpp:615 engines/dialogs.cpp:114 engines/scumm/dialogs.cpp:188
+#: gui/launcher.cpp:639 engines/dialogs.cpp:114 engines/scumm/dialogs.cpp:188
#: engines/mohawk/myst.cpp:255 engines/mohawk/riven.cpp:716
#: engines/cruise/menu.cpp:216 backends/platform/wince/CEActionsPocket.cpp:267
#: backends/platform/wince/CEActionsSmartphone.cpp:231
msgid "Load"
msgstr "Laden"
-#: gui/launcher.cpp:723
+#: gui/launcher.cpp:747
msgid ""
"Do you really want to run the mass game detector? This could potentially add "
"a huge number of games."
@@ -454,7 +458,7 @@ msgstr ""
"Möchten Sie wirklich den PC nach Spielen durchsuchen? Möglicherweise wird "
"dabei eine größere Menge an Spielen hinzugefügt."
-#: gui/launcher.cpp:724 gui/launcher.cpp:872
+#: gui/launcher.cpp:748 gui/launcher.cpp:896
#: backends/events/symbiansdl/symbiansdl-events.cpp:184
#: backends/platform/wince/CEActionsPocket.cpp:326
#: backends/platform/wince/CEActionsSmartphone.cpp:287
@@ -462,7 +466,7 @@ msgstr ""
msgid "Yes"
msgstr "Ja"
-#: gui/launcher.cpp:724 gui/launcher.cpp:872
+#: gui/launcher.cpp:748 gui/launcher.cpp:896
#: backends/events/symbiansdl/symbiansdl-events.cpp:184
#: backends/platform/wince/CEActionsPocket.cpp:326
#: backends/platform/wince/CEActionsSmartphone.cpp:287
@@ -470,37 +474,37 @@ msgstr "Ja"
msgid "No"
msgstr "Nein"
-#: gui/launcher.cpp:772
+#: gui/launcher.cpp:796
msgid "ScummVM couldn't open the specified directory!"
msgstr "ScummVM konnte das gewählte Verzeichnis nicht öffnen!"
-#: gui/launcher.cpp:784
+#: gui/launcher.cpp:808
msgid "ScummVM could not find any game in the specified directory!"
msgstr "ScummVM konnte im gewählten Verzeichnis kein Spiel finden!"
-#: gui/launcher.cpp:798
+#: gui/launcher.cpp:822
msgid "Pick the game:"
msgstr "Spiel auswählen:"
-#: gui/launcher.cpp:872
+#: gui/launcher.cpp:896
msgid "Do you really want to remove this game configuration?"
msgstr "Möchten Sie wirklich diese Spielkonfiguration entfernen?"
-#: gui/launcher.cpp:936
+#: gui/launcher.cpp:960
msgid "This game does not support loading games from the launcher."
msgstr ""
"Für dieses Spiel wird das Laden aus der Spieleliste heraus nicht unterstützt."
-#: gui/launcher.cpp:940
+#: gui/launcher.cpp:964
msgid "ScummVM could not find any engine capable of running the selected game!"
msgstr "ScummVM konnte keine Engine finden, um das Spiel zu starten!"
-#: gui/launcher.cpp:1054
+#: gui/launcher.cpp:1078
msgctxt "lowres"
msgid "Mass Add..."
msgstr "Durchsuchen"
-#: gui/launcher.cpp:1054
+#: gui/launcher.cpp:1078
msgid "Mass Add..."
msgstr "Durchsuchen"
@@ -527,146 +531,146 @@ msgstr "%d Ordner durchsucht..."
msgid "Discovered %d new games, ignored %d previously added games ..."
msgstr "%d neue Spiele gefunden, %d bereits hinzugefügte Spiele ignoriert..."
-#: gui/options.cpp:72
+#: gui/options.cpp:78
msgid "Never"
msgstr "Niemals"
-#: gui/options.cpp:72
+#: gui/options.cpp:78
msgid "every 5 mins"
msgstr "alle 5 Minuten"
-#: gui/options.cpp:72
+#: gui/options.cpp:78
msgid "every 10 mins"
msgstr "alle 10 Minuten"
-#: gui/options.cpp:72
+#: gui/options.cpp:78
msgid "every 15 mins"
msgstr "alle 15 Minuten"
-#: gui/options.cpp:72
+#: gui/options.cpp:78
msgid "every 30 mins"
msgstr "alle 30 Minuten"
-#: gui/options.cpp:74
+#: gui/options.cpp:80
msgid "8 kHz"
msgstr "8 kHz"
-#: gui/options.cpp:74
+#: gui/options.cpp:80
msgid "11kHz"
msgstr "11 kHz"
-#: gui/options.cpp:74
+#: gui/options.cpp:80
msgid "22 kHz"
msgstr "22 kHz"
-#: gui/options.cpp:74
+#: gui/options.cpp:80
msgid "44 kHz"
msgstr "44 kHz"
-#: gui/options.cpp:74
+#: gui/options.cpp:80
msgid "48 kHz"
msgstr "48 kHz"
-#: gui/options.cpp:236 gui/options.cpp:464 gui/options.cpp:559
-#: gui/options.cpp:625 gui/options.cpp:825
+#: gui/options.cpp:257 gui/options.cpp:485 gui/options.cpp:586
+#: gui/options.cpp:659 gui/options.cpp:868
msgctxt "soundfont"
msgid "None"
msgstr "-"
-#: gui/options.cpp:372
+#: gui/options.cpp:393
msgid "Failed to apply some of the graphic options changes:"
msgstr "Fehler bei einigen Änderungen in Grafikoptionen:"
-#: gui/options.cpp:384
+#: gui/options.cpp:405
msgid "the video mode could not be changed."
msgstr "Grafikmodus konnte nicht geändert werden."
-#: gui/options.cpp:390
+#: gui/options.cpp:411
msgid "the fullscreen setting could not be changed"
msgstr "Vollbildeinstellung konnte nicht geändert werden."
-#: gui/options.cpp:396
+#: gui/options.cpp:417
msgid "the aspect ratio setting could not be changed"
msgstr ""
"Einstellung für Seitenverhältniskorrektur konnte nicht geändert werden."
-#: gui/options.cpp:705
+#: gui/options.cpp:742
msgid "Graphics mode:"
msgstr "Grafikmodus:"
-#: gui/options.cpp:716
+#: gui/options.cpp:756
msgid "Render mode:"
msgstr "Render-Modus:"
-#: gui/options.cpp:716 gui/options.cpp:717
+#: gui/options.cpp:756 gui/options.cpp:757
msgid "Special dithering modes supported by some games"
msgstr ""
"Spezielle Farbmischungsmethoden werden von manchen Spielen unterstützt."
-#: gui/options.cpp:726
+#: gui/options.cpp:768
#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2248
-#: backends/graphics/openglsdl/openglsdl-graphics.cpp:476
+#: backends/graphics/openglsdl/openglsdl-graphics.cpp:472
msgid "Fullscreen mode"
msgstr "Vollbildmodus"
-#: gui/options.cpp:729
+#: gui/options.cpp:771
msgid "Aspect ratio correction"
msgstr "Seitenverhältnis korrigieren"
-#: gui/options.cpp:729
+#: gui/options.cpp:771
msgid "Correct aspect ratio for 320x200 games"
msgstr "Seitenverhältnis für Spiele mit der Auflösung 320x200 korrigieren"
-#: gui/options.cpp:730
+#: gui/options.cpp:772
msgid "EGA undithering"
msgstr "Antifehlerdiffusion für EGA"
-#: gui/options.cpp:730
+#: gui/options.cpp:772
msgid "Enable undithering in EGA games that support it"
msgstr ""
"Aktiviert die Aufhebung der Fehlerdiffusion in EGA-Spielen, die dies "
"unterstützen."
-#: gui/options.cpp:738
+#: gui/options.cpp:780
msgid "Preferred Device:"
msgstr "Standard-Gerät:"
-#: gui/options.cpp:738
+#: gui/options.cpp:780
msgid "Music Device:"
msgstr "Musikgerät:"
-#: gui/options.cpp:738 gui/options.cpp:740
+#: gui/options.cpp:780 gui/options.cpp:782
msgid "Specifies preferred sound device or sound card emulator"
msgstr ""
"Legt das bevorzugte Tonwiedergabe-Gerät oder den Soundkarten-Emulator fest."
-#: gui/options.cpp:738 gui/options.cpp:740 gui/options.cpp:741
+#: gui/options.cpp:780 gui/options.cpp:782 gui/options.cpp:783
msgid "Specifies output sound device or sound card emulator"
msgstr "Legt das Musikwiedergabe-Gerät oder den Soundkarten-Emulator fest."
-#: gui/options.cpp:740
+#: gui/options.cpp:782
msgctxt "lowres"
msgid "Preferred Dev.:"
msgstr "Standard-Gerät:"
-#: gui/options.cpp:740
+#: gui/options.cpp:782
msgctxt "lowres"
msgid "Music Device:"
msgstr "Musikgerät:"
-#: gui/options.cpp:766
+#: gui/options.cpp:809
msgid "AdLib emulator:"
msgstr "AdLib-Emulator"
-#: gui/options.cpp:766 gui/options.cpp:767
+#: gui/options.cpp:809 gui/options.cpp:810
msgid "AdLib is used for music in many games"
msgstr "AdLib wird für die Musik in vielen Spielen verwendet."
-#: gui/options.cpp:777
+#: gui/options.cpp:820
msgid "Output rate:"
msgstr "Ausgabefrequenz:"
-#: gui/options.cpp:777 gui/options.cpp:778
+#: gui/options.cpp:820 gui/options.cpp:821
msgid ""
"Higher value specifies better sound quality but may be not supported by your "
"soundcard"
@@ -674,64 +678,64 @@ msgstr ""
"Höhere Werte bewirken eine bessere Soundqualität, werden aber möglicherweise "
"nicht von jeder Soundkarte unterstützt."
-#: gui/options.cpp:788
+#: gui/options.cpp:831
msgid "GM Device:"
msgstr "GM-Gerät:"
-#: gui/options.cpp:788
+#: gui/options.cpp:831
msgid "Specifies default sound device for General MIDI output"
msgstr ""
"Legt das standardmäßige Musikwiedergabe-Gerät für General-MIDI-Ausgabe fest."
-#: gui/options.cpp:799
+#: gui/options.cpp:842
msgid "Don't use General MIDI music"
msgstr "Keine General-MIDI-Musik"
-#: gui/options.cpp:810 gui/options.cpp:871
+#: gui/options.cpp:853 gui/options.cpp:915
msgid "Use first available device"
msgstr "Erstes verfügbares Gerät"
-#: gui/options.cpp:822
+#: gui/options.cpp:865
msgid "SoundFont:"
msgstr "SoundFont:"
-#: gui/options.cpp:822 gui/options.cpp:824 gui/options.cpp:825
+#: gui/options.cpp:865 gui/options.cpp:867 gui/options.cpp:868
msgid "SoundFont is supported by some audio cards, Fluidsynth and Timidity"
msgstr ""
"SoundFont wird von einigen Soundkarten, Fluidsynth und Timidity unterstützt."
-#: gui/options.cpp:824
+#: gui/options.cpp:867
msgctxt "lowres"
msgid "SoundFont:"
msgstr "SoundFont:"
-#: gui/options.cpp:829
+#: gui/options.cpp:873
msgid "Mixed AdLib/MIDI mode"
msgstr "AdLib-/MIDI-Modus"
-#: gui/options.cpp:829
+#: gui/options.cpp:873
msgid "Use both MIDI and AdLib sound generation"
msgstr "Benutzt MIDI und AdLib zur Sounderzeugung."
-#: gui/options.cpp:832
+#: gui/options.cpp:876
msgid "MIDI gain:"
msgstr "MIDI-Lautstärke:"
-#: gui/options.cpp:842
+#: gui/options.cpp:886
msgid "MT-32 Device:"
msgstr "MT-32-Gerät:"
-#: gui/options.cpp:842
+#: gui/options.cpp:886
msgid "Specifies default sound device for Roland MT-32/LAPC1/CM32l/CM64 output"
msgstr ""
"Legt das standardmäßige Tonwiedergabe-Gerät für die Ausgabe von Roland MT-32/"
"LAPC1/CM32l/CM64 fest."
-#: gui/options.cpp:847
+#: gui/options.cpp:891
msgid "True Roland MT-32 (disable GM emulation)"
msgstr "Echte Roland-MT-32-Emulation (GM-Emulation deaktiviert)"
-#: gui/options.cpp:847 gui/options.cpp:849
+#: gui/options.cpp:891 gui/options.cpp:893
msgid ""
"Check if you want to use your real hardware Roland-compatible sound device "
"connected to your computer"
@@ -739,197 +743,197 @@ msgstr ""
"Wählen Sie dies aus, wenn Sie Ihre echte Hardware, die mit einer Roland-"
"kompatiblen Soundkarte verbunden ist, verwenden möchten."
-#: gui/options.cpp:849
+#: gui/options.cpp:893
msgctxt "lowres"
msgid "True Roland MT-32 (no GM emulation)"
msgstr "Echte Roland-MT-32-Emulation (kein GM)"
-#: gui/options.cpp:852
+#: gui/options.cpp:896
msgid "Enable Roland GS Mode"
msgstr "Roland-GS-Modus"
-#: gui/options.cpp:852
+#: gui/options.cpp:896
msgid "Turns off General MIDI mapping for games with Roland MT-32 soundtrack"
msgstr ""
"Schaltet die General-MIDI-Zuweisung für Spiele mit Roland-MT-32-Audiospur "
"aus."
-#: gui/options.cpp:861
+#: gui/options.cpp:905
msgid "Don't use Roland MT-32 music"
msgstr "Keine Roland-MT-32-Musik"
-#: gui/options.cpp:888
+#: gui/options.cpp:932
msgid "Text and Speech:"
msgstr "Sprache und Text:"
-#: gui/options.cpp:892 gui/options.cpp:902
+#: gui/options.cpp:936 gui/options.cpp:946
msgid "Speech"
msgstr "Sprache"
-#: gui/options.cpp:893 gui/options.cpp:903
+#: gui/options.cpp:937 gui/options.cpp:947
msgid "Subtitles"
msgstr "Untertitel"
-#: gui/options.cpp:894
+#: gui/options.cpp:938
msgid "Both"
msgstr "Beides"
-#: gui/options.cpp:896
+#: gui/options.cpp:940
msgid "Subtitle speed:"
msgstr "Untertitel-Tempo:"
-#: gui/options.cpp:898
+#: gui/options.cpp:942
msgctxt "lowres"
msgid "Text and Speech:"
msgstr "Sprache + Text:"
-#: gui/options.cpp:902
+#: gui/options.cpp:946
msgid "Spch"
msgstr "Spr."
-#: gui/options.cpp:903
+#: gui/options.cpp:947
msgid "Subs"
msgstr "TXT"
-#: gui/options.cpp:904
+#: gui/options.cpp:948
msgctxt "lowres"
msgid "Both"
msgstr "S+T"
-#: gui/options.cpp:904
+#: gui/options.cpp:948
msgid "Show subtitles and play speech"
msgstr "Untertitel anzeigen und Sprachausgabe aktivieren"
-#: gui/options.cpp:906
+#: gui/options.cpp:950
msgctxt "lowres"
msgid "Subtitle speed:"
msgstr "Text-Tempo:"
-#: gui/options.cpp:922
+#: gui/options.cpp:966
msgid "Music volume:"
msgstr "Musiklautstärke:"
-#: gui/options.cpp:924
+#: gui/options.cpp:968
msgctxt "lowres"
msgid "Music volume:"
msgstr "Musiklautstärke:"
-#: gui/options.cpp:931
+#: gui/options.cpp:975
msgid "Mute All"
msgstr "Alles aus"
-#: gui/options.cpp:934
+#: gui/options.cpp:978
msgid "SFX volume:"
msgstr "Effektlautstärke:"
-#: gui/options.cpp:934 gui/options.cpp:936 gui/options.cpp:937
+#: gui/options.cpp:978 gui/options.cpp:980 gui/options.cpp:981
msgid "Special sound effects volume"
msgstr "Lautstärke spezieller Soundeffekte"
-#: gui/options.cpp:936
+#: gui/options.cpp:980
msgctxt "lowres"
msgid "SFX volume:"
msgstr "Effektlautst.:"
-#: gui/options.cpp:944
+#: gui/options.cpp:988
msgid "Speech volume:"
msgstr "Sprachlautstärke:"
-#: gui/options.cpp:946
+#: gui/options.cpp:990
msgctxt "lowres"
msgid "Speech volume:"
msgstr "Sprachlautst.:"
-#: gui/options.cpp:1085
+#: gui/options.cpp:1156
msgid "Theme Path:"
msgstr "Themenpfad:"
-#: gui/options.cpp:1087
+#: gui/options.cpp:1158
msgctxt "lowres"
msgid "Theme Path:"
msgstr "Themenpfad:"
-#: gui/options.cpp:1091 gui/options.cpp:1093 gui/options.cpp:1094
+#: gui/options.cpp:1164 gui/options.cpp:1166 gui/options.cpp:1167
msgid "Specifies path to additional data used by all games or ScummVM"
msgstr ""
"Legt das Verzeichnis für zusätzliche Spieldateien für alle Spiele in ScummVM "
"fest."
-#: gui/options.cpp:1098
+#: gui/options.cpp:1173
msgid "Plugins Path:"
msgstr "Plugin-Pfad:"
-#: gui/options.cpp:1100
+#: gui/options.cpp:1175
msgctxt "lowres"
msgid "Plugins Path:"
msgstr "Plugin-Pfad:"
-#: gui/options.cpp:1109
+#: gui/options.cpp:1184
msgid "Misc"
msgstr "Sonstiges"
-#: gui/options.cpp:1111
+#: gui/options.cpp:1186
msgctxt "lowres"
msgid "Misc"
msgstr "Andere"
-#: gui/options.cpp:1113
+#: gui/options.cpp:1188
msgid "Theme:"
msgstr "Thema:"
-#: gui/options.cpp:1117
+#: gui/options.cpp:1192
msgid "GUI Renderer:"
msgstr "GUI-Renderer:"
-#: gui/options.cpp:1129
+#: gui/options.cpp:1204
msgid "Autosave:"
msgstr "Autom. Speichern:"
-#: gui/options.cpp:1131
+#: gui/options.cpp:1206
msgctxt "lowres"
msgid "Autosave:"
msgstr "Speich.(auto)"
-#: gui/options.cpp:1139
+#: gui/options.cpp:1214
msgid "Keys"
msgstr "Tasten"
-#: gui/options.cpp:1146
+#: gui/options.cpp:1221
msgid "GUI Language:"
msgstr "Sprache:"
-#: gui/options.cpp:1146
+#: gui/options.cpp:1221
msgid "Language of ScummVM GUI"
msgstr "Sprache der ScummVM-Oberfläche"
-#: gui/options.cpp:1295
+#: gui/options.cpp:1372
msgid "You have to restart ScummVM before your changes will take effect."
msgstr "Sie müssen ScummVM neu starten, damit die Änderungen wirksam werden."
-#: gui/options.cpp:1308
+#: gui/options.cpp:1385
msgid "Select directory for savegames"
msgstr "Verzeichnis für Spielstände auswählen"
-#: gui/options.cpp:1315
+#: gui/options.cpp:1392
msgid "The chosen directory cannot be written to. Please select another one."
msgstr ""
"In das gewählte Verzeichnis kann nicht geschrieben werden. Bitte ein anderes "
"auswählen."
-#: gui/options.cpp:1324
+#: gui/options.cpp:1401
msgid "Select directory for GUI themes"
msgstr "Verzeichnis für Oberflächen-Themen"
-#: gui/options.cpp:1334
+#: gui/options.cpp:1411
msgid "Select directory for extra files"
msgstr "Verzeichnis für zusätzliche Dateien auswählen"
-#: gui/options.cpp:1345
+#: gui/options.cpp:1422
msgid "Select directory for plugins"
msgstr "Verzeichnis für Erweiterungen auswählen"
-# Nicht übersetzen, da diese Nachricht nur für nicht-lateinische Sprachen relevant ist.
-#: gui/options.cpp:1389
+# Nicht übersetzen, da diese Nachricht nur für nicht-lateinische Sprachen relevant ist.
+#: gui/options.cpp:1475
msgid ""
"The theme you selected does not support your current language. If you want "
"to use this theme you need to switch to another language first."
@@ -975,60 +979,64 @@ msgstr "Unbenannt"
msgid "Select a Theme"
msgstr "Thema auswählen"
-#: gui/ThemeEngine.cpp:328
+#: gui/ThemeEngine.cpp:333
msgid "Disabled GFX"
msgstr "GFX ausgeschaltet"
-#: gui/ThemeEngine.cpp:328
+#: gui/ThemeEngine.cpp:333
msgctxt "lowres"
msgid "Disabled GFX"
msgstr "GFX ausgeschaltet"
-#: gui/ThemeEngine.cpp:329
+#: gui/ThemeEngine.cpp:334
msgid "Standard Renderer (16bpp)"
msgstr "Standard-Renderer (16bpp)"
-#: gui/ThemeEngine.cpp:329
+#: gui/ThemeEngine.cpp:334
msgid "Standard (16bpp)"
msgstr "Standard (16bpp)"
-#: gui/ThemeEngine.cpp:331
+#: gui/ThemeEngine.cpp:336
msgid "Antialiased Renderer (16bpp)"
msgstr "Kantenglättung (16bpp)"
-#: gui/ThemeEngine.cpp:331
+#: gui/ThemeEngine.cpp:336
msgid "Antialiased (16bpp)"
msgstr "Kantenglättung (16bpp)"
+#: gui/widget.cpp:312 gui/widget.cpp:314 gui/widget.cpp:320 gui/widget.cpp:322
+msgid "Clear value"
+msgstr "Wert löschen"
+
#: base/main.cpp:203
#, c-format
msgid "Engine does not support debug level '%s'"
msgstr "Engine unterstützt den Debug-Level \"%s\" nicht."
-#: base/main.cpp:271
+#: base/main.cpp:275
msgid "Menu"
msgstr "Menü"
-#: base/main.cpp:274 backends/platform/symbian/src/SymbianActions.cpp:45
+#: base/main.cpp:278 backends/platform/symbian/src/SymbianActions.cpp:45
#: backends/platform/wince/CEActionsPocket.cpp:45
#: backends/platform/wince/CEActionsSmartphone.cpp:46
msgid "Skip"
msgstr "Überspringen"
-#: base/main.cpp:277 backends/platform/symbian/src/SymbianActions.cpp:50
+#: base/main.cpp:281 backends/platform/symbian/src/SymbianActions.cpp:50
#: backends/platform/wince/CEActionsPocket.cpp:42
msgid "Pause"
msgstr "Pause"
-#: base/main.cpp:280
+#: base/main.cpp:284
msgid "Skip line"
msgstr "Zeile überspringen"
-#: base/main.cpp:439
+#: base/main.cpp:455
msgid "Error running game:"
msgstr "Fehler beim Ausführen des Spiels:"
-#: base/main.cpp:463
+#: base/main.cpp:479
msgid "Could not find any engine capable of running the selected game"
msgstr "Konnte keine Spiel-Engine finden, die dieses Spiel starten kann."
@@ -1096,25 +1104,6 @@ msgstr "Abbruch durch Benutzer"
msgid "Unknown error"
msgstr "Unbekannter Fehler"
-#. I18N: Hercules is graphics card name
-#: common/util.cpp:275
-msgid "Hercules Green"
-msgstr "Hercules-Grün"
-
-#: common/util.cpp:276
-msgid "Hercules Amber"
-msgstr "Hercules-Bernsteingelb"
-
-#: common/util.cpp:283
-msgctxt "lowres"
-msgid "Hercules Green"
-msgstr "Hercules-Grün"
-
-#: common/util.cpp:284
-msgctxt "lowres"
-msgid "Hercules Amber"
-msgstr "Hercules-Gelb"
-
#: engines/advancedDetector.cpp:296
#, c-format
msgid "The game in '%s' seems to be unknown."
@@ -1166,12 +1155,12 @@ msgid "~R~eturn to Launcher"
msgstr "Zur Spiele~l~iste"
#: engines/dialogs.cpp:116 engines/cruise/menu.cpp:214
-#: engines/sci/engine/kfile.cpp:578
+#: engines/sci/engine/kfile.cpp:566
msgid "Save game:"
msgstr "Speichern:"
#: engines/dialogs.cpp:116 engines/scumm/dialogs.cpp:187
-#: engines/cruise/menu.cpp:214 engines/sci/engine/kfile.cpp:578
+#: engines/cruise/menu.cpp:214 engines/sci/engine/kfile.cpp:566
#: backends/platform/symbian/src/SymbianActions.cpp:44
#: backends/platform/wince/CEActionsPocket.cpp:43
#: backends/platform/wince/CEActionsPocket.cpp:267
@@ -1190,37 +1179,47 @@ msgstr ""
"Datei für grundlegende Informationen und Anweisungen dazu, wie man an "
"weitere Hilfe gelangt."
-#: engines/dialogs.cpp:316 engines/mohawk/dialogs.cpp:109
+#: engines/dialogs.cpp:243
+#, fuzzy, c-format
+msgid ""
+"Gamestate save failed (%s)! Please consult the README for basic information, "
+"and for instructions on how to obtain further assistance."
+msgstr ""
+"Leider bietet diese Engine keine Spielhilfe. Bitte lesen Sie die Liesmich-"
+"Datei für grundlegende Informationen und Anweisungen dazu, wie man an "
+"weitere Hilfe gelangt."
+
+#: engines/dialogs.cpp:321 engines/mohawk/dialogs.cpp:109
#: engines/mohawk/dialogs.cpp:174
msgid "~O~K"
msgstr "~O~K"
-#: engines/dialogs.cpp:317 engines/mohawk/dialogs.cpp:110
+#: engines/dialogs.cpp:322 engines/mohawk/dialogs.cpp:110
#: engines/mohawk/dialogs.cpp:175
msgid "~C~ancel"
msgstr "~A~bbrechen"
-#: engines/dialogs.cpp:320
+#: engines/dialogs.cpp:325
msgid "~K~eys"
msgstr "~T~asten"
-#: engines/engine.cpp:233
+#: engines/engine.cpp:235
msgid "Could not initialize color format."
msgstr "Konnte Farbenformat nicht initialisieren."
-#: engines/engine.cpp:241
+#: engines/engine.cpp:243
msgid "Could not switch to video mode: '"
msgstr "Konnte nicht zu Grafikmodus wechseln: '"
-#: engines/engine.cpp:250
+#: engines/engine.cpp:252
msgid "Could not apply aspect ratio setting."
msgstr "Konnte Einstellung für Seitenverhältniskorrektur nicht anwenden."
-#: engines/engine.cpp:255
+#: engines/engine.cpp:257
msgid "Could not apply fullscreen setting."
msgstr "Konnte Einstellung für Vollbildmodus nicht anwenden."
-#: engines/engine.cpp:355
+#: engines/engine.cpp:357
msgid ""
"You appear to be playing this game directly\n"
"from the CD. This is known to cause problems,\n"
@@ -1236,7 +1235,7 @@ msgstr ""
"Lesen Sie die Liesmich-Datei für\n"
"weitere Informationen."
-#: engines/engine.cpp:366
+#: engines/engine.cpp:368
msgid ""
"This game has audio tracks in its disk. These\n"
"tracks need to be ripped from the disk using\n"
@@ -1251,7 +1250,17 @@ msgstr ""
"Spiel hören zu können. Lesen Sie die\n"
"Liesmich-Datei für weitere Informationen."
-#: engines/engine.cpp:433
+#: engines/engine.cpp:426
+#, fuzzy, c-format
+msgid ""
+"Gamestate load failed (%s)! Please consult the README for basic information, "
+"and for instructions on how to obtain further assistance."
+msgstr ""
+"Leider bietet diese Engine keine Spielhilfe. Bitte lesen Sie die Liesmich-"
+"Datei für grundlegende Informationen und Anweisungen dazu, wie man an "
+"weitere Hilfe gelangt."
+
+#: engines/engine.cpp:439
msgid ""
"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 "
@@ -1262,7 +1271,7 @@ msgstr ""
"und jegliche Spielstände, die Sie erstellen, könnten in zukünftigen "
"Versionen von ScummVM nicht mehr funktionieren."
-#: engines/engine.cpp:436
+#: engines/engine.cpp:442
msgid "Start anyway"
msgstr "Trotzdem starten"
@@ -1306,7 +1315,7 @@ msgstr "Spielen"
#: backends/platform/symbian/src/SymbianActions.cpp:52
#: backends/platform/wince/CEActionsPocket.cpp:44
#: backends/platform/wince/CEActionsSmartphone.cpp:52
-#: backends/events/default/default-events.cpp:244
+#: backends/events/default/default-events.cpp:213
msgid "Quit"
msgstr "Beenden"
@@ -1380,6 +1389,26 @@ msgctxt "lowres"
msgid "Speech & Subs"
msgstr "Sprache & Text"
+#: engines/scumm/dialogs.cpp:653
+msgid "Select a Proficiency Level."
+msgstr "Wähle einen Schwierigkeitsgrad."
+
+#: engines/scumm/dialogs.cpp:655
+msgid "Refer to your Loom(TM) manual for help."
+msgstr "Für Hilfe schaue ins Loom-Handbuch."
+
+#: engines/scumm/dialogs.cpp:658
+msgid "Standard"
+msgstr "Standard"
+
+#: engines/scumm/dialogs.cpp:659
+msgid "Practice"
+msgstr "Anfänger"
+
+#: engines/scumm/dialogs.cpp:660
+msgid "Expert"
+msgstr "Experte"
+
#: engines/scumm/help.cpp:73
msgid "Common keyboard commands:"
msgstr "Allgemeine Tastenbefehle:"
@@ -1893,7 +1922,7 @@ msgstr "Nach rechts fliegen"
msgid "Fly to lower right"
msgstr "Nach unten rechts fliegen"
-#: engines/scumm/scumm.cpp:1774
+#: engines/scumm/scumm.cpp:1773
#, c-format
msgid ""
"Native MIDI support requires the Roland Upgrade from LucasArts,\n"
@@ -1902,7 +1931,7 @@ msgstr ""
"Systemeigene MIDI-Ünterstützung erfordert das Roland-Upgrade von LucasArts,\n"
"aber %s fehlt. Stattdessen wird AdLib verwendet."
-#: engines/scumm/scumm.cpp:2264 engines/agos/saveload.cpp:189
+#: engines/scumm/scumm.cpp:2271 engines/agos/saveload.cpp:189
#, c-format
msgid ""
"Failed to save game state to file:\n"
@@ -1913,7 +1942,7 @@ msgstr ""
"\n"
"%s"
-#: engines/scumm/scumm.cpp:2271 engines/agos/saveload.cpp:154
+#: engines/scumm/scumm.cpp:2278 engines/agos/saveload.cpp:154
#, c-format
msgid ""
"Failed to load game state from file:\n"
@@ -1924,7 +1953,7 @@ msgstr ""
"\n"
"%s"
-#: engines/scumm/scumm.cpp:2283 engines/agos/saveload.cpp:197
+#: engines/scumm/scumm.cpp:2290 engines/agos/saveload.cpp:197
#, c-format
msgid ""
"Successfully saved game state in file:\n"
@@ -1935,7 +1964,7 @@ msgstr ""
"\n"
"%s"
-#: engines/scumm/scumm.cpp:2498
+#: engines/scumm/scumm.cpp:2505
msgid ""
"Usually, Maniac Mansion would start now. But ScummVM doesn't do that yet. To "
"play it, go to 'Add Game' in the ScummVM start menu and select the 'Maniac' "
@@ -1972,11 +2001,11 @@ msgstr "Haupt~m~enü"
msgid "~W~ater Effect Enabled"
msgstr "~W~assereffekt aktiviert"
-#: engines/sci/engine/kfile.cpp:685
+#: engines/sci/engine/kfile.cpp:673
msgid "Restore game:"
msgstr "Spiel laden:"
-#: engines/sci/engine/kfile.cpp:685
+#: engines/sci/engine/kfile.cpp:673
msgid "Restore"
msgstr "Laden"
@@ -1986,11 +2015,11 @@ msgid "Cutscene file '%s' not found!"
msgstr "Zwischensequenz \"%s\" nicht gefunden!"
#: engines/gob/inter_playtoons.cpp:256 engines/gob/inter_v2.cpp:1283
-#: engines/tinsel/saveload.cpp:482
+#: engines/tinsel/saveload.cpp:502
msgid "Failed to load game state from file."
msgstr "Konnte Spielstand aus Datei nicht laden."
-#: engines/gob/inter_v2.cpp:1353 engines/tinsel/saveload.cpp:560
+#: engines/gob/inter_v2.cpp:1353 engines/tinsel/saveload.cpp:515
msgid "Failed to save game state to file."
msgstr "Konnte Spielstand nicht in Datei speichern."
@@ -2002,6 +2031,54 @@ msgstr "Konnte Datei nicht löschen."
msgid "Failed to save game"
msgstr "Konnte Spielstand nicht speichern."
+#: engines/kyra/lol.cpp:478
+msgid "Attack 1"
+msgstr "Attacke 1"
+
+#: engines/kyra/lol.cpp:479
+msgid "Attack 2"
+msgstr "Attacke 2"
+
+#: engines/kyra/lol.cpp:480
+msgid "Attack 3"
+msgstr "Attacke 3"
+
+#: engines/kyra/lol.cpp:481
+msgid "Move Forward"
+msgstr "Nach vorn bewegen"
+
+#: engines/kyra/lol.cpp:482
+msgid "Move Back"
+msgstr "Nach hinten bewegen"
+
+#: engines/kyra/lol.cpp:483
+msgid "Slide Left"
+msgstr "Nach links rutschen"
+
+#: engines/kyra/lol.cpp:484
+msgid "Slide Right"
+msgstr "Nach rechts rutschen"
+
+#: engines/kyra/lol.cpp:485
+msgid "Turn Left"
+msgstr "Nach links drehen"
+
+#: engines/kyra/lol.cpp:486
+msgid "Turn Right"
+msgstr "Nach rechts drehen"
+
+#: engines/kyra/lol.cpp:487
+msgid "Rest"
+msgstr "Ausruhen"
+
+#: engines/kyra/lol.cpp:488
+msgid "Options"
+msgstr "Optionen"
+
+#: engines/kyra/lol.cpp:489
+msgid "Choose Spell"
+msgstr "Zauberspruch auswählen"
+
#: engines/kyra/sound_midi.cpp:475
msgid ""
"You appear to be using a General MIDI device,\n"
@@ -2017,10 +2094,6 @@ msgstr ""
"zuzuordnen. Es kann jedoch vorkommen, dass ein\n"
"paar Musikstücke nicht richtig abgespielt werden."
-#: engines/m4/m4_menus.cpp:138
-msgid "Save game failed!"
-msgstr "Konnte Spielstand nicht speichern!"
-
#: engines/sky/compact.cpp:130
msgid ""
"Unable to find \"sky.cpt\" file!\n"
@@ -2039,17 +2112,22 @@ msgstr ""
"Bitte laden Sie diese Datei (erneut) von\n"
"www.scummvm.org herunter."
-#: engines/sword1/animation.cpp:344 engines/sword2/animation.cpp:379
+#: engines/sword1/animation.cpp:539
+#, c-format
+msgid "PSX stream cutscene '%s' cannot be played in paletted mode"
+msgstr ""
+
+#: engines/sword1/animation.cpp:560 engines/sword2/animation.cpp:455
msgid "DXA cutscenes found but ScummVM has been built without zlib support"
msgstr ""
"DXA-Zwischensequenzen gefunden, aber ScummVM wurde ohne Zlib-Unterstützung "
"erstellt."
-#: engines/sword1/animation.cpp:354 engines/sword2/animation.cpp:389
+#: engines/sword1/animation.cpp:570 engines/sword2/animation.cpp:465
msgid "MPEG2 cutscenes are no longer supported"
msgstr "MPEG2-Zwischensequenzen werden nicht mehr unterstützt."
-#: engines/sword1/animation.cpp:359 engines/sword2/animation.cpp:397
+#: engines/sword1/animation.cpp:576 engines/sword2/animation.cpp:473
#, c-format
msgid "Cutscene '%s' not found"
msgstr "Zwischensequenz \"%s\" gefunden"
@@ -2093,6 +2171,14 @@ msgstr "Den neuen behalten"
msgid "This is the end of the Broken Sword 1 Demo"
msgstr "Das ist das Ende der Demo von Broken Sword 1 (Baphomets Fluch 1)."
+#: engines/sword2/animation.cpp:435
+#, fuzzy
+msgid ""
+"PSX cutscenes found but ScummVM has been built without RGB color support"
+msgstr ""
+"DXA-Zwischensequenzen gefunden, aber ScummVM wurde ohne Zlib-Unterstützung "
+"erstellt."
+
#: engines/parallaction/saveload.cpp:133
#, c-format
msgid ""
@@ -2151,7 +2237,7 @@ msgstr "MAME-OPL-Emulator"
msgid "DOSBox OPL emulator"
msgstr "DOSBox-OPL-Emulator"
-#: audio/mididrv.cpp:205
+#: audio/mididrv.cpp:209
#, c-format
msgid ""
"The selected audio device '%s' was not found (e.g. might be turned off or "
@@ -2160,12 +2246,12 @@ msgstr ""
"Das ausgewählte Audiogerät \"%s\" wurde nicht gefunden (könnte "
"beispielsweise ausgeschaltet oder nicht angeschlossen sein)."
-#: audio/mididrv.cpp:205 audio/mididrv.cpp:217 audio/mididrv.cpp:253
-#: audio/mididrv.cpp:268
+#: audio/mididrv.cpp:209 audio/mididrv.cpp:221 audio/mididrv.cpp:257
+#: audio/mididrv.cpp:272
msgid "Attempting to fall back to the next available device..."
msgstr "Es wird versucht, auf das nächste verfügbare Gerät zurückzugreifen."
-#: audio/mididrv.cpp:217
+#: audio/mididrv.cpp:221
#, c-format
msgid ""
"The selected audio device '%s' cannot be used. See log file for more "
@@ -2174,7 +2260,7 @@ msgstr ""
"Das ausgewählte Audiogerät \"%s\" kann nicht verwendet werden. Schauen Sie "
"für weitere Informationen in der Log-Datei nach."
-#: audio/mididrv.cpp:253
+#: audio/mididrv.cpp:257
#, c-format
msgid ""
"The preferred audio device '%s' was not found (e.g. might be turned off or "
@@ -2183,7 +2269,7 @@ msgstr ""
"Das bevorzugte Audiogerät \"%s\" wurde nicht gefunden (könnte beispielsweise "
"ausgeschaltet oder nicht angeschlossen sein)."
-#: audio/mididrv.cpp:268
+#: audio/mididrv.cpp:272
#, c-format
msgid ""
"The preferred audio device '%s' cannot be used. See log file for more "
@@ -2200,7 +2286,7 @@ msgstr "Keine Musik"
msgid "Amiga Audio Emulator"
msgstr "Amiga-Audio-Emulator"
-#: audio/softsynth/adlib.cpp:1594
+#: audio/softsynth/adlib.cpp:1593
msgid "AdLib Emulator"
msgstr "AdLib-Emulator"
@@ -2212,11 +2298,11 @@ msgstr "Apple-II-GS-Emulator (NICHT INTEGRIERT)"
msgid "C64 Audio Emulator"
msgstr "C64-Audio-Emulator"
-#: audio/softsynth/mt32.cpp:329
+#: audio/softsynth/mt32.cpp:293
msgid "Initializing MT-32 Emulator"
msgstr "MT-32-Emulator wird gestartet"
-#: audio/softsynth/mt32.cpp:543
+#: audio/softsynth/mt32.cpp:512
msgid "MT-32 Emulator"
msgstr "MT-32-Emulation"
@@ -2232,15 +2318,24 @@ msgstr "IBM-PCjr-Emulator"
msgid "Keymap:"
msgstr "Tasten-Layout:"
-#: backends/keymapper/remap-dialog.cpp:64
+#: backends/keymapper/remap-dialog.cpp:66
+#, fuzzy
+msgid " (Effective)"
+msgstr " (Aktiv)"
+
+#: backends/keymapper/remap-dialog.cpp:106
msgid " (Active)"
msgstr " (Aktiv)"
-#: backends/keymapper/remap-dialog.cpp:98
+#: backends/keymapper/remap-dialog.cpp:106
+msgid " (Blocked)"
+msgstr ""
+
+#: backends/keymapper/remap-dialog.cpp:119
msgid " (Global)"
msgstr " (Global)"
-#: backends/keymapper/remap-dialog.cpp:108
+#: backends/keymapper/remap-dialog.cpp:127
msgid " (Game)"
msgstr " (Spiel)"
@@ -2320,42 +2415,66 @@ msgstr "Hohe Audioqualität (lansamer) (erfordert Neustart)"
msgid "Disable power off"
msgstr "Stromsparmodus abschalten"
-#: backends/platform/iphone/osys_events.cpp:338
+#: backends/platform/iphone/osys_events.cpp:301
msgid "Mouse-click-and-drag mode enabled."
msgstr "Maus-klick-und-zieh-Modus aktiviert."
-#: backends/platform/iphone/osys_events.cpp:340
+#: backends/platform/iphone/osys_events.cpp:303
msgid "Mouse-click-and-drag mode disabled."
msgstr "Maus-klick-und-zieh-Modus ausgeschaltet."
-#: backends/platform/iphone/osys_events.cpp:351
+#: backends/platform/iphone/osys_events.cpp:314
msgid "Touchpad mode enabled."
msgstr "Touchpad-Modus aktiviert."
-#: backends/platform/iphone/osys_events.cpp:353
+#: backends/platform/iphone/osys_events.cpp:316
msgid "Touchpad mode disabled."
msgstr "Touchpad-Modus ausgeschaltet."
-#: backends/platform/sdl/macosx/appmenu_osx.mm:67
+#: backends/platform/maemo/maemo.cpp:205
+msgid "Click Mode"
+msgstr ""
+
+#: backends/platform/maemo/maemo.cpp:211
+#: backends/platform/symbian/src/SymbianActions.cpp:42
+#: backends/platform/wince/CEActionsPocket.cpp:60
+#: backends/platform/wince/CEActionsSmartphone.cpp:43
+#: backends/platform/bada/form.cpp:281
+msgid "Left Click"
+msgstr "Linksklick"
+
+#: backends/platform/maemo/maemo.cpp:214
+#, fuzzy
+msgid "Middle Click"
+msgstr "Mittlerer linker Gegenstand"
+
+#: backends/platform/maemo/maemo.cpp:217
+#: backends/platform/symbian/src/SymbianActions.cpp:43
+#: backends/platform/wince/CEActionsSmartphone.cpp:44
+#: backends/platform/bada/form.cpp:273
+msgid "Right Click"
+msgstr "Rechtsklick"
+
+#: backends/platform/sdl/macosx/appmenu_osx.mm:78
msgid "Hide ScummVM"
-msgstr "ScummVM verbergen"
+msgstr "ScummVM ausblenden"
-#: backends/platform/sdl/macosx/appmenu_osx.mm:70
+#: backends/platform/sdl/macosx/appmenu_osx.mm:83
msgid "Hide Others"
-msgstr "Andere verbergen"
+msgstr "Andere ausblenden"
-#: backends/platform/sdl/macosx/appmenu_osx.mm:74
+#: backends/platform/sdl/macosx/appmenu_osx.mm:88
msgid "Show All"
-msgstr "Alles zeigen"
+msgstr "Alle einblenden"
-#: backends/platform/sdl/macosx/appmenu_osx.mm:92
-#: backends/platform/sdl/macosx/appmenu_osx.mm:99
+#: backends/platform/sdl/macosx/appmenu_osx.mm:110
+#: backends/platform/sdl/macosx/appmenu_osx.mm:121
msgid "Window"
msgstr "Fenster"
-#: backends/platform/sdl/macosx/appmenu_osx.mm:95
+#: backends/platform/sdl/macosx/appmenu_osx.mm:115
msgid "Minimize"
-msgstr "Minimieren"
+msgstr "Im Dock ablegen"
#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:45
msgid "Normal (no scaling)"
@@ -2367,12 +2486,12 @@ msgid "Normal (no scaling)"
msgstr "Normal ohn.Skalieren"
#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2147
-#: backends/graphics/openglsdl/openglsdl-graphics.cpp:537
+#: backends/graphics/openglsdl/openglsdl-graphics.cpp:533
msgid "Enabled aspect ratio correction"
msgstr "Seitenverhältniskorrektur an"
#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2153
-#: backends/graphics/openglsdl/openglsdl-graphics.cpp:542
+#: backends/graphics/openglsdl/openglsdl-graphics.cpp:538
msgid "Disabled aspect ratio correction"
msgstr "Seitenverhältniskorrektur aus"
@@ -2381,7 +2500,7 @@ msgid "Active graphics filter:"
msgstr "Aktiver Grafikfilter:"
#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2250
-#: backends/graphics/openglsdl/openglsdl-graphics.cpp:481
+#: backends/graphics/openglsdl/openglsdl-graphics.cpp:477
msgid "Windowed mode"
msgstr "Fenstermodus"
@@ -2405,11 +2524,11 @@ msgstr "Aktueller Grafikmodus"
msgid "Current scale"
msgstr "Aktueller Vergrößerungsfaktor"
-#: backends/graphics/openglsdl/openglsdl-graphics.cpp:562
+#: backends/graphics/openglsdl/openglsdl-graphics.cpp:558
msgid "Active filter mode: Linear"
msgstr "Aktiver Filtermodus: linear"
-#: backends/graphics/openglsdl/openglsdl-graphics.cpp:564
+#: backends/graphics/openglsdl/openglsdl-graphics.cpp:560
msgid "Active filter mode: Nearest"
msgstr "Aktiver Filtermodus: nächste Nachbarn"
@@ -2433,19 +2552,6 @@ msgstr "Links"
msgid "Right"
msgstr "Rechts"
-#: backends/platform/symbian/src/SymbianActions.cpp:42
-#: backends/platform/wince/CEActionsPocket.cpp:60
-#: backends/platform/wince/CEActionsSmartphone.cpp:43
-#: backends/platform/bada/form.cpp:281
-msgid "Left Click"
-msgstr "Linksklick"
-
-#: backends/platform/symbian/src/SymbianActions.cpp:43
-#: backends/platform/wince/CEActionsSmartphone.cpp:44
-#: backends/platform/bada/form.cpp:273
-msgid "Right Click"
-msgstr "Rechtsklick"
-
#: backends/platform/symbian/src/SymbianActions.cpp:46
#: backends/platform/wince/CEActionsSmartphone.cpp:47
msgid "Zone"
@@ -2736,15 +2842,15 @@ msgstr ""
"Vergessen Sie nicht, der Aktion \"Werkzeugleiste verbergen\" eine Taste "
"zuzuweisen, um das ganze Inventar sehen zu können."
-#: backends/events/default/default-events.cpp:222
+#: backends/events/default/default-events.cpp:191
msgid "Do you really want to return to the Launcher?"
msgstr "Möchten Sie wirklich zur Spieleliste zurückkehren?"
-#: backends/events/default/default-events.cpp:222
+#: backends/events/default/default-events.cpp:191
msgid "Launcher"
msgstr "Spieleliste"
-#: backends/events/default/default-events.cpp:244
+#: backends/events/default/default-events.cpp:213
msgid "Do you really want to quit?"
msgstr "Möchten Sie wirklich beenden?"
@@ -2810,14 +2916,31 @@ msgstr "Ziffernblock zeigen"
msgid "Control Mouse"
msgstr "Maus steuern"
-#: backends/events/maemosdl/maemosdl-events.cpp:121
+#: backends/events/maemosdl/maemosdl-events.cpp:192
msgid "Clicking Enabled"
msgstr "Klicken aktiviert"
-#: backends/events/maemosdl/maemosdl-events.cpp:121
+#: backends/events/maemosdl/maemosdl-events.cpp:192
msgid "Clicking Disabled"
msgstr "Klicken deaktiviert"
+#~ msgid "Hercules Green"
+#~ msgstr "Hercules-Grün"
+
+#~ msgid "Hercules Amber"
+#~ msgstr "Hercules-Bernsteingelb"
+
+#~ msgctxt "lowres"
+#~ msgid "Hercules Green"
+#~ msgstr "Hercules-Grün"
+
+#~ msgctxt "lowres"
+#~ msgid "Hercules Amber"
+#~ msgstr "Hercules-Gelb"
+
+#~ msgid "Save game failed!"
+#~ msgstr "Konnte Spielstand nicht speichern!"
+
#~ msgid ""
#~ "Your game version has been detected using filename matching as a variant "
#~ "of %s."
diff --git a/po/es_ES.po b/po/es_ES.po
index 2346d46c3b..c825e9de4f 100644
--- a/po/es_ES.po
+++ b/po/es_ES.po
@@ -1,5 +1,5 @@
# Spanish translation for ScummVM.
-# Copyright (C) 2010-2011 ScummVM Team
+# Copyright (C) 2010-2012 ScummVM Team
# This file is distributed under the same license as the ScummVM package.
# Tomás Maidagan, 2011.
#
@@ -7,14 +7,14 @@ msgid ""
msgstr ""
"Project-Id-Version: ScummVM 1.4.0svn\n"
"Report-Msgid-Bugs-To: scummvm-devel@lists.sf.net\n"
-"POT-Creation-Date: 2011-10-19 13:42+0100\n"
-"PO-Revision-Date: 2011-10-15 13:40+0100\n"
+"POT-Creation-Date: 2012-03-07 22:09+0000\n"
+"PO-Revision-Date: 2011-10-23 21:53+0100\n"
"Last-Translator: Tomás Maidagan\n"
"Language-Team: \n"
-"Language: Espanol\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=iso-8859-1\n"
"Content-Transfer-Encoding: 8bit\n"
+"Language: Espanol\n"
#: gui/about.cpp:91
#, c-format
@@ -43,13 +43,13 @@ msgid "Go up"
msgstr "Arriba"
#: gui/browser.cpp:69 gui/chooser.cpp:45 gui/KeysDialog.cpp:43
-#: gui/launcher.cpp:312 gui/massadd.cpp:94 gui/options.cpp:1178
+#: gui/launcher.cpp:320 gui/massadd.cpp:94 gui/options.cpp:1253
#: gui/saveload.cpp:63 gui/saveload.cpp:155 gui/themebrowser.cpp:54
-#: engines/engine.cpp:436 engines/scumm/dialogs.cpp:190
+#: engines/engine.cpp:442 engines/scumm/dialogs.cpp:190
#: engines/sword1/control.cpp:865 engines/parallaction/saveload.cpp:281
#: backends/platform/wii/options.cpp:48
-#: backends/events/default/default-events.cpp:222
-#: backends/events/default/default-events.cpp:244
+#: backends/events/default/default-events.cpp:191
+#: backends/events/default/default-events.cpp:213
msgid "Cancel"
msgstr "Cancelar"
@@ -57,25 +57,30 @@ msgstr "Cancelar"
msgid "Choose"
msgstr "Aceptar"
-#: gui/gui-manager.cpp:116 engines/scumm/help.cpp:125
+#: gui/gui-manager.cpp:115 engines/scumm/help.cpp:125
#: engines/scumm/help.cpp:140 engines/scumm/help.cpp:165
#: engines/scumm/help.cpp:191 engines/scumm/help.cpp:209
#: backends/keymapper/remap-dialog.cpp:52
msgid "Close"
msgstr "Cerrar"
-#: gui/gui-manager.cpp:119
+#: gui/gui-manager.cpp:118
msgid "Mouse click"
msgstr "Clic de ratón"
-#: gui/gui-manager.cpp:122 base/main.cpp:283
+#: gui/gui-manager.cpp:122 base/main.cpp:288
msgid "Display keyboard"
msgstr "Mostrar el teclado"
-#: gui/gui-manager.cpp:125 base/main.cpp:286
+#: gui/gui-manager.cpp:126 base/main.cpp:292
msgid "Remap keys"
msgstr "Asignar teclas"
+#: gui/gui-manager.cpp:129 base/main.cpp:295
+#, fuzzy
+msgid "Toggle FullScreen"
+msgstr "Activar pantalla completa"
+
#: gui/KeysDialog.h:36 gui/KeysDialog.cpp:145
msgid "Choose an action to map"
msgstr "Elige la acción a asociar"
@@ -84,16 +89,17 @@ msgstr "Elige la acción a asociar"
msgid "Map"
msgstr "Asignar"
-#: gui/KeysDialog.cpp:42 gui/launcher.cpp:313 gui/launcher.cpp:936
-#: gui/launcher.cpp:940 gui/massadd.cpp:91 gui/options.cpp:1179
-#: engines/engine.cpp:359 engines/engine.cpp:370 engines/scumm/dialogs.cpp:192
-#: engines/scumm/scumm.cpp:1776 engines/agos/animation.cpp:551
+#: gui/KeysDialog.cpp:42 gui/launcher.cpp:321 gui/launcher.cpp:960
+#: gui/launcher.cpp:964 gui/massadd.cpp:91 gui/options.cpp:1254
+#: engines/engine.cpp:361 engines/engine.cpp:372 engines/scumm/dialogs.cpp:192
+#: engines/scumm/scumm.cpp:1775 engines/agos/animation.cpp:551
#: engines/groovie/script.cpp:420 engines/sky/compact.cpp:131
-#: engines/sky/compact.cpp:141 engines/sword1/animation.cpp:344
-#: engines/sword1/animation.cpp:354 engines/sword1/animation.cpp:360
-#: engines/sword1/control.cpp:865 engines/sword1/logic.cpp:1633
-#: engines/sword2/animation.cpp:379 engines/sword2/animation.cpp:389
-#: engines/sword2/animation.cpp:398 engines/parallaction/saveload.cpp:281
+#: engines/sky/compact.cpp:141 engines/sword1/animation.cpp:539
+#: engines/sword1/animation.cpp:560 engines/sword1/animation.cpp:570
+#: engines/sword1/animation.cpp:577 engines/sword1/control.cpp:865
+#: engines/sword1/logic.cpp:1633 engines/sword2/animation.cpp:435
+#: engines/sword2/animation.cpp:455 engines/sword2/animation.cpp:465
+#: engines/sword2/animation.cpp:474 engines/parallaction/saveload.cpp:281
#: backends/platform/wii/options.cpp:47
#: backends/platform/wince/CELauncherDialog.cpp:54
msgid "OK"
@@ -121,15 +127,15 @@ msgstr "Por favor, selecciona una acción"
msgid "Press the key to associate"
msgstr "Pulsa la tecla a asignar"
-#: gui/launcher.cpp:165
+#: gui/launcher.cpp:170
msgid "Game"
msgstr "Juego"
-#: gui/launcher.cpp:169
+#: gui/launcher.cpp:174
msgid "ID:"
msgstr "ID:"
-#: gui/launcher.cpp:169 gui/launcher.cpp:171 gui/launcher.cpp:172
+#: gui/launcher.cpp:174 gui/launcher.cpp:176 gui/launcher.cpp:177
msgid ""
"Short game identifier used for referring to savegames and running the game "
"from the command line"
@@ -137,29 +143,29 @@ msgstr ""
"Identificador usado para las partidas guardadas y para ejecutar el juego "
"desde la línea de comando"
-#: gui/launcher.cpp:171
+#: gui/launcher.cpp:176
msgctxt "lowres"
msgid "ID:"
msgstr "ID:"
-#: gui/launcher.cpp:176
+#: gui/launcher.cpp:181
msgid "Name:"
msgstr "Nombre:"
-#: gui/launcher.cpp:176 gui/launcher.cpp:178 gui/launcher.cpp:179
+#: gui/launcher.cpp:181 gui/launcher.cpp:183 gui/launcher.cpp:184
msgid "Full title of the game"
msgstr "Título completo del juego"
-#: gui/launcher.cpp:178
+#: gui/launcher.cpp:183
msgctxt "lowres"
msgid "Name:"
msgstr "Nom.:"
-#: gui/launcher.cpp:182
+#: gui/launcher.cpp:187
msgid "Language:"
msgstr "Idioma:"
-#: gui/launcher.cpp:182 gui/launcher.cpp:183
+#: gui/launcher.cpp:187 gui/launcher.cpp:188
msgid ""
"Language of the game. This will not turn your Spanish game version into "
"English"
@@ -167,282 +173,280 @@ msgstr ""
"Idioma del juego. No sirve para pasar al inglés la versión española de un "
"juego"
-#: gui/launcher.cpp:184 gui/launcher.cpp:198 gui/options.cpp:74
-#: gui/options.cpp:708 gui/options.cpp:718 gui/options.cpp:1149
+#: gui/launcher.cpp:189 gui/launcher.cpp:203 gui/options.cpp:80
+#: gui/options.cpp:745 gui/options.cpp:758 gui/options.cpp:1224
#: audio/null.cpp:40
msgid "<default>"
msgstr "<por defecto>"
-#: gui/launcher.cpp:194
+#: gui/launcher.cpp:199
msgid "Platform:"
msgstr "Plataforma:"
-#: gui/launcher.cpp:194 gui/launcher.cpp:196 gui/launcher.cpp:197
+#: gui/launcher.cpp:199 gui/launcher.cpp:201 gui/launcher.cpp:202
msgid "Platform the game was originally designed for"
msgstr "Plataforma para la que se diseñó el juego"
-#: gui/launcher.cpp:196
+#: gui/launcher.cpp:201
msgctxt "lowres"
msgid "Platform:"
msgstr "Plat.:"
-#: gui/launcher.cpp:208 gui/options.cpp:1018 gui/options.cpp:1035
+#: gui/launcher.cpp:213 gui/options.cpp:1087 gui/options.cpp:1104
msgid "Graphics"
msgstr "Gráficos"
-#: gui/launcher.cpp:208 gui/options.cpp:1018 gui/options.cpp:1035
+#: gui/launcher.cpp:213 gui/options.cpp:1087 gui/options.cpp:1104
msgid "GFX"
msgstr "GFX"
-#: gui/launcher.cpp:211
+#: gui/launcher.cpp:216
msgid "Override global graphic settings"
msgstr "Ignorar opciones gráficas generales"
-#: gui/launcher.cpp:213
+#: gui/launcher.cpp:218
msgctxt "lowres"
msgid "Override global graphic settings"
msgstr "Opciones gráficas específicas"
-#: gui/launcher.cpp:220 gui/options.cpp:1041
+#: gui/launcher.cpp:225 gui/options.cpp:1110
msgid "Audio"
msgstr "Sonido"
-#: gui/launcher.cpp:223
+#: gui/launcher.cpp:228
msgid "Override global audio settings"
msgstr "Ignorar opciones de sonido generales"
-#: gui/launcher.cpp:225
+#: gui/launcher.cpp:230
msgctxt "lowres"
msgid "Override global audio settings"
msgstr "Opciones de sonido específicas"
-#: gui/launcher.cpp:234 gui/options.cpp:1046
+#: gui/launcher.cpp:239 gui/options.cpp:1115
msgid "Volume"
msgstr "Volumen"
-#: gui/launcher.cpp:236 gui/options.cpp:1048
+#: gui/launcher.cpp:241 gui/options.cpp:1117
msgctxt "lowres"
msgid "Volume"
msgstr "Volumen"
-#: gui/launcher.cpp:239
+#: gui/launcher.cpp:244
msgid "Override global volume settings"
msgstr "Ignorar opciones de volumen generales"
-#: gui/launcher.cpp:241
+#: gui/launcher.cpp:246
msgctxt "lowres"
msgid "Override global volume settings"
msgstr "Opciones de volumen específicas"
-#: gui/launcher.cpp:248 gui/options.cpp:1056
+#: gui/launcher.cpp:254 gui/options.cpp:1125
msgid "MIDI"
msgstr "MIDI"
-#: gui/launcher.cpp:251
+#: gui/launcher.cpp:257
msgid "Override global MIDI settings"
msgstr "Ignorar opciones de MIDI generales"
-#: gui/launcher.cpp:253
+#: gui/launcher.cpp:259
msgctxt "lowres"
msgid "Override global MIDI settings"
msgstr "Opciones de MIDI específicas"
-#: gui/launcher.cpp:263 gui/options.cpp:1062
+#: gui/launcher.cpp:268 gui/options.cpp:1131
msgid "MT-32"
msgstr "MT-32"
-#: gui/launcher.cpp:266
+#: gui/launcher.cpp:271
msgid "Override global MT-32 settings"
msgstr "Ignorar opciones de MT-32 generales"
-#: gui/launcher.cpp:268
+#: gui/launcher.cpp:273
msgctxt "lowres"
msgid "Override global MT-32 settings"
msgstr "Opciones de MT-32 específicas"
-#: gui/launcher.cpp:279 gui/options.cpp:1069
+#: gui/launcher.cpp:282 gui/options.cpp:1138
msgid "Paths"
msgstr "Rutas"
-#: gui/launcher.cpp:281 gui/options.cpp:1071
+#: gui/launcher.cpp:284 gui/options.cpp:1140
msgctxt "lowres"
msgid "Paths"
msgstr "Rutas"
-#: gui/launcher.cpp:288
+#: gui/launcher.cpp:291
msgid "Game Path:"
msgstr "Juego:"
-#: gui/launcher.cpp:290
+#: gui/launcher.cpp:293
msgctxt "lowres"
msgid "Game Path:"
msgstr "Juego:"
-#: gui/launcher.cpp:295 gui/options.cpp:1091
+#: gui/launcher.cpp:298 gui/options.cpp:1164
msgid "Extra Path:"
msgstr "Adicional:"
-#: gui/launcher.cpp:295 gui/launcher.cpp:297 gui/launcher.cpp:298
+#: gui/launcher.cpp:298 gui/launcher.cpp:300 gui/launcher.cpp:301
msgid "Specifies path to additional data used the game"
msgstr "Especifica un directorio para datos adicionales del juego"
-#: gui/launcher.cpp:297 gui/options.cpp:1093
+#: gui/launcher.cpp:300 gui/options.cpp:1166
msgctxt "lowres"
msgid "Extra Path:"
msgstr "Adicional:"
-#: gui/launcher.cpp:302 gui/options.cpp:1079
+#: gui/launcher.cpp:307 gui/options.cpp:1148
msgid "Save Path:"
msgstr "Partidas:"
-#: gui/launcher.cpp:302 gui/launcher.cpp:304 gui/launcher.cpp:305
-#: gui/options.cpp:1079 gui/options.cpp:1081 gui/options.cpp:1082
+#: gui/launcher.cpp:307 gui/launcher.cpp:309 gui/launcher.cpp:310
+#: gui/options.cpp:1148 gui/options.cpp:1150 gui/options.cpp:1151
msgid "Specifies where your savegames are put"
msgstr "Especifica dónde guardar tus partidas"
-#: gui/launcher.cpp:304 gui/options.cpp:1081
+#: gui/launcher.cpp:309 gui/options.cpp:1150
msgctxt "lowres"
msgid "Save Path:"
msgstr "Partidas:"
-#: gui/launcher.cpp:321 gui/launcher.cpp:404 gui/launcher.cpp:453
-#: gui/options.cpp:1088 gui/options.cpp:1094 gui/options.cpp:1101
-#: gui/options.cpp:1202 gui/options.cpp:1208 gui/options.cpp:1214
-#: gui/options.cpp:1222 gui/options.cpp:1246 gui/options.cpp:1250
-#: gui/options.cpp:1256 gui/options.cpp:1263 gui/options.cpp:1362
+#: gui/launcher.cpp:329 gui/launcher.cpp:416 gui/launcher.cpp:469
+#: gui/launcher.cpp:523 gui/options.cpp:1159 gui/options.cpp:1167
+#: gui/options.cpp:1176 gui/options.cpp:1283 gui/options.cpp:1289
+#: gui/options.cpp:1297 gui/options.cpp:1327 gui/options.cpp:1333
+#: gui/options.cpp:1340 gui/options.cpp:1433 gui/options.cpp:1436
+#: gui/options.cpp:1448
msgctxt "path"
msgid "None"
msgstr "Ninguna"
-#: gui/launcher.cpp:326 gui/launcher.cpp:408
+#: gui/launcher.cpp:334 gui/launcher.cpp:422 gui/launcher.cpp:527
+#: gui/options.cpp:1277 gui/options.cpp:1321 gui/options.cpp:1439
#: backends/platform/wii/options.cpp:56
msgid "Default"
msgstr "Por defecto"
-#: gui/launcher.cpp:446 gui/options.cpp:1356
+#: gui/launcher.cpp:462 gui/options.cpp:1442
msgid "Select SoundFont"
msgstr "Selecciona un SoundFont"
-#: gui/launcher.cpp:465 gui/launcher.cpp:612
+#: gui/launcher.cpp:481 gui/launcher.cpp:636
msgid "Select directory with game data"
msgstr "Selecciona el directorio del juego"
-#: gui/launcher.cpp:483
+#: gui/launcher.cpp:499
msgid "Select additional game directory"
msgstr "Selecciona el directorio adicional"
-#: gui/launcher.cpp:495
+#: gui/launcher.cpp:511
msgid "Select directory for saved games"
msgstr "Selecciona el directorio para partidas guardadas"
-#: gui/launcher.cpp:514
+#: gui/launcher.cpp:538
msgid "This game ID is already taken. Please choose another one."
msgstr "Esta ID ya está siendo usada. Por favor, elige otra."
-#: gui/launcher.cpp:555 engines/dialogs.cpp:110
+#: gui/launcher.cpp:579 engines/dialogs.cpp:110
msgid "~Q~uit"
msgstr "~S~alir"
-#: gui/launcher.cpp:555 backends/platform/sdl/macosx/appmenu_osx.mm:80
+#: gui/launcher.cpp:579 backends/platform/sdl/macosx/appmenu_osx.mm:96
msgid "Quit ScummVM"
-msgstr "Cerrar ScummVM"
+msgstr "Salir de ScummVM"
-#: gui/launcher.cpp:556
+#: gui/launcher.cpp:580
msgid "A~b~out..."
msgstr "Acerca ~d~e"
-#: gui/launcher.cpp:556 backends/platform/sdl/macosx/appmenu_osx.mm:61
+#: gui/launcher.cpp:580 backends/platform/sdl/macosx/appmenu_osx.mm:70
msgid "About ScummVM"
msgstr "Acerca de ScummVM"
-#: gui/launcher.cpp:557
+#: gui/launcher.cpp:581
msgid "~O~ptions..."
msgstr "~O~pciones..."
-#: gui/launcher.cpp:557
+#: gui/launcher.cpp:581
msgid "Change global ScummVM options"
msgstr "Cambiar opciones generales de ScummVM"
-#: gui/launcher.cpp:559
+#: gui/launcher.cpp:583
msgid "~S~tart"
msgstr "~J~ugar"
-#: gui/launcher.cpp:559
+#: gui/launcher.cpp:583
msgid "Start selected game"
msgstr "Jugar al juego seleccionado"
-#: gui/launcher.cpp:562
+#: gui/launcher.cpp:586
msgid "~L~oad..."
msgstr "~C~argar..."
-#: gui/launcher.cpp:562
+#: gui/launcher.cpp:586
msgid "Load savegame for selected game"
msgstr "Cargar partida del juego seleccionado"
-#: gui/launcher.cpp:567 gui/launcher.cpp:1055
+#: gui/launcher.cpp:591 gui/launcher.cpp:1079
msgid "~A~dd Game..."
msgstr "~A~ñadir juego..."
-#: gui/launcher.cpp:567 gui/launcher.cpp:574
+#: gui/launcher.cpp:591 gui/launcher.cpp:598
msgid "Hold Shift for Mass Add"
msgstr "Mantener pulsado Mayús para añadir varios juegos"
-#: gui/launcher.cpp:569
+#: gui/launcher.cpp:593
msgid "~E~dit Game..."
msgstr "~E~ditar juego..."
-#: gui/launcher.cpp:569 gui/launcher.cpp:576
+#: gui/launcher.cpp:593 gui/launcher.cpp:600
msgid "Change game options"
msgstr "Cambiar opciones de juego"
-#: gui/launcher.cpp:571
+#: gui/launcher.cpp:595
msgid "~R~emove Game"
msgstr "E~l~iminar juego"
-#: gui/launcher.cpp:571 gui/launcher.cpp:578
+#: gui/launcher.cpp:595 gui/launcher.cpp:602
msgid "Remove game from the list. The game data files stay intact"
msgstr "Eliminar el juego de la lista. Los archivos no se borran"
-#: gui/launcher.cpp:574 gui/launcher.cpp:1055
+#: gui/launcher.cpp:598 gui/launcher.cpp:1079
msgctxt "lowres"
msgid "~A~dd Game..."
msgstr "~A~ñadir..."
-#: gui/launcher.cpp:576
+#: gui/launcher.cpp:600
msgctxt "lowres"
msgid "~E~dit Game..."
msgstr "~E~ditar..."
-#: gui/launcher.cpp:578
+#: gui/launcher.cpp:602
msgctxt "lowres"
msgid "~R~emove Game"
msgstr "E~l~iminar"
-#: gui/launcher.cpp:586
+#: gui/launcher.cpp:610
msgid "Search in game list"
msgstr "Buscar en la lista de juegos"
-#: gui/launcher.cpp:590 gui/launcher.cpp:1102
+#: gui/launcher.cpp:614 gui/launcher.cpp:1126
msgid "Search:"
msgstr "Buscar:"
-#: gui/launcher.cpp:593 gui/options.cpp:826
-msgid "Clear value"
-msgstr "Eliminar valor"
-
-#: gui/launcher.cpp:615 engines/dialogs.cpp:114 engines/mohawk/myst.cpp:255
+#: gui/launcher.cpp:639 engines/dialogs.cpp:114 engines/mohawk/myst.cpp:255
#: engines/mohawk/riven.cpp:716 engines/cruise/menu.cpp:216
msgid "Load game:"
msgstr "Cargar juego:"
-#: gui/launcher.cpp:615 engines/dialogs.cpp:114 engines/scumm/dialogs.cpp:188
+#: gui/launcher.cpp:639 engines/dialogs.cpp:114 engines/scumm/dialogs.cpp:188
#: engines/mohawk/myst.cpp:255 engines/mohawk/riven.cpp:716
#: engines/cruise/menu.cpp:216 backends/platform/wince/CEActionsPocket.cpp:267
#: backends/platform/wince/CEActionsSmartphone.cpp:231
msgid "Load"
msgstr "Cargar"
-#: gui/launcher.cpp:723
+#: gui/launcher.cpp:747
msgid ""
"Do you really want to run the mass game detector? This could potentially add "
"a huge number of games."
@@ -450,7 +454,7 @@ msgstr ""
"¿Seguro que quieres ejecutar la detección masiva? Puede que se añada un gran "
"número de juegos."
-#: gui/launcher.cpp:724 gui/launcher.cpp:872
+#: gui/launcher.cpp:748 gui/launcher.cpp:896
#: backends/events/symbiansdl/symbiansdl-events.cpp:184
#: backends/platform/wince/CEActionsPocket.cpp:326
#: backends/platform/wince/CEActionsSmartphone.cpp:287
@@ -458,7 +462,7 @@ msgstr ""
msgid "Yes"
msgstr "Sí"
-#: gui/launcher.cpp:724 gui/launcher.cpp:872
+#: gui/launcher.cpp:748 gui/launcher.cpp:896
#: backends/events/symbiansdl/symbiansdl-events.cpp:184
#: backends/platform/wince/CEActionsPocket.cpp:326
#: backends/platform/wince/CEActionsSmartphone.cpp:287
@@ -466,37 +470,37 @@ msgstr "Sí"
msgid "No"
msgstr "No"
-#: gui/launcher.cpp:772
+#: gui/launcher.cpp:796
msgid "ScummVM couldn't open the specified directory!"
msgstr "¡ScummVM no ha podido abrir el directorio!"
-#: gui/launcher.cpp:784
+#: gui/launcher.cpp:808
msgid "ScummVM could not find any game in the specified directory!"
msgstr "¡ScummVM no ha encontrado ningún juego en el directorio!"
-#: gui/launcher.cpp:798
+#: gui/launcher.cpp:822
msgid "Pick the game:"
msgstr "Elige el juego:"
-#: gui/launcher.cpp:872
+#: gui/launcher.cpp:896
msgid "Do you really want to remove this game configuration?"
msgstr "¿Seguro que quieres eliminar la configuración de este juego?"
-#: gui/launcher.cpp:936
+#: gui/launcher.cpp:960
msgid "This game does not support loading games from the launcher."
msgstr "Este juego no permite cargar partidas desde el lanzador."
-#: gui/launcher.cpp:940
+#: gui/launcher.cpp:964
msgid "ScummVM could not find any engine capable of running the selected game!"
msgstr ""
"¡ScummVM no ha podido encontrar ningún motor capaz de ejecutar el juego!"
-#: gui/launcher.cpp:1054
+#: gui/launcher.cpp:1078
msgctxt "lowres"
msgid "Mass Add..."
msgstr "Añad. varios"
-#: gui/launcher.cpp:1054
+#: gui/launcher.cpp:1078
msgid "Mass Add..."
msgstr "Añadir varios..."
@@ -511,9 +515,7 @@ msgstr "¡Búsqueda completada!"
#: gui/massadd.cpp:261
#, c-format
msgid "Discovered %d new games, ignored %d previously added games."
-msgstr ""
-"Se han encontrado %d juegos nuevos, se han ignorado %d juegos añadidos "
-"previamente."
+msgstr "%d juegos nuevos encontrados. %d juegos ignorados (ya añadidos)."
#: gui/massadd.cpp:265
#, c-format
@@ -523,148 +525,146 @@ msgstr "Se ha buscado en %d directorios..."
#: gui/massadd.cpp:268
#, c-format
msgid "Discovered %d new games, ignored %d previously added games ..."
-msgstr ""
-"Se han encontrado %d juegos nuevos, se han ignorado %d juegos añadidos "
-"previamente..."
+msgstr "%d juegos nuevos encontrados. %d juegos ignorados (ya añadidos)..."
-#: gui/options.cpp:72
+#: gui/options.cpp:78
msgid "Never"
msgstr "Nunca"
-#: gui/options.cpp:72
+#: gui/options.cpp:78
msgid "every 5 mins"
msgstr "cada 5 minutos"
-#: gui/options.cpp:72
+#: gui/options.cpp:78
msgid "every 10 mins"
msgstr "cada 10 minutos"
-#: gui/options.cpp:72
+#: gui/options.cpp:78
msgid "every 15 mins"
msgstr "cada 15 minutos"
-#: gui/options.cpp:72
+#: gui/options.cpp:78
msgid "every 30 mins"
msgstr "cada 30 minutos"
-#: gui/options.cpp:74
+#: gui/options.cpp:80
msgid "8 kHz"
msgstr "8 kHz"
-#: gui/options.cpp:74
+#: gui/options.cpp:80
msgid "11kHz"
msgstr "11kHz"
-#: gui/options.cpp:74
+#: gui/options.cpp:80
msgid "22 kHz"
msgstr "22 kHz"
-#: gui/options.cpp:74
+#: gui/options.cpp:80
msgid "44 kHz"
msgstr "44 kHz"
-#: gui/options.cpp:74
+#: gui/options.cpp:80
msgid "48 kHz"
msgstr "48 kHz"
-#: gui/options.cpp:236 gui/options.cpp:464 gui/options.cpp:559
-#: gui/options.cpp:625 gui/options.cpp:825
+#: gui/options.cpp:257 gui/options.cpp:485 gui/options.cpp:586
+#: gui/options.cpp:659 gui/options.cpp:868
msgctxt "soundfont"
msgid "None"
msgstr "Ninguno"
-#: gui/options.cpp:372
+#: gui/options.cpp:393
msgid "Failed to apply some of the graphic options changes:"
msgstr "Fallo al aplicar algunos cambios en las opciones gráficas:"
-#: gui/options.cpp:384
+#: gui/options.cpp:405
msgid "the video mode could not be changed."
msgstr "no se ha podido cambiar el modo de vídeo."
-#: gui/options.cpp:390
+#: gui/options.cpp:411
msgid "the fullscreen setting could not be changed"
msgstr "no se ha podido cambiar el ajuste de pantalla completa"
-#: gui/options.cpp:396
+#: gui/options.cpp:417
msgid "the aspect ratio setting could not be changed"
msgstr "no se ha podido cambiar el ajuste de corrección de aspecto"
-#: gui/options.cpp:705
+#: gui/options.cpp:742
msgid "Graphics mode:"
msgstr "Modo gráfico:"
-#: gui/options.cpp:716
+#: gui/options.cpp:756
msgid "Render mode:"
msgstr "Renderizado:"
-#: gui/options.cpp:716 gui/options.cpp:717
+#: gui/options.cpp:756 gui/options.cpp:757
msgid "Special dithering modes supported by some games"
msgstr "Modos especiales de expansión soportados por algunos juegos"
-#: gui/options.cpp:726
+#: gui/options.cpp:768
#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2248
-#: backends/graphics/openglsdl/openglsdl-graphics.cpp:476
+#: backends/graphics/openglsdl/openglsdl-graphics.cpp:472
msgid "Fullscreen mode"
msgstr "Pantalla completa"
-#: gui/options.cpp:729
+#: gui/options.cpp:771
msgid "Aspect ratio correction"
msgstr "Corrección de aspecto"
-#: gui/options.cpp:729
+#: gui/options.cpp:771
msgid "Correct aspect ratio for 320x200 games"
msgstr "Corregir relación de aspecto en juegos 320x200"
-#: gui/options.cpp:730
+#: gui/options.cpp:772
msgid "EGA undithering"
msgstr "Difuminado EGA"
-#: gui/options.cpp:730
+#: gui/options.cpp:772
msgid "Enable undithering in EGA games that support it"
msgstr "Activar difuminado en los juegos EGA compatibles"
-#: gui/options.cpp:738
+#: gui/options.cpp:780
msgid "Preferred Device:"
msgstr "Disp. preferido:"
-#: gui/options.cpp:738
+#: gui/options.cpp:780
msgid "Music Device:"
msgstr "Disp. de música:"
-#: gui/options.cpp:738 gui/options.cpp:740
+#: gui/options.cpp:780 gui/options.cpp:782
msgid "Specifies preferred sound device or sound card emulator"
msgstr ""
"Especifica qué dispositivo de sonido o emulador de tarjeta de sonido "
"prefieres"
-#: gui/options.cpp:738 gui/options.cpp:740 gui/options.cpp:741
+#: gui/options.cpp:780 gui/options.cpp:782 gui/options.cpp:783
msgid "Specifies output sound device or sound card emulator"
msgstr ""
"Especifica el dispositivo de sonido o emulador de tarjeta de sonido de salida"
-#: gui/options.cpp:740
+#: gui/options.cpp:782
msgctxt "lowres"
msgid "Preferred Dev.:"
msgstr "Disp. preferido:"
-#: gui/options.cpp:740
+#: gui/options.cpp:782
msgctxt "lowres"
msgid "Music Device:"
msgstr "Disp. de música:"
-#: gui/options.cpp:766
+#: gui/options.cpp:809
msgid "AdLib emulator:"
msgstr "Emul. de AdLib:"
-#: gui/options.cpp:766 gui/options.cpp:767
+#: gui/options.cpp:809 gui/options.cpp:810
msgid "AdLib is used for music in many games"
msgstr "AdLib se usa para la música en muchos juegos"
-#: gui/options.cpp:777
+#: gui/options.cpp:820
msgid "Output rate:"
msgstr "Frec. de salida:"
-#: gui/options.cpp:777 gui/options.cpp:778
+#: gui/options.cpp:820 gui/options.cpp:821
msgid ""
"Higher value specifies better sound quality but may be not supported by your "
"soundcard"
@@ -672,64 +672,64 @@ msgstr ""
"Los valores más altos ofrecen mayor calidad, pero puede que tu tarjeta de "
"sonido no sea compatible"
-#: gui/options.cpp:788
+#: gui/options.cpp:831
msgid "GM Device:"
msgstr "Dispositivo GM:"
-#: gui/options.cpp:788
+#: gui/options.cpp:831
msgid "Specifies default sound device for General MIDI output"
msgstr "Especifica el dispositivo de salida General MIDI por defecto"
-#: gui/options.cpp:799
+#: gui/options.cpp:842
msgid "Don't use General MIDI music"
msgstr "No usar música General MIDI"
-#: gui/options.cpp:810 gui/options.cpp:871
+#: gui/options.cpp:853 gui/options.cpp:915
msgid "Use first available device"
msgstr "Utilizar el primer dispositivo disponible"
-#: gui/options.cpp:822
+#: gui/options.cpp:865
msgid "SoundFont:"
msgstr "SoundFont:"
-#: gui/options.cpp:822 gui/options.cpp:824 gui/options.cpp:825
+#: gui/options.cpp:865 gui/options.cpp:867 gui/options.cpp:868
msgid "SoundFont is supported by some audio cards, Fluidsynth and Timidity"
msgstr ""
"SoundFont está soportado por algunas tarjetas de sonido, además de "
"Fluidsynth y Timidity"
-#: gui/options.cpp:824
+#: gui/options.cpp:867
msgctxt "lowres"
msgid "SoundFont:"
msgstr "SoundFont:"
-#: gui/options.cpp:829
+#: gui/options.cpp:873
msgid "Mixed AdLib/MIDI mode"
msgstr "Modo AdLib/MIDI"
-#: gui/options.cpp:829
+#: gui/options.cpp:873
msgid "Use both MIDI and AdLib sound generation"
msgstr "Usar tanto MIDI como AdLib en la generación de sonido"
-#: gui/options.cpp:832
+#: gui/options.cpp:876
msgid "MIDI gain:"
msgstr "Ganancia MIDI:"
-#: gui/options.cpp:842
+#: gui/options.cpp:886
msgid "MT-32 Device:"
msgstr "Disp. MT-32:"
-#: gui/options.cpp:842
+#: gui/options.cpp:886
msgid "Specifies default sound device for Roland MT-32/LAPC1/CM32l/CM64 output"
msgstr ""
"Especifica el dispositivo de sonido para la salida Roland MT-32/LAPC1/CM32l/"
"CM64 por defecto"
-#: gui/options.cpp:847
+#: gui/options.cpp:891
msgid "True Roland MT-32 (disable GM emulation)"
msgstr "Roland MT-32 auténtica (desactivar emulación GM)"
-#: gui/options.cpp:847 gui/options.cpp:849
+#: gui/options.cpp:891 gui/options.cpp:893
msgid ""
"Check if you want to use your real hardware Roland-compatible sound device "
"connected to your computer"
@@ -737,191 +737,191 @@ msgstr ""
"Marcar si se quiere usar un dispositivo de sonido real conectado al "
"ordenador y compatible con Roland"
-#: gui/options.cpp:849
+#: gui/options.cpp:893
msgctxt "lowres"
msgid "True Roland MT-32 (no GM emulation)"
msgstr "Roland MT-32 real (sin emulación GM)"
-#: gui/options.cpp:852
+#: gui/options.cpp:896
msgid "Enable Roland GS Mode"
msgstr "Activar modo Roland GS"
-#: gui/options.cpp:852
+#: gui/options.cpp:896
msgid "Turns off General MIDI mapping for games with Roland MT-32 soundtrack"
msgstr "Desactiva la conversión General MIDI en juegos con sonido Roland MT-32"
-#: gui/options.cpp:861
+#: gui/options.cpp:905
msgid "Don't use Roland MT-32 music"
msgstr "No usar música Roland MT-32"
-#: gui/options.cpp:888
+#: gui/options.cpp:932
msgid "Text and Speech:"
msgstr "Texto y voces:"
-#: gui/options.cpp:892 gui/options.cpp:902
+#: gui/options.cpp:936 gui/options.cpp:946
msgid "Speech"
msgstr "Voces"
-#: gui/options.cpp:893 gui/options.cpp:903
+#: gui/options.cpp:937 gui/options.cpp:947
msgid "Subtitles"
msgstr "Subtítulos"
-#: gui/options.cpp:894
+#: gui/options.cpp:938
msgid "Both"
msgstr "Ambos"
-#: gui/options.cpp:896
+#: gui/options.cpp:940
msgid "Subtitle speed:"
msgstr "Vel. de subtítulos:"
-#: gui/options.cpp:898
+#: gui/options.cpp:942
msgctxt "lowres"
msgid "Text and Speech:"
msgstr "Texto y voces:"
-#: gui/options.cpp:902
+#: gui/options.cpp:946
msgid "Spch"
msgstr "Voz"
-#: gui/options.cpp:903
+#: gui/options.cpp:947
msgid "Subs"
msgstr "Subt"
-#: gui/options.cpp:904
+#: gui/options.cpp:948
msgctxt "lowres"
msgid "Both"
msgstr "V&S"
-#: gui/options.cpp:904
+#: gui/options.cpp:948
msgid "Show subtitles and play speech"
msgstr "Reproducir voces y subtítulos"
-#: gui/options.cpp:906
+#: gui/options.cpp:950
msgctxt "lowres"
msgid "Subtitle speed:"
msgstr "Vel. de subt.:"
-#: gui/options.cpp:922
+#: gui/options.cpp:966
msgid "Music volume:"
msgstr "Música:"
-#: gui/options.cpp:924
+#: gui/options.cpp:968
msgctxt "lowres"
msgid "Music volume:"
msgstr "Música:"
-#: gui/options.cpp:931
+#: gui/options.cpp:975
msgid "Mute All"
msgstr "Silenciar"
-#: gui/options.cpp:934
+#: gui/options.cpp:978
msgid "SFX volume:"
msgstr "Efectos:"
-#: gui/options.cpp:934 gui/options.cpp:936 gui/options.cpp:937
+#: gui/options.cpp:978 gui/options.cpp:980 gui/options.cpp:981
msgid "Special sound effects volume"
msgstr "Volumen de los efectos de sonido"
-#: gui/options.cpp:936
+#: gui/options.cpp:980
msgctxt "lowres"
msgid "SFX volume:"
msgstr "Efectos:"
-#: gui/options.cpp:944
+#: gui/options.cpp:988
msgid "Speech volume:"
msgstr "Voces:"
-#: gui/options.cpp:946
+#: gui/options.cpp:990
msgctxt "lowres"
msgid "Speech volume:"
msgstr "Voces:"
-#: gui/options.cpp:1085
+#: gui/options.cpp:1156
msgid "Theme Path:"
msgstr "Temas:"
-#: gui/options.cpp:1087
+#: gui/options.cpp:1158
msgctxt "lowres"
msgid "Theme Path:"
msgstr "Temas:"
-#: gui/options.cpp:1091 gui/options.cpp:1093 gui/options.cpp:1094
+#: gui/options.cpp:1164 gui/options.cpp:1166 gui/options.cpp:1167
msgid "Specifies path to additional data used by all games or ScummVM"
msgstr "Especifica el directorio adicional usado por los juegos y ScummVM"
-#: gui/options.cpp:1098
+#: gui/options.cpp:1173
msgid "Plugins Path:"
msgstr "Plugins:"
-#: gui/options.cpp:1100
+#: gui/options.cpp:1175
msgctxt "lowres"
msgid "Plugins Path:"
msgstr "Plugins:"
-#: gui/options.cpp:1109
+#: gui/options.cpp:1184
msgid "Misc"
msgstr "Otras"
-#: gui/options.cpp:1111
+#: gui/options.cpp:1186
msgctxt "lowres"
msgid "Misc"
msgstr "Otras"
-#: gui/options.cpp:1113
+#: gui/options.cpp:1188
msgid "Theme:"
msgstr "Tema:"
-#: gui/options.cpp:1117
+#: gui/options.cpp:1192
msgid "GUI Renderer:"
msgstr "Interfaz:"
-#: gui/options.cpp:1129
+#: gui/options.cpp:1204
msgid "Autosave:"
msgstr "Autoguardado:"
-#: gui/options.cpp:1131
+#: gui/options.cpp:1206
msgctxt "lowres"
msgid "Autosave:"
msgstr "Autoguardado:"
-#: gui/options.cpp:1139
+#: gui/options.cpp:1214
msgid "Keys"
msgstr "Teclas"
-#: gui/options.cpp:1146
+#: gui/options.cpp:1221
msgid "GUI Language:"
msgstr "Idioma:"
-#: gui/options.cpp:1146
+#: gui/options.cpp:1221
msgid "Language of ScummVM GUI"
msgstr "Idioma de la interfaz de ScummVM"
-#: gui/options.cpp:1295
+#: gui/options.cpp:1372
msgid "You have to restart ScummVM before your changes will take effect."
msgstr "Tienes que reiniciar ScummVM para que los cambios surjan efecto."
-#: gui/options.cpp:1308
+#: gui/options.cpp:1385
msgid "Select directory for savegames"
msgstr "Selecciona el directorio de guardado"
-#: gui/options.cpp:1315
+#: gui/options.cpp:1392
msgid "The chosen directory cannot be written to. Please select another one."
msgstr ""
"No se puede escribir en el directorio elegido. Por favor, selecciona otro."
-#: gui/options.cpp:1324
+#: gui/options.cpp:1401
msgid "Select directory for GUI themes"
msgstr "Selecciona el directorio de temas"
-#: gui/options.cpp:1334
+#: gui/options.cpp:1411
msgid "Select directory for extra files"
msgstr "Selecciona el directorio adicional"
-#: gui/options.cpp:1345
+#: gui/options.cpp:1422
msgid "Select directory for plugins"
msgstr "Selecciona el directorio de plugins"
-#: gui/options.cpp:1389
+#: gui/options.cpp:1475
msgid ""
"The theme you selected does not support your current language. If you want "
"to use this theme you need to switch to another language first."
@@ -969,60 +969,64 @@ msgstr "Partida sin nombre"
msgid "Select a Theme"
msgstr "Selecciona un tema"
-#: gui/ThemeEngine.cpp:328
+#: gui/ThemeEngine.cpp:333
msgid "Disabled GFX"
msgstr "GFX desactivados"
-#: gui/ThemeEngine.cpp:328
+#: gui/ThemeEngine.cpp:333
msgctxt "lowres"
msgid "Disabled GFX"
msgstr "GFX desactivados"
-#: gui/ThemeEngine.cpp:329
+#: gui/ThemeEngine.cpp:334
msgid "Standard Renderer (16bpp)"
msgstr "Estándar (16bpp)"
-#: gui/ThemeEngine.cpp:329
+#: gui/ThemeEngine.cpp:334
msgid "Standard (16bpp)"
msgstr "Estándar (16bpp)"
-#: gui/ThemeEngine.cpp:331
+#: gui/ThemeEngine.cpp:336
msgid "Antialiased Renderer (16bpp)"
msgstr "Suavizado (16bpp)"
-#: gui/ThemeEngine.cpp:331
+#: gui/ThemeEngine.cpp:336
msgid "Antialiased (16bpp)"
msgstr "Suavizado (16bpp)"
+#: gui/widget.cpp:312 gui/widget.cpp:314 gui/widget.cpp:320 gui/widget.cpp:322
+msgid "Clear value"
+msgstr "Eliminar valor"
+
#: base/main.cpp:203
#, c-format
msgid "Engine does not support debug level '%s'"
msgstr "El motor no soporta el nivel de debug '%s'"
-#: base/main.cpp:271
+#: base/main.cpp:275
msgid "Menu"
msgstr "Menú"
-#: base/main.cpp:274 backends/platform/symbian/src/SymbianActions.cpp:45
+#: base/main.cpp:278 backends/platform/symbian/src/SymbianActions.cpp:45
#: backends/platform/wince/CEActionsPocket.cpp:45
#: backends/platform/wince/CEActionsSmartphone.cpp:46
msgid "Skip"
msgstr "Saltar"
-#: base/main.cpp:277 backends/platform/symbian/src/SymbianActions.cpp:50
+#: base/main.cpp:281 backends/platform/symbian/src/SymbianActions.cpp:50
#: backends/platform/wince/CEActionsPocket.cpp:42
msgid "Pause"
msgstr "Pausar"
-#: base/main.cpp:280
+#: base/main.cpp:284
msgid "Skip line"
msgstr "Saltar frase"
-#: base/main.cpp:439
+#: base/main.cpp:455
msgid "Error running game:"
msgstr "Error al ejecutar el juego:"
-#: base/main.cpp:463
+#: base/main.cpp:479
msgid "Could not find any engine capable of running the selected game"
msgstr "No se ha podido encontrar ningún motor capaz de ejecutar el juego"
@@ -1090,25 +1094,6 @@ msgstr "Cancel·lat per l'usuari"
msgid "Unknown error"
msgstr "Error desconocido"
-#. I18N: Hercules is graphics card name
-#: common/util.cpp:275
-msgid "Hercules Green"
-msgstr "Hercules verde"
-
-#: common/util.cpp:276
-msgid "Hercules Amber"
-msgstr "Hercules ámbar"
-
-#: common/util.cpp:283
-msgctxt "lowres"
-msgid "Hercules Green"
-msgstr "Hercules verde"
-
-#: common/util.cpp:284
-msgctxt "lowres"
-msgid "Hercules Amber"
-msgstr "Hercules ámbar"
-
#: engines/advancedDetector.cpp:296
#, c-format
msgid "The game in '%s' seems to be unknown."
@@ -1156,12 +1141,12 @@ msgid "~R~eturn to Launcher"
msgstr "~V~olver al lanzador"
#: engines/dialogs.cpp:116 engines/cruise/menu.cpp:214
-#: engines/sci/engine/kfile.cpp:578
+#: engines/sci/engine/kfile.cpp:566
msgid "Save game:"
msgstr "Guardar partida"
#: engines/dialogs.cpp:116 engines/scumm/dialogs.cpp:187
-#: engines/cruise/menu.cpp:214 engines/sci/engine/kfile.cpp:578
+#: engines/cruise/menu.cpp:214 engines/sci/engine/kfile.cpp:566
#: backends/platform/symbian/src/SymbianActions.cpp:44
#: backends/platform/wince/CEActionsPocket.cpp:43
#: backends/platform/wince/CEActionsPocket.cpp:267
@@ -1180,37 +1165,47 @@ msgstr ""
"consulta el archivo README para encontrar información básica e instrucciones "
"para obtener más ayuda."
-#: engines/dialogs.cpp:316 engines/mohawk/dialogs.cpp:109
+#: engines/dialogs.cpp:243
+#, fuzzy, c-format
+msgid ""
+"Gamestate save failed (%s)! Please consult the README for basic information, "
+"and for instructions on how to obtain further assistance."
+msgstr ""
+"Lo sentimos, aún no hay ayuda disponible para este juego. Por favor, "
+"consulta el archivo README para encontrar información básica e instrucciones "
+"para obtener más ayuda."
+
+#: engines/dialogs.cpp:321 engines/mohawk/dialogs.cpp:109
#: engines/mohawk/dialogs.cpp:174
msgid "~O~K"
msgstr "~S~í"
-#: engines/dialogs.cpp:317 engines/mohawk/dialogs.cpp:110
+#: engines/dialogs.cpp:322 engines/mohawk/dialogs.cpp:110
#: engines/mohawk/dialogs.cpp:175
msgid "~C~ancel"
msgstr "~C~ancelar"
-#: engines/dialogs.cpp:320
+#: engines/dialogs.cpp:325
msgid "~K~eys"
msgstr "~T~eclas"
-#: engines/engine.cpp:233
+#: engines/engine.cpp:235
msgid "Could not initialize color format."
msgstr "No se ha podido iniciar el formato de color."
-#: engines/engine.cpp:241
+#: engines/engine.cpp:243
msgid "Could not switch to video mode: '"
msgstr "No se ha podido cambiar al modo de video: '"
-#: engines/engine.cpp:250
+#: engines/engine.cpp:252
msgid "Could not apply aspect ratio setting."
msgstr "No se ha podido aplicar el ajuste de corrección de aspecto"
-#: engines/engine.cpp:255
+#: engines/engine.cpp:257
msgid "Could not apply fullscreen setting."
msgstr "No se ha podido aplicar el ajuste de pantalla completa."
-#: engines/engine.cpp:355
+#: engines/engine.cpp:357
msgid ""
"You appear to be playing this game directly\n"
"from the CD. This is known to cause problems,\n"
@@ -1224,7 +1219,7 @@ msgstr ""
"copiar los archivos del juego al disco duro.\n"
"Consulta el archivo README para más detalles."
-#: engines/engine.cpp:366
+#: engines/engine.cpp:368
msgid ""
"This game has audio tracks in its disk. These\n"
"tracks need to be ripped from the disk using\n"
@@ -1238,7 +1233,17 @@ msgstr ""
"poder escuchar la música del juego.\n"
"Consulta el archivo README para más detalles."
-#: engines/engine.cpp:433
+#: engines/engine.cpp:426
+#, fuzzy, c-format
+msgid ""
+"Gamestate load failed (%s)! Please consult the README for basic information, "
+"and for instructions on how to obtain further assistance."
+msgstr ""
+"Lo sentimos, aún no hay ayuda disponible para este juego. Por favor, "
+"consulta el archivo README para encontrar información básica e instrucciones "
+"para obtener más ayuda."
+
+#: engines/engine.cpp:439
msgid ""
"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 "
@@ -1248,7 +1253,7 @@ msgstr ""
"ScummVM. Por lo tanto, puede que sea inestable, y que las partidas que "
"guardes no funcionen en versiones futuras de ScummVM."
-#: engines/engine.cpp:436
+#: engines/engine.cpp:442
msgid "Start anyway"
msgstr "Jugar de todos modos"
@@ -1276,12 +1281,12 @@ msgstr "Juego pausado. Pulsa Espacio para continuar."
#. Will react to J as 'Yes'
#: engines/scumm/dialogs.cpp:182
msgid "Are you sure you want to restart? (Y/N)"
-msgstr "¿Seguro que quieres reiniciar? (S/N)"
+msgstr "¿Seguro que quieres reiniciar? (S/N)S"
#. I18N: you may specify 'Yes' symbol at the end of the line. See previous comment
#: engines/scumm/dialogs.cpp:184
msgid "Are you sure you want to quit? (Y/N)"
-msgstr "¿Seguro que quieres salir? (S/N)"
+msgstr "¿Seguro que quieres salir? (S/N)S"
#: engines/scumm/dialogs.cpp:189
msgid "Play"
@@ -1292,7 +1297,7 @@ msgstr "Jugar"
#: backends/platform/symbian/src/SymbianActions.cpp:52
#: backends/platform/wince/CEActionsPocket.cpp:44
#: backends/platform/wince/CEActionsSmartphone.cpp:52
-#: backends/events/default/default-events.cpp:244
+#: backends/events/default/default-events.cpp:213
msgid "Quit"
msgstr "Salir"
@@ -1366,6 +1371,27 @@ msgctxt "lowres"
msgid "Speech & Subs"
msgstr "Voces y sub."
+#: engines/scumm/dialogs.cpp:653
+msgid "Select a Proficiency Level."
+msgstr ""
+
+#: engines/scumm/dialogs.cpp:655
+msgid "Refer to your Loom(TM) manual for help."
+msgstr ""
+
+#: engines/scumm/dialogs.cpp:658
+#, fuzzy
+msgid "Standard"
+msgstr "Estándar (16bpp)"
+
+#: engines/scumm/dialogs.cpp:659
+msgid "Practice"
+msgstr ""
+
+#: engines/scumm/dialogs.cpp:660
+msgid "Expert"
+msgstr ""
+
#: engines/scumm/help.cpp:73
msgid "Common keyboard commands:"
msgstr "Comandos básicos de teclado:"
@@ -1879,7 +1905,7 @@ msgstr "Volar a la derecha"
msgid "Fly to lower right"
msgstr "Volar abajo y a la derecha"
-#: engines/scumm/scumm.cpp:1774
+#: engines/scumm/scumm.cpp:1773
#, c-format
msgid ""
"Native MIDI support requires the Roland Upgrade from LucasArts,\n"
@@ -1888,7 +1914,7 @@ msgstr ""
"El soporte MIDI nativo requiere la actualización Roland de LucasArts,\n"
"pero %s no está disponible. Se usará AdLib."
-#: engines/scumm/scumm.cpp:2264 engines/agos/saveload.cpp:189
+#: engines/scumm/scumm.cpp:2271 engines/agos/saveload.cpp:189
#, c-format
msgid ""
"Failed to save game state to file:\n"
@@ -1899,7 +1925,7 @@ msgstr ""
"\n"
"%s"
-#: engines/scumm/scumm.cpp:2271 engines/agos/saveload.cpp:154
+#: engines/scumm/scumm.cpp:2278 engines/agos/saveload.cpp:154
#, c-format
msgid ""
"Failed to load game state from file:\n"
@@ -1910,7 +1936,7 @@ msgstr ""
"\n"
"%s"
-#: engines/scumm/scumm.cpp:2283 engines/agos/saveload.cpp:197
+#: engines/scumm/scumm.cpp:2290 engines/agos/saveload.cpp:197
#, c-format
msgid ""
"Successfully saved game state in file:\n"
@@ -1921,7 +1947,7 @@ msgstr ""
"\n"
"%s"
-#: engines/scumm/scumm.cpp:2498
+#: engines/scumm/scumm.cpp:2505
msgid ""
"Usually, Maniac Mansion would start now. But ScummVM doesn't do that yet. To "
"play it, go to 'Add Game' in the ScummVM start menu and select the 'Maniac' "
@@ -1957,11 +1983,11 @@ msgstr "~M~enú principal"
msgid "~W~ater Effect Enabled"
msgstr "Efecto ag~u~a activado"
-#: engines/sci/engine/kfile.cpp:685
+#: engines/sci/engine/kfile.cpp:673
msgid "Restore game:"
msgstr "Cargar partida:"
-#: engines/sci/engine/kfile.cpp:685
+#: engines/sci/engine/kfile.cpp:673
msgid "Restore"
msgstr "Cargar"
@@ -1971,11 +1997,11 @@ msgid "Cutscene file '%s' not found!"
msgstr "No se ha encontrado el vídeo '%s'"
#: engines/gob/inter_playtoons.cpp:256 engines/gob/inter_v2.cpp:1283
-#: engines/tinsel/saveload.cpp:482
+#: engines/tinsel/saveload.cpp:502
msgid "Failed to load game state from file."
msgstr "Fallo al cargar el estado del juego desde el archivo."
-#: engines/gob/inter_v2.cpp:1353 engines/tinsel/saveload.cpp:560
+#: engines/gob/inter_v2.cpp:1353 engines/tinsel/saveload.cpp:515
msgid "Failed to save game state to file."
msgstr "Fallo al guardar el estado del juego en el archivo."
@@ -1987,6 +2013,60 @@ msgstr "Fallo al borrar el archivo."
msgid "Failed to save game"
msgstr "Fallo al guardar la partida"
+#: engines/kyra/lol.cpp:478
+msgid "Attack 1"
+msgstr ""
+
+#: engines/kyra/lol.cpp:479
+msgid "Attack 2"
+msgstr ""
+
+#: engines/kyra/lol.cpp:480
+msgid "Attack 3"
+msgstr ""
+
+#: engines/kyra/lol.cpp:481
+msgid "Move Forward"
+msgstr ""
+
+#: engines/kyra/lol.cpp:482
+msgid "Move Back"
+msgstr ""
+
+#: engines/kyra/lol.cpp:483
+msgid "Slide Left"
+msgstr ""
+
+#: engines/kyra/lol.cpp:484
+#, fuzzy
+msgid "Slide Right"
+msgstr "Derecha"
+
+#: engines/kyra/lol.cpp:485
+#, fuzzy
+msgid "Turn Left"
+msgstr "Apagar"
+
+#: engines/kyra/lol.cpp:486
+#, fuzzy
+msgid "Turn Right"
+msgstr "Derecha"
+
+#: engines/kyra/lol.cpp:487
+#, fuzzy
+msgid "Rest"
+msgstr "Cargar"
+
+#: engines/kyra/lol.cpp:488
+#, fuzzy
+msgid "Options"
+msgstr "~O~pciones"
+
+#: engines/kyra/lol.cpp:489
+#, fuzzy
+msgid "Choose Spell"
+msgstr "Aceptar"
+
#: engines/kyra/sound_midi.cpp:475
msgid ""
"You appear to be using a General MIDI device,\n"
@@ -2001,10 +2081,6 @@ msgstr ""
"a los de General MIDI, pero es posible que algunas\n"
"de las pistas no se reproduzcan correctamente."
-#: engines/m4/m4_menus.cpp:138
-msgid "Save game failed!"
-msgstr "No se ha podido guardar la partida."
-
#: engines/sky/compact.cpp:130
msgid ""
"Unable to find \"sky.cpt\" file!\n"
@@ -2021,16 +2097,21 @@ msgstr ""
"El archivo \"sky.cpt\" tiene un tamaño incorrecto.\n"
"Por favor, vuelve a bajarlo de www.scummvm.org"
-#: engines/sword1/animation.cpp:344 engines/sword2/animation.cpp:379
+#: engines/sword1/animation.cpp:539
+#, c-format
+msgid "PSX stream cutscene '%s' cannot be played in paletted mode"
+msgstr ""
+
+#: engines/sword1/animation.cpp:560 engines/sword2/animation.cpp:455
msgid "DXA cutscenes found but ScummVM has been built without zlib support"
msgstr ""
"Se han encontrado vídeos DXA, pero se ha compilado ScummVM sin soporte zlib"
-#: engines/sword1/animation.cpp:354 engines/sword2/animation.cpp:389
+#: engines/sword1/animation.cpp:570 engines/sword2/animation.cpp:465
msgid "MPEG2 cutscenes are no longer supported"
msgstr "Los vídeos MPEG2 ya no son compatibles"
-#: engines/sword1/animation.cpp:359 engines/sword2/animation.cpp:397
+#: engines/sword1/animation.cpp:576 engines/sword2/animation.cpp:473
#, c-format
msgid "Cutscene '%s' not found"
msgstr "No se ha encontrado el vídeo '%s'"
@@ -2074,6 +2155,13 @@ msgstr "Conservar la nueva"
msgid "This is the end of the Broken Sword 1 Demo"
msgstr "Este es el final de la demo de Broken Sword 1"
+#: engines/sword2/animation.cpp:435
+#, fuzzy
+msgid ""
+"PSX cutscenes found but ScummVM has been built without RGB color support"
+msgstr ""
+"Se han encontrado vídeos DXA, pero se ha compilado ScummVM sin soporte zlib"
+
#: engines/parallaction/saveload.cpp:133
#, c-format
msgid ""
@@ -2132,7 +2220,7 @@ msgstr "Emulador OPL de MAME"
msgid "DOSBox OPL emulator"
msgstr "Emulador OPL de DOSBox"
-#: audio/mididrv.cpp:205
+#: audio/mididrv.cpp:209
#, c-format
msgid ""
"The selected audio device '%s' was not found (e.g. might be turned off or "
@@ -2141,12 +2229,12 @@ msgstr ""
"El dispositivo de sonido seleccionado, '%s', no se ha podido encontrar "
"(puede estar apagado o desconectado)."
-#: audio/mididrv.cpp:205 audio/mididrv.cpp:217 audio/mididrv.cpp:253
-#: audio/mididrv.cpp:268
+#: audio/mididrv.cpp:209 audio/mididrv.cpp:221 audio/mididrv.cpp:257
+#: audio/mididrv.cpp:272
msgid "Attempting to fall back to the next available device..."
msgstr "Recorriendo al siguiente dispositivo disponible..."
-#: audio/mididrv.cpp:217
+#: audio/mididrv.cpp:221
#, c-format
msgid ""
"The selected audio device '%s' cannot be used. See log file for more "
@@ -2155,7 +2243,7 @@ msgstr ""
"El dispositivo de sonido seleccionado, '%s', no se puede utilizar. Consulta "
"el registro para más información."
-#: audio/mididrv.cpp:253
+#: audio/mididrv.cpp:257
#, c-format
msgid ""
"The preferred audio device '%s' was not found (e.g. might be turned off or "
@@ -2164,7 +2252,7 @@ msgstr ""
"El dispositivo de sonido preferido, '%s', no se ha podido encontrar (puede "
"estar apagado o desconectado)."
-#: audio/mididrv.cpp:268
+#: audio/mididrv.cpp:272
#, c-format
msgid ""
"The preferred audio device '%s' cannot be used. See log file for more "
@@ -2181,7 +2269,7 @@ msgstr "Sin música"
msgid "Amiga Audio Emulator"
msgstr "Emulador de Amiga Audio"
-#: audio/softsynth/adlib.cpp:1594
+#: audio/softsynth/adlib.cpp:1593
msgid "AdLib Emulator"
msgstr "Emulador de AdLib"
@@ -2193,11 +2281,11 @@ msgstr "Emulador de Apple II GS (NO IMPLEMENTADO)"
msgid "C64 Audio Emulator"
msgstr "Emulador de C64 Audio"
-#: audio/softsynth/mt32.cpp:329
+#: audio/softsynth/mt32.cpp:293
msgid "Initializing MT-32 Emulator"
msgstr "Iniciando el emulador de MT-32"
-#: audio/softsynth/mt32.cpp:543
+#: audio/softsynth/mt32.cpp:512
msgid "MT-32 Emulator"
msgstr "Emulador de MT-32"
@@ -2213,15 +2301,24 @@ msgstr "Emulador de IBM PCjr"
msgid "Keymap:"
msgstr "Asignación de teclas:"
-#: backends/keymapper/remap-dialog.cpp:64
+#: backends/keymapper/remap-dialog.cpp:66
+#, fuzzy
+msgid " (Effective)"
+msgstr "(Activa)"
+
+#: backends/keymapper/remap-dialog.cpp:106
msgid " (Active)"
msgstr "(Activa)"
-#: backends/keymapper/remap-dialog.cpp:98
+#: backends/keymapper/remap-dialog.cpp:106
+msgid " (Blocked)"
+msgstr ""
+
+#: backends/keymapper/remap-dialog.cpp:119
msgid " (Global)"
msgstr "(General)"
-#: backends/keymapper/remap-dialog.cpp:108
+#: backends/keymapper/remap-dialog.cpp:127
msgid " (Game)"
msgstr "(Juego)"
@@ -2301,40 +2398,64 @@ msgstr "Sonido de alta calidad (más lento) (reinicio)"
msgid "Disable power off"
msgstr "Desactivar apagado"
-#: backends/platform/iphone/osys_events.cpp:338
+#: backends/platform/iphone/osys_events.cpp:301
msgid "Mouse-click-and-drag mode enabled."
msgstr "Modo clic-de-ratón-y-arrastrar activado."
-#: backends/platform/iphone/osys_events.cpp:340
+#: backends/platform/iphone/osys_events.cpp:303
msgid "Mouse-click-and-drag mode disabled."
msgstr "Modo clic-de-ratón-y-arrastrar desactivado."
-#: backends/platform/iphone/osys_events.cpp:351
+#: backends/platform/iphone/osys_events.cpp:314
msgid "Touchpad mode enabled."
msgstr "Modo Touchpad activado."
-#: backends/platform/iphone/osys_events.cpp:353
+#: backends/platform/iphone/osys_events.cpp:316
msgid "Touchpad mode disabled."
msgstr "Modo Touchpad desactivado."
-#: backends/platform/sdl/macosx/appmenu_osx.mm:67
+#: backends/platform/maemo/maemo.cpp:205
+msgid "Click Mode"
+msgstr ""
+
+#: backends/platform/maemo/maemo.cpp:211
+#: backends/platform/symbian/src/SymbianActions.cpp:42
+#: backends/platform/wince/CEActionsPocket.cpp:60
+#: backends/platform/wince/CEActionsSmartphone.cpp:43
+#: backends/platform/bada/form.cpp:281
+msgid "Left Click"
+msgstr "Clic izquierdo"
+
+#: backends/platform/maemo/maemo.cpp:214
+#, fuzzy
+msgid "Middle Click"
+msgstr "Objeto izquierdo del medio"
+
+#: backends/platform/maemo/maemo.cpp:217
+#: backends/platform/symbian/src/SymbianActions.cpp:43
+#: backends/platform/wince/CEActionsSmartphone.cpp:44
+#: backends/platform/bada/form.cpp:273
+msgid "Right Click"
+msgstr "Clic derecho"
+
+#: backends/platform/sdl/macosx/appmenu_osx.mm:78
msgid "Hide ScummVM"
-msgstr "Oculta ScummVM"
+msgstr "Ocultar ScummVM"
-#: backends/platform/sdl/macosx/appmenu_osx.mm:70
+#: backends/platform/sdl/macosx/appmenu_osx.mm:83
msgid "Hide Others"
msgstr "Ocultar otros"
-#: backends/platform/sdl/macosx/appmenu_osx.mm:74
+#: backends/platform/sdl/macosx/appmenu_osx.mm:88
msgid "Show All"
msgstr "Mostrar todo"
-#: backends/platform/sdl/macosx/appmenu_osx.mm:92
-#: backends/platform/sdl/macosx/appmenu_osx.mm:99
+#: backends/platform/sdl/macosx/appmenu_osx.mm:110
+#: backends/platform/sdl/macosx/appmenu_osx.mm:121
msgid "Window"
msgstr "Ventana"
-#: backends/platform/sdl/macosx/appmenu_osx.mm:95
+#: backends/platform/sdl/macosx/appmenu_osx.mm:115
msgid "Minimize"
msgstr "Minimizar"
@@ -2348,12 +2469,12 @@ msgid "Normal (no scaling)"
msgstr "Normal"
#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2147
-#: backends/graphics/openglsdl/openglsdl-graphics.cpp:537
+#: backends/graphics/openglsdl/openglsdl-graphics.cpp:533
msgid "Enabled aspect ratio correction"
msgstr "Activar la corrección de aspecto"
#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2153
-#: backends/graphics/openglsdl/openglsdl-graphics.cpp:542
+#: backends/graphics/openglsdl/openglsdl-graphics.cpp:538
msgid "Disabled aspect ratio correction"
msgstr "Desactivar la corrección de aspecto"
@@ -2362,7 +2483,7 @@ msgid "Active graphics filter:"
msgstr "Filtro de gráficos activo:"
#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2250
-#: backends/graphics/openglsdl/openglsdl-graphics.cpp:481
+#: backends/graphics/openglsdl/openglsdl-graphics.cpp:477
msgid "Windowed mode"
msgstr "Modo ventana"
@@ -2386,11 +2507,11 @@ msgstr "Modo de vídeo actual"
msgid "Current scale"
msgstr "Escala actual"
-#: backends/graphics/openglsdl/openglsdl-graphics.cpp:562
+#: backends/graphics/openglsdl/openglsdl-graphics.cpp:558
msgid "Active filter mode: Linear"
msgstr "Modo de filtro activo: lineal"
-#: backends/graphics/openglsdl/openglsdl-graphics.cpp:564
+#: backends/graphics/openglsdl/openglsdl-graphics.cpp:560
msgid "Active filter mode: Nearest"
msgstr "Modo de filtro activo: el más cercano"
@@ -2414,19 +2535,6 @@ msgstr "Izquierda"
msgid "Right"
msgstr "Derecha"
-#: backends/platform/symbian/src/SymbianActions.cpp:42
-#: backends/platform/wince/CEActionsPocket.cpp:60
-#: backends/platform/wince/CEActionsSmartphone.cpp:43
-#: backends/platform/bada/form.cpp:281
-msgid "Left Click"
-msgstr "Clic izquierdo"
-
-#: backends/platform/symbian/src/SymbianActions.cpp:43
-#: backends/platform/wince/CEActionsSmartphone.cpp:44
-#: backends/platform/bada/form.cpp:273
-msgid "Right Click"
-msgstr "Clic derecho"
-
#: backends/platform/symbian/src/SymbianActions.cpp:46
#: backends/platform/wince/CEActionsSmartphone.cpp:47
msgid "Zone"
@@ -2716,15 +2824,15 @@ msgstr ""
"No olvides asignar una tecla a la acción 'Ocultar barra de tareas' para ver "
"todo el inventario"
-#: backends/events/default/default-events.cpp:222
+#: backends/events/default/default-events.cpp:191
msgid "Do you really want to return to the Launcher?"
msgstr "¿Seguro que quieres volver al Lanzador?"
-#: backends/events/default/default-events.cpp:222
+#: backends/events/default/default-events.cpp:191
msgid "Launcher"
msgstr "Lanzador"
-#: backends/events/default/default-events.cpp:244
+#: backends/events/default/default-events.cpp:213
msgid "Do you really want to quit?"
msgstr "¿Realmente quieres salir?"
@@ -2790,10 +2898,27 @@ msgstr "Mostrar el teclado numérico"
msgid "Control Mouse"
msgstr "Control del ratón"
-#: backends/events/maemosdl/maemosdl-events.cpp:121
+#: backends/events/maemosdl/maemosdl-events.cpp:192
msgid "Clicking Enabled"
msgstr "Clic activado"
-#: backends/events/maemosdl/maemosdl-events.cpp:121
+#: backends/events/maemosdl/maemosdl-events.cpp:192
msgid "Clicking Disabled"
msgstr "Clic desactivado"
+
+#~ msgid "Hercules Green"
+#~ msgstr "Hercules verde"
+
+#~ msgid "Hercules Amber"
+#~ msgstr "Hercules ámbar"
+
+#~ msgctxt "lowres"
+#~ msgid "Hercules Green"
+#~ msgstr "Hercules verde"
+
+#~ msgctxt "lowres"
+#~ msgid "Hercules Amber"
+#~ msgstr "Hercules ámbar"
+
+#~ msgid "Save game failed!"
+#~ msgstr "No se ha podido guardar la partida."
diff --git a/po/fr_FR.po b/po/fr_FR.po
index 1385f27ba6..d937777ea5 100644
--- a/po/fr_FR.po
+++ b/po/fr_FR.po
@@ -1,5 +1,5 @@
# French translation for ScummVM.
-# Copyright (C) 2010-2011 ScummVM Team
+# Copyright (C) 2010-2012 ScummVM Team
# This file is distributed under the same license as the ScummVM package.
# Thierry Crozat <criezy@scummvm.org>, 2011.
#
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: ScummVM 1.3.0svn\n"
"Report-Msgid-Bugs-To: scummvm-devel@lists.sf.net\n"
-"POT-Creation-Date: 2011-10-19 13:42+0100\n"
+"POT-Creation-Date: 2012-03-07 22:09+0000\n"
"PO-Revision-Date: 2011-10-23 14:52+0100\n"
"Last-Translator: Thierry Crozat <criezy@scummvm.org>\n"
"Language-Team: French <scummvm-devel@lists.sf.net>\n"
@@ -44,13 +44,13 @@ msgid "Go up"
msgstr "Remonter"
#: gui/browser.cpp:69 gui/chooser.cpp:45 gui/KeysDialog.cpp:43
-#: gui/launcher.cpp:312 gui/massadd.cpp:94 gui/options.cpp:1178
+#: gui/launcher.cpp:320 gui/massadd.cpp:94 gui/options.cpp:1253
#: gui/saveload.cpp:63 gui/saveload.cpp:155 gui/themebrowser.cpp:54
-#: engines/engine.cpp:436 engines/scumm/dialogs.cpp:190
+#: engines/engine.cpp:442 engines/scumm/dialogs.cpp:190
#: engines/sword1/control.cpp:865 engines/parallaction/saveload.cpp:281
#: backends/platform/wii/options.cpp:48
-#: backends/events/default/default-events.cpp:222
-#: backends/events/default/default-events.cpp:244
+#: backends/events/default/default-events.cpp:191
+#: backends/events/default/default-events.cpp:213
msgid "Cancel"
msgstr "Annuler"
@@ -58,25 +58,29 @@ msgstr "Annuler"
msgid "Choose"
msgstr "Choisir"
-#: gui/gui-manager.cpp:116 engines/scumm/help.cpp:125
+#: gui/gui-manager.cpp:115 engines/scumm/help.cpp:125
#: engines/scumm/help.cpp:140 engines/scumm/help.cpp:165
#: engines/scumm/help.cpp:191 engines/scumm/help.cpp:209
#: backends/keymapper/remap-dialog.cpp:52
msgid "Close"
msgstr "Fermer"
-#: gui/gui-manager.cpp:119
+#: gui/gui-manager.cpp:118
msgid "Mouse click"
msgstr "Clic de souris"
-#: gui/gui-manager.cpp:122 base/main.cpp:283
+#: gui/gui-manager.cpp:122 base/main.cpp:288
msgid "Display keyboard"
msgstr "Afficher le clavier"
-#: gui/gui-manager.cpp:125 base/main.cpp:286
+#: gui/gui-manager.cpp:126 base/main.cpp:292
msgid "Remap keys"
msgstr "Changer l'affectation des touches"
+#: gui/gui-manager.cpp:129 base/main.cpp:295
+msgid "Toggle FullScreen"
+msgstr "Basculer en plein écran"
+
#: gui/KeysDialog.h:36 gui/KeysDialog.cpp:145
msgid "Choose an action to map"
msgstr "Sélectionnez une action à affecter"
@@ -85,16 +89,17 @@ msgstr "Sélectionnez une action à affecter"
msgid "Map"
msgstr "Affecter"
-#: gui/KeysDialog.cpp:42 gui/launcher.cpp:313 gui/launcher.cpp:936
-#: gui/launcher.cpp:940 gui/massadd.cpp:91 gui/options.cpp:1179
-#: engines/engine.cpp:359 engines/engine.cpp:370 engines/scumm/dialogs.cpp:192
-#: engines/scumm/scumm.cpp:1776 engines/agos/animation.cpp:551
+#: gui/KeysDialog.cpp:42 gui/launcher.cpp:321 gui/launcher.cpp:960
+#: gui/launcher.cpp:964 gui/massadd.cpp:91 gui/options.cpp:1254
+#: engines/engine.cpp:361 engines/engine.cpp:372 engines/scumm/dialogs.cpp:192
+#: engines/scumm/scumm.cpp:1775 engines/agos/animation.cpp:551
#: engines/groovie/script.cpp:420 engines/sky/compact.cpp:131
-#: engines/sky/compact.cpp:141 engines/sword1/animation.cpp:344
-#: engines/sword1/animation.cpp:354 engines/sword1/animation.cpp:360
-#: engines/sword1/control.cpp:865 engines/sword1/logic.cpp:1633
-#: engines/sword2/animation.cpp:379 engines/sword2/animation.cpp:389
-#: engines/sword2/animation.cpp:398 engines/parallaction/saveload.cpp:281
+#: engines/sky/compact.cpp:141 engines/sword1/animation.cpp:539
+#: engines/sword1/animation.cpp:560 engines/sword1/animation.cpp:570
+#: engines/sword1/animation.cpp:577 engines/sword1/control.cpp:865
+#: engines/sword1/logic.cpp:1633 engines/sword2/animation.cpp:435
+#: engines/sword2/animation.cpp:455 engines/sword2/animation.cpp:465
+#: engines/sword2/animation.cpp:474 engines/parallaction/saveload.cpp:281
#: backends/platform/wii/options.cpp:47
#: backends/platform/wince/CELauncherDialog.cpp:54
msgid "OK"
@@ -122,15 +127,15 @@ msgstr "Selectionnez une action"
msgid "Press the key to associate"
msgstr "Appuyez sur la touche à associer"
-#: gui/launcher.cpp:165
+#: gui/launcher.cpp:170
msgid "Game"
msgstr "Jeu"
-#: gui/launcher.cpp:169
+#: gui/launcher.cpp:174
msgid "ID:"
msgstr "ID:"
-#: gui/launcher.cpp:169 gui/launcher.cpp:171 gui/launcher.cpp:172
+#: gui/launcher.cpp:174 gui/launcher.cpp:176 gui/launcher.cpp:177
msgid ""
"Short game identifier used for referring to savegames and running the game "
"from the command line"
@@ -138,29 +143,29 @@ msgstr ""
"ID compact du jeu utilisée pour identifier les sauvegardes et démarrer le "
"jeu depuis la ligne de commande"
-#: gui/launcher.cpp:171
+#: gui/launcher.cpp:176
msgctxt "lowres"
msgid "ID:"
msgstr "ID:"
-#: gui/launcher.cpp:176
+#: gui/launcher.cpp:181
msgid "Name:"
msgstr "Nom:"
-#: gui/launcher.cpp:176 gui/launcher.cpp:178 gui/launcher.cpp:179
+#: gui/launcher.cpp:181 gui/launcher.cpp:183 gui/launcher.cpp:184
msgid "Full title of the game"
msgstr "Nom complet du jeu"
-#: gui/launcher.cpp:178
+#: gui/launcher.cpp:183
msgctxt "lowres"
msgid "Name:"
msgstr "Nom:"
-#: gui/launcher.cpp:182
+#: gui/launcher.cpp:187
msgid "Language:"
msgstr "Langue:"
-#: gui/launcher.cpp:182 gui/launcher.cpp:183
+#: gui/launcher.cpp:187 gui/launcher.cpp:188
msgid ""
"Language of the game. This will not turn your Spanish game version into "
"English"
@@ -168,283 +173,281 @@ msgstr ""
"Langue du jeu. Cela ne traduira pas en anglais par magie votre version "
"espagnole du jeu."
-#: gui/launcher.cpp:184 gui/launcher.cpp:198 gui/options.cpp:74
-#: gui/options.cpp:708 gui/options.cpp:718 gui/options.cpp:1149
+#: gui/launcher.cpp:189 gui/launcher.cpp:203 gui/options.cpp:80
+#: gui/options.cpp:745 gui/options.cpp:758 gui/options.cpp:1224
#: audio/null.cpp:40
msgid "<default>"
msgstr "<defaut>"
-#: gui/launcher.cpp:194
+#: gui/launcher.cpp:199
msgid "Platform:"
msgstr "Plateforme:"
-#: gui/launcher.cpp:194 gui/launcher.cpp:196 gui/launcher.cpp:197
+#: gui/launcher.cpp:199 gui/launcher.cpp:201 gui/launcher.cpp:202
msgid "Platform the game was originally designed for"
msgstr "Plateforme pour laquelle votre jeu a été conçu"
-#: gui/launcher.cpp:196
+#: gui/launcher.cpp:201
msgctxt "lowres"
msgid "Platform:"
msgstr "Système:"
-#: gui/launcher.cpp:208 gui/options.cpp:1018 gui/options.cpp:1035
+#: gui/launcher.cpp:213 gui/options.cpp:1087 gui/options.cpp:1104
msgid "Graphics"
msgstr "Graphique"
-#: gui/launcher.cpp:208 gui/options.cpp:1018 gui/options.cpp:1035
+#: gui/launcher.cpp:213 gui/options.cpp:1087 gui/options.cpp:1104
msgid "GFX"
msgstr "GFX"
-#: gui/launcher.cpp:211
+#: gui/launcher.cpp:216
msgid "Override global graphic settings"
msgstr "Utiliser des réglages graphiques spécifiques à ce jeux"
-#: gui/launcher.cpp:213
+#: gui/launcher.cpp:218
msgctxt "lowres"
msgid "Override global graphic settings"
msgstr "Réglages spécifiques à ce jeux"
-#: gui/launcher.cpp:220 gui/options.cpp:1041
+#: gui/launcher.cpp:225 gui/options.cpp:1110
msgid "Audio"
msgstr "Audio"
-#: gui/launcher.cpp:223
+#: gui/launcher.cpp:228
msgid "Override global audio settings"
msgstr "Utiliser des réglages audio spécifiques à ce jeux"
-#: gui/launcher.cpp:225
+#: gui/launcher.cpp:230
msgctxt "lowres"
msgid "Override global audio settings"
msgstr "Réglages spécifiques à ce jeux"
-#: gui/launcher.cpp:234 gui/options.cpp:1046
+#: gui/launcher.cpp:239 gui/options.cpp:1115
msgid "Volume"
msgstr "Volume"
-#: gui/launcher.cpp:236 gui/options.cpp:1048
+#: gui/launcher.cpp:241 gui/options.cpp:1117
msgctxt "lowres"
msgid "Volume"
msgstr "Volume"
-#: gui/launcher.cpp:239
+#: gui/launcher.cpp:244
msgid "Override global volume settings"
msgstr "Utiliser des réglages de volume sonore spécifiques à ce jeux"
-#: gui/launcher.cpp:241
+#: gui/launcher.cpp:246
msgctxt "lowres"
msgid "Override global volume settings"
msgstr "Réglages spécifiques à ce jeux"
-#: gui/launcher.cpp:248 gui/options.cpp:1056
+#: gui/launcher.cpp:254 gui/options.cpp:1125
msgid "MIDI"
msgstr "MIDI"
-#: gui/launcher.cpp:251
+#: gui/launcher.cpp:257
msgid "Override global MIDI settings"
msgstr "Utiliser des réglages MIDI spécifiques à ce jeux"
-#: gui/launcher.cpp:253
+#: gui/launcher.cpp:259
msgctxt "lowres"
msgid "Override global MIDI settings"
msgstr "Réglages spécifiques à ce jeux"
-#: gui/launcher.cpp:263 gui/options.cpp:1062
+#: gui/launcher.cpp:268 gui/options.cpp:1131
msgid "MT-32"
msgstr "MT-32"
-#: gui/launcher.cpp:266
+#: gui/launcher.cpp:271
msgid "Override global MT-32 settings"
msgstr "Utiliser des réglages MT-32 spécifiques à ce jeux"
-#: gui/launcher.cpp:268
+#: gui/launcher.cpp:273
msgctxt "lowres"
msgid "Override global MT-32 settings"
msgstr "Réglages spécifiques à ce jeux"
-#: gui/launcher.cpp:279 gui/options.cpp:1069
+#: gui/launcher.cpp:282 gui/options.cpp:1138
msgid "Paths"
msgstr "Chemins"
-#: gui/launcher.cpp:281 gui/options.cpp:1071
+#: gui/launcher.cpp:284 gui/options.cpp:1140
msgctxt "lowres"
msgid "Paths"
msgstr "Chemins"
-#: gui/launcher.cpp:288
+#: gui/launcher.cpp:291
msgid "Game Path:"
msgstr "Chemin du Jeu:"
-#: gui/launcher.cpp:290
+#: gui/launcher.cpp:293
msgctxt "lowres"
msgid "Game Path:"
msgstr "Chemin du Jeu:"
-#: gui/launcher.cpp:295 gui/options.cpp:1091
+#: gui/launcher.cpp:298 gui/options.cpp:1164
msgid "Extra Path:"
msgstr "Extra:"
-#: gui/launcher.cpp:295 gui/launcher.cpp:297 gui/launcher.cpp:298
+#: gui/launcher.cpp:298 gui/launcher.cpp:300 gui/launcher.cpp:301
msgid "Specifies path to additional data used the game"
msgstr "Définie un chemin vers des données suplémentaires utilisées par le jeu"
-#: gui/launcher.cpp:297 gui/options.cpp:1093
+#: gui/launcher.cpp:300 gui/options.cpp:1166
msgctxt "lowres"
msgid "Extra Path:"
msgstr "Extra:"
-#: gui/launcher.cpp:302 gui/options.cpp:1079
+#: gui/launcher.cpp:307 gui/options.cpp:1148
msgid "Save Path:"
msgstr "Sauvegardes:"
-#: gui/launcher.cpp:302 gui/launcher.cpp:304 gui/launcher.cpp:305
-#: gui/options.cpp:1079 gui/options.cpp:1081 gui/options.cpp:1082
+#: gui/launcher.cpp:307 gui/launcher.cpp:309 gui/launcher.cpp:310
+#: gui/options.cpp:1148 gui/options.cpp:1150 gui/options.cpp:1151
msgid "Specifies where your savegames are put"
msgstr "Définie l'emplacement où les fichiers de sauvegarde sont créés"
-#: gui/launcher.cpp:304 gui/options.cpp:1081
+#: gui/launcher.cpp:309 gui/options.cpp:1150
msgctxt "lowres"
msgid "Save Path:"
msgstr "Sauvegardes:"
-#: gui/launcher.cpp:321 gui/launcher.cpp:404 gui/launcher.cpp:453
-#: gui/options.cpp:1088 gui/options.cpp:1094 gui/options.cpp:1101
-#: gui/options.cpp:1202 gui/options.cpp:1208 gui/options.cpp:1214
-#: gui/options.cpp:1222 gui/options.cpp:1246 gui/options.cpp:1250
-#: gui/options.cpp:1256 gui/options.cpp:1263 gui/options.cpp:1362
+#: gui/launcher.cpp:329 gui/launcher.cpp:416 gui/launcher.cpp:469
+#: gui/launcher.cpp:523 gui/options.cpp:1159 gui/options.cpp:1167
+#: gui/options.cpp:1176 gui/options.cpp:1283 gui/options.cpp:1289
+#: gui/options.cpp:1297 gui/options.cpp:1327 gui/options.cpp:1333
+#: gui/options.cpp:1340 gui/options.cpp:1433 gui/options.cpp:1436
+#: gui/options.cpp:1448
msgctxt "path"
msgid "None"
msgstr "Aucun"
-#: gui/launcher.cpp:326 gui/launcher.cpp:408
+#: gui/launcher.cpp:334 gui/launcher.cpp:422 gui/launcher.cpp:527
+#: gui/options.cpp:1277 gui/options.cpp:1321 gui/options.cpp:1439
#: backends/platform/wii/options.cpp:56
msgid "Default"
msgstr "Défaut"
-#: gui/launcher.cpp:446 gui/options.cpp:1356
+#: gui/launcher.cpp:462 gui/options.cpp:1442
msgid "Select SoundFont"
msgstr "Choisir une banque de sons"
-#: gui/launcher.cpp:465 gui/launcher.cpp:612
+#: gui/launcher.cpp:481 gui/launcher.cpp:636
msgid "Select directory with game data"
msgstr "Sélectionner le répertoire contenant les données du jeu"
-#: gui/launcher.cpp:483
+#: gui/launcher.cpp:499
msgid "Select additional game directory"
msgstr "Sélectionner un répertoire supplémentaire"
-#: gui/launcher.cpp:495
+#: gui/launcher.cpp:511
msgid "Select directory for saved games"
msgstr "Sélectionner le répertoire pour les sauvegardes"
-#: gui/launcher.cpp:514
+#: gui/launcher.cpp:538
msgid "This game ID is already taken. Please choose another one."
msgstr "Cet ID est déjà utilisé par un autre jeu. Choisissez en un autre svp."
-#: gui/launcher.cpp:555 engines/dialogs.cpp:110
+#: gui/launcher.cpp:579 engines/dialogs.cpp:110
msgid "~Q~uit"
msgstr "~Q~uitter"
-#: gui/launcher.cpp:555 backends/platform/sdl/macosx/appmenu_osx.mm:80
+#: gui/launcher.cpp:579 backends/platform/sdl/macosx/appmenu_osx.mm:96
msgid "Quit ScummVM"
msgstr "Quitter ScummVM"
-#: gui/launcher.cpp:556
+#: gui/launcher.cpp:580
msgid "A~b~out..."
msgstr "À ~P~ropos..."
-#: gui/launcher.cpp:556 backends/platform/sdl/macosx/appmenu_osx.mm:61
+#: gui/launcher.cpp:580 backends/platform/sdl/macosx/appmenu_osx.mm:70
msgid "About ScummVM"
msgstr "À propos de ScummVM"
-#: gui/launcher.cpp:557
+#: gui/launcher.cpp:581
msgid "~O~ptions..."
msgstr "~O~ptions..."
-#: gui/launcher.cpp:557
+#: gui/launcher.cpp:581
msgid "Change global ScummVM options"
msgstr "Change les options globales de ScummVM"
-#: gui/launcher.cpp:559
+#: gui/launcher.cpp:583
msgid "~S~tart"
msgstr "~D~émarrer"
-#: gui/launcher.cpp:559
+#: gui/launcher.cpp:583
msgid "Start selected game"
msgstr "Démarre le jeu sélectionné"
-#: gui/launcher.cpp:562
+#: gui/launcher.cpp:586
msgid "~L~oad..."
msgstr "~C~harger"
-#: gui/launcher.cpp:562
+#: gui/launcher.cpp:586
msgid "Load savegame for selected game"
msgstr "Charge une sauvegarde pour le jeu sélectionné"
-#: gui/launcher.cpp:567 gui/launcher.cpp:1055
+#: gui/launcher.cpp:591 gui/launcher.cpp:1079
msgid "~A~dd Game..."
msgstr "~A~jouter..."
-#: gui/launcher.cpp:567 gui/launcher.cpp:574
+#: gui/launcher.cpp:591 gui/launcher.cpp:598
msgid "Hold Shift for Mass Add"
msgstr ""
"Ajoute un jeu à la Liste. Maintenez Shift enfoncée pour un Ajout Massif"
-#: gui/launcher.cpp:569
+#: gui/launcher.cpp:593
msgid "~E~dit Game..."
msgstr "~E~diter..."
-#: gui/launcher.cpp:569 gui/launcher.cpp:576
+#: gui/launcher.cpp:593 gui/launcher.cpp:600
msgid "Change game options"
msgstr "Change les options du jeu"
-#: gui/launcher.cpp:571
+#: gui/launcher.cpp:595
msgid "~R~emove Game"
msgstr "~S~upprimer"
-#: gui/launcher.cpp:571 gui/launcher.cpp:578
+#: gui/launcher.cpp:595 gui/launcher.cpp:602
msgid "Remove game from the list. The game data files stay intact"
msgstr "Supprime le jeu de la liste. Les fichiers sont conservés"
-#: gui/launcher.cpp:574 gui/launcher.cpp:1055
+#: gui/launcher.cpp:598 gui/launcher.cpp:1079
msgctxt "lowres"
msgid "~A~dd Game..."
msgstr "~A~jouter..."
-#: gui/launcher.cpp:576
+#: gui/launcher.cpp:600
msgctxt "lowres"
msgid "~E~dit Game..."
msgstr "~E~diter..."
-#: gui/launcher.cpp:578
+#: gui/launcher.cpp:602
msgctxt "lowres"
msgid "~R~emove Game"
msgstr "~S~upprimer"
-#: gui/launcher.cpp:586
+#: gui/launcher.cpp:610
msgid "Search in game list"
msgstr "Recherche dans la liste de jeux"
-#: gui/launcher.cpp:590 gui/launcher.cpp:1102
+#: gui/launcher.cpp:614 gui/launcher.cpp:1126
msgid "Search:"
msgstr "Filtre:"
-#: gui/launcher.cpp:593 gui/options.cpp:826
-msgid "Clear value"
-msgstr "Effacer la valeur"
-
-#: gui/launcher.cpp:615 engines/dialogs.cpp:114 engines/mohawk/myst.cpp:255
+#: gui/launcher.cpp:639 engines/dialogs.cpp:114 engines/mohawk/myst.cpp:255
#: engines/mohawk/riven.cpp:716 engines/cruise/menu.cpp:216
msgid "Load game:"
msgstr "Charger le jeu:"
-#: gui/launcher.cpp:615 engines/dialogs.cpp:114 engines/scumm/dialogs.cpp:188
+#: gui/launcher.cpp:639 engines/dialogs.cpp:114 engines/scumm/dialogs.cpp:188
#: engines/mohawk/myst.cpp:255 engines/mohawk/riven.cpp:716
#: engines/cruise/menu.cpp:216 backends/platform/wince/CEActionsPocket.cpp:267
#: backends/platform/wince/CEActionsSmartphone.cpp:231
msgid "Load"
msgstr "Charger"
-#: gui/launcher.cpp:723
+#: gui/launcher.cpp:747
msgid ""
"Do you really want to run the mass game detector? This could potentially add "
"a huge number of games."
@@ -452,7 +455,7 @@ msgstr ""
"Voulez-vous vraiment lancer la détection automatique des jeux? Cela peut "
"potentiellement ajouter un grand nombre de jeux."
-#: gui/launcher.cpp:724 gui/launcher.cpp:872
+#: gui/launcher.cpp:748 gui/launcher.cpp:896
#: backends/events/symbiansdl/symbiansdl-events.cpp:184
#: backends/platform/wince/CEActionsPocket.cpp:326
#: backends/platform/wince/CEActionsSmartphone.cpp:287
@@ -460,7 +463,7 @@ msgstr ""
msgid "Yes"
msgstr "Oui"
-#: gui/launcher.cpp:724 gui/launcher.cpp:872
+#: gui/launcher.cpp:748 gui/launcher.cpp:896
#: backends/events/symbiansdl/symbiansdl-events.cpp:184
#: backends/platform/wince/CEActionsPocket.cpp:326
#: backends/platform/wince/CEActionsSmartphone.cpp:287
@@ -468,37 +471,37 @@ msgstr "Oui"
msgid "No"
msgstr "Non"
-#: gui/launcher.cpp:772
+#: gui/launcher.cpp:796
msgid "ScummVM couldn't open the specified directory!"
msgstr "ScummVM n'a pas pu ouvrir le répertoire sélectionné."
-#: gui/launcher.cpp:784
+#: gui/launcher.cpp:808
msgid "ScummVM could not find any game in the specified directory!"
msgstr "ScummVM n'a pas trouvé de jeux dans le répertoire sélectionné."
-#: gui/launcher.cpp:798
+#: gui/launcher.cpp:822
msgid "Pick the game:"
msgstr "Choisissez le jeu:"
-#: gui/launcher.cpp:872
+#: gui/launcher.cpp:896
msgid "Do you really want to remove this game configuration?"
msgstr "Voulez-vous vraiment supprimer ce jeu?"
-#: gui/launcher.cpp:936
+#: gui/launcher.cpp:960
msgid "This game does not support loading games from the launcher."
msgstr ""
"Le chargement de sauvegarde depuis le lanceur n'est pas supporté pour ce jeu."
-#: gui/launcher.cpp:940
+#: gui/launcher.cpp:964
msgid "ScummVM could not find any engine capable of running the selected game!"
msgstr "ScummVM n'a pas pu trouvé de moteur pour lancer le jeu sélectionné."
-#: gui/launcher.cpp:1054
+#: gui/launcher.cpp:1078
msgctxt "lowres"
msgid "Mass Add..."
msgstr "Ajout Massif..."
-#: gui/launcher.cpp:1054
+#: gui/launcher.cpp:1078
msgid "Mass Add..."
msgstr "Ajout Massif..."
@@ -526,143 +529,143 @@ msgid "Discovered %d new games, ignored %d previously added games ..."
msgstr ""
"%d nouveaux jeux trouvés, %d jeux ignorés (déjà ajouté précédemment) ..."
-#: gui/options.cpp:72
+#: gui/options.cpp:78
msgid "Never"
msgstr "Jamais"
-#: gui/options.cpp:72
+#: gui/options.cpp:78
msgid "every 5 mins"
msgstr "Toutes les 5 mins"
-#: gui/options.cpp:72
+#: gui/options.cpp:78
msgid "every 10 mins"
msgstr "Toutes les 10 mins"
-#: gui/options.cpp:72
+#: gui/options.cpp:78
msgid "every 15 mins"
msgstr "Toutes les 15 mins"
-#: gui/options.cpp:72
+#: gui/options.cpp:78
msgid "every 30 mins"
msgstr "Toutes les 30 mins"
-#: gui/options.cpp:74
+#: gui/options.cpp:80
msgid "8 kHz"
msgstr "8 kHz"
-#: gui/options.cpp:74
+#: gui/options.cpp:80
msgid "11kHz"
msgstr "11 kHz"
-#: gui/options.cpp:74
+#: gui/options.cpp:80
msgid "22 kHz"
msgstr "22 kHz"
-#: gui/options.cpp:74
+#: gui/options.cpp:80
msgid "44 kHz"
msgstr "44 kHz"
-#: gui/options.cpp:74
+#: gui/options.cpp:80
msgid "48 kHz"
msgstr "48 kHz"
-#: gui/options.cpp:236 gui/options.cpp:464 gui/options.cpp:559
-#: gui/options.cpp:625 gui/options.cpp:825
+#: gui/options.cpp:257 gui/options.cpp:485 gui/options.cpp:586
+#: gui/options.cpp:659 gui/options.cpp:868
msgctxt "soundfont"
msgid "None"
msgstr "Aucune"
-#: gui/options.cpp:372
+#: gui/options.cpp:393
msgid "Failed to apply some of the graphic options changes:"
msgstr "Certaines options graphiques n'ont pu être changées:"
-#: gui/options.cpp:384
+#: gui/options.cpp:405
msgid "the video mode could not be changed."
msgstr "le mode vidéo n'a pu être changé."
-#: gui/options.cpp:390
+#: gui/options.cpp:411
msgid "the fullscreen setting could not be changed"
msgstr "le mode plein écran n'a pu être changé."
-#: gui/options.cpp:396
+#: gui/options.cpp:417
msgid "the aspect ratio setting could not be changed"
msgstr "la correction de rapport d'aspect n'a pu être changée."
-#: gui/options.cpp:705
+#: gui/options.cpp:742
msgid "Graphics mode:"
msgstr "Mode graphique:"
-#: gui/options.cpp:716
+#: gui/options.cpp:756
msgid "Render mode:"
msgstr "Mode de rendu:"
-#: gui/options.cpp:716 gui/options.cpp:717
+#: gui/options.cpp:756 gui/options.cpp:757
msgid "Special dithering modes supported by some games"
msgstr "Mode spécial de tramage supporté par certains jeux"
-#: gui/options.cpp:726
+#: gui/options.cpp:768
#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2248
-#: backends/graphics/openglsdl/openglsdl-graphics.cpp:476
+#: backends/graphics/openglsdl/openglsdl-graphics.cpp:472
msgid "Fullscreen mode"
msgstr "Plein écran"
-#: gui/options.cpp:729
+#: gui/options.cpp:771
msgid "Aspect ratio correction"
msgstr "Correction du rapport d'aspect"
-#: gui/options.cpp:729
+#: gui/options.cpp:771
msgid "Correct aspect ratio for 320x200 games"
msgstr "Corrige le rapport d'aspect pour les jeu 320x200"
-#: gui/options.cpp:730
+#: gui/options.cpp:772
msgid "EGA undithering"
msgstr "Détramage EGA"
-#: gui/options.cpp:730
+#: gui/options.cpp:772
msgid "Enable undithering in EGA games that support it"
msgstr "Active le détramage dans les jeux EGA qui le supporte"
-#: gui/options.cpp:738
+#: gui/options.cpp:780
msgid "Preferred Device:"
msgstr "Sortie Préféré:"
-#: gui/options.cpp:738
+#: gui/options.cpp:780
msgid "Music Device:"
msgstr "Sortie Audio:"
-#: gui/options.cpp:738 gui/options.cpp:740
+#: gui/options.cpp:780 gui/options.cpp:782
msgid "Specifies preferred sound device or sound card emulator"
msgstr ""
"Spécifie le périphérique de sortie audio ou l'émulateur de carte audio "
"préféré"
-#: gui/options.cpp:738 gui/options.cpp:740 gui/options.cpp:741
+#: gui/options.cpp:780 gui/options.cpp:782 gui/options.cpp:783
msgid "Specifies output sound device or sound card emulator"
msgstr "Spécifie le périphérique de sortie audio ou l'émulateur de carte audio"
-#: gui/options.cpp:740
+#: gui/options.cpp:782
msgctxt "lowres"
msgid "Preferred Dev.:"
msgstr "Sortie Préféré:"
-#: gui/options.cpp:740
+#: gui/options.cpp:782
msgctxt "lowres"
msgid "Music Device:"
msgstr "Sortie Audio:"
-#: gui/options.cpp:766
+#: gui/options.cpp:809
msgid "AdLib emulator:"
msgstr "Émulateur AdLib:"
-#: gui/options.cpp:766 gui/options.cpp:767
+#: gui/options.cpp:809 gui/options.cpp:810
msgid "AdLib is used for music in many games"
msgstr "AdLib est utilisé pour la musique dans de nombreux jeux"
-#: gui/options.cpp:777
+#: gui/options.cpp:820
msgid "Output rate:"
msgstr "Fréquence:"
-#: gui/options.cpp:777 gui/options.cpp:778
+#: gui/options.cpp:820 gui/options.cpp:821
msgid ""
"Higher value specifies better sound quality but may be not supported by your "
"soundcard"
@@ -670,64 +673,64 @@ msgstr ""
"Une valeur plus élevée donne une meilleure qualité audio mais peut ne pas "
"être supporté par votre carte son"
-#: gui/options.cpp:788
+#: gui/options.cpp:831
msgid "GM Device:"
msgstr "Sortie GM:"
-#: gui/options.cpp:788
+#: gui/options.cpp:831
msgid "Specifies default sound device for General MIDI output"
msgstr "Spécifie le périphérique audio par défaut pour la sortie General MIDI"
-#: gui/options.cpp:799
+#: gui/options.cpp:842
msgid "Don't use General MIDI music"
msgstr "Ne pas utiliser la musique General MIDI"
-#: gui/options.cpp:810 gui/options.cpp:871
+#: gui/options.cpp:853 gui/options.cpp:915
msgid "Use first available device"
msgstr "Utiliser le premier périphérique disponible"
-#: gui/options.cpp:822
+#: gui/options.cpp:865
msgid "SoundFont:"
msgstr "Banque de sons:"
-#: gui/options.cpp:822 gui/options.cpp:824 gui/options.cpp:825
+#: gui/options.cpp:865 gui/options.cpp:867 gui/options.cpp:868
msgid "SoundFont is supported by some audio cards, Fluidsynth and Timidity"
msgstr ""
"La banque de sons (SoundFont) est utilisée par certaines cartes audio, "
"Fluidsynth et Timidity"
-#: gui/options.cpp:824
+#: gui/options.cpp:867
msgctxt "lowres"
msgid "SoundFont:"
msgstr "SoundFont:"
-#: gui/options.cpp:829
+#: gui/options.cpp:873
msgid "Mixed AdLib/MIDI mode"
msgstr "Mode mixe AdLib/MIDI"
-#: gui/options.cpp:829
+#: gui/options.cpp:873
msgid "Use both MIDI and AdLib sound generation"
msgstr "Utiliser à la fois MIDI et AdLib"
-#: gui/options.cpp:832
+#: gui/options.cpp:876
msgid "MIDI gain:"
msgstr "Gain MIDI:"
-#: gui/options.cpp:842
+#: gui/options.cpp:886
msgid "MT-32 Device:"
msgstr "Sortie MT-32:"
-#: gui/options.cpp:842
+#: gui/options.cpp:886
msgid "Specifies default sound device for Roland MT-32/LAPC1/CM32l/CM64 output"
msgstr ""
"Spécifie le périphérique audio par défaut pour la sortie Roland MT-32/LAPC1/"
"CM32l/CM64"
-#: gui/options.cpp:847
+#: gui/options.cpp:891
msgid "True Roland MT-32 (disable GM emulation)"
msgstr "Roland MT-32 exacte (désactive l'émulation GM)"
-#: gui/options.cpp:847 gui/options.cpp:849
+#: gui/options.cpp:891 gui/options.cpp:893
msgid ""
"Check if you want to use your real hardware Roland-compatible sound device "
"connected to your computer"
@@ -735,195 +738,195 @@ msgstr ""
"Vérifie si vous voulez utiliser un périphérique audio compatible Roland "
"connecté à l'ordinateur"
-#: gui/options.cpp:849
+#: gui/options.cpp:893
msgctxt "lowres"
msgid "True Roland MT-32 (no GM emulation)"
msgstr "Roland MT-32 exacte (pas d'ému GM)"
-#: gui/options.cpp:852
+#: gui/options.cpp:896
msgid "Enable Roland GS Mode"
msgstr "Activer le mode Roland GS"
-#: gui/options.cpp:852
+#: gui/options.cpp:896
msgid "Turns off General MIDI mapping for games with Roland MT-32 soundtrack"
msgstr "Désactiver la conversion des pistes MT-32 en General MIDI"
-#: gui/options.cpp:861
+#: gui/options.cpp:905
msgid "Don't use Roland MT-32 music"
msgstr "Ne pas utiliser la musique Roland MT-32"
-#: gui/options.cpp:888
+#: gui/options.cpp:932
msgid "Text and Speech:"
msgstr "Dialogue:"
-#: gui/options.cpp:892 gui/options.cpp:902
+#: gui/options.cpp:936 gui/options.cpp:946
msgid "Speech"
msgstr "Voix"
-#: gui/options.cpp:893 gui/options.cpp:903
+#: gui/options.cpp:937 gui/options.cpp:947
msgid "Subtitles"
msgstr "Sous-titres"
-#: gui/options.cpp:894
+#: gui/options.cpp:938
msgid "Both"
msgstr "Les deux"
-#: gui/options.cpp:896
+#: gui/options.cpp:940
msgid "Subtitle speed:"
msgstr "Vitesse des ST:"
-#: gui/options.cpp:898
+#: gui/options.cpp:942
msgctxt "lowres"
msgid "Text and Speech:"
msgstr "Dialogue:"
-#: gui/options.cpp:902
+#: gui/options.cpp:946
msgid "Spch"
msgstr "Voix"
-#: gui/options.cpp:903
+#: gui/options.cpp:947
msgid "Subs"
msgstr "Subs"
-#: gui/options.cpp:904
+#: gui/options.cpp:948
msgctxt "lowres"
msgid "Both"
msgstr "V&S"
-#: gui/options.cpp:904
+#: gui/options.cpp:948
msgid "Show subtitles and play speech"
msgstr "Affiche les sous-titres et joue les dialogues audio"
-#: gui/options.cpp:906
+#: gui/options.cpp:950
msgctxt "lowres"
msgid "Subtitle speed:"
msgstr "Vitesse des ST:"
-#: gui/options.cpp:922
+#: gui/options.cpp:966
msgid "Music volume:"
msgstr "Volume Musique:"
-#: gui/options.cpp:924
+#: gui/options.cpp:968
msgctxt "lowres"
msgid "Music volume:"
msgstr "Musique:"
-#: gui/options.cpp:931
+#: gui/options.cpp:975
msgid "Mute All"
msgstr "Silence"
-#: gui/options.cpp:934
+#: gui/options.cpp:978
msgid "SFX volume:"
msgstr "Volume Bruitage:"
-#: gui/options.cpp:934 gui/options.cpp:936 gui/options.cpp:937
+#: gui/options.cpp:978 gui/options.cpp:980 gui/options.cpp:981
msgid "Special sound effects volume"
msgstr "Volume des effets spéciaux sonores"
-#: gui/options.cpp:936
+#: gui/options.cpp:980
msgctxt "lowres"
msgid "SFX volume:"
msgstr "Bruitage:"
-#: gui/options.cpp:944
+#: gui/options.cpp:988
msgid "Speech volume:"
msgstr "Volume Dialogues:"
-#: gui/options.cpp:946
+#: gui/options.cpp:990
msgctxt "lowres"
msgid "Speech volume:"
msgstr "Dialogues:"
-#: gui/options.cpp:1085
+#: gui/options.cpp:1156
msgid "Theme Path:"
msgstr "Thèmes:"
-#: gui/options.cpp:1087
+#: gui/options.cpp:1158
msgctxt "lowres"
msgid "Theme Path:"
msgstr "Thèmes:"
-#: gui/options.cpp:1091 gui/options.cpp:1093 gui/options.cpp:1094
+#: gui/options.cpp:1164 gui/options.cpp:1166 gui/options.cpp:1167
msgid "Specifies path to additional data used by all games or ScummVM"
msgstr ""
"Spécifie un chemin vers des données supplémentaires utilisées par tous les "
"jeux ou ScummVM"
-#: gui/options.cpp:1098
+#: gui/options.cpp:1173
msgid "Plugins Path:"
msgstr "Plugins:"
-#: gui/options.cpp:1100
+#: gui/options.cpp:1175
msgctxt "lowres"
msgid "Plugins Path:"
msgstr "Plugins:"
-#: gui/options.cpp:1109
+#: gui/options.cpp:1184
msgid "Misc"
msgstr "Divers"
-#: gui/options.cpp:1111
+#: gui/options.cpp:1186
msgctxt "lowres"
msgid "Misc"
msgstr "Divers"
-#: gui/options.cpp:1113
+#: gui/options.cpp:1188
msgid "Theme:"
msgstr "Thème:"
-#: gui/options.cpp:1117
+#: gui/options.cpp:1192
msgid "GUI Renderer:"
msgstr "Interface:"
-#: gui/options.cpp:1129
+#: gui/options.cpp:1204
msgid "Autosave:"
msgstr "Sauvegarde auto:"
-#: gui/options.cpp:1131
+#: gui/options.cpp:1206
msgctxt "lowres"
msgid "Autosave:"
msgstr "Sauvegarde:"
-#: gui/options.cpp:1139
+#: gui/options.cpp:1214
msgid "Keys"
msgstr "Touches"
-#: gui/options.cpp:1146
+#: gui/options.cpp:1221
msgid "GUI Language:"
msgstr "Langue:"
-#: gui/options.cpp:1146
+#: gui/options.cpp:1221
msgid "Language of ScummVM GUI"
msgstr "Langue de l'interface graphique de ScummVM"
-#: gui/options.cpp:1295
+#: gui/options.cpp:1372
msgid "You have to restart ScummVM before your changes will take effect."
msgstr ""
"Vous devez relancer ScummVM pour que le changement soit pris en compte."
-#: gui/options.cpp:1308
+#: gui/options.cpp:1385
msgid "Select directory for savegames"
msgstr "Sélectionner le répertoire pour les sauvegardes"
-#: gui/options.cpp:1315
+#: gui/options.cpp:1392
msgid "The chosen directory cannot be written to. Please select another one."
msgstr ""
"Le répertoire sélectionné est vérouillé en écriture. Sélectionnez un autre "
"répertoire."
-#: gui/options.cpp:1324
+#: gui/options.cpp:1401
msgid "Select directory for GUI themes"
msgstr "Sélectionner le répertoire des thèmes d'interface"
-#: gui/options.cpp:1334
+#: gui/options.cpp:1411
msgid "Select directory for extra files"
msgstr "Sélectionner le répertoire pour les fichiers suplémentaires"
-#: gui/options.cpp:1345
+#: gui/options.cpp:1422
msgid "Select directory for plugins"
msgstr "Sélectionner le répertoire des plugins"
-#: gui/options.cpp:1389
+#: gui/options.cpp:1475
msgid ""
"The theme you selected does not support your current language. If you want "
"to use this theme you need to switch to another language first."
@@ -971,60 +974,64 @@ msgstr "Sauvegarde sans nom"
msgid "Select a Theme"
msgstr "Sélectionnez un Thème"
-#: gui/ThemeEngine.cpp:328
+#: gui/ThemeEngine.cpp:333
msgid "Disabled GFX"
msgstr "GFX désactivé"
-#: gui/ThemeEngine.cpp:328
+#: gui/ThemeEngine.cpp:333
msgctxt "lowres"
msgid "Disabled GFX"
msgstr "GFX désactivé"
-#: gui/ThemeEngine.cpp:329
+#: gui/ThemeEngine.cpp:334
msgid "Standard Renderer (16bpp)"
msgstr "Rendu Standard (16bpp)"
-#: gui/ThemeEngine.cpp:329
+#: gui/ThemeEngine.cpp:334
msgid "Standard (16bpp)"
msgstr "Standard (16bpp)"
-#: gui/ThemeEngine.cpp:331
+#: gui/ThemeEngine.cpp:336
msgid "Antialiased Renderer (16bpp)"
msgstr "Rendu Anti-crénelé (16 bpp)"
-#: gui/ThemeEngine.cpp:331
+#: gui/ThemeEngine.cpp:336
msgid "Antialiased (16bpp)"
msgstr "Anti-crénelé (16 bpp)"
+#: gui/widget.cpp:312 gui/widget.cpp:314 gui/widget.cpp:320 gui/widget.cpp:322
+msgid "Clear value"
+msgstr "Effacer la valeur"
+
#: base/main.cpp:203
#, c-format
msgid "Engine does not support debug level '%s'"
msgstr "Le niveau de debug '%s' n'est pas supporté par ce moteur de jeu"
-#: base/main.cpp:271
+#: base/main.cpp:275
msgid "Menu"
msgstr "Menu"
-#: base/main.cpp:274 backends/platform/symbian/src/SymbianActions.cpp:45
+#: base/main.cpp:278 backends/platform/symbian/src/SymbianActions.cpp:45
#: backends/platform/wince/CEActionsPocket.cpp:45
#: backends/platform/wince/CEActionsSmartphone.cpp:46
msgid "Skip"
msgstr "Passer"
-#: base/main.cpp:277 backends/platform/symbian/src/SymbianActions.cpp:50
+#: base/main.cpp:281 backends/platform/symbian/src/SymbianActions.cpp:50
#: backends/platform/wince/CEActionsPocket.cpp:42
msgid "Pause"
msgstr "Mettre en pause"
-#: base/main.cpp:280
+#: base/main.cpp:284
msgid "Skip line"
msgstr "Passer la phrase"
-#: base/main.cpp:439
+#: base/main.cpp:455
msgid "Error running game:"
msgstr "Erreur lors de l'éxécution du jeu:"
-#: base/main.cpp:463
+#: base/main.cpp:479
msgid "Could not find any engine capable of running the selected game"
msgstr "Impossible de trouver un moteur pour exécuter le jeu sélectionné"
@@ -1092,25 +1099,6 @@ msgstr "Annuler par l'utilisateur"
msgid "Unknown error"
msgstr "Erreur inconnue"
-#. I18N: Hercules is graphics card name
-#: common/util.cpp:275
-msgid "Hercules Green"
-msgstr "Hercules Vert"
-
-#: common/util.cpp:276
-msgid "Hercules Amber"
-msgstr "Hercules Ambre"
-
-#: common/util.cpp:283
-msgctxt "lowres"
-msgid "Hercules Green"
-msgstr "Hercules Vert"
-
-#: common/util.cpp:284
-msgctxt "lowres"
-msgid "Hercules Amber"
-msgstr "Hercules Ambre"
-
#: engines/advancedDetector.cpp:296
#, c-format
msgid "The game in '%s' seems to be unknown."
@@ -1160,12 +1148,12 @@ msgid "~R~eturn to Launcher"
msgstr "Retour au ~L~anceur"
#: engines/dialogs.cpp:116 engines/cruise/menu.cpp:214
-#: engines/sci/engine/kfile.cpp:578
+#: engines/sci/engine/kfile.cpp:566
msgid "Save game:"
msgstr "Sauvegarde:"
#: engines/dialogs.cpp:116 engines/scumm/dialogs.cpp:187
-#: engines/cruise/menu.cpp:214 engines/sci/engine/kfile.cpp:578
+#: engines/cruise/menu.cpp:214 engines/sci/engine/kfile.cpp:566
#: backends/platform/symbian/src/SymbianActions.cpp:44
#: backends/platform/wince/CEActionsPocket.cpp:43
#: backends/platform/wince/CEActionsPocket.cpp:267
@@ -1184,37 +1172,47 @@ msgstr ""
"fichier README pour les informations de base et les instructions pour "
"obtenir de l'aide supplémentaire."
-#: engines/dialogs.cpp:316 engines/mohawk/dialogs.cpp:109
+#: engines/dialogs.cpp:243
+#, fuzzy, c-format
+msgid ""
+"Gamestate save failed (%s)! Please consult the README for basic information, "
+"and for instructions on how to obtain further assistance."
+msgstr ""
+"Désolé, il n'y a pas d'aide disponible dans ce jeu actuellement. Lisez le "
+"fichier README pour les informations de base et les instructions pour "
+"obtenir de l'aide supplémentaire."
+
+#: engines/dialogs.cpp:321 engines/mohawk/dialogs.cpp:109
#: engines/mohawk/dialogs.cpp:174
msgid "~O~K"
msgstr "~O~K"
-#: engines/dialogs.cpp:317 engines/mohawk/dialogs.cpp:110
+#: engines/dialogs.cpp:322 engines/mohawk/dialogs.cpp:110
#: engines/mohawk/dialogs.cpp:175
msgid "~C~ancel"
msgstr "~A~nnuler"
-#: engines/dialogs.cpp:320
+#: engines/dialogs.cpp:325
msgid "~K~eys"
msgstr "~T~ouches"
-#: engines/engine.cpp:233
+#: engines/engine.cpp:235
msgid "Could not initialize color format."
msgstr "Impossible d'initialiser le format des couleurs."
-#: engines/engine.cpp:241
+#: engines/engine.cpp:243
msgid "Could not switch to video mode: '"
msgstr "Impossible de changer le mode vidéo à: '"
-#: engines/engine.cpp:250
+#: engines/engine.cpp:252
msgid "Could not apply aspect ratio setting."
msgstr "Impossible d'appliquer la correction du rapport d'aspect."
-#: engines/engine.cpp:255
+#: engines/engine.cpp:257
msgid "Could not apply fullscreen setting."
msgstr "Impossible d'appliquer l'option plein écran."
-#: engines/engine.cpp:355
+#: engines/engine.cpp:357
msgid ""
"You appear to be playing this game directly\n"
"from the CD. This is known to cause problems,\n"
@@ -1228,7 +1226,7 @@ msgstr ""
"données du jeu sur votre disque dur.\n"
"Lisez le fichier README pour plus de détails."
-#: engines/engine.cpp:366
+#: engines/engine.cpp:368
msgid ""
"This game has audio tracks in its disk. These\n"
"tracks need to be ripped from the disk using\n"
@@ -1242,7 +1240,17 @@ msgstr ""
"logiciel approprié.\n"
"Lisez le fichier README pour plus de détails."
-#: engines/engine.cpp:433
+#: engines/engine.cpp:426
+#, fuzzy, c-format
+msgid ""
+"Gamestate load failed (%s)! Please consult the README for basic information, "
+"and for instructions on how to obtain further assistance."
+msgstr ""
+"Désolé, il n'y a pas d'aide disponible dans ce jeu actuellement. Lisez le "
+"fichier README pour les informations de base et les instructions pour "
+"obtenir de l'aide supplémentaire."
+
+#: engines/engine.cpp:439
msgid ""
"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 "
@@ -1252,7 +1260,7 @@ msgstr ""
"complètement supporté par ScummVM. Il est donc instable et les sauvegardes "
"peuvent ne pas marcher avec une future version de ScummVM."
-#: engines/engine.cpp:436
+#: engines/engine.cpp:442
msgid "Start anyway"
msgstr "Jouer quand même"
@@ -1296,7 +1304,7 @@ msgstr "Jouer"
#: backends/platform/symbian/src/SymbianActions.cpp:52
#: backends/platform/wince/CEActionsPocket.cpp:44
#: backends/platform/wince/CEActionsSmartphone.cpp:52
-#: backends/events/default/default-events.cpp:244
+#: backends/events/default/default-events.cpp:213
msgid "Quit"
msgstr "Quitter"
@@ -1370,6 +1378,26 @@ msgctxt "lowres"
msgid "Speech & Subs"
msgstr "Voix & ST"
+#: engines/scumm/dialogs.cpp:653
+msgid "Select a Proficiency Level."
+msgstr ""
+
+#: engines/scumm/dialogs.cpp:655
+msgid "Refer to your Loom(TM) manual for help."
+msgstr ""
+
+#: engines/scumm/dialogs.cpp:658
+msgid "Standard"
+msgstr "Standard"
+
+#: engines/scumm/dialogs.cpp:659
+msgid "Practice"
+msgstr ""
+
+#: engines/scumm/dialogs.cpp:660
+msgid "Expert"
+msgstr ""
+
#: engines/scumm/help.cpp:73
msgid "Common keyboard commands:"
msgstr "Commandes clavier communes:"
@@ -1883,7 +1911,7 @@ msgstr "Voler vers la droite"
msgid "Fly to lower right"
msgstr "Voler vers la bas à droite"
-#: engines/scumm/scumm.cpp:1774
+#: engines/scumm/scumm.cpp:1773
#, c-format
msgid ""
"Native MIDI support requires the Roland Upgrade from LucasArts,\n"
@@ -1892,7 +1920,7 @@ msgstr ""
"Support MIDI natif requière la mise à jour Roland de LucasArt,\n"
"mais %s manque. Utilise AdLib à la place."
-#: engines/scumm/scumm.cpp:2264 engines/agos/saveload.cpp:189
+#: engines/scumm/scumm.cpp:2271 engines/agos/saveload.cpp:189
#, c-format
msgid ""
"Failed to save game state to file:\n"
@@ -1903,7 +1931,7 @@ msgstr ""
"\n"
"%s"
-#: engines/scumm/scumm.cpp:2271 engines/agos/saveload.cpp:154
+#: engines/scumm/scumm.cpp:2278 engines/agos/saveload.cpp:154
#, c-format
msgid ""
"Failed to load game state from file:\n"
@@ -1914,7 +1942,7 @@ msgstr ""
"\n"
"%s"
-#: engines/scumm/scumm.cpp:2283 engines/agos/saveload.cpp:197
+#: engines/scumm/scumm.cpp:2290 engines/agos/saveload.cpp:197
#, c-format
msgid ""
"Successfully saved game state in file:\n"
@@ -1925,7 +1953,7 @@ msgstr ""
"\n"
"%s"
-#: engines/scumm/scumm.cpp:2498
+#: engines/scumm/scumm.cpp:2505
msgid ""
"Usually, Maniac Mansion would start now. But ScummVM doesn't do that yet. To "
"play it, go to 'Add Game' in the ScummVM start menu and select the 'Maniac' "
@@ -1962,11 +1990,11 @@ msgstr "~M~enu Principal"
msgid "~W~ater Effect Enabled"
msgstr "~E~ffets de l'Eau Activés"
-#: engines/sci/engine/kfile.cpp:685
+#: engines/sci/engine/kfile.cpp:673
msgid "Restore game:"
msgstr "Charger le jeu:"
-#: engines/sci/engine/kfile.cpp:685
+#: engines/sci/engine/kfile.cpp:673
msgid "Restore"
msgstr "Charger"
@@ -1976,11 +2004,11 @@ msgid "Cutscene file '%s' not found!"
msgstr "Fichier de séquence '%s' non trouvé!"
#: engines/gob/inter_playtoons.cpp:256 engines/gob/inter_v2.cpp:1283
-#: engines/tinsel/saveload.cpp:482
+#: engines/tinsel/saveload.cpp:502
msgid "Failed to load game state from file."
msgstr "Échec du chargement de l'état du jeu depuis le disque."
-#: engines/gob/inter_v2.cpp:1353 engines/tinsel/saveload.cpp:560
+#: engines/gob/inter_v2.cpp:1353 engines/tinsel/saveload.cpp:515
msgid "Failed to save game state to file."
msgstr "Échec de l'enregistrement de l'état du jeu sur le disque."
@@ -1992,6 +2020,54 @@ msgstr "Échec de la suppression du fichier."
msgid "Failed to save game"
msgstr "Échec de la sauvegarde."
+#: engines/kyra/lol.cpp:478
+msgid "Attack 1"
+msgstr "Attaque 1"
+
+#: engines/kyra/lol.cpp:479
+msgid "Attack 2"
+msgstr "Attaque 2"
+
+#: engines/kyra/lol.cpp:480
+msgid "Attack 3"
+msgstr "Attaque 3"
+
+#: engines/kyra/lol.cpp:481
+msgid "Move Forward"
+msgstr "Avancer"
+
+#: engines/kyra/lol.cpp:482
+msgid "Move Back"
+msgstr "Reculer"
+
+#: engines/kyra/lol.cpp:483
+msgid "Slide Left"
+msgstr "Faire un pas vers la Gauche"
+
+#: engines/kyra/lol.cpp:484
+msgid "Slide Right"
+msgstr "Faire un pas vers la Droite"
+
+#: engines/kyra/lol.cpp:485
+msgid "Turn Left"
+msgstr "Tourner vers la Gauche"
+
+#: engines/kyra/lol.cpp:486
+msgid "Turn Right"
+msgstr "Tourner vers la Droite"
+
+#: engines/kyra/lol.cpp:487
+msgid "Rest"
+msgstr "Se Reposer"
+
+#: engines/kyra/lol.cpp:488
+msgid "Options"
+msgstr "Options"
+
+#: engines/kyra/lol.cpp:489
+msgid "Choose Spell"
+msgstr "Choisir un Sort"
+
#: engines/kyra/sound_midi.cpp:475
msgid ""
"You appear to be using a General MIDI device,\n"
@@ -2006,10 +2082,6 @@ msgstr ""
"MIDI. Mais il est possible que quelquespistes ne soient pas jouées "
"correctement."
-#: engines/m4/m4_menus.cpp:138
-msgid "Save game failed!"
-msgstr "Échec de la sauvegarde!"
-
#: engines/sky/compact.cpp:130
msgid ""
"Unable to find \"sky.cpt\" file!\n"
@@ -2026,17 +2098,22 @@ msgstr ""
"Le fichier \"sky.cpt\" a une taille incorrecte.\n"
"Vous pouvez le (re)télécharger sur www.scummvm.org"
-#: engines/sword1/animation.cpp:344 engines/sword2/animation.cpp:379
+#: engines/sword1/animation.cpp:539
+#, c-format
+msgid "PSX stream cutscene '%s' cannot be played in paletted mode"
+msgstr ""
+
+#: engines/sword1/animation.cpp:560 engines/sword2/animation.cpp:455
msgid "DXA cutscenes found but ScummVM has been built without zlib support"
msgstr ""
"Les séquences DXA sont présente mais ScummVM a été compilé sans le support "
"zlib."
-#: engines/sword1/animation.cpp:354 engines/sword2/animation.cpp:389
+#: engines/sword1/animation.cpp:570 engines/sword2/animation.cpp:465
msgid "MPEG2 cutscenes are no longer supported"
msgstr "Les séquences MPEG2 ne sont plus supportées"
-#: engines/sword1/animation.cpp:359 engines/sword2/animation.cpp:397
+#: engines/sword1/animation.cpp:576 engines/sword2/animation.cpp:473
#, c-format
msgid "Cutscene '%s' not found"
msgstr "Séquence '%s' non trouvé"
@@ -2080,6 +2157,14 @@ msgstr "Garder la nouvelle"
msgid "This is the end of the Broken Sword 1 Demo"
msgstr "C'est la fin de la démo des Chevaliers de Baphomet"
+#: engines/sword2/animation.cpp:435
+#, fuzzy
+msgid ""
+"PSX cutscenes found but ScummVM has been built without RGB color support"
+msgstr ""
+"Les séquences DXA sont présente mais ScummVM a été compilé sans le support "
+"zlib."
+
#: engines/parallaction/saveload.cpp:133
#, c-format
msgid ""
@@ -2136,7 +2221,7 @@ msgstr "Émulateur MAME OPL"
msgid "DOSBox OPL emulator"
msgstr "Émulateur DOSBox OPL"
-#: audio/mididrv.cpp:205
+#: audio/mididrv.cpp:209
#, c-format
msgid ""
"The selected audio device '%s' was not found (e.g. might be turned off or "
@@ -2145,12 +2230,12 @@ msgstr ""
"Le périphérique audio sélectionné '%s' n'a pas été trouvé (il est peut-être "
"éteint ou débranché)."
-#: audio/mididrv.cpp:205 audio/mididrv.cpp:217 audio/mididrv.cpp:253
-#: audio/mididrv.cpp:268
+#: audio/mididrv.cpp:209 audio/mididrv.cpp:221 audio/mididrv.cpp:257
+#: audio/mididrv.cpp:272
msgid "Attempting to fall back to the next available device..."
msgstr "Essaye d'utiliser le prochain périphérique disponible..."
-#: audio/mididrv.cpp:217
+#: audio/mididrv.cpp:221
#, c-format
msgid ""
"The selected audio device '%s' cannot be used. See log file for more "
@@ -2159,7 +2244,7 @@ msgstr ""
"The selected audio device '%s' ne peut pas être utilisé. Voir le fichier de "
"log pour plus de détails."
-#: audio/mididrv.cpp:253
+#: audio/mididrv.cpp:257
#, c-format
msgid ""
"The preferred audio device '%s' was not found (e.g. might be turned off or "
@@ -2168,7 +2253,7 @@ msgstr ""
"Le périphérique audio préféré '%s' n'a pas été trouvé (il est peut-être "
"éteint ou débranché)."
-#: audio/mididrv.cpp:268
+#: audio/mididrv.cpp:272
#, c-format
msgid ""
"The preferred audio device '%s' cannot be used. See log file for more "
@@ -2185,7 +2270,7 @@ msgstr "Pas de musique"
msgid "Amiga Audio Emulator"
msgstr "Émulateur Amiga Audio"
-#: audio/softsynth/adlib.cpp:1594
+#: audio/softsynth/adlib.cpp:1593
msgid "AdLib Emulator"
msgstr "Émulateur AdLib"
@@ -2197,11 +2282,11 @@ msgstr "Émulateur Apple II GS (PAS IMPLÉMENTÉ)"
msgid "C64 Audio Emulator"
msgstr "Émulateur C64 Audio"
-#: audio/softsynth/mt32.cpp:329
+#: audio/softsynth/mt32.cpp:293
msgid "Initializing MT-32 Emulator"
msgstr "Initialisation de l'Émulateur MT-32"
-#: audio/softsynth/mt32.cpp:543
+#: audio/softsynth/mt32.cpp:512
msgid "MT-32 Emulator"
msgstr "Émulateur MT-32"
@@ -2217,15 +2302,24 @@ msgstr "Émulateur IBM PCjr"
msgid "Keymap:"
msgstr "Affectation des touches:"
-#: backends/keymapper/remap-dialog.cpp:64
+#: backends/keymapper/remap-dialog.cpp:66
+#, fuzzy
+msgid " (Effective)"
+msgstr "(Actif)"
+
+#: backends/keymapper/remap-dialog.cpp:106
msgid " (Active)"
msgstr "(Actif)"
-#: backends/keymapper/remap-dialog.cpp:98
+#: backends/keymapper/remap-dialog.cpp:106
+msgid " (Blocked)"
+msgstr ""
+
+#: backends/keymapper/remap-dialog.cpp:119
msgid " (Global)"
msgstr "(Global)"
-#: backends/keymapper/remap-dialog.cpp:108
+#: backends/keymapper/remap-dialog.cpp:127
msgid " (Game)"
msgstr "(Jeu)"
@@ -2305,42 +2399,65 @@ msgstr "Audio haute qualité (plus lent) (redémarrer)"
msgid "Disable power off"
msgstr "Désactivé l'extinction"
-#: backends/platform/iphone/osys_events.cpp:338
+#: backends/platform/iphone/osys_events.cpp:301
msgid "Mouse-click-and-drag mode enabled."
msgstr "Mode souris-cliquer-et-déplacer activé"
-#: backends/platform/iphone/osys_events.cpp:340
+#: backends/platform/iphone/osys_events.cpp:303
msgid "Mouse-click-and-drag mode disabled."
msgstr "Mode souris-cliquer-et-déplacer désactivé"
-#: backends/platform/iphone/osys_events.cpp:351
+#: backends/platform/iphone/osys_events.cpp:314
msgid "Touchpad mode enabled."
msgstr "Mode touchpad activé"
-#: backends/platform/iphone/osys_events.cpp:353
+#: backends/platform/iphone/osys_events.cpp:316
msgid "Touchpad mode disabled."
msgstr "Mode touchpad désactivé"
-#: backends/platform/sdl/macosx/appmenu_osx.mm:67
+#: backends/platform/maemo/maemo.cpp:205
+msgid "Click Mode"
+msgstr "Mode Clic"
+
+#: backends/platform/maemo/maemo.cpp:211
+#: backends/platform/symbian/src/SymbianActions.cpp:42
+#: backends/platform/wince/CEActionsPocket.cpp:60
+#: backends/platform/wince/CEActionsSmartphone.cpp:43
+#: backends/platform/bada/form.cpp:281
+msgid "Left Click"
+msgstr "Clic Gauche"
+
+#: backends/platform/maemo/maemo.cpp:214
+msgid "Middle Click"
+msgstr "Clic Milieu"
+
+#: backends/platform/maemo/maemo.cpp:217
+#: backends/platform/symbian/src/SymbianActions.cpp:43
+#: backends/platform/wince/CEActionsSmartphone.cpp:44
+#: backends/platform/bada/form.cpp:273
+msgid "Right Click"
+msgstr "Clic Droit"
+
+#: backends/platform/sdl/macosx/appmenu_osx.mm:78
msgid "Hide ScummVM"
-msgstr "Cacher ScummVM"
+msgstr "Masquer ScummVM"
-#: backends/platform/sdl/macosx/appmenu_osx.mm:70
+#: backends/platform/sdl/macosx/appmenu_osx.mm:83
msgid "Hide Others"
-msgstr "Masquer les Autres"
+msgstr "Masquer les autres"
-#: backends/platform/sdl/macosx/appmenu_osx.mm:74
+#: backends/platform/sdl/macosx/appmenu_osx.mm:88
msgid "Show All"
-msgstr "Tout Afficher"
+msgstr "Tout afficher"
-#: backends/platform/sdl/macosx/appmenu_osx.mm:92
-#: backends/platform/sdl/macosx/appmenu_osx.mm:99
+#: backends/platform/sdl/macosx/appmenu_osx.mm:110
+#: backends/platform/sdl/macosx/appmenu_osx.mm:121
msgid "Window"
msgstr "Fenêtre"
-#: backends/platform/sdl/macosx/appmenu_osx.mm:95
+#: backends/platform/sdl/macosx/appmenu_osx.mm:115
msgid "Minimize"
-msgstr "Minimiser"
+msgstr "Placer dans le Dock"
#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:45
msgid "Normal (no scaling)"
@@ -2352,12 +2469,12 @@ msgid "Normal (no scaling)"
msgstr "Normal"
#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2147
-#: backends/graphics/openglsdl/openglsdl-graphics.cpp:537
+#: backends/graphics/openglsdl/openglsdl-graphics.cpp:533
msgid "Enabled aspect ratio correction"
msgstr "Activer la correction du rapport d'aspect"
#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2153
-#: backends/graphics/openglsdl/openglsdl-graphics.cpp:542
+#: backends/graphics/openglsdl/openglsdl-graphics.cpp:538
msgid "Disabled aspect ratio correction"
msgstr "Désactiver la correction du rapport d'aspect"
@@ -2366,7 +2483,7 @@ msgid "Active graphics filter:"
msgstr "Mode graphique actif:"
#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2250
-#: backends/graphics/openglsdl/openglsdl-graphics.cpp:481
+#: backends/graphics/openglsdl/openglsdl-graphics.cpp:477
msgid "Windowed mode"
msgstr "Mode Fenêtre"
@@ -2390,11 +2507,11 @@ msgstr "Mode vidéo actuel"
msgid "Current scale"
msgstr "Échelle actuelle"
-#: backends/graphics/openglsdl/openglsdl-graphics.cpp:562
+#: backends/graphics/openglsdl/openglsdl-graphics.cpp:558
msgid "Active filter mode: Linear"
msgstr "Filtre actif: Linéaire"
-#: backends/graphics/openglsdl/openglsdl-graphics.cpp:564
+#: backends/graphics/openglsdl/openglsdl-graphics.cpp:560
msgid "Active filter mode: Nearest"
msgstr "Filtre actif: Plus proche"
@@ -2418,19 +2535,6 @@ msgstr "Gauche"
msgid "Right"
msgstr "Droite"
-#: backends/platform/symbian/src/SymbianActions.cpp:42
-#: backends/platform/wince/CEActionsPocket.cpp:60
-#: backends/platform/wince/CEActionsSmartphone.cpp:43
-#: backends/platform/bada/form.cpp:281
-msgid "Left Click"
-msgstr "Clic Gauche"
-
-#: backends/platform/symbian/src/SymbianActions.cpp:43
-#: backends/platform/wince/CEActionsSmartphone.cpp:44
-#: backends/platform/bada/form.cpp:273
-msgid "Right Click"
-msgstr "Clic Droit"
-
#: backends/platform/symbian/src/SymbianActions.cpp:46
#: backends/platform/wince/CEActionsSmartphone.cpp:47
msgid "Zone"
@@ -2721,15 +2825,15 @@ msgstr ""
"Noubliez pas d'affecter une touche à l'action 'Cacher Bar d'Outils' pour "
"pouvoir voir entièrement l'inventaire"
-#: backends/events/default/default-events.cpp:222
+#: backends/events/default/default-events.cpp:191
msgid "Do you really want to return to the Launcher?"
msgstr "Voulez-vous vraiment retourner au Lanceur?"
-#: backends/events/default/default-events.cpp:222
+#: backends/events/default/default-events.cpp:191
msgid "Launcher"
msgstr "Lanceur"
-#: backends/events/default/default-events.cpp:244
+#: backends/events/default/default-events.cpp:213
msgid "Do you really want to quit?"
msgstr "Voulez-vous vraiment quitter?"
@@ -2795,14 +2899,31 @@ msgstr "Afficher le clavier"
msgid "Control Mouse"
msgstr "Contrôles la Souris"
-#: backends/events/maemosdl/maemosdl-events.cpp:121
+#: backends/events/maemosdl/maemosdl-events.cpp:192
msgid "Clicking Enabled"
msgstr "Clic Activé"
-#: backends/events/maemosdl/maemosdl-events.cpp:121
+#: backends/events/maemosdl/maemosdl-events.cpp:192
msgid "Clicking Disabled"
msgstr "Clic Désactivé"
+#~ msgid "Hercules Green"
+#~ msgstr "Hercules Vert"
+
+#~ msgid "Hercules Amber"
+#~ msgstr "Hercules Ambre"
+
+#~ msgctxt "lowres"
+#~ msgid "Hercules Green"
+#~ msgstr "Hercules Vert"
+
+#~ msgctxt "lowres"
+#~ msgid "Hercules Amber"
+#~ msgstr "Hercules Ambre"
+
+#~ msgid "Save game failed!"
+#~ msgstr "Échec de la sauvegarde!"
+
#~ msgctxt "lowres"
#~ msgid "Add Game..."
#~ msgstr "Ajouter..."
diff --git a/po/hu_HU.po b/po/hu_HU.po
index 57a7a5acc0..f230c84d1a 100644
--- a/po/hu_HU.po
+++ b/po/hu_HU.po
@@ -7,14 +7,14 @@ msgid ""
msgstr ""
"Project-Id-Version: ScummVM 1.3.0svn\n"
"Report-Msgid-Bugs-To: scummvm-devel@lists.sf.net\n"
-"POT-Creation-Date: 2011-10-19 13:42+0100\n"
-"PO-Revision-Date: 2011-10-06 11:24+0100\n"
+"POT-Creation-Date: 2012-03-07 22:09+0000\n"
+"PO-Revision-Date: 2012-02-17 07:10+0100\n"
"Last-Translator: Gruby <grubycza@hotmail.com>\n"
"Language-Team: Hungarian\n"
-"Language: Magyar\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=iso-8859-2\n"
"Content-Transfer-Encoding: 8bit\n"
+"Language: Magyar\n"
"Plural-Forms: nplurals=2; plural=(n != 1)\n"
"X-Poedit-Language: Hungarian\n"
"X-Poedit-Country: HUNGARY\n"
@@ -47,13 +47,13 @@ msgid "Go up"
msgstr "Feljebb"
#: gui/browser.cpp:69 gui/chooser.cpp:45 gui/KeysDialog.cpp:43
-#: gui/launcher.cpp:312 gui/massadd.cpp:94 gui/options.cpp:1178
+#: gui/launcher.cpp:320 gui/massadd.cpp:94 gui/options.cpp:1253
#: gui/saveload.cpp:63 gui/saveload.cpp:155 gui/themebrowser.cpp:54
-#: engines/engine.cpp:436 engines/scumm/dialogs.cpp:190
+#: engines/engine.cpp:442 engines/scumm/dialogs.cpp:190
#: engines/sword1/control.cpp:865 engines/parallaction/saveload.cpp:281
#: backends/platform/wii/options.cpp:48
-#: backends/events/default/default-events.cpp:222
-#: backends/events/default/default-events.cpp:244
+#: backends/events/default/default-events.cpp:191
+#: backends/events/default/default-events.cpp:213
msgid "Cancel"
msgstr "Mégse"
@@ -61,25 +61,29 @@ msgstr "Mégse"
msgid "Choose"
msgstr "Választ"
-#: gui/gui-manager.cpp:116 engines/scumm/help.cpp:125
+#: gui/gui-manager.cpp:115 engines/scumm/help.cpp:125
#: engines/scumm/help.cpp:140 engines/scumm/help.cpp:165
#: engines/scumm/help.cpp:191 engines/scumm/help.cpp:209
#: backends/keymapper/remap-dialog.cpp:52
msgid "Close"
msgstr "Bezár"
-#: gui/gui-manager.cpp:119
+#: gui/gui-manager.cpp:118
msgid "Mouse click"
msgstr "Egérkattintás"
-#: gui/gui-manager.cpp:122 base/main.cpp:283
+#: gui/gui-manager.cpp:122 base/main.cpp:288
msgid "Display keyboard"
msgstr "Billentyûzet beállítások"
-#: gui/gui-manager.cpp:125 base/main.cpp:286
+#: gui/gui-manager.cpp:126 base/main.cpp:292
msgid "Remap keys"
msgstr "Billentyûk átállítása"
+#: gui/gui-manager.cpp:129 base/main.cpp:295
+msgid "Toggle FullScreen"
+msgstr "Teljesképernyõ kapcsoló"
+
#: gui/KeysDialog.h:36 gui/KeysDialog.cpp:145
msgid "Choose an action to map"
msgstr "Válassz mûveletet a kiosztáshoz"
@@ -88,16 +92,17 @@ msgstr "Válassz mûveletet a kiosztáshoz"
msgid "Map"
msgstr "Kiosztás"
-#: gui/KeysDialog.cpp:42 gui/launcher.cpp:313 gui/launcher.cpp:936
-#: gui/launcher.cpp:940 gui/massadd.cpp:91 gui/options.cpp:1179
-#: engines/engine.cpp:359 engines/engine.cpp:370 engines/scumm/dialogs.cpp:192
-#: engines/scumm/scumm.cpp:1776 engines/agos/animation.cpp:551
+#: gui/KeysDialog.cpp:42 gui/launcher.cpp:321 gui/launcher.cpp:960
+#: gui/launcher.cpp:964 gui/massadd.cpp:91 gui/options.cpp:1254
+#: engines/engine.cpp:361 engines/engine.cpp:372 engines/scumm/dialogs.cpp:192
+#: engines/scumm/scumm.cpp:1775 engines/agos/animation.cpp:551
#: engines/groovie/script.cpp:420 engines/sky/compact.cpp:131
-#: engines/sky/compact.cpp:141 engines/sword1/animation.cpp:344
-#: engines/sword1/animation.cpp:354 engines/sword1/animation.cpp:360
-#: engines/sword1/control.cpp:865 engines/sword1/logic.cpp:1633
-#: engines/sword2/animation.cpp:379 engines/sword2/animation.cpp:389
-#: engines/sword2/animation.cpp:398 engines/parallaction/saveload.cpp:281
+#: engines/sky/compact.cpp:141 engines/sword1/animation.cpp:539
+#: engines/sword1/animation.cpp:560 engines/sword1/animation.cpp:570
+#: engines/sword1/animation.cpp:577 engines/sword1/control.cpp:865
+#: engines/sword1/logic.cpp:1633 engines/sword2/animation.cpp:435
+#: engines/sword2/animation.cpp:455 engines/sword2/animation.cpp:465
+#: engines/sword2/animation.cpp:474 engines/parallaction/saveload.cpp:281
#: backends/platform/wii/options.cpp:47
#: backends/platform/wince/CELauncherDialog.cpp:54
msgid "OK"
@@ -125,326 +130,324 @@ msgstr "Válassz egy mûveletet"
msgid "Press the key to associate"
msgstr "Nyomj egy billentyût a társításhoz"
-#: gui/launcher.cpp:165
+#: gui/launcher.cpp:170
msgid "Game"
msgstr "Játék"
-#: gui/launcher.cpp:169
+#: gui/launcher.cpp:174
msgid "ID:"
msgstr "ID:"
-#: gui/launcher.cpp:169 gui/launcher.cpp:171 gui/launcher.cpp:172
+#: gui/launcher.cpp:174 gui/launcher.cpp:176 gui/launcher.cpp:177
msgid ""
"Short game identifier used for referring to savegames and running the game "
"from the command line"
msgstr ""
"Rövid játékazonosító a játékmentésekhez és a játék parancssori futtatásához"
-#: gui/launcher.cpp:171
+#: gui/launcher.cpp:176
msgctxt "lowres"
msgid "ID:"
msgstr "ID:"
-#: gui/launcher.cpp:176
+#: gui/launcher.cpp:181
msgid "Name:"
msgstr "Név:"
-#: gui/launcher.cpp:176 gui/launcher.cpp:178 gui/launcher.cpp:179
+#: gui/launcher.cpp:181 gui/launcher.cpp:183 gui/launcher.cpp:184
msgid "Full title of the game"
msgstr "A játék teljes neve"
-#: gui/launcher.cpp:178
+#: gui/launcher.cpp:183
msgctxt "lowres"
msgid "Name:"
msgstr "Név:"
-#: gui/launcher.cpp:182
+#: gui/launcher.cpp:187
msgid "Language:"
msgstr "Nyelv:"
-#: gui/launcher.cpp:182 gui/launcher.cpp:183
+#: gui/launcher.cpp:187 gui/launcher.cpp:188
msgid ""
"Language of the game. This will not turn your Spanish game version into "
"English"
msgstr ""
"A játék nyelve. Ne állítsd át a pl. Spanyol nyelvû játékodat Angol nyelvre"
-#: gui/launcher.cpp:184 gui/launcher.cpp:198 gui/options.cpp:74
-#: gui/options.cpp:708 gui/options.cpp:718 gui/options.cpp:1149
+#: gui/launcher.cpp:189 gui/launcher.cpp:203 gui/options.cpp:80
+#: gui/options.cpp:745 gui/options.cpp:758 gui/options.cpp:1224
#: audio/null.cpp:40
msgid "<default>"
msgstr "<alapértelmezett>"
-#: gui/launcher.cpp:194
+#: gui/launcher.cpp:199
msgid "Platform:"
msgstr "Platform:"
-#: gui/launcher.cpp:194 gui/launcher.cpp:196 gui/launcher.cpp:197
+#: gui/launcher.cpp:199 gui/launcher.cpp:201 gui/launcher.cpp:202
msgid "Platform the game was originally designed for"
msgstr "Platform amire a játékot eredetileg készítették"
-#: gui/launcher.cpp:196
+#: gui/launcher.cpp:201
msgctxt "lowres"
msgid "Platform:"
msgstr "Platform:"
-#: gui/launcher.cpp:208 gui/options.cpp:1018 gui/options.cpp:1035
+#: gui/launcher.cpp:213 gui/options.cpp:1087 gui/options.cpp:1104
msgid "Graphics"
msgstr "Grafika"
-#: gui/launcher.cpp:208 gui/options.cpp:1018 gui/options.cpp:1035
+#: gui/launcher.cpp:213 gui/options.cpp:1087 gui/options.cpp:1104
msgid "GFX"
msgstr "GFX"
-#: gui/launcher.cpp:211
+#: gui/launcher.cpp:216
msgid "Override global graphic settings"
msgstr "Globális grafikai beállítások felülbírálása"
-#: gui/launcher.cpp:213
+#: gui/launcher.cpp:218
msgctxt "lowres"
msgid "Override global graphic settings"
msgstr "Globális grafikai beállítások felülbírálása"
-#: gui/launcher.cpp:220 gui/options.cpp:1041
+#: gui/launcher.cpp:225 gui/options.cpp:1110
msgid "Audio"
msgstr "Audió"
-#: gui/launcher.cpp:223
+#: gui/launcher.cpp:228
msgid "Override global audio settings"
msgstr "Globális audió beállítások felülbírálása"
-#: gui/launcher.cpp:225
+#: gui/launcher.cpp:230
msgctxt "lowres"
msgid "Override global audio settings"
msgstr "Globális audió beállítások felülbírálása"
-#: gui/launcher.cpp:234 gui/options.cpp:1046
+#: gui/launcher.cpp:239 gui/options.cpp:1115
msgid "Volume"
msgstr "Hangerõ"
-#: gui/launcher.cpp:236 gui/options.cpp:1048
+#: gui/launcher.cpp:241 gui/options.cpp:1117
msgctxt "lowres"
msgid "Volume"
msgstr "Hangerõ"
-#: gui/launcher.cpp:239
+#: gui/launcher.cpp:244
msgid "Override global volume settings"
msgstr "Globális hangerõbeállítások felülbírálása"
-#: gui/launcher.cpp:241
+#: gui/launcher.cpp:246
msgctxt "lowres"
msgid "Override global volume settings"
msgstr "Globális hangerõbeállítások felülbírálása"
-#: gui/launcher.cpp:248 gui/options.cpp:1056
+#: gui/launcher.cpp:254 gui/options.cpp:1125
msgid "MIDI"
msgstr "MIDI"
-#: gui/launcher.cpp:251
+#: gui/launcher.cpp:257
msgid "Override global MIDI settings"
msgstr "Globális MIDI beállítások felülbírálása"
-#: gui/launcher.cpp:253
+#: gui/launcher.cpp:259
msgctxt "lowres"
msgid "Override global MIDI settings"
msgstr "Globális MIDI beállítások felülbírálása"
-#: gui/launcher.cpp:263 gui/options.cpp:1062
+#: gui/launcher.cpp:268 gui/options.cpp:1131
msgid "MT-32"
msgstr "MT-32"
-#: gui/launcher.cpp:266
+#: gui/launcher.cpp:271
msgid "Override global MT-32 settings"
msgstr "Globális MT-32 beállítások felülbírálása"
-#: gui/launcher.cpp:268
+#: gui/launcher.cpp:273
msgctxt "lowres"
msgid "Override global MT-32 settings"
msgstr "Globális MT-32 beállítások felülbírálása"
-#: gui/launcher.cpp:279 gui/options.cpp:1069
+#: gui/launcher.cpp:282 gui/options.cpp:1138
msgid "Paths"
msgstr "Mappák"
-#: gui/launcher.cpp:281 gui/options.cpp:1071
+#: gui/launcher.cpp:284 gui/options.cpp:1140
msgctxt "lowres"
msgid "Paths"
msgstr "Mappák"
-#: gui/launcher.cpp:288
+#: gui/launcher.cpp:291
msgid "Game Path:"
msgstr "Játék Mappa:"
-#: gui/launcher.cpp:290
+#: gui/launcher.cpp:293
msgctxt "lowres"
msgid "Game Path:"
msgstr "Játék Mappa:"
-#: gui/launcher.cpp:295 gui/options.cpp:1091
+#: gui/launcher.cpp:298 gui/options.cpp:1164
msgid "Extra Path:"
msgstr "Extra Mappa:"
-#: gui/launcher.cpp:295 gui/launcher.cpp:297 gui/launcher.cpp:298
+#: gui/launcher.cpp:298 gui/launcher.cpp:300 gui/launcher.cpp:301
msgid "Specifies path to additional data used the game"
msgstr "Mappa kiválasztás a játékok kiegészítõ fájljaihoz"
-#: gui/launcher.cpp:297 gui/options.cpp:1093
+#: gui/launcher.cpp:300 gui/options.cpp:1166
msgctxt "lowres"
msgid "Extra Path:"
msgstr "Extra Mappa:"
-#: gui/launcher.cpp:302 gui/options.cpp:1079
+#: gui/launcher.cpp:307 gui/options.cpp:1148
msgid "Save Path:"
msgstr "Mentés Mappa:"
-#: gui/launcher.cpp:302 gui/launcher.cpp:304 gui/launcher.cpp:305
-#: gui/options.cpp:1079 gui/options.cpp:1081 gui/options.cpp:1082
+#: gui/launcher.cpp:307 gui/launcher.cpp:309 gui/launcher.cpp:310
+#: gui/options.cpp:1148 gui/options.cpp:1150 gui/options.cpp:1151
msgid "Specifies where your savegames are put"
msgstr "Játékmentések helyének meghatározása"
-#: gui/launcher.cpp:304 gui/options.cpp:1081
+#: gui/launcher.cpp:309 gui/options.cpp:1150
msgctxt "lowres"
msgid "Save Path:"
msgstr "Mentés Mappa:"
-#: gui/launcher.cpp:321 gui/launcher.cpp:404 gui/launcher.cpp:453
-#: gui/options.cpp:1088 gui/options.cpp:1094 gui/options.cpp:1101
-#: gui/options.cpp:1202 gui/options.cpp:1208 gui/options.cpp:1214
-#: gui/options.cpp:1222 gui/options.cpp:1246 gui/options.cpp:1250
-#: gui/options.cpp:1256 gui/options.cpp:1263 gui/options.cpp:1362
+#: gui/launcher.cpp:329 gui/launcher.cpp:416 gui/launcher.cpp:469
+#: gui/launcher.cpp:523 gui/options.cpp:1159 gui/options.cpp:1167
+#: gui/options.cpp:1176 gui/options.cpp:1283 gui/options.cpp:1289
+#: gui/options.cpp:1297 gui/options.cpp:1327 gui/options.cpp:1333
+#: gui/options.cpp:1340 gui/options.cpp:1433 gui/options.cpp:1436
+#: gui/options.cpp:1448
msgctxt "path"
msgid "None"
msgstr "Nincs"
-#: gui/launcher.cpp:326 gui/launcher.cpp:408
+#: gui/launcher.cpp:334 gui/launcher.cpp:422 gui/launcher.cpp:527
+#: gui/options.cpp:1277 gui/options.cpp:1321 gui/options.cpp:1439
#: backends/platform/wii/options.cpp:56
msgid "Default"
msgstr "Alapértelmezett"
-#: gui/launcher.cpp:446 gui/options.cpp:1356
+#: gui/launcher.cpp:462 gui/options.cpp:1442
msgid "Select SoundFont"
msgstr "SoundFont kiválasztás"
-#: gui/launcher.cpp:465 gui/launcher.cpp:612
+#: gui/launcher.cpp:481 gui/launcher.cpp:636
msgid "Select directory with game data"
msgstr "Játékok helyének kiválasztása"
-#: gui/launcher.cpp:483
+#: gui/launcher.cpp:499
msgid "Select additional game directory"
msgstr "Válassz mappát a játék kiegészítõkhöz"
-#: gui/launcher.cpp:495
+#: gui/launcher.cpp:511
msgid "Select directory for saved games"
msgstr "Válaszz játékmentéseknek mappát"
-#: gui/launcher.cpp:514
+#: gui/launcher.cpp:538
msgid "This game ID is already taken. Please choose another one."
msgstr "Ez a játékazonosító ID már foglalt, Válassz egy másikat."
-#: gui/launcher.cpp:555 engines/dialogs.cpp:110
+#: gui/launcher.cpp:579 engines/dialogs.cpp:110
msgid "~Q~uit"
msgstr "Kilépés"
-#: gui/launcher.cpp:555 backends/platform/sdl/macosx/appmenu_osx.mm:80
+#: gui/launcher.cpp:579 backends/platform/sdl/macosx/appmenu_osx.mm:96
msgid "Quit ScummVM"
msgstr "ScummVM bezárása"
-#: gui/launcher.cpp:556
+#: gui/launcher.cpp:580
msgid "A~b~out..."
msgstr "Névjegy"
-#: gui/launcher.cpp:556 backends/platform/sdl/macosx/appmenu_osx.mm:61
+#: gui/launcher.cpp:580 backends/platform/sdl/macosx/appmenu_osx.mm:70
msgid "About ScummVM"
msgstr "ScummVM névjegy"
-#: gui/launcher.cpp:557
+#: gui/launcher.cpp:581
msgid "~O~ptions..."
msgstr "~O~pciók..."
-#: gui/launcher.cpp:557
+#: gui/launcher.cpp:581
msgid "Change global ScummVM options"
msgstr "Globális ScummVM opciók cseréje"
-#: gui/launcher.cpp:559
+#: gui/launcher.cpp:583
msgid "~S~tart"
msgstr "Indítás"
-#: gui/launcher.cpp:559
+#: gui/launcher.cpp:583
msgid "Start selected game"
msgstr "A választott játék indítása"
-#: gui/launcher.cpp:562
+#: gui/launcher.cpp:586
msgid "~L~oad..."
msgstr "Betöltés"
-#: gui/launcher.cpp:562
+#: gui/launcher.cpp:586
msgid "Load savegame for selected game"
msgstr "Kimentett játékállás betöltése"
-#: gui/launcher.cpp:567 gui/launcher.cpp:1055
+#: gui/launcher.cpp:591 gui/launcher.cpp:1079
msgid "~A~dd Game..."
msgstr "Játék hozzáadás"
-#: gui/launcher.cpp:567 gui/launcher.cpp:574
+#: gui/launcher.cpp:591 gui/launcher.cpp:598
msgid "Hold Shift for Mass Add"
msgstr "Tratsd lenyomva a Shift-et a Masszív módhoz"
-#: gui/launcher.cpp:569
+#: gui/launcher.cpp:593
msgid "~E~dit Game..."
msgstr "Játékopciók"
-#: gui/launcher.cpp:569 gui/launcher.cpp:576
+#: gui/launcher.cpp:593 gui/launcher.cpp:600
msgid "Change game options"
msgstr "Játék beállítások megváltoztatása"
-#: gui/launcher.cpp:571
+#: gui/launcher.cpp:595
msgid "~R~emove Game"
msgstr "Játék törlése"
-#: gui/launcher.cpp:571 gui/launcher.cpp:578
+#: gui/launcher.cpp:595 gui/launcher.cpp:602
msgid "Remove game from the list. The game data files stay intact"
msgstr "Törli a játék nevét a listáról. A játékfájlok megmaradnak"
-#: gui/launcher.cpp:574 gui/launcher.cpp:1055
+#: gui/launcher.cpp:598 gui/launcher.cpp:1079
msgctxt "lowres"
msgid "~A~dd Game..."
msgstr "Játék hozzáadás"
-#: gui/launcher.cpp:576
+#: gui/launcher.cpp:600
msgctxt "lowres"
msgid "~E~dit Game..."
msgstr "Játékopciók"
-#: gui/launcher.cpp:578
+#: gui/launcher.cpp:602
msgctxt "lowres"
msgid "~R~emove Game"
msgstr "Játék törlése"
-#: gui/launcher.cpp:586
+#: gui/launcher.cpp:610
msgid "Search in game list"
msgstr "Keresés a játéklistában"
-#: gui/launcher.cpp:590 gui/launcher.cpp:1102
+#: gui/launcher.cpp:614 gui/launcher.cpp:1126
msgid "Search:"
msgstr "Keresés:"
-#: gui/launcher.cpp:593 gui/options.cpp:826
-msgid "Clear value"
-msgstr "Érték törlése"
-
-#: gui/launcher.cpp:615 engines/dialogs.cpp:114 engines/mohawk/myst.cpp:255
+#: gui/launcher.cpp:639 engines/dialogs.cpp:114 engines/mohawk/myst.cpp:255
#: engines/mohawk/riven.cpp:716 engines/cruise/menu.cpp:216
msgid "Load game:"
msgstr "Játék betöltése:"
-#: gui/launcher.cpp:615 engines/dialogs.cpp:114 engines/scumm/dialogs.cpp:188
+#: gui/launcher.cpp:639 engines/dialogs.cpp:114 engines/scumm/dialogs.cpp:188
#: engines/mohawk/myst.cpp:255 engines/mohawk/riven.cpp:716
#: engines/cruise/menu.cpp:216 backends/platform/wince/CEActionsPocket.cpp:267
#: backends/platform/wince/CEActionsSmartphone.cpp:231
msgid "Load"
msgstr "Betöltés"
-#: gui/launcher.cpp:723
+#: gui/launcher.cpp:747
msgid ""
"Do you really want to run the mass game detector? This could potentially add "
"a huge number of games."
@@ -452,7 +455,7 @@ msgstr ""
"Biztos hogy futtatod a Masszív játékdetektort? Ez potenciálisan sok játékot "
"hozzáad a listához."
-#: gui/launcher.cpp:724 gui/launcher.cpp:872
+#: gui/launcher.cpp:748 gui/launcher.cpp:896
#: backends/events/symbiansdl/symbiansdl-events.cpp:184
#: backends/platform/wince/CEActionsPocket.cpp:326
#: backends/platform/wince/CEActionsSmartphone.cpp:287
@@ -460,7 +463,7 @@ msgstr ""
msgid "Yes"
msgstr "Igen"
-#: gui/launcher.cpp:724 gui/launcher.cpp:872
+#: gui/launcher.cpp:748 gui/launcher.cpp:896
#: backends/events/symbiansdl/symbiansdl-events.cpp:184
#: backends/platform/wince/CEActionsPocket.cpp:326
#: backends/platform/wince/CEActionsSmartphone.cpp:287
@@ -468,37 +471,37 @@ msgstr "Igen"
msgid "No"
msgstr "Nem"
-#: gui/launcher.cpp:772
+#: gui/launcher.cpp:796
msgid "ScummVM couldn't open the specified directory!"
msgstr "ScummVM nem tudja megnyitni a választott mappát!"
-#: gui/launcher.cpp:784
+#: gui/launcher.cpp:808
msgid "ScummVM could not find any game in the specified directory!"
msgstr "A ScummVM nem talált egy játékot sem a választott mappában!"
-#: gui/launcher.cpp:798
+#: gui/launcher.cpp:822
msgid "Pick the game:"
msgstr "Válassztott játék:"
-#: gui/launcher.cpp:872
+#: gui/launcher.cpp:896
msgid "Do you really want to remove this game configuration?"
msgstr "Biztosan törölni akarod ezt a játékkonfigurációt?"
-#: gui/launcher.cpp:936
+#: gui/launcher.cpp:960
msgid "This game does not support loading games from the launcher."
msgstr "Ez a játék nem támogatja a játékállás betöltést az indítóból."
-#: gui/launcher.cpp:940
+#: gui/launcher.cpp:964
msgid "ScummVM could not find any engine capable of running the selected game!"
msgstr ""
"ScummVM nem talált olyan játékmotort ami a választott játékot támogatja!"
-#: gui/launcher.cpp:1054
+#: gui/launcher.cpp:1078
msgctxt "lowres"
msgid "Mass Add..."
msgstr "Masszív mód..."
-#: gui/launcher.cpp:1054
+#: gui/launcher.cpp:1078
msgid "Mass Add..."
msgstr "Masszív mód..."
@@ -525,202 +528,202 @@ msgstr "%d Mappa átvizsgálva..."
msgid "Discovered %d new games, ignored %d previously added games ..."
msgstr "%d új játékot találtam, %d elõzõleg hozzáadott játék kihagyva..."
-#: gui/options.cpp:72
+#: gui/options.cpp:78
msgid "Never"
msgstr "Soha"
-#: gui/options.cpp:72
+#: gui/options.cpp:78
msgid "every 5 mins"
msgstr "5 percenként"
-#: gui/options.cpp:72
+#: gui/options.cpp:78
msgid "every 10 mins"
msgstr "10 percenként"
-#: gui/options.cpp:72
+#: gui/options.cpp:78
msgid "every 15 mins"
msgstr "15 percenként"
-#: gui/options.cpp:72
+#: gui/options.cpp:78
msgid "every 30 mins"
msgstr "30 percenként"
-#: gui/options.cpp:74
+#: gui/options.cpp:80
msgid "8 kHz"
msgstr "8 kHz"
-#: gui/options.cpp:74
+#: gui/options.cpp:80
msgid "11kHz"
msgstr "11kHz"
-#: gui/options.cpp:74
+#: gui/options.cpp:80
msgid "22 kHz"
msgstr "22 kHz"
-#: gui/options.cpp:74
+#: gui/options.cpp:80
msgid "44 kHz"
msgstr "44 kHz"
-#: gui/options.cpp:74
+#: gui/options.cpp:80
msgid "48 kHz"
msgstr "48 kHz"
-#: gui/options.cpp:236 gui/options.cpp:464 gui/options.cpp:559
-#: gui/options.cpp:625 gui/options.cpp:825
+#: gui/options.cpp:257 gui/options.cpp:485 gui/options.cpp:586
+#: gui/options.cpp:659 gui/options.cpp:868
msgctxt "soundfont"
msgid "None"
msgstr "Nincs"
-#: gui/options.cpp:372
+#: gui/options.cpp:393
msgid "Failed to apply some of the graphic options changes:"
msgstr "Néhány grafikus opció változtatása sikertelen:"
-#: gui/options.cpp:384
+#: gui/options.cpp:405
msgid "the video mode could not be changed."
msgstr "a videómód nem változott."
-#: gui/options.cpp:390
+#: gui/options.cpp:411
msgid "the fullscreen setting could not be changed"
msgstr "a teljesképernyõs beállítás nem változott"
-#: gui/options.cpp:396
+#: gui/options.cpp:417
msgid "the aspect ratio setting could not be changed"
msgstr "a képméretarány beállítások nem változtak"
-#: gui/options.cpp:705
+#: gui/options.cpp:742
msgid "Graphics mode:"
msgstr "Grafikus mód:"
-#: gui/options.cpp:716
+#: gui/options.cpp:756
msgid "Render mode:"
msgstr "Kirajzolás mód:"
-#: gui/options.cpp:716 gui/options.cpp:717
+#: gui/options.cpp:756 gui/options.cpp:757
msgid "Special dithering modes supported by some games"
msgstr "Néhány játék támogatja a speciális árnyalási módokat"
-#: gui/options.cpp:726
+#: gui/options.cpp:768
#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2248
-#: backends/graphics/openglsdl/openglsdl-graphics.cpp:476
+#: backends/graphics/openglsdl/openglsdl-graphics.cpp:472
msgid "Fullscreen mode"
msgstr "Teljesképernyõs mód:"
-#: gui/options.cpp:729
+#: gui/options.cpp:771
msgid "Aspect ratio correction"
msgstr "Képméretarány korrekció"
-#: gui/options.cpp:729
+#: gui/options.cpp:771
msgid "Correct aspect ratio for 320x200 games"
msgstr "Helyes oldalarány a 320x200 játékokhoz"
-#: gui/options.cpp:730
+#: gui/options.cpp:772
msgid "EGA undithering"
msgstr "EGA szinjavítás"
-#: gui/options.cpp:730
+#: gui/options.cpp:772
msgid "Enable undithering in EGA games that support it"
msgstr "EGA színjavítás támogatott EGA játékokban"
-#: gui/options.cpp:738
+#: gui/options.cpp:780
msgid "Preferred Device:"
msgstr "Elsõdleges eszköz:"
-#: gui/options.cpp:738
+#: gui/options.cpp:780
msgid "Music Device:"
msgstr "Zene eszköz:"
-#: gui/options.cpp:738 gui/options.cpp:740
+#: gui/options.cpp:780 gui/options.cpp:782
msgid "Specifies preferred sound device or sound card emulator"
msgstr "Elsõdleges hangeszköz vagy hang emulátor beállítások"
-#: gui/options.cpp:738 gui/options.cpp:740 gui/options.cpp:741
+#: gui/options.cpp:780 gui/options.cpp:782 gui/options.cpp:783
msgid "Specifies output sound device or sound card emulator"
msgstr "Hangeszköz vagy hangkártya emulátor beállítások"
-#: gui/options.cpp:740
+#: gui/options.cpp:782
msgctxt "lowres"
msgid "Preferred Dev.:"
msgstr "Elsõdleges eszk.:"
-#: gui/options.cpp:740
+#: gui/options.cpp:782
msgctxt "lowres"
msgid "Music Device:"
msgstr "Zene eszköz:"
-#: gui/options.cpp:766
+#: gui/options.cpp:809
msgid "AdLib emulator:"
msgstr "AdLib emulátor:"
-#: gui/options.cpp:766 gui/options.cpp:767
+#: gui/options.cpp:809 gui/options.cpp:810
msgid "AdLib is used for music in many games"
msgstr "AdLib meghajtót sok játék használja zenéhez"
-#: gui/options.cpp:777
+#: gui/options.cpp:820
msgid "Output rate:"
msgstr "Kimeneti ráta:"
-#: gui/options.cpp:777 gui/options.cpp:778
+#: gui/options.cpp:820 gui/options.cpp:821
msgid ""
"Higher value specifies better sound quality but may be not supported by your "
"soundcard"
msgstr ""
"Nagyobb értékek jobb hangminõséget adnak, de nem minden hangkártya támogatja"
-#: gui/options.cpp:788
+#: gui/options.cpp:831
msgid "GM Device:"
msgstr "GM Eszköz:"
-#: gui/options.cpp:788
+#: gui/options.cpp:831
msgid "Specifies default sound device for General MIDI output"
msgstr "Alapértelmezett hangeszköz General MIDI kimenethez"
-#: gui/options.cpp:799
+#: gui/options.cpp:842
msgid "Don't use General MIDI music"
msgstr "Ne használj General MIDI zenét"
-#: gui/options.cpp:810 gui/options.cpp:871
+#: gui/options.cpp:853 gui/options.cpp:915
msgid "Use first available device"
msgstr "Elsõ elérhetõ eszköz használata"
-#: gui/options.cpp:822
+#: gui/options.cpp:865
msgid "SoundFont:"
msgstr "SoundFont:"
-#: gui/options.cpp:822 gui/options.cpp:824 gui/options.cpp:825
+#: gui/options.cpp:865 gui/options.cpp:867 gui/options.cpp:868
msgid "SoundFont is supported by some audio cards, Fluidsynth and Timidity"
msgstr ""
"Néhány hangkárya, Fluidsynth és Timidyti támogatja a SoundFont betöltését"
-#: gui/options.cpp:824
+#: gui/options.cpp:867
msgctxt "lowres"
msgid "SoundFont:"
msgstr "SoundFont:"
-#: gui/options.cpp:829
+#: gui/options.cpp:873
msgid "Mixed AdLib/MIDI mode"
msgstr "Vegyes AdLib/MIDI mód"
-#: gui/options.cpp:829
+#: gui/options.cpp:873
msgid "Use both MIDI and AdLib sound generation"
msgstr "MIDI és AdLib hanggenerátorok használata"
-#: gui/options.cpp:832
+#: gui/options.cpp:876
msgid "MIDI gain:"
msgstr "MIDI erõsítés:"
-#: gui/options.cpp:842
+#: gui/options.cpp:886
msgid "MT-32 Device:"
msgstr "MT-32 Eszköz:"
-#: gui/options.cpp:842
+#: gui/options.cpp:886
msgid "Specifies default sound device for Roland MT-32/LAPC1/CM32l/CM64 output"
msgstr "Roland MT-32/LAPC1/CM32l/CM64 alapértelmezett hangeszközök beállítása"
-#: gui/options.cpp:847
+#: gui/options.cpp:891
msgid "True Roland MT-32 (disable GM emulation)"
msgstr "Roland MT-32 Hardver (GM emuláció tiltva)"
-#: gui/options.cpp:847 gui/options.cpp:849
+#: gui/options.cpp:891 gui/options.cpp:893
msgid ""
"Check if you want to use your real hardware Roland-compatible sound device "
"connected to your computer"
@@ -728,190 +731,190 @@ msgstr ""
"Jelöld be, ha hardveres Roland-Kompatibilis hangeszköz van csatlakoztatva a "
"gépedhez és használni akarod"
-#: gui/options.cpp:849
+#: gui/options.cpp:893
msgctxt "lowres"
msgid "True Roland MT-32 (no GM emulation)"
msgstr "Roland MT-32 Hardver (GM emuláció nincs)"
-#: gui/options.cpp:852
+#: gui/options.cpp:896
msgid "Enable Roland GS Mode"
msgstr "Roland GS Mód engedélyezve"
-#: gui/options.cpp:852
+#: gui/options.cpp:896
msgid "Turns off General MIDI mapping for games with Roland MT-32 soundtrack"
msgstr "General MIDI leképezés Roland MT-32 zenés játékokhoz kikapcsolva"
-#: gui/options.cpp:861
+#: gui/options.cpp:905
msgid "Don't use Roland MT-32 music"
msgstr "Ne használj Roland MT-32 zenét"
-#: gui/options.cpp:888
+#: gui/options.cpp:932
msgid "Text and Speech:"
msgstr "Szöveg és beszéd:"
-#: gui/options.cpp:892 gui/options.cpp:902
+#: gui/options.cpp:936 gui/options.cpp:946
msgid "Speech"
msgstr "Csak beszéd"
-#: gui/options.cpp:893 gui/options.cpp:903
+#: gui/options.cpp:937 gui/options.cpp:947
msgid "Subtitles"
msgstr "Csak felirat"
-#: gui/options.cpp:894
+#: gui/options.cpp:938
msgid "Both"
msgstr "Mind"
-#: gui/options.cpp:896
+#: gui/options.cpp:940
msgid "Subtitle speed:"
msgstr "Felirat sebesség:"
-#: gui/options.cpp:898
+#: gui/options.cpp:942
msgctxt "lowres"
msgid "Text and Speech:"
msgstr "Felirat és beszéd:"
-#: gui/options.cpp:902
+#: gui/options.cpp:946
msgid "Spch"
msgstr "Besz"
-#: gui/options.cpp:903
+#: gui/options.cpp:947
msgid "Subs"
msgstr "Text"
-#: gui/options.cpp:904
+#: gui/options.cpp:948
msgctxt "lowres"
msgid "Both"
msgstr "Mind"
-#: gui/options.cpp:904
+#: gui/options.cpp:948
msgid "Show subtitles and play speech"
msgstr "Hang és feliratok megjelenítése"
-#: gui/options.cpp:906
+#: gui/options.cpp:950
msgctxt "lowres"
msgid "Subtitle speed:"
msgstr "Felirat sebesség:"
-#: gui/options.cpp:922
+#: gui/options.cpp:966
msgid "Music volume:"
msgstr "Zene hangerõ:"
-#: gui/options.cpp:924
+#: gui/options.cpp:968
msgctxt "lowres"
msgid "Music volume:"
msgstr "Zene hangerõ:"
-#: gui/options.cpp:931
+#: gui/options.cpp:975
msgid "Mute All"
msgstr "Összes némítása"
-#: gui/options.cpp:934
+#: gui/options.cpp:978
msgid "SFX volume:"
msgstr "SFX hangerõ:"
-#: gui/options.cpp:934 gui/options.cpp:936 gui/options.cpp:937
+#: gui/options.cpp:978 gui/options.cpp:980 gui/options.cpp:981
msgid "Special sound effects volume"
msgstr "Speciális hangeffektusok hangereje"
-#: gui/options.cpp:936
+#: gui/options.cpp:980
msgctxt "lowres"
msgid "SFX volume:"
msgstr "SFX hangerõ:"
-#: gui/options.cpp:944
+#: gui/options.cpp:988
msgid "Speech volume:"
msgstr "Beszéd hangerõ:"
-#: gui/options.cpp:946
+#: gui/options.cpp:990
msgctxt "lowres"
msgid "Speech volume:"
msgstr "Beszéd hangerõ:"
-#: gui/options.cpp:1085
+#: gui/options.cpp:1156
msgid "Theme Path:"
msgstr "Téma Mappa:"
-#: gui/options.cpp:1087
+#: gui/options.cpp:1158
msgctxt "lowres"
msgid "Theme Path:"
msgstr "Téma Mappa:"
-#: gui/options.cpp:1091 gui/options.cpp:1093 gui/options.cpp:1094
+#: gui/options.cpp:1164 gui/options.cpp:1166 gui/options.cpp:1167
msgid "Specifies path to additional data used by all games or ScummVM"
msgstr "Minden jéték és ScummVM kiegészítõ fájljainak mappája:"
-#: gui/options.cpp:1098
+#: gui/options.cpp:1173
msgid "Plugins Path:"
msgstr "Plugin Mappa:"
-#: gui/options.cpp:1100
+#: gui/options.cpp:1175
msgctxt "lowres"
msgid "Plugins Path:"
msgstr "Plugin Mappa:"
-#: gui/options.cpp:1109
+#: gui/options.cpp:1184
msgid "Misc"
msgstr "Vegyes"
-#: gui/options.cpp:1111
+#: gui/options.cpp:1186
msgctxt "lowres"
msgid "Misc"
msgstr "Vegyes"
-#: gui/options.cpp:1113
+#: gui/options.cpp:1188
msgid "Theme:"
msgstr "Téma:"
-#: gui/options.cpp:1117
+#: gui/options.cpp:1192
msgid "GUI Renderer:"
msgstr "GUI Renderelõ:"
-#: gui/options.cpp:1129
+#: gui/options.cpp:1204
msgid "Autosave:"
msgstr "Automentés:"
-#: gui/options.cpp:1131
+#: gui/options.cpp:1206
msgctxt "lowres"
msgid "Autosave:"
msgstr "Automentés:"
-#: gui/options.cpp:1139
+#: gui/options.cpp:1214
msgid "Keys"
msgstr "Billentyûk"
-#: gui/options.cpp:1146
+#: gui/options.cpp:1221
msgid "GUI Language:"
msgstr "GUI nyelve:"
-#: gui/options.cpp:1146
+#: gui/options.cpp:1221
msgid "Language of ScummVM GUI"
msgstr "A ScummVM GUI nyelve"
-#: gui/options.cpp:1295
+#: gui/options.cpp:1372
msgid "You have to restart ScummVM before your changes will take effect."
msgstr "Indítsd újra a ScummVM-et a változások érvényesítéséhez."
-#: gui/options.cpp:1308
+#: gui/options.cpp:1385
msgid "Select directory for savegames"
msgstr "Válassz játékmentés mappát"
-#: gui/options.cpp:1315
+#: gui/options.cpp:1392
msgid "The chosen directory cannot be written to. Please select another one."
msgstr "A kiválasztott mappába nem lehet írni, válassz egy másikat"
-#: gui/options.cpp:1324
+#: gui/options.cpp:1401
msgid "Select directory for GUI themes"
msgstr "GUI téma mappa kiválasztása"
-#: gui/options.cpp:1334
+#: gui/options.cpp:1411
msgid "Select directory for extra files"
msgstr "Mappa választás az extra fájloknak"
-#: gui/options.cpp:1345
+#: gui/options.cpp:1422
msgid "Select directory for plugins"
msgstr "Plugin mappa kiválasztása"
-#: gui/options.cpp:1389
+#: gui/options.cpp:1475
msgid ""
"The theme you selected does not support your current language. If you want "
"to use this theme you need to switch to another language first."
@@ -959,60 +962,64 @@ msgstr "Névtelen játékállás"
msgid "Select a Theme"
msgstr "Válassz témát"
-#: gui/ThemeEngine.cpp:328
+#: gui/ThemeEngine.cpp:333
msgid "Disabled GFX"
msgstr "GFX letiltva"
-#: gui/ThemeEngine.cpp:328
+#: gui/ThemeEngine.cpp:333
msgctxt "lowres"
msgid "Disabled GFX"
msgstr "GFX letiltva"
-#: gui/ThemeEngine.cpp:329
+#: gui/ThemeEngine.cpp:334
msgid "Standard Renderer (16bpp)"
msgstr "Standard leképezõ (16bpp)"
-#: gui/ThemeEngine.cpp:329
+#: gui/ThemeEngine.cpp:334
msgid "Standard (16bpp)"
msgstr "Standard (16bpp)"
-#: gui/ThemeEngine.cpp:331
+#: gui/ThemeEngine.cpp:336
msgid "Antialiased Renderer (16bpp)"
msgstr "Élsimításos leképezõ (16bpp)"
-#: gui/ThemeEngine.cpp:331
+#: gui/ThemeEngine.cpp:336
msgid "Antialiased (16bpp)"
msgstr "Élsimított (16bpp)"
+#: gui/widget.cpp:312 gui/widget.cpp:314 gui/widget.cpp:320 gui/widget.cpp:322
+msgid "Clear value"
+msgstr "Érték törlése"
+
#: base/main.cpp:203
#, c-format
msgid "Engine does not support debug level '%s'"
msgstr "A motor nem támogatja a '%s' debug szintet"
-#: base/main.cpp:271
+#: base/main.cpp:275
msgid "Menu"
msgstr "Menü"
-#: base/main.cpp:274 backends/platform/symbian/src/SymbianActions.cpp:45
+#: base/main.cpp:278 backends/platform/symbian/src/SymbianActions.cpp:45
#: backends/platform/wince/CEActionsPocket.cpp:45
#: backends/platform/wince/CEActionsSmartphone.cpp:46
msgid "Skip"
msgstr "Tovább"
-#: base/main.cpp:277 backends/platform/symbian/src/SymbianActions.cpp:50
+#: base/main.cpp:281 backends/platform/symbian/src/SymbianActions.cpp:50
#: backends/platform/wince/CEActionsPocket.cpp:42
msgid "Pause"
msgstr "Szünet"
-#: base/main.cpp:280
+#: base/main.cpp:284
msgid "Skip line"
msgstr "Sor átlépése"
-#: base/main.cpp:439
+#: base/main.cpp:455
msgid "Error running game:"
msgstr "Hiba a játék futtatásakor:"
-#: base/main.cpp:463
+#: base/main.cpp:479
msgid "Could not find any engine capable of running the selected game"
msgstr "Nem található olyan játékmotor ami a választott játékot támogatja"
@@ -1080,25 +1087,6 @@ msgstr "Felhasználói megszakítás"
msgid "Unknown error"
msgstr "Ismeretlen hiba"
-#. I18N: Hercules is graphics card name
-#: common/util.cpp:275
-msgid "Hercules Green"
-msgstr "Hercules Zöld"
-
-#: common/util.cpp:276
-msgid "Hercules Amber"
-msgstr "Hercules Sárga"
-
-#: common/util.cpp:283
-msgctxt "lowres"
-msgid "Hercules Green"
-msgstr "Hercules Zöld"
-
-#: common/util.cpp:284
-msgctxt "lowres"
-msgid "Hercules Amber"
-msgstr "Hercules Sárga"
-
#: engines/advancedDetector.cpp:296
#, c-format
msgid "The game in '%s' seems to be unknown."
@@ -1146,12 +1134,12 @@ msgid "~R~eturn to Launcher"
msgstr "Visszatérés az indítóba"
#: engines/dialogs.cpp:116 engines/cruise/menu.cpp:214
-#: engines/sci/engine/kfile.cpp:578
+#: engines/sci/engine/kfile.cpp:566
msgid "Save game:"
msgstr "Játék mentése:"
#: engines/dialogs.cpp:116 engines/scumm/dialogs.cpp:187
-#: engines/cruise/menu.cpp:214 engines/sci/engine/kfile.cpp:578
+#: engines/cruise/menu.cpp:214 engines/sci/engine/kfile.cpp:566
#: backends/platform/symbian/src/SymbianActions.cpp:44
#: backends/platform/wince/CEActionsPocket.cpp:43
#: backends/platform/wince/CEActionsPocket.cpp:267
@@ -1169,37 +1157,46 @@ msgstr ""
"Sajnálom, a motor jelenleg nem tartalmaz játék közbeni súgót. Olvassd el a "
"README-t az alap információkról, és hogy hogyan segíthetsz a késõbbiekben."
-#: engines/dialogs.cpp:316 engines/mohawk/dialogs.cpp:109
+#: engines/dialogs.cpp:243
+#, fuzzy, c-format
+msgid ""
+"Gamestate save failed (%s)! Please consult the README for basic information, "
+"and for instructions on how to obtain further assistance."
+msgstr ""
+"Sajnálom, a motor jelenleg nem tartalmaz játék közbeni súgót. Olvassd el a "
+"README-t az alap információkról, és hogy hogyan segíthetsz a késõbbiekben."
+
+#: engines/dialogs.cpp:321 engines/mohawk/dialogs.cpp:109
#: engines/mohawk/dialogs.cpp:174
msgid "~O~K"
msgstr "~O~K"
-#: engines/dialogs.cpp:317 engines/mohawk/dialogs.cpp:110
+#: engines/dialogs.cpp:322 engines/mohawk/dialogs.cpp:110
#: engines/mohawk/dialogs.cpp:175
msgid "~C~ancel"
msgstr "Mégse"
-#: engines/dialogs.cpp:320
+#: engines/dialogs.cpp:325
msgid "~K~eys"
msgstr "Billentyük"
-#: engines/engine.cpp:233
+#: engines/engine.cpp:235
msgid "Could not initialize color format."
msgstr "Szín formátum nincs alkalmazva"
-#: engines/engine.cpp:241
+#: engines/engine.cpp:243
msgid "Could not switch to video mode: '"
msgstr "Videómód nincs átállítva: ' "
-#: engines/engine.cpp:250
+#: engines/engine.cpp:252
msgid "Could not apply aspect ratio setting."
msgstr "Méretarány korrekció nem változott."
-#: engines/engine.cpp:255
+#: engines/engine.cpp:257
msgid "Could not apply fullscreen setting."
msgstr "Teljesképernyõs beállítás nincs alkalmazva"
-#: engines/engine.cpp:355
+#: engines/engine.cpp:357
msgid ""
"You appear to be playing this game directly\n"
"from the CD. This is known to cause problems,\n"
@@ -1213,7 +1210,7 @@ msgstr ""
"adatfájljait a merevlemezedre.\n"
"Nézd meg a README fájlt a részletekért."
-#: engines/engine.cpp:366
+#: engines/engine.cpp:368
msgid ""
"This game has audio tracks in its disk. These\n"
"tracks need to be ripped from the disk using\n"
@@ -1227,7 +1224,16 @@ msgstr ""
"hogy a játék zenéje hallható legyen.\n"
"Nézd meg a README fájlt a részletekért."
-#: engines/engine.cpp:433
+#: engines/engine.cpp:426
+#, fuzzy, c-format
+msgid ""
+"Gamestate load failed (%s)! Please consult the README for basic information, "
+"and for instructions on how to obtain further assistance."
+msgstr ""
+"Sajnálom, a motor jelenleg nem tartalmaz játék közbeni súgót. Olvassd el a "
+"README-t az alap információkról, és hogy hogyan segíthetsz a késõbbiekben."
+
+#: engines/engine.cpp:439
msgid ""
"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 "
@@ -1237,7 +1243,7 @@ msgstr ""
"ScummVM. Számíts rá hogy nem stabilan fut, és a mentések nem mûködnek a "
"jövõbeni ScummVM verziókkal."
-#: engines/engine.cpp:436
+#: engines/engine.cpp:442
msgid "Start anyway"
msgstr "Indítás így is"
@@ -1281,7 +1287,7 @@ msgstr "Játék"
#: backends/platform/symbian/src/SymbianActions.cpp:52
#: backends/platform/wince/CEActionsPocket.cpp:44
#: backends/platform/wince/CEActionsSmartphone.cpp:52
-#: backends/events/default/default-events.cpp:244
+#: backends/events/default/default-events.cpp:213
msgid "Quit"
msgstr "Kilépés"
@@ -1355,6 +1361,26 @@ msgctxt "lowres"
msgid "Speech & Subs"
msgstr "Beszéd & Felir"
+#: engines/scumm/dialogs.cpp:653
+msgid "Select a Proficiency Level."
+msgstr "Válassz hozzáértés szintet."
+
+#: engines/scumm/dialogs.cpp:655
+msgid "Refer to your Loom(TM) manual for help."
+msgstr "Segítségért nézd meg a Loom(TM) kézikönyvedet."
+
+#: engines/scumm/dialogs.cpp:658
+msgid "Standard"
+msgstr "Átlagos"
+
+#: engines/scumm/dialogs.cpp:659
+msgid "Practice"
+msgstr "Gyakorlás"
+
+#: engines/scumm/dialogs.cpp:660
+msgid "Expert"
+msgstr "Szakértõ"
+
#: engines/scumm/help.cpp:73
msgid "Common keyboard commands:"
msgstr "Általános billentyûparancsok:"
@@ -1868,7 +1894,7 @@ msgstr "Jobbra repülés"
msgid "Fly to lower right"
msgstr "Jobbra le repülés"
-#: engines/scumm/scumm.cpp:1774
+#: engines/scumm/scumm.cpp:1773
#, c-format
msgid ""
"Native MIDI support requires the Roland Upgrade from LucasArts,\n"
@@ -1877,7 +1903,7 @@ msgstr ""
"Native MIDI támogatáshoz kell a Roland Upgrade a LucasArts-tól,\n"
"a %s hiányzik. AdLib-ot használok helyette."
-#: engines/scumm/scumm.cpp:2264 engines/agos/saveload.cpp:189
+#: engines/scumm/scumm.cpp:2271 engines/agos/saveload.cpp:189
#, c-format
msgid ""
"Failed to save game state to file:\n"
@@ -1888,7 +1914,7 @@ msgstr ""
"\n"
"%s fájlba nem sikerült"
-#: engines/scumm/scumm.cpp:2271 engines/agos/saveload.cpp:154
+#: engines/scumm/scumm.cpp:2278 engines/agos/saveload.cpp:154
#, c-format
msgid ""
"Failed to load game state from file:\n"
@@ -1899,7 +1925,7 @@ msgstr ""
"\n"
"%s fájlból nem sikerült"
-#: engines/scumm/scumm.cpp:2283 engines/agos/saveload.cpp:197
+#: engines/scumm/scumm.cpp:2290 engines/agos/saveload.cpp:197
#, c-format
msgid ""
"Successfully saved game state in file:\n"
@@ -1910,7 +1936,7 @@ msgstr ""
"\n"
"%s fájlba elkészült"
-#: engines/scumm/scumm.cpp:2498
+#: engines/scumm/scumm.cpp:2505
msgid ""
"Usually, Maniac Mansion would start now. But ScummVM doesn't do that yet. To "
"play it, go to 'Add Game' in the ScummVM start menu and select the 'Maniac' "
@@ -1946,11 +1972,11 @@ msgstr "Fõ~M~enü"
msgid "~W~ater Effect Enabled"
msgstr "Vízeffektus engedélyezve"
-#: engines/sci/engine/kfile.cpp:685
+#: engines/sci/engine/kfile.cpp:673
msgid "Restore game:"
msgstr "Játékmenet visszaállítása:"
-#: engines/sci/engine/kfile.cpp:685
+#: engines/sci/engine/kfile.cpp:673
msgid "Restore"
msgstr "Visszaállítás"
@@ -1960,11 +1986,11 @@ msgid "Cutscene file '%s' not found!"
msgstr "'%s' átvezetõ fájl nem található"
#: engines/gob/inter_playtoons.cpp:256 engines/gob/inter_v2.cpp:1283
-#: engines/tinsel/saveload.cpp:482
+#: engines/tinsel/saveload.cpp:502
msgid "Failed to load game state from file."
msgstr "Játékállás betöltése fájlból nem sikerült."
-#: engines/gob/inter_v2.cpp:1353 engines/tinsel/saveload.cpp:560
+#: engines/gob/inter_v2.cpp:1353 engines/tinsel/saveload.cpp:515
msgid "Failed to save game state to file."
msgstr "Játékállás mentése fájlba nem sikerült."
@@ -1976,6 +2002,54 @@ msgstr "Fájl törlés sikertelen."
msgid "Failed to save game"
msgstr "Játék mentés nem sikerült"
+#: engines/kyra/lol.cpp:478
+msgid "Attack 1"
+msgstr "Támadás 1"
+
+#: engines/kyra/lol.cpp:479
+msgid "Attack 2"
+msgstr "Támadás 2"
+
+#: engines/kyra/lol.cpp:480
+msgid "Attack 3"
+msgstr "Támadás 3"
+
+#: engines/kyra/lol.cpp:481
+msgid "Move Forward"
+msgstr "Mozgás elõre"
+
+#: engines/kyra/lol.cpp:482
+msgid "Move Back"
+msgstr "Mozgás hátra"
+
+#: engines/kyra/lol.cpp:483
+msgid "Slide Left"
+msgstr "Siklás balra"
+
+#: engines/kyra/lol.cpp:484
+msgid "Slide Right"
+msgstr "Siklás jobbra"
+
+#: engines/kyra/lol.cpp:485
+msgid "Turn Left"
+msgstr "Balra fordul"
+
+#: engines/kyra/lol.cpp:486
+msgid "Turn Right"
+msgstr "Jobbra fordul"
+
+#: engines/kyra/lol.cpp:487
+msgid "Rest"
+msgstr "Pihenés"
+
+#: engines/kyra/lol.cpp:488
+msgid "Options"
+msgstr "Opciók"
+
+#: engines/kyra/lol.cpp:489
+msgid "Choose Spell"
+msgstr "Válassz varázslatot"
+
#: engines/kyra/sound_midi.cpp:475
msgid ""
"You appear to be using a General MIDI device,\n"
@@ -1990,10 +2064,6 @@ msgstr ""
"a General MIDI-t. Különben néhány\n"
"sávot nem lehet rendesen lejátszani."
-#: engines/m4/m4_menus.cpp:138
-msgid "Save game failed!"
-msgstr "Játék mentése nem sikerült!"
-
#: engines/sky/compact.cpp:130
msgid ""
"Unable to find \"sky.cpt\" file!\n"
@@ -2010,15 +2080,20 @@ msgstr ""
"A \"sky.cpt\" fájl mérete nem megfelelõ.\n"
"Töltsd le a www.scummvm.org oldaláról"
-#: engines/sword1/animation.cpp:344 engines/sword2/animation.cpp:379
+#: engines/sword1/animation.cpp:539
+#, c-format
+msgid "PSX stream cutscene '%s' cannot be played in paletted mode"
+msgstr ""
+
+#: engines/sword1/animation.cpp:560 engines/sword2/animation.cpp:455
msgid "DXA cutscenes found but ScummVM has been built without zlib support"
msgstr "DXA átvezetõ elérhetõ, de a ScummVM zlib támogatás nincs lefordítva"
-#: engines/sword1/animation.cpp:354 engines/sword2/animation.cpp:389
+#: engines/sword1/animation.cpp:570 engines/sword2/animation.cpp:465
msgid "MPEG2 cutscenes are no longer supported"
msgstr "MPEG2 átvezetõk már nem támogatottak"
-#: engines/sword1/animation.cpp:359 engines/sword2/animation.cpp:397
+#: engines/sword1/animation.cpp:576 engines/sword2/animation.cpp:473
#, c-format
msgid "Cutscene '%s' not found"
msgstr "'%s' átvezetõ nem található"
@@ -2062,6 +2137,12 @@ msgstr "Az újat megtartom"
msgid "This is the end of the Broken Sword 1 Demo"
msgstr "Ez a Broken Sword 1 Demo vége"
+#: engines/sword2/animation.cpp:435
+#, fuzzy
+msgid ""
+"PSX cutscenes found but ScummVM has been built without RGB color support"
+msgstr "DXA átvezetõ elérhetõ, de a ScummVM zlib támogatás nincs lefordítva"
+
#: engines/parallaction/saveload.cpp:133
#, c-format
msgid ""
@@ -2119,7 +2200,7 @@ msgstr "MAME OPL emulátor"
msgid "DOSBox OPL emulator"
msgstr "DOSBox OPL emulátor"
-#: audio/mididrv.cpp:205
+#: audio/mididrv.cpp:209
#, c-format
msgid ""
"The selected audio device '%s' was not found (e.g. might be turned off or "
@@ -2127,12 +2208,12 @@ msgid ""
msgstr ""
"A kiválasztott '%s' hangeszköz nem található (Lekapcsoltad, vagy kihúztad)."
-#: audio/mididrv.cpp:205 audio/mididrv.cpp:217 audio/mididrv.cpp:253
-#: audio/mididrv.cpp:268
+#: audio/mididrv.cpp:209 audio/mididrv.cpp:221 audio/mididrv.cpp:257
+#: audio/mididrv.cpp:272
msgid "Attempting to fall back to the next available device..."
msgstr "A következõ elérhetõ eszköz keresése..."
-#: audio/mididrv.cpp:217
+#: audio/mididrv.cpp:221
#, c-format
msgid ""
"The selected audio device '%s' cannot be used. See log file for more "
@@ -2141,7 +2222,7 @@ msgstr ""
"A kiválasztott '%s' hangeszköz nem használható. Bõvebb információ a "
"naplófájlban."
-#: audio/mididrv.cpp:253
+#: audio/mididrv.cpp:257
#, c-format
msgid ""
"The preferred audio device '%s' was not found (e.g. might be turned off or "
@@ -2149,7 +2230,7 @@ msgid ""
msgstr ""
"Az elsõdleges '%s' hangeszköz nem található (Lekapcsoltad, vagy kihúztad)."
-#: audio/mididrv.cpp:268
+#: audio/mididrv.cpp:272
#, c-format
msgid ""
"The preferred audio device '%s' cannot be used. See log file for more "
@@ -2166,7 +2247,7 @@ msgstr "Nincs zene"
msgid "Amiga Audio Emulator"
msgstr "Amiga Audió Emulátor"
-#: audio/softsynth/adlib.cpp:1594
+#: audio/softsynth/adlib.cpp:1593
msgid "AdLib Emulator"
msgstr "AdLib Emulátor"
@@ -2178,11 +2259,11 @@ msgstr "Apple II GS Emulátor (NEM TÁMOGATOTT)"
msgid "C64 Audio Emulator"
msgstr "C64 Audio Emulátor"
-#: audio/softsynth/mt32.cpp:329
+#: audio/softsynth/mt32.cpp:293
msgid "Initializing MT-32 Emulator"
msgstr "MT-32 Emulátor inicializálása"
-#: audio/softsynth/mt32.cpp:543
+#: audio/softsynth/mt32.cpp:512
msgid "MT-32 Emulator"
msgstr "MT-32 Emulátor"
@@ -2198,15 +2279,23 @@ msgstr "IBM PCjr Emulátor"
msgid "Keymap:"
msgstr "Billentyûzet kiosztás:"
-#: backends/keymapper/remap-dialog.cpp:64
+#: backends/keymapper/remap-dialog.cpp:66
+msgid " (Effective)"
+msgstr " (Tényleges)"
+
+#: backends/keymapper/remap-dialog.cpp:106
msgid " (Active)"
msgstr " (Aktív)"
-#: backends/keymapper/remap-dialog.cpp:98
+#: backends/keymapper/remap-dialog.cpp:106
+msgid " (Blocked)"
+msgstr ""
+
+#: backends/keymapper/remap-dialog.cpp:119
msgid " (Global)"
msgstr " (Globális)"
-#: backends/keymapper/remap-dialog.cpp:108
+#: backends/keymapper/remap-dialog.cpp:127
msgid " (Game)"
msgstr " (Játék)"
@@ -2286,40 +2375,63 @@ msgstr "Jóminõségü audió (lassabb)(újraindítás)"
msgid "Disable power off"
msgstr "Leállítás tiltva"
-#: backends/platform/iphone/osys_events.cpp:338
+#: backends/platform/iphone/osys_events.cpp:301
msgid "Mouse-click-and-drag mode enabled."
msgstr "Egér kattint-és-húz mód engedélyezve."
-#: backends/platform/iphone/osys_events.cpp:340
+#: backends/platform/iphone/osys_events.cpp:303
msgid "Mouse-click-and-drag mode disabled."
msgstr "Egér kattint-és-húz mód letiltva."
-#: backends/platform/iphone/osys_events.cpp:351
+#: backends/platform/iphone/osys_events.cpp:314
msgid "Touchpad mode enabled."
msgstr "Touchpad mód engedélyezve."
-#: backends/platform/iphone/osys_events.cpp:353
+#: backends/platform/iphone/osys_events.cpp:316
msgid "Touchpad mode disabled."
msgstr "Touchpad mód letiltva."
-#: backends/platform/sdl/macosx/appmenu_osx.mm:67
+#: backends/platform/maemo/maemo.cpp:205
+msgid "Click Mode"
+msgstr "Kattintás Mód"
+
+#: backends/platform/maemo/maemo.cpp:211
+#: backends/platform/symbian/src/SymbianActions.cpp:42
+#: backends/platform/wince/CEActionsPocket.cpp:60
+#: backends/platform/wince/CEActionsSmartphone.cpp:43
+#: backends/platform/bada/form.cpp:281
+msgid "Left Click"
+msgstr "Bal katt"
+
+#: backends/platform/maemo/maemo.cpp:214
+msgid "Middle Click"
+msgstr "Középsõ katt"
+
+#: backends/platform/maemo/maemo.cpp:217
+#: backends/platform/symbian/src/SymbianActions.cpp:43
+#: backends/platform/wince/CEActionsSmartphone.cpp:44
+#: backends/platform/bada/form.cpp:273
+msgid "Right Click"
+msgstr "Jobb katt"
+
+#: backends/platform/sdl/macosx/appmenu_osx.mm:78
msgid "Hide ScummVM"
msgstr "ScummVM elrejtése"
-#: backends/platform/sdl/macosx/appmenu_osx.mm:70
+#: backends/platform/sdl/macosx/appmenu_osx.mm:83
msgid "Hide Others"
msgstr "Többi elrejtése"
-#: backends/platform/sdl/macosx/appmenu_osx.mm:74
+#: backends/platform/sdl/macosx/appmenu_osx.mm:88
msgid "Show All"
msgstr "Mutasd mind"
-#: backends/platform/sdl/macosx/appmenu_osx.mm:92
-#: backends/platform/sdl/macosx/appmenu_osx.mm:99
+#: backends/platform/sdl/macosx/appmenu_osx.mm:110
+#: backends/platform/sdl/macosx/appmenu_osx.mm:121
msgid "Window"
msgstr "Ablak"
-#: backends/platform/sdl/macosx/appmenu_osx.mm:95
+#: backends/platform/sdl/macosx/appmenu_osx.mm:115
msgid "Minimize"
msgstr "Kis méret"
@@ -2333,12 +2445,12 @@ msgid "Normal (no scaling)"
msgstr "Normál (nincs átméretezés)"
#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2147
-#: backends/graphics/openglsdl/openglsdl-graphics.cpp:537
+#: backends/graphics/openglsdl/openglsdl-graphics.cpp:533
msgid "Enabled aspect ratio correction"
msgstr "Méretarány korrekció engedélyezve"
#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2153
-#: backends/graphics/openglsdl/openglsdl-graphics.cpp:542
+#: backends/graphics/openglsdl/openglsdl-graphics.cpp:538
msgid "Disabled aspect ratio correction"
msgstr "Méretarány korrekció letiltva"
@@ -2347,7 +2459,7 @@ msgid "Active graphics filter:"
msgstr "Aktív grafikus szûrõk:"
#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2250
-#: backends/graphics/openglsdl/openglsdl-graphics.cpp:481
+#: backends/graphics/openglsdl/openglsdl-graphics.cpp:477
msgid "Windowed mode"
msgstr "Ablakos mód"
@@ -2371,11 +2483,11 @@ msgstr "Jelenlegi videómód"
msgid "Current scale"
msgstr "Aktuális méretezés"
-#: backends/graphics/openglsdl/openglsdl-graphics.cpp:562
+#: backends/graphics/openglsdl/openglsdl-graphics.cpp:558
msgid "Active filter mode: Linear"
msgstr "Aktív filter mód: Lineáris"
-#: backends/graphics/openglsdl/openglsdl-graphics.cpp:564
+#: backends/graphics/openglsdl/openglsdl-graphics.cpp:560
msgid "Active filter mode: Nearest"
msgstr "Aktív filter mód: Közelítõ"
@@ -2399,19 +2511,6 @@ msgstr "Bal"
msgid "Right"
msgstr "Jobb"
-#: backends/platform/symbian/src/SymbianActions.cpp:42
-#: backends/platform/wince/CEActionsPocket.cpp:60
-#: backends/platform/wince/CEActionsSmartphone.cpp:43
-#: backends/platform/bada/form.cpp:281
-msgid "Left Click"
-msgstr "Bal katt"
-
-#: backends/platform/symbian/src/SymbianActions.cpp:43
-#: backends/platform/wince/CEActionsSmartphone.cpp:44
-#: backends/platform/bada/form.cpp:273
-msgid "Right Click"
-msgstr "Jobb katt"
-
#: backends/platform/symbian/src/SymbianActions.cpp:46
#: backends/platform/wince/CEActionsSmartphone.cpp:47
msgid "Zone"
@@ -2698,15 +2797,15 @@ msgstr ""
"Ne felejts billentyût társítani az 'Eszköztár rejtés' mûvelethez, hogy lásd "
"a teljes listát"
-#: backends/events/default/default-events.cpp:222
+#: backends/events/default/default-events.cpp:191
msgid "Do you really want to return to the Launcher?"
msgstr "Biztos hogy visszatérsz az indítópulthoz?"
-#: backends/events/default/default-events.cpp:222
+#: backends/events/default/default-events.cpp:191
msgid "Launcher"
msgstr "Indítópult"
-#: backends/events/default/default-events.cpp:244
+#: backends/events/default/default-events.cpp:213
msgid "Do you really want to quit?"
msgstr "Biztos hogy ki akarsz lépni ?"
@@ -2772,14 +2871,31 @@ msgstr "Kézi billentyûzet"
msgid "Control Mouse"
msgstr "Egér irányitás"
-#: backends/events/maemosdl/maemosdl-events.cpp:121
+#: backends/events/maemosdl/maemosdl-events.cpp:192
msgid "Clicking Enabled"
msgstr "Kattintás engedve"
-#: backends/events/maemosdl/maemosdl-events.cpp:121
+#: backends/events/maemosdl/maemosdl-events.cpp:192
msgid "Clicking Disabled"
msgstr "Kattintás tiltva"
+#~ msgid "Hercules Green"
+#~ msgstr "Hercules Zöld"
+
+#~ msgid "Hercules Amber"
+#~ msgstr "Hercules Sárga"
+
+#~ msgctxt "lowres"
+#~ msgid "Hercules Green"
+#~ msgstr "Hercules Zöld"
+
+#~ msgctxt "lowres"
+#~ msgid "Hercules Amber"
+#~ msgstr "Hercules Sárga"
+
+#~ msgid "Save game failed!"
+#~ msgstr "Játék mentése nem sikerült!"
+
#~ msgctxt "lowres"
#~ msgid "Add Game..."
#~ msgstr "Játék hozzáadás"
diff --git a/po/iso-8859-2.cp b/po/iso-8859-2.cp
new file mode 100644
index 0000000000..f8e673bf70
--- /dev/null
+++ b/po/iso-8859-2.cp
@@ -0,0 +1,320 @@
+# 0x00 ( 0)
+0 0 # Not required
+1 0 # Not required
+2 0 # Not required
+3 0 # Not required
+# 0x04 ( 4)
+4 0 # Not required
+5 0 # Not required
+6 0 # Not required
+7 0 # Not required
+# 0x08 ( 8)
+8 0 # Not required
+9 0 # Not required
+10 0 # Not required
+11 0 # Not required
+# 0x0C ( 12)
+12 0 # Not required
+13 0 # Not required
+14 0 # Not required
+15 0 # Not required
+# 0x10 ( 16)
+16 0 # Not required
+17 0 # Not required
+18 0 # Not required
+19 0 # Not required
+# 0x14 ( 20)
+20 0 # Not required
+21 0 # Not required
+22 0 # Not required
+23 0 # Not required
+# 0x18 ( 24)
+24 0 # Not required
+25 0 # Not required
+26 0 # Not required
+27 0 # Not required
+# 0x1C ( 28)
+28 0 # Not required
+29 0 # Not required
+30 0 # Not required
+31 0 # Not required
+# 0x20 ( 32)
+32
+33
+34
+35
+# 0x24 ( 36)
+36
+37
+38
+39
+# 0x28 ( 40)
+40
+41
+42
+43
+# 0x2C ( 44)
+44
+45
+46
+47
+# 0x30 ( 48)
+48
+49
+50
+51
+# 0x34 ( 52)
+52
+53
+54
+55
+# 0x38 ( 56)
+56
+57
+58
+59
+# 0x3C ( 60)
+60
+61
+62
+63
+# 0x40 ( 64)
+64
+65
+66
+67
+# 0x44 ( 68)
+68
+69
+70
+71
+# 0x48 ( 72)
+72
+73
+74
+75
+# 0x4C ( 76)
+76
+77
+78
+79
+# 0x50 ( 80)
+80
+81
+82
+83
+# 0x54 ( 84)
+84
+85
+86
+87
+# 0x58 ( 88)
+88
+89
+90
+91
+# 0x5C ( 92)
+92
+93
+94
+95
+# 0x60 ( 96)
+96
+97
+98
+99
+# 0x64 (100)
+100
+101
+102
+103
+# 0x68 (104)
+104
+105
+106
+107
+# 0x6C (108)
+108
+109
+110
+111
+# 0x70 (112)
+112
+113
+114
+115
+# 0x74 (116)
+116
+117
+118
+119
+# 0x78 (120)
+120
+121
+122
+123
+# 0x7C (124)
+124
+125
+126
+127 0 # Not required
+# 0x80 (128)
+128 0 # Not required
+129 0 # Not required
+130 0 # Not required
+131 0 # Not required
+# 0x84 (132)
+132 0 # Not required
+133 0 # Not required
+134 0 # Not required
+135 0 # Not required
+# 0x88 (136)
+136 0 # Not required
+137 0 # Not required
+138 0 # Not required
+139 0 # Not required
+# 0x8C (140)
+140 0 # Not required
+141 0 # Not required
+142 0 # Not required
+143 0 # Not required
+# 0x90 (144)
+144 0 # Not required
+145 0 # Not required
+146 0 # Not required
+147 0 # Not required
+# 0x94 (148)
+148 0 # Not required
+149 0 # Not required
+150 0 # Not required
+151 0 # Not required
+# 0x98 (152)
+152 0 # Not required
+153 0 # Not required
+154 0 # Not required
+155 0 # Not required
+# 0x9C (156)
+156 0 # Not required
+157 0 # Not required
+158 0 # Not required
+159 0 # Not required
+# 0xA0 (160)
+160
+260
+728
+321
+# 0xA4 (164)
+164
+317
+346
+167
+# 0xA8 (168)
+168
+352
+350
+356
+# 0xAC (172)
+377
+173
+381
+379
+# 0xB0 (176)
+176
+261
+731
+322
+# 0xB4 (180)
+180
+318
+347
+711
+# 0xB8 (184)
+184
+353
+351
+357
+# 0xBC (188)
+378
+733
+382
+380
+# 0xC0 (192)
+340
+193
+194
+258
+# 0xC4 (196)
+196
+313
+262
+199
+# 0xC8 (200)
+268
+201
+280
+203
+# 0xCC (204)
+282
+205
+206
+270
+# 0xD0 (208)
+272
+323
+327
+211
+# 0xD4 (212)
+212
+336
+214
+215
+# 0xD8 (216)
+344
+366
+218
+368
+# 0xDC (220)
+220
+221
+354
+223
+# 0xE0 (224)
+341
+225
+226
+259
+# 0xE4 (228)
+228
+314
+263
+231
+# 0xE8 (232)
+269
+233
+281
+235
+# 0xEC (236)
+283
+237
+238
+271
+# 0xF0 (240)
+273
+324
+328
+243
+# 0xF4 (244)
+244
+337
+246
+247
+# 0xF8 (248)
+345
+367
+250
+369
+# 0xFC (252)
+252
+253
+355
+729
diff --git a/po/iso-8859-5.cp b/po/iso-8859-5.cp
new file mode 100644
index 0000000000..47350101b2
--- /dev/null
+++ b/po/iso-8859-5.cp
@@ -0,0 +1,320 @@
+# 0x00 ( 0)
+0 0 # Not required
+1 0 # Not required
+2 0 # Not required
+3 0 # Not required
+# 0x04 ( 4)
+4 0 # Not required
+5 0 # Not required
+6 0 # Not required
+7 0 # Not required
+# 0x08 ( 8)
+8 0 # Not required
+9 0 # Not required
+10 0 # Not required
+11 0 # Not required
+# 0x0C ( 12)
+12 0 # Not required
+13 0 # Not required
+14 0 # Not required
+15 0 # Not required
+# 0x10 ( 16)
+16 0 # Not required
+17 0 # Not required
+18 0 # Not required
+19 0 # Not required
+# 0x14 ( 20)
+20 0 # Not required
+21 0 # Not required
+22 0 # Not required
+23 0 # Not required
+# 0x18 ( 24)
+24 0 # Not required
+25 0 # Not required
+26 0 # Not required
+27 0 # Not required
+# 0x1C ( 28)
+28 0 # Not required
+29 0 # Not required
+30 0 # Not required
+31 0 # Not required
+# 0x20 ( 32)
+32
+33
+34
+35
+# 0x24 ( 36)
+36
+37
+38
+39
+# 0x28 ( 40)
+40
+41
+42
+43
+# 0x2C ( 44)
+44
+45
+46
+47
+# 0x30 ( 48)
+48
+49
+50
+51
+# 0x34 ( 52)
+52
+53
+54
+55
+# 0x38 ( 56)
+56
+57
+58
+59
+# 0x3C ( 60)
+60
+61
+62
+63
+# 0x40 ( 64)
+64
+65
+66
+67
+# 0x44 ( 68)
+68
+69
+70
+71
+# 0x48 ( 72)
+72
+73
+74
+75
+# 0x4C ( 76)
+76
+77
+78
+79
+# 0x50 ( 80)
+80
+81
+82
+83
+# 0x54 ( 84)
+84
+85
+86
+87
+# 0x58 ( 88)
+88
+89
+90
+91
+# 0x5C ( 92)
+92
+93
+94
+95
+# 0x60 ( 96)
+96
+97
+98
+99
+# 0x64 (100)
+100
+101
+102
+103
+# 0x68 (104)
+104
+105
+106
+107
+# 0x6C (108)
+108
+109
+110
+111
+# 0x70 (112)
+112
+113
+114
+115
+# 0x74 (116)
+116
+117
+118
+119
+# 0x78 (120)
+120
+121
+122
+123
+# 0x7C (124)
+124
+125
+126
+127 0 # Not required
+# 0x80 (128)
+128 0 # Not required
+129 0 # Not required
+130 0 # Not required
+131 0 # Not required
+# 0x84 (132)
+132 0 # Not required
+133 0 # Not required
+134 0 # Not required
+135 0 # Not required
+# 0x88 (136)
+136 0 # Not required
+137 0 # Not required
+138 0 # Not required
+139 0 # Not required
+# 0x8C (140)
+140 0 # Not required
+141 0 # Not required
+142 0 # Not required
+143 0 # Not required
+# 0x90 (144)
+144 0 # Not required
+145 0 # Not required
+146 0 # Not required
+147 0 # Not required
+# 0x94 (148)
+148 0 # Not required
+149 0 # Not required
+150 0 # Not required
+151 0 # Not required
+# 0x98 (152)
+152 0 # Not required
+153 0 # Not required
+154 0 # Not required
+155 0 # Not required
+# 0x9C (156)
+156 0 # Not required
+157 0 # Not required
+158 0 # Not required
+159 0 # Not required
+# 0xA0 (160)
+160
+1025
+1026
+1027
+# 0xA4 (164)
+1028
+1029
+1030
+1031
+# 0xA8 (168)
+1032
+1033
+1034
+1035
+# 0xAC (172)
+1036
+173
+1038
+1039
+# 0xB0 (176)
+1040
+1041
+1042
+1043
+# 0xB4 (180)
+1044
+1045
+1046
+1047
+# 0xB8 (184)
+1048
+1049
+1050
+1051
+# 0xBC (188)
+1052
+1053
+1054
+1055
+# 0xC0 (192)
+1056
+1057
+1058
+1059
+# 0xC4 (196)
+1060
+1061
+1062
+1063
+# 0xC8 (200)
+1064
+1065
+1066
+1067
+# 0xCC (204)
+1068
+1069
+1070
+1071
+# 0xD0 (208)
+1072
+1073
+1074
+1075
+# 0xD4 (212)
+1076
+1077
+1078
+1079
+# 0xD8 (216)
+1080
+1081
+1082
+1083
+# 0xDC (220)
+1084
+1085
+1086
+1087
+# 0xE0 (224)
+1088
+1089
+1090
+1091
+# 0xE4 (228)
+1092
+1093
+1094
+1095
+# 0xE8 (232)
+1096
+1097
+1098
+1099
+# 0xEC (236)
+1100
+1101
+1102
+1103
+# 0xF0 (240)
+8470
+1105
+1106
+1107
+# 0xF4 (244)
+1108
+1109
+1110
+1111
+# 0xF8 (248)
+1112
+1113
+1114
+1115
+# 0xFC (252)
+1116
+167
+1118
+1119
diff --git a/po/it_IT.po b/po/it_IT.po
index 2bfa8c0c16..29811d81ff 100644
--- a/po/it_IT.po
+++ b/po/it_IT.po
@@ -1,5 +1,5 @@
# Italian translation for ScummVM.
-# Copyright (C) 2010-2011 ScummVM Team
+# Copyright (C) 2010-2012 ScummVM Team
# This file is distributed under the same license as the ScummVM package.
# Matteo 'Maff' Angelino <matteo.maff at gmail dot com>, 2010.
#
@@ -7,14 +7,14 @@ msgid ""
msgstr ""
"Project-Id-Version: ScummVM 1.3.0svn\n"
"Report-Msgid-Bugs-To: scummvm-devel@lists.sf.net\n"
-"POT-Creation-Date: 2011-10-19 13:42+0100\n"
+"POT-Creation-Date: 2012-03-07 22:09+0000\n"
"PO-Revision-Date: 2011-10-08 17:29+0100\n"
"Last-Translator: Matteo 'Maff' Angelino <matteo.maff at gmail dot com>\n"
"Language-Team: Italian\n"
-"Language: Italiano\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=iso-8859-1\n"
"Content-Transfer-Encoding: 8bit\n"
+"Language: Italiano\n"
#: gui/about.cpp:91
#, c-format
@@ -43,13 +43,13 @@ msgid "Go up"
msgstr "Su"
#: gui/browser.cpp:69 gui/chooser.cpp:45 gui/KeysDialog.cpp:43
-#: gui/launcher.cpp:312 gui/massadd.cpp:94 gui/options.cpp:1178
+#: gui/launcher.cpp:320 gui/massadd.cpp:94 gui/options.cpp:1253
#: gui/saveload.cpp:63 gui/saveload.cpp:155 gui/themebrowser.cpp:54
-#: engines/engine.cpp:436 engines/scumm/dialogs.cpp:190
+#: engines/engine.cpp:442 engines/scumm/dialogs.cpp:190
#: engines/sword1/control.cpp:865 engines/parallaction/saveload.cpp:281
#: backends/platform/wii/options.cpp:48
-#: backends/events/default/default-events.cpp:222
-#: backends/events/default/default-events.cpp:244
+#: backends/events/default/default-events.cpp:191
+#: backends/events/default/default-events.cpp:213
msgid "Cancel"
msgstr "Annulla"
@@ -57,25 +57,30 @@ msgstr "Annulla"
msgid "Choose"
msgstr "Scegli"
-#: gui/gui-manager.cpp:116 engines/scumm/help.cpp:125
+#: gui/gui-manager.cpp:115 engines/scumm/help.cpp:125
#: engines/scumm/help.cpp:140 engines/scumm/help.cpp:165
#: engines/scumm/help.cpp:191 engines/scumm/help.cpp:209
#: backends/keymapper/remap-dialog.cpp:52
msgid "Close"
msgstr "Chiudi"
-#: gui/gui-manager.cpp:119
+#: gui/gui-manager.cpp:118
msgid "Mouse click"
msgstr "Clic del mouse"
-#: gui/gui-manager.cpp:122 base/main.cpp:283
+#: gui/gui-manager.cpp:122 base/main.cpp:288
msgid "Display keyboard"
msgstr "Mostra tastiera"
-#: gui/gui-manager.cpp:125 base/main.cpp:286
+#: gui/gui-manager.cpp:126 base/main.cpp:292
msgid "Remap keys"
msgstr "Riprogramma tasti"
+#: gui/gui-manager.cpp:129 base/main.cpp:295
+#, fuzzy
+msgid "Toggle FullScreen"
+msgstr "Attiva / disattiva schermo intero"
+
#: gui/KeysDialog.h:36 gui/KeysDialog.cpp:145
msgid "Choose an action to map"
msgstr "Scegli un'azione da mappare"
@@ -84,16 +89,17 @@ msgstr "Scegli un'azione da mappare"
msgid "Map"
msgstr "Mappa"
-#: gui/KeysDialog.cpp:42 gui/launcher.cpp:313 gui/launcher.cpp:936
-#: gui/launcher.cpp:940 gui/massadd.cpp:91 gui/options.cpp:1179
-#: engines/engine.cpp:359 engines/engine.cpp:370 engines/scumm/dialogs.cpp:192
-#: engines/scumm/scumm.cpp:1776 engines/agos/animation.cpp:551
+#: gui/KeysDialog.cpp:42 gui/launcher.cpp:321 gui/launcher.cpp:960
+#: gui/launcher.cpp:964 gui/massadd.cpp:91 gui/options.cpp:1254
+#: engines/engine.cpp:361 engines/engine.cpp:372 engines/scumm/dialogs.cpp:192
+#: engines/scumm/scumm.cpp:1775 engines/agos/animation.cpp:551
#: engines/groovie/script.cpp:420 engines/sky/compact.cpp:131
-#: engines/sky/compact.cpp:141 engines/sword1/animation.cpp:344
-#: engines/sword1/animation.cpp:354 engines/sword1/animation.cpp:360
-#: engines/sword1/control.cpp:865 engines/sword1/logic.cpp:1633
-#: engines/sword2/animation.cpp:379 engines/sword2/animation.cpp:389
-#: engines/sword2/animation.cpp:398 engines/parallaction/saveload.cpp:281
+#: engines/sky/compact.cpp:141 engines/sword1/animation.cpp:539
+#: engines/sword1/animation.cpp:560 engines/sword1/animation.cpp:570
+#: engines/sword1/animation.cpp:577 engines/sword1/control.cpp:865
+#: engines/sword1/logic.cpp:1633 engines/sword2/animation.cpp:435
+#: engines/sword2/animation.cpp:455 engines/sword2/animation.cpp:465
+#: engines/sword2/animation.cpp:474 engines/parallaction/saveload.cpp:281
#: backends/platform/wii/options.cpp:47
#: backends/platform/wince/CELauncherDialog.cpp:54
msgid "OK"
@@ -121,15 +127,15 @@ msgstr "Seleziona un'azione"
msgid "Press the key to associate"
msgstr "Premi il tasto da associare"
-#: gui/launcher.cpp:165
+#: gui/launcher.cpp:170
msgid "Game"
msgstr "Gioco"
-#: gui/launcher.cpp:169
+#: gui/launcher.cpp:174
msgid "ID:"
msgstr "ID:"
-#: gui/launcher.cpp:169 gui/launcher.cpp:171 gui/launcher.cpp:172
+#: gui/launcher.cpp:174 gui/launcher.cpp:176 gui/launcher.cpp:177
msgid ""
"Short game identifier used for referring to savegames and running the game "
"from the command line"
@@ -137,311 +143,309 @@ msgstr ""
"Breve identificatore di gioco utilizzato per il riferimento a salvataggi e "
"per l'esecuzione del gioco dalla riga di comando"
-#: gui/launcher.cpp:171
+#: gui/launcher.cpp:176
msgctxt "lowres"
msgid "ID:"
msgstr "ID:"
-#: gui/launcher.cpp:176
+#: gui/launcher.cpp:181
msgid "Name:"
msgstr "Nome:"
-#: gui/launcher.cpp:176 gui/launcher.cpp:178 gui/launcher.cpp:179
+#: gui/launcher.cpp:181 gui/launcher.cpp:183 gui/launcher.cpp:184
msgid "Full title of the game"
msgstr "Titolo completo del gioco"
-#: gui/launcher.cpp:178
+#: gui/launcher.cpp:183
msgctxt "lowres"
msgid "Name:"
msgstr "Nome:"
-#: gui/launcher.cpp:182
+#: gui/launcher.cpp:187
msgid "Language:"
msgstr "Lingua:"
-#: gui/launcher.cpp:182 gui/launcher.cpp:183
+#: gui/launcher.cpp:187 gui/launcher.cpp:188
msgid ""
"Language of the game. This will not turn your Spanish game version into "
"English"
msgstr ""
"Lingua del gioco. Un gioco inglese non potrà risultare tradotto in italiano"
-#: gui/launcher.cpp:184 gui/launcher.cpp:198 gui/options.cpp:74
-#: gui/options.cpp:708 gui/options.cpp:718 gui/options.cpp:1149
+#: gui/launcher.cpp:189 gui/launcher.cpp:203 gui/options.cpp:80
+#: gui/options.cpp:745 gui/options.cpp:758 gui/options.cpp:1224
#: audio/null.cpp:40
msgid "<default>"
msgstr "<predefinito>"
-#: gui/launcher.cpp:194
+#: gui/launcher.cpp:199
msgid "Platform:"
msgstr "Piattaforma:"
-#: gui/launcher.cpp:194 gui/launcher.cpp:196 gui/launcher.cpp:197
+#: gui/launcher.cpp:199 gui/launcher.cpp:201 gui/launcher.cpp:202
msgid "Platform the game was originally designed for"
msgstr "La piattaforma per la quale il gioco è stato concepito"
-#: gui/launcher.cpp:196
+#: gui/launcher.cpp:201
msgctxt "lowres"
msgid "Platform:"
msgstr "Piattaf.:"
-#: gui/launcher.cpp:208 gui/options.cpp:1018 gui/options.cpp:1035
+#: gui/launcher.cpp:213 gui/options.cpp:1087 gui/options.cpp:1104
msgid "Graphics"
msgstr "Grafica"
-#: gui/launcher.cpp:208 gui/options.cpp:1018 gui/options.cpp:1035
+#: gui/launcher.cpp:213 gui/options.cpp:1087 gui/options.cpp:1104
msgid "GFX"
msgstr "Grafica"
-#: gui/launcher.cpp:211
+#: gui/launcher.cpp:216
msgid "Override global graphic settings"
msgstr "Ignora le impostazioni grafiche globali"
-#: gui/launcher.cpp:213
+#: gui/launcher.cpp:218
msgctxt "lowres"
msgid "Override global graphic settings"
msgstr "Ignora le impostazioni grafiche globali"
-#: gui/launcher.cpp:220 gui/options.cpp:1041
+#: gui/launcher.cpp:225 gui/options.cpp:1110
msgid "Audio"
msgstr "Audio"
-#: gui/launcher.cpp:223
+#: gui/launcher.cpp:228
msgid "Override global audio settings"
msgstr "Ignora le impostazioni audio globali"
-#: gui/launcher.cpp:225
+#: gui/launcher.cpp:230
msgctxt "lowres"
msgid "Override global audio settings"
msgstr "Ignora le impostazioni audio globali"
-#: gui/launcher.cpp:234 gui/options.cpp:1046
+#: gui/launcher.cpp:239 gui/options.cpp:1115
msgid "Volume"
msgstr "Volume"
-#: gui/launcher.cpp:236 gui/options.cpp:1048
+#: gui/launcher.cpp:241 gui/options.cpp:1117
msgctxt "lowres"
msgid "Volume"
msgstr "Volume"
-#: gui/launcher.cpp:239
+#: gui/launcher.cpp:244
msgid "Override global volume settings"
msgstr "Ignora le impostazioni globali di volume"
-#: gui/launcher.cpp:241
+#: gui/launcher.cpp:246
msgctxt "lowres"
msgid "Override global volume settings"
msgstr "Ignora le impostazioni globali di volume"
-#: gui/launcher.cpp:248 gui/options.cpp:1056
+#: gui/launcher.cpp:254 gui/options.cpp:1125
msgid "MIDI"
msgstr "MIDI"
-#: gui/launcher.cpp:251
+#: gui/launcher.cpp:257
msgid "Override global MIDI settings"
msgstr "Ignora le impostazioni MIDI globali"
-#: gui/launcher.cpp:253
+#: gui/launcher.cpp:259
msgctxt "lowres"
msgid "Override global MIDI settings"
msgstr "Ignora le impostazioni MIDI globali"
-#: gui/launcher.cpp:263 gui/options.cpp:1062
+#: gui/launcher.cpp:268 gui/options.cpp:1131
msgid "MT-32"
msgstr "MT-32"
-#: gui/launcher.cpp:266
+#: gui/launcher.cpp:271
msgid "Override global MT-32 settings"
msgstr "Ignora le impostazioni MT-32 globali"
-#: gui/launcher.cpp:268
+#: gui/launcher.cpp:273
msgctxt "lowres"
msgid "Override global MT-32 settings"
msgstr "Ignora le impostazioni MT-32 globali"
-#: gui/launcher.cpp:279 gui/options.cpp:1069
+#: gui/launcher.cpp:282 gui/options.cpp:1138
msgid "Paths"
msgstr "Percorsi"
-#: gui/launcher.cpp:281 gui/options.cpp:1071
+#: gui/launcher.cpp:284 gui/options.cpp:1140
msgctxt "lowres"
msgid "Paths"
msgstr "Perc."
-#: gui/launcher.cpp:288
+#: gui/launcher.cpp:291
msgid "Game Path:"
msgstr "Percorso gioco:"
-#: gui/launcher.cpp:290
+#: gui/launcher.cpp:293
msgctxt "lowres"
msgid "Game Path:"
msgstr "Perc. gioco:"
-#: gui/launcher.cpp:295 gui/options.cpp:1091
+#: gui/launcher.cpp:298 gui/options.cpp:1164
msgid "Extra Path:"
msgstr "Percorso extra:"
-#: gui/launcher.cpp:295 gui/launcher.cpp:297 gui/launcher.cpp:298
+#: gui/launcher.cpp:298 gui/launcher.cpp:300 gui/launcher.cpp:301
msgid "Specifies path to additional data used the game"
msgstr "Specifica il percorso di ulteriori dati usati dal gioco"
-#: gui/launcher.cpp:297 gui/options.cpp:1093
+#: gui/launcher.cpp:300 gui/options.cpp:1166
msgctxt "lowres"
msgid "Extra Path:"
msgstr "Perc. extra:"
-#: gui/launcher.cpp:302 gui/options.cpp:1079
+#: gui/launcher.cpp:307 gui/options.cpp:1148
msgid "Save Path:"
msgstr "Salvataggi:"
-#: gui/launcher.cpp:302 gui/launcher.cpp:304 gui/launcher.cpp:305
-#: gui/options.cpp:1079 gui/options.cpp:1081 gui/options.cpp:1082
+#: gui/launcher.cpp:307 gui/launcher.cpp:309 gui/launcher.cpp:310
+#: gui/options.cpp:1148 gui/options.cpp:1150 gui/options.cpp:1151
msgid "Specifies where your savegames are put"
msgstr "Specifica dove archiviare i salvataggi"
-#: gui/launcher.cpp:304 gui/options.cpp:1081
+#: gui/launcher.cpp:309 gui/options.cpp:1150
msgctxt "lowres"
msgid "Save Path:"
msgstr "Salvataggi:"
-#: gui/launcher.cpp:321 gui/launcher.cpp:404 gui/launcher.cpp:453
-#: gui/options.cpp:1088 gui/options.cpp:1094 gui/options.cpp:1101
-#: gui/options.cpp:1202 gui/options.cpp:1208 gui/options.cpp:1214
-#: gui/options.cpp:1222 gui/options.cpp:1246 gui/options.cpp:1250
-#: gui/options.cpp:1256 gui/options.cpp:1263 gui/options.cpp:1362
+#: gui/launcher.cpp:329 gui/launcher.cpp:416 gui/launcher.cpp:469
+#: gui/launcher.cpp:523 gui/options.cpp:1159 gui/options.cpp:1167
+#: gui/options.cpp:1176 gui/options.cpp:1283 gui/options.cpp:1289
+#: gui/options.cpp:1297 gui/options.cpp:1327 gui/options.cpp:1333
+#: gui/options.cpp:1340 gui/options.cpp:1433 gui/options.cpp:1436
+#: gui/options.cpp:1448
msgctxt "path"
msgid "None"
msgstr "Nessuno"
-#: gui/launcher.cpp:326 gui/launcher.cpp:408
+#: gui/launcher.cpp:334 gui/launcher.cpp:422 gui/launcher.cpp:527
+#: gui/options.cpp:1277 gui/options.cpp:1321 gui/options.cpp:1439
#: backends/platform/wii/options.cpp:56
msgid "Default"
msgstr "Predefinito"
-#: gui/launcher.cpp:446 gui/options.cpp:1356
+#: gui/launcher.cpp:462 gui/options.cpp:1442
msgid "Select SoundFont"
msgstr "Seleziona SoundFont"
-#: gui/launcher.cpp:465 gui/launcher.cpp:612
+#: gui/launcher.cpp:481 gui/launcher.cpp:636
msgid "Select directory with game data"
msgstr "Seleziona la cartella contenente i file di gioco"
-#: gui/launcher.cpp:483
+#: gui/launcher.cpp:499
msgid "Select additional game directory"
msgstr "Seleziona la cartella di gioco aggiuntiva"
-#: gui/launcher.cpp:495
+#: gui/launcher.cpp:511
msgid "Select directory for saved games"
msgstr "Seleziona la cartella dei salvataggi"
-#: gui/launcher.cpp:514
+#: gui/launcher.cpp:538
msgid "This game ID is already taken. Please choose another one."
msgstr "Questo ID di gioco è già in uso. Si prega di sceglierne un'altro."
-#: gui/launcher.cpp:555 engines/dialogs.cpp:110
+#: gui/launcher.cpp:579 engines/dialogs.cpp:110
msgid "~Q~uit"
msgstr "C~h~iudi"
-#: gui/launcher.cpp:555 backends/platform/sdl/macosx/appmenu_osx.mm:80
+#: gui/launcher.cpp:579 backends/platform/sdl/macosx/appmenu_osx.mm:96
msgid "Quit ScummVM"
-msgstr "Chiudi ScummVM"
+msgstr "Esci da ScummVM"
-#: gui/launcher.cpp:556
+#: gui/launcher.cpp:580
msgid "A~b~out..."
msgstr "~I~nfo..."
-#: gui/launcher.cpp:556 backends/platform/sdl/macosx/appmenu_osx.mm:61
+#: gui/launcher.cpp:580 backends/platform/sdl/macosx/appmenu_osx.mm:70
msgid "About ScummVM"
msgstr "Informazioni su ScummVM"
-#: gui/launcher.cpp:557
+#: gui/launcher.cpp:581
msgid "~O~ptions..."
msgstr "~O~pzioni..."
-#: gui/launcher.cpp:557
+#: gui/launcher.cpp:581
msgid "Change global ScummVM options"
msgstr "Modifica le opzioni globali di ScummVM"
-#: gui/launcher.cpp:559
+#: gui/launcher.cpp:583
msgid "~S~tart"
msgstr "~G~ioca"
-#: gui/launcher.cpp:559
+#: gui/launcher.cpp:583
msgid "Start selected game"
msgstr "Esegue il gioco selezionato"
-#: gui/launcher.cpp:562
+#: gui/launcher.cpp:586
msgid "~L~oad..."
msgstr "~C~arica..."
-#: gui/launcher.cpp:562
+#: gui/launcher.cpp:586
msgid "Load savegame for selected game"
msgstr "Carica un salvataggio del gioco selezionato"
-#: gui/launcher.cpp:567 gui/launcher.cpp:1055
+#: gui/launcher.cpp:591 gui/launcher.cpp:1079
msgid "~A~dd Game..."
msgstr "~A~ggiungi gioco..."
-#: gui/launcher.cpp:567 gui/launcher.cpp:574
+#: gui/launcher.cpp:591 gui/launcher.cpp:598
msgid "Hold Shift for Mass Add"
msgstr "Tieni premuto Shift per l'aggiunta in massa"
-#: gui/launcher.cpp:569
+#: gui/launcher.cpp:593
msgid "~E~dit Game..."
msgstr "~M~odifica gioco..."
-#: gui/launcher.cpp:569 gui/launcher.cpp:576
+#: gui/launcher.cpp:593 gui/launcher.cpp:600
msgid "Change game options"
msgstr "Modifica le opzioni di gioco"
-#: gui/launcher.cpp:571
+#: gui/launcher.cpp:595
msgid "~R~emove Game"
msgstr "~R~imuovi gioco"
-#: gui/launcher.cpp:571 gui/launcher.cpp:578
+#: gui/launcher.cpp:595 gui/launcher.cpp:602
msgid "Remove game from the list. The game data files stay intact"
msgstr "Rimuove il gioco dalla lista. I file del gioco rimarranno intatti"
-#: gui/launcher.cpp:574 gui/launcher.cpp:1055
+#: gui/launcher.cpp:598 gui/launcher.cpp:1079
msgctxt "lowres"
msgid "~A~dd Game..."
msgstr "~A~gg. gioco..."
-#: gui/launcher.cpp:576
+#: gui/launcher.cpp:600
msgctxt "lowres"
msgid "~E~dit Game..."
msgstr "~M~odif. gioco..."
-#: gui/launcher.cpp:578
+#: gui/launcher.cpp:602
msgctxt "lowres"
msgid "~R~emove Game"
msgstr "~R~im. gioco"
-#: gui/launcher.cpp:586
+#: gui/launcher.cpp:610
msgid "Search in game list"
msgstr "Cerca nella lista dei giochi"
-#: gui/launcher.cpp:590 gui/launcher.cpp:1102
+#: gui/launcher.cpp:614 gui/launcher.cpp:1126
msgid "Search:"
msgstr "Cerca:"
-#: gui/launcher.cpp:593 gui/options.cpp:826
-msgid "Clear value"
-msgstr "Cancella"
-
-#: gui/launcher.cpp:615 engines/dialogs.cpp:114 engines/mohawk/myst.cpp:255
+#: gui/launcher.cpp:639 engines/dialogs.cpp:114 engines/mohawk/myst.cpp:255
#: engines/mohawk/riven.cpp:716 engines/cruise/menu.cpp:216
msgid "Load game:"
msgstr "Carica gioco:"
-#: gui/launcher.cpp:615 engines/dialogs.cpp:114 engines/scumm/dialogs.cpp:188
+#: gui/launcher.cpp:639 engines/dialogs.cpp:114 engines/scumm/dialogs.cpp:188
#: engines/mohawk/myst.cpp:255 engines/mohawk/riven.cpp:716
#: engines/cruise/menu.cpp:216 backends/platform/wince/CEActionsPocket.cpp:267
#: backends/platform/wince/CEActionsSmartphone.cpp:231
msgid "Load"
msgstr "Carica"
-#: gui/launcher.cpp:723
+#: gui/launcher.cpp:747
msgid ""
"Do you really want to run the mass game detector? This could potentially add "
"a huge number of games."
@@ -449,7 +453,7 @@ msgstr ""
"Vuoi davvero eseguire il rilevatore di giochi in massa? Potrebbe aggiungere "
"un numero enorme di giochi."
-#: gui/launcher.cpp:724 gui/launcher.cpp:872
+#: gui/launcher.cpp:748 gui/launcher.cpp:896
#: backends/events/symbiansdl/symbiansdl-events.cpp:184
#: backends/platform/wince/CEActionsPocket.cpp:326
#: backends/platform/wince/CEActionsSmartphone.cpp:287
@@ -457,7 +461,7 @@ msgstr ""
msgid "Yes"
msgstr "Sì"
-#: gui/launcher.cpp:724 gui/launcher.cpp:872
+#: gui/launcher.cpp:748 gui/launcher.cpp:896
#: backends/events/symbiansdl/symbiansdl-events.cpp:184
#: backends/platform/wince/CEActionsPocket.cpp:326
#: backends/platform/wince/CEActionsSmartphone.cpp:287
@@ -465,40 +469,40 @@ msgstr "Sì"
msgid "No"
msgstr "No"
-#: gui/launcher.cpp:772
+#: gui/launcher.cpp:796
msgid "ScummVM couldn't open the specified directory!"
msgstr "ScummVM non ha potuto aprire la cartella specificata!"
-#: gui/launcher.cpp:784
+#: gui/launcher.cpp:808
msgid "ScummVM could not find any game in the specified directory!"
msgstr "ScummVM non ha potuto trovare nessun gioco nella cartella specificata!"
-#: gui/launcher.cpp:798
+#: gui/launcher.cpp:822
msgid "Pick the game:"
msgstr "Scegli il gioco:"
-#: gui/launcher.cpp:872
+#: gui/launcher.cpp:896
msgid "Do you really want to remove this game configuration?"
msgstr "Sei sicuro di voler rimuovere questa configurazione di gioco?"
-#: gui/launcher.cpp:936
+#: gui/launcher.cpp:960
msgid "This game does not support loading games from the launcher."
msgstr ""
"Questo gioco non supporta il caricamento di salvataggi dalla schermata di "
"avvio."
-#: gui/launcher.cpp:940
+#: gui/launcher.cpp:964
msgid "ScummVM could not find any engine capable of running the selected game!"
msgstr ""
"ScummVM non ha potuto trovare un motore in grado di eseguire il gioco "
"selezionato!"
-#: gui/launcher.cpp:1054
+#: gui/launcher.cpp:1078
msgctxt "lowres"
msgid "Mass Add..."
msgstr "Agg. massa..."
-#: gui/launcher.cpp:1054
+#: gui/launcher.cpp:1078
msgid "Mass Add..."
msgstr "Agg. in massa..."
@@ -525,143 +529,143 @@ msgstr "%d cartelle analizzate..."
msgid "Discovered %d new games, ignored %d previously added games ..."
msgstr "Rilevati %d nuovi giochi, ignorati %d giochi aggiunti in precedenza..."
-#: gui/options.cpp:72
+#: gui/options.cpp:78
msgid "Never"
msgstr "Mai"
-#: gui/options.cpp:72
+#: gui/options.cpp:78
msgid "every 5 mins"
msgstr "ogni 5 minuti"
-#: gui/options.cpp:72
+#: gui/options.cpp:78
msgid "every 10 mins"
msgstr "ogni 10 minuti"
-#: gui/options.cpp:72
+#: gui/options.cpp:78
msgid "every 15 mins"
msgstr "ogni 15 minuti"
-#: gui/options.cpp:72
+#: gui/options.cpp:78
msgid "every 30 mins"
msgstr "ogni 30 minuti"
-#: gui/options.cpp:74
+#: gui/options.cpp:80
msgid "8 kHz"
msgstr "8 kHz"
-#: gui/options.cpp:74
+#: gui/options.cpp:80
msgid "11kHz"
msgstr "11kHz"
-#: gui/options.cpp:74
+#: gui/options.cpp:80
msgid "22 kHz"
msgstr "22 kHz"
-#: gui/options.cpp:74
+#: gui/options.cpp:80
msgid "44 kHz"
msgstr "44 kHz"
-#: gui/options.cpp:74
+#: gui/options.cpp:80
msgid "48 kHz"
msgstr "48 kHz"
-#: gui/options.cpp:236 gui/options.cpp:464 gui/options.cpp:559
-#: gui/options.cpp:625 gui/options.cpp:825
+#: gui/options.cpp:257 gui/options.cpp:485 gui/options.cpp:586
+#: gui/options.cpp:659 gui/options.cpp:868
msgctxt "soundfont"
msgid "None"
msgstr "Nessuno"
-#: gui/options.cpp:372
+#: gui/options.cpp:393
msgid "Failed to apply some of the graphic options changes:"
msgstr "Impossibile applicare alcuni dei cambiamenti nelle opzioni grafiche."
-#: gui/options.cpp:384
+#: gui/options.cpp:405
msgid "the video mode could not be changed."
msgstr "impossibile modificare la modalità video."
-#: gui/options.cpp:390
+#: gui/options.cpp:411
msgid "the fullscreen setting could not be changed"
msgstr "impossibile modificare l'impostazione schermo intero"
-#: gui/options.cpp:396
+#: gui/options.cpp:417
msgid "the aspect ratio setting could not be changed"
msgstr "impossibile modificare l'impostazione proporzioni"
-#: gui/options.cpp:705
+#: gui/options.cpp:742
msgid "Graphics mode:"
msgstr "Modalità:"
-#: gui/options.cpp:716
+#: gui/options.cpp:756
msgid "Render mode:"
msgstr "Resa grafica:"
-#: gui/options.cpp:716 gui/options.cpp:717
+#: gui/options.cpp:756 gui/options.cpp:757
msgid "Special dithering modes supported by some games"
msgstr "Modalità di resa grafica speciali supportate da alcuni giochi"
-#: gui/options.cpp:726
+#: gui/options.cpp:768
#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2248
-#: backends/graphics/openglsdl/openglsdl-graphics.cpp:476
+#: backends/graphics/openglsdl/openglsdl-graphics.cpp:472
msgid "Fullscreen mode"
msgstr "Modalità a schermo intero"
-#: gui/options.cpp:729
+#: gui/options.cpp:771
msgid "Aspect ratio correction"
msgstr "Correzione proporzioni"
-#: gui/options.cpp:729
+#: gui/options.cpp:771
msgid "Correct aspect ratio for 320x200 games"
msgstr "Corregge le proporzioni dei giochi 320x200"
-#: gui/options.cpp:730
+#: gui/options.cpp:772
msgid "EGA undithering"
msgstr "Undithering EGA"
-#: gui/options.cpp:730
+#: gui/options.cpp:772
msgid "Enable undithering in EGA games that support it"
msgstr "Attiva undithering nei giochi EGA che lo supportano"
-#: gui/options.cpp:738
+#: gui/options.cpp:780
msgid "Preferred Device:"
msgstr "Disp. preferito:"
-#: gui/options.cpp:738
+#: gui/options.cpp:780
msgid "Music Device:"
msgstr "Dispositivo audio:"
-#: gui/options.cpp:738 gui/options.cpp:740
+#: gui/options.cpp:780 gui/options.cpp:782
msgid "Specifies preferred sound device or sound card emulator"
msgstr ""
"Specifica il dispositivo audio o l'emulatore della scheda audio preferiti"
-#: gui/options.cpp:738 gui/options.cpp:740 gui/options.cpp:741
+#: gui/options.cpp:780 gui/options.cpp:782 gui/options.cpp:783
msgid "Specifies output sound device or sound card emulator"
msgstr ""
"Specifica il dispositivo di output audio o l'emulatore della scheda audio"
-#: gui/options.cpp:740
+#: gui/options.cpp:782
msgctxt "lowres"
msgid "Preferred Dev.:"
msgstr "Disp. preferito:"
-#: gui/options.cpp:740
+#: gui/options.cpp:782
msgctxt "lowres"
msgid "Music Device:"
msgstr "Disposit. audio:"
-#: gui/options.cpp:766
+#: gui/options.cpp:809
msgid "AdLib emulator:"
msgstr "Emulatore AdLib:"
-#: gui/options.cpp:766 gui/options.cpp:767
+#: gui/options.cpp:809 gui/options.cpp:810
msgid "AdLib is used for music in many games"
msgstr "AdLib è utilizzato per la musica in molti giochi"
-#: gui/options.cpp:777
+#: gui/options.cpp:820
msgid "Output rate:"
msgstr "Frequenza:"
-#: gui/options.cpp:777 gui/options.cpp:778
+#: gui/options.cpp:820 gui/options.cpp:821
msgid ""
"Higher value specifies better sound quality but may be not supported by your "
"soundcard"
@@ -669,62 +673,62 @@ msgstr ""
"Valori più alti restituiscono un suono di maggior qualità, ma potrebbero non "
"essere supportati dalla tua scheda audio"
-#: gui/options.cpp:788
+#: gui/options.cpp:831
msgid "GM Device:"
msgstr "Dispositivo GM:"
-#: gui/options.cpp:788
+#: gui/options.cpp:831
msgid "Specifies default sound device for General MIDI output"
msgstr "Specifica il dispositivo audio predefinito per l'output General MIDI"
-#: gui/options.cpp:799
+#: gui/options.cpp:842
msgid "Don't use General MIDI music"
msgstr "Non utilizzare la musica General MIDI"
-#: gui/options.cpp:810 gui/options.cpp:871
+#: gui/options.cpp:853 gui/options.cpp:915
msgid "Use first available device"
msgstr "Utilizza il primo dispositivo disponibile"
-#: gui/options.cpp:822
+#: gui/options.cpp:865
msgid "SoundFont:"
msgstr "SoundFont:"
-#: gui/options.cpp:822 gui/options.cpp:824 gui/options.cpp:825
+#: gui/options.cpp:865 gui/options.cpp:867 gui/options.cpp:868
msgid "SoundFont is supported by some audio cards, Fluidsynth and Timidity"
msgstr "SoundFont è supportato da alcune schede audio, Fluidsynth e Timidity"
-#: gui/options.cpp:824
+#: gui/options.cpp:867
msgctxt "lowres"
msgid "SoundFont:"
msgstr "SoundFont:"
-#: gui/options.cpp:829
+#: gui/options.cpp:873
msgid "Mixed AdLib/MIDI mode"
msgstr "Modalità mista AdLib/MIDI"
-#: gui/options.cpp:829
+#: gui/options.cpp:873
msgid "Use both MIDI and AdLib sound generation"
msgstr "Utilizza generazione di suono sia MIDI che AdLib"
-#: gui/options.cpp:832
+#: gui/options.cpp:876
msgid "MIDI gain:"
msgstr "Guadagno MIDI:"
-#: gui/options.cpp:842
+#: gui/options.cpp:886
msgid "MT-32 Device:"
msgstr "Disposit. MT-32:"
-#: gui/options.cpp:842
+#: gui/options.cpp:886
msgid "Specifies default sound device for Roland MT-32/LAPC1/CM32l/CM64 output"
msgstr ""
"Specifica il dispositivo audio predefinito per l'output Roland MT-32/LAPC1/"
"CM32l/CM64"
-#: gui/options.cpp:847
+#: gui/options.cpp:891
msgid "True Roland MT-32 (disable GM emulation)"
msgstr "Roland MT-32 effettivo (disattiva emulazione GM)"
-#: gui/options.cpp:847 gui/options.cpp:849
+#: gui/options.cpp:891 gui/options.cpp:893
msgid ""
"Check if you want to use your real hardware Roland-compatible sound device "
"connected to your computer"
@@ -732,192 +736,192 @@ msgstr ""
"Seleziona se vuoi usare il dispositivo hardware audio compatibile con Roland "
"che è connesso al tuo computer"
-#: gui/options.cpp:849
+#: gui/options.cpp:893
msgctxt "lowres"
msgid "True Roland MT-32 (no GM emulation)"
msgstr "Roland MT-32 effettivo (disat.emul.GM)"
-#: gui/options.cpp:852
+#: gui/options.cpp:896
msgid "Enable Roland GS Mode"
msgstr "Attiva la modalità Roland GS"
-#: gui/options.cpp:852
+#: gui/options.cpp:896
msgid "Turns off General MIDI mapping for games with Roland MT-32 soundtrack"
msgstr ""
"Disattiva la mappatura General MIDI per i giochi con colonna sonora Roland "
"MT-32"
-#: gui/options.cpp:861
+#: gui/options.cpp:905
msgid "Don't use Roland MT-32 music"
msgstr "Non utilizzare la musica Roland MT-32"
-#: gui/options.cpp:888
+#: gui/options.cpp:932
msgid "Text and Speech:"
msgstr "Testo e voci:"
-#: gui/options.cpp:892 gui/options.cpp:902
+#: gui/options.cpp:936 gui/options.cpp:946
msgid "Speech"
msgstr "Voci"
-#: gui/options.cpp:893 gui/options.cpp:903
+#: gui/options.cpp:937 gui/options.cpp:947
msgid "Subtitles"
msgstr "Sottotitoli"
-#: gui/options.cpp:894
+#: gui/options.cpp:938
msgid "Both"
msgstr "Entrambi"
-#: gui/options.cpp:896
+#: gui/options.cpp:940
msgid "Subtitle speed:"
msgstr "Velocità testo:"
-#: gui/options.cpp:898
+#: gui/options.cpp:942
msgctxt "lowres"
msgid "Text and Speech:"
msgstr "Testo e voci:"
-#: gui/options.cpp:902
+#: gui/options.cpp:946
msgid "Spch"
msgstr "Voci"
-#: gui/options.cpp:903
+#: gui/options.cpp:947
msgid "Subs"
msgstr "Sub"
-#: gui/options.cpp:904
+#: gui/options.cpp:948
msgctxt "lowres"
msgid "Both"
msgstr "Entr."
-#: gui/options.cpp:904
+#: gui/options.cpp:948
msgid "Show subtitles and play speech"
msgstr "Mostra i sottotitoli e attiva le voci"
-#: gui/options.cpp:906
+#: gui/options.cpp:950
msgctxt "lowres"
msgid "Subtitle speed:"
msgstr "Velocità testo:"
-#: gui/options.cpp:922
+#: gui/options.cpp:966
msgid "Music volume:"
msgstr "Volume musica:"
-#: gui/options.cpp:924
+#: gui/options.cpp:968
msgctxt "lowres"
msgid "Music volume:"
msgstr "Volume musica:"
-#: gui/options.cpp:931
+#: gui/options.cpp:975
msgid "Mute All"
msgstr "Disattiva audio"
-#: gui/options.cpp:934
+#: gui/options.cpp:978
msgid "SFX volume:"
msgstr "Volume effetti:"
-#: gui/options.cpp:934 gui/options.cpp:936 gui/options.cpp:937
+#: gui/options.cpp:978 gui/options.cpp:980 gui/options.cpp:981
msgid "Special sound effects volume"
msgstr "Volume degli effetti sonori"
-#: gui/options.cpp:936
+#: gui/options.cpp:980
msgctxt "lowres"
msgid "SFX volume:"
msgstr "Volume effetti:"
-#: gui/options.cpp:944
+#: gui/options.cpp:988
msgid "Speech volume:"
msgstr "Volume voci:"
-#: gui/options.cpp:946
+#: gui/options.cpp:990
msgctxt "lowres"
msgid "Speech volume:"
msgstr "Volume voci:"
-#: gui/options.cpp:1085
+#: gui/options.cpp:1156
msgid "Theme Path:"
msgstr "Percorso tema:"
-#: gui/options.cpp:1087
+#: gui/options.cpp:1158
msgctxt "lowres"
msgid "Theme Path:"
msgstr "Perc. tema:"
-#: gui/options.cpp:1091 gui/options.cpp:1093 gui/options.cpp:1094
+#: gui/options.cpp:1164 gui/options.cpp:1166 gui/options.cpp:1167
msgid "Specifies path to additional data used by all games or ScummVM"
msgstr "Specifica il percorso di ulteriori dati usati dai giochi o da ScummVM"
-#: gui/options.cpp:1098
+#: gui/options.cpp:1173
msgid "Plugins Path:"
msgstr "Percorso plugin:"
-#: gui/options.cpp:1100
+#: gui/options.cpp:1175
msgctxt "lowres"
msgid "Plugins Path:"
msgstr "Perc. plugin:"
-#: gui/options.cpp:1109
+#: gui/options.cpp:1184
msgid "Misc"
msgstr "Varie"
-#: gui/options.cpp:1111
+#: gui/options.cpp:1186
msgctxt "lowres"
msgid "Misc"
msgstr "Varie"
-#: gui/options.cpp:1113
+#: gui/options.cpp:1188
msgid "Theme:"
msgstr "Tema:"
-#: gui/options.cpp:1117
+#: gui/options.cpp:1192
msgid "GUI Renderer:"
msgstr "Renderer GUI:"
-#: gui/options.cpp:1129
+#: gui/options.cpp:1204
msgid "Autosave:"
msgstr "Autosalva:"
-#: gui/options.cpp:1131
+#: gui/options.cpp:1206
msgctxt "lowres"
msgid "Autosave:"
msgstr "Autosalva:"
-#: gui/options.cpp:1139
+#: gui/options.cpp:1214
msgid "Keys"
msgstr "Tasti"
-#: gui/options.cpp:1146
+#: gui/options.cpp:1221
msgid "GUI Language:"
msgstr "Lingua GUI:"
-#: gui/options.cpp:1146
+#: gui/options.cpp:1221
msgid "Language of ScummVM GUI"
msgstr "Lingua dell'interfaccia grafica di ScummVM"
-#: gui/options.cpp:1295
+#: gui/options.cpp:1372
msgid "You have to restart ScummVM before your changes will take effect."
msgstr "Devi riavviare ScummVM affinché le modifiche abbiano effetto."
-#: gui/options.cpp:1308
+#: gui/options.cpp:1385
msgid "Select directory for savegames"
msgstr "Seleziona la cartella per i salvataggi"
-#: gui/options.cpp:1315
+#: gui/options.cpp:1392
msgid "The chosen directory cannot be written to. Please select another one."
msgstr "La cartella scelta è in sola lettura. Si prega di sceglierne un'altra."
-#: gui/options.cpp:1324
+#: gui/options.cpp:1401
msgid "Select directory for GUI themes"
msgstr "Seleziona la cartella dei temi dell'interfaccia"
-#: gui/options.cpp:1334
+#: gui/options.cpp:1411
msgid "Select directory for extra files"
msgstr "Seleziona la cartella dei file aggiuntivi"
-#: gui/options.cpp:1345
+#: gui/options.cpp:1422
msgid "Select directory for plugins"
msgstr "Seleziona la cartella dei plugin"
-#: gui/options.cpp:1389
+#: gui/options.cpp:1475
msgid ""
"The theme you selected does not support your current language. If you want "
"to use this theme you need to switch to another language first."
@@ -965,60 +969,64 @@ msgstr "Salvataggio senza titolo"
msgid "Select a Theme"
msgstr "Seleziona un tema"
-#: gui/ThemeEngine.cpp:328
+#: gui/ThemeEngine.cpp:333
msgid "Disabled GFX"
msgstr "Grafica disattivata"
-#: gui/ThemeEngine.cpp:328
+#: gui/ThemeEngine.cpp:333
msgctxt "lowres"
msgid "Disabled GFX"
msgstr "Grafica disattivata"
-#: gui/ThemeEngine.cpp:329
+#: gui/ThemeEngine.cpp:334
msgid "Standard Renderer (16bpp)"
msgstr "Renderer standard (16bpp)"
-#: gui/ThemeEngine.cpp:329
+#: gui/ThemeEngine.cpp:334
msgid "Standard (16bpp)"
msgstr "Standard (16bpp)"
-#: gui/ThemeEngine.cpp:331
+#: gui/ThemeEngine.cpp:336
msgid "Antialiased Renderer (16bpp)"
msgstr "Renderer con antialiasing (16bpp)"
-#: gui/ThemeEngine.cpp:331
+#: gui/ThemeEngine.cpp:336
msgid "Antialiased (16bpp)"
msgstr "Con antialiasing (16bpp)"
+#: gui/widget.cpp:312 gui/widget.cpp:314 gui/widget.cpp:320 gui/widget.cpp:322
+msgid "Clear value"
+msgstr "Cancella"
+
#: base/main.cpp:203
#, c-format
msgid "Engine does not support debug level '%s'"
msgstr "Il motore non supporta il livello di debug '%s'"
-#: base/main.cpp:271
+#: base/main.cpp:275
msgid "Menu"
msgstr "Menu"
-#: base/main.cpp:274 backends/platform/symbian/src/SymbianActions.cpp:45
+#: base/main.cpp:278 backends/platform/symbian/src/SymbianActions.cpp:45
#: backends/platform/wince/CEActionsPocket.cpp:45
#: backends/platform/wince/CEActionsSmartphone.cpp:46
msgid "Skip"
msgstr "Salta"
-#: base/main.cpp:277 backends/platform/symbian/src/SymbianActions.cpp:50
+#: base/main.cpp:281 backends/platform/symbian/src/SymbianActions.cpp:50
#: backends/platform/wince/CEActionsPocket.cpp:42
msgid "Pause"
msgstr "Pausa"
-#: base/main.cpp:280
+#: base/main.cpp:284
msgid "Skip line"
msgstr "Salta battuta"
-#: base/main.cpp:439
+#: base/main.cpp:455
msgid "Error running game:"
msgstr "Errore nell'esecuzione del gioco:"
-#: base/main.cpp:463
+#: base/main.cpp:479
msgid "Could not find any engine capable of running the selected game"
msgstr ""
"Impossibile trovare un motore in grado di eseguire il gioco selezionato"
@@ -1087,25 +1095,6 @@ msgstr "Utente cancellato"
msgid "Unknown error"
msgstr "Errore sconosciuto"
-#. I18N: Hercules is graphics card name
-#: common/util.cpp:275
-msgid "Hercules Green"
-msgstr "Hercules verde"
-
-#: common/util.cpp:276
-msgid "Hercules Amber"
-msgstr "Hercules ambra"
-
-#: common/util.cpp:283
-msgctxt "lowres"
-msgid "Hercules Green"
-msgstr "Hercules verde"
-
-#: common/util.cpp:284
-msgctxt "lowres"
-msgid "Hercules Amber"
-msgstr "Hercules ambra"
-
#: engines/advancedDetector.cpp:296
#, c-format
msgid "The game in '%s' seems to be unknown."
@@ -1153,12 +1142,12 @@ msgid "~R~eturn to Launcher"
msgstr "~V~ai a elenco giochi"
#: engines/dialogs.cpp:116 engines/cruise/menu.cpp:214
-#: engines/sci/engine/kfile.cpp:578
+#: engines/sci/engine/kfile.cpp:566
msgid "Save game:"
msgstr "Salva gioco:"
#: engines/dialogs.cpp:116 engines/scumm/dialogs.cpp:187
-#: engines/cruise/menu.cpp:214 engines/sci/engine/kfile.cpp:578
+#: engines/cruise/menu.cpp:214 engines/sci/engine/kfile.cpp:566
#: backends/platform/symbian/src/SymbianActions.cpp:44
#: backends/platform/wince/CEActionsPocket.cpp:43
#: backends/platform/wince/CEActionsPocket.cpp:267
@@ -1177,37 +1166,47 @@ msgstr ""
"gioco. Si prega di consultare il file README per le informazioni di base e "
"per le istruzioni su come ottenere ulteriore assistenza."
-#: engines/dialogs.cpp:316 engines/mohawk/dialogs.cpp:109
+#: engines/dialogs.cpp:243
+#, fuzzy, c-format
+msgid ""
+"Gamestate save failed (%s)! Please consult the README for basic information, "
+"and for instructions on how to obtain further assistance."
+msgstr ""
+"Siamo spiacenti, ma l'attuale motore non prevede aiuto all'interno del "
+"gioco. Si prega di consultare il file README per le informazioni di base e "
+"per le istruzioni su come ottenere ulteriore assistenza."
+
+#: engines/dialogs.cpp:321 engines/mohawk/dialogs.cpp:109
#: engines/mohawk/dialogs.cpp:174
msgid "~O~K"
msgstr "~O~K"
-#: engines/dialogs.cpp:317 engines/mohawk/dialogs.cpp:110
+#: engines/dialogs.cpp:322 engines/mohawk/dialogs.cpp:110
#: engines/mohawk/dialogs.cpp:175
msgid "~C~ancel"
msgstr "~A~nnulla"
-#: engines/dialogs.cpp:320
+#: engines/dialogs.cpp:325
msgid "~K~eys"
msgstr "~T~asti"
-#: engines/engine.cpp:233
+#: engines/engine.cpp:235
msgid "Could not initialize color format."
msgstr "Impossibile inizializzare il formato colore."
-#: engines/engine.cpp:241
+#: engines/engine.cpp:243
msgid "Could not switch to video mode: '"
msgstr "Impossibile cambiare la modalità video: '"
-#: engines/engine.cpp:250
+#: engines/engine.cpp:252
msgid "Could not apply aspect ratio setting."
msgstr "Impossibile applicare l'impostazione proporzioni"
-#: engines/engine.cpp:255
+#: engines/engine.cpp:257
msgid "Could not apply fullscreen setting."
msgstr "Impossibile applicare l'impostazione schermo intero."
-#: engines/engine.cpp:355
+#: engines/engine.cpp:357
msgid ""
"You appear to be playing this game directly\n"
"from the CD. This is known to cause problems,\n"
@@ -1221,7 +1220,7 @@ msgstr ""
"sull'hard disk.\n"
"Vedi il file README per i dettagli."
-#: engines/engine.cpp:366
+#: engines/engine.cpp:368
msgid ""
"This game has audio tracks in its disk. These\n"
"tracks need to be ripped from the disk using\n"
@@ -1235,7 +1234,17 @@ msgstr ""
"la musica del gioco.\n"
"Vedi il file README per i dettagli."
-#: engines/engine.cpp:433
+#: engines/engine.cpp:426
+#, fuzzy, c-format
+msgid ""
+"Gamestate load failed (%s)! Please consult the README for basic information, "
+"and for instructions on how to obtain further assistance."
+msgstr ""
+"Siamo spiacenti, ma l'attuale motore non prevede aiuto all'interno del "
+"gioco. Si prega di consultare il file README per le informazioni di base e "
+"per le istruzioni su come ottenere ulteriore assistenza."
+
+#: engines/engine.cpp:439
msgid ""
"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 "
@@ -1245,7 +1254,7 @@ msgstr ""
"ScummVM. È quindi possibile che sia instabile, e i salvataggi potrebbero non "
"funzionare con future versioni di ScummVM."
-#: engines/engine.cpp:436
+#: engines/engine.cpp:442
msgid "Start anyway"
msgstr "Avvia comunque"
@@ -1289,7 +1298,7 @@ msgstr "Gioca"
#: backends/platform/symbian/src/SymbianActions.cpp:52
#: backends/platform/wince/CEActionsPocket.cpp:44
#: backends/platform/wince/CEActionsSmartphone.cpp:52
-#: backends/events/default/default-events.cpp:244
+#: backends/events/default/default-events.cpp:213
msgid "Quit"
msgstr "Esci"
@@ -1363,6 +1372,27 @@ msgctxt "lowres"
msgid "Speech & Subs"
msgstr "Voci e testo"
+#: engines/scumm/dialogs.cpp:653
+msgid "Select a Proficiency Level."
+msgstr ""
+
+#: engines/scumm/dialogs.cpp:655
+msgid "Refer to your Loom(TM) manual for help."
+msgstr ""
+
+#: engines/scumm/dialogs.cpp:658
+#, fuzzy
+msgid "Standard"
+msgstr "Standard (16bpp)"
+
+#: engines/scumm/dialogs.cpp:659
+msgid "Practice"
+msgstr ""
+
+#: engines/scumm/dialogs.cpp:660
+msgid "Expert"
+msgstr ""
+
#: engines/scumm/help.cpp:73
msgid "Common keyboard commands:"
msgstr "Comandi da tastiera comuni:"
@@ -1876,7 +1906,7 @@ msgstr "Vola a destra"
msgid "Fly to lower right"
msgstr "Vola in basso a destra"
-#: engines/scumm/scumm.cpp:1774
+#: engines/scumm/scumm.cpp:1773
#, c-format
msgid ""
"Native MIDI support requires the Roland Upgrade from LucasArts,\n"
@@ -1885,7 +1915,7 @@ msgstr ""
"Il supporto nativo MIDI richiede il Roland Upgrade della LucasArts,\n"
"ma %s non è presente. Verrà usato AdLib."
-#: engines/scumm/scumm.cpp:2264 engines/agos/saveload.cpp:189
+#: engines/scumm/scumm.cpp:2271 engines/agos/saveload.cpp:189
#, c-format
msgid ""
"Failed to save game state to file:\n"
@@ -1896,7 +1926,7 @@ msgstr ""
"\n"
"%s"
-#: engines/scumm/scumm.cpp:2271 engines/agos/saveload.cpp:154
+#: engines/scumm/scumm.cpp:2278 engines/agos/saveload.cpp:154
#, c-format
msgid ""
"Failed to load game state from file:\n"
@@ -1907,7 +1937,7 @@ msgstr ""
"\n"
"%s"
-#: engines/scumm/scumm.cpp:2283 engines/agos/saveload.cpp:197
+#: engines/scumm/scumm.cpp:2290 engines/agos/saveload.cpp:197
#, c-format
msgid ""
"Successfully saved game state in file:\n"
@@ -1918,7 +1948,7 @@ msgstr ""
"\n"
"%s"
-#: engines/scumm/scumm.cpp:2498
+#: engines/scumm/scumm.cpp:2505
msgid ""
"Usually, Maniac Mansion would start now. But ScummVM doesn't do that yet. To "
"play it, go to 'Add Game' in the ScummVM start menu and select the 'Maniac' "
@@ -1955,11 +1985,11 @@ msgstr "~M~enu principale"
msgid "~W~ater Effect Enabled"
msgstr "~E~ffetto acqua attivo"
-#: engines/sci/engine/kfile.cpp:685
+#: engines/sci/engine/kfile.cpp:673
msgid "Restore game:"
msgstr "Ripristina gioco:"
-#: engines/sci/engine/kfile.cpp:685
+#: engines/sci/engine/kfile.cpp:673
msgid "Restore"
msgstr "Ripristina"
@@ -1969,11 +1999,11 @@ msgid "Cutscene file '%s' not found!"
msgstr "File della scena di intermezzo '%s' non trovato!"
#: engines/gob/inter_playtoons.cpp:256 engines/gob/inter_v2.cpp:1283
-#: engines/tinsel/saveload.cpp:482
+#: engines/tinsel/saveload.cpp:502
msgid "Failed to load game state from file."
msgstr "Impossibile caricare il gioco dal file."
-#: engines/gob/inter_v2.cpp:1353 engines/tinsel/saveload.cpp:560
+#: engines/gob/inter_v2.cpp:1353 engines/tinsel/saveload.cpp:515
msgid "Failed to save game state to file."
msgstr "Impossibile salvare il gioco nel file."
@@ -1985,6 +2015,60 @@ msgstr "Impossibile eliminare il file."
msgid "Failed to save game"
msgstr "Impossibile salvare il gioco"
+#: engines/kyra/lol.cpp:478
+msgid "Attack 1"
+msgstr ""
+
+#: engines/kyra/lol.cpp:479
+msgid "Attack 2"
+msgstr ""
+
+#: engines/kyra/lol.cpp:480
+msgid "Attack 3"
+msgstr ""
+
+#: engines/kyra/lol.cpp:481
+msgid "Move Forward"
+msgstr ""
+
+#: engines/kyra/lol.cpp:482
+msgid "Move Back"
+msgstr ""
+
+#: engines/kyra/lol.cpp:483
+msgid "Slide Left"
+msgstr ""
+
+#: engines/kyra/lol.cpp:484
+#, fuzzy
+msgid "Slide Right"
+msgstr "Destra"
+
+#: engines/kyra/lol.cpp:485
+#, fuzzy
+msgid "Turn Left"
+msgstr "Spegni"
+
+#: engines/kyra/lol.cpp:486
+#, fuzzy
+msgid "Turn Right"
+msgstr "Cursore a destra"
+
+#: engines/kyra/lol.cpp:487
+#, fuzzy
+msgid "Rest"
+msgstr "Ripristina"
+
+#: engines/kyra/lol.cpp:488
+#, fuzzy
+msgid "Options"
+msgstr "~O~pzioni"
+
+#: engines/kyra/lol.cpp:489
+#, fuzzy
+msgid "Choose Spell"
+msgstr "Scegli"
+
#: engines/kyra/sound_midi.cpp:475
msgid ""
"You appear to be using a General MIDI device,\n"
@@ -1999,10 +2083,6 @@ msgstr ""
"Roland MT32 in quelli General MIDI. Alcune tracce\n"
"potrebbero non essere riprodotte correttamente."
-#: engines/m4/m4_menus.cpp:138
-msgid "Save game failed!"
-msgstr "Salvataggio fallito!"
-
#: engines/sky/compact.cpp:130
msgid ""
"Unable to find \"sky.cpt\" file!\n"
@@ -2019,17 +2099,22 @@ msgstr ""
"Il file \"sky.cpt\" non ha una dimensione corretta.\n"
"Si prega di (ri)scaricarlo da www.scummvm.org"
-#: engines/sword1/animation.cpp:344 engines/sword2/animation.cpp:379
+#: engines/sword1/animation.cpp:539
+#, c-format
+msgid "PSX stream cutscene '%s' cannot be played in paletted mode"
+msgstr ""
+
+#: engines/sword1/animation.cpp:560 engines/sword2/animation.cpp:455
msgid "DXA cutscenes found but ScummVM has been built without zlib support"
msgstr ""
"Sono state trovare scene di intermezzo DXA ma ScummVM è stato compilato "
"senza il supporto zlib"
-#: engines/sword1/animation.cpp:354 engines/sword2/animation.cpp:389
+#: engines/sword1/animation.cpp:570 engines/sword2/animation.cpp:465
msgid "MPEG2 cutscenes are no longer supported"
msgstr "Le scene di intermezzo MPEG2 non sono più supportate"
-#: engines/sword1/animation.cpp:359 engines/sword2/animation.cpp:397
+#: engines/sword1/animation.cpp:576 engines/sword2/animation.cpp:473
#, c-format
msgid "Cutscene '%s' not found"
msgstr "Scena di intermezzo '%s' non trovata"
@@ -2073,6 +2158,14 @@ msgstr "Mantieni quello nuovo"
msgid "This is the end of the Broken Sword 1 Demo"
msgstr "Questa è la fine della demo di Broken Sword 1"
+#: engines/sword2/animation.cpp:435
+#, fuzzy
+msgid ""
+"PSX cutscenes found but ScummVM has been built without RGB color support"
+msgstr ""
+"Sono state trovare scene di intermezzo DXA ma ScummVM è stato compilato "
+"senza il supporto zlib"
+
#: engines/parallaction/saveload.cpp:133
#, c-format
msgid ""
@@ -2131,7 +2224,7 @@ msgstr "Emulatore OPL MAME"
msgid "DOSBox OPL emulator"
msgstr "Emulatore OPL DOSBox"
-#: audio/mididrv.cpp:205
+#: audio/mididrv.cpp:209
#, c-format
msgid ""
"The selected audio device '%s' was not found (e.g. might be turned off or "
@@ -2140,12 +2233,12 @@ msgstr ""
"Il dispositivo audio selezionato '%s' non è stato trovato (potrebbe essere "
"spento o scollegato)."
-#: audio/mididrv.cpp:205 audio/mididrv.cpp:217 audio/mididrv.cpp:253
-#: audio/mididrv.cpp:268
+#: audio/mididrv.cpp:209 audio/mididrv.cpp:221 audio/mididrv.cpp:257
+#: audio/mididrv.cpp:272
msgid "Attempting to fall back to the next available device..."
msgstr "Tentativo di ripristinare il primo dispositivo disponibile..."
-#: audio/mididrv.cpp:217
+#: audio/mididrv.cpp:221
#, c-format
msgid ""
"The selected audio device '%s' cannot be used. See log file for more "
@@ -2154,7 +2247,7 @@ msgstr ""
"Il dispositivo audio selezionato '%s' non può essere usato. Vedi il file log "
"per maggiori informazioni."
-#: audio/mididrv.cpp:253
+#: audio/mididrv.cpp:257
#, c-format
msgid ""
"The preferred audio device '%s' was not found (e.g. might be turned off or "
@@ -2163,7 +2256,7 @@ msgstr ""
"Il dispositivo audio preferito '%s' non è stato trovato (potrebbe essere "
"spento o scollegato)."
-#: audio/mididrv.cpp:268
+#: audio/mididrv.cpp:272
#, c-format
msgid ""
"The preferred audio device '%s' cannot be used. See log file for more "
@@ -2180,7 +2273,7 @@ msgstr "Nessuna musica"
msgid "Amiga Audio Emulator"
msgstr "Emulatore audio Amiga"
-#: audio/softsynth/adlib.cpp:1594
+#: audio/softsynth/adlib.cpp:1593
msgid "AdLib Emulator"
msgstr "Emulatore AdLib"
@@ -2192,11 +2285,11 @@ msgstr "Emulatore Apple II GS (NON IMPLEMENTATO)"
msgid "C64 Audio Emulator"
msgstr "Emulatore audio C64"
-#: audio/softsynth/mt32.cpp:329
+#: audio/softsynth/mt32.cpp:293
msgid "Initializing MT-32 Emulator"
msgstr "Avvio in corso dell'emulatore MT-32"
-#: audio/softsynth/mt32.cpp:543
+#: audio/softsynth/mt32.cpp:512
msgid "MT-32 Emulator"
msgstr "Emulatore MT-32"
@@ -2212,15 +2305,24 @@ msgstr "Emulatore IBM PCjr"
msgid "Keymap:"
msgstr "Mappa tasti:"
-#: backends/keymapper/remap-dialog.cpp:64
+#: backends/keymapper/remap-dialog.cpp:66
+#, fuzzy
+msgid " (Effective)"
+msgstr " (Attivo)"
+
+#: backends/keymapper/remap-dialog.cpp:106
msgid " (Active)"
msgstr " (Attivo)"
-#: backends/keymapper/remap-dialog.cpp:98
+#: backends/keymapper/remap-dialog.cpp:106
+msgid " (Blocked)"
+msgstr ""
+
+#: backends/keymapper/remap-dialog.cpp:119
msgid " (Global)"
msgstr " (Globale)"
-#: backends/keymapper/remap-dialog.cpp:108
+#: backends/keymapper/remap-dialog.cpp:127
msgid " (Game)"
msgstr " (Gioco)"
@@ -2300,42 +2402,66 @@ msgstr "Audio ad alta qualità (più lento) (riavviare)"
msgid "Disable power off"
msgstr "Disattiva spegnimento in chiusura"
-#: backends/platform/iphone/osys_events.cpp:338
+#: backends/platform/iphone/osys_events.cpp:301
msgid "Mouse-click-and-drag mode enabled."
msgstr "Modalità mouse-clicca-e-trascina attivata."
-#: backends/platform/iphone/osys_events.cpp:340
+#: backends/platform/iphone/osys_events.cpp:303
msgid "Mouse-click-and-drag mode disabled."
msgstr "Modalità mouse-clicca-e-trascina disattivata."
-#: backends/platform/iphone/osys_events.cpp:351
+#: backends/platform/iphone/osys_events.cpp:314
msgid "Touchpad mode enabled."
msgstr "Modalità touchpad attivata."
-#: backends/platform/iphone/osys_events.cpp:353
+#: backends/platform/iphone/osys_events.cpp:316
msgid "Touchpad mode disabled."
msgstr "Modalità touchpad disattivata."
-#: backends/platform/sdl/macosx/appmenu_osx.mm:67
+#: backends/platform/maemo/maemo.cpp:205
+msgid "Click Mode"
+msgstr ""
+
+#: backends/platform/maemo/maemo.cpp:211
+#: backends/platform/symbian/src/SymbianActions.cpp:42
+#: backends/platform/wince/CEActionsPocket.cpp:60
+#: backends/platform/wince/CEActionsSmartphone.cpp:43
+#: backends/platform/bada/form.cpp:281
+msgid "Left Click"
+msgstr "Clic sinistro"
+
+#: backends/platform/maemo/maemo.cpp:214
+#, fuzzy
+msgid "Middle Click"
+msgstr "Oggetto al centro a sinistra"
+
+#: backends/platform/maemo/maemo.cpp:217
+#: backends/platform/symbian/src/SymbianActions.cpp:43
+#: backends/platform/wince/CEActionsSmartphone.cpp:44
+#: backends/platform/bada/form.cpp:273
+msgid "Right Click"
+msgstr "Clic destro"
+
+#: backends/platform/sdl/macosx/appmenu_osx.mm:78
msgid "Hide ScummVM"
msgstr "Nascondi ScummVM"
-#: backends/platform/sdl/macosx/appmenu_osx.mm:70
+#: backends/platform/sdl/macosx/appmenu_osx.mm:83
msgid "Hide Others"
-msgstr "Nascondi altri"
+msgstr "Nascondi altre"
-#: backends/platform/sdl/macosx/appmenu_osx.mm:74
+#: backends/platform/sdl/macosx/appmenu_osx.mm:88
msgid "Show All"
-msgstr "Mostra tutti"
+msgstr "Mostra tutte"
-#: backends/platform/sdl/macosx/appmenu_osx.mm:92
-#: backends/platform/sdl/macosx/appmenu_osx.mm:99
+#: backends/platform/sdl/macosx/appmenu_osx.mm:110
+#: backends/platform/sdl/macosx/appmenu_osx.mm:121
msgid "Window"
msgstr "Finestra"
-#: backends/platform/sdl/macosx/appmenu_osx.mm:95
+#: backends/platform/sdl/macosx/appmenu_osx.mm:115
msgid "Minimize"
-msgstr "Minimizza"
+msgstr "Contrai"
#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:45
msgid "Normal (no scaling)"
@@ -2347,12 +2473,12 @@ msgid "Normal (no scaling)"
msgstr "Normale (no ridim.)"
#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2147
-#: backends/graphics/openglsdl/openglsdl-graphics.cpp:537
+#: backends/graphics/openglsdl/openglsdl-graphics.cpp:533
msgid "Enabled aspect ratio correction"
msgstr "Correzione proporzioni attivata"
#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2153
-#: backends/graphics/openglsdl/openglsdl-graphics.cpp:542
+#: backends/graphics/openglsdl/openglsdl-graphics.cpp:538
msgid "Disabled aspect ratio correction"
msgstr "Correzione proporzioni disattivata"
@@ -2361,7 +2487,7 @@ msgid "Active graphics filter:"
msgstr "Filtro grafico attivo:"
#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2250
-#: backends/graphics/openglsdl/openglsdl-graphics.cpp:481
+#: backends/graphics/openglsdl/openglsdl-graphics.cpp:477
msgid "Windowed mode"
msgstr "Modalità finestra"
@@ -2385,11 +2511,11 @@ msgstr "Modalità visualizzazione attuale"
msgid "Current scale"
msgstr "Dimensioni attuali"
-#: backends/graphics/openglsdl/openglsdl-graphics.cpp:562
+#: backends/graphics/openglsdl/openglsdl-graphics.cpp:558
msgid "Active filter mode: Linear"
msgstr "Modalità filtro attiva: Lineare"
-#: backends/graphics/openglsdl/openglsdl-graphics.cpp:564
+#: backends/graphics/openglsdl/openglsdl-graphics.cpp:560
msgid "Active filter mode: Nearest"
msgstr "Modalità filtro attiva: Più vicino"
@@ -2413,19 +2539,6 @@ msgstr "Sinistra"
msgid "Right"
msgstr "Destra"
-#: backends/platform/symbian/src/SymbianActions.cpp:42
-#: backends/platform/wince/CEActionsPocket.cpp:60
-#: backends/platform/wince/CEActionsSmartphone.cpp:43
-#: backends/platform/bada/form.cpp:281
-msgid "Left Click"
-msgstr "Clic sinistro"
-
-#: backends/platform/symbian/src/SymbianActions.cpp:43
-#: backends/platform/wince/CEActionsSmartphone.cpp:44
-#: backends/platform/bada/form.cpp:273
-msgid "Right Click"
-msgstr "Clic destro"
-
#: backends/platform/symbian/src/SymbianActions.cpp:46
#: backends/platform/wince/CEActionsSmartphone.cpp:47
msgid "Zone"
@@ -2714,15 +2827,15 @@ msgstr ""
"Non dimenticare di mappare un tasto per l'azione \"Nascondi barra degli "
"strumenti\" per vedere l'intero inventario"
-#: backends/events/default/default-events.cpp:222
+#: backends/events/default/default-events.cpp:191
msgid "Do you really want to return to the Launcher?"
msgstr "Sei sicuro di voler tornare all'elenco giochi?"
-#: backends/events/default/default-events.cpp:222
+#: backends/events/default/default-events.cpp:191
msgid "Launcher"
msgstr "Elenco giochi"
-#: backends/events/default/default-events.cpp:244
+#: backends/events/default/default-events.cpp:213
msgid "Do you really want to quit?"
msgstr "Sei sicuro di voler uscire?"
@@ -2792,14 +2905,31 @@ msgstr "Mostra tastiera"
msgid "Control Mouse"
msgstr ""
-#: backends/events/maemosdl/maemosdl-events.cpp:121
+#: backends/events/maemosdl/maemosdl-events.cpp:192
msgid "Clicking Enabled"
msgstr ""
-#: backends/events/maemosdl/maemosdl-events.cpp:121
+#: backends/events/maemosdl/maemosdl-events.cpp:192
msgid "Clicking Disabled"
msgstr ""
+#~ msgid "Hercules Green"
+#~ msgstr "Hercules verde"
+
+#~ msgid "Hercules Amber"
+#~ msgstr "Hercules ambra"
+
+#~ msgctxt "lowres"
+#~ msgid "Hercules Green"
+#~ msgstr "Hercules verde"
+
+#~ msgctxt "lowres"
+#~ msgid "Hercules Amber"
+#~ msgstr "Hercules ambra"
+
+#~ msgid "Save game failed!"
+#~ msgstr "Salvataggio fallito!"
+
#~ msgctxt "lowres"
#~ msgid "Add Game..."
#~ msgstr "Agg. gioco..."
diff --git a/po/module.mk b/po/module.mk
index ef3e0589fc..a9295656db 100644
--- a/po/module.mk
+++ b/po/module.mk
@@ -1,5 +1,6 @@
POTFILE := $(srcdir)/po/scummvm.pot
POFILES := $(wildcard $(srcdir)/po/*.po)
+CPFILES := $(wildcard $(srcdir)/po/*.cp)
updatepot:
xgettext -f $(srcdir)/po/POTFILES -D $(srcdir) -d scummvm --c++ -k_ -k_s -k_c:1,2c -k_sc:1,2c --add-comments=I18N\
@@ -34,12 +35,12 @@ updatepot:
fi;
translations-dat: devtools/create_translations
- devtools/create_translations/create_translations $(POFILES)
+ devtools/create_translations/create_translations $(POFILES) $(CPFILES)
mv translations.dat $(srcdir)/gui/themes/
-update-translations: updatepot $(POFILES) translations-dat
+update-translations: updatepot $(POFILES) $(CPFILES) translations-dat
-update-translations: updatepot $(POFILES)
+update-translations: updatepot $(POFILES) $(CPFILES)
@$(foreach file, $(POFILES), echo -n $(notdir $(basename $(file)))": ";msgfmt --statistic $(file);)
@rm -f messages.mo
diff --git a/po/nb_NO.po b/po/nb_NO.po
index bfe0da8997..780cd8daa7 100644
--- a/po/nb_NO.po
+++ b/po/nb_NO.po
@@ -1,20 +1,20 @@
-# Norwegian (Bokmaal) translation for ScummVM.
-# Copyright (C) 2010 ScummVM Team
-# This file is distributed under the same license as the ScummVM package.
-# Einar Johan T. Sømåen <einarjohants@gmail.com>, 2010.
-#
+# Norwegian (Bokmaal) translation for ScummVM.
+# Copyright (C) 2010-2012 ScummVM Team
+# This file is distributed under the same license as the ScummVM package.
+# Einar Johan T. Sømåen <einarjohants@gmail.com>, 2010.
+#
msgid ""
msgstr ""
"Project-Id-Version: ScummVM 1.3.0svn\n"
"Report-Msgid-Bugs-To: scummvm-devel@lists.sf.net\n"
-"POT-Creation-Date: 2011-10-19 13:42+0100\n"
+"POT-Creation-Date: 2012-03-07 22:09+0000\n"
"PO-Revision-Date: 2011-04-25 22:56+0100\n"
"Last-Translator: Einar Johan T. Sømåen <einarjohants@gmail.com>\n"
"Language-Team: somaen <einarjohants@gmail.com>\n"
-"Language: Norsk (bokmaal)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=iso-8859-1\n"
"Content-Transfer-Encoding: 8bit\n"
+"Language: Norsk (bokmaal)\n"
"Plural-Forms: nplurals=2; plural=(n != 1)\n"
"X-Poedit-Language: Norsk Bokmål\n"
"X-Poedit-Country: NORWAY\n"
@@ -47,13 +47,13 @@ msgid "Go up"
msgstr "Gå tilbake"
#: gui/browser.cpp:69 gui/chooser.cpp:45 gui/KeysDialog.cpp:43
-#: gui/launcher.cpp:312 gui/massadd.cpp:94 gui/options.cpp:1178
+#: gui/launcher.cpp:320 gui/massadd.cpp:94 gui/options.cpp:1253
#: gui/saveload.cpp:63 gui/saveload.cpp:155 gui/themebrowser.cpp:54
-#: engines/engine.cpp:436 engines/scumm/dialogs.cpp:190
+#: engines/engine.cpp:442 engines/scumm/dialogs.cpp:190
#: engines/sword1/control.cpp:865 engines/parallaction/saveload.cpp:281
#: backends/platform/wii/options.cpp:48
-#: backends/events/default/default-events.cpp:222
-#: backends/events/default/default-events.cpp:244
+#: backends/events/default/default-events.cpp:191
+#: backends/events/default/default-events.cpp:213
msgid "Cancel"
msgstr "Avbryt"
@@ -61,25 +61,30 @@ msgstr "Avbryt"
msgid "Choose"
msgstr "Velg"
-#: gui/gui-manager.cpp:116 engines/scumm/help.cpp:125
+#: gui/gui-manager.cpp:115 engines/scumm/help.cpp:125
#: engines/scumm/help.cpp:140 engines/scumm/help.cpp:165
#: engines/scumm/help.cpp:191 engines/scumm/help.cpp:209
#: backends/keymapper/remap-dialog.cpp:52
msgid "Close"
msgstr "Lukk"
-#: gui/gui-manager.cpp:119
+#: gui/gui-manager.cpp:118
msgid "Mouse click"
msgstr "Musklikk"
-#: gui/gui-manager.cpp:122 base/main.cpp:283
+#: gui/gui-manager.cpp:122 base/main.cpp:288
msgid "Display keyboard"
msgstr "Vis tastatur"
-#: gui/gui-manager.cpp:125 base/main.cpp:286
+#: gui/gui-manager.cpp:126 base/main.cpp:292
msgid "Remap keys"
msgstr "Omkoble taster"
+#: gui/gui-manager.cpp:129 base/main.cpp:295
+#, fuzzy
+msgid "Toggle FullScreen"
+msgstr "Veksle fullskjerm"
+
#: gui/KeysDialog.h:36 gui/KeysDialog.cpp:145
msgid "Choose an action to map"
msgstr "Velg en handling for kobling"
@@ -88,16 +93,17 @@ msgstr "Velg en handling for kobling"
msgid "Map"
msgstr "Koble"
-#: gui/KeysDialog.cpp:42 gui/launcher.cpp:313 gui/launcher.cpp:936
-#: gui/launcher.cpp:940 gui/massadd.cpp:91 gui/options.cpp:1179
-#: engines/engine.cpp:359 engines/engine.cpp:370 engines/scumm/dialogs.cpp:192
-#: engines/scumm/scumm.cpp:1776 engines/agos/animation.cpp:551
+#: gui/KeysDialog.cpp:42 gui/launcher.cpp:321 gui/launcher.cpp:960
+#: gui/launcher.cpp:964 gui/massadd.cpp:91 gui/options.cpp:1254
+#: engines/engine.cpp:361 engines/engine.cpp:372 engines/scumm/dialogs.cpp:192
+#: engines/scumm/scumm.cpp:1775 engines/agos/animation.cpp:551
#: engines/groovie/script.cpp:420 engines/sky/compact.cpp:131
-#: engines/sky/compact.cpp:141 engines/sword1/animation.cpp:344
-#: engines/sword1/animation.cpp:354 engines/sword1/animation.cpp:360
-#: engines/sword1/control.cpp:865 engines/sword1/logic.cpp:1633
-#: engines/sword2/animation.cpp:379 engines/sword2/animation.cpp:389
-#: engines/sword2/animation.cpp:398 engines/parallaction/saveload.cpp:281
+#: engines/sky/compact.cpp:141 engines/sword1/animation.cpp:539
+#: engines/sword1/animation.cpp:560 engines/sword1/animation.cpp:570
+#: engines/sword1/animation.cpp:577 engines/sword1/control.cpp:865
+#: engines/sword1/logic.cpp:1633 engines/sword2/animation.cpp:435
+#: engines/sword2/animation.cpp:455 engines/sword2/animation.cpp:465
+#: engines/sword2/animation.cpp:474 engines/parallaction/saveload.cpp:281
#: backends/platform/wii/options.cpp:47
#: backends/platform/wince/CELauncherDialog.cpp:54
msgid "OK"
@@ -125,15 +131,15 @@ msgstr "Vennligst velg en handling"
msgid "Press the key to associate"
msgstr "Trykk tasten som skal kobles"
-#: gui/launcher.cpp:165
+#: gui/launcher.cpp:170
msgid "Game"
msgstr "Spill"
-#: gui/launcher.cpp:169
+#: gui/launcher.cpp:174
msgid "ID:"
msgstr "ID:"
-#: gui/launcher.cpp:169 gui/launcher.cpp:171 gui/launcher.cpp:172
+#: gui/launcher.cpp:174 gui/launcher.cpp:176 gui/launcher.cpp:177
msgid ""
"Short game identifier used for referring to savegames and running the game "
"from the command line"
@@ -141,29 +147,29 @@ msgstr ""
"Kort spill-identifikator, brukt for å referere til lagrede spill, og å kjøre "
"spillet fra kommandolinjen"
-#: gui/launcher.cpp:171
+#: gui/launcher.cpp:176
msgctxt "lowres"
msgid "ID:"
msgstr "ID:"
-#: gui/launcher.cpp:176
+#: gui/launcher.cpp:181
msgid "Name:"
msgstr "Navn:"
-#: gui/launcher.cpp:176 gui/launcher.cpp:178 gui/launcher.cpp:179
+#: gui/launcher.cpp:181 gui/launcher.cpp:183 gui/launcher.cpp:184
msgid "Full title of the game"
msgstr "Full spilltittel"
-#: gui/launcher.cpp:178
+#: gui/launcher.cpp:183
msgctxt "lowres"
msgid "Name:"
msgstr "Navn:"
-#: gui/launcher.cpp:182
+#: gui/launcher.cpp:187
msgid "Language:"
msgstr "Språk:"
-#: gui/launcher.cpp:182 gui/launcher.cpp:183
+#: gui/launcher.cpp:187 gui/launcher.cpp:188
msgid ""
"Language of the game. This will not turn your Spanish game version into "
"English"
@@ -171,282 +177,280 @@ msgstr ""
"Spillets språk. Dette vil ikke gjøre din spanske spillversjon om til engelsk "
"versjon"
-#: gui/launcher.cpp:184 gui/launcher.cpp:198 gui/options.cpp:74
-#: gui/options.cpp:708 gui/options.cpp:718 gui/options.cpp:1149
+#: gui/launcher.cpp:189 gui/launcher.cpp:203 gui/options.cpp:80
+#: gui/options.cpp:745 gui/options.cpp:758 gui/options.cpp:1224
#: audio/null.cpp:40
msgid "<default>"
msgstr "<standard>"
-#: gui/launcher.cpp:194
+#: gui/launcher.cpp:199
msgid "Platform:"
msgstr "Plattform:"
-#: gui/launcher.cpp:194 gui/launcher.cpp:196 gui/launcher.cpp:197
+#: gui/launcher.cpp:199 gui/launcher.cpp:201 gui/launcher.cpp:202
msgid "Platform the game was originally designed for"
msgstr "Plattform spillet opprinnelig ble designet for"
-#: gui/launcher.cpp:196
+#: gui/launcher.cpp:201
msgctxt "lowres"
msgid "Platform:"
msgstr "Plattform:"
-#: gui/launcher.cpp:208 gui/options.cpp:1018 gui/options.cpp:1035
+#: gui/launcher.cpp:213 gui/options.cpp:1087 gui/options.cpp:1104
msgid "Graphics"
msgstr "Grafikk"
-#: gui/launcher.cpp:208 gui/options.cpp:1018 gui/options.cpp:1035
+#: gui/launcher.cpp:213 gui/options.cpp:1087 gui/options.cpp:1104
msgid "GFX"
msgstr "GFX"
-#: gui/launcher.cpp:211
+#: gui/launcher.cpp:216
msgid "Override global graphic settings"
msgstr "Overstyr globale grafikkinstillinger"
-#: gui/launcher.cpp:213
+#: gui/launcher.cpp:218
msgctxt "lowres"
msgid "Override global graphic settings"
msgstr "Overstyr globale grafikkinstillinger"
-#: gui/launcher.cpp:220 gui/options.cpp:1041
+#: gui/launcher.cpp:225 gui/options.cpp:1110
msgid "Audio"
msgstr "Lyd"
-#: gui/launcher.cpp:223
+#: gui/launcher.cpp:228
msgid "Override global audio settings"
msgstr "Overstyr globale lydinstillinger"
-#: gui/launcher.cpp:225
+#: gui/launcher.cpp:230
msgctxt "lowres"
msgid "Override global audio settings"
msgstr "Overstyr globale lydinstillinger"
-#: gui/launcher.cpp:234 gui/options.cpp:1046
+#: gui/launcher.cpp:239 gui/options.cpp:1115
msgid "Volume"
msgstr "Volum"
-#: gui/launcher.cpp:236 gui/options.cpp:1048
+#: gui/launcher.cpp:241 gui/options.cpp:1117
msgctxt "lowres"
msgid "Volume"
msgstr "Volum"
-#: gui/launcher.cpp:239
+#: gui/launcher.cpp:244
msgid "Override global volume settings"
msgstr "Overstyr globale voluminstillinger"
-#: gui/launcher.cpp:241
+#: gui/launcher.cpp:246
msgctxt "lowres"
msgid "Override global volume settings"
msgstr "Overstyr globale voluminstillinger"
-#: gui/launcher.cpp:248 gui/options.cpp:1056
+#: gui/launcher.cpp:254 gui/options.cpp:1125
msgid "MIDI"
msgstr "MIDI"
-#: gui/launcher.cpp:251
+#: gui/launcher.cpp:257
msgid "Override global MIDI settings"
msgstr "Overstyr globale MIDI-instillinger"
-#: gui/launcher.cpp:253
+#: gui/launcher.cpp:259
msgctxt "lowres"
msgid "Override global MIDI settings"
msgstr "Overstyr globale MIDI-instillinger"
-#: gui/launcher.cpp:263 gui/options.cpp:1062
+#: gui/launcher.cpp:268 gui/options.cpp:1131
msgid "MT-32"
msgstr "MT-32"
-#: gui/launcher.cpp:266
+#: gui/launcher.cpp:271
msgid "Override global MT-32 settings"
msgstr "Overstyr globale MT-32-instillinger"
-#: gui/launcher.cpp:268
+#: gui/launcher.cpp:273
msgctxt "lowres"
msgid "Override global MT-32 settings"
msgstr "Overstyr globale MT-32-instillinger"
-#: gui/launcher.cpp:279 gui/options.cpp:1069
+#: gui/launcher.cpp:282 gui/options.cpp:1138
msgid "Paths"
msgstr "Sti"
-#: gui/launcher.cpp:281 gui/options.cpp:1071
+#: gui/launcher.cpp:284 gui/options.cpp:1140
msgctxt "lowres"
msgid "Paths"
msgstr "Sti"
-#: gui/launcher.cpp:288
+#: gui/launcher.cpp:291
msgid "Game Path:"
msgstr "Spillsti:"
-#: gui/launcher.cpp:290
+#: gui/launcher.cpp:293
msgctxt "lowres"
msgid "Game Path:"
msgstr "Spillsti:"
-#: gui/launcher.cpp:295 gui/options.cpp:1091
+#: gui/launcher.cpp:298 gui/options.cpp:1164
msgid "Extra Path:"
msgstr "Ekstrasti:"
-#: gui/launcher.cpp:295 gui/launcher.cpp:297 gui/launcher.cpp:298
+#: gui/launcher.cpp:298 gui/launcher.cpp:300 gui/launcher.cpp:301
msgid "Specifies path to additional data used the game"
msgstr "Bestemmer sti til ytterligere data brukt av spillet"
-#: gui/launcher.cpp:297 gui/options.cpp:1093
+#: gui/launcher.cpp:300 gui/options.cpp:1166
msgctxt "lowres"
msgid "Extra Path:"
msgstr "Ekstrasti:"
-#: gui/launcher.cpp:302 gui/options.cpp:1079
+#: gui/launcher.cpp:307 gui/options.cpp:1148
msgid "Save Path:"
msgstr "Lagringssti:"
-#: gui/launcher.cpp:302 gui/launcher.cpp:304 gui/launcher.cpp:305
-#: gui/options.cpp:1079 gui/options.cpp:1081 gui/options.cpp:1082
+#: gui/launcher.cpp:307 gui/launcher.cpp:309 gui/launcher.cpp:310
+#: gui/options.cpp:1148 gui/options.cpp:1150 gui/options.cpp:1151
msgid "Specifies where your savegames are put"
msgstr "Bestemmer sti til lagrede spill"
-#: gui/launcher.cpp:304 gui/options.cpp:1081
+#: gui/launcher.cpp:309 gui/options.cpp:1150
msgctxt "lowres"
msgid "Save Path:"
msgstr "Lagringssti:"
-#: gui/launcher.cpp:321 gui/launcher.cpp:404 gui/launcher.cpp:453
-#: gui/options.cpp:1088 gui/options.cpp:1094 gui/options.cpp:1101
-#: gui/options.cpp:1202 gui/options.cpp:1208 gui/options.cpp:1214
-#: gui/options.cpp:1222 gui/options.cpp:1246 gui/options.cpp:1250
-#: gui/options.cpp:1256 gui/options.cpp:1263 gui/options.cpp:1362
+#: gui/launcher.cpp:329 gui/launcher.cpp:416 gui/launcher.cpp:469
+#: gui/launcher.cpp:523 gui/options.cpp:1159 gui/options.cpp:1167
+#: gui/options.cpp:1176 gui/options.cpp:1283 gui/options.cpp:1289
+#: gui/options.cpp:1297 gui/options.cpp:1327 gui/options.cpp:1333
+#: gui/options.cpp:1340 gui/options.cpp:1433 gui/options.cpp:1436
+#: gui/options.cpp:1448
msgctxt "path"
msgid "None"
msgstr "Ingen"
-#: gui/launcher.cpp:326 gui/launcher.cpp:408
+#: gui/launcher.cpp:334 gui/launcher.cpp:422 gui/launcher.cpp:527
+#: gui/options.cpp:1277 gui/options.cpp:1321 gui/options.cpp:1439
#: backends/platform/wii/options.cpp:56
msgid "Default"
msgstr "Standard"
-#: gui/launcher.cpp:446 gui/options.cpp:1356
+#: gui/launcher.cpp:462 gui/options.cpp:1442
msgid "Select SoundFont"
msgstr "Velg SoundFont"
-#: gui/launcher.cpp:465 gui/launcher.cpp:612
+#: gui/launcher.cpp:481 gui/launcher.cpp:636
msgid "Select directory with game data"
msgstr "Velg mappe med spilldata"
-#: gui/launcher.cpp:483
+#: gui/launcher.cpp:499
msgid "Select additional game directory"
msgstr "Velg mappe med ytterligere data"
-#: gui/launcher.cpp:495
+#: gui/launcher.cpp:511
msgid "Select directory for saved games"
msgstr "Velg mappe for lagrede spill"
-#: gui/launcher.cpp:514
+#: gui/launcher.cpp:538
msgid "This game ID is already taken. Please choose another one."
msgstr "Denne spill-IDen er allerede i bruk. Vennligst velg en annen."
-#: gui/launcher.cpp:555 engines/dialogs.cpp:110
+#: gui/launcher.cpp:579 engines/dialogs.cpp:110
msgid "~Q~uit"
msgstr "~A~vslutt"
-#: gui/launcher.cpp:555 backends/platform/sdl/macosx/appmenu_osx.mm:80
+#: gui/launcher.cpp:579 backends/platform/sdl/macosx/appmenu_osx.mm:96
msgid "Quit ScummVM"
msgstr "Avslutt ScummVM"
-#: gui/launcher.cpp:556
+#: gui/launcher.cpp:580
msgid "A~b~out..."
msgstr "~O~m..."
-#: gui/launcher.cpp:556 backends/platform/sdl/macosx/appmenu_osx.mm:61
+#: gui/launcher.cpp:580 backends/platform/sdl/macosx/appmenu_osx.mm:70
msgid "About ScummVM"
msgstr "Om ScummVM"
-#: gui/launcher.cpp:557
+#: gui/launcher.cpp:581
msgid "~O~ptions..."
msgstr "~V~alg..."
-#: gui/launcher.cpp:557
+#: gui/launcher.cpp:581
msgid "Change global ScummVM options"
msgstr "Endre globale ScummVM-innstillinger"
-#: gui/launcher.cpp:559
+#: gui/launcher.cpp:583
msgid "~S~tart"
msgstr "~S~tart"
-#: gui/launcher.cpp:559
+#: gui/launcher.cpp:583
msgid "Start selected game"
msgstr "Start valgt spill"
-#: gui/launcher.cpp:562
+#: gui/launcher.cpp:586
msgid "~L~oad..."
msgstr "~Å~pne..."
-#: gui/launcher.cpp:562
+#: gui/launcher.cpp:586
msgid "Load savegame for selected game"
msgstr "Åpne lagret spill for det valgte spillet"
-#: gui/launcher.cpp:567 gui/launcher.cpp:1055
+#: gui/launcher.cpp:591 gui/launcher.cpp:1079
msgid "~A~dd Game..."
msgstr "~L~egg til spill..."
-#: gui/launcher.cpp:567 gui/launcher.cpp:574
+#: gui/launcher.cpp:591 gui/launcher.cpp:598
msgid "Hold Shift for Mass Add"
msgstr "Hold Shift for å legge til flere"
-#: gui/launcher.cpp:569
+#: gui/launcher.cpp:593
msgid "~E~dit Game..."
msgstr "~R~ediger spill..."
-#: gui/launcher.cpp:569 gui/launcher.cpp:576
+#: gui/launcher.cpp:593 gui/launcher.cpp:600
msgid "Change game options"
msgstr "Endre spillinstillinger"
-#: gui/launcher.cpp:571
+#: gui/launcher.cpp:595
msgid "~R~emove Game"
msgstr "~F~jern spill"
-#: gui/launcher.cpp:571 gui/launcher.cpp:578
+#: gui/launcher.cpp:595 gui/launcher.cpp:602
msgid "Remove game from the list. The game data files stay intact"
msgstr "Fjern spill fra listen. Spilldataene forblir intakte"
-#: gui/launcher.cpp:574 gui/launcher.cpp:1055
+#: gui/launcher.cpp:598 gui/launcher.cpp:1079
msgctxt "lowres"
msgid "~A~dd Game..."
msgstr "~L~egg til spill..."
-#: gui/launcher.cpp:576
+#: gui/launcher.cpp:600
msgctxt "lowres"
msgid "~E~dit Game..."
msgstr "~R~ediger spill..."
-#: gui/launcher.cpp:578
+#: gui/launcher.cpp:602
msgctxt "lowres"
msgid "~R~emove Game"
msgstr "~F~jern spill"
-#: gui/launcher.cpp:586
+#: gui/launcher.cpp:610
msgid "Search in game list"
msgstr "Søk i spilliste"
-#: gui/launcher.cpp:590 gui/launcher.cpp:1102
+#: gui/launcher.cpp:614 gui/launcher.cpp:1126
msgid "Search:"
msgstr "Søk:"
-#: gui/launcher.cpp:593 gui/options.cpp:826
-msgid "Clear value"
-msgstr "Tøm verdi"
-
-#: gui/launcher.cpp:615 engines/dialogs.cpp:114 engines/mohawk/myst.cpp:255
+#: gui/launcher.cpp:639 engines/dialogs.cpp:114 engines/mohawk/myst.cpp:255
#: engines/mohawk/riven.cpp:716 engines/cruise/menu.cpp:216
msgid "Load game:"
msgstr "Åpne spill:"
-#: gui/launcher.cpp:615 engines/dialogs.cpp:114 engines/scumm/dialogs.cpp:188
+#: gui/launcher.cpp:639 engines/dialogs.cpp:114 engines/scumm/dialogs.cpp:188
#: engines/mohawk/myst.cpp:255 engines/mohawk/riven.cpp:716
#: engines/cruise/menu.cpp:216 backends/platform/wince/CEActionsPocket.cpp:267
#: backends/platform/wince/CEActionsSmartphone.cpp:231
msgid "Load"
msgstr "Åpne"
-#: gui/launcher.cpp:723
+#: gui/launcher.cpp:747
msgid ""
"Do you really want to run the mass game detector? This could potentially add "
"a huge number of games."
@@ -454,7 +458,7 @@ msgstr ""
"Vil du virkelig kjøre flerspill-finneren? Dette kan potensielt legge til et "
"stort antall spill."
-#: gui/launcher.cpp:724 gui/launcher.cpp:872
+#: gui/launcher.cpp:748 gui/launcher.cpp:896
#: backends/events/symbiansdl/symbiansdl-events.cpp:184
#: backends/platform/wince/CEActionsPocket.cpp:326
#: backends/platform/wince/CEActionsSmartphone.cpp:287
@@ -462,7 +466,7 @@ msgstr ""
msgid "Yes"
msgstr "Ja"
-#: gui/launcher.cpp:724 gui/launcher.cpp:872
+#: gui/launcher.cpp:748 gui/launcher.cpp:896
#: backends/events/symbiansdl/symbiansdl-events.cpp:184
#: backends/platform/wince/CEActionsPocket.cpp:326
#: backends/platform/wince/CEActionsSmartphone.cpp:287
@@ -470,37 +474,37 @@ msgstr "Ja"
msgid "No"
msgstr "Nei"
-#: gui/launcher.cpp:772
+#: gui/launcher.cpp:796
msgid "ScummVM couldn't open the specified directory!"
msgstr "ScummVM kunne ikke åpne den valgte mappen!"
-#: gui/launcher.cpp:784
+#: gui/launcher.cpp:808
msgid "ScummVM could not find any game in the specified directory!"
msgstr "ScummVM kunne ikke finne noe spill i den valgte mappen!"
-#: gui/launcher.cpp:798
+#: gui/launcher.cpp:822
msgid "Pick the game:"
msgstr "Velg spill:"
-#: gui/launcher.cpp:872
+#: gui/launcher.cpp:896
msgid "Do you really want to remove this game configuration?"
msgstr "Vil du virkelig fjerne denne spillkonfigurasjonen?"
-#: gui/launcher.cpp:936
+#: gui/launcher.cpp:960
msgid "This game does not support loading games from the launcher."
msgstr "Dette spillet støtter ikke lasting av spill fra oppstarteren."
-#: gui/launcher.cpp:940
+#: gui/launcher.cpp:964
msgid "ScummVM could not find any engine capable of running the selected game!"
msgstr ""
"ScummVM kunne ikke finne noen motor som kunne kjøre det valgte spillet!"
-#: gui/launcher.cpp:1054
+#: gui/launcher.cpp:1078
msgctxt "lowres"
msgid "Mass Add..."
msgstr "Legg til flere..."
-#: gui/launcher.cpp:1054
+#: gui/launcher.cpp:1078
msgid "Mass Add..."
msgstr "Legg til flere..."
@@ -527,141 +531,141 @@ msgstr "Sjekket %d mapper ..."
msgid "Discovered %d new games, ignored %d previously added games ..."
msgstr "Fant %d nye spill ..."
-#: gui/options.cpp:72
+#: gui/options.cpp:78
msgid "Never"
msgstr "Aldri"
-#: gui/options.cpp:72
+#: gui/options.cpp:78
msgid "every 5 mins"
msgstr "hvert 5. min"
-#: gui/options.cpp:72
+#: gui/options.cpp:78
msgid "every 10 mins"
msgstr "hvert 10. min"
-#: gui/options.cpp:72
+#: gui/options.cpp:78
msgid "every 15 mins"
msgstr "hvert 15. min"
-#: gui/options.cpp:72
+#: gui/options.cpp:78
msgid "every 30 mins"
msgstr "hvert 30. min"
-#: gui/options.cpp:74
+#: gui/options.cpp:80
msgid "8 kHz"
msgstr "8 kHz"
-#: gui/options.cpp:74
+#: gui/options.cpp:80
msgid "11kHz"
msgstr "11kHz"
-#: gui/options.cpp:74
+#: gui/options.cpp:80
msgid "22 kHz"
msgstr "22 kHz"
-#: gui/options.cpp:74
+#: gui/options.cpp:80
msgid "44 kHz"
msgstr "44 kHz"
-#: gui/options.cpp:74
+#: gui/options.cpp:80
msgid "48 kHz"
msgstr "48 kHz"
-#: gui/options.cpp:236 gui/options.cpp:464 gui/options.cpp:559
-#: gui/options.cpp:625 gui/options.cpp:825
+#: gui/options.cpp:257 gui/options.cpp:485 gui/options.cpp:586
+#: gui/options.cpp:659 gui/options.cpp:868
msgctxt "soundfont"
msgid "None"
msgstr "Ingen"
-#: gui/options.cpp:372
+#: gui/options.cpp:393
msgid "Failed to apply some of the graphic options changes:"
msgstr ""
-#: gui/options.cpp:384
+#: gui/options.cpp:405
msgid "the video mode could not be changed."
msgstr ""
-#: gui/options.cpp:390
+#: gui/options.cpp:411
msgid "the fullscreen setting could not be changed"
msgstr ""
-#: gui/options.cpp:396
+#: gui/options.cpp:417
msgid "the aspect ratio setting could not be changed"
msgstr ""
-#: gui/options.cpp:705
+#: gui/options.cpp:742
msgid "Graphics mode:"
msgstr "Grafikkmodus:"
-#: gui/options.cpp:716
+#: gui/options.cpp:756
msgid "Render mode:"
msgstr "Tegnemodus:"
-#: gui/options.cpp:716 gui/options.cpp:717
+#: gui/options.cpp:756 gui/options.cpp:757
msgid "Special dithering modes supported by some games"
msgstr "Spesiel dithering-modus støttet av enkelte spill"
-#: gui/options.cpp:726
+#: gui/options.cpp:768
#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2248
-#: backends/graphics/openglsdl/openglsdl-graphics.cpp:476
+#: backends/graphics/openglsdl/openglsdl-graphics.cpp:472
msgid "Fullscreen mode"
msgstr "Fullskjermsmodus"
-#: gui/options.cpp:729
+#: gui/options.cpp:771
msgid "Aspect ratio correction"
msgstr "Aspekt-rate korrigering"
-#: gui/options.cpp:729
+#: gui/options.cpp:771
msgid "Correct aspect ratio for 320x200 games"
msgstr "Korriger aspekt-rate for 320x200-spill"
-#: gui/options.cpp:730
+#: gui/options.cpp:772
msgid "EGA undithering"
msgstr "EGA av-dithering"
-#: gui/options.cpp:730
+#: gui/options.cpp:772
msgid "Enable undithering in EGA games that support it"
msgstr "Slår av dithering i EGA-spill som støtter det."
-#: gui/options.cpp:738
+#: gui/options.cpp:780
msgid "Preferred Device:"
msgstr "Foretrukket enhet:"
-#: gui/options.cpp:738
+#: gui/options.cpp:780
msgid "Music Device:"
msgstr "Musikkenhet:"
-#: gui/options.cpp:738 gui/options.cpp:740
+#: gui/options.cpp:780 gui/options.cpp:782
msgid "Specifies preferred sound device or sound card emulator"
msgstr "Velger foretrukket lydenhet eller lydkort-emulator"
-#: gui/options.cpp:738 gui/options.cpp:740 gui/options.cpp:741
+#: gui/options.cpp:780 gui/options.cpp:782 gui/options.cpp:783
msgid "Specifies output sound device or sound card emulator"
msgstr "Velger ut-lydenhet eller lydkortemulator"
-#: gui/options.cpp:740
+#: gui/options.cpp:782
msgctxt "lowres"
msgid "Preferred Dev.:"
msgstr "Foretrukket enh.:"
-#: gui/options.cpp:740
+#: gui/options.cpp:782
msgctxt "lowres"
msgid "Music Device:"
msgstr "Musikkenhet:"
-#: gui/options.cpp:766
+#: gui/options.cpp:809
msgid "AdLib emulator:"
msgstr "AdLib-emulator:"
-#: gui/options.cpp:766 gui/options.cpp:767
+#: gui/options.cpp:809 gui/options.cpp:810
msgid "AdLib is used for music in many games"
msgstr "AdLib brukes til musikk i mange spill"
-#: gui/options.cpp:777
+#: gui/options.cpp:820
msgid "Output rate:"
msgstr "Utrate:"
-#: gui/options.cpp:777 gui/options.cpp:778
+#: gui/options.cpp:820 gui/options.cpp:821
msgid ""
"Higher value specifies better sound quality but may be not supported by your "
"soundcard"
@@ -669,60 +673,60 @@ msgstr ""
"Høyere verdier gir bedre lydkvalitet, men støttes kanskje ikke av ditt "
"lydkort "
-#: gui/options.cpp:788
+#: gui/options.cpp:831
msgid "GM Device:"
msgstr "GM-enhet:"
-#: gui/options.cpp:788
+#: gui/options.cpp:831
msgid "Specifies default sound device for General MIDI output"
msgstr "Velger standard lydenhet for General MIDI-utdata"
-#: gui/options.cpp:799
+#: gui/options.cpp:842
msgid "Don't use General MIDI music"
msgstr "Ikke bruk General MIDI-musikk"
-#: gui/options.cpp:810 gui/options.cpp:871
+#: gui/options.cpp:853 gui/options.cpp:915
msgid "Use first available device"
msgstr "Bruk første tilgjengelige enhet"
-#: gui/options.cpp:822
+#: gui/options.cpp:865
msgid "SoundFont:"
msgstr "SoundFont:"
-#: gui/options.cpp:822 gui/options.cpp:824 gui/options.cpp:825
+#: gui/options.cpp:865 gui/options.cpp:867 gui/options.cpp:868
msgid "SoundFont is supported by some audio cards, Fluidsynth and Timidity"
msgstr "SoundFont støttes ikke av enkelte lydkort, FluidSynth og Timidity"
-#: gui/options.cpp:824
+#: gui/options.cpp:867
msgctxt "lowres"
msgid "SoundFont:"
msgstr "SoundFont:"
-#: gui/options.cpp:829
+#: gui/options.cpp:873
msgid "Mixed AdLib/MIDI mode"
msgstr "Mikset AdLib/MIDI-modus"
-#: gui/options.cpp:829
+#: gui/options.cpp:873
msgid "Use both MIDI and AdLib sound generation"
msgstr "Bruk både MIDI- og AdLib- lydgenerering"
-#: gui/options.cpp:832
+#: gui/options.cpp:876
msgid "MIDI gain:"
msgstr "MIDI gain:"
-#: gui/options.cpp:842
+#: gui/options.cpp:886
msgid "MT-32 Device:"
msgstr "MT-32 Enhet:"
-#: gui/options.cpp:842
+#: gui/options.cpp:886
msgid "Specifies default sound device for Roland MT-32/LAPC1/CM32l/CM64 output"
msgstr "Velger standard lydenhet for Roland MT-32/LAPC1/CM32I/CM64-avspilling"
-#: gui/options.cpp:847
+#: gui/options.cpp:891
msgid "True Roland MT-32 (disable GM emulation)"
msgstr "Ekte Roland MT-32 (deaktiver GM-emulering)"
-#: gui/options.cpp:847 gui/options.cpp:849
+#: gui/options.cpp:891 gui/options.cpp:893
msgid ""
"Check if you want to use your real hardware Roland-compatible sound device "
"connected to your computer"
@@ -730,191 +734,191 @@ msgstr ""
"Velg hvis du har et ekte Roland-kompatible lydkort tilkoblet maskinen, og "
"vil bruke dette."
-#: gui/options.cpp:849
+#: gui/options.cpp:893
msgctxt "lowres"
msgid "True Roland MT-32 (no GM emulation)"
msgstr "Ekte Roland MT-32 (deaktiver GM-emulering)"
-#: gui/options.cpp:852
+#: gui/options.cpp:896
msgid "Enable Roland GS Mode"
msgstr "Aktiver Roland GS-modus"
-#: gui/options.cpp:852
+#: gui/options.cpp:896
msgid "Turns off General MIDI mapping for games with Roland MT-32 soundtrack"
msgstr "Slå av General MIDI-kobling for spill som har Roland MT-32-lydspor"
-#: gui/options.cpp:861
+#: gui/options.cpp:905
msgid "Don't use Roland MT-32 music"
msgstr "Ikke bruk Roland MT-32-musikk"
-#: gui/options.cpp:888
+#: gui/options.cpp:932
msgid "Text and Speech:"
msgstr "Tekst og Tale:"
-#: gui/options.cpp:892 gui/options.cpp:902
+#: gui/options.cpp:936 gui/options.cpp:946
msgid "Speech"
msgstr "Tale"
-#: gui/options.cpp:893 gui/options.cpp:903
+#: gui/options.cpp:937 gui/options.cpp:947
msgid "Subtitles"
msgstr "Undertekster"
-#: gui/options.cpp:894
+#: gui/options.cpp:938
msgid "Both"
msgstr "Begge"
-#: gui/options.cpp:896
+#: gui/options.cpp:940
msgid "Subtitle speed:"
msgstr "Teksthastighet:"
-#: gui/options.cpp:898
+#: gui/options.cpp:942
msgctxt "lowres"
msgid "Text and Speech:"
msgstr "Tekst og Tale:"
-#: gui/options.cpp:902
+#: gui/options.cpp:946
msgid "Spch"
msgstr "Tale"
-#: gui/options.cpp:903
+#: gui/options.cpp:947
msgid "Subs"
msgstr "Tekst"
-#: gui/options.cpp:904
+#: gui/options.cpp:948
msgctxt "lowres"
msgid "Both"
msgstr "Begge"
-#: gui/options.cpp:904
+#: gui/options.cpp:948
msgid "Show subtitles and play speech"
msgstr "Vis undertekster, og spill av tale"
-#: gui/options.cpp:906
+#: gui/options.cpp:950
msgctxt "lowres"
msgid "Subtitle speed:"
msgstr "Underteksthastighet:"
-#: gui/options.cpp:922
+#: gui/options.cpp:966
msgid "Music volume:"
msgstr "Musikkvolum:"
-#: gui/options.cpp:924
+#: gui/options.cpp:968
msgctxt "lowres"
msgid "Music volume:"
msgstr "Musikkvolum:"
-#: gui/options.cpp:931
+#: gui/options.cpp:975
msgid "Mute All"
msgstr "Demp alle"
-#: gui/options.cpp:934
+#: gui/options.cpp:978
msgid "SFX volume:"
msgstr "Lydeffektvolum:"
-#: gui/options.cpp:934 gui/options.cpp:936 gui/options.cpp:937
+#: gui/options.cpp:978 gui/options.cpp:980 gui/options.cpp:981
msgid "Special sound effects volume"
msgstr "Volum for spesielle lydeffekter"
-#: gui/options.cpp:936
+#: gui/options.cpp:980
msgctxt "lowres"
msgid "SFX volume:"
msgstr "Lydeffektvolum:"
-#: gui/options.cpp:944
+#: gui/options.cpp:988
msgid "Speech volume:"
msgstr "Talevolum:"
-#: gui/options.cpp:946
+#: gui/options.cpp:990
msgctxt "lowres"
msgid "Speech volume:"
msgstr "Talevolum:"
-#: gui/options.cpp:1085
+#: gui/options.cpp:1156
msgid "Theme Path:"
msgstr "Temasti:"
-#: gui/options.cpp:1087
+#: gui/options.cpp:1158
msgctxt "lowres"
msgid "Theme Path:"
msgstr "Temasti:"
-#: gui/options.cpp:1091 gui/options.cpp:1093 gui/options.cpp:1094
+#: gui/options.cpp:1164 gui/options.cpp:1166 gui/options.cpp:1167
msgid "Specifies path to additional data used by all games or ScummVM"
msgstr "Velger sti for ytterligere data brukt av alle spill eller ScummVM"
-#: gui/options.cpp:1098
+#: gui/options.cpp:1173
msgid "Plugins Path:"
msgstr "Pluginsti:"
-#: gui/options.cpp:1100
+#: gui/options.cpp:1175
msgctxt "lowres"
msgid "Plugins Path:"
msgstr "Pluginsti:"
-#: gui/options.cpp:1109
+#: gui/options.cpp:1184
msgid "Misc"
msgstr "Div"
-#: gui/options.cpp:1111
+#: gui/options.cpp:1186
msgctxt "lowres"
msgid "Misc"
msgstr "Div"
-#: gui/options.cpp:1113
+#: gui/options.cpp:1188
msgid "Theme:"
msgstr "Tema:"
-#: gui/options.cpp:1117
+#: gui/options.cpp:1192
msgid "GUI Renderer:"
msgstr "GUI-tegner:"
-#: gui/options.cpp:1129
+#: gui/options.cpp:1204
msgid "Autosave:"
msgstr "Autolagre:"
-#: gui/options.cpp:1131
+#: gui/options.cpp:1206
msgctxt "lowres"
msgid "Autosave:"
msgstr "Autolagre:"
-#: gui/options.cpp:1139
+#: gui/options.cpp:1214
msgid "Keys"
msgstr "Taster"
-#: gui/options.cpp:1146
+#: gui/options.cpp:1221
msgid "GUI Language:"
msgstr "GUI-språk:"
-#: gui/options.cpp:1146
+#: gui/options.cpp:1221
msgid "Language of ScummVM GUI"
msgstr "Språk i ScummVM-GUIet"
-#: gui/options.cpp:1295
+#: gui/options.cpp:1372
#, fuzzy
msgid "You have to restart ScummVM before your changes will take effect."
msgstr "Du må omstarte ScummVM for at endringene skal skje. "
-#: gui/options.cpp:1308
+#: gui/options.cpp:1385
msgid "Select directory for savegames"
msgstr "Velg mappe for lagrede spill"
-#: gui/options.cpp:1315
+#: gui/options.cpp:1392
msgid "The chosen directory cannot be written to. Please select another one."
msgstr "Den valgte mappen kan ikke skrives til. Vennligst velg en annen."
-#: gui/options.cpp:1324
+#: gui/options.cpp:1401
msgid "Select directory for GUI themes"
msgstr "Velg mappe for GUI-temaer"
-#: gui/options.cpp:1334
+#: gui/options.cpp:1411
msgid "Select directory for extra files"
msgstr "Velg mappe for ytterligere filer"
-#: gui/options.cpp:1345
+#: gui/options.cpp:1422
msgid "Select directory for plugins"
msgstr "Velg mappe for plugins"
-#: gui/options.cpp:1389
+#: gui/options.cpp:1475
msgid ""
"The theme you selected does not support your current language. If you want "
"to use this theme you need to switch to another language first."
@@ -962,60 +966,64 @@ msgstr "Ikke navngitt spilltilstand"
msgid "Select a Theme"
msgstr "Velg et tema"
-#: gui/ThemeEngine.cpp:328
+#: gui/ThemeEngine.cpp:333
msgid "Disabled GFX"
msgstr "Deaktivert GFX"
-#: gui/ThemeEngine.cpp:328
+#: gui/ThemeEngine.cpp:333
msgctxt "lowres"
msgid "Disabled GFX"
msgstr "Deaktivert GFX"
-#: gui/ThemeEngine.cpp:329
+#: gui/ThemeEngine.cpp:334
msgid "Standard Renderer (16bpp)"
msgstr "Standard Tegner (16bpp)"
-#: gui/ThemeEngine.cpp:329
+#: gui/ThemeEngine.cpp:334
msgid "Standard (16bpp)"
msgstr "Standard (16bpp)"
-#: gui/ThemeEngine.cpp:331
+#: gui/ThemeEngine.cpp:336
msgid "Antialiased Renderer (16bpp)"
msgstr "Antialiased Tegner (16bpp)"
-#: gui/ThemeEngine.cpp:331
+#: gui/ThemeEngine.cpp:336
msgid "Antialiased (16bpp)"
msgstr "Antialiased (16bpp)"
+#: gui/widget.cpp:312 gui/widget.cpp:314 gui/widget.cpp:320 gui/widget.cpp:322
+msgid "Clear value"
+msgstr "Tøm verdi"
+
#: base/main.cpp:203
#, c-format
msgid "Engine does not support debug level '%s'"
msgstr "Motoren støtter ikke debug-nivå '%s'"
-#: base/main.cpp:271
+#: base/main.cpp:275
msgid "Menu"
msgstr "Meny"
-#: base/main.cpp:274 backends/platform/symbian/src/SymbianActions.cpp:45
+#: base/main.cpp:278 backends/platform/symbian/src/SymbianActions.cpp:45
#: backends/platform/wince/CEActionsPocket.cpp:45
#: backends/platform/wince/CEActionsSmartphone.cpp:46
msgid "Skip"
msgstr "Hopp over"
-#: base/main.cpp:277 backends/platform/symbian/src/SymbianActions.cpp:50
+#: base/main.cpp:281 backends/platform/symbian/src/SymbianActions.cpp:50
#: backends/platform/wince/CEActionsPocket.cpp:42
msgid "Pause"
msgstr "Pause"
-#: base/main.cpp:280
+#: base/main.cpp:284
msgid "Skip line"
msgstr "Hopp over linje"
-#: base/main.cpp:439
+#: base/main.cpp:455
msgid "Error running game:"
msgstr "Problem ved kjøring av spill:"
-#: base/main.cpp:463
+#: base/main.cpp:479
msgid "Could not find any engine capable of running the selected game"
msgstr "Kunne ikke finne noen motor som kunne kjøre det valgte spillet"
@@ -1083,25 +1091,6 @@ msgstr ""
msgid "Unknown error"
msgstr "Ukjent feil"
-#. I18N: Hercules is graphics card name
-#: common/util.cpp:275
-msgid "Hercules Green"
-msgstr "Hercules Grønn"
-
-#: common/util.cpp:276
-msgid "Hercules Amber"
-msgstr "Hercules Oransje"
-
-#: common/util.cpp:283
-msgctxt "lowres"
-msgid "Hercules Green"
-msgstr "Hercules Grønn"
-
-#: common/util.cpp:284
-msgctxt "lowres"
-msgid "Hercules Amber"
-msgstr "Hercules Oransje"
-
#: engines/advancedDetector.cpp:296
#, c-format
msgid "The game in '%s' seems to be unknown."
@@ -1149,12 +1138,12 @@ msgid "~R~eturn to Launcher"
msgstr "~T~ilbake til oppstarter"
#: engines/dialogs.cpp:116 engines/cruise/menu.cpp:214
-#: engines/sci/engine/kfile.cpp:578
+#: engines/sci/engine/kfile.cpp:566
msgid "Save game:"
msgstr "Lagret spill:"
#: engines/dialogs.cpp:116 engines/scumm/dialogs.cpp:187
-#: engines/cruise/menu.cpp:214 engines/sci/engine/kfile.cpp:578
+#: engines/cruise/menu.cpp:214 engines/sci/engine/kfile.cpp:566
#: backends/platform/symbian/src/SymbianActions.cpp:44
#: backends/platform/wince/CEActionsPocket.cpp:43
#: backends/platform/wince/CEActionsPocket.cpp:267
@@ -1170,39 +1159,46 @@ msgid ""
"further assistance."
msgstr ""
-#: engines/dialogs.cpp:316 engines/mohawk/dialogs.cpp:109
+#: engines/dialogs.cpp:243
+#, c-format
+msgid ""
+"Gamestate save failed (%s)! Please consult the README for basic information, "
+"and for instructions on how to obtain further assistance."
+msgstr ""
+
+#: engines/dialogs.cpp:321 engines/mohawk/dialogs.cpp:109
#: engines/mohawk/dialogs.cpp:174
msgid "~O~K"
msgstr "~O~K"
-#: engines/dialogs.cpp:317 engines/mohawk/dialogs.cpp:110
+#: engines/dialogs.cpp:322 engines/mohawk/dialogs.cpp:110
#: engines/mohawk/dialogs.cpp:175
msgid "~C~ancel"
msgstr "~A~vbryt"
-#: engines/dialogs.cpp:320
+#: engines/dialogs.cpp:325
msgid "~K~eys"
msgstr "~T~aster"
-#: engines/engine.cpp:233
+#: engines/engine.cpp:235
msgid "Could not initialize color format."
msgstr ""
-#: engines/engine.cpp:241
+#: engines/engine.cpp:243
#, fuzzy
msgid "Could not switch to video mode: '"
msgstr "Nåværende videomodus:"
-#: engines/engine.cpp:250
+#: engines/engine.cpp:252
#, fuzzy
msgid "Could not apply aspect ratio setting."
msgstr "Veksle aspekt-rate korrigering"
-#: engines/engine.cpp:255
+#: engines/engine.cpp:257
msgid "Could not apply fullscreen setting."
msgstr ""
-#: engines/engine.cpp:355
+#: engines/engine.cpp:357
msgid ""
"You appear to be playing this game directly\n"
"from the CD. This is known to cause problems,\n"
@@ -1211,7 +1207,7 @@ msgid ""
"See the README file for details."
msgstr ""
-#: engines/engine.cpp:366
+#: engines/engine.cpp:368
msgid ""
"This game has audio tracks in its disk. These\n"
"tracks need to be ripped from the disk using\n"
@@ -1220,14 +1216,21 @@ msgid ""
"See the README file for details."
msgstr ""
-#: engines/engine.cpp:433
+#: engines/engine.cpp:426
+#, c-format
+msgid ""
+"Gamestate load failed (%s)! Please consult the README for basic information, "
+"and for instructions on how to obtain further assistance."
+msgstr ""
+
+#: engines/engine.cpp:439
msgid ""
"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."
msgstr ""
-#: engines/engine.cpp:436
+#: engines/engine.cpp:442
msgid "Start anyway"
msgstr ""
@@ -1273,7 +1276,7 @@ msgstr ""
#: backends/platform/symbian/src/SymbianActions.cpp:52
#: backends/platform/wince/CEActionsPocket.cpp:44
#: backends/platform/wince/CEActionsSmartphone.cpp:52
-#: backends/events/default/default-events.cpp:244
+#: backends/events/default/default-events.cpp:213
msgid "Quit"
msgstr "Avslutt"
@@ -1352,6 +1355,27 @@ msgctxt "lowres"
msgid "Speech & Subs"
msgstr "Tale"
+#: engines/scumm/dialogs.cpp:653
+msgid "Select a Proficiency Level."
+msgstr ""
+
+#: engines/scumm/dialogs.cpp:655
+msgid "Refer to your Loom(TM) manual for help."
+msgstr ""
+
+#: engines/scumm/dialogs.cpp:658
+#, fuzzy
+msgid "Standard"
+msgstr "Standard (16bpp)"
+
+#: engines/scumm/dialogs.cpp:659
+msgid "Practice"
+msgstr ""
+
+#: engines/scumm/dialogs.cpp:660
+msgid "Expert"
+msgstr ""
+
#: engines/scumm/help.cpp:73
msgid "Common keyboard commands:"
msgstr "Vanlige tastaturkommandoer:"
@@ -1866,14 +1890,14 @@ msgstr "Fly til høyre"
msgid "Fly to lower right"
msgstr "Fly til nedre høyre"
-#: engines/scumm/scumm.cpp:1774
+#: engines/scumm/scumm.cpp:1773
#, c-format
msgid ""
"Native MIDI support requires the Roland Upgrade from LucasArts,\n"
"but %s is missing. Using AdLib instead."
msgstr ""
-#: engines/scumm/scumm.cpp:2264 engines/agos/saveload.cpp:189
+#: engines/scumm/scumm.cpp:2271 engines/agos/saveload.cpp:189
#, c-format
msgid ""
"Failed to save game state to file:\n"
@@ -1884,7 +1908,7 @@ msgstr ""
"\n"
"%s"
-#: engines/scumm/scumm.cpp:2271 engines/agos/saveload.cpp:154
+#: engines/scumm/scumm.cpp:2278 engines/agos/saveload.cpp:154
#, c-format
msgid ""
"Failed to load game state from file:\n"
@@ -1895,7 +1919,7 @@ msgstr ""
"\n"
"%s"
-#: engines/scumm/scumm.cpp:2283 engines/agos/saveload.cpp:197
+#: engines/scumm/scumm.cpp:2290 engines/agos/saveload.cpp:197
#, c-format
msgid ""
"Successfully saved game state in file:\n"
@@ -1906,7 +1930,7 @@ msgstr ""
"\n"
"%s"
-#: engines/scumm/scumm.cpp:2498
+#: engines/scumm/scumm.cpp:2505
msgid ""
"Usually, Maniac Mansion would start now. But ScummVM doesn't do that yet. To "
"play it, go to 'Add Game' in the ScummVM start menu and select the 'Maniac' "
@@ -1943,11 +1967,11 @@ msgstr "ScummVM Hovedmeny"
msgid "~W~ater Effect Enabled"
msgstr "~V~anneffekt aktivert"
-#: engines/sci/engine/kfile.cpp:685
+#: engines/sci/engine/kfile.cpp:673
msgid "Restore game:"
msgstr "Gjennopprett spill:"
-#: engines/sci/engine/kfile.cpp:685
+#: engines/sci/engine/kfile.cpp:673
msgid "Restore"
msgstr "Gjenopprett"
@@ -1957,7 +1981,7 @@ msgid "Cutscene file '%s' not found!"
msgstr ""
#: engines/gob/inter_playtoons.cpp:256 engines/gob/inter_v2.cpp:1283
-#: engines/tinsel/saveload.cpp:482
+#: engines/tinsel/saveload.cpp:502
#, fuzzy
msgid "Failed to load game state from file."
msgstr ""
@@ -1965,7 +1989,7 @@ msgstr ""
"\n"
"%s"
-#: engines/gob/inter_v2.cpp:1353 engines/tinsel/saveload.cpp:560
+#: engines/gob/inter_v2.cpp:1353 engines/tinsel/saveload.cpp:515
#, fuzzy
msgid "Failed to save game state to file."
msgstr ""
@@ -1989,6 +2013,60 @@ msgstr ""
"\n"
"%s"
+#: engines/kyra/lol.cpp:478
+msgid "Attack 1"
+msgstr ""
+
+#: engines/kyra/lol.cpp:479
+msgid "Attack 2"
+msgstr ""
+
+#: engines/kyra/lol.cpp:480
+msgid "Attack 3"
+msgstr ""
+
+#: engines/kyra/lol.cpp:481
+msgid "Move Forward"
+msgstr ""
+
+#: engines/kyra/lol.cpp:482
+msgid "Move Back"
+msgstr ""
+
+#: engines/kyra/lol.cpp:483
+msgid "Slide Left"
+msgstr ""
+
+#: engines/kyra/lol.cpp:484
+#, fuzzy
+msgid "Slide Right"
+msgstr "Høyre"
+
+#: engines/kyra/lol.cpp:485
+#, fuzzy
+msgid "Turn Left"
+msgstr "Slå av"
+
+#: engines/kyra/lol.cpp:486
+#, fuzzy
+msgid "Turn Right"
+msgstr "Peker høyre"
+
+#: engines/kyra/lol.cpp:487
+#, fuzzy
+msgid "Rest"
+msgstr "Gjenopprett"
+
+#: engines/kyra/lol.cpp:488
+#, fuzzy
+msgid "Options"
+msgstr "~V~alg"
+
+#: engines/kyra/lol.cpp:489
+#, fuzzy
+msgid "Choose Spell"
+msgstr "Velg"
+
#: engines/kyra/sound_midi.cpp:475
msgid ""
"You appear to be using a General MIDI device,\n"
@@ -1998,11 +2076,6 @@ msgid ""
"that a few tracks will not be correctly played."
msgstr ""
-#: engines/m4/m4_menus.cpp:138
-#, fuzzy
-msgid "Save game failed!"
-msgstr "Lagret spill:"
-
#: engines/sky/compact.cpp:130
msgid ""
"Unable to find \"sky.cpt\" file!\n"
@@ -2015,15 +2088,20 @@ msgid ""
"Please (re)download it from www.scummvm.org"
msgstr ""
-#: engines/sword1/animation.cpp:344 engines/sword2/animation.cpp:379
+#: engines/sword1/animation.cpp:539
+#, c-format
+msgid "PSX stream cutscene '%s' cannot be played in paletted mode"
+msgstr ""
+
+#: engines/sword1/animation.cpp:560 engines/sword2/animation.cpp:455
msgid "DXA cutscenes found but ScummVM has been built without zlib support"
msgstr ""
-#: engines/sword1/animation.cpp:354 engines/sword2/animation.cpp:389
+#: engines/sword1/animation.cpp:570 engines/sword2/animation.cpp:465
msgid "MPEG2 cutscenes are no longer supported"
msgstr ""
-#: engines/sword1/animation.cpp:359 engines/sword2/animation.cpp:397
+#: engines/sword1/animation.cpp:576 engines/sword2/animation.cpp:473
#, c-format
msgid "Cutscene '%s' not found"
msgstr ""
@@ -2058,6 +2136,11 @@ msgstr ""
msgid "This is the end of the Broken Sword 1 Demo"
msgstr ""
+#: engines/sword2/animation.cpp:435
+msgid ""
+"PSX cutscenes found but ScummVM has been built without RGB color support"
+msgstr ""
+
#: engines/parallaction/saveload.cpp:133
#, c-format
msgid ""
@@ -2105,33 +2188,33 @@ msgstr "MAME OPL emulator"
msgid "DOSBox OPL emulator"
msgstr "DOSBox OPL emulator"
-#: audio/mididrv.cpp:205
+#: audio/mididrv.cpp:209
#, c-format
msgid ""
"The selected audio device '%s' was not found (e.g. might be turned off or "
"disconnected)."
msgstr ""
-#: audio/mididrv.cpp:205 audio/mididrv.cpp:217 audio/mididrv.cpp:253
-#: audio/mididrv.cpp:268
+#: audio/mididrv.cpp:209 audio/mididrv.cpp:221 audio/mididrv.cpp:257
+#: audio/mididrv.cpp:272
msgid "Attempting to fall back to the next available device..."
msgstr ""
-#: audio/mididrv.cpp:217
+#: audio/mididrv.cpp:221
#, c-format
msgid ""
"The selected audio device '%s' cannot be used. See log file for more "
"information."
msgstr ""
-#: audio/mididrv.cpp:253
+#: audio/mididrv.cpp:257
#, c-format
msgid ""
"The preferred audio device '%s' was not found (e.g. might be turned off or "
"disconnected)."
msgstr ""
-#: audio/mididrv.cpp:268
+#: audio/mididrv.cpp:272
#, c-format
msgid ""
"The preferred audio device '%s' cannot be used. See log file for more "
@@ -2146,7 +2229,7 @@ msgstr "Ingen musikk"
msgid "Amiga Audio Emulator"
msgstr "Amiga Lydemulator"
-#: audio/softsynth/adlib.cpp:1594
+#: audio/softsynth/adlib.cpp:1593
msgid "AdLib Emulator"
msgstr "AdLib Emulator"
@@ -2158,12 +2241,12 @@ msgstr "Apple II GS Emulator (IKKE IMPLEMENTERT)"
msgid "C64 Audio Emulator"
msgstr "C64 Lydemulator"
-#: audio/softsynth/mt32.cpp:329
+#: audio/softsynth/mt32.cpp:293
#, fuzzy
msgid "Initializing MT-32 Emulator"
msgstr "Initialiserer MT-32-Emulator"
-#: audio/softsynth/mt32.cpp:543
+#: audio/softsynth/mt32.cpp:512
msgid "MT-32 Emulator"
msgstr "MT-32 Emulator"
@@ -2179,15 +2262,24 @@ msgstr "IBM PCjr Emulator"
msgid "Keymap:"
msgstr "Tastkobling:"
-#: backends/keymapper/remap-dialog.cpp:64
+#: backends/keymapper/remap-dialog.cpp:66
+#, fuzzy
+msgid " (Effective)"
+msgstr " (Aktiv)"
+
+#: backends/keymapper/remap-dialog.cpp:106
msgid " (Active)"
msgstr " (Aktiv)"
-#: backends/keymapper/remap-dialog.cpp:98
+#: backends/keymapper/remap-dialog.cpp:106
+msgid " (Blocked)"
+msgstr ""
+
+#: backends/keymapper/remap-dialog.cpp:119
msgid " (Global)"
msgstr " (Global)"
-#: backends/keymapper/remap-dialog.cpp:108
+#: backends/keymapper/remap-dialog.cpp:127
msgid " (Game)"
msgstr " (Spill)"
@@ -2267,46 +2359,69 @@ msgstr "Høy lydkvalitet (tregere) (omstart)"
msgid "Disable power off"
msgstr "Deaktiver strømsparing"
-#: backends/platform/iphone/osys_events.cpp:338
+#: backends/platform/iphone/osys_events.cpp:301
#, fuzzy
msgid "Mouse-click-and-drag mode enabled."
msgstr "Touchpad-modus aktivert."
-#: backends/platform/iphone/osys_events.cpp:340
+#: backends/platform/iphone/osys_events.cpp:303
#, fuzzy
msgid "Mouse-click-and-drag mode disabled."
msgstr "Touchpad-modus deaktivert."
-#: backends/platform/iphone/osys_events.cpp:351
+#: backends/platform/iphone/osys_events.cpp:314
msgid "Touchpad mode enabled."
msgstr "Touchpad-modus aktivert."
-#: backends/platform/iphone/osys_events.cpp:353
+#: backends/platform/iphone/osys_events.cpp:316
msgid "Touchpad mode disabled."
msgstr "Touchpad-modus deaktivert."
-#: backends/platform/sdl/macosx/appmenu_osx.mm:67
+#: backends/platform/maemo/maemo.cpp:205
+msgid "Click Mode"
+msgstr ""
+
+#: backends/platform/maemo/maemo.cpp:211
+#: backends/platform/symbian/src/SymbianActions.cpp:42
+#: backends/platform/wince/CEActionsPocket.cpp:60
+#: backends/platform/wince/CEActionsSmartphone.cpp:43
+#: backends/platform/bada/form.cpp:281
+msgid "Left Click"
+msgstr "Venstreklikk"
+
+#: backends/platform/maemo/maemo.cpp:214
+#, fuzzy
+msgid "Middle Click"
+msgstr "Midtre venstre gjenstand"
+
+#: backends/platform/maemo/maemo.cpp:217
+#: backends/platform/symbian/src/SymbianActions.cpp:43
+#: backends/platform/wince/CEActionsSmartphone.cpp:44
+#: backends/platform/bada/form.cpp:273
+msgid "Right Click"
+msgstr "Høyreklikk"
+
+#: backends/platform/sdl/macosx/appmenu_osx.mm:78
#, fuzzy
msgid "Hide ScummVM"
-msgstr "Avslutt ScummVM"
+msgstr "Skjul ScummVM"
-#: backends/platform/sdl/macosx/appmenu_osx.mm:70
+#: backends/platform/sdl/macosx/appmenu_osx.mm:83
msgid "Hide Others"
-msgstr ""
+msgstr "Skjul andre"
-#: backends/platform/sdl/macosx/appmenu_osx.mm:74
+#: backends/platform/sdl/macosx/appmenu_osx.mm:88
msgid "Show All"
-msgstr ""
+msgstr "Vis alle"
-#: backends/platform/sdl/macosx/appmenu_osx.mm:92
-#: backends/platform/sdl/macosx/appmenu_osx.mm:99
-#, fuzzy
+#: backends/platform/sdl/macosx/appmenu_osx.mm:110
+#: backends/platform/sdl/macosx/appmenu_osx.mm:121
msgid "Window"
-msgstr "Windows MIDI"
+msgstr "Vindu"
-#: backends/platform/sdl/macosx/appmenu_osx.mm:95
+#: backends/platform/sdl/macosx/appmenu_osx.mm:115
msgid "Minimize"
-msgstr ""
+msgstr "Minimer"
#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:45
msgid "Normal (no scaling)"
@@ -2318,13 +2433,13 @@ msgid "Normal (no scaling)"
msgstr "Normal (ingen skalering)"
#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2147
-#: backends/graphics/openglsdl/openglsdl-graphics.cpp:537
+#: backends/graphics/openglsdl/openglsdl-graphics.cpp:533
#, fuzzy
msgid "Enabled aspect ratio correction"
msgstr "Veksle aspekt-rate korrigering"
#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2153
-#: backends/graphics/openglsdl/openglsdl-graphics.cpp:542
+#: backends/graphics/openglsdl/openglsdl-graphics.cpp:538
#, fuzzy
msgid "Disabled aspect ratio correction"
msgstr "Veksle aspekt-rate korrigering"
@@ -2335,7 +2450,7 @@ msgid "Active graphics filter:"
msgstr "Bytt grafikkfiltre"
#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2250
-#: backends/graphics/openglsdl/openglsdl-graphics.cpp:481
+#: backends/graphics/openglsdl/openglsdl-graphics.cpp:477
#, fuzzy
msgid "Windowed mode"
msgstr "Tegnemodus:"
@@ -2361,11 +2476,11 @@ msgstr "Nåværende videomodus:"
msgid "Current scale"
msgstr ""
-#: backends/graphics/openglsdl/openglsdl-graphics.cpp:562
+#: backends/graphics/openglsdl/openglsdl-graphics.cpp:558
msgid "Active filter mode: Linear"
msgstr ""
-#: backends/graphics/openglsdl/openglsdl-graphics.cpp:564
+#: backends/graphics/openglsdl/openglsdl-graphics.cpp:560
msgid "Active filter mode: Nearest"
msgstr ""
@@ -2389,19 +2504,6 @@ msgstr "Venstre"
msgid "Right"
msgstr "Høyre"
-#: backends/platform/symbian/src/SymbianActions.cpp:42
-#: backends/platform/wince/CEActionsPocket.cpp:60
-#: backends/platform/wince/CEActionsSmartphone.cpp:43
-#: backends/platform/bada/form.cpp:281
-msgid "Left Click"
-msgstr "Venstreklikk"
-
-#: backends/platform/symbian/src/SymbianActions.cpp:43
-#: backends/platform/wince/CEActionsSmartphone.cpp:44
-#: backends/platform/bada/form.cpp:273
-msgid "Right Click"
-msgstr "Høyreklikk"
-
#: backends/platform/symbian/src/SymbianActions.cpp:46
#: backends/platform/wince/CEActionsSmartphone.cpp:47
msgid "Zone"
@@ -2694,17 +2796,17 @@ msgstr ""
"Ikke glem å koble en tast til handlingen 'Skjul verktøylinje' for å se hele "
"inventaret"
-#: backends/events/default/default-events.cpp:222
+#: backends/events/default/default-events.cpp:191
#, fuzzy
msgid "Do you really want to return to the Launcher?"
msgstr "Vil du virkelig slette dette lagrede spillet?"
-#: backends/events/default/default-events.cpp:222
+#: backends/events/default/default-events.cpp:191
#, fuzzy
msgid "Launcher"
msgstr "Slå"
-#: backends/events/default/default-events.cpp:244
+#: backends/events/default/default-events.cpp:213
#, fuzzy
msgid "Do you really want to quit?"
msgstr "Vil du avslutte?"
@@ -2777,14 +2879,32 @@ msgstr "Vis tastatur"
msgid "Control Mouse"
msgstr ""
-#: backends/events/maemosdl/maemosdl-events.cpp:121
+#: backends/events/maemosdl/maemosdl-events.cpp:192
msgid "Clicking Enabled"
msgstr ""
-#: backends/events/maemosdl/maemosdl-events.cpp:121
+#: backends/events/maemosdl/maemosdl-events.cpp:192
msgid "Clicking Disabled"
msgstr ""
+#~ msgid "Hercules Green"
+#~ msgstr "Hercules Grønn"
+
+#~ msgid "Hercules Amber"
+#~ msgstr "Hercules Oransje"
+
+#~ msgctxt "lowres"
+#~ msgid "Hercules Green"
+#~ msgstr "Hercules Grønn"
+
+#~ msgctxt "lowres"
+#~ msgid "Hercules Amber"
+#~ msgstr "Hercules Oransje"
+
+#, fuzzy
+#~ msgid "Save game failed!"
+#~ msgstr "Lagret spill:"
+
#~ msgctxt "lowres"
#~ msgid "Add Game..."
#~ msgstr "Legg til spill..."
diff --git a/po/nn_NO.po b/po/nn_NO.po
index e7da5a8946..00dce83302 100644
--- a/po/nn_NO.po
+++ b/po/nn_NO.po
@@ -1,20 +1,20 @@
-# Norwegian (Nynorsk) translation for ScummVM.
-# Copyright (C) 2010 ScummVM Team
-# This file is distributed under the same license as the ScummVM package.
-# Einar Johan T. Sømåen <einarjohants@gmail.com>, 2010.
-#
+# Norwegian (Nynorsk) translation for ScummVM.
+# Copyright (C) 2010-2012 ScummVM Team
+# This file is distributed under the same license as the ScummVM package.
+# Einar Johan T. Sømåen <einarjohants@gmail.com>, 2010.
+#
msgid ""
msgstr ""
"Project-Id-Version: ScummVM 1.3.0svn\n"
"Report-Msgid-Bugs-To: scummvm-devel@lists.sf.net\n"
-"POT-Creation-Date: 2011-10-19 13:42+0100\n"
+"POT-Creation-Date: 2012-03-07 22:09+0000\n"
"PO-Revision-Date: 2011-04-25 23:07+0100\n"
"Last-Translator: Einar Johan T. Sømåen <einarjohants@gmail.com>\n"
"Language-Team: somaen <einarjohants@gmail.com>\n"
-"Language: Norsk (nynorsk)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=iso-8859-1\n"
"Content-Transfer-Encoding: 8bit\n"
+"Language: Norsk (nynorsk)\n"
"X-Poedit-Language: Norwegian Nynorsk\n"
"X-Poedit-SourceCharset: iso-8859-1\n"
"Plural-Forms: nplurals=2; plural=(n != 1)\n"
@@ -47,13 +47,13 @@ msgid "Go up"
msgstr "Gå tilbake"
#: gui/browser.cpp:69 gui/chooser.cpp:45 gui/KeysDialog.cpp:43
-#: gui/launcher.cpp:312 gui/massadd.cpp:94 gui/options.cpp:1178
+#: gui/launcher.cpp:320 gui/massadd.cpp:94 gui/options.cpp:1253
#: gui/saveload.cpp:63 gui/saveload.cpp:155 gui/themebrowser.cpp:54
-#: engines/engine.cpp:436 engines/scumm/dialogs.cpp:190
+#: engines/engine.cpp:442 engines/scumm/dialogs.cpp:190
#: engines/sword1/control.cpp:865 engines/parallaction/saveload.cpp:281
#: backends/platform/wii/options.cpp:48
-#: backends/events/default/default-events.cpp:222
-#: backends/events/default/default-events.cpp:244
+#: backends/events/default/default-events.cpp:191
+#: backends/events/default/default-events.cpp:213
msgid "Cancel"
msgstr "Avbryt"
@@ -61,25 +61,30 @@ msgstr "Avbryt"
msgid "Choose"
msgstr "Vel"
-#: gui/gui-manager.cpp:116 engines/scumm/help.cpp:125
+#: gui/gui-manager.cpp:115 engines/scumm/help.cpp:125
#: engines/scumm/help.cpp:140 engines/scumm/help.cpp:165
#: engines/scumm/help.cpp:191 engines/scumm/help.cpp:209
#: backends/keymapper/remap-dialog.cpp:52
msgid "Close"
msgstr "Steng"
-#: gui/gui-manager.cpp:119
+#: gui/gui-manager.cpp:118
msgid "Mouse click"
msgstr "Musklikk"
-#: gui/gui-manager.cpp:122 base/main.cpp:283
+#: gui/gui-manager.cpp:122 base/main.cpp:288
msgid "Display keyboard"
msgstr "Syn Tastatur"
-#: gui/gui-manager.cpp:125 base/main.cpp:286
+#: gui/gui-manager.cpp:126 base/main.cpp:292
msgid "Remap keys"
msgstr "Omkople tastar"
+#: gui/gui-manager.cpp:129 base/main.cpp:295
+#, fuzzy
+msgid "Toggle FullScreen"
+msgstr "Veksle fullskjerm"
+
#: gui/KeysDialog.h:36 gui/KeysDialog.cpp:145
msgid "Choose an action to map"
msgstr "Vel ei handling for kopling:"
@@ -88,16 +93,17 @@ msgstr "Vel ei handling for kopling:"
msgid "Map"
msgstr "Kople"
-#: gui/KeysDialog.cpp:42 gui/launcher.cpp:313 gui/launcher.cpp:936
-#: gui/launcher.cpp:940 gui/massadd.cpp:91 gui/options.cpp:1179
-#: engines/engine.cpp:359 engines/engine.cpp:370 engines/scumm/dialogs.cpp:192
-#: engines/scumm/scumm.cpp:1776 engines/agos/animation.cpp:551
+#: gui/KeysDialog.cpp:42 gui/launcher.cpp:321 gui/launcher.cpp:960
+#: gui/launcher.cpp:964 gui/massadd.cpp:91 gui/options.cpp:1254
+#: engines/engine.cpp:361 engines/engine.cpp:372 engines/scumm/dialogs.cpp:192
+#: engines/scumm/scumm.cpp:1775 engines/agos/animation.cpp:551
#: engines/groovie/script.cpp:420 engines/sky/compact.cpp:131
-#: engines/sky/compact.cpp:141 engines/sword1/animation.cpp:344
-#: engines/sword1/animation.cpp:354 engines/sword1/animation.cpp:360
-#: engines/sword1/control.cpp:865 engines/sword1/logic.cpp:1633
-#: engines/sword2/animation.cpp:379 engines/sword2/animation.cpp:389
-#: engines/sword2/animation.cpp:398 engines/parallaction/saveload.cpp:281
+#: engines/sky/compact.cpp:141 engines/sword1/animation.cpp:539
+#: engines/sword1/animation.cpp:560 engines/sword1/animation.cpp:570
+#: engines/sword1/animation.cpp:577 engines/sword1/control.cpp:865
+#: engines/sword1/logic.cpp:1633 engines/sword2/animation.cpp:435
+#: engines/sword2/animation.cpp:455 engines/sword2/animation.cpp:465
+#: engines/sword2/animation.cpp:474 engines/parallaction/saveload.cpp:281
#: backends/platform/wii/options.cpp:47
#: backends/platform/wince/CELauncherDialog.cpp:54
msgid "OK"
@@ -125,15 +131,15 @@ msgstr "Vel ei handling"
msgid "Press the key to associate"
msgstr "Trykk tasten du vil kople"
-#: gui/launcher.cpp:165
+#: gui/launcher.cpp:170
msgid "Game"
msgstr "Spel"
-#: gui/launcher.cpp:169
+#: gui/launcher.cpp:174
msgid "ID:"
msgstr "ID:"
-#: gui/launcher.cpp:169 gui/launcher.cpp:171 gui/launcher.cpp:172
+#: gui/launcher.cpp:174 gui/launcher.cpp:176 gui/launcher.cpp:177
msgid ""
"Short game identifier used for referring to savegames and running the game "
"from the command line"
@@ -141,29 +147,29 @@ msgstr ""
"Kort spelidentifikator nytta for å referere til lagra spel, og å køyre "
"spelet frå kommandolinja"
-#: gui/launcher.cpp:171
+#: gui/launcher.cpp:176
msgctxt "lowres"
msgid "ID:"
msgstr "ID:"
-#: gui/launcher.cpp:176
+#: gui/launcher.cpp:181
msgid "Name:"
msgstr "Namn:"
-#: gui/launcher.cpp:176 gui/launcher.cpp:178 gui/launcher.cpp:179
+#: gui/launcher.cpp:181 gui/launcher.cpp:183 gui/launcher.cpp:184
msgid "Full title of the game"
msgstr "Full speltittel:"
-#: gui/launcher.cpp:178
+#: gui/launcher.cpp:183
msgctxt "lowres"
msgid "Name:"
msgstr "Namn:"
-#: gui/launcher.cpp:182
+#: gui/launcher.cpp:187
msgid "Language:"
msgstr "Språk:"
-#: gui/launcher.cpp:182 gui/launcher.cpp:183
+#: gui/launcher.cpp:187 gui/launcher.cpp:188
msgid ""
"Language of the game. This will not turn your Spanish game version into "
"English"
@@ -171,288 +177,286 @@ msgstr ""
"Spelets språk. Dette vil ikkje gjere den spanske versjonen av spelet til ein "
"engelsk versjon"
-#: gui/launcher.cpp:184 gui/launcher.cpp:198 gui/options.cpp:74
-#: gui/options.cpp:708 gui/options.cpp:718 gui/options.cpp:1149
+#: gui/launcher.cpp:189 gui/launcher.cpp:203 gui/options.cpp:80
+#: gui/options.cpp:745 gui/options.cpp:758 gui/options.cpp:1224
#: audio/null.cpp:40
msgid "<default>"
msgstr "<standard>"
-#: gui/launcher.cpp:194
+#: gui/launcher.cpp:199
msgid "Platform:"
msgstr "Plattform:"
-#: gui/launcher.cpp:194 gui/launcher.cpp:196 gui/launcher.cpp:197
+#: gui/launcher.cpp:199 gui/launcher.cpp:201 gui/launcher.cpp:202
msgid "Platform the game was originally designed for"
msgstr "Plattform spelet opprineleg vart designa for"
-#: gui/launcher.cpp:196
+#: gui/launcher.cpp:201
msgctxt "lowres"
msgid "Platform:"
msgstr "Plattform:"
-#: gui/launcher.cpp:208 gui/options.cpp:1018 gui/options.cpp:1035
+#: gui/launcher.cpp:213 gui/options.cpp:1087 gui/options.cpp:1104
msgid "Graphics"
msgstr "Grafikk"
-#: gui/launcher.cpp:208 gui/options.cpp:1018 gui/options.cpp:1035
+#: gui/launcher.cpp:213 gui/options.cpp:1087 gui/options.cpp:1104
msgid "GFX"
msgstr "GFX"
-#: gui/launcher.cpp:211
+#: gui/launcher.cpp:216
msgid "Override global graphic settings"
msgstr "Overstyr globale grafikkinstillingar"
-#: gui/launcher.cpp:213
+#: gui/launcher.cpp:218
msgctxt "lowres"
msgid "Override global graphic settings"
msgstr "Overstyr globale grafikkinstillingar"
-#: gui/launcher.cpp:220 gui/options.cpp:1041
+#: gui/launcher.cpp:225 gui/options.cpp:1110
msgid "Audio"
msgstr "Lyd"
-#: gui/launcher.cpp:223
+#: gui/launcher.cpp:228
msgid "Override global audio settings"
msgstr "Overstyr globale lydinstillingar"
-#: gui/launcher.cpp:225
+#: gui/launcher.cpp:230
msgctxt "lowres"
msgid "Override global audio settings"
msgstr "Overstyr globale lydinstillingar"
-#: gui/launcher.cpp:234 gui/options.cpp:1046
+#: gui/launcher.cpp:239 gui/options.cpp:1115
msgid "Volume"
msgstr "Volum"
-#: gui/launcher.cpp:236 gui/options.cpp:1048
+#: gui/launcher.cpp:241 gui/options.cpp:1117
msgctxt "lowres"
msgid "Volume"
msgstr "Volum"
-#: gui/launcher.cpp:239
+#: gui/launcher.cpp:244
msgid "Override global volume settings"
msgstr "Overstyr globale voluminstillingar"
-#: gui/launcher.cpp:241
+#: gui/launcher.cpp:246
msgctxt "lowres"
msgid "Override global volume settings"
msgstr "Overstyr globale voluminstillingar"
-#: gui/launcher.cpp:248 gui/options.cpp:1056
+#: gui/launcher.cpp:254 gui/options.cpp:1125
msgid "MIDI"
msgstr "MIDI"
-#: gui/launcher.cpp:251
+#: gui/launcher.cpp:257
msgid "Override global MIDI settings"
msgstr "Overstyr globale MIDI-instillingar"
-#: gui/launcher.cpp:253
+#: gui/launcher.cpp:259
msgctxt "lowres"
msgid "Override global MIDI settings"
msgstr "Overstyr globale MIDI-instillingar"
-#: gui/launcher.cpp:263 gui/options.cpp:1062
+#: gui/launcher.cpp:268 gui/options.cpp:1131
msgid "MT-32"
msgstr "MT-32"
-#: gui/launcher.cpp:266
+#: gui/launcher.cpp:271
msgid "Override global MT-32 settings"
msgstr "Overstyr globale MT-32-instillingar"
-#: gui/launcher.cpp:268
+#: gui/launcher.cpp:273
msgctxt "lowres"
msgid "Override global MT-32 settings"
msgstr "Overstyr globale MT-32-instillingar"
-#: gui/launcher.cpp:279 gui/options.cpp:1069
+#: gui/launcher.cpp:282 gui/options.cpp:1138
msgid "Paths"
msgstr "Stiar"
-#: gui/launcher.cpp:281 gui/options.cpp:1071
+#: gui/launcher.cpp:284 gui/options.cpp:1140
msgctxt "lowres"
msgid "Paths"
msgstr "Stiar"
-#: gui/launcher.cpp:288
+#: gui/launcher.cpp:291
msgid "Game Path:"
msgstr "Spelsti:"
-#: gui/launcher.cpp:290
+#: gui/launcher.cpp:293
msgctxt "lowres"
msgid "Game Path:"
msgstr "Spelsti:"
-#: gui/launcher.cpp:295 gui/options.cpp:1091
+#: gui/launcher.cpp:298 gui/options.cpp:1164
msgid "Extra Path:"
msgstr "Ekstrasti:"
-#: gui/launcher.cpp:295 gui/launcher.cpp:297 gui/launcher.cpp:298
+#: gui/launcher.cpp:298 gui/launcher.cpp:300 gui/launcher.cpp:301
msgid "Specifies path to additional data used the game"
msgstr ""
-#: gui/launcher.cpp:297 gui/options.cpp:1093
+#: gui/launcher.cpp:300 gui/options.cpp:1166
msgctxt "lowres"
msgid "Extra Path:"
msgstr "Ekstrasti:"
-#: gui/launcher.cpp:302 gui/options.cpp:1079
+#: gui/launcher.cpp:307 gui/options.cpp:1148
msgid "Save Path:"
msgstr "Lagringssti:"
-#: gui/launcher.cpp:302 gui/launcher.cpp:304 gui/launcher.cpp:305
-#: gui/options.cpp:1079 gui/options.cpp:1081 gui/options.cpp:1082
+#: gui/launcher.cpp:307 gui/launcher.cpp:309 gui/launcher.cpp:310
+#: gui/options.cpp:1148 gui/options.cpp:1150 gui/options.cpp:1151
msgid "Specifies where your savegames are put"
msgstr ""
-#: gui/launcher.cpp:304 gui/options.cpp:1081
+#: gui/launcher.cpp:309 gui/options.cpp:1150
msgctxt "lowres"
msgid "Save Path:"
msgstr "Lagringssti:"
-#: gui/launcher.cpp:321 gui/launcher.cpp:404 gui/launcher.cpp:453
-#: gui/options.cpp:1088 gui/options.cpp:1094 gui/options.cpp:1101
-#: gui/options.cpp:1202 gui/options.cpp:1208 gui/options.cpp:1214
-#: gui/options.cpp:1222 gui/options.cpp:1246 gui/options.cpp:1250
-#: gui/options.cpp:1256 gui/options.cpp:1263 gui/options.cpp:1362
+#: gui/launcher.cpp:329 gui/launcher.cpp:416 gui/launcher.cpp:469
+#: gui/launcher.cpp:523 gui/options.cpp:1159 gui/options.cpp:1167
+#: gui/options.cpp:1176 gui/options.cpp:1283 gui/options.cpp:1289
+#: gui/options.cpp:1297 gui/options.cpp:1327 gui/options.cpp:1333
+#: gui/options.cpp:1340 gui/options.cpp:1433 gui/options.cpp:1436
+#: gui/options.cpp:1448
msgctxt "path"
msgid "None"
msgstr "Ingen"
-#: gui/launcher.cpp:326 gui/launcher.cpp:408
+#: gui/launcher.cpp:334 gui/launcher.cpp:422 gui/launcher.cpp:527
+#: gui/options.cpp:1277 gui/options.cpp:1321 gui/options.cpp:1439
#: backends/platform/wii/options.cpp:56
msgid "Default"
msgstr "Standard"
-#: gui/launcher.cpp:446 gui/options.cpp:1356
+#: gui/launcher.cpp:462 gui/options.cpp:1442
msgid "Select SoundFont"
msgstr "Vel SoundFont"
-#: gui/launcher.cpp:465 gui/launcher.cpp:612
+#: gui/launcher.cpp:481 gui/launcher.cpp:636
msgid "Select directory with game data"
msgstr "Vel mappe med speldata"
-#: gui/launcher.cpp:483
+#: gui/launcher.cpp:499
msgid "Select additional game directory"
msgstr ""
-#: gui/launcher.cpp:495
+#: gui/launcher.cpp:511
msgid "Select directory for saved games"
msgstr "Vel mappe for lagra spel"
-#: gui/launcher.cpp:514
+#: gui/launcher.cpp:538
msgid "This game ID is already taken. Please choose another one."
msgstr ""
-#: gui/launcher.cpp:555 engines/dialogs.cpp:110
+#: gui/launcher.cpp:579 engines/dialogs.cpp:110
msgid "~Q~uit"
msgstr "~A~vslutt"
-#: gui/launcher.cpp:555 backends/platform/sdl/macosx/appmenu_osx.mm:80
+#: gui/launcher.cpp:579 backends/platform/sdl/macosx/appmenu_osx.mm:96
msgid "Quit ScummVM"
msgstr "Avslutt ScummVM"
-#: gui/launcher.cpp:556
+#: gui/launcher.cpp:580
msgid "A~b~out..."
msgstr "~O~m..."
-#: gui/launcher.cpp:556 backends/platform/sdl/macosx/appmenu_osx.mm:61
+#: gui/launcher.cpp:580 backends/platform/sdl/macosx/appmenu_osx.mm:70
msgid "About ScummVM"
msgstr "Om ScummVM"
-#: gui/launcher.cpp:557
+#: gui/launcher.cpp:581
msgid "~O~ptions..."
msgstr "~V~al..."
-#: gui/launcher.cpp:557
+#: gui/launcher.cpp:581
msgid "Change global ScummVM options"
msgstr "Endre globale ScummVM-instillingar"
-#: gui/launcher.cpp:559
+#: gui/launcher.cpp:583
msgid "~S~tart"
msgstr "~S~tart"
-#: gui/launcher.cpp:559
+#: gui/launcher.cpp:583
msgid "Start selected game"
msgstr "Start det velde spelet"
-#: gui/launcher.cpp:562
+#: gui/launcher.cpp:586
msgid "~L~oad..."
msgstr "~Å~pne..."
-#: gui/launcher.cpp:562
+#: gui/launcher.cpp:586
msgid "Load savegame for selected game"
msgstr "Åpne eit lagra spel for the velde spelet"
-#: gui/launcher.cpp:567 gui/launcher.cpp:1055
+#: gui/launcher.cpp:591 gui/launcher.cpp:1079
msgid "~A~dd Game..."
msgstr "~L~egg til spel..."
-#: gui/launcher.cpp:567 gui/launcher.cpp:574
+#: gui/launcher.cpp:591 gui/launcher.cpp:598
msgid "Hold Shift for Mass Add"
msgstr "Hold Shift nede for å legge til fleire"
-#: gui/launcher.cpp:569
+#: gui/launcher.cpp:593
msgid "~E~dit Game..."
msgstr "~R~ediger spel..."
-#: gui/launcher.cpp:569 gui/launcher.cpp:576
+#: gui/launcher.cpp:593 gui/launcher.cpp:600
msgid "Change game options"
msgstr "Endre spelinstillingar"
-#: gui/launcher.cpp:571
+#: gui/launcher.cpp:595
msgid "~R~emove Game"
msgstr "~F~jern spel"
-#: gui/launcher.cpp:571 gui/launcher.cpp:578
+#: gui/launcher.cpp:595 gui/launcher.cpp:602
msgid "Remove game from the list. The game data files stay intact"
msgstr ""
-#: gui/launcher.cpp:574 gui/launcher.cpp:1055
+#: gui/launcher.cpp:598 gui/launcher.cpp:1079
msgctxt "lowres"
msgid "~A~dd Game..."
msgstr "~L~egg til spel..."
-#: gui/launcher.cpp:576
+#: gui/launcher.cpp:600
msgctxt "lowres"
msgid "~E~dit Game..."
msgstr "~R~ediger spel..."
-#: gui/launcher.cpp:578
+#: gui/launcher.cpp:602
msgctxt "lowres"
msgid "~R~emove Game"
msgstr "~F~jern spel"
-#: gui/launcher.cpp:586
+#: gui/launcher.cpp:610
msgid "Search in game list"
msgstr "Søk i spelliste"
-#: gui/launcher.cpp:590 gui/launcher.cpp:1102
+#: gui/launcher.cpp:614 gui/launcher.cpp:1126
msgid "Search:"
msgstr "Søk:"
-#: gui/launcher.cpp:593 gui/options.cpp:826
-msgid "Clear value"
-msgstr "Tøm verdi"
-
-#: gui/launcher.cpp:615 engines/dialogs.cpp:114 engines/mohawk/myst.cpp:255
+#: gui/launcher.cpp:639 engines/dialogs.cpp:114 engines/mohawk/myst.cpp:255
#: engines/mohawk/riven.cpp:716 engines/cruise/menu.cpp:216
msgid "Load game:"
msgstr "Åpne spel:"
-#: gui/launcher.cpp:615 engines/dialogs.cpp:114 engines/scumm/dialogs.cpp:188
+#: gui/launcher.cpp:639 engines/dialogs.cpp:114 engines/scumm/dialogs.cpp:188
#: engines/mohawk/myst.cpp:255 engines/mohawk/riven.cpp:716
#: engines/cruise/menu.cpp:216 backends/platform/wince/CEActionsPocket.cpp:267
#: backends/platform/wince/CEActionsSmartphone.cpp:231
msgid "Load"
msgstr "Åpne"
-#: gui/launcher.cpp:723
+#: gui/launcher.cpp:747
msgid ""
"Do you really want to run the mass game detector? This could potentially add "
"a huge number of games."
msgstr ""
-#: gui/launcher.cpp:724 gui/launcher.cpp:872
+#: gui/launcher.cpp:748 gui/launcher.cpp:896
#: backends/events/symbiansdl/symbiansdl-events.cpp:184
#: backends/platform/wince/CEActionsPocket.cpp:326
#: backends/platform/wince/CEActionsSmartphone.cpp:287
@@ -460,7 +464,7 @@ msgstr ""
msgid "Yes"
msgstr "Ja"
-#: gui/launcher.cpp:724 gui/launcher.cpp:872
+#: gui/launcher.cpp:748 gui/launcher.cpp:896
#: backends/events/symbiansdl/symbiansdl-events.cpp:184
#: backends/platform/wince/CEActionsPocket.cpp:326
#: backends/platform/wince/CEActionsSmartphone.cpp:287
@@ -468,38 +472,38 @@ msgstr "Ja"
msgid "No"
msgstr "Nei"
-#: gui/launcher.cpp:772
+#: gui/launcher.cpp:796
msgid "ScummVM couldn't open the specified directory!"
msgstr "ScummVM kunne ikkje åpne den velde mappa!"
-#: gui/launcher.cpp:784
+#: gui/launcher.cpp:808
msgid "ScummVM could not find any game in the specified directory!"
msgstr "ScummVM kunne ikkje finne noko spel i den velde mappa!"
-#: gui/launcher.cpp:798
+#: gui/launcher.cpp:822
msgid "Pick the game:"
msgstr "Vel spelet:"
-#: gui/launcher.cpp:872
+#: gui/launcher.cpp:896
msgid "Do you really want to remove this game configuration?"
msgstr "Vil du verkeleg fjerne denne spelkonfigurasjonen?"
-#: gui/launcher.cpp:936
+#: gui/launcher.cpp:960
msgid "This game does not support loading games from the launcher."
msgstr "Dette spelet støttar ikkje åpning av lagra spel frå oppstartaren."
-#: gui/launcher.cpp:940
+#: gui/launcher.cpp:964
msgid "ScummVM could not find any engine capable of running the selected game!"
msgstr ""
"ScummVM kunne ikkje finne nokon motor som var i stand til å køyre det velde "
"spelet!"
-#: gui/launcher.cpp:1054
+#: gui/launcher.cpp:1078
msgctxt "lowres"
msgid "Mass Add..."
msgstr "Legg til fleire..."
-#: gui/launcher.cpp:1054
+#: gui/launcher.cpp:1078
msgid "Mass Add..."
msgstr "Legg til fleire..."
@@ -526,141 +530,141 @@ msgstr "Søkt i %d mappar ..."
msgid "Discovered %d new games, ignored %d previously added games ..."
msgstr "Oppdaga %d nye spel ..."
-#: gui/options.cpp:72
+#: gui/options.cpp:78
msgid "Never"
msgstr "Aldri"
-#: gui/options.cpp:72
+#: gui/options.cpp:78
msgid "every 5 mins"
msgstr "kvart 5. min"
-#: gui/options.cpp:72
+#: gui/options.cpp:78
msgid "every 10 mins"
msgstr "kvart 10. min"
-#: gui/options.cpp:72
+#: gui/options.cpp:78
msgid "every 15 mins"
msgstr "kvart 15. min"
-#: gui/options.cpp:72
+#: gui/options.cpp:78
msgid "every 30 mins"
msgstr "kvart 30. min"
-#: gui/options.cpp:74
+#: gui/options.cpp:80
msgid "8 kHz"
msgstr "8 kHz"
-#: gui/options.cpp:74
+#: gui/options.cpp:80
msgid "11kHz"
msgstr "11kHz"
-#: gui/options.cpp:74
+#: gui/options.cpp:80
msgid "22 kHz"
msgstr "22 kHz"
-#: gui/options.cpp:74
+#: gui/options.cpp:80
msgid "44 kHz"
msgstr "44 kHz"
-#: gui/options.cpp:74
+#: gui/options.cpp:80
msgid "48 kHz"
msgstr "48 kHz"
-#: gui/options.cpp:236 gui/options.cpp:464 gui/options.cpp:559
-#: gui/options.cpp:625 gui/options.cpp:825
+#: gui/options.cpp:257 gui/options.cpp:485 gui/options.cpp:586
+#: gui/options.cpp:659 gui/options.cpp:868
msgctxt "soundfont"
msgid "None"
msgstr "Ingen"
-#: gui/options.cpp:372
+#: gui/options.cpp:393
msgid "Failed to apply some of the graphic options changes:"
msgstr ""
-#: gui/options.cpp:384
+#: gui/options.cpp:405
msgid "the video mode could not be changed."
msgstr ""
-#: gui/options.cpp:390
+#: gui/options.cpp:411
msgid "the fullscreen setting could not be changed"
msgstr ""
-#: gui/options.cpp:396
+#: gui/options.cpp:417
msgid "the aspect ratio setting could not be changed"
msgstr ""
-#: gui/options.cpp:705
+#: gui/options.cpp:742
msgid "Graphics mode:"
msgstr "Grafikkmodus:"
-#: gui/options.cpp:716
+#: gui/options.cpp:756
msgid "Render mode:"
msgstr "Teiknemodus:"
-#: gui/options.cpp:716 gui/options.cpp:717
+#: gui/options.cpp:756 gui/options.cpp:757
msgid "Special dithering modes supported by some games"
msgstr "Spesielle dithering-modus som støttast av nokre spel"
-#: gui/options.cpp:726
+#: gui/options.cpp:768
#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2248
-#: backends/graphics/openglsdl/openglsdl-graphics.cpp:476
+#: backends/graphics/openglsdl/openglsdl-graphics.cpp:472
msgid "Fullscreen mode"
msgstr "Fullskjermsmodus"
-#: gui/options.cpp:729
+#: gui/options.cpp:771
msgid "Aspect ratio correction"
msgstr "Aspekt-korrigering"
-#: gui/options.cpp:729
+#: gui/options.cpp:771
msgid "Correct aspect ratio for 320x200 games"
msgstr "Rett opp aspekt for 320x200 spel"
-#: gui/options.cpp:730
+#: gui/options.cpp:772
msgid "EGA undithering"
msgstr ""
-#: gui/options.cpp:730
+#: gui/options.cpp:772
msgid "Enable undithering in EGA games that support it"
msgstr ""
-#: gui/options.cpp:738
+#: gui/options.cpp:780
msgid "Preferred Device:"
msgstr "Føretrukken eining:"
-#: gui/options.cpp:738
+#: gui/options.cpp:780
msgid "Music Device:"
msgstr ""
-#: gui/options.cpp:738 gui/options.cpp:740
+#: gui/options.cpp:780 gui/options.cpp:782
msgid "Specifies preferred sound device or sound card emulator"
msgstr ""
-#: gui/options.cpp:738 gui/options.cpp:740 gui/options.cpp:741
+#: gui/options.cpp:780 gui/options.cpp:782 gui/options.cpp:783
msgid "Specifies output sound device or sound card emulator"
msgstr ""
-#: gui/options.cpp:740
+#: gui/options.cpp:782
msgctxt "lowres"
msgid "Preferred Dev.:"
msgstr ""
-#: gui/options.cpp:740
+#: gui/options.cpp:782
msgctxt "lowres"
msgid "Music Device:"
msgstr ""
-#: gui/options.cpp:766
+#: gui/options.cpp:809
msgid "AdLib emulator:"
msgstr "AdLib emulator:"
-#: gui/options.cpp:766 gui/options.cpp:767
+#: gui/options.cpp:809 gui/options.cpp:810
msgid "AdLib is used for music in many games"
msgstr "AdLib nyttast til musikk i mange spel"
-#: gui/options.cpp:777
+#: gui/options.cpp:820
msgid "Output rate:"
msgstr ""
-#: gui/options.cpp:777 gui/options.cpp:778
+#: gui/options.cpp:820 gui/options.cpp:821
msgid ""
"Higher value specifies better sound quality but may be not supported by your "
"soundcard"
@@ -668,250 +672,250 @@ msgstr ""
"Høgare verdier gir betre lydkvalitet, men støttast kanskje ikkje av "
"lydkortet ditt"
-#: gui/options.cpp:788
+#: gui/options.cpp:831
msgid "GM Device:"
msgstr ""
-#: gui/options.cpp:788
+#: gui/options.cpp:831
msgid "Specifies default sound device for General MIDI output"
msgstr ""
-#: gui/options.cpp:799
+#: gui/options.cpp:842
msgid "Don't use General MIDI music"
msgstr "Ikkje nytt General MIDI musikk"
-#: gui/options.cpp:810 gui/options.cpp:871
+#: gui/options.cpp:853 gui/options.cpp:915
msgid "Use first available device"
msgstr ""
-#: gui/options.cpp:822
+#: gui/options.cpp:865
msgid "SoundFont:"
msgstr "SoundFont:"
-#: gui/options.cpp:822 gui/options.cpp:824 gui/options.cpp:825
+#: gui/options.cpp:865 gui/options.cpp:867 gui/options.cpp:868
msgid "SoundFont is supported by some audio cards, Fluidsynth and Timidity"
msgstr "SoundFont støttast av enkelte lydkort, Fluidsynth og Timidity"
-#: gui/options.cpp:824
+#: gui/options.cpp:867
msgctxt "lowres"
msgid "SoundFont:"
msgstr "SoundFont:"
-#: gui/options.cpp:829
+#: gui/options.cpp:873
msgid "Mixed AdLib/MIDI mode"
msgstr "Blanda AdLib/MIDI-modus"
-#: gui/options.cpp:829
+#: gui/options.cpp:873
msgid "Use both MIDI and AdLib sound generation"
msgstr "Nytt båe MIDI og AdLib lydskaping"
-#: gui/options.cpp:832
+#: gui/options.cpp:876
msgid "MIDI gain:"
msgstr "MIDI gain:"
-#: gui/options.cpp:842
+#: gui/options.cpp:886
msgid "MT-32 Device:"
msgstr ""
-#: gui/options.cpp:842
+#: gui/options.cpp:886
msgid "Specifies default sound device for Roland MT-32/LAPC1/CM32l/CM64 output"
msgstr ""
-#: gui/options.cpp:847
+#: gui/options.cpp:891
msgid "True Roland MT-32 (disable GM emulation)"
msgstr "Ekte Roland MT-32 (deaktiver GM-emulering)"
-#: gui/options.cpp:847 gui/options.cpp:849
+#: gui/options.cpp:891 gui/options.cpp:893
msgid ""
"Check if you want to use your real hardware Roland-compatible sound device "
"connected to your computer"
msgstr ""
-#: gui/options.cpp:849
+#: gui/options.cpp:893
msgctxt "lowres"
msgid "True Roland MT-32 (no GM emulation)"
msgstr "Ekte Roland MT-32 (ingen GS-emulering)"
-#: gui/options.cpp:852
+#: gui/options.cpp:896
msgid "Enable Roland GS Mode"
msgstr "Aktiver Roland GS-modus"
-#: gui/options.cpp:852
+#: gui/options.cpp:896
msgid "Turns off General MIDI mapping for games with Roland MT-32 soundtrack"
msgstr "Slår av General MIDI-kopling for spel med Roland MT-32 lydspor"
-#: gui/options.cpp:861
+#: gui/options.cpp:905
msgid "Don't use Roland MT-32 music"
msgstr "Ikkje nytt Roland MT-32 musikk"
-#: gui/options.cpp:888
+#: gui/options.cpp:932
msgid "Text and Speech:"
msgstr "Tekst og Tale:"
-#: gui/options.cpp:892 gui/options.cpp:902
+#: gui/options.cpp:936 gui/options.cpp:946
msgid "Speech"
msgstr "Tale"
-#: gui/options.cpp:893 gui/options.cpp:903
+#: gui/options.cpp:937 gui/options.cpp:947
msgid "Subtitles"
msgstr "Teksting"
-#: gui/options.cpp:894
+#: gui/options.cpp:938
msgid "Both"
msgstr "Begge"
-#: gui/options.cpp:896
+#: gui/options.cpp:940
msgid "Subtitle speed:"
msgstr "Undertekstfart:"
-#: gui/options.cpp:898
+#: gui/options.cpp:942
msgctxt "lowres"
msgid "Text and Speech:"
msgstr "Tekst og Tale:"
-#: gui/options.cpp:902
+#: gui/options.cpp:946
msgid "Spch"
msgstr "Tale"
-#: gui/options.cpp:903
+#: gui/options.cpp:947
msgid "Subs"
msgstr "Tekst"
-#: gui/options.cpp:904
+#: gui/options.cpp:948
msgctxt "lowres"
msgid "Both"
msgstr "Båe"
-#: gui/options.cpp:904
+#: gui/options.cpp:948
msgid "Show subtitles and play speech"
msgstr "Vis teksting og spel av tale"
-#: gui/options.cpp:906
+#: gui/options.cpp:950
msgctxt "lowres"
msgid "Subtitle speed:"
msgstr "Undertekstfart:"
-#: gui/options.cpp:922
+#: gui/options.cpp:966
msgid "Music volume:"
msgstr "Musikkvolum:"
-#: gui/options.cpp:924
+#: gui/options.cpp:968
msgctxt "lowres"
msgid "Music volume:"
msgstr "Musikkvolum:"
-#: gui/options.cpp:931
+#: gui/options.cpp:975
msgid "Mute All"
msgstr "Demp alle"
-#: gui/options.cpp:934
+#: gui/options.cpp:978
msgid "SFX volume:"
msgstr "Lydeffektvolum:"
-#: gui/options.cpp:934 gui/options.cpp:936 gui/options.cpp:937
+#: gui/options.cpp:978 gui/options.cpp:980 gui/options.cpp:981
msgid "Special sound effects volume"
msgstr ""
-#: gui/options.cpp:936
+#: gui/options.cpp:980
msgctxt "lowres"
msgid "SFX volume:"
msgstr "Lydeffektvolum:"
-#: gui/options.cpp:944
+#: gui/options.cpp:988
msgid "Speech volume:"
msgstr "Talevolum:"
-#: gui/options.cpp:946
+#: gui/options.cpp:990
msgctxt "lowres"
msgid "Speech volume:"
msgstr "Talevolum:"
-#: gui/options.cpp:1085
+#: gui/options.cpp:1156
msgid "Theme Path:"
msgstr "Temasti:"
-#: gui/options.cpp:1087
+#: gui/options.cpp:1158
msgctxt "lowres"
msgid "Theme Path:"
msgstr "Temasti:"
-#: gui/options.cpp:1091 gui/options.cpp:1093 gui/options.cpp:1094
+#: gui/options.cpp:1164 gui/options.cpp:1166 gui/options.cpp:1167
msgid "Specifies path to additional data used by all games or ScummVM"
msgstr ""
-#: gui/options.cpp:1098
+#: gui/options.cpp:1173
msgid "Plugins Path:"
msgstr "Pluginsti:"
-#: gui/options.cpp:1100
+#: gui/options.cpp:1175
msgctxt "lowres"
msgid "Plugins Path:"
msgstr "Pluginsti:"
-#: gui/options.cpp:1109
+#: gui/options.cpp:1184
msgid "Misc"
msgstr "Div"
-#: gui/options.cpp:1111
+#: gui/options.cpp:1186
msgctxt "lowres"
msgid "Misc"
msgstr "Div"
-#: gui/options.cpp:1113
+#: gui/options.cpp:1188
msgid "Theme:"
msgstr "Tema:"
-#: gui/options.cpp:1117
+#: gui/options.cpp:1192
msgid "GUI Renderer:"
msgstr "GUI-teiknar:"
-#: gui/options.cpp:1129
+#: gui/options.cpp:1204
msgid "Autosave:"
msgstr "Autolagre:"
-#: gui/options.cpp:1131
+#: gui/options.cpp:1206
msgctxt "lowres"
msgid "Autosave:"
msgstr "Autolagre:"
-#: gui/options.cpp:1139
+#: gui/options.cpp:1214
msgid "Keys"
msgstr "Tastar"
-#: gui/options.cpp:1146
+#: gui/options.cpp:1221
msgid "GUI Language:"
msgstr "GUI-språk:"
-#: gui/options.cpp:1146
+#: gui/options.cpp:1221
msgid "Language of ScummVM GUI"
msgstr "Språk i ScummVM-GUIet"
-#: gui/options.cpp:1295
+#: gui/options.cpp:1372
#, fuzzy
msgid "You have to restart ScummVM before your changes will take effect."
msgstr "Du må omstarte ScummVM for at endringane skal skje."
-#: gui/options.cpp:1308
+#: gui/options.cpp:1385
msgid "Select directory for savegames"
msgstr "Vel mappe for lagra spel"
-#: gui/options.cpp:1315
+#: gui/options.cpp:1392
msgid "The chosen directory cannot be written to. Please select another one."
msgstr "Den velde mappa kan ikkje skrivast til. Vennlegst vel ein annan."
-#: gui/options.cpp:1324
+#: gui/options.cpp:1401
msgid "Select directory for GUI themes"
msgstr "Vel ei mappe for GUI-tema:"
-#: gui/options.cpp:1334
+#: gui/options.cpp:1411
msgid "Select directory for extra files"
msgstr "Vel ei mappe for ekstra filer"
-#: gui/options.cpp:1345
+#: gui/options.cpp:1422
msgid "Select directory for plugins"
msgstr "Vel ei mappe for plugins"
-#: gui/options.cpp:1389
+#: gui/options.cpp:1475
msgid ""
"The theme you selected does not support your current language. If you want "
"to use this theme you need to switch to another language first."
@@ -959,60 +963,64 @@ msgstr "Ikkje navngjeven speltilstand"
msgid "Select a Theme"
msgstr "Vel eit tema"
-#: gui/ThemeEngine.cpp:328
+#: gui/ThemeEngine.cpp:333
msgid "Disabled GFX"
msgstr "Deaktivert GFX"
-#: gui/ThemeEngine.cpp:328
+#: gui/ThemeEngine.cpp:333
msgctxt "lowres"
msgid "Disabled GFX"
msgstr "Deaktivert GFX"
-#: gui/ThemeEngine.cpp:329
+#: gui/ThemeEngine.cpp:334
msgid "Standard Renderer (16bpp)"
msgstr "Standard Teiknar (16bpp)"
-#: gui/ThemeEngine.cpp:329
+#: gui/ThemeEngine.cpp:334
msgid "Standard (16bpp)"
msgstr "Standard (16bpp)"
-#: gui/ThemeEngine.cpp:331
+#: gui/ThemeEngine.cpp:336
msgid "Antialiased Renderer (16bpp)"
msgstr "Antialiased Teiknar (16bpp)"
-#: gui/ThemeEngine.cpp:331
+#: gui/ThemeEngine.cpp:336
msgid "Antialiased (16bpp)"
msgstr "Antialiased (16bpp)"
+#: gui/widget.cpp:312 gui/widget.cpp:314 gui/widget.cpp:320 gui/widget.cpp:322
+msgid "Clear value"
+msgstr "Tøm verdi"
+
#: base/main.cpp:203
#, c-format
msgid "Engine does not support debug level '%s'"
msgstr "Motoren støttar ikkje debug-nivå '%s'"
-#: base/main.cpp:271
+#: base/main.cpp:275
msgid "Menu"
msgstr "Meny"
-#: base/main.cpp:274 backends/platform/symbian/src/SymbianActions.cpp:45
+#: base/main.cpp:278 backends/platform/symbian/src/SymbianActions.cpp:45
#: backends/platform/wince/CEActionsPocket.cpp:45
#: backends/platform/wince/CEActionsSmartphone.cpp:46
msgid "Skip"
msgstr "Hopp over"
-#: base/main.cpp:277 backends/platform/symbian/src/SymbianActions.cpp:50
+#: base/main.cpp:281 backends/platform/symbian/src/SymbianActions.cpp:50
#: backends/platform/wince/CEActionsPocket.cpp:42
msgid "Pause"
msgstr "Pause"
-#: base/main.cpp:280
+#: base/main.cpp:284
msgid "Skip line"
msgstr "Hopp over linje"
-#: base/main.cpp:439
+#: base/main.cpp:455
msgid "Error running game:"
msgstr "Feil under køyring av spel:"
-#: base/main.cpp:463
+#: base/main.cpp:479
msgid "Could not find any engine capable of running the selected game"
msgstr "Kunne ikkje finne nokon motor som kunne køyre det velde spelet."
@@ -1081,25 +1089,6 @@ msgstr ""
msgid "Unknown error"
msgstr "Ukjend feil"
-#. I18N: Hercules is graphics card name
-#: common/util.cpp:275
-msgid "Hercules Green"
-msgstr "Hercules Grønn"
-
-#: common/util.cpp:276
-msgid "Hercules Amber"
-msgstr "Hercules Raudgul"
-
-#: common/util.cpp:283
-msgctxt "lowres"
-msgid "Hercules Green"
-msgstr "Hercules Grønn"
-
-#: common/util.cpp:284
-msgctxt "lowres"
-msgid "Hercules Amber"
-msgstr "Hercules Raudgul"
-
#: engines/advancedDetector.cpp:296
#, c-format
msgid "The game in '%s' seems to be unknown."
@@ -1149,12 +1138,12 @@ msgid "~R~eturn to Launcher"
msgstr "~T~ilbake til oppstarter"
#: engines/dialogs.cpp:116 engines/cruise/menu.cpp:214
-#: engines/sci/engine/kfile.cpp:578
+#: engines/sci/engine/kfile.cpp:566
msgid "Save game:"
msgstr "Lagra spel:"
#: engines/dialogs.cpp:116 engines/scumm/dialogs.cpp:187
-#: engines/cruise/menu.cpp:214 engines/sci/engine/kfile.cpp:578
+#: engines/cruise/menu.cpp:214 engines/sci/engine/kfile.cpp:566
#: backends/platform/symbian/src/SymbianActions.cpp:44
#: backends/platform/wince/CEActionsPocket.cpp:43
#: backends/platform/wince/CEActionsPocket.cpp:267
@@ -1170,39 +1159,46 @@ msgid ""
"further assistance."
msgstr ""
-#: engines/dialogs.cpp:316 engines/mohawk/dialogs.cpp:109
+#: engines/dialogs.cpp:243
+#, c-format
+msgid ""
+"Gamestate save failed (%s)! Please consult the README for basic information, "
+"and for instructions on how to obtain further assistance."
+msgstr ""
+
+#: engines/dialogs.cpp:321 engines/mohawk/dialogs.cpp:109
#: engines/mohawk/dialogs.cpp:174
msgid "~O~K"
msgstr "~O~K"
-#: engines/dialogs.cpp:317 engines/mohawk/dialogs.cpp:110
+#: engines/dialogs.cpp:322 engines/mohawk/dialogs.cpp:110
#: engines/mohawk/dialogs.cpp:175
msgid "~C~ancel"
msgstr "~A~vbryt"
-#: engines/dialogs.cpp:320
+#: engines/dialogs.cpp:325
msgid "~K~eys"
msgstr "~T~astar"
-#: engines/engine.cpp:233
+#: engines/engine.cpp:235
msgid "Could not initialize color format."
msgstr ""
-#: engines/engine.cpp:241
+#: engines/engine.cpp:243
#, fuzzy
msgid "Could not switch to video mode: '"
msgstr "Gjeldende videomodus:"
-#: engines/engine.cpp:250
+#: engines/engine.cpp:252
#, fuzzy
msgid "Could not apply aspect ratio setting."
msgstr "Veksle aspekt-korrigering"
-#: engines/engine.cpp:255
+#: engines/engine.cpp:257
msgid "Could not apply fullscreen setting."
msgstr ""
-#: engines/engine.cpp:355
+#: engines/engine.cpp:357
msgid ""
"You appear to be playing this game directly\n"
"from the CD. This is known to cause problems,\n"
@@ -1211,7 +1207,7 @@ msgid ""
"See the README file for details."
msgstr ""
-#: engines/engine.cpp:366
+#: engines/engine.cpp:368
msgid ""
"This game has audio tracks in its disk. These\n"
"tracks need to be ripped from the disk using\n"
@@ -1220,14 +1216,21 @@ msgid ""
"See the README file for details."
msgstr ""
-#: engines/engine.cpp:433
+#: engines/engine.cpp:426
+#, c-format
+msgid ""
+"Gamestate load failed (%s)! Please consult the README for basic information, "
+"and for instructions on how to obtain further assistance."
+msgstr ""
+
+#: engines/engine.cpp:439
msgid ""
"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."
msgstr ""
-#: engines/engine.cpp:436
+#: engines/engine.cpp:442
msgid "Start anyway"
msgstr ""
@@ -1273,7 +1276,7 @@ msgstr ""
#: backends/platform/symbian/src/SymbianActions.cpp:52
#: backends/platform/wince/CEActionsPocket.cpp:44
#: backends/platform/wince/CEActionsSmartphone.cpp:52
-#: backends/events/default/default-events.cpp:244
+#: backends/events/default/default-events.cpp:213
msgid "Quit"
msgstr "Avslutt"
@@ -1352,6 +1355,27 @@ msgctxt "lowres"
msgid "Speech & Subs"
msgstr "Tale"
+#: engines/scumm/dialogs.cpp:653
+msgid "Select a Proficiency Level."
+msgstr ""
+
+#: engines/scumm/dialogs.cpp:655
+msgid "Refer to your Loom(TM) manual for help."
+msgstr ""
+
+#: engines/scumm/dialogs.cpp:658
+#, fuzzy
+msgid "Standard"
+msgstr "Standard (16bpp)"
+
+#: engines/scumm/dialogs.cpp:659
+msgid "Practice"
+msgstr ""
+
+#: engines/scumm/dialogs.cpp:660
+msgid "Expert"
+msgstr ""
+
#: engines/scumm/help.cpp:73
msgid "Common keyboard commands:"
msgstr "Vanlege tastaturkommandoar:"
@@ -1866,14 +1890,14 @@ msgstr "Fly til høgre"
msgid "Fly to lower right"
msgstr "Fly til nedre høgre"
-#: engines/scumm/scumm.cpp:1774
+#: engines/scumm/scumm.cpp:1773
#, c-format
msgid ""
"Native MIDI support requires the Roland Upgrade from LucasArts,\n"
"but %s is missing. Using AdLib instead."
msgstr ""
-#: engines/scumm/scumm.cpp:2264 engines/agos/saveload.cpp:189
+#: engines/scumm/scumm.cpp:2271 engines/agos/saveload.cpp:189
#, c-format
msgid ""
"Failed to save game state to file:\n"
@@ -1881,7 +1905,7 @@ msgid ""
"%s"
msgstr ""
-#: engines/scumm/scumm.cpp:2271 engines/agos/saveload.cpp:154
+#: engines/scumm/scumm.cpp:2278 engines/agos/saveload.cpp:154
#, c-format
msgid ""
"Failed to load game state from file:\n"
@@ -1889,7 +1913,7 @@ msgid ""
"%s"
msgstr ""
-#: engines/scumm/scumm.cpp:2283 engines/agos/saveload.cpp:197
+#: engines/scumm/scumm.cpp:2290 engines/agos/saveload.cpp:197
#, c-format
msgid ""
"Successfully saved game state in file:\n"
@@ -1897,7 +1921,7 @@ msgid ""
"%s"
msgstr ""
-#: engines/scumm/scumm.cpp:2498
+#: engines/scumm/scumm.cpp:2505
msgid ""
"Usually, Maniac Mansion would start now. But ScummVM doesn't do that yet. To "
"play it, go to 'Add Game' in the ScummVM start menu and select the 'Maniac' "
@@ -1934,11 +1958,11 @@ msgstr "ScummVM Hovudmeny"
msgid "~W~ater Effect Enabled"
msgstr "~V~anneffekt aktivert"
-#: engines/sci/engine/kfile.cpp:685
+#: engines/sci/engine/kfile.cpp:673
msgid "Restore game:"
msgstr "Gjenopprett spel:"
-#: engines/sci/engine/kfile.cpp:685
+#: engines/sci/engine/kfile.cpp:673
msgid "Restore"
msgstr "Gjenopprett"
@@ -1948,11 +1972,11 @@ msgid "Cutscene file '%s' not found!"
msgstr ""
#: engines/gob/inter_playtoons.cpp:256 engines/gob/inter_v2.cpp:1283
-#: engines/tinsel/saveload.cpp:482
+#: engines/tinsel/saveload.cpp:502
msgid "Failed to load game state from file."
msgstr ""
-#: engines/gob/inter_v2.cpp:1353 engines/tinsel/saveload.cpp:560
+#: engines/gob/inter_v2.cpp:1353 engines/tinsel/saveload.cpp:515
msgid "Failed to save game state to file."
msgstr ""
@@ -1965,6 +1989,60 @@ msgstr ""
msgid "Failed to save game"
msgstr "Full speltittel:"
+#: engines/kyra/lol.cpp:478
+msgid "Attack 1"
+msgstr ""
+
+#: engines/kyra/lol.cpp:479
+msgid "Attack 2"
+msgstr ""
+
+#: engines/kyra/lol.cpp:480
+msgid "Attack 3"
+msgstr ""
+
+#: engines/kyra/lol.cpp:481
+msgid "Move Forward"
+msgstr ""
+
+#: engines/kyra/lol.cpp:482
+msgid "Move Back"
+msgstr ""
+
+#: engines/kyra/lol.cpp:483
+msgid "Slide Left"
+msgstr ""
+
+#: engines/kyra/lol.cpp:484
+#, fuzzy
+msgid "Slide Right"
+msgstr "Høgre"
+
+#: engines/kyra/lol.cpp:485
+#, fuzzy
+msgid "Turn Left"
+msgstr "Slå av"
+
+#: engines/kyra/lol.cpp:486
+#, fuzzy
+msgid "Turn Right"
+msgstr "Peikar høgre"
+
+#: engines/kyra/lol.cpp:487
+#, fuzzy
+msgid "Rest"
+msgstr "Gjenopprett"
+
+#: engines/kyra/lol.cpp:488
+#, fuzzy
+msgid "Options"
+msgstr "~V~al"
+
+#: engines/kyra/lol.cpp:489
+#, fuzzy
+msgid "Choose Spell"
+msgstr "Vel"
+
#: engines/kyra/sound_midi.cpp:475
msgid ""
"You appear to be using a General MIDI device,\n"
@@ -1974,11 +2052,6 @@ msgid ""
"that a few tracks will not be correctly played."
msgstr ""
-#: engines/m4/m4_menus.cpp:138
-#, fuzzy
-msgid "Save game failed!"
-msgstr "Lagra spel:"
-
#: engines/sky/compact.cpp:130
msgid ""
"Unable to find \"sky.cpt\" file!\n"
@@ -1991,15 +2064,20 @@ msgid ""
"Please (re)download it from www.scummvm.org"
msgstr ""
-#: engines/sword1/animation.cpp:344 engines/sword2/animation.cpp:379
+#: engines/sword1/animation.cpp:539
+#, c-format
+msgid "PSX stream cutscene '%s' cannot be played in paletted mode"
+msgstr ""
+
+#: engines/sword1/animation.cpp:560 engines/sword2/animation.cpp:455
msgid "DXA cutscenes found but ScummVM has been built without zlib support"
msgstr ""
-#: engines/sword1/animation.cpp:354 engines/sword2/animation.cpp:389
+#: engines/sword1/animation.cpp:570 engines/sword2/animation.cpp:465
msgid "MPEG2 cutscenes are no longer supported"
msgstr ""
-#: engines/sword1/animation.cpp:359 engines/sword2/animation.cpp:397
+#: engines/sword1/animation.cpp:576 engines/sword2/animation.cpp:473
#, c-format
msgid "Cutscene '%s' not found"
msgstr ""
@@ -2034,6 +2112,11 @@ msgstr ""
msgid "This is the end of the Broken Sword 1 Demo"
msgstr ""
+#: engines/sword2/animation.cpp:435
+msgid ""
+"PSX cutscenes found but ScummVM has been built without RGB color support"
+msgstr ""
+
#: engines/parallaction/saveload.cpp:133
#, c-format
msgid ""
@@ -2081,33 +2164,33 @@ msgstr "MAME OPL emulator"
msgid "DOSBox OPL emulator"
msgstr "DOSBox OPL emulator"
-#: audio/mididrv.cpp:205
+#: audio/mididrv.cpp:209
#, c-format
msgid ""
"The selected audio device '%s' was not found (e.g. might be turned off or "
"disconnected)."
msgstr ""
-#: audio/mididrv.cpp:205 audio/mididrv.cpp:217 audio/mididrv.cpp:253
-#: audio/mididrv.cpp:268
+#: audio/mididrv.cpp:209 audio/mididrv.cpp:221 audio/mididrv.cpp:257
+#: audio/mididrv.cpp:272
msgid "Attempting to fall back to the next available device..."
msgstr ""
-#: audio/mididrv.cpp:217
+#: audio/mididrv.cpp:221
#, c-format
msgid ""
"The selected audio device '%s' cannot be used. See log file for more "
"information."
msgstr ""
-#: audio/mididrv.cpp:253
+#: audio/mididrv.cpp:257
#, c-format
msgid ""
"The preferred audio device '%s' was not found (e.g. might be turned off or "
"disconnected)."
msgstr ""
-#: audio/mididrv.cpp:268
+#: audio/mididrv.cpp:272
#, c-format
msgid ""
"The preferred audio device '%s' cannot be used. See log file for more "
@@ -2122,7 +2205,7 @@ msgstr "Ingen musikk"
msgid "Amiga Audio Emulator"
msgstr "Amiga Lydemulator"
-#: audio/softsynth/adlib.cpp:1594
+#: audio/softsynth/adlib.cpp:1593
msgid "AdLib Emulator"
msgstr "AdLib Emulator"
@@ -2134,12 +2217,12 @@ msgstr "Apple II GS Emulator (IKKJE IMPLEMENTERT)"
msgid "C64 Audio Emulator"
msgstr "C64 Lydemulator"
-#: audio/softsynth/mt32.cpp:329
+#: audio/softsynth/mt32.cpp:293
#, fuzzy
msgid "Initializing MT-32 Emulator"
msgstr "Initialiserar MT-32-emulator"
-#: audio/softsynth/mt32.cpp:543
+#: audio/softsynth/mt32.cpp:512
msgid "MT-32 Emulator"
msgstr "MT-32 Emulator"
@@ -2155,15 +2238,24 @@ msgstr "IBM PCjr Emulator"
msgid "Keymap:"
msgstr "Tastkopling:"
-#: backends/keymapper/remap-dialog.cpp:64
+#: backends/keymapper/remap-dialog.cpp:66
+#, fuzzy
+msgid " (Effective)"
+msgstr " (Aktivt)"
+
+#: backends/keymapper/remap-dialog.cpp:106
msgid " (Active)"
msgstr " (Aktivt)"
-#: backends/keymapper/remap-dialog.cpp:98
+#: backends/keymapper/remap-dialog.cpp:106
+msgid " (Blocked)"
+msgstr ""
+
+#: backends/keymapper/remap-dialog.cpp:119
msgid " (Global)"
msgstr " (Global)"
-#: backends/keymapper/remap-dialog.cpp:108
+#: backends/keymapper/remap-dialog.cpp:127
msgid " (Game)"
msgstr " (Spel)"
@@ -2243,42 +2335,65 @@ msgstr ""
msgid "Disable power off"
msgstr "Deaktiver strømsparing"
-#: backends/platform/iphone/osys_events.cpp:338
+#: backends/platform/iphone/osys_events.cpp:301
msgid "Mouse-click-and-drag mode enabled."
msgstr ""
-#: backends/platform/iphone/osys_events.cpp:340
+#: backends/platform/iphone/osys_events.cpp:303
msgid "Mouse-click-and-drag mode disabled."
msgstr ""
-#: backends/platform/iphone/osys_events.cpp:351
+#: backends/platform/iphone/osys_events.cpp:314
msgid "Touchpad mode enabled."
msgstr ""
-#: backends/platform/iphone/osys_events.cpp:353
+#: backends/platform/iphone/osys_events.cpp:316
msgid "Touchpad mode disabled."
msgstr ""
-#: backends/platform/sdl/macosx/appmenu_osx.mm:67
+#: backends/platform/maemo/maemo.cpp:205
+msgid "Click Mode"
+msgstr ""
+
+#: backends/platform/maemo/maemo.cpp:211
+#: backends/platform/symbian/src/SymbianActions.cpp:42
+#: backends/platform/wince/CEActionsPocket.cpp:60
+#: backends/platform/wince/CEActionsSmartphone.cpp:43
+#: backends/platform/bada/form.cpp:281
+msgid "Left Click"
+msgstr "Venstreklikk"
+
+#: backends/platform/maemo/maemo.cpp:214
+#, fuzzy
+msgid "Middle Click"
+msgstr "Midtre venstre gjenstand"
+
+#: backends/platform/maemo/maemo.cpp:217
+#: backends/platform/symbian/src/SymbianActions.cpp:43
+#: backends/platform/wince/CEActionsSmartphone.cpp:44
+#: backends/platform/bada/form.cpp:273
+msgid "Right Click"
+msgstr "Høgreklikk"
+
+#: backends/platform/sdl/macosx/appmenu_osx.mm:78
#, fuzzy
msgid "Hide ScummVM"
msgstr "Avslutt ScummVM"
-#: backends/platform/sdl/macosx/appmenu_osx.mm:70
+#: backends/platform/sdl/macosx/appmenu_osx.mm:83
msgid "Hide Others"
msgstr ""
-#: backends/platform/sdl/macosx/appmenu_osx.mm:74
+#: backends/platform/sdl/macosx/appmenu_osx.mm:88
msgid "Show All"
msgstr ""
-#: backends/platform/sdl/macosx/appmenu_osx.mm:92
-#: backends/platform/sdl/macosx/appmenu_osx.mm:99
-#, fuzzy
+#: backends/platform/sdl/macosx/appmenu_osx.mm:110
+#: backends/platform/sdl/macosx/appmenu_osx.mm:121
msgid "Window"
-msgstr "Windows MIDI"
+msgstr ""
-#: backends/platform/sdl/macosx/appmenu_osx.mm:95
+#: backends/platform/sdl/macosx/appmenu_osx.mm:115
msgid "Minimize"
msgstr ""
@@ -2292,13 +2407,13 @@ msgid "Normal (no scaling)"
msgstr "Normal (inga skalering)"
#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2147
-#: backends/graphics/openglsdl/openglsdl-graphics.cpp:537
+#: backends/graphics/openglsdl/openglsdl-graphics.cpp:533
#, fuzzy
msgid "Enabled aspect ratio correction"
msgstr "Veksle aspekt-korrigering"
#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2153
-#: backends/graphics/openglsdl/openglsdl-graphics.cpp:542
+#: backends/graphics/openglsdl/openglsdl-graphics.cpp:538
#, fuzzy
msgid "Disabled aspect ratio correction"
msgstr "Veksle aspekt-korrigering"
@@ -2309,7 +2424,7 @@ msgid "Active graphics filter:"
msgstr "Veksle grafikkfiltre"
#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2250
-#: backends/graphics/openglsdl/openglsdl-graphics.cpp:481
+#: backends/graphics/openglsdl/openglsdl-graphics.cpp:477
#, fuzzy
msgid "Windowed mode"
msgstr "Teiknemodus:"
@@ -2335,11 +2450,11 @@ msgstr "Gjeldende videomodus:"
msgid "Current scale"
msgstr ""
-#: backends/graphics/openglsdl/openglsdl-graphics.cpp:562
+#: backends/graphics/openglsdl/openglsdl-graphics.cpp:558
msgid "Active filter mode: Linear"
msgstr ""
-#: backends/graphics/openglsdl/openglsdl-graphics.cpp:564
+#: backends/graphics/openglsdl/openglsdl-graphics.cpp:560
msgid "Active filter mode: Nearest"
msgstr ""
@@ -2363,19 +2478,6 @@ msgstr "Venstre"
msgid "Right"
msgstr "Høgre"
-#: backends/platform/symbian/src/SymbianActions.cpp:42
-#: backends/platform/wince/CEActionsPocket.cpp:60
-#: backends/platform/wince/CEActionsSmartphone.cpp:43
-#: backends/platform/bada/form.cpp:281
-msgid "Left Click"
-msgstr "Venstreklikk"
-
-#: backends/platform/symbian/src/SymbianActions.cpp:43
-#: backends/platform/wince/CEActionsSmartphone.cpp:44
-#: backends/platform/bada/form.cpp:273
-msgid "Right Click"
-msgstr "Høgreklikk"
-
#: backends/platform/symbian/src/SymbianActions.cpp:46
#: backends/platform/wince/CEActionsSmartphone.cpp:47
msgid "Zone"
@@ -2665,17 +2767,17 @@ msgstr ""
"Ikkje gløym å kople ein tast til 'Skjul verktøylinje' for å se heile "
"inventaret"
-#: backends/events/default/default-events.cpp:222
+#: backends/events/default/default-events.cpp:191
#, fuzzy
msgid "Do you really want to return to the Launcher?"
msgstr "Vil du verkeleg slette det lagra spelet?"
-#: backends/events/default/default-events.cpp:222
+#: backends/events/default/default-events.cpp:191
#, fuzzy
msgid "Launcher"
msgstr "Slå"
-#: backends/events/default/default-events.cpp:244
+#: backends/events/default/default-events.cpp:213
#, fuzzy
msgid "Do you really want to quit?"
msgstr "Vil du avslutte?"
@@ -2748,14 +2850,32 @@ msgstr "Syn tastatur"
msgid "Control Mouse"
msgstr ""
-#: backends/events/maemosdl/maemosdl-events.cpp:121
+#: backends/events/maemosdl/maemosdl-events.cpp:192
msgid "Clicking Enabled"
msgstr ""
-#: backends/events/maemosdl/maemosdl-events.cpp:121
+#: backends/events/maemosdl/maemosdl-events.cpp:192
msgid "Clicking Disabled"
msgstr ""
+#~ msgid "Hercules Green"
+#~ msgstr "Hercules Grønn"
+
+#~ msgid "Hercules Amber"
+#~ msgstr "Hercules Raudgul"
+
+#~ msgctxt "lowres"
+#~ msgid "Hercules Green"
+#~ msgstr "Hercules Grønn"
+
+#~ msgctxt "lowres"
+#~ msgid "Hercules Amber"
+#~ msgstr "Hercules Raudgul"
+
+#, fuzzy
+#~ msgid "Save game failed!"
+#~ msgstr "Lagra spel:"
+
#~ msgctxt "lowres"
#~ msgid "Add Game..."
#~ msgstr "Legg til spill..."
diff --git a/po/pl_PL.po b/po/pl_PL.po
index 513ac79ce4..d74c40f47d 100644
--- a/po/pl_PL.po
+++ b/po/pl_PL.po
@@ -1,20 +1,20 @@
-# Polish translation for ScummVM.
-# Copyright (C) 2010-2011 ScummVM Team
-# This file is distributed under the same license as the ScummVM package.
-# Grajpopolsku.pl <grajpopolsku@gmail.com>, 2011.
-#
+# Polish translation for ScummVM.
+# Copyright (C) 2010-2012 ScummVM Team
+# This file is distributed under the same license as the ScummVM package.
+# Grajpopolsku.pl <grajpopolsku@gmail.com>, 2011.
+#
msgid ""
msgstr ""
"Project-Id-Version: ScummVM 1.3.0\n"
"Report-Msgid-Bugs-To: scummvm-devel@lists.sf.net\n"
-"POT-Creation-Date: 2011-10-19 13:42+0100\n"
-"PO-Revision-Date: 2011-05-02 12:09+0100\n"
-"Last-Translator: \n"
+"POT-Creation-Date: 2012-03-07 22:09+0000\n"
+"PO-Revision-Date: 2011-10-24 21:14+0100\n"
+"Last-Translator: Micha³ Zi±bkowski <mziab@o2.pl>\n"
"Language-Team: Grajpopolsku.pl <grajpopolsku@gmail.com>\n"
-"Language: Polski\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=iso-8859-2\n"
"Content-Transfer-Encoding: 8bit\n"
+"Language: Polski\n"
"X-Poedit-KeywordsList: _;gettext;gettext_noop\n"
"X-Poedit-Basepath: .\n"
"X-Poedit-Language: Polish\n"
@@ -47,13 +47,13 @@ msgid "Go up"
msgstr "W górê"
#: gui/browser.cpp:69 gui/chooser.cpp:45 gui/KeysDialog.cpp:43
-#: gui/launcher.cpp:312 gui/massadd.cpp:94 gui/options.cpp:1178
+#: gui/launcher.cpp:320 gui/massadd.cpp:94 gui/options.cpp:1253
#: gui/saveload.cpp:63 gui/saveload.cpp:155 gui/themebrowser.cpp:54
-#: engines/engine.cpp:436 engines/scumm/dialogs.cpp:190
+#: engines/engine.cpp:442 engines/scumm/dialogs.cpp:190
#: engines/sword1/control.cpp:865 engines/parallaction/saveload.cpp:281
#: backends/platform/wii/options.cpp:48
-#: backends/events/default/default-events.cpp:222
-#: backends/events/default/default-events.cpp:244
+#: backends/events/default/default-events.cpp:191
+#: backends/events/default/default-events.cpp:213
msgid "Cancel"
msgstr "Anuluj"
@@ -61,25 +61,30 @@ msgstr "Anuluj"
msgid "Choose"
msgstr "Wybierz"
-#: gui/gui-manager.cpp:116 engines/scumm/help.cpp:125
+#: gui/gui-manager.cpp:115 engines/scumm/help.cpp:125
#: engines/scumm/help.cpp:140 engines/scumm/help.cpp:165
#: engines/scumm/help.cpp:191 engines/scumm/help.cpp:209
#: backends/keymapper/remap-dialog.cpp:52
msgid "Close"
msgstr "Zamknij"
-#: gui/gui-manager.cpp:119
+#: gui/gui-manager.cpp:118
msgid "Mouse click"
msgstr "Klikniêcie"
-#: gui/gui-manager.cpp:122 base/main.cpp:283
+#: gui/gui-manager.cpp:122 base/main.cpp:288
msgid "Display keyboard"
msgstr "Wy¶wietl klawiaturê"
-#: gui/gui-manager.cpp:125 base/main.cpp:286
+#: gui/gui-manager.cpp:126 base/main.cpp:292
msgid "Remap keys"
msgstr "Dostosuj klawisze"
+#: gui/gui-manager.cpp:129 base/main.cpp:295
+#, fuzzy
+msgid "Toggle FullScreen"
+msgstr "W³±cz/wy³±cz pe³ny ekran"
+
#: gui/KeysDialog.h:36 gui/KeysDialog.cpp:145
msgid "Choose an action to map"
msgstr "Wybierz akcjê do przypisania"
@@ -88,16 +93,17 @@ msgstr "Wybierz akcjê do przypisania"
msgid "Map"
msgstr "Przypisz"
-#: gui/KeysDialog.cpp:42 gui/launcher.cpp:313 gui/launcher.cpp:936
-#: gui/launcher.cpp:940 gui/massadd.cpp:91 gui/options.cpp:1179
-#: engines/engine.cpp:359 engines/engine.cpp:370 engines/scumm/dialogs.cpp:192
-#: engines/scumm/scumm.cpp:1776 engines/agos/animation.cpp:551
+#: gui/KeysDialog.cpp:42 gui/launcher.cpp:321 gui/launcher.cpp:960
+#: gui/launcher.cpp:964 gui/massadd.cpp:91 gui/options.cpp:1254
+#: engines/engine.cpp:361 engines/engine.cpp:372 engines/scumm/dialogs.cpp:192
+#: engines/scumm/scumm.cpp:1775 engines/agos/animation.cpp:551
#: engines/groovie/script.cpp:420 engines/sky/compact.cpp:131
-#: engines/sky/compact.cpp:141 engines/sword1/animation.cpp:344
-#: engines/sword1/animation.cpp:354 engines/sword1/animation.cpp:360
-#: engines/sword1/control.cpp:865 engines/sword1/logic.cpp:1633
-#: engines/sword2/animation.cpp:379 engines/sword2/animation.cpp:389
-#: engines/sword2/animation.cpp:398 engines/parallaction/saveload.cpp:281
+#: engines/sky/compact.cpp:141 engines/sword1/animation.cpp:539
+#: engines/sword1/animation.cpp:560 engines/sword1/animation.cpp:570
+#: engines/sword1/animation.cpp:577 engines/sword1/control.cpp:865
+#: engines/sword1/logic.cpp:1633 engines/sword2/animation.cpp:435
+#: engines/sword2/animation.cpp:455 engines/sword2/animation.cpp:465
+#: engines/sword2/animation.cpp:474 engines/parallaction/saveload.cpp:281
#: backends/platform/wii/options.cpp:47
#: backends/platform/wince/CELauncherDialog.cpp:54
msgid "OK"
@@ -125,15 +131,15 @@ msgstr "Wybierz akcjê"
msgid "Press the key to associate"
msgstr "Wci¶nij klawisz do przypisania"
-#: gui/launcher.cpp:165
+#: gui/launcher.cpp:170
msgid "Game"
msgstr "Gra"
-#: gui/launcher.cpp:169
+#: gui/launcher.cpp:174
msgid "ID:"
msgstr "ID:"
-#: gui/launcher.cpp:169 gui/launcher.cpp:171 gui/launcher.cpp:172
+#: gui/launcher.cpp:174 gui/launcher.cpp:176 gui/launcher.cpp:177
msgid ""
"Short game identifier used for referring to savegames and running the game "
"from the command line"
@@ -141,317 +147,315 @@ msgstr ""
"Krótki identyfikator gry u¿ywany do rozpoznawania zapisów i uruchamiania gry "
"z linii komend"
-#: gui/launcher.cpp:171
+#: gui/launcher.cpp:176
msgctxt "lowres"
msgid "ID:"
msgstr "ID:"
-#: gui/launcher.cpp:176
+#: gui/launcher.cpp:181
msgid "Name:"
msgstr "Nazwa:"
-#: gui/launcher.cpp:176 gui/launcher.cpp:178 gui/launcher.cpp:179
+#: gui/launcher.cpp:181 gui/launcher.cpp:183 gui/launcher.cpp:184
msgid "Full title of the game"
msgstr "Pe³ny tytu³ gry:"
-#: gui/launcher.cpp:178
+#: gui/launcher.cpp:183
msgctxt "lowres"
msgid "Name:"
msgstr "Nazwa:"
-#: gui/launcher.cpp:182
+#: gui/launcher.cpp:187
msgid "Language:"
msgstr "Jêzyk:"
-#: gui/launcher.cpp:182 gui/launcher.cpp:183
+#: gui/launcher.cpp:187 gui/launcher.cpp:188
msgid ""
"Language of the game. This will not turn your Spanish game version into "
"English"
msgstr "Jêzyk gry. Nie zmieni to hiszpañskiej wersji gry w angielsk±."
-#: gui/launcher.cpp:184 gui/launcher.cpp:198 gui/options.cpp:74
-#: gui/options.cpp:708 gui/options.cpp:718 gui/options.cpp:1149
+#: gui/launcher.cpp:189 gui/launcher.cpp:203 gui/options.cpp:80
+#: gui/options.cpp:745 gui/options.cpp:758 gui/options.cpp:1224
#: audio/null.cpp:40
msgid "<default>"
msgstr "<domy¶lne>"
-#: gui/launcher.cpp:194
+#: gui/launcher.cpp:199
msgid "Platform:"
msgstr "Platforma:"
-#: gui/launcher.cpp:194 gui/launcher.cpp:196 gui/launcher.cpp:197
+#: gui/launcher.cpp:199 gui/launcher.cpp:201 gui/launcher.cpp:202
msgid "Platform the game was originally designed for"
msgstr "Platforma, na któr± stworzono grê"
-#: gui/launcher.cpp:196
+#: gui/launcher.cpp:201
msgctxt "lowres"
msgid "Platform:"
msgstr "Platforma:"
-#: gui/launcher.cpp:208 gui/options.cpp:1018 gui/options.cpp:1035
+#: gui/launcher.cpp:213 gui/options.cpp:1087 gui/options.cpp:1104
msgid "Graphics"
msgstr "Grafika"
-#: gui/launcher.cpp:208 gui/options.cpp:1018 gui/options.cpp:1035
+#: gui/launcher.cpp:213 gui/options.cpp:1087 gui/options.cpp:1104
msgid "GFX"
msgstr "Grafika"
-#: gui/launcher.cpp:211
+#: gui/launcher.cpp:216
msgid "Override global graphic settings"
msgstr "U¿yj w³asnych ustawieñ grafiki"
-#: gui/launcher.cpp:213
+#: gui/launcher.cpp:218
msgctxt "lowres"
msgid "Override global graphic settings"
msgstr "U¿yj w³asnych ustawieñ grafiki"
-#: gui/launcher.cpp:220 gui/options.cpp:1041
+#: gui/launcher.cpp:225 gui/options.cpp:1110
msgid "Audio"
msgstr "D¼wiêk"
-#: gui/launcher.cpp:223
+#: gui/launcher.cpp:228
msgid "Override global audio settings"
msgstr "U¿yj w³asnych ustawieñ d¼wiêku"
-#: gui/launcher.cpp:225
+#: gui/launcher.cpp:230
msgctxt "lowres"
msgid "Override global audio settings"
msgstr "U¿yj w³asnych ustawieñ d¼wiêku"
-#: gui/launcher.cpp:234 gui/options.cpp:1046
+#: gui/launcher.cpp:239 gui/options.cpp:1115
msgid "Volume"
msgstr "G³o¶no¶æ"
-#: gui/launcher.cpp:236 gui/options.cpp:1048
+#: gui/launcher.cpp:241 gui/options.cpp:1117
msgctxt "lowres"
msgid "Volume"
msgstr "G³o¶no¶æ"
-#: gui/launcher.cpp:239
+#: gui/launcher.cpp:244
msgid "Override global volume settings"
msgstr "U¿yj w³asnych ustawieñ g³o¶no¶ci"
-#: gui/launcher.cpp:241
+#: gui/launcher.cpp:246
msgctxt "lowres"
msgid "Override global volume settings"
msgstr "U¿yj w³asnych ustawieñ g³o¶no¶ci"
-#: gui/launcher.cpp:248 gui/options.cpp:1056
+#: gui/launcher.cpp:254 gui/options.cpp:1125
msgid "MIDI"
msgstr "MIDI"
-#: gui/launcher.cpp:251
+#: gui/launcher.cpp:257
msgid "Override global MIDI settings"
msgstr "U¿yj w³asnych ustawieñ MIDI"
-#: gui/launcher.cpp:253
+#: gui/launcher.cpp:259
msgctxt "lowres"
msgid "Override global MIDI settings"
msgstr "U¿yj w³asnych ustawieñ MIDI"
-#: gui/launcher.cpp:263 gui/options.cpp:1062
+#: gui/launcher.cpp:268 gui/options.cpp:1131
msgid "MT-32"
msgstr "MT-32"
-#: gui/launcher.cpp:266
+#: gui/launcher.cpp:271
msgid "Override global MT-32 settings"
msgstr "U¿yj w³asnych ustawieñ MT-32"
-#: gui/launcher.cpp:268
+#: gui/launcher.cpp:273
msgctxt "lowres"
msgid "Override global MT-32 settings"
msgstr "U¿yj w³asnych ustawieñ MT-32"
-#: gui/launcher.cpp:279 gui/options.cpp:1069
+#: gui/launcher.cpp:282 gui/options.cpp:1138
msgid "Paths"
msgstr "¦cie¿ki"
-#: gui/launcher.cpp:281 gui/options.cpp:1071
+#: gui/launcher.cpp:284 gui/options.cpp:1140
msgctxt "lowres"
msgid "Paths"
msgstr "¦cie¿ki"
-#: gui/launcher.cpp:288
+#: gui/launcher.cpp:291
msgid "Game Path:"
msgstr "¦cie¿ka gry:"
-#: gui/launcher.cpp:290
+#: gui/launcher.cpp:293
msgctxt "lowres"
msgid "Game Path:"
msgstr "¦cie¿ka gry:"
-#: gui/launcher.cpp:295 gui/options.cpp:1091
+#: gui/launcher.cpp:298 gui/options.cpp:1164
msgid "Extra Path:"
msgstr "¦c. dodatków:"
-#: gui/launcher.cpp:295 gui/launcher.cpp:297 gui/launcher.cpp:298
+#: gui/launcher.cpp:298 gui/launcher.cpp:300 gui/launcher.cpp:301
msgid "Specifies path to additional data used the game"
msgstr "Okre¶la ¶cie¿kê dodatkowych danych gry"
-#: gui/launcher.cpp:297 gui/options.cpp:1093
+#: gui/launcher.cpp:300 gui/options.cpp:1166
msgctxt "lowres"
msgid "Extra Path:"
msgstr "¦c. dodatków:"
-#: gui/launcher.cpp:302 gui/options.cpp:1079
+#: gui/launcher.cpp:307 gui/options.cpp:1148
msgid "Save Path:"
msgstr "¦cie¿ka zapisów:"
-#: gui/launcher.cpp:302 gui/launcher.cpp:304 gui/launcher.cpp:305
-#: gui/options.cpp:1079 gui/options.cpp:1081 gui/options.cpp:1082
+#: gui/launcher.cpp:307 gui/launcher.cpp:309 gui/launcher.cpp:310
+#: gui/options.cpp:1148 gui/options.cpp:1150 gui/options.cpp:1151
msgid "Specifies where your savegames are put"
msgstr "Okre¶la gdzie zapisywaæ stan gry"
-#: gui/launcher.cpp:304 gui/options.cpp:1081
+#: gui/launcher.cpp:309 gui/options.cpp:1150
msgctxt "lowres"
msgid "Save Path:"
msgstr "¦cie¿ka zapisów:"
-#: gui/launcher.cpp:321 gui/launcher.cpp:404 gui/launcher.cpp:453
-#: gui/options.cpp:1088 gui/options.cpp:1094 gui/options.cpp:1101
-#: gui/options.cpp:1202 gui/options.cpp:1208 gui/options.cpp:1214
-#: gui/options.cpp:1222 gui/options.cpp:1246 gui/options.cpp:1250
-#: gui/options.cpp:1256 gui/options.cpp:1263 gui/options.cpp:1362
+#: gui/launcher.cpp:329 gui/launcher.cpp:416 gui/launcher.cpp:469
+#: gui/launcher.cpp:523 gui/options.cpp:1159 gui/options.cpp:1167
+#: gui/options.cpp:1176 gui/options.cpp:1283 gui/options.cpp:1289
+#: gui/options.cpp:1297 gui/options.cpp:1327 gui/options.cpp:1333
+#: gui/options.cpp:1340 gui/options.cpp:1433 gui/options.cpp:1436
+#: gui/options.cpp:1448
msgctxt "path"
msgid "None"
msgstr "Brak"
-#: gui/launcher.cpp:326 gui/launcher.cpp:408
+#: gui/launcher.cpp:334 gui/launcher.cpp:422 gui/launcher.cpp:527
+#: gui/options.cpp:1277 gui/options.cpp:1321 gui/options.cpp:1439
#: backends/platform/wii/options.cpp:56
msgid "Default"
msgstr "Domy¶lnie"
-#: gui/launcher.cpp:446 gui/options.cpp:1356
+#: gui/launcher.cpp:462 gui/options.cpp:1442
msgid "Select SoundFont"
msgstr "Wybierz SoundFont"
-#: gui/launcher.cpp:465 gui/launcher.cpp:612
+#: gui/launcher.cpp:481 gui/launcher.cpp:636
msgid "Select directory with game data"
msgstr "Wybierz katalog z plikami gry"
-#: gui/launcher.cpp:483
+#: gui/launcher.cpp:499
msgid "Select additional game directory"
msgstr "Wybierz dodatkowy katalog gry"
-#: gui/launcher.cpp:495
+#: gui/launcher.cpp:511
msgid "Select directory for saved games"
msgstr "Wybierz katalog dla zapisów"
-#: gui/launcher.cpp:514
+#: gui/launcher.cpp:538
msgid "This game ID is already taken. Please choose another one."
msgstr "Identyfikator jest ju¿ zajêty. Wybierz inny."
-#: gui/launcher.cpp:555 engines/dialogs.cpp:110
+#: gui/launcher.cpp:579 engines/dialogs.cpp:110
msgid "~Q~uit"
msgstr "~Z~akoñcz"
-#: gui/launcher.cpp:555 backends/platform/sdl/macosx/appmenu_osx.mm:80
+#: gui/launcher.cpp:579 backends/platform/sdl/macosx/appmenu_osx.mm:96
msgid "Quit ScummVM"
msgstr "Zakoñcz ScummVM"
-#: gui/launcher.cpp:556
+#: gui/launcher.cpp:580
msgid "A~b~out..."
msgstr "I~n~formacje..."
-#: gui/launcher.cpp:556 backends/platform/sdl/macosx/appmenu_osx.mm:61
+#: gui/launcher.cpp:580 backends/platform/sdl/macosx/appmenu_osx.mm:70
msgid "About ScummVM"
-msgstr "O ScummVM"
+msgstr "Ksi±¿ka ScummVM"
-#: gui/launcher.cpp:557
+#: gui/launcher.cpp:581
msgid "~O~ptions..."
msgstr "~O~pcje..."
-#: gui/launcher.cpp:557
+#: gui/launcher.cpp:581
msgid "Change global ScummVM options"
msgstr "Zmieñ ustawienia ScummVM"
-#: gui/launcher.cpp:559
+#: gui/launcher.cpp:583
msgid "~S~tart"
msgstr "~S~tart"
-#: gui/launcher.cpp:559
+#: gui/launcher.cpp:583
msgid "Start selected game"
msgstr "Rozpocznij wybran± grê"
-#: gui/launcher.cpp:562
+#: gui/launcher.cpp:586
msgid "~L~oad..."
msgstr "~W~czytaj..."
-#: gui/launcher.cpp:562
+#: gui/launcher.cpp:586
msgid "Load savegame for selected game"
msgstr "Wczytaj zapis wybranej gry"
-#: gui/launcher.cpp:567 gui/launcher.cpp:1055
+#: gui/launcher.cpp:591 gui/launcher.cpp:1079
msgid "~A~dd Game..."
msgstr "~D~odaj grê..."
-#: gui/launcher.cpp:567 gui/launcher.cpp:574
+#: gui/launcher.cpp:591 gui/launcher.cpp:598
msgid "Hold Shift for Mass Add"
msgstr "Przytrzymaj Shift, by dodawaæ zbiorowo"
-#: gui/launcher.cpp:569
+#: gui/launcher.cpp:593
msgid "~E~dit Game..."
msgstr "~E~dytuj grê..."
-#: gui/launcher.cpp:569 gui/launcher.cpp:576
+#: gui/launcher.cpp:593 gui/launcher.cpp:600
msgid "Change game options"
msgstr "Zmieñ opcje gry"
-#: gui/launcher.cpp:571
+#: gui/launcher.cpp:595
msgid "~R~emove Game"
msgstr "~U~suñ grê"
-#: gui/launcher.cpp:571 gui/launcher.cpp:578
+#: gui/launcher.cpp:595 gui/launcher.cpp:602
msgid "Remove game from the list. The game data files stay intact"
msgstr "Usuwa grê z listy. Pliki gry pozostaj± nietkniête"
-#: gui/launcher.cpp:574 gui/launcher.cpp:1055
+#: gui/launcher.cpp:598 gui/launcher.cpp:1079
msgctxt "lowres"
msgid "~A~dd Game..."
msgstr "~D~odaj grê..."
-#: gui/launcher.cpp:576
+#: gui/launcher.cpp:600
msgctxt "lowres"
msgid "~E~dit Game..."
msgstr "~E~dytuj grê..."
-#: gui/launcher.cpp:578
+#: gui/launcher.cpp:602
msgctxt "lowres"
msgid "~R~emove Game"
msgstr "~U~suñ grê"
-#: gui/launcher.cpp:586
+#: gui/launcher.cpp:610
msgid "Search in game list"
msgstr "Wyszukaj grê na li¶cie"
-#: gui/launcher.cpp:590 gui/launcher.cpp:1102
+#: gui/launcher.cpp:614 gui/launcher.cpp:1126
msgid "Search:"
msgstr "Szukaj"
-#: gui/launcher.cpp:593 gui/options.cpp:826
-msgid "Clear value"
-msgstr "Wyczy¶æ"
-
-#: gui/launcher.cpp:615 engines/dialogs.cpp:114 engines/mohawk/myst.cpp:255
+#: gui/launcher.cpp:639 engines/dialogs.cpp:114 engines/mohawk/myst.cpp:255
#: engines/mohawk/riven.cpp:716 engines/cruise/menu.cpp:216
msgid "Load game:"
msgstr "Wczytaj grê:"
-#: gui/launcher.cpp:615 engines/dialogs.cpp:114 engines/scumm/dialogs.cpp:188
+#: gui/launcher.cpp:639 engines/dialogs.cpp:114 engines/scumm/dialogs.cpp:188
#: engines/mohawk/myst.cpp:255 engines/mohawk/riven.cpp:716
#: engines/cruise/menu.cpp:216 backends/platform/wince/CEActionsPocket.cpp:267
#: backends/platform/wince/CEActionsSmartphone.cpp:231
msgid "Load"
msgstr "Wczytaj"
-#: gui/launcher.cpp:723
+#: gui/launcher.cpp:747
msgid ""
"Do you really want to run the mass game detector? This could potentially add "
"a huge number of games."
msgstr ""
"Chcesz uruchomiæ masowy detektor gier? Mo¿e dodaæ wiele tytu³ów do listy"
-#: gui/launcher.cpp:724 gui/launcher.cpp:872
+#: gui/launcher.cpp:748 gui/launcher.cpp:896
#: backends/events/symbiansdl/symbiansdl-events.cpp:184
#: backends/platform/wince/CEActionsPocket.cpp:326
#: backends/platform/wince/CEActionsSmartphone.cpp:287
@@ -459,7 +463,7 @@ msgstr ""
msgid "Yes"
msgstr "Tak"
-#: gui/launcher.cpp:724 gui/launcher.cpp:872
+#: gui/launcher.cpp:748 gui/launcher.cpp:896
#: backends/events/symbiansdl/symbiansdl-events.cpp:184
#: backends/platform/wince/CEActionsPocket.cpp:326
#: backends/platform/wince/CEActionsSmartphone.cpp:287
@@ -467,36 +471,36 @@ msgstr "Tak"
msgid "No"
msgstr "Nie"
-#: gui/launcher.cpp:772
+#: gui/launcher.cpp:796
msgid "ScummVM couldn't open the specified directory!"
msgstr "ScummVM nie mo¿e otworzyæ katalogu!"
-#: gui/launcher.cpp:784
+#: gui/launcher.cpp:808
msgid "ScummVM could not find any game in the specified directory!"
msgstr "ScummVM nie znalaz³ ¿adnej gry w tym katalogu!"
-#: gui/launcher.cpp:798
+#: gui/launcher.cpp:822
msgid "Pick the game:"
msgstr "Wybierz grê:"
-#: gui/launcher.cpp:872
+#: gui/launcher.cpp:896
msgid "Do you really want to remove this game configuration?"
msgstr "Na pewno chcesz usun±æ tê grê z konfiguracji?"
-#: gui/launcher.cpp:936
+#: gui/launcher.cpp:960
msgid "This game does not support loading games from the launcher."
msgstr "Ta gra nie wspiera wczytywania z launchera."
-#: gui/launcher.cpp:940
+#: gui/launcher.cpp:964
msgid "ScummVM could not find any engine capable of running the selected game!"
msgstr "ScummVM nie znalaz³ silnika zdolnego uruchomiæ wybran± grê!"
-#: gui/launcher.cpp:1054
+#: gui/launcher.cpp:1078
msgctxt "lowres"
msgid "Mass Add..."
msgstr "Masowe dodawanie..."
-#: gui/launcher.cpp:1054
+#: gui/launcher.cpp:1078
msgid "Mass Add..."
msgstr "Masowe dodawanie..."
@@ -511,7 +515,7 @@ msgstr "Skanowanie zakoñczone!"
#: gui/massadd.cpp:261
#, c-format
msgid "Discovered %d new games, ignored %d previously added games."
-msgstr ""
+msgstr "Wykryto %d nowych gier, zignorowano %d poprzednio dodanych."
#: gui/massadd.cpp:265
#, c-format
@@ -519,145 +523,145 @@ msgid "Scanned %d directories ..."
msgstr "Przeskanowano %d katalogów ..."
#: gui/massadd.cpp:268
-#, fuzzy, c-format
+#, c-format
msgid "Discovered %d new games, ignored %d previously added games ..."
-msgstr "Wykryto %d nowych gier..."
+msgstr "Wykryto %d nowych gier, zignorowano %d poprzednio dodanych..."
-#: gui/options.cpp:72
+#: gui/options.cpp:78
msgid "Never"
msgstr "Nigdy"
-#: gui/options.cpp:72
+#: gui/options.cpp:78
msgid "every 5 mins"
msgstr "co 5 min"
-#: gui/options.cpp:72
+#: gui/options.cpp:78
msgid "every 10 mins"
msgstr "co 10 min"
-#: gui/options.cpp:72
+#: gui/options.cpp:78
msgid "every 15 mins"
msgstr "co 15 min"
-#: gui/options.cpp:72
+#: gui/options.cpp:78
msgid "every 30 mins"
msgstr "co 30 min"
-#: gui/options.cpp:74
+#: gui/options.cpp:80
msgid "8 kHz"
msgstr "8 kHz"
-#: gui/options.cpp:74
+#: gui/options.cpp:80
msgid "11kHz"
msgstr "11 kHz"
-#: gui/options.cpp:74
+#: gui/options.cpp:80
msgid "22 kHz"
msgstr "22 kHz"
-#: gui/options.cpp:74
+#: gui/options.cpp:80
msgid "44 kHz"
msgstr "44 kHz"
-#: gui/options.cpp:74
+#: gui/options.cpp:80
msgid "48 kHz"
msgstr "48 kHz"
-#: gui/options.cpp:236 gui/options.cpp:464 gui/options.cpp:559
-#: gui/options.cpp:625 gui/options.cpp:825
+#: gui/options.cpp:257 gui/options.cpp:485 gui/options.cpp:586
+#: gui/options.cpp:659 gui/options.cpp:868
msgctxt "soundfont"
msgid "None"
msgstr "Brak"
-#: gui/options.cpp:372
+#: gui/options.cpp:393
msgid "Failed to apply some of the graphic options changes:"
-msgstr ""
+msgstr "Nie uda³o siê zastosowaæ czê¶ci zmian opcji grafiki:"
-#: gui/options.cpp:384
+#: gui/options.cpp:405
msgid "the video mode could not be changed."
-msgstr ""
+msgstr "nie uda³o siê zmieniæ trybu wideo."
-#: gui/options.cpp:390
+#: gui/options.cpp:411
msgid "the fullscreen setting could not be changed"
-msgstr ""
+msgstr "nie uda³o siê zmieniæ trybu pe³noekranowego"
-#: gui/options.cpp:396
+#: gui/options.cpp:417
msgid "the aspect ratio setting could not be changed"
-msgstr ""
+msgstr "nie uda³o siê zmieniæ formatu obrazu"
-#: gui/options.cpp:705
+#: gui/options.cpp:742
msgid "Graphics mode:"
msgstr "Tryb grafiki:"
-#: gui/options.cpp:716
+#: gui/options.cpp:756
msgid "Render mode:"
msgstr "Renderer:"
-#: gui/options.cpp:716 gui/options.cpp:717
+#: gui/options.cpp:756 gui/options.cpp:757
msgid "Special dithering modes supported by some games"
msgstr "Specjalne tryby ditheringu wspierane przez niektóre gry"
-#: gui/options.cpp:726
+#: gui/options.cpp:768
#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2248
-#: backends/graphics/openglsdl/openglsdl-graphics.cpp:476
+#: backends/graphics/openglsdl/openglsdl-graphics.cpp:472
msgid "Fullscreen mode"
-msgstr "Tryb pe³noekranowy"
+msgstr "Pe³ny ekran"
-#: gui/options.cpp:729
+#: gui/options.cpp:771
msgid "Aspect ratio correction"
msgstr "Korekcja formatu obrazu"
-#: gui/options.cpp:729
+#: gui/options.cpp:771
msgid "Correct aspect ratio for 320x200 games"
msgstr "Korekcja formatu obrazu dla gier 320x200"
-#: gui/options.cpp:730
+#: gui/options.cpp:772
msgid "EGA undithering"
-msgstr "anty-dithering EGA"
+msgstr "Anty-dithering EGA"
-#: gui/options.cpp:730
+#: gui/options.cpp:772
msgid "Enable undithering in EGA games that support it"
msgstr "W³±cz anty-dithering we wspieranych grach EGA"
-#: gui/options.cpp:738
+#: gui/options.cpp:780
msgid "Preferred Device:"
msgstr "Pref. urz±dzenie:"
-#: gui/options.cpp:738
+#: gui/options.cpp:780
msgid "Music Device:"
msgstr "Urz. muzyczne:"
-#: gui/options.cpp:738 gui/options.cpp:740
+#: gui/options.cpp:780 gui/options.cpp:782
msgid "Specifies preferred sound device or sound card emulator"
msgstr "Okre¶la preferowane urz±dzenie d¼wiêkowe lub emulator karty d¼wiêkowej"
-#: gui/options.cpp:738 gui/options.cpp:740 gui/options.cpp:741
+#: gui/options.cpp:780 gui/options.cpp:782 gui/options.cpp:783
msgid "Specifies output sound device or sound card emulator"
msgstr "Okre¶la wyj¶ciowe urz±dzenie d¼wiêkowe lub emulator karty d¼wiêkowej"
-#: gui/options.cpp:740
+#: gui/options.cpp:782
msgctxt "lowres"
msgid "Preferred Dev.:"
msgstr "Pref. urz±dzenie:"
-#: gui/options.cpp:740
+#: gui/options.cpp:782
msgctxt "lowres"
msgid "Music Device:"
msgstr "Urz. muzyczne:"
-#: gui/options.cpp:766
+#: gui/options.cpp:809
msgid "AdLib emulator:"
msgstr "Emulator AdLib:"
-#: gui/options.cpp:766 gui/options.cpp:767
+#: gui/options.cpp:809 gui/options.cpp:810
msgid "AdLib is used for music in many games"
msgstr "AdLib jest u¿ywany do muzyki w wielu grach"
-#: gui/options.cpp:777
+#: gui/options.cpp:820
msgid "Output rate:"
msgstr "Czêst. wyj.:"
-#: gui/options.cpp:777 gui/options.cpp:778
+#: gui/options.cpp:820 gui/options.cpp:821
msgid ""
"Higher value specifies better sound quality but may be not supported by your "
"soundcard"
@@ -665,63 +669,63 @@ msgstr ""
"Wy¿sze warto¶ci daj± lepsz± jako¶æ d¼wiêku, ale mog± byæ nieobs³ugiwane "
"przez twoj± kartê d¼wiêkow±"
-#: gui/options.cpp:788
+#: gui/options.cpp:831
msgid "GM Device:"
msgstr "Urz±dzenie GM:"
-#: gui/options.cpp:788
+#: gui/options.cpp:831
msgid "Specifies default sound device for General MIDI output"
msgstr "Okre¶la domy¶lne urz±dzenie d¼wiêkowe dla wyj¶cia General MIDI"
-#: gui/options.cpp:799
+#: gui/options.cpp:842
msgid "Don't use General MIDI music"
msgstr "Nie u¿ywaj muzyki General MIDI"
-#: gui/options.cpp:810 gui/options.cpp:871
+#: gui/options.cpp:853 gui/options.cpp:915
msgid "Use first available device"
msgstr "U¿yj pierwszego dostêpnego urz±dzenia"
-#: gui/options.cpp:822
+#: gui/options.cpp:865
msgid "SoundFont:"
msgstr "SoundFont:"
-#: gui/options.cpp:822 gui/options.cpp:824 gui/options.cpp:825
+#: gui/options.cpp:865 gui/options.cpp:867 gui/options.cpp:868
msgid "SoundFont is supported by some audio cards, Fluidsynth and Timidity"
msgstr ""
"SoundFont jest wspierany przez niektóre karty d¼wiêkowe, Fluidsynth i "
"Timidity"
-#: gui/options.cpp:824
+#: gui/options.cpp:867
msgctxt "lowres"
msgid "SoundFont:"
msgstr "SoundFont:"
-#: gui/options.cpp:829
+#: gui/options.cpp:873
msgid "Mixed AdLib/MIDI mode"
msgstr "Tryb miksowanego AdLib/MIDI"
-#: gui/options.cpp:829
+#: gui/options.cpp:873
msgid "Use both MIDI and AdLib sound generation"
msgstr "U¿ywaj obu generatorów d¼wiêku, MIDI i AdLib, jednocze¶nie"
-#: gui/options.cpp:832
+#: gui/options.cpp:876
msgid "MIDI gain:"
msgstr "Wzm. MIDI:"
-#: gui/options.cpp:842
+#: gui/options.cpp:886
msgid "MT-32 Device:"
msgstr "Urz±dzenie MT-32:"
-#: gui/options.cpp:842
+#: gui/options.cpp:886
msgid "Specifies default sound device for Roland MT-32/LAPC1/CM32l/CM64 output"
msgstr ""
"Okre¶la domy¶lne urz±dzenie d¼wiêku dla wyj¶cia Roland MT-32/LAPC1/CM32l/CM64"
-#: gui/options.cpp:847
+#: gui/options.cpp:891
msgid "True Roland MT-32 (disable GM emulation)"
msgstr "Prawdziwy Roland MT-32 (wy³±cz emulacjê GM)"
-#: gui/options.cpp:847 gui/options.cpp:849
+#: gui/options.cpp:891 gui/options.cpp:893
msgid ""
"Check if you want to use your real hardware Roland-compatible sound device "
"connected to your computer"
@@ -729,192 +733,191 @@ msgstr ""
"Zaznacz, je¶li chcesz u¿ywaæ swojej prawdziwej karty kompatybilnej z Roland "
"pod³±czonej do twojego komputera"
-#: gui/options.cpp:849
+#: gui/options.cpp:893
msgctxt "lowres"
msgid "True Roland MT-32 (no GM emulation)"
msgstr "Prawdziwy Roland MT-32 (brak emulacji GM)"
-#: gui/options.cpp:852
+#: gui/options.cpp:896
msgid "Enable Roland GS Mode"
msgstr "W³±cz tryb Roland GS"
-#: gui/options.cpp:852
+#: gui/options.cpp:896
msgid "Turns off General MIDI mapping for games with Roland MT-32 soundtrack"
msgstr ""
"Wy³±cza mapowanie General MIDI dla gier ze ¶cie¿k± d¼wiêkow± Roland MT-32"
-#: gui/options.cpp:861
+#: gui/options.cpp:905
msgid "Don't use Roland MT-32 music"
msgstr "Nie u¿ywaj muzyki Roland MT-32"
-#: gui/options.cpp:888
+#: gui/options.cpp:932
msgid "Text and Speech:"
msgstr "Tekst i mowa:"
-#: gui/options.cpp:892 gui/options.cpp:902
+#: gui/options.cpp:936 gui/options.cpp:946
msgid "Speech"
msgstr "Mowa"
-#: gui/options.cpp:893 gui/options.cpp:903
+#: gui/options.cpp:937 gui/options.cpp:947
msgid "Subtitles"
msgstr "Napisy"
-#: gui/options.cpp:894
+#: gui/options.cpp:938
msgid "Both"
msgstr "Oba"
-#: gui/options.cpp:896
+#: gui/options.cpp:940
msgid "Subtitle speed:"
msgstr "Prêd. napisów:"
-#: gui/options.cpp:898
+#: gui/options.cpp:942
msgctxt "lowres"
msgid "Text and Speech:"
msgstr "Tekst i mowa:"
-#: gui/options.cpp:902
+#: gui/options.cpp:946
msgid "Spch"
msgstr "Mowa"
-#: gui/options.cpp:903
+#: gui/options.cpp:947
msgid "Subs"
msgstr "Napisy"
-#: gui/options.cpp:904
+#: gui/options.cpp:948
msgctxt "lowres"
msgid "Both"
msgstr "Oba"
-#: gui/options.cpp:904
+#: gui/options.cpp:948
msgid "Show subtitles and play speech"
msgstr "Wy¶wietlaj napisy i odtwarzaj mowê"
-#: gui/options.cpp:906
+#: gui/options.cpp:950
msgctxt "lowres"
msgid "Subtitle speed:"
msgstr "Prêd. napisów:"
-#: gui/options.cpp:922
+#: gui/options.cpp:966
msgid "Music volume:"
msgstr "G³o¶no¶æ muzyki:"
-#: gui/options.cpp:924
+#: gui/options.cpp:968
msgctxt "lowres"
msgid "Music volume:"
msgstr "G³o¶no¶æ muzyki:"
-#: gui/options.cpp:931
+#: gui/options.cpp:975
msgid "Mute All"
msgstr "Wycisz"
-#: gui/options.cpp:934
+#: gui/options.cpp:978
msgid "SFX volume:"
msgstr "G³. efekt. d¼w.:"
-#: gui/options.cpp:934 gui/options.cpp:936 gui/options.cpp:937
+#: gui/options.cpp:978 gui/options.cpp:980 gui/options.cpp:981
msgid "Special sound effects volume"
msgstr "G³o¶no¶æ efektów d¼w."
-#: gui/options.cpp:936
+#: gui/options.cpp:980
msgctxt "lowres"
msgid "SFX volume:"
msgstr "G³. efekt. d¼w.:"
-#: gui/options.cpp:944
+#: gui/options.cpp:988
msgid "Speech volume:"
msgstr "G³o¶no¶æ mowy:"
-#: gui/options.cpp:946
+#: gui/options.cpp:990
msgctxt "lowres"
msgid "Speech volume:"
msgstr "G³o¶no¶æ mowy:"
-#: gui/options.cpp:1085
+#: gui/options.cpp:1156
msgid "Theme Path:"
msgstr "¦cie¿ka stylu:"
-#: gui/options.cpp:1087
+#: gui/options.cpp:1158
msgctxt "lowres"
msgid "Theme Path:"
msgstr "¦cie¿ka stylu:"
-#: gui/options.cpp:1091 gui/options.cpp:1093 gui/options.cpp:1094
+#: gui/options.cpp:1164 gui/options.cpp:1166 gui/options.cpp:1167
msgid "Specifies path to additional data used by all games or ScummVM"
msgstr "Okre¶la ¶cie¿kê dla dodatkowych danych dla wszystkich gier lub ScummVM"
-#: gui/options.cpp:1098
+#: gui/options.cpp:1173
msgid "Plugins Path:"
msgstr "¦cie¿ka wtyczek:"
-#: gui/options.cpp:1100
+#: gui/options.cpp:1175
msgctxt "lowres"
msgid "Plugins Path:"
msgstr "¦cie¿ka wtyczek:"
-#: gui/options.cpp:1109
+#: gui/options.cpp:1184
msgid "Misc"
msgstr "Ró¿ne"
-#: gui/options.cpp:1111
+#: gui/options.cpp:1186
msgctxt "lowres"
msgid "Misc"
msgstr "Ró¿ne"
-#: gui/options.cpp:1113
+#: gui/options.cpp:1188
msgid "Theme:"
msgstr "Styl:"
-#: gui/options.cpp:1117
+#: gui/options.cpp:1192
msgid "GUI Renderer:"
msgstr "Renderer interf.:"
-#: gui/options.cpp:1129
+#: gui/options.cpp:1204
msgid "Autosave:"
msgstr "Autozapis:"
-#: gui/options.cpp:1131
+#: gui/options.cpp:1206
msgctxt "lowres"
msgid "Autosave:"
msgstr "Autozapis:"
-#: gui/options.cpp:1139
+#: gui/options.cpp:1214
msgid "Keys"
msgstr "Klawisze"
-#: gui/options.cpp:1146
+#: gui/options.cpp:1221
msgid "GUI Language:"
msgstr "Jêzyk interfejsu:"
-#: gui/options.cpp:1146
+#: gui/options.cpp:1221
msgid "Language of ScummVM GUI"
msgstr "Jêzyk interfejsu ScummVM"
-#: gui/options.cpp:1295
-#, fuzzy
+#: gui/options.cpp:1372
msgid "You have to restart ScummVM before your changes will take effect."
-msgstr "Musisz zrestartowaæ ScummVM, by zmiany zosta³y uwzglêdnione"
+msgstr "Musisz zrestartowaæ ScummVM, by zmiany zosta³y uwzglêdnione."
-#: gui/options.cpp:1308
+#: gui/options.cpp:1385
msgid "Select directory for savegames"
msgstr "Wybierz katalog zapisów"
-#: gui/options.cpp:1315
+#: gui/options.cpp:1392
msgid "The chosen directory cannot be written to. Please select another one."
msgstr "Ten katalog jest zabezpieczony przed zapisem. Wybierz inny."
-#: gui/options.cpp:1324
+#: gui/options.cpp:1401
msgid "Select directory for GUI themes"
msgstr "Wybierz katalog dla stylów GUI."
-#: gui/options.cpp:1334
+#: gui/options.cpp:1411
msgid "Select directory for extra files"
msgstr "Wybierz katalog dla dodatkowych plików"
-#: gui/options.cpp:1345
+#: gui/options.cpp:1422
msgid "Select directory for plugins"
msgstr "Wybierz katalog dla wtyczek"
-#: gui/options.cpp:1389
+#: gui/options.cpp:1475
msgid ""
"The theme you selected does not support your current language. If you want "
"to use this theme you need to switch to another language first."
@@ -962,60 +965,64 @@ msgstr "Zapis bez nazwy"
msgid "Select a Theme"
msgstr "Wybierz styl"
-#: gui/ThemeEngine.cpp:328
+#: gui/ThemeEngine.cpp:333
msgid "Disabled GFX"
msgstr "Wy³±czona grafika"
-#: gui/ThemeEngine.cpp:328
+#: gui/ThemeEngine.cpp:333
msgctxt "lowres"
msgid "Disabled GFX"
msgstr "Wy³±czona grafika"
-#: gui/ThemeEngine.cpp:329
+#: gui/ThemeEngine.cpp:334
msgid "Standard Renderer (16bpp)"
msgstr "Standardowy renderer (16bpp)"
-#: gui/ThemeEngine.cpp:329
+#: gui/ThemeEngine.cpp:334
msgid "Standard (16bpp)"
msgstr "Standardowy (16bpp)"
-#: gui/ThemeEngine.cpp:331
+#: gui/ThemeEngine.cpp:336
msgid "Antialiased Renderer (16bpp)"
msgstr "Wyg³adzany renderer (16bpp)"
-#: gui/ThemeEngine.cpp:331
+#: gui/ThemeEngine.cpp:336
msgid "Antialiased (16bpp)"
msgstr "Wyg³adzany (16bpp)"
+#: gui/widget.cpp:312 gui/widget.cpp:314 gui/widget.cpp:320 gui/widget.cpp:322
+msgid "Clear value"
+msgstr "Wyczy¶æ"
+
#: base/main.cpp:203
#, c-format
msgid "Engine does not support debug level '%s'"
msgstr "Silnik nie wspiera poziomu debugowania '%s'"
-#: base/main.cpp:271
+#: base/main.cpp:275
msgid "Menu"
msgstr "Menu"
-#: base/main.cpp:274 backends/platform/symbian/src/SymbianActions.cpp:45
+#: base/main.cpp:278 backends/platform/symbian/src/SymbianActions.cpp:45
#: backends/platform/wince/CEActionsPocket.cpp:45
#: backends/platform/wince/CEActionsSmartphone.cpp:46
msgid "Skip"
msgstr "Pomiñ"
-#: base/main.cpp:277 backends/platform/symbian/src/SymbianActions.cpp:50
+#: base/main.cpp:281 backends/platform/symbian/src/SymbianActions.cpp:50
#: backends/platform/wince/CEActionsPocket.cpp:42
msgid "Pause"
msgstr "Wstrzymaj"
-#: base/main.cpp:280
+#: base/main.cpp:284
msgid "Skip line"
msgstr "Pomiñ liniê"
-#: base/main.cpp:439
+#: base/main.cpp:455
msgid "Error running game:"
msgstr "B³±d podczas uruchamiania gry:"
-#: base/main.cpp:463
+#: base/main.cpp:479
msgid "Could not find any engine capable of running the selected game"
msgstr "Nie uda³o siê znale¼æ silnika zdolnego do uruchomienia zaznaczonej gry"
@@ -1077,43 +1084,24 @@ msgstr "Silnik nie wspiera zapisu stanu gry"
#: common/error.cpp:71
msgid "User canceled"
-msgstr ""
+msgstr "Przerwane przez u¿ytkownika"
#: common/error.cpp:75
msgid "Unknown error"
msgstr "Nieznany b³±d"
-#. I18N: Hercules is graphics card name
-#: common/util.cpp:275
-msgid "Hercules Green"
-msgstr "Zielony Hercules"
-
-#: common/util.cpp:276
-msgid "Hercules Amber"
-msgstr "Bursztynowy Hercules"
-
-#: common/util.cpp:283
-msgctxt "lowres"
-msgid "Hercules Green"
-msgstr "Zielony Hercules"
-
-#: common/util.cpp:284
-msgctxt "lowres"
-msgid "Hercules Amber"
-msgstr "Bursztynowy Hercules"
-
#: engines/advancedDetector.cpp:296
#, c-format
msgid "The game in '%s' seems to be unknown."
-msgstr ""
+msgstr "Gra w '%s' wygl±da na nieznan±."
#: engines/advancedDetector.cpp:297
msgid "Please, report the following data to the ScummVM team along with name"
-msgstr ""
+msgstr "Przeka¿ poni¿sze dane zespo³owi ScummVM razem z nazw±"
#: engines/advancedDetector.cpp:299
msgid "of the game you tried to add and its version/language/etc.:"
-msgstr ""
+msgstr "gry, któr± próbowa³e¶ dodaæ oraz jej wersj±, jêzykiem itd.:"
#: engines/dialogs.cpp:84
msgid "~R~esume"
@@ -1149,12 +1137,12 @@ msgid "~R~eturn to Launcher"
msgstr "~P~owrót do launchera"
#: engines/dialogs.cpp:116 engines/cruise/menu.cpp:214
-#: engines/sci/engine/kfile.cpp:578
+#: engines/sci/engine/kfile.cpp:566
msgid "Save game:"
msgstr "Zapis:"
#: engines/dialogs.cpp:116 engines/scumm/dialogs.cpp:187
-#: engines/cruise/menu.cpp:214 engines/sci/engine/kfile.cpp:578
+#: engines/cruise/menu.cpp:214 engines/sci/engine/kfile.cpp:566
#: backends/platform/symbian/src/SymbianActions.cpp:44
#: backends/platform/wince/CEActionsPocket.cpp:43
#: backends/platform/wince/CEActionsPocket.cpp:267
@@ -1169,40 +1157,51 @@ msgid ""
"the README for basic information, and for instructions on how to obtain "
"further assistance."
msgstr ""
+"Przepraszamy, ten silnik obecnie nie oferuje pomocy wewn±trz gry. Aby "
+"uzyskaæ podstawowe informacje oraz dowiedzieæ jak szukaæ dalszej pomocy, "
+"sprawd¼ plik README."
-#: engines/dialogs.cpp:316 engines/mohawk/dialogs.cpp:109
+#: engines/dialogs.cpp:243
+#, fuzzy, c-format
+msgid ""
+"Gamestate save failed (%s)! Please consult the README for basic information, "
+"and for instructions on how to obtain further assistance."
+msgstr ""
+"Przepraszamy, ten silnik obecnie nie oferuje pomocy wewn±trz gry. Aby "
+"uzyskaæ podstawowe informacje oraz dowiedzieæ jak szukaæ dalszej pomocy, "
+"sprawd¼ plik README."
+
+#: engines/dialogs.cpp:321 engines/mohawk/dialogs.cpp:109
#: engines/mohawk/dialogs.cpp:174
msgid "~O~K"
msgstr "~O~K"
-#: engines/dialogs.cpp:317 engines/mohawk/dialogs.cpp:110
+#: engines/dialogs.cpp:322 engines/mohawk/dialogs.cpp:110
#: engines/mohawk/dialogs.cpp:175
msgid "~C~ancel"
msgstr "~A~nuluj"
-#: engines/dialogs.cpp:320
+#: engines/dialogs.cpp:325
msgid "~K~eys"
msgstr "~K~lawisze"
-#: engines/engine.cpp:233
+#: engines/engine.cpp:235
msgid "Could not initialize color format."
-msgstr ""
+msgstr "Nie uda³o siê zainicjalizowaæ formatu kolorów."
-#: engines/engine.cpp:241
-#, fuzzy
+#: engines/engine.cpp:243
msgid "Could not switch to video mode: '"
-msgstr "Obecny tryb wideo:"
+msgstr "Nie uda³o siê prze³±czyæ w tryb wideo: '"
-#: engines/engine.cpp:250
-#, fuzzy
+#: engines/engine.cpp:252
msgid "Could not apply aspect ratio setting."
-msgstr "W³±cz/wy³±cz korekcjê formatu obrazu"
+msgstr "Nie uda³o siê zastosowaæ ustawienia formatu obrazu."
-#: engines/engine.cpp:255
+#: engines/engine.cpp:257
msgid "Could not apply fullscreen setting."
-msgstr ""
+msgstr "Nie uda³o siê zastosowaæ ustawienia pe³nego ekranu."
-#: engines/engine.cpp:355
+#: engines/engine.cpp:357
msgid ""
"You appear to be playing this game directly\n"
"from the CD. This is known to cause problems,\n"
@@ -1210,8 +1209,11 @@ msgid ""
"the data files to your hard disk instead.\n"
"See the README file for details."
msgstr ""
+"Wygl±da na to, ¿e uruchamiasz grê bezpo¶rednio z p³yty CD, co powoduje pewne "
+"znane problemów. St±d zalecane jest skopiowanie plików gry na twardy dysk.\n"
+"Dalsze informacje s± dostêpne w pliku README."
-#: engines/engine.cpp:366
+#: engines/engine.cpp:368
msgid ""
"This game has audio tracks in its disk. These\n"
"tracks need to be ripped from the disk using\n"
@@ -1219,112 +1221,125 @@ msgid ""
"order to listen to the game's music.\n"
"See the README file for details."
msgstr ""
+"Gra zawiera na swojej p³ycie ¶cie¿ki audio. Aby s³yszeæ muzykê, nale¿y je "
+"skopiowaæ na dysk za pomoc± odpowiedniego rippera CD audio.\n"
+"Dalsze informacje s± dostêpne w pliku README."
+
+#: engines/engine.cpp:426
+#, fuzzy, c-format
+msgid ""
+"Gamestate load failed (%s)! Please consult the README for basic information, "
+"and for instructions on how to obtain further assistance."
+msgstr ""
+"Przepraszamy, ten silnik obecnie nie oferuje pomocy wewn±trz gry. Aby "
+"uzyskaæ podstawowe informacje oraz dowiedzieæ jak szukaæ dalszej pomocy, "
+"sprawd¼ plik README."
-#: engines/engine.cpp:433
+#: engines/engine.cpp:439
msgid ""
"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."
msgstr ""
+"UWAGA: Gra, któr± chcesz w³±czyæ, nie jest jeszcze w pe³ni obs³ugiwana przez "
+"ScummVM. W zwi±zku z tym mo¿e byæ ona niestabilna, a wszelkie zapisy, "
+"których dokonasz, mog± byæ nieobs³ugiwane w przysz³ych wersjach ScummVM."
-#: engines/engine.cpp:436
+#: engines/engine.cpp:442
msgid "Start anyway"
-msgstr ""
+msgstr "W³±cz mimo tego"
#: engines/scumm/dialogs.cpp:175
#, c-format
msgid "Insert Disk %c and Press Button to Continue."
-msgstr ""
+msgstr "W³ó¿ dysk %c i naci¶nij przycisk, aby kontynuowaæ."
#: engines/scumm/dialogs.cpp:176
#, c-format
msgid "Unable to Find %s, (%c%d) Press Button."
-msgstr ""
+msgstr "Nie znaleziono %s, (%c%d). Naci¶nij przycisk."
#: engines/scumm/dialogs.cpp:177
#, c-format
msgid "Error reading disk %c, (%c%d) Press Button."
-msgstr ""
+msgstr "B³±d podczas odczytu dysku %c, (%c%d). Naci¶nij przycisk."
#: engines/scumm/dialogs.cpp:178
msgid "Game Paused. Press SPACE to Continue."
-msgstr ""
+msgstr "Gra wstrzymana. Naci¶nij spacjê, aby wznowiæ."
#. I18N: You may specify 'Yes' symbol at the end of the line, like this:
#. "Moechten Sie wirklich neu starten? (J/N)J"
#. Will react to J as 'Yes'
#: engines/scumm/dialogs.cpp:182
-#, fuzzy
msgid "Are you sure you want to restart? (Y/N)"
-msgstr " Na pewno chcesz wyj¶æ? "
+msgstr "Na pewno chcesz zrestartowaæ grê? (T/N)T"
#. I18N: you may specify 'Yes' symbol at the end of the line. See previous comment
#: engines/scumm/dialogs.cpp:184
-#, fuzzy
msgid "Are you sure you want to quit? (Y/N)"
-msgstr " Na pewno chcesz wyj¶æ? "
+msgstr "Na pewno chcesz wyj¶æ? (T/N)T"
#: engines/scumm/dialogs.cpp:189
msgid "Play"
-msgstr ""
+msgstr "Uruchom"
#: engines/scumm/dialogs.cpp:191 engines/scumm/help.cpp:82
#: engines/scumm/help.cpp:84
#: backends/platform/symbian/src/SymbianActions.cpp:52
#: backends/platform/wince/CEActionsPocket.cpp:44
#: backends/platform/wince/CEActionsSmartphone.cpp:52
-#: backends/events/default/default-events.cpp:244
+#: backends/events/default/default-events.cpp:213
msgid "Quit"
msgstr "Zakoñcz"
#: engines/scumm/dialogs.cpp:193
msgid "Insert save/load game disk"
-msgstr ""
+msgstr "W³ó¿ dysk zapisu"
#: engines/scumm/dialogs.cpp:194
msgid "You must enter a name"
-msgstr ""
+msgstr "Musisz podaæ nazwê"
#: engines/scumm/dialogs.cpp:195
msgid "The game was NOT saved (disk full?)"
-msgstr ""
+msgstr "NIE zapisano stanu gry (brak miejsca?)"
#: engines/scumm/dialogs.cpp:196
msgid "The game was NOT loaded"
-msgstr ""
+msgstr "NIE wczytano gry"
#: engines/scumm/dialogs.cpp:197
#, c-format
msgid "Saving '%s'"
-msgstr ""
+msgstr "Zapisywanie '%s'"
#: engines/scumm/dialogs.cpp:198
#, c-format
msgid "Loading '%s'"
-msgstr ""
+msgstr "Wczytywanie '%s'"
#: engines/scumm/dialogs.cpp:199
msgid "Name your SAVE game"
-msgstr ""
+msgstr "Podaj nazwê zapisu"
#: engines/scumm/dialogs.cpp:200
-#, fuzzy
msgid "Select a game to LOAD"
-msgstr "Wybierz styl"
+msgstr "Wybierz zapis do wczytania"
#: engines/scumm/dialogs.cpp:201
msgid "Game title)"
-msgstr ""
+msgstr "Tytu³ gry)"
#. I18N: Previous page button
#: engines/scumm/dialogs.cpp:287
msgid "~P~revious"
-msgstr "~P~oprzedni"
+msgstr "~P~oprzednia"
#. I18N: Next page button
#: engines/scumm/dialogs.cpp:289
msgid "~N~ext"
-msgstr "~N~astêpny"
+msgstr "~N~astêpna"
#: engines/scumm/dialogs.cpp:290
#: backends/platform/ds/arm9/source/dsoptions.cpp:56
@@ -1332,25 +1347,42 @@ msgid "~C~lose"
msgstr "~Z~amknij"
#: engines/scumm/dialogs.cpp:597
-#, fuzzy
msgid "Speech Only"
-msgstr "Mowa"
+msgstr "Tylko mowa"
#: engines/scumm/dialogs.cpp:598
-#, fuzzy
msgid "Speech and Subtitles"
-msgstr "Napisy"
+msgstr "Mowa i napisy"
#: engines/scumm/dialogs.cpp:599
-#, fuzzy
msgid "Subtitles Only"
-msgstr "Napisy"
+msgstr "Tylko napisy"
#: engines/scumm/dialogs.cpp:607
-#, fuzzy
msgctxt "lowres"
msgid "Speech & Subs"
-msgstr "Mowa"
+msgstr "Mowa i napisy"
+
+#: engines/scumm/dialogs.cpp:653
+msgid "Select a Proficiency Level."
+msgstr ""
+
+#: engines/scumm/dialogs.cpp:655
+msgid "Refer to your Loom(TM) manual for help."
+msgstr ""
+
+#: engines/scumm/dialogs.cpp:658
+#, fuzzy
+msgid "Standard"
+msgstr "Standardowy (16bpp)"
+
+#: engines/scumm/dialogs.cpp:659
+msgid "Practice"
+msgstr ""
+
+#: engines/scumm/dialogs.cpp:660
+msgid "Expert"
+msgstr ""
#: engines/scumm/help.cpp:73
msgid "Common keyboard commands:"
@@ -1483,7 +1515,6 @@ msgid " since they may cause crashes"
msgstr " poniewa¿ mog± one spowodowaæ zawieszenie siê,"
#: engines/scumm/help.cpp:110
-#, fuzzy
msgid " or incorrect game behavior."
msgstr " b±d¼ nieodpowiednie zachowanie gry."
@@ -1636,11 +1667,11 @@ msgstr "zagraj C-dur na k±dzieli"
#: engines/scumm/help.cpp:192 engines/scumm/help.cpp:214
msgid "puSh"
-msgstr "pchnj"
+msgstr "pchnij"
#: engines/scumm/help.cpp:193 engines/scumm/help.cpp:215
msgid "pull (Yank)"
-msgstr "poci±gnij (Yank)"
+msgstr "poci±gnij"
#: engines/scumm/help.cpp:196 engines/scumm/help.cpp:212
#: engines/scumm/help.cpp:248
@@ -1719,7 +1750,7 @@ msgstr "Zwyk³y kursor"
#. I18N: Comm is a communication device
#: engines/scumm/help.cpp:243
msgid "Comm"
-msgstr "Comm"
+msgstr "Kom."
#: engines/scumm/help.cpp:246
msgid "Save / Load / Options"
@@ -1866,14 +1897,16 @@ msgstr "Leæ w prawo"
msgid "Fly to lower right"
msgstr "Leæ w dó³, w prawo"
-#: engines/scumm/scumm.cpp:1774
+#: engines/scumm/scumm.cpp:1773
#, c-format
msgid ""
"Native MIDI support requires the Roland Upgrade from LucasArts,\n"
"but %s is missing. Using AdLib instead."
msgstr ""
+"Natywne wsparcie MIDI wymaga aktualizacji Rolanda od LucasArts,\n"
+"ale brakuje %s. Prze³±czam na tryb AdLib."
-#: engines/scumm/scumm.cpp:2264 engines/agos/saveload.cpp:189
+#: engines/scumm/scumm.cpp:2271 engines/agos/saveload.cpp:189
#, c-format
msgid ""
"Failed to save game state to file:\n"
@@ -1884,7 +1917,7 @@ msgstr ""
"\n"
"%s"
-#: engines/scumm/scumm.cpp:2271 engines/agos/saveload.cpp:154
+#: engines/scumm/scumm.cpp:2278 engines/agos/saveload.cpp:154
#, c-format
msgid ""
"Failed to load game state from file:\n"
@@ -1895,7 +1928,7 @@ msgstr ""
"\n"
"%s"
-#: engines/scumm/scumm.cpp:2283 engines/agos/saveload.cpp:197
+#: engines/scumm/scumm.cpp:2290 engines/agos/saveload.cpp:197
#, c-format
msgid ""
"Successfully saved game state in file:\n"
@@ -1906,7 +1939,7 @@ msgstr ""
"\n"
"%s"
-#: engines/scumm/scumm.cpp:2498
+#: engines/scumm/scumm.cpp:2505
msgid ""
"Usually, Maniac Mansion would start now. But ScummVM doesn't do that yet. To "
"play it, go to 'Add Game' in the ScummVM start menu and select the 'Maniac' "
@@ -1919,7 +1952,7 @@ msgstr ""
#. I18N: Option for fast scene switching
#: engines/mohawk/dialogs.cpp:92 engines/mohawk/dialogs.cpp:171
msgid "~Z~ip Mode Activated"
-msgstr "~T~ryb zip aktywny"
+msgstr "~T~ryb turbo aktywny"
#: engines/mohawk/dialogs.cpp:93
msgid "~T~ransitions Enabled"
@@ -1928,66 +1961,103 @@ msgstr "~P~rzej¶cia w³±czone"
#. I18N: Drop book page
#: engines/mohawk/dialogs.cpp:95
msgid "~D~rop Page"
-msgstr ""
+msgstr "~O~pu¶æ stronê"
#: engines/mohawk/dialogs.cpp:99
msgid "~S~how Map"
-msgstr ""
+msgstr "~P~oka¿ mapê"
#: engines/mohawk/dialogs.cpp:105
-#, fuzzy
msgid "~M~ain Menu"
-msgstr "G³ówne menu ScummVM"
+msgstr "~M~enu g³ówne"
#: engines/mohawk/dialogs.cpp:172
msgid "~W~ater Effect Enabled"
msgstr "~E~fekty wody w³±czone"
-#: engines/sci/engine/kfile.cpp:685
+#: engines/sci/engine/kfile.cpp:673
msgid "Restore game:"
msgstr "Wznów grê:"
-#: engines/sci/engine/kfile.cpp:685
+#: engines/sci/engine/kfile.cpp:673
msgid "Restore"
msgstr "Wznów"
#: engines/agos/animation.cpp:550
#, c-format
msgid "Cutscene file '%s' not found!"
-msgstr ""
+msgstr "Nie znaleziono pliku przerywnika '%s'!"
#: engines/gob/inter_playtoons.cpp:256 engines/gob/inter_v2.cpp:1283
-#: engines/tinsel/saveload.cpp:482
-#, fuzzy
+#: engines/tinsel/saveload.cpp:502
msgid "Failed to load game state from file."
-msgstr ""
-"Nie uda³o siê wczytaæ stanu gry z pliku:\n"
-"\n"
-"%s"
+msgstr "Nie uda³o siê wczytaæ stanu gry z pliku."
-#: engines/gob/inter_v2.cpp:1353 engines/tinsel/saveload.cpp:560
-#, fuzzy
+#: engines/gob/inter_v2.cpp:1353 engines/tinsel/saveload.cpp:515
msgid "Failed to save game state to file."
-msgstr ""
-"Nie uda³o siê zapisaæ stanu gry do pliku:\n"
-"\n"
-"%s"
+msgstr "Nie uda³o siê zapisaæ stanu gry do pliku."
#: engines/gob/inter_v5.cpp:107
-#, fuzzy
msgid "Failed to delete file."
-msgstr ""
-"Nie uda³o siê zapisaæ stanu gry do pliku:\n"
-"\n"
-"%s"
+msgstr "Nie uda³o siê usun±æ pliku."
#: engines/groovie/script.cpp:420
-#, fuzzy
msgid "Failed to save game"
+msgstr "Nie uda³o siê zapisaæ stanu gry"
+
+#: engines/kyra/lol.cpp:478
+msgid "Attack 1"
msgstr ""
-"Nie uda³o siê zapisaæ stanu gry do pliku:\n"
-"\n"
-"%s"
+
+#: engines/kyra/lol.cpp:479
+msgid "Attack 2"
+msgstr ""
+
+#: engines/kyra/lol.cpp:480
+msgid "Attack 3"
+msgstr ""
+
+#: engines/kyra/lol.cpp:481
+msgid "Move Forward"
+msgstr ""
+
+#: engines/kyra/lol.cpp:482
+msgid "Move Back"
+msgstr ""
+
+#: engines/kyra/lol.cpp:483
+msgid "Slide Left"
+msgstr ""
+
+#: engines/kyra/lol.cpp:484
+#, fuzzy
+msgid "Slide Right"
+msgstr "W prawo"
+
+#: engines/kyra/lol.cpp:485
+#, fuzzy
+msgid "Turn Left"
+msgstr "Wy³±cz"
+
+#: engines/kyra/lol.cpp:486
+#, fuzzy
+msgid "Turn Right"
+msgstr "Kursor w prawo"
+
+#: engines/kyra/lol.cpp:487
+#, fuzzy
+msgid "Rest"
+msgstr "Wznów"
+
+#: engines/kyra/lol.cpp:488
+#, fuzzy
+msgid "Options"
+msgstr "~O~pcje"
+
+#: engines/kyra/lol.cpp:489
+#, fuzzy
+msgid "Choose Spell"
+msgstr "Wybierz"
#: engines/kyra/sound_midi.cpp:475
msgid ""
@@ -1997,36 +2067,46 @@ msgid ""
"General MIDI ones. After all it might happen\n"
"that a few tracks will not be correctly played."
msgstr ""
-
-#: engines/m4/m4_menus.cpp:138
-#, fuzzy
-msgid "Save game failed!"
-msgstr "Zapis:"
+"Wygl±da na to, ¿e u¿ywasz urz±dzenia General MIDI, ale gra obs³uguje tylko "
+"MIDI Roland MT32.\n"
+"Próbujemy przypisaæ instrumenty Rolanda MT32 do instrumentów General MIDI. "
+"Niektóre utwory mog± byæ ¼le odtwarzane."
#: engines/sky/compact.cpp:130
msgid ""
"Unable to find \"sky.cpt\" file!\n"
"Please download it from www.scummvm.org"
msgstr ""
+"Nie znaleziono pliku \"sky.cpt\"!\n"
+"Pobierz go ze strony www.scummvm.org"
#: engines/sky/compact.cpp:141
msgid ""
"The \"sky.cpt\" file has an incorrect size.\n"
"Please (re)download it from www.scummvm.org"
msgstr ""
+"Plik \"sky.cpt\" ma nieprawid³owy rozmiar.\n"
+"Pobierz go (ponownie) ze strony www.scummvm.org"
-#: engines/sword1/animation.cpp:344 engines/sword2/animation.cpp:379
+#: engines/sword1/animation.cpp:539
+#, c-format
+msgid "PSX stream cutscene '%s' cannot be played in paletted mode"
+msgstr ""
+
+#: engines/sword1/animation.cpp:560 engines/sword2/animation.cpp:455
msgid "DXA cutscenes found but ScummVM has been built without zlib support"
msgstr ""
+"Znaleziono przerywniki w formacie DXA, ale ScummVM jest skompilowany bez "
+"obs³ugi zlib"
-#: engines/sword1/animation.cpp:354 engines/sword2/animation.cpp:389
+#: engines/sword1/animation.cpp:570 engines/sword2/animation.cpp:465
msgid "MPEG2 cutscenes are no longer supported"
-msgstr ""
+msgstr "Przerywniki w formacie MPEG2 nie s± ju¿ obs³ugiwane"
-#: engines/sword1/animation.cpp:359 engines/sword2/animation.cpp:397
+#: engines/sword1/animation.cpp:576 engines/sword2/animation.cpp:473
#, c-format
msgid "Cutscene '%s' not found"
-msgstr ""
+msgstr "Nie znaleziono przerywnika '%s'"
#: engines/sword1/control.cpp:863
msgid ""
@@ -2038,6 +2118,13 @@ msgid ""
"Press OK to convert them now, otherwise you will be asked again the next "
"time you start the game.\n"
msgstr ""
+"ScummVM znalaz³ stare zapisy z Broken Sword 1, które nale¿y "
+"przekonwertowaæ.\n"
+"Stary format zapisu nie jest ju¿ obs³ugiwany. Nie bêdziesz móg³ wczytaæ "
+"zapisów, je¶li ich nie przekonwertujesz.\n"
+"\n"
+"Naci¶nij OK, ¿eby je teraz przekonwertowaæ. W przeciwnym wypadku zostaniesz "
+"zapytany ponownie przy nastêpnym w³±czeniu gry.\n"
#: engines/sword1/control.cpp:1232
#, c-format
@@ -2045,18 +2132,28 @@ msgid ""
"Target new save game already exists!\n"
"Would you like to keep the old save game (%s) or the new one (%s)?\n"
msgstr ""
+"Docelowy plik nowego zapisu ju¿ istnieje!\n"
+"Chcesz zachowaæ stary zapis (%s) czy nowy (%s)?\n"
#: engines/sword1/control.cpp:1235
msgid "Keep the old one"
-msgstr ""
+msgstr "Zachowaj stary"
#: engines/sword1/control.cpp:1235
msgid "Keep the new one"
-msgstr ""
+msgstr "Zachowaj nowy"
#: engines/sword1/logic.cpp:1633
msgid "This is the end of the Broken Sword 1 Demo"
+msgstr "To koniec dema Broken Sword 1"
+
+#: engines/sword2/animation.cpp:435
+#, fuzzy
+msgid ""
+"PSX cutscenes found but ScummVM has been built without RGB color support"
msgstr ""
+"Znaleziono przerywniki w formacie DXA, ale ScummVM jest skompilowany bez "
+"obs³ugi zlib"
#: engines/parallaction/saveload.cpp:133
#, c-format
@@ -2064,16 +2161,16 @@ msgid ""
"Can't save game in slot %i\n"
"\n"
msgstr ""
+"Nie mo¿na zapisaæ w slocie %i\n"
+"\n"
#: engines/parallaction/saveload.cpp:211
-#, fuzzy
msgid "Loading game..."
-msgstr "Wczytaj grê:"
+msgstr "Wczytywanie stanu gry..."
#: engines/parallaction/saveload.cpp:226
-#, fuzzy
msgid "Saving game..."
-msgstr "Zapis:"
+msgstr "Zapisywanie stanu gry..."
#: engines/parallaction/saveload.cpp:279
msgid ""
@@ -2084,10 +2181,16 @@ msgid ""
"\n"
"Press OK to convert them now, otherwise you will be asked next time.\n"
msgstr ""
+"ScummVM znalaz³ stare zapisy z Nippon Safes, które nale¿y przekonwertowaæ.\n"
+"Stary format zapisu nie jest ju¿ obs³ugiwany. Nie bêdziesz móg³ wczytaæ "
+"zapisów, je¶li ich nie przekonwertujesz.\n"
+"\n"
+"Naci¶nij OK, ¿eby je teraz przekonwertowaæ. W przeciwnym wypadku zostaniesz "
+"zapytany ponownie przy nastêpnym w³±czeniu gry.\n"
#: engines/parallaction/saveload.cpp:326
msgid "ScummVM successfully converted all your savefiles."
-msgstr ""
+msgstr "ScummVM pomy¶lnie przekonwertowa³ wszystkie twoje zapisy."
#: engines/parallaction/saveload.cpp:328
msgid ""
@@ -2096,6 +2199,10 @@ msgid ""
"\n"
"Please report to the team."
msgstr ""
+"ScummVM wy¶wietli³ ostrze¿enia w oknie konsoli i nie mo¿e zagwarantowaæ, ¿e "
+"wszystkie twoje pliki zosta³y przekonwertowane.\n"
+"\n"
+"Prosimy o zg³oszenie tego zespo³owi."
#: audio/fmopl.cpp:49
msgid "MAME OPL emulator"
@@ -2105,38 +2212,46 @@ msgstr "Emulator OPL MAME"
msgid "DOSBox OPL emulator"
msgstr "Emulator OPL DOSBox"
-#: audio/mididrv.cpp:205
+#: audio/mididrv.cpp:209
#, c-format
msgid ""
"The selected audio device '%s' was not found (e.g. might be turned off or "
"disconnected)."
msgstr ""
+"Nie znaleziono wybranego urz±dzenia audio '%s' (mo¿e byæ wy³±czone albo "
+"niepod³±czone)."
-#: audio/mididrv.cpp:205 audio/mididrv.cpp:217 audio/mididrv.cpp:253
-#: audio/mididrv.cpp:268
+#: audio/mididrv.cpp:209 audio/mididrv.cpp:221 audio/mididrv.cpp:257
+#: audio/mididrv.cpp:272
msgid "Attempting to fall back to the next available device..."
-msgstr ""
+msgstr "Próbujê u¿yæ nastêpnego dostêpnego urz±dzenia..."
-#: audio/mididrv.cpp:217
+#: audio/mididrv.cpp:221
#, c-format
msgid ""
"The selected audio device '%s' cannot be used. See log file for more "
"information."
msgstr ""
+"Nie mo¿na u¿yæ wybranego urz±dzenia audio '%s'. Dalsze szczegó³y s± dostêpne "
+"w pliku dziennika."
-#: audio/mididrv.cpp:253
+#: audio/mididrv.cpp:257
#, c-format
msgid ""
"The preferred audio device '%s' was not found (e.g. might be turned off or "
"disconnected)."
msgstr ""
+"Nie znaleziono preferowanego urz±dzenia audio '%s' (mo¿e byæ wy³±czone albo "
+"niepod³±czone)."
-#: audio/mididrv.cpp:268
+#: audio/mididrv.cpp:272
#, c-format
msgid ""
"The preferred audio device '%s' cannot be used. See log file for more "
"information."
msgstr ""
+"Nie mo¿na u¿yæ preferowanego urz±dzenia audio '%s'. Dalsze szczegó³y s± "
+"dostêpne w pliku dziennika."
#: audio/null.h:43
msgid "No music"
@@ -2146,7 +2261,7 @@ msgstr "Brak muzyki"
msgid "Amiga Audio Emulator"
msgstr "Emulator d¼wiêku Amigi"
-#: audio/softsynth/adlib.cpp:1594
+#: audio/softsynth/adlib.cpp:1593
msgid "AdLib Emulator"
msgstr "Emulator AdLib"
@@ -2158,12 +2273,11 @@ msgstr "Emulator Apple II GS (NIE ZAIMPLEMENTOWANY)"
msgid "C64 Audio Emulator"
msgstr "Emulator d¼wiêku C64"
-#: audio/softsynth/mt32.cpp:329
-#, fuzzy
+#: audio/softsynth/mt32.cpp:293
msgid "Initializing MT-32 Emulator"
msgstr "Inicjalizacja emulatora MT-32"
-#: audio/softsynth/mt32.cpp:543
+#: audio/softsynth/mt32.cpp:512
msgid "MT-32 Emulator"
msgstr "Emulator MT-32"
@@ -2179,15 +2293,24 @@ msgstr "Emulator IBM PCjr"
msgid "Keymap:"
msgstr "Klawisze:"
-#: backends/keymapper/remap-dialog.cpp:64
+#: backends/keymapper/remap-dialog.cpp:66
+#, fuzzy
+msgid " (Effective)"
+msgstr " (Aktywny)"
+
+#: backends/keymapper/remap-dialog.cpp:106
msgid " (Active)"
msgstr " (Aktywny)"
-#: backends/keymapper/remap-dialog.cpp:98
+#: backends/keymapper/remap-dialog.cpp:106
+msgid " (Blocked)"
+msgstr ""
+
+#: backends/keymapper/remap-dialog.cpp:119
msgid " (Global)"
msgstr " (Globalny)"
-#: backends/keymapper/remap-dialog.cpp:108
+#: backends/keymapper/remap-dialog.cpp:127
msgid " (Game)"
msgstr " (Gra)"
@@ -2267,46 +2390,66 @@ msgstr "D¼wiêk wysokiej jako¶ci (wolniejszy) (restart)"
msgid "Disable power off"
msgstr "Nie wy³±czaj zasilania"
-#: backends/platform/iphone/osys_events.cpp:338
-#, fuzzy
+#: backends/platform/iphone/osys_events.cpp:301
msgid "Mouse-click-and-drag mode enabled."
-msgstr "Tryb touchpada w³±czony."
+msgstr "W³±czono tryb kliknij i przeci±gaj."
-#: backends/platform/iphone/osys_events.cpp:340
-#, fuzzy
+#: backends/platform/iphone/osys_events.cpp:303
msgid "Mouse-click-and-drag mode disabled."
-msgstr "Tryb touchpada wy³±czony."
+msgstr "Wy³±czono tryb kliknij i przeci±gaj."
-#: backends/platform/iphone/osys_events.cpp:351
+#: backends/platform/iphone/osys_events.cpp:314
msgid "Touchpad mode enabled."
msgstr "Tryb touchpada w³±czony."
-#: backends/platform/iphone/osys_events.cpp:353
+#: backends/platform/iphone/osys_events.cpp:316
msgid "Touchpad mode disabled."
msgstr "Tryb touchpada wy³±czony."
-#: backends/platform/sdl/macosx/appmenu_osx.mm:67
+#: backends/platform/maemo/maemo.cpp:205
+msgid "Click Mode"
+msgstr ""
+
+#: backends/platform/maemo/maemo.cpp:211
+#: backends/platform/symbian/src/SymbianActions.cpp:42
+#: backends/platform/wince/CEActionsPocket.cpp:60
+#: backends/platform/wince/CEActionsSmartphone.cpp:43
+#: backends/platform/bada/form.cpp:281
+msgid "Left Click"
+msgstr "Klikniêcie LPM"
+
+#: backends/platform/maemo/maemo.cpp:214
#, fuzzy
+msgid "Middle Click"
+msgstr "Przedmiot na ¶rodku, z lewej"
+
+#: backends/platform/maemo/maemo.cpp:217
+#: backends/platform/symbian/src/SymbianActions.cpp:43
+#: backends/platform/wince/CEActionsSmartphone.cpp:44
+#: backends/platform/bada/form.cpp:273
+msgid "Right Click"
+msgstr "Klikniêcie PPM"
+
+#: backends/platform/sdl/macosx/appmenu_osx.mm:78
msgid "Hide ScummVM"
-msgstr "Zakoñcz ScummVM"
+msgstr "Ukryj ScummVM"
-#: backends/platform/sdl/macosx/appmenu_osx.mm:70
+#: backends/platform/sdl/macosx/appmenu_osx.mm:83
msgid "Hide Others"
-msgstr ""
+msgstr "Ukryj pozosta³e"
-#: backends/platform/sdl/macosx/appmenu_osx.mm:74
+#: backends/platform/sdl/macosx/appmenu_osx.mm:88
msgid "Show All"
-msgstr ""
+msgstr "Poka¿ wszystkie"
-#: backends/platform/sdl/macosx/appmenu_osx.mm:92
-#: backends/platform/sdl/macosx/appmenu_osx.mm:99
-#, fuzzy
+#: backends/platform/sdl/macosx/appmenu_osx.mm:110
+#: backends/platform/sdl/macosx/appmenu_osx.mm:121
msgid "Window"
-msgstr "Windows MIDI"
+msgstr "Okno"
-#: backends/platform/sdl/macosx/appmenu_osx.mm:95
+#: backends/platform/sdl/macosx/appmenu_osx.mm:115
msgid "Minimize"
-msgstr ""
+msgstr "Miniaturka"
#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:45
msgid "Normal (no scaling)"
@@ -2318,27 +2461,23 @@ msgid "Normal (no scaling)"
msgstr "Zwyk³y (bez skalowania)"
#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2147
-#: backends/graphics/openglsdl/openglsdl-graphics.cpp:537
-#, fuzzy
+#: backends/graphics/openglsdl/openglsdl-graphics.cpp:533
msgid "Enabled aspect ratio correction"
-msgstr "W³±cz/wy³±cz korekcjê formatu obrazu"
+msgstr "W³±czono korekcjê formatu obrazu"
#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2153
-#: backends/graphics/openglsdl/openglsdl-graphics.cpp:542
-#, fuzzy
+#: backends/graphics/openglsdl/openglsdl-graphics.cpp:538
msgid "Disabled aspect ratio correction"
-msgstr "W³±cz/wy³±cz korekcjê formatu obrazu"
+msgstr "Wy³±czono korekcjê formatu obrazu"
#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2208
-#, fuzzy
msgid "Active graphics filter:"
-msgstr "Prze³±czaj pomiêdzy filtrami grafiki"
+msgstr "Aktywny filtr graficzny:"
#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2250
-#: backends/graphics/openglsdl/openglsdl-graphics.cpp:481
-#, fuzzy
+#: backends/graphics/openglsdl/openglsdl-graphics.cpp:477
msgid "Windowed mode"
-msgstr "Renderer:"
+msgstr "Okno"
#: backends/graphics/opengl/opengl-graphics.cpp:130
msgid "OpenGL Normal"
@@ -2346,28 +2485,27 @@ msgstr "OpenGL - normalny"
#: backends/graphics/opengl/opengl-graphics.cpp:131
msgid "OpenGL Conserve"
-msgstr "OpenGL - zachow."
+msgstr "OpenGL - zachowanie proporcji"
#: backends/graphics/opengl/opengl-graphics.cpp:132
msgid "OpenGL Original"
-msgstr "OpenGL - pierw."
+msgstr "OpenGL - oryginalny rozmiar"
#: backends/graphics/openglsdl/openglsdl-graphics.cpp:415
-#, fuzzy
msgid "Current display mode"
-msgstr "Obecny tryb wideo:"
+msgstr "Obecny tryb wideo"
#: backends/graphics/openglsdl/openglsdl-graphics.cpp:428
msgid "Current scale"
-msgstr ""
+msgstr "Aktualne powiêkszenie"
-#: backends/graphics/openglsdl/openglsdl-graphics.cpp:562
+#: backends/graphics/openglsdl/openglsdl-graphics.cpp:558
msgid "Active filter mode: Linear"
-msgstr ""
+msgstr "Aktywny tryb filtru: dwuliniowy"
-#: backends/graphics/openglsdl/openglsdl-graphics.cpp:564
+#: backends/graphics/openglsdl/openglsdl-graphics.cpp:560
msgid "Active filter mode: Nearest"
-msgstr ""
+msgstr "Aktywny tryb filtru: najbli¿szy s±siad"
#: backends/platform/symbian/src/SymbianActions.cpp:38
#: backends/platform/wince/CEActionsSmartphone.cpp:39
@@ -2389,19 +2527,6 @@ msgstr "W lewo"
msgid "Right"
msgstr "W prawo"
-#: backends/platform/symbian/src/SymbianActions.cpp:42
-#: backends/platform/wince/CEActionsPocket.cpp:60
-#: backends/platform/wince/CEActionsSmartphone.cpp:43
-#: backends/platform/bada/form.cpp:281
-msgid "Left Click"
-msgstr "Klikniêcie LPM"
-
-#: backends/platform/symbian/src/SymbianActions.cpp:43
-#: backends/platform/wince/CEActionsSmartphone.cpp:44
-#: backends/platform/bada/form.cpp:273
-msgid "Right Click"
-msgstr "Klikniêcie PPM"
-
#: backends/platform/symbian/src/SymbianActions.cpp:46
#: backends/platform/wince/CEActionsSmartphone.cpp:47
msgid "Zone"
@@ -2562,17 +2687,15 @@ msgid "Network down"
msgstr "Sieæ nie dzia³a"
#: backends/platform/wii/options.cpp:178
-#, fuzzy
msgid "Initializing network"
msgstr "Inicjalizacja sieci"
#: backends/platform/wii/options.cpp:182
-#, fuzzy
msgid "Timeout while initializing network"
msgstr "Przekroczono limit czasu inicjalizacji sieci"
#: backends/platform/wii/options.cpp:186
-#, fuzzy, c-format
+#, c-format
msgid "Network not initialized (%d)"
msgstr "Sieæ nie zosta³a zainicjalizowana (%d)"
@@ -2690,96 +2813,104 @@ msgstr ""
"Nie zapomnij przypisaæ klawisza 'Ukryj pasek narzêdzi', by widzieæ ca³y "
"ekwipunek"
-#: backends/events/default/default-events.cpp:222
-#, fuzzy
+#: backends/events/default/default-events.cpp:191
msgid "Do you really want to return to the Launcher?"
-msgstr "Na pewno chcesz skasowaæ ten zapis?"
+msgstr "Na pewno chcesz powróciæ do launchera?"
-#: backends/events/default/default-events.cpp:222
-#, fuzzy
+#: backends/events/default/default-events.cpp:191
msgid "Launcher"
-msgstr "Piê¶æ"
+msgstr ""
-#: backends/events/default/default-events.cpp:244
-#, fuzzy
+#: backends/events/default/default-events.cpp:213
msgid "Do you really want to quit?"
-msgstr "Chcesz wyj¶æ?"
+msgstr "Na pewno chcesz wyj¶æ?"
#: backends/events/gph/gph-events.cpp:338
#: backends/events/gph/gph-events.cpp:381
#: backends/events/openpandora/op-events.cpp:139
msgid "Touchscreen 'Tap Mode' - Left Click"
-msgstr ""
+msgstr "Dotkniêcie ekranu - klikniêcie LPM"
#: backends/events/gph/gph-events.cpp:340
#: backends/events/gph/gph-events.cpp:383
#: backends/events/openpandora/op-events.cpp:141
msgid "Touchscreen 'Tap Mode' - Right Click"
-msgstr ""
+msgstr "Dotkniêcie ekranu - klikniêcie PPM"
#: backends/events/gph/gph-events.cpp:342
#: backends/events/gph/gph-events.cpp:385
#: backends/events/openpandora/op-events.cpp:143
msgid "Touchscreen 'Tap Mode' - Hover (No Click)"
-msgstr ""
+msgstr "Dotkniêcie ekranu - brak klikniêcia"
#: backends/events/gph/gph-events.cpp:362
-#, fuzzy
msgid "Maximum Volume"
-msgstr "G³o¶no¶æ"
+msgstr "Maksymalna g³o¶no¶æ"
#: backends/events/gph/gph-events.cpp:364
msgid "Increasing Volume"
-msgstr ""
+msgstr "Zwiêkszenie g³o¶no¶ci"
#: backends/events/gph/gph-events.cpp:370
-#, fuzzy
msgid "Minimal Volume"
-msgstr "G³o¶no¶æ"
+msgstr "Minimalna g³o¶no¶æ"
#: backends/events/gph/gph-events.cpp:372
msgid "Decreasing Volume"
-msgstr ""
+msgstr "Zmniejszenie g³o¶no¶ci"
#: backends/updates/macosx/macosx-updates.mm:65
msgid "Check for Updates..."
-msgstr ""
+msgstr "Sprawd¼ aktualizacjê..."
#: backends/platform/bada/form.cpp:269
-#, fuzzy
msgid "Right Click Once"
-msgstr "Klikniêcie PPM"
+msgstr "Pojedyncze klikniêcie PPM"
#: backends/platform/bada/form.cpp:277
-#, fuzzy
msgid "Move Only"
-msgstr "Mowa"
+msgstr "Tylko ruch"
#: backends/platform/bada/form.cpp:291
msgid "Escape Key"
-msgstr ""
+msgstr "Przycisk wyj¶cia"
#: backends/platform/bada/form.cpp:296
-#, fuzzy
msgid "Game Menu"
-msgstr "Gra"
+msgstr "Menu gry"
#: backends/platform/bada/form.cpp:301
-#, fuzzy
msgid "Show Keypad"
msgstr "Poka¿ klawiaturê"
#: backends/platform/bada/form.cpp:309
msgid "Control Mouse"
-msgstr ""
+msgstr "Steruj myszk±"
-#: backends/events/maemosdl/maemosdl-events.cpp:121
+#: backends/events/maemosdl/maemosdl-events.cpp:192
msgid "Clicking Enabled"
-msgstr ""
+msgstr "Klikanie w³±czone"
-#: backends/events/maemosdl/maemosdl-events.cpp:121
+#: backends/events/maemosdl/maemosdl-events.cpp:192
msgid "Clicking Disabled"
-msgstr ""
+msgstr "Klikanie wy³±czone"
+
+#~ msgid "Hercules Green"
+#~ msgstr "Zielony Hercules"
+
+#~ msgid "Hercules Amber"
+#~ msgstr "Bursztynowy Hercules"
+
+#~ msgctxt "lowres"
+#~ msgid "Hercules Green"
+#~ msgstr "Zielony Hercules"
+
+#~ msgctxt "lowres"
+#~ msgid "Hercules Amber"
+#~ msgstr "Bursztynowy Hercules"
+
+#~ msgid "Save game failed!"
+#~ msgstr "Nie uda³o siê zapisaæ stanu gry!"
#~ msgctxt "lowres"
#~ msgid "Add Game..."
diff --git a/po/pt_BR.po b/po/pt_BR.po
index 07073644a4..16293a543f 100644
--- a/po/pt_BR.po
+++ b/po/pt_BR.po
@@ -1,5 +1,5 @@
# Portuguese (Brazilian) translation for ScummVM.
-# Copyright (C) 2010-2011 ScummVM Team
+# Copyright (C) 2010-2012 ScummVM Team
# This file is distributed under the same license as the ScummVM package.
# Saulo Benigno <saulobenigno@gmail.com>, 2010.
#
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: ScummVM 1.3.0svn\n"
"Report-Msgid-Bugs-To: scummvm-devel@lists.sf.net\n"
-"POT-Creation-Date: 2011-10-19 13:42+0100\n"
+"POT-Creation-Date: 2012-03-07 22:09+0000\n"
"PO-Revision-Date: 2011-10-21 21:30-0300\n"
"Last-Translator: Saulo Benigno <saulobenigno@gmail.com>\n"
"Language-Team: ScummBR (www.scummbr.com) <scummbr@yahoo.com.br>\n"
@@ -47,13 +47,13 @@ msgid "Go up"
msgstr "Acima"
#: gui/browser.cpp:69 gui/chooser.cpp:45 gui/KeysDialog.cpp:43
-#: gui/launcher.cpp:312 gui/massadd.cpp:94 gui/options.cpp:1178
+#: gui/launcher.cpp:320 gui/massadd.cpp:94 gui/options.cpp:1253
#: gui/saveload.cpp:63 gui/saveload.cpp:155 gui/themebrowser.cpp:54
-#: engines/engine.cpp:436 engines/scumm/dialogs.cpp:190
+#: engines/engine.cpp:442 engines/scumm/dialogs.cpp:190
#: engines/sword1/control.cpp:865 engines/parallaction/saveload.cpp:281
#: backends/platform/wii/options.cpp:48
-#: backends/events/default/default-events.cpp:222
-#: backends/events/default/default-events.cpp:244
+#: backends/events/default/default-events.cpp:191
+#: backends/events/default/default-events.cpp:213
msgid "Cancel"
msgstr "Cancelar"
@@ -61,25 +61,30 @@ msgstr "Cancelar"
msgid "Choose"
msgstr "Escolher"
-#: gui/gui-manager.cpp:116 engines/scumm/help.cpp:125
+#: gui/gui-manager.cpp:115 engines/scumm/help.cpp:125
#: engines/scumm/help.cpp:140 engines/scumm/help.cpp:165
#: engines/scumm/help.cpp:191 engines/scumm/help.cpp:209
#: backends/keymapper/remap-dialog.cpp:52
msgid "Close"
msgstr "Fechar"
-#: gui/gui-manager.cpp:119
+#: gui/gui-manager.cpp:118
msgid "Mouse click"
msgstr "Clique do mouse"
-#: gui/gui-manager.cpp:122 base/main.cpp:283
+#: gui/gui-manager.cpp:122 base/main.cpp:288
msgid "Display keyboard"
msgstr "Mostrar teclado"
-#: gui/gui-manager.cpp:125 base/main.cpp:286
+#: gui/gui-manager.cpp:126 base/main.cpp:292
msgid "Remap keys"
msgstr "Remapear teclas"
+#: gui/gui-manager.cpp:129 base/main.cpp:295
+#, fuzzy
+msgid "Toggle FullScreen"
+msgstr "Habilita Tela Cheia"
+
#: gui/KeysDialog.h:36 gui/KeysDialog.cpp:145
msgid "Choose an action to map"
msgstr "Selecione uma ação para mapear"
@@ -88,16 +93,17 @@ msgstr "Selecione uma ação para mapear"
msgid "Map"
msgstr "Mapear"
-#: gui/KeysDialog.cpp:42 gui/launcher.cpp:313 gui/launcher.cpp:936
-#: gui/launcher.cpp:940 gui/massadd.cpp:91 gui/options.cpp:1179
-#: engines/engine.cpp:359 engines/engine.cpp:370 engines/scumm/dialogs.cpp:192
-#: engines/scumm/scumm.cpp:1776 engines/agos/animation.cpp:551
+#: gui/KeysDialog.cpp:42 gui/launcher.cpp:321 gui/launcher.cpp:960
+#: gui/launcher.cpp:964 gui/massadd.cpp:91 gui/options.cpp:1254
+#: engines/engine.cpp:361 engines/engine.cpp:372 engines/scumm/dialogs.cpp:192
+#: engines/scumm/scumm.cpp:1775 engines/agos/animation.cpp:551
#: engines/groovie/script.cpp:420 engines/sky/compact.cpp:131
-#: engines/sky/compact.cpp:141 engines/sword1/animation.cpp:344
-#: engines/sword1/animation.cpp:354 engines/sword1/animation.cpp:360
-#: engines/sword1/control.cpp:865 engines/sword1/logic.cpp:1633
-#: engines/sword2/animation.cpp:379 engines/sword2/animation.cpp:389
-#: engines/sword2/animation.cpp:398 engines/parallaction/saveload.cpp:281
+#: engines/sky/compact.cpp:141 engines/sword1/animation.cpp:539
+#: engines/sword1/animation.cpp:560 engines/sword1/animation.cpp:570
+#: engines/sword1/animation.cpp:577 engines/sword1/control.cpp:865
+#: engines/sword1/logic.cpp:1633 engines/sword2/animation.cpp:435
+#: engines/sword2/animation.cpp:455 engines/sword2/animation.cpp:465
+#: engines/sword2/animation.cpp:474 engines/parallaction/saveload.cpp:281
#: backends/platform/wii/options.cpp:47
#: backends/platform/wince/CELauncherDialog.cpp:54
msgid "OK"
@@ -125,15 +131,15 @@ msgstr "Por favor selecione uma ação"
msgid "Press the key to associate"
msgstr "Pressione a tecla para associar"
-#: gui/launcher.cpp:165
+#: gui/launcher.cpp:170
msgid "Game"
msgstr "Jogo"
-#: gui/launcher.cpp:169
+#: gui/launcher.cpp:174
msgid "ID:"
msgstr "Código:"
-#: gui/launcher.cpp:169 gui/launcher.cpp:171 gui/launcher.cpp:172
+#: gui/launcher.cpp:174 gui/launcher.cpp:176 gui/launcher.cpp:177
msgid ""
"Short game identifier used for referring to savegames and running the game "
"from the command line"
@@ -141,311 +147,309 @@ msgstr ""
"Código identificador usado para se referir a jogos salvos e execução do jogo "
"a partir da linha de comando"
-#: gui/launcher.cpp:171
+#: gui/launcher.cpp:176
msgctxt "lowres"
msgid "ID:"
msgstr "Código:"
-#: gui/launcher.cpp:176
+#: gui/launcher.cpp:181
msgid "Name:"
msgstr "Nome:"
-#: gui/launcher.cpp:176 gui/launcher.cpp:178 gui/launcher.cpp:179
+#: gui/launcher.cpp:181 gui/launcher.cpp:183 gui/launcher.cpp:184
msgid "Full title of the game"
msgstr "Título completo do jogo"
-#: gui/launcher.cpp:178
+#: gui/launcher.cpp:183
msgctxt "lowres"
msgid "Name:"
msgstr "Nome:"
-#: gui/launcher.cpp:182
+#: gui/launcher.cpp:187
msgid "Language:"
msgstr "Idioma:"
-#: gui/launcher.cpp:182 gui/launcher.cpp:183
+#: gui/launcher.cpp:187 gui/launcher.cpp:188
msgid ""
"Language of the game. This will not turn your Spanish game version into "
"English"
msgstr "Idioma do jogo. Isto não irá passar seu jogo Inglês para Português"
-#: gui/launcher.cpp:184 gui/launcher.cpp:198 gui/options.cpp:74
-#: gui/options.cpp:708 gui/options.cpp:718 gui/options.cpp:1149
+#: gui/launcher.cpp:189 gui/launcher.cpp:203 gui/options.cpp:80
+#: gui/options.cpp:745 gui/options.cpp:758 gui/options.cpp:1224
#: audio/null.cpp:40
msgid "<default>"
msgstr "<padrão>"
-#: gui/launcher.cpp:194
+#: gui/launcher.cpp:199
msgid "Platform:"
msgstr "Sistema:"
-#: gui/launcher.cpp:194 gui/launcher.cpp:196 gui/launcher.cpp:197
+#: gui/launcher.cpp:199 gui/launcher.cpp:201 gui/launcher.cpp:202
msgid "Platform the game was originally designed for"
msgstr "Sistema que o jogo foi desenvolvido originalmente"
-#: gui/launcher.cpp:196
+#: gui/launcher.cpp:201
msgctxt "lowres"
msgid "Platform:"
msgstr "Sistema:"
-#: gui/launcher.cpp:208 gui/options.cpp:1018 gui/options.cpp:1035
+#: gui/launcher.cpp:213 gui/options.cpp:1087 gui/options.cpp:1104
msgid "Graphics"
msgstr "Gráficos"
-#: gui/launcher.cpp:208 gui/options.cpp:1018 gui/options.cpp:1035
+#: gui/launcher.cpp:213 gui/options.cpp:1087 gui/options.cpp:1104
msgid "GFX"
msgstr "GFX"
-#: gui/launcher.cpp:211
+#: gui/launcher.cpp:216
msgid "Override global graphic settings"
msgstr "Sobrepor configuração global de gráficos"
-#: gui/launcher.cpp:213
+#: gui/launcher.cpp:218
msgctxt "lowres"
msgid "Override global graphic settings"
msgstr "Sobrepor configuração global de gráficos"
-#: gui/launcher.cpp:220 gui/options.cpp:1041
+#: gui/launcher.cpp:225 gui/options.cpp:1110
msgid "Audio"
msgstr "Áudio"
-#: gui/launcher.cpp:223
+#: gui/launcher.cpp:228
msgid "Override global audio settings"
msgstr "Sobrepor configuração global de áudio"
-#: gui/launcher.cpp:225
+#: gui/launcher.cpp:230
msgctxt "lowres"
msgid "Override global audio settings"
msgstr "Sobrepor configuração global de áudio"
-#: gui/launcher.cpp:234 gui/options.cpp:1046
+#: gui/launcher.cpp:239 gui/options.cpp:1115
msgid "Volume"
msgstr "Volume"
-#: gui/launcher.cpp:236 gui/options.cpp:1048
+#: gui/launcher.cpp:241 gui/options.cpp:1117
msgctxt "lowres"
msgid "Volume"
msgstr "Volume"
-#: gui/launcher.cpp:239
+#: gui/launcher.cpp:244
msgid "Override global volume settings"
msgstr "Sobrepor configuração global de volume"
-#: gui/launcher.cpp:241
+#: gui/launcher.cpp:246
msgctxt "lowres"
msgid "Override global volume settings"
msgstr "Sobrepor configuração global de volume"
-#: gui/launcher.cpp:248 gui/options.cpp:1056
+#: gui/launcher.cpp:254 gui/options.cpp:1125
msgid "MIDI"
msgstr "MIDI"
-#: gui/launcher.cpp:251
+#: gui/launcher.cpp:257
msgid "Override global MIDI settings"
msgstr "Sobrepor configuração global de MIDI"
-#: gui/launcher.cpp:253
+#: gui/launcher.cpp:259
msgctxt "lowres"
msgid "Override global MIDI settings"
msgstr "Sobrepor configuração global de MIDI"
-#: gui/launcher.cpp:263 gui/options.cpp:1062
+#: gui/launcher.cpp:268 gui/options.cpp:1131
msgid "MT-32"
msgstr "MT-32"
-#: gui/launcher.cpp:266
+#: gui/launcher.cpp:271
msgid "Override global MT-32 settings"
msgstr "Sobrepor configuração global de MT-32"
-#: gui/launcher.cpp:268
+#: gui/launcher.cpp:273
msgctxt "lowres"
msgid "Override global MT-32 settings"
msgstr "Sobrepor configuração global de MT-32"
-#: gui/launcher.cpp:279 gui/options.cpp:1069
+#: gui/launcher.cpp:282 gui/options.cpp:1138
msgid "Paths"
msgstr "Pastas"
-#: gui/launcher.cpp:281 gui/options.cpp:1071
+#: gui/launcher.cpp:284 gui/options.cpp:1140
msgctxt "lowres"
msgid "Paths"
msgstr "Pastas"
-#: gui/launcher.cpp:288
+#: gui/launcher.cpp:291
msgid "Game Path:"
msgstr "Pasta do Jogo:"
-#: gui/launcher.cpp:290
+#: gui/launcher.cpp:293
msgctxt "lowres"
msgid "Game Path:"
msgstr "Pasta do Jogo:"
-#: gui/launcher.cpp:295 gui/options.cpp:1091
+#: gui/launcher.cpp:298 gui/options.cpp:1164
msgid "Extra Path:"
msgstr "Pasta de Extras"
-#: gui/launcher.cpp:295 gui/launcher.cpp:297 gui/launcher.cpp:298
+#: gui/launcher.cpp:298 gui/launcher.cpp:300 gui/launcher.cpp:301
msgid "Specifies path to additional data used the game"
msgstr "Especifique a pasta para dados utilizados no jogo"
-#: gui/launcher.cpp:297 gui/options.cpp:1093
+#: gui/launcher.cpp:300 gui/options.cpp:1166
msgctxt "lowres"
msgid "Extra Path:"
msgstr "Pasta de Extras"
-#: gui/launcher.cpp:302 gui/options.cpp:1079
+#: gui/launcher.cpp:307 gui/options.cpp:1148
msgid "Save Path:"
msgstr "Pasta para Salvar"
-#: gui/launcher.cpp:302 gui/launcher.cpp:304 gui/launcher.cpp:305
-#: gui/options.cpp:1079 gui/options.cpp:1081 gui/options.cpp:1082
+#: gui/launcher.cpp:307 gui/launcher.cpp:309 gui/launcher.cpp:310
+#: gui/options.cpp:1148 gui/options.cpp:1150 gui/options.cpp:1151
msgid "Specifies where your savegames are put"
msgstr "Especifique onde guardar seus jogos salvos"
-#: gui/launcher.cpp:304 gui/options.cpp:1081
+#: gui/launcher.cpp:309 gui/options.cpp:1150
msgctxt "lowres"
msgid "Save Path:"
msgstr "Pasta para Salvar"
-#: gui/launcher.cpp:321 gui/launcher.cpp:404 gui/launcher.cpp:453
-#: gui/options.cpp:1088 gui/options.cpp:1094 gui/options.cpp:1101
-#: gui/options.cpp:1202 gui/options.cpp:1208 gui/options.cpp:1214
-#: gui/options.cpp:1222 gui/options.cpp:1246 gui/options.cpp:1250
-#: gui/options.cpp:1256 gui/options.cpp:1263 gui/options.cpp:1362
+#: gui/launcher.cpp:329 gui/launcher.cpp:416 gui/launcher.cpp:469
+#: gui/launcher.cpp:523 gui/options.cpp:1159 gui/options.cpp:1167
+#: gui/options.cpp:1176 gui/options.cpp:1283 gui/options.cpp:1289
+#: gui/options.cpp:1297 gui/options.cpp:1327 gui/options.cpp:1333
+#: gui/options.cpp:1340 gui/options.cpp:1433 gui/options.cpp:1436
+#: gui/options.cpp:1448
msgctxt "path"
msgid "None"
msgstr "Nenhum(a)"
-#: gui/launcher.cpp:326 gui/launcher.cpp:408
+#: gui/launcher.cpp:334 gui/launcher.cpp:422 gui/launcher.cpp:527
+#: gui/options.cpp:1277 gui/options.cpp:1321 gui/options.cpp:1439
#: backends/platform/wii/options.cpp:56
msgid "Default"
msgstr "Padrão"
-#: gui/launcher.cpp:446 gui/options.cpp:1356
+#: gui/launcher.cpp:462 gui/options.cpp:1442
msgid "Select SoundFont"
msgstr "Selecione o SoundFont"
-#: gui/launcher.cpp:465 gui/launcher.cpp:612
+#: gui/launcher.cpp:481 gui/launcher.cpp:636
msgid "Select directory with game data"
msgstr "Selecione a pasta com os arquivos do jogo"
-#: gui/launcher.cpp:483
+#: gui/launcher.cpp:499
msgid "Select additional game directory"
msgstr "Selecione a pasta adicional do jogo"
-#: gui/launcher.cpp:495
+#: gui/launcher.cpp:511
msgid "Select directory for saved games"
msgstr "Selecione a pasta para os jogos salvos"
-#: gui/launcher.cpp:514
+#: gui/launcher.cpp:538
msgid "This game ID is already taken. Please choose another one."
msgstr "Este código já esta sendo utilizado. Por favor, escolha outro."
-#: gui/launcher.cpp:555 engines/dialogs.cpp:110
+#: gui/launcher.cpp:579 engines/dialogs.cpp:110
msgid "~Q~uit"
msgstr "~S~air"
-#: gui/launcher.cpp:555 backends/platform/sdl/macosx/appmenu_osx.mm:80
+#: gui/launcher.cpp:579 backends/platform/sdl/macosx/appmenu_osx.mm:96
msgid "Quit ScummVM"
msgstr "Sair do ScummVM"
-#: gui/launcher.cpp:556
+#: gui/launcher.cpp:580
msgid "A~b~out..."
msgstr "So~b~re..."
-#: gui/launcher.cpp:556 backends/platform/sdl/macosx/appmenu_osx.mm:61
+#: gui/launcher.cpp:580 backends/platform/sdl/macosx/appmenu_osx.mm:70
msgid "About ScummVM"
msgstr "Sobre o ScumnmVM"
-#: gui/launcher.cpp:557
+#: gui/launcher.cpp:581
msgid "~O~ptions..."
msgstr "~O~pções"
-#: gui/launcher.cpp:557
+#: gui/launcher.cpp:581
msgid "Change global ScummVM options"
msgstr "Alterar opções globais do ScummVM"
-#: gui/launcher.cpp:559
+#: gui/launcher.cpp:583
msgid "~S~tart"
msgstr "~I~niciar"
-#: gui/launcher.cpp:559
+#: gui/launcher.cpp:583
msgid "Start selected game"
msgstr "Iniciar jogo selecionado"
-#: gui/launcher.cpp:562
+#: gui/launcher.cpp:586
msgid "~L~oad..."
msgstr "~C~arregar"
-#: gui/launcher.cpp:562
+#: gui/launcher.cpp:586
msgid "Load savegame for selected game"
msgstr "Carregar jogo salvo do jogo selecionado"
-#: gui/launcher.cpp:567 gui/launcher.cpp:1055
+#: gui/launcher.cpp:591 gui/launcher.cpp:1079
msgid "~A~dd Game..."
msgstr "~A~dicionar Jogo..."
-#: gui/launcher.cpp:567 gui/launcher.cpp:574
+#: gui/launcher.cpp:591 gui/launcher.cpp:598
msgid "Hold Shift for Mass Add"
msgstr "Segure Shift para Multi-Adição"
-#: gui/launcher.cpp:569
+#: gui/launcher.cpp:593
msgid "~E~dit Game..."
msgstr "~E~ditar Jogo..."
-#: gui/launcher.cpp:569 gui/launcher.cpp:576
+#: gui/launcher.cpp:593 gui/launcher.cpp:600
msgid "Change game options"
msgstr "Alterar opções do jogo"
-#: gui/launcher.cpp:571
+#: gui/launcher.cpp:595
msgid "~R~emove Game"
msgstr "~R~emover Jogo"
-#: gui/launcher.cpp:571 gui/launcher.cpp:578
+#: gui/launcher.cpp:595 gui/launcher.cpp:602
msgid "Remove game from the list. The game data files stay intact"
msgstr ""
"Remover jogo da lista. Os arquivos de dados do jogo permanecem intactos"
-#: gui/launcher.cpp:574 gui/launcher.cpp:1055
+#: gui/launcher.cpp:598 gui/launcher.cpp:1079
msgctxt "lowres"
msgid "~A~dd Game..."
msgstr "~A~dicionar Jogo..."
-#: gui/launcher.cpp:576
+#: gui/launcher.cpp:600
msgctxt "lowres"
msgid "~E~dit Game..."
msgstr "~E~ditar Jogo..."
-#: gui/launcher.cpp:578
+#: gui/launcher.cpp:602
msgctxt "lowres"
msgid "~R~emove Game"
msgstr "~R~emover Jogo"
-#: gui/launcher.cpp:586
+#: gui/launcher.cpp:610
msgid "Search in game list"
msgstr "Pesquisar na lista de jogos"
-#: gui/launcher.cpp:590 gui/launcher.cpp:1102
+#: gui/launcher.cpp:614 gui/launcher.cpp:1126
msgid "Search:"
msgstr "Pesquisar:"
-#: gui/launcher.cpp:593 gui/options.cpp:826
-msgid "Clear value"
-msgstr "Limpar valor"
-
-#: gui/launcher.cpp:615 engines/dialogs.cpp:114 engines/mohawk/myst.cpp:255
+#: gui/launcher.cpp:639 engines/dialogs.cpp:114 engines/mohawk/myst.cpp:255
#: engines/mohawk/riven.cpp:716 engines/cruise/menu.cpp:216
msgid "Load game:"
msgstr "Carregar jogo:"
-#: gui/launcher.cpp:615 engines/dialogs.cpp:114 engines/scumm/dialogs.cpp:188
+#: gui/launcher.cpp:639 engines/dialogs.cpp:114 engines/scumm/dialogs.cpp:188
#: engines/mohawk/myst.cpp:255 engines/mohawk/riven.cpp:716
#: engines/cruise/menu.cpp:216 backends/platform/wince/CEActionsPocket.cpp:267
#: backends/platform/wince/CEActionsSmartphone.cpp:231
msgid "Load"
msgstr "Carregar"
-#: gui/launcher.cpp:723
+#: gui/launcher.cpp:747
msgid ""
"Do you really want to run the mass game detector? This could potentially add "
"a huge number of games."
@@ -453,7 +457,7 @@ msgstr ""
"Você realmente deseja adicionar vários jogos ao mesmo tempo? Isso poderá "
"resultar em uma adição gigantesca de jogos."
-#: gui/launcher.cpp:724 gui/launcher.cpp:872
+#: gui/launcher.cpp:748 gui/launcher.cpp:896
#: backends/events/symbiansdl/symbiansdl-events.cpp:184
#: backends/platform/wince/CEActionsPocket.cpp:326
#: backends/platform/wince/CEActionsSmartphone.cpp:287
@@ -461,7 +465,7 @@ msgstr ""
msgid "Yes"
msgstr "Sim"
-#: gui/launcher.cpp:724 gui/launcher.cpp:872
+#: gui/launcher.cpp:748 gui/launcher.cpp:896
#: backends/events/symbiansdl/symbiansdl-events.cpp:184
#: backends/platform/wince/CEActionsPocket.cpp:326
#: backends/platform/wince/CEActionsSmartphone.cpp:287
@@ -469,38 +473,38 @@ msgstr "Sim"
msgid "No"
msgstr "Não"
-#: gui/launcher.cpp:772
+#: gui/launcher.cpp:796
msgid "ScummVM couldn't open the specified directory!"
msgstr "ScummVM não conseguiu abrir a pasta especificada!"
-#: gui/launcher.cpp:784
+#: gui/launcher.cpp:808
msgid "ScummVM could not find any game in the specified directory!"
msgstr "ScummVM não encontrou nenhum jogo na pasta especificada!"
-#: gui/launcher.cpp:798
+#: gui/launcher.cpp:822
msgid "Pick the game:"
msgstr "Escolha o jogo:"
-#: gui/launcher.cpp:872
+#: gui/launcher.cpp:896
msgid "Do you really want to remove this game configuration?"
msgstr "Você deseja realmente remover a configuração deste jogo?"
-#: gui/launcher.cpp:936
+#: gui/launcher.cpp:960
msgid "This game does not support loading games from the launcher."
msgstr "Este jogo não suporta abrir jogos a partir do menu principal."
-#: gui/launcher.cpp:940
+#: gui/launcher.cpp:964
msgid "ScummVM could not find any engine capable of running the selected game!"
msgstr ""
"ScummVM não conseguiu encontrar qualquer programa capaz de rodar o jogo "
"selecionado!"
-#: gui/launcher.cpp:1054
+#: gui/launcher.cpp:1078
msgctxt "lowres"
msgid "Mass Add..."
msgstr "Multi-Adição..."
-#: gui/launcher.cpp:1054
+#: gui/launcher.cpp:1078
msgid "Mass Add..."
msgstr "Multi-Adição..."
@@ -531,141 +535,141 @@ msgstr ""
"Encontrado(s) %d novo(s) jogo(s, ignorados %d previamente adicionados "
"jogos..."
-#: gui/options.cpp:72
+#: gui/options.cpp:78
msgid "Never"
msgstr "Nunca"
-#: gui/options.cpp:72
+#: gui/options.cpp:78
msgid "every 5 mins"
msgstr "a cada 5 mins"
-#: gui/options.cpp:72
+#: gui/options.cpp:78
msgid "every 10 mins"
msgstr "a cada 10 mins"
-#: gui/options.cpp:72
+#: gui/options.cpp:78
msgid "every 15 mins"
msgstr "a cada 15 mins"
-#: gui/options.cpp:72
+#: gui/options.cpp:78
msgid "every 30 mins"
msgstr "a cada 30 mins"
-#: gui/options.cpp:74
+#: gui/options.cpp:80
msgid "8 kHz"
msgstr "8 kHz"
-#: gui/options.cpp:74
+#: gui/options.cpp:80
msgid "11kHz"
msgstr "11 kHz"
-#: gui/options.cpp:74
+#: gui/options.cpp:80
msgid "22 kHz"
msgstr "22 kHz"
-#: gui/options.cpp:74
+#: gui/options.cpp:80
msgid "44 kHz"
msgstr "44 kHz"
-#: gui/options.cpp:74
+#: gui/options.cpp:80
msgid "48 kHz"
msgstr "48 kHz"
-#: gui/options.cpp:236 gui/options.cpp:464 gui/options.cpp:559
-#: gui/options.cpp:625 gui/options.cpp:825
+#: gui/options.cpp:257 gui/options.cpp:485 gui/options.cpp:586
+#: gui/options.cpp:659 gui/options.cpp:868
msgctxt "soundfont"
msgid "None"
msgstr "Nenhum(a)"
-#: gui/options.cpp:372
+#: gui/options.cpp:393
msgid "Failed to apply some of the graphic options changes:"
msgstr "Falha ao aplicar algumas mudanças nas opções de gráfico:"
-#: gui/options.cpp:384
+#: gui/options.cpp:405
msgid "the video mode could not be changed."
msgstr "o modo de vídeo não pôde ser alterado."
-#: gui/options.cpp:390
+#: gui/options.cpp:411
msgid "the fullscreen setting could not be changed"
msgstr "a configuração de tela cheia não pôde ser mudada"
-#: gui/options.cpp:396
+#: gui/options.cpp:417
msgid "the aspect ratio setting could not be changed"
msgstr "a configuração de proporção não pôde ser mudada"
-#: gui/options.cpp:705
+#: gui/options.cpp:742
msgid "Graphics mode:"
msgstr "Modo gráfico:"
-#: gui/options.cpp:716
+#: gui/options.cpp:756
msgid "Render mode:"
msgstr "Renderização"
-#: gui/options.cpp:716 gui/options.cpp:717
+#: gui/options.cpp:756 gui/options.cpp:757
msgid "Special dithering modes supported by some games"
msgstr "Modos especiais de dithering suportados por alguns jogos"
-#: gui/options.cpp:726
+#: gui/options.cpp:768
#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2248
-#: backends/graphics/openglsdl/openglsdl-graphics.cpp:476
+#: backends/graphics/openglsdl/openglsdl-graphics.cpp:472
msgid "Fullscreen mode"
msgstr "Modo Tela Cheia"
-#: gui/options.cpp:729
+#: gui/options.cpp:771
msgid "Aspect ratio correction"
msgstr "Correção de proporção"
-#: gui/options.cpp:729
+#: gui/options.cpp:771
msgid "Correct aspect ratio for 320x200 games"
msgstr "Correção de proporção para jogos 320x200"
-#: gui/options.cpp:730
+#: gui/options.cpp:772
msgid "EGA undithering"
msgstr "EGA sem dithering"
-#: gui/options.cpp:730
+#: gui/options.cpp:772
msgid "Enable undithering in EGA games that support it"
msgstr "Habilita EGA sem dithering em jogos com suporte"
-#: gui/options.cpp:738
+#: gui/options.cpp:780
msgid "Preferred Device:"
msgstr "Dispositivo pref.:"
-#: gui/options.cpp:738
+#: gui/options.cpp:780
msgid "Music Device:"
msgstr "Disp. de música:"
-#: gui/options.cpp:738 gui/options.cpp:740
+#: gui/options.cpp:780 gui/options.cpp:782
msgid "Specifies preferred sound device or sound card emulator"
msgstr "Especifica o dispositivo de som preferido ou emulador de placa de som"
-#: gui/options.cpp:738 gui/options.cpp:740 gui/options.cpp:741
+#: gui/options.cpp:780 gui/options.cpp:782 gui/options.cpp:783
msgid "Specifies output sound device or sound card emulator"
msgstr "Especifica o dispositivo de saída de som ou emulador de placa de som"
-#: gui/options.cpp:740
+#: gui/options.cpp:782
msgctxt "lowres"
msgid "Preferred Dev.:"
msgstr "Dispositivo pref.:"
-#: gui/options.cpp:740
+#: gui/options.cpp:782
msgctxt "lowres"
msgid "Music Device:"
msgstr "Dispositivo de música:"
-#: gui/options.cpp:766
+#: gui/options.cpp:809
msgid "AdLib emulator:"
msgstr "Emulador AdLib:"
-#: gui/options.cpp:766 gui/options.cpp:767
+#: gui/options.cpp:809 gui/options.cpp:810
msgid "AdLib is used for music in many games"
msgstr "AdLib é utilizado para música em vários jogos"
-#: gui/options.cpp:777
+#: gui/options.cpp:820
msgid "Output rate:"
msgstr "Taxa de saída:"
-#: gui/options.cpp:777 gui/options.cpp:778
+#: gui/options.cpp:820 gui/options.cpp:821
msgid ""
"Higher value specifies better sound quality but may be not supported by your "
"soundcard"
@@ -673,62 +677,62 @@ msgstr ""
"Maior valor especifica melhor qualidade de som, mas pode não ser suportado "
"por sua placa de som"
-#: gui/options.cpp:788
+#: gui/options.cpp:831
msgid "GM Device:"
msgstr "Dispositivo GM:"
-#: gui/options.cpp:788
+#: gui/options.cpp:831
msgid "Specifies default sound device for General MIDI output"
msgstr "Especifique o dispositivo de som padrão para a saída General MIDI"
-#: gui/options.cpp:799
+#: gui/options.cpp:842
msgid "Don't use General MIDI music"
msgstr "Não usar música General MIDI"
-#: gui/options.cpp:810 gui/options.cpp:871
+#: gui/options.cpp:853 gui/options.cpp:915
msgid "Use first available device"
msgstr "Usar o primeiro dispositivo disponível"
-#: gui/options.cpp:822
+#: gui/options.cpp:865
msgid "SoundFont:"
msgstr "SoundFont:"
-#: gui/options.cpp:822 gui/options.cpp:824 gui/options.cpp:825
+#: gui/options.cpp:865 gui/options.cpp:867 gui/options.cpp:868
msgid "SoundFont is supported by some audio cards, Fluidsynth and Timidity"
msgstr "SoundFont é suportado por algumas placas de som, Fluidsynth e Timidity"
-#: gui/options.cpp:824
+#: gui/options.cpp:867
msgctxt "lowres"
msgid "SoundFont:"
msgstr "SoundFont:"
-#: gui/options.cpp:829
+#: gui/options.cpp:873
msgid "Mixed AdLib/MIDI mode"
msgstr "Mixar AdLib/MIDI"
-#: gui/options.cpp:829
+#: gui/options.cpp:873
msgid "Use both MIDI and AdLib sound generation"
msgstr "Usar MIDI e AdLib juntos na geração de som"
-#: gui/options.cpp:832
+#: gui/options.cpp:876
msgid "MIDI gain:"
msgstr "Ganho MIDI:"
-#: gui/options.cpp:842
+#: gui/options.cpp:886
msgid "MT-32 Device:"
msgstr "Dispositivo MT-32:"
-#: gui/options.cpp:842
+#: gui/options.cpp:886
msgid "Specifies default sound device for Roland MT-32/LAPC1/CM32l/CM64 output"
msgstr ""
"Especifique o dispositivo de som padrão para a saída Roland MT-32/LAPC1/"
"CM32l/CM64"
-#: gui/options.cpp:847
+#: gui/options.cpp:891
msgid "True Roland MT-32 (disable GM emulation)"
msgstr "Roland MT-32 real (desligar emulação GM)"
-#: gui/options.cpp:847 gui/options.cpp:849
+#: gui/options.cpp:891 gui/options.cpp:893
msgid ""
"Check if you want to use your real hardware Roland-compatible sound device "
"connected to your computer"
@@ -736,193 +740,193 @@ msgstr ""
"Verifique se você quer usar o seu dispositivo de hardware de som compatível "
"com Roland"
-#: gui/options.cpp:849
+#: gui/options.cpp:893
msgctxt "lowres"
msgid "True Roland MT-32 (no GM emulation)"
msgstr "Roland MT-32 real (sem emulação GM)"
-#: gui/options.cpp:852
+#: gui/options.cpp:896
msgid "Enable Roland GS Mode"
msgstr "Ligar modo Roland GS"
-#: gui/options.cpp:852
+#: gui/options.cpp:896
msgid "Turns off General MIDI mapping for games with Roland MT-32 soundtrack"
msgstr ""
"Desliga o mapeamento General MIDI para jogos com trilha sonora Roland MT-32"
-#: gui/options.cpp:861
+#: gui/options.cpp:905
msgid "Don't use Roland MT-32 music"
msgstr "Não usar música Roland MT-32"
-#: gui/options.cpp:888
+#: gui/options.cpp:932
msgid "Text and Speech:"
msgstr "Texto e Voz:"
-#: gui/options.cpp:892 gui/options.cpp:902
+#: gui/options.cpp:936 gui/options.cpp:946
msgid "Speech"
msgstr "Voz"
-#: gui/options.cpp:893 gui/options.cpp:903
+#: gui/options.cpp:937 gui/options.cpp:947
msgid "Subtitles"
msgstr "Legendas"
-#: gui/options.cpp:894
+#: gui/options.cpp:938
msgid "Both"
msgstr "Ambos"
-#: gui/options.cpp:896
+#: gui/options.cpp:940
msgid "Subtitle speed:"
msgstr "Rapidez legendas:"
-#: gui/options.cpp:898
+#: gui/options.cpp:942
msgctxt "lowres"
msgid "Text and Speech:"
msgstr "Texto e Voz:"
-#: gui/options.cpp:902
+#: gui/options.cpp:946
msgid "Spch"
msgstr "Voz"
-#: gui/options.cpp:903
+#: gui/options.cpp:947
msgid "Subs"
msgstr "Legs"
-#: gui/options.cpp:904
+#: gui/options.cpp:948
msgctxt "lowres"
msgid "Both"
msgstr "Ambos"
-#: gui/options.cpp:904
+#: gui/options.cpp:948
msgid "Show subtitles and play speech"
msgstr "Mostrar legenda e vozes (dublagem)"
-#: gui/options.cpp:906
+#: gui/options.cpp:950
msgctxt "lowres"
msgid "Subtitle speed:"
msgstr "Velocidade das legendas:"
-#: gui/options.cpp:922
+#: gui/options.cpp:966
msgid "Music volume:"
msgstr "Volume da Música:"
-#: gui/options.cpp:924
+#: gui/options.cpp:968
msgctxt "lowres"
msgid "Music volume:"
msgstr "Volume da Música:"
-#: gui/options.cpp:931
+#: gui/options.cpp:975
msgid "Mute All"
msgstr "Mudo"
-#: gui/options.cpp:934
+#: gui/options.cpp:978
msgid "SFX volume:"
msgstr "Volume dos Sons:"
-#: gui/options.cpp:934 gui/options.cpp:936 gui/options.cpp:937
+#: gui/options.cpp:978 gui/options.cpp:980 gui/options.cpp:981
msgid "Special sound effects volume"
msgstr "Volume dos efeitos sonoros especiais"
-#: gui/options.cpp:936
+#: gui/options.cpp:980
msgctxt "lowres"
msgid "SFX volume:"
msgstr "Volume dos Sons:"
-#: gui/options.cpp:944
+#: gui/options.cpp:988
msgid "Speech volume:"
msgstr "Volume da Voz:"
-#: gui/options.cpp:946
+#: gui/options.cpp:990
msgctxt "lowres"
msgid "Speech volume:"
msgstr "Volume da Voz:"
-#: gui/options.cpp:1085
+#: gui/options.cpp:1156
msgid "Theme Path:"
msgstr "Pasta do Tema"
-#: gui/options.cpp:1087
+#: gui/options.cpp:1158
msgctxt "lowres"
msgid "Theme Path:"
msgstr "Pasta do Tema"
-#: gui/options.cpp:1091 gui/options.cpp:1093 gui/options.cpp:1094
+#: gui/options.cpp:1164 gui/options.cpp:1166 gui/options.cpp:1167
msgid "Specifies path to additional data used by all games or ScummVM"
msgstr ""
"Especifica a pasta para os dados adicionais usados por todos os jogos ou "
"ScummVM"
-#: gui/options.cpp:1098
+#: gui/options.cpp:1173
msgid "Plugins Path:"
msgstr "Pasta de Plugins:"
-#: gui/options.cpp:1100
+#: gui/options.cpp:1175
msgctxt "lowres"
msgid "Plugins Path:"
msgstr "Pasta de Plugins:"
-#: gui/options.cpp:1109
+#: gui/options.cpp:1184
msgid "Misc"
msgstr "Outros"
-#: gui/options.cpp:1111
+#: gui/options.cpp:1186
msgctxt "lowres"
msgid "Misc"
msgstr "Outros"
-#: gui/options.cpp:1113
+#: gui/options.cpp:1188
msgid "Theme:"
msgstr "Tema:"
-#: gui/options.cpp:1117
+#: gui/options.cpp:1192
msgid "GUI Renderer:"
msgstr "Renderizador GUI:"
-#: gui/options.cpp:1129
+#: gui/options.cpp:1204
msgid "Autosave:"
msgstr "Auto-Salvar:"
-#: gui/options.cpp:1131
+#: gui/options.cpp:1206
msgctxt "lowres"
msgid "Autosave:"
msgstr "Auto-Salvar:"
-#: gui/options.cpp:1139
+#: gui/options.cpp:1214
msgid "Keys"
msgstr "Teclas"
-#: gui/options.cpp:1146
+#: gui/options.cpp:1221
msgid "GUI Language:"
msgstr "Idioma do GUI:"
-#: gui/options.cpp:1146
+#: gui/options.cpp:1221
msgid "Language of ScummVM GUI"
msgstr "Linguagem do ScummVM GUI"
-#: gui/options.cpp:1295
+#: gui/options.cpp:1372
msgid "You have to restart ScummVM before your changes will take effect."
msgstr "Você tem que reiniciar o ScummVM para funcionar."
-#: gui/options.cpp:1308
+#: gui/options.cpp:1385
msgid "Select directory for savegames"
msgstr "Selecione a pasta para o jogos salvos"
-#: gui/options.cpp:1315
+#: gui/options.cpp:1392
msgid "The chosen directory cannot be written to. Please select another one."
msgstr "O diretório escolhido não pode ser usado. Por favor, selecione outro."
-#: gui/options.cpp:1324
+#: gui/options.cpp:1401
msgid "Select directory for GUI themes"
msgstr "Selecione a pasta para os temas da Interface de Uso Gráfico"
-#: gui/options.cpp:1334
+#: gui/options.cpp:1411
msgid "Select directory for extra files"
msgstr "Selecione a pasta para os arquivos extras"
-#: gui/options.cpp:1345
+#: gui/options.cpp:1422
msgid "Select directory for plugins"
msgstr "Selecione a pasta para os plugins"
-#: gui/options.cpp:1389
+#: gui/options.cpp:1475
msgid ""
"The theme you selected does not support your current language. If you want "
"to use this theme you need to switch to another language first."
@@ -970,60 +974,64 @@ msgstr "Não-titulado arquivo de save"
msgid "Select a Theme"
msgstr "Selecione um Tema"
-#: gui/ThemeEngine.cpp:328
+#: gui/ThemeEngine.cpp:333
msgid "Disabled GFX"
msgstr "GFX desabilitado"
-#: gui/ThemeEngine.cpp:328
+#: gui/ThemeEngine.cpp:333
msgctxt "lowres"
msgid "Disabled GFX"
msgstr "GFX desabilitado"
-#: gui/ThemeEngine.cpp:329
+#: gui/ThemeEngine.cpp:334
msgid "Standard Renderer (16bpp)"
msgstr "Renderizador padrão (16bpp)"
-#: gui/ThemeEngine.cpp:329
+#: gui/ThemeEngine.cpp:334
msgid "Standard (16bpp)"
msgstr "Padrão (16bpp)"
-#: gui/ThemeEngine.cpp:331
+#: gui/ThemeEngine.cpp:336
msgid "Antialiased Renderer (16bpp)"
msgstr "Renderizador Anti-Serrilhamento (16bpp)"
-#: gui/ThemeEngine.cpp:331
+#: gui/ThemeEngine.cpp:336
msgid "Antialiased (16bpp)"
msgstr "Anti-Serrilhamento (16bpp)"
+#: gui/widget.cpp:312 gui/widget.cpp:314 gui/widget.cpp:320 gui/widget.cpp:322
+msgid "Clear value"
+msgstr "Limpar valor"
+
#: base/main.cpp:203
#, c-format
msgid "Engine does not support debug level '%s'"
msgstr "Esse programa não suporta o nível de debug '%s'"
-#: base/main.cpp:271
+#: base/main.cpp:275
msgid "Menu"
msgstr "Menu"
-#: base/main.cpp:274 backends/platform/symbian/src/SymbianActions.cpp:45
+#: base/main.cpp:278 backends/platform/symbian/src/SymbianActions.cpp:45
#: backends/platform/wince/CEActionsPocket.cpp:45
#: backends/platform/wince/CEActionsSmartphone.cpp:46
msgid "Skip"
msgstr "Pular"
-#: base/main.cpp:277 backends/platform/symbian/src/SymbianActions.cpp:50
+#: base/main.cpp:281 backends/platform/symbian/src/SymbianActions.cpp:50
#: backends/platform/wince/CEActionsPocket.cpp:42
msgid "Pause"
msgstr "Pausar"
-#: base/main.cpp:280
+#: base/main.cpp:284
msgid "Skip line"
msgstr "Pula linha"
-#: base/main.cpp:439
+#: base/main.cpp:455
msgid "Error running game:"
msgstr "Erro ao executar o jogo:"
-#: base/main.cpp:463
+#: base/main.cpp:479
msgid "Could not find any engine capable of running the selected game"
msgstr ""
"Não foi possível encontrar qualquer programa capaz de rodar o jogo "
@@ -1093,25 +1101,6 @@ msgstr "Usuário cancelou"
msgid "Unknown error"
msgstr "Erro desconhecido"
-#. I18N: Hercules is graphics card name
-#: common/util.cpp:275
-msgid "Hercules Green"
-msgstr "Hercules Green"
-
-#: common/util.cpp:276
-msgid "Hercules Amber"
-msgstr "Hercules Amber"
-
-#: common/util.cpp:283
-msgctxt "lowres"
-msgid "Hercules Green"
-msgstr "Hercules Green"
-
-#: common/util.cpp:284
-msgctxt "lowres"
-msgid "Hercules Amber"
-msgstr "Hercules Amber"
-
#: engines/advancedDetector.cpp:296
#, c-format
msgid "The game in '%s' seems to be unknown."
@@ -1160,12 +1149,12 @@ msgid "~R~eturn to Launcher"
msgstr "~V~oltar ao menu"
#: engines/dialogs.cpp:116 engines/cruise/menu.cpp:214
-#: engines/sci/engine/kfile.cpp:578
+#: engines/sci/engine/kfile.cpp:566
msgid "Save game:"
msgstr "Salvar jogo:"
#: engines/dialogs.cpp:116 engines/scumm/dialogs.cpp:187
-#: engines/cruise/menu.cpp:214 engines/sci/engine/kfile.cpp:578
+#: engines/cruise/menu.cpp:214 engines/sci/engine/kfile.cpp:566
#: backends/platform/symbian/src/SymbianActions.cpp:44
#: backends/platform/wince/CEActionsPocket.cpp:43
#: backends/platform/wince/CEActionsPocket.cpp:267
@@ -1184,37 +1173,47 @@ msgstr ""
"Por favor, consulte o README para obter informações básicas, e para obter "
"instruções sobre como obter assistência adicional."
-#: engines/dialogs.cpp:316 engines/mohawk/dialogs.cpp:109
+#: engines/dialogs.cpp:243
+#, fuzzy, c-format
+msgid ""
+"Gamestate save failed (%s)! Please consult the README for basic information, "
+"and for instructions on how to obtain further assistance."
+msgstr ""
+"Desculpe, este programa não fornece atualmente ajuda internamente no jogo. "
+"Por favor, consulte o README para obter informações básicas, e para obter "
+"instruções sobre como obter assistência adicional."
+
+#: engines/dialogs.cpp:321 engines/mohawk/dialogs.cpp:109
#: engines/mohawk/dialogs.cpp:174
msgid "~O~K"
msgstr "~O~K"
-#: engines/dialogs.cpp:317 engines/mohawk/dialogs.cpp:110
+#: engines/dialogs.cpp:322 engines/mohawk/dialogs.cpp:110
#: engines/mohawk/dialogs.cpp:175
msgid "~C~ancel"
msgstr "~C~ancelar"
-#: engines/dialogs.cpp:320
+#: engines/dialogs.cpp:325
msgid "~K~eys"
msgstr "~T~eclas"
-#: engines/engine.cpp:233
+#: engines/engine.cpp:235
msgid "Could not initialize color format."
msgstr "Não foi possível inicializar o formato de cor."
-#: engines/engine.cpp:241
+#: engines/engine.cpp:243
msgid "Could not switch to video mode: '"
msgstr "Não foi possível alternar o modo de vídeo atual:"
-#: engines/engine.cpp:250
+#: engines/engine.cpp:252
msgid "Could not apply aspect ratio setting."
msgstr "Não foi possível aplicar a correção de proporção"
-#: engines/engine.cpp:255
+#: engines/engine.cpp:257
msgid "Could not apply fullscreen setting."
msgstr "Não foi possível aplicar a configuração de tela cheia."
-#: engines/engine.cpp:355
+#: engines/engine.cpp:357
msgid ""
"You appear to be playing this game directly\n"
"from the CD. This is known to cause problems,\n"
@@ -1228,7 +1227,7 @@ msgstr ""
"os arquivos de dados para o disco rígido.\n"
"Consulte o arquivo README para mais detalhes."
-#: engines/engine.cpp:366
+#: engines/engine.cpp:368
msgid ""
"This game has audio tracks in its disk. These\n"
"tracks need to be ripped from the disk using\n"
@@ -1242,7 +1241,17 @@ msgstr ""
"para ouvir a música do jogo.\n"
"Consulte o arquivo README para mais detalhes."
-#: engines/engine.cpp:433
+#: engines/engine.cpp:426
+#, fuzzy, c-format
+msgid ""
+"Gamestate load failed (%s)! Please consult the README for basic information, "
+"and for instructions on how to obtain further assistance."
+msgstr ""
+"Desculpe, este programa não fornece atualmente ajuda internamente no jogo. "
+"Por favor, consulte o README para obter informações básicas, e para obter "
+"instruções sobre como obter assistência adicional."
+
+#: engines/engine.cpp:439
msgid ""
"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 "
@@ -1252,7 +1261,7 @@ msgstr ""
"suportado pelo ScummVM. Como tal, é provável que seja instável, e qualquer "
"jogo salvo que você fizer pode não funcionar em futuras versões do ScummVM."
-#: engines/engine.cpp:436
+#: engines/engine.cpp:442
msgid "Start anyway"
msgstr "Iniciar de qualquer maneira"
@@ -1296,7 +1305,7 @@ msgstr "Jogar"
#: backends/platform/symbian/src/SymbianActions.cpp:52
#: backends/platform/wince/CEActionsPocket.cpp:44
#: backends/platform/wince/CEActionsSmartphone.cpp:52
-#: backends/events/default/default-events.cpp:244
+#: backends/events/default/default-events.cpp:213
msgid "Quit"
msgstr "Sair"
@@ -1370,6 +1379,27 @@ msgctxt "lowres"
msgid "Speech & Subs"
msgstr "Voz e Legendas"
+#: engines/scumm/dialogs.cpp:653
+msgid "Select a Proficiency Level."
+msgstr ""
+
+#: engines/scumm/dialogs.cpp:655
+msgid "Refer to your Loom(TM) manual for help."
+msgstr ""
+
+#: engines/scumm/dialogs.cpp:658
+#, fuzzy
+msgid "Standard"
+msgstr "Padrão (16bpp)"
+
+#: engines/scumm/dialogs.cpp:659
+msgid "Practice"
+msgstr ""
+
+#: engines/scumm/dialogs.cpp:660
+msgid "Expert"
+msgstr ""
+
#: engines/scumm/help.cpp:73
msgid "Common keyboard commands:"
msgstr "Comandos de teclado comuns:"
@@ -1883,7 +1913,7 @@ msgstr "Voar para direita"
msgid "Fly to lower right"
msgstr "Voar para direita inferior"
-#: engines/scumm/scumm.cpp:1774
+#: engines/scumm/scumm.cpp:1773
#, c-format
msgid ""
"Native MIDI support requires the Roland Upgrade from LucasArts,\n"
@@ -1893,7 +1923,7 @@ msgstr ""
"LucasArts,\n"
"mas %s está faltando. Utilizando AdLib ao invés."
-#: engines/scumm/scumm.cpp:2264 engines/agos/saveload.cpp:189
+#: engines/scumm/scumm.cpp:2271 engines/agos/saveload.cpp:189
#, c-format
msgid ""
"Failed to save game state to file:\n"
@@ -1904,7 +1934,7 @@ msgstr ""
"\n"
"%s"
-#: engines/scumm/scumm.cpp:2271 engines/agos/saveload.cpp:154
+#: engines/scumm/scumm.cpp:2278 engines/agos/saveload.cpp:154
#, c-format
msgid ""
"Failed to load game state from file:\n"
@@ -1915,7 +1945,7 @@ msgstr ""
"\n"
"%s"
-#: engines/scumm/scumm.cpp:2283 engines/agos/saveload.cpp:197
+#: engines/scumm/scumm.cpp:2290 engines/agos/saveload.cpp:197
#, c-format
msgid ""
"Successfully saved game state in file:\n"
@@ -1926,7 +1956,7 @@ msgstr ""
"\n"
"%s"
-#: engines/scumm/scumm.cpp:2498
+#: engines/scumm/scumm.cpp:2505
msgid ""
"Usually, Maniac Mansion would start now. But ScummVM doesn't do that yet. To "
"play it, go to 'Add Game' in the ScummVM start menu and select the 'Maniac' "
@@ -1963,11 +1993,11 @@ msgstr "~M~enu Principal ScummVM"
msgid "~W~ater Effect Enabled"
msgstr "Modo ~E~feitos de água ativado"
-#: engines/sci/engine/kfile.cpp:685
+#: engines/sci/engine/kfile.cpp:673
msgid "Restore game:"
msgstr "Restaurar jogo:"
-#: engines/sci/engine/kfile.cpp:685
+#: engines/sci/engine/kfile.cpp:673
msgid "Restore"
msgstr "Restaurar"
@@ -1977,14 +2007,14 @@ msgid "Cutscene file '%s' not found!"
msgstr "Arquivo de vídeo '%s' não encontrado!"
#: engines/gob/inter_playtoons.cpp:256 engines/gob/inter_v2.cpp:1283
-#: engines/tinsel/saveload.cpp:482
+#: engines/tinsel/saveload.cpp:502
msgid "Failed to load game state from file."
msgstr ""
"Falha ao carregar o estado do jogo a partir do arquivo:\n"
"\n"
"%s"
-#: engines/gob/inter_v2.cpp:1353 engines/tinsel/saveload.cpp:560
+#: engines/gob/inter_v2.cpp:1353 engines/tinsel/saveload.cpp:515
msgid "Failed to save game state to file."
msgstr ""
"Falha ao salvar o estado do jogo para o arquivo:\n"
@@ -1999,6 +2029,60 @@ msgstr "Falha ao excluir arquivo."
msgid "Failed to save game"
msgstr "Falha ao salvar o jogo"
+#: engines/kyra/lol.cpp:478
+msgid "Attack 1"
+msgstr ""
+
+#: engines/kyra/lol.cpp:479
+msgid "Attack 2"
+msgstr ""
+
+#: engines/kyra/lol.cpp:480
+msgid "Attack 3"
+msgstr ""
+
+#: engines/kyra/lol.cpp:481
+msgid "Move Forward"
+msgstr ""
+
+#: engines/kyra/lol.cpp:482
+msgid "Move Back"
+msgstr ""
+
+#: engines/kyra/lol.cpp:483
+msgid "Slide Left"
+msgstr ""
+
+#: engines/kyra/lol.cpp:484
+#, fuzzy
+msgid "Slide Right"
+msgstr "Direita"
+
+#: engines/kyra/lol.cpp:485
+#, fuzzy
+msgid "Turn Left"
+msgstr "Desligar"
+
+#: engines/kyra/lol.cpp:486
+#, fuzzy
+msgid "Turn Right"
+msgstr "Cursor para a direita"
+
+#: engines/kyra/lol.cpp:487
+#, fuzzy
+msgid "Rest"
+msgstr "Restaurar"
+
+#: engines/kyra/lol.cpp:488
+#, fuzzy
+msgid "Options"
+msgstr "~O~pções"
+
+#: engines/kyra/lol.cpp:489
+#, fuzzy
+msgid "Choose Spell"
+msgstr "Escolher"
+
#: engines/kyra/sound_midi.cpp:475
msgid ""
"You appear to be using a General MIDI device,\n"
@@ -2013,10 +2097,6 @@ msgstr ""
"o modelo General MIDI. Talvez possa acontecer\n"
"que algumas faixas não sejam corretamente tocadas."
-#: engines/m4/m4_menus.cpp:138
-msgid "Save game failed!"
-msgstr "Falha ao salvar jogo!"
-
#: engines/sky/compact.cpp:130
msgid ""
"Unable to find \"sky.cpt\" file!\n"
@@ -2033,17 +2113,22 @@ msgstr ""
"O arquivo \"sky.cpt\" possui um tamanho incorreto.\n"
"Por favor, refaça o download em www.scummvm.org"
-#: engines/sword1/animation.cpp:344 engines/sword2/animation.cpp:379
+#: engines/sword1/animation.cpp:539
+#, c-format
+msgid "PSX stream cutscene '%s' cannot be played in paletted mode"
+msgstr ""
+
+#: engines/sword1/animation.cpp:560 engines/sword2/animation.cpp:455
msgid "DXA cutscenes found but ScummVM has been built without zlib support"
msgstr ""
"Vídeos no formato DXA foram encontrados, mas o ScummVM foi compilado sem "
"suporte a zlib"
-#: engines/sword1/animation.cpp:354 engines/sword2/animation.cpp:389
+#: engines/sword1/animation.cpp:570 engines/sword2/animation.cpp:465
msgid "MPEG2 cutscenes are no longer supported"
msgstr "Vídeos em MPEG2 não são mais suportados"
-#: engines/sword1/animation.cpp:359 engines/sword2/animation.cpp:397
+#: engines/sword1/animation.cpp:576 engines/sword2/animation.cpp:473
#, c-format
msgid "Cutscene '%s' not found"
msgstr "Vídeo '%s' não encontrado"
@@ -2087,6 +2172,14 @@ msgstr "Mantenha o novo"
msgid "This is the end of the Broken Sword 1 Demo"
msgstr "Este é o fim do demo de Broken Sword 1"
+#: engines/sword2/animation.cpp:435
+#, fuzzy
+msgid ""
+"PSX cutscenes found but ScummVM has been built without RGB color support"
+msgstr ""
+"Vídeos no formato DXA foram encontrados, mas o ScummVM foi compilado sem "
+"suporte a zlib"
+
#: engines/parallaction/saveload.cpp:133
#, c-format
msgid ""
@@ -2145,7 +2238,7 @@ msgstr "Emulador MAME OPL"
msgid "DOSBox OPL emulator"
msgstr "Emulador DOSBox OPL"
-#: audio/mididrv.cpp:205
+#: audio/mididrv.cpp:209
#, c-format
msgid ""
"The selected audio device '%s' was not found (e.g. might be turned off or "
@@ -2154,12 +2247,12 @@ msgstr ""
"O dispositivo de áudio selecionado '%s' não foi encontrado (ex: pode estar "
"desligado ou desconectado)."
-#: audio/mididrv.cpp:205 audio/mididrv.cpp:217 audio/mididrv.cpp:253
-#: audio/mididrv.cpp:268
+#: audio/mididrv.cpp:209 audio/mididrv.cpp:221 audio/mididrv.cpp:257
+#: audio/mididrv.cpp:272
msgid "Attempting to fall back to the next available device..."
msgstr "Tentando retornar para o próximo dispositivo disponível..."
-#: audio/mididrv.cpp:217
+#: audio/mididrv.cpp:221
#, c-format
msgid ""
"The selected audio device '%s' cannot be used. See log file for more "
@@ -2168,7 +2261,7 @@ msgstr ""
"O dispositivo de áudio selecionado '%s' não pode ser usado. Veja o arquivo "
"de log para mais informações."
-#: audio/mididrv.cpp:253
+#: audio/mididrv.cpp:257
#, c-format
msgid ""
"The preferred audio device '%s' was not found (e.g. might be turned off or "
@@ -2177,7 +2270,7 @@ msgstr ""
"O dispositivo de áudio preferido '%s' não foi encontrado (ex: pode estar "
"desligado ou desconectado)."
-#: audio/mididrv.cpp:268
+#: audio/mididrv.cpp:272
#, c-format
msgid ""
"The preferred audio device '%s' cannot be used. See log file for more "
@@ -2194,7 +2287,7 @@ msgstr "Sem música"
msgid "Amiga Audio Emulator"
msgstr "Emulador Som Amiga"
-#: audio/softsynth/adlib.cpp:1594
+#: audio/softsynth/adlib.cpp:1593
msgid "AdLib Emulator"
msgstr "Emulador AdLib"
@@ -2206,11 +2299,11 @@ msgstr "Emulador Apple II GS (NÃO IMPLEMENTADO)"
msgid "C64 Audio Emulator"
msgstr "Emulador Som C64"
-#: audio/softsynth/mt32.cpp:329
+#: audio/softsynth/mt32.cpp:293
msgid "Initializing MT-32 Emulator"
msgstr "Inicializando Emulador MT-32"
-#: audio/softsynth/mt32.cpp:543
+#: audio/softsynth/mt32.cpp:512
msgid "MT-32 Emulator"
msgstr "Emulador MT-32"
@@ -2226,15 +2319,24 @@ msgstr "Emulador IBM PCjr"
msgid "Keymap:"
msgstr "Mapa de Teclas:"
-#: backends/keymapper/remap-dialog.cpp:64
+#: backends/keymapper/remap-dialog.cpp:66
+#, fuzzy
+msgid " (Effective)"
+msgstr "(Ativo)"
+
+#: backends/keymapper/remap-dialog.cpp:106
msgid " (Active)"
msgstr "(Ativo)"
-#: backends/keymapper/remap-dialog.cpp:98
+#: backends/keymapper/remap-dialog.cpp:106
+msgid " (Blocked)"
+msgstr ""
+
+#: backends/keymapper/remap-dialog.cpp:119
msgid " (Global)"
msgstr "(Global)"
-#: backends/keymapper/remap-dialog.cpp:108
+#: backends/keymapper/remap-dialog.cpp:127
msgid " (Game)"
msgstr "(Jogo)"
@@ -2314,40 +2416,64 @@ msgstr "Som de alta qualidade (mais lento) (reiniciar)"
msgid "Disable power off"
msgstr "Desativar desligamento"
-#: backends/platform/iphone/osys_events.cpp:338
+#: backends/platform/iphone/osys_events.cpp:301
msgid "Mouse-click-and-drag mode enabled."
msgstr "Modo clique-e-arraste do mouse ligado."
-#: backends/platform/iphone/osys_events.cpp:340
+#: backends/platform/iphone/osys_events.cpp:303
msgid "Mouse-click-and-drag mode disabled."
msgstr "Modo clique-e-arraste do mouse desligado."
-#: backends/platform/iphone/osys_events.cpp:351
+#: backends/platform/iphone/osys_events.cpp:314
msgid "Touchpad mode enabled."
msgstr "Modo Touchpad ligado."
-#: backends/platform/iphone/osys_events.cpp:353
+#: backends/platform/iphone/osys_events.cpp:316
msgid "Touchpad mode disabled."
msgstr "Modo Touchpad desligado."
-#: backends/platform/sdl/macosx/appmenu_osx.mm:67
+#: backends/platform/maemo/maemo.cpp:205
+msgid "Click Mode"
+msgstr ""
+
+#: backends/platform/maemo/maemo.cpp:211
+#: backends/platform/symbian/src/SymbianActions.cpp:42
+#: backends/platform/wince/CEActionsPocket.cpp:60
+#: backends/platform/wince/CEActionsSmartphone.cpp:43
+#: backends/platform/bada/form.cpp:281
+msgid "Left Click"
+msgstr "Clique com o botão esquerdo"
+
+#: backends/platform/maemo/maemo.cpp:214
+#, fuzzy
+msgid "Middle Click"
+msgstr "Item do meio na esquerda"
+
+#: backends/platform/maemo/maemo.cpp:217
+#: backends/platform/symbian/src/SymbianActions.cpp:43
+#: backends/platform/wince/CEActionsSmartphone.cpp:44
+#: backends/platform/bada/form.cpp:273
+msgid "Right Click"
+msgstr "Clique com o botão direito"
+
+#: backends/platform/sdl/macosx/appmenu_osx.mm:78
msgid "Hide ScummVM"
msgstr "Ocultar ScummVM"
-#: backends/platform/sdl/macosx/appmenu_osx.mm:70
+#: backends/platform/sdl/macosx/appmenu_osx.mm:83
msgid "Hide Others"
msgstr "Ocultar Outros"
-#: backends/platform/sdl/macosx/appmenu_osx.mm:74
+#: backends/platform/sdl/macosx/appmenu_osx.mm:88
msgid "Show All"
-msgstr "Exibir Todos"
+msgstr "Mostrar Tudo"
-#: backends/platform/sdl/macosx/appmenu_osx.mm:92
-#: backends/platform/sdl/macosx/appmenu_osx.mm:99
+#: backends/platform/sdl/macosx/appmenu_osx.mm:110
+#: backends/platform/sdl/macosx/appmenu_osx.mm:121
msgid "Window"
msgstr "Janela"
-#: backends/platform/sdl/macosx/appmenu_osx.mm:95
+#: backends/platform/sdl/macosx/appmenu_osx.mm:115
msgid "Minimize"
msgstr "Minimizar"
@@ -2361,12 +2487,12 @@ msgid "Normal (no scaling)"
msgstr "Normal (sem escala)"
#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2147
-#: backends/graphics/openglsdl/openglsdl-graphics.cpp:537
+#: backends/graphics/openglsdl/openglsdl-graphics.cpp:533
msgid "Enabled aspect ratio correction"
msgstr "Correção de proporção habilitada"
#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2153
-#: backends/graphics/openglsdl/openglsdl-graphics.cpp:542
+#: backends/graphics/openglsdl/openglsdl-graphics.cpp:538
msgid "Disabled aspect ratio correction"
msgstr "Correção de proporção desabilitada"
@@ -2375,7 +2501,7 @@ msgid "Active graphics filter:"
msgstr "Ativa os filtros gráficos"
#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2250
-#: backends/graphics/openglsdl/openglsdl-graphics.cpp:481
+#: backends/graphics/openglsdl/openglsdl-graphics.cpp:477
msgid "Windowed mode"
msgstr "Modo janela"
@@ -2399,11 +2525,11 @@ msgstr "Modo de vídeo atual"
msgid "Current scale"
msgstr "Escala atual"
-#: backends/graphics/openglsdl/openglsdl-graphics.cpp:562
+#: backends/graphics/openglsdl/openglsdl-graphics.cpp:558
msgid "Active filter mode: Linear"
msgstr "Filtro de imagem ativo: Linear"
-#: backends/graphics/openglsdl/openglsdl-graphics.cpp:564
+#: backends/graphics/openglsdl/openglsdl-graphics.cpp:560
msgid "Active filter mode: Nearest"
msgstr "Filtro de imagem ativo: Nearest"
@@ -2427,19 +2553,6 @@ msgstr "Esquerda"
msgid "Right"
msgstr "Direita"
-#: backends/platform/symbian/src/SymbianActions.cpp:42
-#: backends/platform/wince/CEActionsPocket.cpp:60
-#: backends/platform/wince/CEActionsSmartphone.cpp:43
-#: backends/platform/bada/form.cpp:281
-msgid "Left Click"
-msgstr "Clique com o botão esquerdo"
-
-#: backends/platform/symbian/src/SymbianActions.cpp:43
-#: backends/platform/wince/CEActionsSmartphone.cpp:44
-#: backends/platform/bada/form.cpp:273
-msgid "Right Click"
-msgstr "Clique com o botão direito"
-
#: backends/platform/symbian/src/SymbianActions.cpp:46
#: backends/platform/wince/CEActionsSmartphone.cpp:47
msgid "Zone"
@@ -2729,15 +2842,15 @@ msgstr ""
"Não se esqueça de mapear uma tecla para \"Ocultar a barra de ferramentas\" "
"para ver todo o seu inventário"
-#: backends/events/default/default-events.cpp:222
+#: backends/events/default/default-events.cpp:191
msgid "Do you really want to return to the Launcher?"
msgstr "Você realmente deseja voltar para o menu principal?"
-#: backends/events/default/default-events.cpp:222
+#: backends/events/default/default-events.cpp:191
msgid "Launcher"
msgstr "Menu principal"
-#: backends/events/default/default-events.cpp:244
+#: backends/events/default/default-events.cpp:213
msgid "Do you really want to quit?"
msgstr "Você realmente deseja sair?"
@@ -2803,14 +2916,31 @@ msgstr "Mostrar teclado"
msgid "Control Mouse"
msgstr "Controle do Mouse"
-#: backends/events/maemosdl/maemosdl-events.cpp:121
+#: backends/events/maemosdl/maemosdl-events.cpp:192
msgid "Clicking Enabled"
msgstr "Clicando Habilitado"
-#: backends/events/maemosdl/maemosdl-events.cpp:121
+#: backends/events/maemosdl/maemosdl-events.cpp:192
msgid "Clicking Disabled"
msgstr "Clicando Desabilitado"
+#~ msgid "Hercules Green"
+#~ msgstr "Hercules Green"
+
+#~ msgid "Hercules Amber"
+#~ msgstr "Hercules Amber"
+
+#~ msgctxt "lowres"
+#~ msgid "Hercules Green"
+#~ msgstr "Hercules Green"
+
+#~ msgctxt "lowres"
+#~ msgid "Hercules Amber"
+#~ msgstr "Hercules Amber"
+
+#~ msgid "Save game failed!"
+#~ msgstr "Falha ao salvar jogo!"
+
#~ msgctxt "lowres"
#~ msgid "Add Game..."
#~ msgstr "Adicionar Jogo..."
diff --git a/po/ru_RU.po b/po/ru_RU.po
index 9ff97d9282..fe2204f6e5 100644
--- a/po/ru_RU.po
+++ b/po/ru_RU.po
@@ -1,22 +1,22 @@
-# Russian translation for ScummVM.
-# Copyright (C) 2010-2011 ScummVM Team
-# This file is distributed under the same license as the ScummVM package.
-# Eugene Sandulenko <sev@scummvm.org>, 2010.
-#
+# Russian translation for ScummVM.
+# Copyright (C) 2010-2012 ScummVM Team
+# This file is distributed under the same license as the ScummVM package.
+# Eugene Sandulenko <sev@scummvm.org>, 2010.
+#
msgid ""
msgstr ""
"Project-Id-Version: ScummVM 1.3.0svn\n"
"Report-Msgid-Bugs-To: scummvm-devel@lists.sf.net\n"
-"POT-Creation-Date: 2011-10-19 13:42+0100\n"
-"PO-Revision-Date: 2011-08-20 13:22+0200\n"
+"POT-Creation-Date: 2012-03-07 22:09+0000\n"
+"PO-Revision-Date: 2012-02-16 13:09+0200+0200\n"
"Last-Translator: Eugene Sandulenko <sev@scummvm.org>\n"
"Language-Team: Russian\n"
-"Language: Russian\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=iso-8859-5\n"
"Content-Transfer-Encoding: 8bit\n"
-"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n"
-"%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
+"Language: Russian\n"
+"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%"
+"10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
#: gui/about.cpp:91
#, c-format
@@ -45,13 +45,13 @@ msgid "Go up"
msgstr "²ÒÕàå"
#: gui/browser.cpp:69 gui/chooser.cpp:45 gui/KeysDialog.cpp:43
-#: gui/launcher.cpp:312 gui/massadd.cpp:94 gui/options.cpp:1178
+#: gui/launcher.cpp:320 gui/massadd.cpp:94 gui/options.cpp:1253
#: gui/saveload.cpp:63 gui/saveload.cpp:155 gui/themebrowser.cpp:54
-#: engines/engine.cpp:436 engines/scumm/dialogs.cpp:190
+#: engines/engine.cpp:442 engines/scumm/dialogs.cpp:190
#: engines/sword1/control.cpp:865 engines/parallaction/saveload.cpp:281
#: backends/platform/wii/options.cpp:48
-#: backends/events/default/default-events.cpp:222
-#: backends/events/default/default-events.cpp:244
+#: backends/events/default/default-events.cpp:191
+#: backends/events/default/default-events.cpp:213
msgid "Cancel"
msgstr "¾âÜÕÝÐ"
@@ -59,25 +59,29 @@ msgstr "¾âÜÕÝÐ"
msgid "Choose"
msgstr "²ëÑàÐâì"
-#: gui/gui-manager.cpp:116 engines/scumm/help.cpp:125
+#: gui/gui-manager.cpp:115 engines/scumm/help.cpp:125
#: engines/scumm/help.cpp:140 engines/scumm/help.cpp:165
#: engines/scumm/help.cpp:191 engines/scumm/help.cpp:209
#: backends/keymapper/remap-dialog.cpp:52
msgid "Close"
msgstr "·ÐÚàëâì"
-#: gui/gui-manager.cpp:119
+#: gui/gui-manager.cpp:118
msgid "Mouse click"
msgstr "ºÛØÚ Üëèìî"
-#: gui/gui-manager.cpp:122 base/main.cpp:283
+#: gui/gui-manager.cpp:122 base/main.cpp:288
msgid "Display keyboard"
msgstr "¿ÞÚÐ×Ðâì ÚÛÐÒØÐâãàã"
-#: gui/gui-manager.cpp:125 base/main.cpp:286
+#: gui/gui-manager.cpp:126 base/main.cpp:292
msgid "Remap keys"
msgstr "¿ÕàÕÝÐ×ÝÐçØâì ÚÛÐÒØèØ"
+#: gui/gui-manager.cpp:129 base/main.cpp:295
+msgid "Toggle FullScreen"
+msgstr "¿ÕàÕÚÛîçÕÝØÕ ÝÐ ÒÕáì íÚàÐÝ"
+
#: gui/KeysDialog.h:36 gui/KeysDialog.cpp:145
msgid "Choose an action to map"
msgstr "²ëÑÕàØâÕ ÔÕÙáâÒØÕ ÔÛï ÝÐ×ÝÐçÕÝØï"
@@ -86,16 +90,17 @@ msgstr "²ëÑÕàØâÕ ÔÕÙáâÒØÕ ÔÛï ÝÐ×ÝÐçÕÝØï"
msgid "Map"
msgstr "½Ð×ÝÐçØâì"
-#: gui/KeysDialog.cpp:42 gui/launcher.cpp:313 gui/launcher.cpp:936
-#: gui/launcher.cpp:940 gui/massadd.cpp:91 gui/options.cpp:1179
-#: engines/engine.cpp:359 engines/engine.cpp:370 engines/scumm/dialogs.cpp:192
-#: engines/scumm/scumm.cpp:1776 engines/agos/animation.cpp:551
+#: gui/KeysDialog.cpp:42 gui/launcher.cpp:321 gui/launcher.cpp:960
+#: gui/launcher.cpp:964 gui/massadd.cpp:91 gui/options.cpp:1254
+#: engines/engine.cpp:361 engines/engine.cpp:372 engines/scumm/dialogs.cpp:192
+#: engines/scumm/scumm.cpp:1775 engines/agos/animation.cpp:551
#: engines/groovie/script.cpp:420 engines/sky/compact.cpp:131
-#: engines/sky/compact.cpp:141 engines/sword1/animation.cpp:344
-#: engines/sword1/animation.cpp:354 engines/sword1/animation.cpp:360
-#: engines/sword1/control.cpp:865 engines/sword1/logic.cpp:1633
-#: engines/sword2/animation.cpp:379 engines/sword2/animation.cpp:389
-#: engines/sword2/animation.cpp:398 engines/parallaction/saveload.cpp:281
+#: engines/sky/compact.cpp:141 engines/sword1/animation.cpp:539
+#: engines/sword1/animation.cpp:560 engines/sword1/animation.cpp:570
+#: engines/sword1/animation.cpp:577 engines/sword1/control.cpp:865
+#: engines/sword1/logic.cpp:1633 engines/sword2/animation.cpp:435
+#: engines/sword2/animation.cpp:455 engines/sword2/animation.cpp:465
+#: engines/sword2/animation.cpp:474 engines/parallaction/saveload.cpp:281
#: backends/platform/wii/options.cpp:47
#: backends/platform/wince/CELauncherDialog.cpp:54
msgid "OK"
@@ -123,15 +128,15 @@ msgstr "¿ÞÖÐÛãÙáâÐ, ÒëÑÕàØâÕ ÔÕÙáâÒØÕ"
msgid "Press the key to associate"
msgstr "½ÐÖÜØâÕ ÚÛÐÒØèã ÔÛï ÝÐ×ÝÐçÕÝØï"
-#: gui/launcher.cpp:165
+#: gui/launcher.cpp:170
msgid "Game"
msgstr "¸ÓàÐ"
-#: gui/launcher.cpp:169
+#: gui/launcher.cpp:174
msgid "ID:"
msgstr "ID:"
-#: gui/launcher.cpp:169 gui/launcher.cpp:171 gui/launcher.cpp:172
+#: gui/launcher.cpp:174 gui/launcher.cpp:176 gui/launcher.cpp:177
msgid ""
"Short game identifier used for referring to savegames and running the game "
"from the command line"
@@ -139,311 +144,309 @@ msgstr ""
"ºÞàÞâÚØÙ ØÔÕÝâØäØÚÐâÞà, ØáßÞÛì×ãÕÜëÙ ÔÛï ØÜÕÝ áÞåàÐÝÕÝØÙ ØÓà Ø ÔÛï ×ÐßãáÚÐ "
"Ø× ÚÞÜÐÝÔÝÞÙ áâàÞÚØ"
-#: gui/launcher.cpp:171
+#: gui/launcher.cpp:176
msgctxt "lowres"
msgid "ID:"
msgstr "ID:"
-#: gui/launcher.cpp:176
+#: gui/launcher.cpp:181
msgid "Name:"
msgstr "½Ð×ÒÐÝØÕ:"
-#: gui/launcher.cpp:176 gui/launcher.cpp:178 gui/launcher.cpp:179
+#: gui/launcher.cpp:181 gui/launcher.cpp:183 gui/launcher.cpp:184
msgid "Full title of the game"
msgstr "¿ÞÛÝÞÕ ÝÐ×ÒÐÝØÕ ØÓàë"
-#: gui/launcher.cpp:178
+#: gui/launcher.cpp:183
msgctxt "lowres"
msgid "Name:"
msgstr "½Ð×Ò:"
-#: gui/launcher.cpp:182
+#: gui/launcher.cpp:187
msgid "Language:"
msgstr "Ï×ëÚ:"
-#: gui/launcher.cpp:182 gui/launcher.cpp:183
+#: gui/launcher.cpp:187 gui/launcher.cpp:188
msgid ""
"Language of the game. This will not turn your Spanish game version into "
"English"
msgstr ""
"Ï×ëÚ ØÓàë. ¸×ÜÕÝÕÝØÕ íâÞÙ ÝÐáâàÞÙÚØ ÝÕ ßàÕÒàÐâØâ ØÓàã ÝÐ ÐÝÓÛØÙáÚÞÜ Ò àãááÚãî"
-#: gui/launcher.cpp:184 gui/launcher.cpp:198 gui/options.cpp:74
-#: gui/options.cpp:708 gui/options.cpp:718 gui/options.cpp:1149
+#: gui/launcher.cpp:189 gui/launcher.cpp:203 gui/options.cpp:80
+#: gui/options.cpp:745 gui/options.cpp:758 gui/options.cpp:1224
#: audio/null.cpp:40
msgid "<default>"
msgstr "<ßÞ ãÜÞÛçÐÝØî>"
-#: gui/launcher.cpp:194
+#: gui/launcher.cpp:199
msgid "Platform:"
msgstr "¿ÛÐâäÞàÜÐ:"
-#: gui/launcher.cpp:194 gui/launcher.cpp:196 gui/launcher.cpp:197
+#: gui/launcher.cpp:199 gui/launcher.cpp:201 gui/launcher.cpp:202
msgid "Platform the game was originally designed for"
msgstr "¿ÛÐâäÞàÜÐ, ÔÛï ÚÞâÞàÞÙ ØÓàÐ ÑëÛÐ Ø×ÝÐçÐÛìÝÞ àÐ×àÐÑÞâÐÝÐ"
-#: gui/launcher.cpp:196
+#: gui/launcher.cpp:201
msgctxt "lowres"
msgid "Platform:"
msgstr "¿ÛÐâäÞàÜÐ:"
-#: gui/launcher.cpp:208 gui/options.cpp:1018 gui/options.cpp:1035
+#: gui/launcher.cpp:213 gui/options.cpp:1087 gui/options.cpp:1104
msgid "Graphics"
msgstr "³àÐäØÚÐ"
-#: gui/launcher.cpp:208 gui/options.cpp:1018 gui/options.cpp:1035
+#: gui/launcher.cpp:213 gui/options.cpp:1087 gui/options.cpp:1104
msgid "GFX"
msgstr "³àä"
-#: gui/launcher.cpp:211
+#: gui/launcher.cpp:216
msgid "Override global graphic settings"
msgstr "¿ÕàÕÚàëâì ÓÛÞÑÐÛìÝëÕ ãáâÐÝÞÒÚØ ÓàÐäØÚØ"
-#: gui/launcher.cpp:213
+#: gui/launcher.cpp:218
msgctxt "lowres"
msgid "Override global graphic settings"
msgstr "¿ÕàÕÚàëâì ÓÛÞÑÐÛìÝëÕ ãáâÐÝÞÒÚØ ÓàÐäØÚØ"
-#: gui/launcher.cpp:220 gui/options.cpp:1041
+#: gui/launcher.cpp:225 gui/options.cpp:1110
msgid "Audio"
msgstr "°ãÔØÞ"
-#: gui/launcher.cpp:223
+#: gui/launcher.cpp:228
msgid "Override global audio settings"
msgstr "¿ÕàÕÚàëâì ÓÛÞÑÐÛìÝëÕ ãáâÐÝÞÒÚØ ÐãÔØÞ"
-#: gui/launcher.cpp:225
+#: gui/launcher.cpp:230
msgctxt "lowres"
msgid "Override global audio settings"
msgstr "¿ÕàÕÚàëâì ÓÛÞÑÐÛìÝëÕ ãáâÐÝÞÒÚØ ÐãÔØÞ"
-#: gui/launcher.cpp:234 gui/options.cpp:1046
+#: gui/launcher.cpp:239 gui/options.cpp:1115
msgid "Volume"
msgstr "³àÞÜÚÞáâì"
-#: gui/launcher.cpp:236 gui/options.cpp:1048
+#: gui/launcher.cpp:241 gui/options.cpp:1117
msgctxt "lowres"
msgid "Volume"
msgstr "³àÞÜÚ"
-#: gui/launcher.cpp:239
+#: gui/launcher.cpp:244
msgid "Override global volume settings"
msgstr "¿ÕàÕÚàëâì ÓÛÞÑÐÛìÝëÕ ãáâÐÝÞÒÚØ ÓàÞÜÚÞáâØ"
-#: gui/launcher.cpp:241
+#: gui/launcher.cpp:246
msgctxt "lowres"
msgid "Override global volume settings"
msgstr "¿ÕàÕÚàëâì ÓÛÞÑÐÛìÝëÕ ãáâÐÝÞÒÚØ ÓàÞÜÚÞáâØ"
-#: gui/launcher.cpp:248 gui/options.cpp:1056
+#: gui/launcher.cpp:254 gui/options.cpp:1125
msgid "MIDI"
msgstr "MIDI"
-#: gui/launcher.cpp:251
+#: gui/launcher.cpp:257
msgid "Override global MIDI settings"
msgstr "¿ÕàÕÚàëâì ÓÛÞÑÐÛìÝëÕ ãáâÐÝÞÒÚØ MIDI"
-#: gui/launcher.cpp:253
+#: gui/launcher.cpp:259
msgctxt "lowres"
msgid "Override global MIDI settings"
msgstr "¿ÕàÕÚàëâì ÓÛÞÑÐÛìÝëÕ ãáâÐÝÞÒÚØ MIDI"
-#: gui/launcher.cpp:263 gui/options.cpp:1062
+#: gui/launcher.cpp:268 gui/options.cpp:1131
msgid "MT-32"
msgstr "MT-32"
-#: gui/launcher.cpp:266
+#: gui/launcher.cpp:271
msgid "Override global MT-32 settings"
msgstr "¿ÕàÕÚàëâì ÓÛÞÑÐÛìÝëÕ ãáâÐÝÞÒÚØ MT-32"
-#: gui/launcher.cpp:268
+#: gui/launcher.cpp:273
msgctxt "lowres"
msgid "Override global MT-32 settings"
msgstr "¿ÕàÕÚàëâì ÓÛÞÑÐÛìÝëÕ ãáâÐÝÞÒÚØ MT-32"
-#: gui/launcher.cpp:279 gui/options.cpp:1069
+#: gui/launcher.cpp:282 gui/options.cpp:1138
msgid "Paths"
msgstr "¿ãâØ"
-#: gui/launcher.cpp:281 gui/options.cpp:1071
+#: gui/launcher.cpp:284 gui/options.cpp:1140
msgctxt "lowres"
msgid "Paths"
msgstr "¿ãâØ"
-#: gui/launcher.cpp:288
+#: gui/launcher.cpp:291
msgid "Game Path:"
msgstr "¿ãâì Ú ØÓàÕ:"
-#: gui/launcher.cpp:290
+#: gui/launcher.cpp:293
msgctxt "lowres"
msgid "Game Path:"
msgstr "³ÔÕ ØÓàÐ:"
-#: gui/launcher.cpp:295 gui/options.cpp:1091
+#: gui/launcher.cpp:298 gui/options.cpp:1164
msgid "Extra Path:"
msgstr "´Þß. ßãâì:"
-#: gui/launcher.cpp:295 gui/launcher.cpp:297 gui/launcher.cpp:298
+#: gui/launcher.cpp:298 gui/launcher.cpp:300 gui/launcher.cpp:301
msgid "Specifies path to additional data used the game"
msgstr "ÃÚÐ×ëÒÐÕâ ßãâì Ú ÔÞßÞÛÝØâÕÛìÝëÜ äÐÙÛÐÜ ÔÐÝÝëå ÔÛï ØÓàë"
-#: gui/launcher.cpp:297 gui/options.cpp:1093
+#: gui/launcher.cpp:300 gui/options.cpp:1166
msgctxt "lowres"
msgid "Extra Path:"
msgstr "´Þß. ßãâì:"
-#: gui/launcher.cpp:302 gui/options.cpp:1079
+#: gui/launcher.cpp:307 gui/options.cpp:1148
msgid "Save Path:"
msgstr "ÁÞåàÐÝÕÝØï ØÓà:"
-#: gui/launcher.cpp:302 gui/launcher.cpp:304 gui/launcher.cpp:305
-#: gui/options.cpp:1079 gui/options.cpp:1081 gui/options.cpp:1082
+#: gui/launcher.cpp:307 gui/launcher.cpp:309 gui/launcher.cpp:310
+#: gui/options.cpp:1148 gui/options.cpp:1150 gui/options.cpp:1151
msgid "Specifies where your savegames are put"
msgstr "ÃÚÐ×ëÒÐÕâ ßãâì Ú áÞåàÐÝÕÝØïÜ ØÓàë"
-#: gui/launcher.cpp:304 gui/options.cpp:1081
+#: gui/launcher.cpp:309 gui/options.cpp:1150
msgctxt "lowres"
msgid "Save Path:"
msgstr "¿ãâì áÞåà:"
-#: gui/launcher.cpp:321 gui/launcher.cpp:404 gui/launcher.cpp:453
-#: gui/options.cpp:1088 gui/options.cpp:1094 gui/options.cpp:1101
-#: gui/options.cpp:1202 gui/options.cpp:1208 gui/options.cpp:1214
-#: gui/options.cpp:1222 gui/options.cpp:1246 gui/options.cpp:1250
-#: gui/options.cpp:1256 gui/options.cpp:1263 gui/options.cpp:1362
+#: gui/launcher.cpp:329 gui/launcher.cpp:416 gui/launcher.cpp:469
+#: gui/launcher.cpp:523 gui/options.cpp:1159 gui/options.cpp:1167
+#: gui/options.cpp:1176 gui/options.cpp:1283 gui/options.cpp:1289
+#: gui/options.cpp:1297 gui/options.cpp:1327 gui/options.cpp:1333
+#: gui/options.cpp:1340 gui/options.cpp:1433 gui/options.cpp:1436
+#: gui/options.cpp:1448
msgctxt "path"
msgid "None"
msgstr "½Õ ×ÐÔÐÝ"
-#: gui/launcher.cpp:326 gui/launcher.cpp:408
+#: gui/launcher.cpp:334 gui/launcher.cpp:422 gui/launcher.cpp:527
+#: gui/options.cpp:1277 gui/options.cpp:1321 gui/options.cpp:1439
#: backends/platform/wii/options.cpp:56
msgid "Default"
msgstr "¿Þ ãÜÞÛçÐÝØî"
-#: gui/launcher.cpp:446 gui/options.cpp:1356
+#: gui/launcher.cpp:462 gui/options.cpp:1442
msgid "Select SoundFont"
msgstr "²ëÑÕàØâÕ SoundFont"
-#: gui/launcher.cpp:465 gui/launcher.cpp:612
+#: gui/launcher.cpp:481 gui/launcher.cpp:636
msgid "Select directory with game data"
msgstr "²ëÑÕàØâÕ ÔØàÕÚâÞàØî á äÐÙÛÐÜØ ØÓàë"
-#: gui/launcher.cpp:483
+#: gui/launcher.cpp:499
msgid "Select additional game directory"
msgstr "²ëÑÕàØâÕ ÔÞßÞÛÝØâÕÛìÝãî ÔØàÕÚâÞàØî ØÓàë"
-#: gui/launcher.cpp:495
+#: gui/launcher.cpp:511
msgid "Select directory for saved games"
msgstr "²ëÑÕàØâÕ ÔØàÕÚâÞàØî ÔÛï áÞåàÐÝÕÝØÙ"
-#: gui/launcher.cpp:514
+#: gui/launcher.cpp:538
msgid "This game ID is already taken. Please choose another one."
msgstr "ÍâÞâ ID ØÓàë ãÖÕ ØáßÞÛì×ãÕâáï. ¿ÞÖÐÛãÙáâÐ, ÒëÑÕàØâÕ ÔàãÓÞÙ."
-#: gui/launcher.cpp:555 engines/dialogs.cpp:110
+#: gui/launcher.cpp:579 engines/dialogs.cpp:110
msgid "~Q~uit"
msgstr "~²~ëåÞÔ"
-#: gui/launcher.cpp:555 backends/platform/sdl/macosx/appmenu_osx.mm:80
+#: gui/launcher.cpp:579 backends/platform/sdl/macosx/appmenu_osx.mm:96
msgid "Quit ScummVM"
-msgstr "²ëåÞÔ Ø× ScummVM"
+msgstr "·ÐÒÕàèØâì ScummVM"
-#: gui/launcher.cpp:556
+#: gui/launcher.cpp:580
msgid "A~b~out..."
msgstr "¾ ß~à~ÞÓàÐÜÜÕ..."
-#: gui/launcher.cpp:556 backends/platform/sdl/macosx/appmenu_osx.mm:61
+#: gui/launcher.cpp:580 backends/platform/sdl/macosx/appmenu_osx.mm:70
msgid "About ScummVM"
msgstr "¾ ßàÞÓàÐÜÜÕ ScummVM"
-#: gui/launcher.cpp:557
+#: gui/launcher.cpp:581
msgid "~O~ptions..."
msgstr "~½~ÐáâàÞÙÚØ..."
-#: gui/launcher.cpp:557
+#: gui/launcher.cpp:581
msgid "Change global ScummVM options"
msgstr "¸×ÜÕÝØâì ÓÛÞÑÐÛìÝëÕ ÝÐáâàÞÙÚØ ScummVM"
-#: gui/launcher.cpp:559
+#: gui/launcher.cpp:583
msgid "~S~tart"
msgstr "¿~ã~áÚ"
-#: gui/launcher.cpp:559
+#: gui/launcher.cpp:583
msgid "Start selected game"
msgstr "·ÐßãáâØâì ÒëÑàÐÝÝãî ØÓàã"
-#: gui/launcher.cpp:562
+#: gui/launcher.cpp:586
msgid "~L~oad..."
msgstr "~·~ÐÓàã×Øâì..."
-#: gui/launcher.cpp:562
+#: gui/launcher.cpp:586
msgid "Load savegame for selected game"
msgstr "·ÐÓàã×Øâì áÞåàÝÕÝØÕ ÔÛï ÒëÑàÐÝÝÞÙ ØÓàë"
-#: gui/launcher.cpp:567 gui/launcher.cpp:1055
+#: gui/launcher.cpp:591 gui/launcher.cpp:1079
msgid "~A~dd Game..."
msgstr "~´~ÞÑÐÒØâì ØÓàã..."
-#: gui/launcher.cpp:567 gui/launcher.cpp:574
+#: gui/launcher.cpp:591 gui/launcher.cpp:598
msgid "Hold Shift for Mass Add"
msgstr "ÃÔÕàÖØÒÐÙâÕ ÚÛÐÒØèã Shift ÔÛï âÞÓÞ, çâÞÑë ÔÞÑÐÒØâì ÝÕáÚÞÛìÚÞ ØÓà"
-#: gui/launcher.cpp:569
+#: gui/launcher.cpp:593
msgid "~E~dit Game..."
msgstr "½~Ð~áâàÞÙÚØ ØÓàë..."
-#: gui/launcher.cpp:569 gui/launcher.cpp:576
+#: gui/launcher.cpp:593 gui/launcher.cpp:600
msgid "Change game options"
msgstr "¸×ÜÕÝØâì ÝÐáâàÞÙÚØ ØÓàë"
-#: gui/launcher.cpp:571
+#: gui/launcher.cpp:595
msgid "~R~emove Game"
msgstr "~Ã~ÔÐÛØâì ØÓàã"
-#: gui/launcher.cpp:571 gui/launcher.cpp:578
+#: gui/launcher.cpp:595 gui/launcher.cpp:602
msgid "Remove game from the list. The game data files stay intact"
msgstr "ÃÔÐÛØâì ØÓàã Ø× áßØáÚÐ. ½Õ ãÔÐÛïÕâ ØÓàã á ÖÕáâÚÞÓÞ ÔØáÚÐ"
-#: gui/launcher.cpp:574 gui/launcher.cpp:1055
+#: gui/launcher.cpp:598 gui/launcher.cpp:1079
msgctxt "lowres"
msgid "~A~dd Game..."
msgstr "~´~ÞÑ. ØÓàã..."
-#: gui/launcher.cpp:576
+#: gui/launcher.cpp:600
msgctxt "lowres"
msgid "~E~dit Game..."
msgstr "½~Ð~á. ØÓàë..."
-#: gui/launcher.cpp:578
+#: gui/launcher.cpp:602
msgctxt "lowres"
msgid "~R~emove Game"
msgstr "~Ã~ÔÐÛØâì ØÓàã"
-#: gui/launcher.cpp:586
+#: gui/launcher.cpp:610
msgid "Search in game list"
msgstr "¿ÞØáÚ Ò áßØáÚÕ ØÓà"
-#: gui/launcher.cpp:590 gui/launcher.cpp:1102
+#: gui/launcher.cpp:614 gui/launcher.cpp:1126
msgid "Search:"
msgstr "¿ÞØáÚ:"
-#: gui/launcher.cpp:593 gui/options.cpp:826
-msgid "Clear value"
-msgstr "¾çØáâØâì ×ÝÐçÕÝØÕ"
-
-#: gui/launcher.cpp:615 engines/dialogs.cpp:114 engines/mohawk/myst.cpp:255
+#: gui/launcher.cpp:639 engines/dialogs.cpp:114 engines/mohawk/myst.cpp:255
#: engines/mohawk/riven.cpp:716 engines/cruise/menu.cpp:216
msgid "Load game:"
msgstr "·ÐÓàã×Øâì ØÓàã:"
-#: gui/launcher.cpp:615 engines/dialogs.cpp:114 engines/scumm/dialogs.cpp:188
+#: gui/launcher.cpp:639 engines/dialogs.cpp:114 engines/scumm/dialogs.cpp:188
#: engines/mohawk/myst.cpp:255 engines/mohawk/riven.cpp:716
#: engines/cruise/menu.cpp:216 backends/platform/wince/CEActionsPocket.cpp:267
#: backends/platform/wince/CEActionsSmartphone.cpp:231
msgid "Load"
msgstr "·ÐÓàã×Øâì"
-#: gui/launcher.cpp:723
+#: gui/launcher.cpp:747
msgid ""
"Do you really want to run the mass game detector? This could potentially add "
"a huge number of games."
@@ -451,7 +454,7 @@ msgstr ""
"²ë ÔÕÙáâÒØâÕÛìÝÞ åÞâØâÕ ×ÐßãáâØâì ÔÕâÕÚâÞà ÒáÕå ØÓà? ÍâÞ ßÞâÕÝæØÐÛìÝÞ ÜÞÖÕâ "
"ÔÞÑÐÒØâì ÑÞÛìèÞÕ ÚÞÛØçÕáâÒÞ ØÓà."
-#: gui/launcher.cpp:724 gui/launcher.cpp:872
+#: gui/launcher.cpp:748 gui/launcher.cpp:896
#: backends/events/symbiansdl/symbiansdl-events.cpp:184
#: backends/platform/wince/CEActionsPocket.cpp:326
#: backends/platform/wince/CEActionsSmartphone.cpp:287
@@ -459,7 +462,7 @@ msgstr ""
msgid "Yes"
msgstr "´Ð"
-#: gui/launcher.cpp:724 gui/launcher.cpp:872
+#: gui/launcher.cpp:748 gui/launcher.cpp:896
#: backends/events/symbiansdl/symbiansdl-events.cpp:184
#: backends/platform/wince/CEActionsPocket.cpp:326
#: backends/platform/wince/CEActionsSmartphone.cpp:287
@@ -467,36 +470,36 @@ msgstr "´Ð"
msgid "No"
msgstr "½Õâ"
-#: gui/launcher.cpp:772
+#: gui/launcher.cpp:796
msgid "ScummVM couldn't open the specified directory!"
msgstr "ScummVM ÝÕ ÜÞÖÕâ ÞâÚàëâì ãÚÐ×ÐÝÝãî ÔØàÕÚâÞàØî!"
-#: gui/launcher.cpp:784
+#: gui/launcher.cpp:808
msgid "ScummVM could not find any game in the specified directory!"
msgstr "ScummVM ÝÕ ÜÞÖÕâ ÝÐÙâØ ØÓàã Ò ãÚÐ×ÐÝÝÞÙ ÔØàÕÚâÞàØØ!"
-#: gui/launcher.cpp:798
+#: gui/launcher.cpp:822
msgid "Pick the game:"
msgstr "²ëÑÕàØâÕ ØÓàã:"
-#: gui/launcher.cpp:872
+#: gui/launcher.cpp:896
msgid "Do you really want to remove this game configuration?"
msgstr "²ë ÔÕÙáâÒØâÕÛìÝÞ åÞâØâÕ ãÔÐÛØâì ÝÐáâàÞÙÚØ ÔÛï íâÞÙ ØÓàë?"
-#: gui/launcher.cpp:936
+#: gui/launcher.cpp:960
msgid "This game does not support loading games from the launcher."
msgstr "ÍâÐ ØÓàÐ ÝÕ ßÞÔÔÕàÖØÒÐÕâ ×ÐÓàã×Úã áÞåàÐÝÕÝØÙ çÕàÕ× ÓÛÐÒÝÞÕ ÜÕÝî."
-#: gui/launcher.cpp:940
+#: gui/launcher.cpp:964
msgid "ScummVM could not find any engine capable of running the selected game!"
msgstr "ScummVM ÝÕ áÜÞÓ ÝÐÙâØ ÔÒØÖÞÚ ÔÛï ×ÐßãáÚÐ ÒëÑàÐÝÝÞÙ ØÓàë!"
-#: gui/launcher.cpp:1054
+#: gui/launcher.cpp:1078
msgctxt "lowres"
msgid "Mass Add..."
msgstr "¼ÝÞÓÞ ØÓà..."
-#: gui/launcher.cpp:1054
+#: gui/launcher.cpp:1078
msgid "Mass Add..."
msgstr "¼ÝÞÓÞ ØÓà..."
@@ -523,144 +526,144 @@ msgstr "¿àÞáÜÞâàÕÝÞ %d ÔØàÕÚâÞàØÙ ..."
msgid "Discovered %d new games, ignored %d previously added games ..."
msgstr "½ÐÙÔÕÝÞ %d ÝÞÒëå ØÓà, ßàÞßãéÕÝÞ %d àÐÝÕÕ ÔÞÑÐÒÛÕÝÝëå ØÓà ..."
-#: gui/options.cpp:72
+#: gui/options.cpp:78
msgid "Never"
msgstr "½ØÚÞÓÔÐ"
-#: gui/options.cpp:72
+#: gui/options.cpp:78
msgid "every 5 mins"
msgstr "ÚÐÖÔëÕ 5 ÜØÝãâ"
-#: gui/options.cpp:72
+#: gui/options.cpp:78
msgid "every 10 mins"
msgstr "ÚÐÖÔëÕ 10 ÜØÝãâ"
-#: gui/options.cpp:72
+#: gui/options.cpp:78
msgid "every 15 mins"
msgstr "ÚÐÖÔëÕ 15 ÜØÝãâ"
-#: gui/options.cpp:72
+#: gui/options.cpp:78
msgid "every 30 mins"
msgstr "ÚÐÖÔëÕ 30 ÜØÝãâ"
-#: gui/options.cpp:74
+#: gui/options.cpp:80
msgid "8 kHz"
msgstr "8 Ú³æ"
-#: gui/options.cpp:74
+#: gui/options.cpp:80
msgid "11kHz"
msgstr "11 Ú³æ"
-#: gui/options.cpp:74
+#: gui/options.cpp:80
msgid "22 kHz"
msgstr "22 Ú³æ"
-#: gui/options.cpp:74
+#: gui/options.cpp:80
msgid "44 kHz"
msgstr "44 Ú³æ"
-#: gui/options.cpp:74
+#: gui/options.cpp:80
msgid "48 kHz"
msgstr "48 Ú³æ"
-#: gui/options.cpp:236 gui/options.cpp:464 gui/options.cpp:559
-#: gui/options.cpp:625 gui/options.cpp:825
+#: gui/options.cpp:257 gui/options.cpp:485 gui/options.cpp:586
+#: gui/options.cpp:659 gui/options.cpp:868
msgctxt "soundfont"
msgid "None"
msgstr "½Õ ×ÐÔÐÝ"
-#: gui/options.cpp:372
+#: gui/options.cpp:393
msgid "Failed to apply some of the graphic options changes:"
msgstr "½Õ ãÔÐÛÞáì ßàØÜÕÝØâì Ø×ÜÕÝÕÝØï ÝÕÚâÞàëå ÓàÐäØçÕáÚØå ÝÐáâàÞÕÚ:"
-#: gui/options.cpp:384
+#: gui/options.cpp:405
msgid "the video mode could not be changed."
msgstr "ÒØÔÕÞàÕÖØÜ ÝÕ ÜÞÖÕâ Ñëâì Ø×ÜÕÝñÝ."
-#: gui/options.cpp:390
+#: gui/options.cpp:411
msgid "the fullscreen setting could not be changed"
msgstr "ßÞÛÝÞíÚàÐÝÝëÙ àÕÖØÜ ÝÕ ÜÞÖÕâ Ñëâì Ø×ÜÕÝñÝ"
-#: gui/options.cpp:396
+#: gui/options.cpp:417
msgid "the aspect ratio setting could not be changed"
msgstr "àÕÖØÜ ÚÞààÕÚâØàÞÒÚØ áÞÞâÝÞèÕÝØï áâÞàÞÝ ÝÕ ÜÞÖÕâ Ñëâì Ø×ÜÕÝñÝ"
-#: gui/options.cpp:705
+#: gui/options.cpp:742
msgid "Graphics mode:"
msgstr "³àÐä. àÕÖØÜ:"
-#: gui/options.cpp:716
+#: gui/options.cpp:756
msgid "Render mode:"
msgstr "ÀÕÖØÜ àÐáâàÐ:"
-#: gui/options.cpp:716 gui/options.cpp:717
+#: gui/options.cpp:756 gui/options.cpp:757
msgid "Special dithering modes supported by some games"
msgstr "ÁßÕæØÐÛìÝëÕ àÕÖØÜë àÕÝÔÕàØÝÓÐ, ßÞÔÔÕàÖØÒÐÕÜëÕ ÝÕÚÞâÞàëÜØ ØÓàÐÜØ"
-#: gui/options.cpp:726
+#: gui/options.cpp:768
#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2248
-#: backends/graphics/openglsdl/openglsdl-graphics.cpp:476
+#: backends/graphics/openglsdl/openglsdl-graphics.cpp:472
msgid "Fullscreen mode"
msgstr "¿ÞÛÝÞíÚàÐÝÝëÙ àÕÖØÜ"
-#: gui/options.cpp:729
+#: gui/options.cpp:771
msgid "Aspect ratio correction"
msgstr "ºÞààÕÚæØï áÞÞâÝÞèÕÝØï áâÞàÞÝ"
-#: gui/options.cpp:729
+#: gui/options.cpp:771
msgid "Correct aspect ratio for 320x200 games"
msgstr "ºÞààÕÚâØàÞÒÐâì áÞÞâÝÞèÕÝØÕ áâÞàÞÝ ÔÛï ØÓà á àÐ×àÕèÕÝØÕÜ 320x200"
-#: gui/options.cpp:730
+#: gui/options.cpp:772
msgid "EGA undithering"
msgstr "EGA ÑÕ× àÐáâàÐ"
-#: gui/options.cpp:730
+#: gui/options.cpp:772
msgid "Enable undithering in EGA games that support it"
msgstr ""
"²ÚÛîçÐÕâ àÕÖØÜ ÑÕ× àÐáâàØàÞÒÐÝØï Ò EGA ØÓàÐå, ÚÞâÞàëÕ ßÞÔÔÕàÖØÒÐîâ âÐÚÞÙ "
"àÕÖØÜ"
-#: gui/options.cpp:738
+#: gui/options.cpp:780
msgid "Preferred Device:"
msgstr "¿àÕÔßÞçØâÐÕÜÞÕ:"
-#: gui/options.cpp:738
+#: gui/options.cpp:780
msgid "Music Device:"
msgstr "·ÒãÚÞÒÞÕ ãáâ-ÒÞ:"
-#: gui/options.cpp:738 gui/options.cpp:740
+#: gui/options.cpp:780 gui/options.cpp:782
msgid "Specifies preferred sound device or sound card emulator"
msgstr ""
"ÃÚÐ×ëÒÐÕâ ßàÕÔßÞçØâÐÕÜÞÕ ×ÒãÚÞÒÞÕ ãáâàÞÙáâÒÞ ØÛØ íÜãÛïâÞà ×ÒãÚÞÒÞÙ ÚÐàâë"
-#: gui/options.cpp:738 gui/options.cpp:740 gui/options.cpp:741
+#: gui/options.cpp:780 gui/options.cpp:782 gui/options.cpp:783
msgid "Specifies output sound device or sound card emulator"
msgstr "ÃÚÐ×ëÒÐÕâ ÒëåÞÔÝÞÕ ×ÒãÚÞÒÞÕ ãáâàÞÙáâÒÞ ØÛØ íÜãÛïâÞà ×ÒãÚÞÒÞÙ ÚÐàâë"
-#: gui/options.cpp:740
+#: gui/options.cpp:782
msgctxt "lowres"
msgid "Preferred Dev.:"
msgstr "¿àÕÔßÞçØâÐÕÜÞÕ:"
-#: gui/options.cpp:740
+#: gui/options.cpp:782
msgctxt "lowres"
msgid "Music Device:"
msgstr "·ÒãÚÞÒÞÕ ãáâ-ÒÞ:"
-#: gui/options.cpp:766
+#: gui/options.cpp:809
msgid "AdLib emulator:"
msgstr "ÍÜãÛïâÞà AdLib:"
-#: gui/options.cpp:766 gui/options.cpp:767
+#: gui/options.cpp:809 gui/options.cpp:810
msgid "AdLib is used for music in many games"
msgstr "·ÒãÚÞÒÐï ÚÐàâÐ AdLib ØáßÞÛì×ãÕâáï ÜÝÞÓØÜØ ØÓàÐÜØ"
-#: gui/options.cpp:777
+#: gui/options.cpp:820
msgid "Output rate:"
msgstr "ÇÐáâÞâÐ ×ÒãÚÐ:"
-#: gui/options.cpp:777 gui/options.cpp:778
+#: gui/options.cpp:820 gui/options.cpp:821
msgid ""
"Higher value specifies better sound quality but may be not supported by your "
"soundcard"
@@ -668,64 +671,64 @@ msgstr ""
"±¾ÛìèØÕ ×ÝÐçÕÝØï ×ÐÔÐîâ ÛãçèÕÕ ÚÐçÕáâÒÞ ×ÒãÚÐ, ÞÔÝÐÚÞ ÞÝØ ÜÞÓãâ ÝÕ "
"ßÞÔÔÕàÖØÒÐâìáï ÒÐèÕÙ ×ÒãÚÞÒÞÙ ÚÐàâÞÙ"
-#: gui/options.cpp:788
+#: gui/options.cpp:831
msgid "GM Device:"
msgstr "ÃáâàÞÙáâÒÞ GM:"
-#: gui/options.cpp:788
+#: gui/options.cpp:831
msgid "Specifies default sound device for General MIDI output"
msgstr "ÃÚÐ×ëÒÐÕâ ÒëåÞÔÝÞÕ ×ÒãÚÞÒÞÕ ãáâàÞÙáâÒÞ ÔÛï MIDI"
-#: gui/options.cpp:799
+#: gui/options.cpp:842
msgid "Don't use General MIDI music"
msgstr "½Õ ØáßÞÛì×ÞÒÐâì Üã×ëÚã ÔÛï General MIDI"
-#: gui/options.cpp:810 gui/options.cpp:871
+#: gui/options.cpp:853 gui/options.cpp:915
msgid "Use first available device"
msgstr "¸áßÞÛì×ÞÒÐâì ßÕàÒÞÕ ÔÞáâãßÝÞÕ ãáâàÞÙáâÒÞ"
-#: gui/options.cpp:822
+#: gui/options.cpp:865
msgid "SoundFont:"
msgstr "SoundFont:"
-#: gui/options.cpp:822 gui/options.cpp:824 gui/options.cpp:825
+#: gui/options.cpp:865 gui/options.cpp:867 gui/options.cpp:868
msgid "SoundFont is supported by some audio cards, Fluidsynth and Timidity"
msgstr ""
"SoundFontë ßÞÔÔÕàÔÖØÒÐîâáï ÝÕÚÞâÞàëÜØ ×ÒãÚÞÒëÜØ ÚÐàâÐÜØ, Fluidsynth Ø "
"Timidity"
-#: gui/options.cpp:824
+#: gui/options.cpp:867
msgctxt "lowres"
msgid "SoundFont:"
msgstr "SoundFont:"
-#: gui/options.cpp:829
+#: gui/options.cpp:873
msgid "Mixed AdLib/MIDI mode"
msgstr "ÁÜÕèÐÝÝëÙ àÕÖØÜ AdLib/MIDI"
-#: gui/options.cpp:829
+#: gui/options.cpp:873
msgid "Use both MIDI and AdLib sound generation"
msgstr "¸áßÞÛì×ÞÒÐâì Ø MIDI Ø AdLib ÔÛï ÓÕÝÕàÐæØØ ×ÒãÚÐ"
-#: gui/options.cpp:832
+#: gui/options.cpp:876
msgid "MIDI gain:"
msgstr "ÃáØÛÕÝØÕ MIDI:"
-#: gui/options.cpp:842
+#: gui/options.cpp:886
msgid "MT-32 Device:"
msgstr "Ãáâà. MT-32:"
-#: gui/options.cpp:842
+#: gui/options.cpp:886
msgid "Specifies default sound device for Roland MT-32/LAPC1/CM32l/CM64 output"
msgstr ""
"ÃÚÐ×ëÒÐÕâ ×ÒãÚÞÒÞÕ ãáâàÞÙáâÒÞ ßÞ ãÜÞÛçÐÝØï ÔÛï ÒëÒÞÔÐ ÝÐ Roland MT-32/LAPC1/"
"CM32l/CM64"
-#: gui/options.cpp:847
+#: gui/options.cpp:891
msgid "True Roland MT-32 (disable GM emulation)"
msgstr "½ÐáâÞïéØÙ Roland MT-32 (×ÐßàÕâØâì íÜãÛïæØî GM)"
-#: gui/options.cpp:847 gui/options.cpp:849
+#: gui/options.cpp:891 gui/options.cpp:893
msgid ""
"Check if you want to use your real hardware Roland-compatible sound device "
"connected to your computer"
@@ -733,193 +736,193 @@ msgstr ""
"¾âÜÕâìâÕ, ÕáÛØ ã ÒÐá ßÞÔÚÛîçÕÝÞ Roland-áÞÒÜÕáâØÜÞÕ ×ÒãÚÞÒÞÕ ãáâàÞÙáâÒÞ Ø Òë "
"åÞâØâÕ ÕÓÞ ØáßÞÛì×ÞÒÐâì"
-#: gui/options.cpp:849
+#: gui/options.cpp:893
msgctxt "lowres"
msgid "True Roland MT-32 (no GM emulation)"
msgstr "½ÐáâÞïéØÙ Roland MT-32 (×ÐßàÕâØâì GM)"
-#: gui/options.cpp:852
+#: gui/options.cpp:896
msgid "Enable Roland GS Mode"
msgstr "²ÚÛîçØâì àÕÖØÜ Roland GS"
-#: gui/options.cpp:852
+#: gui/options.cpp:896
msgid "Turns off General MIDI mapping for games with Roland MT-32 soundtrack"
msgstr ""
"²ëÚÛîçÐÕâ ÜÐßßØÝÓ General MIDI ÔÛï ØÓà á ×ÒãÚÞÒÞÙ ÔÞàÞÖÚÞÙ ÔÛï Roland MT-32"
-#: gui/options.cpp:861
+#: gui/options.cpp:905
msgid "Don't use Roland MT-32 music"
msgstr "½Õ ØáßÞÛì×ÞÒÐâì Üã×ëÚã ÔÛï MT-32"
-#: gui/options.cpp:888
+#: gui/options.cpp:932
msgid "Text and Speech:"
msgstr "ÂÕÚáâ Ø Þ×ÒãçÚÐ:"
-#: gui/options.cpp:892 gui/options.cpp:902
+#: gui/options.cpp:936 gui/options.cpp:946
msgid "Speech"
msgstr "¾×ÒãçÚÐ"
-#: gui/options.cpp:893 gui/options.cpp:903
+#: gui/options.cpp:937 gui/options.cpp:947
msgid "Subtitles"
msgstr "ÁãÑâØâàë"
-#: gui/options.cpp:894
+#: gui/options.cpp:938
msgid "Both"
msgstr "¾ÑÐ"
-#: gui/options.cpp:896
+#: gui/options.cpp:940
msgid "Subtitle speed:"
msgstr "ÁÚÞàÞáâì âØâàÞÒ:"
-#: gui/options.cpp:898
+#: gui/options.cpp:942
msgctxt "lowres"
msgid "Text and Speech:"
msgstr "ÂÕÚáâ Ø Þ×ÒãçÚÐ:"
-#: gui/options.cpp:902
+#: gui/options.cpp:946
msgid "Spch"
msgstr "¾×Ò"
-#: gui/options.cpp:903
+#: gui/options.cpp:947
msgid "Subs"
msgstr "狄"
-#: gui/options.cpp:904
+#: gui/options.cpp:948
msgctxt "lowres"
msgid "Both"
msgstr "¾ÑÐ"
-#: gui/options.cpp:904
+#: gui/options.cpp:948
msgid "Show subtitles and play speech"
msgstr "¿ÞÚÐ×ëÒÐâì áãÑâØâàë Ø ÒÞáßàÞØ×ÒÞÔØâì àÕçì"
-#: gui/options.cpp:906
+#: gui/options.cpp:950
msgctxt "lowres"
msgid "Subtitle speed:"
msgstr "ÁÚÞàÞáâì âØâàÞÒ:"
-#: gui/options.cpp:922
+#: gui/options.cpp:966
msgid "Music volume:"
msgstr "³àÞÜÚ. Üã×ëÚØ:"
-#: gui/options.cpp:924
+#: gui/options.cpp:968
msgctxt "lowres"
msgid "Music volume:"
msgstr "³àÞÜÚ. Üã×ëÚØ:"
-#: gui/options.cpp:931
+#: gui/options.cpp:975
msgid "Mute All"
msgstr "²ëÚÛ. Òáñ"
-#: gui/options.cpp:934
+#: gui/options.cpp:978
msgid "SFX volume:"
msgstr "³àÞÜÚÞáâì SFX:"
-#: gui/options.cpp:934 gui/options.cpp:936 gui/options.cpp:937
+#: gui/options.cpp:978 gui/options.cpp:980 gui/options.cpp:981
msgid "Special sound effects volume"
msgstr "³àÞÜÚÞáâì áßÕæØÐÛìÝëå ×ÒãÚÞÒëå íääÕÚâÞÒ"
-#: gui/options.cpp:936
+#: gui/options.cpp:980
msgctxt "lowres"
msgid "SFX volume:"
msgstr "³àÞÜÚ. SFX:"
-#: gui/options.cpp:944
+#: gui/options.cpp:988
msgid "Speech volume:"
msgstr "³àÞÜÚ. Þ×ÒãçÚØ:"
-#: gui/options.cpp:946
+#: gui/options.cpp:990
msgctxt "lowres"
msgid "Speech volume:"
msgstr "³àÞÜÚ. Þ×ÒãçÚØ:"
-#: gui/options.cpp:1085
+#: gui/options.cpp:1156
msgid "Theme Path:"
msgstr "¿ãâì Ú âÕÜÐÜ:"
-#: gui/options.cpp:1087
+#: gui/options.cpp:1158
msgctxt "lowres"
msgid "Theme Path:"
msgstr "³ÔÕ âÕÜë:"
-#: gui/options.cpp:1091 gui/options.cpp:1093 gui/options.cpp:1094
+#: gui/options.cpp:1164 gui/options.cpp:1166 gui/options.cpp:1167
msgid "Specifies path to additional data used by all games or ScummVM"
msgstr ""
"ÃÚÐ×ëÒÐÕâ ßãâì Ú ÔÞßÞÛÝØâÕÛìÝëÜ äÐÙÛÐÜ ÔÐÝÝëå, ØáßÞÛì×ãÕÜëå ÒáÕÜØ ØÓàÐÜØ, "
"ÛØÑÞ ScummVM"
-#: gui/options.cpp:1098
+#: gui/options.cpp:1173
msgid "Plugins Path:"
msgstr "¿ãâì Ú ßÛÐÓØÝÐÜ:"
-#: gui/options.cpp:1100
+#: gui/options.cpp:1175
msgctxt "lowres"
msgid "Plugins Path:"
msgstr "¿ãâì Ú ßÛÐÓØÝÐÜ:"
-#: gui/options.cpp:1109
+#: gui/options.cpp:1184
msgid "Misc"
msgstr "ÀÐ×ÝÞÕ"
-#: gui/options.cpp:1111
+#: gui/options.cpp:1186
msgctxt "lowres"
msgid "Misc"
msgstr "ÀÐ×ÝÞÕ"
-#: gui/options.cpp:1113
+#: gui/options.cpp:1188
msgid "Theme:"
msgstr "ÂÕÜÐ:"
-#: gui/options.cpp:1117
+#: gui/options.cpp:1192
msgid "GUI Renderer:"
msgstr "ÀØáÞÒÐÛÚÐ GUI:"
-#: gui/options.cpp:1129
+#: gui/options.cpp:1204
msgid "Autosave:"
msgstr "°ÒâÞáÞåàÐÝÕÝØÕ:"
-#: gui/options.cpp:1131
+#: gui/options.cpp:1206
msgctxt "lowres"
msgid "Autosave:"
msgstr "°ÒâÞáÞåà.:"
-#: gui/options.cpp:1139
+#: gui/options.cpp:1214
msgid "Keys"
msgstr "ºÛÐÒØèØ"
-#: gui/options.cpp:1146
+#: gui/options.cpp:1221
msgid "GUI Language:"
msgstr "Ï×ëÚ GUI:"
-#: gui/options.cpp:1146
+#: gui/options.cpp:1221
msgid "Language of ScummVM GUI"
msgstr "Ï×ëÚ ÓàÐäØçÕáÚÞÓÞ ØÝâÕàäÕÙáÐ ScummVM"
-#: gui/options.cpp:1295
+#: gui/options.cpp:1372
msgid "You have to restart ScummVM before your changes will take effect."
msgstr "²ë ÔÞÛÖÝë ßÕàÕ×ÐßãáâØâì ScummVM çâÞÑë ßàØÜÕÝØâì Ø×ÜÕÝÕÝØï."
-#: gui/options.cpp:1308
+#: gui/options.cpp:1385
msgid "Select directory for savegames"
msgstr "²ëÑÕàØâÕ ÔØàÕÚâÞàØî ÔÛï áÞåàÐÝÕÝØÙ"
-#: gui/options.cpp:1315
+#: gui/options.cpp:1392
msgid "The chosen directory cannot be written to. Please select another one."
msgstr "½Õ ÜÞÓã ßØáÐâì Ò ÒëÑàÐÝÝãî ÔØàÕÚâÞàØî. ¿ÞÖÐÛãÙáâÐ, ãÚÐÖØâÕ ÔàãÓãî."
-#: gui/options.cpp:1324
+#: gui/options.cpp:1401
msgid "Select directory for GUI themes"
msgstr "²ëÑÕàØâÕ ÔØàÕÚâÞàØî ÔÛï âÕÜ GUI"
-#: gui/options.cpp:1334
+#: gui/options.cpp:1411
msgid "Select directory for extra files"
msgstr "²ëÑÕàØâÕ ÔØàÕÚâÞàØî á ÔÞßÞÛÝØâÕÛìÝëÜØ äÐÙÛÐÜØ"
-#: gui/options.cpp:1345
+#: gui/options.cpp:1422
msgid "Select directory for plugins"
msgstr "²ëÑÕàØâÕ ÔØàÕÚâÞàØî á ßÛÐÓØÝÐÜØ"
-#: gui/options.cpp:1389
+#: gui/options.cpp:1475
msgid ""
"The theme you selected does not support your current language. If you want "
"to use this theme you need to switch to another language first."
@@ -967,60 +970,64 @@ msgstr "ÁÞåàÐÝÕÝØÕ ÑÕ× ØÜÕÝØ"
msgid "Select a Theme"
msgstr "²ëÑÕàØâÕ âÕÜã"
-#: gui/ThemeEngine.cpp:328
+#: gui/ThemeEngine.cpp:333
msgid "Disabled GFX"
msgstr "±Õ× ÓàÐäØÚØ"
-#: gui/ThemeEngine.cpp:328
+#: gui/ThemeEngine.cpp:333
msgctxt "lowres"
msgid "Disabled GFX"
msgstr "±Õ× ÓàÐäØÚØ"
-#: gui/ThemeEngine.cpp:329
+#: gui/ThemeEngine.cpp:334
msgid "Standard Renderer (16bpp)"
msgstr "ÁâÐÝÔÐàâÝëÙ àÐáâÕàØ×ÐâÞà (16bpp)"
-#: gui/ThemeEngine.cpp:329
+#: gui/ThemeEngine.cpp:334
msgid "Standard (16bpp)"
msgstr "ÁâÐÝÔÐàâÝëÙ àÐáâÕàØ×ÐâÞà (16bpp)"
-#: gui/ThemeEngine.cpp:331
+#: gui/ThemeEngine.cpp:336
msgid "Antialiased Renderer (16bpp)"
msgstr "ÀÐáâÕàØ×ÐâÞà áÞ áÓÛÐÖØÒÐÝØÕÜ (16bpp)"
-#: gui/ThemeEngine.cpp:331
+#: gui/ThemeEngine.cpp:336
msgid "Antialiased (16bpp)"
msgstr "ÀÐáâÕàØ×ÐâÞà áÞ áÓÛÐÖØÒÐÝØÕÜ (16bpp)"
+#: gui/widget.cpp:312 gui/widget.cpp:314 gui/widget.cpp:320 gui/widget.cpp:322
+msgid "Clear value"
+msgstr "¾çØáâØâì ×ÝÐçÕÝØÕ"
+
#: base/main.cpp:203
#, c-format
msgid "Engine does not support debug level '%s'"
msgstr "´ÒØÖÞÚ ÝÕ ßÞÔÔÕàÖØÒÐÕâ ãàÞÒÕÝì ÞâÛÐÔÚØ '%s'"
-#: base/main.cpp:271
+#: base/main.cpp:275
msgid "Menu"
msgstr "¼ÕÝî"
-#: base/main.cpp:274 backends/platform/symbian/src/SymbianActions.cpp:45
+#: base/main.cpp:278 backends/platform/symbian/src/SymbianActions.cpp:45
#: backends/platform/wince/CEActionsPocket.cpp:45
#: backends/platform/wince/CEActionsSmartphone.cpp:46
msgid "Skip"
msgstr "¿àÞßãáâØâì"
-#: base/main.cpp:277 backends/platform/symbian/src/SymbianActions.cpp:50
+#: base/main.cpp:281 backends/platform/symbian/src/SymbianActions.cpp:50
#: backends/platform/wince/CEActionsPocket.cpp:42
msgid "Pause"
msgstr "¿Ðã×Ð"
-#: base/main.cpp:280
+#: base/main.cpp:284
msgid "Skip line"
msgstr "¿àÞßãáâØâì áâàÞÚã"
-#: base/main.cpp:439
+#: base/main.cpp:455
msgid "Error running game:"
msgstr "¾èØÑÚÐ ×ÐßãáÚÐ ØÓàë:"
-#: base/main.cpp:463
+#: base/main.cpp:479
msgid "Could not find any engine capable of running the selected game"
msgstr "½Õ ÜÞÓã ÝÐÙâØ ÔÒØÖÞÚ ÔÛï ×ÐßãáÚÐ ÒëÑàÐÝÝÞÙ ØÓàë"
@@ -1088,25 +1095,6 @@ msgstr "¿àÕàÒÐÝÞ ßÞÛì×ÞÒÐâÕÛÕÜ"
msgid "Unknown error"
msgstr "½ÕØ×ÒÕáâÝÐï ÞèØÑÚÐ"
-#. I18N: Hercules is graphics card name
-#: common/util.cpp:275
-msgid "Hercules Green"
-msgstr "Hercules ·ÕÛñÝëÙ"
-
-#: common/util.cpp:276
-msgid "Hercules Amber"
-msgstr "Hercules ÏÝâÐàÝëÙ"
-
-#: common/util.cpp:283
-msgctxt "lowres"
-msgid "Hercules Green"
-msgstr "Hercules ·ÕÛñÝëÙ"
-
-#: common/util.cpp:284
-msgctxt "lowres"
-msgid "Hercules Amber"
-msgstr "Hercules ÏÝâÐàÝëÙ"
-
#: engines/advancedDetector.cpp:296
#, c-format
msgid "The game in '%s' seems to be unknown."
@@ -1155,12 +1143,12 @@ msgid "~R~eturn to Launcher"
msgstr "~²~ ÓÛÐÒÝÞÕ ÜÕÝî"
#: engines/dialogs.cpp:116 engines/cruise/menu.cpp:214
-#: engines/sci/engine/kfile.cpp:578
+#: engines/sci/engine/kfile.cpp:566
msgid "Save game:"
msgstr "ÁÞåàÐÝØâì ØÓàã:"
#: engines/dialogs.cpp:116 engines/scumm/dialogs.cpp:187
-#: engines/cruise/menu.cpp:214 engines/sci/engine/kfile.cpp:578
+#: engines/cruise/menu.cpp:214 engines/sci/engine/kfile.cpp:566
#: backends/platform/symbian/src/SymbianActions.cpp:44
#: backends/platform/wince/CEActionsPocket.cpp:43
#: backends/platform/wince/CEActionsPocket.cpp:267
@@ -1179,37 +1167,47 @@ msgstr ""
"¿ÞÖÐÛãÙáâÐ, ÞÑàÐâØâÕáì Ò äÐÙÛ README ×Ð ÑÐ×ÞÒÞÙ ØÝäÞàÜÐæØÕÙ, Ð âÐÚÖÕ "
"ØÝáâàãÚæØïÜØ Þ âÞÜ, ÚÐÚ ßÞÛãçØâì ÔÐÛìÝÕÙèãî ßÞÜÞéì."
-#: engines/dialogs.cpp:316 engines/mohawk/dialogs.cpp:109
+#: engines/dialogs.cpp:243
+#, fuzzy, c-format
+msgid ""
+"Gamestate save failed (%s)! Please consult the README for basic information, "
+"and for instructions on how to obtain further assistance."
+msgstr ""
+"¿àÞáØÜ ßàÞéÕÝØï, ÝÞ íâÞâ ÔÒØÖÞÕ ßÞÚÐ ÝÕ ßàÕÔÞáâÐÒÛïÕâ ßÞÜÞéØ ÒÝãâàØ ØÓàë. "
+"¿ÞÖÐÛãÙáâÐ, ÞÑàÐâØâÕáì Ò äÐÙÛ README ×Ð ÑÐ×ÞÒÞÙ ØÝäÞàÜÐæØÕÙ, Ð âÐÚÖÕ "
+"ØÝáâàãÚæØïÜØ Þ âÞÜ, ÚÐÚ ßÞÛãçØâì ÔÐÛìÝÕÙèãî ßÞÜÞéì."
+
+#: engines/dialogs.cpp:321 engines/mohawk/dialogs.cpp:109
#: engines/mohawk/dialogs.cpp:174
msgid "~O~K"
msgstr "~O~K"
-#: engines/dialogs.cpp:317 engines/mohawk/dialogs.cpp:110
+#: engines/dialogs.cpp:322 engines/mohawk/dialogs.cpp:110
#: engines/mohawk/dialogs.cpp:175
msgid "~C~ancel"
msgstr "¾~â~ÜÕÝÐ"
-#: engines/dialogs.cpp:320
+#: engines/dialogs.cpp:325
msgid "~K~eys"
msgstr "~º~ÛÐÒØèØ"
-#: engines/engine.cpp:233
+#: engines/engine.cpp:235
msgid "Could not initialize color format."
msgstr "½Õ ÜÞÓã ØÝØæØÐÛØ×ØàÞÒÐâì äÞàÜÐâ æÒÕâÐ."
-#: engines/engine.cpp:241
+#: engines/engine.cpp:243
msgid "Could not switch to video mode: '"
msgstr "½Õ ãÔÐÛÞáì ßÕàÕÚÛîçØâì ÒØÔÕÞàÕÖØÜ: '"
-#: engines/engine.cpp:250
+#: engines/engine.cpp:252
msgid "Could not apply aspect ratio setting."
msgstr "½Õ ãÔÐÛÞáì ØáßÞÛì×ÞÒÐâì ÚÞààÕÚæØî áÞÞâÝÞèÕÝØï áâÞàÞÝ."
-#: engines/engine.cpp:255
+#: engines/engine.cpp:257
msgid "Could not apply fullscreen setting."
msgstr "½Õ ÜÞÓã ßàØÜÕÝØâì ßÞÛÝÞíÚàÐÝÝëÙ àÕÖØÜ."
-#: engines/engine.cpp:355
+#: engines/engine.cpp:357
msgid ""
"You appear to be playing this game directly\n"
"from the CD. This is known to cause problems,\n"
@@ -1223,7 +1221,7 @@ msgstr ""
"ÝÐ ÖñáâÚØÙ ÔØáÚ. ¿ÞÔàÞÑÝÞáâØ ÜÞÖÝÞ ÝÐÙâØ Ò\n"
"äÐÙÛÕ README."
-#: engines/engine.cpp:366
+#: engines/engine.cpp:368
msgid ""
"This game has audio tracks in its disk. These\n"
"tracks need to be ripped from the disk using\n"
@@ -1238,7 +1236,17 @@ msgstr ""
"ßÞïÒØâáï Üã×ëÚÐ. ¿ÞÔàÞÑÝÞáâØ ÜÞÖÝÞ ÝÐÙâØ Ò\n"
"äÐÙÛÕ README."
-#: engines/engine.cpp:433
+#: engines/engine.cpp:426
+#, fuzzy, c-format
+msgid ""
+"Gamestate load failed (%s)! Please consult the README for basic information, "
+"and for instructions on how to obtain further assistance."
+msgstr ""
+"¿àÞáØÜ ßàÞéÕÝØï, ÝÞ íâÞâ ÔÒØÖÞÕ ßÞÚÐ ÝÕ ßàÕÔÞáâÐÒÛïÕâ ßÞÜÞéØ ÒÝãâàØ ØÓàë. "
+"¿ÞÖÐÛãÙáâÐ, ÞÑàÐâØâÕáì Ò äÐÙÛ README ×Ð ÑÐ×ÞÒÞÙ ØÝäÞàÜÐæØÕÙ, Ð âÐÚÖÕ "
+"ØÝáâàãÚæØïÜØ Þ âÞÜ, ÚÐÚ ßÞÛãçØâì ÔÐÛìÝÕÙèãî ßÞÜÞéì."
+
+#: engines/engine.cpp:439
msgid ""
"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 "
@@ -1248,7 +1256,7 @@ msgstr ""
"ScummVM ßÞÛÝÞáâìî. ¾ÝÐ áÚÞàÕÕ ÒáÕÓÞ ÝÕ ÑãÔÕâ àÐÑÞâÐâì áâÐÑØÛìÝÞ, Ø "
"áÞåàÐÝÕÝØï ØÓà ÜÞÓãâ ÝÕ àÐÑÞâÐâì Ò ÑãÔãéØå ÒÕàáØïå ScummVM."
-#: engines/engine.cpp:436
+#: engines/engine.cpp:442
msgid "Start anyway"
msgstr "²áñ àÐÒÝÞ ×ÐßãáâØâì"
@@ -1292,7 +1300,7 @@ msgstr "¸ÓàÐâì"
#: backends/platform/symbian/src/SymbianActions.cpp:52
#: backends/platform/wince/CEActionsPocket.cpp:44
#: backends/platform/wince/CEActionsSmartphone.cpp:52
-#: backends/events/default/default-events.cpp:244
+#: backends/events/default/default-events.cpp:213
msgid "Quit"
msgstr "²ëåÞÔ"
@@ -1366,6 +1374,26 @@ msgctxt "lowres"
msgid "Speech & Subs"
msgstr "¾×ÒãçÚÐ Ø âÕÚáâ"
+#: engines/scumm/dialogs.cpp:653
+msgid "Select a Proficiency Level."
+msgstr "²ëÑÕàØâÕ ãàÞÒÕÝì áÛÞÖÝÞáâØ."
+
+#: engines/scumm/dialogs.cpp:655
+msgid "Refer to your Loom(TM) manual for help."
+msgstr "·Ð ßÞÜÞéìî ÞÑàÐâØâÕáì Ú ØÝáâãÚæØØ Loom(TM)"
+
+#: engines/scumm/dialogs.cpp:658
+msgid "Standard"
+msgstr "ÁâÐÝÔÐàâÝëÙ"
+
+#: engines/scumm/dialogs.cpp:659
+msgid "Practice"
+msgstr "¿àÐÚâØÚÐÝâ"
+
+#: engines/scumm/dialogs.cpp:660
+msgid "Expert"
+msgstr "ÍÚáßÕàâ"
+
#: engines/scumm/help.cpp:73
msgid "Common keyboard commands:"
msgstr "¾ÑéØÕ ÚÛÐÒØÐâãàÝëÕ ÚÞÜÐÝÔë:"
@@ -1879,7 +1907,7 @@ msgstr "»ÕâÕâì ÒßàÐÒÞ"
msgid "Fly to lower right"
msgstr "»ÕâÕâì ÒßàÐÒÞ-ÒÝØ×"
-#: engines/scumm/scumm.cpp:1774
+#: engines/scumm/scumm.cpp:1773
#, c-format
msgid ""
"Native MIDI support requires the Roland Upgrade from LucasArts,\n"
@@ -1888,7 +1916,7 @@ msgstr ""
"ÀÕÖØÜ \"àÞÔÝÞÓÞ\" MIDI âàÕÑãÕâ ÞÑÝÞÒÛÕÝØÕ Roland Upgrade Þâ\n"
"LucasArts, ÝÞ ÝÕ åÒÐâÐÕâ %s. ¿ÕàÕÚÛîçÐîáì ÝÐ AdLib."
-#: engines/scumm/scumm.cpp:2264 engines/agos/saveload.cpp:189
+#: engines/scumm/scumm.cpp:2271 engines/agos/saveload.cpp:189
#, c-format
msgid ""
"Failed to save game state to file:\n"
@@ -1899,7 +1927,7 @@ msgstr ""
"\n"
"%s"
-#: engines/scumm/scumm.cpp:2271 engines/agos/saveload.cpp:154
+#: engines/scumm/scumm.cpp:2278 engines/agos/saveload.cpp:154
#, c-format
msgid ""
"Failed to load game state from file:\n"
@@ -1910,7 +1938,7 @@ msgstr ""
"\n"
"%s"
-#: engines/scumm/scumm.cpp:2283 engines/agos/saveload.cpp:197
+#: engines/scumm/scumm.cpp:2290 engines/agos/saveload.cpp:197
#, c-format
msgid ""
"Successfully saved game state in file:\n"
@@ -1921,7 +1949,7 @@ msgstr ""
"\n"
"%s"
-#: engines/scumm/scumm.cpp:2498
+#: engines/scumm/scumm.cpp:2505
msgid ""
"Usually, Maniac Mansion would start now. But ScummVM doesn't do that yet. To "
"play it, go to 'Add Game' in the ScummVM start menu and select the 'Maniac' "
@@ -1957,11 +1985,11 @@ msgstr "³ÛÐÒÝÞÕ ÜÕÝî"
msgid "~W~ater Effect Enabled"
msgstr "ÍääÕÚâë ÒÞÔë ÒÚÛîçÕÝë"
-#: engines/sci/engine/kfile.cpp:685
+#: engines/sci/engine/kfile.cpp:673
msgid "Restore game:"
msgstr "²ÞááâÐÝÞÒØâì ØÓàã:"
-#: engines/sci/engine/kfile.cpp:685
+#: engines/sci/engine/kfile.cpp:673
msgid "Restore"
msgstr "²ÞááâÒÝÞÒØâì"
@@ -1971,11 +1999,11 @@ msgid "Cutscene file '%s' not found!"
msgstr "ÄÐÙÛ ×ÐáâÐÒÚØ '%s' ÝÕ ÝÐÙÔÕÝ!"
#: engines/gob/inter_playtoons.cpp:256 engines/gob/inter_v2.cpp:1283
-#: engines/tinsel/saveload.cpp:482
+#: engines/tinsel/saveload.cpp:502
msgid "Failed to load game state from file."
msgstr "½Õ ãÔÐÛÞáì ×ÐÓàã×Øâì áÞåàÐÝñÝÝãî ØÓàã Ø× äÐÙÛÐ."
-#: engines/gob/inter_v2.cpp:1353 engines/tinsel/saveload.cpp:560
+#: engines/gob/inter_v2.cpp:1353 engines/tinsel/saveload.cpp:515
msgid "Failed to save game state to file."
msgstr "½Õ ãÔÐÛÞáì áÞåàÐÝØâì ØÓàã Ò äÐÙÛ."
@@ -1987,6 +2015,54 @@ msgstr "½Õ ãÔÐÛÞáì ãÔÐÛØâì äÐÙÛ."
msgid "Failed to save game"
msgstr "½Õ ãÔÐÛÞáì áÞåàÐÝØâì ØÓàã"
+#: engines/kyra/lol.cpp:478
+msgid "Attack 1"
+msgstr "°âÐÚÐ 1"
+
+#: engines/kyra/lol.cpp:479
+msgid "Attack 2"
+msgstr "°âÐÚÐ 2"
+
+#: engines/kyra/lol.cpp:480
+msgid "Attack 3"
+msgstr "°âÐÚÐ 3"
+
+#: engines/kyra/lol.cpp:481
+msgid "Move Forward"
+msgstr "¸ÔâØ ÒßÕàñÔ"
+
+#: engines/kyra/lol.cpp:482
+msgid "Move Back"
+msgstr "¸ÔâØ ÝÐ×ÐÔ"
+
+#: engines/kyra/lol.cpp:483
+msgid "Slide Left"
+msgstr "ÁÚÞÛì×Øâì ÒÛÕÒÞ"
+
+#: engines/kyra/lol.cpp:484
+msgid "Slide Right"
+msgstr "ÁÚÞÛì×Øâì ÒßàÐÒÞ"
+
+#: engines/kyra/lol.cpp:485
+msgid "Turn Left"
+msgstr "¿ÞÒÞàÞâ ÝÐÛÕÒÞ"
+
+#: engines/kyra/lol.cpp:486
+msgid "Turn Right"
+msgstr "¿ÞÒÞàÞâ ÝÐßàÐÒÞ"
+
+#: engines/kyra/lol.cpp:487
+msgid "Rest"
+msgstr "¾âÔÞåÝãâì"
+
+#: engines/kyra/lol.cpp:488
+msgid "Options"
+msgstr "¾ßæØØ"
+
+#: engines/kyra/lol.cpp:489
+msgid "Choose Spell"
+msgstr "²ëÑàÐâì ×ÐÚÛØÝÐÝØÕ"
+
#: engines/kyra/sound_midi.cpp:475
msgid ""
"You appear to be using a General MIDI device,\n"
@@ -2002,10 +2078,6 @@ msgstr ""
"ÜÞÖÕâ âÐÚ ßÞÛãçØâìáï, çâÞ ÝÕÚÞâÞàëÕ âàÕÚØ ÑãÔãâ\n"
"áëÓàÐÝë ÝÕÒÕàÝÞ."
-#: engines/m4/m4_menus.cpp:138
-msgid "Save game failed!"
-msgstr "½Õ ãÔÐÛÞáì áÞåàÐÝØâì ØÓàã!"
-
#: engines/sky/compact.cpp:130
msgid ""
"Unable to find \"sky.cpt\" file!\n"
@@ -2022,16 +2094,21 @@ msgstr ""
"ÄÐÙÛ sky.cpt ØÜÕÕâ ÝÕÒÕàÝëÙ àÐ×ÜÕà.\n"
"¿ÞÖÐÛãÙáâÐ, áÚÐçÐÙâÕ ÕÓÞ ×ÐÝÞÒÞ á www.scummvm.org"
-#: engines/sword1/animation.cpp:344 engines/sword2/animation.cpp:379
+#: engines/sword1/animation.cpp:539
+#, c-format
+msgid "PSX stream cutscene '%s' cannot be played in paletted mode"
+msgstr ""
+
+#: engines/sword1/animation.cpp:560 engines/sword2/animation.cpp:455
msgid "DXA cutscenes found but ScummVM has been built without zlib support"
msgstr ""
"½ÐÙÔÕÝë ×ÐáâÐÒÚØ Ò äÞàÜÐâÕ DXA, ÝÞ ScummVM ÑëÛ áÞÑàÐÝ ÑÕ× ßÞÔÔÕàÖÚØ zlib"
-#: engines/sword1/animation.cpp:354 engines/sword2/animation.cpp:389
+#: engines/sword1/animation.cpp:570 engines/sword2/animation.cpp:465
msgid "MPEG2 cutscenes are no longer supported"
msgstr "·ÐáâÐÒÚØ Ò äÞàÜÐâÕ MPEG2 ÑÞÛìèÕ ÝÕ ßÞÔÔÕàÖØÒÐîâáï"
-#: engines/sword1/animation.cpp:359 engines/sword2/animation.cpp:397
+#: engines/sword1/animation.cpp:576 engines/sword2/animation.cpp:473
#, c-format
msgid "Cutscene '%s' not found"
msgstr "·ÐáâÐÒÚÐ '%s' ÝÕ ÝÐÙÔÕÝÐ"
@@ -2074,6 +2151,13 @@ msgstr "ÁÔÕÛÐâì ÝÞÒÞÕ"
msgid "This is the end of the Broken Sword 1 Demo"
msgstr "ÍâÞ ×ÐÒÕàèÕÝØÕ ÔÕÜÞ ÁÛÞÜÐÝÝÞÓÞ ¼ÕçÐ 1"
+#: engines/sword2/animation.cpp:435
+#, fuzzy
+msgid ""
+"PSX cutscenes found but ScummVM has been built without RGB color support"
+msgstr ""
+"½ÐÙÔÕÝë ×ÐáâÐÒÚØ Ò äÞàÜÐâÕ DXA, ÝÞ ScummVM ÑëÛ áÞÑàÐÝ ÑÕ× ßÞÔÔÕàÖÚØ zlib"
+
#: engines/parallaction/saveload.cpp:133
#, c-format
msgid ""
@@ -2131,7 +2215,7 @@ msgstr "ÍÜãÛïâÞà MAME OPL"
msgid "DOSBox OPL emulator"
msgstr "ÍÜãÛïâÞà DOSBox OPL"
-#: audio/mididrv.cpp:205
+#: audio/mididrv.cpp:209
#, c-format
msgid ""
"The selected audio device '%s' was not found (e.g. might be turned off or "
@@ -2140,12 +2224,12 @@ msgstr ""
"²ëÑàÐÝÝÞÕ ×ÒãÚÞÒÞÕ ãáâàÞÙáâÒÞ '%s' ÝÕ ÑëÛÞ ÝÐÙÔÕÝÞ (ÒÞ×ÜÞÖÝÞ ÞÝÞ ÒëÚÛîçÕÝÞ "
"ØÛØ ÝÕ ßÞÔÚÛîçÕÝÞ)."
-#: audio/mididrv.cpp:205 audio/mididrv.cpp:217 audio/mididrv.cpp:253
-#: audio/mididrv.cpp:268
+#: audio/mididrv.cpp:209 audio/mididrv.cpp:221 audio/mididrv.cpp:257
+#: audio/mididrv.cpp:272
msgid "Attempting to fall back to the next available device..."
msgstr "¿ëâÐîáì ØáßÞÛì×ÞÒÐâì ÔàãÓÞÕ ÔÞáâãßÝÞÕ ãáâàÞÙáâÒÞ..."
-#: audio/mididrv.cpp:217
+#: audio/mididrv.cpp:221
#, c-format
msgid ""
"The selected audio device '%s' cannot be used. See log file for more "
@@ -2154,7 +2238,7 @@ msgstr ""
"²ëÑàÐÝÝÞÕ ×ÒãÚÞÒÞÕ ãáâàÞÙáâÒÞ '%s' ÝÕ ÜÞÖÕâ Ñëâì ØáßÞÛì×ÞÒÐÝÞ. ÁÜÞâàØâÕ äÐÙÛ "
"ßàÞâÞÚÞÛÐ ÔÛï ÑÞÛÕÕ ßÞÔàÞÑÝÞÙ ØÝäÞàÜÐæØØ."
-#: audio/mididrv.cpp:253
+#: audio/mididrv.cpp:257
#, c-format
msgid ""
"The preferred audio device '%s' was not found (e.g. might be turned off or "
@@ -2163,7 +2247,7 @@ msgstr ""
"¿àÕÔßÞçâØâÕÛìÝÞÕ ×ÒãÚÞÒÞÕ ãáâàÞÙáâÒÞ '%s' ÝÕ ÑëÛÞ ÝÐÙÔÕÝÞ (ÒÞ×ÜÞÖÝÞ ÞÝÞ "
"ÒëÚÛîçÕÝÞ ØÛØ ÝÕ ßÞÔÚÛîçÕÝÞ)."
-#: audio/mididrv.cpp:268
+#: audio/mididrv.cpp:272
#, c-format
msgid ""
"The preferred audio device '%s' cannot be used. See log file for more "
@@ -2180,7 +2264,7 @@ msgstr "±Õ× Üã×ëÚØ"
msgid "Amiga Audio Emulator"
msgstr "ÍÜãÛïâÞà ×ÒãÚÐ Amiga"
-#: audio/softsynth/adlib.cpp:1594
+#: audio/softsynth/adlib.cpp:1593
msgid "AdLib Emulator"
msgstr "ÍÜãÛïâÞà AdLib"
@@ -2192,11 +2276,11 @@ msgstr "ÍÜãÛïâÞà Apple II GS (ÞâáãâáâÒãÕâ)"
msgid "C64 Audio Emulator"
msgstr "ÍÜãÛïâÞà ×ÒãÚÐ C64"
-#: audio/softsynth/mt32.cpp:329
+#: audio/softsynth/mt32.cpp:293
msgid "Initializing MT-32 Emulator"
msgstr "½ÐáâàÐØÒÐî íÜãÛïâÞà MT-32"
-#: audio/softsynth/mt32.cpp:543
+#: audio/softsynth/mt32.cpp:512
msgid "MT-32 Emulator"
msgstr "ÍÜãÛïâÞà MT-32"
@@ -2212,15 +2296,23 @@ msgstr "ÍÜãÛïâÞà IBM PCjr"
msgid "Keymap:"
msgstr "ÂÐÑÛØæÐ ÚÛÐÒØè:"
-#: backends/keymapper/remap-dialog.cpp:64
+#: backends/keymapper/remap-dialog.cpp:66
+msgid " (Effective)"
+msgstr " (´ÕÙáâÒãîéÐï)"
+
+#: backends/keymapper/remap-dialog.cpp:106
msgid " (Active)"
msgstr " (°ÚâØÒÝÐï)"
-#: backends/keymapper/remap-dialog.cpp:98
+#: backends/keymapper/remap-dialog.cpp:106
+msgid " (Blocked)"
+msgstr ""
+
+#: backends/keymapper/remap-dialog.cpp:119
msgid " (Global)"
msgstr " (³ÛÞÑÐÛìÝÐï)"
-#: backends/keymapper/remap-dialog.cpp:108
+#: backends/keymapper/remap-dialog.cpp:127
msgid " (Game)"
msgstr " (¸Óàë)"
@@ -2300,42 +2392,65 @@ msgstr "²ëáÞÚÞÕ ÚÐçÕáâÒÞ ×ÒãÚÐ (ÜÕÔÛÕÝÝÕÕ) (àÕÑãâ)"
msgid "Disable power off"
msgstr "·ÐßàÕâØâì ÒëÚÛîçÕÝØÕ"
-#: backends/platform/iphone/osys_events.cpp:338
+#: backends/platform/iphone/osys_events.cpp:301
msgid "Mouse-click-and-drag mode enabled."
msgstr "ÀÕÖØÜ ÜëèØ ÝÐÖÐâì-Ø-âïÝãâì ÒÚÛîçÕÝ."
-#: backends/platform/iphone/osys_events.cpp:340
+#: backends/platform/iphone/osys_events.cpp:303
msgid "Mouse-click-and-drag mode disabled."
msgstr "ÀÕÖØÜ ÜëèØ ÝÐÖÐâì-Ø-âïÝãâì ÒëÚÛîçÕÝ."
-#: backends/platform/iphone/osys_events.cpp:351
+#: backends/platform/iphone/osys_events.cpp:314
msgid "Touchpad mode enabled."
msgstr "ÀÕÖØÜ âÐçßÐÔÐ ÒÚÛîçÕÝ."
-#: backends/platform/iphone/osys_events.cpp:353
+#: backends/platform/iphone/osys_events.cpp:316
msgid "Touchpad mode disabled."
msgstr "ÀÕÖØÜ âÐçßÐÔÐ ÒëÚÛîçÕÝ."
-#: backends/platform/sdl/macosx/appmenu_osx.mm:67
+#: backends/platform/maemo/maemo.cpp:205
+msgid "Click Mode"
+msgstr "ÀÕÖØÜ éÕÛçÚÐ"
+
+#: backends/platform/maemo/maemo.cpp:211
+#: backends/platform/symbian/src/SymbianActions.cpp:42
+#: backends/platform/wince/CEActionsPocket.cpp:60
+#: backends/platform/wince/CEActionsSmartphone.cpp:43
+#: backends/platform/bada/form.cpp:281
+msgid "Left Click"
+msgstr "»ÕÒëÙ éÕÛçÞÚ"
+
+#: backends/platform/maemo/maemo.cpp:214
+msgid "Middle Click"
+msgstr "ÁàÕÔÝØÙ éÕÛçÞÚ"
+
+#: backends/platform/maemo/maemo.cpp:217
+#: backends/platform/symbian/src/SymbianActions.cpp:43
+#: backends/platform/wince/CEActionsSmartphone.cpp:44
+#: backends/platform/bada/form.cpp:273
+msgid "Right Click"
+msgstr "¿àÐÒëÙ éÕÛçÞÚ"
+
+#: backends/platform/sdl/macosx/appmenu_osx.mm:78
msgid "Hide ScummVM"
-msgstr "ÁßàïâÐâì ScummVM"
+msgstr "ÁÚàëâì ScummVM"
-#: backends/platform/sdl/macosx/appmenu_osx.mm:70
+#: backends/platform/sdl/macosx/appmenu_osx.mm:83
msgid "Hide Others"
-msgstr "ÁßàïâÐâì ´àãÓØÕ"
+msgstr "ÁÚàëâì ÞáâÐÛìÝëÕ"
-#: backends/platform/sdl/macosx/appmenu_osx.mm:74
+#: backends/platform/sdl/macosx/appmenu_osx.mm:88
msgid "Show All"
-msgstr "¿ÞÚÐ×Ðâì Òáñ"
+msgstr "¿ÞÚÐ×Ðâì ÒáÕ"
-#: backends/platform/sdl/macosx/appmenu_osx.mm:92
-#: backends/platform/sdl/macosx/appmenu_osx.mm:99
+#: backends/platform/sdl/macosx/appmenu_osx.mm:110
+#: backends/platform/sdl/macosx/appmenu_osx.mm:121
msgid "Window"
msgstr "¾ÚÝÞ"
-#: backends/platform/sdl/macosx/appmenu_osx.mm:95
+#: backends/platform/sdl/macosx/appmenu_osx.mm:115
msgid "Minimize"
-msgstr "¼ØÝØÜØ×ØàÞÒÐâì"
+msgstr "ÃÑàÐâì Ò Dock"
#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:45
msgid "Normal (no scaling)"
@@ -2347,12 +2462,12 @@ msgid "Normal (no scaling)"
msgstr "±Õ× ãÒÕÛØçÕÝØï"
#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2147
-#: backends/graphics/openglsdl/openglsdl-graphics.cpp:537
+#: backends/graphics/openglsdl/openglsdl-graphics.cpp:533
msgid "Enabled aspect ratio correction"
msgstr "ºÞààÕÚæØï áÞÞâÝÞèÕÝØï áâÞàÞÝ ÒÚÛîçÕÝÐ"
#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2153
-#: backends/graphics/openglsdl/openglsdl-graphics.cpp:542
+#: backends/graphics/openglsdl/openglsdl-graphics.cpp:538
msgid "Disabled aspect ratio correction"
msgstr "ºÞààÕÚæØï áÞÞâÝÞèÕÝØï áâÞàÞÝ ÒëÚÛîçÕÝÐ"
@@ -2361,7 +2476,7 @@ msgid "Active graphics filter:"
msgstr "°ÚâØÒÝëÙ ÓàÐäØçÕáÚØÙ äØÛìâà:"
#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2250
-#: backends/graphics/openglsdl/openglsdl-graphics.cpp:481
+#: backends/graphics/openglsdl/openglsdl-graphics.cpp:477
msgid "Windowed mode"
msgstr "¾ÚÞÝÝëÙ àÕÖØÜ"
@@ -2385,11 +2500,11 @@ msgstr "ÂÕÚãéØÙ ÒØÔÕÞàÕÖØÜ"
msgid "Current scale"
msgstr "ÂÕÚãéØÙ ÜÐáèâÐÑ"
-#: backends/graphics/openglsdl/openglsdl-graphics.cpp:562
+#: backends/graphics/openglsdl/openglsdl-graphics.cpp:558
msgid "Active filter mode: Linear"
msgstr "°ÚâØÒÝëÙ àÕÖØÜ äØÛìâàÐ: »ØÝÕÙÝëÙ"
-#: backends/graphics/openglsdl/openglsdl-graphics.cpp:564
+#: backends/graphics/openglsdl/openglsdl-graphics.cpp:560
msgid "Active filter mode: Nearest"
msgstr "°ÚâØÒÝëÙ àÕÖØÜ äØÛìâàÐ: ±ÛØÖÐÙèØÙ"
@@ -2413,19 +2528,6 @@ msgstr "²ÛÕÒÞ"
msgid "Right"
msgstr "²ßàÐÒÞ"
-#: backends/platform/symbian/src/SymbianActions.cpp:42
-#: backends/platform/wince/CEActionsPocket.cpp:60
-#: backends/platform/wince/CEActionsSmartphone.cpp:43
-#: backends/platform/bada/form.cpp:281
-msgid "Left Click"
-msgstr "»ÕÒëÙ éÕÛçÞÚ"
-
-#: backends/platform/symbian/src/SymbianActions.cpp:43
-#: backends/platform/wince/CEActionsSmartphone.cpp:44
-#: backends/platform/bada/form.cpp:273
-msgid "Right Click"
-msgstr "¿àÐÒëÙ éÕÛçÞÚ"
-
#: backends/platform/symbian/src/SymbianActions.cpp:46
#: backends/platform/wince/CEActionsSmartphone.cpp:47
msgid "Zone"
@@ -2712,15 +2814,15 @@ msgstr ""
"½Õ ×ÐÑãÔìâÕ ÝÐ×ÝÐçØâì ÚÛÐÒØèã ÔÛï ÔÕÙáâÒØï 'Hide Toolbar' çâÞÑë ãÒØÔÕâì ÒÕáì "
"ØÝÒÕÝâÐàì Ò ØÓàÕ"
-#: backends/events/default/default-events.cpp:222
+#: backends/events/default/default-events.cpp:191
msgid "Do you really want to return to the Launcher?"
msgstr "²ë ÔÕÙáâÒØâÕÛìÝÞ åÞâØâÕ ÒÕàÝãâìáï Ò ÓÛÐÒÝÞÕ ÜÕÝî?"
-#: backends/events/default/default-events.cpp:222
+#: backends/events/default/default-events.cpp:191
msgid "Launcher"
msgstr "³ÛÐÒÝÞÕ ÜÕÝî"
-#: backends/events/default/default-events.cpp:244
+#: backends/events/default/default-events.cpp:213
msgid "Do you really want to quit?"
msgstr "²ë ÔÕÙáâÒØâÕÛìÝÞ åÞâØâÕ ÒëÙâØ?"
@@ -2786,14 +2888,31 @@ msgstr "¿ÞÚÐ×Ðâì ÚÛÐÒØÐâãàã"
msgid "Control Mouse"
msgstr "ÃßàÐÒÛÕÝØÕ Üëèìî"
-#: backends/events/maemosdl/maemosdl-events.cpp:121
+#: backends/events/maemosdl/maemosdl-events.cpp:192
msgid "Clicking Enabled"
msgstr "ÉÕÛçÚØ ÒÚÛîçÕÝë"
-#: backends/events/maemosdl/maemosdl-events.cpp:121
+#: backends/events/maemosdl/maemosdl-events.cpp:192
msgid "Clicking Disabled"
msgstr "ÉÕÛçÚØ ÒëÚÛîçÕÝë"
+#~ msgid "Hercules Green"
+#~ msgstr "Hercules ·ÕÛñÝëÙ"
+
+#~ msgid "Hercules Amber"
+#~ msgstr "Hercules ÏÝâÐàÝëÙ"
+
+#~ msgctxt "lowres"
+#~ msgid "Hercules Green"
+#~ msgstr "Hercules ·ÕÛñÝëÙ"
+
+#~ msgctxt "lowres"
+#~ msgid "Hercules Amber"
+#~ msgstr "Hercules ÏÝâÐàÝëÙ"
+
+#~ msgid "Save game failed!"
+#~ msgstr "½Õ ãÔÐÛÞáì áÞåàÐÝØâì ØÓàã!"
+
#~ msgctxt "lowres"
#~ msgid "Add Game..."
#~ msgstr "´ÞÑ. ØÓàã"
diff --git a/po/scummvm.pot b/po/scummvm.pot
index a94e0ab705..989779fc91 100644
--- a/po/scummvm.pot
+++ b/po/scummvm.pot
@@ -6,13 +6,12 @@
#, fuzzy
msgid ""
msgstr ""
-"Project-Id-Version: ScummVM 1.4.0git\n"
+"Project-Id-Version: ScummVM 1.5.0git\n"
"Report-Msgid-Bugs-To: scummvm-devel@lists.sf.net\n"
-"POT-Creation-Date: 2011-10-19 13:42+0100\n"
+"POT-Creation-Date: 2012-03-07 22:09+0000\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
-"Language: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=CHARSET\n"
"Content-Transfer-Encoding: 8bit\n"
@@ -44,13 +43,13 @@ msgid "Go up"
msgstr ""
#: gui/browser.cpp:69 gui/chooser.cpp:45 gui/KeysDialog.cpp:43
-#: gui/launcher.cpp:312 gui/massadd.cpp:94 gui/options.cpp:1178
+#: gui/launcher.cpp:320 gui/massadd.cpp:94 gui/options.cpp:1253
#: gui/saveload.cpp:63 gui/saveload.cpp:155 gui/themebrowser.cpp:54
-#: engines/engine.cpp:436 engines/scumm/dialogs.cpp:190
+#: engines/engine.cpp:442 engines/scumm/dialogs.cpp:190
#: engines/sword1/control.cpp:865 engines/parallaction/saveload.cpp:281
#: backends/platform/wii/options.cpp:48
-#: backends/events/default/default-events.cpp:222
-#: backends/events/default/default-events.cpp:244
+#: backends/events/default/default-events.cpp:191
+#: backends/events/default/default-events.cpp:213
msgid "Cancel"
msgstr ""
@@ -58,25 +57,29 @@ msgstr ""
msgid "Choose"
msgstr ""
-#: gui/gui-manager.cpp:116 engines/scumm/help.cpp:125
+#: gui/gui-manager.cpp:115 engines/scumm/help.cpp:125
#: engines/scumm/help.cpp:140 engines/scumm/help.cpp:165
#: engines/scumm/help.cpp:191 engines/scumm/help.cpp:209
#: backends/keymapper/remap-dialog.cpp:52
msgid "Close"
msgstr ""
-#: gui/gui-manager.cpp:119
+#: gui/gui-manager.cpp:118
msgid "Mouse click"
msgstr ""
-#: gui/gui-manager.cpp:122 base/main.cpp:283
+#: gui/gui-manager.cpp:122 base/main.cpp:288
msgid "Display keyboard"
msgstr ""
-#: gui/gui-manager.cpp:125 base/main.cpp:286
+#: gui/gui-manager.cpp:126 base/main.cpp:292
msgid "Remap keys"
msgstr ""
+#: gui/gui-manager.cpp:129 base/main.cpp:295
+msgid "Toggle FullScreen"
+msgstr ""
+
#: gui/KeysDialog.h:36 gui/KeysDialog.cpp:145
msgid "Choose an action to map"
msgstr ""
@@ -85,16 +88,17 @@ msgstr ""
msgid "Map"
msgstr ""
-#: gui/KeysDialog.cpp:42 gui/launcher.cpp:313 gui/launcher.cpp:936
-#: gui/launcher.cpp:940 gui/massadd.cpp:91 gui/options.cpp:1179
-#: engines/engine.cpp:359 engines/engine.cpp:370 engines/scumm/dialogs.cpp:192
-#: engines/scumm/scumm.cpp:1776 engines/agos/animation.cpp:551
+#: gui/KeysDialog.cpp:42 gui/launcher.cpp:321 gui/launcher.cpp:960
+#: gui/launcher.cpp:964 gui/massadd.cpp:91 gui/options.cpp:1254
+#: engines/engine.cpp:361 engines/engine.cpp:372 engines/scumm/dialogs.cpp:192
+#: engines/scumm/scumm.cpp:1775 engines/agos/animation.cpp:551
#: engines/groovie/script.cpp:420 engines/sky/compact.cpp:131
-#: engines/sky/compact.cpp:141 engines/sword1/animation.cpp:344
-#: engines/sword1/animation.cpp:354 engines/sword1/animation.cpp:360
-#: engines/sword1/control.cpp:865 engines/sword1/logic.cpp:1633
-#: engines/sword2/animation.cpp:379 engines/sword2/animation.cpp:389
-#: engines/sword2/animation.cpp:398 engines/parallaction/saveload.cpp:281
+#: engines/sky/compact.cpp:141 engines/sword1/animation.cpp:539
+#: engines/sword1/animation.cpp:560 engines/sword1/animation.cpp:570
+#: engines/sword1/animation.cpp:577 engines/sword1/control.cpp:865
+#: engines/sword1/logic.cpp:1633 engines/sword2/animation.cpp:435
+#: engines/sword2/animation.cpp:455 engines/sword2/animation.cpp:465
+#: engines/sword2/animation.cpp:474 engines/parallaction/saveload.cpp:281
#: backends/platform/wii/options.cpp:47
#: backends/platform/wince/CELauncherDialog.cpp:54
msgid "OK"
@@ -122,330 +126,328 @@ msgstr ""
msgid "Press the key to associate"
msgstr ""
-#: gui/launcher.cpp:165
+#: gui/launcher.cpp:170
msgid "Game"
msgstr ""
-#: gui/launcher.cpp:169
+#: gui/launcher.cpp:174
msgid "ID:"
msgstr ""
-#: gui/launcher.cpp:169 gui/launcher.cpp:171 gui/launcher.cpp:172
+#: gui/launcher.cpp:174 gui/launcher.cpp:176 gui/launcher.cpp:177
msgid ""
"Short game identifier used for referring to savegames and running the game "
"from the command line"
msgstr ""
-#: gui/launcher.cpp:171
+#: gui/launcher.cpp:176
msgctxt "lowres"
msgid "ID:"
msgstr ""
-#: gui/launcher.cpp:176
+#: gui/launcher.cpp:181
msgid "Name:"
msgstr ""
-#: gui/launcher.cpp:176 gui/launcher.cpp:178 gui/launcher.cpp:179
+#: gui/launcher.cpp:181 gui/launcher.cpp:183 gui/launcher.cpp:184
msgid "Full title of the game"
msgstr ""
-#: gui/launcher.cpp:178
+#: gui/launcher.cpp:183
msgctxt "lowres"
msgid "Name:"
msgstr ""
-#: gui/launcher.cpp:182
+#: gui/launcher.cpp:187
msgid "Language:"
msgstr ""
-#: gui/launcher.cpp:182 gui/launcher.cpp:183
+#: gui/launcher.cpp:187 gui/launcher.cpp:188
msgid ""
"Language of the game. This will not turn your Spanish game version into "
"English"
msgstr ""
-#: gui/launcher.cpp:184 gui/launcher.cpp:198 gui/options.cpp:74
-#: gui/options.cpp:708 gui/options.cpp:718 gui/options.cpp:1149
+#: gui/launcher.cpp:189 gui/launcher.cpp:203 gui/options.cpp:80
+#: gui/options.cpp:745 gui/options.cpp:758 gui/options.cpp:1224
#: audio/null.cpp:40
msgid "<default>"
msgstr ""
-#: gui/launcher.cpp:194
+#: gui/launcher.cpp:199
msgid "Platform:"
msgstr ""
-#: gui/launcher.cpp:194 gui/launcher.cpp:196 gui/launcher.cpp:197
+#: gui/launcher.cpp:199 gui/launcher.cpp:201 gui/launcher.cpp:202
msgid "Platform the game was originally designed for"
msgstr ""
-#: gui/launcher.cpp:196
+#: gui/launcher.cpp:201
msgctxt "lowres"
msgid "Platform:"
msgstr ""
-#: gui/launcher.cpp:208 gui/options.cpp:1018 gui/options.cpp:1035
+#: gui/launcher.cpp:213 gui/options.cpp:1087 gui/options.cpp:1104
msgid "Graphics"
msgstr ""
-#: gui/launcher.cpp:208 gui/options.cpp:1018 gui/options.cpp:1035
+#: gui/launcher.cpp:213 gui/options.cpp:1087 gui/options.cpp:1104
msgid "GFX"
msgstr ""
-#: gui/launcher.cpp:211
+#: gui/launcher.cpp:216
msgid "Override global graphic settings"
msgstr ""
-#: gui/launcher.cpp:213
+#: gui/launcher.cpp:218
msgctxt "lowres"
msgid "Override global graphic settings"
msgstr ""
-#: gui/launcher.cpp:220 gui/options.cpp:1041
+#: gui/launcher.cpp:225 gui/options.cpp:1110
msgid "Audio"
msgstr ""
-#: gui/launcher.cpp:223
+#: gui/launcher.cpp:228
msgid "Override global audio settings"
msgstr ""
-#: gui/launcher.cpp:225
+#: gui/launcher.cpp:230
msgctxt "lowres"
msgid "Override global audio settings"
msgstr ""
-#: gui/launcher.cpp:234 gui/options.cpp:1046
+#: gui/launcher.cpp:239 gui/options.cpp:1115
msgid "Volume"
msgstr ""
-#: gui/launcher.cpp:236 gui/options.cpp:1048
+#: gui/launcher.cpp:241 gui/options.cpp:1117
msgctxt "lowres"
msgid "Volume"
msgstr ""
-#: gui/launcher.cpp:239
+#: gui/launcher.cpp:244
msgid "Override global volume settings"
msgstr ""
-#: gui/launcher.cpp:241
+#: gui/launcher.cpp:246
msgctxt "lowres"
msgid "Override global volume settings"
msgstr ""
-#: gui/launcher.cpp:248 gui/options.cpp:1056
+#: gui/launcher.cpp:254 gui/options.cpp:1125
msgid "MIDI"
msgstr ""
-#: gui/launcher.cpp:251
+#: gui/launcher.cpp:257
msgid "Override global MIDI settings"
msgstr ""
-#: gui/launcher.cpp:253
+#: gui/launcher.cpp:259
msgctxt "lowres"
msgid "Override global MIDI settings"
msgstr ""
-#: gui/launcher.cpp:263 gui/options.cpp:1062
+#: gui/launcher.cpp:268 gui/options.cpp:1131
msgid "MT-32"
msgstr ""
-#: gui/launcher.cpp:266
+#: gui/launcher.cpp:271
msgid "Override global MT-32 settings"
msgstr ""
-#: gui/launcher.cpp:268
+#: gui/launcher.cpp:273
msgctxt "lowres"
msgid "Override global MT-32 settings"
msgstr ""
-#: gui/launcher.cpp:279 gui/options.cpp:1069
+#: gui/launcher.cpp:282 gui/options.cpp:1138
msgid "Paths"
msgstr ""
-#: gui/launcher.cpp:281 gui/options.cpp:1071
+#: gui/launcher.cpp:284 gui/options.cpp:1140
msgctxt "lowres"
msgid "Paths"
msgstr ""
-#: gui/launcher.cpp:288
+#: gui/launcher.cpp:291
msgid "Game Path:"
msgstr ""
-#: gui/launcher.cpp:290
+#: gui/launcher.cpp:293
msgctxt "lowres"
msgid "Game Path:"
msgstr ""
-#: gui/launcher.cpp:295 gui/options.cpp:1091
+#: gui/launcher.cpp:298 gui/options.cpp:1164
msgid "Extra Path:"
msgstr ""
-#: gui/launcher.cpp:295 gui/launcher.cpp:297 gui/launcher.cpp:298
+#: gui/launcher.cpp:298 gui/launcher.cpp:300 gui/launcher.cpp:301
msgid "Specifies path to additional data used the game"
msgstr ""
-#: gui/launcher.cpp:297 gui/options.cpp:1093
+#: gui/launcher.cpp:300 gui/options.cpp:1166
msgctxt "lowres"
msgid "Extra Path:"
msgstr ""
-#: gui/launcher.cpp:302 gui/options.cpp:1079
+#: gui/launcher.cpp:307 gui/options.cpp:1148
msgid "Save Path:"
msgstr ""
-#: gui/launcher.cpp:302 gui/launcher.cpp:304 gui/launcher.cpp:305
-#: gui/options.cpp:1079 gui/options.cpp:1081 gui/options.cpp:1082
+#: gui/launcher.cpp:307 gui/launcher.cpp:309 gui/launcher.cpp:310
+#: gui/options.cpp:1148 gui/options.cpp:1150 gui/options.cpp:1151
msgid "Specifies where your savegames are put"
msgstr ""
-#: gui/launcher.cpp:304 gui/options.cpp:1081
+#: gui/launcher.cpp:309 gui/options.cpp:1150
msgctxt "lowres"
msgid "Save Path:"
msgstr ""
-#: gui/launcher.cpp:321 gui/launcher.cpp:404 gui/launcher.cpp:453
-#: gui/options.cpp:1088 gui/options.cpp:1094 gui/options.cpp:1101
-#: gui/options.cpp:1202 gui/options.cpp:1208 gui/options.cpp:1214
-#: gui/options.cpp:1222 gui/options.cpp:1246 gui/options.cpp:1250
-#: gui/options.cpp:1256 gui/options.cpp:1263 gui/options.cpp:1362
+#: gui/launcher.cpp:329 gui/launcher.cpp:416 gui/launcher.cpp:469
+#: gui/launcher.cpp:523 gui/options.cpp:1159 gui/options.cpp:1167
+#: gui/options.cpp:1176 gui/options.cpp:1283 gui/options.cpp:1289
+#: gui/options.cpp:1297 gui/options.cpp:1327 gui/options.cpp:1333
+#: gui/options.cpp:1340 gui/options.cpp:1433 gui/options.cpp:1436
+#: gui/options.cpp:1448
msgctxt "path"
msgid "None"
msgstr ""
-#: gui/launcher.cpp:326 gui/launcher.cpp:408
+#: gui/launcher.cpp:334 gui/launcher.cpp:422 gui/launcher.cpp:527
+#: gui/options.cpp:1277 gui/options.cpp:1321 gui/options.cpp:1439
#: backends/platform/wii/options.cpp:56
msgid "Default"
msgstr ""
-#: gui/launcher.cpp:446 gui/options.cpp:1356
+#: gui/launcher.cpp:462 gui/options.cpp:1442
msgid "Select SoundFont"
msgstr ""
-#: gui/launcher.cpp:465 gui/launcher.cpp:612
+#: gui/launcher.cpp:481 gui/launcher.cpp:636
msgid "Select directory with game data"
msgstr ""
-#: gui/launcher.cpp:483
+#: gui/launcher.cpp:499
msgid "Select additional game directory"
msgstr ""
-#: gui/launcher.cpp:495
+#: gui/launcher.cpp:511
msgid "Select directory for saved games"
msgstr ""
-#: gui/launcher.cpp:514
+#: gui/launcher.cpp:538
msgid "This game ID is already taken. Please choose another one."
msgstr ""
-#: gui/launcher.cpp:555 engines/dialogs.cpp:110
+#: gui/launcher.cpp:579 engines/dialogs.cpp:110
msgid "~Q~uit"
msgstr ""
-#: gui/launcher.cpp:555 backends/platform/sdl/macosx/appmenu_osx.mm:80
+#: gui/launcher.cpp:579 backends/platform/sdl/macosx/appmenu_osx.mm:96
msgid "Quit ScummVM"
msgstr ""
-#: gui/launcher.cpp:556
+#: gui/launcher.cpp:580
msgid "A~b~out..."
msgstr ""
-#: gui/launcher.cpp:556 backends/platform/sdl/macosx/appmenu_osx.mm:61
+#: gui/launcher.cpp:580 backends/platform/sdl/macosx/appmenu_osx.mm:70
msgid "About ScummVM"
msgstr ""
-#: gui/launcher.cpp:557
+#: gui/launcher.cpp:581
msgid "~O~ptions..."
msgstr ""
-#: gui/launcher.cpp:557
+#: gui/launcher.cpp:581
msgid "Change global ScummVM options"
msgstr ""
-#: gui/launcher.cpp:559
+#: gui/launcher.cpp:583
msgid "~S~tart"
msgstr ""
-#: gui/launcher.cpp:559
+#: gui/launcher.cpp:583
msgid "Start selected game"
msgstr ""
-#: gui/launcher.cpp:562
+#: gui/launcher.cpp:586
msgid "~L~oad..."
msgstr ""
-#: gui/launcher.cpp:562
+#: gui/launcher.cpp:586
msgid "Load savegame for selected game"
msgstr ""
-#: gui/launcher.cpp:567 gui/launcher.cpp:1055
+#: gui/launcher.cpp:591 gui/launcher.cpp:1079
msgid "~A~dd Game..."
msgstr ""
-#: gui/launcher.cpp:567 gui/launcher.cpp:574
+#: gui/launcher.cpp:591 gui/launcher.cpp:598
msgid "Hold Shift for Mass Add"
msgstr ""
-#: gui/launcher.cpp:569
+#: gui/launcher.cpp:593
msgid "~E~dit Game..."
msgstr ""
-#: gui/launcher.cpp:569 gui/launcher.cpp:576
+#: gui/launcher.cpp:593 gui/launcher.cpp:600
msgid "Change game options"
msgstr ""
-#: gui/launcher.cpp:571
+#: gui/launcher.cpp:595
msgid "~R~emove Game"
msgstr ""
-#: gui/launcher.cpp:571 gui/launcher.cpp:578
+#: gui/launcher.cpp:595 gui/launcher.cpp:602
msgid "Remove game from the list. The game data files stay intact"
msgstr ""
-#: gui/launcher.cpp:574 gui/launcher.cpp:1055
+#: gui/launcher.cpp:598 gui/launcher.cpp:1079
msgctxt "lowres"
msgid "~A~dd Game..."
msgstr ""
-#: gui/launcher.cpp:576
+#: gui/launcher.cpp:600
msgctxt "lowres"
msgid "~E~dit Game..."
msgstr ""
-#: gui/launcher.cpp:578
+#: gui/launcher.cpp:602
msgctxt "lowres"
msgid "~R~emove Game"
msgstr ""
-#: gui/launcher.cpp:586
+#: gui/launcher.cpp:610
msgid "Search in game list"
msgstr ""
-#: gui/launcher.cpp:590 gui/launcher.cpp:1102
+#: gui/launcher.cpp:614 gui/launcher.cpp:1126
msgid "Search:"
msgstr ""
-#: gui/launcher.cpp:593 gui/options.cpp:826
-msgid "Clear value"
-msgstr ""
-
-#: gui/launcher.cpp:615 engines/dialogs.cpp:114 engines/mohawk/myst.cpp:255
+#: gui/launcher.cpp:639 engines/dialogs.cpp:114 engines/mohawk/myst.cpp:255
#: engines/mohawk/riven.cpp:716 engines/cruise/menu.cpp:216
msgid "Load game:"
msgstr ""
-#: gui/launcher.cpp:615 engines/dialogs.cpp:114 engines/scumm/dialogs.cpp:188
+#: gui/launcher.cpp:639 engines/dialogs.cpp:114 engines/scumm/dialogs.cpp:188
#: engines/mohawk/myst.cpp:255 engines/mohawk/riven.cpp:716
#: engines/cruise/menu.cpp:216 backends/platform/wince/CEActionsPocket.cpp:267
#: backends/platform/wince/CEActionsSmartphone.cpp:231
msgid "Load"
msgstr ""
-#: gui/launcher.cpp:723
+#: gui/launcher.cpp:747
msgid ""
"Do you really want to run the mass game detector? This could potentially add "
"a huge number of games."
msgstr ""
-#: gui/launcher.cpp:724 gui/launcher.cpp:872
+#: gui/launcher.cpp:748 gui/launcher.cpp:896
#: backends/events/symbiansdl/symbiansdl-events.cpp:184
#: backends/platform/wince/CEActionsPocket.cpp:326
#: backends/platform/wince/CEActionsSmartphone.cpp:287
@@ -453,7 +455,7 @@ msgstr ""
msgid "Yes"
msgstr ""
-#: gui/launcher.cpp:724 gui/launcher.cpp:872
+#: gui/launcher.cpp:748 gui/launcher.cpp:896
#: backends/events/symbiansdl/symbiansdl-events.cpp:184
#: backends/platform/wince/CEActionsPocket.cpp:326
#: backends/platform/wince/CEActionsSmartphone.cpp:287
@@ -461,36 +463,36 @@ msgstr ""
msgid "No"
msgstr ""
-#: gui/launcher.cpp:772
+#: gui/launcher.cpp:796
msgid "ScummVM couldn't open the specified directory!"
msgstr ""
-#: gui/launcher.cpp:784
+#: gui/launcher.cpp:808
msgid "ScummVM could not find any game in the specified directory!"
msgstr ""
-#: gui/launcher.cpp:798
+#: gui/launcher.cpp:822
msgid "Pick the game:"
msgstr ""
-#: gui/launcher.cpp:872
+#: gui/launcher.cpp:896
msgid "Do you really want to remove this game configuration?"
msgstr ""
-#: gui/launcher.cpp:936
+#: gui/launcher.cpp:960
msgid "This game does not support loading games from the launcher."
msgstr ""
-#: gui/launcher.cpp:940
+#: gui/launcher.cpp:964
msgid "ScummVM could not find any engine capable of running the selected game!"
msgstr ""
-#: gui/launcher.cpp:1054
+#: gui/launcher.cpp:1078
msgctxt "lowres"
msgid "Mass Add..."
msgstr ""
-#: gui/launcher.cpp:1054
+#: gui/launcher.cpp:1078
msgid "Mass Add..."
msgstr ""
@@ -517,389 +519,389 @@ msgstr ""
msgid "Discovered %d new games, ignored %d previously added games ..."
msgstr ""
-#: gui/options.cpp:72
+#: gui/options.cpp:78
msgid "Never"
msgstr ""
-#: gui/options.cpp:72
+#: gui/options.cpp:78
msgid "every 5 mins"
msgstr ""
-#: gui/options.cpp:72
+#: gui/options.cpp:78
msgid "every 10 mins"
msgstr ""
-#: gui/options.cpp:72
+#: gui/options.cpp:78
msgid "every 15 mins"
msgstr ""
-#: gui/options.cpp:72
+#: gui/options.cpp:78
msgid "every 30 mins"
msgstr ""
-#: gui/options.cpp:74
+#: gui/options.cpp:80
msgid "8 kHz"
msgstr ""
-#: gui/options.cpp:74
+#: gui/options.cpp:80
msgid "11kHz"
msgstr ""
-#: gui/options.cpp:74
+#: gui/options.cpp:80
msgid "22 kHz"
msgstr ""
-#: gui/options.cpp:74
+#: gui/options.cpp:80
msgid "44 kHz"
msgstr ""
-#: gui/options.cpp:74
+#: gui/options.cpp:80
msgid "48 kHz"
msgstr ""
-#: gui/options.cpp:236 gui/options.cpp:464 gui/options.cpp:559
-#: gui/options.cpp:625 gui/options.cpp:825
+#: gui/options.cpp:257 gui/options.cpp:485 gui/options.cpp:586
+#: gui/options.cpp:659 gui/options.cpp:868
msgctxt "soundfont"
msgid "None"
msgstr ""
-#: gui/options.cpp:372
+#: gui/options.cpp:393
msgid "Failed to apply some of the graphic options changes:"
msgstr ""
-#: gui/options.cpp:384
+#: gui/options.cpp:405
msgid "the video mode could not be changed."
msgstr ""
-#: gui/options.cpp:390
+#: gui/options.cpp:411
msgid "the fullscreen setting could not be changed"
msgstr ""
-#: gui/options.cpp:396
+#: gui/options.cpp:417
msgid "the aspect ratio setting could not be changed"
msgstr ""
-#: gui/options.cpp:705
+#: gui/options.cpp:742
msgid "Graphics mode:"
msgstr ""
-#: gui/options.cpp:716
+#: gui/options.cpp:756
msgid "Render mode:"
msgstr ""
-#: gui/options.cpp:716 gui/options.cpp:717
+#: gui/options.cpp:756 gui/options.cpp:757
msgid "Special dithering modes supported by some games"
msgstr ""
-#: gui/options.cpp:726
+#: gui/options.cpp:768
#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2248
-#: backends/graphics/openglsdl/openglsdl-graphics.cpp:476
+#: backends/graphics/openglsdl/openglsdl-graphics.cpp:472
msgid "Fullscreen mode"
msgstr ""
-#: gui/options.cpp:729
+#: gui/options.cpp:771
msgid "Aspect ratio correction"
msgstr ""
-#: gui/options.cpp:729
+#: gui/options.cpp:771
msgid "Correct aspect ratio for 320x200 games"
msgstr ""
-#: gui/options.cpp:730
+#: gui/options.cpp:772
msgid "EGA undithering"
msgstr ""
-#: gui/options.cpp:730
+#: gui/options.cpp:772
msgid "Enable undithering in EGA games that support it"
msgstr ""
-#: gui/options.cpp:738
+#: gui/options.cpp:780
msgid "Preferred Device:"
msgstr ""
-#: gui/options.cpp:738
+#: gui/options.cpp:780
msgid "Music Device:"
msgstr ""
-#: gui/options.cpp:738 gui/options.cpp:740
+#: gui/options.cpp:780 gui/options.cpp:782
msgid "Specifies preferred sound device or sound card emulator"
msgstr ""
-#: gui/options.cpp:738 gui/options.cpp:740 gui/options.cpp:741
+#: gui/options.cpp:780 gui/options.cpp:782 gui/options.cpp:783
msgid "Specifies output sound device or sound card emulator"
msgstr ""
-#: gui/options.cpp:740
+#: gui/options.cpp:782
msgctxt "lowres"
msgid "Preferred Dev.:"
msgstr ""
-#: gui/options.cpp:740
+#: gui/options.cpp:782
msgctxt "lowres"
msgid "Music Device:"
msgstr ""
-#: gui/options.cpp:766
+#: gui/options.cpp:809
msgid "AdLib emulator:"
msgstr ""
-#: gui/options.cpp:766 gui/options.cpp:767
+#: gui/options.cpp:809 gui/options.cpp:810
msgid "AdLib is used for music in many games"
msgstr ""
-#: gui/options.cpp:777
+#: gui/options.cpp:820
msgid "Output rate:"
msgstr ""
-#: gui/options.cpp:777 gui/options.cpp:778
+#: gui/options.cpp:820 gui/options.cpp:821
msgid ""
"Higher value specifies better sound quality but may be not supported by your "
"soundcard"
msgstr ""
-#: gui/options.cpp:788
+#: gui/options.cpp:831
msgid "GM Device:"
msgstr ""
-#: gui/options.cpp:788
+#: gui/options.cpp:831
msgid "Specifies default sound device for General MIDI output"
msgstr ""
-#: gui/options.cpp:799
+#: gui/options.cpp:842
msgid "Don't use General MIDI music"
msgstr ""
-#: gui/options.cpp:810 gui/options.cpp:871
+#: gui/options.cpp:853 gui/options.cpp:915
msgid "Use first available device"
msgstr ""
-#: gui/options.cpp:822
+#: gui/options.cpp:865
msgid "SoundFont:"
msgstr ""
-#: gui/options.cpp:822 gui/options.cpp:824 gui/options.cpp:825
+#: gui/options.cpp:865 gui/options.cpp:867 gui/options.cpp:868
msgid "SoundFont is supported by some audio cards, Fluidsynth and Timidity"
msgstr ""
-#: gui/options.cpp:824
+#: gui/options.cpp:867
msgctxt "lowres"
msgid "SoundFont:"
msgstr ""
-#: gui/options.cpp:829
+#: gui/options.cpp:873
msgid "Mixed AdLib/MIDI mode"
msgstr ""
-#: gui/options.cpp:829
+#: gui/options.cpp:873
msgid "Use both MIDI and AdLib sound generation"
msgstr ""
-#: gui/options.cpp:832
+#: gui/options.cpp:876
msgid "MIDI gain:"
msgstr ""
-#: gui/options.cpp:842
+#: gui/options.cpp:886
msgid "MT-32 Device:"
msgstr ""
-#: gui/options.cpp:842
+#: gui/options.cpp:886
msgid "Specifies default sound device for Roland MT-32/LAPC1/CM32l/CM64 output"
msgstr ""
-#: gui/options.cpp:847
+#: gui/options.cpp:891
msgid "True Roland MT-32 (disable GM emulation)"
msgstr ""
-#: gui/options.cpp:847 gui/options.cpp:849
+#: gui/options.cpp:891 gui/options.cpp:893
msgid ""
"Check if you want to use your real hardware Roland-compatible sound device "
"connected to your computer"
msgstr ""
-#: gui/options.cpp:849
+#: gui/options.cpp:893
msgctxt "lowres"
msgid "True Roland MT-32 (no GM emulation)"
msgstr ""
-#: gui/options.cpp:852
+#: gui/options.cpp:896
msgid "Enable Roland GS Mode"
msgstr ""
-#: gui/options.cpp:852
+#: gui/options.cpp:896
msgid "Turns off General MIDI mapping for games with Roland MT-32 soundtrack"
msgstr ""
-#: gui/options.cpp:861
+#: gui/options.cpp:905
msgid "Don't use Roland MT-32 music"
msgstr ""
-#: gui/options.cpp:888
+#: gui/options.cpp:932
msgid "Text and Speech:"
msgstr ""
-#: gui/options.cpp:892 gui/options.cpp:902
+#: gui/options.cpp:936 gui/options.cpp:946
msgid "Speech"
msgstr ""
-#: gui/options.cpp:893 gui/options.cpp:903
+#: gui/options.cpp:937 gui/options.cpp:947
msgid "Subtitles"
msgstr ""
-#: gui/options.cpp:894
+#: gui/options.cpp:938
msgid "Both"
msgstr ""
-#: gui/options.cpp:896
+#: gui/options.cpp:940
msgid "Subtitle speed:"
msgstr ""
-#: gui/options.cpp:898
+#: gui/options.cpp:942
msgctxt "lowres"
msgid "Text and Speech:"
msgstr ""
-#: gui/options.cpp:902
+#: gui/options.cpp:946
msgid "Spch"
msgstr ""
-#: gui/options.cpp:903
+#: gui/options.cpp:947
msgid "Subs"
msgstr ""
-#: gui/options.cpp:904
+#: gui/options.cpp:948
msgctxt "lowres"
msgid "Both"
msgstr ""
-#: gui/options.cpp:904
+#: gui/options.cpp:948
msgid "Show subtitles and play speech"
msgstr ""
-#: gui/options.cpp:906
+#: gui/options.cpp:950
msgctxt "lowres"
msgid "Subtitle speed:"
msgstr ""
-#: gui/options.cpp:922
+#: gui/options.cpp:966
msgid "Music volume:"
msgstr ""
-#: gui/options.cpp:924
+#: gui/options.cpp:968
msgctxt "lowres"
msgid "Music volume:"
msgstr ""
-#: gui/options.cpp:931
+#: gui/options.cpp:975
msgid "Mute All"
msgstr ""
-#: gui/options.cpp:934
+#: gui/options.cpp:978
msgid "SFX volume:"
msgstr ""
-#: gui/options.cpp:934 gui/options.cpp:936 gui/options.cpp:937
+#: gui/options.cpp:978 gui/options.cpp:980 gui/options.cpp:981
msgid "Special sound effects volume"
msgstr ""
-#: gui/options.cpp:936
+#: gui/options.cpp:980
msgctxt "lowres"
msgid "SFX volume:"
msgstr ""
-#: gui/options.cpp:944
+#: gui/options.cpp:988
msgid "Speech volume:"
msgstr ""
-#: gui/options.cpp:946
+#: gui/options.cpp:990
msgctxt "lowres"
msgid "Speech volume:"
msgstr ""
-#: gui/options.cpp:1085
+#: gui/options.cpp:1156
msgid "Theme Path:"
msgstr ""
-#: gui/options.cpp:1087
+#: gui/options.cpp:1158
msgctxt "lowres"
msgid "Theme Path:"
msgstr ""
-#: gui/options.cpp:1091 gui/options.cpp:1093 gui/options.cpp:1094
+#: gui/options.cpp:1164 gui/options.cpp:1166 gui/options.cpp:1167
msgid "Specifies path to additional data used by all games or ScummVM"
msgstr ""
-#: gui/options.cpp:1098
+#: gui/options.cpp:1173
msgid "Plugins Path:"
msgstr ""
-#: gui/options.cpp:1100
+#: gui/options.cpp:1175
msgctxt "lowres"
msgid "Plugins Path:"
msgstr ""
-#: gui/options.cpp:1109
+#: gui/options.cpp:1184
msgid "Misc"
msgstr ""
-#: gui/options.cpp:1111
+#: gui/options.cpp:1186
msgctxt "lowres"
msgid "Misc"
msgstr ""
-#: gui/options.cpp:1113
+#: gui/options.cpp:1188
msgid "Theme:"
msgstr ""
-#: gui/options.cpp:1117
+#: gui/options.cpp:1192
msgid "GUI Renderer:"
msgstr ""
-#: gui/options.cpp:1129
+#: gui/options.cpp:1204
msgid "Autosave:"
msgstr ""
-#: gui/options.cpp:1131
+#: gui/options.cpp:1206
msgctxt "lowres"
msgid "Autosave:"
msgstr ""
-#: gui/options.cpp:1139
+#: gui/options.cpp:1214
msgid "Keys"
msgstr ""
-#: gui/options.cpp:1146
+#: gui/options.cpp:1221
msgid "GUI Language:"
msgstr ""
-#: gui/options.cpp:1146
+#: gui/options.cpp:1221
msgid "Language of ScummVM GUI"
msgstr ""
-#: gui/options.cpp:1295
+#: gui/options.cpp:1372
msgid "You have to restart ScummVM before your changes will take effect."
msgstr ""
-#: gui/options.cpp:1308
+#: gui/options.cpp:1385
msgid "Select directory for savegames"
msgstr ""
-#: gui/options.cpp:1315
+#: gui/options.cpp:1392
msgid "The chosen directory cannot be written to. Please select another one."
msgstr ""
-#: gui/options.cpp:1324
+#: gui/options.cpp:1401
msgid "Select directory for GUI themes"
msgstr ""
-#: gui/options.cpp:1334
+#: gui/options.cpp:1411
msgid "Select directory for extra files"
msgstr ""
-#: gui/options.cpp:1345
+#: gui/options.cpp:1422
msgid "Select directory for plugins"
msgstr ""
-#: gui/options.cpp:1389
+#: gui/options.cpp:1475
msgid ""
"The theme you selected does not support your current language. If you want "
"to use this theme you need to switch to another language first."
@@ -945,60 +947,64 @@ msgstr ""
msgid "Select a Theme"
msgstr ""
-#: gui/ThemeEngine.cpp:328
+#: gui/ThemeEngine.cpp:333
msgid "Disabled GFX"
msgstr ""
-#: gui/ThemeEngine.cpp:328
+#: gui/ThemeEngine.cpp:333
msgctxt "lowres"
msgid "Disabled GFX"
msgstr ""
-#: gui/ThemeEngine.cpp:329
+#: gui/ThemeEngine.cpp:334
msgid "Standard Renderer (16bpp)"
msgstr ""
-#: gui/ThemeEngine.cpp:329
+#: gui/ThemeEngine.cpp:334
msgid "Standard (16bpp)"
msgstr ""
-#: gui/ThemeEngine.cpp:331
+#: gui/ThemeEngine.cpp:336
msgid "Antialiased Renderer (16bpp)"
msgstr ""
-#: gui/ThemeEngine.cpp:331
+#: gui/ThemeEngine.cpp:336
msgid "Antialiased (16bpp)"
msgstr ""
+#: gui/widget.cpp:312 gui/widget.cpp:314 gui/widget.cpp:320 gui/widget.cpp:322
+msgid "Clear value"
+msgstr ""
+
#: base/main.cpp:203
#, c-format
msgid "Engine does not support debug level '%s'"
msgstr ""
-#: base/main.cpp:271
+#: base/main.cpp:275
msgid "Menu"
msgstr ""
-#: base/main.cpp:274 backends/platform/symbian/src/SymbianActions.cpp:45
+#: base/main.cpp:278 backends/platform/symbian/src/SymbianActions.cpp:45
#: backends/platform/wince/CEActionsPocket.cpp:45
#: backends/platform/wince/CEActionsSmartphone.cpp:46
msgid "Skip"
msgstr ""
-#: base/main.cpp:277 backends/platform/symbian/src/SymbianActions.cpp:50
+#: base/main.cpp:281 backends/platform/symbian/src/SymbianActions.cpp:50
#: backends/platform/wince/CEActionsPocket.cpp:42
msgid "Pause"
msgstr ""
-#: base/main.cpp:280
+#: base/main.cpp:284
msgid "Skip line"
msgstr ""
-#: base/main.cpp:439
+#: base/main.cpp:455
msgid "Error running game:"
msgstr ""
-#: base/main.cpp:463
+#: base/main.cpp:479
msgid "Could not find any engine capable of running the selected game"
msgstr ""
@@ -1066,25 +1072,6 @@ msgstr ""
msgid "Unknown error"
msgstr ""
-#. I18N: Hercules is graphics card name
-#: common/util.cpp:275
-msgid "Hercules Green"
-msgstr ""
-
-#: common/util.cpp:276
-msgid "Hercules Amber"
-msgstr ""
-
-#: common/util.cpp:283
-msgctxt "lowres"
-msgid "Hercules Green"
-msgstr ""
-
-#: common/util.cpp:284
-msgctxt "lowres"
-msgid "Hercules Amber"
-msgstr ""
-
#: engines/advancedDetector.cpp:296
#, c-format
msgid "The game in '%s' seems to be unknown."
@@ -1132,12 +1119,12 @@ msgid "~R~eturn to Launcher"
msgstr ""
#: engines/dialogs.cpp:116 engines/cruise/menu.cpp:214
-#: engines/sci/engine/kfile.cpp:578
+#: engines/sci/engine/kfile.cpp:566
msgid "Save game:"
msgstr ""
#: engines/dialogs.cpp:116 engines/scumm/dialogs.cpp:187
-#: engines/cruise/menu.cpp:214 engines/sci/engine/kfile.cpp:578
+#: engines/cruise/menu.cpp:214 engines/sci/engine/kfile.cpp:566
#: backends/platform/symbian/src/SymbianActions.cpp:44
#: backends/platform/wince/CEActionsPocket.cpp:43
#: backends/platform/wince/CEActionsPocket.cpp:267
@@ -1153,37 +1140,44 @@ msgid ""
"further assistance."
msgstr ""
-#: engines/dialogs.cpp:316 engines/mohawk/dialogs.cpp:109
+#: engines/dialogs.cpp:243
+#, c-format
+msgid ""
+"Gamestate save failed (%s)! Please consult the README for basic information, "
+"and for instructions on how to obtain further assistance."
+msgstr ""
+
+#: engines/dialogs.cpp:321 engines/mohawk/dialogs.cpp:109
#: engines/mohawk/dialogs.cpp:174
msgid "~O~K"
msgstr ""
-#: engines/dialogs.cpp:317 engines/mohawk/dialogs.cpp:110
+#: engines/dialogs.cpp:322 engines/mohawk/dialogs.cpp:110
#: engines/mohawk/dialogs.cpp:175
msgid "~C~ancel"
msgstr ""
-#: engines/dialogs.cpp:320
+#: engines/dialogs.cpp:325
msgid "~K~eys"
msgstr ""
-#: engines/engine.cpp:233
+#: engines/engine.cpp:235
msgid "Could not initialize color format."
msgstr ""
-#: engines/engine.cpp:241
+#: engines/engine.cpp:243
msgid "Could not switch to video mode: '"
msgstr ""
-#: engines/engine.cpp:250
+#: engines/engine.cpp:252
msgid "Could not apply aspect ratio setting."
msgstr ""
-#: engines/engine.cpp:255
+#: engines/engine.cpp:257
msgid "Could not apply fullscreen setting."
msgstr ""
-#: engines/engine.cpp:355
+#: engines/engine.cpp:357
msgid ""
"You appear to be playing this game directly\n"
"from the CD. This is known to cause problems,\n"
@@ -1192,7 +1186,7 @@ msgid ""
"See the README file for details."
msgstr ""
-#: engines/engine.cpp:366
+#: engines/engine.cpp:368
msgid ""
"This game has audio tracks in its disk. These\n"
"tracks need to be ripped from the disk using\n"
@@ -1201,14 +1195,21 @@ msgid ""
"See the README file for details."
msgstr ""
-#: engines/engine.cpp:433
+#: engines/engine.cpp:426
+#, c-format
+msgid ""
+"Gamestate load failed (%s)! Please consult the README for basic information, "
+"and for instructions on how to obtain further assistance."
+msgstr ""
+
+#: engines/engine.cpp:439
msgid ""
"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."
msgstr ""
-#: engines/engine.cpp:436
+#: engines/engine.cpp:442
msgid "Start anyway"
msgstr ""
@@ -1252,7 +1253,7 @@ msgstr ""
#: backends/platform/symbian/src/SymbianActions.cpp:52
#: backends/platform/wince/CEActionsPocket.cpp:44
#: backends/platform/wince/CEActionsSmartphone.cpp:52
-#: backends/events/default/default-events.cpp:244
+#: backends/events/default/default-events.cpp:213
msgid "Quit"
msgstr ""
@@ -1326,6 +1327,26 @@ msgctxt "lowres"
msgid "Speech & Subs"
msgstr ""
+#: engines/scumm/dialogs.cpp:653
+msgid "Select a Proficiency Level."
+msgstr ""
+
+#: engines/scumm/dialogs.cpp:655
+msgid "Refer to your Loom(TM) manual for help."
+msgstr ""
+
+#: engines/scumm/dialogs.cpp:658
+msgid "Standard"
+msgstr ""
+
+#: engines/scumm/dialogs.cpp:659
+msgid "Practice"
+msgstr ""
+
+#: engines/scumm/dialogs.cpp:660
+msgid "Expert"
+msgstr ""
+
#: engines/scumm/help.cpp:73
msgid "Common keyboard commands:"
msgstr ""
@@ -1839,14 +1860,14 @@ msgstr ""
msgid "Fly to lower right"
msgstr ""
-#: engines/scumm/scumm.cpp:1774
+#: engines/scumm/scumm.cpp:1773
#, c-format
msgid ""
"Native MIDI support requires the Roland Upgrade from LucasArts,\n"
"but %s is missing. Using AdLib instead."
msgstr ""
-#: engines/scumm/scumm.cpp:2264 engines/agos/saveload.cpp:189
+#: engines/scumm/scumm.cpp:2271 engines/agos/saveload.cpp:189
#, c-format
msgid ""
"Failed to save game state to file:\n"
@@ -1854,7 +1875,7 @@ msgid ""
"%s"
msgstr ""
-#: engines/scumm/scumm.cpp:2271 engines/agos/saveload.cpp:154
+#: engines/scumm/scumm.cpp:2278 engines/agos/saveload.cpp:154
#, c-format
msgid ""
"Failed to load game state from file:\n"
@@ -1862,7 +1883,7 @@ msgid ""
"%s"
msgstr ""
-#: engines/scumm/scumm.cpp:2283 engines/agos/saveload.cpp:197
+#: engines/scumm/scumm.cpp:2290 engines/agos/saveload.cpp:197
#, c-format
msgid ""
"Successfully saved game state in file:\n"
@@ -1870,7 +1891,7 @@ msgid ""
"%s"
msgstr ""
-#: engines/scumm/scumm.cpp:2498
+#: engines/scumm/scumm.cpp:2505
msgid ""
"Usually, Maniac Mansion would start now. But ScummVM doesn't do that yet. To "
"play it, go to 'Add Game' in the ScummVM start menu and select the 'Maniac' "
@@ -1903,11 +1924,11 @@ msgstr ""
msgid "~W~ater Effect Enabled"
msgstr ""
-#: engines/sci/engine/kfile.cpp:685
+#: engines/sci/engine/kfile.cpp:673
msgid "Restore game:"
msgstr ""
-#: engines/sci/engine/kfile.cpp:685
+#: engines/sci/engine/kfile.cpp:673
msgid "Restore"
msgstr ""
@@ -1917,11 +1938,11 @@ msgid "Cutscene file '%s' not found!"
msgstr ""
#: engines/gob/inter_playtoons.cpp:256 engines/gob/inter_v2.cpp:1283
-#: engines/tinsel/saveload.cpp:482
+#: engines/tinsel/saveload.cpp:502
msgid "Failed to load game state from file."
msgstr ""
-#: engines/gob/inter_v2.cpp:1353 engines/tinsel/saveload.cpp:560
+#: engines/gob/inter_v2.cpp:1353 engines/tinsel/saveload.cpp:515
msgid "Failed to save game state to file."
msgstr ""
@@ -1933,6 +1954,54 @@ msgstr ""
msgid "Failed to save game"
msgstr ""
+#: engines/kyra/lol.cpp:478
+msgid "Attack 1"
+msgstr ""
+
+#: engines/kyra/lol.cpp:479
+msgid "Attack 2"
+msgstr ""
+
+#: engines/kyra/lol.cpp:480
+msgid "Attack 3"
+msgstr ""
+
+#: engines/kyra/lol.cpp:481
+msgid "Move Forward"
+msgstr ""
+
+#: engines/kyra/lol.cpp:482
+msgid "Move Back"
+msgstr ""
+
+#: engines/kyra/lol.cpp:483
+msgid "Slide Left"
+msgstr ""
+
+#: engines/kyra/lol.cpp:484
+msgid "Slide Right"
+msgstr ""
+
+#: engines/kyra/lol.cpp:485
+msgid "Turn Left"
+msgstr ""
+
+#: engines/kyra/lol.cpp:486
+msgid "Turn Right"
+msgstr ""
+
+#: engines/kyra/lol.cpp:487
+msgid "Rest"
+msgstr ""
+
+#: engines/kyra/lol.cpp:488
+msgid "Options"
+msgstr ""
+
+#: engines/kyra/lol.cpp:489
+msgid "Choose Spell"
+msgstr ""
+
#: engines/kyra/sound_midi.cpp:475
msgid ""
"You appear to be using a General MIDI device,\n"
@@ -1942,10 +2011,6 @@ msgid ""
"that a few tracks will not be correctly played."
msgstr ""
-#: engines/m4/m4_menus.cpp:138
-msgid "Save game failed!"
-msgstr ""
-
#: engines/sky/compact.cpp:130
msgid ""
"Unable to find \"sky.cpt\" file!\n"
@@ -1958,15 +2023,20 @@ msgid ""
"Please (re)download it from www.scummvm.org"
msgstr ""
-#: engines/sword1/animation.cpp:344 engines/sword2/animation.cpp:379
+#: engines/sword1/animation.cpp:539
+#, c-format
+msgid "PSX stream cutscene '%s' cannot be played in paletted mode"
+msgstr ""
+
+#: engines/sword1/animation.cpp:560 engines/sword2/animation.cpp:455
msgid "DXA cutscenes found but ScummVM has been built without zlib support"
msgstr ""
-#: engines/sword1/animation.cpp:354 engines/sword2/animation.cpp:389
+#: engines/sword1/animation.cpp:570 engines/sword2/animation.cpp:465
msgid "MPEG2 cutscenes are no longer supported"
msgstr ""
-#: engines/sword1/animation.cpp:359 engines/sword2/animation.cpp:397
+#: engines/sword1/animation.cpp:576 engines/sword2/animation.cpp:473
#, c-format
msgid "Cutscene '%s' not found"
msgstr ""
@@ -2001,6 +2071,11 @@ msgstr ""
msgid "This is the end of the Broken Sword 1 Demo"
msgstr ""
+#: engines/sword2/animation.cpp:435
+msgid ""
+"PSX cutscenes found but ScummVM has been built without RGB color support"
+msgstr ""
+
#: engines/parallaction/saveload.cpp:133
#, c-format
msgid ""
@@ -2046,33 +2121,33 @@ msgstr ""
msgid "DOSBox OPL emulator"
msgstr ""
-#: audio/mididrv.cpp:205
+#: audio/mididrv.cpp:209
#, c-format
msgid ""
"The selected audio device '%s' was not found (e.g. might be turned off or "
"disconnected)."
msgstr ""
-#: audio/mididrv.cpp:205 audio/mididrv.cpp:217 audio/mididrv.cpp:253
-#: audio/mididrv.cpp:268
+#: audio/mididrv.cpp:209 audio/mididrv.cpp:221 audio/mididrv.cpp:257
+#: audio/mididrv.cpp:272
msgid "Attempting to fall back to the next available device..."
msgstr ""
-#: audio/mididrv.cpp:217
+#: audio/mididrv.cpp:221
#, c-format
msgid ""
"The selected audio device '%s' cannot be used. See log file for more "
"information."
msgstr ""
-#: audio/mididrv.cpp:253
+#: audio/mididrv.cpp:257
#, c-format
msgid ""
"The preferred audio device '%s' was not found (e.g. might be turned off or "
"disconnected)."
msgstr ""
-#: audio/mididrv.cpp:268
+#: audio/mididrv.cpp:272
#, c-format
msgid ""
"The preferred audio device '%s' cannot be used. See log file for more "
@@ -2087,7 +2162,7 @@ msgstr ""
msgid "Amiga Audio Emulator"
msgstr ""
-#: audio/softsynth/adlib.cpp:1594
+#: audio/softsynth/adlib.cpp:1593
msgid "AdLib Emulator"
msgstr ""
@@ -2099,11 +2174,11 @@ msgstr ""
msgid "C64 Audio Emulator"
msgstr ""
-#: audio/softsynth/mt32.cpp:329
+#: audio/softsynth/mt32.cpp:293
msgid "Initializing MT-32 Emulator"
msgstr ""
-#: audio/softsynth/mt32.cpp:543
+#: audio/softsynth/mt32.cpp:512
msgid "MT-32 Emulator"
msgstr ""
@@ -2119,15 +2194,23 @@ msgstr ""
msgid "Keymap:"
msgstr ""
-#: backends/keymapper/remap-dialog.cpp:64
+#: backends/keymapper/remap-dialog.cpp:66
+msgid " (Effective)"
+msgstr ""
+
+#: backends/keymapper/remap-dialog.cpp:106
msgid " (Active)"
msgstr ""
-#: backends/keymapper/remap-dialog.cpp:98
+#: backends/keymapper/remap-dialog.cpp:106
+msgid " (Blocked)"
+msgstr ""
+
+#: backends/keymapper/remap-dialog.cpp:119
msgid " (Global)"
msgstr ""
-#: backends/keymapper/remap-dialog.cpp:108
+#: backends/keymapper/remap-dialog.cpp:127
msgid " (Game)"
msgstr ""
@@ -2207,40 +2290,63 @@ msgstr ""
msgid "Disable power off"
msgstr ""
-#: backends/platform/iphone/osys_events.cpp:338
+#: backends/platform/iphone/osys_events.cpp:301
msgid "Mouse-click-and-drag mode enabled."
msgstr ""
-#: backends/platform/iphone/osys_events.cpp:340
+#: backends/platform/iphone/osys_events.cpp:303
msgid "Mouse-click-and-drag mode disabled."
msgstr ""
-#: backends/platform/iphone/osys_events.cpp:351
+#: backends/platform/iphone/osys_events.cpp:314
msgid "Touchpad mode enabled."
msgstr ""
-#: backends/platform/iphone/osys_events.cpp:353
+#: backends/platform/iphone/osys_events.cpp:316
msgid "Touchpad mode disabled."
msgstr ""
-#: backends/platform/sdl/macosx/appmenu_osx.mm:67
+#: backends/platform/maemo/maemo.cpp:205
+msgid "Click Mode"
+msgstr ""
+
+#: backends/platform/maemo/maemo.cpp:211
+#: backends/platform/symbian/src/SymbianActions.cpp:42
+#: backends/platform/wince/CEActionsPocket.cpp:60
+#: backends/platform/wince/CEActionsSmartphone.cpp:43
+#: backends/platform/bada/form.cpp:281
+msgid "Left Click"
+msgstr ""
+
+#: backends/platform/maemo/maemo.cpp:214
+msgid "Middle Click"
+msgstr ""
+
+#: backends/platform/maemo/maemo.cpp:217
+#: backends/platform/symbian/src/SymbianActions.cpp:43
+#: backends/platform/wince/CEActionsSmartphone.cpp:44
+#: backends/platform/bada/form.cpp:273
+msgid "Right Click"
+msgstr ""
+
+#: backends/platform/sdl/macosx/appmenu_osx.mm:78
msgid "Hide ScummVM"
msgstr ""
-#: backends/platform/sdl/macosx/appmenu_osx.mm:70
+#: backends/platform/sdl/macosx/appmenu_osx.mm:83
msgid "Hide Others"
msgstr ""
-#: backends/platform/sdl/macosx/appmenu_osx.mm:74
+#: backends/platform/sdl/macosx/appmenu_osx.mm:88
msgid "Show All"
msgstr ""
-#: backends/platform/sdl/macosx/appmenu_osx.mm:92
-#: backends/platform/sdl/macosx/appmenu_osx.mm:99
+#: backends/platform/sdl/macosx/appmenu_osx.mm:110
+#: backends/platform/sdl/macosx/appmenu_osx.mm:121
msgid "Window"
msgstr ""
-#: backends/platform/sdl/macosx/appmenu_osx.mm:95
+#: backends/platform/sdl/macosx/appmenu_osx.mm:115
msgid "Minimize"
msgstr ""
@@ -2254,12 +2360,12 @@ msgid "Normal (no scaling)"
msgstr ""
#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2147
-#: backends/graphics/openglsdl/openglsdl-graphics.cpp:537
+#: backends/graphics/openglsdl/openglsdl-graphics.cpp:533
msgid "Enabled aspect ratio correction"
msgstr ""
#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2153
-#: backends/graphics/openglsdl/openglsdl-graphics.cpp:542
+#: backends/graphics/openglsdl/openglsdl-graphics.cpp:538
msgid "Disabled aspect ratio correction"
msgstr ""
@@ -2268,7 +2374,7 @@ msgid "Active graphics filter:"
msgstr ""
#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2250
-#: backends/graphics/openglsdl/openglsdl-graphics.cpp:481
+#: backends/graphics/openglsdl/openglsdl-graphics.cpp:477
msgid "Windowed mode"
msgstr ""
@@ -2292,11 +2398,11 @@ msgstr ""
msgid "Current scale"
msgstr ""
-#: backends/graphics/openglsdl/openglsdl-graphics.cpp:562
+#: backends/graphics/openglsdl/openglsdl-graphics.cpp:558
msgid "Active filter mode: Linear"
msgstr ""
-#: backends/graphics/openglsdl/openglsdl-graphics.cpp:564
+#: backends/graphics/openglsdl/openglsdl-graphics.cpp:560
msgid "Active filter mode: Nearest"
msgstr ""
@@ -2320,19 +2426,6 @@ msgstr ""
msgid "Right"
msgstr ""
-#: backends/platform/symbian/src/SymbianActions.cpp:42
-#: backends/platform/wince/CEActionsPocket.cpp:60
-#: backends/platform/wince/CEActionsSmartphone.cpp:43
-#: backends/platform/bada/form.cpp:281
-msgid "Left Click"
-msgstr ""
-
-#: backends/platform/symbian/src/SymbianActions.cpp:43
-#: backends/platform/wince/CEActionsSmartphone.cpp:44
-#: backends/platform/bada/form.cpp:273
-msgid "Right Click"
-msgstr ""
-
#: backends/platform/symbian/src/SymbianActions.cpp:46
#: backends/platform/wince/CEActionsSmartphone.cpp:47
msgid "Zone"
@@ -2617,15 +2710,15 @@ msgid ""
"Don't forget to map a key to 'Hide Toolbar' action to see the whole inventory"
msgstr ""
-#: backends/events/default/default-events.cpp:222
+#: backends/events/default/default-events.cpp:191
msgid "Do you really want to return to the Launcher?"
msgstr ""
-#: backends/events/default/default-events.cpp:222
+#: backends/events/default/default-events.cpp:191
msgid "Launcher"
msgstr ""
-#: backends/events/default/default-events.cpp:244
+#: backends/events/default/default-events.cpp:213
msgid "Do you really want to quit?"
msgstr ""
@@ -2691,10 +2784,10 @@ msgstr ""
msgid "Control Mouse"
msgstr ""
-#: backends/events/maemosdl/maemosdl-events.cpp:121
+#: backends/events/maemosdl/maemosdl-events.cpp:192
msgid "Clicking Enabled"
msgstr ""
-#: backends/events/maemosdl/maemosdl-events.cpp:121
+#: backends/events/maemosdl/maemosdl-events.cpp:192
msgid "Clicking Disabled"
msgstr ""
diff --git a/po/se_SE.po b/po/se_SE.po
index d4ce073feb..812852ca53 100644
--- a/po/se_SE.po
+++ b/po/se_SE.po
@@ -1,20 +1,20 @@
-# Swedish translation for ScummVM.
-# Copyright (C) 2011 ScummVM Team
-# This file is distributed under the same license as the ScummVM package.
-# Hampus Flink <hampus.flink@gmail.com>, 2011.
-#
+# Swedish translation for ScummVM.
+# Copyright (C) 2011-2012 ScummVM Team
+# This file is distributed under the same license as the ScummVM package.
+# Hampus Flink <hampus.flink@gmail.com>, 2011.
+#
msgid ""
msgstr ""
"Project-Id-Version: ScummVM 1.3.0svn\n"
"Report-Msgid-Bugs-To: scummvm-devel@lists.sf.net\n"
-"POT-Creation-Date: 2011-10-19 13:42+0100\n"
-"PO-Revision-Date: 2011-05-02 13:07+0100\n"
+"POT-Creation-Date: 2012-03-07 22:09+0000\n"
+"PO-Revision-Date: 2011-11-27 19:00+0100\n"
"Last-Translator: Hampus Flink <hampus.flink@gmail.com>\n"
"Language-Team: \n"
-"Language: Svenska\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=iso-8859-1\n"
"Content-Transfer-Encoding: 8bit\n"
+"Language: Svenska\n"
"Plural-Forms: nplurals=2; plural=(n != 1)\n"
"X-Poedit-Language: Swedish\n"
"X-Poedit-Country: SWEDEN\n"
@@ -23,10 +23,9 @@ msgstr ""
#: gui/about.cpp:91
#, c-format
msgid "(built on %s)"
-msgstr "(byggt på %s)"
+msgstr "(byggt %s)"
#: gui/about.cpp:98
-#, fuzzy
msgid "Features compiled in:"
msgstr "Funktioner kompilerade i:"
@@ -48,13 +47,13 @@ msgid "Go up"
msgstr "Uppåt"
#: gui/browser.cpp:69 gui/chooser.cpp:45 gui/KeysDialog.cpp:43
-#: gui/launcher.cpp:312 gui/massadd.cpp:94 gui/options.cpp:1178
+#: gui/launcher.cpp:320 gui/massadd.cpp:94 gui/options.cpp:1253
#: gui/saveload.cpp:63 gui/saveload.cpp:155 gui/themebrowser.cpp:54
-#: engines/engine.cpp:436 engines/scumm/dialogs.cpp:190
+#: engines/engine.cpp:442 engines/scumm/dialogs.cpp:190
#: engines/sword1/control.cpp:865 engines/parallaction/saveload.cpp:281
#: backends/platform/wii/options.cpp:48
-#: backends/events/default/default-events.cpp:222
-#: backends/events/default/default-events.cpp:244
+#: backends/events/default/default-events.cpp:191
+#: backends/events/default/default-events.cpp:213
msgid "Cancel"
msgstr "Avbryt"
@@ -62,25 +61,30 @@ msgstr "Avbryt"
msgid "Choose"
msgstr "Välj"
-#: gui/gui-manager.cpp:116 engines/scumm/help.cpp:125
+#: gui/gui-manager.cpp:115 engines/scumm/help.cpp:125
#: engines/scumm/help.cpp:140 engines/scumm/help.cpp:165
#: engines/scumm/help.cpp:191 engines/scumm/help.cpp:209
#: backends/keymapper/remap-dialog.cpp:52
msgid "Close"
msgstr "Stäng"
-#: gui/gui-manager.cpp:119
+#: gui/gui-manager.cpp:118
msgid "Mouse click"
msgstr "Musklick"
-#: gui/gui-manager.cpp:122 base/main.cpp:283
+#: gui/gui-manager.cpp:122 base/main.cpp:288
msgid "Display keyboard"
msgstr "Visa tangentbord"
-#: gui/gui-manager.cpp:125 base/main.cpp:286
+#: gui/gui-manager.cpp:126 base/main.cpp:292
msgid "Remap keys"
msgstr "Ställ in tangenter"
+#: gui/gui-manager.cpp:129 base/main.cpp:295
+#, fuzzy
+msgid "Toggle FullScreen"
+msgstr "Fullskärmsläge"
+
#: gui/KeysDialog.h:36 gui/KeysDialog.cpp:145
msgid "Choose an action to map"
msgstr "Välj en handling att ställa in"
@@ -89,16 +93,17 @@ msgstr "Välj en handling att ställa in"
msgid "Map"
msgstr "Ställ in"
-#: gui/KeysDialog.cpp:42 gui/launcher.cpp:313 gui/launcher.cpp:936
-#: gui/launcher.cpp:940 gui/massadd.cpp:91 gui/options.cpp:1179
-#: engines/engine.cpp:359 engines/engine.cpp:370 engines/scumm/dialogs.cpp:192
-#: engines/scumm/scumm.cpp:1776 engines/agos/animation.cpp:551
+#: gui/KeysDialog.cpp:42 gui/launcher.cpp:321 gui/launcher.cpp:960
+#: gui/launcher.cpp:964 gui/massadd.cpp:91 gui/options.cpp:1254
+#: engines/engine.cpp:361 engines/engine.cpp:372 engines/scumm/dialogs.cpp:192
+#: engines/scumm/scumm.cpp:1775 engines/agos/animation.cpp:551
#: engines/groovie/script.cpp:420 engines/sky/compact.cpp:131
-#: engines/sky/compact.cpp:141 engines/sword1/animation.cpp:344
-#: engines/sword1/animation.cpp:354 engines/sword1/animation.cpp:360
-#: engines/sword1/control.cpp:865 engines/sword1/logic.cpp:1633
-#: engines/sword2/animation.cpp:379 engines/sword2/animation.cpp:389
-#: engines/sword2/animation.cpp:398 engines/parallaction/saveload.cpp:281
+#: engines/sky/compact.cpp:141 engines/sword1/animation.cpp:539
+#: engines/sword1/animation.cpp:560 engines/sword1/animation.cpp:570
+#: engines/sword1/animation.cpp:577 engines/sword1/control.cpp:865
+#: engines/sword1/logic.cpp:1633 engines/sword2/animation.cpp:435
+#: engines/sword2/animation.cpp:455 engines/sword2/animation.cpp:465
+#: engines/sword2/animation.cpp:474 engines/parallaction/saveload.cpp:281
#: backends/platform/wii/options.cpp:47
#: backends/platform/wince/CELauncherDialog.cpp:54
msgid "OK"
@@ -126,15 +131,15 @@ msgstr "Var god välj en handling"
msgid "Press the key to associate"
msgstr "Tryck på en tangent för att ställa in"
-#: gui/launcher.cpp:165
+#: gui/launcher.cpp:170
msgid "Game"
msgstr "Spel"
-#: gui/launcher.cpp:169
+#: gui/launcher.cpp:174
msgid "ID:"
msgstr "ID:"
-#: gui/launcher.cpp:169 gui/launcher.cpp:171 gui/launcher.cpp:172
+#: gui/launcher.cpp:174 gui/launcher.cpp:176 gui/launcher.cpp:177
msgid ""
"Short game identifier used for referring to savegames and running the game "
"from the command line"
@@ -142,29 +147,29 @@ msgstr ""
"Kortnamn för spel. Används för att hänvisa till spardata och att starta "
"spelet från kommandoraden"
-#: gui/launcher.cpp:171
+#: gui/launcher.cpp:176
msgctxt "lowres"
msgid "ID:"
msgstr "ID:"
-#: gui/launcher.cpp:176
+#: gui/launcher.cpp:181
msgid "Name:"
msgstr "Namn:"
-#: gui/launcher.cpp:176 gui/launcher.cpp:178 gui/launcher.cpp:179
+#: gui/launcher.cpp:181 gui/launcher.cpp:183 gui/launcher.cpp:184
msgid "Full title of the game"
msgstr "Spelets fullständiga titel"
-#: gui/launcher.cpp:178
+#: gui/launcher.cpp:183
msgctxt "lowres"
msgid "Name:"
msgstr "Namn:"
-#: gui/launcher.cpp:182
+#: gui/launcher.cpp:187
msgid "Language:"
msgstr "Språk:"
-#: gui/launcher.cpp:182 gui/launcher.cpp:183
+#: gui/launcher.cpp:187 gui/launcher.cpp:188
msgid ""
"Language of the game. This will not turn your Spanish game version into "
"English"
@@ -172,282 +177,280 @@ msgstr ""
"Spelets språk. Den här inställningen omvandlar inte din spanska spelversion "
"till en engelsk"
-#: gui/launcher.cpp:184 gui/launcher.cpp:198 gui/options.cpp:74
-#: gui/options.cpp:708 gui/options.cpp:718 gui/options.cpp:1149
+#: gui/launcher.cpp:189 gui/launcher.cpp:203 gui/options.cpp:80
+#: gui/options.cpp:745 gui/options.cpp:758 gui/options.cpp:1224
#: audio/null.cpp:40
msgid "<default>"
msgstr "<standard>"
-#: gui/launcher.cpp:194
+#: gui/launcher.cpp:199
msgid "Platform:"
msgstr "Plattform:"
-#: gui/launcher.cpp:194 gui/launcher.cpp:196 gui/launcher.cpp:197
+#: gui/launcher.cpp:199 gui/launcher.cpp:201 gui/launcher.cpp:202
msgid "Platform the game was originally designed for"
msgstr "Plattformen spelet ursprungligen tillverkades för"
-#: gui/launcher.cpp:196
+#: gui/launcher.cpp:201
msgctxt "lowres"
msgid "Platform:"
msgstr "Plattform:"
-#: gui/launcher.cpp:208 gui/options.cpp:1018 gui/options.cpp:1035
+#: gui/launcher.cpp:213 gui/options.cpp:1087 gui/options.cpp:1104
msgid "Graphics"
msgstr "Grafik"
-#: gui/launcher.cpp:208 gui/options.cpp:1018 gui/options.cpp:1035
+#: gui/launcher.cpp:213 gui/options.cpp:1087 gui/options.cpp:1104
msgid "GFX"
msgstr "GFX"
-#: gui/launcher.cpp:211
+#: gui/launcher.cpp:216
msgid "Override global graphic settings"
msgstr "Överskrid globala grafikinställningar"
-#: gui/launcher.cpp:213
+#: gui/launcher.cpp:218
msgctxt "lowres"
msgid "Override global graphic settings"
msgstr "Överskrid globala grafikinställningar"
-#: gui/launcher.cpp:220 gui/options.cpp:1041
+#: gui/launcher.cpp:225 gui/options.cpp:1110
msgid "Audio"
msgstr "Ljud"
-#: gui/launcher.cpp:223
+#: gui/launcher.cpp:228
msgid "Override global audio settings"
msgstr "Överskrid globala ljudinställningar"
-#: gui/launcher.cpp:225
+#: gui/launcher.cpp:230
msgctxt "lowres"
msgid "Override global audio settings"
msgstr "Överskrid globala ljudinställningar"
-#: gui/launcher.cpp:234 gui/options.cpp:1046
+#: gui/launcher.cpp:239 gui/options.cpp:1115
msgid "Volume"
msgstr "Volym"
-#: gui/launcher.cpp:236 gui/options.cpp:1048
+#: gui/launcher.cpp:241 gui/options.cpp:1117
msgctxt "lowres"
msgid "Volume"
msgstr "Volym"
-#: gui/launcher.cpp:239
+#: gui/launcher.cpp:244
msgid "Override global volume settings"
msgstr "Överskrid globala volyminställningar"
-#: gui/launcher.cpp:241
+#: gui/launcher.cpp:246
msgctxt "lowres"
msgid "Override global volume settings"
msgstr "Överskrid globala volyminställningar"
-#: gui/launcher.cpp:248 gui/options.cpp:1056
+#: gui/launcher.cpp:254 gui/options.cpp:1125
msgid "MIDI"
msgstr "MIDI"
-#: gui/launcher.cpp:251
+#: gui/launcher.cpp:257
msgid "Override global MIDI settings"
msgstr "Överskrid globala MIDI-inställningar"
-#: gui/launcher.cpp:253
+#: gui/launcher.cpp:259
msgctxt "lowres"
msgid "Override global MIDI settings"
msgstr "Överskrid globala MIDI-inställningar"
-#: gui/launcher.cpp:263 gui/options.cpp:1062
+#: gui/launcher.cpp:268 gui/options.cpp:1131
msgid "MT-32"
msgstr "MT-32"
-#: gui/launcher.cpp:266
+#: gui/launcher.cpp:271
msgid "Override global MT-32 settings"
msgstr "Överskrid globala MT-32 inställningar"
-#: gui/launcher.cpp:268
+#: gui/launcher.cpp:273
msgctxt "lowres"
msgid "Override global MT-32 settings"
msgstr "Överskrid globala MT-32 inställningar"
-#: gui/launcher.cpp:279 gui/options.cpp:1069
+#: gui/launcher.cpp:282 gui/options.cpp:1138
msgid "Paths"
msgstr "Sökvägar"
-#: gui/launcher.cpp:281 gui/options.cpp:1071
+#: gui/launcher.cpp:284 gui/options.cpp:1140
msgctxt "lowres"
msgid "Paths"
msgstr "Sökvägar"
-#: gui/launcher.cpp:288
+#: gui/launcher.cpp:291
msgid "Game Path:"
msgstr "Sökv. spel:"
-#: gui/launcher.cpp:290
+#: gui/launcher.cpp:293
msgctxt "lowres"
msgid "Game Path:"
msgstr "Sökv. spel:"
-#: gui/launcher.cpp:295 gui/options.cpp:1091
+#: gui/launcher.cpp:298 gui/options.cpp:1164
msgid "Extra Path:"
msgstr "Sökv. extra:"
-#: gui/launcher.cpp:295 gui/launcher.cpp:297 gui/launcher.cpp:298
+#: gui/launcher.cpp:298 gui/launcher.cpp:300 gui/launcher.cpp:301
msgid "Specifies path to additional data used the game"
msgstr "Bestämmer sökvägen till ytterligare data som spelet använder"
-#: gui/launcher.cpp:297 gui/options.cpp:1093
+#: gui/launcher.cpp:300 gui/options.cpp:1166
msgctxt "lowres"
msgid "Extra Path:"
msgstr "Sökv. extra:"
-#: gui/launcher.cpp:302 gui/options.cpp:1079
+#: gui/launcher.cpp:307 gui/options.cpp:1148
msgid "Save Path:"
msgstr "Sökv. sparat:"
-#: gui/launcher.cpp:302 gui/launcher.cpp:304 gui/launcher.cpp:305
-#: gui/options.cpp:1079 gui/options.cpp:1081 gui/options.cpp:1082
+#: gui/launcher.cpp:307 gui/launcher.cpp:309 gui/launcher.cpp:310
+#: gui/options.cpp:1148 gui/options.cpp:1150 gui/options.cpp:1151
msgid "Specifies where your savegames are put"
msgstr "Bestämmer var dina spardata lagras"
-#: gui/launcher.cpp:304 gui/options.cpp:1081
+#: gui/launcher.cpp:309 gui/options.cpp:1150
msgctxt "lowres"
msgid "Save Path:"
msgstr "Sökv. sparat:"
-#: gui/launcher.cpp:321 gui/launcher.cpp:404 gui/launcher.cpp:453
-#: gui/options.cpp:1088 gui/options.cpp:1094 gui/options.cpp:1101
-#: gui/options.cpp:1202 gui/options.cpp:1208 gui/options.cpp:1214
-#: gui/options.cpp:1222 gui/options.cpp:1246 gui/options.cpp:1250
-#: gui/options.cpp:1256 gui/options.cpp:1263 gui/options.cpp:1362
+#: gui/launcher.cpp:329 gui/launcher.cpp:416 gui/launcher.cpp:469
+#: gui/launcher.cpp:523 gui/options.cpp:1159 gui/options.cpp:1167
+#: gui/options.cpp:1176 gui/options.cpp:1283 gui/options.cpp:1289
+#: gui/options.cpp:1297 gui/options.cpp:1327 gui/options.cpp:1333
+#: gui/options.cpp:1340 gui/options.cpp:1433 gui/options.cpp:1436
+#: gui/options.cpp:1448
msgctxt "path"
msgid "None"
msgstr "Ingen"
-#: gui/launcher.cpp:326 gui/launcher.cpp:408
+#: gui/launcher.cpp:334 gui/launcher.cpp:422 gui/launcher.cpp:527
+#: gui/options.cpp:1277 gui/options.cpp:1321 gui/options.cpp:1439
#: backends/platform/wii/options.cpp:56
msgid "Default"
msgstr "Standard"
-#: gui/launcher.cpp:446 gui/options.cpp:1356
+#: gui/launcher.cpp:462 gui/options.cpp:1442
msgid "Select SoundFont"
msgstr "Välj SoundFont"
-#: gui/launcher.cpp:465 gui/launcher.cpp:612
+#: gui/launcher.cpp:481 gui/launcher.cpp:636
msgid "Select directory with game data"
msgstr "Välj katalog med speldata"
-#: gui/launcher.cpp:483
+#: gui/launcher.cpp:499
msgid "Select additional game directory"
msgstr "Välj en ytterligare spelkatalog"
-#: gui/launcher.cpp:495
+#: gui/launcher.cpp:511
msgid "Select directory for saved games"
msgstr "Välj katalog för spardata"
-#: gui/launcher.cpp:514
+#: gui/launcher.cpp:538
msgid "This game ID is already taken. Please choose another one."
msgstr "Detta ID-namn är upptaget. Var god välj ett annat."
-#: gui/launcher.cpp:555 engines/dialogs.cpp:110
+#: gui/launcher.cpp:579 engines/dialogs.cpp:110
msgid "~Q~uit"
msgstr "~A~vsluta"
-#: gui/launcher.cpp:555 backends/platform/sdl/macosx/appmenu_osx.mm:80
+#: gui/launcher.cpp:579 backends/platform/sdl/macosx/appmenu_osx.mm:96
msgid "Quit ScummVM"
msgstr "Avsluta ScummVM"
-#: gui/launcher.cpp:556
+#: gui/launcher.cpp:580
msgid "A~b~out..."
msgstr "O~m~..."
-#: gui/launcher.cpp:556 backends/platform/sdl/macosx/appmenu_osx.mm:61
+#: gui/launcher.cpp:580 backends/platform/sdl/macosx/appmenu_osx.mm:70
msgid "About ScummVM"
msgstr "Om ScummVM"
-#: gui/launcher.cpp:557
+#: gui/launcher.cpp:581
msgid "~O~ptions..."
msgstr "~I~nställningar..."
-#: gui/launcher.cpp:557
+#: gui/launcher.cpp:581
msgid "Change global ScummVM options"
msgstr "Redigera globala ScummVM-inställningar"
-#: gui/launcher.cpp:559
+#: gui/launcher.cpp:583
msgid "~S~tart"
msgstr "~S~tarta"
-#: gui/launcher.cpp:559
+#: gui/launcher.cpp:583
msgid "Start selected game"
msgstr "Starta det valda spelet"
-#: gui/launcher.cpp:562
+#: gui/launcher.cpp:586
msgid "~L~oad..."
msgstr "~L~adda..."
-#: gui/launcher.cpp:562
+#: gui/launcher.cpp:586
msgid "Load savegame for selected game"
msgstr "Ladda spardata för det valda spelet"
-#: gui/launcher.cpp:567 gui/launcher.cpp:1055
+#: gui/launcher.cpp:591 gui/launcher.cpp:1079
msgid "~A~dd Game..."
msgstr "Lä~g~g till spel..."
-#: gui/launcher.cpp:567 gui/launcher.cpp:574
+#: gui/launcher.cpp:591 gui/launcher.cpp:598
msgid "Hold Shift for Mass Add"
msgstr "Håll ned Skift för masstillägg"
-#: gui/launcher.cpp:569
+#: gui/launcher.cpp:593
msgid "~E~dit Game..."
msgstr "R~e~digera spel..."
-#: gui/launcher.cpp:569 gui/launcher.cpp:576
+#: gui/launcher.cpp:593 gui/launcher.cpp:600
msgid "Change game options"
msgstr "Redigera spelinställningarna"
-#: gui/launcher.cpp:571
+#: gui/launcher.cpp:595
msgid "~R~emove Game"
msgstr "~R~adera spel"
-#: gui/launcher.cpp:571 gui/launcher.cpp:578
+#: gui/launcher.cpp:595 gui/launcher.cpp:602
msgid "Remove game from the list. The game data files stay intact"
msgstr "Radera spelet från listan. Spelets datafiler påverkas inte."
-#: gui/launcher.cpp:574 gui/launcher.cpp:1055
+#: gui/launcher.cpp:598 gui/launcher.cpp:1079
msgctxt "lowres"
msgid "~A~dd Game..."
msgstr "Lä~g~g till spel..."
-#: gui/launcher.cpp:576
+#: gui/launcher.cpp:600
msgctxt "lowres"
msgid "~E~dit Game..."
msgstr "R~e~digera spel..."
-#: gui/launcher.cpp:578
+#: gui/launcher.cpp:602
msgctxt "lowres"
msgid "~R~emove Game"
msgstr "~R~adera spel"
-#: gui/launcher.cpp:586
+#: gui/launcher.cpp:610
msgid "Search in game list"
msgstr "Sök i spellistan"
-#: gui/launcher.cpp:590 gui/launcher.cpp:1102
+#: gui/launcher.cpp:614 gui/launcher.cpp:1126
msgid "Search:"
msgstr "Sök:"
-#: gui/launcher.cpp:593 gui/options.cpp:826
-msgid "Clear value"
-msgstr "Töm sökfältet"
-
-#: gui/launcher.cpp:615 engines/dialogs.cpp:114 engines/mohawk/myst.cpp:255
+#: gui/launcher.cpp:639 engines/dialogs.cpp:114 engines/mohawk/myst.cpp:255
#: engines/mohawk/riven.cpp:716 engines/cruise/menu.cpp:216
msgid "Load game:"
msgstr "Ladda spel:"
-#: gui/launcher.cpp:615 engines/dialogs.cpp:114 engines/scumm/dialogs.cpp:188
+#: gui/launcher.cpp:639 engines/dialogs.cpp:114 engines/scumm/dialogs.cpp:188
#: engines/mohawk/myst.cpp:255 engines/mohawk/riven.cpp:716
#: engines/cruise/menu.cpp:216 backends/platform/wince/CEActionsPocket.cpp:267
#: backends/platform/wince/CEActionsSmartphone.cpp:231
msgid "Load"
msgstr "Ladda"
-#: gui/launcher.cpp:723
+#: gui/launcher.cpp:747
msgid ""
"Do you really want to run the mass game detector? This could potentially add "
"a huge number of games."
@@ -455,7 +458,7 @@ msgstr ""
"Vill du verkligen använda mass-speldetektorn? Processen kan potentiellt "
"lägga till ett enormt antal spel."
-#: gui/launcher.cpp:724 gui/launcher.cpp:872
+#: gui/launcher.cpp:748 gui/launcher.cpp:896
#: backends/events/symbiansdl/symbiansdl-events.cpp:184
#: backends/platform/wince/CEActionsPocket.cpp:326
#: backends/platform/wince/CEActionsSmartphone.cpp:287
@@ -463,7 +466,7 @@ msgstr ""
msgid "Yes"
msgstr "Ja"
-#: gui/launcher.cpp:724 gui/launcher.cpp:872
+#: gui/launcher.cpp:748 gui/launcher.cpp:896
#: backends/events/symbiansdl/symbiansdl-events.cpp:184
#: backends/platform/wince/CEActionsPocket.cpp:326
#: backends/platform/wince/CEActionsSmartphone.cpp:287
@@ -471,37 +474,37 @@ msgstr "Ja"
msgid "No"
msgstr "Nej"
-#: gui/launcher.cpp:772
+#: gui/launcher.cpp:796
msgid "ScummVM couldn't open the specified directory!"
msgstr "ScummVM kunde inte öppna den valda katalogen!"
-#: gui/launcher.cpp:784
+#: gui/launcher.cpp:808
msgid "ScummVM could not find any game in the specified directory!"
msgstr "ScummVM kunde inte hitta några spel i den valda katalogen!"
-#: gui/launcher.cpp:798
+#: gui/launcher.cpp:822
msgid "Pick the game:"
msgstr "Välj spel:"
-#: gui/launcher.cpp:872
+#: gui/launcher.cpp:896
msgid "Do you really want to remove this game configuration?"
msgstr "Vill du verkligen radera den här spelkonfigurationen?"
-#: gui/launcher.cpp:936
+#: gui/launcher.cpp:960
msgid "This game does not support loading games from the launcher."
msgstr "Det här spelet stöder inte laddning av spardata från launchern."
-#: gui/launcher.cpp:940
+#: gui/launcher.cpp:964
msgid "ScummVM could not find any engine capable of running the selected game!"
msgstr ""
"ScummVM kunde inte hitta en motor kapabel till att köra det valda spelet!"
-#: gui/launcher.cpp:1054
+#: gui/launcher.cpp:1078
msgctxt "lowres"
msgid "Mass Add..."
msgstr "Masstillägg..."
-#: gui/launcher.cpp:1054
+#: gui/launcher.cpp:1078
msgid "Mass Add..."
msgstr "Masstillägg..."
@@ -516,7 +519,7 @@ msgstr "Scanning färdig!"
#: gui/massadd.cpp:261
#, c-format
msgid "Discovered %d new games, ignored %d previously added games."
-msgstr ""
+msgstr "Upptäckte %n nya spel. Ignorerade %d tidigare tillagda spel."
#: gui/massadd.cpp:265
#, c-format
@@ -524,145 +527,145 @@ msgid "Scanned %d directories ..."
msgstr "Kataloger scannade: %d ..."
#: gui/massadd.cpp:268
-#, fuzzy, c-format
+#, c-format
msgid "Discovered %d new games, ignored %d previously added games ..."
-msgstr "Nya spel upptäckta: %d ..."
+msgstr "Upptäckte %d nya spel, ignorerade %d tidigare tillagda spel ..."
-#: gui/options.cpp:72
+#: gui/options.cpp:78
msgid "Never"
msgstr "Aldrig"
-#: gui/options.cpp:72
+#: gui/options.cpp:78
msgid "every 5 mins"
msgstr "var 5:e minut"
-#: gui/options.cpp:72
+#: gui/options.cpp:78
msgid "every 10 mins"
msgstr "var 10:e minut"
-#: gui/options.cpp:72
+#: gui/options.cpp:78
msgid "every 15 mins"
msgstr "var 15:e minut"
-#: gui/options.cpp:72
+#: gui/options.cpp:78
msgid "every 30 mins"
msgstr "var 30:e minut"
-#: gui/options.cpp:74
+#: gui/options.cpp:80
msgid "8 kHz"
msgstr "8 kHz"
-#: gui/options.cpp:74
+#: gui/options.cpp:80
msgid "11kHz"
msgstr "11 kHz"
-#: gui/options.cpp:74
+#: gui/options.cpp:80
msgid "22 kHz"
msgstr "22 kHz"
-#: gui/options.cpp:74
+#: gui/options.cpp:80
msgid "44 kHz"
msgstr "44 kHz"
-#: gui/options.cpp:74
+#: gui/options.cpp:80
msgid "48 kHz"
msgstr "48 kHz"
-#: gui/options.cpp:236 gui/options.cpp:464 gui/options.cpp:559
-#: gui/options.cpp:625 gui/options.cpp:825
+#: gui/options.cpp:257 gui/options.cpp:485 gui/options.cpp:586
+#: gui/options.cpp:659 gui/options.cpp:868
msgctxt "soundfont"
msgid "None"
msgstr "Ingen"
-#: gui/options.cpp:372
+#: gui/options.cpp:393
msgid "Failed to apply some of the graphic options changes:"
-msgstr ""
+msgstr "Kunde inte verkställa några av grafikinställningarna:"
-#: gui/options.cpp:384
+#: gui/options.cpp:405
msgid "the video mode could not be changed."
-msgstr ""
+msgstr "videoläget kunde inte ändras."
-#: gui/options.cpp:390
+#: gui/options.cpp:411
msgid "the fullscreen setting could not be changed"
-msgstr ""
+msgstr "fullskärmsinställningen kunde inte ändras."
-#: gui/options.cpp:396
+#: gui/options.cpp:417
msgid "the aspect ratio setting could not be changed"
-msgstr ""
+msgstr "inställningen för bildförhållandet kunde inte ändras."
-#: gui/options.cpp:705
+#: gui/options.cpp:742
msgid "Graphics mode:"
msgstr "Grafikläge:"
-#: gui/options.cpp:716
+#: gui/options.cpp:756
msgid "Render mode:"
msgstr "Renderingsläge:"
-#: gui/options.cpp:716 gui/options.cpp:717
+#: gui/options.cpp:756 gui/options.cpp:757
msgid "Special dithering modes supported by some games"
msgstr "Speciella gitterlägen stödda av vissa spel"
-#: gui/options.cpp:726
+#: gui/options.cpp:768
#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2248
-#: backends/graphics/openglsdl/openglsdl-graphics.cpp:476
+#: backends/graphics/openglsdl/openglsdl-graphics.cpp:472
msgid "Fullscreen mode"
msgstr "Fullskärmsläge"
-#: gui/options.cpp:729
+#: gui/options.cpp:771
msgid "Aspect ratio correction"
msgstr "Korrektion av bildförhållande"
-#: gui/options.cpp:729
+#: gui/options.cpp:771
msgid "Correct aspect ratio for 320x200 games"
msgstr "Korrigerar bildförhållanden för 320x200-spel"
-#: gui/options.cpp:730
+#: gui/options.cpp:772
msgid "EGA undithering"
msgstr "EGA anti-gitter"
-#: gui/options.cpp:730
+#: gui/options.cpp:772
msgid "Enable undithering in EGA games that support it"
msgstr "Aktiverar anti-gitter i EGA spel som stöder det"
-#: gui/options.cpp:738
+#: gui/options.cpp:780
msgid "Preferred Device:"
msgstr "Föredragen enhet:"
-#: gui/options.cpp:738
+#: gui/options.cpp:780
msgid "Music Device:"
msgstr "Musikenhet:"
-#: gui/options.cpp:738 gui/options.cpp:740
+#: gui/options.cpp:780 gui/options.cpp:782
msgid "Specifies preferred sound device or sound card emulator"
msgstr "Bestämmer din föredragna emulator för ljudenhet eller ljudkort"
-#: gui/options.cpp:738 gui/options.cpp:740 gui/options.cpp:741
+#: gui/options.cpp:780 gui/options.cpp:782 gui/options.cpp:783
msgid "Specifies output sound device or sound card emulator"
msgstr "Bestämmer emulator för ljudenhet eller ljudkort"
-#: gui/options.cpp:740
+#: gui/options.cpp:782
msgctxt "lowres"
msgid "Preferred Dev.:"
msgstr "Föredr. enhet:"
-#: gui/options.cpp:740
+#: gui/options.cpp:782
msgctxt "lowres"
msgid "Music Device:"
msgstr "Musikenhet:"
-#: gui/options.cpp:766
+#: gui/options.cpp:809
msgid "AdLib emulator:"
msgstr "AdLib-emulator:"
-#: gui/options.cpp:766 gui/options.cpp:767
+#: gui/options.cpp:809 gui/options.cpp:810
msgid "AdLib is used for music in many games"
msgstr "AdLib används för musik i många spel"
-#: gui/options.cpp:777
+#: gui/options.cpp:820
msgid "Output rate:"
msgstr "Ljudfrekvens:"
-#: gui/options.cpp:777 gui/options.cpp:778
+#: gui/options.cpp:820 gui/options.cpp:821
msgid ""
"Higher value specifies better sound quality but may be not supported by your "
"soundcard"
@@ -670,61 +673,61 @@ msgstr ""
"Ett högre värde betecknar bättre ljudkvalitet men stöds kanske inte av ditt "
"ljudkort"
-#: gui/options.cpp:788
+#: gui/options.cpp:831
msgid "GM Device:"
msgstr "GM-enhet:"
-#: gui/options.cpp:788
+#: gui/options.cpp:831
msgid "Specifies default sound device for General MIDI output"
msgstr "Bestämmer standardenheten för General MIDI-uppspelning"
-#: gui/options.cpp:799
+#: gui/options.cpp:842
msgid "Don't use General MIDI music"
msgstr "Använd inte General MIDI-musik"
-#: gui/options.cpp:810 gui/options.cpp:871
+#: gui/options.cpp:853 gui/options.cpp:915
msgid "Use first available device"
msgstr "Använd första tillgängliga enhet"
-#: gui/options.cpp:822
+#: gui/options.cpp:865
msgid "SoundFont:"
msgstr "SoundFont:"
-#: gui/options.cpp:822 gui/options.cpp:824 gui/options.cpp:825
+#: gui/options.cpp:865 gui/options.cpp:867 gui/options.cpp:868
msgid "SoundFont is supported by some audio cards, Fluidsynth and Timidity"
msgstr "SoundFont stöds endast av vissa ljudkort, Fluidsynth och Timidity"
-#: gui/options.cpp:824
+#: gui/options.cpp:867
msgctxt "lowres"
msgid "SoundFont:"
msgstr "SoundFont:"
-#: gui/options.cpp:829
+#: gui/options.cpp:873
msgid "Mixed AdLib/MIDI mode"
msgstr "Blandat AdLib/MIDI-läge"
-#: gui/options.cpp:829
+#: gui/options.cpp:873
msgid "Use both MIDI and AdLib sound generation"
msgstr "Använd både MIDI och AdLib för ljudgeneration"
-#: gui/options.cpp:832
+#: gui/options.cpp:876
msgid "MIDI gain:"
msgstr "MIDI gain:"
-#: gui/options.cpp:842
+#: gui/options.cpp:886
msgid "MT-32 Device:"
msgstr "MT-32 enhet:"
-#: gui/options.cpp:842
+#: gui/options.cpp:886
msgid "Specifies default sound device for Roland MT-32/LAPC1/CM32l/CM64 output"
msgstr ""
"Bestämmer standardenheten för Roland MT-32/LAPC1/CM32I/CM64-uppspelning"
-#: gui/options.cpp:847
+#: gui/options.cpp:891
msgid "True Roland MT-32 (disable GM emulation)"
msgstr "Äkta Roland MT-32 (inaktivera GM-emulation)"
-#: gui/options.cpp:847 gui/options.cpp:849
+#: gui/options.cpp:891 gui/options.cpp:893
msgid ""
"Check if you want to use your real hardware Roland-compatible sound device "
"connected to your computer"
@@ -732,194 +735,193 @@ msgstr ""
"Aktivera om du vill använda din verkliga Roland-kompatibla och dator-"
"anslutna ljudenhet"
-#: gui/options.cpp:849
+#: gui/options.cpp:893
msgctxt "lowres"
msgid "True Roland MT-32 (no GM emulation)"
msgstr "Äkta Roland MT-32 (ingen GM-emulation)"
-#: gui/options.cpp:852
+#: gui/options.cpp:896
msgid "Enable Roland GS Mode"
msgstr "Aktivera Roland GS-läge"
-#: gui/options.cpp:852
+#: gui/options.cpp:896
msgid "Turns off General MIDI mapping for games with Roland MT-32 soundtrack"
msgstr ""
"Stänger av General MIDI-kartläggning för spel med Roland MT-32 soundtrack"
-#: gui/options.cpp:861
+#: gui/options.cpp:905
msgid "Don't use Roland MT-32 music"
msgstr "Använd inte Roland MT-32 musik"
-#: gui/options.cpp:888
+#: gui/options.cpp:932
msgid "Text and Speech:"
msgstr "Undertext och tal:"
-#: gui/options.cpp:892 gui/options.cpp:902
+#: gui/options.cpp:936 gui/options.cpp:946
msgid "Speech"
msgstr "Tal"
-#: gui/options.cpp:893 gui/options.cpp:903
+#: gui/options.cpp:937 gui/options.cpp:947
msgid "Subtitles"
msgstr "Undertexter"
-#: gui/options.cpp:894
+#: gui/options.cpp:938
msgid "Both"
msgstr "Båda"
-#: gui/options.cpp:896
+#: gui/options.cpp:940
msgid "Subtitle speed:"
msgstr "Texthastighet:"
-#: gui/options.cpp:898
+#: gui/options.cpp:942
msgctxt "lowres"
msgid "Text and Speech:"
msgstr "Text och tal:"
-#: gui/options.cpp:902
+#: gui/options.cpp:946
msgid "Spch"
msgstr "Tal"
-#: gui/options.cpp:903
+#: gui/options.cpp:947
msgid "Subs"
msgstr "Text"
-#: gui/options.cpp:904
+#: gui/options.cpp:948
msgctxt "lowres"
msgid "Both"
msgstr "Båda"
-#: gui/options.cpp:904
+#: gui/options.cpp:948
msgid "Show subtitles and play speech"
msgstr "Visa undertexter och spela upp tal"
-#: gui/options.cpp:906
+#: gui/options.cpp:950
msgctxt "lowres"
msgid "Subtitle speed:"
msgstr "Texthastighet:"
-#: gui/options.cpp:922
+#: gui/options.cpp:966
msgid "Music volume:"
msgstr "Musikvolym:"
-#: gui/options.cpp:924
+#: gui/options.cpp:968
msgctxt "lowres"
msgid "Music volume:"
msgstr "Musikvolym:"
-#: gui/options.cpp:931
+#: gui/options.cpp:975
msgid "Mute All"
msgstr "Ljud av"
-#: gui/options.cpp:934
+#: gui/options.cpp:978
msgid "SFX volume:"
msgstr "SFX-volym:"
-#: gui/options.cpp:934 gui/options.cpp:936 gui/options.cpp:937
+#: gui/options.cpp:978 gui/options.cpp:980 gui/options.cpp:981
msgid "Special sound effects volume"
msgstr "Volym för specialeffekter"
-#: gui/options.cpp:936
+#: gui/options.cpp:980
msgctxt "lowres"
msgid "SFX volume:"
msgstr "SFX-volym:"
-#: gui/options.cpp:944
+#: gui/options.cpp:988
msgid "Speech volume:"
msgstr "Talvolym:"
-#: gui/options.cpp:946
+#: gui/options.cpp:990
msgctxt "lowres"
msgid "Speech volume:"
msgstr "Talvolym:"
-#: gui/options.cpp:1085
+#: gui/options.cpp:1156
msgid "Theme Path:"
msgstr "Sökv. tema:"
-#: gui/options.cpp:1087
+#: gui/options.cpp:1158
msgctxt "lowres"
msgid "Theme Path:"
msgstr "Sökv. tema:"
-#: gui/options.cpp:1091 gui/options.cpp:1093 gui/options.cpp:1094
+#: gui/options.cpp:1164 gui/options.cpp:1166 gui/options.cpp:1167
msgid "Specifies path to additional data used by all games or ScummVM"
msgstr ""
"Bestämmer sökväg till andra data som används av alla spel eller ScummVM"
-#: gui/options.cpp:1098
+#: gui/options.cpp:1173
msgid "Plugins Path:"
msgstr "Sökv. tillägg:"
-#: gui/options.cpp:1100
+#: gui/options.cpp:1175
msgctxt "lowres"
msgid "Plugins Path:"
msgstr "Sökv. tillägg:"
-#: gui/options.cpp:1109
+#: gui/options.cpp:1184
msgid "Misc"
msgstr "Diverse"
-#: gui/options.cpp:1111
+#: gui/options.cpp:1186
msgctxt "lowres"
msgid "Misc"
msgstr "Diverse"
-#: gui/options.cpp:1113
+#: gui/options.cpp:1188
msgid "Theme:"
msgstr "Tema:"
-#: gui/options.cpp:1117
+#: gui/options.cpp:1192
msgid "GUI Renderer:"
msgstr "GUI-rendering:"
-#: gui/options.cpp:1129
+#: gui/options.cpp:1204
msgid "Autosave:"
msgstr "Autospara:"
-#: gui/options.cpp:1131
+#: gui/options.cpp:1206
msgctxt "lowres"
msgid "Autosave:"
msgstr "Autospara:"
-#: gui/options.cpp:1139
+#: gui/options.cpp:1214
msgid "Keys"
msgstr "Tangenter"
-#: gui/options.cpp:1146
+#: gui/options.cpp:1221
msgid "GUI Language:"
msgstr "GUI-språk:"
-#: gui/options.cpp:1146
+#: gui/options.cpp:1221
msgid "Language of ScummVM GUI"
msgstr "Språk för ScummVM:s användargränssnitt"
-#: gui/options.cpp:1295
-#, fuzzy
+#: gui/options.cpp:1372
msgid "You have to restart ScummVM before your changes will take effect."
msgstr "Du måste starta om ScummVM för att ändringarna ska få effekt."
-#: gui/options.cpp:1308
+#: gui/options.cpp:1385
msgid "Select directory for savegames"
msgstr "Välj katalog för spardata"
-#: gui/options.cpp:1315
+#: gui/options.cpp:1392
msgid "The chosen directory cannot be written to. Please select another one."
msgstr ""
"Det går inte att skriva till den valda katalogen. Var god välj en annan."
-#: gui/options.cpp:1324
+#: gui/options.cpp:1401
msgid "Select directory for GUI themes"
msgstr "Välj katalog för GUI-teman"
-#: gui/options.cpp:1334
+#: gui/options.cpp:1411
msgid "Select directory for extra files"
msgstr "Välj katalog för extra filer"
-#: gui/options.cpp:1345
+#: gui/options.cpp:1422
msgid "Select directory for plugins"
msgstr "Välj katalog för tillägg"
-#: gui/options.cpp:1389
+#: gui/options.cpp:1475
msgid ""
"The theme you selected does not support your current language. If you want "
"to use this theme you need to switch to another language first."
@@ -967,60 +969,64 @@ msgstr "Namnlös spardata"
msgid "Select a Theme"
msgstr "Välj ett tema"
-#: gui/ThemeEngine.cpp:328
+#: gui/ThemeEngine.cpp:333
msgid "Disabled GFX"
msgstr "Inaktiverad GFX"
-#: gui/ThemeEngine.cpp:328
+#: gui/ThemeEngine.cpp:333
msgctxt "lowres"
msgid "Disabled GFX"
msgstr "Inaktiverad GFX"
-#: gui/ThemeEngine.cpp:329
+#: gui/ThemeEngine.cpp:334
msgid "Standard Renderer (16bpp)"
msgstr "Standard rendering (16 bpp)"
-#: gui/ThemeEngine.cpp:329
+#: gui/ThemeEngine.cpp:334
msgid "Standard (16bpp)"
msgstr "Standard (16 bpp)"
-#: gui/ThemeEngine.cpp:331
+#: gui/ThemeEngine.cpp:336
msgid "Antialiased Renderer (16bpp)"
msgstr "Antialiserad rendering (16 bpp)"
-#: gui/ThemeEngine.cpp:331
+#: gui/ThemeEngine.cpp:336
msgid "Antialiased (16bpp)"
msgstr "Antialiserad (16 bpp)"
+#: gui/widget.cpp:312 gui/widget.cpp:314 gui/widget.cpp:320 gui/widget.cpp:322
+msgid "Clear value"
+msgstr "Töm sökfältet"
+
#: base/main.cpp:203
#, c-format
msgid "Engine does not support debug level '%s'"
msgstr "Motorn stöder inte debug-nivå '%s'"
-#: base/main.cpp:271
+#: base/main.cpp:275
msgid "Menu"
msgstr "Meny"
-#: base/main.cpp:274 backends/platform/symbian/src/SymbianActions.cpp:45
+#: base/main.cpp:278 backends/platform/symbian/src/SymbianActions.cpp:45
#: backends/platform/wince/CEActionsPocket.cpp:45
#: backends/platform/wince/CEActionsSmartphone.cpp:46
msgid "Skip"
msgstr "Skippa"
-#: base/main.cpp:277 backends/platform/symbian/src/SymbianActions.cpp:50
+#: base/main.cpp:281 backends/platform/symbian/src/SymbianActions.cpp:50
#: backends/platform/wince/CEActionsPocket.cpp:42
msgid "Pause"
msgstr "Paus"
-#: base/main.cpp:280
+#: base/main.cpp:284
msgid "Skip line"
msgstr "Skippa rad"
-#: base/main.cpp:439
+#: base/main.cpp:455
msgid "Error running game:"
msgstr "Fel under körning av spel:"
-#: base/main.cpp:463
+#: base/main.cpp:479
msgid "Could not find any engine capable of running the selected game"
msgstr "Kunde inte hitta en motor kapabel till att köra det valda spelet"
@@ -1037,7 +1043,6 @@ msgid "Game id not supported"
msgstr "Spel-ID stöds inte"
#: common/error.cpp:44
-#, fuzzy
msgid "Unsupported color mode"
msgstr "Ej stött färgläge"
@@ -1066,7 +1071,6 @@ msgid "Cannot create file"
msgstr "Kan inte skapa fil"
#: common/error.cpp:61
-#, fuzzy
msgid "Reading data failed"
msgstr "Inläsning misslyckades"
@@ -1079,49 +1083,30 @@ msgid "Could not find suitable engine plugin"
msgstr "Kunde inte hitta lämpligt motortillägg"
#: common/error.cpp:68
-#, fuzzy
msgid "Engine plugin does not support save states"
-msgstr "Motorn stöder inte debug-nivå '%s'"
+msgstr "Motortillägget stöder inte spardata"
#: common/error.cpp:71
msgid "User canceled"
-msgstr ""
+msgstr "Avbrutit av användaren"
#: common/error.cpp:75
msgid "Unknown error"
msgstr "Okänt fel"
-#. I18N: Hercules is graphics card name
-#: common/util.cpp:275
-msgid "Hercules Green"
-msgstr "Herkules grön"
-
-#: common/util.cpp:276
-msgid "Hercules Amber"
-msgstr "Herkules bärnsten"
-
-#: common/util.cpp:283
-msgctxt "lowres"
-msgid "Hercules Green"
-msgstr "Herkules grön"
-
-#: common/util.cpp:284
-msgctxt "lowres"
-msgid "Hercules Amber"
-msgstr "Herkules bärnsten"
-
#: engines/advancedDetector.cpp:296
#, c-format
msgid "The game in '%s' seems to be unknown."
-msgstr ""
+msgstr "Spelet i '%s' verkar vara okänt."
#: engines/advancedDetector.cpp:297
msgid "Please, report the following data to the ScummVM team along with name"
msgstr ""
+"Var god rapportera följande data till ScummVM-teamet tillsammans med namnet"
#: engines/advancedDetector.cpp:299
msgid "of the game you tried to add and its version/language/etc.:"
-msgstr ""
+msgstr "på spelet du försökte lägga till och dess version/språk/etc.:"
#: engines/dialogs.cpp:84
msgid "~R~esume"
@@ -1157,12 +1142,12 @@ msgid "~R~eturn to Launcher"
msgstr "Åte~r~vänd till launcher"
#: engines/dialogs.cpp:116 engines/cruise/menu.cpp:214
-#: engines/sci/engine/kfile.cpp:578
+#: engines/sci/engine/kfile.cpp:566
msgid "Save game:"
msgstr "Spara spelet:"
#: engines/dialogs.cpp:116 engines/scumm/dialogs.cpp:187
-#: engines/cruise/menu.cpp:214 engines/sci/engine/kfile.cpp:578
+#: engines/cruise/menu.cpp:214 engines/sci/engine/kfile.cpp:566
#: backends/platform/symbian/src/SymbianActions.cpp:44
#: backends/platform/wince/CEActionsPocket.cpp:43
#: backends/platform/wince/CEActionsPocket.cpp:267
@@ -1177,40 +1162,51 @@ msgid ""
"the README for basic information, and for instructions on how to obtain "
"further assistance."
msgstr ""
+"Tyvärr stöder för tillfället inte den här motorn hjälp-funktionen. Var god "
+"hänvisa till README-filen för information och instruktioner för att få "
+"ytterligare assistens."
+
+#: engines/dialogs.cpp:243
+#, fuzzy, c-format
+msgid ""
+"Gamestate save failed (%s)! Please consult the README for basic information, "
+"and for instructions on how to obtain further assistance."
+msgstr ""
+"Tyvärr stöder för tillfället inte den här motorn hjälp-funktionen. Var god "
+"hänvisa till README-filen för information och instruktioner för att få "
+"ytterligare assistens."
-#: engines/dialogs.cpp:316 engines/mohawk/dialogs.cpp:109
+#: engines/dialogs.cpp:321 engines/mohawk/dialogs.cpp:109
#: engines/mohawk/dialogs.cpp:174
msgid "~O~K"
msgstr "~O~K"
-#: engines/dialogs.cpp:317 engines/mohawk/dialogs.cpp:110
+#: engines/dialogs.cpp:322 engines/mohawk/dialogs.cpp:110
#: engines/mohawk/dialogs.cpp:175
msgid "~C~ancel"
msgstr "A~v~bryt"
-#: engines/dialogs.cpp:320
+#: engines/dialogs.cpp:325
msgid "~K~eys"
msgstr "~T~angenter"
-#: engines/engine.cpp:233
+#: engines/engine.cpp:235
msgid "Could not initialize color format."
-msgstr ""
+msgstr "Kunde inte initialisera färgformat."
-#: engines/engine.cpp:241
-#, fuzzy
+#: engines/engine.cpp:243
msgid "Could not switch to video mode: '"
-msgstr "Aktivt videoläge:"
+msgstr "Kunde inte byta till videoläget: '"
-#: engines/engine.cpp:250
-#, fuzzy
+#: engines/engine.cpp:252
msgid "Could not apply aspect ratio setting."
-msgstr "Korrektion av bildförhållande på/av"
+msgstr "Kunde inte ändra inställningen för bildförhållanden."
-#: engines/engine.cpp:255
+#: engines/engine.cpp:257
msgid "Could not apply fullscreen setting."
-msgstr ""
+msgstr "Kunde inte applicera fullskärmsinställning."
-#: engines/engine.cpp:355
+#: engines/engine.cpp:357
msgid ""
"You appear to be playing this game directly\n"
"from the CD. This is known to cause problems,\n"
@@ -1218,8 +1214,13 @@ msgid ""
"the data files to your hard disk instead.\n"
"See the README file for details."
msgstr ""
+"Det verkar som att du spelar det här spelet direkt\n"
+"från CD:n. Detta har en tendens att orsaka problem.\n"
+"Det är därför rekommenderat att du kopierar\n"
+"datafilerna till din hårddisk istället.\n"
+"Se README-filen för detaljer."
-#: engines/engine.cpp:366
+#: engines/engine.cpp:368
msgid ""
"This game has audio tracks in its disk. These\n"
"tracks need to be ripped from the disk using\n"
@@ -1227,102 +1228,117 @@ msgid ""
"order to listen to the game's music.\n"
"See the README file for details."
msgstr ""
+"Det här spelet har ljudspår på sin skiva. Dessa\n"
+"spår måste rippas från skivan med hjälp av\n"
+"ett lämpligt program för extraktion av CD-ljud\n"
+"för att kunna lyssna på spelets musik.\n"
+"Se README-filen för detaljer."
+
+#: engines/engine.cpp:426
+#, fuzzy, c-format
+msgid ""
+"Gamestate load failed (%s)! Please consult the README for basic information, "
+"and for instructions on how to obtain further assistance."
+msgstr ""
+"Tyvärr stöder för tillfället inte den här motorn hjälp-funktionen. Var god "
+"hänvisa till README-filen för information och instruktioner för att få "
+"ytterligare assistens."
-#: engines/engine.cpp:433
+#: engines/engine.cpp:439
msgid ""
"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."
msgstr ""
+"VARNING: Spelet du är på väg att starta stöds inte ännu till fullo av "
+"ScummVM. Därför är det troligtvis instabilt och om du skapar spardata kan de "
+"möjligtvis vara inkompatibla med framtida versioner av ScummVM."
-#: engines/engine.cpp:436
+#: engines/engine.cpp:442
msgid "Start anyway"
-msgstr ""
+msgstr "Starta ändå"
#: engines/scumm/dialogs.cpp:175
#, c-format
msgid "Insert Disk %c and Press Button to Continue."
-msgstr ""
+msgstr "Mata in skivan %c och tryck på knappen för att fortsätta."
#: engines/scumm/dialogs.cpp:176
#, c-format
msgid "Unable to Find %s, (%c%d) Press Button."
-msgstr ""
+msgstr "Kunde inte hitta %s, (%c%d) tryck på knappen."
#: engines/scumm/dialogs.cpp:177
#, c-format
msgid "Error reading disk %c, (%c%d) Press Button."
-msgstr ""
+msgstr "Fel vid inläsning av skivan %c, (%c%d) tryck på knappen."
#: engines/scumm/dialogs.cpp:178
msgid "Game Paused. Press SPACE to Continue."
-msgstr ""
+msgstr "Spelet pausat. Tryck MELLANSLAG för att fortsätta."
#. I18N: You may specify 'Yes' symbol at the end of the line, like this:
#. "Moechten Sie wirklich neu starten? (J/N)J"
#. Will react to J as 'Yes'
#: engines/scumm/dialogs.cpp:182
-#, fuzzy
msgid "Are you sure you want to restart? (Y/N)"
-msgstr "Är du säker på att du vill avsluta?"
+msgstr "Är du säker på att du vill starta om? (J/N)J"
#. I18N: you may specify 'Yes' symbol at the end of the line. See previous comment
#: engines/scumm/dialogs.cpp:184
-#, fuzzy
msgid "Are you sure you want to quit? (Y/N)"
-msgstr "Är du säker på att du vill avsluta?"
+msgstr "Är du säker på att du vill avsluta? (J/N)J"
#: engines/scumm/dialogs.cpp:189
msgid "Play"
-msgstr ""
+msgstr "Spela"
#: engines/scumm/dialogs.cpp:191 engines/scumm/help.cpp:82
#: engines/scumm/help.cpp:84
#: backends/platform/symbian/src/SymbianActions.cpp:52
#: backends/platform/wince/CEActionsPocket.cpp:44
#: backends/platform/wince/CEActionsSmartphone.cpp:52
-#: backends/events/default/default-events.cpp:244
+#: backends/events/default/default-events.cpp:213
msgid "Quit"
msgstr "Avsluta"
#: engines/scumm/dialogs.cpp:193
msgid "Insert save/load game disk"
-msgstr ""
+msgstr "Mata in skiva för spardata"
#: engines/scumm/dialogs.cpp:194
msgid "You must enter a name"
-msgstr ""
+msgstr "Du måste ange ett namn"
#: engines/scumm/dialogs.cpp:195
msgid "The game was NOT saved (disk full?)"
-msgstr ""
+msgstr "Spelet sprades EJ (skivan full?)"
#: engines/scumm/dialogs.cpp:196
msgid "The game was NOT loaded"
-msgstr ""
+msgstr "Spelet laddades EJ"
#: engines/scumm/dialogs.cpp:197
#, c-format
msgid "Saving '%s'"
-msgstr ""
+msgstr "Sparar '%s'"
#: engines/scumm/dialogs.cpp:198
#, c-format
msgid "Loading '%s'"
-msgstr ""
+msgstr "Laddar '%s'"
#: engines/scumm/dialogs.cpp:199
msgid "Name your SAVE game"
-msgstr ""
+msgstr "Namnge ditt SPARADE spel"
#: engines/scumm/dialogs.cpp:200
-#, fuzzy
msgid "Select a game to LOAD"
-msgstr "Välj ett tema"
+msgstr "Välj ett spel att LADDA"
#: engines/scumm/dialogs.cpp:201
msgid "Game title)"
-msgstr ""
+msgstr "Speltitel)"
#. I18N: Previous page button
#: engines/scumm/dialogs.cpp:287
@@ -1340,25 +1356,42 @@ msgid "~C~lose"
msgstr "~S~täng"
#: engines/scumm/dialogs.cpp:597
-#, fuzzy
msgid "Speech Only"
-msgstr "Tal"
+msgstr "Endast tal"
#: engines/scumm/dialogs.cpp:598
-#, fuzzy
msgid "Speech and Subtitles"
-msgstr "Undertexter"
+msgstr "Tal och undertexter"
#: engines/scumm/dialogs.cpp:599
-#, fuzzy
msgid "Subtitles Only"
-msgstr "Undertexter"
+msgstr "Endast undertexter"
#: engines/scumm/dialogs.cpp:607
-#, fuzzy
msgctxt "lowres"
msgid "Speech & Subs"
-msgstr "Tal"
+msgstr "Tal & text"
+
+#: engines/scumm/dialogs.cpp:653
+msgid "Select a Proficiency Level."
+msgstr ""
+
+#: engines/scumm/dialogs.cpp:655
+msgid "Refer to your Loom(TM) manual for help."
+msgstr ""
+
+#: engines/scumm/dialogs.cpp:658
+#, fuzzy
+msgid "Standard"
+msgstr "Standard (16 bpp)"
+
+#: engines/scumm/dialogs.cpp:659
+msgid "Practice"
+msgstr ""
+
+#: engines/scumm/dialogs.cpp:660
+msgid "Expert"
+msgstr ""
#: engines/scumm/help.cpp:73
msgid "Common keyboard commands:"
@@ -1491,9 +1524,8 @@ msgid " since they may cause crashes"
msgstr "då detta kan orsaka krascher"
#: engines/scumm/help.cpp:110
-#, fuzzy
msgid " or incorrect game behavior."
-msgstr "eller felaktigt spelbeteende."
+msgstr " eller felaktigt spelbeteende."
#: engines/scumm/help.cpp:114
msgid "Spinning drafts on the keyboard:"
@@ -1874,14 +1906,16 @@ msgstr "Flyg åt höger"
msgid "Fly to lower right"
msgstr "Flyg åt nedre höger"
-#: engines/scumm/scumm.cpp:1774
+#: engines/scumm/scumm.cpp:1773
#, c-format
msgid ""
"Native MIDI support requires the Roland Upgrade from LucasArts,\n"
"but %s is missing. Using AdLib instead."
msgstr ""
+"Stöd för Native MIDI kräver Roland-uppdateringen från LucasArts,\n"
+"men %s saknas. Använder AdLib istället."
-#: engines/scumm/scumm.cpp:2264 engines/agos/saveload.cpp:189
+#: engines/scumm/scumm.cpp:2271 engines/agos/saveload.cpp:189
#, c-format
msgid ""
"Failed to save game state to file:\n"
@@ -1892,7 +1926,7 @@ msgstr ""
"\n"
"%s"
-#: engines/scumm/scumm.cpp:2271 engines/agos/saveload.cpp:154
+#: engines/scumm/scumm.cpp:2278 engines/agos/saveload.cpp:154
#, c-format
msgid ""
"Failed to load game state from file:\n"
@@ -1903,7 +1937,7 @@ msgstr ""
"\n"
"%s"
-#: engines/scumm/scumm.cpp:2283 engines/agos/saveload.cpp:197
+#: engines/scumm/scumm.cpp:2290 engines/agos/saveload.cpp:197
#, c-format
msgid ""
"Successfully saved game state in file:\n"
@@ -1914,7 +1948,7 @@ msgstr ""
"\n"
"%s"
-#: engines/scumm/scumm.cpp:2498
+#: engines/scumm/scumm.cpp:2505
msgid ""
"Usually, Maniac Mansion would start now. But ScummVM doesn't do that yet. To "
"play it, go to 'Add Game' in the ScummVM start menu and select the 'Maniac' "
@@ -1936,66 +1970,97 @@ msgstr "Öv~e~rgångar aktiverade"
#. I18N: Drop book page
#: engines/mohawk/dialogs.cpp:95
msgid "~D~rop Page"
-msgstr ""
+msgstr "Släpp si~d~a"
#: engines/mohawk/dialogs.cpp:99
msgid "~S~how Map"
-msgstr ""
+msgstr "~V~isa karta"
#: engines/mohawk/dialogs.cpp:105
-#, fuzzy
msgid "~M~ain Menu"
-msgstr "ScummVM huvudmeny"
+msgstr "Huvud~m~eny"
#: engines/mohawk/dialogs.cpp:172
msgid "~W~ater Effect Enabled"
msgstr "~V~atteneffekt aktiverad"
-#: engines/sci/engine/kfile.cpp:685
+#: engines/sci/engine/kfile.cpp:673
msgid "Restore game:"
msgstr "Återställ spel:"
-#: engines/sci/engine/kfile.cpp:685
+#: engines/sci/engine/kfile.cpp:673
msgid "Restore"
msgstr "Återställ"
#: engines/agos/animation.cpp:550
#, c-format
msgid "Cutscene file '%s' not found!"
-msgstr ""
+msgstr "Filmscensfilen '%s' hittades ej!"
#: engines/gob/inter_playtoons.cpp:256 engines/gob/inter_v2.cpp:1283
-#: engines/tinsel/saveload.cpp:482
-#, fuzzy
+#: engines/tinsel/saveload.cpp:502
msgid "Failed to load game state from file."
-msgstr ""
-"Kunde inte läsa spardata från file:\n"
-"\n"
-"%s"
+msgstr "Kunde inte läsa spardata från filen"
-#: engines/gob/inter_v2.cpp:1353 engines/tinsel/saveload.cpp:560
-#, fuzzy
+#: engines/gob/inter_v2.cpp:1353 engines/tinsel/saveload.cpp:515
msgid "Failed to save game state to file."
-msgstr ""
-"Kunde inte skriva spardata till file:\n"
-"\n"
-"%s"
+msgstr "Kunde inte skriva spardata till filen."
#: engines/gob/inter_v5.cpp:107
-#, fuzzy
msgid "Failed to delete file."
-msgstr ""
-"Kunde inte skriva spardata till file:\n"
-"\n"
-"%s"
+msgstr "Kunde inte radera filen."
#: engines/groovie/script.cpp:420
-#, fuzzy
msgid "Failed to save game"
-msgstr ""
-"Kunde inte skriva spardata till file:\n"
-"\n"
-"%s"
+msgstr "Kunde inte spara spelet."
+
+#: engines/kyra/lol.cpp:478
+msgid "Attack 1"
+msgstr "Attack 1"
+
+#: engines/kyra/lol.cpp:479
+msgid "Attack 2"
+msgstr "Attack 2"
+
+#: engines/kyra/lol.cpp:480
+msgid "Attack 3"
+msgstr "Attack 3"
+
+#: engines/kyra/lol.cpp:481
+msgid "Move Forward"
+msgstr "Steg framåt"
+
+#: engines/kyra/lol.cpp:482
+msgid "Move Back"
+msgstr "Steg bakåt"
+
+#: engines/kyra/lol.cpp:483
+msgid "Slide Left"
+msgstr "Glid vänster"
+
+#: engines/kyra/lol.cpp:484
+msgid "Slide Right"
+msgstr "Glid höger"
+
+#: engines/kyra/lol.cpp:485
+msgid "Turn Left"
+msgstr "Sväng vänster"
+
+#: engines/kyra/lol.cpp:486
+msgid "Turn Right"
+msgstr "Sväng höger"
+
+#: engines/kyra/lol.cpp:487
+msgid "Rest"
+msgstr "Vila"
+
+#: engines/kyra/lol.cpp:488
+msgid "Options"
+msgstr "Inställningar"
+
+#: engines/kyra/lol.cpp:489
+msgid "Choose Spell"
+msgstr "Välj trollformel"
#: engines/kyra/sound_midi.cpp:475
msgid ""
@@ -2005,36 +2070,45 @@ msgid ""
"General MIDI ones. After all it might happen\n"
"that a few tracks will not be correctly played."
msgstr ""
-
-#: engines/m4/m4_menus.cpp:138
-#, fuzzy
-msgid "Save game failed!"
-msgstr "Spara spelet:"
+"Du verkar använda en General MIDI enhet\n"
+"men ditt spel stöder endast Roland MT32 MIDI.\n"
+"Vi försöker kartlägga Roland MT32 instrument för\n"
+"General MIDI instrument. Det kan trots allt hända\n"
+"att ett fåtal ljudspår inte spelas korrekt."
#: engines/sky/compact.cpp:130
msgid ""
"Unable to find \"sky.cpt\" file!\n"
"Please download it from www.scummvm.org"
msgstr ""
+"Kunde inte hitta \"sky.cpt\"-filen!\n"
+"Var god ladda hem den från www.scummvm.org"
#: engines/sky/compact.cpp:141
msgid ""
"The \"sky.cpt\" file has an incorrect size.\n"
"Please (re)download it from www.scummvm.org"
msgstr ""
+"Filen \"sky.cpt\" har inkorrekt filstorlek.\n"
+"Var god ladda hem den igen från www.scummvm.org"
-#: engines/sword1/animation.cpp:344 engines/sword2/animation.cpp:379
-msgid "DXA cutscenes found but ScummVM has been built without zlib support"
+#: engines/sword1/animation.cpp:539
+#, c-format
+msgid "PSX stream cutscene '%s' cannot be played in paletted mode"
msgstr ""
-#: engines/sword1/animation.cpp:354 engines/sword2/animation.cpp:389
+#: engines/sword1/animation.cpp:560 engines/sword2/animation.cpp:455
+msgid "DXA cutscenes found but ScummVM has been built without zlib support"
+msgstr "DXA filmscener hittades men ScummVM har byggts utan stöd för zlib"
+
+#: engines/sword1/animation.cpp:570 engines/sword2/animation.cpp:465
msgid "MPEG2 cutscenes are no longer supported"
-msgstr ""
+msgstr "MPEG2 filmscener stöds inte längre"
-#: engines/sword1/animation.cpp:359 engines/sword2/animation.cpp:397
+#: engines/sword1/animation.cpp:576 engines/sword2/animation.cpp:473
#, c-format
msgid "Cutscene '%s' not found"
-msgstr ""
+msgstr "Filmscenen '%s' hittades ej"
#: engines/sword1/control.cpp:863
msgid ""
@@ -2046,6 +2120,13 @@ msgid ""
"Press OK to convert them now, otherwise you will be asked again the next "
"time you start the game.\n"
msgstr ""
+"ScummVM upptäckte att du har gamla spardata för Broken Sword 1 som borde "
+"konverteras.\n"
+"Det gamla spardataformatet stöds inte längre, så du kommer inte kunna ladda "
+"dina data om du inte konverterar dem.\n"
+"\n"
+"Tryck \"OK\" för att konvertera dem nu, annars kommer du tillfrågas igen "
+"nästa gång du startar spelet.\n"
#: engines/sword1/control.cpp:1232
#, c-format
@@ -2053,18 +2134,26 @@ msgid ""
"Target new save game already exists!\n"
"Would you like to keep the old save game (%s) or the new one (%s)?\n"
msgstr ""
+"Den valda spardatan existerar redan!\n"
+"Vill du behålla den gamla spardatan (%s) eller den nya (%s)?\n"
#: engines/sword1/control.cpp:1235
msgid "Keep the old one"
-msgstr ""
+msgstr "Behåll den gamla"
#: engines/sword1/control.cpp:1235
msgid "Keep the new one"
-msgstr ""
+msgstr "Behåll den nya"
#: engines/sword1/logic.cpp:1633
msgid "This is the end of the Broken Sword 1 Demo"
-msgstr ""
+msgstr "Här slutar Broken Sword 1 demon"
+
+#: engines/sword2/animation.cpp:435
+#, fuzzy
+msgid ""
+"PSX cutscenes found but ScummVM has been built without RGB color support"
+msgstr "DXA filmscener hittades men ScummVM har byggts utan stöd för zlib"
#: engines/parallaction/saveload.cpp:133
#, c-format
@@ -2072,16 +2161,16 @@ msgid ""
"Can't save game in slot %i\n"
"\n"
msgstr ""
+"Kan inte spara data i position %i\n"
+"\n"
#: engines/parallaction/saveload.cpp:211
-#, fuzzy
msgid "Loading game..."
-msgstr "Ladda spel:"
+msgstr "Laddar speldata..."
#: engines/parallaction/saveload.cpp:226
-#, fuzzy
msgid "Saving game..."
-msgstr "Spara spelet:"
+msgstr "Sparar speldata..."
#: engines/parallaction/saveload.cpp:279
msgid ""
@@ -2092,10 +2181,17 @@ msgid ""
"\n"
"Press OK to convert them now, otherwise you will be asked next time.\n"
msgstr ""
+"ScummVM upptäckte att du har gamla spardata för Nippon Safes som borde byta "
+"namn.\n"
+"De gamla filnamnen stöds inte längre, så du kommer inte kunna ladda dina "
+"data om du inte konverterar dem.\n"
+"\n"
+"Tryck \"OK\" för att konvertera dem nu, annars kommer du tillfrågas igen "
+"nästa gång du startar spelet.\n"
#: engines/parallaction/saveload.cpp:326
msgid "ScummVM successfully converted all your savefiles."
-msgstr ""
+msgstr "ScummVM lyckades konvertera alla dina spardata."
#: engines/parallaction/saveload.cpp:328
msgid ""
@@ -2104,6 +2200,10 @@ msgid ""
"\n"
"Please report to the team."
msgstr ""
+"ScummVM skrev ut några varningar i ditt konsolfönster och kan inte garantera "
+"att alla dina filer har konverterats.\n"
+"\n"
+"Var god rapportera till teamet."
#: audio/fmopl.cpp:49
msgid "MAME OPL emulator"
@@ -2113,38 +2213,46 @@ msgstr "MAME OPL-emulator"
msgid "DOSBox OPL emulator"
msgstr "DOSBox OPL-emulator"
-#: audio/mididrv.cpp:205
+#: audio/mididrv.cpp:209
#, c-format
msgid ""
"The selected audio device '%s' was not found (e.g. might be turned off or "
"disconnected)."
msgstr ""
+"Den valda ljudenheten '%s' kunde inte hittas (möjligtvis avstängd eller "
+"frånkopplad)."
-#: audio/mididrv.cpp:205 audio/mididrv.cpp:217 audio/mididrv.cpp:253
-#: audio/mididrv.cpp:268
+#: audio/mididrv.cpp:209 audio/mididrv.cpp:221 audio/mididrv.cpp:257
+#: audio/mididrv.cpp:272
msgid "Attempting to fall back to the next available device..."
-msgstr ""
+msgstr "Försöker använda nästa tillgängliga ljudenhet..."
-#: audio/mididrv.cpp:217
+#: audio/mididrv.cpp:221
#, c-format
msgid ""
"The selected audio device '%s' cannot be used. See log file for more "
"information."
msgstr ""
+"Den valda ljudenheten '%s' kan inte användas. Se loggfilen för mer "
+"information."
-#: audio/mididrv.cpp:253
+#: audio/mididrv.cpp:257
#, c-format
msgid ""
"The preferred audio device '%s' was not found (e.g. might be turned off or "
"disconnected)."
msgstr ""
+"Den föredragna ljudenheten '%s' kunde inte hittas (möjligtvis avstängd eller "
+"frånkopplad)."
-#: audio/mididrv.cpp:268
+#: audio/mididrv.cpp:272
#, c-format
msgid ""
"The preferred audio device '%s' cannot be used. See log file for more "
"information."
msgstr ""
+"Den föredragna ljudenheten '%s' kan inte användas. Se loggfilen för mer "
+"information."
#: audio/null.h:43
msgid "No music"
@@ -2154,7 +2262,7 @@ msgstr "Ingen musik"
msgid "Amiga Audio Emulator"
msgstr "Amiga ljudemulator"
-#: audio/softsynth/adlib.cpp:1594
+#: audio/softsynth/adlib.cpp:1593
msgid "AdLib Emulator"
msgstr "AdLib-emulator"
@@ -2166,12 +2274,11 @@ msgstr "Apple II GS-emulator (INTE IMPLEMENTERAD)"
msgid "C64 Audio Emulator"
msgstr "C64 ljudemulator"
-#: audio/softsynth/mt32.cpp:329
-#, fuzzy
+#: audio/softsynth/mt32.cpp:293
msgid "Initializing MT-32 Emulator"
msgstr "Initialiserar MT-32 emulator"
-#: audio/softsynth/mt32.cpp:543
+#: audio/softsynth/mt32.cpp:512
msgid "MT-32 Emulator"
msgstr "MT-32 emulator"
@@ -2187,15 +2294,24 @@ msgstr "IBM PCjr-emulator"
msgid "Keymap:"
msgstr "Tangenter:"
-#: backends/keymapper/remap-dialog.cpp:64
+#: backends/keymapper/remap-dialog.cpp:66
+#, fuzzy
+msgid " (Effective)"
+msgstr "(Aktiv)"
+
+#: backends/keymapper/remap-dialog.cpp:106
msgid " (Active)"
msgstr "(Aktiv)"
-#: backends/keymapper/remap-dialog.cpp:98
+#: backends/keymapper/remap-dialog.cpp:106
+msgid " (Blocked)"
+msgstr ""
+
+#: backends/keymapper/remap-dialog.cpp:119
msgid " (Global)"
msgstr "(Global)"
-#: backends/keymapper/remap-dialog.cpp:108
+#: backends/keymapper/remap-dialog.cpp:127
msgid " (Game)"
msgstr "(Spel)"
@@ -2275,46 +2391,66 @@ msgstr "Hög ljudkvalitet (långsammare) (omstart)"
msgid "Disable power off"
msgstr "Inaktivera strömsparning"
-#: backends/platform/iphone/osys_events.cpp:338
-#, fuzzy
+#: backends/platform/iphone/osys_events.cpp:301
msgid "Mouse-click-and-drag mode enabled."
-msgstr "Touchpad-läge aktiverat."
+msgstr "Dra-och-släpp-läge med mus aktiverat."
-#: backends/platform/iphone/osys_events.cpp:340
-#, fuzzy
+#: backends/platform/iphone/osys_events.cpp:303
msgid "Mouse-click-and-drag mode disabled."
-msgstr "Touchpad-läge inaktiverat."
+msgstr "Dra-och-släpp-läge med mus deaktiverat."
-#: backends/platform/iphone/osys_events.cpp:351
+#: backends/platform/iphone/osys_events.cpp:314
msgid "Touchpad mode enabled."
msgstr "Touchpad-läge aktiverat."
-#: backends/platform/iphone/osys_events.cpp:353
+#: backends/platform/iphone/osys_events.cpp:316
msgid "Touchpad mode disabled."
msgstr "Touchpad-läge inaktiverat."
-#: backends/platform/sdl/macosx/appmenu_osx.mm:67
+#: backends/platform/maemo/maemo.cpp:205
+msgid "Click Mode"
+msgstr ""
+
+#: backends/platform/maemo/maemo.cpp:211
+#: backends/platform/symbian/src/SymbianActions.cpp:42
+#: backends/platform/wince/CEActionsPocket.cpp:60
+#: backends/platform/wince/CEActionsSmartphone.cpp:43
+#: backends/platform/bada/form.cpp:281
+msgid "Left Click"
+msgstr "Vänsterklick"
+
+#: backends/platform/maemo/maemo.cpp:214
#, fuzzy
+msgid "Middle Click"
+msgstr "Mellersta vänstra föremålet"
+
+#: backends/platform/maemo/maemo.cpp:217
+#: backends/platform/symbian/src/SymbianActions.cpp:43
+#: backends/platform/wince/CEActionsSmartphone.cpp:44
+#: backends/platform/bada/form.cpp:273
+msgid "Right Click"
+msgstr "Högerklick"
+
+#: backends/platform/sdl/macosx/appmenu_osx.mm:78
msgid "Hide ScummVM"
-msgstr "Avsluta ScummVM"
+msgstr "Göm ScummVM"
-#: backends/platform/sdl/macosx/appmenu_osx.mm:70
+#: backends/platform/sdl/macosx/appmenu_osx.mm:83
msgid "Hide Others"
-msgstr ""
+msgstr "Göm övriga"
-#: backends/platform/sdl/macosx/appmenu_osx.mm:74
+#: backends/platform/sdl/macosx/appmenu_osx.mm:88
msgid "Show All"
-msgstr ""
+msgstr "Visa alla"
-#: backends/platform/sdl/macosx/appmenu_osx.mm:92
-#: backends/platform/sdl/macosx/appmenu_osx.mm:99
-#, fuzzy
+#: backends/platform/sdl/macosx/appmenu_osx.mm:110
+#: backends/platform/sdl/macosx/appmenu_osx.mm:121
msgid "Window"
-msgstr "Windows MIDI"
+msgstr "Fönster"
-#: backends/platform/sdl/macosx/appmenu_osx.mm:95
+#: backends/platform/sdl/macosx/appmenu_osx.mm:115
msgid "Minimize"
-msgstr ""
+msgstr "Minimera"
#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:45
msgid "Normal (no scaling)"
@@ -2326,27 +2462,23 @@ msgid "Normal (no scaling)"
msgstr "Normalt (ingen skalning)"
#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2147
-#: backends/graphics/openglsdl/openglsdl-graphics.cpp:537
-#, fuzzy
+#: backends/graphics/openglsdl/openglsdl-graphics.cpp:533
msgid "Enabled aspect ratio correction"
-msgstr "Korrektion av bildförhållande på/av"
+msgstr "Korrektion av bildförhållande på"
#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2153
-#: backends/graphics/openglsdl/openglsdl-graphics.cpp:542
-#, fuzzy
+#: backends/graphics/openglsdl/openglsdl-graphics.cpp:538
msgid "Disabled aspect ratio correction"
-msgstr "Korrektion av bildförhållande på/av"
+msgstr "Korrektion av bildförhållande av"
#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2208
-#, fuzzy
msgid "Active graphics filter:"
-msgstr "Växla grafikfilter"
+msgstr "Aktivt grafikfilter:"
#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2250
-#: backends/graphics/openglsdl/openglsdl-graphics.cpp:481
-#, fuzzy
+#: backends/graphics/openglsdl/openglsdl-graphics.cpp:477
msgid "Windowed mode"
-msgstr "Renderingsläge:"
+msgstr "Fönsterläge"
#: backends/graphics/opengl/opengl-graphics.cpp:130
msgid "OpenGL Normal"
@@ -2361,21 +2493,20 @@ msgid "OpenGL Original"
msgstr "OpenGL original"
#: backends/graphics/openglsdl/openglsdl-graphics.cpp:415
-#, fuzzy
msgid "Current display mode"
-msgstr "Aktivt videoläge:"
+msgstr "Nuvarande visningsläge"
#: backends/graphics/openglsdl/openglsdl-graphics.cpp:428
msgid "Current scale"
-msgstr ""
+msgstr "Nuvarande skala"
-#: backends/graphics/openglsdl/openglsdl-graphics.cpp:562
+#: backends/graphics/openglsdl/openglsdl-graphics.cpp:558
msgid "Active filter mode: Linear"
-msgstr ""
+msgstr "Aktivt filterläge: Linjärt"
-#: backends/graphics/openglsdl/openglsdl-graphics.cpp:564
+#: backends/graphics/openglsdl/openglsdl-graphics.cpp:560
msgid "Active filter mode: Nearest"
-msgstr ""
+msgstr "Aktivt filterläge: Närmast"
#: backends/platform/symbian/src/SymbianActions.cpp:38
#: backends/platform/wince/CEActionsSmartphone.cpp:39
@@ -2397,19 +2528,6 @@ msgstr "Vänster"
msgid "Right"
msgstr "Höger"
-#: backends/platform/symbian/src/SymbianActions.cpp:42
-#: backends/platform/wince/CEActionsPocket.cpp:60
-#: backends/platform/wince/CEActionsSmartphone.cpp:43
-#: backends/platform/bada/form.cpp:281
-msgid "Left Click"
-msgstr "Vänsterklick"
-
-#: backends/platform/symbian/src/SymbianActions.cpp:43
-#: backends/platform/wince/CEActionsSmartphone.cpp:44
-#: backends/platform/bada/form.cpp:273
-msgid "Right Click"
-msgstr "Högerklick"
-
#: backends/platform/symbian/src/SymbianActions.cpp:46
#: backends/platform/wince/CEActionsSmartphone.cpp:47
msgid "Zone"
@@ -2570,17 +2688,15 @@ msgid "Network down"
msgstr "Nätverk inaktivt"
#: backends/platform/wii/options.cpp:178
-#, fuzzy
msgid "Initializing network"
msgstr "Initialiserar nätverk"
#: backends/platform/wii/options.cpp:182
-#, fuzzy
msgid "Timeout while initializing network"
msgstr "Timeout under initialisering av nätverk"
#: backends/platform/wii/options.cpp:186
-#, fuzzy, c-format
+#, c-format
msgid "Network not initialized (%d)"
msgstr "Nätverk ej initialiserat (%d)"
@@ -2701,96 +2817,105 @@ msgstr ""
"Glöm inte att välja en tangent för \"Göm verktygsrad\" för att se hela "
"inventariet"
-#: backends/events/default/default-events.cpp:222
-#, fuzzy
+#: backends/events/default/default-events.cpp:191
msgid "Do you really want to return to the Launcher?"
-msgstr "Vill du verkligen radera den här spardatan?"
+msgstr "Vill du verkligen återgå till launchern?"
-#: backends/events/default/default-events.cpp:222
-#, fuzzy
+#: backends/events/default/default-events.cpp:191
msgid "Launcher"
-msgstr "Slå"
+msgstr "Launcher"
-#: backends/events/default/default-events.cpp:244
-#, fuzzy
+#: backends/events/default/default-events.cpp:213
msgid "Do you really want to quit?"
-msgstr "Vill du avsluta?"
+msgstr "Vill du verkligen avsluta?"
#: backends/events/gph/gph-events.cpp:338
#: backends/events/gph/gph-events.cpp:381
#: backends/events/openpandora/op-events.cpp:139
msgid "Touchscreen 'Tap Mode' - Left Click"
-msgstr ""
+msgstr "Touchscreen \"Tap-läge\" - Vänsterklick"
#: backends/events/gph/gph-events.cpp:340
#: backends/events/gph/gph-events.cpp:383
#: backends/events/openpandora/op-events.cpp:141
msgid "Touchscreen 'Tap Mode' - Right Click"
-msgstr ""
+msgstr "Touchscren \"Tap-läge\" - Högerklick"
#: backends/events/gph/gph-events.cpp:342
#: backends/events/gph/gph-events.cpp:385
#: backends/events/openpandora/op-events.cpp:143
msgid "Touchscreen 'Tap Mode' - Hover (No Click)"
-msgstr ""
+msgstr "Touchscreen \"Tap-läge\" - Hover (utan klick)"
#: backends/events/gph/gph-events.cpp:362
-#, fuzzy
msgid "Maximum Volume"
-msgstr "Volym"
+msgstr "Max. volym"
#: backends/events/gph/gph-events.cpp:364
msgid "Increasing Volume"
-msgstr ""
+msgstr "Höja volymen"
#: backends/events/gph/gph-events.cpp:370
-#, fuzzy
msgid "Minimal Volume"
-msgstr "Volym"
+msgstr "Min. volym"
#: backends/events/gph/gph-events.cpp:372
msgid "Decreasing Volume"
-msgstr ""
+msgstr "Sänka volymen"
#: backends/updates/macosx/macosx-updates.mm:65
msgid "Check for Updates..."
-msgstr ""
+msgstr "Sök efter uppdateringar..."
#: backends/platform/bada/form.cpp:269
-#, fuzzy
msgid "Right Click Once"
-msgstr "Högerklick"
+msgstr "Ett högerklick"
#: backends/platform/bada/form.cpp:277
-#, fuzzy
msgid "Move Only"
-msgstr "Tal"
+msgstr "Endast rörelse"
#: backends/platform/bada/form.cpp:291
msgid "Escape Key"
-msgstr ""
+msgstr "Escape-tangenten"
#: backends/platform/bada/form.cpp:296
-#, fuzzy
msgid "Game Menu"
-msgstr "Spel"
+msgstr "Spelmeny"
#: backends/platform/bada/form.cpp:301
-#, fuzzy
msgid "Show Keypad"
msgstr "Visa tangentbord"
#: backends/platform/bada/form.cpp:309
msgid "Control Mouse"
-msgstr ""
+msgstr "Kontrollera musen"
-#: backends/events/maemosdl/maemosdl-events.cpp:121
+#: backends/events/maemosdl/maemosdl-events.cpp:192
msgid "Clicking Enabled"
-msgstr ""
+msgstr "Klickning aktiverad"
-#: backends/events/maemosdl/maemosdl-events.cpp:121
+#: backends/events/maemosdl/maemosdl-events.cpp:192
msgid "Clicking Disabled"
-msgstr ""
+msgstr "Klickning deaktiverad"
+
+#~ msgid "Hercules Green"
+#~ msgstr "Herkules grön"
+
+#~ msgid "Hercules Amber"
+#~ msgstr "Herkules bärnsten"
+
+#~ msgctxt "lowres"
+#~ msgid "Hercules Green"
+#~ msgstr "Herkules grön"
+
+#~ msgctxt "lowres"
+#~ msgid "Hercules Amber"
+#~ msgstr "Herkules bärnsten"
+
+#, fuzzy
+#~ msgid "Save game failed!"
+#~ msgstr "Spara spelet:"
#~ msgctxt "lowres"
#~ msgid "Add Game..."
diff --git a/po/uk_UA.po b/po/uk_UA.po
index 3acd9c3d80..3971b29f6e 100644
--- a/po/uk_UA.po
+++ b/po/uk_UA.po
@@ -1,22 +1,22 @@
-# Ukrainian translation for ScummVM.
-# Copyright (C) 2010-2011 ScummVM Team
-# This file is distributed under the same license as the ScummVM package.
-# Lubomyr Lisen, 2010.
-#
+# Ukrainian translation for ScummVM.
+# Copyright (C) 2010-2012 ScummVM Team
+# This file is distributed under the same license as the ScummVM package.
+# Lubomyr Lisen, 2010.
+#
msgid ""
msgstr ""
"Project-Id-Version: ScummVM 1.3.0svn\n"
"Report-Msgid-Bugs-To: scummvm-devel@lists.sf.net\n"
-"POT-Creation-Date: 2011-10-19 13:42+0100\n"
-"PO-Revision-Date: 2011-08-20 13:30+0200\n"
+"POT-Creation-Date: 2012-03-07 22:09+0000\n"
+"PO-Revision-Date: 2012-02-16 13:09+0200\n"
"Last-Translator: Eugene Sandulenko\n"
"Language-Team: Ukrainian\n"
-"Language: Ukrainian\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=iso-8859-5\n"
"Content-Transfer-Encoding: 8bit\n"
-"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n"
-"%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
+"Language: Ukrainian\n"
+"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%"
+"10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
#: gui/about.cpp:91
#, c-format
@@ -45,13 +45,13 @@ msgid "Go up"
msgstr "²ÓÞàã"
#: gui/browser.cpp:69 gui/chooser.cpp:45 gui/KeysDialog.cpp:43
-#: gui/launcher.cpp:312 gui/massadd.cpp:94 gui/options.cpp:1178
+#: gui/launcher.cpp:320 gui/massadd.cpp:94 gui/options.cpp:1253
#: gui/saveload.cpp:63 gui/saveload.cpp:155 gui/themebrowser.cpp:54
-#: engines/engine.cpp:436 engines/scumm/dialogs.cpp:190
+#: engines/engine.cpp:442 engines/scumm/dialogs.cpp:190
#: engines/sword1/control.cpp:865 engines/parallaction/saveload.cpp:281
#: backends/platform/wii/options.cpp:48
-#: backends/events/default/default-events.cpp:222
-#: backends/events/default/default-events.cpp:244
+#: backends/events/default/default-events.cpp:191
+#: backends/events/default/default-events.cpp:213
msgid "Cancel"
msgstr "²öÔÜöÝÐ"
@@ -59,25 +59,29 @@ msgstr "²öÔÜöÝÐ"
msgid "Choose"
msgstr "²ØÑàÐâØ"
-#: gui/gui-manager.cpp:116 engines/scumm/help.cpp:125
+#: gui/gui-manager.cpp:115 engines/scumm/help.cpp:125
#: engines/scumm/help.cpp:140 engines/scumm/help.cpp:165
#: engines/scumm/help.cpp:191 engines/scumm/help.cpp:209
#: backends/keymapper/remap-dialog.cpp:52
msgid "Close"
msgstr "·ÐÚàØâØ"
-#: gui/gui-manager.cpp:119
+#: gui/gui-manager.cpp:118
msgid "Mouse click"
msgstr "ºÛöÚ ÜØèÚÞî"
-#: gui/gui-manager.cpp:122 base/main.cpp:283
+#: gui/gui-manager.cpp:122 base/main.cpp:288
msgid "Display keyboard"
msgstr "¿ÞÚÐ×ÐâØ ÚÛÐÒöÐâãàã"
-#: gui/gui-manager.cpp:125 base/main.cpp:286
+#: gui/gui-manager.cpp:126 base/main.cpp:292
msgid "Remap keys"
msgstr "¿ÕàÕßàØ×ÝÐçØâØ ÚÛÐÒöèö"
+#: gui/gui-manager.cpp:129 base/main.cpp:295
+msgid "Toggle FullScreen"
+msgstr "¿ÕàÕÜÚÝãâØ ßÞÒÝÞÕÚàÐÝÝØÙ àÕÖØÜ"
+
#: gui/KeysDialog.h:36 gui/KeysDialog.cpp:145
msgid "Choose an action to map"
msgstr "²ØÑÕàöâì Ôöî ÔÛï ßàØ×ÝÐçÕÝÝï"
@@ -86,16 +90,17 @@ msgstr "²ØÑÕàöâì Ôöî ÔÛï ßàØ×ÝÐçÕÝÝï"
msgid "Map"
msgstr "¿àØ×ÝÐçØâØ"
-#: gui/KeysDialog.cpp:42 gui/launcher.cpp:313 gui/launcher.cpp:936
-#: gui/launcher.cpp:940 gui/massadd.cpp:91 gui/options.cpp:1179
-#: engines/engine.cpp:359 engines/engine.cpp:370 engines/scumm/dialogs.cpp:192
-#: engines/scumm/scumm.cpp:1776 engines/agos/animation.cpp:551
+#: gui/KeysDialog.cpp:42 gui/launcher.cpp:321 gui/launcher.cpp:960
+#: gui/launcher.cpp:964 gui/massadd.cpp:91 gui/options.cpp:1254
+#: engines/engine.cpp:361 engines/engine.cpp:372 engines/scumm/dialogs.cpp:192
+#: engines/scumm/scumm.cpp:1775 engines/agos/animation.cpp:551
#: engines/groovie/script.cpp:420 engines/sky/compact.cpp:131
-#: engines/sky/compact.cpp:141 engines/sword1/animation.cpp:344
-#: engines/sword1/animation.cpp:354 engines/sword1/animation.cpp:360
-#: engines/sword1/control.cpp:865 engines/sword1/logic.cpp:1633
-#: engines/sword2/animation.cpp:379 engines/sword2/animation.cpp:389
-#: engines/sword2/animation.cpp:398 engines/parallaction/saveload.cpp:281
+#: engines/sky/compact.cpp:141 engines/sword1/animation.cpp:539
+#: engines/sword1/animation.cpp:560 engines/sword1/animation.cpp:570
+#: engines/sword1/animation.cpp:577 engines/sword1/control.cpp:865
+#: engines/sword1/logic.cpp:1633 engines/sword2/animation.cpp:435
+#: engines/sword2/animation.cpp:455 engines/sword2/animation.cpp:465
+#: engines/sword2/animation.cpp:474 engines/parallaction/saveload.cpp:281
#: backends/platform/wii/options.cpp:47
#: backends/platform/wince/CELauncherDialog.cpp:54
msgid "OK"
@@ -123,15 +128,15 @@ msgstr "±ãÔì ÛÐáÚÐ, ÒØÑÕàöâì Ôöî"
msgid "Press the key to associate"
msgstr "½ÐâØáÝöâì ÚÛÐÒöèã ÔÛï ßàØ×ÝÐçÕÝÝï"
-#: gui/launcher.cpp:165
+#: gui/launcher.cpp:170
msgid "Game"
msgstr "³àÐ"
-#: gui/launcher.cpp:169
+#: gui/launcher.cpp:174
msgid "ID:"
msgstr "ID:"
-#: gui/launcher.cpp:169 gui/launcher.cpp:171 gui/launcher.cpp:172
+#: gui/launcher.cpp:174 gui/launcher.cpp:176 gui/launcher.cpp:177
msgid ""
"Short game identifier used for referring to savegames and running the game "
"from the command line"
@@ -139,29 +144,29 @@ msgstr ""
"ºÞàÞâÚØÙ öÔÕÝâØäöÚÐâÞà, ïÚØÙ ÒØÚÞàØáâÞÒãôâìáï ÔÛï ÝÐ×Ò ×ÑÕàÕÖÕÝØå öÓÞà ö ÔÛï "
"×ÐßãáÚã × ÚÞÜÐÝÔÝÞ÷ áâàöçÚØ"
-#: gui/launcher.cpp:171
+#: gui/launcher.cpp:176
msgctxt "lowres"
msgid "ID:"
msgstr "ID:"
-#: gui/launcher.cpp:176
+#: gui/launcher.cpp:181
msgid "Name:"
msgstr "½Ð×ÒÐ:"
-#: gui/launcher.cpp:176 gui/launcher.cpp:178 gui/launcher.cpp:179
+#: gui/launcher.cpp:181 gui/launcher.cpp:183 gui/launcher.cpp:184
msgid "Full title of the game"
msgstr "¿ÞÒÝÐ ÝÐ×ÒÐ ÓàØ"
-#: gui/launcher.cpp:178
+#: gui/launcher.cpp:183
msgctxt "lowres"
msgid "Name:"
msgstr "½Ð×ÒÐ:"
-#: gui/launcher.cpp:182
+#: gui/launcher.cpp:187
msgid "Language:"
msgstr "¼ÞÒÐ:"
-#: gui/launcher.cpp:182 gui/launcher.cpp:183
+#: gui/launcher.cpp:187 gui/launcher.cpp:188
msgid ""
"Language of the game. This will not turn your Spanish game version into "
"English"
@@ -169,282 +174,280 @@ msgstr ""
"¼ÞÒÐ ÓàØ. ·ÜöÝÐ æìÞÓÞ ÝÐÛÐèâãÒÐÝÝï ÝÕ ßÕàÕâÒÞàØâì Óàã ÐÝÓÛöÙáìÚÞî ÝÐ "
"ãÚàÐ÷ÝáìÚã"
-#: gui/launcher.cpp:184 gui/launcher.cpp:198 gui/options.cpp:74
-#: gui/options.cpp:708 gui/options.cpp:718 gui/options.cpp:1149
+#: gui/launcher.cpp:189 gui/launcher.cpp:203 gui/options.cpp:80
+#: gui/options.cpp:745 gui/options.cpp:758 gui/options.cpp:1224
#: audio/null.cpp:40
msgid "<default>"
msgstr "<×Ð ãÜÞÒçÐÝÝïÜ>"
-#: gui/launcher.cpp:194
+#: gui/launcher.cpp:199
msgid "Platform:"
msgstr "¿ÛÐâäÞàÜÐ:"
-#: gui/launcher.cpp:194 gui/launcher.cpp:196 gui/launcher.cpp:197
+#: gui/launcher.cpp:199 gui/launcher.cpp:201 gui/launcher.cpp:202
msgid "Platform the game was originally designed for"
msgstr "¿ÛÐâäÞàÜÐ, ÔÛï ïÚÞ÷ Óàã ÑãÛÞ àÞ×àÞÑÛÕÝÞ ßÞçÐâÚÞÒÞ"
-#: gui/launcher.cpp:196
+#: gui/launcher.cpp:201
msgctxt "lowres"
msgid "Platform:"
msgstr "¿ÛÐâäÞàÜÐ:"
-#: gui/launcher.cpp:208 gui/options.cpp:1018 gui/options.cpp:1035
+#: gui/launcher.cpp:213 gui/options.cpp:1087 gui/options.cpp:1104
msgid "Graphics"
msgstr "³àÐäöÚÐ"
-#: gui/launcher.cpp:208 gui/options.cpp:1018 gui/options.cpp:1035
+#: gui/launcher.cpp:213 gui/options.cpp:1087 gui/options.cpp:1104
msgid "GFX"
msgstr "³àä"
-#: gui/launcher.cpp:211
+#: gui/launcher.cpp:216
msgid "Override global graphic settings"
msgstr "¿ÕàÕÚàØâØ ÓÛÞÑÐÛìÝö ãáâÐÝÞÒÚØ ÓàÐäöÚØ"
-#: gui/launcher.cpp:213
+#: gui/launcher.cpp:218
msgctxt "lowres"
msgid "Override global graphic settings"
msgstr "¿ÕàÕÚàØâØ ÓÛÞÑÐÛìÝö ãáâÐÝÞÒÚØ ÓàÐäöÚØ"
-#: gui/launcher.cpp:220 gui/options.cpp:1041
+#: gui/launcher.cpp:225 gui/options.cpp:1110
msgid "Audio"
msgstr "°ãÔöÞ"
-#: gui/launcher.cpp:223
+#: gui/launcher.cpp:228
msgid "Override global audio settings"
msgstr "¿ÕàÕÚàØâØ ÓÛÞÑÐÛìÝö ãáâÐÝÞÒÚØ ÐãÔöÞ"
-#: gui/launcher.cpp:225
+#: gui/launcher.cpp:230
msgctxt "lowres"
msgid "Override global audio settings"
msgstr "¿ÕàÕÚàØâØ ÓÛÞÑÐÛìÝö ãáâÐÝÞÒÚØ ÐãÔöÞ"
-#: gui/launcher.cpp:234 gui/options.cpp:1046
+#: gui/launcher.cpp:239 gui/options.cpp:1115
msgid "Volume"
msgstr "³ãçÝöáâì"
-#: gui/launcher.cpp:236 gui/options.cpp:1048
+#: gui/launcher.cpp:241 gui/options.cpp:1117
msgctxt "lowres"
msgid "Volume"
msgstr "³ãçÝ."
-#: gui/launcher.cpp:239
+#: gui/launcher.cpp:244
msgid "Override global volume settings"
msgstr "¿ÕàÕÚàØâØ ÓÛÞÑÐÛìÝö ãáâÐÝÞÒÚØ ÓãçÝÞáâö"
-#: gui/launcher.cpp:241
+#: gui/launcher.cpp:246
msgctxt "lowres"
msgid "Override global volume settings"
msgstr "¿ÕàÕÚàØâØ ÓÛÞÑÐÛìÝö ãáâÐÝÞÒÚØ ÓãçÝÞáâö"
-#: gui/launcher.cpp:248 gui/options.cpp:1056
+#: gui/launcher.cpp:254 gui/options.cpp:1125
msgid "MIDI"
msgstr "MIDI"
-#: gui/launcher.cpp:251
+#: gui/launcher.cpp:257
msgid "Override global MIDI settings"
msgstr "¿ÕàÕÚàØâØ ÓÛÞÑÐÛìÝö ãáâÐÝÞÒÚØ MIDI"
-#: gui/launcher.cpp:253
+#: gui/launcher.cpp:259
msgctxt "lowres"
msgid "Override global MIDI settings"
msgstr "¿ÕàÕÚàØâØ ÓÛÞÑÐÛìÝö ãáâÐÝÞÒÚØ MIDI"
-#: gui/launcher.cpp:263 gui/options.cpp:1062
+#: gui/launcher.cpp:268 gui/options.cpp:1131
msgid "MT-32"
msgstr "MT-32"
-#: gui/launcher.cpp:266
+#: gui/launcher.cpp:271
msgid "Override global MT-32 settings"
msgstr "¿ÕàÕÚàØâØ ÓÛÞÑÐÛìÝö ãáâÐÝÞÒÚØ MT-32"
-#: gui/launcher.cpp:268
+#: gui/launcher.cpp:273
msgctxt "lowres"
msgid "Override global MT-32 settings"
msgstr "¿ÕàÕÚàØâØ ÓÛÞÑÐÛìÝö ãáâÐÝÞÒÚØ MT-32"
-#: gui/launcher.cpp:279 gui/options.cpp:1069
+#: gui/launcher.cpp:282 gui/options.cpp:1138
msgid "Paths"
msgstr "ÈÛïåØ"
-#: gui/launcher.cpp:281 gui/options.cpp:1071
+#: gui/launcher.cpp:284 gui/options.cpp:1140
msgctxt "lowres"
msgid "Paths"
msgstr "ÈÛïåØ"
-#: gui/launcher.cpp:288
+#: gui/launcher.cpp:291
msgid "Game Path:"
msgstr "ÈÛïå ÔÞ ÓàØ:"
-#: gui/launcher.cpp:290
+#: gui/launcher.cpp:293
msgctxt "lowres"
msgid "Game Path:"
msgstr "ÈÛïå ÔÞ ÓàØ:"
-#: gui/launcher.cpp:295 gui/options.cpp:1091
+#: gui/launcher.cpp:298 gui/options.cpp:1164
msgid "Extra Path:"
msgstr "´ÞÔÐâÚ. èÛïå:"
-#: gui/launcher.cpp:295 gui/launcher.cpp:297 gui/launcher.cpp:298
+#: gui/launcher.cpp:298 gui/launcher.cpp:300 gui/launcher.cpp:301
msgid "Specifies path to additional data used the game"
msgstr "²ÚÐ×ãô èÛïå ÔÞ ÔÞÔÐâÚÞÒØå äÐÙÛöÒ ÔÐÝØå ÔÛï ÓàØ"
-#: gui/launcher.cpp:297 gui/options.cpp:1093
+#: gui/launcher.cpp:300 gui/options.cpp:1166
msgctxt "lowres"
msgid "Extra Path:"
msgstr "´ÞÔ. èÛïå:"
-#: gui/launcher.cpp:302 gui/options.cpp:1079
+#: gui/launcher.cpp:307 gui/options.cpp:1148
msgid "Save Path:"
msgstr "ÈÛïå ×ÑÕà.:"
-#: gui/launcher.cpp:302 gui/launcher.cpp:304 gui/launcher.cpp:305
-#: gui/options.cpp:1079 gui/options.cpp:1081 gui/options.cpp:1082
+#: gui/launcher.cpp:307 gui/launcher.cpp:309 gui/launcher.cpp:310
+#: gui/options.cpp:1148 gui/options.cpp:1150 gui/options.cpp:1151
msgid "Specifies where your savegames are put"
msgstr "²ÚÐ×ãô èÛïå ÔÞ ×ÑÕàÕÖÕÝì ÓàØ"
-#: gui/launcher.cpp:304 gui/options.cpp:1081
+#: gui/launcher.cpp:309 gui/options.cpp:1150
msgctxt "lowres"
msgid "Save Path:"
msgstr "ÈÛïå ×ÑÕà.:"
-#: gui/launcher.cpp:321 gui/launcher.cpp:404 gui/launcher.cpp:453
-#: gui/options.cpp:1088 gui/options.cpp:1094 gui/options.cpp:1101
-#: gui/options.cpp:1202 gui/options.cpp:1208 gui/options.cpp:1214
-#: gui/options.cpp:1222 gui/options.cpp:1246 gui/options.cpp:1250
-#: gui/options.cpp:1256 gui/options.cpp:1263 gui/options.cpp:1362
+#: gui/launcher.cpp:329 gui/launcher.cpp:416 gui/launcher.cpp:469
+#: gui/launcher.cpp:523 gui/options.cpp:1159 gui/options.cpp:1167
+#: gui/options.cpp:1176 gui/options.cpp:1283 gui/options.cpp:1289
+#: gui/options.cpp:1297 gui/options.cpp:1327 gui/options.cpp:1333
+#: gui/options.cpp:1340 gui/options.cpp:1433 gui/options.cpp:1436
+#: gui/options.cpp:1448
msgctxt "path"
msgid "None"
msgstr "½Õ ×ÐÒÔÐÝØÙ"
-#: gui/launcher.cpp:326 gui/launcher.cpp:408
+#: gui/launcher.cpp:334 gui/launcher.cpp:422 gui/launcher.cpp:527
+#: gui/options.cpp:1277 gui/options.cpp:1321 gui/options.cpp:1439
#: backends/platform/wii/options.cpp:56
msgid "Default"
msgstr "·Ð ãÜÞÒçÐÝÝïÜ"
-#: gui/launcher.cpp:446 gui/options.cpp:1356
+#: gui/launcher.cpp:462 gui/options.cpp:1442
msgid "Select SoundFont"
msgstr "²ØÑÕàöâì SoundFont"
-#: gui/launcher.cpp:465 gui/launcher.cpp:612
+#: gui/launcher.cpp:481 gui/launcher.cpp:636
msgid "Select directory with game data"
msgstr "²ØÑÕàöâì ßÐßÚã × äÐÙÛÐÜØ ÓàØ"
-#: gui/launcher.cpp:483
+#: gui/launcher.cpp:499
msgid "Select additional game directory"
msgstr "²ØÑÕàöâì ÔÞÔÐâÚÞÒã ßÐßÚã ÓàØ"
-#: gui/launcher.cpp:495
+#: gui/launcher.cpp:511
msgid "Select directory for saved games"
msgstr "²ØÑÕàöâì ßÐßÚã ÔÛï ×ÑÕàÕÖÕÝì"
-#: gui/launcher.cpp:514
+#: gui/launcher.cpp:538
msgid "This game ID is already taken. Please choose another one."
msgstr "ÆÕÙ ID ÓàØ ÒÖÕ ÒØÚÞàØáâÞÒãôâìáï. ±ãÔì ÛÐáÚÐ, ÒØÑÕàöâì öÝèØÙ."
-#: gui/launcher.cpp:555 engines/dialogs.cpp:110
+#: gui/launcher.cpp:579 engines/dialogs.cpp:110
msgid "~Q~uit"
msgstr "~²~ØåöÔ"
-#: gui/launcher.cpp:555 backends/platform/sdl/macosx/appmenu_osx.mm:80
+#: gui/launcher.cpp:579 backends/platform/sdl/macosx/appmenu_osx.mm:96
msgid "Quit ScummVM"
msgstr "²ØåöÔ ×ö ScummVM"
-#: gui/launcher.cpp:556
+#: gui/launcher.cpp:580
msgid "A~b~out..."
msgstr "¿àÞ ß~à~ÞÓàÐÜã..."
-#: gui/launcher.cpp:556 backends/platform/sdl/macosx/appmenu_osx.mm:61
+#: gui/launcher.cpp:580 backends/platform/sdl/macosx/appmenu_osx.mm:70
msgid "About ScummVM"
msgstr "¿àÞ ScummVM"
-#: gui/launcher.cpp:557
+#: gui/launcher.cpp:581
msgid "~O~ptions..."
msgstr "~½~ÐÛÐèâãÒÐÝÝï"
-#: gui/launcher.cpp:557
+#: gui/launcher.cpp:581
msgid "Change global ScummVM options"
msgstr "·ÜöÝØâØ ÓÛÞÑÐÛìÝö ÝÐÛÐèâãÒÐÝÝï ScummVM"
-#: gui/launcher.cpp:559
+#: gui/launcher.cpp:583
msgid "~S~tart"
msgstr "·~Ð~ßãáÚ"
-#: gui/launcher.cpp:559
+#: gui/launcher.cpp:583
msgid "Start selected game"
msgstr "·ÐßãáâØâØ ÒØÑàÐÝã Óàã"
-#: gui/launcher.cpp:562
+#: gui/launcher.cpp:586
msgid "~L~oad..."
msgstr "~·~ÐÒÐÝâÐÖØâØ..."
-#: gui/launcher.cpp:562
+#: gui/launcher.cpp:586
msgid "Load savegame for selected game"
msgstr "·ÐÒÐÝâÐÖØâØ ×ÑÕàÕÖÕÝÝï ÔÛï ÒØÑàÐÝÞ÷ ÓàØ"
-#: gui/launcher.cpp:567 gui/launcher.cpp:1055
+#: gui/launcher.cpp:591 gui/launcher.cpp:1079
msgid "~A~dd Game..."
msgstr "~´~ÞÔÐâØ Óàã..."
-#: gui/launcher.cpp:567 gui/launcher.cpp:574
+#: gui/launcher.cpp:591 gui/launcher.cpp:598
msgid "Hold Shift for Mass Add"
msgstr "ÃâàØÜãÙâÕ ÚÛÐÒöèã Shift ÔÛï âÞÓÞ, éÞÑ ÔÞÔÐâØ ÔÕÚöÛìÚÐ öÓÞà"
-#: gui/launcher.cpp:569
+#: gui/launcher.cpp:593
msgid "~E~dit Game..."
msgstr "ÀÕÔÐ~Ó~ãÒÐâØ Óàã"
-#: gui/launcher.cpp:569 gui/launcher.cpp:576
+#: gui/launcher.cpp:593 gui/launcher.cpp:600
msgid "Change game options"
msgstr "·ÜöÝØâØ ÝÐÛÐèâãÒÐÝÝï ÓàØ"
-#: gui/launcher.cpp:571
+#: gui/launcher.cpp:595
msgid "~R~emove Game"
msgstr "~²~ØÔÐÛØâØ Óàã"
-#: gui/launcher.cpp:571 gui/launcher.cpp:578
+#: gui/launcher.cpp:595 gui/launcher.cpp:602
msgid "Remove game from the list. The game data files stay intact"
msgstr "²ØÔÐÛØâØ Óàã ×ö áßØáÚã. ½Õ ÒØÔÐÛïô Óàã × ÖÞàáâÚÞÓÞ ÔØáÚã"
-#: gui/launcher.cpp:574 gui/launcher.cpp:1055
+#: gui/launcher.cpp:598 gui/launcher.cpp:1079
msgctxt "lowres"
msgid "~A~dd Game..."
msgstr "~´~ÞÔÐâØ Óàã..."
-#: gui/launcher.cpp:576
+#: gui/launcher.cpp:600
msgctxt "lowres"
msgid "~E~dit Game..."
msgstr "ÀÕÔÐ~Ó~. Óàã..."
-#: gui/launcher.cpp:578
+#: gui/launcher.cpp:602
msgctxt "lowres"
msgid "~R~emove Game"
msgstr "~²~ØÔÐÛØâØ Óàã"
-#: gui/launcher.cpp:586
+#: gui/launcher.cpp:610
msgid "Search in game list"
msgstr "¿ÞèãÚ ã áßØáÚã öÓÞà"
-#: gui/launcher.cpp:590 gui/launcher.cpp:1102
+#: gui/launcher.cpp:614 gui/launcher.cpp:1126
msgid "Search:"
msgstr "¿ÞèãÚ:"
-#: gui/launcher.cpp:593 gui/options.cpp:826
-msgid "Clear value"
-msgstr "¾çØáâØâØ ×ÝÐçÕÝÝï"
-
-#: gui/launcher.cpp:615 engines/dialogs.cpp:114 engines/mohawk/myst.cpp:255
+#: gui/launcher.cpp:639 engines/dialogs.cpp:114 engines/mohawk/myst.cpp:255
#: engines/mohawk/riven.cpp:716 engines/cruise/menu.cpp:216
msgid "Load game:"
msgstr "·ÐÒÐÝâÐÖØâØ Óàã:"
-#: gui/launcher.cpp:615 engines/dialogs.cpp:114 engines/scumm/dialogs.cpp:188
+#: gui/launcher.cpp:639 engines/dialogs.cpp:114 engines/scumm/dialogs.cpp:188
#: engines/mohawk/myst.cpp:255 engines/mohawk/riven.cpp:716
#: engines/cruise/menu.cpp:216 backends/platform/wince/CEActionsPocket.cpp:267
#: backends/platform/wince/CEActionsSmartphone.cpp:231
msgid "Load"
msgstr "·ÐÒÐÝâÐÖØâØ"
-#: gui/launcher.cpp:723
+#: gui/launcher.cpp:747
msgid ""
"Do you really want to run the mass game detector? This could potentially add "
"a huge number of games."
@@ -452,7 +455,7 @@ msgstr ""
"ÇØ ÒØ ÔöÙáÝÞ åÞçÕâÕ ×ÐßãáâØâØ ßÞèãÚ ãáöå öÓÞà? ÆÕ ßÞâÕÝæöÙÝÞ ÜÞÖÕ ÔÞÔÐâØ "
"ÒÕÛØÚã ÚöÛìÚöáâì öÓÞà."
-#: gui/launcher.cpp:724 gui/launcher.cpp:872
+#: gui/launcher.cpp:748 gui/launcher.cpp:896
#: backends/events/symbiansdl/symbiansdl-events.cpp:184
#: backends/platform/wince/CEActionsPocket.cpp:326
#: backends/platform/wince/CEActionsSmartphone.cpp:287
@@ -460,7 +463,7 @@ msgstr ""
msgid "Yes"
msgstr "ÂÐÚ"
-#: gui/launcher.cpp:724 gui/launcher.cpp:872
+#: gui/launcher.cpp:748 gui/launcher.cpp:896
#: backends/events/symbiansdl/symbiansdl-events.cpp:184
#: backends/platform/wince/CEActionsPocket.cpp:326
#: backends/platform/wince/CEActionsSmartphone.cpp:287
@@ -468,36 +471,36 @@ msgstr "ÂÐÚ"
msgid "No"
msgstr "½ö"
-#: gui/launcher.cpp:772
+#: gui/launcher.cpp:796
msgid "ScummVM couldn't open the specified directory!"
msgstr "ScummVM ÝÕ ÜÞÖÕ ÒöÔÚàØâØ ÒÚÐ×ÐÝã ßÐßÚã!"
-#: gui/launcher.cpp:784
+#: gui/launcher.cpp:808
msgid "ScummVM could not find any game in the specified directory!"
msgstr "ScummVM ÝÕ ÜÞÖÕ ×ÝÐÙâØ Óàã ã ÒÚÐ×ÐÝöÙ ßÐßæö!"
-#: gui/launcher.cpp:798
+#: gui/launcher.cpp:822
msgid "Pick the game:"
msgstr "²ØÑÕàöâì Óàã:"
-#: gui/launcher.cpp:872
+#: gui/launcher.cpp:896
msgid "Do you really want to remove this game configuration?"
msgstr "²Ø ÔöÙáÝÞ åÞçÕâÕ ÒØÔÐÛØâØ ãáâÐÝÞÒÚØ ÔÛï æöô÷ ÓàØ?"
-#: gui/launcher.cpp:936
+#: gui/launcher.cpp:960
msgid "This game does not support loading games from the launcher."
msgstr "Æï ÓàÐ ÝÕ ßöÔâàØÜãô ×ÐÒÐÝâÐÖÕÝÝï ×ÑÕàÕÖÕÝì çÕàÕ× ÓÞÛÞÒÝÕ ÜÕÝî."
-#: gui/launcher.cpp:940
+#: gui/launcher.cpp:964
msgid "ScummVM could not find any engine capable of running the selected game!"
msgstr "ScummVM ÝÕ ×ÜöÓ ×ÝÐÙâØ ÔÒØÖÞÚ ÔÛï ×ÐßãáÚã ÒØÑàÐÝÞ÷ ÓàØ!"
-#: gui/launcher.cpp:1054
+#: gui/launcher.cpp:1078
msgctxt "lowres"
msgid "Mass Add..."
msgstr "´ÞÔ. ÑÐÓÐâÞ..."
-#: gui/launcher.cpp:1054
+#: gui/launcher.cpp:1078
msgid "Mass Add..."
msgstr "´ÞÔ. ÑÐÓÐâÞ..."
@@ -524,141 +527,141 @@ msgstr "¿àÞÓÛïÝãâÞ %d ßÐßÞÚ ..."
msgid "Discovered %d new games, ignored %d previously added games ..."
msgstr "·ÝÐÙÔÕÝÞ %d ÝÞÒØå öÓÞà, ßàÞßãéÕÝÞ %d ßÞßÕàÕÔÝìÞ ÔÞÔÐÝØå öÓÞà ..."
-#: gui/options.cpp:72
+#: gui/options.cpp:78
msgid "Never"
msgstr "½öÚÞÛØ"
-#: gui/options.cpp:72
+#: gui/options.cpp:78
msgid "every 5 mins"
msgstr "ÚÞÖÝö 5 åÒ"
-#: gui/options.cpp:72
+#: gui/options.cpp:78
msgid "every 10 mins"
msgstr "ÚÞÖÝö 10 åÒ"
-#: gui/options.cpp:72
+#: gui/options.cpp:78
msgid "every 15 mins"
msgstr "ÚÞÖÝö 15 åÒ"
-#: gui/options.cpp:72
+#: gui/options.cpp:78
msgid "every 30 mins"
msgstr "ÚÞÖÝö 30 åÒ"
-#: gui/options.cpp:74
+#: gui/options.cpp:80
msgid "8 kHz"
msgstr "8 Ú³æ"
-#: gui/options.cpp:74
+#: gui/options.cpp:80
msgid "11kHz"
msgstr "11 Ú³æ"
-#: gui/options.cpp:74
+#: gui/options.cpp:80
msgid "22 kHz"
msgstr "22 Ú³æ"
-#: gui/options.cpp:74
+#: gui/options.cpp:80
msgid "44 kHz"
msgstr "44 Ú³æ"
-#: gui/options.cpp:74
+#: gui/options.cpp:80
msgid "48 kHz"
msgstr "48 Ú³æ"
-#: gui/options.cpp:236 gui/options.cpp:464 gui/options.cpp:559
-#: gui/options.cpp:625 gui/options.cpp:825
+#: gui/options.cpp:257 gui/options.cpp:485 gui/options.cpp:586
+#: gui/options.cpp:659 gui/options.cpp:868
msgctxt "soundfont"
msgid "None"
msgstr "½Õ ×ÐÔÐÝØÙ"
-#: gui/options.cpp:372
+#: gui/options.cpp:393
msgid "Failed to apply some of the graphic options changes:"
msgstr "½Õ ÒÔÐÛÞáï ×ÐáâÞáãÒÐâØ ÔÕïÚö ×ö ×ÜöÝ ÓàÐäöçÝØå ÝÐÛÐèâãÒÐÝì:"
-#: gui/options.cpp:384
+#: gui/options.cpp:405
msgid "the video mode could not be changed."
msgstr "ÝÕ ÒÔÐÛÞáï ×ÜöÝØâØ ÓàÐäöçÝØÙ àÕÖØÜ."
-#: gui/options.cpp:390
+#: gui/options.cpp:411
msgid "the fullscreen setting could not be changed"
msgstr "ÝÕ ÒÔÐÛÞáï ×ÜöÝØâØ àÕÖØÜ ßÞÒÝÞÓÞ ÕÚàÐÝã"
-#: gui/options.cpp:396
+#: gui/options.cpp:417
msgid "the aspect ratio setting could not be changed"
msgstr "ÝÕ ÒÔÐÛÞáï ×ÜöÝØâØ àÕÖØÜ ÚÞàÕÚæö÷ áßöÒÒöÔÝÞèÕÝÝï áâÞàöÝ"
-#: gui/options.cpp:705
+#: gui/options.cpp:742
msgid "Graphics mode:"
msgstr "³àÐäöçÝ. àÕÖØÜ:"
-#: gui/options.cpp:716
+#: gui/options.cpp:756
msgid "Render mode:"
msgstr "ÀÕÖØÜ àÐáâàãÒ.:"
-#: gui/options.cpp:716 gui/options.cpp:717
+#: gui/options.cpp:756 gui/options.cpp:757
msgid "Special dithering modes supported by some games"
msgstr "ÁßÕæöÐÛìÝö àÕÖØÜØ àÐáâàãÒÐÝÝï, ïÚö ßöÔâàØÜãîâì ÔÕïÚö öÓàØ"
-#: gui/options.cpp:726
+#: gui/options.cpp:768
#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2248
-#: backends/graphics/openglsdl/openglsdl-graphics.cpp:476
+#: backends/graphics/openglsdl/openglsdl-graphics.cpp:472
msgid "Fullscreen mode"
msgstr "¿ÞÒÝÞÕÚàÐÝÝØÙ àÕÖØÜ"
-#: gui/options.cpp:729
+#: gui/options.cpp:771
msgid "Aspect ratio correction"
msgstr "ºÞàÕÚæöï áßöÒÒöÔÝÞèÕÝÝï áâÞàöÝ"
-#: gui/options.cpp:729
+#: gui/options.cpp:771
msgid "Correct aspect ratio for 320x200 games"
msgstr "ºÞàØÓãÒÐâØ áßöÒÒöÔÝÞèÕÝÝï áâÞàöÝ ÔÛï öÓÞà × ÓàÐäöÚÞî 320x200"
-#: gui/options.cpp:730
+#: gui/options.cpp:772
msgid "EGA undithering"
msgstr "EGA ÑÕ× àÐáâàãÒÐÝÝï"
-#: gui/options.cpp:730
+#: gui/options.cpp:772
msgid "Enable undithering in EGA games that support it"
msgstr "²öÜÚÝãâØ àÐáâàãÒÐÝÝï Ò EGA öÓàÐå ïÚö æÕ ßöÔâàØÜãîâì"
-#: gui/options.cpp:738
+#: gui/options.cpp:780
msgid "Preferred Device:"
msgstr "ÃßÞÔÞÑÐÝØÙ ßàØáâàöÙ:"
-#: gui/options.cpp:738
+#: gui/options.cpp:780
msgid "Music Device:"
msgstr "¼ã×Øç. ßàØáâàöÙ:"
-#: gui/options.cpp:738 gui/options.cpp:740
+#: gui/options.cpp:780 gui/options.cpp:782
msgid "Specifies preferred sound device or sound card emulator"
msgstr "²ÚÐ×ãô ãßÞÔÞÑÐÝØÙ ×ÒãÚÞÒØÙ ßàØáâàöÙ ÐÑÞ ÕÜãÛïâÞà ×ÒãÚÞÒÞ÷ ÚÐàâØ"
-#: gui/options.cpp:738 gui/options.cpp:740 gui/options.cpp:741
+#: gui/options.cpp:780 gui/options.cpp:782 gui/options.cpp:783
msgid "Specifies output sound device or sound card emulator"
msgstr "²ÚÐ×ãô ÒØåöÔÝØÙ ×ÒãÚÞÒØÙ ßàØáâàöÙ ÐÑÞ ÕÜãÛïâÞà ×ÒãÚÞÒÞ÷ ÚÐàâØ"
-#: gui/options.cpp:740
+#: gui/options.cpp:782
msgctxt "lowres"
msgid "Preferred Dev.:"
msgstr "ÃßÞÔÞÑ. ßàØáâàöÙ:"
-#: gui/options.cpp:740
+#: gui/options.cpp:782
msgctxt "lowres"
msgid "Music Device:"
msgstr "¼ã×ØçÝØÙ ßàØáâàöÙ:"
-#: gui/options.cpp:766
+#: gui/options.cpp:809
msgid "AdLib emulator:"
msgstr "µÜãÛïâÞà AdLib:"
-#: gui/options.cpp:766 gui/options.cpp:767
+#: gui/options.cpp:809 gui/options.cpp:810
msgid "AdLib is used for music in many games"
msgstr "·ÒãÚÞÒÐ ÚÐàâÐ AdLib ÒØÚÞàØáâÞÒãôâìáï ÑÐÓÐâìÜÐ öÓàÐÜØ"
-#: gui/options.cpp:777
+#: gui/options.cpp:820
msgid "Output rate:"
msgstr "²ØåöÔÝÐ çÐáâÞâÐ:"
-#: gui/options.cpp:777 gui/options.cpp:778
+#: gui/options.cpp:820 gui/options.cpp:821
msgid ""
"Higher value specifies better sound quality but may be not supported by your "
"soundcard"
@@ -666,63 +669,63 @@ msgstr ""
"²ÕÛØÚö ×ÝÐçÕÝÝï ×ÐÔÐîâì ÚàÐéã ïÚöáâì ×ÒãÚã, ßàÞâÕ ÒÞÝØ ÜÞÖãâì ÝÕ "
"ßöÔâàØÜãÒÐâØáï ÒÐèÞî ×ÒãÚÞÒÞî ÚÐàâÞî"
-#: gui/options.cpp:788
+#: gui/options.cpp:831
msgid "GM Device:"
msgstr "¿àØáâàöÙ GM:"
-#: gui/options.cpp:788
+#: gui/options.cpp:831
msgid "Specifies default sound device for General MIDI output"
msgstr "²ÚÐ×ãô ÒØåöÔÝØÙ ×ÒãÚÞÒØÙ ßàØáâàöÙ ÔÛï General MIDI"
-#: gui/options.cpp:799
+#: gui/options.cpp:842
msgid "Don't use General MIDI music"
msgstr "½Õ ÒØÚÞàØáâÞÒãÒÐâØ Üã×ØÚã General MIDI"
-#: gui/options.cpp:810 gui/options.cpp:871
+#: gui/options.cpp:853 gui/options.cpp:915
msgid "Use first available device"
msgstr "²ØÚÞàØáâÞÒãÒÐâØ ßÕàèØÙ ÝÐïÒÝØÙ ßàØáâàöÙ"
-#: gui/options.cpp:822
+#: gui/options.cpp:865
msgid "SoundFont:"
msgstr "SoundFont:"
-#: gui/options.cpp:822 gui/options.cpp:824 gui/options.cpp:825
+#: gui/options.cpp:865 gui/options.cpp:867 gui/options.cpp:868
msgid "SoundFont is supported by some audio cards, Fluidsynth and Timidity"
msgstr ""
"SoundFont ßöÔâàØÜãôâìáï ÔÕïÚØÜØ ×ÒãÚÞÒØÜØ ÚÐàâÐÜØ, Fluidsynth âÐ Timidity"
-#: gui/options.cpp:824
+#: gui/options.cpp:867
msgctxt "lowres"
msgid "SoundFont:"
msgstr "SoundFont:"
-#: gui/options.cpp:829
+#: gui/options.cpp:873
msgid "Mixed AdLib/MIDI mode"
msgstr "·ÜöèÐÝØÙ àÕÖØÜ AdLib/MIDI"
-#: gui/options.cpp:829
+#: gui/options.cpp:873
msgid "Use both MIDI and AdLib sound generation"
msgstr "²ØÚÞàØáâÞÒãÒÐâØ ö MIDI ö AdLib ÔÛï ÓÕÝÕàÐæö÷ ×ÒãÚã"
-#: gui/options.cpp:832
+#: gui/options.cpp:876
msgid "MIDI gain:"
msgstr "¿ÞáØÛÕÝÝï MIDI:"
-#: gui/options.cpp:842
+#: gui/options.cpp:886
msgid "MT-32 Device:"
msgstr "¿àØáâàöÙ MT-32:"
-#: gui/options.cpp:842
+#: gui/options.cpp:886
msgid "Specifies default sound device for Roland MT-32/LAPC1/CM32l/CM64 output"
msgstr ""
"²ÚÐ×ãô ×ÒãÚÞÒØÙ ßàØáâàöÙ ×Ð ãÜÞÒçÐÝÝïÜ ÔÛï ÒØÒÞÔã ÝÐ Roland MT-32/LAPC1/"
"CM32l/CM64"
-#: gui/options.cpp:847
+#: gui/options.cpp:891
msgid "True Roland MT-32 (disable GM emulation)"
msgstr "ÁßàÐÒÖÝöÙ Roland MT-32 (ÒØÜÚÝãâØ ÕÜãÛïæØî GM)"
-#: gui/options.cpp:847 gui/options.cpp:849
+#: gui/options.cpp:891 gui/options.cpp:893
msgid ""
"Check if you want to use your real hardware Roland-compatible sound device "
"connected to your computer"
@@ -730,193 +733,193 @@ msgstr ""
"²öÔÜöâìâÕ, ïÚéÞ ã ÒÐá ßöÔÚÛîçÕÝÞ Roland-áãÜöáÝØÙ ×ÒãÚÞÒØÙ ßàØáâàöÙ ö ÒØ "
"åÞçÕâÕ ÙÞÓÞ ÒØÚÞàØáâÞÒãÒÐâØ"
-#: gui/options.cpp:849
+#: gui/options.cpp:893
msgctxt "lowres"
msgid "True Roland MT-32 (no GM emulation)"
msgstr "ÁßàÐÒÖÝöÙ Roland MT-32 (ÒØÜÚÝãâØ ÕÜãÛïæØî GM)"
-#: gui/options.cpp:852
+#: gui/options.cpp:896
msgid "Enable Roland GS Mode"
msgstr "ÃÒöÜÚÝãâØ àÕÖØÜ Roland GS"
-#: gui/options.cpp:852
+#: gui/options.cpp:896
msgid "Turns off General MIDI mapping for games with Roland MT-32 soundtrack"
msgstr ""
"²ØÜØÚÐô ÜÐßöÝÓ General MIDI ÔÛï öÓÞà ×ö ×ÒãÚÞÒÞî ÔÞàöÖÚÞî ÔÛï Roland MT-32"
-#: gui/options.cpp:861
+#: gui/options.cpp:905
msgid "Don't use Roland MT-32 music"
msgstr "½Õ ÒØÚÞàØáâÞÒãÒÐâØ Roland MT-32"
-#: gui/options.cpp:888
+#: gui/options.cpp:932
msgid "Text and Speech:"
msgstr "ÂÕÚáâ ö Þ×ÒãçÚÐ:"
-#: gui/options.cpp:892 gui/options.cpp:902
+#: gui/options.cpp:936 gui/options.cpp:946
msgid "Speech"
msgstr "¾×ÒãçÚÐ"
-#: gui/options.cpp:893 gui/options.cpp:903
+#: gui/options.cpp:937 gui/options.cpp:947
msgid "Subtitles"
msgstr "ÁãÑâØâàØ"
-#: gui/options.cpp:894
+#: gui/options.cpp:938
msgid "Both"
msgstr "²áÕ"
-#: gui/options.cpp:896
+#: gui/options.cpp:940
msgid "Subtitle speed:"
msgstr "ÈÒØÔ. áãÑâØâàöÒ:"
-#: gui/options.cpp:898
+#: gui/options.cpp:942
msgctxt "lowres"
msgid "Text and Speech:"
msgstr "ÂÕÚáâ ö Þ×ÒãçÚÐ:"
-#: gui/options.cpp:902
+#: gui/options.cpp:946
msgid "Spch"
msgstr "¾×Ò"
-#: gui/options.cpp:903
+#: gui/options.cpp:947
msgid "Subs"
msgstr "狄"
-#: gui/options.cpp:904
+#: gui/options.cpp:948
msgctxt "lowres"
msgid "Both"
msgstr "²áÕ"
-#: gui/options.cpp:904
+#: gui/options.cpp:948
msgid "Show subtitles and play speech"
msgstr "¿ÞÚÐ×ãÒÐâØ áãÑâØâàØ ö ÒöÔâÒÞàîÒÐâØ ÜÞÒã"
-#: gui/options.cpp:906
+#: gui/options.cpp:950
msgctxt "lowres"
msgid "Subtitle speed:"
msgstr "ÈÒØÔ. áãÑâØâàöÒ:"
-#: gui/options.cpp:922
+#: gui/options.cpp:966
msgid "Music volume:"
msgstr "³ãçÝöáâì Üã×ØÚØ:"
-#: gui/options.cpp:924
+#: gui/options.cpp:968
msgctxt "lowres"
msgid "Music volume:"
msgstr "³ãçÝöáâì Üã×ØÚØ:"
-#: gui/options.cpp:931
+#: gui/options.cpp:975
msgid "Mute All"
msgstr "²ØÜÚÝãâØ ÒáÕ"
-#: gui/options.cpp:934
+#: gui/options.cpp:978
msgid "SFX volume:"
msgstr "³ãçÝöáâì ÕäÕÚâöÒ:"
-#: gui/options.cpp:934 gui/options.cpp:936 gui/options.cpp:937
+#: gui/options.cpp:978 gui/options.cpp:980 gui/options.cpp:981
msgid "Special sound effects volume"
msgstr "³ãçÝöáâì áßÕæöÐÛìÝØå ×ÒãÚÞÒØå ÕäÕÚâöÒ"
-#: gui/options.cpp:936
+#: gui/options.cpp:980
msgctxt "lowres"
msgid "SFX volume:"
msgstr "³ãçÝ. ÕäÕÚâöÒ:"
-#: gui/options.cpp:944
+#: gui/options.cpp:988
msgid "Speech volume:"
msgstr "³ãçÝöáâì Þ×ÒãçÚØ:"
-#: gui/options.cpp:946
+#: gui/options.cpp:990
msgctxt "lowres"
msgid "Speech volume:"
msgstr "³ãçÝ. Þ×ÒãçÚØ:"
-#: gui/options.cpp:1085
+#: gui/options.cpp:1156
msgid "Theme Path:"
msgstr "ÈÛïå ÔÞ âÕÜ:"
-#: gui/options.cpp:1087
+#: gui/options.cpp:1158
msgctxt "lowres"
msgid "Theme Path:"
msgstr "ÈÛïå ÔÞ âÕÜ:"
-#: gui/options.cpp:1091 gui/options.cpp:1093 gui/options.cpp:1094
+#: gui/options.cpp:1164 gui/options.cpp:1166 gui/options.cpp:1167
msgid "Specifies path to additional data used by all games or ScummVM"
msgstr ""
"²ÚÐ×ãô èÛïå ÔÞ ÔÞÔÐâÚÞÒØå äÐÙÛöÒ ÔÐÝØå, ïÚö ÒØÚÞàØáâÞÒãîâìáï ãáöÜÐ öÓàÐÜØ "
"ÐÑÞ ScummVM"
-#: gui/options.cpp:1098
+#: gui/options.cpp:1173
msgid "Plugins Path:"
msgstr "ÈÛïå ÔÞ ÒâãÛÚöÒ:"
-#: gui/options.cpp:1100
+#: gui/options.cpp:1175
msgctxt "lowres"
msgid "Plugins Path:"
msgstr "ÈÛïå ÔÞ ÒâãÛÚöÒ:"
-#: gui/options.cpp:1109
+#: gui/options.cpp:1184
msgid "Misc"
msgstr "Àö×ÝÕ"
-#: gui/options.cpp:1111
+#: gui/options.cpp:1186
msgctxt "lowres"
msgid "Misc"
msgstr "Àö×ÝÕ"
-#: gui/options.cpp:1113
+#: gui/options.cpp:1188
msgid "Theme:"
msgstr "ÂÕÜÐ:"
-#: gui/options.cpp:1117
+#: gui/options.cpp:1192
msgid "GUI Renderer:"
msgstr "ÀÐáâÕà. GUI:"
-#: gui/options.cpp:1129
+#: gui/options.cpp:1204
msgid "Autosave:"
msgstr "°ÒâÞ×ÑÕàÕÖÕÝÝï:"
-#: gui/options.cpp:1131
+#: gui/options.cpp:1206
msgctxt "lowres"
msgid "Autosave:"
msgstr "°ÒâÞ×ÑÕàÕÖ.:"
-#: gui/options.cpp:1139
+#: gui/options.cpp:1214
msgid "Keys"
msgstr "ºÛÐÒöèö"
-#: gui/options.cpp:1146
+#: gui/options.cpp:1221
msgid "GUI Language:"
msgstr "¼ÞÒÐ öÝâÕàä.:"
-#: gui/options.cpp:1146
+#: gui/options.cpp:1221
msgid "Language of ScummVM GUI"
msgstr "¼ÞÒÐ ÓàÐäöçÝÞÓÞ öÝâÕàäÕÙáã ScummVM"
-#: gui/options.cpp:1295
+#: gui/options.cpp:1372
msgid "You have to restart ScummVM before your changes will take effect."
msgstr "²Ø ßÞÒØÝÝö ßÕàÕ×ÐßãáâØâØ ScummVM éÞÑ ×ÐáâÞáãÒÐâØ ×ÜöÝØ."
-#: gui/options.cpp:1308
+#: gui/options.cpp:1385
msgid "Select directory for savegames"
msgstr "²ØÑÕàöâì ßÐßÚã ÔÛï ×ÑÕàÕÖÕÝì"
-#: gui/options.cpp:1315
+#: gui/options.cpp:1392
msgid "The chosen directory cannot be written to. Please select another one."
msgstr "½Õ ÜÞÖã ßØáÐâØ ã ÒØÑàÐÝã ßÐßÚã. ±ãÔì ÛÐáÚÐ, ÒÚÐÖöâì öÝèã."
-#: gui/options.cpp:1324
+#: gui/options.cpp:1401
msgid "Select directory for GUI themes"
msgstr "²ØÑÕàöâì ßÐßÚã ÔÛï âÕÜ GUI"
-#: gui/options.cpp:1334
+#: gui/options.cpp:1411
msgid "Select directory for extra files"
msgstr "²ØÑÕàöâì ßÐßÚã × ÔÞÔÐâÚÞÒØÜØ äÐÙÛÐÜØ"
-#: gui/options.cpp:1345
+#: gui/options.cpp:1422
msgid "Select directory for plugins"
msgstr "²ØÑÕàöâì ßÐßÚã ×ö ÒâãÛÚÐÜØ"
-#: gui/options.cpp:1389
+#: gui/options.cpp:1475
msgid ""
"The theme you selected does not support your current language. If you want "
"to use this theme you need to switch to another language first."
@@ -964,60 +967,64 @@ msgstr "·ÑÕàÕÖÕÝÝï ÑÕ× öÜÕÝö"
msgid "Select a Theme"
msgstr "²ØÑÕàöâì âÕÜã"
-#: gui/ThemeEngine.cpp:328
+#: gui/ThemeEngine.cpp:333
msgid "Disabled GFX"
msgstr "±Õ× ÓàÐäöÚØ"
-#: gui/ThemeEngine.cpp:328
+#: gui/ThemeEngine.cpp:333
msgctxt "lowres"
msgid "Disabled GFX"
msgstr "±Õ× ÓàÐäöÚØ"
-#: gui/ThemeEngine.cpp:329
+#: gui/ThemeEngine.cpp:334
msgid "Standard Renderer (16bpp)"
msgstr "ÁâÐÝÔÐàâÝØÙ àÐáâÕàØ×ÐâÞà (16bpp)"
-#: gui/ThemeEngine.cpp:329
+#: gui/ThemeEngine.cpp:334
msgid "Standard (16bpp)"
msgstr "ÁâÐÝÔÐàâÝØÙ àÐáâÕàØ×ÐâÞà (16bpp)"
-#: gui/ThemeEngine.cpp:331
+#: gui/ThemeEngine.cpp:336
msgid "Antialiased Renderer (16bpp)"
msgstr "ÀÐáâÕàØ×ÐâÞà ×ö ×ÓÛÐÔÖãÒÐÝÝïÜ (16bpp)"
-#: gui/ThemeEngine.cpp:331
+#: gui/ThemeEngine.cpp:336
msgid "Antialiased (16bpp)"
msgstr "ÀÐáâÕàØ×ÐâÞà ×ö ×ÓÛÐÔÖãÒÐÝÝïÜ (16bpp)"
+#: gui/widget.cpp:312 gui/widget.cpp:314 gui/widget.cpp:320 gui/widget.cpp:322
+msgid "Clear value"
+msgstr "¾çØáâØâØ ×ÝÐçÕÝÝï"
+
#: base/main.cpp:203
#, c-format
msgid "Engine does not support debug level '%s'"
msgstr "´ÒØÖÞÚ ÝÕ ßöÔâàØÜãô àöÒÕÝì ÒöÔÛÐÔÚØ '%s'"
-#: base/main.cpp:271
+#: base/main.cpp:275
msgid "Menu"
msgstr "¼ÕÝî"
-#: base/main.cpp:274 backends/platform/symbian/src/SymbianActions.cpp:45
+#: base/main.cpp:278 backends/platform/symbian/src/SymbianActions.cpp:45
#: backends/platform/wince/CEActionsPocket.cpp:45
#: backends/platform/wince/CEActionsSmartphone.cpp:46
msgid "Skip"
msgstr "¿àÞßãáâØâØ"
-#: base/main.cpp:277 backends/platform/symbian/src/SymbianActions.cpp:50
+#: base/main.cpp:281 backends/platform/symbian/src/SymbianActions.cpp:50
#: backends/platform/wince/CEActionsPocket.cpp:42
msgid "Pause"
msgstr "¿Ðã×Ð"
-#: base/main.cpp:280
+#: base/main.cpp:284
msgid "Skip line"
msgstr "¿àÞßãáâØâØ àïÔÞÚ"
-#: base/main.cpp:439
+#: base/main.cpp:455
msgid "Error running game:"
msgstr "¿ÞÜØÛÚÐ ×ÐßãáÚã ÓàØ:"
-#: base/main.cpp:463
+#: base/main.cpp:479
msgid "Could not find any engine capable of running the selected game"
msgstr "½Õ ÜÞÖã ×ÝÐÙâØ ÔÒØÖÞÚ ÔÛï ×ÐßãáÚã ÒØÑàÐÝÞ÷ ÓàØ"
@@ -1085,25 +1092,6 @@ msgstr "²öÔÜöÝÕÝÞ ÚÞàØáâãÒÐçÕÜ"
msgid "Unknown error"
msgstr "½ÕÒöÔÞÜÐ ßÞÜØÛÚÐ"
-#. I18N: Hercules is graphics card name
-#: common/util.cpp:275
-msgid "Hercules Green"
-msgstr "Hercules ·ÕÛÕÝØÙ"
-
-#: common/util.cpp:276
-msgid "Hercules Amber"
-msgstr "Hercules ±ãàèâØÝÝØÙ"
-
-#: common/util.cpp:283
-msgctxt "lowres"
-msgid "Hercules Green"
-msgstr "Hercules ·ÕÛÕÝØÙ"
-
-#: common/util.cpp:284
-msgctxt "lowres"
-msgid "Hercules Amber"
-msgstr "Hercules ±ãàèâØÝÝØÙ"
-
#: engines/advancedDetector.cpp:296
#, c-format
msgid "The game in '%s' seems to be unknown."
@@ -1151,12 +1139,12 @@ msgid "~R~eturn to Launcher"
msgstr "~¿~ÞÒÕà.Ò ÓÞÛÞÒÝÕ ÜÕÝî"
#: engines/dialogs.cpp:116 engines/cruise/menu.cpp:214
-#: engines/sci/engine/kfile.cpp:578
+#: engines/sci/engine/kfile.cpp:566
msgid "Save game:"
msgstr "·ÑÕàÕÓâØ Óàã: "
#: engines/dialogs.cpp:116 engines/scumm/dialogs.cpp:187
-#: engines/cruise/menu.cpp:214 engines/sci/engine/kfile.cpp:578
+#: engines/cruise/menu.cpp:214 engines/sci/engine/kfile.cpp:566
#: backends/platform/symbian/src/SymbianActions.cpp:44
#: backends/platform/wince/CEActionsPocket.cpp:43
#: backends/platform/wince/CEActionsPocket.cpp:267
@@ -1175,37 +1163,47 @@ msgstr ""
"README ÔÛï ÞáÝÞÒÝÞ÷ öÝÞàÜÐæö÷, Ð âÐÚÞÖ öÝáâàãÚæöÙ, ïÚ ÞâàØÜÐâØ ßÞÔÐÛìèã "
"ÔÞßÞÜÞÓã."
-#: engines/dialogs.cpp:316 engines/mohawk/dialogs.cpp:109
+#: engines/dialogs.cpp:243
+#, fuzzy, c-format
+msgid ""
+"Gamestate save failed (%s)! Please consult the README for basic information, "
+"and for instructions on how to obtain further assistance."
+msgstr ""
+"²ØÑÐçâÕ, æÕÙ ÔÒØÖÞÚ ÝÕ ßöÔâàØÜãô ÔÞÒöÔÚã ßÞ öÓàÐÜ. ±ãÔì-ÛÐáÚÐ, ÔØÒöâìáï äÐÙÛ "
+"README ÔÛï ÞáÝÞÒÝÞ÷ öÝÞàÜÐæö÷, Ð âÐÚÞÖ öÝáâàãÚæöÙ, ïÚ ÞâàØÜÐâØ ßÞÔÐÛìèã "
+"ÔÞßÞÜÞÓã."
+
+#: engines/dialogs.cpp:321 engines/mohawk/dialogs.cpp:109
#: engines/mohawk/dialogs.cpp:174
msgid "~O~K"
msgstr "~O~K"
-#: engines/dialogs.cpp:317 engines/mohawk/dialogs.cpp:110
+#: engines/dialogs.cpp:322 engines/mohawk/dialogs.cpp:110
#: engines/mohawk/dialogs.cpp:175
msgid "~C~ancel"
msgstr "²ö~Ô~ÜöÝÐ"
-#: engines/dialogs.cpp:320
+#: engines/dialogs.cpp:325
msgid "~K~eys"
msgstr "~º~ÛÐÒöèö"
-#: engines/engine.cpp:233
+#: engines/engine.cpp:235
msgid "Could not initialize color format."
msgstr "½Õ ÜÞÖã ÝÐÛÐèâãÒÐâØ äÞàÜÐâ ÚÞÛìÞàã."
-#: engines/engine.cpp:241
+#: engines/engine.cpp:243
msgid "Could not switch to video mode: '"
msgstr "½Õ ÒÔÐÛÞáï ßÕàÕÚÛîçØâØ ÒöÔÕÞàÕÖØÜ: '"
-#: engines/engine.cpp:250
+#: engines/engine.cpp:252
msgid "Could not apply aspect ratio setting."
msgstr "½Õ ÒÔÐÛÞáï ×ÐáâÞáãÒÐâØ ÚÞàÕÚæöî áßöÒÒöÔÝÞèÕÝÝï áâÞàöÝ."
-#: engines/engine.cpp:255
+#: engines/engine.cpp:257
msgid "Could not apply fullscreen setting."
msgstr "½Õ ÒÔÐÛÞáï ×ÐáâÞáãÒÐâØ ßÞÒÝÞÕÚàÐÝÝØÙ àÕÖØÜ."
-#: engines/engine.cpp:355
+#: engines/engine.cpp:357
msgid ""
"You appear to be playing this game directly\n"
"from the CD. This is known to cause problems,\n"
@@ -1219,7 +1217,7 @@ msgstr ""
"ÓàØ ÝÐ ÖÞàáâÚØÙ ÔØáÚ.\n"
"´ØÒöâìáï äÐÙÛ README ÔÛï ßÞÔÐÛìèØå öÝáâàãÚæöÙ."
-#: engines/engine.cpp:366
+#: engines/engine.cpp:368
msgid ""
"This game has audio tracks in its disk. These\n"
"tracks need to be ripped from the disk using\n"
@@ -1233,7 +1231,17 @@ msgstr ""
"âÞÓÞ, éÞÑ ÜÞÖÝÐ ÑãÛÞ áÛãåÐâØ Üã×ØÚã ã Óàö.\n"
"´ØÒöâìáï äÐÙÛ README ÔÛï ßÞÔÐÛìèØå öÝáâàãÚæöÙ."
-#: engines/engine.cpp:433
+#: engines/engine.cpp:426
+#, fuzzy, c-format
+msgid ""
+"Gamestate load failed (%s)! Please consult the README for basic information, "
+"and for instructions on how to obtain further assistance."
+msgstr ""
+"²ØÑÐçâÕ, æÕÙ ÔÒØÖÞÚ ÝÕ ßöÔâàØÜãô ÔÞÒöÔÚã ßÞ öÓàÐÜ. ±ãÔì-ÛÐáÚÐ, ÔØÒöâìáï äÐÙÛ "
+"README ÔÛï ÞáÝÞÒÝÞ÷ öÝÞàÜÐæö÷, Ð âÐÚÞÖ öÝáâàãÚæöÙ, ïÚ ÞâàØÜÐâØ ßÞÔÐÛìèã "
+"ÔÞßÞÜÞÓã."
+
+#: engines/engine.cpp:439
msgid ""
"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 "
@@ -1243,7 +1251,7 @@ msgstr ""
"ScummVM. ÁÚÞàèÕ ×Ð ÒáÕ ÒÞÝÐ ÝÕ ÑãÔÕ ßàÐæîÒÐâØ áâÐÑöÛìÝÞ, ö ×ÑÕàÕÖÕÝÝï öÓÞà, "
"ïÚö ÒØ ×àÞÑØâÕ, ÜÞÖãâì ÝÕ ßàÐæîÒÐâØ ã ßÞÔÐÛìèØå ÒÕàáöïå ScummVM."
-#: engines/engine.cpp:436
+#: engines/engine.cpp:442
msgid "Start anyway"
msgstr "²áÕ ÞÔÝÞ ×ÐßãáâØâØ"
@@ -1287,7 +1295,7 @@ msgstr "³àÐâØ"
#: backends/platform/symbian/src/SymbianActions.cpp:52
#: backends/platform/wince/CEActionsPocket.cpp:44
#: backends/platform/wince/CEActionsSmartphone.cpp:52
-#: backends/events/default/default-events.cpp:244
+#: backends/events/default/default-events.cpp:213
msgid "Quit"
msgstr "²ØåöÔ"
@@ -1361,6 +1369,26 @@ msgctxt "lowres"
msgid "Speech & Subs"
msgstr "¾×ÒãçÚÐ âÐ âÕÚáâ"
+#: engines/scumm/dialogs.cpp:653
+msgid "Select a Proficiency Level."
+msgstr "¾ÑÕàöâì àÕÖØÜ áÚÛÐÔÝÞáâö."
+
+#: engines/scumm/dialogs.cpp:655
+msgid "Refer to your Loom(TM) manual for help."
+msgstr "·Ð ÔÞßÞÜÞÓÞî ×ÒÕàâÐÙâÕáï ÔÞ öÝáâàãÚæö÷ Loom(TM)."
+
+#: engines/scumm/dialogs.cpp:658
+msgid "Standard"
+msgstr "ÁâÐÝÔÐàâÝØÙ"
+
+#: engines/scumm/dialogs.cpp:659
+msgid "Practice"
+msgstr "¿àÐÚâØÚÐ"
+
+#: engines/scumm/dialogs.cpp:660
+msgid "Expert"
+msgstr "µÚáßÕàâ"
+
#: engines/scumm/help.cpp:73
msgid "Common keyboard commands:"
msgstr "¾áÝÞÒÝö ÚÞÜÐÝÔØ ÚÛÐÒöÐâãàØ:"
@@ -1874,7 +1902,7 @@ msgstr "»ÕâöâØ ÝÐßàÐÒÞ"
msgid "Fly to lower right"
msgstr "»ÕâöâØ ÔÞÝØ×ã ÝÐßàÐÒÞ"
-#: engines/scumm/scumm.cpp:1774
+#: engines/scumm/scumm.cpp:1773
#, c-format
msgid ""
"Native MIDI support requires the Roland Upgrade from LucasArts,\n"
@@ -1883,7 +1911,7 @@ msgstr ""
"ÀÕÖØÜ \"àöÔÝÞÓÞ\" MIDI ßÞâàÕÑãô ßÞÝÞÒÛÕÝÝï Roland Upgrade ÒöÔ\n"
"LucasArts, ßàÞâÕ %s ÒöÔáãâÝöÙ. ¿ÕàÕÜØÚÐîáì ÝÐ AdLib."
-#: engines/scumm/scumm.cpp:2264 engines/agos/saveload.cpp:189
+#: engines/scumm/scumm.cpp:2271 engines/agos/saveload.cpp:189
#, c-format
msgid ""
"Failed to save game state to file:\n"
@@ -1894,7 +1922,7 @@ msgstr ""
"\n"
"%s"
-#: engines/scumm/scumm.cpp:2271 engines/agos/saveload.cpp:154
+#: engines/scumm/scumm.cpp:2278 engines/agos/saveload.cpp:154
#, c-format
msgid ""
"Failed to load game state from file:\n"
@@ -1905,7 +1933,7 @@ msgstr ""
"\n"
"%s"
-#: engines/scumm/scumm.cpp:2283 engines/agos/saveload.cpp:197
+#: engines/scumm/scumm.cpp:2290 engines/agos/saveload.cpp:197
#, c-format
msgid ""
"Successfully saved game state in file:\n"
@@ -1916,7 +1944,7 @@ msgstr ""
"\n"
"%s"
-#: engines/scumm/scumm.cpp:2498
+#: engines/scumm/scumm.cpp:2505
msgid ""
"Usually, Maniac Mansion would start now. But ScummVM doesn't do that yet. To "
"play it, go to 'Add Game' in the ScummVM start menu and select the 'Maniac' "
@@ -1952,11 +1980,11 @@ msgstr "³ÞÛÞÒÝÕ ÜÕÝî"
msgid "~W~ater Effect Enabled"
msgstr "µäÕÚâØ ÒÞÔØ ãÒöÜÚÝÕÝÞ"
-#: engines/sci/engine/kfile.cpp:685
+#: engines/sci/engine/kfile.cpp:673
msgid "Restore game:"
msgstr "²öÔÝÞÒØâØ Óàã:"
-#: engines/sci/engine/kfile.cpp:685
+#: engines/sci/engine/kfile.cpp:673
msgid "Restore"
msgstr "²öÔÝÞÒØâØ"
@@ -1966,11 +1994,11 @@ msgid "Cutscene file '%s' not found!"
msgstr "ÄÐÙÛ ×ÐáâÐÒÚØ '%s' ÝÕ ×ÝÐÙÔÕÝÞ!"
#: engines/gob/inter_playtoons.cpp:256 engines/gob/inter_v2.cpp:1283
-#: engines/tinsel/saveload.cpp:482
+#: engines/tinsel/saveload.cpp:502
msgid "Failed to load game state from file."
msgstr "½Õ ÒÔÐÛÞáï ×ÐÒÐÝâÐÖØâØ áâÐÝ ÓàØ × äÐÙÛã."
-#: engines/gob/inter_v2.cpp:1353 engines/tinsel/saveload.cpp:560
+#: engines/gob/inter_v2.cpp:1353 engines/tinsel/saveload.cpp:515
msgid "Failed to save game state to file."
msgstr "½Õ ÒÔÐÛÞáï ×ÑÕàÕÓâØ áâÐÝ ÓàØ ã äÐÙÛ."
@@ -1982,6 +2010,54 @@ msgstr "½Õ ÒÔÐÛÞáï ÒØÔÐÛØâØ äÐÙÛ."
msgid "Failed to save game"
msgstr "½Õ ÒÔÐÛÞáï ×ÐßØáÐâØ Óàã"
+#: engines/kyra/lol.cpp:478
+msgid "Attack 1"
+msgstr "°âÐÚÐ 1"
+
+#: engines/kyra/lol.cpp:479
+msgid "Attack 2"
+msgstr "°âÐÚÐ 2"
+
+#: engines/kyra/lol.cpp:480
+msgid "Attack 3"
+msgstr "°âÐÚÐ 3"
+
+#: engines/kyra/lol.cpp:481
+msgid "Move Forward"
+msgstr "ÀãåÐâØáì ãßÕàÕÔ"
+
+#: engines/kyra/lol.cpp:482
+msgid "Move Back"
+msgstr "ÀãåÐâØáì ÝÐ×ÐÔ"
+
+#: engines/kyra/lol.cpp:483
+msgid "Slide Left"
+msgstr "ºÞÒ×ÐâØ ÝÐÛöÒÞ"
+
+#: engines/kyra/lol.cpp:484
+msgid "Slide Right"
+msgstr "ºÞÒ×ÐâØ ÝÐßàÐÒÞ"
+
+#: engines/kyra/lol.cpp:485
+msgid "Turn Left"
+msgstr "¿ÞÒÕàÝãâØáï ÝÐÛöÒÞ"
+
+#: engines/kyra/lol.cpp:486
+msgid "Turn Right"
+msgstr "¿ÞÒÕàÝãâØáï ÝÐßàÐÒÞ"
+
+#: engines/kyra/lol.cpp:487
+msgid "Rest"
+msgstr "²öÔßÞçØâØ"
+
+#: engines/kyra/lol.cpp:488
+msgid "Options"
+msgstr "½ÐÛÐèâãÒÐÝÝï"
+
+#: engines/kyra/lol.cpp:489
+msgid "Choose Spell"
+msgstr "²ØÑàÐâØ ×ÐÚÛïââï"
+
#: engines/kyra/sound_midi.cpp:475
msgid ""
"You appear to be using a General MIDI device,\n"
@@ -1996,10 +2072,6 @@ msgstr ""
"MT32 ÝÐ General MIDI. °ÛÕ Ò àÕ×ãÛìâÐâö ÜÞÖÕ\n"
"áâÐâØáï, éÞ ÔÕïÚö âàÕÚØ ÑãÔãâì ÓàÐâØ ÝÕßàÐÒØÛìÝÞ."
-#: engines/m4/m4_menus.cpp:138
-msgid "Save game failed!"
-msgstr "½Õ ÒÔÐÛÞáï ×ÑÕàÕÓâØ Óàã!"
-
#: engines/sky/compact.cpp:130
msgid ""
"Unable to find \"sky.cpt\" file!\n"
@@ -2016,15 +2088,20 @@ msgstr ""
"ÄÐÙÛ sky.cpt ÜÐô ÝÕÒöàÝØÙ àÞ×Üöà.\n"
"±ãÔì ÛÐáÚÐ, (ßÕàÕ)×ÐÒÐÝâÐÖâÕ ÙÞÓÞ × www.scummvm.org"
-#: engines/sword1/animation.cpp:344 engines/sword2/animation.cpp:379
+#: engines/sword1/animation.cpp:539
+#, c-format
+msgid "PSX stream cutscene '%s' cannot be played in paletted mode"
+msgstr ""
+
+#: engines/sword1/animation.cpp:560 engines/sword2/animation.cpp:455
msgid "DXA cutscenes found but ScummVM has been built without zlib support"
msgstr "·ÝÐÙÔÕÝÞ ×ÐáâÐÒÚØ DXA, ÐÛÕ ScummVM ÑãÒ ßÞÑãÔÞÒÐÝØÙ ÑÕ× ßöÔâàØÜÚØ zlib"
-#: engines/sword1/animation.cpp:354 engines/sword2/animation.cpp:389
+#: engines/sword1/animation.cpp:570 engines/sword2/animation.cpp:465
msgid "MPEG2 cutscenes are no longer supported"
msgstr "·ÐáâÐÒÚØ MPEG2 ÑöÛìèÕ ÝÕ ßöÔâàØÜãîâìáï"
-#: engines/sword1/animation.cpp:359 engines/sword2/animation.cpp:397
+#: engines/sword1/animation.cpp:576 engines/sword2/animation.cpp:473
#, c-format
msgid "Cutscene '%s' not found"
msgstr "·ÐáâÐÒÚã '%s' ÝÕ ×ÝÐÙÔÕÝÞ"
@@ -2067,6 +2144,12 @@ msgstr "²×ïâØ ÝÞÒÕ"
msgid "This is the end of the Broken Sword 1 Demo"
msgstr "½Ð æìÞÜã ×ÐÚöÝçãôâìáï ÔÕÜÞ Broken Sword 1"
+#: engines/sword2/animation.cpp:435
+#, fuzzy
+msgid ""
+"PSX cutscenes found but ScummVM has been built without RGB color support"
+msgstr "·ÝÐÙÔÕÝÞ ×ÐáâÐÒÚØ DXA, ÐÛÕ ScummVM ÑãÒ ßÞÑãÔÞÒÐÝØÙ ÑÕ× ßöÔâàØÜÚØ zlib"
+
#: engines/parallaction/saveload.cpp:133
#, c-format
msgid ""
@@ -2124,7 +2207,7 @@ msgstr "µÜãÛïâÞà MAME OPL:"
msgid "DOSBox OPL emulator"
msgstr "µÜãÛïâÞà DOSBox OPL"
-#: audio/mididrv.cpp:205
+#: audio/mididrv.cpp:209
#, c-format
msgid ""
"The selected audio device '%s' was not found (e.g. might be turned off or "
@@ -2133,12 +2216,12 @@ msgstr ""
"²ØÑàÐÝØÙ ×ÒãÚÞÒØÙ ßàØáâàöÙ %s ÝÕ ÑãÛÞ ×ÝÐÙÔÕÝÞ (âÞÑâÞ, ÙÞÓÞ ÜÞÖÕ ÑãâØ "
"ÒØÜÚÝÕÝÞ ÐÑÞ ÝÕ ßöÔÚÛîçÕÝÞ)."
-#: audio/mididrv.cpp:205 audio/mididrv.cpp:217 audio/mididrv.cpp:253
-#: audio/mididrv.cpp:268
+#: audio/mididrv.cpp:209 audio/mididrv.cpp:221 audio/mididrv.cpp:257
+#: audio/mididrv.cpp:272
msgid "Attempting to fall back to the next available device..."
msgstr "½ÐÜÐÓÐîáï ÒØÚÞàØáâÐâØ ÝÐáâãßÝØÙ ÔÞáâãßÝØÙ ßàØáâàöÙ..."
-#: audio/mididrv.cpp:217
+#: audio/mididrv.cpp:221
#, c-format
msgid ""
"The selected audio device '%s' cannot be used. See log file for more "
@@ -2147,7 +2230,7 @@ msgstr ""
"²ØÑàÐÝØÙ ×ÒãÚÞÒØÙ ßàØáâàöÙ %s ÝÕ ÜÞÖÕ ÑãâØ ÒØÚÞàØáâÐÝØÙ. ´ØÒöâìáï äÐÙÛ ÛÞÓã "
"ÔÛï ÔÞÔÐâÚÞÒÞ÷ öÝäÞàÜÐæö÷."
-#: audio/mididrv.cpp:253
+#: audio/mididrv.cpp:257
#, c-format
msgid ""
"The preferred audio device '%s' was not found (e.g. might be turned off or "
@@ -2156,7 +2239,7 @@ msgstr ""
"ÃßÞÔÞÑÐÝØÙ ×ÒãÚÞÒØÙ ßàØáâàöÙ %s ÝÕ ÑãÛÞ ×ÝÐÙÔÕÝÞ (âÞÑâÞ, ÙÞÓÞ ÜÞÖÕ ÑãâØ "
"ÒØÜÚÝÕÝÞ ÐÑÞ ÝÕ ßöÔÚÛîçÕÝÞ)."
-#: audio/mididrv.cpp:268
+#: audio/mididrv.cpp:272
#, c-format
msgid ""
"The preferred audio device '%s' cannot be used. See log file for more "
@@ -2173,7 +2256,7 @@ msgstr "±Õ× Üã×ØÚØ"
msgid "Amiga Audio Emulator"
msgstr "°ÜöÓÐ °ãÔöÞ µÜãÛïâÞà"
-#: audio/softsynth/adlib.cpp:1594
+#: audio/softsynth/adlib.cpp:1593
msgid "AdLib Emulator"
msgstr "µÜãÛïâÞà AdLib"
@@ -2185,11 +2268,11 @@ msgstr "Apple II GS µÜãÛïâÞà (½µ Àµ°»¦·¾²°½¾)"
msgid "C64 Audio Emulator"
msgstr "C64 °ãÔöÞ µÜãÛïâÞà"
-#: audio/softsynth/mt32.cpp:329
+#: audio/softsynth/mt32.cpp:293
msgid "Initializing MT-32 Emulator"
msgstr "½ÐÛÐèâÞÒãî ÕÜãÛïâÞà MT-32"
-#: audio/softsynth/mt32.cpp:543
+#: audio/softsynth/mt32.cpp:512
msgid "MT-32 Emulator"
msgstr "µÜãÛïâÞà MT-32"
@@ -2205,15 +2288,23 @@ msgstr "µÜãÛïâÞà IBM PCjr"
msgid "Keymap:"
msgstr "¼ÐßÐ ÚÛÐÒöè:"
-#: backends/keymapper/remap-dialog.cpp:64
+#: backends/keymapper/remap-dialog.cpp:66
+msgid " (Effective)"
+msgstr " (µäÕÚâØÒÝÐ)"
+
+#: backends/keymapper/remap-dialog.cpp:106
msgid " (Active)"
msgstr " (°ÚâØÒÝÐ)"
-#: backends/keymapper/remap-dialog.cpp:98
+#: backends/keymapper/remap-dialog.cpp:106
+msgid " (Blocked)"
+msgstr ""
+
+#: backends/keymapper/remap-dialog.cpp:119
msgid " (Global)"
msgstr " (³ÛÞÑÐÛìÝÐ)"
-#: backends/keymapper/remap-dialog.cpp:108
+#: backends/keymapper/remap-dialog.cpp:127
msgid " (Game)"
msgstr " (¦ÓàØ)"
@@ -2293,40 +2384,63 @@ msgstr "²ØáÞÚÐ ïÚöáâì ×ÒãÚã (ßÞÒöÛìÝöèÕ) (àÕÑãâ)"
msgid "Disable power off"
msgstr "·ÐÑÞàÞÝØâØ ÒØÜÚÝÕÝÝï"
-#: backends/platform/iphone/osys_events.cpp:338
+#: backends/platform/iphone/osys_events.cpp:301
msgid "Mouse-click-and-drag mode enabled."
msgstr "ÀÕÖØÜ ÜØèö ÚÛöÚÝãâØ-âÐ-âïÓÝãâØ ãÒöÜÚÝÕÝÞ."
-#: backends/platform/iphone/osys_events.cpp:340
+#: backends/platform/iphone/osys_events.cpp:303
msgid "Mouse-click-and-drag mode disabled."
msgstr "ÀÕÖØÜ ÜØèö ÚÛöÚÝãâØ-âÐ-âïÓÝãâØ ÒØÜÚÝÕÝÞ."
-#: backends/platform/iphone/osys_events.cpp:351
+#: backends/platform/iphone/osys_events.cpp:314
msgid "Touchpad mode enabled."
msgstr "ÀÕÖØÜ âÐçßÐÔã ãÒöÜÚÝÕÝÞ."
-#: backends/platform/iphone/osys_events.cpp:353
+#: backends/platform/iphone/osys_events.cpp:316
msgid "Touchpad mode disabled."
msgstr "ÀÕÖØÜ âÐçßÐÔã ÒØÜÚÝÕÝÞ."
-#: backends/platform/sdl/macosx/appmenu_osx.mm:67
+#: backends/platform/maemo/maemo.cpp:205
+msgid "Click Mode"
+msgstr "ÀÕÖØÜ ÚÛöÚöÒ"
+
+#: backends/platform/maemo/maemo.cpp:211
+#: backends/platform/symbian/src/SymbianActions.cpp:42
+#: backends/platform/wince/CEActionsPocket.cpp:60
+#: backends/platform/wince/CEActionsSmartphone.cpp:43
+#: backends/platform/bada/form.cpp:281
+msgid "Left Click"
+msgstr "»öÒØÙ ÚÛöÚ"
+
+#: backends/platform/maemo/maemo.cpp:214
+msgid "Middle Click"
+msgstr "ÁÕàÕÔÝöÙ ÚÛöÚ"
+
+#: backends/platform/maemo/maemo.cpp:217
+#: backends/platform/symbian/src/SymbianActions.cpp:43
+#: backends/platform/wince/CEActionsSmartphone.cpp:44
+#: backends/platform/bada/form.cpp:273
+msgid "Right Click"
+msgstr "¿àÐÒØÙ ÚÛöÚ"
+
+#: backends/platform/sdl/macosx/appmenu_osx.mm:78
msgid "Hide ScummVM"
msgstr "ÁåÞÒÐâØ ScummVM"
-#: backends/platform/sdl/macosx/appmenu_osx.mm:70
+#: backends/platform/sdl/macosx/appmenu_osx.mm:83
msgid "Hide Others"
msgstr "ÁåÞÒÐâØ ¦Ýèö"
-#: backends/platform/sdl/macosx/appmenu_osx.mm:74
+#: backends/platform/sdl/macosx/appmenu_osx.mm:88
msgid "Show All"
msgstr "¿ÞÚÐ×ÐâØ ²áÕ"
-#: backends/platform/sdl/macosx/appmenu_osx.mm:92
-#: backends/platform/sdl/macosx/appmenu_osx.mm:99
+#: backends/platform/sdl/macosx/appmenu_osx.mm:110
+#: backends/platform/sdl/macosx/appmenu_osx.mm:121
msgid "Window"
msgstr "²öÚÝÞ"
-#: backends/platform/sdl/macosx/appmenu_osx.mm:95
+#: backends/platform/sdl/macosx/appmenu_osx.mm:115
msgid "Minimize"
msgstr "¼öÝöÜö×ãÒÐâØ"
@@ -2340,12 +2454,12 @@ msgid "Normal (no scaling)"
msgstr "±Õ× ×ÑöÛìèÕÝÝï"
#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2147
-#: backends/graphics/openglsdl/openglsdl-graphics.cpp:537
+#: backends/graphics/openglsdl/openglsdl-graphics.cpp:533
msgid "Enabled aspect ratio correction"
msgstr "ºÞàÕÚæöî áßöÒÒöÔÝÞèÕÝÝï áâÞàöÝ ãÒöÜÚÝÕÝÞ"
#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2153
-#: backends/graphics/openglsdl/openglsdl-graphics.cpp:542
+#: backends/graphics/openglsdl/openglsdl-graphics.cpp:538
msgid "Disabled aspect ratio correction"
msgstr "ºÞàÕÚæöî áßöÒÒöÔÝÞèÕÝÝï áâÞàöÝ ÒØÜÚÝÕÝÞ"
@@ -2354,7 +2468,7 @@ msgid "Active graphics filter:"
msgstr "¿ÞâÞçÝØÙ ÓàÐäöçÝØÙ äöÛìâà:"
#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2250
-#: backends/graphics/openglsdl/openglsdl-graphics.cpp:481
+#: backends/graphics/openglsdl/openglsdl-graphics.cpp:477
msgid "Windowed mode"
msgstr "²öÚÞÝÝØÙ àÕÖØÜ"
@@ -2378,11 +2492,11 @@ msgstr "¿ÞâÞçÝØÙ ÒöÔÕÞàÕÖØÜ"
msgid "Current scale"
msgstr "¿ÞâÞçÝØÙ ÜÐáèâÐÑ"
-#: backends/graphics/openglsdl/openglsdl-graphics.cpp:562
+#: backends/graphics/openglsdl/openglsdl-graphics.cpp:558
msgid "Active filter mode: Linear"
msgstr "°ÚâØÒÝØÙ àÕÖØÜ äöÛìâàÐæö÷: »öÝöÙÝØÙ"
-#: backends/graphics/openglsdl/openglsdl-graphics.cpp:564
+#: backends/graphics/openglsdl/openglsdl-graphics.cpp:560
msgid "Active filter mode: Nearest"
msgstr "°ÚâØÒÝØÙ àÕÖØÜ äöÛìâàÐæö÷: ½ÐÙÑÛØÖçÕ"
@@ -2406,19 +2520,6 @@ msgstr "½ÐÛöÒÞ"
msgid "Right"
msgstr "½ÐßàÐÒÞ"
-#: backends/platform/symbian/src/SymbianActions.cpp:42
-#: backends/platform/wince/CEActionsPocket.cpp:60
-#: backends/platform/wince/CEActionsSmartphone.cpp:43
-#: backends/platform/bada/form.cpp:281
-msgid "Left Click"
-msgstr "»öÒØÙ ÚÛöÚ"
-
-#: backends/platform/symbian/src/SymbianActions.cpp:43
-#: backends/platform/wince/CEActionsSmartphone.cpp:44
-#: backends/platform/bada/form.cpp:273
-msgid "Right Click"
-msgstr "¿àÐÒØÙ ÚÛöÚ"
-
#: backends/platform/symbian/src/SymbianActions.cpp:46
#: backends/platform/wince/CEActionsSmartphone.cpp:47
msgid "Zone"
@@ -2707,15 +2808,15 @@ msgstr ""
"½Õ ×ÐÑãÔìâÕ ßÕàÕßàØ×ÝÐçØâØ ÚÝÞßÚã ÔÛï Ôö÷ 'ÁåÞÒÐâØ ¿ÐÝÕÛì öÝáâà.' éÞÑ "
"ßÞÑÐçØâØ ÒÕáì öÝÒÕÝâÐà"
-#: backends/events/default/default-events.cpp:222
+#: backends/events/default/default-events.cpp:191
msgid "Do you really want to return to the Launcher?"
msgstr "²Ø ÔöÙáÝÞ åÞçÕâÕ ßÞÒÕàÝãâØáï ÔÞ ÓÞÛÞÒÝÞÓÞ ÜÕÝî?"
-#: backends/events/default/default-events.cpp:222
+#: backends/events/default/default-events.cpp:191
msgid "Launcher"
msgstr "³ÞÛÞÒÝÕ ÜÕÝî"
-#: backends/events/default/default-events.cpp:244
+#: backends/events/default/default-events.cpp:213
msgid "Do you really want to quit?"
msgstr "²Ø ÔöÙáÝÞ åÞçÕâÕ ÒØÙâØ?"
@@ -2781,14 +2882,31 @@ msgstr "¿ÞÚÐ×ÐâØ ÚÛÐÒöÐâãàã"
msgid "Control Mouse"
msgstr "ÃßàÐÒÛöÝÝï ÜØèÕî"
-#: backends/events/maemosdl/maemosdl-events.cpp:121
+#: backends/events/maemosdl/maemosdl-events.cpp:192
msgid "Clicking Enabled"
msgstr "ºÛöÚØ ãÒöÜÚÝÕÝÞ"
-#: backends/events/maemosdl/maemosdl-events.cpp:121
+#: backends/events/maemosdl/maemosdl-events.cpp:192
msgid "Clicking Disabled"
msgstr "ºÛöÚØ ÒØÜÚÝÕÝÞ"
+#~ msgid "Hercules Green"
+#~ msgstr "Hercules ·ÕÛÕÝØÙ"
+
+#~ msgid "Hercules Amber"
+#~ msgstr "Hercules ±ãàèâØÝÝØÙ"
+
+#~ msgctxt "lowres"
+#~ msgid "Hercules Green"
+#~ msgstr "Hercules ·ÕÛÕÝØÙ"
+
+#~ msgctxt "lowres"
+#~ msgid "Hercules Amber"
+#~ msgstr "Hercules ±ãàèâØÝÝØÙ"
+
+#~ msgid "Save game failed!"
+#~ msgstr "½Õ ÒÔÐÛÞáï ×ÑÕàÕÓâØ Óàã!"
+
#~ msgctxt "lowres"
#~ msgid "Add Game..."
#~ msgstr "´ÞÔÐâØ Óàã..."
diff --git a/ports.mk b/ports.mk
index ddb841c571..419b91581a 100644
--- a/ports.mk
+++ b/ports.mk
@@ -110,7 +110,7 @@ OSX_STATIC_LIBS += $(STATICLIBPATH)/lib/libfaad.a
endif
ifdef USE_ZLIB
-OSX_ZLIB ?= -lz
+OSX_ZLIB ?= $(STATICLIBPATH)/lib/libz.a
endif
ifdef USE_SPARKLE
@@ -159,13 +159,16 @@ osxsnap: bundle
cp $(srcdir)/doc/de/Liesmich ./ScummVM-snapshot/doc/de/Liesmich
cp $(srcdir)/doc/de/Schnellstart ./ScummVM-snapshot/doc/de/Schnellstart
mkdir ScummVM-snapshot/doc/es
- cp $(srcdir)/doc/es/"Inicio Rápido" ./ScummVM-snapshot/doc/es
+ cp $(srcdir)/doc/es/InicioRapido ./ScummVM-snapshot/doc/es
mkdir ScummVM-snapshot/doc/fr
cp $(srcdir)/doc/fr/DemarrageRapide ./ScummVM-snapshot/doc/fr/DemarrageRapide
mkdir ScummVM-snapshot/doc/it
cp $(srcdir)/doc/it/GuidaRapida ./ScummVM-snapshot/doc/it/GuidaRapida
mkdir ScummVM-snapshot/doc/no-nb
- cp $(srcdir)doc/no-nb/HurtigStart ./ScummVM-snapshot/doc/no-nb/HurtigStart
+ cp $(srcdir)/doc/no-nb/HurtigStart ./ScummVM-snapshot/doc/no-nb/HurtigStart
+ mkdir ScummVM-snapshot/doc/se
+ cp $(srcdir)/doc/se/LasMig ./ScummVM-snapshot/doc/se/LasMig
+ cp $(srcdir)/doc/se/Snabbstart ./ScummVM-snapshot/doc/se/Snabbstart
/Developer/Tools/SetFile -t ttro -c ttxt ./ScummVM-snapshot/*
xattr -w "com.apple.TextEncoding" "utf-8;134217984" ./ScummVM-snapshot/doc/cz/*
xattr -w "com.apple.TextEncoding" "utf-8;134217984" ./ScummVM-snapshot/doc/de/*
@@ -173,6 +176,7 @@ osxsnap: bundle
xattr -w "com.apple.TextEncoding" "utf-8;134217984" ./ScummVM-snapshot/doc/fr/*
xattr -w "com.apple.TextEncoding" "utf-8;134217984" ./ScummVM-snapshot/doc/it/*
xattr -w "com.apple.TextEncoding" "utf-8;134217984" ./ScummVM-snapshot/doc/no-nb/*
+ xattr -w "com.apple.TextEncoding" "utf-8;134217984" ./ScummVM-snapshot/doc/se/*
/Developer/Tools/CpMac -r $(bundle_name) ./ScummVM-snapshot/
cp $(srcdir)/dists/macosx/DS_Store ./ScummVM-snapshot/.DS_Store
cp $(srcdir)/dists/macosx/background.jpg ./ScummVM-snapshot/background.jpg
@@ -202,6 +206,7 @@ win32dist: $(EXECUTABLE)
mkdir -p $(WIN32PATH)/doc/fr
mkdir -p $(WIN32PATH)/doc/it
mkdir -p $(WIN32PATH)/doc/no-nb
+ mkdir -p $(WIN32PATH)/doc/se
$(STRIP) $(EXECUTABLE) -o $(WIN32PATH)/$(EXECUTABLE)
cp $(DIST_FILES_THEMES) $(WIN32PATH)
ifdef DIST_FILES_ENGINEDATA
@@ -210,30 +215,37 @@ endif
cp $(srcdir)/AUTHORS $(WIN32PATH)/AUTHORS.txt
cp $(srcdir)/COPYING $(WIN32PATH)/COPYING.txt
cp $(srcdir)/COPYING.LGPL $(WIN32PATH)/COPYING.LGPL.txt
+ cp $(srcdir)/COPYING.FREEFONT $(WIN32PATH)/COPYING.FREEFONT.txt
cp $(srcdir)/COPYRIGHT $(WIN32PATH)/COPYRIGHT.txt
cp $(srcdir)/NEWS $(WIN32PATH)/NEWS.txt
cp $(srcdir)/doc/cz/PrectiMe $(WIN32PATH)/doc/cz/PrectiMe.txt
cp $(srcdir)/doc/de/Neues $(WIN32PATH)/doc/de/Neues.txt
cp $(srcdir)/doc/QuickStart $(WIN32PATH)/doc/QuickStart.txt
- cp $(srcdir)/doc/es/"Inicio Rápido" $(WIN32PATH)/doc/es/"Inicio Rápido".txt
+ cp $(srcdir)/doc/es/InicioRapido $(WIN32PATH)/doc/es/InicioRapido.txt
cp $(srcdir)/doc/fr/DemarrageRapide $(WIN32PATH)/doc/fr/DemarrageRapide.txt
cp $(srcdir)/doc/it/GuidaRapida $(WIN32PATH)/doc/it/GuidaRapida.txt
cp $(srcdir)/doc/no-nb/HurtigStart $(WIN32PATH)/doc/no-nb/HurtigStart.txt
cp $(srcdir)/doc/de/Schnellstart $(WIN32PATH)/doc/de/Schnellstart.txt
+ cp $(srcdir)/doc/se/Snabbstart $(WIN32PATH)/doc/se/Snabbstart.txt
cp $(srcdir)/README $(WIN32PATH)/README.txt
cp $(srcdir)/doc/de/Liesmich $(WIN32PATH)/doc/de/Liesmich.txt
+ cp $(srcdir)/doc/se/LasMig $(WIN32PATH)/doc/se/LasMig.txt
cp /usr/local/README-SDL.txt $(WIN32PATH)
cp /usr/local/bin/SDL.dll $(WIN32PATH)
cp $(srcdir)/dists/win32/graphics/left.bmp $(WIN32PATH)/graphics
cp $(srcdir)/dists/win32/graphics/scummvm-install.ico $(WIN32PATH)/graphics
+ cp $(srcdir)/dists/win32/migration.bat $(WIN32PATH)
+ cp $(srcdir)/dists/win32/migration.txt $(WIN32PATH)
cp $(srcdir)/dists/win32/ScummVM.iss $(WIN32PATH)
unix2dos $(WIN32PATH)/*.txt
+ unix2dos $(WIN32PATH)/doc/*.txt
unix2dos $(WIN32PATH)/doc/cz/*.txt
unix2dos $(WIN32PATH)/doc/de/*.txt
unix2dos $(WIN32PATH)/doc/es/*.txt
unix2dos $(WIN32PATH)/doc/fr/*.txt
unix2dos $(WIN32PATH)/doc/it/*.txt
unix2dos $(WIN32PATH)/doc/no-nb/*.txt
+ unix2dos $(WIN32PATH)/doc/se/*.txt
# Special target to create a win32 NSIS installer
win32setup: $(EXECUTABLE)
@@ -242,6 +254,38 @@ win32setup: $(EXECUTABLE)
cp /usr/local/bin/SDL.dll $(srcdir)/$(STAGINGPATH)
makensis -V2 -Dtop_srcdir="../.." -Dstaging_dir="../../$(STAGINGPATH)" -Darch=$(ARCH) $(srcdir)/dists/win32/scummvm.nsi
+
+#
+# Special target to generate project files for various IDEs
+# Mainly Win32-specific
+#
+
+# The release branch is in form 'heads/branch-1-4-1', for this case
+# $CUR_BRANCH will be equal to '1', for the rest cases it will be empty
+CUR_BRANCH := $(shell cd $(srcdir); git describe --all |cut -d '-' -f 4-)
+
+ideprojects: devtools/create_project
+ifeq ($(VER_DIRTY), -dirty)
+ $(error You have uncommitted changes)
+endif
+ifeq "$(CUR_BRANCH)" "heads/master"
+ $(error You cannot do it on master)
+else ifeq "$(CUR_BRANCH)" ""
+ $(error You must be on a release branch)
+endif
+ @echo Creating Code::Blocks project files...
+ @cd $(srcdir)/dists/codeblocks && ../../devtools/create_project/create_project ../.. --codeblocks >/dev/null && git add -f *.workspace *.cbp
+ @echo Creating MSVC8 project files...
+ @cd $(srcdir)/dists/msvc8 && ../../devtools/create_project/create_project ../.. --msvc --msvc-version 8 >/dev/null && git add -f *.sln *.vcproj *.vsprops
+ @echo Creating MSVC9 project files...
+ @cd $(srcdir)/dists/msvc9 && ../../devtools/create_project/create_project ../.. --msvc --msvc-version 9 >/dev/null && git add -f *.sln *.vcproj *.vsprops
+ @echo Creating MSVC10 project files...
+ @cd $(srcdir)/dists/msvc10 && ../../devtools/create_project/create_project ../.. --msvc --msvc-version 10 >/dev/null && git add -f *.sln *.vcxproj *.vcxproj.filters *.props
+ @echo
+ @echo All is done.
+ @echo Now run
+ @echo "\tgit commit 'DISTS: Generated Code::Blocks and MSVC project files'"
+
#
# AmigaOS specific
#
diff --git a/test/audio/helper.h b/test/audio/helper.h
index 5080c79eef..77dc63b619 100644
--- a/test/audio/helper.h
+++ b/test/audio/helper.h
@@ -24,40 +24,7 @@ static T *createSine(const int sampleRate, const int time) {
}
template<typename T>
-static Common::SeekableReadStream *createPartitionStream(T *sine, const int samples, Audio::RawStreamBlockList &blockList) {
- const int block1Len = samples / 2;
- const int block1Size = block1Len * sizeof(T);
- const int block2Len = samples - block1Len;
- const int block2Size = block2Len * sizeof(T);
-
- const int bufferLen = samples * 2;
- const int bufferSize = bufferLen * sizeof(T);
- T *partition = (T *)calloc(1, bufferSize);
-
- Audio::RawStreamBlock block;
-
- // The will layout the buffer like the following:
- // [Zero], [Part2], [Zero], [Part1]
-
- // The first part of the stream is at the end of the memory buffer
- block.pos = bufferSize - block1Size;
- block.len = block1Len;
- memcpy(partition + bufferLen - block1Len, sine, block1Size);
- blockList.push_back(block);
-
- // The second part of the stream is near the beginning of the memory buffer
- block.pos = block2Size;
- block.len = block2Len;
- memcpy(partition + block2Len, sine + block1Len, block2Size);
- blockList.push_back(block);
-
- free(sine);
-
- return new Common::MemoryReadStream((const byte *)partition, bufferSize, DisposeAfterUse::YES);
-}
-
-template<typename T>
-static Audio::SeekableAudioStream *createSineStream(const int sampleRate, const int time, int16 **comp, bool le, bool isStereo, bool makePartition = false) {
+static Audio::SeekableAudioStream *createSineStream(const int sampleRate, const int time, int16 **comp, bool le, bool isStereo) {
T *sine = createSine<T>(sampleRate, time * (isStereo ? 2 : 1));
const bool isUnsigned = !std::numeric_limits<T>::is_signed;
@@ -88,22 +55,12 @@ static Audio::SeekableAudioStream *createSineStream(const int sampleRate, const
}
Audio::SeekableAudioStream *s = 0;
- if (makePartition) {
- Audio::RawStreamBlockList blockList;
- Common::SeekableReadStream *sD = createPartitionStream<T>(sine, samples, blockList);
- s = Audio::makeRawStream(sD, blockList, sampleRate,
- (is16Bits ? Audio::FLAG_16BITS : 0)
- | (isUnsigned ? Audio::FLAG_UNSIGNED : 0)
- | (le ? Audio::FLAG_LITTLE_ENDIAN : 0)
- | (isStereo ? Audio::FLAG_STEREO : 0));
- } else {
- Common::SeekableReadStream *sD = new Common::MemoryReadStream((const byte *)sine, sizeof(T) * samples, DisposeAfterUse::YES);
- s = Audio::makeRawStream(sD, sampleRate,
- (is16Bits ? Audio::FLAG_16BITS : 0)
- | (isUnsigned ? Audio::FLAG_UNSIGNED : 0)
- | (le ? Audio::FLAG_LITTLE_ENDIAN : 0)
- | (isStereo ? Audio::FLAG_STEREO : 0));
- }
+ Common::SeekableReadStream *sD = new Common::MemoryReadStream((const byte *)sine, sizeof(T) * samples, DisposeAfterUse::YES);
+ s = Audio::makeRawStream(sD, sampleRate,
+ (is16Bits ? Audio::FLAG_16BITS : 0)
+ | (isUnsigned ? Audio::FLAG_UNSIGNED : 0)
+ | (le ? Audio::FLAG_LITTLE_ENDIAN : 0)
+ | (isStereo ? Audio::FLAG_STEREO : 0));
return s;
}
diff --git a/test/audio/raw.h b/test/audio/raw.h
index 51ec067f7e..e7cb42ac44 100644
--- a/test/audio/raw.h
+++ b/test/audio/raw.h
@@ -8,9 +8,9 @@ class RawStreamTestSuite : public CxxTest::TestSuite
{
private:
template<typename T>
- void readBufferTestTemplate(const int sampleRate, const int time, const bool le, const bool isStereo, const bool makePartition = false) {
+ void readBufferTestTemplate(const int sampleRate, const int time, const bool le, const bool isStereo) {
int16 *sine;
- Audio::SeekableAudioStream *s = createSineStream<int8>(sampleRate, time, &sine, le, isStereo, makePartition);
+ Audio::SeekableAudioStream *s = createSineStream<int8>(sampleRate, time, &sine, le, isStereo);
const int totalSamples = sampleRate * time * (isStereo ? 2 : 1);
int16 *buffer = new int16[totalSamples];
@@ -68,57 +68,13 @@ public:
readBufferTestTemplate<uint16>(11025, 2, true, true);
}
- void test_read_buffer_8_bit_signed_mono_parted() {
- readBufferTestTemplate<int8>(11025, 2, false, false, true);
- }
-
- void test_read_buffer_8_bit_signed_stereo_parted() {
- readBufferTestTemplate<int8>(11025, 2, false, true, true);
- }
-
- void test_read_buffer_8_bit_unsigned_mono_parted() {
- readBufferTestTemplate<uint8>(11025, 2, false, false, true);
- }
-
- void test_read_buffer_16_bit_signed_be_mono_parted() {
- readBufferTestTemplate<int16>(11025, 2, false, false, true);
- }
-
- void test_read_buffer_16_bit_signed_be_stereo_parted() {
- readBufferTestTemplate<int16>(11025, 2, false, true, true);
- }
-
- void test_read_buffer_16_bit_unsigned_be_mono_parted() {
- readBufferTestTemplate<uint16>(11025, 2, false, false, true);
- }
-
- void test_read_buffer_16_bit_unsigned_be_stereo_parted() {
- readBufferTestTemplate<uint16>(11025, 2, false, true, true);
- }
-
- void test_read_buffer_16_bit_signed_le_mono_parted() {
- readBufferTestTemplate<int16>(11025, 2, true, false, true);
- }
-
- void test_read_buffer_16_bit_signed_le_stereo_parted() {
- readBufferTestTemplate<int16>(11025, 2, true, true, true);
- }
-
- void test_read_buffer_16_bit_unsigned_le_mono_parted() {
- readBufferTestTemplate<uint16>(11025, 2, true, false, true);
- }
-
- void test_read_buffer_16_bit_unsigned_le_stereo_parted() {
- readBufferTestTemplate<uint16>(11025, 2, true, true, true);
- }
-
private:
- void partialReadTest(const bool makePartition) {
+ void partialReadTest() {
const int sampleRate = 11025;
const int time = 4;
int16 *sine;
- Audio::SeekableAudioStream *s = createSineStream<int8>(sampleRate, time, &sine, false, false, makePartition);
+ Audio::SeekableAudioStream *s = createSineStream<int8>(sampleRate, time, &sine, false, false);
int16 *buffer = new int16[sampleRate * time];
TS_ASSERT_EQUALS(s->readBuffer(buffer, sampleRate), sampleRate);
@@ -139,15 +95,11 @@ private:
}
public:
void test_partial_read() {
- partialReadTest(false);
- }
-
- void test_partial_read_parted() {
- partialReadTest(true);
+ partialReadTest();
}
private:
- void readAfterEndTest(const bool makePartition) {
+ void readAfterEndTest() {
const int sampleRate = 11025;
const int time = 1;
Audio::SeekableAudioStream *s = createSineStream<int8>(sampleRate, time, 0, false, false);
@@ -165,18 +117,14 @@ private:
public:
void test_read_after_end() {
- readAfterEndTest(false);
- }
-
- void test_read_after_end_parted() {
- readAfterEndTest(true);
+ readAfterEndTest();
}
private:
- void rewindTest(const bool makePartition) {
+ void rewindTest() {
const int sampleRate = 11025;
const int time = 2;
- Audio::SeekableAudioStream *s = createSineStream<int8>(sampleRate, time, 0, false, false, makePartition);
+ Audio::SeekableAudioStream *s = createSineStream<int8>(sampleRate, time, 0, false, false);
int16 *buffer = new int16[sampleRate * time];
TS_ASSERT_EQUALS(s->readBuffer(buffer, sampleRate * time), sampleRate * time);
@@ -193,15 +141,11 @@ private:
}
public:
void test_rewind() {
- rewindTest(false);
- }
-
- void test_rewind_parted() {
- rewindTest(true);
+ rewindTest();
}
private:
- void lengthTest(const bool makePartition) {
+ void lengthTest() {
int sampleRate = 0;
const int time = 4;
@@ -209,66 +153,62 @@ private:
// 11025 Hz tests
sampleRate = 11025;
- s = createSineStream<int8>(sampleRate, time, 0, false, false, makePartition);
+ s = createSineStream<int8>(sampleRate, time, 0, false, false);
TS_ASSERT_EQUALS(s->getLength().totalNumberOfFrames(), sampleRate * time);
delete s;
- s = createSineStream<uint16>(sampleRate, time, 0, false, false, makePartition);
+ s = createSineStream<uint16>(sampleRate, time, 0, false, false);
TS_ASSERT_EQUALS(s->getLength().totalNumberOfFrames(), sampleRate * time);
delete s;
// 48000 Hz tests
sampleRate = 48000;
- s = createSineStream<int8>(sampleRate, time, 0, false, false, makePartition);
+ s = createSineStream<int8>(sampleRate, time, 0, false, false);
TS_ASSERT_EQUALS(s->getLength().totalNumberOfFrames(), sampleRate * time);
delete s;
- s = createSineStream<uint16>(sampleRate, time, 0, true, false, makePartition);
+ s = createSineStream<uint16>(sampleRate, time, 0, true, false);
TS_ASSERT_EQUALS(s->getLength().totalNumberOfFrames(), sampleRate * time);
delete s;
// 11840 Hz tests
sampleRate = 11840;
- s = createSineStream<int8>(sampleRate, time, 0, false, false, makePartition);
+ s = createSineStream<int8>(sampleRate, time, 0, false, false);
TS_ASSERT_EQUALS(s->getLength().totalNumberOfFrames(), sampleRate * time);
delete s;
- s = createSineStream<uint16>(sampleRate, time, 0, false, false, makePartition);
+ s = createSineStream<uint16>(sampleRate, time, 0, false, false);
TS_ASSERT_EQUALS(s->getLength().totalNumberOfFrames(), sampleRate * time);
delete s;
// 11111 Hz tests
sampleRate = 11111;
- s = createSineStream<int8>(sampleRate, time, 0, false, false, makePartition);
+ s = createSineStream<int8>(sampleRate, time, 0, false, false);
TS_ASSERT_EQUALS(s->getLength().totalNumberOfFrames(), sampleRate * time);
delete s;
- s = createSineStream<uint16>(sampleRate, time, 0, false, false, makePartition);
+ s = createSineStream<uint16>(sampleRate, time, 0, false, false);
TS_ASSERT_EQUALS(s->getLength().totalNumberOfFrames(), sampleRate * time);
delete s;
// 22050 Hz stereo test
sampleRate = 22050;
- s = createSineStream<int8>(sampleRate, time, 0, false, true, makePartition);
+ s = createSineStream<int8>(sampleRate, time, 0, false, true);
TS_ASSERT_EQUALS(s->getLength().totalNumberOfFrames(), sampleRate * time);
delete s;
- s = createSineStream<uint16>(sampleRate, time, 0, true, true, makePartition);
+ s = createSineStream<uint16>(sampleRate, time, 0, true, true);
TS_ASSERT_EQUALS(s->getLength().totalNumberOfFrames(), sampleRate * time);
delete s;
}
public:
void test_length() {
- lengthTest(false);
- }
-
- void test_length_parted() {
- lengthTest(true);
+ lengthTest();
}
private:
- void seekTest(const int sampleRate, const int time, const bool isStereo, const bool makePartition) {
+ void seekTest(const int sampleRate, const int time, const bool isStereo) {
const int totalFrames = sampleRate * time * (isStereo ? 2 : 1);
int readData = 0, offset = 0;
@@ -276,7 +216,7 @@ private:
Audio::SeekableAudioStream *s = 0;
int16 *sine = 0;
- s = createSineStream<int8>(sampleRate, time, &sine, false, isStereo, makePartition);
+ s = createSineStream<int8>(sampleRate, time, &sine, false, isStereo);
// Seek to 500ms
const Audio::Timestamp a(0, 1, 2);
@@ -341,18 +281,10 @@ private:
public:
void test_seek_mono() {
- seekTest(11025, 2, false, false);
+ seekTest(11025, 2, false);
}
void test_seek_stereo() {
- seekTest(11025, 2, true, false);
- }
-
- void test_seek_mono_parted() {
- seekTest(11025, 2, false, true);
- }
-
- void test_seek_stereo_parted() {
- seekTest(11025, 2, true, true);
+ seekTest(11025, 2, true);
}
};
diff --git a/test/common/fixedstack.h b/test/common/fixedstack.h
index 9aa00b4680..9d4cceb2e6 100644
--- a/test/common/fixedstack.h
+++ b/test/common/fixedstack.h
@@ -18,18 +18,20 @@ public:
}
void test_size() {
- Common::FixedStack<int> stack;
- TS_ASSERT_EQUALS(stack.size(), 0);
+ typedef Common::FixedStack<int> Stack;
+
+ Stack stack;
+ TS_ASSERT_EQUALS(stack.size(), (Stack::size_type)0);
stack.push(5);
- TS_ASSERT_EQUALS(stack.size(), 1);
+ TS_ASSERT_EQUALS(stack.size(), (Stack::size_type)1);
stack.push(9);
stack.push(0);
- TS_ASSERT_EQUALS(stack.size(), 3);
+ TS_ASSERT_EQUALS(stack.size(), (Stack::size_type)3);
stack.pop();
- TS_ASSERT_EQUALS(stack.size(), 2);
+ TS_ASSERT_EQUALS(stack.size(), (Stack::size_type)2);
}
void test_top_pop() {
@@ -44,7 +46,7 @@ public:
stack[0] = -23;
stack.top() = 42;
TS_ASSERT_EQUALS(stack[0], -23);
- TS_ASSERT_EQUALS(stack.top(), 42);
+ TS_ASSERT_EQUALS(stack.top(), 42);
stack.pop();
TS_ASSERT_EQUALS(stack[0], -23);
diff --git a/test/common/memoryreadstream.h b/test/common/memoryreadstream.h
index a476f12a2f..adef861a5e 100644
--- a/test/common/memoryreadstream.h
+++ b/test/common/memoryreadstream.h
@@ -84,4 +84,20 @@ class MemoryReadStreamTestSuite : public CxxTest::TestSuite {
TS_ASSERT_EQUALS(ms.pos(), 7);
TS_ASSERT(!ms.eos());
}
+
+ void test_eos() {
+ byte contents[] = { 1, 2, 3, 4, 5, 6, 7 };
+ Common::MemoryReadStream ms(contents, sizeof(contents));
+
+ // Read after the end of the stream
+ for (int32 i = 0; i <= ms.size(); ++i)
+ ms.readByte();
+
+ // The eos flag should be set here
+ TS_ASSERT(ms.eos());
+
+ // Seeking should reset the eos flag
+ ms.seek(0, SEEK_SET);
+ TS_ASSERT(!ms.eos());
+ }
};
diff --git a/test/common/pack.h b/test/common/pack.h
index 724457f838..f62b31e9dc 100644
--- a/test/common/pack.h
+++ b/test/common/pack.h
@@ -15,7 +15,7 @@ struct TestStruct {
#include <common/pack-end.h> // END STRUCT PACKING
-#define OFFS(type,item) (((ptrdiff_t)(&((type*)42)->type::item))-42)
+#define OFFS(type,item) (((ptrdiff_t)(&((type *)42)->type::item))-42)
class PackTestSuite : public CxxTest::TestSuite
{
diff --git a/test/common/stack.h b/test/common/stack.h
index 0b1bcee350..ed32ec6496 100644
--- a/test/common/stack.h
+++ b/test/common/stack.h
@@ -18,18 +18,20 @@ public:
}
void test_size() {
- Common::Stack<int> stack;
- TS_ASSERT_EQUALS(stack.size(), 0);
+ typedef Common::Stack<int> Stack;
+
+ Stack stack;
+ TS_ASSERT_EQUALS(stack.size(), (Stack::size_type)0);
stack.push(5);
- TS_ASSERT_EQUALS(stack.size(), 1);
+ TS_ASSERT_EQUALS(stack.size(), (Stack::size_type)1);
stack.push(9);
stack.push(0);
- TS_ASSERT_EQUALS(stack.size(), 3);
+ TS_ASSERT_EQUALS(stack.size(), (Stack::size_type)3);
stack.pop();
- TS_ASSERT_EQUALS(stack.size(), 2);
+ TS_ASSERT_EQUALS(stack.size(), (Stack::size_type)2);
}
void test_top_pop() {
diff --git a/test/common/subreadstream.h b/test/common/subreadstream.h
index 463f49e929..32e6f938d2 100644
--- a/test/common/subreadstream.h
+++ b/test/common/subreadstream.h
@@ -26,4 +26,22 @@ class SubReadStreamTestSuite : public CxxTest::TestSuite {
b = srs.readByte();
TS_ASSERT(srs.eos());
}
+
+ void test_safe_eos() {
+ byte contents[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
+ Common::MemoryReadStream ms(contents, sizeof(contents));
+
+ Common::SafeSeekableSubReadStream ssrs1(&ms, 0, sizeof(contents));
+ Common::SafeSeekableSubReadStream ssrs2(&ms, 0, sizeof(contents));
+
+ // Read after the end of the stream of the first sub stream
+ for (int32 i = 0; i <= ssrs1.size(); ++i)
+ ssrs1.readByte();
+
+ // eos should be set for the first sub stream
+ TS_ASSERT(ssrs1.eos());
+
+ // eos should not be set for the second sub stream
+ TS_ASSERT(!ssrs2.eos());
+ }
};
diff --git a/test/cxxtest/cxxtest/ValueTraits.h b/test/cxxtest/cxxtest/ValueTraits.h
index 339a345029..45b2ea39c1 100644
--- a/test/cxxtest/cxxtest/ValueTraits.h
+++ b/test/cxxtest/cxxtest/ValueTraits.h
@@ -70,7 +70,7 @@ namespace CxxTest
//
// The default ValueTraits class dumps up to 8 bytes as hex values
//
- template <class T>
+ template<class T>
class ValueTraits
{
enum { MAX_BYTES = 8 };
@@ -85,7 +85,7 @@ namespace CxxTest
// traits( T t )
// Creates an object of type ValueTraits<T>
//
- template <class T>
+ template<class T>
inline ValueTraits<T> traits( T t )
{
return ValueTraits<T>( t );
diff --git a/video/avi_decoder.h b/video/avi_decoder.h
index 540a76855d..508760ec89 100644
--- a/video/avi_decoder.h
+++ b/video/avi_decoder.h
@@ -43,10 +43,6 @@ namespace Graphics {
struct PixelFormat;
}
-namespace Graphics {
-struct Surface;
-}
-
namespace Video {
class Codec;
diff --git a/video/bink_decoder.cpp b/video/bink_decoder.cpp
index 46ac8ac386..884ca69f17 100644
--- a/video/bink_decoder.cpp
+++ b/video/bink_decoder.cpp
@@ -113,23 +113,33 @@ BinkDecoder::BinkDecoder() {
}
_audioStream = 0;
- _audioStarted = false;
}
-BinkDecoder::~BinkDecoder() {
- close();
-}
+void BinkDecoder::startAudio() {
+ if (_audioTrack < _audioTracks.size()) {
+ const AudioTrack &audio = _audioTracks[_audioTrack];
-void BinkDecoder::close() {
- reset();
+ _audioStream = Audio::makeQueuingAudioStream(audio.outSampleRate, audio.outChannels == 2);
+ g_system->getMixer()->playStream(Audio::Mixer::kPlainSoundType, &_audioHandle, _audioStream);
+ } // else no audio
+}
+void BinkDecoder::stopAudio() {
if (_audioStream) {
- // Stop audio
g_system->getMixer()->stopHandle(_audioHandle);
_audioStream = 0;
}
+}
+
+BinkDecoder::~BinkDecoder() {
+ close();
+}
- _audioStarted = false;
+void BinkDecoder::close() {
+ reset();
+
+ // Stop audio
+ stopAudio();
for (int i = 0; i < 4; i++) {
delete[] _curPlanes[i]; _curPlanes[i] = 0;
@@ -173,7 +183,7 @@ void BinkDecoder::close() {
uint32 BinkDecoder::getElapsedTime() const {
if (_audioStream && g_system->getMixer()->isSoundHandleActive(_audioHandle))
- return g_system->getMixer()->getSoundElapsedTime(_audioHandle);
+ return g_system->getMixer()->getSoundElapsedTime(_audioHandle) + _audioStartOffset;
return g_system->getMillis() - _startTime;
}
@@ -241,11 +251,6 @@ const Graphics::Surface *BinkDecoder::decodeNextFrame() {
if (_curFrame == 0)
_startTime = g_system->getMillis();
- if (!_audioStarted && _audioStream) {
- _audioStarted = true;
- g_system->getMixer()->playStream(Audio::Mixer::kPlainSoundType, &_audioHandle, _audioStream);
- }
-
return &_surface;
}
@@ -510,6 +515,11 @@ void BinkDecoder::mergeHuffmanSymbols(VideoFrame &video, byte *dst, const byte *
}
bool BinkDecoder::loadStream(Common::SeekableReadStream *stream) {
+ Graphics::PixelFormat format = g_system->getScreenFormat();
+ return loadStream(stream, format);
+}
+
+bool BinkDecoder::loadStream(Common::SeekableReadStream *stream, const Graphics::PixelFormat &format) {
close();
_id = stream->readUint32BE();
@@ -589,7 +599,6 @@ bool BinkDecoder::loadStream(Common::SeekableReadStream *stream) {
_hasAlpha = _videoFlags & kVideoFlagAlpha;
_swapPlanes = (_id == kBIKhID) || (_id == kBIKiID); // BIKh and BIKi swap the chroma planes
- Graphics::PixelFormat format = g_system->getScreenFormat();
_surface.create(width, height, format);
// Give the planes a bit extra space
@@ -618,11 +627,8 @@ bool BinkDecoder::loadStream(Common::SeekableReadStream *stream) {
initBundles();
initHuffman();
- if (_audioTrack < _audioTracks.size()) {
- const AudioTrack &audio = _audioTracks[_audioTrack];
-
- _audioStream = Audio::makeQueuingAudioStream(audio.outSampleRate, audio.outChannels == 2);
- }
+ startAudio();
+ _audioStartOffset = 0;
return true;
}
@@ -711,15 +717,15 @@ void BinkDecoder::initBundles() {
for (int i = 0; i < 2; i++) {
int width = MAX<uint32>(cw[i], 8);
- _bundles[kSourceBlockTypes ].countLengths[i] = Common::intLog2((width >> 3) + 511) + 1;
- _bundles[kSourceSubBlockTypes].countLengths[i] = Common::intLog2((width >> 4) + 511) + 1;
- _bundles[kSourceColors ].countLengths[i] = Common::intLog2((cbw[i] )*64 + 511) + 1;
- _bundles[kSourceIntraDC ].countLengths[i] = Common::intLog2((width >> 3) + 511) + 1;
- _bundles[kSourceInterDC ].countLengths[i] = Common::intLog2((width >> 3) + 511) + 1;
- _bundles[kSourceXOff ].countLengths[i] = Common::intLog2((width >> 3) + 511) + 1;
- _bundles[kSourceYOff ].countLengths[i] = Common::intLog2((width >> 3) + 511) + 1;
- _bundles[kSourcePattern ].countLengths[i] = Common::intLog2((cbw[i] << 3) + 511) + 1;
- _bundles[kSourceRun ].countLengths[i] = Common::intLog2((cbw[i] )*48 + 511) + 1;
+ _bundles[kSourceBlockTypes ].countLengths[i] = Common::intLog2((width >> 3) + 511) + 1;
+ _bundles[kSourceSubBlockTypes].countLengths[i] = Common::intLog2(((width + 7) >> 4) + 511) + 1;
+ _bundles[kSourceColors ].countLengths[i] = Common::intLog2((cbw[i]) * 64 + 511) + 1;
+ _bundles[kSourceIntraDC ].countLengths[i] = Common::intLog2((width >> 3) + 511) + 1;
+ _bundles[kSourceInterDC ].countLengths[i] = Common::intLog2((width >> 3) + 511) + 1;
+ _bundles[kSourceXOff ].countLengths[i] = Common::intLog2((width >> 3) + 511) + 1;
+ _bundles[kSourceYOff ].countLengths[i] = Common::intLog2((width >> 3) + 511) + 1;
+ _bundles[kSourcePattern ].countLengths[i] = Common::intLog2((cbw[i] << 3) + 511) + 1;
+ _bundles[kSourceRun ].countLengths[i] = Common::intLog2((cbw[i]) * 48 + 511) + 1;
}
}
diff --git a/video/bink_decoder.h b/video/bink_decoder.h
index dd1b7ca67d..3d5e882dd7 100644
--- a/video/bink_decoder.h
+++ b/video/bink_decoder.h
@@ -76,7 +76,9 @@ public:
// FixedRateVideoDecoder
Common::Rational getFrameRate() const { return _frameRate; }
-private:
+ // Bink specific
+ bool loadStream(Common::SeekableReadStream *stream, const Graphics::PixelFormat &format);
+protected:
static const int kAudioChannelsMax = 2;
static const int kAudioBlockSizeMax = (kAudioChannelsMax << 11);
@@ -221,15 +223,13 @@ private:
Audio::SoundHandle _audioHandle;
Audio::QueuingAudioStream *_audioStream;
- bool _audioStarted;
+ int32 _audioStartOffset;
uint32 _videoFlags; ///< Video frame features.
bool _hasAlpha; ///< Do video frames have alpha?
bool _swapPlanes; ///< Are the planes ordered (A)YVU instead of (A)YUV?
- uint32 _audioFrame;
-
Common::Array<AudioTrack> _audioTracks; ///< All audio tracks.
Common::Array<VideoFrame> _frames; ///< All video frames.
@@ -259,7 +259,7 @@ private:
/** Decode an audio packet. */
void audioPacket(AudioTrack &audio);
/** Decode a video packet. */
- void videoPacket(VideoFrame &video);
+ virtual void videoPacket(VideoFrame &video);
/** Decode a plane. */
void decodePlane(VideoFrame &video, int planeIdx, bool isChroma);
@@ -327,6 +327,11 @@ private:
void IDCT(int16 *block);
void IDCTPut(DecodeContext &ctx, int16 *block);
void IDCTAdd(DecodeContext &ctx, int16 *block);
+
+ /** Start playing the audio track */
+ void startAudio();
+ /** Stop playing the audio track */
+ void stopAudio();
};
} // End of namespace Video
diff --git a/video/codecs/cinepak.h b/video/codecs/cinepak.h
index 67000bf58a..ca4552fae6 100644
--- a/video/codecs/cinepak.h
+++ b/video/codecs/cinepak.h
@@ -33,10 +33,6 @@ namespace Common {
class SeekableReadStream;
}
-namespace Graphics {
-struct Surface;
-}
-
namespace Video {
struct CinepakCodebook {
diff --git a/video/codecs/mjpeg.h b/video/codecs/mjpeg.h
index 8a446ee005..45cb57dea2 100644
--- a/video/codecs/mjpeg.h
+++ b/video/codecs/mjpeg.h
@@ -32,7 +32,6 @@ class SeekableReadStream;
namespace Graphics {
class JPEG;
-struct Surface;
}
namespace Video {
diff --git a/video/coktel_decoder.cpp b/video/coktel_decoder.cpp
index 8ea2d08acb..ae0c35cd76 100644
--- a/video/coktel_decoder.cpp
+++ b/video/coktel_decoder.cpp
@@ -1505,23 +1505,6 @@ VMDDecoder::Frame::~Frame() {
delete[] parts;
}
-
-const uint16 VMDDecoder::_tableDPCM[128] = {
- 0x0000, 0x0008, 0x0010, 0x0020, 0x0030, 0x0040, 0x0050, 0x0060, 0x0070, 0x0080,
- 0x0090, 0x00A0, 0x00B0, 0x00C0, 0x00D0, 0x00E0, 0x00F0, 0x0100, 0x0110, 0x0120,
- 0x0130, 0x0140, 0x0150, 0x0160, 0x0170, 0x0180, 0x0190, 0x01A0, 0x01B0, 0x01C0,
- 0x01D0, 0x01E0, 0x01F0, 0x0200, 0x0208, 0x0210, 0x0218, 0x0220, 0x0228, 0x0230,
- 0x0238, 0x0240, 0x0248, 0x0250, 0x0258, 0x0260, 0x0268, 0x0270, 0x0278, 0x0280,
- 0x0288, 0x0290, 0x0298, 0x02A0, 0x02A8, 0x02B0, 0x02B8, 0x02C0, 0x02C8, 0x02D0,
- 0x02D8, 0x02E0, 0x02E8, 0x02F0, 0x02F8, 0x0300, 0x0308, 0x0310, 0x0318, 0x0320,
- 0x0328, 0x0330, 0x0338, 0x0340, 0x0348, 0x0350, 0x0358, 0x0360, 0x0368, 0x0370,
- 0x0378, 0x0380, 0x0388, 0x0390, 0x0398, 0x03A0, 0x03A8, 0x03B0, 0x03B8, 0x03C0,
- 0x03C8, 0x03D0, 0x03D8, 0x03E0, 0x03E8, 0x03F0, 0x03F8, 0x0400, 0x0440, 0x0480,
- 0x04C0, 0x0500, 0x0540, 0x0580, 0x05C0, 0x0600, 0x0640, 0x0680, 0x06C0, 0x0700,
- 0x0740, 0x0780, 0x07C0, 0x0800, 0x0900, 0x0A00, 0x0B00, 0x0C00, 0x0D00, 0x0E00,
- 0x0F00, 0x1000, 0x1400, 0x1800, 0x1C00, 0x2000, 0x3000, 0x4000
-};
-
VMDDecoder::VMDDecoder(Audio::Mixer *mixer, Audio::Mixer::SoundType soundType) : CoktelDecoder(mixer, soundType),
_stream(0), _version(0), _flags(0), _frameInfoOffset(0), _partsPerFrame(0), _frames(0),
_soundFlags(0), _soundFreq(0), _soundSliceSize(0), _soundSlicesCount(0),
@@ -2402,33 +2385,36 @@ void VMDDecoder::blit24(const Graphics::Surface &srcSurf, Common::Rect &rect) {
}
void VMDDecoder::emptySoundSlice(uint32 size) {
- byte *sound = soundEmpty(size);
+ byte *soundBuf = (byte *)malloc(size);
- if (sound) {
+ if (soundBuf) {
uint32 flags = 0;
+ memset(soundBuf, 0, size);
flags |= (_soundBytesPerSample == 2) ? Audio::FLAG_16BITS : 0;
flags |= (_soundStereo > 0) ? Audio::FLAG_STEREO : 0;
- _audioStream->queueBuffer(sound, size, DisposeAfterUse::YES, flags);
+ _audioStream->queueBuffer(soundBuf, size, DisposeAfterUse::YES, flags);
}
}
void VMDDecoder::filledSoundSlice(uint32 size) {
- byte *sound = 0;
+ if (!_audioStream) {
+ _stream->skip(size);
+ return;
+ }
+
+ Common::SeekableReadStream *data = _stream->readStream(size);
+ Audio::AudioStream *sliceStream = 0;
+
if (_audioFormat == kAudioFormat8bitRaw)
- sound = sound8bitRaw(size);
+ sliceStream = create8bitRaw(data);
else if (_audioFormat == kAudioFormat16bitDPCM)
- sound = sound16bitDPCM(size);
+ sliceStream = create16bitDPCM(data);
else if (_audioFormat == kAudioFormat16bitADPCM)
- sound = sound16bitADPCM(size);
+ sliceStream = create16bitADPCM(data);
- if (sound) {
- uint32 flags = 0;
- flags |= (_soundBytesPerSample == 2) ? Audio::FLAG_16BITS : 0;
- flags |= (_soundStereo > 0) ? Audio::FLAG_STEREO : 0;
-
- _audioStream->queueBuffer(sound, size, DisposeAfterUse::YES, flags);
- }
+ if (sliceStream)
+ _audioStream->queueAudioStream(sliceStream);
}
void VMDDecoder::filledSoundSlices(uint32 size, uint32 mask) {
@@ -2475,173 +2461,120 @@ uint8 VMDDecoder::evaluateMask(uint32 mask, bool *fillInfo, uint8 &max) {
return n;
}
-byte *VMDDecoder::soundEmpty(uint32 &size) {
- if (!_audioStream)
- return 0;
+Audio::AudioStream *VMDDecoder::create8bitRaw(Common::SeekableReadStream *stream) {
+ int flags = Audio::FLAG_UNSIGNED;
- byte *soundBuf = (byte *)malloc(size);
- memset(soundBuf, 0, size);
+ if (_soundStereo != 0)
+ flags |= Audio::FLAG_STEREO;
- return soundBuf;
+ return Audio::makeRawStream(stream, _soundFreq, flags, DisposeAfterUse::YES);
}
-byte *VMDDecoder::sound8bitRaw(uint32 &size) {
- if (!_audioStream) {
- _stream->skip(size);
- return 0;
+class DPCMStream : public Audio::AudioStream {
+public:
+ DPCMStream(Common::SeekableReadStream *stream, int rate, int channels) {
+ _stream = stream;
+ _rate = rate;
+ _channels = channels;
}
- byte *soundBuf = (byte *)malloc(size);
- _stream->read(soundBuf, size);
- unsignedToSigned(soundBuf, size);
-
- return soundBuf;
-}
-
-byte *VMDDecoder::sound16bitDPCM(uint32 &size) {
- if (!_audioStream) {
- _stream->skip(size);
- return 0;
+ ~DPCMStream() {
+ delete _stream;
}
- int32 init[2];
+ int readBuffer(int16 *buffer, const int numSamples);
+ bool isStereo() const { return _channels == 2; }
+ int getRate() const { return _rate; }
+ bool endOfData() const { return _stream->pos() >= _stream->size() || _stream->eos() || _stream->err(); }
- init[0] = _stream->readSint16LE();
- size -= 2;
-
- if (_soundStereo > 0) {
- init[1] = _stream->readSint16LE();
- size -= 2;
- }
-
- byte *data = new byte[size];
- byte *sound = 0;
-
- if (_stream->read(data, size) == size)
- sound = deDPCM(data, size, init);
-
- delete[] data;
+private:
+ Common::SeekableReadStream *_stream;
+ int _channels;
+ int _rate;
+ int _buffer[2];
+};
- return sound;
-}
+int DPCMStream::readBuffer(int16 *buffer, const int numSamples) {
+ static const uint16 tableDPCM[128] = {
+ 0x0000, 0x0008, 0x0010, 0x0020, 0x0030, 0x0040, 0x0050, 0x0060, 0x0070, 0x0080,
+ 0x0090, 0x00A0, 0x00B0, 0x00C0, 0x00D0, 0x00E0, 0x00F0, 0x0100, 0x0110, 0x0120,
+ 0x0130, 0x0140, 0x0150, 0x0160, 0x0170, 0x0180, 0x0190, 0x01A0, 0x01B0, 0x01C0,
+ 0x01D0, 0x01E0, 0x01F0, 0x0200, 0x0208, 0x0210, 0x0218, 0x0220, 0x0228, 0x0230,
+ 0x0238, 0x0240, 0x0248, 0x0250, 0x0258, 0x0260, 0x0268, 0x0270, 0x0278, 0x0280,
+ 0x0288, 0x0290, 0x0298, 0x02A0, 0x02A8, 0x02B0, 0x02B8, 0x02C0, 0x02C8, 0x02D0,
+ 0x02D8, 0x02E0, 0x02E8, 0x02F0, 0x02F8, 0x0300, 0x0308, 0x0310, 0x0318, 0x0320,
+ 0x0328, 0x0330, 0x0338, 0x0340, 0x0348, 0x0350, 0x0358, 0x0360, 0x0368, 0x0370,
+ 0x0378, 0x0380, 0x0388, 0x0390, 0x0398, 0x03A0, 0x03A8, 0x03B0, 0x03B8, 0x03C0,
+ 0x03C8, 0x03D0, 0x03D8, 0x03E0, 0x03E8, 0x03F0, 0x03F8, 0x0400, 0x0440, 0x0480,
+ 0x04C0, 0x0500, 0x0540, 0x0580, 0x05C0, 0x0600, 0x0640, 0x0680, 0x06C0, 0x0700,
+ 0x0740, 0x0780, 0x07C0, 0x0800, 0x0900, 0x0A00, 0x0B00, 0x0C00, 0x0D00, 0x0E00,
+ 0x0F00, 0x1000, 0x1400, 0x1800, 0x1C00, 0x2000, 0x3000, 0x4000
+ };
+
+ assert((numSamples % _channels) == 0);
+
+ int samples = 0;
+
+ // Our starting position
+ if (_stream->pos() == 0) {
+ for (int i = 0; i < _channels; i++)
+ *buffer++ = _buffer[i] = _stream->readSint16LE();
+
+ samples += _channels;
+ }
+
+ while (!endOfData() && samples < numSamples) {
+ for (int i = 0; i < _channels; i++) {
+ byte data = _stream->readByte();
+
+ if (data & 0x80)
+ _buffer[i] -= tableDPCM[data & 0x7f];
+ else
+ _buffer[i] += tableDPCM[data];
+
+ *buffer++ = _buffer[i] = CLIP<int32>(_buffer[i], -32768, 32767);
+ }
-byte *VMDDecoder::sound16bitADPCM(uint32 &size) {
- if (!_audioStream) {
- _stream->skip(size);
- return 0;
+ samples += _channels;
}
- int32 init = _stream->readSint16LE();
- size -= 2;
-
- int32 index = _stream->readByte();
- size--;
-
- byte *data = new byte[size];
- byte *sound = 0;
-
- if (_stream->read(data, size) == size)
- sound = deADPCM(data, size, init, index);
-
- delete[] data;
-
- return sound;
+ return samples;
}
-byte *VMDDecoder::deDPCM(const byte *data, uint32 &size, int32 init[2]) {
- if (!data || (size == 0))
- return 0;
-
- int channels = (_soundStereo > 0) ? 2 : 1;
-
- uint32 inSize = size;
- uint32 outSize = size + channels;
-
- int16 *out = (int16 *)malloc(outSize * 2);
- byte *sound = (byte *)out;
-
- if (!out)
- return 0;
-
- int channel = 0;
-
- for (int i = 0; i < channels; i++) {
- *out++ = TO_BE_16(init[channel]);
+Audio::AudioStream *VMDDecoder::create16bitDPCM(Common::SeekableReadStream *stream) {
+ return new DPCMStream(stream, _soundFreq, (_soundStereo == 0) ? 1 : 2);
+}
- channel = (channel + 1) % channels;
+class VMD_ADPCMStream : public Audio::DVI_ADPCMStream {
+public:
+ VMD_ADPCMStream(Common::SeekableReadStream *stream, DisposeAfterUse::Flag disposeAfterUse,
+ int rate, int channels) : Audio::DVI_ADPCMStream(stream, disposeAfterUse, stream->size(), rate, channels, 0) {
+ // FIXME: Using the same predictor/index for two channels probably won't work
+ // properly However, we have no samples of this, so an assert is here for now.
+ // Also, since the DPCM stereo has a second predictor, I'm lead to believe
+ // all VMD with ADPCM are mono unless they changed the code in a later
+ // revision.
+ assert(channels == 1);
+ _startPredictorValue = stream->readSint16LE();
+ _startIndexValue = stream->readByte();
+ _startpos = 3;
+ reset();
}
- while (inSize-- > 0) {
- if (*data & 0x80)
- init[channel] -= _tableDPCM[*data++ & 0x7F];
- else
- init[channel] += _tableDPCM[*data++];
-
- init[channel] = CLIP<int32>(init[channel], -32768, 32767);
- *out++ = TO_BE_16(init[channel]);
-
- channel = (channel + 1) % channels;
+protected:
+ virtual void reset() {
+ Audio::DVI_ADPCMStream::reset();
+ _status.ima_ch[0].last = _startPredictorValue;
+ _status.ima_ch[0].stepIndex = _startIndexValue;
}
- size = outSize * 2;
- return sound;
-}
-
-// Yet another IMA ADPCM variant
-byte *VMDDecoder::deADPCM(const byte *data, uint32 &size, int32 init, int32 index) {
- if (!data || (size == 0))
- return 0;
-
- uint32 outSize = size * 2;
-
- int16 *out = (int16 *)malloc(outSize * 2);
- byte *sound = (byte *) out;
-
- index = CLIP<int32>(index, 0, 88);
-
- int32 predictor = Audio::Ima_ADPCMStream::_imaTable[index];
-
- uint32 dataByte = 0;
- bool newByte = true;
-
- size *= 2;
- while (size -- > 0) {
- byte code = 0;
-
- if (newByte) {
- dataByte = *data++;
- code = (dataByte >> 4) & 0xF;
- } else
- code = dataByte & 0xF;
-
- newByte = !newByte;
-
- index += Audio::ADPCMStream::_stepAdjustTable[code];
- index = CLIP<int32>(index, 0, 88);
-
- int32 value = predictor / 8;
-
- if (code & 4)
- value += predictor;
- if (code & 2)
- value += predictor / 2;
- if (code & 1)
- value += predictor / 4;
-
- if (code & 8)
- init -= value;
- else
- init += value;
-
- init = CLIP<int32>(init, -32768, 32767);
-
- predictor = Audio::Ima_ADPCMStream::_imaTable[index];
-
- *out++ = TO_BE_16(init);
- }
+private:
+ int32 _startPredictorValue;
+ int32 _startIndexValue;
+};
- size = outSize * 2;
- return sound;
+Audio::AudioStream *VMDDecoder::create16bitADPCM(Common::SeekableReadStream *stream) {
+ return new VMD_ADPCMStream(stream, DisposeAfterUse::YES, _soundFreq, (_soundStereo == 0) ? 1 : 2);
}
Graphics::PixelFormat VMDDecoder::getPixelFormat() const {
diff --git a/video/coktel_decoder.h b/video/coktel_decoder.h
index 8ad1456037..b99a44f332 100644
--- a/video/coktel_decoder.h
+++ b/video/coktel_decoder.h
@@ -437,9 +437,6 @@ private:
~Frame();
};
- // Tables for the audio decompressors
- static const uint16 _tableDPCM[128];
-
Common::SeekableReadStream *_stream;
byte _version;
@@ -508,15 +505,10 @@ private:
uint8 evaluateMask(uint32 mask, bool *fillInfo, uint8 &max);
- // Generating sound slices
- byte *soundEmpty (uint32 &size);
- byte *sound8bitRaw (uint32 &size);
- byte *sound16bitDPCM (uint32 &size);
- byte *sound16bitADPCM(uint32 &size);
-
- // Sound decompression
- byte *deDPCM (const byte *data, uint32 &size, int32 init[2]);
- byte *deADPCM(const byte *data, uint32 &size, int32 init, int32 index);
+ // Generating audio streams
+ Audio::AudioStream *create8bitRaw (Common::SeekableReadStream *stream);
+ Audio::AudioStream *create16bitDPCM (Common::SeekableReadStream *stream);
+ Audio::AudioStream *create16bitADPCM(Common::SeekableReadStream *stream);
bool getPartCoords(int16 frame, PartType type, int16 &x, int16 &y, int16 &width, int16 &height);
};
diff --git a/video/dxa_decoder.cpp b/video/dxa_decoder.cpp
index 561719a27d..7d1112a59c 100644
--- a/video/dxa_decoder.cpp
+++ b/video/dxa_decoder.cpp
@@ -115,9 +115,9 @@ bool DXADecoder::loadStream(Common::SeekableReadStream *stream) {
_scaledBuffer = 0;
if (_scaleMode != S_NONE) {
_scaledBuffer = (uint8 *)malloc(_frameSize);
- memset(_scaledBuffer, 0, _frameSize);
if (!_scaledBuffer)
error("Error allocating scale buffer (size %u)", _frameSize);
+ memset(_scaledBuffer, 0, _frameSize);
}
#ifdef DXA_EXPERIMENT_MAXD
@@ -318,7 +318,7 @@ void DXADecoder::decode13(int size) {
for (uint32 by = 0; by < _curHeight; by += BLOCKH) {
for (uint32 bx = 0; bx < _width; bx += BLOCKW) {
uint8 type = *codeBuf++;
- uint8 *b2 = (uint8*)_frameBuffer1 + bx + by * _width;
+ uint8 *b2 = (uint8 *)_frameBuffer1 + bx + by * _width;
switch (type) {
case 0:
@@ -369,7 +369,7 @@ void DXADecoder::decode13(int size) {
if (mbyte & 0x08)
my = -my;
- uint8 *b1 = (uint8*)_frameBuffer2 + (bx+mx) + (by+my) * _width;
+ uint8 *b1 = (uint8 *)_frameBuffer2 + (bx+mx) + (by+my) * _width;
for (int yc = 0; yc < BLOCKH; yc++) {
memcpy(b2, b1, BLOCKW);
b1 += _width;
@@ -385,7 +385,7 @@ void DXADecoder::decode13(int size) {
for (int subBlock = 0; subBlock < 4; subBlock++) {
int sx = bx + subX[subBlock], sy = by + subY[subBlock];
- b2 = (uint8*)_frameBuffer1 + sx + sy * _width;
+ b2 = (uint8 *)_frameBuffer1 + sx + sy * _width;
switch (subMask & 0xC0) {
// 00: skip
case 0x00:
@@ -413,7 +413,7 @@ void DXADecoder::decode13(int size) {
if (mbyte & 0x08)
my = -my;
- uint8 *b1 = (uint8*)_frameBuffer2 + (sx+mx) + (sy+my) * _width;
+ uint8 *b1 = (uint8 *)_frameBuffer2 + (sx+mx) + (sy+my) * _width;
for (int yc = 0; yc < BLOCKH / 2; yc++) {
memcpy(b2, b1, BLOCKW / 2);
b1 += _width;
@@ -489,9 +489,9 @@ const Graphics::Surface *DXADecoder::decodeNextFrame() {
if ((_inBuffer == NULL) || (_inBufferSize < size)) {
free(_inBuffer);
_inBuffer = (byte *)malloc(size);
- memset(_inBuffer, 0, size);
if (_inBuffer == NULL)
error("Error allocating input buffer (size %u)", size);
+ memset(_inBuffer, 0, size);
_inBufferSize = size;
}
diff --git a/video/dxa_decoder.h b/video/dxa_decoder.h
index 4eb4a8958d..d13cd3076c 100644
--- a/video/dxa_decoder.h
+++ b/video/dxa_decoder.h
@@ -31,10 +31,6 @@ namespace Common {
class SeekableReadStream;
}
-namespace Graphics {
-struct Surface;
-}
-
namespace Video {
/**
diff --git a/video/module.mk b/video/module.mk
index ceeac94384..900a781d0a 100644
--- a/video/module.mk
+++ b/video/module.mk
@@ -5,6 +5,7 @@ MODULE_OBJS := \
coktel_decoder.o \
dxa_decoder.o \
flic_decoder.o \
+ psx_decoder.o \
qt_decoder.o \
smk_decoder.o \
video_decoder.o \
diff --git a/video/psx_decoder.cpp b/video/psx_decoder.cpp
new file mode 100644
index 0000000000..7c04b7f041
--- /dev/null
+++ b/video/psx_decoder.cpp
@@ -0,0 +1,697 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+// PlayStation Stream demuxer and XA audio decoder based on FFmpeg/libav
+// MDEC video emulation based on http://kenai.com/downloads/jpsxdec/Old/PlayStation1_STR_format1-00.txt
+
+#include "audio/audiostream.h"
+#include "audio/mixer.h"
+#include "audio/decoders/raw.h"
+#include "common/bitstream.h"
+#include "common/huffman.h"
+#include "common/memstream.h"
+#include "common/stream.h"
+#include "common/system.h"
+#include "common/textconsole.h"
+#include "graphics/yuv_to_rgb.h"
+
+#include "video/psx_decoder.h"
+
+namespace Video {
+
+// Here are the codes/lengths/symbols that are used for decoding
+// DC coefficients (version 3 frames only)
+
+#define DC_CODE_COUNT 9
+#define DC_HUFF_VAL(b, n, p) (((b) << 16) | ((n) << 8) | (p))
+#define GET_DC_BITS(x) ((x) >> 16)
+#define GET_DC_NEG(x) ((int)(((x) >> 8) & 0xff))
+#define GET_DC_POS(x) ((int)((x) & 0xff))
+
+static const uint32 s_huffmanDCChromaCodes[DC_CODE_COUNT] = {
+ 254, 126, 62, 30, 14, 6, 2, 1, 0
+};
+
+static const byte s_huffmanDCChromaLengths[DC_CODE_COUNT] = {
+ 8, 7, 6, 5, 4, 3, 2, 2, 2
+};
+
+static const uint32 s_huffmanDCLumaCodes[DC_CODE_COUNT] = {
+ 126, 62, 30, 14, 6, 5, 1, 0, 4
+};
+
+static const byte s_huffmanDCLumaLengths[DC_CODE_COUNT] = {
+ 7, 6, 5, 4, 3, 3, 2, 2, 3
+};
+
+static const uint32 s_huffmanDCSymbols[DC_CODE_COUNT] = {
+ DC_HUFF_VAL(8, 255, 128), DC_HUFF_VAL(7, 127, 64), DC_HUFF_VAL(6, 63, 32),
+ DC_HUFF_VAL(5, 31, 16), DC_HUFF_VAL(4, 15, 8), DC_HUFF_VAL(3, 7, 4),
+ DC_HUFF_VAL(2, 3, 2), DC_HUFF_VAL(1, 1, 1), DC_HUFF_VAL(0, 0, 0)
+};
+
+// Here are the codes/lengths/symbols that are used for decoding
+// DC coefficients (version 2 and 3 frames)
+
+#define AC_CODE_COUNT 113
+#define AC_HUFF_VAL(z, a) ((z << 8) | a)
+#define ESCAPE_CODE ((uint32)-1) // arbitrary, just so we can tell what code it is
+#define END_OF_BLOCK ((uint32)-2) // arbitrary, just so we can tell what code it is
+#define GET_AC_ZERO_RUN(code) (code >> 8)
+#define GET_AC_COEFFICIENT(code) ((int)(code & 0xff))
+
+static const uint32 s_huffmanACCodes[AC_CODE_COUNT] = {
+ // Regular codes
+ 3, 3, 4, 5, 5, 6, 7, 4, 5, 6, 7, 4, 5, 6, 7,
+ 32, 33, 34, 35, 36, 37, 38, 39, 8, 9, 10, 11,
+ 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22,
+ 23, 24, 25, 26, 27, 28, 29, 30, 31, 16, 17,
+ 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28,
+ 29, 30, 31, 16, 17, 18, 19, 20, 21, 22, 23,
+ 24, 25, 26, 27, 28, 29, 30, 31, 16, 17, 18,
+ 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
+ 30, 31, 16, 17, 18, 19, 20, 21, 22, 23, 24,
+ 25, 26, 27, 28, 29, 30, 31,
+
+ // Escape code
+ 1,
+ // End of block code
+ 2
+};
+
+static const byte s_huffmanACLengths[AC_CODE_COUNT] = {
+ // Regular codes
+ 2, 3, 4, 4, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7,
+ 8, 8, 8, 8, 8, 8, 8, 8, 10, 10, 10, 10, 10,
+ 10, 10, 10, 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16,
+
+ // Escape code
+ 6,
+ // End of block code
+ 2
+};
+
+static const uint32 s_huffmanACSymbols[AC_CODE_COUNT] = {
+ // Regular codes
+ AC_HUFF_VAL(0, 1), AC_HUFF_VAL(1, 1), AC_HUFF_VAL(0, 2), AC_HUFF_VAL(2, 1), AC_HUFF_VAL(0, 3),
+ AC_HUFF_VAL(4, 1), AC_HUFF_VAL(3, 1), AC_HUFF_VAL(7, 1), AC_HUFF_VAL(6, 1), AC_HUFF_VAL(1, 2),
+ AC_HUFF_VAL(5, 1), AC_HUFF_VAL(2, 2), AC_HUFF_VAL(9, 1), AC_HUFF_VAL(0, 4), AC_HUFF_VAL(8, 1),
+ AC_HUFF_VAL(13, 1), AC_HUFF_VAL(0, 6), AC_HUFF_VAL(12, 1), AC_HUFF_VAL(11, 1), AC_HUFF_VAL(3, 2),
+ AC_HUFF_VAL(1, 3), AC_HUFF_VAL(0, 5), AC_HUFF_VAL(10, 1), AC_HUFF_VAL(16, 1), AC_HUFF_VAL(5, 2),
+ AC_HUFF_VAL(0, 7), AC_HUFF_VAL(2, 3), AC_HUFF_VAL(1, 4), AC_HUFF_VAL(15, 1), AC_HUFF_VAL(14, 1),
+ AC_HUFF_VAL(4, 2), AC_HUFF_VAL(0, 11), AC_HUFF_VAL(8, 2), AC_HUFF_VAL(4, 3), AC_HUFF_VAL(0, 10),
+ AC_HUFF_VAL(2, 4), AC_HUFF_VAL(7, 2), AC_HUFF_VAL(21, 1), AC_HUFF_VAL(20, 1), AC_HUFF_VAL(0, 9),
+ AC_HUFF_VAL(19, 1), AC_HUFF_VAL(18, 1), AC_HUFF_VAL(1, 5), AC_HUFF_VAL(3, 3), AC_HUFF_VAL(0, 8),
+ AC_HUFF_VAL(6, 2), AC_HUFF_VAL(17, 1), AC_HUFF_VAL(10, 2), AC_HUFF_VAL(9, 2), AC_HUFF_VAL(5, 3),
+ AC_HUFF_VAL(3, 4), AC_HUFF_VAL(2, 5), AC_HUFF_VAL(1, 7), AC_HUFF_VAL(1, 6), AC_HUFF_VAL(0, 15),
+ AC_HUFF_VAL(0, 14), AC_HUFF_VAL(0, 13), AC_HUFF_VAL(0, 12), AC_HUFF_VAL(26, 1), AC_HUFF_VAL(25, 1),
+ AC_HUFF_VAL(24, 1), AC_HUFF_VAL(23, 1), AC_HUFF_VAL(22, 1), AC_HUFF_VAL(0, 31), AC_HUFF_VAL(0, 30),
+ AC_HUFF_VAL(0, 29), AC_HUFF_VAL(0, 28), AC_HUFF_VAL(0, 27), AC_HUFF_VAL(0, 26), AC_HUFF_VAL(0, 25),
+ AC_HUFF_VAL(0, 24), AC_HUFF_VAL(0, 23), AC_HUFF_VAL(0, 22), AC_HUFF_VAL(0, 21), AC_HUFF_VAL(0, 20),
+ AC_HUFF_VAL(0, 19), AC_HUFF_VAL(0, 18), AC_HUFF_VAL(0, 17), AC_HUFF_VAL(0, 16), AC_HUFF_VAL(0, 40),
+ AC_HUFF_VAL(0, 39), AC_HUFF_VAL(0, 38), AC_HUFF_VAL(0, 37), AC_HUFF_VAL(0, 36), AC_HUFF_VAL(0, 35),
+ AC_HUFF_VAL(0, 34), AC_HUFF_VAL(0, 33), AC_HUFF_VAL(0, 32), AC_HUFF_VAL(1, 14), AC_HUFF_VAL(1, 13),
+ AC_HUFF_VAL(1, 12), AC_HUFF_VAL(1, 11), AC_HUFF_VAL(1, 10), AC_HUFF_VAL(1, 9), AC_HUFF_VAL(1, 8),
+ AC_HUFF_VAL(1, 18), AC_HUFF_VAL(1, 17), AC_HUFF_VAL(1, 16), AC_HUFF_VAL(1, 15), AC_HUFF_VAL(6, 3),
+ AC_HUFF_VAL(16, 2), AC_HUFF_VAL(15, 2), AC_HUFF_VAL(14, 2), AC_HUFF_VAL(13, 2), AC_HUFF_VAL(12, 2),
+ AC_HUFF_VAL(11, 2), AC_HUFF_VAL(31, 1), AC_HUFF_VAL(30, 1), AC_HUFF_VAL(29, 1), AC_HUFF_VAL(28, 1),
+ AC_HUFF_VAL(27, 1),
+
+ // Escape code
+ ESCAPE_CODE,
+ // End of block code
+ END_OF_BLOCK
+};
+
+PSXStreamDecoder::PSXStreamDecoder(CDSpeed speed, uint32 frameCount) : _nextFrameStartTime(0, speed), _frameCount(frameCount) {
+ _stream = 0;
+ _audStream = 0;
+ _surface = new Graphics::Surface();
+ _yBuffer = _cbBuffer = _crBuffer = 0;
+ _acHuffman = new Common::Huffman(0, AC_CODE_COUNT, s_huffmanACCodes, s_huffmanACLengths, s_huffmanACSymbols);
+ _dcHuffmanChroma = new Common::Huffman(0, DC_CODE_COUNT, s_huffmanDCChromaCodes, s_huffmanDCChromaLengths, s_huffmanDCSymbols);
+ _dcHuffmanLuma = new Common::Huffman(0, DC_CODE_COUNT, s_huffmanDCLumaCodes, s_huffmanDCLumaLengths, s_huffmanDCSymbols);
+}
+
+PSXStreamDecoder::~PSXStreamDecoder() {
+ close();
+ delete _surface;
+ delete _acHuffman;
+ delete _dcHuffmanLuma;
+ delete _dcHuffmanChroma;
+}
+
+#define RAW_CD_SECTOR_SIZE 2352
+
+#define CDXA_TYPE_MASK 0x0E
+#define CDXA_TYPE_DATA 0x08
+#define CDXA_TYPE_AUDIO 0x04
+#define CDXA_TYPE_VIDEO 0x02
+
+bool PSXStreamDecoder::loadStream(Common::SeekableReadStream *stream) {
+ close();
+
+ _stream = stream;
+
+ Common::SeekableReadStream *sector = readSector();
+
+ if (!sector) {
+ close();
+ return false;
+ }
+
+ // Rip out video info from the first frame
+ sector->seek(18);
+ byte sectorType = sector->readByte() & CDXA_TYPE_MASK;
+
+ if (sectorType != CDXA_TYPE_VIDEO && sectorType != CDXA_TYPE_DATA) {
+ close();
+ return false;
+ }
+
+ sector->seek(40);
+
+ uint16 width = sector->readUint16LE();
+ uint16 height = sector->readUint16LE();
+ _surface->create(width, height, g_system->getScreenFormat());
+
+ _macroBlocksW = (width + 15) / 16;
+ _macroBlocksH = (height + 15) / 16;
+ _yBuffer = new byte[_macroBlocksW * _macroBlocksH * 16 * 16];
+ _cbBuffer = new byte[_macroBlocksW * _macroBlocksH * 8 * 8];
+ _crBuffer = new byte[_macroBlocksW * _macroBlocksH * 8 * 8];
+
+ delete sector;
+ _stream->seek(0);
+
+ return true;
+}
+
+void PSXStreamDecoder::close() {
+ if (!_stream)
+ return;
+
+ delete _stream;
+ _stream = 0;
+
+ // Deinitialize sound
+ g_system->getMixer()->stopHandle(_audHandle);
+ _audStream = 0;
+
+ _surface->free();
+
+ memset(&_adpcmStatus, 0, sizeof(_adpcmStatus));
+
+ _macroBlocksW = _macroBlocksH = 0;
+ delete[] _yBuffer; _yBuffer = 0;
+ delete[] _cbBuffer; _cbBuffer = 0;
+ delete[] _crBuffer; _crBuffer = 0;
+
+ reset();
+}
+
+uint32 PSXStreamDecoder::getElapsedTime() const {
+ // TODO: Currently, the audio is always after the video so using this
+ // can often lead to gaps in the audio...
+ //if (_audStream)
+ // return _mixer->getSoundElapsedTime(_audHandle);
+
+ return VideoDecoder::getElapsedTime();
+}
+
+uint32 PSXStreamDecoder::getTimeToNextFrame() const {
+ if (!isVideoLoaded() || endOfVideo())
+ return 0;
+
+ uint32 nextTimeMillis = _nextFrameStartTime.msecs();
+ uint32 elapsedTime = getElapsedTime();
+
+ if (elapsedTime > nextTimeMillis)
+ return 0;
+
+ return nextTimeMillis - elapsedTime;
+}
+
+#define VIDEO_DATA_CHUNK_SIZE 2016
+#define VIDEO_DATA_HEADER_SIZE 56
+
+const Graphics::Surface *PSXStreamDecoder::decodeNextFrame() {
+ Common::SeekableReadStream *sector = 0;
+ byte *partialFrame = 0;
+ int sectorsRead = 0;
+
+ while (!endOfVideo()) {
+ sector = readSector();
+ sectorsRead++;
+
+ if (!sector)
+ error("Corrupt PSX stream sector");
+
+ sector->seek(0x11);
+ byte track = sector->readByte();
+ if (track >= 32)
+ error("Bad PSX stream track");
+
+ byte sectorType = sector->readByte() & CDXA_TYPE_MASK;
+
+ switch (sectorType) {
+ case CDXA_TYPE_DATA:
+ case CDXA_TYPE_VIDEO:
+ if (track == 1) {
+ sector->seek(28);
+ uint16 curSector = sector->readUint16LE();
+ uint16 sectorCount = sector->readUint16LE();
+ sector->readUint32LE();
+ uint16 frameSize = sector->readUint32LE();
+
+ if (curSector >= sectorCount)
+ error("Bad sector");
+
+ if (!partialFrame)
+ partialFrame = (byte *)malloc(sectorCount * VIDEO_DATA_CHUNK_SIZE);
+
+ sector->seek(VIDEO_DATA_HEADER_SIZE);
+ sector->read(partialFrame + curSector * VIDEO_DATA_CHUNK_SIZE, VIDEO_DATA_CHUNK_SIZE);
+
+ if (curSector == sectorCount - 1) {
+ // Done assembling the frame
+ Common::SeekableReadStream *frame = new Common::MemoryReadStream(partialFrame, frameSize, DisposeAfterUse::YES);
+
+ decodeFrame(frame);
+
+ delete frame;
+ delete sector;
+
+ _curFrame++;
+ if (_curFrame == 0)
+ _startTime = g_system->getMillis();
+
+ // Increase the time by the amount of sectors we read
+ // One may notice that this is still not the most precise
+ // method since a frame takes up the time its sectors took
+ // up instead of the amount of time it takes the next frame
+ // to be read from the sectors. The actual frame rate should
+ // be constant instead of variable, so the slight difference
+ // in a frame's showing time is negligible (1/150 of a second).
+ _nextFrameStartTime = _nextFrameStartTime.addFrames(sectorsRead);
+
+ return _surface;
+ }
+ } else
+ error("Unhandled multi-track video");
+ break;
+ case CDXA_TYPE_AUDIO:
+ // We only handle one audio channel so far
+ if (track == 1)
+ queueAudioFromSector(sector);
+ else
+ warning("Unhandled multi-track audio");
+ break;
+ default:
+ // This shows up way too often, but the other sectors
+ // are safe to ignore
+ //warning("Unknown PSX sector type 0x%x", sectorType);
+ break;
+ }
+
+ delete sector;
+ }
+
+ return 0;
+}
+
+static const byte s_syncHeader[12] = { 0x00, 0xff ,0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00 };
+
+Common::SeekableReadStream *PSXStreamDecoder::readSector() {
+ assert(_stream);
+
+ Common::SeekableReadStream *stream = _stream->readStream(RAW_CD_SECTOR_SIZE);
+
+ byte syncHeader[12];
+ stream->read(syncHeader, 12);
+ if (!memcmp(s_syncHeader, syncHeader, 12))
+ return stream;
+
+ return 0;
+}
+
+// Ha! It's palindromic!
+#define AUDIO_DATA_CHUNK_SIZE 2304
+#define AUDIO_DATA_SAMPLE_COUNT 4032
+
+static const int s_xaTable[5][2] = {
+ { 0, 0 },
+ { 60, 0 },
+ { 115, -52 },
+ { 98, -55 },
+ { 122, -60 }
+};
+
+void PSXStreamDecoder::queueAudioFromSector(Common::SeekableReadStream *sector) {
+ assert(sector);
+
+ if (!_audStream) {
+ // Initialize audio stream
+ sector->seek(19);
+ byte format = sector->readByte();
+
+ bool stereo = (format & (1 << 0)) != 0;
+ uint rate = (format & (1 << 2)) ? 18900 : 37800;
+
+ _audStream = Audio::makeQueuingAudioStream(rate, stereo);
+ g_system->getMixer()->playStream(Audio::Mixer::kPlainSoundType, &_audHandle, _audStream);
+ }
+
+ sector->seek(24);
+
+ // This XA audio is different (yet similar) from normal XA audio! Watch out!
+ // TODO: It's probably similar enough to normal XA that we can merge it somehow...
+ // TODO: RTZ PSX needs the same audio code in a regular AudioStream class. Probably
+ // will do something similar to QuickTime and creating a base class 'ISOMode2Parser'
+ // or something similar.
+ byte *buf = new byte[AUDIO_DATA_CHUNK_SIZE];
+ sector->read(buf, AUDIO_DATA_CHUNK_SIZE);
+
+ int channels = _audStream->isStereo() ? 2 : 1;
+ int16 *dst = new int16[AUDIO_DATA_SAMPLE_COUNT];
+ int16 *leftChannel = dst;
+ int16 *rightChannel = dst + 1;
+
+ for (byte *src = buf; src < buf + AUDIO_DATA_CHUNK_SIZE; src += 128) {
+ for (int i = 0; i < 4; i++) {
+ int shift = 12 - (src[4 + i * 2] & 0xf);
+ int filter = src[4 + i * 2] >> 4;
+ int f0 = s_xaTable[filter][0];
+ int f1 = s_xaTable[filter][1];
+ int16 s_1 = _adpcmStatus[0].sample[0];
+ int16 s_2 = _adpcmStatus[0].sample[1];
+
+ for (int j = 0; j < 28; j++) {
+ byte d = src[16 + i + j * 4];
+ int t = (int8)(d << 4) >> 4;
+ int s = (t << shift) + ((s_1 * f0 + s_2 * f1 + 32) >> 6);
+ s_2 = s_1;
+ s_1 = CLIP<int>(s, -32768, 32767);
+ *leftChannel = s_1;
+ leftChannel += channels;
+ }
+
+ if (channels == 2) {
+ _adpcmStatus[0].sample[0] = s_1;
+ _adpcmStatus[0].sample[1] = s_2;
+ s_1 = _adpcmStatus[1].sample[0];
+ s_2 = _adpcmStatus[1].sample[1];
+ }
+
+ shift = 12 - (src[5 + i * 2] & 0xf);
+ filter = src[5 + i * 2] >> 4;
+ f0 = s_xaTable[filter][0];
+ f1 = s_xaTable[filter][1];
+
+ for (int j = 0; j < 28; j++) {
+ byte d = src[16 + i + j * 4];
+ int t = (int8)d >> 4;
+ int s = (t << shift) + ((s_1 * f0 + s_2 * f1 + 32) >> 6);
+ s_2 = s_1;
+ s_1 = CLIP<int>(s, -32768, 32767);
+
+ if (channels == 2) {
+ *rightChannel = s_1;
+ rightChannel += 2;
+ } else {
+ *leftChannel++ = s_1;
+ }
+ }
+
+ if (channels == 2) {
+ _adpcmStatus[1].sample[0] = s_1;
+ _adpcmStatus[1].sample[1] = s_2;
+ } else {
+ _adpcmStatus[0].sample[0] = s_1;
+ _adpcmStatus[0].sample[1] = s_2;
+ }
+ }
+ }
+
+ int flags = Audio::FLAG_16BITS;
+
+ if (_audStream->isStereo())
+ flags |= Audio::FLAG_STEREO;
+
+#ifdef SCUMM_LITTLE_ENDIAN
+ flags |= Audio::FLAG_LITTLE_ENDIAN;
+#endif
+
+ _audStream->queueBuffer((byte *)dst, AUDIO_DATA_SAMPLE_COUNT * 2, DisposeAfterUse::YES, flags);
+ delete[] buf;
+}
+
+void PSXStreamDecoder::decodeFrame(Common::SeekableReadStream *frame) {
+ // A frame is essentially an MPEG-1 intra frame
+
+ Common::BitStream16LEMSB bits(frame);
+
+ bits.skip(16); // unknown
+ bits.skip(16); // 0x3800
+ uint16 scale = bits.getBits(16);
+ uint16 version = bits.getBits(16);
+
+ if (version != 2 && version != 3)
+ error("Unknown PSX stream frame version");
+
+ // Initalize default v3 DC here
+ _lastDC[0] = _lastDC[1] = _lastDC[2] = 0;
+
+ for (int mbX = 0; mbX < _macroBlocksW; mbX++)
+ for (int mbY = 0; mbY < _macroBlocksH; mbY++)
+ decodeMacroBlock(&bits, mbX, mbY, scale, version);
+
+ // Output data onto the frame
+ Graphics::convertYUV420ToRGB(_surface, _yBuffer, _cbBuffer, _crBuffer, _surface->w, _surface->h, _macroBlocksW * 16, _macroBlocksW * 8);
+}
+
+void PSXStreamDecoder::decodeMacroBlock(Common::BitStream *bits, int mbX, int mbY, uint16 scale, uint16 version) {
+ int pitchY = _macroBlocksW * 16;
+ int pitchC = _macroBlocksW * 8;
+
+ // Note the strange order of red before blue
+ decodeBlock(bits, _crBuffer + (mbY * pitchC + mbX) * 8, pitchC, scale, version, kPlaneV);
+ decodeBlock(bits, _cbBuffer + (mbY * pitchC + mbX) * 8, pitchC, scale, version, kPlaneU);
+ decodeBlock(bits, _yBuffer + (mbY * pitchY + mbX) * 16, pitchY, scale, version, kPlaneY);
+ decodeBlock(bits, _yBuffer + (mbY * pitchY + mbX) * 16 + 8, pitchY, scale, version, kPlaneY);
+ decodeBlock(bits, _yBuffer + (mbY * pitchY + mbX) * 16 + 8 * pitchY, pitchY, scale, version, kPlaneY);
+ decodeBlock(bits, _yBuffer + (mbY * pitchY + mbX) * 16 + 8 * pitchY + 8, pitchY, scale, version, kPlaneY);
+}
+
+// Standard JPEG/MPEG zig zag table
+static const byte s_zigZagTable[8 * 8] = {
+ 0, 1, 5, 6, 14, 15, 27, 28,
+ 2, 4, 7, 13, 16, 26, 29, 42,
+ 3, 8, 12, 17, 25, 30, 41, 43,
+ 9, 11, 18, 24, 31, 40, 44, 53,
+ 10, 19, 23, 32, 39, 45, 52, 54,
+ 20, 22, 33, 38, 46, 51, 55, 60,
+ 21, 34, 37, 47, 50, 56, 59, 61,
+ 35, 36, 48, 49, 57, 58, 62, 63
+};
+
+// One byte different from the standard MPEG-1 table
+static const byte s_quantizationTable[8 * 8] = {
+ 2, 16, 19, 22, 26, 27, 29, 34,
+ 16, 16, 22, 24, 27, 29, 34, 37,
+ 19, 22, 26, 27, 29, 34, 34, 38,
+ 22, 22, 26, 27, 29, 34, 37, 40,
+ 22, 26, 27, 29, 32, 35, 40, 48,
+ 26, 27, 29, 32, 35, 40, 48, 58,
+ 26, 27, 29, 34, 38, 46, 56, 69,
+ 27, 29, 35, 38, 46, 56, 69, 83
+};
+
+void PSXStreamDecoder::dequantizeBlock(int *coefficients, float *block, uint16 scale) {
+ // Dequantize the data, un-zig-zagging as we go along
+ for (int i = 0; i < 8 * 8; i++) {
+ if (i == 0) // Special case for the DC coefficient
+ block[i] = coefficients[i] * s_quantizationTable[i];
+ else
+ block[i] = (float)coefficients[s_zigZagTable[i]] * s_quantizationTable[i] * scale / 8;
+ }
+}
+
+int PSXStreamDecoder::readDC(Common::BitStream *bits, uint16 version, PlaneType plane) {
+ // Version 2 just has its coefficient as 10-bits
+ if (version == 2)
+ return readSignedCoefficient(bits);
+
+ // Version 3 has it stored as huffman codes as a difference from the previous DC value
+
+ Common::Huffman *huffman = (plane == kPlaneY) ? _dcHuffmanLuma : _dcHuffmanChroma;
+
+ uint32 symbol = huffman->getSymbol(*bits);
+ int dc = 0;
+
+ if (GET_DC_BITS(symbol) != 0) {
+ bool negative = (bits->getBit() == 0);
+ dc = bits->getBits(GET_DC_BITS(symbol) - 1);
+
+ if (negative)
+ dc -= GET_DC_NEG(symbol);
+ else
+ dc += GET_DC_POS(symbol);
+ }
+
+ _lastDC[plane] += dc * 4; // convert from 8-bit to 10-bit
+ return _lastDC[plane];
+}
+
+#define BLOCK_OVERFLOW_CHECK() \
+ if (count > 63) \
+ error("PSXStreamDecoder::readAC(): Too many coefficients")
+
+void PSXStreamDecoder::readAC(Common::BitStream *bits, int *block) {
+ // Clear the block first
+ for (int i = 0; i < 63; i++)
+ block[i] = 0;
+
+ int count = 0;
+
+ while (!bits->eos()) {
+ uint32 symbol = _acHuffman->getSymbol(*bits);
+
+ if (symbol == ESCAPE_CODE) {
+ // The escape code!
+ int zeroes = bits->getBits(6);
+ count += zeroes + 1;
+ BLOCK_OVERFLOW_CHECK();
+ block += zeroes;
+ *block++ = readSignedCoefficient(bits);
+ } else if (symbol == END_OF_BLOCK) {
+ // We're done
+ break;
+ } else {
+ // Normal huffman code
+ int zeroes = GET_AC_ZERO_RUN(symbol);
+ count += zeroes + 1;
+ BLOCK_OVERFLOW_CHECK();
+ block += zeroes;
+
+ if (bits->getBit())
+ *block++ = -GET_AC_COEFFICIENT(symbol);
+ else
+ *block++ = GET_AC_COEFFICIENT(symbol);
+ }
+ }
+}
+
+int PSXStreamDecoder::readSignedCoefficient(Common::BitStream *bits) {
+ uint val = bits->getBits(10);
+
+ // extend the sign
+ uint shift = 8 * sizeof(int) - 10;
+ return (int)(val << shift) >> shift;
+}
+
+// IDCT table built with :
+// _idct8x8[x][y] = cos(((2 * x + 1) * y) * (M_PI / 16.0)) * 0.5;
+// _idct8x8[x][y] /= sqrt(2.0) if y == 0
+static const double s_idct8x8[8][8] = {
+ { 0.353553390593274, 0.490392640201615, 0.461939766255643, 0.415734806151273, 0.353553390593274, 0.277785116509801, 0.191341716182545, 0.097545161008064 },
+ { 0.353553390593274, 0.415734806151273, 0.191341716182545, -0.097545161008064, -0.353553390593274, -0.490392640201615, -0.461939766255643, -0.277785116509801 },
+ { 0.353553390593274, 0.277785116509801, -0.191341716182545, -0.490392640201615, -0.353553390593274, 0.097545161008064, 0.461939766255643, 0.415734806151273 },
+ { 0.353553390593274, 0.097545161008064, -0.461939766255643, -0.277785116509801, 0.353553390593274, 0.415734806151273, -0.191341716182545, -0.490392640201615 },
+ { 0.353553390593274, -0.097545161008064, -0.461939766255643, 0.277785116509801, 0.353553390593274, -0.415734806151273, -0.191341716182545, 0.490392640201615 },
+ { 0.353553390593274, -0.277785116509801, -0.191341716182545, 0.490392640201615, -0.353553390593273, -0.097545161008064, 0.461939766255643, -0.415734806151273 },
+ { 0.353553390593274, -0.415734806151273, 0.191341716182545, 0.097545161008064, -0.353553390593274, 0.490392640201615, -0.461939766255643, 0.277785116509801 },
+ { 0.353553390593274, -0.490392640201615, 0.461939766255643, -0.415734806151273, 0.353553390593273, -0.277785116509801, 0.191341716182545, -0.097545161008064 }
+};
+
+void PSXStreamDecoder::idct(float *dequantData, float *result) {
+ // IDCT code based on JPEG's IDCT code
+ // TODO: Switch to the integer-based one mentioned in the docs
+ // This is by far the costliest operation here
+
+ float tmp[8 * 8];
+
+ // Apply 1D IDCT to rows
+ for (int y = 0; y < 8; y++) {
+ for (int x = 0; x < 8; x++) {
+ tmp[y + x * 8] = dequantData[0] * s_idct8x8[x][0]
+ + dequantData[1] * s_idct8x8[x][1]
+ + dequantData[2] * s_idct8x8[x][2]
+ + dequantData[3] * s_idct8x8[x][3]
+ + dequantData[4] * s_idct8x8[x][4]
+ + dequantData[5] * s_idct8x8[x][5]
+ + dequantData[6] * s_idct8x8[x][6]
+ + dequantData[7] * s_idct8x8[x][7];
+ }
+
+ dequantData += 8;
+ }
+
+ // Apply 1D IDCT to columns
+ for (int x = 0; x < 8; x++) {
+ const float *u = tmp + x * 8;
+ for (int y = 0; y < 8; y++) {
+ result[y * 8 + x] = u[0] * s_idct8x8[y][0]
+ + u[1] * s_idct8x8[y][1]
+ + u[2] * s_idct8x8[y][2]
+ + u[3] * s_idct8x8[y][3]
+ + u[4] * s_idct8x8[y][4]
+ + u[5] * s_idct8x8[y][5]
+ + u[6] * s_idct8x8[y][6]
+ + u[7] * s_idct8x8[y][7];
+ }
+ }
+}
+
+void PSXStreamDecoder::decodeBlock(Common::BitStream *bits, byte *block, int pitch, uint16 scale, uint16 version, PlaneType plane) {
+ // Version 2 just has signed 10 bits for DC
+ // Version 3 has them huffman coded
+ int coefficients[8 * 8];
+ coefficients[0] = readDC(bits, version, plane);
+ readAC(bits, &coefficients[1]); // Read in the AC
+
+ // Dequantize
+ float dequantData[8 * 8];
+ dequantizeBlock(coefficients, dequantData, scale);
+
+ // Perform IDCT
+ float idctData[8 * 8];
+ idct(dequantData, idctData);
+
+ // Now output the data
+ for (int y = 0; y < 8; y++) {
+ byte *start = block + pitch * y;
+
+ // Convert the result to be in the range [0, 255]
+ for (int x = 0; x < 8; x++)
+ *start++ = (int)CLIP<float>(idctData[y * 8 + x], -128.0f, 127.0f) + 128;
+ }
+}
+
+} // End of namespace Video
diff --git a/video/psx_decoder.h b/video/psx_decoder.h
new file mode 100644
index 0000000000..c8ad92c45a
--- /dev/null
+++ b/video/psx_decoder.h
@@ -0,0 +1,128 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef VIDEO_PSX_DECODER_H
+#define VIDEO_PSX_DECODER_H
+
+#include "common/endian.h"
+#include "common/rational.h"
+#include "common/rect.h"
+#include "common/str.h"
+#include "graphics/surface.h"
+#include "video/video_decoder.h"
+
+namespace Audio {
+class QueuingAudioStream;
+}
+
+namespace Common {
+class BitStream;
+class Huffman;
+class SeekableReadStream;
+}
+
+namespace Graphics {
+struct PixelFormat;
+}
+
+namespace Video {
+
+/**
+ * Decoder for PSX stream videos.
+ * This currently implements the most basic PSX stream format that is
+ * used by most games on the system. Special variants are not supported
+ * at this time.
+ *
+ * Video decoder used in engines:
+ * - sword1 (psx)
+ * - sword2 (psx)
+ */
+class PSXStreamDecoder : public VideoDecoder {
+public:
+ // CD speed in sectors/second
+ // Calling code should use these enum values instead of the constants
+ enum CDSpeed {
+ kCD1x = 75,
+ kCD2x = 150
+ };
+
+ PSXStreamDecoder(CDSpeed speed, uint32 frameCount = 0);
+ virtual ~PSXStreamDecoder();
+
+ bool loadStream(Common::SeekableReadStream *stream);
+ void close();
+
+ bool isVideoLoaded() const { return _stream != 0; }
+ uint16 getWidth() const { return _surface->w; }
+ uint16 getHeight() const { return _surface->h; }
+ uint32 getFrameCount() const { return _frameCount; }
+ uint32 getElapsedTime() const;
+ uint32 getTimeToNextFrame() const;
+ const Graphics::Surface *decodeNextFrame();
+ Graphics::PixelFormat getPixelFormat() const { return _surface->format; }
+ bool endOfVideo() const { return _stream->pos() >= _stream->size(); }
+
+private:
+ void initCommon();
+ Common::SeekableReadStream *_stream;
+ Graphics::Surface *_surface;
+
+ uint32 _frameCount;
+ Audio::Timestamp _nextFrameStartTime;
+
+ Audio::SoundHandle _audHandle;
+ Audio::QueuingAudioStream *_audStream;
+ void queueAudioFromSector(Common::SeekableReadStream *sector);
+
+ enum PlaneType {
+ kPlaneY = 0,
+ kPlaneU = 1,
+ kPlaneV = 2
+ };
+
+ uint16 _macroBlocksW, _macroBlocksH;
+ byte *_yBuffer, *_cbBuffer, *_crBuffer;
+ void decodeFrame(Common::SeekableReadStream *frame);
+ void decodeMacroBlock(Common::BitStream *bits, int mbX, int mbY, uint16 scale, uint16 version);
+ void decodeBlock(Common::BitStream *bits, byte *block, int pitch, uint16 scale, uint16 version, PlaneType plane);
+
+ void readAC(Common::BitStream *bits, int *block);
+ Common::Huffman *_acHuffman;
+
+ int readDC(Common::BitStream *bits, uint16 version, PlaneType plane);
+ Common::Huffman *_dcHuffmanLuma, *_dcHuffmanChroma;
+ int _lastDC[3];
+
+ void dequantizeBlock(int *coefficients, float *block, uint16 scale);
+ void idct(float *dequantData, float *result);
+ int readSignedCoefficient(Common::BitStream *bits);
+
+ struct ADPCMStatus {
+ int16 sample[2];
+ } _adpcmStatus[2];
+
+ Common::SeekableReadStream *readSector();
+};
+
+} // End of namespace Video
+
+#endif
diff --git a/video/qt_decoder.cpp b/video/qt_decoder.cpp
index 74bf533e62..959e3c4fc7 100644
--- a/video/qt_decoder.cpp
+++ b/video/qt_decoder.cpp
@@ -56,155 +56,42 @@ namespace Video {
////////////////////////////////////////////
QuickTimeDecoder::QuickTimeDecoder() {
- _curFrame = -1;
- _startTime = _nextFrameStartTime = 0;
+ _setStartTime = false;
_audHandle = Audio::SoundHandle();
_scaledSurface = 0;
_dirtyPalette = false;
_palette = 0;
+ _width = _height = 0;
+ _needUpdate = false;
}
QuickTimeDecoder::~QuickTimeDecoder() {
close();
}
-uint16 QuickTimeDecoder::getWidth() const {
- if (_videoTrackIndex < 0)
- return 0;
-
- return (Common::Rational(_tracks[_videoTrackIndex]->width) / getScaleFactorX()).toInt();
-}
-
-uint16 QuickTimeDecoder::getHeight() const {
- if (_videoTrackIndex < 0)
- return 0;
-
- return (Common::Rational(_tracks[_videoTrackIndex]->height) / getScaleFactorY()).toInt();
-}
-
-uint32 QuickTimeDecoder::getFrameCount() const {
- if (_videoTrackIndex < 0)
- return 0;
-
- return _tracks[_videoTrackIndex]->frameCount;
-}
-
-Common::Rational QuickTimeDecoder::getScaleFactorX() const {
- if (_videoTrackIndex < 0)
- return 1;
-
- return (_scaleFactorX * _tracks[_videoTrackIndex]->scaleFactorX);
-}
-
-Common::Rational QuickTimeDecoder::getScaleFactorY() const {
- if (_videoTrackIndex < 0)
- return 1;
+int32 QuickTimeDecoder::getCurFrame() const {
+ // TODO: This is rather simplistic and doesn't take edits that
+ // repeat sections of the media into account. Doing that
+ // over-complicates things and shouldn't be necessary, but
+ // it would be nice to have in the future.
- return (_scaleFactorY * _tracks[_videoTrackIndex]->scaleFactorY);
-}
+ int32 frame = -1;
-uint32 QuickTimeDecoder::getFrameDuration() {
- if (_videoTrackIndex < 0)
- return 0;
+ for (uint32 i = 0; i < _handlers.size(); i++)
+ if (_handlers[i]->getTrackType() == TrackHandler::kTrackTypeVideo)
+ frame += ((VideoTrackHandler *)_handlers[i])->getCurFrame() + 1;
- uint32 curFrameIndex = 0;
- for (int32 i = 0; i < _tracks[_videoTrackIndex]->timeToSampleCount; i++) {
- curFrameIndex += _tracks[_videoTrackIndex]->timeToSample[i].count;
- if ((uint32)_curFrame < curFrameIndex) {
- // Ok, now we have what duration this frame has.
- return _tracks[_videoTrackIndex]->timeToSample[i].duration;
- }
- }
-
- // This should never occur
- error ("Cannot find duration for frame %d", _curFrame);
- return 0;
-}
-
-Graphics::PixelFormat QuickTimeDecoder::getPixelFormat() const {
- Codec *codec = findDefaultVideoCodec();
-
- if (!codec)
- return Graphics::PixelFormat::createFormatCLUT8();
-
- return codec->getPixelFormat();
-}
-
-uint32 QuickTimeDecoder::findKeyFrame(uint32 frame) const {
- for (int i = _tracks[_videoTrackIndex]->keyframeCount - 1; i >= 0; i--)
- if (_tracks[_videoTrackIndex]->keyframes[i] <= frame)
- return _tracks[_videoTrackIndex]->keyframes[i];
-
- // If none found, we'll assume the requested frame is a key frame
return frame;
}
-void QuickTimeDecoder::seekToFrame(uint32 frame) {
- assert(_videoTrackIndex >= 0);
- assert(frame < _tracks[_videoTrackIndex]->frameCount);
-
- // Stop all audio (for now)
- stopAudio();
-
- // Track down the keyframe
- _curFrame = findKeyFrame(frame) - 1;
- while (_curFrame < (int32)frame - 1)
- decodeNextFrame();
-
- // Map out the starting point
- _nextFrameStartTime = 0;
- uint32 curFrame = 0;
-
- for (int32 i = 0; i < _tracks[_videoTrackIndex]->timeToSampleCount && curFrame < frame; i++) {
- for (int32 j = 0; j < _tracks[_videoTrackIndex]->timeToSample[i].count && curFrame < frame; j++) {
- curFrame++;
- _nextFrameStartTime += _tracks[_videoTrackIndex]->timeToSample[i].duration;
- }
- }
-
- // Adjust the video starting point
- const Audio::Timestamp curVideoTime(0, _nextFrameStartTime, _tracks[_videoTrackIndex]->timeScale);
- _startTime = g_system->getMillis() - curVideoTime.msecs();
- resetPauseStartTime();
-
- // Adjust the audio starting point
- if (_audioTrackIndex >= 0) {
- _audioStartOffset = curVideoTime;
-
- // Seek to the new audio location
- setAudioStreamPos(_audioStartOffset);
-
- // Restart the audio
- startAudio();
-
- // Pause the audio again if we're still paused
- if (isPaused() && _audStream)
- g_system->getMixer()->pauseHandle(_audHandle, true);
- }
-}
-
-void QuickTimeDecoder::seekToTime(Audio::Timestamp time) {
- // Use makeQuickTimeStream() instead
- if (_videoTrackIndex < 0)
- error("Audio-only seeking not supported");
-
- // Try to find the last frame that should have been decoded
- uint32 frame = 0;
- Audio::Timestamp totalDuration(0, _tracks[_videoTrackIndex]->timeScale);
- bool done = false;
+uint32 QuickTimeDecoder::getFrameCount() const {
+ uint32 count = 0;
- for (int32 i = 0; i < _tracks[_videoTrackIndex]->timeToSampleCount && !done; i++) {
- for (int32 j = 0; j < _tracks[_videoTrackIndex]->timeToSample[i].count; j++) {
- totalDuration = totalDuration.addFrames(_tracks[_videoTrackIndex]->timeToSample[i].duration);
- if (totalDuration > time) {
- done = true;
- break;
- }
- frame++;
- }
- }
+ for (uint32 i = 0; i < _handlers.size(); i++)
+ if (_handlers[i]->getTrackType() == TrackHandler::kTrackTypeVideo)
+ count += ((VideoTrackHandler *)_handlers[i])->getFrameCount();
- seekToFrame(frame);
+ return count;
}
void QuickTimeDecoder::startAudio() {
@@ -224,98 +111,107 @@ void QuickTimeDecoder::pauseVideoIntern(bool pause) {
g_system->getMixer()->pauseHandle(_audHandle, pause);
}
-Codec *QuickTimeDecoder::findDefaultVideoCodec() const {
- if (_videoTrackIndex < 0 || _tracks[_videoTrackIndex]->sampleDescs.empty())
- return 0;
+QuickTimeDecoder::VideoTrackHandler *QuickTimeDecoder::findNextVideoTrack() const {
+ VideoTrackHandler *bestTrack = 0;
+ uint32 bestTime = 0xffffffff;
+
+ for (uint32 i = 0; i < _handlers.size(); i++) {
+ if (_handlers[i]->getTrackType() == TrackHandler::kTrackTypeVideo && !_handlers[i]->endOfTrack()) {
+ VideoTrackHandler *track = (VideoTrackHandler *)_handlers[i];
+ uint32 time = track->getNextFrameStartTime();
+
+ if (time < bestTime) {
+ bestTime = time;
+ bestTrack = track;
+ }
+ }
+ }
- return ((VideoSampleDesc *)_tracks[_videoTrackIndex]->sampleDescs[0])->_videoCodec;
+ return bestTrack;
}
const Graphics::Surface *QuickTimeDecoder::decodeNextFrame() {
- if (_videoTrackIndex < 0 || _curFrame >= (int32)getFrameCount() - 1)
+ if (!_nextVideoTrack)
return 0;
- if (_startTime == 0)
- _startTime = g_system->getMillis();
-
- _curFrame++;
- _nextFrameStartTime += getFrameDuration();
-
- // Update the audio while we're at it
- updateAudioBuffer();
-
- // Get the next packet
- uint32 descId;
- Common::SeekableReadStream *frameData = getNextFramePacket(descId);
-
- if (!frameData || !descId || descId > _tracks[_videoTrackIndex]->sampleDescs.size())
- return 0;
+ const Graphics::Surface *frame = _nextVideoTrack->decodeNextFrame();
- // Find which video description entry we want
- VideoSampleDesc *entry = (VideoSampleDesc *)_tracks[_videoTrackIndex]->sampleDescs[descId - 1];
+ if (!_setStartTime) {
+ _startTime = g_system->getMillis();
+ _setStartTime = true;
+ }
- if (!entry->_videoCodec)
- return 0;
+ _nextVideoTrack = findNextVideoTrack();
+ _needUpdate = false;
- const Graphics::Surface *frame = entry->_videoCodec->decodeImage(frameData);
- delete frameData;
+ // Update audio buffers too
+ // (needs to be done after we find the next track)
+ for (uint32 i = 0; i < _handlers.size(); i++)
+ if (_handlers[i]->getTrackType() == TrackHandler::kTrackTypeAudio)
+ ((AudioTrackHandler *)_handlers[i])->updateBuffer();
- // Update the palette
- if (entry->_videoCodec->containsPalette()) {
- // The codec itself contains a palette
- if (entry->_videoCodec->hasDirtyPalette()) {
- _palette = entry->_videoCodec->getPalette();
- _dirtyPalette = true;
- }
- } else {
- // Check if the video description has been updated
- byte *palette = entry->_palette;
-
- if (palette != _palette) {
- _palette = palette;
- _dirtyPalette = true;
- }
+ if (_scaledSurface) {
+ scaleSurface(frame, _scaledSurface, _scaleFactorX, _scaleFactorY);
+ return _scaledSurface;
}
- return scaleSurface(frame);
+ return frame;
}
-const Graphics::Surface *QuickTimeDecoder::scaleSurface(const Graphics::Surface *frame) {
- if (getScaleFactorX() == 1 && getScaleFactorY() == 1)
- return frame;
+void QuickTimeDecoder::scaleSurface(const Graphics::Surface *src, Graphics::Surface *dst, Common::Rational scaleFactorX, Common::Rational scaleFactorY) {
+ assert(src && dst);
- assert(_scaledSurface);
-
- for (int32 j = 0; j < _scaledSurface->h; j++)
- for (int32 k = 0; k < _scaledSurface->w; k++)
- memcpy(_scaledSurface->getBasePtr(k, j), frame->getBasePtr((k * getScaleFactorX()).toInt() , (j * getScaleFactorY()).toInt()), frame->format.bytesPerPixel);
-
- return _scaledSurface;
+ for (int32 j = 0; j < dst->h; j++)
+ for (int32 k = 0; k < dst->w; k++)
+ memcpy(dst->getBasePtr(k, j), src->getBasePtr((k * scaleFactorX).toInt() , (j * scaleFactorY).toInt()), src->format.bytesPerPixel);
}
bool QuickTimeDecoder::endOfVideo() const {
- return (!_audStream || _audStream->endOfData()) && (!findDefaultVideoCodec() || SeekableVideoDecoder::endOfVideo());
+ if (!isVideoLoaded())
+ return true;
+
+ for (uint32 i = 0; i < _handlers.size(); i++)
+ if (!_handlers[i]->endOfTrack())
+ return false;
+
+ return true;
}
uint32 QuickTimeDecoder::getElapsedTime() const {
- if (_audStream)
- return g_system->getMixer()->getSoundElapsedTime(_audHandle) + _audioStartOffset.msecs();
+ // TODO: Convert to multi-track
+ if (_audStream) {
+ // Use the audio time if present and the audio track's time is less than the
+ // total length of the audio track. The audio track can end before the video
+ // track, so we need to fall back on the getMillis() time tracking in that
+ // case.
+ uint32 time = g_system->getMixer()->getSoundElapsedTime(_audHandle) + _audioStartOffset.msecs();
+ if (time < _tracks[_audioTrackIndex]->mediaDuration * 1000 / _tracks[_audioTrackIndex]->timeScale)
+ return time;
+ }
+ // Just use time elapsed since the beginning
return SeekableVideoDecoder::getElapsedTime();
}
uint32 QuickTimeDecoder::getTimeToNextFrame() const {
- if (endOfVideo() || _curFrame < 0)
+ if (_needUpdate)
return 0;
- // Convert from the QuickTime rate base to 1000
- uint32 nextFrameStartTime = _nextFrameStartTime * 1000 / _tracks[_videoTrackIndex]->timeScale;
- uint32 elapsedTime = getElapsedTime();
+ if (_nextVideoTrack) {
+ uint32 nextFrameStartTime = _nextVideoTrack->getNextFrameStartTime();
- if (nextFrameStartTime <= elapsedTime)
- return 0;
+ if (nextFrameStartTime == 0)
+ return 0;
+
+ // TODO: Add support for rate modification
+
+ uint32 elapsedTime = getElapsedTime();
+
+ if (elapsedTime < nextFrameStartTime)
+ return nextFrameStartTime - elapsedTime;
+ }
- return nextFrameStartTime - elapsedTime;
+ return 0;
}
bool QuickTimeDecoder::loadFile(const Common::String &filename) {
@@ -337,30 +233,49 @@ bool QuickTimeDecoder::loadStream(Common::SeekableReadStream *stream) {
void QuickTimeDecoder::init() {
Audio::QuickTimeAudioDecoder::init();
- _videoTrackIndex = -1;
_startTime = 0;
-
- // Find video streams
- for (uint32 i = 0; i < _tracks.size(); i++)
- if (_tracks[i]->codecType == CODEC_TYPE_VIDEO && _videoTrackIndex < 0)
- _videoTrackIndex = i;
+ _setStartTime = false;
// Start the audio codec if we've got one that we can handle
if (_audStream) {
startAudio();
_audioStartOffset = Audio::Timestamp(0);
+
+ // TODO: Support multiple audio tracks
+ // For now, just push back a handler for the first audio track
+ _handlers.push_back(new AudioTrackHandler(this, _tracks[_audioTrackIndex]));
}
- // Initialize video, if present
- if (_videoTrackIndex >= 0) {
- for (uint32 i = 0; i < _tracks[_videoTrackIndex]->sampleDescs.size(); i++)
- ((VideoSampleDesc *)_tracks[_videoTrackIndex]->sampleDescs[i])->initCodec();
+ // Initialize all the video tracks
+ for (uint32 i = 0; i < _tracks.size(); i++) {
+ if (_tracks[i]->codecType == CODEC_TYPE_VIDEO) {
+ for (uint32 j = 0; j < _tracks[i]->sampleDescs.size(); j++)
+ ((VideoSampleDesc *)_tracks[i]->sampleDescs[j])->initCodec();
- if (getScaleFactorX() != 1 || getScaleFactorY() != 1) {
+ _handlers.push_back(new VideoTrackHandler(this, _tracks[i]));
+ }
+ }
+
+ // Prepare the first video track
+ _nextVideoTrack = findNextVideoTrack();
+
+ if (_nextVideoTrack) {
+ // Initialize the scaled surface
+ if (_scaleFactorX != 1 || _scaleFactorY != 1) {
// We have to initialize the scaled surface
_scaledSurface = new Graphics::Surface();
- _scaledSurface->create(getWidth(), getHeight(), getPixelFormat());
+ _scaledSurface->create((_nextVideoTrack->getWidth() / _scaleFactorX).toInt(),
+ (_nextVideoTrack->getHeight() / _scaleFactorY).toInt(), getPixelFormat());
+ _width = _scaledSurface->w;
+ _height = _scaledSurface->h;
+ } else {
+ _width = _nextVideoTrack->getWidth().toInt();
+ _height = _nextVideoTrack->getHeight().toInt();
}
+
+ _needUpdate = true;
+ } else {
+ _needUpdate = false;
}
}
@@ -464,6 +379,7 @@ Common::QuickTimeParser::SampleDesc *QuickTimeDecoder::readSampleDesc(Track *tra
void QuickTimeDecoder::close() {
stopAudio();
+ freeAllTrackHandlers();
if (_scaledSurface) {
_scaledSurface->free();
@@ -471,93 +387,46 @@ void QuickTimeDecoder::close() {
_scaledSurface = 0;
}
+ _width = _height = 0;
+
Common::QuickTimeParser::close();
SeekableVideoDecoder::reset();
}
-Common::SeekableReadStream *QuickTimeDecoder::getNextFramePacket(uint32 &descId) {
- if (_videoTrackIndex < 0)
- return NULL;
-
- // First, we have to track down which chunk holds the sample and which sample in the chunk contains the frame we are looking for.
- int32 totalSampleCount = 0;
- int32 sampleInChunk = 0;
- int32 actualChunk = -1;
- uint32 sampleToChunkIndex = 0;
+void QuickTimeDecoder::freeAllTrackHandlers() {
+ for (uint32 i = 0; i < _handlers.size(); i++)
+ delete _handlers[i];
- for (uint32 i = 0; i < _tracks[_videoTrackIndex]->chunkCount; i++) {
- if (sampleToChunkIndex < _tracks[_videoTrackIndex]->sampleToChunkCount && i >= _tracks[_videoTrackIndex]->sampleToChunk[sampleToChunkIndex].first)
- sampleToChunkIndex++;
-
- totalSampleCount += _tracks[_videoTrackIndex]->sampleToChunk[sampleToChunkIndex - 1].count;
-
- if (totalSampleCount > getCurFrame()) {
- actualChunk = i;
- descId = _tracks[_videoTrackIndex]->sampleToChunk[sampleToChunkIndex - 1].id;
- sampleInChunk = _tracks[_videoTrackIndex]->sampleToChunk[sampleToChunkIndex - 1].count - totalSampleCount + getCurFrame();
- break;
- }
- }
-
- if (actualChunk < 0) {
- warning ("Could not find data for frame %d", getCurFrame());
- return NULL;
- }
-
- // Next seek to that frame
- _fd->seek(_tracks[_videoTrackIndex]->chunkOffsets[actualChunk]);
-
- // Then, if the chunk holds more than one frame, seek to where the frame we want is located
- for (int32 i = getCurFrame() - sampleInChunk; i < getCurFrame(); i++) {
- if (_tracks[_videoTrackIndex]->sampleSize != 0)
- _fd->skip(_tracks[_videoTrackIndex]->sampleSize);
- else
- _fd->skip(_tracks[_videoTrackIndex]->sampleSizes[i]);
- }
+ _handlers.clear();
+}
- // Finally, read in the raw data for the frame
- //printf ("Frame Data[%d]: Offset = %d, Size = %d\n", getCurFrame(), _fd->pos(), _tracks[_videoTrackIndex]->sampleSizes[getCurFrame()]);
+void QuickTimeDecoder::seekToTime(Audio::Timestamp time) {
+ // Sets all tracks to this time
+ for (uint32 i = 0; i < _handlers.size(); i++)
+ _handlers[i]->seekToTime(time);
- if (_tracks[_videoTrackIndex]->sampleSize != 0)
- return _fd->readStream(_tracks[_videoTrackIndex]->sampleSize);
+ // Reset our start time
+ _startTime = g_system->getMillis() - time.msecs();
+ _setStartTime = true;
+ resetPauseStartTime();
- return _fd->readStream(_tracks[_videoTrackIndex]->sampleSizes[getCurFrame()]);
+ // Reset the next video track too
+ _nextVideoTrack = findNextVideoTrack();
+ _needUpdate = _nextVideoTrack != 0;
}
void QuickTimeDecoder::updateAudioBuffer() {
- if (!_audStream)
- return;
-
- uint32 numberOfChunksNeeded = 0;
-
- if (_videoTrackIndex < 0 || _curFrame == (int32)_tracks[_videoTrackIndex]->frameCount - 1) {
- // If we have no video, there's nothing to base our buffer against
- // However, one must ask why a QuickTimeDecoder is being used instead of the nice makeQuickTimeStream() function
-
- // If we're on the last frame, make sure all audio remaining is buffered
- numberOfChunksNeeded = _tracks[_audioTrackIndex]->chunkCount;
- } else {
- Audio::QuickTimeAudioDecoder::AudioSampleDesc *entry = (Audio::QuickTimeAudioDecoder::AudioSampleDesc *)_tracks[_audioTrackIndex]->sampleDescs[0];
-
- // Calculate the amount of chunks we need in memory until the next frame
- uint32 timeToNextFrame = getTimeToNextFrame();
- uint32 timeFilled = 0;
- uint32 curAudioChunk = _curAudioChunk - _audStream->numQueuedStreams();
-
- for (; timeFilled < timeToNextFrame && curAudioChunk < _tracks[_audioTrackIndex]->chunkCount; numberOfChunksNeeded++, curAudioChunk++) {
- uint32 sampleCount = entry->getAudioChunkSampleCount(curAudioChunk);
- assert(sampleCount);
-
- timeFilled += sampleCount * 1000 / entry->_sampleRate;
- }
+ // Updates the audio buffers for all audio tracks
+ for (uint32 i = 0; i < _handlers.size(); i++)
+ if (_handlers[i]->getTrackType() == TrackHandler::kTrackTypeAudio)
+ ((AudioTrackHandler *)_handlers[i])->updateBuffer();
+}
- // Add a couple extra to ensure we don't underrun
- numberOfChunksNeeded += 3;
- }
+Graphics::PixelFormat QuickTimeDecoder::getPixelFormat() const {
+ if (_nextVideoTrack)
+ return _nextVideoTrack->getPixelFormat();
- // Keep three streams in buffer so that if/when the first two end, it goes right into the next
- while (_audStream->numQueuedStreams() < numberOfChunksNeeded && _curAudioChunk < _tracks[_audioTrackIndex]->chunkCount)
- queueNextAudioChunk();
+ return Graphics::PixelFormat();
}
QuickTimeDecoder::VideoSampleDesc::VideoSampleDesc(Common::QuickTimeParser::Track *parentTrack, uint32 codecTag) : Common::QuickTimeParser::SampleDesc(parentTrack, codecTag) {
@@ -612,4 +481,383 @@ void QuickTimeDecoder::VideoSampleDesc::initCodec() {
}
}
+bool QuickTimeDecoder::endOfVideoTracks() const {
+ for (uint32 i = 0; i < _handlers.size(); i++)
+ if (_handlers[i]->getTrackType() == TrackHandler::kTrackTypeVideo && !_handlers[i]->endOfTrack())
+ return false;
+
+ return true;
+}
+
+QuickTimeDecoder::TrackHandler::TrackHandler(QuickTimeDecoder *decoder, Track *parent) : _decoder(decoder), _parent(parent), _fd(_decoder->_fd) {
+ _curEdit = 0;
+}
+
+bool QuickTimeDecoder::TrackHandler::endOfTrack() {
+ // A track is over when we've finished going through all edits
+ return _curEdit == _parent->editCount;
+}
+
+QuickTimeDecoder::AudioTrackHandler::AudioTrackHandler(QuickTimeDecoder *decoder, Track *parent) : TrackHandler(decoder, parent) {
+}
+
+void QuickTimeDecoder::AudioTrackHandler::updateBuffer() {
+ if (!_decoder->_audStream)
+ return;
+
+ uint32 numberOfChunksNeeded = 0;
+
+ if (_decoder->endOfVideoTracks()) {
+ // If we have no video left (or no video), there's nothing to base our buffer against
+ numberOfChunksNeeded = _parent->chunkCount;
+ } else {
+ Audio::QuickTimeAudioDecoder::AudioSampleDesc *entry = (Audio::QuickTimeAudioDecoder::AudioSampleDesc *)_parent->sampleDescs[0];
+
+ // Calculate the amount of chunks we need in memory until the next frame
+ uint32 timeToNextFrame = _decoder->getTimeToNextFrame();
+ uint32 timeFilled = 0;
+ uint32 curAudioChunk = _decoder->_curAudioChunk - _decoder->_audStream->numQueuedStreams();
+
+ for (; timeFilled < timeToNextFrame && curAudioChunk < _parent->chunkCount; numberOfChunksNeeded++, curAudioChunk++) {
+ uint32 sampleCount = entry->getAudioChunkSampleCount(curAudioChunk);
+ assert(sampleCount);
+
+ timeFilled += sampleCount * 1000 / entry->_sampleRate;
+ }
+
+ // Add a couple extra to ensure we don't underrun
+ numberOfChunksNeeded += 3;
+ }
+
+ // Keep three streams in buffer so that if/when the first two end, it goes right into the next
+ while (_decoder->_audStream->numQueuedStreams() < numberOfChunksNeeded && _decoder->_curAudioChunk < _parent->chunkCount)
+ _decoder->queueNextAudioChunk();
+}
+
+bool QuickTimeDecoder::AudioTrackHandler::endOfTrack() {
+ // TODO: Handle edits
+ return (_decoder->_curAudioChunk == _parent->chunkCount) && _decoder->_audStream->endOfData();
+}
+
+void QuickTimeDecoder::AudioTrackHandler::seekToTime(Audio::Timestamp time) {
+ if (_decoder->_audStream) {
+ // Stop all audio
+ _decoder->stopAudio();
+
+ _decoder->_audioStartOffset = time;
+
+ // Seek to the new audio location
+ _decoder->setAudioStreamPos(_decoder->_audioStartOffset);
+
+ // Restart the audio
+ _decoder->startAudio();
+
+ // Pause the audio again if we're still paused
+ if (_decoder->isPaused() && _decoder->_audStream)
+ g_system->getMixer()->pauseHandle(_decoder->_audHandle, true);
+ }
+}
+
+QuickTimeDecoder::VideoTrackHandler::VideoTrackHandler(QuickTimeDecoder *decoder, Common::QuickTimeParser::Track *parent) : TrackHandler(decoder, parent) {
+ if (_parent->scaleFactorX != 1 || _parent->scaleFactorY != 1) {
+ _scaledSurface = new Graphics::Surface();
+ _scaledSurface->create(getWidth().toInt(), getHeight().toInt(), getPixelFormat());
+ } else {
+ _scaledSurface = 0;
+ }
+
+ enterNewEditList(false);
+
+ _holdNextFrameStartTime = false;
+ _curFrame = -1;
+ _durationOverride = -1;
+
+}
+
+QuickTimeDecoder::VideoTrackHandler::~VideoTrackHandler() {
+ if (_scaledSurface) {
+ _scaledSurface->free();
+ delete _scaledSurface;
+ }
+}
+
+const Graphics::Surface *QuickTimeDecoder::VideoTrackHandler::decodeNextFrame() {
+ if (endOfTrack())
+ return 0;
+
+ const Graphics::Surface *frame = bufferNextFrame();
+
+ if (_holdNextFrameStartTime) {
+ // Don't set the next frame start time here; we just did a seek
+ _holdNextFrameStartTime = false;
+ } else if (_durationOverride >= 0) {
+ // Use our own duration from the edit list calculation
+ _nextFrameStartTime += _durationOverride;
+ _durationOverride = -1;
+ } else {
+ _nextFrameStartTime += getFrameDuration();
+ }
+
+ // Update the edit list, if applicable
+ // HACK: We're also accepting the time minus one because edit lists
+ // aren't as accurate as one would hope.
+ if (!endOfTrack() && getRateAdjustedFrameTime() >= getCurEditTimeOffset() + getCurEditTrackDuration() - 1) {
+ _curEdit++;
+
+ if (!endOfTrack())
+ enterNewEditList(true);
+ }
+
+ if (_scaledSurface) {
+ _decoder->scaleSurface(frame, _scaledSurface, _parent->scaleFactorX, _parent->scaleFactorY);
+ return _scaledSurface;
+ }
+
+ return frame;
+}
+
+void QuickTimeDecoder::VideoTrackHandler::enterNewEditList(bool bufferFrames) {
+ // Bypass all empty edit lists first
+ while (!endOfTrack() && _parent->editList[_curEdit].mediaTime == -1)
+ _curEdit++;
+
+ if (endOfTrack())
+ return;
+
+ uint32 frameNum = 0;
+ bool done = false;
+ uint32 totalDuration = 0;
+ uint32 prevDuration = 0;
+
+ // Track down where the mediaTime is in the media
+ for (int32 i = 0; i < _parent->timeToSampleCount && !done; i++) {
+ for (int32 j = 0; j < _parent->timeToSample[i].count; j++) {
+ if (totalDuration == (uint32)_parent->editList[_curEdit].mediaTime) {
+ done = true;
+ prevDuration = totalDuration;
+ break;
+ } else if (totalDuration > (uint32)_parent->editList[_curEdit].mediaTime) {
+ done = true;
+ frameNum--;
+ break;
+ }
+
+ prevDuration = totalDuration;
+ totalDuration += _parent->timeToSample[i].duration;
+ frameNum++;
+ }
+ }
+
+ if (bufferFrames) {
+ // Track down the keyframe
+ _curFrame = findKeyFrame(frameNum) - 1;
+ while (_curFrame < (int32)frameNum - 1)
+ bufferNextFrame();
+ } else {
+ _curFrame = frameNum - 1;
+ }
+
+ _nextFrameStartTime = getCurEditTimeOffset();
+
+ // Set an override for the duration since we came up in-between two frames
+ if (prevDuration != totalDuration)
+ _durationOverride = totalDuration - prevDuration;
+}
+
+const Graphics::Surface *QuickTimeDecoder::VideoTrackHandler::bufferNextFrame() {
+ _curFrame++;
+
+ // Get the next packet
+ uint32 descId;
+ Common::SeekableReadStream *frameData = getNextFramePacket(descId);
+
+ if (!frameData || !descId || descId > _parent->sampleDescs.size())
+ return 0;
+
+ // Find which video description entry we want
+ VideoSampleDesc *entry = (VideoSampleDesc *)_parent->sampleDescs[descId - 1];
+
+ if (!entry->_videoCodec)
+ return 0;
+
+ const Graphics::Surface *frame = entry->_videoCodec->decodeImage(frameData);
+ delete frameData;
+
+ // Update the palette
+ if (entry->_videoCodec->containsPalette()) {
+ // The codec itself contains a palette
+ if (entry->_videoCodec->hasDirtyPalette()) {
+ _decoder->_palette = entry->_videoCodec->getPalette();
+ _decoder->_dirtyPalette = true;
+ }
+ } else {
+ // Check if the video description has been updated
+ byte *palette = entry->_palette;
+
+ if (palette !=_decoder-> _palette) {
+ _decoder->_palette = palette;
+ _decoder->_dirtyPalette = true;
+ }
+ }
+
+ return frame;
+}
+
+uint32 QuickTimeDecoder::VideoTrackHandler::getNextFrameStartTime() {
+ if (endOfTrack())
+ return 0;
+
+ // Convert to milliseconds so the tracks can be compared
+ return getRateAdjustedFrameTime() * 1000 / _parent->timeScale;
+}
+
+uint32 QuickTimeDecoder::VideoTrackHandler::getFrameCount() {
+ return _parent->frameCount;
+}
+
+uint32 QuickTimeDecoder::VideoTrackHandler::getFrameDuration() {
+ uint32 curFrameIndex = 0;
+ for (int32 i = 0; i < _parent->timeToSampleCount; i++) {
+ curFrameIndex += _parent->timeToSample[i].count;
+ if ((uint32)_curFrame < curFrameIndex) {
+ // Ok, now we have what duration this frame has.
+ return _parent->timeToSample[i].duration;
+ }
+ }
+
+ // This should never occur
+ error("Cannot find duration for frame %d", _curFrame);
+ return 0;
+}
+
+Common::SeekableReadStream *QuickTimeDecoder::VideoTrackHandler::getNextFramePacket(uint32 &descId) {
+ // First, we have to track down which chunk holds the sample and which sample in the chunk contains the frame we are looking for.
+ int32 totalSampleCount = 0;
+ int32 sampleInChunk = 0;
+ int32 actualChunk = -1;
+ uint32 sampleToChunkIndex = 0;
+
+ for (uint32 i = 0; i < _parent->chunkCount; i++) {
+ if (sampleToChunkIndex < _parent->sampleToChunkCount && i >= _parent->sampleToChunk[sampleToChunkIndex].first)
+ sampleToChunkIndex++;
+
+ totalSampleCount += _parent->sampleToChunk[sampleToChunkIndex - 1].count;
+
+ if (totalSampleCount > _curFrame) {
+ actualChunk = i;
+ descId = _parent->sampleToChunk[sampleToChunkIndex - 1].id;
+ sampleInChunk = _parent->sampleToChunk[sampleToChunkIndex - 1].count - totalSampleCount + _curFrame;
+ break;
+ }
+ }
+
+ if (actualChunk < 0) {
+ warning("Could not find data for frame %d", _curFrame);
+ return 0;
+ }
+
+ // Next seek to that frame
+ _fd->seek(_parent->chunkOffsets[actualChunk]);
+
+ // Then, if the chunk holds more than one frame, seek to where the frame we want is located
+ for (int32 i = _curFrame - sampleInChunk; i < _curFrame; i++) {
+ if (_parent->sampleSize != 0)
+ _fd->skip(_parent->sampleSize);
+ else
+ _fd->skip(_parent->sampleSizes[i]);
+ }
+
+ // Finally, read in the raw data for the frame
+ //debug("Frame Data[%d]: Offset = %d, Size = %d", _curFrame, _fd->pos(), _parent->sampleSizes[_curFrame]);
+
+ if (_parent->sampleSize != 0)
+ return _fd->readStream(_parent->sampleSize);
+
+ return _fd->readStream(_parent->sampleSizes[_curFrame]);
+}
+
+uint32 QuickTimeDecoder::VideoTrackHandler::findKeyFrame(uint32 frame) const {
+ for (int i = _parent->keyframeCount - 1; i >= 0; i--)
+ if (_parent->keyframes[i] <= frame)
+ return _parent->keyframes[i];
+
+ // If none found, we'll assume the requested frame is a key frame
+ return frame;
+}
+
+void QuickTimeDecoder::VideoTrackHandler::seekToTime(Audio::Timestamp time) {
+ // First, figure out what edit we're in
+ time = time.convertToFramerate(_parent->timeScale);
+
+ // Continue until we get to where we need to be
+ for (_curEdit = 0; !endOfTrack(); _curEdit++)
+ if ((uint32)time.totalNumberOfFrames() >= getCurEditTimeOffset() && (uint32)time.totalNumberOfFrames() < getCurEditTimeOffset() + getCurEditTrackDuration())
+ break;
+
+ // This track is done
+ if (endOfTrack())
+ return;
+
+ enterNewEditList(false);
+
+ // One extra check for the end of a track
+ if (endOfTrack())
+ return;
+
+ // Now we're in the edit and need to figure out what frame we need
+ while (getRateAdjustedFrameTime() < (uint32)time.totalNumberOfFrames()) {
+ _curFrame++;
+ if (_durationOverride >= 0) {
+ _nextFrameStartTime += _durationOverride;
+ _durationOverride = -1;
+ } else {
+ _nextFrameStartTime += getFrameDuration();
+ }
+ }
+
+ // All that's left is to figure out what our starting time is going to be
+ // Compare the starting point for the frame to where we need to be
+ _holdNextFrameStartTime = getRateAdjustedFrameTime() != (uint32)time.totalNumberOfFrames();
+
+ // If we went past the time, go back a frame
+ if (_holdNextFrameStartTime)
+ _curFrame--;
+
+ // Handle the keyframe here
+ int32 destinationFrame = _curFrame + 1;
+
+ assert(destinationFrame < (int32)_parent->frameCount);
+ _curFrame = findKeyFrame(destinationFrame) - 1;
+ while (_curFrame < destinationFrame - 1)
+ bufferNextFrame();
+}
+
+Common::Rational QuickTimeDecoder::VideoTrackHandler::getWidth() const {
+ return Common::Rational(_parent->width) / _parent->scaleFactorX;
+}
+
+Common::Rational QuickTimeDecoder::VideoTrackHandler::getHeight() const {
+ return Common::Rational(_parent->height) / _parent->scaleFactorY;
+}
+
+Graphics::PixelFormat QuickTimeDecoder::VideoTrackHandler::getPixelFormat() const {
+ return ((VideoSampleDesc *)_parent->sampleDescs[0])->_videoCodec->getPixelFormat();
+}
+
+uint32 QuickTimeDecoder::VideoTrackHandler::getRateAdjustedFrameTime() const {
+ // Figure out what time the next frame is at taking the edit list rate into account
+ uint32 convertedTime = (Common::Rational(_nextFrameStartTime - getCurEditTimeOffset()) / _parent->editList[_curEdit].mediaRate).toInt();
+ return convertedTime + getCurEditTimeOffset();
+}
+
+uint32 QuickTimeDecoder::VideoTrackHandler::getCurEditTimeOffset() const {
+ // Need to convert to the track scale
+ return _parent->editList[_curEdit].timeOffset * _parent->timeScale / _decoder->_timeScale;
+}
+
+uint32 QuickTimeDecoder::VideoTrackHandler::getCurEditTrackDuration() const {
+ // Need to convert to the track scale
+ return _parent->editList[_curEdit].trackDuration * _parent->timeScale / _decoder->_timeScale;
+}
+
} // End of namespace Video
diff --git a/video/qt_decoder.h b/video/qt_decoder.h
index b51fd043e7..b2d7153f42 100644
--- a/video/qt_decoder.h
+++ b/video/qt_decoder.h
@@ -31,14 +31,14 @@
#ifndef VIDEO_QT_DECODER_H
#define VIDEO_QT_DECODER_H
+#include "audio/mixer.h"
+#include "audio/decoders/quicktime_intern.h"
#include "common/scummsys.h"
#include "common/rational.h"
+#include "graphics/pixelformat.h"
#include "video/video_decoder.h"
-#include "audio/mixer.h"
-#include "audio/decoders/quicktime_intern.h"
-
namespace Common {
class Rational;
}
@@ -63,13 +63,13 @@ public:
* Returns the width of the video
* @return the width of the video
*/
- uint16 getWidth() const;
+ uint16 getWidth() const { return _width; }
/**
* Returns the height of the video
* @return the height of the video
*/
- uint16 getHeight() const;
+ uint16 getHeight() const { return _height; }
/**
* Returns the amount of frames in the video
@@ -101,6 +101,8 @@ public:
const byte *getPalette() { _dirtyPalette = false; return _palette; }
bool hasDirtyPalette() const { return _dirtyPalette; }
+ int32 getCurFrame() const;
+
bool isVideoLoaded() const { return isOpen(); }
const Graphics::Surface *decodeNextFrame();
bool endOfVideo() const;
@@ -132,8 +134,6 @@ protected:
Common::QuickTimeParser::SampleDesc *readSampleDesc(Track *track, uint32 format);
private:
- Common::SeekableReadStream *getNextFramePacket(uint32 &descId);
- uint32 getFrameDuration();
void init();
void startAudio();
@@ -144,20 +144,108 @@ private:
Audio::Timestamp _audioStartOffset;
Codec *createCodec(uint32 codecTag, byte bitsPerPixel);
- Codec *findDefaultVideoCodec() const;
- uint32 _nextFrameStartTime;
- int _videoTrackIndex;
uint32 findKeyFrame(uint32 frame) const;
bool _dirtyPalette;
const byte *_palette;
+ bool _setStartTime;
+ bool _needUpdate;
+
+ uint16 _width, _height;
Graphics::Surface *_scaledSurface;
- const Graphics::Surface *scaleSurface(const Graphics::Surface *frame);
- Common::Rational getScaleFactorX() const;
- Common::Rational getScaleFactorY() const;
+ void scaleSurface(const Graphics::Surface *src, Graphics::Surface *dst,
+ Common::Rational scaleFactorX, Common::Rational scaleFactorY);
void pauseVideoIntern(bool pause);
+ bool endOfVideoTracks() const;
+
+ // The TrackHandler is a class that wraps around a QuickTime Track
+ // and handles playback in this decoder class.
+ class TrackHandler {
+ public:
+ TrackHandler(QuickTimeDecoder *decoder, Track *parent);
+ virtual ~TrackHandler() {}
+
+ enum TrackType {
+ kTrackTypeAudio,
+ kTrackTypeVideo
+ };
+
+ virtual TrackType getTrackType() const = 0;
+
+ virtual void seekToTime(Audio::Timestamp time) = 0;
+
+ virtual bool endOfTrack();
+
+ protected:
+ uint32 _curEdit;
+ QuickTimeDecoder *_decoder;
+ Common::SeekableReadStream *_fd;
+ Track *_parent;
+ };
+
+ // The AudioTrackHandler is currently just a wrapper around some
+ // QuickTimeDecoder functions. Eventually this can be made to
+ // handle multiple audio tracks, but I haven't seen a video with
+ // that yet.
+ class AudioTrackHandler : public TrackHandler {
+ public:
+ AudioTrackHandler(QuickTimeDecoder *decoder, Track *parent);
+ TrackType getTrackType() const { return kTrackTypeAudio; }
+
+ void updateBuffer();
+ void seekToTime(Audio::Timestamp time);
+ bool endOfTrack();
+ };
+
+ // The VideoTrackHandler is the bridge between the time of playback
+ // and the media for the given track. It calculates when to start
+ // tracks and at what rate to play the media using the edit list.
+ class VideoTrackHandler : public TrackHandler {
+ public:
+ VideoTrackHandler(QuickTimeDecoder *decoder, Track *parent);
+ ~VideoTrackHandler();
+
+ TrackType getTrackType() const { return kTrackTypeVideo; }
+
+ const Graphics::Surface *decodeNextFrame();
+
+ uint32 getNextFrameStartTime();
+
+ uint32 getFrameCount();
+
+ int32 getCurFrame() { return _curFrame; }
+
+ Graphics::PixelFormat getPixelFormat() const;
+
+ void seekToTime(Audio::Timestamp time);
+
+ Common::Rational getWidth() const;
+ Common::Rational getHeight() const;
+
+ private:
+ int32 _curFrame;
+ uint32 _nextFrameStartTime;
+ Graphics::Surface *_scaledSurface;
+ bool _holdNextFrameStartTime;
+ int32 _durationOverride;
+
+ Common::SeekableReadStream *getNextFramePacket(uint32 &descId);
+ uint32 getFrameDuration();
+ uint32 findKeyFrame(uint32 frame) const;
+ void enterNewEditList(bool bufferFrames);
+ const Graphics::Surface *bufferNextFrame();
+ uint32 getRateAdjustedFrameTime() const;
+ uint32 getCurEditTimeOffset() const;
+ uint32 getCurEditTrackDuration() const;
+ };
+
+ Common::Array<TrackHandler *> _handlers;
+ VideoTrackHandler *_nextVideoTrack;
+ VideoTrackHandler *findNextVideoTrack() const;
+
+ void freeAllTrackHandlers();
};
} // End of namespace Video